From shawn.gsc at gmail.com  Thu Feb  1 01:47:48 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Thu, 1 Feb 2024 17:47:48 +0800
Subject: [PATCH v2 0/4] TQMa8Xx (i.MX8QXP/i.MX8DXP) support
In-Reply-To: <20231214142327.1962914-1-alexander.stein@ew.tq-group.com>
References: <20231214142327.1962914-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240201094748.GC463595@dragon>

On Thu, Dec 14, 2023 at 03:23:23PM +0100, Alexander Stein wrote:
> Alexander Stein (4):
>   arm64: dts: imx: add imx8dxp support
>   dt-bindings: arm: add TQMa8Xx boards
>   arm64: dts: freescale: add initial device tree for TQMa8Xx
>   arm64: defconfig: Enable i.MX8QXP device drivers

Applied all, thanks!


From shawn.gsc at gmail.com  Thu Feb  1 02:02:26 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Thu, 1 Feb 2024 18:02:26 +0800
Subject: [PATCH 0/5] TQMa8Xx (imx8qxp) audio support
In-Reply-To: <20231214150243.1991532-1-alexander.stein@ew.tq-group.com>
References: <20231214150243.1991532-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240201100226.GD463595@dragon>

On Thu, Dec 14, 2023 at 04:02:38PM +0100, Alexander Stein wrote:
> Hi,
> 
> this series adds audio support for TQMa8Xx on MBa8Xx.
> The first 4 patches add the necessary nodes for providing clocks and SAI,
> which are used in the last patch. Patch 5 depends on [1], but right now it is
> to show a consumer.
> 
> Best regards,
> Alexander
> 
> [1] https://lore.kernel.org/all/20231214142327.1962914-1-alexander.stein at ew.tq-group.com/
> 
> Alexander Stein (5):
>   arm64: dts: imx8qxp: Add ACM input clock gates
>   arm64: dts: imx8qxp: Add audio clock mux node
>   arm64: dts: imx8qxp: Add audio SAI nodes
>   arm64: dts: imx8qxp: Add mclkout clock gates
>   arm64: dts: imx8qxp: mba8xx: Add analog audio output on MBa8Xx

Applied all, thanks!


From shawn.gsc at gmail.com  Thu Feb  1 02:04:47 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Thu, 1 Feb 2024 18:04:47 +0800
Subject: [PATCH 1/2] arm64: dts: imx8qm: Align edma3 power-domains
 resources indentation
In-Reply-To: <20231214194655.608902-1-Frank.Li@nxp.com>
References: <20231214194655.608902-1-Frank.Li@nxp.com>
Message-ID: <20240201100447.GE463595@dragon>

On Thu, Dec 14, 2023 at 02:46:54PM -0500, Frank Li wrote:
> <&pd IMX_SC_R_DMA_1_CH*> is now properly aligned with the previous line
> for improved code readability.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied both, thanks!


From shawn.gsc at gmail.com  Thu Feb  1 02:09:15 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Thu, 1 Feb 2024 18:09:15 +0800
Subject: [PATCH 1/1] arm64: dts: imx8qxp: add GPU nodes
In-Reply-To: <20231218142312.3175828-1-alexander.stein@ew.tq-group.com>
References: <20231218142312.3175828-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240201100915.GF463595@dragon>

On Mon, Dec 18, 2023 at 03:23:12PM +0100, Alexander Stein wrote:
> Add the DT node for the GPU core found on the i.MX8QXP.
> 
> etnaviv-gpu 53100000.gpu: model: GC7000, revision: 6214
> [drm] Initialized etnaviv 1.3.0 20151214 for etnaviv on minor 0
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied, thanks!


From liuyongqiang13 at huawei.com  Thu Feb  1 00:00:04 2024
From: liuyongqiang13 at huawei.com (Yongqiang Liu)
Date: Thu, 1 Feb 2024 16:00:04 +0800
Subject: [PATCH] arm: flush: don't abuse pfn_valid() to check if pfn is in
 RAM
In-Reply-To: <edc4e8fa-af0a-46c2-bf07-20a0c4e20af5@arm.com>
References: <20240131125907.1006760-1-liuyongqiang13@huawei.com>
 <0da50102-3e87-49f7-b8f7-45cfcb4232d6@arm.com>
 <ZbqY12U/CXwAAu7A@shell.armlinux.org.uk>
 <edc4e8fa-af0a-46c2-bf07-20a0c4e20af5@arm.com>
Message-ID: <8b50ca93-c164-ddfc-cd79-8f8525198a96@huawei.com>

Very appreciate it for extra explanation. Notice that commit 024591f9a6e0

("arm: ioremap: don't abuse pfn_valid() to check if pfn is in RAM") use

memblock_is_map_memory() instead of pfn_valid() to check if a PFN is in

RAM or not, so I wrote the patch to solve this case.? Otherwise, when we

use pageblock align(4M) address of memory or uio, like :

 ???? node?? 0: [mem 0x00000000c0c00000-0x00000000cc8fffff]
 ???? node?? 0: [mem 0x00000000d0000000-0x00000000da1fffff]

or uio address set like:

 ?? 0xc0400000, 0x100000

the pfn_valid will return false as memblock_is_map_memory.

? 2024/2/1 5:20, Robin Murphy ??:
> On 2024-01-31 7:00 pm, Russell King (Oracle) wrote:
>> On Wed, Jan 31, 2024 at 06:39:31PM +0000, Robin Murphy wrote:
>>> On 31/01/2024 12:59 pm, Yongqiang Liu wrote:
>>>> @@ -292,7 +293,7 @@ void __sync_icache_dcache(pte_t pteval)
>>>> ?????????? /* only flush non-aliasing VIPT caches for exec mappings */
>>>> ?????????? return;
>>>> ?????? pfn = pte_pfn(pteval);
>>>> -??? if (!pfn_valid(pfn))
>>>> +??? if (!memblock_is_map_memory(PFN_PHYS(pfn)))
>>>> ?????????? return;
>>>> ?????? folio = page_folio(pfn_to_page(pfn));
>>>
>>> Hmm, it's a bit odd in context, since pfn_valid() obviously pairs 
>>> with this
>>> pfn_to_page(), whereas it's not necessarily clear that
>>> memblock_is_map_memory() implies pfn_valid().
>>>
>>> However, in this case we're starting from a PTE - rather than going 
>>> off to
>>> do a slow scan of memblock to determine whether a round-trip through
>>> page_address() is going to give back a mapped VA, can we not trivially
>>> identify that from whether the PTE itself is valid?
>>
>> Depends what you mean by "valid". If you're referring to pte_valid()
>> and L_PTE_VALID then no.
>>
>> On 32-bit non-LPAE, the valid bit is the same as the present bit, and
>> needs to be set for the PTE to not fault. Any PTE that is mapping
>> something will be "valid" whether it is memory or not, whether it is
>> backed by a page or not.
>>
>> pfn_valid() should be telling us whether the PFN is suitable to be
>> passed to pfn_to_page(), and if we have a situation where pfn_valid()
>> returns true, but pfn_to_page() returns an invalid page, then that in
>> itself is a bug that needs to be fixed and probably has far reaching
>> implications for the stability of the kernel.
>
> Right, the problem here seems to be the opposite one, wherein we *do* 
> often have a valid struct page for an address which is reserved and 
> thus not mapped by the kernel, but seemingly we then take it down a 
> path which assumes anything !PageHighmem() is lowmem and dereferences 
> page_address() without looking.
>
> However I realise I should have looked closer at the caller, and my 
> idea is futile since the PTE here is for a userspace mapping, not a 
> kernel VA, and is already pte_valid_user() && !pte_special(). Plus the 
> fact that the stack trace indicates an mmap() path suggests it most 
> likely is a legitimate mapping of some no-map carveout or MMIO region. 
> Oh well. My first point still stands, though - I think at least a 
> comment to clarify that assumption would be warranted.
>
> Thanks,
> Robin.
> .


From yangjihong1 at huawei.com  Thu Feb  1 00:03:39 2024
From: yangjihong1 at huawei.com (Yang Jihong)
Date: Thu, 1 Feb 2024 16:03:39 +0800
Subject: [PATCH v2 8/8] perf cpumap: Use perf_cpu_map__for_each_cpu when
 possible
In-Reply-To: <20240201042236.1538928-9-irogers@google.com>
References: <20240201042236.1538928-1-irogers@google.com>
 <20240201042236.1538928-9-irogers@google.com>
Message-ID: <aa719d3b-5b96-a341-b776-a67cc6fad64a@huawei.com>

Hello,

On 2024/2/1 12:22, Ian Rogers wrote:
> Rather than manually iterating the CPU map, use
> perf_cpu_map__for_each_cpu. When possible tidy local variables.
> 
> Signed-off-by: Ian Rogers <irogers at google.com>
> Reviewed-by: James Clark <james.clark at arm.com>
> ---
>   tools/perf/arch/arm64/util/header.c           | 10 ++--
>   tools/perf/tests/bitmap.c                     | 13 +++---
>   tools/perf/tests/topology.c                   | 46 +++++++++----------
>   tools/perf/util/bpf_kwork.c                   | 16 ++++---
>   tools/perf/util/bpf_kwork_top.c               | 12 ++---
>   tools/perf/util/cpumap.c                      | 12 ++---
>   .../scripting-engines/trace-event-python.c    | 12 +++--
>   tools/perf/util/session.c                     |  5 +-
>   tools/perf/util/svghelper.c                   | 20 ++++----
>   9 files changed, 72 insertions(+), 74 deletions(-)
> 
> diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
> index a9de0b5187dd..741df3614a09 100644
> --- a/tools/perf/arch/arm64/util/header.c
> +++ b/tools/perf/arch/arm64/util/header.c
> @@ -4,8 +4,6 @@
>   #include <stdio.h>
>   #include <stdlib.h>
>   #include <perf/cpumap.h>
> -#include <util/cpumap.h>
> -#include <internal/cpumap.h>
>   #include <api/fs/fs.h>
>   #include <errno.h>
>   #include "debug.h"
> @@ -19,18 +17,18 @@
>   static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus)
>   {
>   	const char *sysfs = sysfs__mountpoint();
> -	int cpu;
> -	int ret = EINVAL;
> +	struct perf_cpu cpu;
> +	int idx, ret = EINVAL;
>   
>   	if (!sysfs || sz < MIDR_SIZE)
>   		return EINVAL;
>   
> -	for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) {
> +	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
>   		char path[PATH_MAX];
>   		FILE *file;
>   
>   		scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d" MIDR,
> -			  sysfs, RC_CHK_ACCESS(cpus)->map[cpu].cpu);
> +			  sysfs, cpu.cpu);
>   
>   		file = fopen(path, "r");
>   		if (!file) {
> diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c
> index 0173f5402a35..98956e0e0765 100644
> --- a/tools/perf/tests/bitmap.c
> +++ b/tools/perf/tests/bitmap.c
> @@ -11,18 +11,19 @@
>   static unsigned long *get_bitmap(const char *str, int nbits)
>   {
>   	struct perf_cpu_map *map = perf_cpu_map__new(str);
> -	unsigned long *bm = NULL;
> -	int i;
> +	unsigned long *bm;
>   
>   	bm = bitmap_zalloc(nbits);
>   
>   	if (map && bm) {
> -		for (i = 0; i < perf_cpu_map__nr(map); i++)
> -			__set_bit(perf_cpu_map__cpu(map, i).cpu, bm);
> +		int i;
> +		struct perf_cpu cpu;
> +
> +		perf_cpu_map__for_each_cpu(cpu, i, map)
> +			__set_bit(cpu.cpu, bm);
>   	}
>   
> -	if (map)
> -		perf_cpu_map__put(map);
> +	perf_cpu_map__put(map);
>   	return bm;
>   }
>   
> diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
> index 2a842f53fbb5..a8cb5ba898ab 100644
> --- a/tools/perf/tests/topology.c
> +++ b/tools/perf/tests/topology.c
> @@ -68,6 +68,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
>   	};
>   	int i;
>   	struct aggr_cpu_id id;
> +	struct perf_cpu cpu;
>   
>   	session = perf_session__new(&data, NULL);
>   	TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
> @@ -113,8 +114,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++) {
> -		struct perf_cpu cpu = { .cpu = i };
> -
> +		cpu.cpu = i;
>   		if (!perf_cpu_map__has(map, cpu))
>   			continue;
>   		pr_debug("CPU %d, core %d, socket %d\n", i,
> @@ -123,48 +123,48 @@ 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 < perf_cpu_map__nr(map); i++) {
> -		id = aggr_cpu_id__cpu(perf_cpu_map__cpu(map, i), NULL);
> +	perf_cpu_map__for_each_cpu(cpu, i, map) {
> +		id = aggr_cpu_id__cpu(cpu, NULL);
>   		TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match",
> -				perf_cpu_map__cpu(map, i).cpu == id.cpu.cpu);
> +				cpu.cpu == id.cpu.cpu);
>   
>   		TEST_ASSERT_VAL("Cpu map - Core ID doesn't match",
> -			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].core_id == id.core);
> +			session->header.env.cpu[cpu.cpu].core_id == id.core);
>   		TEST_ASSERT_VAL("Cpu map - Socket ID doesn't match",
> -			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
> +			session->header.env.cpu[cpu.cpu].socket_id ==
>   			id.socket);
>   
>   		TEST_ASSERT_VAL("Cpu map - Die ID doesn't match",
> -			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id == id.die);
> +			session->header.env.cpu[cpu.cpu].die_id == id.die);
>   		TEST_ASSERT_VAL("Cpu map - Node ID is set", id.node == -1);
>   		TEST_ASSERT_VAL("Cpu map - Thread IDX is set", id.thread_idx == -1);
>   	}
>   
>   	// Test that core ID contains socket, die and core
> -	for (i = 0; i < perf_cpu_map__nr(map); i++) {
> -		id = aggr_cpu_id__core(perf_cpu_map__cpu(map, i), NULL);
> +	perf_cpu_map__for_each_cpu(cpu, i, map) {
> +		id = aggr_cpu_id__core(cpu, NULL);
>   		TEST_ASSERT_VAL("Core map - Core ID doesn't match",
> -			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].core_id == id.core);
> +			session->header.env.cpu[cpu.cpu].core_id == id.core);
>   
>   		TEST_ASSERT_VAL("Core map - Socket ID doesn't match",
> -			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
> +			session->header.env.cpu[cpu.cpu].socket_id ==
>   			id.socket);
>   
>   		TEST_ASSERT_VAL("Core map - Die ID doesn't match",
> -			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id == id.die);
> +			session->header.env.cpu[cpu.cpu].die_id == id.die);
>   		TEST_ASSERT_VAL("Core map - Node ID is set", id.node == -1);
>   		TEST_ASSERT_VAL("Core map - Thread IDX is set", id.thread_idx == -1);
>   	}
>   
>   	// Test that die ID contains socket and die
> -	for (i = 0; i < perf_cpu_map__nr(map); i++) {
> -		id = aggr_cpu_id__die(perf_cpu_map__cpu(map, i), NULL);
> +	perf_cpu_map__for_each_cpu(cpu, i, map) {
> +		id = aggr_cpu_id__die(cpu, NULL);
>   		TEST_ASSERT_VAL("Die map - Socket ID doesn't match",
> -			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
> +			session->header.env.cpu[cpu.cpu].socket_id ==
>   			id.socket);
>   
>   		TEST_ASSERT_VAL("Die map - Die ID doesn't match",
> -			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id == id.die);
> +			session->header.env.cpu[cpu.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);
> @@ -173,10 +173,10 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
>   	}
>   
>   	// Test that socket ID contains only socket
> -	for (i = 0; i < perf_cpu_map__nr(map); i++) {
> -		id = aggr_cpu_id__socket(perf_cpu_map__cpu(map, i), NULL);
> +	perf_cpu_map__for_each_cpu(cpu, i, map) {
> +		id = aggr_cpu_id__socket(cpu, NULL);
>   		TEST_ASSERT_VAL("Socket map - Socket ID doesn't match",
> -			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
> +			session->header.env.cpu[cpu.cpu].socket_id ==
>   			id.socket);
>   
>   		TEST_ASSERT_VAL("Socket map - Node ID is set", id.node == -1);
> @@ -187,10 +187,10 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
>   	}
>   
>   	// Test that node ID contains only node
> -	for (i = 0; i < perf_cpu_map__nr(map); i++) {
> -		id = aggr_cpu_id__node(perf_cpu_map__cpu(map, i), NULL);
> +	perf_cpu_map__for_each_cpu(cpu, i, map) {
> +		id = aggr_cpu_id__node(cpu, NULL);
>   		TEST_ASSERT_VAL("Node map - Node ID doesn't match",
> -				cpu__get_node(perf_cpu_map__cpu(map, i)) == id.node);
> +				cpu__get_node(cpu) == id.node);
>   		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);
> diff --git a/tools/perf/util/bpf_kwork.c b/tools/perf/util/bpf_kwork.c
> index 6eb2c78fd7f4..44f0f708a15d 100644
> --- a/tools/perf/util/bpf_kwork.c
> +++ b/tools/perf/util/bpf_kwork.c
> @@ -147,12 +147,12 @@ static bool valid_kwork_class_type(enum kwork_class_type type)
>   
>   static int setup_filters(struct perf_kwork *kwork)
>   {
> -	u8 val = 1;
> -	int i, nr_cpus, key, fd;
> -	struct perf_cpu_map *map;
> -
>   	if (kwork->cpu_list != NULL) {
> -		fd = bpf_map__fd(skel->maps.perf_kwork_cpu_filter);
> +		int idx, nr_cpus;
> +		struct perf_cpu_map *map;
> +		struct perf_cpu cpu;
> +		int fd = bpf_map__fd(skel->maps.perf_kwork_cpu_filter);
> +
>   		if (fd < 0) {
>   			pr_debug("Invalid cpu filter fd\n");
>   			return -1;
> @@ -165,8 +165,8 @@ static int setup_filters(struct perf_kwork *kwork)
>   		}
>   
>   		nr_cpus = libbpf_num_possible_cpus();
> -		for (i = 0; i < perf_cpu_map__nr(map); i++) {
> -			struct perf_cpu cpu = perf_cpu_map__cpu(map, i);
> +		perf_cpu_map__for_each_cpu(cpu, idx, map) {
> +			u8 val = 1;
>   
>   			if (cpu.cpu >= nr_cpus) {
>   				perf_cpu_map__put(map);
> @@ -181,6 +181,8 @@ static int setup_filters(struct perf_kwork *kwork)
>   	}
>   
>   	if (kwork->profile_name != NULL) {
> +		int key, fd;
> +
>   		if (strlen(kwork->profile_name) >= MAX_KWORKNAME) {
>   			pr_err("Requested name filter %s too large, limit to %d\n",
>   			       kwork->profile_name, MAX_KWORKNAME - 1);
> diff --git a/tools/perf/util/bpf_kwork_top.c b/tools/perf/util/bpf_kwork_top.c
> index 035e02272790..22a3b00a1e23 100644
> --- a/tools/perf/util/bpf_kwork_top.c
> +++ b/tools/perf/util/bpf_kwork_top.c
> @@ -122,11 +122,11 @@ static bool valid_kwork_class_type(enum kwork_class_type type)
>   
>   static int setup_filters(struct perf_kwork *kwork)
>   {
> -	u8 val = 1;
> -	int i, nr_cpus, fd;
> -	struct perf_cpu_map *map;
> -
>   	if (kwork->cpu_list) {
> +		int idx, nr_cpus, fd;
> +		struct perf_cpu_map *map;
> +		struct perf_cpu cpu;
> +
>   		fd = bpf_map__fd(skel->maps.kwork_top_cpu_filter);
>   		if (fd < 0) {
>   			pr_debug("Invalid cpu filter fd\n");
> @@ -140,8 +140,8 @@ static int setup_filters(struct perf_kwork *kwork)
>   		}
>   
>   		nr_cpus = libbpf_num_possible_cpus();
> -		for (i = 0; i < perf_cpu_map__nr(map); i++) {
> -			struct perf_cpu cpu = perf_cpu_map__cpu(map, i);
> +		perf_cpu_map__for_each_cpu(cpu, idx, map) {
> +			u8 val = 1;
>   
>   			if (cpu.cpu >= nr_cpus) {
>   				perf_cpu_map__put(map);

For part of perf-kwork utility:
Reviewed-and-tested-by: Yang Jihong <yangjihong1 at huawei.com>


Thanks,
Yang


From krzysztof.kozlowski at linaro.org  Thu Feb  1 00:07:34 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 09:07:34 +0100
Subject: [PATCH 2/3] dt-bindings: fpga: xlnx,fpga-slave-selectmap: add DT
 schema
In-Reply-To: <20240131230542.3993409-3-charles.perry@savoirfairelinux.com>
References: <20240129225602.3832449-1-charles.perry@savoirfairelinux.com>
 <20240131230542.3993409-1-charles.perry@savoirfairelinux.com>
 <20240131230542.3993409-3-charles.perry@savoirfairelinux.com>
Message-ID: <d5fe1ec2-b647-4902-a599-fb866e96e9cf@linaro.org>

On 01/02/2024 00:05, Charles Perry wrote:
> Document the slave SelectMAP interface of Xilinx 7 series FPGA.
> 
> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
> ---
>  .../bindings/fpga/xlnx,fpga-selectmap.yaml    | 83 +++++++++++++++++++
>  1 file changed, 83 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
> 
> diff --git a/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
> new file mode 100644
> index 0000000000000..c9a446b43cdd9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
> @@ -0,0 +1,83 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/fpga/xlnx,fpga-selectmap.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Xilinx SelectMAP FPGA interface
> +
> +maintainers:
> +  - Charles Perry <charles.perry at savoirfairelinux.com>
> +
> +description: |
> +  Xilinx 7 Series FPGAs support a method of loading the bitstream over a
> +  parallel port named the SelectMAP interface in the documentation. Only
> +  the x8 mode is supported where data is loaded at one byte per rising edge of
> +  the clock, with the MSB of each byte presented to the D0 pin.
> +
> +  Datasheets:
> +    https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf
> +
> +allOf:
> +  - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - xlnx,fpga-selectmap

Your description mentions "7 Series" which is not present in compatible
and title. What is exactly the product here? Interface usually is not
the final binding, so is this specific to some particular FPGA or SoC?


Best regards,
Krzysztof



From m-chawdhry at ti.com  Thu Feb  1 00:07:25 2024
From: m-chawdhry at ti.com (Manorit Chawdhry)
Date: Thu, 1 Feb 2024 13:37:25 +0530
Subject: [PATCH v2 0/2] TI: K3: Fix the device IDs for VTM node.
Message-ID: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-0-85fd568b77e3@ti.com>

Signed-off-by: Manorit Chawdhry <m-chawdhry at ti.com>
---
Changes in v2:
- Fix the device ID for J784s4 ( Andrew )
- Link to v1: https://lore.kernel.org/r/20240131-b4-upstream-j721s2-fix-vtm-devid-v1-1-94c927bb9595 at ti.com

---
Manorit Chawdhry (2):
      arm64: dts: ti: k3-j721s2: Fix power domain for VTM node
      arm64: dts: ti: k3-j784s4: Fix power domain for VTM node

 arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi | 2 +-
 arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
---
base-commit: 774551425799cb5bbac94e1768fd69eec4f78dd4
change-id: 20240123-b4-upstream-j721s2-fix-vtm-devid-86e55c8a59ca

Best regards,
-- 
Manorit Chawdhry <m-chawdhry at ti.com>



From m-chawdhry at ti.com  Thu Feb  1 00:07:26 2024
From: m-chawdhry at ti.com (Manorit Chawdhry)
Date: Thu, 1 Feb 2024 13:37:26 +0530
Subject: [PATCH v2 1/2] arm64: dts: ti: k3-j721s2: Fix power domain for VTM
 node
In-Reply-To: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-0-85fd568b77e3@ti.com>
References: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-0-85fd568b77e3@ti.com>
Message-ID: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-1-85fd568b77e3@ti.com>

Fix the power domain device ID for wkup_vtm0 node.

Link: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j721s2/devices.html
Fixes: d148e3fe52c8 ("arm64: dts: ti: j721s2: Add VTM node")
Signed-off-by: Manorit Chawdhry <m-chawdhry at ti.com>
Reviewed-by: Andrew Davis <afd at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
index 80aa33c58a45..a47cb557dd95 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
@@ -663,7 +663,7 @@ wkup_vtm0: temperature-sensor at 42040000 {
 		compatible = "ti,j7200-vtm";
 		reg = <0x00 0x42040000 0x0 0x350>,
 		      <0x00 0x42050000 0x0 0x350>;
-		power-domains = <&k3_pds 154 TI_SCI_PD_SHARED>;
+		power-domains = <&k3_pds 180 TI_SCI_PD_SHARED>;
 		#thermal-sensor-cells = <1>;
 	};
 

-- 
2.43.0



From m-chawdhry at ti.com  Thu Feb  1 00:07:27 2024
From: m-chawdhry at ti.com (Manorit Chawdhry)
Date: Thu, 1 Feb 2024 13:37:27 +0530
Subject: [PATCH v2 2/2] arm64: dts: ti: k3-j784s4: Fix power domain for VTM
 node
In-Reply-To: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-0-85fd568b77e3@ti.com>
References: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-0-85fd568b77e3@ti.com>
Message-ID: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-2-85fd568b77e3@ti.com>

Fix the power domain device ID for wkup_vtm0 node.

Link: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j784s4/devices.html
Fixes: 64821fbf6738 ("arm64: dts: ti: j784s4: Add VTM node")
Signed-off-by: Manorit Chawdhry <m-chawdhry at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
index 3902a921d7e5..337122c3f402 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
@@ -628,7 +628,7 @@ wkup_vtm0: temperature-sensor at 42040000 {
 		compatible = "ti,j7200-vtm";
 		reg = <0x00 0x42040000 0x00 0x350>,
 		      <0x00 0x42050000 0x00 0x350>;
-		power-domains = <&k3_pds 154 TI_SCI_PD_SHARED>;
+		power-domains = <&k3_pds 243 TI_SCI_PD_SHARED>;
 		#thermal-sensor-cells = <1>;
 	};
 

-- 
2.43.0



From peng.fan at nxp.com  Thu Feb  1 00:07:51 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 1 Feb 2024 08:07:51 +0000
Subject: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <20240129163043.if5jj4kyacqfe2n5@bogus>
References: <20240121-pinctrl-scmi-v3-0-8d94ba79dca8@nxp.com>
 <f88d07ef-83b2-4d14-976a-6dbbd71e036f@oss.nxp.com>
 <20240129163043.if5jj4kyacqfe2n5@bogus>
Message-ID: <DU0PR04MB94178FAC347A4500E9449ECB88432@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
> protocol basic support
> 
> On Mon, Jan 29, 2024 at 08:36:50PM +0800, Peng Fan wrote:
> > Hi Sudeep, Cristian
> >
> > Would you pick up patch 1-4?
> 
> I will for v6.9 sometime.
> 
> > And for i.MX95 OEM extenstion, do you have any suggestions?
> > I have two points:
> > 1. use vendor compatible. This would also benefit when supporting
> > vendor protocol.
> 
> May be, but that was never on plate for standard protocols. So I don't like
> that approach either.
> 
> > 2. Introduce a property saying supporting-generic-pinconf
> >
> 
> I am not sure what you mean by that. But that doesn't sound right especial in
> context of SCMI. So I would say no.
> 
> > How do you think?
> >
> 
> I don't have any other suggestions than fix your driver to use the pinmux
> properly with features in the upstream pinmux subsystem.

So for OEM specific units in Pin Configuration Type and Enumerations,
Any ideas how to support them if not talking about i.MX?

Thanks,
Peng.

> 
> --
> Regards,
> Sudeep


From ardb at kernel.org  Thu Feb  1 00:08:22 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 1 Feb 2024 09:08:22 +0100
Subject: [PATCH] arm64: jump_label: use constraint "S" instead of "i"
In-Reply-To: <20240201045551.ajg4iqcajyowl2rh@google.com>
References: <20240131065322.1126831-1-maskray@google.com> <CAMj1kXGzADFWa7RmXyjWpCnQ=9hhz6i-XkN4PS1CboZ-kFL8dQ@mail.gmail.com>
 <ZbpEnDK3U/O24ng0@e133380.arm.com> <20240201045551.ajg4iqcajyowl2rh@google.com>
Message-ID: <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>

On Thu, 1 Feb 2024 at 05:55, Fangrui Song <maskray at google.com> wrote:
>
> On 2024-01-31, Dave Martin wrote:
> >On Wed, Jan 31, 2024 at 08:16:04AM +0100, Ard Biesheuvel wrote:
> >> Hello Fangrui,
> >>
> >> On Wed, 31 Jan 2024 at 07:53, Fangrui Song <maskray at google.com> wrote:
> >> >
> >> > The constraint "i" seems to be copied from x86 (and with a redundant
> >> > modifier "c"). It works with -fno-PIE but not with -fPIE/-fPIC in GCC's
> >> > aarch64 port.
> >
> >(I'm not sure of the exact history, but the "c" may be inherited from
> >arm, where an output modifier was needed to suppress the "#" that
> >prefixes immediates in the traditional asm syntax.  This does not
> >actually seem to be required for AArch64: rather while a # is allowed
> >and still considered good style in handwritten asm code, the syntax
> >doesn't require it, and the compiler doesn't emit it for "i" arguments,
> >AFAICT.)
>
> The aarch64 one could be inherited from
> arch/arm/include/asm/jump_label.h (2012), which could in turn be
> inherited from x86 (2010).
> Both the constraint "i" and the modifier "c" are generic..
> For -fno-pic this combination can be used for every arch.
>
> >> > The constraint "S", which denotes a symbol reference (e.g. function,
> >> > global variable) or label reference, is more appropriate, and has been
> >> > available in GCC since 2012 and in Clang since 7.0.
> >> >
> >> > Signed-off-by: Fangrui Song <maskray at google.com>
> >> > Link: https://maskray.me/blog/2024-01-30-raw-symbol-names-in-inline-assembly
> >> > ---
> >> >  arch/arm64/include/asm/jump_label.h | 8 ++++----
> >> >  1 file changed, 4 insertions(+), 4 deletions(-)
> >> >
> >> > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> >> > index 48ddc0f45d22..31862b3bb33d 100644
> >> > --- a/arch/arm64/include/asm/jump_label.h
> >> > +++ b/arch/arm64/include/asm/jump_label.h
> >> > @@ -23,9 +23,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
> >> >                  "      .pushsection    __jump_table, \"aw\"    \n\t"
> >> >                  "      .align          3                       \n\t"
> >> >                  "      .long           1b - ., %l[l_yes] - .   \n\t"
> >> > -                "      .quad           %c0 - .                 \n\t"
> >> > +                "      .quad           %0 - .                  \n\t"
> >> >                  "      .popsection                             \n\t"
> >> > -                :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> >> > +                :  :  "S"(&((char *)key)[branch]) :  : l_yes);
> >>
> >> 'key' is not used as a raw symbol name. We should make this
> >>
> >> "    .quad   %0 + %1 - ."
> >>
> >> and
> >>
> >> ::  "S"(key), "i"(branch) :: l_yes);
> >>
> >> if we want to really clean this up.
> >
> >This hides more logic in the asm so it's arguably more cryptic
> >(although the code is fairly cryptic to begin with -- I don't really
> >see why the argument wasn't written as the equivalent
> >(char *)key + branch...)
>
> I agree that using "S" and "i" would introduce complexity.
> Using just "S" as this patch does should be clear.
>
> All of "i" "s" "S" support a symbol or label reference and a constant offset (can be zero),
> (in object file, a symbol and an addend; in GCC's term, the sum of a SYMBOL_REF and a CONST_INT).
>

Taken the address of a struct, cast it to char[] and then index it
using a boolean is rather disgusting, no?

> >Anyway, I don't think the "i" versys "S" distinction makes any
> >difference without -fpic or equivalent, so it is not really relevant
> >for the kernel (except that "S" breaks compatibility with older
> >compilers...)
> >
> >
> >I think the main advantage of "S" is that it stops you accidentally
> >emitting undesirable relocations from asm code that is not written for
> >the -fpic case.
> >
> >But just changing "i" to "S" is not sufficient to port asms to -fpic:
> >the asms still need to be reviewed.
> >
> >
> >So unless the asm has been reviewed for position-independence, it may
> >anyway be better to stick with "i" so that the compiler actually chokes
> >if someone tries to build the code with -fpic.
>

The virtual address of the kernel is randomized by KASLR, which relies
on PIE linking, and this puts constraints on the permitted types of
relocations.

IOW, we basically already build the kernel as PIC code, but without
relying on -fPIC, because that triggers some behaviors that only make
sense for shared objects in user space.

> >Since we are not trying to run arbitraily many running kernels in a
> >common address space (and not likely to do that), I'm not sure that we
> >would ever build the kernel with -fpic except for a few special-case
> >bits like the EFI stub and vDSO... unless I've missed something?
> >

Yes, KASLR. The number of kernels is not the point, the point is that
the virtual load address of the kernel is usually decided at boot, and
so the code needs to be generated to accommodate that.

> >If there's another reason why "S" is advantageous though, I'm happy to
> >be corrected.
>
> I remember that Ard has an RFC
> https://lore.kernel.org/linux-arm-kernel/20220427171241.2426592-1-ardb at kernel.org/
> "[RFC PATCH 0/2] arm64: use PIE code generation for KASLR kernel"
> and see some recent PIE codegen patches.
>
> > Building the KASLR kernel without -fpie but linking it with -pie works
> > in practice, but it is not something that is explicitly supported by the
> > toolchains - it happens to work because the default 'small' code model
> > used by both GCC and Clang relies mostly on ADRP+ADD/LDR to generate
> > symbol references.
>
> I agree that current -fno-PIE with -shared -Bsymbolic linking is a hack
> that works as a conincidence, not guaranteed by the toolchain.
> This jump_label improvement (with no object file difference) fixes an
> obstacle.

If we can get the guaranteed behavior of #pragma GCC visibility
push(hidden) from a command line option, we should build the core
kernel with -fpie instead. (Modules are partially linked objects, so
they can be built non-PIC as before)


From anshuman.khandual at arm.com  Thu Feb  1 00:12:08 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 1 Feb 2024 13:42:08 +0530
Subject: [PATCH RFC v3 31/35] khugepaged: arm64: Don't collapse MTE
 enabled VMAs
In-Reply-To: <20240125164256.4147-32-alexandru.elisei@arm.com>
References: <20240125164256.4147-1-alexandru.elisei@arm.com>
 <20240125164256.4147-32-alexandru.elisei@arm.com>
Message-ID: <599769c3-0aef-4c5b-ac98-f109649862f7@arm.com>



On 1/25/24 22:12, Alexandru Elisei wrote:
> copy_user_highpage() will do memory allocation if there are saved tags for
> the destination page, and the page is missing tag storage.
> 
> After commit a349d72fd9ef ("mm/pgtable: add rcu_read_lock() and
> rcu_read_unlock()s"), collapse_huge_page() calls
> __collapse_huge_page_copy() -> .. -> copy_user_highpage() with the RCU lock
> held, which means that copy_user_highpage() can only allocate memory using
> GFP_ATOMIC or equivalent.
> 
> Get around this by refusing to collapse pages into a transparent huge page
> if the VMA is MTE-enabled.

Makes sense when copy_user_highpage() will allocate memory for tag storage.

> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> ---
> 
> Changes since rfc v2:
> 
> * New patch. I think an agreement on whether copy*_user_highpage() should be
> always allowed to sleep, or should not be allowed, would be useful.

This is a good question ! Even after preventing the collapse of MTE VMA here,
there still might be more paths where a sleeping (i.e memory allocating)
copy*_user_highpage() becomes problematic ?

> 
>  arch/arm64/include/asm/pgtable.h    | 3 +++
>  arch/arm64/kernel/mte_tag_storage.c | 5 +++++
>  include/linux/khugepaged.h          | 5 +++++
>  mm/khugepaged.c                     | 4 ++++
>  4 files changed, 17 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 87ae59436162..d0473538c926 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -1120,6 +1120,9 @@ static inline bool arch_alloc_cma(gfp_t gfp_mask)
>  	return true;
>  }
>  
> +bool arch_hugepage_vma_revalidate(struct vm_area_struct *vma, unsigned long address);
> +#define arch_hugepage_vma_revalidate arch_hugepage_vma_revalidate
> +
>  #endif /* CONFIG_ARM64_MTE_TAG_STORAGE */
>  #endif /* CONFIG_ARM64_MTE */
>  
> diff --git a/arch/arm64/kernel/mte_tag_storage.c b/arch/arm64/kernel/mte_tag_storage.c
> index ac7b9c9c585c..a99959b70573 100644
> --- a/arch/arm64/kernel/mte_tag_storage.c
> +++ b/arch/arm64/kernel/mte_tag_storage.c
> @@ -636,3 +636,8 @@ void arch_alloc_page(struct page *page, int order, gfp_t gfp)
>  	if (tag_storage_enabled() && alloc_requires_tag_storage(gfp))
>  		reserve_tag_storage(page, order, gfp);
>  }
> +
> +bool arch_hugepage_vma_revalidate(struct vm_area_struct *vma, unsigned long address)
> +{
> +	return !(vma->vm_flags & VM_MTE);
> +}
> diff --git a/include/linux/khugepaged.h b/include/linux/khugepaged.h
> index f68865e19b0b..461e4322dff2 100644
> --- a/include/linux/khugepaged.h
> +++ b/include/linux/khugepaged.h
> @@ -38,6 +38,11 @@ static inline void khugepaged_exit(struct mm_struct *mm)
>  	if (test_bit(MMF_VM_HUGEPAGE, &mm->flags))
>  		__khugepaged_exit(mm);
>  }
> +
> +#ifndef arch_hugepage_vma_revalidate
> +#define arch_hugepage_vma_revalidate(vma, address) 1

Please replace s/1/true as arch_hugepage_vma_revalidate() returns bool ?

> +#endif

Right, above construct is much better than __HAVE_ARCH_XXXX based one.

> +
>  #else /* CONFIG_TRANSPARENT_HUGEPAGE */
>  static inline void khugepaged_fork(struct mm_struct *mm, struct mm_struct *oldmm)
>  {
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index 2b219acb528e..cb9a9ddb4d86 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -935,6 +935,10 @@ static int hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address,
>  	 */
>  	if (expect_anon && (!(*vmap)->anon_vma || !vma_is_anonymous(*vmap)))
>  		return SCAN_PAGE_ANON;
> +
> +	if (!arch_hugepage_vma_revalidate(vma, address))
> +		return SCAN_VMA_CHECK;
> +
>  	return SCAN_SUCCEED;
>  }
>  

Otherwise this LGTM.


From miquel.raynal at bootlin.com  Thu Feb  1 00:25:58 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 1 Feb 2024 09:25:58 +0100
Subject: [PATCH v3 10/10] mtd: rawnand: brcmnand: allow for on-die ecc
In-Reply-To: <bcd9f8a5-7dab-42e6-b860-8a56ebb51cb6@broadcom.com>
References: <20240124030458.98408-1-dregan@broadcom.com>
	<20240124030458.98408-11-dregan@broadcom.com>
	<20240124184027.712b1e47@xps-13>
	<CAA_RMS42FaiN+Za1iY12o0YUANH9rJarBTBa=9jNn8x6_g-Fng@mail.gmail.com>
	<20240126071913.699c3795@xps-13>
	<CAA_RMS5gX88v_Qt1csgSL_ffMNsqo2G8B164EB_Hg=hXd620eg@mail.gmail.com>
	<20240129115228.06dc2292@xps-13>
	<2a3edcf5-7afc-410c-a402-3d8cd3feb1da@broadcom.com>
	<20240130120155.3cb6feed@xps-13>
	<CAA_RMS577vw=QWN9_NHfmWqt+_cDG22tA01aU019CPNjAgHqJQ@mail.gmail.com>
	<20240130195504.506fb446@xps-13>
	<bcd9f8a5-7dab-42e6-b860-8a56ebb51cb6@broadcom.com>
Message-ID: <20240201092558.5499ee6a@xps-13>

Hi William,

> >>>>>>>> This is a double check to turn on/off our hardware ECC.  
> >>>>>>>
> >>>>>>> I expect the engine to be always disabled. Enable it only when you
> >>>>>>> need (may require an additional patch before this one).  
> >>>>>>
> >>>>>> We are already turning on the ECC enable at this point,
> >>>>>> this is just adding the option to turn it off if the NAND chip
> >>>>>> itself will be doing the ECC instead of our controller.  
> >>>>>
> >>>>> Sorry if I have not been clear.
> >>>>>
> >>>>> This sequence:
> >>>>> - init
> >>>>> - enable hw ECC engine
> >>>>> Is broken.  
> >>>>>   >>>> ECC engine is not enabled for all the cases. Here we only intended to enable it for the nand chip that is set to use NAND_ECC_ENGINE_TYPE_ON_HOST. The logic here should better change to:  
> >>>> if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST)
> >>>>       brcmnand_set_ecc_enabled(host, 1);
> >>>> else
> >>>>       brcmnand_set_ecc_enabled(host, 0);  
> >>>>   >>>>> It *cannot* work as any operation going through exec_op now may  
> >>>>> perform page reads which should be unmodified by the ECC engine. You > driver *must* follow the following sequence:
> >>>>> - init and disable (or keep disabled) the hw ECC engine
> >>>>> - when you perform a page operation with correction you need to
> >>>>>      - enable the engine
> >>>>>      - perform the operation
> >>>>>      - disable the engine
> >>>>> Maybe I am missing something here but are you saying the exec_op can have different ecc type for page read/write at run time on the same nand chip? I don't see the op instr structure has the ecc type field and thought it is only bind to the nand chip and won't change at run time. So looks to me the init time setting to the engine based on ecc.engine_type should be sufficient.  
> >>>>
> >>>> What you described here can work for the hw.ecc read path (ecc.read_page = brcmnand_read_page) which always assumes ecc is enabled. Although it is probably not too bad with these two extra operation, it would be better if we don't have to add anything as our current code does. For the brcmnand_read_page_raw,  we currently disable the engine and then re-enable it(but we need to fix it to only enable it with hw ecc engine type).  So it is just opposite of you logic but works the same with no impact on the most performance critical path.  
> >>>
> >>> This is not "my" logic, this is the "core's" logic. I am saying: your
> >>> approach is broken because that is not how the API is supposed to work,
> >>> but it mostly works in the standard case.  
> >>
> >> In the interest of minimizing register writes, would it be acceptable to
> >> enable/disable ECC at the beginning of a standard
> >> path transfer but not, after the transfer, turn off the ECC? This should not
> >> affect other standard path operations nor affect the exec_op path as those
> >> are low level transfers which our ECC engine would not touch and the NAND
> >> device driver should be responsible for turning on/off its own ECC.  
> > 
> > Do you have legitimate concerns about this register write taking way
> > more time than I could expect? Because compared to the transfer of a
> > NAND page + tR/tPROG it should not be noticeable. I don't see how you
> > could even measure such impact actually, unless the register write does
> > way more than usual. I'm fine with the above idea if you show me it has
> > an interest.
> >   
> Dave did the mtd_speed test and we can see we get consistently ~35KB/s slower with the extra enable and disable ecc engine calls in ecc read page path.
> 
> With the change:
> [   28.148355] mtd_speedtest:   page read speed is 9857 KiB/s
> [   31.754258] mtd_speedtest: 2 page read speed is 9865 KiB/s
> Without the change
> [   56.444735] mtd_speedtest:   page read speed is 9892 KiB/s
> [   60.042262] mtd_speedtest: 2 page read speed is 9897 KiB/s

I believe if you repeat this 10 times you'll get totally different
results. I don't think this test on a non RT machine is precise enough
so that a unique 35kiB difference can be interpreted as being
significant.

> Although it is only less than 1% drop, it is still something. I understand the procedure you laid out above is the preferred way but with our driver fully control the chip ecc read/write page, ecc read_raw/write_raw page function and exec_op path, I don't see where it may not work.

I just told you, the exec_op path runs with ECC enabled. I don't know
how this controller works. Now if you don't care and are 100% sure this
is working and future proof, just keep it like this.

Cheers,
Miqu?l


From esben at geanix.com  Thu Feb  1 00:26:06 2024
From: esben at geanix.com (Esben Haabendal)
Date: Thu, 01 Feb 2024 09:26:06 +0100
Subject: [PATCH net-next 2/2] net: stmmac: TBS support for platform driver
In-Reply-To: <5626e874-066c-4bf2-842d-a7f3387b6c1b@quicinc.com> (Abhishek
	Chauhan's message of "Wed, 31 Jan 2024 13:59:20 -0800")
References: <20230927130919.25683-1-rohan.g.thomas@intel.com>
	<20230927130919.25683-3-rohan.g.thomas@intel.com>
	<92892988-bb77-4075-812e-19f6112f436e@quicinc.com>
	<87r0i44h8v.fsf@geanix.com>
	<5626e874-066c-4bf2-842d-a7f3387b6c1b@quicinc.com>
Message-ID: <87a5okvbdt.fsf@geanix.com>

"Abhishek Chauhan (ABC)" <quic_abchauha at quicinc.com> writes:
> On 1/26/2024 12:43 AM, Esben Haabendal wrote:
>> "Abhishek Chauhan (ABC)" <quic_abchauha at quicinc.com> writes:
>>
>>> Qualcomm had similar discussions with respect to enabling of TBS for a
>>> particular queue. We had similar discussion on these terms yesterday
>>> with Redhat. Adding Andrew from Redhat here
>>>
>>> What we discovered as part of the discussions is listed below.
>>>
>>> 1. Today upstream stmmac code is designed in such a way that TBS flag
>>> is put as part of queue configurations(see below snippet) and as well
>>> know that stmmac queue configuration comes from the dtsi file.
>>>
>>> //ndo_open => stmmac_open
>>> int tbs_en = priv->plat->tx_queues_cfg[chan].tbs_en;(comes from tx_queues_cfg)
>>>
>>> /* Setup per-TXQ tbs flag before TX descriptor alloc */
>>> tx_q->tbs |= tbs_en ? STMMAC_TBS_AVAIL : 0;
>>>
>>> 2. There is a no way to do this dynamically from user space because
>>> we don't have any API exposed which can do it from user space
>>
>> Not now. But why not extend ethtool API to allow enabling TBS for
>> supported controllers?
>
> ethtool API can be implemented but that still doesn't solve the
> problem of stopping the entire MAC block because of enhanced desc
> allocation.

I am not sure what you exact point is here.

If you look at the implementation of ethtool API for changing ring
parameters, you have stmmac_set_ringparam() which calls
stmmac_reinit_ringparam(), which again calls stmmac_release() if the
interface is up (stopping the entire MAC), and then stmmac_open() which
reinitializes everything.

The same pattern could be applied to changes to enable enhanced
descriptor allocation.

I don't see why that will not be acceptable. Why would anyone have to do
that while critical traffic is flowing? In your system you should be
able to know which queues needs enhanced descriptors before starting
communication.

> 1. We can either allocate enhanced desc for all channels at bootup and
> then choose to switch to enable TBS mode at runtime (Additional memory
> usage)

A good default would IMHO be to enable enhanced descriptors for all but
TX queue 0. This will allow use of TBS without needing to change
anything. If the rather minimal extra memory usage is disturbing anyone,
then they can tune it at boot time before bringing the interface up.

> 2. Live with the disruption of traffic for a brief duration of time.
> Which is not a good solution for priority and critical traffic.

As mentioned above, I don't see why anyone would need to modify the
descriptor allocation while critical traffic is flowing.

If you are able put this information in your device tree, you definitely
will be able to put it in an boot script in some form.

>>> and also TBS rely on special descriptors aka enhanced desc this
>>> cannot be done run time and stmmac has to be aware of it before we
>>> do DMA/MAC/MTL start.
>>
>> Isn't this somewhat similar to changing the RX/TX ring parameters,
>> which I believe also is quite difficult to do at run time, and
>> ethtool therefore requires the interface to be down in oroer to
>> change them?
>>
>>> To do this dynamically would only mean stopping DMA/MAC/MTL realloc
>>> resources for enhanced desc and the starting MAC/DMA/MTL. This means
>>> we are disrupting other traffic(By stopping MAC block).
>>
>> Yes. But you would be disrupting traffic less than by requiring a
>> complete reboot of the target which is needed if the devicetree must be
>> changed.
>>
> any DTS solution today anyway requires completely loading the boot
> image and rebooting the device, but once the device is functional, End
> user can activate TBS, as he knows the exact usecase and requirements.
> I understand the solution is not scalable, but at this point we don't
> have a solution to activate TBS at runtime.

Exactly. We are discussing a solution to activate enhanced descriptors
at "runtime". But I propose to do it in a similar way as changing ring
parameters, so it is in runtime seen from a CPU perspective, but the
interface will be shortly brought down when changing it.

>>> 3. I dont think there is a way we can enable this dynamically today. I
>>> would like upstream community to share your thoughts as well.
>>
>> Hereby done. Could we investigate the possibility of using ethtool to
>> change TBS enable/disable "run-time"?
>>
> We can either allocate enhanced desc for all channels at bootup
> and then choose to switch to enable TBS mode at runtime.

I think we should do something like this:
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=3b12ec8f618e

for all glue drivers, so a sane default is established that allows using
TBS from boot up.

But in addition to that, I think it would make sense to create an
ethtool API to change it from that default. And it will bring down the
interface while applying the change.

/Esben


From linux at armlinux.org.uk  Thu Feb  1 00:38:01 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 1 Feb 2024 08:38:01 +0000
Subject: [PATCH net-next v4 06/11] net: stmmac: resetup XPCS according to
 the new interface mode
In-Reply-To: <9e23671e-788c-4191-bdb4-94915ff7da5a@linux.intel.com>
References: <20240129130253.1400707-1-yong.liang.choong@linux.intel.com>
 <20240129130253.1400707-7-yong.liang.choong@linux.intel.com>
 <ZbjNn+C/VHegH2t7@shell.armlinux.org.uk>
 <9e23671e-788c-4191-bdb4-94915ff7da5a@linux.intel.com>
Message-ID: <ZbtYaXkNf2ZF1prE@shell.armlinux.org.uk>

On Thu, Feb 01, 2024 at 01:10:05PM +0800, Choong Yong Liang wrote:
> 
> 
> On 30/1/2024 6:21 pm, Russell King (Oracle) wrote:
> > NAK. Absolutely not. You haven't read the phylink documentation, nor
> > understood how phylink works.
> > 
> > Since you haven't read the phylink documentation, I'm not going to
> > waste any more time reviewing this series since you haven't done your
> > side of the bargin here.
> > 
> Hi Russell,
> 
> Sorry that previously I only studied the phylink based on the `phylink.h`
> itself.

>From phylink.h:

/**
 * mac_select_pcs: Select a PCS for the interface mode.
 * @config: a pointer to a &struct phylink_config.
 * @interface: PHY interface mode for PCS
 *
 * Return the &struct phylink_pcs for the specified interface mode, or
 * NULL if none is required, or an error pointer on error.
 *
 * This must not modify any state. It is used to query which PCS should
 * be used. Phylink will use this during validation to ensure that the
 * configuration is valid, and when setting a configuration to internally
 * set the PCS that will be used.
 */

Note the "This must not modify any state." statement. By reinitialising
the PCS in this method, you are violating that statement.

This requirement is because this method will be called by
phylink_validate_mac_and_pcs() at various times, potentially for each
and every interface that stmmac supports, which will lead to you
reinitialising the PCS, killing the link, each time we ask the MAC for
a PCS, whether we are going to make use of it in that mode or not.

You can not do this. Sorry. Hard NAK for this approach.

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


From krzysztof.kozlowski at linaro.org  Thu Feb  1 00:40:58 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 09:40:58 +0100
Subject: [PATCH v3] regulator: dt-bindings: microchip,mcp16502: convert to
 YAML
In-Reply-To: <20240131130727.447738-1-andrei.simion@microchip.com>
References: <20240131130727.447738-1-andrei.simion@microchip.com>
Message-ID: <d2c0c5dd-e1a2-4607-9177-f3855cb5601e@linaro.org>

On 31/01/2024 14:07, Andrei Simion wrote:
> Convert devicetree binding mcp16502-regulator.txt to YAML format.
> 
> Signed-off-by: Andrei Simion <andrei.simion at microchip.com>
> ---
> Changes v2 -> v3:
> - keep one line of regulators description
> - add additionalProperties: false for regulators
> - "description:" at the end for each properties
> 
> Changes v1 -> v2:
> - reverse subject prefixes
> - line break after file "description:"
> - drop description for reg
> - drop regulator-name
> - add regulator-initial-mode
> - unevaluatedProperties just after $ref: regulator.yaml#
> - additionalProperties  just before "required"

I missed it before, why did you move it? Previous placement was what we
expect. I did not comment about it.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>


---

This is an automated instruction, just in case, because many review tags
are being ignored. If you know the process, you can skip it (please do
not feel offended by me posting it here - no bad intentions intended).
If you do not know the process, here is a short explanation:

Please add Acked-by/Reviewed-by/Tested-by tags when posting new
versions, under or above your Signed-off-by tag. Tag is "received", when
provided in a message replied to you on the mailing list. Tools like b4
can help here. However, there's no need to repost patches *only* to add
the tags. The upstream maintainer will do that for tags received on the
version they apply.

https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577

Best regards,
Krzysztof



From heiko at sntech.de  Thu Feb  1 00:41:31 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 01 Feb 2024 09:41:31 +0100
Subject: [PATCH] arm64: dts: rockchip: rk3588: remove redundant cd-gpios in sdmmc
 node
In-Reply-To: <20240201034621.1970279-1-kever.yang@rock-chips.com>
References: <20240201034621.1970279-1-kever.yang@rock-chips.com>
Message-ID: <4514845.zXnORWrf4K@diego>

Hi Kever,

Am Donnerstag, 1. Februar 2024, 04:46:21 CET schrieb Kever Yang:
> The sdmmc node already have a "&sdmmc_det" for pinctrl which switch the
> GPIO0A4 to sdmmc detect function, no need to define a separate "cd-gpios".

just to make sure, did you test this on actual hardware?
Because there might be differences in behaviour.

> RK3588 has force_jtage feature which is enable JTAG function via sdmmc
> pins automatically when there is no SD card insert, this feature will
> need the GPIO0A4 works in sdmmc_det function like other mmc signal instead
> of GPIO function, or else the force_jtag can not auto be disabled when
> SD card insert.

We disable the jtag switching by default [0] ;-) .
And there are very good reasons for it too:


(1) JTAG is very much a debug feature, that the normal user will not need.
Especially not in a finished product. If a developer is debugging _that_
deep and needs jtag, they can enable it in their debug build.


(2) Randomly enabling features that may compromise security.
Why go through all the hoops of doing things like secure boot, signed
images and everything, just to have the kernel then export direct access
to the hardware on sd-card pins. If one wants to expose JTAG somewhere
this should be conscious choice and devs should not need to fork their
kernel just to shut down unwanted security-critical functionality.


(3) It affects board layouts _not following_ the standard layout.
Nobody is forcing board-designers to use Rockchip's desired pin
for card-detection. Some designer may just select a different pin
or a board could go without card-detect at all - see rk3588-jaguar.
These are both valid use-cases that need to be supported.


Heiko


[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6f6878ec6faf16a5f36761c93da6ea9cf09adb33


> ---
> 
>  arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 1 -
>  arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts     | 1 -
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts         | 1 -
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts        | 1 -
>  4 files changed, 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> index 3e660ff6cd5ff..1b606ea5b6cf2 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
> @@ -444,7 +444,6 @@ &sdhci {
>  &sdmmc {
>  	bus-width = <4>;
>  	cap-sd-highspeed;
> -	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>  	disable-wp;
>  	max-frequency = <150000000>;
>  	no-sdio;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
> index 87a0abf95f7d4..67414d72e2b6e 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
> @@ -429,7 +429,6 @@ &sdhci {
>  &sdmmc {
>  	bus-width = <4>;
>  	cap-sd-highspeed;
> -	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>  	disable-wp;
>  	max-frequency = <150000000>;
>  	no-sdio;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> index a0e303c3a1dc6..25a82008e4f76 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> @@ -371,7 +371,6 @@ &sdmmc {
>  	bus-width = <4>;
>  	cap-mmc-highspeed;
>  	cap-sd-highspeed;
> -	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>  	disable-wp;
>  	sd-uhs-sdr104;
>  	vmmc-supply = <&vcc_3v3_s3>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> index 2002fd0221fa3..00afb90d4eb10 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> @@ -366,7 +366,6 @@ &sdmmc {
>  	bus-width = <4>;
>  	cap-mmc-highspeed;
>  	cap-sd-highspeed;
> -	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>  	disable-wp;
>  	max-frequency = <150000000>;
>  	no-sdio;
> 






From angelogioacchino.delregno at collabora.com  Thu Feb  1 00:44:48 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 1 Feb 2024 09:44:48 +0100
Subject: [PATCH] firmware: arm_scmi: Avoid to call mbox_client_txdone on
 txdone_irq mode
In-Reply-To: <20240201045253.14390-1-flash.liu@mediatek.com>
References: <20240201045253.14390-1-flash.liu@mediatek.com>
Message-ID: <7cf660b8-240f-442e-be55-2e6e6521338b@collabora.com>

Il 01/02/24 05:52, Pin-Chuan Liu ha scritto:
> On txdone_irq mode, tx_tick is done from mbox_chan_txdone.
> Calling to mbox_client_txdone could get error message
> and return directly, add a check to avoid this.
> 
> Signed-off-by: Pin-Chuan Liu <flash.liu at mediatek.com>
> Change-Id: Iacbe0d36ef9cc16974c013c3e94c47dc79eae52b

Change-Id is something internal to you and has no meaning upstream.
Please remove it.

> ---
>   drivers/firmware/arm_scmi/mailbox.c | 8 +++++++-
>   1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c
> index b8d470417e8f..f6fe801c2e34 100644
> --- a/drivers/firmware/arm_scmi/mailbox.c
> +++ b/drivers/firmware/arm_scmi/mailbox.c
> @@ -8,6 +8,7 @@
>   
>   #include <linux/err.h>
>   #include <linux/device.h>
> +#include <linux/mailbox_controller.h>
>   #include <linux/mailbox_client.h>
>   #include <linux/of.h>
>   #include <linux/of_address.h>
> @@ -275,7 +276,12 @@ static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
>   	 * Unfortunately, we have to kick the mailbox framework after we have
>   	 * received our message.
>   	 */
> -	mbox_client_txdone(smbox->chan, ret);
> +
> +	/*
> +	 * With txdone_irq mode, kick can be done by mbox_chan_txdone.
> +	 */

Besides, you need one single line for this comment

Regards,
Angelo

> +	if (!(smbox->chan->mbox->txdone_irq))
> +		mbox_client_txdone(smbox->chan, ret);
>   }
>   
>   static void mailbox_fetch_response(struct scmi_chan_info *cinfo,




From u.kleine-koenig at pengutronix.de  Thu Feb  1 00:49:22 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Thu, 1 Feb 2024 09:49:22 +0100
Subject: [PATCH v8 2/3] pwm: Add Allwinner's D1/T113-S3/R329 SoCs PWM
 support
In-Reply-To: <20240131125920.2879433-3-privatesub2@gmail.com>
References: <20240131125920.2879433-1-privatesub2@gmail.com>
 <20240131125920.2879433-3-privatesub2@gmail.com>
Message-ID: <eynkbikmzcffid2jft3b6pmjfcbvda6mpzu7l5mefrw3za3iwh@ctgn57kb7ard>

hello Aleksandr,

On Wed, Jan 31, 2024 at 03:59:15PM +0300, Aleksandr Shubin wrote:
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>

Some time ago there was some effort by Rob Herring to detangle the
headers platform_device.h, of_device.h and of.h. See for example commit
87e51b76c9db8c29cde573af0faf5a3e13e23960. I think you should use
linux/of.h instead of linux/of_device.h.

> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/reset.h>
> +
> +#define SUN20I_PWM_CLK_CFG(chan)		(0x20 + (((chan) >> 1) * 0x4))
> +#define SUN20I_PWM_CLK_CFG_SRC			GENMASK(8, 7)
> +#define SUN20I_PWM_CLK_CFG_DIV_M		GENMASK(3, 0)
> +#define SUN20I_PWM_CLK_DIV_M_MAX		8

SUN20I_PWM_CLK_CFG_DIV_M_MAX?

> +#define SUN20I_PWM_CLK_GATE			0x40
> +#define SUN20I_PWM_CLK_GATE_BYPASS(chan)	BIT((chan) + 16)
> +#define SUN20I_PWM_CLK_GATE_GATING(chan)	BIT(chan)
> +
> +#define SUN20I_PWM_ENABLE			0x80
> +#define SUN20I_PWM_ENABLE_EN(chan)		BIT(chan)
> +
> +#define SUN20I_PWM_CTL(chan)			(0x100 + (chan) * 0x20)
> +#define SUN20I_PWM_CTL_ACT_STA			BIT(8)
> +#define UN20I_PWM_CTL_PRESCAL_K		GENMASK(7, 0)
> +#define SUN20I_PWM_CTL_PRESCAL_K_MAX		0xff

This matches the theoretical maximum for GENMASK(7,0), so you could make
use of field_max(SUN20I_PWM_CTL_PRESCAL_K) here.

> +#define SUN20I_PWM_PERIOD(chan)			(0x104 + (chan) * 0x20)
> +#define SUN20I_PWM_PERIOD_ENTIRE_CYCLE		GENMASK(31, 16)
> +#define SUN20I_PWM_PERIOD_ACT_CYCLE		GENMASK(15, 0)
> +
> +#define SUN20I_PWM_PCNTR_SIZE			BIT(16)
> +
> +/**
> + * SUN20I_PWM_MAGIC is used to quickly compute the values of the clock dividers
> + * div_m (SUN20I_PWM_CLK_CFG_DIV_M) & prescale_k (SUN20I_PWM_CTL_PRESCAL_K)
> + * without using a loop. These dividers limit the # of cycles in a period
> + * to SUN20I_PWM_PCNTR_SIZE by applying a scaling factor of
> + * 1/(div_m * (prescale_k + 1)) to the clock source.
> + *
> + * SUN20I_PWM_MAGIC is derived by solving for div_m and prescale_k
> + * such that for a given requested period,
> + *
> + * i) div_m is minimized for any prescale_k ? SUN20I_PWM_CTL_PRESCAL_K_MAX,
> + * ii) prescale_k is minimized.
> + *
> + * The derivation proceeds as follows, with val = # of cycles for reqested

s/reqested/requested/

> + * period:
> + *
> + * for a given value of div_m we want the smallest prescale_k such that
> + *
> + * (val >> div_m) // (prescale_k + 1) ? 65536 (SUN20I_PWM_PCNTR_SIZE)
> + *
> + * This is equivalent to:
> + *
> + * (val >> div_m) ? 65536 * (prescale_k + 1) + prescale_k
> + * ? (val >> div_m) ? 65537 * prescale_k + 65536
> + * ? (val >> div_m) - 65536 ? 65537 * prescale_k
> + * ? ((val >> div_m) - 65536) / 65537 ? prescale_k
> + *
> + * As prescale_k is integer, this becomes
> + *
> + * ((val >> div_m) - 65536) // 65537 ? prescale_k
> + *
> + * And is minimized at
> + *
> + * ((val >> div_m) - 65536) // 65537
> + *
> + * Now we pick the smallest div_m that satifies prescale_k ? 255
> + * (i.e SUN20I_PWM_CTL_PRESCAL_K_MAX),
> + *
> + * ((val >> div_m) - 65536) // 65537 ? 255
> + * ? (val >> div_m) - 65536 ? 255 * 65537 + 65536
> + * ? val >> div_m ? 255 * 65537 + 2 * 65536
> + * ? val >> div_m < (255 * 65537 + 2 * 65536 + 1)
> + * ? div_m = fls((val) / (255 * 65537 + 2 * 65536 + 1))
> + *
> + * Suggested by Uwe Kleine-K?nig

Good man, I assume this is all sane then :-)

> + */
> +#define SUN20I_PWM_MAGIC			(255 * 65537 + 2 * 65536 + 1)
> +
> +struct sun20i_pwm_chip {
> +	struct clk *clk_bus, *clk_hosc, *clk_apb0;
> +	struct reset_control *rst;
> +	struct pwm_chip chip;
> +	void __iomem *base;
> +	/* Mutex to protect pwm apply state */
> +	struct mutex mutex;
> +};
> +
> +static inline struct sun20i_pwm_chip *to_sun20i_pwm_chip(struct pwm_chip *chip)
> +{
> +	return container_of(chip, struct sun20i_pwm_chip, chip);
> +}
> +
> +static inline u32 sun20i_pwm_readl(struct sun20i_pwm_chip *chip,
> +				   unsigned long offset)
> +{
> +	return readl(chip->base + offset);
> +}
> +
> +static inline void sun20i_pwm_writel(struct sun20i_pwm_chip *chip,
> +				     u32 val, unsigned long offset)
> +{
> +	writel(val, chip->base + offset);
> +}
> +
> +static int sun20i_pwm_get_state(struct pwm_chip *chip,
> +				struct pwm_device *pwm,
> +				struct pwm_state *state)
> +{
> +	struct sun20i_pwm_chip *sun20i_chip = to_sun20i_pwm_chip(chip);
> +	u16 ent_cycle, act_cycle, prescale_k;
> +	u64 clk_rate, tmp;
> +	u8 div_m;
> +	u32 val;
> +
> +	mutex_lock(&sun20i_chip->mutex);
> +
> +	val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_CLK_CFG(pwm->hwpwm));
> +	div_m = FIELD_GET(SUN20I_PWM_CLK_CFG_DIV_M, val);
> +	if (div_m > SUN20I_PWM_CLK_DIV_M_MAX)
> +		div_m = SUN20I_PWM_CLK_DIV_M_MAX;
> +
> +	if (FIELD_GET(SUN20I_PWM_CLK_CFG_SRC, val) == 0)
> +		clk_rate = clk_get_rate(sun20i_chip->clk_hosc);
> +	else
> +		clk_rate = clk_get_rate(sun20i_chip->clk_apb0);
> +
> +	val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_CTL(pwm->hwpwm));
> +	state->polarity = (SUN20I_PWM_CTL_ACT_STA & val) ?
> +			   PWM_POLARITY_NORMAL : PWM_POLARITY_INVERSED;
> +
> +	prescale_k = FIELD_GET(SUN20I_PWM_CTL_PRESCAL_K, val) + 1;
> +
> +	val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_ENABLE);
> +	state->enabled = (SUN20I_PWM_ENABLE_EN(pwm->hwpwm) & val) ? true : false;
> +
> +	val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_PERIOD(pwm->hwpwm));
> +
> +	mutex_unlock(&sun20i_chip->mutex);
> +
> +	act_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ACT_CYCLE, val);
> +	ent_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ENTIRE_CYCLE, val);
> +
> +	/*
> +	 * The duration of the active phase should not be longer
> +	 * than the duration of the period
> +	 */
> +	if (act_cycle > ent_cycle)
> +		act_cycle = ent_cycle;
> +
> +	tmp = ((u64)(act_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> +	state->duty_cycle = DIV_ROUND_UP_ULL(tmp, clk_rate);
> +	tmp = ((u64)(ent_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> +	state->period = DIV_ROUND_UP_ULL(tmp, clk_rate);

Please add a comment above this block that justifies assuming that the
multiplication doesn't overflow. Something like:

	We have act_cycle <= ent_cycle <= 0xffff, prescale_k <= 0x100,
	div_m <= 8. So the multiplication fits into an u64 without
	overflow.

> +
> +	return 0;
> +}
> +
> +static int sun20i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> +			    const struct pwm_state *state)
> +{
> +...
> +}

I didn't recheck all the logic in .apply in detail and will assume it is
sane for this round.

> +static const struct pwm_ops sun20i_pwm_ops = {
> +	.apply = sun20i_pwm_apply,
> +	.get_state = sun20i_pwm_get_state,
> +};
> +
> +static const struct of_device_id sun20i_pwm_dt_ids[] = {
> +	{ .compatible = "allwinner,sun20i-d1-pwm" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, sun20i_pwm_dt_ids);
> +
> +static int sun20i_pwm_probe(struct platform_device *pdev)
> +{
> +	struct sun20i_pwm_chip *sun20i_chip;
> +	int ret;
> +
> +	sun20i_chip = devm_kzalloc(&pdev->dev, sizeof(*sun20i_chip), GFP_KERNEL);
> +	if (!sun20i_chip)
> +		return -ENOMEM;
> +
> +	sun20i_chip->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(sun20i_chip->base))
> +		return PTR_ERR(sun20i_chip->base);
> +
> +	sun20i_chip->clk_bus = devm_clk_get_enabled(&pdev->dev, "bus");
> +	if (IS_ERR(sun20i_chip->clk_bus))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_bus),
> +				     "failed to get bus clock\n");
> +
> +	sun20i_chip->clk_hosc = devm_clk_get_enabled(&pdev->dev, "hosc");
> +	if (IS_ERR(sun20i_chip->clk_hosc))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_hosc),
> +				     "failed to get hosc clock\n");
> +
> +	sun20i_chip->clk_apb0 = devm_clk_get_enabled(&pdev->dev, "apb0");
> +	if (IS_ERR(sun20i_chip->clk_apb0))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_apb0),
> +				     "failed to get apb0 clock\n");
> +
> +	sun20i_chip->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> +	if (IS_ERR(sun20i_chip->rst))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->rst),
> +				     "failed to get bus reset\n");
> +
> +	ret = of_property_read_u32(pdev->dev.of_node, "allwinner,pwm-channels",
> +				   &sun20i_chip->chip.npwm);
> +	if (ret)
> +		sun20i_chip->chip.npwm = 8;
> +
> +	if (sun20i_chip->chip.npwm > 16)
> +		sun20i_chip->chip.npwm = 16;

Is it worth to emit an error message here? Something like:

	Limiting number of PWM lines from %u to 16

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/20240201/465ae1f0/attachment.sig>

From francesco at dolcini.it  Thu Feb  1 00:52:05 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Thu, 1 Feb 2024 09:52:05 +0100
Subject: [PATCH v2] spi: imx: fix the burst length at DMA mode and CPU
 mode
In-Reply-To: <VI1PR04MB5005EB37DD02F4E32D94336FE8432@VI1PR04MB5005.eurprd04.prod.outlook.com>
References: <20240131101916.437398-1-carlos.song@nxp.com>
 <20240131194207.GB12870@francesco-nb>
 <VI1PR04MB5005EB37DD02F4E32D94336FE8432@VI1PR04MB5005.eurprd04.prod.outlook.com>
Message-ID: <20240201085205.GA3906@francesco-nb>

On Thu, Feb 01, 2024 at 02:02:36AM +0000, Carlos Song wrote:
> > From: Francesco Dolcini <francesco at dolcini.it>
> > Add #include <linux/bits.h> given you are using BITS_PER_BYTE
> > 
> I found that <linux/property.h> has been included in spi-imx.c driver.
> And <linux/bits.h> has been included in <linux/property.h>.
> So I didn't add the "#include <linux/bits.h>" on purpose.

I think you should be explicit and include this header.
Code get refactored all the time and you can prevent issues this way.

Francesco




From piotr.firek at financialflows.pl  Thu Feb  1 00:50:53 2024
From: piotr.firek at financialflows.pl (Piotr Firek)
Date: Thu,  1 Feb 2024 08:50:53 GMT
Subject: =?UTF-8?Q?Prosz=C4=99_o_kontakt?=
Message-ID: <20240201074501-0.1.2f.8i4i.0.avgnkgo802@financialflows.pl>

Dzie? dobry,

Czy jest mo?liwo?? nawi?zania wsp??pracy z Pa?stwem?

Z ch?ci? porozmawiam z osob? zajmuj?c? si? dzia?aniami zwi?zanymi ze sprzeda??.

Pomagamy skutecznie pozyskiwa? nowych klient?w.

Zapraszam do kontaktu.


Pozdrawiam
Piotr Firek


From s-vadapalli at ti.com  Thu Feb  1 01:02:04 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 1 Feb 2024 14:32:04 +0530
Subject: [PATCH] dt-bindings: mfd: syscon: Add ti,k3-pcie-ctrl compatible
In-Reply-To: <2824fd42-d588-4a0b-b6f9-1e9cb6055d6a@linaro.org>
References: <20240131112342.1300893-1-s-vadapalli@ti.com>
 <be60e695-894e-4281-a62c-b77e45680293@ti.com>
 <91737281-8249-4fcb-b5bf-750c015b7c24@ti.com>
 <2824fd42-d588-4a0b-b6f9-1e9cb6055d6a@linaro.org>
Message-ID: <42d2afa0-27f6-457d-bf95-690c83ed42d5@ti.com>

Hello Krzysztof,

On 01/02/24 13:01, Krzysztof Kozlowski wrote:
> On 01/02/2024 05:48, Siddharth Vadapalli wrote:
>> Hello Andrew,
>>
>> On 31/01/24 21:43, Andrew Davis wrote:
>>> On 1/31/24 5:23 AM, Siddharth Vadapalli wrote:
>>>> The PCIE_CTRL registers within the CTRL_MMR space of TI's K3 SoCs are
>>>> used to configure the link speed, lane count and mode of operation of
>>>> the respective PCIe instance. Add compatible for allowing the PCIe
>>>> driver to obtain a regmap for the PCIE_CTRL register within the System
>>>> Controller device-tree node in order to configure the PCIe instance
>>>> accordingly.
>>>>
>>>> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
>>>> ---
>>>>
>>>> This patch is based on linux-next tagged next-20240131.
>>>>
>>>> ? Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
>>>> ? 1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml
>>>> b/Documentation/devicetree/bindings/mfd/syscon.yaml
>>>> index 084b5c2a2a3c..da571a24e21f 100644
>>>> --- a/Documentation/devicetree/bindings/mfd/syscon.yaml
>>>> +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
>>>> @@ -73,6 +73,7 @@ properties:
>>>> ??????????????? - rockchip,rv1126-qos
>>>> ??????????????? - starfive,jh7100-sysmain
>>>> ??????????????? - ti,am654-dss-oldi-io-ctrl
>>>> +????????????? - ti,k3-pcie-ctrl
>>>
>>> This might not be the same for all K3 devices, you should use
>>> the name of the first device which uses this, so:
>>>
>>> ti,j721e-pcie-ctrl
>>
>> It is the same for all K3 devices so far. However, since the convention appears
>> to be the first device that it is applicable to as you pointed out, I will post
>> the v2 patch for this accordingly.
> 
> This was repeated so many times... so one more. Compatibles are specific
> to SoC, not to family.
> 
> https://elixir.bootlin.com/linux/v6.1-rc1/source/Documentation/devicetree/bindings/writing-bindings.rst#L42

Thank you for reviewing the patch and sharing your feedback. I will make sure
not to repeat this in my future patches.

-- 
Regards,
Siddharth.


From Andrei.Simion at microchip.com  Thu Feb  1 01:02:12 2024
From: Andrei.Simion at microchip.com (Andrei.Simion at microchip.com)
Date: Thu, 1 Feb 2024 09:02:12 +0000
Subject: [PATCH v3] regulator: dt-bindings: microchip,mcp16502: convert to
 YAML
In-Reply-To: <d2c0c5dd-e1a2-4607-9177-f3855cb5601e@linaro.org>
References: <20240131130727.447738-1-andrei.simion@microchip.com>
 <d2c0c5dd-e1a2-4607-9177-f3855cb5601e@linaro.org>
Message-ID: <00417e83-ee1f-42f6-a48f-e7f5d9fa374f@microchip.com>

On 01.02.2024 10:40, Krzysztof Kozlowski wrote:
> [You don't often get email from krzysztof.kozlowski at linaro.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On 31/01/2024 14:07, Andrei Simion wrote:
>> Convert devicetree binding mcp16502-regulator.txt to YAML format.
>>
>> Signed-off-by: Andrei Simion <andrei.simion at microchip.com>
>> ---
>> Changes v2 -> v3:
>> - keep one line of regulators description
>> - add additionalProperties: false for regulators
>> - "description:" at the end for each properties
>>
>> Changes v1 -> v2:
>> - reverse subject prefixes
>> - line break after file "description:"
>> - drop description for reg
>> - drop regulator-name
>> - add regulator-initial-mode
>> - unevaluatedProperties just after $ref: regulator.yaml#
>> - additionalProperties  just before "required"
> 
> I missed it before, why did you move it? Previous placement was what we
> expect. I did not comment about it.
> 

Ah, I will place the "additionalProperties: false" as in my first attempt in v4. Thank you for clarification.

> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> 
> ---
> 
> This is an automated instruction, just in case, because many review tags
> are being ignored. If you know the process, you can skip it (please do
> not feel offended by me posting it here - no bad intentions intended).
> If you do not know the process, here is a short explanation:
> 
> Please add Acked-by/Reviewed-by/Tested-by tags when posting new
> versions, under or above your Signed-off-by tag. Tag is "received", when
> provided in a message replied to you on the mailing list. Tools like b4
> can help here. However, there's no need to repost patches *only* to add
> the tags. The upstream maintainer will do that for tags received on the
> version they apply.
> 
> https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577
> 
> Best regards,
> Krzysztof
> 

Best regards,
Andrei Simion



From rppt at linux.ibm.com  Thu Feb  1 01:00:41 2024
From: rppt at linux.ibm.com (Mike Rapoport)
Date: Thu, 1 Feb 2024 11:00:41 +0200
Subject: [PATCH] arm: flush: don't abuse pfn_valid() to check if pfn is
 in RAM
In-Reply-To: <8b50ca93-c164-ddfc-cd79-8f8525198a96@huawei.com>
References: <20240131125907.1006760-1-liuyongqiang13@huawei.com>
 <0da50102-3e87-49f7-b8f7-45cfcb4232d6@arm.com>
 <ZbqY12U/CXwAAu7A@shell.armlinux.org.uk>
 <edc4e8fa-af0a-46c2-bf07-20a0c4e20af5@arm.com>
 <8b50ca93-c164-ddfc-cd79-8f8525198a96@huawei.com>
Message-ID: <Zbtdue57RO0QScJM@linux.ibm.com>

Hi,

Please don't top-post to Linux mailing lists.

On Thu, Feb 01, 2024 at 04:00:04PM +0800, Yongqiang Liu wrote:
> Very appreciate it for extra explanation. Notice that commit 024591f9a6e0
> 
> ("arm: ioremap: don't abuse pfn_valid() to check if pfn is in RAM") use
> 
> memblock_is_map_memory() instead of pfn_valid() to check if a PFN is in
> 
> RAM or not, so I wrote the patch to solve this case.? Otherwise, when we
> 
> use pageblock align(4M) address of memory or uio, like :
> 
> ???? node?? 0: [mem 0x00000000c0c00000-0x00000000cc8fffff]
> ???? node?? 0: [mem 0x00000000d0000000-0x00000000da1fffff]
> 
> or uio address set like:
> 
> ?? 0xc0400000, 0x100000
> 
> the pfn_valid will return false as memblock_is_map_memory.

pfn_valid() should return false if and only if there is no struct page for
that pfn.

My understanding is that struct pages exist for the range of UIO addresses,
and hopefully they have PG_reserved bit set, so a better fix IMO would be
to check if the folio is !reserved.
 
> ? 2024/2/1 5:20, Robin Murphy ??:
> > On 2024-01-31 7:00 pm, Russell King (Oracle) wrote:
> > > On Wed, Jan 31, 2024 at 06:39:31PM +0000, Robin Murphy wrote:
> > > > On 31/01/2024 12:59 pm, Yongqiang Liu wrote:
> > > > > @@ -292,7 +293,7 @@ void __sync_icache_dcache(pte_t pteval)
> > > > > ?????????? /* only flush non-aliasing VIPT caches for exec mappings */
> > > > > ?????????? return;
> > > > > ?????? pfn = pte_pfn(pteval);
> > > > > -??? if (!pfn_valid(pfn))
> > > > > +??? if (!memblock_is_map_memory(PFN_PHYS(pfn)))
> > > > > ?????????? return;
> > > > > ?????? folio = page_folio(pfn_to_page(pfn));
> > > > 
> > > > Hmm, it's a bit odd in context, since pfn_valid() obviously
> > > > pairs with this
> > > > pfn_to_page(), whereas it's not necessarily clear that
> > > > memblock_is_map_memory() implies pfn_valid().
> > > > 
> > > > However, in this case we're starting from a PTE - rather than
> > > > going off to
> > > > do a slow scan of memblock to determine whether a round-trip through
> > > > page_address() is going to give back a mapped VA, can we not trivially
> > > > identify that from whether the PTE itself is valid?
> > > 
> > > Depends what you mean by "valid". If you're referring to pte_valid()
> > > and L_PTE_VALID then no.
> > > 
> > > On 32-bit non-LPAE, the valid bit is the same as the present bit, and
> > > needs to be set for the PTE to not fault. Any PTE that is mapping
> > > something will be "valid" whether it is memory or not, whether it is
> > > backed by a page or not.
> > > 
> > > pfn_valid() should be telling us whether the PFN is suitable to be
> > > passed to pfn_to_page(), and if we have a situation where pfn_valid()
> > > returns true, but pfn_to_page() returns an invalid page, then that in
> > > itself is a bug that needs to be fixed and probably has far reaching
> > > implications for the stability of the kernel.
> > 
> > Right, the problem here seems to be the opposite one, wherein we *do*
> > often have a valid struct page for an address which is reserved and thus
> > not mapped by the kernel, but seemingly we then take it down a path
> > which assumes anything !PageHighmem() is lowmem and dereferences
> > page_address() without looking.
> > 
> > However I realise I should have looked closer at the caller, and my idea
> > is futile since the PTE here is for a userspace mapping, not a kernel
> > VA, and is already pte_valid_user() && !pte_special(). Plus the fact
> > that the stack trace indicates an mmap() path suggests it most likely is
> > a legitimate mapping of some no-map carveout or MMIO region. Oh well. My
> > first point still stands, though - I think at least a comment to clarify
> > that assumption would be warranted.
> > 
> > Thanks,
> > Robin.
> > .

-- 
Sincerely yours,
Mike.


From maskray at google.com  Thu Feb  1 01:11:20 2024
From: maskray at google.com (Fangrui Song)
Date: Thu, 1 Feb 2024 01:11:20 -0800
Subject: [PATCH] arm64: jump_label: use constraint "S" instead of "i"
In-Reply-To: <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>
References: <20240131065322.1126831-1-maskray@google.com>
 <CAMj1kXGzADFWa7RmXyjWpCnQ=9hhz6i-XkN4PS1CboZ-kFL8dQ@mail.gmail.com>
 <ZbpEnDK3U/O24ng0@e133380.arm.com>
 <20240201045551.ajg4iqcajyowl2rh@google.com>
 <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>
Message-ID: <20240201091120.pbgr7ng6t2c36fut@google.com>

On 2024-02-01, Ard Biesheuvel wrote:
>On Thu, 1 Feb 2024 at 05:55, Fangrui Song <maskray at google.com> wrote:
>>
>> On 2024-01-31, Dave Martin wrote:
>> >On Wed, Jan 31, 2024 at 08:16:04AM +0100, Ard Biesheuvel wrote:
>> >> Hello Fangrui,
>> >>
>> >> On Wed, 31 Jan 2024 at 07:53, Fangrui Song <maskray at google.com> wrote:
>> >> >
>> >> > The constraint "i" seems to be copied from x86 (and with a redundant
>> >> > modifier "c"). It works with -fno-PIE but not with -fPIE/-fPIC in GCC's
>> >> > aarch64 port.
>> >
>> >(I'm not sure of the exact history, but the "c" may be inherited from
>> >arm, where an output modifier was needed to suppress the "#" that
>> >prefixes immediates in the traditional asm syntax.  This does not
>> >actually seem to be required for AArch64: rather while a # is allowed
>> >and still considered good style in handwritten asm code, the syntax
>> >doesn't require it, and the compiler doesn't emit it for "i" arguments,
>> >AFAICT.)
>>
>> The aarch64 one could be inherited from
>> arch/arm/include/asm/jump_label.h (2012), which could in turn be
>> inherited from x86 (2010).
>> Both the constraint "i" and the modifier "c" are generic..
>> For -fno-pic this combination can be used for every arch.
>>
>> >> > The constraint "S", which denotes a symbol reference (e.g. function,
>> >> > global variable) or label reference, is more appropriate, and has been
>> >> > available in GCC since 2012 and in Clang since 7.0.
>> >> >
>> >> > Signed-off-by: Fangrui Song <maskray at google.com>
>> >> > Link: https://maskray.me/blog/2024-01-30-raw-symbol-names-in-inline-assembly
>> >> > ---
>> >> >  arch/arm64/include/asm/jump_label.h | 8 ++++----
>> >> >  1 file changed, 4 insertions(+), 4 deletions(-)
>> >> >
>> >> > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
>> >> > index 48ddc0f45d22..31862b3bb33d 100644
>> >> > --- a/arch/arm64/include/asm/jump_label.h
>> >> > +++ b/arch/arm64/include/asm/jump_label.h
>> >> > @@ -23,9 +23,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
>> >> >                  "      .pushsection    __jump_table, \"aw\"    \n\t"
>> >> >                  "      .align          3                       \n\t"
>> >> >                  "      .long           1b - ., %l[l_yes] - .   \n\t"
>> >> > -                "      .quad           %c0 - .                 \n\t"
>> >> > +                "      .quad           %0 - .                  \n\t"
>> >> >                  "      .popsection                             \n\t"
>> >> > -                :  :  "i"(&((char *)key)[branch]) :  : l_yes);
>> >> > +                :  :  "S"(&((char *)key)[branch]) :  : l_yes);
>> >>
>> >> 'key' is not used as a raw symbol name. We should make this
>> >>
>> >> "    .quad   %0 + %1 - ."
>> >>
>> >> and
>> >>
>> >> ::  "S"(key), "i"(branch) :: l_yes);
>> >>
>> >> if we want to really clean this up.
>> >
>> >This hides more logic in the asm so it's arguably more cryptic
>> >(although the code is fairly cryptic to begin with -- I don't really
>> >see why the argument wasn't written as the equivalent
>> >(char *)key + branch...)
>>
>> I agree that using "S" and "i" would introduce complexity.
>> Using just "S" as this patch does should be clear.
>>
>> All of "i" "s" "S" support a symbol or label reference and a constant offset (can be zero),
>> (in object file, a symbol and an addend; in GCC's term, the sum of a SYMBOL_REF and a CONST_INT).
>>
>
>Taken the address of a struct, cast it to char[] and then index it
>using a boolean is rather disgusting, no?

I agree with you.

Hmm. Clang's constraint "S" implementation doesn't support a constant
offset, so
`static_key_false(&nf_hooks_needed[pf][hook])` in include/linux/netfilter.h:nf_hook
would not compile with Clang <= 18.

I have a patch https://github.com/llvm/llvm-project/pull/80255 , but
even if it is accepted and cherry-picked into the 18.x release branch,
if we still support older Clang, we cannot use "S" unconditionally.


So we probably need the following to prepare for -fPIE support in the
future:

diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
index 48ddc0f45d22..b8af2f8b0c99 100644
--- a/arch/arm64/include/asm/jump_label.h
+++ b/arch/arm64/include/asm/jump_label.h
@@ -15,6 +15,16 @@
  
  #define JUMP_LABEL_NOP_SIZE		AARCH64_INSN_SIZE
  
+/*
+ * Prefer "S" to support PIC. However, use "i" for Clang 18 and earlier as "S"
+ * on a symbol with a constant offset is not supported.
+ */
+#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 18
+#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
+#else
+#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "S"
+#endif
+
  static __always_inline bool arch_static_branch(struct static_key * const key,
  					       const bool branch)
  {
@@ -23,9 +33,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
  		 "	.pushsection	__jump_table, \"aw\"	\n\t"
  		 "	.align		3			\n\t"
  		 "	.long		1b - ., %l[l_yes] - .	\n\t"
-		 "	.quad		%c0 - .			\n\t"
+		 "	.quad		%0 + %1 - .		\n\t"
  		 "	.popsection				\n\t"
-		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
+		 :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);
  
  	return false;
  l_yes:
@@ -40,9 +50,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
  		 "	.pushsection	__jump_table, \"aw\"	\n\t"
  		 "	.align		3			\n\t"
  		 "	.long		1b - ., %l[l_yes] - .	\n\t"
-		 "	.quad		%c0 - .			\n\t"
+		 "	.quad		%0 + %1 - .		\n\t"
  		 "	.popsection				\n\t"
-		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
+		 :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);
  
  	return false;
  l_yes:


>> >Anyway, I don't think the "i" versys "S" distinction makes any
>> >difference without -fpic or equivalent, so it is not really relevant
>> >for the kernel (except that "S" breaks compatibility with older
>> >compilers...)
>> >
>> >
>> >I think the main advantage of "S" is that it stops you accidentally
>> >emitting undesirable relocations from asm code that is not written for
>> >the -fpic case.
>> >
>> >But just changing "i" to "S" is not sufficient to port asms to -fpic:
>> >the asms still need to be reviewed.
>> >
>> >
>> >So unless the asm has been reviewed for position-independence, it may
>> >anyway be better to stick with "i" so that the compiler actually chokes
>> >if someone tries to build the code with -fpic.
>>
>
>The virtual address of the kernel is randomized by KASLR, which relies
>on PIE linking, and this puts constraints on the permitted types of
>relocations.
>
>IOW, we basically already build the kernel as PIC code, but without
>relying on -fPIC, because that triggers some behaviors that only make
>sense for shared objects in user space.
>
>> >Since we are not trying to run arbitraily many running kernels in a
>> >common address space (and not likely to do that), I'm not sure that we
>> >would ever build the kernel with -fpic except for a few special-case
>> >bits like the EFI stub and vDSO... unless I've missed something?
>> >
>
>Yes, KASLR. The number of kernels is not the point, the point is that
>the virtual load address of the kernel is usually decided at boot, and
>so the code needs to be generated to accommodate that.
>
>> >If there's another reason why "S" is advantageous though, I'm happy to
>> >be corrected.
>>
>> I remember that Ard has an RFC
>> https://lore.kernel.org/linux-arm-kernel/20220427171241.2426592-1-ardb at kernel.org/
>> "[RFC PATCH 0/2] arm64: use PIE code generation for KASLR kernel"
>> and see some recent PIE codegen patches.
>>
>> > Building the KASLR kernel without -fpie but linking it with -pie works
>> > in practice, but it is not something that is explicitly supported by the
>> > toolchains - it happens to work because the default 'small' code model
>> > used by both GCC and Clang relies mostly on ADRP+ADD/LDR to generate
>> > symbol references.
>>
>> I agree that current -fno-PIE with -shared -Bsymbolic linking is a hack
>> that works as a conincidence, not guaranteed by the toolchain.
>> This jump_label improvement (with no object file difference) fixes an
>> obstacle.
>
>If we can get the guaranteed behavior of #pragma GCC visibility
>push(hidden) from a command line option, we should build the core
>kernel with -fpie instead. (Modules are partially linked objects, so
>they can be built non-PIC as before)
>

I believe we don't have such a GCC option, but the effect can be
simulated by -include hidden.h ...


From anshuman.khandual at arm.com  Thu Feb  1 01:21:39 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 1 Feb 2024 14:51:39 +0530
Subject: [PATCH RFC v3 30/35] arm64: mte: ptrace: Handle pages with
 missing tag storage
In-Reply-To: <20240125164256.4147-31-alexandru.elisei@arm.com>
References: <20240125164256.4147-1-alexandru.elisei@arm.com>
 <20240125164256.4147-31-alexandru.elisei@arm.com>
Message-ID: <30278898-c4b2-4dd6-ba68-a19575f81a65@arm.com>



On 1/25/24 22:12, Alexandru Elisei wrote:
> A page can end up mapped in a MTE enabled VMA without the corresponding tag
> storage block reserved. Tag accesses made by ptrace in this case can lead
> to the wrong tags being read or memory corruption for the process that is
> using the tag storage memory as data.
> 
> Reserve tag storage by treating ptrace accesses like a fault.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> ---
> 
> Changes since rfc v2:
> 
> * New patch, issue reported by Peter Collingbourne.
> 
>  arch/arm64/kernel/mte.c | 26 ++++++++++++++++++++++++--
>  1 file changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
> index faf09da3400a..b1fa02dad4fd 100644
> --- a/arch/arm64/kernel/mte.c
> +++ b/arch/arm64/kernel/mte.c
> @@ -412,10 +412,13 @@ static int __access_remote_tags(struct mm_struct *mm, unsigned long addr,
>  	while (len) {
>  		struct vm_area_struct *vma;
>  		unsigned long tags, offset;
> +		unsigned int fault_flags;
> +		struct page *page;
> +		vm_fault_t ret;
>  		void *maddr;
> -		struct page *page = get_user_page_vma_remote(mm, addr,
> -							     gup_flags, &vma);
>  
> +get_page:
> +		page = get_user_page_vma_remote(mm, addr, gup_flags, &vma);

But if there is valid page returned here in the first GUP attempt, will there
still be a subsequent handle_mm_fault() on the same vma and addr ?

>  		if (IS_ERR(page)) {
>  			err = PTR_ERR(page);
>  			break;
> @@ -433,6 +436,25 @@ static int __access_remote_tags(struct mm_struct *mm, unsigned long addr,
>  			put_page(page);
>  			break;
>  		}
> +
> +		if (tag_storage_enabled() && !page_tag_storage_reserved(page)) {

Should not '!page' be checked here as well ?

> +			fault_flags = FAULT_FLAG_DEFAULT | \
> +				      FAULT_FLAG_USER | \
> +				      FAULT_FLAG_REMOTE | \
> +				      FAULT_FLAG_ALLOW_RETRY | \
> +				      FAULT_FLAG_RETRY_NOWAIT;
> +			if (write)
> +				fault_flags |= FAULT_FLAG_WRITE;
> +
> +			put_page(page);
> +			ret = handle_mm_fault(vma, addr, fault_flags, NULL);
> +			if (ret & VM_FAULT_ERROR) {
> +				err = -EFAULT;
> +				break;
> +			}
> +			goto get_page;
> +		}
> +
>  		WARN_ON_ONCE(!page_mte_tagged(page));
>  
>  		/* limit access to the end of the page */


From krzk at kernel.org  Thu Feb  1 01:22:55 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 10:22:55 +0100
Subject: [PATCH RFC/RFT v2 2/4] dt-bindings: riscv: Add Svvptc ISA
 extension description
In-Reply-To: <20240131155929.169961-3-alexghiti@rivosinc.com>
References: <20240131155929.169961-1-alexghiti@rivosinc.com>
 <20240131155929.169961-3-alexghiti@rivosinc.com>
Message-ID: <d47bc2dd-17e1-47b3-9c8f-ac97048ca660@kernel.org>

On 31/01/2024 16:59, Alexandre Ghiti wrote:
> Add description for the Svvptc ISA extension which was ratified recently.
> 
> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> ---

Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.

Tools like b4 or scripts_getmaintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, use mainline), work on fork of kernel (don't, use
mainline) or you ignore some maintainers (really don't). Just use b4 and
everything should be fine, although remember about `b4 prep
--auto-to-cc` if you added new patches to the patchset.

You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time, thus I will skip this patch entirely till you follow
the process allowing the patch to be tested.

Please kindly resend and include all necessary To/Cc entries.


Best regards,
Krzysztof



From linux at armlinux.org.uk  Thu Feb  1 01:32:41 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 1 Feb 2024 09:32:41 +0000
Subject: [PATCH 00/13] ARM: OMAP2+: fix a bunch of kernel-doc warnings
In-Reply-To: <e6692a04-142c-4df4-83dc-534ab27a55f6@infradead.org>
References: <20240117011004.22669-1-rdunlap@infradead.org>
 <20240117131305.GP5185@atomide.com>
 <e6692a04-142c-4df4-83dc-534ab27a55f6@infradead.org>
Message-ID: <ZbtlOWcGglCeYj6X@shell.armlinux.org.uk>

On Wed, Jan 17, 2024 at 08:52:16AM -0800, Randy Dunlap wrote:
> 
> 
> On 1/17/24 05:13, Tony Lindgren wrote:
> > * Randy Dunlap <rdunlap at infradead.org> [240117 01:10]:
> >> Fix many kernel-doc warnings in arch/arm/mach-omap2/:
> > 
> > Thanks for fixing these. These are unlikely to conflict with anything so
> > please queue them along with other clean-up:
> > 
> > Acked-by: Tony Lindgren <tony at atomide.com>
> > 
> > Or alternatively let me know if you want me to apply them.
> 
> Yes, please go ahead and apply them.

If you intend people other than me to apply patches, then please do not
copy the patches to the patch system. I now have to go through all 16
patches and search the mailing list to find out what happened... and so
far for the few I've checked, other people have applied them. So I'm
coming to the conclusion I should just discard the entire lot.

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


From angelogioacchino.delregno at collabora.com  Thu Feb  1 01:44:07 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 1 Feb 2024 10:44:07 +0100
Subject: [PATCH v9 05/21] virt: geniezone: Add vm support
In-Reply-To: <20240129083302.26044-6-yi-de.wu@mediatek.com>
References: <20240129083302.26044-1-yi-de.wu@mediatek.com>
 <20240129083302.26044-6-yi-de.wu@mediatek.com>
Message-ID: <e772e44f-9c60-4c4b-8054-957b07180c45@collabora.com>

Il 29/01/24 09:32, Yi-De Wu ha scritto:
> From: "Yingshiuan Pan" <yingshiuan.pan at mediatek.com>
> 
> The VM component is responsible for setting up the capability and memory
> management for the protected VMs. The capability is mainly about the
> lifecycle control and boot context initialization.
> 
> Signed-off-by: Yingshiuan Pan <yingshiuan.pan at mediatek.com>
> Signed-off-by: Jerry Wang <ze-yu.wang at mediatek.com>
> Signed-off-by: Liju Chen <liju-clr.chen at mediatek.com>
> Signed-off-by: Yi-De Wu <yi-de.wu at mediatek.com>
> ---
>   MAINTAINERS                             |   1 +
>   arch/arm64/geniezone/gzvm_arch_common.h |   9 ++
>   arch/arm64/geniezone/vm.c               |  29 +++++++
>   drivers/virt/geniezone/Makefile         |   2 +-
>   drivers/virt/geniezone/gzvm_main.c      |  19 +++++
>   drivers/virt/geniezone/gzvm_vm.c        | 107 ++++++++++++++++++++++++
>   include/linux/gzvm_drv.h                |  26 ++++++
>   include/uapi/linux/gzvm.h               |  25 ++++++
>   8 files changed, 217 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/virt/geniezone/gzvm_vm.c
>   create mode 100644 include/uapi/linux/gzvm.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 0cb2d0599469..3ecac8794ba9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -9022,6 +9022,7 @@ F:	Documentation/virt/geniezone/
>   F:	arch/arm64/geniezone/
>   F:	drivers/virt/geniezone/
>   F:	include/linux/gzvm_drv.h
> +F:	include/uapi/linux/gzvm.h
>   
>   GENWQE (IBM Generic Workqueue Card)
>   M:	Frank Haverkamp <haver at linux.ibm.com>
> diff --git a/arch/arm64/geniezone/gzvm_arch_common.h b/arch/arm64/geniezone/gzvm_arch_common.h
> index f5bddcfe3a1f..fdaa7849353d 100644
> --- a/arch/arm64/geniezone/gzvm_arch_common.h
> +++ b/arch/arm64/geniezone/gzvm_arch_common.h
> @@ -9,6 +9,8 @@
>   #include <linux/arm-smccc.h>
>   
>   enum {
> +	GZVM_FUNC_CREATE_VM = 0,


	GZVM_FUNC_CREATE_VM,
	GZVM_FUNC_DESTROY_VM,

The first one will always be zero by default, subsequent members are always
incremental anyway.

> +	GZVM_FUNC_DESTROY_VM = 1,
>   	GZVM_FUNC_PROBE = 12,
>   	NR_GZVM_FUNC,
>   };
> @@ -19,6 +21,8 @@ enum {
>   	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64,	\
>   			   SMC_ENTITY_MTK, (GZVM_FUNCID_START + (func)))
>   
> +#define MT_HVC_GZVM_CREATE_VM		GZVM_HCALL_ID(GZVM_FUNC_CREATE_VM)
> +#define MT_HVC_GZVM_DESTROY_VM		GZVM_HCALL_ID(GZVM_FUNC_DESTROY_VM)
>   #define MT_HVC_GZVM_PROBE		GZVM_HCALL_ID(GZVM_FUNC_PROBE)
>   
>   /**
> @@ -41,4 +45,9 @@ int gzvm_hypcall_wrapper(unsigned long a0, unsigned long a1,
>   			 unsigned long a6, unsigned long a7,
>   			 struct arm_smccc_res *res);
>   
> +static inline u16 get_vmid_from_tuple(unsigned int tuple)
> +{
> +	return (u16)(tuple >> 16);

As far as I can understand, this tuple is a union of two u16.

If you add that union, you won't even need this function anymore.

> +}
> +
>   #endif /* __GZVM_ARCH_COMMON_H__ */
> diff --git a/arch/arm64/geniezone/vm.c b/arch/arm64/geniezone/vm.c
> index e313aadec212..a15bad13c2ee 100644
> --- a/arch/arm64/geniezone/vm.c
> +++ b/arch/arm64/geniezone/vm.c
> @@ -7,9 +7,12 @@
>   #include <linux/err.h>
>   #include <linux/uaccess.h>
>   
> +#include <linux/gzvm.h>
>   #include <linux/gzvm_drv.h>
>   #include "gzvm_arch_common.h"
>   
> +#define PAR_PA47_MASK ((((1UL << 48) - 1) >> 12) << 12)

This value is unused. Anyway, isn't this just GENMASK_ULL(47, 12) ?!

> +
>   /**
>    * gzvm_hypcall_wrapper() - the wrapper for hvc calls
>    * @a0: arguments passed in registers 0
> @@ -45,3 +48,29 @@ int gzvm_arch_probe(void)
>   
>   	return 0;
>   }
> +
> +/**
> + * gzvm_arch_create_vm() - create vm
> + * @vm_type: VM type. Only supports Linux VM now.
> + *
> + * Return:
> + * * positive value	- VM ID
> + * * -ENOMEM		- Memory not enough for storing VM data
> + */
> +int gzvm_arch_create_vm(unsigned long vm_type)
> +{
> +	struct arm_smccc_res res;
> +	int ret;
> +
> +	ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_CREATE_VM, vm_type, 0, 0, 0, 0,
> +				   0, 0, &res);
> +	return ret ? ret : res.a1;
> +}
> +
> +int gzvm_arch_destroy_vm(u16 vm_id)
> +{
> +	struct arm_smccc_res res;
> +
> +	return gzvm_hypcall_wrapper(MT_HVC_GZVM_DESTROY_VM, vm_id, 0, 0, 0, 0,
> +				    0, 0, &res);
> +}
> diff --git a/drivers/virt/geniezone/Makefile b/drivers/virt/geniezone/Makefile
> index 8c1f0053e773..066efddc0b9c 100644
> --- a/drivers/virt/geniezone/Makefile
> +++ b/drivers/virt/geniezone/Makefile
> @@ -6,5 +6,5 @@
>   
>   GZVM_DIR ?= ../../../drivers/virt/geniezone
>   
> -gzvm-y := $(GZVM_DIR)/gzvm_main.o
> +gzvm-y := $(GZVM_DIR)/gzvm_main.o $(GZVM_DIR)/gzvm_vm.o
>   
> diff --git a/drivers/virt/geniezone/gzvm_main.c b/drivers/virt/geniezone/gzvm_main.c
> index f7d4f0646d97..4e7d60067c55 100644
> --- a/drivers/virt/geniezone/gzvm_main.c
> +++ b/drivers/virt/geniezone/gzvm_main.c
> @@ -4,6 +4,7 @@
>    */
>   
>   #include <linux/device.h>
> +#include <linux/file.h>
>   #include <linux/kdev_t.h>
>   #include <linux/miscdevice.h>
>   #include <linux/module.h>
> @@ -40,7 +41,24 @@ int gzvm_err_to_errno(unsigned long err)
>   	return -EINVAL;
>   }
>   
> +static long gzvm_dev_ioctl(struct file *filp, unsigned int cmd,
> +			   unsigned long user_args)
> +{
> +	long ret;
> +
> +	switch (cmd) {
> +	case GZVM_CREATE_VM:
> +		ret = gzvm_dev_ioctl_create_vm(user_args);
> +		return ret;

return gzvm_dev_ioctl_create_vm(user_args);

> +	default:
> +		break;
> +	}
> +
> +	return -ENOTTY;
> +}
> +
>   static const struct file_operations gzvm_chardev_ops = {
> +	.unlocked_ioctl = gzvm_dev_ioctl,
>   	.llseek		= noop_llseek,
>   };
>   
> @@ -62,6 +80,7 @@ static int gzvm_drv_probe(struct platform_device *pdev)
>   
>   static int gzvm_drv_remove(struct platform_device *pdev)
>   {
> +	gzvm_destroy_all_vms();
>   	misc_deregister(&gzvm_dev);
>   	return 0;
>   }
> diff --git a/drivers/virt/geniezone/gzvm_vm.c b/drivers/virt/geniezone/gzvm_vm.c
> new file mode 100644
> index 000000000000..d5e850af924a
> --- /dev/null
> +++ b/drivers/virt/geniezone/gzvm_vm.c
> @@ -0,0 +1,107 @@

..snip..

> diff --git a/include/linux/gzvm_drv.h b/include/linux/gzvm_drv.h
> index 907f2f984de9..f1dce23838e4 100644
> --- a/include/linux/gzvm_drv.h
> +++ b/include/linux/gzvm_drv.h
> @@ -6,6 +6,12 @@
>   #ifndef __GZVM_DRV_H__
>   #define __GZVM_DRV_H__
>   
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/gzvm.h>
> +
> +#define INVALID_VM_ID   0xffff
> +
>   /*
>    * These are the definitions of APIs between GenieZone hypervisor and driver,
>    * there's no need to be visible to uapi. Furthermore, we need GenieZone
> @@ -17,9 +23,29 @@
>   #define ERR_NOT_IMPLEMENTED     (-27)
>   #define ERR_FAULT               (-40)
>   
> +/*
> + * The following data structures are for data transferring between driver and
> + * hypervisor, and they're aligned with hypervisor definitions
> + */
> +
> +struct gzvm {
> +	/* userspace tied to this vm */
> +	struct mm_struct *mm;
> +	/* lock for list_add*/

Why are you not using kerneldoc to document this structure?

After all, you're already partially documenting it.

> +	struct mutex lock;
> +	struct list_head vm_list;
> +	u16 vm_id;
> +};
> +
> +int gzvm_dev_ioctl_create_vm(unsigned long vm_type);
> +
>   int gzvm_err_to_errno(unsigned long err);
>   

Why is there a trailing space on this function sig?

Regards,
Angelo



From angelogioacchino.delregno at collabora.com  Thu Feb  1 01:44:06 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 1 Feb 2024 10:44:06 +0100
Subject: [PATCH v9 09/21] virt: geniezone: Add vcpu support
In-Reply-To: <20240129083302.26044-10-yi-de.wu@mediatek.com>
References: <20240129083302.26044-1-yi-de.wu@mediatek.com>
 <20240129083302.26044-10-yi-de.wu@mediatek.com>
Message-ID: <c117f6a7-59ea-4291-aa70-7c363d928ff7@collabora.com>

Il 29/01/24 09:32, Yi-De Wu ha scritto:
> From: "Yingshiuan Pan" <yingshiuan.pan at mediatek.com>
> 
> VMM use this interface to create vcpu instance which is a fd, and this
> fd will be for any vcpu operations, such as setting vcpu registers and
> accepts the most important ioctl GZVM_VCPU_RUN which requests GenieZone
> hypervisor to do context switch to execute VM's vcpu context.
> 
> Signed-off-by: Yingshiuan Pan <yingshiuan.pan at mediatek.com>
> Signed-off-by: Jerry Wang <ze-yu.wang at mediatek.com>
> Signed-off-by: kevenny hsieh <kevenny.hsieh at mediatek.com>
> Signed-off-by: Liju Chen <liju-clr.chen at mediatek.com>
> Signed-off-by: Yi-De Wu <yi-de.wu at mediatek.com>
> ---
>   arch/arm64/geniezone/Makefile           |   2 +-
>   arch/arm64/geniezone/gzvm_arch_common.h |  30 +++
>   arch/arm64/geniezone/vcpu.c             |  80 ++++++++
>   arch/arm64/geniezone/vm.c               |  12 ++
>   drivers/virt/geniezone/Makefile         |   2 +-
>   drivers/virt/geniezone/gzvm_vcpu.c      | 251 ++++++++++++++++++++++++
>   drivers/virt/geniezone/gzvm_vm.c        |   5 +
>   include/linux/gzvm_drv.h                |  23 +++
>   include/uapi/linux/gzvm.h               | 163 +++++++++++++++
>   9 files changed, 566 insertions(+), 2 deletions(-)
>   create mode 100644 arch/arm64/geniezone/vcpu.c
>   create mode 100644 drivers/virt/geniezone/gzvm_vcpu.c
> 
> diff --git a/arch/arm64/geniezone/Makefile b/arch/arm64/geniezone/Makefile
> index 2957898cdd05..69b0a4abeab0 100644
> --- a/arch/arm64/geniezone/Makefile
> +++ b/arch/arm64/geniezone/Makefile
> @@ -4,6 +4,6 @@
>   #
>   include $(srctree)/drivers/virt/geniezone/Makefile
>   
> -gzvm-y += vm.o
> +gzvm-y += vm.o vcpu.o
>   
>   obj-$(CONFIG_MTK_GZVM) += gzvm.o
> diff --git a/arch/arm64/geniezone/gzvm_arch_common.h b/arch/arm64/geniezone/gzvm_arch_common.h
> index 383af0829f11..684c35e2d9bc 100644
> --- a/arch/arm64/geniezone/gzvm_arch_common.h
> +++ b/arch/arm64/geniezone/gzvm_arch_common.h
> @@ -11,9 +11,15 @@
>   enum {
>   	GZVM_FUNC_CREATE_VM = 0,
>   	GZVM_FUNC_DESTROY_VM = 1,
> +	GZVM_FUNC_CREATE_VCPU = 2,
> +	GZVM_FUNC_DESTROY_VCPU = 3,
>   	GZVM_FUNC_SET_MEMREGION = 4,
> +	GZVM_FUNC_RUN = 5,
> +	GZVM_FUNC_GET_ONE_REG = 8,
> +	GZVM_FUNC_SET_ONE_REG = 9,
>   	GZVM_FUNC_PROBE = 12,
>   	GZVM_FUNC_ENABLE_CAP = 13,
> +	GZVM_FUNC_INFORM_EXIT = 14,
>   	NR_GZVM_FUNC,
>   };
>   
> @@ -25,9 +31,15 @@ enum {
>   
>   #define MT_HVC_GZVM_CREATE_VM		GZVM_HCALL_ID(GZVM_FUNC_CREATE_VM)
>   #define MT_HVC_GZVM_DESTROY_VM		GZVM_HCALL_ID(GZVM_FUNC_DESTROY_VM)
> +#define MT_HVC_GZVM_CREATE_VCPU		GZVM_HCALL_ID(GZVM_FUNC_CREATE_VCPU)
> +#define MT_HVC_GZVM_DESTROY_VCPU	GZVM_HCALL_ID(GZVM_FUNC_DESTROY_VCPU)
>   #define MT_HVC_GZVM_SET_MEMREGION	GZVM_HCALL_ID(GZVM_FUNC_SET_MEMREGION)
> +#define MT_HVC_GZVM_RUN			GZVM_HCALL_ID(GZVM_FUNC_RUN)
> +#define MT_HVC_GZVM_GET_ONE_REG		GZVM_HCALL_ID(GZVM_FUNC_GET_ONE_REG)
> +#define MT_HVC_GZVM_SET_ONE_REG		GZVM_HCALL_ID(GZVM_FUNC_SET_ONE_REG)
>   #define MT_HVC_GZVM_PROBE		GZVM_HCALL_ID(GZVM_FUNC_PROBE)
>   #define MT_HVC_GZVM_ENABLE_CAP		GZVM_HCALL_ID(GZVM_FUNC_ENABLE_CAP)
> +#define MT_HVC_GZVM_INFORM_EXIT		GZVM_HCALL_ID(GZVM_FUNC_INFORM_EXIT)
>   
>   /**
>    * gzvm_hypcall_wrapper() - the wrapper for hvc calls
> @@ -54,4 +66,22 @@ static inline u16 get_vmid_from_tuple(unsigned int tuple)
>   	return (u16)(tuple >> 16);
>   }
>   
> +static inline u16 get_vcpuid_from_tuple(unsigned int tuple)
> +{
> +	return (u16)(tuple & 0xffff);
> +}
> +
> +static inline unsigned int
> +assemble_vm_vcpu_tuple(u16 vmid, u16 vcpuid)
> +{
> +	return ((unsigned int)vmid << 16 | vcpuid);

A union could be useful for this one too.

> +}
> +
> +static inline void
> +disassemble_vm_vcpu_tuple(unsigned int tuple, u16 *vmid, u16 *vcpuid)
> +{
> +	*vmid = get_vmid_from_tuple(tuple);
> +	*vcpuid = get_vcpuid_from_tuple(tuple);
> +}
> +
>   #endif /* __GZVM_ARCH_COMMON_H__ */
> diff --git a/arch/arm64/geniezone/vcpu.c b/arch/arm64/geniezone/vcpu.c
> new file mode 100644
> index 000000000000..f6670bd77ad6
> --- /dev/null
> +++ b/arch/arm64/geniezone/vcpu.c
> @@ -0,0 +1,80 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/err.h>
> +#include <linux/uaccess.h>
> +
> +#include <linux/gzvm.h>
> +#include <linux/gzvm_drv.h>
> +#include "gzvm_arch_common.h"
> +
> +int gzvm_arch_vcpu_update_one_reg(struct gzvm_vcpu *vcpu, __u64 reg_id,
> +				  bool is_write, __u64 *data)
> +{
> +	struct arm_smccc_res res;
> +	unsigned long a1;
> +	int ret;
> +
> +	a1 = assemble_vm_vcpu_tuple(vcpu->gzvm->vm_id, vcpu->vcpuid);

	if (is_write)
		return gzvm_hypcall_wrapper(MT_HVC_GZVM_GET_ONE_REG,
					   a1, reg_id, *data, 0, 0, 0, 0, &res);

	ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_GET_ONE_REG,
					   a1, reg_id, 0, 0, 0, 0, 0, &res);
	if (ret)
		return ret;

	*data = res.a1;

	return 0;
}


> +	if (!is_write) {
> +		ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_GET_ONE_REG,
> +					   a1, reg_id, 0, 0, 0, 0, 0, &res);

		if (ret)
			return ret;
		*data = res.a1;
	}

> +		if (ret == 0)
> +			*data = res.a1;
> +	} else {
> +		ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_SET_ONE_REG,
> +					   a1, reg_id, *data, 0, 0, 0, 0, &res);
> +	}
> +
> +	return ret;
> +}
> +
> +int gzvm_arch_vcpu_run(struct gzvm_vcpu *vcpu, __u64 *exit_reason)
> +{
> +	struct arm_smccc_res res;
> +	unsigned long a1;
> +	int ret;
> +
> +	a1 = assemble_vm_vcpu_tuple(vcpu->gzvm->vm_id, vcpu->vcpuid);
> +	ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_RUN, a1, 0, 0, 0, 0, 0,
> +				   0, &res);
> +	*exit_reason = res.a1;
> +	return ret;
> +}
> +
> +int gzvm_arch_destroy_vcpu(u16 vm_id, int vcpuid)
> +{
> +	struct arm_smccc_res res;
> +	unsigned long a1;
> +
> +	a1 = assemble_vm_vcpu_tuple(vm_id, vcpuid);
> +	gzvm_hypcall_wrapper(MT_HVC_GZVM_DESTROY_VCPU, a1, 0, 0, 0, 0, 0, 0,
> +			     &res);
> +
> +	return 0;
> +}
> +
> +/**
> + * gzvm_arch_create_vcpu() - Call smc to gz hypervisor to create vcpu
> + * @vm_id: vm id
> + * @vcpuid: vcpu id
> + * @run: Virtual address of vcpu->run
> + *
> + * Return: The wrapper helps caller to convert geniezone errno to Linux errno.
> + */
> +int gzvm_arch_create_vcpu(u16 vm_id, int vcpuid, void *run)
> +{
> +	struct arm_smccc_res res;
> +	unsigned long a1, a2;
> +	int ret;
> +
> +	a1 = assemble_vm_vcpu_tuple(vm_id, vcpuid);
> +	a2 = (__u64)virt_to_phys(run);
> +	ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_CREATE_VCPU, a1, a2, 0, 0, 0, 0,
> +				   0, &res);
> +
> +	return ret;
> +}
> diff --git a/arch/arm64/geniezone/vm.c b/arch/arm64/geniezone/vm.c
> index b6a2bfa98b43..1fac10b98c11 100644
> --- a/arch/arm64/geniezone/vm.c
> +++ b/arch/arm64/geniezone/vm.c
> @@ -37,6 +37,18 @@ int gzvm_hypcall_wrapper(unsigned long a0, unsigned long a1,
>   	return gzvm_err_to_errno(res->a0);
>   }
>   
> +int gzvm_arch_inform_exit(u16 vm_id)
> +{
> +	struct arm_smccc_res res;
> +	int ret;
> +
> +	ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_INFORM_EXIT, vm_id, 0, 0, 0, 0, 0, 0, &res);
> +	if (ret)
> +		return -ENXIO;
> +
> +	return 0;
> +}
> +
>   int gzvm_arch_probe(void)
>   {
>   	struct arm_smccc_res res;
> diff --git a/drivers/virt/geniezone/Makefile b/drivers/virt/geniezone/Makefile
> index 59fc4510a843..a630b919cda5 100644
> --- a/drivers/virt/geniezone/Makefile
> +++ b/drivers/virt/geniezone/Makefile
> @@ -7,4 +7,4 @@
>   GZVM_DIR ?= ../../../drivers/virt/geniezone
>   
>   gzvm-y := $(GZVM_DIR)/gzvm_main.o $(GZVM_DIR)/gzvm_vm.o \
> -	  $(GZVM_DIR)/gzvm_mmu.o
> +	  $(GZVM_DIR)/gzvm_mmu.o $(GZVM_DIR)/gzvm_vcpu.o
> diff --git a/drivers/virt/geniezone/gzvm_vcpu.c b/drivers/virt/geniezone/gzvm_vcpu.c
> new file mode 100644
> index 000000000000..39c471d0d257
> --- /dev/null
> +++ b/drivers/virt/geniezone/gzvm_vcpu.c
> @@ -0,0 +1,251 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + */
> +
> +#include <asm/sysreg.h>
> +#include <linux/anon_inodes.h>
> +#include <linux/device.h>
> +#include <linux/file.h>
> +#include <linux/mm.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/gzvm_drv.h>
> +
> +/* maximum size needed for holding an integer */
> +#define ITOA_MAX_LEN 12
> +
> +static long gzvm_vcpu_update_one_reg(struct gzvm_vcpu *vcpu,
> +				     void __user *argp,
> +				     bool is_write)
> +{
> +	struct gzvm_one_reg reg;
> +	void __user *reg_addr;
> +	u64 data = 0;
> +	u64 reg_size;
> +	long ret;
> +
> +	if (copy_from_user(&reg, argp, sizeof(reg)))
> +		return -EFAULT;
> +
> +	reg_addr = (void __user *)reg.addr;
> +	reg_size = (reg.id & GZVM_REG_SIZE_MASK) >> GZVM_REG_SIZE_SHIFT;
> +	reg_size = BIT(reg_size);
> +
> +	if (reg_size != 1 && reg_size != 2 && reg_size != 4 && reg_size != 8)
> +		return -EINVAL;
> +

	if (!is_write)
		return -EOPNOTSUPP;

	/* GZ hypervisor would filter out invalid vcpu register access */
	if (copy_from_user(&data, reg_addr, reg_size))
		return -EFAULT;

> +	if (is_write) {
> +		/* GZ hypervisor would filter out invalid vcpu register access */
> +		if (copy_from_user(&data, reg_addr, reg_size))
> +			return -EFAULT;
> +	} else {
> +		return -EOPNOTSUPP;
> +	}
> +
> +	ret = gzvm_arch_vcpu_update_one_reg(vcpu, reg.id, is_write, &data);
> +
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +/**
> + * gzvm_vcpu_run() - Handle vcpu run ioctl, entry point to guest and exit
> + *		     point from guest
> + * @vcpu: Pointer to struct gzvm_vcpu
> + * @argp: Pointer to struct gzvm_vcpu_run in userspace
> + *
> + * Return:
> + * * 0			- Success.
> + * * Negative		- Failure.
> + */
> +static long gzvm_vcpu_run(struct gzvm_vcpu *vcpu, void __user *argp)
> +{
> +	bool need_userspace = false;
> +	u64 exit_reason = 0;
> +
> +	if (copy_from_user(vcpu->run, argp, sizeof(struct gzvm_vcpu_run)))
> +		return -EFAULT;
> +
> +	for (int i = 0; i < ARRAY_SIZE(vcpu->run->padding1); i++) {
> +		if (vcpu->run->padding1[i])
> +			return -EINVAL;
> +	}
> +
> +	if (vcpu->run->immediate_exit == 1)
> +		return -EINTR;
> +
> +	while (!need_userspace && !signal_pending(current)) {
> +		gzvm_arch_vcpu_run(vcpu, &exit_reason);
> +
> +		switch (exit_reason) {
> +		case GZVM_EXIT_MMIO:
> +			need_userspace = true;
> +			break;
> +		/**
> +		 * it's geniezone's responsibility to fill corresponding data
> +		 * structure
> +		 */
> +		case GZVM_EXIT_HYPERCALL:
> +			fallthrough;
> +		case GZVM_EXIT_EXCEPTION:
> +			fallthrough;
> +		case GZVM_EXIT_DEBUG:
> +			fallthrough;
> +		case GZVM_EXIT_FAIL_ENTRY:
> +			fallthrough;
> +		case GZVM_EXIT_INTERNAL_ERROR:
> +			fallthrough;
> +		case GZVM_EXIT_SYSTEM_EVENT:
> +			fallthrough;
> +		case GZVM_EXIT_SHUTDOWN:
> +			need_userspace = true;
> +			break;
> +		case GZVM_EXIT_IRQ:
> +			fallthrough;
> +		case GZVM_EXIT_GZ:
> +			break;
> +		case GZVM_EXIT_UNKNOWN:
> +			fallthrough;
> +		default:
> +			pr_err("vcpu unknown exit\n");
> +			need_userspace = true;
> +			goto out;
> +		}
> +	}
> +
> +out:
> +	if (copy_to_user(argp, vcpu->run, sizeof(struct gzvm_vcpu_run)))
> +		return -EFAULT;
> +	if (signal_pending(current)) {
> +		// invoke hvc to inform gz to map memory

/* invoke ... */

> +		gzvm_arch_inform_exit(vcpu->gzvm->vm_id);
> +		return -ERESTARTSYS;
> +	}
> +	return 0;
> +}

Regards,
Angelo




From angelogioacchino.delregno at collabora.com  Thu Feb  1 01:44:10 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 1 Feb 2024 10:44:10 +0100
Subject: [PATCH v9 07/21] virt: geniezone: Add vm capability check
In-Reply-To: <20240129083302.26044-8-yi-de.wu@mediatek.com>
References: <20240129083302.26044-1-yi-de.wu@mediatek.com>
 <20240129083302.26044-8-yi-de.wu@mediatek.com>
Message-ID: <c027bf67-e9b2-4eb2-9dee-a47a9c3bdd8a@collabora.com>

Il 29/01/24 09:32, Yi-De Wu ha scritto:
> From: "Yingshiuan Pan" <yingshiuan.pan at mediatek.com>
> 
> Inquire the `capability support` on GenieZone hypervisor.
> Example:
> `GZVM_CAP_PROTECTED_VM` or `GZVM_CAP_VM_GPA_SIZE`.
> 
> Signed-off-by: Yingshiuan Pan <yingshiuan.pan at mediatek.com>
> Signed-off-by: Jerry Wang <ze-yu.wang at mediatek.com>
> Signed-off-by: kevenny hsieh <kevenny.hsieh at mediatek.com>
> Signed-off-by: Liju Chen <liju-clr.chen at mediatek.com>
> Signed-off-by: Yi-De Wu <yi-de.wu at mediatek.com>
> ---
>   arch/arm64/geniezone/gzvm_arch_common.h |   2 +
>   arch/arm64/geniezone/vm.c               | 122 ++++++++++++++++++++++++
>   drivers/virt/geniezone/gzvm_main.c      |  27 ++++++
>   drivers/virt/geniezone/gzvm_vm.c        |  21 ++++
>   include/linux/gzvm_drv.h                |   5 +
>   include/uapi/linux/gzvm.h               |  31 ++++++
>   6 files changed, 208 insertions(+)
> 
> diff --git a/arch/arm64/geniezone/gzvm_arch_common.h b/arch/arm64/geniezone/gzvm_arch_common.h
> index 2f66e496dfae..383af0829f11 100644
> --- a/arch/arm64/geniezone/gzvm_arch_common.h
> +++ b/arch/arm64/geniezone/gzvm_arch_common.h
> @@ -13,6 +13,7 @@ enum {
>   	GZVM_FUNC_DESTROY_VM = 1,
>   	GZVM_FUNC_SET_MEMREGION = 4,
>   	GZVM_FUNC_PROBE = 12,
> +	GZVM_FUNC_ENABLE_CAP = 13,

GZVM_FUNC_PROBE  = 12,
GZVM_FUNC_ENABLE_CAP,

>   	NR_GZVM_FUNC,
>   };
>   

Regards,
Angelo



From angelogioacchino.delregno at collabora.com  Thu Feb  1 01:44:07 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 1 Feb 2024 10:44:07 +0100
Subject: [PATCH v9 04/21] virt: geniezone: Add GenieZone hypervisor driver
In-Reply-To: <20240129083302.26044-5-yi-de.wu@mediatek.com>
References: <20240129083302.26044-1-yi-de.wu@mediatek.com>
 <20240129083302.26044-5-yi-de.wu@mediatek.com>
Message-ID: <ea4c8128-d2cb-43fb-aebf-0f4733e1248b@collabora.com>

Il 29/01/24 09:32, Yi-De Wu ha scritto:
> From: "Yingshiuan Pan" <yingshiuan.pan at mediatek.com>
> 
> GenieZone hypervisor(gzvm) is a type-1 hypervisor that supports various
> virtual machine types and provides security features such as TEE-like
> scenarios and secure boot. It can create guest VMs for security use
> cases and has virtualization capabilities for both platform and
> interrupt. Although the hypervisor can be booted independently, it
> requires the assistance of GenieZone hypervisor kernel driver(gzvm-ko)
> to leverage the ability of Linux kernel for vCPU scheduling, memory
> management, inter-VM communication and virtio backend support.
> 
> Add the basic hypervisor driver. Subsequent patches will add more
> supported features to this driver.
> 
> Signed-off-by: Yingshiuan Pan <yingshiuan.pan at mediatek.com>
> Signed-off-by: Jerry Wang <ze-yu.wang at mediatek.com>
> Signed-off-by: Liju Chen <liju-clr.chen at mediatek.com>
> Signed-off-by: Yi-De Wu <yi-de.wu at mediatek.com>
> ---
>   MAINTAINERS                             |  3 +
>   arch/arm64/Kbuild                       |  1 +
>   arch/arm64/geniezone/Makefile           |  9 +++
>   arch/arm64/geniezone/gzvm_arch_common.h | 44 ++++++++++++
>   arch/arm64/geniezone/vm.c               | 47 +++++++++++++
>   drivers/virt/Kconfig                    |  2 +
>   drivers/virt/geniezone/Kconfig          | 16 +++++
>   drivers/virt/geniezone/Makefile         | 10 +++
>   drivers/virt/geniezone/gzvm_main.c      | 89 +++++++++++++++++++++++++
>   include/linux/gzvm_drv.h                | 25 +++++++
>   10 files changed, 246 insertions(+)
>   create mode 100644 arch/arm64/geniezone/Makefile
>   create mode 100644 arch/arm64/geniezone/gzvm_arch_common.h
>   create mode 100644 arch/arm64/geniezone/vm.c
>   create mode 100644 drivers/virt/geniezone/Kconfig
>   create mode 100644 drivers/virt/geniezone/Makefile
>   create mode 100644 drivers/virt/geniezone/gzvm_main.c
>   create mode 100644 include/linux/gzvm_drv.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 17a8e20d2baa..0cb2d0599469 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -9019,6 +9019,9 @@ M:	Ze-Yu Wang <ze-yu.wang at mediatek.com>
>   M:	Yi-De Wu <yi-de.wu at mediatek.com>
>   F:	Documentation/devicetree/bindings/hypervisor/mediatek,geniezone-hyp.yaml
>   F:	Documentation/virt/geniezone/
> +F:	arch/arm64/geniezone/
> +F:	drivers/virt/geniezone/
> +F:	include/linux/gzvm_drv.h
>   
>   GENWQE (IBM Generic Workqueue Card)
>   M:	Frank Haverkamp <haver at linux.ibm.com>
> diff --git a/arch/arm64/Kbuild b/arch/arm64/Kbuild
> index 5bfbf7d79c99..0c3cca572919 100644
> --- a/arch/arm64/Kbuild
> +++ b/arch/arm64/Kbuild
> @@ -4,6 +4,7 @@ obj-$(CONFIG_KVM)	+= kvm/
>   obj-$(CONFIG_XEN)	+= xen/
>   obj-$(subst m,y,$(CONFIG_HYPERV))	+= hyperv/
>   obj-$(CONFIG_CRYPTO)	+= crypto/
> +obj-$(CONFIG_MTK_GZVM)	+= geniezone/
>   
>   # for cleaning
>   subdir- += boot
> diff --git a/arch/arm64/geniezone/Makefile b/arch/arm64/geniezone/Makefile
> new file mode 100644
> index 000000000000..2957898cdd05
> --- /dev/null
> +++ b/arch/arm64/geniezone/Makefile
> @@ -0,0 +1,9 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Main Makefile for gzvm, this one includes drivers/virt/geniezone/Makefile
> +#
> +include $(srctree)/drivers/virt/geniezone/Makefile
> +
> +gzvm-y += vm.o
> +
> +obj-$(CONFIG_MTK_GZVM) += gzvm.o
> diff --git a/arch/arm64/geniezone/gzvm_arch_common.h b/arch/arm64/geniezone/gzvm_arch_common.h
> new file mode 100644
> index 000000000000..f5bddcfe3a1f
> --- /dev/null
> +++ b/arch/arm64/geniezone/gzvm_arch_common.h
> @@ -0,0 +1,44 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + */
> +
> +#ifndef __GZVM_ARCH_COMMON_H__
> +#define __GZVM_ARCH_COMMON_H__
> +
> +#include <linux/arm-smccc.h>
> +
> +enum {
> +	GZVM_FUNC_PROBE = 12,
> +	NR_GZVM_FUNC,
> +};
> +
> +#define SMC_ENTITY_MTK			59
> +#define GZVM_FUNCID_START		(0x1000)
> +#define GZVM_HCALL_ID(func)						\
> +	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64,	\
> +			   SMC_ENTITY_MTK, (GZVM_FUNCID_START + (func)))
> +
> +#define MT_HVC_GZVM_PROBE		GZVM_HCALL_ID(GZVM_FUNC_PROBE)
> +
> +/**
> + * gzvm_hypcall_wrapper() - the wrapper for hvc calls
> + * @a0: arguments passed in registers 0
> + * @a1: arguments passed in registers 1
> + * @a2: arguments passed in registers 2
> + * @a3: arguments passed in registers 3
> + * @a4: arguments passed in registers 4
> + * @a5: arguments passed in registers 5
> + * @a6: arguments passed in registers 6
> + * @a7: arguments passed in registers 7
> + * @res: result values from registers 0 to 3
> + *
> + * Return: The wrapper helps caller to convert geniezone errno to Linux errno.
> + */
> +int gzvm_hypcall_wrapper(unsigned long a0, unsigned long a1,
> +			 unsigned long a2, unsigned long a3,
> +			 unsigned long a4, unsigned long a5,
> +			 unsigned long a6, unsigned long a7,
> +			 struct arm_smccc_res *res);
> +
> +#endif /* __GZVM_ARCH_COMMON_H__ */
> diff --git a/arch/arm64/geniezone/vm.c b/arch/arm64/geniezone/vm.c
> new file mode 100644
> index 000000000000..e313aadec212
> --- /dev/null
> +++ b/arch/arm64/geniezone/vm.c
> @@ -0,0 +1,47 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/err.h>
> +#include <linux/uaccess.h>
> +
> +#include <linux/gzvm_drv.h>
> +#include "gzvm_arch_common.h"
> +
> +/**
> + * gzvm_hypcall_wrapper() - the wrapper for hvc calls
> + * @a0: arguments passed in registers 0

argument passed in register 0

> + * @a1: arguments passed in registers 1
> + * @a2: arguments passed in registers 2
> + * @a3: arguments passed in registers 3
> + * @a4: arguments passed in registers 4
> + * @a5: arguments passed in registers 5
> + * @a6: arguments passed in registers 6
> + * @a7: arguments passed in registers 7

...in registe7

> + * @res: result values from registers 0 to 3
> + *
> + * Return: The wrapper helps caller to convert geniezone errno to Linux errno.
> + */
> +int gzvm_hypcall_wrapper(unsigned long a0, unsigned long a1,
> +			 unsigned long a2, unsigned long a3,
> +			 unsigned long a4, unsigned long a5,
> +			 unsigned long a6, unsigned long a7,
> +			 struct arm_smccc_res *res)
> +{
> +	arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
> +	return gzvm_err_to_errno(res->a0);
> +}
> +
> +int gzvm_arch_probe(void)
> +{
> +	struct arm_smccc_res res;
> +	int ret;
> +
> +	ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_PROBE, 0, 0, 0, 0, 0, 0, 0, &res);
> +	if (ret)
> +		return -ENXIO;
> +
> +	return 0;
> +}
> diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
> index 40129b6f0eca..b4e9bddbcee7 100644
> --- a/drivers/virt/Kconfig
> +++ b/drivers/virt/Kconfig
> @@ -50,4 +50,6 @@ source "drivers/virt/acrn/Kconfig"
>   
>   source "drivers/virt/coco/Kconfig"
>   
> +source "drivers/virt/geniezone/Kconfig"
> +
>   endif
> diff --git a/drivers/virt/geniezone/Kconfig b/drivers/virt/geniezone/Kconfig
> new file mode 100644
> index 000000000000..b17c06c91074
> --- /dev/null
> +++ b/drivers/virt/geniezone/Kconfig
> @@ -0,0 +1,16 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +config MTK_GZVM
> +	tristate "GenieZone Hypervisor driver for guest VM operation"
> +	depends on ARM64 && EVENTFD
> +	help
> +	  This driver, gzvm, enables to run guest VMs on MTK GenieZone
> +	  hypervisor. It exports kvm-like interfaces for VMM (e.g., crosvm) in
> +	  order to operate guest VMs on GenieZone hypervisor.
> +
> +	  GenieZone hypervisor now only supports MediaTek SoC and arm64
> +	  architecture.
> +
> +	  Select M if you want it be built as a module (gzvm.ko).
> +
> +	  If unsure, say N.
> diff --git a/drivers/virt/geniezone/Makefile b/drivers/virt/geniezone/Makefile
> new file mode 100644
> index 000000000000..8c1f0053e773
> --- /dev/null
> +++ b/drivers/virt/geniezone/Makefile
> @@ -0,0 +1,10 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Makefile for GenieZone driver, this file should be include in arch's
> +# to avoid two ko being generated.
> +#
> +
> +GZVM_DIR ?= ../../../drivers/virt/geniezone
> +
> +gzvm-y := $(GZVM_DIR)/gzvm_main.o
> +
> diff --git a/drivers/virt/geniezone/gzvm_main.c b/drivers/virt/geniezone/gzvm_main.c
> new file mode 100644
> index 000000000000..f7d4f0646d97
> --- /dev/null
> +++ b/drivers/virt/geniezone/gzvm_main.c
> @@ -0,0 +1,89 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/kdev_t.h>
> +#include <linux/miscdevice.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/gzvm_drv.h>
> +
> +/**
> + * gzvm_err_to_errno() - Convert geniezone return value to standard errno
> + *
> + * @err: Return value from geniezone function return
> + *
> + * Return: Standard errno
> + */
> +int gzvm_err_to_errno(unsigned long err)
> +{
> +	int gz_err = (int)err;
> +
> +	switch (gz_err) {
> +	case 0:
> +		return 0;
> +	case ERR_NO_MEMORY:
> +		return -ENOMEM;
> +	case ERR_NOT_SUPPORTED:

case ERR_NOT_SUPPORTED:
	fallthrough;
case ERR_NOT_IMPLEMENTED:
	return -EOPNOTSUPP;

> +		return -EOPNOTSUPP;
> +	case ERR_NOT_IMPLEMENTED:
> +		return -EOPNOTSUPP;
> +	case ERR_FAULT:
> +		return -EFAULT;
> +	default:
> +		break;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct file_operations gzvm_chardev_ops = {
> +	.llseek		= noop_llseek,
> +};
> +
> +static struct miscdevice gzvm_dev = {
> +	.minor = MISC_DYNAMIC_MINOR,
> +	.name = KBUILD_MODNAME,
> +	.fops = &gzvm_chardev_ops,
> +};
> +
> +static int gzvm_drv_probe(struct platform_device *pdev)
> +{
> +	if (gzvm_arch_probe() != 0) {
> +		dev_err(&pdev->dev, "Not found available conduit\n");
> +		return -ENODEV;
> +	}
> +
> +	return misc_register(&gzvm_dev);
> +}
> +
> +static int gzvm_drv_remove(struct platform_device *pdev)
> +{
> +	misc_deregister(&gzvm_dev);
> +	return 0;
> +}
> +
> +static const struct of_device_id gzvm_of_match[] = {
> +	{ .compatible = "mediatek,geniezone-hyp" },
> +	{/* sentinel */},
> +};
> +
> +static struct platform_driver gzvm_driver = {
> +	.probe = gzvm_drv_probe,
> +	.remove = gzvm_drv_remove,
> +	.driver = {
> +		.name = KBUILD_MODNAME,
> +		.owner = THIS_MODULE,
> +		.of_match_table = gzvm_of_match,
> +	},
> +};
> +
> +module_platform_driver(gzvm_driver);
> +
> +MODULE_DEVICE_TABLE(of, gzvm_of_match);
> +MODULE_AUTHOR("MediaTek");
> +MODULE_DESCRIPTION("GenieZone interface for VMM");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/gzvm_drv.h b/include/linux/gzvm_drv.h

Why is this not `include/linux/soc/mediatek/gzvm_drv.h`?!

That's MediaTek specific, so it should go there.

Regards,
Angelo

> new file mode 100644
> index 000000000000..907f2f984de9
> --- /dev/null
> +++ b/include/linux/gzvm_drv.h
> @@ -0,0 +1,25 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + */
> +
> +#ifndef __GZVM_DRV_H__
> +#define __GZVM_DRV_H__
> +
> +/*
> + * These are the definitions of APIs between GenieZone hypervisor and driver,
> + * there's no need to be visible to uapi. Furthermore, we need GenieZone
> + * specific error code in order to map to Linux errno
> + */
> +#define NO_ERROR                (0)
> +#define ERR_NO_MEMORY           (-5)
> +#define ERR_NOT_SUPPORTED       (-24)
> +#define ERR_NOT_IMPLEMENTED     (-27)
> +#define ERR_FAULT               (-40)
> +
> +int gzvm_err_to_errno(unsigned long err);
> +
> +/* arch-dependant functions */
> +int gzvm_arch_probe(void);
> +
> +#endif /* __GZVM_DRV_H__ */




From angelogioacchino.delregno at collabora.com  Thu Feb  1 01:44:12 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 1 Feb 2024 10:44:12 +0100
Subject: [PATCH v9 06/21] virt: geniezone: Add set_user_memory_region for
 vm
In-Reply-To: <20240129083302.26044-7-yi-de.wu@mediatek.com>
References: <20240129083302.26044-1-yi-de.wu@mediatek.com>
 <20240129083302.26044-7-yi-de.wu@mediatek.com>
Message-ID: <e43a6f6e-6e95-4cbd-9e73-49c129d5724e@collabora.com>

Il 29/01/24 09:32, Yi-De Wu ha scritto:
> From: "Yingshiuan Pan" <yingshiuan.pan at mediatek.com>
> 
> Direct use of physical memory from VMs is forbidden and designed to be
> dictated to the privilege models managed by GenieZone hypervisor for
> security reason. With the help of gzvm-ko, the hypervisor would be able
> to manipulate memory as objects. And the memory management is highly
> integrated with ARM 2-stage translation tables to convert VA to IPA to
> PA under proper security measures required by protected VMs.
> 
> Signed-off-by: Yingshiuan Pan <yingshiuan.pan at mediatek.com>
> Signed-off-by: Jerry Wang <ze-yu.wang at mediatek.com>
> Signed-off-by: Liju Chen <liju-clr.chen at mediatek.com>
> Signed-off-by: Yi-De Wu <yi-de.wu at mediatek.com>
> ---
>   arch/arm64/geniezone/gzvm_arch_common.h |   2 +
>   arch/arm64/geniezone/vm.c               |   9 ++
>   drivers/virt/geniezone/Makefile         |   1 -
>   drivers/virt/geniezone/gzvm_vm.c        | 110 ++++++++++++++++++++++++
>   include/linux/gzvm_drv.h                |  40 +++++++++
>   include/uapi/linux/gzvm.h               |  26 ++++++
>   6 files changed, 187 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/geniezone/gzvm_arch_common.h b/arch/arm64/geniezone/gzvm_arch_common.h
> index fdaa7849353d..2f66e496dfae 100644
> --- a/arch/arm64/geniezone/gzvm_arch_common.h
> +++ b/arch/arm64/geniezone/gzvm_arch_common.h
> @@ -11,6 +11,7 @@
>   enum {
>   	GZVM_FUNC_CREATE_VM = 0,
>   	GZVM_FUNC_DESTROY_VM = 1,
> +	GZVM_FUNC_SET_MEMREGION = 4,
>   	GZVM_FUNC_PROBE = 12,
>   	NR_GZVM_FUNC,
>   };
> @@ -23,6 +24,7 @@ enum {
>   
>   #define MT_HVC_GZVM_CREATE_VM		GZVM_HCALL_ID(GZVM_FUNC_CREATE_VM)
>   #define MT_HVC_GZVM_DESTROY_VM		GZVM_HCALL_ID(GZVM_FUNC_DESTROY_VM)
> +#define MT_HVC_GZVM_SET_MEMREGION	GZVM_HCALL_ID(GZVM_FUNC_SET_MEMREGION)
>   #define MT_HVC_GZVM_PROBE		GZVM_HCALL_ID(GZVM_FUNC_PROBE)
>   
>   /**
> diff --git a/arch/arm64/geniezone/vm.c b/arch/arm64/geniezone/vm.c
> index a15bad13c2ee..998d6498ac5e 100644
> --- a/arch/arm64/geniezone/vm.c
> +++ b/arch/arm64/geniezone/vm.c
> @@ -49,6 +49,15 @@ int gzvm_arch_probe(void)
>   	return 0;
>   }
>   
> +int gzvm_arch_set_memregion(u16 vm_id, size_t buf_size,
> +			    phys_addr_t region)
> +{
> +	struct arm_smccc_res res;
> +
> +	return gzvm_hypcall_wrapper(MT_HVC_GZVM_SET_MEMREGION, vm_id,
> +				    buf_size, region, 0, 0, 0, 0, &res);
> +}
> +
>   /**
>    * gzvm_arch_create_vm() - create vm
>    * @vm_type: VM type. Only supports Linux VM now.
> diff --git a/drivers/virt/geniezone/Makefile b/drivers/virt/geniezone/Makefile
> index 066efddc0b9c..25614ea3dea2 100644
> --- a/drivers/virt/geniezone/Makefile
> +++ b/drivers/virt/geniezone/Makefile
> @@ -7,4 +7,3 @@
>   GZVM_DIR ?= ../../../drivers/virt/geniezone
>   
>   gzvm-y := $(GZVM_DIR)/gzvm_main.o $(GZVM_DIR)/gzvm_vm.o
> -

Don't remove this line here - actually, don't introduce it in the first place...

> diff --git a/drivers/virt/geniezone/gzvm_vm.c b/drivers/virt/geniezone/gzvm_vm.c
> index d5e850af924a..326cc9e93d92 100644
> --- a/drivers/virt/geniezone/gzvm_vm.c
> +++ b/drivers/virt/geniezone/gzvm_vm.c
> @@ -15,6 +15,115 @@
>   static DEFINE_MUTEX(gzvm_list_lock);
>   static LIST_HEAD(gzvm_list);
>   
> +u64 gzvm_gfn_to_hva_memslot(struct gzvm_memslot *memslot, u64 gfn)
> +{
> +	u64 offset = gfn - memslot->base_gfn;

I'd check if `gfn` is less than `memslot->base_gfn` - that's a potential security
issue.

This means that this function should be

int gzvm_gfn_to_hva_memslot(struct gzvm_memslot *memslot, u64 gfn, u64 *hva_memslot)

if (gfn < memslot->base_gfn)
	return -EINVAL

offset = gfn - memslot->base_gfn;
*hva_memslot = memslot->userspace_addr + offset * PAGE_SIZE:

return 0;

> +
> +	return memslot->userspace_addr + offset * PAGE_SIZE;
> +}
> +
> +/**
> + * register_memslot_addr_range() - Register memory region to GenieZone
> + * @gzvm: Pointer to struct gzvm
> + * @memslot: Pointer to struct gzvm_memslot
> + *
> + * Return: 0 for success, negative number for error
> + */
> +static int
> +register_memslot_addr_range(struct gzvm *gzvm, struct gzvm_memslot *memslot)
> +{
> +	struct gzvm_memory_region_ranges *region;
> +	u32 buf_size = PAGE_SIZE * 2;
> +	u64 gfn;
> +
> +	region = alloc_pages_exact(buf_size, GFP_KERNEL);
> +	if (!region)
> +		return -ENOMEM;
> +
> +	region->slot = memslot->slot_id;
> +	region->total_pages = memslot->npages;
> +	gfn = memslot->base_gfn;
> +	region->gpa = PFN_PHYS(gfn);
> +
> +	if (gzvm_arch_set_memregion(gzvm->vm_id, buf_size,
> +				    virt_to_phys(region))) {
> +		pr_err("Failed to register memregion to hypervisor\n");
> +		free_pages_exact(region, buf_size);
> +		return -EFAULT;
> +	}
> +
> +	free_pages_exact(region, buf_size);
> +	return 0;
> +}
> +
> +/**
> + * gzvm_vm_ioctl_set_memory_region() - Set memory region of guest
> + * @gzvm: Pointer to struct gzvm.
> + * @mem: Input memory region from user.
> + *
> + * Return: 0 for success, negative number for error
> + *
> + * -EXIO		- The memslot is out-of-range
> + * -EFAULT		- Cannot find corresponding vma
> + * -EINVAL		- Region size and VMA size mismatch
> + */
> +static int
> +gzvm_vm_ioctl_set_memory_region(struct gzvm *gzvm,
> +				struct gzvm_userspace_memory_region *mem)
> +{
> +	struct vm_area_struct *vma;
> +	struct gzvm_memslot *memslot;
> +	unsigned long size;
> +	__u32 slot;
> +

Remove __u32 slot.....

	if (mem->slot >= GZVM_MAX_MEM_REGION)
		return -ENXIO;

	memslot = &gzvm->memslot[mem->slot];

> +	slot = mem->slot;
> +	if (slot >= GZVM_MAX_MEM_REGION)
> +		return -ENXIO;
> +	memslot = &gzvm->memslot[slot];
> + > +	vma = vma_lookup(gzvm->mm, mem->userspace_addr);
> +	if (!vma)
> +		return -EFAULT;
> +
> +	size = vma->vm_end - vma->vm_start;
> +	if (size != mem->memory_size)
> +		return -EINVAL;
> +
> +	memslot->base_gfn = __phys_to_pfn(mem->guest_phys_addr);
> +	memslot->npages = size >> PAGE_SHIFT;
> +	memslot->userspace_addr = mem->userspace_addr;
> +	memslot->vma = vma;
> +	memslot->flags = mem->flags;
> +	memslot->slot_id = mem->slot;
> +	return register_memslot_addr_range(gzvm, memslot);
> +}
> +
> +/* gzvm_vm_ioctl() - Ioctl handler of VM FD */
> +static long gzvm_vm_ioctl(struct file *filp, unsigned int ioctl,
> +			  unsigned long arg)
> +{
> +	long ret;
> +	void __user *argp = (void __user *)arg;
> +	struct gzvm *gzvm = filp->private_data;
> +
> +	switch (ioctl) {
> +	case GZVM_SET_USER_MEMORY_REGION: {
> +		struct gzvm_userspace_memory_region userspace_mem;
> +
> +		if (copy_from_user(&userspace_mem, argp, sizeof(userspace_mem))) {

			return -EFAULT;

> +			ret = -EFAULT;
> +			goto out;
> +		}
> +		ret = gzvm_vm_ioctl_set_memory_region(gzvm, &userspace_mem);
> +		break;
> +	}
> +	default:
> +		ret = -ENOTTY;
> +	}
> +out:
> +	return ret;
> +}
> +
>   static void gzvm_destroy_vm(struct gzvm *gzvm)
>   {
>   	pr_debug("VM-%u is going to be destroyed\n", gzvm->vm_id);
> @@ -42,6 +151,7 @@ static int gzvm_vm_release(struct inode *inode, struct file *filp)
>   
>   static const struct file_operations gzvm_vm_fops = {
>   	.release        = gzvm_vm_release,
> +	.unlocked_ioctl = gzvm_vm_ioctl,
>   	.llseek		= noop_llseek,
>   };
>   
> diff --git a/include/linux/gzvm_drv.h b/include/linux/gzvm_drv.h
> index f1dce23838e4..81696b7b67cc 100644
> --- a/include/linux/gzvm_drv.h
> +++ b/include/linux/gzvm_drv.h
> @@ -7,9 +7,16 @@
>   #define __GZVM_DRV_H__
>   
>   #include <linux/list.h>
> +#include <linux/mm.h>
>   #include <linux/mutex.h>
>   #include <linux/gzvm.h>
>   
> +/*
> + * For the normal physical address, the highest 12 bits should be zero, so we
> + * can mask bit 62 ~ bit 52 to indicate the error physical address
> + */
> +#define GZVM_PA_ERR_BAD (0x7ffULL << 52)
> +
>   #define INVALID_VM_ID   0xffff
>   
>   /*
> @@ -27,10 +34,39 @@
>    * The following data structures are for data transferring between driver and
>    * hypervisor, and they're aligned with hypervisor definitions
>    */
> +#define GZVM_MAX_MEM_REGION	10
> +
> +/* struct mem_region_addr_range - Identical to ffa memory constituent */
> +struct mem_region_addr_range {
> +	/* the base IPA of the constituent memory region, aligned to 4 kiB */
> +	__u64 address;
> +	/* the number of 4 kiB pages in the constituent memory region. */
> +	__u32 pg_cnt;
> +	__u32 reserved;
> +};
> +
> +struct gzvm_memory_region_ranges {
> +	__u32 slot;
> +	__u32 constituent_cnt;
> +	__u64 total_pages;
> +	__u64 gpa;
> +	struct mem_region_addr_range constituents[];
> +};
> +
> +/* struct gzvm_memslot - VM's memory slot descriptor */
> +struct gzvm_memslot {
> +	u64 base_gfn;			/* begin of guest page frame */
> +	unsigned long npages;		/* number of pages this slot covers */
> +	unsigned long userspace_addr;	/* corresponding userspace va */
> +	struct vm_area_struct *vma;	/* vma related to this userspace addr */

kerneldoc please

> +	u32 flags;
> +	u32 slot_id;
> +};
>   

Regards,
Angelo



From carlos.song at nxp.com  Thu Feb  1 01:58:13 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Thu, 1 Feb 2024 09:58:13 +0000
Subject: [PATCH v2] spi: imx: fix the burst length at DMA mode and CPU
 mode
In-Reply-To: <20240201085205.GA3906@francesco-nb>
References: <20240131101916.437398-1-carlos.song@nxp.com>
 <20240131194207.GB12870@francesco-nb>
 <VI1PR04MB5005EB37DD02F4E32D94336FE8432@VI1PR04MB5005.eurprd04.prod.outlook.com>
 <20240201085205.GA3906@francesco-nb>
Message-ID: <VI1PR04MB50055CD3C608C5A0407B113BE8432@VI1PR04MB5005.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Francesco Dolcini <francesco at dolcini.it>
> Sent: Thursday, February 1, 2024 4:52 PM
> To: Carlos Song <carlos.song at nxp.com>
> Cc: Francesco Dolcini <francesco at dolcini.it>; broonie at kernel.org;
> shawnguo at kernel.org; s.hauer at pengutronix.de; kernel at pengutronix.de;
> dl-linux-imx <linux-imx at nxp.com>; benjamin at bigler.one;
> stefanmoring at gmail.com; linux-spi at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
> Subject: [EXT] Re: [PATCH v2] spi: imx: fix the burst length at DMA mode and CPU
> mode
> 
> Caution: This is an external email. Please take care when clicking links or opening
> attachments. When in doubt, report the message using the 'Report this email'
> button
> 
> 
> On Thu, Feb 01, 2024 at 02:02:36AM +0000, Carlos Song wrote:
> > > From: Francesco Dolcini <francesco at dolcini.it> Add #include
> > > <linux/bits.h> given you are using BITS_PER_BYTE
> > >
> > I found that <linux/property.h> has been included in spi-imx.c driver.
> > And <linux/bits.h> has been included in <linux/property.h>.
> > So I didn't add the "#include <linux/bits.h>" on purpose.
> 
> I think you should be explicit and include this header.
> Code get refactored all the time and you can prevent issues this way.
> 
Hi?
Thank you! This is acceptable, I will include <linux/bits.h> explicitly and send V3.

BR
Carlos

> Francesco
> 


From krzysztof.kozlowski at linaro.org  Thu Feb  1 01:58:15 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 10:58:15 +0100
Subject: [PATCH v2 1/6] clk: samsung: gs101: gpio_peric0_pclk needs to be
 kept on
In-Reply-To: <20240130093812.1746512-2-andre.draszik@linaro.org>
References: <20240130093812.1746512-1-andre.draszik@linaro.org>
 <20240130093812.1746512-2-andre.draszik@linaro.org>
Message-ID: <31c4afb2-b80a-4f41-bc09-badf8aa5818f@linaro.org>

On 30/01/2024 10:36, Andr? Draszik wrote:
> This pclk clock is required any time we access the pinctrl registers of
> this block.
> 
> Since pinctrl-samsung doesn't support a clock at the moment, we just
> keep the kernel from disabling it at boot, until we have an update for
> pinctrl-samsung to handle this required clock, at which point we'll be
> able to drop the flag again.
> 
> Fixes: 893f133a040b ("clk: samsung: gs101: add support for cmu_peric0")

Dropped fixes tag. The driver looks correct, it's pinctrl issue.

I really dislike how these patches are inter-mixed with DTS. Makes
applying difficult and confuses about dependencies.

I assume there are no dependencies here.

I am repeating this and repeating, but in future I will just reject the
patches:

Your DTS and driver changes cannot depend on each other for new feature
submissions.

Best regards,
Krzysztof



From carlos.song at nxp.com  Thu Feb  1 02:01:15 2024
From: carlos.song at nxp.com (carlos.song at nxp.com)
Date: Thu,  1 Feb 2024 18:01:15 +0800
Subject: [PATCH v3] spi: imx: fix the burst length at DMA mode and CPU mode
Message-ID: <20240201100115.503296-1-carlos.song@nxp.com>

From: Carlos Song <carlos.song at nxp.com>

For DMA mode, the bus width of the DMA is equal to the size of data
word, so burst length should be configured as bits per word.

For CPU mode, because of the spi transfer len is in byte, so burst
length should be configured as bits per byte * spi_imx->count.

Signed-off-by: Carlos Song <carlos.song at nxp.com>
Reviewed-by: Clark Wang <xiaoning.wang at nxp.com>
Fixes: e9b220aeacf1 ("spi: spi-imx: correctly configure burst length when using dma")
Fixes: 5f66db08cbd3 ("spi: imx: Take in account bits per word instead of assuming 8-bits")
---
Changes for V3:
- include <linux/bits.h> 
---
 drivers/spi/spi-imx.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 546cdce525fc..2a1ae7b00760 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -21,7 +21,7 @@
 #include <linux/types.h>
 #include <linux/of.h>
 #include <linux/property.h>
-
+#include <linux/bits.h>
 #include <linux/dma/imx-dma.h>
 
 #define DRIVER_NAME "spi_imx"
@@ -660,15 +660,14 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx,
 			<< MX51_ECSPI_CTRL_BL_OFFSET;
 	else {
 		if (spi_imx->usedma) {
-			ctrl |= (spi_imx->bits_per_word *
-				spi_imx_bytes_per_word(spi_imx->bits_per_word) - 1)
+			ctrl |= (spi_imx->bits_per_word - 1)
 				<< MX51_ECSPI_CTRL_BL_OFFSET;
 		} else {
 			if (spi_imx->count >= MX51_ECSPI_CTRL_MAX_BURST)
-				ctrl |= (MX51_ECSPI_CTRL_MAX_BURST - 1)
+				ctrl |= (MX51_ECSPI_CTRL_MAX_BURST * BITS_PER_BYTE - 1)
 						<< MX51_ECSPI_CTRL_BL_OFFSET;
 			else
-				ctrl |= (spi_imx->count * spi_imx->bits_per_word - 1)
+				ctrl |= (spi_imx->count * BITS_PER_BYTE - 1)
 						<< MX51_ECSPI_CTRL_BL_OFFSET;
 		}
 	}
-- 
2.34.1



From flash.liu at mediatek.com  Thu Feb  1 01:57:52 2024
From: flash.liu at mediatek.com (Pin-Chuan Liu)
Date: Thu, 1 Feb 2024 17:57:52 +0800
Subject: [PATCH v2] firmware: arm_scmi: Avoid to call mbox_client_txdone on txdone_irq mode
Message-ID: <20240201095754.25374-1-flash.liu@mediatek.com>

On txdone_irq mode, tx_tick is done from mbox_chan_txdone.
Calling to mbox_client_txdone could get error message
and return directly, add a check to avoid this.

Signed-off-by: Pin-Chuan Liu <flash.liu at mediatek.com>
---
V1 -> V2:
 - Remove Change-Id
 - Use single line comment
 
 drivers/firmware/arm_scmi/mailbox.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c
index b8d470417e8f..d391463e3208 100644
--- a/drivers/firmware/arm_scmi/mailbox.c
+++ b/drivers/firmware/arm_scmi/mailbox.c
@@ -8,6 +8,7 @@
 
 #include <linux/err.h>
 #include <linux/device.h>
+#include <linux/mailbox_controller.h>
 #include <linux/mailbox_client.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -275,7 +276,10 @@ static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
 	 * Unfortunately, we have to kick the mailbox framework after we have
 	 * received our message.
 	 */
-	mbox_client_txdone(smbox->chan, ret);
+
+	/* With txdone_irq mode, kick can be done by mbox_chan_txdone */
+	if (!(smbox->chan->mbox->txdone_irq))
+		mbox_client_txdone(smbox->chan, ret);
 }
 
 static void mailbox_fetch_response(struct scmi_chan_info *cinfo,
-- 
2.18.0



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:02:27 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 11:02:27 +0100
Subject: [PATCH v2 5/6] clk: samsung: gs101: don't mark non-essential
 clocks as critical
In-Reply-To: <20240130093812.1746512-6-andre.draszik@linaro.org>
References: <20240130093812.1746512-1-andre.draszik@linaro.org>
 <20240130093812.1746512-6-andre.draszik@linaro.org>
Message-ID: <8dfab6a9-f9d1-46c2-8bd1-6ead4b26fbe1@linaro.org>

On 30/01/2024 10:36, Andr? Draszik wrote:
> The peric0_top1_ipclk_0 and peric0_top1_pclk_0 are the clocks going to
> peric0/uart_usi, with pclk being the bus clock. Without pclk running,
> any bus access will hang.
> Unfortunately, in commit d97b6c902a40 ("arm64: dts: exynos: gs101:
> update USI UART to use peric0 clocks") the gs101 DT ended up specifying
> an incorrect pclk in the respective node and instead the two clocks
> here were marked as critical.
> 
> We have fixed the gs101 DT and can therefore drop this incorrect
> work-around here, the uart driver will claim these clocks as needed.

How did you fixed the DTS? Which commit did it? Are we going back to
basics of driver changes depending on DTS?

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:04:11 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 11:04:11 +0100
Subject: [PATCH v2 6/6] arm64: dts: exynos: gs101: reorder hsi2c_8
 pinctrl-* properties
In-Reply-To: <20240130093812.1746512-7-andre.draszik@linaro.org>
References: <20240130093812.1746512-1-andre.draszik@linaro.org>
 <20240130093812.1746512-7-andre.draszik@linaro.org>
Message-ID: <98810c49-38e6-4402-bd47-05d8cbc99ef3@linaro.org>

On 30/01/2024 10:36, Andr? Draszik wrote:
> The preferred order for these is pinctrl-0 pinctrl-names.
> 
> Update the DTSI accordingly.
> 
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> Suggested-by: Sam Protsenko <semen.protsenko at linaro.org>
> 
> ---
> v2: new patch in this series
> ---
>  arch/arm64/boot/dts/exynos/google/gs101.dtsi | 2 +-

This is trivial cleanup, which is fine but then do it for entire Google
GS DTSI and DTS, not only one case.

Best regards,
Krzysztof



From mkl at pengutronix.de  Thu Feb  1 02:05:57 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Thu, 1 Feb 2024 11:05:57 +0100
Subject: [PATCH v3] spi: imx: fix the burst length at DMA mode and CPU
 mode
In-Reply-To: <20240201100115.503296-1-carlos.song@nxp.com>
References: <20240201100115.503296-1-carlos.song@nxp.com>
Message-ID: <20240201-resupply-doorframe-feb41940155f-mkl@pengutronix.de>

On 01.02.2024 18:01:15, carlos.song at nxp.com wrote:
> From: Carlos Song <carlos.song at nxp.com>
> 
> For DMA mode, the bus width of the DMA is equal to the size of data
> word, so burst length should be configured as bits per word.
> 
> For CPU mode, because of the spi transfer len is in byte, so burst
> length should be configured as bits per byte * spi_imx->count.
> 
> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Reviewed-by: Clark Wang <xiaoning.wang at nxp.com>
> Fixes: e9b220aeacf1 ("spi: spi-imx: correctly configure burst length when using dma")
> Fixes: 5f66db08cbd3 ("spi: imx: Take in account bits per word instead of assuming 8-bits")
> ---
> Changes for V3:
> - include <linux/bits.h> 
> ---
>  drivers/spi/spi-imx.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
> index 546cdce525fc..2a1ae7b00760 100644
> --- a/drivers/spi/spi-imx.c
> +++ b/drivers/spi/spi-imx.c
> @@ -21,7 +21,7 @@
>  #include <linux/types.h>
>  #include <linux/of.h>
>  #include <linux/property.h>
> -
> +#include <linux/bits.h>

nitpick:
Please keep the includes sorted alphabetically.

>  #include <linux/dma/imx-dma.h>

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |


From angelogioacchino.delregno at collabora.com  Thu Feb  1 02:08:41 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 1 Feb 2024 11:08:41 +0100
Subject: [PATCH 0/7] ASoC: mediatek: AFE drivers cleanups
In-Reply-To: <20240111105247.117766-1-angelogioacchino.delregno@collabora.com>
References: <20240111105247.117766-1-angelogioacchino.delregno@collabora.com>
Message-ID: <cace3472-7ee3-459b-ab2c-51764db99bd7@collabora.com>

Il 11/01/24 11:52, AngeloGioacchino Del Regno ha scritto:
> This series converts MediaTek AFE drivers' probe functions to use
> dev_err_probe() and devm functions where possible and, in some
> cases, dropping the .remove_new() callback, reducing the size.
> 
> Cheers!

Gentle ping for this series, afraid that went out of the radar :-)

Cheers,
Angelo

> 
> AngeloGioacchino Del Regno (7):
>    ASoC: mediatek: mt8173-afe-pcm: Convert to devm_pm_runtime_enable()
>    ASoC: mediatek: mt8173-afe-pcm: Use devm_snd_soc_register_component()
>    ASoC: mediatek: mt8183-afe-pcm: Convert to devm_pm_runtime_enable()
>    ASoC: mediatek: mt8183-afe-pcm: Simplify with dev_err_probe()
>    ASoC: mediatek: mt8192-afe-pcm: Convert to devm_pm_runtime_enable()
>    ASoC: mediatek: mt8192-afe-pcm: Simplify with dev_err_probe()
>    ASoC: mediatek: mt8195-afe-pcm: Drop .remove_new() callback
> 
>   sound/soc/mediatek/mt8173/mt8173-afe-pcm.c |  78 +++------------
>   sound/soc/mediatek/mt8183/mt8183-afe-pcm.c | 108 +++++++--------------
>   sound/soc/mediatek/mt8192/mt8192-afe-pcm.c |  95 ++++++------------
>   sound/soc/mediatek/mt8195/mt8195-afe-pcm.c |  12 +--
>   4 files changed, 81 insertions(+), 212 deletions(-)
> 



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:16:32 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 11:16:32 +0100
Subject: [PATCH v2 2/6] arm64: dts: exynos: gs101: fix usi8 default mode
In-Reply-To: <20240130093812.1746512-3-andre.draszik@linaro.org>
References: <20240130093812.1746512-1-andre.draszik@linaro.org>
 <20240130093812.1746512-3-andre.draszik@linaro.org>
Message-ID: <54cbf305-8cad-495a-a805-94a249bdefcf@linaro.org>

On 30/01/2024 10:36, Andr? Draszik wrote:
> While commit 6d44d1a1fb62 ("arm64: dts: exynos: gs101: define USI8 with
> I2C configuration") states that the USI8 CONFIG is 0 at reset, the boot
> loader has configured it by the time Linux runs and it has a different
> value at this stage.

This issue was pointed during review:
https://lore.kernel.org/all/CAPLW+4=U9DBmwgxyWz3cy=V-Ui7s2Z9um4xbEuyax1o=0zB_NA at mail.gmail.com/

Yet you posted new version of patchset not implementing this, just to do
it week later as new patch.

Sorry guys, it seems you need much more time to accept and go through
review, I will use two weeks delay time for applying GS patches.

Now, for the patch, we don't do it for any other nodes which have 0 as
reset value and we do not know what bootloader does there. Bootloader
also can change.

This is a required property, therefore please explain me how, really
how, this can happen:

" we should
set it to none here so as to ensure things don't work by accident"

NAK

Best regards,
Krzysztof



From angelogioacchino.delregno at collabora.com  Thu Feb  1 02:16:46 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 1 Feb 2024 11:16:46 +0100
Subject: [PATCH v4 00/17] Support IGT in display driver
In-Reply-To: <20231212121957.19231-1-shawn.sung@mediatek.com>
References: <20231212121957.19231-1-shawn.sung@mediatek.com>
Message-ID: <488c6f38-02c6-4e62-b90b-d2ac112541ae@collabora.com>

Il 12/12/23 13:19, Hsiao Chien Sung ha scritto:
> This series is based on mediatek-drm-next.
> 
> This series adds support for running IGT (Intel GPU Tool) tests
> with MediaTek display driver. The following changes will be
> applied:
> 
> 1. Add a new API for creating GCE thread loop to retrieve CRCs
>     from the hardware component
> 2. Support hardware CRC calculation in both VDOSYS0 and VDOSYS1
> 3. Support alpha blending in both VDOSYS0 and VDOSYS1
> 

Hello,
is there still interest in upstreaming this?

We're interested in enabling more comprehensive IGT tests on MediaTek SoCs
and this series is definitely useful.

Regards,
Angelo

> Changes in v4:
> - Seperate the patch into smaller ones
> - Change the title of some patches
> - Revert the changes that are not related to the series
> 
> Changes in v3:
> - Modify the dt-binding document of Mediatek OVL
> - Set DRM mode configs accroding to the hardware capabilities
> - Replace cmdq_pkt_jump_absolute() with cmdq_pkt_jump()
> 
> Changes in v2:
> - Simplify CMDQ by adding commands that are currently used only
> - Integrate CRC related codes into new APIs for Mixer and OVL to reuse
> - Add CPU version CRC retrieval when CMDQ is disabled
> 
> Hsiao Chien Sung (17):
>    soc: mediatek: Add register definitions for GCE
>    soc: mediatek: Disable 9-bit alpha in ETHDR
>    dt-bindings: display: mediatek: ovl: Modify rules for MT8195/MT8188
>    drm/mediatek: Add OVL compatible name for MT8195
>    drm/mediatek: Set DRM mode configs accordingly
>    drm/mediatek: Support alpha blending in OVL
>    drm/mediatek: Support alpha blending in Mixer
>    drm/mediatek: Support alpha blending in display driver
>    drm/mediatek: Support CSC in OVL
>    drm/mediatek: Support more color formats in OVL
>    drm/mediatek: Turn off the layers with zero width or height
>    drm/mediatek: Support CRC in display driver
>    drm/mediatek: Support CRC in OVL
>    drm/mediatek: Support CRC in OVL adaptor
>    drm/mediatek: Add missing plane settings when async update
>    drm/mediatek: Fix errors when reporting rotation capability
>    drm/mediatek: Add comments for the structures
> 
>   .../display/mediatek/mediatek,ovl.yaml        |  12 +-
>   drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   7 +
>   drivers/gpu/drm/mediatek/mtk_disp_ovl.c       | 326 +++++++++++++++---
>   .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   |  32 +-
>   drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 261 +++++++++++++-
>   drivers/gpu/drm/mediatek/mtk_drm_crtc.h       |  39 +++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |   7 +
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  35 ++
>   drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  30 +-
>   drivers/gpu/drm/mediatek/mtk_drm_drv.h        |  16 +
>   drivers/gpu/drm/mediatek/mtk_drm_plane.c      |  15 +-
>   drivers/gpu/drm/mediatek/mtk_ethdr.c          | 106 +++++-
>   drivers/gpu/drm/mediatek/mtk_ethdr.h          |   5 +
>   drivers/soc/mediatek/mtk-mmsys.c              |   1 +
>   include/linux/soc/mediatek/mtk-cmdq.h         |  10 +
>   15 files changed, 834 insertions(+), 68 deletions(-)
> 
> --
> 2.18.0
> 




From suzuki.poulose at arm.com  Thu Feb  1 02:23:45 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu, 1 Feb 2024 10:23:45 +0000
Subject: [PATCH 00/10] KVM: arm64: fix many kernel-doc warnings
In-Reply-To: <20240117230714.31025-1-rdunlap@infradead.org>
References: <20240117230714.31025-1-rdunlap@infradead.org>
Message-ID: <a05a9c6a-af7a-4591-a6b7-69e15109aed2@arm.com>

On 17/01/2024 23:07, Randy Dunlap wrote:
> Fix a bunch of kernel-doc warnings in arch/arm64/kvm/.
> 
>   [PATCH 01/10] KVM: arm64: debug: fix kernel-doc warnings
>   [PATCH 02/10] KVM: arm64: guest: fix kernel-doc warnings
>   [PATCH 03/10] KVM: arm64: hyp/aarch32: fix kernel-doc warnings
>   [PATCH 04/10] KVM: arm64: vhe: fix a kernel-doc warning
>   [PATCH 05/10] KVM: arm64: mmu: fix a kernel-doc warning
>   [PATCH 06/10] KVM: arm64: PMU: fix kernel-doc warnings
>   [PATCH 07/10] KVM: arm64: sys_regs: fix kernel-doc warnings
>   [PATCH 08/10] KVM: arm64: vgic-init: fix a kernel-doc warning
>   [PATCH 09/10] KVM: arm64: vgic-its: fix kernel-doc warnings
>   [PATCH 10/10] KVM: arm64: vgic: fix a kernel-doc warning
> 
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oliver.upton at linux.dev>
> Cc: James Morse <james.morse at arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Zenghui Yu <yuzenghui at huawei.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.linux.dev
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>

For the series:

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>



From suzuki.poulose at arm.com  Thu Feb  1 02:26:40 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu, 1 Feb 2024 10:26:40 +0000
Subject: [PATCH v5 05/10] coresight-tpda: Add support to configure CMB
 element
In-Reply-To: <9fca774e-3519-4d0c-ba61-6b84965f36c2@quicinc.com>
References: <1706605366-31705-1-git-send-email-quic_taozha@quicinc.com>
 <1706605366-31705-6-git-send-email-quic_taozha@quicinc.com>
 <6ccb98f2-2f68-45db-9941-1c7b05da84d0@arm.com>
 <6fff5991-01ed-44ea-aa08-9f302d2465e8@quicinc.com>
 <1f5a7c7b-56de-4f19-9d48-652ae6efe50f@arm.com>
 <9fca774e-3519-4d0c-ba61-6b84965f36c2@quicinc.com>
Message-ID: <812bd339-4728-40ee-b19e-c8a04cc740de@arm.com>

On 01/02/2024 02:25, Tao Zhang wrote:
> 
> On 1/31/2024 6:02 PM, Suzuki K Poulose wrote:
>> On 31/01/2024 01:39, Tao Zhang wrote:
>>>
>>> On 1/30/2024 8:35 PM, Suzuki K Poulose wrote:
>>>> On 30/01/2024 09:02, Tao Zhang wrote:
>>>>> Read the CMB element size from the device tree. Set the register
>>>>> bit that controls the CMB element size of the corresponding port.
>>>>>
>>>>> Reviewed-by: James Clark <james.clark at arm.com>
>>>>> Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
>>>>> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
>>>>> ---
>>>>> ? drivers/hwtracing/coresight/coresight-tpda.c | 123 
>>>>> +++++++++++--------
>>>>> ? drivers/hwtracing/coresight/coresight-tpda.h |?? 6 +
>>>>> ? 2 files changed, 79 insertions(+), 50 deletions(-)
>>>>>
>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c 
>>>>> b/drivers/hwtracing/coresight/coresight-tpda.c
>>>>> index 4ac954f4bc13..fcddff3ded81 100644
>>>>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>>>>> @@ -18,6 +18,7 @@
>>>>> ? #include "coresight-priv.h"
>>>>> ? #include "coresight-tpda.h"
>>>>> ? #include "coresight-trace-id.h"
>>>>> +#include "coresight-tpdm.h"
>>>>> ? ? DEFINE_CORESIGHT_DEVLIST(tpda_devs, "tpda");
>>>>> ? @@ -28,24 +29,57 @@ static bool coresight_device_is_tpdm(struct 
>>>>> coresight_device *csdev)
>>>>> ????????????? CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
>>>>> ? }
>>>>> ? +static void tpdm_clear_element_size(struct coresight_device *csdev)
>>>>> +{
>>>>> +??? struct tpda_drvdata *drvdata = 
>>>>> dev_get_drvdata(csdev->dev.parent);
>>>>> +
>>>>> +??? drvdata->dsb_esize = 0;
>>>>> +??? drvdata->cmb_esize = 0;
>>>>> +}
>>>>> +
>>>>> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, 
>>>>> u32 *val)
>>>>> +{
>>>>> +
>>>>
>>>>
>>>>
>>>>> +??? if (drvdata->dsb_esize == 64)
>>>>> +??????? *val |= TPDA_Pn_CR_DSBSIZE;
>>>>
>>>> We don't seem to be clearing the fields we modify, before updating 
>>>> them. This may be OK in real world where the device connected to 
>>>> TPDA port
>>>> may not change. But it is always safer to clear the bits and set it.
>>>>
>>>> e.g.:
>>>> ????*val &= ~(TPDA_Pn_CR_DSBSIZE | TPDA_Pn_CR_CMBSIZE);
>>>>
>>>>
>>>>
>>>>> +??? else if (drvdata->dsb_esize == 32)
>>>>> +??????? *val &= ~TPDA_Pn_CR_DSBSIZE;
>>>>> +
>>>>> +??? if (drvdata->cmb_esize == 64)
>>>>> +??????? *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
>>>>> +??? else if (drvdata->cmb_esize == 32)
>>>>> +??????? *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
>>>>
>>>> Similarly here ^^^. I am happy to fix it up if you are OK with it 
>>>> (unless there are other changes that need a respin)
>>>
>>> Thank you. I would be very grateful if you could help for this.
>>
>> Given, you need to respin, please incorporate this change too.
> 
> Sure.
> 
> Is it OK if I modify the code as follow and update to this patch directly?
> 
>  ??? *val &= ~(TPDA_Pn_CR_DSBSIZE | TPDA_Pn_CR_CMBSIZE);
> 
>  ??? if (drvdata->dsb_esize == 64)
>  ?? ???? *val |= TPDA_Pn_CR_DSBSIZE;
>  ?? ?else if (drvdata->dsb_esize == 32)
>  ?? ???? *val &= ~TPDA_Pn_CR_DSBSIZE;
> 
>  ?? ?if (drvdata->cmb_esize == 64)
>  ?? ???? *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
>  ?? ?else if (drvdata->cmb_esize == 32)
>  ?? ???? *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);.
>  ?? ?else if (drvdata->cmb_esize == 8)
>  ?? ???? *val &= ~TPDA_Pn_CR_CMBSIZE;

Yes, that looks good to me. Even though you would be clearing the fields 
for (DSB=32 and CMB=8) once again, it is good to leave it like that 
rather than skipping them, making people stare at it to figure out if 
this was correct or not.

Suzuki




> 
> Best,
> 
> Tao
> 
>>
>> Suzuki
>>
>>
>>



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:31:05 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 11:31:05 +0100
Subject: [PATCH v2 3/3] arm64: dts: exynos: Add SPI nodes for Exynos850
In-Reply-To: <20240125013858.3986-4-semen.protsenko@linaro.org>
References: <20240125013858.3986-1-semen.protsenko@linaro.org>
 <20240125013858.3986-4-semen.protsenko@linaro.org>
Message-ID: <cd9ca36f-84f6-4cc7-bc1e-a4c5781d2bf2@linaro.org>

On 25/01/2024 02:38, Sam Protsenko wrote:
> Some USI blocks can be configured as SPI controllers. Add corresponding
> SPI nodes to Exynos850 SoC device tree.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> Changes in v2:
>   - Sorted pinctrl properties properly
> 
>  arch/arm64/boot/dts/exynos/exynos850.dtsi | 54 +++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> index 618bc674896e..ca257da74b50 100644
> --- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> @@ -738,6 +738,24 @@ usi_spi_0: usi at 139400c0 {
>  				 <&cmu_peri CLK_GOUT_SPI0_IPCLK>;
>  			clock-names = "pclk", "ipclk";
>  			status = "disabled";
> +
> +			spi_0: spi at 13940000 {
> +				compatible = "samsung,exynos850-spi";
> +				reg = <0x13940000 0x30>;
> +				interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
> +				pinctrl-0 = <&spi0_pins>;
> +				pinctrl-names = "default";
> +				clocks = <&cmu_peri CLK_GOUT_SPI0_IPCLK>,
> +					 <&cmu_peri CLK_GOUT_SPI0_PCLK>;
> +				clock-names = "spi_busclk0", "spi";
> +				samsung,spi-src-clk = <0>;
> +				dmas = <&pdma0 5>, <&pdma0 4>;
> +				dma-names = "tx", "rx";
> +				num-cs = <1>;

For the future: please keep properties sorted by name, so clocks+name,
dmas+name, interrupts, pinctrl+name, more-or-less matching DTS coding
style. address/size cells can go to the end.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:33:18 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 11:33:18 +0100
Subject: [PATCH 0/7] ARM: dts: samsung: specify the SPI fifosize
In-Reply-To: <20240125151630.753318-1-tudor.ambarus@linaro.org>
References: <20240125151630.753318-1-tudor.ambarus@linaro.org>
Message-ID: <85856b38-e42e-412b-b201-ee2798722f67@linaro.org>

On 25/01/2024 16:16, Tudor Ambarus wrote:
> Hi,
> 
> The "samsung,spi-fifosize" was introduced in the following patch set:
> https://lore.kernel.org/linux-arm-kernel/20240125145007.748295-1-tudor.ambarus at linaro.org/T/#t
> 

Judging by Rob's statement the bindings were not accepted, so I drop
this series for now.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:36:07 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 01 Feb 2024 11:36:07 +0100
Subject: (subset) [PATCH v2 3/6] arm64: dts: exynos: gs101: use correct
 clocks for usi8
In-Reply-To: <20240130093812.1746512-4-andre.draszik@linaro.org>
References: <20240130093812.1746512-1-andre.draszik@linaro.org>
 <20240130093812.1746512-4-andre.draszik@linaro.org>
Message-ID: <170678376730.179918.14593646521347774739.b4-ty@linaro.org>


On Tue, 30 Jan 2024 09:36:42 +0000, Andr? Draszik wrote:
> Wrong pclk clocks have been used in this usi8 instance here. For USI
> and I2C, we need the ipclk and pclk, where pclk is the bus clock.
> Without it, nothing can work.
> 
> It is unclear what exactly is using USI8_USI_CLK, but it is not
> required for the IP to be operational at this stage, while pclk is.
> This also brings the DT in line with the clock names expected by the
> usi and i2c drivers.
> 
> [...]

Applied, thanks!

[3/6] arm64: dts: exynos: gs101: use correct clocks for usi8
      https://git.kernel.org/krzk/linux/c/512b5a875cd8b8352257fefe71513097ee97be77

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:36:09 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 01 Feb 2024 11:36:09 +0100
Subject: (subset) [PATCH v2 4/6] arm64: dts: exynos: gs101: use correct
 clocks for usi_uart
In-Reply-To: <20240130093812.1746512-5-andre.draszik@linaro.org>
References: <20240130093812.1746512-1-andre.draszik@linaro.org>
 <20240130093812.1746512-5-andre.draszik@linaro.org>
Message-ID: <170678376968.179918.16892357043934653425.b4-ty@linaro.org>


On Tue, 30 Jan 2024 09:36:43 +0000, Andr? Draszik wrote:
> Wrong pclk clocks have been used in this usi_uart instance here. For
> USI and UART, we need the ipclk and pclk, where pclk is the bus clock.
> Without it, nothing can work.
> 
> It is unclear what exactly is using USI0_UART_CLK, but it is not
> required for the IP to be operational at this stage, while pclk is.
> This also brings the DT in line with the clock names expected by the
> usi and uart drivers.
> 
> [...]

Applied, thanks!

[4/6] arm64: dts: exynos: gs101: use correct clocks for usi_uart
      https://git.kernel.org/krzk/linux/c/21e4e8807bfc7acc0fc9fe3ab69e1dc0662e7ce4

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:36:12 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 01 Feb 2024 11:36:12 +0100
Subject: (subset) [PATCH v2 2/3] arm64: dts: exynos: Add PDMA node for
 Exynos850
In-Reply-To: <20240125013858.3986-3-semen.protsenko@linaro.org>
References: <20240125013858.3986-1-semen.protsenko@linaro.org>
 <20240125013858.3986-3-semen.protsenko@linaro.org>
Message-ID: <170678377214.179918.10215466663876855155.b4-ty@linaro.org>


On Wed, 24 Jan 2024 19:38:57 -0600, Sam Protsenko wrote:
> Enable PDMA node. It's needed for multiple peripheral modules, like SPI.
> Use "arm,pl330-broken-no-flushp" quirk, as otherwise SPI transfers in
> DMA mode often fail with error like this:
> 
>     I/O Error: rx-1 tx-1 rx-f tx-f len-786 dma-1 res-(-5)
> 
> 
> [...]

Applied, thanks!

[2/3] arm64: dts: exynos: Add PDMA node for Exynos850
      https://git.kernel.org/krzk/linux/c/c0fe557853f3d4b61c4e2e729061482f4da901db

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:36:14 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 01 Feb 2024 11:36:14 +0100
Subject: (subset) [PATCH v2 3/3] arm64: dts: exynos: Add SPI nodes for
 Exynos850
In-Reply-To: <20240125013858.3986-4-semen.protsenko@linaro.org>
References: <20240125013858.3986-1-semen.protsenko@linaro.org>
 <20240125013858.3986-4-semen.protsenko@linaro.org>
Message-ID: <170678377409.179918.13077326172475089482.b4-ty@linaro.org>


On Wed, 24 Jan 2024 19:38:58 -0600, Sam Protsenko wrote:
> Some USI blocks can be configured as SPI controllers. Add corresponding
> SPI nodes to Exynos850 SoC device tree.
> 
> 

Applied, thanks!

[3/3] arm64: dts: exynos: Add SPI nodes for Exynos850
      https://git.kernel.org/krzk/linux/c/98473b0d78caa5502b7eee05553ee168f0b0b424

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:36:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 01 Feb 2024 11:36:38 +0100
Subject: (subset) [PATCH v2 1/6] clk: samsung: gs101: gpio_peric0_pclk
 needs to be kept on
In-Reply-To: <20240130093812.1746512-2-andre.draszik@linaro.org>
References: <20240130093812.1746512-1-andre.draszik@linaro.org>
 <20240130093812.1746512-2-andre.draszik@linaro.org>
Message-ID: <170678379863.179994.10165116011101753606.b4-ty@linaro.org>


On Tue, 30 Jan 2024 09:36:40 +0000, Andr? Draszik wrote:
> This pclk clock is required any time we access the pinctrl registers of
> this block.
> 
> Since pinctrl-samsung doesn't support a clock at the moment, we just
> keep the kernel from disabling it at boot, until we have an update for
> pinctrl-samsung to handle this required clock, at which point we'll be
> able to drop the flag again.
> 
> [...]

Applied, thanks!

[1/6] clk: samsung: gs101: gpio_peric0_pclk needs to be kept on
      https://git.kernel.org/krzk/linux/c/8a96d2701f7c794e45102a9cc7fc4a5c4951e699

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Thu Feb  1 02:36:41 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 01 Feb 2024 11:36:41 +0100
Subject: (subset) [PATCH v2 1/3] clk: samsung: exynos850: Propagate SPI
 IPCLK rate change
In-Reply-To: <20240125013858.3986-2-semen.protsenko@linaro.org>
References: <20240125013858.3986-1-semen.protsenko@linaro.org>
 <20240125013858.3986-2-semen.protsenko@linaro.org>
Message-ID: <170678380102.179994.1389430718462116561.b4-ty@linaro.org>


On Wed, 24 Jan 2024 19:38:56 -0600, Sam Protsenko wrote:
> When SPI transfer is being prepared, the spi-s3c64xx driver will call
> clk_set_rate() to change the rate of SPI source clock (IPCLK). But IPCLK
> is a gate (leaf) clock, so it must propagate the rate change up the
> clock tree, so that corresponding DIV clocks can actually change their
> divider values. Add CLK_SET_RATE_PARENT flag to corresponding clocks for
> all SPI instances in Exynos850 (spi_0, spi_1 and spi_2) to make it
> possible. This change involves next clocks:
> 
> [...]

Applied, thanks!

[1/3] clk: samsung: exynos850: Propagate SPI IPCLK rate change
      https://git.kernel.org/krzk/linux/c/67c15187d4910ee353374676d4dddf09d8cb227e

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From j-choudhary at ti.com  Thu Feb  1 02:40:23 2024
From: j-choudhary at ti.com (Jayesh Choudhary)
Date: Thu, 1 Feb 2024 16:10:23 +0530
Subject: [PATCH] arm64: dts: ti: k3-am69-sk: remove assigned-clock-parents
 for unused VP
In-Reply-To: <bf271671-861d-43d4-a24f-de49256ef9d0@ideasonboard.com>
References: <20231221113042.48492-1-j-choudhary@ti.com>
 <bf271671-861d-43d4-a24f-de49256ef9d0@ideasonboard.com>
Message-ID: <30ac8486-325d-44cb-9855-84a0b41f6857@ti.com>

Hello Tomi,

On 03/01/24 18:35, Tomi Valkeinen wrote:
> Hi,
> 
> On 21/12/2023 13:30, Jayesh Choudhary wrote:
>> VP2 and VP3 are unused video ports and VP3 share the same parent
>> clock as VP1 causing issue with pixel clock setting for HDMI (VP1).
>> So remove the parent clocks for unused VPs.
>>
>> Fixes: 6f8605fd7d11 ("arm64: dts: ti: k3-am69-sk: Add DP and HDMI 
>> support")
>> Reported-by: Nishanth Menon <nm at ti.com>
>> Closes: 
>> https://storage.kernelci.org/mainline/master/v6.7-rc6/arm64/defconfig/gcc-10/lab-ti/baseline-nfs-am69_sk-fs.txt
>> Signed-off-by: Jayesh Choudhary <j-choudhary at ti.com>
>> ---
>>
>> Local testing log for HDMI on AM69-SK:
>> <https://gist.github.com/Jayesh2000/517395cd85eb28d65b8ee4568cefb809>
>>
>> ? arch/arm64/boot/dts/ti/k3-am69-sk.dts | 8 ++------
>> ? 1 file changed, 2 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts 
>> b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
>> index 8da591579868..370980eb59b0 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
>> @@ -918,13 +918,9 @@ &dss {
>> ????? pinctrl-names = "default";
>> ????? pinctrl-0 = <&dss_vout0_pins_default>;
>> ????? assigned-clocks = <&k3_clks 218 2>,
>> -????????????? <&k3_clks 218 5>,
>> -????????????? <&k3_clks 218 14>,
>> -????????????? <&k3_clks 218 18>;
>> +????????????? <&k3_clks 218 5>;
>> ????? assigned-clock-parents = <&k3_clks 218 3>,
>> -???????????????? <&k3_clks 218 7>,
>> -???????????????? <&k3_clks 218 16>,
>> -???????????????? <&k3_clks 218 22>;
>> +???????????????? <&k3_clks 218 7>;
>> ? };
>> ? &serdes_wiz4 {
> 
> The SK has two outputs, using VP0 and VP1, so the above kind of makes 
> sense. Then again, setting up 4 clocks here really shouldn't break the 
> SK, should it? The AM69 has 4 available VPs. How does one configure the 
> clocks for a board that uses 4 VPs, or possibly a different selection of 
> VPs?

> 
> I think the patch desc should explain why this doesn't work. Afaik, the 
> dts is not wrong as such, but there's an underlying issue that breaks 
> the clocking if all four clocks are set up here.
> 

I discussed this with firmware team, there is an issue with sibling
child clocks. If parent clock is shared, DM cannot set its rate.
The determine_rate and set_rate query are behaving unexpectedly in
this case. determine_rate is returning 0 and set_rate is setting it
to 1.8G even when VP can support max 600M.

Jayesh

> So, with the desc updated, as this fixes an issue and is not wrong:
> 
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> 
> But I also feel this is dodging a firmware (?) issue.
> 
>  ?Tomi
> 


From carlos.song at nxp.com  Thu Feb  1 02:47:14 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Thu, 1 Feb 2024 10:47:14 +0000
Subject: [PATCH v3] spi: imx: fix the burst length at DMA mode and CPU
 mode
In-Reply-To: <20240201-resupply-doorframe-feb41940155f-mkl@pengutronix.de>
References: <20240201100115.503296-1-carlos.song@nxp.com>
 <20240201-resupply-doorframe-feb41940155f-mkl@pengutronix.de>
Message-ID: <VI1PR04MB500557BCDB04B9385F20906BE8432@VI1PR04MB5005.eurprd04.prod.outlook.com>


> -----Original Message-----
> From: Marc Kleine-Budde <mkl at pengutronix.de>
> Sent: Thursday, February 1, 2024 6:06 PM
> To: Carlos Song <carlos.song at nxp.com>
> Cc: broonie at kernel.org; shawnguo at kernel.org; s.hauer at pengutronix.de;
> kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>; benjamin at bigler.one;
> stefanmoring at gmail.com; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-spi at vger.kernel.org
> Subject: [EXT] Re: [PATCH v3] spi: imx: fix the burst length at DMA mode and CPU
> mode
>
> Caution: This is an external email. Please take care when clicking links or opening
> attachments. When in doubt, report the message using the 'Report this email'
> button
>
>
> On 01.02.2024 18:01:15, carlos.song at nxp.com wrote:
> > From: Carlos Song <carlos.song at nxp.com>
> >
> > For DMA mode, the bus width of the DMA is equal to the size of data
> > word, so burst length should be configured as bits per word.
> >
> > For CPU mode, because of the spi transfer len is in byte, so burst
> > length should be configured as bits per byte * spi_imx->count.
> >
> > Signed-off-by: Carlos Song <carlos.song at nxp.com>
> > Reviewed-by: Clark Wang <xiaoning.wang at nxp.com>
> > Fixes: e9b220aeacf1 ("spi: spi-imx: correctly configure burst length
> > when using dma")
> > Fixes: 5f66db08cbd3 ("spi: imx: Take in account bits per word instead
> > of assuming 8-bits")
> > ---
> > Changes for V3:
> > - include <linux/bits.h>
> > ---
> >  drivers/spi/spi-imx.c | 9 ++++-----
> >  1 file changed, 4 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index
> > 546cdce525fc..2a1ae7b00760 100644
> > --- a/drivers/spi/spi-imx.c
> > +++ b/drivers/spi/spi-imx.c
> > @@ -21,7 +21,7 @@
> >  #include <linux/types.h>
> >  #include <linux/of.h>
> >  #include <linux/property.h>
> > -
> > +#include <linux/bits.h>
>
> nitpick:
> Please keep the includes sorted alphabetically.
>
> >  #include <linux/dma/imx-dma.h>
>
Hi,

Hhh, thank you!
I will try my best to strictly adhere to the code format in the future!
This is a good habit and I couldn't agree more! V4 will be sent.

BR
Carlos


> Marc
>
> --
> Pengutronix e.K.                 | Marc Kleine-Budde          |
> Embedded Linux                   |
> https://www.pen/
> gutronix.de%2F&data=05%7C02%7Ccarlos.song%40nxp.com%7C53112bdae1e4
> 478f5fff08dc230d69fb%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%
> 7C638423787724098671%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAw
> MDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&s
> data=33MzYSg%2Fq5ciMNGJmbrUcprP%2BH%2F%2FNl0IPNcUO%2BHoeF4%3D
> &reserved=0 |
> Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
> Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |


From carlos.song at nxp.com  Thu Feb  1 02:54:51 2024
From: carlos.song at nxp.com (carlos.song at nxp.com)
Date: Thu,  1 Feb 2024 18:54:51 +0800
Subject: [PATCH v4] spi: imx: fix the burst length at DMA mode and CPU mode
Message-ID: <20240201105451.507005-1-carlos.song@nxp.com>

From: Carlos Song <carlos.song at nxp.com>

For DMA mode, the bus width of the DMA is equal to the size of data
word, so burst length should be configured as bits per word.

For CPU mode, because of the spi transfer len is in byte, so burst
length should be configured as bits per byte * spi_imx->count.

Signed-off-by: Carlos Song <carlos.song at nxp.com>
Reviewed-by: Clark Wang <xiaoning.wang at nxp.com>
Fixes: e9b220aeacf1 ("spi: spi-imx: correctly configure burst length when using dma")
Fixes: 5f66db08cbd3 ("spi: imx: Take in account bits per word instead of assuming 8-bits")
---
Changes for V3:
- include <linux/bits.h>
Changes for V4:
- keep the includes sorted alphabetically.
---
 drivers/spi/spi-imx.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 546cdce525fc..f7990ac2c654 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -2,6 +2,7 @@
 // Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
 // Copyright (C) 2008 Juergen Beisert
 
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
@@ -660,15 +661,14 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx,
 			<< MX51_ECSPI_CTRL_BL_OFFSET;
 	else {
 		if (spi_imx->usedma) {
-			ctrl |= (spi_imx->bits_per_word *
-				spi_imx_bytes_per_word(spi_imx->bits_per_word) - 1)
+			ctrl |= (spi_imx->bits_per_word - 1)
 				<< MX51_ECSPI_CTRL_BL_OFFSET;
 		} else {
 			if (spi_imx->count >= MX51_ECSPI_CTRL_MAX_BURST)
-				ctrl |= (MX51_ECSPI_CTRL_MAX_BURST - 1)
+				ctrl |= (MX51_ECSPI_CTRL_MAX_BURST * BITS_PER_BYTE - 1)
 						<< MX51_ECSPI_CTRL_BL_OFFSET;
 			else
-				ctrl |= (spi_imx->count * spi_imx->bits_per_word - 1)
+				ctrl |= (spi_imx->count * BITS_PER_BYTE - 1)
 						<< MX51_ECSPI_CTRL_BL_OFFSET;
 		}
 	}
-- 
2.34.1



From james.clark at arm.com  Thu Feb  1 03:06:47 2024
From: james.clark at arm.com (James Clark)
Date: Thu, 1 Feb 2024 11:06:47 +0000
Subject: [PATCH v1 07/14] perf arm-spe/cs-etm: Directly iterate CPU maps
In-Reply-To: <CAP-5=fVkwz4fb4hn=cg_RaEW-s_N-4t2nm4mX_oWOduP+0QdOA@mail.gmail.com>
References: <20231129060211.1890454-1-irogers@google.com>
 <20231129060211.1890454-8-irogers@google.com>
 <e3a01313-ed03-bc54-0260-5445fb2c15ee@arm.com>
 <2adf8e9c-e08d-a772-bfe2-378d6759721f@arm.com>
 <CAP-5=fVkwz4fb4hn=cg_RaEW-s_N-4t2nm4mX_oWOduP+0QdOA@mail.gmail.com>
Message-ID: <b9b3cca0-57c8-572b-916b-61916bd750d4@arm.com>



On 01/02/2024 02:12, Ian Rogers wrote:
> On Tue, Dec 12, 2023 at 6:36?AM James Clark <james.clark at arm.com> wrote:
>>
>>
>>
>> On 12/12/2023 14:17, James Clark wrote:
>>>
>>>
>>> On 29/11/2023 06:02, Ian Rogers wrote:
>>>> Rather than iterate all CPUs and see if they are in CPU maps, directly
>>>> iterate the CPU map. Similarly make use of the intersect
>>>> function. Switch perf_cpu_map__has_any_cpu_or_is_empty to more
>>>> appropriate alternatives.
>>>>
>>>> Signed-off-by: Ian Rogers <irogers at google.com>
>>>> ---
>>>>  tools/perf/arch/arm/util/cs-etm.c    | 77 ++++++++++++----------------
>>>>  tools/perf/arch/arm64/util/arm-spe.c |  4 +-
>>>>  2 files changed, 34 insertions(+), 47 deletions(-)
>>>>
>>>> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
>>>> index 77e6663c1703..a68a72f2f668 100644
>>>> --- a/tools/perf/arch/arm/util/cs-etm.c
>>>> +++ b/tools/perf/arch/arm/util/cs-etm.c
>>>> @@ -197,38 +197,32 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr,
>>>>  static int cs_etm_validate_config(struct auxtrace_record *itr,
>>>>                                struct evsel *evsel)
>>>>  {
>>>> -    int i, err = -EINVAL;
>>>> +    int idx, err = -EINVAL;
>>>>      struct perf_cpu_map *event_cpus = evsel->evlist->core.user_requested_cpus;
>>>>      struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
>>>> +    struct perf_cpu_map *intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
>>>> +    struct perf_cpu cpu;
>>>>
>>>> -    /* Set option of each CPU we have */
>>>> -    for (i = 0; i < cpu__max_cpu().cpu; i++) {
>>>> -            struct perf_cpu cpu = { .cpu = i, };
>>>> -
>>>> -            /*
>>>> -             * In per-cpu case, do the validation for CPUs to work with.
>>>> -             * In per-thread case, the CPU map is empty.  Since the traced
>>>> -             * program can run on any CPUs in this case, thus don't skip
>>>> -             * validation.
>>>> -             */
>>>> -            if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus) &&
>>>> -                !perf_cpu_map__has(event_cpus, cpu))
>>>> -                    continue;
>>>
>>> This has broken validation for per-thread sessions.
>>> perf_cpu_map__intersect() doesn't seem to be able to handle the case
>>> where an 'any' map intersected with an online map should return the
>>> online map. Or at least it should for this to work, and it seems to make
>>> sense for it to work that way.
>>>
>>> At least that was my initial impression, but I only debugged it and saw
>>> that the loop is now skipped entirely.
>>>
>>>> -
>>>> -            if (!perf_cpu_map__has(online_cpus, cpu))
>>>> -                    continue;
>>>> +    perf_cpu_map__put(online_cpus);
>>>>
>>>> -            err = cs_etm_validate_context_id(itr, evsel, i);
>>>> +    /*
>>>> +     * Set option of each CPU we have. In per-cpu case, do the validation
>>>> +     * for CPUs to work with.  In per-thread case, the CPU map is empty.
>>>> +     * Since the traced program can run on any CPUs in this case, thus don't
>>>> +     * skip validation.
>>>> +     */
>>>> +    perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
>>>> +            err = cs_etm_validate_context_id(itr, evsel, cpu.cpu);
>>>>              if (err)
>>>>                      goto out;
>>>> -            err = cs_etm_validate_timestamp(itr, evsel, i);
>>>> +            err = cs_etm_validate_timestamp(itr, evsel, idx);
> 
> I think this is an error, idx shouldn't be used here, cpu.cpu should.
> 

Yes I think you're right. But when I tested this it was on a machine
with all CPUs online, and all traced, so I think idx == cpu.cpu. So
although this might need to be fixed it didn't cause the breakage.

Also this line of code was also never hit because the issue was the
intersect returning an empty map before here.

>>>>              if (err)
>>>>                      goto out;
>>>>      }
>>>>
>>>>      err = 0;
>>>>  out:
>>>> -    perf_cpu_map__put(online_cpus);
>>>> +    perf_cpu_map__put(intersect_cpus);
>>>>      return err;
>>>>  }
>>>>
>>>> @@ -435,7 +429,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
>>>>       * Also the case of per-cpu mmaps, need the contextID in order to be notified
>>>>       * when a context switch happened.
>>>>       */
>>>> -    if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
>>>> +    if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>>>>              evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
>>>>                                         "timestamp", 1);
>>>>              evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
>>>> @@ -461,7 +455,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
>>>>      evsel->core.attr.sample_period = 1;
>>>>
>>>>      /* In per-cpu case, always need the time of mmap events etc */
>>>> -    if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus))
>>>> +    if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
>>>>              evsel__set_sample_bit(evsel, TIME);
>>>>
>>>>      err = cs_etm_validate_config(itr, cs_etm_evsel);
>>>> @@ -533,38 +527,32 @@ static size_t
>>>>  cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
>>>>                    struct evlist *evlist __maybe_unused)
>>>>  {
>>>> -    int i;
>>>> +    int idx;
>>>>      int etmv3 = 0, etmv4 = 0, ete = 0;
>>>>      struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus;
>>>>      struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
>>>> +    struct perf_cpu cpu;
>>>>
>>>>      /* cpu map is not empty, we have specific CPUs to work with */
>>>> -    if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
>>>> -            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 (!perf_cpu_map__is_empty(event_cpus)) {
>>>> +            struct perf_cpu_map *intersect_cpus =
>>>> +                    perf_cpu_map__intersect(event_cpus, online_cpus);
>>>>
>>>> -                    if (cs_etm_is_ete(itr, i))
>>>> +            perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
>>>> +                    if (cs_etm_is_ete(itr, cpu.cpu))
>>
>> Similar problem here. For a per-thread session, the CPU map is not empty
>> (it's an 'any' map, presumably length 1), so it comes into this first
>> if, rather than the else below which is for the 'any' scenario.
>>
>> Then the intersect with online CPUs results in an empty map, so no CPU
>> metadata is recorded, then the session fails.
>>
>> If you made the intersect work in the way I mentioned above we could
>> also delete the else below, because that's just another way to convert
>> from 'any' to 'all online'.
> 
> I don't think intersect of "all online" with an "any CPU" should
> return "all online" as these would be quite different options to
> perf_event_open. Let's see if the issue above fixes this change
> otherwise I can revert it to a more mechanical translation of the
> existing code into the new APIs.
> 

If you're not ok with the intersection behavior that I suggested, then
maybe we need a new function like perf_cpu_map__flatten() or
perf_cpu_map__expand() which can be used in these two cases which does
behave in that way. It doesn't look like it needs any more re-writing,
it's just the perf_cpu_map__intersect() needs to behave slightly
differently in this case.

It's because ETM cares about validating and saving the configuration
per-core, even if you finally open the event with CPU==-1, because later
we'll need all that info to decode the trace.

Although I can't see what scenario that you wouldn't want ('any'
intersect '1,2') == '1,2'. Is there any code in Perf that's already
doing that that would be broken by that change? It might be best to have
that behavior earlier rather than later in case something does start
depending on it.

As far as I know you can't do both per-thread and per-cpu sessions in
Perf, so it doesn't really matter how the intersection behaves in that
scenario.

> Thanks,
> Ian
> 
>>>>                              ete++;
>>>> -                    else if (cs_etm_is_etmv4(itr, i))
>>>> +                    else if (cs_etm_is_etmv4(itr, cpu.cpu))
>>>>                              etmv4++;
>>>>                      else
>>>>                              etmv3++;
>>>>              }
>>>> +            perf_cpu_map__put(intersect_cpus);
>>>>      } else {
>>>>              /* get configuration for all CPUs in the system */
>>>> -            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))
>>>> +            perf_cpu_map__for_each_cpu(cpu, idx, online_cpus) {
>>>> +                    if (cs_etm_is_ete(itr, cpu.cpu))
>>>>                              ete++;
>>>> -                    else if (cs_etm_is_etmv4(itr, i))
>>>> +                    else if (cs_etm_is_etmv4(itr, cpu.cpu))
>>>>                              etmv4++;
>>>>                      else
>>>>                              etmv3++;
>>>> @@ -814,15 +802,14 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
>>>>              return -EINVAL;
>>>>
>>>>      /* If the cpu_map is empty all online CPUs are involved */
>>>> -    if (perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
>>>> +    if (perf_cpu_map__is_empty(event_cpus)) {
>>>>              cpu_map = online_cpus;
>>>>      } else {
>>>>              /* Make sure all specified CPUs are online */
>>>> -            for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) {
>>>> -                    struct perf_cpu cpu = { .cpu = i, };
>>>> +            struct perf_cpu cpu;
>>>>
>>>> -                    if (perf_cpu_map__has(event_cpus, cpu) &&
>>>> -                        !perf_cpu_map__has(online_cpus, cpu))
>>>> +            perf_cpu_map__for_each_cpu(cpu, i, event_cpus) {
>>>> +                    if (!perf_cpu_map__has(online_cpus, cpu))
>>>>                              return -EINVAL;
>>>>              }
>>>>
>>>> diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
>>>> index 51ccbfd3d246..0b52e67edb3b 100644
>>>> --- a/tools/perf/arch/arm64/util/arm-spe.c
>>>> +++ b/tools/perf/arch/arm64/util/arm-spe.c
>>>> @@ -232,7 +232,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
>>>>       * In the case of per-cpu mmaps, sample CPU for AUX event;
>>>>       * also enable the timestamp tracing for samples correlation.
>>>>       */
>>>> -    if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
>>>> +    if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>>>>              evsel__set_sample_bit(arm_spe_evsel, CPU);
>>>>              evsel__set_config_if_unset(arm_spe_pmu, arm_spe_evsel,
>>>>                                         "ts_enable", 1);
>>>> @@ -265,7 +265,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
>>>>      tracking_evsel->core.attr.sample_period = 1;
>>>>
>>>>      /* In per-cpu case, always need the time of mmap events etc */
>>>> -    if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
>>>> +    if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>>>>              evsel__set_sample_bit(tracking_evsel, TIME);
>>>>              evsel__set_sample_bit(tracking_evsel, CPU);
>>>>


From sebastianene at google.com  Thu Feb  1 03:20:53 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Thu, 1 Feb 2024 11:20:53 +0000
Subject: [PATCH v4 02/10] KVM: arm64: Add ptdump registration with
 debugfs for the stage-2 pagetables
In-Reply-To: <ZYSAfORj2-cXo5t_@linux.dev>
References: <20231218135859.2513568-2-sebastianene@google.com>
 <20231218135859.2513568-4-sebastianene@google.com>
 <ZYSAfORj2-cXo5t_@linux.dev>
Message-ID: <Zbt-leieTD64ZefR@google.com>

On Thu, Dec 21, 2023 at 06:14:20PM +0000, Oliver Upton wrote:

Hi Oliver,

I am planning to split the series based on your suggestion and I
wanted to make sure that I understand your feedback.

> On Mon, Dec 18, 2023 at 01:58:52PM +0000, Sebastian Ene wrote:
> > +config PTDUMP_STAGE2_DEBUGFS
> > +       bool "Present the stage-2 pagetables to debugfs"
> > +       depends on PTDUMP_DEBUGFS && KVM
> > +       default n
> > +       help
> > +         Say Y here if you want to show the stage-2 kernel pagetables
> > +         layout in a debugfs file. This information is only useful for kernel developers
> > +         who are working in architecture specific areas of the kernel.
> > +         It is probably not a good idea to enable this feature in a production
> > +         kernel.
> 
> It isn't really a good idea to mount debugfs at all in a production
> system. There are already plenty worse interfaces lurking in that
> filesystem. The pKVM portions already depend on CONFIG_NVHE_EL2_DEBUG,
> so I don't see a need for this Kconfig option.
> 

I created a separate option because I wanted to re-use the parsing
functionality from the already existing ptdump code for EL1. This option
is turned off in production and only enabled for debug.

I was thinking to make use of the `CONFIG_NVHE_EL2_DEBUG` but then I abandoned 
this ideea as one can use ptdump for vHE as well.

> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index e5f75f1f1..ee8d7cb67 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -40,6 +40,7 @@
> >  #include <asm/kvm_pkvm.h>
> >  #include <asm/kvm_emulate.h>
> >  #include <asm/sections.h>
> > +#include <kvm_ptdump.h>
> >  
> >  #include <kvm/arm_hypercalls.h>
> >  #include <kvm/arm_pmu.h>
> > @@ -2592,6 +2593,7 @@ static __init int kvm_arm_init(void)
> >  	if (err)
> >  		goto out_subs;
> >  
> > +	kvm_ptdump_register_host();
> >  	kvm_arm_initialised = true;
> >  
> >  	return 0;
> > diff --git a/arch/arm64/kvm/kvm_ptdump.h b/arch/arm64/kvm/kvm_ptdump.h
> > new file mode 100644
> > index 000000000..98b595ce8
> > --- /dev/null
> > +++ b/arch/arm64/kvm/kvm_ptdump.h
> > @@ -0,0 +1,18 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +//
> > +// Copyright (C) Google, 2023
> > +// Author: Sebastian Ene <sebastianene at google.com>
> 
> You've got the comment styles backwards for these. The SPDX license uses
> the 'C++' style comment (//), whereas your multiline comment should always
> use a 'C' style comment (/* */).
>

Let me fix this, thanks.

> > +struct kvm_ptdump_register {
> > +	void *(*get_ptdump_info)(struct kvm_ptdump_register *reg);
> > +	void (*put_ptdump_info)(void *priv);
> > +	int (*show_ptdump_info)(struct seq_file *m, void *v);
> > +	void *priv;
> > +};
> 
> Please thoroughly consider the necessity of this. You're wrapping a
> callback structure with yet another callback structure. IMO, it would
> make a lot more sense to implement the file ops structure for every
> walker variant you need and avoid the indirection, it's hard to
> understand.
>

I think we can drop this and have different file_ops.

> > +void kvm_ptdump_register_host(void)
> > +{
> > +	if (!is_protected_kvm_enabled())
> > +		return;
> > +
> > +	kvm_ptdump_debugfs_register(&host_reg, "host_page_tables",
> > +				    kvm_debugfs_dir);
> > +}
> > +
> > +static int __init kvm_host_ptdump_init(void)
> > +{
> > +	host_reg.priv = (void *)host_s2_pgtable_pages();
> > +	return 0;
> > +}
> > +
> > +device_initcall(kvm_host_ptdump_init);
> 
> Why can't all of this be called from finalize_pkvm()?
> 

I guess it can be called from finalize_pkvm before the is_protected_kvm_enabled
check. This should work for nvhe & vhe as well.

Thanks,
Seb

> > -- 
> > 2.43.0.472.g3155946c3a-goog
> > 
> 
> -- 
> Thanks,
> Oliver


From cristian.marussi at arm.com  Thu Feb  1 03:19:30 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Thu, 1 Feb 2024 11:19:30 +0000
Subject: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <DU0PR04MB9417A9074C5DC49AE689E65288432@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20240121-pinctrl-scmi-v3-0-8d94ba79dca8@nxp.com>
 <f88d07ef-83b2-4d14-976a-6dbbd71e036f@oss.nxp.com>
 <CACRpkdYV=qYQ9qDUWYTLDAV1niay30gYH5S=zjfi31GpeY5o-A@mail.gmail.com>
 <DU0PR04MB9417A9074C5DC49AE689E65288432@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <Zbt-QkWhz5d9P-v6@pluto>

On Thu, Feb 01, 2024 at 07:14:17AM +0000, Peng Fan wrote:
> > Subject: Re: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
> > protocol basic support
> > 

Hi Peng,

> > On Mon, Jan 29, 2024 at 1:37?PM Peng Fan <peng.fan at oss.nxp.com> wrote:
> > 
> > > And for i.MX95 OEM extenstion, do you have any suggestions?
> > > I have two points:
> > > 1. use vendor compatible. This would also benefit when supporting
> > > vendor protocol.
> > > 2. Introduce a property saying supporting-generic-pinconf
> > >
> > > How do you think?
> > 
> > While I don't know how OEM extensions to SCMI were designed, the pin
> > control subsystem has the philosophy that extensions are for minor fringe
> > stuff, such as a pin config option that no other silicon is using and thus have
> > no use for anyone else. Well that is actually all the custom extensions we
> > have.
> > (This notion is even carried over to SCMI pinctrl.)
> > 
> > The i.MX95 OEM extension is really odd to me, it looks like a
> > reimplementation of the core aspects of SCMI pin control, and looks much
> > more like the old i.MX drivers than like the SCMI driver.
> 
> i.MX SCMI pin protocol conf settings follows non-SCMI pin conf settings.
> 

It is not just a matter of using custom SCMI OEM types, it is the whole
layout/definitions of the i.MX pin/groups/funcs DT bindings that deviates from
the generic DT bindings layout as handled and expected by the Linux Pinctrl
subsystem (AFAIU), while the SCMI Pinctrl driver as it stands in this series,
was conceived, designed and implemented originally by Oleksii to just use the
generic existing Pinctrl DT bindings; as a consequence, in your i.MX extensions,
you had to add a dedicated i.MX DT parser to interpret the protocol at 19 DT snippet
in a completely different way, to try to stick your custom solution on top of
the generic one.

Thanks,
Cristian

> > 
> > But I sure cannot speak of what is allowed in SCMI OEM extensions or not.
> 
> + SPEC owner, Souvik. Any comments?
> 
> Thanks,
> Peng.
> 
> > 
> > Yours,
> > Linus Walleij


From broonie at kernel.org  Thu Feb  1 03:25:27 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 1 Feb 2024 11:25:27 +0000
Subject: [PATCH 0/7] ASoC: mediatek: AFE drivers cleanups
In-Reply-To: <cace3472-7ee3-459b-ab2c-51764db99bd7@collabora.com>
References: <20240111105247.117766-1-angelogioacchino.delregno@collabora.com>
 <cace3472-7ee3-459b-ab2c-51764db99bd7@collabora.com>
Message-ID: <6f7a34b6-6f65-42c3-a92d-6b064bf9dee1@sirena.org.uk>

On Thu, Feb 01, 2024 at 11:08:41AM +0100, AngeloGioacchino Del Regno wrote:
> Il 11/01/24 11:52, AngeloGioacchino Del Regno ha scritto:
> > This series converts MediaTek AFE drivers' probe functions to use
> > dev_err_probe() and devm functions where possible and, in some
> > cases, dropping the .remove_new() callback, reducing the size.

> Gentle ping for this series, afraid that went out of the radar :-)

Please don't send content free pings and please allow a reasonable time
for review.  People get busy, go on holiday, attend conferences and so 
on so unless there is some reason for urgency (like critical bug fixes)
please allow at least a couple of weeks for review.  If there have been
review comments then people may be waiting for those to be addressed.

Sending content free pings adds to the mail volume (if they are seen at
all) which is often the problem and since they can't be reviewed
directly if something has gone wrong you'll have to resend the patches
anyway, so sending again is generally a better approach though there are
some other maintainers who like them - if in doubt look at how patches
for the subsystem are normally handled.
-------------- 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/20240201/328eca79/attachment.sig>

From james.clark at arm.com  Thu Feb  1 03:25:47 2024
From: james.clark at arm.com (James Clark)
Date: Thu, 1 Feb 2024 11:25:47 +0000
Subject: [PATCH v2 3/8] perf arm-spe/cs-etm: Directly iterate CPU maps
In-Reply-To: <20240201042236.1538928-4-irogers@google.com>
References: <20240201042236.1538928-1-irogers@google.com>
 <20240201042236.1538928-4-irogers@google.com>
Message-ID: <9d177173-c66f-a0d3-ba4d-2261f8663fce@arm.com>



On 01/02/2024 04:22, Ian Rogers wrote:
> Rather than iterate all CPUs and see if they are in CPU maps, directly
> iterate the CPU map. Similarly make use of the intersect
> function. Switch perf_cpu_map__has_any_cpu_or_is_empty to more
> appropriate alternatives.
> 
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/perf/arch/arm/util/cs-etm.c    | 77 ++++++++++++----------------
>  tools/perf/arch/arm64/util/arm-spe.c |  4 +-
>  2 files changed, 34 insertions(+), 47 deletions(-)
> 
> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> index 77e6663c1703..f4378ba0b8d6 100644
> --- a/tools/perf/arch/arm/util/cs-etm.c
> +++ b/tools/perf/arch/arm/util/cs-etm.c
> @@ -197,38 +197,32 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr,
>  static int cs_etm_validate_config(struct auxtrace_record *itr,
>  				  struct evsel *evsel)
>  {
> -	int i, err = -EINVAL;
> +	int idx, err = -EINVAL;
>  	struct perf_cpu_map *event_cpus = evsel->evlist->core.user_requested_cpus;
>  	struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
> +	struct perf_cpu_map *intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);

Hi Ian,

This has the same issue as V1. 'any' intersect 'online' == empty. Now no
validation happens anymore. For this to be the same as it used to be,
validation has to happen on _all_ cores when event_cpus == -1. So it
needs to be 'any' intersect 'online' == 'online'.

Same issue below with cs_etm_info_priv_size()

Thanks
James

> +	struct perf_cpu cpu;
>  
> -	/* Set option of each CPU we have */
> -	for (i = 0; i < cpu__max_cpu().cpu; i++) {
> -		struct perf_cpu cpu = { .cpu = i, };
> -
> -		/*
> -		 * In per-cpu case, do the validation for CPUs to work with.
> -		 * In per-thread case, the CPU map is empty.  Since the traced
> -		 * program can run on any CPUs in this case, thus don't skip
> -		 * validation.
> -		 */
> -		if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus) &&
> -		    !perf_cpu_map__has(event_cpus, cpu))
> -			continue;
> -
> -		if (!perf_cpu_map__has(online_cpus, cpu))
> -			continue;
> +	perf_cpu_map__put(online_cpus);
>  
> -		err = cs_etm_validate_context_id(itr, evsel, i);
> +	/*
> +	 * Set option of each CPU we have. In per-cpu case, do the validation
> +	 * for CPUs to work with.  In per-thread case, the CPU map is empty.
> +	 * Since the traced program can run on any CPUs in this case, thus don't
> +	 * skip validation.
> +	 */
> +	perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
> +		err = cs_etm_validate_context_id(itr, evsel, cpu.cpu);
>  		if (err)
>  			goto out;
> -		err = cs_etm_validate_timestamp(itr, evsel, i);
> +		err = cs_etm_validate_timestamp(itr, evsel, cpu.cpu);
>  		if (err)
>  			goto out;
>  	}
>  
>  	err = 0;
>  out:
> -	perf_cpu_map__put(online_cpus);
> +	perf_cpu_map__put(intersect_cpus);
>  	return err;
>  }
>  
> @@ -435,7 +429,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
>  	 * Also the case of per-cpu mmaps, need the contextID in order to be notified
>  	 * when a context switch happened.
>  	 */
> -	if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> +	if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>  		evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
>  					   "timestamp", 1);
>  		evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
> @@ -461,7 +455,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
>  	evsel->core.attr.sample_period = 1;
>  
>  	/* In per-cpu case, always need the time of mmap events etc */
> -	if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus))
> +	if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
>  		evsel__set_sample_bit(evsel, TIME);
>  
>  	err = cs_etm_validate_config(itr, cs_etm_evsel);
> @@ -533,38 +527,32 @@ static size_t
>  cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
>  		      struct evlist *evlist __maybe_unused)
>  {
> -	int i;
> +	int idx;
>  	int etmv3 = 0, etmv4 = 0, ete = 0;
>  	struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus;
>  	struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
> +	struct perf_cpu cpu;
>  
>  	/* cpu map is not empty, we have specific CPUs to work with */
> -	if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
> -		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 (!perf_cpu_map__is_empty(event_cpus)) {
> +		struct perf_cpu_map *intersect_cpus =
> +			perf_cpu_map__intersect(event_cpus, online_cpus);
>  
> -			if (cs_etm_is_ete(itr, i))
> +		perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
> +			if (cs_etm_is_ete(itr, cpu.cpu))
>  				ete++;
> -			else if (cs_etm_is_etmv4(itr, i))
> +			else if (cs_etm_is_etmv4(itr, cpu.cpu))
>  				etmv4++;
>  			else
>  				etmv3++;
>  		}
> +		perf_cpu_map__put(intersect_cpus);
>  	} else {
>  		/* get configuration for all CPUs in the system */
> -		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))
> +		perf_cpu_map__for_each_cpu(cpu, idx, online_cpus) {
> +			if (cs_etm_is_ete(itr, cpu.cpu))
>  				ete++;
> -			else if (cs_etm_is_etmv4(itr, i))
> +			else if (cs_etm_is_etmv4(itr, cpu.cpu))
>  				etmv4++;
>  			else
>  				etmv3++;
> @@ -814,15 +802,14 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
>  		return -EINVAL;
>  
>  	/* If the cpu_map is empty all online CPUs are involved */
> -	if (perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
> +	if (perf_cpu_map__is_empty(event_cpus)) {
>  		cpu_map = online_cpus;
>  	} else {
>  		/* Make sure all specified CPUs are online */
> -		for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) {
> -			struct perf_cpu cpu = { .cpu = i, };
> +		struct perf_cpu cpu;
>  
> -			if (perf_cpu_map__has(event_cpus, cpu) &&
> -			    !perf_cpu_map__has(online_cpus, cpu))
> +		perf_cpu_map__for_each_cpu(cpu, i, event_cpus) {
> +			if (!perf_cpu_map__has(online_cpus, cpu))
>  				return -EINVAL;
>  		}
>  
> diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
> index 51ccbfd3d246..0b52e67edb3b 100644
> --- a/tools/perf/arch/arm64/util/arm-spe.c
> +++ b/tools/perf/arch/arm64/util/arm-spe.c
> @@ -232,7 +232,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
>  	 * In the case of per-cpu mmaps, sample CPU for AUX event;
>  	 * also enable the timestamp tracing for samples correlation.
>  	 */
> -	if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> +	if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>  		evsel__set_sample_bit(arm_spe_evsel, CPU);
>  		evsel__set_config_if_unset(arm_spe_pmu, arm_spe_evsel,
>  					   "ts_enable", 1);
> @@ -265,7 +265,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
>  	tracking_evsel->core.attr.sample_period = 1;
>  
>  	/* In per-cpu case, always need the time of mmap events etc */
> -	if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> +	if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>  		evsel__set_sample_bit(tracking_evsel, TIME);
>  		evsel__set_sample_bit(tracking_evsel, CPU);
>  


From peter.griffin at linaro.org  Thu Feb  1 03:29:36 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu, 1 Feb 2024 11:29:36 +0000
Subject: [PATCH v2 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <fb530eb8-e32b-4faf-81f3-efc334ebf241@linaro.org>
References: <20240129211912.3068411-1-peter.griffin@linaro.org>
 <20240129211912.3068411-2-peter.griffin@linaro.org> <fb530eb8-e32b-4faf-81f3-efc334ebf241@linaro.org>
Message-ID: <CADrjBPrNryfccFkrZWY9_4EfDF1h3VyqKcxh8vim9Hp8D_AhkQ@mail.gmail.com>

Hi Krzysztof,

Thanks for the review feedback.

On Tue, 30 Jan 2024 at 16:01, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 29/01/2024 22:19, Peter Griffin wrote:
> > Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> > security hardening reasons so that they are only accessible in el3 via an
> > SMC call.
> >
> > As most Exynos drivers that need to write PMU registers currently obtain a
> > regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> > is implemented in this driver using a custom regmap similar to syscon to
> > handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> > regmap like before. As regmaps abstract out the underlying register access
> > changes to the leaf drivers are minimal.
> >
> > A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> > that currently use syscon_regmap_lookup_by_phandle(). This also handles
> > deferred probing.
> >
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > ---
> >  drivers/soc/samsung/exynos-pmu.c       | 227 ++++++++++++++++++++++++-
> >  include/linux/soc/samsung/exynos-pmu.h |  10 ++
> >  2 files changed, 236 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> > index 250537d7cfd6..7bcc144e53a2 100644
> > --- a/drivers/soc/samsung/exynos-pmu.c
> > +++ b/drivers/soc/samsung/exynos-pmu.c
> > @@ -5,6 +5,7 @@
> >  //
> >  // Exynos - CPU PMU(Power Management Unit) support
> >
> > +#include <linux/arm-smccc.h>
> >  #include <linux/of.h>
> >  #include <linux/of_address.h>
> >  #include <linux/mfd/core.h>
> > @@ -12,20 +13,159 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/delay.h>
> > +#include <linux/regmap.h>
> >
> >  #include <linux/soc/samsung/exynos-regs-pmu.h>
> >  #include <linux/soc/samsung/exynos-pmu.h>
> >
> >  #include "exynos-pmu.h"
> >
> > +static struct platform_driver exynos_pmu_driver;
>
> I don't understand why do you need it. You can have only one
> pmu_context. The moment you probe second one, previous becomes invalid.
>
> I guess you want to parse phandle and check if just in case if it points
> to the right device, but still the original code is not ready for two
> PMU devices. I say either this problem should be solved entirely,
> allowing two devices, or just compare device node from phandle with
> device node of exynos_pmu_context->dev and return -EINVAL on mismatches.

I'll update like you suggest in v3.

>
> Anyway, keep all file scope declarations together.

OK
>
>
> > +
> > +#define PMUALIVE_MASK GENMASK(14, 0)
> > +
> >  struct exynos_pmu_context {
> >       struct device *dev;
> >       const struct exynos_pmu_data *pmu_data;
> > +     struct regmap *pmureg;
> >  };
> >
> >  void __iomem *pmu_base_addr;
> >  static struct exynos_pmu_context *pmu_context;
> >
> > +/*
> > + * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
> > + * from el3. As Linux needs to write some of these registers, the following
> > + * SMC register read/write/read,write,modify interface is used.
> > + *
> > + * Note: This SMC interface is known to be implemented on gs101 and derivative
> > + * SoCs.
> > + */
> > +#define TENSOR_SMC_PMU_SEC_REG                       (0x82000504)
> > +#define TENSOR_PMUREG_READ                   0
> > +#define TENSOR_PMUREG_WRITE                  1
> > +#define TENSOR_PMUREG_RMW                    2
> > +
> > +/**
> > + * tensor_sec_reg_write
> > + * Write to a protected SMC register.
> > + * @base: Base address of PMU
> > + * @reg:  Address offset of register
> > + * @val:  Value to write
> > + * Return: (0) on success
> > + *
>
> This does not really look like kerneldoc...

Sam suggested that I remove the kerneldoc and replace with a one line
comment in v3
>
> > + */
> > +static int tensor_sec_reg_write(void *base, unsigned int reg, unsigned int val)
> > +{
> > +     struct arm_smccc_res res;
> > +     unsigned long pmu_base = (unsigned long)base;
> > +
> > +     arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG,
> > +                   pmu_base + reg,
> > +                   TENSOR_PMUREG_WRITE,
> > +                   val, 0, 0, 0, 0, &res);
> > +
> > +     if (res.a0)
> > +             pr_warn("%s(): SMC failed: %lu\n", __func__, res.a0);
> > +
> > +     return (int)res.a0;
> > +}
> > +
> > +/**
> > + * tensor_sec_reg_rmw
> > + * Read/Modify/Write to a protected SMC register.
> > + * @base: Base address of PMU
> > + * @reg:  Address offset of register
> > + * @val:  Value to write
> > + * Return: (0) on success
> > + *
> > + */
> > +static int tensor_sec_reg_rmw(void *base, unsigned int reg,
> > +                           unsigned int mask, unsigned int val)
> > +{
> > +     struct arm_smccc_res res;
> > +     unsigned long pmu_base = (unsigned long)base;
> > +
> > +     arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG,
> > +                   pmu_base + reg,
> > +                   TENSOR_PMUREG_RMW,
> > +                   mask, val, 0, 0, 0, &res);
> > +
> > +     if (res.a0)
> > +             pr_warn("%s(): SMC failed: %lu\n", __func__, res.a0);
> > +
> > +     return (int)res.a0;
> > +}
> > +
> > +/**
> > + * tensor_sec_reg_read
> > + * Read a protected SMC register.
> > + * @base: Base address of PMU
> > + * @reg:  Address offset of register
> > + * @val:  Value read
> > + * Return: (0) on success
> > + */
> > +static int tensor_sec_reg_read(void *base, unsigned int reg, unsigned int *val)
> > +{
> > +     struct arm_smccc_res res;
> > +     unsigned long pmu_base = (unsigned long)base;
> > +
> > +     arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG,
> > +                   pmu_base + reg,
> > +                   TENSOR_PMUREG_READ,
> > +                   0, 0, 0, 0, 0, &res);
> > +
> > +     *val = (unsigned int)res.a0;
> > +
> > +     return 0;
> > +}
> > +
> > +
> > +/*
> > + * For SoCs that have set/clear bit hardware this function
> > + * can be used when the PMU register will be accessed by
> > + * multiple masters.
> > + *
> > + * For example, to set bits 13:8 in PMU reg offset 0x3e80
> > + * tensor_set_bit_atomic(0x3e80, 0x3f00, 0x3f00);
> > + *
> > + * To clear bits 13:8 in PMU offset 0x3e80
> > + * tensor_set_bit_atomic(0x3e80, 0x0, 0x3f00);
> > + */
> > +static inline void tensor_set_bit_atomic(void *ctx, unsigned int offset,
> > +                                      u32 val, u32 mask)
> > +{
> > +     unsigned int i;
> > +
> > +     for (i = 0; i < 32; i++) {
> > +             if (mask & BIT(i)) {
> > +                     if (val & BIT(i)) {
> > +                             offset |= 0xc000;
> > +                             tensor_sec_reg_write(ctx, offset, i);
> > +                     } else {
> > +                             offset |= 0x8000;
> > +                             tensor_sec_reg_write(ctx, offset, i);
> > +                     }
> > +             }
> > +     }
> > +}
> > +
> > +int tensor_sec_update_bits(void *ctx, unsigned int reg, unsigned int mask, unsigned int val)
> > +{
> > +     int ret = 0;
> > +
> > +     /*
> > +      * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
> > +      * as the target registers can be accessed by multiple masters.
> > +      */
> > +     if (reg > PMUALIVE_MASK)
> > +             return tensor_sec_reg_rmw(ctx, reg, mask, val);
> > +
> > +     tensor_set_bit_atomic(ctx, reg, val, mask);
> > +
> > +     return ret;
> > +}
> > +
> >  void pmu_raw_writel(u32 val, u32 offset)
> >  {
> >       writel_relaxed(val, pmu_base_addr + offset);
> > @@ -80,6 +220,8 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
> >   */
> >  static const struct of_device_id exynos_pmu_of_device_ids[] = {
> >       {
> > +             .compatible = "google,gs101-pmu",
> > +     }, {
> >               .compatible = "samsung,exynos3250-pmu",
> >               .data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
> >       }, {
> > @@ -113,19 +255,73 @@ static const struct mfd_cell exynos_pmu_devs[] = {
> >       { .name = "exynos-clkout", },
> >  };
> >
> > +/**
> > + * exynos_get_pmu_regmap
> > + * Find the pmureg previously configured in probe() and return regmap property.
> > + * Return: regmap if found or error if not found.
> > + */
> >  struct regmap *exynos_get_pmu_regmap(void)
> >  {
> >       struct device_node *np = of_find_matching_node(NULL,
> >                                                     exynos_pmu_of_device_ids);
> >       if (np)
> > -             return syscon_node_to_regmap(np);
> > +             return exynos_get_pmu_regmap_by_phandle(np, NULL);
> >       return ERR_PTR(-ENODEV);
> >  }
> >  EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
> >
> > +/**
> > + * exynos_get_pmu_regmap_by_phandle
> > + * Find the pmureg previously configured in probe() and return regmap property.
> > + * Return: regmap if found or error if not found.
>
> Return is the last. This does not look tested - make htmldocs, make W=1

Thanks, will fix and test in v3.

>
> > + *
> > + * @np: Pointer to device's Device Tree node
> > + * @property: Device Tree property name which references the pmu
> > + */
> > +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> > +                                             const char *property)
> > +{
> > +     struct device *dev;
> > +     struct exynos_pmu_context *ctx;
> > +     struct device_node *pmu_np;
> > +
> > +     if (property)
> > +             pmu_np = of_parse_phandle(np, property, 0);
> > +     else
> > +             pmu_np = np;
> > +
> > +     if (!pmu_np)
> > +             return ERR_PTR(-ENODEV);
> > +
> > +     dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
> > +                                         (void *)pmu_np);
> > +     of_node_put(pmu_np);
> > +     if (!dev)
> > +             return ERR_PTR(-EPROBE_DEFER);
> > +
> > +     ctx = dev_get_drvdata(dev);
> > +
> > +     return ctx->pmureg;
> > +}
> > +EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
> > +
> > +static struct regmap_config pmu_regs_regmap_cfg = {
> > +     .name = "pmu_regs",
> > +     .reg_bits = 32,
> > +     .reg_stride = 4,
> > +     .val_bits = 32,
> > +     .fast_io = true,
> > +     .use_single_read = true,
> > +     .use_single_write = true,
> > +};
> > +
> >  static int exynos_pmu_probe(struct platform_device *pdev)
> >  {
> > +     struct resource *res;
> > +     struct regmap *regmap;
> > +     struct regmap_config pmuregmap_config = pmu_regs_regmap_cfg;
> >       struct device *dev = &pdev->dev;
> > +     struct device_node *np = dev->of_node;
>
> Please do not mix order declarations with and without initializations. I
> propose first ones with initializations, followed by ones without.

Will fix.

>
> >       int ret;
> >
> >       pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
> > @@ -137,6 +333,35 @@ static int exynos_pmu_probe(struct platform_device *pdev)
> >                       GFP_KERNEL);
> >       if (!pmu_context)
> >               return -ENOMEM;
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     if (!res)
> > +             return -ENODEV;
> > +
> > +     pmuregmap_config.max_register = resource_size(res) -
> > +                                  pmuregmap_config.reg_stride;
> > +
> > +     if (of_device_is_compatible(np, "google,gs101-pmu")) {
>
> No compatibles inside the probe. Use driver match data. This applies to
> all drivers in all subsystems.

Noted, will fix in v3.

>
> > +             pmuregmap_config.reg_read = tensor_sec_reg_read;
> > +             pmuregmap_config.reg_write = tensor_sec_reg_write;
> > +             pmuregmap_config.reg_update_bits = tensor_sec_update_bits;
>
> No, regmap_config should be const and please use match data.

Are you sure you want the regmap_config struct const?

In my draft v3 I have implemented it so far having a regmap_smccfg
struct which sets all the configuration apart from max_register field
(used by gs101) and a regmap_mmiocfg struct (used by all other
exynos-pmu SoCs). The choice over which regmap_config to register is
made via match data exynos_pmu_data flag 'pmu_secure' which is set
only for gs101. That avoids having to define exynos_pmu_data structs
for the other exynos SoCs that currently don't really need them
(exynos7, exynos850, exynos5443, exyno5410 etc).

But I still wish to set at runtime the regmap_config.max_register
field based on the resource size coming from DT. Having the structs
const would prohibit that and mean we need to specify many more
regmap_config structs where the only difference is the max_register
field.

Is the above approach acceptable for you?

>
> > +
> > +             /* Need physical address for SMC call */
> > +             regmap = devm_regmap_init(dev, NULL,
> > +                                       (void *)(uintptr_t)res->start,
> > +                                       &pmuregmap_config);
> > +     } else {
> > +             pmuregmap_config.max_register = resource_size(res) - 4;
> > +             regmap = devm_regmap_init_mmio(dev, pmu_base_addr,
> > +                                            &pmuregmap_config);
> > +     }
> > +
> > +     if (IS_ERR(regmap)) {
> > +             pr_err("regmap init failed\n");
>
> dev_err

Will fix

>
> > +             return PTR_ERR(regmap);
> > +     }
> > +
> > +     pmu_context->pmureg = regmap;
> >       pmu_context->dev = dev;
> >       pmu_context->pmu_data = of_device_get_match_data(dev);
> >
> > diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
> > index a4f5516cc956..68fb01ba6bef 100644
> > --- a/include/linux/soc/samsung/exynos-pmu.h
> > +++ b/include/linux/soc/samsung/exynos-pmu.h
> > @@ -21,11 +21,21 @@ enum sys_powerdown {
> >  extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
> >  #ifdef CONFIG_EXYNOS_PMU
> >  extern struct regmap *exynos_get_pmu_regmap(void);
> > +
> > +extern struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> > +                                                    const char *property);
>
> Drop extern from new code. I understand it makes it inconsistent but it
> extern does not matter, so at some point we will clean all existing code...

Will fix

Thanks,

Peter


From smostafa at google.com  Thu Feb  1 03:32:41 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 1 Feb 2024 11:32:41 +0000
Subject: [PATCH v4 02/16] iommu/arm-smmu-v3: Consolidate the STE
 generation for abort/bypass
In-Reply-To: <20240131144702.GJ1455070@nvidia.com>
References: <0-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <2-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <Zbpb2JSgnRuHGIo-@google.com>
 <20240131144702.GJ1455070@nvidia.com>
Message-ID: <ZbuBWQNEDqlFAoFi@google.com>

On Wed, Jan 31, 2024 at 10:47:02AM -0400, Jason Gunthorpe wrote:
> On Wed, Jan 31, 2024 at 02:40:24PM +0000, Mostafa Saleh wrote:
> > > +static void arm_smmu_make_bypass_ste(struct arm_smmu_ste *target)
> > > +{
> > > +	memset(target, 0, sizeof(*target));
> > 
> > I see this can be used with the actual STE. Although this is done at init, but
> > briefly making the STE abort from ?arm_smmu_make_bypass_ste?, seems a bit
> > fragile to me, in case we use this in the future in different scenarios, it
> > might break the hitless assumption. But no strong opinion though.
> 
> At init time, when that case happens, the STE table hasn't been
> installed in the HW yet. This is why that specific code path has been
> directly manipulating the STE and does not call the normal update path
> with the sync'ing.
> 
> It is perhaps subtle that is why it is a different flow.
> 
> (this is also why I moved the function order as it was a bit obscure
> to see that indeed all this stuff was sequenced right and we were not
> updating a live STE improperly)

I agree, this is not an issue, but it was just confusing when I first read it
as ?arm_smmu_make_bypass_ste? would make the STE transiently unavailable, and
I had to go and check the usage. Maybe we can add a comment to clarify how this
function is expected to be used.

Thanks,
Mostafa


From smostafa at google.com  Thu Feb  1 03:34:25 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 1 Feb 2024 11:34:25 +0000
Subject: [PATCH v4 05/16] iommu/arm-smmu-v3: Build the whole STE in
 arm_smmu_make_s2_domain_ste()
In-Reply-To: <5-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <5-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <ZbuBwSvDEowh4vjr@google.com>

Hi Jason,

On Thu, Jan 25, 2024 at 07:57:15PM -0400, Jason Gunthorpe wrote:
> Half the code was living in arm_smmu_domain_finalise_s2(), just move it
> here and take the values directly from the pgtbl_ops instead of storing
> copies.
> 
> Reviewed-by: Michael Shavit <mshavit at google.com>
> Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Moritz Fischer <moritzf at google.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 27 ++++++++++++---------
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  2 --
>  2 files changed, 15 insertions(+), 14 deletions(-)
> 
> 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 910156881423e0..9a95d0f1494223 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1552,6 +1552,11 @@ static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
>  					struct arm_smmu_domain *smmu_domain)
>  {
>  	struct arm_smmu_s2_cfg *s2_cfg = &smmu_domain->s2_cfg;
> +	const struct io_pgtable_cfg *pgtbl_cfg =
> +		&io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops)->cfg;
> +	typeof(&pgtbl_cfg->arm_lpae_s2_cfg.vtcr) vtcr =
> +		&pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
> +	u64 vtcr_val;
>  
>  	memset(target, 0, sizeof(*target));
>  	target->data[0] = cpu_to_le64(
> @@ -1562,9 +1567,16 @@ static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
>  		FIELD_PREP(STRTAB_STE_1_EATS,
>  			   master->ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0));
>  
> +	vtcr_val = FIELD_PREP(STRTAB_STE_2_VTCR_S2T0SZ, vtcr->tsz) |
> +		   FIELD_PREP(STRTAB_STE_2_VTCR_S2SL0, vtcr->sl) |
> +		   FIELD_PREP(STRTAB_STE_2_VTCR_S2IR0, vtcr->irgn) |
> +		   FIELD_PREP(STRTAB_STE_2_VTCR_S2OR0, vtcr->orgn) |
> +		   FIELD_PREP(STRTAB_STE_2_VTCR_S2SH0, vtcr->sh) |
> +		   FIELD_PREP(STRTAB_STE_2_VTCR_S2TG, vtcr->tg) |
> +		   FIELD_PREP(STRTAB_STE_2_VTCR_S2PS, vtcr->ps);
>  	target->data[2] = cpu_to_le64(
>  		FIELD_PREP(STRTAB_STE_2_S2VMID, s2_cfg->vmid) |
> -		FIELD_PREP(STRTAB_STE_2_VTCR, s2_cfg->vtcr) |
> +		FIELD_PREP(STRTAB_STE_2_VTCR, vtcr_val) |
>  		STRTAB_STE_2_S2AA64 |
>  #ifdef __BIG_ENDIAN
>  		STRTAB_STE_2_S2ENDI |
> @@ -1572,7 +1584,8 @@ static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
>  		STRTAB_STE_2_S2PTW |
>  		STRTAB_STE_2_S2R);
>  
> -	target->data[3] = cpu_to_le64(s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK);
> +	target->data[3] = cpu_to_le64(pgtbl_cfg->arm_lpae_s2_cfg.vttbr &
> +				      STRTAB_STE_3_S2TTB_MASK);
>  }
>  
>  static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
> @@ -2328,7 +2341,6 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
>  	int vmid;
>  	struct arm_smmu_device *smmu = smmu_domain->smmu;
>  	struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
> -	typeof(&pgtbl_cfg->arm_lpae_s2_cfg.vtcr) vtcr;
>  
>  	/* Reserve VMID 0 for stage-2 bypass STEs */
>  	vmid = ida_alloc_range(&smmu->vmid_map, 1, (1 << smmu->vmid_bits) - 1,
> @@ -2336,16 +2348,7 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
>  	if (vmid < 0)
>  		return vmid;
>  
> -	vtcr = &pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
>  	cfg->vmid	= (u16)vmid;
> -	cfg->vttbr	= pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
> -	cfg->vtcr	= FIELD_PREP(STRTAB_STE_2_VTCR_S2T0SZ, vtcr->tsz) |
> -			  FIELD_PREP(STRTAB_STE_2_VTCR_S2SL0, vtcr->sl) |
> -			  FIELD_PREP(STRTAB_STE_2_VTCR_S2IR0, vtcr->irgn) |
> -			  FIELD_PREP(STRTAB_STE_2_VTCR_S2OR0, vtcr->orgn) |
> -			  FIELD_PREP(STRTAB_STE_2_VTCR_S2SH0, vtcr->sh) |
> -			  FIELD_PREP(STRTAB_STE_2_VTCR_S2TG, vtcr->tg) |
> -			  FIELD_PREP(STRTAB_STE_2_VTCR_S2PS, vtcr->ps);
>  	return 0;
>  }
>  
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index 65fb388d51734d..eb669121f1954d 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -609,8 +609,6 @@ struct arm_smmu_ctx_desc_cfg {
>  
>  struct arm_smmu_s2_cfg {
>  	u16				vmid;
> -	u64				vttbr;
> -	u64				vtcr;
>  };
>  
>  struct arm_smmu_strtab_cfg {
> -- 
> 2.43.0
>

Reviewed-by: Mostafa Saleh <smostafa at google.com>

Thanks,
Mostafa


From frank-w at public-files.de  Thu Feb  1 03:40:17 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Thu, 01 Feb 2024 12:40:17 +0100
Subject: =?US-ASCII?Q?Re=3A_Aw=3A_Re=3A_=5BPATCH_v3_1/2=5D_dt-bindings?= =?US-ASCII?Q?=3A_reset=3A_mediatek=3A_add_MT7988_reset_IDs?=
In-Reply-To: <20240119-dupe-obligate-707b3a01b356@spud>
References: <20240117184111.62371-1-linux@fw-web.de> <20240117184111.62371-2-linux@fw-web.de> <20240118-calcium-krypton-3c787b8d1912@spud> <trinity-afc4f48e-65e1-46ee-a78b-1d670cc0f310-1705615200900@3c-app-gmx-bap21> <43f946cc-07e1-48c5-9b31-40fc9bc93037@collabora.com> <20240119-dupe-obligate-707b3a01b356@spud>
Message-ID: <0EA6A126-DDC0-4E9F-BEBC-FD018B08CA84@public-files.de>

Am 19. Januar 2024 18:04:36 MEZ schrieb Conor Dooley <conor at kernel.org>:
>On Fri, Jan 19, 2024 at 10:28:30AM +0100, AngeloGioacchino Del Regno wrote:
>>
>> The resets are organized on a per-reset-controller basis, so, the ETHWARP
>> reset controller's first reset is RST_SWITCH, the second one is RST_something_else,
>> etc. while the first reset of the INFRA reset controller is PEXTP_MAC_SWRST.
>> 
>> That's why ETHWARP has a reset index 0 and INFRA also starts at 0.
>> I think that the numbering is good as it is, and having one driver start at index 5
>> while the other starts at index 12 would only overcomplicate registering the resets
>> in each driver, or waste bytes by making unnecessarily large arrays, for (imo) no
>> good reason.
>> 
>> This is one header, but it should "in theory" be more than one... so we would have
>> one for each hardware block - but that'd make the reset directory over-crowded, as
>> other MediaTek SoCs have got even more resets in even more hardware blocks than the
>> MT7988. That'd be something like ~4 reset headers per SoC (and will increase with
>> newer ones)...
>> ...and this is why we have one binding header for resets.
>
>That's okay. The commit message leaves me, who clearly isn't a mediatek
>guy, with no information as to why these are not one contiguous set.
>IMO being for different reset controllers entirely is fine.
>
>> On the topic of leaving space to allow grouping RST0/RST1: -> No. <-
>> The indices have to start from zero and have to be sequential, with no holes.
>
>Agreed.

Hi,

Just a friendly reminder.

As far as i understood, Patches are fine so far and do not need any rework,right?

But i have not seen them picked up yet in linux-next.
regards Frank


From Dave.Martin at arm.com  Thu Feb  1 03:49:45 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 1 Feb 2024 11:49:45 +0000
Subject: [PATCH] arm64: jump_label: use constraint "S" instead of "i"
In-Reply-To: <20240201091120.pbgr7ng6t2c36fut@google.com>
References: <20240131065322.1126831-1-maskray@google.com>
 <CAMj1kXGzADFWa7RmXyjWpCnQ=9hhz6i-XkN4PS1CboZ-kFL8dQ@mail.gmail.com>
 <ZbpEnDK3U/O24ng0@e133380.arm.com>
 <20240201045551.ajg4iqcajyowl2rh@google.com>
 <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>
 <20240201091120.pbgr7ng6t2c36fut@google.com>
Message-ID: <ZbuFWSRBntgm2ukJ@e133380.arm.com>

On Thu, Feb 01, 2024 at 01:11:20AM -0800, Fangrui Song wrote:
> On 2024-02-01, Ard Biesheuvel wrote:
> > On Thu, 1 Feb 2024 at 05:55, Fangrui Song <maskray at google.com> wrote:
> > > 
> > > On 2024-01-31, Dave Martin wrote:
> > > >On Wed, Jan 31, 2024 at 08:16:04AM +0100, Ard Biesheuvel wrote:
> > > >> Hello Fangrui,
> > > >>
> > > >> On Wed, 31 Jan 2024 at 07:53, Fangrui Song <maskray at google.com> wrote:
> > > >> >
> > > >> > The constraint "i" seems to be copied from x86 (and with a redundant
> > > >> > modifier "c"). It works with -fno-PIE but not with -fPIE/-fPIC in GCC's
> > > >> > aarch64 port.
> > > >
> > > >(I'm not sure of the exact history, but the "c" may be inherited from
> > > >arm, where an output modifier was needed to suppress the "#" that
> > > >prefixes immediates in the traditional asm syntax.  This does not
> > > >actually seem to be required for AArch64: rather while a # is allowed
> > > >and still considered good style in handwritten asm code, the syntax
> > > >doesn't require it, and the compiler doesn't emit it for "i" arguments,
> > > >AFAICT.)
> > > 
> > > The aarch64 one could be inherited from
> > > arch/arm/include/asm/jump_label.h (2012), which could in turn be
> > > inherited from x86 (2010).
> > > Both the constraint "i" and the modifier "c" are generic..
> > > For -fno-pic this combination can be used for every arch.

Fair enough.  It wasn't clear to me that "c" was generic; the output
modifiers have always been a bit of a black art...

> > > 
> > > >> > The constraint "S", which denotes a symbol reference (e.g. function,
> > > >> > global variable) or label reference, is more appropriate, and has been
> > > >> > available in GCC since 2012 and in Clang since 7.0.
> > > >> >
> > > >> > Signed-off-by: Fangrui Song <maskray at google.com>
> > > >> > Link: https://maskray.me/blog/2024-01-30-raw-symbol-names-in-inline-assembly
> > > >> > ---
> > > >> >  arch/arm64/include/asm/jump_label.h | 8 ++++----
> > > >> >  1 file changed, 4 insertions(+), 4 deletions(-)
> > > >> >
> > > >> > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> > > >> > index 48ddc0f45d22..31862b3bb33d 100644
> > > >> > --- a/arch/arm64/include/asm/jump_label.h
> > > >> > +++ b/arch/arm64/include/asm/jump_label.h
> > > >> > @@ -23,9 +23,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
> > > >> >                  "      .pushsection    __jump_table, \"aw\"    \n\t"
> > > >> >                  "      .align          3                       \n\t"
> > > >> >                  "      .long           1b - ., %l[l_yes] - .   \n\t"
> > > >> > -                "      .quad           %c0 - .                 \n\t"
> > > >> > +                "      .quad           %0 - .                  \n\t"
> > > >> >                  "      .popsection                             \n\t"
> > > >> > -                :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> > > >> > +                :  :  "S"(&((char *)key)[branch]) :  : l_yes);
> > > >>
> > > >> 'key' is not used as a raw symbol name. We should make this
> > > >>
> > > >> "    .quad   %0 + %1 - ."
> > > >>
> > > >> and
> > > >>
> > > >> ::  "S"(key), "i"(branch) :: l_yes);
> > > >>
> > > >> if we want to really clean this up.
> > > >
> > > >This hides more logic in the asm so it's arguably more cryptic
> > > >(although the code is fairly cryptic to begin with -- I don't really
> > > >see why the argument wasn't written as the equivalent
> > > >(char *)key + branch...)
> > > 
> > > I agree that using "S" and "i" would introduce complexity.
> > > Using just "S" as this patch does should be clear.
> > > 
> > > All of "i" "s" "S" support a symbol or label reference and a constant offset (can be zero),
> > > (in object file, a symbol and an addend; in GCC's term, the sum of a SYMBOL_REF and a CONST_INT).
> > > 
> > 
> > Taken the address of a struct, cast it to char[] and then index it
> > using a boolean is rather disgusting, no?
> 
> I agree with you.
> 
> Hmm. Clang's constraint "S" implementation doesn't support a constant
> offset, so
> `static_key_false(&nf_hooks_needed[pf][hook])` in include/linux/netfilter.h:nf_hook
> would not compile with Clang <= 18.
> 
> I have a patch https://github.com/llvm/llvm-project/pull/80255 , but
> even if it is accepted and cherry-picked into the 18.x release branch,
> if we still support older Clang, we cannot use "S" unconditionally.
> 
> 
> So we probably need the following to prepare for -fPIE support in the
> future:
> 
> diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> index 48ddc0f45d22..b8af2f8b0c99 100644
> --- a/arch/arm64/include/asm/jump_label.h
> +++ b/arch/arm64/include/asm/jump_label.h
> @@ -15,6 +15,16 @@
>  #define JUMP_LABEL_NOP_SIZE		AARCH64_INSN_SIZE
> +/*
> + * Prefer "S" to support PIC. However, use "i" for Clang 18 and earlier as "S"
> + * on a symbol with a constant offset is not supported.
> + */
> +#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 18

Is a GCC version check needed?  Or is the minimum GCC version specified
for building the kernel new enough?

> +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
> +#else
> +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "S"
> +#endif
> +
>  static __always_inline bool arch_static_branch(struct static_key * const key,
>  					       const bool branch)
>  {
> @@ -23,9 +33,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
>  		 "	.pushsection	__jump_table, \"aw\"	\n\t"
>  		 "	.align		3			\n\t"
>  		 "	.long		1b - ., %l[l_yes] - .	\n\t"
> -		 "	.quad		%c0 - .			\n\t"
> +		 "	.quad		%0 + %1 - .		\n\t"
>  		 "	.popsection				\n\t"
> -		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> +		 :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);

While this looks reasonable, I'm still not clear now why the asm must do
the addition.

Can we roll the branch argument into the macro?

"S"(symbol + constant) seems to do the right thing for AArch64, at least
in GCC.

>  	return false;
>  l_yes:
> @@ -40,9 +50,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
>  		 "	.pushsection	__jump_table, \"aw\"	\n\t"
>  		 "	.align		3			\n\t"
>  		 "	.long		1b - ., %l[l_yes] - .	\n\t"
> -		 "	.quad		%c0 - .			\n\t"
> +		 "	.quad		%0 + %1 - .		\n\t"
>  		 "	.popsection				\n\t"
> -		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> +		 :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);
>  	return false;
>  l_yes:
> 
> 
> > > >Anyway, I don't think the "i" versys "S" distinction makes any
> > > >difference without -fpic or equivalent, so it is not really relevant
> > > >for the kernel (except that "S" breaks compatibility with older
> > > >compilers...)
> > > >
> > > >
> > > >I think the main advantage of "S" is that it stops you accidentally
> > > >emitting undesirable relocations from asm code that is not written for
> > > >the -fpic case.
> > > >
> > > >But just changing "i" to "S" is not sufficient to port asms to -fpic:
> > > >the asms still need to be reviewed.
> > > >
> > > >
> > > >So unless the asm has been reviewed for position-independence, it may
> > > >anyway be better to stick with "i" so that the compiler actually chokes
> > > >if someone tries to build the code with -fpic.
> > > 
> > 
> > The virtual address of the kernel is randomized by KASLR, which relies
> > on PIE linking, and this puts constraints on the permitted types of
> > relocations.
> > 
> > IOW, we basically already build the kernel as PIC code, but without
> > relying on -fPIC, because that triggers some behaviors that only make
> > sense for shared objects in user space.
> > 
> > > >Since we are not trying to run arbitraily many running kernels in a
> > > >common address space (and not likely to do that), I'm not sure that we
> > > >would ever build the kernel with -fpic except for a few special-case
> > > >bits like the EFI stub and vDSO... unless I've missed something?
> > > >
> > 
> > Yes, KASLR. The number of kernels is not the point, the point is that
> > the virtual load address of the kernel is usually decided at boot, and
> > so the code needs to be generated to accommodate that.
> > 
> > > >If there's another reason why "S" is advantageous though, I'm happy to
> > > >be corrected.
> > > 
> > > I remember that Ard has an RFC
> > > https://lore.kernel.org/linux-arm-kernel/20220427171241.2426592-1-ardb at kernel.org/
> > > "[RFC PATCH 0/2] arm64: use PIE code generation for KASLR kernel"
> > > and see some recent PIE codegen patches.
> > > 
> > > > Building the KASLR kernel without -fpie but linking it with -pie works
> > > > in practice, but it is not something that is explicitly supported by the
> > > > toolchains - it happens to work because the default 'small' code model
> > > > used by both GCC and Clang relies mostly on ADRP+ADD/LDR to generate
> > > > symbol references.

Does this mean that doing boot-time relocation on a fully statically
linked kernel doesn't bring much benefit?  It would tend to be more
painful to do the relocation work, and mean that the kernel text has to
be temporarily writeable, but static linking should have the best
runtime performance.

Maybe it doesn't make as much difference as I thought (certainly ADRP
based addressing should make a fair amount of the PIC/PIE overhead go
away).

> > > 
> > > I agree that current -fno-PIE with -shared -Bsymbolic linking is a hack
> > > that works as a conincidence, not guaranteed by the toolchain.
> > > This jump_label improvement (with no object file difference) fixes an
> > > obstacle.
> > 
> > If we can get the guaranteed behavior of #pragma GCC visibility
> > push(hidden) from a command line option, we should build the core
> > kernel with -fpie instead. (Modules are partially linked objects, so
> > they can be built non-PIC as before)
> > 
> I believe we don't have such a GCC option, but the effect can be
> simulated by -include hidden.h ...

[...]

Cheers
---Dave


From krzysztof.kozlowski at linaro.org  Thu Feb  1 03:56:43 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 12:56:43 +0100
Subject: (subset) [PATCH v2 3/3] arm64: dts: exynos: Add SPI nodes for
 Exynos850
In-Reply-To: <170678377409.179918.13077326172475089482.b4-ty@linaro.org>
References: <20240125013858.3986-1-semen.protsenko@linaro.org>
 <20240125013858.3986-4-semen.protsenko@linaro.org>
 <170678377409.179918.13077326172475089482.b4-ty@linaro.org>
Message-ID: <4c2c425b-3ddd-4484-98cf-3f7768c94e82@linaro.org>

On 01/02/2024 11:36, Krzysztof Kozlowski wrote:
> 
> On Wed, 24 Jan 2024 19:38:58 -0600, Sam Protsenko wrote:
>> Some USI blocks can be configured as SPI controllers. Add corresponding
>> SPI nodes to Exynos850 SoC device tree.
>>
>>
> 
> Applied, thanks!
> 
> [3/3] arm64: dts: exynos: Add SPI nodes for Exynos850
>       https://git.kernel.org/krzk/linux/c/98473b0d78caa5502b7eee05553ee168f0b0b424

And dropped. You did not test it.

For some time, all Samsung SoCs and its variants are expected not to
introduce any new `dtbs_check W=1` warnings. Several platforms, like all
ARM64 Samsung SoCs, have already zero warnings, thus for such platforms
it is extra easy for the submitter to validate DTS before posting a
patch. The patch briefly looks like it is not conforming to this rule.
Please confirm that you tested your patch and it does not introduce any
new warnings (linux-next is decisive here).

Best regards,
Krzysztof



From adiupina at astralinux.ru  Thu Feb  1 04:02:52 2024
From: adiupina at astralinux.ru (=?UTF-8?B?0JDQu9C10LrRgdCw0L3QtNGA0LAg0JTRjtC/0LjQvdCw?=)
Date: Thu, 1 Feb 2024 15:02:52 +0300
Subject: [PATCH] clk: keystone: sci-clk: check devm_kmalloc_array() return
 value
In-Reply-To: <20240110134621.17209-1-adiupina@astralinux.ru>
References: <20240110134621.17209-1-adiupina@astralinux.ru>
Message-ID: <93df720b-1d99-47e5-8a89-187d2bc119a1@astralinux.ru>

just a friendly reminder

10/01/24 16:46, Alexandra Diupina:
> devm_kmalloc_array() may return NULL, so
> check return value to avoid null pointer
> dereferencing
>
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
>
> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
> Signed-off-by: Alexandra Diupina <adiupina at astralinux.ru>
> ---
>   drivers/clk/keystone/sci-clk.c | 3 +++
>   1 file changed, 3 insertions(+)
>
> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> index 35fe197dd303..a2fa24e4f88a 100644
> --- a/drivers/clk/keystone/sci-clk.c
> +++ b/drivers/clk/keystone/sci-clk.c
> @@ -459,6 +459,9 @@ static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider)
>   			tmp_clks = devm_kmalloc_array(dev, max_clks + 64,
>   						      sizeof(sci_clk),
>   						      GFP_KERNEL);
> +			if (!tmp_clks)
> +				return -ENOMEM;
> +
>   			memcpy(tmp_clks, clks, max_clks * sizeof(sci_clk));
>   			if (max_clks)
>   				devm_kfree(dev, clks);




From rogerq at kernel.org  Thu Feb  1 04:03:27 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  1 Feb 2024 14:03:27 +0200
Subject: [PATCH v3 0/5] arm64: dts: ti: am62: Add USB support for k3-am62p
Message-ID: <20240201120332.4811-1-rogerq@kernel.org>

Hi,

This series first adds device nodes for USB0_PHY_CTRL and USB1_PHY_CTRL
in the wkup_conf node and fixus up the USB nodes to use the newly
added nodes.

Then it adds USB support for AM62P SoC and AM62P5-SK board.

In v3, 2 new patches were added to add the missing PHY2 register
space to the USB controller wrapper node.

Changelog in each patch.

cheers,
-roger

Roger Quadros (5):
  dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl compatible
  arm64: dts: ti: k3-am62/a: use sub-node for USB_PHY_CTRL registers
  arm64: dts: ti: k3-am62p: add the USB sub-system
  dt-bindings: usb/ti,am62-usb.yaml: Add PHY2 register space
  arm64: dts: ti: k3-am62*: Add PHY2 region to USB wrapper node

 .../devicetree/bindings/mfd/syscon.yaml       |  1 +
 .../devicetree/bindings/usb/ti,am62-usb.yaml  |  7 +-
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi      | 10 +--
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi    | 10 +++
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi     | 10 +--
 arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi   | 10 +++
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi     | 48 +++++++++++++
 arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi   | 10 +++
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts       | 67 +++++++++++++++++++
 9 files changed, 163 insertions(+), 10 deletions(-)


base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
-- 
2.34.1



From rogerq at kernel.org  Thu Feb  1 04:03:28 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  1 Feb 2024 14:03:28 +0200
Subject: [PATCH v3 1/5] dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl compatible
In-Reply-To: <20240201120332.4811-1-rogerq@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
Message-ID: <20240201120332.4811-2-rogerq@kernel.org>

Add the compatible for TI AM62 USB PHY Control register. This
register is found in the TI AM62 WKUP_CTRL_MMR0 space [1]. It
is used to indicate the USB PHY PLL reference clock rate and
core voltage level to the USB controller.

[1] - https://www.ti.com/lit/pdf/spruiv7

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---

Notes:
    Changelog:
    
    v3 - add compatibles in alphabetical order
    v2 - New patch
    
    Changelog:
    
    v2 - New patch

 Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index 084b5c2a2a3c..9437705af92f 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -72,6 +72,7 @@ properties:
               - rockchip,rk3588-qos
               - rockchip,rv1126-qos
               - starfive,jh7100-sysmain
+              - ti,am62-usb-phy-ctrl
               - ti,am654-dss-oldi-io-ctrl
 
           - const: syscon
-- 
2.34.1



From andriy.shevchenko at linux.intel.com  Thu Feb  1 03:32:57 2024
From: andriy.shevchenko at linux.intel.com ('andriy.shevchenko@linux.intel.com')
Date: Thu, 1 Feb 2024 13:32:57 +0200
Subject: [PATCH 30 7/7] Add AST2500 and AST2600 JTAG device in DTS
In-Reply-To: <ZbuBOmtyYdlmnCBa@smile.fi.intel.com>
References: <LV8PR11MB8463F88C2364A08DEF3ABAC28B7D2@LV8PR11MB8463.namprd11.prod.outlook.com>
 <ZbuBOmtyYdlmnCBa@smile.fi.intel.com>
Message-ID: <ZbuBaRyZJR9-ZS-K@smile.fi.intel.com>

On Thu, Feb 01, 2024 at 01:32:11PM +0200, 'andriy.shevchenko at linux.intel.com' wrote:
> On Tue, Jan 30, 2024 at 11:32:48PM +0000, Corona, Ernesto wrote:
> > Adding aspeed jtag device to device tree
> > 
> > Signed-off-by: Ernesto Corona <ernesto.corona at intel.com>
> > Signed-off-by: Omar Castro <omar.eduardo.castro at linux.intel.com>
> > Acked-by: Arnd Bergmann <arnd at arndb.de>
> 
> First of all, please use --thread to git-format-patch when preparing the
> series.
> 
> > Cc: Jiri Pirko <jiri at nvidia.com>
> > Cc: Vadim Pasternak <vadimp at mellanox.com>
> > Cc: Mauro Carvalho Chehab <mchehab+samsung at kernel.org>
> > Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> > Cc: David S. Miller <davem at davemloft.net>
> > Cc: Nicolas Ferre <nicolas.ferre at microchip.com>
> > Cc: Rob Herring <robh at kernel.org>
> > Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> > Cc: Lukas Bulwahn <lukas.bulwahn at gmail.com>
> > Cc: Steven Filary <steven.a.filary at intel.com>
> > Cc: Amithash Prasad <amithash at fb.com>
> > Cc: Patrick Williams <patrickw3 at fb.com>
> > Cc: Luke Chen <luke_chen at aspeedtech.com>
> > Cc: Billy Tsai <billy_tsai at aspeedtech.com>
> 
> Second, please avoid flooding commit message with unneeded details, i.e. move
> these Cc:s to...
> 
> > ---
> ...the after this cutter line.

Also, you may use standard versioning pattern by using -v31 next time for
git-format-patch (31 is an example, you may choose the correct version).

-- 
With Best Regards,
Andy Shevchenko




From rogerq at kernel.org  Thu Feb  1 04:03:29 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  1 Feb 2024 14:03:29 +0200
Subject: [PATCH v3 2/5] arm64: dts: ti: k3-am62/a: use sub-node for USB_PHY_CTRL registers
In-Reply-To: <20240201120332.4811-1-rogerq@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
Message-ID: <20240201120332.4811-3-rogerq@kernel.org>

Exposing the entire CTRL_MMR space to syscon is not a good idea.
Add sub-nodes for USB0_PHY_CTRL and USB1_PHY_CTRL and use them
in the USB0/USB1 nodes.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---

Notes:
    Changelog:
    
    v3 - no change
    
    v2:
    - moved am62p changes to next patch
    - use new compatible for USB PHY CTRL node

 arch/arm64/boot/dts/ti/k3-am62-main.dtsi    |  4 ++--
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi  | 10 ++++++++++
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi   |  4 ++--
 arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi | 10 ++++++++++
 4 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 464b7565d085..9432ed344d52 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -625,7 +625,7 @@ usbss0: dwc3-usb at f900000 {
 		reg = <0x00 0x0f900000 0x00 0x800>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
@@ -648,7 +648,7 @@ usbss1: dwc3-usb at f910000 {
 		reg = <0x00 0x0f910000 0x00 0x800>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
index fef76f52a52e..817700b2eacf 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -19,6 +19,16 @@ chipid: chipid at 14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	wkup_uart0: serial at 2b300000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index f0b8c9ab1459..8311c7c44cd3 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -566,7 +566,7 @@ usbss0: dwc3-usb at f900000 {
 		reg = <0x00 0x0f900000 0x00 0x800>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
@@ -589,7 +589,7 @@ usbss1: dwc3-usb at f910000 {
 		reg = <0x00 0x0f910000 0x00 0x800>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
index 4e8279fa01e1..4a375f5e0c19 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
@@ -17,6 +17,16 @@ chipid: chipid at 14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	wkup_uart0: serial at 2b300000 {
-- 
2.34.1



From rogerq at kernel.org  Thu Feb  1 04:03:30 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  1 Feb 2024 14:03:30 +0200
Subject: [PATCH v3 3/5] arm64: dts: ti: k3-am62p: add the USB sub-system
In-Reply-To: <20240201120332.4811-1-rogerq@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
Message-ID: <20240201120332.4811-4-rogerq@kernel.org>

There are two USB instances available on the am62p5 starter kit. Include
and enable them for use on the board.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Roger Quadros <rogerq at kernel.org>
---

Notes:
    Changelog:
    
    v3 - no change
    
    v2:
    - added USB PHY CTRL node changes here
    - changed USB wrapper node names to usb@
    - changed Type-C chip node name to usb-power-control@

 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi   | 46 ++++++++++++++
 arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi | 10 +++
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts     | 67 +++++++++++++++++++++
 3 files changed, 123 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 4c51bae06b57..17d28390d587 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -560,6 +560,52 @@ sdhci2: mmc at fa20000 {
 		status = "disabled";
 	};
 
+	usbss0: usb at f900000 {
+		compatible = "ti,am62-usb";
+		reg = <0x00 0x0f900000 0x00 0x800>;
+		clocks = <&k3_clks 161 3>;
+		clock-names = "ref";
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
+		ranges;
+		status = "disabled";
+
+		usb0: usb at 31000000 {
+			compatible = "snps,dwc3";
+			reg = <0x00 0x31000000 0x00 0x50000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+			<GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+			interrupt-names = "host", "peripheral";
+			maximum-speed = "high-speed";
+			dr_mode = "otg";
+		};
+	};
+
+	usbss1: usb at f910000 {
+		compatible = "ti,am62-usb";
+		reg = <0x00 0x0f910000 0x00 0x800>;
+		clocks = <&k3_clks 162 3>;
+		clock-names = "ref";
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
+		ranges;
+		status = "disabled";
+
+		usb1: usb at 31100000 {
+			compatible = "snps,dwc3";
+			reg = <0x00 0x31100000 0x00 0x50000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+			<GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+			interrupt-names = "host", "peripheral";
+			maximum-speed = "high-speed";
+			dr_mode = "otg";
+		};
+	};
+
 	fss: bus at fc00000 {
 		compatible = "simple-bus";
 		reg = <0x00 0x0fc00000 0x00 0x70000>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
index 19f42b39394e..00dd38b02a52 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
@@ -18,6 +18,16 @@ chipid: chipid at 14 {
 			reg = <0x14 0x4>;
 			bootph-all;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	wkup_uart0: serial at 2b300000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 1773c05f752c..80be56c0a4e0 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -27,6 +27,8 @@ aliases {
 		spi0 = &ospi0;
 		ethernet0 = &cpsw_port1;
 		ethernet1 = &cpsw_port2;
+		usb0 = &usb0;
+		usb1 = &usb1;
 	};
 
 	chosen {
@@ -297,6 +299,12 @@ AM62PX_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (G20) MCASP0_ACLKR.UART1_TXD */
 		bootph-all;
 	};
 
+	main_usb1_pins_default: main-usb1-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
+		>;
+	};
+
 	main_wlirq_pins_default: main-wlirq-default-pins {
 		pinctrl-single,pins = <
 			AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
@@ -340,6 +348,36 @@ AM62PX_IOPAD(0x0124, PIN_INPUT, 7) /* (J25) MMC2_SDCD.GPIO0_71 */
 	};
 };
 
+&main_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+
+	typec_pd0: usb-power-controller at 3f {
+		compatible = "ti,tps6598x";
+		reg = <0x3f>;
+
+		connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			self-powered;
+			data-role = "dual";
+			power-role = "sink";
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port at 0 {
+					reg = <0>;
+					usb_con_hs: endpoint {
+						remote-endpoint = <&usb0_hs_ep>;
+					};
+				};
+			};
+		};
+	};
+};
+
 &main_i2c1 {
 	status = "okay";
 	pinctrl-names = "default";
@@ -460,6 +498,35 @@ cpsw3g_phy1: ethernet-phy at 1 {
 	};
 };
 
+&usbss0 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usbss1 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usb0 {
+	usb-role-switch;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port at 0 {
+		reg = <0>;
+		usb0_hs_ep: endpoint {
+			remote-endpoint = <&usb_con_hs>;
+		};
+	};
+};
+
+&usb1 {
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_usb1_pins_default>;
+};
+
 &mcasp1 {
 	status = "okay";
 	#sound-dai-cells = <0>;
-- 
2.34.1



From andriy.shevchenko at linux.intel.com  Thu Feb  1 03:32:10 2024
From: andriy.shevchenko at linux.intel.com ('andriy.shevchenko@linux.intel.com')
Date: Thu, 1 Feb 2024 13:32:10 +0200
Subject: [PATCH 30 7/7] Add AST2500 and AST2600 JTAG device in DTS
In-Reply-To: <LV8PR11MB8463F88C2364A08DEF3ABAC28B7D2@LV8PR11MB8463.namprd11.prod.outlook.com>
References: <LV8PR11MB8463F88C2364A08DEF3ABAC28B7D2@LV8PR11MB8463.namprd11.prod.outlook.com>
Message-ID: <ZbuBOmtyYdlmnCBa@smile.fi.intel.com>

On Tue, Jan 30, 2024 at 11:32:48PM +0000, Corona, Ernesto wrote:
> Adding aspeed jtag device to device tree
> 
> Signed-off-by: Ernesto Corona <ernesto.corona at intel.com>
> Signed-off-by: Omar Castro <omar.eduardo.castro at linux.intel.com>
> Acked-by: Arnd Bergmann <arnd at arndb.de>

First of all, please use --thread to git-format-patch when preparing the
series.

> Cc: Jiri Pirko <jiri at nvidia.com>
> Cc: Vadim Pasternak <vadimp at mellanox.com>
> Cc: Mauro Carvalho Chehab <mchehab+samsung at kernel.org>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: David S. Miller <davem at davemloft.net>
> Cc: Nicolas Ferre <nicolas.ferre at microchip.com>
> Cc: Rob Herring <robh at kernel.org>
> Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> Cc: Lukas Bulwahn <lukas.bulwahn at gmail.com>
> Cc: Steven Filary <steven.a.filary at intel.com>
> Cc: Amithash Prasad <amithash at fb.com>
> Cc: Patrick Williams <patrickw3 at fb.com>
> Cc: Luke Chen <luke_chen at aspeedtech.com>
> Cc: Billy Tsai <billy_tsai at aspeedtech.com>

Second, please avoid flooding commit message with unneeded details, i.e. move
these Cc:s to...

> ---
...the after this cutter line.

-- 
With Best Regards,
Andy Shevchenko




From rogerq at kernel.org  Thu Feb  1 04:03:31 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  1 Feb 2024 14:03:31 +0200
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2 register space
In-Reply-To: <20240201120332.4811-1-rogerq@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
Message-ID: <20240201120332.4811-5-rogerq@kernel.org>

So far this was not required but due to the newly identified
Errata i2409 [1] we need to poke this register space.

[1] https://www.ti.com/lit/er/sprz487d/sprz487d.pdf

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---

Notes:
    Changelog:
    
    v3 - new patch

 Documentation/devicetree/bindings/usb/ti,am62-usb.yaml | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml b/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
index fec5651f5602..c02d9d467d9c 100644
--- a/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
+++ b/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
@@ -14,7 +14,9 @@ properties:
     const: ti,am62-usb
 
   reg:
-    maxItems: 1
+    items:
+      - description: USB CFG register space
+      - description: USB PHY2 register space
 
   ranges: true
 
@@ -82,7 +84,8 @@ examples:
 
       usbss1: usb at f910000 {
         compatible = "ti,am62-usb";
-        reg = <0x00 0x0f910000 0x00 0x800>;
+        reg = <0x00 0x0f910000 0x00 0x800>,
+              <0x00 0x0f918000 0x00 0x400>;
         clocks = <&k3_clks 162 3>;
         clock-names = "ref";
         ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
-- 
2.34.1



From rogerq at kernel.org  Thu Feb  1 04:03:32 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  1 Feb 2024 14:03:32 +0200
Subject: [PATCH v3 5/5] arm64: dts: ti: k3-am62*: Add PHY2 region to USB wrapper node
In-Reply-To: <20240201120332.4811-1-rogerq@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
Message-ID: <20240201120332.4811-6-rogerq@kernel.org>

Add PHY2 register space to USB wrapper node. This is required
to deal with Errata i2409.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---

Notes:
    Changelog:
    
    v3 - new patch

 arch/arm64/boot/dts/ti/k3-am62-main.dtsi  | 6 ++++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 6 ++++--
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 6 ++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 9432ed344d52..da50fbfcce56 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -622,7 +622,8 @@ sdhci2: mmc at fa20000 {
 
 	usbss0: dwc3-usb at f900000 {
 		compatible = "ti,am62-usb";
-		reg = <0x00 0x0f900000 0x00 0x800>;
+		reg = <0x00 0x0f900000 0x00 0x800>,
+		      <0x00 0x0f908000 0x00 0x400>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
 		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
@@ -645,7 +646,8 @@ usb0: usb at 31000000 {
 
 	usbss1: dwc3-usb at f910000 {
 		compatible = "ti,am62-usb";
-		reg = <0x00 0x0f910000 0x00 0x800>;
+		reg = <0x00 0x0f910000 0x00 0x800>,
+		      <0x00 0x0f918000 0x00 0x400>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
 		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 8311c7c44cd3..523bab94eace 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -563,7 +563,8 @@ sdhci1: mmc at fa00000 {
 
 	usbss0: dwc3-usb at f900000 {
 		compatible = "ti,am62-usb";
-		reg = <0x00 0x0f900000 0x00 0x800>;
+		reg = <0x00 0x0f900000 0x00 0x800>,
+		      <0x00 0x0f908000 0x00 0x400>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
 		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
@@ -586,7 +587,8 @@ usb0: usb at 31000000 {
 
 	usbss1: dwc3-usb at f910000 {
 		compatible = "ti,am62-usb";
-		reg = <0x00 0x0f910000 0x00 0x800>;
+		reg = <0x00 0x0f910000 0x00 0x800>,
+		      <0x00 0x0f918000 0x00 0x400>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
 		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 17d28390d587..ae0ab67460b4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -562,7 +562,8 @@ sdhci2: mmc at fa20000 {
 
 	usbss0: usb at f900000 {
 		compatible = "ti,am62-usb";
-		reg = <0x00 0x0f900000 0x00 0x800>;
+		reg = <0x00 0x0f900000 0x00 0x800>,
+		      <0x00 0x0f908000 0x00 0x400>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
 		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
@@ -585,7 +586,8 @@ usb0: usb at 31000000 {
 
 	usbss1: usb at f910000 {
 		compatible = "ti,am62-usb";
-		reg = <0x00 0x0f910000 0x00 0x800>;
+		reg = <0x00 0x0f910000 0x00 0x800>,
+		      <0x00 0x0f918000 0x00 0x400>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
 		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
-- 
2.34.1



From jirislaby at kernel.org  Thu Feb  1 04:05:42 2024
From: jirislaby at kernel.org (Jiri Slaby)
Date: Thu, 1 Feb 2024 13:05:42 +0100
Subject: [PATCH v2 2/2] serial: mxs-auart: fix tx
In-Reply-To: <20240201105557.28043-2-jirislaby@kernel.org>
References: <20240201105557.28043-1-jirislaby@kernel.org>
 <20240201105557.28043-2-jirislaby@kernel.org>
Message-ID: <3935b841-77b7-4265-a727-98a358cd56be@kernel.org>

On 01. 02. 24, 11:55, Jiri Slaby (SUSE) wrote:
> Emil reports:
>    After updating Linux on an i.MX28 board, serial communication over
>    AUART broke. When I TX from the board and measure on the TX pin, it
>    seems like the HW fifo is not emptied before the transmission is
>    stopped.
> 
> MXS performs weird things with stop_tx(). The driver makes it
> conditional on uart_tx_stopped().
> 
> So the driver needs special handling. Pass the brand new UART_TX_NOSTOP
> to uart_port_tx_flags() and handle the stop on its own.
> 
> Signed-off-by: Jiri Slaby (SUSE) <jirislaby at kernel.org>
> Reported-by: Emil Kronborg <emil.kronborg at protonmail.com>
> Fixes: 2d141e683e9a ("tty: serial: use uart_port_tx() helper")
> Closes: https://lore.kernel.org/all/miwgbnvy3hjpnricubg76ytpn7xoceehwahupy25bubbduu23s at om2lptpa26xw/

Am I unable to send a proper patch anymore?

I forgot to add mxs+arm maintainers:
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

I can resend with those fixed, if you prefer...

> ---
>   drivers/tty/serial/mxs-auart.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
> index 3ec725555bcc..4749331fe618 100644
> --- a/drivers/tty/serial/mxs-auart.c
> +++ b/drivers/tty/serial/mxs-auart.c
> @@ -605,13 +605,16 @@ static void mxs_auart_tx_chars(struct mxs_auart_port *s)
>   		return;
>   	}
>   
> -	pending = uart_port_tx(&s->port, ch,
> +	pending = uart_port_tx_flags(&s->port, ch, UART_TX_NOSTOP,
>   		!(mxs_read(s, REG_STAT) & AUART_STAT_TXFF),
>   		mxs_write(ch, s, REG_DATA));
>   	if (pending)
>   		mxs_set(AUART_INTR_TXIEN, s, REG_INTR);
>   	else
>   		mxs_clr(AUART_INTR_TXIEN, s, REG_INTR);
> +
> +	if (uart_tx_stopped(&s->port))
> +               mxs_auart_stop_tx(&s->port);
>   }
>   
>   static void mxs_auart_rx_char(struct mxs_auart_port *s)

-- 
js
suse labs



From andyshrk at 163.com  Thu Feb  1 04:11:04 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu,  1 Feb 2024 20:11:04 +0800
Subject: [PATCH v2 2/4] arm64: dts: rockchip: aliase sdmmc as mmc1 for Cool Pi CM5 EVB
In-Reply-To: <20240201121106.1471301-1-andyshrk@163.com>
References: <20240201121106.1471301-1-andyshrk@163.com>
Message-ID: <20240201121106.1471301-2-andyshrk@163.com>

Follow others rk3588 based boards, and u-boot only use mmc0/1
as mmc boot targets, so aliase sdmmc as mmc1.

Fixes: 791c154c3982 ("arm64: dts: rockchip: Add support for rk3588 based board Cool Pi CM5 EVB")
Signed-off-by: Andy Yan <andyshrk at 163.com>
Reviewed-by: Dragan Simic <dsimic at manjaro.org>
---

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
index 0b02f4d6e003..cce1c8e83587 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
@@ -16,8 +16,8 @@ / {
 
 	aliases {
 		mmc0 = &sdhci;
-		mmc1 = &sdio;
-		mmc2 = &sdmmc;
+		mmc1 = &sdmmc;
+		mmc2 = &sdio;
 		serial2 = &uart2;
 	};
 
-- 
2.34.1



From andyshrk at 163.com  Thu Feb  1 04:11:05 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu,  1 Feb 2024 20:11:05 +0800
Subject: [PATCH v2 3/4] arm64: dts: rockchip: rename vcc5v0_usb30_host regulator for Cool Pi CM5 EVB
In-Reply-To: <20240201121106.1471301-1-andyshrk@163.com>
References: <20240201121106.1471301-1-andyshrk@163.com>
Message-ID: <20240201121106.1471301-3-andyshrk@163.com>

According to the schematic, USB20 HOST0 and HOST1 each have their own
independent power supply, but these two regulators controlled by a
same GPIO, so give it a more appropriate name.

Fixes: 791c154c3982 ("arm64: dts: rockchip: Add support for rk3588 based board Cool Pi CM5 EVB")
Signed-off-by: Andy Yan <andyshrk at 163.com>
---

Changes in v2:
- Add two lable for this regulator

 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
index 1b5681fe0471..9c0f408ef339 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
@@ -84,7 +84,7 @@ vcc3v3_lcd: vcc3v3-lcd-regulator {
 		vin-supply = <&vcc3v3_sys>;
 	};
 
-	vcc5v0_usb30_host: vcc5v0-usb30-host-regulator {
+	vcc5v0_usb_host1: vcc5v0_usb_host2: vcc5v0-usb-host-regulator {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc5v0_host";
 		regulator-boot-on;
@@ -200,12 +200,12 @@ &u2phy3 {
 };
 
 &u2phy2_host {
-	phy-supply = <&vcc5v0_usb30_host>;
+	phy-supply = <&vcc5v0_usb_host1>;
 	status = "okay";
 };
 
 &u2phy3_host {
-	phy-supply = <&vcc5v0_usb30_host>;
+	phy-supply = <&vcc5v0_usb_host2>;
 	status = "okay";
 };
 
-- 
2.34.1



From andyshrk at 163.com  Thu Feb  1 04:11:06 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu,  1 Feb 2024 20:11:06 +0800
Subject: [PATCH v2 4/4] arm64: dts: rockchip: Fix the num-lanes of pcie3x4 on Cool Pi CM5 EVB
In-Reply-To: <20240201121106.1471301-1-andyshrk@163.com>
References: <20240201121106.1471301-1-andyshrk@163.com>
Message-ID: <20240201121106.1471301-4-andyshrk@163.com>

The 4 lane pcie30 phy is shared by pcie3x4 and pcie3x2, so
the num-lanes of pcie3x4 should be 2.

Fixes: 791c154c3982 ("arm64: dts: rockchip: Add support for rk3588 based board Cool Pi CM5 EVB")
Signed-off-by: Andy Yan <andyshrk at 163.com>
---

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
index 9c0f408ef339..d6366e7b57bb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
@@ -126,6 +126,7 @@ &pcie30phy {
 	status = "okay";
 };
 
+/* Standard pcie */
 &pcie3x2 {
 	reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
 	vpcie3v3-supply = <&vcc3v3_sys>;
@@ -134,6 +135,7 @@ &pcie3x2 {
 
 /* M.2 M-Key ssd */
 &pcie3x4 {
+	num-lanes = <2>;
 	reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
 	vpcie3v3-supply = <&vcc3v3_sys>;
 	status = "okay";
-- 
2.34.1



From andyshrk at 163.com  Thu Feb  1 04:11:03 2024
From: andyshrk at 163.com (Andy Yan)
Date: Thu,  1 Feb 2024 20:11:03 +0800
Subject: [PATCH v2 1/4] arm64: dts: rockchip: aliase sdmmc as mmc1 for Cool Pi 4B
Message-ID: <20240201121106.1471301-1-andyshrk@163.com>

Follow others rk3588 based boards, and u-boot only use mmc0/1
as mmc boot targets, so aliase sdmmc as mmc1.

Fixes: 3f5d336d64d6 ("arm64: dts: rockchip: Add support for rk3588s based board Cool Pi 4B")
Signed-off-by: Andy Yan <andyshrk at 163.com>
Reviewed-by: Dragan Simic <dsimic at manjaro.org>

---

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
index 3fae40b9ae1b..3b9d21a6f8bf 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
@@ -20,8 +20,8 @@ / {
 
 	aliases {
 		mmc0 = &sdhci;
-		mmc1 = &sdio;
-		mmc2 = &sdmmc;
+		mmc1 = &sdmmc;
+		mmc2 = &sdio;
 	};
 
 	analog-sound {
-- 
2.34.1



From smostafa at google.com  Thu Feb  1 04:15:53 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 1 Feb 2024 12:15:53 +0000
Subject: [PATCH v4 06/16] iommu/arm-smmu-v3: Hold arm_smmu_asid_lock
 during all of attach_dev
In-Reply-To: <6-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <6-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <ZbuLeWDvhhufT7Pa@google.com>

Hi Jason,

On Thu, Jan 25, 2024 at 07:57:16PM -0400, Jason Gunthorpe wrote:
> The BTM support wants to be able to change the ASID of any smmu_domain.
> When it goes to do this it holds the arm_smmu_asid_lock and iterates over
> the target domain's devices list.
> 
> During attach of a S1 domain we must ensure that the devices list and
> CD are in sync, otherwise we could miss CD updates or a parallel CD update
> could push an out of date CD.
> 
> This is pretty complicated, and almost works today because
> arm_smmu_detach_dev() removes the master from the linked list before
> working on the CD entries, preventing parallel update of the CD.
> 
> However, it does have an issue where the CD can remain programed while the
> domain appears to be unattached. arm_smmu_share_asid() will then not clear
> any CD entriess and install its own CD entry with the same ASID
> concurrently. This creates a small race window where the IOMMU can see two
> ASIDs pointing to different translations.

I don?t see the race condition.

The current flow is as follows,
For SVA, if the asid was used by domain_x, it will do:

lock(arm_smmu_asid_lock)
Alloc new asid and set cd->asid.
lock(domain_x->devices_lock)
Write new CD with the new asid
unlock(domain_x->devices_lock)
unlock(arm_smmu_asid_lock)

For attach_dev (domain_y), if the device was attached to domain_z
//Detach old domain
lock(domain_z->devices_lock)
Remove master from old domain
unlock(domain_z->devices_lock)
Clear CD
//Attach new domain
lock(arm_smmu_asid_lock)
Allocate ASID
unlock(arm_smmu_asid_lock)

lock(domain_y->devices_lock)
Insert new master.
unlock(domain_y->devices_lock)

lock(arm_smmu_asid_lock)
Write CD
unlock(arm_smmu_asid_lock)


In case
1) domain_x == domain_z(old domain)
Write to the CD is protected by domain_x->devices_lock, so either:
    a) The device will be removed, so SVA code will not touch it, and the
    detach will clear the CD.
    b) The device CD will be updated from the SVA with the new code, but then
    it will be removed from the domain and cleared.

I don?t see any case where we end with a programmed CD.

2) domain_x == domain_y(new domain)

Similarly the device would either see the new CD(new asid) or the old CD
then the new CD.

Can you please clarify the race condition? as it seems I am missing something.

> Solve this by wrapping most of the attach flow in the
> arm_smmu_asid_lock. This locks more than strictly needed to prepare for
> the next patch which will reorganize the order of the linked list, STE and
> CD changes.
> 
> Move arm_smmu_detach_dev() till after we have initialized the domain so
> the lock can be held for less time.
> 
> Reviewed-by: Michael Shavit <mshavit at google.com>
> Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Moritz Fischer <moritzf at google.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 22 ++++++++++++---------
>  1 file changed, 13 insertions(+), 9 deletions(-)
> 
> 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 9a95d0f1494223..539ef380f457fa 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2612,8 +2612,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  		return -EBUSY;
>  	}
>  
> -	arm_smmu_detach_dev(master);
> -
>  	mutex_lock(&smmu_domain->init_mutex);
>  
>  	if (!smmu_domain->smmu) {
> @@ -2628,6 +2626,16 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  	if (ret)
>  		return ret;
>  
> +	/*
> +	 * Prevent arm_smmu_share_asid() from trying to change the ASID
> +	 * of either the old or new domain while we are working on it.
> +	 * This allows the STE and the smmu_domain->devices list to
> +	 * be inconsistent during this routine.
> +	 */
> +	mutex_lock(&arm_smmu_asid_lock);
> +
> +	arm_smmu_detach_dev(master);
> +
>  	master->domain = smmu_domain;
>  
>  	/*
> @@ -2653,13 +2661,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  			}
>  		}
>  
> -		/*
> -		 * Prevent SVA from concurrently modifying the CD or writing to
> -		 * the CD entry
> -		 */
> -		mutex_lock(&arm_smmu_asid_lock);
>  		ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, &smmu_domain->cd);
> -		mutex_unlock(&arm_smmu_asid_lock);
>  		if (ret) {
>  			master->domain = NULL;
>  			goto out_list_del;
> @@ -2669,13 +2671,15 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  	arm_smmu_install_ste_for_dev(master);
>  
>  	arm_smmu_enable_ats(master);
> -	return 0;
> +	goto out_unlock;
>  
>  out_list_del:
>  	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
>  	list_del(&master->domain_head);
>  	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
>  
> +out_unlock:
> +	mutex_unlock(&arm_smmu_asid_lock);
>  	return ret;
>  }
>  
> -- 
> 2.43.0
> 

Thanks,
Mostafa


From smostafa at google.com  Thu Feb  1 04:18:10 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Thu, 1 Feb 2024 12:18:10 +0000
Subject: [PATCH v4 07/16] iommu/arm-smmu-v3: Compute the STE only once
 for each master
In-Reply-To: <7-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <7-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <ZbuMAq-phWP5KZ3D@google.com>

Hi Jason,

On Thu, Jan 25, 2024 at 07:57:17PM -0400, Jason Gunthorpe wrote:
> Currently arm_smmu_install_ste_for_dev() iterates over every SID and
> computes from scratch an identical STE. Every SID should have the same STE
> contents. Turn this inside out so that the STE is supplied by the caller
> and arm_smmu_install_ste_for_dev() simply installs it to every SID.
> 
> This is possible now that the STE generation does not inform what sequence
> should be used to program it.
> 
> This allows splitting the STE calculation up according to the call site,
> which following patches will make use of, and removes the confusing NULL
> domain special case that only supported arm_smmu_detach_dev().
> 
> Reviewed-by: Michael Shavit <mshavit at google.com>
> Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Moritz Fischer <moritzf at google.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 57 ++++++++-------------
>  1 file changed, 22 insertions(+), 35 deletions(-)
> 
> 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 539ef380f457fa..cf3e348cb9abe1 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1588,35 +1588,6 @@ static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
>  				      STRTAB_STE_3_S2TTB_MASK);
>  }
>  
> -static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
> -				      struct arm_smmu_ste *dst)
> -{
> -	struct arm_smmu_domain *smmu_domain = master->domain;
> -	struct arm_smmu_ste target = {};
> -
> -	if (!smmu_domain) {
> -		if (disable_bypass)
> -			arm_smmu_make_abort_ste(&target);
> -		else
> -			arm_smmu_make_bypass_ste(&target);
> -		arm_smmu_write_ste(master, sid, dst, &target);
> -		return;
> -	}
> -
> -	switch (smmu_domain->stage) {
> -	case ARM_SMMU_DOMAIN_S1:
> -		arm_smmu_make_cdtable_ste(&target, master, &master->cd_table);
> -		break;
> -	case ARM_SMMU_DOMAIN_S2:
> -		arm_smmu_make_s2_domain_ste(&target, master, smmu_domain);
> -		break;
> -	case ARM_SMMU_DOMAIN_BYPASS:
> -		arm_smmu_make_bypass_ste(&target);
> -		break;
> -	}
> -	arm_smmu_write_ste(master, sid, dst, &target);
> -}
> -
>  static void arm_smmu_init_bypass_stes(struct arm_smmu_ste *strtab,
>  				      unsigned int nent)
>  {
> @@ -2439,7 +2410,8 @@ arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
>  	}
>  }
>  
> -static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
> +static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
> +					 const struct arm_smmu_ste *target)
>  {
>  	int i, j;
>  	struct arm_smmu_device *smmu = master->smmu;
> @@ -2456,7 +2428,7 @@ static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
>  		if (j < i)
>  			continue;
>  
> -		arm_smmu_write_strtab_ent(master, sid, step);
> +		arm_smmu_write_ste(master, sid, step, target);
>  	}
>  }
>  
> @@ -2563,6 +2535,7 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
>  static void arm_smmu_detach_dev(struct arm_smmu_master *master)
>  {
>  	unsigned long flags;
> +	struct arm_smmu_ste target;
>  	struct arm_smmu_domain *smmu_domain = master->domain;
>  
>  	if (!smmu_domain)
> @@ -2576,7 +2549,11 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
>  
>  	master->domain = NULL;
>  	master->ats_enabled = false;
> -	arm_smmu_install_ste_for_dev(master);
> +	if (disable_bypass)
> +		arm_smmu_make_abort_ste(&target);
> +	else
> +		arm_smmu_make_bypass_ste(&target);
> +	arm_smmu_install_ste_for_dev(master, &target);
>  	/*
>  	 * Clearing the CD entry isn't strictly required to detach the domain
>  	 * since the table is uninstalled anyway, but it helps avoid confusion
> @@ -2591,6 +2568,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  {
>  	int ret = 0;
>  	unsigned long flags;
> +	struct arm_smmu_ste target;
>  	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>  	struct arm_smmu_device *smmu;
>  	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> @@ -2652,7 +2630,8 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  	list_add(&master->domain_head, &smmu_domain->devices);
>  	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
>  
> -	if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
> +	switch (smmu_domain->stage) {
> +	case ARM_SMMU_DOMAIN_S1:
>  		if (!master->cd_table.cdtab) {
>  			ret = arm_smmu_alloc_cd_tables(master);
>  			if (ret) {
> @@ -2666,9 +2645,17 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  			master->domain = NULL;
>  			goto out_list_del;
>  		}
> -	}
>  
> -	arm_smmu_install_ste_for_dev(master);
> +		arm_smmu_make_cdtable_ste(&target, master, &master->cd_table);
> +		break;
> +	case ARM_SMMU_DOMAIN_S2:
> +		arm_smmu_make_s2_domain_ste(&target, master, smmu_domain);
> +		break;
> +	case ARM_SMMU_DOMAIN_BYPASS:
> +		arm_smmu_make_bypass_ste(&target);
> +		break;
> +	}
> +	arm_smmu_install_ste_for_dev(master, &target);
>  
>  	arm_smmu_enable_ats(master);
>  	goto out_unlock;
> -- 
> 2.43.0
>

Reviewed-by: Mostafa Saleh <smostafa at google.com>

Thanks,
Mostafa


From dan.carpenter at linaro.org  Thu Feb  1 04:20:04 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Thu, 1 Feb 2024 15:20:04 +0300
Subject: [bug report] soc: xilinx: Fix for call trace due to the usage of
 smp_processor_id()
Message-ID: <52a41911-7c7d-4164-aeb7-aba5eddfeea9@moroto.mountain>

Hello HariBabu Gattem,

The patch daed80ed0758: "soc: xilinx: Fix for call trace due to the
usage of smp_processor_id()" from Oct 26, 2023 (linux-next), leads to
the following Smatch static checker warning:

	kernel/irq/manage.c:2614 __request_percpu_irq()
	warn: sleeping in atomic context

drivers/soc/xilinx/xlnx_event_manager.c
   610          cpu = get_cpu();
                ^^^^^^^^^^^^^^^
The patch adds get_cpu() which disables preemption.

   611          per_cpu(cpu_number1, cpu) = cpu;
   612          ret = request_percpu_irq(virq_sgi, xlnx_event_handler, "xlnx_event_mgmt",
                      ^^^^^^^^^^^^^^^^^^
request_percpu_irq() does a sleeping allocation so it's a sleeping in
atomic bug.

   613                                   &cpu_number1);
   614          put_cpu();

regards,
dan carpenter


From viorel.suman at oss.nxp.com  Thu Feb  1 04:22:42 2024
From: viorel.suman at oss.nxp.com (Viorel Suman (OSS))
Date: Thu,  1 Feb 2024 14:22:42 +0200
Subject: [PATCH] pwm: imx-tpm: reset module on probe
Message-ID: <20240201122242.1597601-1-viorel.suman@oss.nxp.com>

From: Viorel Suman <viorel.suman at nxp.com>

Reset Timer PWM module on probe so that the module
takes the default state after probe is finished.

Signed-off-by: Viorel Suman <viorel.suman at nxp.com>
Signed-off-by: Florin Leotescu <florin.leotescu at nxp.com>
---
 drivers/pwm/pwm-imx-tpm.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c
index 9fc290e647e1..27e6a5342693 100644
--- a/drivers/pwm/pwm-imx-tpm.c
+++ b/drivers/pwm/pwm-imx-tpm.c
@@ -33,6 +33,7 @@
 #define PWM_IMX_TPM_CnV(n)	(0x24 + (n) * 0x8)
 
 #define PWM_IMX_TPM_PARAM_CHAN			GENMASK(7, 0)
+#define PWM_IMX_TPM_GLOBAL_RST			BIT(1)
 
 #define PWM_IMX_TPM_SC_PS			GENMASK(2, 0)
 #define PWM_IMX_TPM_SC_CMOD			GENMASK(4, 3)
@@ -362,6 +363,10 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
 	val = readl(tpm->base + PWM_IMX_TPM_PARAM);
 	tpm->chip.npwm = FIELD_GET(PWM_IMX_TPM_PARAM_CHAN, val);
 
+	/* Resets all internal logic and registers */
+	writel(PWM_IMX_TPM_GLOBAL_RST, tpm->base + PWM_IMX_TPM_GLOBAL);
+	writel(0, tpm->base + PWM_IMX_TPM_GLOBAL);
+
 	mutex_init(&tpm->lock);
 
 	ret = devm_pwmchip_add(&pdev->dev, &tpm->chip);
-- 
2.34.1



From lkp at intel.com  Thu Feb  1 04:23:17 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 01 Feb 2024 20:23:17 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS
 1b5af823d703ee183ffdde188aaf584ab93eea19
Message-ID: <202402012014.TA6sCE8k-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: 1b5af823d703ee183ffdde188aaf584ab93eea19  soc/tegra: fix build failure on Tegra241

elapsed time: 888m

configs tested: 138
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                            hsdk_defconfig   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   gcc  
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
i386                             allmodconfig   clang
i386                              allnoconfig   clang
i386                             allyesconfig   clang
i386         buildonly-randconfig-001-20240201   gcc  
i386         buildonly-randconfig-002-20240201   gcc  
i386         buildonly-randconfig-003-20240201   gcc  
i386         buildonly-randconfig-004-20240201   gcc  
i386         buildonly-randconfig-005-20240201   gcc  
i386         buildonly-randconfig-006-20240201   gcc  
i386                                defconfig   gcc  
i386                  randconfig-001-20240201   gcc  
i386                  randconfig-002-20240201   gcc  
i386                  randconfig-003-20240201   gcc  
i386                  randconfig-004-20240201   gcc  
i386                  randconfig-005-20240201   gcc  
i386                  randconfig-006-20240201   gcc  
i386                  randconfig-011-20240201   clang
i386                  randconfig-012-20240201   clang
i386                  randconfig-013-20240201   clang
i386                  randconfig-014-20240201   clang
i386                  randconfig-015-20240201   clang
i386                  randconfig-016-20240201   clang
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                        allyesconfig   gcc  
loongarch                           defconfig   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
microblaze                      mmu_defconfig   gcc  
mips                             allmodconfig   gcc  
mips                              allnoconfig   clang
mips                             allyesconfig   gcc  
nios2                         10m50_defconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
openrisc                         allmodconfig   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   clang
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc                      arches_defconfig   gcc  
powerpc                   currituck_defconfig   gcc  
powerpc                    ge_imp3a_defconfig   gcc  
powerpc                     ksi8560_defconfig   gcc  
powerpc                      ppc40x_defconfig   gcc  
powerpc                  storcenter_defconfig   gcc  
powerpc                        warp_defconfig   gcc  
riscv                            allmodconfig   gcc  
riscv                             allnoconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   gcc  
riscv                               defconfig   gcc  
s390                             allmodconfig   clang
s390                             allmodconfig   gcc  
s390                              allnoconfig   gcc  
s390                             allyesconfig   gcc  
s390                                defconfig   gcc  
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                          polaris_defconfig   gcc  
sh                          r7785rp_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                            allyesconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                                allnoconfig   gcc  
um                               allyesconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   gcc  
um                             i386_defconfig   gcc  
um                           x86_64_defconfig   gcc  
x86_64                            allnoconfig   clang
x86_64                            allnoconfig   gcc  
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240201   gcc  
x86_64       buildonly-randconfig-002-20240201   gcc  
x86_64       buildonly-randconfig-003-20240201   gcc  
x86_64       buildonly-randconfig-004-20240201   gcc  
x86_64       buildonly-randconfig-005-20240201   gcc  
x86_64       buildonly-randconfig-006-20240201   gcc  
x86_64                              defconfig   clang
x86_64                              defconfig   gcc  
x86_64                                  kexec   clang
x86_64                                  kexec   gcc  
x86_64                randconfig-011-20240201   gcc  
x86_64                randconfig-012-20240201   gcc  
x86_64                randconfig-013-20240201   gcc  
x86_64                randconfig-014-20240201   gcc  
x86_64                randconfig-015-20240201   gcc  
x86_64                randconfig-016-20240201   gcc  
x86_64                randconfig-071-20240201   gcc  
x86_64                randconfig-072-20240201   gcc  
x86_64                randconfig-073-20240201   gcc  
x86_64                randconfig-074-20240201   gcc  
x86_64                randconfig-075-20240201   gcc  
x86_64                randconfig-076-20240201   gcc  
x86_64                          rhel-8.3-rust   clang
x86_64                               rhel-8.3   clang
x86_64                               rhel-8.3   gcc  
xtensa                            allnoconfig   gcc  
xtensa                           allyesconfig   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From lkp at intel.com  Thu Feb  1 04:22:51 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 01 Feb 2024 20:22:51 +0800
Subject: [soc:soc/defconfig] BUILD SUCCESS
 849ffbf054ab4429df636a18af557b0195f3c2d0
Message-ID: <202402012048.8vXihVmD-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/defconfig
branch HEAD: 849ffbf054ab4429df636a18af557b0195f3c2d0  ARM: multi_v7_defconfig: Add more TI Keystone support

elapsed time: 888m

configs tested: 111
configs skipped: 124

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                            hsdk_defconfig   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   gcc  
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
hexagon                          allmodconfig   clang
hexagon                          allyesconfig   clang
i386                             allmodconfig   clang
i386                              allnoconfig   clang
i386                             allyesconfig   clang
i386                  randconfig-011-20240201   clang
i386                  randconfig-012-20240201   clang
i386                  randconfig-013-20240201   clang
i386                  randconfig-014-20240201   clang
i386                  randconfig-015-20240201   clang
i386                  randconfig-016-20240201   clang
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                        allyesconfig   gcc  
loongarch                           defconfig   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
microblaze                      mmu_defconfig   gcc  
mips                             allmodconfig   gcc  
mips                             allyesconfig   gcc  
nios2                         10m50_defconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
openrisc                         allmodconfig   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc64                            defconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                      arches_defconfig   gcc  
powerpc                   currituck_defconfig   gcc  
powerpc                    ge_imp3a_defconfig   gcc  
powerpc                     ksi8560_defconfig   gcc  
powerpc                      ppc40x_defconfig   gcc  
powerpc                  storcenter_defconfig   gcc  
powerpc                        warp_defconfig   gcc  
riscv                            allmodconfig   gcc  
riscv                            allyesconfig   gcc  
riscv                               defconfig   gcc  
s390                             allmodconfig   clang
s390                              allnoconfig   gcc  
s390                                defconfig   gcc  
sh                                allnoconfig   gcc  
sh                                  defconfig   gcc  
sh                          polaris_defconfig   gcc  
sh                          r7785rp_defconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                            allyesconfig   gcc  
sparc                               defconfig   gcc  
sparc64                             defconfig   gcc  
um                               allmodconfig   clang
um                               allyesconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   gcc  
um                             i386_defconfig   gcc  
um                           x86_64_defconfig   gcc  
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240201   gcc  
x86_64       buildonly-randconfig-002-20240201   gcc  
x86_64       buildonly-randconfig-003-20240201   gcc  
x86_64       buildonly-randconfig-004-20240201   gcc  
x86_64       buildonly-randconfig-005-20240201   gcc  
x86_64       buildonly-randconfig-006-20240201   gcc  
x86_64                              defconfig   clang
x86_64                                  kexec   clang
x86_64                                  kexec   gcc  
x86_64                randconfig-011-20240201   gcc  
x86_64                randconfig-012-20240201   gcc  
x86_64                randconfig-013-20240201   gcc  
x86_64                randconfig-014-20240201   gcc  
x86_64                randconfig-015-20240201   gcc  
x86_64                randconfig-016-20240201   gcc  
x86_64                randconfig-071-20240201   gcc  
x86_64                randconfig-072-20240201   gcc  
x86_64                randconfig-073-20240201   gcc  
x86_64                randconfig-074-20240201   gcc  
x86_64                randconfig-075-20240201   gcc  
x86_64                randconfig-076-20240201   gcc  
x86_64                          rhel-8.3-rust   clang
x86_64                               rhel-8.3   clang
x86_64                               rhel-8.3   gcc  
xtensa                            allnoconfig   gcc  
xtensa                           allyesconfig   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From dsimic at manjaro.org  Thu Feb  1 04:35:53 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu, 01 Feb 2024 13:35:53 +0100
Subject: [PATCH v2 3/4] arm64: dts: rockchip: rename vcc5v0_usb30_host
 regulator for Cool Pi CM5 EVB
In-Reply-To: <20240201121106.1471301-3-andyshrk@163.com>
References: <20240201121106.1471301-1-andyshrk@163.com>
 <20240201121106.1471301-3-andyshrk@163.com>
Message-ID: <2da07d89de139b6325c7353273b16805@manjaro.org>

On 2024-02-01 13:11, Andy Yan wrote:
> According to the schematic, USB20 HOST0 and HOST1 each have their own
> independent power supply, but these two regulators controlled by a
> same GPIO, so give it a more appropriate name.
> 
> Fixes: 791c154c3982 ("arm64: dts: rockchip: Add support for rk3588
> based board Cool Pi CM5 EVB")
> Signed-off-by: Andy Yan <andyshrk at 163.com>

Looking good to me.

Reviewed-by: Dragan Simic <dsimic at manjaro.org>

> ---
> 
> Changes in v2:
> - Add two lable for this regulator
> 
>  arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
> b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
> index 1b5681fe0471..9c0f408ef339 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
> @@ -84,7 +84,7 @@ vcc3v3_lcd: vcc3v3-lcd-regulator {
>  		vin-supply = <&vcc3v3_sys>;
>  	};
> 
> -	vcc5v0_usb30_host: vcc5v0-usb30-host-regulator {
> +	vcc5v0_usb_host1: vcc5v0_usb_host2: vcc5v0-usb-host-regulator {
>  		compatible = "regulator-fixed";
>  		regulator-name = "vcc5v0_host";
>  		regulator-boot-on;
> @@ -200,12 +200,12 @@ &u2phy3 {
>  };
> 
>  &u2phy2_host {
> -	phy-supply = <&vcc5v0_usb30_host>;
> +	phy-supply = <&vcc5v0_usb_host1>;
>  	status = "okay";
>  };
> 
>  &u2phy3_host {
> -	phy-supply = <&vcc5v0_usb30_host>;
> +	phy-supply = <&vcc5v0_usb_host2>;
>  	status = "okay";
>  };


From stefan.wiehler at nokia.com  Thu Feb  1 04:36:06 2024
From: stefan.wiehler at nokia.com (Stefan Wiehler)
Date: Thu,  1 Feb 2024 13:36:06 +0100
Subject: [PATCH RESEND] arm: topology: Fix missing clock-frequency property warning
Message-ID: <20240201123605.3037829-2-stefan.wiehler@nokia.com>

If the clock-frequency property is not set in the cpu node but in the
parent /cpus node, the following warning is emitted:

  /cpus/cpu at X missing clock-frequency property

The devicetree specification in section 3.8 however specifies that
"properties that have identical values across cpu nodes may be placed in
the /cpus node instead.  A client program must first examine a specific cpu
node, but if an expected property is not found then it should look at the
parent /cpus node."

Signed-off-by: Stefan Wiehler <stefan.wiehler at nokia.com>
---
 arch/arm/kernel/topology.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index ef0058de432b..32fc1c8d9d11 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -85,15 +85,24 @@ static bool cap_from_dt = true;
 static void __init parse_dt_topology(void)
 {
 	const struct cpu_efficiency *cpu_eff;
-	struct device_node *cn = NULL;
+	struct device_node *pcn = NULL, *cn = NULL;
 	unsigned long min_capacity = ULONG_MAX;
 	unsigned long max_capacity = 0;
 	unsigned long capacity = 0;
 	int cpu = 0;
+	const __be32 *common_rate;
+	int common_rate_len;
 
 	__cpu_capacity = kcalloc(nr_cpu_ids, sizeof(*__cpu_capacity),
 				 GFP_NOWAIT);
 
+	pcn = of_find_node_by_path("/cpus");
+	if (!pcn) {
+		pr_err("missing CPU root device node\n");
+		return;
+	}
+	common_rate = of_get_property(pcn, "clock-frequency", &common_rate_len);
+
 	for_each_possible_cpu(cpu) {
 		const __be32 *rate;
 		int len;
@@ -121,8 +130,12 @@ static void __init parse_dt_topology(void)
 
 		rate = of_get_property(cn, "clock-frequency", &len);
 		if (!rate || len != 4) {
-			pr_err("%pOF missing clock-frequency property\n", cn);
-			continue;
+			if (common_rate && common_rate_len == 4) {
+				rate = common_rate;
+			} else {
+				pr_err("%pOF missing clock-frequency property\n", cn);
+				continue;
+			}
 		}
 
 		capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
@@ -154,6 +167,8 @@ static void __init parse_dt_topology(void)
 
 	if (cap_from_dt)
 		topology_normalize_cpu_scale();
+
+	of_node_put(pcn);
 }
 
 /*
-- 
2.42.0



From j-luthra at ti.com  Thu Feb  1 04:43:53 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 1 Feb 2024 18:13:53 +0530
Subject: [PATCH] arm64: dts: ti: k3-am62p5-sk: Enable CPSW MDIO node
Message-ID: <20240201-am62p_cpsw_mdio-v1-1-05f758300f6e@ti.com>

From: Ravi Gunasekaran <r-gunasekaran at ti.com>

Enable the CPSW MDIO node, and link the pinctrl information to enable
ethernet on SK-AM62P.

Ethernet was unintentally broken on this board, even though these nodes
were already present, as enabling them was missed in the original
patch.

Fixes: c00504ea42c0 ("arm64: dts: ti: k3-am62p5-sk: Updates for SK EVM")
Signed-off-by: Ravi Gunasekaran <r-gunasekaran at ti.com>
Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
Boot logs: https://0x0.st/HDOO.txt
---
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 1773c05f752c..60868862e3b4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -445,6 +445,10 @@ &cpsw_port2 {
 };
 
 &cpsw3g_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mdio1_pins_default>;
+	status = "okay";
+
 	cpsw3g_phy0: ethernet-phy at 0 {
 		reg = <0>;
 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;

---
base-commit: 01af33cc9894b4489fb68fa35c40e9fe85df63dc
change-id: 20240201-am62p_cpsw_mdio-27f6a3ade8e0

Best regards,
-- 
Jai Luthra <j-luthra at ti.com>



From pabeni at redhat.com  Thu Feb  1 04:45:18 2024
From: pabeni at redhat.com (Paolo Abeni)
Date: Thu, 01 Feb 2024 13:45:18 +0100
Subject: [PATCH net-next v3] net: stmmac: dwmac-qcom-ethqos: Add support
 for 2.5G SGMII
In-Reply-To: <20240130111234.1244-1-quic_snehshah@quicinc.com>
References: <20240130111234.1244-1-quic_snehshah@quicinc.com>
Message-ID: <6fa06fbcc77fadbf87c63df66838fd98c07ff14a.camel@redhat.com>

On Tue, 2024-01-30 at 16:42 +0530, Sneh Shah wrote:
> @@ -608,17 +609,38 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
>  {
>  	int val;
>  
> +	struct platform_device *pdev = ethqos->pdev;
> +	struct net_device *dev = platform_get_drvdata(pdev);
> +	struct stmmac_priv *priv = netdev_priv(dev);
>  	val = readl(ethqos->mac_base + MAC_CTRL_REG);

I'm unsure why checkpatch did not catch the above, but you need to
remove the empty line in-between the local variables declaration and
you must insert an empty line between the last definition and the first
statement.

Please also reorder the variables to respect the reverse x-mas tree
order, something alike:

	struct net_device *dev = platform_get_drvdata(ethqos->pdev);
	struct stmmac_priv *priv = netdev_priv(dev);
	int val;

	val = readl(ethqos->mac_base + MAC_CTRL_REG);

...

Cheers,

Paolo




From mripard at kernel.org  Thu Feb  1 04:51:15 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 1 Feb 2024 13:51:15 +0100
Subject: [PATCH v5 15/44] drm/connector: hdmi: Compute bpc and format
 automatically
In-Reply-To: <CAPY8ntBQ+qY9441-rMzq_JAoYAaY_r+E-ADv7Wry0tJNTzKpwg@mail.gmail.com>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-15-6538e19d634d@kernel.org>
 <CAPY8ntBQ+qY9441-rMzq_JAoYAaY_r+E-ADv7Wry0tJNTzKpwg@mail.gmail.com>
Message-ID: <jlkoofv7nszj2uqmo2672yo4wjd3yjqarge2l2hxofixcchu6a@j72pa4iybitd>

On Thu, Dec 14, 2023 at 03:10:43PM +0000, Dave Stevenson wrote:
> > +static bool
> > +sink_supports_format_bpc(const struct drm_connector *connector,
> > +                        const struct drm_display_info *info,
> > +                        const struct drm_display_mode *mode,
> > +                        unsigned int format, unsigned int bpc)
> > +{
> > +       struct drm_device *dev = connector->dev;
> > +       u8 vic = drm_match_cea_mode(mode);
> > +
> > +       if (vic == 1 && bpc != 8) {
> > +               drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
> > +               return false;
> > +       }
> > +
> > +       if (!info->is_hdmi &&
> > +           (format != HDMI_COLORSPACE_RGB || bpc != 8)) {
> > +               drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
> > +               return false;
> > +       }
> > +
> > +       if (!(connector->hdmi.supported_formats & BIT(format))) {
> > +               drm_dbg(dev, "%s format unsupported by the connector.\n",
> > +                       drm_hdmi_connector_get_output_format_name(format));
> > +               return false;
> > +       }
> > +
> > +       switch (format) {
> > +       case HDMI_COLORSPACE_RGB:
> > +               drm_dbg(dev, "RGB Format, checking the constraints.\n");
> > +
> > +               if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
> > +                       return false;
> 
> We've dropped this check from vc4 in our downstream kernel as it stops
> you using the prebaked EDIDs (eg drm.edid_firmware=edid/1024x768.bin),
> or any other EDID that is defined as an analog monitor.
> The EDID parsing bombs out at [1], so info->color_formats gets left at 0.

Right, but it only does so if the display isn't defined as a digital display...

> RGB is mandatory for both DVI and HDMI, so rejecting it seems overly fussy.

... which is required for both DVI and HDMI.

And sure enough, if we decode that EDID:

edid-decode (hex):

00 ff ff ff ff ff ff 00 31 d8 00 00 00 00 00 00
05 16 01 03 6d 23 1a 78 ea 5e c0 a4 59 4a 98 25
20 50 54 00 08 00 61 40 01 01 01 01 01 01 01 01
01 01 01 01 01 01 64 19 00 40 41 00 26 30 08 90
36 00 63 0a 11 00 00 18 00 00 00 ff 00 4c 69 6e
75 78 20 23 30 0a 20 20 20 20 00 00 00 fd 00 3b
3d 2f 31 07 00 0a 20 20 20 20 20 20 00 00 00 fc
00 4c 69 6e 75 78 20 58 47 41 0a 20 20 20 00 55

----------------

Block 0, Base EDID:
  EDID Structure Version & Revision: 1.3
  Vendor & Product Identification:
    Manufacturer: LNX
    Model: 0
    Made in: week 5 of 2012
  Basic Display Parameters & Features:
    Analog display
    Signal Level Standard: 0.700 : 0.000 : 0.700 V p-p
    Blank level equals black level
    Sync: Separate Composite Serration
    Maximum image size: 35 cm x 26 cm
    Gamma: 2.20
    DPMS levels: Standby Suspend Off
    RGB color display
    First detailed timing is the preferred timing
  Color Characteristics:
    Red  : 0.6416, 0.3486
    Green: 0.2919, 0.5957
    Blue : 0.1474, 0.1250
    White: 0.3125, 0.3281
  Established Timings I & II:
    DMT 0x10:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz
  Standard Timings:
    DMT 0x10:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz
  Detailed Timing Descriptors:
    DTD 1:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz (355 mm x 266 mm)
                 Hfront    8 Hsync 144 Hback  168 Hpol N
                 Vfront    3 Vsync   6 Vback   29 Vpol N
    Display Product Serial Number: 'Linux #0'
    Display Range Limits:
      Monitor ranges (GTF): 59-61 Hz V, 47-49 kHz H, max dotclock 70 MHz
    Display Product Name: 'Linux XGA'
Checksum: 0x55

----------------

Warnings:

Block 0, Base EDID:
  Detailed Timing Descriptor #1: DTD is similar but not identical to DMT 0x10.

EDID conformity: PASS

So, if anything, it's the EDID that needs to be updated, not the code there.
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/20240201/fdb6755e/attachment.sig>

From peter.griffin at linaro.org  Thu Feb  1 04:51:47 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu, 1 Feb 2024 12:51:47 +0000
Subject: [PATCH v2 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <fb530eb8-e32b-4faf-81f3-efc334ebf241@linaro.org>
References: <20240129211912.3068411-1-peter.griffin@linaro.org>
 <20240129211912.3068411-2-peter.griffin@linaro.org> <fb530eb8-e32b-4faf-81f3-efc334ebf241@linaro.org>
Message-ID: <CADrjBPoQmTRsFYRtxBxdvAoKK816O8XN3=hOJ3vBt8wbbbk-=Q@mail.gmail.com>

Hi Krzysztof,

On Tue, 30 Jan 2024 at 16:01, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 29/01/2024 22:19, Peter Griffin wrote:
> > Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> > security hardening reasons so that they are only accessible in el3 via an
> > SMC call.
> >
> > As most Exynos drivers that need to write PMU registers currently obtain a
> > regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> > is implemented in this driver using a custom regmap similar to syscon to
> > handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> > regmap like before. As regmaps abstract out the underlying register access
> > changes to the leaf drivers are minimal.
> >
> > A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> > that currently use syscon_regmap_lookup_by_phandle(). This also handles
> > deferred probing.
> >
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > ---
> >  drivers/soc/samsung/exynos-pmu.c       | 227 ++++++++++++++++++++++++-
> >  include/linux/soc/samsung/exynos-pmu.h |  10 ++
> >  2 files changed, 236 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> > index 250537d7cfd6..7bcc144e53a2 100644
> > --- a/drivers/soc/samsung/exynos-pmu.c
> > +++ b/drivers/soc/samsung/exynos-pmu.c
> > @@ -5,6 +5,7 @@
> >  //
> >  // Exynos - CPU PMU(Power Management Unit) support
> >
> > +#include <linux/arm-smccc.h>
> >  #include <linux/of.h>
> >  #include <linux/of_address.h>
> >  #include <linux/mfd/core.h>
> > @@ -12,20 +13,159 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/delay.h>
> > +#include <linux/regmap.h>
> >
> >  #include <linux/soc/samsung/exynos-regs-pmu.h>
> >  #include <linux/soc/samsung/exynos-pmu.h>
> >
> >  #include "exynos-pmu.h"
> >
> > +static struct platform_driver exynos_pmu_driver;
>
> I don't understand why do you need it. You can have only one
> pmu_context. The moment you probe second one, previous becomes invalid.
>
> I guess you want to parse phandle and check if just in case if it points
> to the right device, but still the original code is not ready for two
> PMU devices. I say either this problem should be solved entirely,
> allowing two devices, or just compare device node from phandle with
> device node of exynos_pmu_context->dev and return -EINVAL on mismatches.

Apologies I didn't answer your original question. This wasn't about
having partial support for multiple pmu devices. It is being used by
driver_find_device_by_of_node() in exynos_get_pmu_regmap_by_phandle()
to determine that the exynos-pmu device has probed and therefore a
pmu_context exists and a regmap has been created and can be returned
to the caller (as opposed to doing a -EPROBE_DEFER).

Is there some better/other API you recommend for this purpose? Just
checking pmu_context directly seems racy, so I don't think we should
do that.

Peter

[...]


From puranjay12 at gmail.com  Thu Feb  1 04:52:23 2024
From: puranjay12 at gmail.com (Puranjay Mohan)
Date: Thu,  1 Feb 2024 12:52:23 +0000
Subject: [PATCH bpf-next v3 0/2] bpf, arm64: Support Exceptions
Message-ID: <20240201125225.72796-1-puranjay12@gmail.com>

Changes in V2->V3:
V2: https://lore.kernel.org/all/20230917000045.56377-1-puranjay12 at gmail.com/
- Use unwinder from stacktrace.c rather than open coding the unwind logic.
- Fix a bug in the prologue related to BPF_FP (Xu Kuohai)

Changes in V1->V2:
V1: https://lore.kernel.org/all/20230912233942.6734-1-puranjay12 at gmail.com/
- Remove exceptions from DENYLIST.aarch64 as they are supported now.

The base support for exceptions was merged with [1] and it was enabled for
x86-64.

This patch set enables the support on ARM64, all sefltests are passing:

# ./test_progs -a exceptions
#74/1    exceptions/exception_throw_always_1:OK
#74/2    exceptions/exception_throw_always_2:OK
#74/3    exceptions/exception_throw_unwind_1:OK
#74/4    exceptions/exception_throw_unwind_2:OK
#74/5    exceptions/exception_throw_default:OK
#74/6    exceptions/exception_throw_default_value:OK
#74/7    exceptions/exception_tail_call:OK
#74/8    exceptions/exception_ext:OK
#74/9    exceptions/exception_ext_mod_cb_runtime:OK
#74/10   exceptions/exception_throw_subprog:OK
#74/11   exceptions/exception_assert_nz_gfunc:OK
#74/12   exceptions/exception_assert_zero_gfunc:OK
#74/13   exceptions/exception_assert_neg_gfunc:OK
#74/14   exceptions/exception_assert_pos_gfunc:OK
#74/15   exceptions/exception_assert_negeq_gfunc:OK
#74/16   exceptions/exception_assert_poseq_gfunc:OK
#74/17   exceptions/exception_assert_nz_gfunc_with:OK
#74/18   exceptions/exception_assert_zero_gfunc_with:OK
#74/19   exceptions/exception_assert_neg_gfunc_with:OK
#74/20   exceptions/exception_assert_pos_gfunc_with:OK
#74/21   exceptions/exception_assert_negeq_gfunc_with:OK
#74/22   exceptions/exception_assert_poseq_gfunc_with:OK
#74/23   exceptions/exception_bad_assert_nz_gfunc:OK
#74/24   exceptions/exception_bad_assert_zero_gfunc:OK
#74/25   exceptions/exception_bad_assert_neg_gfunc:OK
#74/26   exceptions/exception_bad_assert_pos_gfunc:OK
#74/27   exceptions/exception_bad_assert_negeq_gfunc:OK
#74/28   exceptions/exception_bad_assert_poseq_gfunc:OK
#74/29   exceptions/exception_bad_assert_nz_gfunc_with:OK
#74/30   exceptions/exception_bad_assert_zero_gfunc_with:OK
#74/31   exceptions/exception_bad_assert_neg_gfunc_with:OK
#74/32   exceptions/exception_bad_assert_pos_gfunc_with:OK
#74/33   exceptions/exception_bad_assert_negeq_gfunc_with:OK
#74/34   exceptions/exception_bad_assert_poseq_gfunc_with:OK
#74/35   exceptions/exception_assert_range:OK
#74/36   exceptions/exception_assert_range_with:OK
#74/37   exceptions/exception_bad_assert_range:OK
#74/38   exceptions/exception_bad_assert_range_with:OK
#74/39   exceptions/non-throwing fentry -> exception_cb:OK
#74/40   exceptions/throwing fentry -> exception_cb:OK
#74/41   exceptions/non-throwing fexit -> exception_cb:OK
#74/42   exceptions/throwing fexit -> exception_cb:OK
#74/43   exceptions/throwing extension (with custom cb) -> exception_cb:OK
#74/44   exceptions/throwing extension -> global func in exception_cb:OK
#74/45   exceptions/exception_ext_mod_cb_runtime:OK
#74/46   exceptions/throwing extension (with custom cb) -> global func in exception_cb:OK
#74/47   exceptions/exception_ext:OK
#74/48   exceptions/non-throwing fentry -> non-throwing subprog:OK
#74/49   exceptions/throwing fentry -> non-throwing subprog:OK
#74/50   exceptions/non-throwing fentry -> throwing subprog:OK
#74/51   exceptions/throwing fentry -> throwing subprog:OK
#74/52   exceptions/non-throwing fexit -> non-throwing subprog:OK
#74/53   exceptions/throwing fexit -> non-throwing subprog:OK
#74/54   exceptions/non-throwing fexit -> throwing subprog:OK
#74/55   exceptions/throwing fexit -> throwing subprog:OK
#74/56   exceptions/non-throwing fmod_ret -> non-throwing subprog:OK
#74/57   exceptions/non-throwing fmod_ret -> non-throwing global subprog:OK
#74/58   exceptions/non-throwing extension -> non-throwing subprog:OK
#74/59   exceptions/non-throwing extension -> throwing subprog:OK
#74/60   exceptions/non-throwing extension -> non-throwing subprog:OK
#74/61   exceptions/non-throwing extension -> throwing global subprog:OK
#74/62   exceptions/throwing extension -> throwing global subprog:OK
#74/63   exceptions/throwing extension -> non-throwing global subprog:OK
#74/64   exceptions/non-throwing extension -> main subprog:OK
#74/65   exceptions/throwing extension -> main subprog:OK
#74/66   exceptions/reject_exception_cb_type_1:OK
#74/67   exceptions/reject_exception_cb_type_2:OK
#74/68   exceptions/reject_exception_cb_type_3:OK
#74/69   exceptions/reject_exception_cb_type_4:OK
#74/70   exceptions/reject_async_callback_throw:OK
#74/71   exceptions/reject_with_lock:OK
#74/72   exceptions/reject_subprog_with_lock:OK
#74/73   exceptions/reject_with_rcu_read_lock:OK
#74/74   exceptions/reject_subprog_with_rcu_read_lock:OK
#74/75   exceptions/reject_with_rbtree_add_throw:OK
#74/76   exceptions/reject_with_reference:OK
#74/77   exceptions/reject_with_cb_reference:OK
#74/78   exceptions/reject_with_cb:OK
#74/79   exceptions/reject_with_subprog_reference:OK
#74/80   exceptions/reject_throwing_exception_cb:OK
#74/81   exceptions/reject_exception_cb_call_global_func:OK
#74/82   exceptions/reject_exception_cb_call_static_func:OK
#74/83   exceptions/reject_multiple_exception_cb:OK
#74/84   exceptions/reject_exception_throw_cb:OK
#74/85   exceptions/reject_exception_throw_cb_diff:OK
#74/86   exceptions/reject_set_exception_cb_bad_ret1:OK
#74/87   exceptions/reject_set_exception_cb_bad_ret2:OK
#74/88   exceptions/check_assert_eq_int_min:OK
#74/89   exceptions/check_assert_eq_int_max:OK
#74/90   exceptions/check_assert_eq_zero:OK
#74/91   exceptions/check_assert_eq_llong_min:OK
#74/92   exceptions/check_assert_eq_llong_max:OK
#74/93   exceptions/check_assert_lt_pos:OK
#74/94   exceptions/check_assert_lt_zero:OK
#74/95   exceptions/check_assert_lt_neg:OK
#74/96   exceptions/check_assert_le_pos:OK
#74/97   exceptions/check_assert_le_zero:OK
#74/98   exceptions/check_assert_le_neg:OK
#74/99   exceptions/check_assert_gt_pos:OK
#74/100  exceptions/check_assert_gt_zero:OK
#74/101  exceptions/check_assert_gt_neg:OK
#74/102  exceptions/check_assert_ge_pos:OK
#74/103  exceptions/check_assert_ge_zero:OK
#74/104  exceptions/check_assert_ge_neg:OK
#74/105  exceptions/check_assert_range_s64:OK
#74/106  exceptions/check_assert_range_u64:OK
#74/107  exceptions/check_assert_single_range_s64:OK
#74/108  exceptions/check_assert_single_range_u64:OK
#74/109  exceptions/check_assert_generic:OK
#74/110  exceptions/check_assert_with_return:OK
#74      exceptions:OK
Summary: 1/110 PASSED, 0 SKIPPED, 0 FAILED

[1] https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?h=for-next&id=ec6f1b4db95b7eedb3fe85f4f14e08fa0e9281c3

Puranjay Mohan (2):
  arm64: stacktrace: Implement arch_bpf_stack_walk() for the BPF JIT
  bpf, arm64: support exceptions

 arch/arm64/kernel/stacktrace.c               | 26 ++++++
 arch/arm64/net/bpf_jit_comp.c                | 87 +++++++++++++++-----
 tools/testing/selftests/bpf/DENYLIST.aarch64 |  1 -
 3 files changed, 94 insertions(+), 20 deletions(-)

-- 
2.40.1



From puranjay12 at gmail.com  Thu Feb  1 04:52:24 2024
From: puranjay12 at gmail.com (Puranjay Mohan)
Date: Thu,  1 Feb 2024 12:52:24 +0000
Subject: [PATCH bpf-next v3 1/2] arm64: stacktrace: Implement arch_bpf_stack_walk() for the BPF JIT
In-Reply-To: <20240201125225.72796-1-puranjay12@gmail.com>
References: <20240201125225.72796-1-puranjay12@gmail.com>
Message-ID: <20240201125225.72796-2-puranjay12@gmail.com>

This will be used by bpf_throw() to unwind till the program marked as
exception boundary and run the callback with the stack of the main
program.

This is required for supporting BPF exceptions on ARM64.

Signed-off-by: Puranjay Mohan <puranjay12 at gmail.com>
---
 arch/arm64/kernel/stacktrace.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 7f88028a00c0..66cffc5fc0be 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -7,6 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/efi.h>
 #include <linux/export.h>
+#include <linux/filter.h>
 #include <linux/ftrace.h>
 #include <linux/kprobes.h>
 #include <linux/sched.h>
@@ -266,6 +267,31 @@ noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
 	kunwind_stack_walk(arch_kunwind_consume_entry, &data, task, regs);
 }
 
+struct bpf_unwind_consume_entry_data {
+	bool (*consume_entry)(void *cookie, u64 ip, u64 sp, u64 fp);
+	void *cookie;
+};
+
+static bool
+arch_bpf_unwind_consume_entry(const struct kunwind_state *state, void *cookie)
+{
+	struct bpf_unwind_consume_entry_data *data = cookie;
+
+	return data->consume_entry(data->cookie, state->common.pc, 0,
+				   state->common.fp);
+}
+
+noinline noinstr void arch_bpf_stack_walk(bool (*consume_entry)(void *cookie, u64 ip, u64 sp,
+								u64 fp), void *cookie)
+{
+	struct bpf_unwind_consume_entry_data data = {
+		.consume_entry = consume_entry,
+		.cookie = cookie,
+	};
+
+	kunwind_stack_walk(arch_bpf_unwind_consume_entry, &data, current, NULL);
+}
+
 static bool dump_backtrace_entry(void *arg, unsigned long where)
 {
 	char *loglvl = arg;
-- 
2.40.1



From puranjay12 at gmail.com  Thu Feb  1 04:52:25 2024
From: puranjay12 at gmail.com (Puranjay Mohan)
Date: Thu,  1 Feb 2024 12:52:25 +0000
Subject: [PATCH bpf-next v3 2/2] bpf, arm64: support exceptions
In-Reply-To: <20240201125225.72796-1-puranjay12@gmail.com>
References: <20240201125225.72796-1-puranjay12@gmail.com>
Message-ID: <20240201125225.72796-3-puranjay12@gmail.com>

The prologue generation code has been modified to make the callback
program use the stack of the program marked as exception boundary where
callee-saved registers are already pushed.

As the bpf_throw function never returns, if it clobbers any callee-saved
registers, they would remain clobbered. So, the prologue of the
exception-boundary program is modified to push R23 and R24 as well,
which the callback will then recover in its epilogue.

The Procedure Call Standard for the Arm 64-bit Architecture[1] states
that registers r19 to r28 should be saved by the callee. BPF programs on
ARM64 already save all callee-saved registers except r23 and r24. This
patch adds an instruction in prologue of the  program to save these
two registers and another instruction in the epilogue to recover them.

These extra instructions are only added if bpf_throw() is used. Otherwise
the emitted prologue/epilogue remains unchanged.

[1] https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst

Signed-off-by: Puranjay Mohan <puranjay12 at gmail.com>
---
 arch/arm64/net/bpf_jit_comp.c                | 87 +++++++++++++++-----
 tools/testing/selftests/bpf/DENYLIST.aarch64 |  1 -
 2 files changed, 68 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index cfd5434de483..20720ec346b8 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -285,7 +285,8 @@ static bool is_lsi_offset(int offset, int scale)
 /* Tail call offset to jump into */
 #define PROLOGUE_OFFSET (BTI_INSNS + 2 + PAC_INSNS + 8)
 
-static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
+static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf,
+			  bool is_exception_cb)
 {
 	const struct bpf_prog *prog = ctx->prog;
 	const bool is_main_prog = !bpf_is_subprog(prog);
@@ -333,19 +334,34 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
 	emit(A64_MOV(1, A64_R(9), A64_LR), ctx);
 	emit(A64_NOP, ctx);
 
-	/* Sign lr */
-	if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL))
-		emit(A64_PACIASP, ctx);
-
-	/* Save FP and LR registers to stay align with ARM64 AAPCS */
-	emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
-	emit(A64_MOV(1, A64_FP, A64_SP), ctx);
-
-	/* Save callee-saved registers */
-	emit(A64_PUSH(r6, r7, A64_SP), ctx);
-	emit(A64_PUSH(r8, r9, A64_SP), ctx);
-	emit(A64_PUSH(fp, tcc, A64_SP), ctx);
-	emit(A64_PUSH(fpb, A64_R(28), A64_SP), ctx);
+	if (!is_exception_cb) {
+		/* Sign lr */
+		if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL))
+			emit(A64_PACIASP, ctx);
+		/* Save FP and LR registers to stay align with ARM64 AAPCS */
+		emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
+		emit(A64_MOV(1, A64_FP, A64_SP), ctx);
+
+		/* Save callee-saved registers */
+		emit(A64_PUSH(r6, r7, A64_SP), ctx);
+		emit(A64_PUSH(r8, r9, A64_SP), ctx);
+		emit(A64_PUSH(fp, tcc, A64_SP), ctx);
+		emit(A64_PUSH(fpb, A64_R(28), A64_SP), ctx);
+	} else {
+		/*
+		 * Exception callback receives FP of Main Program as third
+		 * parameter
+		 */
+		emit(A64_MOV(1, A64_FP, A64_R(2)), ctx);
+		/*
+		 * Main Program already pushed the frame record and the
+		 * callee-saved registers. The exception callback will not push
+		 * anything and re-use the main program's stack.
+		 *
+		 * 10 registers are on the stack
+		 */
+		emit(A64_SUB_I(1, A64_SP, A64_FP, 80), ctx);
+	}
 
 	/* Set up BPF prog stack base register */
 	emit(A64_MOV(1, fp, A64_SP), ctx);
@@ -365,6 +381,20 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
 		emit_bti(A64_BTI_J, ctx);
 	}
 
+	/*
+	 * Program acting as exception boundary should save all ARM64
+	 * Callee-saved registers as the exception callback needs to recover
+	 * all ARM64 Callee-saved registers in its epilogue.
+	 */
+	if (prog->aux->exception_boundary) {
+		/*
+		 * As we are pushing two more registers, BPF_FP should be moved
+		 * 16 bytes
+		 */
+		emit(A64_SUB_I(1, fp, fp, 16), ctx);
+		emit(A64_PUSH(A64_R(23), A64_R(24), A64_SP), ctx);
+	}
+
 	emit(A64_SUB_I(1, fpb, fp, ctx->fpb_offset), ctx);
 
 	/* Stack must be multiples of 16B */
@@ -653,7 +683,7 @@ static void build_plt(struct jit_ctx *ctx)
 		plt->target = (u64)&dummy_tramp;
 }
 
-static void build_epilogue(struct jit_ctx *ctx)
+static void build_epilogue(struct jit_ctx *ctx, bool is_exception_cb)
 {
 	const u8 r0 = bpf2a64[BPF_REG_0];
 	const u8 r6 = bpf2a64[BPF_REG_6];
@@ -666,6 +696,15 @@ static void build_epilogue(struct jit_ctx *ctx)
 	/* We're done with BPF stack */
 	emit(A64_ADD_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
 
+	/*
+	 * Program acting as exception boundary pushes R23 and R24 in addition
+	 * to BPF callee-saved registers. Exception callback uses the boundary
+	 * program's stack frame, so recover these extra registers in the above
+	 * two cases.
+	 */
+	if (ctx->prog->aux->exception_boundary || is_exception_cb)
+		emit(A64_POP(A64_R(23), A64_R(24), A64_SP), ctx);
+
 	/* Restore x27 and x28 */
 	emit(A64_POP(fpb, A64_R(28), A64_SP), ctx);
 	/* Restore fs (x25) and x26 */
@@ -1575,7 +1614,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	 * 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)) {
+	if (build_prologue(&ctx, was_classic, prog->aux->exception_cb)) {
 		prog = orig_prog;
 		goto out_off;
 	}
@@ -1586,7 +1625,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	}
 
 	ctx.epilogue_offset = ctx.idx;
-	build_epilogue(&ctx);
+	build_epilogue(&ctx, prog->aux->exception_cb);
 	build_plt(&ctx);
 
 	extable_align = __alignof__(struct exception_table_entry);
@@ -1614,7 +1653,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	ctx.idx = 0;
 	ctx.exentry_idx = 0;
 
-	build_prologue(&ctx, was_classic);
+	build_prologue(&ctx, was_classic, prog->aux->exception_cb);
 
 	if (build_body(&ctx, extra_pass)) {
 		bpf_jit_binary_free(header);
@@ -1622,7 +1661,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 		goto out_off;
 	}
 
-	build_epilogue(&ctx);
+	build_epilogue(&ctx, prog->aux->exception_cb);
 	build_plt(&ctx);
 
 	/* 3. Extra pass to validate JITed code. */
@@ -2310,3 +2349,13 @@ bool bpf_jit_supports_ptr_xchg(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_exceptions(void)
+{
+	/* We unwind through both kernel frames starting from within bpf_throw
+	 * call and BPF frames. Therefore we require FP unwinder to be enabled
+	 * to walk kernel frames and reach BPF frames in the stack trace.
+	 * ARM64 kernel is aways compiled with CONFIG_FRAME_POINTER=y
+	 */
+	return true;
+}
diff --git a/tools/testing/selftests/bpf/DENYLIST.aarch64 b/tools/testing/selftests/bpf/DENYLIST.aarch64
index 5c2cc7e8c5d0..0445ac38bc07 100644
--- a/tools/testing/selftests/bpf/DENYLIST.aarch64
+++ b/tools/testing/selftests/bpf/DENYLIST.aarch64
@@ -1,6 +1,5 @@
 bpf_cookie/multi_kprobe_attach_api               # kprobe_multi_link_api_subtest:FAIL:fentry_raw_skel_load unexpected error: -3
 bpf_cookie/multi_kprobe_link_api                 # kprobe_multi_link_api_subtest:FAIL:fentry_raw_skel_load unexpected error: -3
-exceptions					 # JIT does not support calling kfunc bpf_throw: -524
 fexit_sleep                                      # The test never returns. The remaining tests cannot start.
 kprobe_multi_bench_attach                        # needs CONFIG_FPROBE
 kprobe_multi_test                                # needs CONFIG_FPROBE
-- 
2.40.1



From angelogioacchino.delregno at collabora.com  Thu Feb  1 04:53:01 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  1 Feb 2024 13:53:01 +0100
Subject: [PATCH 0/3] drm/mediatek: Fixes for DDP component search/destroy
Message-ID: <20240201125304.218467-1-angelogioacchino.delregno@collabora.com>

This series performs some cleanups for DDP component CRTC search and
correctly iounmaps the previously of_iomap() calls from drm_ddp_comp.

Tested on MT8195 Cherry Tomato

AngeloGioacchino Del Regno (3):
  drm/mediatek: drm_ddp_comp: Fix and cleanup DDP component CRTC search
  drm/mediatek: Perform iounmap on simple DDP component destruction
  drm/mediatek: drm_ddp_comp: Add mtk_ddp_is_simple_comp() internal
    helper

 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 113 +++++++++++++-------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   4 +-
 3 files changed, 80 insertions(+), 38 deletions(-)

-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb  1 04:53:04 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  1 Feb 2024 13:53:04 +0100
Subject: [PATCH 3/3] drm/mediatek: drm_ddp_comp: Add mtk_ddp_is_simple_comp() internal helper
In-Reply-To: <20240201125304.218467-1-angelogioacchino.delregno@collabora.com>
References: <20240201125304.218467-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240201125304.218467-4-angelogioacchino.delregno@collabora.com>

Move the simple component check to a new mtk_ddp_is_simple_comp()
internal helper to reduce code duplication.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 57 +++++++++++----------
 1 file changed, 31 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 539b526a6b0a..4ca2a02ada3c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -575,6 +575,29 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
 	return ret;
 }
 
+static bool mtk_ddp_is_simple_comp(enum mtk_ddp_comp_type type)
+{
+	switch (type) {
+	case MTK_DISP_AAL:
+	case MTK_DISP_BLS:
+	case MTK_DISP_CCORR:
+	case MTK_DISP_COLOR:
+	case MTK_DISP_GAMMA:
+	case MTK_DISP_MERGE:
+	case MTK_DISP_OVL:
+	case MTK_DISP_OVL_2L:
+	case MTK_DISP_OVL_ADAPTOR:
+	case MTK_DISP_PWM:
+	case MTK_DISP_RDMA:
+	case MTK_DP_INTF:
+	case MTK_DPI:
+	case MTK_DSI:
+		return false;
+	default:
+		return true;
+	}
+}
+
 int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 		      unsigned int comp_id)
 {
@@ -605,19 +628,13 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	}
 	comp->dev = &comp_pdev->dev;
 
-	if (type == MTK_DISP_AAL ||
-	    type == MTK_DISP_BLS ||
-	    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 ||
-	    type == MTK_DISP_RDMA ||
-	    type == MTK_DPI ||
-	    type == MTK_DP_INTF ||
-	    type == MTK_DSI)
+	/*
+	 * Resources for simple components are retrieved here as those are
+	 * managed in here without the need of more complex drivers; for
+	 * the latter, their respective probe function will do the job, so
+	 * we must avoid getting their resources here.
+	 */
+	if (!mtk_ddp_is_simple_comp(type))
 		return 0;
 
 	priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
@@ -651,19 +668,7 @@ void mtk_ddp_comp_destroy(struct mtk_ddp_comp *comp)
 		return;
 
 	/* Complex components are destroyed with their own remove callback */
-	if (type == MTK_DISP_AAL ||
-	    type == MTK_DISP_BLS ||
-	    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 ||
-	    type == MTK_DISP_RDMA ||
-	    type == MTK_DPI ||
-	    type == MTK_DP_INTF ||
-	    type == MTK_DSI)
+	if (!mtk_ddp_is_simple_comp(mtk_ddp_matches[comp->id].type))
 		return;
 
 	priv = dev_get_drvdata(comp->dev);
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb  1 04:53:03 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  1 Feb 2024 13:53:03 +0100
Subject: [PATCH 2/3] drm/mediatek: Perform iounmap on simple DDP component destruction
In-Reply-To: <20240201125304.218467-1-angelogioacchino.delregno@collabora.com>
References: <20240201125304.218467-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240201125304.218467-3-angelogioacchino.delregno@collabora.com>

Add a new mtk_ddp_comp_destroy() function and call it in the teardown
path of mtk_drm_drv to make sure that we unmap the iospace of the
simple DDP components.

While at it, also fix iounmapping on mtk_ddp_comp_init() error path.

Fixes: ff1395609e20 ("drm/mediatek: Move mtk_ddp_comp_init() from sub driver to DRM driver")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 38 ++++++++++++++++++++-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  4 ++-
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index c13359eeb3cd..539b526a6b0a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -626,8 +626,11 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 
 	priv->regs = of_iomap(node, 0);
 	priv->clk = of_clk_get(node, 0);
-	if (IS_ERR(priv->clk))
+	if (IS_ERR(priv->clk)) {
+		iounmap(priv->regs);
+		priv->regs = NULL;
 		return PTR_ERR(priv->clk);
+	}
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	ret = cmdq_dev_get_client_reg(comp->dev, &priv->cmdq_reg, 0);
@@ -639,3 +642,36 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 
 	return 0;
 }
+
+void mtk_ddp_comp_destroy(struct mtk_ddp_comp *comp)
+{
+	struct mtk_ddp_comp_dev *priv;
+
+	if (!comp || !comp->dev)
+		return;
+
+	/* Complex components are destroyed with their own remove callback */
+	if (type == MTK_DISP_AAL ||
+	    type == MTK_DISP_BLS ||
+	    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 ||
+	    type == MTK_DISP_RDMA ||
+	    type == MTK_DPI ||
+	    type == MTK_DP_INTF ||
+	    type == MTK_DSI)
+		return;
+
+	priv = dev_get_drvdata(comp->dev);
+	if (!priv)
+		return;
+
+	if (priv->regs) {
+		iounmap(priv->regs);
+		priv->regs = NULL;
+	}
+}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 15b2eafff438..43372b416a3f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -318,6 +318,7 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
 						struct device *dev);
 int mtk_ddp_comp_init(struct device_node *comp_node, struct mtk_ddp_comp *comp,
 		      unsigned int comp_id);
+void mtk_ddp_comp_destroy(struct mtk_ddp_comp *comp);
 enum mtk_ddp_comp_type mtk_ddp_comp_get_type(unsigned int comp_id);
 void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 		   struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 14a1e0157cc4..89b6c31a1511 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -944,8 +944,10 @@ static void mtk_drm_remove(struct platform_device *pdev)
 	component_master_del(&pdev->dev, &mtk_drm_ops);
 	pm_runtime_disable(&pdev->dev);
 	of_node_put(private->mutex_node);
-	for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
+	for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++) {
+		mtk_ddp_comp_destroy(&private->ddp_comp[i]);
 		of_node_put(private->comp_node[i]);
+	}
 }
 
 static int mtk_drm_sys_prepare(struct device *dev)
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb  1 04:53:02 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  1 Feb 2024 13:53:02 +0100
Subject: [PATCH 1/3] drm/mediatek: drm_ddp_comp: Fix and cleanup DDP component CRTC search
In-Reply-To: <20240201125304.218467-1-angelogioacchino.delregno@collabora.com>
References: <20240201125304.218467-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240201125304.218467-2-angelogioacchino.delregno@collabora.com>

Finding a possible CRTC by DDP component is done by first checking
static routes in three paths (main, external, third/extra path) and
then, if not found, we check for dynamic connection on a per-route
basis because, for example, on some SoCs the main route may output
to either a DSI display or DisplayPort and this is finally done by
assigning a CRTC mask to `possible_crtcs`, found with function
mtk_drm_find_comp_in_ddp_conn_path(): being that a mask the possible
values are BIT(x) and, if no CRTC is possible, zero.

Problem is, both mtk_drm_find_possible_crtc_by_comp() and the
aforementioned function are trying to return a negative error value
(but it's unsigned int!) if no CRTC was found, which is wrong for
multiple obvious reasons.

Cleanup both functions, so that:
 - mtk_drm_find_comp_in_ddp_conn_path() returns a signed integer
   with a negative number for error, or a bit/bitmask of the found
   possible CRTC; and
 - mtk_drm_find_possible_crtc_by_comp() always returns either a
   bitmask of the possible CRTC, or zero if none available.

Fixes: 01389b324c97 ("drm/mediatek: Add connector dynamic selection capability")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 44 ++++++++++-----------
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index a9b5a21cde2d..c13359eeb3cd 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -513,29 +513,25 @@ static bool mtk_drm_find_comp_in_ddp(struct device *dev,
 	return false;
 }
 
-static unsigned int mtk_drm_find_comp_in_ddp_conn_path(struct device *dev,
-						       const struct mtk_drm_route *routes,
-						       unsigned int num_routes,
-						       struct mtk_ddp_comp *ddp_comp)
+static int mtk_drm_find_comp_in_ddp_conn_path(struct device *dev,
+					      const struct mtk_drm_route *routes,
+					      unsigned int num_routes,
+					      struct mtk_ddp_comp *ddp_comp)
 {
-	int ret;
-	unsigned int i;
+	int i;
 
-	if (!routes) {
-		ret = -EINVAL;
-		goto err;
+	if (!routes || !num_routes) {
+		DRM_ERROR("No connection routes specified!\n");
+		return -EINVAL;
 	}
 
 	for (i = 0; i < num_routes; i++)
 		if (dev == ddp_comp[routes[i].route_ddp].dev)
 			return BIT(routes[i].crtc_id);
 
-	ret = -ENODEV;
-err:
-
-	DRM_INFO("Failed to find comp in ddp table, ret = %d\n", ret);
+	DRM_ERROR("Failed to find component in ddp table\n");
 
-	return 0;
+	return -ENODEV;
 }
 
 int mtk_ddp_comp_get_id(struct device_node *node,
@@ -557,22 +553,24 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
 						struct device *dev)
 {
 	struct mtk_drm_private *private = drm->dev_private;
-	unsigned int ret = 0;
+	int ret;
 
 	if (mtk_drm_find_comp_in_ddp(dev, private->data->main_path, private->data->main_len,
 				     private->ddp_comp))
-		ret = BIT(0);
+		return BIT(0);
 	else if (mtk_drm_find_comp_in_ddp(dev, private->data->ext_path,
 					  private->data->ext_len, private->ddp_comp))
-		ret = BIT(1);
+		return BIT(1);
 	else if (mtk_drm_find_comp_in_ddp(dev, private->data->third_path,
 					  private->data->third_len, private->ddp_comp))
-		ret = BIT(2);
-	else
-		ret = mtk_drm_find_comp_in_ddp_conn_path(dev,
-							 private->data->conn_routes,
-							 private->data->num_conn_routes,
-							 private->ddp_comp);
+		return BIT(2);
+
+	ret = mtk_drm_find_comp_in_ddp_conn_path(dev, private->data->conn_routes,
+						 private->data->num_conn_routes,
+						 private->ddp_comp);
+	/* No CRTC is available: return a zero mask */
+	if (ret < 0)
+		return 0;
 
 	return ret;
 }
-- 
2.43.0



From a-bhatia1 at ti.com  Thu Feb  1 04:54:50 2024
From: a-bhatia1 at ti.com (Aradhya Bhatia)
Date: Thu, 1 Feb 2024 18:24:50 +0530
Subject: [PATCH 1/3] arm64: dts: ti: k3-am62a-main: Add node for Display SubSystem (DSS)
In-Reply-To: <20240201125452.1920623-1-a-bhatia1@ti.com>
References: <20240201125452.1920623-1-a-bhatia1@ti.com>
Message-ID: <20240201125452.1920623-2-a-bhatia1@ti.com>

Add Display SubSystem (DSS) DT node for the AM62A7 SoC.

The DSS supports one each of video pipeline (vid) and video-lite
pipeline (vidl1). The video port 1 (vp1) is tied-off in AM62A SoC, but
the pipeline remains active. The video port 2 (vp2) outputs the DPI
signals. Both the video ports are connected to the pipelines via 2
identical overlay managers (ovr1 and ovr2).

Signed-off-by: Aradhya Bhatia <a-bhatia1 at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 25 +++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index f0b8c9ab1459..d3de5ad3eeb2 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -985,4 +985,29 @@ dphy0: phy at 30110000 {
 		power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 	};
+
+	dss: dss at 30200000 {
+		compatible = "ti,am62a7-dss";
+		reg = <0x00 0x30200000 0x00 0x1000>, /* common */
+		      <0x00 0x30202000 0x00 0x1000>, /* vidl1 */
+		      <0x00 0x30206000 0x00 0x1000>, /* vid */
+		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
+		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
+		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Tied OFF in the SoC */
+		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+		reg-names = "common", "vidl1", "vid",
+			    "ovr1", "ovr2", "vp1", "vp2";
+		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 186 6>,
+			 <&k3_clks 186 0>,
+			 <&k3_clks 186 2>;
+		clock-names = "fck", "vp1", "vp2";
+		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+
+		dss_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
 };
-- 
2.34.1



From a-bhatia1 at ti.com  Thu Feb  1 04:54:49 2024
From: a-bhatia1 at ti.com (Aradhya Bhatia)
Date: Thu, 1 Feb 2024 18:24:49 +0530
Subject: [PATCH 0/3] arm64: ti: k3-am62a: Add display support
Message-ID: <20240201125452.1920623-1-a-bhatia1@ti.com>

Hi,

This patch series adds DT nodes for Display SubSystem (DSS) and other
peripherals required to enable the HDMI audio and video on the
AM62A7-SK EVM. An HDMI monitor can be connected to the platform for the
audio-video outputs.

Regards
Aradhya

Aradhya Bhatia (3):
  arm64: dts: ti: k3-am62a-main: Add node for Display SubSystem (DSS)
  arm64: dts: ti: k3-am62a7-sk: Add HDMI support
  arm64: dts: ti: Makefile: Add HDMI audio for AM62A7-SK

 arch/arm64/boot/dts/ti/Makefile           |  2 +
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 25 ++++++
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts   | 92 +++++++++++++++++++++++
 3 files changed, 119 insertions(+)


base-commit: 51b70ff55ed88edd19b080a524063446bcc34b62
-- 
2.34.1



From a-bhatia1 at ti.com  Thu Feb  1 04:54:51 2024
From: a-bhatia1 at ti.com (Aradhya Bhatia)
Date: Thu, 1 Feb 2024 18:24:51 +0530
Subject: [PATCH 2/3] arm64: dts: ti: k3-am62a7-sk: Add HDMI support
In-Reply-To: <20240201125452.1920623-1-a-bhatia1@ti.com>
References: <20240201125452.1920623-1-a-bhatia1@ti.com>
Message-ID: <20240201125452.1920623-3-a-bhatia1@ti.com>

The DSS outputs DPI signals via its second video port (VP2). The DPI
output from DSS is 24 bits (RGB888) and is forwarded to an HDMI
transmitter (SIL9022) on the board.

Add pinmux info for DSS DPI output.

Add DT nodes for SIL9022 HDMI transmitter (TX), and the HDMI connector
on the AM62A7-SK platforms.

Additionally, connect the output of DSS (VP2) with input of the HDMI TX,
and the output of HDMI TX to the input of the HDMI connector.

Signed-off-by: Aradhya Bhatia <a-bhatia1 at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts | 92 +++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index 7b7142586295..c9eb2a9aef39 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -132,6 +132,18 @@ tlv320_mclk: clk-0 {
 		clock-frequency = <12288000>;
 	};
 
+	hdmi0: connector-hdmi {
+		compatible = "hdmi-connector";
+		label = "hdmi";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&sii9022_out>;
+			};
+		};
+	};
+
 	codec_audio: sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,name = "AM62Ax-SKEVM";
@@ -181,6 +193,39 @@ &wkup_uart0 {
 };
 
 &main_pmx0 {
+	main_dss0_pins_default: main-dss0-default-pins {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x100, PIN_OUTPUT, 0) /* (V17) VOUT0_VSYNC */
+			AM62AX_IOPAD(0x0f8, PIN_OUTPUT, 0) /* (T18) VOUT0_HSYNC */
+			AM62AX_IOPAD(0x104, PIN_OUTPUT, 0) /* (AA22) VOUT0_PCLK */
+			AM62AX_IOPAD(0x0fc, PIN_OUTPUT, 0) /* (U17) VOUT0_DE */
+			AM62AX_IOPAD(0x0b8, PIN_OUTPUT, 0) /* (U22) VOUT0_DATA0 */
+			AM62AX_IOPAD(0x0bc, PIN_OUTPUT, 0) /* (U21) VOUT0_DATA1 */
+			AM62AX_IOPAD(0x0c0, PIN_OUTPUT, 0) /* (U20) VOUT0_DATA2 */
+			AM62AX_IOPAD(0x0c4, PIN_OUTPUT, 0) /* (U19) VOUT0_DATA3 */
+			AM62AX_IOPAD(0x0c8, PIN_OUTPUT, 0) /* (T19) VOUT0_DATA4 */
+			AM62AX_IOPAD(0x0cc, PIN_OUTPUT, 0) /* (U18) VOUT0_DATA5 */
+			AM62AX_IOPAD(0x0d0, PIN_OUTPUT, 0) /* (V22) VOUT0_DATA6 */
+			AM62AX_IOPAD(0x0d4, PIN_OUTPUT, 0) /* (V21) VOUT0_DATA7 */
+			AM62AX_IOPAD(0x0d8, PIN_OUTPUT, 0) /* (V19) VOUT0_DATA8 */
+			AM62AX_IOPAD(0x0dc, PIN_OUTPUT, 0) /* (V18) VOUT0_DATA9 */
+			AM62AX_IOPAD(0x0e0, PIN_OUTPUT, 0) /* (W22) VOUT0_DATA10 */
+			AM62AX_IOPAD(0x0e4, PIN_OUTPUT, 0) /* (W21) VOUT0_DATA11 */
+			AM62AX_IOPAD(0x0e8, PIN_OUTPUT, 0) /* (W20) VOUT0_DATA12 */
+			AM62AX_IOPAD(0x0ec, PIN_OUTPUT, 0) /* (W19) VOUT0_DATA13 */
+			AM62AX_IOPAD(0x0f0, PIN_OUTPUT, 0) /* (Y21) VOUT0_DATA14 */
+			AM62AX_IOPAD(0x0f4, PIN_OUTPUT, 0) /* (Y22) VOUT0_DATA15 */
+			AM62AX_IOPAD(0x05c, PIN_OUTPUT, 1) /* (P22) GPMC0_AD8.VOUT0_DATA16 */
+			AM62AX_IOPAD(0x060, PIN_OUTPUT, 1) /* (R19) GPMC0_AD9.VOUT0_DATA17 */
+			AM62AX_IOPAD(0x064, PIN_OUTPUT, 1) /* (R20) GPMC0_AD10.VOUT0_DATA18 */
+			AM62AX_IOPAD(0x068, PIN_OUTPUT, 1) /* (R22) GPMC0_AD11.VOUT0_DATA19 */
+			AM62AX_IOPAD(0x06c, PIN_OUTPUT, 1) /* (T22) GPMC0_AD12.VOUT0_DATA20 */
+			AM62AX_IOPAD(0x070, PIN_OUTPUT, 1) /* (R21) GPMC0_AD13.VOUT0_DATA21 */
+			AM62AX_IOPAD(0x074, PIN_OUTPUT, 1) /* (T20) GPMC0_AD14.VOUT0_DATA22 */
+			AM62AX_IOPAD(0x078, PIN_OUTPUT, 1) /* (T21) GPMC0_AD15.VOUT0_DATA23 */
+		>;
+	};
+
 	main_uart0_pins_default: main-uart0-default-pins {
 		pinctrl-single,pins = <
 			AM62AX_IOPAD(0x1c8, PIN_INPUT, 0) /* (E14) UART0_RXD */
@@ -466,6 +511,36 @@ exp2: gpio at 23 {
 				  "CSI_EN", "AUTO_100M_1000M_CONFIG",
 				  "CSI_VLDO_SEL", "SoC_WLAN_SDIO_RST";
 	};
+
+	sii9022: bridge-hdmi at 3b {
+		compatible = "sil,sii9022";
+		reg = <0x3b>;
+		interrupt-parent = <&exp1>;
+		interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
+		#sound-dai-cells = <0>;
+		sil,i2s-data-lanes = < 0 >;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				sii9022_in: endpoint {
+					remote-endpoint = <&dpi1_out>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				sii9022_out: endpoint {
+					remote-endpoint = <&hdmi_connector_in>;
+				};
+			};
+		};
+	};
 };
 
 &main_i2c2 {
@@ -583,3 +658,20 @@ &mcasp1 {
 	tx-num-evt = <32>;
 	rx-num-evt = <32>;
 };
+
+&dss {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_dss0_pins_default>;
+};
+
+&dss_ports {
+	/* VP2: DPI Output */
+	port at 1 {
+		reg = <1>;
+
+		dpi1_out: endpoint {
+			remote-endpoint = <&sii9022_in>;
+		};
+	};
+};
-- 
2.34.1



From a-bhatia1 at ti.com  Thu Feb  1 04:54:52 2024
From: a-bhatia1 at ti.com (Aradhya Bhatia)
Date: Thu, 1 Feb 2024 18:24:52 +0530
Subject: [PATCH 3/3] arm64: dts: ti: Makefile: Add HDMI audio check for AM62A7-SK
In-Reply-To: <20240201125452.1920623-1-a-bhatia1@ti.com>
References: <20240201125452.1920623-1-a-bhatia1@ti.com>
Message-ID: <20240201125452.1920623-4-a-bhatia1@ti.com>

HDMI audio can be enabled over AM62A-SK using the same DT overlay that
is used for AM625 / AM62-LP SK-EVMs.

Add the sk.dtb + hdmi-audio.dtbo combination for AM62A7-SK as well, to
check for overlay applicability during DTBS compile tests.

Signed-off-by: Aradhya Bhatia <a-bhatia1 at ti.com>
---
 arch/arm64/boot/dts/ti/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..a0304fcd6b5e 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -101,6 +101,7 @@ k3-am62a7-sk-csi2-ov5640-dtbs := k3-am62a7-sk.dtb \
 	k3-am62x-sk-csi2-ov5640.dtbo
 k3-am62a7-sk-csi2-tevi-ov5640-dtbs := k3-am62a7-sk.dtb \
 	k3-am62x-sk-csi2-tevi-ov5640.dtbo
+k3-am62a7-sk-hdmi-audio-dtbs := k3-am62a7-sk.dtb k3-am62x-sk-hdmi-audio.dtbo
 k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
@@ -118,6 +119,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am62-lp-sk-hdmi-audio.dtb \
 	k3-am62a7-sk-csi2-imx219.dtb \
 	k3-am62a7-sk-csi2-ov5640.dtb \
+	k3-am62a7-sk-hdmi-audio.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
 	k3-j721e-evm-pcie0-ep.dtb \
-- 
2.34.1



From jgg at nvidia.com  Thu Feb  1 05:02:42 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 1 Feb 2024 09:02:42 -0400
Subject: [PATCH v4 02/16] iommu/arm-smmu-v3: Consolidate the STE
 generation for abort/bypass
In-Reply-To: <ZbuBWQNEDqlFAoFi@google.com>
References: <0-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <2-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <Zbpb2JSgnRuHGIo-@google.com>
 <20240131144702.GJ1455070@nvidia.com>
 <ZbuBWQNEDqlFAoFi@google.com>
Message-ID: <20240201130242.GO1455070@nvidia.com>

On Thu, Feb 01, 2024 at 11:32:41AM +0000, Mostafa Saleh wrote:
> On Wed, Jan 31, 2024 at 10:47:02AM -0400, Jason Gunthorpe wrote:
> > On Wed, Jan 31, 2024 at 02:40:24PM +0000, Mostafa Saleh wrote:
> > > > +static void arm_smmu_make_bypass_ste(struct arm_smmu_ste *target)
> > > > +{
> > > > +	memset(target, 0, sizeof(*target));
> > > 
> > > I see this can be used with the actual STE. Although this is done at init, but
> > > briefly making the STE abort from ?arm_smmu_make_bypass_ste?, seems a bit
> > > fragile to me, in case we use this in the future in different scenarios, it
> > > might break the hitless assumption. But no strong opinion though.
> > 
> > At init time, when that case happens, the STE table hasn't been
> > installed in the HW yet. This is why that specific code path has been
> > directly manipulating the STE and does not call the normal update path
> > with the sync'ing.
> > 
> > It is perhaps subtle that is why it is a different flow.
> > 
> > (this is also why I moved the function order as it was a bit obscure
> > to see that indeed all this stuff was sequenced right and we were not
> > updating a live STE improperly)
> 
> I agree, this is not an issue, but it was just confusing when I first read it
> as ?arm_smmu_make_bypass_ste? would make the STE transiently unavailable, and
> I had to go and check the usage. Maybe we can add a comment to clarify how this
> function is expected to be used.

I added this remark:

@@ -1592,6 +1592,10 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
        arm_smmu_write_ste(master, sid, dst, &target);
 }
 
+/*
+ * This can safely directly manipulate the STE memory without a sync sequence
+ * because the STE table has not been installed in the SMMU yet.
+ */
 static void arm_smmu_init_bypass_stes(struct arm_smmu_ste *strtab,
                                      unsigned int nent)
 {
@@ -3971,6 +3975,10 @@ static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
                                continue;
                        }
 
+                       /*
+                        * STE table is not programmed to HW, see
+                        * arm_smmu_init_bypass_stes()
+                        */
                        arm_smmu_make_bypass_ste(
                                arm_smmu_get_step_for_sid(smmu, rmr->sids[i]));
                }

Jason


From j-luthra at ti.com  Thu Feb  1 05:06:59 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 1 Feb 2024 18:36:59 +0530
Subject: [PATCH 0/4] arm64: dts: ti: Enable camera for SK-AM62P
Message-ID: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>

This series enables support for camera sensors using CSI-RX ports on
AM62P family of SoCs.

Particularly, it enables OV5640 and IMX219 sensors via the 22-pin FFC
CSI-RX connector on SK-AM62P [1] using the existing common overlays for
SK-AM62* family of boards.

Capture test:
https://gist.github.com/jailuthra/11f3383ccc0902b9db90d806222597a3

[1]: https://www.ti.com/tool/SK-AM62P-LP

Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
Jai Luthra (4):
      arm64: dts: ti: k3-am62p: Fix memory ranges for DMSS
      arm64: dts: ti: k3-am62p: Add DMASS1 for CSI
      arm64: dts: ti: k3-am62p: Add nodes for CSI-RX
      arm64: dts: ti: Enable overlays for SK-AM62P

 arch/arm64/boot/dts/ti/Makefile           | 10 ++++
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 98 +++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am62p.dtsi      |  2 +-
 3 files changed, 109 insertions(+), 1 deletion(-)
---
base-commit: ef7bf0ae92cdee584950f74f364338c28f549cc7
change-id: 20240201-am62p_csi-b69d172406ca

Best regards,
-- 
Jai Luthra <j-luthra at ti.com>



From j-luthra at ti.com  Thu Feb  1 05:07:00 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 1 Feb 2024 18:37:00 +0530
Subject: [PATCH 1/4] arm64: dts: ti: k3-am62p: Fix memory ranges for DMSS
In-Reply-To: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
References: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
Message-ID: <20240201-am62p_csi-v1-1-c83bb9eaeb49@ti.com>

The INTR module for DMASS1 (CSI specific DMASS) is outside the currently
available ranges, as it starts at 0x4e400000. So fix the ranges property
to enable programming the interrupts correctly.

Fixes: 29075cc09f43 ("arm64: dts: ti: Introduce AM62P5 family of SoCs")
Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
index 84ffe7b9dcaf..4f22b5d9fb9f 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
@@ -71,7 +71,7 @@ cbass_main: bus at f0000 {
 			 <0x00 0x43600000 0x00 0x43600000 0x00 0x00010000>, /* SA3 sproxy data */
 			 <0x00 0x44043000 0x00 0x44043000 0x00 0x00000fe0>, /* TI SCI DEBUG */
 			 <0x00 0x44860000 0x00 0x44860000 0x00 0x00040000>, /* SA3 sproxy config */
-			 <0x00 0x48000000 0x00 0x48000000 0x00 0x06400000>, /* DMSS */
+			 <0x00 0x48000000 0x00 0x48000000 0x00 0x06408000>, /* DMSS */
 			 <0x00 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS0 DAT1 */
 			 <0x00 0x70000000 0x00 0x70000000 0x00 0x00010000>, /* OCSRAM */
 			 <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */

-- 
2.43.0



From j-luthra at ti.com  Thu Feb  1 05:07:01 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 1 Feb 2024 18:37:01 +0530
Subject: [PATCH 2/4] arm64: dts: ti: k3-am62p: Add DMASS1 for CSI
In-Reply-To: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
References: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
Message-ID: <20240201-am62p_csi-v1-2-c83bb9eaeb49@ti.com>

On AM62P, CSI-RX uses a dedicated BCDMA instance (DMASS1) for
transferring captured camera frames to DDR, so enable it.

Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 37 +++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 4c51bae06b57..57ec4ef334e4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -158,6 +158,43 @@ main_pktdma: dma-controller at 485c0000 {
 		};
 	};
 
+	dmss_csi: bus at 4e000000 {
+		compatible = "simple-bus";
+		ranges = <0x00 0x4e000000 0x00 0x4e000000 0x00 0x408000>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dma-ranges;
+		ti,sci-dev-id = <198>;
+
+		inta_main_dmss_csi: interrupt-controller at 4e400000 {
+			compatible = "ti,sci-inta";
+			reg = <0x00 0x4e400000 0x00 0x8000>;
+			#interrupt-cells = <0>;
+			interrupt-controller;
+			interrupt-parent = <&gic500>;
+			msi-controller;
+			power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+			ti,sci = <&dmsc>;
+			ti,sci-dev-id = <200>;
+			ti,interrupt-ranges = <0 237 8>;
+			ti,unmapped-event-sources = <&main_bcdma_csi>;
+		};
+
+		main_bcdma_csi: dma-controller at 4e230000 {
+			compatible = "ti,am62a-dmss-bcdma-csirx";
+			reg = <0x00 0x4e230000 0x00 0x100>,
+			      <0x00 0x4e180000 0x00 0x8000>,
+			      <0x00 0x4e100000 0x00 0x10000>;
+			reg-names = "gcfg", "rchanrt", "ringrt";
+			#dma-cells = <3>;
+			msi-parent = <&inta_main_dmss_csi>;
+			power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+			ti,sci = <&dmsc>;
+			ti,sci-dev-id = <199>;
+			ti,sci-rm-range-rchan = <0x21>;
+		};
+	};
+
 	dmsc: system-controller at 44043000 {
 		compatible = "ti,k2g-sci";
 		ti,host-id = <12>;

-- 
2.43.0



From j-luthra at ti.com  Thu Feb  1 05:07:03 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 1 Feb 2024 18:37:03 +0530
Subject: [PATCH 4/4] arm64: dts: ti: Enable overlays for SK-AM62P
In-Reply-To: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
References: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
Message-ID: <20240201-am62p_csi-v1-4-c83bb9eaeb49@ti.com>

Enable symbols so that overlays can be applied on the base DTB for
SK-AM62P.

Also compile-test known-to-work camera sensor overlays for OV5640 and
IMX219.

Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
 arch/arm64/boot/dts/ti/Makefile | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..80733ed747a2 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -101,6 +101,12 @@ k3-am62a7-sk-csi2-ov5640-dtbs := k3-am62a7-sk.dtb \
 	k3-am62x-sk-csi2-ov5640.dtbo
 k3-am62a7-sk-csi2-tevi-ov5640-dtbs := k3-am62a7-sk.dtb \
 	k3-am62x-sk-csi2-tevi-ov5640.dtbo
+k3-am62p5-sk-csi2-imx219-dtbs := k3-am62p5-sk.dtb \
+	k3-am62x-sk-csi2-imx219.dtbo
+k3-am62p5-sk-csi2-ov5640-dtbs := k3-am62p5-sk.dtb \
+	k3-am62x-sk-csi2-ov5640.dtbo
+k3-am62p5-sk-csi2-tevi-ov5640-dtbs := k3-am62p5-sk.dtb \
+	k3-am62x-sk-csi2-tevi-ov5640.dtbo
 k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
@@ -118,6 +124,9 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am62-lp-sk-hdmi-audio.dtb \
 	k3-am62a7-sk-csi2-imx219.dtb \
 	k3-am62a7-sk-csi2-ov5640.dtb \
+	k3-am62p5-sk-csi2-imx219.dtb \
+	k3-am62p5-sk-csi2-ov5640.dtb \
+	k3-am62p5-sk-csi2-tevi-ov5640.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
 	k3-j721e-evm-pcie0-ep.dtb \
@@ -128,6 +137,7 @@ DTC_FLAGS_k3-am625-beagleplay += -@
 DTC_FLAGS_k3-am625-sk += -@
 DTC_FLAGS_k3-am62-lp-sk += -@
 DTC_FLAGS_k3-am62a7-sk += -@
+DTC_FLAGS_k3-am62p5-sk += -@
 DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
 DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
 DTC_FLAGS_k3-j721e-common-proc-board += -@

-- 
2.43.0



From j-luthra at ti.com  Thu Feb  1 05:07:02 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 1 Feb 2024 18:37:02 +0530
Subject: [PATCH 3/4] arm64: dts: ti: k3-am62p: Add nodes for CSI-RX
In-Reply-To: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
References: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
Message-ID: <20240201-am62p_csi-v1-3-c83bb9eaeb49@ti.com>

AM62P supports image capture via the MIPI CSI-2 protocol, it uses three
IPs to achieve this: Cadence DPHY, Cadence CSI-RX, and TI's pixelgrabber
wrapper on top. Enable all of these IPs in the devicetree.

Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 61 +++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 57ec4ef334e4..fdd835a04327 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -928,4 +928,65 @@ mcasp2: audio-controller at 2b20000 {
 		power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 	};
+
+	ti_csi2rx0: ticsi2rx at 30102000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x30102000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x5000 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 30101000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x30101000 0x00 0x1000>;
+			clocks = <&k3_clks 182 0>, <&k3_clks 182 3>, <&k3_clks 182 0>,
+				<&k3_clks 182 0>, <&k3_clks 182 4>, <&k3_clks 182 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 30110000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x30110000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
 };

-- 
2.43.0



From conor.dooley at microchip.com  Thu Feb  1 05:11:39 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Thu, 1 Feb 2024 13:11:39 +0000
Subject: Aw: Re: [PATCH v3 1/2] dt-bindings: reset: mediatek: add MT7988
 reset IDs
In-Reply-To: <0EA6A126-DDC0-4E9F-BEBC-FD018B08CA84@public-files.de>
References: <20240117184111.62371-1-linux@fw-web.de>
 <20240117184111.62371-2-linux@fw-web.de>
 <20240118-calcium-krypton-3c787b8d1912@spud>
 <trinity-afc4f48e-65e1-46ee-a78b-1d670cc0f310-1705615200900@3c-app-gmx-bap21>
 <43f946cc-07e1-48c5-9b31-40fc9bc93037@collabora.com>
 <20240119-dupe-obligate-707b3a01b356@spud>
 <0EA6A126-DDC0-4E9F-BEBC-FD018B08CA84@public-files.de>
Message-ID: <20240201-goes-passable-0ba841d36bc3@wendy>

On Thu, Feb 01, 2024 at 12:40:17PM +0100, Frank Wunderlich wrote:
> Am 19. Januar 2024 18:04:36 MEZ schrieb Conor Dooley <conor at kernel.org>:
> >On Fri, Jan 19, 2024 at 10:28:30AM +0100, AngeloGioacchino Del Regno wrote:
> >>
> >> The resets are organized on a per-reset-controller basis, so, the ETHWARP
> >> reset controller's first reset is RST_SWITCH, the second one is RST_something_else,
> >> etc. while the first reset of the INFRA reset controller is PEXTP_MAC_SWRST.
> >> 
> >> That's why ETHWARP has a reset index 0 and INFRA also starts at 0.
> >> I think that the numbering is good as it is, and having one driver start at index 5
> >> while the other starts at index 12 would only overcomplicate registering the resets
> >> in each driver, or waste bytes by making unnecessarily large arrays, for (imo) no
> >> good reason.
> >> 
> >> This is one header, but it should "in theory" be more than one... so we would have
> >> one for each hardware block - but that'd make the reset directory over-crowded, as
> >> other MediaTek SoCs have got even more resets in even more hardware blocks than the
> >> MT7988. That'd be something like ~4 reset headers per SoC (and will increase with
> >> newer ones)...
> >> ...and this is why we have one binding header for resets.
> >
> >That's okay. The commit message leaves me, who clearly isn't a mediatek
> >guy, with no information as to why these are not one contiguous set.
> >IMO being for different reset controllers entirely is fine.
> >
> >> On the topic of leaving space to allow grouping RST0/RST1: -> No. <-
> >> The indices have to start from zero and have to be sequential, with no holes.
> >
> >Agreed.
> 
> Hi,
> 
> Just a friendly reminder.
> 
> As far as i understood, Patches are fine so far and do not need any rework,right?

I suspect I was asking for a commit message that explains why these
numbers don't continue in sequence. With that,
Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> 
> But i have not seen them picked up yet in linux-next.
> regards Frank
-------------- 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/20240201/14761e61/attachment-0001.sig>

From lkp at intel.com  Thu Feb  1 05:15:27 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 01 Feb 2024 21:15:27 +0800
Subject: [soc:for-next] BUILD SUCCESS
 de4b6d6705a75de2c277e123ac30d13f4292771b
Message-ID: <202402012125.n89QoDHN-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: de4b6d6705a75de2c277e123ac30d13f4292771b  Merge branch 'soc/defconfig' into for-next

elapsed time: 867m

configs tested: 126
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                            hsdk_defconfig   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   gcc  
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
i386                             allmodconfig   clang
i386                              allnoconfig   clang
i386                             allyesconfig   clang
i386                                defconfig   gcc  
i386                  randconfig-011-20240201   clang
i386                  randconfig-012-20240201   clang
i386                  randconfig-013-20240201   clang
i386                  randconfig-014-20240201   clang
i386                  randconfig-015-20240201   clang
i386                  randconfig-016-20240201   clang
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                        allyesconfig   gcc  
loongarch                           defconfig   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
microblaze                      mmu_defconfig   gcc  
mips                             allmodconfig   gcc  
mips                              allnoconfig   clang
mips                             allyesconfig   gcc  
nios2                         10m50_defconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
openrisc                         allmodconfig   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc                      arches_defconfig   gcc  
powerpc                   currituck_defconfig   gcc  
powerpc                    ge_imp3a_defconfig   gcc  
powerpc                     ksi8560_defconfig   gcc  
powerpc                      ppc40x_defconfig   gcc  
powerpc                  storcenter_defconfig   gcc  
powerpc                        warp_defconfig   gcc  
riscv                            allmodconfig   clang
riscv                            allmodconfig   gcc  
riscv                             allnoconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                            allyesconfig   gcc  
riscv                               defconfig   gcc  
s390                             allmodconfig   clang
s390                             allmodconfig   gcc  
s390                              allnoconfig   gcc  
s390                             allyesconfig   gcc  
s390                                defconfig   gcc  
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                          polaris_defconfig   gcc  
sh                          r7785rp_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                            allyesconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                                allnoconfig   gcc  
um                               allyesconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   gcc  
um                             i386_defconfig   gcc  
um                           x86_64_defconfig   gcc  
x86_64                            allnoconfig   clang
x86_64                            allnoconfig   gcc  
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240201   gcc  
x86_64       buildonly-randconfig-002-20240201   gcc  
x86_64       buildonly-randconfig-003-20240201   gcc  
x86_64       buildonly-randconfig-004-20240201   gcc  
x86_64       buildonly-randconfig-005-20240201   gcc  
x86_64       buildonly-randconfig-006-20240201   gcc  
x86_64                              defconfig   clang
x86_64                              defconfig   gcc  
x86_64                                  kexec   clang
x86_64                                  kexec   gcc  
x86_64                randconfig-011-20240201   gcc  
x86_64                randconfig-012-20240201   gcc  
x86_64                randconfig-013-20240201   gcc  
x86_64                randconfig-014-20240201   gcc  
x86_64                randconfig-015-20240201   gcc  
x86_64                randconfig-016-20240201   gcc  
x86_64                randconfig-071-20240201   gcc  
x86_64                randconfig-072-20240201   gcc  
x86_64                randconfig-073-20240201   gcc  
x86_64                randconfig-074-20240201   gcc  
x86_64                randconfig-075-20240201   gcc  
x86_64                randconfig-076-20240201   gcc  
x86_64                          rhel-8.3-rust   clang
x86_64                               rhel-8.3   clang
x86_64                               rhel-8.3   gcc  
xtensa                            allnoconfig   gcc  
xtensa                           allyesconfig   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From linux at armlinux.org.uk  Thu Feb  1 05:16:06 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 1 Feb 2024 13:16:06 +0000
Subject: [PATCH RESEND] arm: topology: Fix missing clock-frequency
 property warning
In-Reply-To: <20240201123605.3037829-2-stefan.wiehler@nokia.com>
References: <20240201123605.3037829-2-stefan.wiehler@nokia.com>
Message-ID: <ZbuZlok+8ZkxGBq7@shell.armlinux.org.uk>

Sorry, I was going to reply to this, but having composed the reply,
and attempting to add the DT maintainers, mutt decided to completely
obliterate the To: line.

Please check with the DT maintainers what the expected behaviour is
supposed to be.

On Thu, Feb 01, 2024 at 01:36:06PM +0100, Stefan Wiehler wrote:
> The devicetree specification in section 3.8 however specifies that
> "properties that have identical values across cpu nodes may be placed in
> the /cpus node instead.

Does this mean the /cpus property is like a default for when a CPU node
doesn't specify the clock frequency, or does it mean that the /cpus
property should only exist when all the values for each CPU are
identical and thus the individual CPU node clock frequency should
not be specified.

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


From krzysztof.kozlowski at linaro.org  Thu Feb  1 05:16:35 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 1 Feb 2024 14:16:35 +0100
Subject: [PATCH RESEND] arm: topology: Fix missing clock-frequency
 property warning
In-Reply-To: <20240201123605.3037829-2-stefan.wiehler@nokia.com>
References: <20240201123605.3037829-2-stefan.wiehler@nokia.com>
Message-ID: <dfccb849-67b6-489b-8e83-3df1f9b29877@linaro.org>

On 01/02/2024 13:36, Stefan Wiehler wrote:
> If the clock-frequency property is not set in the cpu node but in the
> parent /cpus node, the following warning is emitted:
> 
>   /cpus/cpu at X missing clock-frequency property
> 
> The devicetree specification in section 3.8 however specifies that
> "properties that have identical values across cpu nodes may be placed in
> the /cpus node instead.  A client program must first examine a specific cpu
> node, but if an expected property is not found then it should look at the
> parent /cpus node."
> 
> Signed-off-by: Stefan Wiehler <stefan.wiehler at nokia.com>
> ---
>  arch/arm/kernel/topology.c | 21 ++++++++++++++++++---
>  1 file changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
> index ef0058de432b..32fc1c8d9d11 100644
> --- a/arch/arm/kernel/topology.c
> +++ b/arch/arm/kernel/topology.c
> @@ -85,15 +85,24 @@ static bool cap_from_dt = true;
>  static void __init parse_dt_topology(void)
>  {
>  	const struct cpu_efficiency *cpu_eff;
> -	struct device_node *cn = NULL;
> +	struct device_node *pcn = NULL, *cn = NULL;
>  	unsigned long min_capacity = ULONG_MAX;
>  	unsigned long max_capacity = 0;
>  	unsigned long capacity = 0;
>  	int cpu = 0;
> +	const __be32 *common_rate;
> +	int common_rate_len;
>  
>  	__cpu_capacity = kcalloc(nr_cpu_ids, sizeof(*__cpu_capacity),
>  				 GFP_NOWAIT);
>  
> +	pcn = of_find_node_by_path("/cpus");
> +	if (!pcn) {
> +		pr_err("missing CPU root device node\n");
> +		return;
> +	}
> +	common_rate = of_get_property(pcn, "clock-frequency", &common_rate_len);

Aren't you adding new property? Is it already documented in the
bindings? After a quick look I think this is not documented.

Best regards,
Krzysztof



From jgg at nvidia.com  Thu Feb  1 05:24:43 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 1 Feb 2024 09:24:43 -0400
Subject: [PATCH v4 06/16] iommu/arm-smmu-v3: Hold arm_smmu_asid_lock
 during all of attach_dev
In-Reply-To: <ZbuLeWDvhhufT7Pa@google.com>
References: <0-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <6-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZbuLeWDvhhufT7Pa@google.com>
Message-ID: <20240201132443.GP1455070@nvidia.com>

On Thu, Feb 01, 2024 at 12:15:53PM +0000, Mostafa Saleh wrote:
> Hi Jason,
> 
> On Thu, Jan 25, 2024 at 07:57:16PM -0400, Jason Gunthorpe wrote:
> > The BTM support wants to be able to change the ASID of any smmu_domain.
> > When it goes to do this it holds the arm_smmu_asid_lock and iterates over
> > the target domain's devices list.
> > 
> > During attach of a S1 domain we must ensure that the devices list and
> > CD are in sync, otherwise we could miss CD updates or a parallel CD update
> > could push an out of date CD.
> > 
> > This is pretty complicated, and almost works today because
> > arm_smmu_detach_dev() removes the master from the linked list before
> > working on the CD entries, preventing parallel update of the CD.
> > 
> > However, it does have an issue where the CD can remain programed while the
> > domain appears to be unattached. arm_smmu_share_asid() will then not clear
> > any CD entriess and install its own CD entry with the same ASID
> > concurrently. This creates a small race window where the IOMMU can see two
> > ASIDs pointing to different translations.
> 
> I don?t see the race condition.
> 
> The current flow is as follows,
> For SVA, if the asid was used by domain_x, it will do:
> 
> lock(arm_smmu_asid_lock)
> Alloc new asid and set cd->asid.
> lock(domain_x->devices_lock)
> Write new CD with the new asid
> unlock(domain_x->devices_lock)
> unlock(arm_smmu_asid_lock)
> 
> For attach_dev (domain_y), if the device was attached to domain_z
> //Detach old domain
> lock(domain_z->devices_lock)
> Remove master from old domain
> unlock(domain_z->devices_lock)

At this moment all locks are dropped and the RID's CD entry continues
to use the ASID.

The racing BTM flow now runs and will do your above:

arm_smmu_mmu_notifier_get()
 arm_smmu_alloc_shared_cd()
  arm_smmu_share_asid():
    arm_smmu_update_ctx_desc_devices() <<- Does nothing due to list_del above
    arm_smmu_tlb_inv_asid() <<-- Woops, we are invalidating an ASID that is still in a CD!
 arm_smmu_write_ctx_desc() <<-- Install a new translation on a PASID's CD

Now the HW can observe two installed CDs using the same ASID but they
point to different translations. This is illegal.

> Clear CD

Now we remove the RID CD, but it is too late, the PASID CD is already
installed.

ASID/VMID lifecycle must be strictly contained to ensure the cache
remains coherent:

1. All programmed STE/CDs using the ASID/VMID must always point to the
   same translation

2. All references to a ASID/VMID must be removed from their STE/CDs
   before the ASID is flushed

3. The ASID/VMID must be flushed before it is assigned to a STE/CD
   with a new translation.

We solve this by requiring that the arm_smmu_asid_lock must be held
such that the smmu_domains->devices list AND the actual content of the
CD tables are always observed to be consistent.

Jason


From rsc at runtux.com  Thu Feb  1 05:15:40 2024
From: rsc at runtux.com (Ralf Schlatterbeck)
Date: Thu, 1 Feb 2024 14:15:40 +0100
Subject: [PATCH 1/1] spi-mxs: Fix chipselect glitch
Message-ID: <20240201131540.3dlqoxlrrbzshz7w@runtux.com>

There was a change in the mxs-dma engine that uses a new custom flag.
The change was not applied to the mxs spi driver.
This results in chipselect being deasserted too early.
This fixes the chipselect problem by using the new flag in the mxs-spi
driver.

Fixes: ceeeb99cd821 ("dmaengine: mxs: rename custom flag")
Signed-off-by: Ralf Schlatterbeck <rsc at runtux.com>
---
For oscilloscope screenshots and a verbose explanation see my blog post
at https://blog.runtux.com/posts/2024/02/01/

 drivers/spi/spi-mxs.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index 1bf080339b5a..a296050c8bd3 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -39,6 +39,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/mxs-spi.h>
 #include <trace/events/spi.h>
+#include <linux/dma/mxs-dma.h>
 
 #define DRIVER_NAME		"mxs-spi"
 
@@ -251,8 +252,9 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
 
 		desc = dmaengine_prep_slave_sg(ssp->dmach,
 				&dma_xfer[sg_count].sg, 1,
-				(flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
-				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+				(flags & TXRX_WRITE)
+				? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
+				DMA_PREP_INTERRUPT | MXS_DMA_CTRL_WAIT4END);
 
 		if (!desc) {
 			dev_err(ssp->dev,
-- 
2.20.1

-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   www.runtux.com
Reichergasse 131, A-3411 Weidling       email: office at runtux.com


From u.kleine-koenig at pengutronix.de  Thu Feb  1 05:38:19 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Thu, 1 Feb 2024 14:38:19 +0100
Subject: [PATCH] pwm: imx-tpm: reset module on probe
In-Reply-To: <20240201122242.1597601-1-viorel.suman@oss.nxp.com>
References: <20240201122242.1597601-1-viorel.suman@oss.nxp.com>
Message-ID: <vvldfzpthexjb7bir5imrdslgnnqztl2rdclfp6qiesj6hgiea@o53kcxs66mjr>

Hello,

On Thu, Feb 01, 2024 at 02:22:42PM +0200, Viorel Suman (OSS) wrote:
> From: Viorel Suman <viorel.suman at nxp.com>
> 
> Reset Timer PWM module on probe so that the module
> takes the default state after probe is finished.
> 
> Signed-off-by: Viorel Suman <viorel.suman at nxp.com>
> Signed-off-by: Florin Leotescu <florin.leotescu at nxp.com>

The order of Signed-off-lines is supposed to be in the order that people
touched the patch during submission. So your S-o-b line should be last
and it should ideally use the email address you use for sending out the
patch.

> ---
>  drivers/pwm/pwm-imx-tpm.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c
> index 9fc290e647e1..27e6a5342693 100644
> --- a/drivers/pwm/pwm-imx-tpm.c
> +++ b/drivers/pwm/pwm-imx-tpm.c
> @@ -33,6 +33,7 @@
>  #define PWM_IMX_TPM_CnV(n)	(0x24 + (n) * 0x8)
>  
>  #define PWM_IMX_TPM_PARAM_CHAN			GENMASK(7, 0)
> +#define PWM_IMX_TPM_GLOBAL_RST			BIT(1)
>  
>  #define PWM_IMX_TPM_SC_PS			GENMASK(2, 0)
>  #define PWM_IMX_TPM_SC_CMOD			GENMASK(4, 3)
> @@ -362,6 +363,10 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
>  	val = readl(tpm->base + PWM_IMX_TPM_PARAM);
>  	tpm->chip.npwm = FIELD_GET(PWM_IMX_TPM_PARAM_CHAN, val);
>  
> +	/* Resets all internal logic and registers */
> +	writel(PWM_IMX_TPM_GLOBAL_RST, tpm->base + PWM_IMX_TPM_GLOBAL);
> +	writel(0, tpm->base + PWM_IMX_TPM_GLOBAL);
> +

This opposes the use case that the bootloader setup the pwm-backlight to
show a splash screen that is simply taken over by Linux without
flickering, right?

Otherwise the commit log should motivate why "the module takes the
default state" is better than the status quo and what this default state
is.

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/20240201/5314259d/attachment.sig>

From nm at ti.com  Thu Feb  1 05:38:41 2024
From: nm at ti.com (Nishanth Menon)
Date: Thu, 1 Feb 2024 07:38:41 -0600
Subject: [PATCH] MAINTAINERS: drop Sekhar Nori
In-Reply-To: <20240131093434.55652-1-nsekhar@ti.com>
References: <20240131093434.55652-1-nsekhar@ti.com>
Message-ID: <20240201133841.qcerpmyo4xwc7zxu@volatile>

On 15:04-20240131, Sekhar Nori wrote:
> My TI e-mail address will become inactive soon. Drop it.
> Add an entry to CREDITS file for work done on TI DaVinci
> family SoCs.
> 
> Signed-off-by: Sekhar Nori <nsekhar at ti.com>
> ---
>  CREDITS     | 5 +++++
>  MAINTAINERS | 1 -
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/CREDITS b/CREDITS
> index df8d6946739f..11d918e0fb0e 100644
> --- a/CREDITS
> +++ b/CREDITS
> @@ -2955,6 +2955,11 @@ S: 2364 Old Trail Drive
>  S: Reston, Virginia 20191
>  S: USA
>  
> +N: Sekhar Nori
> +E: nori.sekhar at gmail.com
> +D: Maintainer of Texas Instruments DaVinci machine support, contributor
> +D: to device drivers relevant to that SoC family.
> +
>  N: Fredrik Noring
>  E: noring at nocrew.org
>  W: http://www.lysator.liu.se/~noring/
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c4828ab15f1a..f74ecde541bb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -21945,7 +21945,6 @@ F:	drivers/i2c/busses/i2c-davinci.c
>  
>  TI DAVINCI SERIES CLOCK DRIVER
>  M:	David Lechner <david at lechnology.com>
> -R:	Sekhar Nori <nsekhar at ti.com>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/clock/ti/davinci/
>  F:	drivers/clk/davinci/
> -- 
> 2.17.1

Thank you Sekhar for over 2 decades of consistent upstream focus,
numerous contributions and helping set the essence of working in
upstream @ TI. Wish you the very best ahead.

Acked-by: Nishanth Menon <nm at ti.com>

I am going to assume this is going via Stephen's tree. If there is any
help needed, let me know.
-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From horms at kernel.org  Thu Feb  1 05:44:09 2024
From: horms at kernel.org (Simon Horman)
Date: Thu, 1 Feb 2024 14:44:09 +0100
Subject: [PATCH net v3] net: stmmac: xgmac: fix handling of DPP safety
 error for DMA channels
In-Reply-To: <20240131020828.2007741-1-0x1207@gmail.com>
References: <20240131020828.2007741-1-0x1207@gmail.com>
Message-ID: <20240201134409.GD530335@kernel.org>

On Wed, Jan 31, 2024 at 10:08:28AM +0800, Furong Xu wrote:
> Commit 56e58d6c8a56 ("net: stmmac: Implement Safety Features in
> XGMAC core") checks and reports safety errors, but leaves the
> Data Path Parity Errors for each channel in DMA unhandled at all, lead to
> a storm of interrupt.
> Fix it by checking and clearing the DMA_DPP_Interrupt_Status register.
> 
> Fixes: 56e58d6c8a56 ("net: stmmac: Implement Safety Features in XGMAC core")
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> ---
> Changes in v3:
>  - code style fix, thanks Paolo Abeni
> 
> Changes in v2:
>   - explicit enable Data Path Parity Protection
>   - add new counters to stmmac_safety_stats
>   - add detailed log

Thanks for the updates.

Reviewed-by: Simon Horman <horms at kernel.org>



From maz at kernel.org  Thu Feb  1 05:45:04 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 01 Feb 2024 13:45:04 +0000
Subject: [PATCH 00/10] KVM: arm64: fix many kernel-doc warnings
In-Reply-To: <618cb278-0b9f-4cc2-bfc6-bfcbefc79b69@infradead.org>
References: <20240117230714.31025-1-rdunlap@infradead.org>
	<618cb278-0b9f-4cc2-bfc6-bfcbefc79b69@infradead.org>
Message-ID: <86le8470yn.wl-maz@kernel.org>

On Thu, 01 Feb 2024 06:19:14 +0000,
Randy Dunlap <rdunlap at infradead.org> wrote:
> 
> Hi,
>
> Any comments on this series?

This is currently earmarked for 6.9.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From yuzenghui at huawei.com  Thu Feb  1 05:49:04 2024
From: yuzenghui at huawei.com (Zenghui Yu)
Date: Thu, 1 Feb 2024 21:49:04 +0800
Subject: [PATCH 00/10] KVM: arm64: fix many kernel-doc warnings
In-Reply-To: <20240117230714.31025-1-rdunlap@infradead.org>
References: <20240117230714.31025-1-rdunlap@infradead.org>
Message-ID: <e875f1c6-2e1e-632a-3db0-5a21aa73f20f@huawei.com>

On 2024/1/18 7:07, Randy Dunlap wrote:
> Fix a bunch of kernel-doc warnings in arch/arm64/kvm/.
> 
>  [PATCH 01/10] KVM: arm64: debug: fix kernel-doc warnings
>  [PATCH 02/10] KVM: arm64: guest: fix kernel-doc warnings
>  [PATCH 03/10] KVM: arm64: hyp/aarch32: fix kernel-doc warnings
>  [PATCH 04/10] KVM: arm64: vhe: fix a kernel-doc warning
>  [PATCH 05/10] KVM: arm64: mmu: fix a kernel-doc warning
>  [PATCH 06/10] KVM: arm64: PMU: fix kernel-doc warnings
>  [PATCH 07/10] KVM: arm64: sys_regs: fix kernel-doc warnings
>  [PATCH 08/10] KVM: arm64: vgic-init: fix a kernel-doc warning
>  [PATCH 09/10] KVM: arm64: vgic-its: fix kernel-doc warnings
>  [PATCH 10/10] KVM: arm64: vgic: fix a kernel-doc warning

All look good to me,

Reviewed-by: Zenghui Yu <yuzenghui at huawei.com>

Thanks!


From maz at kernel.org  Thu Feb  1 05:52:29 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 01 Feb 2024 13:52:29 +0000
Subject: [PATCH v3 5/8] ptp/kvm, arm_arch_timer: Set system_counterval_t.cs_id to constant
In-Reply-To: <20240201010453.2212371-6-peter.hilber@opensynergy.com>
References: <20240201010453.2212371-1-peter.hilber@opensynergy.com>
	<20240201010453.2212371-6-peter.hilber@opensynergy.com>
Message-ID: <86jzno70ma.wl-maz@kernel.org>

On Thu, 01 Feb 2024 01:04:50 +0000,
Peter Hilber <peter.hilber at opensynergy.com> wrote:
> 
> Identify the clocksources used by ptp_kvm by setting clocksource ID enum
> constants. This avoids dereferencing struct clocksource. Once the
> system_counterval_t.cs member will be removed, this will also avoid the
> need to obtain clocksource pointers from kvm_arch_ptp_get_crosststamp().
> 
> The clocksource IDs are associated to timestamps requested from the KVM
> hypervisor, so the proper clocksource ID is known at the ptp_kvm request
> site.
> 
> While at it, also rectify the ptp_kvm_get_time_fn() ret type.

Not sure what is wrong with that return type, but this patch doesn't
seem to affect it.

	M.

-- 
Without deviation from the norm, progress is not possible.


From laurent.pinchart at ideasonboard.com  Thu Feb  1 05:52:32 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Thu, 1 Feb 2024 15:52:32 +0200
Subject: [PATCH v6 04/11] media: rkisp1: Support devices lacking dual crop
In-Reply-To: <20240111114831.656736-5-paul.elder@ideasonboard.com>
References: <20240111114831.656736-1-paul.elder@ideasonboard.com>
 <20240111114831.656736-5-paul.elder@ideasonboard.com>
Message-ID: <20240201135232.GB5344@pendragon.ideasonboard.com>

Hi Paul,

Thank you for the patch.

On Thu, Jan 11, 2024 at 08:48:24PM +0900, Paul Elder wrote:
> Some versions of the ISP supported by the rkisp1 driver, such as the ISP
> in the i.MX8MP, lack the dual crop registers and don't support cropping
> at the resizer input. They instead rely on cropping in the Image
> Stabilization module, at the output of the ISP, to modify the resizer
> input size and implement digital zoom.
> 
> Support those ISP versions by addind a dual crop feature flag, and

s/addind/adding/

> mapping the resizer input crop rectangle to either the resizer dual crop
> module or the image stabilization module.

The implementation doesn't match the commit message. You only disable
dual-crop here, you don't handle the image stabilization module. I'm
fine with that, I think adding IS support belongs to a separate patch,
but what this patch is missing is disabling the ability to set a crop
rectangle on the resizer input when dual-crop is not supported.

> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Tested-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
>  drivers/media/platform/rockchip/rkisp1/rkisp1-common.h  | 2 ++
>  drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c     | 6 ++++--
>  drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c | 6 ++++--
>  3 files changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> index f7c251f79aa9..219d4a2547aa 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> @@ -112,6 +112,7 @@ enum rkisp1_isp_pad {
>   * @RKISP1_FEATURE_MIPI_CSI2: The ISP has an internal MIPI CSI-2 receiver
>   * @RKISP1_FEATURE_MAIN_STRIDE: The ISP supports configurable stride on the main path
>   * @RKISP1_FEATURE_SELF_PATH: The ISP has a self path
> + * @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the resizer input
>   *
>   * The ISP features are stored in a bitmask in &rkisp1_info.features and allow
>   * the driver to implement support for features present in some ISP versions
> @@ -121,6 +122,7 @@ enum rkisp1_feature {
>  	RKISP1_FEATURE_MIPI_CSI2 = BIT(0),
>  	RKISP1_FEATURE_MAIN_STRIDE = BIT(1),
>  	RKISP1_FEATURE_SELF_PATH = BIT(2),
> +	RKISP1_FEATURE_DUAL_CROP = BIT(3),
>  };
>  
>  #define rkisp1_has_feature(rkisp1, feature) \
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> index f48a21985b18..2e40c376cab5 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> @@ -507,7 +507,8 @@ static const struct rkisp1_info px30_isp_info = {
>  	.isr_size = ARRAY_SIZE(px30_isp_isrs),
>  	.isp_ver = RKISP1_V12,
>  	.features = RKISP1_FEATURE_MIPI_CSI2
> -		  | RKISP1_FEATURE_SELF_PATH,
> +		  | RKISP1_FEATURE_SELF_PATH
> +		  | RKISP1_FEATURE_DUAL_CROP,
>  };
>  
>  static const char * const rk3399_isp_clks[] = {
> @@ -527,7 +528,8 @@ static const struct rkisp1_info rk3399_isp_info = {
>  	.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
>  	.isp_ver = RKISP1_V10,
>  	.features = RKISP1_FEATURE_MIPI_CSI2
> -		  | RKISP1_FEATURE_SELF_PATH,
> +		  | RKISP1_FEATURE_SELF_PATH
> +		  | RKISP1_FEATURE_DUAL_CROP,
>  };
>  
>  static const struct of_device_id rkisp1_of_match[] = {
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
> index dd77a31e6014..de2eb2c97cc4 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
> @@ -635,7 +635,8 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
>  	struct v4l2_subdev_state *sd_state;
>  
>  	if (!enable) {
> -		rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
> +		if (rkisp1_has_feature(rkisp1, DUAL_CROP))
> +			rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
>  		rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
>  		return 0;
>  	}
> @@ -646,7 +647,8 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
>  	sd_state = v4l2_subdev_lock_and_get_active_state(sd);
>  
>  	rkisp1_rsz_config(rsz, sd_state, when);
> -	rkisp1_dcrop_config(rsz, sd_state);
> +	if (rkisp1_has_feature(rkisp1, DUAL_CROP))
> +		rkisp1_dcrop_config(rsz, sd_state);
>  
>  	v4l2_subdev_unlock_state(sd_state);
>  

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Thu Feb  1 05:55:44 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Thu, 1 Feb 2024 15:55:44 +0200
Subject: [PATCH v6 06/11] media: rkisp1: Add match data for i.MX8MP ISP
In-Reply-To: <20240111114831.656736-7-paul.elder@ideasonboard.com>
References: <20240111114831.656736-1-paul.elder@ideasonboard.com>
 <20240111114831.656736-7-paul.elder@ideasonboard.com>
Message-ID: <20240201135544.GC5344@pendragon.ideasonboard.com>

On Thu, Jan 11, 2024 at 08:48:26PM +0900, Paul Elder wrote:
> Add match data to the rkisp1 driver to match the i.MX8MP ISP.

This patch, or at least the part that adds the compatible entry, should
move to the end of the series, after the other patches that enable the
features needed by the i.MX8MP.

> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Tested-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
>  .../platform/rockchip/rkisp1/rkisp1-dev.c     | 23 +++++++++++++++++++
>  include/uapi/linux/rkisp1-config.h            |  2 ++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> index 2e40c376cab5..e4aac0234178 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> @@ -532,6 +532,25 @@ static const struct rkisp1_info rk3399_isp_info = {
>  		  | RKISP1_FEATURE_DUAL_CROP,
>  };
>  
> +static const char * const imx8mp_isp_clks[] = {
> +	"isp",
> +	"hclk",
> +	"aclk",
> +};
> +
> +static const struct rkisp1_isr_data imx8mp_isp_isrs[] = {
> +	{ NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) },
> +};
> +
> +static const struct rkisp1_info imx8mp_isp_info = {
> +	.clks = imx8mp_isp_clks,
> +	.clk_size = ARRAY_SIZE(imx8mp_isp_clks),
> +	.isrs = imx8mp_isp_isrs,
> +	.isr_size = ARRAY_SIZE(imx8mp_isp_isrs),
> +	.isp_ver = IMX8MP_V10,
> +	.features = RKISP1_FEATURE_MAIN_STRIDE,
> +};
> +
>  static const struct of_device_id rkisp1_of_match[] = {
>  	{
>  		.compatible = "rockchip,px30-cif-isp",
> @@ -541,6 +560,10 @@ static const struct of_device_id rkisp1_of_match[] = {
>  		.compatible = "rockchip,rk3399-cif-isp",
>  		.data = &rk3399_isp_info,
>  	},
> +	{
> +		.compatible = "fsl,imx8mp-isp",
> +		.data = &imx8mp_isp_info,
> +	},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, rkisp1_of_match);
> diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h
> index 730673ecc63d..f602442c2018 100644
> --- a/include/uapi/linux/rkisp1-config.h
> +++ b/include/uapi/linux/rkisp1-config.h
> @@ -179,12 +179,14 @@
>   * @RKISP1_V11: declared in the original vendor code, but not used
>   * @RKISP1_V12: used at least in rk3326 and px30
>   * @RKISP1_V13: used at least in rk1808
> + * @IMX8MP_V10: used in at least imx8mp
>   */
>  enum rkisp1_cif_isp_version {
>  	RKISP1_V10 = 10,
>  	RKISP1_V11,
>  	RKISP1_V12,
>  	RKISP1_V13,
> +	IMX8MP_V10,

This is prone to namespace clashes, especially in the userspace API. I
prefer keeping the RKISP1_ prefix. Furthermore, there's no "V10" for the
i.MX8MP. You can name the version RKISP1_V_IMX8MP. I dislike it very
much but have no better alternative to propose without more information
from VSI.

>  };
>  
>  enum rkisp1_cif_isp_histogram_mode {

-- 
Regards,

Laurent Pinchart


From mkorpershoek at baylibre.com  Thu Feb  1 05:55:55 2024
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Thu, 01 Feb 2024 14:55:55 +0100
Subject: [PATCH v3 5/6] arm64: dts: ti: k3-am62p: Add Wave5 Video
 Encoder/Decoder Node
In-Reply-To: <20240131212625.1862775-6-b-brnich@ti.com>
References: <20240131212625.1862775-1-b-brnich@ti.com>
 <20240131212625.1862775-6-b-brnich@ti.com>
Message-ID: <8734ucmgpg.fsf@baylibre.com>

Hi Brandon,

Thank you for the patch.

On mer., janv. 31, 2024 at 15:26, Brandon Brnich <b-brnich at ti.com> wrote:

> This patch adds support for the Wave521cl on the AM62P.
>
> Signed-off-by: Brandon Brnich <b-brnich at ti.com>

Reviewed-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>

> ---
>  arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 10 ++++++++++
>  arch/arm64/boot/dts/ti/k3-am62p5-sk.dts   |  4 ++++
>  2 files changed, 14 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> index 4c51bae06b57..94c89699b35f 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> @@ -891,4 +891,14 @@ mcasp2: audio-controller at 2b20000 {
>  		power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
>  		status = "disabled";
>  	};
> +
> +	vpu: video-codec at 30210000 {
> +		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
> +		reg = <0x00 0x30210000 0x00 0x10000>;
> +		interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&k3_clks 204 2>;
> +		clock-names = "vcodec";
> +		power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
> +	};
>  };
> diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
> index 1773c05f752c..0aec79ed5578 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
> @@ -569,6 +569,10 @@ &main_uart0 {
>  	bootph-all;
>  };
>  
> +&vpu {
> +	status = "okay";
> +};
> +
>  &main_uart1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_uart1_pins_default>;
> -- 
> 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 tomasz.figa at gmail.com  Thu Feb  1 06:01:34 2024
From: tomasz.figa at gmail.com (Tomasz Figa)
Date: Thu,  1 Feb 2024 23:01:34 +0900
Subject: [PATCH] MAINTAINERS: Remove Tomasz from Samsung clock and pinctrl entries
Message-ID: <20240201140134.4345-1-tomasz.figa@gmail.com>

I have been no longer at Samsung for a long time, the platforms
that I am knowledgable about (S3C24xx, S3C64xx, Exynos 4) are no longer
relevant and we have people with better capabilities as maintainers
already, so let me remove myself. Thanks for the nice collaboration
everyone!

Signed-off-by: Tomasz Figa <tomasz.figa at gmail.com>
---
 MAINTAINERS | 2 --
 1 file changed, 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 61117c3afa80..7f550edab68e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17343,7 +17343,6 @@ F:	Documentation/devicetree/bindings/pinctrl/renesas,*
 F:	drivers/pinctrl/renesas/
 
 PIN CONTROLLER - SAMSUNG
-M:	Tomasz Figa <tomasz.figa at gmail.com>
 M:	Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
 M:	Sylwester Nawrocki <s.nawrocki at samsung.com>
 R:	Alim Akhtar <alim.akhtar at samsung.com>
@@ -19392,7 +19391,6 @@ F:	drivers/media/platform/samsung/exynos4-is/
 SAMSUNG SOC CLOCK DRIVERS
 M:	Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
 M:	Sylwester Nawrocki <s.nawrocki at samsung.com>
-M:	Tomasz Figa <tomasz.figa at gmail.com>
 M:	Chanwoo Choi <cw00.choi at samsung.com>
 R:	Alim Akhtar <alim.akhtar at samsung.com>
 L:	linux-samsung-soc at vger.kernel.org
-- 
2.39.2



From laurent.pinchart at ideasonboard.com  Thu Feb  1 06:03:48 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Thu, 1 Feb 2024 16:03:48 +0200
Subject: [PATCH v6 11/11] media: rkisp1: Fix endianness on raw streams on
 i.MX8MP
In-Reply-To: <20240111114831.656736-12-paul.elder@ideasonboard.com>
References: <20240111114831.656736-1-paul.elder@ideasonboard.com>
 <20240111114831.656736-12-paul.elder@ideasonboard.com>
Message-ID: <20240201140348.GD5344@pendragon.ideasonboard.com>

Hi Paul,

Thank you for the patch.

On Thu, Jan 11, 2024 at 08:48:31PM +0900, Paul Elder wrote:
> The i.MX8MP has extra register fields in the memory interface control
> register for setting the output format, which work with the output
> alignment format register for byte-swapping and LSB/MSB alignment.
> 
> With processed and 8-bit raw streams, it doesn't cause any problems to
> not set these, but with raw streams of higher bit depth the endianness
> is swapped and the data is not aligned properly.
> 
> Add support for setting these registers and plumb them in to fix this.
> 
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> ---
> New in v6
> ---
>  .../platform/rockchip/rkisp1/rkisp1-capture.c | 95 ++++++++++++++-----
>  .../platform/rockchip/rkisp1/rkisp1-common.h  |  2 +
>  .../platform/rockchip/rkisp1/rkisp1-dev.c     |  3 +-
>  .../platform/rockchip/rkisp1/rkisp1-regs.h    |  8 ++
>  4 files changed, 83 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> index 813d4274f118..8067b5c003a6 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> @@ -48,16 +48,20 @@ enum rkisp1_plane {
>   * @fmt_type: helper filed for pixel format
>   * @uv_swap: if cb cr swapped, for yuv
>   * @yc_swap: if y and cb/cr swapped, for yuv
> + * @byte_swap: if byte pairs are swapped, for raw
>   * @write_format: defines how YCbCr self picture data is written to memory
> - * @output_format: defines sp output format
> + * @output_format_mp: defines mp output format
> + * @output_format_sp: defines sp output format
>   * @mbus: the mbus code on the src resizer pad that matches the pixel format
>   */
>  struct rkisp1_capture_fmt_cfg {
>  	u32 fourcc;
>  	u32 uv_swap : 1;
>  	u32 yc_swap : 1;
> +	u32 byte_swap : 1;
>  	u32 write_format;
> -	u32 output_format;
> +	u32 output_format_mp;
> +	u32 output_format_sp;
>  	u32 mbus;
>  };
>  
> @@ -96,42 +100,50 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
>  		.fourcc = V4L2_PIX_FMT_YUYV,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_UYVY,
>  		.uv_swap = 0,
>  		.yc_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YUV422P,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV16,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV61,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV16M,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV61M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YVU422M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	},
>  	/* yuv400 */
> @@ -139,6 +151,7 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
>  		.fourcc = V4L2_PIX_FMT_GREY,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	},
>  	/* yuv420 */
> @@ -146,81 +159,107 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
>  		.fourcc = V4L2_PIX_FMT_NV21,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV12,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV21M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV12M,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YUV420,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YVU420,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	},
>  	/* raw */
>  	{
>  		.fourcc = V4L2_PIX_FMT_SRGGB8,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
>  		.mbus = MEDIA_BUS_FMT_SRGGB8_1X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGRBG8,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
>  		.mbus = MEDIA_BUS_FMT_SGRBG8_1X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGBRG8,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
>  		.mbus = MEDIA_BUS_FMT_SGBRG8_1X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SBGGR8,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
>  		.mbus = MEDIA_BUS_FMT_SBGGR8_1X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SRGGB10,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
>  		.mbus = MEDIA_BUS_FMT_SRGGB10_1X10,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGRBG10,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
>  		.mbus = MEDIA_BUS_FMT_SGRBG10_1X10,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGBRG10,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
>  		.mbus = MEDIA_BUS_FMT_SGBRG10_1X10,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SBGGR10,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
>  		.mbus = MEDIA_BUS_FMT_SBGGR10_1X10,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SRGGB12,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
>  		.mbus = MEDIA_BUS_FMT_SRGGB12_1X12,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGRBG12,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
>  		.mbus = MEDIA_BUS_FMT_SGRBG12_1X12,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGBRG12,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
>  		.mbus = MEDIA_BUS_FMT_SGBRG12_1X12,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SBGGR12,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
>  		.mbus = MEDIA_BUS_FMT_SBGGR12_1X12,
>  	},
>  };
> @@ -235,50 +274,50 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
>  		.fourcc = V4L2_PIX_FMT_YUYV,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_UYVY,
>  		.uv_swap = 0,
>  		.yc_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YUV422P,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV16,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV61,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV16M,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV61M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YVU422M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	},
>  	/* yuv400 */
> @@ -286,19 +325,19 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
>  		.fourcc = V4L2_PIX_FMT_GREY,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	},
>  	/* rgb */
>  	{
>  		.fourcc = V4L2_PIX_FMT_XBGR32,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_RGB565,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	},
>  	/* yuv420 */
> @@ -306,37 +345,37 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
>  		.fourcc = V4L2_PIX_FMT_NV21,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV12,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV21M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV12M,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YUV420,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YVU420,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	},
>  };
> @@ -482,12 +521,14 @@ static void rkisp1_mp_config(struct rkisp1_capture *cap)
>  	 * NV12/NV21 and NV16/NV61, so instead use byte swap to support UYVY.
>  	 * YVYU and VYUY cannot be supported with this method.
>  	 */
> -	if (rkisp1->info->features & RKISP1_FEATURE_MI_OUTPUT_ALIGN) {
> +	if (rkisp1_has_feature(rkisp1, MI_OUTPUT_ALIGN)) {
>  		reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
> -		if (cap->pix.cfg->yc_swap)
> +		if (cap->pix.cfg->yc_swap || cap->pix.cfg->byte_swap)
>  			reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
>  		else
>  			reg &= ~RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
> +
> +		reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_LSB_ALIGNMENT;
>  		rkisp1_write(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT, reg);
>  	}
>  
> @@ -554,7 +595,7 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap)
>  	mi_ctrl &= ~RKISP1_MI_CTRL_SP_FMT_MASK;
>  	mi_ctrl |= cap->pix.cfg->write_format |
>  		   RKISP1_MI_CTRL_SP_INPUT_YUV422 |
> -		   cap->pix.cfg->output_format |
> +		   cap->pix.cfg->output_format_sp |
>  		   RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE;
>  	rkisp1_write(rkisp1, RKISP1_CIF_MI_CTRL, mi_ctrl);
>  }
> @@ -946,6 +987,7 @@ static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
>  	struct rkisp1_device *rkisp1 = cap->rkisp1;
>  	struct rkisp1_capture *other = &rkisp1->capture_devs[cap->id ^ 1];
>  	bool has_self_path = rkisp1_has_feature(rkisp1, SELF_PATH);
> +	u32 reg;
>  
>  	cap->ops->set_data_path(cap);
>  	cap->ops->config(cap);
> @@ -965,8 +1007,13 @@ static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
>  	 */
>  	if (!has_self_path || !other->is_streaming) {
>  		/* force cfg update */
> -		rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT,
> -			     RKISP1_CIF_MI_INIT_SOFT_UPD);
> +		reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_INIT);
> +
> +		if (rkisp1_has_feature(rkisp1, MP_OUTPUT_FORMAT))
> +			reg |= cap->pix.cfg->output_format_mp;
> +
> +		reg |= RKISP1_CIF_MI_INIT_SOFT_UPD;
> +		rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT, reg);
>  		rkisp1_set_next_buf(cap);
>  	}
>  	spin_unlock_irq(&cap->buf.lock);
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> index 8e2a63ab2cdd..7167257ecde2 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> @@ -116,6 +116,7 @@ enum rkisp1_isp_pad {
>   * @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the resizer input
>   * @RKISP1_FEATURE_DMA_34BIT: The ISP uses 34-bit DMA addresses
>   * @RKISP1_FEATURE_MI_OUTPUT_ALIGN: The ISP has the MI_OUTPUT_ALIGN_FORMAT register
> + * @RKISP1_FEATURE_MP_OUTPUT_FORMAT: The ISP has mp_output_format field in the MI_INIT register

Do you foresee ISP versions that will support one and only one of the
two features ? If not I would prefer merging them in a single feature.
They could also be merged with the RKISP1_FEATURE_MAIN_STRIDE feature if
desired I think. A ISP8000 feature flag is tempted, but we don't know if
that's accurate :-S

>   *
>   * The ISP features are stored in a bitmask in &rkisp1_info.features and allow
>   * the driver to implement support for features present in some ISP versions
> @@ -128,6 +129,7 @@ enum rkisp1_feature {
>  	RKISP1_FEATURE_DUAL_CROP = BIT(3),
>  	RKISP1_FEATURE_DMA_34BIT = BIT(4),
>  	RKISP1_FEATURE_MI_OUTPUT_ALIGN = BIT(5),
> +	RKISP1_FEATURE_MP_OUTPUT_FORMAT = BIT(6),
>  };
>  
>  #define rkisp1_has_feature(rkisp1, feature) \
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> index 307bfe9030f2..43fc2c728cea 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> @@ -551,7 +551,8 @@ static const struct rkisp1_info imx8mp_isp_info = {
>  	.isp_ver = IMX8MP_V10,
>  	.features = RKISP1_FEATURE_MAIN_STRIDE
>  		  | RKISP1_FEATURE_DMA_34BIT
> -		  | RKISP1_FEATURE_MI_OUTPUT_ALIGN,
> +		  | RKISP1_FEATURE_MI_OUTPUT_ALIGN
> +		  | RKISP1_FEATURE_MP_OUTPUT_FORMAT,
>  };
>  
>  static const struct of_device_id rkisp1_of_match[] = {
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> index 3b19c8411360..762243016f05 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> @@ -144,6 +144,14 @@
>  /* MI_INIT */
>  #define RKISP1_CIF_MI_INIT_SKIP				BIT(2)
>  #define RKISP1_CIF_MI_INIT_SOFT_UPD			BIT(4)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400		(0 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420		(1 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422		(2 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV444		(3 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12		(4 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8		(5 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_JPEG		(6 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10		(7 << 5)
>  
>  /* MI_CTRL_SHD */
>  #define RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED		BIT(0)

-- 
Regards,

Laurent Pinchart


From peter.hilber at opensynergy.com  Thu Feb  1 06:04:43 2024
From: peter.hilber at opensynergy.com (Peter Hilber)
Date: Thu, 1 Feb 2024 15:04:43 +0100
Subject: [PATCH v3 5/8] ptp/kvm, arm_arch_timer: Set
 system_counterval_t.cs_id to constant
In-Reply-To: <86jzno70ma.wl-maz@kernel.org>
References: <20240201010453.2212371-1-peter.hilber@opensynergy.com>
 <20240201010453.2212371-6-peter.hilber@opensynergy.com>
 <86jzno70ma.wl-maz@kernel.org>
Message-ID: <afbd30fb-929e-4d17-97cd-e0456fe99f34@opensynergy.com>

On 01.02.24 14:52, Marc Zyngier wrote:
> On Thu, 01 Feb 2024 01:04:50 +0000,
> Peter Hilber <peter.hilber at opensynergy.com> wrote:
>>
>> Identify the clocksources used by ptp_kvm by setting clocksource ID enum
>> constants. This avoids dereferencing struct clocksource. Once the
>> system_counterval_t.cs member will be removed, this will also avoid the
>> need to obtain clocksource pointers from kvm_arch_ptp_get_crosststamp().
>>
>> The clocksource IDs are associated to timestamps requested from the KVM
>> hypervisor, so the proper clocksource ID is known at the ptp_kvm request
>> site.
>>
>> While at it, also rectify the ptp_kvm_get_time_fn() ret type.
> 
> Not sure what is wrong with that return type, but this patch doesn't
> seem to affect it.
> 

I meant to refer to the type of the variable ret declared in
ptp_kvm_get_time_fn(). I will reword the commit message to make this clear.

Thanks for the comment,

Peter


From geert+renesas at glider.be  Thu Feb  1 06:09:17 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:09:17 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: gray-hawk-single: Enable watchdog timer
In-Reply-To: <cover.1706790320.git.geert+renesas@glider.be>
References: <cover.1706790320.git.geert+renesas@glider.be>
Message-ID: <cf6effafd9e0472a457eed9d84a834abc3e1c833.1706790320.git.geert+renesas@glider.be>

Enable the watchdog timer on the Gray Hawk Single board.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
index 716cb7622f167973..1c84fe7171d3fd85 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
+++ b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
@@ -65,6 +65,11 @@ scif_clk_pins: scif_clk {
 	};
 };
 
+&rwdt {
+	timeout-sec = <60>;
+	status = "okay";
+};
+
 &scif_clk {
 	clock-frequency = <24000000>;
 };
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb  1 06:09:15 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:09:15 +0100
Subject: [PATCH 0/2] arm64: dts: renesas: r8a779h0/gray-hawk-single: Add watchdog support
Message-ID: <cover.1706790320.git.geert+renesas@glider.be>

	Hi all,

This patch series adds watchdog timer support for the Renesas R-Car V4M
(R8A779H0) Soc and the Gray Hawk Single development board.

I intend to queue this in renesas-devel for v6.9.

Thanks for your comments!

Geert Uytterhoeven (1):
  arm64: dts: renesas: gray-hawk-single: Enable watchdog timer

Minh Le (1):
  arm64: dts: renesas: r8a779h0: Add RWDT node

 .../boot/dts/renesas/r8a779h0-gray-hawk-single.dts    |  5 +++++
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi             | 11 +++++++++++
 2 files changed, 16 insertions(+)

-- 
2.34.1

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 geert+renesas at glider.be  Thu Feb  1 06:09:16 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:09:16 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: r8a779h0: Add RWDT node
In-Reply-To: <cover.1706790320.git.geert+renesas@glider.be>
References: <cover.1706790320.git.geert+renesas@glider.be>
Message-ID: <43bb03f3baa87b4be8ce953b1955df6b89387e4c.1706790320.git.geert+renesas@glider.be>

From: Minh Le <minh.le.aj at renesas.com>

Add a device node for the RCLK Watchdog Timer (RWDT) on the Renesas
R-Car V4M (R8A779H0) SoC.

Signed-off-by: Minh Le <minh.le.aj at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Split in separate commits for SoC and board support,
  - Use TABs for indentation,
  - Add missing interrupts property.
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index f59d0dd25ca93822..f5a688e300d29a73 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -59,6 +59,17 @@ soc: soc {
 		#size-cells = <2>;
 		ranges;
 
+		rwdt: watchdog at e6020000 {
+			compatible = "renesas,r8a779h0-wdt",
+				     "renesas,rcar-gen4-wdt";
+			reg = <0 0xe6020000 0 0x0c>;
+			interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 907>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 907>;
+			status = "disabled";
+		};
+
 		pfc: pinctrl at e6050000 {
 			compatible = "renesas,pfc-r8a779h0";
 			reg = <0 0xe6050000 0 0x16c>, <0 0xe6050800 0 0x16c>,
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb  1 06:14:32 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:14:32 +0100
Subject: [PATCH 0/2] arm64: dts: renesas: r8a779h0/gray-hawk-single: Add I2C and EEPROM support
Message-ID: <cover.1706796660.git.geert+renesas@glider.be>

	Hi all,

This patch series adds I2C support for the Renesas R-Car V4M (R8A779H0)
Soc, and I2C0 and board ID EEPROM support for the Gray Hawk Single
development board.

I intend to queue this in renesas-devel for v6.9.

Thanks for your comments!

Geert Uytterhoeven (1):
  arm64: dts: renesas: gray-hawk-single: Add I2C0 and EEPROMs

Hai Pham (1):
  arm64: dts: renesas: r8a779h0: Add I2C nodes

 .../dts/renesas/r8a779h0-gray-hawk-single.dts | 41 ++++++++++++++
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi     | 56 +++++++++++++++++++
 2 files changed, 97 insertions(+)

-- 
2.34.1

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 geert+renesas at glider.be  Thu Feb  1 06:14:34 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:14:34 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: gray-hawk-single: Add I2C0 and EEPROMs
In-Reply-To: <cover.1706796660.git.geert+renesas@glider.be>
References: <cover.1706796660.git.geert+renesas@glider.be>
Message-ID: <960595394a274b675f1ec9ec1c324e4cc1ac1f77.1706796660.git.geert+renesas@glider.be>

Enable the I2C0 bus on the Gray Hawk Single board, and describe the I2C
EEPROMs present.

Based on patches for Gray Hawk in the BSP by Hai Pham.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
The Gray Hawk Single documentation does not mention the purpose of the
I2C EEPROMs, but the schematics label the last two as "Board ID".
The labels match the corresponding EEPROMs on the White Hawk CPU and
BreakOut board stack, from which the Gray Hawk Single board is derived.
---
 .../dts/renesas/r8a779h0-gray-hawk-single.dts | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
index 1c84fe7171d3fd85..1bee27b2284d2eee 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
+++ b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
@@ -50,6 +50,42 @@ &hscif0 {
 	status = "okay";
 };
 
+&i2c0 {
+	pinctrl-0 = <&i2c0_pins>;
+	pinctrl-names = "default";
+
+	status = "okay";
+	clock-frequency = <400000>;
+
+	eeprom at 50 {
+		compatible = "rohm,br24g01", "atmel,24c01";
+		label = "cpu-board";
+		reg = <0x50>;
+		pagesize = <8>;
+	};
+
+	eeprom at 51 {
+		compatible = "rohm,br24g01", "atmel,24c01";
+		label = "breakout-board";
+		reg = <0x51>;
+		pagesize = <8>;
+	};
+
+	eeprom at 52 {
+		compatible = "rohm,br24g01", "atmel,24c01";
+		label = "csi-dsi-sub-board-id";
+		reg = <0x52>;
+		pagesize = <8>;
+	};
+
+	eeprom at 53 {
+		compatible = "rohm,br24g01", "atmel,24c01";
+		label = "ethernet-sub-board-id";
+		reg = <0x53>;
+		pagesize = <8>;
+	};
+};
+
 &pfc {
 	pinctrl-0 = <&scif_clk_pins>;
 	pinctrl-names = "default";
@@ -59,6 +95,11 @@ hscif0_pins: hscif0 {
 		function = "hscif0";
 	};
 
+	i2c0_pins: i2c0 {
+		groups = "i2c0";
+		function = "i2c0";
+	};
+
 	scif_clk_pins: scif_clk {
 		groups = "scif_clk";
 		function = "scif_clk";
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb  1 06:14:33 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:14:33 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: r8a779h0: Add I2C nodes
In-Reply-To: <cover.1706796660.git.geert+renesas@glider.be>
References: <cover.1706796660.git.geert+renesas@glider.be>
Message-ID: <7dbbe13428273c5786ddff6ea7af6724fcdd4de8.1706796660.git.geert+renesas@glider.be>

From: Hai Pham <hai.pham.ud at renesas.com>

Add device nodes for the I2C Bus Interfaces on the Renesas R-Car V4M
(R8A779H0) SoC.

Signed-off-by: Hai Pham <hai.pham.ud at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Incorporate i2c2 fix from "arm64: dts: renesas: r8a779h0: Sort IPMMU driver nodes".
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 56 +++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index f5a688e300d29a73..8121aadaf6999429 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -99,6 +99,62 @@ sysc: system-controller at e6180000 {
 			#power-domain-cells = <1>;
 		};
 
+		i2c0: i2c at e6500000 {
+			compatible = "renesas,i2c-r8a779h0",
+				     "renesas,rcar-gen4-i2c";
+			reg = <0 0xe6500000 0 0x40>;
+			interrupts = <GIC_SPI 610 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 518>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 518>;
+			i2c-scl-internal-delay-ns = <110>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c1: i2c at e6508000 {
+			compatible = "renesas,i2c-r8a779h0",
+				     "renesas,rcar-gen4-i2c";
+			reg = <0 0xe6508000 0 0x40>;
+			interrupts = <GIC_SPI 611 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 519>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 519>;
+			i2c-scl-internal-delay-ns = <110>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c2: i2c at e6510000 {
+			compatible = "renesas,i2c-r8a779h0",
+				     "renesas,rcar-gen4-i2c";
+			reg = <0 0xe6510000 0 0x40>;
+			interrupts = <GIC_SPI 612 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 520>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 520>;
+			i2c-scl-internal-delay-ns = <110>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c3: i2c at e66d0000 {
+			compatible = "renesas,i2c-r8a779h0",
+				     "renesas,rcar-gen4-i2c";
+			reg = <0 0xe66d0000 0 0x40>;
+			interrupts = <GIC_SPI 613 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 521>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 521>;
+			i2c-scl-internal-delay-ns = <110>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		hscif0: serial at e6540000 {
 			compatible = "renesas,hscif-r8a779h0",
 				     "renesas,rcar-gen4-hscif", "renesas,hscif";
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb  1 06:15:56 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:15:56 +0100
Subject: [PATCH] arm64: dts: renesas: r8a779h0: Add GPIO nodes
Message-ID: <d4c1c40404ab84c7e7c07612077ca1a319ae7283.1706796918.git.geert+renesas@glider.be>

From: Cong Dang <cong.dang.xn at renesas.com>

Add device nodes for the General Purpose Input/Output (GPIO) blocks on
the Renesas R-Car V4M (R8A779H0) SoC.

Signed-off-by: Cong Dang <cong.dang.xn at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Correct module clock and reset for gpio[2-7] (verified by checking
    impacted registers on reset).
---
To be queued in renesas-devel for v6.9.

 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 120 ++++++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index 8121aadaf6999429..eb555cbf51a41001 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -78,6 +78,126 @@ pfc: pinctrl at e6050000 {
 			      <0 0xe6061000 0 0x16c>, <0 0xe6061800 0 0x16c>;
 		};
 
+		gpio0: gpio at e6050180 {
+			compatible = "renesas,gpio-r8a779h0",
+				     "renesas,rcar-gen4-gpio";
+			reg = <0 0xe6050180 0 0x54>;
+			interrupts = <GIC_SPI 619 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 0 19>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 915>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 915>;
+		};
+
+		gpio1: gpio at e6050980 {
+			compatible = "renesas,gpio-r8a779h0",
+				     "renesas,rcar-gen4-gpio";
+			reg = <0 0xe6050980 0 0x54>;
+			interrupts = <GIC_SPI 623 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 32 30>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 915>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 915>;
+		};
+
+		gpio2: gpio at e6058180 {
+			compatible = "renesas,gpio-r8a779h0",
+				     "renesas,rcar-gen4-gpio";
+			reg = <0 0xe6058180 0 0x54>;
+			interrupts = <GIC_SPI 627 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 64 20>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 916>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 916>;
+		};
+
+		gpio3: gpio at e6058980 {
+			compatible = "renesas,gpio-r8a779h0",
+				     "renesas,rcar-gen4-gpio";
+			reg = <0 0xe6058980 0 0x54>;
+			interrupts = <GIC_SPI 631 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 96 32>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 916>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 916>;
+		};
+
+		gpio4: gpio at e6060180 {
+			compatible = "renesas,gpio-r8a779h0",
+				     "renesas,rcar-gen4-gpio";
+			reg = <0 0xe6060180 0 0x54>;
+			interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 128 25>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 917>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 917>;
+		};
+
+		gpio5: gpio at e6060980 {
+			compatible = "renesas,gpio-r8a779h0",
+				     "renesas,rcar-gen4-gpio";
+			reg = <0 0xe6060980 0 0x54>;
+			interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 160 21>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 917>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 917>;
+		};
+
+		gpio6: gpio at e6061180 {
+			compatible = "renesas,gpio-r8a779h0",
+				     "renesas,rcar-gen4-gpio";
+			reg = <0 0xe6061180 0 0x54>;
+			interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 192 21>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 917>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 917>;
+		};
+
+		gpio7: gpio at e6061980 {
+			compatible = "renesas,gpio-r8a779h0",
+				     "renesas,rcar-gen4-gpio";
+			reg = <0 0xe6061980 0 0x54>;
+			interrupts = <GIC_SPI 647 IRQ_TYPE_LEVEL_HIGH>;
+			#gpio-cells = <2>;
+			gpio-controller;
+			gpio-ranges = <&pfc 0 224 21>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			clocks = <&cpg CPG_MOD 917>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 917>;
+		};
+
 		cpg: clock-controller at e6150000 {
 			compatible = "renesas,r8a779h0-cpg-mssr";
 			reg = <0 0xe6150000 0 0x4000>;
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb  1 06:19:20 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:19:20 +0100
Subject: [PATCH 5/5] arm64: dts: renesas: r8a779h0: Add CA76 operating points
In-Reply-To: <cover.1706796979.git.geert+renesas@glider.be>
References: <cover.1706796979.git.geert+renesas@glider.be>
Message-ID: <736b5836ec2b54e8b36712866309dc1b7ee1fc48.1706796979.git.geert+renesas@glider.be>

From: Duy Nguyen <duy.nguyen.rh at renesas.com>

Add operating points for running the Cortex-A76 CPU cores on R-Car V4M
at various speeds, up to the Normal (1.0 GHz).

Signed-off-by: Duy Nguyen <duy.nguyen.rh at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index 622775f6160f55bd..4e9e487ec51661fd 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -14,6 +14,22 @@ / {
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	cluster0_opp: opp-table-0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-500000000 {
+			opp-hz = /bits/ 64 <500000000>;
+			opp-microvolt = <825000>;
+			clock-latency-ns = <500000>;
+		};
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <825000>;
+			clock-latency-ns = <500000>;
+		};
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -44,6 +60,7 @@ a76_0: cpu at 0 {
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
 			clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC0>;
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		a76_1: cpu at 100 {
@@ -55,6 +72,7 @@ a76_1: cpu at 100 {
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
 			clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC1>;
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		a76_2: cpu at 200 {
@@ -66,6 +84,7 @@ a76_2: cpu at 200 {
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
 			clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC2>;
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		a76_3: cpu at 300 {
@@ -77,6 +96,7 @@ a76_3: cpu at 300 {
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
 			clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC3>;
+			operating-points-v2 = <&cluster0_opp>;
 		};
 
 		idle-states {
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb  1 06:19:17 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:19:17 +0100
Subject: [PATCH 2/5] arm64: dts: renesas: r8a779h0: Add secondary CA76 CPU cores
In-Reply-To: <cover.1706796979.git.geert+renesas@glider.be>
References: <cover.1706796979.git.geert+renesas@glider.be>
Message-ID: <c2a38a0da74915bf2a9171e53886c83a1c732934.1706796979.git.geert+renesas@glider.be>

From: Duy Nguyen <duy.nguyen.rh at renesas.com>

Complete the description of the Cortex-A76 CPU cores and L3 cache
controllers on the Renesas R-Car V4M (R8A779H0) SoC, including CPU
topology and PSCI support for enabling CPU cores.

Signed-off-by: Duy Nguyen <duy.nguyen.rh at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Rename L3_CA76_0 label to L3_CA76,
  - Move psci node to preserve sort order (alphabetical),
  - Drop GIC_CPU_MASK_SIMPLE changes, as GICv3 PPI interrupt specifiers
    have no such masks.
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 50 +++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index f47695158d991288..88c5dcbc38d59dab 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -18,12 +18,57 @@ cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&a76_0>;
+				};
+				core1 {
+					cpu = <&a76_1>;
+				};
+				core2 {
+					cpu = <&a76_2>;
+				};
+				core3 {
+					cpu = <&a76_3>;
+				};
+			};
+		};
+
 		a76_0: cpu at 0 {
 			compatible = "arm,cortex-a76";
 			reg = <0>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A779H0_PD_A1E0D0C0>;
 			next-level-cache = <&L3_CA76>;
+			enable-method = "psci";
+		};
+
+		a76_1: cpu at 100 {
+			compatible = "arm,cortex-a76";
+			reg = <0x100>;
+			device_type = "cpu";
+			power-domains = <&sysc R8A779H0_PD_A1E0D0C1>;
+			next-level-cache = <&L3_CA76>;
+			enable-method = "psci";
+		};
+
+		a76_2: cpu at 200 {
+			compatible = "arm,cortex-a76";
+			reg = <0x200>;
+			device_type = "cpu";
+			power-domains = <&sysc R8A779H0_PD_A1E0D0C2>;
+			next-level-cache = <&L3_CA76>;
+			enable-method = "psci";
+		};
+
+		a76_3: cpu at 300 {
+			compatible = "arm,cortex-a76";
+			reg = <0x300>;
+			device_type = "cpu";
+			power-domains = <&sysc R8A779H0_PD_A1E0D0C3>;
+			next-level-cache = <&L3_CA76>;
+			enable-method = "psci";
 		};
 
 		L3_CA76: cache-controller {
@@ -53,6 +98,11 @@ pmu-a76 {
 		interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
 	};
 
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+	};
+
 	/* External SCIF clock - to be overridden by boards that provide it */
 	scif_clk: scif-clk {
 		compatible = "fixed-clock";
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb  1 06:19:19 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:19:19 +0100
Subject: [PATCH 4/5] arm64: dts: renesas: r8a779h0: Add CPU core clocks
In-Reply-To: <cover.1706796979.git.geert+renesas@glider.be>
References: <cover.1706796979.git.geert+renesas@glider.be>
Message-ID: <c64cf6ca1590fa1a36b90a18fd70c831d5b8318e.1706796979.git.geert+renesas@glider.be>

From: Duy Nguyen <duy.nguyen.rh at renesas.com>

Describe the clocks for the four Cortex-A76 CPU cores.
CA76 CPU cores 0,1,2,3 are clocked by ZC0,ZC1,ZC2,ZC3.

Signed-off-by: Duy Nguyen <duy.nguyen.rh at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index b3255bba69e3e6da..622775f6160f55bd 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -43,6 +43,7 @@ a76_0: cpu at 0 {
 			next-level-cache = <&L3_CA76>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
+			clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC0>;
 		};
 
 		a76_1: cpu at 100 {
@@ -53,6 +54,7 @@ a76_1: cpu at 100 {
 			next-level-cache = <&L3_CA76>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
+			clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC1>;
 		};
 
 		a76_2: cpu at 200 {
@@ -63,6 +65,7 @@ a76_2: cpu at 200 {
 			next-level-cache = <&L3_CA76>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
+			clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC2>;
 		};
 
 		a76_3: cpu at 300 {
@@ -73,6 +76,7 @@ a76_3: cpu at 300 {
 			next-level-cache = <&L3_CA76>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
+			clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC3>;
 		};
 
 		idle-states {
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb  1 06:19:15 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:19:15 +0100
Subject: [PATCH 0/5] arm64: dts: renesas: r8a779h0: Add full CA76 CPU core support
Message-ID: <cover.1706796979.git.geert+renesas@glider.be>

	Hi all,

This patch series adds full support for the four Cortex-A76 CPU cores on
the Renesas R-Car V4M (R8A779H0) Soc.  It has been tested on the Gray
Hawk Single development board.

I intend to queue this in renesas-devel for v6.9.

Thanks for your comments!


Duy Nguyen (5):
  arm64: dts: renesas: r8a779h0: Add L3 cache controller
  arm64: dts: renesas: r8a779h0: Add secondary CA76 CPU cores
  arm64: dts: renesas: r8a779h0: Add CPUIdle support
  arm64: dts: renesas: r8a779h0: Add CPU core clocks
  arm64: dts: renesas: r8a779h0: Add CA76 operating points

 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 99 +++++++++++++++++++++++
 1 file changed, 99 insertions(+)

-- 
2.34.1

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 geert+renesas at glider.be  Thu Feb  1 06:19:18 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:19:18 +0100
Subject: [PATCH 3/5] arm64: dts: renesas: r8a779h0: Add CPUIdle support
In-Reply-To: <cover.1706796979.git.geert+renesas@glider.be>
References: <cover.1706796979.git.geert+renesas@glider.be>
Message-ID: <848d176bdbcaf3bc44e5dae555afa9c812a19fd1.1706796979.git.geert+renesas@glider.be>

From: Duy Nguyen <duy.nguyen.rh at renesas.com>

Support CPUIdle for ARM Cortex-A76 on R-Car V4M.

Signed-off-by: Duy Nguyen <duy.nguyen.rh at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index 88c5dcbc38d59dab..b3255bba69e3e6da 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -42,6 +42,7 @@ a76_0: cpu at 0 {
 			power-domains = <&sysc R8A779H0_PD_A1E0D0C0>;
 			next-level-cache = <&L3_CA76>;
 			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0>;
 		};
 
 		a76_1: cpu at 100 {
@@ -51,6 +52,7 @@ a76_1: cpu at 100 {
 			power-domains = <&sysc R8A779H0_PD_A1E0D0C1>;
 			next-level-cache = <&L3_CA76>;
 			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0>;
 		};
 
 		a76_2: cpu at 200 {
@@ -60,6 +62,7 @@ a76_2: cpu at 200 {
 			power-domains = <&sysc R8A779H0_PD_A1E0D0C2>;
 			next-level-cache = <&L3_CA76>;
 			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0>;
 		};
 
 		a76_3: cpu at 300 {
@@ -69,6 +72,20 @@ a76_3: cpu at 300 {
 			power-domains = <&sysc R8A779H0_PD_A1E0D0C3>;
 			next-level-cache = <&L3_CA76>;
 			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0>;
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x0010000>;
+				local-timer-stop;
+				entry-latency-us = <400>;
+				exit-latency-us = <500>;
+				min-residency-us = <4000>;
+			};
 		};
 
 		L3_CA76: cache-controller {
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb  1 06:19:16 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu,  1 Feb 2024 15:19:16 +0100
Subject: [PATCH 1/5] arm64: dts: renesas: r8a779h0: Add L3 cache controller
In-Reply-To: <cover.1706796979.git.geert+renesas@glider.be>
References: <cover.1706796979.git.geert+renesas@glider.be>
Message-ID: <9d56a46892c5e0957d244370e6809013cf815905.1706796979.git.geert+renesas@glider.be>

From: Duy Nguyen <duy.nguyen.rh at renesas.com>

Describe the cache configuration for the first Cortex-A76 CPU core on
the Renesas R-Car V4M (R8A779H0) SoC.

Signed-off-by: Duy Nguyen <duy.nguyen.rh at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Rename L3_CA76_0 label to L3_CA76,
  - Rename cache-controller-0 node to cache-controller.
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index eb555cbf51a41001..f47695158d991288 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -23,6 +23,14 @@ a76_0: cpu at 0 {
 			reg = <0>;
 			device_type = "cpu";
 			power-domains = <&sysc R8A779H0_PD_A1E0D0C0>;
+			next-level-cache = <&L3_CA76>;
+		};
+
+		L3_CA76: cache-controller {
+			compatible = "cache";
+			power-domains = <&sysc R8A779H0_PD_A2E0D0>;
+			cache-unified;
+			cache-level = <3>;
 		};
 	};
 
-- 
2.34.1



From semen.protsenko at linaro.org  Thu Feb  1 06:22:04 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 1 Feb 2024 08:22:04 -0600
Subject: [PATCH v2 3/3] arm64: dts: exynos: Add SPI nodes for Exynos850
In-Reply-To: <cd9ca36f-84f6-4cc7-bc1e-a4c5781d2bf2@linaro.org>
References: <20240125013858.3986-1-semen.protsenko@linaro.org>
 <20240125013858.3986-4-semen.protsenko@linaro.org> <cd9ca36f-84f6-4cc7-bc1e-a4c5781d2bf2@linaro.org>
Message-ID: <CAPLW+4ke9AJ_7FkmqTsT7kQv3TWYW0_G2rc=RsSGVFuvX2qi-w@mail.gmail.com>

On Thu, Feb 1, 2024 at 4:31?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 25/01/2024 02:38, Sam Protsenko wrote:
> > Some USI blocks can be configured as SPI controllers. Add corresponding
> > SPI nodes to Exynos850 SoC device tree.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> > Changes in v2:
> >   - Sorted pinctrl properties properly
> >
> >  arch/arm64/boot/dts/exynos/exynos850.dtsi | 54 +++++++++++++++++++++++
> >  1 file changed, 54 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> > index 618bc674896e..ca257da74b50 100644
> > --- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
> > +++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> > @@ -738,6 +738,24 @@ usi_spi_0: usi at 139400c0 {
> >                                <&cmu_peri CLK_GOUT_SPI0_IPCLK>;
> >                       clock-names = "pclk", "ipclk";
> >                       status = "disabled";
> > +
> > +                     spi_0: spi at 13940000 {
> > +                             compatible = "samsung,exynos850-spi";
> > +                             reg = <0x13940000 0x30>;
> > +                             interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
> > +                             pinctrl-0 = <&spi0_pins>;
> > +                             pinctrl-names = "default";
> > +                             clocks = <&cmu_peri CLK_GOUT_SPI0_IPCLK>,
> > +                                      <&cmu_peri CLK_GOUT_SPI0_PCLK>;
> > +                             clock-names = "spi_busclk0", "spi";
> > +                             samsung,spi-src-clk = <0>;
> > +                             dmas = <&pdma0 5>, <&pdma0 4>;
> > +                             dma-names = "tx", "rx";
> > +                             num-cs = <1>;
>
> For the future: please keep properties sorted by name, so clocks+name,
> dmas+name, interrupts, pinctrl+name, more-or-less matching DTS coding
> style. address/size cells can go to the end.
>

Noted, thanks! So IIUC, basically follow the order of properties
described at [1], but keep the standard/common properties block
sorted, and then keep vendor properties sorted, right?

[1] Documentation/devicetree/bindings/dts-coding-style.rst

> Best regards,
> Krzysztof
>


From j-choudhary at ti.com  Thu Feb  1 06:23:08 2024
From: j-choudhary at ti.com (Jayesh Choudhary)
Date: Thu, 1 Feb 2024 19:53:08 +0530
Subject: [RESEND PATCH v2] arm64: dts: ti: k3-am69-sk: remove assigned-clock-parents for unused VP
Message-ID: <20240201142308.4954-1-j-choudhary@ti.com>

VP2 and VP3 are unused video ports and VP3 share the same parent
clock as VP1 causing issue with pixel clock setting for HDMI (VP1).
The current DM firmware does not support changing parent clock if it
is shared by another component. It returns 0 for the determine_rate
query before causing set_rate to set the clock at default maximum of
1.8GHz which is a lot more than the maximum frequency videoports can
support (600MHz) causing SYNC LOST issues.
So remove the parent clocks for unused VPs to avoid conflict.

Fixes: 6f8605fd7d11 ("arm64: dts: ti: k3-am69-sk: Add DP and HDMI support")
Reported-by: Nishanth Menon <nm at ti.com>
Signed-off-by: Jayesh Choudhary <j-choudhary at ti.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---

v1: <https://lore.kernel.org/all/20231221113042.48492-1-j-choudhary at ti.com/>

Changelog v1->v2:
- Updated commit message
- Picked up Tomi's R-by from v1
- Removed "Closes:" link since its invalid now

(NOTE: Sending again as forgot to put mailing list in cc earlier)

 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 8da591579868..370980eb59b0 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -918,13 +918,9 @@ &dss {
 	pinctrl-names = "default";
 	pinctrl-0 = <&dss_vout0_pins_default>;
 	assigned-clocks = <&k3_clks 218 2>,
-			  <&k3_clks 218 5>,
-			  <&k3_clks 218 14>,
-			  <&k3_clks 218 18>;
+			  <&k3_clks 218 5>;
 	assigned-clock-parents = <&k3_clks 218 3>,
-				 <&k3_clks 218 7>,
-				 <&k3_clks 218 16>,
-				 <&k3_clks 218 22>;
+				 <&k3_clks 218 7>;
 };
 
 &serdes_wiz4 {
-- 
2.25.1



From frank-w at public-files.de  Thu Feb  1 06:23:03 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Thu, 1 Feb 2024 15:23:03 +0100
Subject: Aw: Re:  Re: [PATCH v3 1/2] dt-bindings: reset: mediatek: add
 MT7988 reset IDs
In-Reply-To: <20240201-goes-passable-0ba841d36bc3@wendy>
References: <20240117184111.62371-1-linux@fw-web.de>
 <20240117184111.62371-2-linux@fw-web.de>
 <20240118-calcium-krypton-3c787b8d1912@spud>
 <trinity-afc4f48e-65e1-46ee-a78b-1d670cc0f310-1705615200900@3c-app-gmx-bap21>
 <43f946cc-07e1-48c5-9b31-40fc9bc93037@collabora.com>
 <20240119-dupe-obligate-707b3a01b356@spud>
 <0EA6A126-DDC0-4E9F-BEBC-FD018B08CA84@public-files.de>
 <20240201-goes-passable-0ba841d36bc3@wendy>
Message-ID: <trinity-2aef55db-42e0-4f58-9c43-696311a96eb8-1706797383340@3c-app-gmx-bap28>

> Gesendet: Donnerstag, 01. Februar 2024 um 14:11 Uhr
> Von: "Conor Dooley" <conor.dooley at microchip.com>
> I suspect I was asking for a commit message that explains why these
> numbers don't continue in sequence. With that,
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
>
> Cheers,
> Conor.

OK, i would add this to commit message:

"Value is starting again from 0 because resets are used in another driver
than existing constants."

and adding infracfg in commit title, if this is enough?

regards Frank


From irogers at google.com  Thu Feb  1 06:24:51 2024
From: irogers at google.com (Ian Rogers)
Date: Thu, 1 Feb 2024 06:24:51 -0800
Subject: [PATCH v2 3/8] perf arm-spe/cs-etm: Directly iterate CPU maps
In-Reply-To: <9d177173-c66f-a0d3-ba4d-2261f8663fce@arm.com>
References: <20240201042236.1538928-1-irogers@google.com> <20240201042236.1538928-4-irogers@google.com>
 <9d177173-c66f-a0d3-ba4d-2261f8663fce@arm.com>
Message-ID: <CAP-5=fVDjOfM8rZStYJCFPcTD3uhJDNSf_=JrkwYjFrnoOLC=w@mail.gmail.com>

On Thu, Feb 1, 2024 at 3:25?AM James Clark <james.clark at arm.com> wrote:
>
>
>
> On 01/02/2024 04:22, Ian Rogers wrote:
> > Rather than iterate all CPUs and see if they are in CPU maps, directly
> > iterate the CPU map. Similarly make use of the intersect
> > function. Switch perf_cpu_map__has_any_cpu_or_is_empty to more
> > appropriate alternatives.
> >
> > Signed-off-by: Ian Rogers <irogers at google.com>
> > ---
> >  tools/perf/arch/arm/util/cs-etm.c    | 77 ++++++++++++----------------
> >  tools/perf/arch/arm64/util/arm-spe.c |  4 +-
> >  2 files changed, 34 insertions(+), 47 deletions(-)
> >
> > diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> > index 77e6663c1703..f4378ba0b8d6 100644
> > --- a/tools/perf/arch/arm/util/cs-etm.c
> > +++ b/tools/perf/arch/arm/util/cs-etm.c
> > @@ -197,38 +197,32 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr,
> >  static int cs_etm_validate_config(struct auxtrace_record *itr,
> >                                 struct evsel *evsel)
> >  {
> > -     int i, err = -EINVAL;
> > +     int idx, err = -EINVAL;
> >       struct perf_cpu_map *event_cpus = evsel->evlist->core.user_requested_cpus;
> >       struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
> > +     struct perf_cpu_map *intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
>
> Hi Ian,
>
> This has the same issue as V1. 'any' intersect 'online' == empty. Now no
> validation happens anymore. For this to be the same as it used to be,
> validation has to happen on _all_ cores when event_cpus == -1. So it
> needs to be 'any' intersect 'online' == 'online'.
>
> Same issue below with cs_etm_info_priv_size()

Thanks James, sorry for the churn. I'll work on that for v3.

Ian

> Thanks
> James
>
> > +     struct perf_cpu cpu;
> >
> > -     /* Set option of each CPU we have */
> > -     for (i = 0; i < cpu__max_cpu().cpu; i++) {
> > -             struct perf_cpu cpu = { .cpu = i, };
> > -
> > -             /*
> > -              * In per-cpu case, do the validation for CPUs to work with.
> > -              * In per-thread case, the CPU map is empty.  Since the traced
> > -              * program can run on any CPUs in this case, thus don't skip
> > -              * validation.
> > -              */
> > -             if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus) &&
> > -                 !perf_cpu_map__has(event_cpus, cpu))
> > -                     continue;
> > -
> > -             if (!perf_cpu_map__has(online_cpus, cpu))
> > -                     continue;
> > +     perf_cpu_map__put(online_cpus);
> >
> > -             err = cs_etm_validate_context_id(itr, evsel, i);
> > +     /*
> > +      * Set option of each CPU we have. In per-cpu case, do the validation
> > +      * for CPUs to work with.  In per-thread case, the CPU map is empty.
> > +      * Since the traced program can run on any CPUs in this case, thus don't
> > +      * skip validation.
> > +      */
> > +     perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
> > +             err = cs_etm_validate_context_id(itr, evsel, cpu.cpu);
> >               if (err)
> >                       goto out;
> > -             err = cs_etm_validate_timestamp(itr, evsel, i);
> > +             err = cs_etm_validate_timestamp(itr, evsel, cpu.cpu);
> >               if (err)
> >                       goto out;
> >       }
> >
> >       err = 0;
> >  out:
> > -     perf_cpu_map__put(online_cpus);
> > +     perf_cpu_map__put(intersect_cpus);
> >       return err;
> >  }
> >
> > @@ -435,7 +429,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
> >        * Also the case of per-cpu mmaps, need the contextID in order to be notified
> >        * when a context switch happened.
> >        */
> > -     if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> > +     if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
> >               evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
> >                                          "timestamp", 1);
> >               evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
> > @@ -461,7 +455,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
> >       evsel->core.attr.sample_period = 1;
> >
> >       /* In per-cpu case, always need the time of mmap events etc */
> > -     if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus))
> > +     if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
> >               evsel__set_sample_bit(evsel, TIME);
> >
> >       err = cs_etm_validate_config(itr, cs_etm_evsel);
> > @@ -533,38 +527,32 @@ static size_t
> >  cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
> >                     struct evlist *evlist __maybe_unused)
> >  {
> > -     int i;
> > +     int idx;
> >       int etmv3 = 0, etmv4 = 0, ete = 0;
> >       struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus;
> >       struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
> > +     struct perf_cpu cpu;
> >
> >       /* cpu map is not empty, we have specific CPUs to work with */
> > -     if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
> > -             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 (!perf_cpu_map__is_empty(event_cpus)) {
> > +             struct perf_cpu_map *intersect_cpus =
> > +                     perf_cpu_map__intersect(event_cpus, online_cpus);
> >
> > -                     if (cs_etm_is_ete(itr, i))
> > +             perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
> > +                     if (cs_etm_is_ete(itr, cpu.cpu))
> >                               ete++;
> > -                     else if (cs_etm_is_etmv4(itr, i))
> > +                     else if (cs_etm_is_etmv4(itr, cpu.cpu))
> >                               etmv4++;
> >                       else
> >                               etmv3++;
> >               }
> > +             perf_cpu_map__put(intersect_cpus);
> >       } else {
> >               /* get configuration for all CPUs in the system */
> > -             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))
> > +             perf_cpu_map__for_each_cpu(cpu, idx, online_cpus) {
> > +                     if (cs_etm_is_ete(itr, cpu.cpu))
> >                               ete++;
> > -                     else if (cs_etm_is_etmv4(itr, i))
> > +                     else if (cs_etm_is_etmv4(itr, cpu.cpu))
> >                               etmv4++;
> >                       else
> >                               etmv3++;
> > @@ -814,15 +802,14 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
> >               return -EINVAL;
> >
> >       /* If the cpu_map is empty all online CPUs are involved */
> > -     if (perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
> > +     if (perf_cpu_map__is_empty(event_cpus)) {
> >               cpu_map = online_cpus;
> >       } else {
> >               /* Make sure all specified CPUs are online */
> > -             for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) {
> > -                     struct perf_cpu cpu = { .cpu = i, };
> > +             struct perf_cpu cpu;
> >
> > -                     if (perf_cpu_map__has(event_cpus, cpu) &&
> > -                         !perf_cpu_map__has(online_cpus, cpu))
> > +             perf_cpu_map__for_each_cpu(cpu, i, event_cpus) {
> > +                     if (!perf_cpu_map__has(online_cpus, cpu))
> >                               return -EINVAL;
> >               }
> >
> > diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
> > index 51ccbfd3d246..0b52e67edb3b 100644
> > --- a/tools/perf/arch/arm64/util/arm-spe.c
> > +++ b/tools/perf/arch/arm64/util/arm-spe.c
> > @@ -232,7 +232,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
> >        * In the case of per-cpu mmaps, sample CPU for AUX event;
> >        * also enable the timestamp tracing for samples correlation.
> >        */
> > -     if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> > +     if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
> >               evsel__set_sample_bit(arm_spe_evsel, CPU);
> >               evsel__set_config_if_unset(arm_spe_pmu, arm_spe_evsel,
> >                                          "ts_enable", 1);
> > @@ -265,7 +265,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
> >       tracking_evsel->core.attr.sample_period = 1;
> >
> >       /* In per-cpu case, always need the time of mmap events etc */
> > -     if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> > +     if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
> >               evsel__set_sample_bit(tracking_evsel, TIME);
> >               evsel__set_sample_bit(tracking_evsel, CPU);
> >


From wens at kernel.org  Thu Feb  1 06:26:09 2024
From: wens at kernel.org (Chen-Yu Tsai)
Date: Thu, 1 Feb 2024 22:26:09 +0800
Subject: [PATCH v2 2/4] arm64: dts: rockchip: enable temperature driven
 fan control on Rock 5B
In-Reply-To: <20240130-rk-dts-additions-v2-2-c6222c4c78df@gmail.com>
References: <20240130-rk-dts-additions-v2-0-c6222c4c78df@gmail.com> <20240130-rk-dts-additions-v2-2-c6222c4c78df@gmail.com>
Message-ID: <CAGb2v65--rgb2FqmG_0-w1-jUL0odqKXxiZJ-XPYA4uomfYmaQ@mail.gmail.com>

On Wed, Jan 31, 2024 at 2:22?AM Alexey Charkov <alchark at gmail.com> wrote:
>
> This enables thermal monitoring on Radxa Rock 5B and links the PWM
> fan as an active cooling device managed automatically by the thermal
> subsystem, with a target SoC temperature of 65C and a minimum-spin
> interval from 55C to 65C to ensure airflow when the system gets warm
>
> Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>
> Signed-off-by: Alexey Charkov <alchark at gmail.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 34 ++++++++++++++++++++++++-
>  1 file changed, 33 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> index a0e303c3a1dc..b485edeef876 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> @@ -52,7 +52,7 @@ led_rgb_b {
>
>         fan: pwm-fan {
>                 compatible = "pwm-fan";
> -               cooling-levels = <0 95 145 195 255>;
> +               cooling-levels = <0 120 150 180 210 240 255>;
>                 fan-supply = <&vcc5v0_sys>;
>                 pwms = <&pwm1 0 50000 0>;
>                 #cooling-cells = <2>;
> @@ -173,6 +173,34 @@ &cpu_l3 {
>         cpu-supply = <&vdd_cpu_lit_s0>;
>  };
>
> +&package_thermal {
> +       polling-delay = <1000>;
> +
> +       trips {
> +               package_fan0: package-fan0 {
> +                       temperature = <55000>;
> +                       hysteresis = <2000>;
> +                       type = "active";
> +               };
> +               package_fan1: package-fan1 {
> +                       temperature = <65000>;
> +                       hysteresis = <2000>;
> +                       type = "active";
> +               };
> +       };
> +
> +       cooling-maps {
> +               map0 {
> +                       trip = <&package_fan0>;
> +                       cooling-device = <&fan THERMAL_NO_LIMIT 1>;
> +               };
> +               map1 {
> +                       trip = <&package_fan1>;
> +                       cooling-device = <&fan 1 THERMAL_NO_LIMIT>;
> +               };
> +       };
> +};
> +
>  &i2c0 {
>         pinctrl-names = "default";
>         pinctrl-0 = <&i2c0m2_xfer>;
> @@ -731,6 +759,10 @@ regulator-state-mem {
>         };
>  };
>
> +&tsadc {
> +       status = "okay";
> +};
> +

Is there any reason this can't be enabled by default in the .dtsi file?
The thermal sensor doesn't depend on anything external, so there should
be no reason to push this down to the board level.

ChenYu

>  &uart2 {
>         pinctrl-0 = <&uart2m0_xfer>;
>         status = "okay";
>
> --
> 2.43.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From joey.gouly at arm.com  Thu Feb  1 06:38:06 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Thu, 1 Feb 2024 14:38:06 +0000
Subject: [PATCH v2 05/25] KVM: arm64: nv: Add sanitising to VNCR-backed
 FGT sysregs
In-Reply-To: <20240130204533.693853-6-maz@kernel.org>
References: <20240130204533.693853-1-maz@kernel.org>
 <20240130204533.693853-6-maz@kernel.org>
Message-ID: <20240201143806.GG2284078@e124191.cambridge.arm.com>

On Tue, Jan 30, 2024 at 08:45:12PM +0000, Marc Zyngier wrote:
> Fine Grained Traps are controlled by a whole bunch of features.
> Each one of them must be checked and the corresponding masks
> computed so that we don't let the guest apply traps it shouldn't
> be using.
> 
> This takes care of HFGxTR_EL2, HDFGxTR_EL2, and HAFGRTR_EL2.

 ^^ and HFGITR_EL2

> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/nested.c | 128 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 128 insertions(+)
> 
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index ee461e630527..cdeef3259193 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -263,6 +263,134 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
>  		res1 |= HCR_E2H;
>  	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
>  
> +	/* HFG[RW]TR_EL2 */
> +	res0 = res1 = 0;
> +	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
> +	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS)))
> +		res0 |= (HFGxTR_EL2_APDAKey | HFGxTR_EL2_APDBKey |
> +			 HFGxTR_EL2_APGAKey | HFGxTR_EL2_APIAKey |
> +			 HFGxTR_EL2_APIBKey);
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
> +		res0 |= (HFGxTR_EL2_LORC_EL1 | HFGxTR_EL2_LOREA_EL1 |
> +			 HFGxTR_EL2_LORID_EL1 | HFGxTR_EL2_LORN_EL1 |
> +			 HFGxTR_EL2_LORSA_EL1);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, CSV2, CSV2_2) &&
> +	    !kvm_has_feat(kvm, ID_AA64PFR1_EL1, CSV2_frac, CSV2_1p2))
> +		res0 |= (HFGxTR_EL2_SCXTNUM_EL1 | HFGxTR_EL2_SCXTNUM_EL0);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, GIC, IMP))
> +		res0 |= HFGxTR_EL2_ICC_IGRPENn_EL1;
> +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP))
> +		res0 |= (HFGxTR_EL2_ERRIDR_EL1 | HFGxTR_EL2_ERRSELR_EL1 |
> +			 HFGxTR_EL2_ERXFR_EL1 | HFGxTR_EL2_ERXCTLR_EL1 |
> +			 HFGxTR_EL2_ERXSTATUS_EL1 | HFGxTR_EL2_ERXMISCn_EL1 |
> +			 HFGxTR_EL2_ERXPFGF_EL1 | HFGxTR_EL2_ERXPFGCTL_EL1 |
> +			 HFGxTR_EL2_ERXPFGCDN_EL1 | HFGxTR_EL2_ERXADDR_EL1);
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA))
> +		res0 |= HFGxTR_EL2_nACCDATA_EL1;
> +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
> +		res0 |= (HFGxTR_EL2_nGCS_EL0 | HFGxTR_EL2_nGCS_EL1);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
> +		res0 |= (HFGxTR_EL2_nSMPRI_EL1 | HFGxTR_EL2_nTPIDR2_EL0);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
> +		res0 |= HFGxTR_EL2_nRCWMASK_EL1;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
> +		res0 |= (HFGxTR_EL2_nPIRE0_EL1 | HFGxTR_EL2_nPIR_EL1);
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1POE, IMP))
> +		res0 |= (HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nPOR_EL1);
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
> +		res0 |= HFGxTR_EL2_nS2POR_EL1;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, AIE, IMP))
> +		res0 |= (HFGxTR_EL2_nMAIR2_EL1 | HFGxTR_EL2_nAMAIR2_EL1);
> +	set_sysreg_masks(kvm, HFGRTR_EL2, res0 | __HFGRTR_EL2_RES0, res1);
> +	set_sysreg_masks(kvm, HFGWTR_EL2, res0 | __HFGWTR_EL2_RES0, res1);
> +
> +	/* HDFG[RW]TR_EL2 */
> +	res0 = res1 = 0;
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
> +		res0 |= HDFGRTR_EL2_OSDLR_EL1;
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
> +		res0 |= (HDFGRTR_EL2_PMEVCNTRn_EL0 | HDFGRTR_EL2_PMEVTYPERn_EL0 |
> +			 HDFGRTR_EL2_PMCCFILTR_EL0 | HDFGRTR_EL2_PMCCNTR_EL0 |
> +			 HDFGRTR_EL2_PMCNTEN | HDFGRTR_EL2_PMINTEN |
> +			 HDFGRTR_EL2_PMOVS | HDFGRTR_EL2_PMSELR_EL0 |
> +			 HDFGRTR_EL2_PMMIR_EL1 | HDFGRTR_EL2_PMUSERENR_EL0 |
> +			 HDFGRTR_EL2_PMCEIDn_EL0);
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, IMP))
> +		res0 |= (HDFGRTR_EL2_PMBLIMITR_EL1 | HDFGRTR_EL2_PMBPTR_EL1 |
> +			 HDFGRTR_EL2_PMBSR_EL1 | HDFGRTR_EL2_PMSCR_EL1 |
> +			 HDFGRTR_EL2_PMSEVFR_EL1 | HDFGRTR_EL2_PMSFCR_EL1 |
> +			 HDFGRTR_EL2_PMSICR_EL1 | HDFGRTR_EL2_PMSIDR_EL1 |
> +			 HDFGRTR_EL2_PMSIRR_EL1 | HDFGRTR_EL2_PMSLATFR_EL1 |
> +			 HDFGRTR_EL2_PMBIDR_EL1);
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP))
> +		res0 |= (HDFGRTR_EL2_TRC | HDFGRTR_EL2_TRCAUTHSTATUS |
> +			 HDFGRTR_EL2_TRCAUXCTLR | HDFGRTR_EL2_TRCCLAIM |
> +			 HDFGRTR_EL2_TRCCNTVRn | HDFGRTR_EL2_TRCID |
> +			 HDFGRTR_EL2_TRCIMSPECn | HDFGRTR_EL2_TRCOSLSR |
> +			 HDFGRTR_EL2_TRCPRGCTLR | HDFGRTR_EL2_TRCSEQSTR |
> +			 HDFGRTR_EL2_TRCSSCSRn | HDFGRTR_EL2_TRCSTATR |
> +			 HDFGRTR_EL2_TRCVICTLR);
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
> +		res0 |= (HDFGRTR_EL2_TRBBASER_EL1 | HDFGRTR_EL2_TRBIDR_EL1 |
> +			 HDFGRTR_EL2_TRBLIMITR_EL1 | HDFGRTR_EL2_TRBMAR_EL1 |
> +			 HDFGRTR_EL2_TRBPTR_EL1 | HDFGRTR_EL2_TRBSR_EL1 |
> +			 HDFGRTR_EL2_TRBTRG_EL1);
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, BRBE, IMP))
> +		res0 |= (HDFGRTR_EL2_nBRBIDR | HDFGRTR_EL2_nBRBCTL |
> +			 HDFGRTR_EL2_nBRBDATA);
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, V1P2))
> +		res0 |= HDFGRTR_EL2_nPMSNEVFR_EL1;
> +	set_sysreg_masks(kvm, HDFGRTR_EL2, res0 | HDFGRTR_EL2_RES0, res1);
> +
> +	/* Reuse the bits from the read-side and add the write-specific stuff */
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
> +		res0 |= (HDFGWTR_EL2_PMCR_EL0 | HDFGWTR_EL2_PMSWINC_EL0);
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP))
> +		res0 |= HDFGWTR_EL2_TRCOSLAR;
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
> +		res0 |= HDFGWTR_EL2_TRFCR_EL1;
> +	set_sysreg_masks(kvm, HFGWTR_EL2, res0 | HDFGWTR_EL2_RES0, res1);
> +
> +	/* HFGITR_EL2 */
> +	res0 = HFGITR_EL2_RES0;
> +	res1 = HFGITR_EL2_RES1;
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, DPB, DPB2))
> +		res0 |= HFGITR_EL2_DCCVADP;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, PAN, PAN2))
> +		res0 |= (HFGITR_EL2_ATS1E1RP | HFGITR_EL2_ATS1E1WP);
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
> +		res0 |= (HFGITR_EL2_TLBIRVAALE1OS | HFGITR_EL2_TLBIRVALE1OS |
> +			 HFGITR_EL2_TLBIRVAAE1OS | HFGITR_EL2_TLBIRVAE1OS |
> +			 HFGITR_EL2_TLBIVAALE1OS | HFGITR_EL2_TLBIVALE1OS |
> +			 HFGITR_EL2_TLBIVAAE1OS | HFGITR_EL2_TLBIASIDE1OS |
> +			 HFGITR_EL2_TLBIVAE1OS | HFGITR_EL2_TLBIVMALLE1OS);
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
> +		res0 |= (HFGITR_EL2_TLBIRVAALE1 | HFGITR_EL2_TLBIRVALE1 |
> +			 HFGITR_EL2_TLBIRVAAE1 | HFGITR_EL2_TLBIRVAE1 |
> +			 HFGITR_EL2_TLBIRVAALE1IS | HFGITR_EL2_TLBIRVALE1IS |
> +			 HFGITR_EL2_TLBIRVAAE1IS | HFGITR_EL2_TLBIRVAE1IS |
> +			 HFGITR_EL2_TLBIRVAALE1OS | HFGITR_EL2_TLBIRVALE1OS |
> +			 HFGITR_EL2_TLBIRVAAE1OS | HFGITR_EL2_TLBIRVAE1OS);
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, SPECRES, IMP))
> +		res0 |= (HFGITR_EL2_CFPRCTX | HFGITR_EL2_DVPRCTX |
> +			 HFGITR_EL2_CPPRCTX);
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, BRBE, IMP))
> +		res0 |= (HFGITR_EL2_nBRBINJ | HFGITR_EL2_nBRBIALL);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
> +		res0 |= (HFGITR_EL2_nGCSPUSHM_EL1 | HFGITR_EL2_nGCSSTR_EL1 |
> +			 HFGITR_EL2_nGCSEPP);
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, SPECRES, COSP_RCTX))
> +		res0 |= HFGITR_EL2_COSPRCTX;
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, ATS1A, IMP))
> +		res0 |= HFGITR_EL2_ATS1E1A;
> +	set_sysreg_masks(kvm, HFGITR_EL2, res0, res1);
> +
> +	/* HAFGRTR_EL2 - not a lot to see here*/

*very* minor nitpick: add a space before the */

> +	res0 = HAFGRTR_EL2_RES0;
> +	res1 = HAFGRTR_EL2_RES1;
> +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1))
> +		res0 |= ~(res0 | res1);
> +	set_sysreg_masks(kvm, HAFGRTR_EL2, res0, res1);
>  out:
>  	mutex_unlock(&kvm->arch.config_lock);
>  

Looked through every trap bit, that was tedious! and I just realised HCRX_EL2
is still left to do...

Reviewed-by: Joey Gouly <joey.gouly at arm.com>

Thanks,
Joey


From joey.gouly at arm.com  Thu Feb  1 06:56:07 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Thu, 1 Feb 2024 14:56:07 +0000
Subject: [PATCH v2 04/25] KVM: arm64: nv: Add sanitising to EL2
 configuration registers
In-Reply-To: <20240130204533.693853-5-maz@kernel.org>
References: <20240130204533.693853-1-maz@kernel.org>
 <20240130204533.693853-5-maz@kernel.org>
Message-ID: <20240201145607.GH2284078@e124191.cambridge.arm.com>

On Tue, Jan 30, 2024 at 08:45:11PM +0000, Marc Zyngier wrote:
> We can now start making use of our sanitising masks by setting them
> to values that depend on the guest's configuration.
> 
> First up are VTTBR_EL2, VTCR_EL2, VMPIDR_EL2 and HCR_EL2.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/nested.c | 56 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 55 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index c976cd4b8379..ee461e630527 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -181,7 +181,7 @@ u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg sr)
>  	return v;
>  }
>  
> -static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
> +static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
>  {
>  	int i = sr - __VNCR_START__;
>  
> @@ -191,6 +191,7 @@ static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u
>  
>  int kvm_init_nv_sysregs(struct kvm *kvm)
>  {
> +	u64 res0, res1;
>  	int ret = 0;
>  
>  	mutex_lock(&kvm->arch.config_lock);
> @@ -209,6 +210,59 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
>  		kvm->arch.id_regs[i] = limit_nv_id_reg(IDX_IDREG(i),
>  						       kvm->arch.id_regs[i]);
>  
> +	/* VTTBR_EL2 */
> +	res0 = res1 = 0;
> +	if (!kvm_has_feat_enum(kvm, ID_AA64MMFR1_EL1, VMIDBits, 16))
> +		res0 |= GENMASK(63, 56);
> +	set_sysreg_masks(kvm, VTTBR_EL2, res0, res1);
> +
> +	/* VTCR_EL2 */
> +	res0 = GENMASK(63, 32) | GENMASK(30, 20);
> +	res1 = BIT(31);
> +	set_sysreg_masks(kvm, VTCR_EL2, res0, res1);
> +
> +	/* VMPIDR_EL2 */
> +	res0 = GENMASK(63, 40) | GENMASK(30, 24);
> +	res1 = BIT(31);
> +	set_sysreg_masks(kvm, VMPIDR_EL2, res0, res1);
> +
> +	/* HCR_EL2 */
> +	res0 = BIT(48);
> +	res1 = HCR_RW;

Just want to clarify this bit actually, this is restricting the (first level
only?) nested EL1 to run as AArch64?
Should we be sanitising ID_AA64PFR0_EL1.EL1=0b0001?

> +	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, TWED, IMP))
> +		res0 |= GENMASK(63, 59);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, MTE, MTE2))
> +		res0 |= (HCR_TID5 | HCR_DCT | HCR_ATA);
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, EVT, TTLBxS))
> +		res0 |= (HCR_TTLBIS | HCR_TTLBOS);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, CSV2, CSV2_2) &&
> +	    !kvm_has_feat(kvm, ID_AA64PFR1_EL1, CSV2_frac, CSV2_1p2))
> +		res1 = HCR_ENSCXT;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, EVT, IMP))
> +		res0 |= (HCR_TID4 | HCR_TICAB | HCR_TOCU);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1))
> +		res0 |= HCR_AMVOFFEN;
> +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1))
> +		res0 |= HCR_FIEN;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, FWB, IMP))
> +		res0 |= HCR_FWB;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, NV2))
> +		res0 |= HCR_NV2;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, IMP))
> +		res0 |= (HCR_AT | HCR_NV1 | HCR_NV);
> +	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
> +	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS)))
> +		res0 |= (HCR_API | HCR_APK);
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TME, IMP))
> +		res0 |= BIT(39);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP))
> +		res0 |= (HCR_TERR | HCR_TEA);
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
> +		res0 |= HCR_TLOR;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR4_EL1, E2H0, IMP))
> +		res1 |= HCR_E2H;
> +	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
> +
>  out:
>  	mutex_unlock(&kvm->arch.config_lock);
>  

Thanks,
Joey


From gregkh at linuxfoundation.org  Thu Feb  1 06:57:17 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Thu, 1 Feb 2024 06:57:17 -0800
Subject: [PATCH v2 2/2] serial: mxs-auart: fix tx
In-Reply-To: <3935b841-77b7-4265-a727-98a358cd56be@kernel.org>
References: <20240201105557.28043-1-jirislaby@kernel.org>
 <20240201105557.28043-2-jirislaby@kernel.org>
 <3935b841-77b7-4265-a727-98a358cd56be@kernel.org>
Message-ID: <2024020103-dictation-magma-d8ed@gregkh>

On Thu, Feb 01, 2024 at 01:05:42PM +0100, Jiri Slaby wrote:
> On 01. 02. 24, 11:55, Jiri Slaby (SUSE) wrote:
> > Emil reports:
> >    After updating Linux on an i.MX28 board, serial communication over
> >    AUART broke. When I TX from the board and measure on the TX pin, it
> >    seems like the HW fifo is not emptied before the transmission is
> >    stopped.
> > 
> > MXS performs weird things with stop_tx(). The driver makes it
> > conditional on uart_tx_stopped().
> > 
> > So the driver needs special handling. Pass the brand new UART_TX_NOSTOP
> > to uart_port_tx_flags() and handle the stop on its own.
> > 
> > Signed-off-by: Jiri Slaby (SUSE) <jirislaby at kernel.org>
> > Reported-by: Emil Kronborg <emil.kronborg at protonmail.com>
> > Fixes: 2d141e683e9a ("tty: serial: use uart_port_tx() helper")
> > Closes: https://lore.kernel.org/all/miwgbnvy3hjpnricubg76ytpn7xoceehwahupy25bubbduu23s at om2lptpa26xw/
> 
> Am I unable to send a proper patch anymore?
> 
> I forgot to add mxs+arm maintainers:
> 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
> 
> I can resend with those fixed, if you prefer...

Nah, this is fine, I'll take this as-is, thanks!

greg k-h


From parri.andrea at gmail.com  Thu Feb  1 07:03:48 2024
From: parri.andrea at gmail.com (Andrea Parri)
Date: Thu, 1 Feb 2024 16:03:48 +0100
Subject: [PATCH RFC/RFT v2 4/4] riscv: Stop emitting preventive
 sfence.vma for new userspace mappings with Svvptc
In-Reply-To: <20240131155929.169961-5-alexghiti@rivosinc.com>
References: <20240131155929.169961-1-alexghiti@rivosinc.com>
 <20240131155929.169961-5-alexghiti@rivosinc.com>
Message-ID: <Zbuy1E7mz9Oui1Dl@andrea>

On Wed, Jan 31, 2024 at 04:59:29PM +0100, Alexandre Ghiti wrote:
> The preventive sfence.vma were emitted because new mappings must be made
> visible to the page table walker but Svvptc guarantees that xRET act as
> a fence, so no need to sfence.vma for the uarchs that implement this
> extension.

AFAIU, your first submission shows that you don't need that xRET property.
Similarly for other archs.  What was rationale behind this Svvptc change?


> This allows to drastically reduce the number of sfence.vma emitted:
> 
> * Ubuntu boot to login:
> Before: ~630k sfence.vma
> After:  ~200k sfence.vma
> 
> * ltp - mmapstress01
> Before: ~45k
> After:  ~6.3k
> 
> * lmbench - lat_pagefault
> Before: ~665k
> After:   832 (!)
> 
> * lmbench - lat_mmap
> Before: ~546k
> After:   718 (!)

This Svvptc seems to move/add the "burden" of the synchronization to xRET:
Perhaps integrate the above counts w/ the perf gains in the cover letter?

  Andrea


From stefan.wiehler at nokia.com  Thu Feb  1 07:03:59 2024
From: stefan.wiehler at nokia.com (Stefan Wiehler)
Date: Thu, 1 Feb 2024 16:03:59 +0100
Subject: [PATCH RESEND] arm: topology: Fix missing clock-frequency
 property warning
In-Reply-To: <dfccb849-67b6-489b-8e83-3df1f9b29877@linaro.org>
References: <20240201123605.3037829-2-stefan.wiehler@nokia.com>
 <dfccb849-67b6-489b-8e83-3df1f9b29877@linaro.org>
Message-ID: <9da01fb1-9bab-436b-af49-783e44821b26@nokia.com>

> Does this mean the /cpus property is like a default for when a CPU node
> doesn't specify the clock frequency, or does it mean that the /cpus
> property should only exist when all the values for each CPU are
> identical and thus the individual CPU node clock frequency should
> not be specified.

Good question, the device tree specification in Section 3.7 [1] says:

 > The /cpus node may contain properties that are common across cpu
nodes. See Section 3.8 for details.

And in Section 3.8 [2]:

 > Properties that have identical values across cpu nodes may be placed
 > in the /cpus node instead. A client program must first examine a
 > specific cpu node, but if an expected property is not found then it
 > should look at the parent /cpus node. This results in a less verbose
 > representation of properties which are identical across all CPUs.

So I think it is pretty clear that it should only be used for 
common/identical values.

> Aren't you adding new property? Is it already documented in the
> bindings? After a quick look I think this is not documented.

You are right, clock-frequency is not mentioned neither in arm/cpus.yaml 
nor in any other <arch>/cpus.yaml binding, but the DT spec has it as a 
required property [3]. Should I add clock-frequency to all 
<arch>/cpus.yaml bindings? Only the ARM one explicitly mentions 
following the DT spec.

Kind regards,

Stefan

[1] 
https://devicetree-specification.readthedocs.io/en/latest/chapter3-devicenodes.html#cpus-node-properties
[2] 
https://devicetree-specification.readthedocs.io/en/latest/chapter3-devicenodes.html#cpus-cpu-node-properties
[3] 
https://devicetree-specification.readthedocs.io/en/latest/chapter3-devicenodes.html#general-properties-of-cpus-cpu-nodes


From arnaud.pouliquen at foss.st.com  Thu Feb  1 07:06:37 2024
From: arnaud.pouliquen at foss.st.com (Arnaud POULIQUEN)
Date: Thu, 1 Feb 2024 16:06:37 +0100
Subject: [PATCH v2 4/4] remoteproc: stm32: Add support of an OP-TEE TA to
 load the firmware
In-Reply-To: <ZbqW5YfDmEWG4G1X@p14s>
References: <20240118100433.3984196-1-arnaud.pouliquen@foss.st.com>
 <20240118100433.3984196-5-arnaud.pouliquen@foss.st.com>
 <ZbPnsJm67G10+HQ3@p14s> <7ec6c9e8-9267-4e7c-81a4-abcdb2ab4239@foss.st.com>
 <ZbqW5YfDmEWG4G1X@p14s>
Message-ID: <8ede77bb-0fbc-4de2-b51b-67674744b551@foss.st.com>

hello Mathieu,

On 1/31/24 19:52, Mathieu Poirier wrote:
> On Tue, Jan 30, 2024 at 10:13:48AM +0100, Arnaud POULIQUEN wrote:
>>
>>
>> On 1/26/24 18:11, Mathieu Poirier wrote:
>>> On Thu, Jan 18, 2024 at 11:04:33AM +0100, Arnaud Pouliquen wrote:
>>>> The new TEE remoteproc device is used to manage remote firmware in a
>>>> secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
>>>> introduced to delegate the loading of the firmware to the trusted
>>>> execution context. In such cases, the firmware should be signed and
>>>> adhere to the image format defined by the TEE.
>>>>
>>>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
>>>> ---
>>>> V1 to V2 update:
>>>> - remove the select "TEE_REMOTEPROC" in STM32_RPROC config as detected by
>>>>   the kernel test robot:
>>>>      WARNING: unmet direct dependencies detected for TEE_REMOTEPROC
>>>>      Depends on [n]: REMOTEPROC [=y] && OPTEE [=n]
>>>>      Selected by [y]:
>>>>      - STM32_RPROC [=y] && (ARCH_STM32 || COMPILE_TEST [=y]) && REMOTEPROC [=y]
>>>> - Fix initialized trproc variable in  stm32_rproc_probe
>>>> ---
>>>>  drivers/remoteproc/stm32_rproc.c | 149 +++++++++++++++++++++++++++++--
>>>>  1 file changed, 144 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
>>>> index fcc0001e2657..cf6a21bac945 100644
>>>> --- a/drivers/remoteproc/stm32_rproc.c
>>>> +++ b/drivers/remoteproc/stm32_rproc.c
>>>> @@ -20,6 +20,7 @@
>>>>  #include <linux/remoteproc.h>
>>>>  #include <linux/reset.h>
>>>>  #include <linux/slab.h>
>>>> +#include <linux/tee_remoteproc.h>
>>>>  #include <linux/workqueue.h>
>>>>  
>>>>  #include "remoteproc_internal.h"
>>>> @@ -49,6 +50,9 @@
>>>>  #define M4_STATE_STANDBY	4
>>>>  #define M4_STATE_CRASH		5
>>>>  
>>>> +/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
>>>> +#define STM32_MP1_M4_PROC_ID    0
>>>> +
>>>>  struct stm32_syscon {
>>>>  	struct regmap *map;
>>>>  	u32 reg;
>>>> @@ -90,6 +94,8 @@ struct stm32_rproc {
>>>>  	struct stm32_mbox mb[MBOX_NB_MBX];
>>>>  	struct workqueue_struct *workqueue;
>>>>  	bool hold_boot_smc;
>>>> +	bool fw_loaded;
>>>> +	struct tee_rproc *trproc;
>>>>  	void __iomem *rsc_va;
>>>>  };
>>>>  
>>>> @@ -257,6 +263,91 @@ static int stm32_rproc_release(struct rproc *rproc)
>>>>  	return err;
>>>>  }
>>>>  
>>>> +static int stm32_rproc_tee_elf_sanity_check(struct rproc *rproc,
>>>> +					    const struct firmware *fw)
>>>> +{
>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>> +	unsigned int ret = 0;
>>>> +
>>>> +	if (rproc->state == RPROC_DETACHED)
>>>> +		return 0;
>>>> +
>>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
>>>> +	if (!ret)
>>>> +		ddata->fw_loaded = true;
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +static int stm32_rproc_tee_elf_load(struct rproc *rproc,
>>>> +				    const struct firmware *fw)
>>>> +{
>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>> +	unsigned int ret;
>>>> +
>>>> +	/*
>>>> +	 * This function can be called by remote proc for recovery
>>>> +	 * without the sanity check. In this case we need to load the firmware
>>>> +	 * else nothing done here as the firmware has been preloaded for the
>>>> +	 * sanity check to be able to parse it for the resource table.
>>>> +	 */
>>>
>>> This comment is very confusing - please consider refactoring.  
>>>
>>>> +	if (ddata->fw_loaded)
>>>> +		return 0;
>>>> +
>>>
>>> I'm not sure about keeping a flag to indicate the status of the loaded firmware.
>>> It is not done for the non-secure method, I don't see why it would be needed for
>>> the secure one.
>>>
>>
>> The difference is on the sanity check.
>> - in rproc_elf_sanity_check we  parse the elf file to verify that it is
>> valid.
>> - in stm32_rproc_tee_elf_sanity_check we have to do the same, that means to
>> authenticate it. the authentication is done during the load.
>>
>> So this flag is used to avoid to reload it twice time.
>> refactoring the comment should help to understand this flag
>>
>>
>> An alternative would be to bypass the sanity check. But this lead to same
>> limitation.
>> Before loading the firmware in remoteproc_core, we call rproc_parse_fw() that is
>> used to get the resource table address. To get it from tee we need to
>> authenticate the firmware so load it...
>>
> 
> I spent a long time thinking about this patchset.  Looking at the code as it
> is now, request_firmware() in rproc_boot() is called even when the TEE is
> responsible for loading the firmware.  There should be some conditional code
> that calls either request_firmware() or tee_rproc_load_fw().  The latter should
> also be renamed to tee_rproc_request_firmware() to avoid confusion.


The request_firmware() call is needed in both cases to get the image from the
filesystem. The tee_rproc_load_fw() gets, as input, the struct firmware provided
by request_firmware().

If we want to integrate in remoteproc_core the solution could probably have to
create the equivalent of the rproc_fw_boot() to load the firmware with an
external method. Here is an example based on a new rproc_ops ( not tested)

+ static int rproc_fw_ext_boot(struct rproc *rproc, const struct firmware *fw)
+ {
+ 	struct device *dev = &rproc->dev;
+ 	const char *name = rproc->firmware;
+ 	int ret;
+
+
+ 	dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size);
+ 	
+ 	/* ops to load and start the remoteprocessor */
+ 	ret = rproc->ops->boot(rproc, fw);
+ 	if (ret)
+ 		return ret;
+
+ 	/*
+ 	 * if enabling an IOMMU isn't relevant for this rproc, this is
+ 	 * just a nop
+ 	 */
+ 	ret = rproc_enable_iommu(rproc);
+ 	if (ret) {
+ 		dev_err(dev, "can't enable iommu: %d\n", ret);
+ 		return ret;
+ 	}
+
+ 	/* Prepare rproc for firmware loading if needed */
+ 	ret = rproc_prepare_device(rproc);
+ 	if (ret) {
+ 		dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
+ 		goto disable_iommu;
+ 	}
+
+ 	ret = rproc_set_rsc_table(rproc);
+ 	if (ret) {
+ 		dev_err(dev, "can't load resource table: %d\n", ret);
+ 		goto unprepare_device;
+ 	}
+
+
+ 	/* reset max_notifyid */
+ 	rproc->max_notifyid = -1;
+
+ 	/* reset handled vdev */
+ 	rproc->nb_vdev = 0;
+
+ 	/* handle fw resources which are required to boot rproc */
+ 	ret = rproc_handle_resources(rproc, rproc_loading_handlers);
+ 	if (ret) {
+ 		dev_err(dev, "Failed to process resources: %d\n", ret);
+ 		goto clean_up_resources;
+ 	}
+
+ 	/* Allocate carveout resources associated to rproc */
+ 	ret = rproc_alloc_registered_carveouts(rproc);
+ 	if (ret) {
+ 		dev_err(dev, "Failed to allocate associated carveouts: %d\n",
+ 			ret);
+ 		goto clean_up_resources;
+ 	}
+
+ 	return 0;
+
+ clean_up_resources:
+ 	rproc_resource_cleanup(rproc);
+ unprepare_rproc:
+ 	/* release HW resources if needed */
+ 	rproc_unprepare_device(rproc);
+ disable_iommu:
+ 	rproc_disable_iommu(rproc);
+ 	return ret;
+ }


int rproc_boot(struct rproc *rproc)
{
[...]

- 		ret = rproc_fw_boot(rproc, firmware_p);
+ 		if(rproc->ops->boot)
+ 			ret = rproc_fw_ext_boot(rproc, firmware_p);
+ 		else
+ 			ret = rproc_fw_boot(rproc, firmware_p);

Another advantage of this solution is that it opens the framework to other
formats. For instance it could be a way to support dtb format requested in [RFC]
Passing device-tree to remoteproc [1].

[1]
https://lore.kernel.org/linux-remoteproc/f67cd822-4e29-71f2-7c42-e11dbaa6cd8c at kalrayinc.com/T/#t

Thanks,
Arnaud



> 
> I touched on that before but please rename rproc_tee_get_rsc_table() to
> rproc_tee_elf_load_rsc_table().  I also suggest to introduce a new function,
> rproc_tee_get_loaded_rsc_table() that would be called from
> rproc_tee_elf_load_rsc_table().  That way we don't need trproc->rsc_va.  
> 
> I also think tee_rproc should be renamed to "rproc_tee_interface" and folded
> under struct rproc.  
> 
> With the above most of the problems with the current implementation should
> naturally go away.
> 
> Thanks,
> Mathieu
> 
>>
>>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +	ddata->fw_loaded = true;
>>>> +
>>>> +	/* Update the resource table parameters. */
>>>> +	if (rproc_tee_get_rsc_table(ddata->trproc)) {
>>>> +		/* No resource table: reset the related fields. */
>>>> +		rproc->cached_table = NULL;
>>>> +		rproc->table_ptr = NULL;
>>>> +		rproc->table_sz = 0;
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static struct resource_table *
>>>> +stm32_rproc_tee_elf_find_loaded_rsc_table(struct rproc *rproc,
>>>> +					  const struct firmware *fw)
>>>> +{
>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>> +
>>>> +	return tee_rproc_get_loaded_rsc_table(ddata->trproc);
>>>> +}
>>>> +
>>>> +static int stm32_rproc_tee_start(struct rproc *rproc)
>>>> +{
>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>> +
>>>> +	return tee_rproc_start(ddata->trproc);
>>>> +}
>>>> +
>>>> +static int stm32_rproc_tee_attach(struct rproc *rproc)
>>>> +{
>>>> +	/* Nothing to do, remote proc already started by the secured context. */
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int stm32_rproc_tee_stop(struct rproc *rproc)
>>>> +{
>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>> +	int err;
>>>> +
>>>> +	stm32_rproc_request_shutdown(rproc);
>>>> +
>>>> +	err = tee_rproc_stop(ddata->trproc);
>>>> +	if (err)
>>>> +		return err;
>>>> +
>>>> +	ddata->fw_loaded = false;
>>>> +
>>>> +	return stm32_rproc_release(rproc);
>>>> +}
>>>> +
>>>>  static int stm32_rproc_prepare(struct rproc *rproc)
>>>>  {
>>>>  	struct device *dev = rproc->dev.parent;
>>>> @@ -319,7 +410,14 @@ static int stm32_rproc_prepare(struct rproc *rproc)
>>>>  
>>>>  static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
>>>>  {
>>>> -	if (rproc_elf_load_rsc_table(rproc, fw))
>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>> +	int ret;
>>>> +
>>>> +	if (ddata->trproc)
>>>> +		ret = rproc_tee_get_rsc_table(ddata->trproc);
>>>> +	else
>>>> +		ret = rproc_elf_load_rsc_table(rproc, fw);
>>>> +	if (ret)
>>>>  		dev_warn(&rproc->dev, "no resource table found for this firmware\n");
>>>>  
>>>>  	return 0;
>>>> @@ -693,8 +791,22 @@ static const struct rproc_ops st_rproc_ops = {
>>>>  	.get_boot_addr	= rproc_elf_get_boot_addr,
>>>>  };
>>>>  
>>>> +static const struct rproc_ops st_rproc_tee_ops = {
>>>> +	.prepare	= stm32_rproc_prepare,
>>>> +	.start		= stm32_rproc_tee_start,
>>>> +	.stop		= stm32_rproc_tee_stop,
>>>> +	.attach		= stm32_rproc_tee_attach,
>>>> +	.kick		= stm32_rproc_kick,
>>>> +	.parse_fw	= stm32_rproc_parse_fw,
>>>> +	.find_loaded_rsc_table = stm32_rproc_tee_elf_find_loaded_rsc_table,
>>>> +	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
>>>> +	.sanity_check	= stm32_rproc_tee_elf_sanity_check,
>>>> +	.load		= stm32_rproc_tee_elf_load,
>>>> +};
>>>> +
>>>>  static const struct of_device_id stm32_rproc_match[] = {
>>>> -	{ .compatible = "st,stm32mp1-m4" },
>>>> +	{.compatible = "st,stm32mp1-m4",},
>>>> +	{.compatible = "st,stm32mp1-m4-tee",},
>>>>  	{},
>>>>  };
>>>>  MODULE_DEVICE_TABLE(of, stm32_rproc_match);
>>>> @@ -853,6 +965,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>  	struct device *dev = &pdev->dev;
>>>>  	struct stm32_rproc *ddata;
>>>>  	struct device_node *np = dev->of_node;
>>>> +	struct tee_rproc *trproc = NULL;
>>>>  	struct rproc *rproc;
>>>>  	unsigned int state;
>>>>  	int ret;
>>>> @@ -861,11 +974,31 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>  	if (ret)
>>>>  		return ret;
>>>>  
>>>> -	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
>>>> -	if (!rproc)
>>>> -		return -ENOMEM;
>>>> +	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
>>>> +		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
>>>> +		if (IS_ERR(trproc)) {
>>>> +			dev_err_probe(dev, PTR_ERR(trproc),
>>>> +				      "signed firmware not supported by TEE\n");
>>>> +			return PTR_ERR(trproc);
>>>> +		}
>>>> +		/*
>>>> +		 * Delegate the firmware management to the secure context.
>>>> +		 * The firmware loaded has to be signed.
>>>> +		 */
>>>> +		dev_info(dev, "Support of signed firmware only\n");
>>>
>>> Not sure what this adds.  Please remove.
>>
>> This is used to inform the user that only a signed firmware can be loaded, not
>> an ELF file.
>> I have a patch in my pipe to provide the supported format in the debugfs. In a
>> first step, I can suppress this message and we can revisit the issue when I push
>> the debugfs proposal.
>>
>> Thanks,
>> Arnaud
>>
>>>
>>>> +	}
>>>> +	rproc = rproc_alloc(dev, np->name,
>>>> +			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
>>>> +			    NULL, sizeof(*ddata));
>>>> +	if (!rproc) {
>>>> +		ret = -ENOMEM;
>>>> +		goto free_tee;
>>>> +	}
>>>>  
>>>>  	ddata = rproc->priv;
>>>> +	ddata->trproc = trproc;
>>>> +	if (trproc)
>>>> +		trproc->rproc = rproc;
>>>>  
>>>>  	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
>>>>  
>>>> @@ -916,6 +1049,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>  		device_init_wakeup(dev, false);
>>>>  	}
>>>>  	rproc_free(rproc);
>>>> +free_tee:
>>>> +	if (trproc)
>>>> +		tee_rproc_unregister(trproc);
>>>> +
>>>>  	return ret;
>>>>  }
>>>>  
>>>> @@ -937,6 +1074,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
>>>>  		device_init_wakeup(dev, false);
>>>>  	}
>>>>  	rproc_free(rproc);
>>>> +	if (ddata->trproc)
>>>> +		tee_rproc_unregister(ddata->trproc);
>>>>  }
>>>>  
>>>>  static int stm32_rproc_suspend(struct device *dev)
>>>> -- 
>>>> 2.25.1
>>>>


From brgl at bgdev.pl  Thu Feb  1 07:06:47 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 1 Feb 2024 16:06:47 +0100
Subject: [RESEND PATCH v6 00/12] arm64: qcom: add and enable SHM Bridge support
In-Reply-To: <20240122102157.22761-1-brgl@bgdev.pl>
References: <20240122102157.22761-1-brgl@bgdev.pl>
Message-ID: <CAMRc=MfURBi=5frjL2EB0M-bzoiXU-5do+gtWDKqK9fp48HvXA@mail.gmail.com>

On Mon, Jan 22, 2024 at 11:22?AM Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>
> Resending after the merge window. I dropped the first patch which was a
> fix and was picked up last release cycle.
>
> We've established the need for using separate secured memory pools for
> SCM and QSEECOM as well as the upcoming scminvoke driver.
>
> It's also become clear that in order to be future-proof, the new
> allocator must be an abstraction layer of a higher level as the SHM
> Bridge will not be the only memory protection mechanism that we'll see
> upstream. Hence the rename to TrustZone Memory rather than SCM Memory
> allocator.
>
> Also to that end: the new allocator is its own module now and provides a
> Kconfig choice menu for selecting the mode of operation (currently
> default and SHM Bridge).
>
> Tested on sm8550 and sa8775p with the Inline Crypto Engine and
> remoteproc.
>
> v5 -> v6:
> Fixed two issues reported by autobuilders:
> - add a fix for memory leaks in the qseecom driver as the first patch for
>   easier backporting to the v6.6.y branch
> - explicitly cast the bus address stored in a variable of type dma_addr_t
>   to phys_addr_t expected by the genpool API
>
> v4 -> v5:
> - fix the return value from qcom_tzmem_init() if SHM Bridge is not supported
> - remove a comment that's no longer useful
> - collect tags
>
> v3 -> v4:
> - include linux/sizes.h for SZ_X macros
> - use dedicated RCU APIs to dereference radix tree slots
> - fix kerneldocs
> - fix the comment in patch 14/15: it's the hypervisor, not the TrustZone
>   that creates the SHM bridge
>
> v2 -> v3:
> - restore pool management and use separate pools for different users
> - don't use the new allocator in qcom_scm_pas_init_image() as the
>   TrustZone will create an SHM bridge for us here
> - rewrite the entire series again for most part
>
> v1 -> v2:
> - too many changes to list, it's a complete rewrite as explained above
>
> Bartosz Golaszewski (12):
>   firmware: qcom: add a dedicated TrustZone buffer allocator
>   firmware: qcom: scm: enable the TZ mem allocator
>   firmware: qcom: scm: smc: switch to using the SCM allocator
>   firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ
>     allocator
>   firmware: qcom: qseecom: convert to using the TZ allocator
>   firmware: qcom: scm: add support for SHM bridge operations
>   firmware: qcom: tzmem: enable SHM Bridge support
>   firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
>   arm64: defconfig: enable SHM Bridge support for the TZ memory
>     allocator
>
>  MAINTAINERS                                   |   8 +
>  arch/arm64/configs/defconfig                  |   1 +
>  drivers/firmware/qcom/Kconfig                 |  30 ++
>  drivers/firmware/qcom/Makefile                |   1 +
>  .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++---------
>  drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
>  drivers/firmware/qcom/qcom_scm.c              | 179 +++++----
>  drivers/firmware/qcom/qcom_scm.h              |   6 +
>  drivers/firmware/qcom/qcom_tzmem.c            | 365 ++++++++++++++++++
>  drivers/firmware/qcom/qcom_tzmem.h            |  13 +
>  include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
>  include/linux/firmware/qcom/qcom_scm.h        |   6 +
>  include/linux/firmware/qcom/qcom_tzmem.h      |  28 ++
>  13 files changed, 684 insertions(+), 268 deletions(-)
>  create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
>  create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
>  create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h
>
> --
> 2.40.1
>

Bjorn,

I tested it on db410c as well so let me gently ping you about picking
it up into your tree.

Bartosz


From apatel at ventanamicro.com  Thu Feb  1 07:07:22 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 1 Feb 2024 20:37:22 +0530
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <87fryeognc.fsf@all.your.base.are.belong.to.us>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <87r0hzuw87.fsf@all.your.base.are.belong.to.us> <87le87uulb.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2UYCKUBKggtM606orH2mBu_AbTdB5-R5AP1M0t-LsEbEQ@mail.gmail.com>
 <87cytjvybb.fsf@all.your.base.are.belong.to.us> <87ttmuq3m7.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2UEpbd+pHAMg-AuP-fTPZVho16u69oSjOHhsR11HTwiew@mail.gmail.com> <87fryeognc.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAK9=C2UX0sRb5UbLdm8xwe1dP=x+enJRYzAuCPf6MdHTLTC_Cw@mail.gmail.com>

On Tue, Jan 30, 2024 at 11:19?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Anup Patel <apatel at ventanamicro.com> writes:
>
> > On Tue, Jan 30, 2024 at 8:18?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
> >>
> >> Bj?rn T?pel <bjorn at kernel.org> writes:
> >>
> >> > Anup Patel <apatel at ventanamicro.com> writes:
> >> >
> >> >> On Tue, Jan 30, 2024 at 1:22?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
> >> >>>
> >> >>> Bj?rn T?pel <bjorn at kernel.org> writes:
> >> >>>
> >> >>> > Anup Patel <apatel at ventanamicro.com> writes:
> >> >>> >
> >> >>> >> The RISC-V AIA specification is ratified as-per the RISC-V international
> >> >>> >> process. The latest ratified AIA specifcation can be found at:
> >> >>> >> https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf
> >> >>> >>
> >> >>> >> At a high-level, the AIA specification adds three things:
> >> >>> >> 1) AIA CSRs
> >> >>> >>    - Improved local interrupt support
> >> >>> >> 2) Incoming Message Signaled Interrupt Controller (IMSIC)
> >> >>> >>    - Per-HART MSI controller
> >> >>> >>    - Support MSI virtualization
> >> >>> >>    - Support IPI along with virtualization
> >> >>> >> 3) Advanced Platform-Level Interrupt Controller (APLIC)
> >> >>> >>    - Wired interrupt controller
> >> >>> >>    - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
> >> >>> >>    - In Direct-mode, injects external interrupts directly into HARTs
> >> >>> >>
> >> >>> >> For an overview of the AIA specification, refer the AIA virtualization
> >> >>> >> talk at KVM Forum 2022:
> >> >>> >> https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
> >> >>> >> https://www.youtube.com/watch?v=r071dL8Z0yo
> >> >>> >>
> >> >>> >> To test this series, use QEMU v7.2 (or higher) and OpenSBI v1.2 (or higher).
> >> >>> >>
> >> >>> >> These patches can also be found in the riscv_aia_v12 branch at:
> >> >>> >> https://github.com/avpatel/linux.git
> >> >>> >>
> >> >>> >> Changes since v11:
> >> >>> >>  - Rebased on Linux-6.8-rc1
> >> >>> >>  - Included kernel/irq related patches from "genirq, irqchip: Convert ARM
> >> >>> >>    MSI handling to per device MSI domains" series by Thomas.
> >> >>> >>    (PATCH7, PATCH8, PATCH9, PATCH14, PATCH16, PATCH17, PATCH18, PATCH19,
> >> >>> >>     PATCH20, PATCH21, PATCH22, PATCH23, and PATCH32 of
> >> >>> >>     https://lore.kernel.org/linux-arm-kernel/20221121135653.208611233 at linutronix.de/)
> >> >>> >>  - Updated APLIC MSI-mode driver to use the new WIRED_TO_MSI mechanism.
> >> >>> >>  - Updated IMSIC driver to support per-device MSI domains for PCI and
> >> >>> >>    platform devices.
> >> >>> >
> >> >>> > Thanks for working on this, Anup! I'm still reviewing the patches.
> >> >>> >
> >> >>> > I'm hitting a boot hang in text patching, with this series applied on
> >> >>> > 6.8-rc2. IPI issues?
> >> >>>
> >> >>> Not text patching! One cpu spinning in smp_call_function_many_cond() and
> >> >>> the others are in cpu_relax(). Smells like IPI...
> >> >>
> >> >> I tried bootefi from U-Boot multiple times but can't reproduce the
> >> >> issue you are seeing.
> >> >
> >> > Thanks! I can reproduce without EFI, and simpler command-line:
> >> >
> >> > qemu-system-riscv64 \
> >> >   -bios /path/to/fw_dynamic.bin \
> >> >   -kernel /path/to/Image \
> >> >   -append 'earlycon console=tty0 console=ttyS0' \
> >> >   -machine virt,aia=aplic-imsic \
> >> >   -no-reboot -nodefaults -nographic \
> >> >   -smp 4 \
> >> >   -object rng-random,filename=/dev/urandom,id=rng0 \
> >> >   -device virtio-rng-device,rng=rng0 \
> >> >   -m 4G -chardev stdio,id=char0 -serial chardev:char0
> >> >
> >> > I can reproduce with your upstream riscv_aia_v12 plus the config in the
> >> > gist [1], and all latest QEMU/OpenSBI:
> >> >
> >> > QEMU: 11be70677c70 ("Merge tag 'pull-vfio-20240129' of https://github.com/legoater/qemu into staging")
> >> > OpenSBI: bb90a9ebf6d9 ("lib: sbi: Print number of debug triggers found")
> >> > Linux: d9b9d6eb987f ("MAINTAINERS: Add entry for RISC-V AIA drivers")
> >> >
> >> > Removing ",aia=aplic-imsic" from the CLI above completes the boot (i.e.
> >> > panicking about missing root mount ;-))
> >>
> >> More context; The hang is during a late initcall, where an ftrace direct
> >> (register_ftrace_direct()) modification is done.
> >>
> >> Stop machine is used to call into __ftrace_modify_call(). Then into the
> >> arch specific patch_text_nosync(), where flush_icache_range() hangs in
> >> flush_icache_all(). From "on_each_cpu(ipi_remote_fence_i, NULL, 1);" to
> >> on_each_cpu_cond_mask() "smp_call_function_many_cond(mask, func, info,
> >> scf_flags, cond_func);" which never returns from "csd_lock_wait(csd)"
> >> right before the end of the function.
> >>
> >> Any ideas? Disabling CONFIG_HID_BPF, that does the early ftrace code
> >> patching fixes the boot hang, but it does seem related to IPI...
> >>
> > Looks like flush_icache_all() does not use the IPIs (on_each_cpu()
> > and friends) correctly.
> >
> > On other hand, the flush_icache_mm() does the right thing by
> > doing local flush on the current CPU and IPI based flush on other
> > CPUs.
> >
> > Can you try the following patch ?
> >
> > diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
> > index 55a34f2020a8..a3dfbe4de832 100644
> > --- a/arch/riscv/mm/cacheflush.c
> > +++ b/arch/riscv/mm/cacheflush.c
> > @@ -19,12 +19,18 @@ static void ipi_remote_fence_i(void *info)
> >
> >  void flush_icache_all(void)
> >  {
> > +    cpumask_t others;
> > +
> >      local_flush_icache_all();
> >
> > +    cpumask_andnot(&others, cpu_online_mask, cpumask_of(smp_processor_id()));
> > +    if (cpumask_empty(&others))
> > +        return;
> > +
> >      if (IS_ENABLED(CONFIG_RISCV_SBI) && !riscv_use_ipi_for_rfence())
> > -        sbi_remote_fence_i(NULL);
> > +        sbi_remote_fence_i(&others);
> >      else
> > -        on_each_cpu(ipi_remote_fence_i, NULL, 1);
> > +        on_each_cpu_mask(&others, ipi_remote_fence_i, NULL, 1);
> >  }
> >  EXPORT_SYMBOL(flush_icache_all);
>
> Unfortunately, I see the same hang. LMK if you'd like me to try anything
> else.

I was able to reproduce this at my end but I had to use your config.

Digging further, it seems the issue is observed only when we use
in-kernel IPIs for cache flushing (instead of SBI calls) along with
some of the tracers (or debugging features) enabled. With the tracers
(or debug features) disabled we don't see any issue. In fact, the
upstream defconfig works perfectly fine with AIA drivers and
in-kernel IPIs.

It seems AIA based in-kernel IPIs are exposing some other issue
with RISC-V kernel. I will debug more to find the root cause.

Regards,
Anup


From afd at ti.com  Thu Feb  1 07:12:19 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 09:12:19 -0600
Subject: [PATCH v2 2/2] arm64: dts: ti: k3-j784s4: Fix power domain for
 VTM node
In-Reply-To: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-2-85fd568b77e3@ti.com>
References: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-0-85fd568b77e3@ti.com>
 <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-2-85fd568b77e3@ti.com>
Message-ID: <82349e32-ed8e-4952-bf80-3f5319f32a45@ti.com>

On 2/1/24 2:07 AM, Manorit Chawdhry wrote:
> Fix the power domain device ID for wkup_vtm0 node.
> 
> Link: https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j784s4/devices.html
> Fixes: 64821fbf6738 ("arm64: dts: ti: j784s4: Add VTM node")
> Signed-off-by: Manorit Chawdhry <m-chawdhry at ti.com>
> ---

Reviewed-by: Andrew Davis <afd at ti.com>

>   arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
> index 3902a921d7e5..337122c3f402 100644
> --- a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
> @@ -628,7 +628,7 @@ wkup_vtm0: temperature-sensor at 42040000 {
>   		compatible = "ti,j7200-vtm";
>   		reg = <0x00 0x42040000 0x00 0x350>,
>   		      <0x00 0x42050000 0x00 0x350>;
> -		power-domains = <&k3_pds 154 TI_SCI_PD_SHARED>;
> +		power-domains = <&k3_pds 243 TI_SCI_PD_SHARED>;
>   		#thermal-sensor-cells = <1>;
>   	};
>   
> 


From afd at ti.com  Thu Feb  1 07:23:03 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 09:23:03 -0600
Subject: [PATCH v3 2/5] arm64: dts: ti: k3-am62/a: use sub-node for
 USB_PHY_CTRL registers
In-Reply-To: <20240201120332.4811-3-rogerq@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-3-rogerq@kernel.org>
Message-ID: <c032c8c7-a4f3-4cd0-a96f-dd177ad84ba4@ti.com>

On 2/1/24 6:03 AM, Roger Quadros wrote:
> Exposing the entire CTRL_MMR space to syscon is not a good idea.
> Add sub-nodes for USB0_PHY_CTRL and USB1_PHY_CTRL and use them
> in the USB0/USB1 nodes.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
> 

Reviewed-by: Andrew Davis <afd at ti.com>

> Notes:
>      Changelog:
>      
>      v3 - no change
>      
>      v2:
>      - moved am62p changes to next patch
>      - use new compatible for USB PHY CTRL node
> 
>   arch/arm64/boot/dts/ti/k3-am62-main.dtsi    |  4 ++--
>   arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi  | 10 ++++++++++
>   arch/arm64/boot/dts/ti/k3-am62a-main.dtsi   |  4 ++--
>   arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi | 10 ++++++++++
>   4 files changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> index 464b7565d085..9432ed344d52 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> @@ -625,7 +625,7 @@ usbss0: dwc3-usb at f900000 {
>   		reg = <0x00 0x0f900000 0x00 0x800>;
>   		clocks = <&k3_clks 161 3>;
>   		clock-names = "ref";
> -		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
> +		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
>   		#address-cells = <2>;
>   		#size-cells = <2>;
>   		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
> @@ -648,7 +648,7 @@ usbss1: dwc3-usb at f910000 {
>   		reg = <0x00 0x0f910000 0x00 0x800>;
>   		clocks = <&k3_clks 162 3>;
>   		clock-names = "ref";
> -		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
> +		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
>   		#address-cells = <2>;
>   		#size-cells = <2>;
>   		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
> index fef76f52a52e..817700b2eacf 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
> @@ -19,6 +19,16 @@ chipid: chipid at 14 {
>   			compatible = "ti,am654-chipid";
>   			reg = <0x14 0x4>;
>   		};
> +
> +		usb0_phy_ctrl: syscon at 4008 {
> +			compatible = "ti,am62-usb-phy-ctrl", "syscon";
> +			reg = <0x4008 0x4>;
> +		};
> +
> +		usb1_phy_ctrl: syscon at 4018 {
> +			compatible = "ti,am62-usb-phy-ctrl", "syscon";
> +			reg = <0x4018 0x4>;
> +		};
>   	};
>   
>   	wkup_uart0: serial at 2b300000 {
> diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> index f0b8c9ab1459..8311c7c44cd3 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> @@ -566,7 +566,7 @@ usbss0: dwc3-usb at f900000 {
>   		reg = <0x00 0x0f900000 0x00 0x800>;
>   		clocks = <&k3_clks 161 3>;
>   		clock-names = "ref";
> -		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
> +		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
>   		#address-cells = <2>;
>   		#size-cells = <2>;
>   		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
> @@ -589,7 +589,7 @@ usbss1: dwc3-usb at f910000 {
>   		reg = <0x00 0x0f910000 0x00 0x800>;
>   		clocks = <&k3_clks 162 3>;
>   		clock-names = "ref";
> -		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
> +		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
>   		#address-cells = <2>;
>   		#size-cells = <2>;
>   		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
> diff --git a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
> index 4e8279fa01e1..4a375f5e0c19 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
> @@ -17,6 +17,16 @@ chipid: chipid at 14 {
>   			compatible = "ti,am654-chipid";
>   			reg = <0x14 0x4>;
>   		};
> +
> +		usb0_phy_ctrl: syscon at 4008 {
> +			compatible = "ti,am62-usb-phy-ctrl", "syscon";
> +			reg = <0x4008 0x4>;
> +		};
> +
> +		usb1_phy_ctrl: syscon at 4018 {
> +			compatible = "ti,am62-usb-phy-ctrl", "syscon";
> +			reg = <0x4018 0x4>;
> +		};
>   	};
>   
>   	wkup_uart0: serial at 2b300000 {


From andre.draszik at linaro.org  Thu Feb  1 07:23:37 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Thu, 01 Feb 2024 15:23:37 +0000
Subject: [PATCH v2 5/6] clk: samsung: gs101: don't mark non-essential
 clocks as critical
In-Reply-To: <8dfab6a9-f9d1-46c2-8bd1-6ead4b26fbe1@linaro.org>
References: <20240130093812.1746512-1-andre.draszik@linaro.org>
	 <20240130093812.1746512-6-andre.draszik@linaro.org>
	 <8dfab6a9-f9d1-46c2-8bd1-6ead4b26fbe1@linaro.org>
Message-ID: <5d696d79d453c6b77f4ebc2d91256e4de6cd5ef5.camel@linaro.org>

Hi Krzysztof,

On Thu, 2024-02-01 at 11:02 +0100, Krzysztof Kozlowski wrote:
> On 30/01/2024 10:36, Andr? Draszik wrote:
> > The peric0_top1_ipclk_0 and peric0_top1_pclk_0 are the clocks going to
> > peric0/uart_usi, with pclk being the bus clock. Without pclk running,
> > any bus access will hang.
> > Unfortunately, in commit d97b6c902a40 ("arm64: dts: exynos: gs101:
> > update USI UART to use peric0 clocks") the gs101 DT ended up specifying
> > an incorrect pclk in the respective node and instead the two clocks
> > here were marked as critical.
> > 
> > We have fixed the gs101 DT and can therefore drop this incorrect
> > work-around here, the uart driver will claim these clocks as needed.
> 
> How did you fixed the DTS? Which commit did it? Are we going back to
> basics of driver changes depending on DTS?

Sorry if the description isn't clear.

a) these clocks are not critical for the system to work, and this patch fixes that.
b) the initial DTSI for gs101 used incorrect clocks for the serial, and it didn't
work. The work-around was to specify these clocks here as critical instead. Patch
#4 in this series has corrected the DTSI.

So there is no dependency between the DTS update and the driver update here as such,
no new properties, or otherwise.

That said, now that b) above has been fixed (in patch #4), it is OK to mark these
clocks as non-critical without any ill effects. That's all that is happening. I was
merely referencing that in the commit message.

I can rephrase things if you wish.


Cheers,
Andre'



From didi.debian at cknow.org  Thu Feb  1 07:28:15 2024
From: didi.debian at cknow.org (Diederik de Haas)
Date: Thu, 01 Feb 2024 16:28:15 +0100
Subject: [PATCH v4 4/4] arm64: dts: rockchip: Add devicetree for Pine64 PineTab2
In-Reply-To: <20240127-pinetab2-v4-4-37aab1c39194@mecka.net>
References: <20240127-pinetab2-v4-0-37aab1c39194@mecka.net>
 <20240127-pinetab2-v4-4-37aab1c39194@mecka.net>
Message-ID: <13234147.MA61SxHe9P@bagend>

On Saturday, 27 January 2024 10:48:45 CET Manuel Traut wrote:
> This includes support for both the v0.1 units that were sent to developers
> and the v2.0 units from production.
> 
> v1.0 is not included as no units are known to exist.
> 
> Working/Tested:
> - SDMMC
> - UART
> - Buttons
> - Charging/Battery/PMIC
> - Audio
> - USB
> - Display
> - SPI NOR Flash
> 
> Signed-off-by: Alexander Warnecke <awarnecke002 at hotmail.com>
> Signed-off-by: Manuel Traut <manut at mecka.net>

Everything seems to (still) work, so:
Tested-By: Diederik de Haas <didi.debian at cknow.org>

Thanks for submitting this upstream :-)

Cheers,
  Diederik
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240201/52af9cdd/attachment.sig>

From avromanov at salutedevices.com  Thu Feb  1 07:30:33 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Thu, 1 Feb 2024 15:30:33 +0000
Subject: [PATCH v1] arch: arm64: dts: meson: a1: add assigned-clocks for
 usb node
In-Reply-To: <20240124130623.3471236-1-avromanov@salutedevices.com>
References: <20240124130623.3471236-1-avromanov@salutedevices.com>
Message-ID: <20240201153027.ecxqx3ehh6tbkgrc@cab-wsm-0029881>

Hello! Ping.

On Wed, Jan 24, 2024 at 04:06:23PM +0300, Alexey Romanov wrote:
> To ensure proper functionality of USB, it is necessary to use
> the rate of 64000000 for CLKID_USB_BUS. For instance, adb may
> not function correctly without this setting. This information
> has been derived from the vendor SDK.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> Signed-off-by: Dmitry Rokosov <ddrokosov at salutedevices.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> index cf150f568335..b9fd69112535 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> @@ -668,6 +668,8 @@ usb: usb at fe004400 {
>  				 <&clkc_periphs CLKID_USB_BUS>,
>  				 <&clkc_periphs CLKID_USB_CTRL_IN>;
>  			clock-names = "usb_ctrl", "usb_bus", "xtal_usb_ctrl";
> +			assigned-clocks = <&clkc_periphs CLKID_USB_BUS>;
> +			assigned-clock-rates = <64000000>;
>  			resets = <&reset RESET_USBCTRL>;
>  			reset-name = "usb_ctrl";
>  
> -- 
> 2.34.1
> 

-- 
Thank you,
Alexey

From dave.stevenson at raspberrypi.com  Thu Feb  1 07:33:24 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Thu, 1 Feb 2024 15:33:24 +0000
Subject: [PATCH v5 15/44] drm/connector: hdmi: Compute bpc and format automatically
In-Reply-To: <jlkoofv7nszj2uqmo2672yo4wjd3yjqarge2l2hxofixcchu6a@j72pa4iybitd>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-15-6538e19d634d@kernel.org>
 <CAPY8ntBQ+qY9441-rMzq_JAoYAaY_r+E-ADv7Wry0tJNTzKpwg@mail.gmail.com> <jlkoofv7nszj2uqmo2672yo4wjd3yjqarge2l2hxofixcchu6a@j72pa4iybitd>
Message-ID: <CAPY8ntAmXyKtebMeM7rLtgRR+QwL1H+UCwSO=bLBQN4TsgwsDg@mail.gmail.com>

Hi Maxime

On Thu, 1 Feb 2024 at 12:51, Maxime Ripard <mripard at kernel.org> wrote:
>
> On Thu, Dec 14, 2023 at 03:10:43PM +0000, Dave Stevenson wrote:
> > > +static bool
> > > +sink_supports_format_bpc(const struct drm_connector *connector,
> > > +                        const struct drm_display_info *info,
> > > +                        const struct drm_display_mode *mode,
> > > +                        unsigned int format, unsigned int bpc)
> > > +{
> > > +       struct drm_device *dev = connector->dev;
> > > +       u8 vic = drm_match_cea_mode(mode);
> > > +
> > > +       if (vic == 1 && bpc != 8) {
> > > +               drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
> > > +               return false;
> > > +       }
> > > +
> > > +       if (!info->is_hdmi &&
> > > +           (format != HDMI_COLORSPACE_RGB || bpc != 8)) {
> > > +               drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
> > > +               return false;
> > > +       }
> > > +
> > > +       if (!(connector->hdmi.supported_formats & BIT(format))) {
> > > +               drm_dbg(dev, "%s format unsupported by the connector.\n",
> > > +                       drm_hdmi_connector_get_output_format_name(format));
> > > +               return false;
> > > +       }
> > > +
> > > +       switch (format) {
> > > +       case HDMI_COLORSPACE_RGB:
> > > +               drm_dbg(dev, "RGB Format, checking the constraints.\n");
> > > +
> > > +               if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
> > > +                       return false;
> >
> > We've dropped this check from vc4 in our downstream kernel as it stops
> > you using the prebaked EDIDs (eg drm.edid_firmware=edid/1024x768.bin),
> > or any other EDID that is defined as an analog monitor.
> > The EDID parsing bombs out at [1], so info->color_formats gets left at 0.
>
> Right, but it only does so if the display isn't defined as a digital display...
>
> > RGB is mandatory for both DVI and HDMI, so rejecting it seems overly fussy.
>
> ... which is required for both DVI and HDMI.
>
> And sure enough, if we decode that EDID:
>
> edid-decode (hex):
>
> 00 ff ff ff ff ff ff 00 31 d8 00 00 00 00 00 00
> 05 16 01 03 6d 23 1a 78 ea 5e c0 a4 59 4a 98 25
> 20 50 54 00 08 00 61 40 01 01 01 01 01 01 01 01
> 01 01 01 01 01 01 64 19 00 40 41 00 26 30 08 90
> 36 00 63 0a 11 00 00 18 00 00 00 ff 00 4c 69 6e
> 75 78 20 23 30 0a 20 20 20 20 00 00 00 fd 00 3b
> 3d 2f 31 07 00 0a 20 20 20 20 20 20 00 00 00 fc
> 00 4c 69 6e 75 78 20 58 47 41 0a 20 20 20 00 55
>
> ----------------
>
> Block 0, Base EDID:
>   EDID Structure Version & Revision: 1.3
>   Vendor & Product Identification:
>     Manufacturer: LNX
>     Model: 0
>     Made in: week 5 of 2012
>   Basic Display Parameters & Features:
>     Analog display
>     Signal Level Standard: 0.700 : 0.000 : 0.700 V p-p
>     Blank level equals black level
>     Sync: Separate Composite Serration
>     Maximum image size: 35 cm x 26 cm
>     Gamma: 2.20
>     DPMS levels: Standby Suspend Off
>     RGB color display
>     First detailed timing is the preferred timing
>   Color Characteristics:
>     Red  : 0.6416, 0.3486
>     Green: 0.2919, 0.5957
>     Blue : 0.1474, 0.1250
>     White: 0.3125, 0.3281
>   Established Timings I & II:
>     DMT 0x10:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz
>   Standard Timings:
>     DMT 0x10:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz
>   Detailed Timing Descriptors:
>     DTD 1:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz (355 mm x 266 mm)
>                  Hfront    8 Hsync 144 Hback  168 Hpol N
>                  Vfront    3 Vsync   6 Vback   29 Vpol N
>     Display Product Serial Number: 'Linux #0'
>     Display Range Limits:
>       Monitor ranges (GTF): 59-61 Hz V, 47-49 kHz H, max dotclock 70 MHz
>     Display Product Name: 'Linux XGA'
> Checksum: 0x55
>
> ----------------
>
> Warnings:
>
> Block 0, Base EDID:
>   Detailed Timing Descriptor #1: DTD is similar but not identical to DMT 0x10.
>
> EDID conformity: PASS
>
> So, if anything, it's the EDID that needs to be updated, not the code there.

So are these EDIDs only valid for VGA outputs and another set needs to
be added for HDMI monitors?

Having drm.edid_firmware=edid/1024x768.bin works on an HDMI connector
prior to this patch, so presumably drm_edid_loader needs to
automatically switch between the existing (analog) and new (digital)
EDIDs based on the connector type? Or are you requiring users to
change the strings they use?

Cheers.
  Dave


From neil.armstrong at linaro.org  Thu Feb  1 07:33:36 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Thu, 1 Feb 2024 16:33:36 +0100
Subject: [PATCH v1] arch: arm64: dts: meson: a1: add assigned-clocks for
 usb node
In-Reply-To: <20240124130623.3471236-1-avromanov@salutedevices.com>
References: <20240124130623.3471236-1-avromanov@salutedevices.com>
Message-ID: <7bcfa06b-f426-4575-9359-e97e4af52465@linaro.org>

On 24/01/2024 14:06, Alexey Romanov wrote:
> To ensure proper functionality of USB, it is necessary to use
> the rate of 64000000 for CLKID_USB_BUS. For instance, adb may
> not function correctly without this setting. This information
> has been derived from the vendor SDK.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> Signed-off-by: Dmitry Rokosov <ddrokosov at salutedevices.com>
> ---
>   arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> index cf150f568335..b9fd69112535 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> @@ -668,6 +668,8 @@ usb: usb at fe004400 {
>   				 <&clkc_periphs CLKID_USB_BUS>,
>   				 <&clkc_periphs CLKID_USB_CTRL_IN>;
>   			clock-names = "usb_ctrl", "usb_bus", "xtal_usb_ctrl";
> +			assigned-clocks = <&clkc_periphs CLKID_USB_BUS>;
> +			assigned-clock-rates = <64000000>;
>   			resets = <&reset RESET_USBCTRL>;
>   			reset-name = "usb_ctrl";
>   

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From stefan.wiehler at nokia.com  Thu Feb  1 07:38:11 2024
From: stefan.wiehler at nokia.com (Stefan Wiehler)
Date: Thu,  1 Feb 2024 16:38:11 +0100
Subject: [PATCH] arm64: Print provenance information for addresses in registers
Message-ID: <20240201153811.1793120-1-stefan.wiehler@nokia.com>

Like commit 5aa6b70ed182 ("arm: print alloc free paths for address in
registers") already does for 32-bit ARM, print available provenance information
for addresses in registers in case of internal error as a debugging aid:

  Unable to handle kernel write to read-only memory at virtual address ffffffc00117cd5c
  ...
  x2 : 0000000000001b98 x1 : 0000000000000000 x0 : ffffffc00117cd5c
  ...
  Register x0 information: 14-page vmalloc region starting at 0xffffffc00117a000 allocated at load_module+0x15c4/0x2bc0
  Register x1 information: NULL pointer
  Register x2 information: non-paged memory
  ...

Signed-off-by: Stefan Wiehler <stefan.wiehler at nokia.com>
---
 arch/arm64/include/asm/system_misc.h |  1 +
 arch/arm64/kernel/process.c          | 11 +++++++++++
 arch/arm64/kernel/traps.c            |  1 +
 3 files changed, 13 insertions(+)

diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
index c34344256762..5b9b02fee988 100644
--- a/arch/arm64/include/asm/system_misc.h
+++ b/arch/arm64/include/asm/system_misc.h
@@ -31,6 +31,7 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned long,
 
 struct mm_struct;
 extern void __show_regs(struct pt_regs *);
+extern void __show_regs_alloc_free(struct pt_regs *);
 
 #endif	/* __ASSEMBLY__ */
 
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 7387b68c745b..b6fc2ac6e007 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -197,6 +197,17 @@ static void print_pstate(struct pt_regs *regs)
 	}
 }
 
+void __show_regs_alloc_free(struct pt_regs *regs)
+{
+	int i;
+
+	/* check for x0 - x29 only */
+	for (i = 0; i < 30; i++) {
+		pr_alert("Register x%d information:", i);
+		mem_dump_obj((void *)regs->regs[i]);
+	}
+}
+
 void __show_regs(struct pt_regs *regs)
 {
 	int i, top_reg;
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 215e6d7f2df8..b7bf22f1b33f 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -197,6 +197,7 @@ static int __die(const char *str, long err, struct pt_regs *regs)
 
 	print_modules();
 	show_regs(regs);
+	__show_regs_alloc_free(regs);
 
 	dump_kernel_instr(KERN_EMERG, regs);
 
-- 
2.42.0



From mkl at pengutronix.de  Thu Feb  1 07:38:38 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Thu, 1 Feb 2024 16:38:38 +0100
Subject: [PATCH 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <20240201131540.3dlqoxlrrbzshz7w@runtux.com>
References: <20240201131540.3dlqoxlrrbzshz7w@runtux.com>
Message-ID: <20240201-tributary-fax-dd6055160dbe-mkl@pengutronix.de>

On 01.02.2024 14:15:40, Ralf Schlatterbeck wrote:
> There was a change in the mxs-dma engine that uses a new custom flag.
> The change was not applied to the mxs spi driver.
> This results in chipselect being deasserted too early.
> This fixes the chipselect problem by using the new flag in the mxs-spi
> driver.
> 
> Fixes: ceeeb99cd821 ("dmaengine: mxs: rename custom flag")
> Signed-off-by: Ralf Schlatterbeck <rsc at runtux.com>
> ---
> For oscilloscope screenshots and a verbose explanation see my blog post
> at https://blog.runtux.com/posts/2024/02/01/
> 
>  drivers/spi/spi-mxs.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
> index 1bf080339b5a..a296050c8bd3 100644
> --- a/drivers/spi/spi-mxs.c
> +++ b/drivers/spi/spi-mxs.c
> @@ -39,6 +39,7 @@
>  #include <linux/spi/spi.h>
>  #include <linux/spi/mxs-spi.h>
>  #include <trace/events/spi.h>
> +#include <linux/dma/mxs-dma.h>
>  
>  #define DRIVER_NAME		"mxs-spi"
>  
> @@ -251,8 +252,9 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
>  
>  		desc = dmaengine_prep_slave_sg(ssp->dmach,
>  				&dma_xfer[sg_count].sg, 1,
> -				(flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
> -				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +				(flags & TXRX_WRITE)
> +				? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
> +				DMA_PREP_INTERRUPT | MXS_DMA_CTRL_WAIT4END);

nitpick: Please omit the line break change from this patch.

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |


From mathieu.poirier at linaro.org  Thu Feb  1 08:02:35 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 1 Feb 2024 09:02:35 -0700
Subject: [PATCH v2 4/4] remoteproc: stm32: Add support of an OP-TEE TA to
 load the firmware
In-Reply-To: <8ede77bb-0fbc-4de2-b51b-67674744b551@foss.st.com>
References: <20240118100433.3984196-1-arnaud.pouliquen@foss.st.com>
 <20240118100433.3984196-5-arnaud.pouliquen@foss.st.com>
 <ZbPnsJm67G10+HQ3@p14s>
 <7ec6c9e8-9267-4e7c-81a4-abcdb2ab4239@foss.st.com>
 <ZbqW5YfDmEWG4G1X@p14s>
 <8ede77bb-0fbc-4de2-b51b-67674744b551@foss.st.com>
Message-ID: <ZbvAmxHscnbUQGOD@p14s>

On Thu, Feb 01, 2024 at 04:06:37PM +0100, Arnaud POULIQUEN wrote:
> hello Mathieu,
> 
> On 1/31/24 19:52, Mathieu Poirier wrote:
> > On Tue, Jan 30, 2024 at 10:13:48AM +0100, Arnaud POULIQUEN wrote:
> >>
> >>
> >> On 1/26/24 18:11, Mathieu Poirier wrote:
> >>> On Thu, Jan 18, 2024 at 11:04:33AM +0100, Arnaud Pouliquen wrote:
> >>>> The new TEE remoteproc device is used to manage remote firmware in a
> >>>> secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
> >>>> introduced to delegate the loading of the firmware to the trusted
> >>>> execution context. In such cases, the firmware should be signed and
> >>>> adhere to the image format defined by the TEE.
> >>>>
> >>>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
> >>>> ---
> >>>> V1 to V2 update:
> >>>> - remove the select "TEE_REMOTEPROC" in STM32_RPROC config as detected by
> >>>>   the kernel test robot:
> >>>>      WARNING: unmet direct dependencies detected for TEE_REMOTEPROC
> >>>>      Depends on [n]: REMOTEPROC [=y] && OPTEE [=n]
> >>>>      Selected by [y]:
> >>>>      - STM32_RPROC [=y] && (ARCH_STM32 || COMPILE_TEST [=y]) && REMOTEPROC [=y]
> >>>> - Fix initialized trproc variable in  stm32_rproc_probe
> >>>> ---
> >>>>  drivers/remoteproc/stm32_rproc.c | 149 +++++++++++++++++++++++++++++--
> >>>>  1 file changed, 144 insertions(+), 5 deletions(-)
> >>>>
> >>>> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
> >>>> index fcc0001e2657..cf6a21bac945 100644
> >>>> --- a/drivers/remoteproc/stm32_rproc.c
> >>>> +++ b/drivers/remoteproc/stm32_rproc.c
> >>>> @@ -20,6 +20,7 @@
> >>>>  #include <linux/remoteproc.h>
> >>>>  #include <linux/reset.h>
> >>>>  #include <linux/slab.h>
> >>>> +#include <linux/tee_remoteproc.h>
> >>>>  #include <linux/workqueue.h>
> >>>>  
> >>>>  #include "remoteproc_internal.h"
> >>>> @@ -49,6 +50,9 @@
> >>>>  #define M4_STATE_STANDBY	4
> >>>>  #define M4_STATE_CRASH		5
> >>>>  
> >>>> +/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
> >>>> +#define STM32_MP1_M4_PROC_ID    0
> >>>> +
> >>>>  struct stm32_syscon {
> >>>>  	struct regmap *map;
> >>>>  	u32 reg;
> >>>> @@ -90,6 +94,8 @@ struct stm32_rproc {
> >>>>  	struct stm32_mbox mb[MBOX_NB_MBX];
> >>>>  	struct workqueue_struct *workqueue;
> >>>>  	bool hold_boot_smc;
> >>>> +	bool fw_loaded;
> >>>> +	struct tee_rproc *trproc;
> >>>>  	void __iomem *rsc_va;
> >>>>  };
> >>>>  
> >>>> @@ -257,6 +263,91 @@ static int stm32_rproc_release(struct rproc *rproc)
> >>>>  	return err;
> >>>>  }
> >>>>  
> >>>> +static int stm32_rproc_tee_elf_sanity_check(struct rproc *rproc,
> >>>> +					    const struct firmware *fw)
> >>>> +{
> >>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>> +	unsigned int ret = 0;
> >>>> +
> >>>> +	if (rproc->state == RPROC_DETACHED)
> >>>> +		return 0;
> >>>> +
> >>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
> >>>> +	if (!ret)
> >>>> +		ddata->fw_loaded = true;
> >>>> +
> >>>> +	return ret;
> >>>> +}
> >>>> +
> >>>> +static int stm32_rproc_tee_elf_load(struct rproc *rproc,
> >>>> +				    const struct firmware *fw)
> >>>> +{
> >>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>> +	unsigned int ret;
> >>>> +
> >>>> +	/*
> >>>> +	 * This function can be called by remote proc for recovery
> >>>> +	 * without the sanity check. In this case we need to load the firmware
> >>>> +	 * else nothing done here as the firmware has been preloaded for the
> >>>> +	 * sanity check to be able to parse it for the resource table.
> >>>> +	 */
> >>>
> >>> This comment is very confusing - please consider refactoring.  
> >>>
> >>>> +	if (ddata->fw_loaded)
> >>>> +		return 0;
> >>>> +
> >>>
> >>> I'm not sure about keeping a flag to indicate the status of the loaded firmware.
> >>> It is not done for the non-secure method, I don't see why it would be needed for
> >>> the secure one.
> >>>
> >>
> >> The difference is on the sanity check.
> >> - in rproc_elf_sanity_check we  parse the elf file to verify that it is
> >> valid.
> >> - in stm32_rproc_tee_elf_sanity_check we have to do the same, that means to
> >> authenticate it. the authentication is done during the load.
> >>
> >> So this flag is used to avoid to reload it twice time.
> >> refactoring the comment should help to understand this flag
> >>
> >>
> >> An alternative would be to bypass the sanity check. But this lead to same
> >> limitation.
> >> Before loading the firmware in remoteproc_core, we call rproc_parse_fw() that is
> >> used to get the resource table address. To get it from tee we need to
> >> authenticate the firmware so load it...
> >>
> > 
> > I spent a long time thinking about this patchset.  Looking at the code as it
> > is now, request_firmware() in rproc_boot() is called even when the TEE is
> > responsible for loading the firmware.  There should be some conditional code
> > that calls either request_firmware() or tee_rproc_load_fw().  The latter should
> > also be renamed to tee_rproc_request_firmware() to avoid confusion.
> 
> 
> The request_firmware() call is needed in both cases to get the image from the
> filesystem. The tee_rproc_load_fw() gets, as input, the struct firmware provided
> by request_firmware().

The cover letter clearly state the secure side is responsible for loading the
firmware image but here you're telling me it has to be loaded twice.  This is
very confusing.

I'm also confused as to why stm32_rproc_tee_elf_sanity_check() is calling
tee_rproc_load_fw().  There should be one call to load the firmware and another
to perform a sanity check on it.  If the sanity check is done at load time by
the secure world then ops::sanity_check() is NULL.

Most of what this patchset does makes sense, but some of it needs to be moved
around.  

Thanks,
Mathieu

> 
> If we want to integrate in remoteproc_core the solution could probably have to
> create the equivalent of the rproc_fw_boot() to load the firmware with an
> external method. Here is an example based on a new rproc_ops ( not tested)
> 
> + static int rproc_fw_ext_boot(struct rproc *rproc, const struct firmware *fw)
> + {
> + 	struct device *dev = &rproc->dev;
> + 	const char *name = rproc->firmware;
> + 	int ret;
> +
> +
> + 	dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size);
> + 	
> + 	/* ops to load and start the remoteprocessor */
> + 	ret = rproc->ops->boot(rproc, fw);
> + 	if (ret)
> + 		return ret;
> +
> + 	/*
> + 	 * if enabling an IOMMU isn't relevant for this rproc, this is
> + 	 * just a nop
> + 	 */
> + 	ret = rproc_enable_iommu(rproc);
> + 	if (ret) {
> + 		dev_err(dev, "can't enable iommu: %d\n", ret);
> + 		return ret;
> + 	}
> +
> + 	/* Prepare rproc for firmware loading if needed */
> + 	ret = rproc_prepare_device(rproc);
> + 	if (ret) {
> + 		dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
> + 		goto disable_iommu;
> + 	}
> +
> + 	ret = rproc_set_rsc_table(rproc);
> + 	if (ret) {
> + 		dev_err(dev, "can't load resource table: %d\n", ret);
> + 		goto unprepare_device;
> + 	}
> +
> +
> + 	/* reset max_notifyid */
> + 	rproc->max_notifyid = -1;
> +
> + 	/* reset handled vdev */
> + 	rproc->nb_vdev = 0;
> +
> + 	/* handle fw resources which are required to boot rproc */
> + 	ret = rproc_handle_resources(rproc, rproc_loading_handlers);
> + 	if (ret) {
> + 		dev_err(dev, "Failed to process resources: %d\n", ret);
> + 		goto clean_up_resources;
> + 	}
> +
> + 	/* Allocate carveout resources associated to rproc */
> + 	ret = rproc_alloc_registered_carveouts(rproc);
> + 	if (ret) {
> + 		dev_err(dev, "Failed to allocate associated carveouts: %d\n",
> + 			ret);
> + 		goto clean_up_resources;
> + 	}
> +
> + 	return 0;
> +
> + clean_up_resources:
> + 	rproc_resource_cleanup(rproc);
> + unprepare_rproc:
> + 	/* release HW resources if needed */
> + 	rproc_unprepare_device(rproc);
> + disable_iommu:
> + 	rproc_disable_iommu(rproc);
> + 	return ret;
> + }
> 
> 
> int rproc_boot(struct rproc *rproc)
> {
> [...]
> 
> - 		ret = rproc_fw_boot(rproc, firmware_p);
> + 		if(rproc->ops->boot)
> + 			ret = rproc_fw_ext_boot(rproc, firmware_p);
> + 		else
> + 			ret = rproc_fw_boot(rproc, firmware_p);
> 
> Another advantage of this solution is that it opens the framework to other
> formats. For instance it could be a way to support dtb format requested in [RFC]
> Passing device-tree to remoteproc [1].
> 
> [1]
> https://lore.kernel.org/linux-remoteproc/f67cd822-4e29-71f2-7c42-e11dbaa6cd8c at kalrayinc.com/T/#t
> 
> Thanks,
> Arnaud
> 
> 
> 
> > 
> > I touched on that before but please rename rproc_tee_get_rsc_table() to
> > rproc_tee_elf_load_rsc_table().  I also suggest to introduce a new function,
> > rproc_tee_get_loaded_rsc_table() that would be called from
> > rproc_tee_elf_load_rsc_table().  That way we don't need trproc->rsc_va.  
> > 
> > I also think tee_rproc should be renamed to "rproc_tee_interface" and folded
> > under struct rproc.  
> > 
> > With the above most of the problems with the current implementation should
> > naturally go away.
> > 
> > Thanks,
> > Mathieu
> > 
> >>
> >>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
> >>>> +	if (ret)
> >>>> +		return ret;
> >>>> +	ddata->fw_loaded = true;
> >>>> +
> >>>> +	/* Update the resource table parameters. */
> >>>> +	if (rproc_tee_get_rsc_table(ddata->trproc)) {
> >>>> +		/* No resource table: reset the related fields. */
> >>>> +		rproc->cached_table = NULL;
> >>>> +		rproc->table_ptr = NULL;
> >>>> +		rproc->table_sz = 0;
> >>>> +	}
> >>>> +
> >>>> +	return 0;
> >>>> +}
> >>>> +
> >>>> +static struct resource_table *
> >>>> +stm32_rproc_tee_elf_find_loaded_rsc_table(struct rproc *rproc,
> >>>> +					  const struct firmware *fw)
> >>>> +{
> >>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>> +
> >>>> +	return tee_rproc_get_loaded_rsc_table(ddata->trproc);
> >>>> +}
> >>>> +
> >>>> +static int stm32_rproc_tee_start(struct rproc *rproc)
> >>>> +{
> >>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>> +
> >>>> +	return tee_rproc_start(ddata->trproc);
> >>>> +}
> >>>> +
> >>>> +static int stm32_rproc_tee_attach(struct rproc *rproc)
> >>>> +{
> >>>> +	/* Nothing to do, remote proc already started by the secured context. */
> >>>> +	return 0;
> >>>> +}
> >>>> +
> >>>> +static int stm32_rproc_tee_stop(struct rproc *rproc)
> >>>> +{
> >>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>> +	int err;
> >>>> +
> >>>> +	stm32_rproc_request_shutdown(rproc);
> >>>> +
> >>>> +	err = tee_rproc_stop(ddata->trproc);
> >>>> +	if (err)
> >>>> +		return err;
> >>>> +
> >>>> +	ddata->fw_loaded = false;
> >>>> +
> >>>> +	return stm32_rproc_release(rproc);
> >>>> +}
> >>>> +
> >>>>  static int stm32_rproc_prepare(struct rproc *rproc)
> >>>>  {
> >>>>  	struct device *dev = rproc->dev.parent;
> >>>> @@ -319,7 +410,14 @@ static int stm32_rproc_prepare(struct rproc *rproc)
> >>>>  
> >>>>  static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
> >>>>  {
> >>>> -	if (rproc_elf_load_rsc_table(rproc, fw))
> >>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>> +	int ret;
> >>>> +
> >>>> +	if (ddata->trproc)
> >>>> +		ret = rproc_tee_get_rsc_table(ddata->trproc);
> >>>> +	else
> >>>> +		ret = rproc_elf_load_rsc_table(rproc, fw);
> >>>> +	if (ret)
> >>>>  		dev_warn(&rproc->dev, "no resource table found for this firmware\n");
> >>>>  
> >>>>  	return 0;
> >>>> @@ -693,8 +791,22 @@ static const struct rproc_ops st_rproc_ops = {
> >>>>  	.get_boot_addr	= rproc_elf_get_boot_addr,
> >>>>  };
> >>>>  
> >>>> +static const struct rproc_ops st_rproc_tee_ops = {
> >>>> +	.prepare	= stm32_rproc_prepare,
> >>>> +	.start		= stm32_rproc_tee_start,
> >>>> +	.stop		= stm32_rproc_tee_stop,
> >>>> +	.attach		= stm32_rproc_tee_attach,
> >>>> +	.kick		= stm32_rproc_kick,
> >>>> +	.parse_fw	= stm32_rproc_parse_fw,
> >>>> +	.find_loaded_rsc_table = stm32_rproc_tee_elf_find_loaded_rsc_table,
> >>>> +	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
> >>>> +	.sanity_check	= stm32_rproc_tee_elf_sanity_check,
> >>>> +	.load		= stm32_rproc_tee_elf_load,
> >>>> +};
> >>>> +
> >>>>  static const struct of_device_id stm32_rproc_match[] = {
> >>>> -	{ .compatible = "st,stm32mp1-m4" },
> >>>> +	{.compatible = "st,stm32mp1-m4",},
> >>>> +	{.compatible = "st,stm32mp1-m4-tee",},
> >>>>  	{},
> >>>>  };
> >>>>  MODULE_DEVICE_TABLE(of, stm32_rproc_match);
> >>>> @@ -853,6 +965,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>>>  	struct device *dev = &pdev->dev;
> >>>>  	struct stm32_rproc *ddata;
> >>>>  	struct device_node *np = dev->of_node;
> >>>> +	struct tee_rproc *trproc = NULL;
> >>>>  	struct rproc *rproc;
> >>>>  	unsigned int state;
> >>>>  	int ret;
> >>>> @@ -861,11 +974,31 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>>>  	if (ret)
> >>>>  		return ret;
> >>>>  
> >>>> -	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
> >>>> -	if (!rproc)
> >>>> -		return -ENOMEM;
> >>>> +	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
> >>>> +		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
> >>>> +		if (IS_ERR(trproc)) {
> >>>> +			dev_err_probe(dev, PTR_ERR(trproc),
> >>>> +				      "signed firmware not supported by TEE\n");
> >>>> +			return PTR_ERR(trproc);
> >>>> +		}
> >>>> +		/*
> >>>> +		 * Delegate the firmware management to the secure context.
> >>>> +		 * The firmware loaded has to be signed.
> >>>> +		 */
> >>>> +		dev_info(dev, "Support of signed firmware only\n");
> >>>
> >>> Not sure what this adds.  Please remove.
> >>
> >> This is used to inform the user that only a signed firmware can be loaded, not
> >> an ELF file.
> >> I have a patch in my pipe to provide the supported format in the debugfs. In a
> >> first step, I can suppress this message and we can revisit the issue when I push
> >> the debugfs proposal.
> >>
> >> Thanks,
> >> Arnaud
> >>
> >>>
> >>>> +	}
> >>>> +	rproc = rproc_alloc(dev, np->name,
> >>>> +			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
> >>>> +			    NULL, sizeof(*ddata));
> >>>> +	if (!rproc) {
> >>>> +		ret = -ENOMEM;
> >>>> +		goto free_tee;
> >>>> +	}
> >>>>  
> >>>>  	ddata = rproc->priv;
> >>>> +	ddata->trproc = trproc;
> >>>> +	if (trproc)
> >>>> +		trproc->rproc = rproc;
> >>>>  
> >>>>  	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
> >>>>  
> >>>> @@ -916,6 +1049,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>>>  		device_init_wakeup(dev, false);
> >>>>  	}
> >>>>  	rproc_free(rproc);
> >>>> +free_tee:
> >>>> +	if (trproc)
> >>>> +		tee_rproc_unregister(trproc);
> >>>> +
> >>>>  	return ret;
> >>>>  }
> >>>>  
> >>>> @@ -937,6 +1074,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
> >>>>  		device_init_wakeup(dev, false);
> >>>>  	}
> >>>>  	rproc_free(rproc);
> >>>> +	if (ddata->trproc)
> >>>> +		tee_rproc_unregister(ddata->trproc);
> >>>>  }
> >>>>  
> >>>>  static int stm32_rproc_suspend(struct device *dev)
> >>>> -- 
> >>>> 2.25.1
> >>>>


From ardb at kernel.org  Thu Feb  1 08:07:59 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 1 Feb 2024 17:07:59 +0100
Subject: [PATCH] arm64: jump_label: use constraint "S" instead of "i"
In-Reply-To: <ZbuFWSRBntgm2ukJ@e133380.arm.com>
References: <20240131065322.1126831-1-maskray@google.com> <CAMj1kXGzADFWa7RmXyjWpCnQ=9hhz6i-XkN4PS1CboZ-kFL8dQ@mail.gmail.com>
 <ZbpEnDK3U/O24ng0@e133380.arm.com> <20240201045551.ajg4iqcajyowl2rh@google.com>
 <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>
 <20240201091120.pbgr7ng6t2c36fut@google.com> <ZbuFWSRBntgm2ukJ@e133380.arm.com>
Message-ID: <CAMj1kXGu76WHY8=Y-KhCxBq3xeHeCYQ9syqViSr9VRkjgWQ3BQ@mail.gmail.com>

On Thu, 1 Feb 2024 at 12:50, Dave Martin <Dave.Martin at arm.com> wrote:
>
> On Thu, Feb 01, 2024 at 01:11:20AM -0800, Fangrui Song wrote:
...
> >
> > Hmm. Clang's constraint "S" implementation doesn't support a constant
> > offset, so
> > `static_key_false(&nf_hooks_needed[pf][hook])` in include/linux/netfilter.h:nf_hook
> > would not compile with Clang <= 18.
> >
> > I have a patch https://github.com/llvm/llvm-project/pull/80255 , but
> > even if it is accepted and cherry-picked into the 18.x release branch,
> > if we still support older Clang, we cannot use "S" unconditionally.
> >
> >
> > So we probably need the following to prepare for -fPIE support in the
> > future:
> >
> > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> > index 48ddc0f45d22..b8af2f8b0c99 100644
> > --- a/arch/arm64/include/asm/jump_label.h
> > +++ b/arch/arm64/include/asm/jump_label.h
> > @@ -15,6 +15,16 @@
> >  #define JUMP_LABEL_NOP_SIZE          AARCH64_INSN_SIZE
> > +/*
> > + * Prefer "S" to support PIC. However, use "i" for Clang 18 and earlier as "S"
> > + * on a symbol with a constant offset is not supported.
> > + */
> > +#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 18
>
> Is a GCC version check needed?  Or is the minimum GCC version specified
> for building the kernel new enough?
>
> > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
> > +#else
> > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "S"
> > +#endif
> > +

Can we use "Si" instead?

> >  static __always_inline bool arch_static_branch(struct static_key * const key,
> >                                              const bool branch)
> >  {
> > @@ -23,9 +33,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
> >                "      .pushsection    __jump_table, \"aw\"    \n\t"
> >                "      .align          3                       \n\t"
> >                "      .long           1b - ., %l[l_yes] - .   \n\t"
> > -              "      .quad           %c0 - .                 \n\t"
> > +              "      .quad           %0 + %1 - .             \n\t"
> >                "      .popsection                             \n\t"
> > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> > +              :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);
>
> While this looks reasonable, I'm still not clear now why the asm must do
> the addition.
>
> Can we roll the branch argument into the macro?
>
> "S"(symbol + constant) seems to do the right thing for AArch64, at least
> in GCC.
>

'symbol' is a struct static_key pointer, so adding '1' to it will not
produce the needed result.

...
> > > > >If there's another reason why "S" is advantageous though, I'm happy to
> > > > >be corrected.
> > > >
> > > > I remember that Ard has an RFC
> > > > https://lore.kernel.org/linux-arm-kernel/20220427171241.2426592-1-ardb at kernel.org/
> > > > "[RFC PATCH 0/2] arm64: use PIE code generation for KASLR kernel"
> > > > and see some recent PIE codegen patches.
> > > >
> > > > > Building the KASLR kernel without -fpie but linking it with -pie works
> > > > > in practice, but it is not something that is explicitly supported by the
> > > > > toolchains - it happens to work because the default 'small' code model
> > > > > used by both GCC and Clang relies mostly on ADRP+ADD/LDR to generate
> > > > > symbol references.
>
> Does this mean that doing boot-time relocation on a fully statically
> linked kernel doesn't bring much benefit?

Not sure I follow you here. The boot-time relocation is necessary in
any case, to fix up statically initialized pointer variables all over
the kernel.

> It would tend to be more
> painful to do the relocation work, and mean that the kernel text has to
> be temporarily writeable, but static linking should have the best
> runtime performance.
>

Not sure what you mean by 'static linking' here.

The only thing PIE linking does in the case of the kernel is
a) complain if static relocations are used that cannot be fixed up at
runtime (e.g., movk/movz sequences)
b) emit dynamic relocations that the early startup code can use to fix
up all statically initialized pointers

>From a codegen point-of-view, there is no difference because we don't
use -fpic code. The problem with -fpic codegen is that it makes some
assumptions that only hold for shared ELF objects, e.g., avoiding
dynamic relocations in .text, using GOT entries even for variables
defined in the same compilation so that they can be preempted, keeping
all runtime relocatable quantities together so the CoW footprint of
the shared library is minimized.

None of this matters for the kernel, and as it turns out, the non-PIC
small C model produces code that the PIE linker is happy with.

TL;DR our code (including inline and out-of-line asm) is already PIC,
and this property is relied upon by KASLR.

> Maybe it doesn't make as much difference as I thought (certainly ADRP
> based addressing should make a fair amount of the PIC/PIE overhead go
> away).
>

The PIC/PIE overhead is in the indirections via the GOT. However,
recent linkers will actually perform some relaxations too: if a symbol
is defined in the same executable and is not preemptible, a GOT load

ADRP
LDR

can be transparently converted to

ADRP
ADD

referring to the symbol directly. This is also where hidden.h comes
in: making all symbol declarations and definitions 'hidden' will allow
the compiler to assume that a GOT entry is never needed.

So building with -fPIC is currently not need in practice, and creates
some complications, which is why we have been avoiding it. But PIE
linking non-PIC objects is not guaranteed to remain supported going
forward, so it would be better to have a plan B, i.e., being able to
turn on -fpic without massive regressions due to GOT overhead, or
codegen problems with our asm hacks.


From andre.draszik at linaro.org  Thu Feb  1 08:11:36 2024
From: andre.draszik at linaro.org (=?UTF-8?q?Andr=C3=A9=20Draszik?=)
Date: Thu,  1 Feb 2024 16:11:36 +0000
Subject: [PATCH v3 0/7] gs101 oriole: peripheral block 1 (peric1) and i2c12 support
Message-ID: <20240201161258.1013664-1-andre.draszik@linaro.org>

Hi,

This patch series implements support for the 2nd connectivity
peripheral block on gs101.
This block contains an additional 6 USI, 1 I3C and 1 PWM
interfaces/busses.

i2cdetect shows all expected devices on the one i2c bus that this patch
series enables.
Everything that's in scope in this series works also without the
clk_ignore_unused kernel command line argument.

While working on this, I noticed the existing peric0 support for gs101
has a couple issues. That explains why there are differences compared
to it and a separate patch series has been sent to fix up peric0
support.

Cheers,
Andre'

Changes in v3:
- drop samsung,mode = <USI_V2_NONE> default assignment in patch #6

Changes in v2:
- squash original patches #3+#9 (Krzysztof)
- move original patch #7 to new #4
- squash original patches #4+#8 and make it #5 (Krzysztof)
- add short summary of devices attached to i2c bus 12 & add TODO (Sam & Peter)
- collect Reviewed-by: tags
- I kept Reviewed-by: tags for the squashed patches. Please shout if
  that wasn't expected

 .../bindings/clock/google,gs101-clock.yaml    |   9 +-
 .../soc/samsung/samsung,exynos-sysreg.yaml    |   1 +
 .../boot/dts/exynos/google/gs101-oriole.dts   |  10 +
 arch/arm64/boot/dts/exynos/google/gs101.dtsi  |  40 ++
 drivers/clk/samsung/clk-gs101.c               | 347 ++++++++++++++++-
 include/dt-bindings/clock/google,gs101.h      |  48 +++
 6 files changed, 451 insertions(+), 4 deletions(-)



From andre.draszik at linaro.org  Thu Feb  1 08:11:37 2024
From: andre.draszik at linaro.org (=?UTF-8?q?Andr=C3=A9=20Draszik?=)
Date: Thu,  1 Feb 2024 16:11:37 +0000
Subject: [PATCH v3 1/7] clk: samsung: gs-101: drop extra empty line
In-Reply-To: <20240201161258.1013664-1-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
Message-ID: <20240201161258.1013664-2-andre.draszik@linaro.org>

There is an extra empty line here which doesn't exist in any of the
other cmu code blocks in this file.

Drop it to align cmu_top with the rest of the file.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>

---
v2: collect Reviewed-by: tags
---
 drivers/clk/samsung/clk-gs101.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/clk/samsung/clk-gs101.c b/drivers/clk/samsung/clk-gs101.c
index 4a0520e825b6..27debbafdce4 100644
--- a/drivers/clk/samsung/clk-gs101.c
+++ b/drivers/clk/samsung/clk-gs101.c
@@ -25,7 +25,6 @@
 /* ---- CMU_TOP ------------------------------------------------------------- */
 
 /* Register Offset definitions for CMU_TOP (0x1e080000) */
-
 #define PLL_LOCKTIME_PLL_SHARED0			0x0000
 #define PLL_LOCKTIME_PLL_SHARED1			0x0004
 #define PLL_LOCKTIME_PLL_SHARED2			0x0008
-- 
2.43.0.594.gd9cf4e227d-goog



From andre.draszik at linaro.org  Thu Feb  1 08:11:38 2024
From: andre.draszik at linaro.org (=?UTF-8?q?Andr=C3=A9=20Draszik?=)
Date: Thu,  1 Feb 2024 16:11:38 +0000
Subject: [PATCH v3 2/7] dt-bindings: clock: google,gs101-clock: add PERIC1 clock management unit
In-Reply-To: <20240201161258.1013664-1-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
Message-ID: <20240201161258.1013664-3-andre.draszik@linaro.org>

Add dt-schema documentation and clock IDs for the Connectivity
Peripheral 1 (PERIC1) clock management unit.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>
Reviewed-by: Rob Herring <robh at kernel.org>

---
v3: collect Reviewed-by: tags

v2: collect Reviewed-by: tags

Note for future reference: To ensure consistent naming throughout this
file, the IDs have been derived from the data sheet using the
following, with the expectation for all future additions to this file
to use the same:
    sed \
        -e 's|^PLL_LOCKTIME_PLL_\([^_]\+\)|CLK_FOUT_\1_PLL|' \
        \
        -e 's|^PLL_CON0_MUX_CLKCMU_\([^_]\+\)_|CLK_MOUT_\1_|' \
        -e 's|^PLL_CON0_PLL_\(.*\)|CLK_MOUT_PLL_\1|' \
        -e 's|^CLK_CON_MUX_MUX_CLK_\(.*\)|CLK_MOUT_\1|' \
        -e '/^PLL_CON[1-4]_[^_]\+_/d' \
        -e '/^[^_]\+_CMU_[^_]\+_CONTROLLER_OPTION/d' \
        -e '/^CLKOUT_CON_BLK_[^_]\+_CMU_[^_]\+_CLKOUT0/d' \
        \
        -e 's|_IPCLKPORT||' \
        -e 's|_RSTNSYNC||' \
        \
        -e 's|^CLK_CON_DIV_DIV_CLK_\([^_]\+\)_|CLK_DOUT_\1_|' \
        \
        -e 's|^CLK_CON_BUF_CLKBUF_\([^_]\+\)_|CLK_GOUT_\1_|' \
        -e 's|^CLK_CON_GAT_CLK_BLK_\([^_]\+\)_UID_|CLK_GOUT_\1_|' \
        -e 's|^CLK_GOUT_[^_]\+_[^_]\+_CMU_\([^_]\+\)_PCLK$|CLK_GOUT_\1_PCLK|' \
        -e 's|^CLK_CON_GAT_GOUT_BLK_\([^_]\+\)_UID_|CLK_GOUT_\1_|' \
        -e 's|^CLK_CON_GAT_CLK_\([^_]\+\)_\(.*\)|CLK_GOUT_\1_CLK_\1_\2|' \
        \
        -e '/^\(DMYQCH\|PCH\|QCH\|QUEUE\)_/d'
---
 .../bindings/clock/google,gs101-clock.yaml    |  9 ++--
 include/dt-bindings/clock/google,gs101.h      | 48 +++++++++++++++++++
 2 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml b/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
index 03698cdecf7a..1d2bcea41c85 100644
--- a/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
@@ -31,6 +31,7 @@ properties:
       - google,gs101-cmu-apm
       - google,gs101-cmu-misc
       - google,gs101-cmu-peric0
+      - google,gs101-cmu-peric1
 
   clocks:
     minItems: 1
@@ -93,15 +94,17 @@ allOf:
       properties:
         compatible:
           contains:
-            const: google,gs101-cmu-peric0
+            enum:
+              - google,gs101-cmu-peric0
+              - google,gs101-cmu-peric1
 
     then:
       properties:
         clocks:
           items:
             - description: External reference clock (24.576 MHz)
-            - description: Connectivity Peripheral 0 bus clock (from CMU_TOP)
-            - description: Connectivity Peripheral 0 IP clock (from CMU_TOP)
+            - description: Connectivity Peripheral 0/1 bus clock (from CMU_TOP)
+            - description: Connectivity Peripheral 0/1 IP clock (from CMU_TOP)
 
         clock-names:
           items:
diff --git a/include/dt-bindings/clock/google,gs101.h b/include/dt-bindings/clock/google,gs101.h
index 64e6bdc6359c..3dac3577788a 100644
--- a/include/dt-bindings/clock/google,gs101.h
+++ b/include/dt-bindings/clock/google,gs101.h
@@ -470,4 +470,52 @@
 #define CLK_GOUT_PERIC0_CLK_PERIC0_USI8_USI_CLK		78
 #define CLK_GOUT_PERIC0_SYSREG_PERIC0_PCLK		79
 
+/* CMU_PERIC1 */
+#define CLK_MOUT_PERIC1_BUS_USER			1
+#define CLK_MOUT_PERIC1_I3C_USER			2
+#define CLK_MOUT_PERIC1_USI0_USI_USER			3
+#define CLK_MOUT_PERIC1_USI10_USI_USER			4
+#define CLK_MOUT_PERIC1_USI11_USI_USER			5
+#define CLK_MOUT_PERIC1_USI12_USI_USER			6
+#define CLK_MOUT_PERIC1_USI13_USI_USER			7
+#define CLK_MOUT_PERIC1_USI9_USI_USER			8
+#define CLK_DOUT_PERIC1_I3C				9
+#define CLK_DOUT_PERIC1_USI0_USI			10
+#define CLK_DOUT_PERIC1_USI10_USI			11
+#define CLK_DOUT_PERIC1_USI11_USI			12
+#define CLK_DOUT_PERIC1_USI12_USI			13
+#define CLK_DOUT_PERIC1_USI13_USI			14
+#define CLK_DOUT_PERIC1_USI9_USI			15
+#define CLK_GOUT_PERIC1_IP				16
+#define CLK_GOUT_PERIC1_PCLK				17
+#define CLK_GOUT_PERIC1_CLK_PERIC1_I3C_CLK		18
+#define CLK_GOUT_PERIC1_CLK_PERIC1_OSCCLK_CLK		19
+#define CLK_GOUT_PERIC1_D_TZPC_PERIC1_PCLK		20
+#define CLK_GOUT_PERIC1_GPC_PERIC1_PCLK			21
+#define CLK_GOUT_PERIC1_GPIO_PERIC1_PCLK		22
+#define CLK_GOUT_PERIC1_LHM_AXI_P_PERIC1_I_CLK		23
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_1		24
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_2		25
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_3		26
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_4		27
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5		28
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_6		29
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_8		30
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_1		31
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_15		32
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_2		33
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_3		34
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_4		35
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5		36
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_6		37
+#define CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_8		38
+#define CLK_GOUT_PERIC1_CLK_PERIC1_BUSP_CLK		39
+#define CLK_GOUT_PERIC1_CLK_PERIC1_USI0_USI_CLK		40
+#define CLK_GOUT_PERIC1_CLK_PERIC1_USI10_USI_CLK	41
+#define CLK_GOUT_PERIC1_CLK_PERIC1_USI11_USI_CLK	42
+#define CLK_GOUT_PERIC1_CLK_PERIC1_USI12_USI_CLK	43
+#define CLK_GOUT_PERIC1_CLK_PERIC1_USI13_USI_CLK	44
+#define CLK_GOUT_PERIC1_CLK_PERIC1_USI9_USI_CLK		45
+#define CLK_GOUT_PERIC1_SYSREG_PERIC1_PCLK		46
+
 #endif /* _DT_BINDINGS_CLOCK_GOOGLE_GS101_H */
-- 
2.43.0.594.gd9cf4e227d-goog



From andre.draszik at linaro.org  Thu Feb  1 08:11:43 2024
From: andre.draszik at linaro.org (=?UTF-8?q?Andr=C3=A9=20Draszik?=)
Date: Thu,  1 Feb 2024 16:11:43 +0000
Subject: [PATCH v3 7/7] arm64: dts: exynos: gs101: enable i2c bus 12 on gs101-oriole
In-Reply-To: <20240201161258.1013664-1-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
Message-ID: <20240201161258.1013664-8-andre.draszik@linaro.org>

This bus has three USB-related devices attached to it:
    0x25: Maxim 77759 Type-C port controller
    0x35: Maxim 20339EWB Surge protection IC
    0x36: Maxim 77759 Fuel gauge
    0x57: NXP PCA9468 Battery charger
    0x66: Maxim 77759 PMIC
    0x69: Maxim 77759 Charger
where the Maxim 77759 has multiple i2c slave addresses.

These don't have (upstream) Linux drivers yet, but nevertheless we can
enable the bus so as to allow working on them (and to make i2cdetect /
i2cdump / etc. work).

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>

---
v3: collect Reviewed-by: tags

v2:
* add short summary of devices attached to this bus & add TODO
* collect Reviewed-by: tags
---
 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
index cb4d17339b6b..6ccade2c8cb4 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
+++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
@@ -72,6 +72,11 @@ eeprom: eeprom at 50 {
 	};
 };
 
+&hsi2c_12 {
+	status = "okay";
+	/* TODO: add the devices once drivers exist */
+};
+
 &pinctrl_far_alive {
 	key_voldown: key-voldown-pins {
 		samsung,pins = "gpa7-3";
@@ -113,6 +118,11 @@ &usi8 {
 	status = "okay";
 };
 
+&usi12 {
+	samsung,mode = <USI_V2_I2C>;
+	status = "okay";
+};
+
 &watchdog_cl0 {
 	timeout-sec = <30>;
 	status = "okay";
-- 
2.43.0.594.gd9cf4e227d-goog



From andre.draszik at linaro.org  Thu Feb  1 08:11:41 2024
From: andre.draszik at linaro.org (=?UTF-8?q?Andr=C3=A9=20Draszik?=)
Date: Thu,  1 Feb 2024 16:11:41 +0000
Subject: [PATCH v3 5/7] arm64: dts: exynos: gs101: enable cmu-peric1 clock controller
In-Reply-To: <20240201161258.1013664-1-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
Message-ID: <20240201161258.1013664-6-andre.draszik@linaro.org>

Enable the cmu-peric1 clock controller. It feeds additional USI, I3C
and PWM interfaces / busses.

Note that &sysreg_peric1 needs a clock to be able to access its
registers and now that Linux knows about this clock, we need to add it
in this commit as well so as to keep &sysreg_peric1 working, so that
the clock can be enabled as and when needed.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>

---
v3: collect Reviewed-by: tags

v2:
* merge patch #8 from original series version 1 into this patch, i.e.
add the clock to &sysreg_peric1 in this commit & update commit message
* collect Reviewed-by: tags
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index aaac04df5e65..e1bcf490309a 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -429,9 +429,20 @@ serial_0: serial at 10a00000 {
 			};
 		};
 
+		cmu_peric1: clock-controller at 10c00000 {
+			compatible = "google,gs101-cmu-peric1";
+			reg = <0x10c00000 0x4000>;
+			#clock-cells = <1>;
+			clocks = <&ext_24_5m>,
+				 <&cmu_top CLK_DOUT_CMU_PERIC1_BUS>,
+				 <&cmu_top CLK_DOUT_CMU_PERIC1_IP>;
+			clock-names = "oscclk", "bus", "ip";
+		};
+
 		sysreg_peric1: syscon at 10c20000 {
 			compatible = "google,gs101-peric1-sysreg", "syscon";
 			reg = <0x10c20000 0x10000>;
+			clocks = <&cmu_peric1 CLK_GOUT_PERIC1_SYSREG_PERIC1_PCLK>;
 		};
 
 		pinctrl_peric1: pinctrl at 10c40000 {
-- 
2.43.0.594.gd9cf4e227d-goog



From andre.draszik at linaro.org  Thu Feb  1 08:11:40 2024
From: andre.draszik at linaro.org (=?UTF-8?q?Andr=C3=A9=20Draszik?=)
Date: Thu,  1 Feb 2024 16:11:40 +0000
Subject: [PATCH v3 4/7] dt-bindings: samsung: exynos-sysreg: gs101-peric1 requires a clock
In-Reply-To: <20240201161258.1013664-1-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
Message-ID: <20240201161258.1013664-5-andre.draszik@linaro.org>

Otherwise it won't be accessible.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>
Reviewed-by: Rob Herring <robh at kernel.org>

---
v3: collect Reviewed-by: tags
v2: collect Reviewed-by: tags
---
 .../devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml   | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml
index 33d837ae4f45..c0c6ce8fc786 100644
--- a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml
+++ b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml
@@ -73,6 +73,7 @@ allOf:
           contains:
             enum:
               - google,gs101-peric0-sysreg
+              - google,gs101-peric1-sysreg
               - samsung,exynos850-cmgp-sysreg
               - samsung,exynos850-peri-sysreg
               - samsung,exynos850-sysreg
-- 
2.43.0.594.gd9cf4e227d-goog



From andre.draszik at linaro.org  Thu Feb  1 08:11:39 2024
From: andre.draszik at linaro.org (=?UTF-8?q?Andr=C3=A9=20Draszik?=)
Date: Thu,  1 Feb 2024 16:11:39 +0000
Subject: [PATCH v3 3/7] clk: samsung: gs101: add support for cmu_peric1
In-Reply-To: <20240201161258.1013664-1-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
Message-ID: <20240201161258.1013664-4-andre.draszik@linaro.org>

CMU_PERIC1 is the clock management unit used for the peric1 block which
is used for additional USI, I3C and PWM interfaces/busses. Add support
for muxes, dividers and gates of cmu_peric1, except for
CLK_GOUT_PERIC1_IP which isn't well described in the datasheet and
which downstream also ignores (similar to cmu_peric0).

Two clocks have been marked as CLK_IS_CRITICAL for the following
reason:
    * disabling them makes it impossible to access any peric1
      registers, (including those two registers).
    * disabling gout_peric1_lhm_axi_p_peric1_i_clk sometimes has the
      additional effect of making the whole system unresponsive.

One clock marked as CLK_IGNORE_UNUSED needs to be kept on until we have
updated the respective driver for the following reason:
    * gout_peric1_gpio_peric1_pclk is required by the pinctrl
      configuration. With this clock disabled, reconfiguring the pins
      (for USI/I2C, USI/UART) will hang during register access.
      Since pinctrl-samsung doesn't support a clock at the moment, we
      just keep the kernel from disabling it at boot, until we have an
      update for pinctrl-samsung, at which point we'll drop the flag.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>

---
v3:
* collect Reviewed-by: tags

v2:
* fix typo pingctrl -> pinctrl in commit message
* merge patch #9 from original series version 1 into this patch, i.e.
drop temporary CLK_IGNORE_UNUSED of gout_peric1_sysreg_peric1_pclk and
remove explanation why this was done in the first place from commit
message
* collect Reviewed-by: tags

Note for future reference: To ensure consistent naming throughout this
driver, the clock names have been derived from the data sheet using the
following, with the expectation for all future additions to this file
to use the same:
    sed \
        -e 's|^PLL_LOCKTIME_PLL_\([^_]\+\)|fout_\L\1_pll|' \
        \
        -e 's|^PLL_CON0_MUX_CLKCMU_\([^_]\+\)_\(.*\)|mout_\L\1_\2|' \
        -e 's|^PLL_CON0_PLL_\(.*\)|mout_pll_\L\1|' \
        -e 's|^CLK_CON_MUX_MUX_CLK_\(.*\)|mout_\L\1|' \
        -e '/^PLL_CON[1-4]_[^_]\+_/d' \
        -e '/^[^_]\+_CMU_[^_]\+_CONTROLLER_OPTION/d' \
        -e '/^CLKOUT_CON_BLK_[^_]\+_CMU_[^_]\+_CLKOUT0/d' \
        \
        -e 's|_IPCLKPORT||' \
        -e 's|_RSTNSYNC||' \
        \
        -e 's|^CLK_CON_DIV_DIV_CLK_\([^_]\+\)_\(.*\)|dout_\L\1_\2|' \
        \
        -e 's|^CLK_CON_BUF_CLKBUF_\([^_]\+\)_\(.*\)|gout_\L\1_\2|' \
        -e 's|^CLK_CON_GAT_CLK_BLK_\([^_]\+\)_UID_\(.*\)|gout_\L\1_\2|' \
        -e 's|^gout_[^_]\+_[^_]\+_cmu_\([^_]\+\)_pclk$|gout_\1_\1_pclk|' \
        -e 's|^CLK_CON_GAT_GOUT_BLK_\([^_]\+\)_UID_\(.*\)|gout_\L\1_\2|' \
        -e 's|^CLK_CON_GAT_CLK_\([^_]\+\)_\(.*\)|gout_\L\1_clk_\L\1_\2|' \
        \
        -e '/^\(DMYQCH\|PCH\|QCH\|QUEUE\)_/d'
---
 drivers/clk/samsung/clk-gs101.c | 346 ++++++++++++++++++++++++++++++++
 1 file changed, 346 insertions(+)

diff --git a/drivers/clk/samsung/clk-gs101.c b/drivers/clk/samsung/clk-gs101.c
index 27debbafdce4..d55ed64d0e29 100644
--- a/drivers/clk/samsung/clk-gs101.c
+++ b/drivers/clk/samsung/clk-gs101.c
@@ -21,6 +21,7 @@
 #define CLKS_NR_APM	(CLK_APM_PLL_DIV16_APM + 1)
 #define CLKS_NR_MISC	(CLK_GOUT_MISC_XIU_D_MISC_ACLK + 1)
 #define CLKS_NR_PERIC0	(CLK_GOUT_PERIC0_SYSREG_PERIC0_PCLK + 1)
+#define CLKS_NR_PERIC1	(CLK_GOUT_PERIC1_SYSREG_PERIC1_PCLK + 1)
 
 /* ---- CMU_TOP ------------------------------------------------------------- */
 
@@ -3066,6 +3067,348 @@ static const struct samsung_cmu_info peric0_cmu_info __initconst = {
 	.clk_name		= "bus",
 };
 
+/* ---- CMU_PERIC1 ---------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_PERIC1 (0x10c00000) */
+#define PLL_CON0_MUX_CLKCMU_PERIC1_BUS_USER						0x0600
+#define PLL_CON1_MUX_CLKCMU_PERIC1_BUS_USER						0x0604
+#define PLL_CON0_MUX_CLKCMU_PERIC1_I3C_USER						0x0610
+#define PLL_CON1_MUX_CLKCMU_PERIC1_I3C_USER						0x0614
+#define PLL_CON0_MUX_CLKCMU_PERIC1_USI0_USI_USER					0x0620
+#define PLL_CON1_MUX_CLKCMU_PERIC1_USI0_USI_USER					0x0624
+#define PLL_CON0_MUX_CLKCMU_PERIC1_USI10_USI_USER					0x0630
+#define PLL_CON1_MUX_CLKCMU_PERIC1_USI10_USI_USER					0x0634
+#define PLL_CON0_MUX_CLKCMU_PERIC1_USI11_USI_USER					0x0640
+#define PLL_CON1_MUX_CLKCMU_PERIC1_USI11_USI_USER					0x0644
+#define PLL_CON0_MUX_CLKCMU_PERIC1_USI12_USI_USER					0x0650
+#define PLL_CON1_MUX_CLKCMU_PERIC1_USI12_USI_USER					0x0654
+#define PLL_CON0_MUX_CLKCMU_PERIC1_USI13_USI_USER					0x0660
+#define PLL_CON1_MUX_CLKCMU_PERIC1_USI13_USI_USER					0x0664
+#define PLL_CON0_MUX_CLKCMU_PERIC1_USI9_USI_USER					0x0670
+#define PLL_CON1_MUX_CLKCMU_PERIC1_USI9_USI_USER					0x0674
+#define PERIC1_CMU_PERIC1_CONTROLLER_OPTION						0x0800
+#define CLKOUT_CON_BLK_PERIC1_CMU_PERIC1_CLKOUT0					0x0810
+#define CLK_CON_DIV_DIV_CLK_PERIC1_I3C							0x1800
+#define CLK_CON_DIV_DIV_CLK_PERIC1_USI0_USI						0x1804
+#define CLK_CON_DIV_DIV_CLK_PERIC1_USI10_USI						0x1808
+#define CLK_CON_DIV_DIV_CLK_PERIC1_USI11_USI						0x180c
+#define CLK_CON_DIV_DIV_CLK_PERIC1_USI12_USI						0x1810
+#define CLK_CON_DIV_DIV_CLK_PERIC1_USI13_USI						0x1814
+#define CLK_CON_DIV_DIV_CLK_PERIC1_USI9_USI						0x1818
+#define CLK_CON_BUF_CLKBUF_PERIC1_IP							0x2000
+#define CLK_CON_GAT_CLK_BLK_PERIC1_UID_PERIC1_CMU_PERIC1_IPCLKPORT_PCLK			0x2004
+#define CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_I3C_IPCLKPORT_CLK		0x2008
+#define CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_OSCCLK_IPCLKPORT_CLK		0x200c
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_D_TZPC_PERIC1_IPCLKPORT_PCLK			0x2010
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_GPC_PERIC1_IPCLKPORT_PCLK			0x2014
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_GPIO_PERIC1_IPCLKPORT_PCLK			0x2018
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_LHM_AXI_P_PERIC1_IPCLKPORT_I_CLK		0x201c
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_1			0x2020
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_2			0x2024
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_3			0x2028
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_4			0x202c
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_5			0x2030
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_6			0x2034
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_8			0x2038
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_1			0x203c
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_15			0x2040
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2			0x2044
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3			0x2048
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4			0x204c
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5			0x2050
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6			0x2054
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8			0x2058
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_BUSP_IPCLKPORT_CLK		0x205c
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI0_USI_IPCLKPORT_CLK	0x2060
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI10_USI_IPCLKPORT_CLK	0x2064
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI11_USI_IPCLKPORT_CLK	0x2068
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI12_USI_IPCLKPORT_CLK	0x206c
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI13_USI_IPCLKPORT_CLK	0x2070
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI9_USI_IPCLKPORT_CLK	0x2074
+#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_SYSREG_PERIC1_IPCLKPORT_PCLK			0x2078
+#define DMYQCH_CON_PERIC1_TOP0_QCH_S							0x3000
+#define PCH_CON_LHM_AXI_P_PERIC1_PCH							0x3004
+#define QCH_CON_D_TZPC_PERIC1_QCH							0x3008
+#define QCH_CON_GPC_PERIC1_QCH								0x300c
+#define QCH_CON_GPIO_PERIC1_QCH								0x3010
+#define QCH_CON_LHM_AXI_P_PERIC1_QCH							0x3014
+#define QCH_CON_PERIC1_CMU_PERIC1_QCH							0x3018
+#define QCH_CON_PERIC1_TOP0_QCH_I3C0							0x301c
+#define QCH_CON_PERIC1_TOP0_QCH_PWM							0x3020
+#define QCH_CON_PERIC1_TOP0_QCH_USI0_USI						0x3024
+#define QCH_CON_PERIC1_TOP0_QCH_USI10_USI						0x3028
+#define QCH_CON_PERIC1_TOP0_QCH_USI11_USI						0x302c
+#define QCH_CON_PERIC1_TOP0_QCH_USI12_USI						0x3030
+#define QCH_CON_PERIC1_TOP0_QCH_USI13_USI						0x3034
+#define QCH_CON_PERIC1_TOP0_QCH_USI9_USI						0x3038
+#define QCH_CON_SYSREG_PERIC1_QCH							0x303c
+#define QUEUE_CTRL_REG_BLK_PERIC1_CMU_PERIC1						0x3c00
+
+static const unsigned long peric1_clk_regs[] __initconst = {
+	PLL_CON0_MUX_CLKCMU_PERIC1_BUS_USER,
+	PLL_CON1_MUX_CLKCMU_PERIC1_BUS_USER,
+	PLL_CON0_MUX_CLKCMU_PERIC1_I3C_USER,
+	PLL_CON1_MUX_CLKCMU_PERIC1_I3C_USER,
+	PLL_CON0_MUX_CLKCMU_PERIC1_USI0_USI_USER,
+	PLL_CON1_MUX_CLKCMU_PERIC1_USI0_USI_USER,
+	PLL_CON0_MUX_CLKCMU_PERIC1_USI10_USI_USER,
+	PLL_CON1_MUX_CLKCMU_PERIC1_USI10_USI_USER,
+	PLL_CON0_MUX_CLKCMU_PERIC1_USI11_USI_USER,
+	PLL_CON1_MUX_CLKCMU_PERIC1_USI11_USI_USER,
+	PLL_CON0_MUX_CLKCMU_PERIC1_USI12_USI_USER,
+	PLL_CON1_MUX_CLKCMU_PERIC1_USI12_USI_USER,
+	PLL_CON0_MUX_CLKCMU_PERIC1_USI13_USI_USER,
+	PLL_CON1_MUX_CLKCMU_PERIC1_USI13_USI_USER,
+	PLL_CON0_MUX_CLKCMU_PERIC1_USI9_USI_USER,
+	PLL_CON1_MUX_CLKCMU_PERIC1_USI9_USI_USER,
+	PERIC1_CMU_PERIC1_CONTROLLER_OPTION,
+	CLKOUT_CON_BLK_PERIC1_CMU_PERIC1_CLKOUT0,
+	CLK_CON_DIV_DIV_CLK_PERIC1_I3C,
+	CLK_CON_DIV_DIV_CLK_PERIC1_USI0_USI,
+	CLK_CON_DIV_DIV_CLK_PERIC1_USI10_USI,
+	CLK_CON_DIV_DIV_CLK_PERIC1_USI11_USI,
+	CLK_CON_DIV_DIV_CLK_PERIC1_USI12_USI,
+	CLK_CON_DIV_DIV_CLK_PERIC1_USI13_USI,
+	CLK_CON_DIV_DIV_CLK_PERIC1_USI9_USI,
+	CLK_CON_BUF_CLKBUF_PERIC1_IP,
+	CLK_CON_GAT_CLK_BLK_PERIC1_UID_PERIC1_CMU_PERIC1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_I3C_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_OSCCLK_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_D_TZPC_PERIC1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_GPC_PERIC1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_GPIO_PERIC1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_LHM_AXI_P_PERIC1_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_1,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_2,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_3,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_4,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_5,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_6,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_8,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_1,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_15,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_BUSP_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI0_USI_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI10_USI_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI11_USI_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI12_USI_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI13_USI_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI9_USI_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_SYSREG_PERIC1_IPCLKPORT_PCLK,
+	DMYQCH_CON_PERIC1_TOP0_QCH_S,
+	PCH_CON_LHM_AXI_P_PERIC1_PCH,
+	QCH_CON_D_TZPC_PERIC1_QCH,
+	QCH_CON_GPC_PERIC1_QCH,
+	QCH_CON_GPIO_PERIC1_QCH,
+	QCH_CON_LHM_AXI_P_PERIC1_QCH,
+	QCH_CON_PERIC1_CMU_PERIC1_QCH,
+	QCH_CON_PERIC1_TOP0_QCH_I3C0,
+	QCH_CON_PERIC1_TOP0_QCH_PWM,
+	QCH_CON_PERIC1_TOP0_QCH_USI0_USI,
+	QCH_CON_PERIC1_TOP0_QCH_USI10_USI,
+	QCH_CON_PERIC1_TOP0_QCH_USI11_USI,
+	QCH_CON_PERIC1_TOP0_QCH_USI12_USI,
+	QCH_CON_PERIC1_TOP0_QCH_USI13_USI,
+	QCH_CON_PERIC1_TOP0_QCH_USI9_USI,
+	QCH_CON_SYSREG_PERIC1_QCH,
+	QUEUE_CTRL_REG_BLK_PERIC1_CMU_PERIC1,
+};
+
+/* List of parent clocks for Muxes in CMU_PERIC1 */
+PNAME(mout_peric1_bus_user_p)		= { "oscclk", "dout_cmu_peric1_bus" };
+PNAME(mout_peric1_nonbususer_p)		= { "oscclk", "dout_cmu_peric1_ip" };
+
+static const struct samsung_mux_clock peric1_mux_clks[] __initconst = {
+	MUX(CLK_MOUT_PERIC1_BUS_USER, "mout_peric1_bus_user",
+	    mout_peric1_bus_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_BUS_USER, 4, 1),
+	MUX(CLK_MOUT_PERIC1_I3C_USER,
+	    "mout_peric1_i3c_user", mout_peric1_nonbususer_p,
+	    PLL_CON0_MUX_CLKCMU_PERIC1_I3C_USER, 4, 1),
+	MUX(CLK_MOUT_PERIC1_USI0_USI_USER,
+	    "mout_peric1_usi0_usi_user", mout_peric1_nonbususer_p,
+	    PLL_CON0_MUX_CLKCMU_PERIC1_USI0_USI_USER, 4, 1),
+	MUX(CLK_MOUT_PERIC1_USI10_USI_USER,
+	    "mout_peric1_usi10_usi_user", mout_peric1_nonbususer_p,
+	    PLL_CON0_MUX_CLKCMU_PERIC1_USI10_USI_USER, 4, 1),
+	MUX(CLK_MOUT_PERIC1_USI11_USI_USER,
+	    "mout_peric1_usi11_usi_user", mout_peric1_nonbususer_p,
+	    PLL_CON0_MUX_CLKCMU_PERIC1_USI11_USI_USER, 4, 1),
+	MUX(CLK_MOUT_PERIC1_USI12_USI_USER,
+	    "mout_peric1_usi12_usi_user", mout_peric1_nonbususer_p,
+	    PLL_CON0_MUX_CLKCMU_PERIC1_USI12_USI_USER, 4, 1),
+	MUX(CLK_MOUT_PERIC1_USI13_USI_USER,
+	    "mout_peric1_usi13_usi_user", mout_peric1_nonbususer_p,
+	    PLL_CON0_MUX_CLKCMU_PERIC1_USI13_USI_USER, 4, 1),
+	MUX(CLK_MOUT_PERIC1_USI9_USI_USER,
+	    "mout_peric1_usi9_usi_user", mout_peric1_nonbususer_p,
+	    PLL_CON0_MUX_CLKCMU_PERIC1_USI9_USI_USER, 4, 1),
+};
+
+static const struct samsung_div_clock peric1_div_clks[] __initconst = {
+	DIV(CLK_DOUT_PERIC1_I3C, "dout_peric1_i3c", "mout_peric1_i3c_user",
+	    CLK_CON_DIV_DIV_CLK_PERIC1_I3C, 0, 4),
+	DIV(CLK_DOUT_PERIC1_USI0_USI,
+	    "dout_peric1_usi0_usi", "mout_peric1_usi0_usi_user",
+	    CLK_CON_DIV_DIV_CLK_PERIC1_USI0_USI, 0, 4),
+	DIV(CLK_DOUT_PERIC1_USI10_USI,
+	    "dout_peric1_usi10_usi", "mout_peric1_usi10_usi_user",
+	    CLK_CON_DIV_DIV_CLK_PERIC1_USI10_USI, 0, 4),
+	DIV(CLK_DOUT_PERIC1_USI11_USI,
+	    "dout_peric1_usi11_usi", "mout_peric1_usi11_usi_user",
+	    CLK_CON_DIV_DIV_CLK_PERIC1_USI11_USI, 0, 4),
+	DIV(CLK_DOUT_PERIC1_USI12_USI,
+	    "dout_peric1_usi12_usi", "mout_peric1_usi12_usi_user",
+	    CLK_CON_DIV_DIV_CLK_PERIC1_USI12_USI, 0, 4),
+	DIV(CLK_DOUT_PERIC1_USI13_USI,
+	    "dout_peric1_usi13_usi", "mout_peric1_usi13_usi_user",
+	    CLK_CON_DIV_DIV_CLK_PERIC1_USI13_USI, 0, 4),
+	DIV(CLK_DOUT_PERIC1_USI9_USI,
+	    "dout_peric1_usi9_usi", "mout_peric1_usi9_usi_user",
+	    CLK_CON_DIV_DIV_CLK_PERIC1_USI9_USI, 0, 4),
+};
+
+static const struct samsung_gate_clock peric1_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_PERIC1_PCLK,
+	     "gout_peric1_peric1_pclk", "mout_peric1_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERIC1_UID_PERIC1_CMU_PERIC1_IPCLKPORT_PCLK,
+	     21, CLK_IS_CRITICAL, 0),
+	GATE(CLK_GOUT_PERIC1_CLK_PERIC1_I3C_CLK,
+	     "gout_peric1_clk_peric1_i3c_clk", "dout_peric1_i3c",
+	     CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_I3C_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_CLK_PERIC1_OSCCLK_CLK,
+	     "gout_peric1_clk_peric1_oscclk_clk", "oscclk",
+	     CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_OSCCLK_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_D_TZPC_PERIC1_PCLK,
+	     "gout_peric1_d_tzpc_peric1_pclk", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_D_TZPC_PERIC1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_GPC_PERIC1_PCLK,
+	     "gout_peric1_gpc_peric1_pclk", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_GPC_PERIC1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_GPIO_PERIC1_PCLK,
+	     "gout_peric1_gpio_peric1_pclk", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_GPIO_PERIC1_IPCLKPORT_PCLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_PERIC1_LHM_AXI_P_PERIC1_I_CLK,
+	     "gout_peric1_lhm_axi_p_peric1_i_clk", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_LHM_AXI_P_PERIC1_IPCLKPORT_I_CLK,
+	     21, CLK_IS_CRITICAL, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_1,
+	     "gout_peric1_peric1_top0_ipclk_1", "dout_peric1_usi0_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_1,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_2,
+	     "gout_peric1_peric1_top0_ipclk_2", "dout_peric1_usi9_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_2,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_3,
+	     "gout_peric1_peric1_top0_ipclk_3", "dout_peric1_usi10_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_3,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_4,
+	     "gout_peric1_peric1_top0_ipclk_4", "dout_peric1_usi11_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_4,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5,
+	     "gout_peric1_peric1_top0_ipclk_5", "dout_peric1_usi12_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_5,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_6,
+	     "gout_peric1_peric1_top0_ipclk_6", "dout_peric1_usi13_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_6,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_8,
+	     "gout_peric1_peric1_top0_ipclk_8", "dout_peric1_i3c",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_8,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_1,
+	     "gout_peric1_peric1_top0_pclk_1", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_1,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_15,
+	     "gout_peric1_peric1_top0_pclk_15", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_15,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_2,
+	     "gout_peric1_peric1_top0_pclk_2", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_3,
+	     "gout_peric1_peric1_top0_pclk_3", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_4,
+	     "gout_peric1_peric1_top0_pclk_4", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5,
+	     "gout_peric1_peric1_top0_pclk_5", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_6,
+	     "gout_peric1_peric1_top0_pclk_6", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_8,
+	     "gout_peric1_peric1_top0_pclk_8", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_CLK_PERIC1_BUSP_CLK,
+	     "gout_peric1_clk_peric1_busp_clk", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_BUSP_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_CLK_PERIC1_USI0_USI_CLK,
+	     "gout_peric1_clk_peric1_usi0_usi_clk", "dout_peric1_usi0_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI0_USI_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_CLK_PERIC1_USI10_USI_CLK,
+	     "gout_peric1_clk_peric1_usi10_usi_clk", "dout_peric1_usi10_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI10_USI_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_CLK_PERIC1_USI11_USI_CLK,
+	     "gout_peric1_clk_peric1_usi11_usi_clk", "dout_peric1_usi11_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI11_USI_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_CLK_PERIC1_USI12_USI_CLK,
+	     "gout_peric1_clk_peric1_usi12_usi_clk", "dout_peric1_usi12_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI12_USI_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_CLK_PERIC1_USI13_USI_CLK,
+	     "gout_peric1_clk_peric1_usi13_usi_clk", "dout_peric1_usi13_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI13_USI_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_CLK_PERIC1_USI9_USI_CLK,
+	     "gout_peric1_clk_peric1_usi9_usi_clk", "dout_peric1_usi9_usi",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI9_USI_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERIC1_SYSREG_PERIC1_PCLK,
+	     "gout_peric1_sysreg_peric1_pclk", "mout_peric1_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_PERIC1_UID_SYSREG_PERIC1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+};
+
+static const struct samsung_cmu_info peric1_cmu_info __initconst = {
+	.mux_clks		= peric1_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(peric1_mux_clks),
+	.div_clks		= peric1_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(peric1_div_clks),
+	.gate_clks		= peric1_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(peric1_gate_clks),
+	.nr_clk_ids		= CLKS_NR_PERIC1,
+	.clk_regs		= peric1_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(peric1_clk_regs),
+	.clk_name		= "bus",
+};
+
 /* ---- platform_driver ----------------------------------------------------- */
 
 static int __init gs101_cmu_probe(struct platform_device *pdev)
@@ -3086,6 +3429,9 @@ static const struct of_device_id gs101_cmu_of_match[] = {
 	}, {
 		.compatible = "google,gs101-cmu-peric0",
 		.data = &peric0_cmu_info,
+	}, {
+		.compatible = "google,gs101-cmu-peric1",
+		.data = &peric1_cmu_info,
 	}, {
 	},
 };
-- 
2.43.0.594.gd9cf4e227d-goog



From andre.draszik at linaro.org  Thu Feb  1 08:11:42 2024
From: andre.draszik at linaro.org (=?UTF-8?q?Andr=C3=A9=20Draszik?=)
Date: Thu,  1 Feb 2024 16:11:42 +0000
Subject: [PATCH v3 6/7] arm64: dts: exynos: gs101: define USI12 with I2C configuration
In-Reply-To: <20240201161258.1013664-1-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
Message-ID: <20240201161258.1013664-7-andre.draszik@linaro.org>

On the gs101-oriole board, i2c bus 12 has various USB-related
controllers attached to it.

Note the selection of the USI protocol is intentionally left for the
board dts file.

Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>

---
v3:
* drop samsung,mode = <USI_V2_NONE> default assignment
* collect Reviewed-by: tags

v2:
* reorder pinctrl-0 & pinctrl-names
* collect Reviewed-by: tags
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 29 ++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index e1bcf490309a..55481916fd1f 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -451,6 +451,35 @@ pinctrl_peric1: pinctrl at 10c40000 {
 			interrupts = <GIC_SPI 644 IRQ_TYPE_LEVEL_HIGH 0>;
 		};
 
+		usi12: usi at 10d500c0 {
+			compatible = "google,gs101-usi",
+				     "samsung,exynos850-usi";
+			reg = <0x10d500c0 0x20>;
+			ranges;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5>,
+				 <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5>;
+			clock-names = "pclk", "ipclk";
+			samsung,sysreg = <&sysreg_peric1 0x1010>;
+			status = "disabled";
+
+			hsi2c_12: i2c at 10d50000 {
+				compatible = "google,gs101-hsi2c",
+					     "samsung,exynosautov9-hsi2c";
+				reg = <0x10d50000 0xc0>;
+				interrupts = <GIC_SPI 655 IRQ_TYPE_LEVEL_HIGH 0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				pinctrl-0 = <&hsi2c12_bus>;
+				pinctrl-names = "default";
+				clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5>,
+					 <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5>;
+				clock-names = "hsi2c", "hsi2c_pclk";
+				status = "disabled";
+			};
+		};
+
 		pinctrl_hsi1: pinctrl at 11840000 {
 			compatible = "google,gs101-pinctrl";
 			reg = <0x11840000 0x00001000>;
-- 
2.43.0.594.gd9cf4e227d-goog



From james.clark at arm.com  Thu Feb  1 08:14:11 2024
From: james.clark at arm.com (James Clark)
Date: Thu, 1 Feb 2024 16:14:11 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event
 state to hypervisor
In-Reply-To: <20240104162714.1062610-3-james.clark@arm.com>
References: <20240104162714.1062610-1-james.clark@arm.com>
 <20240104162714.1062610-3-james.clark@arm.com>
Message-ID: <486c9452-2d36-f7c7-8b54-38427336d4c1@arm.com>



On 04/01/2024 16:27, James Clark wrote:
> Currently the state of the PMU events is copied into the VCPU struct
> before every VCPU run. This isn't scalable if more data for other
> features needs to be added too. So make a writable area that's shared
> between the host and the hypervisor to store this state.
> 
> Normal per-cpu constructs can't be used because although the framework
> exists for the host to write to the hypervisor's per-cpu structs, this
> only works until the protection is enabled. And for the other way
> around, no framework exists for the hypervisor to access the host's size
> and layout of per-cpu data. Instead of making a new framework for the
> hypervisor to access the host's per-cpu data that would only be used
> once, just define the new shared area as an array with NR_CPUS elements.
> This also reduces the amount of sharing that needs to be done, because
> unlike this array, the per-cpu data isn't contiguous.
> 
> Signed-off-by: James Clark <james.clark at arm.com>

Hi Marc,

Do you have any feedback about whether this what you were thinking of in
your comment here:
https://lore.kernel.org/kvmarm/86msuqb84g.wl-maz at kernel.org/

Thanks
James

> ---
>  arch/arm64/include/asm/kvm_host.h |  8 ++++++++
>  arch/arm64/kernel/image-vars.h    |  1 +
>  arch/arm64/kvm/arm.c              | 16 ++++++++++++++--
>  arch/arm64/kvm/hyp/nvhe/setup.c   | 11 +++++++++++
>  arch/arm64/kvm/hyp/nvhe/switch.c  |  9 +++++++--
>  arch/arm64/kvm/pmu.c              |  4 +---
>  include/kvm/arm_pmu.h             | 17 -----------------
>  7 files changed, 42 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 824f29f04916..93d38ad257ed 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -466,6 +466,14 @@ struct kvm_cpu_context {
>  	struct kvm_vcpu *__hyp_running_vcpu;
>  };
>  
> +struct kvm_host_global_state {
> +	struct kvm_pmu_events {
> +		u32 events_host;
> +		u32 events_guest;
> +	} pmu_events;
> +} ____cacheline_aligned;
> +extern struct kvm_host_global_state kvm_host_global_state[NR_CPUS];
> +
>  struct kvm_host_data {
>  	struct kvm_cpu_context host_ctxt;
>  };
> diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
> index 119ca121b5f8..1a9dbb02bb4a 100644
> --- a/arch/arm64/kernel/image-vars.h
> +++ b/arch/arm64/kernel/image-vars.h
> @@ -59,6 +59,7 @@ KVM_NVHE_ALIAS(alt_cb_patch_nops);
>  
>  /* Global kernel state accessed by nVHE hyp code. */
>  KVM_NVHE_ALIAS(kvm_vgic_global_state);
> +KVM_NVHE_ALIAS(kvm_host_global_state);
>  
>  /* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */
>  KVM_NVHE_ALIAS(nvhe_hyp_panic_handler);
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 4796104c4471..bd6b2eda5f4f 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -47,6 +47,20 @@
>  
>  static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT;
>  
> +/*
> + * Host state that isn't associated with any VCPU, but will affect any VCPU
> + * running on a host CPU in the future. This remains writable from the host and
> + * readable in the hyp.
> + *
> + * PER_CPU constructs aren't compatible between the hypervisor and the host so
> + * just define it as a NR_CPUS array. DECLARE_KVM_NVHE_PER_CPU works in both
> + * places, but not after the hypervisor protection is initialised. After that,
> + * kvm_arm_hyp_percpu_base isn't accessible from the host, so even if the
> + * kvm_host_global_state struct was shared with the host, the per-cpu offset
> + * can't be calculated without sharing even more data with the host.
> + */
> +struct kvm_host_global_state kvm_host_global_state[NR_CPUS];
> +
>  DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector);
>  
>  DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
> @@ -1016,8 +1030,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
>  
>  		kvm_vgic_flush_hwstate(vcpu);
>  
> -		kvm_pmu_update_vcpu_events(vcpu);
> -
>  		/*
>  		 * Ensure we set mode to IN_GUEST_MODE after we disable
>  		 * interrupts and before the final VCPU requests check.
> diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
> index b5452e58c49a..3e45cc10ba96 100644
> --- a/arch/arm64/kvm/hyp/nvhe/setup.c
> +++ b/arch/arm64/kvm/hyp/nvhe/setup.c
> @@ -159,6 +159,17 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
>  	if (ret)
>  		return ret;
>  
> +	/*
> +	 * Similar to kvm_vgic_global_state, but this one remains writable by
> +	 * the host rather than read-only. Used to store per-cpu state about the
> +	 * host that isn't associated with any particular VCPU.
> +	 */
> +	prot = pkvm_mkstate(KVM_PGTABLE_PROT_RW, PKVM_PAGE_SHARED_OWNED);
> +	ret = pkvm_create_mappings(&kvm_host_global_state,
> +				   &kvm_host_global_state + 1, prot);
> +	if (ret)
> +		return ret;
> +
>  	ret = create_hyp_debug_uart_mapping();
>  	if (ret)
>  		return ret;
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index c50f8459e4fc..89147a9dc38c 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -130,13 +130,18 @@ static void __hyp_vgic_restore_state(struct kvm_vcpu *vcpu)
>  	}
>  }
>  
> +static struct kvm_pmu_events *kvm_nvhe_get_pmu_events(struct kvm_vcpu *vcpu)
> +{
> +	return &kvm_host_global_state[vcpu->cpu].pmu_events;
> +}
> +
>  /*
>   * Disable host events, enable guest events
>   */
>  #ifdef CONFIG_HW_PERF_EVENTS
>  static bool __pmu_switch_to_guest(struct kvm_vcpu *vcpu)
>  {
> -	struct kvm_pmu_events *pmu = &vcpu->arch.pmu.events;
> +	struct kvm_pmu_events *pmu = kvm_nvhe_get_pmu_events(vcpu);
>  
>  	if (pmu->events_host)
>  		write_sysreg(pmu->events_host, pmcntenclr_el0);
> @@ -152,7 +157,7 @@ static bool __pmu_switch_to_guest(struct kvm_vcpu *vcpu)
>   */
>  static void __pmu_switch_to_host(struct kvm_vcpu *vcpu)
>  {
> -	struct kvm_pmu_events *pmu = &vcpu->arch.pmu.events;
> +	struct kvm_pmu_events *pmu = kvm_nvhe_get_pmu_events(vcpu);
>  
>  	if (pmu->events_guest)
>  		write_sysreg(pmu->events_guest, pmcntenclr_el0);
> diff --git a/arch/arm64/kvm/pmu.c b/arch/arm64/kvm/pmu.c
> index a243934c5568..136d5c6c1916 100644
> --- a/arch/arm64/kvm/pmu.c
> +++ b/arch/arm64/kvm/pmu.c
> @@ -6,8 +6,6 @@
>  #include <linux/kvm_host.h>
>  #include <linux/perf_event.h>
>  
> -static DEFINE_PER_CPU(struct kvm_pmu_events, kvm_pmu_events);
> -
>  /*
>   * Given the perf event attributes and system type, determine
>   * if we are going to need to switch counters at guest entry/exit.
> @@ -28,7 +26,7 @@ static bool kvm_pmu_switch_needed(struct perf_event_attr *attr)
>  
>  struct kvm_pmu_events *kvm_get_pmu_events(void)
>  {
> -	return this_cpu_ptr(&kvm_pmu_events);
> +	return &kvm_host_global_state[smp_processor_id()].pmu_events;
>  }
>  
>  /*
> diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
> index 4b9d8fb393a8..71a835970ab5 100644
> --- a/include/kvm/arm_pmu.h
> +++ b/include/kvm/arm_pmu.h
> @@ -18,14 +18,8 @@ struct kvm_pmc {
>  	struct perf_event *perf_event;
>  };
>  
> -struct kvm_pmu_events {
> -	u32 events_host;
> -	u32 events_guest;
> -};
> -
>  struct kvm_pmu {
>  	struct irq_work overflow_work;
> -	struct kvm_pmu_events events;
>  	struct kvm_pmc pmc[ARMV8_PMU_MAX_COUNTERS];
>  	int irq_num;
>  	bool created;
> @@ -79,17 +73,6 @@ void kvm_vcpu_pmu_resync_el0(void);
>  #define kvm_vcpu_has_pmu(vcpu)					\
>  	(vcpu_has_feature(vcpu, KVM_ARM_VCPU_PMU_V3))
>  
> -/*
> - * Updates the vcpu's view of the pmu events for this cpu.
> - * Must be called before every vcpu run after disabling interrupts, to ensure
> - * that an interrupt cannot fire and update the structure.
> - */
> -#define kvm_pmu_update_vcpu_events(vcpu)				\
> -	do {								\
> -		if (!has_vhe() && kvm_vcpu_has_pmu(vcpu))		\
> -			vcpu->arch.pmu.events = *kvm_get_pmu_events();	\
> -	} while (0)
> -
>  /*
>   * Evaluates as true when emulating PMUv3p5, and false otherwise.
>   */


From andrei.simion at microchip.com  Thu Feb  1 08:15:17 2024
From: andrei.simion at microchip.com (Andrei Simion)
Date: Thu, 1 Feb 2024 18:15:17 +0200
Subject: [PATCH v4] regulator: dt-bindings: microchip,mcp16502: convert to YAML
Message-ID: <20240201161517.492162-1-andrei.simion@microchip.com>

Convert devicetree binding mcp16502-regulator.txt to YAML format.

Signed-off-by: Andrei Simion <andrei.simion at microchip.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
Changes v3 -> v4:
- "additionalProperties: false" placed just after the required list

Changes v2 -> v3:
- keep one line of regulators description
- add additionalProperties: false for regulators
- "description:" at the end for each properties

Changes v1 -> v2:
- reverse subject prefixes
- line break after file "description:"
- drop description for reg
- drop regulator-name
- add regulator-initial-mode
- unevaluatedProperties just after $ref: regulator.yaml#
- additionalProperties  just before "required"
- node names generic in example
- drop reg property from i2c
- use 4 spaces for example indentation
---
 .../bindings/regulator/mcp16502-regulator.txt | 144 --------------
 .../regulator/microchip,mcp16502.yaml         | 180 ++++++++++++++++++
 2 files changed, 180 insertions(+), 144 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/microchip,mcp16502.yaml

diff --git a/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt b/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
deleted file mode 100644
index 451cc4e86b01..000000000000
--- a/Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
+++ /dev/null
@@ -1,144 +0,0 @@
-MCP16502 PMIC
-
-Required properties:
-- compatible: "microchip,mcp16502"
-- reg: I2C slave address
-- lpm-gpios: GPIO for LPM pin. Note that this GPIO *must* remain high during
-	     suspend-to-ram, keeping the PMIC into HIBERNATE mode; this
-	     property is optional;
-- regulators: A node that houses a sub-node for each regulator within
-              the device. Each sub-node is identified using the node's
-              name. The content of each sub-node is defined by the
-              standard binding for regulators; see regulator.txt.
-
-Regulators of MCP16502 PMIC:
-1) VDD_IO	- Buck (1.2 - 3.7 V)
-2) VDD_DDR	- Buck (0.6 - 1.85 V)
-3) VDD_CORE	- Buck (0.6 - 1.85 V)
-4) VDD_OTHER	- BUCK (0.6 - 1.85 V)
-5) LDO1		- LDO  (1.2 - 3.7 V)
-6) LDO2		- LDO  (1.2 - 3.7 V)
-
-Regulator modes:
-2 - FPWM: higher precision, higher consumption
-4 - AutoPFM: lower precision, lower consumption
-
-Each regulator is defined using the standard binding for regulators.
-
-Example:
-
-mcp16502 at 5b {
-	compatible = "microchip,mcp16502";
-	reg = <0x5b>;
-	status = "okay";
-	lpm-gpios = <&pioBU 7 GPIO_ACTIVE_HIGH>;
-
-	regulators {
-		VDD_IO {
-			regulator-name = "VDD_IO";
-			regulator-min-microvolt = <1200000>;
-			regulator-max-microvolt = <3700000>;
-			regulator-initial-mode = <2>;
-			regulator-allowed-modes = <2>, <4>;
-			regulator-always-on;
-
-			regulator-state-standby {
-				regulator-on-in-suspend;
-				regulator-mode = <4>;
-			};
-
-			regulator-state-mem {
-				regulator-off-in-suspend;
-				regulator-mode = <4>;
-			};
-		};
-
-		VDD_DDR {
-			regulator-name = "VDD_DDR";
-			regulator-min-microvolt = <600000>;
-			regulator-max-microvolt = <1850000>;
-			regulator-initial-mode = <2>;
-			regulator-allowed-modes = <2>, <4>;
-			regulator-always-on;
-
-			regulator-state-standby {
-				regulator-on-in-suspend;
-				regulator-mode = <4>;
-			};
-
-			regulator-state-mem {
-				regulator-on-in-suspend;
-				regulator-mode = <4>;
-			};
-		};
-
-		VDD_CORE {
-			regulator-name = "VDD_CORE";
-			regulator-min-microvolt = <600000>;
-			regulator-max-microvolt = <1850000>;
-			regulator-initial-mode = <2>;
-			regulator-allowed-modes = <2>, <4>;
-			regulator-always-on;
-
-			regulator-state-standby {
-				regulator-on-in-suspend;
-				regulator-mode = <4>;
-			};
-
-			regulator-state-mem {
-				regulator-off-in-suspend;
-				regulator-mode = <4>;
-			};
-		};
-
-		VDD_OTHER {
-			regulator-name = "VDD_OTHER";
-			regulator-min-microvolt = <600000>;
-			regulator-max-microvolt = <1850000>;
-			regulator-initial-mode = <2>;
-			regulator-allowed-modes = <2>, <4>;
-			regulator-always-on;
-
-			regulator-state-standby {
-				regulator-on-in-suspend;
-				regulator-mode = <4>;
-			};
-
-			regulator-state-mem {
-				regulator-off-in-suspend;
-				regulator-mode = <4>;
-			};
-		};
-
-		LDO1 {
-			regulator-name = "LDO1";
-			regulator-min-microvolt = <1200000>;
-			regulator-max-microvolt = <3700000>;
-			regulator-always-on;
-
-			regulator-state-standby {
-				regulator-on-in-suspend;
-			};
-
-			regulator-state-mem {
-				regulator-off-in-suspend;
-			};
-		};
-
-		LDO2 {
-			regulator-name = "LDO2";
-			regulator-min-microvolt = <1200000>;
-			regulator-max-microvolt = <3700000>;
-			regulator-always-on;
-
-			regulator-state-standby {
-				regulator-on-in-suspend;
-			};
-
-			regulator-state-mem {
-				regulator-off-in-suspend;
-			};
-		};
-
-	};
-};
diff --git a/Documentation/devicetree/bindings/regulator/microchip,mcp16502.yaml b/Documentation/devicetree/bindings/regulator/microchip,mcp16502.yaml
new file mode 100644
index 000000000000..1aca3646789e
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/microchip,mcp16502.yaml
@@ -0,0 +1,180 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/microchip,mcp16502.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MCP16502 - High-Performance PMIC
+
+maintainers:
+  - Andrei Simion <andrei.simion at microchip.com>
+
+description:
+  The MCP16502 is an optimally integrated PMIC compatible
+  with Microchip's eMPUs(Embedded Microprocessor Units),
+  requiring Dynamic Voltage Scaling (DVS) with the use
+  of High-Performance mode (HPM).
+
+properties:
+  compatible:
+    const: microchip,mcp16502
+
+  lpm-gpios:
+    maxItems: 1
+    description: GPIO for LPM pin.
+      Note that this GPIO must remain high during
+      suspend-to-ram, keeping the PMIC into HIBERNATE mode.
+
+  reg:
+    maxItems: 1
+
+  regulators:
+    type: object
+    additionalProperties: false
+    description: List of regulators and its properties.
+
+    patternProperties:
+      "^(VDD_(IO|CORE|DDR|OTHER)|LDO[1-2])$":
+        type: object
+        $ref: regulator.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          regulator-initial-mode:
+            enum: [2, 4]
+            default: 2
+            description: Initial operating mode
+
+          regulator-allowed-modes:
+            items:
+              enum: [2, 4]
+            description: Supported modes
+              2 - FPWM higher precision, higher consumption
+              4 - AutoPFM lower precision, lower consumption
+
+required:
+  - compatible
+  - reg
+  - regulators
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic at 5b {
+            compatible = "microchip,mcp16502";
+            reg = <0x5b>;
+
+            regulators {
+                VDD_IO {
+                    regulator-name = "VDD_IO";
+                    regulator-min-microvolt = <3300000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-initial-mode = <2>;
+                    regulator-allowed-modes = <2>, <4>;
+                    regulator-always-on;
+
+                    regulator-state-standby {
+                        regulator-on-in-suspend;
+                        regulator-mode = <4>;
+                    };
+
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                        regulator-mode = <4>;
+                    };
+                };
+
+                VDD_DDR {
+                    regulator-name = "VDD_DDR";
+                    regulator-min-microvolt = <1350000>;
+                    regulator-max-microvolt = <1350000>;
+                    regulator-initial-mode = <2>;
+                    regulator-allowed-modes = <2>, <4>;
+                    regulator-always-on;
+
+                    regulator-state-standby {
+                        regulator-on-in-suspend;
+                        regulator-mode = <4>;
+                    };
+
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-mode = <4>;
+                    };
+                };
+
+                VDD_CORE {
+                    regulator-name = "VDD_CORE";
+                    regulator-min-microvolt = <1150000>;
+                    regulator-max-microvolt = <1150000>;
+                    regulator-initial-mode = <2>;
+                    regulator-allowed-modes = <2>, <4>;
+                    regulator-always-on;
+
+                    regulator-state-standby {
+                        regulator-on-in-suspend;
+                        regulator-mode = <4>;
+                    };
+
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                        regulator-mode = <4>;
+                    };
+                };
+
+                VDD_OTHER {
+                    regulator-name = "VDD_OTHER";
+                    regulator-min-microvolt = <1050000>;
+                    regulator-max-microvolt = <1250000>;
+                    regulator-initial-mode = <2>;
+                    regulator-allowed-modes = <2>, <4>;
+                    regulator-always-on;
+
+                    regulator-state-standby {
+                        regulator-on-in-suspend;
+                        regulator-mode = <4>;
+                    };
+
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                        regulator-mode = <4>;
+                    };
+                };
+
+                LDO1 {
+                    regulator-name = "LDO1";
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-always-on;
+
+                    regulator-state-standby {
+                        regulator-on-in-suspend;
+                    };
+
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                LDO2 {
+                    regulator-name = "LDO2";
+                    regulator-min-microvolt = <1200000>;
+                    regulator-max-microvolt = <3700000>;
+                    regulator-always-on;
+
+                    regulator-state-standby {
+                        regulator-on-in-suspend;
+                    };
+
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+            };
+        };
+    };
-- 
2.34.1



From rdunlap at infradead.org  Thu Feb  1 08:27:25 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Thu, 1 Feb 2024 08:27:25 -0800
Subject: [PATCH 00/13] ARM: OMAP2+: fix a bunch of kernel-doc warnings
In-Reply-To: <ZbtlOWcGglCeYj6X@shell.armlinux.org.uk>
References: <20240117011004.22669-1-rdunlap@infradead.org>
 <20240117131305.GP5185@atomide.com>
 <e6692a04-142c-4df4-83dc-534ab27a55f6@infradead.org>
 <ZbtlOWcGglCeYj6X@shell.armlinux.org.uk>
Message-ID: <1f53a83d-cae4-4223-ad47-6d1d9c80dc2b@infradead.org>



On 2/1/24 01:32, Russell King (Oracle) wrote:
> On Wed, Jan 17, 2024 at 08:52:16AM -0800, Randy Dunlap wrote:
>>
>>
>> On 1/17/24 05:13, Tony Lindgren wrote:
>>> * Randy Dunlap <rdunlap at infradead.org> [240117 01:10]:
>>>> Fix many kernel-doc warnings in arch/arm/mach-omap2/:
>>>
>>> Thanks for fixing these. These are unlikely to conflict with anything so
>>> please queue them along with other clean-up:
>>>
>>> Acked-by: Tony Lindgren <tony at atomide.com>
>>>
>>> Or alternatively let me know if you want me to apply them.
>>
>> Yes, please go ahead and apply them.
> 
> If you intend people other than me to apply patches, then please do not
> copy the patches to the patch system. I now have to go through all 16
> patches and search the mailing list to find out what happened... and so
> far for the few I've checked, other people have applied them. So I'm
> coming to the conclusion I should just discard the entire lot.
> 

Got it. and sorry about that.  :(


-- 
#Randy


From james.clark at arm.com  Thu Feb  1 08:29:27 2024
From: james.clark at arm.com (James Clark)
Date: Thu, 1 Feb 2024 16:29:27 +0000
Subject: [PATCH V4 00/11] perf/core: Add ability for an event to "pause"
 or "resume" AUX area tracing
In-Reply-To: <CAP-5=fUo96EABpH6=7i2cXFmZhAB2MM=UsnG-+vL4HJtLGS=bA@mail.gmail.com>
References: <20240111081914.3123-1-adrian.hunter@intel.com>
 <31bae596-ecb1-4b9c-9f1c-aaec4bcefd38@intel.com>
 <CAP-5=fUo96EABpH6=7i2cXFmZhAB2MM=UsnG-+vL4HJtLGS=bA@mail.gmail.com>
Message-ID: <a4c616ff-12bf-592b-b74d-407013a68cb7@arm.com>



On 31/01/2024 16:53, Ian Rogers wrote:
> On Mon, Jan 29, 2024 at 4:49?AM Adrian Hunter <adrian.hunter at intel.com> wrote:
>>
>> On 11/01/24 10:19, Adrian Hunter wrote:
>>> Hi
>>>
>>> Hardware traces, such as instruction traces, can produce a vast amount of
>>> trace data, so being able to reduce tracing to more specific circumstances
>>> can be useful.
>>>
>>> The ability to pause or resume tracing when another event happens, can do
>>> that.
>>>
>>> These patches add such a facilty and show how it would work for Intel
>>> Processor Trace.
>>>
>>> Maintainers of other AUX area tracing implementations are requested to
>>> consider if this is something they might employ and then whether or not
>>> the ABI would work for them.
>>>
>>> Changes to perf tools are now (since V4) fleshed out.
>>>
>>>
>>> Changes in V4:
>>>
>>>     perf/core: Add aux_pause, aux_resume, aux_start_paused
>>>       Rename aux_output_cfg -> aux_action
>>>       Reorder aux_action bits from:
>>>               aux_pause, aux_resume, aux_start_paused
>>>       to:
>>>               aux_start_paused, aux_pause, aux_resume
>>>       Fix aux_action bits __u64 -> __u32
>>>
>>>     coresight: Have a stab at support for pause / resume
>>>       Dropped
>>>
>>>     perf tools
>>>       All new patches
>>>
>>> Changes in RFC V3:
>>>
>>>     coresight: Have a stab at support for pause / resume
>>>       'mode' -> 'flags' so it at least compiles
>>>
>>> Changes in RFC V2:
>>>
>>>       Use ->stop() / ->start() instead of ->pause_resume()
>>>       Move aux_start_paused bit into aux_output_cfg
>>>       Tighten up when Intel PT pause / resume is allowed
>>>       Add an example of how it might work for CoreSight
>>
>> Any more comments?
> 
> I think the tools side looks good. The parsing changes match the
> existing style. I wonder if it wouldn't be better to handle the valid
> strings (pause, resume, etc.) in the lexer rather than a separate
> parse function, but the pattern used matches the existing one. You can
> have my Acked-by on the tools changes, although the subtleties of ARM
> PMUs makes me somewhat nervous in this regard.
> 
> Thanks,
> Ian

Acked-by: James Clark <james.clark at arm.com>

I will get round to adding the Coresight support at some point. I
checked the new parsing in this version and it seems to work ok.


From rsc at runtux.com  Thu Feb  1 08:30:12 2024
From: rsc at runtux.com (Ralf Schlatterbeck)
Date: Thu, 1 Feb 2024 17:30:12 +0100
Subject: [PATCH 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <20240201-tributary-fax-dd6055160dbe-mkl@pengutronix.de>
References: <20240201131540.3dlqoxlrrbzshz7w@runtux.com>
 <20240201-tributary-fax-dd6055160dbe-mkl@pengutronix.de>
Message-ID: <20240201163012.pf2ywwxwcd3rgsur@runtux.com>

On Thu, Feb 01, 2024 at 04:38:38PM +0100, Marc Kleine-Budde wrote:
> 
> nitpick: Please omit the line break change from this patch.

Thanks for the quick feedback!
I'll make a v2 when tomorrow there are no further comments.

Thanks
Ralf
-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   www.runtux.com
Reichergasse 131, A-3411 Weidling       email: office at runtux.com


From mripard at kernel.org  Thu Feb  1 08:50:07 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 1 Feb 2024 17:50:07 +0100
Subject: [PATCH v5 15/44] drm/connector: hdmi: Compute bpc and
 format automatically
In-Reply-To: <CAPY8ntAmXyKtebMeM7rLtgRR+QwL1H+UCwSO=bLBQN4TsgwsDg@mail.gmail.com>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-15-6538e19d634d@kernel.org>
 <CAPY8ntBQ+qY9441-rMzq_JAoYAaY_r+E-ADv7Wry0tJNTzKpwg@mail.gmail.com>
 <jlkoofv7nszj2uqmo2672yo4wjd3yjqarge2l2hxofixcchu6a@j72pa4iybitd>
 <CAPY8ntAmXyKtebMeM7rLtgRR+QwL1H+UCwSO=bLBQN4TsgwsDg@mail.gmail.com>
Message-ID: <vydlftxen23kd2odwegxbtpaz73sy2lgpv7nlynfjr3p2xvc2b@7lkdkaw3gp5q>

On Thu, Feb 01, 2024 at 03:33:24PM +0000, Dave Stevenson wrote:
> Hi Maxime
> 
> On Thu, 1 Feb 2024 at 12:51, Maxime Ripard <mripard at kernel.org> wrote:
> >
> > On Thu, Dec 14, 2023 at 03:10:43PM +0000, Dave Stevenson wrote:
> > > > +static bool
> > > > +sink_supports_format_bpc(const struct drm_connector *connector,
> > > > +                        const struct drm_display_info *info,
> > > > +                        const struct drm_display_mode *mode,
> > > > +                        unsigned int format, unsigned int bpc)
> > > > +{
> > > > +       struct drm_device *dev = connector->dev;
> > > > +       u8 vic = drm_match_cea_mode(mode);
> > > > +
> > > > +       if (vic == 1 && bpc != 8) {
> > > > +               drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
> > > > +               return false;
> > > > +       }
> > > > +
> > > > +       if (!info->is_hdmi &&
> > > > +           (format != HDMI_COLORSPACE_RGB || bpc != 8)) {
> > > > +               drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
> > > > +               return false;
> > > > +       }
> > > > +
> > > > +       if (!(connector->hdmi.supported_formats & BIT(format))) {
> > > > +               drm_dbg(dev, "%s format unsupported by the connector.\n",
> > > > +                       drm_hdmi_connector_get_output_format_name(format));
> > > > +               return false;
> > > > +       }
> > > > +
> > > > +       switch (format) {
> > > > +       case HDMI_COLORSPACE_RGB:
> > > > +               drm_dbg(dev, "RGB Format, checking the constraints.\n");
> > > > +
> > > > +               if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
> > > > +                       return false;
> > >
> > > We've dropped this check from vc4 in our downstream kernel as it stops
> > > you using the prebaked EDIDs (eg drm.edid_firmware=edid/1024x768.bin),
> > > or any other EDID that is defined as an analog monitor.
> > > The EDID parsing bombs out at [1], so info->color_formats gets left at 0.
> >
> > Right, but it only does so if the display isn't defined as a digital display...
> >
> > > RGB is mandatory for both DVI and HDMI, so rejecting it seems overly fussy.
> >
> > ... which is required for both DVI and HDMI.
> >
> > And sure enough, if we decode that EDID:
> >
> > edid-decode (hex):
> >
> > 00 ff ff ff ff ff ff 00 31 d8 00 00 00 00 00 00
> > 05 16 01 03 6d 23 1a 78 ea 5e c0 a4 59 4a 98 25
> > 20 50 54 00 08 00 61 40 01 01 01 01 01 01 01 01
> > 01 01 01 01 01 01 64 19 00 40 41 00 26 30 08 90
> > 36 00 63 0a 11 00 00 18 00 00 00 ff 00 4c 69 6e
> > 75 78 20 23 30 0a 20 20 20 20 00 00 00 fd 00 3b
> > 3d 2f 31 07 00 0a 20 20 20 20 20 20 00 00 00 fc
> > 00 4c 69 6e 75 78 20 58 47 41 0a 20 20 20 00 55
> >
> > ----------------
> >
> > Block 0, Base EDID:
> >   EDID Structure Version & Revision: 1.3
> >   Vendor & Product Identification:
> >     Manufacturer: LNX
> >     Model: 0
> >     Made in: week 5 of 2012
> >   Basic Display Parameters & Features:
> >     Analog display
> >     Signal Level Standard: 0.700 : 0.000 : 0.700 V p-p
> >     Blank level equals black level
> >     Sync: Separate Composite Serration
> >     Maximum image size: 35 cm x 26 cm
> >     Gamma: 2.20
> >     DPMS levels: Standby Suspend Off
> >     RGB color display
> >     First detailed timing is the preferred timing
> >   Color Characteristics:
> >     Red  : 0.6416, 0.3486
> >     Green: 0.2919, 0.5957
> >     Blue : 0.1474, 0.1250
> >     White: 0.3125, 0.3281
> >   Established Timings I & II:
> >     DMT 0x10:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz
> >   Standard Timings:
> >     DMT 0x10:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz
> >   Detailed Timing Descriptors:
> >     DTD 1:  1024x768    60.003840 Hz   4:3     48.363 kHz     65.000000 MHz (355 mm x 266 mm)
> >                  Hfront    8 Hsync 144 Hback  168 Hpol N
> >                  Vfront    3 Vsync   6 Vback   29 Vpol N
> >     Display Product Serial Number: 'Linux #0'
> >     Display Range Limits:
> >       Monitor ranges (GTF): 59-61 Hz V, 47-49 kHz H, max dotclock 70 MHz
> >     Display Product Name: 'Linux XGA'
> > Checksum: 0x55
> >
> > ----------------
> >
> > Warnings:
> >
> > Block 0, Base EDID:
> >   Detailed Timing Descriptor #1: DTD is similar but not identical to DMT 0x10.
> >
> > EDID conformity: PASS
> >
> > So, if anything, it's the EDID that needs to be updated, not the code there.
> 
> So are these EDIDs only valid for VGA outputs and another set needs to
> be added for HDMI monitors?
> 
> Having drm.edid_firmware=edid/1024x768.bin works on an HDMI connector
> prior to this patch, so presumably drm_edid_loader needs to
> automatically switch between the existing (analog) and new (digital)
> EDIDs based on the connector type? Or are you requiring users to
> change the strings they use?

We've discussed that on IRC today. I'm not sure there was a conclusion
other than "well this doesn't seem right". I think we should at least
provide different EDIDs depending on the connector type indeed, but
there was also a few discussions that arose:

  - Is it useful to have embedded EDIDs in the kernel at all, and could
    we just get rid of it?

  - Should we expose those EDIDs to userspace, and what happens to the
    compositor when we do?

  - The current way to generate those EDIDs isn't... optimal? Should we
    get rid of that as well?

Anyway, all of those issues have been here for a while so I don't really
expect this series to fix that.

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/20240201/8444ab1c/attachment.sig>

From helgaas at kernel.org  Thu Feb  1 08:50:25 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 1 Feb 2024 10:50:25 -0600
Subject: [PATCH v12 2/3] PCI: dwc: Implement general suspend/resume
 functionality for L2/L3 transitions
In-Reply-To: <20230821184815.2167131-3-Frank.Li@nxp.com>
Message-ID: <20240201165025.GA637154@bhelgaas>

On Mon, Aug 21, 2023 at 02:48:14PM -0400, Frank Li wrote:
> Introduce helper function dw_pcie_get_ltssm() to retrieve SMLH_LTSS_STATE.
> ...

> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index 615660640801..91d13f9b21b1 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h

> @@ -364,6 +375,7 @@ struct dw_pcie_ops {
>  	void    (*write_dbi2)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
>  			      size_t size, u32 val);
>  	int	(*link_up)(struct dw_pcie *pcie);
> +	enum dw_pcie_ltssm (*get_ltssm)(struct dw_pcie *pcie);

This has already been applied as
https://git.kernel.org/linus/4774faf854f5 ("PCI: dwc: Implement
generic suspend/resume functionality"), but this .get_ltssm() pointer
doesn't seem to be used anywhere.  Should we remove it until we need
it?

> +static inline enum dw_pcie_ltssm dw_pcie_get_ltssm(struct dw_pcie *pci)
> +{
> +	u32 val;
> +
> +	if (pci->ops && pci->ops->get_ltssm)
> +		return pci->ops->get_ltssm(pci);
> +
> +	val = dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0);
> +
> +	return (enum dw_pcie_ltssm)FIELD_GET(PORT_LOGIC_LTSSM_STATE_MASK, val);
> +}


From lkp at intel.com  Thu Feb  1 08:54:42 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 02 Feb 2024 00:54:42 +0800
Subject: [linux-next:master] BUILD REGRESSION
 51b70ff55ed88edd19b080a524063446bcc34b62
Message-ID: <202402020037.EMvofdJ6-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: 51b70ff55ed88edd19b080a524063446bcc34b62  Add linux-next specific files for 20240201

Error/Warning reports:

https://lore.kernel.org/oe-kbuild-all/202402011430.vDOuYPku-lkp at intel.com
https://lore.kernel.org/oe-kbuild-all/202402011519.RwyEbkrS-lkp at intel.com

Error/Warning: (recently discovered and may have been fixed)

iptable_nat.c:(.rodata+0x58): undefined reference to `ipt_do_table'
iptable_nat.c:(.text+0x228): undefined reference to `ipt_alloc_initial_table'
iptable_nat.c:(.text+0x294): undefined reference to `ipt_register_table'
iptable_nat.c:(.text+0x8): undefined reference to `ipt_unregister_table_exit'
ld.lld: error: undefined symbol: snd_pcm_format_big_endian
ld.lld: error: undefined symbol: snd_pcm_format_little_endian
ld.lld: error: undefined symbol: snd_pcm_format_name
ld.lld: error: undefined symbol: snd_pcm_format_physical_width
ld.lld: error: undefined symbol: snd_pcm_format_set_silence
ld.lld: error: undefined symbol: snd_pcm_format_signed
ld.lld: error: undefined symbol: snd_pcm_format_unsigned
ld.lld: error: undefined symbol: snd_pcm_format_width
loongarch64-linux-ld: iptable_nat.c:(.rodata+0x80): undefined reference to `ipt_do_table'
make[2]: *** kselftest/livepatch/test_modules: No such file or directory.  Stop.

Error/Warning ids grouped by kconfigs:

gcc_recent_errors
|-- arm-randconfig-001-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- arm-randconfig-002-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- arm-randconfig-004-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- arm-sama5_defconfig
|   |-- drivers-dma-at_hdmac.c:warning:Enum-value-ATC_IS_CYCLIC-not-described-in-enum-atc_status
|   `-- drivers-dma-at_hdmac.c:warning:Enum-value-ATC_IS_PAUSED-not-described-in-enum-atc_status
|-- arm64-randconfig-002-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- arm64-randconfig-004-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- csky-randconfig-r131-20240201
|   |-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- sound-core-sound_kunit.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-restricted-snd_pcm_format_t-usertype-format-got-int
|   `-- sound-core-sound_kunit.c:sparse:sparse:restricted-snd_pcm_format_t-degrades-to-integer
|-- i386-buildonly-randconfig-001-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-buildonly-randconfig-002-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-buildonly-randconfig-006-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-002-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-141-20240201
|   `-- mm-huge_memory.c-thpsize_create()-warn:Calling-kobject_put-get-with-state-initialized-unset-from-line:
|-- loongarch-randconfig-002-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- loongarch-randconfig-r004-20230730
|   |-- iptable_nat.c:(.rodata):undefined-reference-to-ipt_do_table
|   |-- iptable_nat.c:(.text):undefined-reference-to-ipt_alloc_initial_table
|   |-- iptable_nat.c:(.text):undefined-reference-to-ipt_register_table
|   |-- iptable_nat.c:(.text):undefined-reference-to-ipt_unregister_table_exit
|   `-- loongarch64-linux-ld:iptable_nat.c:(.rodata):undefined-reference-to-ipt_do_table
|-- loongarch-randconfig-r123-20240201
|   |-- mm-mempolicy.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-__to-got-unsigned-char-noderef-usertype-__rcu-new
|   `-- mm-mempolicy.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-__from-got-unsigned-char-noderef-usertype-__rcu-old
|-- m68k-randconfig-r111-20240201
|   `-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
|-- microblaze-randconfig-r133-20240201
|   |-- drivers-regulator-qcom_smd-regulator.c:sparse:sparse:symbol-smd_vreg_rpm-was-not-declared.-Should-it-be-static
|   `-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
|-- mips-allyesconfig
|   |-- (.ref.text):relocation-truncated-to-fit:R_MIPS_26-against-start_secondary
|   `-- (.text):relocation-truncated-to-fit:R_MIPS_26-against-kernel_entry
|-- powerpc-randconfig-003-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- sh-allmodconfig
|   `-- standard-input:Error:unknown-pseudo-op:cfi_def_
|-- sparc64-randconfig-002-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-allnoconfig
|   `-- Warning:Documentation-gpu-amdgpu-display-display-contributing.rst-references-a-file-that-doesn-t-exist:Documentation-GPU-amdgpu-display-mpo-overview.rst
|-- x86_64-buildonly-randconfig-003-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-005-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-015-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-071-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-074-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-161-20240201
|   |-- fs-bcachefs-btree_locking.c-bch2_trans_relock()-warn:passing-zero-to-PTR_ERR
|   |-- fs-bcachefs-buckets.c-bch2_trans_account_disk_usage_change()-error:we-previously-assumed-trans-disk_res-could-be-null-(see-line-)
|   `-- mm-huge_memory.c-thpsize_create()-warn:Calling-kobject_put-get-with-state-initialized-unset-from-line:
|-- x86_64-randconfig-r123-20240201
|   `-- lib-checksum_kunit.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-restricted-__wsum-usertype-sum-got-unsigned-int-assigned-csum
|-- x86_64-randconfig-r132-20240201
|   `-- lib-checksum_kunit.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-restricted-__wsum-usertype-sum-got-unsigned-int-assigned-csum
`-- x86_64-rhel-8.3-bpf
    `-- make:kselftest-livepatch-test_modules:No-such-file-or-directory.-Stop.
clang_recent_errors
|-- arm-defconfig
|   |-- drivers-dma-at_hdmac.c:warning:Enum-value-ATC_IS_CYCLIC-not-described-in-enum-atc_status
|   `-- drivers-dma-at_hdmac.c:warning:Enum-value-ATC_IS_PAUSED-not-described-in-enum-atc_status
|-- arm-randconfig-002-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- arm-randconfig-004-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- arm64-randconfig-002-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- hexagon-randconfig-r015-20220417
|   |-- ld.lld:error:undefined-symbol:snd_pcm_format_big_endian
|   |-- ld.lld:error:undefined-symbol:snd_pcm_format_little_endian
|   |-- ld.lld:error:undefined-symbol:snd_pcm_format_name
|   |-- ld.lld:error:undefined-symbol:snd_pcm_format_physical_width
|   |-- ld.lld:error:undefined-symbol:snd_pcm_format_set_silence
|   |-- ld.lld:error:undefined-symbol:snd_pcm_format_signed
|   |-- ld.lld:error:undefined-symbol:snd_pcm_format_unsigned
|   `-- ld.lld:error:undefined-symbol:snd_pcm_format_width
|-- hexagon-randconfig-r113-20240201
|   |-- drivers-regulator-qcom_smd-regulator.c:sparse:sparse:symbol-smd_vreg_rpm-was-not-declared.-Should-it-be-static
|   |-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|   |-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
|   `-- net-core-sock_diag.c:sparse:sparse:Using-plain-integer-as-NULL-pointer
|-- riscv-randconfig-002-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-buildonly-randconfig-003-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-006-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-072-20240201
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-122-20240201
|   `-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
`-- x86_64-rhel-8.3-rust
    `-- error-E0425:cannot-find-value-WORK_CPU_UNBOUND-in-crate-bindings

elapsed time: 731m

configs tested: 176
configs skipped: 4

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                   randconfig-001-20240201   gcc  
arc                   randconfig-002-20240201   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   gcc  
arm                              allyesconfig   gcc  
arm                     davinci_all_defconfig   clang
arm                                 defconfig   clang
arm                        mvebu_v5_defconfig   clang
arm                             mxs_defconfig   clang
arm                         orion5x_defconfig   clang
arm                   randconfig-001-20240201   gcc  
arm                   randconfig-002-20240201   clang
arm                   randconfig-002-20240201   gcc  
arm                   randconfig-003-20240201   gcc  
arm                   randconfig-004-20240201   clang
arm                   randconfig-004-20240201   gcc  
arm                           sama5_defconfig   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240201   gcc  
arm64                 randconfig-002-20240201   clang
arm64                 randconfig-002-20240201   gcc  
arm64                 randconfig-003-20240201   gcc  
arm64                 randconfig-004-20240201   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240201   gcc  
csky                  randconfig-002-20240201   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
hexagon               randconfig-001-20240201   clang
hexagon               randconfig-002-20240201   clang
i386                             allmodconfig   clang
i386                              allnoconfig   clang
i386                             allyesconfig   clang
i386         buildonly-randconfig-001-20240201   gcc  
i386         buildonly-randconfig-002-20240201   gcc  
i386         buildonly-randconfig-003-20240201   gcc  
i386         buildonly-randconfig-004-20240201   gcc  
i386         buildonly-randconfig-005-20240201   gcc  
i386         buildonly-randconfig-006-20240201   gcc  
i386                                defconfig   gcc  
i386                  randconfig-001-20240201   gcc  
i386                  randconfig-002-20240201   gcc  
i386                  randconfig-003-20240201   gcc  
i386                  randconfig-004-20240201   gcc  
i386                  randconfig-005-20240201   gcc  
i386                  randconfig-006-20240201   gcc  
i386                  randconfig-011-20240201   clang
i386                  randconfig-012-20240201   clang
i386                  randconfig-013-20240201   clang
i386                  randconfig-014-20240201   clang
i386                  randconfig-015-20240201   clang
i386                  randconfig-016-20240201   clang
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240201   gcc  
loongarch             randconfig-002-20240201   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
m68k                            mac_defconfig   gcc  
m68k                            q40_defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                              allnoconfig   clang
mips                             allyesconfig   gcc  
mips                           gcw0_defconfig   gcc  
mips                            gpr_defconfig   gcc  
mips                      loongson3_defconfig   gcc  
mips                      malta_kvm_defconfig   clang
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240201   gcc  
nios2                 randconfig-002-20240201   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                generic-64bit_defconfig   gcc  
parisc                randconfig-001-20240201   gcc  
parisc                randconfig-002-20240201   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc                     ep8248e_defconfig   gcc  
powerpc                      ppc64e_defconfig   clang
powerpc               randconfig-001-20240201   clang
powerpc               randconfig-001-20240201   gcc  
powerpc               randconfig-002-20240201   clang
powerpc               randconfig-002-20240201   gcc  
powerpc               randconfig-003-20240201   gcc  
powerpc64             randconfig-001-20240201   clang
powerpc64             randconfig-002-20240201   clang
powerpc64             randconfig-003-20240201   gcc  
riscv                            allmodconfig   clang
riscv                             allnoconfig   clang
riscv                            allyesconfig   clang
riscv                               defconfig   gcc  
riscv                 randconfig-001-20240201   gcc  
riscv                 randconfig-002-20240201   clang
s390                             allmodconfig   gcc  
s390                              allnoconfig   gcc  
s390                             allyesconfig   gcc  
s390                                defconfig   gcc  
s390                  randconfig-001-20240201   gcc  
s390                  randconfig-002-20240201   clang
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                          lboxre2_defconfig   gcc  
sh                    randconfig-001-20240201   gcc  
sh                    randconfig-002-20240201   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240201   gcc  
sparc64               randconfig-002-20240201   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   clang
um                                  defconfig   gcc  
um                             i386_defconfig   gcc  
um                    randconfig-001-20240201   gcc  
um                    randconfig-002-20240201   gcc  
um                           x86_64_defconfig   gcc  
x86_64                            allnoconfig   gcc  
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240201   clang
x86_64       buildonly-randconfig-002-20240201   clang
x86_64       buildonly-randconfig-003-20240201   clang
x86_64       buildonly-randconfig-003-20240201   gcc  
x86_64       buildonly-randconfig-004-20240201   clang
x86_64       buildonly-randconfig-005-20240201   clang
x86_64       buildonly-randconfig-006-20240201   gcc  
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240201   clang
x86_64                randconfig-002-20240201   gcc  
x86_64                randconfig-003-20240201   gcc  
x86_64                randconfig-004-20240201   gcc  
x86_64                randconfig-005-20240201   gcc  
x86_64                randconfig-006-20240201   clang
x86_64                randconfig-011-20240201   clang
x86_64                randconfig-012-20240201   gcc  
x86_64                randconfig-013-20240201   gcc  
x86_64                randconfig-014-20240201   clang
x86_64                randconfig-015-20240201   gcc  
x86_64                randconfig-016-20240201   gcc  
x86_64                randconfig-071-20240201   gcc  
x86_64                randconfig-072-20240201   clang
x86_64                randconfig-073-20240201   clang
x86_64                randconfig-074-20240201   gcc  
x86_64                          rhel-8.3-rust   clang
xtensa                            allnoconfig   gcc  
xtensa                randconfig-001-20240201   gcc  
xtensa                randconfig-002-20240201   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From mripard at kernel.org  Thu Feb  1 09:01:01 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 1 Feb 2024 18:01:01 +0100
Subject: [PATCH 0/4] Fixing live video input in ZynqMP DPSUB
In-Reply-To: <MW4PR12MB7165D35189BEECA8769552AFE6792@MW4PR12MB7165.namprd12.prod.outlook.com>
References: <20240112234222.913138-1-anatoliy.klymenko@amd.com>
 <6jhwss2wego6yoo5mwmphwawhsj5bbj62gwrzcpapoixwkrkli@g4fbxdooopby>
 <20240117142343.GD17920@pendragon.ideasonboard.com>
 <u5mngxudtdgy3vqkfbpgqng6tdahijnet2jtj345hrowbt47ce@t3e7hul45mr3>
 <MW4PR12MB7165D35189BEECA8769552AFE6792@MW4PR12MB7165.namprd12.prod.outlook.com>
Message-ID: <2ytxhpti53e743b5pca3oa5jmscffi4vpsyeh727bcoh4v6cuw@zkz5pqkcv7v2>

On Fri, Jan 26, 2024 at 11:18:30PM +0000, Klymenko, Anatoliy wrote:
> 
> 
> > -----Original Message-----
> > From: Maxime Ripard <mripard at kernel.org>
> > Sent: Friday, January 26, 2024 4:26 AM
> > To: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > Cc: Klymenko, Anatoliy <Anatoliy.Klymenko at amd.com>;
> > maarten.lankhorst at linux.intel.com; tzimmermann at suse.de; airlied at gmail.com;
> > daniel at ffwll.ch; Simek, Michal <michal.simek at amd.com>; dri-
> > devel at lists.freedesktop.org; linux-arm-kernel at lists.infradead.org; linux-
> > kernel at vger.kernel.org
> > Subject: Re: Re: [PATCH 0/4] Fixing live video input in ZynqMP DPSUB
> > 
> > On Wed, Jan 17, 2024 at 04:23:43PM +0200, Laurent Pinchart wrote:
> > > On Mon, Jan 15, 2024 at 09:28:39AM +0100, Maxime Ripard wrote:
> > > > On Fri, Jan 12, 2024 at 03:42:18PM -0800, Anatoliy Klymenko wrote:
> > > > > Patches 1/4,2/4,3/4 are minor fixes.
> > > > >
> > > > > DPSUB requires input live video format to be configured.
> > > > > Patch 4/4: The DP Subsystem requires the input live video format to be
> > > > > configured. In this patch we are assuming that the CRTC's bus format is fixed
> > > > > and comes from the device tree. This is a proposed solution, as there are no
> > api
> > > > > to query CRTC output bus format.
> > > > >
> > > > > Is this a good approach to go with?
> > > >
> > > > I guess you would need to expand a bit on what "live video input" is? Is
> > > > it some kind of mechanism to bypass memory and take your pixels straight
> > > > from a FIFO from another device, or something else?
> > >
> > > Yes and no.
> > >
> > > The DPSUB integrates DMA engines, a blending engine (two planes), and a
> > > DP encoder. The dpsub driver supports all of this, and creates a DRM
> > > device. The DP encoder hardware always takes its input data from the
> > > output of the blending engine.
> > >
> > > The blending engine can optionally take input data from a bus connected
> > > to the FPGA fabric, instead of taking it from the DPSUB internal DMA
> > > engines. When operating in that mode, the dpsub driver exposes the DP
> > > encoder as a bridge, and internally programs the blending engine to
> > > disable blending. Typically, the FPGA fabric will then contain a CRTC of
> > > some sort, with a driver that will acquire the DP encoder bridge as
> > > usually done.
> > >
> > > In this mode of operation, it is typical for the IP cores in FPGA fabric
> > > to be synthesized with a fixed format (as that saves resources), while
> > > the DPSUB supports multiple input formats.
> > 
> > Where is that CRTC driver? It's not clear to me why the format would
> > need to be in the device tree at all. Format negociation between the
> > CRTC and whatever comes next is already done in a number of drivers so
> > it would be useful to have that kind of API outside of the bridge
> > support.
>
> One example of such CRTC driver:
> https://github.com/Xilinx/linux-xlnx/blob/master/drivers/gpu/drm/xlnx/xlnx_mixer.c It's not
> upstreamed yet. Bus format negotiations here are handled by utilizing Xilinx-specific bridge
> framework. Ideally, it would be nice to rework this to comply with the upstream DRM bridge
> framework.
>
> > > Bridge drivers in the upstream kernel work the other way around, with
> > > the bridge hardware supporting a limited set of formats, and the CRTC
> > > then being programmed with whatever the bridges chain needs. Here, the
> > > negotiation needs to go the other way around, as the CRTC is the
> > > limiting factor, not the bridge.
> > 
> > Sounds like there's something to rework in the API then?
> > 
> Adding an optional CRTC callback imposing CRTC specific bus format restrictions, which may be
> called from here https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/drm_bridge.c#L935
> would solve the problem.

CRTCs and bridges are orthogonal. If anything, I'd expect that callback
to be set at the CRTC, encoder and connector levels and filled by the
drm_bridge code if relevant.

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/20240201/3622e314/attachment.sig>

From Frank.li at nxp.com  Thu Feb  1 09:08:23 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 1 Feb 2024 12:08:23 -0500
Subject: [PATCH v12 2/3] PCI: dwc: Implement general suspend/resume
 functionality for L2/L3 transitions
In-Reply-To: <20240201165025.GA637154@bhelgaas>
References: <20230821184815.2167131-3-Frank.Li@nxp.com>
 <20240201165025.GA637154@bhelgaas>
Message-ID: <ZbvQB/X0kwFs7nAb@lizhi-Precision-Tower-5810>

On Thu, Feb 01, 2024 at 10:50:25AM -0600, Bjorn Helgaas wrote:
> On Mon, Aug 21, 2023 at 02:48:14PM -0400, Frank Li wrote:
> > Introduce helper function dw_pcie_get_ltssm() to retrieve SMLH_LTSS_STATE.
> > ...
> 
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > index 615660640801..91d13f9b21b1 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> 
> > @@ -364,6 +375,7 @@ struct dw_pcie_ops {
> >  	void    (*write_dbi2)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
> >  			      size_t size, u32 val);
> >  	int	(*link_up)(struct dw_pcie *pcie);
> > +	enum dw_pcie_ltssm (*get_ltssm)(struct dw_pcie *pcie);
> 
> This has already been applied as
> https://git.kernel.org/linus/4774faf854f5 ("PCI: dwc: Implement
> generic suspend/resume functionality"), but this .get_ltssm() pointer
> doesn't seem to be used anywhere.  Should we remove it until we need
> it?

Could you place hold on for a while? I am working on imx PCIe. One old
imx6 may need it!

If not, I will submit patch to clean it. My new patches depend on

https://lore.kernel.org/imx/ZbJ+tFPn3aOYHCwf at lizhi-Precision-Tower-5810/T/#t

All already reviewed, could you please pick up these, so I can continue
my futher work.

Another
https://lore.kernel.org/imx/20240201-pme_msg-v2-0-6767052fe6a4 at nxp.com/T/#t
was under review.

After these, suspend/resume will become simple and common for all dwc
platform.

Frank.

> 
> > +static inline enum dw_pcie_ltssm dw_pcie_get_ltssm(struct dw_pcie *pci)
> > +{
> > +	u32 val;
> > +
> > +	if (pci->ops && pci->ops->get_ltssm)
> > +		return pci->ops->get_ltssm(pci);
> > +
> > +	val = dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0);
> > +
> > +	return (enum dw_pcie_ltssm)FIELD_GET(PORT_LOGIC_LTSSM_STATE_MASK, val);
> > +}


From quic_obabatun at quicinc.com  Thu Feb  1 09:08:06 2024
From: quic_obabatun at quicinc.com (Oreoluwa Babatunde)
Date: Thu, 1 Feb 2024 09:08:06 -0800
Subject: [PATCH 00/46] Dynamic allocation of reserved_mem array.
In-Reply-To: <20240131000710.GA2581425-robh@kernel.org>
References: <20240126235425.12233-1-quic_obabatun@quicinc.com>
 <20240131000710.GA2581425-robh@kernel.org>
Message-ID: <51dc64bb-3101-4b4a-a54f-c0df6c0b264c@quicinc.com>


On 1/30/2024 4:07 PM, Rob Herring wrote:
> On Fri, Jan 26, 2024 at 03:53:39PM -0800, Oreoluwa Babatunde wrote:
>> The reserved_mem array is used to store data for the different
>> reserved memory regions defined in the DT of a device.  The array
>> stores information such as region name, node, start-address, and size
>> of the reserved memory regions.
>>
>> The array is currently statically allocated with a size of
>> MAX_RESERVED_REGIONS(64). This means that any system that specifies a
>> number of reserved memory regions greater than MAX_RESERVED_REGIONS(64)
>> will not have enough space to store the information for all the regions.
>>
>> Therefore, this series extends the use of the static array for
>> reserved_mem, and introduces a dynamically allocated array using
>> memblock_alloc() based on the number of reserved memory regions
>> specified in the DT.
>>
>> Some architectures such as arm64 require the page tables to be setup
>> before memblock allocated memory is writable.  Therefore, the dynamic
>> allocation of the reserved_mem array will need to be done after the
>> page tables have been setup on these architectures. In most cases that
>> will be after paging_init().
>>
>> Reserved memory regions can be divided into 2 groups.
>> i) Statically-placed reserved memory regions
>> i.e. regions defined in the DT using the @reg property.
>> ii) Dynamically-placed reserved memory regions.
>> i.e. regions specified in the DT using the @alloc_ranges
>>     and @size properties.
>>
>> It is possible to call memblock_reserve() and memblock_mark_nomap() on
>> the statically-placed reserved memory regions and not need to save them
>> to the reserved_mem array until memory is allocated for it using
>> memblock, which will be after the page tables have been setup.
>> For the dynamically-placed reserved memory regions, it is not possible
>> to wait to store its information because the starting address is
>> allocated only at run time, and hence they need to be stored somewhere
>> after they are allocated.
>> Waiting until after the page tables have been setup to allocate memory
>> for the dynamically-placed regions is also not an option because the
>> allocations will come from memory that have already been added to the
>> page tables, which is not good for memory that is supposed to be
>> reserved and/or marked as nomap.
>>
>> Therefore, this series splits up the processing of the reserved memory
>> regions into two stages, of which the first stage is carried out by
>> early_init_fdt_scan_reserved_mem() and the second is carried out by
>> fdt_init_reserved_mem().
>>
>> The early_init_fdt_scan_reserved_mem(), which is called before the page
>> tables are setup is used to:
>> 1. Call memblock_reserve() and memblock_mark_nomap() on all the
>>    statically-placed reserved memory regions as needed.
>> 2. Allocate memory from memblock for the dynamically-placed reserved
>>    memory regions and store them in the static array for reserved_mem.
>>    memblock_reserve() and memblock_mark_nomap() are also called as
>>    needed on all the memory allocated for the dynamically-placed
>>    regions.
>> 3. Count the total number of reserved memory regions found in the DT.
>>
>> fdt_init_reserved_mem(), which should be called after the page tables
>> have been setup, is used to carry out the following:
>> 1. Allocate memory for the reserved_mem array based on the number of
>>    reserved memory regions counted as mentioned above.
>> 2. Copy all the information for the dynamically-placed reserved memory
>>    regions from the static array into the new allocated memory for the
>>    reserved_mem array.
>> 3. Add the information for the statically-placed reserved memory into
>>    reserved_mem array.
>> 4. Run the region specific init functions for each of the reserve memory
>>    regions saved in the reserved_mem array.
> I don't see the need for fdt_init_reserved_mem() to be explicitly called 
> by arch code. I said this already, but that can be done at the same time 
> as unflattening the DT. The same conditions are needed for both: we need 
> to be able to allocate memory from memblock.
>
> To put it another way, if fdt_init_reserved_mem() can be called "early", 
> then unflattening could be moved earlier as well. Though I don't think 
> we should optimize that. I'd rather see all arches call the DT functions 
> at the same stages.
Hi Rob,

The reason we moved fdt_init_reserved_mem() back into the arch specific code
was because we realized that there was no apparently obvious way to call
early_init_fdt_scan_reserved_mem() and fdt_init_reserved_mem() in the correct
order that will work for all archs if we placed fdt_init_reserved_mem() inside the
unflatten_devicetree() function.

early_init_fdt_scan_reserved_mem() needs to be
called first before fdt_init_reserved_mem(). But on some archs,
unflatten_devicetree() is called before early_init_fdt_scan_reserved_mem(), which
means that if we have fdt_init_reserved_mem() inside the unflatten_devicetree()
function, it will be called before early_init_fdt_scan_reserved_mem().

This is connected to your other comments on Patch 7 & Patch 14.
I agree, unflatten_devicetree() should NOT be getting called before we reserve
memory for the reserved memory regions because that could cause memory to be
allocated from regions that should be reserved.

Hence, resolving this issue should allow us to call fdt_init_reserved_mem() from
the? unflatten_devicetree() function without it changing the order that we are
trying to have.

I will work on implementing this and send another revision.
>
>> Once the above steps have been completed and the init process is done
>> running, the original statically allocated reserved_mem array of size
>> MAX_RESERVED_REGIONS(64) will be automatically freed back to buddy
>> because it is no longer needed. This is done by marking the array as an
>> "__initdata" object in Patch 0018.
>>
>> Note:
>>
>> - Per Architecture, this series is effectively only 10 patches. The
>>   code for each architecture is split up into separate patches to
>>   allow each architecture to be tested independently of changes from
>>   other architectures. Should this series be accepted, this should
>>   allow for each arcitecture change to be picked up independently as
>>   well.
> Only if patches 1 and 2 are accepted in one cycle and the arch ones in 
> the next cycle. No need for that though, I can take the whole thing 
> (when it's ready).
ack.
>
>>   Patch 0001: Splits up the processing of the reserved memory regions
>>   between early_init_fdt_scan_reserved_mem and fdt_init_reserved_mem.
>>
>>   Patch 0002: Introduces a copy of early_init_fdt_scan_reserved_mem()
>>   which is used to separate it from fdt_init_reserved_mem() so that the
>>   two functions can be called independently of each other.
>>
>>   Patch 0003 - Patch 0016: Duplicated change for each architecture to
>>   call early_init_fdt_scan_reserved_mem() and fdt_init_reserved_mem()
>>   at their appropriate locations. Here fdt_init_reserved_mem() is called
>>   either before of after the page tables have been setup depending on
>>   the architecture requirements.
>>
>>   Patch 0017: Deletes the early_init_fdt_scan_reserved_mem() function
>>   since all architectures are now using the copy introduced in
>>   Patch 0002.
>>
>>   Patch 0018: Dynamically allocate memory for the reserved_mem array
>>   based on the total number of reserved memory regions specified in the
>>   DT.
>>
>>   Patch 0019 - Patch 0029: Duplicated change for each architecture to
>>   move the fdt_init_reserved_mem() function call to below the
>>   unflatten_devicetree() function call. This is so that the unflatten
>>   devicetree APIs can be used to process the reserved memory regions.
>>
>>   Patch 0030: Make code changes to start using the unflatten devicetree
>>   APIs to access the reserved memory regions defined in the DT.
>>
>>   Patch 0031: Rename fdt_* functions as dt_* to refelct that the
>>   flattened devicetree (fdt) APIs have been replaced with the unflatten
>>   devicetree APIs.
>>
>>   Patch 0032 - Patch 0045: Duplicated change for each architecture to
>>   switch from the use of fdt_init_reserved_mem() to
>>   dt_init_reserved_mem(), which is the same function but the later uses
>>   the unflatten devicetree APIs.
>>
>>   Patch 0046: Delete the fdt_init_reserved_mem() function as all
>>   architectures have switched to using dt_init_reserved_mem() which was
>>   introduced in Patch 0031.
>>
>> - The limitation to this approach is that there is still a limit of
>>   64 for dynamically-placed reserved memory regions. But from my current
>>   analysis, these types of reserved memory regions are generally less
>>   in number when compared to the statically-placed reserved memory
>>   regions.
>>
>> - I have looked through all architectures and placed the call to
>>   memblock_alloc() for the reserved_mem array at points where I
>>   believe memblock allocated memory are available to be written to.
>>   I currently only have access to an arm64 device and this is where I am
>>   testing the functionality of this series. Hence, I will need help from
>>   architecture maintainers to test this series on other architectures to
>>   ensure that the code is functioning properly on there.
>>
>> Previous patch revisions:
>> 1. [RFC V1 Patchset]:
>> https://lore.kernel.org/all/20231019184825.9712-1-quic_obabatun at quicinc.com/
>>
>> 2. [RFC V2 Patchset]:
>> https://lore.kernel.org/all/20231204041339.9902-1-quic_obabatun at quicinc.com/
>> - Extend changes to all other relevant architectures.
>> - Add code to use unflatten devicetree APIs to process the reserved
>>   memory regions.
> Dropping RFC does not make this v1. RFC is a state of the patches not a 
> version.
ack.


Thank you for your comments!

Oreoluwa


From avromanov at salutedevices.com  Thu Feb  1 09:13:56 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Thu, 1 Feb 2024 17:13:56 +0000
Subject: [PATCH v2 03/20] drviers: crypto: meson: add platform data
In-Reply-To: <ZbC8qLXogjxJD8LD@Red>
References: <20240123165831.970023-1-avromanov@salutedevices.com>
 <20240123165831.970023-4-avromanov@salutedevices.com> <ZbC8qLXogjxJD8LD@Red>
Message-ID: <20240201171352.ut5xhw3u2b77v33d@cab-wsm-0029881>

Hello,

On Wed, Jan 24, 2024 at 08:30:48AM +0100, Corentin Labbe wrote:
> Le Tue, Jan 23, 2024 at 07:58:14PM +0300, Alexey Romanov a 'ecrit :
> > To support other Amlogic SoC's we have to
> > use platform data: descriptors and status registers
> > offsets are individual for each SoC series.
> > 
> > Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> > ---
> >  drivers/crypto/amlogic/amlogic-gxl-cipher.c |  2 +-
> >  drivers/crypto/amlogic/amlogic-gxl-core.c   | 31 +++++++++++++++------
> >  drivers/crypto/amlogic/amlogic-gxl.h        | 11 ++++++++
> >  3 files changed, 35 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> > index b19032f92415..7eff3ae7356f 100644
> > --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> > +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> > @@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)
> >  
> >  	reinit_completion(&mc->chanlist[flow].complete);
> >  	mc->chanlist[flow].status = 0;
> > -	writel(mc->chanlist[flow].t_phy | 2, mc->base + (flow << 2));
> > +	writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
> >  	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
> >  						  msecs_to_jiffies(500));
> >  	if (mc->chanlist[flow].status == 0) {
> > diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> > index a58644be76e9..2be381e157c4 100644
> > --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> > +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> > @@ -18,6 +18,7 @@
> >  #include <linux/kernel.h>
> >  #include <linux/module.h>
> >  #include <linux/of.h>
> > +#include <linux/of_device.h>
> >  #include <linux/platform_device.h>
> >  
> >  #include "amlogic-gxl.h"
> > @@ -30,9 +31,10 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
> >  
> >  	for (flow = 0; flow < mc->flow_cnt; flow++) {
> >  		if (mc->chanlist[flow].irq == irq) {
> > -			p = readl(mc->base + ((0x04 + flow) << 2));
> > +			p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
> >  			if (p) {
> > -				writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
> > +				writel_relaxed(0xF, mc->base +
> > +					      ((mc->pdata->status_reg + flow) << 2));
> >  				mc->chanlist[flow].status = 1;
> >  				complete(&mc->chanlist[flow].complete);
> >  				return IRQ_HANDLED;
> > @@ -245,15 +247,34 @@ static void meson_unregister_algs(struct meson_dev *mc)
> >  	}
> >  }
> >  
> > +static const struct meson_pdata meson_gxl_pdata = {
> > +	.descs_reg = 0x0,
> > +	.status_reg = 0x4,
> > +};
> > +
> > +static const struct of_device_id meson_crypto_of_match_table[] = {
> > +	{
> > +		.compatible = "amlogic,gxl-crypto",
> > +		.data = &meson_gxl_pdata,
> > +	},
> > +	{},
> > +};
> > +
> >  static int meson_crypto_probe(struct platform_device *pdev)
> >  {
> > +	const struct of_device_id *match;
> >  	struct meson_dev *mc;
> >  	int err;
> >  
> > +	match = of_match_device(meson_crypto_of_match_table, &pdev->dev);
> > +	if (!match)
> > +		return -EINVAL;
> > +
> >  	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
> >  	if (!mc)
> >  		return -ENOMEM;
> >  
> > +	mc->pdata = match->data;
> >  	mc->dev = &pdev->dev;
> >  	platform_set_drvdata(pdev, mc);
> >  
> > @@ -312,12 +333,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
> >  	clk_disable_unprepare(mc->busclk);
> >  }
> >  
> > -static const struct of_device_id meson_crypto_of_match_table[] = {
> > -	{ .compatible = "amlogic,gxl-crypto", },
> > -	{}
> > -};
> > -MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
> 
> Hello
> 
> This patch breaks bisection, since it removes MODULE_DEVICE_TABLE.
> After applying patchs 1,2,3 the driver does not load anymore on lepotato board.

Please, give more information. 

I applied the first 3 patches and the driver probes correctly.

> 
> Regards

-- 
Thank you,
Alexey

From quic_obabatun at quicinc.com  Thu Feb  1 09:15:20 2024
From: quic_obabatun at quicinc.com (Oreoluwa Babatunde)
Date: Thu, 1 Feb 2024 09:15:20 -0800
Subject: [PATCH 14/46] sh: reserved_mem: Implement the new processing
 order for reserved memory
In-Reply-To: <20240131154130.GA1336725-robh@kernel.org>
References: <20240126235425.12233-1-quic_obabatun@quicinc.com>
 <20240126235425.12233-15-quic_obabatun@quicinc.com>
 <20240131154130.GA1336725-robh@kernel.org>
Message-ID: <a574e6ac-1ac7-4c27-b6eb-58225033262c@quicinc.com>


On 1/31/2024 7:41 AM, Rob Herring wrote:
> On Fri, Jan 26, 2024 at 03:53:53PM -0800, Oreoluwa Babatunde wrote:
>> Call early_fdt_scan_reserved_mem() in place of
>> early_init_fdt_scan_reserved_mem() to carry out the first stage of the
>> reserved memory processing only.
>>
>> The early_fdt_scan_reserved_mem() function is used to scan through the
>> DT and mark all the reserved memory regions as reserved or nomap as
>> needed, as well as allocate the memory required by the
>> dynamically-placed
>> reserved memory regions.
>>
>> The second stage of the reserved memory processing is done by
>> fdt_init_reserved_mem(). This function is used to store the information
>> of the statically-placed reserved memory nodes in the reserved_mem
>> array as well as call the region specific initialization function on all
>> the stored reserved memory regions.
>>
>> The call to fdt_init_reserved_mem() is placed right after
>> early_fdt_scan_reserved_mem() because memblock allocated memory should
>> already be writable at this point.
>>
>> Signed-off-by: Oreoluwa Babatunde <quic_obabatun at quicinc.com>
>> ---
>>  arch/sh/boards/of-generic.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
>> index f7f3e618e85b..7bec409f077c 100644
>> --- a/arch/sh/boards/of-generic.c
>> +++ b/arch/sh/boards/of-generic.c
>> @@ -8,6 +8,7 @@
>>  #include <linux/of.h>
>>  #include <linux/of_clk.h>
>>  #include <linux/of_fdt.h>
>> +#include <linux/of_reserved_mem.h>
>>  #include <linux/clocksource.h>
>>  #include <linux/irqchip.h>
>>  #include <asm/machvec.h>
>> @@ -110,7 +111,8 @@ static int noopi(void)
>>  static void __init sh_of_mem_reserve(void)
>>  {
>>  	early_init_fdt_reserve_self();
>> -	early_init_fdt_scan_reserved_mem();
>> +	early_fdt_scan_reserved_mem();
>> +	fdt_init_reserved_mem();
> Looking at the sh code, there's an existing problem with the order of
> init. This is called from paging_init() and is done after unflattening
> and copying the DT. That means the kernel could freely allocate memory
> for the DT in a reserved region.
>
> Rob

Hi Rob,

Yes I agree! I can try to restructure the code to address
this. I think we should be able to move the call to
early_init_fdt_scan_reserved_mem() higher in the init
sequence without having any issues.

Will try this out and see.

Regards,
Oreoluwa



From quic_obabatun at quicinc.com  Thu Feb  1 09:17:36 2024
From: quic_obabatun at quicinc.com (Oreoluwa Babatunde)
Date: Thu, 1 Feb 2024 09:17:36 -0800
Subject: [PATCH 07/46] Loongarch: reserved_mem: Implement the new
 processing order for reserved memory
In-Reply-To: <20240131152709.GA1272666-robh@kernel.org>
References: <20240126235425.12233-1-quic_obabatun@quicinc.com>
 <20240126235425.12233-8-quic_obabatun@quicinc.com>
 <20240131152709.GA1272666-robh@kernel.org>
Message-ID: <c1d00213-bc4c-4f1a-b577-2cc95b62d7f9@quicinc.com>


On 1/31/2024 7:27 AM, Rob Herring wrote:
> On Fri, Jan 26, 2024 at 03:53:46PM -0800, Oreoluwa Babatunde wrote:
>> Call early_fdt_scan_reserved_mem() in place of
>> early_init_fdt_scan_reserved_mem() to carry out the first stage of the
>> reserved memory processing only.
>>
>> The early_fdt_scan_reserved_mem() function is used to scan through the
>> DT and mark all the reserved memory regions as reserved or nomap as
>> needed, as well as allocate the memory required by the
>> dynamically-placed
>> reserved memory regions.
>>
>> The second stage of the reserved memory processing is done by
>> fdt_init_reserved_mem(). This function is used to store the information
>> of the statically-placed reserved memory nodes in the reserved_mem
>> array as well as call the region specific initialization function on all
>> the stored reserved memory regions.
>>
>> The call to fdt_init_reserved_mem() is placed right after
>> early_fdt_scan_reserved_mem() since memblock allocated memory should
>> already be writable at this point.
>>
>> Signed-off-by: Oreoluwa Babatunde <quic_obabatun at quicinc.com>
>> ---
>>  arch/loongarch/kernel/setup.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
>> index edf2bba80130..72b164d3ace0 100644
>> --- a/arch/loongarch/kernel/setup.c
>> +++ b/arch/loongarch/kernel/setup.c
>> @@ -30,6 +30,7 @@
>>  #include <linux/dma-map-ops.h>
>>  #include <linux/libfdt.h>
>>  #include <linux/of_fdt.h>
>> +#include <linux/of_reserved_mem.h>
>>  #include <linux/of_address.h>
>>  #include <linux/suspend.h>
>>  #include <linux/swiotlb.h>
>> @@ -390,8 +391,9 @@ static void __init arch_mem_init(char **cmdline_p)
>>  
>>  	check_kernel_sections_mem();
>>  
>> -	early_init_fdt_scan_reserved_mem();
>> +	early_fdt_scan_reserved_mem();
> Looking at the loongarch code, there's an existing problem with the 
> order of init. This is done after unflattening and copying the DT. That 
> means the kernel could freely allocate memory for the DT in a reserved 
> region.
>
> Rob
Same here, I think we should be able to move the call to
early_init_fdt_scan_reserved_mem() higher in the init
sequence without having any issues.

Will try this out and see.

Regards,
Oreoluwa



From alexey.klimov at linaro.org  Thu Feb  1 09:22:21 2024
From: alexey.klimov at linaro.org (Alexey Klimov)
Date: Thu,  1 Feb 2024 17:22:21 +0000
Subject: [PATCH 1/4] dt-bindings: hwinfo: samsung,exynos-chipid: add gs101-chipid compatible
Message-ID: <20240201172224.574238-1-alexey.klimov@linaro.org>

Add "google,gs101-chipid" compatible string to binding document.

Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
---
 .../devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml        | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml
index 780ccb5ee9b4..b1d933808b6c 100644
--- a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml
+++ b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml
@@ -13,6 +13,7 @@ properties:
   compatible:
     oneOf:
       - enum:
+          - google,gs101-chipid
           - samsung,exynos4210-chipid
           - samsung,exynos850-chipid
       - items:
-- 
2.43.0



From alexey.klimov at linaro.org  Thu Feb  1 09:22:22 2024
From: alexey.klimov at linaro.org (Alexey Klimov)
Date: Thu,  1 Feb 2024 17:22:22 +0000
Subject: [PATCH 2/4] arm64: dts: exynos: gs101: add chipid node
In-Reply-To: <20240201172224.574238-1-alexey.klimov@linaro.org>
References: <20240201172224.574238-1-alexey.klimov@linaro.org>
Message-ID: <20240201172224.574238-2-alexey.klimov@linaro.org>

Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
---
 arch/arm64/boot/dts/exynos/google/gs101.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index d838e3a7af6e..156fec2575bc 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -283,6 +283,11 @@ soc: soc at 0 {
 		#size-cells = <1>;
 		ranges = <0x0 0x0 0x0 0x40000000>;
 
+		chipid at 10000000 {
+			compatible = "google,gs101-chipid";
+			reg = <0x10000000 0xd000>;
+		};
+
 		cmu_misc: clock-controller at 10010000 {
 			compatible = "google,gs101-cmu-misc";
 			reg = <0x10010000 0x8000>;
-- 
2.43.0



From alexey.klimov at linaro.org  Thu Feb  1 09:22:23 2024
From: alexey.klimov at linaro.org (Alexey Klimov)
Date: Thu,  1 Feb 2024 17:22:23 +0000
Subject: [PATCH 3/4] soc: samsung: exynos-chipid: add Google Tensor gs101 SoC support
In-Reply-To: <20240201172224.574238-1-alexey.klimov@linaro.org>
References: <20240201172224.574238-1-alexey.klimov@linaro.org>
Message-ID: <20240201172224.574238-3-alexey.klimov@linaro.org>

Add GS101 information to soc_ids table and related entries to other
places. This SoC product id is "0x09845000".

Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
---
 drivers/soc/samsung/exynos-chipid.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
index b1118d37779e..7fee6094db12 100644
--- a/drivers/soc/samsung/exynos-chipid.c
+++ b/drivers/soc/samsung/exynos-chipid.c
@@ -60,6 +60,8 @@ static const struct exynos_soc_id {
 	{ "EXYNOS850", 0xE3830000 },
 	{ "EXYNOSAUTOV9", 0xAAA80000 },
 	{ "EXYNOSAUTOV920", 0x0A920000 },
+	/* Compatible with: google,gs101-chipid */
+	{ "GS101", 0x09845000 },
 };
 
 static const char *product_id_to_soc_id(unsigned int product_id)
@@ -178,8 +180,17 @@ static const struct exynos_chipid_variant exynos850_chipid_drv_data = {
 	.sub_rev_shift	= 16,
 };
 
+static const struct exynos_chipid_variant gs101_chipid_drv_data = {
+	.rev_reg	= 0x10,
+	.main_rev_shift	= 0,
+	.sub_rev_shift	= 16,
+};
+
 static const struct of_device_id exynos_chipid_of_device_ids[] = {
 	{
+		.compatible	= "google,gs101-chipid",
+		.data		= &gs101_chipid_drv_data,
+	}, {
 		.compatible	= "samsung,exynos4210-chipid",
 		.data		= &exynos4210_chipid_drv_data,
 	}, {
-- 
2.43.0



From alexey.klimov at linaro.org  Thu Feb  1 09:22:24 2024
From: alexey.klimov at linaro.org (Alexey Klimov)
Date: Thu,  1 Feb 2024 17:22:24 +0000
Subject: [PATCH 4/4] soc: samsung: exynos-chipid: fix revision calculation for gs101
In-Reply-To: <20240201172224.574238-1-alexey.klimov@linaro.org>
References: <20240201172224.574238-1-alexey.klimov@linaro.org>
Message-ID: <20240201172224.574238-4-alexey.klimov@linaro.org>

The main revision for gs101 SoC is not reported in the CHIPID_REV
register. The gs101 Product ID and revisions registers have a behaviour
split between old Exynos SoCs and new SoCs. The sub-revision is
reported in CHIPID_REV register in [19:16] bits but main revision
is still present in Product ID [7:0].

To construct soc_info->revision correctly for gs101 the main_rev
should not be reset from a value read from CHIPID_REV.

Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
---
 drivers/soc/samsung/exynos-chipid.c       | 20 ++++++++++++++++----
 include/linux/soc/samsung/exynos-chipid.h |  1 +
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
index 7fee6094db12..3b952ffd8cf7 100644
--- a/drivers/soc/samsung/exynos-chipid.c
+++ b/drivers/soc/samsung/exynos-chipid.c
@@ -87,14 +87,26 @@ static int exynos_chipid_get_chipid_info(struct regmap *regmap,
 	soc_info->product_id = val & EXYNOS_MASK;
 
 	if (data->rev_reg != EXYNOS_CHIPID_REG_PRO_ID) {
-		ret = regmap_read(regmap, data->rev_reg, &val);
+		unsigned int val2;
+
+		ret = regmap_read(regmap, data->rev_reg, &val2);
 		if (ret < 0)
 			return ret;
+
+		if (data->main_rev_shift == 0)
+			main_rev = (val >> data->main_rev_shift)
+				   & EXYNOS_REV_PART_MASK_GS101;
+		else
+			main_rev = (val2 >> data->main_rev_shift)
+				   & EXYNOS_REV_PART_MASK;
+
+		sub_rev = (val2 >> data->sub_rev_shift) & EXYNOS_REV_PART_MASK;
+	} else {
+		main_rev = (val >> data->main_rev_shift) & EXYNOS_REV_PART_MASK;
+		sub_rev = (val >> data->sub_rev_shift) & EXYNOS_REV_PART_MASK;
 	}
-	main_rev = (val >> data->main_rev_shift) & EXYNOS_REV_PART_MASK;
-	sub_rev = (val >> data->sub_rev_shift) & EXYNOS_REV_PART_MASK;
-	soc_info->revision = (main_rev << EXYNOS_REV_PART_SHIFT) | sub_rev;
 
+	soc_info->revision = (main_rev << EXYNOS_REV_PART_SHIFT) | sub_rev;
 	return 0;
 }
 
diff --git a/include/linux/soc/samsung/exynos-chipid.h b/include/linux/soc/samsung/exynos-chipid.h
index 62f0e2531068..1eb13068f513 100644
--- a/include/linux/soc/samsung/exynos-chipid.h
+++ b/include/linux/soc/samsung/exynos-chipid.h
@@ -10,6 +10,7 @@
 
 #define EXYNOS_CHIPID_REG_PRO_ID	0x00
 #define EXYNOS_REV_PART_MASK		0xf
+#define EXYNOS_REV_PART_MASK_GS101	0xff
 #define EXYNOS_REV_PART_SHIFT		4
 #define EXYNOS_MASK			0xfffff000
 
-- 
2.43.0



From Dave.Martin at arm.com  Thu Feb  1 09:29:38 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 1 Feb 2024 17:29:38 +0000
Subject: [PATCH] arm64: jump_label: use constraint "S" instead of "i"
In-Reply-To: <CAMj1kXGu76WHY8=Y-KhCxBq3xeHeCYQ9syqViSr9VRkjgWQ3BQ@mail.gmail.com>
References: <20240131065322.1126831-1-maskray@google.com>
 <CAMj1kXGzADFWa7RmXyjWpCnQ=9hhz6i-XkN4PS1CboZ-kFL8dQ@mail.gmail.com>
 <ZbpEnDK3U/O24ng0@e133380.arm.com>
 <20240201045551.ajg4iqcajyowl2rh@google.com>
 <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>
 <20240201091120.pbgr7ng6t2c36fut@google.com>
 <ZbuFWSRBntgm2ukJ@e133380.arm.com>
 <CAMj1kXGu76WHY8=Y-KhCxBq3xeHeCYQ9syqViSr9VRkjgWQ3BQ@mail.gmail.com>
Message-ID: <ZbvVApJ2/+yca0u6@e133380.arm.com>

On Thu, Feb 01, 2024 at 05:07:59PM +0100, Ard Biesheuvel wrote:
> On Thu, 1 Feb 2024 at 12:50, Dave Martin <Dave.Martin at arm.com> wrote:
> >
> > On Thu, Feb 01, 2024 at 01:11:20AM -0800, Fangrui Song wrote:
> ...
> > >
> > > Hmm. Clang's constraint "S" implementation doesn't support a constant
> > > offset, so
> > > `static_key_false(&nf_hooks_needed[pf][hook])` in include/linux/netfilter.h:nf_hook
> > > would not compile with Clang <= 18.
> > >
> > > I have a patch https://github.com/llvm/llvm-project/pull/80255 , but
> > > even if it is accepted and cherry-picked into the 18.x release branch,
> > > if we still support older Clang, we cannot use "S" unconditionally.
> > >
> > >
> > > So we probably need the following to prepare for -fPIE support in the
> > > future:
> > >
> > > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> > > index 48ddc0f45d22..b8af2f8b0c99 100644
> > > --- a/arch/arm64/include/asm/jump_label.h
> > > +++ b/arch/arm64/include/asm/jump_label.h
> > > @@ -15,6 +15,16 @@
> > >  #define JUMP_LABEL_NOP_SIZE          AARCH64_INSN_SIZE
> > > +/*
> > > + * Prefer "S" to support PIC. However, use "i" for Clang 18 and earlier as "S"
> > > + * on a symbol with a constant offset is not supported.
> > > + */
> > > +#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 18
> >
> > Is a GCC version check needed?  Or is the minimum GCC version specified
> > for building the kernel new enough?
> >
> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
> > > +#else
> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "S"
> > > +#endif
> > > +
> 
> Can we use "Si" instead?

I thought the point was to avoid "S" on compilers that would choke on
it?  If so, those compilers would surely choke on "Si" too, no?


> > >  static __always_inline bool arch_static_branch(struct static_key * const key,
> > >                                              const bool branch)
> > >  {
> > > @@ -23,9 +33,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
> > >                "      .pushsection    __jump_table, \"aw\"    \n\t"
> > >                "      .align          3                       \n\t"
> > >                "      .long           1b - ., %l[l_yes] - .   \n\t"
> > > -              "      .quad           %c0 - .                 \n\t"
> > > +              "      .quad           %0 + %1 - .             \n\t"
> > >                "      .popsection                             \n\t"
> > > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> > > +              :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);
> >
> > While this looks reasonable, I'm still not clear now why the asm must do
> > the addition.
> >
> > Can we roll the branch argument into the macro?
> >
> > "S"(symbol + constant) seems to do the right thing for AArch64, at least
> > in GCC.
> >
> 
> 'symbol' is a struct static_key pointer, so adding '1' to it will not
> produce the needed result.

I mean loosely things that resolve to something of the form
"symbol + constant" in the compiler output.

"S"(&((char *)key)[branch]) does indeed seem to do the right thing,
at least with GCC.

I probably didn't help by bikeshedding the way that expression was
written, apologies for that.  It's orthogonal to what this patch is
doing.

> 
> ...
> > > > > >If there's another reason why "S" is advantageous though, I'm happy to
> > > > > >be corrected.
> > > > >
> > > > > I remember that Ard has an RFC
> > > > > https://lore.kernel.org/linux-arm-kernel/20220427171241.2426592-1-ardb at kernel.org/
> > > > > "[RFC PATCH 0/2] arm64: use PIE code generation for KASLR kernel"
> > > > > and see some recent PIE codegen patches.
> > > > >
> > > > > > Building the KASLR kernel without -fpie but linking it with -pie works
> > > > > > in practice, but it is not something that is explicitly supported by the
> > > > > > toolchains - it happens to work because the default 'small' code model
> > > > > > used by both GCC and Clang relies mostly on ADRP+ADD/LDR to generate
> > > > > > symbol references.
> >
> > Does this mean that doing boot-time relocation on a fully statically
> > linked kernel doesn't bring much benefit?
> 
> Not sure I follow you here. The boot-time relocation is necessary in
> any case, to fix up statically initialized pointer variables all over
> the kernel.
> 
> > It would tend to be more
> > painful to do the relocation work, and mean that the kernel text has to
> > be temporarily writeable, but static linking should have the best
> > runtime performance.
> >
> 
> Not sure what you mean by 'static linking' here.
> 
> The only thing PIE linking does in the case of the kernel is
> a) complain if static relocations are used that cannot be fixed up at
> runtime (e.g., movk/movz sequences)
> b) emit dynamic relocations that the early startup code can use to fix
> up all statically initialized pointers
> 
> From a codegen point-of-view, there is no difference because we don't
> use -fpic code. The problem with -fpic codegen is that it makes some
> assumptions that only hold for shared ELF objects, e.g., avoiding
> dynamic relocations in .text, using GOT entries even for variables
> defined in the same compilation so that they can be preempted, keeping
> all runtime relocatable quantities together so the CoW footprint of
> the shared library is minimized.
> 
> None of this matters for the kernel, and as it turns out, the non-PIC
> small C model produces code that the PIE linker is happy with.
> 
> TL;DR our code (including inline and out-of-line asm) is already PIC,
> and this property is relied upon by KASLR.
> 
> > Maybe it doesn't make as much difference as I thought (certainly ADRP
> > based addressing should make a fair amount of the PIC/PIE overhead go
> > away).
> >
> 
> The PIC/PIE overhead is in the indirections via the GOT. However,
> recent linkers will actually perform some relaxations too: if a symbol
> is defined in the same executable and is not preemptible, a GOT load
> 
> ADRP
> LDR
> 
> can be transparently converted to
> 
> ADRP
> ADD
> 
> referring to the symbol directly. This is also where hidden.h comes
> in: making all symbol declarations and definitions 'hidden' will allow
> the compiler to assume that a GOT entry is never needed.

Is there a reason why we don't just build the whole kernel with
-fvisibility=hidden today?

> So building with -fPIC is currently not need in practice, and creates
> some complications, which is why we have been avoiding it. But PIE
> linking non-PIC objects is not guaranteed to remain supported going
> forward, so it would be better to have a plan B, i.e., being able to
> turn on -fpic without massive regressions due to GOT overhead, or
> codegen problems with our asm hacks.

Summarising all of this is it right that:

1) ld -pie is how we get the reloc info into the kernel for KASLR
today.

2) We use gcc -fno-pic today, but this might break with ld -pie in the
future, although it works for now.

3) gcc -fno-pic and gcc -fPIC (or -fPIE) generate almost the same code,
assuming we tweak symbol visibility and use a memory model that
ADR+ADD/LDR can span.  So, moving to -fPIE is likely to be do-able.


My point is that an alternative option would be to move to ld -no-pie.
We would need another way to get relocs into the kernel, such as an
intermediate step with ld --emit-relocs.  I have definitely seen this
done before somewhere, but it would be extra work and not necessarily
worth it, based on what you say about code gen.

This may all have been discussed to death already -- I didn't mean to
hijack this patch, so I'll stop digging here, but if I've misunderstood,
please shout!

Cheers
---Dave


From alexandru.elisei at arm.com  Thu Feb  1 09:32:40 2024
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 1 Feb 2024 17:32:40 +0000
Subject: [PATCH RFC v3 12/35] mm: Call arch_swap_prepare_to_restore()
 before arch_swap_restore()
In-Reply-To: <08a4971e-c31d-46f7-afbc-7404bd9a293f@arm.com>
References: <20240125164256.4147-1-alexandru.elisei@arm.com>
 <20240125164256.4147-13-alexandru.elisei@arm.com>
 <08a4971e-c31d-46f7-afbc-7404bd9a293f@arm.com>
Message-ID: <ZbvVuIUe3W8OZnZ5@raptor>

Hi,

On Thu, Feb 01, 2024 at 09:00:23AM +0530, Anshuman Khandual wrote:
> 
> 
> On 1/25/24 22:12, Alexandru Elisei wrote:
> > arm64 uses arch_swap_restore() to restore saved tags before the page is
> > swapped in and it's called in atomic context (with the ptl lock held).
> > 
> > Introduce arch_swap_prepare_to_restore() that will allow an architecture to
> > perform extra work during swap in and outside of a critical section.
> > This will be used by arm64 to allocate a buffer in memory where to
> > temporarily save tags if tag storage is not available for the page being
> > swapped in.
> 
> Just wondering if tag storage will always be unavailable for tagged pages
> being swapped in ? OR there are cases where allocation might not even be

In some (probably most) situations, tag storage will be available for the
page that will be swapped in. That's because either the page will have been
taken from the swap cache (which means it hasn't been freed, so it still
has tag storage reserved) or it has been allocated with vma_alloc_folio()
(when it's swapped back in in a VMA with VM_MTE set).

I've explained a scenario where tags will be restored for a page without
tag storage in patch #28 ("mte: swap: Handle tag restoring when missing tag
storage") [1]. Basically, it's because tagged pages can be mapped as tagged
in one VMA and untagged in another VMA; and swap tags are restored the
first time a page is swapped back in, even if it's swapped in a VMA with
MTE disabled.

[1] https://lore.kernel.org/linux-arm-kernel/20240125164256.4147-29-alexandru.elisei at arm.com/

> required ? This prepare phase needs to be outside the critical section -
> only because there might be memory allocations ?

Yes, exactly. See patch above :)

Thanks,
Alex


From dsimic at manjaro.org  Thu Feb  1 09:34:18 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu, 01 Feb 2024 18:34:18 +0100
Subject: [PATCH v2 2/4] arm64: dts: rockchip: enable temperature driven
 fan control on Rock 5B
In-Reply-To: <CAGb2v65--rgb2FqmG_0-w1-jUL0odqKXxiZJ-XPYA4uomfYmaQ@mail.gmail.com>
References: <20240130-rk-dts-additions-v2-0-c6222c4c78df@gmail.com>
 <20240130-rk-dts-additions-v2-2-c6222c4c78df@gmail.com>
 <CAGb2v65--rgb2FqmG_0-w1-jUL0odqKXxiZJ-XPYA4uomfYmaQ@mail.gmail.com>
Message-ID: <5e3e12d65e4919372e7fb02d56202393@manjaro.org>

Hello Chen-Yu,

On 2024-02-01 15:26, Chen-Yu Tsai wrote:
> On Wed, Jan 31, 2024 at 2:22?AM Alexey Charkov <alchark at gmail.com> 
> wrote:
>> 
>> This enables thermal monitoring on Radxa Rock 5B and links the PWM
>> fan as an active cooling device managed automatically by the thermal
>> subsystem, with a target SoC temperature of 65C and a minimum-spin
>> interval from 55C to 65C to ensure airflow when the system gets warm
>> 
>> Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>
>> Signed-off-by: Alexey Charkov <alchark at gmail.com>
>> ---
>>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 34 
>> ++++++++++++++++++++++++-
>>  1 file changed, 33 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts 
>> b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> index a0e303c3a1dc..b485edeef876 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> @@ -52,7 +52,7 @@ led_rgb_b {
>> 
>>         fan: pwm-fan {
>>                 compatible = "pwm-fan";
>> -               cooling-levels = <0 95 145 195 255>;
>> +               cooling-levels = <0 120 150 180 210 240 255>;
>>                 fan-supply = <&vcc5v0_sys>;
>>                 pwms = <&pwm1 0 50000 0>;
>>                 #cooling-cells = <2>;
>> @@ -173,6 +173,34 @@ &cpu_l3 {
>>         cpu-supply = <&vdd_cpu_lit_s0>;
>>  };
>> 
>> +&package_thermal {
>> +       polling-delay = <1000>;
>> +
>> +       trips {
>> +               package_fan0: package-fan0 {
>> +                       temperature = <55000>;
>> +                       hysteresis = <2000>;
>> +                       type = "active";
>> +               };
>> +               package_fan1: package-fan1 {
>> +                       temperature = <65000>;
>> +                       hysteresis = <2000>;
>> +                       type = "active";
>> +               };
>> +       };
>> +
>> +       cooling-maps {
>> +               map0 {
>> +                       trip = <&package_fan0>;
>> +                       cooling-device = <&fan THERMAL_NO_LIMIT 1>;
>> +               };
>> +               map1 {
>> +                       trip = <&package_fan1>;
>> +                       cooling-device = <&fan 1 THERMAL_NO_LIMIT>;
>> +               };
>> +       };
>> +};
>> +
>>  &i2c0 {
>>         pinctrl-names = "default";
>>         pinctrl-0 = <&i2c0m2_xfer>;
>> @@ -731,6 +759,10 @@ regulator-state-mem {
>>         };
>>  };
>> 
>> +&tsadc {
>> +       status = "okay";
>> +};
>> +
> 
> Is there any reason this can't be enabled by default in the .dtsi file?
> The thermal sensor doesn't depend on anything external, so there should
> be no reason to push this down to the board level.

Actually, there is a reason.  Different boards can handle the critical
overheating differently, by letting the CRU or the PMIC handle it.  This
was also the case for the RK3399.

Please, have a look at the following DT properties, which are consumed
by drivers/thermal/rockchip_thermal.c:
   - "rockchip,hw-tshut-mode"
   - "rockchip,hw-tshut-polarity"

See also page 1,372 of the RK3588 TRM v1.0.

This has also reminded me to check how is the Rock 5B actually wired,
just to make sure.  We actually need to provide the two DT properties
listed above, at least to avoid emitting the warnings.

>>  &uart2 {
>>         pinctrl-0 = <&uart2m0_xfer>;
>>         status = "okay";
>> 
>> --
>> 2.43.0


From alexandru.elisei at arm.com  Thu Feb  1 09:36:02 2024
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 1 Feb 2024 17:36:02 +0000
Subject: [PATCH RFC v3 13/35] mm: memory: Introduce fault-on-access
 mechanism for pages
In-Reply-To: <9a881a18-bc50-44d6-a4b5-48f8e2f73045@arm.com>
References: <20240125164256.4147-1-alexandru.elisei@arm.com>
 <20240125164256.4147-14-alexandru.elisei@arm.com>
 <9a881a18-bc50-44d6-a4b5-48f8e2f73045@arm.com>
Message-ID: <ZbvWgnMAzbGWWQvn@raptor>

Hi,

On Thu, Feb 01, 2024 at 11:22:13AM +0530, Anshuman Khandual wrote:
> On 1/25/24 22:12, Alexandru Elisei wrote:
> > Introduce a mechanism that allows an architecture to trigger a page fault,
> > and add the infrastructure to handle that fault accordingly. To use make> use of this, an arch is expected to mark the table entry as PAGE_NONE (which
> > will cause a fault next time it is accessed) and to implement an
> > arch-specific method (like a software bit) for recognizing that the fault
> > needs to be handled by the arch code.
> > 
> > arm64 will use of this approach to reserve tag storage for pages which are
> > mapped in an MTE enabled VMA, but the storage needed to store tags isn't
> > reserved (for example, because of an mprotect(PROT_MTE) call on a VMA with
> > existing pages).
> 
> Just to summerize -
> 
> So platform will create NUMA balancing like page faults - via marking existing
> mappings with PAGE_NONE permission, when the subsequent fault happens identify
> such cases via a software bit in the page table entry and then route the fault
> to the platform code itself for special purpose page fault handling where page
> might come from some reserved areas instead.

Indeed. In the tag storage scenario, the page is page that will be mapped
as tagged, if it's missing tag storage, the tag storage needs to be
reserved before it can be mapped as tagged (and tags can be accessed).

> 
> Some questions
> 
> - How often PAGE_NONE is to be marked for applicable MTE VMA based mappings 
> 
> 	- Is it periodic like NUMA balancing or just one time for tag storage

It's deterministic, and only for tag storage. It's done in
set_ptes()/__set_pte_at()->..->mte_sync_tags(), if the page is going to be
mapped as tagged, but is missing tag storage. See patch #26 ("arm64: mte:
Use fault-on-access to reserve missing tag storage") [1] for the code.

[1] https://lore.kernel.org/linux-arm-kernel/20240125164256.4147-27-alexandru.elisei at arm.com/

> 
> - How this is going to interact with NUMA balancing given both use PAGE_NONE
> 
> 	- How to differentiate these mappings from standard pte_protnone()

The only place where the difference matters is in do_numa_page(), here
renamed to handle_pte_protnone(), and in the huge page equivalent.

Userspace can access tags only if set_ptes()/__set_pte_at() maps the pte
with the PT_NORMAL_TAGGED attribute, but those functions will always map
the page as arch_fault_on_access_pte() if it's missing tag storage. That
makes it impossible for the kernel to map it as tagged behind our back.

Unless you had other concerns.

Thanks,
Alex

> 
> > 
> > Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> > ---
> > 
> > Changes since rfc v2:
> > 
> > * New patch. Split from patch #19 ("mm: mprotect: Introduce PAGE_FAULT_ON_ACCESS
> > for mprotect(PROT_MTE)") (David Hildenbrand).
> > 
> >  include/linux/huge_mm.h |  4 ++--
> >  include/linux/pgtable.h | 47 +++++++++++++++++++++++++++++++++++--
> >  mm/Kconfig              |  3 +++
> >  mm/huge_memory.c        | 36 +++++++++++++++++++++--------
> >  mm/memory.c             | 51 ++++++++++++++++++++++++++---------------
> >  5 files changed, 109 insertions(+), 32 deletions(-)
> > 
> > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
> > index 5adb86af35fc..4678a0a5e6a8 100644
> > --- a/include/linux/huge_mm.h
> > +++ b/include/linux/huge_mm.h
> > @@ -346,7 +346,7 @@ struct page *follow_devmap_pmd(struct vm_area_struct *vma, unsigned long addr,
> >  struct page *follow_devmap_pud(struct vm_area_struct *vma, unsigned long addr,
> >  		pud_t *pud, int flags, struct dev_pagemap **pgmap);
> >  
> > -vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf);
> > +vm_fault_t handle_huge_pmd_protnone(struct vm_fault *vmf);
> >  
> >  extern struct page *huge_zero_page;
> >  extern unsigned long huge_zero_pfn;
> > @@ -476,7 +476,7 @@ static inline spinlock_t *pud_trans_huge_lock(pud_t *pud,
> >  	return NULL;
> >  }
> >  
> > -static inline vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf)
> > +static inline vm_fault_t handle_huge_pmd_protnone(struct vm_fault *vmf)
> >  {
> >  	return 0;
> >  }
> > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> > index 2d0f04042f62..81a21be855a2 100644
> > --- a/include/linux/pgtable.h
> > +++ b/include/linux/pgtable.h
> > @@ -1455,7 +1455,7 @@ static inline int pud_trans_unstable(pud_t *pud)
> >  	return 0;
> >  }
> >  
> > -#ifndef CONFIG_NUMA_BALANCING
> > +#if !defined(CONFIG_NUMA_BALANCING) && !defined(CONFIG_ARCH_HAS_FAULT_ON_ACCESS)
> >  /*
> >   * In an inaccessible (PROT_NONE) VMA, pte_protnone() may indicate "yes". It is
> >   * perfectly valid to indicate "no" in that case, which is why our default
> > @@ -1477,7 +1477,50 @@ static inline int pmd_protnone(pmd_t pmd)
> >  {
> >  	return 0;
> >  }
> > -#endif /* CONFIG_NUMA_BALANCING */
> > +#endif /* !CONFIG_NUMA_BALANCING && !CONFIG_ARCH_HAS_FAULT_ON_ACCESS */
> > +
> > +#ifndef CONFIG_ARCH_HAS_FAULT_ON_ACCESS
> > +static inline bool arch_fault_on_access_pte(pte_t pte)
> > +{
> > +	return false;
> > +}
> > +
> > +static inline bool arch_fault_on_access_pmd(pmd_t pmd)
> > +{
> > +	return false;
> > +}
> > +
> > +/*
> > + * The function is called with the fault lock held and an elevated reference on
> > + * the folio.
> > + *
> > + * Rules that an arch implementation of the function must follow:
> > + *
> > + * 1. The function must return with the elevated reference dropped.
> > + *
> > + * 2. If the return value contains VM_FAULT_RETRY or VM_FAULT_COMPLETED then:
> > + *
> > + * - if FAULT_FLAG_RETRY_NOWAIT is not set, the function must return with the
> > + *   correct fault lock released, which can be accomplished with
> > + *   release_fault_lock(vmf). Note that release_fault_lock() doesn't check if
> > + *   FAULT_FLAG_RETRY_NOWAIT is set before releasing the mmap_lock.
> > + *
> > + * - if FAULT_FLAG_RETRY_NOWAIT is set, then the function must not release the
> > + *   mmap_lock. The flag should be set only if the mmap_lock is held.
> > + *
> > + * 3. If the return value contains neither of the above, the function must not
> > + * release the fault lock; the generic fault handler will take care of releasing
> > + * the correct lock.
> > + */
> > +static inline vm_fault_t arch_handle_folio_fault_on_access(struct folio *folio,
> > +							   struct vm_fault *vmf,
> > +							   bool *map_pte)
> > +{
> > +	*map_pte = false;
> > +
> > +	return VM_FAULT_SIGBUS;
> > +}
> > +#endif
> >  
> >  #endif /* CONFIG_MMU */
> >  
> > diff --git a/mm/Kconfig b/mm/Kconfig
> > index 341cf53898db..153df67221f1 100644
> > --- a/mm/Kconfig
> > +++ b/mm/Kconfig
> > @@ -1006,6 +1006,9 @@ config IDLE_PAGE_TRACKING
> >  config ARCH_HAS_CACHE_LINE_SIZE
> >  	bool
> >  
> > +config ARCH_HAS_FAULT_ON_ACCESS
> > +	bool
> > +
> >  config ARCH_HAS_CURRENT_STACK_POINTER
> >  	bool
> >  	help
> > diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> > index 94ef5c02b459..2bad63a7ec16 100644
> > --- a/mm/huge_memory.c
> > +++ b/mm/huge_memory.c
> > @@ -1698,7 +1698,7 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
> >  }
> >  
> >  /* NUMA hinting page fault entry point for trans huge pmds */
> > -vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf)
> > +vm_fault_t handle_huge_pmd_protnone(struct vm_fault *vmf)
> >  {
> >  	struct vm_area_struct *vma = vmf->vma;
> >  	pmd_t oldpmd = vmf->orig_pmd;
> > @@ -1708,6 +1708,7 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf)
> >  	int nid = NUMA_NO_NODE;
> >  	int target_nid, last_cpupid = (-1 & LAST_CPUPID_MASK);
> >  	bool migrated = false, writable = false;
> > +	vm_fault_t ret;
> >  	int flags = 0;
> >  
> >  	vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);
> > @@ -1731,6 +1732,20 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf)
> >  	if (!folio)
> >  		goto out_map;
> >  
> > +	folio_get(folio);
> > +	vma_set_access_pid_bit(vma);
> > +
> > +	if (arch_fault_on_access_pmd(oldpmd)) {
> > +		bool map_pte = false;
> > +
> > +		spin_unlock(vmf->ptl);
> > +		ret = arch_handle_folio_fault_on_access(folio, vmf, &map_pte);
> > +		if (ret || !map_pte)
> > +			return ret;
> > +		writable = false;
> > +		goto out_lock_and_map;
> > +	}
> > +
> >  	/* See similar comment in do_numa_page for explanation */
> >  	if (!writable)
> >  		flags |= TNF_NO_GROUP;
> > @@ -1755,15 +1770,18 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf)
> >  	if (migrated) {
> >  		flags |= TNF_MIGRATED;
> >  		nid = target_nid;
> > -	} else {
> > -		flags |= TNF_MIGRATE_FAIL;
> > -		vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);
> > -		if (unlikely(!pmd_same(oldpmd, *vmf->pmd))) {
> > -			spin_unlock(vmf->ptl);
> > -			goto out;
> > -		}
> > -		goto out_map;
> > +		goto out;
> > +	}
> > +
> > +	flags |= TNF_MIGRATE_FAIL;
> > +
> > +out_lock_and_map:
> > +	vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);
> > +	if (unlikely(!pmd_same(oldpmd, *vmf->pmd))) {
> > +		spin_unlock(vmf->ptl);
> > +		goto out;
> >  	}
> > +	goto out_map;
> >  
> >  out:
> >  	if (nid != NUMA_NO_NODE)
> > diff --git a/mm/memory.c b/mm/memory.c
> > index 8a421e168b57..110fe2224277 100644
> > --- a/mm/memory.c
> > +++ b/mm/memory.c
> > @@ -4886,11 +4886,6 @@ static vm_fault_t do_fault(struct vm_fault *vmf)
> >  int numa_migrate_prep(struct folio *folio, struct vm_area_struct *vma,
> >  		      unsigned long addr, int page_nid, int *flags)
> >  {
> > -	folio_get(folio);
> > -
> > -	/* Record the current PID acceesing VMA */
> > -	vma_set_access_pid_bit(vma);
> > -
> >  	count_vm_numa_event(NUMA_HINT_FAULTS);
> >  	if (page_nid == numa_node_id()) {
> >  		count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL);
> > @@ -4900,13 +4895,14 @@ int numa_migrate_prep(struct folio *folio, struct vm_area_struct *vma,
> >  	return mpol_misplaced(folio, vma, addr);
> >  }
> >  
> > -static vm_fault_t do_numa_page(struct vm_fault *vmf)
> > +static vm_fault_t handle_pte_protnone(struct vm_fault *vmf)
> >  {
> >  	struct vm_area_struct *vma = vmf->vma;
> >  	struct folio *folio = NULL;
> >  	int nid = NUMA_NO_NODE;
> >  	bool writable = false;
> >  	int last_cpupid;
> > +	vm_fault_t ret;
> >  	int target_nid;
> >  	pte_t pte, old_pte;
> >  	int flags = 0;
> > @@ -4939,6 +4935,20 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
> >  	if (!folio || folio_is_zone_device(folio))
> >  		goto out_map;
> >  
> > +	folio_get(folio);
> > +	/* Record the current PID acceesing VMA */
> > +	vma_set_access_pid_bit(vma);
> > +
> > +	if (arch_fault_on_access_pte(old_pte)) {
> > +		bool map_pte = false;
> > +
> > +		pte_unmap_unlock(vmf->pte, vmf->ptl);
> > +		ret = arch_handle_folio_fault_on_access(folio, vmf, &map_pte);
> > +		if (ret || !map_pte)
> > +			return ret;
> > +		goto out_lock_and_map;
> > +	}
> > +
> >  	/* TODO: handle PTE-mapped THP */
> >  	if (folio_test_large(folio))
> >  		goto out_map;
> > @@ -4983,18 +4993,21 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
> >  	if (migrate_misplaced_folio(folio, vma, target_nid)) {
> >  		nid = target_nid;
> >  		flags |= TNF_MIGRATED;
> > -	} else {
> > -		flags |= TNF_MIGRATE_FAIL;
> > -		vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
> > -					       vmf->address, &vmf->ptl);
> > -		if (unlikely(!vmf->pte))
> > -			goto out;
> > -		if (unlikely(!pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
> > -			pte_unmap_unlock(vmf->pte, vmf->ptl);
> > -			goto out;
> > -		}
> > -		goto out_map;
> > +		goto out;
> > +	}
> > +
> > +	flags |= TNF_MIGRATE_FAIL;
> > +
> > +out_lock_and_map:
> > +	vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
> > +				       vmf->address, &vmf->ptl);
> > +	if (unlikely(!vmf->pte))
> > +		goto out;
> > +	if (unlikely(!pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
> > +		pte_unmap_unlock(vmf->pte, vmf->ptl);
> > +		goto out;
> >  	}
> > +	goto out_map;
> >  
> >  out:
> >  	if (nid != NUMA_NO_NODE)
> > @@ -5151,7 +5164,7 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
> >  		return do_swap_page(vmf);
> >  
> >  	if (pte_protnone(vmf->orig_pte) && vma_is_accessible(vmf->vma))
> > -		return do_numa_page(vmf);
> > +		return handle_pte_protnone(vmf);
> >  
> >  	spin_lock(vmf->ptl);
> >  	entry = vmf->orig_pte;
> > @@ -5272,7 +5285,7 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
> >  		}
> >  		if (pmd_trans_huge(vmf.orig_pmd) || pmd_devmap(vmf.orig_pmd)) {
> >  			if (pmd_protnone(vmf.orig_pmd) && vma_is_accessible(vma))
> > -				return do_huge_pmd_numa_page(&vmf);
> > +				return handle_huge_pmd_protnone(&vmf);
> >  
> >  			if ((flags & (FAULT_FLAG_WRITE|FAULT_FLAG_UNSHARE)) &&
> >  			    !pmd_write(vmf.orig_pmd)) {


From alexandru.elisei at arm.com  Thu Feb  1 09:38:04 2024
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 1 Feb 2024 17:38:04 +0000
Subject: [PATCH RFC v3 30/35] arm64: mte: ptrace: Handle pages with
 missing tag storage
In-Reply-To: <30278898-c4b2-4dd6-ba68-a19575f81a65@arm.com>
References: <20240125164256.4147-1-alexandru.elisei@arm.com>
 <20240125164256.4147-31-alexandru.elisei@arm.com>
 <30278898-c4b2-4dd6-ba68-a19575f81a65@arm.com>
Message-ID: <ZbvW_HlrSMOpETlF@raptor>

Hi,

On Thu, Feb 01, 2024 at 02:51:39PM +0530, Anshuman Khandual wrote:
> 
> 
> On 1/25/24 22:12, Alexandru Elisei wrote:
> > A page can end up mapped in a MTE enabled VMA without the corresponding tag
> > storage block reserved. Tag accesses made by ptrace in this case can lead
> > to the wrong tags being read or memory corruption for the process that is
> > using the tag storage memory as data.
> > 
> > Reserve tag storage by treating ptrace accesses like a fault.
> > 
> > Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> > ---
> > 
> > Changes since rfc v2:
> > 
> > * New patch, issue reported by Peter Collingbourne.
> > 
> >  arch/arm64/kernel/mte.c | 26 ++++++++++++++++++++++++--
> >  1 file changed, 24 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
> > index faf09da3400a..b1fa02dad4fd 100644
> > --- a/arch/arm64/kernel/mte.c
> > +++ b/arch/arm64/kernel/mte.c
> > @@ -412,10 +412,13 @@ static int __access_remote_tags(struct mm_struct *mm, unsigned long addr,
> >  	while (len) {
> >  		struct vm_area_struct *vma;
> >  		unsigned long tags, offset;
> > +		unsigned int fault_flags;
> > +		struct page *page;
> > +		vm_fault_t ret;
> >  		void *maddr;
> > -		struct page *page = get_user_page_vma_remote(mm, addr,
> > -							     gup_flags, &vma);
> >  
> > +get_page:
> > +		page = get_user_page_vma_remote(mm, addr, gup_flags, &vma);
> 
> But if there is valid page returned here in the first GUP attempt, will there
> still be a subsequent handle_mm_fault() on the same vma and addr ?

Only if it's missing tag storage. If it's missing tag storage, the page has
been mapped as arch_fault_on_access_pte(), and
handle_mm_fault()->..->arch_handle_folio_fault_on_access() will either
reserve tag storage, or migrate it.

> 
> >  		if (IS_ERR(page)) {
> >  			err = PTR_ERR(page);
> >  			break;
> > @@ -433,6 +436,25 @@ static int __access_remote_tags(struct mm_struct *mm, unsigned long addr,
> >  			put_page(page);
> >  			break;
> >  		}
> > +
> > +		if (tag_storage_enabled() && !page_tag_storage_reserved(page)) {
> 
> Should not '!page' be checked here as well ?

I was under the impression that get_user_page_vma_remote() returns an error
pointer if gup couldn't pin the page.

Thanks,
Alex

> 
> > +			fault_flags = FAULT_FLAG_DEFAULT | \
> > +				      FAULT_FLAG_USER | \
> > +				      FAULT_FLAG_REMOTE | \
> > +				      FAULT_FLAG_ALLOW_RETRY | \
> > +				      FAULT_FLAG_RETRY_NOWAIT;
> > +			if (write)
> > +				fault_flags |= FAULT_FLAG_WRITE;
> > +
> > +			put_page(page);
> > +			ret = handle_mm_fault(vma, addr, fault_flags, NULL);
> > +			if (ret & VM_FAULT_ERROR) {
> > +				err = -EFAULT;
> > +				break;
> > +			}
> > +			goto get_page;
> > +		}
> > +
> >  		WARN_ON_ONCE(!page_mte_tagged(page));
> >  
> >  		/* limit access to the end of the page */


From alexandru.elisei at arm.com  Thu Feb  1 09:38:42 2024
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 1 Feb 2024 17:38:42 +0000
Subject: [PATCH RFC v3 31/35] khugepaged: arm64: Don't collapse MTE
 enabled VMAs
In-Reply-To: <599769c3-0aef-4c5b-ac98-f109649862f7@arm.com>
References: <20240125164256.4147-1-alexandru.elisei@arm.com>
 <20240125164256.4147-32-alexandru.elisei@arm.com>
 <599769c3-0aef-4c5b-ac98-f109649862f7@arm.com>
Message-ID: <ZbvXImzAJNKQvamJ@raptor>

On Thu, Feb 01, 2024 at 01:42:08PM +0530, Anshuman Khandual wrote:
> 
> 
> On 1/25/24 22:12, Alexandru Elisei wrote:
> > copy_user_highpage() will do memory allocation if there are saved tags for
> > the destination page, and the page is missing tag storage.
> > 
> > After commit a349d72fd9ef ("mm/pgtable: add rcu_read_lock() and
> > rcu_read_unlock()s"), collapse_huge_page() calls
> > __collapse_huge_page_copy() -> .. -> copy_user_highpage() with the RCU lock
> > held, which means that copy_user_highpage() can only allocate memory using
> > GFP_ATOMIC or equivalent.
> > 
> > Get around this by refusing to collapse pages into a transparent huge page
> > if the VMA is MTE-enabled.
> 
> Makes sense when copy_user_highpage() will allocate memory for tag storage.
> 
> > 
> > Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> > ---
> > 
> > Changes since rfc v2:
> > 
> > * New patch. I think an agreement on whether copy*_user_highpage() should be
> > always allowed to sleep, or should not be allowed, would be useful.
> 
> This is a good question ! Even after preventing the collapse of MTE VMA here,
> there still might be more paths where a sleeping (i.e memory allocating)
> copy*_user_highpage() becomes problematic ?

Exactly!

> 
> > 
> >  arch/arm64/include/asm/pgtable.h    | 3 +++
> >  arch/arm64/kernel/mte_tag_storage.c | 5 +++++
> >  include/linux/khugepaged.h          | 5 +++++
> >  mm/khugepaged.c                     | 4 ++++
> >  4 files changed, 17 insertions(+)
> > 
> > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> > index 87ae59436162..d0473538c926 100644
> > --- a/arch/arm64/include/asm/pgtable.h
> > +++ b/arch/arm64/include/asm/pgtable.h
> > @@ -1120,6 +1120,9 @@ static inline bool arch_alloc_cma(gfp_t gfp_mask)
> >  	return true;
> >  }
> >  
> > +bool arch_hugepage_vma_revalidate(struct vm_area_struct *vma, unsigned long address);
> > +#define arch_hugepage_vma_revalidate arch_hugepage_vma_revalidate
> > +
> >  #endif /* CONFIG_ARM64_MTE_TAG_STORAGE */
> >  #endif /* CONFIG_ARM64_MTE */
> >  
> > diff --git a/arch/arm64/kernel/mte_tag_storage.c b/arch/arm64/kernel/mte_tag_storage.c
> > index ac7b9c9c585c..a99959b70573 100644
> > --- a/arch/arm64/kernel/mte_tag_storage.c
> > +++ b/arch/arm64/kernel/mte_tag_storage.c
> > @@ -636,3 +636,8 @@ void arch_alloc_page(struct page *page, int order, gfp_t gfp)
> >  	if (tag_storage_enabled() && alloc_requires_tag_storage(gfp))
> >  		reserve_tag_storage(page, order, gfp);
> >  }
> > +
> > +bool arch_hugepage_vma_revalidate(struct vm_area_struct *vma, unsigned long address)
> > +{
> > +	return !(vma->vm_flags & VM_MTE);
> > +}
> > diff --git a/include/linux/khugepaged.h b/include/linux/khugepaged.h
> > index f68865e19b0b..461e4322dff2 100644
> > --- a/include/linux/khugepaged.h
> > +++ b/include/linux/khugepaged.h
> > @@ -38,6 +38,11 @@ static inline void khugepaged_exit(struct mm_struct *mm)
> >  	if (test_bit(MMF_VM_HUGEPAGE, &mm->flags))
> >  		__khugepaged_exit(mm);
> >  }
> > +
> > +#ifndef arch_hugepage_vma_revalidate
> > +#define arch_hugepage_vma_revalidate(vma, address) 1
> 
> Please replace s/1/true as arch_hugepage_vma_revalidate() returns bool ?

Yeah, that's strange, I don't know why I used 1 there. Will change it to true,
thanks for spotting it.

> 
> > +#endif
> 
> Right, above construct is much better than __HAVE_ARCH_XXXX based one.

Thanks!

Alex

> 
> > +
> >  #else /* CONFIG_TRANSPARENT_HUGEPAGE */
> >  static inline void khugepaged_fork(struct mm_struct *mm, struct mm_struct *oldmm)
> >  {
> > diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> > index 2b219acb528e..cb9a9ddb4d86 100644
> > --- a/mm/khugepaged.c
> > +++ b/mm/khugepaged.c
> > @@ -935,6 +935,10 @@ static int hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address,
> >  	 */
> >  	if (expect_anon && (!(*vmap)->anon_vma || !vma_is_anonymous(*vmap)))
> >  		return SCAN_PAGE_ANON;
> > +
> > +	if (!arch_hugepage_vma_revalidate(vma, address))
> > +		return SCAN_VMA_CHECK;
> > +
> >  	return SCAN_SUCCEED;
> >  }
> >  
> 
> Otherwise this LGTM.


From oliver.upton at linux.dev  Thu Feb  1 09:47:52 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 1 Feb 2024 17:47:52 +0000
Subject: [PATCH 00/10] KVM: arm64: fix many kernel-doc warnings
In-Reply-To: <86le8470yn.wl-maz@kernel.org>
References: <20240117230714.31025-1-rdunlap@infradead.org>
 <618cb278-0b9f-4cc2-bfc6-bfcbefc79b69@infradead.org>
 <86le8470yn.wl-maz@kernel.org>
Message-ID: <ZbvZSOKoOma0lFy1@linux.dev>

On Thu, Feb 01, 2024 at 01:45:04PM +0000, Marc Zyngier wrote:
> On Thu, 01 Feb 2024 06:19:14 +0000,
> Randy Dunlap <rdunlap at infradead.org> wrote:
> > 
> > Hi,
> >
> > Any comments on this series?
> 
> This is currently earmarked for 6.9.

Yup, I'm going to start applying some stuff soon and I'll grab this.

-- 
Thanks,
Oliver


From andre.przywara at arm.com  Thu Feb  1 09:48:51 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Thu, 1 Feb 2024 17:48:51 +0000
Subject: [PATCH v8 1/3] dt-bindings: pwm: Add binding for Allwinner
 D1/T113-S3/R329 PWM controller
In-Reply-To: <20240131-renewably-glimpse-a80339e8ff81@spud>
References: <20240131125920.2879433-1-privatesub2@gmail.com>
 <20240131125920.2879433-2-privatesub2@gmail.com>
 <20240131145244.4f534bac@donnerap.manchester.arm.com>
 <20240131-renewably-glimpse-a80339e8ff81@spud>
Message-ID: <20240201174851.62e74089@donnerap.manchester.arm.com>

On Wed, 31 Jan 2024 21:22:06 +0000
Conor Dooley <conor at kernel.org> wrote:

Hi,

> On Wed, Jan 31, 2024 at 02:52:44PM +0000, Andre Przywara wrote:
> > On Wed, 31 Jan 2024 15:59:14 +0300
> > Aleksandr Shubin <privatesub2 at gmail.com> wrote:
> > 
> > Hi,
> >   
> > > Allwinner's D1, T113-S3 and R329 SoCs have a new pwm
> > > controller witch is different from the previous pwm-sun4i.
> > > 
> > > The D1 and T113 are identical in terms of peripherals,
> > > they differ only in the architecture of the CPU core, and
> > > even share the majority of their DT. Because of that,
> > > using the same compatible makes sense.
> > > The R329 is a different SoC though, and should have
> > > a different compatible string added, especially as there
> > > is a difference in the number of channels.
> > > 
> > > D1 and T113s SoCs have one PWM controller with 8 channels.
> > > R329 SoC has two PWM controllers in both power domains, one of
> > > them has 9 channels (CPUX one) and the other has 6 (CPUS one).
> > > 
> > > Add a device tree binding for them.
> > > 
> > > Signed-off-by: Aleksandr Shubin <privatesub2 at gmail.com>
> > > Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> > > ---
> > >  .../bindings/pwm/allwinner,sun20i-pwm.yaml    | 88 +++++++++++++++++++
> > >  1 file changed, 88 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/pwm/allwinner,sun20i-pwm.yaml
> > > 
> > > diff --git a/Documentation/devicetree/bindings/pwm/allwinner,sun20i-pwm.yaml b/Documentation/devicetree/bindings/pwm/allwinner,sun20i-pwm.yaml
> > > new file mode 100644
> > > index 000000000000..716f75776006
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/pwm/allwinner,sun20i-pwm.yaml
> > > @@ -0,0 +1,88 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/pwm/allwinner,sun20i-pwm.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Allwinner D1, T113-S3 and R329 PWM
> > > +
> > > +maintainers:
> > > +  - Aleksandr Shubin <privatesub2 at gmail.com>
> > > +  - Brandon Cheo Fusi <fusibrandon13 at gmail.com>
> > > +
> > > +properties:
> > > +  compatible:
> > > +    oneOf:
> > > +      - const: allwinner,sun20i-d1-pwm
> > > +      - items:
> > > +          - const: allwinner,sun20i-r329-pwm
> > > +          - const: allwinner,sun20i-d1-pwm
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  "#pwm-cells":
> > > +    const: 3
> > > +
> > > +  clocks:
> > > +    items:
> > > +      - description: Bus clock
> > > +      - description: 24 MHz oscillator
> > > +      - description: APB0 clock
> > > +
> > > +  clock-names:
> > > +    items:
> > > +      - const: bus
> > > +      - const: hosc
> > > +      - const: apb0
> > > +
> > > +  resets:
> > > +    maxItems: 1
> > > +
> > > +  allwinner,pwm-channels:
> > > +    $ref: /schemas/types.yaml#/definitions/uint32
> > > +    description: The number of PWM channels configured for this instance
> > > +    enum: [6, 9]
> > > +
> > > +allOf:
> > > +  - $ref: pwm.yaml#
> > > +
> > > +  - if:
> > > +      properties:
> > > +        compatible:
> > > +          contains:
> > > +            const: allwinner,sun20i-r329-pwm
> > > +
> > > +    then:
> > > +      required:
> > > +        - allwinner,pwm-channels
> > > +
> > > +    else:
> > > +      properties:
> > > +        allwinner,pwm-channels: false  
> > 
> > Do we really need to be that strict?
> > If something compatible to D1 pops up in the future, just with a different
> > number of channels, we would need a new compatible string.  
> 
> Well, you would want to have a soc specific compatible anyway then,
> right?

So the idea would be to add any new (specific) compatible string to that
list then, when we add them?
I guess this would work, but strictly speaking any current driver would
then only need to check this property for the R329 type? The Linux
driver proposed in the next patch *always* honours the
allwinner,pwm-channels property, which is IMHO the right way to implement
this. And that's why I think the binding should reflect that, and not
explicitly *forbid* the property for every one other than R329 (atm).

With the current Linux driver, a potential new SoC using:
	"allwinner,sun20i-d2-pwm", "allwinner,sun20i-d1-pwm";
	allwinner,pwm-channels = <6>;
would work without driver changes. A driver strictly written to this
binding here might not, though, as it would be free to ignore the
pwm-channels property.

Does that make sense? So to encourage future compatibility, can we drop
the "else" branch?

> > If we would leave this else branch out, we could just specify some
> > number differing from the default, and be good.  
> 
> If it were compatible with the d1, then the "then:" branch would apply,
> provided you used the fallback correctly.
>
> Although if the number of
> channels were different, we'd likely end up with modifications here to
> limit it to the correct values for each soc.

That's fine, because this just affects the bindings (and the DT), but
doesn't require any driver changes, which take months to trickle into
distributions, not to speak of LTS distros. A DT can be updated
independently.

Cheers,
Andre.

> > The number of channels really looks like a parameter to the IP, it's
> > modelled like this in the manual (PCR: 0x0100 + 0x0000 + N * 0x0020).  



From helgaas at kernel.org  Thu Feb  1 09:53:55 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 1 Feb 2024 11:53:55 -0600
Subject: [PATCH v12 2/3] PCI: dwc: Implement general suspend/resume
 functionality for L2/L3 transitions
In-Reply-To: <ZbvQB/X0kwFs7nAb@lizhi-Precision-Tower-5810>
Message-ID: <20240201175355.GA639928@bhelgaas>

On Thu, Feb 01, 2024 at 12:08:23PM -0500, Frank Li wrote:
> On Thu, Feb 01, 2024 at 10:50:25AM -0600, Bjorn Helgaas wrote:
> > On Mon, Aug 21, 2023 at 02:48:14PM -0400, Frank Li wrote:
> > > Introduce helper function dw_pcie_get_ltssm() to retrieve SMLH_LTSS_STATE.
> > > ...
> > 
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > > index 615660640801..91d13f9b21b1 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > 
> > > @@ -364,6 +375,7 @@ struct dw_pcie_ops {
> > >  	void    (*write_dbi2)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
> > >  			      size_t size, u32 val);
> > >  	int	(*link_up)(struct dw_pcie *pcie);
> > > +	enum dw_pcie_ltssm (*get_ltssm)(struct dw_pcie *pcie);
> > 
> > This has already been applied as
> > https://git.kernel.org/linus/4774faf854f5 ("PCI: dwc: Implement
> > generic suspend/resume functionality"), but this .get_ltssm() pointer
> > doesn't seem to be used anywhere.  Should we remove it until we need
> > it?
> 
> Could you place hold on for a while? I am working on imx PCIe. One old
> imx6 may need it!
> 
> If not, I will submit patch to clean it. My new patches depend on
> 
> https://lore.kernel.org/imx/ZbJ+tFPn3aOYHCwf at lizhi-Precision-Tower-5810/T/#t
> 
> All already reviewed, could you please pick up these, so I can continue
> my futher work.
> 
> Another
> https://lore.kernel.org/imx/20240201-pme_msg-v2-0-6767052fe6a4 at nxp.com/T/#t
> was under review.

OK.  I don't see .get_ltssm() used in that series either.  But if you
will need it soon, no point in removing it right now.

Bjorn


From wahrenst at gmx.net  Thu Feb  1 09:56:52 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Thu, 1 Feb 2024 18:56:52 +0100
Subject: [PATCH 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <20240201131540.3dlqoxlrrbzshz7w@runtux.com>
References: <20240201131540.3dlqoxlrrbzshz7w@runtux.com>
Message-ID: <4498d3df-762b-4ecf-a196-605c096913e0@gmx.net>

Am 01.02.24 um 14:15 schrieb Ralf Schlatterbeck:
> There was a change in the mxs-dma engine that uses a new custom flag.
> The change was not applied to the mxs spi driver.
> This results in chipselect being deasserted too early.
> This fixes the chipselect problem by using the new flag in the mxs-spi
> driver.
>
> Fixes: ceeeb99cd821 ("dmaengine: mxs: rename custom flag")
> Signed-off-by: Ralf Schlatterbeck <rsc at runtux.com>
Tested-by: Stefan Wahren <wahrenst at gmx.net>

Thanks


From keescook at chromium.org  Thu Feb  1 09:58:51 2024
From: keescook at chromium.org (Kees Cook)
Date: Thu,  1 Feb 2024 09:58:51 -0800
Subject: [PATCH 0/2] Enable PSTORE_RAM as a module in the arm64 defconfig
In-Reply-To: <20240110210600.787703-1-nfraprado@collabora.com>
References: <20240110210600.787703-1-nfraprado@collabora.com>
Message-ID: <170681032908.3615624.2380873910802248311.b4-ty@chromium.org>

On Wed, 10 Jan 2024 18:05:01 -0300, N?colas F. R. A. Prado wrote:
> This series enables the PSTORE_RAM config, aka the ramoops driver, in
> the defconfig.
> 
> 
> N?colas F. R. A. Prado (2):
>   pstore/ram: Register to module device table
>   arm64: defconfig: Enable PSTORE_RAM
> 
> [...]

Applied to for-next/pstore, thanks!

[1/2] pstore/ram: Register to module device table
      https://git.kernel.org/kees/c/d8c70720ebfd
[2/2] arm64: defconfig: Enable PSTORE_RAM
      https://git.kernel.org/kees/c/393bd157dbf8

Take care,

-- 
Kees Cook



From wahrenst at gmx.net  Thu Feb  1 09:59:37 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Thu, 1 Feb 2024 18:59:37 +0100
Subject: [PATCH v2 2/2] serial: mxs-auart: fix tx
In-Reply-To: <3935b841-77b7-4265-a727-98a358cd56be@kernel.org>
References: <20240201105557.28043-1-jirislaby@kernel.org>
 <20240201105557.28043-2-jirislaby@kernel.org>
 <3935b841-77b7-4265-a727-98a358cd56be@kernel.org>
Message-ID: <aba9744f-977c-4306-9cdf-104800344b5d@gmx.net>

Am 01.02.24 um 13:05 schrieb Jiri Slaby:
> On 01. 02. 24, 11:55, Jiri Slaby (SUSE) wrote:
>> Emil reports:
>> ?? After updating Linux on an i.MX28 board, serial communication over
>> ?? AUART broke. When I TX from the board and measure on the TX pin, it
>> ?? seems like the HW fifo is not emptied before the transmission is
>> ?? stopped.
>>
>> MXS performs weird things with stop_tx(). The driver makes it
>> conditional on uart_tx_stopped().
>>
>> So the driver needs special handling. Pass the brand new UART_TX_NOSTOP
>> to uart_port_tx_flags() and handle the stop on its own.
>>
>> Signed-off-by: Jiri Slaby (SUSE) <jirislaby at kernel.org>
>> Reported-by: Emil Kronborg <emil.kronborg at protonmail.com>
>> Fixes: 2d141e683e9a ("tty: serial: use uart_port_tx() helper")
>> Closes:
>> https://lore.kernel.org/all/miwgbnvy3hjpnricubg76ytpn7xoceehwahupy25bubbduu23s at om2lptpa26xw/
>
Tested-by: Stefan Wahren <wahrenst at gmx.net>

Thanks


From rafael at kernel.org  Thu Feb  1 10:00:51 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 1 Feb 2024 19:00:51 +0100
Subject: [RFC PATCH v2 05/21] pnp.h: Return -EPROBE_DEFER for disabled IRQ
 resource in pnp_irq()
In-Reply-To: <20231025202344.581132-6-sunilvl@ventanamicro.com>
References: <20231025202344.581132-1-sunilvl@ventanamicro.com> <20231025202344.581132-6-sunilvl@ventanamicro.com>
Message-ID: <CAJZ5v0hHYa4c2U-tegdBtoTak=MirXwyBXbN9yrWPx_x-+yMzg@mail.gmail.com>

On Wed, Oct 25, 2023 at 10:24?PM Sunil V L <sunilvl at ventanamicro.com> wrote:
>
> To support deferred PNP driver probe, pnp_irq() must return -EPROBE_DEFER
> so that the device driver can do deferred probe if the interrupt controller
> is not probed early.
>
> Signed-off-by: Sunil V L <sunilvl at ventanamicro.com>
> ---
>  include/linux/pnp.h | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/pnp.h b/include/linux/pnp.h
> index c2a7cfbca713..21cf833789fb 100644
> --- a/include/linux/pnp.h
> +++ b/include/linux/pnp.h
> @@ -147,12 +147,18 @@ static inline resource_size_t pnp_mem_len(struct pnp_dev *dev,
>  }
>
>
> -static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar)
> +static inline int pnp_irq(struct pnp_dev *dev, unsigned int bar)
>  {
>         struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar);
>
> -       if (pnp_resource_valid(res))
> +       if (pnp_resource_valid(res)) {
> +#if IS_ENABLED(CONFIG_ARCH_ACPI_DEFERRED_GSI)
> +               if (!pnp_resource_enabled(res))
> +                       return -EPROBE_DEFER;
> +#endif

What would be wrong with

if (IS_ENABLED(CONFIG_ARCH_ACPI_DEFERRED_GSI) && !pnp_resource_enabled(res))
        return -EPROBE_DEFER;

?

> +
>                 return res->start;
> +       }
>         return -1;
>  }
>
> --
> 2.39.2
>


From festevam at gmail.com  Thu Feb  1 10:00:54 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Thu,  1 Feb 2024 15:00:54 -0300
Subject: [PATCH] ARM: imx_v6_v7_defconfig: Restore CONFIG_BACKLIGHT_CLASS_DEVICE
Message-ID: <20240201180054.3869350-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

Since commit bfac19e239a7 ("fbdev: mx3fb: Remove the driver") backlight
is no longer functional.

The fbdev mx3fb driver used to automatically select 
CONFIG_BACKLIGHT_CLASS_DEVICE.

Now that the mx3fb driver has been removed, enable the
CONFIG_BACKLIGHT_CLASS_DEVICE option so that backlight can still work
by default.

Tested on a imx6dl-sabresd board.

Cc: stable at vger.kernel.org
Fixes: bfac19e239a7 ("fbdev: mx3fb: Remove the driver")
Signed-off-by: Fabio Estevam <festevam at denx.de>
---
 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 0a90583f9f01..8f9dbe8d9029 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -297,6 +297,7 @@ CONFIG_FB_MODE_HELPERS=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_L4F00242T03=y
 CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_BACKLIGHT_GPIO=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-- 
2.34.1



From afd at ti.com  Thu Feb  1 10:00:44 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:44 -0600
Subject: [PATCH 00/18] Remove pm_power_off use in drivers/power/reset
Message-ID: <20240201180102.70395-1-afd@ti.com>

Hello all,

Use of pm_power_off is considered legacy and should be replaced with
register_sys_off*(). Same for register_restart_handler(). Do this
for the drivers/power/reset subsystem for all trivial cases.

Thanks,
Andrew

Andrew Davis (18):
  power: reset: atc260x-poweroff: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: atc260x-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: xgene-reboot: Use devm_register_sys_off_handler(RESTART)
  power: reset: tps65086-restart: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: tps65086-restart: Remove unneeded device data struct
  power: reset: brcm-kona-reset: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: axxia-reset: Use devm_register_sys_off_handler(RESTART)
  power: reset: rmobile-reset: Use devm_platform_ioremap_resource()
    helper
  power: reset: rmobile-reset: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: mt6323-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: msm-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: msm-poweroff: Use devm_register_sys_off_handler(RESTART)
  power: reset: regulator-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: as3722-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: gemini-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: restart-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: syscon-poweroff: Move device data into a struct
  power: reset: syscon-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)

 drivers/power/reset/as3722-poweroff.c    | 30 ++++-------
 drivers/power/reset/atc260x-poweroff.c   | 55 ++++++++------------
 drivers/power/reset/axxia-reset.c        | 16 +++---
 drivers/power/reset/brcm-kona-reset.c    | 18 +++----
 drivers/power/reset/gemini-poweroff.c    | 16 +++---
 drivers/power/reset/msm-poweroff.c       | 25 ++++-----
 drivers/power/reset/mt6323-poweroff.c    | 28 +++++-----
 drivers/power/reset/regulator-poweroff.c | 36 +++++--------
 drivers/power/reset/restart-poweroff.c   | 25 +++------
 drivers/power/reset/rmobile-reset.c      | 38 +++++---------
 drivers/power/reset/syscon-poweroff.c    | 66 ++++++++++++------------
 drivers/power/reset/tps65086-restart.c   | 58 ++++-----------------
 drivers/power/reset/xgene-reboot.c       | 13 ++---
 13 files changed, 158 insertions(+), 266 deletions(-)

-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:45 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:45 -0600
Subject: [PATCH 01/18] power: reset: atc260x-poweroff: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-2-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/atc260x-poweroff.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/power/reset/atc260x-poweroff.c b/drivers/power/reset/atc260x-poweroff.c
index b4aa50e9685e1..ce2748d3282c3 100644
--- a/drivers/power/reset/atc260x-poweroff.c
+++ b/drivers/power/reset/atc260x-poweroff.c
@@ -16,7 +16,6 @@
 struct atc260x_pwrc {
 	struct device *dev;
 	struct regmap *regmap;
-	struct notifier_block restart_nb;
 	int (*do_poweroff)(const struct atc260x_pwrc *pwrc, bool restart);
 };
 
@@ -172,11 +171,9 @@ static void atc260x_pwrc_pm_handler(void)
 	WARN_ONCE(1, "Unable to power off system\n");
 }
 
-static int atc260x_pwrc_restart_handler(struct notifier_block *nb,
-					unsigned long mode, void *cmd)
+static int atc260x_pwrc_restart_handler(struct sys_off_data *data)
 {
-	struct atc260x_pwrc *pwrc = container_of(nb, struct atc260x_pwrc,
-						 restart_nb);
+	struct atc260x_pwrc *pwrc = data->cb_data;
 	pwrc->do_poweroff(pwrc, true);
 
 	return NOTIFY_DONE;
@@ -194,8 +191,6 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 
 	priv->dev = &pdev->dev;
 	priv->regmap = atc260x->regmap;
-	priv->restart_nb.notifier_call = atc260x_pwrc_restart_handler;
-	priv->restart_nb.priority = 192;
 
 	switch (atc260x->ic_type) {
 	case ATC2603C:
@@ -225,7 +220,11 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 		dev_warn(priv->dev, "Poweroff callback already assigned\n");
 	}
 
-	ret = register_restart_handler(&priv->restart_nb);
+	ret = devm_register_sys_off_handler(priv->dev,
+					    SYS_OFF_MODE_RESTART,
+					    SYS_OFF_PRIO_HIGH,
+					    atc260x_pwrc_restart_handler,
+					    priv);
 	if (ret)
 		dev_err(priv->dev, "failed to register restart handler: %d\n",
 			ret);
@@ -241,8 +240,6 @@ static void atc260x_pwrc_remove(struct platform_device *pdev)
 		pm_power_off = NULL;
 		atc260x_pwrc_data = NULL;
 	}
-
-	unregister_restart_handler(&priv->restart_nb);
 }
 
 static struct platform_driver atc260x_pwrc_driver = {
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:51 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:51 -0600
Subject: [PATCH 07/18] power: reset: axxia-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-8-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/axxia-reset.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/power/reset/axxia-reset.c b/drivers/power/reset/axxia-reset.c
index 24946766760c3..797bf6773860e 100644
--- a/drivers/power/reset/axxia-reset.c
+++ b/drivers/power/reset/axxia-reset.c
@@ -26,11 +26,10 @@
 #define SC_EFUSE_INT_STATUS	0x180c
 #define   EFUSE_READ_DONE	(1<<31)
 
-static struct regmap *syscon;
-
-static int axxia_restart_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int axxia_restart_handler(struct sys_off_data *data)
 {
+	struct regmap *syscon = data->cb_data;
+
 	/* Access Key (0xab) */
 	regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab);
 	/* Select internal boot from 0xffff0000 */
@@ -44,14 +43,10 @@ static int axxia_restart_handler(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block axxia_restart_nb = {
-	.notifier_call = axxia_restart_handler,
-	.priority = 128,
-};
-
 static int axxia_reset_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct regmap *syscon;
 	int err;
 
 	syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
@@ -60,7 +55,8 @@ static int axxia_reset_probe(struct platform_device *pdev)
 		return PTR_ERR(syscon);
 	}
 
-	err = register_restart_handler(&axxia_restart_nb);
+	err = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+					    128, axxia_restart_handler, syscon);
 	if (err)
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
 
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:54 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:54 -0600
Subject: [PATCH 10/18] power: reset: mt6323-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-11-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/mt6323-poweroff.c | 28 ++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c
index 57a63c0ab7fb7..ca5d11b17ff03 100644
--- a/drivers/power/reset/mt6323-poweroff.c
+++ b/drivers/power/reset/mt6323-poweroff.c
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/mfd/mt6397/core.h>
 #include <linux/mfd/mt6397/rtc.h>
+#include <linux/reboot.h>
 
 struct mt6323_pwrc {
 	struct device *dev;
@@ -21,11 +22,9 @@ struct mt6323_pwrc {
 	u32 base;
 };
 
-static struct mt6323_pwrc *mt_pwrc;
-
-static void mt6323_do_pwroff(void)
+static int mt6323_do_pwroff(struct sys_off_data *data)
 {
-	struct mt6323_pwrc *pwrc = mt_pwrc;
+	struct mt6323_pwrc *pwrc = data->cb_data;
 	unsigned int val;
 	int ret;
 
@@ -44,6 +43,8 @@ static void mt6323_do_pwroff(void)
 	mdelay(1000);
 
 	WARN_ONCE(1, "Unable to power off system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int mt6323_pwrc_probe(struct platform_device *pdev)
@@ -51,6 +52,7 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
 	struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
 	struct mt6323_pwrc *pwrc;
 	struct resource *res;
+	int ret;
 
 	pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
 	if (!pwrc)
@@ -63,19 +65,20 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
 	pwrc->base = res->start;
 	pwrc->regmap = mt6397_chip->regmap;
 	pwrc->dev = &pdev->dev;
-	mt_pwrc = pwrc;
 
-	pm_power_off = &mt6323_do_pwroff;
+	ret = devm_register_sys_off_handler(pwrc->dev,
+					    SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    mt6323_do_pwroff,
+					    pwrc);
+	if (ret) {
+		dev_err(pwrc->dev, "failed to register power-off handler: %d\n", ret);
+		return ret;
+	}
 
 	return 0;
 }
 
-static void mt6323_pwrc_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &mt6323_do_pwroff)
-		pm_power_off = NULL;
-}
-
 static const struct of_device_id mt6323_pwrc_dt_match[] = {
 	{ .compatible = "mediatek,mt6323-pwrc" },
 	{},
@@ -84,7 +87,6 @@ MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match);
 
 static struct platform_driver mt6323_pwrc_driver = {
 	.probe          = mt6323_pwrc_probe,
-	.remove_new     = mt6323_pwrc_remove,
 	.driver         = {
 		.name   = "mt6323-pwrc",
 		.of_match_table = mt6323_pwrc_dt_match,
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:50 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:50 -0600
Subject: [PATCH 06/18] power: reset: brcm-kona-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-7-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/brcm-kona-reset.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/power/reset/brcm-kona-reset.c b/drivers/power/reset/brcm-kona-reset.c
index d05728b1db097..4bb956c8f24f8 100644
--- a/drivers/power/reset/brcm-kona-reset.c
+++ b/drivers/power/reset/brcm-kona-reset.c
@@ -13,11 +13,10 @@
 #define RSTMGR_WR_PASSWORD_SHIFT	8
 #define RSTMGR_WR_ACCESS_ENABLE		1
 
-static void __iomem *kona_reset_base;
-
-static int kona_reset_handler(struct notifier_block *this,
-				unsigned long mode, void *cmd)
+static int kona_reset_handler(struct sys_off_data *data)
 {
+	void __iomem *kona_reset_base = data->cb_data;
+
 	/*
 	 * A soft reset is triggered by writing a 0 to bit 0 of the soft reset
 	 * register. To write to that register we must first write the password
@@ -31,18 +30,17 @@ static int kona_reset_handler(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block kona_reset_nb = {
-	.notifier_call = kona_reset_handler,
-	.priority = 128,
-};
-
 static int kona_reset_probe(struct platform_device *pdev)
 {
+	void __iomem *kona_reset_base;
+
 	kona_reset_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(kona_reset_base))
 		return PTR_ERR(kona_reset_base);
 
-	return register_restart_handler(&kona_reset_nb);
+	return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+					     128, kona_reset_handler,
+					     kona_reset_base);
 }
 
 static const struct of_device_id of_match[] = {
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:46 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:46 -0600
Subject: [PATCH 02/18] power: reset: atc260x-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-3-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/atc260x-poweroff.c | 38 ++++++++++----------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/drivers/power/reset/atc260x-poweroff.c b/drivers/power/reset/atc260x-poweroff.c
index ce2748d3282c3..e3e4621ccb1dd 100644
--- a/drivers/power/reset/atc260x-poweroff.c
+++ b/drivers/power/reset/atc260x-poweroff.c
@@ -19,9 +19,6 @@ struct atc260x_pwrc {
 	int (*do_poweroff)(const struct atc260x_pwrc *pwrc, bool restart);
 };
 
-/* Global variable needed only for pm_power_off */
-static struct atc260x_pwrc *atc260x_pwrc_data;
-
 static int atc2603c_do_poweroff(const struct atc260x_pwrc *pwrc, bool restart)
 {
 	int ret, deep_sleep = 0;
@@ -164,11 +161,15 @@ static int atc2609a_init(const struct atc260x_pwrc *pwrc)
 	return ret;
 }
 
-static void atc260x_pwrc_pm_handler(void)
+static int atc260x_pwrc_pm_handler(struct sys_off_data *data)
 {
-	atc260x_pwrc_data->do_poweroff(atc260x_pwrc_data, false);
+	struct atc260x_pwrc *pwrc = data->cb_data;
+
+	pwrc->do_poweroff(pwrc, false);
 
 	WARN_ONCE(1, "Unable to power off system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int atc260x_pwrc_restart_handler(struct sys_off_data *data)
@@ -211,14 +212,14 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	platform_set_drvdata(pdev, priv);
-
-	if (!pm_power_off) {
-		atc260x_pwrc_data = priv;
-		pm_power_off = atc260x_pwrc_pm_handler;
-	} else {
-		dev_warn(priv->dev, "Poweroff callback already assigned\n");
-	}
+	ret = devm_register_sys_off_handler(priv->dev,
+					    SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    atc260x_pwrc_pm_handler,
+					    priv);
+	if (ret)
+		dev_err(priv->dev, "failed to register power-off handler: %d\n",
+			ret);
 
 	ret = devm_register_sys_off_handler(priv->dev,
 					    SYS_OFF_MODE_RESTART,
@@ -232,19 +233,8 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static void atc260x_pwrc_remove(struct platform_device *pdev)
-{
-	struct atc260x_pwrc *priv = platform_get_drvdata(pdev);
-
-	if (atc260x_pwrc_data == priv) {
-		pm_power_off = NULL;
-		atc260x_pwrc_data = NULL;
-	}
-}
-
 static struct platform_driver atc260x_pwrc_driver = {
 	.probe = atc260x_pwrc_probe,
-	.remove_new = atc260x_pwrc_remove,
 	.driver = {
 		.name = "atc260x-pwrc",
 	},
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:53 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:53 -0600
Subject: [PATCH 09/18] power: reset: rmobile-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-10-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/rmobile-reset.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c
index 29c17ed2d4de9..41e98ff33a3c3 100644
--- a/drivers/power/reset/rmobile-reset.c
+++ b/drivers/power/reset/rmobile-reset.c
@@ -19,12 +19,9 @@
 /* Reset Control Register 2 */
 #define RESCNT2_PRES	0x80000000	/* Soft power-on reset */
 
-static void __iomem *sysc_base2;
-
-static int rmobile_reset_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int rmobile_reset_handler(struct sys_off_data *data)
 {
-	pr_debug("%s %lu\n", __func__, mode);
+	void __iomem *sysc_base2 = data->cb_data;
 
 	/* Let's assume we have acquired the HPB semaphore */
 	writel(RESCNT2_PRES, sysc_base2 + RESCNT2);
@@ -32,20 +29,20 @@ static int rmobile_reset_handler(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block rmobile_reset_nb = {
-	.notifier_call = rmobile_reset_handler,
-	.priority = 192,
-};
-
 static int rmobile_reset_probe(struct platform_device *pdev)
 {
+	void __iomem *sysc_base2;
 	int error;
 
 	sysc_base2 = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(sysc_base2))
 		return PTR_ERR(sysc_base2);
 
-	error = register_restart_handler(&rmobile_reset_nb);
+	error = devm_register_sys_off_handler(&pdev->dev,
+					      SYS_OFF_MODE_RESTART,
+					      SYS_OFF_PRIO_HIGH,
+					      rmobile_reset_handler,
+					      sysc_base2);
 	if (error) {
 		dev_err(&pdev->dev,
 			"cannot register restart handler (err=%d)\n", error);
@@ -55,11 +52,6 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static void rmobile_reset_remove(struct platform_device *pdev)
-{
-	unregister_restart_handler(&rmobile_reset_nb);
-}
-
 static const struct of_device_id rmobile_reset_of_match[] = {
 	{ .compatible = "renesas,sysc-rmobile", },
 	{ /* sentinel */ }
@@ -68,7 +60,6 @@ MODULE_DEVICE_TABLE(of, rmobile_reset_of_match);
 
 static struct platform_driver rmobile_reset_driver = {
 	.probe = rmobile_reset_probe,
-	.remove_new = rmobile_reset_remove,
 	.driver = {
 		.name = "rmobile_reset",
 		.of_match_table = rmobile_reset_of_match,
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:55 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:55 -0600
Subject: [PATCH 11/18] power: reset: msm-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-12-afd@ti.com>

Use this helper to register sys_off handler. Drivers should move away from
setting pm_power_off directly as it only allows for one handler. The new
way allows for trying multiple if the first one doesn't work.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/msm-poweroff.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index d96d248a6e25b..bcf04491e7022 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -28,9 +28,11 @@ static struct notifier_block restart_nb = {
 	.priority = 128,
 };
 
-static void do_msm_poweroff(void)
+static int do_msm_poweroff(struct sys_off_data *data)
 {
 	deassert_pshold(&restart_nb, 0, NULL);
+
+	return NOTIFY_DONE;
 }
 
 static int msm_restart_probe(struct platform_device *pdev)
@@ -41,7 +43,9 @@ static int msm_restart_probe(struct platform_device *pdev)
 
 	register_restart_handler(&restart_nb);
 
-	pm_power_off = do_msm_poweroff;
+	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
+				      SYS_OFF_PRIO_DEFAULT, do_msm_poweroff,
+				      msm_ps_hold);
 
 	return 0;
 }
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:48 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:48 -0600
Subject: [PATCH 04/18] power: reset: tps65086-restart: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-5-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/tps65086-restart.c | 35 ++++++--------------------
 1 file changed, 7 insertions(+), 28 deletions(-)

diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c
index ee8e9f4b837ea..82d7a761a0385 100644
--- a/drivers/power/reset/tps65086-restart.c
+++ b/drivers/power/reset/tps65086-restart.c
@@ -10,15 +10,12 @@
 #include <linux/reboot.h>
 
 struct tps65086_restart {
-	struct notifier_block handler;
 	struct device *dev;
 };
 
-static int tps65086_restart_notify(struct notifier_block *this,
-				   unsigned long mode, void *cmd)
+static int tps65086_restart_notify(struct sys_off_data *data)
 {
-	struct tps65086_restart *tps65086_restart =
-		container_of(this, struct tps65086_restart, handler);
+	struct tps65086_restart *tps65086_restart = data->cb_data;
 	struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent);
 	int ret;
 
@@ -46,13 +43,13 @@ static int tps65086_restart_probe(struct platform_device *pdev)
 	if (!tps65086_restart)
 		return -ENOMEM;
 
-	platform_set_drvdata(pdev, tps65086_restart);
-
-	tps65086_restart->handler.notifier_call = tps65086_restart_notify;
-	tps65086_restart->handler.priority = 192;
 	tps65086_restart->dev = &pdev->dev;
 
-	ret = register_restart_handler(&tps65086_restart->handler);
+	ret = devm_register_sys_off_handler(&pdev->dev,
+					    SYS_OFF_MODE_RESTART,
+					    SYS_OFF_PRIO_HIGH,
+					    tps65086_restart_notify,
+					    tps65086_restart);
 	if (ret) {
 		dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
 			__func__, ret);
@@ -62,23 +59,6 @@ static int tps65086_restart_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static void tps65086_restart_remove(struct platform_device *pdev)
-{
-	struct tps65086_restart *tps65086_restart = platform_get_drvdata(pdev);
-	int ret;
-
-	ret = unregister_restart_handler(&tps65086_restart->handler);
-	if (ret) {
-		/*
-		 * tps65086_restart_probe() registered the restart handler. So
-		 * unregistering should work fine. Checking the error code
-		 * shouldn't be needed, still doing it for completeness.
-		 */
-		dev_err(&pdev->dev, "%s: cannot unregister restart handler: %d\n",
-			__func__, ret);
-	}
-}
-
 static const struct platform_device_id tps65086_restart_id_table[] = {
 	{ "tps65086-reset", },
 	{ /* sentinel */ }
@@ -90,7 +70,6 @@ static struct platform_driver tps65086_restart_driver = {
 		.name = "tps65086-restart",
 	},
 	.probe = tps65086_restart_probe,
-	.remove_new = tps65086_restart_remove,
 	.id_table = tps65086_restart_id_table,
 };
 module_platform_driver(tps65086_restart_driver);
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:01:01 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:01:01 -0600
Subject: [PATCH 17/18] power: reset: syscon-poweroff: Move device data into a struct
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-18-afd@ti.com>

Currently all these device data elements are top level global variables.
Move these into a struct. This will be used in the next patch when
the global variable usage is removed. Doing this in two steps makes
the patches easier to read.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/syscon-poweroff.c | 36 +++++++++++++++------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
index 1b2ce7734260c..4899a019256e8 100644
--- a/drivers/power/reset/syscon-poweroff.c
+++ b/drivers/power/reset/syscon-poweroff.c
@@ -15,15 +15,19 @@
 #include <linux/pm.h>
 #include <linux/regmap.h>
 
-static struct regmap *map;
-static u32 offset;
-static u32 value;
-static u32 mask;
+struct syscon_poweroff_data {
+	struct regmap *map;
+	u32 offset;
+	u32 value;
+	u32 mask;
+};
+
+static struct syscon_poweroff_data *data;
 
 static void syscon_poweroff(void)
 {
 	/* Issue the poweroff */
-	regmap_update_bits(map, offset, mask, value);
+	regmap_update_bits(data->map, data->offset, data->mask, data->value);
 
 	mdelay(1000);
 
@@ -35,22 +39,22 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	int mask_err, value_err;
 
-	map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
-	if (IS_ERR(map)) {
-		map = syscon_node_to_regmap(dev->parent->of_node);
-		if (IS_ERR(map)) {
+	data->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
+	if (IS_ERR(data->map)) {
+		data->map = syscon_node_to_regmap(dev->parent->of_node);
+		if (IS_ERR(data->map)) {
 			dev_err(dev, "unable to get syscon");
-			return PTR_ERR(map);
+			return PTR_ERR(data->map);
 		}
 	}
 
-	if (of_property_read_u32(dev->of_node, "offset", &offset)) {
+	if (of_property_read_u32(dev->of_node, "offset", &data->offset)) {
 		dev_err(dev, "unable to read 'offset'");
 		return -EINVAL;
 	}
 
-	value_err = of_property_read_u32(dev->of_node, "value", &value);
-	mask_err = of_property_read_u32(dev->of_node, "mask", &mask);
+	value_err = of_property_read_u32(dev->of_node, "value", &data->value);
+	mask_err = of_property_read_u32(dev->of_node, "mask", &data->mask);
 	if (value_err && mask_err) {
 		dev_err(dev, "unable to read 'value' and 'mask'");
 		return -EINVAL;
@@ -58,11 +62,11 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 
 	if (value_err) {
 		/* support old binding */
-		value = mask;
-		mask = 0xFFFFFFFF;
+		data->value = data->mask;
+		data->mask = 0xFFFFFFFF;
 	} else if (mask_err) {
 		/* support value without mask*/
-		mask = 0xFFFFFFFF;
+		data->mask = 0xFFFFFFFF;
 	}
 
 	if (pm_power_off) {
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:59 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:59 -0600
Subject: [PATCH 15/18] power: reset: gemini-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-16-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/gemini-poweroff.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/power/reset/gemini-poweroff.c b/drivers/power/reset/gemini-poweroff.c
index d309b610142ce..06d6992dec892 100644
--- a/drivers/power/reset/gemini-poweroff.c
+++ b/drivers/power/reset/gemini-poweroff.c
@@ -70,12 +70,9 @@ static irqreturn_t gemini_powerbutton_interrupt(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-/* This callback needs this static local as it has void as argument */
-static struct gemini_powercon *gpw_poweroff;
-
-static void gemini_poweroff(void)
+static int gemini_poweroff(struct sys_off_data *data)
 {
-	struct gemini_powercon *gpw = gpw_poweroff;
+	struct gemini_powercon *gpw = data->cb_data;
 	u32 val;
 
 	dev_crit(gpw->dev, "Gemini power off\n");
@@ -86,6 +83,8 @@ static void gemini_poweroff(void)
 	val &= ~GEMINI_CTRL_ENABLE;
 	val |= GEMINI_CTRL_SHUTDOWN;
 	writel(val, gpw->base + GEMINI_PWC_CTRLREG);
+
+	return NOTIFY_DONE;
 }
 
 static int gemini_poweroff_probe(struct platform_device *pdev)
@@ -148,8 +147,11 @@ static int gemini_poweroff_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	pm_power_off = gemini_poweroff;
-	gpw_poweroff = gpw;
+	ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    gemini_poweroff, gpw);
+	if (ret)
+		return ret;
 
 	dev_info(dev, "Gemini poweroff driver registered\n");
 
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:47 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:47 -0600
Subject: [PATCH 03/18] power: reset: xgene-reboot: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-4-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/xgene-reboot.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
index c2e5a99940d37..5c923ab838a55 100644
--- a/drivers/power/reset/xgene-reboot.c
+++ b/drivers/power/reset/xgene-reboot.c
@@ -24,15 +24,11 @@ struct xgene_reboot_context {
 	struct device *dev;
 	void *csr;
 	u32 mask;
-	struct notifier_block restart_handler;
 };
 
-static int xgene_restart_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int xgene_restart_handler(struct sys_off_data *data)
 {
-	struct xgene_reboot_context *ctx =
-		container_of(this, struct xgene_reboot_context,
-			     restart_handler);
+	struct xgene_reboot_context *ctx = data->cb_data;
 
 	/* Issue the reboot */
 	writel(ctx->mask, ctx->csr);
@@ -64,9 +60,8 @@ static int xgene_reboot_probe(struct platform_device *pdev)
 		ctx->mask = 0xFFFFFFFF;
 
 	ctx->dev = dev;
-	ctx->restart_handler.notifier_call = xgene_restart_handler;
-	ctx->restart_handler.priority = 128;
-	err = register_restart_handler(&ctx->restart_handler);
+	err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, 128,
+					    xgene_restart_handler, ctx);
 	if (err) {
 		iounmap(ctx->csr);
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:56 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:56 -0600
Subject: [PATCH 12/18] power: reset: msm-poweroff: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-13-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/msm-poweroff.c | 23 ++++++-----------------
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index bcf04491e7022..c5831c46f69e2 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -13,35 +13,24 @@
 #include <linux/reboot.h>
 #include <linux/pm.h>
 
-static void __iomem *msm_ps_hold;
-static int deassert_pshold(struct notifier_block *nb, unsigned long action,
-			   void *data)
+static int do_msm_poweroff(struct sys_off_data *data)
 {
+	void __iomem *msm_ps_hold = data->cb_data;
+
 	writel(0, msm_ps_hold);
 	mdelay(10000);
 
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block restart_nb = {
-	.notifier_call = deassert_pshold,
-	.priority = 128,
-};
-
-static int do_msm_poweroff(struct sys_off_data *data)
-{
-	deassert_pshold(&restart_nb, 0, NULL);
-
-	return NOTIFY_DONE;
-}
-
 static int msm_restart_probe(struct platform_device *pdev)
 {
-	msm_ps_hold = devm_platform_ioremap_resource(pdev, 0);
+	void __iomem *msm_ps_hold = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(msm_ps_hold))
 		return PTR_ERR(msm_ps_hold);
 
-	register_restart_handler(&restart_nb);
+	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+				      128, do_msm_poweroff, msm_ps_hold);
 
 	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
 				      SYS_OFF_PRIO_DEFAULT, do_msm_poweroff,
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:01:02 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:01:02 -0600
Subject: [PATCH 18/18] power: reset: syscon-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-19-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/syscon-poweroff.c | 34 ++++++++++++---------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
index 4899a019256e8..203936f4c544f 100644
--- a/drivers/power/reset/syscon-poweroff.c
+++ b/drivers/power/reset/syscon-poweroff.c
@@ -13,6 +13,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+#include <linux/reboot.h>
 #include <linux/regmap.h>
 
 struct syscon_poweroff_data {
@@ -22,23 +23,30 @@ struct syscon_poweroff_data {
 	u32 mask;
 };
 
-static struct syscon_poweroff_data *data;
-
-static void syscon_poweroff(void)
+static int syscon_poweroff(struct sys_off_data *off_data)
 {
+	struct syscon_poweroff_data *data = off_data->cb_data;
+
 	/* Issue the poweroff */
 	regmap_update_bits(data->map, data->offset, data->mask, data->value);
 
 	mdelay(1000);
 
 	pr_emerg("Unable to poweroff system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int syscon_poweroff_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct syscon_poweroff_data *data;
 	int mask_err, value_err;
 
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
 	data->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
 	if (IS_ERR(data->map)) {
 		data->map = syscon_node_to_regmap(dev->parent->of_node);
@@ -69,21 +77,10 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 		data->mask = 0xFFFFFFFF;
 	}
 
-	if (pm_power_off) {
-		dev_err(dev, "pm_power_off already claimed for %ps",
-			pm_power_off);
-		return -EBUSY;
-	}
-
-	pm_power_off = syscon_poweroff;
-
-	return 0;
-}
-
-static void syscon_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == syscon_poweroff)
-		pm_power_off = NULL;
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_DEFAULT,
+					     syscon_poweroff, data);
 }
 
 static const struct of_device_id syscon_poweroff_of_match[] = {
@@ -93,7 +90,6 @@ static const struct of_device_id syscon_poweroff_of_match[] = {
 
 static struct platform_driver syscon_poweroff_driver = {
 	.probe = syscon_poweroff_probe,
-	.remove_new = syscon_poweroff_remove,
 	.driver = {
 		.name = "syscon-poweroff",
 		.of_match_table = syscon_poweroff_of_match,
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:49 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:49 -0600
Subject: [PATCH 05/18] power: reset: tps65086-restart: Remove unneeded device data struct
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-6-afd@ti.com>

We only need one member of the struct tps65086_restart, pass that
tps65086_restart_notify() directly. Remove that struct and its
allocation.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/tps65086-restart.c | 35 ++++++--------------------
 1 file changed, 8 insertions(+), 27 deletions(-)

diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c
index 82d7a761a0385..6976dbcac74fa 100644
--- a/drivers/power/reset/tps65086-restart.c
+++ b/drivers/power/reset/tps65086-restart.c
@@ -9,19 +9,14 @@
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
 
-struct tps65086_restart {
-	struct device *dev;
-};
-
 static int tps65086_restart_notify(struct sys_off_data *data)
 {
-	struct tps65086_restart *tps65086_restart = data->cb_data;
-	struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent);
+	struct tps65086 *tps65086 = data->cb_data;
 	int ret;
 
 	ret = regmap_write(tps65086->regmap, TPS65086_FORCESHUTDN, 1);
 	if (ret) {
-		dev_err(tps65086_restart->dev, "%s: error writing to tps65086 pmic: %d\n",
+		dev_err(tps65086->dev, "%s: error writing to tps65086 pmic: %d\n",
 			__func__, ret);
 		return NOTIFY_DONE;
 	}
@@ -36,27 +31,13 @@ static int tps65086_restart_notify(struct sys_off_data *data)
 
 static int tps65086_restart_probe(struct platform_device *pdev)
 {
-	struct tps65086_restart *tps65086_restart;
-	int ret;
-
-	tps65086_restart = devm_kzalloc(&pdev->dev, sizeof(*tps65086_restart), GFP_KERNEL);
-	if (!tps65086_restart)
-		return -ENOMEM;
-
-	tps65086_restart->dev = &pdev->dev;
-
-	ret = devm_register_sys_off_handler(&pdev->dev,
-					    SYS_OFF_MODE_RESTART,
-					    SYS_OFF_PRIO_HIGH,
-					    tps65086_restart_notify,
-					    tps65086_restart);
-	if (ret) {
-		dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
-			__func__, ret);
-		return -ENODEV;
-	}
+	struct tps65086 *tps65086 = dev_get_drvdata(pdev->dev.parent);
 
-	return 0;
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_RESTART,
+					     SYS_OFF_PRIO_HIGH,
+					     tps65086_restart_notify,
+					     tps65086);
 }
 
 static const struct platform_device_id tps65086_restart_id_table[] = {
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:01:00 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:01:00 -0600
Subject: [PATCH 16/18] power: reset: restart-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-17-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/restart-poweroff.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
index f4d6004793d3a..fcd588f9ae9d3 100644
--- a/drivers/power/reset/restart-poweroff.c
+++ b/drivers/power/reset/restart-poweroff.c
@@ -14,29 +14,21 @@
 #include <linux/module.h>
 #include <linux/reboot.h>
 
-static void restart_poweroff_do_poweroff(void)
+static int restart_poweroff_do_poweroff(struct sys_off_data *data)
 {
 	reboot_mode = REBOOT_HARD;
 	machine_restart(NULL);
+	return NOTIFY_DONE;
 }
 
 static int restart_poweroff_probe(struct platform_device *pdev)
 {
-	/* If a pm_power_off function has already been added, leave it alone */
-	if (pm_power_off != NULL) {
-		dev_err(&pdev->dev,
-			"pm_power_off function already registered");
-		return -EBUSY;
-	}
-
-	pm_power_off = &restart_poweroff_do_poweroff;
-	return 0;
-}
-
-static void restart_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &restart_poweroff_do_poweroff)
-		pm_power_off = NULL;
+	/* Set this handler to low priority to not override an existing handler */
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_LOW,
+					     restart_poweroff_do_poweroff,
+					     NULL);
 }
 
 static const struct of_device_id of_restart_poweroff_match[] = {
@@ -47,7 +39,6 @@ MODULE_DEVICE_TABLE(of, of_restart_poweroff_match);
 
 static struct platform_driver restart_poweroff_driver = {
 	.probe = restart_poweroff_probe,
-	.remove_new = restart_poweroff_remove,
 	.driver = {
 		.name = "poweroff-restart",
 		.of_match_table = of_restart_poweroff_match,
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:57 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:57 -0600
Subject: [PATCH 13/18] power: reset: regulator-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-14-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/regulator-poweroff.c | 36 +++++++++---------------
 1 file changed, 13 insertions(+), 23 deletions(-)

diff --git a/drivers/power/reset/regulator-poweroff.c b/drivers/power/reset/regulator-poweroff.c
index 15160809c423a..fed4978e38580 100644
--- a/drivers/power/reset/regulator-poweroff.c
+++ b/drivers/power/reset/regulator-poweroff.c
@@ -13,18 +13,15 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+#include <linux/reboot.h>
 #include <linux/regulator/consumer.h>
 
 #define TIMEOUT_MS 3000
 
-/*
- * Hold configuration here, cannot be more than one instance of the driver
- * since pm_power_off itself is global.
- */
-static struct regulator *cpu_regulator;
-
-static void regulator_poweroff_do_poweroff(void)
+static int regulator_poweroff_do_poweroff(struct sys_off_data *data)
 {
+	struct regulator *cpu_regulator = data->cb_data;
+
 	if (cpu_regulator && regulator_is_enabled(cpu_regulator))
 		regulator_force_disable(cpu_regulator);
 
@@ -32,30 +29,24 @@ static void regulator_poweroff_do_poweroff(void)
 	mdelay(TIMEOUT_MS);
 
 	WARN_ON(1);
+
+	return NOTIFY_DONE;
 }
 
 static int regulator_poweroff_probe(struct platform_device *pdev)
 {
-	/* If a pm_power_off function has already been added, leave it alone */
-	if (pm_power_off != NULL) {
-		dev_err(&pdev->dev,
-			"%s: pm_power_off function already registered\n",
-			__func__);
-		return -EBUSY;
-	}
+	struct regulator *cpu_regulator;
 
 	cpu_regulator = devm_regulator_get(&pdev->dev, "cpu");
 	if (IS_ERR(cpu_regulator))
 		return PTR_ERR(cpu_regulator);
 
-	pm_power_off = &regulator_poweroff_do_poweroff;
-	return 0;
-}
-
-static void regulator_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &regulator_poweroff_do_poweroff)
-		pm_power_off = NULL;
+	/* Set this handler to low priority to not override an existing handler */
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_LOW,
+					     regulator_poweroff_do_poweroff,
+					     cpu_regulator);
 }
 
 static const struct of_device_id of_regulator_poweroff_match[] = {
@@ -66,7 +57,6 @@ MODULE_DEVICE_TABLE(of, of_regulator_poweroff_match);
 
 static struct platform_driver regulator_poweroff_driver = {
 	.probe = regulator_poweroff_probe,
-	.remove_new = regulator_poweroff_remove,
 	.driver = {
 		.name = "poweroff-regulator",
 		.of_match_table = of_regulator_poweroff_match,
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:52 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:52 -0600
Subject: [PATCH 08/18] power: reset: rmobile-reset: Use devm_platform_ioremap_resource() helper
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-9-afd@ti.com>

Use device life-cycle managed ioremap function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/rmobile-reset.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c
index 5df9b41c68c79..29c17ed2d4de9 100644
--- a/drivers/power/reset/rmobile-reset.c
+++ b/drivers/power/reset/rmobile-reset.c
@@ -41,28 +41,23 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 {
 	int error;
 
-	sysc_base2 = of_iomap(pdev->dev.of_node, 1);
-	if (!sysc_base2)
-		return -ENODEV;
+	sysc_base2 = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(sysc_base2))
+		return PTR_ERR(sysc_base2);
 
 	error = register_restart_handler(&rmobile_reset_nb);
 	if (error) {
 		dev_err(&pdev->dev,
 			"cannot register restart handler (err=%d)\n", error);
-		goto fail_unmap;
+		return error;
 	}
 
 	return 0;
-
-fail_unmap:
-	iounmap(sysc_base2);
-	return error;
 }
 
 static void rmobile_reset_remove(struct platform_device *pdev)
 {
 	unregister_restart_handler(&rmobile_reset_nb);
-	iounmap(sysc_base2);
 }
 
 static const struct of_device_id rmobile_reset_of_match[] = {
-- 
2.39.2



From afd at ti.com  Thu Feb  1 10:00:58 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:00:58 -0600
Subject: [PATCH 14/18] power: reset: as3722-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240201180102.70395-1-afd@ti.com>
References: <20240201180102.70395-1-afd@ti.com>
Message-ID: <20240201180102.70395-15-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/as3722-poweroff.c | 30 ++++++++++-----------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/power/reset/as3722-poweroff.c b/drivers/power/reset/as3722-poweroff.c
index ab3350ce2d621..bb26fa6fa67ca 100644
--- a/drivers/power/reset/as3722-poweroff.c
+++ b/drivers/power/reset/as3722-poweroff.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/slab.h>
 
 struct as3722_poweroff {
@@ -18,22 +19,18 @@ struct as3722_poweroff {
 	struct as3722 *as3722;
 };
 
-static struct as3722_poweroff *as3722_pm_poweroff;
-
-static void as3722_pm_power_off(void)
+static int as3722_pm_power_off(struct sys_off_data *data)
 {
+	struct as3722_poweroff *as3722_pm_poweroff = data->cb_data;
 	int ret;
 
-	if (!as3722_pm_poweroff) {
-		pr_err("AS3722 poweroff is not initialised\n");
-		return;
-	}
-
 	ret = as3722_update_bits(as3722_pm_poweroff->as3722,
 		AS3722_RESET_CONTROL_REG, AS3722_POWER_OFF, AS3722_POWER_OFF);
 	if (ret < 0)
 		dev_err(as3722_pm_poweroff->dev,
 			"RESET_CONTROL_REG update failed, %d\n", ret);
+
+	return NOTIFY_DONE;
 }
 
 static int as3722_poweroff_probe(struct platform_device *pdev)
@@ -54,18 +51,14 @@ static int as3722_poweroff_probe(struct platform_device *pdev)
 
 	as3722_poweroff->as3722 = dev_get_drvdata(pdev->dev.parent);
 	as3722_poweroff->dev = &pdev->dev;
-	as3722_pm_poweroff = as3722_poweroff;
-	if (!pm_power_off)
-		pm_power_off = as3722_pm_power_off;
 
-	return 0;
-}
+	return devm_register_sys_off_handler(as3722_poweroff->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_DEFAULT,
+					     as3722_pm_power_off,
+					     as3722_poweroff);
 
-static void as3722_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == as3722_pm_power_off)
-		pm_power_off = NULL;
-	as3722_pm_poweroff = NULL;
+	return 0;
 }
 
 static struct platform_driver as3722_poweroff_driver = {
@@ -73,7 +66,6 @@ static struct platform_driver as3722_poweroff_driver = {
 		.name = "as3722-power-off",
 	},
 	.probe = as3722_poweroff_probe,
-	.remove_new = as3722_poweroff_remove,
 };
 
 module_platform_driver(as3722_poweroff_driver);
-- 
2.39.2



From linux at armlinux.org.uk  Thu Feb  1 10:04:53 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 1 Feb 2024 18:04:53 +0000
Subject: [PATCH RESEND] arm: topology: Fix missing clock-frequency
 property warning
In-Reply-To: <9da01fb1-9bab-436b-af49-783e44821b26@nokia.com>
References: <20240201123605.3037829-2-stefan.wiehler@nokia.com>
 <dfccb849-67b6-489b-8e83-3df1f9b29877@linaro.org>
 <9da01fb1-9bab-436b-af49-783e44821b26@nokia.com>
Message-ID: <ZbvdRXsvY2qBXApS@shell.armlinux.org.uk>

On Thu, Feb 01, 2024 at 04:03:59PM +0100, Stefan Wiehler wrote:
> > Does this mean the /cpus property is like a default for when a CPU node
> > doesn't specify the clock frequency, or does it mean that the /cpus
> > property should only exist when all the values for each CPU are
> > identical and thus the individual CPU node clock frequency should
> > not be specified.
> 
> Good question, the device tree specification in Section 3.7 [1] says:
> 
> > The /cpus node may contain properties that are common across cpu
> nodes. See Section 3.8 for details.
> 
> And in Section 3.8 [2]:
> 
> > Properties that have identical values across cpu nodes may be placed
> > in the /cpus node instead. A client program must first examine a
> > specific cpu node, but if an expected property is not found then it
> > should look at the parent /cpus node. This results in a less verbose
> > representation of properties which are identical across all CPUs.
> 
> So I think it is pretty clear that it should only be used for
> common/identical values.

Thanks for the clarification.

As this is DT specified behaviour, I question whether it should be
implemented in arch/arm/kernel/topology.c - what I'm meaning is
a helper such as:

const void *of_get_cpu_property(const struct device_node *node,
				const char *name, int *lenp)
{
	const void *res;

	res = of_get_property(node, name, lenp);
	if (!res) {
		node = of_find_node_by_path("/cpus");
		if (node)
			res = of_get_property(node, name, lenp);
		of_node_put(node);
	}

	return res;
}

?

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


From contact at christina-quast.de  Thu Feb  1 10:06:57 2024
From: contact at christina-quast.de (Christina Quast)
Date: Thu, 01 Feb 2024 19:06:57 +0100
Subject: [PATCH v2 0/3] Add Rust Rockchip PHY driver
Message-ID: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>

Based on the example shown in drivers/net/phy/ax88796b_rust.rs, I ported
the rockchip phy driver to Rust. The code in drivers/net/phy/rockchip.c
was basically rewritten in Rust.  The patchset includes changes to
phy.rs, adding more struct driver functions for the abstraction with
Rust.

The driver was not tested on real hardware, because I do not have a
board with this phy, and I would appreciate it if somebody could try
out the driver on their board.

Signed-off-by: Christina Quast <contact at christina-quast.de>
---
Christina Quast (3):
      DONOTMERGE: rust: prelude: add bit function
      rust: phy: add some phy_driver and genphy_ functions
      net: phy: add Rust Rockchip PHY driver

 drivers/net/phy/Kconfig          |   8 +++
 drivers/net/phy/Makefile         |   4 ++
 drivers/net/phy/rockchip_rust.rs | 131 +++++++++++++++++++++++++++++++++++++++
 rust/kernel/net/phy.rs           |  31 +++++++++
 rust/kernel/prelude.rs           |  16 +++++
 5 files changed, 190 insertions(+)
---
base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
change-id: 20240201-rockchip-rust-phy_depend-681db4707777

Best regards,
-- 
Christina Quast <contact at christina-quast.de>



From contact at christina-quast.de  Thu Feb  1 10:06:59 2024
From: contact at christina-quast.de (Christina Quast)
Date: Thu, 01 Feb 2024 19:06:59 +0100
Subject: [PATCH v2 2/3] rust: phy: add some phy_driver and genphy_
 functions
In-Reply-To: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
Message-ID: <20240201-rockchip-rust-phy_depend-v2-2-c5fa4faab924@christina-quast.de>

Those functions are need for the rockchip_rust.rs implementation.

Added functions:
genphy_config_aneg
config_init

Getter functions for mdix and speed.

Signed-off-by: Christina Quast <contact at christina-quast.de>
---
 rust/kernel/net/phy.rs | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs
index e457b3c7cb2f..373a4d358e9f 100644
--- a/rust/kernel/net/phy.rs
+++ b/rust/kernel/net/phy.rs
@@ -95,6 +95,22 @@ pub fn phy_id(&self) -> u32 {
         unsafe { (*phydev).phy_id }
     }
 
+    /// Gets the current crossover of the PHY.
+    pub fn mdix(&self) -> u8 {
+        let phydev = self.0.get();
+        // SAFETY: The struct invariant ensures that we may access
+        // this field without additional synchronization.
+        unsafe { (*phydev).mdix }
+    }
+
+    /// Gets the speed of the PHY.
+    pub fn speed(&mut self) -> u32 {
+        let phydev = self.0.get();
+        // SAFETY: The struct invariant ensures that we may access
+        // this field without additional synchronization.
+        unsafe { (*phydev).speed as u32 }
+    }
+
     /// Gets the state of PHY state machine states.
     pub fn state(&self) -> DeviceState {
         let phydev = self.0.get();
@@ -300,6 +316,15 @@ pub fn genphy_read_abilities(&mut self) -> Result {
         // So it's just an FFI call.
         to_result(unsafe { bindings::genphy_read_abilities(phydev) })
     }
+
+    /// Writes BMCR
+    pub fn genphy_config_aneg(&mut self) -> Result {
+        let phydev = self.0.get();
+        // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`.
+        // So it's just an FFI call.
+        // second param = false => autoneg not requested
+        to_result(unsafe { bindings::__genphy_config_aneg(phydev, false) })
+    }
 }
 
 /// Defines certain other features this PHY supports (like interrupts).
@@ -583,6 +608,12 @@ fn soft_reset(_dev: &mut Device) -> Result {
         Err(code::ENOTSUPP)
     }
 
+    /// Called to initialize the PHY,
+    /// including after a reset
+    fn config_init(_dev: &mut Device) -> Result {
+        Err(code::ENOTSUPP)
+    }
+
     /// Probes the hardware to determine what abilities it has.
     fn get_features(_dev: &mut Device) -> Result {
         Err(code::ENOTSUPP)

-- 
2.43.0



From contact at christina-quast.de  Thu Feb  1 10:06:58 2024
From: contact at christina-quast.de (Christina Quast)
Date: Thu, 01 Feb 2024 19:06:58 +0100
Subject: [PATCH v2 1/3] DONOTMERGE: rust: prelude: add bit function
In-Reply-To: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
Message-ID: <20240201-rockchip-rust-phy_depend-v2-1-c5fa4faab924@christina-quast.de>

In order to create masks easily, the define BIT() is used in C code.
This commit adds the same functionality to the rust kernel.

Do not merge this commit, because rust/kernel/types.rs in Rust-for-Linux
already contains this functionality and will be merged into next-net
soon.
But this driver does not compile without this commit, so I am adding it
to the patchset to get more feedback on the actual driver.

Signed-off-by: Christina Quast <contact at christina-quast.de>
---
 rust/kernel/prelude.rs | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs
index ae21600970b3..16e483de2f27 100644
--- a/rust/kernel/prelude.rs
+++ b/rust/kernel/prelude.rs
@@ -38,3 +38,19 @@
 pub use super::init::{InPlaceInit, Init, PinInit};
 
 pub use super::current;
+
+/// Returns a `u32` number that has only the `n`th bit set.
+///
+/// # Arguments
+///
+/// * `n` - A `u32` that specifies the bit position (zero-based index)
+///
+/// # Example
+///
+/// ```
+/// let b = bit(2);
+/// assert_eq!(b, 4);
+#[inline]
+pub const fn bit(n: u32) -> u32 {
+    1 << n
+}

-- 
2.43.0



From contact at christina-quast.de  Thu Feb  1 10:07:00 2024
From: contact at christina-quast.de (Christina Quast)
Date: Thu, 01 Feb 2024 19:07:00 +0100
Subject: [PATCH v2 3/3] net: phy: add Rust Rockchip PHY driver
In-Reply-To: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
Message-ID: <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>

This is the Rust implementation of drivers/net/phy/rockchip.c. The
features are equivalent. You can choose C or Rust version kernel
configuration.

Signed-off-by: Christina Quast <contact at christina-quast.de>
---
 drivers/net/phy/Kconfig          |   8 +++
 drivers/net/phy/Makefile         |   4 ++
 drivers/net/phy/rockchip_rust.rs | 131 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+)

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 9e2672800f0b..8b73edb7e836 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -362,6 +362,14 @@ config ROCKCHIP_PHY
 	help
 	  Currently supports the integrated Ethernet PHY.
 
+config ROCKCHIP_RUST_PHY
+	bool "Rust driver for Rockchip Ethernet PHYs"
+	depends on RUST_PHYLIB_ABSTRACTIONS && ROCKCHIP_PHY
+	help
+	  Uses the Rust reference driver for Rockchip PHYs (rockchip_rust.ko).
+	  The features are equivalent. It supports the integrated Ethernet PHY.
+
+
 config SMSC_PHY
 	tristate "SMSC PHYs"
 	select CRC16
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 6097afd44392..045d2913bf2e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -94,7 +94,11 @@ obj-$(CONFIG_NXP_TJA11XX_PHY)	+= nxp-tja11xx.o
 obj-$(CONFIG_QSEMI_PHY)		+= qsemi.o
 obj-$(CONFIG_REALTEK_PHY)	+= realtek.o
 obj-$(CONFIG_RENESAS_PHY)	+= uPD60620.o
+ifdef CONFIG_ROCKCHIP_RUST_PHY
+obj-$(CONFIG_ROCKCHIP_PHY)	+= rockchip_rust.o
+else
 obj-$(CONFIG_ROCKCHIP_PHY)	+= rockchip.o
+endif
 obj-$(CONFIG_SMSC_PHY)		+= smsc.o
 obj-$(CONFIG_STE10XP)		+= ste10Xp.o
 obj-$(CONFIG_TERANETICS_PHY)	+= teranetics.o
diff --git a/drivers/net/phy/rockchip_rust.rs b/drivers/net/phy/rockchip_rust.rs
new file mode 100644
index 000000000000..17a1f94da8c1
--- /dev/null
+++ b/drivers/net/phy/rockchip_rust.rs
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2024 Christina Quast <contact at christina-quast.de>
+
+//! Rust Rockchip PHY driver
+//!
+//! C version of this driver: [`drivers/net/phy/rockchip.c`](./rockchip.c)
+use kernel::{
+    c_str,
+    net::phy::{self, DeviceId, Driver},
+    prelude::*,
+    uapi,
+};
+
+kernel::module_phy_driver! {
+    drivers: [PhyRockchip],
+    device_table: [
+        DeviceId::new_with_driver::<PhyRockchip>(),
+    ],
+    name: "rust_asix_phy",
+    author: "FUJITA Tomonori <fujita.tomonori at gmail.com>",
+    description: "Rust Asix PHYs driver",
+    license: "GPL",
+}
+
+
+const MII_INTERNAL_CTRL_STATUS: u16 = 17;
+const SMI_ADDR_TSTCNTL: u16 = 20;
+const SMI_ADDR_TSTWRITE: u16 = 23;
+
+const MII_AUTO_MDIX_EN: u16 = bit(7);
+const MII_MDIX_EN: u16 = bit(6);
+
+const TSTCNTL_WR: u16 = bit(14) | bit(10);
+
+const TSTMODE_ENABLE: u16 = 0x400;
+const TSTMODE_DISABLE: u16 = 0x0;
+
+const WR_ADDR_A7CFG: u16 = 0x18;
+
+struct PhyRockchip;
+
+impl PhyRockchip {
+   /// Helper function for helper_integrated_phy_analog_init
+    fn helper_init_tstmode(dev: &mut phy::Device) -> Result {
+        // Enable access to Analog and DSP register banks
+        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_ENABLE)?;
+        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_DISABLE)?;
+        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_ENABLE)
+    }
+
+    /// Helper function for helper_integrated_phy_analog_init
+    fn helper_close_tstmode(dev: &mut phy::Device) -> Result {
+        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_DISABLE)
+    }
+
+    /// Helper function for rockchip_config_init
+    fn helper_integrated_phy_analog_init(dev: &mut phy::Device) -> Result {
+        Self::helper_init_tstmode(dev)?;
+        dev.write(SMI_ADDR_TSTWRITE, 0xB)?;
+        dev.write(SMI_ADDR_TSTCNTL, TSTCNTL_WR | WR_ADDR_A7CFG)?;
+        Self::helper_close_tstmode(dev)
+    }
+
+    /// Helper function for config_init
+    fn helper_config_init(dev: &mut phy::Device) -> Result {
+        let val = !MII_AUTO_MDIX_EN & dev.read(MII_INTERNAL_CTRL_STATUS)?;
+        dev.write(MII_INTERNAL_CTRL_STATUS, val)?;
+        Self::helper_integrated_phy_analog_init(dev)
+    }
+
+    fn helper_set_polarity(dev: &mut phy::Device, polarity: u8) -> Result {
+        let reg = !MII_AUTO_MDIX_EN & dev.read(MII_INTERNAL_CTRL_STATUS)?;
+        let val = match polarity as u32 {
+            // status: MDI; control: force MDI
+            uapi::ETH_TP_MDI => Some(reg & !MII_MDIX_EN),
+            // status: MDI-X; control: force MDI-X
+            uapi::ETH_TP_MDI_X => Some(reg | MII_MDIX_EN),
+            // uapi::ETH_TP_MDI_AUTO => control: auto-select
+            // uapi::ETH_TP_MDI_INVALID => status: unknown; control: unsupported
+            _ => None,
+        };
+        if let Some(v) = val {
+            if v != reg {
+                return dev.write(MII_INTERNAL_CTRL_STATUS, v);
+            }
+        }
+        Ok(())
+
+    }
+}
+
+#[vtable]
+impl Driver for PhyRockchip {
+    const FLAGS: u32 = 0;
+    const NAME: &'static CStr = c_str!("Rockchip integrated EPHY");
+    const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_custom_mask(0x1234d400, 0xfffffff0);
+
+    fn link_change_notify(dev: &mut phy::Device) {
+    // If mode switch happens from 10BT to 100BT, all DSP/AFE
+    // registers are set to default values. So any AFE/DSP
+    // registers have to be re-initialized in this case.
+        if dev.state() == phy::DeviceState::Running && dev.speed() == uapi::SPEED_100 {
+            if let Err(e) = Self::helper_integrated_phy_analog_init(dev) {
+                pr_err!("rockchip: integrated_phy_analog_init err: {:?}", e);
+            }
+        }
+    }
+
+    fn soft_reset(dev: &mut phy::Device) -> Result {
+        dev.genphy_soft_reset()
+    }
+
+    fn config_init(dev: &mut phy::Device) -> Result {
+        PhyRockchip::helper_config_init(dev)
+    }
+
+    fn config_aneg(dev: &mut phy::Device) -> Result {
+        PhyRockchip::helper_set_polarity(dev, dev.mdix())?;
+        dev.genphy_config_aneg()
+    }
+
+    fn suspend(dev: &mut phy::Device) -> Result {
+        dev.genphy_suspend()
+    }
+
+    fn resume(dev: &mut phy::Device) -> Result {
+        let _ = dev.genphy_resume();
+
+        PhyRockchip::helper_config_init(dev)
+    }
+}

-- 
2.43.0



From rafael at kernel.org  Thu Feb  1 10:10:28 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 1 Feb 2024 19:10:28 +0100
Subject: [RFC PATCH v3 00/17] RISC-V: ACPI: Add external interrupt
 controller support
In-Reply-To: <ZbiQ/tO/odnJCBD1@sunil-laptop>
References: <20231219174526.2235150-1-sunilvl@ventanamicro.com>
 <CAJZ5v0j6Veze8xDFKTbVZ5=WAfmLdeJ8NXRnh9kwCZgyaDdgew@mail.gmail.com> <ZbiQ/tO/odnJCBD1@sunil-laptop>
Message-ID: <CAJZ5v0gnH0uPEM0q9VzJOg2Z_7bOP9XdQbOttpRtnkLGej45Sw@mail.gmail.com>

On Tue, Jan 30, 2024 at 7:02?AM Sunil V L <sunilvl at ventanamicro.com> wrote:
>
> On Tue, Dec 19, 2023 at 06:50:19PM +0100, Rafael J. Wysocki wrote:
> > On Tue, Dec 19, 2023 at 6:45?PM Sunil V L <sunilvl at ventanamicro.com> wrote:
> > >
> > > This series adds support for the below ECR approved by ASWG.
> > > 1) MADT - https://drive.google.com/file/d/1oMGPyOD58JaPgMl1pKasT-VKsIKia7zR/view?usp=sharing
> > >
> > > The series primarily enables irqchip drivers for RISC-V ACPI based
> > > platforms.
> > >
> > > The series can be broadly categorized like below.
> > >
> > > 1) PCI ACPI related functions are migrated from arm64 to common file so
> > > that we don't need to duplicate them for RISC-V.
> > >
> > > 2) Introduced support for fw_devlink for ACPI nodes for IRQ dependency.
> > > This helps to support deferred probe of interrupt controller drivers.
> > >
> > > 3) Modified pnp_irq() to try registering the IRQ  again if it sees it in
> > > disabled state. This solution is similar to how
> > > platform_get_irq_optional() works for regular platform devices.
> > >
> > > 4) Added support for re-ordering the probe of interrupt controllers when
> > > IRQCHIP_ACPI_DECLARE is used.
> > >
> > > 5) ACPI support added in RISC-V interrupt controller drivers.
> > >
> > > This series is based on Anup's AIA v11 series. Since Anup's AIA v11 is
> > > not merged yet and first time introducing fw_devlink, deferred probe and
> > > reordering support for IRQCHIP probe, this series is still kept as RFC.
> > > Looking forward for the feedback!
> > >
> > > Changes since RFC v2:
> > >         1) Introduced fw_devlink for ACPI nodes for IRQ dependency.
> > >         2) Dropped patches in drivers which are not required due to
> > >            fw_devlink support.
> > >         3) Dropped pci_set_msi() patch and added a patch in
> > >            pci_create_root_bus().
> > >         4) Updated pnp_irq() patch so that none of the actual PNP
> > >            drivers need to change.
> > >
> > > Changes since RFC v1:
> > >         1) Abandoned swnode approach as per Marc's feedback.
> > >         2) To cope up with AIA series changes which changed irqchip driver
> > >            probe from core_initcall() to platform_driver, added patches
> > >            to support deferred probing.
> > >         3) Rebased on top of Anup's AIA v11 and added tags.
> > >
> > > To test the series,
> > >
> > > 1) Qemu should be built using the riscv_acpi_b2_v8 branch at
> > > https://github.com/vlsunil/qemu.git
> > >
> > > 2) EDK2 should be built using the instructions at:
> > > https://github.com/tianocore/edk2/blob/master/OvmfPkg/RiscVVirt/README.md
> > >
> > > 3) Build Linux using this series on top of Anup's AIA v11 series.
> > >
> > > Run Qemu:
> > > qemu-system-riscv64 \
> > >  -M virt,pflash0=pflash0,pflash1=pflash1,aia=aplic-imsic \
> > >  -m 2G -smp 8 \
> > >  -serial mon:stdio \
> > >  -device virtio-gpu-pci -full-screen \
> > >  -device qemu-xhci \
> > >  -device usb-kbd \
> > >  -blockdev node-name=pflash0,driver=file,read-only=on,filename=RISCV_VIRT_CODE.fd \
> > >  -blockdev node-name=pflash1,driver=file,filename=RISCV_VIRT_VARS.fd \
> > >  -netdev user,id=net0 -device virtio-net-pci,netdev=net0 \
> > >  -kernel arch/riscv/boot/Image \
> > >  -initrd rootfs.cpio \
> > >  -append "root=/dev/ram ro console=ttyS0 rootwait earlycon=uart8250,mmio,0x10000000"
> > >
> > > To boot with APLIC only, use aia=aplic.
> > > To boot with PLIC, remove aia= option.
> > >
> > > This series is also available in acpi_b2_v3_riscv_aia_v11 branch at
> > > https://github.com/vlsunil/linux.git
> > >
> > > Based-on: 20231023172800.315343-1-apatel at ventanamicro.com
> > > (https://lore.kernel.org/lkml/20231023172800.315343-1-apatel at ventanamicro.com/)
> > >
> > > Sunil V L (17):
> > >   arm64: PCI: Migrate ACPI related functions to pci-acpi.c
> > >   RISC-V: ACPI: Implement PCI related functionality
> > >   PCI: Make pci_create_root_bus() declare its reliance on MSI domains
> > >   ACPI: Add fw_devlink support for ACPI fwnode for IRQ dependency
> > >   ACPI: irq: Add support for deferred probe in acpi_register_gsi()
> > >   pnp.h: Reconfigure IRQ in pnp_irq() to support deferred probe
> > >   ACPI: scan.c: Add weak arch specific function to reorder the IRQCHIP
> > >     probe
> > >   ACPI: RISC-V: Implement arch function to reorder irqchip probe entries
> > >   irqchip: riscv-intc: Add ACPI support for AIA
> > >   irqchip: riscv-imsic: Add ACPI support
> > >   irqchip: riscv-aplic: Add ACPI support
> > >   irqchip: irq-sifive-plic: Add ACPI support
> > >   ACPI: bus: Add RINTC IRQ model for RISC-V
> > >   ACPI: bus: Add acpi_riscv_init function
> > >   ACPI: RISC-V: Create APLIC platform device
> > >   ACPI: RISC-V: Create PLIC platform device
> > >   irqchip: riscv-intc: Set ACPI irqmodel
> >
> > JFYI, I have no capacity to provide any feedback on this till 6.8-rc1 is out.
> >
> Hi Rafael,
>
> Gentle ping.
>
> Could you please provide feedback on the series? Patches 4, 5, 6, 7 and
> 8 are bit critical IMO. So, I really look forward for your and other
> ACPI experts!.

There was quite a bit of discussion on patch [6/21] and it still seems
relevant to me.

ACPI actually has a way to at least indicate what the probe ordering
should be which is _DEP.

The current handling of _DEP in the kernel may not be covering this
particular use case, but I would rather extend it (if necessary)
instead of doing all of the -EPROBE_DEFER dance which seems fragile to
me.

Thanks!


From conor at kernel.org  Thu Feb  1 10:15:20 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 1 Feb 2024 18:15:20 +0000
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <20240201120332.4811-5-rogerq@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-5-rogerq@kernel.org>
Message-ID: <20240201-viewpoint-upload-fb714f650ff5@spud>

On Thu, Feb 01, 2024 at 02:03:31PM +0200, Roger Quadros wrote:
> So far this was not required but due to the newly identified
> Errata i2409 [1] we need to poke this register space.
> 
> [1] https://www.ti.com/lit/er/sprz487d/sprz487d.pdf
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

> ---
> 
> Notes:
>     Changelog:
>     
>     v3 - new patch
> 
>  Documentation/devicetree/bindings/usb/ti,am62-usb.yaml | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml b/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
> index fec5651f5602..c02d9d467d9c 100644
> --- a/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
> +++ b/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
> @@ -14,7 +14,9 @@ properties:
>      const: ti,am62-usb
>  
>    reg:
> -    maxItems: 1
> +    items:
> +      - description: USB CFG register space
> +      - description: USB PHY2 register space
>  
>    ranges: true
>  
> @@ -82,7 +84,8 @@ examples:
>  
>        usbss1: usb at f910000 {
>          compatible = "ti,am62-usb";
> -        reg = <0x00 0x0f910000 0x00 0x800>;
> +        reg = <0x00 0x0f910000 0x00 0x800>,
> +              <0x00 0x0f918000 0x00 0x400>;

Why the double zeros btw?

Cheers,
Conor.

>          clocks = <&k3_clks 162 3>;
>          clock-names = "ref";
>          ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
> -- 
> 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/20240201/0aacc50e/attachment.sig>

From conor at kernel.org  Thu Feb  1 10:18:05 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 1 Feb 2024 18:18:05 +0000
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <20240201-viewpoint-upload-fb714f650ff5@spud>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-5-rogerq@kernel.org>
 <20240201-viewpoint-upload-fb714f650ff5@spud>
Message-ID: <20240201-violet-chalice-51a73f113e7b@spud>

On Thu, Feb 01, 2024 at 06:15:20PM +0000, Conor Dooley wrote:
> On Thu, Feb 01, 2024 at 02:03:31PM +0200, Roger Quadros wrote:
> > So far this was not required but due to the newly identified
> > Errata i2409 [1] we need to poke this register space.
> > 
> > [1] https://www.ti.com/lit/er/sprz487d/sprz487d.pdf
> > 
> > Signed-off-by: Roger Quadros <rogerq at kernel.org>
> 
> Acked-by: Conor Dooley <conor.dooley at microchip.com>

Actually, where is the user for this that actually pokes the register
space?
You're adding another register region, so I went to check how you were
handling that in drivers, but there's no driver patch.


> 
> > ---
> > 
> > Notes:
> >     Changelog:
> >     
> >     v3 - new patch
> > 
> >  Documentation/devicetree/bindings/usb/ti,am62-usb.yaml | 7 +++++--
> >  1 file changed, 5 insertions(+), 2 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml b/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
> > index fec5651f5602..c02d9d467d9c 100644
> > --- a/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
> > +++ b/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
> > @@ -14,7 +14,9 @@ properties:
> >      const: ti,am62-usb
> >  
> >    reg:
> > -    maxItems: 1
> > +    items:
> > +      - description: USB CFG register space
> > +      - description: USB PHY2 register space
> >  
> >    ranges: true
> >  
> > @@ -82,7 +84,8 @@ examples:
> >  
> >        usbss1: usb at f910000 {
> >          compatible = "ti,am62-usb";
> > -        reg = <0x00 0x0f910000 0x00 0x800>;
> > +        reg = <0x00 0x0f910000 0x00 0x800>,
> > +              <0x00 0x0f918000 0x00 0x400>;
> 
> Why the double zeros btw?
> 
> Cheers,
> Conor.
> 
> >          clocks = <&k3_clks 162 3>;
> >          clock-names = "ref";
> >          ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
> > -- 
> > 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/20240201/7b4faf03/attachment.sig>

From conor at kernel.org  Thu Feb  1 10:20:14 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 1 Feb 2024 18:20:14 +0000
Subject: Aw: Re:  Re: [PATCH v3 1/2] dt-bindings: reset: mediatek: add
 MT7988 reset IDs
In-Reply-To: <trinity-2aef55db-42e0-4f58-9c43-696311a96eb8-1706797383340@3c-app-gmx-bap28>
References: <20240117184111.62371-1-linux@fw-web.de>
 <20240117184111.62371-2-linux@fw-web.de>
 <20240118-calcium-krypton-3c787b8d1912@spud>
 <trinity-afc4f48e-65e1-46ee-a78b-1d670cc0f310-1705615200900@3c-app-gmx-bap21>
 <43f946cc-07e1-48c5-9b31-40fc9bc93037@collabora.com>
 <20240119-dupe-obligate-707b3a01b356@spud>
 <0EA6A126-DDC0-4E9F-BEBC-FD018B08CA84@public-files.de>
 <20240201-goes-passable-0ba841d36bc3@wendy>
 <trinity-2aef55db-42e0-4f58-9c43-696311a96eb8-1706797383340@3c-app-gmx-bap28>
Message-ID: <20240201-gutless-rising-692b7fa45f65@spud>

On Thu, Feb 01, 2024 at 03:23:03PM +0100, Frank Wunderlich wrote:
> > Gesendet: Donnerstag, 01. Februar 2024 um 14:11 Uhr
> > Von: "Conor Dooley" <conor.dooley at microchip.com>
> > I suspect I was asking for a commit message that explains why these
> > numbers don't continue in sequence. With that,
> > Acked-by: Conor Dooley <conor.dooley at microchip.com>
> >
> > Cheers,
> > Conor.
> 
> OK, i would add this to commit message:
> 
> "Value is starting again from 0 because resets are used in another driver
> than existing constants."

s/driver/device/ and sure.
-------------- 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/20240201/28c27c2e/attachment.sig>

From gregkh at linuxfoundation.org  Thu Feb  1 10:23:03 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Thu, 1 Feb 2024 10:23:03 -0800
Subject: [PATCH v2 3/3] net: phy: add Rust Rockchip PHY driver
In-Reply-To: <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
 <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>
Message-ID: <2024020105-bankroll-opium-a6e5@gregkh>

On Thu, Feb 01, 2024 at 07:07:00PM +0100, Christina Quast wrote:
> This is the Rust implementation of drivers/net/phy/rockchip.c. The
> features are equivalent. You can choose C or Rust version kernel
> configuration.
> 
> Signed-off-by: Christina Quast <contact at christina-quast.de>
Cool, but why?  Is this going to happen for all phy drivers going
forward?  What's the end-game here, dropping all .c phy drivers that are
in rust?  Or having duplicates for all of them?

thanks,

greg k-h


From linux at fw-web.de  Thu Feb  1 10:24:07 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Thu,  1 Feb 2024 19:24:07 +0100
Subject: [PATCH v4 0/2] Add reset controller to mt7988 infracfg
Message-ID: <20240201182409.39878-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Infracfg on mt7988 supports reset controller function which is
needed to get lvts thermal working.

changes:
 v4:
   - changed commit message of dt-bindings patch to include information
     about starting from 0 again suggested by Conor Dooley.
 v3:
   - start resets on RST0 offset (LVTS is RST1)
   - rename offset constants with MT7988 prefix (else collision with reset.h)
 v2:
   - change value of constant to 0 from 9
   - add missing SoB and commit-message for binding-patch


Frank Wunderlich (2):
  dt-bindings: reset: mediatek: add MT7988 infracfg reset IDs
  clk: mediatek: add infracfg reset controller for mt7988

 drivers/clk/mediatek/clk-mt7988-infracfg.c    | 23 +++++++++++++++++++
 .../reset/mediatek,mt7988-resets.h            |  6 +++++
 2 files changed, 29 insertions(+)

-- 
2.34.1



From linux at fw-web.de  Thu Feb  1 10:24:08 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Thu,  1 Feb 2024 19:24:08 +0100
Subject: [PATCH v4 1/2] dt-bindings: reset: mediatek: add MT7988 infracfg reset IDs
In-Reply-To: <20240201182409.39878-1-linux@fw-web.de>
References: <20240201182409.39878-1-linux@fw-web.de>
Message-ID: <20240201182409.39878-2-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add reset constants for using as index in driver and dts.

Value is starting again from 0 because resets are used in another device
than existing constants.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
v4:
- add info about restarting ids from 0 to commit message

v3:
- add pcie reset id as suggested by angelo

v2:
 - add missing commit message and SoB
 - change value of infrareset to 0
---
 include/dt-bindings/reset/mediatek,mt7988-resets.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/dt-bindings/reset/mediatek,mt7988-resets.h b/include/dt-bindings/reset/mediatek,mt7988-resets.h
index 493301971367..0eb152889a89 100644
--- a/include/dt-bindings/reset/mediatek,mt7988-resets.h
+++ b/include/dt-bindings/reset/mediatek,mt7988-resets.h
@@ -10,4 +10,10 @@
 /* ETHWARP resets */
 #define MT7988_ETHWARP_RST_SWITCH		0
 
+/* INFRA resets */
+#define MT7988_INFRA_RST0_PEXTP_MAC_SWRST	0
+#define MT7988_INFRA_RST1_THERM_CTRL_SWRST	1
+
+
 #endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT7988 */
+
-- 
2.34.1



From linux at fw-web.de  Thu Feb  1 10:24:09 2024
From: linux at fw-web.de (Frank Wunderlich)
Date: Thu,  1 Feb 2024 19:24:09 +0100
Subject: [PATCH v4 2/2] clk: mediatek: add infracfg reset controller for mt7988
In-Reply-To: <20240201182409.39878-1-linux@fw-web.de>
References: <20240201182409.39878-1-linux@fw-web.de>
Message-ID: <20240201182409.39878-3-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Infracfg can also operate as reset controller, add support for it.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v4: unchanged
v3:
- start with RST0 (LVTS is in RST1)
- rename reset offset to contain SOC to not collide with constants
  defined in reset.h
---
 drivers/clk/mediatek/clk-mt7988-infracfg.c | 23 ++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mt7988-infracfg.c b/drivers/clk/mediatek/clk-mt7988-infracfg.c
index 8011ef278bea..449041f8abbc 100644
--- a/drivers/clk/mediatek/clk-mt7988-infracfg.c
+++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c
@@ -14,6 +14,10 @@
 #include "clk-gate.h"
 #include "clk-mux.h"
 #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+#include <dt-bindings/reset/mediatek,mt7988-resets.h>
+
+#define	MT7988_INFRA_RST0_SET_OFFSET	0x70
+#define	MT7988_INFRA_RST1_SET_OFFSET	0x80
 
 static DEFINE_SPINLOCK(mt7988_clk_lock);
 
@@ -249,12 +253,31 @@ static const struct mtk_gate infra_clks[] = {
 	GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P3, "infra_133m_pcie_ck_p3", "sysaxi_sel", 31),
 };
 
+static u16 infra_rst_ofs[] = {
+	MT7988_INFRA_RST0_SET_OFFSET,
+	MT7988_INFRA_RST1_SET_OFFSET,
+};
+
+static u16 infra_idx_map[] = {
+	[MT7988_INFRA_RST0_PEXTP_MAC_SWRST] = 0 * RST_NR_PER_BANK + 6,
+	[MT7988_INFRA_RST1_THERM_CTRL_SWRST] = 1 * RST_NR_PER_BANK + 9,
+};
+
+static struct mtk_clk_rst_desc infra_rst_desc = {
+	.version = MTK_RST_SET_CLR,
+	.rst_bank_ofs = infra_rst_ofs,
+	.rst_bank_nr = ARRAY_SIZE(infra_rst_ofs),
+	.rst_idx_map = infra_idx_map,
+	.rst_idx_map_nr = ARRAY_SIZE(infra_idx_map),
+};
+
 static const struct mtk_clk_desc infra_desc = {
 	.clks = infra_clks,
 	.num_clks = ARRAY_SIZE(infra_clks),
 	.mux_clks = infra_muxes,
 	.num_mux_clks = ARRAY_SIZE(infra_muxes),
 	.clk_lock = &mt7988_clk_lock,
+	.rst_desc = &infra_rst_desc,
 };
 
 static const struct of_device_id of_match_clk_mt7988_infracfg[] = {
-- 
2.34.1



From semen.protsenko at linaro.org  Thu Feb  1 10:24:25 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 1 Feb 2024 12:24:25 -0600
Subject: (subset) [PATCH v2 3/3] arm64: dts: exynos: Add SPI nodes for Exynos850
In-Reply-To: <4c2c425b-3ddd-4484-98cf-3f7768c94e82@linaro.org>
References: <20240125013858.3986-1-semen.protsenko@linaro.org>
 <20240125013858.3986-4-semen.protsenko@linaro.org> <170678377409.179918.13077326172475089482.b4-ty@linaro.org>
 <4c2c425b-3ddd-4484-98cf-3f7768c94e82@linaro.org>
Message-ID: <CAPLW+4=wsR=V+6vctf0gMzFVg6havL-M0kTDLLwhr-XdfuCD5Q@mail.gmail.com>

On Thu, Feb 1, 2024 at 5:56?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 01/02/2024 11:36, Krzysztof Kozlowski wrote:
> >
> > On Wed, 24 Jan 2024 19:38:58 -0600, Sam Protsenko wrote:
> >> Some USI blocks can be configured as SPI controllers. Add corresponding
> >> SPI nodes to Exynos850 SoC device tree.
> >>
> >>
> >
> > Applied, thanks!
> >
> > [3/3] arm64: dts: exynos: Add SPI nodes for Exynos850
> >       https://git.kernel.org/krzk/linux/c/98473b0d78caa5502b7eee05553ee168f0b0b424
>
> And dropped. You did not test it.
>

Right. Forgot to re-test it after re-shuffling the clocks. Sorry for
the hustle, I'll send v3 shortly.

> For some time, all Samsung SoCs and its variants are expected not to
> introduce any new `dtbs_check W=1` warnings. Several platforms, like all
> ARM64 Samsung SoCs, have already zero warnings, thus for such platforms
> it is extra easy for the submitter to validate DTS before posting a
> patch. The patch briefly looks like it is not conforming to this rule.
> Please confirm that you tested your patch and it does not introduce any
> new warnings (linux-next is decisive here).
>
> Best regards,
> Krzysztof
>


From charles.perry at savoirfairelinux.com  Thu Feb  1 10:24:52 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Thu, 1 Feb 2024 13:24:52 -0500 (EST)
Subject: [PATCH 2/3] dt-bindings: fpga: xlnx,fpga-slave-selectmap: add
 DT schema
In-Reply-To: <d5fe1ec2-b647-4902-a599-fb866e96e9cf@linaro.org>
References: <20240129225602.3832449-1-charles.perry@savoirfairelinux.com> <20240131230542.3993409-1-charles.perry@savoirfairelinux.com> <20240131230542.3993409-3-charles.perry@savoirfairelinux.com> <d5fe1ec2-b647-4902-a599-fb866e96e9cf@linaro.org>
Message-ID: <1391244934.434321.1706811892834.JavaMail.zimbra@savoirfairelinux.com>



----- On Feb 1, 2024, at 3:07 AM, Krzysztof Kozlowski krzysztof.kozlowski at linaro.org wrote:

> On 01/02/2024 00:05, Charles Perry wrote:
>> Document the slave SelectMAP interface of Xilinx 7 series FPGA.
>> 
>> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
>> ---
>>  .../bindings/fpga/xlnx,fpga-selectmap.yaml    | 83 +++++++++++++++++++
>>  1 file changed, 83 insertions(+)
>>  create mode 100644
>>  Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>> 
>> diff --git a/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>> b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>> new file mode 100644
>> index 0000000000000..c9a446b43cdd9
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>> @@ -0,0 +1,83 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/fpga/xlnx,fpga-selectmap.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Xilinx SelectMAP FPGA interface
>> +
>> +maintainers:
>> +  - Charles Perry <charles.perry at savoirfairelinux.com>
>> +
>> +description: |
>> +  Xilinx 7 Series FPGAs support a method of loading the bitstream over a
>> +  parallel port named the SelectMAP interface in the documentation. Only
>> +  the x8 mode is supported where data is loaded at one byte per rising edge of
>> +  the clock, with the MSB of each byte presented to the D0 pin.
>> +
>> +  Datasheets:
>> +
>> https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf
>> +
>> +allOf:
>> +  - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - xlnx,fpga-selectmap
> 
> Your description mentions "7 Series" which is not present in compatible
> and title. What is exactly the product here? Interface usually is not
> the final binding, so is this specific to some particular FPGA or SoC?
> 
> 
> Best regards,
> Krzysztof

This is specific to the FPGA, the 7 series encompass the following part
family:
 * Spartan-7 (XC7S6, XC7S15, ... XC7S100)
 * Artix-7 (XC7A12T, XC7A15T, ... XC7A200T)
 * Kintex-7 (XC7K70T, XC7K160T, ... XC7K480T)
 * Virtex-7 (XC7V585T, XC7V2000T, 
             XC7VX330T, XC7VX415T, ... XC7VX1140T,
             XC7VH580T, XC7VH870T)


The configuration guide of Xilinx [1] tells us that all those devices
share a common programming scheme.

I do agree that having a mention of "7 series" in the compatible name
would be beneficial as Xilinx has more FPGA than just the 7 series.
The name was inspired from "xlnx,fpga-slave-serial" which is the compatible
for the serial interface.

What about "xlnx,fpga-xc7-selectmap" ?

I'm also seeing that I missed some mention of the "slave" word in the
commit message, will fix.

Regards,
Charles

[1] https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf




From semen.protsenko at linaro.org  Thu Feb  1 10:30:25 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu,  1 Feb 2024 12:30:25 -0600
Subject: [PATCH v3] arm64: dts: exynos: Add SPI nodes for Exynos850
Message-ID: <20240201183025.14566-1-semen.protsenko@linaro.org>

Some USI blocks can be configured as SPI controllers. Add corresponding
SPI nodes to Exynos850 SoC device tree.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>
Link: https://lore.kernel.org/r/20240125013858.3986-4-semen.protsenko at linaro.org
[krzysztof: order properties according to DTS coding style]
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
Changes in v3:
  - Fix dtschema warnings by specifying "spi" as a first clock

Changes in v2:
  - Sorted pinctrl properties properly

 arch/arm64/boot/dts/exynos/exynos850.dtsi | 54 +++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
index e7e1171a3864..2ba67c3d0681 100644
--- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -738,6 +738,24 @@ usi_spi_0: usi at 139400c0 {
 				 <&cmu_peri CLK_GOUT_SPI0_IPCLK>;
 			clock-names = "pclk", "ipclk";
 			status = "disabled";
+
+			spi_0: spi at 13940000 {
+				compatible = "samsung,exynos850-spi";
+				reg = <0x13940000 0x30>;
+				clocks = <&cmu_peri CLK_GOUT_SPI0_PCLK>,
+					 <&cmu_peri CLK_GOUT_SPI0_IPCLK>;
+				clock-names = "spi", "spi_busclk0";
+				dmas = <&pdma0 5>, <&pdma0 4>;
+				dma-names = "tx", "rx";
+				interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+				pinctrl-0 = <&spi0_pins>;
+				pinctrl-names = "default";
+				num-cs = <1>;
+				samsung,spi-src-clk = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
 		};
 
 		usi_cmgp0: usi at 11d000c0 {
@@ -779,6 +797,24 @@ serial_1: serial at 11d00000 {
 				clock-names = "uart", "clk_uart_baud0";
 				status = "disabled";
 			};
+
+			spi_1: spi at 11d00000 {
+				compatible = "samsung,exynos850-spi";
+				reg = <0x11d00000 0x30>;
+				clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI0_PCLK>,
+					 <&cmu_cmgp CLK_GOUT_CMGP_USI0_IPCLK>;
+				clock-names = "spi", "spi_busclk0";
+				dmas = <&pdma0 12>, <&pdma0 13>;
+				dma-names = "tx", "rx";
+				interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+				pinctrl-0 = <&spi1_pins>;
+				pinctrl-names = "default";
+				num-cs = <1>;
+				samsung,spi-src-clk = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
 		};
 
 		usi_cmgp1: usi at 11d200c0 {
@@ -820,6 +856,24 @@ serial_2: serial at 11d20000 {
 				clock-names = "uart", "clk_uart_baud0";
 				status = "disabled";
 			};
+
+			spi_2: spi at 11d20000 {
+				compatible = "samsung,exynos850-spi";
+				reg = <0x11d20000 0x30>;
+				clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI1_PCLK>,
+					 <&cmu_cmgp CLK_GOUT_CMGP_USI1_IPCLK>;
+				clock-names = "spi", "spi_busclk0";
+				dmas = <&pdma0 14>, <&pdma0 15>;
+				dma-names = "tx", "rx";
+				interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+				pinctrl-0 = <&spi2_pins>;
+				pinctrl-names = "default";
+				num-cs = <1>;
+				samsung,spi-src-clk = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
 		};
 	};
 };
-- 
2.39.2



From arnaud.pouliquen at foss.st.com  Thu Feb  1 10:33:35 2024
From: arnaud.pouliquen at foss.st.com (Arnaud POULIQUEN)
Date: Thu, 1 Feb 2024 19:33:35 +0100
Subject: [PATCH v2 4/4] remoteproc: stm32: Add support of an OP-TEE TA to
 load the firmware
In-Reply-To: <ZbvAmxHscnbUQGOD@p14s>
References: <20240118100433.3984196-1-arnaud.pouliquen@foss.st.com>
 <20240118100433.3984196-5-arnaud.pouliquen@foss.st.com>
 <ZbPnsJm67G10+HQ3@p14s> <7ec6c9e8-9267-4e7c-81a4-abcdb2ab4239@foss.st.com>
 <ZbqW5YfDmEWG4G1X@p14s> <8ede77bb-0fbc-4de2-b51b-67674744b551@foss.st.com>
 <ZbvAmxHscnbUQGOD@p14s>
Message-ID: <a52e00c5-fb60-4a9e-85ff-0f9649850f48@foss.st.com>



On 2/1/24 17:02, Mathieu Poirier wrote:
> On Thu, Feb 01, 2024 at 04:06:37PM +0100, Arnaud POULIQUEN wrote:
>> hello Mathieu,
>>
>> On 1/31/24 19:52, Mathieu Poirier wrote:
>>> On Tue, Jan 30, 2024 at 10:13:48AM +0100, Arnaud POULIQUEN wrote:
>>>>
>>>>
>>>> On 1/26/24 18:11, Mathieu Poirier wrote:
>>>>> On Thu, Jan 18, 2024 at 11:04:33AM +0100, Arnaud Pouliquen wrote:
>>>>>> The new TEE remoteproc device is used to manage remote firmware in a
>>>>>> secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
>>>>>> introduced to delegate the loading of the firmware to the trusted
>>>>>> execution context. In such cases, the firmware should be signed and
>>>>>> adhere to the image format defined by the TEE.
>>>>>>
>>>>>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
>>>>>> ---
>>>>>> V1 to V2 update:
>>>>>> - remove the select "TEE_REMOTEPROC" in STM32_RPROC config as detected by
>>>>>>   the kernel test robot:
>>>>>>      WARNING: unmet direct dependencies detected for TEE_REMOTEPROC
>>>>>>      Depends on [n]: REMOTEPROC [=y] && OPTEE [=n]
>>>>>>      Selected by [y]:
>>>>>>      - STM32_RPROC [=y] && (ARCH_STM32 || COMPILE_TEST [=y]) && REMOTEPROC [=y]
>>>>>> - Fix initialized trproc variable in  stm32_rproc_probe
>>>>>> ---
>>>>>>  drivers/remoteproc/stm32_rproc.c | 149 +++++++++++++++++++++++++++++--
>>>>>>  1 file changed, 144 insertions(+), 5 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
>>>>>> index fcc0001e2657..cf6a21bac945 100644
>>>>>> --- a/drivers/remoteproc/stm32_rproc.c
>>>>>> +++ b/drivers/remoteproc/stm32_rproc.c
>>>>>> @@ -20,6 +20,7 @@
>>>>>>  #include <linux/remoteproc.h>
>>>>>>  #include <linux/reset.h>
>>>>>>  #include <linux/slab.h>
>>>>>> +#include <linux/tee_remoteproc.h>
>>>>>>  #include <linux/workqueue.h>
>>>>>>  
>>>>>>  #include "remoteproc_internal.h"
>>>>>> @@ -49,6 +50,9 @@
>>>>>>  #define M4_STATE_STANDBY	4
>>>>>>  #define M4_STATE_CRASH		5
>>>>>>  
>>>>>> +/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
>>>>>> +#define STM32_MP1_M4_PROC_ID    0
>>>>>> +
>>>>>>  struct stm32_syscon {
>>>>>>  	struct regmap *map;
>>>>>>  	u32 reg;
>>>>>> @@ -90,6 +94,8 @@ struct stm32_rproc {
>>>>>>  	struct stm32_mbox mb[MBOX_NB_MBX];
>>>>>>  	struct workqueue_struct *workqueue;
>>>>>>  	bool hold_boot_smc;
>>>>>> +	bool fw_loaded;
>>>>>> +	struct tee_rproc *trproc;
>>>>>>  	void __iomem *rsc_va;
>>>>>>  };
>>>>>>  
>>>>>> @@ -257,6 +263,91 @@ static int stm32_rproc_release(struct rproc *rproc)
>>>>>>  	return err;
>>>>>>  }
>>>>>>  
>>>>>> +static int stm32_rproc_tee_elf_sanity_check(struct rproc *rproc,
>>>>>> +					    const struct firmware *fw)
>>>>>> +{
>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>> +	unsigned int ret = 0;
>>>>>> +
>>>>>> +	if (rproc->state == RPROC_DETACHED)
>>>>>> +		return 0;
>>>>>> +
>>>>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
>>>>>> +	if (!ret)
>>>>>> +		ddata->fw_loaded = true;
>>>>>> +
>>>>>> +	return ret;
>>>>>> +}
>>>>>> +
>>>>>> +static int stm32_rproc_tee_elf_load(struct rproc *rproc,
>>>>>> +				    const struct firmware *fw)
>>>>>> +{
>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>> +	unsigned int ret;
>>>>>> +
>>>>>> +	/*
>>>>>> +	 * This function can be called by remote proc for recovery
>>>>>> +	 * without the sanity check. In this case we need to load the firmware
>>>>>> +	 * else nothing done here as the firmware has been preloaded for the
>>>>>> +	 * sanity check to be able to parse it for the resource table.
>>>>>> +	 */
>>>>>
>>>>> This comment is very confusing - please consider refactoring.  
>>>>>
>>>>>> +	if (ddata->fw_loaded)
>>>>>> +		return 0;
>>>>>> +
>>>>>
>>>>> I'm not sure about keeping a flag to indicate the status of the loaded firmware.
>>>>> It is not done for the non-secure method, I don't see why it would be needed for
>>>>> the secure one.
>>>>>
>>>>
>>>> The difference is on the sanity check.
>>>> - in rproc_elf_sanity_check we  parse the elf file to verify that it is
>>>> valid.
>>>> - in stm32_rproc_tee_elf_sanity_check we have to do the same, that means to
>>>> authenticate it. the authentication is done during the load.
>>>>
>>>> So this flag is used to avoid to reload it twice time.
>>>> refactoring the comment should help to understand this flag
>>>>
>>>>
>>>> An alternative would be to bypass the sanity check. But this lead to same
>>>> limitation.
>>>> Before loading the firmware in remoteproc_core, we call rproc_parse_fw() that is
>>>> used to get the resource table address. To get it from tee we need to
>>>> authenticate the firmware so load it...
>>>>
>>>
>>> I spent a long time thinking about this patchset.  Looking at the code as it
>>> is now, request_firmware() in rproc_boot() is called even when the TEE is
>>> responsible for loading the firmware.  There should be some conditional code
>>> that calls either request_firmware() or tee_rproc_load_fw().  The latter should
>>> also be renamed to tee_rproc_request_firmware() to avoid confusion.
>>
>>
>> The request_firmware() call is needed in both cases to get the image from the
>> filesystem. The tee_rproc_load_fw() gets, as input, the struct firmware provided
>> by request_firmware().
> 
> The cover letter clearly state the secure side is responsible for loading the
> firmware image but here you're telling me it has to be loaded twice.  This is
> very confusing.

Concerning the call of request_firmware()

By "both cases" I would say that the call of request_firmware() is needed in
both modes:
- the ELF firmware is parsed and loaded by linux (legacy)
- the binary firmware is parsed and loaded by OP-TEE.

The Op-TEE is not able to get the firmware image from the file system.


Concerning the call of tee_rproc_load_fw twice time

There are 2 use cases:

- First boot of the remote processor:

  1) The Linux rproc gets the binary firmware image from the file system by
     calling  request_firmware(). A copy is stored in memory.
  2) the linux performs a sanity check on the firmware calling
     rproc_fw_sanity_check()
	=> from OP-TEE point of view this means to autenticate the firmware
	=> let consider in this exemple that we bypass this step
           (ops->sanity_check = NULL)
		
  3) the linux rproc call rproc_parse_fw() to get the resource table
	=> From OP-TEE point of view the resource table is available only when
           the firmware is loaded
	=> We need to call tee_rproc_load_fw() to be able then to get the
           address of the resource table.
  4) The Linux rproc calls rproc_handle_resources() to parse the resource table.
  5) The linux rproc calls rproc_start()
	- load the firrmware calling rproc_load_segments()
		=> we don't want to call tee_rproc_load_fw() it a second time
	- start the firmware calling ops->start()

- Reboot on crash recovery using rproc_boot_recovery()

  1)  The Linux rproc gets the binary firmware image from the file system by
     calling request_firmware(). A copy is stored in memory.
  5) The linux rproc calls rproc_start()
	- load the firrmware calling rproc_load_segments()
		=> we have to call tee_rproc_load_fw() to reload the firmware
	- start the firmware calling ops->start()

In first use case we have to load the firmware on rproc_parse_fw(), in second
usecase on rproc_load_segments().

This is the point I have tried to solve with the ddata->fw_loaded variable.

> 
> I'm also confused as to why stm32_rproc_tee_elf_sanity_check() is calling
> tee_rproc_load_fw().  There should be one call to load the firmware and another
> to perform a sanity check on it.  If the sanity check is done at load time by
> the secure world then ops::sanity_check() is NULL.

Sure, make sense to remove the sanity_check ops

Thanks,
Arnaud

> 
> Most of what this patchset does makes sense, but some of it needs to be moved
> around.  
> 
> Thanks,
> Mathieu
> 
>>
>> If we want to integrate in remoteproc_core the solution could probably have to
>> create the equivalent of the rproc_fw_boot() to load the firmware with an
>> external method. Here is an example based on a new rproc_ops ( not tested)
>>
>> + static int rproc_fw_ext_boot(struct rproc *rproc, const struct firmware *fw)
>> + {
>> + 	struct device *dev = &rproc->dev;
>> + 	const char *name = rproc->firmware;
>> + 	int ret;
>> +
>> +
>> + 	dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size);
>> + 	
>> + 	/* ops to load and start the remoteprocessor */
>> + 	ret = rproc->ops->boot(rproc, fw);
>> + 	if (ret)
>> + 		return ret;
>> +
>> + 	/*
>> + 	 * if enabling an IOMMU isn't relevant for this rproc, this is
>> + 	 * just a nop
>> + 	 */
>> + 	ret = rproc_enable_iommu(rproc);
>> + 	if (ret) {
>> + 		dev_err(dev, "can't enable iommu: %d\n", ret);
>> + 		return ret;
>> + 	}
>> +
>> + 	/* Prepare rproc for firmware loading if needed */
>> + 	ret = rproc_prepare_device(rproc);
>> + 	if (ret) {
>> + 		dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
>> + 		goto disable_iommu;
>> + 	}
>> +
>> + 	ret = rproc_set_rsc_table(rproc);
>> + 	if (ret) {
>> + 		dev_err(dev, "can't load resource table: %d\n", ret);
>> + 		goto unprepare_device;
>> + 	}
>> +
>> +
>> + 	/* reset max_notifyid */
>> + 	rproc->max_notifyid = -1;
>> +
>> + 	/* reset handled vdev */
>> + 	rproc->nb_vdev = 0;
>> +
>> + 	/* handle fw resources which are required to boot rproc */
>> + 	ret = rproc_handle_resources(rproc, rproc_loading_handlers);
>> + 	if (ret) {
>> + 		dev_err(dev, "Failed to process resources: %d\n", ret);
>> + 		goto clean_up_resources;
>> + 	}
>> +
>> + 	/* Allocate carveout resources associated to rproc */
>> + 	ret = rproc_alloc_registered_carveouts(rproc);
>> + 	if (ret) {
>> + 		dev_err(dev, "Failed to allocate associated carveouts: %d\n",
>> + 			ret);
>> + 		goto clean_up_resources;
>> + 	}
>> +
>> + 	return 0;
>> +
>> + clean_up_resources:
>> + 	rproc_resource_cleanup(rproc);
>> + unprepare_rproc:
>> + 	/* release HW resources if needed */
>> + 	rproc_unprepare_device(rproc);
>> + disable_iommu:
>> + 	rproc_disable_iommu(rproc);
>> + 	return ret;
>> + }
>>
>>
>> int rproc_boot(struct rproc *rproc)
>> {
>> [...]
>>
>> - 		ret = rproc_fw_boot(rproc, firmware_p);
>> + 		if(rproc->ops->boot)
>> + 			ret = rproc_fw_ext_boot(rproc, firmware_p);
>> + 		else
>> + 			ret = rproc_fw_boot(rproc, firmware_p);
>>
>> Another advantage of this solution is that it opens the framework to other
>> formats. For instance it could be a way to support dtb format requested in [RFC]
>> Passing device-tree to remoteproc [1].
>>
>> [1]
>> https://lore.kernel.org/linux-remoteproc/f67cd822-4e29-71f2-7c42-e11dbaa6cd8c at kalrayinc.com/T/#t
>>
>> Thanks,
>> Arnaud
>>
>>
>>
>>>
>>> I touched on that before but please rename rproc_tee_get_rsc_table() to
>>> rproc_tee_elf_load_rsc_table().  I also suggest to introduce a new function,
>>> rproc_tee_get_loaded_rsc_table() that would be called from
>>> rproc_tee_elf_load_rsc_table().  That way we don't need trproc->rsc_va.  
>>>
>>> I also think tee_rproc should be renamed to "rproc_tee_interface" and folded
>>> under struct rproc.  
>>>
>>> With the above most of the problems with the current implementation should
>>> naturally go away.
>>>
>>> Thanks,
>>> Mathieu
>>>
>>>>
>>>>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
>>>>>> +	if (ret)
>>>>>> +		return ret;
>>>>>> +	ddata->fw_loaded = true;
>>>>>> +
>>>>>> +	/* Update the resource table parameters. */
>>>>>> +	if (rproc_tee_get_rsc_table(ddata->trproc)) {
>>>>>> +		/* No resource table: reset the related fields. */
>>>>>> +		rproc->cached_table = NULL;
>>>>>> +		rproc->table_ptr = NULL;
>>>>>> +		rproc->table_sz = 0;
>>>>>> +	}
>>>>>> +
>>>>>> +	return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static struct resource_table *
>>>>>> +stm32_rproc_tee_elf_find_loaded_rsc_table(struct rproc *rproc,
>>>>>> +					  const struct firmware *fw)
>>>>>> +{
>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>> +
>>>>>> +	return tee_rproc_get_loaded_rsc_table(ddata->trproc);
>>>>>> +}
>>>>>> +
>>>>>> +static int stm32_rproc_tee_start(struct rproc *rproc)
>>>>>> +{
>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>> +
>>>>>> +	return tee_rproc_start(ddata->trproc);
>>>>>> +}
>>>>>> +
>>>>>> +static int stm32_rproc_tee_attach(struct rproc *rproc)
>>>>>> +{
>>>>>> +	/* Nothing to do, remote proc already started by the secured context. */
>>>>>> +	return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static int stm32_rproc_tee_stop(struct rproc *rproc)
>>>>>> +{
>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>> +	int err;
>>>>>> +
>>>>>> +	stm32_rproc_request_shutdown(rproc);
>>>>>> +
>>>>>> +	err = tee_rproc_stop(ddata->trproc);
>>>>>> +	if (err)
>>>>>> +		return err;
>>>>>> +
>>>>>> +	ddata->fw_loaded = false;
>>>>>> +
>>>>>> +	return stm32_rproc_release(rproc);
>>>>>> +}
>>>>>> +
>>>>>>  static int stm32_rproc_prepare(struct rproc *rproc)
>>>>>>  {
>>>>>>  	struct device *dev = rproc->dev.parent;
>>>>>> @@ -319,7 +410,14 @@ static int stm32_rproc_prepare(struct rproc *rproc)
>>>>>>  
>>>>>>  static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
>>>>>>  {
>>>>>> -	if (rproc_elf_load_rsc_table(rproc, fw))
>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>> +	int ret;
>>>>>> +
>>>>>> +	if (ddata->trproc)
>>>>>> +		ret = rproc_tee_get_rsc_table(ddata->trproc);
>>>>>> +	else
>>>>>> +		ret = rproc_elf_load_rsc_table(rproc, fw);
>>>>>> +	if (ret)
>>>>>>  		dev_warn(&rproc->dev, "no resource table found for this firmware\n");
>>>>>>  
>>>>>>  	return 0;
>>>>>> @@ -693,8 +791,22 @@ static const struct rproc_ops st_rproc_ops = {
>>>>>>  	.get_boot_addr	= rproc_elf_get_boot_addr,
>>>>>>  };
>>>>>>  
>>>>>> +static const struct rproc_ops st_rproc_tee_ops = {
>>>>>> +	.prepare	= stm32_rproc_prepare,
>>>>>> +	.start		= stm32_rproc_tee_start,
>>>>>> +	.stop		= stm32_rproc_tee_stop,
>>>>>> +	.attach		= stm32_rproc_tee_attach,
>>>>>> +	.kick		= stm32_rproc_kick,
>>>>>> +	.parse_fw	= stm32_rproc_parse_fw,
>>>>>> +	.find_loaded_rsc_table = stm32_rproc_tee_elf_find_loaded_rsc_table,
>>>>>> +	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
>>>>>> +	.sanity_check	= stm32_rproc_tee_elf_sanity_check,
>>>>>> +	.load		= stm32_rproc_tee_elf_load,
>>>>>> +};
>>>>>> +
>>>>>>  static const struct of_device_id stm32_rproc_match[] = {
>>>>>> -	{ .compatible = "st,stm32mp1-m4" },
>>>>>> +	{.compatible = "st,stm32mp1-m4",},
>>>>>> +	{.compatible = "st,stm32mp1-m4-tee",},
>>>>>>  	{},
>>>>>>  };
>>>>>>  MODULE_DEVICE_TABLE(of, stm32_rproc_match);
>>>>>> @@ -853,6 +965,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>>>  	struct device *dev = &pdev->dev;
>>>>>>  	struct stm32_rproc *ddata;
>>>>>>  	struct device_node *np = dev->of_node;
>>>>>> +	struct tee_rproc *trproc = NULL;
>>>>>>  	struct rproc *rproc;
>>>>>>  	unsigned int state;
>>>>>>  	int ret;
>>>>>> @@ -861,11 +974,31 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>>>  	if (ret)
>>>>>>  		return ret;
>>>>>>  
>>>>>> -	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
>>>>>> -	if (!rproc)
>>>>>> -		return -ENOMEM;
>>>>>> +	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
>>>>>> +		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
>>>>>> +		if (IS_ERR(trproc)) {
>>>>>> +			dev_err_probe(dev, PTR_ERR(trproc),
>>>>>> +				      "signed firmware not supported by TEE\n");
>>>>>> +			return PTR_ERR(trproc);
>>>>>> +		}
>>>>>> +		/*
>>>>>> +		 * Delegate the firmware management to the secure context.
>>>>>> +		 * The firmware loaded has to be signed.
>>>>>> +		 */
>>>>>> +		dev_info(dev, "Support of signed firmware only\n");
>>>>>
>>>>> Not sure what this adds.  Please remove.
>>>>
>>>> This is used to inform the user that only a signed firmware can be loaded, not
>>>> an ELF file.
>>>> I have a patch in my pipe to provide the supported format in the debugfs. In a
>>>> first step, I can suppress this message and we can revisit the issue when I push
>>>> the debugfs proposal.
>>>>
>>>> Thanks,
>>>> Arnaud
>>>>
>>>>>
>>>>>> +	}
>>>>>> +	rproc = rproc_alloc(dev, np->name,
>>>>>> +			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
>>>>>> +			    NULL, sizeof(*ddata));
>>>>>> +	if (!rproc) {
>>>>>> +		ret = -ENOMEM;
>>>>>> +		goto free_tee;
>>>>>> +	}
>>>>>>  
>>>>>>  	ddata = rproc->priv;
>>>>>> +	ddata->trproc = trproc;
>>>>>> +	if (trproc)
>>>>>> +		trproc->rproc = rproc;
>>>>>>  
>>>>>>  	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
>>>>>>  
>>>>>> @@ -916,6 +1049,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>>>  		device_init_wakeup(dev, false);
>>>>>>  	}
>>>>>>  	rproc_free(rproc);
>>>>>> +free_tee:
>>>>>> +	if (trproc)
>>>>>> +		tee_rproc_unregister(trproc);
>>>>>> +
>>>>>>  	return ret;
>>>>>>  }
>>>>>>  
>>>>>> @@ -937,6 +1074,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
>>>>>>  		device_init_wakeup(dev, false);
>>>>>>  	}
>>>>>>  	rproc_free(rproc);
>>>>>> +	if (ddata->trproc)
>>>>>> +		tee_rproc_unregister(ddata->trproc);
>>>>>>  }
>>>>>>  
>>>>>>  static int stm32_rproc_suspend(struct device *dev)
>>>>>> -- 
>>>>>> 2.25.1
>>>>>>


From miguel.ojeda.sandonis at gmail.com  Thu Feb  1 10:34:08 2024
From: miguel.ojeda.sandonis at gmail.com (Miguel Ojeda)
Date: Thu, 1 Feb 2024 19:34:08 +0100
Subject: [PATCH v2 1/3] DONOTMERGE: rust: prelude: add bit function
In-Reply-To: <20240201-rockchip-rust-phy_depend-v2-1-c5fa4faab924@christina-quast.de>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
 <20240201-rockchip-rust-phy_depend-v2-1-c5fa4faab924@christina-quast.de>
Message-ID: <CANiq72nE6vy3dy3VTUkdKb3Vep72jxvHb=Jd2ykue8Nd1Vk-jg@mail.gmail.com>

On Thu, Feb 1, 2024 at 7:07?PM Christina Quast
<contact at christina-quast.de> wrote:
>
> In order to create masks easily, the define BIT() is used in C code.
> This commit adds the same functionality to the rust kernel.

Note that it is the same kernel :) Typically we would say "to the Rust
side" or similar.

> Do not merge this commit, because rust/kernel/types.rs in Rust-for-Linux
> already contains this functionality and will be merged into next-net
> soon.

I think you mean the archived `rust` branch (it is useful to point
this out -- Rust for Linux is not just that branch).

However, has the `Bit` type (assuming you mean that) been submitted? I
don't recall seeing it, and normally something like that would not go
through `net-next`. If it has been, could you please send the Lore
link?

> But this driver does not compile without this commit, so I am adding it
> to the patchset to get more feedback on the actual driver.

Assuming the patch was not sent, I would suggest replacing this commit
with the dependency you want to use, e.g. the `Bit` type, since it is
a small enough one.

In addition, this series has v2 in the title -- I think you did that
because this patch was already submitted, but this is not really a v2
of that series since this is mainly about the driver (and anyway this
patch in particular is not meant to be merged; plus you didn't change
it from what I can see).

Thanks!

Cheers,
Miguel


From afd at ti.com  Thu Feb  1 10:34:56 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 12:34:56 -0600
Subject: [PATCH v3 1/6] arm64: dts: ti: k3-j784s4: Add Wave5 Video
 Encoder/Decoder Node
In-Reply-To: <20240131212625.1862775-2-b-brnich@ti.com>
References: <20240131212625.1862775-1-b-brnich@ti.com>
 <20240131212625.1862775-2-b-brnich@ti.com>
Message-ID: <a5f0059d-b80f-44e6-8c1e-793054586e0a@ti.com>

On 1/31/24 3:26 PM, Brandon Brnich wrote:
> This patch adds support for the Wave521cl on the J784S4-evm.
> 
> Signed-off-by: Brandon Brnich <b-brnich at ti.com>
> ---
>   arch/arm64/boot/dts/ti/k3-j784s4-evm.dts   |  8 ++++++++
>   arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 20 ++++++++++++++++++++
>   arch/arm64/boot/dts/ti/k3-j784s4.dtsi      |  2 ++
>   3 files changed, 30 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
> index f34b92acc56d..7d37c11b4df4 100644
> --- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
> +++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
> @@ -784,6 +784,14 @@ &main_gpio0 {
>   	status = "okay";
>   };
>   
> +&vpu0 {
> +	status = "okay";
> +};
> +
> +&vpu1 {
> +	status = "okay";
> +};
> +
>   &mcu_cpsw {
>   	status = "okay";
>   	pinctrl-names = "default";
> diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> index f2b720ed1e4f..8b2623ac8160 100644
> --- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> @@ -662,6 +662,26 @@ main_i2c6: i2c at 2060000 {
>   		status = "disabled";
>   	};
>   
> +	vpu0: video-codec at 4210000 {
> +		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
> +		reg = <0x00 0x4210000 0x00 0x10000>;
> +		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&k3_clks 241 2>;
> +		clock-names = "vcodec";
> +		power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";

Why are these default disabled? I don't see anything missing that
would need to be added at the board level. You disable them
just to re-enable them in the next patch. Leave these default
enabled.

> +	};
> +
> +	vpu1: video-codec at 4220000 {
> +		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
> +		reg = <0x00 0x4220000 0x00 0x10000>;
> +		interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&k3_clks 242 2>;
> +		clock-names = "vcodec";
> +		power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
> +	};
> +
>   	main_sdhci0: mmc at 4f80000 {
>   		compatible = "ti,j721e-sdhci-8bit";
>   		reg = <0x00 0x04f80000 0x00 0x1000>,
> diff --git a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
> index 4398c3a463e1..93bb0cba1b48 100644
> --- a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
> @@ -247,6 +247,8 @@ cbass_main: bus at 100000 {
>   			 <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>, /* MAIN NAVSS */
>   			 <0x41 0x00000000 0x41 0x00000000 0x01 0x00000000>, /* PCIe1 DAT1 */
>   			 <0x4e 0x20000000 0x4e 0x20000000 0x00 0x00080000>, /* GPU */
> +			 <0x00 0x04210000 0x00 0x04210000 0x00 0x00010000>, /* VPU0 */
> +			 <0x00 0x04220000 0x00 0x04220000 0x00 0x00010000>, /* VPU1 */

Add these in sorted by memory address order.

Andrew

>   
>   			 /* MCUSS_WKUP Range */
>   			 <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>,


From rafael at kernel.org  Thu Feb  1 10:35:07 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 1 Feb 2024 19:35:07 +0100
Subject: [PATCH v1 00/18] Thermal: Part 1 - Introduce new structs and registration
In-Reply-To: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
Message-ID: <CAJZ5v0haFEGOjaMC4a8CZbQe+cxFfaB1hD60NkN297NY2TZB5A@mail.gmail.com>

On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> This series is a preparation for a bigger cleanup that will be split in
> three parts in order to avoid immutable branches on multiple subsystems,
> as in other parts of this series there will be changes in:
> - drivers/acpi
> - drivers/platform/x86
> - drivers/power/supply
> - drivers/net/wireless
> - drivers/net/ethernet
>
> This is the first part which adds new structures and starts reorganizing
> struct members around, plus, this migrates all of the thermal drivers
> found in drivers/thermal/ to the new thermal_zone_device_register()
> function, and advertises that the old registration functions are
> deprecated and will be removed.
>
> The reorganization is supposed to be complete (or mostly) but...
>  - struct thermal_zone_platform_params has a temporary name:
>    this is done in order to avoid compile time failures for
>    the drivers outside of drivers/thermal before migrating
>    them to thermal_zone_device_params/thermal_zone_device_register();
>  - struct thermal_zone_params temporarily has two duplicated members,
>    governor_name and no_hwmon;
>
> Part 2 of this topic will migrate all drivers that are external to
> drivers/thermal to thermal_zone_device_register(); I will send that
> part only after part 1 is confirmed to be acceptable, as otherwise
> I'd be spamming people for no reason :-)
>
> After all drivers will be migrated to thermal_zone_device_register(),
> we won't have to care about changing anything outside of drivers/thermal
> to finish this set of cleanups/changes (and no immutable branches needed)
> and this means that...
> Part 3 of this topic will contain the following changes:
>  - thermal_zone_device_register_with_trips() will be removed
>  - thermal_tripless_zone_device_register() will be removed
>  - thermal_zone_params will be renamed to thermal_governor_ipa_params
>    - governor_name, no_hwmon members will be removed
>  - thermal_zone_platform_params will be renamed to thermal_zone_params
>  - Removal of the THERMAL_NAME_LENGTH limitation for `type`
>
> More scheduled changes, which should end up in part 3 (at least that's
> my intention), or eventually entirely after this cleanup topic, include:
>  - Introduction of Thermal Zone names
>  - Disambiguation of TZ name and type
>  - Addition of `thermal-zones`, `thermal-zone-names` parsing for
>    devicetrees

You really should start with this, because that's your goal.

It is quite arguable that it can be achieved without making all of the
changes mentioned above.

>
> ... Summarizing ...
>
> Part 1:
>  - Reorganize structures (some temporary names/leftovers)
>  - New registration function, deprecation of old ones
>  - Migration of drivers/thermal drivers to new registration

I kind of see where this is going, but I don't agree with some of the
changes made.

Let me comment on individual patches (which is not necessarily going
to happen today or even tomorrow, so let me go through the entire
series before deciding what to do next).

Thanks!


From b-liu at ti.com  Thu Feb  1 10:35:22 2024
From: b-liu at ti.com (Bin Liu)
Date: Thu, 1 Feb 2024 12:35:22 -0600
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <20240201-violet-chalice-51a73f113e7b@spud>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-5-rogerq@kernel.org>
 <20240201-viewpoint-upload-fb714f650ff5@spud>
 <20240201-violet-chalice-51a73f113e7b@spud>
Message-ID: <20240201183522.ssj553rwefr2wuqi@iaqt7>

On Thu, Feb 01, 2024 at 06:18:05PM +0000, Conor Dooley wrote:
> On Thu, Feb 01, 2024 at 06:15:20PM +0000, Conor Dooley wrote:
> > On Thu, Feb 01, 2024 at 02:03:31PM +0200, Roger Quadros wrote:
> > > So far this was not required but due to the newly identified
> > > Errata i2409 [1] we need to poke this register space.
> > > 
> > > [1] https://www.ti.com/lit/er/sprz487d/sprz487d.pdf
> > > 
> > > Signed-off-by: Roger Quadros <rogerq at kernel.org>
> > 
> > Acked-by: Conor Dooley <conor.dooley at microchip.com>
> 
> Actually, where is the user for this that actually pokes the register
> space?
> You're adding another register region, so I went to check how you were
> handling that in drivers, but there's no driver patch.

See Roger's another patch set 'Add workaround for Errata i2409' posted
on 16th.

-Bin.

> 
> 
> > 
> > > ---
> > > 
> > > Notes:
> > >     Changelog:
> > >     
> > >     v3 - new patch
> > > 
> > >  Documentation/devicetree/bindings/usb/ti,am62-usb.yaml | 7 +++++--
> > >  1 file changed, 5 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml b/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
> > > index fec5651f5602..c02d9d467d9c 100644
> > > --- a/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
> > > +++ b/Documentation/devicetree/bindings/usb/ti,am62-usb.yaml
> > > @@ -14,7 +14,9 @@ properties:
> > >      const: ti,am62-usb
> > >  
> > >    reg:
> > > -    maxItems: 1
> > > +    items:
> > > +      - description: USB CFG register space
> > > +      - description: USB PHY2 register space
> > >  
> > >    ranges: true
> > >  
> > > @@ -82,7 +84,8 @@ examples:
> > >  
> > >        usbss1: usb at f910000 {
> > >          compatible = "ti,am62-usb";
> > > -        reg = <0x00 0x0f910000 0x00 0x800>;
> > > +        reg = <0x00 0x0f910000 0x00 0x800>,
> > > +              <0x00 0x0f918000 0x00 0x400>;
> > 
> > Why the double zeros btw?
> > 
> > Cheers,
> > Conor.
> > 
> > >          clocks = <&k3_clks 162 3>;
> > >          clock-names = "ref";
> > >          ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
> > > -- 
> > > 2.34.1
> > > 
> 
> 




From rafael at kernel.org  Thu Feb  1 10:37:37 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 1 Feb 2024 19:37:37 +0100
Subject: [PATCH v1 01/18] thermal: core: Change governor name to const
 char pointer
In-Reply-To: <20240130111250.185718-2-angelogioacchino.delregno@collabora.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com> <20240130111250.185718-2-angelogioacchino.delregno@collabora.com>
Message-ID: <CAJZ5v0hOcS0Fm2-mKWtc1-0ym33XuH=B39GGL9b6MfGSqeERkQ@mail.gmail.com>

On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> All users are already assigning a const char * to the `governor_name`
> member of struct thermal_zone_params and to the `name` member of
> struct thermal_governor.
> Even if users are technically wrong, it just makes more sense to change
> this member to be a const char pointer instead of doing the other way
> around.
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Acked-by: Rafael J. Wysocki <rafael at kernel.org>

or I can pick it up right away if you want me to do that.

> ---
>  include/linux/thermal.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index b7a3deb372fd..65d8f92a9a0d 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -214,7 +214,7 @@ struct thermal_zone_device {
>   * @governor_list:     node in thermal_governor_list (in thermal_core.c)
>   */
>  struct thermal_governor {
> -       char name[THERMAL_NAME_LENGTH];
> +       const char *name;
>         int (*bind_to_tz)(struct thermal_zone_device *tz);
>         void (*unbind_from_tz)(struct thermal_zone_device *tz);
>         int (*throttle)(struct thermal_zone_device *tz,
> @@ -226,7 +226,7 @@ struct thermal_governor {
>
>  /* Structure to define Thermal Zone parameters */
>  struct thermal_zone_params {
> -       char governor_name[THERMAL_NAME_LENGTH];
> +       const char *governor_name;
>
>         /*
>          * a boolean to indicate if the thermal to hwmon sysfs interface
> --


From conor at kernel.org  Thu Feb  1 10:42:59 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 1 Feb 2024 18:42:59 +0000
Subject: [PATCH 02/12] dt-bindings: arm: keystone: ti-sci: Add
 reboot-controller child node
In-Reply-To: <20240131221957.213717-3-afd@ti.com>
References: <20240131221957.213717-1-afd@ti.com>
 <20240131221957.213717-3-afd@ti.com>
Message-ID: <20240201-jester-gleeful-3ac8f035e0a4@spud>

On Wed, Jan 31, 2024 at 04:19:47PM -0600, Andrew Davis wrote:
> The TI-SCI firmware supports rebooting the system in addition to the
> functions already listed here, document child node for the same.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
>  .../devicetree/bindings/arm/keystone/ti,sci.yaml          | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml b/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
> index c24ad0968f3ef..e392175b33c74 100644
> --- a/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
> +++ b/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
> @@ -83,6 +83,10 @@ properties:
>      type: object
>      $ref: /schemas/reset/ti,sci-reset.yaml#
>  
> +  reboot-controller:
> +    type: object
> +    $ref: /schemas/power/reset/ti,sci-reboot.yaml#
> +
>  required:
>    - compatible
>    - mbox-names
> @@ -126,4 +130,8 @@ examples:
>          compatible = "ti,sci-reset";
>          #reset-cells = <2>;
>        };
> +
> +      k3_reboot: reboot-controller {
> +        compatible = "ti,sci-reboot";
> +      };
>      };
> -- 
> 2.39.2
> 
-------------- 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/20240201/d7ca498a/attachment.sig>

From bjorn at kernel.org  Thu Feb  1 10:45:47 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Thu, 01 Feb 2024 19:45:47 +0100
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <CAK9=C2UX0sRb5UbLdm8xwe1dP=x+enJRYzAuCPf6MdHTLTC_Cw@mail.gmail.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <87r0hzuw87.fsf@all.your.base.are.belong.to.us>
 <87le87uulb.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2UYCKUBKggtM606orH2mBu_AbTdB5-R5AP1M0t-LsEbEQ@mail.gmail.com>
 <87cytjvybb.fsf@all.your.base.are.belong.to.us>
 <87ttmuq3m7.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2UEpbd+pHAMg-AuP-fTPZVho16u69oSjOHhsR11HTwiew@mail.gmail.com>
 <87fryeognc.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2UX0sRb5UbLdm8xwe1dP=x+enJRYzAuCPf6MdHTLTC_Cw@mail.gmail.com>
Message-ID: <87v878dnvo.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

> On Tue, Jan 30, 2024 at 11:19?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>>
>> Anup Patel <apatel at ventanamicro.com> writes:
>>
>> > On Tue, Jan 30, 2024 at 8:18?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>> >>
>> >> Bj?rn T?pel <bjorn at kernel.org> writes:
>> >>
>> >> > Anup Patel <apatel at ventanamicro.com> writes:
>> >> >
>> >> >> On Tue, Jan 30, 2024 at 1:22?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>> >> >>>
>> >> >>> Bj?rn T?pel <bjorn at kernel.org> writes:
>> >> >>>
>> >> >>> > Anup Patel <apatel at ventanamicro.com> writes:
>> >> >>> >
>> >> >>> >> The RISC-V AIA specification is ratified as-per the RISC-V international
>> >> >>> >> process. The latest ratified AIA specifcation can be found at:
>> >> >>> >> https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf
>> >> >>> >>
>> >> >>> >> At a high-level, the AIA specification adds three things:
>> >> >>> >> 1) AIA CSRs
>> >> >>> >>    - Improved local interrupt support
>> >> >>> >> 2) Incoming Message Signaled Interrupt Controller (IMSIC)
>> >> >>> >>    - Per-HART MSI controller
>> >> >>> >>    - Support MSI virtualization
>> >> >>> >>    - Support IPI along with virtualization
>> >> >>> >> 3) Advanced Platform-Level Interrupt Controller (APLIC)
>> >> >>> >>    - Wired interrupt controller
>> >> >>> >>    - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
>> >> >>> >>    - In Direct-mode, injects external interrupts directly into HARTs
>> >> >>> >>
>> >> >>> >> For an overview of the AIA specification, refer the AIA virtualization
>> >> >>> >> talk at KVM Forum 2022:
>> >> >>> >> https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
>> >> >>> >> https://www.youtube.com/watch?v=r071dL8Z0yo
>> >> >>> >>
>> >> >>> >> To test this series, use QEMU v7.2 (or higher) and OpenSBI v1.2 (or higher).
>> >> >>> >>
>> >> >>> >> These patches can also be found in the riscv_aia_v12 branch at:
>> >> >>> >> https://github.com/avpatel/linux.git
>> >> >>> >>
>> >> >>> >> Changes since v11:
>> >> >>> >>  - Rebased on Linux-6.8-rc1
>> >> >>> >>  - Included kernel/irq related patches from "genirq, irqchip: Convert ARM
>> >> >>> >>    MSI handling to per device MSI domains" series by Thomas.
>> >> >>> >>    (PATCH7, PATCH8, PATCH9, PATCH14, PATCH16, PATCH17, PATCH18, PATCH19,
>> >> >>> >>     PATCH20, PATCH21, PATCH22, PATCH23, and PATCH32 of
>> >> >>> >>     https://lore.kernel.org/linux-arm-kernel/20221121135653.208611233 at linutronix.de/)
>> >> >>> >>  - Updated APLIC MSI-mode driver to use the new WIRED_TO_MSI mechanism.
>> >> >>> >>  - Updated IMSIC driver to support per-device MSI domains for PCI and
>> >> >>> >>    platform devices.
>> >> >>> >
>> >> >>> > Thanks for working on this, Anup! I'm still reviewing the patches.
>> >> >>> >
>> >> >>> > I'm hitting a boot hang in text patching, with this series applied on
>> >> >>> > 6.8-rc2. IPI issues?
>> >> >>>
>> >> >>> Not text patching! One cpu spinning in smp_call_function_many_cond() and
>> >> >>> the others are in cpu_relax(). Smells like IPI...
>> >> >>
>> >> >> I tried bootefi from U-Boot multiple times but can't reproduce the
>> >> >> issue you are seeing.
>> >> >
>> >> > Thanks! I can reproduce without EFI, and simpler command-line:
>> >> >
>> >> > qemu-system-riscv64 \
>> >> >   -bios /path/to/fw_dynamic.bin \
>> >> >   -kernel /path/to/Image \
>> >> >   -append 'earlycon console=tty0 console=ttyS0' \
>> >> >   -machine virt,aia=aplic-imsic \
>> >> >   -no-reboot -nodefaults -nographic \
>> >> >   -smp 4 \
>> >> >   -object rng-random,filename=/dev/urandom,id=rng0 \
>> >> >   -device virtio-rng-device,rng=rng0 \
>> >> >   -m 4G -chardev stdio,id=char0 -serial chardev:char0
>> >> >
>> >> > I can reproduce with your upstream riscv_aia_v12 plus the config in the
>> >> > gist [1], and all latest QEMU/OpenSBI:
>> >> >
>> >> > QEMU: 11be70677c70 ("Merge tag 'pull-vfio-20240129' of https://github.com/legoater/qemu into staging")
>> >> > OpenSBI: bb90a9ebf6d9 ("lib: sbi: Print number of debug triggers found")
>> >> > Linux: d9b9d6eb987f ("MAINTAINERS: Add entry for RISC-V AIA drivers")
>> >> >
>> >> > Removing ",aia=aplic-imsic" from the CLI above completes the boot (i.e.
>> >> > panicking about missing root mount ;-))
>> >>
>> >> More context; The hang is during a late initcall, where an ftrace direct
>> >> (register_ftrace_direct()) modification is done.
>> >>
>> >> Stop machine is used to call into __ftrace_modify_call(). Then into the
>> >> arch specific patch_text_nosync(), where flush_icache_range() hangs in
>> >> flush_icache_all(). From "on_each_cpu(ipi_remote_fence_i, NULL, 1);" to
>> >> on_each_cpu_cond_mask() "smp_call_function_many_cond(mask, func, info,
>> >> scf_flags, cond_func);" which never returns from "csd_lock_wait(csd)"
>> >> right before the end of the function.
>> >>
>> >> Any ideas? Disabling CONFIG_HID_BPF, that does the early ftrace code
>> >> patching fixes the boot hang, but it does seem related to IPI...
>> >>
>> > Looks like flush_icache_all() does not use the IPIs (on_each_cpu()
>> > and friends) correctly.
>> >
>> > On other hand, the flush_icache_mm() does the right thing by
>> > doing local flush on the current CPU and IPI based flush on other
>> > CPUs.
>> >
>> > Can you try the following patch ?
>> >
>> > diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
>> > index 55a34f2020a8..a3dfbe4de832 100644
>> > --- a/arch/riscv/mm/cacheflush.c
>> > +++ b/arch/riscv/mm/cacheflush.c
>> > @@ -19,12 +19,18 @@ static void ipi_remote_fence_i(void *info)
>> >
>> >  void flush_icache_all(void)
>> >  {
>> > +    cpumask_t others;
>> > +
>> >      local_flush_icache_all();
>> >
>> > +    cpumask_andnot(&others, cpu_online_mask, cpumask_of(smp_processor_id()));
>> > +    if (cpumask_empty(&others))
>> > +        return;
>> > +
>> >      if (IS_ENABLED(CONFIG_RISCV_SBI) && !riscv_use_ipi_for_rfence())
>> > -        sbi_remote_fence_i(NULL);
>> > +        sbi_remote_fence_i(&others);
>> >      else
>> > -        on_each_cpu(ipi_remote_fence_i, NULL, 1);
>> > +        on_each_cpu_mask(&others, ipi_remote_fence_i, NULL, 1);
>> >  }
>> >  EXPORT_SYMBOL(flush_icache_all);
>>
>> Unfortunately, I see the same hang. LMK if you'd like me to try anything
>> else.
>
> I was able to reproduce this at my end but I had to use your config.
>
> Digging further, it seems the issue is observed only when we use
> in-kernel IPIs for cache flushing (instead of SBI calls) along with
> some of the tracers (or debugging features) enabled. With the tracers
> (or debug features) disabled we don't see any issue. In fact, the
> upstream defconfig works perfectly fine with AIA drivers and
> in-kernel IPIs.

Same here. I only see the issue for *one* scenario. Other than that
scenario, AIA is working fine! We're doing ftrace text patching, and I
wonder if this is the issue. RISC-V (unfortunately) still rely on
stop_machine() text patching (which will change!).

Again, the hang is in stop_machine() context, where interrupts should
very much be disabled, right? So, triggering an IPI will be impossible.

Dumping mstatus in QEMU:
  | mstatus  0000000a000000a0
  | mstatus  0000000a000000a0
  | mstatus  0000000a000000a0
  | mstatus  0000000a000000a0

Indeed sstatus.SIE is 0.

Seems like the bug is that text patching is trying to issue an IPI:
  | [<ffffffff801145d4>] smp_call_function_many_cond+0x81e/0x8ba
  | [<ffffffff80114716>] on_each_cpu_cond_mask+0x3e/0xde
  | [<ffffffff80013968>] flush_icache_all+0x98/0xc4
  | [<ffffffff80009c26>] patch_text_nosync+0x7c/0x146
  | [<ffffffff80ef9116>] __ftrace_modify_call.constprop.0+0xca/0x120
  | [<ffffffff80ef918c>] ftrace_update_ftrace_func+0x20/0x40
  | [<ffffffff80efb8ac>] ftrace_modify_all_code+0x5a/0x1d8
  | [<ffffffff80efba50>] __ftrace_modify_code+0x26/0x42
  | [<ffffffff80131734>] multi_cpu_stop+0x14e/0x1d8
  | [<ffffffff8013107a>] cpu_stopper_thread+0x9e/0x182
  | [<ffffffff80077a04>] smpboot_thread_fn+0xf8/0x1d2
  | [<ffffffff800718fc>] kthread+0xe8/0x108
  | [<ffffffff80f1cde6>] ret_from_fork+0xe/0x20


Bj?rn


From thierry.reding at gmail.com  Thu Feb  1 10:49:04 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 01 Feb 2024 19:49:04 +0100
Subject: [PATCH net-next 0/3] net: stmmac: Allow driver-specific AXI
 configuration
Message-ID: <20240201-stmmac-axi-config-v1-0-822e97b2d26e@nvidia.com>

AXI bus configuration can, in most cases, be derived from the compatible
string, so instead of relying exclusively on device tree for the AXI bus
configuration, create a method for device drivers to pass along a known-
good configuration.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
Thierry Reding (3):
      net: stmmac: Pass resources to DT parsing code
      net: stmmac: Allow drivers to provide a default AXI configuration
      net: stmmac: Configure AXI on Tegra234 MGBE

 .../net/ethernet/stmicro/stmmac/dwmac-anarion.c    |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-generic.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-ingenic.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-loongson1.c  |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c  |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-starfive.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c  | 11 +++-
 .../net/ethernet/stmicro/stmmac/dwmac-visconti.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 66 ++++++++++++++--------
 .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |  3 +-
 25 files changed, 77 insertions(+), 47 deletions(-)
---
base-commit: 51b70ff55ed88edd19b080a524063446bcc34b62
change-id: 20240201-stmmac-axi-config-77ea05ea9eff

Best regards,
-- 
Thierry Reding <treding at nvidia.com>



From thierry.reding at gmail.com  Thu Feb  1 10:49:05 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 01 Feb 2024 19:49:05 +0100
Subject: [PATCH net-next 1/3] net: stmmac: Pass resources to DT parsing
 code
In-Reply-To: <20240201-stmmac-axi-config-v1-0-822e97b2d26e@nvidia.com>
References: <20240201-stmmac-axi-config-v1-0-822e97b2d26e@nvidia.com>
Message-ID: <20240201-stmmac-axi-config-v1-1-822e97b2d26e@nvidia.com>

From: Thierry Reding <treding at nvidia.com>

We already pass the stmmac_resources structure to other initialization
functions since it allows us to exchange more data between the driver
and those functions. Passing this structure to the DT parsing code makes
it easier to extend what we pass around in the future.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-loongson1.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c      |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-starfive.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-visconti.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c   | 21 ++++++++++++---------
 .../net/ethernet/stmicro/stmmac/stmmac_platform.h   |  3 ++-
 24 files changed, 36 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
index 643ee6d8d4dd..f37d9912380b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
@@ -115,7 +115,7 @@ static int anarion_dwmac_probe(struct platform_device *pdev)
 	if (IS_ERR(gmac))
 		return PTR_ERR(gmac);
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
index ec924c6c76c6..36ef2ed9fd2d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
@@ -435,7 +435,7 @@ static int dwc_eth_dwmac_probe(struct platform_device *pdev)
 	if (IS_ERR(stmmac_res.addr))
 		return PTR_ERR(stmmac_res.addr);
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
index 598eff926815..98a00084807b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
@@ -27,7 +27,7 @@ static int dwmac_generic_probe(struct platform_device *pdev)
 		return ret;
 
 	if (pdev->dev.of_node) {
-		plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+		plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 		if (IS_ERR(plat_dat)) {
 			dev_err(&pdev->dev, "dt configuration failed\n");
 			return PTR_ERR(plat_dat);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
index 6b65420e11b5..d72b9d8ac464 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
@@ -331,7 +331,7 @@ static int imx_dwmac_probe(struct platform_device *pdev)
 	if (!dwmac)
 		return -ENOMEM;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c
index 19c93b998fb3..de2f5d7e95b2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c
@@ -241,7 +241,7 @@ static int ingenic_mac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
index d68f0c4e7835..79582983c060 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
@@ -84,7 +84,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat)) {
 		dev_err(&pdev->dev, "dt configuration failed\n");
 		return PTR_ERR(plat_dat);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
index 281687d7083b..311410509012 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
@@ -384,7 +384,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
 	if (val)
 		return val;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
index 3e86810717d3..1ede4f409937 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
@@ -169,7 +169,7 @@ static int ls1x_dwmac_probe(struct platform_device *pdev)
 	if (!dwmac)
 		return -ENOMEM;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
 				     "dt configuration failed\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
index 4c810d8f5bea..004bf4d14fdb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
@@ -37,7 +37,7 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
index 2a9132d6d743..763ec218ff2c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -656,7 +656,7 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
index a16bfa9089ea..5bd936ef2796 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
@@ -52,7 +52,7 @@ static int meson6_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index b23944aa344e..88db2907640d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -400,7 +400,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 31631e3f89d0..473e8d4228e4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -735,7 +735,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, ret,
 				     "Failed to get platform resources\n");
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat)) {
 		return dev_err_probe(dev, PTR_ERR(plat_dat),
 				     "dt configuration failed\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 382e8de1255d..4297a6919c8a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1824,7 +1824,7 @@ static int rk_gmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 68f85e4605cb..e827e01b4398 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -400,7 +400,7 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
index 4e1076faee0c..a0f15fbb8993 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
@@ -122,7 +122,7 @@ static int starfive_dwmac_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, err,
 				     "failed to get resources\n");
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
 				     "dt configuration failed\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
index 4445cddc4cbe..5b2cde45dc3e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -273,7 +273,7 @@ static int sti_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index c92dfc4ecf57..af131b0bf589 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -366,7 +366,7 @@ static int stm32_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 137741b94122..3ccf695c8b5f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1224,7 +1224,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return -EINVAL;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
index 2653a9f0958c..f78e244b9d81 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
@@ -108,7 +108,7 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
index 362f85136c3e..bab57d1675df 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
@@ -284,7 +284,7 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
 	if (err < 0)
 		goto disable_clks;
 
-	plat = devm_stmmac_probe_config_dt(pdev, res.mac);
+	plat = devm_stmmac_probe_config_dt(pdev, &res);
 	if (IS_ERR(plat)) {
 		err = PTR_ERR(plat);
 		goto disable_clks;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
index a5a5cfa989c6..f99d147b3424 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
@@ -220,7 +220,7 @@ static int visconti_eth_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 70eadc83ca68..8ec2ac28a775 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -424,13 +424,14 @@ static void stmmac_remove_config_dt(struct platform_device *pdev,
 /**
  * stmmac_probe_config_dt - parse device-tree driver parameters
  * @pdev: platform_device structure
- * @mac: MAC address to use
+ * @res: driver-specific parameters
  * Description:
  * this function is to read the driver parameters from device-tree and
  * set some private fields that will be used by the main at runtime.
  */
 static struct plat_stmmacenet_data *
-stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+stmmac_probe_config_dt(struct platform_device *pdev,
+		       struct stmmac_resources *res)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct plat_stmmacenet_data *plat;
@@ -443,12 +444,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 	if (!plat)
 		return ERR_PTR(-ENOMEM);
 
-	rc = of_get_mac_address(np, mac);
+	rc = of_get_mac_address(np, res->mac);
 	if (rc) {
 		if (rc == -EPROBE_DEFER)
 			return ERR_PTR(rc);
 
-		eth_zero_addr(mac);
+		eth_zero_addr(res->mac);
 	}
 
 	phy_mode = device_get_phy_mode(&pdev->dev);
@@ -605,7 +606,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 
 	of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed);
 
-	plat->axi = stmmac_axi_setup(pdev);
+	plat->axi = stmmac_axi_setup(pdev, res);
 
 	rc = stmmac_mtl_setup(pdev, plat);
 	if (rc) {
@@ -677,17 +678,18 @@ static void devm_stmmac_remove_config_dt(void *data)
 /**
  * devm_stmmac_probe_config_dt
  * @pdev: platform_device structure
- * @mac: MAC address to use
+ * @res: driver-specific parameters
  * Description: Devres variant of stmmac_probe_config_dt(). Does not require
  * the user to call stmmac_remove_config_dt() at driver detach.
  */
 struct plat_stmmacenet_data *
-devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+devm_stmmac_probe_config_dt(struct platform_device *pdev,
+			    struct stmmac_resources *res)
 {
 	struct plat_stmmacenet_data *plat;
 	int ret;
 
-	plat = stmmac_probe_config_dt(pdev, mac);
+	plat = stmmac_probe_config_dt(pdev, res);
 	if (IS_ERR(plat))
 		return plat;
 
@@ -700,7 +702,8 @@ devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 }
 #else
 struct plat_stmmacenet_data *
-devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+devm_stmmac_probe_config_dt(struct platform_device *pdev,
+			    struct stmmac_resources *res)
 {
 	return ERR_PTR(-EINVAL);
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
index bb6fc7e59aed..daf3bbb503a3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
@@ -12,7 +12,8 @@
 #include "stmmac.h"
 
 struct plat_stmmacenet_data *
-devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
+devm_stmmac_probe_config_dt(struct platform_device *pdev,
+			    struct stmmac_resources *res);
 
 int stmmac_get_platform_resources(struct platform_device *pdev,
 				  struct stmmac_resources *stmmac_res);

-- 
2.43.0



From thierry.reding at gmail.com  Thu Feb  1 10:49:06 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 01 Feb 2024 19:49:06 +0100
Subject: [PATCH net-next 2/3] net: stmmac: Allow drivers to provide a
 default AXI configuration
In-Reply-To: <20240201-stmmac-axi-config-v1-0-822e97b2d26e@nvidia.com>
References: <20240201-stmmac-axi-config-v1-0-822e97b2d26e@nvidia.com>
Message-ID: <20240201-stmmac-axi-config-v1-2-822e97b2d26e@nvidia.com>

From: Thierry Reding <treding at nvidia.com>

In many cases the AXI configuration can be derived from the compatible
string, so there's no need to add the configuration to DT. Allow drivers
to pass in the default AXI configuration so they can be properly set up
without extra data in DT.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 47 ++++++++++++++--------
 2 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index f155e4841c62..07706e7b3cfc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -35,6 +35,8 @@ struct stmmac_resources {
 	int sfty_ue_irq;
 	int rx_irq[MTL_MAX_RX_QUEUES];
 	int tx_irq[MTL_MAX_TX_QUEUES];
+
+	const struct stmmac_axi *axi;
 };
 
 enum stmmac_txbuf_type {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 8ec2ac28a775..0d5f2cebd6fc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -91,34 +91,49 @@ static int dwmac1000_validate_ucast_entries(struct device *dev,
  * if required, from device-tree the AXI internal register can be tuned
  * by using platform parameters.
  */
-static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
+static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev,
+					   struct stmmac_resources *res)
 {
 	struct device_node *np;
 	struct stmmac_axi *axi;
 
 	np = of_parse_phandle(pdev->dev.of_node, "snps,axi-config", 0);
-	if (!np)
+	if (!np && !res->axi)
 		return NULL;
 
 	axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
 	if (!axi) {
-		of_node_put(np);
+		if (np)
+			of_node_put(np);
+
 		return ERR_PTR(-ENOMEM);
 	}
 
-	axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
-	axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
-	axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
-	axi->axi_fb = of_property_read_bool(np, "snps,fb");
-	axi->axi_mb = of_property_read_bool(np, "snps,mb");
-	axi->axi_rb =  of_property_read_bool(np, "snps,rb");
-
-	if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
-		axi->axi_wr_osr_lmt = 1;
-	if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt))
-		axi->axi_rd_osr_lmt = 1;
-	of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
-	of_node_put(np);
+	if (res->axi)
+		*axi = *res->axi;
+
+	if (np) {
+		axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
+		axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
+		axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
+		axi->axi_fb = of_property_read_bool(np, "snps,fb");
+		axi->axi_mb = of_property_read_bool(np, "snps,mb");
+		axi->axi_rb =  of_property_read_bool(np, "snps,rb");
+
+		if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt)) {
+			if (!res->axi)
+				axi->axi_wr_osr_lmt = 1;
+		}
+
+		if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt)) {
+			if (!res->axi)
+				axi->axi_rd_osr_lmt = 1;
+		}
+
+		of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
+
+		of_node_put(np);
+	}
 
 	return axi;
 }

-- 
2.43.0



From thierry.reding at gmail.com  Thu Feb  1 10:49:07 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 01 Feb 2024 19:49:07 +0100
Subject: [PATCH net-next 3/3] net: stmmac: Configure AXI on Tegra234 MGBE
In-Reply-To: <20240201-stmmac-axi-config-v1-0-822e97b2d26e@nvidia.com>
References: <20240201-stmmac-axi-config-v1-0-822e97b2d26e@nvidia.com>
Message-ID: <20240201-stmmac-axi-config-v1-3-822e97b2d26e@nvidia.com>

From: Thierry Reding <treding at nvidia.com>

Allow the device to use bursts and increase the maximum number of
outstanding requests to improve performance. Measurements show an
increase in throughput of around 5x on a 1 Gbps link.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
index bab57d1675df..b6bfa48f279d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
@@ -199,6 +199,12 @@ static void mgbe_uphy_lane_bringup_serdes_down(struct net_device *ndev, void *mg
 	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 }
 
+static const struct stmmac_axi tegra234_mgbe_axi = {
+	.axi_wr_osr_lmt = 63,
+	.axi_rd_osr_lmt = 63,
+	.axi_blen = { 256, },
+};
+
 static int tegra_mgbe_probe(struct platform_device *pdev)
 {
 	struct plat_stmmacenet_data *plat;
@@ -284,6 +290,9 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
 	if (err < 0)
 		goto disable_clks;
 
+	/* setup default AXI configuration */
+	res.axi = &tegra234_mgbe_axi;
+
 	plat = devm_stmmac_probe_config_dt(pdev, &res);
 	if (IS_ERR(plat)) {
 		err = PTR_ERR(plat);

-- 
2.43.0



From conor at kernel.org  Thu Feb  1 10:53:02 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 1 Feb 2024 18:53:02 +0000
Subject: [PATCH 01/12] dt-bindings: power: reset: Document ti,sci-reboot
 compatible
In-Reply-To: <20240131221957.213717-2-afd@ti.com>
References: <20240131221957.213717-1-afd@ti.com>
 <20240131221957.213717-2-afd@ti.com>
Message-ID: <20240201-ambiguous-swan-a927ae8f126f@spud>

On Wed, Jan 31, 2024 at 04:19:46PM -0600, Andrew Davis wrote:
> This calls into the system firmware using TI-SCI to reboot the system.
> Used as a fallback when PSCI is unable or not available to reboot
> the system.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  .../bindings/power/reset/ti,sci-reboot.yaml   | 33 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 34 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/reset/ti,sci-reboot.yaml
> 
> diff --git a/Documentation/devicetree/bindings/power/reset/ti,sci-reboot.yaml b/Documentation/devicetree/bindings/power/reset/ti,sci-reboot.yaml
> new file mode 100644
> index 0000000000000..aa628be33d122
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/reset/ti,sci-reboot.yaml
> @@ -0,0 +1,33 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/power/reset/ti,sci-reboot.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: TI-SCI reboot controller
> +
> +maintainers:
> +  - Andrew Davis <afd at ti.com>
> +
> +description: |
> +  Some TI SoCs contain a system controller (like the Power Management Micro
> +  Controller (PMMC) on Keystone 66AK2G SoC) that are responsible for controlling
> +  the state of the various hardware modules present on the SoC. Communication
> +  between the host processor running an OS and the system controller happens
> +  through a protocol called TI System Control Interface (TI-SCI protocol).
> +
> +  This reboot controller node uses the TI SCI protocol to perform a device reboot.
> +
> +  Must be a child node of the associated TI-SCI system controller node.
> +
> +properties:
> +  compatible:
> +    const: ti,sci-reboot
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    k3_reboot: reboot-controller {
> +        compatible = "ti,sci-reboot";
> +    };

I'd drop the example since this has no use standalone and just rely on
the one in the parent. Otherwise I think this is fine.

Acked-by: Conor Dooley <conor.dooley at microchip.com>
-------------- 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/20240201/6f71c485/attachment.sig>

From william.zhang at broadcom.com  Thu Feb  1 10:53:11 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 1 Feb 2024 10:53:11 -0800
Subject: [PATCH v3 10/10] mtd: rawnand: brcmnand: allow for on-die ecc
In-Reply-To: <20240201092558.5499ee6a@xps-13>
References: <20240124030458.98408-1-dregan@broadcom.com>
 <20240124030458.98408-11-dregan@broadcom.com>
 <20240124184027.712b1e47@xps-13>
 <CAA_RMS42FaiN+Za1iY12o0YUANH9rJarBTBa=9jNn8x6_g-Fng@mail.gmail.com>
 <20240126071913.699c3795@xps-13>
 <CAA_RMS5gX88v_Qt1csgSL_ffMNsqo2G8B164EB_Hg=hXd620eg@mail.gmail.com>
 <20240129115228.06dc2292@xps-13>
 <2a3edcf5-7afc-410c-a402-3d8cd3feb1da@broadcom.com>
 <20240130120155.3cb6feed@xps-13>
 <CAA_RMS577vw=QWN9_NHfmWqt+_cDG22tA01aU019CPNjAgHqJQ@mail.gmail.com>
 <20240130195504.506fb446@xps-13>
 <bcd9f8a5-7dab-42e6-b860-8a56ebb51cb6@broadcom.com>
 <20240201092558.5499ee6a@xps-13>
Message-ID: <9d54dead-7015-42fb-95b3-730ee8b2e553@broadcom.com>



On 2/1/24 00:25, Miquel Raynal wrote:
> Hi William,
> 
>>>>>>>>>> This is a double check to turn on/off our hardware ECC.
>>>>>>>>>
>>>>>>>>> I expect the engine to be always disabled. Enable it only when you
>>>>>>>>> need (may require an additional patch before this one).
>>>>>>>>
>>>>>>>> We are already turning on the ECC enable at this point,
>>>>>>>> this is just adding the option to turn it off if the NAND chip
>>>>>>>> itself will be doing the ECC instead of our controller.
>>>>>>>
>>>>>>> Sorry if I have not been clear.
>>>>>>>
>>>>>>> This sequence:
>>>>>>> - init
>>>>>>> - enable hw ECC engine
>>>>>>> Is broken.
>>>>>>>    >>>> ECC engine is not enabled for all the cases. Here we only intended to enable it for the nand chip that is set to use NAND_ECC_ENGINE_TYPE_ON_HOST. The logic here should better change to:
>>>>>> if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST)
>>>>>>        brcmnand_set_ecc_enabled(host, 1);
>>>>>> else
>>>>>>        brcmnand_set_ecc_enabled(host, 0);
>>>>>>    >>>>> It *cannot* work as any operation going through exec_op now may
>>>>>>> perform page reads which should be unmodified by the ECC engine. You > driver *must* follow the following sequence:
>>>>>>> - init and disable (or keep disabled) the hw ECC engine
>>>>>>> - when you perform a page operation with correction you need to
>>>>>>>       - enable the engine
>>>>>>>       - perform the operation
>>>>>>>       - disable the engine
>>>>>>> Maybe I am missing something here but are you saying the exec_op can have different ecc type for page read/write at run time on the same nand chip? I don't see the op instr structure has the ecc type field and thought it is only bind to the nand chip and won't change at run time. So looks to me the init time setting to the engine based on ecc.engine_type should be sufficient.
>>>>>>
>>>>>> What you described here can work for the hw.ecc read path (ecc.read_page = brcmnand_read_page) which always assumes ecc is enabled. Although it is probably not too bad with these two extra operation, it would be better if we don't have to add anything as our current code does. For the brcmnand_read_page_raw,  we currently disable the engine and then re-enable it(but we need to fix it to only enable it with hw ecc engine type).  So it is just opposite of you logic but works the same with no impact on the most performance critical path.
>>>>>
>>>>> This is not "my" logic, this is the "core's" logic. I am saying: your
>>>>> approach is broken because that is not how the API is supposed to work,
>>>>> but it mostly works in the standard case.
>>>>
>>>> In the interest of minimizing register writes, would it be acceptable to
>>>> enable/disable ECC at the beginning of a standard
>>>> path transfer but not, after the transfer, turn off the ECC? This should not
>>>> affect other standard path operations nor affect the exec_op path as those
>>>> are low level transfers which our ECC engine would not touch and the NAND
>>>> device driver should be responsible for turning on/off its own ECC.
>>>
>>> Do you have legitimate concerns about this register write taking way
>>> more time than I could expect? Because compared to the transfer of a
>>> NAND page + tR/tPROG it should not be noticeable. I don't see how you
>>> could even measure such impact actually, unless the register write does
>>> way more than usual. I'm fine with the above idea if you show me it has
>>> an interest.
>>>    
>> Dave did the mtd_speed test and we can see we get consistently ~35KB/s slower with the extra enable and disable ecc engine calls in ecc read page path.
>>
>> With the change:
>> [   28.148355] mtd_speedtest:   page read speed is 9857 KiB/s
>> [   31.754258] mtd_speedtest: 2 page read speed is 9865 KiB/s
>> Without the change
>> [   56.444735] mtd_speedtest:   page read speed is 9892 KiB/s
>> [   60.042262] mtd_speedtest: 2 page read speed is 9897 KiB/s
> 
> I believe if you repeat this 10 times you'll get totally different
> results. I don't think this test on a non RT machine is precise enough
> so that a unique 35kiB difference can be interpreted as being
> significant.
> 
No, it is very consistent. It is not RT system but a bare minimum setup 
with just linux kernel, mtd/nand drivers and a shell. We don't run any 
apps and extra drivers. So the system is pretty idle while we run mtd 
speed test.

>> Although it is only less than 1% drop, it is still something. I understand the procedure you laid out above is the preferred way but with our driver fully control the chip ecc read/write page, ecc read_raw/write_raw page function and exec_op path, I don't see where it may not work.
> 
> I just told you, the exec_op path runs with ECC enabled. I don't know
> how this controller works. Now if you don't care and are 100% sure this
> is working and future proof, just keep it like this.
> 
This is something I don't get.  The patch basically only enable the ecc 
when NAND_ECC_ENGINE_TYPE_ON_HOST is set. But in this case exec_op does 
not do page read/write. Even page read/write go through exec_op, we do 
want the engine to do the ecc checking. So need to have it enabled. 
Other op like parameter read does not go through controller's ecc engine 
so it does not matter if ecc is on or not.

If NAND_ECC_ENGINE_TYPE_ON_DIE is set, this patch disable the controller 
engine and let NAND chip do the work as it requires.  So exec_op path 
run with ecc disabled when page read/write also go through exec_op path. 
  I don't see any issue with this either.

I am not trying to make your job hard but I want to understand if there 
is really any issue here.

> Cheers,
> Miqu?l
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240201/8b83d982/attachment-0001.p7s>

From conor at kernel.org  Thu Feb  1 10:59:30 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 1 Feb 2024 18:59:30 +0000
Subject: [PATCH v8 1/3] dt-bindings: pwm: Add binding for Allwinner
 D1/T113-S3/R329 PWM controller
In-Reply-To: <20240201174851.62e74089@donnerap.manchester.arm.com>
References: <20240131125920.2879433-1-privatesub2@gmail.com>
 <20240131125920.2879433-2-privatesub2@gmail.com>
 <20240131145244.4f534bac@donnerap.manchester.arm.com>
 <20240131-renewably-glimpse-a80339e8ff81@spud>
 <20240201174851.62e74089@donnerap.manchester.arm.com>
Message-ID: <20240201-numbing-reconcile-64d05bb88e9c@spud>

On Thu, Feb 01, 2024 at 05:48:51PM +0000, Andre Przywara wrote:
> On Wed, 31 Jan 2024 21:22:06 +0000
> Conor Dooley <conor at kernel.org> wrote:
> 
> Hi,
> 
> > On Wed, Jan 31, 2024 at 02:52:44PM +0000, Andre Przywara wrote:
> > > On Wed, 31 Jan 2024 15:59:14 +0300
> > > Aleksandr Shubin <privatesub2 at gmail.com> wrote:
> > > 
> > > Hi,
> > >   
> > > > Allwinner's D1, T113-S3 and R329 SoCs have a new pwm
> > > > controller witch is different from the previous pwm-sun4i.
> > > > 
> > > > The D1 and T113 are identical in terms of peripherals,
> > > > they differ only in the architecture of the CPU core, and
> > > > even share the majority of their DT. Because of that,
> > > > using the same compatible makes sense.
> > > > The R329 is a different SoC though, and should have
> > > > a different compatible string added, especially as there
> > > > is a difference in the number of channels.
> > > > 
> > > > D1 and T113s SoCs have one PWM controller with 8 channels.
> > > > R329 SoC has two PWM controllers in both power domains, one of
> > > > them has 9 channels (CPUX one) and the other has 6 (CPUS one).
> > > > 
> > > > Add a device tree binding for them.
> > > > 
> > > > Signed-off-by: Aleksandr Shubin <privatesub2 at gmail.com>
> > > > Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> > > > ---
> > > >  .../bindings/pwm/allwinner,sun20i-pwm.yaml    | 88 +++++++++++++++++++
> > > >  1 file changed, 88 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/pwm/allwinner,sun20i-pwm.yaml
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/pwm/allwinner,sun20i-pwm.yaml b/Documentation/devicetree/bindings/pwm/allwinner,sun20i-pwm.yaml
> > > > new file mode 100644
> > > > index 000000000000..716f75776006
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/pwm/allwinner,sun20i-pwm.yaml
> > > > @@ -0,0 +1,88 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/pwm/allwinner,sun20i-pwm.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Allwinner D1, T113-S3 and R329 PWM
> > > > +
> > > > +maintainers:
> > > > +  - Aleksandr Shubin <privatesub2 at gmail.com>
> > > > +  - Brandon Cheo Fusi <fusibrandon13 at gmail.com>
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +    oneOf:
> > > > +      - const: allwinner,sun20i-d1-pwm
> > > > +      - items:
> > > > +          - const: allwinner,sun20i-r329-pwm
> > > > +          - const: allwinner,sun20i-d1-pwm
> > > > +
> > > > +  reg:
> > > > +    maxItems: 1
> > > > +
> > > > +  "#pwm-cells":
> > > > +    const: 3
> > > > +
> > > > +  clocks:
> > > > +    items:
> > > > +      - description: Bus clock
> > > > +      - description: 24 MHz oscillator
> > > > +      - description: APB0 clock
> > > > +
> > > > +  clock-names:
> > > > +    items:
> > > > +      - const: bus
> > > > +      - const: hosc
> > > > +      - const: apb0
> > > > +
> > > > +  resets:
> > > > +    maxItems: 1
> > > > +
> > > > +  allwinner,pwm-channels:
> > > > +    $ref: /schemas/types.yaml#/definitions/uint32
> > > > +    description: The number of PWM channels configured for this instance
> > > > +    enum: [6, 9]
> > > > +
> > > > +allOf:
> > > > +  - $ref: pwm.yaml#
> > > > +
> > > > +  - if:
> > > > +      properties:
> > > > +        compatible:
> > > > +          contains:
> > > > +            const: allwinner,sun20i-r329-pwm
> > > > +
> > > > +    then:
> > > > +      required:
> > > > +        - allwinner,pwm-channels
> > > > +
> > > > +    else:
> > > > +      properties:
> > > > +        allwinner,pwm-channels: false  
> > > 
> > > Do we really need to be that strict?
> > > If something compatible to D1 pops up in the future, just with a different
> > > number of channels, we would need a new compatible string.  
> > 
> > Well, you would want to have a soc specific compatible anyway then,
> > right?
> 
> So the idea would be to add any new (specific) compatible string to that
> list then, when we add them?
> I guess this would work, but strictly speaking any current driver would
> then only need to check this property for the R329 type? The Linux
> driver proposed in the next patch *always* honours the
> allwinner,pwm-channels property, which is IMHO the right way to implement
> this. And that's why I think the binding should reflect that, and not
> explicitly *forbid* the property for every one other than R329 (atm).
> 
> With the current Linux driver, a potential new SoC using:
> 	"allwinner,sun20i-d2-pwm", "allwinner,sun20i-d1-pwm";
> 	allwinner,pwm-channels = <6>;
> would work without driver changes. A driver strictly written to this
> binding here might not, though, as it would be free to ignore the
> pwm-channels property.
> 
> Does that make sense? So to encourage future compatibility, can we drop
> the "else" branch?

Oh true, I see what you mean now with the example you gave. I wouldn't
respin for this alone, since the else branch could be dropped when
another user showed up given the driver doesn't restrict things.
I'm okay with your suggestion though.

Cheer,
Conor.
-------------- 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/20240201/ac68d5f9/attachment.sig>

From quic_abchauha at quicinc.com  Thu Feb  1 11:00:52 2024
From: quic_abchauha at quicinc.com (Abhishek Chauhan (ABC))
Date: Thu, 1 Feb 2024 11:00:52 -0800
Subject: [PATCH net-next 2/2] net: stmmac: TBS support for platform driver
In-Reply-To: <87a5okvbdt.fsf@geanix.com>
References: <20230927130919.25683-1-rohan.g.thomas@intel.com>
 <20230927130919.25683-3-rohan.g.thomas@intel.com>
 <92892988-bb77-4075-812e-19f6112f436e@quicinc.com>
 <87r0i44h8v.fsf@geanix.com>
 <5626e874-066c-4bf2-842d-a7f3387b6c1b@quicinc.com>
 <87a5okvbdt.fsf@geanix.com>
Message-ID: <c2497eef-1041-4cd0-8220-42622c8902f4@quicinc.com>



On 2/1/2024 12:26 AM, Esben Haabendal wrote:
> "Abhishek Chauhan (ABC)" <quic_abchauha at quicinc.com> writes:
>> On 1/26/2024 12:43 AM, Esben Haabendal wrote:
>>> "Abhishek Chauhan (ABC)" <quic_abchauha at quicinc.com> writes:
>>>
>>>> Qualcomm had similar discussions with respect to enabling of TBS for a
>>>> particular queue. We had similar discussion on these terms yesterday
>>>> with Redhat. Adding Andrew from Redhat here
>>>>
>>>> What we discovered as part of the discussions is listed below.
>>>>
>>>> 1. Today upstream stmmac code is designed in such a way that TBS flag
>>>> is put as part of queue configurations(see below snippet) and as well
>>>> know that stmmac queue configuration comes from the dtsi file.
>>>>
>>>> //ndo_open => stmmac_open
>>>> int tbs_en = priv->plat->tx_queues_cfg[chan].tbs_en;(comes from tx_queues_cfg)
>>>>
>>>> /* Setup per-TXQ tbs flag before TX descriptor alloc */
>>>> tx_q->tbs |= tbs_en ? STMMAC_TBS_AVAIL : 0;
>>>>
>>>> 2. There is a no way to do this dynamically from user space because
>>>> we don't have any API exposed which can do it from user space
>>>
>>> Not now. But why not extend ethtool API to allow enabling TBS for
>>> supported controllers?
>>
>> ethtool API can be implemented but that still doesn't solve the
>> problem of stopping the entire MAC block because of enhanced desc
>> allocation.
> 
> I am not sure what you exact point is here.
> 
> If you look at the implementation of ethtool API for changing ring
> parameters, you have stmmac_set_ringparam() which calls
> stmmac_reinit_ringparam(), which again calls stmmac_release() if the
> interface is up (stopping the entire MAC), and then stmmac_open() which
> reinitializes everything.
> 
> The same pattern could be applied to changes to enable enhanced
> descriptor allocation.
> 
> I don't see why that will not be acceptable. Why would anyone have to do
> that while critical traffic is flowing? In your system you should be
> able to know which queues needs enhanced descriptors before starting
> communication.
> 
>> 1. We can either allocate enhanced desc for all channels at bootup and
>> then choose to switch to enable TBS mode at runtime (Additional memory
>> usage)
> 
> A good default would IMHO be to enable enhanced descriptors for all but
> TX queue 0. This will allow use of TBS without needing to change
> anything. If the rather minimal extra memory usage is disturbing anyone,
> then they can tune it at boot time before bringing the interface up.
> 
>> 2. Live with the disruption of traffic for a brief duration of time.
>> Which is not a good solution for priority and critical traffic.
> 
> As mentioned above, I don't see why anyone would need to modify the
> descriptor allocation while critical traffic is flowing.
> 
> If you are able put this information in your device tree, you definitely
> will be able to put it in an boot script in some form.
> 
>>>> and also TBS rely on special descriptors aka enhanced desc this
>>>> cannot be done run time and stmmac has to be aware of it before we
>>>> do DMA/MAC/MTL start.
>>>
>>> Isn't this somewhat similar to changing the RX/TX ring parameters,
>>> which I believe also is quite difficult to do at run time, and
>>> ethtool therefore requires the interface to be down in oroer to
>>> change them?
>>>
>>>> To do this dynamically would only mean stopping DMA/MAC/MTL realloc
>>>> resources for enhanced desc and the starting MAC/DMA/MTL. This means
>>>> we are disrupting other traffic(By stopping MAC block).
>>>
>>> Yes. But you would be disrupting traffic less than by requiring a
>>> complete reboot of the target which is needed if the devicetree must be
>>> changed.
>>>
>> any DTS solution today anyway requires completely loading the boot
>> image and rebooting the device, but once the device is functional, End
>> user can activate TBS, as he knows the exact usecase and requirements.
>> I understand the solution is not scalable, but at this point we don't
>> have a solution to activate TBS at runtime.
> 
> Exactly. We are discussing a solution to activate enhanced descriptors
> at "runtime". But I propose to do it in a similar way as changing ring
> parameters, so it is in runtime seen from a CPU perspective, but the
> interface will be shortly brought down when changing it.
> 
>>>> 3. I dont think there is a way we can enable this dynamically today. I
>>>> would like upstream community to share your thoughts as well.
>>>
>>> Hereby done. Could we investigate the possibility of using ethtool to
>>> change TBS enable/disable "run-time"?
>>>
>> We can either allocate enhanced desc for all channels at bootup
>> and then choose to switch to enable TBS mode at runtime.
> 
> I think we should do something like this:
> https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=3b12ec8f618e
> 
> for all glue drivers, so a sane default is established that allows using
> TBS from boot up.
> 
> But in addition to that, I think it would make sense to create an
> ethtool API to change it from that default. And it will bring down the
> interface while applying the change.
> 

Agreed. Okay, We can go with this approach. I will evaluate the changes from ethtool perspective.
ethtool approach will be favorable to everyone as most of the users rely on ethtool to configure 
the NIC parameters. 

For now glue drivers can exclude queue0 for tbs and have all other queues to have tbs enabled.  

> /Esben


From conor at kernel.org  Thu Feb  1 11:13:29 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 1 Feb 2024 19:13:29 +0000
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <20240201183522.ssj553rwefr2wuqi@iaqt7>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-5-rogerq@kernel.org>
 <20240201-viewpoint-upload-fb714f650ff5@spud>
 <20240201-violet-chalice-51a73f113e7b@spud>
 <20240201183522.ssj553rwefr2wuqi@iaqt7>
Message-ID: <20240201-clad-unopposed-ccfdfe53b770@spud>

On Thu, Feb 01, 2024 at 12:35:22PM -0600, Bin Liu wrote:
> On Thu, Feb 01, 2024 at 06:18:05PM +0000, Conor Dooley wrote:
> > On Thu, Feb 01, 2024 at 06:15:20PM +0000, Conor Dooley wrote:
> > > On Thu, Feb 01, 2024 at 02:03:31PM +0200, Roger Quadros wrote:
> > > > So far this was not required but due to the newly identified
> > > > Errata i2409 [1] we need to poke this register space.
> > > > 
> > > > [1] https://www.ti.com/lit/er/sprz487d/sprz487d.pdf
> > > > 
> > > > Signed-off-by: Roger Quadros <rogerq at kernel.org>
> > > 
> > > Acked-by: Conor Dooley <conor.dooley at microchip.com>
> > 
> > Actually, where is the user for this that actually pokes the register
> > space?
> > You're adding another register region, so I went to check how you were
> > handling that in drivers, but there's no driver patch.
> 
> See Roger's another patch set 'Add workaround for Errata i2409' posted
> on 16th.

This patch should be with that series, not with these dts patches.

Thanks,
Conor.
-------------- 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/20240201/a63e7445/attachment.sig>

From b-brnich at ti.com  Thu Feb  1 11:13:50 2024
From: b-brnich at ti.com (Brnich, Brandon)
Date: Thu, 1 Feb 2024 19:13:50 +0000
Subject: [PATCH v3 1/6] arm64: dts: ti: k3-j784s4: Add Wave5 Video
 Encoder/Decoder Node
In-Reply-To: <a5f0059d-b80f-44e6-8c1e-793054586e0a@ti.com>
References: <20240131212625.1862775-1-b-brnich@ti.com>
 <20240131212625.1862775-2-b-brnich@ti.com>
 <a5f0059d-b80f-44e6-8c1e-793054586e0a@ti.com>
Message-ID: <a168bbdc2efd4cb1a71c6c6421dbd7ce@ti.com>

Hi Andrew,

> -----Original Message-----
> From: Davis, Andrew <afd at ti.com>
> Sent: Thursday, February 1, 2024 12:35 PM
> To: Brnich, Brandon <b-brnich at ti.com>; Menon, Nishanth <nm at ti.com>;
> Raghavendra, Vignesh <vigneshr at ti.com>; Tero Kristo <kristo at kernel.org>;
> Rob Herring <robh+dt at kernel.org>; Krzysztof Kozlowski
> <krzysztof.kozlowski+dt at linaro.org>; Conor Dooley <conor+dt at kernel.org>;
> Catalin Marinas <catalin.marinas at arm.com>; Will Deacon
> <will at kernel.org>; Bjorn Andersson <quic_bjorande at quicinc.com>; Geert
> Uytterhoeven <geert+renesas at glider.be>; Arnd Bergmann
> <arnd at arndb.de>; Konrad Dybcio <konrad.dybcio at linaro.org>; Neil
> Armstrong <neil.armstrong at linaro.org>; N?colas F . R . A . Prado
> <nfraprado at collabora.com>; Marek Szyprowski
> <m.szyprowski at samsung.com>; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; Etheridge, Darren
> <detheridge at ti.com>
> Subject: Re: [PATCH v3 1/6] arm64: dts: ti: k3-j784s4: Add Wave5 Video
> Encoder/Decoder Node
> 
> On 1/31/24 3:26 PM, Brandon Brnich wrote:
> > This patch adds support for the Wave521cl on the J784S4-evm.
> >
> > Signed-off-by: Brandon Brnich <b-brnich at ti.com>
> > ---
> >   arch/arm64/boot/dts/ti/k3-j784s4-evm.dts   |  8 ++++++++
> >   arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 20 ++++++++++++++++++++
> >   arch/arm64/boot/dts/ti/k3-j784s4.dtsi      |  2 ++
> >   3 files changed, 30 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
> > b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
> > index f34b92acc56d..7d37c11b4df4 100644
> > --- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
> > +++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
> > @@ -784,6 +784,14 @@ &main_gpio0 {
> >   	status = "okay";
> >   };
> >
> > +&vpu0 {
> > +	status = "okay";
> > +};
> > +
> > +&vpu1 {
> > +	status = "okay";
> > +};
> > +
> >   &mcu_cpsw {
> >   	status = "okay";
> >   	pinctrl-names = "default";
> > diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> > b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> > index f2b720ed1e4f..8b2623ac8160 100644
> > --- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> > @@ -662,6 +662,26 @@ main_i2c6: i2c at 2060000 {
> >   		status = "disabled";
> >   	};
> >
> > +	vpu0: video-codec at 4210000 {
> > +		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
> > +		reg = <0x00 0x4210000 0x00 0x10000>;
> > +		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&k3_clks 241 2>;
> > +		clock-names = "vcodec";
> > +		power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> 
> Why are these default disabled? I don't see anything missing that would
> need to be added at the board level. You disable them just to re-enable them
> in the next patch. Leave these default enabled.

I thought that disabled by default was the standard for node in dtsi files, where
they get specifically enabled in the particular dts file for the SoC.

In V4 I will remove the disabled by default. Should this apply to all platforms in
the series?
 
> > +	};
> > +
> > +	vpu1: video-codec at 4220000 {
> > +		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
> > +		reg = <0x00 0x4220000 0x00 0x10000>;
> > +		interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&k3_clks 242 2>;
> > +		clock-names = "vcodec";
> > +		power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> > +	};
> > +
> >   	main_sdhci0: mmc at 4f80000 {
> >   		compatible = "ti,j721e-sdhci-8bit";
> >   		reg = <0x00 0x04f80000 0x00 0x1000>, diff --git
> > a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
> > b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
> > index 4398c3a463e1..93bb0cba1b48 100644
> > --- a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
> > @@ -247,6 +247,8 @@ cbass_main: bus at 100000 {
> >   			 <0x00 0x30000000 0x00 0x30000000 0x00
> 0x0c400000>, /* MAIN NAVSS */
> >   			 <0x41 0x00000000 0x41 0x00000000 0x01
> 0x00000000>, /* PCIe1 DAT1 */
> >   			 <0x4e 0x20000000 0x4e 0x20000000 0x00
> 0x00080000>, /* GPU */
> > +			 <0x00 0x04210000 0x00 0x04210000 0x00
> 0x00010000>, /* VPU0 */
> > +			 <0x00 0x04220000 0x00 0x04220000 0x00
> 0x00010000>, /* VPU1 */
> 
> Add these in sorted by memory address order.

Will do in V4 as well.

> 
> Andrew
> 
> >
> >   			 /* MCUSS_WKUP Range */
> >   			 <0x00 0x28380000 0x00 0x28380000 0x00
> 0x03880000>,

Brandon

From devnull+arinc.unal.arinc9.com at kernel.org  Thu Feb  1 11:13:39 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Thu, 01 Feb 2024 22:13:39 +0300
Subject: [PATCH net RFC] net: dsa: mt7530: fix link-local frames that
 ingress vlan filtering ports
Message-ID: =?utf-8?q?=3C20240201-b4-for-net-mt7530-fix-link-local-that-ingr?=
 =?utf-8?q?ess-vlan-filtering-ports-v1-1-881c1c96b27f=40arinc9=2Ecom=3E?=

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

When a port is vlan filtering, the VLAN egress type of the CPU port is set
to stack mode. This is so that VLAN tags can be appended after hardware
special tag (called DSA tag in the context of Linux drivers). Because of
this, all frames egress the CPU port VLAN-tagged when vlan filtering is
enabled on a port.

This causes issues with link-local frames, specifically BPDUs, because the
software expects to receive them VLAN-untagged.

Set the egress VLAN tag to consistent for these frames so that they egress
the CPU port exactly as they ingress.

With this change, it can be observed that a bridge interface with stp_state
and vlan_filtering enabled will properly block ports now.

One remaining limitation is that the ingress port must have a PVID assigned
to it for the frame to be trapped to the CPU port. A PVID is set by default
on vlan aware and vlan unaware ports. However, when the network interface
that pertains to the ingress port is attached to a vlan_filtering enabled
bridge, the user can remove the PVID assignment from it which would prevent
the link-local frames from being trapped to the CPU port.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
I couldn't figure out a way to bypass VLAN table lookup for link-local
frames to directly trap them to the CPU port. The CPU port is hardcoded for
MT7530. For MT7531 and the switch on the MT7988 SoC, it depends on the port
matrix to choose the CPU port to trap the frames to. Port matrix and VLAN
table seem to go hand in hand so I don't know if this would even be
possible.

If possible to implement, link-local frames must not be influenced by the
VLAN table. They must always be trapped to the CPU port, and trapped
untagged.

Ar?n?
---
 drivers/net/dsa/mt7530.c | 23 +++++++++++++++--------
 drivers/net/dsa/mt7530.h |  8 +++++++-
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 3c1f657593a8..7ff1f8d7e4d6 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1001,16 +1001,23 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
 static void
 mt753x_trap_frames(struct mt7530_priv *priv)
 {
-	/* Trap BPDUs to the CPU port(s) */
-	mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
+	/* Trap 802.1X PAE frames and BPDUs to the CPU port(s) and egress them
+	 * exactly as they ingress.
+	 */
+	mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_EG_TAG_MASK |
+		   MT753X_PAE_PORT_FW_MASK | MT753X_BPDU_EG_TAG_MASK |
+		   MT753X_BPDU_PORT_FW_MASK,
+		   MT753X_PAE_EG_TAG(MT7530_VLAN_EG_CONSISTENT) |
+		   MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY) |
+		   MT753X_BPDU_EG_TAG(MT7530_VLAN_EG_CONSISTENT) |
 		   MT753X_BPDU_CPU_ONLY);
 
-	/* Trap 802.1X PAE frames to the CPU port(s) */
-	mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_PORT_FW_MASK,
-		   MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY));
-
-	/* Trap LLDP frames with :0E MAC DA to the CPU port(s) */
-	mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_PORT_FW_MASK,
+	/* Trap LLDP frames with :0E MAC DA to the CPU port(s) and egress them
+	 * exactly as they ingress.
+	 */
+	mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_EG_TAG_MASK |
+		   MT753X_R0E_PORT_FW_MASK,
+		   MT753X_R0E_EG_TAG(MT7530_VLAN_EG_CONSISTENT) |
 		   MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY));
 }
 
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 17e42d30fff4..e4e8f2484c25 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -65,12 +65,18 @@ enum mt753x_id {
 
 /* Registers for BPDU and PAE frame control*/
 #define MT753X_BPC			0x24
-#define  MT753X_BPDU_PORT_FW_MASK	GENMASK(2, 0)
+#define  MT753X_PAE_EG_TAG_MASK		GENMASK(24, 22)
+#define  MT753X_PAE_EG_TAG(x)		FIELD_PREP(MT753X_PAE_EG_TAG_MASK, x)
 #define  MT753X_PAE_PORT_FW_MASK	GENMASK(18, 16)
 #define  MT753X_PAE_PORT_FW(x)		FIELD_PREP(MT753X_PAE_PORT_FW_MASK, x)
+#define  MT753X_BPDU_EG_TAG_MASK	GENMASK(8, 6)
+#define  MT753X_BPDU_EG_TAG(x)		FIELD_PREP(MT753X_BPDU_EG_TAG_MASK, x)
+#define  MT753X_BPDU_PORT_FW_MASK	GENMASK(2, 0)
 
 /* Register for :03 and :0E MAC DA frame control */
 #define MT753X_RGAC2			0x2c
+#define  MT753X_R0E_EG_TAG_MASK		GENMASK(24, 22)
+#define  MT753X_R0E_EG_TAG(x)		FIELD_PREP(MT753X_R0E_EG_TAG_MASK, x)
 #define  MT753X_R0E_PORT_FW_MASK	GENMASK(18, 16)
 #define  MT753X_R0E_PORT_FW(x)		FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x)
 

---
base-commit: 4e192be1a225b7b1c4e315a44754312347628859
change-id: 20240201-b4-for-net-mt7530-fix-link-local-that-ingress-vlan-filtering-ports-6a2099e7ffb3

Best regards,
-- 
Ar?n? ?NAL <arinc.unal at arinc9.com>



From alchark at gmail.com  Thu Feb  1 11:15:28 2024
From: alchark at gmail.com (Alexey Charkov)
Date: Thu, 1 Feb 2024 23:15:28 +0400
Subject: [PATCH v2 2/4] arm64: dts: rockchip: enable temperature driven
 fan control on Rock 5B
In-Reply-To: <5e3e12d65e4919372e7fb02d56202393@manjaro.org>
References: <20240130-rk-dts-additions-v2-0-c6222c4c78df@gmail.com>
 <20240130-rk-dts-additions-v2-2-c6222c4c78df@gmail.com> <CAGb2v65--rgb2FqmG_0-w1-jUL0odqKXxiZJ-XPYA4uomfYmaQ@mail.gmail.com>
 <5e3e12d65e4919372e7fb02d56202393@manjaro.org>
Message-ID: <CABjd4Yx0kQ67fScrFVavjObMLaNt_PJ3TVOhLpCmj00Dx9dOqA@mail.gmail.com>

On Thu, Feb 1, 2024 at 9:34?PM Dragan Simic <dsimic at manjaro.org> wrote:
>
> Hello Chen-Yu,
>
> On 2024-02-01 15:26, Chen-Yu Tsai wrote:
> > On Wed, Jan 31, 2024 at 2:22?AM Alexey Charkov <alchark at gmail.com>
> > wrote:
> >>
> >> This enables thermal monitoring on Radxa Rock 5B and links the PWM
> >> fan as an active cooling device managed automatically by the thermal
> >> subsystem, with a target SoC temperature of 65C and a minimum-spin
> >> interval from 55C to 65C to ensure airflow when the system gets warm
> >>
> >> Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>
> >> Signed-off-by: Alexey Charkov <alchark at gmail.com>
> >> ---
> >>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 34
> >> ++++++++++++++++++++++++-
> >>  1 file changed, 33 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> >> b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> >> index a0e303c3a1dc..b485edeef876 100644
> >> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> >> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> >> @@ -52,7 +52,7 @@ led_rgb_b {
> >>
> >>         fan: pwm-fan {
> >>                 compatible = "pwm-fan";
> >> -               cooling-levels = <0 95 145 195 255>;
> >> +               cooling-levels = <0 120 150 180 210 240 255>;
> >>                 fan-supply = <&vcc5v0_sys>;
> >>                 pwms = <&pwm1 0 50000 0>;
> >>                 #cooling-cells = <2>;
> >> @@ -173,6 +173,34 @@ &cpu_l3 {
> >>         cpu-supply = <&vdd_cpu_lit_s0>;
> >>  };
> >>
> >> +&package_thermal {
> >> +       polling-delay = <1000>;
> >> +
> >> +       trips {
> >> +               package_fan0: package-fan0 {
> >> +                       temperature = <55000>;
> >> +                       hysteresis = <2000>;
> >> +                       type = "active";
> >> +               };
> >> +               package_fan1: package-fan1 {
> >> +                       temperature = <65000>;
> >> +                       hysteresis = <2000>;
> >> +                       type = "active";
> >> +               };
> >> +       };
> >> +
> >> +       cooling-maps {
> >> +               map0 {
> >> +                       trip = <&package_fan0>;
> >> +                       cooling-device = <&fan THERMAL_NO_LIMIT 1>;
> >> +               };
> >> +               map1 {
> >> +                       trip = <&package_fan1>;
> >> +                       cooling-device = <&fan 1 THERMAL_NO_LIMIT>;
> >> +               };
> >> +       };
> >> +};
> >> +
> >>  &i2c0 {
> >>         pinctrl-names = "default";
> >>         pinctrl-0 = <&i2c0m2_xfer>;
> >> @@ -731,6 +759,10 @@ regulator-state-mem {
> >>         };
> >>  };
> >>
> >> +&tsadc {
> >> +       status = "okay";
> >> +};
> >> +
> >
> > Is there any reason this can't be enabled by default in the .dtsi file?
> > The thermal sensor doesn't depend on anything external, so there should
> > be no reason to push this down to the board level.
>
> Actually, there is a reason.  Different boards can handle the critical
> overheating differently, by letting the CRU or the PMIC handle it.  This
> was also the case for the RK3399.
>
> Please, have a look at the following DT properties, which are consumed
> by drivers/thermal/rockchip_thermal.c:
>    - "rockchip,hw-tshut-mode"
>    - "rockchip,hw-tshut-polarity"
>
> See also page 1,372 of the RK3588 TRM v1.0.
>
> This has also reminded me to check how is the Rock 5B actually wired,
> just to make sure.  We actually need to provide the two DT properties
> listed above, at least to avoid emitting the warnings.

Well the defaults are already provided in rk3588s.dtsi, so there won't
be any warnings (see lines 2222-2223 in Linus' master version), and
according to the vendor kernel those are also what Rock 5B uses.

This made me think however: what if a board doesn't enable TSADC, but
has OPPs in place for higher voltage and frequency states? There won't
be any throttling (as there won't be any thermal monitoring) and there
might not be a critical shutdown at all if it heats up - possibly even
causing hardware damage. In this case it seems that having TSADC
enabled by default would at least trigger passive cooling, hopefully
avoiding the critical shutdown altogether and making those properties
irrelevant in 99% cases.

Best regards,
Alexey


From rafael at kernel.org  Thu Feb  1 11:24:15 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 1 Feb 2024 20:24:15 +0100
Subject: [PATCH v1 02/18] thermal: Add new structures and thermal_zone_device_register()
In-Reply-To: <20240130111250.185718-3-angelogioacchino.delregno@collabora.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com> <20240130111250.185718-3-angelogioacchino.delregno@collabora.com>
Message-ID: <CAJZ5v0jzaGpK8LnsFDtjuPoURrwrUgM1Z2QfZhK_FUzDeK3wcw@mail.gmail.com>

On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> In preparation for extending the thermal zone devices to actually
> have a name and disambiguate thermal zone types/names, and to do
> a reorganization in thermal_zone_device, add some new Thermal Zone
> structures:
>
> Introduce new thermal_governor_params, thermal_zone_platform_params
> and thermal_zone_device_params structures which are meant to hold
> the parameters for thermal zone registration and, in the future, to
> stop having a catch-all thermal_zone_device structure.
>
> While at it, also add a new thermal_zone_device_register() function
> which uses the new structure(s) for registration;
> the now old functions thermal_tripless_zone_device_register() and
> thermal_zone_device_register_with_trips() are now advertised as
> being deprecated and changed to instead act as wrappers around the
> new thermal_zone_device_register().
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/thermal/gov_power_allocator.c |  38 +++----
>  drivers/thermal/qcom/tsens.c          |   4 +-
>  drivers/thermal/thermal_core.c        | 146 ++++++++++++++++++--------
>  drivers/thermal/thermal_helpers.c     |   8 +-
>  drivers/thermal/thermal_sysfs.c       |  16 +--
>  include/linux/thermal.h               |  73 +++++++++++--
>  6 files changed, 202 insertions(+), 83 deletions(-)
>
> diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c
> index 81e061f183ad..3efbc60cd148 100644
> --- a/drivers/thermal/gov_power_allocator.c
> +++ b/drivers/thermal/gov_power_allocator.c
> @@ -167,14 +167,14 @@ static void estimate_pid_constants(struct thermal_zone_device *tz,
>         if (!temperature_threshold)
>                 return;
>
> -       tz->tzp->k_po = int_to_frac(sustainable_power) /
> +       tz->tgp->ipa_params.k_po = int_to_frac(sustainable_power) /

This is getting hard to read.

I would at least introduce a local zone_ipa_params and use it to refer
to this field:

zone_ipa_params->K-no = int_to_frac(sustainable_power) / temperature_threshold;

and analogously below.

>                 temperature_threshold;
>
> -       tz->tzp->k_pu = int_to_frac(2 * sustainable_power) /
> +       tz->tgp->ipa_params.k_pu = int_to_frac(2 * sustainable_power) /
>                 temperature_threshold;
>
> -       k_i = tz->tzp->k_pu / 10;
> -       tz->tzp->k_i = k_i > 0 ? k_i : 1;
> +       k_i = tz->tgp->ipa_params.k_pu / 10;
> +       tz->tgp->ipa_params.k_i = k_i > 0 ? k_i : 1;
>
>         /*
>          * The default for k_d and integral_cutoff is 0, so we can
> @@ -199,10 +199,10 @@ static u32 get_sustainable_power(struct thermal_zone_device *tz,
>  {
>         u32 sustainable_power;
>
> -       if (!tz->tzp->sustainable_power)
> +       if (!tz->tgp->ipa_params.sustainable_power)
>                 sustainable_power = estimate_sustainable_power(tz);
>         else
> -               sustainable_power = tz->tzp->sustainable_power;
> +               sustainable_power = tz->tgp->ipa_params.sustainable_power;
>
>         /* Check if it's init value 0 or there was update via sysfs */
>         if (sustainable_power != params->sustainable_power) {
> @@ -210,7 +210,7 @@ static u32 get_sustainable_power(struct thermal_zone_device *tz,
>                                        params->trip_switch_on, control_temp);
>
>                 /* Do the estimation only once and make available in sysfs */
> -               tz->tzp->sustainable_power = sustainable_power;
> +               tz->tgp->ipa_params.sustainable_power = sustainable_power;
>                 params->sustainable_power = sustainable_power;
>         }
>
> @@ -252,7 +252,7 @@ static u32 pid_controller(struct thermal_zone_device *tz,
>         err = int_to_frac(err);
>
>         /* Calculate the proportional term */
> -       p = mul_frac(err < 0 ? tz->tzp->k_po : tz->tzp->k_pu, err);
> +       p = mul_frac(err < 0 ? tz->tgp->ipa_params.k_po : tz->tgp->ipa_params.k_pu, err);
>
>         /*
>          * Calculate the integral term
> @@ -260,10 +260,10 @@ static u32 pid_controller(struct thermal_zone_device *tz,
>          * if the error is less than cut off allow integration (but
>          * the integral is limited to max power)
>          */
> -       i = mul_frac(tz->tzp->k_i, params->err_integral);
> +       i = mul_frac(tz->tgp->ipa_params.k_i, params->err_integral);
>
> -       if (err < int_to_frac(tz->tzp->integral_cutoff)) {
> -               s64 i_next = i + mul_frac(tz->tzp->k_i, err);
> +       if (err < int_to_frac(tz->tgp->ipa_params.integral_cutoff)) {
> +               s64 i_next = i + mul_frac(tz->tgp->ipa_params.k_i, err);
>
>                 if (abs(i_next) < max_power_frac) {
>                         i = i_next;
> @@ -278,7 +278,7 @@ static u32 pid_controller(struct thermal_zone_device *tz,
>          * error (i.e. driving closer to the line) results in less
>          * power being applied, slowing down the controller)
>          */
> -       d = mul_frac(tz->tzp->k_d, err - params->prev_err);
> +       d = mul_frac(tz->tgp->ipa_params.k_d, err - params->prev_err);
>         d = div_frac(d, jiffies_to_msecs(tz->passive_delay_jiffies));
>         params->prev_err = err;
>
> @@ -699,9 +699,9 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
>                 return ret;
>         }
>
> -       if (!tz->tzp) {
> -               tz->tzp = kzalloc(sizeof(*tz->tzp), GFP_KERNEL);
> -               if (!tz->tzp) {
> +       if (!tz->tgp) {
> +               tz->tgp = kzalloc(sizeof(*tz->tgp), GFP_KERNEL);
> +               if (!tz->tgp) {
>                         ret = -ENOMEM;
>                         goto free_params;
>                 }
> @@ -709,10 +709,10 @@ static int power_allocator_bind(struct thermal_zone_device *tz)
>                 params->allocated_tzp = true;
>         }
>
> -       if (!tz->tzp->sustainable_power)
> +       if (!tz->tgp->ipa_params.sustainable_power)
>                 dev_warn(&tz->device, "power_allocator: sustainable_power will be estimated\n");
>
> -       estimate_pid_constants(tz, tz->tzp->sustainable_power,
> +       estimate_pid_constants(tz, tz->tgp->ipa_params.sustainable_power,
>                                params->trip_switch_on,
>                                params->trip_max->temperature);
>
> @@ -736,8 +736,8 @@ static void power_allocator_unbind(struct thermal_zone_device *tz)
>         dev_dbg(&tz->device, "Unbinding from thermal zone %d\n", tz->id);
>
>         if (params->allocated_tzp) {
> -               kfree(tz->tzp);
> -               tz->tzp = NULL;
> +               kfree(tz->tgp);
> +               tz->tgp = NULL;
>         }
>
>         kfree(params->power);
> diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
> index 6d7c16ccb44d..9eddac93d683 100644
> --- a/drivers/thermal/qcom/tsens.c
> +++ b/drivers/thermal/qcom/tsens.c
> @@ -252,8 +252,8 @@ int tsens_read_calibration_legacy(struct tsens_priv *priv,
>  /*
>   * Use this function on devices where slope and offset calculations
>   * depend on calibration data read from qfprom. On others the slope
> - * and offset values are derived from tz->tzp->slope and tz->tzp->offset
> - * resp.
> + * and offset values are derived from tz->tgp->ipa_params.slope and
> + * tz->tgp->ipa_params.offset resp.
>   */
>  void compute_intercept_slope(struct tsens_priv *priv, u32 *p1,
>                              u32 *p2, u32 mode)
> diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> index dfaa6341694a..3150475b947f 100644
> --- a/drivers/thermal/thermal_core.c
> +++ b/drivers/thermal/thermal_core.c
> @@ -141,13 +141,13 @@ int thermal_register_governor(struct thermal_governor *governor)
>
>         list_for_each_entry(pos, &thermal_tz_list, node) {
>                 /*
> -                * only thermal zones with specified tz->tzp->governor_name
> +                * only thermal zones with specified tz->tgp->governor_name
>                  * may run with tz->govenor unset
>                  */
>                 if (pos->governor)
>                         continue;
>
> -               name = pos->tzp->governor_name;
> +               name = pos->tgp->governor_name;
>
>                 if (!strncasecmp(name, governor->name, THERMAL_NAME_LENGTH)) {
>                         int ret;
> @@ -1261,6 +1261,8 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_crit_temp);
>   *                whether trip points have been crossed (0 for interrupt
>   *                driven systems)
>   *
> + * This function is deprecated. See thermal_zone_device_register().
> + *
>   * This interface function adds a new thermal zone device (sensor) to
>   * /sys/class/thermal folder as thermal_zone[0-*]. It tries to bind all the
>   * thermal cooling devices registered at the same time.
> @@ -1277,19 +1279,80 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
>                                         const struct thermal_zone_params *tzp, int passive_delay,
>                                         int polling_delay)
>  {
> +       struct thermal_zone_device_params tzdp = {
> +               /* Thermal Zone Platform parameters */
> +               .tzp = {
> +                       .type = type,
> +                       .ops = ops,
> +                       .trips = trips,
> +                       .num_trips = num_trips,
> +                       .mask = mask,

I'm not sure about trips, num_trips and mask.

In the future, trips and mask will only be used once during zone
registration (and mask will probably go away entirely at one point)
and num_trips defines the shape of the zone, so to speak, so it makes
sense to pass it directly in the arg list.

> +                       .passive_delay = passive_delay,
> +                       .polling_delay = polling_delay,
> +                       .devdata = devdata
> +               },
> +       };
>         struct thermal_zone_device *tz;
> +
> +       /* Thermal Zone Governor parameters */
> +       if (tzp) {
> +               tzdp.tgp = kzalloc(sizeof(*tzdp.tgp), GFP_KERNEL);
> +               if (!tzdp.tgp)
> +                       return ERR_PTR(-ENOMEM);
> +
> +               tzdp.tgp->governor_name = tzp->governor_name;
> +               tzdp.tzp.no_hwmon = tzp->no_hwmon;
> +               memcpy(&tzdp.tgp->ipa_params, tzp, sizeof(*tzp));
> +       }
> +
> +       tz = thermal_zone_device_register(&tzdp);
> +       kfree(tzdp.tgp);
> +       return tz;
> +}
> +EXPORT_SYMBOL_GPL(thermal_zone_device_register_with_trips);
> +
> +/* This function is deprecated. See thermal_zone_device_register(). */

I'm not sure why you want to deprecate this function.

Tripless thermal zones are a special case and it makes sense to me to
register them in a special way.

> +struct thermal_zone_device *thermal_tripless_zone_device_register(
> +                                       const char *type,
> +                                       void *devdata,
> +                                       struct thermal_zone_device_ops *ops,
> +                                       const struct thermal_zone_params *tzp)
> +{
> +       return thermal_zone_device_register_with_trips(type, NULL, 0, 0, devdata,
> +                                                      ops, tzp, 0, 0);
> +}
> +EXPORT_SYMBOL_GPL(thermal_tripless_zone_device_register);
> +
> +/**
> + * thermal_zone_device_register() - register a new thermal zone device
> + * @tzdp:      Parameters of the new thermal zone device
> + *             See struct thermal_zone_device_register.

I don't quite agree that passing just one argument to this function is
an improvement.

First off, it is better to pass some values in the arg list just
because they will be only used once during registration and so it is
not useful to store them within the thermal zone object.  I mentioned
trips and mask above, but type is also copied into the thermal zone
object, so why to store a pointer to the original string?

> + *
> + * This interface function adds a new thermal zone device (sensor) to
> + * /sys/class/thermal folder as thermal_zone[0-*]. It tries to bind all the
> + * thermal cooling devices registered at the same time.
> + * thermal_zone_device_unregister() must be called when the device is no
> + * longer needed. The passive cooling depends on the .get_trend() return value.
> + *
> + * Return: a pointer to the created struct thermal_zone_device or an
> + * in case of error, an ERR_PTR. Caller must check return value with
> + * IS_ERR*() helpers.
> + */
> +struct thermal_zone_device *thermal_zone_device_register(struct thermal_zone_device_params *tzdp)
> +{
> +       struct thermal_zone_device *tz;
> +       struct thermal_governor *gov;
>         int id;
>         int result;
> -       struct thermal_governor *governor;
>
> -       if (!type || strlen(type) == 0) {
> +       if (!tzdp->tzp.type || strlen(tzdp->tzp.type) == 0) {
>                 pr_err("No thermal zone type defined\n");
>                 return ERR_PTR(-EINVAL);
>         }
>
> -       if (strlen(type) >= THERMAL_NAME_LENGTH) {
> +       if (strlen(tzdp->tzp.type) >= THERMAL_NAME_LENGTH) {
>                 pr_err("Thermal zone name (%s) too long, should be under %d chars\n",
> -                      type, THERMAL_NAME_LENGTH);
> +                      tzdp->tzp.type, THERMAL_NAME_LENGTH);
>                 return ERR_PTR(-EINVAL);
>         }
>
> @@ -1306,17 +1369,19 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
>          * Check will be true when the bit 31 of the mask is set.
>          * 32 bit shift will cause overflow of 4 byte integer.
>          */
> -       if (num_trips > (BITS_PER_TYPE(int) - 1) || num_trips < 0 || mask >> num_trips) {
> +       if (tzdp->tzp.num_trips > (BITS_PER_TYPE(int) - 1) ||
> +           tzdp->tzp.num_trips < 0 ||
> +           tzdp->tzp.mask >> tzdp->tzp.num_trips) {
>                 pr_err("Incorrect number of thermal trips\n");
>                 return ERR_PTR(-EINVAL);
>         }
>
> -       if (!ops || !ops->get_temp) {
> +       if (!tzdp->tzp.ops || !tzdp->tzp.ops->get_temp) {
>                 pr_err("Thermal zone device ops not defined\n");
>                 return ERR_PTR(-EINVAL);
>         }
>
> -       if (num_trips > 0 && !trips)
> +       if (tzdp->tzp.num_trips > 0 && !tzdp->tzp.trips)
>                 return ERR_PTR(-EINVAL);
>
>         if (!thermal_class)
> @@ -1326,11 +1391,17 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
>         if (!tz)
>                 return ERR_PTR(-ENOMEM);
>
> -       if (tzp) {
> -               tz->tzp = kmemdup(tzp, sizeof(*tzp), GFP_KERNEL);
> -               if (!tz->tzp) {
> +       tz->tzp = kmemdup(&tzdp->tzp, sizeof(tzdp->tzp), GFP_KERNEL);
> +       if (!tz->tzp) {
> +               result = -ENOMEM;
> +               goto free_tz;
> +       }
> +
> +       if (tzdp->tgp) {
> +               tz->tgp = kmemdup(tzdp->tgp, sizeof(*tzdp->tgp), GFP_KERNEL);
> +               if (!tz->tgp) {
>                         result = -ENOMEM;
> -                       goto free_tz;
> +                       goto free_tzp;
>                 }
>         }
>
> @@ -1342,27 +1413,27 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
>         id = ida_alloc(&thermal_tz_ida, GFP_KERNEL);
>         if (id < 0) {
>                 result = id;
> -               goto free_tzp;
> +               goto free_tgp;
>         }
>
>         tz->id = id;
> -       strscpy(tz->type, type, sizeof(tz->type));
> +       strscpy(tz->type, tzdp->tzp.type, sizeof(tz->type));
>
> -       if (!ops->critical)
> -               ops->critical = thermal_zone_device_critical;
> +       if (!tzdp->tzp.ops->critical)
> +               tzdp->tzp.ops->critical = thermal_zone_device_critical;
>
> -       tz->ops = ops;
> +       tz->ops = tzdp->tzp.ops;
>         tz->device.class = thermal_class;
> -       tz->devdata = devdata;
> -       tz->trips = trips;
> -       tz->num_trips = num_trips;
> +       tz->devdata = tzdp->tzp.devdata;
> +       tz->trips = tzdp->tzp.trips;
> +       tz->num_trips = tzdp->tzp.num_trips;
>
> -       thermal_set_delay_jiffies(&tz->passive_delay_jiffies, passive_delay);
> -       thermal_set_delay_jiffies(&tz->polling_delay_jiffies, polling_delay);
> +       thermal_set_delay_jiffies(&tz->passive_delay_jiffies, tzdp->tzp.passive_delay);
> +       thermal_set_delay_jiffies(&tz->polling_delay_jiffies, tzdp->tzp.polling_delay);
>
>         /* sys I/F */
>         /* Add nodes that are always present via .groups */
> -       result = thermal_zone_create_device_groups(tz, mask);
> +       result = thermal_zone_create_device_groups(tz, tzdp->tzp.mask);
>         if (result)
>                 goto remove_id;
>
> @@ -1381,12 +1452,12 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
>         /* Update 'this' zone's governor information */
>         mutex_lock(&thermal_governor_lock);
>
> -       if (tz->tzp)
> -               governor = __find_governor(tz->tzp->governor_name);
> +       if (tzdp->tgp)
> +               gov = __find_governor(tzdp->tgp->governor_name);
>         else
> -               governor = def_governor;
> +               gov = def_governor;
>
> -       result = thermal_set_governor(tz, governor);
> +       result = thermal_set_governor(tz, gov);
>         if (result) {
>                 mutex_unlock(&thermal_governor_lock);
>                 goto unregister;
> @@ -1394,7 +1465,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
>
>         mutex_unlock(&thermal_governor_lock);
>
> -       if (!tz->tzp || !tz->tzp->no_hwmon) {
> +       if (!tzdp->tzp.no_hwmon) {
>                 result = thermal_add_hwmon_sysfs(tz);
>                 if (result)
>                         goto unregister;
> @@ -1426,24 +1497,15 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
>         put_device(&tz->device);
>  remove_id:
>         ida_free(&thermal_tz_ida, id);
> +free_tgp:
> +       kfree(tz->tgp);
>  free_tzp:
>         kfree(tz->tzp);
>  free_tz:
>         kfree(tz);
>         return ERR_PTR(result);
>  }
> -EXPORT_SYMBOL_GPL(thermal_zone_device_register_with_trips);
> -
> -struct thermal_zone_device *thermal_tripless_zone_device_register(
> -                                       const char *type,
> -                                       void *devdata,
> -                                       struct thermal_zone_device_ops *ops,
> -                                       const struct thermal_zone_params *tzp)
> -{
> -       return thermal_zone_device_register_with_trips(type, NULL, 0, 0, devdata,
> -                                                      ops, tzp, 0, 0);
> -}
> -EXPORT_SYMBOL_GPL(thermal_tripless_zone_device_register);
> +EXPORT_SYMBOL_GPL(thermal_zone_device_register);
>
>  void *thermal_zone_device_priv(struct thermal_zone_device *tzd)
>  {
> @@ -1514,7 +1576,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
>
>         device_del(&tz->device);
>
> -       kfree(tz->tzp);
> +       kfree(tz->tgp);
>
>         put_device(&tz->device);
>
> diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c
> index 0329f4a71b02..a72095cfb771 100644
> --- a/drivers/thermal/thermal_helpers.c
> +++ b/drivers/thermal/thermal_helpers.c
> @@ -211,8 +211,8 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev)
>   */
>  int thermal_zone_get_slope(struct thermal_zone_device *tz)
>  {
> -       if (tz && tz->tzp)
> -               return tz->tzp->slope;
> +       if (tz && tz->tgp)
> +               return tz->tgp->ipa_params.slope;
>         return 1;
>  }
>  EXPORT_SYMBOL_GPL(thermal_zone_get_slope);
> @@ -226,8 +226,8 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_slope);
>   */
>  int thermal_zone_get_offset(struct thermal_zone_device *tz)
>  {
> -       if (tz && tz->tzp)
> -               return tz->tzp->offset;
> +       if (tz && tz->tgp)
> +               return tz->tgp->ipa_params.offset;
>         return 0;
>  }
>  EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
> diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
> index f4033865b093..3f5f4a04a754 100644
> --- a/drivers/thermal/thermal_sysfs.c
> +++ b/drivers/thermal/thermal_sysfs.c
> @@ -271,8 +271,8 @@ sustainable_power_show(struct device *dev, struct device_attribute *devattr,
>  {
>         struct thermal_zone_device *tz = to_thermal_zone(dev);
>
> -       if (tz->tzp)
> -               return sprintf(buf, "%u\n", tz->tzp->sustainable_power);
> +       if (tz->tgp)
> +               return sprintf(buf, "%u\n", tz->tgp->ipa_params.sustainable_power);
>         else
>                 return -EIO;
>  }
> @@ -284,13 +284,13 @@ sustainable_power_store(struct device *dev, struct device_attribute *devattr,
>         struct thermal_zone_device *tz = to_thermal_zone(dev);
>         u32 sustainable_power;
>
> -       if (!tz->tzp)
> +       if (!tz->tgp)
>                 return -EIO;
>
>         if (kstrtou32(buf, 10, &sustainable_power))
>                 return -EINVAL;
>
> -       tz->tzp->sustainable_power = sustainable_power;
> +       tz->tgp->ipa_params.sustainable_power = sustainable_power;
>
>         return count;
>  }
> @@ -302,8 +302,8 @@ sustainable_power_store(struct device *dev, struct device_attribute *devattr,
>         {                                                               \
>         struct thermal_zone_device *tz = to_thermal_zone(dev);          \
>                                                                         \
> -       if (tz->tzp)                                                    \
> -               return sprintf(buf, "%d\n", tz->tzp->name);             \
> +       if (tz->tgp)                                                    \
> +               return sprintf(buf, "%d\n", tz->tgp->ipa_params.name);  \
>         else                                                            \
>                 return -EIO;                                            \
>         }                                                               \
> @@ -315,13 +315,13 @@ sustainable_power_store(struct device *dev, struct device_attribute *devattr,
>                 struct thermal_zone_device *tz = to_thermal_zone(dev);  \
>                 s32 value;                                              \
>                                                                         \
> -               if (!tz->tzp)                                           \
> +               if (!tz->tgp)                                           \
>                         return -EIO;                                    \
>                                                                         \
>                 if (kstrtos32(buf, 10, &value))                         \
>                         return -EINVAL;                                 \
>                                                                         \
> -               tz->tzp->name = value;                                  \
> +               tz->tgp->ipa_params.name = value;                       \
>                                                                         \
>                 return count;                                           \
>         }                                                               \
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index 65d8f92a9a0d..7a540b746703 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -149,7 +149,8 @@ struct thermal_cooling_device {
>                         passive trip point.
>   * @need_update:       if equals 1, thermal_zone_device_update needs to be invoked.
>   * @ops:       operations this &thermal_zone_device supports
> - * @tzp:       thermal zone parameters
> + * @tzp:               Thermal zone parameters
> + * @tgp:               Thermal zone governor parameters
>   * @governor:  pointer to the governor for this thermal zone
>   * @governor_data:     private pointer for governor data
>   * @thermal_instances: list of &struct thermal_instance of this thermal zone
> @@ -184,7 +185,8 @@ struct thermal_zone_device {
>         int prev_high_trip;
>         atomic_t need_update;
>         struct thermal_zone_device_ops *ops;
> -       struct thermal_zone_params *tzp;
> +       struct thermal_zone_platform_params *tzp;
> +       struct thermal_governor_params *tgp;

I agree with doing a split here, but I'm not sure about moving items
from the arg list to struct thermal_zone_platform_params (as mentioned
above).

Also the naming is quite inconsistent.  IMO it would be better to call
the first pointer "tzpp", rename struct thermal_governor_params to
struct thermal_zone_governor_params and call the second pointer
"tzgp".

>         struct thermal_governor *governor;
>         void *governor_data;
>         struct list_head thermal_instances;
> @@ -224,15 +226,12 @@ struct thermal_governor {
>         struct list_head        governor_list;
>  };
>
> -/* Structure to define Thermal Zone parameters */
> +/* Structure to define Thermal Zone IPA parameters */
>  struct thermal_zone_params {
> +       /* Scheduled for removal - see struct thermal_governor_params. */
>         const char *governor_name;
>
> -       /*
> -        * a boolean to indicate if the thermal to hwmon sysfs interface
> -        * is required. when no_hwmon == false, a hwmon sysfs interface
> -        * will be created. when no_hwmon == true, nothing will be done
> -        */
> +       /* Scheduled for removal - see struct thermal_zone_platform_params. */
>         bool no_hwmon;
>
>         /*
> @@ -274,6 +273,58 @@ struct thermal_zone_params {
>         int offset;
>  };
>
> +/**
> + * struct thermal_governor_params - Thermal Zone governor parameters
> + * @governor_name:     Name of the Thermal Zone governor
> + * @ipa_params:                IPA parameters for Thermal Zone governors
> + */
> +struct thermal_governor_params {
> +       const char *governor_name;
> +       struct thermal_zone_params ipa_params;
> +};
> +
> +/**
> + * struct thermal_zone_platform_params - Thermal Zone parameters
> + * @type:              The thermal zone device type
> + * @ops:               Standard thermal zone device callbacks
> + * @trips:             Pointer to an array of thermal trips, if any
> + * @num_trips:         Number of trip points the thermal zone support
> + * @mask:              Bit string indicating the writeablility of trip points
> + * @passive_delay:     Number of milliseconds to wait between polls when
> + *                     performing passive cooling
> + * @polling_delay:     Number of milliseconds to wait between polls when checking
> + *                     whether trip points have been crossed (0 for interrupt
> + *                     driven systems)
> + * @devdata:           Private device data
> + * @no_hwmon:          Indicates whether the thermal to hwmon sysfs interface is
> + *                     required; this means that when no_hwmon == false, a hwmon
> + *                     sysfs interface will be created and when no_hwmon == true
> + *                     nothing will be done

Could this be the other way around?  So could this field be called
hwmon and could hwmon = true cause the hwmon sysfs i/f to be created?
It would be less confusing this way IMO.

> + */
> +struct thermal_zone_platform_params {
> +       const char *type;
> +       struct thermal_zone_device_ops *ops;
> +       struct thermal_trip *trips;
> +       int num_trips;
> +       int mask;

As I said above, IMO type, trips, num_trips and mask should stay in
the registration function arg list and not be stored in
thermal_zone_platform_params.

> +
> +       int passive_delay;
> +       int polling_delay;
> +
> +       void *devdata;

Same here.  It is just copied directly into tz during registration, so
why store a pointer to it in the params structure?

And same for ops probably.

> +       bool no_hwmon;
> +};
> +
> +/**
> + * struct thermal_zone_device_params - Thermal Zone device parameters
> + * @tzp:               Thermal zone platform parameters
> + * @tgp:               Thermal zone governor parameters
> + */
> +struct thermal_zone_device_params {
> +       struct thermal_zone_platform_params tzp;
> +       struct thermal_governor_params *tgp;
> +};
> +
>  /* Function declarations */
>  #ifdef CONFIG_THERMAL_OF
>  struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, int id, void *data,
> @@ -328,6 +379,8 @@ struct thermal_zone_device *thermal_tripless_zone_device_register(
>                                         struct thermal_zone_device_ops *ops,
>                                         const struct thermal_zone_params *tzp);
>
> +struct thermal_zone_device *thermal_zone_device_register(struct thermal_zone_device_params *tzdp);
> +
>  void thermal_zone_device_unregister(struct thermal_zone_device *tz);
>
>  void *thermal_zone_device_priv(struct thermal_zone_device *tzd);
> @@ -390,6 +443,10 @@ static inline struct thermal_zone_device *thermal_tripless_zone_device_register(
>                                         const struct thermal_zone_params *tzp)
>  { return ERR_PTR(-ENODEV); }
>
> +static inline struct thermal_zone_device *thermal_zone_device_register(
> +                                       struct thermal_zone_device_params *tzdp)
> +{ return ERR_PTR(-ENODEV); }
> +
>  static inline void thermal_zone_device_unregister(struct thermal_zone_device *tz)
>  { }
>
> --


From robh at kernel.org  Thu Feb  1 11:29:30 2024
From: robh at kernel.org (Rob Herring)
Date: Thu,  1 Feb 2024 13:29:30 -0600
Subject: [PATCH] soc: fsl: qbman: Remove RESERVEDMEM_OF_DECLARE usage
Message-ID: <20240201192931.1324130-1-robh@kernel.org>

There is no reason to use RESERVEDMEM_OF_DECLARE() as the initialization
hook just saves off the base address and size. Use of
RESERVEDMEM_OF_DECLARE() is reserved for non-driver code and
initialization which must be done early. For qbman, retrieving the
address and size can be done in probe just as easily.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 drivers/soc/fsl/qbman/bman_ccsr.c | 27 +++---------
 drivers/soc/fsl/qbman/dpaa_sys.c  | 12 +++--
 drivers/soc/fsl/qbman/dpaa_sys.h  |  4 +-
 drivers/soc/fsl/qbman/qman_ccsr.c | 73 ++++++++++---------------------
 4 files changed, 38 insertions(+), 78 deletions(-)

diff --git a/drivers/soc/fsl/qbman/bman_ccsr.c b/drivers/soc/fsl/qbman/bman_ccsr.c
index cb24a08be084..b0f26f6f731e 100644
--- a/drivers/soc/fsl/qbman/bman_ccsr.c
+++ b/drivers/soc/fsl/qbman/bman_ccsr.c
@@ -144,17 +144,6 @@ static int bm_set_memory(u64 ba, u32 size)
 static dma_addr_t fbpr_a;
 static size_t fbpr_sz;
 
-static int bman_fbpr(struct reserved_mem *rmem)
-{
-	fbpr_a = rmem->base;
-	fbpr_sz = rmem->size;
-
-	WARN_ON(!(fbpr_a && fbpr_sz));
-
-	return 0;
-}
-RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr);
-
 static irqreturn_t bman_isr(int irq, void *ptr)
 {
 	u32 isr_val, ier_val, ecsr_val, isr_mask, i;
@@ -242,17 +231,11 @@ static int fsl_bman_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	/*
-	 * If FBPR memory wasn't defined using the qbman compatible string
-	 * try using the of_reserved_mem_device method
-	 */
-	if (!fbpr_a) {
-		ret = qbman_init_private_mem(dev, 0, &fbpr_a, &fbpr_sz);
-		if (ret) {
-			dev_err(dev, "qbman_init_private_mem() failed 0x%x\n",
-				ret);
-			return -ENODEV;
-		}
+	ret = qbman_init_private_mem(dev, 0, "fsl,bman-fbpr", &fbpr_a, &fbpr_sz);
+	if (ret) {
+		dev_err(dev, "qbman_init_private_mem() failed 0x%x\n",
+			ret);
+		return -ENODEV;
 	}
 
 	dev_dbg(dev, "Allocated FBPR 0x%llx 0x%zx\n", fbpr_a, fbpr_sz);
diff --git a/drivers/soc/fsl/qbman/dpaa_sys.c b/drivers/soc/fsl/qbman/dpaa_sys.c
index 33751450047e..e1d7b79cc450 100644
--- a/drivers/soc/fsl/qbman/dpaa_sys.c
+++ b/drivers/soc/fsl/qbman/dpaa_sys.c
@@ -34,8 +34,8 @@
 /*
  * Initialize a devices private memory region
  */
-int qbman_init_private_mem(struct device *dev, int idx, dma_addr_t *addr,
-				size_t *size)
+int qbman_init_private_mem(struct device *dev, int idx, const char *compat,
+			   dma_addr_t *addr, size_t *size)
 {
 	struct device_node *mem_node;
 	struct reserved_mem *rmem;
@@ -44,8 +44,12 @@ int qbman_init_private_mem(struct device *dev, int idx, dma_addr_t *addr,
 
 	mem_node = of_parse_phandle(dev->of_node, "memory-region", idx);
 	if (!mem_node) {
-		dev_err(dev, "No memory-region found for index %d\n", idx);
-		return -ENODEV;
+		mem_node = of_find_compatible_node(NULL, NULL, compat);
+		if (!mem_node) {
+			dev_err(dev, "No memory-region found for index %d or compatible '%s'\n",
+				idx, compat);
+			return -ENODEV;
+		}
 	}
 
 	rmem = of_reserved_mem_lookup(mem_node);
diff --git a/drivers/soc/fsl/qbman/dpaa_sys.h b/drivers/soc/fsl/qbman/dpaa_sys.h
index ae8afa552b1e..16485bde9636 100644
--- a/drivers/soc/fsl/qbman/dpaa_sys.h
+++ b/drivers/soc/fsl/qbman/dpaa_sys.h
@@ -101,8 +101,8 @@ static inline u8 dpaa_cyc_diff(u8 ringsize, u8 first, u8 last)
 #define DPAA_GENALLOC_OFF	0x80000000
 
 /* Initialize the devices private memory region */
-int qbman_init_private_mem(struct device *dev, int idx, dma_addr_t *addr,
-				size_t *size);
+int qbman_init_private_mem(struct device *dev, int idx, const char *compat,
+			   dma_addr_t *addr, size_t *size);
 
 /* memremap() attributes for different platforms */
 #ifdef CONFIG_PPC
diff --git a/drivers/soc/fsl/qbman/qman_ccsr.c b/drivers/soc/fsl/qbman/qman_ccsr.c
index 157659fd033a..392e54f14dbe 100644
--- a/drivers/soc/fsl/qbman/qman_ccsr.c
+++ b/drivers/soc/fsl/qbman/qman_ccsr.c
@@ -468,28 +468,6 @@ static int zero_priv_mem(phys_addr_t addr, size_t sz)
 
 	return 0;
 }
-
-static int qman_fqd(struct reserved_mem *rmem)
-{
-	fqd_a = rmem->base;
-	fqd_sz = rmem->size;
-
-	WARN_ON(!(fqd_a && fqd_sz));
-	return 0;
-}
-RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd);
-
-static int qman_pfdr(struct reserved_mem *rmem)
-{
-	pfdr_a = rmem->base;
-	pfdr_sz = rmem->size;
-
-	WARN_ON(!(pfdr_a && pfdr_sz));
-
-	return 0;
-}
-RESERVEDMEM_OF_DECLARE(qman_pfdr, "fsl,qman-pfdr", qman_pfdr);
-
 #endif
 
 unsigned int qm_get_fqid_maxcnt(void)
@@ -796,39 +774,34 @@ static int fsl_qman_probe(struct platform_device *pdev)
 		qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
 	}
 
-	if (fqd_a) {
+	/*
+	* Order of memory regions is assumed as FQD followed by PFDR
+	* in order to ensure allocations from the correct regions the
+	* driver initializes then allocates each piece in order
+	*/
+	ret = qbman_init_private_mem(dev, 0, "fsl,qman-fqd", &fqd_a, &fqd_sz);
+	if (ret) {
+		dev_err(dev, "qbman_init_private_mem() for FQD failed 0x%x\n",
+			ret);
+		return -ENODEV;
+	}
 #ifdef CONFIG_PPC
-		/*
-		 * For PPC backward DT compatibility
-		 * FQD memory MUST be zero'd by software
-		 */
-		zero_priv_mem(fqd_a, fqd_sz);
+	/*
+	 * For PPC backward DT compatibility
+	 * FQD memory MUST be zero'd by software
+	 */
+	zero_priv_mem(fqd_a, fqd_sz);
 #else
-		WARN(1, "Unexpected architecture using non shared-dma-mem reservations");
+	WARN(1, "Unexpected architecture using non shared-dma-mem reservations");
 #endif
-	} else {
-		/*
-		 * Order of memory regions is assumed as FQD followed by PFDR
-		 * in order to ensure allocations from the correct regions the
-		 * driver initializes then allocates each piece in order
-		 */
-		ret = qbman_init_private_mem(dev, 0, &fqd_a, &fqd_sz);
-		if (ret) {
-			dev_err(dev, "qbman_init_private_mem() for FQD failed 0x%x\n",
-				ret);
-			return -ENODEV;
-		}
-	}
 	dev_dbg(dev, "Allocated FQD 0x%llx 0x%zx\n", fqd_a, fqd_sz);
 
-	if (!pfdr_a) {
-		/* Setup PFDR memory */
-		ret = qbman_init_private_mem(dev, 1, &pfdr_a, &pfdr_sz);
-		if (ret) {
-			dev_err(dev, "qbman_init_private_mem() for PFDR failed 0x%x\n",
-				ret);
-			return -ENODEV;
-		}
+	/* Setup PFDR memory */
+	ret = qbman_init_private_mem(dev, 1, "fsl,qman-pfdr", &pfdr_a, &pfdr_sz);
+	if (ret) {
+		dev_err(dev, "qbman_init_private_mem() for PFDR failed 0x%x\n",
+			ret);
+		return -ENODEV;
 	}
 	dev_dbg(dev, "Allocated PFDR 0x%llx 0x%zx\n", pfdr_a, pfdr_sz);
 
-- 
2.43.0



From dsimic at manjaro.org  Thu Feb  1 11:31:43 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu, 01 Feb 2024 20:31:43 +0100
Subject: [PATCH v2 2/4] arm64: dts: rockchip: enable temperature driven
 fan control on Rock 5B
In-Reply-To: <CABjd4Yx0kQ67fScrFVavjObMLaNt_PJ3TVOhLpCmj00Dx9dOqA@mail.gmail.com>
References: <20240130-rk-dts-additions-v2-0-c6222c4c78df@gmail.com>
 <20240130-rk-dts-additions-v2-2-c6222c4c78df@gmail.com>
 <CAGb2v65--rgb2FqmG_0-w1-jUL0odqKXxiZJ-XPYA4uomfYmaQ@mail.gmail.com>
 <5e3e12d65e4919372e7fb02d56202393@manjaro.org>
 <CABjd4Yx0kQ67fScrFVavjObMLaNt_PJ3TVOhLpCmj00Dx9dOqA@mail.gmail.com>
Message-ID: <a8aa04ca0061cd09c7b3eb5336e534a4@manjaro.org>

On 2024-02-01 20:15, Alexey Charkov wrote:
> On Thu, Feb 1, 2024 at 9:34?PM Dragan Simic <dsimic at manjaro.org> wrote:
>> On 2024-02-01 15:26, Chen-Yu Tsai wrote:
>> > On Wed, Jan 31, 2024 at 2:22?AM Alexey Charkov <alchark at gmail.com>
>> > wrote:
>> >>
>> >> This enables thermal monitoring on Radxa Rock 5B and links the PWM
>> >> fan as an active cooling device managed automatically by the thermal
>> >> subsystem, with a target SoC temperature of 65C and a minimum-spin
>> >> interval from 55C to 65C to ensure airflow when the system gets warm
>> >>
>> >> Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>
>> >> Signed-off-by: Alexey Charkov <alchark at gmail.com>
>> >> ---
>> >>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 34
>> >> ++++++++++++++++++++++++-
>> >>  1 file changed, 33 insertions(+), 1 deletion(-)
>> >>
>> >> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> >> b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> >> index a0e303c3a1dc..b485edeef876 100644
>> >> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> >> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> >> @@ -52,7 +52,7 @@ led_rgb_b {
>> >>
>> >>         fan: pwm-fan {
>> >>                 compatible = "pwm-fan";
>> >> -               cooling-levels = <0 95 145 195 255>;
>> >> +               cooling-levels = <0 120 150 180 210 240 255>;
>> >>                 fan-supply = <&vcc5v0_sys>;
>> >>                 pwms = <&pwm1 0 50000 0>;
>> >>                 #cooling-cells = <2>;
>> >> @@ -173,6 +173,34 @@ &cpu_l3 {
>> >>         cpu-supply = <&vdd_cpu_lit_s0>;
>> >>  };
>> >>
>> >> +&package_thermal {
>> >> +       polling-delay = <1000>;
>> >> +
>> >> +       trips {
>> >> +               package_fan0: package-fan0 {
>> >> +                       temperature = <55000>;
>> >> +                       hysteresis = <2000>;
>> >> +                       type = "active";
>> >> +               };
>> >> +               package_fan1: package-fan1 {
>> >> +                       temperature = <65000>;
>> >> +                       hysteresis = <2000>;
>> >> +                       type = "active";
>> >> +               };
>> >> +       };
>> >> +
>> >> +       cooling-maps {
>> >> +               map0 {
>> >> +                       trip = <&package_fan0>;
>> >> +                       cooling-device = <&fan THERMAL_NO_LIMIT 1>;
>> >> +               };
>> >> +               map1 {
>> >> +                       trip = <&package_fan1>;
>> >> +                       cooling-device = <&fan 1 THERMAL_NO_LIMIT>;
>> >> +               };
>> >> +       };
>> >> +};
>> >> +
>> >>  &i2c0 {
>> >>         pinctrl-names = "default";
>> >>         pinctrl-0 = <&i2c0m2_xfer>;
>> >> @@ -731,6 +759,10 @@ regulator-state-mem {
>> >>         };
>> >>  };
>> >>
>> >> +&tsadc {
>> >> +       status = "okay";
>> >> +};
>> >> +
>> >
>> > Is there any reason this can't be enabled by default in the .dtsi file?
>> > The thermal sensor doesn't depend on anything external, so there should
>> > be no reason to push this down to the board level.
>> 
>> Actually, there is a reason.  Different boards can handle the critical
>> overheating differently, by letting the CRU or the PMIC handle it.  
>> This
>> was also the case for the RK3399.
>> 
>> Please, have a look at the following DT properties, which are consumed
>> by drivers/thermal/rockchip_thermal.c:
>>    - "rockchip,hw-tshut-mode"
>>    - "rockchip,hw-tshut-polarity"
>> 
>> See also page 1,372 of the RK3588 TRM v1.0.
>> 
>> This has also reminded me to check how is the Rock 5B actually wired,
>> just to make sure.  We actually need to provide the two DT properties
>> listed above, at least to avoid emitting the warnings.
> 
> Well the defaults are already provided in rk3588s.dtsi, so there won't
> be any warnings (see lines 2222-2223 in Linus' master version), and
> according to the vendor kernel those are also what Rock 5B uses.

Yes, I noticed the same a couple of minutes after sending my last
message, but didn't want to make more noise about it. :)  I would've
mentioned it in my next message, of course.

> This made me think however: what if a board doesn't enable TSADC, but
> has OPPs in place for higher voltage and frequency states? There won't
> be any throttling (as there won't be any thermal monitoring) and there
> might not be a critical shutdown at all if it heats up - possibly even
> causing hardware damage. In this case it seems that having TSADC
> enabled by default would at least trigger passive cooling, hopefully
> avoiding the critical shutdown altogether and making those properties
> irrelevant in 99% cases.

Those are very good questions.  Thumbs up!

The trouble is that the boards can use different wiring to handle the
thermal runaways, by expecting the PMIC to handle it or not.  Thus,
it's IMHO better to simply leave that to be tested and enabled on a
board-by-board basis, whenever a new RK3588(s)-based board is added.

Thus, the only right way at this point would be to merge the addition
of the OPPs and the enabling of the TSADC for all currently supported
RK3588(s)-based boards at once, instead of just for the Rock 5B.

I can handle the required changes for the QuartzPro64 dts file.  For
other supported RK3588(s)-based boards, if there are no people having
access to them and willing to perform the dts changes and the testing,
I'd be willing to go through the board schematics, to enable the
TSADC for them as well.


From Frank.li at nxp.com  Thu Feb  1 11:34:34 2024
From: Frank.li at nxp.com (Frank Li)
Date: Thu, 1 Feb 2024 14:34:34 -0500
Subject: [PATCH v9 00/16] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <ZbJ+tFPn3aOYHCwf@lizhi-Precision-Tower-5810>
References: <20240119171122.3057511-1-Frank.Li@nxp.com>
 <ZbJ+tFPn3aOYHCwf@lizhi-Precision-Tower-5810>
Message-ID: <ZbvySvCoeNbBxYjW@lizhi-Precision-Tower-5810>

On Thu, Jan 25, 2024 at 10:31:00AM -0500, Frank Li wrote:
> On Fri, Jan 19, 2024 at 12:11:06PM -0500, Frank Li wrote:
> > first 6 patches use drvdata: flags to simplify some switch-case code.
> > Improve maintaince and easy to read code.
> 
> @lpieralisi:
> 
> 	Could you please pick up these patches? All already reviewed by
> Mani. dt-binding part acked by rob/krzysztof. Add it only impact freecale
> imx platform.
> 
> Frank

@lpieralisi at kernel.org

Ping!

Frank

> 
> > 
> > Then add imx95 basic pci host function.
> > 
> > follow two patch do endpoint code clean up.
> > Then add imx95 basic endpont function.
> > 
> > Compared with v2, added EP function support and some fixes,  please change
> > notes at each patches.
> > 
> > dt-binding pass pcie node:
> > 
> > pcie0: pcie at 4c300000 {
> >                         compatible = "fsl,imx95-pcie";
> >                         reg = <0 0x4c300000 0 0x40000>,
> >                                 <0 0x4c360000 0 0x10000>,
> >                                 <0 0x4c340000 0 0x20000>,
> >                                 <0 0x60100000 0 0xfe00000>;
> >                         reg-names = "dbi", "atu", "app", "config";
> >                         #address-cells = <3>;
> >                         #size-cells = <2>;
> >                         device_type = "pci";
> >                         linux,pci-domain = <0>;
> >                         bus-range = <0x00 0xff>;
> >                         ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
> >                                  <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
> >                         num-lanes = <1>;
> >                         num-viewport = <8>;
> >                         interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
> >                         interrupt-names = "msi";
> >                         #interrupt-cells = <1>;
> >                         interrupt-map-mask = <0 0 0 0x7>;
> >                         interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0 0 0 2 &gic 0 0 GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0 0 0 3 &gic 0 0 GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0 0 0 4 &gic 0 0 GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
> >                         fsl,max-link-speed = <3>;
> >                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
> >                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
> >                         assigned-clock-parents = <0>, <0>,
> >                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
> >                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> >                         /* 0x30~0x37 stream id for pci0 */
> >                         /*
> >                          * iommu-map = <0x000 &apps_smmu 0x30 0x1>,
> >                          * <0x100 &apps_smmu 0x31 0x1>;
> >                          */
> >                         status = "disabled";
> >                 };
> > 
> > pcie1: pcie-ep at 4c380000 {
> >                         compatible = "fsl,imx95-pcie-ep";
> >                         reg = <0 0x4c380000 0 0x20000>,
> >                               <0 0x4c3e0000 0 0x1000>,
> >                               <0 0x4c3a0000 0 0x1000>,
> >                               <0 0x4c3c0000 0 0x10000>,
> >                               <0 0x4c3f0000 0 0x10000>,
> >                               <0xa 0 1 0>;
> >                         reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
> >                         interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
> >                         interrupt-names = "dma";
> >                         fsl,max-link-speed = <3>;
> >                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
> >                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
> >                         assigned-clock-parents = <0>, <0>,
> >                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
> >                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> >                         status = "disabled";
> >                 };
> > 
> > Frank Li (15):
> >   PCI: imx6: Simplify clock handling by using clk_bulk*() function
> >   PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
> >   PCI: imx6: Simplify reset handling by using by using
> >     *_FLAG_HAS_*_RESET
> >   dt-bindings: imx6q-pcie: Add linux,pci-domain as required for iMX8MQ
> >   PCI: imx6: Using "linux,pci-domain" as slot ID
> >   PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
> >   PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
> >   PCI: imx6: Simplify switch-case logic by involve init_phy callback
> >   dt-bindings: imx6q-pcie: Clean up irrationality clocks check
> >   dt-bindings: imx6q-pcie: Restruct reg and reg-name
> >   PCI: imx6: Add iMX95 PCIe Root Complex support
> >   PCI: imx6: Clean up get addr_space code
> >   PCI: imx6: Add epc_features in imx6_pcie_drvdata
> >   dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
> >   PCI: imx6: Add iMX95 Endpoint (EP) support
> > 
> > Richard Zhu (1):
> >   dt-bindings: imx6q-pcie: Add imx95 pcie compatible string
> > 
> >  .../bindings/pci/fsl,imx6q-pcie-common.yaml   |  28 +-
> >  .../bindings/pci/fsl,imx6q-pcie-ep.yaml       |  57 +-
> >  .../bindings/pci/fsl,imx6q-pcie.yaml          |  49 +-
> >  drivers/pci/controller/dwc/pci-imx6.c         | 640 ++++++++++--------
> >  4 files changed, 462 insertions(+), 312 deletions(-)
> > 
> > -- 
> > 2.34.1
> > 


From dsimic at manjaro.org  Thu Feb  1 11:43:01 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu, 01 Feb 2024 20:43:01 +0100
Subject: [PATCH v2 2/4] arm64: dts: rockchip: enable temperature driven
 fan control on Rock 5B
In-Reply-To: <a8aa04ca0061cd09c7b3eb5336e534a4@manjaro.org>
References: <20240130-rk-dts-additions-v2-0-c6222c4c78df@gmail.com>
 <20240130-rk-dts-additions-v2-2-c6222c4c78df@gmail.com>
 <CAGb2v65--rgb2FqmG_0-w1-jUL0odqKXxiZJ-XPYA4uomfYmaQ@mail.gmail.com>
 <5e3e12d65e4919372e7fb02d56202393@manjaro.org>
 <CABjd4Yx0kQ67fScrFVavjObMLaNt_PJ3TVOhLpCmj00Dx9dOqA@mail.gmail.com>
 <a8aa04ca0061cd09c7b3eb5336e534a4@manjaro.org>
Message-ID: <bd6e93cf907572e86697dc10a50bfe66@manjaro.org>

On 2024-02-01 20:31, Dragan Simic wrote:
> On 2024-02-01 20:15, Alexey Charkov wrote:
>> On Thu, Feb 1, 2024 at 9:34?PM Dragan Simic <dsimic at manjaro.org> 
>> wrote:
>>> On 2024-02-01 15:26, Chen-Yu Tsai wrote:
>>> > On Wed, Jan 31, 2024 at 2:22?AM Alexey Charkov <alchark at gmail.com>
>>> > wrote:
>>> >>
>>> >> This enables thermal monitoring on Radxa Rock 5B and links the PWM
>>> >> fan as an active cooling device managed automatically by the thermal
>>> >> subsystem, with a target SoC temperature of 65C and a minimum-spin
>>> >> interval from 55C to 65C to ensure airflow when the system gets warm
>>> >>
>>> >> Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>
>>> >> Signed-off-by: Alexey Charkov <alchark at gmail.com>
>>> >> ---
>>> >>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 34
>>> >> ++++++++++++++++++++++++-
>>> >>  1 file changed, 33 insertions(+), 1 deletion(-)
>>> >>
>>> >> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>>> >> b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>>> >> index a0e303c3a1dc..b485edeef876 100644
>>> >> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>>> >> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>>> >> @@ -52,7 +52,7 @@ led_rgb_b {
>>> >>
>>> >>         fan: pwm-fan {
>>> >>                 compatible = "pwm-fan";
>>> >> -               cooling-levels = <0 95 145 195 255>;
>>> >> +               cooling-levels = <0 120 150 180 210 240 255>;
>>> >>                 fan-supply = <&vcc5v0_sys>;
>>> >>                 pwms = <&pwm1 0 50000 0>;
>>> >>                 #cooling-cells = <2>;
>>> >> @@ -173,6 +173,34 @@ &cpu_l3 {
>>> >>         cpu-supply = <&vdd_cpu_lit_s0>;
>>> >>  };
>>> >>
>>> >> +&package_thermal {
>>> >> +       polling-delay = <1000>;
>>> >> +
>>> >> +       trips {
>>> >> +               package_fan0: package-fan0 {
>>> >> +                       temperature = <55000>;
>>> >> +                       hysteresis = <2000>;
>>> >> +                       type = "active";
>>> >> +               };
>>> >> +               package_fan1: package-fan1 {
>>> >> +                       temperature = <65000>;
>>> >> +                       hysteresis = <2000>;
>>> >> +                       type = "active";
>>> >> +               };
>>> >> +       };
>>> >> +
>>> >> +       cooling-maps {
>>> >> +               map0 {
>>> >> +                       trip = <&package_fan0>;
>>> >> +                       cooling-device = <&fan THERMAL_NO_LIMIT 1>;
>>> >> +               };
>>> >> +               map1 {
>>> >> +                       trip = <&package_fan1>;
>>> >> +                       cooling-device = <&fan 1 THERMAL_NO_LIMIT>;
>>> >> +               };
>>> >> +       };
>>> >> +};
>>> >> +
>>> >>  &i2c0 {
>>> >>         pinctrl-names = "default";
>>> >>         pinctrl-0 = <&i2c0m2_xfer>;
>>> >> @@ -731,6 +759,10 @@ regulator-state-mem {
>>> >>         };
>>> >>  };
>>> >>
>>> >> +&tsadc {
>>> >> +       status = "okay";
>>> >> +};
>>> >> +
>>> >
>>> > Is there any reason this can't be enabled by default in the .dtsi file?
>>> > The thermal sensor doesn't depend on anything external, so there should
>>> > be no reason to push this down to the board level.
>>> 
>>> Actually, there is a reason.  Different boards can handle the 
>>> critical
>>> overheating differently, by letting the CRU or the PMIC handle it.  
>>> This
>>> was also the case for the RK3399.
>>> 
>>> Please, have a look at the following DT properties, which are 
>>> consumed
>>> by drivers/thermal/rockchip_thermal.c:
>>>    - "rockchip,hw-tshut-mode"
>>>    - "rockchip,hw-tshut-polarity"
>>> 
>>> See also page 1,372 of the RK3588 TRM v1.0.
>>> 
>>> This has also reminded me to check how is the Rock 5B actually wired,
>>> just to make sure.  We actually need to provide the two DT properties
>>> listed above, at least to avoid emitting the warnings.
>> 
>> Well the defaults are already provided in rk3588s.dtsi, so there won't
>> be any warnings (see lines 2222-2223 in Linus' master version), and
>> according to the vendor kernel those are also what Rock 5B uses.
> 
> Yes, I noticed the same a couple of minutes after sending my last
> message, but didn't want to make more noise about it. :)  I would've
> mentioned it in my next message, of course.

Just checked the Rock 5B schematic and it expects the CRU to be used
to perform the hardware reset in case of a thermal runaway, so the
defaults in the RK3588s dtsi are fine.  I had to double-check it. :)

However, now I have some open questions related to interrupt-driven
operation.  I'll research it further and come back with an update.

>> This made me think however: what if a board doesn't enable TSADC, but
>> has OPPs in place for higher voltage and frequency states? There won't
>> be any throttling (as there won't be any thermal monitoring) and there
>> might not be a critical shutdown at all if it heats up - possibly even
>> causing hardware damage. In this case it seems that having TSADC
>> enabled by default would at least trigger passive cooling, hopefully
>> avoiding the critical shutdown altogether and making those properties
>> irrelevant in 99% cases.
> 
> Those are very good questions.  Thumbs up!
> 
> The trouble is that the boards can use different wiring to handle the
> thermal runaways, by expecting the PMIC to handle it or not.  Thus,
> it's IMHO better to simply leave that to be tested and enabled on a
> board-by-board basis, whenever a new RK3588(s)-based board is added.
> 
> Thus, the only right way at this point would be to merge the addition
> of the OPPs and the enabling of the TSADC for all currently supported
> RK3588(s)-based boards at once, instead of just for the Rock 5B.
> 
> I can handle the required changes for the QuartzPro64 dts file.  For
> other supported RK3588(s)-based boards, if there are no people having
> access to them and willing to perform the dts changes and the testing,
> I'd be willing to go through the board schematics, to enable the
> TSADC for them as well.

Please, let me know are you fine with the above-described approach.


From rafael at kernel.org  Thu Feb  1 11:42:52 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 1 Feb 2024 20:42:52 +0100
Subject: [PATCH v1 03/18] thermal: Directly use thermal_zone_platform_params
 for thermal_zone_device
In-Reply-To: <20240130111250.185718-4-angelogioacchino.delregno@collabora.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com> <20240130111250.185718-4-angelogioacchino.delregno@collabora.com>
Message-ID: <CAJZ5v0g6YNDAUxaWK9KfM0tt2x4wqaCap4--UjSauwmfYiEgoA@mail.gmail.com>

On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Remove all duplicate members from thermal_zone_device and directly
> use the corresponding ones from struct thermal_zone_platform_params.

I totally disagree with this approach.

It does make sense to store these things in a tz directly.

1. devdata allows the caller of the thermal zone to get to their own
information on it conveniently.  This patch makes it harder.
2. It makes sense to copy type into tz to allow the zone creator to
free the string (should they want to do that).
3. It would make sense to copy the contents of the trips[] table to tz
to allow the zone creator to free their initial table.  This doesn't
happen today, but it is in the works and your patch goes against this.
4. It makes sense to copy num_trips directly to tz, because it is
closely related to trips[].
5. It makes sense to copy ops directly into tz, because this will
allow zone creators to use const ops for zone registration.  Again,
this doesn't happen today, but it is in the works and this patch goes
against this.

As far as I'm concerned, this one is a total no-go.

Thanks!


From clabbe.montjoie at gmail.com  Thu Feb  1 11:45:54 2024
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Thu, 1 Feb 2024 20:45:54 +0100
Subject: [PATCH v2 03/20] drviers: crypto: meson: add platform data
In-Reply-To: <20240201171352.ut5xhw3u2b77v33d@cab-wsm-0029881>
References: <20240123165831.970023-1-avromanov@salutedevices.com>
 <20240123165831.970023-4-avromanov@salutedevices.com>
 <ZbC8qLXogjxJD8LD@Red>
 <20240201171352.ut5xhw3u2b77v33d@cab-wsm-0029881>
Message-ID: <Zbv08i_Yn0wrjkwH@Red>

Le Thu, Feb 01, 2024 at 05:13:56PM +0000, Alexey Romanov a ?crit :
> Hello,
> 
> On Wed, Jan 24, 2024 at 08:30:48AM +0100, Corentin Labbe wrote:
> > Le Tue, Jan 23, 2024 at 07:58:14PM +0300, Alexey Romanov a 'ecrit :
> > > To support other Amlogic SoC's we have to
> > > use platform data: descriptors and status registers
> > > offsets are individual for each SoC series.
> > > 
> > > Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> > > ---
> > >  drivers/crypto/amlogic/amlogic-gxl-cipher.c |  2 +-
> > >  drivers/crypto/amlogic/amlogic-gxl-core.c   | 31 +++++++++++++++------
> > >  drivers/crypto/amlogic/amlogic-gxl.h        | 11 ++++++++
> > >  3 files changed, 35 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> > > index b19032f92415..7eff3ae7356f 100644
> > > --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> > > +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> > > @@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)
> > >  
> > >  	reinit_completion(&mc->chanlist[flow].complete);
> > >  	mc->chanlist[flow].status = 0;
> > > -	writel(mc->chanlist[flow].t_phy | 2, mc->base + (flow << 2));
> > > +	writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
> > >  	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
> > >  						  msecs_to_jiffies(500));
> > >  	if (mc->chanlist[flow].status == 0) {
> > > diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> > > index a58644be76e9..2be381e157c4 100644
> > > --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> > > +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> > > @@ -18,6 +18,7 @@
> > >  #include <linux/kernel.h>
> > >  #include <linux/module.h>
> > >  #include <linux/of.h>
> > > +#include <linux/of_device.h>
> > >  #include <linux/platform_device.h>
> > >  
> > >  #include "amlogic-gxl.h"
> > > @@ -30,9 +31,10 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
> > >  
> > >  	for (flow = 0; flow < mc->flow_cnt; flow++) {
> > >  		if (mc->chanlist[flow].irq == irq) {
> > > -			p = readl(mc->base + ((0x04 + flow) << 2));
> > > +			p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
> > >  			if (p) {
> > > -				writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
> > > +				writel_relaxed(0xF, mc->base +
> > > +					      ((mc->pdata->status_reg + flow) << 2));
> > >  				mc->chanlist[flow].status = 1;
> > >  				complete(&mc->chanlist[flow].complete);
> > >  				return IRQ_HANDLED;
> > > @@ -245,15 +247,34 @@ static void meson_unregister_algs(struct meson_dev *mc)
> > >  	}
> > >  }
> > >  
> > > +static const struct meson_pdata meson_gxl_pdata = {
> > > +	.descs_reg = 0x0,
> > > +	.status_reg = 0x4,
> > > +};
> > > +
> > > +static const struct of_device_id meson_crypto_of_match_table[] = {
> > > +	{
> > > +		.compatible = "amlogic,gxl-crypto",
> > > +		.data = &meson_gxl_pdata,
> > > +	},
> > > +	{},
> > > +};
> > > +
> > >  static int meson_crypto_probe(struct platform_device *pdev)
> > >  {
> > > +	const struct of_device_id *match;
> > >  	struct meson_dev *mc;
> > >  	int err;
> > >  
> > > +	match = of_match_device(meson_crypto_of_match_table, &pdev->dev);
> > > +	if (!match)
> > > +		return -EINVAL;
> > > +
> > >  	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
> > >  	if (!mc)
> > >  		return -ENOMEM;
> > >  
> > > +	mc->pdata = match->data;
> > >  	mc->dev = &pdev->dev;
> > >  	platform_set_drvdata(pdev, mc);
> > >  
> > > @@ -312,12 +333,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
> > >  	clk_disable_unprepare(mc->busclk);
> > >  }
> > >  
> > > -static const struct of_device_id meson_crypto_of_match_table[] = {
> > > -	{ .compatible = "amlogic,gxl-crypto", },
> > > -	{}
> > > -};
> > > -MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
> > 
> > Hello
> > 
> > This patch breaks bisection, since it removes MODULE_DEVICE_TABLE.
> > After applying patchs 1,2,3 the driver does not load anymore on lepotato board.
> 
> Please, give more information. 
> 
> I applied the first 3 patches and the driver probes correctly.
> 

Did you tried to set the driver as module ?
The breakage is when the driver is set as module.

Regards


From robh at kernel.org  Thu Feb  1 11:46:53 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 1 Feb 2024 13:46:53 -0600
Subject: [PATCH 00/46] Dynamic allocation of reserved_mem array.
In-Reply-To: <51dc64bb-3101-4b4a-a54f-c0df6c0b264c@quicinc.com>
References: <20240126235425.12233-1-quic_obabatun@quicinc.com>
 <20240131000710.GA2581425-robh@kernel.org>
 <51dc64bb-3101-4b4a-a54f-c0df6c0b264c@quicinc.com>
Message-ID: <20240201194653.GA1328565-robh@kernel.org>

On Thu, Feb 01, 2024 at 09:08:06AM -0800, Oreoluwa Babatunde wrote:
> 
> On 1/30/2024 4:07 PM, Rob Herring wrote:
> > On Fri, Jan 26, 2024 at 03:53:39PM -0800, Oreoluwa Babatunde wrote:
> >> The reserved_mem array is used to store data for the different
> >> reserved memory regions defined in the DT of a device.  The array
> >> stores information such as region name, node, start-address, and size
> >> of the reserved memory regions.
> >>
> >> The array is currently statically allocated with a size of
> >> MAX_RESERVED_REGIONS(64). This means that any system that specifies a
> >> number of reserved memory regions greater than MAX_RESERVED_REGIONS(64)
> >> will not have enough space to store the information for all the regions.
> >>
> >> Therefore, this series extends the use of the static array for
> >> reserved_mem, and introduces a dynamically allocated array using
> >> memblock_alloc() based on the number of reserved memory regions
> >> specified in the DT.
> >>
> >> Some architectures such as arm64 require the page tables to be setup
> >> before memblock allocated memory is writable.  Therefore, the dynamic
> >> allocation of the reserved_mem array will need to be done after the
> >> page tables have been setup on these architectures. In most cases that
> >> will be after paging_init().
> >>
> >> Reserved memory regions can be divided into 2 groups.
> >> i) Statically-placed reserved memory regions
> >> i.e. regions defined in the DT using the @reg property.
> >> ii) Dynamically-placed reserved memory regions.
> >> i.e. regions specified in the DT using the @alloc_ranges
> >>     and @size properties.
> >>
> >> It is possible to call memblock_reserve() and memblock_mark_nomap() on
> >> the statically-placed reserved memory regions and not need to save them
> >> to the reserved_mem array until memory is allocated for it using
> >> memblock, which will be after the page tables have been setup.
> >> For the dynamically-placed reserved memory regions, it is not possible
> >> to wait to store its information because the starting address is
> >> allocated only at run time, and hence they need to be stored somewhere
> >> after they are allocated.
> >> Waiting until after the page tables have been setup to allocate memory
> >> for the dynamically-placed regions is also not an option because the
> >> allocations will come from memory that have already been added to the
> >> page tables, which is not good for memory that is supposed to be
> >> reserved and/or marked as nomap.
> >>
> >> Therefore, this series splits up the processing of the reserved memory
> >> regions into two stages, of which the first stage is carried out by
> >> early_init_fdt_scan_reserved_mem() and the second is carried out by
> >> fdt_init_reserved_mem().
> >>
> >> The early_init_fdt_scan_reserved_mem(), which is called before the page
> >> tables are setup is used to:
> >> 1. Call memblock_reserve() and memblock_mark_nomap() on all the
> >>    statically-placed reserved memory regions as needed.
> >> 2. Allocate memory from memblock for the dynamically-placed reserved
> >>    memory regions and store them in the static array for reserved_mem.
> >>    memblock_reserve() and memblock_mark_nomap() are also called as
> >>    needed on all the memory allocated for the dynamically-placed
> >>    regions.
> >> 3. Count the total number of reserved memory regions found in the DT.
> >>
> >> fdt_init_reserved_mem(), which should be called after the page tables
> >> have been setup, is used to carry out the following:
> >> 1. Allocate memory for the reserved_mem array based on the number of
> >>    reserved memory regions counted as mentioned above.
> >> 2. Copy all the information for the dynamically-placed reserved memory
> >>    regions from the static array into the new allocated memory for the
> >>    reserved_mem array.
> >> 3. Add the information for the statically-placed reserved memory into
> >>    reserved_mem array.
> >> 4. Run the region specific init functions for each of the reserve memory
> >>    regions saved in the reserved_mem array.
> > I don't see the need for fdt_init_reserved_mem() to be explicitly called 
> > by arch code. I said this already, but that can be done at the same time 
> > as unflattening the DT. The same conditions are needed for both: we need 
> > to be able to allocate memory from memblock.
> >
> > To put it another way, if fdt_init_reserved_mem() can be called "early", 
> > then unflattening could be moved earlier as well. Though I don't think 
> > we should optimize that. I'd rather see all arches call the DT functions 
> > at the same stages.
> Hi Rob,
> 
> The reason we moved fdt_init_reserved_mem() back into the arch specific code
> was because we realized that there was no apparently obvious way to call
> early_init_fdt_scan_reserved_mem() and fdt_init_reserved_mem() in the correct
> order that will work for all archs if we placed fdt_init_reserved_mem() inside the
> unflatten_devicetree() function.
> 
> early_init_fdt_scan_reserved_mem() needs to be
> called first before fdt_init_reserved_mem(). But on some archs,
> unflatten_devicetree() is called before early_init_fdt_scan_reserved_mem(), which
> means that if we have fdt_init_reserved_mem() inside the unflatten_devicetree()
> function, it will be called before early_init_fdt_scan_reserved_mem().
> 
> This is connected to your other comments on Patch 7 & Patch 14.
> I agree, unflatten_devicetree() should NOT be getting called before we reserve
> memory for the reserved memory regions because that could cause memory to be
> allocated from regions that should be reserved.
> 
> Hence, resolving this issue should allow us to call fdt_init_reserved_mem() from
> the? unflatten_devicetree() function without it changing the order that we are
> trying to have.

There's one issue I've found which is unflatten_device_tree() isn't 
called for ACPI case on arm64. Turns out we need /reserved-memory 
handled in that case too. However, I think we're going to change 
calling unflatten_device_tree() unconditionally for another reason[1]. 

[1] https://lore.kernel.org/all/efe6a7886c3491cc9c225a903efa2b1e.sboyd at kernel.org/

> 
> I will work on implementing this and send another revision.

I think we should go with a simpler route that's just copy the an 
initial array in initdata to a properly sized, allocated array like the 
patch below. Of course it will need some arch fixes and a follow-on 
patch to increase the initial array size.

8<--------------------------------------------------------------------
From: Rob Herring <robh at kernel.org>
Date: Wed, 31 Jan 2024 16:26:23 -0600
Subject: [PATCH] of: reserved-mem: Re-allocate reserved_mem array to actual
 size

In preparation to increase the static reserved_mem array size yet again,
copy the initial array to an allocated array sized based on the actual
size needed. Now increasing the the size of the static reserved_mem
array only eats up the initdata space. For platforms with reasonable
number of reserved regions, we have a net gain in free memory.

In order to do memblock allocations, fdt_init_reserved_mem() is moved a
bit later to unflatten_device_tree(). On some arches this is effectively
a nop.

Signed-off-by: Rob Herring <robh at kernel.org>
---
RFC as this is compile tested only. This is an alternative to this
series[1].

[1] https://lore.kernel.org/all/20240126235425.12233-1-quic_obabatun at quicinc.com/
---
 drivers/of/fdt.c             |  4 ++--
 drivers/of/of_reserved_mem.c | 18 +++++++++++++-----
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index bf502ba8da95..14360f5191ae 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -645,8 +645,6 @@ void __init early_init_fdt_scan_reserved_mem(void)
 			break;
 		memblock_reserve(base, size);
 	}
-
-	fdt_init_reserved_mem();
 }
 
 /**
@@ -1328,6 +1326,8 @@ bool __init early_init_dt_scan(void *params)
  */
 void __init unflatten_device_tree(void)
 {
+	fdt_init_reserved_mem();
+
 	__unflatten_device_tree(initial_boot_params, NULL, &of_root,
 				early_init_dt_alloc_memory_arch, false);
 
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 7ec94cfcbddb..ae323d6b25ad 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -27,7 +27,8 @@
 #include "of_private.h"
 
 #define MAX_RESERVED_REGIONS	64
-static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
+static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS] __initdata;
+static struct reserved_mem *reserved_mem_p;
 static int reserved_mem_count;
 
 static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
@@ -354,6 +355,13 @@ void __init fdt_init_reserved_mem(void)
 			}
 		}
 	}
+
+	reserved_mem_p = memblock_alloc(sizeof(struct reserved_mem) * reserved_mem_count,
+					sizeof(struct reserved_mem));
+	if (WARN(!reserved_mem_p, "of: reserved-memory allocation failed, continuing with __initdata array!\n"))
+		reserved_mem_p = reserved_mem;
+	else
+		memcpy(reserved_mem_p, reserved_mem, sizeof(struct reserved_mem) * reserved_mem_count);
 }
 
 static inline struct reserved_mem *__find_rmem(struct device_node *node)
@@ -364,8 +372,8 @@ static inline struct reserved_mem *__find_rmem(struct device_node *node)
 		return NULL;
 
 	for (i = 0; i < reserved_mem_count; i++)
-		if (reserved_mem[i].phandle == node->phandle)
-			return &reserved_mem[i];
+		if (reserved_mem_p[i].phandle == node->phandle)
+			return &reserved_mem_p[i];
 	return NULL;
 }
 
@@ -507,8 +515,8 @@ struct reserved_mem *of_reserved_mem_lookup(struct device_node *np)
 
 	name = kbasename(np->full_name);
 	for (i = 0; i < reserved_mem_count; i++)
-		if (!strcmp(reserved_mem[i].name, name))
-			return &reserved_mem[i];
+		if (!strcmp(reserved_mem_p[i].name, name))
+			return &reserved_mem_p[i];
 
 	return NULL;
 }
-- 
2.43.0




From conor at kernel.org  Thu Feb  1 11:47:14 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 1 Feb 2024 19:47:14 +0000
Subject: [PATCH v2 1/6] dt-bindings: display: rockchip: rockchip,dw-hdmi:
 remove port property
In-Reply-To: <a493c65e-7cf9-455f-95d5-8c98cad35710@gmail.com>
References: <a493c65e-7cf9-455f-95d5-8c98cad35710@gmail.com>
Message-ID: <20240201-raffle-frays-6b5a47faab69@spud>

On Wed, Jan 31, 2024 at 10:14:29PM +0100, Johan Jonker wrote:
> The hdmi-connector nodes are now functional and the new way to model
> hdmi ports nodes with both in and output port subnodes. Unfortunately
> with the conversion to YAML the old method with only an input port node
> was used. Later the new method was also added to the binding.
> A binding must be unambiguously, so remove the old port property
> entirely and make port at 0 and port at 1 a requirement as all
> upstream dts files are updated as well and because checking
> deprecated stuff is a bit pointless.
> Update the example to avoid use of the removed property.
> 
> Signed-off-by: Johan Jonker <jbx6244 at gmail.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Thanks,
Conor.

> ---
> 
> Changed V2:
>   rename title from deprecate to remove
>   reword
> ---
>  .../display/rockchip/rockchip,dw-hdmi.yaml    | 24 +++++++++++++++----
>  1 file changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
> index 7e59dee15a5f..391c2a7e79de 100644
> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
> @@ -97,8 +97,8 @@ properties:
>    ports:
>      $ref: /schemas/graph.yaml#/properties/ports
> 
> -    patternProperties:
> -      "^port(@0)?$":
> +    properties:
> +      port at 0:
>          $ref: /schemas/graph.yaml#/properties/port
>          description: Input of the DWC HDMI TX
>          properties:
> @@ -108,11 +108,14 @@ properties:
>              description: Connection to the VOPB
>            endpoint at 1:
>              description: Connection to the VOPL
> -    properties:
>        port at 1:
>          $ref: /schemas/graph.yaml#/properties/port
>          description: Output of the DWC HDMI TX
> 
> +    required:
> +      - port at 0
> +      - port at 1
> +
>    rockchip,grf:
>      $ref: /schemas/types.yaml#/definitions/phandle
>      description:
> @@ -147,7 +150,11 @@ examples:
>          clock-names = "iahb", "isfr";
> 
>          ports {
> -            port {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port at 0 {
> +                reg = <0>;
>                  #address-cells = <1>;
>                  #size-cells = <0>;
> 
> @@ -155,11 +162,20 @@ examples:
>                      reg = <0>;
>                      remote-endpoint = <&vopb_out_hdmi>;
>                  };
> +
>                  hdmi_in_vopl: endpoint at 1 {
>                      reg = <1>;
>                      remote-endpoint = <&vopl_out_hdmi>;
>                  };
>              };
> +
> +            port at 1 {
> +                reg = <1>;
> +
> +                hdmi_out_con: endpoint {
> +                    remote-endpoint = <&hdmi_con_in>;
> +                };
> +            };
>          };
>      };
> 
> --
> 2.39.2
> 
-------------- 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/20240201/7cd3e10f/attachment.sig>

From rafael at kernel.org  Thu Feb  1 11:51:56 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 1 Feb 2024 20:51:56 +0100
Subject: [PATCH v1 08/18] thermal: intel: pch_thermal: Migrate to thermal_zone_device_register()
In-Reply-To: <20240130111250.185718-9-angelogioacchino.delregno@collabora.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com> <20240130111250.185718-9-angelogioacchino.delregno@collabora.com>
Message-ID: <CAJZ5v0ifn7eg9WrpNF2_PB62gE_BzV2Vx5_k7ebOoZWdQNVWaQ@mail.gmail.com>

On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> The thermal API has a new thermal_zone_device_register() function which
> is deprecating the older thermal_zone_device_register_with_trips() and
> thermal_tripless_zone_device_register().
>
> Migrate to the new thermal zone device registration function.
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/thermal/intel/intel_pch_thermal.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/thermal/intel/intel_pch_thermal.c b/drivers/thermal/intel/intel_pch_thermal.c
> index b3905e34c507..73d7c2ac7dbc 100644
> --- a/drivers/thermal/intel/intel_pch_thermal.c
> +++ b/drivers/thermal/intel/intel_pch_thermal.c
> @@ -160,6 +160,7 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev,
>                                    const struct pci_device_id *id)
>  {
>         enum pch_board_ids board_id = id->driver_data;
> +       struct thermal_zone_device_params tzdp;
>         struct pch_thermal_device *ptd;
>         int nr_trips = 0;
>         u16 trip_temp;
> @@ -233,10 +234,13 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev,
>
>         nr_trips += pch_wpt_add_acpi_psv_trip(ptd, nr_trips);
>
> -       ptd->tzd = thermal_zone_device_register_with_trips(board_names[board_id],
> -                                                          ptd->trips, nr_trips,
> -                                                          0, ptd, &tzd_ops,
> -                                                          NULL, 0, 0);
> +       tzdp.tzp.type = board_names[board_id];
> +       tzdp.tzp.devdata = ptd;
> +       tzdp.tzp.trips = ptd->trips;
> +       tzdp.tzp.num_trips = nr_trips;
> +       tzdp.tzp.ops = &tzd_ops;
> +
> +       ptd->tzd = thermal_zone_device_register(&tzdp);

IMV, this should be

ptd->tzd = thermal_zone_device_register(board_names[board_id],
ptd->trips, nr_trips, &tzd_ops, ptd, NULL);

and the tzdp variable is not necessary even.

Analogously in the rest of the series (ie. patches [4-18/18]).

>         if (IS_ERR(ptd->tzd)) {
>                 dev_err(&pdev->dev, "Failed to register thermal zone %s\n",
>                         board_names[board_id]);
> --


From jernej.skrabec at gmail.com  Thu Feb  1 11:54:12 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 01 Feb 2024 20:54:12 +0100
Subject: [PATCH 2/4] arm64: dts: sun50i-a64-pinephone: Retain leds state in
 suspend
In-Reply-To: <sbcg74hktwv5x7hookeb4su27xut7swarl3d5mbs3i5cqxtq4g@4evugu43ctiv>
References: <20240128204740.2355092-1-aren@peacevolution.org>
 <4892315.31r3eYUQgx@jernej-laptop>
 <sbcg74hktwv5x7hookeb4su27xut7swarl3d5mbs3i5cqxtq4g@4evugu43ctiv>
Message-ID: <10409647.nUPlyArG6x@jernej-laptop>

Dne ?etrtek, 01. februar 2024 ob 02:36:46 CET je Aren napisal(a):
> On Tue, Jan 30, 2024 at 08:06:24PM +0100, Jernej ?krabec wrote:
> > Dne nedelja, 28. januar 2024 ob 21:45:08 CET je Aren Moynihan napisal(a):
> > > From: Miles Alan <m at milesalan.com>
> > > 
> > > Allows user to set a led before entering suspend to know that
> > > the phone is still on (or could be used for notifications etc.)
> > > 
> > > Signed-off-by: Miles Alan <m at milesalan.com>
> > > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > > Signed-off-by: Aren Moynihan <aren at peacevolution.org>
> > 
> > Where is patch 1 and possibly cover letter? Please resend with all patches.
> 
> Oops, sorry about that, I'm still getting used to get_maintainer.pl.
> I'll resend this properly when I have time this weekend, until then the
> patch you missed is available at
> https://lore.kernel.org/lkml/20240128204740.2355092-1-aren at peacevolution.org/

When sending patch series it's customary to send all patches to all
maintainers and mailing lists (to have a context). In case of large patch
series, you can send only selected patches to each maintainer and mailing
lists, but then send cover letter to all involved and explain general idea
behind the series.

Best regards,
Jernej

> 
> > However, this particular patch is:
> > Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> 
> Thanks
>  - Aren
> 
> > Best regards,
> > Jernej
> > 
> > > ---
> > > 
> > >  arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 3 +++
> > >  1 file changed, 3 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > index 87847116ab6d..ad2476ee01e4 100644
> > > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > @@ -43,18 +43,21 @@ led-0 {
> > >  			function = LED_FUNCTION_INDICATOR;
> > >  			color = <LED_COLOR_ID_BLUE>;
> > >  			gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */
> > > +			retain-state-suspended;
> > >  		};
> > >  
> > >  		led-1 {
> > >  			function = LED_FUNCTION_INDICATOR;
> > >  			color = <LED_COLOR_ID_GREEN>;
> > >  			gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */
> > > +			retain-state-suspended;
> > >  		};
> > >  
> > >  		led-2 {
> > >  			function = LED_FUNCTION_INDICATOR;
> > >  			color = <LED_COLOR_ID_RED>;
> > >  			gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */
> > > +			retain-state-suspended;
> > >  		};
> > >  	};
> > >  
> > > 
> > 
> > 
> > 
> > 
> 






From tmgross at umich.edu  Thu Feb  1 12:02:03 2024
From: tmgross at umich.edu (Trevor Gross)
Date: Thu, 1 Feb 2024 14:02:03 -0600
Subject: [PATCH v2 2/3] rust: phy: add some phy_driver and genphy_ functions
In-Reply-To: <20240201-rockchip-rust-phy_depend-v2-2-c5fa4faab924@christina-quast.de>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
 <20240201-rockchip-rust-phy_depend-v2-2-c5fa4faab924@christina-quast.de>
Message-ID: <CALNs47tWNNi2GXHAwwT=A1LP=xWwXvrPy4xVapqMQOeyeN0+9Q@mail.gmail.com>

On Thu, Feb 1, 2024 at 12:07?PM Christina Quast
<contact at christina-quast.de> wrote:
> diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs
> index e457b3c7cb2f..373a4d358e9f 100644
> --- a/rust/kernel/net/phy.rs
> +++ b/rust/kernel/net/phy.rs
> @@ -95,6 +95,22 @@ pub fn phy_id(&self) -> u32 {
>          unsafe { (*phydev).phy_id }
>      }
>
> +    /// Gets the current crossover of the PHY.
> +    pub fn mdix(&self) -> u8 {

Are possible values for mdix always ETH_TP_MDI{,_INVALID,_X,_AUTO}? If
so, this would be better as an enum.

> +        let phydev = self.0.get();
> +        // SAFETY: The struct invariant ensures that we may access
> +        // this field without additional synchronization.
> +        unsafe { (*phydev).mdix }
> +    }

> +
>      /// Gets the state of PHY state machine states.
>      pub fn state(&self) -> DeviceState {
>          let phydev = self.0.get();
> @@ -300,6 +316,15 @@ pub fn genphy_read_abilities(&mut self) -> Result {
>          // So it's just an FFI call.
>          to_result(unsafe { bindings::genphy_read_abilities(phydev) })
>      }
> +
> +    /// Writes BMCR
> +    pub fn genphy_config_aneg(&mut self) -> Result {

The docs need an update here

> +        let phydev = self.0.get();
> +        // SAFETY: `phydev` is pointing to a valid object by the type invariant of `Self`.
> +        // So it's just an FFI call.
> +        // second param = false => autoneg not requested
> +        to_result(unsafe { bindings::__genphy_config_aneg(phydev, false) })

I assume you did this since the non-dunder `genphy_config_aneg` is
inline. I think that is ok since the implementation is so minimal, but
you could also add a binding helper and call that (rust/helpers.c).

> +    }
>  }
>
>  /// Defines certain other features this PHY supports (like interrupts).
> @@ -583,6 +608,12 @@ fn soft_reset(_dev: &mut Device) -> Result {
>          Err(code::ENOTSUPP)
>      }
>
> +    /// Called to initialize the PHY,
> +    /// including after a reset

Docs wrapping

> +    fn config_init(_dev: &mut Device) -> Result {
> +        Err(code::ENOTSUPP)
> +    }

These have been changed to raise a build error rather than ENOTSUPP in
recent , see [1]. That patch is in net-next so you should see it next
time you rebase.

Also - these functions are meant for the vtable and don't do anything
if they are not wired up. See the create_phy_driver function, you will
need to add the field.

>      /// Probes the hardware to determine what abilities it has.
>      fn get_features(_dev: &mut Device) -> Result {
>          Err(code::ENOTSUPP)
>
> --
> 2.43.0
>

[1]: https://lore.kernel.org/rust-for-linux/20240125014502.3527275-2-fujita.tomonori at gmail.com/


From afd at ti.com  Thu Feb  1 12:08:53 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 14:08:53 -0600
Subject: [PATCH v3 1/6] arm64: dts: ti: k3-j784s4: Add Wave5 Video
 Encoder/Decoder Node
In-Reply-To: <a168bbdc2efd4cb1a71c6c6421dbd7ce@ti.com>
References: <20240131212625.1862775-1-b-brnich@ti.com>
 <20240131212625.1862775-2-b-brnich@ti.com>
 <a5f0059d-b80f-44e6-8c1e-793054586e0a@ti.com>
 <a168bbdc2efd4cb1a71c6c6421dbd7ce@ti.com>
Message-ID: <799640ba-3b7f-474b-8d70-64ed013e0755@ti.com>

On 2/1/24 1:13 PM, Brnich, Brandon wrote:
> Hi Andrew,
> 
>> -----Original Message-----
>> From: Davis, Andrew <afd at ti.com>
>> Sent: Thursday, February 1, 2024 12:35 PM
>> To: Brnich, Brandon <b-brnich at ti.com>; Menon, Nishanth <nm at ti.com>;
>> Raghavendra, Vignesh <vigneshr at ti.com>; Tero Kristo <kristo at kernel.org>;
>> Rob Herring <robh+dt at kernel.org>; Krzysztof Kozlowski
>> <krzysztof.kozlowski+dt at linaro.org>; Conor Dooley <conor+dt at kernel.org>;
>> Catalin Marinas <catalin.marinas at arm.com>; Will Deacon
>> <will at kernel.org>; Bjorn Andersson <quic_bjorande at quicinc.com>; Geert
>> Uytterhoeven <geert+renesas at glider.be>; Arnd Bergmann
>> <arnd at arndb.de>; Konrad Dybcio <konrad.dybcio at linaro.org>; Neil
>> Armstrong <neil.armstrong at linaro.org>; N?colas F . R . A . Prado
>> <nfraprado at collabora.com>; Marek Szyprowski
>> <m.szyprowski at samsung.com>; linux-arm-kernel at lists.infradead.org;
>> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; Etheridge, Darren
>> <detheridge at ti.com>
>> Subject: Re: [PATCH v3 1/6] arm64: dts: ti: k3-j784s4: Add Wave5 Video
>> Encoder/Decoder Node
>>
>> On 1/31/24 3:26 PM, Brandon Brnich wrote:
>>> This patch adds support for the Wave521cl on the J784S4-evm.
>>>
>>> Signed-off-by: Brandon Brnich <b-brnich at ti.com>
>>> ---
>>>    arch/arm64/boot/dts/ti/k3-j784s4-evm.dts   |  8 ++++++++
>>>    arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 20 ++++++++++++++++++++
>>>    arch/arm64/boot/dts/ti/k3-j784s4.dtsi      |  2 ++
>>>    3 files changed, 30 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
>>> b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
>>> index f34b92acc56d..7d37c11b4df4 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
>>> +++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
>>> @@ -784,6 +784,14 @@ &main_gpio0 {
>>>    	status = "okay";
>>>    };
>>>
>>> +&vpu0 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&vpu1 {
>>> +	status = "okay";
>>> +};
>>> +
>>>    &mcu_cpsw {
>>>    	status = "okay";
>>>    	pinctrl-names = "default";
>>> diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
>>> b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
>>> index f2b720ed1e4f..8b2623ac8160 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
>>> @@ -662,6 +662,26 @@ main_i2c6: i2c at 2060000 {
>>>    		status = "disabled";
>>>    	};
>>>
>>> +	vpu0: video-codec at 4210000 {
>>> +		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
>>> +		reg = <0x00 0x4210000 0x00 0x10000>;
>>> +		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
>>> +		clocks = <&k3_clks 241 2>;
>>> +		clock-names = "vcodec";
>>> +		power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>;
>>> +		status = "disabled";
>>
>> Why are these default disabled? I don't see anything missing that would
>> need to be added at the board level. You disable them just to re-enable them
>> in the next patch. Leave these default enabled.
> 
> I thought that disabled by default was the standard for node in dtsi files, where
> they get specifically enabled in the particular dts file for the SoC.
> 

Only disabled if there is missing information needed for the node to function
that can only be added at the board level, e.g. pinmux usually.

> In V4 I will remove the disabled by default. Should this apply to all platforms in
> the series?

Yes

Andrew

>   
>>> +	};
>>> +
>>> +	vpu1: video-codec at 4220000 {
>>> +		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
>>> +		reg = <0x00 0x4220000 0x00 0x10000>;
>>> +		interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
>>> +		clocks = <&k3_clks 242 2>;
>>> +		clock-names = "vcodec";
>>> +		power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
>>> +		status = "disabled";
>>> +	};
>>> +
>>>    	main_sdhci0: mmc at 4f80000 {
>>>    		compatible = "ti,j721e-sdhci-8bit";
>>>    		reg = <0x00 0x04f80000 0x00 0x1000>, diff --git
>>> a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
>>> b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
>>> index 4398c3a463e1..93bb0cba1b48 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
>>> @@ -247,6 +247,8 @@ cbass_main: bus at 100000 {
>>>    			 <0x00 0x30000000 0x00 0x30000000 0x00
>> 0x0c400000>, /* MAIN NAVSS */
>>>    			 <0x41 0x00000000 0x41 0x00000000 0x01
>> 0x00000000>, /* PCIe1 DAT1 */
>>>    			 <0x4e 0x20000000 0x4e 0x20000000 0x00
>> 0x00080000>, /* GPU */
>>> +			 <0x00 0x04210000 0x00 0x04210000 0x00
>> 0x00010000>, /* VPU0 */
>>> +			 <0x00 0x04220000 0x00 0x04220000 0x00
>> 0x00010000>, /* VPU1 */
>>
>> Add these in sorted by memory address order.
> 
> Will do in V4 as well.
> 
>>
>> Andrew
>>
>>>
>>>    			 /* MCUSS_WKUP Range */
>>>    			 <0x00 0x28380000 0x00 0x28380000 0x00
>> 0x03880000>,
> 
> Brandon


From benjamin at bigler.one  Thu Feb  1 12:14:39 2024
From: benjamin at bigler.one (Benjamin Bigler)
Date: Thu, 01 Feb 2024 21:14:39 +0100
Subject: [PATCH v4] spi: imx: fix the burst length at DMA mode and CPU
 mode
In-Reply-To: <20240201105451.507005-1-carlos.song@nxp.com>
References: <20240201105451.507005-1-carlos.song@nxp.com>
Message-ID: <c7326b50ce3fe2a660638e1eb2c11519ad82feee.camel@bigler.one>

On Thu, 2024-02-01 at 18:54 +0800, carlos.song at nxp.com wrote:
> From: Carlos Song <carlos.song at nxp.com>
> 
> For DMA mode, the bus width of the DMA is equal to the size of data
> word, so burst length should be configured as bits per word.
> 
> For CPU mode, because of the spi transfer len is in byte, so burst
> length should be configured as bits per byte * spi_imx->count.
> 
> Signed-off-by: Carlos Song <carlos.song at nxp.com>
> Reviewed-by: Clark Wang <xiaoning.wang at nxp.com>
> Fixes: e9b220aeacf1 ("spi: spi-imx: correctly configure burst length when using dma")
> Fixes: 5f66db08cbd3 ("spi: imx: Take in account bits per word instead of assuming 8-bits")
> ---
> Changes for V3:
> - include <linux/bits.h>
> Changes for V4:
> - keep the includes sorted alphabetically.
> ---
>  drivers/spi/spi-imx.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
> index 546cdce525fc..f7990ac2c654 100644
> --- a/drivers/spi/spi-imx.c
> +++ b/drivers/spi/spi-imx.c
> @@ -2,6 +2,7 @@
>  // Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
>  // Copyright (C) 2008 Juergen Beisert
>  
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/completion.h>
>  #include <linux/delay.h>
> @@ -660,15 +661,14 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx,
>  			<< MX51_ECSPI_CTRL_BL_OFFSET;
>  	else {
>  		if (spi_imx->usedma) {
> -			ctrl |= (spi_imx->bits_per_word *
> -				spi_imx_bytes_per_word(spi_imx->bits_per_word) - 1)
> +			ctrl |= (spi_imx->bits_per_word - 1)
>  				<< MX51_ECSPI_CTRL_BL_OFFSET;
>  		} else {
>  			if (spi_imx->count >= MX51_ECSPI_CTRL_MAX_BURST)
> -				ctrl |= (MX51_ECSPI_CTRL_MAX_BURST - 1)
> +				ctrl |= (MX51_ECSPI_CTRL_MAX_BURST * BITS_PER_BYTE - 1)
>  						<< MX51_ECSPI_CTRL_BL_OFFSET;
>  			else
> -				ctrl |= (spi_imx->count * spi_imx->bits_per_word - 1)
> +				ctrl |= (spi_imx->count * BITS_PER_BYTE - 1)
I think that will not work for drivers which dont use bits_per_word=8.?
https://lore.kernel.org/all/20230917164037.29284-1-stefanmoring at gmail.com/
>  						<< MX51_ECSPI_CTRL_BL_OFFSET;
>  		}
>  	}

Best regards,
Benjamin Bigler



From dsimic at manjaro.org  Thu Feb  1 12:17:08 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu, 01 Feb 2024 21:17:08 +0100
Subject: [PATCH v2 3/3] net: phy: add Rust Rockchip PHY driver
In-Reply-To: <2024020105-bankroll-opium-a6e5@gregkh>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
 <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>
 <2024020105-bankroll-opium-a6e5@gregkh>
Message-ID: <cabb91e97a5e563cccbffd56f331a477@manjaro.org>

On 2024-02-01 19:23, Greg KH wrote:
> On Thu, Feb 01, 2024 at 07:07:00PM +0100, Christina Quast wrote:
>> This is the Rust implementation of drivers/net/phy/rockchip.c. The
>> features are equivalent. You can choose C or Rust version kernel
>> configuration.
>> 
>> Signed-off-by: Christina Quast <contact at christina-quast.de>
> 
> Cool, but why?  Is this going to happen for all phy drivers going
> forward?  What's the end-game here, dropping all .c phy drivers that
> are in rust?  Or having duplicates for all of them?

I'd also like to know what's the intended purpose of rewriting a mature
existing PHY driver in Rust?


From Frank.Li at nxp.com  Thu Feb  1 12:22:40 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 01 Feb 2024 15:22:40 -0500
Subject: [PATCH v2 0/4] Add 8qm SMMU information
Message-ID: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>

Change at v2
- Remove iM95 for fec.

To: Ulf Hansson <ulf.hansson at linaro.org>
To: Rob Herring <robh+dt at kernel.org>
To: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
To: Conor Dooley <conor+dt at kernel.org>
To: Shawn Guo <shawnguo at kernel.org>
To: Sascha Hauer <s.hauer at pengutronix.de>
To: Pengutronix Kernel Team <kernel at pengutronix.de>
To: Fabio Estevam <festevam at gmail.com>
To: NXP Linux Team <linux-imx at nxp.com>
To: Wei Fang <wei.fang at nxp.com>
To: Shenwei Wang <shenwei.wang at nxp.com>
To: Clark Wang <xiaoning.wang at nxp.com>
To: David S. Miller <davem at davemloft.net>
To: Eric Dumazet <edumazet at google.com>
To: Jakub Kicinski <kuba at kernel.org>
To: Paolo Abeni <pabeni at redhat.com>
Cc: linux-mmc at vger.kernel.org
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: netdev at vger.kernel.org
Cc: imx at lists.linux.dev

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
Frank Li (4):
      dt-bindings: mmc: fsl-imx-esdhc: add iommus property
      dt-bindings: net: fec: add iommus property
      arm64: dts: imx8qm: add smmu node
      arm64: dts: imx8qm: add smmu stream id information

 .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml     |  3 ++
 Documentation/devicetree/bindings/net/fsl,fec.yaml |  3 ++
 arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi  |  6 ++++
 arch/arm64/boot/dts/freescale/imx8qm.dtsi          | 41 ++++++++++++++++++++++
 4 files changed, 53 insertions(+)
---
base-commit: 99748ff5ee0953610765e9d0cd6015c2eb0f7ace
change-id: 20240201-8qm_smmu-6318da8e9017

Best regards,
-- 
Frank Li <Frank.Li at nxp.com>



From Frank.Li at nxp.com  Thu Feb  1 12:22:41 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 01 Feb 2024 15:22:41 -0500
Subject: [PATCH v2 1/4] dt-bindings: mmc: fsl-imx-esdhc: add iommus
 property
In-Reply-To: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
Message-ID: <20240201-8qm_smmu-v2-1-3d12a80201a3@nxp.com>

iMX95 and iMX8QM have smmu. Add property "iommus".

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
index 82eb7a24c8578..0d8ed9d055ffe 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
@@ -162,6 +162,9 @@ properties:
       - const: ahb
       - const: per
 
+  iommus:
+    maxItems: 1
+
   power-domains:
     maxItems: 1
 

-- 
2.34.1



From Frank.Li at nxp.com  Thu Feb  1 12:22:42 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 01 Feb 2024 15:22:42 -0500
Subject: [PATCH v2 2/4] dt-bindings: net: fec: add iommus property
In-Reply-To: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
Message-ID: <20240201-8qm_smmu-v2-2-3d12a80201a3@nxp.com>

iMX8QM have iommu. Add proerty 'iommus'.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 Documentation/devicetree/bindings/net/fsl,fec.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/fsl,fec.yaml b/Documentation/devicetree/bindings/net/fsl,fec.yaml
index 8948a11c994e4..5536c06139cae 100644
--- a/Documentation/devicetree/bindings/net/fsl,fec.yaml
+++ b/Documentation/devicetree/bindings/net/fsl,fec.yaml
@@ -224,6 +224,9 @@ properties:
       Can be omitted thus no delay is observed. Delay is in range of 1ms to 1000ms.
       Other delays are invalid.
 
+  iommus:
+    maxItems: 1
+
 required:
   - compatible
   - reg

-- 
2.34.1



From Frank.Li at nxp.com  Thu Feb  1 12:22:44 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 01 Feb 2024 15:22:44 -0500
Subject: [PATCH v2 4/4] arm64: dts: imx8qm: add smmu stream id information
In-Reply-To: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
Message-ID: <20240201-8qm_smmu-v2-4-3d12a80201a3@nxp.com>

Add smmu stream id information for fec and esdhc.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
index ec1639174e2e5..3cbc861400b43 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
@@ -6,20 +6,26 @@
 
 &fec1 {
 	compatible = "fsl,imx8qm-fec", "fsl,imx6sx-fec";
+	iommus = <&smmu 0x12 0x7f80>;
 };
 
 &fec2 {
 	compatible = "fsl,imx8qm-fec", "fsl,imx6sx-fec";
+	iommus = <&smmu 0x12 0x7f80>;
 };
 
 &usdhc1 {
 	compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
+	iommus = <&smmu 0x11 0x7f80>;
 };
 
 &usdhc2 {
 	compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
+	iommus = <&smmu 0x11 0x7f80>;
 };
 
 &usdhc3 {
 	compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
+	iommus = <&smmu 0x11 0x7f80>;
 };
+

-- 
2.34.1



From oliver.upton at linux.dev  Thu Feb  1 12:30:19 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu,  1 Feb 2024 20:30:19 +0000
Subject: [PATCH 00/10] KVM: arm64: fix many kernel-doc warnings
In-Reply-To: <20240117230714.31025-1-rdunlap@infradead.org>
References: <20240117230714.31025-1-rdunlap@infradead.org>
Message-ID: <170681941355.2769902.10865128203340654876.b4-ty@linux.dev>

On Wed, 17 Jan 2024 15:07:04 -0800, Randy Dunlap wrote:
> Fix a bunch of kernel-doc warnings in arch/arm64/kvm/.
> 
>  [PATCH 01/10] KVM: arm64: debug: fix kernel-doc warnings
>  [PATCH 02/10] KVM: arm64: guest: fix kernel-doc warnings
>  [PATCH 03/10] KVM: arm64: hyp/aarch32: fix kernel-doc warnings
>  [PATCH 04/10] KVM: arm64: vhe: fix a kernel-doc warning
>  [PATCH 05/10] KVM: arm64: mmu: fix a kernel-doc warning
>  [PATCH 06/10] KVM: arm64: PMU: fix kernel-doc warnings
>  [PATCH 07/10] KVM: arm64: sys_regs: fix kernel-doc warnings
>  [PATCH 08/10] KVM: arm64: vgic-init: fix a kernel-doc warning
>  [PATCH 09/10] KVM: arm64: vgic-its: fix kernel-doc warnings
>  [PATCH 10/10] KVM: arm64: vgic: fix a kernel-doc warning
> 
> [...]

Applied to kvmarm/next, thanks!

[01/10] KVM: arm64: debug: fix kernel-doc warnings
        https://git.kernel.org/kvmarm/kvmarm/c/c4d15f841570
[02/10] KVM: arm64: guest: fix kernel-doc warnings
        https://git.kernel.org/kvmarm/kvmarm/c/39db66e6b404
[03/10] KVM: arm64: hyp/aarch32: fix kernel-doc warnings
        https://git.kernel.org/kvmarm/kvmarm/c/bc13610b4240
[04/10] KVM: arm64: vhe: fix a kernel-doc warning
        https://git.kernel.org/kvmarm/kvmarm/c/aa96af24f320
[05/10] KVM: arm64: mmu: fix a kernel-doc warning
        https://git.kernel.org/kvmarm/kvmarm/c/ffd9eaffa34d
[06/10] KVM: arm64: PMU: fix kernel-doc warnings
        https://git.kernel.org/kvmarm/kvmarm/c/2a00f0855530
[07/10] KVM: arm64: sys_regs: fix kernel-doc warnings
        https://git.kernel.org/kvmarm/kvmarm/c/8ce783927268
[08/10] KVM: arm64: vgic-init: fix a kernel-doc warning
        https://git.kernel.org/kvmarm/kvmarm/c/dd609a574a02
[09/10] KVM: arm64: vgic-its: fix kernel-doc warnings
        https://git.kernel.org/kvmarm/kvmarm/c/f779d2c0176c
[10/10] KVM: arm64: vgic: fix a kernel-doc warning
        https://git.kernel.org/kvmarm/kvmarm/c/e634ff9598a4

--
Best,
Oliver


From Frank.Li at nxp.com  Thu Feb  1 12:22:43 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Thu, 01 Feb 2024 15:22:43 -0500
Subject: [PATCH v2 3/4] arm64: dts: imx8qm: add smmu node
In-Reply-To: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
Message-ID: <20240201-8qm_smmu-v2-3-3d12a80201a3@nxp.com>

Add smmu node for imx8qm.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qm.dtsi | 41 +++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
index 31744fc1ab085..b3d01677b70c4 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
@@ -265,6 +265,47 @@ timer {
 			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */
 	};
 
+	smmu: iommu at 51400000 {
+		compatible = "arm,mmu-500";
+		interrupt-parent = <&gic>;
+		reg = <0 0x51400000 0 0x40000>;
+		#global-interrupts = <1>;
+		#iommu-cells = <2>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	system-controller {
 		compatible = "fsl,imx-scu";
 		mbox-names = "tx0",

-- 
2.34.1



From maskray at google.com  Thu Feb  1 12:56:14 2024
From: maskray at google.com (Fangrui Song)
Date: Thu, 1 Feb 2024 12:56:14 -0800
Subject: [PATCH] arm64: jump_label: use constraint "S" instead of "i"
In-Reply-To: <ZbvVApJ2/+yca0u6@e133380.arm.com>
References: <20240131065322.1126831-1-maskray@google.com>
 <CAMj1kXGzADFWa7RmXyjWpCnQ=9hhz6i-XkN4PS1CboZ-kFL8dQ@mail.gmail.com>
 <ZbpEnDK3U/O24ng0@e133380.arm.com>
 <20240201045551.ajg4iqcajyowl2rh@google.com>
 <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>
 <20240201091120.pbgr7ng6t2c36fut@google.com>
 <ZbuFWSRBntgm2ukJ@e133380.arm.com>
 <CAMj1kXGu76WHY8=Y-KhCxBq3xeHeCYQ9syqViSr9VRkjgWQ3BQ@mail.gmail.com>
 <ZbvVApJ2/+yca0u6@e133380.arm.com>
Message-ID: <20240201205614.w3gcz6urfxtydr77@google.com>

On 2024-02-01, Dave Martin wrote:
>On Thu, Feb 01, 2024 at 05:07:59PM +0100, Ard Biesheuvel wrote:
>> On Thu, 1 Feb 2024 at 12:50, Dave Martin <Dave.Martin at arm.com> wrote:
>> >
>> > On Thu, Feb 01, 2024 at 01:11:20AM -0800, Fangrui Song wrote:
>> ...
>> > >
>> > > Hmm. Clang's constraint "S" implementation doesn't support a constant
>> > > offset, so
>> > > `static_key_false(&nf_hooks_needed[pf][hook])` in include/linux/netfilter.h:nf_hook
>> > > would not compile with Clang <= 18.
>> > >
>> > > I have a patch https://github.com/llvm/llvm-project/pull/80255 , but
>> > > even if it is accepted and cherry-picked into the 18.x release branch,
>> > > if we still support older Clang, we cannot use "S" unconditionally.
>> > >
>> > >
>> > > So we probably need the following to prepare for -fPIE support in the
>> > > future:
>> > >
>> > > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
>> > > index 48ddc0f45d22..b8af2f8b0c99 100644
>> > > --- a/arch/arm64/include/asm/jump_label.h
>> > > +++ b/arch/arm64/include/asm/jump_label.h
>> > > @@ -15,6 +15,16 @@
>> > >  #define JUMP_LABEL_NOP_SIZE          AARCH64_INSN_SIZE
>> > > +/*
>> > > + * Prefer "S" to support PIC. However, use "i" for Clang 18 and earlier as "S"
>> > > + * on a symbol with a constant offset is not supported.
>> > > + */
>> > > +#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 18
>> >
>> > Is a GCC version check needed?  Or is the minimum GCC version specified
>> > for building the kernel new enough?
>> >
>> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
>> > > +#else
>> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "S"
>> > > +#endif
>> > > +
>>
>> Can we use "Si" instead?
>
>I thought the point was to avoid "S" on compilers that would choke on
>it?  If so, those compilers would surely choke on "Si" too, no?

"Si" is an invalid constraint. Unfortunately, GCC recognizes "S" as a
valid constraint and ignores trailing characters (asm_operand_ok). That
is, GCC would accept "Siiiii" as well...

The GCC support for "S" is great. The initial aarch64 port in 2012 supports "S".

>> > >  static __always_inline bool arch_static_branch(struct static_key * const key,
>> > >                                              const bool branch)
>> > >  {
>> > > @@ -23,9 +33,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
>> > >                "      .pushsection    __jump_table, \"aw\"    \n\t"
>> > >                "      .align          3                       \n\t"
>> > >                "      .long           1b - ., %l[l_yes] - .   \n\t"
>> > > -              "      .quad           %c0 - .                 \n\t"
>> > > +              "      .quad           %0 + %1 - .             \n\t"
>> > >                "      .popsection                             \n\t"
>> > > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
>> > > +              :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);
>> >
>> > While this looks reasonable, I'm still not clear now why the asm must do
>> > the addition.
>> >
>> > Can we roll the branch argument into the macro?
>> >
>> > "S"(symbol + constant) seems to do the right thing for AArch64, at least
>> > in GCC.
>> >
>>
>> 'symbol' is a struct static_key pointer, so adding '1' to it will not
>> produce the needed result.
>
>I mean loosely things that resolve to something of the form
>"symbol + constant" in the compiler output.
>
>"S"(&((char *)key)[branch]) does indeed seem to do the right thing,
>at least with GCC.
>
>I probably didn't help by bikeshedding the way that expression was
>written, apologies for that.  It's orthogonal to what this patch is
>doing.

Yes, "S"(&((char *)key)[branch])  would do the right thing.
I have compared assembly output. It's a matter of "s" vs "s + 0" and "s+1" vs "s + 1".

>>
>> ...
>> > > > > >If there's another reason why "S" is advantageous though, I'm happy to
>> > > > > >be corrected.
>> > > > >
>> > > > > I remember that Ard has an RFC
>> > > > > https://lore.kernel.org/linux-arm-kernel/20220427171241.2426592-1-ardb at kernel.org/
>> > > > > "[RFC PATCH 0/2] arm64: use PIE code generation for KASLR kernel"
>> > > > > and see some recent PIE codegen patches.
>> > > > >
>> > > > > > Building the KASLR kernel without -fpie but linking it with -pie works
>> > > > > > in practice, but it is not something that is explicitly supported by the
>> > > > > > toolchains - it happens to work because the default 'small' code model
>> > > > > > used by both GCC and Clang relies mostly on ADRP+ADD/LDR to generate
>> > > > > > symbol references.
>> >
>> > Does this mean that doing boot-time relocation on a fully statically
>> > linked kernel doesn't bring much benefit?
>>
>> Not sure I follow you here. The boot-time relocation is necessary in
>> any case, to fix up statically initialized pointer variables all over
>> the kernel.
>>
>> > It would tend to be more
>> > painful to do the relocation work, and mean that the kernel text has to
>> > be temporarily writeable, but static linking should have the best
>> > runtime performance.
>> >
>>
>> Not sure what you mean by 'static linking' here.
>>
>> The only thing PIE linking does in the case of the kernel is
>> a) complain if static relocations are used that cannot be fixed up at
>> runtime (e.g., movk/movz sequences)
>> b) emit dynamic relocations that the early startup code can use to fix
>> up all statically initialized pointers
>>
>> From a codegen point-of-view, there is no difference because we don't
>> use -fpic code. The problem with -fpic codegen is that it makes some
>> assumptions that only hold for shared ELF objects, e.g., avoiding
>> dynamic relocations in .text, using GOT entries even for variables
>> defined in the same compilation so that they can be preempted, keeping
>> all runtime relocatable quantities together so the CoW footprint of
>> the shared library is minimized.
>>
>> None of this matters for the kernel, and as it turns out, the non-PIC
>> small C model produces code that the PIE linker is happy with.
>>
>> TL;DR our code (including inline and out-of-line asm) is already PIC,
>> and this property is relied upon by KASLR.
>>
>> > Maybe it doesn't make as much difference as I thought (certainly ADRP
>> > based addressing should make a fair amount of the PIC/PIE overhead go
>> > away).
>> >
>>
>> The PIC/PIE overhead is in the indirections via the GOT. However,
>> recent linkers will actually perform some relaxations too: if a symbol
>> is defined in the same executable and is not preemptible, a GOT load
>>
>> ADRP
>> LDR
>>
>> can be transparently converted to
>>
>> ADRP
>> ADD
>>
>> referring to the symbol directly. This is also where hidden.h comes
>> in: making all symbol declarations and definitions 'hidden' will allow
>> the compiler to assume that a GOT entry is never needed.
>
>Is there a reason why we don't just build the whole kernel with
>-fvisibility=hidden today?

This topic, loosely related to this patch, is about switching to PIC
compiles. I am not familiar with the Linux kernel, so I'll mostly leave
the discussion to you and Ard :)

That said, I have done a lot of Clang work in visibility/symbol
preemptibility and linkers, so I am happy to add what I know.

-fvisibility=hidden only applies to definitions, not non-definition
declarations.

I've mentioned this at
https://lore.kernel.org/all/20220429070318.iwj3j5lpfkw4t7g2 at google.com/

     `#pragma GCC visibility push(hidden)` is very similar to -fvisibility=hidden -fdirect-access-external-data with Clang.
     ...
     The kernel uses neither TLS nor -fno-plt, so -fvisibility=hidden
     -fdirect-access-external-data can replace `#pragma GCC visibility
     push(hidden)`.

>> So building with -fPIC is currently not need in practice, and creates
>> some complications, which is why we have been avoiding it. But PIE
>> linking non-PIC objects is not guaranteed to remain supported going
>> forward, so it would be better to have a plan B, i.e., being able to
>> turn on -fpic without massive regressions due to GOT overhead, or
>> codegen problems with our asm hacks.
>
>Summarising all of this is it right that:
>
>1) ld -pie is how we get the reloc info into the kernel for KASLR
>today.
>
>2) We use gcc -fno-pic today, but this might break with ld -pie in the
>future, although it works for now.
>
>3) gcc -fno-pic and gcc -fPIC (or -fPIE) generate almost the same code,
>assuming we tweak symbol visibility and use a memory model that
>ADR+ADD/LDR can span.  So, moving to -fPIE is likely to be do-able.
>
>
>My point is that an alternative option would be to move to ld -no-pie.
>We would need another way to get relocs into the kernel, such as an
>intermediate step with ld --emit-relocs.  I have definitely seen this
>done before somewhere, but it would be extra work and not necessarily
>worth it, based on what you say about code gen.
>
>This may all have been discussed to death already -- I didn't mean to
>hijack this patch, so I'll stop digging here, but if I've misunderstood,
>please shout!
>
>Cheers
>---Dave


From robh at kernel.org  Thu Feb  1 13:03:17 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 1 Feb 2024 15:03:17 -0600
Subject: [PATCH v9 2/2] arm64: boot: Support Flat Image Tree
In-Reply-To: <CAK7LNAR-3rL6=YdhRRXB9dz+94y2yHTA=9mF4p7OPj7KExd7rg@mail.gmail.com>
References: <20231202035511.487946-1-sjg@chromium.org> <20231202035511.487946-3-sjg@chromium.org>
 <20231213121353.GA31326@willie-the-truck> <CAFLszTjfmSx1YMqzb2TsQf7sP4KrcQB=X7DY_HxRQp0J5HAppQ@mail.gmail.com>
 <CAK7LNAQRCDC03e=TVO=k4FuD2a2RdTy7yLr3UptQjVCX7pM1CA@mail.gmail.com>
 <20240109143349.GR1610741@bill-the-cat> <CAFLszTjwhy24UiT6kUJABMC1Xn0h9Q1q9fYpZZJg9DX8Vss9cA@mail.gmail.com>
 <CAFLszTjPAHd6RdO1mvatXC=yRS+h=sgJ_pMdyEnkROTx7yRpog@mail.gmail.com>
 <CAK7LNARsY6-rrx=sNFq6oFqpqf0s5S_=3DrUsCOS7zF0BXcoTg@mail.gmail.com>
 <CAL_JsqLYB0D5wAfedsb6tQp4EmD1AROgxiCncwO7gvA2p1C6Lg@mail.gmail.com> <CAK7LNAR-3rL6=YdhRRXB9dz+94y2yHTA=9mF4p7OPj7KExd7rg@mail.gmail.com>
Message-ID: <CAL_JsqLeTDALoKBuk9r+4NGXo0pc9LbK6bhDiZET+=UHG60fEA@mail.gmail.com>

On Wed, Jan 31, 2024 at 8:09?PM Masahiro Yamada <masahiroy at kernel.org> wrote:
>
> On Thu, Feb 1, 2024 at 7:03?AM Rob Herring <robh at kernel.org> wrote:
> >
> > On Tue, Jan 30, 2024 at 3:16?AM Masahiro Yamada <masahiroy at kernel.org> wrote:
> > >
> > > On Fri, Jan 26, 2024 at 1:04?AM Simon Glass <sjg at chromium.org> wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Wed, 17 Jan 2024 at 06:14, Simon Glass <sjg at chromium.org> wrote:
> > > > >
> > > > > Hi Masahiro, Tom,
> > > > >
> > > > > On Tue, 9 Jan 2024 at 07:33, Tom Rini <trini at konsulko.com> wrote:
> > > > > >
> > > > > > On Tue, Jan 09, 2024 at 11:01:42PM +0900, Masahiro Yamada wrote:
> > > > > > > Hi Simon,
> > > > > > >
> > > > > > >
> > > > > > > On Wed, Jan 3, 2024 at 8:47?AM Simon Glass <sjg at chromium.org> wrote:
> > > > > > > >
> > > > > > > > Hi Masahiro,
> > > > > > > >
> > > > > > > > On Wed, Dec 13, 2023 at 5:14?AM Will Deacon <will at kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > On Fri, Dec 01, 2023 at 08:54:42PM -0700, Simon Glass wrote:
> > > > > > > > > > Add a script which produces a Flat Image Tree (FIT), a single file
> > > > > > > > > > containing the built kernel and associated devicetree files.
> > > > > > > > > > Compression defaults to gzip which gives a good balance of size and
> > > > > > > > > > performance.
> > > > > > > > > >
> > > > > > > > > > The files compress from about 86MB to 24MB using this approach.
> > > > > > > > > >
> > > > > > > > > > The FIT can be used by bootloaders which support it, such as U-Boot
> > > > > > > > > > and Linuxboot. It permits automatic selection of the correct
> > > > > > > > > > devicetree, matching the compatible string of the running board with
> > > > > > > > > > the closest compatible string in the FIT. There is no need for
> > > > > > > > > > filenames or other workarounds.
> > > > > > > > > >
> > > > > > > > > > Add a 'make image.fit' build target for arm64, as well. Use
> > > > > > > > > > FIT_COMPRESSION to select a different algorithm.
> > > > > > > > > >
> > > > > > > > > > The FIT can be examined using 'dumpimage -l'.
> > > > > > > > > >
> > > > > > > > > > This features requires pylibfdt (use 'pip install libfdt'). It also
> > > > > > > > > > requires compression utilities for the algorithm being used. Supported
> > > > > > > > > > compression options are the same as the Image.xxx files. For now there
> > > > > > > > > > is no way to change the compression other than by editing the rule for
> > > > > > > > > > $(obj)/image.fit
> > > > > > > > > >
> > > > > > > > > > While FIT supports a ramdisk / initrd, no attempt is made to support
> > > > > > > > > > this here, since it must be built separately from the Linux build.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Simon Glass <sjg at chromium.org>
> > > > > > > > > > ---
> > > > > > > > > >
> > > > > > > > > > Changes in v9:
> > > > > > > > > > - Move the compression control into Makefile.lib
> > > > > > > > > >
> > > > > > > > > > Changes in v8:
> > > > > > > > > > - Drop compatible string in FDT node
> > > > > > > > > > - Correct sorting of MAINTAINERS to before ARM64 PORT
> > > > > > > > > > - Turn compress part of the make_fit.py comment in to a sentence
> > > > > > > > > > - Add two blank lines before parse_args() and setup_fit()
> > > > > > > > > > - Use 'image.fit: dtbs' instead of BUILD_DTBS var
> > > > > > > > > > - Use '$(<D)/dts' instead of '$(dir $<)dts'
> > > > > > > > > > - Add 'mkimage' details Documentation/process/changes.rst
> > > > > > > > > > - Allow changing the compression used
> > > > > > > > > > - Tweak cover letter since there is only one clean-up patch
> > > > > > > > > >
> > > > > > > > > > Changes in v7:
> > > > > > > > > > - Add Image as a dependency of image.fit
> > > > > > > > > > - Drop kbuild tag
> > > > > > > > > > - Add dependency on dtbs
> > > > > > > > > > - Drop unnecessary path separator for dtbs
> > > > > > > > > > - Rebase to -next
> > > > > > > > > >
> > > > > > > > > > Changes in v5:
> > > > > > > > > > - Drop patch previously applied
> > > > > > > > > > - Correct compression rule which was broken in v4
> > > > > > > > > >
> > > > > > > > > > Changes in v4:
> > > > > > > > > > - Use single quotes for UIMAGE_NAME
> > > > > > > > > >
> > > > > > > > > > Changes in v3:
> > > > > > > > > > - Drop temporary file image.itk
> > > > > > > > > > - Drop patch 'Use double quotes for image name'
> > > > > > > > > > - Drop double quotes in use of UIMAGE_NAME
> > > > > > > > > > - Drop unnecessary CONFIG_EFI_ZBOOT condition for help
> > > > > > > > > > - Avoid hard-coding "arm64" for the DT architecture
> > > > > > > > > >
> > > > > > > > > > Changes in v2:
> > > > > > > > > > - Drop patch previously applied
> > > > > > > > > > - Add .gitignore file
> > > > > > > > > > - Move fit rule to Makefile.lib using an intermediate file
> > > > > > > > > > - Drop dependency on CONFIG_EFI_ZBOOT
> > > > > > > > > > - Pick up .dtb files separately from the kernel
> > > > > > > > > > - Correct pylint too-many-args warning for write_kernel()
> > > > > > > > > > - Include the kernel image in the file count
> > > > > > > > > > - Add a pointer to the FIT spec and mention of its wide industry usage
> > > > > > > > > > - Mention the kernel version in the FIT description
> > > > > > > > > >
> > > > > > > > > >  Documentation/process/changes.rst |   9 +
> > > > > > > > > >  MAINTAINERS                       |   7 +
> > > > > > > > > >  arch/arm64/Makefile               |   7 +-
> > > > > > > > > >  arch/arm64/boot/.gitignore        |   1 +
> > > > > > > > > >  arch/arm64/boot/Makefile          |   6 +-
> > > > > > > > > >  scripts/Makefile.lib              |  16 ++
> > > > > > > > > >  scripts/make_fit.py               | 291 ++++++++++++++++++++++++++++++
> > > > > > > > > >  7 files changed, 334 insertions(+), 3 deletions(-)
> > > > > > > > > >  create mode 100755 scripts/make_fit.py
> > > > > > > > >
> > > > > > > > > I'll need Masahiro's Ack on the scripts/ changes before I can take this
> > > > > > > > > one.
> > > > > > > >
> > > > > > > > Any thoughts on this request, please?
> > > > > > > >
> > > > > > > > Regards,
> > > > > > > > Simon
> > > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > As I mentioned before, I am concerned with having
> > > > > > > the same "compatible" entries, with different contents,
> > > > > > > as you use the "compatible" string as an ID to selecting
> > > > > > > the target config node, right?
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > $ fdtdump  arch/arm64/boot/image.fit
> > > > > > >
> > > > > > >         ...
> > > > > > >
> > > > > > >         conf-10 {
> > > > > > >             compatible = "tq,am642-tqma6442l-mbax4xxl",
> > > > > > > "tq,am642-tqma6442l", "ti,am642";
> > > > > > >             description = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > > > >             fdt = "fdt-10";
> > > > > > >             kernel = "kernel";
> > > > > > >         };
> > > > > > >
> > > > > > >         ...
> > > > > > >
> > > > > > >         conf-25 {
> > > > > > >             compatible = "tq,am642-tqma6442l-mbax4xxl",
> > > > > > > "tq,am642-tqma6442l", "ti,am642";
> > > > > > >             description = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > > > >             fdt = "fdt-25";
> > > > > > >             kernel = "kernel";
> > > > > > >         };
> > > > > >
> > > > > > I had asked Rob a while ago about if having the same compatible for two
> > > > > > functionally different machines is a feature, or a bug, and I don't
> > > > > > think either of us fully agreed either way. I'd be leaning towards
> > > > > > saying the above example is a bug in the dts files, it's just not been a
> > > > > > bug people have worried about before due to (sadly) how little the
> > > > > > top-level compatible has been used.
> >
> > I much prefer being able to use compatibles over filenames.
> >
> > > > >
> > > > > Yes I believe this is a bug in the files.
> > > > >
> > > > > What should the script do in this case? Print a warning, perhaps?
> > > >
> > > > Is there anything I should do here? Would a warning be helpful, or
> > > > just confusing?
> > >
> > >
> > >
> > > I do not think it is useful.
> > > You would almost always get a warning, and there is no way to fix it.
> >
> > The above case is due to overlays. Why would you have a FIT image with
> > both a base tree and applied overlays?
>
>
>
> Because they are different hardware.

Meaning the base tree is valid on its own without any overlays?

> If FIT includes only base DTBs, how to use a base with extensions?

I would expect that you package up base and overlays or DTs with
already applied overlays, but not both together. That would be based
on whether your bootloader can apply overlays or not.

This problem boils down to your firmware knows or gains the knowledge
of some set of extra features or h/w pop options. The result is you
need base plus X, Y, Z whether those are a list of overlays or an
encoding of filename or something else. For example, FIT entries could
have a field that just lists those X, Y, Z features. But I'd much
rather have something that works outside of FIT images.

> > In any case, maybe we need to record in dtb overlays that have been
> > applied (which you asked about recently on dtc list). Not sure what
> > that looks like though. Overlays have a 'top-level' compatible that we
> > add in either separately or merged with the base's top-level
> > compatible?
>
>
> If there is a way to make "compatible" unique, that will be good.
>
> But, in my understanding, we can replace a property value,
> but not modify it.

Currently yes, but that shouldn't be too hard to add. The dtc
modification is the easy part. The hard part is figuring out the
policy around how we would use that.

But I don't really know what you want to accomplish with FIT here.
IMO, if you need filenames, then use a filesystem. They work pretty
well for storing large collections of files.

Rob


From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:24 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:24 -0800
Subject: [PATCH v4 05/10] iommu/arm-smmu: Allow using a threaded handler for context interrupts
In-Reply-To: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
Message-ID: <20240201210529.7728-6-quic_c_gdjako@quicinc.com>

Threaded IRQ handlers run in a less critical context compared to normal
IRQs, so they can perform more complex and time-consuming operations
without causing significant delays in other parts of the kernel.
During a context fault, it might be needed to do more processing and
gather debug information from TBUs in the handler. These operations may
sleep, so add an option to use a threaded IRQ handler in these cases.

Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 12 ++++++++++--
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  1 +
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 68b6bc5e7c71..978ef8ab042c 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -806,8 +806,16 @@ static int arm_smmu_init_domain_context(struct arm_smmu_domain *smmu_domain,
 	else
 		context_fault = arm_smmu_context_fault;
 
-	ret = devm_request_irq(smmu->dev, irq, context_fault, IRQF_SHARED,
-			       "arm-smmu-context-fault", smmu_domain);
+	if (smmu->impl && smmu->impl->context_fault_needs_threaded_irq)
+		ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
+						context_fault,
+						IRQF_ONESHOT | IRQF_SHARED,
+						"arm-smmu-context-fault",
+						smmu_domain);
+	else
+		ret = devm_request_irq(smmu->dev, irq, context_fault, IRQF_SHARED,
+				       "arm-smmu-context-fault", smmu_domain);
+
 	if (ret < 0) {
 		dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
 			cfg->irptndx, irq);
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index 17f704920190..54cb9dfcec76 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -438,6 +438,7 @@ struct arm_smmu_impl {
 	int (*def_domain_type)(struct device *dev);
 	irqreturn_t (*global_fault)(int irq, void *dev);
 	irqreturn_t (*context_fault)(int irq, void *dev);
+	bool context_fault_needs_threaded_irq;
 	int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain,
 				  struct arm_smmu_device *smmu,
 				  struct device *dev, int start);


From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:26 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:26 -0800
Subject: [PATCH v4 07/10] arm64: dts: qcom: sdm845: Add DT nodes for the TBUs
In-Reply-To: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
Message-ID: <20240201210529.7728-8-quic_c_gdjako@quicinc.com>

Add the device-tree nodes for the TBUs (translation buffer units) that
are present on the sdm845 platforms. The TBUs can be used debug the
kernel and provide additional information when a context faults occur.

Describe the all registers, clocks, interconnects and power-domain
resources that are needed for each of the TBUs.

Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 74 ++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index c20592fa7dc8..9ccb504d27af 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -15,6 +15,7 @@
 #include <dt-bindings/dma/qcom-gpi.h>
 #include <dt-bindings/firmware/qcom,scm.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
 #include <dt-bindings/interconnect/qcom,osm-l3.h>
 #include <dt-bindings/interconnect/qcom,sdm845.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -5014,6 +5015,7 @@ pil-reloc at 94c {
 		apps_smmu: iommu at 15000000 {
 			compatible = "qcom,sdm845-smmu-500", "arm,mmu-500";
 			reg = <0 0x15000000 0 0x80000>;
+			ranges;
 			#iommu-cells = <2>;
 			#global-interrupts = <1>;
 			interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
@@ -5081,6 +5083,78 @@ apps_smmu: iommu at 15000000 {
 				     <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+
+			anoc_1_tbu: tbu at 150c5000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x150c5000 0x0 0x1000>;
+				interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+				power-domains = <&gcc HLOS1_VOTE_AGGRE_NOC_MMU_TBU1_GDSC>;
+				stream-id-range = <0x0 0x400>;
+			};
+
+			anoc_2_tbu: tbu at 150c9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x150c9000 0x0 0x1000>;
+				interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+				power-domains = <&gcc HLOS1_VOTE_AGGRE_NOC_MMU_TBU2_GDSC>;
+				stream-id-range = <0x400 0x400>;
+			};
+
+			mnoc_hf_0_tbu: tbu at 150cd000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x150cd000 0x0 0x1000>;
+				interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY
+						 &mmss_noc SLAVE_MNOC_HF_MEM_NOC QCOM_ICC_TAG_ACTIVE_ONLY>;
+				stream-id-range = <0x800 0x400>;
+			};
+
+			mnoc_hf_1_tbu: tbu at 150d1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x150d1000 0x0 0x1000>;
+				interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY
+						 &mmss_noc SLAVE_MNOC_HF_MEM_NOC QCOM_ICC_TAG_ACTIVE_ONLY>;
+				stream-id-range = <0xc00 0x400>;
+			};
+
+			mnoc_sf_0_tbu: tbu at 150d5000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x150d5000 0x0 0x1000>;
+				interconnects = <&mmss_noc MASTER_CAMNOC_SF QCOM_ICC_TAG_ACTIVE_ONLY
+						 &mmss_noc SLAVE_MNOC_SF_MEM_NOC QCOM_ICC_TAG_ACTIVE_ONLY>;
+				stream-id-range = <0x1000 0x400>;
+			};
+
+			compute_dsp_tbu: tbu at 150d9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x150d9000 0x0 0x1000>;
+				interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+				stream-id-range = <0x1400 0x400>;
+			};
+
+			adsp_tbu: tbu at 150dd000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x150dd000 0x0 0x1000>;
+				interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+				power-domains = <&gcc HLOS1_VOTE_AGGRE_NOC_MMU_AUDIO_TBU_GDSC>;
+				stream-id-range = <0x1800 0x400>;
+			};
+
+			anoc_1_pcie_tbu: tbu at 150e1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x150e1000 0x0 0x1000>;
+				clocks = <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>;
+				interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+				power-domains = <&gcc HLOS1_VOTE_AGGRE_NOC_MMU_PCIE_TBU_GDSC>;
+				stream-id-range = <0x1c00 0x400>;
+			};
 		};
 
 		lpasscc: clock-controller at 17014000 {


From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:22 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:22 -0800
Subject: [PATCH v4 03/10] iommu/arm-smmu-qcom: Add support for TBUs
In-Reply-To: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
Message-ID: <20240201210529.7728-4-quic_c_gdjako@quicinc.com>

The ARM MMU-500 implements a Translation Buffer Unit (TBU) for each
connected master besides a single TCU which controls and manages the
address translations.

Allow the Qualcomm SMMU driver to probe for any TBU devices that can
provide additional debug features like triggering transactions, logging
outstanding transactions, snapshot capture etc. The primary use-case
would be to get information from a TBU and print it during a context
fault.

Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 9 +++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 4 +++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 8b04ece00420..ca806644e6eb 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -1,12 +1,14 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved
  */
 
 #include <linux/acpi.h>
 #include <linux/adreno-smmu-priv.h>
 #include <linux/delay.h>
 #include <linux/of_device.h>
+#include <linux/of_platform.h>
 #include <linux/firmware/qcom/qcom_scm.h>
 
 #include "arm-smmu.h"
@@ -446,6 +448,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
 	const struct device_node *np = smmu->dev->of_node;
 	const struct arm_smmu_impl *impl;
 	struct qcom_smmu *qsmmu;
+	int ret;
 
 	if (!data)
 		return ERR_PTR(-EINVAL);
@@ -469,6 +472,12 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
 	qsmmu->smmu.impl = impl;
 	qsmmu->cfg = data->cfg;
 
+	INIT_LIST_HEAD(&qsmmu->tbu_list);
+	mutex_init(&qsmmu->tbu_list_lock);
+	ret = devm_of_platform_populate(smmu->dev);
+	if (ret)
+		return ERR_PTR(ret);
+
 	return &qsmmu->smmu;
 }
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
index 593910567b88..77e5becc2482 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _ARM_SMMU_QCOM_H
@@ -12,6 +12,8 @@ struct qcom_smmu {
 	bool bypass_quirk;
 	u8 bypass_cbndx;
 	u32 stall_enabled;
+	struct mutex tbu_list_lock;  /* protects tbu_list */
+	struct list_head tbu_list;
 };
 
 enum qcom_smmu_impl_reg_offset {


From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:28 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:28 -0800
Subject: [PATCH v4 09/10] iommu/arm-smmu-qcom: Use the custom fault handler on more platforms
In-Reply-To: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
Message-ID: <20240201210529.7728-10-quic_c_gdjako@quicinc.com>

The TBU support is now available, so let's allow it to be used on other
platforms that have the Qualcomm SMMU-500 implementation with TBUs. This
will allow the context fault handler to query the TBUs when a context
fault occurs.

Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 2635f5b31455..0e587bd1cae8 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -414,6 +414,10 @@ static const struct arm_smmu_impl qcom_smmu_500_impl = {
 	.reset = arm_mmu500_reset,
 	.write_s2cr = qcom_smmu_write_s2cr,
 	.tlb_sync = qcom_smmu_tlb_sync,
+#ifdef CONFIG_ARM_SMMU_QCOM_TBU
+	.context_fault = qcom_smmu_context_fault,
+	.context_fault_needs_threaded_irq = true,
+#endif
 };
 
 static const struct arm_smmu_impl sdm845_smmu_500_impl = {


From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:27 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:27 -0800
Subject: [PATCH v4 08/10] dt-bindings: arm-smmu: Add TBU support for sc7280
In-Reply-To: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
Message-ID: <20240201210529.7728-9-quic_c_gdjako@quicinc.com>

Add the sc7280 SMMU to the platforms that have TBUs. This will allow
to validate the DT files against the json schema.

Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index 537e6a2fc02b..50ee76970a79 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -330,7 +330,9 @@ allOf:
       properties:
         compatible:
           contains:
-            const: qcom,sdm845-smmu-500
+            enum:
+              - qcom,sc7280-smmu-500
+              - qcom,sdm845-smmu-500
     then:
       patternProperties:
         "^tbu@[0-9a-f]+$":


From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:19 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:19 -0800
Subject: [PATCH v4 00/10] Add support for Translation Buffer Units
Message-ID: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>

The TCUs (Translation Control Units) and TBUs (Translation Buffer
Units) are key components of the MMU-500. Multiple TBUs are connected
to a single TCU over an interconnect. Each TBU contains a TLB that
caches page tables. The MMU-500 implements a TBU for each connected
master, and the TBU is designed, so that it is local to the master.
A common TBU DT schema is added to describe the TBUs.

The Qualcomm SDM845 and SC7280 platforms have an implementation of the
SMMU-500, that has multiple TBUs. A vendor-specific DT schema is added
to describe the resources for each TBU (register space, power-domains,
interconnects and clocks).

The TBU driver will manage the resources and allow the system to
operate the TBUs during a context fault to obtain details by doing
s1 inv, software + hardware page table walks etc. This is implemented
with ATOS/eCATs as the ATS feature is not supported. Being able to
query the TBUs is useful for debugging various hardware/software
issues on these platforms.

v4: 
- Create a common TBU schema. Move the vendor-specific properties into
  a separate schema that references the common one. (Rob)
- Drop unused DT labels in example, fix regex. (Rob)
- Properly rebase on latest code.

v3: https://lore.kernel.org/r/20231220060236.18600-1-quic_c_gdjako at quicinc.com
- Having a TBU is not Qualcomm specific, so allow having TBU child
  nodes with no specific constraints on properties. For some of the
  vendor compatibles however, add a schema to describe specific
  properties and allow validation. (Rob)
- Drop the useless reg-names DT property on TBUs. (Rob)
- Make the stream-id-range DT property a common one. (Rob)
- Fix the DT example. (Rob)
- Minor fixes on the TBU driver.
- Add support for SC7280 platforms.

v2: https://lore.kernel.org/r/20231118042730.2799-1-quic_c_gdjako at quicinc.com
- Improve DT binding description, add full example. (Konrad)
- Drop Qcom specific stuff from the generic binding. (Rob)
- Unconditionally try to populate subnodes. (Konrad)
- Improve TBU driver commit text, remove memory barriers. (Bjorn)
- Move TBU stuff into separate file. Make the driver builtin.
- TODO: Evaluate whether to keep TBU support as a separate driver
  or just instantiate things from qcom_smmu_impl_init()

v1: https://lore.kernel.org/r/20231019021923.13939-1-quic_c_gdjako at quicinc.com

Georgi Djakov (10):
  dt-bindings: iommu: Add Translation Buffer Unit bindings
  dt-bindings: iommu: Add Qualcomm TBU bindings
  iommu/arm-smmu-qcom: Add support for TBUs
  iommu/arm-smmu-qcom-tbu: Add Qualcomm TBU driver
  iommu/arm-smmu: Allow using a threaded handler for context interrupts
  iommu/arm-smmu-qcom: Use a custom context fault handler for sdm845
  arm64: dts: qcom: sdm845: Add DT nodes for the TBUs
  dt-bindings: arm-smmu: Add TBU support for sc7280
  iommu/arm-smmu-qcom: Use the custom fault handler on more platforms
  arm64: dts: qcom: sc7280: Add DT nodes for the TBUs

 .../devicetree/bindings/iommu/arm,smmu.yaml   |  26 +
 .../bindings/iommu/qcom,qsmmuv500-tbu.yaml    |  71 +++
 .../devicetree/bindings/iommu/tbu-common.yaml |  28 +
 arch/arm64/boot/dts/qcom/sc7280.dtsi          |  97 ++++
 arch/arm64/boot/dts/qcom/sdm845.dtsi          |  74 +++
 drivers/iommu/Kconfig                         |   8 +
 drivers/iommu/arm/arm-smmu/Makefile           |   1 +
 .../iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c    | 496 ++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c    |  17 +
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h    |   6 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c         |  12 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.h         |   3 +
 12 files changed, 836 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iommu/qcom,qsmmuv500-tbu.yaml
 create mode 100644 Documentation/devicetree/bindings/iommu/tbu-common.yaml
 create mode 100644 drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c



From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:21 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:21 -0800
Subject: [PATCH v4 02/10] dt-bindings: iommu: Add Qualcomm TBU bindings
In-Reply-To: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
Message-ID: <20240201210529.7728-3-quic_c_gdjako@quicinc.com>

The "apps_smmu" on the Qualcomm sdm845 platform is an implementation
of the SMMU-500, that consists of a single TCU (Translation Control
Unit) and multiple TBUs (Translation Buffer Units). The TCU is already
being described in the ARM SMMU schema and now we have also a common
schema for TBUs. The TBUs on Qualcomm platforms have some additional
hardware resources that need to be described in the schema. Create a
vendor-specific TBU schema to include all the needed resources like
clocks, power domains and interconnects.

Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
---
 .../devicetree/bindings/iommu/arm,smmu.yaml   | 10 +++
 .../bindings/iommu/qcom,qsmmuv500-tbu.yaml    | 71 +++++++++++++++++++
 2 files changed, 81 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/qcom,qsmmuv500-tbu.yaml

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index ba3237023b39..537e6a2fc02b 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -326,6 +326,16 @@ allOf:
                     through the TCU's programming interface.
                 - description: bus clock required for the smmu ptw
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: qcom,sdm845-smmu-500
+    then:
+      patternProperties:
+        "^tbu@[0-9a-f]+$":
+          $ref: qcom,qsmmuv500-tbu.yaml#
+
   - if:
       properties:
         compatible:
diff --git a/Documentation/devicetree/bindings/iommu/qcom,qsmmuv500-tbu.yaml b/Documentation/devicetree/bindings/iommu/qcom,qsmmuv500-tbu.yaml
new file mode 100644
index 000000000000..0e86e1c42133
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/qcom,qsmmuv500-tbu.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/qcom,qsmmuv500-tbu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm TBU (Translation Buffer Unit)
+
+maintainers:
+  - Georgi Djakov <quic_c_gdjako at quicinc.com>
+
+description:
+  The Qualcomm SMMU500 implementation consists of TCU and TBU. The TBU contains
+  a Translation Lookaside Buffer (TLB) that caches page tables. TBUs provides
+  debug features to trace and trigger debug transactions. There are multiple TBU
+  instances with each client core.
+
+allOf:
+  - $ref: tbu-common.yaml#
+
+properties:
+  compatible:
+    const: qcom,qsmmuv500-tbu
+
+  clocks:
+    maxItems: 1
+
+  interconnects:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - stream-id-range
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-sdm845.h>
+    #include <dt-bindings/interconnect/qcom,icc.h>
+    #include <dt-bindings/interconnect/qcom,sdm845.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/qcom-rpmpd.h>
+
+    iommu at 15000000 {
+        compatible = "qcom,sdm845-smmu-500", "arm,mmu-500";
+        reg = <0x15000000 0x80000>;
+        ranges = <0 0 0 0 0xffffffff>;
+        #iommu-cells = <2>;
+        #global-interrupts = <1>;
+        interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>;
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        tbu at 150e1000 {
+            compatible = "qcom,qsmmuv500-tbu";
+            reg = <0x0 0x150e1000 0x0 0x1000>;
+            clocks = <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>;
+            interconnects = <&system_noc MASTER_GNOC_SNOC QCOM_ICC_TAG_ACTIVE_ONLY
+                             &config_noc SLAVE_IMEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+            power-domains = <&gcc HLOS1_VOTE_AGGRE_NOC_MMU_PCIE_TBU_GDSC>;
+            stream-id-range = <0x1c00 0x400>;
+        };
+    };
+...


From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:29 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:29 -0800
Subject: [PATCH v4 10/10] arm64: dts: qcom: sc7280: Add DT nodes for the TBUs
In-Reply-To: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
Message-ID: <20240201210529.7728-11-quic_c_gdjako@quicinc.com>

Add the device-tree nodes for the TBUs (translation buffer units) that
are present on the sc7280 platforms. The TBUs can be used debug the
kernel and provide additional information when a context faults occur.

Describe the all registers, clocks, interconnects and power-domain
resources that are needed for each of the TBUs.

Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi | 97 ++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index c3a94c4c6490..9fbba9d7b090 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -2881,6 +2881,7 @@ adreno_smmu: iommu at 3da0000 {
 			compatible = "qcom,sc7280-smmu-500", "qcom,adreno-smmu",
 				     "qcom,smmu-500", "arm,mmu-500";
 			reg = <0 0x03da0000 0 0x20000>;
+			ranges;
 			#iommu-cells = <2>;
 			#global-interrupts = <2>;
 			interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
@@ -2913,6 +2914,21 @@ adreno_smmu: iommu at 3da0000 {
 
 			power-domains = <&gpucc GPU_CC_CX_GDSC>;
 			dma-coherent;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+
+			gfx_0_tbu: tbu at 3dd9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x3dd9000 0x0 0x1000>;
+				stream-id-range = <0x0 0x400>;
+			};
+
+			gfx_1_tbu: tbu at 3ddd000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x3ddd000 0x0 0x1000>;
+				stream-id-range = <0x400 0x400>;
+			};
 		};
 
 		remoteproc_mpss: remoteproc at 4080000 {
@@ -5637,6 +5653,7 @@ pil-reloc at 594c {
 		apps_smmu: iommu at 15000000 {
 			compatible = "qcom,sc7280-smmu-500", "arm,mmu-500";
 			reg = <0 0x15000000 0 0x100000>;
+			ranges;
 			#iommu-cells = <2>;
 			#global-interrupts = <1>;
 			dma-coherent;
@@ -5721,6 +5738,86 @@ apps_smmu: iommu at 15000000 {
 				     <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+
+			anoc_1_tbu: tbu at 151dd000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151dd000 0x0 0x1000>;
+				interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &cnoc3 SLAVE_TCU QCOM_ICC_TAG_ACTIVE_ONLY>;
+				stream-id-range = <0x0 0x400>;
+			};
+
+			anoc_2_tbu: tbu at 151e1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151e1000 0x0 0x1000>;
+				interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &cnoc3 SLAVE_TCU QCOM_ICC_TAG_ACTIVE_ONLY>;
+				stream-id-range = <0x400 0x400>;
+			};
+
+			mnoc_hf_0_tbu: tbu at 151e5000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151e5000 0x0 0x1000>;
+				interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+				power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC>;
+				stream-id-range = <0x800 0x400>;
+			};
+
+			mnoc_hf_1_tbu: tbu at 151e9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151e9000 0x0 0x1000>;
+				interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ACTIVE_ONLY
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+				power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC>;
+				stream-id-range = <0xc00 0x400>;
+			};
+
+			compute_dsp_0_tbu: tbu at 151ed000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151ed000 0x0 0x1000>;
+				interconnects = <&nsp_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+				power-domains = <&gcc HLOS1_VOTE_TURING_MMU_TBU1_GDSC>;
+				stream-id-range = <0x1000 0x400>;
+			};
+
+			compute_dsp_1_tbu: tbu at 151f1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151f1000 0x0 0x1000>;
+				interconnects = <&nsp_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+				power-domains = <&gcc HLOS1_VOTE_TURING_MMU_TBU0_GDSC>;
+				stream-id-range = <0x1400 0x400>;
+			};
+
+			adsp_tbu: tbu at 151f5000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151f5000 0x0 0x1000>;
+				interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &lpass_ag_noc SLAVE_LPASS_CORE_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+				stream-id-range = <0x1800 0x400>;
+			};
+
+			anoc_1_pcie_tbu: tbu at 151f9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151f9000 0x0 0x1000>;
+				interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+						 &cnoc3 SLAVE_TCU QCOM_ICC_TAG_ACTIVE_ONLY>;
+				stream-id-range = <0x1c00 0x400>;
+			};
+
+			mnoc_sf_0_tbu: tbu at 151fd000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151fd000 0x0 0x1000>;
+				interconnects = <&mmss_noc MASTER_CAMNOC_SF QCOM_ICC_TAG_ACTIVE_ONLY
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+				power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_SF0_GDSC>;
+				stream-id-range = <0x2000 0x400>;
+			};
 		};
 
 		intc: interrupt-controller at 17a00000 {


From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:20 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:20 -0800
Subject: [PATCH v4 01/10] dt-bindings: iommu: Add Translation Buffer Unit bindings
In-Reply-To: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
Message-ID: <20240201210529.7728-2-quic_c_gdjako@quicinc.com>

Add common bindings for the TBUs to describe their properties. The
TBUs are modelled as child devices of the IOMMU and each of them is
described with their compatible, reg and stream-id-range properties.
There could be other implementation specific properties to describe
any resources like clocks, regulators, power-domains, interconnects
that would be needed for TBU operation. Such properties will be
documented in a separate vendor-specific TBU schema.

Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
---
 .../devicetree/bindings/iommu/arm,smmu.yaml   | 14 ++++++++++
 .../devicetree/bindings/iommu/tbu-common.yaml | 28 +++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/tbu-common.yaml

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index a4042ae24770..ba3237023b39 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -235,6 +235,20 @@ properties:
       enabled for any given device.
     $ref: /schemas/types.yaml#/definitions/phandle
 
+  '#address-cells':
+    enum: [ 1, 2 ]
+
+  '#size-cells':
+    enum: [ 1, 2 ]
+
+  ranges: true
+
+patternProperties:
+  "^tbu@[0-9a-f]+$":
+    description: TBU child nodes
+    type: object
+    $ref: tbu-common.yaml#
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/iommu/tbu-common.yaml b/Documentation/devicetree/bindings/iommu/tbu-common.yaml
new file mode 100644
index 000000000000..3e95b356e572
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/tbu-common.yaml
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/tbu-common.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Translation Buffer Unit (TBU) common properties
+
+maintainers:
+  - Georgi Djakov <quic_c_gdjako at quicinc.com>
+
+description:
+  The SMMU implements a TBU for system masters. It consists if a
+  Translation Lookaside Buffer (TLB) that caches page tables.
+
+properties:
+  reg:
+    maxItems: 1
+
+  stream-id-range:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: Stream ID range (address and size) that is assigned by the TBU
+    items:
+      minItems: 2
+      maxItems: 2
+
+additionalProperties: true
+...


From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:25 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:25 -0800
Subject: [PATCH v4 06/10] iommu/arm-smmu-qcom: Use a custom context fault handler for sdm845
In-Reply-To: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
Message-ID: <20240201210529.7728-7-quic_c_gdjako@quicinc.com>

The sdm845 platform now supports TBUs, so let's get additional debug
info from the TBUs when a context fault occurs. Implement a custom
context fault handler that does both software + hardware page table
walks and TLB Invalidate All.

Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
---
 .../iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c    | 130 ++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c    |   4 +
 2 files changed, 134 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c
index c00f89f223bd..167e3616f021 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c
@@ -301,6 +301,136 @@ static phys_addr_t qsmmuv500_iova_to_phys(struct arm_smmu_domain *smmu_domain,
 	return phys;
 }
 
+static phys_addr_t qcom_smmu_iova_to_phys_hard(struct arm_smmu_domain *smmu_domain, dma_addr_t iova)
+{
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	int idx = smmu_domain->cfg.cbndx;
+	u32 frsynra;
+	u16 sid;
+
+	frsynra = arm_smmu_gr1_read(smmu, ARM_SMMU_GR1_CBFRSYNRA(idx));
+	sid = FIELD_GET(ARM_SMMU_CBFRSYNRA_SID, frsynra);
+
+	return qsmmuv500_iova_to_phys(smmu_domain, iova, sid);
+}
+
+static phys_addr_t qcom_smmu_verify_fault(struct arm_smmu_domain *smmu_domain, dma_addr_t iova, u32 fsr)
+{
+	struct io_pgtable *iop = io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	phys_addr_t phys_post_tlbiall;
+	phys_addr_t phys;
+
+	phys = qcom_smmu_iova_to_phys_hard(smmu_domain, iova);
+	io_pgtable_tlb_flush_all(iop);
+	phys_post_tlbiall = qcom_smmu_iova_to_phys_hard(smmu_domain, iova);
+
+	if (phys != phys_post_tlbiall) {
+		dev_err(smmu->dev,
+			"ATOS results differed across TLBIALL... (before: %pa after: %pa)\n",
+			&phys, &phys_post_tlbiall);
+	}
+
+	return (phys == 0 ? phys_post_tlbiall : phys);
+}
+
+irqreturn_t qcom_smmu_context_fault(int irq, void *dev)
+{
+	struct arm_smmu_domain *smmu_domain = dev;
+	struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	u32 fsr, fsynr, cbfrsynra, resume = 0;
+	int idx = smmu_domain->cfg.cbndx;
+	phys_addr_t phys_soft;
+	unsigned long iova;
+	int ret, tmp;
+
+	static DEFINE_RATELIMIT_STATE(_rs,
+				      DEFAULT_RATELIMIT_INTERVAL,
+				      DEFAULT_RATELIMIT_BURST);
+
+	fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
+	if (!(fsr & ARM_SMMU_FSR_FAULT))
+		return IRQ_NONE;
+
+	fsynr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSYNR0);
+	iova = arm_smmu_cb_readq(smmu, idx, ARM_SMMU_CB_FAR);
+	cbfrsynra = arm_smmu_gr1_read(smmu, ARM_SMMU_GR1_CBFRSYNRA(idx));
+
+	phys_soft = ops->iova_to_phys(ops, iova);
+
+	tmp = report_iommu_fault(&smmu_domain->domain, NULL, iova,
+				 fsynr & ARM_SMMU_FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ);
+	if (!tmp || tmp == -EBUSY) {
+		dev_dbg(smmu->dev,
+			"Context fault handled by client: iova=0x%08lx, fsr=0x%x, fsynr=0x%x, cb=%d\n",
+			iova, fsr, fsynr, idx);
+		dev_dbg(smmu->dev, "soft iova-to-phys=%pa\n", &phys_soft);
+		ret = IRQ_HANDLED;
+		resume = ARM_SMMU_RESUME_TERMINATE;
+	} else {
+		phys_addr_t phys_atos = qcom_smmu_verify_fault(smmu_domain, iova, fsr);
+
+		if (__ratelimit(&_rs)) {
+			dev_err(smmu->dev,
+				"Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cbfrsynra=0x%x, cb=%d\n",
+				fsr, iova, fsynr, cbfrsynra, idx);
+			dev_err(smmu->dev,
+				"FSR    = %08x [%s%s%s%s%s%s%s%s%s], SID=0x%x\n",
+				fsr,
+				(fsr & 0x02) ? "TF " : "",
+				(fsr & 0x04) ? "AFF " : "",
+				(fsr & 0x08) ? "PF " : "",
+				(fsr & 0x10) ? "EF " : "",
+				(fsr & 0x20) ? "TLBMCF " : "",
+				(fsr & 0x40) ? "TLBLKF " : "",
+				(fsr & 0x80) ? "MHF " : "",
+				(fsr & 0x40000000) ? "SS " : "",
+				(fsr & 0x80000000) ? "MULTI " : "",
+				cbfrsynra);
+
+			dev_err(smmu->dev,
+				"soft iova-to-phys=%pa\n", &phys_soft);
+			if (!phys_soft)
+				dev_err(smmu->dev,
+					"SOFTWARE TABLE WALK FAILED! Looks like %s accessed an unmapped address!\n",
+					dev_name(smmu->dev));
+			if (phys_atos)
+				dev_err(smmu->dev, "hard iova-to-phys (ATOS)=%pa\n",
+					&phys_atos);
+			else
+				dev_err(smmu->dev, "hard iova-to-phys (ATOS) failed\n");
+		}
+		ret = IRQ_NONE;
+		resume = ARM_SMMU_RESUME_TERMINATE;
+	}
+
+	/*
+	 * If the client returns -EBUSY, do not clear FSR and do not RESUME
+	 * if stalled. This is required to keep the IOMMU client stalled on
+	 * the outstanding fault. This gives the client a chance to take any
+	 * debug action and then terminate the stalled transaction.
+	 * So, the sequence in case of stall on fault should be:
+	 * 1) Do not clear FSR or write to RESUME here
+	 * 2) Client takes any debug action
+	 * 3) Client terminates the stalled transaction and resumes the IOMMU
+	 * 4) Client clears FSR. The FSR should only be cleared after 3) and
+	 *    not before so that the fault remains outstanding. This ensures
+	 *    SCTLR.HUPCF has the desired effect if subsequent transactions also
+	 *    need to be terminated.
+	 */
+	if (tmp != -EBUSY) {
+		/* Clear the faulting FSR */
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
+
+		/* Retry or terminate any stalled transactions */
+		if (fsr & ARM_SMMU_FSR_SS)
+			arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_RESUME, resume);
+	}
+
+	return ret;
+}
+
 static int qsmmuv500_tbu_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index ca806644e6eb..2635f5b31455 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -423,6 +423,10 @@ static const struct arm_smmu_impl sdm845_smmu_500_impl = {
 	.reset = qcom_sdm845_smmu500_reset,
 	.write_s2cr = qcom_smmu_write_s2cr,
 	.tlb_sync = qcom_smmu_tlb_sync,
+#ifdef CONFIG_ARM_SMMU_QCOM_TBU
+	.context_fault = qcom_smmu_context_fault,
+	.context_fault_needs_threaded_irq = true,
+#endif
 };
 
 static const struct arm_smmu_impl qcom_adreno_smmu_v2_impl = {


From quic_c_gdjako at quicinc.com  Thu Feb  1 13:05:23 2024
From: quic_c_gdjako at quicinc.com (Georgi Djakov)
Date: Thu, 1 Feb 2024 13:05:23 -0800
Subject: [PATCH v4 04/10] iommu/arm-smmu-qcom-tbu: Add Qualcomm TBU driver
In-Reply-To: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
Message-ID: <20240201210529.7728-5-quic_c_gdjako@quicinc.com>

Add a driver for the Qualcomm implementation of the MMU-500 TBU.

Operating the TBUs (Translation Buffer Units) from Linux can help
with debugging context faults. The TBUs can provide debug features
such as running ATOS (Address Translation Operations) to manually
trigger address translation of IOVA to physical address in hardware.

The driver will control the resources needed by the TBU to allow
running ATOS on the TBUs or check for outstanding transactions.

Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
---
 drivers/iommu/Kconfig                         |   8 +
 drivers/iommu/arm/arm-smmu/Makefile           |   1 +
 .../iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c    | 366 ++++++++++++++++++
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h    |   2 +
 drivers/iommu/arm/arm-smmu/arm-smmu.h         |   2 +
 5 files changed, 379 insertions(+)
 create mode 100644 drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 9a29d742617e..314dc5dbe7ea 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -371,6 +371,14 @@ config ARM_SMMU_QCOM
 	  When running on a Qualcomm platform that has the custom variant
 	  of the ARM SMMU, this needs to be built into the SMMU driver.
 
+config ARM_SMMU_QCOM_TBU
+	bool "Qualcomm TBU driver"
+	depends on ARM_SMMU_QCOM
+	help
+	  The SMMU on Qualcomm platform may include a Translation Buffer
+	  Units (TBUs) for each master. Enabling support for these will
+	  allow operating the TBUs to help debugging context faults.
+
 config ARM_SMMU_QCOM_DEBUG
 	bool "ARM SMMU QCOM implementation defined debug support"
 	depends on ARM_SMMU_QCOM
diff --git a/drivers/iommu/arm/arm-smmu/Makefile b/drivers/iommu/arm/arm-smmu/Makefile
index 2a5a95e8e3f9..c35ff78fcfd5 100644
--- a/drivers/iommu/arm/arm-smmu/Makefile
+++ b/drivers/iommu/arm/arm-smmu/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
 obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
 arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o
 arm_smmu-$(CONFIG_ARM_SMMU_QCOM) += arm-smmu-qcom.o
+arm_smmu-$(CONFIG_ARM_SMMU_QCOM_TBU) += arm-smmu-qcom-tbu.o
 arm_smmu-$(CONFIG_ARM_SMMU_QCOM_DEBUG) += arm-smmu-qcom-debug.o
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c
new file mode 100644
index 000000000000..c00f89f223bd
--- /dev/null
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c
@@ -0,0 +1,366 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved
+ */
+
+#include <linux/interconnect.h>
+#include <linux/iopoll.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#include "arm-smmu.h"
+#include "arm-smmu-qcom.h"
+
+#define TBU_DBG_TIMEOUT_US		100
+#define DEBUG_AXUSER_REG		0x30
+#define DEBUG_AXUSER_CDMID		GENMASK_ULL(43, 36)
+#define DEBUG_AXUSER_CDMID_VAL		0xff
+#define DEBUG_PAR_REG			0x28
+#define DEBUG_PAR_FAULT_VAL		BIT(0)
+#define DEBUG_PAR_PA			GENMASK_ULL(47, 12)
+#define DEBUG_SID_HALT_REG		0x0
+#define DEBUG_SID_HALT_VAL		BIT(16)
+#define DEBUG_SID_HALT_SID		GENMASK(9, 0)
+#define DEBUG_SR_HALT_ACK_REG		0x20
+#define DEBUG_SR_HALT_ACK_VAL		BIT(1)
+#define DEBUG_SR_ECATS_RUNNING_VAL	BIT(0)
+#define DEBUG_TXN_AXCACHE		GENMASK(5, 2)
+#define DEBUG_TXN_AXPROT		GENMASK(8, 6)
+#define DEBUG_TXN_AXPROT_PRIV		0x1
+#define DEBUG_TXN_AXPROT_NSEC		0x2
+#define DEBUG_TXN_TRIGG_REG		0x18
+#define DEBUG_TXN_TRIGGER		BIT(0)
+#define DEBUG_VA_ADDR_REG		0x8
+
+struct qsmmuv500_tbu {
+	struct device *dev;
+	struct arm_smmu_device *smmu;
+	u32 sid_range[2];
+	struct list_head list;
+	struct clk *clk;
+	struct icc_path	*path;
+	void __iomem *base;
+	spinlock_t halt_lock; /* multiple halt or resume can't execute concurrently */
+	int halt_count;
+};
+
+static DEFINE_SPINLOCK(atos_lock);
+
+static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
+{
+	return container_of(smmu, struct qcom_smmu, smmu);
+}
+
+static struct qsmmuv500_tbu *qsmmuv500_find_tbu(struct qcom_smmu *qsmmu, u32 sid)
+{
+	struct qsmmuv500_tbu *tbu = NULL;
+	u32 start, end;
+
+	mutex_lock(&qsmmu->tbu_list_lock);
+
+	list_for_each_entry(tbu, &qsmmu->tbu_list, list) {
+		start = tbu->sid_range[0];
+		end = start + tbu->sid_range[1];
+
+		if (start <= sid && sid < end)
+			break;
+	}
+
+	mutex_unlock(&qsmmu->tbu_list_lock);
+
+	return tbu;
+}
+
+static int qsmmuv500_tbu_halt(struct qsmmuv500_tbu *tbu, struct arm_smmu_domain *smmu_domain)
+{
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	int ret = 0, idx = smmu_domain->cfg.cbndx;
+	unsigned long flags;
+	u32 val, fsr, status;
+
+	spin_lock_irqsave(&tbu->halt_lock, flags);
+	if (tbu->halt_count) {
+		tbu->halt_count++;
+		goto out;
+	}
+
+	val = readl_relaxed(tbu->base + DEBUG_SID_HALT_REG);
+	val |= DEBUG_SID_HALT_VAL;
+	writel_relaxed(val, tbu->base + DEBUG_SID_HALT_REG);
+
+	fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
+	if ((fsr & ARM_SMMU_FSR_FAULT) && (fsr & ARM_SMMU_FSR_SS)) {
+		u32 sctlr_orig, sctlr;
+
+		/*
+		 * We are in a fault. Our request to halt the bus will not
+		 * complete until transactions in front of us (such as the fault
+		 * itself) have completed. Disable iommu faults and terminate
+		 * any existing transactions.
+		 */
+		sctlr_orig = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_SCTLR);
+		sctlr = sctlr_orig & ~(ARM_SMMU_SCTLR_CFCFG | ARM_SMMU_SCTLR_CFIE);
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, sctlr);
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_RESUME, ARM_SMMU_RESUME_TERMINATE);
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, sctlr_orig);
+	}
+
+	if (readl_poll_timeout_atomic(tbu->base + DEBUG_SR_HALT_ACK_REG, status,
+				      (status & DEBUG_SR_HALT_ACK_VAL),
+				      0, TBU_DBG_TIMEOUT_US)) {
+		dev_err(tbu->dev, "Timeout while trying to halt TBU!\n");
+		ret = -ETIMEDOUT;
+
+		val = readl_relaxed(tbu->base + DEBUG_SID_HALT_REG);
+		val &= ~DEBUG_SID_HALT_VAL;
+		writel_relaxed(val, tbu->base + DEBUG_SID_HALT_REG);
+
+		goto out;
+	}
+
+	tbu->halt_count = 1;
+
+out:
+	spin_unlock_irqrestore(&tbu->halt_lock, flags);
+	return ret;
+}
+
+static void qsmmuv500_tbu_resume(struct qsmmuv500_tbu *tbu)
+{
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&tbu->halt_lock, flags);
+	if (!tbu->halt_count) {
+		WARN(1, "%s: halt_count is 0", dev_name(tbu->dev));
+		goto out;
+	}
+
+	if (tbu->halt_count > 1) {
+		tbu->halt_count--;
+		goto out;
+	}
+
+	val = readl_relaxed(tbu->base + DEBUG_SID_HALT_REG);
+	val &= ~DEBUG_SID_HALT_VAL;
+	writel_relaxed(val, tbu->base + DEBUG_SID_HALT_REG);
+
+	tbu->halt_count = 0;
+out:
+	spin_unlock_irqrestore(&tbu->halt_lock, flags);
+}
+
+static phys_addr_t qsmmuv500_tbu_trigger_atos(struct arm_smmu_domain *smmu_domain,
+					      struct qsmmuv500_tbu *tbu, dma_addr_t iova, u32 sid)
+{
+	bool atos_timedout = false;
+	phys_addr_t phys = 0;
+	ktime_t timeout;
+	u64 val;
+
+	/* Set address and stream-id */
+	val = readq_relaxed(tbu->base + DEBUG_SID_HALT_REG);
+	val &= ~DEBUG_SID_HALT_SID;
+	val |= FIELD_PREP(DEBUG_SID_HALT_SID, sid);
+	writeq_relaxed(val, tbu->base + DEBUG_SID_HALT_REG);
+	writeq_relaxed(iova, tbu->base + DEBUG_VA_ADDR_REG);
+	val = FIELD_PREP(DEBUG_AXUSER_CDMID, DEBUG_AXUSER_CDMID_VAL);
+	writeq_relaxed(val, tbu->base + DEBUG_AXUSER_REG);
+
+	/* Write-back read and write-allocate */
+	val = FIELD_PREP(DEBUG_TXN_AXCACHE, 0xf);
+
+	/* Non-secure access */
+	val |= FIELD_PREP(DEBUG_TXN_AXPROT, DEBUG_TXN_AXPROT_NSEC);
+
+	/* Privileged access */
+	val |= FIELD_PREP(DEBUG_TXN_AXPROT, DEBUG_TXN_AXPROT_PRIV);
+
+	val |= DEBUG_TXN_TRIGGER;
+	writeq_relaxed(val, tbu->base + DEBUG_TXN_TRIGG_REG);
+
+	timeout = ktime_add_us(ktime_get(), TBU_DBG_TIMEOUT_US);
+	for (;;) {
+		val = readl_relaxed(tbu->base + DEBUG_SR_HALT_ACK_REG);
+		if (!(val & DEBUG_SR_ECATS_RUNNING_VAL))
+			break;
+		val = readl_relaxed(tbu->base + DEBUG_PAR_REG);
+		if (val & DEBUG_PAR_FAULT_VAL)
+			break;
+		if (ktime_compare(ktime_get(), timeout) > 0) {
+			atos_timedout = true;
+			break;
+		}
+	}
+
+	val = readq_relaxed(tbu->base + DEBUG_PAR_REG);
+	if (val & DEBUG_PAR_FAULT_VAL)
+		dev_err(tbu->dev, "ATOS generated a fault interrupt! PAR = %llx, SID=0x%x\n",
+			val, sid);
+	else if (atos_timedout)
+		dev_err_ratelimited(tbu->dev, "ATOS translation timed out!\n");
+	else
+		phys = FIELD_GET(DEBUG_PAR_PA, val);
+
+	/* Reset hardware */
+	writeq_relaxed(0, tbu->base + DEBUG_TXN_TRIGG_REG);
+	writeq_relaxed(0, tbu->base + DEBUG_VA_ADDR_REG);
+	val = readl_relaxed(tbu->base + DEBUG_SID_HALT_REG);
+	val &= ~DEBUG_SID_HALT_SID;
+	writel_relaxed(val, tbu->base + DEBUG_SID_HALT_REG);
+
+	return phys;
+}
+
+static phys_addr_t qsmmuv500_iova_to_phys(struct arm_smmu_domain *smmu_domain,
+					  dma_addr_t iova, u32 sid)
+{
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+	int idx = smmu_domain->cfg.cbndx;
+	struct qsmmuv500_tbu *tbu;
+	u32 sctlr_orig, sctlr;
+	phys_addr_t phys = 0;
+	unsigned long flags;
+	int attempt = 0;
+	int ret;
+	u64 fsr;
+
+	tbu = qsmmuv500_find_tbu(qsmmu, sid);
+	if (!tbu)
+		return 0;
+
+	ret = icc_set_bw(tbu->path, 0, UINT_MAX);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(tbu->clk);
+	if (ret)
+		goto disable_icc;
+
+	ret = qsmmuv500_tbu_halt(tbu, smmu_domain);
+	if (ret)
+		goto disable_clk;
+
+	/*
+	 * ATOS/ECATS can trigger the fault interrupt, so disable it temporarily
+	 * and check for an interrupt manually.
+	 */
+	sctlr_orig = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_SCTLR);
+	sctlr = sctlr_orig & ~(ARM_SMMU_SCTLR_CFCFG | ARM_SMMU_SCTLR_CFIE);
+	arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, sctlr);
+
+	fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
+	if (fsr & ARM_SMMU_FSR_FAULT) {
+		/* Clear pending interrupts */
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
+
+		/*
+		 * TBU halt takes care of resuming any stalled transcation.
+		 * Kept it here for completeness sake.
+		 */
+		if (fsr & ARM_SMMU_FSR_SS)
+			arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_RESUME,
+					  ARM_SMMU_RESUME_TERMINATE);
+	}
+
+	/* Only one concurrent atos operation */
+	spin_lock_irqsave(&atos_lock, flags);
+
+	/*
+	 * If the translation fails, attempt the lookup more time."
+	 */
+	do {
+		phys = qsmmuv500_tbu_trigger_atos(smmu_domain, tbu, iova, sid);
+
+		fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
+		if (fsr & ARM_SMMU_FSR_FAULT) {
+			/* Clear pending interrupts */
+			arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
+
+			if (fsr & ARM_SMMU_FSR_SS)
+				arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_RESUME,
+						  ARM_SMMU_RESUME_TERMINATE);
+		}
+	} while (!phys && attempt++ < 2);
+
+	arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, sctlr_orig);
+	spin_unlock_irqrestore(&atos_lock, flags);
+	qsmmuv500_tbu_resume(tbu);
+
+	/* Read to complete prior write transcations */
+	readl_relaxed(tbu->base + DEBUG_SR_HALT_ACK_REG);
+
+disable_clk:
+	clk_disable_unprepare(tbu->clk);
+disable_icc:
+	icc_set_bw(tbu->path, 0, 0);
+
+	return phys;
+}
+
+static int qsmmuv500_tbu_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct arm_smmu_device *smmu;
+	struct qsmmuv500_tbu *tbu;
+	struct qcom_smmu *qsmmu;
+	int ret;
+
+	smmu = dev_get_drvdata(dev->parent);
+	if (!smmu)
+		return -EPROBE_DEFER;
+
+	qsmmu = to_qcom_smmu(smmu);
+
+	tbu = devm_kzalloc(dev, sizeof(*tbu), GFP_KERNEL);
+	if (!tbu)
+		return -ENOMEM;
+
+	tbu->dev = dev;
+	INIT_LIST_HEAD(&tbu->list);
+	spin_lock_init(&tbu->halt_lock);
+
+	tbu->base = devm_of_iomap(dev, np, 0, NULL);
+	if (IS_ERR(tbu->base))
+		return PTR_ERR(tbu->base);
+
+	ret = of_property_read_u32_array(np, "stream-id-range", tbu->sid_range, 2);
+	if (ret) {
+		dev_err(dev, "The DT property 'stream-id-range' is mandatory\n");
+		return ret;
+	}
+
+	tbu->clk = devm_clk_get_optional(dev, NULL);
+	if (IS_ERR(tbu->clk))
+		return PTR_ERR(tbu->clk);
+
+	tbu->path = devm_of_icc_get(dev, NULL);
+	if (IS_ERR(tbu->path))
+		return PTR_ERR(tbu->path);
+
+	mutex_lock(&qsmmu->tbu_list_lock);
+	list_add_tail(&tbu->list, &qsmmu->tbu_list);
+	mutex_unlock(&qsmmu->tbu_list_lock);
+
+	dev_set_drvdata(dev, tbu);
+
+	return 0;
+}
+
+static const struct of_device_id qsmmuv500_tbu_of_match[] = {
+	{ .compatible = "qcom,qsmmuv500-tbu" },
+	{ }
+};
+
+static struct platform_driver qsmmuv500_tbu_driver = {
+	.driver = {
+		.name           = "qsmmuv500-tbu",
+		.of_match_table = qsmmuv500_tbu_of_match,
+	},
+	.probe = qsmmuv500_tbu_probe,
+};
+builtin_platform_driver(qsmmuv500_tbu_driver);
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
index 77e5becc2482..528c9a8a7568 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
@@ -32,6 +32,8 @@ struct qcom_smmu_match_data {
 	const struct arm_smmu_impl *adreno_impl;
 };
 
+irqreturn_t qcom_smmu_context_fault(int irq, void *dev);
+
 #ifdef CONFIG_ARM_SMMU_QCOM_DEBUG
 void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu);
 #else
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index d375e910b52c..17f704920190 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -136,6 +136,7 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_CBAR_VMID		GENMASK(7, 0)
 
 #define ARM_SMMU_GR1_CBFRSYNRA(n)	(0x400 + ((n) << 2))
+#define ARM_SMMU_CBFRSYNRA_SID		GENMASK(15, 0)
 
 #define ARM_SMMU_GR1_CBA2R(n)		(0x800 + ((n) << 2))
 #define ARM_SMMU_CBA2R_VMID16		GENMASK(31, 16)
@@ -238,6 +239,7 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_CB_ATSR		0x8f0
 #define ARM_SMMU_ATSR_ACTIVE		BIT(0)
 
+#define ARM_SMMU_RESUME_TERMINATE	BIT(0)
 
 /* Maximum number of context banks per SMMU */
 #define ARM_SMMU_MAX_CBS		128


From tmgross at umich.edu  Thu Feb  1 13:06:47 2024
From: tmgross at umich.edu (Trevor Gross)
Date: Thu, 1 Feb 2024 15:06:47 -0600
Subject: [PATCH v2 3/3] net: phy: add Rust Rockchip PHY driver
In-Reply-To: <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
 <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>
Message-ID: <CALNs47tnwCgyvM2jBo=bTt1=2AJFt3b6W+JsTHM3Np2tbNJYCA@mail.gmail.com>

On Thu, Feb 1, 2024 at 12:07?PM Christina Quast
<contact at christina-quast.de> wrote:
> +++ b/drivers/net/phy/rockchip_rust.rs
> @@ -0,0 +1,131 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) 2024 Christina Quast <contact at christina-quast.de>
> +
> +//! Rust Rockchip PHY driver
> +//!
> +//! C version of this driver: [`drivers/net/phy/rockchip.c`](./rockchip.c)
> +use kernel::{
> +    c_str,
> +    net::phy::{self, DeviceId, Driver},
> +    prelude::*,
> +    uapi,
> +};
> +
> +kernel::module_phy_driver! {
> +    drivers: [PhyRockchip],
> +    device_table: [
> +        DeviceId::new_with_driver::<PhyRockchip>(),
> +    ],
> +    name: "rust_asix_phy",
> +    author: "FUJITA Tomonori <fujita.tomonori at gmail.com>",

Tomo wrote this? :)

> +    description: "Rust Asix PHYs driver",
> +    license: "GPL",
> +}
> +
> +
> +const MII_INTERNAL_CTRL_STATUS: u16 = 17;
> +const SMI_ADDR_TSTCNTL: u16 = 20;
> +const SMI_ADDR_TSTWRITE: u16 = 23;
> +
> +const MII_AUTO_MDIX_EN: u16 = bit(7);
> +const MII_MDIX_EN: u16 = bit(6);
> +
> +const TSTCNTL_WR: u16 = bit(14) | bit(10);
> +
> +const TSTMODE_ENABLE: u16 = 0x400;
> +const TSTMODE_DISABLE: u16 = 0x0;
> +
> +const WR_ADDR_A7CFG: u16 = 0x18;

Most of these are clear enough, but could you add comments about what
the more ambiguous constants are for? (e.g. A7CFG).

> +struct PhyRockchip;
> +
> +impl PhyRockchip {

Remove the `helper_` prefix for these functions, and change the docs.
Their use as helpers is obvious enough based on where they are called,
better to say what they actually accomplish.

Since they don't take `self`, these could also just be standalone
functions rather than in an `impl PhyRockchip` block. This makes
calling them a bit cleaner since you don't need the `PhyRockchip::`
prefix.

> +   /// Helper function for helper_integrated_phy_analog_init
> +    fn helper_init_tstmode(dev: &mut phy::Device) -> Result {
> +        // Enable access to Analog and DSP register banks
> +        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_ENABLE)?;
> +        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_DISABLE)?;
> +        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_ENABLE)
> +    }

For consistency, just make the last write also end with `?;` and add a
`Ok(())` line.

> +
> +    /// Helper function for helper_integrated_phy_analog_init
> +    fn helper_close_tstmode(dev: &mut phy::Device) -> Result {
> +        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_DISABLE)
> +    }
> +
> +    /// Helper function for rockchip_config_init
> +    fn helper_integrated_phy_analog_init(dev: &mut phy::Device) -> Result {
> +        Self::helper_init_tstmode(dev)?;
> +        dev.write(SMI_ADDR_TSTWRITE, 0xB)?;
> +        dev.write(SMI_ADDR_TSTCNTL, TSTCNTL_WR | WR_ADDR_A7CFG)?;
> +        Self::helper_close_tstmode(dev)
> +    }
> +
> +    /// Helper function for config_init
> +    fn helper_config_init(dev: &mut phy::Device) -> Result {
> +        let val = !MII_AUTO_MDIX_EN & dev.read(MII_INTERNAL_CTRL_STATUS)?;
> +        dev.write(MII_INTERNAL_CTRL_STATUS, val)?;
> +        Self::helper_integrated_phy_analog_init(dev)
> +    }
> +
> +    fn helper_set_polarity(dev: &mut phy::Device, polarity: u8) -> Result {
> +        let reg = !MII_AUTO_MDIX_EN & dev.read(MII_INTERNAL_CTRL_STATUS)?;
> +        let val = match polarity as u32 {
> +            // status: MDI; control: force MDI
> +            uapi::ETH_TP_MDI => Some(reg & !MII_MDIX_EN),
> +            // status: MDI-X; control: force MDI-X
> +            uapi::ETH_TP_MDI_X => Some(reg | MII_MDIX_EN),
> +            // uapi::ETH_TP_MDI_AUTO => control: auto-select
> +            // uapi::ETH_TP_MDI_INVALID => status: unknown; control: unsupported
> +            _ => None,

Is receiving an invalid value not an error? I.e.

    uapi::ETH_TP_MDI_AUTO | uapi::ETH_TP_MDI_INVALID => None,
    _ => return Err(...)

I know the current implementation came from the C version, just
wondering about correctness here.

> +        };
> +        if let Some(v) = val {
> +            if v != reg {
> +                return dev.write(MII_INTERNAL_CTRL_STATUS, v);
> +            }
> +        }

In the match statement above - I think you can replace `=> None` with
`=> return Ok(())` and drop the `Some(...)` wrappers. Then you don't
need to destructure val here.

> +        Ok(())
> +
> +    }
> +}
> +
> +#[vtable]
> +impl Driver for PhyRockchip {
> +    const FLAGS: u32 = 0;
> +    const NAME: &'static CStr = c_str!("Rockchip integrated EPHY");
> +    const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_custom_mask(0x1234d400, 0xfffffff0);
> +
> +    fn link_change_notify(dev: &mut phy::Device) {
> +    // If mode switch happens from 10BT to 100BT, all DSP/AFE
> +    // registers are set to default values. So any AFE/DSP
> +    // registers have to be re-initialized in this case.

Comment indent

> +        if dev.state() == phy::DeviceState::Running && dev.speed() == uapi::SPEED_100 {
> +            if let Err(e) = Self::helper_integrated_phy_analog_init(dev) {
> +                pr_err!("rockchip: integrated_phy_analog_init err: {:?}", e);
> +            }
> +        }
> +    }
> +
> +    fn soft_reset(dev: &mut phy::Device) -> Result {
> +        dev.genphy_soft_reset()
> +    }
> +
> +    fn config_init(dev: &mut phy::Device) -> Result {
> +        PhyRockchip::helper_config_init(dev)
> +    }
> +
> +    fn config_aneg(dev: &mut phy::Device) -> Result {
> +        PhyRockchip::helper_set_polarity(dev, dev.mdix())?;
> +        dev.genphy_config_aneg()
> +    }
> +
> +    fn suspend(dev: &mut phy::Device) -> Result {
> +        dev.genphy_suspend()
> +    }
> +
> +    fn resume(dev: &mut phy::Device) -> Result {
> +        let _ = dev.genphy_resume();

Why not `?` the possible error?

> +
> +        PhyRockchip::helper_config_init(dev)
> +    }
> +}
>
> --
> 2.43.0
>

As Greg and Dragan mentioned, duplicate drivers are generally not
accepted in-tree to avoid double maintenance and confusing config. Is
there a specific goal?

It is quite alright to request feedback on Rust drivers (and I have
provided some) or even ask if anyone is willing to help test it out,
but please use RFC PATCH and make it clear that this is for
experimentation rather than upstreaming.

Netdev has seemed relatively open to adding Rust drivers for new phys
that don't have a C implementation, but these phys are of course
tougher to find.

Also for future reference, changes intended for the net tree should be
labeled [PATCH v? net-next].

Best regards,
Trevor


From quic_obabatun at quicinc.com  Thu Feb  1 13:10:18 2024
From: quic_obabatun at quicinc.com (Oreoluwa Babatunde)
Date: Thu, 1 Feb 2024 13:10:18 -0800
Subject: [PATCH 00/46] Dynamic allocation of reserved_mem array.
In-Reply-To: <20240201194653.GA1328565-robh@kernel.org>
References: <20240126235425.12233-1-quic_obabatun@quicinc.com>
 <20240131000710.GA2581425-robh@kernel.org>
 <51dc64bb-3101-4b4a-a54f-c0df6c0b264c@quicinc.com>
 <20240201194653.GA1328565-robh@kernel.org>
Message-ID: <d98288ed-a0d9-4fc1-87bc-d79cb528778c@quicinc.com>


On 2/1/2024 11:46 AM, Rob Herring wrote:
> On Thu, Feb 01, 2024 at 09:08:06AM -0800, Oreoluwa Babatunde wrote:
>> On 1/30/2024 4:07 PM, Rob Herring wrote:
>>> On Fri, Jan 26, 2024 at 03:53:39PM -0800, Oreoluwa Babatunde wrote:
>>>> The reserved_mem array is used to store data for the different
>>>> reserved memory regions defined in the DT of a device.  The array
>>>> stores information such as region name, node, start-address, and size
>>>> of the reserved memory regions.
>>>>
>>>> The array is currently statically allocated with a size of
>>>> MAX_RESERVED_REGIONS(64). This means that any system that specifies a
>>>> number of reserved memory regions greater than MAX_RESERVED_REGIONS(64)
>>>> will not have enough space to store the information for all the regions.
>>>>
>>>> Therefore, this series extends the use of the static array for
>>>> reserved_mem, and introduces a dynamically allocated array using
>>>> memblock_alloc() based on the number of reserved memory regions
>>>> specified in the DT.
>>>>
>>>> Some architectures such as arm64 require the page tables to be setup
>>>> before memblock allocated memory is writable.  Therefore, the dynamic
>>>> allocation of the reserved_mem array will need to be done after the
>>>> page tables have been setup on these architectures. In most cases that
>>>> will be after paging_init().
>>>>
>>>> Reserved memory regions can be divided into 2 groups.
>>>> i) Statically-placed reserved memory regions
>>>> i.e. regions defined in the DT using the @reg property.
>>>> ii) Dynamically-placed reserved memory regions.
>>>> i.e. regions specified in the DT using the @alloc_ranges
>>>>     and @size properties.
>>>>
>>>> It is possible to call memblock_reserve() and memblock_mark_nomap() on
>>>> the statically-placed reserved memory regions and not need to save them
>>>> to the reserved_mem array until memory is allocated for it using
>>>> memblock, which will be after the page tables have been setup.
>>>> For the dynamically-placed reserved memory regions, it is not possible
>>>> to wait to store its information because the starting address is
>>>> allocated only at run time, and hence they need to be stored somewhere
>>>> after they are allocated.
>>>> Waiting until after the page tables have been setup to allocate memory
>>>> for the dynamically-placed regions is also not an option because the
>>>> allocations will come from memory that have already been added to the
>>>> page tables, which is not good for memory that is supposed to be
>>>> reserved and/or marked as nomap.
>>>>
>>>> Therefore, this series splits up the processing of the reserved memory
>>>> regions into two stages, of which the first stage is carried out by
>>>> early_init_fdt_scan_reserved_mem() and the second is carried out by
>>>> fdt_init_reserved_mem().
>>>>
>>>> The early_init_fdt_scan_reserved_mem(), which is called before the page
>>>> tables are setup is used to:
>>>> 1. Call memblock_reserve() and memblock_mark_nomap() on all the
>>>>    statically-placed reserved memory regions as needed.
>>>> 2. Allocate memory from memblock for the dynamically-placed reserved
>>>>    memory regions and store them in the static array for reserved_mem.
>>>>    memblock_reserve() and memblock_mark_nomap() are also called as
>>>>    needed on all the memory allocated for the dynamically-placed
>>>>    regions.
>>>> 3. Count the total number of reserved memory regions found in the DT.
>>>>
>>>> fdt_init_reserved_mem(), which should be called after the page tables
>>>> have been setup, is used to carry out the following:
>>>> 1. Allocate memory for the reserved_mem array based on the number of
>>>>    reserved memory regions counted as mentioned above.
>>>> 2. Copy all the information for the dynamically-placed reserved memory
>>>>    regions from the static array into the new allocated memory for the
>>>>    reserved_mem array.
>>>> 3. Add the information for the statically-placed reserved memory into
>>>>    reserved_mem array.
>>>> 4. Run the region specific init functions for each of the reserve memory
>>>>    regions saved in the reserved_mem array.
>>> I don't see the need for fdt_init_reserved_mem() to be explicitly called 
>>> by arch code. I said this already, but that can be done at the same time 
>>> as unflattening the DT. The same conditions are needed for both: we need 
>>> to be able to allocate memory from memblock.
>>>
>>> To put it another way, if fdt_init_reserved_mem() can be called "early", 
>>> then unflattening could be moved earlier as well. Though I don't think 
>>> we should optimize that. I'd rather see all arches call the DT functions 
>>> at the same stages.
>> Hi Rob,
>>
>> The reason we moved fdt_init_reserved_mem() back into the arch specific code
>> was because we realized that there was no apparently obvious way to call
>> early_init_fdt_scan_reserved_mem() and fdt_init_reserved_mem() in the correct
>> order that will work for all archs if we placed fdt_init_reserved_mem() inside the
>> unflatten_devicetree() function.
>>
>> early_init_fdt_scan_reserved_mem() needs to be
>> called first before fdt_init_reserved_mem(). But on some archs,
>> unflatten_devicetree() is called before early_init_fdt_scan_reserved_mem(), which
>> means that if we have fdt_init_reserved_mem() inside the unflatten_devicetree()
>> function, it will be called before early_init_fdt_scan_reserved_mem().
>>
>> This is connected to your other comments on Patch 7 & Patch 14.
>> I agree, unflatten_devicetree() should NOT be getting called before we reserve
>> memory for the reserved memory regions because that could cause memory to be
>> allocated from regions that should be reserved.
>>
>> Hence, resolving this issue should allow us to call fdt_init_reserved_mem() from
>> the? unflatten_devicetree() function without it changing the order that we are
>> trying to have.
> There's one issue I've found which is unflatten_device_tree() isn't 
> called for ACPI case on arm64. Turns out we need /reserved-memory 
> handled in that case too. However, I think we're going to change 
> calling unflatten_device_tree() unconditionally for another reason[1]. 
>
> [1] https://lore.kernel.org/all/efe6a7886c3491cc9c225a903efa2b1e.sboyd at kernel.org/
>
>> I will work on implementing this and send another revision.
> I think we should go with a simpler route that's just copy the an 
> initial array in initdata to a properly sized, allocated array like the 
> patch below. Of course it will need some arch fixes and a follow-on 
> patch to increase the initial array size.
>
> 8<--------------------------------------------------------------------
> From: Rob Herring <robh at kernel.org>
> Date: Wed, 31 Jan 2024 16:26:23 -0600
> Subject: [PATCH] of: reserved-mem: Re-allocate reserved_mem array to actual
>  size
>
> In preparation to increase the static reserved_mem array size yet again,
> copy the initial array to an allocated array sized based on the actual
> size needed. Now increasing the the size of the static reserved_mem
> array only eats up the initdata space. For platforms with reasonable
> number of reserved regions, we have a net gain in free memory.
>
> In order to do memblock allocations, fdt_init_reserved_mem() is moved a
> bit later to unflatten_device_tree(). On some arches this is effectively
> a nop.
>
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
> RFC as this is compile tested only. This is an alternative to this
> series[1].
>
> [1] https://lore.kernel.org/all/20240126235425.12233-1-quic_obabatun at quicinc.com/
> ---
>  drivers/of/fdt.c             |  4 ++--
>  drivers/of/of_reserved_mem.c | 18 +++++++++++++-----
>  2 files changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index bf502ba8da95..14360f5191ae 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -645,8 +645,6 @@ void __init early_init_fdt_scan_reserved_mem(void)
>  			break;
>  		memblock_reserve(base, size);
>  	}
> -
> -	fdt_init_reserved_mem();
>  }
>  
>  /**
> @@ -1328,6 +1326,8 @@ bool __init early_init_dt_scan(void *params)
>   */
>  void __init unflatten_device_tree(void)
>  {
> +	fdt_init_reserved_mem();
> +
>  	__unflatten_device_tree(initial_boot_params, NULL, &of_root,
>  				early_init_dt_alloc_memory_arch, false);
>  
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> index 7ec94cfcbddb..ae323d6b25ad 100644
> --- a/drivers/of/of_reserved_mem.c
> +++ b/drivers/of/of_reserved_mem.c
> @@ -27,7 +27,8 @@
>  #include "of_private.h"
>  
>  #define MAX_RESERVED_REGIONS	64
> -static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS] __initdata;
> +static struct reserved_mem *reserved_mem_p;
>  static int reserved_mem_count;
>  
>  static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
> @@ -354,6 +355,13 @@ void __init fdt_init_reserved_mem(void)
>  			}
>  		}
>  	}
> +
> +	reserved_mem_p = memblock_alloc(sizeof(struct reserved_mem) * reserved_mem_count,
> +					sizeof(struct reserved_mem));
> +	if (WARN(!reserved_mem_p, "of: reserved-memory allocation failed, continuing with __initdata array!\n"))
> +		reserved_mem_p = reserved_mem;
> +	else
> +		memcpy(reserved_mem_p, reserved_mem, sizeof(struct reserved_mem) * reserved_mem_count);
>  }
>  
>  static inline struct reserved_mem *__find_rmem(struct device_node *node)
> @@ -364,8 +372,8 @@ static inline struct reserved_mem *__find_rmem(struct device_node *node)
>  		return NULL;
>  
>  	for (i = 0; i < reserved_mem_count; i++)
> -		if (reserved_mem[i].phandle == node->phandle)
> -			return &reserved_mem[i];
> +		if (reserved_mem_p[i].phandle == node->phandle)
> +			return &reserved_mem_p[i];
>  	return NULL;
>  }
>  
> @@ -507,8 +515,8 @@ struct reserved_mem *of_reserved_mem_lookup(struct device_node *np)
>  
>  	name = kbasename(np->full_name);
>  	for (i = 0; i < reserved_mem_count; i++)
> -		if (!strcmp(reserved_mem[i].name, name))
> -			return &reserved_mem[i];
> +		if (!strcmp(reserved_mem_p[i].name, name))
> +			return &reserved_mem_p[i];
>  
>  	return NULL;
>  }
Hi Rob,

One thing that could come up with this is that? memory
for the dynamically-placed reserved memory regions
won't be allocated until we call fdt_init_reserved_mem().
(i.e. reserved memory regions defined using @alloc-ranges
and @size properties)

Since fdt_init_reserved_mem() is now being called from
unflatten_device_tree(), the page tables would have been
setup on most architectures, which means we will be
allocating from memory that have already been mapped.

Could this be an issue for memory that is supposed to be
reserved? Especially for the regions that are specified as
no-map?


From nm at ti.com  Thu Feb  1 13:14:02 2024
From: nm at ti.com (Nishanth Menon)
Date: Thu, 1 Feb 2024 15:14:02 -0600
Subject: [PATCH 00/12] Add TI-SCI reboot driver
In-Reply-To: <20240131221957.213717-1-afd@ti.com>
References: <20240131221957.213717-1-afd@ti.com>
Message-ID: <20240201211402.nldc6x2iosi4fkxq@morbidity>

On 16:19-20240131, Andrew Davis wrote:
> Hello all,
> 
> While PCSI normally handles reboot for K3, this is an available
> fallback in case PCSI reboot fails. This driver is registered 
> with low priority as we want PSCI to remain the main way these
> devices are rebooted.
> 
> The important part is the binding/DT changes. Currently in
> U-Boot (which use the Linux device trees) we may not have
> PSCI available yet (pre TF-A) and so we need this node
> to correctly reboot. Adding this node in U-Boot is one of
> the last remaining deltas between the two project DT files. 
> 
> Thanks,
> Andrew
> 
> Andrew Davis (12):
>   dt-bindings: power: reset: Document ti,sci-reboot compatible
>   dt-bindings: arm: keystone: ti-sci: Add reboot-controller child node
>   power: reset: Add TI-SCI reboot driver
>   arm64: dts: ti: k3-am64: Add reboot-controller node
>   arm64: dts: ti: k3-am62: Add reboot-controller node
>   arm64: dts: ti: k3-am62a: Add reboot-controller node
>   arm64: dts: ti: k3-am62p: Add reboot-controller node
>   arm64: dts: ti: k3-am65: Add reboot-controller node
>   arm64: dts: ti: k3-j7200: Add reboot-controller node
>   arm64: dts: ti: k3-j721e: Add reboot-controller node
>   arm64: dts: ti: k3-j721s2: Add reboot-controller node
>   arm64: dts: ti: k3-j784s4: Add reboot-controller node

Maybe after the driver has been accepted, a defconfig patch(module) might be
useful?

> 
>  .../bindings/arm/keystone/ti,sci.yaml         |  8 +++
>  .../bindings/power/reset/ti,sci-reboot.yaml   | 33 ++++++++++
>  MAINTAINERS                                   |  2 +
>  arch/arm64/boot/dts/ti/k3-am62-main.dtsi      |  5 ++
>  arch/arm64/boot/dts/ti/k3-am62a-main.dtsi     |  4 ++
>  arch/arm64/boot/dts/ti/k3-am62p-main.dtsi     |  5 ++
>  arch/arm64/boot/dts/ti/k3-am64-main.dtsi      |  5 ++
>  arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi    |  4 ++
>  .../boot/dts/ti/k3-j7200-mcu-wakeup.dtsi      |  4 ++
>  .../boot/dts/ti/k3-j721e-mcu-wakeup.dtsi      |  4 ++
>  .../boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi     |  4 ++
>  .../boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi     |  5 ++
>  drivers/power/reset/Kconfig                   |  7 +++
>  drivers/power/reset/Makefile                  |  1 +
>  drivers/power/reset/ti-sci-reboot.c           | 63 +++++++++++++++++++
>  15 files changed, 154 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/reset/ti,sci-reboot.yaml
>  create mode 100644 drivers/power/reset/ti-sci-reboot.c

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From nm at ti.com  Thu Feb  1 13:15:34 2024
From: nm at ti.com (Nishanth Menon)
Date: Thu, 1 Feb 2024 15:15:34 -0600
Subject: [PATCH 03/12] power: reset: Add TI-SCI reboot driver
In-Reply-To: <20240131221957.213717-4-afd@ti.com>
References: <20240131221957.213717-1-afd@ti.com>
 <20240131221957.213717-4-afd@ti.com>
Message-ID: <20240201211534.dv6qu7ila54vqykn@cheating>

On 16:19-20240131, Andrew Davis wrote:
> This reboot driver calls into firmware using TI-SCI to reboot the system.
> We register the handler with low priority as we want PSCI to remain the
> main way these devices are rebooted. This driver acts as a fallback if
> PSCI is not able to reboot the system.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  MAINTAINERS                         |  1 +
>  drivers/power/reset/Kconfig         |  7 ++++
>  drivers/power/reset/Makefile        |  1 +
>  drivers/power/reset/ti-sci-reboot.c | 63 +++++++++++++++++++++++++++++
>  4 files changed, 72 insertions(+)
>  create mode 100644 drivers/power/reset/ti-sci-reboot.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 45983bb174fe4..ee67ea497fc56 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -21758,6 +21758,7 @@ F:	drivers/clk/keystone/sci-clk.c
>  F:	drivers/firmware/ti_sci*
>  F:	drivers/irqchip/irq-ti-sci-inta.c
>  F:	drivers/irqchip/irq-ti-sci-intr.c
> +F:	drivers/power/reset/ti-sci-reboot.c
>  F:	drivers/reset/reset-ti-sci.c
>  F:	drivers/soc/ti/ti_sci_inta_msi.c
>  F:	drivers/pmdomain/ti/ti_sci_pm_domains.c
> diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
> index fece990af4a75..d3e91e54cae24 100644
> --- a/drivers/power/reset/Kconfig
> +++ b/drivers/power/reset/Kconfig
> @@ -205,6 +205,13 @@ config POWER_RESET_ST
>  	help
>  	  Reset support for STMicroelectronics boards.
>  
> +config POWER_RESET_TI_SCI
> +	tristate "TI System Control Interface (TI-SCI) reboot driver"
> +	depends on TI_SCI_PROTOCOL
> +	help
> +	  This enables the reboot driver support over TI System Control
> +	  Interface available on some TI's SoCs.
> +
>  config POWER_RESET_TPS65086
>  	bool "TPS65086 restart driver"
>  	depends on MFD_TPS65086
> diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
> index a95d1bd275d18..881ca58a43b9c 100644
> --- a/drivers/power/reset/Makefile
> +++ b/drivers/power/reset/Makefile
> @@ -23,6 +23,7 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
>  obj-$(CONFIG_POWER_RESET_REGULATOR) += regulator-poweroff.o
>  obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
>  obj-$(CONFIG_POWER_RESET_ST) += st-poweroff.o
> +obj-$(CONFIG_POWER_RESET_TI_SCI) += ti-sci-reboot.o
>  obj-$(CONFIG_POWER_RESET_TPS65086) += tps65086-restart.o
>  obj-$(CONFIG_POWER_RESET_VERSATILE) += arm-versatile-reboot.o
>  obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
> diff --git a/drivers/power/reset/ti-sci-reboot.c b/drivers/power/reset/ti-sci-reboot.c
> new file mode 100644
> index 0000000000000..400bd5d740f8b
> --- /dev/null
> +++ b/drivers/power/reset/ti-sci-reboot.c
> @@ -0,0 +1,63 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Texas Instrument's System Control Interface (TI-SCI) reboot driver
> + *
> + * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
> + *	Andrew Davis <afd at ti.com>
> + */
> +
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/reboot.h>
> +
> +#include <linux/soc/ti/ti_sci_protocol.h>
> +
> +static int ti_sci_reboot_handler(struct sys_off_data *data)
> +{
> +	const struct ti_sci_handle *sci = data->cb_data;
> +	const struct ti_sci_core_ops *core_ops = &sci->ops.core_ops;
> +
> +	core_ops->reboot_device(sci);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static int ti_sci_reboot_probe(struct platform_device *pdev)
> +{
> +	const struct ti_sci_handle *sci;
> +	int err;
> +
> +	sci = devm_ti_sci_get_handle(&pdev->dev);
> +	if (IS_ERR(sci))
> +		return PTR_ERR(sci);
> +
> +	err = devm_register_sys_off_handler(&pdev->dev,
> +					    SYS_OFF_MODE_RESTART,
> +					    SYS_OFF_PRIO_LOW,
> +					    ti_sci_reboot_handler,
> +					    (void *)sci);
> +	if (err)
> +		return dev_err_probe(&pdev->dev, err, "Cannot register restart handler\n");
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id ti_sci_reboot_of_match[] = {
> +	{ .compatible = "ti,sci-reboot", },
> +	{ /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, ti_sci_reboot_of_match);
> +
> +static struct platform_driver ti_sci_reboot_driver = {
> +	.probe = ti_sci_reboot_probe,
> +	.driver = {
> +		.name = "ti-sci-reboot",
> +		.of_match_table = ti_sci_reboot_of_match,
> +	},
> +};
> +module_platform_driver(ti_sci_reboot_driver);
> +
> +MODULE_AUTHOR("Andrew Davis <afd at ti.com>");
> +MODULE_DESCRIPTION("TI System Control Interface (TI SCI) Reboot driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.39.2

Will assume the patch to go via Sebastien. Will be good for the dts to
go via SoC tree. So hoping Sebastien will just pick the driver and
bindings.

Reviewed-by: Nishanth Menon <nm at ti.com>
-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From ardb at kernel.org  Thu Feb  1 13:23:16 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 1 Feb 2024 22:23:16 +0100
Subject: [PATCH] arm64: jump_label: use constraint "S" instead of "i"
In-Reply-To: <20240201205614.w3gcz6urfxtydr77@google.com>
References: <20240131065322.1126831-1-maskray@google.com> <CAMj1kXGzADFWa7RmXyjWpCnQ=9hhz6i-XkN4PS1CboZ-kFL8dQ@mail.gmail.com>
 <ZbpEnDK3U/O24ng0@e133380.arm.com> <20240201045551.ajg4iqcajyowl2rh@google.com>
 <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>
 <20240201091120.pbgr7ng6t2c36fut@google.com> <ZbuFWSRBntgm2ukJ@e133380.arm.com>
 <CAMj1kXGu76WHY8=Y-KhCxBq3xeHeCYQ9syqViSr9VRkjgWQ3BQ@mail.gmail.com>
 <ZbvVApJ2/+yca0u6@e133380.arm.com> <20240201205614.w3gcz6urfxtydr77@google.com>
Message-ID: <CAMj1kXGAi94DuCYRPWQujGz7YVTS=53h_+FretCsYFbxznJVHw@mail.gmail.com>

On Thu, 1 Feb 2024 at 21:56, Fangrui Song <maskray at google.com> wrote:
>
> On 2024-02-01, Dave Martin wrote:
> >On Thu, Feb 01, 2024 at 05:07:59PM +0100, Ard Biesheuvel wrote:
> >> On Thu, 1 Feb 2024 at 12:50, Dave Martin <Dave.Martin at arm.com> wrote:
> >> >
> >> > On Thu, Feb 01, 2024 at 01:11:20AM -0800, Fangrui Song wrote:
> >> ...
> >> > >
> >> > > Hmm. Clang's constraint "S" implementation doesn't support a constant
> >> > > offset, so
> >> > > `static_key_false(&nf_hooks_needed[pf][hook])` in include/linux/netfilter.h:nf_hook
> >> > > would not compile with Clang <= 18.
> >> > >
> >> > > I have a patch https://github.com/llvm/llvm-project/pull/80255 , but
> >> > > even if it is accepted and cherry-picked into the 18.x release branch,
> >> > > if we still support older Clang, we cannot use "S" unconditionally.
> >> > >
> >> > >
> >> > > So we probably need the following to prepare for -fPIE support in the
> >> > > future:
> >> > >
> >> > > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> >> > > index 48ddc0f45d22..b8af2f8b0c99 100644
> >> > > --- a/arch/arm64/include/asm/jump_label.h
> >> > > +++ b/arch/arm64/include/asm/jump_label.h
> >> > > @@ -15,6 +15,16 @@
> >> > >  #define JUMP_LABEL_NOP_SIZE          AARCH64_INSN_SIZE
> >> > > +/*
> >> > > + * Prefer "S" to support PIC. However, use "i" for Clang 18 and earlier as "S"
> >> > > + * on a symbol with a constant offset is not supported.
> >> > > + */
> >> > > +#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 18
> >> >
> >> > Is a GCC version check needed?  Or is the minimum GCC version specified
> >> > for building the kernel new enough?
> >> >
> >> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
> >> > > +#else
> >> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "S"
> >> > > +#endif
> >> > > +
> >>
> >> Can we use "Si" instead?
> >
> >I thought the point was to avoid "S" on compilers that would choke on
> >it?  If so, those compilers would surely choke on "Si" too, no?
>
> "Si" is an invalid constraint. Unfortunately, GCC recognizes "S" as a
> valid constraint and ignores trailing characters (asm_operand_ok). That
> is, GCC would accept "Siiiii" as well...
>
> The GCC support for "S" is great. The initial aarch64 port in 2012 supports "S".
>

So it is not possible to combine the S and i constraint, and let the
compiler figure out whether it meets either? We rely on this elsewhere
by combining r and Z into rZ. x86 uses "rm" for inline asm parameters
that could be either register or memory operands.


> >> > >  static __always_inline bool arch_static_branch(struct static_key * const key,
> >> > >                                              const bool branch)
> >> > >  {
> >> > > @@ -23,9 +33,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
> >> > >                "      .pushsection    __jump_table, \"aw\"    \n\t"
> >> > >                "      .align          3                       \n\t"
> >> > >                "      .long           1b - ., %l[l_yes] - .   \n\t"
> >> > > -              "      .quad           %c0 - .                 \n\t"
> >> > > +              "      .quad           %0 + %1 - .             \n\t"
> >> > >                "      .popsection                             \n\t"
> >> > > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> >> > > +              :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);
> >> >
> >> > While this looks reasonable, I'm still not clear now why the asm must do
> >> > the addition.
> >> >
> >> > Can we roll the branch argument into the macro?
> >> >
> >> > "S"(symbol + constant) seems to do the right thing for AArch64, at least
> >> > in GCC.
> >> >
> >>
> >> 'symbol' is a struct static_key pointer, so adding '1' to it will not
> >> produce the needed result.
> >
> >I mean loosely things that resolve to something of the form
> >"symbol + constant" in the compiler output.
> >
> >"S"(&((char *)key)[branch]) does indeed seem to do the right thing,
> >at least with GCC.
> >
> >I probably didn't help by bikeshedding the way that expression was
> >written, apologies for that.  It's orthogonal to what this patch is
> >doing.
>
> Yes, "S"(&((char *)key)[branch])  would do the right thing.
> I have compared assembly output. It's a matter of "s" vs "s + 0" and "s+1" vs "s + 1".
>

But if S does not work with constant offsets with older Clang, what is
the harm in splitting it into "S" for the symbol and "i" for the
branch?
...
> >>
> >> The only thing PIE linking does in the case of the kernel is
> >> a) complain if static relocations are used that cannot be fixed up at
> >> runtime (e.g., movk/movz sequences)
> >> b) emit dynamic relocations that the early startup code can use to fix
> >> up all statically initialized pointers
> >>
> >> From a codegen point-of-view, there is no difference because we don't
> >> use -fpic code. The problem with -fpic codegen is that it makes some
> >> assumptions that only hold for shared ELF objects, e.g., avoiding
> >> dynamic relocations in .text, using GOT entries even for variables
> >> defined in the same compilation so that they can be preempted, keeping
> >> all runtime relocatable quantities together so the CoW footprint of
> >> the shared library is minimized.
> >>
> >> None of this matters for the kernel, and as it turns out, the non-PIC
> >> small C model produces code that the PIE linker is happy with.
> >>
> >> TL;DR our code (including inline and out-of-line asm) is already PIC,
> >> and this property is relied upon by KASLR.
> >>
> >> > Maybe it doesn't make as much difference as I thought (certainly ADRP
> >> > based addressing should make a fair amount of the PIC/PIE overhead go
> >> > away).
> >> >
> >>
> >> The PIC/PIE overhead is in the indirections via the GOT. However,
> >> recent linkers will actually perform some relaxations too: if a symbol
> >> is defined in the same executable and is not preemptible, a GOT load
> >>
> >> ADRP
> >> LDR
> >>
> >> can be transparently converted to
> >>
> >> ADRP
> >> ADD
> >>
> >> referring to the symbol directly. This is also where hidden.h comes
> >> in: making all symbol declarations and definitions 'hidden' will allow
> >> the compiler to assume that a GOT entry is never needed.
> >
> >Is there a reason why we don't just build the whole kernel with
> >-fvisibility=hidden today?
>
> This topic, loosely related to this patch, is about switching to PIC
> compiles. I am not familiar with the Linux kernel, so I'll mostly leave
> the discussion to you and Ard :)
>
> That said, I have done a lot of Clang work in visibility/symbol
> preemptibility and linkers, so I am happy to add what I know.
>
> -fvisibility=hidden only applies to definitions, not non-definition
> declarations.
>
> I've mentioned this at
> https://lore.kernel.org/all/20220429070318.iwj3j5lpfkw4t7g2 at google.com/
>
>      `#pragma GCC visibility push(hidden)` is very similar to -fvisibility=hidden -fdirect-access-external-data with Clang.
>      ...
>      The kernel uses neither TLS nor -fno-plt, so -fvisibility=hidden
>      -fdirect-access-external-data can replace `#pragma GCC visibility
>      push(hidden)`.
>
> >> So building with -fPIC is currently not need in practice, and creates
> >> some complications, which is why we have been avoiding it. But PIE
> >> linking non-PIC objects is not guaranteed to remain supported going
> >> forward, so it would be better to have a plan B, i.e., being able to
> >> turn on -fpic without massive regressions due to GOT overhead, or
> >> codegen problems with our asm hacks.
> >
> >Summarising all of this is it right that:
> >
> >1) ld -pie is how we get the reloc info into the kernel for KASLR
> >today.
> >
> >2) We use gcc -fno-pic today, but this might break with ld -pie in the
> >future, although it works for now.
> >
> >3) gcc -fno-pic and gcc -fPIC (or -fPIE) generate almost the same code,
> >assuming we tweak symbol visibility and use a memory model that
> >ADR+ADD/LDR can span.  So, moving to -fPIE is likely to be do-able.
> >
> >
> >My point is that an alternative option would be to move to ld -no-pie.

Why? What would that achieve?

> >We would need another way to get relocs into the kernel, such as an
> >intermediate step with ld --emit-relocs.  I have definitely seen this
> >done before somewhere, but it would be extra work and not necessarily
> >worth it, based on what you say about code gen.

Relying on --emit-relocs is a terrible hack. It contains mostly
relocations that we don't need at runtime, so we need to postprocess
them. And linkers may not update these relocations in some cases after
relaxation or other transformations (and sometimes, it is not even
possible to do so, if the post-transformation situation cannot be
described by a relocation).

And with Fangrui's RELR optimization, the PIE relocation data is
extremely dense.

There is nothing to fix here, really.

> >
> >This may all have been discussed to death already -- I didn't mean to
> >hijack this patch, so I'll stop digging here, but if I've misunderstood,
> >please shout!

No worries. Ramana and I spent some time 5+ years ago to document how
PIC codegen for the kernel (or any freestanding executable, really)
deviates from the typical PIC codegen for shared libraries and PIE
executables, with the intention of adding a GCC compiler switch for
it, but that never really materialized, mostly because things just
work fine today.


From devnull+quic_bjorande.quicinc.com at kernel.org  Thu Feb  1 13:31:19 2024
From: devnull+quic_bjorande.quicinc.com at kernel.org (Bjorn Andersson via B4 Relay)
Date: Thu, 01 Feb 2024 13:31:19 -0800
Subject: [PATCH] arm64: defconfig: Enable Qualcomm interconnect providers
Message-ID: <20240201-enable-icc-8250-2290-v1-1-8ded02750521@quicinc.com>

From: Bjorn Andersson <quic_bjorande at quicinc.com>

With interconnect providers built as modules Qualcomm SM8250 and QCM2290
platforms launches init without /dev/console being backed by the debug
UART.

Build there drivers into the kernel, to make sure the dependencies for
the UART driver are available and thereby give userspace access to the
UART without having to re-open the console, once the deferred UART
driver has probed.

Signed-off-by: Bjorn Andersson <quic_bjorande at quicinc.com>
---
 arch/arm64/configs/defconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e6cf3e5d63c3..0463db563215 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1550,7 +1550,7 @@ CONFIG_INTERCONNECT_QCOM=y
 CONFIG_INTERCONNECT_QCOM_MSM8916=m
 CONFIG_INTERCONNECT_QCOM_MSM8996=m
 CONFIG_INTERCONNECT_QCOM_OSM_L3=m
-CONFIG_INTERCONNECT_QCOM_QCM2290=m
+CONFIG_INTERCONNECT_QCOM_QCM2290=y
 CONFIG_INTERCONNECT_QCOM_QCS404=m
 CONFIG_INTERCONNECT_QCOM_SA8775P=y
 CONFIG_INTERCONNECT_QCOM_SC7180=y
@@ -1560,7 +1560,7 @@ CONFIG_INTERCONNECT_QCOM_SC8280XP=y
 CONFIG_INTERCONNECT_QCOM_SDM845=y
 CONFIG_INTERCONNECT_QCOM_SDX75=y
 CONFIG_INTERCONNECT_QCOM_SM8150=m
-CONFIG_INTERCONNECT_QCOM_SM8250=m
+CONFIG_INTERCONNECT_QCOM_SM8250=y
 CONFIG_INTERCONNECT_QCOM_SM8350=m
 CONFIG_INTERCONNECT_QCOM_SM8450=y
 CONFIG_INTERCONNECT_QCOM_SM8550=y

---
base-commit: 06f658aadff0e483ee4f807b0b46c9e5cba62bfa
change-id: 20240201-enable-icc-8250-2290-b4fa7dc7b9de

Best regards,
-- 
Bjorn Andersson <quic_bjorande at quicinc.com>



From andrew at lunn.ch  Thu Feb  1 13:29:45 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Thu, 1 Feb 2024 22:29:45 +0100
Subject: [PATCH v2 3/3] net: phy: add Rust Rockchip PHY driver
In-Reply-To: <2024020105-bankroll-opium-a6e5@gregkh>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
 <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>
 <2024020105-bankroll-opium-a6e5@gregkh>
Message-ID: <6725eeac-45ee-4f3f-a612-0ef5725b9fd9@lunn.ch>

On Thu, Feb 01, 2024 at 10:23:03AM -0800, Greg KH wrote:
> On Thu, Feb 01, 2024 at 07:07:00PM +0100, Christina Quast wrote:
> > This is the Rust implementation of drivers/net/phy/rockchip.c. The
> > features are equivalent. You can choose C or Rust version kernel
> > configuration.
> > 
> > Signed-off-by: Christina Quast <contact at christina-quast.de>
> Cool, but why?  Is this going to happen for all phy drivers going
> forward?  What's the end-game here, dropping all .c phy drivers that are
> in rust?  Or having duplicates for all of them?

As one of the PHY Maintainers, i would say no.

Now we have an example, i think we should be a lot more strict about
what we actually merge. It should be a driver for hardware which does
not have a C driver.

We cannot drop C drivers since Rust at the moment does not support all
architectures GCC/Clang does. PHY drivers are architecture
independent, and in real life used on multiple architectures. When
Rust eventually catches up, we could consider dropping C drivers when
there is an equivalent Rust driver, but from what i hear, that is a
few years away. I don't want to be supporting a C and Rust driver for
the same hardware.

     Andrew


From konrad.dybcio at linaro.org  Thu Feb  1 13:30:20 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Thu, 1 Feb 2024 22:30:20 +0100
Subject: [PATCH] arm64: defconfig: Enable Qualcomm interconnect providers
In-Reply-To: <20240201-enable-icc-8250-2290-v1-1-8ded02750521@quicinc.com>
References: <20240201-enable-icc-8250-2290-v1-1-8ded02750521@quicinc.com>
Message-ID: <67c87d4e-bfab-4248-8f4c-60a80ca3969f@linaro.org>

On 1.02.2024 22:31, Bjorn Andersson via B4 Relay wrote:
> From: Bjorn Andersson <quic_bjorande at quicinc.com>
> 
> With interconnect providers built as modules Qualcomm SM8250 and QCM2290
> platforms launches init without /dev/console being backed by the debug
> UART.
> 
> Build there drivers into the kernel, to make sure the dependencies for
> the UART driver are available and thereby give userspace access to the
> UART without having to re-open the console, once the deferred UART
> driver has probed.
> 
> Signed-off-by: Bjorn Andersson <quic_bjorande at quicinc.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>

Konrad


From andrew at lunn.ch  Thu Feb  1 13:33:09 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Thu, 1 Feb 2024 22:33:09 +0100
Subject: [PATCH v2 0/3] Add Rust Rockchip PHY driver
In-Reply-To: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
Message-ID: <123204c4-9fe9-42d4-9555-bd421494c0e1@lunn.ch>

On Thu, Feb 01, 2024 at 07:06:57PM +0100, Christina Quast wrote:
> Based on the example shown in drivers/net/phy/ax88796b_rust.rs, I ported
> the rockchip phy driver to Rust. The code in drivers/net/phy/rockchip.c
> was basically rewritten in Rust.  The patchset includes changes to
> phy.rs, adding more struct driver functions for the abstraction with
> Rust.
> 
> The driver was not tested on real hardware, because I do not have a
> board with this phy, and I would appreciate it if somebody could try
> out the driver on their board.

As a general point, please post such code RFT. Also adding RFC would
be good, and explain what sort of comments you are requesting.

    Andrew

---
pw-bot: cr




From florian.fainelli at broadcom.com  Thu Feb  1 13:50:10 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Thu,  1 Feb 2024 13:50:10 -0800
Subject: [PATCH] ARM: brcmstb: Add debug UART entry for 74165
In-Reply-To: <20240129184651.2405485-1-florian.fainelli@broadcom.com>
References: <20240129184651.2405485-1-florian.fainelli@broadcom.com>
Message-ID: <20240201215010.2633163-1-florian.fainelli@broadcom.com>

From: Florian Fainelli <f.fainelli at gmail.com>

On Mon, 29 Jan 2024 10:46:51 -0800, Florian Fainelli <florian.fainelli at broadcom.com> wrote:
> BCM74165 uses the same address map as the 7278 family (v7 memory map)
> therefore re-use that constant and shit down the other labels to keep
> numerical ordering.
> 
> Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/soc/next, thanks!
--
Florian


From daniel at makrotopia.org  Thu Feb  1 13:52:20 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Thu, 1 Feb 2024 21:52:20 +0000
Subject: [PATCH 1/2] dt-bindings: phy: mediatek,xfi-tphy: add new bindings
Message-ID: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>

Add bindings for the MediaTek XFI T-PHY Ethernet SerDes PHY found in the
MediaTek MT7988 SoC which can operate at various interfaces modes:

via USXGMII PCS:
 * USXGMII
 * 10GBase-R
 * 5GBase-R

via LynxI SGMII PCS:
 * 2500Base-X
 * 1000Base-X
 * Cisco SGMII (MAC side)

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 .../bindings/phy/mediatek,xfi-tphy.yaml       | 80 +++++++++++++++++++
 1 file changed, 80 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml

diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
new file mode 100644
index 0000000000000..e897118dcf7e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/mediatek,xfi-tphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek XFI T-PHY
+
+maintainers:
+  - Daniel Golle <daniel at makrotopia.org>
+
+description:
+  The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes
+  used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in
+  MediaTek's 10G-capabale SoCs.
+
+properties:
+  $nodename:
+    pattern: "^phy@[0-9a-f]+$"
+
+  compatible:
+    const: mediatek,mt7988-xfi-tphy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: XFI PHY clock
+      - description: XFI register clock
+
+  clock-names:
+    items:
+      - const: xfipll
+      - const: topxtal
+
+  resets:
+    items:
+      - description: PEXTP reset
+
+  mediatek,usxgmii-performance-errata:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      One instance of the T-PHY on MT7988 suffers from a performance
+      problem in 10GBase-R mode which needs a work-around in the driver.
+      The work-around is enabled using this flag.
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      phy at 11f20000 {
+        compatible = "mediatek,mt7988-xfi-tphy";
+        reg = <0 0x11f20000 0 0x10000>;
+        clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>,
+                 <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
+        clock-names = "xfipll", "topxtal";
+        resets = <&watchdog 14>;
+        mediatek,usxgmii-performance-errata;
+        #phy-cells = <0>;
+      };
+    };
+
+...
-- 
2.43.0


From daniel at makrotopia.org  Thu Feb  1 13:53:06 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Thu, 1 Feb 2024 21:53:06 +0000
Subject: [PATCH 2/2] phy: add driver for MediaTek XFI T-PHY
In-Reply-To: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
Message-ID: <dd6b40ea1f7f8459a9a2cfe7fa60c1108332ade6.1706823233.git.daniel@makrotopia.org>

Add driver for MediaTek's XFI T-PHY, 10 Gigabit/s Ethernet SerDes PHY
which can be found in the MT7988 SoC.

The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
PHY_INTERFACE_MODE_* corresponding to the supported modes:

 * USXGMII                 \
 * 10GBase-R                }- USXGMII PCS - XGDM  \
 * 5GBase-R                /                        \
                                                     }- Ethernet MAC
 * 2500Base-X              \                        /
 * 1000Base-X               }- LynxI PCS - GDM     /
 * Cisco SGMII (MAC side)  /

In order to work-around a performance issue present on the first of
two XFI T-PHYs present in MT7988, special tuning is applied which can be
selected by adding the 'mediatek,usxgmii-performance-errata' property to
the device tree node.

There is no documentation for most registers used for the
analog/tuning part, however, most of the registers have been partially
reverse-engineered from MediaTek's SDK implementation (an opaque
sequence of 32-bit register writes) and descriptions for all relevant
digital registers and bits such as resets and muxes have been supplied
by MediaTek.

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 MAINTAINERS                             |   1 +
 drivers/phy/mediatek/Kconfig            |  12 +
 drivers/phy/mediatek/Makefile           |   1 +
 drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 392 ++++++++++++++++++++++++
 4 files changed, 406 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 52769631bdb1a..52e4192470bd9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13715,6 +13715,7 @@ L:	netdev at vger.kernel.org
 S:	Maintained
 F:	drivers/net/phy/mediatek-ge-soc.c
 F:	drivers/net/phy/mediatek-ge.c
+F:	drivers/phy/mediatek/phy-mtk-xfi-tphy.c
 
 MEDIATEK I2C CONTROLLER DRIVER
 M:	Qii Wang <qii.wang at mediatek.com>
diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index 3125ecb5d119f..5161d130c7f8b 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -13,6 +13,18 @@ config PHY_MTK_PCIE
 	  callback for PCIe GEN3 port, it supports software efuse
 	  initialization.
 
+config PHY_MTK_XFI_TPHY
+	tristate "MediaTek XFI T-PHY Driver"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on OF && OF_ADDRESS
+	depends on HAS_IOMEM
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for MediaTek XFI T-PHY driver.
+	  The driver provides access to the Ethernet SerDes T-PHY supporting
+	  1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
+	  via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
+
 config PHY_MTK_TPHY
 	tristate "MediaTek T-PHY Driver"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index c9a50395533eb..fa7217178e7f4 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
 obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
 obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
+obj-$(CONFIG_PHY_MTK_XFI_TPHY)		+= phy-mtk-xfi-tphy.o
 
 phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
 phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
new file mode 100644
index 0000000000000..d50e6320860e5
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* MediaTek 10GE SerDes PHY driver
+ *
+ * Copyright (c) 2024 Daniel Golle <daniel at makrotopia.org>
+ *                    Bc-bocun Chen <bc-bocun.chen at mediatek.com>
+ * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Henry Yen <henry.yen at mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
+
+#define MTK_XFI_TPHY_NUM_CLOCKS		2
+
+#define REG_DIG_GLB_70			0x0070
+#define  XTP_PCS_RX_EQ_IN_PROGRESS(x)	FIELD_PREP(GENMASK(25, 24), (x))
+#define  XTP_PCS_MODE_MASK		GENMASK(17, 16)
+#define  XTP_PCS_MODE(x)		FIELD_PREP(GENMASK(17, 16), (x))
+#define  XTP_PCS_RST_B			BIT(15)
+#define  XTP_FRC_PCS_RST_B		BIT(14)
+#define  XTP_PCS_PWD_SYNC_MASK		GENMASK(13, 12)
+#define  XTP_PCS_PWD_SYNC(x)		FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
+#define  XTP_PCS_PWD_ASYNC_MASK		GENMASK(11, 10)
+#define  XTP_PCS_PWD_ASYNC(x)		FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
+#define  XTP_FRC_PCS_PWD_ASYNC		BIT(8)
+#define  XTP_PCS_UPDT			BIT(4)
+#define  XTP_PCS_IN_FR_RG		BIT(0)
+
+#define REG_DIG_GLB_F4			0x00f4
+#define  XFI_DPHY_PCS_SEL		BIT(0)
+#define   XFI_DPHY_PCS_SEL_SGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 1)
+#define   XFI_DPHY_PCS_SEL_USXGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 0)
+#define  XFI_DPHY_AD_SGDT_FRC_EN	BIT(5)
+
+#define REG_DIG_LN_TRX_40		0x3040
+#define  XTP_LN_FRC_TX_DATA_EN		BIT(29)
+#define  XTP_LN_TX_DATA_EN		BIT(28)
+
+#define REG_DIG_LN_TRX_B0		0x30b0
+#define  XTP_LN_FRC_TX_MACCK_EN		BIT(5)
+#define  XTP_LN_TX_MACCK_EN		BIT(4)
+
+#define REG_ANA_GLB_D0			0x90d0
+#define  XTP_GLB_USXGMII_SEL_MASK	GENMASK(3, 1)
+#define  XTP_GLB_USXGMII_SEL(x)		FIELD_PREP(GENMASK(3, 1), (x))
+#define  XTP_GLB_USXGMII_EN		BIT(0)
+
+struct mtk_xfi_tphy {
+	void __iomem		*base;
+	struct device		*dev;
+	struct reset_control	*reset;
+	struct clk_bulk_data	clocks[MTK_XFI_TPHY_NUM_CLOCKS];
+	bool			da_war;
+};
+
+static void mtk_xfi_tphy_write(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
+			       u32 value)
+{
+	iowrite32(value, xfi_tphy->base + reg);
+}
+
+static void mtk_xfi_tphy_rmw(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
+			     u32 clr, u32 set)
+{
+	u32 val;
+
+	val = ioread32(xfi_tphy->base + reg);
+	val &= ~clr;
+	val |= set;
+	iowrite32(val, xfi_tphy->base + reg);
+}
+
+static void mtk_xfi_tphy_set(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
+			     u32 set)
+{
+	mtk_xfi_tphy_rmw(xfi_tphy, reg, 0, set);
+}
+
+static void mtk_xfi_tphy_clear(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
+			       u32 clr)
+{
+	mtk_xfi_tphy_rmw(xfi_tphy, reg, clr, 0);
+}
+
+static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
+			       phy_interface_t interface)
+{
+	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
+	bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
+		      interface == PHY_INTERFACE_MODE_SGMII);
+	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
+		       interface == PHY_INTERFACE_MODE_USXGMII);
+	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
+	bool is_xgmii = (is_10g || is_5g);
+
+	dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));
+
+	/* Setup PLL setting */
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x2030, 0x500, is_1g ? 0x0 : 0x500);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x2040, 0x340000, is_1g ? 0x200000 :
+							     0x140000);
+
+	/* Setup RXFE BW setting */
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x50f0, 0xc10, is_1g ? 0x410 :
+							  is_5g ? 0x800 : 0x400);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
+
+	/* Setup RX CDR setting */
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x5078, 0xf000400, is_5g ? 0x8000000 :
+							      0x7000400);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x507c, 0x5000500, is_5g ? 0x4000400 :
+							      0x1000100);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x5080, 0x1410, is_1g ? 0x400 :
+							   is_5g ? 0x1010 : 0x0);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x5084, 0x30300, is_1g ? 0x30300 :
+							    is_5g ? 0x30100 :
+								    0x100);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x5088, 0x60200, is_1g ? 0x20200 :
+							 is_5g ? 0x40000 :
+								 0x20000);
+
+	/* Setting RXFE adaptation range setting */
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x50a8, 0xee0000, is_5g ? 0x800000 :
+							     0x6e0000);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);
+	if (is_10g)
+		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x01423342);
+	else if (is_5g)
+		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00a132a1);
+	else if (is_2p5g)
+		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x009c329c);
+	else
+		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00fa32fa);
+
+	/* Force SGDT_OUT off and select PCS */
+	mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_F4,
+			 XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
+			 XFI_DPHY_AD_SGDT_FRC_EN |
+			 (is_xgmii ? XFI_DPHY_PCS_SEL_USXGMII :
+				     XFI_DPHY_PCS_SEL_SGMII));
+
+
+	/* Force GLB_CKDET_OUT */
+	mtk_xfi_tphy_set(xfi_tphy, 0x0030, 0xc00);
+
+	/* Force AEQ on */
+	mtk_xfi_tphy_write(xfi_tphy, REG_DIG_GLB_70,
+			   XTP_PCS_RX_EQ_IN_PROGRESS(2) |
+			   XTP_PCS_PWD_SYNC(2) |
+			   XTP_PCS_PWD_ASYNC(2));
+
+	usleep_range(1, 5);
+
+	/* Setup TX DA default value */
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x30b0, 0x30, 0x20);
+	mtk_xfi_tphy_write(xfi_tphy, 0x3028, 0x00008a01);
+	mtk_xfi_tphy_write(xfi_tphy, 0x302c, 0x0000a884);
+	mtk_xfi_tphy_write(xfi_tphy, 0x3024, 0x00083002);
+
+	/* Setup RG default value */
+	if (is_xgmii) {
+		mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00022220);
+		mtk_xfi_tphy_write(xfi_tphy, 0x5064, 0x0f020a01);
+		mtk_xfi_tphy_write(xfi_tphy, 0x50b4, 0x06100600);
+		if (interface == PHY_INTERFACE_MODE_USXGMII)
+			mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
+		else
+			mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x47684100);
+	} else {
+		mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00011110);
+		mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
+	}
+
+	if (is_1g)
+		mtk_xfi_tphy_write(xfi_tphy, 0x3064, 0x0000c000);
+
+	/* Setup RX EQ initial value */
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x3050, 0xa8000000,
+			 (interface != PHY_INTERFACE_MODE_10GBASER) ?
+			  0xa8000000 : 0x0);
+	mtk_xfi_tphy_rmw(xfi_tphy, 0x3054, 0xaa,
+			 (interface != PHY_INTERFACE_MODE_10GBASER) ?
+			  0xaa : 0x0);
+
+	if (is_xgmii)
+		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x00000f00);
+	else if (is_2p5g)
+		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x22000f00);
+	else
+		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x20200f00);
+
+	if (interface == PHY_INTERFACE_MODE_10GBASER && xfi_tphy->da_war)
+		mtk_xfi_tphy_rmw(xfi_tphy, 0xa008, 0x10000, 0x10000);
+
+	mtk_xfi_tphy_rmw(xfi_tphy, 0xa060, 0x50000, is_xgmii ? 0x40000 :
+							       0x50000);
+
+	/* Setup PHYA speed */
+	mtk_xfi_tphy_rmw(xfi_tphy, REG_ANA_GLB_D0,
+			 XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
+			 is_10g ?  XTP_GLB_USXGMII_SEL(0) :
+			 is_5g ?   XTP_GLB_USXGMII_SEL(1) :
+			 is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
+				   XTP_GLB_USXGMII_SEL(3));
+	mtk_xfi_tphy_set(xfi_tphy, REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
+
+	/* Release reset */
+	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_GLB_70,
+			 XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
+	usleep_range(150, 500);
+
+	/* Switch to P0 */
+	mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
+			 XTP_PCS_PWD_SYNC_MASK |
+			 XTP_PCS_PWD_ASYNC_MASK,
+			 XTP_FRC_PCS_PWD_ASYNC |
+			 XTP_PCS_UPDT | XTP_PCS_IN_FR_RG);
+	usleep_range(1, 5);
+
+	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
+	usleep_range(15, 50);
+
+	if (is_xgmii) {
+		/* Switch to Gen3 */
+		mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
+				 XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
+				 XTP_PCS_MODE(2) | XTP_PCS_UPDT);
+	} else {
+		/* Switch to Gen2 */
+		mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
+				 XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
+				 XTP_PCS_MODE(1) | XTP_PCS_UPDT);
+	}
+	usleep_range(1, 5);
+
+	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
+
+	usleep_range(100, 500);
+
+	/* Enable MAC CK */
+	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
+	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN);
+
+	/* Enable TX data */
+	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_40,
+			 XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
+	usleep_range(400, 1000);
+}
+
+static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int
+				 submode)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	if (mode != PHY_MODE_ETHERNET)
+		return -EINVAL;
+
+	switch (submode) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		mtk_xfi_tphy_setup(xfi_tphy, submode);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mtk_xfi_tphy_reset(struct phy *phy)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	reset_control_assert(xfi_tphy->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(xfi_tphy->reset);
+	usleep_range(1, 10);
+
+	return 0;
+}
+
+static int mtk_xfi_tphy_power_on(struct phy *phy)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
+}
+
+static int mtk_xfi_tphy_power_off(struct phy *phy)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_xfi_tphy_ops = {
+	.power_on	= mtk_xfi_tphy_power_on,
+	.power_off	= mtk_xfi_tphy_power_off,
+	.set_mode	= mtk_xfi_tphy_set_mode,
+	.reset		= mtk_xfi_tphy_reset,
+	.owner		= THIS_MODULE,
+};
+
+static int mtk_xfi_tphy_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct phy_provider *phy_provider;
+	struct mtk_xfi_tphy *xfi_tphy;
+	struct phy *phy;
+
+	if (!np)
+		return -ENODEV;
+
+	xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
+	if (!xfi_tphy)
+		return -ENOMEM;
+
+	xfi_tphy->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
+	if (!xfi_tphy->base)
+		return -EIO;
+
+	xfi_tphy->dev = &pdev->dev;
+
+	xfi_tphy->clocks[0].id = "topxtal";
+	xfi_tphy->clocks[0].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[0].id);
+	if (IS_ERR(xfi_tphy->clocks[0].clk))
+		return PTR_ERR(xfi_tphy->clocks[0].clk);
+
+	xfi_tphy->clocks[1].id = "xfipll";
+	xfi_tphy->clocks[1].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[1].id);
+	if (IS_ERR(xfi_tphy->clocks[1].clk))
+		return PTR_ERR(xfi_tphy->clocks[1].clk);
+
+	xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(xfi_tphy->reset))
+		return PTR_ERR(xfi_tphy->reset);
+
+	xfi_tphy->da_war = of_property_read_bool(np,
+						 "mediatek,usxgmii-performance-errata");
+
+	phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	phy_set_drvdata(phy, xfi_tphy);
+
+	phy_provider = devm_of_phy_provider_register(&pdev->dev,
+						     of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id mtk_xfi_tphy_match[] = {
+	{ .compatible = "mediatek,mt7988-xfi-tphy", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
+
+static struct platform_driver mtk_xfi_tphy_driver = {
+	.probe = mtk_xfi_tphy_probe,
+	.driver = {
+		.name = "mtk-xfi-tphy",
+		.of_match_table = mtk_xfi_tphy_match,
+	},
+};
+module_platform_driver(mtk_xfi_tphy_driver);
+
+MODULE_DESCRIPTION("MediaTek XFI T-PHY driver");
+MODULE_AUTHOR("Daniel Golle <daniel at makrotopia.org>");
+MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen at mediatek.com>");
+MODULE_LICENSE("GPL");
-- 
2.43.0


From robh at kernel.org  Thu Feb  1 13:53:38 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 1 Feb 2024 15:53:38 -0600
Subject: [PATCH 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240131164709.810587-3-dan.scally@ideasonboard.com>
References: <20240131164709.810587-1-dan.scally@ideasonboard.com>
 <20240131164709.810587-3-dan.scally@ideasonboard.com>
Message-ID: <20240201215338.GA1544581-robh@kernel.org>

On Wed, Jan 31, 2024 at 04:47:06PM +0000, Daniel Scally wrote:
> Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
> 
> Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> ---
>  .../bindings/media/arm,mali-c55.yaml          | 51 +++++++++++++++++++
>  1 file changed, 51 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> new file mode 100644
> index 000000000000..83000175aeda
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ARM Mali-C55 Image Signal Processor
> +
> +maintainers:
> +  - Daniel Scally <dan.scally at ideasonboard.com>
> +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> +
> +properties:
> +  compatible:
> +    const: arm,mali-c55
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  port:
> +    $ref: /schemas/graph.yaml#/properties/port
> +
> +    properties:
> +      endpoint:
> +        $ref: /schemas/graph.yaml#/properties/endpoint
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - port

Surely some clocks are needed.

> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    mali_c55: isp at 400000 {
> +      compatible = "arm,mali-c55";
> +      reg = <0x400000 0x200000>;
> +      interrupts = <0>;
> +
> +      port at 0 {
> +        isp_in: endpoint at 0 {
> +          remote-endpoint = <&mipi_out>;
> +        };
> +      };
> +    };
> +...
> -- 
> 2.34.1
> 


From andersson at kernel.org  Thu Feb  1 13:53:51 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Thu,  1 Feb 2024 15:53:51 -0600
Subject: (subset) [PATCH v4 0/8] arm64: dts: qcom: sa8295p: Enable GPU
In-Reply-To: <20240125-sa8295p-gpu-v4-0-7011c2a63037@quicinc.com>
References: <20240125-sa8295p-gpu-v4-0-7011c2a63037@quicinc.com>
Message-ID: <170682442869.248329.14691453184149397609.b4-ty@kernel.org>


On Thu, 25 Jan 2024 13:05:06 -0800, Bjorn Andersson wrote:
> Due to the different PMIC configuration found in the SA8295P platform,
> compared to SC8280XP, the VDD_GFX pads are supplied by an dedicated
> MAX20411 LDO.
> 
> Support for expressing the regulator supply is added to the binding, the
> support for enabling the parent supply for GX is added, the missing
> gfx.lvl power-domain is dropped, and the DeviceTree is wired up to
> enable the GPU in this configuration.
> 
> [...]

Applied, thanks!

[8/8] arm64: defconfig: Enable MAX20411 regulator driver
      commit: 42945eb663d88471a0c394d9f466401b1a8d791f

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From mmayer at broadcom.com  Thu Feb  1 14:01:50 2024
From: mmayer at broadcom.com (Markus Mayer)
Date: Thu, 1 Feb 2024 14:01:50 -0800
Subject: [PATCH v2 1/5] dt-bindings: memory: remove generic compatible
 string brcm,dpfe-cpu
In-Reply-To: <6d8d5c33-f814-4c06-ae97-7579aec3bb15@linaro.org>
References: <20240119215231.758844-1-mmayer@broadcom.com> <20240119215231.758844-2-mmayer@broadcom.com>
 <6d8d5c33-f814-4c06-ae97-7579aec3bb15@linaro.org>
Message-ID: <CAGt4E5uU1aiS9ZFowYFUYM5ARdzR2sP+FaWErjZ-VbEoui3-0A@mail.gmail.com>

On Tue, 23 Jan 2024 at 13:22, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 19/01/2024 22:52, Markus Mayer wrote:
> > The generic compatible string "brcm,dpfe-cpu" is removed from the
> > binding as it does not provide any actual benefit.
> >
> > Signed-off-by: Markus Mayer <mmayer at broadcom.com>
> > ---
> >  .../devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml  | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> > index 08cbdcddfead..e2b990e4a792 100644
> > --- a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> > +++ b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> > @@ -16,7 +16,6 @@ properties:
> >        - enum:
> >            - brcm,bcm7271-dpfe-cpu
> >            - brcm,bcm7268-dpfe-cpu
> > -      - const: brcm,dpfe-cpu
>
> We cannot have undocumented compatibles, so I think you wanted to
> deprecate it instead. Also, please extend the reasoning from "any actual
> benefit". Were there any users? Don't they need it?

Absolutely. I'll change it to deprecate the compatible string instead.

As for the reason deprecating it, it was intended as the "standard"
compatible string that everybody would end up using with the
chip-specific one as fallback should a particular chip require a tweak
down the road. That's why it was introduced. But then the business
with the incompatible DPFE APIs started happening, and the plan to use
"brcm,dpfe-cpu" as the "normal" compatible string that everybody could
use was no longer workable.

Does that make sense as the more in-depth explanation for deprecating it?

Regards,
-Markus


From mmayer at broadcom.com  Thu Feb  1 14:03:03 2024
From: mmayer at broadcom.com (Markus Mayer)
Date: Thu, 1 Feb 2024 14:03:03 -0800
Subject: [PATCH v2 2/5] dt-bindings: memory: add two chip-specific
 compatible string
In-Reply-To: <279dab82-aff6-4d1d-b414-57910433e36c@linaro.org>
References: <20240119215231.758844-1-mmayer@broadcom.com> <20240119215231.758844-3-mmayer@broadcom.com>
 <279dab82-aff6-4d1d-b414-57910433e36c@linaro.org>
Message-ID: <CAGt4E5uucNbsyeBeTesQ9pJj+9gtOut7MaoOBhqVfVJL-Hjq1A@mail.gmail.com>

On Tue, 23 Jan 2024 at 13:23, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 19/01/2024 22:52, Markus Mayer wrote:
> > Add brcm,bcm7278-dpfe-cpu and brcm,bcm7211-dpfe-cpu to the list of
> > acceptable compatible strings.
> >
> > Signed-off-by: Markus Mayer <mmayer at broadcom.com>
> > ---
> >  .../devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml   | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> > index e2b990e4a792..3f00bc2fd3ec 100644
> > --- a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> > +++ b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> > @@ -16,6 +16,8 @@ properties:
> >        - enum:
> >            - brcm,bcm7271-dpfe-cpu
> >            - brcm,bcm7268-dpfe-cpu
> > +          - brcm,bcm7278-dpfe-cpu
> > +          - brcm,bcm7211-dpfe-cpu
>
> Let's not make it more random than it already is. Feel free to re-order
> the two entries to have alphabetical order and then place new entries in
> proper places.

Will do.

> Best regards,
> Krzysztof


From nathan at kernel.org  Thu Feb  1 14:08:53 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Thu, 1 Feb 2024 15:08:53 -0700
Subject: [PATCH 1/3] media: pci: sta2x11: Fix Wcast-function-type-strict
 warnings
In-Reply-To: <20240128-fix-clang-warnings-v1-1-1d946013a421@chromium.org>
References: <20240128-fix-clang-warnings-v1-0-1d946013a421@chromium.org>
 <20240128-fix-clang-warnings-v1-1-1d946013a421@chromium.org>
Message-ID: <20240201220853.GA2240065@dev-arch.thelio-3990X>

On Sun, Jan 28, 2024 at 02:12:20AM +0000, Ricardo Ribalda wrote:
> Building with LLVM=1 throws the following warning:
> drivers/media/pci/sta2x11/sta2x11_vip.c:1057:6: warning: cast from 'irqreturn_t (*)(int, struct sta2x11_vip *)' (aka 'enum irqreturn (*)(int, struct sta2x11_vip *)') to 'irq_handler_t' (aka 'enum irqreturn (*)(int, void *)') converts to incompatible function type [-Wcast-function-type-strict]
> 
> Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>

Reviewed-by: Nathan Chancellor <nathan at kernel.org>

I wonder if the media tree cares about reverse Christmas tree order for
variables?

> ---
>  drivers/media/pci/sta2x11/sta2x11_vip.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
> index e4cf9d63e926..0a3827575753 100644
> --- a/drivers/media/pci/sta2x11/sta2x11_vip.c
> +++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
> @@ -757,7 +757,7 @@ static const struct video_device video_dev_template = {
>  /**
>   * vip_irq - interrupt routine
>   * @irq: Number of interrupt ( not used, correct number is assumed )
> - * @vip: local data structure containing all information
> + * @data: local data structure containing all information
>   *
>   * check for both frame interrupts set ( top and bottom ).
>   * check FIFO overflow, but limit number of log messages after open.
> @@ -767,9 +767,10 @@ static const struct video_device video_dev_template = {
>   *
>   * IRQ_HANDLED, interrupt done.
>   */
> -static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
> +static irqreturn_t vip_irq(int irq, void *data)
>  {
>  	unsigned int status;
> +	struct sta2x11_vip *vip = data;
>  
>  	status = reg_read(vip, DVP_ITS);
>  
> 
> -- 
> 2.43.0.429.g432eaa2c6b-goog
> 


From nathan at kernel.org  Thu Feb  1 14:09:26 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Thu, 1 Feb 2024 15:09:26 -0700
Subject: [PATCH 2/3] media: usb: pvrusb2: Fix Wcast-function-type-strict
 warnings
In-Reply-To: <20240128-fix-clang-warnings-v1-2-1d946013a421@chromium.org>
References: <20240128-fix-clang-warnings-v1-0-1d946013a421@chromium.org>
 <20240128-fix-clang-warnings-v1-2-1d946013a421@chromium.org>
Message-ID: <20240201220926.GB2240065@dev-arch.thelio-3990X>

On Sun, Jan 28, 2024 at 02:12:21AM +0000, Ricardo Ribalda wrote:
> Building with LLVM=1 throws the following warning:
> drivers/media/usb/pvrusb2/pvrusb2-context.c:110:6: warning: cast from 'void (*)(struct pvr2_context *)' to 'void (*)(void *)' converts to incompatible function type [-Wcast-function-type-strict]
> drivers/media/usb/pvrusb2/pvrusb2-v4l2.c:1070:30: warning: cast from 'void (*)(struct pvr2_v4l2_fh *)' to 'pvr2_stream_callback' (aka 'void (*)(void *)') converts to incompatible function type [-Wcast-function-type-strict] drivers/media/usb/pvrusb2/pvrusb2-dvb.c:152:6: warning: cast from 'void (*)(struct pvr2_dvb_adapter *)' to 'pvr2_stream_callback' (aka 'void (*)(void *)') converts to incompatible function type [-Wcast-function-type-strict]
> 
> Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>

Reviewed-by: Nathan Chancellor <nathan at kernel.org>

> ---
>  drivers/media/usb/pvrusb2/pvrusb2-context.c | 5 +++--
>  drivers/media/usb/pvrusb2/pvrusb2-dvb.c     | 7 ++++---
>  drivers/media/usb/pvrusb2/pvrusb2-v4l2.c    | 7 ++++---
>  3 files changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c
> index 1764674de98b..16edabda191c 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-context.c
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c
> @@ -90,8 +90,9 @@ static void pvr2_context_destroy(struct pvr2_context *mp)
>  }
>  
>  
> -static void pvr2_context_notify(struct pvr2_context *mp)
> +static void pvr2_context_notify(void *data)
>  {
> +	struct pvr2_context *mp = data;
>  	pvr2_context_set_notify(mp,!0);
>  }
>  
> @@ -107,7 +108,7 @@ static void pvr2_context_check(struct pvr2_context *mp)
>  			   "pvr2_context %p (initialize)", mp);
>  		/* Finish hardware initialization */
>  		if (pvr2_hdw_initialize(mp->hdw,
> -					(void (*)(void *))pvr2_context_notify,
> +					pvr2_context_notify,
>  					mp)) {
>  			mp->video_stream.stream =
>  				pvr2_hdw_get_video_stream(mp->hdw);
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
> index 26811efe0fb5..8b9f1a09bd53 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
> @@ -88,8 +88,9 @@ static int pvr2_dvb_feed_thread(void *data)
>  	return stat;
>  }
>  
> -static void pvr2_dvb_notify(struct pvr2_dvb_adapter *adap)
> +static void pvr2_dvb_notify(void *data)
>  {
> +	struct pvr2_dvb_adapter *adap = data;
>  	wake_up(&adap->buffer_wait_data);
>  }
>  
> @@ -148,8 +149,8 @@ static int pvr2_dvb_stream_do_start(struct pvr2_dvb_adapter *adap)
>  		if (!(adap->buffer_storage[idx])) return -ENOMEM;
>  	}
>  
> -	pvr2_stream_set_callback(pvr->video_stream.stream,
> -				 (pvr2_stream_callback) pvr2_dvb_notify, adap);
> +	pvr2_stream_set_callback(pvr->video_stream.stream, pvr2_dvb_notify,
> +				 adap);
>  
>  	ret = pvr2_stream_set_buffer_count(stream, PVR2_DVB_BUFFER_COUNT);
>  	if (ret < 0) return ret;
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
> index c04ab7258d64..590f80949bbf 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
> @@ -1032,9 +1032,10 @@ static int pvr2_v4l2_open(struct file *file)
>  	return 0;
>  }
>  
> -
> -static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
> +static void pvr2_v4l2_notify(void *data)
>  {
> +	struct pvr2_v4l2_fh *fhp = data;
> +
>  	wake_up(&fhp->wait_data);
>  }
>  
> @@ -1067,7 +1068,7 @@ static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
>  
>  	hdw = fh->channel.mc_head->hdw;
>  	sp = fh->pdi->stream->stream;
> -	pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
> +	pvr2_stream_set_callback(sp, pvr2_v4l2_notify, fh);
>  	pvr2_hdw_set_stream_type(hdw,fh->pdi->config);
>  	if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
>  	return pvr2_ioread_set_enabled(fh->rhp,!0);
> 
> -- 
> 2.43.0.429.g432eaa2c6b-goog
> 


From maskray at google.com  Thu Feb  1 14:12:06 2024
From: maskray at google.com (Fangrui Song)
Date: Thu, 1 Feb 2024 14:12:06 -0800
Subject: [PATCH] arm64: jump_label: use constraint "S" instead of "i"
In-Reply-To: <CAMj1kXGAi94DuCYRPWQujGz7YVTS=53h_+FretCsYFbxznJVHw@mail.gmail.com>
References: <20240131065322.1126831-1-maskray@google.com> <CAMj1kXGzADFWa7RmXyjWpCnQ=9hhz6i-XkN4PS1CboZ-kFL8dQ@mail.gmail.com>
 <ZbpEnDK3U/O24ng0@e133380.arm.com> <20240201045551.ajg4iqcajyowl2rh@google.com>
 <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>
 <20240201091120.pbgr7ng6t2c36fut@google.com> <ZbuFWSRBntgm2ukJ@e133380.arm.com>
 <CAMj1kXGu76WHY8=Y-KhCxBq3xeHeCYQ9syqViSr9VRkjgWQ3BQ@mail.gmail.com>
 <ZbvVApJ2/+yca0u6@e133380.arm.com> <20240201205614.w3gcz6urfxtydr77@google.com>
 <CAMj1kXGAi94DuCYRPWQujGz7YVTS=53h_+FretCsYFbxznJVHw@mail.gmail.com>
Message-ID: <CAFP8O3JB1miCHoGFh7UY6dCa4WS6+88mnB_qxXnvYp4wHnYgBw@mail.gmail.com>

On Thu, Feb 1, 2024 at 1:23?PM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> On Thu, 1 Feb 2024 at 21:56, Fangrui Song <maskray at google.com> wrote:
> >
> > On 2024-02-01, Dave Martin wrote:
> > >On Thu, Feb 01, 2024 at 05:07:59PM +0100, Ard Biesheuvel wrote:
> > >> On Thu, 1 Feb 2024 at 12:50, Dave Martin <Dave.Martin at arm.com> wrote:
> > >> >
> > >> > On Thu, Feb 01, 2024 at 01:11:20AM -0800, Fangrui Song wrote:
> > >> ...
> > >> > >
> > >> > > Hmm. Clang's constraint "S" implementation doesn't support a constant
> > >> > > offset, so
> > >> > > `static_key_false(&nf_hooks_needed[pf][hook])` in include/linux/netfilter.h:nf_hook
> > >> > > would not compile with Clang <= 18.
> > >> > >
> > >> > > I have a patch https://github.com/llvm/llvm-project/pull/80255 , but
> > >> > > even if it is accepted and cherry-picked into the 18.x release branch,
> > >> > > if we still support older Clang, we cannot use "S" unconditionally.
> > >> > >
> > >> > >
> > >> > > So we probably need the following to prepare for -fPIE support in the
> > >> > > future:
> > >> > >
> > >> > > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> > >> > > index 48ddc0f45d22..b8af2f8b0c99 100644
> > >> > > --- a/arch/arm64/include/asm/jump_label.h
> > >> > > +++ b/arch/arm64/include/asm/jump_label.h
> > >> > > @@ -15,6 +15,16 @@
> > >> > >  #define JUMP_LABEL_NOP_SIZE          AARCH64_INSN_SIZE
> > >> > > +/*
> > >> > > + * Prefer "S" to support PIC. However, use "i" for Clang 18 and earlier as "S"
> > >> > > + * on a symbol with a constant offset is not supported.
> > >> > > + */
> > >> > > +#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 18
> > >> >
> > >> > Is a GCC version check needed?  Or is the minimum GCC version specified
> > >> > for building the kernel new enough?
> > >> >
> > >> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
> > >> > > +#else
> > >> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "S"
> > >> > > +#endif
> > >> > > +
> > >>
> > >> Can we use "Si" instead?
> > >
> > >I thought the point was to avoid "S" on compilers that would choke on
> > >it?  If so, those compilers would surely choke on "Si" too, no?
> >
> > "Si" is an invalid constraint. Unfortunately, GCC recognizes "S" as a
> > valid constraint and ignores trailing characters (asm_operand_ok). That
> > is, GCC would accept "Siiiii" as well...
> >
> > The GCC support for "S" is great. The initial aarch64 port in 2012 supports "S".
> >
>
> So it is not possible to combine the S and i constraint, and let the
> compiler figure out whether it meets either? We rely on this elsewhere
> by combining r and Z into rZ. x86 uses "rm" for inline asm parameters
> that could be either register or memory operands.

I did not realize that your "Si" suggestion meant this feature
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

    After the prefix, there must be one or more additional constraints
(see Constraints for asm Operands) that describe where the value
resides. Common constraints include ?r? for register and ?m? for
memory. When you list more than one possible location (for example,
"=rm"), the compiler chooses the most efficient one based on the
current context.

After some debugging of both GCC and Clang, I think you are right and
"Si" will work. Thanks for the suggestion!

GCC accepts "Si". Sorry for my incorrectly stating that GCC ignores
the trailing constraint. GCC does ignore an unknown constraint, as
long as one accepted constraint.

Clang accepts "Si" as well. In the absence of
https://github.com/llvm/llvm-project/pull/80255 (constant offset
support for 'S'), in TargetLowering::ComputeConstraintToUse, 'S' is
skipped and 'i' will be picked. This is unrelated to the "rm" weakness
in Clang (https://github.com/llvm/llvm-project/issues/20571).

I'll post a PATCH v2 removing JUMP_LABEL_STATIC_KEY_CONSTRAINT and
using "Si" unconditionally.

>
> > >> > >  static __always_inline bool arch_static_branch(struct static_key * const key,
> > >> > >                                              const bool branch)
> > >> > >  {
> > >> > > @@ -23,9 +33,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
> > >> > >                "      .pushsection    __jump_table, \"aw\"    \n\t"
> > >> > >                "      .align          3                       \n\t"
> > >> > >                "      .long           1b - ., %l[l_yes] - .   \n\t"
> > >> > > -              "      .quad           %c0 - .                 \n\t"
> > >> > > +              "      .quad           %0 + %1 - .             \n\t"
> > >> > >                "      .popsection                             \n\t"
> > >> > > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> > >> > > +              :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);
> > >> >
> > >> > While this looks reasonable, I'm still not clear now why the asm must do
> > >> > the addition.
> > >> >
> > >> > Can we roll the branch argument into the macro?
> > >> >
> > >> > "S"(symbol + constant) seems to do the right thing for AArch64, at least
> > >> > in GCC.
> > >> >
> > >>
> > >> 'symbol' is a struct static_key pointer, so adding '1' to it will not
> > >> produce the needed result.
> > >
> > >I mean loosely things that resolve to something of the form
> > >"symbol + constant" in the compiler output.
> > >
> > >"S"(&((char *)key)[branch]) does indeed seem to do the right thing,
> > >at least with GCC.
> > >
> > >I probably didn't help by bikeshedding the way that expression was
> > >written, apologies for that.  It's orthogonal to what this patch is
> > >doing.
> >
> > Yes, "S"(&((char *)key)[branch])  would do the right thing.
> > I have compared assembly output. It's a matter of "s" vs "s + 0" and "s+1" vs "s + 1".
> >
>
> But if S does not work with constant offsets with older Clang, what is
> the harm in splitting it into "S" for the symbol and "i" for the
> branch?
> ...
> > >>
> > >> The only thing PIE linking does in the case of the kernel is
> > >> a) complain if static relocations are used that cannot be fixed up at
> > >> runtime (e.g., movk/movz sequences)
> > >> b) emit dynamic relocations that the early startup code can use to fix
> > >> up all statically initialized pointers
> > >>
> > >> From a codegen point-of-view, there is no difference because we don't
> > >> use -fpic code. The problem with -fpic codegen is that it makes some
> > >> assumptions that only hold for shared ELF objects, e.g., avoiding
> > >> dynamic relocations in .text, using GOT entries even for variables
> > >> defined in the same compilation so that they can be preempted, keeping
> > >> all runtime relocatable quantities together so the CoW footprint of
> > >> the shared library is minimized.
> > >>
> > >> None of this matters for the kernel, and as it turns out, the non-PIC
> > >> small C model produces code that the PIE linker is happy with.
> > >>
> > >> TL;DR our code (including inline and out-of-line asm) is already PIC,
> > >> and this property is relied upon by KASLR.
> > >>
> > >> > Maybe it doesn't make as much difference as I thought (certainly ADRP
> > >> > based addressing should make a fair amount of the PIC/PIE overhead go
> > >> > away).
> > >> >
> > >>
> > >> The PIC/PIE overhead is in the indirections via the GOT. However,
> > >> recent linkers will actually perform some relaxations too: if a symbol
> > >> is defined in the same executable and is not preemptible, a GOT load
> > >>
> > >> ADRP
> > >> LDR
> > >>
> > >> can be transparently converted to
> > >>
> > >> ADRP
> > >> ADD
> > >>
> > >> referring to the symbol directly. This is also where hidden.h comes
> > >> in: making all symbol declarations and definitions 'hidden' will allow
> > >> the compiler to assume that a GOT entry is never needed.
> > >
> > >Is there a reason why we don't just build the whole kernel with
> > >-fvisibility=hidden today?
> >
> > This topic, loosely related to this patch, is about switching to PIC
> > compiles. I am not familiar with the Linux kernel, so I'll mostly leave
> > the discussion to you and Ard :)
> >
> > That said, I have done a lot of Clang work in visibility/symbol
> > preemptibility and linkers, so I am happy to add what I know.
> >
> > -fvisibility=hidden only applies to definitions, not non-definition
> > declarations.
> >
> > I've mentioned this at
> > https://lore.kernel.org/all/20220429070318.iwj3j5lpfkw4t7g2 at google.com/
> >
> >      `#pragma GCC visibility push(hidden)` is very similar to -fvisibility=hidden -fdirect-access-external-data with Clang.
> >      ...
> >      The kernel uses neither TLS nor -fno-plt, so -fvisibility=hidden
> >      -fdirect-access-external-data can replace `#pragma GCC visibility
> >      push(hidden)`.
> >
> > >> So building with -fPIC is currently not need in practice, and creates
> > >> some complications, which is why we have been avoiding it. But PIE
> > >> linking non-PIC objects is not guaranteed to remain supported going
> > >> forward, so it would be better to have a plan B, i.e., being able to
> > >> turn on -fpic without massive regressions due to GOT overhead, or
> > >> codegen problems with our asm hacks.
> > >
> > >Summarising all of this is it right that:
> > >
> > >1) ld -pie is how we get the reloc info into the kernel for KASLR
> > >today.
> > >
> > >2) We use gcc -fno-pic today, but this might break with ld -pie in the
> > >future, although it works for now.
> > >
> > >3) gcc -fno-pic and gcc -fPIC (or -fPIE) generate almost the same code,
> > >assuming we tweak symbol visibility and use a memory model that
> > >ADR+ADD/LDR can span.  So, moving to -fPIE is likely to be do-able.
> > >
> > >
> > >My point is that an alternative option would be to move to ld -no-pie.
>
> Why? What would that achieve?
>
> > >We would need another way to get relocs into the kernel, such as an
> > >intermediate step with ld --emit-relocs.  I have definitely seen this
> > >done before somewhere, but it would be extra work and not necessarily
> > >worth it, based on what you say about code gen.
>
> Relying on --emit-relocs is a terrible hack. It contains mostly
> relocations that we don't need at runtime, so we need to postprocess
> them. And linkers may not update these relocations in some cases after
> relaxation or other transformations (and sometimes, it is not even
> possible to do so, if the post-transformation situation cannot be
> described by a relocation).

Agreed. I've filed
https://sourceware.org/bugzilla/show_bug.cgi?id=30844
("ld riscv: --emit-relocs does not retain the original relocation
type") for a RISC-V version.

--emit-relocs is under-specified and the linker behaviors are less tested.

> And with Fangrui's RELR optimization, the PIE relocation data is
> extremely dense.
>
> There is nothing to fix here, really.
>
> > >
> > >This may all have been discussed to death already -- I didn't mean to
> > >hijack this patch, so I'll stop digging here, but if I've misunderstood,
> > >please shout!
>
> No worries. Ramana and I spent some time 5+ years ago to document how
> PIC codegen for the kernel (or any freestanding executable, really)
> deviates from the typical PIC codegen for shared libraries and PIE
> executables, with the intention of adding a GCC compiler switch for
> it, but that never really materialized, mostly because things just
> work fine today.
>


From nathan at kernel.org  Thu Feb  1 14:16:54 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Thu, 1 Feb 2024 15:16:54 -0700
Subject: [PATCH 3/3] media: mediatek: vcodedc: Fix
 Wcast-function-type-strict warnings
In-Reply-To: <20240128-fix-clang-warnings-v1-3-1d946013a421@chromium.org>
References: <20240128-fix-clang-warnings-v1-0-1d946013a421@chromium.org>
 <20240128-fix-clang-warnings-v1-3-1d946013a421@chromium.org>
Message-ID: <20240201221654.GC2240065@dev-arch.thelio-3990X>

On Sun, Jan 28, 2024 at 02:12:22AM +0000, Ricardo Ribalda wrote:
> Building with LLVM=1 throws the following warning:
> drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c:38:32: warning: cast from 'mtk_vcodec_ipi_handler' (aka 'void (*)(void *, unsigned int, void *)') to 'ipi_handler_t' (aka 'void (*)(const void *, unsigned int, void *)') converts to incompatible function type [-Wcast-function-type-strict]
> 
> Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>

I am not positive because I don't have any hardware to test this driver
but I suspect this patch is just hiding the warning without actually
addressing the issue that it is pointing out. If handler is called
through vpu_ipi_register() indirectly (which it obviously is if it is
being passed down), there will be a CFI failure because the type of
mtk_vcodec_ipi_handler is not the same as ipi_handler_t, as the comment
mentions.

Has this seen testing on real hardware with kCFI?

> ---
>  drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
> index 9f6e4b59455d..781a0359afdc 100644
> --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
> +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
> @@ -33,9 +33,11 @@ static int mtk_vcodec_vpu_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
>  	 * The handler we receive takes a void * as its first argument. We
>  	 * cannot change this because it needs to be passed down to the rproc
>  	 * subsystem when SCP is used. VPU takes a const argument, which is
> -	 * more constrained, so the conversion below is safe.
> +	 * more constrained, so the conversion below is safe. We use the void
> +	 * casting, to convince clang with -Wcast-function-type-sctrict that
> +	 * this is safe.
>  	 */
> -	ipi_handler_t handler_const = (ipi_handler_t)handler;
> +	ipi_handler_t handler_const = (ipi_handler_t)((void *)handler);
>  
>  	return vpu_ipi_register(fw->pdev, id, handler_const, name, priv);
>  }
> 
> -- 
> 2.43.0.429.g432eaa2c6b-goog
> 


From samitolvanen at google.com  Thu Feb  1 14:25:48 2024
From: samitolvanen at google.com (Sami Tolvanen)
Date: Thu, 1 Feb 2024 22:25:48 +0000
Subject: [PATCH 3/3] media: mediatek: vcodedc: Fix Wcast-function-type-strict
 warnings
In-Reply-To: <20240201221654.GC2240065@dev-arch.thelio-3990X>
References: <20240128-fix-clang-warnings-v1-0-1d946013a421@chromium.org>
 <20240128-fix-clang-warnings-v1-3-1d946013a421@chromium.org> <20240201221654.GC2240065@dev-arch.thelio-3990X>
Message-ID: <CABCJKudd3SUy3Qor7Tc0zyJsSAWy0PavbbBFALuWEpBa32pBCQ@mail.gmail.com>

On Thu, Feb 1, 2024 at 10:17?PM Nathan Chancellor <nathan at kernel.org> wrote:
>
> On Sun, Jan 28, 2024 at 02:12:22AM +0000, Ricardo Ribalda wrote:
> > Building with LLVM=1 throws the following warning:
> > drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c:38:32: warning: cast from 'mtk_vcodec_ipi_handler' (aka 'void (*)(void *, unsigned int, void *)') to 'ipi_handler_t' (aka 'void (*)(const void *, unsigned int, void *)') converts to incompatible function type [-Wcast-function-type-strict]
> >
> > Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
>
> I am not positive because I don't have any hardware to test this driver
> but I suspect this patch is just hiding the warning without actually
> addressing the issue that it is pointing out.

Agreed, this won't fix the issue. The correct solution is to drop the
cast and change the handler type to match the pointer type (i.e. use
const void* for the first argument).

Sami


From ulf.hansson at linaro.org  Thu Feb  1 14:33:09 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Thu, 1 Feb 2024 23:33:09 +0100
Subject: [PATCH 2/3] pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock
 to hdmimix domain
In-Reply-To: <20240106223951.387067-2-aford173@gmail.com>
References: <20240106223951.387067-1-aford173@gmail.com> <20240106223951.387067-2-aford173@gmail.com>
Message-ID: <CAPDyKFpx_Xo6Y5yGfuMiV8w3kR2hL6f8t31pKC=91-wEperqjA@mail.gmail.com>

On Sat, 6 Jan 2024 at 23:40, Adam Ford <aford173 at gmail.com> wrote:
>
> According to i.MX8MP RM and HDMI ADD, the fdcc clock is part of
> hdmi rx verification IP that should not enable for HDMI TX.
> But actually if the clock is disabled before HDMI/LCDIF probe,
> LCDIF will not get pixel clock from HDMI PHY and print the error
> logs:
>
> [CRTC:39:crtc-2] vblank wait timed out
> WARNING: CPU: 2 PID: 9 at drivers/gpu/drm/drm_atomic_helper.c:1634 drm_atomic_helper_wait_for_vblanks.part.0+0x23c/0x260
>
> Add fdcc clock to LCDIF and HDMI TX power domains to fix the issue.
>
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> Reviewed-by: Jacky Bai <ping.bai at nxp.com>
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Just to let you know, this looks good to me and it seems like the NXP
people like this too. What I am waiting for is an ack on the DT patch,
then I am ready to queue this up.

Kind regards
Uffe

> ---
> The original work was from Sandor on the NXP Down-stream kernel
>
> diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> index e3203eb6a022..a56f7f92d091 100644
> --- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> +++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> @@ -55,7 +55,7 @@ struct imx8mp_blk_ctrl_domain_data {
>         const char *gpc_name;
>  };
>
> -#define DOMAIN_MAX_CLKS 2
> +#define DOMAIN_MAX_CLKS 3
>  #define DOMAIN_MAX_PATHS 3
>
>  struct imx8mp_blk_ctrl_domain {
> @@ -457,8 +457,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
>         },
>         [IMX8MP_HDMIBLK_PD_LCDIF] = {
>                 .name = "hdmiblk-lcdif",
> -               .clk_names = (const char *[]){ "axi", "apb" },
> -               .num_clks = 2,
> +               .clk_names = (const char *[]){ "axi", "apb", "fdcc" },
> +               .num_clks = 3,
>                 .gpc_name = "lcdif",
>                 .path_names = (const char *[]){"lcdif-hdmi"},
>                 .num_paths = 1,
> @@ -483,8 +483,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
>         },
>         [IMX8MP_HDMIBLK_PD_HDMI_TX] = {
>                 .name = "hdmiblk-hdmi-tx",
> -               .clk_names = (const char *[]){ "apb", "ref_266m" },
> -               .num_clks = 2,
> +               .clk_names = (const char *[]){ "apb", "ref_266m", "fdcc" },
> +               .num_clks = 3,
>                 .gpc_name = "hdmi-tx",
>         },
>         [IMX8MP_HDMIBLK_PD_HDMI_TX_PHY] = {
> --
> 2.43.0
>


From robh at kernel.org  Thu Feb  1 14:36:15 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 1 Feb 2024 16:36:15 -0600
Subject: [linux][PATCH v5 0/3] Convert Microchip's HLCDC Text based DT
 bindings to JSON schema
In-Reply-To: <478cab42-5f30-4fbe-b42d-02d16b81ca11@microchip.com>
References: <20240131033523.577450-1-dharma.b@microchip.com>
 <478cab42-5f30-4fbe-b42d-02d16b81ca11@microchip.com>
Message-ID: <20240201223615.GA1726520-robh@kernel.org>

On Thu, Feb 01, 2024 at 03:38:37AM +0000, Dharma.B at microchip.com wrote:
> Hi Rob,
> 
> On 31/01/24 9:05 am, Dharma B - I70843 wrote:
> > Converted the text bindings to YAML and validated them individually using following commands
> > 
> > $ make dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/
> > $ make dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/
> > 
> > changelogs are available in respective patches.
> > 
> > As Sam suggested I'm sending the PWM binding as it is in this patch series, clean up patch
> > will be sent as separate patch.
> > 
> 
> I would want to know if I can have the examples in display and pwm 
> bindings separately or if I have to delete them from both and have a 
> single, comprehensive example in mfd binding. I'm a little puzzled about 
> this.

The strong preference is 1 complete example in the MFD binding. That 
avoids 2 copies of the same thing, issues with incomplete examples, 
and temporary warnings bisecting the series.

Rob


From mmayer at broadcom.com  Thu Feb  1 14:36:13 2024
From: mmayer at broadcom.com (Markus Mayer)
Date: Thu, 1 Feb 2024 14:36:13 -0800
Subject: [PATCH v2 3/5] dt-bindings: memory: additional compatible strings
 for Broadcom DPFE
In-Reply-To: <f46951b9-36b0-4155-b6ac-3d3f7cc8ef37@linaro.org>
References: <20240119215231.758844-1-mmayer@broadcom.com> <20240119215231.758844-4-mmayer@broadcom.com>
 <f46951b9-36b0-4155-b6ac-3d3f7cc8ef37@linaro.org>
Message-ID: <CAGt4E5taqv2kgK4ZF6R+otKwrVYiaNNkeCu5Qv7xW8cyBvv3Fw@mail.gmail.com>

On Tue, 23 Jan 2024 at 13:27, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 19/01/2024 22:52, Markus Mayer wrote:
> > Add versioned compatible strings for Broadcom DPFE. These take the form
> > brcm,dpfe-cpu-v<N> where <N> is a number from 1 to 4.
> >
> > The chip-specific strings have been kept for compatibility purposes
> > (hardware is in the field). For new chips, the properly versioned
> > compatible string should be used.
> >
> > Signed-off-by: Markus Mayer <mmayer at broadcom.com>
> > ---
> >  .../memory-controllers/brcm,dpfe-cpu.yaml     | 21 ++++++++++++++++++-
> >  1 file changed, 20 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> > index 3f00bc2fd3ec..42c8160d95d1 100644
> > --- a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> > +++ b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> > @@ -10,9 +10,28 @@ maintainers:
> >    - Krzysztof Kozlowski <krzk at kernel.org>
> >    - Markus Mayer <mmayer at broadcom.com>
> >
> > +description: |
> > +
>
> Drop blank line.

Will do.

> > +  The DCPU (DDR PHY Front End CPU) interfaces directly with the DDR PHY
> > +  chip on Broadcom STB SoCs. An API exists for other agents to retrieve
> > +  or set certain DDR PHY chip parameters by JEDEC.
> > +
> > +  Different, incompatible versions of this API have been created over
> > +  time. The API has changed for the some chips as development progressed
> > +  and features were added or changed.
> > +
> > +  We rely on the boot firmware (which already knows the API version
> > +  required) to populate Device Tree with the corresponding compatible
> > +  string.
> > +
> >  properties:
> >    compatible:
> >      items:
> > +      - enum:
> > +          - brcm,dpfe-cpu-v1
> > +          - brcm,dpfe-cpu-v2
> > +          - brcm,dpfe-cpu-v3
> > +          - brcm,dpfe-cpu-v4
>
> I don't see my comment resolved - except more unusual order of
> compatibles - and nothing in commit msg explains my previous concerns.

I am confused. What about ordering them in alphabetically ascending
order is unusual?

Which concerns, specifically, are you referencing? I promise I am not
deliberately ignoring concerns as there would be no point in doing so.
I have nothing to gain from it. I am trying to get code accepted into
the kernel. I am not trying to "win any battles" or "prove that I can
be more stubborn" or anything of that nature. If it is possible to
integrate concerns raised by the maintainer, I will gladly do so. And
if not, I'd like to find a way that works for both sides.

BTW, I once used to be on the Linaro Landing Team for Broadcom. You'll
find some commits from me in the kernel that carry a linaro.org e-mail
address. Most are from over a decade ago. Yikes, time flies!

The reason I am mentioning this is to point out that

* I am not new to this.
* I am respecting the Open Source community and so is the rest of the team.
* We are trying to do the right thing and be "good citizens".
* We upstream whatever we can to the relevant project, not just the kernel.
* We aren't on some kind of power-trip or unwilling to listen to feedback.

I am not saying this because I think any of the above makes me special
or particularly accomplished. However, I do think that some things may
need to be clarified as there does seem to be a certain attitude at
play here, with certain assumptions, that is far from constructive.
Hopefully, this has now been cleared up, and we can move forward with
addressing the outstanding concerns regarding our DPFE compatible
strings.

> I think my final comment was pretty clear yet ignored completely. There
> was no follow up:
> https://lore.kernel.org/all/3fff866f-fbe8-4d23-87f3-275380adf3d4 at linaro.org/

Unfortunately, it may not be as clear as you think. I did my best to
incorporate what I thought you meant. Clearly that didn't work out so
well.

So, please clarify in more detail, and maybe showing some examples,
what it is you would like to see. For instance, I have no idea what
"(e.g. bcm7271 + v1 + generic fallback)" is actually supposed to mean.
Is that shorthand for 3 compatible strings (brcm,bcm7271-dpfe-cpu,
brcm,dpfe-cpu-v1, brcm,dpfe-cpu). If so, how is that different from
what we already had?

> so with ignored comments: NAK

Like I said before, it is not clear to me what you are looking for.
I'll gladly address any concerns as much as possible.

Regards,
-Markus


From maskray at google.com  Thu Feb  1 14:35:45 2024
From: maskray at google.com (Fangrui Song)
Date: Thu,  1 Feb 2024 14:35:45 -0800
Subject: [PATCH] arm64: jump_label: use constraints "Si" instead of "i"
Message-ID: <20240201223545.728028-1-maskray@google.com>

The generic constraint "i" seems to be copied from x86 or arm (and with
a redundant generic operand modifier "c"). It works with -fno-PIE but
not with -fPIE/-fPIC in GCC's aarch64 port.

The machine constraint "S", which denotes a symbol or label reference
with a constant offset, supports PIC and has been available in GCC since
2012 and in Clang since 7.0. However, Clang before 19 does not support
"S" on a symbol with a constant offset [1] (e.g.
`static_key_false(&nf_hooks_needed[pf][hook])` in
include/linux/netfilter.h), so we use "i" as a fallback.

Suggested-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Fangrui Song <maskray at google.com>
Link: https://github.com/llvm/llvm-project/pull/80255 [1]

---
Changes from
arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)

* Use "Si" as Ard suggested to support Clang<19
* Make branch a separate operand
---
 arch/arm64/include/asm/jump_label.h | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
index 48ddc0f45d22..1f7d529be608 100644
--- a/arch/arm64/include/asm/jump_label.h
+++ b/arch/arm64/include/asm/jump_label.h
@@ -15,6 +15,10 @@
 
 #define JUMP_LABEL_NOP_SIZE		AARCH64_INSN_SIZE
 
+/*
+ * Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
+ * support "S" on a symbol with a constant offset, so we use "i" as a fallback.
+ */
 static __always_inline bool arch_static_branch(struct static_key * const key,
 					       const bool branch)
 {
@@ -23,9 +27,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
 		 "	.pushsection	__jump_table, \"aw\"	\n\t"
 		 "	.align		3			\n\t"
 		 "	.long		1b - ., %l[l_yes] - .	\n\t"
-		 "	.quad		%c0 - .			\n\t"
+		 "	.quad		%0 + %1 - .		\n\t"
 		 "	.popsection				\n\t"
-		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
+		 :  :  "Si"(key), "i"(branch) :  : l_yes);
 
 	return false;
 l_yes:
@@ -40,9 +44,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
 		 "	.pushsection	__jump_table, \"aw\"	\n\t"
 		 "	.align		3			\n\t"
 		 "	.long		1b - ., %l[l_yes] - .	\n\t"
-		 "	.quad		%c0 - .			\n\t"
+		 "	.quad		%0 + %1 - .		\n\t"
 		 "	.popsection				\n\t"
-		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
+		 :  :  "Si"(key), "i"(branch) :  : l_yes);
 
 	return false;
 l_yes:
-- 
2.43.0.594.gd9cf4e227d-goog



From mmayer at broadcom.com  Thu Feb  1 14:40:35 2024
From: mmayer at broadcom.com (Markus Mayer)
Date: Thu, 1 Feb 2024 14:40:35 -0800
Subject: [PATCH v2 4/5] memory: brcmstb_dpfe: introduce version-specific
 compatible strings
In-Reply-To: <bc20da6e-bf97-415b-ba78-ae29311ae38f@linaro.org>
References: <20240119215231.758844-1-mmayer@broadcom.com> <20240119215231.758844-5-mmayer@broadcom.com>
 <bc20da6e-bf97-415b-ba78-ae29311ae38f@linaro.org>
Message-ID: <CAGt4E5uE1Ms8vJbw2tE7fgcxeE9=vPYsa8y2FsJtQt-7jrjE_Q@mail.gmail.com>

On Tue, 23 Jan 2024 at 13:28, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 19/01/2024 22:52, Markus Mayer wrote:
> > Introduce compatible strings brcm,dpfe-cpu-v1 through brcm,dpfe-cpu-v3
> > to the Broadcom DPFE driver.
>
> Nothing improved here. I think my last comment was pretty clear what I
> expect.

You are correct. Nothing changed here. I did not get the impression
that you were asking for changes to the actual driver code.

As I said in my response to the previous patch, I am trying my best to
work with maintainers and other community members providing feedback.

Please explain in further detail what you are looking for. Maybe this
will already happen in conjunction with patch 3/5. Your responses
there may already answer my question here. I guess we'll find out.

Regards,
-Markus

> Best regards,
> Krzysztof


From robh at kernel.org  Thu Feb  1 14:51:39 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 1 Feb 2024 16:51:39 -0600
Subject: [PATCH v5 2/8] arm64: dts: imx8ulp: add usb nodes
In-Reply-To: <20240131114324.3722428-2-xu.yang_2@nxp.com>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-2-xu.yang_2@nxp.com>
Message-ID: <20240201225139.GA1885965-robh@kernel.org>

On Wed, Jan 31, 2024 at 07:43:18PM +0800, Xu Yang wrote:
> Add USB nodes on i.MX8ULP platform which has 2 USB controllers.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v2:
>  - no changes
> Changes in v3:
>  - no changes
> Changes in v4:
>  - no changes
> Changes in v5:
>  - no changes
> ---
>  arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 64 ++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
> index c4a0082f30d3..ead1f57e08ef 100644
> --- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
> @@ -28,6 +28,8 @@ aliases {
>  		serial1 = &lpuart5;
>  		serial2 = &lpuart6;
>  		serial3 = &lpuart7;
> +		usbphy0 = &usbphy1;
> +		usbphy1 = &usbphy2;

Drop these. We have no use for aliases to phys.

>  	};
>  
>  	cpus {
> @@ -472,6 +474,68 @@ usdhc2: mmc at 298f0000 {
>  				status = "disabled";
>  			};
>  
> +			usbotg1: usb at 29900000 {
> +				compatible = "fsl,imx8ulp-usb", "fsl,imx7ulp-usb", "fsl,imx6ul-usb";
> +				reg = <0x29900000 0x200>;
> +				interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> +				clocks = <&pcc4 IMX8ULP_CLK_USB0>;
> +				power-domains = <&scmi_devpd IMX8ULP_PD_USB0>;
> +				phys = <&usbphy1>;
> +				fsl,usbmisc = <&usbmisc1 0>;
> +				ahb-burst-config = <0x0>;
> +				tx-burst-size-dword = <0x8>;
> +				rx-burst-size-dword = <0x8>;
> +				status = "disabled";
> +			};
> +
> +			usbmisc1: usbmisc at 29900200 {
> +				compatible = "fsl,imx8ulp-usbmisc", "fsl,imx7d-usbmisc",
> +						"fsl,imx6q-usbmisc";
> +				#index-cells = <1>;

Deprecated. Why are you using this?

Rob


From robh at kernel.org  Thu Feb  1 14:58:37 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 1 Feb 2024 16:58:37 -0600
Subject: [PATCH v2 1/6] dt-bindings: display: rockchip: rockchip,dw-hdmi:
 remove port property
In-Reply-To: <a493c65e-7cf9-455f-95d5-8c98cad35710@gmail.com>
References: <a493c65e-7cf9-455f-95d5-8c98cad35710@gmail.com>
Message-ID: <170682831660.1899746.18090191904658752173.robh@kernel.org>


On Wed, 31 Jan 2024 22:14:29 +0100, Johan Jonker wrote:
> The hdmi-connector nodes are now functional and the new way to model
> hdmi ports nodes with both in and output port subnodes. Unfortunately
> with the conversion to YAML the old method with only an input port node
> was used. Later the new method was also added to the binding.
> A binding must be unambiguously, so remove the old port property
> entirely and make port at 0 and port at 1 a requirement as all
> upstream dts files are updated as well and because checking
> deprecated stuff is a bit pointless.
> Update the example to avoid use of the removed property.
> 
> Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
> ---
> 
> Changed V2:
>   rename title from deprecate to remove
>   reword
> ---
>  .../display/rockchip/rockchip,dw-hdmi.yaml    | 24 +++++++++++++++----
>  1 file changed, 20 insertions(+), 4 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From olteanv at gmail.com  Thu Feb  1 14:59:43 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Fri, 2 Feb 2024 00:59:43 +0200
Subject: [PATCH net RFC] net: dsa: mt7530: fix link-local frames that
 ingress vlan filtering ports
In-Reply-To: <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
References: <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
Message-ID: <20240201225943.abphuuavp7bkbrt6@skbuf>

On Thu, Feb 01, 2024 at 10:13:39PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> base-commit: 4e192be1a225b7b1c4e315a44754312347628859
> change-id: 20240201-b4-for-net-mt7530-fix-link-local-that-ingress-vlan-filtering-ports-6a2099e7ffb3
> 
> Best regards,
> -- 
> Ar?n? ?NAL <arinc.unal at arinc9.com>

You sent this patch 3 times. What happened, b4 didn't work so well?


From robh at kernel.org  Thu Feb  1 15:03:51 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 1 Feb 2024 17:03:51 -0600
Subject: [PATCH 02/12] dt-bindings: arm: keystone: ti-sci: Add
 reboot-controller child node
In-Reply-To: <20240131221957.213717-3-afd@ti.com>
References: <20240131221957.213717-1-afd@ti.com>
 <20240131221957.213717-3-afd@ti.com>
Message-ID: <20240201230351.GA1900918-robh@kernel.org>

On Wed, Jan 31, 2024 at 04:19:47PM -0600, Andrew Davis wrote:
> The TI-SCI firmware supports rebooting the system in addition to the
> functions already listed here, document child node for the same.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  .../devicetree/bindings/arm/keystone/ti,sci.yaml          | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml b/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
> index c24ad0968f3ef..e392175b33c74 100644
> --- a/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
> +++ b/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
> @@ -83,6 +83,10 @@ properties:
>      type: object
>      $ref: /schemas/reset/ti,sci-reset.yaml#
>  
> +  reboot-controller:
> +    type: object
> +    $ref: /schemas/power/reset/ti,sci-reboot.yaml#

Don't need a ref just for a single property.

But then why do we need a node here at all? Can't you assume reboot 
support for TI-SCI firmware (i.e. based on the parent node). Then you 
don't need a DT update to add the feature.

Rob


From miguel.ojeda.sandonis at gmail.com  Thu Feb  1 15:12:05 2024
From: miguel.ojeda.sandonis at gmail.com (Miguel Ojeda)
Date: Fri, 2 Feb 2024 00:12:05 +0100
Subject: [PATCH v2 3/3] net: phy: add Rust Rockchip PHY driver
In-Reply-To: <6725eeac-45ee-4f3f-a612-0ef5725b9fd9@lunn.ch>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
 <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>
 <2024020105-bankroll-opium-a6e5@gregkh> <6725eeac-45ee-4f3f-a612-0ef5725b9fd9@lunn.ch>
Message-ID: <CANiq72nnHj2PnsM-=RREOcq1wsyydFZQ67-DewDa18=tAHe4NA@mail.gmail.com>

On Thu, Feb 1, 2024 at 10:30?PM Andrew Lunn <andrew at lunn.ch> wrote:
>
> As one of the PHY Maintainers, i would say no.
>
> Now we have an example, i think we should be a lot more strict about
> what we actually merge. It should be a driver for hardware which does
> not have a C driver.

Yeah, a single "Rust reference driver" is likely enough to give a good
example of how things would look.

I guess more than one could be justified if there are significant
differences, e.g. if the maintainers want to cover more of the
abstractions API for some reason.

> We cannot drop C drivers since Rust at the moment does not support all
> architectures GCC/Clang does. PHY drivers are architecture
> independent, and in real life used on multiple architectures. When
> Rust eventually catches up, we could consider dropping C drivers when
> there is an equivalent Rust driver, but from what i hear, that is a
> few years away. I don't want to be supporting a C and Rust driver for
> the same hardware.

The `rustc_codegen_gcc` backend can already build the kernel without
changes, so hopefully we will see some results sooner than that. If we
are talking multiple years, GCC Rust likely enters the equation too.

But, indeed, there is a lot of work to do until we can drop C code in general.

Cheers,
Miguel


From olteanv at gmail.com  Thu Feb  1 15:26:19 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Fri, 2 Feb 2024 01:26:19 +0200
Subject: [PATCH net RFC] net: dsa: mt7530: fix link-local frames that
 ingress vlan filtering ports
In-Reply-To: <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
 <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
References: <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
 <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
Message-ID: <20240201232619.nsmm7lvafuem2gou@skbuf>

On Thu, Feb 01, 2024 at 10:13:39PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> One remaining limitation is that the ingress port must have a PVID assigned
> to it for the frame to be trapped to the CPU port. A PVID is set by default
> on vlan aware and vlan unaware ports. However, when the network interface
> that pertains to the ingress port is attached to a vlan_filtering enabled
> bridge, the user can remove the PVID assignment from it which would prevent
> the link-local frames from being trapped to the CPU port.
> 
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> ---
> I couldn't figure out a way to bypass VLAN table lookup for link-local
> frames to directly trap them to the CPU port. The CPU port is hardcoded for
> MT7530. For MT7531 and the switch on the MT7988 SoC, it depends on the port
> matrix to choose the CPU port to trap the frames to. Port matrix and VLAN
> table seem to go hand in hand so I don't know if this would even be
> possible.
> 
> If possible to implement, link-local frames must not be influenced by the
> VLAN table. They must always be trapped to the CPU port, and trapped
> untagged.

Isn't this, in effect, what the "Leaky VLAN Enable" bit does?


From afd at ti.com  Thu Feb  1 15:50:00 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 1 Feb 2024 17:50:00 -0600
Subject: [PATCH 02/12] dt-bindings: arm: keystone: ti-sci: Add
 reboot-controller child node
In-Reply-To: <20240201230351.GA1900918-robh@kernel.org>
References: <20240131221957.213717-1-afd@ti.com>
 <20240131221957.213717-3-afd@ti.com>
 <20240201230351.GA1900918-robh@kernel.org>
Message-ID: <6ba87a3f-e2f4-4caf-8d23-aa78caaba45a@ti.com>

On 2/1/24 5:03 PM, Rob Herring wrote:
> On Wed, Jan 31, 2024 at 04:19:47PM -0600, Andrew Davis wrote:
>> The TI-SCI firmware supports rebooting the system in addition to the
>> functions already listed here, document child node for the same.
>>
>> Signed-off-by: Andrew Davis <afd at ti.com>
>> ---
>>   .../devicetree/bindings/arm/keystone/ti,sci.yaml          | 8 ++++++++
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml b/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
>> index c24ad0968f3ef..e392175b33c74 100644
>> --- a/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
>> +++ b/Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
>> @@ -83,6 +83,10 @@ properties:
>>       type: object
>>       $ref: /schemas/reset/ti,sci-reset.yaml#
>>   
>> +  reboot-controller:
>> +    type: object
>> +    $ref: /schemas/power/reset/ti,sci-reboot.yaml#
> 
> Don't need a ref just for a single property.
> 
> But then why do we need a node here at all? Can't you assume reboot
> support for TI-SCI firmware (i.e. based on the parent node). Then you
> don't need a DT update to add the feature.
> 

We could yes, but then again we could do the same for all the
child nodes of this system-controller parent node. Might even
have been better that way, for now I'm trying to be consistent
with what is already here (child node per service provided,
even though the services are always the same).

Andrew

> Rob


From Dharma.B at microchip.com  Thu Feb  1 15:52:53 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Thu, 1 Feb 2024 23:52:53 +0000
Subject: [linux][PATCH v5 0/3] Convert Microchip's HLCDC Text based DT
 bindings to JSON schema
In-Reply-To: <20240201223615.GA1726520-robh@kernel.org>
References: <20240131033523.577450-1-dharma.b@microchip.com>
 <478cab42-5f30-4fbe-b42d-02d16b81ca11@microchip.com>
 <20240201223615.GA1726520-robh@kernel.org>
Message-ID: <912f1b87-e266-47dc-99bd-a32d303e70ce@microchip.com>

On 02/02/24 4:06 am, Rob Herring wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Thu, Feb 01, 2024 at 03:38:37AM +0000, Dharma.B at microchip.com wrote:
>> Hi Rob,
>>
>> On 31/01/24 9:05 am, Dharma B - I70843 wrote:
>>> Converted the text bindings to YAML and validated them individually using following commands
>>>
>>> $ make dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/
>>> $ make dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/
>>>
>>> changelogs are available in respective patches.
>>>
>>> As Sam suggested I'm sending the PWM binding as it is in this patch series, clean up patch
>>> will be sent as separate patch.
>>>
>>
>> I would want to know if I can have the examples in display and pwm
>> bindings separately or if I have to delete them from both and have a
>> single, comprehensive example in mfd binding. I'm a little puzzled about
>> this.
> 
> The strong preference is 1 complete example in the MFD binding. That
> avoids 2 copies of the same thing, issues with incomplete examples,
> and temporary warnings bisecting the series.

Sure, I will drop the examples in display and pwm bindings while sending v6.

-- 
Thanks,
Dharma B.

> 
> Rob



From olteanv at gmail.com  Thu Feb  1 15:57:04 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Fri, 2 Feb 2024 01:57:04 +0200
Subject: [PATCH net-next v2 5/7] net: dsa: mt7530: simplify
 mt7530_setup_port6() and change to void
In-Reply-To: <77c38489-8a73-4b00-bd82-48174b4d620f@arinc9.com>
References: <20240130-for-netnext-mt7530-improvements-2-v2-0-ba06f5dd9eb0@arinc9.com>
 <20240130-for-netnext-mt7530-improvements-2-v2-5-ba06f5dd9eb0@arinc9.com>
 <Zbkc4BRORWYu79GZ@makrotopia.org>
 <77c38489-8a73-4b00-bd82-48174b4d620f@arinc9.com>
Message-ID: <20240201235704.6wxbkpli3dk4pn4w@skbuf>

On Tue, Jan 30, 2024 at 08:46:04PM +0300, Ar?n? ?NAL wrote:
> would supposedly achieve 2 Gbps TX & 2 Gbps RX

Source? Commit 8efaa653a8a5 ("net: ethernet: mediatek: Add MT7621 TRGMII
mode support") says "TRGMII speed is 1200MBit.".

> Unless the MediaTek SoC ethernet driver somehow caps TRGMII to 1 Gbps,
> I consider this whole TRGMII shenanigans a scam

I laughed :)

You have to see whether the CPU isn't in fact at 100% already, becoming
a bottleneck before the interface speed does.

Also, mtk_eth_soc.c has an interesting comment "TRGMII is not permitted
on MT7621 if using DDR2" - not sure if applicable to your setup or not.

I just got myself an ASUS RT-AX1800U (uses the mt7621_asus_rt-ax53u.dts
device tree AFAICT) which I'll be setting up with OpenWrt in the weeks
to come, and on which I might also be able to run some tests from time
to time.


From andersson at kernel.org  Thu Feb  1 16:03:12 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Thu, 1 Feb 2024 18:03:12 -0600
Subject: [PATCH 4/9] PCI: create platform devices for child OF
 nodes of the port node
In-Reply-To: <CAMRc=MeXJjpJhDjyn_P-SGo4rDnEuT9kGN5jAbRcuM_c7_aDzQ@mail.gmail.com>
References: <20240117160748.37682-1-brgl@bgdev.pl>
 <20240117160748.37682-5-brgl@bgdev.pl>
 <2024011707-alibi-pregnancy-a64b@gregkh>
 <CAMRc=Mef7wxRccnfQ=EDLckpb1YN4DNLoC=AYL8v1LLJ=uFH2Q@mail.gmail.com>
 <2024011836-wok-treadmill-c517@gregkh>
 <d2he3ufg6m46zos4swww4t3peyq55blxhirsx37ou37rwqxmz2@5khumvic62je>
 <CAMRc=MeXJjpJhDjyn_P-SGo4rDnEuT9kGN5jAbRcuM_c7_aDzQ@mail.gmail.com>
Message-ID: <oiwvcvu6wdmpvhss3t7uaqkl5q73mki5pz6liuv66bap4dr2mp@jtjjwzlvt6za>

On Wed, Jan 31, 2024 at 12:04:14PM +0100, Bartosz Golaszewski wrote:
> On Tue, Jan 30, 2024 at 10:54?PM Bjorn Andersson <andersson at kernel.org> wrote:
> >
> > On Thu, Jan 18, 2024 at 12:15:27PM +0100, Greg Kroah-Hartman wrote:
> > > On Thu, Jan 18, 2024 at 11:58:50AM +0100, Bartosz Golaszewski wrote:
> > > > On Wed, Jan 17, 2024 at 5:45?PM Greg Kroah-Hartman
> > > > <gregkh at linuxfoundation.org> wrote:
> > > > >
> > > > > On Wed, Jan 17, 2024 at 05:07:43PM +0100, Bartosz Golaszewski wrote:
> > > > > > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > > > > >
> > > > > > In order to introduce PCI power-sequencing, we need to create platform
> > > > > > devices for child nodes of the port node.
> > > > >
> > > > > Ick, why a platform device?  What is the parent of this device, a PCI
> > > > > device?  If so, then this can't be a platform device, as that's not what
> > > > > it is, it's something else so make it a device of that type,.
> > > > >
> > > >
> > > > Greg,
> > > >
> > > > This is literally what we agreed on at LPC. In fact: during one of the
> > > > hall track discussions I said that you typically NAK any attempts at
> > > > using the platform bus for "fake" devices but you responded that this
> > > > is what the USB on-board HUB does and while it's not pretty, this is
> > > > what we need to do.
> > >
> > > Ah, you need to remind me of these things, this changelog was pretty
> > > sparse :)
> > >
> >
> > I believe I missed this part of the discussion, why does this need to be
> > a platform_device? What does the platform_bus bring that can't be
> > provided by some other bus?
> >
> 
> Does it need to be a platform_device? No, of course not. Does it make
> sense for it to be one? Yes, for two reasons:
> 
> 1. The ATH11K WLAN module is represented on the device tree like a
> platform device, we know it's always there and it consumes regulators
> from another platform device. The fact it uses PCIe doesn't change the
> fact that it is logically a platform device.

Are you referring to the ath11k SNOC (firmware running on co-processor
in the SoC) variant?

Afaict the PCIe-attached ath11k is not represented as a platform_device
in DeviceTree.

Said platform_device is also not a child under the PCIe bus, so this
would be a different platform_device...

> 2. The platform bus already provides us with the entire infrastructure
> that we'd now need to duplicate (possibly adding bugs) in order to
> introduce a "power sequencing bus".
> 

This is a perfectly reasonable desire. Look at our PMICs, they are full
of platform_devices. But through the years it's been said many times,
that this is not a valid or good reason for using platform_devices, and
as a result we have e.g. auxiliary bus.

Anyway, (please) don't claim that "we need to", when it actually is "we
want to use platform_device because that's more convenient"!

Regards,
Bjorn

> Bart
> 
> > (I'm not questioning the need for having a bus, creating devices, and
> > matching/binding them to a set of drivers)
> >
> > Regards,
> > Bjorn
> >
> 
> [snip]


From olteanv at gmail.com  Thu Feb  1 16:05:28 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Fri, 2 Feb 2024 02:05:28 +0200
Subject: [PATCH net-next v2 6/7] net: dsa: mt7530: correct port
 capabilities of MT7988
In-Reply-To: <20240130-for-netnext-mt7530-improvements-2-v2-6-ba06f5dd9eb0@arinc9.com>
 <20240130-for-netnext-mt7530-improvements-2-v2-6-ba06f5dd9eb0@arinc9.com>
References: <20240130-for-netnext-mt7530-improvements-2-v2-0-ba06f5dd9eb0@arinc9.com>
 <20240130-for-netnext-mt7530-improvements-2-v2-0-ba06f5dd9eb0@arinc9.com>
 <20240130-for-netnext-mt7530-improvements-2-v2-6-ba06f5dd9eb0@arinc9.com>
 <20240130-for-netnext-mt7530-improvements-2-v2-6-ba06f5dd9eb0@arinc9.com>
Message-ID: <20240202000528.efgly2bpfhqxu332@skbuf>

On Tue, Jan 30, 2024 at 06:20:52PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> On the switch on the MT7988 SoC, as shown in Block Diagram 8.1.1.3 on page
> 125 of "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open
> Version) v0.1", there are only 4 PHYs. That's port 0 to 3. Set the case for
> ports which connect to switch PHYs to '0 ... 3'.
> 
> Port 4 and 5 are not used at all in this design.
> 
> Link: https://wiki.banana-pi.org/Banana_Pi_BPI-R4#Documents [1]
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> Acked-by: Daniel Golle <daniel at makrotopia.org>
> ---

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From aford173 at gmail.com  Thu Feb  1 16:17:43 2024
From: aford173 at gmail.com (Adam Ford)
Date: Thu, 1 Feb 2024 18:17:43 -0600
Subject: [PATCH 2/3] pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock
 to hdmimix domain
In-Reply-To: <CAPDyKFpx_Xo6Y5yGfuMiV8w3kR2hL6f8t31pKC=91-wEperqjA@mail.gmail.com>
References: <20240106223951.387067-1-aford173@gmail.com> <20240106223951.387067-2-aford173@gmail.com>
 <CAPDyKFpx_Xo6Y5yGfuMiV8w3kR2hL6f8t31pKC=91-wEperqjA@mail.gmail.com>
Message-ID: <CAHCN7xLqKTAcVpsBYXmzdvSefOnXdXzzrGie7mxkzeJLFKu+Rw@mail.gmail.com>

On Thu, Feb 1, 2024 at 4:33?PM Ulf Hansson <ulf.hansson at linaro.org> wrote:
>
> On Sat, 6 Jan 2024 at 23:40, Adam Ford <aford173 at gmail.com> wrote:
> >
> > According to i.MX8MP RM and HDMI ADD, the fdcc clock is part of
> > hdmi rx verification IP that should not enable for HDMI TX.
> > But actually if the clock is disabled before HDMI/LCDIF probe,
> > LCDIF will not get pixel clock from HDMI PHY and print the error
> > logs:
> >
> > [CRTC:39:crtc-2] vblank wait timed out
> > WARNING: CPU: 2 PID: 9 at drivers/gpu/drm/drm_atomic_helper.c:1634 drm_atomic_helper_wait_for_vblanks.part.0+0x23c/0x260
> >
> > Add fdcc clock to LCDIF and HDMI TX power domains to fix the issue.
> >
> > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > Reviewed-by: Jacky Bai <ping.bai at nxp.com>
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
>
> Just to let you know, this looks good to me and it seems like the NXP
> people like this too. What I am waiting for is an ack on the DT patch,
> then I am ready to queue this up.

What about the bindings?  I'm assuming that Shawn would take the DT
through his IMX tree, but I am not sure if I need to resubmit the
bindings with a different commit message.

adam
>
> Kind regards
> Uffe
>
> > ---
> > The original work was from Sandor on the NXP Down-stream kernel
> >
> > diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> > index e3203eb6a022..a56f7f92d091 100644
> > --- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> > +++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
> > @@ -55,7 +55,7 @@ struct imx8mp_blk_ctrl_domain_data {
> >         const char *gpc_name;
> >  };
> >
> > -#define DOMAIN_MAX_CLKS 2
> > +#define DOMAIN_MAX_CLKS 3
> >  #define DOMAIN_MAX_PATHS 3
> >
> >  struct imx8mp_blk_ctrl_domain {
> > @@ -457,8 +457,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
> >         },
> >         [IMX8MP_HDMIBLK_PD_LCDIF] = {
> >                 .name = "hdmiblk-lcdif",
> > -               .clk_names = (const char *[]){ "axi", "apb" },
> > -               .num_clks = 2,
> > +               .clk_names = (const char *[]){ "axi", "apb", "fdcc" },
> > +               .num_clks = 3,
> >                 .gpc_name = "lcdif",
> >                 .path_names = (const char *[]){"lcdif-hdmi"},
> >                 .num_paths = 1,
> > @@ -483,8 +483,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
> >         },
> >         [IMX8MP_HDMIBLK_PD_HDMI_TX] = {
> >                 .name = "hdmiblk-hdmi-tx",
> > -               .clk_names = (const char *[]){ "apb", "ref_266m" },
> > -               .num_clks = 2,
> > +               .clk_names = (const char *[]){ "apb", "ref_266m", "fdcc" },
> > +               .num_clks = 3,
> >                 .gpc_name = "hdmi-tx",
> >         },
> >         [IMX8MP_HDMIBLK_PD_HDMI_TX_PHY] = {
> > --
> > 2.43.0
> >


From dharma.b at microchip.com  Thu Feb  1 16:17:30 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 2 Feb 2024 05:47:30 +0530
Subject: [linux][PATCH v6 0/3] Convert Microchip's HLCDC Text based DT bindings to JSON schema
Message-ID: <20240202001733.91455-1-dharma.b@microchip.com>

Converted the text bindings to YAML and validated them individually using following commands

$ make dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/
$ make dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/

changelogs are available in respective patches.

Dharma Balasubiramani (3):
  dt-bindings: display: convert Atmel's HLCDC to DT schema
  dt-bindings: atmel,hlcdc: convert pwm bindings to json-schema
  dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format

 .../atmel/atmel,hlcdc-display-controller.yaml | 63 ++++++++++++
 .../bindings/display/atmel/hlcdc-dc.txt       | 75 --------------
 .../devicetree/bindings/mfd/atmel,hlcdc.yaml  | 99 +++++++++++++++++++
 .../devicetree/bindings/mfd/atmel-hlcdc.txt   | 56 -----------
 .../bindings/pwm/atmel,hlcdc-pwm.yaml         | 35 +++++++
 .../bindings/pwm/atmel-hlcdc-pwm.txt          | 29 ------
 6 files changed, 197 insertions(+), 160 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/atmel/atmel,hlcdc-display-controller.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml
 delete mode 100644 Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml
 delete mode 100644 Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt

-- 
2.25.1



From dharma.b at microchip.com  Thu Feb  1 16:17:31 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 2 Feb 2024 05:47:31 +0530
Subject: [linux][PATCH v6 1/3] dt-bindings: display: convert Atmel's HLCDC to DT schema
In-Reply-To: <20240202001733.91455-1-dharma.b@microchip.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
Message-ID: <20240202001733.91455-2-dharma.b@microchip.com>

Convert the existing DT binding to DT schema of the Atmel's HLCDC display
controller.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
Changelog
v5 -> v6
- Drop example as we have one complete example in mfd binding.
v4 -> v5
- No change.
v3 -> v4
- Add bus-width property to have one complete example.
v2 -> v3
- Remove '|' in description, as there is no formatting to preserve.
- Ref video-interfaces as endpoint.
- Remove ref and description for bus-width.
- Add new line before the child node in example.
- Remove 'example 2', as it is not required for just one additional property.
v1 -> v2
- Remove the explicit copyrights.
- Modify filename like compatible.
- Modify title (drop words like binding/driver).
- Modify description actually describing the hardware and not the driver.
- Remove pinctrl properties which aren't required.
- Ref endpoint and not endpoint-base.
- Drop redundant info about bus-width description and add ref to video-interfaces.
- Move 'additionalProperties' after 'Required'.
- Drop parent node and it's other sub-device node which are not related here.
- Add compatible to example 2 and add comments that bus-width is the diff between two examples.
---
 .../atmel/atmel,hlcdc-display-controller.yaml | 63 ++++++++++++++++
 .../bindings/display/atmel/hlcdc-dc.txt       | 75 -------------------
 2 files changed, 63 insertions(+), 75 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/atmel/atmel,hlcdc-display-controller.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt

diff --git a/Documentation/devicetree/bindings/display/atmel/atmel,hlcdc-display-controller.yaml b/Documentation/devicetree/bindings/display/atmel/atmel,hlcdc-display-controller.yaml
new file mode 100644
index 000000000000..29ed42485de3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/atmel/atmel,hlcdc-display-controller.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/atmel/atmel,hlcdc-display-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel's High LCD Controller (HLCDC)
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Alexandre Belloni <alexandre.belloni at bootlin.com>
+  - Claudiu Beznea <claudiu.beznea at tuxon.dev>
+
+description:
+  The LCD Controller (LCDC) consists of logic for transferring LCD image
+  data from an external display buffer to a TFT LCD panel. The LCDC has one
+  display input buffer per layer that fetches pixels through the single bus
+  host interface and a look-up table to allow palletized display
+  configurations.
+
+properties:
+  compatible:
+    const: atmel,hlcdc-display-controller
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+  port at 0:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    unevaluatedProperties: false
+    description:
+      Output endpoint of the controller, connecting the LCD panel signals.
+
+    properties:
+      '#address-cells':
+        const: 1
+
+      '#size-cells':
+        const: 0
+
+      reg:
+        maxItems: 1
+
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+        description:
+          Endpoint connecting the LCD panel signals.
+
+        properties:
+          bus-width:
+            enum: [ 12, 16, 18, 24 ]
+
+required:
+  - '#address-cells'
+  - '#size-cells'
+  - compatible
+  - port at 0
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt b/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt
deleted file mode 100644
index 923aea25344c..000000000000
--- a/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-Device-Tree bindings for Atmel's HLCDC (High LCD Controller) DRM driver
-
-The Atmel HLCDC Display Controller is subdevice of the HLCDC MFD device.
-See ../../mfd/atmel-hlcdc.txt for more details.
-
-Required properties:
- - compatible: value should be "atmel,hlcdc-display-controller"
- - pinctrl-names: the pin control state names. Should contain "default".
- - pinctrl-0: should contain the default pinctrl states.
- - #address-cells: should be set to 1.
- - #size-cells: should be set to 0.
-
-Required children nodes:
- Children nodes are encoding available output ports and their connections
- to external devices using the OF graph representation (see ../graph.txt).
- At least one port node is required.
-
-Optional properties in grandchild nodes:
- Any endpoint grandchild node may specify a desired video interface
- according to ../../media/video-interfaces.txt, specifically
- - bus-width: recognized values are <12>, <16>, <18> and <24>, and
-   override any output mode selection heuristic, forcing "rgb444",
-   "rgb565", "rgb666" and "rgb888" respectively.
-
-Example:
-
-	hlcdc: hlcdc at f0030000 {
-		compatible = "atmel,sama5d3-hlcdc";
-		reg = <0xf0030000 0x2000>;
-		interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>;
-		clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>;
-		clock-names = "periph_clk","sys_clk", "slow_clk";
-
-		hlcdc-display-controller {
-			compatible = "atmel,hlcdc-display-controller";
-			pinctrl-names = "default";
-			pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 0 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				reg = <0>;
-
-				hlcdc_panel_output: endpoint at 0 {
-					reg = <0>;
-					remote-endpoint = <&panel_input>;
-				};
-			};
-		};
-
-		hlcdc_pwm: hlcdc-pwm {
-			compatible = "atmel,hlcdc-pwm";
-			pinctrl-names = "default";
-			pinctrl-0 = <&pinctrl_lcd_pwm>;
-			#pwm-cells = <3>;
-		};
-	};
-
-Example 2: With a video interface override to force rgb565; as above
-but with these changes/additions:
-
-	&hlcdc {
-		hlcdc-display-controller {
-			pinctrl-names = "default";
-			pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb565>;
-
-			port at 0 {
-				hlcdc_panel_output: endpoint at 0 {
-					bus-width = <16>;
-				};
-			};
-		};
-	};
-- 
2.25.1



From dharma.b at microchip.com  Thu Feb  1 16:17:32 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 2 Feb 2024 05:47:32 +0530
Subject: [linux][PATCH v6 2/3] dt-bindings: atmel,hlcdc: convert pwm bindings to json-schema
In-Reply-To: <20240202001733.91455-1-dharma.b@microchip.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
Message-ID: <20240202001733.91455-3-dharma.b@microchip.com>

Convert device tree bindings for Atmel's HLCDC PWM controller to YAML
format.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
Changelog
v5 -> v6
- Drop the example as we have one complete example in mfd binding.
v4 -> v5
v3 -> v4
- No changes
Note: The clean up patch will be sent later as Sam suggested.
v2 -> v3
- Remove '|' in description, as there is no formatting to preserve.
- Delete the description for pwm-cells.
- Drop the label for pwm node as it not used.
v1 -> v2
- Remove the explicit copyrights.
- Modify title (not include words like binding/driver).
- Modify description actually describing the hardware and not the driver.
- Remove pinctrl properties which aren't required.
- Drop parent node and it's other sub-device node which are not related here.
---
 .../bindings/pwm/atmel,hlcdc-pwm.yaml         | 35 +++++++++++++++++++
 .../bindings/pwm/atmel-hlcdc-pwm.txt          | 29 ---------------
 2 files changed, 35 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml
 delete mode 100644 Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt

diff --git a/Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml b/Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml
new file mode 100644
index 000000000000..0e92868a2b68
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/atmel,hlcdc-pwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel's HLCDC's PWM controller
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Alexandre Belloni <alexandre.belloni at bootlin.com>
+  - Claudiu Beznea <claudiu.beznea at tuxon.dev>
+
+description:
+  The LCDC integrates a Pulse Width Modulation (PWM) Controller. This block
+  generates the LCD contrast control signal (LCD_PWM) that controls the
+  display's contrast by software. LCDC_PWM is an 8-bit PWM signal that can be
+  converted to an analog voltage with a simple passive filter. LCD display
+  panels have different backlight specifications in terms of minimum/maximum
+  values for PWM frequency. If the LCDC PWM frequency range does not match the
+  LCD display panel, it is possible to use the standalone PWM Controller to
+  drive the backlight.
+
+properties:
+  compatible:
+    const: atmel,hlcdc-pwm
+
+  "#pwm-cells":
+    const: 3
+
+required:
+  - compatible
+  - "#pwm-cells"
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt b/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt
deleted file mode 100644
index afa501bf7f94..000000000000
--- a/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Device-Tree bindings for Atmel's HLCDC (High-end LCD Controller) PWM driver
-
-The Atmel HLCDC PWM is subdevice of the HLCDC MFD device.
-See ../mfd/atmel-hlcdc.txt for more details.
-
-Required properties:
- - compatible: value should be one of the following:
-   "atmel,hlcdc-pwm"
- - pinctr-names: the pin control state names. Should contain "default".
- - pinctrl-0: should contain the pinctrl states described by pinctrl
-   default.
- - #pwm-cells: should be set to 3. This PWM chip use the default 3 cells
-   bindings defined in pwm.yaml in this directory.
-
-Example:
-
-	hlcdc: hlcdc at f0030000 {
-		compatible = "atmel,sama5d3-hlcdc";
-		reg = <0xf0030000 0x2000>;
-		clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>;
-		clock-names = "periph_clk","sys_clk", "slow_clk";
-
-		hlcdc_pwm: hlcdc-pwm {
-			compatible = "atmel,hlcdc-pwm";
-			pinctrl-names = "default";
-			pinctrl-0 = <&pinctrl_lcd_pwm>;
-			#pwm-cells = <3>;
-		};
-	};
-- 
2.25.1



From dharma.b at microchip.com  Thu Feb  1 16:17:33 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 2 Feb 2024 05:47:33 +0530
Subject: [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
In-Reply-To: <20240202001733.91455-1-dharma.b@microchip.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
Message-ID: <20240202001733.91455-4-dharma.b@microchip.com>

Convert the atmel,hlcdc binding to DT schema format.

Align clocks and clock-names properties to clearly indicate that the LCD
controller expects lvds_pll_clk when interfaced with the lvds display. This
alignment with the specific hardware requirements ensures accurate device tree
configuration for systems utilizing the HLCDC IP.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
Changelog
v5 -> v6
- No changes.
v4 -> v5
- Revert v3 dropping lvds_pll_clk instead add it as an optional clock.
- Update minItems to 3.
- Update commit message accordingly.
v3 -> v4
- Drop lvds_pll_clk, It can be enabled in lvds driver itself.
- Update commit message.
Note: Since there is no complexities now, I believe that specifying
maxitems in the clocks property should be sufficient.
v2 -> v3
- Rename hlcdc-display-controller and hlcdc-pwm to generic names.
- Modify the description by removing the unwanted comments and '|'.
- Modify clock-names simpler.
v1 -> v2
- Remove the explicit copyrights.
- Modify title (not include words like binding/driver).
- Modify description actually describing the hardware and not the driver.
- Add details of lvds_pll addition in commit message.
- Ref endpoint and not endpoint-base.
- Fix coding style.
...
 .../devicetree/bindings/mfd/atmel,hlcdc.yaml  | 99 +++++++++++++++++++
 .../devicetree/bindings/mfd/atmel-hlcdc.txt   | 56 -----------
 2 files changed, 99 insertions(+), 56 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml
 delete mode 100644 Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt

diff --git a/Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml b/Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml
new file mode 100644
index 000000000000..4aa36903e755
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/atmel,hlcdc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel's HLCD Controller
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Alexandre Belloni <alexandre.belloni at bootlin.com>
+  - Claudiu Beznea <claudiu.beznea at tuxon.dev>
+
+description:
+  The Atmel HLCDC (HLCD Controller) IP available on Atmel SoCs exposes two
+  subdevices, a PWM chip and a Display Controller.
+
+properties:
+  compatible:
+    enum:
+      - atmel,at91sam9n12-hlcdc
+      - atmel,at91sam9x5-hlcdc
+      - atmel,sama5d2-hlcdc
+      - atmel,sama5d3-hlcdc
+      - atmel,sama5d4-hlcdc
+      - microchip,sam9x60-hlcdc
+      - microchip,sam9x75-xlcdc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 3
+
+  clock-names:
+    items:
+      - const: periph_clk
+      - const: sys_clk
+      - const: slow_clk
+      - const: lvds_pll_clk
+    minItems: 3
+
+  display-controller:
+    $ref: /schemas/display/atmel/atmel,hlcdc-display-controller.yaml
+
+  pwm:
+    $ref: /schemas/pwm/atmel,hlcdc-pwm.yaml
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/at91.h>
+    #include <dt-bindings/dma/at91.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    lcd_controller: lcd-controller at f0030000 {
+      compatible = "atmel,sama5d3-hlcdc";
+      reg = <0xf0030000 0x2000>;
+      clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>;
+      clock-names = "periph_clk", "sys_clk", "slow_clk";
+      interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>;
+
+      display-controller {
+        compatible = "atmel,hlcdc-display-controller";
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        port at 0 {
+          #address-cells = <1>;
+          #size-cells = <0>;
+          reg = <0>;
+
+          hlcdc_panel_output: endpoint at 0 {
+            reg = <0>;
+            remote-endpoint = <&panel_input>;
+          };
+        };
+      };
+
+      pwm {
+        compatible = "atmel,hlcdc-pwm";
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_lcd_pwm>;
+        #pwm-cells = <3>;
+      };
+    };
diff --git a/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt b/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt
deleted file mode 100644
index 7de696eefaed..000000000000
--- a/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-Device-Tree bindings for Atmel's HLCDC (High LCD Controller) MFD driver
-
-Required properties:
- - compatible: value should be one of the following:
-   "atmel,at91sam9n12-hlcdc"
-   "atmel,at91sam9x5-hlcdc"
-   "atmel,sama5d2-hlcdc"
-   "atmel,sama5d3-hlcdc"
-   "atmel,sama5d4-hlcdc"
-   "microchip,sam9x60-hlcdc"
-   "microchip,sam9x75-xlcdc"
- - reg: base address and size of the HLCDC device registers.
- - clock-names: the name of the 3 clocks requested by the HLCDC device.
-   Should contain "periph_clk", "sys_clk" and "slow_clk".
- - clocks: should contain the 3 clocks requested by the HLCDC device.
- - interrupts: should contain the description of the HLCDC interrupt line
-
-The HLCDC IP exposes two subdevices:
- - a PWM chip: see ../pwm/atmel-hlcdc-pwm.txt
- - a Display Controller: see ../display/atmel/hlcdc-dc.txt
-
-Example:
-
-	hlcdc: hlcdc at f0030000 {
-		compatible = "atmel,sama5d3-hlcdc";
-		reg = <0xf0030000 0x2000>;
-		clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>;
-		clock-names = "periph_clk","sys_clk", "slow_clk";
-		interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>;
-
-		hlcdc-display-controller {
-			compatible = "atmel,hlcdc-display-controller";
-			pinctrl-names = "default";
-			pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 0 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				reg = <0>;
-
-				hlcdc_panel_output: endpoint at 0 {
-					reg = <0>;
-					remote-endpoint = <&panel_input>;
-				};
-			};
-		};
-
-		hlcdc_pwm: hlcdc-pwm {
-			compatible = "atmel,hlcdc-pwm";
-			pinctrl-names = "default";
-			pinctrl-0 = <&pinctrl_lcd_pwm>;
-			#pwm-cells = <3>;
-		};
-	};
-- 
2.25.1



From semen.protsenko at linaro.org  Thu Feb  1 17:05:07 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu,  1 Feb 2024 19:05:07 -0600
Subject: [PATCH] tty: serial: samsung: Remove superfluous braces in macro
Message-ID: <20240202010507.22638-1-semen.protsenko@linaro.org>

Commit 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
removes parameters from EXYNOS_COMMON_SERIAL_DRV_DATA() macro, but
leaves unnecessary empty braces. Remove those to fix the style. No
functional change.

Fixes: 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/tty/serial/samsung_tty.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index fcc675603b14..23cabdab44ff 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -2452,7 +2452,7 @@ static const struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
 #endif
 
 #if defined(CONFIG_ARCH_EXYNOS)
-#define EXYNOS_COMMON_SERIAL_DRV_DATA()				\
+#define EXYNOS_COMMON_SERIAL_DRV_DATA				\
 	.info = {						\
 		.name		= "Samsung Exynos UART",	\
 		.type		= TYPE_S3C6400,			\
@@ -2477,17 +2477,17 @@ static const struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
 	}							\
 
 static const struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
-	EXYNOS_COMMON_SERIAL_DRV_DATA(),
+	EXYNOS_COMMON_SERIAL_DRV_DATA,
 	.fifosize = { 256, 64, 16, 16 },
 };
 
 static const struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
-	EXYNOS_COMMON_SERIAL_DRV_DATA(),
+	EXYNOS_COMMON_SERIAL_DRV_DATA,
 	.fifosize = { 64, 256, 16, 256 },
 };
 
 static const struct s3c24xx_serial_drv_data exynos850_serial_drv_data = {
-	EXYNOS_COMMON_SERIAL_DRV_DATA(),
+	EXYNOS_COMMON_SERIAL_DRV_DATA,
 	.fifosize = { 256, 64, 64, 64 },
 };
 
-- 
2.39.2



From sgsu.park at samsung.com  Thu Feb  1 17:33:06 2024
From: sgsu.park at samsung.com (Seongsu Park)
Date: Fri,  2 Feb 2024 10:33:06 +0900
Subject: [PATCH] arm64: fix typo in comments
References: <CGME20240202013414epcas1p28ce117bb1e5e7f03b68365ec0d3a9c89@epcas1p2.samsung.com>
Message-ID: <20240202013306.883777-1-sgsu.park@samsung.com>

fix typo in comments

thath -> that

Signed-off-by: Seongsu Park <sgsu.park at samsung.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 21c824edf8ce..bd8d4ca81a48 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -83,7 +83,7 @@ struct arm64_ftr_bits {
  * to full-0 denotes that this field has no override
  *
  * A @mask field set to full-0 with the corresponding @val field set
- * to full-1 denotes thath this field has an invalid override.
+ * to full-1 denotes that this field has an invalid override.
  */
 struct arm64_ftr_override {
 	u64		val;
-- 
2.34.1



From shahuang at redhat.com  Thu Feb  1 18:56:49 2024
From: shahuang at redhat.com (Shaoqin Huang)
Date: Thu,  1 Feb 2024 21:56:49 -0500
Subject: [PATCH v4 0/5] KVM: selftests: aarch64: Introduce pmu_event_filter_test
Message-ID: <20240202025659.5065-1-shahuang@redhat.com>

The test is inspired by the pmu_event_filter_test which implemented by x86. On
the arm64 platform, there is the same ability to set the pmu_event_filter
through the KVM_ARM_VCPU_PMU_V3_FILTER attribute. So add the test for arm64.

The series first move some pmu common code from vpmu_counter_access to
lib/aarch64/vpmu.c and include/aarch64/vpmu.h, which can be used by
pmu_event_filter_test. Then fix a bug related to the [enable|disable]_counter,
and at last, implement the test itself.

Changelog:
----------
v3->v4:
  - Rebased to the v6.8-rc2.

v2->v3:
  - Check the pmceid in guest code instead of pmu event count since different
  hardware may have different event count result, check pmceid makes it stable
  on different platform.                        [Eric]
  - Some typo fixed and commit message improved.

v1->v2:
  - Improve the commit message.                 [Eric]
  - Fix the bug in [enable|disable]_counter.    [Raghavendra & Marc]
  - Add the check if kvm has attr KVM_ARM_VCPU_PMU_V3_FILTER.
  - Add if host pmu support the test event throught pmceid0.
  - Split the test_invalid_filter() to another patch. [Eric]

v1: https://lore.kernel.org/all/20231123063750.2176250-1-shahuang at redhat.com/
v2: https://lore.kernel.org/all/20231129072712.2667337-1-shahuang at redhat.com/
v3: https://lore.kernel.org/all/20240116060129.55473-1-shahuang at redhat.com/

Shaoqin Huang (5):
  KVM: selftests: aarch64: Make the [create|destroy]_vpmu_vm() public
  KVM: selftests: aarch64: Move pmu helper functions into vpmu.h
  KVM: selftests: aarch64: Fix the buggy [enable|disable]_counter
  KVM: selftests: aarch64: Introduce pmu_event_filter_test
  KVM: selftests: aarch64: Add invalid filter test in
    pmu_event_filter_test

 tools/testing/selftests/kvm/Makefile          |   2 +
 .../kvm/aarch64/pmu_event_filter_test.c       | 255 ++++++++++++++++++
 .../kvm/aarch64/vpmu_counter_access.c         | 217 ++-------------
 .../selftests/kvm/include/aarch64/vpmu.h      | 134 +++++++++
 .../testing/selftests/kvm/lib/aarch64/vpmu.c  |  74 +++++
 5 files changed, 489 insertions(+), 193 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
 create mode 100644 tools/testing/selftests/kvm/include/aarch64/vpmu.h
 create mode 100644 tools/testing/selftests/kvm/lib/aarch64/vpmu.c


base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
-- 
2.40.1



From shahuang at redhat.com  Thu Feb  1 18:56:51 2024
From: shahuang at redhat.com (Shaoqin Huang)
Date: Thu,  1 Feb 2024 21:56:51 -0500
Subject: [PATCH v4 2/5] KVM: selftests: aarch64: Move pmu helper functions into vpmu.h
In-Reply-To: <20240202025659.5065-1-shahuang@redhat.com>
References: <20240202025659.5065-1-shahuang@redhat.com>
Message-ID: <20240202025659.5065-3-shahuang@redhat.com>

Move those pmu helper functions into include/aarch64/vpmu.h, thus
it can be used by other pmu test.

No functional change intended.

Reviewed-by: Eric Auger <eric.auger at redhat.com>
Signed-off-by: Shaoqin Huang <shahuang at redhat.com>
---
 .../kvm/aarch64/vpmu_counter_access.c         | 117 -----------------
 .../selftests/kvm/include/aarch64/vpmu.h      | 118 ++++++++++++++++++
 2 files changed, 118 insertions(+), 117 deletions(-)

diff --git a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c b/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
index bad0fdbe6d34..62d6315790ab 100644
--- a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
+++ b/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
@@ -20,12 +20,6 @@
 #include <perf/arm_pmuv3.h>
 #include <linux/bitfield.h>
 
-/* The max number of the PMU event counters (excluding the cycle counter) */
-#define ARMV8_PMU_MAX_GENERAL_COUNTERS	(ARMV8_PMU_MAX_COUNTERS - 1)
-
-/* The cycle counter bit position that's common among the PMU registers */
-#define ARMV8_PMU_CYCLE_IDX		31
-
 static struct vpmu_vm *vpmu_vm;
 
 struct pmreg_sets {
@@ -35,117 +29,6 @@ struct pmreg_sets {
 
 #define PMREG_SET(set, clr) {.set_reg_id = set, .clr_reg_id = clr}
 
-static uint64_t get_pmcr_n(uint64_t pmcr)
-{
-	return FIELD_GET(ARMV8_PMU_PMCR_N, pmcr);
-}
-
-static void set_pmcr_n(uint64_t *pmcr, uint64_t pmcr_n)
-{
-	u64p_replace_bits((__u64 *) pmcr, pmcr_n, ARMV8_PMU_PMCR_N);
-}
-
-static uint64_t get_counters_mask(uint64_t n)
-{
-	uint64_t mask = BIT(ARMV8_PMU_CYCLE_IDX);
-
-	if (n)
-		mask |= GENMASK(n - 1, 0);
-	return mask;
-}
-
-/* Read PMEVTCNTR<n>_EL0 through PMXEVCNTR_EL0 */
-static inline unsigned long read_sel_evcntr(int sel)
-{
-	write_sysreg(sel, pmselr_el0);
-	isb();
-	return read_sysreg(pmxevcntr_el0);
-}
-
-/* Write PMEVTCNTR<n>_EL0 through PMXEVCNTR_EL0 */
-static inline void write_sel_evcntr(int sel, unsigned long val)
-{
-	write_sysreg(sel, pmselr_el0);
-	isb();
-	write_sysreg(val, pmxevcntr_el0);
-	isb();
-}
-
-/* Read PMEVTYPER<n>_EL0 through PMXEVTYPER_EL0 */
-static inline unsigned long read_sel_evtyper(int sel)
-{
-	write_sysreg(sel, pmselr_el0);
-	isb();
-	return read_sysreg(pmxevtyper_el0);
-}
-
-/* Write PMEVTYPER<n>_EL0 through PMXEVTYPER_EL0 */
-static inline void write_sel_evtyper(int sel, unsigned long val)
-{
-	write_sysreg(sel, pmselr_el0);
-	isb();
-	write_sysreg(val, pmxevtyper_el0);
-	isb();
-}
-
-static inline void enable_counter(int idx)
-{
-	uint64_t v = read_sysreg(pmcntenset_el0);
-
-	write_sysreg(BIT(idx) | v, pmcntenset_el0);
-	isb();
-}
-
-static inline void disable_counter(int idx)
-{
-	uint64_t v = read_sysreg(pmcntenset_el0);
-
-	write_sysreg(BIT(idx) | v, pmcntenclr_el0);
-	isb();
-}
-
-static void pmu_disable_reset(void)
-{
-	uint64_t pmcr = read_sysreg(pmcr_el0);
-
-	/* Reset all counters, disabling them */
-	pmcr &= ~ARMV8_PMU_PMCR_E;
-	write_sysreg(pmcr | ARMV8_PMU_PMCR_P, pmcr_el0);
-	isb();
-}
-
-#define RETURN_READ_PMEVCNTRN(n) \
-	return read_sysreg(pmevcntr##n##_el0)
-static unsigned long read_pmevcntrn(int n)
-{
-	PMEVN_SWITCH(n, RETURN_READ_PMEVCNTRN);
-	return 0;
-}
-
-#define WRITE_PMEVCNTRN(n) \
-	write_sysreg(val, pmevcntr##n##_el0)
-static void write_pmevcntrn(int n, unsigned long val)
-{
-	PMEVN_SWITCH(n, WRITE_PMEVCNTRN);
-	isb();
-}
-
-#define READ_PMEVTYPERN(n) \
-	return read_sysreg(pmevtyper##n##_el0)
-static unsigned long read_pmevtypern(int n)
-{
-	PMEVN_SWITCH(n, READ_PMEVTYPERN);
-	return 0;
-}
-
-#define WRITE_PMEVTYPERN(n) \
-	write_sysreg(val, pmevtyper##n##_el0)
-static void write_pmevtypern(int n, unsigned long val)
-{
-	PMEVN_SWITCH(n, WRITE_PMEVTYPERN);
-	isb();
-}
-
 /*
  * The pmc_accessor structure has pointers to PMEV{CNTR,TYPER}<n>_EL0
  * accessors that test cases will use. Each of the accessors will
diff --git a/tools/testing/selftests/kvm/include/aarch64/vpmu.h b/tools/testing/selftests/kvm/include/aarch64/vpmu.h
index 0a56183644ee..f78c93a08bff 100644
--- a/tools/testing/selftests/kvm/include/aarch64/vpmu.h
+++ b/tools/testing/selftests/kvm/include/aarch64/vpmu.h
@@ -1,10 +1,17 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 
 #include <kvm_util.h>
+#include <perf/arm_pmuv3.h>
 
 #define GICD_BASE_GPA	0x8000000ULL
 #define GICR_BASE_GPA	0x80A0000ULL
 
+/* The max number of the PMU event counters (excluding the cycle counter) */
+#define ARMV8_PMU_MAX_GENERAL_COUNTERS	(ARMV8_PMU_MAX_COUNTERS - 1)
+
+/* The cycle counter bit position that's common among the PMU registers */
+#define ARMV8_PMU_CYCLE_IDX		31
+
 struct vpmu_vm {
 	struct kvm_vm *vm;
 	struct kvm_vcpu *vcpu;
@@ -14,3 +21,114 @@ struct vpmu_vm {
 struct vpmu_vm *create_vpmu_vm(void *guest_code);
 
 void destroy_vpmu_vm(struct vpmu_vm *vpmu_vm);
+
+static inline uint64_t get_pmcr_n(uint64_t pmcr)
+{
+	return FIELD_GET(ARMV8_PMU_PMCR_N, pmcr);
+}
+
+static inline void set_pmcr_n(uint64_t *pmcr, uint64_t pmcr_n)
+{
+	u64p_replace_bits((__u64 *) pmcr, pmcr_n, ARMV8_PMU_PMCR_N);
+}
+
+static inline uint64_t get_counters_mask(uint64_t n)
+{
+	uint64_t mask = BIT(ARMV8_PMU_CYCLE_IDX);
+
+	if (n)
+		mask |= GENMASK(n - 1, 0);
+	return mask;
+}
+
+/* Read PMEVTCNTR<n>_EL0 through PMXEVCNTR_EL0 */
+static inline unsigned long read_sel_evcntr(int sel)
+{
+	write_sysreg(sel, pmselr_el0);
+	isb();
+	return read_sysreg(pmxevcntr_el0);
+}
+
+/* Write PMEVTCNTR<n>_EL0 through PMXEVCNTR_EL0 */
+static inline void write_sel_evcntr(int sel, unsigned long val)
+{
+	write_sysreg(sel, pmselr_el0);
+	isb();
+	write_sysreg(val, pmxevcntr_el0);
+	isb();
+}
+
+/* Read PMEVTYPER<n>_EL0 through PMXEVTYPER_EL0 */
+static inline unsigned long read_sel_evtyper(int sel)
+{
+	write_sysreg(sel, pmselr_el0);
+	isb();
+	return read_sysreg(pmxevtyper_el0);
+}
+
+/* Write PMEVTYPER<n>_EL0 through PMXEVTYPER_EL0 */
+static inline void write_sel_evtyper(int sel, unsigned long val)
+{
+	write_sysreg(sel, pmselr_el0);
+	isb();
+	write_sysreg(val, pmxevtyper_el0);
+	isb();
+}
+
+static inline void enable_counter(int idx)
+{
+	uint64_t v = read_sysreg(pmcntenset_el0);
+
+	write_sysreg(BIT(idx) | v, pmcntenset_el0);
+	isb();
+}
+
+static inline void disable_counter(int idx)
+{
+	uint64_t v = read_sysreg(pmcntenset_el0);
+
+	write_sysreg(BIT(idx) | v, pmcntenclr_el0);
+	isb();
+}
+
+static inline void pmu_disable_reset(void)
+{
+	uint64_t pmcr = read_sysreg(pmcr_el0);
+
+	/* Reset all counters, disabling them */
+	pmcr &= ~ARMV8_PMU_PMCR_E;
+	write_sysreg(pmcr | ARMV8_PMU_PMCR_P, pmcr_el0);
+	isb();
+}
+
+#define RETURN_READ_PMEVCNTRN(n) \
+	return read_sysreg(pmevcntr##n##_el0)
+static inline unsigned long read_pmevcntrn(int n)
+{
+	PMEVN_SWITCH(n, RETURN_READ_PMEVCNTRN);
+	return 0;
+}
+
+#define WRITE_PMEVCNTRN(n) \
+	write_sysreg(val, pmevcntr##n##_el0)
+static inline void write_pmevcntrn(int n, unsigned long val)
+{
+	PMEVN_SWITCH(n, WRITE_PMEVCNTRN);
+	isb();
+}
+
+#define READ_PMEVTYPERN(n) \
+	return read_sysreg(pmevtyper##n##_el0)
+static inline unsigned long read_pmevtypern(int n)
+{
+	PMEVN_SWITCH(n, READ_PMEVTYPERN);
+	return 0;
+}
+
+#define WRITE_PMEVTYPERN(n) \
+	write_sysreg(val, pmevtyper##n##_el0)
+static inline void write_pmevtypern(int n, unsigned long val)
+{
+	PMEVN_SWITCH(n, WRITE_PMEVTYPERN);
+	isb();
+}
-- 
2.40.1



From shahuang at redhat.com  Thu Feb  1 18:56:54 2024
From: shahuang at redhat.com (Shaoqin Huang)
Date: Thu,  1 Feb 2024 21:56:54 -0500
Subject: [PATCH v4 5/5] KVM: selftests: aarch64: Add invalid filter test in pmu_event_filter_test
In-Reply-To: <20240202025659.5065-1-shahuang@redhat.com>
References: <20240202025659.5065-1-shahuang@redhat.com>
Message-ID: <20240202025659.5065-6-shahuang@redhat.com>

Add the invalid filter test includes sets the filter beyond the event
space and sets the invalid action to double check if the
KVM_ARM_VCPU_PMU_V3_FILTER will return the expected error.

Signed-off-by: Shaoqin Huang <shahuang at redhat.com>
---
 .../kvm/aarch64/pmu_event_filter_test.c       | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
index d280382f362f..68e1f2003312 100644
--- a/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
+++ b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
@@ -7,6 +7,7 @@
  * This test checks if the guest only see the limited pmu event that userspace
  * sets, if the guest can use those events which user allow, and if the guest
  * can't use those events which user deny.
+ * It also checks that setting invalid filter ranges return the expected error.
  * This test runs only when KVM_CAP_ARM_PMU_V3, KVM_ARM_VCPU_PMU_V3_FILTER
  * is supported on the host.
  */
@@ -183,6 +184,39 @@ static void for_each_test(void)
 		run_test(t);
 }
 
+static void set_invalid_filter(struct vpmu_vm *vm, void *arg)
+{
+	struct kvm_pmu_event_filter invalid;
+	struct kvm_device_attr attr = {
+		.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
+		.attr	= KVM_ARM_VCPU_PMU_V3_FILTER,
+		.addr	= (uint64_t)&invalid,
+	};
+	int ret = 0;
+
+	/* The max event number is (1 << 16), set a range largeer than it. */
+	invalid = __DEFINE_FILTER(BIT(15), BIT(15)+1, 0);
+	ret = __vcpu_ioctl(vm->vcpu, KVM_SET_DEVICE_ATTR, &attr);
+	TEST_ASSERT(ret && errno == EINVAL, "Set Invalid filter range "
+		    "ret = %d, errno = %d (expected ret = -1, errno = EINVAL)",
+		    ret, errno);
+
+	ret = 0;
+
+	/* Set the Invalid action. */
+	invalid = __DEFINE_FILTER(0, 1, 3);
+	ret = __vcpu_ioctl(vm->vcpu, KVM_SET_DEVICE_ATTR, &attr);
+	TEST_ASSERT(ret && errno == EINVAL, "Set Invalid filter action "
+		    "ret = %d, errno = %d (expected ret = -1, errno = EINVAL)",
+		    ret, errno);
+}
+
+static void test_invalid_filter(void)
+{
+	vpmu_vm = __create_vpmu_vm(guest_code, set_invalid_filter, NULL);
+	destroy_vpmu_vm(vpmu_vm);
+}
+
 static bool kvm_supports_pmu_event_filter(void)
 {
 	int r;
@@ -216,4 +250,6 @@ int main(void)
 	TEST_REQUIRE(host_pmu_supports_events());
 
 	for_each_test();
+
+	test_invalid_filter();
 }
-- 
2.40.1



From shahuang at redhat.com  Thu Feb  1 18:56:50 2024
From: shahuang at redhat.com (Shaoqin Huang)
Date: Thu,  1 Feb 2024 21:56:50 -0500
Subject: [PATCH v4 1/5] KVM: selftests: aarch64: Make the [create|destroy]_vpmu_vm() public
In-Reply-To: <20240202025659.5065-1-shahuang@redhat.com>
References: <20240202025659.5065-1-shahuang@redhat.com>
Message-ID: <20240202025659.5065-2-shahuang@redhat.com>

Move the implementation of [create|destroy]_vpmu_vm() into
lib/aarch64/pmu.c and export their declaration in a header so they can
be reused by other tests.

The sync exception handler install is test specific so we move it out of
the helper function.

No functional change intended.

Reviewed-by: Eric Auger <eric.auger at redhat.com>
Signed-off-by: Shaoqin Huang <shahuang at redhat.com>
---
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/aarch64/vpmu_counter_access.c         | 100 +++++-------------
 .../selftests/kvm/include/aarch64/vpmu.h      |  16 +++
 .../testing/selftests/kvm/lib/aarch64/vpmu.c  |  64 +++++++++++
 4 files changed, 105 insertions(+), 76 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/include/aarch64/vpmu.h
 create mode 100644 tools/testing/selftests/kvm/lib/aarch64/vpmu.c

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 492e937fab00..709a70b31ca2 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -48,6 +48,7 @@ LIBKVM_aarch64 += lib/aarch64/processor.c
 LIBKVM_aarch64 += lib/aarch64/spinlock.c
 LIBKVM_aarch64 += lib/aarch64/ucall.c
 LIBKVM_aarch64 += lib/aarch64/vgic.c
+LIBKVM_aarch64 += lib/aarch64/vpmu.c
 
 LIBKVM_s390x += lib/s390x/diag318_test_handler.c
 LIBKVM_s390x += lib/s390x/processor.c
diff --git a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c b/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
index 9d51b5691349..bad0fdbe6d34 100644
--- a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
+++ b/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
@@ -16,6 +16,7 @@
 #include <processor.h>
 #include <test_util.h>
 #include <vgic.h>
+#include <vpmu.h>
 #include <perf/arm_pmuv3.h>
 #include <linux/bitfield.h>
 
@@ -25,13 +26,7 @@
 /* The cycle counter bit position that's common among the PMU registers */
 #define ARMV8_PMU_CYCLE_IDX		31
 
-struct vpmu_vm {
-	struct kvm_vm *vm;
-	struct kvm_vcpu *vcpu;
-	int gic_fd;
-};
-
-static struct vpmu_vm vpmu_vm;
+static struct vpmu_vm *vpmu_vm;
 
 struct pmreg_sets {
 	uint64_t set_reg_id;
@@ -420,64 +415,6 @@ static void guest_code(uint64_t expected_pmcr_n)
 	GUEST_DONE();
 }
 
-#define GICD_BASE_GPA	0x8000000ULL
-#define GICR_BASE_GPA	0x80A0000ULL
-
-/* Create a VM that has one vCPU with PMUv3 configured. */
-static void create_vpmu_vm(void *guest_code)
-{
-	struct kvm_vcpu_init init;
-	uint8_t pmuver, ec;
-	uint64_t dfr0, irq = 23;
-	struct kvm_device_attr irq_attr = {
-		.group = KVM_ARM_VCPU_PMU_V3_CTRL,
-		.attr = KVM_ARM_VCPU_PMU_V3_IRQ,
-		.addr = (uint64_t)&irq,
-	};
-	struct kvm_device_attr init_attr = {
-		.group = KVM_ARM_VCPU_PMU_V3_CTRL,
-		.attr = KVM_ARM_VCPU_PMU_V3_INIT,
-	};
-
-	/* The test creates the vpmu_vm multiple times. Ensure a clean state */
-	memset(&vpmu_vm, 0, sizeof(vpmu_vm));
-
-	vpmu_vm.vm = vm_create(1);
-	vm_init_descriptor_tables(vpmu_vm.vm);
-	for (ec = 0; ec < ESR_EC_NUM; ec++) {
-		vm_install_sync_handler(vpmu_vm.vm, VECTOR_SYNC_CURRENT, ec,
-					guest_sync_handler);
-	}
-
-	/* Create vCPU with PMUv3 */
-	vm_ioctl(vpmu_vm.vm, KVM_ARM_PREFERRED_TARGET, &init);
-	init.features[0] |= (1 << KVM_ARM_VCPU_PMU_V3);
-	vpmu_vm.vcpu = aarch64_vcpu_add(vpmu_vm.vm, 0, &init, guest_code);
-	vcpu_init_descriptor_tables(vpmu_vm.vcpu);
-	vpmu_vm.gic_fd = vgic_v3_setup(vpmu_vm.vm, 1, 64,
-					GICD_BASE_GPA, GICR_BASE_GPA);
-	__TEST_REQUIRE(vpmu_vm.gic_fd >= 0,
-		       "Failed to create vgic-v3, skipping");
-
-	/* Make sure that PMUv3 support is indicated in the ID register */
-	vcpu_get_reg(vpmu_vm.vcpu,
-		     KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &dfr0);
-	pmuver = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), dfr0);
-	TEST_ASSERT(pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF &&
-		    pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP,
-		    "Unexpected PMUVER (0x%x) on the vCPU with PMUv3", pmuver);
-
-	/* Initialize vPMU */
-	vcpu_ioctl(vpmu_vm.vcpu, KVM_SET_DEVICE_ATTR, &irq_attr);
-	vcpu_ioctl(vpmu_vm.vcpu, KVM_SET_DEVICE_ATTR, &init_attr);
-}
-
-static void destroy_vpmu_vm(void)
-{
-	close(vpmu_vm.gic_fd);
-	kvm_vm_free(vpmu_vm.vm);
-}
-
 static void run_vcpu(struct kvm_vcpu *vcpu, uint64_t pmcr_n)
 {
 	struct ucall uc;
@@ -496,13 +433,24 @@ static void run_vcpu(struct kvm_vcpu *vcpu, uint64_t pmcr_n)
 	}
 }
 
+static void create_vpmu_vm_with_handler(void *guest_code)
+{
+	uint8_t ec;
+	vpmu_vm = create_vpmu_vm(guest_code);
+
+	for (ec = 0; ec < ESR_EC_NUM; ec++) {
+		vm_install_sync_handler(vpmu_vm->vm, VECTOR_SYNC_CURRENT, ec,
+					guest_sync_handler);
+	}
+}
+
 static void test_create_vpmu_vm_with_pmcr_n(uint64_t pmcr_n, bool expect_fail)
 {
 	struct kvm_vcpu *vcpu;
 	uint64_t pmcr, pmcr_orig;
 
-	create_vpmu_vm(guest_code);
-	vcpu = vpmu_vm.vcpu;
+	create_vpmu_vm_with_handler(guest_code);
+	vcpu = vpmu_vm->vcpu;
 
 	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr_orig);
 	pmcr = pmcr_orig;
@@ -538,7 +486,7 @@ static void run_access_test(uint64_t pmcr_n)
 	pr_debug("Test with pmcr_n %lu\n", pmcr_n);
 
 	test_create_vpmu_vm_with_pmcr_n(pmcr_n, false);
-	vcpu = vpmu_vm.vcpu;
+	vcpu = vpmu_vm->vcpu;
 
 	/* Save the initial sp to restore them later to run the guest again */
 	vcpu_get_reg(vcpu, ARM64_CORE_REG(sp_el1), &sp);
@@ -549,7 +497,7 @@ static void run_access_test(uint64_t pmcr_n)
 	 * Reset and re-initialize the vCPU, and run the guest code again to
 	 * check if PMCR_EL0.N is preserved.
 	 */
-	vm_ioctl(vpmu_vm.vm, KVM_ARM_PREFERRED_TARGET, &init);
+	vm_ioctl(vpmu_vm->vm, KVM_ARM_PREFERRED_TARGET, &init);
 	init.features[0] |= (1 << KVM_ARM_VCPU_PMU_V3);
 	aarch64_vcpu_setup(vcpu, &init);
 	vcpu_init_descriptor_tables(vcpu);
@@ -558,7 +506,7 @@ static void run_access_test(uint64_t pmcr_n)
 
 	run_vcpu(vcpu, pmcr_n);
 
-	destroy_vpmu_vm();
+	destroy_vpmu_vm(vpmu_vm);
 }
 
 static struct pmreg_sets validity_check_reg_sets[] = {
@@ -579,7 +527,7 @@ static void run_pmregs_validity_test(uint64_t pmcr_n)
 	uint64_t valid_counters_mask, max_counters_mask;
 
 	test_create_vpmu_vm_with_pmcr_n(pmcr_n, false);
-	vcpu = vpmu_vm.vcpu;
+	vcpu = vpmu_vm->vcpu;
 
 	valid_counters_mask = get_counters_mask(pmcr_n);
 	max_counters_mask = get_counters_mask(ARMV8_PMU_MAX_COUNTERS);
@@ -620,7 +568,7 @@ static void run_pmregs_validity_test(uint64_t pmcr_n)
 			    KVM_ARM64_SYS_REG(clr_reg_id), reg_val);
 	}
 
-	destroy_vpmu_vm();
+	destroy_vpmu_vm(vpmu_vm);
 }
 
 /*
@@ -633,7 +581,7 @@ static void run_error_test(uint64_t pmcr_n)
 	pr_debug("Error test with pmcr_n %lu (larger than the host)\n", pmcr_n);
 
 	test_create_vpmu_vm_with_pmcr_n(pmcr_n, true);
-	destroy_vpmu_vm();
+	destroy_vpmu_vm(vpmu_vm);
 }
 
 /*
@@ -644,9 +592,9 @@ static uint64_t get_pmcr_n_limit(void)
 {
 	uint64_t pmcr;
 
-	create_vpmu_vm(guest_code);
-	vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr);
-	destroy_vpmu_vm();
+	create_vpmu_vm_with_handler(guest_code);
+	vcpu_get_reg(vpmu_vm->vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr);
+	destroy_vpmu_vm(vpmu_vm);
 	return get_pmcr_n(pmcr);
 }
 
diff --git a/tools/testing/selftests/kvm/include/aarch64/vpmu.h b/tools/testing/selftests/kvm/include/aarch64/vpmu.h
new file mode 100644
index 000000000000..0a56183644ee
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/aarch64/vpmu.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <kvm_util.h>
+
+#define GICD_BASE_GPA	0x8000000ULL
+#define GICR_BASE_GPA	0x80A0000ULL
+
+struct vpmu_vm {
+	struct kvm_vm *vm;
+	struct kvm_vcpu *vcpu;
+	int gic_fd;
+};
+
+struct vpmu_vm *create_vpmu_vm(void *guest_code);
+
+void destroy_vpmu_vm(struct vpmu_vm *vpmu_vm);
diff --git a/tools/testing/selftests/kvm/lib/aarch64/vpmu.c b/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
new file mode 100644
index 000000000000..b3de8fdc555e
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <kvm_util.h>
+#include <processor.h>
+#include <test_util.h>
+#include <vgic.h>
+#include <vpmu.h>
+#include <perf/arm_pmuv3.h>
+
+/* Create a VM that has one vCPU with PMUv3 configured. */
+struct vpmu_vm *create_vpmu_vm(void *guest_code)
+{
+	struct kvm_vcpu_init init;
+	uint8_t pmuver;
+	uint64_t dfr0, irq = 23;
+	struct kvm_device_attr irq_attr = {
+		.group = KVM_ARM_VCPU_PMU_V3_CTRL,
+		.attr = KVM_ARM_VCPU_PMU_V3_IRQ,
+		.addr = (uint64_t)&irq,
+	};
+	struct kvm_device_attr init_attr = {
+		.group = KVM_ARM_VCPU_PMU_V3_CTRL,
+		.attr = KVM_ARM_VCPU_PMU_V3_INIT,
+	};
+	struct vpmu_vm *vpmu_vm;
+
+	vpmu_vm = calloc(1, sizeof(*vpmu_vm));
+	TEST_ASSERT(vpmu_vm != NULL, "Insufficient Memory");
+	memset(vpmu_vm, 0, sizeof(vpmu_vm));
+
+	vpmu_vm->vm = vm_create(1);
+	vm_init_descriptor_tables(vpmu_vm->vm);
+
+	/* Create vCPU with PMUv3 */
+	vm_ioctl(vpmu_vm->vm, KVM_ARM_PREFERRED_TARGET, &init);
+	init.features[0] |= (1 << KVM_ARM_VCPU_PMU_V3);
+	vpmu_vm->vcpu = aarch64_vcpu_add(vpmu_vm->vm, 0, &init, guest_code);
+	vcpu_init_descriptor_tables(vpmu_vm->vcpu);
+	vpmu_vm->gic_fd = vgic_v3_setup(vpmu_vm->vm, 1, 64,
+					GICD_BASE_GPA, GICR_BASE_GPA);
+	__TEST_REQUIRE(vpmu_vm->gic_fd >= 0,
+		       "Failed to create vgic-v3, skipping");
+
+	/* Make sure that PMUv3 support is indicated in the ID register */
+	vcpu_get_reg(vpmu_vm->vcpu,
+		     KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &dfr0);
+	pmuver = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), dfr0);
+	TEST_ASSERT(pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF &&
+		    pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP,
+		    "Unexpected PMUVER (0x%x) on the vCPU with PMUv3", pmuver);
+
+	/* Initialize vPMU */
+	vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &irq_attr);
+	vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &init_attr);
+
+	return vpmu_vm;
+}
+
+void destroy_vpmu_vm(struct vpmu_vm *vpmu_vm)
+{
+	close(vpmu_vm->gic_fd);
+	kvm_vm_free(vpmu_vm->vm);
+	free(vpmu_vm);
+}
-- 
2.40.1



From shahuang at redhat.com  Thu Feb  1 18:56:52 2024
From: shahuang at redhat.com (Shaoqin Huang)
Date: Thu,  1 Feb 2024 21:56:52 -0500
Subject: [PATCH v4 3/5] KVM: selftests: aarch64: Fix the buggy [enable|disable]_counter
In-Reply-To: <20240202025659.5065-1-shahuang@redhat.com>
References: <20240202025659.5065-1-shahuang@redhat.com>
Message-ID: <20240202025659.5065-4-shahuang@redhat.com>

In general, the set/clr registers should always be used in their
write form, never in a RMW form (imagine an interrupt disabling
a counter between the read and the write...).

The current implementation of [enable|disable]_counter both use the RMW
form, fix them by directly write to the set/clr registers.

At the same time, it also fix the buggy disable_counter() which would
end up disabling all the counters.

Signed-off-by: Shaoqin Huang <shahuang at redhat.com>
Reviewed-by: Eric Auger <eric.auger at redhat.com>
---
 tools/testing/selftests/kvm/include/aarch64/vpmu.h | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/aarch64/vpmu.h b/tools/testing/selftests/kvm/include/aarch64/vpmu.h
index f78c93a08bff..92715021f892 100644
--- a/tools/testing/selftests/kvm/include/aarch64/vpmu.h
+++ b/tools/testing/selftests/kvm/include/aarch64/vpmu.h
@@ -77,17 +77,13 @@ static inline void write_sel_evtyper(int sel, unsigned long val)
 
 static inline void enable_counter(int idx)
 {
-	uint64_t v = read_sysreg(pmcntenset_el0);
-
-	write_sysreg(BIT(idx) | v, pmcntenset_el0);
+	write_sysreg(BIT(idx), pmcntenset_el0);
 	isb();
 }
 
 static inline void disable_counter(int idx)
 {
-	uint64_t v = read_sysreg(pmcntenset_el0);
-
-	write_sysreg(BIT(idx) | v, pmcntenclr_el0);
+	write_sysreg(BIT(idx), pmcntenclr_el0);
 	isb();
 }
 
-- 
2.40.1



From shahuang at redhat.com  Thu Feb  1 18:56:53 2024
From: shahuang at redhat.com (Shaoqin Huang)
Date: Thu,  1 Feb 2024 21:56:53 -0500
Subject: [PATCH v4 4/5] KVM: selftests: aarch64: Introduce pmu_event_filter_test
In-Reply-To: <20240202025659.5065-1-shahuang@redhat.com>
References: <20240202025659.5065-1-shahuang@redhat.com>
Message-ID: <20240202025659.5065-5-shahuang@redhat.com>

Introduce pmu_event_filter_test for arm64 platforms. The test configures
PMUv3 for a vCPU, and sets different pmu event filters for the vCPU, and
check if the guest can see those events which user allow and can't use
those events which use deny.

This test refactor the create_vpmu_vm() and make it a wrapper for
__create_vpmu_vm(), which allows some extra init code before
KVM_ARM_VCPU_PMU_V3_INIT.

And this test use the KVM_ARM_VCPU_PMU_V3_FILTER attribute to set the
pmu event filter in KVM. And choose to filter two common event
branches_retired and instructions_retired, and let the guest to check if
it see the right pmceid register.

Signed-off-by: Shaoqin Huang <shahuang at redhat.com>
---
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/aarch64/pmu_event_filter_test.c       | 219 ++++++++++++++++++
 .../selftests/kvm/include/aarch64/vpmu.h      |   4 +
 .../testing/selftests/kvm/lib/aarch64/vpmu.c  |  14 +-
 4 files changed, 236 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 709a70b31ca2..733ec86a3385 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -148,6 +148,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
 TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
+TEST_GEN_PROGS_aarch64 += aarch64/pmu_event_filter_test
 TEST_GEN_PROGS_aarch64 += aarch64/psci_test
 TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs
 TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter
diff --git a/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
new file mode 100644
index 000000000000..d280382f362f
--- /dev/null
+++ b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pmu_event_filter_test - Test user limit pmu event for guest.
+ *
+ * Copyright (c) 2023 Red Hat, Inc.
+ *
+ * This test checks if the guest only see the limited pmu event that userspace
+ * sets, if the guest can use those events which user allow, and if the guest
+ * can't use those events which user deny.
+ * This test runs only when KVM_CAP_ARM_PMU_V3, KVM_ARM_VCPU_PMU_V3_FILTER
+ * is supported on the host.
+ */
+#include <kvm_util.h>
+#include <processor.h>
+#include <vgic.h>
+#include <vpmu.h>
+#include <test_util.h>
+#include <perf/arm_pmuv3.h>
+
+struct pmce{
+	uint64_t pmceid0;
+	uint64_t pmceid1;
+} supported_pmce, guest_pmce;
+
+static struct vpmu_vm *vpmu_vm;
+
+#define FILTER_NR 10
+
+struct test_desc {
+	const char *name;
+	struct kvm_pmu_event_filter filter[FILTER_NR];
+};
+
+#define __DEFINE_FILTER(base, num, act)		\
+	((struct kvm_pmu_event_filter) {	\
+		.base_event	= base,		\
+		.nevents	= num,		\
+		.action		= act,		\
+	})
+
+#define DEFINE_FILTER(base, act) __DEFINE_FILTER(base, 1, act)
+
+#define EMPTY_FILTER	{ 0 }
+
+#define SW_INCR		0x0
+#define INST_RETIRED	0x8
+#define BR_RETIRED	0x21
+
+static void guest_code(void)
+{
+	uint64_t pmceid0 = read_sysreg(pmceid0_el0);
+	uint64_t pmceid1 = read_sysreg(pmceid1_el0);
+
+	GUEST_ASSERT_EQ(guest_pmce.pmceid0, pmceid0);
+	GUEST_ASSERT_EQ(guest_pmce.pmceid1, pmceid1);
+
+	GUEST_DONE();
+}
+
+static void guest_get_pmceid(void)
+{
+	supported_pmce.pmceid0 = read_sysreg(pmceid0_el0);
+	supported_pmce.pmceid1 = read_sysreg(pmceid1_el0);
+
+	GUEST_DONE();
+}
+
+static void pmu_event_filter_init(struct vpmu_vm *vm, void *arg)
+{
+	struct kvm_device_attr attr = {
+		.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
+		.attr	= KVM_ARM_VCPU_PMU_V3_FILTER,
+	};
+	struct kvm_pmu_event_filter *filter = (struct kvm_pmu_event_filter *)arg;
+
+	while (filter && filter->nevents != 0) {
+		attr.addr = (uint64_t)filter;
+		vcpu_ioctl(vm->vcpu, KVM_SET_DEVICE_ATTR, &attr);
+		filter++;
+	}
+}
+
+static void create_vpmu_vm_with_filter(void *guest_code,
+				       struct kvm_pmu_event_filter *filter)
+{
+	vpmu_vm = __create_vpmu_vm(guest_code, pmu_event_filter_init, filter);
+}
+
+static void run_vcpu(struct kvm_vcpu *vcpu)
+{
+	struct ucall uc;
+
+	while (1) {
+		vcpu_run(vcpu);
+		switch (get_ucall(vcpu, &uc)) {
+		case UCALL_DONE:
+			return;
+		default:
+			TEST_FAIL("Unknown ucall %lu", uc.cmd);
+		}
+	}
+}
+
+static void set_pmce(struct pmce *pmce, int action, int event)
+{
+	int base = 0;
+	uint64_t *pmceid = NULL;
+
+	if (event >= 0x4000) {
+		event -= 0x4000;
+		base = 32;
+	}
+
+	if (event >= 0 && event <= 0x1F) {
+		pmceid = &pmce->pmceid0;
+	} else if (event >= 0x20 && event <= 0x3F) {
+		event -= 0x20;
+		pmceid = &pmce->pmceid1;
+	} else {
+		return;
+	}
+
+	event += base;
+	if (action == KVM_PMU_EVENT_ALLOW)
+		*pmceid |= BIT(event);
+	else
+		*pmceid &= ~BIT(event);
+}
+
+static void prepare_guest_pmce(struct kvm_pmu_event_filter *filter)
+{
+	struct pmce pmce_mask = { ~0, ~0 };
+	bool first_filter = true;
+
+	while (filter && filter->nevents != 0) {
+		if (first_filter) {
+			if (filter->action == KVM_PMU_EVENT_ALLOW)
+				memset(&pmce_mask, 0, sizeof(pmce_mask));
+			first_filter = false;
+		}
+
+		set_pmce(&pmce_mask, filter->action, filter->base_event);
+		filter++;
+	}
+
+	guest_pmce.pmceid0 = supported_pmce.pmceid0 & pmce_mask.pmceid0;
+	guest_pmce.pmceid1 = supported_pmce.pmceid1 & pmce_mask.pmceid1;
+}
+
+static void run_test(struct test_desc *t)
+{
+	pr_debug("Test: %s\n", t->name);
+
+	create_vpmu_vm_with_filter(guest_code, t->filter);
+	prepare_guest_pmce(t->filter);
+	sync_global_to_guest(vpmu_vm->vm, guest_pmce);
+
+	run_vcpu(vpmu_vm->vcpu);
+
+	destroy_vpmu_vm(vpmu_vm);
+}
+
+static struct test_desc tests[] = {
+	{"without_filter", { EMPTY_FILTER }},
+	{"member_allow_filter",
+	 {DEFINE_FILTER(SW_INCR, 0), DEFINE_FILTER(INST_RETIRED, 0),
+	  DEFINE_FILTER(BR_RETIRED, 0), EMPTY_FILTER}},
+	{"member_deny_filter",
+	 {DEFINE_FILTER(SW_INCR, 1), DEFINE_FILTER(INST_RETIRED, 1),
+	  DEFINE_FILTER(BR_RETIRED, 1), EMPTY_FILTER}},
+	{"not_member_deny_filter",
+	 {DEFINE_FILTER(SW_INCR, 1), EMPTY_FILTER}},
+	{"not_member_allow_filter",
+	 {DEFINE_FILTER(SW_INCR, 0), EMPTY_FILTER}},
+	{ 0 }
+};
+
+static void for_each_test(void)
+{
+	struct test_desc *t;
+
+	for (t = &tests[0]; t->name; t++)
+		run_test(t);
+}
+
+static bool kvm_supports_pmu_event_filter(void)
+{
+	int r;
+
+	vpmu_vm = create_vpmu_vm(guest_code);
+
+	r = __kvm_has_device_attr(vpmu_vm->vcpu->fd, KVM_ARM_VCPU_PMU_V3_CTRL,
+				  KVM_ARM_VCPU_PMU_V3_FILTER);
+
+	destroy_vpmu_vm(vpmu_vm);
+	return !r;
+}
+
+static bool host_pmu_supports_events(void)
+{
+	vpmu_vm = create_vpmu_vm(guest_get_pmceid);
+
+	memset(&supported_pmce, 0, sizeof(supported_pmce));
+	sync_global_to_guest(vpmu_vm->vm, supported_pmce);
+	run_vcpu(vpmu_vm->vcpu);
+	sync_global_from_guest(vpmu_vm->vm, supported_pmce);
+	destroy_vpmu_vm(vpmu_vm);
+
+	return supported_pmce.pmceid0 & (BR_RETIRED | INST_RETIRED);
+}
+
+int main(void)
+{
+	TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_PMU_V3));
+	TEST_REQUIRE(kvm_supports_pmu_event_filter());
+	TEST_REQUIRE(host_pmu_supports_events());
+
+	for_each_test();
+}
diff --git a/tools/testing/selftests/kvm/include/aarch64/vpmu.h b/tools/testing/selftests/kvm/include/aarch64/vpmu.h
index 92715021f892..ec37dbd0b1c0 100644
--- a/tools/testing/selftests/kvm/include/aarch64/vpmu.h
+++ b/tools/testing/selftests/kvm/include/aarch64/vpmu.h
@@ -18,6 +18,10 @@ struct vpmu_vm {
 	int gic_fd;
 };
 
+struct vpmu_vm *__create_vpmu_vm(void *guest_code,
+				 void (*init_pmu)(struct vpmu_vm *vm, void *arg),
+				 void *arg);
+
 struct vpmu_vm *create_vpmu_vm(void *guest_code);
 
 void destroy_vpmu_vm(struct vpmu_vm *vpmu_vm);
diff --git a/tools/testing/selftests/kvm/lib/aarch64/vpmu.c b/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
index b3de8fdc555e..76ea03d607f1 100644
--- a/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
+++ b/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
@@ -7,8 +7,9 @@
 #include <vpmu.h>
 #include <perf/arm_pmuv3.h>
 
-/* Create a VM that has one vCPU with PMUv3 configured. */
-struct vpmu_vm *create_vpmu_vm(void *guest_code)
+struct vpmu_vm *__create_vpmu_vm(void *guest_code,
+				 void (*init_pmu)(struct vpmu_vm *vm, void *arg),
+				 void *arg)
 {
 	struct kvm_vcpu_init init;
 	uint8_t pmuver;
@@ -50,12 +51,21 @@ struct vpmu_vm *create_vpmu_vm(void *guest_code)
 		    "Unexpected PMUVER (0x%x) on the vCPU with PMUv3", pmuver);
 
 	/* Initialize vPMU */
+	if (init_pmu)
+		init_pmu(vpmu_vm, arg);
+
 	vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &irq_attr);
 	vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &init_attr);
 
 	return vpmu_vm;
 }
 
+/* Create a VM that has one vCPU with PMUv3 configured. */
+struct vpmu_vm *create_vpmu_vm(void *guest_code)
+{
+	return __create_vpmu_vm(guest_code, NULL, NULL);
+}
+
 void destroy_vpmu_vm(struct vpmu_vm *vpmu_vm)
 {
 	close(vpmu_vm->gic_fd);
-- 
2.40.1



From yong.liang.choong at linux.intel.com  Thu Feb  1 19:00:58 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Fri, 2 Feb 2024 11:00:58 +0800
Subject: [PATCH net-next v4 06/11] net: stmmac: resetup XPCS according to
 the new interface mode
In-Reply-To: <ZbtYaXkNf2ZF1prE@shell.armlinux.org.uk>
References: <20240129130253.1400707-1-yong.liang.choong@linux.intel.com>
 <20240129130253.1400707-7-yong.liang.choong@linux.intel.com>
 <ZbjNn+C/VHegH2t7@shell.armlinux.org.uk>
 <9e23671e-788c-4191-bdb4-94915ff7da5a@linux.intel.com>
 <ZbtYaXkNf2ZF1prE@shell.armlinux.org.uk>
Message-ID: <2ad1f55c-f361-4439-9174-6af1bb429d55@linux.intel.com>



On 1/2/2024 4:38 pm, Russell King (Oracle) wrote:
> Note the "This must not modify any state." statement. By reinitialising
> the PCS in this method, you are violating that statement.
> 
> This requirement is because this method will be called by
> phylink_validate_mac_and_pcs() at various times, potentially for each
> and every interface that stmmac supports, which will lead to you
> reinitialising the PCS, killing the link, each time we ask the MAC for
> a PCS, whether we are going to make use of it in that mode or not.
> 
> You can not do this. Sorry. Hard NAK for this approach.
> 
Thank you for taking the time to review, got your concerns, and I'll 
address the following concerns before submitting a new patch series:

1. Remove allow_switch_interface and have the PHY driver fill in 
phydev->possible_interfaces.
2. Rework on the PCS to have similar implementation with the following 
patch "net: macb: use .mac_select_pcs() interface" 
(https://lore.kernel.org/netdev/E1n568J-002SZX-Gr at rmk-PC.armlinux.org.uk/T/).

Kindly let me know if there are any additional concerns or suggestions.


From yong.liang.choong at linux.intel.com  Thu Feb  1 19:04:15 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Fri, 2 Feb 2024 11:04:15 +0800
Subject: [PATCH net-next v4 07/11] arch: x86: Add IPC mailbox accessor
 function and add SoC register access
In-Reply-To: <1fccbf0d-5b96-447b-80f1-19af70628edc@linux.intel.com>
References: <20240129130253.1400707-1-yong.liang.choong@linux.intel.com>
 <20240129130253.1400707-8-yong.liang.choong@linux.intel.com>
 <1fccbf0d-5b96-447b-80f1-19af70628edc@linux.intel.com>
Message-ID: <8fa87696-0c8d-405b-9e38-835d1ed65e90@linux.intel.com>



On 31/1/2024 6:54 pm, Ilpo J?rvinen wrote:
> On Mon, 29 Jan 2024, Choong Yong Liang wrote:
> 
>> From: "David E. Box" <david.e.box at linux.intel.com>
>>
>> - Exports intel_pmc_ipc() for host access to the PMC IPC mailbox
>> - Add support to use IPC command allows host to access SoC registers
>> through PMC firmware that are otherwise inaccessible to the host due to
>> security policies.
>>
>> Signed-off-by: David E. Box <david.e.box at linux.intel.com>
>> Signed-off-by: Chao Qin <chao.qin at intel.com>
>> Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
>> ---
>>   MAINTAINERS                                   |  2 +
>>   arch/x86/Kconfig                              |  9 +++
>>   arch/x86/platform/intel/Makefile              |  1 +
>>   arch/x86/platform/intel/pmc_ipc.c             | 75 +++++++++++++++++++
>>   .../linux/platform_data/x86/intel_pmc_ipc.h   | 34 +++++++++
>>   5 files changed, 121 insertions(+)
>>   create mode 100644 arch/x86/platform/intel/pmc_ipc.c
>>   create mode 100644 include/linux/platform_data/x86/intel_pmc_ipc.h
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 8709c7cd3656..441eb921edef 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -10973,8 +10973,10 @@ M:	Rajneesh Bhardwaj <irenic.rajneesh at gmail.com>
>>   M:	David E Box <david.e.box at intel.com>
>>   L:	platform-driver-x86 at vger.kernel.org
>>   S:	Maintained
>> +F:	arch/x86/platform/intel/pmc_ipc.c
>>   F:	Documentation/ABI/testing/sysfs-platform-intel-pmc
>>   F:	drivers/platform/x86/intel/pmc/
>> +F:	linux/platform_data/x86/intel_pmc_ipc.h
>>   
>>   INTEL PMIC GPIO DRIVERS
>>   M:	Andy Shevchenko <andy at kernel.org>
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index 5edec175b9bf..bceae28b9381 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -666,6 +666,15 @@ config X86_AMD_PLATFORM_DEVICE
>>   	  I2C and UART depend on COMMON_CLK to set clock. GPIO driver is
>>   	  implemented under PINCTRL subsystem.
>>   
>> +config INTEL_PMC_IPC
>> +	tristate "Intel Core SoC Power Management Controller IPC mailbox"
>> +	depends on ACPI
>> +	help
>> +	  This option enables sideband register access support for Intel SoC
>> +	  power management controller IPC mailbox.
>> +
>> +	  If you don't require the option or are in doubt, say N.
>> +
>>   config IOSF_MBI
>>   	tristate "Intel SoC IOSF Sideband support for SoC platforms"
>>   	depends on PCI
>> diff --git a/arch/x86/platform/intel/Makefile b/arch/x86/platform/intel/Makefile
>> index dbee3b00f9d0..470fc68de6ba 100644
>> --- a/arch/x86/platform/intel/Makefile
>> +++ b/arch/x86/platform/intel/Makefile
>> @@ -1,2 +1,3 @@
>>   # SPDX-License-Identifier: GPL-2.0-only
>>   obj-$(CONFIG_IOSF_MBI)			+= iosf_mbi.o
>> +obj-$(CONFIG_INTEL_PMC_IPC)		+= pmc_ipc.o
>> \ No newline at end of file
> 
> New line missing.
> 
> 
Thank you for letting me know.
I will fix it in the new patch series.


From yong.liang.choong at linux.intel.com  Thu Feb  1 19:06:01 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Fri, 2 Feb 2024 11:06:01 +0800
Subject: [PATCH net-next v4 08/11] stmmac: intel: configure SerDes
 according to the interface mode
In-Reply-To: <99d78f25-dd2a-4a52-4c2a-b0e29505a776@linux.intel.com>
References: <20240129130253.1400707-1-yong.liang.choong@linux.intel.com>
 <20240129130253.1400707-9-yong.liang.choong@linux.intel.com>
 <99d78f25-dd2a-4a52-4c2a-b0e29505a776@linux.intel.com>
Message-ID: <c0a87401-9f8b-4b60-b47d-31232873bba9@linux.intel.com>



On 31/1/2024 6:58 pm, Ilpo J?rvinen wrote:
> On Mon, 29 Jan 2024, Choong Yong Liang wrote:
> 
>> From: "Tan, Tee Min" <tee.min.tan at linux.intel.com>
>>
>> Intel platform will configure the SerDes through PMC api based on the
>> provided interface mode.
>>
>> This patch adds several new functions below:-
>> - intel_tsn_interface_is_available(): This new function reads FIA lane
>>    ownership registers and common lane registers through IPC commands
>>    to know which lane the mGbE port is assigned to.
>> - intel_config_serdes(): To configure the SerDes based on the assigned
>>    lane and latest interface mode, it sends IPC command to the PMC through
>>    PMC driver/API. The PMC acts as a proxy for R/W on behalf of the driver.
>> - intel_set_reg_access(): Set the register access to the available TSN
>>    interface.
>>
>> Signed-off-by: Tan, Tee Min <tee.min.tan at linux.intel.com>
>> Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
>> ---
>>   drivers/net/ethernet/stmicro/stmmac/Kconfig   |   1 +
>>   .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 113 +++++++++++++++++-
>>   .../net/ethernet/stmicro/stmmac/dwmac-intel.h |  75 ++++++++++++
>>   3 files changed, 188 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
>> index 85dcda51df05..be423fb2b46c 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
>> +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
>> @@ -273,6 +273,7 @@ config DWMAC_INTEL
>>   	default X86
>>   	depends on X86 && STMMAC_ETH && PCI
>>   	depends on COMMON_CLK
>> +	select INTEL_PMC_IPC
> 
> INTEL_PMC_IPC has depends on ACPI but selecting INTEL_PMC_IPC won't
> enforce it AFAIK.
> 
Hi Ilpo,

Thank you for pointing this out.
I will check on my side too.
Will fix it in the new patch series.


From yong.liang.choong at linux.intel.com  Thu Feb  1 19:07:40 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Fri, 2 Feb 2024 11:07:40 +0800
Subject: [PATCH net-next v3 4/5] net: stmmac: enable Intel mGbE 1G/2.5G
 auto-negotiation support
In-Reply-To: <07a4aa8e-800c-4564-81c8-7cfcdddf1379@lunn.ch>
References: <20230921121946.3025771-1-yong.liang.choong@linux.intel.com>
 <20230921121946.3025771-5-yong.liang.choong@linux.intel.com>
 <jmq54bskx4zd75ay4kf5pcdo6wnz72pxzfo5ivevleef4scucr@uw4fkfs64f3c>
 <26568944-563d-4911-8f6f-14c0162db6e9@linux.intel.com>
 <07a4aa8e-800c-4564-81c8-7cfcdddf1379@lunn.ch>
Message-ID: <46d14e3e-a334-447f-a25c-17ed58170741@linux.intel.com>



On 29/1/2024 9:41 pm, Andrew Lunn wrote:
> Hi Choong
> 
> Please trim the text when replying. It can be hard to find actually
> replies when having to do lots and lots of page downs. Just give the
> context needed to understand your reply.
> 
> 	Andrew
Hi Andrew,

Thank you for the feedback.
I will trim the message next time.


From liuyongqiang13 at huawei.com  Thu Feb  1 19:19:34 2024
From: liuyongqiang13 at huawei.com (Yongqiang Liu)
Date: Fri, 2 Feb 2024 11:19:34 +0800
Subject: [PATCH] arm: flush: don't abuse pfn_valid() to check if pfn is in
 RAM
In-Reply-To: <Zbtdue57RO0QScJM@linux.ibm.com>
References: <20240131125907.1006760-1-liuyongqiang13@huawei.com>
 <0da50102-3e87-49f7-b8f7-45cfcb4232d6@arm.com>
 <ZbqY12U/CXwAAu7A@shell.armlinux.org.uk>
 <edc4e8fa-af0a-46c2-bf07-20a0c4e20af5@arm.com>
 <8b50ca93-c164-ddfc-cd79-8f8525198a96@huawei.com>
 <Zbtdue57RO0QScJM@linux.ibm.com>
Message-ID: <de6d1d35-b334-f0b5-0780-59a87bcc6542@huawei.com>


? 2024/2/1 17:00, Mike Rapoport ??:
> Hi,
>
> Please don't top-post to Linux mailing lists.
>
> On Thu, Feb 01, 2024 at 04:00:04PM +0800, Yongqiang Liu wrote:
>> Very appreciate it for extra explanation. Notice that commit 024591f9a6e0
>>
>> ("arm: ioremap: don't abuse pfn_valid() to check if pfn is in RAM") use
>>
>> memblock_is_map_memory() instead of pfn_valid() to check if a PFN is in
>>
>> RAM or not, so I wrote the patch to solve this case.? Otherwise, when we
>>
>> use pageblock align(4M) address of memory or uio, like :
>>
>>  ???? node?? 0: [mem 0x00000000c0c00000-0x00000000cc8fffff]
>>  ???? node?? 0: [mem 0x00000000d0000000-0x00000000da1fffff]
>>
>> or uio address set like:
>>
>>  ?? 0xc0400000, 0x100000
>>
>> the pfn_valid will return false as memblock_is_map_memory.
> pfn_valid() should return false if and only if there is no struct page for
> that pfn.
>
> My understanding is that struct pages exist for the range of UIO addresses,
> and hopefully they have PG_reserved bit set, so a better fix IMO would be
> to check if the folio is !reserved.
>   

Thanks! All of the? UIO pages have PG_reserved bit set. I'm also 
confused about

whether other cases have the same issue like dma or someone using 
virt_addr_valid.

>> ? 2024/2/1 5:20, Robin Murphy ??:
>>> On 2024-01-31 7:00 pm, Russell King (Oracle) wrote:
>>>> On Wed, Jan 31, 2024 at 06:39:31PM +0000, Robin Murphy wrote:
>>>>> On 31/01/2024 12:59 pm, Yongqiang Liu wrote:
>>>>>> @@ -292,7 +293,7 @@ void __sync_icache_dcache(pte_t pteval)
>>>>>>  ?????????? /* only flush non-aliasing VIPT caches for exec mappings */
>>>>>>  ?????????? return;
>>>>>>  ?????? pfn = pte_pfn(pteval);
>>>>>> -??? if (!pfn_valid(pfn))
>>>>>> +??? if (!memblock_is_map_memory(PFN_PHYS(pfn)))
>>>>>>  ?????????? return;
>>>>>>  ?????? folio = page_folio(pfn_to_page(pfn));
>>>>> Hmm, it's a bit odd in context, since pfn_valid() obviously
>>>>> pairs with this
>>>>> pfn_to_page(), whereas it's not necessarily clear that
>>>>> memblock_is_map_memory() implies pfn_valid().
>>>>>
>>>>> However, in this case we're starting from a PTE - rather than
>>>>> going off to
>>>>> do a slow scan of memblock to determine whether a round-trip through
>>>>> page_address() is going to give back a mapped VA, can we not trivially
>>>>> identify that from whether the PTE itself is valid?
>>>> Depends what you mean by "valid". If you're referring to pte_valid()
>>>> and L_PTE_VALID then no.
>>>>
>>>> On 32-bit non-LPAE, the valid bit is the same as the present bit, and
>>>> needs to be set for the PTE to not fault. Any PTE that is mapping
>>>> something will be "valid" whether it is memory or not, whether it is
>>>> backed by a page or not.
>>>>
>>>> pfn_valid() should be telling us whether the PFN is suitable to be
>>>> passed to pfn_to_page(), and if we have a situation where pfn_valid()
>>>> returns true, but pfn_to_page() returns an invalid page, then that in
>>>> itself is a bug that needs to be fixed and probably has far reaching
>>>> implications for the stability of the kernel.
>>> Right, the problem here seems to be the opposite one, wherein we *do*
>>> often have a valid struct page for an address which is reserved and thus
>>> not mapped by the kernel, but seemingly we then take it down a path
>>> which assumes anything !PageHighmem() is lowmem and dereferences
>>> page_address() without looking.
>>>
>>> However I realise I should have looked closer at the caller, and my idea
>>> is futile since the PTE here is for a userspace mapping, not a kernel
>>> VA, and is already pte_valid_user() && !pte_special(). Plus the fact
>>> that the stack trace indicates an mmap() path suggests it most likely is
>>> a legitimate mapping of some no-map carveout or MMIO region. Oh well. My
>>> first point still stands, though - I think at least a comment to clarify
>>> that assumption would be warranted.
>>>
>>> Thanks,
>>> Robin.
>>> .


From pcc at google.com  Thu Feb  1 20:02:40 2024
From: pcc at google.com (Peter Collingbourne)
Date: Thu, 1 Feb 2024 20:02:40 -0800
Subject: [PATCH RFC v3 28/35] arm64: mte: swap: Handle tag restoring when
 missing tag storage
In-Reply-To: <20240125164256.4147-29-alexandru.elisei@arm.com>
References: <20240125164256.4147-1-alexandru.elisei@arm.com> <20240125164256.4147-29-alexandru.elisei@arm.com>
Message-ID: <CAMn1gO7M51QtxPxkRO3ogH1zasd2-vErWqoPTqGoPiEvr8Pvcw@mail.gmail.com>

On Thu, Jan 25, 2024 at 8:45?AM Alexandru Elisei
<alexandru.elisei at arm.com> wrote:
>
> Linux restores tags when a page is swapped in and there are tags associated
> with the swap entry which the new page will replace. The saved tags are
> restored even if the page will not be mapped as tagged, to protect against
> cases where the page is shared between different VMAs, and is tagged in
> some, but untagged in others. By using this approach, the process can still
> access the correct tags following an mprotect(PROT_MTE) on the non-MTE
> enabled VMA.
>
> But this poses a challenge for managing tag storage: in the scenario above,
> when a new page is allocated to be swapped in for the process where it will
> be mapped as untagged, the corresponding tag storage block is not reserved.
> mte_restore_page_tags_by_swp_entry(), when it restores the saved tags, will
> overwrite data in the tag storage block associated with the new page,
> leading to data corruption if the block is in use by a process.
>
> Get around this issue by saving the tags in a new xarray, this time indexed
> by the page pfn, and then restoring them when tag storage is reserved for
> the page.
>
> Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> ---
>
> Changes since rfc v2:
>
> * Restore saved tags **before** setting the PG_tag_storage_reserved bit to
> eliminate a brief window of opportunity where userspace can access uninitialized
> tags (Peter Collingbourne).
>
>  arch/arm64/include/asm/mte_tag_storage.h |   8 ++
>  arch/arm64/include/asm/pgtable.h         |  11 +++
>  arch/arm64/kernel/mte_tag_storage.c      |  12 ++-
>  arch/arm64/mm/mteswap.c                  | 110 +++++++++++++++++++++++
>  4 files changed, 140 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/mte_tag_storage.h b/arch/arm64/include/asm/mte_tag_storage.h
> index 50bdae94cf71..40590a8c3748 100644
> --- a/arch/arm64/include/asm/mte_tag_storage.h
> +++ b/arch/arm64/include/asm/mte_tag_storage.h
> @@ -36,6 +36,14 @@ bool page_is_tag_storage(struct page *page);
>
>  vm_fault_t handle_folio_missing_tag_storage(struct folio *folio, struct vm_fault *vmf,
>                                             bool *map_pte);
> +vm_fault_t mte_try_transfer_swap_tags(swp_entry_t entry, struct page *page);
> +
> +void tags_by_pfn_lock(void);
> +void tags_by_pfn_unlock(void);
> +
> +void *mte_erase_tags_for_pfn(unsigned long pfn);
> +bool mte_save_tags_for_pfn(void *tags, unsigned long pfn);
> +void mte_restore_tags_for_pfn(unsigned long start_pfn, int order);
>  #else
>  static inline bool tag_storage_enabled(void)
>  {
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 0174e292f890..87ae59436162 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -1085,6 +1085,17 @@ static inline void arch_swap_invalidate_area(int type)
>                 mte_invalidate_tags_area_by_swp_entry(type);
>  }
>
> +#ifdef CONFIG_ARM64_MTE_TAG_STORAGE
> +#define __HAVE_ARCH_SWAP_PREPARE_TO_RESTORE
> +static inline vm_fault_t arch_swap_prepare_to_restore(swp_entry_t entry,
> +                                                     struct folio *folio)
> +{
> +       if (tag_storage_enabled())
> +               return mte_try_transfer_swap_tags(entry, &folio->page);
> +       return 0;
> +}
> +#endif
> +
>  #define __HAVE_ARCH_SWAP_RESTORE
>  static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
>  {
> diff --git a/arch/arm64/kernel/mte_tag_storage.c b/arch/arm64/kernel/mte_tag_storage.c
> index afe2bb754879..ac7b9c9c585c 100644
> --- a/arch/arm64/kernel/mte_tag_storage.c
> +++ b/arch/arm64/kernel/mte_tag_storage.c
> @@ -567,6 +567,7 @@ int reserve_tag_storage(struct page *page, int order, gfp_t gfp)
>                 }
>         }
>
> +       mte_restore_tags_for_pfn(page_to_pfn(page), order);
>         page_set_tag_storage_reserved(page, order);
>  out_unlock:
>         mutex_unlock(&tag_blocks_lock);
> @@ -595,7 +596,8 @@ void free_tag_storage(struct page *page, int order)
>         struct tag_region *region;
>         unsigned long page_va;
>         unsigned long flags;
> -       int ret;
> +       void *tags;
> +       int i, ret;
>
>         ret = tag_storage_find_block(page, &start_block, &region);
>         if (WARN_ONCE(ret, "Missing tag storage block for pfn 0x%lx", page_to_pfn(page)))
> @@ -605,6 +607,14 @@ void free_tag_storage(struct page *page, int order)
>         /* Avoid writeback of dirty tag cache lines corrupting data. */
>         dcache_inval_tags_poc(page_va, page_va + (PAGE_SIZE << order));
>
> +       tags_by_pfn_lock();
> +       for (i = 0; i < (1 << order); i++) {
> +               tags = mte_erase_tags_for_pfn(page_to_pfn(page + i));
> +               if (unlikely(tags))
> +                       mte_free_tag_buf(tags);
> +       }
> +       tags_by_pfn_unlock();
> +
>         end_block = start_block + order_to_num_blocks(order, region->block_size_pages);
>
>         xa_lock_irqsave(&tag_blocks_reserved, flags);
> diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
> index 2a43746b803f..e11495fa3c18 100644
> --- a/arch/arm64/mm/mteswap.c
> +++ b/arch/arm64/mm/mteswap.c
> @@ -20,6 +20,112 @@ void mte_free_tag_buf(void *buf)
>         kfree(buf);
>  }
>
> +#ifdef CONFIG_ARM64_MTE_TAG_STORAGE
> +static DEFINE_XARRAY(tags_by_pfn);
> +
> +void tags_by_pfn_lock(void)
> +{
> +       xa_lock(&tags_by_pfn);
> +}
> +
> +void tags_by_pfn_unlock(void)
> +{
> +       xa_unlock(&tags_by_pfn);
> +}
> +
> +void *mte_erase_tags_for_pfn(unsigned long pfn)
> +{
> +       return __xa_erase(&tags_by_pfn, pfn);
> +}
> +
> +bool mte_save_tags_for_pfn(void *tags, unsigned long pfn)
> +{
> +       void *entry;
> +       int ret;
> +
> +       ret = xa_reserve(&tags_by_pfn, pfn, GFP_KERNEL);

copy_highpage can be called from an atomic context, so it isn't
currently valid to pass GFP_KERNEL here.

To give one example of a possible atomic context call, copy_pte_range
will take a PTE spinlock and can call copy_present_pte, which can call
copy_present_page, which will call copy_user_highpage.

To give another example, __buffer_migrate_folio can call
spin_lock(&mapping->private_lock), then call folio_migrate_copy, which
will call folio_copy.

Peter

> +       if (ret)
> +               return true;
> +
> +       tags_by_pfn_lock();
> +
> +       if (page_tag_storage_reserved(pfn_to_page(pfn))) {
> +               xa_release(&tags_by_pfn, pfn);
> +               tags_by_pfn_unlock();
> +               return false;
> +       }
> +
> +       entry = __xa_store(&tags_by_pfn, pfn, tags, GFP_ATOMIC);
> +       if (xa_is_err(entry)) {
> +               xa_release(&tags_by_pfn, pfn);
> +               goto out_unlock;
> +       } else if (entry) {
> +               mte_free_tag_buf(entry);
> +       }
> +
> +out_unlock:
> +       tags_by_pfn_unlock();
> +       return true;
> +}
> +
> +void mte_restore_tags_for_pfn(unsigned long start_pfn, int order)
> +{
> +       struct page *page = pfn_to_page(start_pfn);
> +       unsigned long pfn;
> +       void *tags;
> +
> +       tags_by_pfn_lock();
> +
> +       for (pfn = start_pfn; pfn < start_pfn + (1 << order); pfn++, page++) {
> +               tags = mte_erase_tags_for_pfn(pfn);
> +               if (unlikely(tags)) {
> +                       /*
> +                        * Mark the page as tagged so mte_sync_tags() doesn't
> +                        * clear the tags.
> +                        */
> +                       WARN_ON_ONCE(!try_page_mte_tagging(page));
> +                       mte_copy_page_tags_from_buf(page_address(page), tags);
> +                       set_page_mte_tagged(page);
> +                       mte_free_tag_buf(tags);
> +               }
> +       }
> +
> +       tags_by_pfn_unlock();
> +}
> +
> +/*
> + * Note on locking: swap in/out is done with the folio locked, which eliminates
> + * races with mte_save/restore_page_tags_by_swp_entry.
> + */
> +vm_fault_t mte_try_transfer_swap_tags(swp_entry_t entry, struct page *page)
> +{
> +       void *swap_tags, *pfn_tags;
> +       bool saved;
> +
> +       /*
> +        * mte_restore_page_tags_by_swp_entry() will take care of copying the
> +        * tags over.
> +        */
> +       if (likely(page_mte_tagged(page) || page_tag_storage_reserved(page)))
> +               return 0;
> +
> +       swap_tags = xa_load(&tags_by_swp_entry, entry.val);
> +       if (!swap_tags)
> +               return 0;
> +
> +       pfn_tags = mte_allocate_tag_buf();
> +       if (!pfn_tags)
> +               return VM_FAULT_OOM;
> +
> +       memcpy(pfn_tags, swap_tags, MTE_PAGE_TAG_STORAGE_SIZE);
> +       saved = mte_save_tags_for_pfn(pfn_tags, page_to_pfn(page));
> +       if (!saved)
> +               mte_free_tag_buf(pfn_tags);
> +
> +       return 0;
> +}
> +#endif
> +
>  int mte_save_page_tags_by_swp_entry(struct page *page)
>  {
>         void *tags, *ret;
> @@ -54,6 +160,10 @@ void mte_restore_page_tags_by_swp_entry(swp_entry_t entry, struct page *page)
>         if (!tags)
>                 return;
>
> +       /* Tags will be restored when tag storage is reserved. */
> +       if (tag_storage_enabled() && unlikely(!page_tag_storage_reserved(page)))
> +               return;
> +
>         if (try_page_mte_tagging(page)) {
>                 mte_copy_page_tags_from_buf(page_address(page), tags);
>                 set_page_mte_tagged(page);
> --
> 2.43.0
>


From dawei.li at shingroup.cn  Thu Feb  1 20:02:11 2024
From: dawei.li at shingroup.cn (Dawei Li)
Date: Fri,  2 Feb 2024 12:02:11 +0800
Subject: [PATCH] arm64: remove unneeded BUILD_BUG_ON assertion
Message-ID: <20240202040211.3118918-1-dawei.li@shingroup.cn>

Since commit c02433dd6de3 ("arm64: split thread_info from task stack"),
CONFIG_THREAD_INFO_IN_TASK is enabled unconditionally for arm64. So
remove this always-true assertion from arch_dup_task_struct.

Signed-off-by: Dawei Li <dawei.li at shingroup.cn>
---
 arch/arm64/kernel/process.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 7387b68c745b..4ae31b7af6c3 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -290,9 +290,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 		fpsimd_preserve_current_state();
 	*dst = *src;
 
-	/* We rely on the above assignment to initialize dst's thread_flags: */
-	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 copies
-- 
2.27.0



From sfr at canb.auug.org.au  Thu Feb  1 20:05:07 2024
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Fri, 2 Feb 2024 15:05:07 +1100
Subject: linux-next: duplicate patch in the tegra tree
Message-ID: <20240202150507.468210de@canb.auug.org.au>

Hi all,

The following commit is also in arm-soc-fixes tree as a different commit
(but the same patch):

  d820100a1bde ("soc/tegra: Fix build failure on Tegra241")

this is commit

  1b5af823d703 ("soc/tegra: fix build failure on Tegra241")

in the arm-soc-fixes tree.

-- 
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/20240202/ca45982c/attachment.sig>

From r-gunasekaran at ti.com  Thu Feb  1 20:46:47 2024
From: r-gunasekaran at ti.com (Ravi Gunasekaran)
Date: Fri, 2 Feb 2024 10:16:47 +0530
Subject: [PATCH v3 0/3] Add AM64x ICSSG Ethernet support
In-Reply-To: <20240122113045.1711818-1-danishanwar@ti.com>
References: <20240122113045.1711818-1-danishanwar@ti.com>
Message-ID: <d40671cc-6e5d-461c-a1cf-3482a545042c@ti.com>



On 1/22/2024 5:00 PM, MD Danish Anwar wrote:
> Hi All,
>
> This series adds support for ICSSG ethernet on AM64x. 
> This series is based on the latest next-20231211 linux-next.
>
> AM64x EVM has three ethernet ports. One is dedicated to CPSW and one is
> dedicated to ICSSG1. The remaining port is muxed between CPSW and ICSSG1
> ICSSG1 ports. The ICSSG1 node is added in the k3-am642-evm.dts. By default
> the muxed port is used by CPSW so 2nd ICSSG1 port is disabled in the
> k3-am642-evm.dts. But overlay k3-am642-evm-icssg1-dualemac.dtso can be
> applied to use muxed port as ICSSG1.
>
> This is the v3 of the series [v1].
>
> Changes from v2 to v3:
> *) No functional changes.
> *) Rebased on latest linux-next (next-20240122) after 6.8-rc1.
>
> Changes from v1 to v2:
> *) Fixed aliases section in k3-am642-evm.dts
> *) Fixed firmware-names in k3-am642-evm.dts
> *) Changed icssg1_phy1 to ethernet-phy at f from ethernet-phy at 0 as suggested
>    by Andrew L.
> *) Changed makefile to handle overlays using CONFIG_OF_ALL_DTBS as
>    suggested by Nishant and Andrew Davis.
> *) Fixed aliases section in k3-am642-evm-icssg1-dualemac.dtso
> *) Fixed pinctrl in k3-am642-evm-icssg1-dualemac.dtso
> *) Updated commit message of patch 3/3 of the series to warn about adding
>    label name to 'mdio-mux-1' node.
>
> [v1] https://lore.kernel.org/all/20231207081917.340167-1-danishanwar at ti.com/
> [v2] https://lore.kernel.org/all/20231212165832.3933335-1-danishanwar at ti.com/
>

For the series,
Reviewed-by: Ravi Gunasekaran <r-gunasekaran at ti.com>


From quic_jjohnson at quicinc.com  Thu Feb  1 20:50:59 2024
From: quic_jjohnson at quicinc.com (Jeff Johnson)
Date: Thu, 1 Feb 2024 20:50:59 -0800
Subject: [PATCH 4/9] PCI: create platform devices for child OF nodes of
 the port node
In-Reply-To: <oiwvcvu6wdmpvhss3t7uaqkl5q73mki5pz6liuv66bap4dr2mp@jtjjwzlvt6za>
References: <20240117160748.37682-1-brgl@bgdev.pl>
 <20240117160748.37682-5-brgl@bgdev.pl>
 <2024011707-alibi-pregnancy-a64b@gregkh>
 <CAMRc=Mef7wxRccnfQ=EDLckpb1YN4DNLoC=AYL8v1LLJ=uFH2Q@mail.gmail.com>
 <2024011836-wok-treadmill-c517@gregkh>
 <d2he3ufg6m46zos4swww4t3peyq55blxhirsx37ou37rwqxmz2@5khumvic62je>
 <CAMRc=MeXJjpJhDjyn_P-SGo4rDnEuT9kGN5jAbRcuM_c7_aDzQ@mail.gmail.com>
 <oiwvcvu6wdmpvhss3t7uaqkl5q73mki5pz6liuv66bap4dr2mp@jtjjwzlvt6za>
Message-ID: <39779388-9aad-43fd-9ede-271ead40cbf7@quicinc.com>

On 2/1/2024 4:03 PM, Bjorn Andersson wrote:
> On Wed, Jan 31, 2024 at 12:04:14PM +0100, Bartosz Golaszewski wrote:
>> On Tue, Jan 30, 2024 at 10:54?PM Bjorn Andersson <andersson at kernel.org> wrote:
>>>
>>> On Thu, Jan 18, 2024 at 12:15:27PM +0100, Greg Kroah-Hartman wrote:
>>>> On Thu, Jan 18, 2024 at 11:58:50AM +0100, Bartosz Golaszewski wrote:
>>>>> On Wed, Jan 17, 2024 at 5:45?PM Greg Kroah-Hartman
>>>>> <gregkh at linuxfoundation.org> wrote:
>>>>>>
>>>>>> On Wed, Jan 17, 2024 at 05:07:43PM +0100, Bartosz Golaszewski wrote:
>>>>>>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>>>>>>
>>>>>>> In order to introduce PCI power-sequencing, we need to create platform
>>>>>>> devices for child nodes of the port node.
>>>>>>
>>>>>> Ick, why a platform device?  What is the parent of this device, a PCI
>>>>>> device?  If so, then this can't be a platform device, as that's not what
>>>>>> it is, it's something else so make it a device of that type,.
>>>>>>
>>>>>
>>>>> Greg,
>>>>>
>>>>> This is literally what we agreed on at LPC. In fact: during one of the
>>>>> hall track discussions I said that you typically NAK any attempts at
>>>>> using the platform bus for "fake" devices but you responded that this
>>>>> is what the USB on-board HUB does and while it's not pretty, this is
>>>>> what we need to do.
>>>>
>>>> Ah, you need to remind me of these things, this changelog was pretty
>>>> sparse :)
>>>>
>>>
>>> I believe I missed this part of the discussion, why does this need to be
>>> a platform_device? What does the platform_bus bring that can't be
>>> provided by some other bus?
>>>
>>
>> Does it need to be a platform_device? No, of course not. Does it make
>> sense for it to be one? Yes, for two reasons:
>>
>> 1. The ATH11K WLAN module is represented on the device tree like a
>> platform device, we know it's always there and it consumes regulators
>> from another platform device. The fact it uses PCIe doesn't change the
>> fact that it is logically a platform device.
> 
> Are you referring to the ath11k SNOC (firmware running on co-processor
> in the SoC) variant?
> 
> Afaict the PCIe-attached ath11k is not represented as a platform_device
> in DeviceTree.

Are you considering out-of-tree drivers? My understanding is that there
are different PCIe modules, ones that don't have GPIO-control for x86
and ones that do have GPIO-control for ARM. The out-of-tree cnss
platform driver used for Android has a large amount of DT control
<https://git.codelinaro.org/clo/la/platform/vendor/qcom-opensource/wlan/platform/-/blob/wlan-platform.lnx.1.0.r1-rel/cnss2/power.c?ref_type=heads>

(not sure off hand where the DT files themselves are)

/jeff


From a-bhatia1 at ti.com  Thu Feb  1 21:16:32 2024
From: a-bhatia1 at ti.com (Aradhya Bhatia)
Date: Fri, 2 Feb 2024 10:46:32 +0530
Subject: [RESEND PATCH v2] arm64: dts: ti: k3-am69-sk: remove
 assigned-clock-parents for unused VP
In-Reply-To: <20240201142308.4954-1-j-choudhary@ti.com>
References: <20240201142308.4954-1-j-choudhary@ti.com>
Message-ID: <92d7de31-2c14-469d-8da8-11bb70ea2707@ti.com>



On 01-Feb-24 19:53, Jayesh Choudhary wrote:
> VP2 and VP3 are unused video ports and VP3 share the same parent
> clock as VP1 causing issue with pixel clock setting for HDMI (VP1).
> The current DM firmware does not support changing parent clock if it
> is shared by another component. It returns 0 for the determine_rate
> query before causing set_rate to set the clock at default maximum of
> 1.8GHz which is a lot more than the maximum frequency videoports can
> support (600MHz) causing SYNC LOST issues.
> So remove the parent clocks for unused VPs to avoid conflict.
> 
> Fixes: 6f8605fd7d11 ("arm64: dts: ti: k3-am69-sk: Add DP and HDMI support")
> Reported-by: Nishanth Menon <nm at ti.com>
> Signed-off-by: Jayesh Choudhary <j-choudhary at ti.com>
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>

Reviewed-by: Aradhya Bhatia <a-bhatia1 at ti.com>

Regards
Aradhya

> ---
> 
> v1: <https://lore.kernel.org/all/20231221113042.48492-1-j-choudhary at ti.com/>
> 
> Changelog v1->v2:
> - Updated commit message
> - Picked up Tomi's R-by from v1
> - Removed "Closes:" link since its invalid now
> 
> (NOTE: Sending again as forgot to put mailing list in cc earlier)
> 
>  arch/arm64/boot/dts/ti/k3-am69-sk.dts | 8 ++------
>  1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> index 8da591579868..370980eb59b0 100644
> --- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> @@ -918,13 +918,9 @@ &dss {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&dss_vout0_pins_default>;
>  	assigned-clocks = <&k3_clks 218 2>,
> -			  <&k3_clks 218 5>,
> -			  <&k3_clks 218 14>,
> -			  <&k3_clks 218 18>;
> +			  <&k3_clks 218 5>;
>  	assigned-clock-parents = <&k3_clks 218 3>,
> -				 <&k3_clks 218 7>,
> -				 <&k3_clks 218 16>,
> -				 <&k3_clks 218 22>;
> +				 <&k3_clks 218 7>;
>  };
>  
>  &serdes_wiz4 {


From hbathini at linux.ibm.com  Thu Feb  1 21:23:23 2024
From: hbathini at linux.ibm.com (Hari Bathini)
Date: Fri, 2 Feb 2024 10:53:23 +0530
Subject: [PATCH v2 00/14] Split crash out from kexec and clean up related
 config items
In-Reply-To: <20240119145241.769622-1-bhe@redhat.com>
References: <20240119145241.769622-1-bhe@redhat.com>
Message-ID: <9101bb07-70f1-476c-bec9-ec67e9899744@linux.ibm.com>

Hi Baoquan,

On 19/01/24 8:22 pm, Baoquan He wrote:
> Motivation:
> =============
> Previously, LKP reported a building error. When investigating, it can't
> be resolved reasonablly with the present messy kdump config items.
> 
>   https://lore.kernel.org/oe-kbuild-all/202312182200.Ka7MzifQ-lkp at intel.com/
> 
> The kdump (crash dumping) related config items could causes confusions:
> 
> Firstly,
> ---
> CRASH_CORE enables codes including
>   - crashkernel reservation;
>   - elfcorehdr updating;
>   - vmcoreinfo exporting;
>   - crash hotplug handling;
> 
> Now fadump of powerpc, kcore dynamic debugging and kdump all selects
> CRASH_CORE, while fadump
>   - fadump needs crashkernel parsing, vmcoreinfo exporting, and accessing
>     global variable 'elfcorehdr_addr';
>   - kcore only needs vmcoreinfo exporting;
>   - kdump needs all of the current kernel/crash_core.c.
> 
> So only enabling PROC_CORE or FA_DUMP will enable CRASH_CORE, this
> mislead people that we enable crash dumping, actual it's not.
> 
> Secondly,
> ---
> It's not reasonable to allow KEXEC_CORE select CRASH_CORE.
> 
> Because KEXEC_CORE enables codes which allocate control pages, copy
> kexec/kdump segments, and prepare for switching. These codes are
> shared by both kexec reboot and kdump. We could want kexec reboot,
> but disable kdump. In that case, CRASH_CORE should not be selected.
> 
>   --------------------
>   CONFIG_CRASH_CORE=y
>   CONFIG_KEXEC_CORE=y
>   CONFIG_KEXEC=y
>   CONFIG_KEXEC_FILE=y
>      ---------------------
> 
> Thirdly,
> ---
> It's not reasonable to allow CRASH_DUMP select KEXEC_CORE.
> 
> That could make KEXEC_CORE, CRASH_DUMP are enabled independently from
> KEXEC or KEXEC_FILE. However, w/o KEXEC or KEXEC_FILE, the KEXEC_CORE
> code built in doesn't make any sense because no kernel loading or
> switching will happen to utilize the KEXEC_CORE code.
>   ---------------------
>   CONFIG_CRASH_CORE=y
>   CONFIG_KEXEC_CORE=y
>   CONFIG_CRASH_DUMP=y
>   ---------------------
> 
> In this case, what is worse, on arch sh and arm, KEXEC relies on MMU,
> while CRASH_DUMP can still be enabled when !MMU, then compiling error is
> seen as the lkp test robot reported in above link.
> 
>   ------arch/sh/Kconfig------
>   config ARCH_SUPPORTS_KEXEC
>           def_bool MMU
> 
>   config ARCH_SUPPORTS_CRASH_DUMP
>           def_bool BROKEN_ON_SMP
>   ---------------------------
> 
> Changes:
> ===========
> 1, split out crash_reserve.c from crash_core.c;
> 2, split out vmcore_infoc. from crash_core.c;
> 3, move crash related codes in kexec_core.c into crash_core.c;
> 4, remove dependency of FA_DUMP on CRASH_DUMP;
> 5, clean up kdump related config items;
> 6, wrap up crash codes in crash related ifdefs on all 9 arch-es
>     which support crash dumping;
> 
> Achievement:
> ===========
> With above changes, I can rearrange the config item logic as below (the right
> item depends on or is selected by the left item):
> 
>      PROC_KCORE -----------> VMCORE_INFO
> 
>                 |----------> VMCORE_INFO
>      FA_DUMP----|
>                 |----------> CRASH_RESERVE

FA_DUMP also needs PROC_VMCORE (CRASH_DUMP by dependency, I guess).
So, the FA_DUMP related changes here will need a relook..


>                                                      ---->VMCORE_INFO
>                                                     /
>                                                     |---->CRASH_RESERVE
>      KEXEC      --|                                /|
>                   |--> KEXEC_CORE--> CRASH_DUMP-->/-|---->PROC_VMCORE
>      KEXEC_FILE --|                               \ |
>                                                     \---->CRASH_HOTPLUG
> 
> 
>      KEXEC      --|
>                   |--> KEXEC_CORE (for kexec reboot only)
>      KEXEC_FILE --|
> 
> Test
> ========
> On all 8 architectures, including x86_64, arm64, s390x, sh, arm, mips,
> riscv, loongarch, I did below three cases of config item setting and
> building all passed. Let me take configs on x86_64 as exampmle here:
> 
> (1) Both CONFIG_KEXEC and KEXEC_FILE is unset, then all kexec/kdump
> items are unset automatically:
> # Kexec and crash features
> # CONFIG_KEXEC is not set
> # CONFIG_KEXEC_FILE is not set
> # end of Kexec and crash features
> 
> (2) set CONFIG_KEXEC_FILE and 'make olddefconfig':
> ---------------
> # Kexec and crash features
> CONFIG_CRASH_RESERVE=y
> CONFIG_VMCORE_INFO=y
> CONFIG_KEXEC_CORE=y
> CONFIG_KEXEC_FILE=y
> CONFIG_CRASH_DUMP=y
> CONFIG_CRASH_HOTPLUG=y
> CONFIG_CRASH_MAX_MEMORY_RANGES=8192
> # end of Kexec and crash features
> ---------------
> 
> (3) unset CONFIG_CRASH_DUMP in case 2 and execute 'make olddefconfig':
> ------------------------
> # Kexec and crash features
> CONFIG_KEXEC_CORE=y
> CONFIG_KEXEC_FILE=y
> # end of Kexec and crash features
> ------------------------
> 
> Note:
> For ppc, it needs investigation to make clear how to split out crash
> code in arch folder.

On powerpc, both kdump and fadump need PROC_VMCORE & CRASH_DUMP.
Hope that clears things. So, patch 3/14 breaks things for FA_DUMP..

> Hope Hari and Pingfan can help have a look, see if
> it's doable. Now, I make it either have both kexec and crash enabled, or
> disable both of them altogether.


Sure. I will take a closer look...

Thanks
Hari


From masahiroy at kernel.org  Thu Feb  1 21:37:27 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Fri, 2 Feb 2024 14:37:27 +0900
Subject: [PATCH v9 2/2] arm64: boot: Support Flat Image Tree
In-Reply-To: <CAL_JsqLeTDALoKBuk9r+4NGXo0pc9LbK6bhDiZET+=UHG60fEA@mail.gmail.com>
References: <20231202035511.487946-1-sjg@chromium.org> <20231202035511.487946-3-sjg@chromium.org>
 <20231213121353.GA31326@willie-the-truck> <CAFLszTjfmSx1YMqzb2TsQf7sP4KrcQB=X7DY_HxRQp0J5HAppQ@mail.gmail.com>
 <CAK7LNAQRCDC03e=TVO=k4FuD2a2RdTy7yLr3UptQjVCX7pM1CA@mail.gmail.com>
 <20240109143349.GR1610741@bill-the-cat> <CAFLszTjwhy24UiT6kUJABMC1Xn0h9Q1q9fYpZZJg9DX8Vss9cA@mail.gmail.com>
 <CAFLszTjPAHd6RdO1mvatXC=yRS+h=sgJ_pMdyEnkROTx7yRpog@mail.gmail.com>
 <CAK7LNARsY6-rrx=sNFq6oFqpqf0s5S_=3DrUsCOS7zF0BXcoTg@mail.gmail.com>
 <CAL_JsqLYB0D5wAfedsb6tQp4EmD1AROgxiCncwO7gvA2p1C6Lg@mail.gmail.com>
 <CAK7LNAR-3rL6=YdhRRXB9dz+94y2yHTA=9mF4p7OPj7KExd7rg@mail.gmail.com> <CAL_JsqLeTDALoKBuk9r+4NGXo0pc9LbK6bhDiZET+=UHG60fEA@mail.gmail.com>
Message-ID: <CAK7LNARSHiNGwHy4Tocbfkgyio1SbHV6sRJCA7yTrcTOXYEQHQ@mail.gmail.com>

On Fri, Feb 2, 2024 at 6:03?AM Rob Herring <robh at kernel.org> wrote:
>
> On Wed, Jan 31, 2024 at 8:09?PM Masahiro Yamada <masahiroy at kernel.org> wrote:
> >
> > On Thu, Feb 1, 2024 at 7:03?AM Rob Herring <robh at kernel.org> wrote:
> > >
> > > On Tue, Jan 30, 2024 at 3:16?AM Masahiro Yamada <masahiroy at kernel.org> wrote:
> > > >
> > > > On Fri, Jan 26, 2024 at 1:04?AM Simon Glass <sjg at chromium.org> wrote:
> > > > >
> > > > > Hi,
> > > > >
> > > > > On Wed, 17 Jan 2024 at 06:14, Simon Glass <sjg at chromium.org> wrote:
> > > > > >
> > > > > > Hi Masahiro, Tom,
> > > > > >
> > > > > > On Tue, 9 Jan 2024 at 07:33, Tom Rini <trini at konsulko.com> wrote:
> > > > > > >
> > > > > > > On Tue, Jan 09, 2024 at 11:01:42PM +0900, Masahiro Yamada wrote:
> > > > > > > > Hi Simon,
> > > > > > > >
> > > > > > > >
> > > > > > > > On Wed, Jan 3, 2024 at 8:47?AM Simon Glass <sjg at chromium.org> wrote:
> > > > > > > > >
> > > > > > > > > Hi Masahiro,
> > > > > > > > >
> > > > > > > > > On Wed, Dec 13, 2023 at 5:14?AM Will Deacon <will at kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > On Fri, Dec 01, 2023 at 08:54:42PM -0700, Simon Glass wrote:
> > > > > > > > > > > Add a script which produces a Flat Image Tree (FIT), a single file
> > > > > > > > > > > containing the built kernel and associated devicetree files.
> > > > > > > > > > > Compression defaults to gzip which gives a good balance of size and
> > > > > > > > > > > performance.
> > > > > > > > > > >
> > > > > > > > > > > The files compress from about 86MB to 24MB using this approach.
> > > > > > > > > > >
> > > > > > > > > > > The FIT can be used by bootloaders which support it, such as U-Boot
> > > > > > > > > > > and Linuxboot. It permits automatic selection of the correct
> > > > > > > > > > > devicetree, matching the compatible string of the running board with
> > > > > > > > > > > the closest compatible string in the FIT. There is no need for
> > > > > > > > > > > filenames or other workarounds.
> > > > > > > > > > >
> > > > > > > > > > > Add a 'make image.fit' build target for arm64, as well. Use
> > > > > > > > > > > FIT_COMPRESSION to select a different algorithm.
> > > > > > > > > > >
> > > > > > > > > > > The FIT can be examined using 'dumpimage -l'.
> > > > > > > > > > >
> > > > > > > > > > > This features requires pylibfdt (use 'pip install libfdt'). It also
> > > > > > > > > > > requires compression utilities for the algorithm being used. Supported
> > > > > > > > > > > compression options are the same as the Image.xxx files. For now there
> > > > > > > > > > > is no way to change the compression other than by editing the rule for
> > > > > > > > > > > $(obj)/image.fit
> > > > > > > > > > >
> > > > > > > > > > > While FIT supports a ramdisk / initrd, no attempt is made to support
> > > > > > > > > > > this here, since it must be built separately from the Linux build.
> > > > > > > > > > >
> > > > > > > > > > > Signed-off-by: Simon Glass <sjg at chromium.org>
> > > > > > > > > > > ---
> > > > > > > > > > >
> > > > > > > > > > > Changes in v9:
> > > > > > > > > > > - Move the compression control into Makefile.lib
> > > > > > > > > > >
> > > > > > > > > > > Changes in v8:
> > > > > > > > > > > - Drop compatible string in FDT node
> > > > > > > > > > > - Correct sorting of MAINTAINERS to before ARM64 PORT
> > > > > > > > > > > - Turn compress part of the make_fit.py comment in to a sentence
> > > > > > > > > > > - Add two blank lines before parse_args() and setup_fit()
> > > > > > > > > > > - Use 'image.fit: dtbs' instead of BUILD_DTBS var
> > > > > > > > > > > - Use '$(<D)/dts' instead of '$(dir $<)dts'
> > > > > > > > > > > - Add 'mkimage' details Documentation/process/changes.rst
> > > > > > > > > > > - Allow changing the compression used
> > > > > > > > > > > - Tweak cover letter since there is only one clean-up patch
> > > > > > > > > > >
> > > > > > > > > > > Changes in v7:
> > > > > > > > > > > - Add Image as a dependency of image.fit
> > > > > > > > > > > - Drop kbuild tag
> > > > > > > > > > > - Add dependency on dtbs
> > > > > > > > > > > - Drop unnecessary path separator for dtbs
> > > > > > > > > > > - Rebase to -next
> > > > > > > > > > >
> > > > > > > > > > > Changes in v5:
> > > > > > > > > > > - Drop patch previously applied
> > > > > > > > > > > - Correct compression rule which was broken in v4
> > > > > > > > > > >
> > > > > > > > > > > Changes in v4:
> > > > > > > > > > > - Use single quotes for UIMAGE_NAME
> > > > > > > > > > >
> > > > > > > > > > > Changes in v3:
> > > > > > > > > > > - Drop temporary file image.itk
> > > > > > > > > > > - Drop patch 'Use double quotes for image name'
> > > > > > > > > > > - Drop double quotes in use of UIMAGE_NAME
> > > > > > > > > > > - Drop unnecessary CONFIG_EFI_ZBOOT condition for help
> > > > > > > > > > > - Avoid hard-coding "arm64" for the DT architecture
> > > > > > > > > > >
> > > > > > > > > > > Changes in v2:
> > > > > > > > > > > - Drop patch previously applied
> > > > > > > > > > > - Add .gitignore file
> > > > > > > > > > > - Move fit rule to Makefile.lib using an intermediate file
> > > > > > > > > > > - Drop dependency on CONFIG_EFI_ZBOOT
> > > > > > > > > > > - Pick up .dtb files separately from the kernel
> > > > > > > > > > > - Correct pylint too-many-args warning for write_kernel()
> > > > > > > > > > > - Include the kernel image in the file count
> > > > > > > > > > > - Add a pointer to the FIT spec and mention of its wide industry usage
> > > > > > > > > > > - Mention the kernel version in the FIT description
> > > > > > > > > > >
> > > > > > > > > > >  Documentation/process/changes.rst |   9 +
> > > > > > > > > > >  MAINTAINERS                       |   7 +
> > > > > > > > > > >  arch/arm64/Makefile               |   7 +-
> > > > > > > > > > >  arch/arm64/boot/.gitignore        |   1 +
> > > > > > > > > > >  arch/arm64/boot/Makefile          |   6 +-
> > > > > > > > > > >  scripts/Makefile.lib              |  16 ++
> > > > > > > > > > >  scripts/make_fit.py               | 291 ++++++++++++++++++++++++++++++
> > > > > > > > > > >  7 files changed, 334 insertions(+), 3 deletions(-)
> > > > > > > > > > >  create mode 100755 scripts/make_fit.py
> > > > > > > > > >
> > > > > > > > > > I'll need Masahiro's Ack on the scripts/ changes before I can take this
> > > > > > > > > > one.
> > > > > > > > >
> > > > > > > > > Any thoughts on this request, please?
> > > > > > > > >
> > > > > > > > > Regards,
> > > > > > > > > Simon
> > > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > As I mentioned before, I am concerned with having
> > > > > > > > the same "compatible" entries, with different contents,
> > > > > > > > as you use the "compatible" string as an ID to selecting
> > > > > > > > the target config node, right?
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > $ fdtdump  arch/arm64/boot/image.fit
> > > > > > > >
> > > > > > > >         ...
> > > > > > > >
> > > > > > > >         conf-10 {
> > > > > > > >             compatible = "tq,am642-tqma6442l-mbax4xxl",
> > > > > > > > "tq,am642-tqma6442l", "ti,am642";
> > > > > > > >             description = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > > > > >             fdt = "fdt-10";
> > > > > > > >             kernel = "kernel";
> > > > > > > >         };
> > > > > > > >
> > > > > > > >         ...
> > > > > > > >
> > > > > > > >         conf-25 {
> > > > > > > >             compatible = "tq,am642-tqma6442l-mbax4xxl",
> > > > > > > > "tq,am642-tqma6442l", "ti,am642";
> > > > > > > >             description = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > > > > >             fdt = "fdt-25";
> > > > > > > >             kernel = "kernel";
> > > > > > > >         };
> > > > > > >
> > > > > > > I had asked Rob a while ago about if having the same compatible for two
> > > > > > > functionally different machines is a feature, or a bug, and I don't
> > > > > > > think either of us fully agreed either way. I'd be leaning towards
> > > > > > > saying the above example is a bug in the dts files, it's just not been a
> > > > > > > bug people have worried about before due to (sadly) how little the
> > > > > > > top-level compatible has been used.
> > >
> > > I much prefer being able to use compatibles over filenames.
> > >
> > > > > >
> > > > > > Yes I believe this is a bug in the files.
> > > > > >
> > > > > > What should the script do in this case? Print a warning, perhaps?
> > > > >
> > > > > Is there anything I should do here? Would a warning be helpful, or
> > > > > just confusing?
> > > >
> > > >
> > > >
> > > > I do not think it is useful.
> > > > You would almost always get a warning, and there is no way to fix it.
> > >
> > > The above case is due to overlays. Why would you have a FIT image with
> > > both a base tree and applied overlays?
> >
> >
> >
> > Because they are different hardware.
>
> Meaning the base tree is valid on its own without any overlays?



If the base board is directly added to dtb-y, we need to assume
it is valid as a standalone board.


k3-am654-gp-evm-dtbs is a base of other composite DTBs, and
it is also added to dtb-y.


dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb



Not only the base board.


There are multiple composite DTBs that have the same compatible string.


k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb
k3-am654-base-board-rocktech-rk101-panel.dtbo
k3-am654-evm-dtbs := k3-am654-base-board.dtb k3-am654-icssg2.dtbo



k3-am654-base-board.dtb, k3-am654-gp-evm-dtbs, and k3-am654-evm-dtbs
have the same top-level compatible string.




>
> > If FIT includes only base DTBs, how to use a base with extensions?
>
> I would expect that you package up base and overlays or DTs with
> already applied overlays, but not both together. That would be based
> on whether your bootloader can apply overlays or not.


Correct.



> This problem boils down to your firmware knows or gains the knowledge
> of some set of extra features or h/w pop options. The result is you
> need base plus X, Y, Z whether those are a list of overlays or an
> encoding of filename or something else. For example, FIT entries could
> have a field that just lists those X, Y, Z features. But I'd much
> rather have something that works outside of FIT images.
>
> > > In any case, maybe we need to record in dtb overlays that have been
> > > applied (which you asked about recently on dtc list). Not sure what
> > > that looks like though. Overlays have a 'top-level' compatible that we
> > > add in either separately or merged with the base's top-level
> > > compatible?
> >
> >
> > If there is a way to make "compatible" unique, that will be good.
> >
> > But, in my understanding, we can replace a property value,
> > but not modify it.
>
> Currently yes, but that shouldn't be too hard to add. The dtc
> modification is the easy part. The hard part is figuring out the
> policy around how we would use that.
>
> But I don't really know what you want to accomplish with FIT here.
> IMO, if you need filenames, then use a filesystem. They work pretty
> well for storing large collections of files.


Whom does the term "you" point to?

If you have questions about the motivation for this patch,
ask its author.



There are two ways to look up the config node;
node-name or compatible string.

The key-value lookup works only when the key is unique.

Apparently, the compatible string is not unique
when overlay comes into play.







>
> Rob

--
Best Regards
Masahiro Yamada


From peng.fan at oss.nxp.com  Thu Feb  1 22:34:38 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 02 Feb 2024 14:34:38 +0800
Subject: [PATCH 0/5] firmware: support i.MX95 SCMI BBM/MISC Extenstion
Message-ID: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>

i.MX95 System Manager Firmware support vendor extension protocol:
- BBM Protocol for RTC and BUTTON feature.
- MISC Protocol for misc settings, such as BLK CTRL GPR settings, GPIO
expander settings.

This patchset is to support the two protocols and users that use the
protocols.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Peng Fan (5):
      dt-bindings: firmware: add i.MX SCMI Extension protocol
      firmware: arm_scmi: add initial support for i.MX BBM protocol
      firmware: arm_scmi: add initial support for i.MX MISC protocol
      firmware: imx: support BBM module
      firmware: imx: add i.MX95 MISC driver

 .../devicetree/bindings/firmware/nxp,scmi.yaml     |  64 ++++
 drivers/firmware/arm_scmi/Kconfig                  |  20 ++
 drivers/firmware/arm_scmi/Makefile                 |   2 +
 drivers/firmware/arm_scmi/imx-sm-bbm.c             | 381 +++++++++++++++++++++
 drivers/firmware/arm_scmi/imx-sm-misc.c            | 289 ++++++++++++++++
 drivers/firmware/imx/Makefile                      |   2 +
 drivers/firmware/imx/sm-bbm.c                      | 317 +++++++++++++++++
 drivers/firmware/imx/sm-misc.c                     |  92 +++++
 include/linux/firmware/imx/sm.h                    |  33 ++
 include/linux/scmi_nxp_protocol.h                  |  67 ++++
 10 files changed, 1267 insertions(+)
---
base-commit: 51b70ff55ed88edd19b080a524063446bcc34b62
change-id: 20240202-imx95-bbm-misc-d4a27c159823

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Thu Feb  1 22:34:39 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 02 Feb 2024 14:34:39 +0800
Subject: [PATCH 1/5] dt-bindings: firmware: add i.MX SCMI Extension
 protocol
In-Reply-To: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
Message-ID: <20240202-imx95-bbm-misc-v1-1-3cb743020933@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add i.MX SCMI Extension protocol BBM and MISC binding.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/firmware/nxp,scmi.yaml     | 64 ++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/nxp,scmi.yaml b/Documentation/devicetree/bindings/firmware/nxp,scmi.yaml
new file mode 100644
index 000000000000..00d6361bbbea
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/nxp,scmi.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2024 NXP
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/nxp,scmi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX System Control and Management Interface (SCMI) Protocol Extension
+
+maintainers:
+  - Peng Fan <peng.fan at nxp.com>
+
+allOf:
+  - $ref: arm,scmi.yaml#
+
+properties:
+  protocol at 11:
+    $ref: 'arm,scmi.yaml#/$defs/protocol-node'
+    unevaluatedProperties: false
+
+    properties:
+      reg:
+        const: 0x81
+
+  protocol at 13:
+    $ref: 'arm,scmi.yaml#/$defs/protocol-node'
+    unevaluatedProperties: false
+
+    properties:
+      reg:
+        const: 0x84
+
+      wakeup-sources:
+        description: each entry consists of 2 integers and represents the source and edge
+        items:
+          items:
+            - description: the wakeup source
+            - description: the wakeup edge
+        $ref: /schemas/types.yaml#/definitions/uint32-matrix
+
+additionalProperties: false
+
+examples:
+  - |
+    firmware {
+        scmi {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            protocol at 81 {
+              reg = <0x81>;
+            };
+
+            protocol at 84 {
+              reg = <0x84>;
+              wakeup-sources = <6 1
+                                7 1
+                                8 1
+                                9 1
+                                10 1>;
+            };
+         };
+    };
+...

-- 
2.37.1



From peng.fan at oss.nxp.com  Thu Feb  1 22:34:40 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 02 Feb 2024 14:34:40 +0800
Subject: [PATCH 2/5] firmware: arm_scmi: add initial support for i.MX BBM
 protocol
In-Reply-To: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
Message-ID: <20240202-imx95-bbm-misc-v1-2-3cb743020933@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

The i.MX BBM protocol is for managing i.MX BBM module which provides
RTC and BUTTON feature.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/firmware/arm_scmi/Kconfig      |  10 +
 drivers/firmware/arm_scmi/Makefile     |   1 +
 drivers/firmware/arm_scmi/imx-sm-bbm.c | 381 +++++++++++++++++++++++++++++++++
 include/linux/scmi_nxp_protocol.h      |  50 +++++
 4 files changed, 442 insertions(+)

diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index aa5842be19b2..56d11c9d9f47 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -181,3 +181,13 @@ config ARM_SCMI_POWER_CONTROL
 	  early shutdown/reboot SCMI requests.
 
 endmenu
+
+config IMX_SCMI_BBM_EXT
+	tristate "i.MX SCMI BBM EXTENSION"
+	depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF)
+	default y if ARCH_MXC
+	help
+	  This enables i.MX System BBM control logic which supports RTC
+	  and BUTTON.
+
+	  This driver can also be built as a module.
diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
index a7bc4796519c..327687acf857 100644
--- a/drivers/firmware/arm_scmi/Makefile
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -11,6 +11,7 @@ scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o powercap.o
+scmi-protocols-$(CONFIG_IMX_SCMI_BBM_EXT) += imx-sm-bbm.o
 scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
 
 obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
diff --git a/drivers/firmware/arm_scmi/imx-sm-bbm.c b/drivers/firmware/arm_scmi/imx-sm-bbm.c
new file mode 100644
index 000000000000..0e12aaeabc42
--- /dev/null
+++ b/drivers/firmware/arm_scmi/imx-sm-bbm.c
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) NXP BBM Protocol
+ *
+ * Copyright 2024 NXP
+ */
+
+#define pr_fmt(fmt) "SCMI Notifications BBM - " fmt
+
+#include <linux/bits.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/scmi_protocol.h>
+#include <linux/scmi_nxp_protocol.h>
+
+#include "protocols.h"
+#include "notify.h"
+
+#define SCMI_PROTOCOL_SUPPORTED_VERSION		0x0
+
+enum scmi_imx_bbm_protocol_cmd {
+	IMX_BBM_GPR_SET = 0x3,
+	IMX_BBM_GPR_GET = 0x4,
+	IMX_BBM_RTC_ATTRIBUTES = 0x5,
+	IMX_BBM_RTC_TIME_SET = 0x6,
+	IMX_BBM_RTC_TIME_GET = 0x7,
+	IMX_BBM_RTC_ALARM_SET = 0x8,
+	IMX_BBM_BUTTON_GET = 0x9,
+	IMX_BBM_RTC_NOTIFY = 0xA,
+	IMX_BBM_BUTTON_NOTIFY = 0xB,
+};
+
+#define BBM_PROTO_ATTR_NUM_RTC(x)  (((x) & 0xFFU) << 16U)
+#define BBM_PROTO_ATTR_NUM_GPR(x)  (((x) & 0xFFFFU) << 0U)
+
+#define GET_RTCS_NR(x)	le32_get_bits((x), GENMASK(23, 16))
+#define GET_GPRS_NR(x)	le32_get_bits((x), GENMASK(15, 0))
+
+#define SCMI_IMX_BBM_NOTIFY_RTC_UPDATED		BIT(2)
+#define SCMI_IMX_BBM_NOTIFY_RTC_ROLLOVER	BIT(1)
+#define SCMI_IMX_BBM_NOTIFY_RTC_ALARM		BIT(0)
+
+#define SCMI_IMX_BBM_RTC_ALARM_ENABLE_FLAG	BIT(0)
+
+#define SCMI_IMX_BBM_NOTIFY_RTC_FLAG	\
+	(SCMI_IMX_BBM_NOTIFY_RTC_UPDATED | \
+	 SCMI_IMX_BBM_NOTIFY_RTC_ROLLOVER | \
+	 SCMI_IMX_BBM_NOTIFY_RTC_ALARM)
+
+#define SCMI_IMX_BBM_EVENT_RTC_ID(x)        (((x) >> 24) & 0xFF)
+
+struct scmi_imx_bbm_info {
+	u32 version;
+	int nr_rtc;
+	int nr_gpr;
+};
+
+struct scmi_msg_imx_bbm_protocol_attributes {
+	__le32 attributes;
+};
+
+struct scmi_imx_bbm_set_time {
+	__le32 id;
+	__le32 flags;
+	__le32 value_low;
+	__le32 value_high;
+};
+
+struct scmi_imx_bbm_get_time {
+	__le32 id;
+	__le32 flags;
+};
+
+struct scmi_imx_bbm_alarm_time {
+	__le32 id;
+	__le32 flags;
+	__le32 value_low;
+	__le32 value_high;
+};
+
+struct scmi_msg_imx_bbm_rtc_notify {
+	__le32 rtc_id;
+	__le32 flags;
+};
+
+struct scmi_msg_imx_bbm_button_notify {
+	__le32 flags;
+};
+
+struct scmi_imx_bbm_notify_payld {
+	__le32 flags;
+};
+
+static int scmi_imx_bbm_attributes_get(const struct scmi_protocol_handle *ph,
+				       struct scmi_imx_bbm_info *pi)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_imx_bbm_protocol_attributes *attr;
+
+	ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0, sizeof(*attr), &t);
+	if (ret)
+		return ret;
+
+	attr = t->rx.buf;
+
+	ret = ph->xops->do_xfer(ph, t);
+	if (!ret) {
+		pi->nr_rtc = GET_RTCS_NR(attr->attributes);
+		pi->nr_gpr = GET_GPRS_NR(attr->attributes);
+	}
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_imx_bbm_notify(const struct scmi_protocol_handle *ph,
+			       u32 src_id, int message_id, bool enable)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_imx_bbm_rtc_notify *rtc_notify;
+	struct scmi_msg_imx_bbm_button_notify *button_notify;
+
+	if (message_id == IMX_BBM_RTC_NOTIFY) {
+		ret = ph->xops->xfer_get_init(ph, message_id, sizeof(*rtc_notify), 0, &t);
+		if (ret)
+			return ret;
+
+		rtc_notify = t->tx.buf;
+		rtc_notify->rtc_id = cpu_to_le32(0);
+		rtc_notify->flags = cpu_to_le32(enable ? SCMI_IMX_BBM_NOTIFY_RTC_FLAG : 0);
+	} else if (message_id == IMX_BBM_BUTTON_NOTIFY) {
+		ret = ph->xops->xfer_get_init(ph, message_id, sizeof(*button_notify), 0, &t);
+		if (ret)
+			return ret;
+
+		button_notify = t->tx.buf;
+		button_notify->flags = cpu_to_le32(enable ? 1 : 0);
+	} else {
+		return -EINVAL;
+	}
+
+	ret = ph->xops->do_xfer(ph, t);
+
+	ph->xops->xfer_put(ph, t);
+	return ret;
+}
+
+static enum scmi_imx_bbm_protocol_cmd evt_2_cmd[] = {
+	IMX_BBM_RTC_NOTIFY,
+	IMX_BBM_BUTTON_NOTIFY
+};
+
+static int scmi_imx_bbm_set_notify_enabled(const struct scmi_protocol_handle *ph,
+					   u8 evt_id, u32 src_id, bool enable)
+{
+	int ret, cmd_id;
+
+	if (evt_id >= ARRAY_SIZE(evt_2_cmd))
+		return -EINVAL;
+
+	cmd_id = evt_2_cmd[evt_id];
+	ret = scmi_imx_bbm_notify(ph, src_id, cmd_id, enable);
+	if (ret)
+		pr_debug("FAIL_ENABLED - evt[%X] dom[%d] - ret:%d\n",
+			 evt_id, src_id, ret);
+
+	return ret;
+}
+
+static void *scmi_imx_bbm_fill_custom_report(const struct scmi_protocol_handle *ph,
+					     u8 evt_id, ktime_t timestamp,
+					     const void *payld, size_t payld_sz,
+					     void *report, u32 *src_id)
+{
+	const struct scmi_imx_bbm_notify_payld *p = payld;
+	struct scmi_imx_bbm_notif_report *r = report;
+
+	if (sizeof(*p) != payld_sz)
+		return NULL;
+
+	if (evt_id == SCMI_EVENT_IMX_BBM_RTC) {
+		r->is_rtc = true;
+		r->is_button = false;
+		r->timestamp = timestamp;
+		r->rtc_id = SCMI_IMX_BBM_EVENT_RTC_ID(le32_to_cpu(p->flags));
+		r->rtc_evt = le32_to_cpu(p->flags) & SCMI_IMX_BBM_NOTIFY_RTC_FLAG;
+		dev_dbg(ph->dev, "RTC: %d evt: %x\n", r->rtc_id, r->rtc_evt);
+		*src_id = r->rtc_evt;
+	} else if (evt_id == SCMI_EVENT_IMX_BBM_BUTTON) {
+		r->is_rtc = false;
+		r->is_button = true;
+		r->timestamp = timestamp;
+		dev_dbg(ph->dev, "BBM Button\n");
+		*src_id = 0;
+	} else {
+		WARN_ON(1);
+		return NULL;
+	}
+
+	return r;
+}
+
+static int scmi_imx_bbm_get_num_sources(const struct scmi_protocol_handle *ph)
+{
+	return 1;
+}
+
+static const struct scmi_event scmi_imx_bbm_events[] = {
+	{
+		.id = SCMI_EVENT_IMX_BBM_RTC,
+		.max_payld_sz = sizeof(struct scmi_imx_bbm_notify_payld),
+		.max_report_sz = sizeof(struct scmi_imx_bbm_notif_report),
+	},
+	{
+		.id = SCMI_EVENT_IMX_BBM_BUTTON,
+		.max_payld_sz = sizeof(struct scmi_imx_bbm_notify_payld),
+		.max_report_sz = sizeof(struct scmi_imx_bbm_notif_report),
+	},
+};
+
+static const struct scmi_event_ops scmi_imx_bbm_event_ops = {
+	.get_num_sources = scmi_imx_bbm_get_num_sources,
+	.set_notify_enabled = scmi_imx_bbm_set_notify_enabled,
+	.fill_custom_report = scmi_imx_bbm_fill_custom_report,
+};
+
+static const struct scmi_protocol_events scmi_imx_bbm_protocol_events = {
+	.queue_sz = SCMI_PROTO_QUEUE_SZ,
+	.ops = &scmi_imx_bbm_event_ops,
+	.evts = scmi_imx_bbm_events,
+	.num_events = ARRAY_SIZE(scmi_imx_bbm_events),
+};
+
+static int scmi_imx_bbm_protocol_init(const struct scmi_protocol_handle *ph)
+{
+	u32 version;
+	int ret;
+	struct scmi_imx_bbm_info *binfo;
+
+	ret = ph->xops->version_get(ph, &version);
+	if (ret)
+		return ret;
+
+	dev_info(ph->dev, "NXP SM BBM Version %d.%d\n",
+		 PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
+
+	binfo = devm_kzalloc(ph->dev, sizeof(*binfo), GFP_KERNEL);
+	if (!binfo)
+		return -ENOMEM;
+
+	ret = scmi_imx_bbm_attributes_get(ph, binfo);
+	if (ret)
+		return ret;
+
+	return ph->set_priv(ph, binfo, version);
+}
+
+static int scmi_imx_bbm_rtc_time_set(const struct scmi_protocol_handle *ph,
+				     u32 rtc_id, u64 sec)
+{
+	struct scmi_imx_bbm_info *pi = ph->get_priv(ph);
+	struct scmi_imx_bbm_set_time *cfg;
+	struct scmi_xfer *t;
+	int ret;
+
+	if (rtc_id >= pi->nr_rtc)
+		return -EINVAL;
+
+	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_BBM_RTC_TIME_SET, sizeof(*cfg), 0, &t);
+	if (ret)
+		return ret;
+
+	cfg = t->tx.buf;
+	cfg->id = cpu_to_le32(rtc_id);
+	cfg->flags = 0;
+	cfg->value_low = cpu_to_le32(sec & 0xffffffff);
+	cfg->value_high = cpu_to_le32(sec >> 32);
+
+	ret = ph->xops->do_xfer(ph, t);
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_imx_bbm_rtc_time_get(const struct scmi_protocol_handle *ph,
+				     u32 rtc_id, u64 *value)
+{
+	struct scmi_imx_bbm_info *pi = ph->get_priv(ph);
+	struct scmi_imx_bbm_get_time *cfg;
+	struct scmi_xfer *t;
+	int ret;
+
+	if (rtc_id >= pi->nr_rtc)
+		return -EINVAL;
+
+	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_BBM_RTC_TIME_GET, sizeof(*cfg), sizeof(u64), &t);
+	if (ret)
+		return ret;
+
+	cfg = t->tx.buf;
+	cfg->id = cpu_to_le32(rtc_id);
+	cfg->flags = 0;
+
+	ret = ph->xops->do_xfer(ph, t);
+	if (!ret)
+		*value = get_unaligned_le64(t->rx.buf);
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_imx_bbm_rtc_alarm_set(const struct scmi_protocol_handle *ph,
+				      u32 rtc_id, u64 sec)
+{
+	struct scmi_imx_bbm_info *pi = ph->get_priv(ph);
+	struct scmi_imx_bbm_alarm_time *cfg;
+	struct scmi_xfer *t;
+	int ret;
+
+	if (rtc_id >= pi->nr_rtc)
+		return -EINVAL;
+
+	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_BBM_RTC_ALARM_SET, sizeof(*cfg), 0, &t);
+	if (ret)
+		return ret;
+
+	cfg = t->tx.buf;
+	cfg->id = cpu_to_le32(rtc_id);
+	cfg->flags = SCMI_IMX_BBM_RTC_ALARM_ENABLE_FLAG;
+	cfg->value_low = cpu_to_le32(sec & 0xffffffff);
+	cfg->value_high = cpu_to_le32(sec >> 32);
+
+	ret = ph->xops->do_xfer(ph, t);
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_imx_bbm_button_get(const struct scmi_protocol_handle *ph, u32 *state)
+{
+	struct scmi_xfer *t;
+	int ret;
+
+	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_BBM_BUTTON_GET, 0, sizeof(u32), &t);
+	if (ret)
+		return ret;
+
+	ret = ph->xops->do_xfer(ph, t);
+	if (!ret)
+		*state = get_unaligned_le32(t->rx.buf);
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static const struct scmi_imx_bbm_proto_ops scmi_imx_bbm_proto_ops = {
+	.rtc_time_get = scmi_imx_bbm_rtc_time_get,
+	.rtc_time_set = scmi_imx_bbm_rtc_time_set,
+	.rtc_alarm_set = scmi_imx_bbm_rtc_alarm_set,
+	.button_get = scmi_imx_bbm_button_get,
+};
+
+static const struct scmi_protocol scmi_imx_bbm = {
+	.id = SCMI_PROTOCOL_IMX_BBM,
+	.owner = THIS_MODULE,
+	.instance_init = &scmi_imx_bbm_protocol_init,
+	.ops = &scmi_imx_bbm_proto_ops,
+	.events = &scmi_imx_bbm_protocol_events,
+	.supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION,
+};
+
+module_scmi_protocol(scmi_imx_bbm);
diff --git a/include/linux/scmi_nxp_protocol.h b/include/linux/scmi_nxp_protocol.h
new file mode 100644
index 000000000000..a2077e1ef5d8
--- /dev/null
+++ b/include/linux/scmi_nxp_protocol.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * SCMI Message Protocol driver NXP extension header
+ *
+ * Copyright 2024 NXP.
+ */
+
+#ifndef _LINUX_SCMI_NXP_PROTOCOL_H
+#define _LINUX_SCMI_NXP_PROTOCOL_H
+
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/notifier.h>
+#include <linux/types.h>
+
+enum scmi_nxp_protocol {
+	SCMI_PROTOCOL_IMX_BBM = 0x81,
+};
+
+struct scmi_imx_bbm_proto_ops {
+	int (*rtc_time_set)(const struct scmi_protocol_handle *ph, u32 id,
+			    uint64_t sec);
+	int (*rtc_time_get)(const struct scmi_protocol_handle *ph, u32 id,
+			    u64 *val);
+	int (*rtc_alarm_set)(const struct scmi_protocol_handle *ph, u32 id,
+			     u64 sec);
+	int (*button_get)(const struct scmi_protocol_handle *ph, u32 *state);
+};
+
+enum scmi_nxp_notification_events {
+	SCMI_EVENT_IMX_BBM_RTC = 0x0,
+	SCMI_EVENT_IMX_BBM_BUTTON = 0x1,
+	SCMI_EVENT_IMX_MISC_CONTROL_DISABLED = 0x0,
+	SCMI_EVENT_IMX_MISC_CONTROL_FALLING_EDGE = 0x1,
+	SCMI_EVENT_IMX_MISC_CONTROL_RISING_EDGE = 0x2,
+};
+
+#define SCMI_IMX_BBM_RTC_TIME_SET	0x6
+#define SCMI_IMX_BBM_RTC_TIME_GET	0x7
+#define SCMI_IMX_BBM_RTC_ALARM_SET	0x8
+#define SCMI_IMX_BBM_BUTTON_GET		0x9
+
+struct scmi_imx_bbm_notif_report {
+	bool			is_rtc;
+	bool			is_button;
+	ktime_t			timestamp;
+	unsigned int		rtc_id;
+	unsigned int		rtc_evt;
+};
+#endif

-- 
2.37.1



From peng.fan at oss.nxp.com  Thu Feb  1 22:34:41 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 02 Feb 2024 14:34:41 +0800
Subject: [PATCH 3/5] firmware: arm_scmi: add initial support for i.MX MISC
 protocol
In-Reply-To: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
Message-ID: <20240202-imx95-bbm-misc-v1-3-3cb743020933@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

The i.MX MISC protocol is for misc settings, such as gpio expander
wakeup.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/firmware/arm_scmi/Kconfig       |  10 ++
 drivers/firmware/arm_scmi/Makefile      |   1 +
 drivers/firmware/arm_scmi/imx-sm-misc.c | 289 ++++++++++++++++++++++++++++++++
 include/linux/scmi_nxp_protocol.h       |  17 ++
 4 files changed, 317 insertions(+)

diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index 56d11c9d9f47..bfeae92f6420 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -191,3 +191,13 @@ config IMX_SCMI_BBM_EXT
 	  and BUTTON.
 
 	  This driver can also be built as a module.
+
+config IMX_SCMI_MISC_EXT
+	tristate "i.MX SCMI MISC EXTENSION"
+	depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF)
+	default y if ARCH_MXC
+	help
+	  This enables i.MX System MISC control logic such as gpio expander
+	  wakeup
+
+	  This driver can also be built as a module.
diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
index 327687acf857..a23fde721222 100644
--- a/drivers/firmware/arm_scmi/Makefile
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -12,6 +12,7 @@ scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o powercap.o
 scmi-protocols-$(CONFIG_IMX_SCMI_BBM_EXT) += imx-sm-bbm.o
+scmi-protocols-$(CONFIG_IMX_SCMI_MISC_EXT) += imx-sm-misc.o
 scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
 
 obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
diff --git a/drivers/firmware/arm_scmi/imx-sm-misc.c b/drivers/firmware/arm_scmi/imx-sm-misc.c
new file mode 100644
index 000000000000..7805d41cca4d
--- /dev/null
+++ b/drivers/firmware/arm_scmi/imx-sm-misc.c
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System control and Management Interface (SCMI) NXP MISC Protocol
+ *
+ * Copyright 2024 NXP
+ */
+
+#define pr_fmt(fmt) "SCMI Notifications MISC - " fmt
+
+#include <linux/bits.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/scmi_protocol.h>
+#include <linux/scmi_nxp_protocol.h>
+
+#include "protocols.h"
+#include "notify.h"
+
+#define SCMI_PROTOCOL_SUPPORTED_VERSION		0x0
+
+enum scmi_imx_misc_protocol_cmd {
+	SCMI_IMX_MISC_CTRL_SET	= 0x3,
+	SCMI_IMX_MISC_CTRL_GET	= 0x4,
+	SCMI_IMX_MISC_CTRL_NOTIFY = 0x8,
+};
+
+struct scmi_imx_misc_info {
+	u32 version;
+	u32 nr_ctrl;
+	u32 nr_reason;
+};
+
+struct scmi_msg_imx_misc_protocol_attributes {
+	__le32 attributes;
+};
+
+#define GET_REASONS_NR(x)	le32_get_bits((x), GENMASK(23, 16))
+#define GET_CTRLS_NR(x)		le32_get_bits((x), GENMASK(15, 0))
+
+struct scmi_imx_misc_ctrl_set_in {
+	__le32 id;
+	__le32 num;
+	__le32 value[MISC_MAX_VAL];
+};
+
+struct scmi_imx_misc_ctrl_notify_in {
+	__le32 ctrl_id;
+	__le32 flags;
+};
+
+struct scmi_imx_misc_ctrl_notify_payld {
+	__le32 ctrl_id;
+	__le32 flags;
+};
+
+struct scmi_imx_misc_ctrl_get_out {
+	__le32 num;
+	__le32 val[MISC_MAX_VAL];
+};
+
+static int scmi_imx_misc_attributes_get(const struct scmi_protocol_handle *ph,
+					struct scmi_imx_misc_info *mi)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_imx_misc_protocol_attributes *attr;
+
+	ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0,
+				      sizeof(*attr), &t);
+	if (ret)
+		return ret;
+
+	attr = t->rx.buf;
+
+	ret = ph->xops->do_xfer(ph, t);
+	if (!ret) {
+		mi->nr_ctrl = GET_CTRLS_NR(attr->attributes);
+		mi->nr_reason = GET_REASONS_NR(attr->attributes);
+		dev_info(ph->dev, "i.MX MISC NUM CTRL: %d, NUM Reason: %d\n",
+			 mi->nr_ctrl, mi->nr_reason);
+	}
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_imx_misc_ctrl_notify(const struct scmi_protocol_handle *ph,
+				     u32 ctrl_id, u32 flags)
+{
+	struct scmi_imx_misc_info *mi = ph->get_priv(ph);
+	struct scmi_imx_misc_ctrl_notify_in *in;
+	struct scmi_xfer *t;
+	int ret;
+
+	if (ctrl_id >= mi->nr_ctrl)
+		return -EINVAL;
+
+	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_CTRL_NOTIFY,
+				      sizeof(*in), 0, &t);
+	if (ret)
+		return ret;
+
+	in = t->tx.buf;
+	in->ctrl_id = cpu_to_le32(ctrl_id);
+	in->flags = cpu_to_le32(flags);
+
+	ret = ph->xops->do_xfer(ph, t);
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int
+scmi_imx_misc_ctrl_set_notify_enabled(const struct scmi_protocol_handle *ph,
+				      u8 evt_id, u32 src_id, bool enable)
+{
+	int ret;
+
+	ret = scmi_imx_misc_ctrl_notify(ph, src_id, enable ? evt_id : 0);
+	if (ret) {
+		dev_err(ph->dev, "FAIL_ENABLED - evt[%X] src[%d] - ret:%d\n",
+			evt_id, src_id, ret);
+	}
+
+	return ret;
+}
+
+static int
+scmi_imx_misc_ctrl_get_num_sources(const struct scmi_protocol_handle *ph)
+{
+	struct scmi_imx_misc_info *mi = ph->get_priv(ph);
+
+	return mi->nr_ctrl;
+}
+
+static void *
+scmi_imx_misc_ctrl_fill_custom_report(const struct scmi_protocol_handle *ph,
+				      u8 evt_id, ktime_t timestamp,
+				      const void *payld, size_t payld_sz,
+				      void *report, u32 *src_id)
+{
+	const struct scmi_imx_misc_ctrl_notify_payld *p = payld;
+	struct scmi_imx_misc_ctrl_notify_report *r = report;
+
+	if (sizeof(*p) != payld_sz)
+		return NULL;
+
+	r->timestamp = timestamp;
+	r->ctrl_id = p->ctrl_id;
+	r->flags = p->flags;
+	if (src_id)
+		*src_id = r->ctrl_id;
+	dev_dbg(ph->dev, "%s: ctrl_id: %d flags: %d\n", __func__, r->ctrl_id, r->flags);
+
+	return r;
+}
+
+static const struct scmi_event_ops scmi_imx_misc_event_ops = {
+	.get_num_sources = scmi_imx_misc_ctrl_get_num_sources,
+	.set_notify_enabled = scmi_imx_misc_ctrl_set_notify_enabled,
+	.fill_custom_report = scmi_imx_misc_ctrl_fill_custom_report,
+};
+
+static const struct scmi_event scmi_imx_misc_events[] = {
+	{
+		.id = SCMI_EVENT_IMX_MISC_CONTROL_DISABLED,
+		.max_payld_sz = sizeof(struct scmi_imx_misc_ctrl_notify_payld),
+		.max_report_sz = sizeof(struct scmi_imx_misc_ctrl_notify_report),
+	},
+	{
+		.id = SCMI_EVENT_IMX_MISC_CONTROL_FALLING_EDGE,
+		.max_payld_sz = sizeof(struct scmi_imx_misc_ctrl_notify_payld),
+		.max_report_sz = sizeof(struct scmi_imx_misc_ctrl_notify_report),
+	},
+	{
+		.id = SCMI_EVENT_IMX_MISC_CONTROL_RISING_EDGE,
+		.max_payld_sz = sizeof(struct scmi_imx_misc_ctrl_notify_payld),
+		.max_report_sz = sizeof(struct scmi_imx_misc_ctrl_notify_report),
+	}
+};
+
+static struct scmi_protocol_events scmi_imx_misc_protocol_events = {
+	.queue_sz = SCMI_PROTO_QUEUE_SZ,
+	.ops = &scmi_imx_misc_event_ops,
+	.evts = scmi_imx_misc_events,
+	.num_events = ARRAY_SIZE(scmi_imx_misc_events),
+};
+
+static int scmi_imx_misc_protocol_init(const struct scmi_protocol_handle *ph)
+{
+	struct scmi_imx_misc_info *minfo;
+	u32 version;
+	int ret;
+
+	ret = ph->xops->version_get(ph, &version);
+	if (ret)
+		return ret;
+
+	dev_info(ph->dev, "NXP SM MISC Version %d.%d\n",
+		 PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
+
+	minfo = devm_kzalloc(ph->dev, sizeof(*minfo), GFP_KERNEL);
+	if (!minfo)
+		return -ENOMEM;
+
+	ret = scmi_imx_misc_attributes_get(ph, minfo);
+	if (ret)
+		return ret;
+
+	return ph->set_priv(ph, minfo, version);
+}
+
+static int scmi_imx_misc_ctrl_get(const struct scmi_protocol_handle *ph,
+				  u32 ctrl_id, u32 *num, u32 *val)
+{
+	struct scmi_imx_misc_info *mi = ph->get_priv(ph);
+	struct scmi_imx_misc_ctrl_get_out *out;
+	struct scmi_xfer *t;
+	int ret, i;
+
+	if (ctrl_id >= mi->nr_ctrl)
+		return -EINVAL;
+
+	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_CTRL_GET, sizeof(u32),
+				      sizeof(*out), &t);
+	if (ret)
+		return ret;
+
+	put_unaligned_le32(ctrl_id, t->tx.buf);
+	ret = ph->xops->do_xfer(ph, t);
+	if (!ret) {
+		out = t->rx.buf;
+		*num = le32_to_cpu(out->num);
+		for (i = 0; i < *num; i++)
+			val[i] = le32_to_cpu(out->val[i]);
+	}
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_imx_misc_ctrl_set(const struct scmi_protocol_handle *ph,
+				  u32 ctrl_id, u32 num, u32 *val)
+{
+	struct scmi_imx_misc_info *mi = ph->get_priv(ph);
+	struct scmi_imx_misc_ctrl_set_in *in;
+	struct scmi_xfer *t;
+	int ret, i;
+
+	if (ctrl_id >= mi->nr_ctrl)
+		return -EINVAL;
+
+	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_CTRL_SET, sizeof(*in),
+				      0, &t);
+	if (ret)
+		return ret;
+
+	in = t->tx.buf;
+	in->id = cpu_to_le32(ctrl_id);
+	in->num = cpu_to_le32(num);
+	for (i = 0; i < num; i++)
+		in->value[i] = cpu_to_le32(val[i]);
+
+	ret = ph->xops->do_xfer(ph, t);
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static const struct scmi_imx_misc_proto_ops scmi_imx_misc_proto_ops = {
+	.misc_ctrl_set = scmi_imx_misc_ctrl_set,
+	.misc_ctrl_get = scmi_imx_misc_ctrl_get,
+};
+
+static const struct scmi_protocol scmi_imx_misc = {
+	.id = SCMI_PROTOCOL_IMX_MISC,
+	.owner = THIS_MODULE,
+	.instance_init = &scmi_imx_misc_protocol_init,
+	.ops = &scmi_imx_misc_proto_ops,
+	.events = &scmi_imx_misc_protocol_events,
+};
+
+module_scmi_protocol(scmi_imx_misc);
diff --git a/include/linux/scmi_nxp_protocol.h b/include/linux/scmi_nxp_protocol.h
index a2077e1ef5d8..45415a6ff845 100644
--- a/include/linux/scmi_nxp_protocol.h
+++ b/include/linux/scmi_nxp_protocol.h
@@ -13,8 +13,14 @@
 #include <linux/notifier.h>
 #include <linux/types.h>
 
+#define SCMI_PAYLOAD_LEN	100
+
+#define SCMI_ARRAY(X, Y)	((SCMI_PAYLOAD_LEN - (X)) / sizeof(Y))
+#define MISC_MAX_VAL		SCMI_ARRAY(8, uint32_t)
+
 enum scmi_nxp_protocol {
 	SCMI_PROTOCOL_IMX_BBM = 0x81,
+	SCMI_PROTOCOL_IMX_MISC = 0x84,
 };
 
 struct scmi_imx_bbm_proto_ops {
@@ -47,4 +53,15 @@ struct scmi_imx_bbm_notif_report {
 	unsigned int		rtc_id;
 	unsigned int		rtc_evt;
 };
+
+struct scmi_imx_misc_ctrl_notify_report {
+	ktime_t			timestamp;
+	unsigned int		ctrl_id;
+	unsigned int		flags;
+};
+
+struct scmi_imx_misc_proto_ops {
+	int (*misc_ctrl_set)(const struct scmi_protocol_handle *ph, u32 id, u32 num, u32 *val);
+	int (*misc_ctrl_get)(const struct scmi_protocol_handle *ph, u32 id, u32 *num, u32 *val);
+};
 #endif

-- 
2.37.1



From peng.fan at oss.nxp.com  Thu Feb  1 22:34:42 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 02 Feb 2024 14:34:42 +0800
Subject: [PATCH 4/5] firmware: imx: support BBM module
In-Reply-To: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
Message-ID: <20240202-imx95-bbm-misc-v1-4-3cb743020933@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

The BBM module provides RTC and BUTTON feature. To i.MX95, this module
is managed by System Manager. Linux could use i.MX SCMI BBM Extension
protocol to use RTC and BUTTON feature.

This driver is to use SCMI interface to get/set RTC, enable pwrkey.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/firmware/imx/Makefile |   1 +
 drivers/firmware/imx/sm-bbm.c | 317 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 318 insertions(+)

diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
index 8f9f04a513a8..fb20e22074e1 100644
--- a/drivers/firmware/imx/Makefile
+++ b/drivers/firmware/imx/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_IMX_DSP)		+= imx-dsp.o
 obj-$(CONFIG_IMX_SCU)		+= imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
+obj-${CONFIG_IMX_SCMI_BBM_EXT}	+= sm-bbm.o
diff --git a/drivers/firmware/imx/sm-bbm.c b/drivers/firmware/imx/sm-bbm.c
new file mode 100644
index 000000000000..c5bc571881c7
--- /dev/null
+++ b/drivers/firmware/imx/sm-bbm.c
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP.
+ */
+
+#include <linux/input.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/scmi_protocol.h>
+#include <linux/scmi_nxp_protocol.h>
+#include <linux/suspend.h>
+
+#define DEBOUNCE_TIME		30
+#define REPEAT_INTERVAL		60
+
+struct scmi_imx_bbm {
+	struct rtc_device *rtc_dev;
+	struct scmi_protocol_handle *ph;
+	const struct scmi_imx_bbm_proto_ops *ops;
+	struct notifier_block nb;
+	int keycode;
+	int keystate;  /* 1:pressed */
+	bool suspended;
+	struct delayed_work check_work;
+	struct input_dev *input;
+};
+
+static int scmi_imx_bbm_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
+	struct scmi_protocol_handle *ph = bbnsm->ph;
+	u64 val;
+	int ret;
+
+	ret = bbnsm->ops->rtc_time_get(ph, 0, &val);
+	if (ret)
+		dev_err(dev, "%s: %d\n", __func__, ret);
+
+	rtc_time64_to_tm(val, tm);
+
+	return 0;
+}
+
+static int scmi_imx_bbm_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
+	struct scmi_protocol_handle *ph = bbnsm->ph;
+	u64 val;
+	int ret;
+
+	val = rtc_tm_to_time64(tm);
+
+	ret = bbnsm->ops->rtc_time_set(ph, 0, val);
+	if (ret)
+		dev_err(dev, "%s: %d\n", __func__, ret);
+
+	return 0;
+}
+
+static int scmi_imx_bbm_alarm_irq_enable(struct device *dev, unsigned int enable)
+{
+	return 0;
+}
+
+static int scmi_imx_bbm_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
+	struct scmi_protocol_handle *ph = bbnsm->ph;
+	struct rtc_time *alrm_tm = &alrm->time;
+	u64 val;
+	int ret;
+
+	val = rtc_tm_to_time64(alrm_tm);
+
+	ret = bbnsm->ops->rtc_alarm_set(ph, 0, val);
+	if (ret)
+		dev_err(dev, "%s: %d\n", __func__, ret);
+
+	return 0;
+}
+
+static const struct rtc_class_ops smci_imx_bbm_rtc_ops = {
+	.read_time = scmi_imx_bbm_read_time,
+	.set_time = scmi_imx_bbm_set_time,
+	.set_alarm = scmi_imx_bbm_set_alarm,
+	.alarm_irq_enable = scmi_imx_bbm_alarm_irq_enable,
+};
+
+static void scmi_imx_bbm_pwrkey_check_for_events(struct work_struct *work)
+{
+	struct scmi_imx_bbm *bbnsm = container_of(work, struct scmi_imx_bbm, check_work.work);
+	struct scmi_protocol_handle *ph = bbnsm->ph;
+	struct input_dev *input = bbnsm->input;
+	u32 state = 0;
+	int ret;
+
+	ret = bbnsm->ops->button_get(ph, &state);
+	if (ret) {
+		pr_err("%s: %d\n", __func__, ret);
+		return;
+	}
+
+	pr_debug("%s: state: %d, keystate %d\n", __func__, state, bbnsm->keystate);
+
+	/* only report new event if status changed */
+	if (state ^ bbnsm->keystate) {
+		bbnsm->keystate = state;
+		input_event(input, EV_KEY, bbnsm->keycode, state);
+		input_sync(input);
+		pm_relax(bbnsm->input->dev.parent);
+		pr_debug("EV_KEY: %x\n", bbnsm->keycode);
+	}
+
+	/* repeat check if pressed long */
+	if (state)
+		schedule_delayed_work(&bbnsm->check_work, msecs_to_jiffies(REPEAT_INTERVAL));
+}
+
+static int scmi_imx_bbm_pwrkey_event(struct scmi_imx_bbm *bbnsm)
+{
+	struct input_dev *input = bbnsm->input;
+
+	schedule_delayed_work(&bbnsm->check_work, msecs_to_jiffies(DEBOUNCE_TIME));
+
+	/*
+	 * Directly report key event after resume to make no key press
+	 * event is missed.
+	 */
+	if (bbnsm->suspended) {
+		bbnsm->keystate = 1;
+		input_event(input, EV_KEY, bbnsm->keycode, 1);
+		input_sync(input);
+	}
+
+	return 0;
+}
+
+static void scmi_imx_bbm_pwrkey_act(void *pdata)
+{
+	struct scmi_imx_bbm *bbnsm = pdata;
+
+	cancel_delayed_work_sync(&bbnsm->check_work);
+}
+
+static int scmi_imx_bbm_notifier(struct notifier_block *nb, unsigned long event, void *data)
+{
+	struct scmi_imx_bbm *bbnsm = container_of(nb, struct scmi_imx_bbm, nb);
+	struct scmi_imx_bbm_notif_report *r = data;
+
+	if (r->is_rtc)
+		rtc_update_irq(bbnsm->rtc_dev, 1, RTC_AF | RTC_IRQF);
+	if (r->is_button) {
+		pr_debug("BBM Button Power key pressed\n");
+		scmi_imx_bbm_pwrkey_event(bbnsm);
+	}
+
+	return 0;
+}
+
+static int scmi_imx_bbm_pwrkey_init(struct scmi_device *sdev)
+{
+	const struct scmi_handle *handle = sdev->handle;
+	struct device *dev = &sdev->dev;
+	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
+	struct input_dev *input;
+	int ret;
+
+	if (device_property_read_u32(dev, "linux,code", &bbnsm->keycode)) {
+		bbnsm->keycode = KEY_POWER;
+		dev_warn(dev, "key code is not specified, using default KEY_POWER\n");
+	}
+
+	INIT_DELAYED_WORK(&bbnsm->check_work, scmi_imx_bbm_pwrkey_check_for_events);
+
+	input = devm_input_allocate_device(dev);
+	if (!input) {
+		dev_err(dev, "failed to allocate the input device for SCMI IMX BBM\n");
+		return -ENOMEM;
+	}
+
+	input->name = dev_name(dev);
+	input->phys = "bbnsm-pwrkey/input0";
+	input->id.bustype = BUS_HOST;
+
+	input_set_capability(input, EV_KEY, bbnsm->keycode);
+
+	ret = devm_add_action_or_reset(dev, scmi_imx_bbm_pwrkey_act, bbnsm);
+	if (ret) {
+		dev_err(dev, "failed to register remove action\n");
+		return ret;
+	}
+
+	bbnsm->input = input;
+
+	ret = handle->notify_ops->devm_event_notifier_register(sdev, SCMI_PROTOCOL_IMX_BBM,
+							       SCMI_EVENT_IMX_BBM_BUTTON,
+							       NULL, &bbnsm->nb);
+
+	if (ret)
+		dev_err(dev, "Failed to register BBM Button Events %d:", ret);
+
+	ret = input_register_device(input);
+	if (ret) {
+		dev_err(dev, "failed to register input device\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int scmi_imx_bbm_rtc_init(struct scmi_device *sdev)
+{
+	const struct scmi_handle *handle = sdev->handle;
+	struct device *dev = &sdev->dev;
+	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
+	int ret;
+
+	bbnsm->rtc_dev = devm_rtc_allocate_device(dev);
+	if (IS_ERR(bbnsm->rtc_dev))
+		return PTR_ERR(bbnsm->rtc_dev);
+
+	bbnsm->rtc_dev->ops = &smci_imx_bbm_rtc_ops;
+	bbnsm->rtc_dev->range_min = 0;
+	bbnsm->rtc_dev->range_max = U32_MAX;
+
+	ret = devm_rtc_register_device(bbnsm->rtc_dev);
+	if (ret)
+		return ret;
+
+	bbnsm->nb.notifier_call = &scmi_imx_bbm_notifier;
+	return handle->notify_ops->devm_event_notifier_register(sdev, SCMI_PROTOCOL_IMX_BBM,
+								SCMI_EVENT_IMX_BBM_RTC,
+								NULL, &bbnsm->nb);
+}
+
+static int scmi_imx_bbm_probe(struct scmi_device *sdev)
+{
+	const struct scmi_handle *handle = sdev->handle;
+	struct device *dev = &sdev->dev;
+	struct scmi_protocol_handle *ph;
+	struct scmi_imx_bbm *bbnsm;
+	int ret;
+
+	if (!handle)
+		return -ENODEV;
+
+	bbnsm = devm_kzalloc(dev, sizeof(struct scmi_imx_bbm), GFP_KERNEL);
+	if (!bbnsm)
+		return -ENOMEM;
+
+	bbnsm->ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_IMX_BBM, &ph);
+	if (IS_ERR(bbnsm->ops))
+		return PTR_ERR(bbnsm->ops);
+
+	bbnsm->ph = ph;
+
+	device_init_wakeup(dev, true);
+
+	dev_set_drvdata(dev, bbnsm);
+
+	ret = scmi_imx_bbm_rtc_init(sdev);
+	if (ret) {
+		dev_err(dev, "rtc init failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = scmi_imx_bbm_pwrkey_init(sdev);
+	if (ret) {
+		dev_err(dev, "pwr init failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused scmi_imx_bbm_suspend(struct device *dev)
+{
+	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
+
+	bbnsm->suspended = true;
+
+	return 0;
+}
+
+static int __maybe_unused scmi_imx_bbm_resume(struct device *dev)
+{
+	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
+
+	bbnsm->suspended = false;
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(scmi_imx_bbm_pm_ops, scmi_imx_bbm_suspend, scmi_imx_bbm_resume);
+
+static const struct scmi_device_id scmi_id_table[] = {
+	{ SCMI_PROTOCOL_IMX_BBM, "imx-bbm" },
+	{ },
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static struct scmi_driver scmi_imx_bbm_driver = {
+	.driver = {
+		.pm = &scmi_imx_bbm_pm_ops,
+	},
+	.name = "scmi-imx-bbm",
+	.probe = scmi_imx_bbm_probe,
+	.id_table = scmi_id_table,
+};
+module_scmi_driver(scmi_imx_bbm_driver);
+
+MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
+MODULE_DESCRIPTION("IMX SM BBM driver");
+MODULE_LICENSE("GPL");

-- 
2.37.1



From peng.fan at oss.nxp.com  Thu Feb  1 22:34:43 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 02 Feb 2024 14:34:43 +0800
Subject: [PATCH 5/5] firmware: imx: add i.MX95 MISC driver
In-Reply-To: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
Message-ID: <20240202-imx95-bbm-misc-v1-5-3cb743020933@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

The i.MX95 System manager exports SCMI MISC protocol for linux to do
various settings, such as set board gpio expander as wakeup source.

The driver is to add the support.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/firmware/imx/Makefile   |  1 +
 drivers/firmware/imx/sm-misc.c  | 92 +++++++++++++++++++++++++++++++++++++++++
 include/linux/firmware/imx/sm.h | 33 +++++++++++++++
 3 files changed, 126 insertions(+)

diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
index fb20e22074e1..cb9c361d9b81 100644
--- a/drivers/firmware/imx/Makefile
+++ b/drivers/firmware/imx/Makefile
@@ -2,3 +2,4 @@
 obj-$(CONFIG_IMX_DSP)		+= imx-dsp.o
 obj-$(CONFIG_IMX_SCU)		+= imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
 obj-${CONFIG_IMX_SCMI_BBM_EXT}	+= sm-bbm.o
+obj-${CONFIG_IMX_SCMI_MISC_EXT}	+= sm-misc.o
diff --git a/drivers/firmware/imx/sm-misc.c b/drivers/firmware/imx/sm-misc.c
new file mode 100644
index 000000000000..4410e69d256b
--- /dev/null
+++ b/drivers/firmware/imx/sm-misc.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP.
+ */
+
+#include <linux/firmware/imx/sm.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/scmi_protocol.h>
+#include <linux/scmi_nxp_protocol.h>
+
+static const struct scmi_imx_misc_proto_ops *imx_misc_ctrl_ops;
+static struct scmi_protocol_handle *ph;
+struct notifier_block scmi_imx_misc_ctrl_nb;
+
+int scmi_imx_misc_ctrl_set(u32 id, u32 val)
+{
+	if (!ph)
+		return -EPROBE_DEFER;
+
+	return imx_misc_ctrl_ops->misc_ctrl_set(ph, id, 1, &val);
+};
+EXPORT_SYMBOL(scmi_imx_misc_ctrl_set);
+
+int scmi_imx_misc_ctrl_get(u32 id, u32 *num, u32 *val)
+{
+	if (!ph)
+		return -EPROBE_DEFER;
+
+	return imx_misc_ctrl_ops->misc_ctrl_get(ph, id, num, val);
+}
+EXPORT_SYMBOL(scmi_imx_misc_ctrl_get);
+
+static int scmi_imx_misc_ctrl_notifier(struct notifier_block *nb,
+				       unsigned long event, void *data)
+{
+	return 0;
+}
+
+static int scmi_imx_misc_ctrl_probe(struct scmi_device *sdev)
+{
+	const struct scmi_handle *handle = sdev->handle;
+	struct device_node *np = sdev->dev.of_node;
+	u32 src_id, evt_id, wu_num;
+	int ret, i;
+
+	if (!handle)
+		return -ENODEV;
+
+	imx_misc_ctrl_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_IMX_MISC, &ph);
+	if (IS_ERR(imx_misc_ctrl_ops))
+		return PTR_ERR(imx_misc_ctrl_ops);
+
+	scmi_imx_misc_ctrl_nb.notifier_call = &scmi_imx_misc_ctrl_notifier;
+	wu_num = of_property_count_u32_elems(np, "wakeup-sources");
+	if (wu_num % 2) {
+		dev_err(&sdev->dev, "Invalid wakeup-sources\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < wu_num; i += 2) {
+		WARN_ON(of_property_read_u32_index(np, "wakeup-sources", i, &src_id));
+		WARN_ON(of_property_read_u32_index(np, "wakeup-sources", i + 1, &evt_id));
+		ret = handle->notify_ops->devm_event_notifier_register(sdev, SCMI_PROTOCOL_IMX_MISC,
+								       evt_id,
+								       &src_id,
+								       &scmi_imx_misc_ctrl_nb);
+		if (ret)
+			dev_err(&sdev->dev, "Failed to register scmi misc event: %d\n", src_id);
+	}
+
+	return 0;
+
+}
+
+static const struct scmi_device_id scmi_id_table[] = {
+	{ SCMI_PROTOCOL_IMX_MISC, "imx-misc-ctrl" },
+	{ },
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static struct scmi_driver scmi_imx_misc_ctrl_driver = {
+	.name = "scmi-imx-misc-ctrl",
+	.probe = scmi_imx_misc_ctrl_probe,
+	.id_table = scmi_id_table,
+};
+module_scmi_driver(scmi_imx_misc_ctrl_driver);
+
+MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
+MODULE_DESCRIPTION("IMX SM MISC driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/firmware/imx/sm.h b/include/linux/firmware/imx/sm.h
new file mode 100644
index 000000000000..daad4bdf7d1c
--- /dev/null
+++ b/include/linux/firmware/imx/sm.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef _SCMI_IMX_H
+#define _SCMI_IMX_H
+
+#include <linux/bitfield.h>
+#include <linux/types.h>
+
+#define SCMI_IMX_CTRL_PDM_CLK_SEL	0	/* AON PDM clock sel */
+#define SCMI_IMX_CTRL_MQS1_SETTINGS	1	/* AON MQS settings */
+#define SCMI_IMX_CTRL_SAI1_MCLK		2	/* AON SAI1 MCLK */
+#define SCMI_IMX_CTRL_SAI3_MCLK		3	/* WAKE SAI3 MCLK */
+#define SCMI_IMX_CTRL_SAI4_MCLK		4	/* WAKE SAI4 MCLK */
+#define SCMI_IMX_CTRL_SAI5_MCLK		5	/* WAKE SAI5 MCLK */
+
+#if IS_ENABLED(CONFIG_IMX_SCMI_MISC_EXT)
+int scmi_imx_misc_ctrl_get(u32 id, u32 *num, u32 *val);
+int scmi_imx_misc_ctrl_set(u32 id, u32 val);
+#else
+static inline int scmi_imx_misc_ctrl_get(u32 id, u32 *num, u32 *val)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int scmi_imx_misc_ctrl_set(u32 id, u32 val);
+{
+	return -EOPNOTSUPP;
+}
+#endif
+#endif

-- 
2.37.1



From sakari.ailus at iki.fi  Thu Feb  1 22:49:38 2024
From: sakari.ailus at iki.fi (Sakari Ailus)
Date: Fri, 2 Feb 2024 06:49:38 +0000
Subject: [PATCH v9 4/5] documentation: media: add documentation for
 Toshiba Visconti Video Input Interface driver
In-Reply-To: <TYAPR01MB620180FF82B8993B45FF6E0A9286A@TYAPR01MB6201.jpnprd01.prod.outlook.com>
References: <20231012071329.2542003-1-yuji2.ishikawa@toshiba.co.jp>
 <20231012071329.2542003-5-yuji2.ishikawa@toshiba.co.jp>
 <ZV3oq0szH8JjSNsc@valkosipuli.retiisi.eu>
 <TYAPR01MB620180FF82B8993B45FF6E0A9286A@TYAPR01MB6201.jpnprd01.prod.outlook.com>
Message-ID: <ZbyQgkGicrnP-XZL@valkosipuli.retiisi.eu>

Hi Yuji,

On Mon, Dec 04, 2023 at 04:32:40AM +0000, yuji2.ishikawa at toshiba.co.jp wrote:
> > > +Vendor specific v4l2 controls
> > > +=============================
> > > +
> > > +.. _V4L2_CID_VISCONTI_VIIF_MAIN_SET_RAWPACK_MODE:
> > > +
> > > +V4L2_CID_VISCONTI_VIIF_MAIN_SET_RAWPACK_MODE
> > > +--------------------------------------------
> > > +
> > > +This control sets the format to pack multiple RAW pixel values into a word.
> > > +
> > > +This control accepts a __u32 value defined as `enum viif_rawpack_mode`.
> > > +
> > > +This control should be set before ioctl(S_FMT) and should not be changed
> > after that.
> > 
> > Why do you need this? Doesn't the V4L2 pixelformat already explicitly define
> > the format, including packing?
> > 
> 
> This control value affects the unpacker between CSI2 receiver and ISP.
> The rawpack mode is an option to receive from Wide-Dynamic-Range image
> sensors, whose output bit width is larger than standard format (RAW20,
> RAW24). For example, some WDR image sensors split 20 bit value into
> upper/lower 10bit values, then put them into consective pixels to make a
> double-width RAW10 format image.

Do you have a sensor that really does this? Which one is it?

> 
> This option is only related to the interpretation of CSI2 input data.
> Therefore, I think V4L2 pixel format (for resulting image) is not related
> to it. The media bus format seems more relevant, but there is no
> corresponding definition to this case.

-- 
Regards,

Sakari Ailus


From krzysztof.kozlowski at linaro.org  Thu Feb  1 23:17:09 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 08:17:09 +0100
Subject: [PATCH v2 3/5] dt-bindings: memory: additional compatible strings
 for Broadcom DPFE
In-Reply-To: <CAGt4E5taqv2kgK4ZF6R+otKwrVYiaNNkeCu5Qv7xW8cyBvv3Fw@mail.gmail.com>
References: <20240119215231.758844-1-mmayer@broadcom.com>
 <20240119215231.758844-4-mmayer@broadcom.com>
 <f46951b9-36b0-4155-b6ac-3d3f7cc8ef37@linaro.org>
 <CAGt4E5taqv2kgK4ZF6R+otKwrVYiaNNkeCu5Qv7xW8cyBvv3Fw@mail.gmail.com>
Message-ID: <636c626e-118c-475f-909d-4f6cdbfb07eb@linaro.org>

On 01/02/2024 23:36, Markus Mayer wrote:
> On Tue, 23 Jan 2024 at 13:27, Krzysztof Kozlowski
> <krzysztof.kozlowski at linaro.org> wrote:
>>
>> On 19/01/2024 22:52, Markus Mayer wrote:
>>> Add versioned compatible strings for Broadcom DPFE. These take the form
>>> brcm,dpfe-cpu-v<N> where <N> is a number from 1 to 4.
>>>
>>> The chip-specific strings have been kept for compatibility purposes
>>> (hardware is in the field). For new chips, the properly versioned
>>> compatible string should be used.
>>>
>>> Signed-off-by: Markus Mayer <mmayer at broadcom.com>
>>> ---
>>>  .../memory-controllers/brcm,dpfe-cpu.yaml     | 21 ++++++++++++++++++-
>>>  1 file changed, 20 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
>>> index 3f00bc2fd3ec..42c8160d95d1 100644
>>> --- a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
>>> +++ b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
>>> @@ -10,9 +10,28 @@ maintainers:
>>>    - Krzysztof Kozlowski <krzk at kernel.org>
>>>    - Markus Mayer <mmayer at broadcom.com>
>>>
>>> +description: |
>>> +
>>
>> Drop blank line.
> 
> Will do.
> 
>>> +  The DCPU (DDR PHY Front End CPU) interfaces directly with the DDR PHY
>>> +  chip on Broadcom STB SoCs. An API exists for other agents to retrieve
>>> +  or set certain DDR PHY chip parameters by JEDEC.
>>> +
>>> +  Different, incompatible versions of this API have been created over
>>> +  time. The API has changed for the some chips as development progressed
>>> +  and features were added or changed.
>>> +
>>> +  We rely on the boot firmware (which already knows the API version
>>> +  required) to populate Device Tree with the corresponding compatible
>>> +  string.
>>> +
>>>  properties:
>>>    compatible:
>>>      items:
>>> +      - enum:
>>> +          - brcm,dpfe-cpu-v1
>>> +          - brcm,dpfe-cpu-v2
>>> +          - brcm,dpfe-cpu-v3
>>> +          - brcm,dpfe-cpu-v4
>>
>> I don't see my comment resolved - except more unusual order of
>> compatibles - and nothing in commit msg explains my previous concerns.
> 
> I am confused. What about ordering them in alphabetically ascending
> order is unusual?

Order of entire list - you just added everything to the beginning of the
list. This does not make sense.

> 
> Which concerns, specifically, are you referencing? I promise I am not

That you claim here that bcm7271 is both v1, v2, v3 and v4. Nothing in
the commit msg explains this.

Nothing from my message here:
https://lore.kernel.org/all/3fff866f-fbe8-4d23-87f3-275380adf3d4 at linaro.org/
is resolved or addressed.


> deliberately ignoring concerns as there would be no point in doing so.
> I have nothing to gain from it. I am trying to get code accepted into
> the kernel. I am not trying to "win any battles" or "prove that I can
> be more stubborn" or anything of that nature. If it is possible to
> integrate concerns raised by the maintainer, I will gladly do so. And
> if not, I'd like to find a way that works for both sides.
> 
> BTW, I once used to be on the Linaro Landing Team for Broadcom. You'll
> find some commits from me in the kernel that carry a linaro.org e-mail
> address. Most are from over a decade ago. Yikes, time flies!
> 
> The reason I am mentioning this is to point out that
> 
> * I am not new to this.
> * I am respecting the Open Source community and so is the rest of the team.
> * We are trying to do the right thing and be "good citizens".
> * We upstream whatever we can to the relevant project, not just the kernel.
> * We aren't on some kind of power-trip or unwilling to listen to feedback.

OK, I see you sent the almost same patch with no improvements in the
code and in commit msg, so that was the assumption. I made quite clear
concerns last time and asked several questions.

> 
> I am not saying this because I think any of the above makes me special
> or particularly accomplished. However, I do think that some things may
> need to be clarified as there does seem to be a certain attitude at
> play here, with certain assumptions, that is far from constructive.
> Hopefully, this has now been cleared up, and we can move forward with
> addressing the outstanding concerns regarding our DPFE compatible
> strings.
> 
>> I think my final comment was pretty clear yet ignored completely. There
>> was no follow up:
>> https://lore.kernel.org/all/3fff866f-fbe8-4d23-87f3-275380adf3d4 at linaro.org/
> 
> Unfortunately, it may not be as clear as you think. I did my best to
> incorporate what I thought you meant. Clearly that didn't work out so
> well.
> 
> So, please clarify in more detail, and maybe showing some examples,
> what it is you would like to see. For instance, I have no idea what
> "(e.g. bcm7271 + v1 + generic fallback)" is actually supposed to mean.

This means: List of three compatibles, SoC specific, your versioned one,
generic compatible used as fallback.

> Is that shorthand for 3 compatible strings (brcm,bcm7271-dpfe-cpu,
> brcm,dpfe-cpu-v1, brcm,dpfe-cpu). If so, how is that different from
> what we already had?

If something is unclear in that message, please continue that message.
There was no further explanation, no further comments on my email, so I
assume you agree or understand it.

> 
>> so with ignored comments: NAK

Also - missing device prefix in subject:

Please use subject prefixes matching the subsystem. You can get them for
example with `git log --oneline -- DIRECTORY_OR_FILE` on the directory
your patch is touching.


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb  1 23:24:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 08:24:38 +0100
Subject: [PATCH v2 4/5] memory: brcmstb_dpfe: introduce version-specific
 compatible strings
In-Reply-To: <CAGt4E5uE1Ms8vJbw2tE7fgcxeE9=vPYsa8y2FsJtQt-7jrjE_Q@mail.gmail.com>
References: <20240119215231.758844-1-mmayer@broadcom.com>
 <20240119215231.758844-5-mmayer@broadcom.com>
 <bc20da6e-bf97-415b-ba78-ae29311ae38f@linaro.org>
 <CAGt4E5uE1Ms8vJbw2tE7fgcxeE9=vPYsa8y2FsJtQt-7jrjE_Q@mail.gmail.com>
Message-ID: <9a8819f1-5a28-4ecb-8094-89316366428f@linaro.org>

On 01/02/2024 23:40, Markus Mayer wrote:
> On Tue, 23 Jan 2024 at 13:28, Krzysztof Kozlowski
> <krzysztof.kozlowski at linaro.org> wrote:
>>
>> On 19/01/2024 22:52, Markus Mayer wrote:
>>> Introduce compatible strings brcm,dpfe-cpu-v1 through brcm,dpfe-cpu-v3
>>> to the Broadcom DPFE driver.
>>
>> Nothing improved here. I think my last comment was pretty clear what I
>> expect.
> 
> You are correct. Nothing changed here. I did not get the impression
> that you were asking for changes to the actual driver code.

I think my concern was pretty obvious:
"No, why?"

Your commit msg is pointless. Says nothing. It says what you do, but it
is obvious and redundant. I see what you do from the patch diff.

What your commit msg is supposed to say, is explain why this is needed
and what problem are you solving.

This applies to all your commits, to all projects, downstream or
upstream. Repeating what the diff is doing is trivial and does not help
people to understand why this commit is there and what is the commit's
bigger impact.

So after I asked to provide rationale, you send exactly the same commit
without rationale.

And this is repeating in this entire patchset. Patch #1 only mentions
"no actual benefit", but it is discussible. It provides benefit in my
opinion and nothing in your commit msg gives arguments to support your
clause. Patch #2 does not need more explanations but it also does not
make sense in entire series - you want to drop the specific compatibles!
What's more patch #2 does not make any sense with combination of patch
#3 and it is not explained in the commit msg.

Patch #3 also brings zero explanations why you are doing it. From all
four patches, only one had some sort of explanation - patch #1.

Best regards,
Krzysztof



From oliver.upton at linux.dev  Thu Feb  1 23:36:08 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 2 Feb 2024 07:36:08 +0000
Subject: [PATCH v4 1/5] KVM: selftests: aarch64: Make the
 [create|destroy]_vpmu_vm() public
In-Reply-To: <20240202025659.5065-2-shahuang@redhat.com>
References: <20240202025659.5065-1-shahuang@redhat.com>
 <20240202025659.5065-2-shahuang@redhat.com>
Message-ID: <ZbybaH2t7Yp9NJOK@linux.dev>

On Thu, Feb 01, 2024 at 09:56:50PM -0500, Shaoqin Huang wrote:

[...]

> diff --git a/tools/testing/selftests/kvm/include/aarch64/vpmu.h b/tools/testing/selftests/kvm/include/aarch64/vpmu.h
> new file mode 100644
> index 000000000000..0a56183644ee
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/include/aarch64/vpmu.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#include <kvm_util.h>
> +
> +#define GICD_BASE_GPA	0x8000000ULL
> +#define GICR_BASE_GPA	0x80A0000ULL

Shouldn't a standardized layout of the GIC frames go with the rest of
the GIC stuff?

> +/* Create a VM that has one vCPU with PMUv3 configured. */
> +struct vpmu_vm *create_vpmu_vm(void *guest_code)
> +{
> +	struct kvm_vcpu_init init;
> +	uint8_t pmuver;
> +	uint64_t dfr0, irq = 23;
> +	struct kvm_device_attr irq_attr = {
> +		.group = KVM_ARM_VCPU_PMU_V3_CTRL,
> +		.attr = KVM_ARM_VCPU_PMU_V3_IRQ,
> +		.addr = (uint64_t)&irq,
> +	};
> +	struct kvm_device_attr init_attr = {
> +		.group = KVM_ARM_VCPU_PMU_V3_CTRL,
> +		.attr = KVM_ARM_VCPU_PMU_V3_INIT,
> +	};
> +	struct vpmu_vm *vpmu_vm;
> +
> +	vpmu_vm = calloc(1, sizeof(*vpmu_vm));
> +	TEST_ASSERT(vpmu_vm != NULL, "Insufficient Memory");

!vpmu_vm would be the normal way to test if a pointer is NULL.

> +	memset(vpmu_vm, 0, sizeof(vpmu_vm));

What? man calloc would tell you that the returned object is already
zero-initalized.

> +	vpmu_vm->vm = vm_create(1);
> +	vm_init_descriptor_tables(vpmu_vm->vm);
> +
> +	/* Create vCPU with PMUv3 */
> +	vm_ioctl(vpmu_vm->vm, KVM_ARM_PREFERRED_TARGET, &init);
> +	init.features[0] |= (1 << KVM_ARM_VCPU_PMU_V3);
> +	vpmu_vm->vcpu = aarch64_vcpu_add(vpmu_vm->vm, 0, &init, guest_code);
> +	vcpu_init_descriptor_tables(vpmu_vm->vcpu);

I extremely dislike that the VM is semi-configured by this helper.
You're still expecting the caller to actually install the exception
handler.

> +	vpmu_vm->gic_fd = vgic_v3_setup(vpmu_vm->vm, 1, 64,
> +					GICD_BASE_GPA, GICR_BASE_GPA);
> +	__TEST_REQUIRE(vpmu_vm->gic_fd >= 0,
> +		       "Failed to create vgic-v3, skipping");
> +
> +	/* Make sure that PMUv3 support is indicated in the ID register */
> +	vcpu_get_reg(vpmu_vm->vcpu,
> +		     KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &dfr0);
> +	pmuver = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), dfr0);
> +	TEST_ASSERT(pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF &&
> +		    pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP,
> +		    "Unexpected PMUVER (0x%x) on the vCPU with PMUv3", pmuver);

Not your code, but this assertion is meaningless. KVM does not advertise
an IMP_DEF PMU to guests.

> +	/* Initialize vPMU */
> +	vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &irq_attr);
> +	vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &init_attr);

Not your code, but these should be converted to kvm_device_attr_set()
calls.

Overall I'm somewhat tepid on the idea of the library being so
coarse-grained. It is usually more helpful to expose finer-grained
controls, like a helper that initializes the vPMU state for a
preexisting VM. That way the PMU code can more easily be composed with
other helpers in different tests.

-- 
Thanks,
Oliver


From oliver.upton at linux.dev  Thu Feb  1 23:44:56 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 2 Feb 2024 07:44:56 +0000
Subject: [PATCH v4 2/5] KVM: selftests: aarch64: Move pmu helper
 functions into vpmu.h
In-Reply-To: <20240202025659.5065-3-shahuang@redhat.com>
References: <20240202025659.5065-1-shahuang@redhat.com>
 <20240202025659.5065-3-shahuang@redhat.com>
Message-ID: <ZbydeB5MEJIhxaw6@linux.dev>

On Thu, Feb 01, 2024 at 09:56:51PM -0500, Shaoqin Huang wrote:
> -static uint64_t get_pmcr_n(uint64_t pmcr)
> -{
> -	return FIELD_GET(ARMV8_PMU_PMCR_N, pmcr);
> -}
> -
> -static void set_pmcr_n(uint64_t *pmcr, uint64_t pmcr_n)
> -{
> -	u64p_replace_bits((__u64 *) pmcr, pmcr_n, ARMV8_PMU_PMCR_N);
> -}
> -
> -static uint64_t get_counters_mask(uint64_t n)
> -{
> -	uint64_t mask = BIT(ARMV8_PMU_CYCLE_IDX);
> -
> -	if (n)
> -		mask |= GENMASK(n - 1, 0);
> -	return mask;
> -}

I don't see these helpers being used by your test, and they seem rather
specific to what the original test was trying to accomplish. Let's not
move this unnecessarily.

-- 
Thanks,
Oliver


From krzysztof.kozlowski at linaro.org  Thu Feb  1 23:49:55 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 08:49:55 +0100
Subject: [PATCH] tty: serial: samsung: Remove superfluous braces in macro
In-Reply-To: <20240202010507.22638-1-semen.protsenko@linaro.org>
References: <20240202010507.22638-1-semen.protsenko@linaro.org>
Message-ID: <bed3d775-2d80-445f-bf28-b28a17a6370c@linaro.org>

On 02/02/2024 02:05, Sam Protsenko wrote:
> Commit 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
> removes parameters from EXYNOS_COMMON_SERIAL_DRV_DATA() macro, but
> leaves unnecessary empty braces. Remove those to fix the style. No
> functional change.
> 
> Fixes: 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  drivers/tty/serial/samsung_tty.c | 8 ++++----

I am pretty sure you did the patch on some old tree, not mainline rc1.
Please work on maintainers tree (or linux-next).

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb  1 23:54:55 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 08:54:55 +0100
Subject: [PATCH v5 4/8] dt-bindings: usb: ci-hdrc-usb2: add restrictions
 for reg, interrupts, clock and clock-names properties
In-Reply-To: <20240131114324.3722428-4-xu.yang_2@nxp.com>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-4-xu.yang_2@nxp.com>
Message-ID: <a0134089-a283-488b-8d7f-3f59dd938b60@linaro.org>

On 31/01/2024 12:43, Xu Yang wrote:
> Change reg, interrupts, clock and clock-names as common properties and add
> restrictions on them for different compatibles.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v4:
>  - new patch since v3's discussion
>  - split the reg, interrupts, clock and clock-names properties into
>    common part and device-specific
> Changes in v5:
>  - keep common property unchanged
>  - make if-then more readable
>  - remove non imx part
> ---
>  .../devicetree/bindings/usb/ci-hdrc-usb2.yaml | 118 ++++++++++++++++++
>  1 file changed, 118 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> index 3b56e0edb1c6..6ad3582051b8 100644
> --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> @@ -412,6 +412,124 @@ allOf:
>          samsung,picophy-pre-emp-curr-control: false
>          samsung,picophy-dc-vol-level-adjust: false
>  
> +  - if:
> +      properties:
> +        compatible:
> +          const: fsl,imx27-usb
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 3
> +          maxItems: 3
> +        clock-names:
> +          minItems: 3
> +          maxItems: 3
> +          items:
> +            anyOf:
> +              - const: ipg
> +              - const: ahb
> +              - const: per

This would be just: enum: [ipg, ahb, per], but in both cases I question
why the order should be flexible? Nothing in commit msg explains it.

Plus I will repeat myself from your v4. I don't think this is helping,
because the file will soon grow to umnanageable chunk. I prefer to fix
it at beginning, before we reach snps-schema level of complexities.

Please define common schema, reference in this file and move IMX to own
file.

In any case, please provide short comment in the code why you have such
duplicated if:then:

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb  1 23:56:34 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 08:56:34 +0100
Subject: [PATCH v5 5/8] dt-bindings: usb: ci-hdrc-usb2: add compatible and
 clock-names restriction for imx93
In-Reply-To: <20240131114324.3722428-5-xu.yang_2@nxp.com>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-5-xu.yang_2@nxp.com>
Message-ID: <41d1bc21-ea4a-4af6-93a6-b498ac1896ef@linaro.org>

On 31/01/2024 12:43, Xu Yang wrote:
> The i.MX93 needs a wakup clock to work properly. This will add compatible
> and restriction for i.MX93 platform.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v2:
>  - no changes
> Changes in v3:
>  - add clocks restriction
> Changes in v4:
>  - use 'contains' rather 'items'
> Changes in v5:
>  - rename clock name
> ---
>  .../devicetree/bindings/usb/ci-hdrc-usb2.yaml | 35 ++++++++++++++++++-
>  1 file changed, 34 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> index 6ad3582051b8..12466f7af00b 100644
> --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> @@ -57,6 +57,7 @@ properties:
>            - enum:
>                - fsl,imx8mm-usb
>                - fsl,imx8mn-usb
> +              - fsl,imx93-usb
>            - const: fsl,imx7d-usb
>            - const: fsl,imx27-usb
>        - items:
> @@ -486,7 +487,6 @@ allOf:
>                - chipidea,usb2
>                - fsl,imx23-usb
>                - fsl,imx28-usb
> -              - fsl,imx7d-usb
>                - fsl,vf610-usb
>      then:
>        properties:
> @@ -497,6 +497,38 @@ allOf:
>            minItems: 1
>            maxItems: 1
>  
> +  - if:
> +      properties:
> +        compatible:
> +          items:
> +            - const: fsl,imx7d-usb
> +            - const: fsl,imx27-usb

This does not look related to imx93.

> +    then:
> +      properties:
> +        clocks:
> +          minItems: 1
> +          maxItems: 1
> +        clock-names:
> +          minItems: 1
> +          maxItems: 1
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - fsl,imx93-usb
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 2
> +          maxItems: 2
> +        clock-names:
> +          minItems: 2
> +          maxItems: 2
> +          contains:
> +            const: usb_wakeup

No, clocks must be fixed and specific. No contains allowed for new variants.

> +
>    - if:
>        properties:
>          compatible:
> @@ -504,6 +536,7 @@ allOf:
>              oneOf:
>                - pattern: '^fsl,imx5[0-3]+-usb$'
>                - pattern: '^fsl,imx6[a-z]+-usb$'
> +              - pattern: '^fsl,imx8[a-z]+-usb$'

Aren't you adding imx9?



Best regards,
Krzysztof



From ryan.roberts at arm.com  Fri Feb  2 00:07:31 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:31 +0000
Subject: [PATCH v5 00/25] Transparent Contiguous PTEs for User Mappings
Message-ID: <20240202080756.1453939-1-ryan.roberts@arm.com>

Hi All,

This is a series to opportunistically and transparently use contpte mappings
(set the contiguous bit in ptes) for user memory when those mappings meet the
requirements. The change benefits arm64, but there is some minor refactoring for
x86 and powerpc to enable its integration with core-mm.

It is part of a wider effort to improve performance by allocating and mapping
variable-sized blocks of memory (folios). One aim is for the 4K kernel to
approach the performance of the 16K kernel, but without breaking compatibility
and without the associated increase in memory. Another aim is to benefit the 16K
and 64K kernels by enabling 2M THP, since this is the contpte size for those
kernels. We have good performance data that demonstrates both aims are being met
(see below).

Of course this is only one half of the change. We require the mapped physical
memory to be the correct size and alignment for this to actually be useful (i.e.
64K for 4K pages, or 2M for 16K/64K pages). Fortunately folios are solving this
problem for us. Filesystems that support it (XFS, AFS, EROFS, tmpfs, ...) will
allocate large folios up to the PMD size today, and more filesystems are coming.
And for anonymous memory, "multi-size THP" is now upstream.


Patch Layout
============

In this version, I've split the patches to better show each optimization:

  - 1-2:    mm prep: misc code and docs cleanups
  - 3-8:    mm,arm,arm64,powerpc,x86 prep: Replace pte_next_pfn() with more
            general pte_advance_pfn()
  - 9-18:   arm64 prep: Refactor ptep helpers into new layer
  - 19:     functional contpte implementation
  - 20-25:  various optimizations on top of the contpte implementation


Testing
=======

I've tested this series on both Ampere Altra (bare metal) and Apple M2 (VM):
  - mm selftests (inc new tests written for multi-size THP); no regressions
  - Speedometer Java script benchmark in Chromium web browser; no issues
  - Kernel compilation; no issues
  - Various tests under high memory pressure with swap enabled; no issues


Performance
===========

High Level Use Cases
~~~~~~~~~~~~~~~~~~~~

First some high level use cases (kernel compilation and speedometer JavaScript
benchmarks). These are running on Ampere Altra (I've seen similar improvements
on Android/Pixel 6).

baseline:                  mm-unstable (mTHP switched off)
mTHP:                      + enable 16K, 32K, 64K mTHP sizes "always"
mTHP + contpte:            + this series
mTHP + contpte + exefolio: + patch at [5], which series supports

Kernel Compilation with -j8 (negative is faster):

| kernel                    | real-time | kern-time | user-time |
|---------------------------|-----------|-----------|-----------|
| baseline                  |      0.0% |      0.0% |      0.0% |
| mTHP                      |     -5.0% |    -39.1% |     -0.7% |
| mTHP + contpte            |     -6.0% |    -41.4% |     -1.5% |
| mTHP + contpte + exefolio |     -7.8% |    -43.1% |     -3.4% |

Kernel Compilation with -j80 (negative is faster):

| kernel                    | real-time | kern-time | user-time |
|---------------------------|-----------|-----------|-----------|
| baseline                  |      0.0% |      0.0% |      0.0% |
| mTHP                      |     -5.0% |    -36.6% |     -0.6% |
| mTHP + contpte            |     -6.1% |    -38.2% |     -1.6% |
| mTHP + contpte + exefolio |     -7.4% |    -39.2% |     -3.2% |

Speedometer (positive is faster):

| kernel                    | runs_per_min |
|:--------------------------|--------------|
| baseline                  |         0.0% |
| mTHP                      |         1.5% |
| mTHP + contpte            |         3.2% |
| mTHP + contpte + exefolio |         4.5% |


Micro Benchmarks
~~~~~~~~~~~~~~~~

The following microbenchmarks are intended to demonstrate the performance of
fork() and munmap() do not regress. I'm showing results for order-0 (4K)
mappings, and for order-9 (2M) PTE-mapped THP. Thanks to David for sharing his
benchmarks.

baseline:                  mm-unstable + batch fork [6] and zap [7] series
contpte-basic:             + patches 0-19; functional contpte implementation
contpte-batch:             + patches 20-23; implement new batched APIs
contpte-inline:            + patch 24; __always_inline to help compiler
contpte-fold:              + patch 25; fold contpte mapping when sensible

Primary platform is Ampere Altra bare metal. I'm also showing results for M2 VM
(on top of MacOS) for reference, although experience suggests this might not be
the most reliable for performance numbers of this sort:

| FORK           |         order-0        |         order-9        |
| Ampere Altra   |------------------------|------------------------|
| (pte-map)      |       mean |     stdev |       mean |     stdev |
|----------------|------------|-----------|------------|-----------|
| baseline       |       0.0% |      2.7% |       0.0% |      0.2% |
| contpte-basic  |       6.3% |      1.4% |    1948.7% |      0.2% |
| contpte-batch  |       7.6% |      2.0% |      -1.9% |      0.4% |
| contpte-inline |       3.6% |      1.5% |      -1.0% |      0.2% |
| contpte-fold   |       4.6% |      2.1% |      -1.8% |      0.2% |

| MUNMAP         |         order-0        |         order-9        |
| Ampere Altra   |------------------------|------------------------|
| (pte-map)      |       mean |     stdev |       mean |     stdev |
|----------------|------------|-----------|------------|-----------|
| baseline       |       0.0% |      0.5% |       0.0% |      0.3% |
| contpte-basic  |       1.8% |      0.3% |    1104.8% |      0.1% |
| contpte-batch  |      -0.3% |      0.4% |       2.7% |      0.1% |
| contpte-inline |      -0.1% |      0.6% |       0.9% |      0.1% |
| contpte-fold   |       0.1% |      0.6% |       0.8% |      0.1% |

| FORK           |         order-0        |         order-9        |
| Apple M2 VM    |------------------------|------------------------|
| (pte-map)      |       mean |     stdev |       mean |     stdev |
|----------------|------------|-----------|------------|-----------|
| baseline       |       0.0% |      1.4% |       0.0% |      0.8% |
| contpte-basic  |       6.8% |      1.2% |     469.4% |      1.4% |
| contpte-batch  |      -7.7% |      2.0% |      -8.9% |      0.7% |
| contpte-inline |      -6.0% |      2.1% |      -6.0% |      2.0% |
| contpte-fold   |       5.9% |      1.4% |      -6.4% |      1.4% |

| MUNMAP         |         order-0        |         order-9        |
| Apple M2 VM    |------------------------|------------------------|
| (pte-map)      |       mean |     stdev |       mean |     stdev |
|----------------|------------|-----------|------------|-----------|
| baseline       |       0.0% |      0.6% |       0.0% |      0.4% |
| contpte-basic  |       1.6% |      0.6% |     233.6% |      0.7% |
| contpte-batch  |       1.9% |      0.3% |      -3.9% |      0.4% |
| contpte-inline |       2.2% |      0.8% |      -1.6% |      0.9% |
| contpte-fold   |       1.5% |      0.7% |      -1.7% |      0.7% |

Misc
~~~~

John Hubbard at Nvidia has indicated dramatic 10x performance improvements for
some workloads at [8], when using 64K base page kernel.

---
I'd really like to get this into v6.9; I've spoken with Catalin and he is happy
for this to go via the mm-unstable branch, once suitably acked by arm64 folks.
That makes most sense because the series depends on some changes from David at
[6] and [7], which in turn apply on top of mm-unstable as of a few days ago
(d162e170f118).


Changes since v4 [4]
====================

  - Rebased onto David's generic fork [6] and zap [8] batching work
      - I had an implementation similar to this prior to v4, but ditched it
        because I couldn't make it reliably provide a speedup; David succeeded.
      - roughly speaking, a few functions get renamed compared to v4:
          - pte_batch_remaining() -> pte_batch_hint()
	  - set_wrprotects() -> wrprotect_ptes()
          - clear_ptes() -> [get_and_]clear_full_ptes()
      - Had to convert pte_next_pfn() to pte_advance_pfn()
      - Integration into core-mm is simpler because most has been done by
        David's work
  - Reworked patches to better show the progression from basic implementation to
    the various optimizations.
  - Removed the 'full' flag that I added to set_ptes() and set_wrprotects() in
    v4: I've been able to make up most of the performance in other ways, so this
    keeps the interface simpler.
  - Simplified contpte_set_ptes(nr > 1): Observed that set_ptes(nr > 1) is only
    called for ptes that are initially not present. So updated the spec to
    require that, and no longer need to check if any ptes are initially present
    when applying a contpte mapping.


Changes since v3 [3]
====================

  - Added v3#1 to batch set_ptes() when splitting a huge pmd to ptes; avoids
    need to fold contpte blocks for perf improvement
  - Separated the clear_ptes() fast path into its own inline function (Alistair)
  - Reworked core-mm changes to copy_present_ptes() and zap_pte_range() to
    remove overhead when memory is all order-0 folios (for arm64 and !arm64)
  - Significant optimization of arm64 backend fork operations (set_ptes_full()
    and set_wrprotects()) to ensure no regression when memory is order-0 folios.
  - fixed local variable declarations to be reverse xmas tree. - Added
    documentation for the new backend APIs (pte_batch_remaining(),
    set_ptes_full(), clear_ptes(), ptep_set_wrprotects())
  - Renamed tlb_get_guaranteed_space() -> tlb_reserve_space() and pass requested
    number of slots. Avoids allocating memory when not needed; perf improvement.


Changes since v2 [2]
====================

  - Removed contpte_ptep_get_and_clear_full() optimisation for exit() (v2#14),
    and replaced with a batch-clearing approach using a new arch helper,
    clear_ptes() (v3#2 and v3#15) (Alistair and Barry)
  - (v2#1 / v3#1)
      - Fixed folio refcounting so that refcount >= mapcount always (DavidH)
      - Reworked batch demarcation to avoid pte_pgprot() (DavidH)
      - Reverted return semantic of copy_present_page() and instead fix it up in
        copy_present_ptes() (Alistair)
      - Removed page_cont_mapped_vaddr() and replaced with simpler logic
        (Alistair)
      - Made batch accounting clearer in copy_pte_range() (Alistair)
  - (v2#12 / v3#13)
      - Renamed contpte_fold() -> contpte_convert() and hoisted setting/
        clearing CONT_PTE bit to higher level (Alistair)


Changes since v1 [1]
====================

  - Export contpte_* symbols so that modules can continue to call inline
    functions (e.g. ptep_get) which may now call the contpte_* functions (thanks
    to JohnH)
  - Use pte_valid() instead of pte_present() where sensible (thanks to Catalin)
  - Factor out (pte_valid() && pte_cont()) into new pte_valid_cont() helper
    (thanks to Catalin)
  - Fixed bug in contpte_ptep_set_access_flags() where TLBIs were missed (thanks
    to Catalin)
  - Added ARM64_CONTPTE expert Kconfig (enabled by default) (thanks to Anshuman)
  - Simplified contpte_ptep_get_and_clear_full()
  - Improved various code comments


[1] https://lore.kernel.org/linux-arm-kernel/20230622144210.2623299-1-ryan.roberts at arm.com/
[2] https://lore.kernel.org/linux-arm-kernel/20231115163018.1303287-1-ryan.roberts at arm.com/
[3] https://lore.kernel.org/linux-arm-kernel/20231204105440.61448-1-ryan.roberts at arm.com/
[4] https://lore.kernel.org/lkml/20231218105100.172635-1-ryan.roberts at arm.com/
[5] https://lore.kernel.org/lkml/08c16f7d-f3b3-4f22-9acc-da943f647dc3 at arm.com/
[6] https://lore.kernel.org/lkml/20240129124649.189745-1-david at redhat.com/
[7] https://lore.kernel.org/lkml/20240129143221.263763-1-david at redhat.com/
[8] https://lore.kernel.org/linux-mm/c507308d-bdd4-5f9e-d4ff-e96e4520be85 at nvidia.com/


Thanks,
Ryan

Ryan Roberts (25):
  mm: Clarify the spec for set_ptes()
  mm: thp: Batch-collapse PMD with set_ptes()
  mm: Make pte_next_pfn() a wrapper around pte_advance_pfn()
  arm/mm: Convert pte_next_pfn() to pte_advance_pfn()
  arm64/mm: Convert pte_next_pfn() to pte_advance_pfn()
  powerpc/mm: Convert pte_next_pfn() to pte_advance_pfn()
  x86/mm: Convert pte_next_pfn() to pte_advance_pfn()
  mm: Remove pte_next_pfn() and replace with pte_advance_pfn()
  arm64/mm: set_pte(): New layer to manage contig bit
  arm64/mm: set_ptes()/set_pte_at(): New layer to manage contig bit
  arm64/mm: pte_clear(): New layer to manage contig bit
  arm64/mm: ptep_get_and_clear(): New layer to manage contig bit
  arm64/mm: ptep_test_and_clear_young(): New layer to manage contig bit
  arm64/mm: ptep_clear_flush_young(): New layer to manage contig bit
  arm64/mm: ptep_set_wrprotect(): New layer to manage contig bit
  arm64/mm: ptep_set_access_flags(): New layer to manage contig bit
  arm64/mm: ptep_get(): New layer to manage contig bit
  arm64/mm: Split __flush_tlb_range() to elide trailing DSB
  arm64/mm: Wire up PTE_CONT for user mappings
  arm64/mm: Implement new wrprotect_ptes() batch API
  arm64/mm: Implement new [get_and_]clear_full_ptes() batch APIs
  mm: Add pte_batch_hint() to reduce scanning in folio_pte_batch()
  arm64/mm: Implement pte_batch_hint()
  arm64/mm: __always_inline to improve fork() perf
  arm64/mm: Automatically fold contpte mappings

 arch/arm/mm/mmu.c                 |   2 +-
 arch/arm64/Kconfig                |   9 +
 arch/arm64/include/asm/pgtable.h  | 404 ++++++++++++++++++++++++++----
 arch/arm64/include/asm/tlbflush.h |  13 +-
 arch/arm64/kernel/efi.c           |   4 +-
 arch/arm64/kernel/mte.c           |   2 +-
 arch/arm64/kvm/guest.c            |   2 +-
 arch/arm64/mm/Makefile            |   1 +
 arch/arm64/mm/contpte.c           | 399 +++++++++++++++++++++++++++++
 arch/arm64/mm/fault.c             |  12 +-
 arch/arm64/mm/fixmap.c            |   4 +-
 arch/arm64/mm/hugetlbpage.c       |  40 +--
 arch/arm64/mm/kasan_init.c        |   6 +-
 arch/arm64/mm/mmu.c               |  16 +-
 arch/arm64/mm/pageattr.c          |   6 +-
 arch/arm64/mm/trans_pgd.c         |   6 +-
 arch/powerpc/mm/pgtable.c         |   2 +-
 arch/x86/include/asm/pgtable.h    |   8 +-
 include/linux/pgtable.h           |  29 ++-
 mm/huge_memory.c                  |  58 +++--
 mm/memory.c                       |  20 +-
 21 files changed, 906 insertions(+), 137 deletions(-)
 create mode 100644 arch/arm64/mm/contpte.c

--
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:32 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:32 +0000
Subject: [PATCH v5 01/25] mm: Clarify the spec for set_ptes()
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-2-ryan.roberts@arm.com>

set_ptes() spec implies that it can only be used to set a present pte
because it interprets the PFN field to increment it. However,
set_pte_at() has been implemented on top of set_ptes() since set_ptes()
was introduced, and set_pte_at() allows setting a pte to a not-present
state. So clarify the spec to state that when nr==1, new state of pte
may be present or not present. When nr>1, new state of all ptes must be
present.

While we are at it, tighten the spec to set requirements around the
initial state of ptes; when nr==1 it may be either present or
not-present. But when nr>1 all ptes must initially be not-present. All
set_ptes() callsites already conform to this requirement. Stating it
explicitly is useful because it allows for a simplification to the
upcoming arm64 contpte implementation.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 include/linux/pgtable.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index f0feae7f89fb..5e7eaf8f2b97 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -229,6 +229,10 @@ static inline pte_t pte_next_pfn(pte_t pte)
  * @pte: Page table entry for the first page.
  * @nr: Number of pages to map.
  *
+ * When nr==1, initial state of pte may be present or not present, and new state
+ * may be present or not present. When nr>1, initial state of all ptes must be
+ * not present, and new state must be present.
+ *
  * May be overridden by the architecture, or the architecture can define
  * set_pte() and PFN_PTE_SHIFT.
  *
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:33 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:33 +0000
Subject: [PATCH v5 02/25] mm: thp: Batch-collapse PMD with set_ptes()
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-3-ryan.roberts@arm.com>

Refactor __split_huge_pmd_locked() so that a present PMD can be
collapsed to PTEs in a single batch using set_ptes().

This should improve performance a little bit, but the real motivation is
to remove the need for the arm64 backend to have to fold the contpte
entries. Instead, since the ptes are set as a batch, the contpte blocks
can be initially set up pre-folded (once the arm64 contpte support is
added in the next few patches). This leads to noticeable performance
improvement during split.

Acked-by: David Hildenbrand <david at redhat.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 mm/huge_memory.c | 58 +++++++++++++++++++++++++++---------------------
 1 file changed, 33 insertions(+), 25 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 016e20bd813e..14888b15121e 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2579,15 +2579,16 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
 
 	pte = pte_offset_map(&_pmd, haddr);
 	VM_BUG_ON(!pte);
-	for (i = 0, addr = haddr; i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE) {
-		pte_t entry;
-		/*
-		 * Note that NUMA hinting access restrictions are not
-		 * transferred to avoid any possibility of altering
-		 * permissions across VMAs.
-		 */
-		if (freeze || pmd_migration) {
+
+	/*
+	 * Note that NUMA hinting access restrictions are not transferred to
+	 * avoid any possibility of altering permissions across VMAs.
+	 */
+	if (freeze || pmd_migration) {
+		for (i = 0, addr = haddr; i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE) {
+			pte_t entry;
 			swp_entry_t swp_entry;
+
 			if (write)
 				swp_entry = make_writable_migration_entry(
 							page_to_pfn(page + i));
@@ -2606,25 +2607,32 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
 				entry = pte_swp_mksoft_dirty(entry);
 			if (uffd_wp)
 				entry = pte_swp_mkuffd_wp(entry);
-		} else {
-			entry = mk_pte(page + i, READ_ONCE(vma->vm_page_prot));
-			if (write)
-				entry = pte_mkwrite(entry, vma);
-			if (!young)
-				entry = pte_mkold(entry);
-			/* NOTE: this may set soft-dirty too on some archs */
-			if (dirty)
-				entry = pte_mkdirty(entry);
-			if (soft_dirty)
-				entry = pte_mksoft_dirty(entry);
-			if (uffd_wp)
-				entry = pte_mkuffd_wp(entry);
+
+			VM_WARN_ON(!pte_none(ptep_get(pte + i)));
+			set_pte_at(mm, addr, pte + i, entry);
 		}
-		VM_BUG_ON(!pte_none(ptep_get(pte)));
-		set_pte_at(mm, addr, pte, entry);
-		pte++;
+	} else {
+		pte_t entry;
+
+		entry = mk_pte(page, READ_ONCE(vma->vm_page_prot));
+		if (write)
+			entry = pte_mkwrite(entry, vma);
+		if (!young)
+			entry = pte_mkold(entry);
+		/* NOTE: this may set soft-dirty too on some archs */
+		if (dirty)
+			entry = pte_mkdirty(entry);
+		if (soft_dirty)
+			entry = pte_mksoft_dirty(entry);
+		if (uffd_wp)
+			entry = pte_mkuffd_wp(entry);
+
+		for (i = 0; i < HPAGE_PMD_NR; i++)
+			VM_WARN_ON(!pte_none(ptep_get(pte + i)));
+
+		set_ptes(mm, haddr, pte, entry, HPAGE_PMD_NR);
 	}
-	pte_unmap(pte - 1);
+	pte_unmap(pte);
 
 	if (!pmd_migration)
 		folio_remove_rmap_pmd(folio, page, vma);
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:34 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:34 +0000
Subject: [PATCH v5 03/25] mm: Make pte_next_pfn() a wrapper around pte_advance_pfn()
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-4-ryan.roberts@arm.com>

The goal is to be able to advance a PTE by an arbitrary number of PFNs.
So introduce a new API that takes a nr param.

We are going to remove pte_next_pfn() and replace it with
pte_advance_pfn(). As a first step, implement pte_next_pfn() as a
wrapper around pte_advance_pfn() so that we can incrementally switch the
architectures over. Once all arches are moved over, we will change all
the core-mm callers to call pte_advance_pfn() directly and remove the
wrapper.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 include/linux/pgtable.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 5e7eaf8f2b97..815d92dcb96b 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -214,9 +214,15 @@ static inline int pmd_dirty(pmd_t pmd)
 
 
 #ifndef pte_next_pfn
+#ifndef pte_advance_pfn
+static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
+{
+	return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
+}
+#endif
 static inline pte_t pte_next_pfn(pte_t pte)
 {
-	return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
+	return pte_advance_pfn(pte, 1);
 }
 #endif
 
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:35 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:35 +0000
Subject: [PATCH v5 04/25] arm/mm: Convert pte_next_pfn() to pte_advance_pfn()
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-5-ryan.roberts@arm.com>

Core-mm needs to be able to advance the pfn by an arbitrary amount, so
improve the API to do so and change the name.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm/mm/mmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index c24e29c0b9a4..137711c68f2f 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1814,6 +1814,6 @@ void set_ptes(struct mm_struct *mm, unsigned long addr,
 		if (--nr == 0)
 			break;
 		ptep++;
-		pteval = pte_next_pfn(pteval);
+		pteval = pte_advance_pfn(pteval, 1);
 	}
 }
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:36 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:36 +0000
Subject: [PATCH v5 05/25] arm64/mm: Convert pte_next_pfn() to pte_advance_pfn()
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-6-ryan.roberts@arm.com>

Core-mm needs to be able to advance the pfn by an arbitrary amount, so
improve the API to do so and change the name.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 9428801c1040..6a6cc78cf879 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -351,10 +351,10 @@ static inline pgprot_t pte_pgprot(pte_t pte)
 	return __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte));
 }
 
-#define pte_next_pfn pte_next_pfn
-static inline pte_t pte_next_pfn(pte_t pte)
+#define pte_advance_pfn pte_advance_pfn
+static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 {
-	return pfn_pte(pte_pfn(pte) + 1, pte_pgprot(pte));
+	return pfn_pte(pte_pfn(pte) + nr, pte_pgprot(pte));
 }
 
 static inline void set_ptes(struct mm_struct *mm,
@@ -370,7 +370,7 @@ static inline void set_ptes(struct mm_struct *mm,
 		if (--nr == 0)
 			break;
 		ptep++;
-		pte = pte_next_pfn(pte);
+		pte = pte_advance_pfn(pte, 1);
 	}
 }
 #define set_ptes set_ptes
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:37 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:37 +0000
Subject: [PATCH v5 06/25] powerpc/mm: Convert pte_next_pfn() to pte_advance_pfn()
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-7-ryan.roberts@arm.com>

Core-mm needs to be able to advance the pfn by an arbitrary amount, so
improve the API to do so and change the name.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/powerpc/mm/pgtable.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 549a440ed7f6..6853cdb1290d 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -220,7 +220,7 @@ void set_ptes(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
 			break;
 		ptep++;
 		addr += PAGE_SIZE;
-		pte = pte_next_pfn(pte);
+		pte = pte_advance_pfn(pte, 1);
 	}
 }
 
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:38 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:38 +0000
Subject: [PATCH v5 07/25] x86/mm: Convert pte_next_pfn() to pte_advance_pfn()
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-8-ryan.roberts@arm.com>

Core-mm needs to be able to advance the pfn by an arbitrary amount, so
improve the API to do so and change the name.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/x86/include/asm/pgtable.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 9d077bca6a10..b60b0c897b4c 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -956,13 +956,13 @@ static inline int pte_same(pte_t a, pte_t b)
 	return a.pte == b.pte;
 }
 
-static inline pte_t pte_next_pfn(pte_t pte)
+static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 {
 	if (__pte_needs_invert(pte_val(pte)))
-		return __pte(pte_val(pte) - (1UL << PFN_PTE_SHIFT));
-	return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
+		return __pte(pte_val(pte) - (nr << PFN_PTE_SHIFT));
+	return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
 }
-#define pte_next_pfn	pte_next_pfn
+#define pte_advance_pfn	pte_advance_pfn
 
 static inline int pte_present(pte_t a)
 {
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:39 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:39 +0000
Subject: [PATCH v5 08/25] mm: Remove pte_next_pfn() and replace with pte_advance_pfn()
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-9-ryan.roberts@arm.com>

Now that the architectures are converted over to pte_advance_pfn(), we
can remove the pte_next_pfn() wrapper and convert the callers to call
pte_advance_pfn().

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 include/linux/pgtable.h | 9 +--------
 mm/memory.c             | 4 ++--
 2 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 815d92dcb96b..50f32cccbd92 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -212,19 +212,12 @@ static inline int pmd_dirty(pmd_t pmd)
 #define arch_flush_lazy_mmu_mode()	do {} while (0)
 #endif
 
-
-#ifndef pte_next_pfn
 #ifndef pte_advance_pfn
 static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 {
 	return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
 }
 #endif
-static inline pte_t pte_next_pfn(pte_t pte)
-{
-	return pte_advance_pfn(pte, 1);
-}
-#endif
 
 #ifndef set_ptes
 /**
@@ -256,7 +249,7 @@ static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
 		if (--nr == 0)
 			break;
 		ptep++;
-		pte = pte_next_pfn(pte);
+		pte = pte_advance_pfn(pte, 1);
 	}
 	arch_leave_lazy_mmu_mode();
 }
diff --git a/mm/memory.c b/mm/memory.c
index 38a010c4d04d..65fbe4f886c1 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -988,7 +988,7 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
 {
 	unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio);
 	const pte_t *end_ptep = start_ptep + max_nr;
-	pte_t expected_pte = __pte_batch_clear_ignored(pte_next_pfn(pte), flags);
+	pte_t expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, 1), flags);
 	pte_t *ptep = start_ptep + 1;
 	bool writable;
 
@@ -1017,7 +1017,7 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
 		if (any_writable)
 			*any_writable |= writable;
 
-		expected_pte = pte_next_pfn(expected_pte);
+		expected_pte = pte_advance_pfn(expected_pte, 1);
 		ptep++;
 	}
 
-- 
2.25.1



From beata.michalska at arm.com  Fri Feb  2 00:08:03 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Fri, 2 Feb 2024 09:08:03 +0100
Subject: [PATCH] cpufreq: CPPC: Resolve the large frequency discrepancy
 from cpuinfo_cur_freq
In-Reply-To: <a84a9749-97a5-a207-dfd3-8322a5a992d9@huawei.com>
References: <20231212072617.14756-1-lihuisong@huawei.com>
 <ZZWfJOsDlEXWYHA5@arm.com>
 <9428a1ed-ba4d-1fe6-63e8-11e152bf1f09@huawei.com>
 <lnocwcitdbmgcyhd2dlczgdlhtfw4pfot2br2i3hqscnvr3xgq@nuxlauxum3nr>
 <d0f47e9d-6a58-8b46-89be-b3182abb69f0@huawei.com>
 <ZZwAmqp6hcmMF8aN@arm.com>
 <6505bdcb-5a5f-cba6-483b-75c51414a9c6@huawei.com>
 <ZaaOQzCpBjmW71xf@e129154.nice.arm.com>
 <a84a9749-97a5-a207-dfd3-8322a5a992d9@huawei.com>
Message-ID: <Zbyi40XtqbqXm0CL@e129154.nice.arm.com>

On Wed, Jan 17, 2024 at 05:18:40PM +0800, lihuisong (C) wrote:

Hi ,

Again, apologies for delay,

> Hi,
> 
> ? 2024/1/16 22:10, Beata Michalska ??:
> > Hi,
> > 
> > Apologies for jumping in so late....
> > 
> > On Wed, Jan 10, 2024 at 03:09:48PM +0800, lihuisong (C) wrote:
> > > Hi Ionela,
> > > 
> > > ? 2024/1/8 22:03, Ionela Voinescu ??:
> > > > Hi,
> > > > 
> > > > On Friday 05 Jan 2024 at 15:04:47 (+0800), lihuisong (C) wrote:
> > > > > Hi Vanshi,
> > > > > 
> > > > > ? 2024/1/5 8:48, Vanshidhar Konda ??:
> > > > > > On Thu, Jan 04, 2024 at 05:36:51PM +0800, lihuisong (C) wrote:
> > > > > > > ? 2024/1/4 1:53, Ionela Voinescu ??:
> > > > > > > > Hi,
> > > > > > > > 
> > > > > > > > On Tuesday 12 Dec 2023 at 15:26:17 (+0800), Huisong Li wrote:
> > > > > > > > > Many developers found that the cpu current frequency is greater than
> > > > > > > > > the maximum frequency of the platform, please see [1], [2] and [3].
> > > > > > > > > 
> > > > > > > > > In the scenarios with high memory access pressure, the patch [1] has
> > > > > > > > > proved the significant latency of cpc_read() which is used to obtain
> > > > > > > > > delivered and reference performance counter cause an absurd frequency.
> > > > > > > > > The sampling interval for this counters is very critical and
> > > > > > > > > is expected
> > > > > > > > > to be equal. However, the different latency of cpc_read() has a direct
> > > > > > > > > impact on their sampling interval.
> > > > > > > > > 
> > > > > > > > Would this [1] alternative solution work for you?
> > > > > > > It would work for me AFAICS.
> > > > > > > Because the "arch_freq_scale" is also from AMU core and constant
> > > > > > > counter, and read together.
> > > > > > > But, from their discuss line, it seems that there are some tricky
> > > > > > > points to clarify or consider.
> > > > > > I think the changes in [1] would work better when CPUs may be idle. With
> > > > > > this
> > > > > > patch we would have to wake any core that is in idle state to read the
> > > > > > AMU
> > > > > > counters. Worst case, if core 0 is trying to read the CPU frequency of
> > > > > > all
> > > > > > cores, it may need to wake up all the other cores to read the AMU
> > > > > > counters.
> > > > >   From the approach in [1], if all CPUs (one or more cores) under one policy
> > > > > are idle, they still cannot be obtained the CPU frequency, right?
> > > > > In this case, the [1] API will return 0 and have to back to call
> > > > > cpufreq_driver->get() for cpuinfo_cur_freq.
> > > > > Then we still need to face the issue this patch mentioned.
> > > > With the implementation at [1], arch_freq_get_on_cpu() will not return 0
> > > > for idle CPUs and the get() callback will not be called to wake up the
> > > > CPUs.
> > > Right, arch_freq_get_on_cpu() will not return 0 for idle CPUs.
> > > However, for no-housekeeping CPUs, it will return 0 and have to call get()
> > > callback, right?
> > > > Worst case, arch_freq_get_on_cpu() will return a frequency based on the
> > > > AMU counter values obtained on the last tick on that CPU. But if that CPU
> > > > is not a housekeeping CPU, a housekeeping CPU in the same policy will be
> > > > selected, as it would have had a more recent tick, and therefore a more
> > > > recent frequency value for the domain.
> > > But this frequency is from the last tick,
> > > this last tick is probably a long time ago and it doesn't update
> > > 'arch_freq_scale' for some reasons like CPU dile.
> > > In addition, I'm not sure if there is possible that amu_scale_freq_tick() is
> > > executed delayed under high stress case.
> > > It also have an impact on the accuracy of the cpu frequency we query.
> > > > I understand that the frequency returned here will not be up to date,
> > > > but there's no proper frequency feedback for an idle CPU. If one only
> > > > wakes up a CPU to sample counters, before the CPU goes back to sleep,
> > > > the obtained frequency feedback is meaningless.
> > > > 
> > > > > > For systems with 128 cores or more, this could be very expensive and
> > > > > > happen
> > > > > > very frequently.
> > > > > > 
> > > > > > AFAICS, the approach in [1] would avoid this cost.
> > > > > But the CPU frequency is just an average value for the last tick period
> > > > > instead of the current one the CPU actually runs at.
> > > > > In addition, there are some conditions to use 'arch_freq_scale' in this
> > > > > approach.
> > > > What are the conditions you are referring to?
> > > It depends on the housekeeping CPUs.
> > > > > So I'm not sure if this approach can entirely cover the frequency
> > > > > discrepancy issue.
> > > > Unfortunately there is no perfect frequency feedback. By the time you
> > > > observe/use the value of scaling_cur_freq/cpuinfo_cur_freq, the frequency
> > > > of the CPU might have already changed. Therefore, an average value might
> > > > be a better indication of the recent performance level of a CPU.
> > > An average value for CPU frequency is ok. It may be better if it has not any
> > > delaying.
> > > 
> > > The original implementation for cpuinfo_cur_freq can more reflect their
> > > meaning in the user-guide [1]. The user-guide said:
> > > "cpuinfo_cur_freq : Current frequency of the CPU as obtained from the
> > > hardware, in KHz.
> > > This is the frequency the CPU actually runs at."
> > > 
> > > 
> > > [1]https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt
> > > 
> > > > Would you be able to test [1] on your platform and usecase?
> > > I has tested it on my platform (CPU number: 64, SMT: off and CPU base
> > > frequency: 2.7GHz).
> > > Accoding to the testing result,
> > > 1> I found that patch [1] and [2] cannot cover the no housekeeping CPUs.
> > > They still have to face the large frequency discrepancy issue my patch
> > > mentioned.
> > > 2> Additionally, the frequency value of all CPUs are almost the same by
> > > using the 'arch_freq_scale' factor way. I'm not sure if it is ok.
> > > 
> > > The patch [1] has been modified silightly as below:
> > > -->
> > > @@ -1756,7 +1756,10 @@ static unsigned int
> > > cpufreq_verify_current_freq(struct cpufreq_policy *policy, b
> > >  ?{
> > >  ??????? unsigned int new_freq;
> > > 
> > > -?????? new_freq = cpufreq_driver->get(policy->cpu);
> > > +?????? new_freq = arch_freq_get_on_cpu(policy->cpu);
> > > +?????? if (!new_freq)
> > > +?????????????? new_freq = cpufreq_driver->get(policy->cpu);
> > > +
> > As pointed out this change will not make it to the next version of the patch.
> > So I'd say you can safely ignore it and assume that arch_freq_get_on_cpu will
> > only be wired for sysfs nodes for scaling_cur_freq/cpuinfo_cur_freq
> > >  ??????? if (!new_freq)
> > >  ??????????????? return 0;
> > > 
> > > And the result is as follows:
> > > *case 1:**No setting the nohz_full and cpufreq use performance governor*
> > > *--> Step1: *read 'cpuinfo_cur_freq' in no pressure
> > >  ? 0: 2699264???? 2: 2699264???? 4: 2699264???? 6: 2699264
> > >  ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2699264
> > >  ?16: 2699264??? 18: 2696628??? 20: 2699264??? 22: 2696628
> > >  ?24: 2699264??? 26: 2696628??? 28: 2699264??? 30: 2696628
> > >  ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
> > >  ?40: 2699264??? 42: 2699264??? 44: 2696628??? 46: 2696628
> > >  ?48: 2696628??? 50: 2699264??? 52: 2699264??? 54: 2696628
> > >  ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
> > >  ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2696628
> > >  ?72: 2699264??? 74: 2696628??? 76: 2696628??? 78: 2699264
> > >  ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
> > >  ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2699264
> > >  ?96: 2696628??? 98: 2699264?? 100: 2699264?? 102: 2696628
> > > 104: 2699264?? 106: 2699264?? 108: 2699264?? 110: 2696628
> > > 112: 2699264?? 114: 2699264?? 116: 2699264?? 118: 2699264
> > > 120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2699264
> > > Note: the frequency of all CPUs are almost the same.
> > Were you expecting smth else ?
> The frequency of each CPU might have a different value.
> All value of all CPUs is the same under high pressure.
> I don't know what the phenomenon is on other platform.
> Do you know who else tested it?
So I might have rushed a bit with my previous comment/question: apologies for
that.
The numbers above: those are on a fairly idle/lightly loaded system right?
Would you mind having another go with just the arch_freq_get_on_cpu
implementation beign added and dropping the changes in the cpufreq and
then read 'scaling_cur_freq', doing several reads in some intervals ?
The change has been tested on RD-N2 model (Neoverse N2 ref platform),
it has also been discussed here [1]

> > > *--> Step 2: *read 'cpuinfo_cur_freq' in the high memory access pressure.
> > >  ? 0: 2696628???? 2: 2696628???? 4: 2696628???? 6: 2696628
> > >  ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2696628
> > >  ?16: 2696628??? 18: 2696628??? 20: 2696628??? 22: 2696628
> > >  ?24: 2696628??? 26: 2696628??? 28: 2696628??? 30: 2696628
> > >  ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
> > >  ?40: 2696628??? 42: 2696628??? 44: 2696628??? 46: 2696628
> > >  ?48: 2696628??? 50: 2696628??? 52: 2696628??? 54: 2696628
> > >  ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
> > >  ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
> > >  ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2696628
> > >  ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
> > >  ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2696628
> > >  ?96: 2696628??? 98: 2696628?? 100: 2696628?? 102: 2696628
> > > 104: 2696628?? 106: 2696628?? 108: 2696628?? 110: 2696628
> > > 112: 2696628?? 114: 2696628?? 116: 2696628?? 118: 2696628
> > > 120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628
> > > 
> > > *Case 2: setting nohz_full and cpufreq use ondemand governor*
> > > There is "isolcpus=1-10,41-50 nohz_full=1-10,41-50 rcu_nocbs=1-10,41-50" in
> > > /proc/cmdline.
> > Right, so if I remember correctly nohz_full implies rcu_nocbs, so no need to
> > set that one.
> > Now, afair, isolcpus will make the selected CPUs to disappear from the
> > schedulers view (no balancing, no migrating), so unless you affine smth
> > explicitly to those CPUs, you will not see much of an activity there.
> Correct.
> > Need to double check though as it has been a while ...
> > > *--> Step 1: *setting ondemand governor to all policy and query
> > > 'cpuinfo_cur_freq' in no pressure case.
> > > And the frequency of CPUs all are about 400MHz.
> > > *--> Step 2:* read 'cpuinfo_cur_freq' in the high memory access pressure.
> > > The high memory access pressure is from the command: "stress-ng -c 64
> > > --cpu-load 100% --taskset 0-63"
> > I'm not entirely convinced that this will affine to isolated cpus, especially
> > that the affinity mask spans all available cpus. If that is the case, no wonder
> > your isolated cpus are getting wasted being idle. But I would have to double
> > check how this is being handled.
> > > The result:
> > >  ?0: 2696628???? 1:? 400000???? 2:? 400000???? 3:? 400909
> > >  ?4:? 400000???? 5:? 400000???? 6:? 400000???? 7:? 400000
> > >  ?8:? 400000???? 9:? 400000??? 10:? 400600??? 11: 2696628
> > > 12: 2696628??? 13: 2696628??? 14: 2696628??? 15: 2696628
> > > 16: 2696628??? 17: 2696628??? 18: 2696628??? 19: 2696628
> > > 20: 2696628??? 21: 2696628??? 22: 2696628??? 23: 2696628
> > > 24: 2696628??? 25: 2696628??? 26: 2696628??? 27: 2696628
> > > 28: 2696628??? 29: 2696628??? 30: 2696628??? 31: 2696628
> > > 32: 2696628??? 33: 2696628??? 34: 2696628??? 35: 2696628
> > > 36: 2696628??? 37: 2696628??? 38: 2696628??? 39: 2696628
> > > 40: 2696628??? 41:? 400000??? 42:? 400000??? 43:? 400000
> > > 44:? 400000??? 45:? 398847??? 46:? 400000??? 47:? 400000
> > > 48:? 400000??? 49:? 400000??? 50:? 400000??? 51: 2696628
> > > 52: 2696628??? 53: 2696628??? 54: 2696628??? 55: 2696628
> > > 56: 2696628??? 57: 2696628??? 58: 2696628??? 59: 2696628
> > > 60: 2696628??? 61: 2696628??? 62: 2696628??? 63: 2699264
> > > 
> > > Note:
> > > (1) The frequency of 1-10 and 41-50 CPUs work on the lowest frequency.
> > >  ???? It turned out that nohz full was already work.
> > >  ???? I guess that stress-ng cannot use the CPU in the range of nohz full.
> > >  ???? Because the CPU frequency will be increased to 2.7G by binding CPU to
> > > other application.
> > > (2) The frequency of the nohz full core is calculated by get() callback
> > > according to ftrace.
> > It is as there is no sched tick on those, and apparently there is nothing
> > running on them either.
> Yes.
> If we select your approach and the above phenomenon is normal,
> the large frequency discrepancy issue can be resolved for CPUs with sched
> tick by the way.
> But the nohz full cores still have to face this issue. So this patch is also
> needed.
> 
Yes, nohz cores full have to be handled by the cpufreq driver.

---
[1] https://lore.kernel.org/lkml/ZIHpd6unkOtYVEqP at e120325.cambridge.arm.com/T/#m4e74cb5a0aaa353c60fedc6cfb95ab7a6e381e3c
---
BR
Beata
> BR
> /huisong
> > 
> > Unless I am missing smth.
> > 
> > ---
> > BR
> > Beata
> > 
> > > [1] https://lore.kernel.org/lkml/20230418113459.12860-7-sumitg at nvidia.com/
> > > [2] https://lore.kernel.org/lkml/20231127160838.1403404-3-beata.michalska at arm.com/
> > > > Many thanks,
> > > > Ionela.
> > > > 
> > > > > /Huisong
> > > > > 
> > > > > > > > [1] https://lore.kernel.org/lkml/20231127160838.1403404-1-beata.michalska at arm.com/
> > > > > > > > 
> > > > > > > > Thanks,
> > > > > > > > Ionela.
> > > > > > > > 
> > > > > > > > > This patch adds a interface, cpc_read_arch_counters_on_cpu, to read
> > > > > > > > > delivered and reference performance counter together. According to my
> > > > > > > > > test[4], the discrepancy of cpu current frequency in the
> > > > > > > > > scenarios with
> > > > > > > > > high memory access pressure is lower than 0.2% by stress-ng
> > > > > > > > > application.
> > > > > > > > > 
> > > > > > > > > [1] https://lore.kernel.org/all/20231025093847.3740104-4-zengheng4 at huawei.com/
> > > > > > > > > [2] https://lore.kernel.org/all/20230328193846.8757-1-yang at os.amperecomputing.com/
> > > > > > > > > [3]
> > > > > > > > > https://lore.kernel.org/all/20230418113459.12860-7-sumitg at nvidia.com/
> > > > > > > > > 
> > > > > > > > > [4] My local test:
> > > > > > > > > The testing platform enable SMT and include 128 logical CPU in total,
> > > > > > > > > and CPU base frequency is 2.7GHz. Reading "cpuinfo_cur_freq" for each
> > > > > > > > > physical core on platform during the high memory access pressure from
> > > > > > > > > stress-ng, and the output is as follows:
> > > > > > > > >   ? 0: 2699133???? 2: 2699942???? 4: 2698189???? 6: 2704347
> > > > > > > > >   ? 8: 2704009??? 10: 2696277??? 12: 2702016??? 14: 2701388
> > > > > > > > >   ?16: 2700358??? 18: 2696741??? 20: 2700091??? 22: 2700122
> > > > > > > > >   ?24: 2701713??? 26: 2702025??? 28: 2699816??? 30: 2700121
> > > > > > > > >   ?32: 2700000??? 34: 2699788??? 36: 2698884??? 38: 2699109
> > > > > > > > >   ?40: 2704494??? 42: 2698350??? 44: 2699997??? 46: 2701023
> > > > > > > > >   ?48: 2703448??? 50: 2699501??? 52: 2700000??? 54: 2699999
> > > > > > > > >   ?56: 2702645??? 58: 2696923??? 60: 2697718??? 62: 2700547
> > > > > > > > >   ?64: 2700313??? 66: 2700000??? 68: 2699904??? 70: 2699259
> > > > > > > > >   ?72: 2699511??? 74: 2700644??? 76: 2702201??? 78: 2700000
> > > > > > > > >   ?80: 2700776??? 82: 2700364??? 84: 2702674??? 86: 2700255
> > > > > > > > >   ?88: 2699886??? 90: 2700359??? 92: 2699662??? 94: 2696188
> > > > > > > > >   ?96: 2705454??? 98: 2699260?? 100: 2701097?? 102: 2699630
> > > > > > > > > 104: 2700463?? 106: 2698408?? 108: 2697766?? 110: 2701181
> > > > > > > > > 112: 2699166?? 114: 2701804?? 116: 2701907?? 118: 2701973
> > > > > > > > > 120: 2699584?? 122: 2700474?? 124: 2700768?? 126: 2701963
> > > > > > > > > 
> > > > > > > > > Signed-off-by: Huisong Li <lihuisong at huawei.com>
> > > > > > > > > ---
> > > [snip]
> > > > .
> > .


From ryan.roberts at arm.com  Fri Feb  2 00:07:41 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:41 +0000
Subject: [PATCH v5 10/25] arm64/mm: set_ptes()/set_pte_at(): New layer to manage contig bit
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-11-ryan.roberts@arm.com>

Create a new layer for the in-table PTE manipulation APIs. For now, The
existing API is prefixed with double underscore to become the
arch-private API and the public API is just a simple wrapper that calls
the private API.

The public API implementation will subsequently be used to transparently
manipulate the contiguous bit where appropriate. But since there are
already some contig-aware users (e.g. hugetlb, kernel mapper), we must
first ensure those users use the private API directly so that the future
contig-bit manipulations in the public API do not interfere with those
existing uses.

set_pte_at() is a core macro that forwards to set_ptes() (with nr=1).
Instead of creating a __set_pte_at() internal macro, convert all arch
users to use set_ptes()/__set_ptes() directly, as appropriate. Callers
in hugetlb may benefit from calling __set_ptes() once for their whole
range rather than managing their own loop. This is left for future
improvement.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 10 +++++-----
 arch/arm64/kernel/mte.c          |  2 +-
 arch/arm64/kvm/guest.c           |  2 +-
 arch/arm64/mm/fault.c            |  2 +-
 arch/arm64/mm/hugetlbpage.c      | 10 +++++-----
 5 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 3cb45e8dbb52..f1fd6c5e3eca 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -358,9 +358,9 @@ static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 	return pfn_pte(pte_pfn(pte) + nr, pte_pgprot(pte));
 }
 
-static inline void set_ptes(struct mm_struct *mm,
-			    unsigned long __always_unused addr,
-			    pte_t *ptep, pte_t pte, unsigned int nr)
+static inline void __set_ptes(struct mm_struct *mm,
+			      unsigned long __always_unused addr,
+			      pte_t *ptep, pte_t pte, unsigned int nr)
 {
 	page_table_check_ptes_set(mm, ptep, pte, nr);
 	__sync_cache_and_tags(pte, nr);
@@ -374,7 +374,6 @@ static inline void set_ptes(struct mm_struct *mm,
 		pte = pte_advance_pfn(pte, 1);
 	}
 }
-#define set_ptes set_ptes
 
 /*
  * Huge pte definitions.
@@ -1079,7 +1078,7 @@ static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
 #endif /* CONFIG_ARM64_MTE */
 
 /*
- * On AArch64, the cache coherency is handled via the set_pte_at() function.
+ * On AArch64, the cache coherency is handled via the __set_ptes() function.
  */
 static inline void update_mmu_cache_range(struct vm_fault *vmf,
 		struct vm_area_struct *vma, unsigned long addr, pte_t *ptep,
@@ -1140,6 +1139,7 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 #endif
 
 #define set_pte					__set_pte
+#define set_ptes				__set_ptes
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index a41ef3213e1e..dcdcccd40891 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -67,7 +67,7 @@ int memcmp_pages(struct page *page1, struct page *page2)
 	/*
 	 * If the page content is identical but at least one of the pages is
 	 * tagged, return non-zero to avoid KSM merging. If only one of the
-	 * pages is tagged, set_pte_at() may zero or change the tags of the
+	 * pages is tagged, __set_ptes() may zero or change the tags of the
 	 * other page via mte_sync_tags().
 	 */
 	if (page_mte_tagged(page1) || page_mte_tagged(page2))
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index aaf1d4939739..629145fd3161 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -1072,7 +1072,7 @@ int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
 		} else {
 			/*
 			 * Only locking to serialise with a concurrent
-			 * set_pte_at() in the VMM but still overriding the
+			 * __set_ptes() in the VMM but still overriding the
 			 * tags, hence ignoring the return value.
 			 */
 			try_page_mte_tagging(page);
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 13189322a38f..23d0dfc16686 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -205,7 +205,7 @@ static void show_pte(unsigned long addr)
  *
  * It needs to cope with hardware update of the accessed/dirty state by other
  * agents in the system and can safely skip the __sync_icache_dcache() call as,
- * like set_pte_at(), the PTE is never changed from no-exec to exec here.
+ * like __set_ptes(), the PTE is never changed from no-exec to exec here.
  *
  * Returns whether or not the PTE actually changed.
  */
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 8116ac599f80..9d7e7315eaa3 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -254,12 +254,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 
 	if (!pte_present(pte)) {
 		for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
-			set_pte_at(mm, addr, ptep, pte);
+			__set_ptes(mm, addr, ptep, pte, 1);
 		return;
 	}
 
 	if (!pte_cont(pte)) {
-		set_pte_at(mm, addr, ptep, pte);
+		__set_ptes(mm, addr, ptep, pte, 1);
 		return;
 	}
 
@@ -270,7 +270,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	clear_flush(mm, addr, ptep, pgsize, ncontig);
 
 	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
-		set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
+		__set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
 }
 
 pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -478,7 +478,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 
 	hugeprot = pte_pgprot(pte);
 	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
-		set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
+		__set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
 
 	return 1;
 }
@@ -507,7 +507,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
 	pfn = pte_pfn(pte);
 
 	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
-		set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
+		__set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
 }
 
 pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:42 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:42 +0000
Subject: [PATCH v5 11/25] arm64/mm: pte_clear(): New layer to manage contig bit
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-12-ryan.roberts@arm.com>

Create a new layer for the in-table PTE manipulation APIs. For now, The
existing API is prefixed with double underscore to become the
arch-private API and the public API is just a simple wrapper that calls
the private API.

The public API implementation will subsequently be used to transparently
manipulate the contiguous bit where appropriate. But since there are
already some contig-aware users (e.g. hugetlb, kernel mapper), we must
first ensure those users use the private API directly so that the future
contig-bit manipulations in the public API do not interfere with those
existing uses.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 3 ++-
 arch/arm64/mm/fixmap.c           | 2 +-
 arch/arm64/mm/hugetlbpage.c      | 2 +-
 arch/arm64/mm/mmu.c              | 2 +-
 4 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index f1fd6c5e3eca..3b0ff58109c5 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -93,7 +93,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) \
+#define __pte_clear(mm, addr, ptep) \
 				__set_pte(ptep, __pte(0))
 #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
 
@@ -1140,6 +1140,7 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 
 #define set_pte					__set_pte
 #define set_ptes				__set_ptes
+#define pte_clear				__pte_clear
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
index 51cd4501816d..bfc02568805a 100644
--- a/arch/arm64/mm/fixmap.c
+++ b/arch/arm64/mm/fixmap.c
@@ -123,7 +123,7 @@ void __set_fixmap(enum fixed_addresses idx,
 	if (pgprot_val(flags)) {
 		__set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
 	} else {
-		pte_clear(&init_mm, addr, ptep);
+		__pte_clear(&init_mm, addr, ptep);
 		flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
 	}
 }
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 9d7e7315eaa3..3d73b83cf97f 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -400,7 +400,7 @@ void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
 	ncontig = num_contig_ptes(sz, &pgsize);
 
 	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
-		pte_clear(mm, addr, ptep);
+		__pte_clear(mm, addr, ptep);
 }
 
 pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 7cc1930f0e10..bcaa5a5d86f8 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -859,7 +859,7 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
 			continue;
 
 		WARN_ON(!pte_present(pte));
-		pte_clear(&init_mm, addr, ptep);
+		__pte_clear(&init_mm, addr, ptep);
 		flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
 		if (free_mapped)
 			free_hotplug_page_range(pte_page(pte),
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:40 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:40 +0000
Subject: [PATCH v5 09/25] arm64/mm: set_pte(): New layer to manage contig bit
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-10-ryan.roberts@arm.com>

Create a new layer for the in-table PTE manipulation APIs. For now, The
existing API is prefixed with double underscore to become the
arch-private API and the public API is just a simple wrapper that calls
the private API.

The public API implementation will subsequently be used to transparently
manipulate the contiguous bit where appropriate. But since there are
already some contig-aware users (e.g. hugetlb, kernel mapper), we must
first ensure those users use the private API directly so that the future
contig-bit manipulations in the public API do not interfere with those
existing uses.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 11 +++++++----
 arch/arm64/kernel/efi.c          |  2 +-
 arch/arm64/mm/fixmap.c           |  2 +-
 arch/arm64/mm/kasan_init.c       |  4 ++--
 arch/arm64/mm/mmu.c              |  2 +-
 arch/arm64/mm/pageattr.c         |  2 +-
 arch/arm64/mm/trans_pgd.c        |  4 ++--
 7 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6a6cc78cf879..3cb45e8dbb52 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -93,7 +93,8 @@ 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(ptep, __pte(0))
 #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
 
 /*
@@ -261,7 +262,7 @@ static inline pte_t pte_mkdevmap(pte_t pte)
 	return set_pte_bit(pte, __pgprot(PTE_DEVMAP | PTE_SPECIAL));
 }
 
-static inline void set_pte(pte_t *ptep, pte_t pte)
+static inline void __set_pte(pte_t *ptep, pte_t pte)
 {
 	WRITE_ONCE(*ptep, pte);
 
@@ -366,7 +367,7 @@ static inline void set_ptes(struct mm_struct *mm,
 
 	for (;;) {
 		__check_safe_pte_update(mm, ptep, pte);
-		set_pte(ptep, pte);
+		__set_pte(ptep, pte);
 		if (--nr == 0)
 			break;
 		ptep++;
@@ -540,7 +541,7 @@ static inline void __set_pte_at(struct mm_struct *mm,
 {
 	__sync_cache_and_tags(pte, nr);
 	__check_safe_pte_update(mm, ptep, pte);
-	set_pte(ptep, pte);
+	__set_pte(ptep, pte);
 }
 
 static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
@@ -1138,6 +1139,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 #define vmemmap_update_pte vmemmap_update_pte
 #endif
 
+#define set_pte					__set_pte
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_PGTABLE_H */
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 0228001347be..44288a12fc6c 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -111,7 +111,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
 		pte = set_pte_bit(pte, __pgprot(PTE_PXN));
 	else if (system_supports_bti_kernel() && spd->has_bti)
 		pte = set_pte_bit(pte, __pgprot(PTE_GP));
-	set_pte(ptep, pte);
+	__set_pte(ptep, pte);
 	return 0;
 }
 
diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
index c0a3301203bd..51cd4501816d 100644
--- a/arch/arm64/mm/fixmap.c
+++ b/arch/arm64/mm/fixmap.c
@@ -121,7 +121,7 @@ void __set_fixmap(enum fixed_addresses idx,
 	ptep = fixmap_pte(addr);
 
 	if (pgprot_val(flags)) {
-		set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
+		__set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
 	} else {
 		pte_clear(&init_mm, addr, ptep);
 		flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 4c7ad574b946..f659bd98c63f 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -112,7 +112,7 @@ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
 		if (!early)
 			memset(__va(page_phys), KASAN_SHADOW_INIT, PAGE_SIZE);
 		next = addr + PAGE_SIZE;
-		set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
+		__set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
 	} while (ptep++, addr = next, addr != end && pte_none(READ_ONCE(*ptep)));
 }
 
@@ -271,7 +271,7 @@ static void __init kasan_init_shadow(void)
 	 * so we should make sure that it maps the zero page read-only.
 	 */
 	for (i = 0; i < PTRS_PER_PTE; i++)
-		set_pte(&kasan_early_shadow_pte[i],
+		__set_pte(&kasan_early_shadow_pte[i],
 			pfn_pte(sym_to_pfn(kasan_early_shadow_page),
 				PAGE_KERNEL_RO));
 
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index d794b2f4b5a3..7cc1930f0e10 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -175,7 +175,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
 	do {
 		pte_t old_pte = READ_ONCE(*ptep);
 
-		set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
+		__set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
 
 		/*
 		 * After the PTE entry has been populated once, we
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 924843f1f661..a7996d8edf0a 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -41,7 +41,7 @@ static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
 	pte = clear_pte_bit(pte, cdata->clear_mask);
 	pte = set_pte_bit(pte, cdata->set_mask);
 
-	set_pte(ptep, pte);
+	__set_pte(ptep, pte);
 	return 0;
 }
 
diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
index 7b14df3c6477..230b607cf881 100644
--- a/arch/arm64/mm/trans_pgd.c
+++ b/arch/arm64/mm/trans_pgd.c
@@ -41,7 +41,7 @@ static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
 		 * read only (code, rodata). Clear the RDONLY bit from
 		 * the temporary mappings we use during restore.
 		 */
-		set_pte(dst_ptep, pte_mkwrite_novma(pte));
+		__set_pte(dst_ptep, pte_mkwrite_novma(pte));
 	} else if ((debug_pagealloc_enabled() ||
 		   is_kfence_address((void *)addr)) && !pte_none(pte)) {
 		/*
@@ -55,7 +55,7 @@ static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
 		 */
 		BUG_ON(!pfn_valid(pte_pfn(pte)));
 
-		set_pte(dst_ptep, pte_mkpresent(pte_mkwrite_novma(pte)));
+		__set_pte(dst_ptep, pte_mkpresent(pte_mkwrite_novma(pte)));
 	}
 }
 
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:44 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:44 +0000
Subject: [PATCH v5 13/25] arm64/mm: ptep_test_and_clear_young(): New layer to manage contig bit
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-14-ryan.roberts@arm.com>

Create a new layer for the in-table PTE manipulation APIs. For now, The
existing API is prefixed with double underscore to become the
arch-private API and the public API is just a simple wrapper that calls
the private API.

The public API implementation will subsequently be used to transparently
manipulate the contiguous bit where appropriate. But since there are
already some contig-aware users (e.g. hugetlb, kernel mapper), we must
first ensure those users use the private API directly so that the future
contig-bit manipulations in the public API do not interfere with those
existing uses.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 5f560326116e..77a8b100e1cd 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -899,8 +899,9 @@ static inline bool pud_user_accessible_page(pud_t pud)
 /*
  * 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 vm_area_struct *vma,
+					      unsigned long address,
+					      pte_t *ptep)
 {
 	pte_t old_pte, pte;
 
@@ -915,18 +916,11 @@ static inline int __ptep_test_and_clear_young(pte_t *ptep)
 	return pte_young(pte);
 }
 
-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);
-}
-
 #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
 static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
 					 unsigned long address, pte_t *ptep)
 {
-	int young = ptep_test_and_clear_young(vma, address, ptep);
+	int young = __ptep_test_and_clear_young(vma, address, ptep);
 
 	if (young) {
 		/*
@@ -949,7 +943,7 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 					    unsigned long address,
 					    pmd_t *pmdp)
 {
-	return ptep_test_and_clear_young(vma, address, (pte_t *)pmdp);
+	return __ptep_test_and_clear_young(vma, address, (pte_t *)pmdp);
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
@@ -1142,6 +1136,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 #define pte_clear				__pte_clear
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 #define ptep_get_and_clear			__ptep_get_and_clear
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define ptep_test_and_clear_young		__ptep_test_and_clear_young
 
 #endif /* !__ASSEMBLY__ */
 
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:46 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:46 +0000
Subject: [PATCH v5 15/25] arm64/mm: ptep_set_wrprotect(): New layer to manage contig bit
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-16-ryan.roberts@arm.com>

Create a new layer for the in-table PTE manipulation APIs. For now, The
existing API is prefixed with double underscore to become the
arch-private API and the public API is just a simple wrapper that calls
the private API.

The public API implementation will subsequently be used to transparently
manipulate the contiguous bit where appropriate. But since there are
already some contig-aware users (e.g. hugetlb, kernel mapper), we must
first ensure those users use the private API directly so that the future
contig-bit manipulations in the public API do not interfere with those
existing uses.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 10 ++++++----
 arch/arm64/mm/hugetlbpage.c      |  2 +-
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 2870bc12f288..4c2d6c483390 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -970,11 +970,11 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
 /*
- * ptep_set_wrprotect - mark read-only while trasferring potential hardware
+ * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
  * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
  */
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
+static inline void __ptep_set_wrprotect(struct mm_struct *mm,
+					unsigned long address, pte_t *ptep)
 {
 	pte_t old_pte, pte;
 
@@ -992,7 +992,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
 static inline void pmdp_set_wrprotect(struct mm_struct *mm,
 				      unsigned long address, pmd_t *pmdp)
 {
-	ptep_set_wrprotect(mm, address, (pte_t *)pmdp);
+	__ptep_set_wrprotect(mm, address, (pte_t *)pmdp);
 }
 
 #define pmdp_establish pmdp_establish
@@ -1139,6 +1139,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 #define ptep_test_and_clear_young		__ptep_test_and_clear_young
 #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
 #define ptep_clear_flush_young			__ptep_clear_flush_young
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define ptep_set_wrprotect			__ptep_set_wrprotect
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 7e74e7b67107..f6612f3e1c07 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -493,7 +493,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
 	pte_t pte;
 
 	if (!pte_cont(READ_ONCE(*ptep))) {
-		ptep_set_wrprotect(mm, addr, ptep);
+		__ptep_set_wrprotect(mm, addr, ptep);
 		return;
 	}
 
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:43 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:43 +0000
Subject: [PATCH v5 12/25] arm64/mm: ptep_get_and_clear(): New layer to manage contig bit
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-13-ryan.roberts@arm.com>

Create a new layer for the in-table PTE manipulation APIs. For now, The
existing API is prefixed with double underscore to become the
arch-private API and the public API is just a simple wrapper that calls
the private API.

The public API implementation will subsequently be used to transparently
manipulate the contiguous bit where appropriate. But since there are
already some contig-aware users (e.g. hugetlb, kernel mapper), we must
first ensure those users use the private API directly so that the future
contig-bit manipulations in the public API do not interfere with those
existing uses.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 5 +++--
 arch/arm64/mm/hugetlbpage.c      | 6 +++---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 3b0ff58109c5..5f560326116e 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -953,8 +953,7 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t __ptep_get_and_clear(struct mm_struct *mm,
 				       unsigned long address, pte_t *ptep)
 {
 	pte_t pte = __pte(xchg_relaxed(&pte_val(*ptep), 0));
@@ -1141,6 +1140,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 #define set_pte					__set_pte
 #define set_ptes				__set_ptes
 #define pte_clear				__pte_clear
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define ptep_get_and_clear			__ptep_get_and_clear
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 3d73b83cf97f..7e74e7b67107 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -188,7 +188,7 @@ static pte_t get_clear_contig(struct mm_struct *mm,
 	unsigned long i;
 
 	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) {
-		pte_t pte = ptep_get_and_clear(mm, addr, ptep);
+		pte_t pte = __ptep_get_and_clear(mm, addr, ptep);
 
 		/*
 		 * If HW_AFDBM is enabled, then the HW could turn on
@@ -236,7 +236,7 @@ static void clear_flush(struct mm_struct *mm,
 	unsigned long i, saddr = addr;
 
 	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
-		ptep_clear(mm, addr, ptep);
+		__ptep_get_and_clear(mm, addr, ptep);
 
 	flush_tlb_range(&vma, saddr, addr);
 }
@@ -411,7 +411,7 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
 	pte_t orig_pte = ptep_get(ptep);
 
 	if (!pte_cont(orig_pte))
-		return ptep_get_and_clear(mm, addr, ptep);
+		return __ptep_get_and_clear(mm, addr, ptep);
 
 	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
 
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:47 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:47 +0000
Subject: [PATCH v5 16/25] arm64/mm: ptep_set_access_flags(): New layer to manage contig bit
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-17-ryan.roberts@arm.com>

Create a new layer for the in-table PTE manipulation APIs. For now, The
existing API is prefixed with double underscore to become the
arch-private API and the public API is just a simple wrapper that calls
the private API.

The public API implementation will subsequently be used to transparently
manipulate the contiguous bit where appropriate. But since there are
already some contig-aware users (e.g. hugetlb, kernel mapper), we must
first ensure those users use the private API directly so that the future
contig-bit manipulations in the public API do not interfere with those
existing uses.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 10 ++++++----
 arch/arm64/mm/fault.c            |  6 +++---
 arch/arm64/mm/hugetlbpage.c      |  2 +-
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 4c2d6c483390..fe27a3175618 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -312,7 +312,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
 
 	/*
 	 * Check for potential race with hardware updates of the pte
-	 * (ptep_set_access_flags safely changes valid ptes without going
+	 * (__ptep_set_access_flags safely changes valid ptes without going
 	 * through an invalid entry).
 	 */
 	VM_WARN_ONCE(!pte_young(pte),
@@ -854,8 +854,7 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
 	return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
 }
 
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-extern int ptep_set_access_flags(struct vm_area_struct *vma,
+extern int __ptep_set_access_flags(struct vm_area_struct *vma,
 				 unsigned long address, pte_t *ptep,
 				 pte_t entry, int dirty);
 
@@ -865,7 +864,8 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
 					unsigned long address, pmd_t *pmdp,
 					pmd_t entry, int dirty)
 {
-	return ptep_set_access_flags(vma, address, (pte_t *)pmdp, pmd_pte(entry), dirty);
+	return __ptep_set_access_flags(vma, address, (pte_t *)pmdp,
+							pmd_pte(entry), dirty);
 }
 
 static inline int pud_devmap(pud_t pud)
@@ -1141,6 +1141,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 #define ptep_clear_flush_young			__ptep_clear_flush_young
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 #define ptep_set_wrprotect			__ptep_set_wrprotect
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+#define ptep_set_access_flags			__ptep_set_access_flags
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 23d0dfc16686..dbbc06cfb848 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -209,9 +209,9 @@ static void show_pte(unsigned long addr)
  *
  * Returns whether or not the PTE actually changed.
  */
-int ptep_set_access_flags(struct vm_area_struct *vma,
-			  unsigned long address, pte_t *ptep,
-			  pte_t entry, int dirty)
+int __ptep_set_access_flags(struct vm_area_struct *vma,
+			    unsigned long address, pte_t *ptep,
+			    pte_t entry, int dirty)
 {
 	pteval_t old_pteval, pteval;
 	pte_t pte = READ_ONCE(*ptep);
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index f6612f3e1c07..9949b80baac8 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -459,7 +459,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 	pte_t orig_pte;
 
 	if (!pte_cont(pte))
-		return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+		return __ptep_set_access_flags(vma, addr, ptep, pte, dirty);
 
 	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
 	dpfn = pgsize >> PAGE_SHIFT;
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:48 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:48 +0000
Subject: [PATCH v5 17/25] arm64/mm: ptep_get(): New layer to manage contig bit
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-18-ryan.roberts@arm.com>

Create a new layer for the in-table PTE manipulation APIs. For now, The
existing API is prefixed with double underscore to become the
arch-private API and the public API is just a simple wrapper that calls
the private API.

The public API implementation will subsequently be used to transparently
manipulate the contiguous bit where appropriate. But since there are
already some contig-aware users (e.g. hugetlb, kernel mapper), we must
first ensure those users use the private API directly so that the future
contig-bit manipulations in the public API do not interfere with those
existing uses.

arm64 did not previously define an arch-specific ptep_get(), so override
the default version in the arch code, and also define the private
__ptep_get() version. Currently they both do the same thing that the
default version does (READ_ONCE()). Some arch users (hugetlb) were
already using ptep_get() so convert those to the private API. While
other callsites were doing direct READ_ONCE(), so convert those to use
the appropriate (public/private) API too.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 12 +++++++++---
 arch/arm64/kernel/efi.c          |  2 +-
 arch/arm64/mm/fault.c            |  4 ++--
 arch/arm64/mm/hugetlbpage.c      | 18 +++++++++---------
 arch/arm64/mm/kasan_init.c       |  2 +-
 arch/arm64/mm/mmu.c              | 12 ++++++------
 arch/arm64/mm/pageattr.c         |  4 ++--
 arch/arm64/mm/trans_pgd.c        |  2 +-
 8 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index fe27a3175618..7dc6b68ee516 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -276,6 +276,11 @@ static inline void __set_pte(pte_t *ptep, pte_t pte)
 	}
 }
 
+static inline pte_t __ptep_get(pte_t *ptep)
+{
+	return READ_ONCE(*ptep);
+}
+
 extern void __sync_icache_dcache(pte_t pteval);
 bool pgattr_change_is_safe(u64 old, u64 new);
 
@@ -303,7 +308,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
 	if (!IS_ENABLED(CONFIG_DEBUG_VM))
 		return;
 
-	old_pte = READ_ONCE(*ptep);
+	old_pte = __ptep_get(ptep);
 
 	if (!pte_valid(old_pte) || !pte_valid(pte))
 		return;
@@ -905,7 +910,7 @@ static inline int __ptep_test_and_clear_young(struct vm_area_struct *vma,
 {
 	pte_t old_pte, pte;
 
-	pte = READ_ONCE(*ptep);
+	pte = __ptep_get(ptep);
 	do {
 		old_pte = pte;
 		pte = pte_mkold(pte);
@@ -978,7 +983,7 @@ static inline void __ptep_set_wrprotect(struct mm_struct *mm,
 {
 	pte_t old_pte, pte;
 
-	pte = READ_ONCE(*ptep);
+	pte = __ptep_get(ptep);
 	do {
 		old_pte = pte;
 		pte = pte_wrprotect(pte);
@@ -1130,6 +1135,7 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 #define vmemmap_update_pte vmemmap_update_pte
 #endif
 
+#define ptep_get				__ptep_get
 #define set_pte					__set_pte
 #define set_ptes				__set_ptes
 #define pte_clear				__pte_clear
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 44288a12fc6c..9afcc690fe73 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -103,7 +103,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
 {
 	struct set_perm_data *spd = data;
 	const efi_memory_desc_t *md = spd->md;
-	pte_t pte = READ_ONCE(*ptep);
+	pte_t pte = __ptep_get(ptep);
 
 	if (md->attribute & EFI_MEMORY_RO)
 		pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index dbbc06cfb848..892e8cc8983f 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -191,7 +191,7 @@ static void show_pte(unsigned long addr)
 		if (!ptep)
 			break;
 
-		pte = READ_ONCE(*ptep);
+		pte = __ptep_get(ptep);
 		pr_cont(", pte=%016llx", pte_val(pte));
 		pte_unmap(ptep);
 	} while(0);
@@ -214,7 +214,7 @@ int __ptep_set_access_flags(struct vm_area_struct *vma,
 			    pte_t entry, int dirty)
 {
 	pteval_t old_pteval, pteval;
-	pte_t pte = READ_ONCE(*ptep);
+	pte_t pte = __ptep_get(ptep);
 
 	if (pte_same(pte, entry))
 		return 0;
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 9949b80baac8..c3db949560f9 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -152,14 +152,14 @@ pte_t huge_ptep_get(pte_t *ptep)
 {
 	int ncontig, i;
 	size_t pgsize;
-	pte_t orig_pte = ptep_get(ptep);
+	pte_t orig_pte = __ptep_get(ptep);
 
 	if (!pte_present(orig_pte) || !pte_cont(orig_pte))
 		return orig_pte;
 
 	ncontig = num_contig_ptes(page_size(pte_page(orig_pte)), &pgsize);
 	for (i = 0; i < ncontig; i++, ptep++) {
-		pte_t pte = ptep_get(ptep);
+		pte_t pte = __ptep_get(ptep);
 
 		if (pte_dirty(pte))
 			orig_pte = pte_mkdirty(orig_pte);
@@ -184,7 +184,7 @@ static pte_t get_clear_contig(struct mm_struct *mm,
 			     unsigned long pgsize,
 			     unsigned long ncontig)
 {
-	pte_t orig_pte = ptep_get(ptep);
+	pte_t orig_pte = __ptep_get(ptep);
 	unsigned long i;
 
 	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) {
@@ -408,7 +408,7 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
 {
 	int ncontig;
 	size_t pgsize;
-	pte_t orig_pte = ptep_get(ptep);
+	pte_t orig_pte = __ptep_get(ptep);
 
 	if (!pte_cont(orig_pte))
 		return __ptep_get_and_clear(mm, addr, ptep);
@@ -431,11 +431,11 @@ static int __cont_access_flags_changed(pte_t *ptep, pte_t pte, int ncontig)
 {
 	int i;
 
-	if (pte_write(pte) != pte_write(ptep_get(ptep)))
+	if (pte_write(pte) != pte_write(__ptep_get(ptep)))
 		return 1;
 
 	for (i = 0; i < ncontig; i++) {
-		pte_t orig_pte = ptep_get(ptep + i);
+		pte_t orig_pte = __ptep_get(ptep + i);
 
 		if (pte_dirty(pte) != pte_dirty(orig_pte))
 			return 1;
@@ -492,7 +492,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
 	size_t pgsize;
 	pte_t pte;
 
-	if (!pte_cont(READ_ONCE(*ptep))) {
+	if (!pte_cont(__ptep_get(ptep))) {
 		__ptep_set_wrprotect(mm, addr, ptep);
 		return;
 	}
@@ -517,7 +517,7 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
 	size_t pgsize;
 	int ncontig;
 
-	if (!pte_cont(READ_ONCE(*ptep)))
+	if (!pte_cont(__ptep_get(ptep)))
 		return ptep_clear_flush(vma, addr, ptep);
 
 	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
@@ -550,7 +550,7 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr
 		 * when the permission changes from executable to non-executable
 		 * in cases where cpu is affected with errata #2645198.
 		 */
-		if (pte_user_exec(READ_ONCE(*ptep)))
+		if (pte_user_exec(__ptep_get(ptep)))
 			return huge_ptep_clear_flush(vma, addr, ptep);
 	}
 	return huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index f659bd98c63f..9ee16cfce587 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -113,7 +113,7 @@ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
 			memset(__va(page_phys), KASAN_SHADOW_INIT, PAGE_SIZE);
 		next = addr + PAGE_SIZE;
 		__set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
-	} while (ptep++, addr = next, addr != end && pte_none(READ_ONCE(*ptep)));
+	} while (ptep++, addr = next, addr != end && pte_none(__ptep_get(ptep)));
 }
 
 static void __init kasan_pmd_populate(pud_t *pudp, unsigned long addr,
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index bcaa5a5d86f8..8c1ab90bb1e5 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -173,7 +173,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
 
 	ptep = pte_set_fixmap_offset(pmdp, addr);
 	do {
-		pte_t old_pte = READ_ONCE(*ptep);
+		pte_t old_pte = __ptep_get(ptep);
 
 		__set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
 
@@ -182,7 +182,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
 		 * only allow updates to the permission attributes.
 		 */
 		BUG_ON(!pgattr_change_is_safe(pte_val(old_pte),
-					      READ_ONCE(pte_val(*ptep))));
+					      pte_val(__ptep_get(ptep))));
 
 		phys += PAGE_SIZE;
 	} while (ptep++, addr += PAGE_SIZE, addr != end);
@@ -854,7 +854,7 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
 
 	do {
 		ptep = pte_offset_kernel(pmdp, addr);
-		pte = READ_ONCE(*ptep);
+		pte = __ptep_get(ptep);
 		if (pte_none(pte))
 			continue;
 
@@ -987,7 +987,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
 
 	do {
 		ptep = pte_offset_kernel(pmdp, addr);
-		pte = READ_ONCE(*ptep);
+		pte = __ptep_get(ptep);
 
 		/*
 		 * This is just a sanity check here which verifies that
@@ -1006,7 +1006,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
 	 */
 	ptep = pte_offset_kernel(pmdp, 0UL);
 	for (i = 0; i < PTRS_PER_PTE; i++) {
-		if (!pte_none(READ_ONCE(ptep[i])))
+		if (!pte_none(__ptep_get(&ptep[i])))
 			return;
 	}
 
@@ -1503,7 +1503,7 @@ pte_t ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, pte
 		 * when the permission changes from executable to non-executable
 		 * in cases where cpu is affected with errata #2645198.
 		 */
-		if (pte_user_exec(READ_ONCE(*ptep)))
+		if (pte_user_exec(ptep_get(ptep)))
 			return ptep_clear_flush(vma, addr, ptep);
 	}
 	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index a7996d8edf0a..0c4e3ecf989d 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -36,7 +36,7 @@ bool can_set_direct_map(void)
 static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
 {
 	struct page_change_data *cdata = data;
-	pte_t pte = READ_ONCE(*ptep);
+	pte_t pte = __ptep_get(ptep);
 
 	pte = clear_pte_bit(pte, cdata->clear_mask);
 	pte = set_pte_bit(pte, cdata->set_mask);
@@ -245,5 +245,5 @@ bool kernel_page_present(struct page *page)
 		return true;
 
 	ptep = pte_offset_kernel(pmdp, addr);
-	return pte_valid(READ_ONCE(*ptep));
+	return pte_valid(__ptep_get(ptep));
 }
diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
index 230b607cf881..5139a28130c0 100644
--- a/arch/arm64/mm/trans_pgd.c
+++ b/arch/arm64/mm/trans_pgd.c
@@ -33,7 +33,7 @@ static void *trans_alloc(struct trans_pgd_info *info)
 
 static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
 {
-	pte_t pte = READ_ONCE(*src_ptep);
+	pte_t pte = __ptep_get(src_ptep);
 
 	if (pte_valid(pte)) {
 		/*
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:49 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:49 +0000
Subject: [PATCH v5 18/25] arm64/mm: Split __flush_tlb_range() to elide trailing DSB
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-19-ryan.roberts@arm.com>

Split __flush_tlb_range() into __flush_tlb_range_nosync() +
__flush_tlb_range(), in the same way as the existing flush_tlb_page()
arrangement. This allows calling __flush_tlb_range_nosync() to elide the
trailing DSB. Forthcoming "contpte" code will take advantage of this
when clearing the young bit from a contiguous range of ptes.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/tlbflush.h | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index 79e932a1bdf8..50a765917327 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -422,7 +422,7 @@ do {									\
 #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \
 	__flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false, kvm_lpa2_is_enabled());
 
-static inline void __flush_tlb_range(struct vm_area_struct *vma,
+static inline void __flush_tlb_range_nosync(struct vm_area_struct *vma,
 				     unsigned long start, unsigned long end,
 				     unsigned long stride, bool last_level,
 				     int tlb_level)
@@ -456,10 +456,19 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
 		__flush_tlb_range_op(vae1is, start, pages, stride, asid,
 				     tlb_level, true, lpa2_is_enabled());
 
-	dsb(ish);
 	mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
 }
 
+static inline void __flush_tlb_range(struct vm_area_struct *vma,
+				     unsigned long start, unsigned long end,
+				     unsigned long stride, bool last_level,
+				     int tlb_level)
+{
+	__flush_tlb_range_nosync(vma, start, end, stride,
+				 last_level, tlb_level);
+	dsb(ish);
+}
+
 static inline void flush_tlb_range(struct vm_area_struct *vma,
 				   unsigned long start, unsigned long end)
 {
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:50 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:50 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-20-ryan.roberts@arm.com>

With the ptep API sufficiently refactored, we can now introduce a new
"contpte" API layer, which transparently manages the PTE_CONT bit for
user mappings.

In this initial implementation, only suitable batches of PTEs, set via
set_ptes(), are mapped with the PTE_CONT bit. Any subsequent
modification of individual PTEs will cause an "unfold" operation to
repaint the contpte block as individual PTEs before performing the
requested operation. While, a modification of a single PTE could cause
the block of PTEs to which it belongs to become eligible for "folding"
into a contpte entry, "folding" is not performed in this initial
implementation due to the costs of checking the requirements are met.
Due to this, contpte mappings will degrade back to normal pte mappings
over time if/when protections are changed. This will be solved in a
future patch.

Since a contpte block only has a single access and dirty bit, the
semantic here changes slightly; when getting a pte (e.g. ptep_get())
that is part of a contpte mapping, the access and dirty information are
pulled from the block (so all ptes in the block return the same
access/dirty info). When changing the access/dirty info on a pte (e.g.
ptep_set_access_flags()) that is part of a contpte mapping, this change
will affect the whole contpte block. This is works fine in practice
since we guarantee that only a single folio is mapped by a contpte
block, and the core-mm tracks access/dirty information per folio.

In order for the public functions, which used to be pure inline, to
continue to be callable by modules, export all the contpte_* symbols
that are now called by those public inline functions.

The feature is enabled/disabled with the ARM64_CONTPTE Kconfig parameter
at build time. It defaults to enabled as long as its dependency,
TRANSPARENT_HUGEPAGE is also enabled. The core-mm depends upon
TRANSPARENT_HUGEPAGE to be able to allocate large folios, so if its not
enabled, then there is no chance of meeting the physical contiguity
requirement for contpte mappings.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/Kconfig               |   9 +
 arch/arm64/include/asm/pgtable.h | 161 ++++++++++++++++++
 arch/arm64/mm/Makefile           |   1 +
 arch/arm64/mm/contpte.c          | 283 +++++++++++++++++++++++++++++++
 4 files changed, 454 insertions(+)
 create mode 100644 arch/arm64/mm/contpte.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index d86d7f4758b5..1442e8ed95b6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2230,6 +2230,15 @@ config UNWIND_PATCH_PAC_INTO_SCS
 	select UNWIND_TABLES
 	select DYNAMIC_SCS
 
+config ARM64_CONTPTE
+	bool "Contiguous PTE mappings for user memory" if EXPERT
+	depends on TRANSPARENT_HUGEPAGE
+	default y
+	help
+	  When enabled, user mappings are configured using the PTE contiguous
+	  bit, for any mappings that meet the size and alignment requirements.
+	  This reduces TLB pressure and improves performance.
+
 endmenu # "Kernel Features"
 
 menu "Boot options"
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7dc6b68ee516..34892a95403d 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -133,6 +133,10 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
  */
 #define pte_valid_not_user(pte) \
 	((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN))
+/*
+ * Returns true if the pte is valid and has the contiguous bit set.
+ */
+#define pte_valid_cont(pte)	(pte_valid(pte) && pte_cont(pte))
 /*
  * Could the pte be present in the TLB? We must check mm_tlb_flush_pending
  * so that we don't erroneously return false for pages that have been
@@ -1135,6 +1139,161 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 #define vmemmap_update_pte vmemmap_update_pte
 #endif
 
+#ifdef CONFIG_ARM64_CONTPTE
+
+/*
+ * The contpte APIs are used to transparently manage the contiguous bit in ptes
+ * where it is possible and makes sense to do so. The PTE_CONT bit is considered
+ * a private implementation detail of the public ptep API (see below).
+ */
+extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, pte_t pte);
+extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
+extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
+extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, pte_t pte, unsigned int nr);
+extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep);
+extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep);
+extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep,
+				pte_t entry, int dirty);
+
+static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
+					pte_t *ptep, pte_t pte)
+{
+	if (unlikely(pte_valid_cont(pte)))
+		__contpte_try_unfold(mm, addr, ptep, pte);
+}
+
+/*
+ * The below functions constitute the public API that arm64 presents to the
+ * core-mm to manipulate PTE entries within their page tables (or at least this
+ * is the subset of the API that arm64 needs to implement). These public
+ * versions will automatically and transparently apply the contiguous bit where
+ * it makes sense to do so. Therefore any users that are contig-aware (e.g.
+ * hugetlb, kernel mapper) should NOT use these APIs, but instead use the
+ * private versions, which are prefixed with double underscore. All of these
+ * APIs except for ptep_get_lockless() are expected to be called with the PTL
+ * held.
+ */
+
+#define ptep_get ptep_get
+static inline pte_t ptep_get(pte_t *ptep)
+{
+	pte_t pte = __ptep_get(ptep);
+
+	if (likely(!pte_valid_cont(pte)))
+		return pte;
+
+	return contpte_ptep_get(ptep, pte);
+}
+
+#define ptep_get_lockless ptep_get_lockless
+static inline pte_t ptep_get_lockless(pte_t *ptep)
+{
+	pte_t pte = __ptep_get(ptep);
+
+	if (likely(!pte_valid_cont(pte)))
+		return pte;
+
+	return contpte_ptep_get_lockless(ptep);
+}
+
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+	/*
+	 * We don't have the mm or vaddr so cannot unfold contig entries (since
+	 * it requires tlb maintenance). set_pte() is not used in core code, so
+	 * this should never even be called. Regardless do our best to service
+	 * any call and emit a warning if there is any attempt to set a pte on
+	 * top of an existing contig range.
+	 */
+	pte_t orig_pte = __ptep_get(ptep);
+
+	WARN_ON_ONCE(pte_valid_cont(orig_pte));
+	__set_pte(ptep, pte_mknoncont(pte));
+}
+
+#define set_ptes set_ptes
+static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, pte_t pte, unsigned int nr)
+{
+	pte = pte_mknoncont(pte);
+
+	if (likely(nr == 1)) {
+		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+		__set_ptes(mm, addr, ptep, pte, 1);
+	} else {
+		contpte_set_ptes(mm, addr, ptep, pte, nr);
+	}
+}
+
+static inline void pte_clear(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep)
+{
+	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+	__pte_clear(mm, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep)
+{
+	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+	return __ptep_get_and_clear(mm, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep)
+{
+	pte_t orig_pte = __ptep_get(ptep);
+
+	if (likely(!pte_valid_cont(orig_pte)))
+		return __ptep_test_and_clear_young(vma, addr, ptep);
+
+	return contpte_ptep_test_and_clear_young(vma, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep)
+{
+	pte_t orig_pte = __ptep_get(ptep);
+
+	if (likely(!pte_valid_cont(orig_pte)))
+		return __ptep_clear_flush_young(vma, addr, ptep);
+
+	return contpte_ptep_clear_flush_young(vma, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep)
+{
+	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+	__ptep_set_wrprotect(mm, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+static inline int ptep_set_access_flags(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep,
+				pte_t entry, int dirty)
+{
+	pte_t orig_pte = __ptep_get(ptep);
+
+	entry = pte_mknoncont(entry);
+
+	if (likely(!pte_valid_cont(orig_pte)))
+		return __ptep_set_access_flags(vma, addr, ptep, entry, dirty);
+
+	return contpte_ptep_set_access_flags(vma, addr, ptep, entry, dirty);
+}
+
+#else /* CONFIG_ARM64_CONTPTE */
+
 #define ptep_get				__ptep_get
 #define set_pte					__set_pte
 #define set_ptes				__set_ptes
@@ -1150,6 +1309,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags			__ptep_set_access_flags
 
+#endif /* CONFIG_ARM64_CONTPTE */
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_PGTABLE_H */
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index dbd1bc95967d..60454256945b 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -3,6 +3,7 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   cache.o copypage.o flush.o \
 				   ioremap.o mmap.o pgd.o mmu.o \
 				   context.o proc.o pageattr.o fixmap.o
+obj-$(CONFIG_ARM64_CONTPTE)	+= contpte.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_PTDUMP_CORE)	+= ptdump.o
 obj-$(CONFIG_PTDUMP_DEBUGFS)	+= ptdump_debugfs.o
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
new file mode 100644
index 000000000000..bfb50e6b44c7
--- /dev/null
+++ b/arch/arm64/mm/contpte.c
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+
+#include <linux/mm.h>
+#include <linux/export.h>
+#include <asm/tlbflush.h>
+
+static inline bool mm_is_user(struct mm_struct *mm)
+{
+	/*
+	 * Don't attempt to apply the contig bit to kernel mappings, because
+	 * dynamically adding/removing the contig bit can cause page faults.
+	 * These racing faults are ok for user space, since they get serialized
+	 * on the PTL. But kernel mappings can't tolerate faults.
+	 */
+	return mm != &init_mm;
+}
+
+static inline pte_t *contpte_align_down(pte_t *ptep)
+{
+	return (pte_t *)(ALIGN_DOWN((unsigned long)ptep >> 3, CONT_PTES) << 3);
+}
+
+static void contpte_convert(struct mm_struct *mm, unsigned long addr,
+			    pte_t *ptep, pte_t pte)
+{
+	struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0);
+	unsigned long start_addr;
+	pte_t *start_ptep;
+	int i;
+
+	start_ptep = ptep = contpte_align_down(ptep);
+	start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+	pte = pfn_pte(ALIGN_DOWN(pte_pfn(pte), CONT_PTES), pte_pgprot(pte));
+
+	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) {
+		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
+
+		if (pte_dirty(ptent))
+			pte = pte_mkdirty(pte);
+
+		if (pte_young(ptent))
+			pte = pte_mkyoung(pte);
+	}
+
+	__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
+
+	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
+}
+
+void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
+			pte_t *ptep, pte_t pte)
+{
+	/*
+	 * We have already checked that the ptes are contiguous in
+	 * contpte_try_unfold(), so just check that the mm is user space.
+	 */
+
+	if (!mm_is_user(mm))
+		return;
+
+	pte = pte_mknoncont(pte);
+	contpte_convert(mm, addr, ptep, pte);
+}
+EXPORT_SYMBOL(__contpte_try_unfold);
+
+pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
+{
+	/*
+	 * Gather access/dirty bits, which may be populated in any of the ptes
+	 * of the contig range. We are guarranteed to be holding the PTL, so any
+	 * contiguous range cannot be unfolded or otherwise modified under our
+	 * feet.
+	 */
+
+	pte_t pte;
+	int i;
+
+	ptep = contpte_align_down(ptep);
+
+	for (i = 0; i < CONT_PTES; i++, ptep++) {
+		pte = __ptep_get(ptep);
+
+		if (pte_dirty(pte))
+			orig_pte = pte_mkdirty(orig_pte);
+
+		if (pte_young(pte))
+			orig_pte = pte_mkyoung(orig_pte);
+	}
+
+	return orig_pte;
+}
+EXPORT_SYMBOL(contpte_ptep_get);
+
+pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
+{
+	/*
+	 * Gather access/dirty bits, which may be populated in any of the ptes
+	 * of the contig range. We may not be holding the PTL, so any contiguous
+	 * range may be unfolded/modified/refolded under our feet. Therefore we
+	 * ensure we read a _consistent_ contpte range by checking that all ptes
+	 * in the range are valid and have CONT_PTE set, that all pfns are
+	 * contiguous and that all pgprots are the same (ignoring access/dirty).
+	 * If we find a pte that is not consistent, then we must be racing with
+	 * an update so start again. If the target pte does not have CONT_PTE
+	 * set then that is considered consistent on its own because it is not
+	 * part of a contpte range.
+	 */
+
+	pgprot_t orig_prot;
+	unsigned long pfn;
+	pte_t orig_pte;
+	pgprot_t prot;
+	pte_t *ptep;
+	pte_t pte;
+	int i;
+
+retry:
+	orig_pte = __ptep_get(orig_ptep);
+
+	if (!pte_valid_cont(orig_pte))
+		return orig_pte;
+
+	orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
+	ptep = contpte_align_down(orig_ptep);
+	pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
+
+	for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
+		pte = __ptep_get(ptep);
+		prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
+
+		if (!pte_valid_cont(pte) ||
+		   pte_pfn(pte) != pfn ||
+		   pgprot_val(prot) != pgprot_val(orig_prot))
+			goto retry;
+
+		if (pte_dirty(pte))
+			orig_pte = pte_mkdirty(orig_pte);
+
+		if (pte_young(pte))
+			orig_pte = pte_mkyoung(orig_pte);
+	}
+
+	return orig_pte;
+}
+EXPORT_SYMBOL(contpte_ptep_get_lockless);
+
+void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
+					pte_t *ptep, pte_t pte, unsigned int nr)
+{
+	unsigned long next;
+	unsigned long end;
+	unsigned long pfn;
+	pgprot_t prot;
+
+	/*
+	 * The set_ptes() spec guarantees that when nr > 1, the initial state of
+	 * all ptes is not-present. Therefore we never need to unfold or
+	 * otherwise invalidate a range before we set the new ptes.
+	 * contpte_set_ptes() should never be called for nr < 2.
+	 */
+	VM_WARN_ON(nr == 1);
+
+	if (!mm_is_user(mm))
+		return __set_ptes(mm, addr, ptep, pte, nr);
+
+	end = addr + (nr << PAGE_SHIFT);
+	pfn = pte_pfn(pte);
+	prot = pte_pgprot(pte);
+
+	do {
+		next = pte_cont_addr_end(addr, end);
+		nr = (next - addr) >> PAGE_SHIFT;
+		pte = pfn_pte(pfn, prot);
+
+		if (((addr | next | (pfn << PAGE_SHIFT)) & ~CONT_PTE_MASK) == 0)
+			pte = pte_mkcont(pte);
+		else
+			pte = pte_mknoncont(pte);
+
+		__set_ptes(mm, addr, ptep, pte, nr);
+
+		addr = next;
+		ptep += nr;
+		pfn += nr;
+
+	} while (addr != end);
+}
+EXPORT_SYMBOL(contpte_set_ptes);
+
+int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
+					unsigned long addr, pte_t *ptep)
+{
+	/*
+	 * ptep_clear_flush_young() technically requires us to clear the access
+	 * flag for a _single_ pte. However, the core-mm code actually tracks
+	 * access/dirty per folio, not per page. And since we only create a
+	 * contig range when the range is covered by a single folio, we can get
+	 * away with clearing young for the whole contig range here, so we avoid
+	 * having to unfold.
+	 */
+
+	int young = 0;
+	int i;
+
+	ptep = contpte_align_down(ptep);
+	addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+
+	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
+		young |= __ptep_test_and_clear_young(vma, addr, ptep);
+
+	return young;
+}
+EXPORT_SYMBOL(contpte_ptep_test_and_clear_young);
+
+int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
+					unsigned long addr, pte_t *ptep)
+{
+	int young;
+
+	young = contpte_ptep_test_and_clear_young(vma, addr, ptep);
+
+	if (young) {
+		/*
+		 * See comment in __ptep_clear_flush_young(); same rationale for
+		 * eliding the trailing DSB applies here.
+		 */
+		addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+		__flush_tlb_range_nosync(vma, addr, addr + CONT_PTE_SIZE,
+					 PAGE_SIZE, true, 3);
+	}
+
+	return young;
+}
+EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
+
+int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
+					unsigned long addr, pte_t *ptep,
+					pte_t entry, int dirty)
+{
+	unsigned long start_addr;
+	pte_t orig_pte;
+	int i;
+
+	/*
+	 * Gather the access/dirty bits for the contiguous range. If nothing has
+	 * changed, its a noop.
+	 */
+	orig_pte = pte_mknoncont(ptep_get(ptep));
+	if (pte_val(orig_pte) == pte_val(entry))
+		return 0;
+
+	/*
+	 * We can fix up access/dirty bits without having to unfold the contig
+	 * range. But if the write bit is changing, we must unfold.
+	 */
+	if (pte_write(orig_pte) == pte_write(entry)) {
+		/*
+		 * For HW access management, we technically only need to update
+		 * the flag on a single pte in the range. But for SW access
+		 * management, we need to update all the ptes to prevent extra
+		 * faults. Avoid per-page tlb flush in __ptep_set_access_flags()
+		 * and instead flush the whole range at the end.
+		 */
+		ptep = contpte_align_down(ptep);
+		start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+
+		for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
+			__ptep_set_access_flags(vma, addr, ptep, entry, 0);
+
+		if (dirty)
+			__flush_tlb_range(vma, start_addr, addr,
+							PAGE_SIZE, true, 3);
+	} else {
+		__contpte_try_unfold(vma->vm_mm, addr, ptep, orig_pte);
+		__ptep_set_access_flags(vma, addr, ptep, entry, dirty);
+	}
+
+	return 1;
+}
+EXPORT_SYMBOL(contpte_ptep_set_access_flags);
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:45 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:45 +0000
Subject: [PATCH v5 14/25] arm64/mm: ptep_clear_flush_young(): New layer to manage contig bit
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-15-ryan.roberts@arm.com>

Create a new layer for the in-table PTE manipulation APIs. For now, The
existing API is prefixed with double underscore to become the
arch-private API and the public API is just a simple wrapper that calls
the private API.

The public API implementation will subsequently be used to transparently
manipulate the contiguous bit where appropriate. But since there are
already some contig-aware users (e.g. hugetlb, kernel mapper), we must
first ensure those users use the private API directly so that the future
contig-bit manipulations in the public API do not interfere with those
existing uses.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 77a8b100e1cd..2870bc12f288 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -138,7 +138,7 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
  * so that we don't erroneously return false for pages that have been
  * remapped as PROT_NONE but are yet to be flushed from the TLB.
  * Note that we can't make any assumptions based on the state of the access
- * flag, since ptep_clear_flush_young() elides a DSB when invalidating the
+ * flag, since __ptep_clear_flush_young() elides a DSB when invalidating the
  * TLB.
  */
 #define pte_accessible(mm, pte)	\
@@ -916,8 +916,7 @@ static inline int __ptep_test_and_clear_young(struct vm_area_struct *vma,
 	return pte_young(pte);
 }
 
-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
+static inline int __ptep_clear_flush_young(struct vm_area_struct *vma,
 					 unsigned long address, pte_t *ptep)
 {
 	int young = __ptep_test_and_clear_young(vma, address, ptep);
@@ -1138,6 +1137,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
 #define ptep_get_and_clear			__ptep_get_and_clear
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define ptep_test_and_clear_young		__ptep_test_and_clear_young
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define ptep_clear_flush_young			__ptep_clear_flush_young
 
 #endif /* !__ASSEMBLY__ */
 
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:52 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:52 +0000
Subject: [PATCH v5 21/25] arm64/mm: Implement new [get_and_]clear_full_ptes() batch APIs
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-22-ryan.roberts@arm.com>

Optimize the contpte implementation to fix some of the
exit/munmap/dontneed performance regression introduced by the initial
contpte commit. Subsequent patches will solve it entirely.

During exit(), munmap() or madvise(MADV_DONTNEED), mappings must be
cleared. Previously this was done 1 PTE at a time. But the core-mm
supports batched clear via the new [get_and_]clear_full_ptes() APIs. So
let's implement those APIs and for fully covered contpte mappings, we no
longer need to unfold the contpte. This significantly reduces unfolding
operations, reducing the number of tlbis that must be issued.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 67 ++++++++++++++++++++++++++++++++
 arch/arm64/mm/contpte.c          | 17 ++++++++
 2 files changed, 84 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index c07f0d563733..ad04adb7b87f 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -965,6 +965,37 @@ static inline pte_t __ptep_get_and_clear(struct mm_struct *mm,
 	return pte;
 }
 
+static inline void __clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr, int full)
+{
+	for (;;) {
+		__ptep_get_and_clear(mm, addr, ptep);
+		if (--nr == 0)
+			break;
+		ptep++;
+		addr += PAGE_SIZE;
+	}
+}
+
+static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep,
+				unsigned int nr, int full)
+{
+	pte_t pte, tmp_pte;
+
+	pte = __ptep_get_and_clear(mm, addr, ptep);
+	while (--nr) {
+		ptep++;
+		addr += PAGE_SIZE;
+		tmp_pte = __ptep_get_and_clear(mm, addr, ptep);
+		if (pte_dirty(tmp_pte))
+			pte = pte_mkdirty(pte);
+		if (pte_young(tmp_pte))
+			pte = pte_mkyoung(pte);
+	}
+	return pte;
+}
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
 static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
@@ -1167,6 +1198,11 @@ extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
 extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
 extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
 				pte_t *ptep, pte_t pte, unsigned int nr);
+extern void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr, int full);
+extern pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep,
+				unsigned int nr, int full);
 extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep);
 extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
@@ -1254,6 +1290,35 @@ static inline void pte_clear(struct mm_struct *mm,
 	__pte_clear(mm, addr, ptep);
 }
 
+#define clear_full_ptes clear_full_ptes
+static inline void clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr, int full)
+{
+	if (likely(nr == 1)) {
+		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+		__clear_full_ptes(mm, addr, ptep, nr, full);
+	} else {
+		contpte_clear_full_ptes(mm, addr, ptep, nr, full);
+	}
+}
+
+#define get_and_clear_full_ptes get_and_clear_full_ptes
+static inline pte_t get_and_clear_full_ptes(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep,
+				unsigned int nr, int full)
+{
+	pte_t pte;
+
+	if (likely(nr == 1)) {
+		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+		pte = __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
+	} else {
+		pte = contpte_get_and_clear_full_ptes(mm, addr, ptep, nr, full);
+	}
+
+	return pte;
+}
+
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 				unsigned long addr, pte_t *ptep)
@@ -1338,6 +1403,8 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
 #define set_pte					__set_pte
 #define set_ptes				__set_ptes
 #define pte_clear				__pte_clear
+#define clear_full_ptes				__clear_full_ptes
+#define get_and_clear_full_ptes			__get_and_clear_full_ptes
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 #define ptep_get_and_clear			__ptep_get_and_clear
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index c85e64baf03b..80346108450b 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -207,6 +207,23 @@ void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
 }
 EXPORT_SYMBOL(contpte_set_ptes);
 
+void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr, int full)
+{
+	contpte_try_unfold_partial(mm, addr, ptep, nr);
+	__clear_full_ptes(mm, addr, ptep, nr, full);
+}
+EXPORT_SYMBOL(contpte_clear_full_ptes);
+
+pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep,
+				unsigned int nr, int full)
+{
+	contpte_try_unfold_partial(mm, addr, ptep, nr);
+	return __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
+}
+EXPORT_SYMBOL(contpte_get_and_clear_full_ptes);
+
 int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
 					unsigned long addr, pte_t *ptep)
 {
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:51 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:51 +0000
Subject: [PATCH v5 20/25] arm64/mm: Implement new wrprotect_ptes() batch API
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-21-ryan.roberts@arm.com>

Optimize the contpte implementation to fix some of the fork performance
regression introduced by the initial contpte commit. Subsequent patches
will solve it entirely.

During fork(), any private memory in the parent must be write-protected.
Previously this was done 1 PTE at a time. But the core-mm supports
batched wrprotect via the new wrprotect_ptes() API. So let's implement
that API and for fully covered contpte mappings, we no longer need to
unfold the contpte. This has 2 benefits:

  - reduced unfolding, reduces the number of tlbis that must be issued.
  - The memory remains contpte-mapped ("folded") in the parent, so it
    continues to benefit from the more efficient use of the TLB after
    the fork.

The optimization to wrprotect a whole contpte block without unfolding is
possible thanks to the tightening of the Arm ARM in respect to the
definition and behaviour when 'Misprogramming the Contiguous bit'. See
section D21194 at https://developer.arm.com/documentation/102105/latest/

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 61 ++++++++++++++++++++++++++------
 arch/arm64/mm/contpte.c          | 35 ++++++++++++++++++
 2 files changed, 86 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 34892a95403d..c07f0d563733 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -978,16 +978,12 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
-/*
- * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
- * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
- */
-static inline void __ptep_set_wrprotect(struct mm_struct *mm,
-					unsigned long address, pte_t *ptep)
+static inline void ___ptep_set_wrprotect(struct mm_struct *mm,
+					unsigned long address, pte_t *ptep,
+					pte_t pte)
 {
-	pte_t old_pte, pte;
+	pte_t old_pte;
 
-	pte = __ptep_get(ptep);
 	do {
 		old_pte = pte;
 		pte = pte_wrprotect(pte);
@@ -996,6 +992,25 @@ static inline void __ptep_set_wrprotect(struct mm_struct *mm,
 	} while (pte_val(pte) != pte_val(old_pte));
 }
 
+/*
+ * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
+ * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
+ */
+static inline void __ptep_set_wrprotect(struct mm_struct *mm,
+					unsigned long address, pte_t *ptep)
+{
+	___ptep_set_wrprotect(mm, address, ptep, __ptep_get(ptep));
+}
+
+static inline void __wrprotect_ptes(struct mm_struct *mm, unsigned long address,
+				pte_t *ptep, unsigned int nr)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr; i++, address += PAGE_SIZE, ptep++)
+		__ptep_set_wrprotect(mm, address, ptep);
+}
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_PMDP_SET_WRPROTECT
 static inline void pmdp_set_wrprotect(struct mm_struct *mm,
@@ -1156,6 +1171,8 @@ extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep);
 extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep);
+extern void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr);
 extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep,
 				pte_t entry, int dirty);
@@ -1269,12 +1286,35 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
 	return contpte_ptep_clear_flush_young(vma, addr, ptep);
 }
 
+#define wrprotect_ptes wrprotect_ptes
+static inline void wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr)
+{
+	if (likely(nr == 1)) {
+		/*
+		 * Optimization: wrprotect_ptes() can only be called for present
+		 * ptes so we only need to check contig bit as condition for
+		 * unfold, and we can remove the contig bit from the pte we read
+		 * to avoid re-reading. This speeds up fork() which is sensitive
+		 * for order-0 folios. Equivalent to contpte_try_unfold().
+		 */
+		pte_t orig_pte = __ptep_get(ptep);
+
+		if (unlikely(pte_cont(orig_pte))) {
+			__contpte_try_unfold(mm, addr, ptep, orig_pte);
+			orig_pte = pte_mknoncont(orig_pte);
+		}
+		___ptep_set_wrprotect(mm, addr, ptep, orig_pte);
+	} else {
+		contpte_wrprotect_ptes(mm, addr, ptep, nr);
+	}
+}
+
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 static inline void ptep_set_wrprotect(struct mm_struct *mm,
 				unsigned long addr, pte_t *ptep)
 {
-	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
-	__ptep_set_wrprotect(mm, addr, ptep);
+	wrprotect_ptes(mm, addr, ptep, 1);
 }
 
 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
@@ -1306,6 +1346,7 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
 #define ptep_clear_flush_young			__ptep_clear_flush_young
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 #define ptep_set_wrprotect			__ptep_set_wrprotect
+#define wrprotect_ptes				__wrprotect_ptes
 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags			__ptep_set_access_flags
 
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index bfb50e6b44c7..c85e64baf03b 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -23,6 +23,23 @@ static inline pte_t *contpte_align_down(pte_t *ptep)
 	return (pte_t *)(ALIGN_DOWN((unsigned long)ptep >> 3, CONT_PTES) << 3);
 }
 
+static void contpte_try_unfold_partial(struct mm_struct *mm, unsigned long addr,
+					pte_t *ptep, unsigned int nr)
+{
+	/*
+	 * Unfold any partially covered contpte block at the beginning and end
+	 * of the range.
+	 */
+
+	if (ptep != contpte_align_down(ptep) || nr < CONT_PTES)
+		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+
+	if (ptep + nr != contpte_align_down(ptep + nr))
+		contpte_try_unfold(mm, addr + PAGE_SIZE * (nr - 1),
+				ptep + nr - 1,
+				__ptep_get(ptep + nr - 1));
+}
+
 static void contpte_convert(struct mm_struct *mm, unsigned long addr,
 			    pte_t *ptep, pte_t pte)
 {
@@ -236,6 +253,24 @@ int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
 }
 EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
 
+void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
+					pte_t *ptep, unsigned int nr)
+{
+	/*
+	 * If wrprotecting an entire contig range, we can avoid unfolding. Just
+	 * set wrprotect and wait for the later mmu_gather flush to invalidate
+	 * the tlb. Until the flush, the page may or may not be wrprotected.
+	 * After the flush, it is guarranteed wrprotected. If its a partial
+	 * range though, we must unfold, because we can't have a case where
+	 * CONT_PTE is set but wrprotect applies to a subset of the PTEs; this
+	 * would cause it to continue to be unpredictable after the flush.
+	 */
+
+	contpte_try_unfold_partial(mm, addr, ptep, nr);
+	__wrprotect_ptes(mm, addr, ptep, nr);
+}
+EXPORT_SYMBOL(contpte_wrprotect_ptes);
+
 int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
 					unsigned long addr, pte_t *ptep,
 					pte_t entry, int dirty)
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:54 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:54 +0000
Subject: [PATCH v5 23/25] arm64/mm: Implement pte_batch_hint()
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-24-ryan.roberts@arm.com>

When core code iterates over a range of ptes and calls ptep_get() for
each of them, if the range happens to cover contpte mappings, the number
of pte reads becomes amplified by a factor of the number of PTEs in a
contpte block. This is because for each call to ptep_get(), the
implementation must read all of the ptes in the contpte block to which
it belongs to gather the access and dirty bits.

This causes a hotspot for fork(), as well as operations that unmap
memory such as munmap(), exit and madvise(MADV_DONTNEED). Fortunately we
can fix this by implementing pte_batch_hint() which allows their
iterators to skip getting the contpte tail ptes when gathering the batch
of ptes to operate on. This results in the number of PTE reads returning
to 1 per pte.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index ad04adb7b87f..353ea67b5d75 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1220,6 +1220,15 @@ static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
 		__contpte_try_unfold(mm, addr, ptep, pte);
 }
 
+#define pte_batch_hint pte_batch_hint
+static inline unsigned int pte_batch_hint(pte_t *ptep, pte_t pte)
+{
+	if (!pte_valid_cont(pte))
+		return 1;
+
+	return CONT_PTES - (((unsigned long)ptep >> 3) & (CONT_PTES - 1));
+}
+
 /*
  * The below functions constitute the public API that arm64 presents to the
  * core-mm to manipulate PTE entries within their page tables (or at least this
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:53 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:53 +0000
Subject: [PATCH v5 22/25] mm: Add pte_batch_hint() to reduce scanning in folio_pte_batch()
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-23-ryan.roberts@arm.com>

Some architectures (e.g. arm64) can tell from looking at a pte, if some
follow-on ptes also map contiguous physical memory with the same pgprot.
(for arm64, these are contpte mappings).

Take advantage of this knowledge to optimize folio_pte_batch() so that
it can skip these ptes when scanning to create a batch. By default, if
an arch does not opt-in, folio_pte_batch() returns a compile-time 1, so
the changes are optimized out and the behaviour is as before.

arm64 will opt-in to providing this hint in the next patch, which will
greatly reduce the cost of ptep_get() when scanning a range of contptes.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 include/linux/pgtable.h | 18 ++++++++++++++++++
 mm/memory.c             | 20 +++++++++++++-------
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 50f32cccbd92..cba31f177d27 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -212,6 +212,24 @@ static inline int pmd_dirty(pmd_t pmd)
 #define arch_flush_lazy_mmu_mode()	do {} while (0)
 #endif
 
+#ifndef pte_batch_hint
+/**
+ * pte_batch_hint - Number of pages that can be added to batch without scanning.
+ * @ptep: Page table pointer for the entry.
+ * @pte: Page table entry.
+ *
+ * Some architectures know that a set of contiguous ptes all map the same
+ * contiguous memory with the same permissions. In this case, it can provide a
+ * hint to aid pte batching without the core code needing to scan every pte.
+ *
+ * May be overridden by the architecture, else pte_batch_hint is always 1.
+ */
+static inline unsigned int pte_batch_hint(pte_t *ptep, pte_t pte)
+{
+	return 1;
+}
+#endif
+
 #ifndef pte_advance_pfn
 static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 {
diff --git a/mm/memory.c b/mm/memory.c
index 65fbe4f886c1..902665b27702 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -988,16 +988,21 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
 {
 	unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio);
 	const pte_t *end_ptep = start_ptep + max_nr;
-	pte_t expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, 1), flags);
-	pte_t *ptep = start_ptep + 1;
+	pte_t expected_pte = __pte_batch_clear_ignored(pte, flags);
+	pte_t *ptep = start_ptep;
 	bool writable;
+	int nr;
 
 	if (any_writable)
 		*any_writable = false;
 
 	VM_WARN_ON_FOLIO(!pte_present(pte), folio);
 
-	while (ptep != end_ptep) {
+	nr = pte_batch_hint(ptep, pte);
+	expected_pte = pte_advance_pfn(expected_pte, nr);
+	ptep += nr;
+
+	while (ptep < end_ptep) {
 		pte = ptep_get(ptep);
 		if (any_writable)
 			writable = !!pte_write(pte);
@@ -1011,17 +1016,18 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
 		 * corner cases the next PFN might fall into a different
 		 * folio.
 		 */
-		if (pte_pfn(pte) == folio_end_pfn)
+		if (pte_pfn(pte) >= folio_end_pfn)
 			break;
 
 		if (any_writable)
 			*any_writable |= writable;
 
-		expected_pte = pte_advance_pfn(expected_pte, 1);
-		ptep++;
+		nr = pte_batch_hint(ptep, pte);
+		expected_pte = pte_advance_pfn(expected_pte, nr);
+		ptep += nr;
 	}
 
-	return ptep - start_ptep;
+	return min(ptep - start_ptep, max_nr);
 }
 
 /*
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:55 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:55 +0000
Subject: [PATCH v5 24/25] arm64/mm: __always_inline to improve fork() perf
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-25-ryan.roberts@arm.com>

As set_ptes() and wrprotect_ptes() become a bit more complex, the
compiler may choose not to inline them. But this is critical for fork()
performance. So mark the functions, along with contpte_try_unfold()
which is called by them, as __always_inline. This is worth ~1% on the
fork() microbenchmark with order-0 folios (the common case).

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 353ea67b5d75..cdc310880a3b 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1213,8 +1213,8 @@ extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep,
 				pte_t entry, int dirty);
 
-static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
-					pte_t *ptep, pte_t pte)
+static __always_inline void contpte_try_unfold(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep, pte_t pte)
 {
 	if (unlikely(pte_valid_cont(pte)))
 		__contpte_try_unfold(mm, addr, ptep, pte);
@@ -1279,7 +1279,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
 }
 
 #define set_ptes set_ptes
-static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
+static __always_inline void set_ptes(struct mm_struct *mm, unsigned long addr,
 				pte_t *ptep, pte_t pte, unsigned int nr)
 {
 	pte = pte_mknoncont(pte);
@@ -1361,8 +1361,8 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
 }
 
 #define wrprotect_ptes wrprotect_ptes
-static inline void wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
-				pte_t *ptep, unsigned int nr)
+static __always_inline void wrprotect_ptes(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep, unsigned int nr)
 {
 	if (likely(nr == 1)) {
 		/*
-- 
2.25.1



From ryan.roberts at arm.com  Fri Feb  2 00:07:56 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri,  2 Feb 2024 08:07:56 +0000
Subject: [PATCH v5 25/25] arm64/mm: Automatically fold contpte mappings
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <20240202080756.1453939-26-ryan.roberts@arm.com>

There are situations where a change to a single PTE could cause the
contpte block in which it resides to become foldable (i.e. could be
repainted with the contiguous bit). Such situations arise, for example,
when user space temporarily changes protections, via mprotect, for
individual pages, such can be the case for certain garbage collectors.

We would like to detect when such a PTE change occurs. However this can
be expensive due to the amount of checking required. Therefore only
perform the checks when an indiviual PTE is modified via mprotect
(ptep_modify_prot_commit() -> set_pte_at() -> set_ptes(nr=1)) and only
when we are setting the final PTE in a contpte-aligned block.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 26 +++++++++++++
 arch/arm64/mm/contpte.c          | 64 ++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index cdc310880a3b..d3357fe4eb89 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1192,6 +1192,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
  * where it is possible and makes sense to do so. The PTE_CONT bit is considered
  * a private implementation detail of the public ptep API (see below).
  */
+extern void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, pte_t pte);
 extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
 				pte_t *ptep, pte_t pte);
 extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
@@ -1213,6 +1215,29 @@ extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep,
 				pte_t entry, int dirty);
 
+static __always_inline void contpte_try_fold(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep, pte_t pte)
+{
+	/*
+	 * Only bother trying if both the virtual and physical addresses are
+	 * aligned and correspond to the last entry in a contig range. The core
+	 * code mostly modifies ranges from low to high, so this is the likely
+	 * the last modification in the contig range, so a good time to fold.
+	 * We can't fold special mappings, because there is no associated folio.
+	 */
+
+	const unsigned long contmask = CONT_PTES - 1;
+	bool valign = ((addr >> PAGE_SHIFT) & contmask) == contmask;
+
+	if (unlikely(valign)) {
+		bool palign = (pte_pfn(pte) & contmask) == contmask;
+
+		if (unlikely(palign &&
+		    pte_valid(pte) && !pte_cont(pte) && !pte_special(pte)))
+			__contpte_try_fold(mm, addr, ptep, pte);
+	}
+}
+
 static __always_inline void contpte_try_unfold(struct mm_struct *mm,
 				unsigned long addr, pte_t *ptep, pte_t pte)
 {
@@ -1287,6 +1312,7 @@ static __always_inline void set_ptes(struct mm_struct *mm, unsigned long addr,
 	if (likely(nr == 1)) {
 		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
 		__set_ptes(mm, addr, ptep, pte, 1);
+		contpte_try_fold(mm, addr, ptep, pte);
 	} else {
 		contpte_set_ptes(mm, addr, ptep, pte, nr);
 	}
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index 80346108450b..2c7dafd0552a 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -67,6 +67,70 @@ static void contpte_convert(struct mm_struct *mm, unsigned long addr,
 	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
 }
 
+void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
+			pte_t *ptep, pte_t pte)
+{
+	/*
+	 * We have already checked that the virtual and pysical addresses are
+	 * correctly aligned for a contpte mapping in contpte_try_fold() so the
+	 * remaining checks are to ensure that the contpte range is fully
+	 * covered by a single folio, and ensure that all the ptes are valid
+	 * with contiguous PFNs and matching prots. We ignore the state of the
+	 * access and dirty bits for the purpose of deciding if its a contiguous
+	 * range; the folding process will generate a single contpte entry which
+	 * has a single access and dirty bit. Those 2 bits are the logical OR of
+	 * their respective bits in the constituent pte entries. In order to
+	 * ensure the contpte range is covered by a single folio, we must
+	 * recover the folio from the pfn, but special mappings don't have a
+	 * folio backing them. Fortunately contpte_try_fold() already checked
+	 * that the pte is not special - we never try to fold special mappings.
+	 * Note we can't use vm_normal_page() for this since we don't have the
+	 * vma.
+	 */
+
+	unsigned long folio_saddr, folio_eaddr;
+	unsigned long cont_saddr, cont_eaddr;
+	pte_t expected_pte, subpte;
+	struct folio *folio;
+	struct page *page;
+	unsigned long pfn;
+	pte_t *orig_ptep;
+	pgprot_t prot;
+
+	int i;
+
+	if (!mm_is_user(mm))
+		return;
+
+	page = pte_page(pte);
+	folio = page_folio(page);
+	folio_saddr = addr - (page - &folio->page) * PAGE_SIZE;
+	folio_eaddr = folio_saddr + folio_nr_pages(folio) * PAGE_SIZE;
+	cont_saddr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+	cont_eaddr = cont_saddr + CONT_PTE_SIZE;
+
+	if (folio_saddr > cont_saddr || folio_eaddr < cont_eaddr)
+		return;
+
+	pfn = pte_pfn(pte) - ((addr - cont_saddr) >> PAGE_SHIFT);
+	prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
+	expected_pte = pfn_pte(pfn, prot);
+	orig_ptep = ptep;
+	ptep = contpte_align_down(ptep);
+
+	for (i = 0; i < CONT_PTES; i++) {
+		subpte = pte_mkold(pte_mkclean(__ptep_get(ptep)));
+		if (!pte_same(subpte, expected_pte))
+			return;
+		expected_pte = pte_advance_pfn(expected_pte, 1);
+		ptep++;
+	}
+
+	pte = pte_mkcont(pte);
+	contpte_convert(mm, addr, orig_ptep, pte);
+}
+EXPORT_SYMBOL(__contpte_try_fold);
+
 void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
 			pte_t *ptep, pte_t pte)
 {
-- 
2.25.1



From p.zabel at pengutronix.de  Fri Feb  2 00:16:50 2024
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Fri, 02 Feb 2024 09:16:50 +0100
Subject: [PATCH] media: imx: csc/scaler: fix v4l2_ctrl_handler memory
 leak
In-Reply-To: <20240131120033.858877-1-l.stach@pengutronix.de>
References: <20240131120033.858877-1-l.stach@pengutronix.de>
Message-ID: <3833ae6cd2a0b16d4a554c8a8eb3b2c3897c765f.camel@pengutronix.de>

On Mi, 2024-01-31 at 13:00 +0100, Lucas Stach wrote:
> Free the memory allocated in v4l2_ctrl_handler_init on release.
> 
> Fixes: a8ef0488cc59 ("media: imx: add csc/scaler mem2mem device")
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
>  drivers/staging/media/imx/imx-media-csc-scaler.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c
> index 1fd39a2fca98..95cca281e8a3 100644
> --- a/drivers/staging/media/imx/imx-media-csc-scaler.c
> +++ b/drivers/staging/media/imx/imx-media-csc-scaler.c
> @@ -803,6 +803,7 @@ static int ipu_csc_scaler_release(struct file *file)
>  
>  	dev_dbg(priv->dev, "Releasing instance %p\n", ctx);
>  
> +	v4l2_ctrl_handler_free(&ctx->ctrl_hdlr);
>  	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
>  	v4l2_fh_del(&ctx->fh);
>  	v4l2_fh_exit(&ctx->fh);

Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>

regards
Philipp


From krzysztof.kozlowski at linaro.org  Fri Feb  2 00:21:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 09:21:38 +0100
Subject: [PATCH 1/2] dt-bindings: phy: mediatek,xfi-tphy: add new bindings
In-Reply-To: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
Message-ID: <adf20671-2f1d-43ea-8584-df0c0b095865@linaro.org>

On 01/02/2024 22:52, Daniel Golle wrote:
> Add bindings for the MediaTek XFI T-PHY Ethernet SerDes PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
> via USXGMII PCS:
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
> 
> via LynxI SGMII PCS:
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---
>  .../bindings/phy/mediatek,xfi-tphy.yaml       | 80 +++++++++++++++++++
>  1 file changed, 80 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> new file mode 100644
> index 0000000000000..e897118dcf7e6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> @@ -0,0 +1,80 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/mediatek,xfi-tphy.yaml#

Please use compatible as filename. Your binding says only one is
possible (const, not enum), so there is no reasoning for different filename.

> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek XFI T-PHY
> +
> +maintainers:
> +  - Daniel Golle <daniel at makrotopia.org>
> +
> +description:
> +  The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes
> +  used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in
> +  MediaTek's 10G-capabale SoCs.
> +
> +properties:
> +  $nodename:
> +    pattern: "^phy@[0-9a-f]+$"

No need for nodename in individual bindings file.

> +
> +  compatible:
> +    const: mediatek,mt7988-xfi-tphy
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: XFI PHY clock
> +      - description: XFI register clock
> +
> +  clock-names:
> +    items:
> +      - const: xfipll
> +      - const: topxtal
> +
> +  resets:
> +    items:
> +      - description: PEXTP reset
> +
> +  mediatek,usxgmii-performance-errata:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description:
> +      One instance of the T-PHY on MT7988 suffers from a performance
> +      problem in 10GBase-R mode which needs a work-around in the driver.

Can you explain what is this issue and errata about (except performance)?

> +      The work-around is enabled using this flag.
> +
> +  "#phy-cells":
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - resets
> +  - "#phy-cells"
> +
> +additionalProperties: false


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb  2 00:23:27 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 09:23:27 +0100
Subject: [PATCH v2 1/4] dt-bindings: mmc: fsl-imx-esdhc: add iommus
 property
In-Reply-To: <20240201-8qm_smmu-v2-1-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240201-8qm_smmu-v2-1-3d12a80201a3@nxp.com>
Message-ID: <c519661e-c37d-45e2-99dc-22fb86a8e97b@linaro.org>

On 01/02/2024 21:22, Frank Li wrote:
> iMX95 and iMX8QM have smmu. Add property "iommus".
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb  2 00:23:37 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 09:23:37 +0100
Subject: [PATCH v2 2/4] dt-bindings: net: fec: add iommus property
In-Reply-To: <20240201-8qm_smmu-v2-2-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240201-8qm_smmu-v2-2-3d12a80201a3@nxp.com>
Message-ID: <49dbd0a2-a4b9-4c05-bb10-44f267672374@linaro.org>

On 01/02/2024 21:22, Frank Li wrote:
> iMX8QM have iommu. Add proerty 'iommus'.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From oliver.upton at linux.dev  Fri Feb  2 00:34:08 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 2 Feb 2024 08:34:08 +0000
Subject: [PATCH v4 4/5] KVM: selftests: aarch64: Introduce
 pmu_event_filter_test
In-Reply-To: <20240202025659.5065-5-shahuang@redhat.com>
References: <20240202025659.5065-1-shahuang@redhat.com>
 <20240202025659.5065-5-shahuang@redhat.com>
Message-ID: <ZbypAAFEHweTDUJK@linux.dev>

On Thu, Feb 01, 2024 at 09:56:53PM -0500, Shaoqin Huang wrote:
> Introduce pmu_event_filter_test for arm64 platforms. The test configures
> PMUv3 for a vCPU, and sets different pmu event filters for the vCPU, and
> check if the guest can see those events which user allow and can't use
> those events which use deny.
> 
> This test refactor the create_vpmu_vm() and make it a wrapper for
> __create_vpmu_vm(), which allows some extra init code before
> KVM_ARM_VCPU_PMU_V3_INIT.
> 
> And this test use the KVM_ARM_VCPU_PMU_V3_FILTER attribute to set the
> pmu event filter in KVM. And choose to filter two common event
> branches_retired and instructions_retired, and let the guest to check if
> it see the right pmceid register.
> 
> Signed-off-by: Shaoqin Huang <shahuang at redhat.com>
> ---
>  tools/testing/selftests/kvm/Makefile          |   1 +
>  .../kvm/aarch64/pmu_event_filter_test.c       | 219 ++++++++++++++++++
>  .../selftests/kvm/include/aarch64/vpmu.h      |   4 +
>  .../testing/selftests/kvm/lib/aarch64/vpmu.c  |  14 +-
>  4 files changed, 236 insertions(+), 2 deletions(-)
>  create mode 100644 tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
> 
> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> index 709a70b31ca2..733ec86a3385 100644
> --- a/tools/testing/selftests/kvm/Makefile
> +++ b/tools/testing/selftests/kvm/Makefile
> @@ -148,6 +148,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
>  TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
>  TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
>  TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
> +TEST_GEN_PROGS_aarch64 += aarch64/pmu_event_filter_test
>  TEST_GEN_PROGS_aarch64 += aarch64/psci_test
>  TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs
>  TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter
> diff --git a/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
> new file mode 100644
> index 000000000000..d280382f362f
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
> @@ -0,0 +1,219 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * pmu_event_filter_test - Test user limit pmu event for guest.
> + *
> + * Copyright (c) 2023 Red Hat, Inc.
> + *
> + * This test checks if the guest only see the limited pmu event that userspace
> + * sets, if the guest can use those events which user allow, and if the guest
> + * can't use those events which user deny.
> + * This test runs only when KVM_CAP_ARM_PMU_V3, KVM_ARM_VCPU_PMU_V3_FILTER
> + * is supported on the host.
> + */
> +#include <kvm_util.h>
> +#include <processor.h>
> +#include <vgic.h>
> +#include <vpmu.h>
> +#include <test_util.h>
> +#include <perf/arm_pmuv3.h>
> +
> +struct pmce{

Missing whitespace before curly brace.

Also -- pmce is an odd name. Maybe common_event_ids or pmu_id_regs.

> +	uint64_t pmceid0;
> +	uint64_t pmceid1;
> +} supported_pmce, guest_pmce;

maybe "max_*" and "expected_*". It took me a bit to understand that
guest_pmce feeds in your expected PMCEID values.

> +static struct vpmu_vm *vpmu_vm;
> +
> +#define FILTER_NR 10
> +
> +struct test_desc {
> +	const char *name;
> +	struct kvm_pmu_event_filter filter[FILTER_NR];
> +};
> +
> +#define __DEFINE_FILTER(base, num, act)		\
> +	((struct kvm_pmu_event_filter) {	\
> +		.base_event	= base,		\
> +		.nevents	= num,		\
> +		.action		= act,		\
> +	})
> +
> +#define DEFINE_FILTER(base, act) __DEFINE_FILTER(base, 1, act)
> +
> +#define EMPTY_FILTER	{ 0 }
> +
> +#define SW_INCR		0x0
> +#define INST_RETIRED	0x8
> +#define BR_RETIRED	0x21

These event numbers are already defined in tools/include/perf/arm_pmuv3.h,
use those instead.

> +static void guest_code(void)
> +{
> +	uint64_t pmceid0 = read_sysreg(pmceid0_el0);
> +	uint64_t pmceid1 = read_sysreg(pmceid1_el0);
> +
> +	GUEST_ASSERT_EQ(guest_pmce.pmceid0, pmceid0);
> +	GUEST_ASSERT_EQ(guest_pmce.pmceid1, pmceid1);
> +
> +	GUEST_DONE();
> +}
> +
> +static void guest_get_pmceid(void)
> +{
> +	supported_pmce.pmceid0 = read_sysreg(pmceid0_el0);
> +	supported_pmce.pmceid1 = read_sysreg(pmceid1_el0);
> +
> +	GUEST_DONE();
> +}
> +
> +static void pmu_event_filter_init(struct vpmu_vm *vm, void *arg)

Why are you obfuscating the pointer to the filter array?

> +{
> +	struct kvm_device_attr attr = {
> +		.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
> +		.attr	= KVM_ARM_VCPU_PMU_V3_FILTER,
> +	};
> +	struct kvm_pmu_event_filter *filter = (struct kvm_pmu_event_filter *)arg;
> +
> +	while (filter && filter->nevents != 0) {
> +		attr.addr = (uint64_t)filter;
> +		vcpu_ioctl(vm->vcpu, KVM_SET_DEVICE_ATTR, &attr);

Again, kvm_device_attr_set() the right helper to use.

> +static void set_pmce(struct pmce *pmce, int action, int event)
> +{
> +	int base = 0;
> +	uint64_t *pmceid = NULL;
> +
> +	if (event >= 0x4000) {
> +		event -= 0x4000;
> +		base = 32;
> +	}
> +
> +	if (event >= 0 && event <= 0x1F) {
> +		pmceid = &pmce->pmceid0;
> +	} else if (event >= 0x20 && event <= 0x3F) {
> +		event -= 0x20;
> +		pmceid = &pmce->pmceid1;
> +	} else {
> +		return;
> +	}
> +
> +	event += base;
> +	if (action == KVM_PMU_EVENT_ALLOW)
> +		*pmceid |= BIT(event);
> +	else
> +		*pmceid &= ~BIT(event);
> +}
> +
> +static void prepare_guest_pmce(struct kvm_pmu_event_filter *filter)
> +{
> +	struct pmce pmce_mask = { ~0, ~0 };
> +	bool first_filter = true;
> +
> +	while (filter && filter->nevents != 0) {
> +		if (first_filter) {
> +			if (filter->action == KVM_PMU_EVENT_ALLOW)
> +				memset(&pmce_mask, 0, sizeof(pmce_mask));
> +			first_filter = false;
> +		}
> +
> +		set_pmce(&pmce_mask, filter->action, filter->base_event);
> +		filter++;
> +	}
> +
> +	guest_pmce.pmceid0 = supported_pmce.pmceid0 & pmce_mask.pmceid0;
> +	guest_pmce.pmceid1 = supported_pmce.pmceid1 & pmce_mask.pmceid1;
> +}

Why do you need to do this? Can't you tell the guests what events to
expect and have it make sense of the PMCEID values it sees?

You could, for example, pass in a pointer to the test descriptor as an
argument.

> +static void run_test(struct test_desc *t)
> +{
> +	pr_debug("Test: %s\n", t->name);

You may as well just pr_info() this thing.

> +	create_vpmu_vm_with_filter(guest_code, t->filter);
> +	prepare_guest_pmce(t->filter);
> +	sync_global_to_guest(vpmu_vm->vm, guest_pmce);
> +
> +	run_vcpu(vpmu_vm->vcpu);
> +
> +	destroy_vpmu_vm(vpmu_vm);
> +}
> +
> +static struct test_desc tests[] = {
> +	{"without_filter", { EMPTY_FILTER }},
> +	{"member_allow_filter",
> +	 {DEFINE_FILTER(SW_INCR, 0), DEFINE_FILTER(INST_RETIRED, 0),
> +	  DEFINE_FILTER(BR_RETIRED, 0), EMPTY_FILTER}},
> +	{"member_deny_filter",
> +	 {DEFINE_FILTER(SW_INCR, 1), DEFINE_FILTER(INST_RETIRED, 1),
> +	  DEFINE_FILTER(BR_RETIRED, 1), EMPTY_FILTER}},
> +	{"not_member_deny_filter",
> +	 {DEFINE_FILTER(SW_INCR, 1), EMPTY_FILTER}},
> +	{"not_member_allow_filter",
> +	 {DEFINE_FILTER(SW_INCR, 0), EMPTY_FILTER}},

Why is the filter array special enough to get its own sentinel macro
but...

> +	{ 0 }

... the test descriptor array is okay to use a 'raw' initialization. My
vote is to drop the macro, zero-initializing a struct in an array is an
extremely common pattern in the kernel.

Also, these descriptors are dense and hard to read. Working with an
example:

	{
		.name = "member_allow_filter",
		.filter = {
			DEFINE_FILTER(SW_INCR, 0),
			DEFINE_FILTER(INST_RETIRED, 0),
			DEFINE_FILTER(BR_RETIRED, 0),
			{ 0 }
		},
	}

See how much more readable that is?

> +};
> +
> +static void for_each_test(void)
> +{
> +	struct test_desc *t;
> +
> +	for (t = &tests[0]; t->name; t++)
> +		run_test(t);
> +}

for_each_test() sounds like an iterator, but this is not. Call it
run_tests()

> +static bool kvm_supports_pmu_event_filter(void)
> +{
> +	int r;
> +
> +	vpmu_vm = create_vpmu_vm(guest_code);
> +
> +	r = __kvm_has_device_attr(vpmu_vm->vcpu->fd, KVM_ARM_VCPU_PMU_V3_CTRL,
> +				  KVM_ARM_VCPU_PMU_V3_FILTER);
> +
> +	destroy_vpmu_vm(vpmu_vm);
> +	return !r;
> +}

TBH, I don't really care much about the test probing for the event
filter UAPI. It has been upstream for a while, and if folks are trying
to run selftests at HEAD on an old kernel then that's their business.

The other prerequisites make more sense since they actually check if HW
features are present.

> +static bool host_pmu_supports_events(void)
> +{
> +	vpmu_vm = create_vpmu_vm(guest_get_pmceid);
> +
> +	memset(&supported_pmce, 0, sizeof(supported_pmce));
> +	sync_global_to_guest(vpmu_vm->vm, supported_pmce);
> +	run_vcpu(vpmu_vm->vcpu);
> +	sync_global_from_guest(vpmu_vm->vm, supported_pmce);
> +	destroy_vpmu_vm(vpmu_vm);
> +
> +	return supported_pmce.pmceid0 & (BR_RETIRED | INST_RETIRED);
> +}

This helper says its probing the host PMU, but you're actually firing up a
VM to do it.

The events supported by a particular PMU instance are readily available
in sysfs. Furthermore, you can tell KVM to select the exact host PMU
instance you probe.

> diff --git a/tools/testing/selftests/kvm/lib/aarch64/vpmu.c b/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
> index b3de8fdc555e..76ea03d607f1 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
> @@ -7,8 +7,9 @@
>  #include <vpmu.h>
>  #include <perf/arm_pmuv3.h>
>  
> -/* Create a VM that has one vCPU with PMUv3 configured. */
> -struct vpmu_vm *create_vpmu_vm(void *guest_code)
> +struct vpmu_vm *__create_vpmu_vm(void *guest_code,
> +				 void (*init_pmu)(struct vpmu_vm *vm, void *arg),
> +				 void *arg)
>  {
>  	struct kvm_vcpu_init init;
>  	uint8_t pmuver;
> @@ -50,12 +51,21 @@ struct vpmu_vm *create_vpmu_vm(void *guest_code)
>  		    "Unexpected PMUVER (0x%x) on the vCPU with PMUv3", pmuver);
>  
>  	/* Initialize vPMU */
> +	if (init_pmu)
> +		init_pmu(vpmu_vm, arg);
> +
>  	vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &irq_attr);
>  	vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &init_attr);
>  
>  	return vpmu_vm;
>  }
>  
> +/* Create a VM that has one vCPU with PMUv3 configured. */
> +struct vpmu_vm *create_vpmu_vm(void *guest_code)
> +{
> +	return __create_vpmu_vm(guest_code, NULL, NULL);
> +}
> +

Ok. This completely proves my point in the other patch. You already need
to refactor this helper to cram in what you're trying to do. Think of
ways to move the code that is actually common into libraries and leave
the rest to the tests themselves.

Some slight code duplication isn't the end of the world if it avoids
churning libraries every time someone wants to add a widget.

-- 
Thanks,
Oliver


From dan.carpenter at linaro.org  Fri Feb  2 00:47:30 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Fri, 2 Feb 2024 11:47:30 +0300
Subject: [PATCH v1 02/18] thermal: Add new structures and
 thermal_zone_device_register()
In-Reply-To: <CAJZ5v0jzaGpK8LnsFDtjuPoURrwrUgM1Z2QfZhK_FUzDeK3wcw@mail.gmail.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
 <20240130111250.185718-3-angelogioacchino.delregno@collabora.com>
 <CAJZ5v0jzaGpK8LnsFDtjuPoURrwrUgM1Z2QfZhK_FUzDeK3wcw@mail.gmail.com>
Message-ID: <e4359d2c-e686-4a97-9d21-d10908e9df61@moroto.mountain>

On Thu, Feb 01, 2024 at 08:24:15PM +0100, Rafael J. Wysocki wrote:
> On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
> > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > index 65d8f92a9a0d..7a540b746703 100644
> > --- a/include/linux/thermal.h
> > +++ b/include/linux/thermal.h
> > @@ -149,7 +149,8 @@ struct thermal_cooling_device {
> >                         passive trip point.
> >   * @need_update:       if equals 1, thermal_zone_device_update needs to be invoked.
> >   * @ops:       operations this &thermal_zone_device supports
> > - * @tzp:       thermal zone parameters
> > + * @tzp:               Thermal zone parameters
> > + * @tgp:               Thermal zone governor parameters
> >   * @governor:  pointer to the governor for this thermal zone
> >   * @governor_data:     private pointer for governor data
> >   * @thermal_instances: list of &struct thermal_instance of this thermal zone
> > @@ -184,7 +185,8 @@ struct thermal_zone_device {
> >         int prev_high_trip;
> >         atomic_t need_update;
> >         struct thermal_zone_device_ops *ops;
> > -       struct thermal_zone_params *tzp;
> > +       struct thermal_zone_platform_params *tzp;
> > +       struct thermal_governor_params *tgp;
> 
> I agree with doing a split here, but I'm not sure about moving items
> from the arg list to struct thermal_zone_platform_params (as mentioned
> above).
> 
> Also the naming is quite inconsistent.  IMO it would be better to call
> the first pointer "tzpp", rename struct thermal_governor_params to
> struct thermal_zone_governor_params and call the second pointer
> "tzgp".
> 

The names "tzgp" and "tzpp" look almost identical at first glance.
Could we increase the hamming distance somehow?

regards,
dan carpenter



From sunilvl at ventanamicro.com  Fri Feb  2 00:48:31 2024
From: sunilvl at ventanamicro.com (Sunil V L)
Date: Fri, 2 Feb 2024 14:18:31 +0530
Subject: [RFC PATCH v2 05/21] pnp.h: Return -EPROBE_DEFER for disabled
 IRQ resource in pnp_irq()
In-Reply-To: <CAJZ5v0hHYa4c2U-tegdBtoTak=MirXwyBXbN9yrWPx_x-+yMzg@mail.gmail.com>
References: <20231025202344.581132-1-sunilvl@ventanamicro.com>
 <20231025202344.581132-6-sunilvl@ventanamicro.com>
 <CAJZ5v0hHYa4c2U-tegdBtoTak=MirXwyBXbN9yrWPx_x-+yMzg@mail.gmail.com>
Message-ID: <ZbysXzWX6FH5e6AH@sunil-laptop>

On Thu, Feb 01, 2024 at 07:00:51PM +0100, Rafael J. Wysocki wrote:
> On Wed, Oct 25, 2023 at 10:24?PM Sunil V L <sunilvl at ventanamicro.com> wrote:
> >
> > To support deferred PNP driver probe, pnp_irq() must return -EPROBE_DEFER
> > so that the device driver can do deferred probe if the interrupt controller
> > is not probed early.
> >
> > Signed-off-by: Sunil V L <sunilvl at ventanamicro.com>
> > ---
> >  include/linux/pnp.h | 10 ++++++++--
> >  1 file changed, 8 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/linux/pnp.h b/include/linux/pnp.h
> > index c2a7cfbca713..21cf833789fb 100644
> > --- a/include/linux/pnp.h
> > +++ b/include/linux/pnp.h
> > @@ -147,12 +147,18 @@ static inline resource_size_t pnp_mem_len(struct pnp_dev *dev,
> >  }
> >
> >
> > -static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar)
> > +static inline int pnp_irq(struct pnp_dev *dev, unsigned int bar)
> >  {
> >         struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar);
> >
> > -       if (pnp_resource_valid(res))
> > +       if (pnp_resource_valid(res)) {
> > +#if IS_ENABLED(CONFIG_ARCH_ACPI_DEFERRED_GSI)
> > +               if (!pnp_resource_enabled(res))
> > +                       return -EPROBE_DEFER;
> > +#endif
> 
> What would be wrong with
> 
> if (IS_ENABLED(CONFIG_ARCH_ACPI_DEFERRED_GSI) && !pnp_resource_enabled(res))
>         return -EPROBE_DEFER;
> 
> ?
Hi Rafael,

Actually, this is v2 version of the patch and there is recent v3. Please
take a look at [1] for the latest version.

However, your comment is still valid for v3. I will update as you
mentioned.

[1] - https://lore.kernel.org/linux-arm-kernel/20231219174526.2235150-7-sunilvl at ventanamicro.com/

Thanks,
Sunil
> 
> > +
> >                 return res->start;
> > +       }
> >         return -1;
> >  }
> >
> > --
> > 2.39.2
> >


From linux at armlinux.org.uk  Fri Feb  2 00:50:34 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 2 Feb 2024 08:50:34 +0000
Subject: [PATCH net-next v4 06/11] net: stmmac: resetup XPCS according to
 the new interface mode
In-Reply-To: <2ad1f55c-f361-4439-9174-6af1bb429d55@linux.intel.com>
References: <20240129130253.1400707-1-yong.liang.choong@linux.intel.com>
 <20240129130253.1400707-7-yong.liang.choong@linux.intel.com>
 <ZbjNn+C/VHegH2t7@shell.armlinux.org.uk>
 <9e23671e-788c-4191-bdb4-94915ff7da5a@linux.intel.com>
 <ZbtYaXkNf2ZF1prE@shell.armlinux.org.uk>
 <2ad1f55c-f361-4439-9174-6af1bb429d55@linux.intel.com>
Message-ID: <Zbys2orOUikYxeOm@shell.armlinux.org.uk>

On Fri, Feb 02, 2024 at 11:00:58AM +0800, Choong Yong Liang wrote:
> 
> 
> On 1/2/2024 4:38 pm, Russell King (Oracle) wrote:
> > Note the "This must not modify any state." statement. By reinitialising
> > the PCS in this method, you are violating that statement.
> > 
> > This requirement is because this method will be called by
> > phylink_validate_mac_and_pcs() at various times, potentially for each
> > and every interface that stmmac supports, which will lead to you
> > reinitialising the PCS, killing the link, each time we ask the MAC for
> > a PCS, whether we are going to make use of it in that mode or not.
> > 
> > You can not do this. Sorry. Hard NAK for this approach.
> > 
> Thank you for taking the time to review, got your concerns, and I'll address
> the following concerns before submitting a new patch series:
> 
> 1. Remove allow_switch_interface and have the PHY driver fill in
> phydev->possible_interfaces.

Yes please.

> 2. Rework on the PCS to have similar implementation with the following patch
> "net: macb: use .mac_select_pcs() interface"
> (https://lore.kernel.org/netdev/E1n568J-002SZX-Gr at rmk-PC.armlinux.org.uk/T/).

mac_select_pcs() is about returning to phylink the PCS that the MAC
needs to use for the specified interface mode, or NULL if no PCS is
required, nothing more, nothing less.

Plase do not copy that mac_select_pcs() implementation - changing the
"ops" underneath phylink is no longer permitted.

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


From oliver.upton at linux.dev  Fri Feb  2 00:52:32 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 2 Feb 2024 08:52:32 +0000
Subject: [PATCH v2 06/25] KVM: arm64: nv: Add sanitising to VNCR-backed
 HCRX_EL2
In-Reply-To: <20240130204533.693853-7-maz@kernel.org>
References: <20240130204533.693853-1-maz@kernel.org>
 <20240130204533.693853-7-maz@kernel.org>
Message-ID: <ZbytUKPFYiP2cdd8@linux.dev>

On Tue, Jan 30, 2024 at 08:45:13PM +0000, Marc Zyngier wrote:
> Just like its little friends, HCRX_EL2 gets the feature set treatment
> when backed by VNCR.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/nested.c | 42 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 42 insertions(+)
> 
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index cdeef3259193..72db632b115a 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -263,6 +263,48 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
>  		res1 |= HCR_E2H;
>  	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
>  
> +	/* HCRX_EL2 */
> +	res0 = HCRX_EL2_RES0;
> +	res1 = HCRX_EL2_RES1;

I'm a bit worried that we're depending on the meaning of these generated
RES0/RES1 bitmasks not changing behind our backs.

Not like people read anything, but do you think it'd make sense to add a
warning comment to the sysreg file that adding new encodings can have a
functional change on KVM?

> +	if (!kvm_has_feat(kvm, ID_AA64ISAR3_EL1, PACM, TRIVIAL_IMP))
> +		res0 |= HCRX_EL2_PACMEn;
> +	if (!kvm_has_feat(kvm, ID_AA64PFR2_EL1, FPMR, IMP))
> +		res0 |= HCRX_EL2_EnFPM;
> +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
> +		res0 |= HCRX_EL2_GCSEn;
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, SYSREG_128, IMP))
> +		res0 |= HCRX_EL2_EnIDCP128;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, ADERR, DEV_ASYNC))
> +		res0 |= (HCRX_EL2_EnSDERR | HCRX_EL2_EnSNERR);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, DF2, IMP))
> +		res0 |= HCRX_EL2_TMEA;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, D128, IMP))
> +		res0 |= HCRX_EL2_D128En;
> +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
> +		res0 |= HCRX_EL2_PTTWI;

Ok, not fair. The latest public version of the ARM ARM doesn't have any
of this. Where are you getting it from?

> +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, SCTLRX, IMP))
> +		res0 |= HCRX_EL2_SCTLR2En;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, TCRX, IMP))
> +		res0 |= HCRX_EL2_TCR2En;
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, MOPS, IMP))
> +		res0 |= (HCRX_EL2_MSCEn | HCRX_EL2_MCE2);
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, CMOW, IMP))
> +		res0 |= HCRX_EL2_CMOW;
> +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, NMI, IMP))
> +		res0 |= (HCRX_EL2_VFNMI | HCRX_EL2_VINMI | HCRX_EL2_TALLINT);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP) ||
> +	    !(read_sysreg_s(SYS_SMIDR_EL1) & SMIDR_EL1_SMPS))
> +		res0 |= HCRX_EL2_SMPME;
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, XS, IMP))
> +		res0 |= (HCRX_EL2_FGTnXS | HCRX_EL2_FnXS);
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_V))
> +		res0 |= HCRX_EL2_EnASR;
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64))
> +		res0 |= HCRX_EL2_EnALS;
> +	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA))
> +		res0 |= HCRX_EL2_EnAS0;
> +	set_sysreg_masks(kvm, HCRX_EL2, res0, res1);
> +
>  	/* HFG[RW]TR_EL2 */
>  	res0 = res1 = 0;
>  	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
> -- 
> 2.39.2
> 

-- 
Thanks,
Oliver


From Shawn.Sung at mediatek.com  Fri Feb  2 01:03:24 2024
From: Shawn.Sung at mediatek.com (=?utf-8?B?U2hhd24gU3VuZyAo5a6L5a2d6KyZKQ==?=)
Date: Fri, 2 Feb 2024 09:03:24 +0000
Subject: [PATCH v4 00/17] Support IGT in display driver
In-Reply-To: <488c6f38-02c6-4e62-b90b-d2ac112541ae@collabora.com>
References: <20231212121957.19231-1-shawn.sung@mediatek.com>
	 <488c6f38-02c6-4e62-b90b-d2ac112541ae@collabora.com>
Message-ID: <16b2d96543e900741aa03864d671ed9cce3d0e4e.camel@mediatek.com>

Hi Angelo,

Thanks for the reminder.
The next version is expected to be released next week.

Regards,
Shawn

The next version will 
On Thu, 2024-02-01 at 11:16 +0100, AngeloGioacchino Del Regno wrote:
> Il 12/12/23 13:19, Hsiao Chien Sung ha scritto:
> > This series is based on mediatek-drm-next.
> > 
> > This series adds support for running IGT (Intel GPU Tool) tests
> > with MediaTek display driver. The following changes will be
> > applied:
> > 
> > 1. Add a new API for creating GCE thread loop to retrieve CRCs
> >     from the hardware component
> > 2. Support hardware CRC calculation in both VDOSYS0 and VDOSYS1
> > 3. Support alpha blending in both VDOSYS0 and VDOSYS1
> > 
> 
> Hello,
> is there still interest in upstreaming this?
> 
> We're interested in enabling more comprehensive IGT tests on MediaTek
> SoCs
> and this series is definitely useful.
> 
> Regards,
> Angelo
> 
> > Changes in v4:
> > - Seperate the patch into smaller ones
> > - Change the title of some patches
> > - Revert the changes that are not related to the series
> > 
> > Changes in v3:
> > - Modify the dt-binding document of Mediatek OVL
> > - Set DRM mode configs accroding to the hardware capabilities
> > - Replace cmdq_pkt_jump_absolute() with cmdq_pkt_jump()
> > 
> > Changes in v2:
> > - Simplify CMDQ by adding commands that are currently used only
> > - Integrate CRC related codes into new APIs for Mixer and OVL to
> > reuse
> > - Add CPU version CRC retrieval when CMDQ is disabled
> > 
> > Hsiao Chien Sung (17):
> >    soc: mediatek: Add register definitions for GCE
> >    soc: mediatek: Disable 9-bit alpha in ETHDR
> >    dt-bindings: display: mediatek: ovl: Modify rules for
> > MT8195/MT8188
> >    drm/mediatek: Add OVL compatible name for MT8195
> >    drm/mediatek: Set DRM mode configs accordingly
> >    drm/mediatek: Support alpha blending in OVL
> >    drm/mediatek: Support alpha blending in Mixer
> >    drm/mediatek: Support alpha blending in display driver
> >    drm/mediatek: Support CSC in OVL
> >    drm/mediatek: Support more color formats in OVL
> >    drm/mediatek: Turn off the layers with zero width or height
> >    drm/mediatek: Support CRC in display driver
> >    drm/mediatek: Support CRC in OVL
> >    drm/mediatek: Support CRC in OVL adaptor
> >    drm/mediatek: Add missing plane settings when async update
> >    drm/mediatek: Fix errors when reporting rotation capability
> >    drm/mediatek: Add comments for the structures
> > 
> >   .../display/mediatek/mediatek,ovl.yaml        |  12 +-
> >   drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   7 +
> >   drivers/gpu/drm/mediatek/mtk_disp_ovl.c       | 326
> > +++++++++++++++---
> >   .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   |  32 +-
> >   drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 261
> > +++++++++++++-
> >   drivers/gpu/drm/mediatek/mtk_drm_crtc.h       |  39 +++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |   7 +
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  35 ++
> >   drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  30 +-
> >   drivers/gpu/drm/mediatek/mtk_drm_drv.h        |  16 +
> >   drivers/gpu/drm/mediatek/mtk_drm_plane.c      |  15 +-
> >   drivers/gpu/drm/mediatek/mtk_ethdr.c          | 106 +++++-
> >   drivers/gpu/drm/mediatek/mtk_ethdr.h          |   5 +
> >   drivers/soc/mediatek/mtk-mmsys.c              |   1 +
> >   include/linux/soc/mediatek/mtk-cmdq.h         |  10 +
> >   15 files changed, 834 insertions(+), 68 deletions(-)
> > 
> > --
> > 2.18.0
> > 
> 
> 

From beata.michalska at arm.com  Fri Feb  2 01:05:05 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Fri, 2 Feb 2024 10:05:05 +0100
Subject: [PATCH v2 2/2] cpufreq: Wire-up arch-flavored freq info into
 cpufreq_verify_current_freq
In-Reply-To: <CAJZ5v0jh3mG3hyFS6war=0bk3PvsVtTwZ1_YwwWov36Bmz7q0w@mail.gmail.com>
References: <20231127160838.1403404-1-beata.michalska@arm.com>
 <20231127160838.1403404-3-beata.michalska@arm.com>
 <CAJZ5v0jh3mG3hyFS6war=0bk3PvsVtTwZ1_YwwWov36Bmz7q0w@mail.gmail.com>
Message-ID: <ZbywQfY7J5DbF1Ev@e129154.nice.arm.com>

Apologies for extremely late reply, juggling too many things at time ....

On Wed, Dec 06, 2023 at 09:41:05PM +0100, Rafael J. Wysocki wrote:
> On Mon, Nov 27, 2023 at 5:09?PM Beata Michalska <beata.michalska at arm.com> wrote:
> >
> > From: Sumit Gupta <sumitg at nvidia.com>
> >
> > When available, use arch_freq_get_on_cpu to obtain current frequency
> > (usually an average reported over given period of time)
> > to better align the cpufreq's view on the current state of affairs.
> 
> And why is this a good idea?
Apart from being problematic with an issue pointed at [1] (which will result
in dropping the change in cpufreq) this was to keep the cpufreq core aware of
potential frequency changes and take appropriate action (informing the governor)
case it got out of sync.
> 
> Any problem statement?
The problem has been raised here [2]
> 
> > This also automatically pulls in the update for cpuinfo_cur_freq sysfs
> > attribute, aligning it with the scaling_cur_freq one, and thus providing
> > consistent view on relevant platforms.
> 
> I have no idea what the above is supposed to mean, sorry.
Bad wording I guess. With this change both 'cpuinfo_cur_freq' and
'scaling_cur_freq' will use the arch_freq_get_on_cpu if available, and will use
the same source of information (one depending on a platform).

> 
> > Signed-off-by: Sumit Gupta <sumitg at nvidia.com>
> > [BM: Subject & commit msg]
> > Signed-off-by: Beata Michalska <beata.michalska at arm.com>
> > ---
> >  drivers/cpufreq/cpufreq.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> > index 8c4f9c2f9c44..109559438f45 100644
> > --- a/drivers/cpufreq/cpufreq.c
> > +++ b/drivers/cpufreq/cpufreq.c
> > @@ -1756,7 +1756,8 @@ static unsigned int cpufreq_verify_current_freq(struct cpufreq_policy *policy, b
> >  {
> >         unsigned int new_freq;
> >
> > -       new_freq = cpufreq_driver->get(policy->cpu);
> > +       new_freq = arch_freq_get_on_cpu(policy->cpu);
> > +       new_freq = new_freq ?: cpufreq_driver->get(policy->cpu);
> 
> Please don't use ?: in general and it is not even useful here AFAICS.
> 
> What would be wrong with
> 
> new_freq = arch_freq_get_on_cpu(policy->cpu);
> if (!new_freq)
>         new_freq = cpufreq_driver->get(policy->cpu);
> 
> ?
Nothing wrong with that.

---
[1] https://lore.kernel.org/all/ZWXy0h%2FfFfQh+Rhy at arm.com/
[2] https://lore.kernel.org/lkml/6a5710f6-bfbb-5dfd-11cd-0cd02220cee7 at nvidia.com/
---
BR
Beata
> 
> >         if (!new_freq)
> >                 return 0;
> >
> > --


From xu.yang_2 at nxp.com  Fri Feb  2 01:10:29 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Fri, 2 Feb 2024 09:10:29 +0000
Subject: [EXT] Re: [PATCH v5 4/8] dt-bindings: usb: ci-hdrc-usb2: add
 restrictions for reg, interrupts, clock and clock-names properties
In-Reply-To: <a0134089-a283-488b-8d7f-3f59dd938b60@linaro.org>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-4-xu.yang_2@nxp.com>
 <a0134089-a283-488b-8d7f-3f59dd938b60@linaro.org>
Message-ID: <DU2PR04MB88221602EB986D2C2A5BBF8D8C422@DU2PR04MB8822.eurprd04.prod.outlook.com>

Hi Krzysztof,

> 
> On 31/01/2024 12:43, Xu Yang wrote:
> > Change reg, interrupts, clock and clock-names as common properties and add
> > restrictions on them for different compatibles.
> >
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> >
> > ---
> > Changes in v4:
> >  - new patch since v3's discussion
> >  - split the reg, interrupts, clock and clock-names properties into
> >    common part and device-specific
> > Changes in v5:
> >  - keep common property unchanged
> >  - make if-then more readable
> >  - remove non imx part
> > ---
> >  .../devicetree/bindings/usb/ci-hdrc-usb2.yaml | 118 ++++++++++++++++++
> >  1 file changed, 118 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-
> hdrc-usb2.yaml
> > index 3b56e0edb1c6..6ad3582051b8 100644
> > --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> > +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> > @@ -412,6 +412,124 @@ allOf:
> >          samsung,picophy-pre-emp-curr-control: false
> >          samsung,picophy-dc-vol-level-adjust: false
> >
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          const: fsl,imx27-usb
> > +    then:
> > +      properties:
> > +        clocks:
> > +          minItems: 3
> > +          maxItems: 3
> > +        clock-names:
> > +          minItems: 3
> > +          maxItems: 3
> > +          items:
> > +            anyOf:
> > +              - const: ipg
> > +              - const: ahb
> > +              - const: per
> 
> This would be just: enum: [ipg, ahb, per], but in both cases I question
> why the order should be flexible? Nothing in commit msg explains it.

The driver will get the clock by clock-name, then the order should not
matter. However, these three clock-names should be present at the same
time. I should use enum then.

> 
> Plus I will repeat myself from your v4. I don't think this is helping,
> because the file will soon grow to umnanageable chunk. I prefer to fix
> it at beginning, before we reach snps-schema level of complexities.
> 
> Please define common schema, reference in this file and move IMX to own
> file.

I'm not that familiar with dt-bindings architecture. If I define a common
schema, then should I create imx, qcom, nvidia and other dt-binding files
too? 

> 
> In any case, please provide short comment in the code why you have such
> duplicated if:then:

Okay.

> 
> Best regards,
> Krzysztof


From arinc.unal at arinc9.com  Fri Feb  2 01:11:37 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Fri, 2 Feb 2024 12:11:37 +0300
Subject: [PATCH net RFC] net: dsa: mt7530: fix link-local frames that
 ingress vlan filtering ports
In-Reply-To: <20240201225943.abphuuavp7bkbrt6@skbuf>
References: <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
 <20240201225943.abphuuavp7bkbrt6@skbuf>
Message-ID: <1f0e67ba-edd7-4998-bc20-1de86bd53a68@arinc9.com>

On 2.02.2024 01:59, Vladimir Oltean wrote:
> On Thu, Feb 01, 2024 at 10:13:39PM +0300, Ar?n? ?NAL via B4 Relay wrote:
>> base-commit: 4e192be1a225b7b1c4e315a44754312347628859
>> change-id: 20240201-b4-for-net-mt7530-fix-link-local-that-ingress-vlan-filtering-ports-6a2099e7ffb3
>>
>> Best regards,
>> -- 
>> Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> You sent this patch 3 times. What happened, b4 didn't work so well?

Odd, I've received only a single email of this patch.

Looking at lore.kernel.org, it looks like the b4 web endpoint properly
submitted the patch to the b4-sent mailing list but for some reason changed
the Message-Id before submitting it to the netdev mailing list.

This is the email with what the Message-Id should be, which only exists on
the b4-sent mailing list:

https://lore.kernel.org/all/20240201-b4-for-net-mt7530-fix-link-local-that-ingress-vlan-filtering-ports-v1-1-881c1c96b27f at arinc9.com/

This is the email with changed Message-Id that was submitted to the netdev
mailing list:

https://lore.kernel.org/all/=%3Futf-8%3Fq%3F=3C20240201-b4-for-net-mt7530-fix-link-local-that-ingr%3F=%20=%3Futf-8%3Fq%3Fess-vlan-filtering-ports-v1-1-881c1c96b27f=40arinc9=2Ecom=3E%3F=/

There're no brackets enclosing the Message-Id. That must be why Gmail
modified it with the SMTPIN_ADDED_BROKEN disclaimer added for you. I can't
come up with a theory as to why you've received it thrice though.

Konstantin, could you take a look at what happened here?

Ar?n?


From beata.michalska at arm.com  Fri Feb  2 01:14:47 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Fri, 2 Feb 2024 10:14:47 +0100
Subject: [PATCH v2 2/2] cpufreq: Wire-up arch-flavored freq info into
 cpufreq_verify_current_freq
In-Reply-To: <ZWXy0h/fFfQh+Rhy@arm.com>
References: <20231127160838.1403404-1-beata.michalska@arm.com>
 <20231127160838.1403404-3-beata.michalska@arm.com>
 <ZWXy0h/fFfQh+Rhy@arm.com>
Message-ID: <ZbyyhxYACe07vocu@e129154.nice.arm.com>

Hi Ionela,

So sorry for relpying so late, lost if from my rader for a while ...
On Tue, Nov 28, 2023 at 02:01:54PM +0000, Ionela Voinescu wrote:
> Hi Beata, Sumit,
> 
> On Monday 27 Nov 2023 at 16:08:38 (+0000), Beata Michalska wrote:
> > From: Sumit Gupta <sumitg at nvidia.com>
> > 
> > When available, use arch_freq_get_on_cpu to obtain current frequency
> > (usually an average reported over given period of time)
> > to better align the cpufreq's view on the current state of affairs.
> > This also automatically pulls in the update for cpuinfo_cur_freq sysfs
> > attribute, aligning it with the scaling_cur_freq one, and thus providing
> > consistent view on relevant platforms.
> > 
> > Signed-off-by: Sumit Gupta <sumitg at nvidia.com>
> > [BM: Subject & commit msg]
> > Signed-off-by: Beata Michalska <beata.michalska at arm.com>
> > ---
> >  drivers/cpufreq/cpufreq.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> > index 8c4f9c2f9c44..109559438f45 100644
> > --- a/drivers/cpufreq/cpufreq.c
> > +++ b/drivers/cpufreq/cpufreq.c
> > @@ -1756,7 +1756,8 @@ static unsigned int cpufreq_verify_current_freq(struct cpufreq_policy *policy, b
> >  {
> >  	unsigned int new_freq;
> >  
> > -	new_freq = cpufreq_driver->get(policy->cpu);
> > +	new_freq = arch_freq_get_on_cpu(policy->cpu);
> > +	new_freq = new_freq ?: cpufreq_driver->get(policy->cpu);
> 
> Given that arch_freq_get_on_cpu() is an average frequency, it does not
> seem right to me to trigger the sync & update process of
> cpufreq_verify_current_freq() based on it.
> 
> cpufreq_verify_current_freq() will at least modify the internal state of
> the policy and send PRE and POST notifications, if not do a full frequency
> update, based on this average frequency, which is likely different from
> the current frequency, even beyond the 1MHz threshold.
> 
Noted, will drop this change.

---
BR
Beata
> While I believe it's okay to return this average frequency in
> cpuinfo_cur_freq, I don't think it should be used as an indication of
> an accurate current frequency, which is what
> cpufreq_verify_current_freq() expects.
> 

> Sumit, can you give more details on the issue at [1] and why this change
> fixes it?
> 
> [1] https://lore.kernel.org/lkml/6a5710f6-bfbb-5dfd-11cd-0cd02220cee7 at nvidia.com/
> 
> Thank you,
> Ionela.
	> 
> >  	if (!new_freq)
> >  		return 0;
> >  
> > -- 
> > 2.25.1
> > 


From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb  2 01:19:13 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 02 Feb 2024 12:19:13 +0300
Subject: [PATCH net-next v3 7/7] net: dsa: mt7530: do not clear
 config->supported_interfaces
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
Message-ID: <20240202-for-netnext-mt7530-improvements-2-v3-7-63d5adae99ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

There's no need to clear the config->supported_interfaces bitmap before
reporting the supported interfaces as all bits in the bitmap will already
be initialized to zero when the phylink_config structure is allocated. The
"config" pointer points to &dp->phylink_config, and "dp" is allocated by
dsa_port_touch() with kzalloc(), so all its fields are filled with zeroes.

There's no code that would change the bitmap beforehand. Remove it.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Acked-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
---
 drivers/net/dsa/mt7530.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 4ca7ba94788e..aed1ea6815ee 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2573,8 +2573,6 @@ static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
 static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 				     struct phylink_config *config)
 {
-	phy_interface_zero(config->supported_interfaces);
-
 	switch (port) {
 	/* Ports which are connected to switch PHYs. There is no MII pinout. */
 	case 0 ... 3:

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb  2 01:19:12 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 02 Feb 2024 12:19:12 +0300
Subject: [PATCH net-next v3 6/7] net: dsa: mt7530: correct port
 capabilities of MT7988
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
Message-ID: <20240202-for-netnext-mt7530-improvements-2-v3-6-63d5adae99ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

On the switch on the MT7988 SoC, as shown in Block Diagram 8.1.1.3 on page
125 of "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open
Version) v0.1", there are only 4 PHYs. That's port 0 to 3. Set the case for
ports which connect to switch PHYs to '0 ... 3'.

Port 4 and 5 are not used at all in this design.

Link: https://wiki.banana-pi.org/Banana_Pi_BPI-R4#Documents [1]
Acked-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index e1fdef5766fb..4ca7ba94788e 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2577,7 +2577,7 @@ static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 
 	switch (port) {
 	/* Ports which are connected to switch PHYs. There is no MII pinout. */
-	case 0 ... 4:
+	case 0 ... 3:
 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 			  config->supported_interfaces);
 		break;

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb  2 01:19:07 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 02 Feb 2024 12:19:07 +0300
Subject: [PATCH net-next v3 1/7] net: dsa: mt7530: empty default case on
 mt7530_setup_port5()
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
Message-ID: <20240202-for-netnext-mt7530-improvements-2-v3-1-63d5adae99ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

There're two code paths for setting up port 5:

mt7530_setup()
-> mt7530_setup_port5()

mt753x_phylink_mac_config()
-> mt753x_mac_config()
   -> mt7530_mac_config()
      -> mt7530_setup_port5()

On the first code path, priv->p5_intf_sel is either set to
P5_INTF_SEL_PHY_P0 or P5_INTF_SEL_PHY_P4 when mt7530_setup_port5() is run.

On the second code path, priv->p5_intf_sel is set to P5_INTF_SEL_GMAC5 when
mt7530_setup_port5() is run.

Empty the default case which will never run but is needed nonetheless to
handle all the remaining enumeration values.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
---
 drivers/net/dsa/mt7530.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 68be38ae66e0..330e22abc076 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -943,9 +943,7 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
 		val &= ~MHWTRAP_P5_DIS;
 		break;
 	default:
-		dev_err(ds->dev, "Unsupported p5_intf_sel %d\n",
-			priv->p5_intf_sel);
-		goto unlock_exit;
+		break;
 	}
 
 	/* Setup RGMII settings */
@@ -975,7 +973,6 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
 	dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
 		val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface));
 
-unlock_exit:
 	mutex_unlock(&priv->reg_mutex);
 }
 

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb  2 01:19:06 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 02 Feb 2024 12:19:06 +0300
Subject: [PATCH net-next v3 0/7] MT7530 DSA Subdriver Improvements Act II
Message-ID: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>

Hello!

This is the second patch series with the goal of simplifying the MT7530 DSA
subdriver and improving support for MT7530, MT7531, and the switch on the
MT7988 SoC.

I have done a simple ping test to confirm basic communication on all switch
ports on MCM and standalone MT7530, and MT7531 switch with this patch
series applied.

MT7621 Unielec, MCM MT7530:

rgmii-only-gmac0-mt7621-unielec-u7621-06-16m.dtb
gmac0-and-gmac1-mt7621-unielec-u7621-06-16m.dtb

tftpboot 0x80008000 mips-uzImage.bin; tftpboot 0x83000000 mips-rootfs.cpio.uboot; tftpboot 0x83f00000 $dtb; bootm 0x80008000 0x83000000 0x83f00000

MT7622 Bananapi, MT7531:

gmac0-and-gmac1-mt7622-bananapi-bpi-r64.dtb

tftpboot 0x40000000 arm64-Image; tftpboot 0x45000000 arm64-rootfs.cpio.uboot; tftpboot 0x4a000000 $dtb; booti 0x40000000 0x45000000 0x4a000000

MT7623 Bananapi, standalone MT7530:

rgmii-only-gmac0-mt7623n-bananapi-bpi-r2.dtb
gmac0-and-gmac1-mt7623n-bananapi-bpi-r2.dtb

tftpboot 0x80008000 arm-zImage; tftpboot 0x83000000 arm-rootfs.cpio.uboot; tftpboot 0x83f00000 $dtb; bootz 0x80008000 0x83000000 0x83f00000

This patch series is the continuation of the patch series linked below.

https://lore.kernel.org/r/20230522121532.86610-1-arinc.unal at arinc9.com

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
Changes in v3:
- Update the patches with the latest received trailers.
- Patch 5
  - Disable TRGMII clocks for all cases.
- Link to v2: https://lore.kernel.org/r/20240130-for-netnext-mt7530-improvements-2-v2-0-ba06f5dd9eb0 at arinc9.com

Changes in v2:
- Update the patches with the latest received trailers.
- Remove 'net: dsa: mt7530: move enabling port 6 to mt7530_setup_port6()'
  which was patch 5. I will bring a more appropriate change with a later
  patch series.
- Patch 5
  - Set P6_INTF_MODE(0) and explain why on the patch log.
- Patch 6
  - Mention the MT7988 document and explain more on the patch log.
- Patch 7
  - Explain more on the patch log.
- Link to v1: https://lore.kernel.org/r/20240113102529.80371-1-arinc.unal at arinc9.com

---
Ar?n? ?NAL (7):
      net: dsa: mt7530: empty default case on mt7530_setup_port5()
      net: dsa: mt7530: call port 6 setup from mt7530_mac_config()
      net: dsa: mt7530: remove pad_setup function pointer
      net: dsa: mt7530: move XTAL check to mt7530_setup()
      net: dsa: mt7530: simplify mt7530_setup_port6() and change to void
      net: dsa: mt7530: correct port capabilities of MT7988
      net: dsa: mt7530: do not clear config->supported_interfaces

 drivers/net/dsa/mt7530.c | 152 +++++++++++++++++------------------------------
 drivers/net/dsa/mt7530.h |   3 -
 2 files changed, 53 insertions(+), 102 deletions(-)
---
base-commit: 4acf4e62cd572b0c806035046b3698f5585ab821
change-id: 20240121-for-netnext-mt7530-improvements-2-b4f43661b485

Best regards,
-- 
Ar?n? ?NAL <arinc.unal at arinc9.com>



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb  2 01:19:08 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 02 Feb 2024 12:19:08 +0300
Subject: [PATCH net-next v3 2/7] net: dsa: mt7530: call port 6 setup from
 mt7530_mac_config()
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
Message-ID: <20240202-for-netnext-mt7530-improvements-2-v3-2-63d5adae99ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

mt7530_pad_clk_setup() is called if port 6 is enabled. It used to do more
things than setting up port 6. That part was moved to more appropriate
locations, mt7530_setup() and mt7530_pll_setup().

Now that all it does is set up port 6, rename it to mt7530_setup_port6(),
and move it to a more appropriate location, under mt7530_mac_config().

Leave an empty mt7530_pad_clk_setup() to satisfy the pad_setup function
pointer.

This is the code path for setting up the ports before:

mt753x_phylink_mac_config()
-> mt753x_mac_config()
   -> mt7530_mac_config()
      -> mt7530_setup_port5()
-> mt753x_pad_setup()
   -> mt7530_pad_clk_setup()

This is after:

mt753x_phylink_mac_config()
-> mt753x_mac_config()
   -> mt7530_mac_config()
      -> mt7530_setup_port5()
      -> mt7530_setup_port6()

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
---
 drivers/net/dsa/mt7530.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 330e22abc076..2d468a5f2e70 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -415,7 +415,7 @@ mt753x_preferred_default_local_cpu_port(struct dsa_switch *ds)
 
 /* Setup port 6 interface mode and TRGMII TX circuit */
 static int
-mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
+mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
 {
 	struct mt7530_priv *priv = ds->priv;
 	u32 ncpo1, ssc_delta, trgint, xtal;
@@ -487,6 +487,12 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 	return 0;
 }
 
+static int
+mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
+{
+	return 0;
+}
+
 static int
 mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
 {
@@ -2624,12 +2630,15 @@ mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
 {
 	struct mt7530_priv *priv = ds->priv;
+	int ret;
 
-	/* Only need to setup port5. */
-	if (port != 5)
-		return 0;
-
-	mt7530_setup_port5(priv->ds, interface);
+	if (port == 5) {
+		mt7530_setup_port5(priv->ds, interface);
+	} else if (port == 6) {
+		ret = mt7530_setup_port6(priv->ds, interface);
+		if (ret)
+			return ret;
+	}
 
 	return 0;
 }

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb  2 01:19:10 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 02 Feb 2024 12:19:10 +0300
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
Message-ID: <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

The crystal frequency concerns the switch core. The frequency should be
checked when the switch is being set up so the driver can reject the
unsupported hardware earlier and without requiring port 6 to be used.

Move it to mt7530_setup(). Drop the unnecessary function printing.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
---
 drivers/net/dsa/mt7530.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index fdaf65b58b72..c4d492e29fdf 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -422,13 +422,6 @@ mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
 
 	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
 
-	if (xtal == HWTRAP_XTAL_20MHZ) {
-		dev_err(priv->dev,
-			"%s: MT7530 with a 20MHz XTAL is not supported!\n",
-			__func__);
-		return -EINVAL;
-	}
-
 	switch (interface) {
 	case PHY_INTERFACE_MODE_RGMII:
 		trgint = 0;
@@ -2253,6 +2246,12 @@ mt7530_setup(struct dsa_switch *ds)
 		return -ENODEV;
 	}
 
+	if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_20MHZ) {
+		dev_err(priv->dev,
+			"MT7530 with a 20MHz XTAL is not supported!\n");
+		return -EINVAL;
+	}
+
 	/* Reset the switch through internal reset */
 	mt7530_write(priv, MT7530_SYS_CTRL,
 		     SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb  2 01:19:09 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 02 Feb 2024 12:19:09 +0300
Subject: [PATCH net-next v3 3/7] net: dsa: mt7530: remove pad_setup
 function pointer
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
Message-ID: <20240202-for-netnext-mt7530-improvements-2-v3-3-63d5adae99ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

The pad_setup function pointer was introduced with 88bdef8be9f6 ("net: dsa:
mt7530: Extend device data ready for adding a new hardware"). It was being
used to set up the core clock and port 6 of the MT7530 switch, and pll of
the MT7531 switch.

All of these were moved to more appropriate locations, and it was never
used for the switch on the MT7988 SoC. Therefore, this function pointer
hasn't got a use anymore. Remove it.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Acked-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
---
 drivers/net/dsa/mt7530.c | 36 ++----------------------------------
 drivers/net/dsa/mt7530.h |  3 ---
 2 files changed, 2 insertions(+), 37 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 2d468a5f2e70..fdaf65b58b72 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -487,18 +487,6 @@ mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
 	return 0;
 }
 
-static int
-mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
-{
-	return 0;
-}
-
-static int
-mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
-{
-	return 0;
-}
-
 static void
 mt7531_pll_setup(struct mt7530_priv *priv)
 {
@@ -2617,14 +2605,6 @@ static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 	}
 }
 
-static int
-mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
-{
-	struct mt7530_priv *priv = ds->priv;
-
-	return priv->info->pad_setup(ds, state->interface);
-}
-
 static int
 mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
@@ -2794,8 +2774,6 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		if (priv->p6_interface == state->interface)
 			break;
 
-		mt753x_pad_setup(ds, state);
-
 		if (mt753x_mac_config(ds, port, mode, state) < 0)
 			goto unsupported;
 
@@ -3113,11 +3091,6 @@ mt753x_conduit_state_change(struct dsa_switch *ds,
 	mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val);
 }
 
-static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
-{
-	return 0;
-}
-
 static int mt7988_setup(struct dsa_switch *ds)
 {
 	struct mt7530_priv *priv = ds->priv;
@@ -3181,7 +3154,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7530_phy_write_c22,
 		.phy_read_c45 = mt7530_phy_read_c45,
 		.phy_write_c45 = mt7530_phy_write_c45,
-		.pad_setup = mt7530_pad_clk_setup,
 		.mac_port_get_caps = mt7530_mac_port_get_caps,
 		.mac_port_config = mt7530_mac_config,
 	},
@@ -3193,7 +3165,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7530_phy_write_c22,
 		.phy_read_c45 = mt7530_phy_read_c45,
 		.phy_write_c45 = mt7530_phy_write_c45,
-		.pad_setup = mt7530_pad_clk_setup,
 		.mac_port_get_caps = mt7530_mac_port_get_caps,
 		.mac_port_config = mt7530_mac_config,
 	},
@@ -3205,7 +3176,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7531_ind_c22_phy_write,
 		.phy_read_c45 = mt7531_ind_c45_phy_read,
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
-		.pad_setup = mt7531_pad_setup,
 		.cpu_port_config = mt7531_cpu_port_config,
 		.mac_port_get_caps = mt7531_mac_port_get_caps,
 		.mac_port_config = mt7531_mac_config,
@@ -3218,7 +3188,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7531_ind_c22_phy_write,
 		.phy_read_c45 = mt7531_ind_c45_phy_read,
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
-		.pad_setup = mt7988_pad_setup,
 		.cpu_port_config = mt7988_cpu_port_config,
 		.mac_port_get_caps = mt7988_mac_port_get_caps,
 		.mac_port_config = mt7988_mac_config,
@@ -3248,9 +3217,8 @@ mt7530_probe_common(struct mt7530_priv *priv)
 	/* Sanity check if these required device operations are filled
 	 * properly.
 	 */
-	if (!priv->info->sw_setup || !priv->info->pad_setup ||
-	    !priv->info->phy_read_c22 || !priv->info->phy_write_c22 ||
-	    !priv->info->mac_port_get_caps ||
+	if (!priv->info->sw_setup || !priv->info->phy_read_c22 ||
+	    !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps ||
 	    !priv->info->mac_port_config)
 		return -EINVAL;
 
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 80060cc740d2..26a6d2160c08 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -704,8 +704,6 @@ struct mt753x_pcs {
  * @phy_write_c22:	Holding the way writing PHY port using C22
  * @phy_read_c45:	Holding the way reading PHY port using C45
  * @phy_write_c45:	Holding the way writing PHY port using C45
- * @pad_setup:		Holding the way setting up the bus pad for a certain
- *			MAC port
  * @phy_mode_supported:	Check if the PHY type is being supported on a certain
  *			port
  * @mac_port_validate:	Holding the way to set addition validate type for a
@@ -726,7 +724,6 @@ struct mt753x_info {
 			    int regnum);
 	int (*phy_write_c45)(struct mt7530_priv *priv, int port, int devad,
 			     int regnum, u16 val);
-	int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
 	int (*cpu_port_config)(struct dsa_switch *ds, int port);
 	void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
 				  struct phylink_config *config);

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb  2 01:19:11 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 02 Feb 2024 12:19:11 +0300
Subject: [PATCH net-next v3 5/7] net: dsa: mt7530: simplify
 mt7530_setup_port6() and change to void
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
Message-ID: <20240202-for-netnext-mt7530-improvements-2-v3-5-63d5adae99ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

This code is from before this driver was converted to phylink API. Phylink
deals with the unsupported interface cases before mt7530_setup_port6() is
run. Therefore, the default case would never run. However, it must be
defined nonetheless to handle all the remaining enumeration values, the
phy-modes.

Switch to if statement for RGMII and return which simplifies the code and
saves an indent.

Set P6_INTF_MODE, which is the the three least significant bits of the
MT7530_P6ECR register, to 0 for RGMII even though it will already be 0
after reset. This is to keep supporting dynamic reconfiguration of the port
in the case the interface changes from TRGMII to RGMII.

Disable the TRGMII clocks for all cases. They will be enabled if TRGMII is
being used.

Read XTAL after checking for RGMII as it's only needed for the TRGMII
interface mode.

Change mt7530_setup_port6() to void now that there're no error cases left.

Reviewed-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 101 ++++++++++++++++++++---------------------------
 1 file changed, 42 insertions(+), 59 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index c4d492e29fdf..e1fdef5766fb 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -414,70 +414,57 @@ mt753x_preferred_default_local_cpu_port(struct dsa_switch *ds)
 }
 
 /* Setup port 6 interface mode and TRGMII TX circuit */
-static int
+static void
 mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
 {
 	struct mt7530_priv *priv = ds->priv;
-	u32 ncpo1, ssc_delta, trgint, xtal;
+	u32 ncpo1, ssc_delta, xtal;
 
-	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
+	/* Disable the MT7530 TRGMII clocks */
+	core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 
-	switch (interface) {
-	case PHY_INTERFACE_MODE_RGMII:
-		trgint = 0;
-		break;
-	case PHY_INTERFACE_MODE_TRGMII:
-		trgint = 1;
-		if (xtal == HWTRAP_XTAL_25MHZ)
-			ssc_delta = 0x57;
-		else
-			ssc_delta = 0x87;
-		if (priv->id == ID_MT7621) {
-			/* PLL frequency: 125MHz: 1.0GBit */
-			if (xtal == HWTRAP_XTAL_40MHZ)
-				ncpo1 = 0x0640;
-			if (xtal == HWTRAP_XTAL_25MHZ)
-				ncpo1 = 0x0a00;
-		} else { /* PLL frequency: 250MHz: 2.0Gbit */
-			if (xtal == HWTRAP_XTAL_40MHZ)
-				ncpo1 = 0x0c80;
-			if (xtal == HWTRAP_XTAL_25MHZ)
-				ncpo1 = 0x1400;
-		}
-		break;
-	default:
-		dev_err(priv->dev, "xMII interface %d not supported\n",
-			interface);
-		return -EINVAL;
+	if (interface == PHY_INTERFACE_MODE_RGMII) {
+		mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
+			   P6_INTF_MODE(0));
+		return;
 	}
 
-	mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
-		   P6_INTF_MODE(trgint));
+	mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
 
-	if (trgint) {
-		/* Disable the MT7530 TRGMII clocks */
-		core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
+	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
 
-		/* Setup the MT7530 TRGMII Tx Clock */
-		core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
-		core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
-		core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
-		core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
-		core_write(priv, CORE_PLL_GROUP4,
-			   RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN |
-			   RG_SYSPLL_BIAS_LPF_EN);
-		core_write(priv, CORE_PLL_GROUP2,
-			   RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
-			   RG_SYSPLL_POSDIV(1));
-		core_write(priv, CORE_PLL_GROUP7,
-			   RG_LCDDS_PCW_NCPO_CHG | RG_LCCDS_C(3) |
-			   RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
+	if (xtal == HWTRAP_XTAL_25MHZ)
+		ssc_delta = 0x57;
+	else
+		ssc_delta = 0x87;
 
-		/* Enable the MT7530 TRGMII clocks */
-		core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
+	if (priv->id == ID_MT7621) {
+		/* PLL frequency: 125MHz: 1.0GBit */
+		if (xtal == HWTRAP_XTAL_40MHZ)
+			ncpo1 = 0x0640;
+		if (xtal == HWTRAP_XTAL_25MHZ)
+			ncpo1 = 0x0a00;
+	} else { /* PLL frequency: 250MHz: 2.0Gbit */
+		if (xtal == HWTRAP_XTAL_40MHZ)
+			ncpo1 = 0x0c80;
+		if (xtal == HWTRAP_XTAL_25MHZ)
+			ncpo1 = 0x1400;
 	}
 
-	return 0;
+	/* Setup the MT7530 TRGMII Tx Clock */
+	core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
+	core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
+	core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
+	core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
+	core_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN |
+		   RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
+	core_write(priv, CORE_PLL_GROUP2, RG_SYSPLL_EN_NORMAL |
+		   RG_SYSPLL_VODEN | RG_SYSPLL_POSDIV(1));
+	core_write(priv, CORE_PLL_GROUP7, RG_LCDDS_PCW_NCPO_CHG |
+		   RG_LCCDS_C(3) | RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
+
+	/* Enable the MT7530 TRGMII clocks */
+	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 }
 
 static void
@@ -2609,15 +2596,11 @@ mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
 {
 	struct mt7530_priv *priv = ds->priv;
-	int ret;
 
-	if (port == 5) {
+	if (port == 5)
 		mt7530_setup_port5(priv->ds, interface);
-	} else if (port == 6) {
-		ret = mt7530_setup_port6(priv->ds, interface);
-		if (ret)
-			return ret;
-	}
+	else if (port == 6)
+		mt7530_setup_port6(priv->ds, interface);
 
 	return 0;
 }

-- 
2.40.1



From beata.michalska at arm.com  Fri Feb  2 01:20:34 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Fri, 2 Feb 2024 10:20:34 +0100
Subject: [PATCH v2 1/2] arm64: Provide an AMU-based version of
 arch_freq_get_on_cpu
In-Reply-To: <ZWYDr6JJJzBvsqf0@arm.com>
References: <20231127160838.1403404-2-beata.michalska@arm.com>
 <ZWYDr6JJJzBvsqf0@arm.com>
Message-ID: <Zbyz4mQHLI9aPK6e@e129154.nice.arm.com>

On Tue, Nov 28, 2023 at 03:13:51PM +0000, Ionela Voinescu wrote:
> Hi Beata,
> 
> On Monday 27 Nov 2023 at 16:08:37 (+0000), Beata Michalska wrote:
> > With the Frequency Invariance Engine (FIE) being already wired up with
> > sched tick and making use of relevant (core counter and constant
> > counter) AMU counters, getting the current frequency for a given CPU
> > on supported platforms, can be achieved by utilizing the frequency scale
> > factor which reflects an average CPU frequency for the last tick period
> > length.
> > 
> > Suggested-by: Ionela Voinescu <ionela.voinescu at arm.com>
> > Signed-off-by: Beata Michalska <beata.michalska at arm.com>
> > Reviewed-by: Sudeep Holla <sudeep.holla at arm.com>
> > ---
> > 
> > Notes:
> >     Due to [1], if merged, there might be a need to modify the patch to
> >     accommodate changes [1] introduces:
> >     
> >     	freq = cpufreq_get_hw_max_freq(cpu) >> SCHED_CAPACITY_SHIFT
> >     	to
> >     	freq = per_cpu(capacity_freq_ref, cpu); >> SCHED_CAPACITY_SHIFT
> >     [1]
> >     https://lore.kernel.org/linux-arm-kernel/20231121154349.GA1938 at willie-the-truck/T/#mcb018d076dbce6f60ed2779634a9b6ffe622641e
> > 
> >  arch/arm64/kernel/topology.c | 39 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 39 insertions(+)
> > 
> > diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
> > index 615c1a20129f..ae2445f6e7da 100644
> > --- a/arch/arm64/kernel/topology.c
> > +++ b/arch/arm64/kernel/topology.c
> > @@ -17,6 +17,7 @@
> >  #include <linux/cpufreq.h>
> >  #include <linux/init.h>
> >  #include <linux/percpu.h>
> > +#include <linux/sched/isolation.h>
> >  
> >  #include <asm/cpu.h>
> >  #include <asm/cputype.h>
> > @@ -186,6 +187,44 @@ static void amu_scale_freq_tick(void)
> >  	this_cpu_write(arch_freq_scale, (unsigned long)scale);
> >  }
> >  
> > +unsigned int arch_freq_get_on_cpu(int cpu)
> > +{
> > +	unsigned int freq;
> > +	u64 scale;
> > +
> > +	if (!cpumask_test_cpu(cpu, amu_fie_cpus))
> > +		return 0;
> > +
> > +	/*
> > +	 * For those CPUs that are in full dynticks mode, try an alternative
> > +	 * source for the counters (and thus freq scale),
> > +	 * if available for given policy
> > +	 */
> > +	if (!housekeeping_cpu(cpu, HK_TYPE_TICK)) {
> > +		struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
> > +		int ref_cpu = nr_cpu_ids;
> > +
> > +		if (cpumask_intersects(housekeeping_cpumask(HK_TYPE_TICK),
> > +				       policy->cpus))
> > +			ref_cpu = cpumask_nth_and(cpu, policy->cpus,
> > +						  housekeeping_cpumask(HK_TYPE_TICK));
> > +		cpufreq_cpu_put(policy);
> > +		if (ref_cpu >= nr_cpu_ids)
> > +			return 0;
> > +		cpu = ref_cpu;
> > +	}
> > +
> > +	/*
> > +	 * Reversed computation to the one used to determine
> > +	 * the arch_freq_scale value
> > +	 * (see amu_scale_freq_tick for details)
> > +	 */
> > +	scale = per_cpu(arch_freq_scale, cpu);
> 
> Any reason for not using arch_scale_freq_capacity() here?
> 
> To me it seems a bit nicer to use the "official" function to return the
> frequency scale factor.
> 
Noted.
> > +	freq = cpufreq_get_hw_max_freq(cpu) >> SCHED_CAPACITY_SHIFT;
> 
> Given Vincent's patch at [1] I think here might be best to call
> arch_scale_freq_ref() instead. That's because the frequency scale factor
> will use that frequency as the maximum frequency in its calculations and
> we'd not want to use a different one here.
> 
OK.
> The annoyance is coping with capacity_freq_ref not having been set
> yet, and that would be easy if capacity_freq_ref was initialized to 0.
> Luckily with Vincent's changes it can now be 0. I'll comments on his
> patches and ask him to make this change.
> 
> So I think you can safely use arch_scale_freq_ref() here. If
> arch_scale_freq_ref() returns 0, arch_freq_get_on_cpu() will just return
> 0 as well.
> 
Will do.
> [1] https://lore.kernel.org/lkml/20231109101438.1139696-8-vincent.guittot at linaro.org/
> 
> > +	freq *= scale;
> 
> In some scenarios the frequencies visible to cpufreq might not look like
> actual frequencies, but some scaled abstract performance values. One
> example is cppc_cpufreq when one does not provide the optional frequency
> information in the CPC objects but just the performance information.
> 
> Therefore the maximum frequency seen here can be quite a small value, so
> it might be best to do the multiplication first and the shift after that.
> 
Right, that was in v1! Must have mixed up things ending with stale data.
Will address that in the next version - if one is out.

---
BR
Beata
> Thanks,
> Ionela.
> 
> > +	return freq;
> > +}
> > +
> >  static struct scale_freq_data amu_sfd = {
> >  	.source = SCALE_FREQ_SOURCE_ARCH,
> >  	.set_freq_scale = amu_scale_freq_tick,
> > -- 
> > 2.25.1
> > 


From xu.yang_2 at nxp.com  Fri Feb  2 01:29:30 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Fri, 2 Feb 2024 09:29:30 +0000
Subject: [EXT] Re: [PATCH v5 5/8] dt-bindings: usb: ci-hdrc-usb2: add
 compatible and clock-names restriction for imx93
In-Reply-To: <41d1bc21-ea4a-4af6-93a6-b498ac1896ef@linaro.org>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-5-xu.yang_2@nxp.com>
 <41d1bc21-ea4a-4af6-93a6-b498ac1896ef@linaro.org>
Message-ID: <DU2PR04MB8822552D13485466C78B95938C422@DU2PR04MB8822.eurprd04.prod.outlook.com>

Hi Krzysztof,

> 
> On 31/01/2024 12:43, Xu Yang wrote:
> > The i.MX93 needs a wakup clock to work properly. This will add compatible
> > and restriction for i.MX93 platform.
> >
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> >
> > ---
> > Changes in v2:
> >  - no changes
> > Changes in v3:
> >  - add clocks restriction
> > Changes in v4:
> >  - use 'contains' rather 'items'
> > Changes in v5:
> >  - rename clock name
> > ---
> >  .../devicetree/bindings/usb/ci-hdrc-usb2.yaml | 35 ++++++++++++++++++-
> >  1 file changed, 34 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-
> hdrc-usb2.yaml
> > index 6ad3582051b8..12466f7af00b 100644
> > --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> > +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> > @@ -57,6 +57,7 @@ properties:
> >            - enum:
> >                - fsl,imx8mm-usb
> >                - fsl,imx8mn-usb
> > +              - fsl,imx93-usb
> >            - const: fsl,imx7d-usb
> >            - const: fsl,imx27-usb
> >        - items:
> > @@ -486,7 +487,6 @@ allOf:
> >                - chipidea,usb2
> >                - fsl,imx23-usb
> >                - fsl,imx28-usb
> > -              - fsl,imx7d-usb
> >                - fsl,vf610-usb
> >      then:
> >        properties:
> > @@ -497,6 +497,38 @@ allOf:
> >            minItems: 1
> >            maxItems: 1
> >
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          items:
> > +            - const: fsl,imx7d-usb
> > +            - const: fsl,imx27-usb
> 
> This does not look related to imx93.

Because fsl,imx93-usb is compatible with fsl,imx7d-usb and only imx93 needs
wakeup clock, so I remove fsl,imx7d-usb from previous if-then restriction.
Otherwise, when do dt-validate for imx93, it will require 1 clocks and 1 clock-names
property. Then imx7d and imx8* socs will lost restrictions on clocks and clock-names.

Then I still need add restrictions for compatible = 'fsl,imx7d-usb ', 'fsl,imx27-usb '
and other compatibles like 'fsl,imx8mm-usb', 'fsl,imx7d-usb, 'fsl,imx27-usb''. So the
below changes are for this purpose.

> 
> > +    then:
> > +      properties:
> > +        clocks:
> > +          minItems: 1
> > +          maxItems: 1
> > +        clock-names:
> > +          minItems: 1
> > +          maxItems: 1
> > +
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - fsl,imx93-usb
> > +    then:
> > +      properties:
> > +        clocks:
> > +          minItems: 2
> > +          maxItems: 2
> > +        clock-names:
> > +          minItems: 2
> > +          maxItems: 2
> > +          contains:
> > +            const: usb_wakeup
> 
> No, clocks must be fixed and specific. No contains allowed for new variants.

Well, I will change this then.

> 
> > +
> >    - if:
> >        properties:
> >          compatible:
> > @@ -504,6 +536,7 @@ allOf:
> >              oneOf:
> >                - pattern: '^fsl,imx5[0-3]+-usb$'
> >                - pattern: '^fsl,imx6[a-z]+-usb$'
> > +              - pattern: '^fsl,imx8[a-z]+-usb$'
> 
> Aren't you adding imx9?

See above explanation.

Thanks,
Xu Yang

From cleger at rivosinc.com  Fri Feb  2 01:29:44 2024
From: cleger at rivosinc.com (=?UTF-8?B?Q2zDqW1lbnQgTMOpZ2Vy?=)
Date: Fri, 2 Feb 2024 10:29:44 +0100
Subject: [PATCH v12 22/25] irqchip: Add RISC-V advanced PLIC driver for
 direct-mode
In-Reply-To: <20240127161753.114685-23-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-23-apatel@ventanamicro.com>
Message-ID: <eed1ee03-923b-41e8-b99a-accc1278da6b@rivosinc.com>



On 27/01/2024 17:17, Anup Patel wrote:
> The RISC-V advanced interrupt architecture (AIA) specification defines
> advanced platform-level interrupt controller (APLIC) which has two modes
> of operation: 1) Direct mode and 2) MSI mode.
> (For more details, refer https://github.com/riscv/riscv-aia)
> 
> In APLIC direct-mode, wired interrupts are forwared to CPUs (or HARTs)
> as a local external interrupt.
> 
> We add a platform irqchip driver for the RISC-V APLIC direct-mode to
> support RISC-V platforms having only wired interrupts.
> 
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> ---
>  drivers/irqchip/Kconfig                  |   5 +
>  drivers/irqchip/Makefile                 |   1 +
>  drivers/irqchip/irq-riscv-aplic-direct.c | 343 +++++++++++++++++++++++
>  drivers/irqchip/irq-riscv-aplic-main.c   | 232 +++++++++++++++
>  drivers/irqchip/irq-riscv-aplic-main.h   |  45 +++
>  include/linux/irqchip/riscv-aplic.h      | 119 ++++++++
>  6 files changed, 745 insertions(+)
>  create mode 100644 drivers/irqchip/irq-riscv-aplic-direct.c
>  create mode 100644 drivers/irqchip/irq-riscv-aplic-main.c
>  create mode 100644 drivers/irqchip/irq-riscv-aplic-main.h
>  create mode 100644 include/linux/irqchip/riscv-aplic.h
> 
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 2fc0cb32341a..dbc8811d3764 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -546,6 +546,11 @@ config SIFIVE_PLIC
>  	select IRQ_DOMAIN_HIERARCHY
>  	select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
>  
> +config RISCV_APLIC
> +	bool
> +	depends on RISCV
> +	select IRQ_DOMAIN_HIERARCHY
> +
>  config RISCV_IMSIC
>  	bool
>  	depends on RISCV
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index abca445a3229..7f8289790ed8 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
>  obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
>  obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
>  obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
> +obj-$(CONFIG_RISCV_APLIC)		+= irq-riscv-aplic-main.o irq-riscv-aplic-direct.o
>  obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
>  obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
>  obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
> diff --git a/drivers/irqchip/irq-riscv-aplic-direct.c b/drivers/irqchip/irq-riscv-aplic-direct.c
> new file mode 100644
> index 000000000000..9ed2666bfb5e
> --- /dev/null
> +++ b/drivers/irqchip/irq-riscv-aplic-direct.c
> @@ -0,0 +1,343 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> + * Copyright (C) 2022 Ventana Micro Systems Inc.

2024 ?

> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/cpu.h>
> +#include <linux/interrupt.h>
> +#include <linux/irqchip.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/irqchip/riscv-aplic.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/printk.h>
> +#include <linux/smp.h>
> +
> +#include "irq-riscv-aplic-main.h"
> +
> +#define APLIC_DISABLE_IDELIVERY		0
> +#define APLIC_ENABLE_IDELIVERY		1
> +#define APLIC_DISABLE_ITHRESHOLD	1
> +#define APLIC_ENABLE_ITHRESHOLD		0
> +
> +struct aplic_direct {
> +	struct aplic_priv	priv;
> +	struct irq_domain	*irqdomain;
> +	struct cpumask		lmask;
> +};
> +
> +struct aplic_idc {
> +	unsigned int		hart_index;
> +	void __iomem		*regs;
> +	struct aplic_direct	*direct;
> +};
> +
> +static unsigned int aplic_direct_parent_irq;
> +static DEFINE_PER_CPU(struct aplic_idc, aplic_idcs);
> +
> +static void aplic_direct_irq_eoi(struct irq_data *d)
> +{
> +	/*
> +	 * The fasteoi_handler requires irq_eoi() callback hence
> +	 * provide a dummy handler.
> +	 */
> +}
> +
> +#ifdef CONFIG_SMP
> +static int aplic_direct_set_affinity(struct irq_data *d,
> +				  const struct cpumask *mask_val, bool force)
> +{
> +	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> +	struct aplic_direct *direct =
> +			container_of(priv, struct aplic_direct, priv);
> +	struct aplic_idc *idc;
> +	unsigned int cpu, val;
> +	struct cpumask amask;
> +	void __iomem *target;
> +
> +	cpumask_and(&amask, &direct->lmask, mask_val);
> +
> +	if (force)
> +		cpu = cpumask_first(&amask);
> +	else
> +		cpu = cpumask_any_and(&amask, cpu_online_mask);
> +
> +	if (cpu >= nr_cpu_ids)
> +		return -EINVAL;
> +
> +	idc = per_cpu_ptr(&aplic_idcs, cpu);
> +	target = priv->regs + APLIC_TARGET_BASE;
> +	target += (d->hwirq - 1) * sizeof(u32);
> +	val = idc->hart_index & APLIC_TARGET_HART_IDX_MASK;
> +	val <<= APLIC_TARGET_HART_IDX_SHIFT;

Hi Anup,

You could use FIELD_PREP() instead of manual mask/shift.

#define APLIC_TARGET_HART_IDX_MASK 0xfffc0000

And then FIELD_PREP(APLIC_TARGET_HART_IDX_MASK, idc->hart_index)


> +	val |= APLIC_DEFAULT_PRIORITY;
> +	writel(val, target);
> +
> +	irq_data_update_effective_affinity(d, cpumask_of(cpu));
> +
> +	return IRQ_SET_MASK_OK_DONE;
> +}
> +#endif
> +
> +static struct irq_chip aplic_direct_chip = {
> +	.name		= "APLIC-DIRECT",
> +	.irq_mask	= aplic_irq_mask,
> +	.irq_unmask	= aplic_irq_unmask,
> +	.irq_set_type	= aplic_irq_set_type,
> +	.irq_eoi	= aplic_direct_irq_eoi,
> +#ifdef CONFIG_SMP
> +	.irq_set_affinity = aplic_direct_set_affinity,
> +#endif
> +	.flags		= IRQCHIP_SET_TYPE_MASKED |
> +			  IRQCHIP_SKIP_SET_WAKE |
> +			  IRQCHIP_MASK_ON_SUSPEND,
> +};
> +
> +static int aplic_direct_irqdomain_translate(struct irq_domain *d,
> +					 struct irq_fwspec *fwspec,
> +					 unsigned long *hwirq,
> +					 unsigned int *type)
> +{
> +	struct aplic_priv *priv = d->host_data;
> +
> +	return aplic_irqdomain_translate(fwspec, priv->gsi_base,
> +					 hwirq, type);
> +}
> +
> +static int aplic_direct_irqdomain_alloc(struct irq_domain *domain,
> +				     unsigned int virq, unsigned int nr_irqs,
> +				     void *arg)
> +{
> +	int i, ret;
> +	unsigned int type;
> +	irq_hw_number_t hwirq;
> +	struct irq_fwspec *fwspec = arg;
> +	struct aplic_priv *priv = domain->host_data;
> +	struct aplic_direct *direct =
> +			container_of(priv, struct aplic_direct, priv);
> +
> +	ret = aplic_irqdomain_translate(fwspec, priv->gsi_base,
> +					&hwirq, &type);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; i < nr_irqs; i++) {
> +		irq_domain_set_info(domain, virq + i, hwirq + i,
> +				    &aplic_direct_chip, priv,
> +				    handle_fasteoi_irq, NULL, NULL);
> +		irq_set_affinity(virq + i, &direct->lmask);
> +		/* See the reason described in aplic_msi_irqdomain_alloc() */
> +		irq_set_status_flags(virq + i, IRQ_DISABLE_UNLAZY);
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops aplic_direct_irqdomain_ops = {
> +	.translate	= aplic_direct_irqdomain_translate,
> +	.alloc		= aplic_direct_irqdomain_alloc,
> +	.free		= irq_domain_free_irqs_top,
> +};
> +
> +/*
> + * To handle an APLIC direct interrupts, we just read the CLAIMI register
> + * which will return highest priority pending interrupt and clear the
> + * pending bit of the interrupt. This process is repeated until CLAIMI
> + * register return zero value.
> + */
> +static void aplic_direct_handle_irq(struct irq_desc *desc)
> +{
> +	struct aplic_idc *idc = this_cpu_ptr(&aplic_idcs);
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	struct irq_domain *irqdomain = idc->direct->irqdomain;
> +	irq_hw_number_t hw_irq;
> +	int irq;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	while ((hw_irq = readl(idc->regs + APLIC_IDC_CLAIMI))) {
> +		hw_irq = hw_irq >> APLIC_IDC_TOPI_ID_SHIFT;
> +		irq = irq_find_mapping(irqdomain, hw_irq);
> +
> +		if (unlikely(irq <= 0))
> +			dev_warn_ratelimited(idc->direct->priv.dev,
> +					     "hw_irq %lu mapping not found\n",
> +					     hw_irq);
> +		else
> +			generic_handle_irq(irq);
> +	}
> +
> +	chained_irq_exit(chip, desc);
> +}
> +
> +static void aplic_idc_set_delivery(struct aplic_idc *idc, bool en)
> +{
> +	u32 de = (en) ? APLIC_ENABLE_IDELIVERY : APLIC_DISABLE_IDELIVERY;
> +	u32 th = (en) ? APLIC_ENABLE_ITHRESHOLD : APLIC_DISABLE_ITHRESHOLD;
> +
> +	/* Priority must be less than threshold for interrupt triggering */
> +	writel(th, idc->regs + APLIC_IDC_ITHRESHOLD);
> +
> +	/* Delivery must be set to 1 for interrupt triggering */
> +	writel(de, idc->regs + APLIC_IDC_IDELIVERY);
> +}
> +
> +static int aplic_direct_dying_cpu(unsigned int cpu)
> +{
> +	if (aplic_direct_parent_irq)
> +		disable_percpu_irq(aplic_direct_parent_irq);
> +
> +	return 0;
> +}
> +
> +static int aplic_direct_starting_cpu(unsigned int cpu)
> +{
> +	if (aplic_direct_parent_irq)
> +		enable_percpu_irq(aplic_direct_parent_irq,
> +				irq_get_trigger_type(aplic_direct_parent_irq));
> +
> +	return 0;
> +}
> +
> +static int aplic_direct_parse_parent_hwirq(struct device *dev,
> +					   u32 index, u32 *parent_hwirq,
> +					   unsigned long *parent_hartid)
> +{
> +	struct of_phandle_args parent;
> +	int rc;
> +
> +	/*
> +	 * Currently, only OF fwnode is supported so extend this
> +	 * function for ACPI support.
> +	 */
> +	if (!is_of_node(dev->fwnode))
> +		return -EINVAL;
> +
> +	rc = of_irq_parse_one(to_of_node(dev->fwnode), index, &parent);
> +	if (rc)
> +		return rc;
> +
> +	rc = riscv_of_parent_hartid(parent.np, parent_hartid);
> +	if (rc)
> +		return rc;
> +
> +	*parent_hwirq = parent.args[0];
> +	return 0;
> +}
> +
> +int aplic_direct_setup(struct device *dev, void __iomem *regs)
> +{
> +	int i, j, rc, cpu, setup_count = 0;
> +	struct aplic_direct *direct;
> +	struct aplic_priv *priv;
> +	struct irq_domain *domain;
> +	unsigned long hartid;
> +	struct aplic_idc *idc;
> +	u32 val, hwirq;
> +
> +	direct = kzalloc(sizeof(*direct), GFP_KERNEL);

Use devm_kzalloc() ?

> +	if (!direct)
> +		return -ENOMEM;
> +	priv = &direct->priv;
> +
> +	rc = aplic_setup_priv(priv, dev, regs);
> +	if (rc) {
> +		dev_err(dev, "failed to create APLIC context\n");
> +		kfree(direct);
> +		return rc;
> +	}
> +
> +	/* Setup per-CPU IDC and target CPU mask */
> +	for (i = 0; i < priv->nr_idcs; i++) {
> +		rc = aplic_direct_parse_parent_hwirq(dev, i, &hwirq, &hartid);
> +		if (rc) {
> +			dev_warn(dev, "parent irq for IDC%d not found\n", i);
> +			continue;
> +		}
> +
> +		/*
> +		 * Skip interrupts other than external interrupts for
> +		 * current privilege level.
> +		 */
> +		if (hwirq != RV_IRQ_EXT)
> +			continue;
> +
> +		cpu = riscv_hartid_to_cpuid(hartid);
> +		if (cpu < 0) {
> +			dev_warn(dev, "invalid cpuid for IDC%d\n", i);
> +			continue;
> +		}
> +
> +		cpumask_set_cpu(cpu, &direct->lmask);
> +
> +		idc = per_cpu_ptr(&aplic_idcs, cpu);
> +		idc->hart_index = i;
> +		idc->regs = priv->regs + APLIC_IDC_BASE + i * APLIC_IDC_SIZE;
> +		idc->direct = direct;
> +
> +		aplic_idc_set_delivery(idc, true);
> +
> +		/*
> +		 * Boot cpu might not have APLIC hart_index = 0 so check
> +		 * and update target registers of all interrupts.
> +		 */
> +		if (cpu == smp_processor_id() && idc->hart_index) {
> +			val = idc->hart_index & APLIC_TARGET_HART_IDX_MASK;
> +			val <<= APLIC_TARGET_HART_IDX_SHIFT;

Ditto (FIELD_PREP)

> +			val |= APLIC_DEFAULT_PRIORITY;
> +			for (j = 1; j <= priv->nr_irqs; j++)
> +				writel(val, priv->regs + APLIC_TARGET_BASE +
> +					    (j - 1) * sizeof(u32));
> +		}
> +
> +		setup_count++;
> +	}
> +
> +	/* Find parent domain and register chained handler */
> +	domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(),
> +					  DOMAIN_BUS_ANY);
> +	if (!aplic_direct_parent_irq && domain) {
> +		aplic_direct_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
> +		if (aplic_direct_parent_irq) {
> +			irq_set_chained_handler(aplic_direct_parent_irq,
> +						aplic_direct_handle_irq);
> +
> +			/*
> +			 * Setup CPUHP notifier to enable parent
> +			 * interrupt on all CPUs
> +			 */
> +			cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
> +					  "irqchip/riscv/aplic:starting",
> +					  aplic_direct_starting_cpu,
> +					  aplic_direct_dying_cpu);
> +		}
> +	}
> +
> +	/* Fail if we were not able to setup IDC for any CPU */
> +	if (!setup_count) {
> +		kfree(direct);

Shouldn't the cpuhp state also be destroyed (cpuhp_remove_state()) ?

> +		return -ENODEV;
> +	}
> +
> +	/* Setup global config and interrupt delivery */
> +	aplic_init_hw_global(priv, false);
> +
> +	/* Create irq domain instance for the APLIC */
> +	direct->irqdomain = irq_domain_create_linear(dev->fwnode,
> +						   priv->nr_irqs + 1,
> +						   &aplic_direct_irqdomain_ops,
> +						   priv);
> +	if (!direct->irqdomain) {
> +		dev_err(dev, "failed to create direct irq domain\n");
> +		kfree(direct);
> +		return -ENOMEM;
> +	}
> +
> +	/* Advertise the interrupt controller */
> +	dev_info(dev, "%d interrupts directly connected to %d CPUs\n",
> +		 priv->nr_irqs, priv->nr_idcs);
> +
> +	return 0;
> +}
> diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
> new file mode 100644
> index 000000000000..87450708a733
> --- /dev/null
> +++ b/drivers/irqchip/irq-riscv-aplic-main.c
> @@ -0,0 +1,232 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> + * Copyright (C) 2022 Ventana Micro Systems Inc.

2024 ?

> + */
> +
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/printk.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/irqchip/riscv-aplic.h>
> +
> +#include "irq-riscv-aplic-main.h"
> +
> +void aplic_irq_unmask(struct irq_data *d)
> +{
> +	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> +
> +	writel(d->hwirq, priv->regs + APLIC_SETIENUM);
> +}
> +
> +void aplic_irq_mask(struct irq_data *d)
> +{
> +	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> +
> +	writel(d->hwirq, priv->regs + APLIC_CLRIENUM);
> +}
> +
> +int aplic_irq_set_type(struct irq_data *d, unsigned int type)
> +{
> +	u32 val = 0;
> +	void __iomem *sourcecfg;
> +	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> +
> +	switch (type) {
> +	case IRQ_TYPE_NONE:
> +		val = APLIC_SOURCECFG_SM_INACTIVE;
> +		break;
> +	case IRQ_TYPE_LEVEL_LOW:
> +		val = APLIC_SOURCECFG_SM_LEVEL_LOW;
> +		break;
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		val = APLIC_SOURCECFG_SM_LEVEL_HIGH;
> +		break;
> +	case IRQ_TYPE_EDGE_FALLING:
> +		val = APLIC_SOURCECFG_SM_EDGE_FALL;
> +		break;
> +	case IRQ_TYPE_EDGE_RISING:
> +		val = APLIC_SOURCECFG_SM_EDGE_RISE;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	sourcecfg = priv->regs + APLIC_SOURCECFG_BASE;
> +	sourcecfg += (d->hwirq - 1) * sizeof(u32);
> +	writel(val, sourcecfg);
> +
> +	return 0;
> +}
> +
> +int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
> +			      unsigned long *hwirq, unsigned int *type)
> +{
> +	if (WARN_ON(fwspec->param_count < 2))
> +		return -EINVAL;
> +	if (WARN_ON(!fwspec->param[0]))
> +		return -EINVAL;
> +
> +	/* For DT, gsi_base is always zero. */
> +	*hwirq = fwspec->param[0] - gsi_base;
> +	*type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
> +
> +	WARN_ON(*type == IRQ_TYPE_NONE);
> +
> +	return 0;
> +}
> +
> +void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
> +{
> +	u32 val;
> +#ifdef CONFIG_RISCV_M_MODE
> +	u32 valH;
> +
> +	if (msi_mode) {
> +		val = priv->msicfg.base_ppn;
> +		valH = ((u64)priv->msicfg.base_ppn >> 32) &
> +			APLIC_xMSICFGADDRH_BAPPN_MASK;
> +		valH |= (priv->msicfg.lhxw & APLIC_xMSICFGADDRH_LHXW_MASK)
> +			<< APLIC_xMSICFGADDRH_LHXW_SHIFT;
> +		valH |= (priv->msicfg.hhxw & APLIC_xMSICFGADDRH_HHXW_MASK)
> +			<< APLIC_xMSICFGADDRH_HHXW_SHIFT;
> +		valH |= (priv->msicfg.lhxs & APLIC_xMSICFGADDRH_LHXS_MASK)
> +			<< APLIC_xMSICFGADDRH_LHXS_SHIFT;
> +		valH |= (priv->msicfg.hhxs & APLIC_xMSICFGADDRH_HHXS_MASK)
> +			<< APLIC_xMSICFGADDRH_HHXS_SHIFT;

Use FIELD_PREP for all of these.

> +		writel(val, priv->regs + APLIC_xMSICFGADDR);
> +		writel(valH, priv->regs + APLIC_xMSICFGADDRH);
> +	}
> +#endif
> +
> +	/* Setup APLIC domaincfg register */
> +	val = readl(priv->regs + APLIC_DOMAINCFG);
> +	val |= APLIC_DOMAINCFG_IE;
> +	if (msi_mode)
> +		val |= APLIC_DOMAINCFG_DM;
> +	writel(val, priv->regs + APLIC_DOMAINCFG);
> +	if (readl(priv->regs + APLIC_DOMAINCFG) != val)
> +		dev_warn(priv->dev, "unable to write 0x%x in domaincfg\n",
> +			 val);
> +}
> +
> +static void aplic_init_hw_irqs(struct aplic_priv *priv)
> +{
> +	int i;
> +
> +	/* Disable all interrupts */
> +	for (i = 0; i <= priv->nr_irqs; i += 32)
> +		writel(-1U, priv->regs + APLIC_CLRIE_BASE +
> +			    (i / 32) * sizeof(u32));
> +
> +	/* Set interrupt type and default priority for all interrupts */
> +	for (i = 1; i <= priv->nr_irqs; i++) {
> +		writel(0, priv->regs + APLIC_SOURCECFG_BASE +
> +			  (i - 1) * sizeof(u32));
> +		writel(APLIC_DEFAULT_PRIORITY,
> +		       priv->regs + APLIC_TARGET_BASE +
> +		       (i - 1) * sizeof(u32));
> +	}
> +
> +	/* Clear APLIC domaincfg */
> +	writel(0, priv->regs + APLIC_DOMAINCFG);
> +}
> +
> +int aplic_setup_priv(struct aplic_priv *priv, struct device *dev,
> +		     void __iomem *regs)
> +{
> +	struct of_phandle_args parent;
> +	int rc;
> +
> +	/*
> +	 * Currently, only OF fwnode is supported so extend this
> +	 * function for ACPI support.
> +	 */
> +	if (!is_of_node(dev->fwnode))
> +		return -EINVAL;
> +
> +	/* Save device pointer and register base */
> +	priv->dev = dev;
> +	priv->regs = regs;
> +
> +	/* Find out number of interrupt sources */
> +	rc = of_property_read_u32(to_of_node(dev->fwnode),
> +					     "riscv,num-sources",
> +					     &priv->nr_irqs);

Use device_property_read_u32() which works for both ACPI and OF.

> +	if (rc) {
> +		dev_err(dev, "failed to get number of interrupt sources\n");
> +		return rc;
> +	}
> +
> +	/*
> +	 * Find out number of IDCs based on parent interrupts
> +	 *
> +	 * If "msi-parent" property is present then we ignore the
> +	 * APLIC IDCs which forces the APLIC driver to use MSI mode.
> +	 */
> +	if (!of_property_present(to_of_node(dev->fwnode), "msi-parent")) {

device_property_present()

> +		while (!of_irq_parse_one(to_of_node(dev->fwnode),
> +					 priv->nr_idcs, &parent))
> +			priv->nr_idcs++;
> +	}
> +
> +	/* Setup initial state APLIC interrupts */
> +	aplic_init_hw_irqs(priv);
> +
> +	return 0;
> +}
> +
> +static int aplic_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	bool msi_mode = false;
> +	struct resource *res;
> +	void __iomem *regs;
> +	int rc;
> +
> +	/* Map the MMIO registers */
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(dev, "failed to get MMIO resource\n");
> +		return -EINVAL;
> +	}
> +	regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
> +	if (!regs) {
> +		dev_err(dev, "failed map MMIO registers\n");
> +		return -ENOMEM;
> +	}

Maybe use devm_platform_ioremap_resource() since you don't need "res"
after that.


> +
> +	/*
> +	 * If msi-parent property is present then setup APLIC MSI
> +	 * mode otherwise setup APLIC direct mode.
> +	 */
> +	if (is_of_node(dev->fwnode))
> +		msi_mode = of_property_present(to_of_node(dev->fwnode),
> +						"msi-parent");
> +	if (msi_mode)
> +		rc = -ENODEV;
> +	else
> +		rc = aplic_direct_setup(dev, regs);
> +	if (rc) {
> +		dev_err(dev, "failed setup APLIC in %s mode\n",
nitpick: maybe reword it like "Failed to setup APLIC" or "APLIC setup
failed in %s mode"

> +			msi_mode ? "MSI" : "direct");
> +		return rc;

Remove this return.

> +	}
> +
> +	return 0;

return rc;

> +}
> +
> +static const struct of_device_id aplic_match[] = {
> +	{ .compatible = "riscv,aplic" },
> +	{}
> +};
> +
> +static struct platform_driver aplic_driver = {
> +	.driver = {
> +		.name		= "riscv-aplic",
> +		.of_match_table	= aplic_match,
> +	},
> +	.probe = aplic_probe,
> +};
> +builtin_platform_driver(aplic_driver);
> diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h
> new file mode 100644
> index 000000000000..474a04229334
> --- /dev/null
> +++ b/drivers/irqchip/irq-riscv-aplic-main.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> + * Copyright (C) 2022 Ventana Micro Systems Inc.

2024 ?

> + */
> +
> +#ifndef _IRQ_RISCV_APLIC_MAIN_H
> +#define _IRQ_RISCV_APLIC_MAIN_H
> +
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/fwnode.h>
> +
> +#define APLIC_DEFAULT_PRIORITY		1
> +
> +struct aplic_msicfg {
> +	phys_addr_t		base_ppn;
> +	u32			hhxs;
> +	u32			hhxw;
> +	u32			lhxs;
> +	u32			lhxw;
> +};
> +
> +struct aplic_priv {
> +	struct device		*dev;
> +	u32			gsi_base;
> +	u32			nr_irqs;
> +	u32			nr_idcs;
> +	void __iomem		*regs;
> +	struct aplic_msicfg	msicfg;
> +};
> +
> +void aplic_irq_unmask(struct irq_data *d);
> +void aplic_irq_mask(struct irq_data *d);
> +int aplic_irq_set_type(struct irq_data *d, unsigned int type);
> +int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
> +			      unsigned long *hwirq, unsigned int *type);
> +void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode);
> +int aplic_setup_priv(struct aplic_priv *priv, struct device *dev,
> +		     void __iomem *regs);
> +int aplic_direct_setup(struct device *dev, void __iomem *regs);
> +
> +#endif
> diff --git a/include/linux/irqchip/riscv-aplic.h b/include/linux/irqchip/riscv-aplic.h
> new file mode 100644
> index 000000000000..97e198ea0109
> --- /dev/null
> +++ b/include/linux/irqchip/riscv-aplic.h
> @@ -0,0 +1,119 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> + * Copyright (C) 2022 Ventana Micro Systems Inc.
> + */
> +#ifndef __LINUX_IRQCHIP_RISCV_APLIC_H
> +#define __LINUX_IRQCHIP_RISCV_APLIC_H
> +
> +#include <linux/bitops.h>
> +
> +#define APLIC_MAX_IDC			BIT(14)
> +#define APLIC_MAX_SOURCE		1024
> +
> +#define APLIC_DOMAINCFG			0x0000
> +#define APLIC_DOMAINCFG_RDONLY		0x80000000
> +#define APLIC_DOMAINCFG_IE		BIT(8)
> +#define APLIC_DOMAINCFG_DM		BIT(2)
> +#define APLIC_DOMAINCFG_BE		BIT(0)
> +
> +#define APLIC_SOURCECFG_BASE		0x0004
> +#define APLIC_SOURCECFG_D		BIT(10)
> +#define APLIC_SOURCECFG_CHILDIDX_MASK	0x000003ff
> +#define APLIC_SOURCECFG_SM_MASK	0x00000007
> +#define APLIC_SOURCECFG_SM_INACTIVE	0x0
> +#define APLIC_SOURCECFG_SM_DETACH	0x1
> +#define APLIC_SOURCECFG_SM_EDGE_RISE	0x4
> +#define APLIC_SOURCECFG_SM_EDGE_FALL	0x5
> +#define APLIC_SOURCECFG_SM_LEVEL_HIGH	0x6
> +#define APLIC_SOURCECFG_SM_LEVEL_LOW	0x7
> +
> +#define APLIC_MMSICFGADDR		0x1bc0
> +#define APLIC_MMSICFGADDRH		0x1bc4
> +#define APLIC_SMSICFGADDR		0x1bc8
> +#define APLIC_SMSICFGADDRH		0x1bcc
> +
> +#ifdef CONFIG_RISCV_M_MODE
> +#define APLIC_xMSICFGADDR		APLIC_MMSICFGADDR
> +#define APLIC_xMSICFGADDRH		APLIC_MMSICFGADDRH
> +#else
> +#define APLIC_xMSICFGADDR		APLIC_SMSICFGADDR
> +#define APLIC_xMSICFGADDRH		APLIC_SMSICFGADDRH
> +#endif
> +
> +#define APLIC_xMSICFGADDRH_L		BIT(31)
> +#define APLIC_xMSICFGADDRH_HHXS_MASK	0x1f
> +#define APLIC_xMSICFGADDRH_HHXS_SHIFT	24
> +#define APLIC_xMSICFGADDRH_LHXS_MASK	0x7
> +#define APLIC_xMSICFGADDRH_LHXS_SHIFT	20
> +#define APLIC_xMSICFGADDRH_HHXW_MASK	0x7
> +#define APLIC_xMSICFGADDRH_HHXW_SHIFT	16
> +#define APLIC_xMSICFGADDRH_LHXW_MASK	0xf
> +#define APLIC_xMSICFGADDRH_LHXW_SHIFT	12
> +#define APLIC_xMSICFGADDRH_BAPPN_MASK	0xfff
> +
> +#define APLIC_xMSICFGADDR_PPN_SHIFT	12
> +
> +#define APLIC_xMSICFGADDR_PPN_HART(__lhxs) \
> +	(BIT(__lhxs) - 1)
> +
> +#define APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) \
> +	(BIT(__lhxw) - 1)
> +#define APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs) \
> +	((__lhxs))
> +#define APLIC_xMSICFGADDR_PPN_LHX(__lhxw, __lhxs) \
> +	(APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) << \
> +	 APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs))
> +
> +#define APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) \
> +	(BIT(__hhxw) - 1)
> +#define APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs) \
> +	((__hhxs) + APLIC_xMSICFGADDR_PPN_SHIFT)
> +#define APLIC_xMSICFGADDR_PPN_HHX(__hhxw, __hhxs) \
> +	(APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) << \
> +	 APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs))
> +
> +#define APLIC_IRQBITS_PER_REG		32
> +
> +#define APLIC_SETIP_BASE		0x1c00
> +#define APLIC_SETIPNUM			0x1cdc
> +
> +#define APLIC_CLRIP_BASE		0x1d00
> +#define APLIC_CLRIPNUM			0x1ddc
> +
> +#define APLIC_SETIE_BASE		0x1e00
> +#define APLIC_SETIENUM			0x1edc
> +
> +#define APLIC_CLRIE_BASE		0x1f00
> +#define APLIC_CLRIENUM			0x1fdc
> +
> +#define APLIC_SETIPNUM_LE		0x2000
> +#define APLIC_SETIPNUM_BE		0x2004
> +
> +#define APLIC_GENMSI			0x3000
> +
> +#define APLIC_TARGET_BASE		0x3004
> +#define APLIC_TARGET_HART_IDX_SHIFT	18
> +#define APLIC_TARGET_HART_IDX_MASK	0x3fff
> +#define APLIC_TARGET_GUEST_IDX_SHIFT	12
> +#define APLIC_TARGET_GUEST_IDX_MASK	0x3f
> +#define APLIC_TARGET_IPRIO_MASK	0xff
> +#define APLIC_TARGET_EIID_MASK	0x7ff
> +
> +#define APLIC_IDC_BASE			0x4000
> +#define APLIC_IDC_SIZE			32
> +
> +#define APLIC_IDC_IDELIVERY		0x00
> +
> +#define APLIC_IDC_IFORCE		0x04
> +
> +#define APLIC_IDC_ITHRESHOLD		0x08
> +
> +#define APLIC_IDC_TOPI			0x18
> +#define APLIC_IDC_TOPI_ID_SHIFT	16
> +#define APLIC_IDC_TOPI_ID_MASK	0x3ff
> +#define APLIC_IDC_TOPI_PRIO_MASK	0xff
> +
> +#define APLIC_IDC_CLAIMI		0x1c
> +
> +#endif


Thanks,

Cl?ment


From quic_taozha at quicinc.com  Fri Feb  2 01:32:35 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:35 +0800
Subject: [PATCH v6 01/10] coresight-tpdm: Optimize the store function of tpdm simple dataset
In-Reply-To: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1706866364-19861-2-git-send-email-quic_taozha@quicinc.com>

Replace spin lock/unlock to avoid forgetting to unlock when the
function exits. And refine methods for handling various conditions.

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpdm.c | 39 ++++++++++----------
 1 file changed, 19 insertions(+), 20 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index bd13a548375c..0427c0fc0bf3 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -77,51 +77,50 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
 					 size_t size)
 {
 	unsigned long val;
-	ssize_t ret = size;
+	ssize_t ret = -EINVAL;
 
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct tpdm_dataset_attribute *tpdm_attr =
 		container_of(attr, struct tpdm_dataset_attribute, attr);
 
 	if (kstrtoul(buf, 0, &val))
-		return -EINVAL;
+		return ret;
 
-	spin_lock(&drvdata->spinlock);
+	guard(spinlock)(&drvdata->spinlock);
 	switch (tpdm_attr->mem) {
 	case DSB_TRIG_PATT:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_TRIG_PATT_MASK:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_PATT:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->patt_val[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_PATT_MASK:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->patt_mask[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_MSR:
-		if (tpdm_attr->idx < drvdata->dsb_msr_num)
+		if (tpdm_attr->idx < drvdata->dsb_msr_num) {
 			drvdata->dsb->msr[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	default:
-		ret = -EINVAL;
+		break;
 	}
-	spin_unlock(&drvdata->spinlock);
 
 	return ret;
 }
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Feb  2 01:32:34 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:34 +0800
Subject: [PATCH v6 00/10] Add support to configure TPDM CMB subunit
Message-ID: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>

Introduction of TPDM CMB(Continuous Multi Bit) subunit
CMB subunit is responsible for creating a dataset element, and is also
optionally responsible for packing it to fit multiple elements on a
single ATB transfer if possible in the configuration. The TPDM Core
Datapath requests timestamps be stored by the TPDA and then delivering
ATB sized data (depending on ATB width and element size, this could
be smaller or larger than a dataset element) to the ATB Mast FSM.
The CMB makes trace elements in two modes. In ?continuous? mode, every
valid data cycle creates an element. In ?trace on change? mode, when
valid data changes on the bus, a trace element is created. In
continuous mode, all cycles where this condition is true create trace
elements. In trace on change mode, a data element is only when the
previously sampled input is different from the current sampled input.

The CMB subunit must be configured prior to enablement. This series
adds support for TPDM to configure the configure CMB subunit.

Once this series patches are applied properly, the new tpdm nodes for
should be observed at the tpdm path /sys/bus/coresight/devices/tpdm*
which supports CMB subunit.
e.g.
root at qemuarm64:/sys/devices/platform/soc at 0/684c000.tpdm/tpdm0# ls -l
-rw-r--r--    1 root     root          4096 Jan  1 00:00 cmb_mode
drwxr-xr-x    2 root     root             0 Jan  1 00:00 cmb_msr
drwxr-xr-x    2 root     root             0 Jan  1 00:00 cmb_patt
drwxr-xr-x    2 root     root             0 Jan  1 00:00 cmb_trig_patt
-rw-r--r--    1 root     root          4096 Jan  1 00:00 cmb_trig_ts
-rw-r--r--    1 root     root          4096 Jan  1 00:00 cmb_ts_all
drwxr-xr-x    2 root     root             0 Jan  1 00:00 connections
drwxr-xr-x    2 root     root             0 Jan  1 00:00 dsb_edge
drwxr-xr-x    2 root     root             0 Jan  1 00:00 dsb_msr
drwxr-xr-x    2 root     root             0 Jan  1 00:00 dsb_patt
drwxr-xr-x    2 root     root             0 Jan  1 00:00 dsb_trig_patt
-rw-r--r--    1 root     root          4096 Jan  1 00:00 enable_source
--w-------    1 root     root          4096 Jan  1 00:00 integration_test
drwxr-xr-x    2 root     root             0 Ja?  1 00:00 power
--w-------    1 root     root          4096 Jan  1 00:00 reset_dataset
lrwxrwxrwx    1 root     root             0 Apr  5  2021 subsystem -> ../../../../../bus/coresight
-rw-r--r--    1 root     root          4096 Apr  5  2021 uevent
-r--r--r--    1 root     root          4096 Jan  1 00:00 waiting_for_supplier

We can use the commands are similar to the below to configure the
TPDMs which support CMB subunit. Enable coresight sink first.
echo 1 > /sys/bus/coresight/devices/tmc_etf0/enable_sink
echo 1 > /sys/bus/coresight/devices/tpdm0/reset_dataset
echo 1 > /sys/bus/coresight/devices/tpdm0/cmb_mode
echo 1 > /sys/bus/coresight/devices/tpdm0/cmb_patt/enable_ts
echo 0xFFFFFFFF > /sys/bus/coresight/devices/tpdm0/cmb_patt/tpmr0
echo 0 > /sys/bus/coresight/devices/tpdm0/cmb_trig_ts
echo 0xFFFFFFFF > /sys/bus/coresight/devices/tpdm0/cmb_trig_patt/xpr1
echo 1 > /sys/bus/coresight/devices/tpdm0/enable_source

codelinaro link:
https://git.codelinaro.org/clo/linux-kernel/coresight/-/commits/tpdm-cmb-v6

Changes in V6:
1. Clear all the relevant fields before setting them in the function
"tpda_set_element_size". In patch#5.
-- Suzuki K Poulose

2. Leave a space after/before '/*' & '*/'. In patch#7 #8.
-- Suzuki K Poulose

Changes in V5:
1. Return directly to refine the process of "tpdm_enable_dsb" and
"tpdm_disable_dsb" if the TPDM does not support DSB dataset.
-- Suzuki K Poulose
2. Change the new property name from "qcom,cmb-element-size" to
"qcom,cmb-element-bits". And update the property name to the new
tpdm example which supports the CMB dataset.
-- Krzysztof
3. Drop unnecessary () around the drvdata member access in patch#5.
-- Suzuki K Poulose
4. Replace the error code "-EEXIST" with the port number in detecting
multiple TPDMs on one input port. In patch#5.
-- Suzuki K Poulose
5. Due to the modification of the new property name, the searched
property name was changed from "qcom,cmb-element-size" to
"qcom,cmb-element-bits". In patch#5.
6. Replace the judgement "tpdm_has_cmb_dataset(drvdata)" with
"drvdata->cmb" in the function "tpdm_reset_datasets". In patch#6.
-- Suzuki K Poulose
7. Drop unnecessary () around kstrtoul() in the function
"cmb_mode_store". In patch#6.
-- Suzuki K Poulose
8. Update the date and the kernel version in the Document.
-- Suzuki K Poulose
9. Initialize the return value to "-EINVAL" and remove the unnecessary
code in the function "enable_ts_show". In patch#8.
-- Suzuki K Poulose
10. Replace spin lock/unlock with guard(spinlock). In patch#8.
-- Suzuki K Poulose
11. Drop _rw from the macro "tpdm_patt_enable_ts_rw". In patch#8.
-- Suzuki K Poulose

Changes in V4:
1. Replace spin lock/unlock to avoid forgetting to unlock when the
function exits.
-- Suzuki K Poulose
2. Move the helper "tpdm_has_dsb_dataset" to the header file.
-- Suzuki K Poulose
3. Fix the incorrect property of the sample in the documents.
-- James Clark
4. Clear the dsb/cmb element size directly in the clear helper.
-- Suzuki K Poulose
5. Correct the comment of "tpdm_read_element_size".
-- Suzuki K Poulose
6. Call the helper "tpdm_has_dsb/cmb_dataset" in TPDA driver to
check what dataset the TPDM supports.
-- Suzuki K Poulose
7. Refine the dsb/cmb dataset support check in enable/disable functions.
-- Suzuki K Poulose
8. Get rid of redundant code in function "set_cmb_tier".
-- Suzuki K Poulose
9. Since one SysFs file should follow "one value", use "dev_ext_attribute"
to instead of the previous "enable_ts" Sysfs file approach.
-- Suzuki K Poulose
10. Change the kernel version to 6.9 for the MSR related SysFs file.
-- James Clark
11. Refine the function "tpdm_simple_dataset_store".
-- Suzuki K Poulose

Changes in V3:
1. Add 8-bit support to the description in the TPDM devicetree document.
-- Rob Herring
2. Change how the result is produced in "tpdm_read_element_size".
-- James Clark
3. Calling "tpdm_clear_element_size" at the beginning of
"tpda_enable_port".
-- James Clark
4. Use "dsb_esize" and "cmb_esize" to determine whether multiple TPDMs
are detected on a TPDA input port in "tpda_get_element_size".
-- James Clark
5. Modify the judgment logic in "tpda_enable_port".
-- James Clark
6. Add more description of "cmb_mode" to TPDM SysFS document.
-- James Clark

Changes in V2:
1. Optimizate and modify this patch series based on the patch series
"Add support to configure TPDM CMB subunit".
2. Modify the functions that read the element size of DSB/CMB in TPDA driver.

Tao Zhang (10):
  coresight-tpdm: Optimize the store function of tpdm simple dataset
  coresight-tpdm: Optimize the useage of tpdm_has_dsb_dataset
  dt-bindings: arm: qcom,coresight-tpdm: Add support for CMB element
    size
  coresight-tpdm: Add CMB dataset support
  coresight-tpda: Add support to configure CMB element
  coresight-tpdm: Add support to configure CMB
  coresight-tpdm: Add pattern registers support for CMB
  coresight-tpdm: Add timestamp control register support for the CMB
  dt-bindings: arm: qcom,coresight-tpdm: Add support for TPDM CMB MSR
    register
  coresight-tpdm: Add msr register support for CMB

 .../testing/sysfs-bus-coresight-devices-tpdm  |  87 ++++
 .../bindings/arm/qcom,coresight-tpdm.yaml     |  35 ++
 drivers/hwtracing/coresight/coresight-tpda.c  | 125 +++--
 drivers/hwtracing/coresight/coresight-tpda.h  |   6 +
 drivers/hwtracing/coresight/coresight-tpdm.c  | 455 ++++++++++++++++--
 drivers/hwtracing/coresight/coresight-tpdm.h  | 113 +++++
 6 files changed, 729 insertions(+), 92 deletions(-)

-- 
2.17.1



From quic_taozha at quicinc.com  Fri Feb  2 01:32:36 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:36 +0800
Subject: [PATCH v6 02/10] coresight-tpdm: Optimize the useage of tpdm_has_dsb_dataset
In-Reply-To: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1706866364-19861-3-git-send-email-quic_taozha@quicinc.com>

Since the function tpdm_has_dsb_dataset will be called by TPDA
driver in subsequent patches, it is moved to the header file.
And move this judgement form the function __tpdm_{enable/disable}
to the beginning of the function tpdm_{enable/disable}_dsb.

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpdm.c | 30 +++++++++-----------
 drivers/hwtracing/coresight/coresight-tpdm.h |  4 +++
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 0427c0fc0bf3..4b1296d11360 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -125,11 +125,6 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
 	return ret;
 }
 
-static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
-{
-	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
-}
-
 static umode_t tpdm_dsb_is_visible(struct kobject *kobj,
 				   struct attribute *attr, int n)
 {
@@ -232,25 +227,27 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
 {
 	u32 val, i;
 
+	if (!tpdm_has_dsb_dataset(drvdata))
+		return;
+
 	for (i = 0; i < TPDM_DSB_MAX_EDCR; i++)
 		writel_relaxed(drvdata->dsb->edge_ctrl[i],
-			   drvdata->base + TPDM_DSB_EDCR(i));
+			       drvdata->base + TPDM_DSB_EDCR(i));
 	for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++)
 		writel_relaxed(drvdata->dsb->edge_ctrl_mask[i],
-			   drvdata->base + TPDM_DSB_EDCMR(i));
+			       drvdata->base + TPDM_DSB_EDCMR(i));
 	for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
 		writel_relaxed(drvdata->dsb->patt_val[i],
-			   drvdata->base + TPDM_DSB_TPR(i));
+			       drvdata->base + TPDM_DSB_TPR(i));
 		writel_relaxed(drvdata->dsb->patt_mask[i],
-			   drvdata->base + TPDM_DSB_TPMR(i));
+			       drvdata->base + TPDM_DSB_TPMR(i));
 		writel_relaxed(drvdata->dsb->trig_patt[i],
-			   drvdata->base + TPDM_DSB_XPR(i));
+			       drvdata->base + TPDM_DSB_XPR(i));
 		writel_relaxed(drvdata->dsb->trig_patt_mask[i],
-			   drvdata->base + TPDM_DSB_XPMR(i));
+			       drvdata->base + TPDM_DSB_XPMR(i));
 	}
 
 	set_dsb_tier(drvdata);
-
 	set_dsb_msr(drvdata);
 
 	val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
@@ -278,8 +275,7 @@ static void __tpdm_enable(struct tpdm_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
-	if (tpdm_has_dsb_dataset(drvdata))
-		tpdm_enable_dsb(drvdata);
+	tpdm_enable_dsb(drvdata);
 
 	CS_LOCK(drvdata->base);
 }
@@ -307,6 +303,9 @@ static void tpdm_disable_dsb(struct tpdm_drvdata *drvdata)
 {
 	u32 val;
 
+	if (!tpdm_has_dsb_dataset(drvdata))
+		return;
+
 	/* Set the enable bit of DSB control register to 0 */
 	val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
 	val &= ~TPDM_DSB_CR_ENA;
@@ -318,8 +317,7 @@ static void __tpdm_disable(struct tpdm_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
-	if (tpdm_has_dsb_dataset(drvdata))
-		tpdm_disable_dsb(drvdata);
+	tpdm_disable_dsb(drvdata);
 
 	CS_LOCK(drvdata->base);
 }
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index 4115b2a17b8d..ddaf333fa1c2 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -220,4 +220,8 @@ struct tpdm_dataset_attribute {
 	u32 idx;
 };
 
+static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
+{
+	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
+}
 #endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Feb  2 01:32:37 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:37 +0800
Subject: [PATCH v6 03/10] dt-bindings: arm: qcom,coresight-tpdm: Add support for CMB element size
In-Reply-To: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1706866364-19861-4-git-send-email-quic_taozha@quicinc.com>

Add property "qcom,cmb-elem-bits" to support CMB(Continuous
Multi-Bit) element for TPDM. The associated aggregator will read
this size before it is enabled. CMB element size currently only
supports 8-bit, 32-bit and 64-bit. Because the existing example
tpdm "tpdm at 684c000" which only supports dsb sub-unit, I introduce
a new example "tpdm at 6c29000" to describe the usage of this new
property.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../bindings/arm/qcom,coresight-tpdm.yaml     | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
index 61ddc3b5b247..2320b5445900 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
@@ -52,6 +52,14 @@ properties:
     $ref: /schemas/types.yaml#/definitions/uint8
     enum: [32, 64]
 
+  qcom,cmb-element-bits:
+    description:
+      Specifies the CMB(Continuous Multi-Bit) element size supported by
+      the monitor. The associated aggregator will read this size before it
+      is enabled. CMB element size currently only supports 8-bit, 32-bit
+      and 64-bit.
+    enum: [8, 32, 64]
+
   qcom,dsb-msrs-num:
     description:
       Specifies the number of DSB(Discrete Single Bit) MSR(mux select register)
@@ -110,4 +118,21 @@ examples:
       };
     };
 
+    tpdm at 6c29000 {
+      compatible = "qcom,coresight-tpdm", "arm,primecell";
+      reg = <0x06c29000 0x1000>;
+
+      qcom,cmb-element-bits = <64>;
+
+      clocks = <&aoss_qmp>;
+      clock-names = "apb_pclk";
+
+      out-ports {
+        port {
+          tpdm_ipcc_out_funnel_center: endpoint {
+            remote-endpoint = <&funnel_center_in_tpdm_ipcc>;
+          };
+        };
+      };
+    };
 ...
-- 
2.17.1



From linux at armlinux.org.uk  Fri Feb  2 01:33:20 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 2 Feb 2024 09:33:20 +0000
Subject: [PATCH net-next 0/6] net: eee network driver cleanups
Message-ID: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>

Hi,

Since commit d1420bb99515 ("net: phy: improve generic EEE ethtool
functions") changed phylib to set eee->eee_active and eee->eee_enabled,
overriding anything that drivers have set these to prior to calling
phy_ethtool_get_eee().

Therefore, drivers setting these members becomes redundant, since
phylib overwrites the values they set. This series finishes off
Heiner's work in the referenced commit by removing these redundant
writes in various drivers and any associated code or structure members
that become unnecessary.

 drivers/net/dsa/b53/b53_common.c                     | 6 ------
 drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c  | 4 ----
 drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c     | 5 +++--
 drivers/net/ethernet/broadcom/genet/bcmgenet.c       | 8 +++-----
 drivers/net/ethernet/broadcom/genet/bcmmii.c         | 5 +++--
 drivers/net/ethernet/freescale/fec_main.c            | 3 ---
 drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h    | 1 -
 drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c   | 2 --
 drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c      | 1 -
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 --
 10 files changed, 9 insertions(+), 28 deletions(-)

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


From quic_taozha at quicinc.com  Fri Feb  2 01:32:38 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:38 +0800
Subject: [PATCH v6 04/10] coresight-tpdm: Add CMB dataset support
In-Reply-To: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1706866364-19861-5-git-send-email-quic_taozha@quicinc.com>

CMB (continuous multi-bit) is one of TPDM's dataset type. CMB subunit
can be enabled for data collection by writing 1 to the first bit of
CMB_CR register. This change is to add enable/disable function for
CMB dataset by writing CMB_CR register.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Jinlong Mao <quic_jinlmao at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpdm.c | 28 ++++++++++++++++++++
 drivers/hwtracing/coresight/coresight-tpdm.h | 13 +++++++++
 2 files changed, 41 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 4b1296d11360..1bb1d8e83501 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -263,6 +263,19 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
 	writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
 }
 
+static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
+{
+	u32 val;
+
+	if (!tpdm_has_cmb_dataset(drvdata))
+		return;
+
+	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
+	/* Set the enable bit of CMB control register to 1 */
+	val |= TPDM_CMB_CR_ENA;
+	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
+}
+
 /*
  * TPDM enable operations
  * The TPDM or Monitor serves as data collection component for various
@@ -276,6 +289,7 @@ static void __tpdm_enable(struct tpdm_drvdata *drvdata)
 	CS_UNLOCK(drvdata->base);
 
 	tpdm_enable_dsb(drvdata);
+	tpdm_enable_cmb(drvdata);
 
 	CS_LOCK(drvdata->base);
 }
@@ -312,12 +326,26 @@ static void tpdm_disable_dsb(struct tpdm_drvdata *drvdata)
 	writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
 }
 
+static void tpdm_disable_cmb(struct tpdm_drvdata *drvdata)
+{
+	u32 val;
+
+	if (!tpdm_has_cmb_dataset(drvdata))
+		return;
+
+	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
+	/* Set the enable bit of CMB control register to 0 */
+	val &= ~TPDM_CMB_CR_ENA;
+	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
+}
+
 /* TPDM disable operations */
 static void __tpdm_disable(struct tpdm_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
 	tpdm_disable_dsb(drvdata);
+	tpdm_disable_cmb(drvdata);
 
 	CS_LOCK(drvdata->base);
 }
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index ddaf333fa1c2..a442d9c6e4ac 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -9,6 +9,12 @@
 /* The max number of the datasets that TPDM supports */
 #define TPDM_DATASETS       7
 
+/* CMB Subunit Registers */
+#define TPDM_CMB_CR		(0xA00)
+
+/* Enable bit for CMB subunit */
+#define TPDM_CMB_CR_ENA		BIT(0)
+
 /* DSB Subunit Registers */
 #define TPDM_DSB_CR		(0x780)
 #define TPDM_DSB_TIER		(0x784)
@@ -79,10 +85,12 @@
  *
  * PERIPHIDR0[0] : Fix to 1 if ImplDef subunit present, else 0
  * PERIPHIDR0[1] : Fix to 1 if DSB subunit present, else 0
+ * PERIPHIDR0[2] : Fix to 1 if CMB subunit present, else 0
  */
 
 #define TPDM_PIDR0_DS_IMPDEF	BIT(0)
 #define TPDM_PIDR0_DS_DSB	BIT(1)
+#define TPDM_PIDR0_DS_CMB	BIT(2)
 
 #define TPDM_DSB_MAX_LINES	256
 /* MAX number of EDCR registers */
@@ -224,4 +232,9 @@ static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
 {
 	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
 }
+
+static bool tpdm_has_cmb_dataset(struct tpdm_drvdata *drvdata)
+{
+	return (drvdata->datasets & TPDM_PIDR0_DS_CMB);
+}
 #endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Feb  2 01:32:39 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:39 +0800
Subject: [PATCH v6 05/10] coresight-tpda: Add support to configure CMB element
In-Reply-To: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1706866364-19861-6-git-send-email-quic_taozha@quicinc.com>

Read the CMB element size from the device tree. Set the register
bit that controls the CMB element size of the corresponding port.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpda.c | 125 +++++++++++--------
 drivers/hwtracing/coresight/coresight-tpda.h |   6 +
 2 files changed, 81 insertions(+), 50 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 4ac954f4bc13..27d567f4c8bf 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -18,6 +18,7 @@
 #include "coresight-priv.h"
 #include "coresight-tpda.h"
 #include "coresight-trace-id.h"
+#include "coresight-tpdm.h"
 
 DEFINE_CORESIGHT_DEVLIST(tpda_devs, "tpda");
 
@@ -28,24 +29,59 @@ static bool coresight_device_is_tpdm(struct coresight_device *csdev)
 			CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
 }
 
+static void tpdm_clear_element_size(struct coresight_device *csdev)
+{
+	struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	drvdata->dsb_esize = 0;
+	drvdata->cmb_esize = 0;
+}
+
+static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 *val)
+{
+	/* Clear all relevant fields */
+	*val &= ~(TPDA_Pn_CR_DSBSIZE | TPDA_Pn_CR_CMBSIZE);
+
+	if (drvdata->dsb_esize == 64)
+		*val |= TPDA_Pn_CR_DSBSIZE;
+	else if (drvdata->dsb_esize == 32)
+		*val &= ~TPDA_Pn_CR_DSBSIZE;
+
+	if (drvdata->cmb_esize == 64)
+		*val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
+	else if (drvdata->cmb_esize == 32)
+		*val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
+	else if (drvdata->cmb_esize == 8)
+		*val &= ~TPDA_Pn_CR_CMBSIZE;
+}
+
 /*
- * Read the DSB element size from the TPDM device
+ * Read the element size from the TPDM device. One TPDM must have at least one of the
+ * element size property.
  * Returns
- *    The dsb element size read from the devicetree if available.
- *    0 - Otherwise, with a warning once.
+ *    0 - The element size property is read
+ *    Others - Cannot read the property of the element size
  */
-static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
+static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
+				  struct coresight_device *csdev)
 {
-	int rc = 0;
-	u8 size = 0;
+	int rc = -EINVAL;
+	struct tpdm_drvdata *tpdm_data = dev_get_drvdata(csdev->dev.parent);
+
+	if (tpdm_has_dsb_dataset(tpdm_data)) {
+		rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
+				"qcom,dsb-element-size", &drvdata->dsb_esize);
+	}
+	if (tpdm_has_cmb_dataset(tpdm_data)) {
+		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
+				"qcom,cmb-element-bits", &drvdata->cmb_esize);
+	}
 
-	rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
-			"qcom,dsb-element-size", &size);
 	if (rc)
 		dev_warn_once(&csdev->dev,
-			"Failed to read TPDM DSB Element size: %d\n", rc);
+			"Failed to read TPDM Element size: %d\n", rc);
 
-	return size;
+	return rc;
 }
 
 /*
@@ -56,11 +92,12 @@ static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
  * Parameter "inport" is used to pass in the input port number
  * of TPDA, and it is set to -1 in the recursize call.
  */
-static int tpda_get_element_size(struct coresight_device *csdev,
+static int tpda_get_element_size(struct tpda_drvdata *drvdata,
+				 struct coresight_device *csdev,
 				 int inport)
 {
-	int dsb_size = -ENOENT;
-	int i, size;
+	int rc = 0;
+	int i;
 	struct coresight_device *in;
 
 	for (i = 0; i < csdev->pdata->nr_inconns; i++) {
@@ -69,30 +106,26 @@ static int tpda_get_element_size(struct coresight_device *csdev,
 			continue;
 
 		/* Ignore the paths that do not match port */
-		if (inport > 0 &&
+		if (inport >= 0 &&
 		    csdev->pdata->in_conns[i]->dest_port != inport)
 			continue;
 
 		if (coresight_device_is_tpdm(in)) {
-			size = tpdm_read_dsb_element_size(in);
+			if (drvdata->dsb_esize || drvdata->cmb_esize)
+				return -EEXIST;
+			rc = tpdm_read_element_size(drvdata, in);
+			if (rc)
+				return rc;
 		} else {
 			/* Recurse down the path */
-			size = tpda_get_element_size(in, -1);
-		}
-
-		if (size < 0)
-			return size;
-
-		if (dsb_size < 0) {
-			/* Found a size, save it. */
-			dsb_size = size;
-		} else {
-			/* Found duplicate TPDMs */
-			return -EEXIST;
+			rc = tpda_get_element_size(drvdata, in, -1);
+			if (rc)
+				return rc;
 		}
 	}
 
-	return dsb_size;
+
+	return rc;
 }
 
 /* Settings pre enabling port control register */
@@ -109,7 +142,7 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
 static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
 {
 	u32 val;
-	int size;
+	int rc;
 
 	val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
 	/*
@@ -117,29 +150,21 @@ static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
 	 * Set the bit to 0 if the size is 32
 	 * Set the bit to 1 if the size is 64
 	 */
-	size = tpda_get_element_size(drvdata->csdev, port);
-	switch (size) {
-	case 32:
-		val &= ~TPDA_Pn_CR_DSBSIZE;
-		break;
-	case 64:
-		val |= TPDA_Pn_CR_DSBSIZE;
-		break;
-	case 0:
-		return -EEXIST;
-	case -EEXIST:
+	tpdm_clear_element_size(drvdata->csdev);
+	rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
+	if (!rc && (drvdata->dsb_esize || drvdata->cmb_esize)) {
+		tpda_set_element_size(drvdata, &val);
+		/* Enable the port */
+		val |= TPDA_Pn_CR_ENA;
+		writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
+	} else if (rc == -EEXIST)
 		dev_warn_once(&drvdata->csdev->dev,
-			"Detected multiple TPDMs on port %d", -EEXIST);
-		return -EEXIST;
-	default:
-		return -EINVAL;
-	}
-
-	/* Enable the port */
-	val |= TPDA_Pn_CR_ENA;
-	writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
+			      "Detected multiple TPDMs on port %d", port);
+	else
+		dev_warn_once(&drvdata->csdev->dev,
+			      "Didn't find TPDM element size");
 
-	return 0;
+	return rc;
 }
 
 static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
index b3b38fd41b64..19af64120fcf 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.h
+++ b/drivers/hwtracing/coresight/coresight-tpda.h
@@ -10,6 +10,8 @@
 #define TPDA_Pn_CR(n)		(0x004 + (n * 4))
 /* Aggregator port enable bit */
 #define TPDA_Pn_CR_ENA		BIT(0)
+/* Aggregator port CMB data set element size bit */
+#define TPDA_Pn_CR_CMBSIZE		GENMASK(7, 6)
 /* Aggregator port DSB data set element size bit */
 #define TPDA_Pn_CR_DSBSIZE		BIT(8)
 
@@ -25,6 +27,8 @@
  * @csdev:      component vitals needed by the framework.
  * @spinlock:   lock for the drvdata value.
  * @enable:     enable status of the component.
+ * @dsb_esize   Record the DSB element size.
+ * @cmb_esize   Record the CMB element size.
  */
 struct tpda_drvdata {
 	void __iomem		*base;
@@ -32,6 +36,8 @@ struct tpda_drvdata {
 	struct coresight_device	*csdev;
 	spinlock_t		spinlock;
 	u8			atid;
+	u8			dsb_esize;
+	u32			cmb_esize;
 };
 
 #endif  /* _CORESIGHT_CORESIGHT_TPDA_H */
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Feb  2 01:32:40 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:40 +0800
Subject: [PATCH v6 06/10] coresight-tpdm: Add support to configure CMB
In-Reply-To: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1706866364-19861-7-git-send-email-quic_taozha@quicinc.com>

TPDM CMB subunits support two forms of CMB data set element creation:
continuous and trace-on-change collection mode. Continuous change
creates CMB data set elements on every CMBCLK edge. Trace-on-change
creates CMB data set elements only when a new data set element differs
in value from the previous element in a CMB data set. Set CMB_CR.MODE
to 0 for continuous CMB collection mode. Set CMB_CR.MODE to 1 for
trace-on-change CMB collection mode.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Jinlong Mao <quic_jinlmao at quicinc.com>
---
 .../testing/sysfs-bus-coresight-devices-tpdm  | 14 +++++
 drivers/hwtracing/coresight/coresight-tpdm.c  | 60 +++++++++++++++++++
 drivers/hwtracing/coresight/coresight-tpdm.h  | 12 ++++
 3 files changed, 86 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index 4dd49b159543..6dfb18d6d64a 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -170,3 +170,17 @@ Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_t
 Description:
 		(RW) Set/Get the MSR(mux select register) for the DSB subunit
 		TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_mode
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:	(Write) Set the data collection mode of CMB tpdm. Continuous
+		change creates CMB data set elements on every CMBCLK edge.
+		Trace-on-change creates CMB data set elements only when a new
+		data set element differs in value from the previous element
+		in a CMB data set.
+
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Continuous CMB collection mode.
+		1 : Trace-on-change CMB collection mode.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 1bb1d8e83501..b20071460375 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -137,6 +137,18 @@ static umode_t tpdm_dsb_is_visible(struct kobject *kobj,
 	return 0;
 }
 
+static umode_t tpdm_cmb_is_visible(struct kobject *kobj,
+				   struct attribute *attr, int n)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (drvdata && tpdm_has_cmb_dataset(drvdata))
+		return attr->mode;
+
+	return 0;
+}
+
 static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj,
 				       struct attribute *attr, int n)
 {
@@ -161,6 +173,9 @@ static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
 		drvdata->dsb->trig_ts = true;
 		drvdata->dsb->trig_type = false;
 	}
+
+	if (drvdata->cmb)
+		memset(drvdata->cmb, 0, sizeof(struct cmb_dataset));
 }
 
 static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val)
@@ -391,6 +406,12 @@ static int tpdm_datasets_setup(struct tpdm_drvdata *drvdata)
 		if (!drvdata->dsb)
 			return -ENOMEM;
 	}
+	if (tpdm_has_cmb_dataset(drvdata) && (!drvdata->cmb)) {
+		drvdata->cmb = devm_kzalloc(drvdata->dev,
+						sizeof(*drvdata->cmb), GFP_KERNEL);
+		if (!drvdata->cmb)
+			return -ENOMEM;
+	}
 	tpdm_reset_datasets(drvdata);
 
 	return 0;
@@ -729,6 +750,34 @@ static ssize_t dsb_trig_ts_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(dsb_trig_ts);
 
+static ssize_t cmb_mode_show(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return sysfs_emit(buf, "%x\n", drvdata->cmb->trace_mode);
+
+}
+
+static ssize_t cmb_mode_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf,
+			      size_t size)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long trace_mode;
+
+	if (kstrtoul(buf, 0, &trace_mode) || (trace_mode & ~1UL))
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	drvdata->cmb->trace_mode = trace_mode;
+	spin_unlock(&drvdata->spinlock);
+	return size;
+}
+static DEVICE_ATTR_RW(cmb_mode);
+
 static struct attribute *tpdm_dsb_edge_attrs[] = {
 	&dev_attr_ctrl_idx.attr,
 	&dev_attr_ctrl_val.attr,
@@ -845,6 +894,11 @@ static struct attribute *tpdm_dsb_attrs[] = {
 	NULL,
 };
 
+static struct attribute *tpdm_cmb_attrs[] = {
+	&dev_attr_cmb_mode.attr,
+	NULL,
+};
+
 static struct attribute_group tpdm_dsb_attr_grp = {
 	.attrs = tpdm_dsb_attrs,
 	.is_visible = tpdm_dsb_is_visible,
@@ -874,6 +928,11 @@ static struct attribute_group tpdm_dsb_msr_grp = {
 	.name = "dsb_msr",
 };
 
+static struct attribute_group tpdm_cmb_attr_grp = {
+	.attrs = tpdm_cmb_attrs,
+	.is_visible = tpdm_cmb_is_visible,
+};
+
 static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_attr_grp,
 	&tpdm_dsb_attr_grp,
@@ -881,6 +940,7 @@ static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_dsb_trig_patt_grp,
 	&tpdm_dsb_patt_grp,
 	&tpdm_dsb_msr_grp,
+	&tpdm_cmb_attr_grp,
 	NULL,
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index a442d9c6e4ac..2af92c270ed1 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -14,6 +14,8 @@
 
 /* Enable bit for CMB subunit */
 #define TPDM_CMB_CR_ENA		BIT(0)
+/* Trace collection mode for CMB subunit */
+#define TPDM_CMB_CR_MODE	BIT(1)
 
 /* DSB Subunit Registers */
 #define TPDM_DSB_CR		(0x780)
@@ -181,6 +183,14 @@ struct dsb_dataset {
 	bool			trig_type;
 };
 
+/**
+ * struct cmb_dataset
+ * @trace_mode:       Dataset collection mode
+ */
+struct cmb_dataset {
+	u32			trace_mode;
+};
+
 /**
  * struct tpdm_drvdata - specifics associated to an TPDM component
  * @base:       memory mapped base address for this component.
@@ -190,6 +200,7 @@ struct dsb_dataset {
  * @enable:     enable status of the component.
  * @datasets:   The datasets types present of the TPDM.
  * @dsb         Specifics associated to TPDM DSB.
+ * @cmb         Specifics associated to TPDM CMB.
  * @dsb_msr_num Number of MSR supported by DSB TPDM
  */
 
@@ -201,6 +212,7 @@ struct tpdm_drvdata {
 	bool			enable;
 	unsigned long		datasets;
 	struct dsb_dataset	*dsb;
+	struct cmb_dataset	*cmb;
 	u32			dsb_msr_num;
 };
 
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Feb  2 01:32:41 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:41 +0800
Subject: [PATCH v6 07/10] coresight-tpdm: Add pattern registers support for CMB
In-Reply-To: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1706866364-19861-8-git-send-email-quic_taozha@quicinc.com>

Timestamps are requested if the monitor?s CMB data set unit input
data matches the value in the Monitor CMB timestamp pattern and mask
registers (M_CMB_TPR and M_CMB_TPMR) when CMB timestamp enabled
via the timestamp insertion enable register bit(CMB_TIER.PATT_TSENAB).
The pattern match trigger output is achieved via setting values into
the CMB trigger pattern and mask registers (CMB_XPR and CMB_XPMR).
After configuring a pattern through these registers, the TPDM subunit
will assert an output trigger every time it receives new input data
that matches the configured pattern value. Values in a given bit
number of the mask register correspond to the same bit number in
the corresponding pattern register.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Jinlong Mao <quic_jinlmao at quicinc.com>
---
 .../testing/sysfs-bus-coresight-devices-tpdm  | 30 ++++++
 drivers/hwtracing/coresight/coresight-tpdm.c  | 96 ++++++++++++++++++-
 drivers/hwtracing/coresight/coresight-tpdm.h  | 39 ++++++++
 3 files changed, 164 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index 6dfb18d6d64a..b6cf050861ed 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -184,3 +184,33 @@ Description:	(Write) Set the data collection mode of CMB tpdm. Continuous
 		Accepts only one of the 2 values -  0 or 1.
 		0 : Continuous CMB collection mode.
 		1 : Trace-on-change CMB collection mode.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the value of the trigger pattern for the CMB
+		subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpmr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the mask of the trigger pattern for the CMB
+		subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the value of the pattern for the CMB subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpmr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index b20071460375..07587287d9fa 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -66,6 +66,26 @@ static ssize_t tpdm_simple_dataset_show(struct device *dev,
 			return -EINVAL;
 		return sysfs_emit(buf, "0x%x\n",
 				drvdata->dsb->msr[tpdm_attr->idx]);
+	case CMB_TRIG_PATT:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->trig_patt[tpdm_attr->idx]);
+	case CMB_TRIG_PATT_MASK:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->trig_patt_mask[tpdm_attr->idx]);
+	case CMB_PATT:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->patt_val[tpdm_attr->idx]);
+	case CMB_PATT_MASK:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->patt_mask[tpdm_attr->idx]);
 	}
 	return -EINVAL;
 }
@@ -118,6 +138,30 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
 			ret = size;
 		}
 		break;
+	case CMB_TRIG_PATT:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->trig_patt[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
+	case CMB_TRIG_PATT_MASK:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->trig_patt_mask[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
+	case CMB_PATT:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->patt_val[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
+	case CMB_PATT_MASK:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->patt_mask[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
 	default:
 		break;
 	}
@@ -280,12 +324,32 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
 
 static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 {
-	u32 val;
+	u32 val, i;
 
 	if (!tpdm_has_cmb_dataset(drvdata))
 		return;
 
+	/* Configure pattern registers */
+	for (i = 0; i < TPDM_CMB_MAX_PATT; i++) {
+		writel_relaxed(drvdata->cmb->patt_val[i],
+			drvdata->base + TPDM_CMB_TPR(i));
+		writel_relaxed(drvdata->cmb->patt_mask[i],
+			drvdata->base + TPDM_CMB_TPMR(i));
+		writel_relaxed(drvdata->cmb->trig_patt[i],
+			drvdata->base + TPDM_CMB_XPR(i));
+		writel_relaxed(drvdata->cmb->trig_patt_mask[i],
+			drvdata->base + TPDM_CMB_XPMR(i));
+	}
+
 	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
+	/*
+	 * Set to 0 for continuous CMB collection mode,
+	 * 1 for trace-on-change CMB collection mode.
+	 */
+	if (drvdata->cmb->trace_mode)
+		val |= TPDM_CMB_CR_MODE;
+	else
+		val &= ~TPDM_CMB_CR_MODE;
 	/* Set the enable bit of CMB control register to 1 */
 	val |= TPDM_CMB_CR_ENA;
 	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
@@ -887,6 +951,22 @@ static struct attribute *tpdm_dsb_msr_attrs[] = {
 	NULL,
 };
 
+static struct attribute *tpdm_cmb_trig_patt_attrs[] = {
+	CMB_TRIG_PATT_ATTR(0),
+	CMB_TRIG_PATT_ATTR(1),
+	CMB_TRIG_PATT_MASK_ATTR(0),
+	CMB_TRIG_PATT_MASK_ATTR(1),
+	NULL,
+};
+
+static struct attribute *tpdm_cmb_patt_attrs[] = {
+	CMB_PATT_ATTR(0),
+	CMB_PATT_ATTR(1),
+	CMB_PATT_MASK_ATTR(0),
+	CMB_PATT_MASK_ATTR(1),
+	NULL,
+};
+
 static struct attribute *tpdm_dsb_attrs[] = {
 	&dev_attr_dsb_mode.attr,
 	&dev_attr_dsb_trig_ts.attr,
@@ -933,6 +1013,18 @@ static struct attribute_group tpdm_cmb_attr_grp = {
 	.is_visible = tpdm_cmb_is_visible,
 };
 
+static struct attribute_group tpdm_cmb_trig_patt_grp = {
+	.attrs = tpdm_cmb_trig_patt_attrs,
+	.is_visible = tpdm_cmb_is_visible,
+	.name = "cmb_trig_patt",
+};
+
+static struct attribute_group tpdm_cmb_patt_grp = {
+	.attrs = tpdm_cmb_patt_attrs,
+	.is_visible = tpdm_cmb_is_visible,
+	.name = "cmb_patt",
+};
+
 static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_attr_grp,
 	&tpdm_dsb_attr_grp,
@@ -941,6 +1033,8 @@ static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_dsb_patt_grp,
 	&tpdm_dsb_msr_grp,
 	&tpdm_cmb_attr_grp,
+	&tpdm_cmb_trig_patt_grp,
+	&tpdm_cmb_patt_grp,
 	NULL,
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index 2af92c270ed1..e5d4c22cd38c 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -11,12 +11,23 @@
 
 /* CMB Subunit Registers */
 #define TPDM_CMB_CR		(0xA00)
+/* CMB subunit timestamp pattern registers */
+#define TPDM_CMB_TPR(n)		(0xA08 + (n * 4))
+/* CMB subunit timestamp pattern mask registers */
+#define TPDM_CMB_TPMR(n)	(0xA10 + (n * 4))
+/* CMB subunit trigger pattern registers */
+#define TPDM_CMB_XPR(n)		(0xA18 + (n * 4))
+/* CMB subunit trigger pattern mask registers */
+#define TPDM_CMB_XPMR(n)	(0xA20 + (n * 4))
 
 /* Enable bit for CMB subunit */
 #define TPDM_CMB_CR_ENA		BIT(0)
 /* Trace collection mode for CMB subunit */
 #define TPDM_CMB_CR_MODE	BIT(1)
 
+/* Patten register number */
+#define TPDM_CMB_MAX_PATT		2
+
 /* DSB Subunit Registers */
 #define TPDM_DSB_CR		(0x780)
 #define TPDM_DSB_TIER		(0x784)
@@ -151,6 +162,22 @@
 		tpdm_simple_dataset_rw(msr##nr,			\
 		DSB_MSR, nr)
 
+#define CMB_TRIG_PATT_ATTR(nr)					\
+		tpdm_simple_dataset_rw(xpr##nr,			\
+		CMB_TRIG_PATT, nr)
+
+#define CMB_TRIG_PATT_MASK_ATTR(nr)				\
+		tpdm_simple_dataset_rw(xpmr##nr,		\
+		CMB_TRIG_PATT_MASK, nr)
+
+#define CMB_PATT_ATTR(nr)					\
+		tpdm_simple_dataset_rw(tpr##nr,			\
+		CMB_PATT, nr)
+
+#define CMB_PATT_MASK_ATTR(nr)					\
+		tpdm_simple_dataset_rw(tpmr##nr,		\
+		CMB_PATT_MASK, nr)
+
 /**
  * struct dsb_dataset - specifics associated to dsb dataset
  * @mode:             DSB programming mode
@@ -186,9 +213,17 @@ struct dsb_dataset {
 /**
  * struct cmb_dataset
  * @trace_mode:       Dataset collection mode
+ * @patt_val:         Save value for pattern
+ * @patt_mask:        Save value for pattern mask
+ * @trig_patt:        Save value for trigger pattern
+ * @trig_patt_mask:   Save value for trigger pattern mask
  */
 struct cmb_dataset {
 	u32			trace_mode;
+	u32			patt_val[TPDM_CMB_MAX_PATT];
+	u32			patt_mask[TPDM_CMB_MAX_PATT];
+	u32			trig_patt[TPDM_CMB_MAX_PATT];
+	u32			trig_patt_mask[TPDM_CMB_MAX_PATT];
 };
 
 /**
@@ -225,6 +260,10 @@ enum dataset_mem {
 	DSB_PATT,
 	DSB_PATT_MASK,
 	DSB_MSR,
+	CMB_TRIG_PATT,
+	CMB_TRIG_PATT_MASK,
+	CMB_PATT,
+	CMB_PATT_MASK
 };
 
 /**
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Feb  2 01:32:42 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:42 +0800
Subject: [PATCH v6 08/10] coresight-tpdm: Add timestamp control register support for the CMB
In-Reply-To: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1706866364-19861-9-git-send-email-quic_taozha@quicinc.com>

CMB_TIER register is CMB subunit timestamp insertion enable register.
Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
Set this bit to 1 to request a timestamp following a CMB CTI timestamp
request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
for all packets.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Jinlong Mao <quic_jinlmao at quicinc.com>
---
 .../testing/sysfs-bus-coresight-devices-tpdm  |  35 +++++
 drivers/hwtracing/coresight/coresight-tpdm.c  | 121 +++++++++++++++++-
 drivers/hwtracing/coresight/coresight-tpdm.h  |  31 +++++
 3 files changed, 180 insertions(+), 7 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index b6cf050861ed..e8c76ce4dd15 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -214,3 +214,38 @@ KernelVersion	6.9
 Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
 Description:
 		(RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(Write) Set the pattern timestamp of CMB tpdm. Read
+		the pattern timestamp of CMB tpdm.
+
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Disable CMB pattern timestamp.
+		1 : Enable CMB pattern timestamp.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the trigger timestamp of the CMB for tpdm.
+
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Set the CMB trigger type to false
+		1 : Set the CMB trigger type to true
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Read or write the status of timestamp upon all interface.
+		Only value 0 and 1  can be written to this node. Set this node to 1 to requeset
+		timestamp to all trace packet.
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Disable the timestamp of all trace packets.
+		1 : Enable the timestamp of all trace packets.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 07587287d9fa..22966d541230 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -322,6 +322,31 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
 	writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
 }
 
+static void set_cmb_tier(struct tpdm_drvdata *drvdata)
+{
+	u32 val;
+
+	val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
+
+	/* Clear all relevant fields */
+	val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
+		 TPDM_CMB_TIER_XTRIG_TSENAB);
+
+	/* Set pattern timestamp type and enablement */
+	if (drvdata->cmb->patt_ts)
+		val |= TPDM_CMB_TIER_PATT_TSENAB;
+
+	/* Set trigger timestamp */
+	if (drvdata->cmb->trig_ts)
+		val |= TPDM_CMB_TIER_XTRIG_TSENAB;
+
+	/* Set all timestamp enablement*/
+	if (drvdata->cmb->ts_all)
+		val |= TPDM_CMB_TIER_TS_ALL;
+
+	writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
+}
+
 static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 {
 	u32 val, i;
@@ -341,6 +366,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 			drvdata->base + TPDM_CMB_XPMR(i));
 	}
 
+	set_cmb_tier(drvdata);
+
 	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
 	/*
 	 * Set to 0 for continuous CMB collection mode,
@@ -687,9 +714,18 @@ static ssize_t enable_ts_show(struct device *dev,
 			      char *buf)
 {
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct tpdm_dataset_attribute *tpdm_attr =
+		container_of(attr, struct tpdm_dataset_attribute, attr);
+	ssize_t size = -EINVAL;
 
-	return sysfs_emit(buf, "%u\n",
-			 (unsigned int)drvdata->dsb->patt_ts);
+	if (tpdm_attr->mem == DSB_PATT)
+		size = sysfs_emit(buf, "%u\n",
+				  (unsigned int)drvdata->dsb->patt_ts);
+	else if (tpdm_attr->mem == CMB_PATT)
+		size = sysfs_emit(buf, "%u\n",
+				  (unsigned int)drvdata->cmb->patt_ts);
+
+	return size;
 }
 
 /*
@@ -701,17 +737,23 @@ static ssize_t enable_ts_store(struct device *dev,
 			       size_t size)
 {
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct tpdm_dataset_attribute *tpdm_attr =
+		container_of(attr, struct tpdm_dataset_attribute, attr);
 	unsigned long val;
 
 	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
-	drvdata->dsb->patt_ts = !!val;
-	spin_unlock(&drvdata->spinlock);
+	guard(spinlock)(&drvdata->spinlock);
+	if (tpdm_attr->mem == DSB_PATT)
+		drvdata->dsb->patt_ts = !!val;
+	else if (tpdm_attr->mem == CMB_PATT)
+		drvdata->cmb->patt_ts = !!val;
+	else
+		return -EINVAL;
+
 	return size;
 }
-static DEVICE_ATTR_RW(enable_ts);
 
 static ssize_t set_type_show(struct device *dev,
 			     struct device_attribute *attr,
@@ -842,6 +884,68 @@ static ssize_t cmb_mode_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(cmb_mode);
 
+static ssize_t cmb_ts_all_show(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return sysfs_emit(buf, "%u\n",
+			  (unsigned int)drvdata->cmb->ts_all);
+}
+
+static ssize_t cmb_ts_all_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf,
+				size_t size)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
+		return -EINVAL;
+
+	guard(spinlock)(&drvdata->spinlock);
+	if (val)
+		drvdata->cmb->ts_all = true;
+	else
+		drvdata->cmb->ts_all = false;
+
+	return size;
+}
+static DEVICE_ATTR_RW(cmb_ts_all);
+
+static ssize_t cmb_trig_ts_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return sysfs_emit(buf, "%u\n",
+			  (unsigned int)drvdata->cmb->trig_ts);
+}
+
+static ssize_t cmb_trig_ts_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t size)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
+		return -EINVAL;
+
+	guard(spinlock)(&drvdata->spinlock);
+	if (val)
+		drvdata->cmb->trig_ts = true;
+	else
+		drvdata->cmb->trig_ts = false;
+
+	return size;
+}
+static DEVICE_ATTR_RW(cmb_trig_ts);
+
 static struct attribute *tpdm_dsb_edge_attrs[] = {
 	&dev_attr_ctrl_idx.attr,
 	&dev_attr_ctrl_val.attr,
@@ -910,7 +1014,7 @@ static struct attribute *tpdm_dsb_patt_attrs[] = {
 	DSB_PATT_MASK_ATTR(5),
 	DSB_PATT_MASK_ATTR(6),
 	DSB_PATT_MASK_ATTR(7),
-	&dev_attr_enable_ts.attr,
+	DSB_PATT_ENABLE_TS,
 	&dev_attr_set_type.attr,
 	NULL,
 };
@@ -964,6 +1068,7 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
 	CMB_PATT_ATTR(1),
 	CMB_PATT_MASK_ATTR(0),
 	CMB_PATT_MASK_ATTR(1),
+	CMB_PATT_ENABLE_TS,
 	NULL,
 };
 
@@ -976,6 +1081,8 @@ static struct attribute *tpdm_dsb_attrs[] = {
 
 static struct attribute *tpdm_cmb_attrs[] = {
 	&dev_attr_cmb_mode.attr,
+	&dev_attr_cmb_ts_all.attr,
+	&dev_attr_cmb_trig_ts.attr,
 	NULL,
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index e5d4c22cd38c..6d1fe4aed7d0 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -11,6 +11,8 @@
 
 /* CMB Subunit Registers */
 #define TPDM_CMB_CR		(0xA00)
+/* CMB subunit timestamp insertion enable register */
+#define TPDM_CMB_TIER		(0xA04)
 /* CMB subunit timestamp pattern registers */
 #define TPDM_CMB_TPR(n)		(0xA08 + (n * 4))
 /* CMB subunit timestamp pattern mask registers */
@@ -24,6 +26,12 @@
 #define TPDM_CMB_CR_ENA		BIT(0)
 /* Trace collection mode for CMB subunit */
 #define TPDM_CMB_CR_MODE	BIT(1)
+/* Timestamp control for pattern match */
+#define TPDM_CMB_TIER_PATT_TSENAB	BIT(0)
+/* CMB CTI timestamp request */
+#define TPDM_CMB_TIER_XTRIG_TSENAB	BIT(1)
+/* For timestamp fo all trace */
+#define TPDM_CMB_TIER_TS_ALL		BIT(2)
 
 /* Patten register number */
 #define TPDM_CMB_MAX_PATT		2
@@ -134,6 +142,15 @@
 	   }								\
 	})[0].attr.attr)
 
+#define tpdm_patt_enable_ts(name, mem)				\
+	(&((struct tpdm_dataset_attribute[]) {			\
+	   {							\
+		__ATTR(name, 0644, enable_ts_show,		\
+		enable_ts_store),		\
+		mem,						\
+	   }							\
+	})[0].attr.attr)
+
 #define DSB_EDGE_CTRL_ATTR(nr)					\
 		tpdm_simple_dataset_ro(edcr##nr,		\
 		DSB_EDGE_CTRL, nr)
@@ -158,6 +175,10 @@
 		tpdm_simple_dataset_rw(tpmr##nr,		\
 		DSB_PATT_MASK, nr)
 
+#define DSB_PATT_ENABLE_TS					\
+		tpdm_patt_enable_ts(enable_ts,			\
+		DSB_PATT)
+
 #define DSB_MSR_ATTR(nr)					\
 		tpdm_simple_dataset_rw(msr##nr,			\
 		DSB_MSR, nr)
@@ -178,6 +199,10 @@
 		tpdm_simple_dataset_rw(tpmr##nr,		\
 		CMB_PATT_MASK, nr)
 
+#define CMB_PATT_ENABLE_TS					\
+		tpdm_patt_enable_ts(enable_ts,			\
+		CMB_PATT)
+
 /**
  * struct dsb_dataset - specifics associated to dsb dataset
  * @mode:             DSB programming mode
@@ -217,6 +242,9 @@ struct dsb_dataset {
  * @patt_mask:        Save value for pattern mask
  * @trig_patt:        Save value for trigger pattern
  * @trig_patt_mask:   Save value for trigger pattern mask
+ * @patt_ts:          Indicates if pattern match for timestamp is enabled.
+ * @trig_ts:          Indicates if CTI trigger for timestamp is enabled.
+ * @ts_all:           Indicates if timestamp is enabled for all packets.
  */
 struct cmb_dataset {
 	u32			trace_mode;
@@ -224,6 +252,9 @@ struct cmb_dataset {
 	u32			patt_mask[TPDM_CMB_MAX_PATT];
 	u32			trig_patt[TPDM_CMB_MAX_PATT];
 	u32			trig_patt_mask[TPDM_CMB_MAX_PATT];
+	bool			patt_ts;
+	bool			trig_ts;
+	bool			ts_all;
 };
 
 /**
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Feb  2 01:32:43 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:43 +0800
Subject: [PATCH v6 09/10] dt-bindings: arm: qcom,coresight-tpdm: Add support for TPDM CMB MSR register
In-Reply-To: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1706866364-19861-10-git-send-email-quic_taozha@quicinc.com>

Add property "qcom,cmb_msr_num" to support CMB MSR(mux select register)
for TPDM. It specifies the number of CMB MSR registers supported by
the TDPM.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml   | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
index 2320b5445900..d0647ffaed71 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
@@ -69,6 +69,15 @@ properties:
     minimum: 0
     maximum: 32
 
+  qcom,cmb-msrs-num:
+    description:
+      Specifies the number of CMB MSR(mux select register) registers supported
+      by the monitor. If this property is not configured or set to 0, it means
+      this TPDM doesn't support CMB MSR.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 32
+
   clocks:
     maxItems: 1
 
@@ -123,6 +132,7 @@ examples:
       reg = <0x06c29000 0x1000>;
 
       qcom,cmb-element-bits = <64>;
+      qcom,cmb-msrs-num = <32>;
 
       clocks = <&aoss_qmp>;
       clock-names = "apb_pclk";
-- 
2.17.1



From quic_taozha at quicinc.com  Fri Feb  2 01:32:44 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Fri, 2 Feb 2024 17:32:44 +0800
Subject: [PATCH v6 10/10] coresight-tpdm: Add msr register support for CMB
In-Reply-To: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1706866364-19861-11-git-send-email-quic_taozha@quicinc.com>

Add the nodes for CMB subunit MSR(mux select register) support.
CMB MSRs(mux select registers) is to separate mux, arbitration,
interleaving,data packing control from stream filtering control.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
 drivers/hwtracing/coresight/coresight-tpdm.c  | 85 +++++++++++++++++++
 drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
 3 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index e8c76ce4dd15..b4d0fc8d319d 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -249,3 +249,11 @@ Description:
 		Accepts only one of the 2 values -  0 or 1.
 		0 : Disable the timestamp of all trace packets.
 		1 : Enable the timestamp of all trace packets.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the MSR(mux select register) for the CMB subunit
+		TPDM.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 22966d541230..a9708ab0d488 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct device *dev,
 			return -EINVAL;
 		return sysfs_emit(buf, "0x%x\n",
 			drvdata->cmb->patt_mask[tpdm_attr->idx]);
+	case CMB_MSR:
+		if (tpdm_attr->idx >= drvdata->cmb_msr_num)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+				drvdata->cmb->msr[tpdm_attr->idx]);
 	}
 	return -EINVAL;
 }
@@ -162,6 +167,12 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
 			ret = size;
 		}
 		break;
+	case CMB_MSR:
+		if (tpdm_attr->idx < drvdata->cmb_msr_num) {
+			drvdata->cmb->msr[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
 	default:
 		break;
 	}
@@ -209,6 +220,23 @@ static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj,
 	return 0;
 }
 
+static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj,
+				       struct attribute *attr, int n)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	struct device_attribute *dev_attr =
+		container_of(attr, struct device_attribute, attr);
+	struct tpdm_dataset_attribute *tpdm_attr =
+		container_of(dev_attr, struct tpdm_dataset_attribute, attr);
+
+	if (tpdm_attr->idx < drvdata->cmb_msr_num)
+		return attr->mode;
+
+	return 0;
+}
+
 static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
 {
 	if (tpdm_has_dsb_dataset(drvdata)) {
@@ -347,6 +375,15 @@ static void set_cmb_tier(struct tpdm_drvdata *drvdata)
 	writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
 }
 
+static void set_cmb_msr(struct tpdm_drvdata *drvdata)
+{
+	int i;
+
+	for (i = 0; i < drvdata->cmb_msr_num; i++)
+		writel_relaxed(drvdata->cmb->msr[i],
+			   drvdata->base + TPDM_CMB_MSR(i));
+}
+
 static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 {
 	u32 val, i;
@@ -367,6 +404,7 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 	}
 
 	set_cmb_tier(drvdata);
+	set_cmb_msr(drvdata);
 
 	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
 	/*
@@ -1072,6 +1110,42 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
 	NULL,
 };
 
+static struct attribute *tpdm_cmb_msr_attrs[] = {
+	CMB_MSR_ATTR(0),
+	CMB_MSR_ATTR(1),
+	CMB_MSR_ATTR(2),
+	CMB_MSR_ATTR(3),
+	CMB_MSR_ATTR(4),
+	CMB_MSR_ATTR(5),
+	CMB_MSR_ATTR(6),
+	CMB_MSR_ATTR(7),
+	CMB_MSR_ATTR(8),
+	CMB_MSR_ATTR(9),
+	CMB_MSR_ATTR(10),
+	CMB_MSR_ATTR(11),
+	CMB_MSR_ATTR(12),
+	CMB_MSR_ATTR(13),
+	CMB_MSR_ATTR(14),
+	CMB_MSR_ATTR(15),
+	CMB_MSR_ATTR(16),
+	CMB_MSR_ATTR(17),
+	CMB_MSR_ATTR(18),
+	CMB_MSR_ATTR(19),
+	CMB_MSR_ATTR(20),
+	CMB_MSR_ATTR(21),
+	CMB_MSR_ATTR(22),
+	CMB_MSR_ATTR(23),
+	CMB_MSR_ATTR(24),
+	CMB_MSR_ATTR(25),
+	CMB_MSR_ATTR(26),
+	CMB_MSR_ATTR(27),
+	CMB_MSR_ATTR(28),
+	CMB_MSR_ATTR(29),
+	CMB_MSR_ATTR(30),
+	CMB_MSR_ATTR(31),
+	NULL,
+};
+
 static struct attribute *tpdm_dsb_attrs[] = {
 	&dev_attr_dsb_mode.attr,
 	&dev_attr_dsb_trig_ts.attr,
@@ -1132,6 +1206,12 @@ static struct attribute_group tpdm_cmb_patt_grp = {
 	.name = "cmb_patt",
 };
 
+static struct attribute_group tpdm_cmb_msr_grp = {
+	.attrs = tpdm_cmb_msr_attrs,
+	.is_visible = tpdm_cmb_msr_is_visible,
+	.name = "cmb_msr",
+};
+
 static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_attr_grp,
 	&tpdm_dsb_attr_grp,
@@ -1142,6 +1222,7 @@ static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_cmb_attr_grp,
 	&tpdm_cmb_trig_patt_grp,
 	&tpdm_cmb_patt_grp,
+	&tpdm_cmb_msr_grp,
 	NULL,
 };
 
@@ -1180,6 +1261,10 @@ static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
 		of_property_read_u32(drvdata->dev->of_node,
 			   "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
 
+	if (drvdata && tpdm_has_cmb_dataset(drvdata))
+		of_property_read_u32(drvdata->dev->of_node,
+			   "qcom,cmb-msrs-num", &drvdata->cmb_msr_num);
+
 	/* Set up coresight component description */
 	desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
 	if (!desc.name)
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index 6d1fe4aed7d0..f3a8f56d0fe7 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -21,6 +21,8 @@
 #define TPDM_CMB_XPR(n)		(0xA18 + (n * 4))
 /* CMB subunit trigger pattern mask registers */
 #define TPDM_CMB_XPMR(n)	(0xA20 + (n * 4))
+/* CMB MSR register */
+#define TPDM_CMB_MSR(n)		(0xA80 + (n * 4))
 
 /* Enable bit for CMB subunit */
 #define TPDM_CMB_CR_ENA		BIT(0)
@@ -36,6 +38,9 @@
 /* Patten register number */
 #define TPDM_CMB_MAX_PATT		2
 
+/* MAX number of DSB MSR */
+#define TPDM_CMB_MAX_MSR 32
+
 /* DSB Subunit Registers */
 #define TPDM_DSB_CR		(0x780)
 #define TPDM_DSB_TIER		(0x784)
@@ -203,6 +208,10 @@
 		tpdm_patt_enable_ts(enable_ts,			\
 		CMB_PATT)
 
+#define CMB_MSR_ATTR(nr)					\
+		tpdm_simple_dataset_rw(msr##nr,			\
+		CMB_MSR, nr)
+
 /**
  * struct dsb_dataset - specifics associated to dsb dataset
  * @mode:             DSB programming mode
@@ -242,6 +251,7 @@ struct dsb_dataset {
  * @patt_mask:        Save value for pattern mask
  * @trig_patt:        Save value for trigger pattern
  * @trig_patt_mask:   Save value for trigger pattern mask
+ * @msr               Save value for MSR
  * @patt_ts:          Indicates if pattern match for timestamp is enabled.
  * @trig_ts:          Indicates if CTI trigger for timestamp is enabled.
  * @ts_all:           Indicates if timestamp is enabled for all packets.
@@ -252,6 +262,7 @@ struct cmb_dataset {
 	u32			patt_mask[TPDM_CMB_MAX_PATT];
 	u32			trig_patt[TPDM_CMB_MAX_PATT];
 	u32			trig_patt_mask[TPDM_CMB_MAX_PATT];
+	u32			msr[TPDM_CMB_MAX_MSR];
 	bool			patt_ts;
 	bool			trig_ts;
 	bool			ts_all;
@@ -268,6 +279,7 @@ struct cmb_dataset {
  * @dsb         Specifics associated to TPDM DSB.
  * @cmb         Specifics associated to TPDM CMB.
  * @dsb_msr_num Number of MSR supported by DSB TPDM
+ * @cmb_msr_num Number of MSR supported by CMB TPDM
  */
 
 struct tpdm_drvdata {
@@ -280,6 +292,7 @@ struct tpdm_drvdata {
 	struct dsb_dataset	*dsb;
 	struct cmb_dataset	*cmb;
 	u32			dsb_msr_num;
+	u32			cmb_msr_num;
 };
 
 /* Enumerate members of various datasets */
@@ -294,7 +307,8 @@ enum dataset_mem {
 	CMB_TRIG_PATT,
 	CMB_TRIG_PATT_MASK,
 	CMB_PATT,
-	CMB_PATT_MASK
+	CMB_PATT_MASK,
+	CMB_MSR
 };
 
 /**
-- 
2.17.1



From rmk+kernel at armlinux.org.uk  Fri Feb  2 01:33:49 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 02 Feb 2024 09:33:49 +0000
Subject: [PATCH net-next 2/6] net: sxgbe: remove eee_enabled/eee_active in
 sxgbe_get_eee()
In-Reply-To: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
Message-ID: <E1rVpvh-002Pdv-Ol@rmk-PC.armlinux.org.uk>

sxgbe_get_eee() sets edata->eee_active and edata->eee_enabled from its
own copy, and then calls phy_ethtool_get_eee() which in turn will call
genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Therefore, setting these members in sxgbe_get_eee() is redundant.
Remove this, and remove the priv->eee_active member which then becomes
a write-only variable.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h  | 1 -
 drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c | 2 --
 drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c    | 1 -
 3 files changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h
index d14e0cfc3a6b..1458939c3bf5 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h
@@ -503,7 +503,6 @@ struct sxgbe_priv_data {
 	bool tx_path_in_lpi_mode;
 	int lpi_irq;
 	int eee_enabled;
-	int eee_active;
 	int tx_lpi_timer;
 };
 
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
index d93b628b7046..4a439b34114d 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
@@ -140,8 +140,6 @@ static int sxgbe_get_eee(struct net_device *dev,
 	if (!priv->hw_cap.eee)
 		return -EOPNOTSUPP;
 
-	edata->eee_enabled = priv->eee_enabled;
-	edata->eee_active = priv->eee_active;
 	edata->tx_lpi_timer = priv->tx_lpi_timer;
 
 	return phy_ethtool_get_eee(dev->phydev, edata);
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 71439825ea4e..ecbe3994f2b1 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -130,7 +130,6 @@ bool sxgbe_eee_init(struct sxgbe_priv_data * const priv)
 		if (phy_init_eee(ndev->phydev, true))
 			return false;
 
-		priv->eee_active = 1;
 		timer_setup(&priv->eee_ctrl_timer, sxgbe_eee_ctrl_timer, 0);
 		priv->eee_ctrl_timer.expires = SXGBE_LPI_TIMER(eee_timer);
 		add_timer(&priv->eee_ctrl_timer);
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Fri Feb  2 01:33:54 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 02 Feb 2024 09:33:54 +0000
Subject: [PATCH net-next 3/6] net: fec: remove eee_enabled/eee_active in
 fec_enet_get_eee()
In-Reply-To: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
Message-ID: <E1rVpvm-002Pe0-TV@rmk-PC.armlinux.org.uk>

fec_enet_get_eee() sets edata->eee_active and edata->eee_enabled from
its own copy, and then calls phy_ethtool_get_eee() which in turn will
call genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Therefore, setting these members in fec_enet_get_eee() is redundant.
Remove this, and remove the setting of fep->eee.eee_active member which
becomes a write-only variable.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/freescale/fec_main.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 63707e065141..38dcf0989e3f 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -3140,7 +3140,6 @@ static int fec_enet_eee_mode_set(struct net_device *ndev, bool enable)
 
 	p->tx_lpi_enabled = enable;
 	p->eee_enabled = enable;
-	p->eee_active = enable;
 
 	writel(sleep_cycle, fep->hwp + FEC_LPI_SLEEP);
 	writel(wake_cycle, fep->hwp + FEC_LPI_WAKE);
@@ -3160,8 +3159,6 @@ fec_enet_get_eee(struct net_device *ndev, struct ethtool_keee *edata)
 	if (!netif_running(ndev))
 		return -ENETDOWN;
 
-	edata->eee_enabled = p->eee_enabled;
-	edata->eee_active = p->eee_active;
 	edata->tx_lpi_timer = p->tx_lpi_timer;
 	edata->tx_lpi_enabled = p->tx_lpi_enabled;
 
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Fri Feb  2 01:34:05 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 02 Feb 2024 09:34:05 +0000
Subject: [PATCH net-next 5/6] net: bcmasp: remove eee_enabled/eee_active in
 bcmasp_get_eee()
In-Reply-To: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
Message-ID: <E1rVpvx-002PeD-71@rmk-PC.armlinux.org.uk>

bcmasp_get_eee() sets edata->eee_active and edata->eee_enabled from
its own copy, and then calls phy_ethtool_get_eee() which in turn will
call genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Therefore, setting these members in bcmasp_get_eee() is redundant, and
can be removed. This also makes intf->eee.eee_active unnecessary, so
remove this and use a local variable where appropriate.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c | 4 ----
 drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c    | 5 +++--
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
index 2851bed153e6..484fc2b5626f 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
@@ -360,7 +360,6 @@ void bcmasp_eee_enable_set(struct bcmasp_intf *intf, bool enable)
 	umac_wl(intf, reg, UMC_EEE_CTRL);
 
 	intf->eee.eee_enabled = enable;
-	intf->eee.eee_active = enable;
 }
 
 static int bcmasp_get_eee(struct net_device *dev, struct ethtool_keee *e)
@@ -371,8 +370,6 @@ static int bcmasp_get_eee(struct net_device *dev, struct ethtool_keee *e)
 	if (!dev->phydev)
 		return -ENODEV;
 
-	e->eee_enabled = p->eee_enabled;
-	e->eee_active = p->eee_active;
 	e->tx_lpi_enabled = p->tx_lpi_enabled;
 	e->tx_lpi_timer = umac_rl(intf, UMC_EEE_LPI_TIMER);
 
@@ -399,7 +396,6 @@ static int bcmasp_set_eee(struct net_device *dev, struct ethtool_keee *e)
 		}
 
 		umac_wl(intf, e->tx_lpi_timer, UMC_EEE_LPI_TIMER);
-		intf->eee.eee_active = ret >= 0;
 		intf->eee.tx_lpi_enabled = e->tx_lpi_enabled;
 		bcmasp_eee_enable_set(intf, true);
 	}
diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
index 53e542881255..3a15f269c7d1 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
@@ -607,6 +607,7 @@ static void bcmasp_adj_link(struct net_device *dev)
 	struct phy_device *phydev = dev->phydev;
 	u32 cmd_bits = 0, reg;
 	int changed = 0;
+	bool active;
 
 	if (intf->old_link != phydev->link) {
 		changed = 1;
@@ -658,8 +659,8 @@ static void bcmasp_adj_link(struct net_device *dev)
 		reg |= cmd_bits;
 		umac_wl(intf, reg, UMC_CMD);
 
-		intf->eee.eee_active = phy_init_eee(phydev, 0) >= 0;
-		bcmasp_eee_enable_set(intf, intf->eee.eee_active);
+		active = phy_init_eee(phydev, 0) >= 0;
+		bcmasp_eee_enable_set(intf, active);
 	}
 
 	reg = rgmii_rl(intf, RGMII_OOB_CNTRL);
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Fri Feb  2 01:34:00 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 02 Feb 2024 09:34:00 +0000
Subject: [PATCH net-next 4/6] net: bcmgenet: remove eee_enabled/eee_active in
 bcmgenet_get_eee()
In-Reply-To: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
Message-ID: <E1rVpvs-002Pe6-1w@rmk-PC.armlinux.org.uk>

bcmgenet_get_eee() sets edata->eee_active and edata->eee_enabled from
its own copy, and then calls phy_ethtool_get_eee() which in turn will
call genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Therefore, setting these members in bcmgenet_get_eee() is redundant,
and can be removed. This also makes priv->eee.eee_active unnecessary,
so remove this and use a local variable where appropriate.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 8 +++-----
 drivers/net/ethernet/broadcom/genet/bcmmii.c   | 5 +++--
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 051c31fb17c2..7396e2823e32 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1313,7 +1313,6 @@ void bcmgenet_eee_enable_set(struct net_device *dev, bool enable,
 	}
 
 	priv->eee.eee_enabled = enable;
-	priv->eee.eee_active = enable;
 	priv->eee.tx_lpi_enabled = tx_lpi_enabled;
 }
 
@@ -1328,8 +1327,6 @@ static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_keee *e)
 	if (!dev->phydev)
 		return -ENODEV;
 
-	e->eee_enabled = p->eee_enabled;
-	e->eee_active = p->eee_active;
 	e->tx_lpi_enabled = p->tx_lpi_enabled;
 	e->tx_lpi_timer = bcmgenet_umac_readl(priv, UMAC_EEE_LPI_TIMER);
 
@@ -1340,6 +1337,7 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_keee *e)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 	struct ethtool_keee *p = &priv->eee;
+	bool active;
 
 	if (GENET_IS_V1(priv))
 		return -EOPNOTSUPP;
@@ -1352,9 +1350,9 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_keee *e)
 	if (!p->eee_enabled) {
 		bcmgenet_eee_enable_set(dev, false, false);
 	} else {
-		p->eee_active = phy_init_eee(dev->phydev, false) >= 0;
+		active = phy_init_eee(dev->phydev, false) >= 0;
 		bcmgenet_umac_writel(priv, e->tx_lpi_timer, UMAC_EEE_LPI_TIMER);
-		bcmgenet_eee_enable_set(dev, p->eee_active, e->tx_lpi_enabled);
+		bcmgenet_eee_enable_set(dev, active, e->tx_lpi_enabled);
 	}
 
 	return phy_ethtool_set_eee(dev->phydev, e);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index 97ea76d443ab..cbbe004621bc 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -30,6 +30,7 @@ static void bcmgenet_mac_config(struct net_device *dev)
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 	struct phy_device *phydev = dev->phydev;
 	u32 reg, cmd_bits = 0;
+	bool active;
 
 	/* speed */
 	if (phydev->speed == SPEED_1000)
@@ -88,9 +89,9 @@ static void bcmgenet_mac_config(struct net_device *dev)
 	}
 	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
 
-	priv->eee.eee_active = phy_init_eee(phydev, 0) >= 0;
+	active = phy_init_eee(phydev, 0) >= 0;
 	bcmgenet_eee_enable_set(dev,
-				priv->eee.eee_enabled && priv->eee.eee_active,
+				priv->eee.eee_enabled && active,
 				priv->eee.tx_lpi_enabled);
 }
 
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Fri Feb  2 01:34:10 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 02 Feb 2024 09:34:10 +0000
Subject: [PATCH net-next 6/6] net: dsa: b53: remove eee_enabled/eee_active in
 b53_get_mac_eee()
In-Reply-To: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
Message-ID: <E1rVpw2-002PeJ-Bh@rmk-PC.armlinux.org.uk>

b53_get_mac_eee() sets both eee_enabled and eee_active, and then
returns zero.

dsa_slave_get_eee(), which calls this function, will then continue to
call phylink_ethtool_get_eee(), which will return -EOPNOTSUPP if there
is no PHY present, otherwise calling phy_ethtool_get_eee() which in
turn will call genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Thus, when there is no PHY, dsa_slave_get_eee() will fail with
-EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
userspace. When there is a PHY, eee_enabled and eee_active will be
overwritten by phylib, making the setting of these members in
b53_get_mac_eee() entirely unnecessary.

Remove this code, thus simplifying b53_get_mac_eee().

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/dsa/b53/b53_common.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index adc93abf4551..9e4c9bd6abcc 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -2227,16 +2227,10 @@ EXPORT_SYMBOL(b53_eee_init);
 int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e)
 {
 	struct b53_device *dev = ds->priv;
-	struct ethtool_keee *p = &dev->ports[port].eee;
-	u16 reg;
 
 	if (is5325(dev) || is5365(dev))
 		return -EOPNOTSUPP;
 
-	b53_read16(dev, B53_EEE_PAGE, B53_EEE_LPI_INDICATE, &reg);
-	e->eee_enabled = p->eee_enabled;
-	e->eee_active = !!(reg & BIT(port));
-
 	return 0;
 }
 EXPORT_SYMBOL(b53_get_mac_eee);
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Fri Feb  2 01:33:44 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 02 Feb 2024 09:33:44 +0000
Subject: [PATCH net-next 1/6] net: stmmac: remove eee_enabled/eee_active in
 stmmac_ethtool_op_get_eee()
In-Reply-To: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
Message-ID: <E1rVpvc-002Pdp-Jj@rmk-PC.armlinux.org.uk>

stmmac_ethtool_op_get_eee() sets both eee_enabled and eee_active, and
then goes on to call phylink_ethtool_get_eee().

phylink_ethtool_get_eee() will return -EOPNOTSUPP if there is no PHY
present, otherwise calling phy_ethtool_get_eee() which in turn will call
genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Thus, when there is no PHY, stmmac_ethtool_op_get_eee() will fail with
-EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
userspace. When there is a PHY, eee_enabled and eee_active will be
overwritten by phylib, making the setting of these members in
stmmac_ethtool_op_get_eee() entirely unnecessary.

Remove this code, thus simplifying stmmac_ethtool_op_get_eee().

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index bbecb3b89535..411c3ac8cb17 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -859,8 +859,6 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev,
 	if (!priv->dma_cap.eee)
 		return -EOPNOTSUPP;
 
-	edata->eee_enabled = priv->eee_enabled;
-	edata->eee_active = priv->eee_active;
 	edata->tx_lpi_timer = priv->tx_lpi_timer;
 	edata->tx_lpi_enabled = priv->tx_lpi_enabled;
 
-- 
2.30.2



From rogerq at kernel.org  Fri Feb  2 01:36:55 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 2 Feb 2024 11:36:55 +0200
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <20240201-clad-unopposed-ccfdfe53b770@spud>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-5-rogerq@kernel.org>
 <20240201-viewpoint-upload-fb714f650ff5@spud>
 <20240201-violet-chalice-51a73f113e7b@spud>
 <20240201183522.ssj553rwefr2wuqi@iaqt7>
 <20240201-clad-unopposed-ccfdfe53b770@spud>
Message-ID: <bc3ab60f-539b-41d0-8595-6e0b55f2763d@kernel.org>



On 01/02/2024 21:13, Conor Dooley wrote:
> On Thu, Feb 01, 2024 at 12:35:22PM -0600, Bin Liu wrote:
>> On Thu, Feb 01, 2024 at 06:18:05PM +0000, Conor Dooley wrote:
>>> On Thu, Feb 01, 2024 at 06:15:20PM +0000, Conor Dooley wrote:
>>>> On Thu, Feb 01, 2024 at 02:03:31PM +0200, Roger Quadros wrote:
>>>>> So far this was not required but due to the newly identified
>>>>> Errata i2409 [1] we need to poke this register space.
>>>>>
>>>>> [1] https://www.ti.com/lit/er/sprz487d/sprz487d.pdf
>>>>>
>>>>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>>>>
>>>> Acked-by: Conor Dooley <conor.dooley at microchip.com>
>>>
>>> Actually, where is the user for this that actually pokes the register
>>> space?

https://lore.kernel.org/all/20240201121220.5523-5-rogerq at kernel.org/

>>> You're adding another register region, so I went to check how you were
>>> handling that in drivers, but there's no driver patch.
>>
>> See Roger's another patch set 'Add workaround for Errata i2409' posted
>> on 16th.
> 
> This patch should be with that series, not with these dts patches.
> 

Why not? There should be no dependency between DTS and driver implementation.

As DTS and driver will be merged by separate maintainers I thought it
would be easier for maintainers this way.

-- 
cheers,
-roger


From m.szyprowski at samsung.com  Fri Feb  2 01:43:00 2024
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Fri,  2 Feb 2024 10:43:00 +0100
Subject: No subject
References: <CGME20240202094306eucas1p2232e5a440da112a5864d7bea83ac2e25@eucas1p2.samsung.com>
Message-ID: <20240202094300.1875944-1-m.szyprowski@samsung.com>

Subject: [PATCH] ARM: multi_v7_defconfig: Enable BACKLIGHT_CLASS_DEVICE

Commit 72fee6b0a3a4 ("fbdev: Restrict FB_SH_MOBILE_LCDC to SuperH")
disabled availablity of the SH_MOBILE_LCDC driver on the RENESAS arch.
This innocent change has a significant side-effect on the ARM's
multi_v7_defconfig, because FB_BACKLIGHT symbol is no longer selected,
what in turn leaves BACKLIGHT_CLASS_DEVICE symbol selected only as
a module. The latter disables some backlight related code in the DRM
core, because the DRM core is set to be compiled-in in this defconfig.
This leaves all DRM display panels without integrated backlight control,
even if the needed modules have been properly loaded and probed.

Fix this by selecting BACKLIGHT_CLASS_DEVICE to be compiled-in in
multi_v7_defconfig.

Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
---
 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 8f7445729cd0..b2955dcb5a53 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -777,6 +777,7 @@ CONFIG_FB_EFI=y
 CONFIG_FB_WM8505=y
 CONFIG_FB_SH_MOBILE_LCDC=y
 CONFIG_FB_SIMPLE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_BACKLIGHT_AS3711=y
 CONFIG_BACKLIGHT_GPIO=y
-- 
2.34.1



From suzuki.poulose at arm.com  Fri Feb  2 01:45:41 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 2 Feb 2024 09:45:41 +0000
Subject: [PATCH v6 05/10] coresight-tpda: Add support to configure CMB
 element
In-Reply-To: <1706866364-19861-6-git-send-email-quic_taozha@quicinc.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
 <1706866364-19861-6-git-send-email-quic_taozha@quicinc.com>
Message-ID: <58e91497-1794-46d9-a935-fc23f327f32b@arm.com>

On 02/02/2024 09:32, Tao Zhang wrote:
> Read the CMB element size from the device tree. Set the register
> bit that controls the CMB element size of the corresponding port.
> 
> Reviewed-by: James Clark <james.clark at arm.com>
> Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
> ---
>   drivers/hwtracing/coresight/coresight-tpda.c | 125 +++++++++++--------
>   drivers/hwtracing/coresight/coresight-tpda.h |   6 +
>   2 files changed, 81 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
> index 4ac954f4bc13..27d567f4c8bf 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.c
> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
> @@ -18,6 +18,7 @@
>   #include "coresight-priv.h"
>   #include "coresight-tpda.h"
>   #include "coresight-trace-id.h"
> +#include "coresight-tpdm.h"
>   
>   DEFINE_CORESIGHT_DEVLIST(tpda_devs, "tpda");
>   
> @@ -28,24 +29,59 @@ static bool coresight_device_is_tpdm(struct coresight_device *csdev)
>   			CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
>   }
>   
> +static void tpdm_clear_element_size(struct coresight_device *csdev)

I just noticed this anomaly. This is supposed to be :

tpda_clear_element_size() ? I can fix it up locally.


Suzuki


> +{
> +	struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +
> +	drvdata->dsb_esize = 0;
> +	drvdata->cmb_esize = 0;
> +}
> +
> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 *val)
> +{
> +	/* Clear all relevant fields */
> +	*val &= ~(TPDA_Pn_CR_DSBSIZE | TPDA_Pn_CR_CMBSIZE);
> +
> +	if (drvdata->dsb_esize == 64)
> +		*val |= TPDA_Pn_CR_DSBSIZE;
> +	else if (drvdata->dsb_esize == 32)
> +		*val &= ~TPDA_Pn_CR_DSBSIZE;
> +
> +	if (drvdata->cmb_esize == 64)
> +		*val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
> +	else if (drvdata->cmb_esize == 32)
> +		*val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
> +	else if (drvdata->cmb_esize == 8)
> +		*val &= ~TPDA_Pn_CR_CMBSIZE;
> +}
> +
>   /*
> - * Read the DSB element size from the TPDM device
> + * Read the element size from the TPDM device. One TPDM must have at least one of the
> + * element size property.
>    * Returns
> - *    The dsb element size read from the devicetree if available.
> - *    0 - Otherwise, with a warning once.
> + *    0 - The element size property is read
> + *    Others - Cannot read the property of the element size
>    */
> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
> +				  struct coresight_device *csdev)
>   {
> -	int rc = 0;
> -	u8 size = 0;
> +	int rc = -EINVAL;
> +	struct tpdm_drvdata *tpdm_data = dev_get_drvdata(csdev->dev.parent);
> +
> +	if (tpdm_has_dsb_dataset(tpdm_data)) {
> +		rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
> +				"qcom,dsb-element-size", &drvdata->dsb_esize);
> +	}
> +	if (tpdm_has_cmb_dataset(tpdm_data)) {
> +		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
> +				"qcom,cmb-element-bits", &drvdata->cmb_esize);
> +	}
>   
> -	rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
> -			"qcom,dsb-element-size", &size);
>   	if (rc)
>   		dev_warn_once(&csdev->dev,
> -			"Failed to read TPDM DSB Element size: %d\n", rc);
> +			"Failed to read TPDM Element size: %d\n", rc);
>   
> -	return size;
> +	return rc;
>   }
>   
>   /*
> @@ -56,11 +92,12 @@ static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
>    * Parameter "inport" is used to pass in the input port number
>    * of TPDA, and it is set to -1 in the recursize call.
>    */
> -static int tpda_get_element_size(struct coresight_device *csdev,
> +static int tpda_get_element_size(struct tpda_drvdata *drvdata,
> +				 struct coresight_device *csdev,
>   				 int inport)
>   {
> -	int dsb_size = -ENOENT;
> -	int i, size;
> +	int rc = 0;
> +	int i;
>   	struct coresight_device *in;
>   
>   	for (i = 0; i < csdev->pdata->nr_inconns; i++) {
> @@ -69,30 +106,26 @@ static int tpda_get_element_size(struct coresight_device *csdev,
>   			continue;
>   
>   		/* Ignore the paths that do not match port */
> -		if (inport > 0 &&
> +		if (inport >= 0 &&
>   		    csdev->pdata->in_conns[i]->dest_port != inport)
>   			continue;
>   
>   		if (coresight_device_is_tpdm(in)) {
> -			size = tpdm_read_dsb_element_size(in);
> +			if (drvdata->dsb_esize || drvdata->cmb_esize)
> +				return -EEXIST;
> +			rc = tpdm_read_element_size(drvdata, in);
> +			if (rc)
> +				return rc;
>   		} else {
>   			/* Recurse down the path */
> -			size = tpda_get_element_size(in, -1);
> -		}
> -
> -		if (size < 0)
> -			return size;
> -
> -		if (dsb_size < 0) {
> -			/* Found a size, save it. */
> -			dsb_size = size;
> -		} else {
> -			/* Found duplicate TPDMs */
> -			return -EEXIST;
> +			rc = tpda_get_element_size(drvdata, in, -1);
> +			if (rc)
> +				return rc;
>   		}
>   	}
>   
> -	return dsb_size;
> +
> +	return rc;
>   }
>   
>   /* Settings pre enabling port control register */
> @@ -109,7 +142,7 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
>   static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
>   {
>   	u32 val;
> -	int size;
> +	int rc;
>   
>   	val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
>   	/*
> @@ -117,29 +150,21 @@ static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
>   	 * Set the bit to 0 if the size is 32
>   	 * Set the bit to 1 if the size is 64
>   	 */
> -	size = tpda_get_element_size(drvdata->csdev, port);
> -	switch (size) {
> -	case 32:
> -		val &= ~TPDA_Pn_CR_DSBSIZE;
> -		break;
> -	case 64:
> -		val |= TPDA_Pn_CR_DSBSIZE;
> -		break;
> -	case 0:
> -		return -EEXIST;
> -	case -EEXIST:
> +	tpdm_clear_element_size(drvdata->csdev);
> +	rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
> +	if (!rc && (drvdata->dsb_esize || drvdata->cmb_esize)) {
> +		tpda_set_element_size(drvdata, &val);
> +		/* Enable the port */
> +		val |= TPDA_Pn_CR_ENA;
> +		writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
> +	} else if (rc == -EEXIST)
>   		dev_warn_once(&drvdata->csdev->dev,
> -			"Detected multiple TPDMs on port %d", -EEXIST);
> -		return -EEXIST;
> -	default:
> -		return -EINVAL;
> -	}
> -
> -	/* Enable the port */
> -	val |= TPDA_Pn_CR_ENA;
> -	writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
> +			      "Detected multiple TPDMs on port %d", port);
> +	else
> +		dev_warn_once(&drvdata->csdev->dev,
> +			      "Didn't find TPDM element size");
>   
> -	return 0;
> +	return rc;
>   }
>   
>   static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
> index b3b38fd41b64..19af64120fcf 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.h
> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
> @@ -10,6 +10,8 @@
>   #define TPDA_Pn_CR(n)		(0x004 + (n * 4))
>   /* Aggregator port enable bit */
>   #define TPDA_Pn_CR_ENA		BIT(0)
> +/* Aggregator port CMB data set element size bit */
> +#define TPDA_Pn_CR_CMBSIZE		GENMASK(7, 6)
>   /* Aggregator port DSB data set element size bit */
>   #define TPDA_Pn_CR_DSBSIZE		BIT(8)
>   
> @@ -25,6 +27,8 @@
>    * @csdev:      component vitals needed by the framework.
>    * @spinlock:   lock for the drvdata value.
>    * @enable:     enable status of the component.
> + * @dsb_esize   Record the DSB element size.
> + * @cmb_esize   Record the CMB element size.
>    */
>   struct tpda_drvdata {
>   	void __iomem		*base;
> @@ -32,6 +36,8 @@ struct tpda_drvdata {
>   	struct coresight_device	*csdev;
>   	spinlock_t		spinlock;
>   	u8			atid;
> +	u8			dsb_esize;
> +	u32			cmb_esize;
>   };
>   
>   #endif  /* _CORESIGHT_CORESIGHT_TPDA_H */



From m.szyprowski at samsung.com  Fri Feb  2 01:50:44 2024
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Fri,  2 Feb 2024 10:50:44 +0100
Subject: [PATCH] ARM: multi_v7_defconfig: Enable BACKLIGHT_CLASS_DEVICE
References: <CGME20240202095104eucas1p2df4522cc4a7ee29540db1fb61d8e19fc@eucas1p2.samsung.com>
Message-ID: <20240202095044.1980696-1-m.szyprowski@samsung.com>

Commit 72fee6b0a3a4 ("fbdev: Restrict FB_SH_MOBILE_LCDC to SuperH")
disabled availablity of the SH_MOBILE_LCDC driver on the RENESAS arch.
This innocent change has a significant side-effect on the ARM's
multi_v7_defconfig, because FB_BACKLIGHT symbol is no longer selected,
what in turn leaves BACKLIGHT_CLASS_DEVICE symbol selected only as
a module. The latter disables some backlight related code in the DRM
core, because the DRM core is set to be compiled-in in this defconfig.
This leaves all DRM display panels without integrated backlight control,
even if the needed modules have been properly loaded and probed.

Fix this by selecting BACKLIGHT_CLASS_DEVICE to be compiled-in in
multi_v7_defconfig.

Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
---
 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 8f7445729cd0..b2955dcb5a53 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -777,6 +777,7 @@ CONFIG_FB_EFI=y
 CONFIG_FB_WM8505=y
 CONFIG_FB_SH_MOBILE_LCDC=y
 CONFIG_FB_SIMPLE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_BACKLIGHT_AS3711=y
 CONFIG_BACKLIGHT_GPIO=y
-- 
2.34.1



From conor.dooley at microchip.com  Fri Feb  2 01:53:11 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Fri, 2 Feb 2024 09:53:11 +0000
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <bc3ab60f-539b-41d0-8595-6e0b55f2763d@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-5-rogerq@kernel.org>
 <20240201-viewpoint-upload-fb714f650ff5@spud>
 <20240201-violet-chalice-51a73f113e7b@spud>
 <20240201183522.ssj553rwefr2wuqi@iaqt7>
 <20240201-clad-unopposed-ccfdfe53b770@spud>
 <bc3ab60f-539b-41d0-8595-6e0b55f2763d@kernel.org>
Message-ID: <20240202-unzip-whacky-bb2f151c618b@wendy>

On Fri, Feb 02, 2024 at 11:36:55AM +0200, Roger Quadros wrote:
> 
> 
> On 01/02/2024 21:13, Conor Dooley wrote:
> > On Thu, Feb 01, 2024 at 12:35:22PM -0600, Bin Liu wrote:
> >> On Thu, Feb 01, 2024 at 06:18:05PM +0000, Conor Dooley wrote:
> >>> On Thu, Feb 01, 2024 at 06:15:20PM +0000, Conor Dooley wrote:
> >>>> On Thu, Feb 01, 2024 at 02:03:31PM +0200, Roger Quadros wrote:
> >>>>> So far this was not required but due to the newly identified
> >>>>> Errata i2409 [1] we need to poke this register space.
> >>>>>
> >>>>> [1] https://www.ti.com/lit/er/sprz487d/sprz487d.pdf
> >>>>>
> >>>>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> >>>>
> >>>> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> >>>
> >>> Actually, where is the user for this that actually pokes the register
> >>> space?
> 
> https://lore.kernel.org/all/20240201121220.5523-5-rogerq at kernel.org/
> 
> >>> You're adding another register region, so I went to check how you were
> >>> handling that in drivers, but there's no driver patch.
> >>
> >> See Roger's another patch set 'Add workaround for Errata i2409' posted
> >> on 16th.
> > 
> > This patch should be with that series, not with these dts patches.
> > 
> 
> Why not? There should be no dependency between DTS and driver implementation.
> 
> As DTS and driver will be merged by separate maintainers I thought it
> would be easier for maintainers this way.

dts and driver might be merged by different people, but dt-bindings and
drivers are merged by the same people. This is a bindings patch, not a
dts patch. Look at what get_maintainer says for this file:
	Greg Kroah-Hartman <gregkh at linuxfoundation.org> (supporter:USB SUBSYSTEM)
	Rob Herring <robh+dt at kernel.org> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
	Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
	Conor Dooley <conor+dt at kernel.org> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
	Aswath Govindraju <a-govindraju at ti.com> (in file)
	linux-usb at vger.kernel.org (open list:USB SUBSYSTEM)
	devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
	linux-kernel at vger.kernel.org (open list)
Greg and linux-usb are on there, but you have not CCed them.

Being with the driver also allows bindings maintainers to check that you
don't break backwards compatibility. It also prevents me having to ask
for the driver patch, then be given just a subject line that I have to
go and look up myself!

Thanks,
Conor.

-------------- 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/20240202/5183d187/attachment.sig>

From angelogioacchino.delregno at collabora.com  Fri Feb  2 01:58:15 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 2 Feb 2024 10:58:15 +0100
Subject: [PATCH v1 00/18] Thermal: Part 1 - Introduce new structs and
 registration
In-Reply-To: <CAJZ5v0haFEGOjaMC4a8CZbQe+cxFfaB1hD60NkN297NY2TZB5A@mail.gmail.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
 <CAJZ5v0haFEGOjaMC4a8CZbQe+cxFfaB1hD60NkN297NY2TZB5A@mail.gmail.com>
Message-ID: <923499c2-1a60-42dc-b0e2-3f7d78de9d8a@collabora.com>

Il 01/02/24 19:35, Rafael J. Wysocki ha scritto:
> On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno at collabora.com> wrote:
>>
>> This series is a preparation for a bigger cleanup that will be split in
>> three parts in order to avoid immutable branches on multiple subsystems,
>> as in other parts of this series there will be changes in:
>> - drivers/acpi
>> - drivers/platform/x86
>> - drivers/power/supply
>> - drivers/net/wireless
>> - drivers/net/ethernet
>>
>> This is the first part which adds new structures and starts reorganizing
>> struct members around, plus, this migrates all of the thermal drivers
>> found in drivers/thermal/ to the new thermal_zone_device_register()
>> function, and advertises that the old registration functions are
>> deprecated and will be removed.
>>
>> The reorganization is supposed to be complete (or mostly) but...
>>   - struct thermal_zone_platform_params has a temporary name:
>>     this is done in order to avoid compile time failures for
>>     the drivers outside of drivers/thermal before migrating
>>     them to thermal_zone_device_params/thermal_zone_device_register();
>>   - struct thermal_zone_params temporarily has two duplicated members,
>>     governor_name and no_hwmon;
>>
>> Part 2 of this topic will migrate all drivers that are external to
>> drivers/thermal to thermal_zone_device_register(); I will send that
>> part only after part 1 is confirmed to be acceptable, as otherwise
>> I'd be spamming people for no reason :-)
>>
>> After all drivers will be migrated to thermal_zone_device_register(),
>> we won't have to care about changing anything outside of drivers/thermal
>> to finish this set of cleanups/changes (and no immutable branches needed)
>> and this means that...
>> Part 3 of this topic will contain the following changes:
>>   - thermal_zone_device_register_with_trips() will be removed
>>   - thermal_tripless_zone_device_register() will be removed
>>   - thermal_zone_params will be renamed to thermal_governor_ipa_params
>>     - governor_name, no_hwmon members will be removed
>>   - thermal_zone_platform_params will be renamed to thermal_zone_params
>>   - Removal of the THERMAL_NAME_LENGTH limitation for `type`
>>
>> More scheduled changes, which should end up in part 3 (at least that's
>> my intention), or eventually entirely after this cleanup topic, include:
>>   - Introduction of Thermal Zone names
>>   - Disambiguation of TZ name and type
>>   - Addition of `thermal-zones`, `thermal-zone-names` parsing for
>>     devicetrees
> 
> You really should start with this, because that's your goal.
> 
> It is quite arguable that it can be achieved without making all of the
> changes mentioned above.
> 

Actually, my initial idea was exactly that... but then there were some
discussions around it, please check [1] for the thermal-zone-names, and
[2] for the rest of the discussion.

[1]: https://lore.kernel.org/all/8d42e0f5-b2d2-471b-ada9-79f76c637abe at collabora.com/

[2]: https://lore.kernel.org/all/4dd4ac79-e8bc-4d88-92d6-6061dae42092 at collabora.com/

>>
>> ... Summarizing ...
>>
>> Part 1:
>>   - Reorganize structures (some temporary names/leftovers)
>>   - New registration function, deprecation of old ones
>>   - Migration of drivers/thermal drivers to new registration
> 
> I kind of see where this is going, but I don't agree with some of the
> changes made.
> 
> Let me comment on individual patches (which is not necessarily going
> to happen today or even tomorrow, so let me go through the entire
> series before deciding what to do next).
> 

Sure, thanks for your feedback!

Cheers,
Angelo



From patchwork-bot+netdevbpf at kernel.org  Fri Feb  2 02:00:30 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 02 Feb 2024 10:00:30 +0000
Subject: [PATCH net v3] net: stmmac: xgmac: fix handling of DPP safety error
 for DMA channels
In-Reply-To: <20240131020828.2007741-1-0x1207@gmail.com>
References: <20240131020828.2007741-1-0x1207@gmail.com>
Message-ID: <170686803017.11061.18210179700306129756.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (main)
by David S. Miller <davem at davemloft.net>:

On Wed, 31 Jan 2024 10:08:28 +0800 you wrote:
> Commit 56e58d6c8a56 ("net: stmmac: Implement Safety Features in
> XGMAC core") checks and reports safety errors, but leaves the
> Data Path Parity Errors for each channel in DMA unhandled at all, lead to
> a storm of interrupt.
> Fix it by checking and clearing the DMA_DPP_Interrupt_Status register.
> 
> Fixes: 56e58d6c8a56 ("net: stmmac: Implement Safety Features in XGMAC core")
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> 
> [...]

Here is the summary with links:
  - [net,v3] net: stmmac: xgmac: fix handling of DPP safety error for DMA channels
    https://git.kernel.org/netdev/net/c/46eba193d04f

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From angelogioacchino.delregno at collabora.com  Fri Feb  2 02:01:32 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 2 Feb 2024 11:01:32 +0100
Subject: [PATCH v1 01/18] thermal: core: Change governor name to const
 char pointer
In-Reply-To: <CAJZ5v0hOcS0Fm2-mKWtc1-0ym33XuH=B39GGL9b6MfGSqeERkQ@mail.gmail.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
 <20240130111250.185718-2-angelogioacchino.delregno@collabora.com>
 <CAJZ5v0hOcS0Fm2-mKWtc1-0ym33XuH=B39GGL9b6MfGSqeERkQ@mail.gmail.com>
Message-ID: <6f8021d5-50af-40c5-983e-cd203b1b3683@collabora.com>

Il 01/02/24 19:37, Rafael J. Wysocki ha scritto:
> On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno at collabora.com> wrote:
>>
>> All users are already assigning a const char * to the `governor_name`
>> member of struct thermal_zone_params and to the `name` member of
>> struct thermal_governor.
>> Even if users are technically wrong, it just makes more sense to change
>> this member to be a const char pointer instead of doing the other way
>> around.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> 
> Acked-by: Rafael J. Wysocki <rafael at kernel.org>
> 
> or I can pick it up right away if you want me to do that.
> 

I appreciate having less patches to carry over with new series versions.

Whatever you can take, please feel free to pick directly :-)

Thanks,
Angelo

>> ---
>>   include/linux/thermal.h | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
>> index b7a3deb372fd..65d8f92a9a0d 100644
>> --- a/include/linux/thermal.h
>> +++ b/include/linux/thermal.h
>> @@ -214,7 +214,7 @@ struct thermal_zone_device {
>>    * @governor_list:     node in thermal_governor_list (in thermal_core.c)
>>    */
>>   struct thermal_governor {
>> -       char name[THERMAL_NAME_LENGTH];
>> +       const char *name;
>>          int (*bind_to_tz)(struct thermal_zone_device *tz);
>>          void (*unbind_from_tz)(struct thermal_zone_device *tz);
>>          int (*throttle)(struct thermal_zone_device *tz,
>> @@ -226,7 +226,7 @@ struct thermal_governor {
>>
>>   /* Structure to define Thermal Zone parameters */
>>   struct thermal_zone_params {
>> -       char governor_name[THERMAL_NAME_LENGTH];
>> +       const char *governor_name;
>>
>>          /*
>>           * a boolean to indicate if the thermal to hwmon sysfs interface
>> --



From brgl at bgdev.pl  Fri Feb  2 02:02:09 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 2 Feb 2024 11:02:09 +0100
Subject: [PATCH 4/9] PCI: create platform devices for child OF
 nodes of the port node
In-Reply-To: <oiwvcvu6wdmpvhss3t7uaqkl5q73mki5pz6liuv66bap4dr2mp@jtjjwzlvt6za>
References: <20240117160748.37682-1-brgl@bgdev.pl> <20240117160748.37682-5-brgl@bgdev.pl>
 <2024011707-alibi-pregnancy-a64b@gregkh> <CAMRc=Mef7wxRccnfQ=EDLckpb1YN4DNLoC=AYL8v1LLJ=uFH2Q@mail.gmail.com>
 <2024011836-wok-treadmill-c517@gregkh> <d2he3ufg6m46zos4swww4t3peyq55blxhirsx37ou37rwqxmz2@5khumvic62je>
 <CAMRc=MeXJjpJhDjyn_P-SGo4rDnEuT9kGN5jAbRcuM_c7_aDzQ@mail.gmail.com> <oiwvcvu6wdmpvhss3t7uaqkl5q73mki5pz6liuv66bap4dr2mp@jtjjwzlvt6za>
Message-ID: <CAMRc=McT8wt6UbKtyofkJo3WcyJ-S4d2MPp8oZmjWbX6LGbETQ@mail.gmail.com>

On Fri, Feb 2, 2024 at 1:03?AM Bjorn Andersson <andersson at kernel.org> wrote:
>

[snip]

> > >
> > > I believe I missed this part of the discussion, why does this need to be
> > > a platform_device? What does the platform_bus bring that can't be
> > > provided by some other bus?
> > >
> >
> > Does it need to be a platform_device? No, of course not. Does it make
> > sense for it to be one? Yes, for two reasons:
> >
> > 1. The ATH11K WLAN module is represented on the device tree like a
> > platform device, we know it's always there and it consumes regulators
> > from another platform device. The fact it uses PCIe doesn't change the
> > fact that it is logically a platform device.
>
> Are you referring to the ath11k SNOC (firmware running on co-processor
> in the SoC) variant?
>
> Afaict the PCIe-attached ath11k is not represented as a platform_device
> in DeviceTree.
>

My bad. In RB5 it isn't (yet - I want to add it in the power
sequencing series). It is in X13s though[1].

> Said platform_device is also not a child under the PCIe bus, so this
> would be a different platform_device...
>

It's the child of the PCIe port node but there's a reason for it to
have the `compatible` property. It's because it's an entity of whose
existence we are aware before the system boots.

> > 2. The platform bus already provides us with the entire infrastructure
> > that we'd now need to duplicate (possibly adding bugs) in order to
> > introduce a "power sequencing bus".
> >
>
> This is a perfectly reasonable desire. Look at our PMICs, they are full
> of platform_devices. But through the years it's been said many times,
> that this is not a valid or good reason for using platform_devices, and
> as a result we have e.g. auxiliary bus.
>

Ok, so I cannot find this information anywhere (nor any example). Do
you happen to know if the auxiliary bus offers any software node
integration so that the `compatible` property from DT can get
seamlessly mapped to auxiliary device IDs?

> Anyway, (please) don't claim that "we need to", when it actually is "we
> want to use platform_device because that's more convenient"!

Bart

[snip]

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts#n744


From angelogioacchino.delregno at collabora.com  Fri Feb  2 02:04:39 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 2 Feb 2024 11:04:39 +0100
Subject: [PATCH v1 03/18] thermal: Directly use
 thermal_zone_platform_params for thermal_zone_device
In-Reply-To: <CAJZ5v0g6YNDAUxaWK9KfM0tt2x4wqaCap4--UjSauwmfYiEgoA@mail.gmail.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
 <20240130111250.185718-4-angelogioacchino.delregno@collabora.com>
 <CAJZ5v0g6YNDAUxaWK9KfM0tt2x4wqaCap4--UjSauwmfYiEgoA@mail.gmail.com>
Message-ID: <3e3aa372-cca4-4d3b-81e3-53abe3f384f2@collabora.com>

Il 01/02/24 20:42, Rafael J. Wysocki ha scritto:
> On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno at collabora.com> wrote:
>>
>> Remove all duplicate members from thermal_zone_device and directly
>> use the corresponding ones from struct thermal_zone_platform_params.
> 
> I totally disagree with this approach.
> 
> It does make sense to store these things in a tz directly.
> 
> 1. devdata allows the caller of the thermal zone to get to their own
> information on it conveniently.  This patch makes it harder.
> 2. It makes sense to copy type into tz to allow the zone creator to
> free the string (should they want to do that).
> 3. It would make sense to copy the contents of the trips[] table to tz
> to allow the zone creator to free their initial table.  This doesn't
> happen today, but it is in the works and your patch goes against this.
> 4. It makes sense to copy num_trips directly to tz, because it is
> closely related to trips[].
> 5. It makes sense to copy ops directly into tz, because this will
> allow zone creators to use const ops for zone registration.  Again,
> this doesn't happen today, but it is in the works and this patch goes
> against this.
> 
> As far as I'm concerned, this one is a total no-go.
> 

I'm sad for all the work that went into this - but at the same time I can also
understand your reasons.

I'll drop this one then!

Cheers,
Angelo

> Thanks!



From suzuki.poulose at arm.com  Fri Feb  2 02:06:23 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 2 Feb 2024 10:06:23 +0000
Subject: [PATCH v6 05/10] coresight-tpda: Add support to configure CMB
 element
In-Reply-To: <58e91497-1794-46d9-a935-fc23f327f32b@arm.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
 <1706866364-19861-6-git-send-email-quic_taozha@quicinc.com>
 <58e91497-1794-46d9-a935-fc23f327f32b@arm.com>
Message-ID: <265086d1-8398-49f8-b873-36194c44505a@arm.com>

On 02/02/2024 09:45, Suzuki K Poulose wrote:
> On 02/02/2024 09:32, Tao Zhang wrote:
>> Read the CMB element size from the device tree. Set the register
>> bit that controls the CMB element size of the corresponding port.
>>
>> Reviewed-by: James Clark <james.clark at arm.com>
>> Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
>> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
>> ---
>> ? drivers/hwtracing/coresight/coresight-tpda.c | 125 +++++++++++--------
>> ? drivers/hwtracing/coresight/coresight-tpda.h |?? 6 +
>> ? 2 files changed, 81 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c 
>> b/drivers/hwtracing/coresight/coresight-tpda.c
>> index 4ac954f4bc13..27d567f4c8bf 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>> @@ -18,6 +18,7 @@
>> ? #include "coresight-priv.h"
>> ? #include "coresight-tpda.h"
>> ? #include "coresight-trace-id.h"
>> +#include "coresight-tpdm.h"
>> ? DEFINE_CORESIGHT_DEVLIST(tpda_devs, "tpda");
>> @@ -28,24 +29,59 @@ static bool coresight_device_is_tpdm(struct 
>> coresight_device *csdev)
>> ????????????? CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
>> ? }
>> +static void tpdm_clear_element_size(struct coresight_device *csdev)
> 
> I just noticed this anomaly. This is supposed to be :
> 
> tpda_clear_element_size() ? I can fix it up locally.
> 
> 
> Suzuki
> 
> 
>> +{
>> +??? struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> +
>> +??? drvdata->dsb_esize = 0;
>> +??? drvdata->cmb_esize = 0;
>> +}
>> +
>> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 
>> *val)
>> +{
>> +??? /* Clear all relevant fields */
>> +??? *val &= ~(TPDA_Pn_CR_DSBSIZE | TPDA_Pn_CR_CMBSIZE);
>> +
>> +??? if (drvdata->dsb_esize == 64)
>> +??????? *val |= TPDA_Pn_CR_DSBSIZE;
>> +??? else if (drvdata->dsb_esize == 32)
>> +??????? *val &= ~TPDA_Pn_CR_DSBSIZE;
>> +
>> +??? if (drvdata->cmb_esize == 64)
>> +??????? *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
>> +??? else if (drvdata->cmb_esize == 32)
>> +??????? *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
>> +??? else if (drvdata->cmb_esize == 8)
>> +??????? *val &= ~TPDA_Pn_CR_CMBSIZE;
>> +}
>> +
>> ? /*
>> - * Read the DSB element size from the TPDM device
>> + * Read the element size from the TPDM device. One TPDM must have at 
>> least one of the
>> + * element size property.
>> ?? * Returns
>> - *??? The dsb element size read from the devicetree if available.
>> - *??? 0 - Otherwise, with a warning once.
>> + *??? 0 - The element size property is read
>> + *??? Others - Cannot read the property of the element size
>> ?? */
>> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
>> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
>> +????????????????? struct coresight_device *csdev)
>> ? {
>> -??? int rc = 0;
>> -??? u8 size = 0;
>> +??? int rc = -EINVAL;
>> +??? struct tpdm_drvdata *tpdm_data = dev_get_drvdata(csdev->dev.parent);
>> +
>> +??? if (tpdm_has_dsb_dataset(tpdm_data)) {
>> +??????? rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>> +??????????????? "qcom,dsb-element-size", &drvdata->dsb_esize);
>> +??? }
>> +??? if (tpdm_has_cmb_dataset(tpdm_data)) {
>> +??????? rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
>> +??????????????? "qcom,cmb-element-bits", &drvdata->cmb_esize);
>> +??? }
>> -??? rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>> -??????????? "qcom,dsb-element-size", &size);
>> ????? if (rc)
>> ????????? dev_warn_once(&csdev->dev,
>> -??????????? "Failed to read TPDM DSB Element size: %d\n", rc);
>> +??????????? "Failed to read TPDM Element size: %d\n", rc);
>> -??? return size;
>> +??? return rc;
>> ? }
>> ? /*
>> @@ -56,11 +92,12 @@ static int tpdm_read_dsb_element_size(struct 
>> coresight_device *csdev)
>> ?? * Parameter "inport" is used to pass in the input port number
>> ?? * of TPDA, and it is set to -1 in the recursize call.
>> ?? */
>> -static int tpda_get_element_size(struct coresight_device *csdev,
>> +static int tpda_get_element_size(struct tpda_drvdata *drvdata,
>> +???????????????? struct coresight_device *csdev,
>> ?????????????????? int inport)
>> ? {
>> -??? int dsb_size = -ENOENT;
>> -??? int i, size;
>> +??? int rc = 0;
>> +??? int i;
>> ????? struct coresight_device *in;
>> ????? for (i = 0; i < csdev->pdata->nr_inconns; i++) {
>> @@ -69,30 +106,26 @@ static int tpda_get_element_size(struct 
>> coresight_device *csdev,
>> ????????????? continue;
>> ????????? /* Ignore the paths that do not match port */
>> -??????? if (inport > 0 &&
>> +??????? if (inport >= 0 &&
>> ????????????? csdev->pdata->in_conns[i]->dest_port != inport)
>> ????????????? continue;
>> ????????? if (coresight_device_is_tpdm(in)) {
>> -??????????? size = tpdm_read_dsb_element_size(in);
>> +??????????? if (drvdata->dsb_esize || drvdata->cmb_esize)
>> +??????????????? return -EEXIST;
>> +??????????? rc = tpdm_read_element_size(drvdata, in);
>> +??????????? if (rc)
>> +??????????????? return rc;
>> ????????? } else {
>> ????????????? /* Recurse down the path */
>> -??????????? size = tpda_get_element_size(in, -1);
>> -??????? }
>> -
>> -??????? if (size < 0)
>> -??????????? return size;
>> -
>> -??????? if (dsb_size < 0) {
>> -??????????? /* Found a size, save it. */
>> -??????????? dsb_size = size;
>> -??????? } else {
>> -??????????? /* Found duplicate TPDMs */
>> -??????????? return -EEXIST;
>> +??????????? rc = tpda_get_element_size(drvdata, in, -1);
>> +??????????? if (rc)
>> +??????????????? return rc;
>> ????????? }
>> ????? }
>> -??? return dsb_size;
>> +
>> +??? return rc;
>> ? }
>> ? /* Settings pre enabling port control register */
>> @@ -109,7 +142,7 @@ static void tpda_enable_pre_port(struct 
>> tpda_drvdata *drvdata)
>> ? static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
>> ? {
>> ????? u32 val;
>> -??? int size;
>> +??? int rc;
>> ????? val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
>> ????? /*
>> @@ -117,29 +150,21 @@ static int tpda_enable_port(struct tpda_drvdata 
>> *drvdata, int port)
>> ?????? * Set the bit to 0 if the size is 32
>> ?????? * Set the bit to 1 if the size is 64
>> ?????? */

The comment above is stale, you need to remove it. I noticed it
after I applied the series for my build tests.

Please could you respin the series with the two issues above fixed ?

Suzuki


>> -??? size = tpda_get_element_size(drvdata->csdev, port);
>> -??? switch (size) {
>> -??? case 32:
>> -??????? val &= ~TPDA_Pn_CR_DSBSIZE;
>> -??????? break;
>> -??? case 64:
>> -??????? val |= TPDA_Pn_CR_DSBSIZE;
>> -??????? break;
>> -??? case 0:
>> -??????? return -EEXIST;
>> -??? case -EEXIST:
>> +??? tpdm_clear_element_size(drvdata->csdev);
>> +??? rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
>> +??? if (!rc && (drvdata->dsb_esize || drvdata->cmb_esize)) {
>> +??????? tpda_set_element_size(drvdata, &val);
>> +??????? /* Enable the port */
>> +??????? val |= TPDA_Pn_CR_ENA;
>> +??????? writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>> +??? } else if (rc == -EEXIST)
>> ????????? dev_warn_once(&drvdata->csdev->dev,
>> -??????????? "Detected multiple TPDMs on port %d", -EEXIST);
>> -??????? return -EEXIST;
>> -??? default:
>> -??????? return -EINVAL;
>> -??? }
>> -
>> -??? /* Enable the port */
>> -??? val |= TPDA_Pn_CR_ENA;
>> -??? writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>> +????????????????? "Detected multiple TPDMs on port %d", port);
>> +??? else
>> +??????? dev_warn_once(&drvdata->csdev->dev,
>> +????????????????? "Didn't find TPDM element size");
>> -??? return 0;
>> +??? return rc;
>> ? }
>> ? static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h 
>> b/drivers/hwtracing/coresight/coresight-tpda.h
>> index b3b38fd41b64..19af64120fcf 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>> @@ -10,6 +10,8 @@
>> ? #define TPDA_Pn_CR(n)??????? (0x004 + (n * 4))
>> ? /* Aggregator port enable bit */
>> ? #define TPDA_Pn_CR_ENA??????? BIT(0)
>> +/* Aggregator port CMB data set element size bit */
>> +#define TPDA_Pn_CR_CMBSIZE??????? GENMASK(7, 6)
>> ? /* Aggregator port DSB data set element size bit */
>> ? #define TPDA_Pn_CR_DSBSIZE??????? BIT(8)
>> @@ -25,6 +27,8 @@
>> ?? * @csdev:????? component vitals needed by the framework.
>> ?? * @spinlock:?? lock for the drvdata value.
>> ?? * @enable:???? enable status of the component.
>> + * @dsb_esize?? Record the DSB element size.
>> + * @cmb_esize?? Record the CMB element size.
>> ?? */
>> ? struct tpda_drvdata {
>> ????? void __iomem??????? *base;
>> @@ -32,6 +36,8 @@ struct tpda_drvdata {
>> ????? struct coresight_device??? *csdev;
>> ????? spinlock_t??????? spinlock;
>> ????? u8??????????? atid;
>> +??? u8??????????? dsb_esize;
>> +??? u32??????????? cmb_esize;
>> ? };
>> ? #endif? /* _CORESIGHT_CORESIGHT_TPDA_H */
> 



From thierry.reding at gmail.com  Fri Feb  2 02:08:12 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri,  2 Feb 2024 11:08:12 +0100
Subject: [PATCH] arm64: tegra: Set the correct PHY mode for MGBE
Message-ID: <20240202100812.866143-1-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

The PHY is configured in 10GBASE-R, so make sure to reflect that in DT.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
index ea13c4a7027c..81a82933e350 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
@@ -175,7 +175,7 @@ ethernet at 6800000 {
 			status = "okay";
 
 			phy-handle = <&mgbe0_phy>;
-			phy-mode = "usxgmii";
+			phy-mode = "10gbase-r";
 
 			mdio {
 				#address-cells = <1>;
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Fri Feb  2 02:10:51 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 2 Feb 2024 11:10:51 +0100
Subject: [PATCH v1 08/18] thermal: intel: pch_thermal: Migrate to
 thermal_zone_device_register()
In-Reply-To: <CAJZ5v0ifn7eg9WrpNF2_PB62gE_BzV2Vx5_k7ebOoZWdQNVWaQ@mail.gmail.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
 <20240130111250.185718-9-angelogioacchino.delregno@collabora.com>
 <CAJZ5v0ifn7eg9WrpNF2_PB62gE_BzV2Vx5_k7ebOoZWdQNVWaQ@mail.gmail.com>
Message-ID: <eec1d1f7-6d8f-46e9-8ce5-4d7319da7d9e@collabora.com>

Il 01/02/24 20:51, Rafael J. Wysocki ha scritto:
> On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno at collabora.com> wrote:
>>
>> The thermal API has a new thermal_zone_device_register() function which
>> is deprecating the older thermal_zone_device_register_with_trips() and
>> thermal_tripless_zone_device_register().
>>
>> Migrate to the new thermal zone device registration function.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
>>   drivers/thermal/intel/intel_pch_thermal.c | 12 ++++++++----
>>   1 file changed, 8 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/thermal/intel/intel_pch_thermal.c b/drivers/thermal/intel/intel_pch_thermal.c
>> index b3905e34c507..73d7c2ac7dbc 100644
>> --- a/drivers/thermal/intel/intel_pch_thermal.c
>> +++ b/drivers/thermal/intel/intel_pch_thermal.c
>> @@ -160,6 +160,7 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev,
>>                                     const struct pci_device_id *id)
>>   {
>>          enum pch_board_ids board_id = id->driver_data;
>> +       struct thermal_zone_device_params tzdp;
>>          struct pch_thermal_device *ptd;
>>          int nr_trips = 0;
>>          u16 trip_temp;
>> @@ -233,10 +234,13 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev,
>>
>>          nr_trips += pch_wpt_add_acpi_psv_trip(ptd, nr_trips);
>>
>> -       ptd->tzd = thermal_zone_device_register_with_trips(board_names[board_id],
>> -                                                          ptd->trips, nr_trips,
>> -                                                          0, ptd, &tzd_ops,
>> -                                                          NULL, 0, 0);
>> +       tzdp.tzp.type = board_names[board_id];
>> +       tzdp.tzp.devdata = ptd;
>> +       tzdp.tzp.trips = ptd->trips;
>> +       tzdp.tzp.num_trips = nr_trips;
>> +       tzdp.tzp.ops = &tzd_ops;
>> +
>> +       ptd->tzd = thermal_zone_device_register(&tzdp);
> 
> IMV, this should be
> 
> ptd->tzd = thermal_zone_device_register(board_names[board_id],
> ptd->trips, nr_trips, &tzd_ops, ptd, NULL);
> 
> and the tzdp variable is not necessary even.
> 

The whole point of thermal_zone_device_register() taking just one parameter was
that those older functions were taking a bit too many params, and with the
introduction of Thermal Zone name we'd be adding even more.

For intel_pch_thermal, things are more or less the same, assignments are done there
line by line... but for most of the others, IMO it's easier and schematized as a
single stack-initialized structure that could even be constified in the future.

> Analogously in the rest of the series (ie. patches [4-18/18]).
> 
>>          if (IS_ERR(ptd->tzd)) {
>>                  dev_err(&pdev->dev, "Failed to register thermal zone %s\n",
>>                          board_names[board_id]);
>> --



From rogerq at kernel.org  Fri Feb  2 02:13:22 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 2 Feb 2024 12:13:22 +0200
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <20240202-unzip-whacky-bb2f151c618b@wendy>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-5-rogerq@kernel.org>
 <20240201-viewpoint-upload-fb714f650ff5@spud>
 <20240201-violet-chalice-51a73f113e7b@spud>
 <20240201183522.ssj553rwefr2wuqi@iaqt7>
 <20240201-clad-unopposed-ccfdfe53b770@spud>
 <bc3ab60f-539b-41d0-8595-6e0b55f2763d@kernel.org>
 <20240202-unzip-whacky-bb2f151c618b@wendy>
Message-ID: <dc3c93dc-74d9-4b1c-a771-3ee6f67b5dcc@kernel.org>



On 02/02/2024 11:53, Conor Dooley wrote:
> On Fri, Feb 02, 2024 at 11:36:55AM +0200, Roger Quadros wrote:
>>
>>
>> On 01/02/2024 21:13, Conor Dooley wrote:
>>> On Thu, Feb 01, 2024 at 12:35:22PM -0600, Bin Liu wrote:
>>>> On Thu, Feb 01, 2024 at 06:18:05PM +0000, Conor Dooley wrote:
>>>>> On Thu, Feb 01, 2024 at 06:15:20PM +0000, Conor Dooley wrote:
>>>>>> On Thu, Feb 01, 2024 at 02:03:31PM +0200, Roger Quadros wrote:
>>>>>>> So far this was not required but due to the newly identified
>>>>>>> Errata i2409 [1] we need to poke this register space.
>>>>>>>
>>>>>>> [1] https://www.ti.com/lit/er/sprz487d/sprz487d.pdf
>>>>>>>
>>>>>>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>>>>>>
>>>>>> Acked-by: Conor Dooley <conor.dooley at microchip.com>
>>>>>
>>>>> Actually, where is the user for this that actually pokes the register
>>>>> space?
>>
>> https://lore.kernel.org/all/20240201121220.5523-5-rogerq at kernel.org/
>>
>>>>> You're adding another register region, so I went to check how you were
>>>>> handling that in drivers, but there's no driver patch.
>>>>
>>>> See Roger's another patch set 'Add workaround for Errata i2409' posted
>>>> on 16th.
>>>
>>> This patch should be with that series, not with these dts patches.
>>>
>>
>> Why not? There should be no dependency between DTS and driver implementation.
>>
>> As DTS and driver will be merged by separate maintainers I thought it
>> would be easier for maintainers this way.
> 
> dts and driver might be merged by different people, but dt-bindings and
> drivers are merged by the same people. This is a bindings patch, not a

If we do that then I get a bunch of dtbs_check warnings

dwc3-usb at f900000: reg: [[0, 261095424, 0, 2048], [0, 261128192, 0, 1024]] is too long

> dts patch. Look at what get_maintainer says for this file:
> 	Greg Kroah-Hartman <gregkh at linuxfoundation.org> (supporter:USB SUBSYSTEM)
> 	Rob Herring <robh+dt at kernel.org> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
> 	Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
> 	Conor Dooley <conor+dt at kernel.org> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
> 	Aswath Govindraju <a-govindraju at ti.com> (in file)
> 	linux-usb at vger.kernel.org (open list:USB SUBSYSTEM)
> 	devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
> 	linux-kernel at vger.kernel.org (open list)
> Greg and linux-usb are on there, but you have not CCed them.

My bad. Will be more careful next time.

> 
> Being with the driver also allows bindings maintainers to check that you
> don't break backwards compatibility. It also prevents me having to ask
> for the driver patch, then be given just a subject line that I have to
> go and look up myself!
> 

Sorry about that. It took a bit longer but I did point you directly to the
patch on lore.kernel.org.

-- 
cheers,
-roger


From arinc.unal at arinc9.com  Fri Feb  2 02:30:02 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Fri, 2 Feb 2024 13:30:02 +0300
Subject: [PATCH net-next v2 5/7] net: dsa: mt7530: simplify
 mt7530_setup_port6() and change to void
In-Reply-To: <20240201235704.6wxbkpli3dk4pn4w@skbuf>
References: <20240130-for-netnext-mt7530-improvements-2-v2-0-ba06f5dd9eb0@arinc9.com>
 <20240130-for-netnext-mt7530-improvements-2-v2-5-ba06f5dd9eb0@arinc9.com>
 <Zbkc4BRORWYu79GZ@makrotopia.org>
 <77c38489-8a73-4b00-bd82-48174b4d620f@arinc9.com>
 <20240201235704.6wxbkpli3dk4pn4w@skbuf>
Message-ID: <5cb18ed0-784d-42d4-9462-9f7a149cb9a4@arinc9.com>

On 2.02.2024 02:57, Vladimir Oltean wrote:
> On Tue, Jan 30, 2024 at 08:46:04PM +0300, Ar?n? ?NAL wrote:
>> would supposedly achieve 2 Gbps TX & 2 Gbps RX
> 
> Source? Commit 8efaa653a8a5 ("net: ethernet: mediatek: Add MT7621 TRGMII
> mode support") says "TRGMII speed is 1200MBit.".

That is for MT7621. It's claimed that TRGMII on MT7621 can only handle that
much. I already told you I'm doing the test on MT7623NI SoC.

MT7623 is ARM and more powerful. On that one, the PLL frequency can be set
all the way up to 362.5 MHz to provide 2900 Mbps (allegedly).

You can check the repository that the commit above links to for more
details:

https://github.com/BPI-SINOVOIP/BPI-R2-bsp/blob/591910e127cd9c811fe9e811ddb6c7278d8ed934/linux-mt/drivers/net/ethernet/raeth/Kconfig#L141
https://github.com/BPI-SINOVOIP/BPI-R2-bsp/blob/591910e127cd9c811fe9e811ddb6c7278d8ed934/linux-mt/drivers/net/ethernet/raeth/raeth_config.h#L201
https://github.com/BPI-SINOVOIP/BPI-R2-bsp/blob/591910e127cd9c811fe9e811ddb6c7278d8ed934/u-boot-mt/drivers/net/rt2880_eth.c#L2178

> 
>> Unless the MediaTek SoC ethernet driver somehow caps TRGMII to 1 Gbps,
>> I consider this whole TRGMII shenanigans a scam
> 
> I laughed :)
> 
> You have to see whether the CPU isn't in fact at 100% already, becoming
> a bottleneck before the interface speed does.

I'm happy I'm entertaining you but you've got to give me a little credit.
:)

MT7621 won't even handle 1 Gbps RX & 1 Gbps TX. But if the IP traffic is
offloaded to the packet processing engine
(drivers/net/ethernet/mediatek/mtk_ppe_offload.c), there won't be any load
on the CPU.

table ip global {
	flowtable f {
		hook ingress priority 0
		devices = { wan, lan1, lan2, lan3, lan4 }
		flags offload
	}

	chain forward {
		type filter hook forward priority 0
		ip protocol { tcp, udp } flow offload @f
	}

	chain postrouting {
		type nat hook postrouting priority 0
		oifname "wan" masquerade
	}
}

MT7623 can handle 1 Gbps RX & 1 Gbps without much CPU load. It performs the
same with or without hardware flow offloading, unlike MT7621.

The way I test this:

I do the test on a single computer. I have two gigabit ports on my
motherboard. I isolate a port by putting it on another network namespace to
do the test.

Client Network
iperf client: 192.168.2.2/24
router: 192.168.2.1/24

Server Network
router: 192.168.3.2/24
iperf server: 192.168.3.1/24

iperf Client
ip a add 192.168.2.2/24 dev enp9s0
ip l set up enp9s0
ip route add 192.168.3.1 via 192.168.2.1
iperf3 -c 192.168.3.1 --bidir -t 20

iperf Server
ip netns add iperfserver
ip link set dev eno1 netns iperfserver
ip netns exec iperfserver ip a add 192.168.3.1/24 dev eno1
ip netns exec iperfserver ip l set up eno1
ip netns exec iperfserver iperf3 -s

I did say I've done thorough testing.

> 
> Also, mtk_eth_soc.c has an interesting comment "TRGMII is not permitted
> on MT7621 if using DDR2" - not sure if applicable to your setup or not.

My device has DDR3 memory. Also, with a device tree defining trgmii on a
link of MediaTek SoC MAC, that check should prevent the mtk_eth_soc driver
from configuring the MAC if the device has DDR2 memory, no?

> 
> I just got myself an ASUS RT-AX1800U (uses the mt7621_asus_rt-ax53u.dts
> device tree AFAICT) which I'll be setting up with OpenWrt in the weeks
> to come, and on which I might also be able to run some tests from time
> to time.

Doing tests on MT7621 will be useless without utilising the PPE. To use it,
you can add these to /etc/config/firewall:

config defaults
	...
	option flow_offloading '1'
	option flow_offloading_hw '1'

Or enable software flow offloading and hardware flow offloading options if
using LuCI. When both options are enabled, hardware flow offloading will be
used.

Make sure to change the PLL frequency on the MT7530 side to 150 MHz. It
operates at the standard RGMII frequency since commit 37c218d8021e ("net:
dsa: mt7530: fix corrupt frames using trgmii on 40 MHz XTAL MT7621").

For 40MHz XTAL:
0x0640 x 0d1,2 = 0x0780

For 25MHz XTAL:
0x0a00 x 0d1,2 = 0x0c00

Ar?n?


From apatel at ventanamicro.com  Fri Feb  2 02:30:13 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Fri, 2 Feb 2024 16:00:13 +0530
Subject: [PATCH v12 22/25] irqchip: Add RISC-V advanced PLIC driver for direct-mode
In-Reply-To: <eed1ee03-923b-41e8-b99a-accc1278da6b@rivosinc.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-23-apatel@ventanamicro.com> <eed1ee03-923b-41e8-b99a-accc1278da6b@rivosinc.com>
Message-ID: <CAK9=C2U5_Ho0XUvEXRgASDKrGaVvPX68+UV2+=Z4k=cUaM3=6A@mail.gmail.com>

On Fri, Feb 2, 2024 at 2:59?PM Cl?ment L?ger <cleger at rivosinc.com> wrote:
>
>
>
> On 27/01/2024 17:17, Anup Patel wrote:
> > The RISC-V advanced interrupt architecture (AIA) specification defines
> > advanced platform-level interrupt controller (APLIC) which has two modes
> > of operation: 1) Direct mode and 2) MSI mode.
> > (For more details, refer https://github.com/riscv/riscv-aia)
> >
> > In APLIC direct-mode, wired interrupts are forwared to CPUs (or HARTs)
> > as a local external interrupt.
> >
> > We add a platform irqchip driver for the RISC-V APLIC direct-mode to
> > support RISC-V platforms having only wired interrupts.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  drivers/irqchip/Kconfig                  |   5 +
> >  drivers/irqchip/Makefile                 |   1 +
> >  drivers/irqchip/irq-riscv-aplic-direct.c | 343 +++++++++++++++++++++++
> >  drivers/irqchip/irq-riscv-aplic-main.c   | 232 +++++++++++++++
> >  drivers/irqchip/irq-riscv-aplic-main.h   |  45 +++
> >  include/linux/irqchip/riscv-aplic.h      | 119 ++++++++
> >  6 files changed, 745 insertions(+)
> >  create mode 100644 drivers/irqchip/irq-riscv-aplic-direct.c
> >  create mode 100644 drivers/irqchip/irq-riscv-aplic-main.c
> >  create mode 100644 drivers/irqchip/irq-riscv-aplic-main.h
> >  create mode 100644 include/linux/irqchip/riscv-aplic.h
> >
> > diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> > index 2fc0cb32341a..dbc8811d3764 100644
> > --- a/drivers/irqchip/Kconfig
> > +++ b/drivers/irqchip/Kconfig
> > @@ -546,6 +546,11 @@ config SIFIVE_PLIC
> >       select IRQ_DOMAIN_HIERARCHY
> >       select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
> >
> > +config RISCV_APLIC
> > +     bool
> > +     depends on RISCV
> > +     select IRQ_DOMAIN_HIERARCHY
> > +
> >  config RISCV_IMSIC
> >       bool
> >       depends on RISCV
> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> > index abca445a3229..7f8289790ed8 100644
> > --- a/drivers/irqchip/Makefile
> > +++ b/drivers/irqchip/Makefile
> > @@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)                      += irq-qcom-mpm.o
> >  obj-$(CONFIG_CSKY_MPINTC)            += irq-csky-mpintc.o
> >  obj-$(CONFIG_CSKY_APB_INTC)          += irq-csky-apb-intc.o
> >  obj-$(CONFIG_RISCV_INTC)             += irq-riscv-intc.o
> > +obj-$(CONFIG_RISCV_APLIC)            += irq-riscv-aplic-main.o irq-riscv-aplic-direct.o
> >  obj-$(CONFIG_RISCV_IMSIC)            += irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
> >  obj-$(CONFIG_SIFIVE_PLIC)            += irq-sifive-plic.o
> >  obj-$(CONFIG_IMX_IRQSTEER)           += irq-imx-irqsteer.o
> > diff --git a/drivers/irqchip/irq-riscv-aplic-direct.c b/drivers/irqchip/irq-riscv-aplic-direct.c
> > new file mode 100644
> > index 000000000000..9ed2666bfb5e
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-aplic-direct.c
> > @@ -0,0 +1,343 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
>
> 2024 ?

Well, it was the year 2022 when the patch was first posted.
Are we supposed to revise this with every passing year ?

>
> > + */
> > +
> > +#include <linux/bitops.h>
> > +#include <linux/cpu.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/irqchip.h>
> > +#include <linux/irqchip/chained_irq.h>
> > +#include <linux/irqchip/riscv-aplic.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/printk.h>
> > +#include <linux/smp.h>
> > +
> > +#include "irq-riscv-aplic-main.h"
> > +
> > +#define APLIC_DISABLE_IDELIVERY              0
> > +#define APLIC_ENABLE_IDELIVERY               1
> > +#define APLIC_DISABLE_ITHRESHOLD     1
> > +#define APLIC_ENABLE_ITHRESHOLD              0
> > +
> > +struct aplic_direct {
> > +     struct aplic_priv       priv;
> > +     struct irq_domain       *irqdomain;
> > +     struct cpumask          lmask;
> > +};
> > +
> > +struct aplic_idc {
> > +     unsigned int            hart_index;
> > +     void __iomem            *regs;
> > +     struct aplic_direct     *direct;
> > +};
> > +
> > +static unsigned int aplic_direct_parent_irq;
> > +static DEFINE_PER_CPU(struct aplic_idc, aplic_idcs);
> > +
> > +static void aplic_direct_irq_eoi(struct irq_data *d)
> > +{
> > +     /*
> > +      * The fasteoi_handler requires irq_eoi() callback hence
> > +      * provide a dummy handler.
> > +      */
> > +}
> > +
> > +#ifdef CONFIG_SMP
> > +static int aplic_direct_set_affinity(struct irq_data *d,
> > +                               const struct cpumask *mask_val, bool force)
> > +{
> > +     struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> > +     struct aplic_direct *direct =
> > +                     container_of(priv, struct aplic_direct, priv);
> > +     struct aplic_idc *idc;
> > +     unsigned int cpu, val;
> > +     struct cpumask amask;
> > +     void __iomem *target;
> > +
> > +     cpumask_and(&amask, &direct->lmask, mask_val);
> > +
> > +     if (force)
> > +             cpu = cpumask_first(&amask);
> > +     else
> > +             cpu = cpumask_any_and(&amask, cpu_online_mask);
> > +
> > +     if (cpu >= nr_cpu_ids)
> > +             return -EINVAL;
> > +
> > +     idc = per_cpu_ptr(&aplic_idcs, cpu);
> > +     target = priv->regs + APLIC_TARGET_BASE;
> > +     target += (d->hwirq - 1) * sizeof(u32);
> > +     val = idc->hart_index & APLIC_TARGET_HART_IDX_MASK;
> > +     val <<= APLIC_TARGET_HART_IDX_SHIFT;
>
> Hi Anup,
>
> You could use FIELD_PREP() instead of manual mask/shift.
>
> #define APLIC_TARGET_HART_IDX_MASK 0xfffc0000
>
> And then FIELD_PREP(APLIC_TARGET_HART_IDX_MASK, idc->hart_index)

Okay, I will update.

>
>
> > +     val |= APLIC_DEFAULT_PRIORITY;
> > +     writel(val, target);
> > +
> > +     irq_data_update_effective_affinity(d, cpumask_of(cpu));
> > +
> > +     return IRQ_SET_MASK_OK_DONE;
> > +}
> > +#endif
> > +
> > +static struct irq_chip aplic_direct_chip = {
> > +     .name           = "APLIC-DIRECT",
> > +     .irq_mask       = aplic_irq_mask,
> > +     .irq_unmask     = aplic_irq_unmask,
> > +     .irq_set_type   = aplic_irq_set_type,
> > +     .irq_eoi        = aplic_direct_irq_eoi,
> > +#ifdef CONFIG_SMP
> > +     .irq_set_affinity = aplic_direct_set_affinity,
> > +#endif
> > +     .flags          = IRQCHIP_SET_TYPE_MASKED |
> > +                       IRQCHIP_SKIP_SET_WAKE |
> > +                       IRQCHIP_MASK_ON_SUSPEND,
> > +};
> > +
> > +static int aplic_direct_irqdomain_translate(struct irq_domain *d,
> > +                                      struct irq_fwspec *fwspec,
> > +                                      unsigned long *hwirq,
> > +                                      unsigned int *type)
> > +{
> > +     struct aplic_priv *priv = d->host_data;
> > +
> > +     return aplic_irqdomain_translate(fwspec, priv->gsi_base,
> > +                                      hwirq, type);
> > +}
> > +
> > +static int aplic_direct_irqdomain_alloc(struct irq_domain *domain,
> > +                                  unsigned int virq, unsigned int nr_irqs,
> > +                                  void *arg)
> > +{
> > +     int i, ret;
> > +     unsigned int type;
> > +     irq_hw_number_t hwirq;
> > +     struct irq_fwspec *fwspec = arg;
> > +     struct aplic_priv *priv = domain->host_data;
> > +     struct aplic_direct *direct =
> > +                     container_of(priv, struct aplic_direct, priv);
> > +
> > +     ret = aplic_irqdomain_translate(fwspec, priv->gsi_base,
> > +                                     &hwirq, &type);
> > +     if (ret)
> > +             return ret;
> > +
> > +     for (i = 0; i < nr_irqs; i++) {
> > +             irq_domain_set_info(domain, virq + i, hwirq + i,
> > +                                 &aplic_direct_chip, priv,
> > +                                 handle_fasteoi_irq, NULL, NULL);
> > +             irq_set_affinity(virq + i, &direct->lmask);
> > +             /* See the reason described in aplic_msi_irqdomain_alloc() */
> > +             irq_set_status_flags(virq + i, IRQ_DISABLE_UNLAZY);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct irq_domain_ops aplic_direct_irqdomain_ops = {
> > +     .translate      = aplic_direct_irqdomain_translate,
> > +     .alloc          = aplic_direct_irqdomain_alloc,
> > +     .free           = irq_domain_free_irqs_top,
> > +};
> > +
> > +/*
> > + * To handle an APLIC direct interrupts, we just read the CLAIMI register
> > + * which will return highest priority pending interrupt and clear the
> > + * pending bit of the interrupt. This process is repeated until CLAIMI
> > + * register return zero value.
> > + */
> > +static void aplic_direct_handle_irq(struct irq_desc *desc)
> > +{
> > +     struct aplic_idc *idc = this_cpu_ptr(&aplic_idcs);
> > +     struct irq_chip *chip = irq_desc_get_chip(desc);
> > +     struct irq_domain *irqdomain = idc->direct->irqdomain;
> > +     irq_hw_number_t hw_irq;
> > +     int irq;
> > +
> > +     chained_irq_enter(chip, desc);
> > +
> > +     while ((hw_irq = readl(idc->regs + APLIC_IDC_CLAIMI))) {
> > +             hw_irq = hw_irq >> APLIC_IDC_TOPI_ID_SHIFT;
> > +             irq = irq_find_mapping(irqdomain, hw_irq);
> > +
> > +             if (unlikely(irq <= 0))
> > +                     dev_warn_ratelimited(idc->direct->priv.dev,
> > +                                          "hw_irq %lu mapping not found\n",
> > +                                          hw_irq);
> > +             else
> > +                     generic_handle_irq(irq);
> > +     }
> > +
> > +     chained_irq_exit(chip, desc);
> > +}
> > +
> > +static void aplic_idc_set_delivery(struct aplic_idc *idc, bool en)
> > +{
> > +     u32 de = (en) ? APLIC_ENABLE_IDELIVERY : APLIC_DISABLE_IDELIVERY;
> > +     u32 th = (en) ? APLIC_ENABLE_ITHRESHOLD : APLIC_DISABLE_ITHRESHOLD;
> > +
> > +     /* Priority must be less than threshold for interrupt triggering */
> > +     writel(th, idc->regs + APLIC_IDC_ITHRESHOLD);
> > +
> > +     /* Delivery must be set to 1 for interrupt triggering */
> > +     writel(de, idc->regs + APLIC_IDC_IDELIVERY);
> > +}
> > +
> > +static int aplic_direct_dying_cpu(unsigned int cpu)
> > +{
> > +     if (aplic_direct_parent_irq)
> > +             disable_percpu_irq(aplic_direct_parent_irq);
> > +
> > +     return 0;
> > +}
> > +
> > +static int aplic_direct_starting_cpu(unsigned int cpu)
> > +{
> > +     if (aplic_direct_parent_irq)
> > +             enable_percpu_irq(aplic_direct_parent_irq,
> > +                             irq_get_trigger_type(aplic_direct_parent_irq));
> > +
> > +     return 0;
> > +}
> > +
> > +static int aplic_direct_parse_parent_hwirq(struct device *dev,
> > +                                        u32 index, u32 *parent_hwirq,
> > +                                        unsigned long *parent_hartid)
> > +{
> > +     struct of_phandle_args parent;
> > +     int rc;
> > +
> > +     /*
> > +      * Currently, only OF fwnode is supported so extend this
> > +      * function for ACPI support.
> > +      */
> > +     if (!is_of_node(dev->fwnode))
> > +             return -EINVAL;
> > +
> > +     rc = of_irq_parse_one(to_of_node(dev->fwnode), index, &parent);
> > +     if (rc)
> > +             return rc;
> > +
> > +     rc = riscv_of_parent_hartid(parent.np, parent_hartid);
> > +     if (rc)
> > +             return rc;
> > +
> > +     *parent_hwirq = parent.args[0];
> > +     return 0;
> > +}
> > +
> > +int aplic_direct_setup(struct device *dev, void __iomem *regs)
> > +{
> > +     int i, j, rc, cpu, setup_count = 0;
> > +     struct aplic_direct *direct;
> > +     struct aplic_priv *priv;
> > +     struct irq_domain *domain;
> > +     unsigned long hartid;
> > +     struct aplic_idc *idc;
> > +     u32 val, hwirq;
> > +
> > +     direct = kzalloc(sizeof(*direct), GFP_KERNEL);
>
> Use devm_kzalloc() ?

Okay, I will update.

>
> > +     if (!direct)
> > +             return -ENOMEM;
> > +     priv = &direct->priv;
> > +
> > +     rc = aplic_setup_priv(priv, dev, regs);
> > +     if (rc) {
> > +             dev_err(dev, "failed to create APLIC context\n");
> > +             kfree(direct);
> > +             return rc;
> > +     }
> > +
> > +     /* Setup per-CPU IDC and target CPU mask */
> > +     for (i = 0; i < priv->nr_idcs; i++) {
> > +             rc = aplic_direct_parse_parent_hwirq(dev, i, &hwirq, &hartid);
> > +             if (rc) {
> > +                     dev_warn(dev, "parent irq for IDC%d not found\n", i);
> > +                     continue;
> > +             }
> > +
> > +             /*
> > +              * Skip interrupts other than external interrupts for
> > +              * current privilege level.
> > +              */
> > +             if (hwirq != RV_IRQ_EXT)
> > +                     continue;
> > +
> > +             cpu = riscv_hartid_to_cpuid(hartid);
> > +             if (cpu < 0) {
> > +                     dev_warn(dev, "invalid cpuid for IDC%d\n", i);
> > +                     continue;
> > +             }
> > +
> > +             cpumask_set_cpu(cpu, &direct->lmask);
> > +
> > +             idc = per_cpu_ptr(&aplic_idcs, cpu);
> > +             idc->hart_index = i;
> > +             idc->regs = priv->regs + APLIC_IDC_BASE + i * APLIC_IDC_SIZE;
> > +             idc->direct = direct;
> > +
> > +             aplic_idc_set_delivery(idc, true);
> > +
> > +             /*
> > +              * Boot cpu might not have APLIC hart_index = 0 so check
> > +              * and update target registers of all interrupts.
> > +              */
> > +             if (cpu == smp_processor_id() && idc->hart_index) {
> > +                     val = idc->hart_index & APLIC_TARGET_HART_IDX_MASK;
> > +                     val <<= APLIC_TARGET_HART_IDX_SHIFT;
>
> Ditto (FIELD_PREP)

Okay, I will update.

>
> > +                     val |= APLIC_DEFAULT_PRIORITY;
> > +                     for (j = 1; j <= priv->nr_irqs; j++)
> > +                             writel(val, priv->regs + APLIC_TARGET_BASE +
> > +                                         (j - 1) * sizeof(u32));
> > +             }
> > +
> > +             setup_count++;
> > +     }
> > +
> > +     /* Find parent domain and register chained handler */
> > +     domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(),
> > +                                       DOMAIN_BUS_ANY);
> > +     if (!aplic_direct_parent_irq && domain) {
> > +             aplic_direct_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
> > +             if (aplic_direct_parent_irq) {
> > +                     irq_set_chained_handler(aplic_direct_parent_irq,
> > +                                             aplic_direct_handle_irq);
> > +
> > +                     /*
> > +                      * Setup CPUHP notifier to enable parent
> > +                      * interrupt on all CPUs
> > +                      */
> > +                     cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
> > +                                       "irqchip/riscv/aplic:starting",
> > +                                       aplic_direct_starting_cpu,
> > +                                       aplic_direct_dying_cpu);
> > +             }
> > +     }
> > +
> > +     /* Fail if we were not able to setup IDC for any CPU */
> > +     if (!setup_count) {
> > +             kfree(direct);
>
> Shouldn't the cpuhp state also be destroyed (cpuhp_remove_state()) ?

Okay, I will update.

>
> > +             return -ENODEV;
> > +     }
> > +
> > +     /* Setup global config and interrupt delivery */
> > +     aplic_init_hw_global(priv, false);
> > +
> > +     /* Create irq domain instance for the APLIC */
> > +     direct->irqdomain = irq_domain_create_linear(dev->fwnode,
> > +                                                priv->nr_irqs + 1,
> > +                                                &aplic_direct_irqdomain_ops,
> > +                                                priv);
> > +     if (!direct->irqdomain) {
> > +             dev_err(dev, "failed to create direct irq domain\n");
> > +             kfree(direct);
> > +             return -ENOMEM;
> > +     }
> > +
> > +     /* Advertise the interrupt controller */
> > +     dev_info(dev, "%d interrupts directly connected to %d CPUs\n",
> > +              priv->nr_irqs, priv->nr_idcs);
> > +
> > +     return 0;
> > +}
> > diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
> > new file mode 100644
> > index 000000000000..87450708a733
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-aplic-main.c
> > @@ -0,0 +1,232 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
>
> 2024 ?

Same comment as above.

>
> > + */
> > +
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/printk.h>
> > +#include <linux/module.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/irqchip/riscv-aplic.h>
> > +
> > +#include "irq-riscv-aplic-main.h"
> > +
> > +void aplic_irq_unmask(struct irq_data *d)
> > +{
> > +     struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> > +
> > +     writel(d->hwirq, priv->regs + APLIC_SETIENUM);
> > +}
> > +
> > +void aplic_irq_mask(struct irq_data *d)
> > +{
> > +     struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> > +
> > +     writel(d->hwirq, priv->regs + APLIC_CLRIENUM);
> > +}
> > +
> > +int aplic_irq_set_type(struct irq_data *d, unsigned int type)
> > +{
> > +     u32 val = 0;
> > +     void __iomem *sourcecfg;
> > +     struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> > +
> > +     switch (type) {
> > +     case IRQ_TYPE_NONE:
> > +             val = APLIC_SOURCECFG_SM_INACTIVE;
> > +             break;
> > +     case IRQ_TYPE_LEVEL_LOW:
> > +             val = APLIC_SOURCECFG_SM_LEVEL_LOW;
> > +             break;
> > +     case IRQ_TYPE_LEVEL_HIGH:
> > +             val = APLIC_SOURCECFG_SM_LEVEL_HIGH;
> > +             break;
> > +     case IRQ_TYPE_EDGE_FALLING:
> > +             val = APLIC_SOURCECFG_SM_EDGE_FALL;
> > +             break;
> > +     case IRQ_TYPE_EDGE_RISING:
> > +             val = APLIC_SOURCECFG_SM_EDGE_RISE;
> > +             break;
> > +     default:
> > +             return -EINVAL;
> > +     }
> > +
> > +     sourcecfg = priv->regs + APLIC_SOURCECFG_BASE;
> > +     sourcecfg += (d->hwirq - 1) * sizeof(u32);
> > +     writel(val, sourcecfg);
> > +
> > +     return 0;
> > +}
> > +
> > +int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
> > +                           unsigned long *hwirq, unsigned int *type)
> > +{
> > +     if (WARN_ON(fwspec->param_count < 2))
> > +             return -EINVAL;
> > +     if (WARN_ON(!fwspec->param[0]))
> > +             return -EINVAL;
> > +
> > +     /* For DT, gsi_base is always zero. */
> > +     *hwirq = fwspec->param[0] - gsi_base;
> > +     *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
> > +
> > +     WARN_ON(*type == IRQ_TYPE_NONE);
> > +
> > +     return 0;
> > +}
> > +
> > +void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
> > +{
> > +     u32 val;
> > +#ifdef CONFIG_RISCV_M_MODE
> > +     u32 valH;
> > +
> > +     if (msi_mode) {
> > +             val = priv->msicfg.base_ppn;
> > +             valH = ((u64)priv->msicfg.base_ppn >> 32) &
> > +                     APLIC_xMSICFGADDRH_BAPPN_MASK;
> > +             valH |= (priv->msicfg.lhxw & APLIC_xMSICFGADDRH_LHXW_MASK)
> > +                     << APLIC_xMSICFGADDRH_LHXW_SHIFT;
> > +             valH |= (priv->msicfg.hhxw & APLIC_xMSICFGADDRH_HHXW_MASK)
> > +                     << APLIC_xMSICFGADDRH_HHXW_SHIFT;
> > +             valH |= (priv->msicfg.lhxs & APLIC_xMSICFGADDRH_LHXS_MASK)
> > +                     << APLIC_xMSICFGADDRH_LHXS_SHIFT;
> > +             valH |= (priv->msicfg.hhxs & APLIC_xMSICFGADDRH_HHXS_MASK)
> > +                     << APLIC_xMSICFGADDRH_HHXS_SHIFT;
>
> Use FIELD_PREP for all of these.

Okay, I will update.

>
> > +             writel(val, priv->regs + APLIC_xMSICFGADDR);
> > +             writel(valH, priv->regs + APLIC_xMSICFGADDRH);
> > +     }
> > +#endif
> > +
> > +     /* Setup APLIC domaincfg register */
> > +     val = readl(priv->regs + APLIC_DOMAINCFG);
> > +     val |= APLIC_DOMAINCFG_IE;
> > +     if (msi_mode)
> > +             val |= APLIC_DOMAINCFG_DM;
> > +     writel(val, priv->regs + APLIC_DOMAINCFG);
> > +     if (readl(priv->regs + APLIC_DOMAINCFG) != val)
> > +             dev_warn(priv->dev, "unable to write 0x%x in domaincfg\n",
> > +                      val);
> > +}
> > +
> > +static void aplic_init_hw_irqs(struct aplic_priv *priv)
> > +{
> > +     int i;
> > +
> > +     /* Disable all interrupts */
> > +     for (i = 0; i <= priv->nr_irqs; i += 32)
> > +             writel(-1U, priv->regs + APLIC_CLRIE_BASE +
> > +                         (i / 32) * sizeof(u32));
> > +
> > +     /* Set interrupt type and default priority for all interrupts */
> > +     for (i = 1; i <= priv->nr_irqs; i++) {
> > +             writel(0, priv->regs + APLIC_SOURCECFG_BASE +
> > +                       (i - 1) * sizeof(u32));
> > +             writel(APLIC_DEFAULT_PRIORITY,
> > +                    priv->regs + APLIC_TARGET_BASE +
> > +                    (i - 1) * sizeof(u32));
> > +     }
> > +
> > +     /* Clear APLIC domaincfg */
> > +     writel(0, priv->regs + APLIC_DOMAINCFG);
> > +}
> > +
> > +int aplic_setup_priv(struct aplic_priv *priv, struct device *dev,
> > +                  void __iomem *regs)
> > +{
> > +     struct of_phandle_args parent;
> > +     int rc;
> > +
> > +     /*
> > +      * Currently, only OF fwnode is supported so extend this
> > +      * function for ACPI support.
> > +      */
> > +     if (!is_of_node(dev->fwnode))
> > +             return -EINVAL;
> > +
> > +     /* Save device pointer and register base */
> > +     priv->dev = dev;
> > +     priv->regs = regs;
> > +
> > +     /* Find out number of interrupt sources */
> > +     rc = of_property_read_u32(to_of_node(dev->fwnode),
> > +                                          "riscv,num-sources",
> > +                                          &priv->nr_irqs);
>
> Use device_property_read_u32() which works for both ACPI and OF.

In the previous versions, we did try to unify property reading for
both ACPI and OF but MarcZ suggested to keep th ACPI and
OF probe paths totally separate hence we use OF APIs over
here because we should reach here only for OF probing.

>
> > +     if (rc) {
> > +             dev_err(dev, "failed to get number of interrupt sources\n");
> > +             return rc;
> > +     }
> > +
> > +     /*
> > +      * Find out number of IDCs based on parent interrupts
> > +      *
> > +      * If "msi-parent" property is present then we ignore the
> > +      * APLIC IDCs which forces the APLIC driver to use MSI mode.
> > +      */
> > +     if (!of_property_present(to_of_node(dev->fwnode), "msi-parent")) {
>
> device_property_present()

Same comment as above.

>
> > +             while (!of_irq_parse_one(to_of_node(dev->fwnode),
> > +                                      priv->nr_idcs, &parent))
> > +                     priv->nr_idcs++;
> > +     }
> > +
> > +     /* Setup initial state APLIC interrupts */
> > +     aplic_init_hw_irqs(priv);
> > +
> > +     return 0;
> > +}
> > +
> > +static int aplic_probe(struct platform_device *pdev)
> > +{
> > +     struct device *dev = &pdev->dev;
> > +     bool msi_mode = false;
> > +     struct resource *res;
> > +     void __iomem *regs;
> > +     int rc;
> > +
> > +     /* Map the MMIO registers */
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     if (!res) {
> > +             dev_err(dev, "failed to get MMIO resource\n");
> > +             return -EINVAL;
> > +     }
> > +     regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
> > +     if (!regs) {
> > +             dev_err(dev, "failed map MMIO registers\n");
> > +             return -ENOMEM;
> > +     }
>
> Maybe use devm_platform_ioremap_resource() since you don't need "res"
> after that.
>

Okay, I will update.

>
> > +
> > +     /*
> > +      * If msi-parent property is present then setup APLIC MSI
> > +      * mode otherwise setup APLIC direct mode.
> > +      */
> > +     if (is_of_node(dev->fwnode))
> > +             msi_mode = of_property_present(to_of_node(dev->fwnode),
> > +                                             "msi-parent");
> > +     if (msi_mode)
> > +             rc = -ENODEV;
> > +     else
> > +             rc = aplic_direct_setup(dev, regs);
> > +     if (rc) {
> > +             dev_err(dev, "failed setup APLIC in %s mode\n",
> nitpick: maybe reword it like "Failed to setup APLIC" or "APLIC setup
> failed in %s mode"

Okay.

>
> > +                     msi_mode ? "MSI" : "direct");
> > +             return rc;
>
> Remove this return.
>
> > +     }
> > +
> > +     return 0;
>
> return rc;

Okay.

>
> > +}
> > +
> > +static const struct of_device_id aplic_match[] = {
> > +     { .compatible = "riscv,aplic" },
> > +     {}
> > +};
> > +
> > +static struct platform_driver aplic_driver = {
> > +     .driver = {
> > +             .name           = "riscv-aplic",
> > +             .of_match_table = aplic_match,
> > +     },
> > +     .probe = aplic_probe,
> > +};
> > +builtin_platform_driver(aplic_driver);
> > diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h
> > new file mode 100644
> > index 000000000000..474a04229334
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-aplic-main.h
> > @@ -0,0 +1,45 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
>
> 2024 ?

Same comment as above.

>
> > + */
> > +
> > +#ifndef _IRQ_RISCV_APLIC_MAIN_H
> > +#define _IRQ_RISCV_APLIC_MAIN_H
> > +
> > +#include <linux/device.h>
> > +#include <linux/io.h>
> > +#include <linux/irq.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/fwnode.h>
> > +
> > +#define APLIC_DEFAULT_PRIORITY               1
> > +
> > +struct aplic_msicfg {
> > +     phys_addr_t             base_ppn;
> > +     u32                     hhxs;
> > +     u32                     hhxw;
> > +     u32                     lhxs;
> > +     u32                     lhxw;
> > +};
> > +
> > +struct aplic_priv {
> > +     struct device           *dev;
> > +     u32                     gsi_base;
> > +     u32                     nr_irqs;
> > +     u32                     nr_idcs;
> > +     void __iomem            *regs;
> > +     struct aplic_msicfg     msicfg;
> > +};
> > +
> > +void aplic_irq_unmask(struct irq_data *d);
> > +void aplic_irq_mask(struct irq_data *d);
> > +int aplic_irq_set_type(struct irq_data *d, unsigned int type);
> > +int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
> > +                           unsigned long *hwirq, unsigned int *type);
> > +void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode);
> > +int aplic_setup_priv(struct aplic_priv *priv, struct device *dev,
> > +                  void __iomem *regs);
> > +int aplic_direct_setup(struct device *dev, void __iomem *regs);
> > +
> > +#endif
> > diff --git a/include/linux/irqchip/riscv-aplic.h b/include/linux/irqchip/riscv-aplic.h
> > new file mode 100644
> > index 000000000000..97e198ea0109
> > --- /dev/null
> > +++ b/include/linux/irqchip/riscv-aplic.h
> > @@ -0,0 +1,119 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
> > + */
> > +#ifndef __LINUX_IRQCHIP_RISCV_APLIC_H
> > +#define __LINUX_IRQCHIP_RISCV_APLIC_H
> > +
> > +#include <linux/bitops.h>
> > +
> > +#define APLIC_MAX_IDC                        BIT(14)
> > +#define APLIC_MAX_SOURCE             1024
> > +
> > +#define APLIC_DOMAINCFG                      0x0000
> > +#define APLIC_DOMAINCFG_RDONLY               0x80000000
> > +#define APLIC_DOMAINCFG_IE           BIT(8)
> > +#define APLIC_DOMAINCFG_DM           BIT(2)
> > +#define APLIC_DOMAINCFG_BE           BIT(0)
> > +
> > +#define APLIC_SOURCECFG_BASE         0x0004
> > +#define APLIC_SOURCECFG_D            BIT(10)
> > +#define APLIC_SOURCECFG_CHILDIDX_MASK        0x000003ff
> > +#define APLIC_SOURCECFG_SM_MASK      0x00000007
> > +#define APLIC_SOURCECFG_SM_INACTIVE  0x0
> > +#define APLIC_SOURCECFG_SM_DETACH    0x1
> > +#define APLIC_SOURCECFG_SM_EDGE_RISE 0x4
> > +#define APLIC_SOURCECFG_SM_EDGE_FALL 0x5
> > +#define APLIC_SOURCECFG_SM_LEVEL_HIGH        0x6
> > +#define APLIC_SOURCECFG_SM_LEVEL_LOW 0x7
> > +
> > +#define APLIC_MMSICFGADDR            0x1bc0
> > +#define APLIC_MMSICFGADDRH           0x1bc4
> > +#define APLIC_SMSICFGADDR            0x1bc8
> > +#define APLIC_SMSICFGADDRH           0x1bcc
> > +
> > +#ifdef CONFIG_RISCV_M_MODE
> > +#define APLIC_xMSICFGADDR            APLIC_MMSICFGADDR
> > +#define APLIC_xMSICFGADDRH           APLIC_MMSICFGADDRH
> > +#else
> > +#define APLIC_xMSICFGADDR            APLIC_SMSICFGADDR
> > +#define APLIC_xMSICFGADDRH           APLIC_SMSICFGADDRH
> > +#endif
> > +
> > +#define APLIC_xMSICFGADDRH_L         BIT(31)
> > +#define APLIC_xMSICFGADDRH_HHXS_MASK 0x1f
> > +#define APLIC_xMSICFGADDRH_HHXS_SHIFT        24
> > +#define APLIC_xMSICFGADDRH_LHXS_MASK 0x7
> > +#define APLIC_xMSICFGADDRH_LHXS_SHIFT        20
> > +#define APLIC_xMSICFGADDRH_HHXW_MASK 0x7
> > +#define APLIC_xMSICFGADDRH_HHXW_SHIFT        16
> > +#define APLIC_xMSICFGADDRH_LHXW_MASK 0xf
> > +#define APLIC_xMSICFGADDRH_LHXW_SHIFT        12
> > +#define APLIC_xMSICFGADDRH_BAPPN_MASK        0xfff
> > +
> > +#define APLIC_xMSICFGADDR_PPN_SHIFT  12
> > +
> > +#define APLIC_xMSICFGADDR_PPN_HART(__lhxs) \
> > +     (BIT(__lhxs) - 1)
> > +
> > +#define APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) \
> > +     (BIT(__lhxw) - 1)
> > +#define APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs) \
> > +     ((__lhxs))
> > +#define APLIC_xMSICFGADDR_PPN_LHX(__lhxw, __lhxs) \
> > +     (APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) << \
> > +      APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs))
> > +
> > +#define APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) \
> > +     (BIT(__hhxw) - 1)
> > +#define APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs) \
> > +     ((__hhxs) + APLIC_xMSICFGADDR_PPN_SHIFT)
> > +#define APLIC_xMSICFGADDR_PPN_HHX(__hhxw, __hhxs) \
> > +     (APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) << \
> > +      APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs))
> > +
> > +#define APLIC_IRQBITS_PER_REG                32
> > +
> > +#define APLIC_SETIP_BASE             0x1c00
> > +#define APLIC_SETIPNUM                       0x1cdc
> > +
> > +#define APLIC_CLRIP_BASE             0x1d00
> > +#define APLIC_CLRIPNUM                       0x1ddc
> > +
> > +#define APLIC_SETIE_BASE             0x1e00
> > +#define APLIC_SETIENUM                       0x1edc
> > +
> > +#define APLIC_CLRIE_BASE             0x1f00
> > +#define APLIC_CLRIENUM                       0x1fdc
> > +
> > +#define APLIC_SETIPNUM_LE            0x2000
> > +#define APLIC_SETIPNUM_BE            0x2004
> > +
> > +#define APLIC_GENMSI                 0x3000
> > +
> > +#define APLIC_TARGET_BASE            0x3004
> > +#define APLIC_TARGET_HART_IDX_SHIFT  18
> > +#define APLIC_TARGET_HART_IDX_MASK   0x3fff
> > +#define APLIC_TARGET_GUEST_IDX_SHIFT 12
> > +#define APLIC_TARGET_GUEST_IDX_MASK  0x3f
> > +#define APLIC_TARGET_IPRIO_MASK      0xff
> > +#define APLIC_TARGET_EIID_MASK       0x7ff
> > +
> > +#define APLIC_IDC_BASE                       0x4000
> > +#define APLIC_IDC_SIZE                       32
> > +
> > +#define APLIC_IDC_IDELIVERY          0x00
> > +
> > +#define APLIC_IDC_IFORCE             0x04
> > +
> > +#define APLIC_IDC_ITHRESHOLD         0x08
> > +
> > +#define APLIC_IDC_TOPI                       0x18
> > +#define APLIC_IDC_TOPI_ID_SHIFT      16
> > +#define APLIC_IDC_TOPI_ID_MASK       0x3ff
> > +#define APLIC_IDC_TOPI_PRIO_MASK     0xff
> > +
> > +#define APLIC_IDC_CLAIMI             0x1c
> > +
> > +#endif
>
>
> Thanks,
>
> Cl?ment

Regards,
Anup


From cleger at rivosinc.com  Fri Feb  2 02:33:05 2024
From: cleger at rivosinc.com (=?UTF-8?B?Q2zDqW1lbnQgTMOpZ2Vy?=)
Date: Fri, 2 Feb 2024 11:33:05 +0100
Subject: [PATCH v12 22/25] irqchip: Add RISC-V advanced PLIC driver for
 direct-mode
In-Reply-To: <CAK9=C2U5_Ho0XUvEXRgASDKrGaVvPX68+UV2+=Z4k=cUaM3=6A@mail.gmail.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-23-apatel@ventanamicro.com>
 <eed1ee03-923b-41e8-b99a-accc1278da6b@rivosinc.com>
 <CAK9=C2U5_Ho0XUvEXRgASDKrGaVvPX68+UV2+=Z4k=cUaM3=6A@mail.gmail.com>
Message-ID: <f2e5fdbf-971c-4f73-af07-3c3a04bd0069@rivosinc.com>



On 02/02/2024 11:30, Anup Patel wrote:
>>> +int aplic_setup_priv(struct aplic_priv *priv, struct device *dev,
>>> +                  void __iomem *regs)
>>> +{
>>> +     struct of_phandle_args parent;
>>> +     int rc;
>>> +
>>> +     /*
>>> +      * Currently, only OF fwnode is supported so extend this
>>> +      * function for ACPI support.
>>> +      */
>>> +     if (!is_of_node(dev->fwnode))
>>> +             return -EINVAL;
>>> +
>>> +     /* Save device pointer and register base */
>>> +     priv->dev = dev;
>>> +     priv->regs = regs;
>>> +
>>> +     /* Find out number of interrupt sources */
>>> +     rc = of_property_read_u32(to_of_node(dev->fwnode),
>>> +                                          "riscv,num-sources",
>>> +                                          &priv->nr_irqs);
>>
>> Use device_property_read_u32() which works for both ACPI and OF.
> 
> In the previous versions, we did try to unify property reading for
> both ACPI and OF but MarcZ suggested to keep th ACPI and
> OF probe paths totally separate hence we use OF APIs over
> here because we should reach here only for OF probing.

Ok, indeed it makes sense. Discard that comment then !

Thanks,

Cl?ment


From krzysztof.kozlowski at linaro.org  Fri Feb  2 02:49:45 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 11:49:45 +0100
Subject: [PATCH 2/3] dt-bindings: fpga: xlnx,fpga-slave-selectmap: add DT
 schema
In-Reply-To: <1391244934.434321.1706811892834.JavaMail.zimbra@savoirfairelinux.com>
References: <20240129225602.3832449-1-charles.perry@savoirfairelinux.com>
 <20240131230542.3993409-1-charles.perry@savoirfairelinux.com>
 <20240131230542.3993409-3-charles.perry@savoirfairelinux.com>
 <d5fe1ec2-b647-4902-a599-fb866e96e9cf@linaro.org>
 <1391244934.434321.1706811892834.JavaMail.zimbra@savoirfairelinux.com>
Message-ID: <4e9360cf-2952-45e9-8c85-caa4c0d92175@linaro.org>

On 01/02/2024 19:24, Charles Perry wrote:
> 
> 
> ----- On Feb 1, 2024, at 3:07 AM, Krzysztof Kozlowski krzysztof.kozlowski at linaro.org wrote:
> 
>> On 01/02/2024 00:05, Charles Perry wrote:
>>> Document the slave SelectMAP interface of Xilinx 7 series FPGA.
>>>
>>> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
>>> ---
>>>  .../bindings/fpga/xlnx,fpga-selectmap.yaml    | 83 +++++++++++++++++++
>>>  1 file changed, 83 insertions(+)
>>>  create mode 100644
>>>  Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>>> b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>>> new file mode 100644
>>> index 0000000000000..c9a446b43cdd9
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>>> @@ -0,0 +1,83 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/fpga/xlnx,fpga-selectmap.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Xilinx SelectMAP FPGA interface
>>> +
>>> +maintainers:
>>> +  - Charles Perry <charles.perry at savoirfairelinux.com>
>>> +
>>> +description: |
>>> +  Xilinx 7 Series FPGAs support a method of loading the bitstream over a
>>> +  parallel port named the SelectMAP interface in the documentation. Only
>>> +  the x8 mode is supported where data is loaded at one byte per rising edge of
>>> +  the clock, with the MSB of each byte presented to the D0 pin.
>>> +
>>> +  Datasheets:
>>> +
>>> https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf
>>> +
>>> +allOf:
>>> +  - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml#
>>> +
>>> +properties:
>>> +  compatible:
>>> +    enum:
>>> +      - xlnx,fpga-selectmap
>>
>> Your description mentions "7 Series" which is not present in compatible
>> and title. What is exactly the product here? Interface usually is not
>> the final binding, so is this specific to some particular FPGA or SoC?
>>
>>
>> Best regards,
>> Krzysztof
> 
> This is specific to the FPGA, the 7 series encompass the following part
> family:
>  * Spartan-7 (XC7S6, XC7S15, ... XC7S100)
>  * Artix-7 (XC7A12T, XC7A15T, ... XC7A200T)
>  * Kintex-7 (XC7K70T, XC7K160T, ... XC7K480T)
>  * Virtex-7 (XC7V585T, XC7V2000T, 
>              XC7VX330T, XC7VX415T, ... XC7VX1140T,
>              XC7VH580T, XC7VH870T)
> 
> 
> The configuration guide of Xilinx [1] tells us that all those devices
> share a common programming scheme.
> 
> I do agree that having a mention of "7 series" in the compatible name
> would be beneficial as Xilinx has more FPGA than just the 7 series.
> The name was inspired from "xlnx,fpga-slave-serial" which is the compatible
> for the serial interface.
> 
> What about "xlnx,fpga-xc7-selectmap" ?
> 

I am not sure what xc7 is and how Xilinx numbers it products, but
compatibles are supposed to be device specific, not family. Common
programming model could be denoted with generic fallback, but then the
fallback could be device-specific as well, which usually we recommend.

Best regards,
Krzysztof



From cristian.marussi at arm.com  Fri Feb  2 02:56:50 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Fri, 2 Feb 2024 10:56:50 +0000
Subject: [PATCH v2] firmware: arm_scmi: Avoid to call mbox_client_txdone
 on txdone_irq mode
In-Reply-To: <20240201095754.25374-1-flash.liu@mediatek.com>
References: <20240201095754.25374-1-flash.liu@mediatek.com>
Message-ID: <ZbzKckIhn8HQv5pW@pluto>

On Thu, Feb 01, 2024 at 05:57:52PM +0800, Pin-Chuan Liu wrote:
> On txdone_irq mode, tx_tick is done from mbox_chan_txdone.
> Calling to mbox_client_txdone could get error message
> and return directly, add a check to avoid this.
> 
> Signed-off-by: Pin-Chuan Liu <flash.liu at mediatek.com>

Hi Pin-Chuan,

thanks for this, it was indeed sort of on my todo-list too, to allow MHUs
equipped with Tx-Ack IRQ to work with SCMI.

Having said that, this looks good to me in general, my only pain points
are: the fact that we have to peek into the controller structures to know
how it is configured, BUT I wouldn't know how to do it in any other
way in fact as pof now...; and the fact that there is a constant runtime
conditional check for each message sent even though the tx_ack irq presence
can be detected once for all at setup time, BUT even this is not easily
solvable as of now in the SCMI stack.

So, after all of this babbling of mine, I would say that  your patch is fine
as it is, also because it is easy to backport; next week when I am back I'll
give it a go on a couple of platforms and get back to you with a proper
review/test.

Thanks again !
Cristian


From krzysztof.kozlowski at linaro.org  Fri Feb  2 02:58:50 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 11:58:50 +0100
Subject: [PATCH RESEND] arm: topology: Fix missing clock-frequency
 property warning
In-Reply-To: <9da01fb1-9bab-436b-af49-783e44821b26@nokia.com>
References: <20240201123605.3037829-2-stefan.wiehler@nokia.com>
 <dfccb849-67b6-489b-8e83-3df1f9b29877@linaro.org>
 <9da01fb1-9bab-436b-af49-783e44821b26@nokia.com>
Message-ID: <e337bfdb-34dd-428f-b0c5-defd93b24822@linaro.org>

On 01/02/2024 16:03, Stefan Wiehler wrote:
>> Does this mean the /cpus property is like a default for when a CPU node
>> doesn't specify the clock frequency, or does it mean that the /cpus
>> property should only exist when all the values for each CPU are
>> identical and thus the individual CPU node clock frequency should
>> not be specified.
> 
> Good question, the device tree specification in Section 3.7 [1] says:
> 
>  > The /cpus node may contain properties that are common across cpu
> nodes. See Section 3.8 for details.
> 
> And in Section 3.8 [2]:
> 
>  > Properties that have identical values across cpu nodes may be placed
>  > in the /cpus node instead. A client program must first examine a
>  > specific cpu node, but if an expected property is not found then it
>  > should look at the parent /cpus node. This results in a less verbose
>  > representation of properties which are identical across all CPUs.
> 
> So I think it is pretty clear that it should only be used for 
> common/identical values.
> 
>> Aren't you adding new property? Is it already documented in the
>> bindings? After a quick look I think this is not documented.
> 
> You are right, clock-frequency is not mentioned neither in arm/cpus.yaml 
> nor in any other <arch>/cpus.yaml binding, but the DT spec has it as a 
> required property [3]. Should I add clock-frequency to all 
> <arch>/cpus.yaml bindings? Only the ARM one explicitly mentions 
> following the DT spec.

It should go to dtschema. dtschema cpu.yaml has it, so you need to
propose such to cpus.yaml, probably you could experiment with:
not:
  - required:
      - clock-frequency
  - patternProperties:
      cpu at ....
        - required:
            - clock-frequency

Anyway, you cannot just keep adding some OF properties to the code
without documenting them.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb  2 03:04:51 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 12:04:51 +0100
Subject: [EXT] Re: [PATCH v5 4/8] dt-bindings: usb: ci-hdrc-usb2: add
 restrictions for reg, interrupts, clock and clock-names properties
In-Reply-To: <DU2PR04MB88221602EB986D2C2A5BBF8D8C422@DU2PR04MB8822.eurprd04.prod.outlook.com>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-4-xu.yang_2@nxp.com>
 <a0134089-a283-488b-8d7f-3f59dd938b60@linaro.org>
 <DU2PR04MB88221602EB986D2C2A5BBF8D8C422@DU2PR04MB8822.eurprd04.prod.outlook.com>
Message-ID: <f62289f2-0f37-4e27-bc27-ab6d70dcc898@linaro.org>

On 02/02/2024 10:10, Xu Yang wrote:
> Hi Krzysztof,
> 
>>
>> On 31/01/2024 12:43, Xu Yang wrote:
>>> Change reg, interrupts, clock and clock-names as common properties and add
>>> restrictions on them for different compatibles.
>>>
>>> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
>>>
>>> ---
>>> Changes in v4:
>>>  - new patch since v3's discussion
>>>  - split the reg, interrupts, clock and clock-names properties into
>>>    common part and device-specific
>>> Changes in v5:
>>>  - keep common property unchanged
>>>  - make if-then more readable
>>>  - remove non imx part
>>> ---
>>>  .../devicetree/bindings/usb/ci-hdrc-usb2.yaml | 118 ++++++++++++++++++
>>>  1 file changed, 118 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-
>> hdrc-usb2.yaml
>>> index 3b56e0edb1c6..6ad3582051b8 100644
>>> --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
>>> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
>>> @@ -412,6 +412,124 @@ allOf:
>>>          samsung,picophy-pre-emp-curr-control: false
>>>          samsung,picophy-dc-vol-level-adjust: false
>>>
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          const: fsl,imx27-usb
>>> +    then:
>>> +      properties:
>>> +        clocks:
>>> +          minItems: 3
>>> +          maxItems: 3
>>> +        clock-names:
>>> +          minItems: 3
>>> +          maxItems: 3
>>> +          items:
>>> +            anyOf:
>>> +              - const: ipg
>>> +              - const: ahb
>>> +              - const: per
>>
>> This would be just: enum: [ipg, ahb, per], but in both cases I question
>> why the order should be flexible? Nothing in commit msg explains it.
> 
> The driver will get the clock by clock-name, then the order should not
> matter. However, these three clock-names should be present at the same
> time. I should use enum then.
> 
>>
>> Plus I will repeat myself from your v4. I don't think this is helping,
>> because the file will soon grow to umnanageable chunk. I prefer to fix
>> it at beginning, before we reach snps-schema level of complexities.
>>
>> Please define common schema, reference in this file and move IMX to own
>> file.
> 
> I'm not that familiar with dt-bindings architecture. If I define a common
> schema, then should I create imx, qcom, nvidia and other dt-binding files
> too? 

No, the rest you can leave here. Someone, maybe me, will move them some
time. The point is to move at least IMX to its own file.

Best regards,
Krzysztof



From jani.nikula at linux.intel.com  Fri Feb  2 03:04:50 2024
From: jani.nikula at linux.intel.com (Jani Nikula)
Date: Fri, 02 Feb 2024 13:04:50 +0200
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB property
In-Reply-To: <20240115143308.GA159345@toolbox>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
Message-ID: <874jerf7ot.fsf@intel.com>

On Mon, 15 Jan 2024, Sebastian Wick <sebastian.wick at redhat.com> wrote:
> On Thu, Dec 07, 2023 at 04:49:31PM +0100, Maxime Ripard wrote:
>> The i915 driver has a property to force the RGB range of an HDMI output.
>> The vc4 driver then implemented the same property with the same
>> semantics. KWin has support for it, and a PR for mutter is also there to
>> support it.
>> 
>> Both drivers implementing the same property with the same semantics,
>> plus the userspace having support for it, is proof enough that it's
>> pretty much a de-facto standard now and we can provide helpers for it.
>> 
>> Let's plumb it into the newly created HDMI connector.
>> 
>> Signed-off-by: Maxime Ripard <mripard at kernel.org>

[snip]

>> @@ -1655,6 +1678,26 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
>>  /**
>>   * DOC: HDMI connector properties
>>   *
>> + * Broadcast RGB
>> + *      Indicates the RGB Quantization Range (Full vs Limited) used.
>> + *      Infoframes will be generated according to that value.
>> + *
>> + *      The value of this property can be one of the following:
>> + *
>> + *      Automatic:
>> + *              RGB Range is selected automatically based on the mode
>> + *              according to the HDMI specifications.
>> + *
>> + *      Full:
>> + *              Full RGB Range is forced.
>> + *
>> + *      Limited 16:235:
>> + *              Limited RGB Range is forced. Unlike the name suggests,
>> + *              this works for any number of bits-per-component.
>> + *
>> + *      Drivers can set up this property by calling
>> + *      drm_connector_attach_broadcast_rgb_property().
>> + *
>
> This is a good time to document this in more detail. There might be two
> different things being affected:
>
> 1. The signalling (InfoFrame/SDP/...)
> 2. The color pipeline processing
>
> All values of Broadcast RGB always affect the color pipeline processing
> such that a full-range input to the CRTC is converted to either full- or
> limited-range, depending on what the monitor is supposed to accept.
>
> When automatic is selected, does that mean that there is no signalling,
> or that the signalling matches what the monitor is supposed to accept
> according to the spec? Also, is this really HDMI specific?

Automatic is based on the mode as described in the specs
below. Basically certain modes are expected to be broadcast range, and
others full range.

I don't remember why we don't use the full range if the display
indicates it supports selectable quantization range in Video
Capabilities Data Block. It's quite possible there are displays that
declare support but don't. Cc: Ville.

- HDMI 1.4b section 6.6 Video Quantization Ranges

- HDMI 2.1 section 7.3 Video Quantization Ranges

- DP 2.1 (and earlier) section 5.1.1.1 Video Colorimetry

- CTA-861-H (and earlier) section 5.1 Default Encoding Parameters and
  section 6.4.3 Quantization Range

> When full or limited is selected and the monitor doesn't support the
> signalling, what happens?

1) Limited selected, display expects full, colors seem washed out.

2) Full selected, display expects limited, black screen possible.

We receive the occasional bug report for 1, because there are displays
that incorrectly expect full when spec says it should be limited. We
reject the bug reports, because erring the other way can lead to black
screens.


BR,
Jani.



-- 
Jani Nikula, Intel


From krzysztof.kozlowski at linaro.org  Fri Feb  2 03:07:06 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 12:07:06 +0100
Subject: [EXT] Re: [PATCH v5 4/8] dt-bindings: usb: ci-hdrc-usb2: add
 restrictions for reg, interrupts, clock and clock-names properties
In-Reply-To: <DU2PR04MB88221602EB986D2C2A5BBF8D8C422@DU2PR04MB8822.eurprd04.prod.outlook.com>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-4-xu.yang_2@nxp.com>
 <a0134089-a283-488b-8d7f-3f59dd938b60@linaro.org>
 <DU2PR04MB88221602EB986D2C2A5BBF8D8C422@DU2PR04MB8822.eurprd04.prod.outlook.com>
Message-ID: <bcd733ab-ea9e-4ef0-a521-8e6c2023479f@linaro.org>

On 02/02/2024 10:10, Xu Yang wrote:
> Hi Krzysztof,
> 
>>
>> On 31/01/2024 12:43, Xu Yang wrote:
>>> Change reg, interrupts, clock and clock-names as common properties and add
>>> restrictions on them for different compatibles.
>>>
>>> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
>>>
>>> ---
>>> Changes in v4:
>>>  - new patch since v3's discussion
>>>  - split the reg, interrupts, clock and clock-names properties into
>>>    common part and device-specific
>>> Changes in v5:
>>>  - keep common property unchanged
>>>  - make if-then more readable
>>>  - remove non imx part
>>> ---
>>>  .../devicetree/bindings/usb/ci-hdrc-usb2.yaml | 118 ++++++++++++++++++
>>>  1 file changed, 118 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-
>> hdrc-usb2.yaml
>>> index 3b56e0edb1c6..6ad3582051b8 100644
>>> --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
>>> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
>>> @@ -412,6 +412,124 @@ allOf:
>>>          samsung,picophy-pre-emp-curr-control: false
>>>          samsung,picophy-dc-vol-level-adjust: false
>>>
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          const: fsl,imx27-usb
>>> +    then:
>>> +      properties:
>>> +        clocks:
>>> +          minItems: 3
>>> +          maxItems: 3
>>> +        clock-names:
>>> +          minItems: 3
>>> +          maxItems: 3
>>> +          items:
>>> +            anyOf:
>>> +              - const: ipg
>>> +              - const: ahb
>>> +              - const: per
>>
>> This would be just: enum: [ipg, ahb, per], but in both cases I question
>> why the order should be flexible? Nothing in commit msg explains it.
> 
> The driver will get the clock by clock-name, then the order should not
> matter. However, these three clock-names should be present at the same
> time. I should use enum then.

Forgot to answer to this.

Which driver? U-boot? OpenBSD? The one in my custom Linux kernel fork
(open-source and published on github)? Did you check all of them?

The order should be strict (or "fixed" as in non-flexible), unless there
is some reason against. If one driver does not care about order, is not
the reason.

This comment applies to all bindings so to all your future
contributions. I really keep repeating it...


Best regards,
Krzysztof



From geert at linux-m68k.org  Fri Feb  2 03:07:43 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 2 Feb 2024 12:07:43 +0100
Subject: [PATCH] ARM: multi_v7_defconfig: Enable BACKLIGHT_CLASS_DEVICE
In-Reply-To: <20240202095044.1980696-1-m.szyprowski@samsung.com>
References: <CGME20240202095104eucas1p2df4522cc4a7ee29540db1fb61d8e19fc@eucas1p2.samsung.com>
 <20240202095044.1980696-1-m.szyprowski@samsung.com>
Message-ID: <CAMuHMdVk0YOUFKy-ZjMHWCGkNMeBGU5Zs6VxtNH38emBnAR9xA@mail.gmail.com>

Hi Marek,

On Fri, Feb 2, 2024 at 10:51?AM Marek Szyprowski
<m.szyprowski at samsung.com> wrote:
> Commit 72fee6b0a3a4 ("fbdev: Restrict FB_SH_MOBILE_LCDC to SuperH")
> disabled availablity of the SH_MOBILE_LCDC driver on the RENESAS arch.
> This innocent change has a significant side-effect on the ARM's
> multi_v7_defconfig, because FB_BACKLIGHT symbol is no longer selected,
> what in turn leaves BACKLIGHT_CLASS_DEVICE symbol selected only as
> a module. The latter disables some backlight related code in the DRM

Oops, sorry for that.

> core, because the DRM core is set to be compiled-in in this defconfig.
> This leaves all DRM display panels without integrated backlight control,
> even if the needed modules have been properly loaded and probed.

Hmm, that's bad.

Is there any way to fix this in DRM?
A quick grep shows that DRM is using the full monty of
IS_{BUILTIN,ENABLED,MODULE,REACHABLE}(CONFIG_BACKLIGHT_CLASS_DEVICE).
Probably not all of them are in perfect sync?

Several DRM drivers do select BACKLIGHT_CLASS_DEVICE, but if that
does not work in the modular case, it should be fixed.

> Fix this by selecting BACKLIGHT_CLASS_DEVICE to be compiled-in in
> multi_v7_defconfig.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>

Sounds like a good interim solution.

Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

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 will at kernel.org  Fri Feb  2 03:11:08 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 2 Feb 2024 11:11:08 +0000
Subject: [GIT PULL] arm64 fixes for -rc3
Message-ID: <20240202111107.GA16598@willie-the-truck>

Hi Linus,

Please pull these two small fixes for -rc3. The first one is an
alternative fix for the SCS patching problem we thought we'd fixed in
-rc1; it turned out not to be robust with all toolchains/configs, so
this is a revert+retry which has seen some more testing.

The other one simply removes an unused header file, but I couldn't
resist the negative diffstat.

There's a crop of fpsimd/SVE/SME fixes pending which I'll probably send
next week once they've been reviewed.

Cheers,

Will

--->8

The following changes since commit 41bccc98fb7931d63d03f326a746ac4d429c1dd3:

  Linux 6.8-rc2 (2024-01-28 17:01:12 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

for you to fetch changes up to c7767f5c43df2c453af4651d1f58f489e3eb4ac1:

  arm64: vdso32: Remove unused vdso32-offsets.h (2024-01-30 11:59:17 +0000)

----------------------------------------------------------------
arm64 fixes for -rc3

- Really fix shadow call stack patching with LTO=full

- Remove unused (empty) header file generated from the compat vDSO

----------------------------------------------------------------
Ard Biesheuvel (2):
      arm64: Revert "scs: Work around full LTO issue with dynamic SCS"
      arm64: scs: Disable LTO for SCS patching code

Kevin Brodsky (1):
      arm64: vdso32: Remove unused vdso32-offsets.h

 arch/arm64/Makefile               | 2 +-
 arch/arm64/include/asm/vdso.h     | 3 ---
 arch/arm64/kernel/Makefile        | 6 +++---
 arch/arm64/kernel/vdso32/Makefile | 9 ---------
 4 files changed, 4 insertions(+), 16 deletions(-)



From hverkuil at xs4all.nl  Fri Feb  2 03:20:21 2024
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Fri, 2 Feb 2024 12:20:21 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB property
In-Reply-To: <874jerf7ot.fsf@intel.com>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox> <874jerf7ot.fsf@intel.com>
Message-ID: <c37e9225-3890-4f4d-b45c-919b907b184b@xs4all.nl>

On 02/02/2024 12:04, Jani Nikula wrote:
> On Mon, 15 Jan 2024, Sebastian Wick <sebastian.wick at redhat.com> wrote:
>> On Thu, Dec 07, 2023 at 04:49:31PM +0100, Maxime Ripard wrote:
>>> The i915 driver has a property to force the RGB range of an HDMI output.
>>> The vc4 driver then implemented the same property with the same
>>> semantics. KWin has support for it, and a PR for mutter is also there to
>>> support it.
>>>
>>> Both drivers implementing the same property with the same semantics,
>>> plus the userspace having support for it, is proof enough that it's
>>> pretty much a de-facto standard now and we can provide helpers for it.
>>>
>>> Let's plumb it into the newly created HDMI connector.
>>>
>>> Signed-off-by: Maxime Ripard <mripard at kernel.org>
> 
> [snip]
> 
>>> @@ -1655,6 +1678,26 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
>>>  /**
>>>   * DOC: HDMI connector properties
>>>   *
>>> + * Broadcast RGB
>>> + *      Indicates the RGB Quantization Range (Full vs Limited) used.
>>> + *      Infoframes will be generated according to that value.
>>> + *
>>> + *      The value of this property can be one of the following:
>>> + *
>>> + *      Automatic:
>>> + *              RGB Range is selected automatically based on the mode
>>> + *              according to the HDMI specifications.
>>> + *
>>> + *      Full:
>>> + *              Full RGB Range is forced.
>>> + *
>>> + *      Limited 16:235:
>>> + *              Limited RGB Range is forced. Unlike the name suggests,
>>> + *              this works for any number of bits-per-component.
>>> + *
>>> + *      Drivers can set up this property by calling
>>> + *      drm_connector_attach_broadcast_rgb_property().
>>> + *
>>
>> This is a good time to document this in more detail. There might be two
>> different things being affected:
>>
>> 1. The signalling (InfoFrame/SDP/...)
>> 2. The color pipeline processing
>>
>> All values of Broadcast RGB always affect the color pipeline processing
>> such that a full-range input to the CRTC is converted to either full- or
>> limited-range, depending on what the monitor is supposed to accept.
>>
>> When automatic is selected, does that mean that there is no signalling,
>> or that the signalling matches what the monitor is supposed to accept
>> according to the spec? Also, is this really HDMI specific?
> 
> Automatic is based on the mode as described in the specs
> below. Basically certain modes are expected to be broadcast range, and
> others full range.
> 
> I don't remember why we don't use the full range if the display
> indicates it supports selectable quantization range in Video
> Capabilities Data Block. It's quite possible there are displays that
> declare support but don't. Cc: Ville.

I have not seen such displays. Enabling RGB Selectable Quantization Range
is something that a vendor has to do explicitly, so it is reasonable to
expect that it works, otherwise there would be no point to that flag!

Transmitting full range if possible gives a better picture quality and
so is recommended.

> 
> - HDMI 1.4b section 6.6 Video Quantization Ranges
> 
> - HDMI 2.1 section 7.3 Video Quantization Ranges
> 
> - DP 2.1 (and earlier) section 5.1.1.1 Video Colorimetry
> 
> - CTA-861-H (and earlier) section 5.1 Default Encoding Parameters and
>   section 6.4.3 Quantization Range

Note that CTA-861-H deprecated the use of Default Range in the AVI
InfoFrame, instead the source should always signal limited or full range
in the Q field.

Regards,

	Hans

> 
>> When full or limited is selected and the monitor doesn't support the
>> signalling, what happens?
> 
> 1) Limited selected, display expects full, colors seem washed out.
> 
> 2) Full selected, display expects limited, black screen possible.
> 
> We receive the occasional bug report for 1, because there are displays
> that incorrectly expect full when spec says it should be limited. We
> reject the bug reports, because erring the other way can lead to black
> screens.
> 
> 
> BR,
> Jani.
> 
> 
> 



From luca.ceresoli at bootlin.com  Fri Feb  2 03:20:36 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Fri, 2 Feb 2024 12:20:36 +0100
Subject: [PATCH V2 2/2] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240106221907.325127-2-aford173@gmail.com>
References: <20240106221907.325127-1-aford173@gmail.com>
	<20240106221907.325127-2-aford173@gmail.com>
Message-ID: <20240202122036.7aa66d9d@booty>

Hello Adam,

On Sat,  6 Jan 2024 16:19:05 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the driver for the Samsung HDMI PHY found on the
> i.MX8MP SoC.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>

I had already tested the v2 from Lucas, however I also tested this
version which works as well, on v6.8-rc1, custom hardware based on the
Avnet i.MX8MP SMARC SoM.

Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

Generally speaking, as there are several small patch series around which
together implement HDMI on iMX8MP and similar, I think it would be much
easier fore reviewing and testing if they were grouped into a unique
series.

Luca

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From arnd at arndb.de  Fri Feb  2 03:20:19 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 02 Feb 2024 11:20:19 +0000
Subject: [PATCH] ARM: multi_v7_defconfig: Enable BACKLIGHT_CLASS_DEVICE
In-Reply-To: <CAMuHMdVk0YOUFKy-ZjMHWCGkNMeBGU5Zs6VxtNH38emBnAR9xA@mail.gmail.com>
References: <CGME20240202095104eucas1p2df4522cc4a7ee29540db1fb61d8e19fc@eucas1p2.samsung.com>
 <20240202095044.1980696-1-m.szyprowski@samsung.com>
 <CAMuHMdVk0YOUFKy-ZjMHWCGkNMeBGU5Zs6VxtNH38emBnAR9xA@mail.gmail.com>
Message-ID: <ebab6070-5f3c-4706-9fe8-11f530bb1054@app.fastmail.com>

On Fri, Feb 2, 2024, at 11:07, Geert Uytterhoeven wrote:
> On Fri, Feb 2, 2024 at 10:51?AM Marek Szyprowski <m.szyprowski at samsung.com> wrote:
>> core, because the DRM core is set to be compiled-in in this defconfig.
>> This leaves all DRM display panels without integrated backlight control,
>> even if the needed modules have been properly loaded and probed.
>
> Hmm, that's bad.
>
> Is there any way to fix this in DRM?
> A quick grep shows that DRM is using the full monty of
> IS_{BUILTIN,ENABLED,MODULE,REACHABLE}(CONFIG_BACKLIGHT_CLASS_DEVICE).
> Probably not all of them are in perfect sync?

The IS_REACHABLE() ones are almost certainly bugs, as are the
'select BACKLIGHT_CLASS_DEVICE' ones we have in drivers/gpu.

> Several DRM drivers do select BACKLIGHT_CLASS_DEVICE, but if that
> does not work in the modular case, it should be fixed.

The select should do the right thing in principle, but mixing
it with depends is what causes circular dependencies. Unfortunately
trying to fix it likely also causes those, but I think it's worth
revisiting.

It should be possible to change it like this:

- change all DRM drivers that require the class to 'depends on
  BACKLIGHT_CLASS_DEVICE'

- change all those drivers that can optionally use it to
  'depends on BACKLIGHT_CLASS_DEVICE || !BACKLIGHT_CLASS_DEVICE'
  to avoid the dependency on a loadable module

- Make BACKLIGHT_CLASS_DEVICE itself default to 'DRM' in order
  to avoid regressions in defconfig files but still make it
  possible to turn it off.

>> Fix this by selecting BACKLIGHT_CLASS_DEVICE to be compiled-in in
>> multi_v7_defconfig.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
>
> Sounds like a good interim solution.
>
> Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

Thanks, I've applied it to the soc/defconfig branch now.

     Arnd


From luca.ceresoli at bootlin.com  Fri Feb  2 03:27:37 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Fri, 2 Feb 2024 12:27:37 +0100
Subject: [PATCH V7 2/2] drm/bridge: imx: add driver for HDMI TX Parallel
 Video Interface
In-Reply-To: <20240106215146.147922-2-aford173@gmail.com>
References: <20240106215146.147922-1-aford173@gmail.com>
	<20240106215146.147922-2-aford173@gmail.com>
Message-ID: <20240202122738.7dde2801@booty>

On Sat,  6 Jan 2024 15:51:45 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This IP block is found in the HDMI subsystem of the i.MX8MP SoC. It has a
> full timing generator and can switch between different video sources. On
> the i.MX8MP however the only supported source is the LCDIF. The block
> just needs to be powered up and told about the polarity of the video
> sync signals to act in bypass mode.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v2)
> Tested-by: Marek Vasut <marex at denx.de> (v1)
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v2)
> Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> (v2)
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com> (v3)
> Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> Tested-by: Fabio Estevam <festevam at gmail.com>
> Signed-off-by: Adam Ford <aford173 at gmail.com>

On v6.8-rc1, custom hardware based on the Avnet i.MX8MP SMARC SoM.

Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

I think you can remove the Tested-by I sent for previous versions.

Luca

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From praveen.teja.kundanala at amd.com  Fri Feb  2 03:38:40 2024
From: praveen.teja.kundanala at amd.com (Praveen Teja Kundanala)
Date: Fri, 2 Feb 2024 17:08:40 +0530
Subject: [PATCH V4 1/4] firmware: xilinx: Add ZynqMP efuse access API
In-Reply-To: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
References: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
Message-ID: <20240202113843.17999-2-praveen.teja.kundanala@amd.com>

Add zynqmp_pm_efuse_access API in the ZynqMP
firmware for read/write access of efuse memory.

Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
---
 drivers/firmware/xilinx/zynqmp.c     | 25 +++++++++++++++++++++++++
 include/linux/firmware/xlnx-zynqmp.h |  8 ++++++++
 2 files changed, 33 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 79789f0563f6..9bc45357e1a8 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -3,6 +3,7 @@
  * Xilinx Zynq MPSoC Firmware layer
  *
  *  Copyright (C) 2014-2022 Xilinx, Inc.
+ *  Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
  *
  *  Michal Simek <michal.simek at amd.com>
  *  Davorin Mista <davorin.mista at aggios.com>
@@ -1384,6 +1385,30 @@ int zynqmp_pm_aes_engine(const u64 address, u32 *out)
 }
 EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine);
 
+/**
+ * zynqmp_pm_efuse_access - Provides access to efuse memory.
+ * @address:	Address of the efuse params structure
+ * @out:		Returned output value
+ *
+ * Return:	Returns status, either success or error code.
+ */
+int zynqmp_pm_efuse_access(const u64 address, u32 *out)
+{
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+	int ret;
+
+	if (!out)
+		return -EINVAL;
+
+	ret = zynqmp_pm_invoke_fn(PM_EFUSE_ACCESS, ret_payload, 2,
+				  upper_32_bits(address),
+				  lower_32_bits(address));
+	*out = ret_payload[1];
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_efuse_access);
+
 /**
  * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash
  * @address:	Address of the data/ Address of output buffer where
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index 9a7e52739251..1a069a56c961 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -3,6 +3,7 @@
  * Xilinx Zynq MPSoC Firmware layer
  *
  *  Copyright (C) 2014-2021 Xilinx
+ *  Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
  *
  *  Michal Simek <michal.simek at amd.com>
  *  Davorin Mista <davorin.mista at aggios.com>
@@ -171,6 +172,7 @@ enum pm_api_id {
 	PM_CLOCK_GETPARENT = 44,
 	PM_FPGA_READ = 46,
 	PM_SECURE_AES = 47,
+	PM_EFUSE_ACCESS = 53,
 	PM_FEATURE_CHECK = 63,
 };
 
@@ -562,6 +564,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_efuse_access(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);
@@ -749,6 +752,11 @@ static inline int zynqmp_pm_aes_engine(const u64 address, u32 *out)
 	return -ENODEV;
 }
 
+static inline int zynqmp_pm_efuse_access(const u64 address, u32 *out)
+{
+	return -ENODEV;
+}
+
 static inline int zynqmp_pm_sha_hash(const u64 address, const u32 size,
 				     const u32 flags)
 {
-- 
2.37.6



From praveen.teja.kundanala at amd.com  Fri Feb  2 03:38:39 2024
From: praveen.teja.kundanala at amd.com (Praveen Teja Kundanala)
Date: Fri, 2 Feb 2024 17:08:39 +0530
Subject: [PATCH V4 0/4] Add ZynqMP efuse access support
Message-ID: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>

 - Add ZynqMP efuse firmware API for efuse access
 - zynqmp_nvmem_probe cleanup
 - Add support to read/write ZynqMP efuse memory

The first patch depends on
https://lore.kernel.org/linux-arm-kernel/20231004094116.27128-2-jay.buddhabhatti at amd.com/

---
V3 patch link:
	https://lore.kernel.org/all/20240108052617.32510-1-praveen.teja.kundanala at amd.com/
V4 Changes:
      - Removed [2/3] dt-bindings: nvmem: Convert xlnx,zynqmp-nvmem.txt to yaml
        as it got applied https://lore.kernel.org/all/170635581622.41421.8980881999042944764.b4-ty at linaro.org/#r
      - Split patches as per comments
---

Praveen Teja Kundanala (4):
  firmware: xilinx: Add ZynqMP efuse access API
  nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
  nvmem: zynqmp_nvmem: Add support to access efuse
  MAINTAINERS: Add maintainers for ZynqMP NVMEM driver

 MAINTAINERS                          |   8 +
 drivers/firmware/xilinx/zynqmp.c     |  25 ++++
 drivers/nvmem/zynqmp_nvmem.c         | 215 +++++++++++++++++++++++----
 include/linux/firmware/xlnx-zynqmp.h |   8 +
 4 files changed, 225 insertions(+), 31 deletions(-)

-- 
2.37.6



From praveen.teja.kundanala at amd.com  Fri Feb  2 03:38:41 2024
From: praveen.teja.kundanala at amd.com (Praveen Teja Kundanala)
Date: Fri, 2 Feb 2024 17:08:41 +0530
Subject: [PATCH V4 2/4] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
In-Reply-To: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
References: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
Message-ID: <20240202113843.17999-3-praveen.teja.kundanala@amd.com>

- Remove static nvmem_config declaration
- Remove zynqmp_nvmem_data

Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
---
 drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------
 1 file changed, 12 insertions(+), 25 deletions(-)

diff --git a/drivers/nvmem/zynqmp_nvmem.c b/drivers/nvmem/zynqmp_nvmem.c
index 7f15aa89a9d0..391d8e88b270 100644
--- a/drivers/nvmem/zynqmp_nvmem.c
+++ b/drivers/nvmem/zynqmp_nvmem.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2019 Xilinx, Inc.
+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
  */
 
 #include <linux/module.h>
@@ -11,36 +12,25 @@
 
 #define SILICON_REVISION_MASK 0xF
 
-struct zynqmp_nvmem_data {
-	struct device *dev;
-	struct nvmem_device *nvmem;
-};
 
 static int zynqmp_nvmem_read(void *context, unsigned int offset,
 			     void *val, size_t bytes)
 {
+	struct device *dev = context;
 	int ret;
-	int idcode, version;
-	struct zynqmp_nvmem_data *priv = context;
+	int idcode;
+	int version;
 
 	ret = zynqmp_pm_get_chipid(&idcode, &version);
 	if (ret < 0)
 		return ret;
 
-	dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version);
+	dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
 	*(int *)val = version & SILICON_REVISION_MASK;
 
 	return 0;
 }
 
-static struct nvmem_config econfig = {
-	.name = "zynqmp-nvmem",
-	.owner = THIS_MODULE,
-	.word_size = 1,
-	.size = 1,
-	.read_only = true,
-};
-
 static const struct of_device_id zynqmp_nvmem_match[] = {
 	{ .compatible = "xlnx,zynqmp-nvmem-fw", },
 	{ /* sentinel */ },
@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_match);
 static int zynqmp_nvmem_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct zynqmp_nvmem_data *priv;
+	struct nvmem_config econfig = {};
 
-	priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	priv->dev = dev;
+	econfig.name = "zynqmp-nvmem";
+	econfig.owner = THIS_MODULE;
+	econfig.word_size = 1;
+	econfig.size = 1;
 	econfig.dev = dev;
 	econfig.add_legacy_fixed_of_cells = true;
+	econfig.read_only = true;
 	econfig.reg_read = zynqmp_nvmem_read;
-	econfig.priv = priv;
-
-	priv->nvmem = devm_nvmem_register(dev, &econfig);
 
-	return PTR_ERR_OR_ZERO(priv->nvmem);
+	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
 }
 
 static struct platform_driver zynqmp_nvmem_driver = {
-- 
2.37.6



From praveen.teja.kundanala at amd.com  Fri Feb  2 03:38:42 2024
From: praveen.teja.kundanala at amd.com (Praveen Teja Kundanala)
Date: Fri, 2 Feb 2024 17:08:42 +0530
Subject: [PATCH V4 3/4] nvmem: zynqmp_nvmem: Add support to access efuse
In-Reply-To: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
References: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
Message-ID: <20240202113843.17999-4-praveen.teja.kundanala@amd.com>

Add support to read/write efuse memory map of ZynqMP.
Below are the offsets of ZynqMP efuse memory map
	0 - SOC version(read only)
	0xC - 0xFC -ZynqMP specific purpose efuses
	0x100 - 0x17F - Physical Unclonable Function(PUF)
                efuses repurposed as user efuses

Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
---
 drivers/nvmem/zynqmp_nvmem.c | 186 +++++++++++++++++++++++++++++++++--
 1 file changed, 176 insertions(+), 10 deletions(-)

diff --git a/drivers/nvmem/zynqmp_nvmem.c b/drivers/nvmem/zynqmp_nvmem.c
index 391d8e88b270..8682adaacd69 100644
--- a/drivers/nvmem/zynqmp_nvmem.c
+++ b/drivers/nvmem/zynqmp_nvmem.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
  */
 
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/nvmem-provider.h>
 #include <linux/of.h>
@@ -11,24 +12,189 @@
 #include <linux/firmware/xlnx-zynqmp.h>
 
 #define SILICON_REVISION_MASK 0xF
+#define P_USER_0_64_UPPER_MASK	GENMASK(31, 16)
+#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0)
+#define WORD_INBYTES		4
+#define SOC_VER_SIZE		0x4
+#define EFUSE_MEMORY_SIZE	0x177
+#define UNUSED_SPACE		0x8
+#define ZYNQMP_NVMEM_SIZE	(SOC_VER_SIZE + UNUSED_SPACE + \
+				 EFUSE_MEMORY_SIZE)
+#define SOC_VERSION_OFFSET	0x0
+#define EFUSE_START_OFFSET	0xC
+#define EFUSE_END_OFFSET	0xFC
+#define EFUSE_PUF_START_OFFSET	0x100
+#define EFUSE_PUF_MID_OFFSET	0x140
+#define EFUSE_PUF_END_OFFSET	0x17F
+#define EFUSE_NOT_ENABLED	29
 
+/*
+ * efuse access type
+ */
+enum efuse_access {
+	EFUSE_READ = 0,
+	EFUSE_WRITE
+};
+
+/**
+ * struct xilinx_efuse - the basic structure
+ * @src:	address of the buffer to store the data to be write/read
+ * @size:	read/write word count
+ * @offset:	read/write offset
+ * @flag:	0 - represents efuse read and 1- represents efuse write
+ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write
+ *		1 - represents puf user fuse row number.
+ *
+ * this structure stores all the required details to
+ * read/write efuse memory.
+ */
+struct xilinx_efuse {
+	u64 src;
+	u32 size;
+	u32 offset;
+	enum efuse_access flag;
+	u32 pufuserfuse;
+};
+
+static int zynqmp_efuse_access(void *context, unsigned int offset,
+			       void *val, size_t bytes, enum efuse_access flag,
+			       unsigned int pufflag)
+{
+	struct device *dev = context;
+	struct xilinx_efuse *efuse;
+	dma_addr_t dma_addr;
+	dma_addr_t dma_buf;
+	size_t words = bytes / WORD_INBYTES;
+	int ret;
+	int value;
+	char *data;
+
+	if (bytes % WORD_INBYTES != 0) {
+		dev_err(dev, "Bytes requested should be word aligned\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (pufflag == 0 && offset % WORD_INBYTES) {
+		dev_err(dev, "Offset requested should be word aligned\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (pufflag == 1 && flag == EFUSE_WRITE) {
+		memcpy(&value, val, bytes);
+		if ((offset == EFUSE_PUF_START_OFFSET ||
+		     offset == EFUSE_PUF_MID_OFFSET) &&
+		    value & P_USER_0_64_UPPER_MASK) {
+			dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n");
+			return -EOPNOTSUPP;
+		}
+
+		if (offset == EFUSE_PUF_END_OFFSET &&
+		    (value & P_USER_127_LOWER_4_BIT_MASK)) {
+			dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n");
+			return -EOPNOTSUPP;
+		}
+	}
+
+	efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse),
+				   &dma_addr, GFP_KERNEL);
+	if (!efuse)
+		return -ENOMEM;
 
-static int zynqmp_nvmem_read(void *context, unsigned int offset,
-			     void *val, size_t bytes)
+	data = dma_alloc_coherent(dev, sizeof(bytes),
+				  &dma_buf, GFP_KERNEL);
+	if (!data) {
+		ret = -ENOMEM;
+		goto efuse_data_fail;
+	}
+
+	if (flag == EFUSE_WRITE) {
+		memcpy(data, val, bytes);
+		efuse->flag = EFUSE_WRITE;
+	} else {
+		efuse->flag = EFUSE_READ;
+	}
+
+	efuse->src = dma_buf;
+	efuse->size = words;
+	efuse->offset = offset;
+	efuse->pufuserfuse = pufflag;
+
+	zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret);
+	if (ret != 0) {
+		if (ret == EFUSE_NOT_ENABLED) {
+			dev_err(dev, "efuse access is not enabled\n");
+			ret = -EOPNOTSUPP;
+		} else {
+			dev_err(dev, "Error in efuse read %x\n", ret);
+			ret = -EPERM;
+		}
+		goto efuse_access_err;
+	}
+
+	if (flag == EFUSE_READ)
+		memcpy(val, data, bytes);
+efuse_access_err:
+	dma_free_coherent(dev, sizeof(bytes),
+			  data, dma_buf);
+efuse_data_fail:
+	dma_free_coherent(dev, sizeof(struct xilinx_efuse),
+			  efuse, dma_addr);
+
+	return ret;
+}
+
+static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size_t bytes)
 {
 	struct device *dev = context;
 	int ret;
+	int pufflag = 0;
 	int idcode;
 	int version;
 
-	ret = zynqmp_pm_get_chipid(&idcode, &version);
-	if (ret < 0)
-		return ret;
+	if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
+		pufflag = 1;
+
+	switch (offset) {
+	/* Soc version offset is zero */
+	case SOC_VERSION_OFFSET:
+		if (bytes != SOC_VER_SIZE)
+			return -EOPNOTSUPP;
+
+		ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32 *)&version);
+		if (ret < 0)
+			return ret;
+
+		dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
+		*(int *)val = version & SILICON_REVISION_MASK;
+		break;
+	/* Efuse offset starts from 0xc */
+	case EFUSE_START_OFFSET ... EFUSE_END_OFFSET:
+	case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET:
+		ret = zynqmp_efuse_access(context, offset, val,
+					  bytes, EFUSE_READ, pufflag);
+		break;
+	default:
+		*(u32 *)val = 0xDEADBEEF;
+		ret = 0;
+		break;
+	}
+
+	return ret;
+}
+
+static int zynqmp_nvmem_write(void *context,
+			      unsigned int offset, void *val, size_t bytes)
+{
+	int pufflag = 0;
+
+	if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET)
+		return -EOPNOTSUPP;
 
-	dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
-	*(int *)val = version & SILICON_REVISION_MASK;
+	if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
+		pufflag = 1;
 
-	return 0;
+	return zynqmp_efuse_access(context, offset,
+				   val, bytes, EFUSE_WRITE, pufflag);
 }
 
 static const struct of_device_id zynqmp_nvmem_match[] = {
@@ -45,11 +211,11 @@ static int zynqmp_nvmem_probe(struct platform_device *pdev)
 	econfig.name = "zynqmp-nvmem";
 	econfig.owner = THIS_MODULE;
 	econfig.word_size = 1;
-	econfig.size = 1;
+	econfig.size = ZYNQMP_NVMEM_SIZE;
 	econfig.dev = dev;
 	econfig.add_legacy_fixed_of_cells = true;
-	econfig.read_only = true;
 	econfig.reg_read = zynqmp_nvmem_read;
+	econfig.reg_write = zynqmp_nvmem_write;
 
 	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
 }
-- 
2.37.6



From praveen.teja.kundanala at amd.com  Fri Feb  2 03:38:43 2024
From: praveen.teja.kundanala at amd.com (Praveen Teja Kundanala)
Date: Fri, 2 Feb 2024 17:08:43 +0530
Subject: [PATCH V4 4/4] MAINTAINERS: Add maintainers for ZynqMP NVMEM driver
In-Reply-To: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
References: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
Message-ID: <20240202113843.17999-5-praveen.teja.kundanala@amd.com>

Add maintainers for ZynqMP NVMEM driver and driver document.

Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8d1052fa6a69..b3103e03015e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -24233,6 +24233,14 @@ M:	Harsha <harsha.harsha at amd.com>
 S:	Maintained
 F:	drivers/crypto/xilinx/zynqmp-sha.c
 
+XILINX ZYNQMP NVMEM DRIVER
+M:	Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
+M:	Kalyani Akula <kalyani.akula at amd.com>
+R:	Michal Simek <michal.simek at amd.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.yaml
+F:	drivers/nvmem/zynqmp_nvmem.c
+
 XILLYBUS DRIVER
 M:	Eli Billauer <eli.billauer at gmail.com>
 L:	linux-kernel at vger.kernel.org
-- 
2.37.6



From linux at armlinux.org.uk  Fri Feb  2 03:40:18 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 2 Feb 2024 11:40:18 +0000
Subject: [PATCH net-next v3 1/7] net: dsa: mt7530: empty default case on
 mt7530_setup_port5()
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-1-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-1-63d5adae99ca@arinc9.com>
Message-ID: <ZbzUotyQm/FyKK7G@shell.armlinux.org.uk>

On Fri, Feb 02, 2024 at 12:19:07PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> There're two code paths for setting up port 5:
> 
> mt7530_setup()
> -> mt7530_setup_port5()
> 
> mt753x_phylink_mac_config()
> -> mt753x_mac_config()
>    -> mt7530_mac_config()
>       -> mt7530_setup_port5()
> 
> On the first code path, priv->p5_intf_sel is either set to
> P5_INTF_SEL_PHY_P0 or P5_INTF_SEL_PHY_P4 when mt7530_setup_port5() is run.
> 
> On the second code path, priv->p5_intf_sel is set to P5_INTF_SEL_GMAC5 when
> mt7530_setup_port5() is run.
> 
> Empty the default case which will never run but is needed nonetheless to
> handle all the remaining enumeration values.
> 
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Thanks!

While reviewing this change, but not related to it, I notice that this
function sets the TX delay based on the RGMII interface mode. This isn't
correct. I've explained why this is this many times in the past, but
essentially it comes down to the model:


phy-mode in NIC node	Network driver	PCB		PHY
rgmii			no delays	delays		no delays
rgmii-id		no delays	no delays	tx/rx delays
rgmii-txid		no delays	no delays	tx delays
rgmii-rxid		no delays	no delays	rx delays

Then we have rx-internal-delay-ps and tx-internal-delay-ps in the NIC
node which define the RGMII delays at the local end and similar
properties for the PHY node.


So, if we take the view that, when a switch is connected to a NIC in
RGMII mode, then the phy-mode specified delays still should not impact
the local NIC.

Now, for the switch, we specify the phy-mode in the port node as well.
Consider the case of a switch port connected to a RGMII PHY. This has
to operate in exactly the same way as a normal NIC - that is, the
RGMII delays at the port should be ignored as it's the responsibility
of a PHY.

The final scenario to examine is the case of a RGMII switch port
connected to a NIC. The NIC's phy-mode has no way to be communicated
to DSA or vice versa, so neither phy-mode can impact the other side
of the RGMII link, but should only place the link into RGMII mode.
Given everything I've said above, the only way to configure RGMII
delays is via the rx-internal-delay-ps and tx-internal-delay-ps
properties. So, DSA drivers should _not_ be configuring their ports
with RGMII delays based on the RGMII phy interface mode.

The above is my purely logically reasoned point of view on this
subject. Others may have other (to me completely illogical)
interpretations that can only lead to interoperability issues.

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


From linux at armlinux.org.uk  Fri Feb  2 03:45:40 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 2 Feb 2024 11:45:40 +0000
Subject: [PATCH net-next v3 2/7] net: dsa: mt7530: call port 6 setup from
 mt7530_mac_config()
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-2-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-2-63d5adae99ca@arinc9.com>
Message-ID: <ZbzV5Ly9rv6IsmVl@shell.armlinux.org.uk>

On Fri, Feb 02, 2024 at 12:19:08PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> mt7530_pad_clk_setup() is called if port 6 is enabled. It used to do more
> things than setting up port 6. That part was moved to more appropriate
> locations, mt7530_setup() and mt7530_pll_setup().
> 
> Now that all it does is set up port 6, rename it to mt7530_setup_port6(),
> and move it to a more appropriate location, under mt7530_mac_config().
> 
> Leave an empty mt7530_pad_clk_setup() to satisfy the pad_setup function
> pointer.
> 
> This is the code path for setting up the ports before:
> 
> mt753x_phylink_mac_config()
> -> mt753x_mac_config()
>    -> mt7530_mac_config()
>       -> mt7530_setup_port5()
> -> mt753x_pad_setup()
>    -> mt7530_pad_clk_setup()
> 
> This is after:
> 
> mt753x_phylink_mac_config()
> -> mt753x_mac_config()
>    -> mt7530_mac_config()
>       -> mt7530_setup_port5()
>       -> mt7530_setup_port6()
> 
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>

I hope that the "default" case in mt7530_setup_port6() is effectively
unreachable - as long as mt7530_mac_port_get_caps() is paired with this
and only sets the interface modes in supported_interfaces that
mt7530_setup_port6() handles, then that will be fine.

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! 80Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Fri Feb  2 03:46:39 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 2 Feb 2024 11:46:39 +0000
Subject: [PATCH net-next v3 3/7] net: dsa: mt7530: remove pad_setup
 function pointer
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-3-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-3-63d5adae99ca@arinc9.com>
Message-ID: <ZbzWH1boksO1obJB@shell.armlinux.org.uk>

On Fri, Feb 02, 2024 at 12:19:09PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> The pad_setup function pointer was introduced with 88bdef8be9f6 ("net: dsa:
> mt7530: Extend device data ready for adding a new hardware"). It was being
> used to set up the core clock and port 6 of the MT7530 switch, and pll of
> the MT7531 switch.
> 
> All of these were moved to more appropriate locations, and it was never
> used for the switch on the MT7988 SoC. Therefore, this function pointer
> hasn't got a use anymore. Remove it.
> 
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> Acked-by: Daniel Golle <daniel at makrotopia.org>
> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>

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! 80Mbps down 10Mbps up. Decent connectivity at last!


From rogerq at kernel.org  Fri Feb  2 03:47:05 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 2 Feb 2024 13:47:05 +0200
Subject: [PATCH v3 2/3] arm64: dts: ti: k3-am642-evm: add ICSSG1 Ethernet
 support
In-Reply-To: <20240122113045.1711818-3-danishanwar@ti.com>
References: <20240122113045.1711818-1-danishanwar@ti.com>
 <20240122113045.1711818-3-danishanwar@ti.com>
Message-ID: <156ae282-3052-45bd-be71-8220d04e73d1@kernel.org>



On 22/01/2024 13:30, MD Danish Anwar wrote:
> ICSSG1 provides dual Gigabit Ethernet support with proper FW loaded.
> 
> The ICSSG1 MII0 (RGMII1) has DP83869 PHY attached to it. The ICSSG1 shares
> MII1 (RGMII2) PHY DP83869 with CPSW3g and it's assigned by default to
> CPSW3g. The MDIO access to MII1 (RGMII2) PHY DP83869 is controlled by MDIO
> bus switch and also assigned to CPSW3g. Therefore the ICSSG1 MII1 (RGMII2)
> port is kept disable and ICSSG1 is enabled in single MAC mode by
> default.
> 
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> ---
>  arch/arm64/boot/dts/ti/k3-am642-evm.dts | 102 ++++++++++++++++++++++++
>  1 file changed, 102 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> index 8c5651d2cf5d..c08b0223be52 100644
> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> @@ -32,6 +32,8 @@ aliases {
>  		mmc1 = &sdhci1;
>  		ethernet0 = &cpsw_port1;
>  		ethernet1 = &cpsw_port2;
> +		ethernet2 = &icssg1_emac0;
> +		ethernet3 = &icssg1_emac1;

If icssg1_emac1 is disabled by default there is no ethernet3 right?

>  	};
>  
>  	memory at 80000000 {
> @@ -229,6 +231,70 @@ transceiver2: can-phy1 {
>  		max-bitrate = <5000000>;
>  		standby-gpios = <&exp1 9 GPIO_ACTIVE_HIGH>;
>  	};
> +
> +	icssg1_eth: icssg1-eth {
> +		compatible = "ti,am642-icssg-prueth";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&icssg1_rgmii1_pins_default>;
> +
please drop blank line.

> +		sram = <&oc_sram>;
> +		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
> +		firmware-name = "ti-pruss/am64x-sr2-pru0-prueth-fw.elf",
> +				"ti-pruss/am64x-sr2-rtu0-prueth-fw.elf",
> +				"ti-pruss/am64x-sr2-txpru0-prueth-fw.elf",
> +				"ti-pruss/am64x-sr2-pru1-prueth-fw.elf",
> +				"ti-pruss/am64x-sr2-rtu1-prueth-fw.elf",
> +				"ti-pruss/am64x-sr2-txpru1-prueth-fw.elf";
> +
> +		ti,pruss-gp-mux-sel = <2>,	/* MII mode */
> +				      <2>,
> +				      <2>,
> +				      <2>,	/* MII mode */
> +				      <2>,
> +				      <2>;
> +

please drop blank line.

> +		ti,mii-g-rt = <&icssg1_mii_g_rt>;
> +		ti,mii-rt = <&icssg1_mii_rt>;
> +		ti,iep = <&icssg1_iep0>,  <&icssg1_iep1>;
> +
please drop blank line.

> +		interrupt-parent = <&icssg1_intc>;
> +		interrupts = <24 0 2>, <25 1 3>;
> +		interrupt-names = "tx_ts0", "tx_ts1";
> +
please drop blank line.

> +		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
> +		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
> +		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
> +		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
> +		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
> +		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
> +		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
> +			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
> +			    "rx0", "rx1";
> +
> +		ethernet-ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			icssg1_emac0: port at 0 {
> +				reg = <0>;
> +				phy-handle = <&icssg1_phy1>;
> +				phy-mode = "rgmii-id";
> +				ti,syscon-rgmii-delay = <&main_conf 0x4110>;
> +				/* Filled in by bootloader */
> +				local-mac-address = [00 00 00 00 00 00];
> +			};
> +			icssg1_emac1: port at 1 {
> +				reg = <1>;
> +				ti,syscon-rgmii-delay = <&main_conf 0x4114>;
> +				/* Filled in by bootloader */
> +				local-mac-address = [00 00 00 00 00 00];
> +				status = "disabled";
> +			};
> +		};
> +	};
>  };
>  
>  &main_pmx0 {
> @@ -383,6 +449,30 @@ ddr_vtt_pins_default: ddr-vtt-default-pins {
>  			AM64X_IOPAD(0x0030, PIN_OUTPUT_PULLUP, 7) /* (L18) OSPI0_CSN1.GPIO0_12 */
>  		>;
>  	};
> +
> +	icssg1_mdio1_pins_default: icssg1-mdio1-default-pins {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0) /* (Y6) PRG1_MDIO0_MDC */
> +			AM64X_IOPAD(0x0158, PIN_INPUT, 0) /* (AA6) PRG1_MDIO0_MDIO */
> +		>;
> +	};
> +
> +	icssg1_rgmii1_pins_default: icssg1-rgmii1-default-pins{
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x00b8, PIN_INPUT, 2) /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
> +			AM64X_IOPAD(0x00bc, PIN_INPUT, 2) /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
> +			AM64X_IOPAD(0x00c0, PIN_INPUT, 2) /* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
> +			AM64X_IOPAD(0x00c4, PIN_INPUT, 2) /* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
> +			AM64X_IOPAD(0x00d0, PIN_INPUT, 2) /* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
> +			AM64X_IOPAD(0x00c8, PIN_INPUT, 2) /* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
> +			AM64X_IOPAD(0x00e4, PIN_INPUT, 2) /* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
> +			AM64X_IOPAD(0x00e8, PIN_INPUT, 2) /* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
> +			AM64X_IOPAD(0x00ec, PIN_INPUT, 2) /* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
> +			AM64X_IOPAD(0x00f0, PIN_INPUT, 2) /* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
> +			AM64X_IOPAD(0x00f8, PIN_INPUT, 2) /* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
> +			AM64X_IOPAD(0x00f4, PIN_INPUT, 2) /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
> +		>;
> +	};
>  };
>  
>  &main_uart0 {
> @@ -731,3 +821,15 @@ &main_mcan1 {
>  	pinctrl-0 = <&main_mcan1_pins_default>;
>  	phys = <&transceiver2>;
>  };
> +
> +&icssg1_mdio {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&icssg1_mdio1_pins_default>;
> +
> +	icssg1_phy1: ethernet-phy at f {
> +		reg = <0xf>;
> +		tx-internal-delay-ps = <250>;
> +		rx-internal-delay-ps = <2000>;
> +	};
> +};

-- 
cheers,
-roger


From angelogioacchino.delregno at collabora.com  Fri Feb  2 03:48:19 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri,  2 Feb 2024 12:48:19 +0100
Subject: [PATCH v2 0/2] MediaTek: Introduce MT8395 Radxa NIO 12L devicetree
Message-ID: <20240202114821.79227-1-angelogioacchino.delregno@collabora.com>

Changes in v2:
 - Squashed device tree bringup per-device commits into just one
 - Removed dependency on MT6360 PD_IRQB removal series

This series adds a device tree for the Radxa NIO 12L SBC, powered by
the MediaTek Genio 1200 (MT8395).
Not all features of this board are included in this first series but
it's already quite usable, as the eMMC internal storage works and can
be used to boot the system (as much as MicroSD external storage), the
connectivity via ethernet and WiFi (PCI-Express) are working as well.

The two I2C, two SPI and the two UART ports are also ok.

What is missing (and what's next...!):
 - UFS storage is not working yet (but eMMC works)
 - Type-C role switching is not yet implemented, driver is there but
   mt8195.dtsi has no MTU3 yet, needs some research to avoid breaking
   compatibility with MT8195 Chromebooks
 - HDMI Input port: no driver yet
 - HDMI Output (from SoC HDMI IP): no driver yet
 - Audio (sound card driver needs some love)
 - MIPI Camera
 - System LEDs
 - "F15" Button

Cheers,
Angelo

AngeloGioacchino Del Regno (2):
  dt-bindings: arm64: mediatek: Add MT8395 Radxa NIO 12L board
    compatible
  arm64: dts: mediatek: Introduce the MT8395 Radxa NIO 12L board

 .../devicetree/bindings/arm/mediatek.yaml     |   1 +
 arch/arm64/boot/dts/mediatek/Makefile         |   1 +
 .../dts/mediatek/mt8395-radxa-nio-12l.dts     | 825 ++++++++++++++++++
 3 files changed, 827 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts

-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Fri Feb  2 03:48:20 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri,  2 Feb 2024 12:48:20 +0100
Subject: [PATCH v2 1/2] dt-bindings: arm64: mediatek: Add MT8395 Radxa NIO 12L board compatible
In-Reply-To: <20240202114821.79227-1-angelogioacchino.delregno@collabora.com>
References: <20240202114821.79227-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240202114821.79227-2-angelogioacchino.delregno@collabora.com>

Add a board compatible for the Radxa NIO 12L, based on the MediaTek
MT8395 SoC.

Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 Documentation/devicetree/bindings/arm/mediatek.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 6f2f64ae76fc..168538887fee 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -287,6 +287,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8395-evk
+              - radxa,nio-12l
           - const: mediatek,mt8395
           - const: mediatek,mt8195
       - items:
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Fri Feb  2 03:48:21 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri,  2 Feb 2024 12:48:21 +0100
Subject: [PATCH v2 2/2] arm64: dts: mediatek: Introduce the MT8395 Radxa NIO 12L board
In-Reply-To: <20240202114821.79227-1-angelogioacchino.delregno@collabora.com>
References: <20240202114821.79227-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240202114821.79227-3-angelogioacchino.delregno@collabora.com>

Add a device tree for the Radxa NIO 12L SBC, powered by the MediaTek
MT8395 Genio 1200 SoC.

This board features:
 * MT6359 + MT6360 PMICs at I2C-6
   - Regulators, battery charger, TypeC Port Controller Interface
   - Audio through 3.5mm jack (2CH out, 1CH in)
 * Two MT6315 PMICs over SPMI
   - CPU-Big and GPU Core regulators
 * Network Connectivity
   - Realtek RTL8211FD MDIO PHY/Transceiver, 10/100/1000M Ethernet
   - MT7921E WiFi (PCIe1) / Bluetooth (USB 2.0) combo chip
 * Storage
   - On-board UFS storage
   - On-board eMMC on MMC0 controller
   - MicroSD card slot on MMC1 controller
 * Other connectivity
   - 1x USB Type-C Charging/Power only port
   - 1x USB 3.2 SuperSpeed Type-C OTG+DisplayPort mode
     - Muxed by ITE IT5205 Alternate Mode Passive MUX
   - 4x USB 3.0 Type-A ports on VL805 USB Hub (PCIe0)
   - 1x HDMI IN port
   - 1x HDMI OUT port
   - 1x MIPI DSI (Display) port
   - 2x MIPI CSI (Camera) ports
 * 40-pin Expansion Header
   - Two UART ports
   - I2C, SPI busses
   - I2S for external audio chips
   - ADC
   - GPIOs

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/Makefile         |   1 +
 .../dts/mediatek/mt8395-radxa-nio-12l.dts     | 825 ++++++++++++++++++
 2 files changed, 826 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 1e6f91731e92..fdd8f4a58003 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -63,4 +63,5 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts b/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts
new file mode 100644
index 000000000000..e5d9b671a405
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts
@@ -0,0 +1,825 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Radxa Limited
+ * Copyright (C) 2024 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+ */
+
+#include "mt8195.dtsi"
+#include "mt6359.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
+#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/usb/pd.h>
+
+/ {
+	model = "Radxa NIO 12L";
+	chassis-type = "embedded";
+	compatible = "radxa,nio-12l", "mediatek,mt8395", "mediatek,mt8195";
+
+	aliases {
+		i2c0 = &i2c2;
+		i2c1 = &i2c3;
+		i2c2 = &i2c4;
+		i2c3 = &i2c0;
+		i2c4 = &i2c1;
+		ethernet0 = &eth;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		spi0 = &spi1;
+		spi1 = &spi2;
+	};
+
+	chosen {
+		stdout-path = "serial0:921600n8";
+	};
+
+	firmware {
+		optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+	};
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0x1 0x0>;
+	};
+
+	wifi_vreg: regulator-wifi-3v3-en {
+		compatible = "regulator-fixed";
+		regulator-name = "wifi_3v3_en";
+		regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&pio 67 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_vreg_pins>;
+		vin-supply = <&vsys>;
+	};
+
+	/* system wide switching 5.0V power rail */
+	vsys: regulator-vsys {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_vsys>;
+	};
+
+	vsys_buck: regulator-vsys-buck {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_buck";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_vsys>;
+	};
+
+	/* Rail from power-only "TYPE C DC" port */
+	vcc5v0_vsys: regulator-vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/*
+		 * 12 MiB reserved for OP-TEE (BL32)
+		 * +-----------------------+ 0x43e0_0000
+		 * |      SHMEM 2MiB       |
+		 * +-----------------------+ 0x43c0_0000
+		 * |        | TA_RAM  8MiB |
+		 * + TZDRAM +--------------+ 0x4340_0000
+		 * |        | TEE_RAM 2MiB |
+		 * +-----------------------+ 0x4320_0000
+		 */
+		optee_reserved: optee at 43200000 {
+			reg = <0 0x43200000 0 0xc00000>;
+			no-map;
+		};
+
+		scp_mem: memory at 50000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x50000000 0 0x2900000>;
+			no-map;
+		};
+
+		vpu_mem: memory at 53000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x53000000 0 0x1400000>; /* 20 MB */
+		};
+
+		/* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+		bl31_secmon_mem: memory at 54600000 {
+			reg = <0 0x54600000 0x0 0x200000>;
+			no-map;
+		};
+
+		afe_mem: memory at 60000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x60000000 0 0x1100000>;
+			no-map;
+		};
+
+		apu_mem: memory at 62000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x62000000 0 0x1400000>; /* 20 MB */
+		};
+	};
+};
+
+&eth {
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&rgmii_phy>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&eth_default_pins>;
+	pinctrl-1 = <&eth_sleep_pins>;
+	mediatek,tx-delay-ps = <2030>;
+	mediatek,mac-wol;
+	snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>;
+	snps,reset-delays-us = <0 20000 100000>;
+	status = "okay";
+
+	mdio {
+		rgmii_phy: ethernet-phy at 1 {
+			compatible = "ethernet-phy-id001c.c916";
+			reg = <0x1>;
+		};
+	};
+};
+
+&gpu {
+	mali-supply = <&mt6315_7_vbuck1>;
+	status = "okay";
+};
+
+&i2c2 {
+	clock-frequency = <400000>;
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	typec-mux at 48 {
+		compatible = "ite,it5205";
+		reg = <0x48>;
+
+		mode-switch;
+		orientation-switch;
+
+		vcc-supply = <&mt6359_vibr_ldo_reg>;
+
+		port {
+			it5205_sbu_mux: endpoint {
+				remote-endpoint = <&typec_con_mux>;
+			};
+		};
+	};
+};
+
+&i2c4 {
+	clock-frequency = <400000>;
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	/* I2C4 exposed at 39-pins MIPI-LCD connector */
+};
+
+&i2c6 {
+	clock-frequency = <400000>;
+	pinctrl-0 = <&i2c6_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	mt6360: pmic at 34 {
+		compatible = "mediatek,mt6360";
+		reg = <0x34>;
+		interrupts-extended = <&pio 101 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-names = "IRQB";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		pinctrl-0 = <&mt6360_pins>;
+
+		charger {
+			compatible = "mediatek,mt6360-chg";
+			richtek,vinovp-microvolt = <14500000>;
+
+			otg_vbus_regulator: usb-otg-vbus-regulator {
+				regulator-name = "usb-otg-vbus";
+				regulator-min-microvolt = <4425000>;
+				regulator-max-microvolt = <5825000>;
+			};
+		};
+
+		regulator {
+			compatible = "mediatek,mt6360-regulator";
+			LDO_VIN1-supply = <&vsys_buck>;
+			LDO_VIN3-supply = <&mt6360_buck2>;
+
+			mt6360_buck1: buck1 {
+				regulator-name = "emi_vdd2";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP
+							   MT6360_OPMODE_ULP>;
+				regulator-always-on;
+			};
+
+			mt6360_buck2: buck2 {
+				regulator-name = "emi_vddq";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP
+							   MT6360_OPMODE_ULP>;
+				regulator-always-on;
+			};
+
+			mt6360_ldo1: ldo1 {
+				regulator-name = "ext_lcd_3v3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+				regulator-always-on;
+			};
+
+			mt6360_ldo2: ldo2 {
+				regulator-name = "panel1_p1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo3: ldo3 {
+				regulator-name = "vmc_pmu";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo5: ldo5 {
+				regulator-name = "vmch_pmu";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+				regulator-always-on;
+			};
+
+			mt6360_ldo6: ldo6 {
+				regulator-name = "mt6360_ldo6"; /* Test point */
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo7: ldo7 {
+				regulator-name = "emi_vmddr_en";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+				regulator-always-on;
+			};
+		};
+
+		typec {
+			compatible = "mediatek,mt6360-tcpc";
+			interrupts-extended = <&pio 100 IRQ_TYPE_LEVEL_LOW>;
+			interrupt-names = "PD_IRQB";
+
+			connector {
+				compatible = "usb-c-connector";
+				label = "USB-C";
+				data-role = "dual";
+				op-sink-microwatt = <10000000>;
+				power-role = "dual";
+				try-power-role = "sink";
+
+				source-pdos = <PDO_FIXED(5000, 1000,
+							 PDO_FIXED_DUAL_ROLE |
+							 PDO_FIXED_DATA_SWAP)>;
+				sink-pdos = <PDO_FIXED(5000, 3000,
+						       PDO_FIXED_DUAL_ROLE |
+						       PDO_FIXED_DATA_SWAP)>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port at 0 {
+						reg = <0>;
+						typec_con_hs: endpoint {
+							remote-endpoint = <&mtu3_hs0_role_sw>;
+						};
+					};
+
+					port at 2 {
+						reg = <2>;
+						typec_con_mux: endpoint {
+							remote-endpoint = <&it5205_sbu_mux>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
+
+/* MMC0 Controller: eMMC (HS400). Power lines are shared with UFS! */
+&mmc0 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_default_pins>;
+	pinctrl-1 = <&mmc0_uhs_pins>;
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	hs400-ds-delay = <0x14c11>;
+	cap-mmc-highspeed;
+	cap-mmc-hw-reset;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	no-sdio;
+	no-sd;
+	non-removable;
+	vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
+	vqmmc-supply = <&mt6359_vufs_ldo_reg>;
+	status = "okay";
+};
+
+/* MMC1 Controller: MicroSD card slot */
+&mmc1 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc1_default_pins>, <&mmc1_pins_detect>;
+	pinctrl-1 = <&mmc1_default_pins>;
+	bus-width = <4>;
+	max-frequency = <200000000>;
+	cap-sd-highspeed;
+	cd-gpios = <&pio 129 GPIO_ACTIVE_LOW>;
+	no-mmc;
+	no-sdio;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&mt6360_ldo5>;
+	vqmmc-supply = <&mt6360_ldo3>;
+	status = "okay";
+};
+
+&mt6359_vaud18_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vbbck_ldo_reg {
+	regulator-always-on;
+};
+
+/* For USB Hub */
+&mt6359_vcamio_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vcn33_2_bt_ldo_reg {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+};
+
+&mt6359_vcore_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vgpu11_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vproc1_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vproc2_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vpu_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vrf12_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vsram_md_ldo_reg {
+	regulator-always-on;
+};
+
+/* for GPU SRAM */
+&mt6359_vsram_others_ldo_reg {
+	regulator-min-microvolt = <750000>;
+	regulator-max-microvolt = <750000>;
+};
+
+&pio {
+	eth_default_pins: eth-default-pins {
+		pins-cc {
+			pinmux = <PINMUX_GPIO85__FUNC_GBE_TXC>,
+				 <PINMUX_GPIO86__FUNC_GBE_RXC>,
+				 <PINMUX_GPIO87__FUNC_GBE_RXDV>,
+				 <PINMUX_GPIO88__FUNC_GBE_TXEN>;
+			drive-strength = <8>;
+		};
+
+		pins-mdio {
+			pinmux = <PINMUX_GPIO89__FUNC_GBE_MDC>,
+				 <PINMUX_GPIO90__FUNC_GBE_MDIO>;
+			input-enable;
+		};
+
+		pins-power {
+			pinmux = <PINMUX_GPIO91__FUNC_GPIO91>,
+				 <PINMUX_GPIO92__FUNC_GPIO92>;
+			output-high;
+		};
+
+		pins-rst {
+			pinmux = <PINMUX_GPIO93__FUNC_GPIO93>;
+		};
+
+		pins-rxd {
+			pinmux = <PINMUX_GPIO81__FUNC_GBE_RXD3>,
+				 <PINMUX_GPIO82__FUNC_GBE_RXD2>,
+				 <PINMUX_GPIO83__FUNC_GBE_RXD1>,
+				 <PINMUX_GPIO84__FUNC_GBE_RXD0>;
+		};
+
+		pins-txd {
+			pinmux = <PINMUX_GPIO77__FUNC_GBE_TXD3>,
+				 <PINMUX_GPIO78__FUNC_GBE_TXD2>,
+				 <PINMUX_GPIO79__FUNC_GBE_TXD1>,
+				 <PINMUX_GPIO80__FUNC_GBE_TXD0>;
+			drive-strength = <8>;
+		};
+	};
+
+	eth_sleep_pins: eth-sleep-pins {
+		pins-cc {
+			pinmux = <PINMUX_GPIO85__FUNC_GPIO85>,
+				 <PINMUX_GPIO86__FUNC_GPIO86>,
+				 <PINMUX_GPIO87__FUNC_GPIO87>,
+				 <PINMUX_GPIO88__FUNC_GPIO88>;
+		};
+
+		pins-mdio {
+			pinmux = <PINMUX_GPIO89__FUNC_GPIO89>,
+				 <PINMUX_GPIO90__FUNC_GPIO90>;
+			bias-disable;
+			input-disable;
+		};
+
+		pins-rxd {
+			pinmux = <PINMUX_GPIO81__FUNC_GPIO81>,
+				 <PINMUX_GPIO82__FUNC_GPIO82>,
+				 <PINMUX_GPIO83__FUNC_GPIO83>,
+				 <PINMUX_GPIO84__FUNC_GPIO84>;
+		};
+
+		pins-txd {
+			pinmux = <PINMUX_GPIO77__FUNC_GPIO77>,
+				 <PINMUX_GPIO78__FUNC_GPIO78>,
+				 <PINMUX_GPIO79__FUNC_GPIO79>,
+				 <PINMUX_GPIO80__FUNC_GPIO80>;
+		};
+	};
+
+	i2c2_pins: i2c2-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
+				 <PINMUX_GPIO13__FUNC_SCL2>;
+			bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+			drive-strength = <6>;
+			drive-strength-microamp = <1000>;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
+				 <PINMUX_GPIO17__FUNC_SCL4>;
+			bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+			drive-strength-microamp = <1000>;
+		};
+	};
+
+	i2c6_pins: i2c6-pins {
+		pins {
+			pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
+				 <PINMUX_GPIO26__FUNC_SCL6>;
+			bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+		};
+	};
+
+	mmc0_default_pins: mmc0-default-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+			drive-strength = <6>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+				 <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+				 <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+				 <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+				 <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+				 <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+				 <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+				 <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+				 <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			drive-strength = <6>;
+			input-enable;
+		};
+
+		pins-rst {
+			pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			drive-strength = <6>;
+		};
+	};
+
+	mmc0_uhs_pins: mmc0-uhs-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+			drive-strength = <8>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+				 <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+				 <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+				 <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+				 <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+				 <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+				 <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+				 <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+				 <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			drive-strength = <8>;
+			input-enable;
+		};
+
+		pins-ds {
+			pinmux = <PINMUX_GPIO127__FUNC_MSDC0_DSL>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+			drive-strength = <8>;
+		};
+
+		pins-rst {
+			pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			drive-strength = <8>;
+		};
+	};
+
+	mmc1_default_pins: mmc1-default-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+			drive-strength = <8>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
+				 <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
+				 <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
+				 <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
+				 <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			drive-strength = <8>;
+			input-enable;
+		};
+	};
+
+	mmc1_pins_detect: mmc1-detect-pins {
+		pins-insert {
+			pinmux = <PINMUX_GPIO129__FUNC_GPIO129>;
+			bias-pull-up;
+		};
+	};
+
+	mt6360_pins: mt6360-pins {
+		pins-irq {
+			pinmux = <PINMUX_GPIO100__FUNC_GPIO100>,
+				 <PINMUX_GPIO101__FUNC_GPIO101>;
+			input-enable;
+			bias-pull-up;
+		};
+	};
+
+	pcie0_default_pins: pcie0-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO19__FUNC_WAKEN>,
+				 <PINMUX_GPIO20__FUNC_PERSTN>,
+				 <PINMUX_GPIO21__FUNC_CLKREQN>;
+			bias-pull-up;
+		};
+	};
+
+	pcie1_default_pins: pcie1-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO0__FUNC_PERSTN_1>,
+				 <PINMUX_GPIO1__FUNC_CLKREQN_1>,
+				 <PINMUX_GPIO2__FUNC_WAKEN_1>;
+			bias-disable;
+		};
+	};
+
+	spi1_pins: spi1-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO136__FUNC_SPIM1_CSB>,
+				 <PINMUX_GPIO137__FUNC_SPIM1_CLK>,
+				 <PINMUX_GPIO138__FUNC_SPIM1_MO>,
+				 <PINMUX_GPIO139__FUNC_SPIM1_MI>;
+			bias-disable;
+		};
+	};
+
+	spi2_pins: spi2-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO140__FUNC_SPIM2_CSB>,
+				 <PINMUX_GPIO141__FUNC_SPIM2_CLK>,
+				 <PINMUX_GPIO142__FUNC_SPIM2_MO>,
+				 <PINMUX_GPIO143__FUNC_SPIM2_MI>;
+			bias-disable;
+		};
+	};
+
+	uart0_pins: uart0-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO98__FUNC_UTXD0>,
+				 <PINMUX_GPIO99__FUNC_URXD0>;
+		};
+	};
+
+	uart1_pins: uart1-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO102__FUNC_UTXD1>,
+				 <PINMUX_GPIO103__FUNC_URXD1>;
+		};
+	};
+
+	wifi_vreg_pins: wifi-vreg-pins {
+		pins-wifi-pmu-en {
+			pinmux = <PINMUX_GPIO65__FUNC_GPIO65>;
+			output-high;
+		};
+
+		pins-wifi-vreg-en {
+			pinmux = <PINMUX_GPIO67__FUNC_GPIO67>;
+		};
+	};
+};
+
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_default_pins>;
+	status = "okay";
+};
+
+&pcie1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_default_pins>;
+	status = "okay";
+};
+
+&pmic {
+	interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&scp {
+	memory-region = <&scp_mem>;
+	status = "okay";
+};
+
+&spi1 {
+	/* Exposed at 40 pin connector */
+	pinctrl-0 = <&spi1_pins>;
+	pinctrl-names = "default";
+	mediatek,pad-select = <0>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+};
+
+&spi2 {
+	/* Exposed at 40 pin connector */
+	pinctrl-0 = <&spi2_pins>;
+	pinctrl-names = "default";
+	mediatek,pad-select = <0>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+};
+
+&spmi {
+	#address-cells = <2>;
+	#size-cells = <0>;
+
+	mt6315_6: pmic at 6 {
+		compatible = "mediatek,mt6315-regulator";
+		reg = <0x6 SPMI_USID>;
+
+		regulators {
+			mt6315_6_vbuck1: vbuck1 {
+				regulator-compatible = "vbuck1";
+				regulator-name = "Vbcpu";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1193750>;
+				regulator-enable-ramp-delay = <256>;
+				regulator-allowed-modes = <0 1 2>;
+				regulator-always-on;
+			};
+		};
+	};
+
+	mt6315_7: pmic at 7 {
+		compatible = "mediatek,mt6315-regulator";
+		reg = <0x7 SPMI_USID>;
+
+		regulators {
+			mt6315_7_vbuck1: vbuck1 {
+				regulator-compatible = "vbuck1";
+				regulator-name = "Vgpu";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1193750>;
+				regulator-enable-ramp-delay = <256>;
+				regulator-allowed-modes = <0 1 2>;
+			};
+		};
+	};
+};
+
+&uart0 {
+	/* Exposed at 40 pin connector */
+	pinctrl-0 = <&uart0_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&uart1 {
+	/* Exposed at 40 pin connector */
+	pinctrl-0 = <&uart1_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&ssusb0 {
+	role-switch-default-mode = "host";
+	usb-role-switch;
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	status = "okay";
+
+	port {
+		mtu3_hs0_role_sw: endpoint {
+			remote-endpoint = <&typec_con_hs>;
+		};
+	};
+};
+
+&ssusb2 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	status = "okay";
+};
+
+&xhci0 {
+	vbus-supply = <&otg_vbus_regulator>;
+	status = "okay";
+};
+
+&xhci1 {
+	/* MT7921's USB Bluetooth has issues with USB2 LPM */
+	usb2-lpm-disable;
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	vbus-supply = <&vsys>;
+	status = "okay";
+};
+
+&xhci2 {
+	vbus-supply = <&vsys>;
+	status = "okay";
+};
-- 
2.43.0



From linux at armlinux.org.uk  Fri Feb  2 03:48:54 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 2 Feb 2024 11:48:54 +0000
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
Message-ID: <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>

On Fri, Feb 02, 2024 at 12:19:10PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> The crystal frequency concerns the switch core. The frequency should be
> checked when the switch is being set up so the driver can reject the
> unsupported hardware earlier and without requiring port 6 to be used.
> 
> Move it to mt7530_setup(). Drop the unnecessary function printing.
> 
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>

I would prefer this to be earlier in the series, before patch 2 which
moves mt7530_setup_port6() to be called from mac_config(). mac_config()
is supposed to be configuration error-free - in other words, all state
should have been checked before hand.

Thanks.

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


From linux at armlinux.org.uk  Fri Feb  2 03:51:09 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 2 Feb 2024 11:51:09 +0000
Subject: [PATCH net-next v3 5/7] net: dsa: mt7530: simplify
 mt7530_setup_port6() and change to void
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-5-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-5-63d5adae99ca@arinc9.com>
Message-ID: <ZbzXLZ4ZyPSbqkdg@shell.armlinux.org.uk>

On Fri, Feb 02, 2024 at 12:19:11PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> This code is from before this driver was converted to phylink API. Phylink
> deals with the unsupported interface cases before mt7530_setup_port6() is
> run. Therefore, the default case would never run. However, it must be
> defined nonetheless to handle all the remaining enumeration values, the
> phy-modes.
> 
> Switch to if statement for RGMII and return which simplifies the code and
> saves an indent.
> 
> Set P6_INTF_MODE, which is the the three least significant bits of the
> MT7530_P6ECR register, to 0 for RGMII even though it will already be 0
> after reset. This is to keep supporting dynamic reconfiguration of the port
> in the case the interface changes from TRGMII to RGMII.
> 
> Disable the TRGMII clocks for all cases. They will be enabled if TRGMII is
> being used.
> 
> Read XTAL after checking for RGMII as it's only needed for the TRGMII
> interface mode.
> 
> Change mt7530_setup_port6() to void now that there're no error cases left.
> 
> Reviewed-by: Daniel Golle <daniel at makrotopia.org>
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>

Yay. Less possible errors in mac_config()!

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! 80Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Fri Feb  2 03:52:11 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 2 Feb 2024 11:52:11 +0000
Subject: [PATCH net-next v3 7/7] net: dsa: mt7530: do not clear
 config->supported_interfaces
In-Reply-To: <20240202-for-netnext-mt7530-improvements-2-v3-7-63d5adae99ca@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-7-63d5adae99ca@arinc9.com>
Message-ID: <ZbzXayWoRv37zFvp@shell.armlinux.org.uk>

On Fri, Feb 02, 2024 at 12:19:13PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> There's no need to clear the config->supported_interfaces bitmap before
> reporting the supported interfaces as all bits in the bitmap will already
> be initialized to zero when the phylink_config structure is allocated. The
> "config" pointer points to &dp->phylink_config, and "dp" is allocated by
> dsa_port_touch() with kzalloc(), so all its fields are filled with zeroes.
> 
> There's no code that would change the bitmap beforehand. Remove it.
> 
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> Acked-by: Daniel Golle <daniel at makrotopia.org>
> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>

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! 80Mbps down 10Mbps up. Decent connectivity at last!


From krzysztof.kozlowski at linaro.org  Fri Feb  2 03:53:09 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 12:53:09 +0100
Subject: [PATCH V4 4/4] MAINTAINERS: Add maintainers for ZynqMP NVMEM
 driver
In-Reply-To: <20240202113843.17999-5-praveen.teja.kundanala@amd.com>
References: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
 <20240202113843.17999-5-praveen.teja.kundanala@amd.com>
Message-ID: <5dc251d7-a6cd-4b96-9392-b3f99505fc4c@linaro.org>

On 02/02/2024 12:38, Praveen Teja Kundanala wrote:
> Add maintainers for ZynqMP NVMEM driver and driver document.
> 
> Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
> ---
>  MAINTAINERS | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8d1052fa6a69..b3103e03015e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -24233,6 +24233,14 @@ M:	Harsha <harsha.harsha at amd.com>
>  S:	Maintained
>  F:	drivers/crypto/xilinx/zynqmp-sha.c
>  
> +XILINX ZYNQMP NVMEM DRIVER

Are you sure you are not causing another Electric Boogaloo? To me, N
looks like before S...

Please read carefully entire top introduction for this file.

Best regards,
Krzysztof



From rsc at runtux.com  Fri Feb  2 03:53:30 2024
From: rsc at runtux.com (Ralf Schlatterbeck)
Date: Fri, 2 Feb 2024 12:53:30 +0100
Subject: [PATCH v2 1/1] spi-mxs: Fix chipselect glitch
Message-ID: <20240202115330.wxkbfmvd76sy3a6a@runtux.com>

There was a change in the mxs-dma engine that uses a new custom flag.
The change was not applied to the mxs spi driver.
This results in chipselect being deasserted too early.
This fixes the chipselect problem by using the new flag in the mxs-spi
driver.

Fixes: ceeeb99cd821 ("dmaengine: mxs: rename custom flag")
Signed-off-by: Ralf Schlatterbeck <rsc at runtux.com>
---
For oscilloscope screenshots and a verbose explanation see my blog post
at https://blog.runtux.com/posts/2024/02/01/
History:
Omit the line break change from patch requested by Marc Kleine-Budde
<mkl at pengutronix.de>

 drivers/spi/spi-mxs.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index 1bf080339b5a..88cbe4f00cc3 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -39,6 +39,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/mxs-spi.h>
 #include <trace/events/spi.h>
+#include <linux/dma/mxs-dma.h>
 
 #define DRIVER_NAME		"mxs-spi"
 
@@ -252,7 +253,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
 		desc = dmaengine_prep_slave_sg(ssp->dmach,
 				&dma_xfer[sg_count].sg, 1,
 				(flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
-				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+				DMA_PREP_INTERRUPT | MXS_DMA_CTRL_WAIT4END);
 
 		if (!desc) {
 			dev_err(ssp->dev,
-- 
2.20.1

-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   www.runtux.com
Reichergasse 131, A-3411 Weidling       email: office at runtux.com


From thierry.reding at gmail.com  Fri Feb  2 03:53:32 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 02 Feb 2024 12:53:32 +0100
Subject: [PATCH net-next v2 0/3] net: stmmac: Allow driver-specific AXI
 configuration
Message-ID: <20240202-stmmac-axi-config-v2-0-64eab2bab17b@nvidia.com>

AXI bus configuration can, in most cases, be derived from the compatible
string, so instead of relying exclusively on device tree for the AXI bus
configuration, create a method for device drivers to pass along a known-
good configuration.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
Changes in v2:
- fix bisectability issue between patches 1 and 2
- Link to v1: https://lore.kernel.org/r/20240201-stmmac-axi-config-v1-0-822e97b2d26e at nvidia.com

---
Thierry Reding (3):
      net: stmmac: Pass resources to DT parsing code
      net: stmmac: Allow drivers to provide a default AXI configuration
      net: stmmac: Configure AXI on Tegra234 MGBE

 .../net/ethernet/stmicro/stmmac/dwmac-anarion.c    |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-generic.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-ingenic.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-loongson1.c  |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c  |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-starfive.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c  | 11 +++-
 .../net/ethernet/stmicro/stmmac/dwmac-visconti.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 66 ++++++++++++++--------
 .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |  3 +-
 25 files changed, 77 insertions(+), 47 deletions(-)
---
base-commit: 076d56d74f17e625b3d63cf4743b3d7d02180379
change-id: 20240201-stmmac-axi-config-77ea05ea9eff

Best regards,
-- 
Thierry Reding <treding at nvidia.com>



From thierry.reding at gmail.com  Fri Feb  2 03:53:33 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 02 Feb 2024 12:53:33 +0100
Subject: [PATCH net-next v2 1/3] net: stmmac: Pass resources to DT parsing
 code
In-Reply-To: <20240202-stmmac-axi-config-v2-0-64eab2bab17b@nvidia.com>
References: <20240202-stmmac-axi-config-v2-0-64eab2bab17b@nvidia.com>
Message-ID: <20240202-stmmac-axi-config-v2-1-64eab2bab17b@nvidia.com>

From: Thierry Reding <treding at nvidia.com>

We already pass the stmmac_resources structure to other initialization
functions since it allows us to exchange more data between the driver
and those functions. Passing this structure to the DT parsing code makes
it easier to extend what we pass around in the future.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
Changes in v2:
- fix bisectability
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c       |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c        |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c       |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 19 +++++++++++--------
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h |  3 ++-
 24 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
index 643ee6d8d4dd..f37d9912380b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
@@ -115,7 +115,7 @@ static int anarion_dwmac_probe(struct platform_device *pdev)
 	if (IS_ERR(gmac))
 		return PTR_ERR(gmac);
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
index ec924c6c76c6..36ef2ed9fd2d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
@@ -435,7 +435,7 @@ static int dwc_eth_dwmac_probe(struct platform_device *pdev)
 	if (IS_ERR(stmmac_res.addr))
 		return PTR_ERR(stmmac_res.addr);
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
index 598eff926815..98a00084807b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
@@ -27,7 +27,7 @@ static int dwmac_generic_probe(struct platform_device *pdev)
 		return ret;
 
 	if (pdev->dev.of_node) {
-		plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+		plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 		if (IS_ERR(plat_dat)) {
 			dev_err(&pdev->dev, "dt configuration failed\n");
 			return PTR_ERR(plat_dat);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
index 6b65420e11b5..d72b9d8ac464 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
@@ -331,7 +331,7 @@ static int imx_dwmac_probe(struct platform_device *pdev)
 	if (!dwmac)
 		return -ENOMEM;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c
index 19c93b998fb3..de2f5d7e95b2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c
@@ -241,7 +241,7 @@ static int ingenic_mac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
index d68f0c4e7835..79582983c060 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
@@ -84,7 +84,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat)) {
 		dev_err(&pdev->dev, "dt configuration failed\n");
 		return PTR_ERR(plat_dat);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
index 281687d7083b..311410509012 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
@@ -384,7 +384,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
 	if (val)
 		return val;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
index 3e86810717d3..1ede4f409937 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
@@ -169,7 +169,7 @@ static int ls1x_dwmac_probe(struct platform_device *pdev)
 	if (!dwmac)
 		return -ENOMEM;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
 				     "dt configuration failed\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
index 4c810d8f5bea..004bf4d14fdb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
@@ -37,7 +37,7 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
index 2a9132d6d743..763ec218ff2c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -656,7 +656,7 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
index a16bfa9089ea..5bd936ef2796 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
@@ -52,7 +52,7 @@ static int meson6_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index b23944aa344e..88db2907640d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -400,7 +400,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 31631e3f89d0..473e8d4228e4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -735,7 +735,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, ret,
 				     "Failed to get platform resources\n");
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat)) {
 		return dev_err_probe(dev, PTR_ERR(plat_dat),
 				     "dt configuration failed\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 382e8de1255d..4297a6919c8a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1824,7 +1824,7 @@ static int rk_gmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 68f85e4605cb..e827e01b4398 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -400,7 +400,7 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
index 4e1076faee0c..a0f15fbb8993 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
@@ -122,7 +122,7 @@ static int starfive_dwmac_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, err,
 				     "failed to get resources\n");
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
 				     "dt configuration failed\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
index 4445cddc4cbe..5b2cde45dc3e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -273,7 +273,7 @@ static int sti_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index c92dfc4ecf57..af131b0bf589 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -366,7 +366,7 @@ static int stm32_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 137741b94122..3ccf695c8b5f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1224,7 +1224,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return -EINVAL;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
index 2653a9f0958c..f78e244b9d81 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
@@ -108,7 +108,7 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
index 362f85136c3e..bab57d1675df 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
@@ -284,7 +284,7 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
 	if (err < 0)
 		goto disable_clks;
 
-	plat = devm_stmmac_probe_config_dt(pdev, res.mac);
+	plat = devm_stmmac_probe_config_dt(pdev, &res);
 	if (IS_ERR(plat)) {
 		err = PTR_ERR(plat);
 		goto disable_clks;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
index a5a5cfa989c6..f99d147b3424 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
@@ -220,7 +220,7 @@ static int visconti_eth_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 70eadc83ca68..650ec8d2f5d7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -424,13 +424,14 @@ static void stmmac_remove_config_dt(struct platform_device *pdev,
 /**
  * stmmac_probe_config_dt - parse device-tree driver parameters
  * @pdev: platform_device structure
- * @mac: MAC address to use
+ * @res: driver-specific parameters
  * Description:
  * this function is to read the driver parameters from device-tree and
  * set some private fields that will be used by the main at runtime.
  */
 static struct plat_stmmacenet_data *
-stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+stmmac_probe_config_dt(struct platform_device *pdev,
+		       struct stmmac_resources *res)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct plat_stmmacenet_data *plat;
@@ -443,12 +444,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 	if (!plat)
 		return ERR_PTR(-ENOMEM);
 
-	rc = of_get_mac_address(np, mac);
+	rc = of_get_mac_address(np, res->mac);
 	if (rc) {
 		if (rc == -EPROBE_DEFER)
 			return ERR_PTR(rc);
 
-		eth_zero_addr(mac);
+		eth_zero_addr(res->mac);
 	}
 
 	phy_mode = device_get_phy_mode(&pdev->dev);
@@ -677,17 +678,18 @@ static void devm_stmmac_remove_config_dt(void *data)
 /**
  * devm_stmmac_probe_config_dt
  * @pdev: platform_device structure
- * @mac: MAC address to use
+ * @res: driver-specific parameters
  * Description: Devres variant of stmmac_probe_config_dt(). Does not require
  * the user to call stmmac_remove_config_dt() at driver detach.
  */
 struct plat_stmmacenet_data *
-devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+devm_stmmac_probe_config_dt(struct platform_device *pdev,
+			    struct stmmac_resources *res)
 {
 	struct plat_stmmacenet_data *plat;
 	int ret;
 
-	plat = stmmac_probe_config_dt(pdev, mac);
+	plat = stmmac_probe_config_dt(pdev, res);
 	if (IS_ERR(plat))
 		return plat;
 
@@ -700,7 +702,8 @@ devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 }
 #else
 struct plat_stmmacenet_data *
-devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+devm_stmmac_probe_config_dt(struct platform_device *pdev,
+			    struct stmmac_resources *res)
 {
 	return ERR_PTR(-EINVAL);
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
index bb6fc7e59aed..daf3bbb503a3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
@@ -12,7 +12,8 @@
 #include "stmmac.h"
 
 struct plat_stmmacenet_data *
-devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
+devm_stmmac_probe_config_dt(struct platform_device *pdev,
+			    struct stmmac_resources *res);
 
 int stmmac_get_platform_resources(struct platform_device *pdev,
 				  struct stmmac_resources *stmmac_res);

-- 
2.43.0



From thierry.reding at gmail.com  Fri Feb  2 03:53:34 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 02 Feb 2024 12:53:34 +0100
Subject: [PATCH net-next v2 2/3] net: stmmac: Allow drivers to provide a
 default AXI configuration
In-Reply-To: <20240202-stmmac-axi-config-v2-0-64eab2bab17b@nvidia.com>
References: <20240202-stmmac-axi-config-v2-0-64eab2bab17b@nvidia.com>
Message-ID: <20240202-stmmac-axi-config-v2-2-64eab2bab17b@nvidia.com>

From: Thierry Reding <treding at nvidia.com>

In many cases the AXI configuration can be derived from the compatible
string, so there's no need to add the configuration to DT. Allow drivers
to pass in the default AXI configuration so they can be properly set up
without extra data in DT.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
Changes in v2:
- fix bisectability
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 47 ++++++++++++++--------
 2 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index f155e4841c62..07706e7b3cfc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -35,6 +35,8 @@ struct stmmac_resources {
 	int sfty_ue_irq;
 	int rx_irq[MTL_MAX_RX_QUEUES];
 	int tx_irq[MTL_MAX_TX_QUEUES];
+
+	const struct stmmac_axi *axi;
 };
 
 enum stmmac_txbuf_type {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 650ec8d2f5d7..0d5f2cebd6fc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -91,34 +91,49 @@ static int dwmac1000_validate_ucast_entries(struct device *dev,
  * if required, from device-tree the AXI internal register can be tuned
  * by using platform parameters.
  */
-static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
+static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev,
+					   struct stmmac_resources *res)
 {
 	struct device_node *np;
 	struct stmmac_axi *axi;
 
 	np = of_parse_phandle(pdev->dev.of_node, "snps,axi-config", 0);
-	if (!np)
+	if (!np && !res->axi)
 		return NULL;
 
 	axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
 	if (!axi) {
-		of_node_put(np);
+		if (np)
+			of_node_put(np);
+
 		return ERR_PTR(-ENOMEM);
 	}
 
-	axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
-	axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
-	axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
-	axi->axi_fb = of_property_read_bool(np, "snps,fb");
-	axi->axi_mb = of_property_read_bool(np, "snps,mb");
-	axi->axi_rb =  of_property_read_bool(np, "snps,rb");
+	if (res->axi)
+		*axi = *res->axi;
+
+	if (np) {
+		axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
+		axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
+		axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
+		axi->axi_fb = of_property_read_bool(np, "snps,fb");
+		axi->axi_mb = of_property_read_bool(np, "snps,mb");
+		axi->axi_rb =  of_property_read_bool(np, "snps,rb");
+
+		if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt)) {
+			if (!res->axi)
+				axi->axi_wr_osr_lmt = 1;
+		}
+
+		if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt)) {
+			if (!res->axi)
+				axi->axi_rd_osr_lmt = 1;
+		}
+
+		of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
 
-	if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
-		axi->axi_wr_osr_lmt = 1;
-	if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt))
-		axi->axi_rd_osr_lmt = 1;
-	of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
-	of_node_put(np);
+		of_node_put(np);
+	}
 
 	return axi;
 }
@@ -606,7 +621,7 @@ stmmac_probe_config_dt(struct platform_device *pdev,
 
 	of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed);
 
-	plat->axi = stmmac_axi_setup(pdev);
+	plat->axi = stmmac_axi_setup(pdev, res);
 
 	rc = stmmac_mtl_setup(pdev, plat);
 	if (rc) {

-- 
2.43.0



From thierry.reding at gmail.com  Fri Feb  2 03:53:35 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 02 Feb 2024 12:53:35 +0100
Subject: [PATCH net-next v2 3/3] net: stmmac: Configure AXI on Tegra234
 MGBE
In-Reply-To: <20240202-stmmac-axi-config-v2-0-64eab2bab17b@nvidia.com>
References: <20240202-stmmac-axi-config-v2-0-64eab2bab17b@nvidia.com>
Message-ID: <20240202-stmmac-axi-config-v2-3-64eab2bab17b@nvidia.com>

From: Thierry Reding <treding at nvidia.com>

Allow the device to use bursts and increase the maximum number of
outstanding requests to improve performance. Measurements show an
increase in throughput of around 5x on a 1 Gbps link.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
index bab57d1675df..b6bfa48f279d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
@@ -199,6 +199,12 @@ static void mgbe_uphy_lane_bringup_serdes_down(struct net_device *ndev, void *mg
 	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 }
 
+static const struct stmmac_axi tegra234_mgbe_axi = {
+	.axi_wr_osr_lmt = 63,
+	.axi_rd_osr_lmt = 63,
+	.axi_blen = { 256, },
+};
+
 static int tegra_mgbe_probe(struct platform_device *pdev)
 {
 	struct plat_stmmacenet_data *plat;
@@ -284,6 +290,9 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
 	if (err < 0)
 		goto disable_clks;
 
+	/* setup default AXI configuration */
+	res.axi = &tegra234_mgbe_axi;
+
 	plat = devm_stmmac_probe_config_dt(pdev, &res);
 	if (IS_ERR(plat)) {
 		err = PTR_ERR(plat);

-- 
2.43.0



From rsc at runtux.com  Fri Feb  2 03:54:29 2024
From: rsc at runtux.com (Ralf Schlatterbeck)
Date: Fri, 2 Feb 2024 12:54:29 +0100
Subject: [PATCH 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <20240201-tributary-fax-dd6055160dbe-mkl@pengutronix.de>
References: <20240201131540.3dlqoxlrrbzshz7w@runtux.com>
 <20240201-tributary-fax-dd6055160dbe-mkl@pengutronix.de>
Message-ID: <20240202115429.q3ebgcrhlcxyewwn@runtux.com>

On Thu, Feb 01, 2024 at 04:38:38PM +0100, Marc Kleine-Budde wrote:

> nitpick: Please omit the line break change from this patch.

I've posted version v2 of the patch without the line break.

Thanks
Ralf
-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   www.runtux.com
Reichergasse 131, A-3411 Weidling       email: office at runtux.com


From ulf.hansson at linaro.org  Fri Feb  2 03:55:17 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Fri, 2 Feb 2024 12:55:17 +0100
Subject: [PATCH 2/3] pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock
 to hdmimix domain
In-Reply-To: <CAHCN7xLqKTAcVpsBYXmzdvSefOnXdXzzrGie7mxkzeJLFKu+Rw@mail.gmail.com>
References: <20240106223951.387067-1-aford173@gmail.com> <20240106223951.387067-2-aford173@gmail.com>
 <CAPDyKFpx_Xo6Y5yGfuMiV8w3kR2hL6f8t31pKC=91-wEperqjA@mail.gmail.com> <CAHCN7xLqKTAcVpsBYXmzdvSefOnXdXzzrGie7mxkzeJLFKu+Rw@mail.gmail.com>
Message-ID: <CAPDyKFr9q4mio8cVsZ66PQuvLC_zpxTT_E-QUDRy1Df09DcdtA@mail.gmail.com>

On Fri, 2 Feb 2024 at 01:17, Adam Ford <aford173 at gmail.com> wrote:
>
> On Thu, Feb 1, 2024 at 4:33?PM Ulf Hansson <ulf.hansson at linaro.org> wrote:
> >
> > On Sat, 6 Jan 2024 at 23:40, Adam Ford <aford173 at gmail.com> wrote:
> > >
> > > According to i.MX8MP RM and HDMI ADD, the fdcc clock is part of
> > > hdmi rx verification IP that should not enable for HDMI TX.
> > > But actually if the clock is disabled before HDMI/LCDIF probe,
> > > LCDIF will not get pixel clock from HDMI PHY and print the error
> > > logs:
> > >
> > > [CRTC:39:crtc-2] vblank wait timed out
> > > WARNING: CPU: 2 PID: 9 at drivers/gpu/drm/drm_atomic_helper.c:1634 drm_atomic_helper_wait_for_vblanks.part.0+0x23c/0x260
> > >
> > > Add fdcc clock to LCDIF and HDMI TX power domains to fix the issue.
> > >
> > > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > > Reviewed-by: Jacky Bai <ping.bai at nxp.com>
> > > Signed-off-by: Adam Ford <aford173 at gmail.com>
> >
> > Just to let you know, this looks good to me and it seems like the NXP
> > people like this too. What I am waiting for is an ack on the DT patch,
> > then I am ready to queue this up.
>
> What about the bindings?  I'm assuming that Shawn would take the DT
> through his IMX tree, but I am not sure if I need to resubmit the
> bindings with a different commit message.

I am usually trying to help with patch1 and patch2 for pmdomain
related changes - and I am sharing new/updated DT bindings on an
immutable "dt" branch. Then Shawn can pull in that branch and apply
patch3 to his tree.

So, I need an ack on patch1 from some of the DT maintainers to go
ahead. Unless you want to manage this entirely through Shawn's tree,
that works too. Just let me know.

[...]

Kind regards
Uffe


From thierry.reding at gmail.com  Fri Feb  2 03:56:42 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 02 Feb 2024 12:56:42 +0100
Subject: [PATCH net-next 1/3] net: stmmac: Pass resources to DT parsing
 code
In-Reply-To: <20240201-stmmac-axi-config-v1-1-822e97b2d26e@nvidia.com>
References: <20240201-stmmac-axi-config-v1-0-822e97b2d26e@nvidia.com>
 <20240201-stmmac-axi-config-v1-1-822e97b2d26e@nvidia.com>
Message-ID: <CYUKOVAO5YVL.3TA1O4LH0488B@gmail.com>

On Thu Feb 1, 2024 at 7:49 PM CET, Thierry Reding wrote:
[...]
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
[...]
> @@ -605,7 +606,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
>  
>  	of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed);
>  
> -	plat->axi = stmmac_axi_setup(pdev);
> +	plat->axi = stmmac_axi_setup(pdev, res);

Looks like I messed up splitting these changes, so this will actually
fail to build before patch 2. I've sent out an updated v2 that I've
explicitly tested for bisectability.

Sorry for not catching this earlier.

Thierry
-------------- 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/20240202/2a0db731/attachment.sig>

From lpieralisi at kernel.org  Fri Feb  2 04:12:41 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Fri, 2 Feb 2024 13:12:41 +0100
Subject: [PATCH v9 05/16] PCI: imx6: Using "linux,pci-domain" as slot ID
In-Reply-To: <20240119171122.3057511-6-Frank.Li@nxp.com>
References: <20240119171122.3057511-1-Frank.Li@nxp.com>
 <20240119171122.3057511-6-Frank.Li@nxp.com>
Message-ID: <ZbzcOarorCS1MPRc@lpieralisi>

"PCI: imx6: Use "linux,pci-domain" as slot ID"

On Fri, Jan 19, 2024 at 12:11:11PM -0500, Frank Li wrote:
> Avoid use get slot id by compared with register physical address. If there
> are more than 2 slots, compared logic will become complex.
> 
> "linux,pci-domain" already exist at dts since commit:
> 	commit (c0b70f05c87f3b arm64: dts: imx8mq: use_dt_domains for pci node).
> 
> So it is safe to remove compare basic address code:
> 	...
> 	if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> 		imx6_pcie->controller_id = 1;

No it is not unless you magically update all firmware out
there in the field.

> 	...
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> 
> Notes:
>     Change from v7 to v8
>     - fixed comments
>     - Added Manivannan Sadhasivam's review tag
>     Change from v5 to v7
>     - none
>     Change from v3 to v4
>     - remove compare basic address logic
>     Change from v2 to v3
>     - none
>     Change from v1 to v2
>     - fix of_get_pci_domain_nr return value check logic
> 
>  drivers/pci/controller/dwc/pci-imx6.c | 20 ++++++++++++--------
>  1 file changed, 12 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index eda6bc6ef80ee..773411d20329f 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -33,6 +33,7 @@
>  #include <linux/pm_domain.h>
>  #include <linux/pm_runtime.h>
>  
> +#include "../../pci.h"
>  #include "pcie-designware.h"
>  
>  #define IMX8MQ_GPR_PCIE_REF_USE_PAD		BIT(9)
> @@ -40,7 +41,6 @@
>  #define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE	BIT(11)
>  #define IMX8MQ_GPR_PCIE_VREG_BYPASS		BIT(12)
>  #define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE	GENMASK(11, 8)
> -#define IMX8MQ_PCIE2_BASE_ADDR			0x33c00000
>  
>  #define to_imx6_pcie(x)	dev_get_drvdata((x)->dev)
>  
> @@ -1279,13 +1279,17 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>  					     "Failed to get PCIEPHY reset control\n");
>  	}
>  
> -	switch (imx6_pcie->drvdata->variant) {
> -	case IMX7D:
> -		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> -			imx6_pcie->controller_id = 1;
> -	default:
> -		break;
> -	}
> +	/* Using linux,pci-domain as PCI slot id */
> +	imx6_pcie->controller_id = of_get_pci_domain_nr(node);
> +	/*
> +	 * If there are no "linux,pci-domain" property specified in DT, then assume only one
> +	 * controller is available.
> +	 */
> +	if (imx6_pcie->controller_id == -EINVAL)
> +		imx6_pcie->controller_id = 0;

See above, this breaks compatibility with old DTs (and -EINVAL is not
the only error code you should handle).

Lorenzo

> +	else if (imx6_pcie->controller_id < 0)
> +		return dev_err_probe(dev, imx6_pcie->controller_id,
> +				     "linux,pci-domain have wrong value\n");
>  
>  	/* Grab turnoff reset */
>  	imx6_pcie->turnoff_reset = devm_reset_control_get_optional_exclusive(dev, "turnoff");
> -- 
> 2.34.1
> 


From sunilvl at ventanamicro.com  Fri Feb  2 04:17:07 2024
From: sunilvl at ventanamicro.com (Sunil V L)
Date: Fri, 2 Feb 2024 17:47:07 +0530
Subject: [RFC PATCH v3 00/17] RISC-V: ACPI: Add external interrupt
 controller support
In-Reply-To: <CAJZ5v0gnH0uPEM0q9VzJOg2Z_7bOP9XdQbOttpRtnkLGej45Sw@mail.gmail.com>
References: <20231219174526.2235150-1-sunilvl@ventanamicro.com>
 <CAJZ5v0j6Veze8xDFKTbVZ5=WAfmLdeJ8NXRnh9kwCZgyaDdgew@mail.gmail.com>
 <ZbiQ/tO/odnJCBD1@sunil-laptop>
 <CAJZ5v0gnH0uPEM0q9VzJOg2Z_7bOP9XdQbOttpRtnkLGej45Sw@mail.gmail.com>
Message-ID: <ZbzdQ2TdsSsb7PL/@sunil-laptop>

On Thu, Feb 01, 2024 at 07:10:28PM +0100, Rafael J. Wysocki wrote:
> On Tue, Jan 30, 2024 at 7:02?AM Sunil V L <sunilvl at ventanamicro.com> wrote:
> >
> > On Tue, Dec 19, 2023 at 06:50:19PM +0100, Rafael J. Wysocki wrote:
> > > On Tue, Dec 19, 2023 at 6:45?PM Sunil V L <sunilvl at ventanamicro.com> wrote:
> > > >
> > > > This series adds support for the below ECR approved by ASWG.
> > > > 1) MADT - https://drive.google.com/file/d/1oMGPyOD58JaPgMl1pKasT-VKsIKia7zR/view?usp=sharing
> > > >
> > > > The series primarily enables irqchip drivers for RISC-V ACPI based
> > > > platforms.
> > > >
> > > > The series can be broadly categorized like below.
> > > >
> > > > 1) PCI ACPI related functions are migrated from arm64 to common file so
> > > > that we don't need to duplicate them for RISC-V.
> > > >
> > > > 2) Introduced support for fw_devlink for ACPI nodes for IRQ dependency.
> > > > This helps to support deferred probe of interrupt controller drivers.
> > > >
> > > > 3) Modified pnp_irq() to try registering the IRQ  again if it sees it in
> > > > disabled state. This solution is similar to how
> > > > platform_get_irq_optional() works for regular platform devices.
> > > >
> > > > 4) Added support for re-ordering the probe of interrupt controllers when
> > > > IRQCHIP_ACPI_DECLARE is used.
> > > >
> > > > 5) ACPI support added in RISC-V interrupt controller drivers.
> > > >
> > > > This series is based on Anup's AIA v11 series. Since Anup's AIA v11 is
> > > > not merged yet and first time introducing fw_devlink, deferred probe and
> > > > reordering support for IRQCHIP probe, this series is still kept as RFC.
> > > > Looking forward for the feedback!
> > > >
> > > > Changes since RFC v2:
> > > >         1) Introduced fw_devlink for ACPI nodes for IRQ dependency.
> > > >         2) Dropped patches in drivers which are not required due to
> > > >            fw_devlink support.
> > > >         3) Dropped pci_set_msi() patch and added a patch in
> > > >            pci_create_root_bus().
> > > >         4) Updated pnp_irq() patch so that none of the actual PNP
> > > >            drivers need to change.
> > > >
> > > > Changes since RFC v1:
> > > >         1) Abandoned swnode approach as per Marc's feedback.
> > > >         2) To cope up with AIA series changes which changed irqchip driver
> > > >            probe from core_initcall() to platform_driver, added patches
> > > >            to support deferred probing.
> > > >         3) Rebased on top of Anup's AIA v11 and added tags.
> > > >
> > > > To test the series,
> > > >
> > > > 1) Qemu should be built using the riscv_acpi_b2_v8 branch at
> > > > https://github.com/vlsunil/qemu.git
> > > >
> > > > 2) EDK2 should be built using the instructions at:
> > > > https://github.com/tianocore/edk2/blob/master/OvmfPkg/RiscVVirt/README.md
> > > >
> > > > 3) Build Linux using this series on top of Anup's AIA v11 series.
> > > >
> > > > Run Qemu:
> > > > qemu-system-riscv64 \
> > > >  -M virt,pflash0=pflash0,pflash1=pflash1,aia=aplic-imsic \
> > > >  -m 2G -smp 8 \
> > > >  -serial mon:stdio \
> > > >  -device virtio-gpu-pci -full-screen \
> > > >  -device qemu-xhci \
> > > >  -device usb-kbd \
> > > >  -blockdev node-name=pflash0,driver=file,read-only=on,filename=RISCV_VIRT_CODE.fd \
> > > >  -blockdev node-name=pflash1,driver=file,filename=RISCV_VIRT_VARS.fd \
> > > >  -netdev user,id=net0 -device virtio-net-pci,netdev=net0 \
> > > >  -kernel arch/riscv/boot/Image \
> > > >  -initrd rootfs.cpio \
> > > >  -append "root=/dev/ram ro console=ttyS0 rootwait earlycon=uart8250,mmio,0x10000000"
> > > >
> > > > To boot with APLIC only, use aia=aplic.
> > > > To boot with PLIC, remove aia= option.
> > > >
> > > > This series is also available in acpi_b2_v3_riscv_aia_v11 branch at
> > > > https://github.com/vlsunil/linux.git
> > > >
> > > > Based-on: 20231023172800.315343-1-apatel at ventanamicro.com
> > > > (https://lore.kernel.org/lkml/20231023172800.315343-1-apatel at ventanamicro.com/)
> > > >
> > > > Sunil V L (17):
> > > >   arm64: PCI: Migrate ACPI related functions to pci-acpi.c
> > > >   RISC-V: ACPI: Implement PCI related functionality
> > > >   PCI: Make pci_create_root_bus() declare its reliance on MSI domains
> > > >   ACPI: Add fw_devlink support for ACPI fwnode for IRQ dependency
> > > >   ACPI: irq: Add support for deferred probe in acpi_register_gsi()
> > > >   pnp.h: Reconfigure IRQ in pnp_irq() to support deferred probe
> > > >   ACPI: scan.c: Add weak arch specific function to reorder the IRQCHIP
> > > >     probe
> > > >   ACPI: RISC-V: Implement arch function to reorder irqchip probe entries
> > > >   irqchip: riscv-intc: Add ACPI support for AIA
> > > >   irqchip: riscv-imsic: Add ACPI support
> > > >   irqchip: riscv-aplic: Add ACPI support
> > > >   irqchip: irq-sifive-plic: Add ACPI support
> > > >   ACPI: bus: Add RINTC IRQ model for RISC-V
> > > >   ACPI: bus: Add acpi_riscv_init function
> > > >   ACPI: RISC-V: Create APLIC platform device
> > > >   ACPI: RISC-V: Create PLIC platform device
> > > >   irqchip: riscv-intc: Set ACPI irqmodel
> > >
> > > JFYI, I have no capacity to provide any feedback on this till 6.8-rc1 is out.
> > >
> > Hi Rafael,
> >
> > Gentle ping.
> >
> > Could you please provide feedback on the series? Patches 4, 5, 6, 7 and
> > 8 are bit critical IMO. So, I really look forward for your and other
> > ACPI experts!.
> 
> There was quite a bit of discussion on patch [6/21] and it still seems
> relevant to me.
> 
> ACPI actually has a way to at least indicate what the probe ordering
> should be which is _DEP.
> 
> The current handling of _DEP in the kernel may not be covering this
> particular use case, but I would rather extend it (if necessary)
> instead of doing all of the -EPROBE_DEFER dance which seems fragile to
> me.
> 
Hi Rafael,

Appreciate your help to look at the patches. Thank you very much!.

I am not very sure whether you looked into patches in the v3 of the
series. Because, unlike in v2, v3 doesn't need changing all drivers to
handle EPROBE_DEFER. In v3, it creates fw_devlink for the dependency as
suggested by Marc. Please take a look at PATCH 4/17.

For the IRQ dependency, I think adding _DEP is not required. The
"Extended Interrupt Descriptor" supports ResourceSource to
indicate the dependency. Or GSI mapping can indicate the source. This is
already handled in acpi_irq_parse_one_cb(). PATCH 4 uses this
information to create links between producer and consumer so that DD
framework probes the driver in the required order.

As you know, PNP devices are enumerated in a different way. I don't know
why it was done like this. But pnpacpi_init() is called via
fs_initcall() and acpi_dev_resource_interrupt() called from
pnpacpi_allocated_resource() doesn't handle the ResourceSource
dependency. It caches the information in PNP data structure and expects
the IRQ mapping to be available. Even if we add support to
handle extended interrupt descriptor, it is not going to help. Hence, I
had to add PATCH 5/17 and PATCH 6/17. Again, the change is mainly in
pnp_irq() now and hence it doesn't need changing all drivers.

Thanks,
Sunil


From nm at ti.com  Fri Feb  2 04:18:28 2024
From: nm at ti.com (Nishanth Menon)
Date: Fri, 2 Feb 2024 06:18:28 -0600
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <dc3c93dc-74d9-4b1c-a771-3ee6f67b5dcc@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-5-rogerq@kernel.org>
 <20240201-viewpoint-upload-fb714f650ff5@spud>
 <20240201-violet-chalice-51a73f113e7b@spud>
 <20240201183522.ssj553rwefr2wuqi@iaqt7>
 <20240201-clad-unopposed-ccfdfe53b770@spud>
 <bc3ab60f-539b-41d0-8595-6e0b55f2763d@kernel.org>
 <20240202-unzip-whacky-bb2f151c618b@wendy>
 <dc3c93dc-74d9-4b1c-a771-3ee6f67b5dcc@kernel.org>
Message-ID: <20240202121828.oo7grngyh2heqdxn@disposal>

On 12:13-20240202, Roger Quadros wrote:
[..]
> >>
> >> As DTS and driver will be merged by separate maintainers I thought it
> >> would be easier for maintainers this way.
> > 
> > dts and driver might be merged by different people, but dt-bindings and
> > drivers are merged by the same people. This is a bindings patch, not a
> 
> If we do that then I get a bunch of dtbs_check warnings
> 
> dwc3-usb at f900000: reg: [[0, 261095424, 0, 2048], [0, 261128192, 0, 1024]] is too long

Just my 2 cents: If the binding (and driver) change was truly backward
compatible (which it should be - for example: errata can only be
applied if the second property is described), then you want to control
that reg property to add minItems? - thatm I think will allow the dts
change to come in at the next cycle once the binding has been merged.

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From rogerq at kernel.org  Fri Feb  2 04:26:48 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 2 Feb 2024 14:26:48 +0200
Subject: [PATCH v3 3/3] arm64: dts: ti: k3-am642-evm: add overlay for
 icssg1 2nd port
In-Reply-To: <20240122113045.1711818-4-danishanwar@ti.com>
References: <20240122113045.1711818-1-danishanwar@ti.com>
 <20240122113045.1711818-4-danishanwar@ti.com>
Message-ID: <33e62844-a148-4374-aba8-481dc7799e15@kernel.org>



On 22/01/2024 13:30, MD Danish Anwar wrote:
> The am642-evm doesn't allow to enable 2 x CPSW3g ports and 2 x ICSSG1 ports
> all together, so base k3-am642-evm.dts enables by default 2 x CPSW3g ports
> and 1 x ICSSG1 ports, but it also possible to support 1 x CPSW3g ports and
> 2 x ICSSG1 ports configuration.

"it is also possible"

OK so there can only be 3 ethernet ports on this board. There is no "ethernet3" alias.

> 
> This patch adds overlay to support 1 x CPSW3g ports and 2 x ICSSG1 ports
> configuration:
> - Add label name 'mdio_mux_1' for 'mdio-mux-1' node so that the node
>   'mdio-mux-1' can be disabled in the overlay using the label name.
> - disable 2nd CPSW3g port
> - update CPSW3g pinmuxes to not use RGMII2
> - disable mdio-mux-1 and define mdio-mux-2 to route ICSSG1 MDIO to the
>   shared DP83869 PHY
> - add and enable ICSSG1 RGMII2 pinmuxes
> - enable ICSSG1 MII1 port
> 
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> ---
>  arch/arm64/boot/dts/ti/Makefile               |  5 ++
>  .../dts/ti/k3-am642-evm-icssg1-dualemac.dtso  | 75 +++++++++++++++++++
>  arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  2 +-
>  3 files changed, 81 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
> 
> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
> index 52c1dc910308..320b2fae5730 100644
> --- a/arch/arm64/boot/dts/ti/Makefile
> +++ b/arch/arm64/boot/dts/ti/Makefile
> @@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
>  dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
>  dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>  dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
> +dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac.dtbo
>  
>  # Boards with AM65x SoC
>  k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
> @@ -105,6 +106,8 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
>  	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>  k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
>  	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
> +k3-am642-evm-icssg1-dualemac-dtbs := \
> +	k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
>  k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
>  	k3-j721e-evm-pcie0-ep.dtbo
>  k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
> @@ -120,6 +123,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
>  	k3-am62a7-sk-csi2-ov5640.dtb \
>  	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
>  	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
> +	k3-am642-evm-icssg1-dualemac.dtb \
>  	k3-j721e-evm-pcie0-ep.dtb \
>  	k3-j721s2-evm-pcie1-ep.dtb
>  
> @@ -129,6 +133,7 @@ DTC_FLAGS_k3-am625-sk += -@
>  DTC_FLAGS_k3-am62-lp-sk += -@
>  DTC_FLAGS_k3-am62a7-sk += -@
>  DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
> +DTC_FLAGS_k3-am642-evm += -@
>  DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
>  DTC_FLAGS_k3-j721e-common-proc-board += -@
>  DTC_FLAGS_k3-j721s2-common-proc-board += -@
> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
> new file mode 100644
> index 000000000000..b2b1a6252e73
> --- /dev/null
> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
> @@ -0,0 +1,75 @@
> +// SPDX-License-Identifier: GPL-2.0

Don't you need to use updated licensing header like in the series [1]

[1] https://lore.kernel.org/all/20240110140903.4090946-1-nm at ti.com/

> +/**
> + * DT overlay for enabling 2nd ICSSG1 port on AM642 EVM
> + *
> + * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include "k3-pinctrl.h"
> +
> +&{/} {

You need to fixup alias for ethernet1 to icssg1_emac1?

> +	mdio-mux-2 {

this should be mdio-mux at 0 ?

> +		compatible = "mdio-mux-multiplexer";
> +		mux-controls = <&mdio_mux>;
> +		mdio-parent-bus = <&icssg1_mdio>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		mdio at 0 {
> +			reg = <0x0>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			icssg1_phy2: ethernet-phy at 3 {
> +				reg = <3>;
> +				tx-internal-delay-ps = <250>;
> +				rx-internal-delay-ps = <2000>;
> +			};
> +		};
> +	};
> +};
> +
> +&main_pmx0 {
> +	icssg1_rgmii2_pins_default: icssg1-rgmii2-default-pins {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x0108, PIN_INPUT, 2) /* (W11) PRG1_PRU1_GPO0.RGMII2_RD0 */
> +			AM64X_IOPAD(0x010c, PIN_INPUT, 2) /* (V11) PRG1_PRU1_GPO1.RGMII2_RD1 */
> +			AM64X_IOPAD(0x0110, PIN_INPUT, 2) /* (AA12) PRG1_PRU1_GPO2.RGMII2_RD2 */
> +			AM64X_IOPAD(0x0114, PIN_INPUT, 2) /* (Y12) PRG1_PRU1_GPO3.RGMII2_RD3 */
> +			AM64X_IOPAD(0x0120, PIN_INPUT, 2) /* (U11) PRG1_PRU1_GPO6.RGMII2_RXC */
> +			AM64X_IOPAD(0x0118, PIN_INPUT, 2) /* (W12) PRG1_PRU1_GPO4.RGMII2_RX_CTL */
> +			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2) /* (AA10) PRG1_PRU1_GPO11.RGMII2_TD0 */
> +			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2) /* (V10) PRG1_PRU1_GPO12.RGMII2_TD1 */
> +			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2) /* (U10) PRG1_PRU1_GPO13.RGMII2_TD2 */
> +			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2) /* (AA11) PRG1_PRU1_GPO14.RGMII2_TD3 */
> +			AM64X_IOPAD(0x0148, PIN_OUTPUT, 2) /* (Y10) PRG1_PRU1_GPO16.RGMII2_TXC */
> +			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2) /* (Y11) PRG1_PRU1_GPO15.RGMII2_TX_CTL */
> +		>;
> +	};
> +};
> +
> +&cpsw3g {
> +	pinctrl-0 = <&rgmii1_pins_default>;
> +};
> +
> +&cpsw_port2 {
> +	status = "disabled";
> +};
> +
> +&mdio_mux_1 {
> +	status = "disabled";
> +};
> +
> +&icssg1_eth {
> +	pinctrl-0 = <&icssg1_rgmii1_pins_default>, <&icssg1_rgmii2_pins_default>;
> +};
> +
> +&icssg1_emac1 {
> +	status = "okay";
> +	phy-handle = <&icssg1_phy2>;
> +	phy-mode = "rgmii-id";
> +};
> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> index c08b0223be52..6ae43c12419f 100644
> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> @@ -200,7 +200,7 @@ mdio_mux: mux-controller {
>  		mux-gpios = <&exp1 12 GPIO_ACTIVE_HIGH>;
>  	};
>  
> -	mdio-mux-1 {
> +	mdio_mux_1: mdio-mux-1 {

mdio_mux_1: mdio-mux at 1

>  		compatible = "mdio-mux-multiplexer";
>  		mux-controls = <&mdio_mux>;
>  		mdio-parent-bus = <&cpsw3g_mdio>;

-- 
cheers,
-roger


From angelogioacchino.delregno at collabora.com  Fri Feb  2 04:58:05 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 2 Feb 2024 13:58:05 +0100
Subject: [PATCH 3/3] media: mediatek: vcodedc: Fix
 Wcast-function-type-strict warnings
In-Reply-To: <CABCJKudd3SUy3Qor7Tc0zyJsSAWy0PavbbBFALuWEpBa32pBCQ@mail.gmail.com>
References: <20240128-fix-clang-warnings-v1-0-1d946013a421@chromium.org>
 <20240128-fix-clang-warnings-v1-3-1d946013a421@chromium.org>
 <20240201221654.GC2240065@dev-arch.thelio-3990X>
 <CABCJKudd3SUy3Qor7Tc0zyJsSAWy0PavbbBFALuWEpBa32pBCQ@mail.gmail.com>
Message-ID: <5658ec37-868f-454d-a149-467e6de139cd@collabora.com>

Il 01/02/24 23:25, Sami Tolvanen ha scritto:
> On Thu, Feb 1, 2024 at 10:17?PM Nathan Chancellor <nathan at kernel.org> wrote:
>>
>> On Sun, Jan 28, 2024 at 02:12:22AM +0000, Ricardo Ribalda wrote:
>>> Building with LLVM=1 throws the following warning:
>>> drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c:38:32: warning: cast from 'mtk_vcodec_ipi_handler' (aka 'void (*)(void *, unsigned int, void *)') to 'ipi_handler_t' (aka 'void (*)(const void *, unsigned int, void *)') converts to incompatible function type [-Wcast-function-type-strict]
>>>
>>> Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
>>
>> I am not positive because I don't have any hardware to test this driver
>> but I suspect this patch is just hiding the warning without actually
>> addressing the issue that it is pointing out.
> 
> Agreed, this won't fix the issue. The correct solution is to drop the
> cast and change the handler type to match the pointer type (i.e. use
> const void* for the first argument).
> 

Even though I agree that the correct solution is to change the handler's type,
I think that having a test on the actual hardware done is still valuable.

We scheduled a job on KernelCI to test this commit on our integration kernel,
you'll get results for ChromeOS' tast decoders (MT8195 only) and Fluster tests
on MT8183/8186/8192/8195.


The results should be available in a couple of hours here, relative to commit 
`49955a84129dbe1f94fedf729690efcf28513828` on our tree:
https://chromeos.kernelci.org/job/collabora-chromeos-kernel/branch/for-kernelci/

P.S.: If they don't, feel free to ping me or Nicolas (added to the loop) about it.

Cheers,
Angelo


From graf at amazon.com  Fri Feb  2 04:58:52 2024
From: graf at amazon.com (Alexander Graf)
Date: Fri, 2 Feb 2024 13:58:52 +0100
Subject: [PATCH v3 00/17] kexec: Allow preservation of ftrace buffers
In-Reply-To: <20240129173450.038e46b7@rotkaeppchen>
References: <20240117144704.602-1-graf@amazon.com>
 <20240129173450.038e46b7@rotkaeppchen>
Message-ID: <3bfbe6b3-d293-483f-9f30-b7d49440be22@amazon.com>

Hi Philipp,

On 29.01.24 17:34, Philipp Rudo wrote:
> Hi Alex,
>
> adding linux-integrity as there are some synergies with IMA_KEXEC (in case we
> get KHO to work).
>
> Fist of all I believe that having a generic framework to pass information from
> one kernel to the other across kexec would be a good thing. But I'm afraid that


Thanks, I'm happy to hear that you agree with the basic motivation :). 
There are fundamentally 2 problems with passing data:

 ? * Passing structured data in a cross-architecture way
 ? * Passing memory

KHO tackles both. It proposes a common FDT based format that allows us 
to pass per-subsystem properties. That way, a subsystem does not need to 
know whether it's running on ARM, x86, RISC-V or s390x. It just gains 
awareness for KHO and can pass data.

On top of that, it proposes a standardized "mem" property (and some 
magic around that) which allows subsystems to pass memory.


> you are ignoring some fundamental problems which makes it extremely hard, if
> not impossible, to reliably transfer the kernel's state from one kernel to the
> other.
>
> One thing I don't understand is how reusing the scratch area is working. Sure
> you pass it's location via the dt/boot_params but I don't see any code that
> makes it a CMA region. So IIUC the scratch area won't be available for the 2nd
> kernel. Which is probably for the better as IIUC the 2nd kernel gets loaded and
> runs inside that area and I don't believe the CMA design ever considered that
> the kernel image could be included in a CMA area.


That one took me a lot to figure out sensibly (with recursion all the 
way down) while building KHO :). I hope I detailed it sensibly in the 
documentation - please let me know how to improve it in case it's 
unclear: https://lore.kernel.org/lkml/20240117144704.602-8-graf at amazon.com/

Let me explain inline using different words as well what happens:

The first (and only the first) kernel that boots allocates a CMA region 
as "scratch region". It loads the new kernel into that region. It passes 
that region as "scratch region" to the next kernel. The next kernel now 
takes it and marks every page block that the scratch region spans as CMA:

https://lore.kernel.org/lkml/20240117144704.602-3-graf at amazon.com/

The CMA hint doesn't mean we create an actual CMA region. It mostly 
means that the kernel won't use this memory for any kernel allocations. 
Kernel allocations up to this point are allocations we don't need to 
pass on with KHO again. Kernel allocations past that point may be 
allocations that we want to pass, so we just never place them into the 
"scratch region" again.

And because we now already have a scratch region from the previous 
kernel, we keep reusing that forever with any new KHO kexec.


> Staying at reusing the scratch area. One thing that is broken for sure is that
> you reuse the scratch area without ever checking the kho_scratch parameter of
> the 2nd kernel's command line. Remember, with kexec you are dealing with two
> different kernels with two different command lines. Meaning you can only reuse
> the scratch area if the requested size in the 2nd kernel is identical to the
> one of the 1st kernel. In all other cases you need to adjust the scratch area's
> size or reserve a new one.


Hm. So you're saying a user may want to change the size of the scratch 
area with a KHO kexec. That's insanely risky because you (as rightfully 
pointed out below) may have significant fragmentation at that point. And 
we will only know when we're in the new kernel so it's too late to 
abort. IMHO it's better to just declare the scratch region as immutable 
during KHO to avoid that pitfall.


> This directly leads to the next problem. In kho_reserve_previous_mem you are
> reusing the different memory regions wherever the 1st kernel allocated them.
> But that also means you are handing over the 1st kernel's memory
> fragmentation to the 2nd kernel and you do that extremely early during boot.
> Which means that users who need to allocate large continuous physical memory,
> like the scratch area or the crashkernel memory, will have increasing chance to
> not find a suitable area. Which IMHO is unacceptable.


Correct :). It basically means you want to pass large allocations from 
the 1st kernel that you want to preserve on to the next. So if the 1st 
kernel allocated a large crash area, it's safest to pass that allocation 
using KHO to ensure the next kernel also has the region fully reserved. 
Otherwise the next kernel may accidentally place data into the 
previously reserved crash region (which would be contiguously free at 
early init of the 2nd kernel) and fragment it again.


> Finally, and that's the big elephant in the room, is your lax handling of the
> unstable kernel internal ABI. Remember, you are dealing with two different
> kernels, that also means two different source levels and two different configs.
> So only because both the 1st and 2nd kernel have a e.g. struct buffer_page
> doesn't means that they have the same struct buffer_page. But that's what your
> code implicitly assumes. For KHO ever to make it upstream you need to make sure
> that both kernels are "speaking the same language".


Wow, I hope it didn't come across as that! The whole point of using FDT 
and compatible strings in KHO is to solve exactly that problem. Any time 
a passed over data structure changes incompatibly, you would need to 
modify the compatible string of the subsystem that owns the now 
incompatible data.

So in the example of struct buffer_page, it means that if anyone changes 
the few bits we care about in struct buffer_page, we need to ensure that 
the new kernel emits "ftrace,cpu-v2" compatible strings. We can at that 
point choose whether we want to implement compat handling for 
"ftrace,cpu-v1" style struct buffer_pages or only support same version 
ingestion.

The one thing that we could improve on here today IMHO is to have 
compile time errors if any part of struct buffer_page changes 
semantically: So we'd create a few defines for the bits we want in 
"ftrace,cpu-v1" as well as size of struct buffer_page and then compare 
them to what the struct offsets are at compile time to ensure they stay 
identical.

Please let me know how I can clarify that more in the documentation. It 
really is the absolute core of KHO.


> Personally I see two possible solutions:
>
> 1) You introduce a stable intermediate format for every subsystem similar to
> what IMA_KEXEC does. This should work for simple types like struct buffer_page
> but for complex ones like struct vfio_device that's basically impossible.


I don't see why. The only reason KHO passes struct buffer_page as memory 
is because we want to be able to produce traces even after KHO 
serialization is done. For vfio_device, I think it's perfectly 
reasonable to serialize any data we need to preserve directly into FDT 
properties.


> 2) You also hand over the ABI version for every given type (basically just a
> hash over all fields including all the dependencies). So the 2nd kernel can
> verify that the data handed over is in a format it can handle and if not bail
> out with a descriptive error message rather than reading garbage. Plus side is
> that once such a system is in place you can reuse it to automatically resolve
> all dependencies so you no longer need to manually store the buffer_page and
> its buffer_data_page separately.
> Down side is that traversing the debuginfo (including the ones from modules) is
> not a simple task and I expect that such a system will be way more complex than
> the rest of KHO. In addition there are some cases that the versioning won't be
> able to capture. For example if a type contains a "void *"-field. Then although
> the definition of the type is identical in both kernels the field can be cast
> to different types when used. An other problem will be function pointers which
> you first need to resolve in the 1st kernel and then map to the identical
> function in the 2nd kernel. This will become particularly "fun" when the
> function is part of a module that isn't loaded at the time when you try to
> recreate the kernel's state.


The whole point of KHO is to leave it to the subsystem which path they 
want to take. The subsystem can either pass binary data and validate as 
part of FDT properties (like compatible strings). That data can be 
identical to today's in-kernel data structures (usually a bad idea) or 
can be a new intermediate data format. But the subsystem can also choose 
to fully serialize into FDT properties and not pass any memory at all 
for state that would be in structs. Or something in between.


> So to summarize, while it would be nice to have a generic framework like KHO to
> pass data from one kernel to the other via kexec there are good reasons why it
> doesn't exist, yet.


I hope my explanations above clarify things a bit. Let me know if you're 
at FOSDEM, happy to talk about the internals there as well :)


Alex





Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



From mripard at kernel.org  Fri Feb  2 05:01:39 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Fri, 2 Feb 2024 14:01:39 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB
 property
In-Reply-To: <20240115143720.GA160656@toolbox>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <20240115143720.GA160656@toolbox>
Message-ID: <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>

Hi,

On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > >  /**
> > >   * DOC: HDMI connector properties
> > >   *
> > > + * Broadcast RGB
> > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > + *      Infoframes will be generated according to that value.
> > > + *
> > > + *      The value of this property can be one of the following:
> > > + *
> > > + *      Automatic:
> > > + *              RGB Range is selected automatically based on the mode
> > > + *              according to the HDMI specifications.
> > > + *
> > > + *      Full:
> > > + *              Full RGB Range is forced.
> > > + *
> > > + *      Limited 16:235:
> > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > + *              this works for any number of bits-per-component.
> > > + *
> > > + *      Drivers can set up this property by calling
> > > + *      drm_connector_attach_broadcast_rgb_property().
> > > + *
> > 
> > This is a good time to document this in more detail. There might be two
> > different things being affected:
> > 
> > 1. The signalling (InfoFrame/SDP/...)
> > 2. The color pipeline processing
> > 
> > All values of Broadcast RGB always affect the color pipeline processing
> > such that a full-range input to the CRTC is converted to either full- or
> > limited-range, depending on what the monitor is supposed to accept.
> > 
> > When automatic is selected, does that mean that there is no signalling,
> > or that the signalling matches what the monitor is supposed to accept
> > according to the spec? Also, is this really HDMI specific?
> > 
> > When full or limited is selected and the monitor doesn't support the
> > signalling, what happens?
> 
> Forgot to mention: user-space still has no control over RGB vs YCbCr on
> the cable, so is this only affecting RGB? If not, how does it affect
> YCbCr?

So I dug a bit into both the i915 and vc4 drivers, and it looks like if
we're using a YCbCr format, i915 will always use a limited range while
vc4 will follow the value of the property.

I guess the best way to reconcile that would be to state that it also
controls the YCbCr range, and i915 can choose to reject/adjust the
configurations it can't support.

Does that 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/20240202/3659dac6/attachment-0001.sig>

From u.kleine-koenig at pengutronix.de  Fri Feb  2 05:08:27 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Fri, 2 Feb 2024 14:08:27 +0100
Subject: [PATCH v2 17/33] spi: bitbang: Follow renaming of SPI "master"
 to "controller"
In-Reply-To: <202401301813.fehkuS9c-lkp@intel.com>
References: <b2035a8030b77e8a3eea87adf7e4a191c0a18717.1705944943.git.u.kleine-koenig@pengutronix.de>
 <202401301813.fehkuS9c-lkp@intel.com>
Message-ID: <fkqzgxam5hlutiujsdnrhoidx2mjcnkwl427dpvydux7fn3ye4@2p7b4e7z45e6>

Hello,

On Tue, Jan 30, 2024 at 06:46:16PM +0800, kernel test robot wrote:
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on 6613476e225e090cc9aad49be7fa504e290dd33d]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Uwe-Kleine-K-nig/fpga-ice40-spi-Follow-renaming-of-SPI-master-to-controller/20240123-031635
> base:   6613476e225e090cc9aad49be7fa504e290dd33d
> patch link:    https://lore.kernel.org/r/b2035a8030b77e8a3eea87adf7e4a191c0a18717.1705944943.git.u.kleine-koenig%40pengutronix.de
> patch subject: [PATCH v2 17/33] spi: bitbang: Follow renaming of SPI "master" to "controller"
> config: mips-db1xxx_defconfig (https://download.01.org/0day-ci/archive/20240130/202401301813.fehkuS9c-lkp at intel.com/config)
> compiler: mipsel-linux-gcc (GCC) 13.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240130/202401301813.fehkuS9c-lkp at intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp at intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202401301813.fehkuS9c-lkp at intel.com/
> 
> All errors (new ones prefixed by >>):
> 
>    drivers/spi/spi-au1550.c: In function 'au1550_spi_probe':
> >> drivers/spi/spi-au1550.c:803:20: error: 'struct spi_bitbang' has no member named 'master'
>      803 |         hw->bitbang.master = hw->host;
>          |                    ^

Dang, didn't build test on mips. Will send a v3 once I did a few more
build tests.

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/20240202/51d97ca6/attachment.sig>

From aford173 at gmail.com  Fri Feb  2 05:15:07 2024
From: aford173 at gmail.com (Adam Ford)
Date: Fri, 2 Feb 2024 07:15:07 -0600
Subject: [PATCH V2 2/2] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240202122036.7aa66d9d@booty>
References: <20240106221907.325127-1-aford173@gmail.com> <20240106221907.325127-2-aford173@gmail.com>
 <20240202122036.7aa66d9d@booty>
Message-ID: <CAHCN7x+Fyy76_Qo0757fx3bjg5RWUHU=NQHJu+WenSi9PQrwOg@mail.gmail.com>

On Fri, Feb 2, 2024 at 5:20?AM Luca Ceresoli <luca.ceresoli at bootlin.com> wrote:
>
> Hello Adam,
>
> On Sat,  6 Jan 2024 16:19:05 -0600
> Adam Ford <aford173 at gmail.com> wrote:
>
> > From: Lucas Stach <l.stach at pengutronix.de>
> >
> > This adds the driver for the Samsung HDMI PHY found on the
> > i.MX8MP SoC.
> >
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
>
> I had already tested the v2 from Lucas, however I also tested this
> version which works as well, on v6.8-rc1, custom hardware based on the
> Avnet i.MX8MP SMARC SoM.
>
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
>
Thanks for testing.

> Generally speaking, as there are several small patch series around which
> together implement HDMI on iMX8MP and similar, I think it would be much
> easier fore reviewing and testing if they were grouped into a unique
> series.

That will happen for my next attempt to push this series.  It was a
headache for me to gather them all.  I have a github repo setup with
my latest edits here if you're interested:

https://github.com/aford173/linux/tree/for-6.9-imx8mp-hdmi


adam
>
> Luca
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


From andrew at lunn.ch  Fri Feb  2 05:15:21 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 2 Feb 2024 14:15:21 +0100
Subject: [PATCH net-next 1/6] net: stmmac: remove eee_enabled/eee_active
 in stmmac_ethtool_op_get_eee()
In-Reply-To: <E1rVpvc-002Pdp-Jj@rmk-PC.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvc-002Pdp-Jj@rmk-PC.armlinux.org.uk>
Message-ID: <2399ecee-5f5d-46f7-8bb3-bea95cac4dcf@lunn.ch>

On Fri, Feb 02, 2024 at 09:33:44AM +0000, Russell King (Oracle) wrote:
> stmmac_ethtool_op_get_eee() sets both eee_enabled and eee_active, and
> then goes on to call phylink_ethtool_get_eee().
> 
> phylink_ethtool_get_eee() will return -EOPNOTSUPP if there is no PHY
> present, otherwise calling phy_ethtool_get_eee() which in turn will call
> genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Thus, when there is no PHY, stmmac_ethtool_op_get_eee() will fail with
> -EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
> userspace. When there is a PHY, eee_enabled and eee_active will be
> overwritten by phylib, making the setting of these members in
> stmmac_ethtool_op_get_eee() entirely unnecessary.
> 
> Remove this code, thus simplifying stmmac_ethtool_op_get_eee().
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

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

    Andrew


From andrew at lunn.ch  Fri Feb  2 05:18:19 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 2 Feb 2024 14:18:19 +0100
Subject: [PATCH net-next 2/6] net: sxgbe: remove eee_enabled/eee_active
 in sxgbe_get_eee()
In-Reply-To: <E1rVpvh-002Pdv-Ol@rmk-PC.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvh-002Pdv-Ol@rmk-PC.armlinux.org.uk>
Message-ID: <04ed368c-9889-483c-b08f-9c061d433528@lunn.ch>

On Fri, Feb 02, 2024 at 09:33:49AM +0000, Russell King (Oracle) wrote:
> sxgbe_get_eee() sets edata->eee_active and edata->eee_enabled from its
> own copy, and then calls phy_ethtool_get_eee() which in turn will call
> genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Therefore, setting these members in sxgbe_get_eee() is redundant.
> Remove this, and remove the priv->eee_active member which then becomes
> a write-only variable.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

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

    Andrew


From angelogioacchino.delregno at collabora.com  Fri Feb  2 05:21:48 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 2 Feb 2024 14:21:48 +0100
Subject: [PATCH 2/2] phy: add driver for MediaTek XFI T-PHY
In-Reply-To: <dd6b40ea1f7f8459a9a2cfe7fa60c1108332ade6.1706823233.git.daniel@makrotopia.org>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
 <dd6b40ea1f7f8459a9a2cfe7fa60c1108332ade6.1706823233.git.daniel@makrotopia.org>
Message-ID: <3e9afc4b-4ad6-412b-bc4d-f3e3b1475657@collabora.com>

Il 01/02/24 22:53, Daniel Golle ha scritto:
> Add driver for MediaTek's XFI T-PHY, 10 Gigabit/s Ethernet SerDes PHY
> which can be found in the MT7988 SoC.
> 
> The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
> PHY_INTERFACE_MODE_* corresponding to the supported modes:
> 
>   * USXGMII                 \
>   * 10GBase-R                }- USXGMII PCS - XGDM  \
>   * 5GBase-R                /                        \
>                                                       }- Ethernet MAC
>   * 2500Base-X              \                        /
>   * 1000Base-X               }- LynxI PCS - GDM     /
>   * Cisco SGMII (MAC side)  /
> 
> In order to work-around a performance issue present on the first of
> two XFI T-PHYs present in MT7988, special tuning is applied which can be
> selected by adding the 'mediatek,usxgmii-performance-errata' property to
> the device tree node.
> 
> There is no documentation for most registers used for the
> analog/tuning part, however, most of the registers have been partially
> reverse-engineered from MediaTek's SDK implementation (an opaque
> sequence of 32-bit register writes) and descriptions for all relevant
> digital registers and bits such as resets and muxes have been supplied
> by MediaTek.
> 
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---
>   MAINTAINERS                             |   1 +
>   drivers/phy/mediatek/Kconfig            |  12 +
>   drivers/phy/mediatek/Makefile           |   1 +
>   drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 392 ++++++++++++++++++++++++
>   4 files changed, 406 insertions(+)
>   create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 52769631bdb1a..52e4192470bd9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -13715,6 +13715,7 @@ L:	netdev at vger.kernel.org
>   S:	Maintained
>   F:	drivers/net/phy/mediatek-ge-soc.c
>   F:	drivers/net/phy/mediatek-ge.c
> +F:	drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>   
>   MEDIATEK I2C CONTROLLER DRIVER
>   M:	Qii Wang <qii.wang at mediatek.com>
> diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> index 3125ecb5d119f..5161d130c7f8b 100644
> --- a/drivers/phy/mediatek/Kconfig
> +++ b/drivers/phy/mediatek/Kconfig
> @@ -13,6 +13,18 @@ config PHY_MTK_PCIE
>   	  callback for PCIe GEN3 port, it supports software efuse
>   	  initialization.
>   
> +config PHY_MTK_XFI_TPHY
> +	tristate "MediaTek XFI T-PHY Driver"
> +	depends on ARCH_MEDIATEK || COMPILE_TEST
> +	depends on OF && OF_ADDRESS
> +	depends on HAS_IOMEM
> +	select GENERIC_PHY
> +	help
> +	  Say 'Y' here to add support for MediaTek XFI T-PHY driver.
> +	  The driver provides access to the Ethernet SerDes T-PHY supporting
> +	  1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
> +	  via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
> +
>   config PHY_MTK_TPHY
>   	tristate "MediaTek T-PHY Driver"
>   	depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> index c9a50395533eb..fa7217178e7f4 100644
> --- a/drivers/phy/mediatek/Makefile
> +++ b/drivers/phy/mediatek/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
>   obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
>   obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
>   obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
> +obj-$(CONFIG_PHY_MTK_XFI_TPHY)		+= phy-mtk-xfi-tphy.o
>   
>   phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
>   phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
> diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> new file mode 100644
> index 0000000000000..d50e6320860e5
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> @@ -0,0 +1,392 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/* MediaTek 10GE SerDes PHY driver

MediaTek 10GE SerDes XFI T-PHY driver ?

> + *
> + * Copyright (c) 2024 Daniel Golle <daniel at makrotopia.org>
> + *                    Bc-bocun Chen <bc-bocun.chen at mediatek.com>
> + * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Henry Yen <henry.yen at mediatek.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/io.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
> +#include <linux/phy.h>
> +#include <linux/phy/phy.h>
> +
> +#define MTK_XFI_TPHY_NUM_CLOCKS		2
> +
> +#define REG_DIG_GLB_70			0x0070
> +#define  XTP_PCS_RX_EQ_IN_PROGRESS(x)	FIELD_PREP(GENMASK(25, 24), (x))
> +#define  XTP_PCS_MODE_MASK		GENMASK(17, 16)
> +#define  XTP_PCS_MODE(x)		FIELD_PREP(GENMASK(17, 16), (x))
> +#define  XTP_PCS_RST_B			BIT(15)
> +#define  XTP_FRC_PCS_RST_B		BIT(14)
> +#define  XTP_PCS_PWD_SYNC_MASK		GENMASK(13, 12)
> +#define  XTP_PCS_PWD_SYNC(x)		FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
> +#define  XTP_PCS_PWD_ASYNC_MASK		GENMASK(11, 10)
> +#define  XTP_PCS_PWD_ASYNC(x)		FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
> +#define  XTP_FRC_PCS_PWD_ASYNC		BIT(8)
> +#define  XTP_PCS_UPDT			BIT(4)
> +#define  XTP_PCS_IN_FR_RG		BIT(0)
> +
> +#define REG_DIG_GLB_F4			0x00f4
> +#define  XFI_DPHY_PCS_SEL		BIT(0)
> +#define   XFI_DPHY_PCS_SEL_SGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 1)
> +#define   XFI_DPHY_PCS_SEL_USXGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 0)
> +#define  XFI_DPHY_AD_SGDT_FRC_EN	BIT(5)
> +
> +#define REG_DIG_LN_TRX_40		0x3040
> +#define  XTP_LN_FRC_TX_DATA_EN		BIT(29)
> +#define  XTP_LN_TX_DATA_EN		BIT(28)
> +
> +#define REG_DIG_LN_TRX_B0		0x30b0
> +#define  XTP_LN_FRC_TX_MACCK_EN		BIT(5)
> +#define  XTP_LN_TX_MACCK_EN		BIT(4)
> +
> +#define REG_ANA_GLB_D0			0x90d0
> +#define  XTP_GLB_USXGMII_SEL_MASK	GENMASK(3, 1)
> +#define  XTP_GLB_USXGMII_SEL(x)		FIELD_PREP(GENMASK(3, 1), (x))
> +#define  XTP_GLB_USXGMII_EN		BIT(0)
> +
> +struct mtk_xfi_tphy {
> +	void __iomem		*base;
> +	struct device		*dev;
> +	struct reset_control	*reset;
> +	struct clk_bulk_data	clocks[MTK_XFI_TPHY_NUM_CLOCKS];
> +	bool			da_war;
> +};
> +
> +static void mtk_xfi_tphy_write(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
> +			       u32 value)
> +{
> +	iowrite32(value, xfi_tphy->base + reg);
> +}
> +
> +static void mtk_xfi_tphy_rmw(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
> +			     u32 clr, u32 set)
> +{
> +	u32 val;
> +
> +	val = ioread32(xfi_tphy->base + reg);
> +	val &= ~clr;
> +	val |= set;
> +	iowrite32(val, xfi_tphy->base + reg);
> +}
> +
> +static void mtk_xfi_tphy_set(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
> +			     u32 set)
> +{
> +	mtk_xfi_tphy_rmw(xfi_tphy, reg, 0, set);
> +}
> +
> +static void mtk_xfi_tphy_clear(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
> +			       u32 clr)
> +{
> +	mtk_xfi_tphy_rmw(xfi_tphy, reg, clr, 0);
> +}
> +
> +static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
> +			       phy_interface_t interface)
> +{
> +	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
> +	bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
> +		      interface == PHY_INTERFACE_MODE_SGMII);
> +	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
> +		       interface == PHY_INTERFACE_MODE_USXGMII);
> +	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
> +	bool is_xgmii = (is_10g || is_5g);

is_usxgmii, I'd say.

> +
> +	dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));
> +
> +	/* Setup PLL setting */
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2030, 0x500, is_1g ? 0x0 : 0x500);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2040, 0x340000, is_1g ? 0x200000 :
> +							     0x140000);
> +
> +	/* Setup RXFE BW setting */
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50f0, 0xc10, is_1g ? 0x410 :
> +							  is_5g ? 0x800 : 0x400);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
> +
> +	/* Setup RX CDR setting */
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5078, 0xf000400, is_5g ? 0x8000000 :
> +							      0x7000400);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x507c, 0x5000500, is_5g ? 0x4000400 :
> +							      0x1000100);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5080, 0x1410, is_1g ? 0x400 :
> +							   is_5g ? 0x1010 : 0x0);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5084, 0x30300, is_1g ? 0x30300 :
> +							    is_5g ? 0x30100 :
> +								    0x100);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5088, 0x60200, is_1g ? 0x20200 :
> +							 is_5g ? 0x40000 :
> +								 0x20000);
> +
> +	/* Setting RXFE adaptation range setting */
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50a8, 0xee0000, is_5g ? 0x800000 :
> +							     0x6e0000);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);
> +	if (is_10g)
> +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x01423342);
> +	else if (is_5g)
> +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00a132a1);
> +	else if (is_2p5g)
> +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x009c329c);
> +	else
> +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00fa32fa);
> +
> +	/* Force SGDT_OUT off and select PCS */
> +	mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_F4,
> +			 XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
> +			 XFI_DPHY_AD_SGDT_FRC_EN |
> +			 (is_xgmii ? XFI_DPHY_PCS_SEL_USXGMII :
> +				     XFI_DPHY_PCS_SEL_SGMII));
> +
> +
> +	/* Force GLB_CKDET_OUT */
> +	mtk_xfi_tphy_set(xfi_tphy, 0x0030, 0xc00);
> +
> +	/* Force AEQ on */
> +	mtk_xfi_tphy_write(xfi_tphy, REG_DIG_GLB_70,
> +			   XTP_PCS_RX_EQ_IN_PROGRESS(2) |
> +			   XTP_PCS_PWD_SYNC(2) |
> +			   XTP_PCS_PWD_ASYNC(2));
> +
> +	usleep_range(1, 5);
> +
> +	/* Setup TX DA default value */
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x30b0, 0x30, 0x20);
> +	mtk_xfi_tphy_write(xfi_tphy, 0x3028, 0x00008a01);
> +	mtk_xfi_tphy_write(xfi_tphy, 0x302c, 0x0000a884);
> +	mtk_xfi_tphy_write(xfi_tphy, 0x3024, 0x00083002);
> +
> +	/* Setup RG default value */
> +	if (is_xgmii) {
> +		mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00022220);
> +		mtk_xfi_tphy_write(xfi_tphy, 0x5064, 0x0f020a01);
> +		mtk_xfi_tphy_write(xfi_tphy, 0x50b4, 0x06100600);
> +		if (interface == PHY_INTERFACE_MODE_USXGMII)
> +			mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
> +		else
> +			mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x47684100);
> +	} else {
> +		mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00011110);
> +		mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
> +	}
> +
> +	if (is_1g)
> +		mtk_xfi_tphy_write(xfi_tphy, 0x3064, 0x0000c000);
> +
> +	/* Setup RX EQ initial value */
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x3050, 0xa8000000,
> +			 (interface != PHY_INTERFACE_MODE_10GBASER) ?
> +			  0xa8000000 : 0x0);
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x3054, 0xaa,
> +			 (interface != PHY_INTERFACE_MODE_10GBASER) ?
> +			  0xaa : 0x0);
> +
> +	if (is_xgmii)
> +		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x00000f00);
> +	else if (is_2p5g)
> +		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x22000f00);
> +	else
> +		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x20200f00);
> +
> +	if (interface == PHY_INTERFACE_MODE_10GBASER && xfi_tphy->da_war)
> +		mtk_xfi_tphy_rmw(xfi_tphy, 0xa008, 0x10000, 0x10000);
> +
> +	mtk_xfi_tphy_rmw(xfi_tphy, 0xa060, 0x50000, is_xgmii ? 0x40000 :
> +							       0x50000);
> +
> +	/* Setup PHYA speed */
> +	mtk_xfi_tphy_rmw(xfi_tphy, REG_ANA_GLB_D0,
> +			 XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
> +			 is_10g ?  XTP_GLB_USXGMII_SEL(0) :
> +			 is_5g ?   XTP_GLB_USXGMII_SEL(1) :
> +			 is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
> +				   XTP_GLB_USXGMII_SEL(3));
> +	mtk_xfi_tphy_set(xfi_tphy, REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
> +
> +	/* Release reset */
> +	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_GLB_70,
> +			 XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
> +	usleep_range(150, 500);
> +
> +	/* Switch to P0 */
> +	mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
> +			 XTP_PCS_PWD_SYNC_MASK |
> +			 XTP_PCS_PWD_ASYNC_MASK,
> +			 XTP_FRC_PCS_PWD_ASYNC |
> +			 XTP_PCS_UPDT | XTP_PCS_IN_FR_RG);
> +	usleep_range(1, 5);
> +
> +	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
> +	usleep_range(15, 50);
> +
> +	if (is_xgmii) {
> +		/* Switch to Gen3 */
> +		mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
> +				 XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
> +				 XTP_PCS_MODE(2) | XTP_PCS_UPDT);
> +	} else {
> +		/* Switch to Gen2 */
> +		mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
> +				 XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
> +				 XTP_PCS_MODE(1) | XTP_PCS_UPDT);
> +	}
> +	usleep_range(1, 5);
> +
> +	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
> +
> +	usleep_range(100, 500);
> +
> +	/* Enable MAC CK */
> +	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
> +	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN);
> +
> +	/* Enable TX data */
> +	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_40,
> +			 XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
> +	usleep_range(400, 1000);
> +}
> +
> +static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int
> +				 submode)
> +{
> +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> +
> +	if (mode != PHY_MODE_ETHERNET)
> +		return -EINVAL;
> +
> +	switch (submode) {
> +	case PHY_INTERFACE_MODE_1000BASEX:

fallthrough;

> +	case PHY_INTERFACE_MODE_2500BASEX:

fallthrough;

> +	case PHY_INTERFACE_MODE_SGMII:

... etc :-)

> +	case PHY_INTERFACE_MODE_5GBASER:
> +	case PHY_INTERFACE_MODE_10GBASER:
> +	case PHY_INTERFACE_MODE_USXGMII:

Does this PHY support PHY_INTERFACE_MODE_XGMII ?

> +		mtk_xfi_tphy_setup(xfi_tphy, submode);
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int mtk_xfi_tphy_reset(struct phy *phy)
> +{
> +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> +
> +	reset_control_assert(xfi_tphy->reset);
> +	usleep_range(100, 500);
> +	reset_control_deassert(xfi_tphy->reset);
> +	usleep_range(1, 10);
> +
> +	return 0;
> +}
> +
> +static int mtk_xfi_tphy_power_on(struct phy *phy)
> +{
> +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> +
> +	return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
> +}
> +
> +static int mtk_xfi_tphy_power_off(struct phy *phy)
> +{
> +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> +
> +	clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops mtk_xfi_tphy_ops = {
> +	.power_on	= mtk_xfi_tphy_power_on,
> +	.power_off	= mtk_xfi_tphy_power_off,
> +	.set_mode	= mtk_xfi_tphy_set_mode,
> +	.reset		= mtk_xfi_tphy_reset,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static int mtk_xfi_tphy_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct phy_provider *phy_provider;
> +	struct mtk_xfi_tphy *xfi_tphy;
> +	struct phy *phy;
> +
> +	if (!np)
> +		return -ENODEV;
> +
> +	xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
> +	if (!xfi_tphy)
> +		return -ENOMEM;
> +
> +	xfi_tphy->base = devm_of_iomap(&pdev->dev, np, 0, NULL);

Why devm_of_iomap() and not devm_platform_ioremap_resource()?

> +	if (!xfi_tphy->base)
> +		return -EIO;
> +
> +	xfi_tphy->dev = &pdev->dev;
> +
> +	xfi_tphy->clocks[0].id = "topxtal";

xfi_tphy->clocks[0].id = "topxtal";
xfi_tphy->clocks[1].id = "xfipll";

ret = devm_clk_bulk_get(&pdev->dev, MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
if (ret)
	return ret;

...it's that simple :-P

> +	xfi_tphy->clocks[0].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[0].id);
> +	if (IS_ERR(xfi_tphy->clocks[0].clk))
> +		return PTR_ERR(xfi_tphy->clocks[0].clk);
> +
> +	xfi_tphy->clocks[1].id = "xfipll";
> +	xfi_tphy->clocks[1].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[1].id);
> +	if (IS_ERR(xfi_tphy->clocks[1].clk))
> +		return PTR_ERR(xfi_tphy->clocks[1].clk);
> +
> +	xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> +	if (IS_ERR(xfi_tphy->reset))
> +		return PTR_ERR(xfi_tphy->reset);
> +
> +	xfi_tphy->da_war = of_property_read_bool(np,
> +						 "mediatek,usxgmii-performance-errata");
> +

One line please

> +	phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
> +	if (IS_ERR(phy))
> +		return PTR_ERR(phy);
> +
> +	phy_set_drvdata(phy, xfi_tphy);
> +
> +	phy_provider = devm_of_phy_provider_register(&pdev->dev,
> +						     of_phy_simple_xlate);

ditto

> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id mtk_xfi_tphy_match[] = {
> +	{ .compatible = "mediatek,mt7988-xfi-tphy", },
> +	{ }

	{ .compatible = "mediatek,mt7988-xfi-tphy" },
	{ /* sentinel */ }

> +};
> +MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
> +
> +static struct platform_driver mtk_xfi_tphy_driver = {
> +	.probe = mtk_xfi_tphy_probe,
> +	.driver = {
> +		.name = "mtk-xfi-tphy",
> +		.of_match_table = mtk_xfi_tphy_match,
> +	},
> +};
> +module_platform_driver(mtk_xfi_tphy_driver);
> +
> +MODULE_DESCRIPTION("MediaTek XFI T-PHY driver");

MODULE_DESCRIPTION("MediaTek 10GE SerDes XFI T-PHY driver");

Cheers,
Angelo

> +MODULE_AUTHOR("Daniel Golle <daniel at makrotopia.org>");
> +MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen at mediatek.com>");
> +MODULE_LICENSE("GPL");



From andrew at lunn.ch  Fri Feb  2 05:22:02 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 2 Feb 2024 14:22:02 +0100
Subject: [PATCH net-next 3/6] net: fec: remove eee_enabled/eee_active in
 fec_enet_get_eee()
In-Reply-To: <E1rVpvm-002Pe0-TV@rmk-PC.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvm-002Pe0-TV@rmk-PC.armlinux.org.uk>
Message-ID: <011cb523-0561-436a-9f64-4479648b4770@lunn.ch>

On Fri, Feb 02, 2024 at 09:33:54AM +0000, Russell King (Oracle) wrote:
> fec_enet_get_eee() sets edata->eee_active and edata->eee_enabled from
> its own copy, and then calls phy_ethtool_get_eee() which in turn will
> call genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Therefore, setting these members in fec_enet_get_eee() is redundant.
> Remove this, and remove the setting of fep->eee.eee_active member which
> becomes a write-only variable.

I _think_ p->eee_enabled becomes write only as well?

	Andrew


From andrew at lunn.ch  Fri Feb  2 05:25:49 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 2 Feb 2024 14:25:49 +0100
Subject: [PATCH net-next 4/6] net: bcmgenet: remove
 eee_enabled/eee_active in bcmgenet_get_eee()
In-Reply-To: <E1rVpvs-002Pe6-1w@rmk-PC.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvs-002Pe6-1w@rmk-PC.armlinux.org.uk>
Message-ID: <65370f0a-c1de-453f-b3e8-33bde1b096e2@lunn.ch>

On Fri, Feb 02, 2024 at 09:34:00AM +0000, Russell King (Oracle) wrote:
> bcmgenet_get_eee() sets edata->eee_active and edata->eee_enabled from
> its own copy, and then calls phy_ethtool_get_eee() which in turn will
> call genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Therefore, setting these members in bcmgenet_get_eee() is redundant,
> and can be removed. This also makes priv->eee.eee_active unnecessary,
> so remove this and use a local variable where appropriate.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

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

    Andrew


From Frank.li at nxp.com  Fri Feb  2 05:25:58 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 2 Feb 2024 08:25:58 -0500
Subject: [PATCH v9 05/16] PCI: imx6: Using "linux,pci-domain" as slot ID
In-Reply-To: <ZbzcOarorCS1MPRc@lpieralisi>
References: <20240119171122.3057511-1-Frank.Li@nxp.com>
 <20240119171122.3057511-6-Frank.Li@nxp.com>
 <ZbzcOarorCS1MPRc@lpieralisi>
Message-ID: <ZbztZkNQ+wydticD@lizhi-Precision-Tower-5810>

On Fri, Feb 02, 2024 at 01:12:41PM +0100, Lorenzo Pieralisi wrote:
> "PCI: imx6: Use "linux,pci-domain" as slot ID"
> 
> On Fri, Jan 19, 2024 at 12:11:11PM -0500, Frank Li wrote:
> > Avoid use get slot id by compared with register physical address. If there
> > are more than 2 slots, compared logic will become complex.
> > 
> > "linux,pci-domain" already exist at dts since commit:
> > 	commit (c0b70f05c87f3b arm64: dts: imx8mq: use_dt_domains for pci node).
> > 
> > So it is safe to remove compare basic address code:
> > 	...
> > 	if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> > 		imx6_pcie->controller_id = 1;
> 
> No it is not unless you magically update all firmware out
> there in the field.

commit c0b70f05c87f3b09b391027c6f056d0facf331ef
Author:     Peng Fan <peng.fan at nxp.com>
AuthorDate: Fri Jan 15 11:26:57 2021 +0800
Commit:     Shawn Guo <shawnguo at kernel.org>
CommitDate: Fri Jan 29 14:46:28 2021 +0800

I am not sure if it is neccesary to compatible with 2 years ago's dts.
I think it may not boot at all with using 2 year agao dtb file directly.

Do you have other comments? I can remove it from this big patch series,

Frank
> 
> > 	...
> > 
> > Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > 
> > Notes:
> >     Change from v7 to v8
> >     - fixed comments
> >     - Added Manivannan Sadhasivam's review tag
> >     Change from v5 to v7
> >     - none
> >     Change from v3 to v4
> >     - remove compare basic address logic
> >     Change from v2 to v3
> >     - none
> >     Change from v1 to v2
> >     - fix of_get_pci_domain_nr return value check logic
> > 
> >  drivers/pci/controller/dwc/pci-imx6.c | 20 ++++++++++++--------
> >  1 file changed, 12 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> > index eda6bc6ef80ee..773411d20329f 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -33,6 +33,7 @@
> >  #include <linux/pm_domain.h>
> >  #include <linux/pm_runtime.h>
> >  
> > +#include "../../pci.h"
> >  #include "pcie-designware.h"
> >  
> >  #define IMX8MQ_GPR_PCIE_REF_USE_PAD		BIT(9)
> > @@ -40,7 +41,6 @@
> >  #define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE	BIT(11)
> >  #define IMX8MQ_GPR_PCIE_VREG_BYPASS		BIT(12)
> >  #define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE	GENMASK(11, 8)
> > -#define IMX8MQ_PCIE2_BASE_ADDR			0x33c00000
> >  
> >  #define to_imx6_pcie(x)	dev_get_drvdata((x)->dev)
> >  
> > @@ -1279,13 +1279,17 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> >  					     "Failed to get PCIEPHY reset control\n");
> >  	}
> >  
> > -	switch (imx6_pcie->drvdata->variant) {
> > -	case IMX7D:
> > -		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> > -			imx6_pcie->controller_id = 1;
> > -	default:
> > -		break;
> > -	}
> > +	/* Using linux,pci-domain as PCI slot id */
> > +	imx6_pcie->controller_id = of_get_pci_domain_nr(node);
> > +	/*
> > +	 * If there are no "linux,pci-domain" property specified in DT, then assume only one
> > +	 * controller is available.
> > +	 */
> > +	if (imx6_pcie->controller_id == -EINVAL)
> > +		imx6_pcie->controller_id = 0;
> 
> See above, this breaks compatibility with old DTs (and -EINVAL is not
> the only error code you should handle).
> 
> Lorenzo
> 
> > +	else if (imx6_pcie->controller_id < 0)
> > +		return dev_err_probe(dev, imx6_pcie->controller_id,
> > +				     "linux,pci-domain have wrong value\n");
> >  
> >  	/* Grab turnoff reset */
> >  	imx6_pcie->turnoff_reset = devm_reset_control_get_optional_exclusive(dev, "turnoff");
> > -- 
> > 2.34.1
> > 


From andrew at lunn.ch  Fri Feb  2 05:26:44 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 2 Feb 2024 14:26:44 +0100
Subject: [PATCH net-next 5/6] net: bcmasp: remove eee_enabled/eee_active
 in bcmasp_get_eee()
In-Reply-To: <E1rVpvx-002PeD-71@rmk-PC.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvx-002PeD-71@rmk-PC.armlinux.org.uk>
Message-ID: <9b080167-d102-4fb2-ac31-3d171a88fc8e@lunn.ch>

On Fri, Feb 02, 2024 at 09:34:05AM +0000, Russell King (Oracle) wrote:
> bcmasp_get_eee() sets edata->eee_active and edata->eee_enabled from
> its own copy, and then calls phy_ethtool_get_eee() which in turn will
> call genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Therefore, setting these members in bcmasp_get_eee() is redundant, and
> can be removed. This also makes intf->eee.eee_active unnecessary, so
> remove this and use a local variable where appropriate.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

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

    Andrew


From andrew at lunn.ch  Fri Feb  2 05:27:35 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 2 Feb 2024 14:27:35 +0100
Subject: [PATCH net-next 6/6] net: dsa: b53: remove
 eee_enabled/eee_active in b53_get_mac_eee()
In-Reply-To: <E1rVpw2-002PeJ-Bh@rmk-PC.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpw2-002PeJ-Bh@rmk-PC.armlinux.org.uk>
Message-ID: <d989588f-d92a-45aa-baec-a9d616ddd11a@lunn.ch>

On Fri, Feb 02, 2024 at 09:34:10AM +0000, Russell King (Oracle) wrote:
> b53_get_mac_eee() sets both eee_enabled and eee_active, and then
> returns zero.
> 
> dsa_slave_get_eee(), which calls this function, will then continue to
> call phylink_ethtool_get_eee(), which will return -EOPNOTSUPP if there
> is no PHY present, otherwise calling phy_ethtool_get_eee() which in
> turn will call genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Thus, when there is no PHY, dsa_slave_get_eee() will fail with
> -EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
> userspace. When there is a PHY, eee_enabled and eee_active will be
> overwritten by phylib, making the setting of these members in
> b53_get_mac_eee() entirely unnecessary.
> 
> Remove this code, thus simplifying b53_get_mac_eee().
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

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

    Andrew


From broonie at kernel.org  Fri Feb  2 05:30:59 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 2 Feb 2024 13:30:59 +0000
Subject: [PATCH v2 06/25] KVM: arm64: nv: Add sanitising to VNCR-backed
 HCRX_EL2
In-Reply-To: <ZbytUKPFYiP2cdd8@linux.dev>
References: <20240130204533.693853-1-maz@kernel.org>
 <20240130204533.693853-7-maz@kernel.org>
 <ZbytUKPFYiP2cdd8@linux.dev>
Message-ID: <4911fc9f-5eeb-4861-b44b-f80f9f512fb1@sirena.org.uk>

On Fri, Feb 02, 2024 at 08:52:32AM +0000, Oliver Upton wrote:
> On Tue, Jan 30, 2024 at 08:45:13PM +0000, Marc Zyngier wrote:

> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, D128, IMP))
> > +		res0 |= HCRX_EL2_D128En;
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
> > +		res0 |= HCRX_EL2_PTTWI;

> Ok, not fair. The latest public version of the ARM ARM doesn't have any
> of this. Where are you getting it from?

We publish updates of the system register and instruction encodings much
more frequently than we publish updates to the full ARM, these are
released as DDI0601.  You can currently find them at:

    https://developer.arm.com/documentation/ddi0601/
    https://developer.arm.com/downloads/-/exploration-tools

but those URLs might change at some point (the second one has downloads,
the first is a directly viewable web page).  There's also DDI0602 with
SVE instructions.  These are generally the first place that gets updated
when new things are added.
-------------- 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/20240202/21240213/attachment.sig>

From brgl at bgdev.pl  Fri Feb  2 05:32:54 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 2 Feb 2024 14:32:54 +0100
Subject: [PATCH v4 1/4] gpio: vf610: allow disabling the vf610 driver
In-Reply-To: <20240124205900.14791-2-martin@kaiser.cx>
References: <20240124205900.14791-1-martin@kaiser.cx> <20240124205900.14791-2-martin@kaiser.cx>
Message-ID: <CAMRc=MdZQ+TGQTAQLGqeT0DidgVUxSTTkXHwNwiat-ADahjwSw@mail.gmail.com>

On Wed, Jan 24, 2024 at 9:59?PM Martin Kaiser <martin at kaiser.cx> wrote:
>
> The vf610 gpio driver is enabled by default for all i.MX machines,
> without any option to disable it in a board-specific config file.
>
> Most i.MX chipsets have no hardware for this driver. Change the default
> to enable GPIO_VF610 for SOC_VF610 and disable it otherwise.
>
> Add a text description after the bool type, this makes the driver
> selectable by make config etc.
>
> Fixes: 30a35c07d9e9 ("gpio: vf610: drop the SOC_VF610 dependency for GPIO_VF610")
> Signed-off-by: Martin Kaiser <martin at kaiser.cx>
> ---

Applied, thanks!

Bart


From brgl at bgdev.pl  Fri Feb  2 05:33:07 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 2 Feb 2024 14:33:07 +0100
Subject: [PATCH v4 2/4] gpio: vf610: enable COMPILE_TEST
In-Reply-To: <20240124205900.14791-3-martin@kaiser.cx>
References: <20240124205900.14791-1-martin@kaiser.cx> <20240124205900.14791-3-martin@kaiser.cx>
Message-ID: <CAMRc=MeRjV_Nec1CCb-S5q2HW7d_TFFbbRkhFSXFweaaCQ5uZg@mail.gmail.com>

On Wed, Jan 24, 2024 at 9:59?PM Martin Kaiser <martin at kaiser.cx> wrote:
>
> Enable COMPILE_TEST for the vf610 gpio driver to support test builds on
> systems without this hardware.
>
> Signed-off-by: Martin Kaiser <martin at kaiser.cx>
> ---
> v4:
>  - add a new patch to enable COMPILE_TEST
>
>  drivers/gpio/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 353af1a4d0ac..3081406ff57a 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -713,7 +713,7 @@ config GPIO_UNIPHIER
>  config GPIO_VF610
>         bool "VF610 GPIO support"
>         default y if SOC_VF610
> -       depends on ARCH_MXC
> +       depends on ARCH_MXC || COMPILE_TEST
>         select GPIOLIB_IRQCHIP
>         help
>           Say yes here to support i.MX or Vybrid vf610 GPIOs.
> --
> 2.39.2
>

Applied, thanks!

Bart


From linux at armlinux.org.uk  Fri Feb  2 05:45:39 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 2 Feb 2024 13:45:39 +0000
Subject: [PATCH net-next 3/6] net: fec: remove eee_enabled/eee_active in
 fec_enet_get_eee()
In-Reply-To: <011cb523-0561-436a-9f64-4479648b4770@lunn.ch>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvm-002Pe0-TV@rmk-PC.armlinux.org.uk>
 <011cb523-0561-436a-9f64-4479648b4770@lunn.ch>
Message-ID: <ZbzyAy7Nc7vf+BD9@shell.armlinux.org.uk>

On Fri, Feb 02, 2024 at 02:22:02PM +0100, Andrew Lunn wrote:
> On Fri, Feb 02, 2024 at 09:33:54AM +0000, Russell King (Oracle) wrote:
> > fec_enet_get_eee() sets edata->eee_active and edata->eee_enabled from
> > its own copy, and then calls phy_ethtool_get_eee() which in turn will
> > call genphy_c45_ethtool_get_eee().
> > 
> > genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> > with its own interpretation from the PHYs settings and negotiation
> > result.
> > 
> > Therefore, setting these members in fec_enet_get_eee() is redundant.
> > Remove this, and remove the setting of fep->eee.eee_active member which
> > becomes a write-only variable.
> 
> I _think_ p->eee_enabled becomes write only as well?

Thanks for spotting, I'll remove it in v2!

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


From laurentiu.palcu at oss.nxp.com  Fri Feb  2 05:49:43 2024
From: laurentiu.palcu at oss.nxp.com (Laurentiu Palcu)
Date: Fri, 2 Feb 2024 15:49:43 +0200
Subject: [PATCH v4 2/2] drm/imx/dcss: have all init functions use devres
In-Reply-To: <20240124111904.18261-4-pstanner@redhat.com>
References: <20240124111904.18261-2-pstanner@redhat.com>
 <20240124111904.18261-4-pstanner@redhat.com>
Message-ID: <20240202134943.gl5q6464ibpxvfh6@fsr-ub1664-121.ea.freescale.net>

Hi Philipp,

On Wed, Jan 24, 2024 at 12:19:05PM +0100, Philipp Stanner wrote:
> dcss currently allocates and ioremaps quite a few resources in its probe
> function's call graph. Devres now provides convenient functions which
> perform the same task but do the cleanup automatically.
> 
> Port all memory allocations and ioremap() calls to the devres
> counterparts.
> 
> Signed-off-by: Philipp Stanner <pstanner at redhat.com>

Reviewed-by: Laurentiu Palcu <laurentiu.palcu at oss.nxp.com>

Thanks,
Laurentiu
> ---
>  drivers/gpu/drm/imx/dcss/dcss-blkctl.c | 13 ++-----------
>  drivers/gpu/drm/imx/dcss/dcss-ctxld.c  | 14 +++-----------
>  drivers/gpu/drm/imx/dcss/dcss-dev.c    | 12 ++----------
>  drivers/gpu/drm/imx/dcss/dcss-dev.h    |  1 -
>  drivers/gpu/drm/imx/dcss/dcss-dpr.c    | 21 +++------------------
>  drivers/gpu/drm/imx/dcss/dcss-drv.c    | 12 +++---------
>  drivers/gpu/drm/imx/dcss/dcss-dtg.c    | 26 +++++---------------------
>  drivers/gpu/drm/imx/dcss/dcss-scaler.c | 21 +++------------------
>  drivers/gpu/drm/imx/dcss/dcss-ss.c     | 12 +++---------
>  9 files changed, 24 insertions(+), 108 deletions(-)
> 
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-blkctl.c b/drivers/gpu/drm/imx/dcss/dcss-blkctl.c
> index c9b54bb2692d..803e3fcdb50f 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-blkctl.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-blkctl.c
> @@ -42,14 +42,13 @@ int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base)
>  {
>  	struct dcss_blkctl *blkctl;
>  
> -	blkctl = kzalloc(sizeof(*blkctl), GFP_KERNEL);
> +	blkctl = devm_kzalloc(dcss->dev, sizeof(*blkctl), GFP_KERNEL);
>  	if (!blkctl)
>  		return -ENOMEM;
>  
> -	blkctl->base_reg = ioremap(blkctl_base, SZ_4K);
> +	blkctl->base_reg = devm_ioremap(dcss->dev, blkctl_base, SZ_4K);
>  	if (!blkctl->base_reg) {
>  		dev_err(dcss->dev, "unable to remap BLK CTRL base\n");
> -		kfree(blkctl);
>  		return -ENOMEM;
>  	}
>  
> @@ -60,11 +59,3 @@ int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base)
>  
>  	return 0;
>  }
> -
> -void dcss_blkctl_exit(struct dcss_blkctl *blkctl)
> -{
> -	if (blkctl->base_reg)
> -		iounmap(blkctl->base_reg);
> -
> -	kfree(blkctl);
> -}
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-ctxld.c b/drivers/gpu/drm/imx/dcss/dcss-ctxld.c
> index 3a84cb3209c4..e41d5c2a3ea4 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-ctxld.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-ctxld.c
> @@ -202,7 +202,7 @@ int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base)
>  	struct dcss_ctxld *ctxld;
>  	int ret;
>  
> -	ctxld = kzalloc(sizeof(*ctxld), GFP_KERNEL);
> +	ctxld = devm_kzalloc(dcss->dev, sizeof(*ctxld), GFP_KERNEL);
>  	if (!ctxld)
>  		return -ENOMEM;
>  
> @@ -217,7 +217,7 @@ int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base)
>  		goto err;
>  	}
>  
> -	ctxld->ctxld_reg = ioremap(ctxld_base, SZ_4K);
> +	ctxld->ctxld_reg = devm_ioremap(dcss->dev, ctxld_base, SZ_4K);
>  	if (!ctxld->ctxld_reg) {
>  		dev_err(dcss->dev, "ctxld: unable to remap ctxld base\n");
>  		ret = -ENOMEM;
> @@ -226,18 +226,14 @@ int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base)
>  
>  	ret = dcss_ctxld_irq_config(ctxld, to_platform_device(dcss->dev));
>  	if (ret)
> -		goto err_irq;
> +		goto err;
>  
>  	dcss_ctxld_hw_cfg(ctxld);
>  
>  	return 0;
>  
> -err_irq:
> -	iounmap(ctxld->ctxld_reg);
> -
>  err:
>  	dcss_ctxld_free_ctx(ctxld);
> -	kfree(ctxld);
>  
>  	return ret;
>  }
> @@ -246,11 +242,7 @@ void dcss_ctxld_exit(struct dcss_ctxld *ctxld)
>  {
>  	free_irq(ctxld->irq, ctxld);
>  
> -	if (ctxld->ctxld_reg)
> -		iounmap(ctxld->ctxld_reg);
> -
>  	dcss_ctxld_free_ctx(ctxld);
> -	kfree(ctxld);
>  }
>  
>  static int dcss_ctxld_enable_locked(struct dcss_ctxld *ctxld)
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.c b/drivers/gpu/drm/imx/dcss/dcss-dev.c
> index d448bf1c205e..597e9b7bd4bf 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-dev.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.c
> @@ -109,8 +109,6 @@ static int dcss_submodules_init(struct dcss_dev *dcss)
>  	dcss_ctxld_exit(dcss->ctxld);
>  
>  ctxld_err:
> -	dcss_blkctl_exit(dcss->blkctl);
> -
>  	dcss_clocks_disable(dcss);
>  
>  	return ret;
> @@ -124,7 +122,6 @@ static void dcss_submodules_stop(struct dcss_dev *dcss)
>  	dcss_ss_exit(dcss->ss);
>  	dcss_dtg_exit(dcss->dtg);
>  	dcss_ctxld_exit(dcss->ctxld);
> -	dcss_blkctl_exit(dcss->blkctl);
>  	dcss_clocks_disable(dcss);
>  }
>  
> @@ -190,7 +187,7 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output)
>  		return ERR_PTR(-EBUSY);
>  	}
>  
> -	dcss = kzalloc(sizeof(*dcss), GFP_KERNEL);
> +	dcss = devm_kzalloc(dev, sizeof(*dcss), GFP_KERNEL);
>  	if (!dcss)
>  		return ERR_PTR(-ENOMEM);
>  
> @@ -201,7 +198,7 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output)
>  	ret = dcss_clks_init(dcss);
>  	if (ret) {
>  		dev_err(dev, "clocks initialization failed\n");
> -		goto err;
> +		return ERR_PTR(ret);
>  	}
>  
>  	dcss->of_port = of_graph_get_port_by_id(dev->of_node, 0);
> @@ -233,9 +230,6 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output)
>  clks_err:
>  	dcss_clks_release(dcss);
>  
> -err:
> -	kfree(dcss);
> -
>  	return ERR_PTR(ret);
>  }
>  
> @@ -253,8 +247,6 @@ void dcss_dev_destroy(struct dcss_dev *dcss)
>  	dcss_submodules_stop(dcss);
>  
>  	dcss_clks_release(dcss);
> -
> -	kfree(dcss);
>  }
>  
>  static int dcss_dev_suspend(struct device *dev)
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.h b/drivers/gpu/drm/imx/dcss/dcss-dev.h
> index f27b87c09599..b032e873d227 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-dev.h
> +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.h
> @@ -104,7 +104,6 @@ extern const struct dev_pm_ops dcss_dev_pm_ops;
>  /* BLKCTL */
>  int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base);
>  void dcss_blkctl_cfg(struct dcss_blkctl *blkctl);
> -void dcss_blkctl_exit(struct dcss_blkctl *blkctl);
>  
>  /* CTXLD */
>  int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base);
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-dpr.c b/drivers/gpu/drm/imx/dcss/dcss-dpr.c
> index df9dab949bf2..072eb209249f 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-dpr.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-dpr.c
> @@ -135,7 +135,7 @@ static int dcss_dpr_ch_init_all(struct dcss_dpr *dpr, unsigned long dpr_base)
>  
>  		ch->base_ofs = dpr_base + i * 0x1000;
>  
> -		ch->base_reg = ioremap(ch->base_ofs, SZ_4K);
> +		ch->base_reg = devm_ioremap(dpr->dev, ch->base_ofs, SZ_4K);
>  		if (!ch->base_reg) {
>  			dev_err(dpr->dev, "dpr: unable to remap ch %d base\n",
>  				i);
> @@ -155,7 +155,7 @@ int dcss_dpr_init(struct dcss_dev *dcss, unsigned long dpr_base)
>  {
>  	struct dcss_dpr *dpr;
>  
> -	dpr = kzalloc(sizeof(*dpr), GFP_KERNEL);
> +	dpr = devm_kzalloc(dcss->dev, sizeof(*dpr), GFP_KERNEL);
>  	if (!dpr)
>  		return -ENOMEM;
>  
> @@ -164,18 +164,8 @@ int dcss_dpr_init(struct dcss_dev *dcss, unsigned long dpr_base)
>  	dpr->ctxld = dcss->ctxld;
>  	dpr->ctx_id = CTX_SB_HP;
>  
> -	if (dcss_dpr_ch_init_all(dpr, dpr_base)) {
> -		int i;
> -
> -		for (i = 0; i < 3; i++) {
> -			if (dpr->ch[i].base_reg)
> -				iounmap(dpr->ch[i].base_reg);
> -		}
> -
> -		kfree(dpr);
> -
> +	if (dcss_dpr_ch_init_all(dpr, dpr_base))
>  		return -ENOMEM;
> -	}
>  
>  	return 0;
>  }
> @@ -189,12 +179,7 @@ void dcss_dpr_exit(struct dcss_dpr *dpr)
>  		struct dcss_dpr_ch *ch = &dpr->ch[ch_no];
>  
>  		dcss_writel(0, ch->base_reg + DCSS_DPR_SYSTEM_CTRL0);
> -
> -		if (ch->base_reg)
> -			iounmap(ch->base_reg);
>  	}
> -
> -	kfree(dpr);
>  }
>  
>  static u32 dcss_dpr_x_pix_wide_adjust(struct dcss_dpr_ch *ch, u32 pix_wide,
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-drv.c b/drivers/gpu/drm/imx/dcss/dcss-drv.c
> index ad5f29ea8f6a..d881f5a34760 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-drv.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-drv.c
> @@ -51,15 +51,13 @@ static int dcss_drv_platform_probe(struct platform_device *pdev)
>  
>  	of_node_put(remote);
>  
> -	mdrv = kzalloc(sizeof(*mdrv), GFP_KERNEL);
> +	mdrv = devm_kzalloc(dev, sizeof(*mdrv), GFP_KERNEL);
>  	if (!mdrv)
>  		return -ENOMEM;
>  
>  	mdrv->dcss = dcss_dev_create(dev, hdmi_output);
> -	if (IS_ERR(mdrv->dcss)) {
> -		err = PTR_ERR(mdrv->dcss);
> -		goto err;
> -	}
> +	if (IS_ERR(mdrv->dcss))
> +		return PTR_ERR(mdrv->dcss);
>  
>  	dev_set_drvdata(dev, mdrv);
>  
> @@ -75,8 +73,6 @@ static int dcss_drv_platform_probe(struct platform_device *pdev)
>  dcss_shutoff:
>  	dcss_dev_destroy(mdrv->dcss);
>  
> -err:
> -	kfree(mdrv);
>  	return err;
>  }
>  
> @@ -86,8 +82,6 @@ static void dcss_drv_platform_remove(struct platform_device *pdev)
>  
>  	dcss_kms_detach(mdrv->kms);
>  	dcss_dev_destroy(mdrv->dcss);
> -
> -	kfree(mdrv);
>  }
>  
>  static void dcss_drv_platform_shutdown(struct platform_device *pdev)
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-dtg.c b/drivers/gpu/drm/imx/dcss/dcss-dtg.c
> index 30de00540f63..2968f5d5bd41 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-dtg.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-dtg.c
> @@ -152,7 +152,7 @@ int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base)
>  	int ret = 0;
>  	struct dcss_dtg *dtg;
>  
> -	dtg = kzalloc(sizeof(*dtg), GFP_KERNEL);
> +	dtg = devm_kzalloc(dcss->dev, sizeof(*dtg), GFP_KERNEL);
>  	if (!dtg)
>  		return -ENOMEM;
>  
> @@ -160,11 +160,10 @@ int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base)
>  	dtg->dev = dcss->dev;
>  	dtg->ctxld = dcss->ctxld;
>  
> -	dtg->base_reg = ioremap(dtg_base, SZ_4K);
> +	dtg->base_reg = devm_ioremap(dtg->dev, dtg_base, SZ_4K);
>  	if (!dtg->base_reg) {
> -		dev_err(dcss->dev, "dtg: unable to remap dtg base\n");
> -		ret = -ENOMEM;
> -		goto err_ioremap;
> +		dev_err(dtg->dev, "dtg: unable to remap dtg base\n");
> +		return -ENOMEM;
>  	}
>  
>  	dtg->base_ofs = dtg_base;
> @@ -175,17 +174,7 @@ int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base)
>  	dtg->control_status |= OVL_DATA_MODE | BLENDER_VIDEO_ALPHA_SEL |
>  		((dtg->alpha << DEFAULT_FG_ALPHA_POS) & DEFAULT_FG_ALPHA_MASK);
>  
> -	ret = dcss_dtg_irq_config(dtg, to_platform_device(dcss->dev));
> -	if (ret)
> -		goto err_irq;
> -
> -	return 0;
> -
> -err_irq:
> -	iounmap(dtg->base_reg);
> -
> -err_ioremap:
> -	kfree(dtg);
> +	ret = dcss_dtg_irq_config(dtg, to_platform_device(dtg->dev));
>  
>  	return ret;
>  }
> @@ -193,11 +182,6 @@ int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base)
>  void dcss_dtg_exit(struct dcss_dtg *dtg)
>  {
>  	free_irq(dtg->ctxld_kick_irq, dtg);
> -
> -	if (dtg->base_reg)
> -		iounmap(dtg->base_reg);
> -
> -	kfree(dtg);
>  }
>  
>  void dcss_dtg_sync_set(struct dcss_dtg *dtg, struct videomode *vm)
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-scaler.c b/drivers/gpu/drm/imx/dcss/dcss-scaler.c
> index 47852b9dd5ea..825728c356ff 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-scaler.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-scaler.c
> @@ -302,7 +302,7 @@ static int dcss_scaler_ch_init_all(struct dcss_scaler *scl,
>  
>  		ch->base_ofs = scaler_base + i * 0x400;
>  
> -		ch->base_reg = ioremap(ch->base_ofs, SZ_4K);
> +		ch->base_reg = devm_ioremap(scl->dev, ch->base_ofs, SZ_4K);
>  		if (!ch->base_reg) {
>  			dev_err(scl->dev, "scaler: unable to remap ch base\n");
>  			return -ENOMEM;
> @@ -318,7 +318,7 @@ int dcss_scaler_init(struct dcss_dev *dcss, unsigned long scaler_base)
>  {
>  	struct dcss_scaler *scaler;
>  
> -	scaler = kzalloc(sizeof(*scaler), GFP_KERNEL);
> +	scaler = devm_kzalloc(dcss->dev, sizeof(*scaler), GFP_KERNEL);
>  	if (!scaler)
>  		return -ENOMEM;
>  
> @@ -327,18 +327,8 @@ int dcss_scaler_init(struct dcss_dev *dcss, unsigned long scaler_base)
>  	scaler->ctxld = dcss->ctxld;
>  	scaler->ctx_id = CTX_SB_HP;
>  
> -	if (dcss_scaler_ch_init_all(scaler, scaler_base)) {
> -		int i;
> -
> -		for (i = 0; i < 3; i++) {
> -			if (scaler->ch[i].base_reg)
> -				iounmap(scaler->ch[i].base_reg);
> -		}
> -
> -		kfree(scaler);
> -
> +	if (dcss_scaler_ch_init_all(scaler, scaler_base))
>  		return -ENOMEM;
> -	}
>  
>  	return 0;
>  }
> @@ -351,12 +341,7 @@ void dcss_scaler_exit(struct dcss_scaler *scl)
>  		struct dcss_scaler_ch *ch = &scl->ch[ch_no];
>  
>  		dcss_writel(0, ch->base_reg + DCSS_SCALER_CTRL);
> -
> -		if (ch->base_reg)
> -			iounmap(ch->base_reg);
>  	}
> -
> -	kfree(scl);
>  }
>  
>  void dcss_scaler_ch_enable(struct dcss_scaler *scl, int ch_num, bool en)
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-ss.c b/drivers/gpu/drm/imx/dcss/dcss-ss.c
> index 8ddf08da911b..0df81866fb7b 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-ss.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-ss.c
> @@ -83,7 +83,7 @@ int dcss_ss_init(struct dcss_dev *dcss, unsigned long ss_base)
>  {
>  	struct dcss_ss *ss;
>  
> -	ss = kzalloc(sizeof(*ss), GFP_KERNEL);
> +	ss = devm_kzalloc(dcss->dev, sizeof(*ss), GFP_KERNEL);
>  	if (!ss)
>  		return -ENOMEM;
>  
> @@ -91,10 +91,9 @@ int dcss_ss_init(struct dcss_dev *dcss, unsigned long ss_base)
>  	ss->dev = dcss->dev;
>  	ss->ctxld = dcss->ctxld;
>  
> -	ss->base_reg = ioremap(ss_base, SZ_4K);
> +	ss->base_reg = devm_ioremap(ss->dev, ss_base, SZ_4K);
>  	if (!ss->base_reg) {
> -		dev_err(dcss->dev, "ss: unable to remap ss base\n");
> -		kfree(ss);
> +		dev_err(ss->dev, "ss: unable to remap ss base\n");
>  		return -ENOMEM;
>  	}
>  
> @@ -108,11 +107,6 @@ void dcss_ss_exit(struct dcss_ss *ss)
>  {
>  	/* stop SS */
>  	dcss_writel(0, ss->base_reg + DCSS_SS_SYS_CTRL);
> -
> -	if (ss->base_reg)
> -		iounmap(ss->base_reg);
> -
> -	kfree(ss);
>  }
>  
>  void dcss_ss_subsam_set(struct dcss_ss *ss)
> -- 
> 2.43.0
> 


From laurentiu.palcu at oss.nxp.com  Fri Feb  2 05:54:48 2024
From: laurentiu.palcu at oss.nxp.com (Laurentiu Palcu)
Date: Fri, 2 Feb 2024 15:54:48 +0200
Subject: [PATCH v4 0/2] drm/imx/dcss: implement region request and devres
In-Reply-To: <20240124111904.18261-2-pstanner@redhat.com>
References: <20240124111904.18261-2-pstanner@redhat.com>
Message-ID: <20240202135448.5gidibw5lyxt6d6d@fsr-ub1664-121.ea.freescale.net>

Hi Philipp,

Applied series to drm-misc-next.

Thanks,
Laurentiu

On Wed, Jan 24, 2024 at 12:19:03PM +0100, Philipp Stanner wrote:
> @Laurentiu:
> Thank you very much for the review. I was indeed on an older branch. As
> Linus's master is currently broken for ARM64 [1], unfortunately, I built
> it instead against:
> 60096f0a77600ac2cc92b82fee279d1905576950
> 
> Hope that's fine.
> 
> 
> Changes in v4:
> - Add Laurentiu's Reviewed-by to patch #1
> - Remove unnecsseray struct device pointers from all touched files
> - Rebase against newer kernel due to changes in dcss_drv_platform_remove()
> 
> Changes in v3:
> - Fix build errors (missing variable, forgotten remove to call of deleted
>   function)
> 
> Changes in v2:
> - Add the region-request to this patch-series. That was previously a
>   separate patch.
> 
> dcss currently does not request its memory resource. This series adds
> that request with devres. As we're at it, it also ports all the ioremaps
> and associated allocations to devres.
> 
> I can build this, but I don't have the hardware available to test it. So
> you might want to have a closer look.
> 
> P.
> 
> [1] https://lore.kernel.org/lkml/45ad1d0f-a10f-483e-848a-76a30252edbe at paulmck-laptop/
> 
> 
> Philipp Stanner (2):
>   drm/imx/dcss: request memory region
>   drm/imx/dcss: have all init functions use devres
> 
>  drivers/gpu/drm/imx/dcss/dcss-blkctl.c | 13 ++-----------
>  drivers/gpu/drm/imx/dcss/dcss-ctxld.c  | 14 +++-----------
>  drivers/gpu/drm/imx/dcss/dcss-dev.c    | 19 +++++++++----------
>  drivers/gpu/drm/imx/dcss/dcss-dev.h    |  1 -
>  drivers/gpu/drm/imx/dcss/dcss-dpr.c    | 21 +++------------------
>  drivers/gpu/drm/imx/dcss/dcss-drv.c    | 12 +++---------
>  drivers/gpu/drm/imx/dcss/dcss-dtg.c    | 26 +++++---------------------
>  drivers/gpu/drm/imx/dcss/dcss-scaler.c | 21 +++------------------
>  drivers/gpu/drm/imx/dcss/dcss-ss.c     | 12 +++---------
>  9 files changed, 31 insertions(+), 108 deletions(-)
> 
> -- 
> 2.43.0
> 


From jani.nikula at linux.intel.com  Fri Feb  2 05:58:39 2024
From: jani.nikula at linux.intel.com (Jani Nikula)
Date: Fri, 02 Feb 2024 15:58:39 +0200
Subject: [PATCH v5 15/44] drm/connector: hdmi: Compute bpc and
 format automatically
In-Reply-To: <vydlftxen23kd2odwegxbtpaz73sy2lgpv7nlynfjr3p2xvc2b@7lkdkaw3gp5q>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-15-6538e19d634d@kernel.org>
 <CAPY8ntBQ+qY9441-rMzq_JAoYAaY_r+E-ADv7Wry0tJNTzKpwg@mail.gmail.com>
 <jlkoofv7nszj2uqmo2672yo4wjd3yjqarge2l2hxofixcchu6a@j72pa4iybitd>
 <CAPY8ntAmXyKtebMeM7rLtgRR+QwL1H+UCwSO=bLBQN4TsgwsDg@mail.gmail.com>
 <vydlftxen23kd2odwegxbtpaz73sy2lgpv7nlynfjr3p2xvc2b@7lkdkaw3gp5q>
Message-ID: <87y1c3dl2o.fsf@intel.com>

On Thu, 01 Feb 2024, Maxime Ripard <mripard at kernel.org> wrote:
> We've discussed that on IRC today. I'm not sure there was a conclusion
> other than "well this doesn't seem right". I think we should at least
> provide different EDIDs depending on the connector type indeed, but
> there was also a few discussions that arose:
>
>   - Is it useful to have embedded EDIDs in the kernel at all, and could
>     we just get rid of it?
>
>   - Should we expose those EDIDs to userspace, and what happens to the
>     compositor when we do?
>
>   - The current way to generate those EDIDs isn't... optimal? Should we
>     get rid of that as well?
>
> Anyway, all of those issues have been here for a while so I don't really
> expect this series to fix that.

IMO the direction should be towards deprecating and removing the builtin
firmware EDIDs from the kernel instead of adding more or expanding on
them. They were only ever meant to be the immediate aid to get something
on screen so the user could provide a proper EDID via userspace.

BR,
Jani.


-- 
Jani Nikula, Intel


From rogerq at kernel.org  Fri Feb  2 05:59:40 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 2 Feb 2024 15:59:40 +0200
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <20240202121828.oo7grngyh2heqdxn@disposal>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-5-rogerq@kernel.org>
 <20240201-viewpoint-upload-fb714f650ff5@spud>
 <20240201-violet-chalice-51a73f113e7b@spud>
 <20240201183522.ssj553rwefr2wuqi@iaqt7>
 <20240201-clad-unopposed-ccfdfe53b770@spud>
 <bc3ab60f-539b-41d0-8595-6e0b55f2763d@kernel.org>
 <20240202-unzip-whacky-bb2f151c618b@wendy>
 <dc3c93dc-74d9-4b1c-a771-3ee6f67b5dcc@kernel.org>
 <20240202121828.oo7grngyh2heqdxn@disposal>
Message-ID: <2dbbcc17-38e9-48b4-a0b1-450350644fb9@kernel.org>



On 02/02/2024 14:18, Nishanth Menon wrote:
> On 12:13-20240202, Roger Quadros wrote:
> [..]
>>>>
>>>> As DTS and driver will be merged by separate maintainers I thought it
>>>> would be easier for maintainers this way.
>>>
>>> dts and driver might be merged by different people, but dt-bindings and
>>> drivers are merged by the same people. This is a bindings patch, not a
>>
>> If we do that then I get a bunch of dtbs_check warnings
>>
>> dwc3-usb at f900000: reg: [[0, 261095424, 0, 2048], [0, 261128192, 0, 1024]] is too long
> 
> Just my 2 cents: If the binding (and driver) change was truly backward
> compatible (which it should be - for example: errata can only be
> applied if the second property is described), then you want to control
> that reg property to add minItems? - thatm I think will allow the dts
> change to come in at the next cycle once the binding has been merged.
> 

Thanks for the hint.
Please drop patches 4 and 5 in case you pick this series.

I'll send patch 4 along with the driver series v2.
Patch 5, I'll send after the DT binding has been merged.

-- 
cheers,
-roger


From shradha.t at samsung.com  Fri Feb  2 03:59:30 2024
From: shradha.t at samsung.com (Shradha Todi)
Date: Fri, 2 Feb 2024 17:29:30 +0530
Subject: [PATCH v4 1/2] clk: Provide managed helper to get and enable
 bulk clocks
In-Reply-To: <20240129065448.GC2971@thinkpad>
References: <20240124103838.32478-1-shradha.t@samsung.com>
	<CGME20240124103855epcas5p27400bd95df42f36b9547a4e28aa26f5d@epcas5p2.samsung.com>
	<20240124103838.32478-2-shradha.t@samsung.com>
	<20240129065448.GC2971@thinkpad>
Message-ID: <08a901da55cf$4ee48000$ecad8000$@samsung.com>



> -----Original Message-----
> From: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Sent: 29 January 2024 12:25
> To: Shradha Todi <shradha.t at samsung.com>
> Cc: linux-clk at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
> pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-samsung-
> soc at vger.kernel.org; mturquette at baylibre.com; sboyd at kernel.org;
> jingoohan1 at gmail.com; lpieralisi at kernel.org; kw at linux.com; robh at kernel.org;
> bhelgaas at google.com; krzysztof.kozlowski at linaro.org;
> alim.akhtar at samsung.com; linux at armlinux.org.uk;
> m.szyprowski at samsung.com; pankaj.dubey at samsung.com
> Subject: Re: [PATCH v4 1/2] clk: Provide managed helper to get and enable bulk
> clocks
> 
> On Wed, Jan 24, 2024 at 04:08:37PM +0530, Shradha Todi wrote:
> > Provide a managed devm_clk_bulk* wrapper to get and enable all bulk
> > clocks in order to simplify drivers that keeps all clocks enabled for
> > the time of driver operation.
> >
> > Suggested-by: Marek Szyprowski <m.szyprowski at samsung.com>
> > Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> > ---
> >  drivers/clk/clk-devres.c | 40
> ++++++++++++++++++++++++++++++++++++++++
> >  include/linux/clk.h      | 24 ++++++++++++++++++++++++
> >  2 files changed, 64 insertions(+)
> >
> > diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c index
> > 4fb4fd4b06bd..cbbd2cc339c3 100644
> > --- a/drivers/clk/clk-devres.c
> > +++ b/drivers/clk/clk-devres.c
> > @@ -182,6 +182,46 @@ int __must_check devm_clk_bulk_get_all(struct
> > device *dev,  }  EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all);
> >
> > +static void devm_clk_bulk_release_all_enable(struct device *dev, void
> > +*res) {
> > +	struct clk_bulk_devres *devres = res;
> > +
> > +	clk_bulk_disable_unprepare(devres->num_clks, devres->clks);
> > +	clk_bulk_put_all(devres->num_clks, devres->clks); }
> > +
> > +int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
> > +					      struct clk_bulk_data **clks) {
> > +	struct clk_bulk_devres *devres;
> > +	int ret;
> > +
> > +	devres = devres_alloc(devm_clk_bulk_release_all_enable,
> > +			      sizeof(*devres), GFP_KERNEL);
> > +	if (!devres)
> > +		return -ENOMEM;
> > +
> > +	ret = clk_bulk_get_all(dev, &devres->clks);
> > +	if (ret > 0) {
> > +		*clks = devres->clks;
> > +		devres->num_clks = ret;
> > +	} else {
> > +		devres_free(devres);
> > +		return ret;
> > +	}
> 
> How about:
> 
> 	ret = clk_bulk_get_all(dev, &devres->clks);
> 	if (ret <= 0) {
> 		devres_free(devres);
> 		return ret;
> 	}
> 
> 	*clks = devres->clks;
> 	devres->num_clks = ret;
> 
> Even though this patch follows the pattern used by the rest of the APIs in the
> driver, IMO above makes it more readable.
> 

Since I have usually seen that maintainers suggest to maintain the coding style of the file, I followed the same.
If you have a stronger reason to change this, please let me know
Marek, Michael, Stephen please let us know what do you think about this?

> > +
> > +	ret = clk_bulk_prepare_enable(devres->num_clks, *clks);
> > +	if (!ret) {
> > +		devres_add(dev, devres);
> > +	} else {
> > +		clk_bulk_put_all(devres->num_clks, devres->clks);
> > +		devres_free(devres);
> > +	}
> > +
> 
> Same as above:
> 
> 	ret = clk_bulk_prepare_enable(devres->num_clks, *clks);
> 	if (ret) {
> 		clk_bulk_put_all(devres->num_clks, devres->clks);
> 		devres_free(devres);
> 		return ret;
> 	}
> 
> 	devres_add(dev, devres);
> 
> > +	return ret;
> 
> 	return 0;
> 

Same as above

> > +}
> > +EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enable);
> > +
> >  static int devm_clk_match(struct device *dev, void *res, void *data)
> > {
> >  	struct clk **c = res;
> > diff --git a/include/linux/clk.h b/include/linux/clk.h index
> > 1ef013324237..a005e709b7bd 100644
> > --- a/include/linux/clk.h
> > +++ b/include/linux/clk.h
> > @@ -438,6 +438,23 @@ int __must_check
> > devm_clk_bulk_get_optional(struct device *dev, int num_clks,  int
> __must_check devm_clk_bulk_get_all(struct device *dev,
> >  				       struct clk_bulk_data **clks);
> >
> > +/**
> > + * devm_clk_bulk_get_all_enable - managed get multiple clk consumers and
> > + *				  enable all clks
> 
> "Get and enable all clocks of the consumer (managed)"
> 

Will take this up in the next patchset

> > + * @dev: device for clock "consumer"
> > + * @clks: pointer to the clk_bulk_data table of consumer
> > + *
> > + * Returns success (0) or negative errno.
> > + *
> > + * This helper function allows drivers to get several clk
> 
> "This helper function allows drivers to get all clocks of the consumer and enables
> them..."
> 
> - Mani
> 

Will take this up. Thanks for your review Mani!

> > + * consumers and enable all of them in one operation with management.
> > + * The clks will automatically be disabled and freed when the device
> > + * is unbound.
> > + */
> > +
> > +int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
> > +					      struct clk_bulk_data **clks);
> > +
> >  /**
> >   * devm_clk_get - lookup and obtain a managed reference to a clock producer.
> >   * @dev: device for clock "consumer"
> > @@ -960,6 +977,13 @@ static inline int __must_check
> devm_clk_bulk_get_all(struct device *dev,
> >  	return 0;
> >  }
> >
> > +static inline int __must_check devm_clk_bulk_get_all_enable(struct device
> *dev,
> > +						struct clk_bulk_data **clks)
> > +{
> > +
> > +	return 0;
> > +}
> > +
> >  static inline struct clk *devm_get_clk_from_child(struct device *dev,
> >  				struct device_node *np, const char *con_id)  {
> > --
> > 2.17.1
> >
> 
> --
> ????????? ????????




From josua at solid-run.com  Fri Feb  2 06:22:19 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 15:22:19 +0100
Subject: [PATCH v3 3/5] arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
In-Reply-To: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
References: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
Message-ID: <20240202-add-am64-som-v3-3-2f44023d50e9@solid-run.com>

From: Suman Anna <s-anna at ti.com>

The ICSSG IP on AM64x SoCs have two Industrial Ethernet Peripherals (IEPs)
to manage/generate Industrial Ethernet functions such as time stamping.
Each IEP sub-module is sourced from an internal clock mux that can be
derived from either of the IP instance's ICSSG_IEP_GCLK or from another
internal ICSSG CORE_CLK mux. Add both the IEP nodes for both the ICSSG
instances. The IEP clock is currently configured to be derived
indirectly from the ICSSG_ICLK running at 250 MHz.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
Signed-off-by: Suman Anna <s-anna at ti.com>
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index 0be642bc1b86..8130ee02a3d9 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -1232,6 +1232,18 @@ icssg0_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg0_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
+		icssg0_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
 		icssg0_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
@@ -1373,6 +1385,18 @@ icssg1_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg1_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
+		icssg1_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
 		icssg1_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;

-- 
2.35.3



From josua at solid-run.com  Fri Feb  2 06:22:17 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 15:22:17 +0100
Subject: [PATCH v3 1/5] dt-bindings: arm: ti: Add bindings for SolidRun
 AM642 HummingBoard-T
In-Reply-To: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
References: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
Message-ID: <20240202-add-am64-som-v3-1-2f44023d50e9@solid-run.com>

Add bindings for SolidRun AM642 HummingBoard-T Board, which is the
evaluation board for SolidRun AM642 SoM.

Signed-off-by: Josua Mayer <josua at solid-run.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/ti/k3.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
index 03d2a0d79fb0..b9f2a8d36874 100644
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -85,6 +85,13 @@ properties:
           - const: tq,am642-tqma6442l
           - const: ti,am642
 
+      - description: K3 AM642 SoC SolidRun SoM based boards
+        items:
+          - enum:
+              - solidrun,am642-hummingboard-t
+          - const: solidrun,am642-sr-som
+          - const: ti,am642
+
       - description: K3 AM654 SoC
         items:
           - enum:

-- 
2.35.3



From josua at solid-run.com  Fri Feb  2 06:22:18 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 15:22:18 +0100
Subject: [PATCH v3 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
References: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
Message-ID: <20240202-add-am64-som-v3-2-2f44023d50e9@solid-run.com>

Convert the abracon abx80x rtc text bindings to dt-schema format.

In addition to the text description reference generic interrupts
properties and add an example.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ----------
 .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 72 ++++++++++++++++++++++
 2 files changed, 72 insertions(+), 31 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
deleted file mode 100644
index 2405e35a1bc0..000000000000
--- a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-Abracon ABX80X I2C ultra low power RTC/Alarm chip
-
-The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
-ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
-is the superset of ab180x.
-
-Required properties:
-
- - "compatible": should one of:
-        "abracon,abx80x"
-        "abracon,ab0801"
-        "abracon,ab0803"
-        "abracon,ab0804"
-        "abracon,ab0805"
-        "abracon,ab1801"
-        "abracon,ab1803"
-        "abracon,ab1804"
-        "abracon,ab1805"
-        "microcrystal,rv1805"
-	Using "abracon,abx80x" will enable chip autodetection.
- - "reg": I2C bus address of the device
-
-Optional properties:
-
-The abx804 and abx805 have a trickle charger that is able to charge the
-connected battery or supercap. Both the following properties have to be defined
-and valid to enable charging:
-
- - "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
- - "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
-                          resistor, the other values are in kOhm.
diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
new file mode 100644
index 000000000000..0c2cf6410604
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Abracon ABX80X I2C ultra low power RTC/Alarm chip
+
+maintainers:
+  - devicetree at vger.kernel.org
+
+allOf:
+  - $ref: rtc.yaml#
+  - $ref: /schemas/interrupts.yaml#
+
+properties:
+  compatible:
+    description:
+      Select a specific compatible chip.
+
+      'abracon,abx80x' has special meaning,
+      it provides auto-dection based on ID register.
+    enum:
+      - abracon,abx80x
+      - abracon,ab0801
+      - abracon,ab0803
+      - abracon,ab0804
+      - abracon,ab0805
+      - abracon,ab1801
+      - abracon,ab1803
+      - abracon,ab1804
+      - abracon,ab1805
+      - microcrystal,rv1805
+
+  reg:
+    maxItems: 1
+
+  abracon,tc-diode:
+    description:
+      Trickle-charge diode type.
+      Required to enable charging backup battery.
+
+      Supported are 'standard' diodes with a 0.6V drop
+      and 'schottky' diodes with a 0.3V drop.
+    $ref: /schemas/types.yaml#/definitions/string
+    enum:
+      - standard
+      - schottky
+
+  abracon,tc-resistor:
+    description:
+      Trickle-charge resistor value in kOhm.
+      Required to enable charging backup battery.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 3, 6, 11]
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    rtc: rtc at 69 {
+        compatible = "abracon,abx80x";
+        reg = <0x69>;
+        abracon,tc-diode = "schottky";
+        abracon,tc-resistor = <3>;
+        interrupt-parent = <&gpio0>;
+        interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
+    };

-- 
2.35.3



From josua at solid-run.com  Fri Feb  2 06:22:16 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 15:22:16 +0100
Subject: [PATCH v3 0/5] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
Message-ID: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>

This series adds DT bindings and dts descriptions for SolidRun AM642
based SoM and Hummingboard EVB.

Additionally a commit from downstream vendor kernel are included,
enhancing support for pru based ethernet.
I wasn't sure how to properly annotate it in commit description /
signed-off area ...:

1. add description for "Industrial Ethernet Peripherals" (IEP) to am64
   https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/commit/arch/arm64/boot/dts/ti/k3-am64-main.dtsi?h=ti-linux-6.1.y-cicd&id=5afb73d82a014b59462162d960b350b8c58e5ae6
   IEP is already supported in-tree by a driver, and used in
   k3-am65-main.dtsi.

Unfortunately dtbs_check reported many problems, I put some remarks:

- 'mux-controller' does not match any of the regexes
  The expectation seems to be that a mux-controller at minimum has an
  address, something to put behind an @. However this is a gpio mux, not
  sure how to name it better.

- unevaluated properties: interrupts, interrupt-parent
  sensors and flash yaml are missing interrupt descriptions, but these
  parts definitely have an interrupt signal in this solidrun board.

- wrong names for pinctrl nodes
  Other TI DTSs consistently end with *-pins-default. Should a different
  naming convention be used?

- cdns,phy-type required property
  inherited from k3-am64-main.dtsi
  there is a PHY_NONE value in dt-bindings/phy/phy.h,
  but not allowed in phy-cadence-torrent.yaml

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
Changes in v3:
- removed lots more status properties, double-checked against soc dtsi
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
  (reported by Andrew Davis <afd at ti.com>)
- removed intentionally-disabled pcie node from dts
- rewrote yaml bindings to use enum instead of anyof+const+description
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
- abracon yaml
  - added missing maintainer
  - added diode type property type
  - added example
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>)
  - added reference to /schemas/interrupts.yaml#
- use generic name for pru ethernet controller node
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>)
- removed unnamed dmas from pru ethernet controller node
- moved pcie/usb3 features to dtb overlays
- Link to v2: https://lore.kernel.org/r/20240112-add-am64-som-v2-0-1385246c428c at solid-run.com

Changes in v2:
- reordered patchset to drop separate patch adding iep handle to som
- moved dtbs_check warnings to cover letter
- converted abracon abx80x rtc bindings to yaml
- updated dts:
  - remove unnecessary status properties
  - changed non-generic node names
  - use color property for led descriptions,
    they have no default function on evaluation board
  - drop earlycon bootargs from chosen node
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
- converted charger node to comment, part not assembled, has no bindings
- picked up acked-by on board bindings patch
- Link to v1: https://lore.kernel.org/r/20240103-add-am64-som-v1-0-dda1f9227aef at solid-run.com

---
Josua Mayer (4):
      dt-bindings: arm: ti: Add bindings for SolidRun AM642 HummingBoard-T
      dt-bindings: rtc: abx80x: convert to yaml
      arm64: dts: add description for solidrun am642 som and evaluation board
      arm64: dts: ti: hummingboard-t: add overlays for m.2 pci-e and usb-3

Suman Anna (1):
      arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes

 Documentation/devicetree/bindings/arm/ti/k3.yaml   |   7 +
 .../devicetree/bindings/rtc/abracon,abx80x.txt     |  31 --
 .../devicetree/bindings/rtc/abracon,abx80x.yaml    |  72 +++
 arch/arm64/boot/dts/ti/Makefile                    |   7 +
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi           |  24 +
 .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  |  45 ++
 .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  |  44 ++
 arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 592 +++++++++++++++++++++
 9 files changed, 1083 insertions(+), 31 deletions(-)
---
base-commit: 861deac3b092f37b2c5e6871732f3e11486f7082
change-id: 20240101-add-am64-som-51a1ca47edf3

Sincerely,
-- 
Josua Mayer <josua at solid-run.com>



From josua at solid-run.com  Fri Feb  2 06:22:21 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 15:22:21 +0100
Subject: [PATCH v3 5/5] arm64: dts: ti: hummingboard-t: add overlays for
 m.2 pci-e and usb-3
In-Reply-To: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
References: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
Message-ID: <20240202-add-am64-som-v3-5-2f44023d50e9@solid-run.com>

HummingBoard-T features two M.2 connectors labeled "M1" and "M2".
The single SerDes lane of the SoC can be routed to either M1 pci-e
signals, or M2 usb-3 signals by a gpio-controlled mux.

Add overlays for each configuration.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/Makefile                    |  6 +++
 .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  | 45 ++++++++++++++++++++++
 .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  | 44 +++++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 041c3b71155e..ace72b4b85b0 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -31,8 +31,14 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb
 
 # Boards with AM64x SoC
+k3-am642-hummingboard-t-pcie-dtbs := \
+	k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-pcie.dtbo
+k3-am642-hummingboard-t-usb3-dtbs := \
+	k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-usb3.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-pcie.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-usb3.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
new file mode 100644
index 000000000000..fd3f8d00c56a
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable PCI-E.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&pcie0_rc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_pins_default>;
+	reset-gpios = <&main_gpio1 15 GPIO_ACTIVE_HIGH>;
+	phys = <&serdes0_link>;
+	phy-names = "pcie-phy";
+	num-lanes = <1>;
+	status = "okay";
+};
+
+&serdes0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	serdes0_link: phy at 0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		cdns,phy-type = <PHY_TYPE_PCIE>;
+		#phy-cells = <0>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes_ln_ctrl {
+	idle-states = <AM64_SERDES0_LANE0_PCIE0>;
+};
+
+&serdes_mux {
+	idle-state = <1>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
new file mode 100644
index 000000000000..ffcc3bd3c7bc
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable USB-3.1.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&serdes0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	serdes0_link: phy at 0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		cdns,phy-type = <PHY_TYPE_USB3>;
+		#phy-cells = <0>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes_ln_ctrl {
+	idle-states = <AM64_SERDES0_LANE0_USB>;
+};
+
+&serdes_mux {
+	idle-state = <0>;
+};
+
+&usbss0 {
+	/delete-property/ ti,usb2-only;
+};
+
+&usb0 {
+	maximum-speed = "super-speed";
+	phys = <&serdes0_link>;
+	phy-names = "cdns3,usb3-phy";
+};

-- 
2.35.3



From josua at solid-run.com  Fri Feb  2 06:22:20 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 15:22:20 +0100
Subject: [PATCH v3 4/5] arm64: dts: add description for solidrun am642 som
 and evaluation board
In-Reply-To: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
References: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
Message-ID: <20240202-add-am64-som-v3-4-2f44023d50e9@solid-run.com>

Add description for the SolidRun AM642 SoM, and HummingBoard-T
evaluation board.

The SoM features:
- 1x cpsw ethernet with phy
- 2x pru ethernet with phy
- eMMC
- spi flash (assembly option)

Additionally microSD and usb-2.0 otg are included in the SoM
description as they are supported boot sources for the SOC boot-rom.

The Carrier provides:
- 3x RJ45 connector
- 2x M.2 connector
- USB-2.0 Hub
- USB-A Connector
- LEDs
- 2x CAN transceiver
- 1x RS485 transceiver
- sensors

The M.2 connectors support either USB-3.1 or PCI-E depending on status
of a mux. By default the mux is switched off.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/Makefile                    |   1 +
 arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 592 +++++++++++++++++++++
 3 files changed, 885 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 77a347f9f47d..041c3b71155e 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -32,6 +32,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb
 
 # Boards with AM64x SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
new file mode 100644
index 000000000000..ebaf281e1e1e
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * DTS for SolidRun AM642 HummingBoard-T,
+ * running on Cortex A53.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-am642.dtsi"
+#include "k3-am642-sr-som.dtsi"
+
+/ {
+	model = "SolidRun AM642 HummingBoard-T";
+	compatible = "solidrun,am642-hummingboard-t", "solidrun,am642-sr-som", "ti,am642";
+
+	aliases {
+		serial5 = &main_uart3;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&leds_pins_default>;
+
+		/* D24 */
+		led1: led-1 {
+			label = "led1";
+			gpios = <&main_gpio0 29 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		/* D25 */
+		led2: led-2 {
+			label = "led2";
+			gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		/* D26 */
+		led3: led-3 {
+			label = "led3";
+			gpios = <&main_gpio0 33 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+	};
+
+	regulator-m2-3v3 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&regulator_pcie_3v3_pins_default>;
+		regulator-name = "m2-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&main_gpio1 17 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	regulator-vpp-1v8 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&regulator_vpp_1v8_pins_default>;
+		regulator-name = "vpp-1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		gpio = <&main_gpio1 78 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	serdes_mux: mux-controller {
+		compatible = "gpio-mux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&serdes_mux_pins_default>;
+		#mux-control-cells = <0>;
+		/*
+		 * Mux has 2 IOs:
+		 * - select: 0 = USB-3 (M2); 1 = PCIE (M1)
+		 * - shutdown: 0 = active; 1 = disabled (high impedance)
+		 */
+		mux-gpios = <&main_gpio1 40 GPIO_ACTIVE_HIGH>, <&main_gpio1 41 GPIO_ACTIVE_HIGH>;
+		/* default disabled */
+		idle-state = <2>;
+	};
+};
+
+&main_gpio0 {
+	m2-reset-hog {
+		gpio-hog;
+		gpios = <12 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m2-reset";
+	};
+
+	m1-m2-w-disable1-hog {
+		gpio-hog;
+		gpios = <32 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m1-m2-pcie-w-disable1";
+	};
+
+	m1-m2-w-disable2-hog {
+		gpio-hog;
+		gpios = <34 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m1-m2-pcie-w-disable2";
+	};
+};
+
+&main_gpio1 {
+	m1-pcie-clkreq0-hog {
+		gpio-hog;
+		gpios = <11 GPIO_ACTIVE_LOW>;
+		input;
+		line-name = "m1-pcie-clkreq0";
+	};
+
+	m2-pcie-clkreq-hog {
+		gpio-hog;
+		gpios = <35 GPIO_ACTIVE_LOW>;
+		input;
+		line-name = "m2-pcie-clkreq";
+	};
+};
+
+&main_i2c0 {
+	pinctrl-0 = <&main_i2c0_pins_default>, <&main_i2c0_int_pins_default>;
+
+	humidity-sensor at 41 {
+		compatible = "ti,hdc2010";
+		reg = <0x41>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+	light-sensor at 44 {
+		compatible = "ti,opt3001";
+		reg = <0x44>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+	/* charger at 6a */
+};
+
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	status = "okay";
+
+	rtc at 69 {
+		compatible = "abracon,abx80x";
+		reg = <0x69>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtc_int_pins_default>;
+		abracon,tc-diode = "schottky";
+		abracon,tc-resistor = <3>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
+
+&main_mcan0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan0_pins_default>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <8000000>;
+	};
+};
+
+&main_mcan1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan1_pins_default>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <8000000>;
+	};
+};
+
+&main_pmx0 {
+	leds_pins_default: leds-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0074, PIN_OUTPUT, 7)	/* GPMC0_AD14.GPIO0_29 */
+			AM64X_IOPAD(0x0078, PIN_OUTPUT, 7)	/* GPMC0_AD15.GPIO0_30 */
+			AM64X_IOPAD(0x0088, PIN_OUTPUT, 7)	/* GPMC0_OEn_REn.GPIO0_33 */
+		>;
+	};
+
+	main_i2c0_int_pins_default: main-i2c0-pins-int-default {
+		pinctrl-single,pins = <
+			/* external pull-up on Carrier */
+			AM64X_IOPAD(0x0098, PIN_INPUT, 7)	/* GPMC0_WAIT0.GPIO0_37 */
+		>;
+	};
+
+	main_i2c1_pins_default: main-i2c1-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x0268, PIN_INPUT, 0)	/* I2C1_SCL.I2C1_SCL */
+			AM64X_IOPAD(0x026c, PIN_INPUT, 0)	/* I2C1_SDA.I2C1_SDA */
+		>;
+	};
+
+	main_mcan0_pins_default: main-mcan0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0254, PIN_INPUT, 0)	/* MCAN0_RX.MCAN0_RX */
+			AM64X_IOPAD(0x0250, PIN_OUTPUT, 0)	/* MCAN0_TX.MCAN0_TX */
+		>;
+	};
+
+	main_mcan1_pins_default: main-mcan1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x025c, PIN_INPUT, 0)	/* MCAN1_RX.MCAN1_RX */
+			AM64X_IOPAD(0x0258, PIN_OUTPUT, 0)	/* MCAN1_TX.MCAN1_TX */
+		>;
+	};
+
+	main_uart3_pins_default: main-uart3-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x016c, PIN_INPUT, 10)	/* PRG0_PRU0_GPO3.UART3_CTSn */
+			AM64X_IOPAD(0x0170, PIN_OUTPUT, 10)	/* PRG0_PRU0_GPO4.UART3_TXD */
+			AM64X_IOPAD(0x0174, PIN_OUTPUT, 10)	/* PRG0_PRU0_GPO5.UART3_RTSn */
+			AM64X_IOPAD(0x01ac, PIN_INPUT, 10)	/* PRG0_PRU0_GPO19.UART3_RXD */
+		>;
+	};
+
+	pcie0_pins_default: pcie0-pins-default {
+		pinctrl-single,pins = <
+			/* connector M2 RESET */
+			AM64X_IOPAD(0x0030, PIN_OUTPUT, 7)	/* OSPI0_CSn1.GPIO0_12 */
+			/* connectors M1 & M2 W_DISABLE1 */
+			AM64X_IOPAD(0x0084, PIN_OUTPUT, 7)	/* GPMC0_ADVN_ALE.GPIO0_32 */
+			/* connectors M1 & M2 W_DISABLE2 */
+			AM64X_IOPAD(0x008c, PIN_OUTPUT, 7)	/* GPMC0_WEN.GPIO0_34 */
+			/* connectors M1 & M2 PERST0 (PCI Reset) */
+			AM64X_IOPAD(0x019c, PIN_OUTPUT, 7)	/* PRG0_PRU0_GPO15.GPIO1_15 */
+			/* connector M1 CLKREQ0 */
+			AM64X_IOPAD(0x018c, PIN_INPUT, 7)	/* PRG0_PRU0_GPO11.GPIO1_11 */
+			/* connector M2 CLKREQ0 */
+			AM64X_IOPAD(0x01ec, PIN_INPUT, 7)	/* PRG0_PRU1_GPO15.GPIO1_35 */
+		>;
+	};
+
+	regulator_pcie_3v3_pins_default: regulator-pcie-3v3-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01a4, PIN_OUTPUT, 7)	/* PRG0_PRU0_GPO17.GPIO1_17 */
+		>;
+	};
+
+	regulator_vpp_1v8_pins_default: regulator-vpp-1v8-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x029c, PIN_OUTPUT, 7)	/* MMC1_SDWP.GPIO1_78 */
+		>;
+	};
+
+	rtc_int_pins_default: rtc-int-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-up on Carrier */
+			AM64X_IOPAD(0x00b4, PIN_INPUT, 7)	/* GPMC0_CSn3.GPIO0_44 */
+		>;
+	};
+
+	serdes_mux_pins_default: serdes-mux-pins-default {
+		pinctrl-single,pins = <
+			/* SEL, 10k pull-down on carrier, 2.2k pullup on SoM */
+			AM64X_IOPAD(0x0200, PIN_OUTPUT, 7)	/* PRG0_MDIO0_MDIO.GPIO1_40 */
+			/* EN */
+			AM64X_IOPAD(0x0204, PIN_OUTPUT, 7)	/* PRG0_MDIO0_MDC.GPIO1_41 */
+		>;
+	};
+};
+
+&main_uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart3_pins_default>;
+	uart-has-rtscts;
+	rs485-rts-active-low;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+&usb0 {
+	dr_mode = "host";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
new file mode 100644
index 000000000000..83b73d433508
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
@@ -0,0 +1,592 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ */
+
+#include <dt-bindings/net/ti-dp83869.h>
+
+/ {
+	model = "SolidRun AM642 SoM";
+	compatible = "solidrun,am642-sr-som", "ti,am642";
+
+	aliases {
+		ethernet0 = &cpsw_port1;
+		ethernet1 = &icssg1_emac0;
+		ethernet2 = &icssg1_emac1;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		serial2 = &main_uart0;
+	};
+
+	chosen {
+		/* SoC default UART console */
+		stdout-path = "serial2:115200n8";
+	};
+
+	/* PRU Ethernet Controller */
+	ethernet {
+		compatible = "ti,am642-icssg-prueth";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pru_rgmii1_pins_default>, <&pru_rgmii2_pins_default>;
+
+		sram = <&oc_sram>;
+		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
+		firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
+
+		/* configure internal pinmux for mii mode */
+		ti,pruss-gp-mux-sel = <2>, <2>, <2>, <2>, <2>, <2>;
+
+		ti,mii-g-rt = <&icssg1_mii_g_rt>;
+		ti,mii-rt = <&icssg1_mii_rt>;
+		ti,iep = <&icssg1_iep0>, <&icssg1_iep1>;
+
+		/*
+		 * Configure icssg interrupt controller to map pru-internal
+		 * interrupts 8/9 via channels 0/1 to host interrupts 0/1.
+		 *
+		 * For details see interrupt controller documentation:
+		 * Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
+		 */
+		interrupt-parent = <&icssg1_intc>;
+		interrupts = <24 0 2>, <25 1 3>;
+		interrupt-names = "tx_ts0", "tx_ts1";
+
+		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
+		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
+		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
+		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+			    "rx0", "rx1";
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			icssg1_emac0: port at 0 {
+				reg = <0>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4110>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				phy-handle = <&ethernet_phy2>;
+				phy-mode = "rgmii-id";
+			};
+
+			icssg1_emac1: port at 1 {
+				reg = <1>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4114>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				phy-handle = <&ethernet_phy1>;
+				phy-mode = "rgmii-id";
+			};
+		};
+	};
+
+	/* DDR16SS0:
+	 * - Bank 1 @ 0x080000000-0x0FFFFFFFF: max. 2GB in 32-bit address space
+	 * - Bank 2 @ 0x880000000-0x9FFFFFFFF: max. 6GB in 64-bit address space
+	 */
+	memory at 80000000 {
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+		      <0x00000008 0x80000000 0x00000001 0x80000000>;
+		device_type = "memory";
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		secure_ddr: optee at 9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+			no-map;
+		};
+
+		main_r5fss0_core0_dma_memory_region: r5f-dma-memory at a0000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_memory_region: r5f-memory at a0100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_dma_memory_region: r5f-dma-memory at a1000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_memory_region: r5f-memory at a1100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_dma_memory_region: r5f-dma-memory at a2000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_memory_region: r5f-memory at a2100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_dma_memory_region: r5f-dma-memory at a3000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_memory_region: r5f-memory at a3100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3100000 0x00 0xf00000>;
+			no-map;
+		};
+	};
+
+	vdd_mmc0: regulator-vdd-mmc0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd-mmc0";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&cpsw3g {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins_default>;
+};
+
+&cpsw3g_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio0_pins_default>;
+	status = "okay";
+
+	ethernet_phy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy0_pins_default>;
+		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 84 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+};
+
+&cpsw_port1 {
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy0>;
+};
+
+&cpsw_port2 {
+	status = "disabled";
+};
+
+&icssg1_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pru1_mdio0_pins_default>;
+	status = "okay";
+
+	ethernet_phy1: ethernet-phy at 3 {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy1_pins_default>;
+		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 20 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+
+	ethernet_phy2: ethernet-phy at f {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <0xf>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy2_pins_default>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 52 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+};
+
+&mailbox0_cluster2 {
+	status = "okay";
+
+	mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+
+	mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+		ti,mbox-rx = <2 0 2>;
+		ti,mbox-tx = <3 0 2>;
+	};
+};
+
+&mailbox0_cluster4 {
+	status = "okay";
+
+	mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+
+	mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+		ti,mbox-rx = <2 0 2>;
+		ti,mbox-tx = <3 0 2>;
+	};
+};
+
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	status = "okay";
+
+	som_eeprom: eeprom at 50 {
+		compatible = "atmel,24c01";
+		reg = <0x50>;
+		pagesize = <8>;
+	};
+};
+
+&main_pmx0 {
+	/* hog global functions */
+	pinctrl-names = "default";
+	pinctrl-0 = <&ethernet_phy_pins_default>;
+
+	ethernet_phy_pins_default: ethernet-phy-pins-default {
+		pinctrl-single,pins = <
+			/* interrupt / power-down, external pull-up on SoM */
+			AM64X_IOPAD(0x0278, PIN_INPUT, 7)	/* EXTINTn.GPIO1_70 */
+		>;
+	};
+
+	ethernet_phy0_pins_default: ethernet-phy0-pins-default {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x0154, PIN_OUTPUT, 7)	/* PRG1_PRU1_GPO19.GPIO0_84 */
+			/* reference clock */
+			AM64X_IOPAD(0x0274, PIN_OUTPUT, 5)	/* EXT_REFCLK1.CLKOUT0 */
+		>;
+	};
+
+	ethernet_phy1_pins_default: ethernet-phy1-pins-default {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x0150, PIN_OUTPUT, 7)	/* PRG1_PRU1_GPO18.GPIO0_20 */
+			/* led0, external pull-down on SoM */
+			AM64X_IOPAD(0x0128, PIN_INPUT, 7)	/* PRG1_PRU1_GPO8.GPIO0_73 */
+			/* led1/rxer */
+			AM64X_IOPAD(0x011c, PIN_INPUT, 7)	/* PRG1_PRU1_GPO5.GPIO0_70 */
+		>;
+	};
+
+	ethernet_phy2_pins_default: ethernet-phy2-pins-default {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x00d4, PIN_OUTPUT, 7)	/* PRG1_PRU0_GPO7.GPIO0_52 */
+			/* led0, external pull-down on SoM */
+			AM64X_IOPAD(0x00d8, PIN_INPUT, 7)	/* PRG1_PRU0_GPO8.GPIO0_53 */
+			/* led1/rxer */
+			AM64X_IOPAD(0x00cc, PIN_INPUT, 7)	/* PRG1_PRU0_GPO5.GPIO0_50 */
+		>;
+	};
+
+	main_i2c0_pins_default: main-i2c0-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x0260, PIN_INPUT, 0)	/* I2C0_SCL.I2C0_SCL */
+			AM64X_IOPAD(0x0264, PIN_INPUT, 0)	/* I2C0_SDA.I2C0_SDA */
+		>;
+	};
+
+	/*
+	 * main_mmc0_pins_default: main-mmc0-pins-default
+	 *
+	 * MMC0_CMD: no padconfig
+	 * MMC0_CLK: no padconfig, external pull-up on SoM
+	 * MMC0_DAT0: no padconfig
+	 * MMC0_DAT1: no padconfig
+	 * MMC0_DAT2: no padconfig
+	 * MMC0_DAT3: no padconfig
+	 * MMC0_DAT4: no padconfig
+	 * MMC0_DAT5: no padconfig
+	 * MMC0_DAT6: no padconfig
+	 * MMC0_DAT7: no padconfig
+	 * MMC0_DS: no padconfig, external pull-down on SoM
+	 */
+
+	main_mmc1_pins_default: main-mmc1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0294, PIN_INPUT_PULLUP, 0)	/* (J19) MMC1_CMD */
+			AM64X_IOPAD(0x028c, PIN_INPUT, 0)		/* MMC1_CLK.MMC1_CLK */
+			AM64X_IOPAD(0x0288, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT0.MMC1_DAT0 */
+			AM64X_IOPAD(0x0284, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT1.MMC1_DAT1 */
+			AM64X_IOPAD(0x0280, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT2.MMC1_DAT2 */
+			AM64X_IOPAD(0x027c, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT3.MMC1_DAT3 */
+			/* external pull-down on SoM & Carrier */
+			AM64X_IOPAD(0x0298, PIN_INPUT_PULLUP, 0)	/* MMC1_SDCD.MMC1_SDCD */
+			AM64X_IOPAD(0x0290, PIN_INPUT, 0)		/* MMC1_CLKLB: clock loopback */
+		>;
+	};
+
+	main_uart0_pins_default: main-uart0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0230, PIN_INPUT, 0)		/* UART0_RXD.UART0_RXD */
+			AM64X_IOPAD(0x0234, PIN_OUTPUT, 0)		/* UART0_TXD.UART0_TXD */
+		>;
+	};
+
+	mdio0_pins_default: mdio0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01fc, PIN_OUTPUT, 4)		/* PRG0_PRU1_GPO19.MDIO0_MDC */
+			AM64X_IOPAD(0x01f8, PIN_INPUT, 4)		/* PRG0_PRU1_GPO18.MDIO0_MDIO */
+		>;
+	};
+
+	ospi0_pins_default: ospi0-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-down on SoM */
+			AM64X_IOPAD(0x0000, PIN_OUTPUT, 0)		/* OSPI0_CLK.OSPI0_CLK */
+			AM64X_IOPAD(0x0008, PIN_OUTPUT, 0)		/* OSPI0_DQS.OSPI0_DQS */
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x002c, PIN_OUTPUT, 0)		/* OSPI0_CSn0.OSPI0_CSn0 */
+			AM64X_IOPAD(0x000c, PIN_INPUT, 0)		/* OSPI0_D0.OSPI0_D0 */
+			AM64X_IOPAD(0x0010, PIN_INPUT, 0)		/* OSPI0_D1.OSPI0_D1 */
+			AM64X_IOPAD(0x0014, PIN_INPUT, 0)		/* OSPI0_D2.OSPI0_D2 */
+			AM64X_IOPAD(0x0018, PIN_INPUT, 0)		/* OSPI0_D3.OSPI0_D3 */
+			AM64X_IOPAD(0x001c, PIN_INPUT, 0)		/* OSPI0_D4.OSPI0_D4 */
+			AM64X_IOPAD(0x0020, PIN_INPUT, 0)		/* OSPI0_D5.OSPI0_D5 */
+			AM64X_IOPAD(0x0024, PIN_INPUT, 0)		/* OSPI0_D6.OSPI0_D6 */
+			AM64X_IOPAD(0x0028, PIN_INPUT, 0)		/* OSPI0_D7.OSPI0_D7 */
+		>;
+	};
+
+	ospi0_flash0_pins_default: ospi0-flash0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0034, PIN_OUTPUT, 7)		/* OSPI0_CSn2.GPIO0_13 */
+			AM64X_IOPAD(0x0038, PIN_INPUT, 7)		/* OSPI0_CSn3.GPIO0_14 */
+		>;
+	};
+
+	pru1_mdio0_pins_default: pru1-mdio0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0)		/* PRG1_MDIO0_MDC.PRG1_MDIO0_MDC */
+			AM64X_IOPAD(0x0158, PIN_INPUT, 0)		/* PRG1_MDIO0_MDIO.PRG1_MDIO0_MDIO */
+		>;
+	};
+
+	pru_rgmii1_pins_default: pru-rgmii1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x00b8, PIN_INPUT, 2)		/* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
+			AM64X_IOPAD(0x00bc, PIN_INPUT, 2)		/* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
+			AM64X_IOPAD(0x00c0, PIN_INPUT, 2)		/* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
+			AM64X_IOPAD(0x00c4, PIN_INPUT, 2)		/* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
+			AM64X_IOPAD(0x00d0, PIN_INPUT, 2)		/* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
+			AM64X_IOPAD(0x00c8, PIN_INPUT, 2)		/* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
+			AM64X_IOPAD(0x00e4, PIN_OUTPUT, 2)		/* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
+			AM64X_IOPAD(0x00e8, PIN_OUTPUT, 2)		/* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
+			AM64X_IOPAD(0x00ec, PIN_OUTPUT, 2)		/* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
+			AM64X_IOPAD(0x00f0, PIN_OUTPUT, 2)		/* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
+			AM64X_IOPAD(0x00f8, PIN_INPUT, 2)		/* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
+			AM64X_IOPAD(0x00f4, PIN_OUTPUT, 2)		/* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
+		>;
+	};
+
+	pru_rgmii2_pins_default: pru-rgmii2-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0108, PIN_INPUT, 2)		/* PRG1_PRU1_GPO0.RGMII2_RD0 */
+			AM64X_IOPAD(0x010c, PIN_INPUT, 2)		/* PRG1_PRU1_GPO1.RGMII2_RD1 */
+			AM64X_IOPAD(0x0110, PIN_INPUT, 2)		/* PRG1_PRU1_GPO2.RGMII2_RD2 */
+			AM64X_IOPAD(0x0114, PIN_INPUT, 2)		/* PRG1_PRU1_GPO3.RGMII2_RD3 */
+			AM64X_IOPAD(0x0120, PIN_INPUT, 2)		/* PRG1_PRU1_GPO6.RGMII2_RXC */
+			AM64X_IOPAD(0x0118, PIN_INPUT, 2)		/* PRG1_PRU1_GPO4.RGMII2_RX_CTL */
+			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO11.RGMII2_TD0 */
+			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO12.RGMII2_TD1 */
+			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO13.RGMII2_TD2 */
+			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO14.RGMII2_TD3 */
+			AM64X_IOPAD(0x0148, PIN_INPUT, 2)		/* PRG1_PRU1_GPO16.RGMII2_TXC */
+			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO15.RGMII2_TX_CTL */
+		>;
+	};
+
+	rgmii1_pins_default: rgmii1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01cc, PIN_INPUT, 4)		/* PRG0_PRU1_GPO7.RGMII1_RD0 */
+			AM64X_IOPAD(0x01d4, PIN_INPUT, 4)		/* PRG0_PRU1_GPO9.RGMII1_RD1 */
+			AM64X_IOPAD(0x01d8, PIN_INPUT, 4)		/* PRG0_PRU1_GPO10.RGMII1_RD2 */
+			AM64X_IOPAD(0x01f4, PIN_INPUT, 4)		/* PRG0_PRU1_GPO17.RGMII1_RD3 */
+			AM64X_IOPAD(0x0188, PIN_INPUT, 4)		/* PRG0_PRU0_GPO10.RGMII1_RXC */
+			AM64X_IOPAD(0x0184, PIN_INPUT, 4)		/* PRG0_PRU0_GPO9.RGMII1_RX_CTL */
+			AM64X_IOPAD(0x0124, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO7.RGMII1_TD0 */
+			AM64X_IOPAD(0x012c, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO9.RGMII1_TD1 */
+			AM64X_IOPAD(0x0130, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO10.RGMII1_TD2 */
+			AM64X_IOPAD(0x014c, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO17.RGMII1_TD3 */
+			AM64X_IOPAD(0x00e0, PIN_INPUT, 4)		/* PRG1_PRU0_GPO10.RGMII1_TXC */
+			AM64X_IOPAD(0x00dc, PIN_OUTPUT, 4)		/* PRG1_PRU0_GPO9.RGMII1_TX_CTL */
+		>;
+	};
+
+	usb0_pins_default: usb0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0)		/* USB0_DRVVBUS.USB0_DRVVBUS */
+		>;
+	};
+};
+
+&main_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core0>;
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0_core1 {
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core1>;
+	memory-region = <&main_r5fss0_core1_dma_memory_region>,
+			<&main_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss1_core0 {
+	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core0>;
+	memory-region = <&main_r5fss1_core0_dma_memory_region>,
+			<&main_r5fss1_core0_memory_region>;
+};
+
+&main_r5fss1_core1 {
+	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core1>;
+	memory-region = <&main_r5fss1_core1_dma_memory_region>,
+			<&main_r5fss1_core1_memory_region>;
+};
+
+/* SoC default UART console */
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_pins_default>;
+	status = "okay";
+};
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_pins_default>;
+	num-cs = <1>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ospi0_flash0_pins_default>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <200000000>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
+		cdns,read-delay = <0>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&main_gpio0 13 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&sdhci0 {
+	/* mmc0 pins have no padconfig */
+	bus-width = <8>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+	non-removable;
+	cap-mmc-hw-reset;
+	no-sd;
+	/*
+	 * MMC controller supports switching between 1.8V and 3.3V signalling.
+	 * However MMC0 (unlike MMC1) does not integrate an LDO.
+	 * Explicitly link a regulator node for indicating to the driver which
+	 * voltages are actually usable.
+	 */
+	vqmmc-supply = <&vdd_mmc0>;
+};
+
+/*
+ * microSD is on carrier - however since SoC can boot from it,
+ * configure it just in case.
+ */
+&sdhci1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_pins_default>;
+	bus-width = <4>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+};
+
+/*
+ * USB settings are a carrier choice - however since SoC can boot from it,
+ * configure as USB-2.0 OTG here, keeping USB-3 serdes disabled.
+ */
+&usb0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins_default>;
+	dr_mode = "otg";
+	maximum-speed = "high-speed";
+};
+
+&usbss0 {
+	ti,vbus-divider;
+	ti,usb2-only;
+};

-- 
2.35.3



From ivprusov at salutedevices.com  Fri Feb  2 06:25:48 2024
From: ivprusov at salutedevices.com (Igor Prusov)
Date: Fri, 2 Feb 2024 17:25:48 +0300
Subject: [PATCH] clk: meson: Add missing clocks to axg_clk_regmaps
Message-ID: <20240202172537.1.I64656c75d84284bc91e6126b50b33c502be7c42a@changeid>

Some clocks were missing from axg_clk_regmaps, which caused kernel panic
during cat /sys/kernel/debug/clk/clk_summary

[   57.349402] Unable to handle kernel NULL pointer dereference at virtual address 00000000000001fc
...
[   57.430002] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   57.436900] pc : regmap_read+0x1c/0x88
[   57.440608] lr : clk_regmap_gate_is_enabled+0x3c/0xb0
[   57.445611] sp : ffff800082f1b690
[   57.448888] x29: ffff800082f1b690 x28: 0000000000000000 x27: ffff800080eb9a70
[   57.455961] x26: 0000000000000007 x25: 0000000000000016 x24: 0000000000000000
[   57.463033] x23: ffff800080e8b488 x22: 0000000000000015 x21: ffff00000e7e7000
[   57.470106] x20: ffff00000400ec00 x19: 0000000000000000 x18: ffffffffffffffff
[   57.477178] x17: 0000000000000000 x16: 0000000000000000 x15: ffff0000042a3000
[   57.484251] x14: 0000000000000000 x13: ffff0000042a2fec x12: 0000000005f5e100
[   57.491323] x11: abcc77118461cefd x10: 0000000000000020 x9 : ffff8000805e4b24
[   57.498396] x8 : ffff0000028063c0 x7 : ffff800082f1b710 x6 : ffff800082f1b710
[   57.505468] x5 : 00000000ffffffd0 x4 : ffff800082f1b6e0 x3 : 0000000000001000
[   57.512541] x2 : ffff800082f1b6e4 x1 : 000000000000012c x0 : 0000000000000000
[   57.519615] Call trace:
[   57.522030]  regmap_read+0x1c/0x88
[   57.525393]  clk_regmap_gate_is_enabled+0x3c/0xb0
[   57.530050]  clk_core_is_enabled+0x44/0x120
[   57.534190]  clk_summary_show_subtree+0x154/0x2f0
[   57.538847]  clk_summary_show_subtree+0x220/0x2f0
[   57.543505]  clk_summary_show_subtree+0x220/0x2f0
[   57.548162]  clk_summary_show_subtree+0x220/0x2f0
[   57.552820]  clk_summary_show_subtree+0x220/0x2f0
[   57.557477]  clk_summary_show_subtree+0x220/0x2f0
[   57.562135]  clk_summary_show_subtree+0x220/0x2f0
[   57.566792]  clk_summary_show_subtree+0x220/0x2f0
[   57.571450]  clk_summary_show+0x84/0xb8
[   57.575245]  seq_read_iter+0x1bc/0x4b8
[   57.578954]  seq_read+0x8c/0xd0
[   57.582059]  full_proxy_read+0x68/0xc8
[   57.585767]  vfs_read+0xb0/0x268
[   57.588959]  ksys_read+0x70/0x108
[   57.592236]  __arm64_sys_read+0x24/0x38
[   57.596031]  invoke_syscall+0x50/0x128
[   57.599740]  el0_svc_common.constprop.0+0x48/0xf8
[   57.604397]  do_el0_svc+0x28/0x40
[   57.607675]  el0_svc+0x34/0xb8
[   57.610694]  el0t_64_sync_handler+0x13c/0x158
[   57.615006]  el0t_64_sync+0x190/0x198
[   57.618635] Code: a9bd7bfd 910003fd a90153f3 aa0003f3 (b941fc00)
[   57.624668] ---[ end trace 0000000000000000 ]---

Signed-off-by: Igor Prusov <ivprusov at salutedevices.com>
---

 drivers/clk/meson/axg.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index c12f81dfa674..5f60f2bcca59 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -2142,7 +2142,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
 	&axg_vclk_input,
 	&axg_vclk2_input,
 	&axg_vclk_div,
+	&axg_vclk_div1,
 	&axg_vclk2_div,
+	&axg_vclk2_div1,
 	&axg_vclk_div2_en,
 	&axg_vclk_div4_en,
 	&axg_vclk_div6_en,
-- 
2.34.1



From jgg at nvidia.com  Fri Feb  2 06:28:05 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri,  2 Feb 2024 10:28:05 -0400
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
Message-ID: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>

If the SMMU is configured to use a two level CD table then
arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
GFP_KERNEL. Due to recent changes this is being done under a spinlock to
iterate over the device list - thus it will trigger a sleeping while
atomic warning:

  arm_smmu_sva_set_dev_pasid()
    mutex_lock(&sva_lock);
    __arm_smmu_sva_bind()
     arm_smmu_mmu_notifier_get()
      spin_lock_irqsave()
      arm_smmu_write_ctx_desc()
	arm_smmu_get_cd_ptr()
         arm_smmu_alloc_cd_leaf_table()
	  dmam_alloc_coherent(GFP_KERNEL)

This is a 64K high order allocation and really should not be done
atomically.

The proper answer is to sequence CD programming in a way that does not
require the device list or a spinlock. Part two of my lager series does
this and already solves this bug.

In the mean time we can solve the functional issue by preallocating the CD
entry outside any locking. CD leafs are effectively never freed so this
guarantees the arm_smmu_write_ctx_desc() inside the lock will not take the
allocation path.

Fixes: 24503148c545 ("iommu/arm-smmu-v3: Refactor write_ctx_desc")
Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
Closes: https://lore.kernel.org/all/4e25d161-0cf8-4050-9aa3-dfa21cd63e56 at moroto.mountain/
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 5 +++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c     | 2 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h     | 2 ++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index 05722121f00e70..068d60732e6481 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -588,6 +588,11 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
 {
 	int ret = 0;
 	struct mm_struct *mm = domain->mm;
+	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+
+	/* Preallocate the required leafs outside locks */
+	if (!arm_smmu_get_cd_ptr(master, id))
+		return -ENOMEM;
 
 	mutex_lock(&sva_lock);
 	ret = __arm_smmu_sva_bind(dev, mm);
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 0ffb1cf17e0b2e..ec2bb8685bb50e 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1019,7 +1019,7 @@ static void arm_smmu_write_cd_l1_desc(__le64 *dst,
 	WRITE_ONCE(*dst, cpu_to_le64(val));
 }
 
-static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
+__le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
 {
 	__le64 *l1ptr;
 	unsigned int idx;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 65fb388d51734d..fa0eeb3519ef28 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -748,6 +748,8 @@ extern struct xarray arm_smmu_asid_xa;
 extern struct mutex arm_smmu_asid_lock;
 extern struct arm_smmu_ctx_desc quiet_cd;
 
+__le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid);
+
 int arm_smmu_write_ctx_desc(struct arm_smmu_master *smmu_master, int ssid,
 			    struct arm_smmu_ctx_desc *cd);
 void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid);

base-commit: c76c50cd425e574df5a071cd7e1805d0764aabff
-- 
2.43.0



From alchark at gmail.com  Fri Feb  2 06:42:42 2024
From: alchark at gmail.com (Alexey Charkov)
Date: Fri, 2 Feb 2024 18:42:42 +0400
Subject: [PATCH v2 2/4] arm64: dts: rockchip: enable temperature driven
 fan control on Rock 5B
In-Reply-To: <bd6e93cf907572e86697dc10a50bfe66@manjaro.org>
References: <20240130-rk-dts-additions-v2-0-c6222c4c78df@gmail.com>
 <20240130-rk-dts-additions-v2-2-c6222c4c78df@gmail.com> <CAGb2v65--rgb2FqmG_0-w1-jUL0odqKXxiZJ-XPYA4uomfYmaQ@mail.gmail.com>
 <5e3e12d65e4919372e7fb02d56202393@manjaro.org> <CABjd4Yx0kQ67fScrFVavjObMLaNt_PJ3TVOhLpCmj00Dx9dOqA@mail.gmail.com>
 <a8aa04ca0061cd09c7b3eb5336e534a4@manjaro.org> <bd6e93cf907572e86697dc10a50bfe66@manjaro.org>
Message-ID: <CABjd4Yy0HYFEdW-XA4vmX4aMhCS-fKd7X_f=ar3qcm_4ROxk1A@mail.gmail.com>

On Thu, Feb 1, 2024 at 11:43?PM Dragan Simic <dsimic at manjaro.org> wrote:
>
> On 2024-02-01 20:31, Dragan Simic wrote:
> > On 2024-02-01 20:15, Alexey Charkov wrote:
> >> On Thu, Feb 1, 2024 at 9:34?PM Dragan Simic <dsimic at manjaro.org>
> >> wrote:
> >>> On 2024-02-01 15:26, Chen-Yu Tsai wrote:
> >>> > On Wed, Jan 31, 2024 at 2:22?AM Alexey Charkov <alchark at gmail.com>
> >>> > wrote:
> >>> >>
> >>> >> This enables thermal monitoring on Radxa Rock 5B and links the PWM
> >>> >> fan as an active cooling device managed automatically by the thermal
> >>> >> subsystem, with a target SoC temperature of 65C and a minimum-spin
> >>> >> interval from 55C to 65C to ensure airflow when the system gets warm
> >>> >>
> >>> >> Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>
> >>> >> Signed-off-by: Alexey Charkov <alchark at gmail.com>
> >>> >> ---
> >>> >>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 34
> >>> >> ++++++++++++++++++++++++-
> >>> >>  1 file changed, 33 insertions(+), 1 deletion(-)
> >>> >>
> >>> >> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> >>> >> b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> >>> >> index a0e303c3a1dc..b485edeef876 100644
> >>> >> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> >>> >> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> >>> >> @@ -52,7 +52,7 @@ led_rgb_b {
> >>> >>
> >>> >>         fan: pwm-fan {
> >>> >>                 compatible = "pwm-fan";
> >>> >> -               cooling-levels = <0 95 145 195 255>;
> >>> >> +               cooling-levels = <0 120 150 180 210 240 255>;
> >>> >>                 fan-supply = <&vcc5v0_sys>;
> >>> >>                 pwms = <&pwm1 0 50000 0>;
> >>> >>                 #cooling-cells = <2>;
> >>> >> @@ -173,6 +173,34 @@ &cpu_l3 {
> >>> >>         cpu-supply = <&vdd_cpu_lit_s0>;
> >>> >>  };
> >>> >>
> >>> >> +&package_thermal {
> >>> >> +       polling-delay = <1000>;
> >>> >> +
> >>> >> +       trips {
> >>> >> +               package_fan0: package-fan0 {
> >>> >> +                       temperature = <55000>;
> >>> >> +                       hysteresis = <2000>;
> >>> >> +                       type = "active";
> >>> >> +               };
> >>> >> +               package_fan1: package-fan1 {
> >>> >> +                       temperature = <65000>;
> >>> >> +                       hysteresis = <2000>;
> >>> >> +                       type = "active";
> >>> >> +               };
> >>> >> +       };
> >>> >> +
> >>> >> +       cooling-maps {
> >>> >> +               map0 {
> >>> >> +                       trip = <&package_fan0>;
> >>> >> +                       cooling-device = <&fan THERMAL_NO_LIMIT 1>;
> >>> >> +               };
> >>> >> +               map1 {
> >>> >> +                       trip = <&package_fan1>;
> >>> >> +                       cooling-device = <&fan 1 THERMAL_NO_LIMIT>;
> >>> >> +               };
> >>> >> +       };
> >>> >> +};
> >>> >> +
> >>> >>  &i2c0 {
> >>> >>         pinctrl-names = "default";
> >>> >>         pinctrl-0 = <&i2c0m2_xfer>;
> >>> >> @@ -731,6 +759,10 @@ regulator-state-mem {
> >>> >>         };
> >>> >>  };
> >>> >>
> >>> >> +&tsadc {
> >>> >> +       status = "okay";
> >>> >> +};
> >>> >> +
> >>> >
> >>> > Is there any reason this can't be enabled by default in the .dtsi file?
> >>> > The thermal sensor doesn't depend on anything external, so there should
> >>> > be no reason to push this down to the board level.
> >>>
> >>> Actually, there is a reason.  Different boards can handle the
> >>> critical
> >>> overheating differently, by letting the CRU or the PMIC handle it.
> >>> This
> >>> was also the case for the RK3399.
> >>>
> >>> Please, have a look at the following DT properties, which are
> >>> consumed
> >>> by drivers/thermal/rockchip_thermal.c:
> >>>    - "rockchip,hw-tshut-mode"
> >>>    - "rockchip,hw-tshut-polarity"
> >>>
> >>> See also page 1,372 of the RK3588 TRM v1.0.
> >>>
> >>> This has also reminded me to check how is the Rock 5B actually wired,
> >>> just to make sure.  We actually need to provide the two DT properties
> >>> listed above, at least to avoid emitting the warnings.
> >>
> >> Well the defaults are already provided in rk3588s.dtsi, so there won't
> >> be any warnings (see lines 2222-2223 in Linus' master version), and
> >> according to the vendor kernel those are also what Rock 5B uses.
> >
> > Yes, I noticed the same a couple of minutes after sending my last
> > message, but didn't want to make more noise about it. :)  I would've
> > mentioned it in my next message, of course.
>
> Just checked the Rock 5B schematic and it expects the CRU to be used
> to perform the hardware reset in case of a thermal runaway, so the
> defaults in the RK3588s dtsi are fine.  I had to double-check it. :)

I've just looked at Rock 5B, Rock 5A and NanoPC T6 schematics, and
they all seem to have the TSADC_SHUT line connected to RESET_L. At the
same time, Radxa's device tree uses the default CRU-based option. To
me this seems to imply that the CRU option should always work, by the
virtue of CRU being on-chip. At the same time, if the right GPIOs are
wired to the PMIC reset line for a particular board, the board may
also choose to use the GPIO option - or stick with CRU.

If that interpretation is correct, then I suggest we enable TSADC by
default in the .dtsi, and let it handle both throttling and CRU-based
critical resets on all boards. Those who know what they are doing may
then elect to switch their board to GPIO-PMIC based reset.

What do you think?

> However, now I have some open questions related to interrupt-driven
> operation.  I'll research it further and come back with an update.
>
> >> This made me think however: what if a board doesn't enable TSADC, but
> >> has OPPs in place for higher voltage and frequency states? There won't
> >> be any throttling (as there won't be any thermal monitoring) and there
> >> might not be a critical shutdown at all if it heats up - possibly even
> >> causing hardware damage. In this case it seems that having TSADC
> >> enabled by default would at least trigger passive cooling, hopefully
> >> avoiding the critical shutdown altogether and making those properties
> >> irrelevant in 99% cases.
> >
> > Those are very good questions.  Thumbs up!
> >
> > The trouble is that the boards can use different wiring to handle the
> > thermal runaways, by expecting the PMIC to handle it or not.  Thus,
> > it's IMHO better to simply leave that to be tested and enabled on a
> > board-by-board basis, whenever a new RK3588(s)-based board is added.
> >
> > Thus, the only right way at this point would be to merge the addition
> > of the OPPs and the enabling of the TSADC for all currently supported
> > RK3588(s)-based boards at once, instead of just for the Rock 5B.

If we can agree on a workable 'default-on' configuration for TSADC to
be included in the .dtsi I think that would be preferable, because it
would enable all boards to benefit from higher OPPs and throttling.

This would also save us from a scenario when OPPs get included in the
default .dtsi, but TSADC is off by default, and then some poor soul
tries to add a new board with a minimal .dts, forgetting to enable
TSADC and having their SoC fried under high load...

> > I can handle the required changes for the QuartzPro64 dts file.  For
> > other supported RK3588(s)-based boards, if there are no people having
> > access to them and willing to perform the dts changes and the testing,
> > I'd be willing to go through the board schematics, to enable the
> > TSADC for them as well.
>
> Please, let me know are you fine with the above-described approach.

I believe it's great if we can go through the schematics no matter
what! Although if we agree that CRU is an always-working default
option for all, then why don't we just enable TSADC for all, and leave
the conversion to GPIO-PMIC resets for later and for where it's
needed?

Best regards,
Alexey


From semen.protsenko at linaro.org  Fri Feb  2 06:54:46 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 2 Feb 2024 08:54:46 -0600
Subject: [PATCH] tty: serial: samsung: Remove superfluous braces in macro
In-Reply-To: <bed3d775-2d80-445f-bf28-b28a17a6370c@linaro.org>
References: <20240202010507.22638-1-semen.protsenko@linaro.org> <bed3d775-2d80-445f-bf28-b28a17a6370c@linaro.org>
Message-ID: <CAPLW+4nPnPywwsjkeJE70GzyBL=smEo5_=0usGwmnaPRgZwdrQ@mail.gmail.com>

On Fri, Feb 2, 2024 at 1:49?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 02/02/2024 02:05, Sam Protsenko wrote:
> > Commit 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
> > removes parameters from EXYNOS_COMMON_SERIAL_DRV_DATA() macro, but
> > leaves unnecessary empty braces. Remove those to fix the style. No
> > functional change.
> >
> > Fixes: 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> >  drivers/tty/serial/samsung_tty.c | 8 ++++----
>
> I am pretty sure you did the patch on some old tree, not mainline rc1.
> Please work on maintainers tree (or linux-next).
>

Hi Krzysztof,

I worked on linux-next, and rebased it on top of the latest linux-next
yesterday, right before submitting. I distinctly remember solving a
conflict while rebasing, due to the new commit 0b87a9fd670a ("tty:
serial: samsung: set UPIO_MEM32 iotype for gs101") which just got into
linux-next yesterday. Please let me know if you want me to rebase it
on another tree and re-submit.

Thanks!

> Best regards,
> Krzysztof
>


From alexandru.elisei at arm.com  Fri Feb  2 06:56:15 2024
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Fri, 2 Feb 2024 14:56:15 +0000
Subject: [PATCH RFC v3 28/35] arm64: mte: swap: Handle tag restoring when
 missing tag storage
In-Reply-To: <CAMn1gO7M51QtxPxkRO3ogH1zasd2-vErWqoPTqGoPiEvr8Pvcw@mail.gmail.com>
References: <20240125164256.4147-1-alexandru.elisei@arm.com>
 <20240125164256.4147-29-alexandru.elisei@arm.com>
 <CAMn1gO7M51QtxPxkRO3ogH1zasd2-vErWqoPTqGoPiEvr8Pvcw@mail.gmail.com>
Message-ID: <Zb0CRYSmQxJ_N4Sr@raptor>

Hi Peter,

On Thu, Feb 01, 2024 at 08:02:40PM -0800, Peter Collingbourne wrote:
> On Thu, Jan 25, 2024 at 8:45?AM Alexandru Elisei
> <alexandru.elisei at arm.com> wrote:
> >
> > Linux restores tags when a page is swapped in and there are tags associated
> > with the swap entry which the new page will replace. The saved tags are
> > restored even if the page will not be mapped as tagged, to protect against
> > cases where the page is shared between different VMAs, and is tagged in
> > some, but untagged in others. By using this approach, the process can still
> > access the correct tags following an mprotect(PROT_MTE) on the non-MTE
> > enabled VMA.
> >
> > But this poses a challenge for managing tag storage: in the scenario above,
> > when a new page is allocated to be swapped in for the process where it will
> > be mapped as untagged, the corresponding tag storage block is not reserved.
> > mte_restore_page_tags_by_swp_entry(), when it restores the saved tags, will
> > overwrite data in the tag storage block associated with the new page,
> > leading to data corruption if the block is in use by a process.
> >
> > Get around this issue by saving the tags in a new xarray, this time indexed
> > by the page pfn, and then restoring them when tag storage is reserved for
> > the page.
> >
> > Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> > ---
> >
> > Changes since rfc v2:
> >
> > * Restore saved tags **before** setting the PG_tag_storage_reserved bit to
> > eliminate a brief window of opportunity where userspace can access uninitialized
> > tags (Peter Collingbourne).
> >
> >  arch/arm64/include/asm/mte_tag_storage.h |   8 ++
> >  arch/arm64/include/asm/pgtable.h         |  11 +++
> >  arch/arm64/kernel/mte_tag_storage.c      |  12 ++-
> >  arch/arm64/mm/mteswap.c                  | 110 +++++++++++++++++++++++
> >  4 files changed, 140 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/include/asm/mte_tag_storage.h b/arch/arm64/include/asm/mte_tag_storage.h
> > index 50bdae94cf71..40590a8c3748 100644
> > --- a/arch/arm64/include/asm/mte_tag_storage.h
> > +++ b/arch/arm64/include/asm/mte_tag_storage.h
> > @@ -36,6 +36,14 @@ bool page_is_tag_storage(struct page *page);
> >
> >  vm_fault_t handle_folio_missing_tag_storage(struct folio *folio, struct vm_fault *vmf,
> >                                             bool *map_pte);
> > +vm_fault_t mte_try_transfer_swap_tags(swp_entry_t entry, struct page *page);
> > +
> > +void tags_by_pfn_lock(void);
> > +void tags_by_pfn_unlock(void);
> > +
> > +void *mte_erase_tags_for_pfn(unsigned long pfn);
> > +bool mte_save_tags_for_pfn(void *tags, unsigned long pfn);
> > +void mte_restore_tags_for_pfn(unsigned long start_pfn, int order);
> >  #else
> >  static inline bool tag_storage_enabled(void)
> >  {
> > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> > index 0174e292f890..87ae59436162 100644
> > --- a/arch/arm64/include/asm/pgtable.h
> > +++ b/arch/arm64/include/asm/pgtable.h
> > @@ -1085,6 +1085,17 @@ static inline void arch_swap_invalidate_area(int type)
> >                 mte_invalidate_tags_area_by_swp_entry(type);
> >  }
> >
> > +#ifdef CONFIG_ARM64_MTE_TAG_STORAGE
> > +#define __HAVE_ARCH_SWAP_PREPARE_TO_RESTORE
> > +static inline vm_fault_t arch_swap_prepare_to_restore(swp_entry_t entry,
> > +                                                     struct folio *folio)
> > +{
> > +       if (tag_storage_enabled())
> > +               return mte_try_transfer_swap_tags(entry, &folio->page);
> > +       return 0;
> > +}
> > +#endif
> > +
> >  #define __HAVE_ARCH_SWAP_RESTORE
> >  static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
> >  {
> > diff --git a/arch/arm64/kernel/mte_tag_storage.c b/arch/arm64/kernel/mte_tag_storage.c
> > index afe2bb754879..ac7b9c9c585c 100644
> > --- a/arch/arm64/kernel/mte_tag_storage.c
> > +++ b/arch/arm64/kernel/mte_tag_storage.c
> > @@ -567,6 +567,7 @@ int reserve_tag_storage(struct page *page, int order, gfp_t gfp)
> >                 }
> >         }
> >
> > +       mte_restore_tags_for_pfn(page_to_pfn(page), order);
> >         page_set_tag_storage_reserved(page, order);
> >  out_unlock:
> >         mutex_unlock(&tag_blocks_lock);
> > @@ -595,7 +596,8 @@ void free_tag_storage(struct page *page, int order)
> >         struct tag_region *region;
> >         unsigned long page_va;
> >         unsigned long flags;
> > -       int ret;
> > +       void *tags;
> > +       int i, ret;
> >
> >         ret = tag_storage_find_block(page, &start_block, &region);
> >         if (WARN_ONCE(ret, "Missing tag storage block for pfn 0x%lx", page_to_pfn(page)))
> > @@ -605,6 +607,14 @@ void free_tag_storage(struct page *page, int order)
> >         /* Avoid writeback of dirty tag cache lines corrupting data. */
> >         dcache_inval_tags_poc(page_va, page_va + (PAGE_SIZE << order));
> >
> > +       tags_by_pfn_lock();
> > +       for (i = 0; i < (1 << order); i++) {
> > +               tags = mte_erase_tags_for_pfn(page_to_pfn(page + i));
> > +               if (unlikely(tags))
> > +                       mte_free_tag_buf(tags);
> > +       }
> > +       tags_by_pfn_unlock();
> > +
> >         end_block = start_block + order_to_num_blocks(order, region->block_size_pages);
> >
> >         xa_lock_irqsave(&tag_blocks_reserved, flags);
> > diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
> > index 2a43746b803f..e11495fa3c18 100644
> > --- a/arch/arm64/mm/mteswap.c
> > +++ b/arch/arm64/mm/mteswap.c
> > @@ -20,6 +20,112 @@ void mte_free_tag_buf(void *buf)
> >         kfree(buf);
> >  }
> >
> > +#ifdef CONFIG_ARM64_MTE_TAG_STORAGE
> > +static DEFINE_XARRAY(tags_by_pfn);
> > +
> > +void tags_by_pfn_lock(void)
> > +{
> > +       xa_lock(&tags_by_pfn);
> > +}
> > +
> > +void tags_by_pfn_unlock(void)
> > +{
> > +       xa_unlock(&tags_by_pfn);
> > +}
> > +
> > +void *mte_erase_tags_for_pfn(unsigned long pfn)
> > +{
> > +       return __xa_erase(&tags_by_pfn, pfn);
> > +}
> > +
> > +bool mte_save_tags_for_pfn(void *tags, unsigned long pfn)
> > +{
> > +       void *entry;
> > +       int ret;
> > +
> > +       ret = xa_reserve(&tags_by_pfn, pfn, GFP_KERNEL);
> 
> copy_highpage can be called from an atomic context, so it isn't
> currently valid to pass GFP_KERNEL here.
> 
> To give one example of a possible atomic context call, copy_pte_range
> will take a PTE spinlock and can call copy_present_pte, which can call
> copy_present_page, which will call copy_user_highpage.
> 
> To give another example, __buffer_migrate_folio can call
> spin_lock(&mapping->private_lock), then call folio_migrate_copy, which
> will call folio_copy.

That is very unfortunate from my part. I distinctly remember looking
precisely at copy_page_range() to double check that it doesn't call
copy_*highpage() from an atomic context, I can only assume that I missed
that it's called with the ptl lock held.

With your two examples, and the khugepaged case in patch #31 ("khugepaged:
arm64: Don't collapse MTE enabled VMAs"), it's crystal clear that the
convention for copy_*highpage() is that the function cannot sleep.

There are two issues here: allocating the buffer in memory where the tags
will be copied, and xarray allocating memory for a new entry.

One fix would be to allocate an entire page with __GFP_ATOMIC, and use that
as a cache for tag buffers (storing the tags for a page uses 1/32th of a
page). From what little I know about xarray, xarray stores would still have
to be GFP_ATOMIC. This should fix the sleeping in atomic context bug. But
the issue I see with this is that a memory allocation can fail, while
copy_*highpage() cannot. Send a fatal signal to the process if memory
allocation fails?

Another approach would be to preallocate memory in a preemptible context,
something like copy_*highpage_prepare(), but that would mean a lot more
work: finding all the places where copy_*highpage is used and add
copy_*highpage_prepare() outside the critical section, releasing the memory
in case of failure (like in the copy_pte_range() case - maybe
copy_*highpage_end()?). That's a pretty big maintenance burden for the MM
code. Although maybe other architectures can find a use for it?

And yet another approach is reserve the needed memory (for the buffer and
in the xarray) when the page is allocated, if it doesn't have tag storage
reserved, regardless of the page being allocated as tagged or not. Then in
set_pte_at() free this memory if it's unused. But this would mean reserving
memory for possibly all memory allocations in the system (including for tag
storage pages) if userspace doesn't use tags at all, though not all pages
in the system will have this memory reserved at the same time. Pretty big
downside.

Out of the three, I prefer the first, but it's definitely not perfect. I'll
try to think of something else, maybe I can come up with something better.

What are your thoughts?

Thanks,
Alex

> 
> Peter
> 
> > +       if (ret)
> > +               return true;
> > +
> > +       tags_by_pfn_lock();
> > +
> > +       if (page_tag_storage_reserved(pfn_to_page(pfn))) {
> > +               xa_release(&tags_by_pfn, pfn);
> > +               tags_by_pfn_unlock();
> > +               return false;
> > +       }
> > +
> > +       entry = __xa_store(&tags_by_pfn, pfn, tags, GFP_ATOMIC);
> > +       if (xa_is_err(entry)) {
> > +               xa_release(&tags_by_pfn, pfn);
> > +               goto out_unlock;
> > +       } else if (entry) {
> > +               mte_free_tag_buf(entry);
> > +       }
> > +
> > +out_unlock:
> > +       tags_by_pfn_unlock();
> > +       return true;
> > +}
> > +
> > +void mte_restore_tags_for_pfn(unsigned long start_pfn, int order)
> > +{
> > +       struct page *page = pfn_to_page(start_pfn);
> > +       unsigned long pfn;
> > +       void *tags;
> > +
> > +       tags_by_pfn_lock();
> > +
> > +       for (pfn = start_pfn; pfn < start_pfn + (1 << order); pfn++, page++) {
> > +               tags = mte_erase_tags_for_pfn(pfn);
> > +               if (unlikely(tags)) {
> > +                       /*
> > +                        * Mark the page as tagged so mte_sync_tags() doesn't
> > +                        * clear the tags.
> > +                        */
> > +                       WARN_ON_ONCE(!try_page_mte_tagging(page));
> > +                       mte_copy_page_tags_from_buf(page_address(page), tags);
> > +                       set_page_mte_tagged(page);
> > +                       mte_free_tag_buf(tags);
> > +               }
> > +       }
> > +
> > +       tags_by_pfn_unlock();
> > +}
> > +
> > +/*
> > + * Note on locking: swap in/out is done with the folio locked, which eliminates
> > + * races with mte_save/restore_page_tags_by_swp_entry.
> > + */
> > +vm_fault_t mte_try_transfer_swap_tags(swp_entry_t entry, struct page *page)
> > +{
> > +       void *swap_tags, *pfn_tags;
> > +       bool saved;
> > +
> > +       /*
> > +        * mte_restore_page_tags_by_swp_entry() will take care of copying the
> > +        * tags over.
> > +        */
> > +       if (likely(page_mte_tagged(page) || page_tag_storage_reserved(page)))
> > +               return 0;
> > +
> > +       swap_tags = xa_load(&tags_by_swp_entry, entry.val);
> > +       if (!swap_tags)
> > +               return 0;
> > +
> > +       pfn_tags = mte_allocate_tag_buf();
> > +       if (!pfn_tags)
> > +               return VM_FAULT_OOM;
> > +
> > +       memcpy(pfn_tags, swap_tags, MTE_PAGE_TAG_STORAGE_SIZE);
> > +       saved = mte_save_tags_for_pfn(pfn_tags, page_to_pfn(page));
> > +       if (!saved)
> > +               mte_free_tag_buf(pfn_tags);
> > +
> > +       return 0;
> > +}
> > +#endif
> > +
> >  int mte_save_page_tags_by_swp_entry(struct page *page)
> >  {
> >         void *tags, *ret;
> > @@ -54,6 +160,10 @@ void mte_restore_page_tags_by_swp_entry(swp_entry_t entry, struct page *page)
> >         if (!tags)
> >                 return;
> >
> > +       /* Tags will be restored when tag storage is reserved. */
> > +       if (tag_storage_enabled() && unlikely(!page_tag_storage_reserved(page)))
> > +               return;
> > +
> >         if (try_page_mte_tagging(page)) {
> >                 mte_copy_page_tags_from_buf(page_address(page), tags);
> >                 set_page_mte_tagged(page);
> > --
> > 2.43.0
> >


From maz at kernel.org  Fri Feb  2 06:56:50 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 02 Feb 2024 14:56:50 +0000
Subject: [PATCH v2 06/25] KVM: arm64: nv: Add sanitising to VNCR-backed HCRX_EL2
In-Reply-To: <ZbytUKPFYiP2cdd8@linux.dev>
References: <20240130204533.693853-1-maz@kernel.org>
	<20240130204533.693853-7-maz@kernel.org>
	<ZbytUKPFYiP2cdd8@linux.dev>
Message-ID: <86h6iq7w3x.wl-maz@kernel.org>

On Fri, 02 Feb 2024 08:52:32 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Tue, Jan 30, 2024 at 08:45:13PM +0000, Marc Zyngier wrote:
> > Just like its little friends, HCRX_EL2 gets the feature set treatment
> > when backed by VNCR.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/kvm/nested.c | 42 +++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 42 insertions(+)
> > 
> > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> > index cdeef3259193..72db632b115a 100644
> > --- a/arch/arm64/kvm/nested.c
> > +++ b/arch/arm64/kvm/nested.c
> > @@ -263,6 +263,48 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
> >  		res1 |= HCR_E2H;
> >  	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
> >  
> > +	/* HCRX_EL2 */
> > +	res0 = HCRX_EL2_RES0;
> > +	res1 = HCRX_EL2_RES1;
> 
> I'm a bit worried that we're depending on the meaning of these generated
> RES0/RES1 bitmasks not changing behind our backs.
> 
> Not like people read anything, but do you think it'd make sense to add a
> warning comment to the sysreg file that adding new encodings can have a
> functional change on KVM?

No amount of warnings will do, because people don't give a damn.

I'm actually in favour of something far more radical: we snapshot the
raw value of all the used RES0/1, and put BUILD_BUG_ON()s that fire if
any value has changed. They will have to touch the KVM code to fix
that, and we catch them red-handed.

> 
> > +	if (!kvm_has_feat(kvm, ID_AA64ISAR3_EL1, PACM, TRIVIAL_IMP))
> > +		res0 |= HCRX_EL2_PACMEn;
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR2_EL1, FPMR, IMP))
> > +		res0 |= HCRX_EL2_EnFPM;
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
> > +		res0 |= HCRX_EL2_GCSEn;
> > +	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, SYSREG_128, IMP))
> > +		res0 |= HCRX_EL2_EnIDCP128;
> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, ADERR, DEV_ASYNC))
> > +		res0 |= (HCRX_EL2_EnSDERR | HCRX_EL2_EnSNERR);
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, DF2, IMP))
> > +		res0 |= HCRX_EL2_TMEA;
> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, D128, IMP))
> > +		res0 |= HCRX_EL2_D128En;
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
> > +		res0 |= HCRX_EL2_PTTWI;
> 
> Ok, not fair. The latest public version of the ARM ARM doesn't have any
> of this. Where are you getting it from?

The bloody XML, from which all of this should, in theory, be extracted
without any human intervention. Sadly, it seems that we are not
allowed to do so, from what I have been told.

The ARM ARM is, unfortunately, being quickly rendered obsolete by the
lack of updates (FEAT_THE is part of the v9.4 architecture, released
in 2022).

I'll make sure to add a link to the XML in the cover letter when I
repost the series.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From peter.griffin at linaro.org  Fri Feb  2 06:57:29 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri,  2 Feb 2024 14:57:29 +0000
Subject: [PATCH v3 0/2]  Add regmap support to exynos-pmu for protected PMU regs
Message-ID: <20240202145731.4082033-1-peter.griffin@linaro.org>

Hi folks,

This is a v3 of the series to add support for protected PMU registers found
on gs101 and derivative SoCs. In v2 and later it was re-worked to be based on
a regmap abstraction that I think leads to a much neater overall solution.
The advantage of the regmap abstraction is that most leaf drivers that
read/write PMU registers need minimal changes.

Example of Exynos drivers that require PMU register access are:
* watchdog
* usb phy
* mipi phy
* ufs phy

This series has been tested on Pixel 6 / gs101. If the various maintainers/
contributors of other Exynos SoCs like exynos850, exynosautov9, exynos5422
etc can test these patches on your respective systems that would be most
appreciated!

The expectation is this series would be merged via Krzysztofs Samsung Exynos
tree.

regards,

Peter

Changes since v2
 - Add select REGMAP to Kconfig
 - Add constant for SET/CLEAR bits
 - Replace kerneldoc with one line comment
 - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
 - remove superflous extern keyword
 - dev_err_probe() on probe error
 - shorten regmcfg name
 - no compatibles inside probe, use match data
 - don't mix declarations with/without initializations
 - tensor_sec_reg_read() use mmio to avoid access restrictions
 - Collect up Reviewed-by
 - const for regmap_config structs

Changes since v1:
 - Refactor to use custom regmap to abstract SMC register access (Sam / Guenter)
 - Add deferred probing support (Saravana / Krzysztof)

v2 lore: https://lore.kernel.org/lkml/20240129211912.3068411-1-peter.griffin at linaro.org/
v1 lore: https://lore.kernel.org/all/20240122225710.1952066-1-peter.griffin at linaro.org/

Peter Griffin (2):
  soc: samsung: exynos-pmu: Add regmap support for SoCs that protect PMU
    regs
  watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU
    regs

 drivers/soc/samsung/Kconfig            |   1 +
 drivers/soc/samsung/exynos-pmu.c       | 233 ++++++++++++++++++++++++-
 drivers/soc/samsung/exynos-pmu.h       |   1 +
 drivers/watchdog/Kconfig               |   1 -
 drivers/watchdog/s3c2410_wdt.c         |   8 +-
 include/linux/soc/samsung/exynos-pmu.h |  11 +-
 6 files changed, 245 insertions(+), 10 deletions(-)

-- 
2.43.0.594.gd9cf4e227d-goog



From peter.griffin at linaro.org  Fri Feb  2 06:57:30 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri,  2 Feb 2024 14:57:30 +0000
Subject: [PATCH v3 1/2] soc: samsung: exynos-pmu: Add regmap support for SoCs that protect PMU regs
In-Reply-To: <20240202145731.4082033-1-peter.griffin@linaro.org>
References: <20240202145731.4082033-1-peter.griffin@linaro.org>
Message-ID: <20240202145731.4082033-2-peter.griffin@linaro.org>

Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
security hardening reasons so that they are only write accessible in el3
via an SMC call.

As most Exynos drivers that need to write PMU registers currently obtain a
regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
is implemented in this driver using a custom regmap similar to syscon to
handle the SMC call. Platforms that don't secure PMU registers, get a mmio
regmap like before. As regmaps abstract out the underlying register access
changes to the leaf drivers are minimal.

A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
that currently use syscon_regmap_lookup_by_phandle(). This also handles
deferred probing.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
Changes since v2
 - Add select REGMAP to Kconfig
 - Add constant for SET/CLEAR bits
 - Replace kerneldoc with one line comment
 - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
 - remove superflous extern keyword
 - dev_err_probe() on probe error
 - shorten regmcfg name
 - no compatibles inside probe, use match data
 - don't mix declarations with/without initializations
 - tensor_sec_reg_read() use mmio to avoid access restrictions
 - Collect up Reviewed-by
 - const for regmap_config structs
---
 drivers/soc/samsung/Kconfig            |   1 +
 drivers/soc/samsung/exynos-pmu.c       | 233 ++++++++++++++++++++++++-
 drivers/soc/samsung/exynos-pmu.h       |   1 +
 include/linux/soc/samsung/exynos-pmu.h |  11 +-
 4 files changed, 241 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 27ec99af77e3..1a5dfdc978dc 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -42,6 +42,7 @@ config EXYNOS_PMU
 	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
 	select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
 	select MFD_CORE
+	select REGMAP_MMIO
 
 # There is no need to enable these drivers for ARMv8
 config EXYNOS_PMU_ARM_DRIVERS
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index 250537d7cfd6..adf3549370d6 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -5,6 +5,7 @@
 //
 // Exynos - CPU PMU(Power Management Unit) support
 
+#include <linux/arm-smccc.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/mfd/core.h>
@@ -12,19 +13,130 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/regmap.h>
 
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/soc/samsung/exynos-pmu.h>
 
 #include "exynos-pmu.h"
 
+#define PMUALIVE_MASK GENMASK(14, 0)
+#define SET_BITS	0xc000
+#define CLEAR_BITS	0x8000
+
+#define TENSOR_SMC_PMU_SEC_REG		0x82000504
+#define TENSOR_PMUREG_READ		0
+#define TENSOR_PMUREG_WRITE		1
+#define TENSOR_PMUREG_RMW		2
+
 struct exynos_pmu_context {
 	struct device *dev;
 	const struct exynos_pmu_data *pmu_data;
+	struct regmap *pmureg;
 };
 
 void __iomem *pmu_base_addr;
 static struct exynos_pmu_context *pmu_context;
+static struct platform_driver exynos_pmu_driver;
+
+/*
+ * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
+ * from EL3, but are still read accessible. As Linux needs to write some of
+ * these registers, the following functions are provided and exposed via
+ * regmap.
+ *
+ * Note: This SMC interface is known to be implemented on gs101 and derivative
+ * SoCs.
+ */
+
+/* Write to a protected PMU register. */
+static int tensor_sec_reg_write(void *base, unsigned int reg, unsigned int val)
+{
+	struct arm_smccc_res res;
+	unsigned long pmu_base = (unsigned long)base;
+
+	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
+		      TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
+
+	/* returns -EINVAL if access isn't allowed or 0 */
+	if (res.a0)
+		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
+
+	return (int)res.a0;
+}
+
+/* Read/Modify/Write a protected PMU register. */
+static int tensor_sec_reg_rmw(void *base, unsigned int reg,
+			      unsigned int mask, unsigned int val)
+{
+	struct arm_smccc_res res;
+	unsigned long pmu_base = (unsigned long)base;
+
+	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
+		      TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
+
+	/* returns -EINVAL if access isn't allowed or 0*/
+	if (res.a0)
+		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
+
+	return (int)res.a0;
+}
+
+/*
+ * Read a protected PMU register. All PMU registers can be read by Linux.
+ * Note: The SMC read register is not used, as only registers that can be
+ * written are readable via SMC.
+ */
+static int tensor_sec_reg_read(void *base, unsigned int reg, unsigned int *val)
+{
+	*val = pmu_raw_readl(reg);
+	return 0;
+}
+
+/*
+ * For SoCs that have set/clear bit hardware this function can be used when
+ * the PMU register will be accessed by multiple masters.
+ *
+ * For example, to set bits 13:8 in PMU reg offset 0x3e80
+ * tensor_set_bit_atomic(0x3e80, 0x3f00, 0x3f00);
+ *
+ * To clear bits 13:8 in PMU offset 0x3e80
+ * tensor_set_bit_atomic(0x3e80, 0x0, 0x3f00);
+ */
+static inline int tensor_set_bit_atomic(void *ctx, unsigned int offset,
+					u32 val, u32 mask)
+{
+	int ret;
+	unsigned int i;
+
+	for (i = 0; i < 32; i++) {
+		if (mask & BIT(i)) {
+			if (val & BIT(i))
+				offset |= SET_BITS;
+			else
+				offset |= CLEAR_BITS;
+
+			ret = tensor_sec_reg_write(ctx, offset, i);
+			if (ret)
+				goto out;
+		}
+	}
+out:
+	return ret;
+}
+
+static int tensor_sec_update_bits(void *ctx, unsigned int reg,
+				  unsigned int mask, unsigned int val)
+{
+	/*
+	 * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
+	 * as the target registers can be accessed by multiple masters.
+	 */
+	if (reg > PMUALIVE_MASK)
+		return tensor_sec_reg_rmw(ctx, reg, mask, val);
+
+	return tensor_set_bit_atomic(ctx, reg, val, mask);
+}
 
 void pmu_raw_writel(u32 val, u32 offset)
 {
@@ -75,11 +187,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
 #define exynos_pmu_data_arm_ptr(data)	NULL
 #endif
 
+static const struct regmap_config regmap_smccfg = {
+	.name = "pmu_regs",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.use_single_read = true,
+	.use_single_write = true,
+	.reg_read = tensor_sec_reg_read,
+	.reg_write = tensor_sec_reg_write,
+	.reg_update_bits = tensor_sec_update_bits,
+};
+
+static const struct regmap_config regmap_mmiocfg = {
+	.name = "pmu_regs",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.use_single_read = true,
+	.use_single_write = true,
+};
+
+static const struct exynos_pmu_data gs101_pmu_data = {
+	.pmu_secure = true
+};
+
 /*
  * PMU platform driver and devicetree bindings.
  */
 static const struct of_device_id exynos_pmu_of_device_ids[] = {
 	{
+		.compatible = "google,gs101-pmu",
+		.data = &gs101_pmu_data,
+	}, {
 		.compatible = "samsung,exynos3250-pmu",
 		.data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
 	}, {
@@ -113,19 +255,73 @@ static const struct mfd_cell exynos_pmu_devs[] = {
 	{ .name = "exynos-clkout", },
 };
 
+/**
+ * exynos_get_pmu_regmap() - Obtain pmureg regmap
+ *
+ * Find the pmureg regmap previously configured in probe() and return regmap
+ * pointer.
+ *
+ * Return: A pointer to regmap if found or ERR_PTR error value.
+ */
 struct regmap *exynos_get_pmu_regmap(void)
 {
 	struct device_node *np = of_find_matching_node(NULL,
 						      exynos_pmu_of_device_ids);
 	if (np)
-		return syscon_node_to_regmap(np);
+		return exynos_get_pmu_regmap_by_phandle(np, NULL);
 	return ERR_PTR(-ENODEV);
 }
 EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
 
+/**
+ * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
+ * @np: Pointer to device's Device Tree node
+ * @property: Device Tree property name which references the pmu
+ *
+ * Find the pmureg regmap previously configured in probe() and return regmap
+ * pointer.
+ *
+ * Return: A pointer to regmap if found or ERR_PTR error value.
+ */
+struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+						const char *property)
+{
+	struct device *dev;
+	struct exynos_pmu_context *ctx;
+	struct device_node *pmu_np;
+
+	if (property)
+		pmu_np = of_parse_phandle(np, property, 0);
+	else
+		pmu_np = np;
+
+	if (!pmu_np)
+		return ERR_PTR(-ENODEV);
+
+	/*
+	 * Determine if exynos-pmu device has probed and therefore regmap
+	 * has been created and can be returned to the caller. Otherwise we
+	 * return -EPROBE_DEFER.
+	 */
+	dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
+					    (void *)pmu_np);
+
+	of_node_put(pmu_np);
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	ctx = dev_get_drvdata(dev);
+
+	return ctx->pmureg;
+}
+EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
+
 static int exynos_pmu_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct regmap_config pmu_regmcfg;
+	struct regmap *regmap;
+	struct resource *res;
 	int ret;
 
 	pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
@@ -133,13 +329,42 @@ static int exynos_pmu_probe(struct platform_device *pdev)
 		return PTR_ERR(pmu_base_addr);
 
 	pmu_context = devm_kzalloc(&pdev->dev,
-			sizeof(struct exynos_pmu_context),
-			GFP_KERNEL);
+				   sizeof(struct exynos_pmu_context),
+				   GFP_KERNEL);
 	if (!pmu_context)
 		return -ENOMEM;
-	pmu_context->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
 	pmu_context->pmu_data = of_device_get_match_data(dev);
 
+	/* For SoCs that secure PMU register writes use custom regmap */
+	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_secure) {
+		pmu_regmcfg = regmap_smccfg;
+		pmu_regmcfg.max_register = resource_size(res) -
+					   pmu_regmcfg.reg_stride;
+		/* Need physical address for SMC call */
+		regmap = devm_regmap_init(dev, NULL,
+					  (void *)(uintptr_t)res->start,
+					  &pmu_regmcfg);
+	} else {
+		/* all other SoCs use a MMIO regmap */
+		pmu_regmcfg = regmap_mmiocfg;
+		pmu_regmcfg.max_register = resource_size(res) -
+					   pmu_regmcfg.reg_stride;
+		regmap = devm_regmap_init_mmio(dev, pmu_base_addr,
+					       &pmu_regmcfg);
+	}
+
+	if (IS_ERR(regmap))
+		dev_err_probe(&pdev->dev, PTR_ERR(regmap),
+			      "regmap init failed\n");
+
+	pmu_context->pmureg = regmap;
+	pmu_context->dev = dev;
+
 	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init)
 		pmu_context->pmu_data->pmu_init();
 
diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
index 1c652ffd79b4..0a49a2c9a08e 100644
--- a/drivers/soc/samsung/exynos-pmu.h
+++ b/drivers/soc/samsung/exynos-pmu.h
@@ -21,6 +21,7 @@ struct exynos_pmu_conf {
 struct exynos_pmu_data {
 	const struct exynos_pmu_conf *pmu_config;
 	const struct exynos_pmu_conf *pmu_config_extra;
+	bool pmu_secure;
 
 	void (*pmu_init)(void);
 	void (*powerdown_conf)(enum sys_powerdown);
diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
index a4f5516cc956..406ed73614fd 100644
--- a/include/linux/soc/samsung/exynos-pmu.h
+++ b/include/linux/soc/samsung/exynos-pmu.h
@@ -20,12 +20,21 @@ enum sys_powerdown {
 
 extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
 #ifdef CONFIG_EXYNOS_PMU
-extern struct regmap *exynos_get_pmu_regmap(void);
+struct regmap *exynos_get_pmu_regmap(void);
+
+struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+						const char *property);
 #else
 static inline struct regmap *exynos_get_pmu_regmap(void)
 {
 	return ERR_PTR(-ENODEV);
 }
+
+static inline struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+							      const char *property)
+{
+	return ERR_PTR(-ENODEV);
+}
 #endif
 
 #endif /* __LINUX_SOC_EXYNOS_PMU_H */
-- 
2.43.0.594.gd9cf4e227d-goog



From peter.griffin at linaro.org  Fri Feb  2 06:57:31 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri,  2 Feb 2024 14:57:31 +0000
Subject: [PATCH v3 2/2] watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs
In-Reply-To: <20240202145731.4082033-1-peter.griffin@linaro.org>
References: <20240202145731.4082033-1-peter.griffin@linaro.org>
Message-ID: <20240202145731.4082033-3-peter.griffin@linaro.org>

Obtain the PMU regmap using the new API added to exynos-pmu driver rather
than syscon_regmap_lookup_by_phandle(). As this driver no longer depends
on mfd syscon remove that header and Kconfig dependency.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 drivers/watchdog/Kconfig       | 1 -
 drivers/watchdog/s3c2410_wdt.c | 8 ++++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7d22051b15a2..d78fe7137799 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -512,7 +512,6 @@ config S3C2410_WATCHDOG
 	tristate "S3C6410/S5Pv210/Exynos Watchdog"
 	depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
 	select WATCHDOG_CORE
-	select MFD_SYSCON if ARCH_EXYNOS
 	help
 	  Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos
 	  SoCs. This will reboot the system when the timer expires with
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 349d30462c8c..686cf544d0ae 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -24,9 +24,9 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/of.h>
-#include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/delay.h>
+#include <linux/soc/samsung/exynos-pmu.h>
 
 #define S3C2410_WTCON		0x00
 #define S3C2410_WTDAT		0x04
@@ -699,11 +699,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
 		return ret;
 
 	if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
-		wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
-						"samsung,syscon-phandle");
+		wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node,
+						 "samsung,syscon-phandle");
 		if (IS_ERR(wdt->pmureg))
 			return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
-					     "syscon regmap lookup failed.\n");
+					     "PMU regmap lookup failed.\n");
 	}
 
 	wdt_irq = platform_get_irq(pdev, 0);
-- 
2.43.0.594.gd9cf4e227d-goog



From maz at kernel.org  Fri Feb  2 06:58:46 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 02 Feb 2024 14:58:46 +0000
Subject: [PATCH v2 05/25] KVM: arm64: nv: Add sanitising to VNCR-backed FGT sysregs
In-Reply-To: <20240201143806.GG2284078@e124191.cambridge.arm.com>
References: <20240130204533.693853-1-maz@kernel.org>
	<20240130204533.693853-6-maz@kernel.org>
	<20240201143806.GG2284078@e124191.cambridge.arm.com>
Message-ID: <86frya7w0p.wl-maz@kernel.org>

On Thu, 01 Feb 2024 14:38:06 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> On Tue, Jan 30, 2024 at 08:45:12PM +0000, Marc Zyngier wrote:
> > Fine Grained Traps are controlled by a whole bunch of features.
> > Each one of them must be checked and the corresponding masks
> > computed so that we don't let the guest apply traps it shouldn't
> > be using.
> > 
> > This takes care of HFGxTR_EL2, HDFGxTR_EL2, and HAFGRTR_EL2.
> 
>  ^^ and HFGITR_EL2

The intention was that it was covered by HFGxTR, but I can now see how
that can be confusing.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From nm at ti.com  Fri Feb  2 06:59:09 2024
From: nm at ti.com (Nishanth Menon)
Date: Fri, 2 Feb 2024 08:59:09 -0600
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <2dbbcc17-38e9-48b4-a0b1-450350644fb9@kernel.org>
References: <20240201120332.4811-5-rogerq@kernel.org>
 <20240201-viewpoint-upload-fb714f650ff5@spud>
 <20240201-violet-chalice-51a73f113e7b@spud>
 <20240201183522.ssj553rwefr2wuqi@iaqt7>
 <20240201-clad-unopposed-ccfdfe53b770@spud>
 <bc3ab60f-539b-41d0-8595-6e0b55f2763d@kernel.org>
 <20240202-unzip-whacky-bb2f151c618b@wendy>
 <dc3c93dc-74d9-4b1c-a771-3ee6f67b5dcc@kernel.org>
 <20240202121828.oo7grngyh2heqdxn@disposal>
 <2dbbcc17-38e9-48b4-a0b1-450350644fb9@kernel.org>
Message-ID: <20240202145909.a5hnglswn5xivxaj@ebook>

On 15:59-20240202, Roger Quadros wrote:
> 
> 
> On 02/02/2024 14:18, Nishanth Menon wrote:
> > On 12:13-20240202, Roger Quadros wrote:
> > [..]
> >>>>
> >>>> As DTS and driver will be merged by separate maintainers I thought it
> >>>> would be easier for maintainers this way.
> >>>
> >>> dts and driver might be merged by different people, but dt-bindings and
> >>> drivers are merged by the same people. This is a bindings patch, not a
> >>
> >> If we do that then I get a bunch of dtbs_check warnings
> >>
> >> dwc3-usb at f900000: reg: [[0, 261095424, 0, 2048], [0, 261128192, 0, 1024]] is too long
> > 
> > Just my 2 cents: If the binding (and driver) change was truly backward
> > compatible (which it should be - for example: errata can only be
> > applied if the second property is described), then you want to control
> > that reg property to add minItems? - thatm I think will allow the dts
> > change to come in at the next cycle once the binding has been merged.
> > 
> 
> Thanks for the hint.
> Please drop patches 4 and 5 in case you pick this series.
> 
> I'll send patch 4 along with the driver series v2.
> Patch 5, I'll send after the DT binding has been merged.

I suggest to resubmit requisite series (with patches +- or what ever)
specific to appropriate maintainers (I don't typically like folks
sending driver change along with dts change in a single series without
indicating to driver maintainer that dts is something they shouldn't
be picking) and avoid any confusion ;)

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From maz at kernel.org  Fri Feb  2 07:05:44 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 02 Feb 2024 15:05:44 +0000
Subject: [PATCH v2 04/25] KVM: arm64: nv: Add sanitising to EL2 configuration registers
In-Reply-To: <20240131171602.GF2284078@e124191.cambridge.arm.com>
References: <20240130204533.693853-1-maz@kernel.org>
	<20240130204533.693853-5-maz@kernel.org>
	<20240131171602.GF2284078@e124191.cambridge.arm.com>
Message-ID: <86eddu7vp3.wl-maz@kernel.org>

On Wed, 31 Jan 2024 17:16:02 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> On Tue, Jan 30, 2024 at 08:45:11PM +0000, Marc Zyngier wrote:
> > We can now start making use of our sanitising masks by setting them
> > to values that depend on the guest's configuration.
> > 
> > First up are VTTBR_EL2, VTCR_EL2, VMPIDR_EL2 and HCR_EL2.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/kvm/nested.c | 56 ++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 55 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> > index c976cd4b8379..ee461e630527 100644
> > --- a/arch/arm64/kvm/nested.c
> > +++ b/arch/arm64/kvm/nested.c
> > @@ -181,7 +181,7 @@ u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg sr)
> >  	return v;
> >  }
> >  
> > -static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
> > +static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
> >  {
> >  	int i = sr - __VNCR_START__;
> >  
> > @@ -191,6 +191,7 @@ static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u
> >  
> >  int kvm_init_nv_sysregs(struct kvm *kvm)
> >  {
> > +	u64 res0, res1;
> >  	int ret = 0;
> >  
> >  	mutex_lock(&kvm->arch.config_lock);
> > @@ -209,6 +210,59 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
> >  		kvm->arch.id_regs[i] = limit_nv_id_reg(IDX_IDREG(i),
> >  						       kvm->arch.id_regs[i]);
> >  
> > +	/* VTTBR_EL2 */
> > +	res0 = res1 = 0;
> > +	if (!kvm_has_feat_enum(kvm, ID_AA64MMFR1_EL1, VMIDBits, 16))
> > +		res0 |= GENMASK(63, 56);
> > +	set_sysreg_masks(kvm, VTTBR_EL2, res0, res1);
> 
> CnP?

Missing indeed. I'll add it.

> 
> > +
> > +	/* VTCR_EL2 */
> > +	res0 = GENMASK(63, 32) | GENMASK(30, 20);
> > +	res1 = BIT(31);
> > +	set_sysreg_masks(kvm, VTCR_EL2, res0, res1);
> > +
> > +	/* VMPIDR_EL2 */
> > +	res0 = GENMASK(63, 40) | GENMASK(30, 24);
> > +	res1 = BIT(31);
> > +	set_sysreg_masks(kvm, VMPIDR_EL2, res0, res1);
> > +
> > +	/* HCR_EL2 */
> > +	res0 = BIT(48);
> > +	res1 = HCR_RW;
> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, TWED, IMP))
> > +		res0 |= GENMASK(63, 59);
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, MTE, MTE2))
> > +		res0 |= (HCR_TID5 | HCR_DCT | HCR_ATA);
> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, EVT, TTLBxS))
> > +		res0 |= (HCR_TTLBIS | HCR_TTLBOS);
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, CSV2, CSV2_2) &&
> > +	    !kvm_has_feat(kvm, ID_AA64PFR1_EL1, CSV2_frac, CSV2_1p2))
> > +		res1 = HCR_ENSCXT;
> 
> I'm confused here. If the VM doesn't have either CSV2_2 or CSV2_1p2.. HCR_ENSCXT is res1, that means we wouldn't trap?
> 
> The Arm ARM says:
> 
> 	EnSCXT, bit [53]
> 		When FEAT_CSV2_2 is implemented or FEAT_CSV2_1p2 is implemented:
> 
> 			[..]
> 
> 		Otherwise:
> 			RES0
> 
> And if you actually meant res1, then you need: res1 |= HCR_ENSCXT, otherwise you override the HCR_RW res1 bit!

You're right on all counts. This is a total thinko, coupled with a
pretty bad bug.

>
> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, EVT, IMP))
> > +		res0 |= (HCR_TID4 | HCR_TICAB | HCR_TOCU);
> 
> minor nitpick: can you reverse these TOCU | TICAB | TID4 so it matches the relative positions in the register..

Sure can.

>
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1))
> > +		res0 |= HCR_AMVOFFEN;
> 
> We currently mask out ID_AA64PFR0_EL1.AMU (read_sanitised_id_aa64pfr0_el1 and
> part of the .val in the sys_regs_desc[]), can't hurt to be feature
> proof.

That's my idea. We shouldn't have to worry about any of that in the
core code, treat all features as potentially implemented, and actively
check for them being disabled.

> 
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1))
> > +		res0 |= HCR_FIEN;
> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, FWB, IMP))
> > +		res0 |= HCR_FWB;
> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, NV2))
> > +		res0 |= HCR_NV2;
> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, IMP))
> > +		res0 |= (HCR_AT | HCR_NV1 | HCR_NV);
> > +	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
> > +	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS)))
> > +		res0 |= (HCR_API | HCR_APK);
> > +	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TME, IMP))
> > +		res0 |= BIT(39);
> > +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP))
> > +		res0 |= (HCR_TERR | HCR_TEA);
> 
> Same annoying nitpick, flip the values order to match the positions.

Will do.

> 
> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
> > +		res0 |= HCR_TLOR;
> > +	if (!kvm_has_feat(kvm, ID_AA64MMFR4_EL1, E2H0, IMP))
> > +		res1 |= HCR_E2H;
> > +	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
> > +
> >  out:
> >  	mutex_unlock(&kvm->arch.config_lock);
> >  
> 
> I need a lie down now.

I know the feeling. This sort of crap ruins your day. Again, your
effort is much appreciated!

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Fri Feb  2 07:10:26 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 02 Feb 2024 15:10:26 +0000
Subject: [PATCH v2 04/25] KVM: arm64: nv: Add sanitising to EL2 configuration registers
In-Reply-To: <20240201145607.GH2284078@e124191.cambridge.arm.com>
References: <20240130204533.693853-1-maz@kernel.org>
	<20240130204533.693853-5-maz@kernel.org>
	<20240201145607.GH2284078@e124191.cambridge.arm.com>
Message-ID: <86cyte7vh9.wl-maz@kernel.org>

On Thu, 01 Feb 2024 14:56:07 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> On Tue, Jan 30, 2024 at 08:45:11PM +0000, Marc Zyngier wrote:
> > We can now start making use of our sanitising masks by setting them
> > to values that depend on the guest's configuration.
> > 
> > First up are VTTBR_EL2, VTCR_EL2, VMPIDR_EL2 and HCR_EL2.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/kvm/nested.c | 56 ++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 55 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> > index c976cd4b8379..ee461e630527 100644
> > --- a/arch/arm64/kvm/nested.c
> > +++ b/arch/arm64/kvm/nested.c
> > @@ -181,7 +181,7 @@ u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg sr)
> >  	return v;
> >  }
> >  
> > -static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
> > +static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
> >  {
> >  	int i = sr - __VNCR_START__;
> >  
> > @@ -191,6 +191,7 @@ static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u
> >  
> >  int kvm_init_nv_sysregs(struct kvm *kvm)
> >  {
> > +	u64 res0, res1;
> >  	int ret = 0;
> >  
> >  	mutex_lock(&kvm->arch.config_lock);
> > @@ -209,6 +210,59 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
> >  		kvm->arch.id_regs[i] = limit_nv_id_reg(IDX_IDREG(i),
> >  						       kvm->arch.id_regs[i]);
> >  
> > +	/* VTTBR_EL2 */
> > +	res0 = res1 = 0;
> > +	if (!kvm_has_feat_enum(kvm, ID_AA64MMFR1_EL1, VMIDBits, 16))
> > +		res0 |= GENMASK(63, 56);
> > +	set_sysreg_masks(kvm, VTTBR_EL2, res0, res1);
> > +
> > +	/* VTCR_EL2 */
> > +	res0 = GENMASK(63, 32) | GENMASK(30, 20);
> > +	res1 = BIT(31);
> > +	set_sysreg_masks(kvm, VTCR_EL2, res0, res1);
> > +
> > +	/* VMPIDR_EL2 */
> > +	res0 = GENMASK(63, 40) | GENMASK(30, 24);
> > +	res1 = BIT(31);
> > +	set_sysreg_masks(kvm, VMPIDR_EL2, res0, res1);
> > +
> > +	/* HCR_EL2 */
> > +	res0 = BIT(48);
> > +	res1 = HCR_RW;
> 
> Just want to clarify this bit actually, this is restricting the (first level
> only?) nested EL1 to run as AArch64?

This is restricting it at all levels. The guest hypervisor will
eventually write its own view of HCR_EL2.RW in the VNCR page, and if
it has promised AArch32 to its own guest (at any level), it is in for
a treat, because we will forcefully reset this bit to 1.

> Should we be sanitising ID_AA64PFR0_EL1.EL1=0b0001?

We already do. See limit_nv_id_reg() and how it constraints
ID_AA64PFR0_EL1.ELx to 0b0001.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From robh at kernel.org  Fri Feb  2 07:29:08 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 09:29:08 -0600
Subject: [PATCH 00/46] Dynamic allocation of reserved_mem array.
In-Reply-To: <d98288ed-a0d9-4fc1-87bc-d79cb528778c@quicinc.com>
References: <20240126235425.12233-1-quic_obabatun@quicinc.com>
 <20240131000710.GA2581425-robh@kernel.org>
 <51dc64bb-3101-4b4a-a54f-c0df6c0b264c@quicinc.com>
 <20240201194653.GA1328565-robh@kernel.org>
 <d98288ed-a0d9-4fc1-87bc-d79cb528778c@quicinc.com>
Message-ID: <20240202152908.GA4045321-robh@kernel.org>

On Thu, Feb 01, 2024 at 01:10:18PM -0800, Oreoluwa Babatunde wrote:
> 
> On 2/1/2024 11:46 AM, Rob Herring wrote:
> > On Thu, Feb 01, 2024 at 09:08:06AM -0800, Oreoluwa Babatunde wrote:
> >> On 1/30/2024 4:07 PM, Rob Herring wrote:
> >>> On Fri, Jan 26, 2024 at 03:53:39PM -0800, Oreoluwa Babatunde wrote:
> >>>> The reserved_mem array is used to store data for the different
> >>>> reserved memory regions defined in the DT of a device.  The array
> >>>> stores information such as region name, node, start-address, and size
> >>>> of the reserved memory regions.
> >>>>
> >>>> The array is currently statically allocated with a size of
> >>>> MAX_RESERVED_REGIONS(64). This means that any system that specifies a
> >>>> number of reserved memory regions greater than MAX_RESERVED_REGIONS(64)
> >>>> will not have enough space to store the information for all the regions.
> >>>>
> >>>> Therefore, this series extends the use of the static array for
> >>>> reserved_mem, and introduces a dynamically allocated array using
> >>>> memblock_alloc() based on the number of reserved memory regions
> >>>> specified in the DT.
> >>>>
> >>>> Some architectures such as arm64 require the page tables to be setup
> >>>> before memblock allocated memory is writable.  Therefore, the dynamic
> >>>> allocation of the reserved_mem array will need to be done after the
> >>>> page tables have been setup on these architectures. In most cases that
> >>>> will be after paging_init().
> >>>>
> >>>> Reserved memory regions can be divided into 2 groups.
> >>>> i) Statically-placed reserved memory regions
> >>>> i.e. regions defined in the DT using the @reg property.
> >>>> ii) Dynamically-placed reserved memory regions.
> >>>> i.e. regions specified in the DT using the @alloc_ranges
> >>>>     and @size properties.
> >>>>
> >>>> It is possible to call memblock_reserve() and memblock_mark_nomap() on
> >>>> the statically-placed reserved memory regions and not need to save them
> >>>> to the reserved_mem array until memory is allocated for it using
> >>>> memblock, which will be after the page tables have been setup.
> >>>> For the dynamically-placed reserved memory regions, it is not possible
> >>>> to wait to store its information because the starting address is
> >>>> allocated only at run time, and hence they need to be stored somewhere
> >>>> after they are allocated.
> >>>> Waiting until after the page tables have been setup to allocate memory
> >>>> for the dynamically-placed regions is also not an option because the
> >>>> allocations will come from memory that have already been added to the
> >>>> page tables, which is not good for memory that is supposed to be
> >>>> reserved and/or marked as nomap.
> >>>>
> >>>> Therefore, this series splits up the processing of the reserved memory
> >>>> regions into two stages, of which the first stage is carried out by
> >>>> early_init_fdt_scan_reserved_mem() and the second is carried out by
> >>>> fdt_init_reserved_mem().
> >>>>
> >>>> The early_init_fdt_scan_reserved_mem(), which is called before the page
> >>>> tables are setup is used to:
> >>>> 1. Call memblock_reserve() and memblock_mark_nomap() on all the
> >>>>    statically-placed reserved memory regions as needed.
> >>>> 2. Allocate memory from memblock for the dynamically-placed reserved
> >>>>    memory regions and store them in the static array for reserved_mem.
> >>>>    memblock_reserve() and memblock_mark_nomap() are also called as
> >>>>    needed on all the memory allocated for the dynamically-placed
> >>>>    regions.
> >>>> 3. Count the total number of reserved memory regions found in the DT.
> >>>>
> >>>> fdt_init_reserved_mem(), which should be called after the page tables
> >>>> have been setup, is used to carry out the following:
> >>>> 1. Allocate memory for the reserved_mem array based on the number of
> >>>>    reserved memory regions counted as mentioned above.
> >>>> 2. Copy all the information for the dynamically-placed reserved memory
> >>>>    regions from the static array into the new allocated memory for the
> >>>>    reserved_mem array.
> >>>> 3. Add the information for the statically-placed reserved memory into
> >>>>    reserved_mem array.
> >>>> 4. Run the region specific init functions for each of the reserve memory
> >>>>    regions saved in the reserved_mem array.
> >>> I don't see the need for fdt_init_reserved_mem() to be explicitly called 
> >>> by arch code. I said this already, but that can be done at the same time 
> >>> as unflattening the DT. The same conditions are needed for both: we need 
> >>> to be able to allocate memory from memblock.
> >>>
> >>> To put it another way, if fdt_init_reserved_mem() can be called "early", 
> >>> then unflattening could be moved earlier as well. Though I don't think 
> >>> we should optimize that. I'd rather see all arches call the DT functions 
> >>> at the same stages.
> >> Hi Rob,
> >>
> >> The reason we moved fdt_init_reserved_mem() back into the arch specific code
> >> was because we realized that there was no apparently obvious way to call
> >> early_init_fdt_scan_reserved_mem() and fdt_init_reserved_mem() in the correct
> >> order that will work for all archs if we placed fdt_init_reserved_mem() inside the
> >> unflatten_devicetree() function.
> >>
> >> early_init_fdt_scan_reserved_mem() needs to be
> >> called first before fdt_init_reserved_mem(). But on some archs,
> >> unflatten_devicetree() is called before early_init_fdt_scan_reserved_mem(), which
> >> means that if we have fdt_init_reserved_mem() inside the unflatten_devicetree()
> >> function, it will be called before early_init_fdt_scan_reserved_mem().
> >>
> >> This is connected to your other comments on Patch 7 & Patch 14.
> >> I agree, unflatten_devicetree() should NOT be getting called before we reserve
> >> memory for the reserved memory regions because that could cause memory to be
> >> allocated from regions that should be reserved.
> >>
> >> Hence, resolving this issue should allow us to call fdt_init_reserved_mem() from
> >> the? unflatten_devicetree() function without it changing the order that we are
> >> trying to have.
> > There's one issue I've found which is unflatten_device_tree() isn't 
> > called for ACPI case on arm64. Turns out we need /reserved-memory 
> > handled in that case too. However, I think we're going to change 
> > calling unflatten_device_tree() unconditionally for another reason[1]. 
> >
> > [1] https://lore.kernel.org/all/efe6a7886c3491cc9c225a903efa2b1e.sboyd at kernel.org/
> >
> >> I will work on implementing this and send another revision.
> > I think we should go with a simpler route that's just copy the an 
> > initial array in initdata to a properly sized, allocated array like the 
> > patch below. Of course it will need some arch fixes and a follow-on 
> > patch to increase the initial array size.
> >
> > 8<--------------------------------------------------------------------
> > From: Rob Herring <robh at kernel.org>
> > Date: Wed, 31 Jan 2024 16:26:23 -0600
> > Subject: [PATCH] of: reserved-mem: Re-allocate reserved_mem array to actual
> >  size
> >
> > In preparation to increase the static reserved_mem array size yet again,
> > copy the initial array to an allocated array sized based on the actual
> > size needed. Now increasing the the size of the static reserved_mem
> > array only eats up the initdata space. For platforms with reasonable
> > number of reserved regions, we have a net gain in free memory.
> >
> > In order to do memblock allocations, fdt_init_reserved_mem() is moved a
> > bit later to unflatten_device_tree(). On some arches this is effectively
> > a nop.

[...]

> Hi Rob,
> 
> One thing that could come up with this is that? memory
> for the dynamically-placed reserved memory regions
> won't be allocated until we call fdt_init_reserved_mem().
> (i.e. reserved memory regions defined using @alloc-ranges
> and @size properties)
> 
> Since fdt_init_reserved_mem() is now being called from
> unflatten_device_tree(), the page tables would have been
> setup on most architectures, which means we will be
> allocating from memory that have already been mapped.
> 
> Could this be an issue for memory that is supposed to be
> reserved? 

I suppose if the alloc-ranges region is not much bigger than the size 
and the kernel already made some allocation that landed in the region, 
then the allocation could fail. Not much we can do other than alloc the 
reserved regions as soon as possible. Are there cases where that's not 
happening?

I suppose the kernel could try and avoid all alloc-ranges until they've 
been allocated, but that would have to be best effort. I've seen 
optimizations where it's desired to spread buffers across DRAM banks, so 
you could have N alloc-ranges for N banks that covers all of memory.

There's also the issue that if you have more fixed regions than memblock 
can handle (128) before it can reallocate its arrays, then the 
page tables themselves could be allocated in reserved regions.

> Especially for the regions that are specified as
> no-map?

'no-map' is a hint, not a guarantee. Arm32 ignores it for regions 
within the kernel's linear map (at least it used to). I don't think 
anything changes here with it.

Rob


From krzysztof.kozlowski at linaro.org  Fri Feb  2 07:32:41 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 16:32:41 +0100
Subject: [PATCH] tty: serial: samsung: Remove superfluous braces in macro
In-Reply-To: <CAPLW+4nPnPywwsjkeJE70GzyBL=smEo5_=0usGwmnaPRgZwdrQ@mail.gmail.com>
References: <20240202010507.22638-1-semen.protsenko@linaro.org>
 <bed3d775-2d80-445f-bf28-b28a17a6370c@linaro.org>
 <CAPLW+4nPnPywwsjkeJE70GzyBL=smEo5_=0usGwmnaPRgZwdrQ@mail.gmail.com>
Message-ID: <3cf997d1-e178-4162-a5b7-4c2a3ddeffd6@linaro.org>

On 02/02/2024 15:54, Sam Protsenko wrote:
> On Fri, Feb 2, 2024 at 1:49?AM Krzysztof Kozlowski
> <krzysztof.kozlowski at linaro.org> wrote:
>>
>> On 02/02/2024 02:05, Sam Protsenko wrote:
>>> Commit 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
>>> removes parameters from EXYNOS_COMMON_SERIAL_DRV_DATA() macro, but
>>> leaves unnecessary empty braces. Remove those to fix the style. No
>>> functional change.
>>>
>>> Fixes: 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>>> ---
>>>  drivers/tty/serial/samsung_tty.c | 8 ++++----
>>
>> I am pretty sure you did the patch on some old tree, not mainline rc1.
>> Please work on maintainers tree (or linux-next).
>>
> 
> Hi Krzysztof,
> 
> I worked on linux-next, and rebased it on top of the latest linux-next
> yesterday, right before submitting. I distinctly remember solving a
> conflict while rebasing, due to the new commit 0b87a9fd670a ("tty:
> serial: samsung: set UPIO_MEM32 iotype for gs101") which just got into
> linux-next yesterday. Please let me know if you want me to rebase it
> on another tree and re-submit.
> 

Hmm... Almost two months ago GS101 was applied which also uses
EXYNOS_COMMON_SERIAL_DRV_DATA, so should be in the hunks here, but
maybye it's gone now?

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb  2 07:34:11 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 2 Feb 2024 16:34:11 +0100
Subject: [PATCH] tty: serial: samsung: Remove superfluous braces in macro
In-Reply-To: <bed3d775-2d80-445f-bf28-b28a17a6370c@linaro.org>
References: <20240202010507.22638-1-semen.protsenko@linaro.org>
 <bed3d775-2d80-445f-bf28-b28a17a6370c@linaro.org>
Message-ID: <94111a8b-8fef-41b5-b65f-9d5c7f618794@linaro.org>

On 02/02/2024 08:49, Krzysztof Kozlowski wrote:
> On 02/02/2024 02:05, Sam Protsenko wrote:
>> Commit 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
>> removes parameters from EXYNOS_COMMON_SERIAL_DRV_DATA() macro, but
>> leaves unnecessary empty braces. Remove those to fix the style. No
>> functional change.
>>
>> Fixes: 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>> ---
>>  drivers/tty/serial/samsung_tty.c | 8 ++++----
> 
> I am pretty sure you did the patch on some old tree, not mainline rc1.
> Please work on maintainers tree (or linux-next).

My bad, Tudor's patchset changed it few days ago and I missed that it
was applied.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From robh at kernel.org  Fri Feb  2 07:34:49 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 02 Feb 2024 09:34:49 -0600
Subject: [PATCH v3 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240202-add-am64-som-v3-2-2f44023d50e9@solid-run.com>
References: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
 <20240202-add-am64-som-v3-2-2f44023d50e9@solid-run.com>
Message-ID: <170688808822.43802.6252377513690551092.robh@kernel.org>


On Fri, 02 Feb 2024 15:22:18 +0100, Josua Mayer wrote:
> Convert the abracon abx80x rtc text bindings to dt-schema format.
> 
> In addition to the text description reference generic interrupts
> properties and add an example.
> 
> Signed-off-by: Josua Mayer <josua at solid-run.com>
> ---
>  .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ----------
>  .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 72 ++++++++++++++++++++++
>  2 files changed, 72 insertions(+), 31 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:
Error: Documentation/devicetree/bindings/rtc/abracon,abx80x.example.dts:30.30-31 syntax error
FATAL ERROR: Unable to parse input tree
make[2]: *** [scripts/Makefile.lib:419: Documentation/devicetree/bindings/rtc/abracon,abx80x.example.dtb] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1428: dt_binding_check] Error 2
make: *** [Makefile:240: __sub-make] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240202-add-am64-som-v3-2-2f44023d50e9 at solid-run.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From ville.syrjala at linux.intel.com  Fri Feb  2 07:40:47 2024
From: ville.syrjala at linux.intel.com (Ville =?iso-8859-1?Q?Syrj=E4l=E4?=)
Date: Fri, 2 Feb 2024 17:40:47 +0200
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB
 property
In-Reply-To: <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
Message-ID: <Zb0M_2093UwPXK8y@intel.com>

On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > >  /**
> > > >   * DOC: HDMI connector properties
> > > >   *
> > > > + * Broadcast RGB
> > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > + *      Infoframes will be generated according to that value.
> > > > + *
> > > > + *      The value of this property can be one of the following:
> > > > + *
> > > > + *      Automatic:
> > > > + *              RGB Range is selected automatically based on the mode
> > > > + *              according to the HDMI specifications.
> > > > + *
> > > > + *      Full:
> > > > + *              Full RGB Range is forced.
> > > > + *
> > > > + *      Limited 16:235:
> > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > + *              this works for any number of bits-per-component.
> > > > + *
> > > > + *      Drivers can set up this property by calling
> > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > + *
> > > 
> > > This is a good time to document this in more detail. There might be two
> > > different things being affected:
> > > 
> > > 1. The signalling (InfoFrame/SDP/...)
> > > 2. The color pipeline processing
> > > 
> > > All values of Broadcast RGB always affect the color pipeline processing
> > > such that a full-range input to the CRTC is converted to either full- or
> > > limited-range, depending on what the monitor is supposed to accept.
> > > 
> > > When automatic is selected, does that mean that there is no signalling,
> > > or that the signalling matches what the monitor is supposed to accept
> > > according to the spec? Also, is this really HDMI specific?
> > > 
> > > When full or limited is selected and the monitor doesn't support the
> > > signalling, what happens?
> > 
> > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > the cable, so is this only affecting RGB? If not, how does it affect
> > YCbCr?
> 
> So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> we're using a YCbCr format, i915 will always use a limited range while
> vc4 will follow the value of the property.

The property is literally called "Broadcast *RGB*".
That should explain why it's only affecting RGB.

Full range YCbCr is a much rarer beast so we've never bothered
to enable it. Eg. with DP it only became possible with the
introduction of the VSC SDP (and I don't recall if there's
additional capability checks that are also required). With
DP MSA signalling full range YCbCr is not possible at all.
I don't recall right now what the HDMI requirements are.

-- 
Ville Syrj?l?
Intel


From alexghiti at rivosinc.com  Fri Feb  2 07:42:09 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Fri, 2 Feb 2024 16:42:09 +0100
Subject: [PATCH RFC/RFT v2 4/4] riscv: Stop emitting preventive sfence.vma
 for new userspace mappings with Svvptc
In-Reply-To: <Zbuy1E7mz9Oui1Dl@andrea>
References: <20240131155929.169961-1-alexghiti@rivosinc.com>
 <20240131155929.169961-5-alexghiti@rivosinc.com> <Zbuy1E7mz9Oui1Dl@andrea>
Message-ID: <CAHVXubgw0PEZMhFmjA0cAFQ2+_JOYjVfk41qRC9TFdSJtej++w@mail.gmail.com>

Hi Andrea,

On Thu, Feb 1, 2024 at 4:03?PM Andrea Parri <parri.andrea at gmail.com> wrote:
>
> On Wed, Jan 31, 2024 at 04:59:29PM +0100, Alexandre Ghiti wrote:
> > The preventive sfence.vma were emitted because new mappings must be made
> > visible to the page table walker but Svvptc guarantees that xRET act as
> > a fence, so no need to sfence.vma for the uarchs that implement this
> > extension.
>
> AFAIU, your first submission shows that you don't need that xRET property.
> Similarly for other archs.  What was rationale behind this Svvptc change?

Actually, the ARC has just changed its mind and removed this new
behaviour from the Svvptc extension, so we will take some gratuitous
page faults (but that should be outliners), which makes riscv similar
to x86 and arm64.

>
>
> > This allows to drastically reduce the number of sfence.vma emitted:
> >
> > * Ubuntu boot to login:
> > Before: ~630k sfence.vma
> > After:  ~200k sfence.vma
> >
> > * ltp - mmapstress01
> > Before: ~45k
> > After:  ~6.3k
> >
> > * lmbench - lat_pagefault
> > Before: ~665k
> > After:   832 (!)
> >
> > * lmbench - lat_mmap
> > Before: ~546k
> > After:   718 (!)
>
> This Svvptc seems to move/add the "burden" of the synchronization to xRET:
> Perhaps integrate the above counts w/ the perf gains in the cover letter?

Yes, I'll copy that to the cover letter.

Thanks for your interest!

Alex

>
>   Andrea


From lkp at intel.com  Fri Feb  2 07:42:26 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 2 Feb 2024 23:42:26 +0800
Subject: [PATCH 06/18] power: reset: brcm-kona-reset: Use
 devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240201180102.70395-7-afd@ti.com>
References: <20240201180102.70395-7-afd@ti.com>
Message-ID: <202402022349.daHRuWLB-lkp@intel.com>

Hi Andrew,

kernel test robot noticed the following build warnings:

[auto build test WARNING on sre-power-supply/for-next]
[also build test WARNING on mani-mhi/mhi-next soc/for-next linus/master v6.8-rc2 next-20240202]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrew-Davis/power-reset-atc260x-poweroff-Use-devm_register_sys_off_handler-RESTART/20240202-020809
base:   https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git for-next
patch link:    https://lore.kernel.org/r/20240201180102.70395-7-afd%40ti.com
patch subject: [PATCH 06/18] power: reset: brcm-kona-reset: Use devm_register_sys_off_handler(RESTART)
config: arm-randconfig-r121-20240202 (https://download.01.org/0day-ci/archive/20240202/202402022349.daHRuWLB-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20240202/202402022349.daHRuWLB-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402022349.daHRuWLB-lkp at intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/power/reset/brcm-kona-reset.c:18:45: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected void [noderef] __iomem *kona_reset_base @@     got void *cb_data @@
   drivers/power/reset/brcm-kona-reset.c:18:45: sparse:     expected void [noderef] __iomem *kona_reset_base
   drivers/power/reset/brcm-kona-reset.c:18:45: sparse:     got void *cb_data
>> drivers/power/reset/brcm-kona-reset.c:43:46: sparse: sparse: incorrect type in argument 5 (different address spaces) @@     expected void *cb_data @@     got void [noderef] __iomem *[assigned] kona_reset_base @@
   drivers/power/reset/brcm-kona-reset.c:43:46: sparse:     expected void *cb_data
   drivers/power/reset/brcm-kona-reset.c:43:46: sparse:     got void [noderef] __iomem *[assigned] kona_reset_base

vim +18 drivers/power/reset/brcm-kona-reset.c

    15	
    16	static int kona_reset_handler(struct sys_off_data *data)
    17	{
  > 18		void __iomem *kona_reset_base = data->cb_data;
    19	
    20		/*
    21		 * A soft reset is triggered by writing a 0 to bit 0 of the soft reset
    22		 * register. To write to that register we must first write the password
    23		 * and the enable bit in the write access enable register.
    24		 */
    25		writel((RSTMGR_WR_PASSWORD << RSTMGR_WR_PASSWORD_SHIFT) |
    26			RSTMGR_WR_ACCESS_ENABLE,
    27			kona_reset_base + RSTMGR_REG_WR_ACCESS_OFFSET);
    28		writel(0, kona_reset_base + RSTMGR_REG_CHIP_SOFT_RST_OFFSET);
    29	
    30		return NOTIFY_DONE;
    31	}
    32	
    33	static int kona_reset_probe(struct platform_device *pdev)
    34	{
    35		void __iomem *kona_reset_base;
    36	
    37		kona_reset_base = devm_platform_ioremap_resource(pdev, 0);
    38		if (IS_ERR(kona_reset_base))
    39			return PTR_ERR(kona_reset_base);
    40	
    41		return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
    42						     128, kona_reset_handler,
  > 43						     kona_reset_base);
    44	}
    45	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From Dave.Martin at arm.com  Fri Feb  2 07:42:53 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Fri, 2 Feb 2024 15:42:53 +0000
Subject: [PATCH] arm64: jump_label: use constraint "S" instead of "i"
In-Reply-To: <CAFP8O3JB1miCHoGFh7UY6dCa4WS6+88mnB_qxXnvYp4wHnYgBw@mail.gmail.com>
References: <ZbpEnDK3U/O24ng0@e133380.arm.com>
 <20240201045551.ajg4iqcajyowl2rh@google.com>
 <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>
 <20240201091120.pbgr7ng6t2c36fut@google.com>
 <ZbuFWSRBntgm2ukJ@e133380.arm.com>
 <CAMj1kXGu76WHY8=Y-KhCxBq3xeHeCYQ9syqViSr9VRkjgWQ3BQ@mail.gmail.com>
 <ZbvVApJ2/+yca0u6@e133380.arm.com>
 <20240201205614.w3gcz6urfxtydr77@google.com>
 <CAMj1kXGAi94DuCYRPWQujGz7YVTS=53h_+FretCsYFbxznJVHw@mail.gmail.com>
 <CAFP8O3JB1miCHoGFh7UY6dCa4WS6+88mnB_qxXnvYp4wHnYgBw@mail.gmail.com>
Message-ID: <Zb0NfWQAHth9GrpK@e133380.arm.com>

On Thu, Feb 01, 2024 at 02:12:06PM -0800, Fangrui Song wrote:
> On Thu, Feb 1, 2024 at 1:23?PM Ard Biesheuvel <ardb at kernel.org> wrote:
> >
> > On Thu, 1 Feb 2024 at 21:56, Fangrui Song <maskray at google.com> wrote:
> > >
> > > On 2024-02-01, Dave Martin wrote:
> > > >On Thu, Feb 01, 2024 at 05:07:59PM +0100, Ard Biesheuvel wrote:
> > > >> On Thu, 1 Feb 2024 at 12:50, Dave Martin <Dave.Martin at arm.com> wrote:
> > > >> >
> > > >> > On Thu, Feb 01, 2024 at 01:11:20AM -0800, Fangrui Song wrote:

[...]

> > > >> > Is a GCC version check needed?  Or is the minimum GCC version specified
> > > >> > for building the kernel new enough?
> > > >> >
> > > >> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
> > > >> > > +#else
> > > >> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "S"
> > > >> > > +#endif
> > > >> > > +
> > > >>
> > > >> Can we use "Si" instead?
> > > >
> > > >I thought the point was to avoid "S" on compilers that would choke on
> > > >it?  If so, those compilers would surely choke on "Si" too, no?
> > >
> > > "Si" is an invalid constraint. Unfortunately, GCC recognizes "S" as a
> > > valid constraint and ignores trailing characters (asm_operand_ok). That
> > > is, GCC would accept "Siiiii" as well...
> > >
> > > The GCC support for "S" is great. The initial aarch64 port in 2012 supports "S".

Ah, no problem.


> > So it is not possible to combine the S and i constraint, and let the
> > compiler figure out whether it meets either? We rely on this elsewhere
> > by combining r and Z into rZ. x86 uses "rm" for inline asm parameters
> > that could be either register or memory operands.
> 
> I did not realize that your "Si" suggestion meant this feature
> https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
> 
>     After the prefix, there must be one or more additional constraints
> (see Constraints for asm Operands) that describe where the value
> resides. Common constraints include ?r? for register and ?m? for
> memory. When you list more than one possible location (for example,
> "=rm"), the compiler chooses the most efficient one based on the
> current context.
> 
> After some debugging of both GCC and Clang, I think you are right and
> "Si" will work. Thanks for the suggestion!
> 
> GCC accepts "Si". Sorry for my incorrectly stating that GCC ignores
> the trailing constraint. GCC does ignore an unknown constraint, as
> long as one accepted constraint.
> 
> Clang accepts "Si" as well. In the absence of
> https://github.com/llvm/llvm-project/pull/80255 (constant offset
> support for 'S'), in TargetLowering::ComputeConstraintToUse, 'S' is
> skipped and 'i' will be picked. This is unrelated to the "rm" weakness
> in Clang (https://github.com/llvm/llvm-project/issues/20571).
> 
> I'll post a PATCH v2 removing JUMP_LABEL_STATIC_KEY_CONSTRAINT and
> using "Si" unconditionally.

If older Clang just ignores the "S" in "Si" as an unsatisfiable
alternative and falls back on "i", that seems ideal.

> > > >> > >  static __always_inline bool arch_static_branch(struct static_key * const key,
> > > >> > >                                              const bool branch)
> > > >> > >  {
> > > >> > > @@ -23,9 +33,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
> > > >> > >                "      .pushsection    __jump_table, \"aw\"    \n\t"
> > > >> > >                "      .align          3                       \n\t"
> > > >> > >                "      .long           1b - ., %l[l_yes] - .   \n\t"
> > > >> > > -              "      .quad           %c0 - .                 \n\t"
> > > >> > > +              "      .quad           %0 + %1 - .             \n\t"
> > > >> > >                "      .popsection                             \n\t"
> > > >> > > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> > > >> > > +              :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);

[...]

> > > >"S"(&((char *)key)[branch]) does indeed seem to do the right thing,
> > > >at least with GCC.
> > > >
> > > >I probably didn't help by bikeshedding the way that expression was
> > > >written, apologies for that.  It's orthogonal to what this patch is
> > > >doing.
> > >
> > > Yes, "S"(&((char *)key)[branch])  would do the right thing.
> > > I have compared assembly output. It's a matter of "s" vs "s + 0" and "s+1" vs "s + 1".

[...]

> > > >Is there a reason why we don't just build the whole kernel with
> > > >-fvisibility=hidden today?
> > >
> > > This topic, loosely related to this patch, is about switching to PIC
> > > compiles. I am not familiar with the Linux kernel, so I'll mostly leave
> > > the discussion to you and Ard :)
> > >
> > > That said, I have done a lot of Clang work in visibility/symbol
> > > preemptibility and linkers, so I am happy to add what I know.
> > >
> > > -fvisibility=hidden only applies to definitions, not non-definition
> > > declarations.
> > >
> > > I've mentioned this at
> > > https://lore.kernel.org/all/20220429070318.iwj3j5lpfkw4t7g2 at google.com/
> > >
> > >      `#pragma GCC visibility push(hidden)` is very similar to -fvisibility=hidden -fdirect-access-external-data with Clang.
> > >      ...
> > >      The kernel uses neither TLS nor -fno-plt, so -fvisibility=hidden
> > >      -fdirect-access-external-data can replace `#pragma GCC visibility
> > >      push(hidden)`.
> > >
> > > >> So building with -fPIC is currently not need in practice, and creates
> > > >> some complications, which is why we have been avoiding it. But PIE
> > > >> linking non-PIC objects is not guaranteed to remain supported going
> > > >> forward, so it would be better to have a plan B, i.e., being able to
> > > >> turn on -fpic without massive regressions due to GOT overhead, or
> > > >> codegen problems with our asm hacks.
> > > >
> > > >Summarising all of this is it right that:
> > > >
> > > >1) ld -pie is how we get the reloc info into the kernel for KASLR
> > > >today.
> > > >
> > > >2) We use gcc -fno-pic today, but this might break with ld -pie in the
> > > >future, although it works for now.
> > > >
> > > >3) gcc -fno-pic and gcc -fPIC (or -fPIE) generate almost the same code,
> > > >assuming we tweak symbol visibility and use a memory model that
> > > >ADR+ADD/LDR can span.  So, moving to -fPIE is likely to be do-able.
> > > >
> > > >
> > > >My point is that an alternative option would be to move to ld -no-pie.
> >
> > Why? What would that achieve?
> >
> > > >We would need another way to get relocs into the kernel, such as an
> > > >intermediate step with ld --emit-relocs.  I have definitely seen this
> > > >done before somewhere, but it would be extra work and not necessarily
> > > >worth it, based on what you say about code gen.
> >
> > Relying on --emit-relocs is a terrible hack. It contains mostly
> > relocations that we don't need at runtime, so we need to postprocess
> > them. And linkers may not update these relocations in some cases after
> > relaxation or other transformations (and sometimes, it is not even
> > possible to do so, if the post-transformation situation cannot be
> > described by a relocation).
>
> Agreed. I've filed
> https://sourceware.org/bugzilla/show_bug.cgi?id=30844
> ("ld riscv: --emit-relocs does not retain the original relocation
> type") for a RISC-V version.
> 
> --emit-relocs is under-specified and the linker behaviors are less tested.

(Aside: This sounds like an interesting hole in the toolchain world.

I guess if you want post-link-time relocatability, it sounds like all
the focus from the compiler folks is on PIC code, and non-PIC linker
output is not considered relocatable at all (baremetal software being an
inconvenient truth).

"Relocatable" and "PIC" are not really the same requirement, but the
importance of the difference is arch-dependent, and I can see how we got
here.  End aside.)

> > And with Fangrui's RELR optimization, the PIE relocation data is
> > extremely dense.
> >
> > There is nothing to fix here, really.
> >
> > > >
> > > >This may all have been discussed to death already -- I didn't mean to
> > > >hijack this patch, so I'll stop digging here, but if I've misunderstood,
> > > >please shout!
> >
> > No worries. Ramana and I spent some time 5+ years ago to document how
> > PIC codegen for the kernel (or any freestanding executable, really)
> > deviates from the typical PIC codegen for shared libraries and PIE
> > executables, with the intention of adding a GCC compiler switch for
> > it, but that never really materialized, mostly because things just
> > work fine today.
> >

Right.  I was concerned that we would pay a significant runtime
performance penalty when migrating to -fPIC, in which case it would be
worth considering alernatives.  But from the discussion it sounds like
this concern is misguided (or at least, you have found robust
workarounds which mean that the real penalty is negligible).

There's no underlying reason why a toolchain couldn't emit full static
relocation information in a robust way, but since this info is hard to
consume and would be used rarely and only for very specific use cases I
can see why this support is rot-prone or even not considered a goal
at all by many people...

Cheers
---Dave


From mripard at kernel.org  Fri Feb  2 07:49:04 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Fri, 2 Feb 2024 16:49:04 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB
 property
In-Reply-To: <20240115143308.GA159345@toolbox>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
Message-ID: <niqn7eql5neyfp5ficdfisdpmlwrprovqn5g7lgcfwoe74ds23@7fr4yv2miqe7>

Hi Sebastian,

On Mon, Jan 15, 2024 at 03:33:08PM +0100, Sebastian Wick wrote:
> >  /**
> >   * DOC: HDMI connector properties
> >   *
> > + * Broadcast RGB
> > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > + *      Infoframes will be generated according to that value.
> > + *
> > + *      The value of this property can be one of the following:
> > + *
> > + *      Automatic:
> > + *              RGB Range is selected automatically based on the mode
> > + *              according to the HDMI specifications.
> > + *
> > + *      Full:
> > + *              Full RGB Range is forced.
> > + *
> > + *      Limited 16:235:
> > + *              Limited RGB Range is forced. Unlike the name suggests,
> > + *              this works for any number of bits-per-component.
> > + *
> > + *      Drivers can set up this property by calling
> > + *      drm_connector_attach_broadcast_rgb_property().
> > + *
> 
> This is a good time to document this in more detail. There might be two
> different things being affected:
> 
> 1. The signalling (InfoFrame/SDP/...)
> 2. The color pipeline processing
> 
> All values of Broadcast RGB always affect the color pipeline processing
> such that a full-range input to the CRTC is converted to either full- or
> limited-range, depending on what the monitor is supposed to accept.
> 
> When automatic is selected, does that mean that there is no signalling,
> or that the signalling matches what the monitor is supposed to accept
> according to the spec? Also, is this really HDMI specific?
> 
> When full or limited is selected and the monitor doesn't support the
> signalling, what happens?

Leaving the YCbCr vs RGB discussion aside, would this be better ?

 * Broadcast RGB (HDMI specific)
 *      Indicates the Quantization Range (Full vs Limited) used. The color
 *      processing pipeline will be adjusted to match the value of the
 *      property, and the Infoframes will be generated and sent accordingly.
 *
 *      The value of this property can be one of the following:
 *
 *      Automatic:
 *              The quantization range is selected automatically based on the
 *              mode according to the HDMI specifications (HDMI 1.4b - Section
 *              6.6 - Video Quantization Ranges).
 *
 *      Full:
 *              Full quantization range is forced.
 *
 *      Limited 16:235:
 *              Limited quantization range is forced. Unlike the name suggests,
 *              this works for any number of bits-per-component.
 *
 *      Property values other than Automatic can result in colors being off (if
 *      limited is selected but the display expects full), or a black screen
 *      (if full is selected but the display expects limited).
 *
 *      Drivers can set up this property by calling
 *      drm_connector_attach_broadcast_rgb_property().

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/20240202/7bfd0f11/attachment.sig>

From josua at solid-run.com  Fri Feb  2 07:53:55 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 2 Feb 2024 15:53:55 +0000
Subject: [PATCH v3 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <170688808822.43802.6252377513690551092.robh@kernel.org>
References: <20240202-add-am64-som-v3-0-2f44023d50e9@solid-run.com>
 <20240202-add-am64-som-v3-2-2f44023d50e9@solid-run.com>
 <170688808822.43802.6252377513690551092.robh@kernel.org>
Message-ID: <6378c7a9-37b8-4ebb-84dd-547f123d3b4d@solid-run.com>

Am 02.02.24 um 16:34 schrieb Rob Herring:
> On Fri, 02 Feb 2024 15:22:18 +0100, Josua Mayer wrote:
>> Convert the abracon abx80x rtc text bindings to dt-schema format.
>>
>> In addition to the text description reference generic interrupts
>> properties and add an example.
>>
>> Signed-off-by: Josua Mayer <josua at solid-run.com>
>> ---
>>  .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ----------
>>  .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 72 ++++++++++++++++++++++
>>  2 files changed, 72 insertions(+), 31 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:
> Error: Documentation/devicetree/bindings/rtc/abracon,abx80x.example.dts:30.30-31 syntax error
Fixed in v4 by referencing "real" fake_intc0 rather than fictitious gpio0
> FATAL ERROR: Unable to parse input tree
> make[2]: *** [scripts/Makefile.lib:419: Documentation/devicetree/bindings/rtc/abracon,abx80x.example.dtb] Error 1
> make[2]: *** Waiting for unfinished jobs....
> make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1428: dt_binding_check] Error 2
> make: *** [Makefile:240: __sub-make] Error 2

From Dave.Martin at arm.com  Fri Feb  2 07:56:43 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Fri, 2 Feb 2024 15:56:43 +0000
Subject: [PATCH] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <20240201223545.728028-1-maskray@google.com>
References: <20240201223545.728028-1-maskray@google.com>
Message-ID: <Zb0Qu5lR0iZUqImb@e133380.arm.com>

On Thu, Feb 01, 2024 at 02:35:45PM -0800, Fangrui Song wrote:
> The generic constraint "i" seems to be copied from x86 or arm (and with
> a redundant generic operand modifier "c"). It works with -fno-PIE but
> not with -fPIE/-fPIC in GCC's aarch64 port.
> 
> The machine constraint "S", which denotes a symbol or label reference
> with a constant offset, supports PIC and has been available in GCC since
> 2012 and in Clang since 7.0. However, Clang before 19 does not support
> "S" on a symbol with a constant offset [1] (e.g.
> `static_key_false(&nf_hooks_needed[pf][hook])` in
> include/linux/netfilter.h), so we use "i" as a fallback.
> 
> Suggested-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Fangrui Song <maskray at google.com>
> Link: https://github.com/llvm/llvm-project/pull/80255 [1]
> 
> ---
> Changes from
> arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
> 
> * Use "Si" as Ard suggested to support Clang<19
> * Make branch a separate operand
> ---
>  arch/arm64/include/asm/jump_label.h | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> index 48ddc0f45d22..1f7d529be608 100644
> --- a/arch/arm64/include/asm/jump_label.h
> +++ b/arch/arm64/include/asm/jump_label.h
> @@ -15,6 +15,10 @@
>  
>  #define JUMP_LABEL_NOP_SIZE		AARCH64_INSN_SIZE
>  
> +/*
> + * Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
> + * support "S" on a symbol with a constant offset, so we use "i" as a fallback.
> + */
>  static __always_inline bool arch_static_branch(struct static_key * const key,
>  					       const bool branch)
>  {
> @@ -23,9 +27,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
>  		 "	.pushsection	__jump_table, \"aw\"	\n\t"
>  		 "	.align		3			\n\t"
>  		 "	.long		1b - ., %l[l_yes] - .	\n\t"
> -		 "	.quad		%c0 - .			\n\t"
> +		 "	.quad		%0 + %1 - .		\n\t"
>  		 "	.popsection				\n\t"
> -		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> +		 :  :  "Si"(key), "i"(branch) :  : l_yes);

Is the meaning of multi-alternatives well defined if different arguments
specify different numbers of alternatives?  The GCC documentation says:

https://gcc.gnu.org/onlinedocs/gcc/Multi-Alternative.html:

-8<-

[...] All operands for a single instruction must have the same number of
alternatives.

->8-

Also, I still think it may be redundant to move the addition inside the
asm, so long as Clang is happy with the symbol having an offset.

I.e., leave the .quad the same and revert to the one-liner

-		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
+		 :  :  "Si"(&((char *)key)[branch]) :  : l_yes);

This remains a bit nasty, but splitting the arguments and adding them
inside the asm is not really any cleaner.  Changing the way this works
doesn't seem relevant to what this patch is fixing (and apologies if I
created confusion here...)

>  
>  	return false;
>  l_yes:
> @@ -40,9 +44,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
>  		 "	.pushsection	__jump_table, \"aw\"	\n\t"
>  		 "	.align		3			\n\t"
>  		 "	.long		1b - ., %l[l_yes] - .	\n\t"
> -		 "	.quad		%c0 - .			\n\t"
> +		 "	.quad		%0 + %1 - .		\n\t"
>  		 "	.popsection				\n\t"
> -		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> +		 :  :  "Si"(key), "i"(branch) :  : l_yes);

Ditto.

[...]

Cheers
---Dave


From mripard at kernel.org  Fri Feb  2 07:59:30 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Fri, 2 Feb 2024 16:59:30 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB
 property
In-Reply-To: <Zb0M_2093UwPXK8y@intel.com>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
Message-ID: <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>

On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > Hi,
> > 
> > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > >  /**
> > > > >   * DOC: HDMI connector properties
> > > > >   *
> > > > > + * Broadcast RGB
> > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > + *      Infoframes will be generated according to that value.
> > > > > + *
> > > > > + *      The value of this property can be one of the following:
> > > > > + *
> > > > > + *      Automatic:
> > > > > + *              RGB Range is selected automatically based on the mode
> > > > > + *              according to the HDMI specifications.
> > > > > + *
> > > > > + *      Full:
> > > > > + *              Full RGB Range is forced.
> > > > > + *
> > > > > + *      Limited 16:235:
> > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > + *              this works for any number of bits-per-component.
> > > > > + *
> > > > > + *      Drivers can set up this property by calling
> > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > + *
> > > > 
> > > > This is a good time to document this in more detail. There might be two
> > > > different things being affected:
> > > > 
> > > > 1. The signalling (InfoFrame/SDP/...)
> > > > 2. The color pipeline processing
> > > > 
> > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > such that a full-range input to the CRTC is converted to either full- or
> > > > limited-range, depending on what the monitor is supposed to accept.
> > > > 
> > > > When automatic is selected, does that mean that there is no signalling,
> > > > or that the signalling matches what the monitor is supposed to accept
> > > > according to the spec? Also, is this really HDMI specific?
> > > > 
> > > > When full or limited is selected and the monitor doesn't support the
> > > > signalling, what happens?
> > > 
> > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > the cable, so is this only affecting RGB? If not, how does it affect
> > > YCbCr?
> > 
> > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > we're using a YCbCr format, i915 will always use a limited range while
> > vc4 will follow the value of the property.
> 
> The property is literally called "Broadcast *RGB*".
> That should explain why it's only affecting RGB.

Right. And the limited range option is called "Limited 16:235" despite
being usable on bpc > 8 bits. Naming errors occurs, and history happens
to make names inconsistent too, that's fine and not an argument in
itself.

> Full range YCbCr is a much rarer beast so we've never bothered
> to enable it.

vc4 supports it.

> Eg. with DP it only became possible with the introduction of the VSC
> SDP (and I don't recall if there's additional capability checks that
> are also required). With DP MSA signalling full range YCbCr is not
> possible at all.

This is for HDMI only.

> I don't recall right now what the HDMI requirements are.

HDMI has supported it for a while, and it's defined (for example) in the
HDMI 1.4 spec in Section 6.6 - Video Quantization Ranges. It supports
limited and full range on both RGB and YCbCr, as long as the EDIDs state
so and the Infoframes signal it.

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/20240202/8fd72adb/attachment.sig>

From sjg at chromium.org  Fri Feb  2 08:00:29 2024
From: sjg at chromium.org (Simon Glass)
Date: Fri, 2 Feb 2024 09:00:29 -0700
Subject: [PATCH v9 2/2] arm64: boot: Support Flat Image Tree
In-Reply-To: <CAL_JsqLYB0D5wAfedsb6tQp4EmD1AROgxiCncwO7gvA2p1C6Lg@mail.gmail.com>
References: <20231202035511.487946-1-sjg@chromium.org> <20231202035511.487946-3-sjg@chromium.org>
 <20231213121353.GA31326@willie-the-truck> <CAFLszTjfmSx1YMqzb2TsQf7sP4KrcQB=X7DY_HxRQp0J5HAppQ@mail.gmail.com>
 <CAK7LNAQRCDC03e=TVO=k4FuD2a2RdTy7yLr3UptQjVCX7pM1CA@mail.gmail.com>
 <20240109143349.GR1610741@bill-the-cat> <CAFLszTjwhy24UiT6kUJABMC1Xn0h9Q1q9fYpZZJg9DX8Vss9cA@mail.gmail.com>
 <CAFLszTjPAHd6RdO1mvatXC=yRS+h=sgJ_pMdyEnkROTx7yRpog@mail.gmail.com>
 <CAK7LNARsY6-rrx=sNFq6oFqpqf0s5S_=3DrUsCOS7zF0BXcoTg@mail.gmail.com> <CAL_JsqLYB0D5wAfedsb6tQp4EmD1AROgxiCncwO7gvA2p1C6Lg@mail.gmail.com>
Message-ID: <CAFLszTghBXCuSJTqnaA8vweYu2CKf-4y-X0Pr7Zg9qdyGGCE0Q@mail.gmail.com>

Hi,

On Wed, 31 Jan 2024 at 15:03, Rob Herring <robh at kernel.org> wrote:
>
> On Tue, Jan 30, 2024 at 3:16?AM Masahiro Yamada <masahiroy at kernel.org> wrote:
> >
> > On Fri, Jan 26, 2024 at 1:04?AM Simon Glass <sjg at chromium.org> wrote:
> > >
> > > Hi,
> > >
> > > On Wed, 17 Jan 2024 at 06:14, Simon Glass <sjg at chromium.org> wrote:
> > > >
> > > > Hi Masahiro, Tom,
> > > >
> > > > On Tue, 9 Jan 2024 at 07:33, Tom Rini <trini at konsulko.com> wrote:
> > > > >
> > > > > On Tue, Jan 09, 2024 at 11:01:42PM +0900, Masahiro Yamada wrote:
> > > > > > Hi Simon,
> > > > > >
> > > > > >
> > > > > > On Wed, Jan 3, 2024 at 8:47?AM Simon Glass <sjg at chromium.org> wrote:
> > > > > > >
> > > > > > > Hi Masahiro,
> > > > > > >
> > > > > > > On Wed, Dec 13, 2023 at 5:14?AM Will Deacon <will at kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Fri, Dec 01, 2023 at 08:54:42PM -0700, Simon Glass wrote:
> > > > > > > > > Add a script which produces a Flat Image Tree (FIT), a single file
> > > > > > > > > containing the built kernel and associated devicetree files.
> > > > > > > > > Compression defaults to gzip which gives a good balance of size and
> > > > > > > > > performance.
> > > > > > > > >
> > > > > > > > > The files compress from about 86MB to 24MB using this approach.
> > > > > > > > >
> > > > > > > > > The FIT can be used by bootloaders which support it, such as U-Boot
> > > > > > > > > and Linuxboot. It permits automatic selection of the correct
> > > > > > > > > devicetree, matching the compatible string of the running board with
> > > > > > > > > the closest compatible string in the FIT. There is no need for
> > > > > > > > > filenames or other workarounds.
> > > > > > > > >
> > > > > > > > > Add a 'make image.fit' build target for arm64, as well. Use
> > > > > > > > > FIT_COMPRESSION to select a different algorithm.
> > > > > > > > >
> > > > > > > > > The FIT can be examined using 'dumpimage -l'.
> > > > > > > > >
> > > > > > > > > This features requires pylibfdt (use 'pip install libfdt'). It also
> > > > > > > > > requires compression utilities for the algorithm being used. Supported
> > > > > > > > > compression options are the same as the Image.xxx files. For now there
> > > > > > > > > is no way to change the compression other than by editing the rule for
> > > > > > > > > $(obj)/image.fit
> > > > > > > > >
> > > > > > > > > While FIT supports a ramdisk / initrd, no attempt is made to support
> > > > > > > > > this here, since it must be built separately from the Linux build.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Simon Glass <sjg at chromium.org>
> > > > > > > > > ---
> > > > > > > > >
> > > > > > > > > Changes in v9:
> > > > > > > > > - Move the compression control into Makefile.lib
> > > > > > > > >
> > > > > > > > > Changes in v8:
> > > > > > > > > - Drop compatible string in FDT node
> > > > > > > > > - Correct sorting of MAINTAINERS to before ARM64 PORT
> > > > > > > > > - Turn compress part of the make_fit.py comment in to a sentence
> > > > > > > > > - Add two blank lines before parse_args() and setup_fit()
> > > > > > > > > - Use 'image.fit: dtbs' instead of BUILD_DTBS var
> > > > > > > > > - Use '$(<D)/dts' instead of '$(dir $<)dts'
> > > > > > > > > - Add 'mkimage' details Documentation/process/changes.rst
> > > > > > > > > - Allow changing the compression used
> > > > > > > > > - Tweak cover letter since there is only one clean-up patch
> > > > > > > > >
> > > > > > > > > Changes in v7:
> > > > > > > > > - Add Image as a dependency of image.fit
> > > > > > > > > - Drop kbuild tag
> > > > > > > > > - Add dependency on dtbs
> > > > > > > > > - Drop unnecessary path separator for dtbs
> > > > > > > > > - Rebase to -next
> > > > > > > > >
> > > > > > > > > Changes in v5:
> > > > > > > > > - Drop patch previously applied
> > > > > > > > > - Correct compression rule which was broken in v4
> > > > > > > > >
> > > > > > > > > Changes in v4:
> > > > > > > > > - Use single quotes for UIMAGE_NAME
> > > > > > > > >
> > > > > > > > > Changes in v3:
> > > > > > > > > - Drop temporary file image.itk
> > > > > > > > > - Drop patch 'Use double quotes for image name'
> > > > > > > > > - Drop double quotes in use of UIMAGE_NAME
> > > > > > > > > - Drop unnecessary CONFIG_EFI_ZBOOT condition for help
> > > > > > > > > - Avoid hard-coding "arm64" for the DT architecture
> > > > > > > > >
> > > > > > > > > Changes in v2:
> > > > > > > > > - Drop patch previously applied
> > > > > > > > > - Add .gitignore file
> > > > > > > > > - Move fit rule to Makefile.lib using an intermediate file
> > > > > > > > > - Drop dependency on CONFIG_EFI_ZBOOT
> > > > > > > > > - Pick up .dtb files separately from the kernel
> > > > > > > > > - Correct pylint too-many-args warning for write_kernel()
> > > > > > > > > - Include the kernel image in the file count
> > > > > > > > > - Add a pointer to the FIT spec and mention of its wide industry usage
> > > > > > > > > - Mention the kernel version in the FIT description
> > > > > > > > >
> > > > > > > > >  Documentation/process/changes.rst |   9 +
> > > > > > > > >  MAINTAINERS                       |   7 +
> > > > > > > > >  arch/arm64/Makefile               |   7 +-
> > > > > > > > >  arch/arm64/boot/.gitignore        |   1 +
> > > > > > > > >  arch/arm64/boot/Makefile          |   6 +-
> > > > > > > > >  scripts/Makefile.lib              |  16 ++
> > > > > > > > >  scripts/make_fit.py               | 291 ++++++++++++++++++++++++++++++
> > > > > > > > >  7 files changed, 334 insertions(+), 3 deletions(-)
> > > > > > > > >  create mode 100755 scripts/make_fit.py
> > > > > > > >
> > > > > > > > I'll need Masahiro's Ack on the scripts/ changes before I can take this
> > > > > > > > one.
> > > > > > >
> > > > > > > Any thoughts on this request, please?
> > > > > > >
> > > > > > > Regards,
> > > > > > > Simon
> > > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > As I mentioned before, I am concerned with having
> > > > > > the same "compatible" entries, with different contents,
> > > > > > as you use the "compatible" string as an ID to selecting
> > > > > > the target config node, right?
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > $ fdtdump  arch/arm64/boot/image.fit
> > > > > >
> > > > > >         ...
> > > > > >
> > > > > >         conf-10 {
> > > > > >             compatible = "tq,am642-tqma6442l-mbax4xxl",
> > > > > > "tq,am642-tqma6442l", "ti,am642";
> > > > > >             description = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > > >             fdt = "fdt-10";
> > > > > >             kernel = "kernel";
> > > > > >         };
> > > > > >
> > > > > >         ...
> > > > > >
> > > > > >         conf-25 {
> > > > > >             compatible = "tq,am642-tqma6442l-mbax4xxl",
> > > > > > "tq,am642-tqma6442l", "ti,am642";
> > > > > >             description = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > > >             fdt = "fdt-25";
> > > > > >             kernel = "kernel";
> > > > > >         };
> > > > >
> > > > > I had asked Rob a while ago about if having the same compatible for two
> > > > > functionally different machines is a feature, or a bug, and I don't
> > > > > think either of us fully agreed either way. I'd be leaning towards
> > > > > saying the above example is a bug in the dts files, it's just not been a
> > > > > bug people have worried about before due to (sadly) how little the
> > > > > top-level compatible has been used.
>
> I much prefer being able to use compatibles over filenames.

So do I.

There is no check that each dts has a unique compatible string (e.g.
in the first position). Perhaps we should add that and have vendors
fix up their strings?

[..]

>
> Rob

Regards,
Simon


From sjg at chromium.org  Fri Feb  2 08:00:57 2024
From: sjg at chromium.org (Simon Glass)
Date: Fri, 2 Feb 2024 09:00:57 -0700
Subject: [PATCH v9 2/2] arm64: boot: Support Flat Image Tree
In-Reply-To: <CAK7LNARsY6-rrx=sNFq6oFqpqf0s5S_=3DrUsCOS7zF0BXcoTg@mail.gmail.com>
References: <20231202035511.487946-1-sjg@chromium.org> <20231202035511.487946-3-sjg@chromium.org>
 <20231213121353.GA31326@willie-the-truck> <CAFLszTjfmSx1YMqzb2TsQf7sP4KrcQB=X7DY_HxRQp0J5HAppQ@mail.gmail.com>
 <CAK7LNAQRCDC03e=TVO=k4FuD2a2RdTy7yLr3UptQjVCX7pM1CA@mail.gmail.com>
 <20240109143349.GR1610741@bill-the-cat> <CAFLszTjwhy24UiT6kUJABMC1Xn0h9Q1q9fYpZZJg9DX8Vss9cA@mail.gmail.com>
 <CAFLszTjPAHd6RdO1mvatXC=yRS+h=sgJ_pMdyEnkROTx7yRpog@mail.gmail.com> <CAK7LNARsY6-rrx=sNFq6oFqpqf0s5S_=3DrUsCOS7zF0BXcoTg@mail.gmail.com>
Message-ID: <CAFLszTgYMrj2AhYdAXBjGACQjehvVBnJ2EsKg2TO7c50Dp_ukQ@mail.gmail.com>

Hi Masahiro,

On Tue, 30 Jan 2024 at 02:16, Masahiro Yamada <masahiroy at kernel.org> wrote:
>
> On Fri, Jan 26, 2024 at 1:04?AM Simon Glass <sjg at chromium.org> wrote:
> >
> > Hi,
> >
> > On Wed, 17 Jan 2024 at 06:14, Simon Glass <sjg at chromium.org> wrote:
> > >
> > > Hi Masahiro, Tom,
> > >
> > > On Tue, 9 Jan 2024 at 07:33, Tom Rini <trini at konsulko.com> wrote:
> > > >
> > > > On Tue, Jan 09, 2024 at 11:01:42PM +0900, Masahiro Yamada wrote:
> > > > > Hi Simon,
> > > > >
> > > > >
> > > > > On Wed, Jan 3, 2024 at 8:47?AM Simon Glass <sjg at chromium.org> wrote:
> > > > > >
> > > > > > Hi Masahiro,
> > > > > >
> > > > > > On Wed, Dec 13, 2023 at 5:14?AM Will Deacon <will at kernel.org> wrote:
> > > > > > >
> > > > > > > On Fri, Dec 01, 2023 at 08:54:42PM -0700, Simon Glass wrote:
> > > > > > > > Add a script which produces a Flat Image Tree (FIT), a single file
> > > > > > > > containing the built kernel and associated devicetree files.
> > > > > > > > Compression defaults to gzip which gives a good balance of size and
> > > > > > > > performance.
> > > > > > > >
> > > > > > > > The files compress from about 86MB to 24MB using this approach.
> > > > > > > >
> > > > > > > > The FIT can be used by bootloaders which support it, such as U-Boot
> > > > > > > > and Linuxboot. It permits automatic selection of the correct
> > > > > > > > devicetree, matching the compatible string of the running board with
> > > > > > > > the closest compatible string in the FIT. There is no need for
> > > > > > > > filenames or other workarounds.
> > > > > > > >
> > > > > > > > Add a 'make image.fit' build target for arm64, as well. Use
> > > > > > > > FIT_COMPRESSION to select a different algorithm.
> > > > > > > >
> > > > > > > > The FIT can be examined using 'dumpimage -l'.
> > > > > > > >
> > > > > > > > This features requires pylibfdt (use 'pip install libfdt'). It also
> > > > > > > > requires compression utilities for the algorithm being used. Supported
> > > > > > > > compression options are the same as the Image.xxx files. For now there
> > > > > > > > is no way to change the compression other than by editing the rule for
> > > > > > > > $(obj)/image.fit
> > > > > > > >
> > > > > > > > While FIT supports a ramdisk / initrd, no attempt is made to support
> > > > > > > > this here, since it must be built separately from the Linux build.
> > > > > > > >
> > > > > > > > Signed-off-by: Simon Glass <sjg at chromium.org>
> > > > > > > > ---
> > > > > > > >
> > > > > > > > Changes in v9:
> > > > > > > > - Move the compression control into Makefile.lib
> > > > > > > >
> > > > > > > > Changes in v8:
> > > > > > > > - Drop compatible string in FDT node
> > > > > > > > - Correct sorting of MAINTAINERS to before ARM64 PORT
> > > > > > > > - Turn compress part of the make_fit.py comment in to a sentence
> > > > > > > > - Add two blank lines before parse_args() and setup_fit()
> > > > > > > > - Use 'image.fit: dtbs' instead of BUILD_DTBS var
> > > > > > > > - Use '$(<D)/dts' instead of '$(dir $<)dts'
> > > > > > > > - Add 'mkimage' details Documentation/process/changes.rst
> > > > > > > > - Allow changing the compression used
> > > > > > > > - Tweak cover letter since there is only one clean-up patch
> > > > > > > >
> > > > > > > > Changes in v7:
> > > > > > > > - Add Image as a dependency of image.fit
> > > > > > > > - Drop kbuild tag
> > > > > > > > - Add dependency on dtbs
> > > > > > > > - Drop unnecessary path separator for dtbs
> > > > > > > > - Rebase to -next
> > > > > > > >
> > > > > > > > Changes in v5:
> > > > > > > > - Drop patch previously applied
> > > > > > > > - Correct compression rule which was broken in v4
> > > > > > > >
> > > > > > > > Changes in v4:
> > > > > > > > - Use single quotes for UIMAGE_NAME
> > > > > > > >
> > > > > > > > Changes in v3:
> > > > > > > > - Drop temporary file image.itk
> > > > > > > > - Drop patch 'Use double quotes for image name'
> > > > > > > > - Drop double quotes in use of UIMAGE_NAME
> > > > > > > > - Drop unnecessary CONFIG_EFI_ZBOOT condition for help
> > > > > > > > - Avoid hard-coding "arm64" for the DT architecture
> > > > > > > >
> > > > > > > > Changes in v2:
> > > > > > > > - Drop patch previously applied
> > > > > > > > - Add .gitignore file
> > > > > > > > - Move fit rule to Makefile.lib using an intermediate file
> > > > > > > > - Drop dependency on CONFIG_EFI_ZBOOT
> > > > > > > > - Pick up .dtb files separately from the kernel
> > > > > > > > - Correct pylint too-many-args warning for write_kernel()
> > > > > > > > - Include the kernel image in the file count
> > > > > > > > - Add a pointer to the FIT spec and mention of its wide industry usage
> > > > > > > > - Mention the kernel version in the FIT description
> > > > > > > >
> > > > > > > >  Documentation/process/changes.rst |   9 +
> > > > > > > >  MAINTAINERS                       |   7 +
> > > > > > > >  arch/arm64/Makefile               |   7 +-
> > > > > > > >  arch/arm64/boot/.gitignore        |   1 +
> > > > > > > >  arch/arm64/boot/Makefile          |   6 +-
> > > > > > > >  scripts/Makefile.lib              |  16 ++
> > > > > > > >  scripts/make_fit.py               | 291 ++++++++++++++++++++++++++++++
> > > > > > > >  7 files changed, 334 insertions(+), 3 deletions(-)
> > > > > > > >  create mode 100755 scripts/make_fit.py
> > > > > > >
> > > > > > > I'll need Masahiro's Ack on the scripts/ changes before I can take this
> > > > > > > one.
> > > > > >
> > > > > > Any thoughts on this request, please?
> > > > > >
> > > > > > Regards,
> > > > > > Simon
> > > > > >
> > > > >
> > > > >
> > > > >
> > > > > As I mentioned before, I am concerned with having
> > > > > the same "compatible" entries, with different contents,
> > > > > as you use the "compatible" string as an ID to selecting
> > > > > the target config node, right?
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > $ fdtdump  arch/arm64/boot/image.fit
> > > > >
> > > > >         ...
> > > > >
> > > > >         conf-10 {
> > > > >             compatible = "tq,am642-tqma6442l-mbax4xxl",
> > > > > "tq,am642-tqma6442l", "ti,am642";
> > > > >             description = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > >             fdt = "fdt-10";
> > > > >             kernel = "kernel";
> > > > >         };
> > > > >
> > > > >         ...
> > > > >
> > > > >         conf-25 {
> > > > >             compatible = "tq,am642-tqma6442l-mbax4xxl",
> > > > > "tq,am642-tqma6442l", "ti,am642";
> > > > >             description = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > >             fdt = "fdt-25";
> > > > >             kernel = "kernel";
> > > > >         };
> > > >
> > > > I had asked Rob a while ago about if having the same compatible for two
> > > > functionally different machines is a feature, or a bug, and I don't
> > > > think either of us fully agreed either way. I'd be leaning towards
> > > > saying the above example is a bug in the dts files, it's just not been a
> > > > bug people have worried about before due to (sadly) how little the
> > > > top-level compatible has been used.
> > >
> > > Yes I believe this is a bug in the files.
> > >
> > > What should the script do in this case? Print a warning, perhaps?
> >
> > Is there anything I should do here? Would a warning be helpful, or
> > just confusing?
>
>
>
> I do not think it is useful.
> You would almost always get a warning, and there is no way to fix it.
>
>
>
> With arm64 defconfig, image.fit will include a thousand DTBs.
>
>
> The config node of my board was listed 214th.
> (I found it by fdtdump)
>
>
> Then, I learned
>
>   >  bootm  ${loadaddr}#conf-214
>
> is the correct command to boot my board.
>
>
> Of course, the "214" will be different in the future.
>
> The node names, conf-*, are useless.
>
>
>
> Only the useful way is to enable CONFIG_FIT_BEST_MATCH in U-Boot,
> but this relies on the uniqueness of a compatible string,
> which is not true.

See my other email, but I think this is a problem we should fix.

>
> (I do not know how to do it in barebox)
>
>
>
>
>
> I think using the file name as a config node
> mitigates the issue because a file name is
> considered unique.
>
>
> For example, with composite DTBs:
>
> imx8mm-venice-gw72xx-0x-imx219-dtbs := imx8mm-venice-gw72xx-0x.dtb
> imx8mm-venice-gw72xx-0x-imx219.dtbo
> imx8mm-venice-gw72xx-0x-rpidsi-dtbs := imx8mm-venice-gw72xx-0x.dtb
> imx8mm-venice-gw72xx-0x-rpidsi.dtbo
>
>
>
>
> configurations {
>       imx8mm-venice-gw72xx-0x-imx219 {
>             ...
>       };
>
>       imx8mm-venice-gw72xx-0x-rpidsi {
>             ...
>       }
> };
>
>
>
> Then, we can distinguish them by node, even if they have
> the same compatible string.
> At least we can do
>
>   > bootm  ${loadaddr}#imx8mm-venice-gw72xx-0x-imx219
>
>

Sure, but the goal with FIT is to be able to boot with the correct dtb
automatically. What you have above would require some sort of boot
script, or some other information about the configuration-node name.

>
>
> For the issue including stale DTBs, you can use my patch:
> [PATCH 1/4] kbuild: create a list of all built DTB files
> (https://lore.kernel.org/linux-kbuild/CAK7LNASOxi-gzve+_d-sCW9z_eEJ5TMMnzPEvN2Nj2AwgVjF9g at mail.gmail.com/T/#ma3595627a96a04554a78cbbd22056831e13db260)
>
>
> You can change scripts/make_fit.py to take
> the DTB files instead of the directory to search.
>
> Optionally, you can support '@' syntax to
> take command arguments from a file.
>
>
> scripts/make_fit.py ... @arch/$(SRCARCH)/boot/dts/dtbs-list

Thank you for doing that. I will take a look and send v10.

>
>
>
>
>
>
> For the separate base and overlays support,
> you can use my patch as a base:
> [PATCH 3/4] kbuild: create a list of base and overlays for each DTB
> (https://lore.kernel.org/linux-kbuild/CAK7LNASOxi-gzve+_d-sCW9z_eEJ5TMMnzPEvN2Nj2AwgVjF9g at mail.gmail.com/T/#m32c5bdde9098901b7c7776b932827493a05c82d5)
>
>
>
>
>
> Lastly, you do not need to require mkimage for
> args.external.
> You can simply concatenate files.

Yes, that's true. Do you think there is a problem with using mkimage?

Regards,
Simon


From josua at solid-run.com  Fri Feb  2 08:10:48 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 17:10:48 +0100
Subject: [PATCH v4 1/5] dt-bindings: arm: ti: Add bindings for SolidRun
 AM642 HummingBoard-T
In-Reply-To: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
Message-ID: <20240202-add-am64-som-v4-1-5f8b12af5e71@solid-run.com>

Add bindings for SolidRun AM642 HummingBoard-T Board, which is the
evaluation board for SolidRun AM642 SoM.

Signed-off-by: Josua Mayer <josua at solid-run.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/ti/k3.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
index 03d2a0d79fb0..b9f2a8d36874 100644
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -85,6 +85,13 @@ properties:
           - const: tq,am642-tqma6442l
           - const: ti,am642
 
+      - description: K3 AM642 SoC SolidRun SoM based boards
+        items:
+          - enum:
+              - solidrun,am642-hummingboard-t
+          - const: solidrun,am642-sr-som
+          - const: ti,am642
+
       - description: K3 AM654 SoC
         items:
           - enum:

-- 
2.35.3



From josua at solid-run.com  Fri Feb  2 08:10:47 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 17:10:47 +0100
Subject: [PATCH v4 0/5] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
Message-ID: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>

This series adds DT bindings and dts descriptions for SolidRun AM642
based SoM and Hummingboard EVB.

Additionally a commit from downstream vendor kernel are included,
enhancing support for pru based ethernet.
I wasn't sure how to properly annotate it in commit description /
signed-off area ...:

1. add description for "Industrial Ethernet Peripherals" (IEP) to am64
   https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/commit/arch/arm64/boot/dts/ti/k3-am64-main.dtsi?h=ti-linux-6.1.y-cicd&id=5afb73d82a014b59462162d960b350b8c58e5ae6
   IEP is already supported in-tree by a driver, and used in
   k3-am65-main.dtsi.

Unfortunately dtbs_check reported many problems, I put some remarks:

- 'mux-controller' does not match any of the regexes
  The expectation seems to be that a mux-controller at minimum has an
  address, something to put behind an @. However this is a gpio mux, not
  sure how to name it better.

- unevaluated properties: interrupts, interrupt-parent
  sensors and flash yaml are missing interrupt descriptions, but these
  parts definitely have an interrupt signal in this solidrun board.

- wrong names for pinctrl nodes
  Other TI DTSs consistently end with *-pins-default. Should a different
  naming convention be used?

- cdns,phy-type required property
  inherited from k3-am64-main.dtsi
  there is a PHY_NONE value in dt-bindings/phy/phy.h,
  but not allowed in phy-cadence-torrent.yaml

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
Changes in v4:
- abracon,abx80x.yaml: fixed dtc error in example irq reference
- Link to v3: https://lore.kernel.org/r/20240202-add-am64-som-v3-0-2f44023d50e9 at solid-run.com

Changes in v3:
- removed lots more status properties, double-checked against soc dtsi
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
  (reported by Andrew Davis <afd at ti.com>)
- removed intentionally-disabled pcie node from dts
- rewrote yaml bindings to use enum instead of anyof+const+description
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
- abracon yaml
  - added missing maintainer
  - added diode type property type
  - added example
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>)
  - added reference to /schemas/interrupts.yaml#
- use generic name for pru ethernet controller node
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>)
- removed unnamed dmas from pru ethernet controller node
- moved pcie/usb3 features to dtb overlays
- Link to v2: https://lore.kernel.org/r/20240112-add-am64-som-v2-0-1385246c428c at solid-run.com

Changes in v2:
- reordered patchset to drop separate patch adding iep handle to som
- moved dtbs_check warnings to cover letter
- converted abracon abx80x rtc bindings to yaml
- updated dts:
  - remove unnecessary status properties
  - changed non-generic node names
  - use color property for led descriptions,
    they have no default function on evaluation board
  - drop earlycon bootargs from chosen node
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
- converted charger node to comment, part not assembled, has no bindings
- picked up acked-by on board bindings patch
- Link to v1: https://lore.kernel.org/r/20240103-add-am64-som-v1-0-dda1f9227aef at solid-run.com

---
Josua Mayer (4):
      dt-bindings: arm: ti: Add bindings for SolidRun AM642 HummingBoard-T
      dt-bindings: rtc: abx80x: convert to yaml
      arm64: dts: add description for solidrun am642 som and evaluation board
      arm64: dts: ti: hummingboard-t: add overlays for m.2 pci-e and usb-3

Suman Anna (1):
      arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes

 Documentation/devicetree/bindings/arm/ti/k3.yaml   |   7 +
 .../devicetree/bindings/rtc/abracon,abx80x.txt     |  31 --
 .../devicetree/bindings/rtc/abracon,abx80x.yaml    |  74 +++
 arch/arm64/boot/dts/ti/Makefile                    |   7 +
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi           |  24 +
 .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  |  45 ++
 .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  |  44 ++
 arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 592 +++++++++++++++++++++
 9 files changed, 1085 insertions(+), 31 deletions(-)
---
base-commit: 861deac3b092f37b2c5e6871732f3e11486f7082
change-id: 20240101-add-am64-som-51a1ca47edf3

Sincerely,
-- 
Josua Mayer <josua at solid-run.com>



From josua at solid-run.com  Fri Feb  2 08:10:50 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 17:10:50 +0100
Subject: [PATCH v4 3/5] arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
In-Reply-To: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
Message-ID: <20240202-add-am64-som-v4-3-5f8b12af5e71@solid-run.com>

From: Suman Anna <s-anna at ti.com>

The ICSSG IP on AM64x SoCs have two Industrial Ethernet Peripherals (IEPs)
to manage/generate Industrial Ethernet functions such as time stamping.
Each IEP sub-module is sourced from an internal clock mux that can be
derived from either of the IP instance's ICSSG_IEP_GCLK or from another
internal ICSSG CORE_CLK mux. Add both the IEP nodes for both the ICSSG
instances. The IEP clock is currently configured to be derived
indirectly from the ICSSG_ICLK running at 250 MHz.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
Signed-off-by: Suman Anna <s-anna at ti.com>
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index 0be642bc1b86..8130ee02a3d9 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -1232,6 +1232,18 @@ icssg0_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg0_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
+		icssg0_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
 		icssg0_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
@@ -1373,6 +1385,18 @@ icssg1_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg1_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
+		icssg1_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
 		icssg1_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;

-- 
2.35.3



From josua at solid-run.com  Fri Feb  2 08:10:49 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 17:10:49 +0100
Subject: [PATCH v4 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
Message-ID: <20240202-add-am64-som-v4-2-5f8b12af5e71@solid-run.com>

Convert the abracon abx80x rtc text bindings to dt-schema format.

In addition to the text description reference generic interrupts
properties and add an example.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ---------
 .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 74 ++++++++++++++++++++++
 2 files changed, 74 insertions(+), 31 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
deleted file mode 100644
index 2405e35a1bc0..000000000000
--- a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-Abracon ABX80X I2C ultra low power RTC/Alarm chip
-
-The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
-ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
-is the superset of ab180x.
-
-Required properties:
-
- - "compatible": should one of:
-        "abracon,abx80x"
-        "abracon,ab0801"
-        "abracon,ab0803"
-        "abracon,ab0804"
-        "abracon,ab0805"
-        "abracon,ab1801"
-        "abracon,ab1803"
-        "abracon,ab1804"
-        "abracon,ab1805"
-        "microcrystal,rv1805"
-	Using "abracon,abx80x" will enable chip autodetection.
- - "reg": I2C bus address of the device
-
-Optional properties:
-
-The abx804 and abx805 have a trickle charger that is able to charge the
-connected battery or supercap. Both the following properties have to be defined
-and valid to enable charging:
-
- - "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
- - "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
-                          resistor, the other values are in kOhm.
diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
new file mode 100644
index 000000000000..405b386a54b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Abracon ABX80X I2C ultra low power RTC/Alarm chip
+
+maintainers:
+  - devicetree at vger.kernel.org
+
+allOf:
+  - $ref: rtc.yaml#
+  - $ref: /schemas/interrupts.yaml#
+
+properties:
+  compatible:
+    description:
+      Select a specific compatible chip.
+
+      'abracon,abx80x' has special meaning,
+      it provides auto-dection based on ID register.
+    enum:
+      - abracon,abx80x
+      - abracon,ab0801
+      - abracon,ab0803
+      - abracon,ab0804
+      - abracon,ab0805
+      - abracon,ab1801
+      - abracon,ab1803
+      - abracon,ab1804
+      - abracon,ab1805
+      - microcrystal,rv1805
+
+  reg:
+    maxItems: 1
+
+  abracon,tc-diode:
+    description:
+      Trickle-charge diode type.
+      Required to enable charging backup battery.
+
+      Supported are 'standard' diodes with a 0.6V drop
+      and 'schottky' diodes with a 0.3V drop.
+    $ref: /schemas/types.yaml#/definitions/string
+    enum:
+      - standard
+      - schottky
+
+  abracon,tc-resistor:
+    description:
+      Trickle-charge resistor value in kOhm.
+      Required to enable charging backup battery.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 3, 6, 11]
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    rtc at 69 {
+        compatible = "abracon,abx80x";
+        reg = <0x69>;
+        abracon,tc-diode = "schottky";
+        abracon,tc-resistor = <3>;
+        interrupt-parent = <&fake_intc0>;
+        interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
+    };

-- 
2.35.3



From josua at solid-run.com  Fri Feb  2 08:10:52 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 17:10:52 +0100
Subject: [PATCH v4 5/5] arm64: dts: ti: hummingboard-t: add overlays for
 m.2 pci-e and usb-3
In-Reply-To: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
Message-ID: <20240202-add-am64-som-v4-5-5f8b12af5e71@solid-run.com>

HummingBoard-T features two M.2 connectors labeled "M1" and "M2".
The single SerDes lane of the SoC can be routed to either M1 pci-e
signals, or M2 usb-3 signals by a gpio-controlled mux.

Add overlays for each configuration.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/Makefile                    |  6 +++
 .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  | 45 ++++++++++++++++++++++
 .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  | 44 +++++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 041c3b71155e..ace72b4b85b0 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -31,8 +31,14 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb
 
 # Boards with AM64x SoC
+k3-am642-hummingboard-t-pcie-dtbs := \
+	k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-pcie.dtbo
+k3-am642-hummingboard-t-usb3-dtbs := \
+	k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-usb3.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-pcie.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-usb3.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
new file mode 100644
index 000000000000..fd3f8d00c56a
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable PCI-E.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&pcie0_rc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_pins_default>;
+	reset-gpios = <&main_gpio1 15 GPIO_ACTIVE_HIGH>;
+	phys = <&serdes0_link>;
+	phy-names = "pcie-phy";
+	num-lanes = <1>;
+	status = "okay";
+};
+
+&serdes0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	serdes0_link: phy at 0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		cdns,phy-type = <PHY_TYPE_PCIE>;
+		#phy-cells = <0>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes_ln_ctrl {
+	idle-states = <AM64_SERDES0_LANE0_PCIE0>;
+};
+
+&serdes_mux {
+	idle-state = <1>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
new file mode 100644
index 000000000000..ffcc3bd3c7bc
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable USB-3.1.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&serdes0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	serdes0_link: phy at 0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		cdns,phy-type = <PHY_TYPE_USB3>;
+		#phy-cells = <0>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes_ln_ctrl {
+	idle-states = <AM64_SERDES0_LANE0_USB>;
+};
+
+&serdes_mux {
+	idle-state = <0>;
+};
+
+&usbss0 {
+	/delete-property/ ti,usb2-only;
+};
+
+&usb0 {
+	maximum-speed = "super-speed";
+	phys = <&serdes0_link>;
+	phy-names = "cdns3,usb3-phy";
+};

-- 
2.35.3



From josua at solid-run.com  Fri Feb  2 08:10:51 2024
From: josua at solid-run.com (Josua Mayer)
Date: Fri, 02 Feb 2024 17:10:51 +0100
Subject: [PATCH v4 4/5] arm64: dts: add description for solidrun am642 som
 and evaluation board
In-Reply-To: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
Message-ID: <20240202-add-am64-som-v4-4-5f8b12af5e71@solid-run.com>

Add description for the SolidRun AM642 SoM, and HummingBoard-T
evaluation board.

The SoM features:
- 1x cpsw ethernet with phy
- 2x pru ethernet with phy
- eMMC
- spi flash (assembly option)

Additionally microSD and usb-2.0 otg are included in the SoM
description as they are supported boot sources for the SOC boot-rom.

The Carrier provides:
- 3x RJ45 connector
- 2x M.2 connector
- USB-2.0 Hub
- USB-A Connector
- LEDs
- 2x CAN transceiver
- 1x RS485 transceiver
- sensors

The M.2 connectors support either USB-3.1 or PCI-E depending on status
of a mux. By default the mux is switched off.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/Makefile                    |   1 +
 arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 592 +++++++++++++++++++++
 3 files changed, 885 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 77a347f9f47d..041c3b71155e 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -32,6 +32,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb
 
 # Boards with AM64x SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
new file mode 100644
index 000000000000..ebaf281e1e1e
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * DTS for SolidRun AM642 HummingBoard-T,
+ * running on Cortex A53.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-am642.dtsi"
+#include "k3-am642-sr-som.dtsi"
+
+/ {
+	model = "SolidRun AM642 HummingBoard-T";
+	compatible = "solidrun,am642-hummingboard-t", "solidrun,am642-sr-som", "ti,am642";
+
+	aliases {
+		serial5 = &main_uart3;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&leds_pins_default>;
+
+		/* D24 */
+		led1: led-1 {
+			label = "led1";
+			gpios = <&main_gpio0 29 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		/* D25 */
+		led2: led-2 {
+			label = "led2";
+			gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		/* D26 */
+		led3: led-3 {
+			label = "led3";
+			gpios = <&main_gpio0 33 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+	};
+
+	regulator-m2-3v3 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&regulator_pcie_3v3_pins_default>;
+		regulator-name = "m2-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&main_gpio1 17 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	regulator-vpp-1v8 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&regulator_vpp_1v8_pins_default>;
+		regulator-name = "vpp-1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		gpio = <&main_gpio1 78 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	serdes_mux: mux-controller {
+		compatible = "gpio-mux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&serdes_mux_pins_default>;
+		#mux-control-cells = <0>;
+		/*
+		 * Mux has 2 IOs:
+		 * - select: 0 = USB-3 (M2); 1 = PCIE (M1)
+		 * - shutdown: 0 = active; 1 = disabled (high impedance)
+		 */
+		mux-gpios = <&main_gpio1 40 GPIO_ACTIVE_HIGH>, <&main_gpio1 41 GPIO_ACTIVE_HIGH>;
+		/* default disabled */
+		idle-state = <2>;
+	};
+};
+
+&main_gpio0 {
+	m2-reset-hog {
+		gpio-hog;
+		gpios = <12 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m2-reset";
+	};
+
+	m1-m2-w-disable1-hog {
+		gpio-hog;
+		gpios = <32 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m1-m2-pcie-w-disable1";
+	};
+
+	m1-m2-w-disable2-hog {
+		gpio-hog;
+		gpios = <34 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m1-m2-pcie-w-disable2";
+	};
+};
+
+&main_gpio1 {
+	m1-pcie-clkreq0-hog {
+		gpio-hog;
+		gpios = <11 GPIO_ACTIVE_LOW>;
+		input;
+		line-name = "m1-pcie-clkreq0";
+	};
+
+	m2-pcie-clkreq-hog {
+		gpio-hog;
+		gpios = <35 GPIO_ACTIVE_LOW>;
+		input;
+		line-name = "m2-pcie-clkreq";
+	};
+};
+
+&main_i2c0 {
+	pinctrl-0 = <&main_i2c0_pins_default>, <&main_i2c0_int_pins_default>;
+
+	humidity-sensor at 41 {
+		compatible = "ti,hdc2010";
+		reg = <0x41>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+	light-sensor at 44 {
+		compatible = "ti,opt3001";
+		reg = <0x44>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+	/* charger at 6a */
+};
+
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	status = "okay";
+
+	rtc at 69 {
+		compatible = "abracon,abx80x";
+		reg = <0x69>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtc_int_pins_default>;
+		abracon,tc-diode = "schottky";
+		abracon,tc-resistor = <3>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
+
+&main_mcan0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan0_pins_default>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <8000000>;
+	};
+};
+
+&main_mcan1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan1_pins_default>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <8000000>;
+	};
+};
+
+&main_pmx0 {
+	leds_pins_default: leds-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0074, PIN_OUTPUT, 7)	/* GPMC0_AD14.GPIO0_29 */
+			AM64X_IOPAD(0x0078, PIN_OUTPUT, 7)	/* GPMC0_AD15.GPIO0_30 */
+			AM64X_IOPAD(0x0088, PIN_OUTPUT, 7)	/* GPMC0_OEn_REn.GPIO0_33 */
+		>;
+	};
+
+	main_i2c0_int_pins_default: main-i2c0-pins-int-default {
+		pinctrl-single,pins = <
+			/* external pull-up on Carrier */
+			AM64X_IOPAD(0x0098, PIN_INPUT, 7)	/* GPMC0_WAIT0.GPIO0_37 */
+		>;
+	};
+
+	main_i2c1_pins_default: main-i2c1-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x0268, PIN_INPUT, 0)	/* I2C1_SCL.I2C1_SCL */
+			AM64X_IOPAD(0x026c, PIN_INPUT, 0)	/* I2C1_SDA.I2C1_SDA */
+		>;
+	};
+
+	main_mcan0_pins_default: main-mcan0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0254, PIN_INPUT, 0)	/* MCAN0_RX.MCAN0_RX */
+			AM64X_IOPAD(0x0250, PIN_OUTPUT, 0)	/* MCAN0_TX.MCAN0_TX */
+		>;
+	};
+
+	main_mcan1_pins_default: main-mcan1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x025c, PIN_INPUT, 0)	/* MCAN1_RX.MCAN1_RX */
+			AM64X_IOPAD(0x0258, PIN_OUTPUT, 0)	/* MCAN1_TX.MCAN1_TX */
+		>;
+	};
+
+	main_uart3_pins_default: main-uart3-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x016c, PIN_INPUT, 10)	/* PRG0_PRU0_GPO3.UART3_CTSn */
+			AM64X_IOPAD(0x0170, PIN_OUTPUT, 10)	/* PRG0_PRU0_GPO4.UART3_TXD */
+			AM64X_IOPAD(0x0174, PIN_OUTPUT, 10)	/* PRG0_PRU0_GPO5.UART3_RTSn */
+			AM64X_IOPAD(0x01ac, PIN_INPUT, 10)	/* PRG0_PRU0_GPO19.UART3_RXD */
+		>;
+	};
+
+	pcie0_pins_default: pcie0-pins-default {
+		pinctrl-single,pins = <
+			/* connector M2 RESET */
+			AM64X_IOPAD(0x0030, PIN_OUTPUT, 7)	/* OSPI0_CSn1.GPIO0_12 */
+			/* connectors M1 & M2 W_DISABLE1 */
+			AM64X_IOPAD(0x0084, PIN_OUTPUT, 7)	/* GPMC0_ADVN_ALE.GPIO0_32 */
+			/* connectors M1 & M2 W_DISABLE2 */
+			AM64X_IOPAD(0x008c, PIN_OUTPUT, 7)	/* GPMC0_WEN.GPIO0_34 */
+			/* connectors M1 & M2 PERST0 (PCI Reset) */
+			AM64X_IOPAD(0x019c, PIN_OUTPUT, 7)	/* PRG0_PRU0_GPO15.GPIO1_15 */
+			/* connector M1 CLKREQ0 */
+			AM64X_IOPAD(0x018c, PIN_INPUT, 7)	/* PRG0_PRU0_GPO11.GPIO1_11 */
+			/* connector M2 CLKREQ0 */
+			AM64X_IOPAD(0x01ec, PIN_INPUT, 7)	/* PRG0_PRU1_GPO15.GPIO1_35 */
+		>;
+	};
+
+	regulator_pcie_3v3_pins_default: regulator-pcie-3v3-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01a4, PIN_OUTPUT, 7)	/* PRG0_PRU0_GPO17.GPIO1_17 */
+		>;
+	};
+
+	regulator_vpp_1v8_pins_default: regulator-vpp-1v8-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x029c, PIN_OUTPUT, 7)	/* MMC1_SDWP.GPIO1_78 */
+		>;
+	};
+
+	rtc_int_pins_default: rtc-int-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-up on Carrier */
+			AM64X_IOPAD(0x00b4, PIN_INPUT, 7)	/* GPMC0_CSn3.GPIO0_44 */
+		>;
+	};
+
+	serdes_mux_pins_default: serdes-mux-pins-default {
+		pinctrl-single,pins = <
+			/* SEL, 10k pull-down on carrier, 2.2k pullup on SoM */
+			AM64X_IOPAD(0x0200, PIN_OUTPUT, 7)	/* PRG0_MDIO0_MDIO.GPIO1_40 */
+			/* EN */
+			AM64X_IOPAD(0x0204, PIN_OUTPUT, 7)	/* PRG0_MDIO0_MDC.GPIO1_41 */
+		>;
+	};
+};
+
+&main_uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart3_pins_default>;
+	uart-has-rtscts;
+	rs485-rts-active-low;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+&usb0 {
+	dr_mode = "host";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
new file mode 100644
index 000000000000..83b73d433508
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
@@ -0,0 +1,592 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ */
+
+#include <dt-bindings/net/ti-dp83869.h>
+
+/ {
+	model = "SolidRun AM642 SoM";
+	compatible = "solidrun,am642-sr-som", "ti,am642";
+
+	aliases {
+		ethernet0 = &cpsw_port1;
+		ethernet1 = &icssg1_emac0;
+		ethernet2 = &icssg1_emac1;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		serial2 = &main_uart0;
+	};
+
+	chosen {
+		/* SoC default UART console */
+		stdout-path = "serial2:115200n8";
+	};
+
+	/* PRU Ethernet Controller */
+	ethernet {
+		compatible = "ti,am642-icssg-prueth";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pru_rgmii1_pins_default>, <&pru_rgmii2_pins_default>;
+
+		sram = <&oc_sram>;
+		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
+		firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
+
+		/* configure internal pinmux for mii mode */
+		ti,pruss-gp-mux-sel = <2>, <2>, <2>, <2>, <2>, <2>;
+
+		ti,mii-g-rt = <&icssg1_mii_g_rt>;
+		ti,mii-rt = <&icssg1_mii_rt>;
+		ti,iep = <&icssg1_iep0>, <&icssg1_iep1>;
+
+		/*
+		 * Configure icssg interrupt controller to map pru-internal
+		 * interrupts 8/9 via channels 0/1 to host interrupts 0/1.
+		 *
+		 * For details see interrupt controller documentation:
+		 * Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
+		 */
+		interrupt-parent = <&icssg1_intc>;
+		interrupts = <24 0 2>, <25 1 3>;
+		interrupt-names = "tx_ts0", "tx_ts1";
+
+		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
+		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
+		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
+		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+			    "rx0", "rx1";
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			icssg1_emac0: port at 0 {
+				reg = <0>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4110>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				phy-handle = <&ethernet_phy2>;
+				phy-mode = "rgmii-id";
+			};
+
+			icssg1_emac1: port at 1 {
+				reg = <1>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4114>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				phy-handle = <&ethernet_phy1>;
+				phy-mode = "rgmii-id";
+			};
+		};
+	};
+
+	/* DDR16SS0:
+	 * - Bank 1 @ 0x080000000-0x0FFFFFFFF: max. 2GB in 32-bit address space
+	 * - Bank 2 @ 0x880000000-0x9FFFFFFFF: max. 6GB in 64-bit address space
+	 */
+	memory at 80000000 {
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+		      <0x00000008 0x80000000 0x00000001 0x80000000>;
+		device_type = "memory";
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		secure_ddr: optee at 9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+			no-map;
+		};
+
+		main_r5fss0_core0_dma_memory_region: r5f-dma-memory at a0000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_memory_region: r5f-memory at a0100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_dma_memory_region: r5f-dma-memory at a1000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_memory_region: r5f-memory at a1100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_dma_memory_region: r5f-dma-memory at a2000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_memory_region: r5f-memory at a2100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_dma_memory_region: r5f-dma-memory at a3000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_memory_region: r5f-memory at a3100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3100000 0x00 0xf00000>;
+			no-map;
+		};
+	};
+
+	vdd_mmc0: regulator-vdd-mmc0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd-mmc0";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&cpsw3g {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins_default>;
+};
+
+&cpsw3g_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio0_pins_default>;
+	status = "okay";
+
+	ethernet_phy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy0_pins_default>;
+		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 84 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+};
+
+&cpsw_port1 {
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy0>;
+};
+
+&cpsw_port2 {
+	status = "disabled";
+};
+
+&icssg1_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pru1_mdio0_pins_default>;
+	status = "okay";
+
+	ethernet_phy1: ethernet-phy at 3 {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy1_pins_default>;
+		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 20 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+
+	ethernet_phy2: ethernet-phy at f {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <0xf>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy2_pins_default>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 52 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+};
+
+&mailbox0_cluster2 {
+	status = "okay";
+
+	mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+
+	mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+		ti,mbox-rx = <2 0 2>;
+		ti,mbox-tx = <3 0 2>;
+	};
+};
+
+&mailbox0_cluster4 {
+	status = "okay";
+
+	mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+
+	mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+		ti,mbox-rx = <2 0 2>;
+		ti,mbox-tx = <3 0 2>;
+	};
+};
+
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	status = "okay";
+
+	som_eeprom: eeprom at 50 {
+		compatible = "atmel,24c01";
+		reg = <0x50>;
+		pagesize = <8>;
+	};
+};
+
+&main_pmx0 {
+	/* hog global functions */
+	pinctrl-names = "default";
+	pinctrl-0 = <&ethernet_phy_pins_default>;
+
+	ethernet_phy_pins_default: ethernet-phy-pins-default {
+		pinctrl-single,pins = <
+			/* interrupt / power-down, external pull-up on SoM */
+			AM64X_IOPAD(0x0278, PIN_INPUT, 7)	/* EXTINTn.GPIO1_70 */
+		>;
+	};
+
+	ethernet_phy0_pins_default: ethernet-phy0-pins-default {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x0154, PIN_OUTPUT, 7)	/* PRG1_PRU1_GPO19.GPIO0_84 */
+			/* reference clock */
+			AM64X_IOPAD(0x0274, PIN_OUTPUT, 5)	/* EXT_REFCLK1.CLKOUT0 */
+		>;
+	};
+
+	ethernet_phy1_pins_default: ethernet-phy1-pins-default {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x0150, PIN_OUTPUT, 7)	/* PRG1_PRU1_GPO18.GPIO0_20 */
+			/* led0, external pull-down on SoM */
+			AM64X_IOPAD(0x0128, PIN_INPUT, 7)	/* PRG1_PRU1_GPO8.GPIO0_73 */
+			/* led1/rxer */
+			AM64X_IOPAD(0x011c, PIN_INPUT, 7)	/* PRG1_PRU1_GPO5.GPIO0_70 */
+		>;
+	};
+
+	ethernet_phy2_pins_default: ethernet-phy2-pins-default {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x00d4, PIN_OUTPUT, 7)	/* PRG1_PRU0_GPO7.GPIO0_52 */
+			/* led0, external pull-down on SoM */
+			AM64X_IOPAD(0x00d8, PIN_INPUT, 7)	/* PRG1_PRU0_GPO8.GPIO0_53 */
+			/* led1/rxer */
+			AM64X_IOPAD(0x00cc, PIN_INPUT, 7)	/* PRG1_PRU0_GPO5.GPIO0_50 */
+		>;
+	};
+
+	main_i2c0_pins_default: main-i2c0-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x0260, PIN_INPUT, 0)	/* I2C0_SCL.I2C0_SCL */
+			AM64X_IOPAD(0x0264, PIN_INPUT, 0)	/* I2C0_SDA.I2C0_SDA */
+		>;
+	};
+
+	/*
+	 * main_mmc0_pins_default: main-mmc0-pins-default
+	 *
+	 * MMC0_CMD: no padconfig
+	 * MMC0_CLK: no padconfig, external pull-up on SoM
+	 * MMC0_DAT0: no padconfig
+	 * MMC0_DAT1: no padconfig
+	 * MMC0_DAT2: no padconfig
+	 * MMC0_DAT3: no padconfig
+	 * MMC0_DAT4: no padconfig
+	 * MMC0_DAT5: no padconfig
+	 * MMC0_DAT6: no padconfig
+	 * MMC0_DAT7: no padconfig
+	 * MMC0_DS: no padconfig, external pull-down on SoM
+	 */
+
+	main_mmc1_pins_default: main-mmc1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0294, PIN_INPUT_PULLUP, 0)	/* (J19) MMC1_CMD */
+			AM64X_IOPAD(0x028c, PIN_INPUT, 0)		/* MMC1_CLK.MMC1_CLK */
+			AM64X_IOPAD(0x0288, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT0.MMC1_DAT0 */
+			AM64X_IOPAD(0x0284, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT1.MMC1_DAT1 */
+			AM64X_IOPAD(0x0280, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT2.MMC1_DAT2 */
+			AM64X_IOPAD(0x027c, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT3.MMC1_DAT3 */
+			/* external pull-down on SoM & Carrier */
+			AM64X_IOPAD(0x0298, PIN_INPUT_PULLUP, 0)	/* MMC1_SDCD.MMC1_SDCD */
+			AM64X_IOPAD(0x0290, PIN_INPUT, 0)		/* MMC1_CLKLB: clock loopback */
+		>;
+	};
+
+	main_uart0_pins_default: main-uart0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0230, PIN_INPUT, 0)		/* UART0_RXD.UART0_RXD */
+			AM64X_IOPAD(0x0234, PIN_OUTPUT, 0)		/* UART0_TXD.UART0_TXD */
+		>;
+	};
+
+	mdio0_pins_default: mdio0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01fc, PIN_OUTPUT, 4)		/* PRG0_PRU1_GPO19.MDIO0_MDC */
+			AM64X_IOPAD(0x01f8, PIN_INPUT, 4)		/* PRG0_PRU1_GPO18.MDIO0_MDIO */
+		>;
+	};
+
+	ospi0_pins_default: ospi0-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-down on SoM */
+			AM64X_IOPAD(0x0000, PIN_OUTPUT, 0)		/* OSPI0_CLK.OSPI0_CLK */
+			AM64X_IOPAD(0x0008, PIN_OUTPUT, 0)		/* OSPI0_DQS.OSPI0_DQS */
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x002c, PIN_OUTPUT, 0)		/* OSPI0_CSn0.OSPI0_CSn0 */
+			AM64X_IOPAD(0x000c, PIN_INPUT, 0)		/* OSPI0_D0.OSPI0_D0 */
+			AM64X_IOPAD(0x0010, PIN_INPUT, 0)		/* OSPI0_D1.OSPI0_D1 */
+			AM64X_IOPAD(0x0014, PIN_INPUT, 0)		/* OSPI0_D2.OSPI0_D2 */
+			AM64X_IOPAD(0x0018, PIN_INPUT, 0)		/* OSPI0_D3.OSPI0_D3 */
+			AM64X_IOPAD(0x001c, PIN_INPUT, 0)		/* OSPI0_D4.OSPI0_D4 */
+			AM64X_IOPAD(0x0020, PIN_INPUT, 0)		/* OSPI0_D5.OSPI0_D5 */
+			AM64X_IOPAD(0x0024, PIN_INPUT, 0)		/* OSPI0_D6.OSPI0_D6 */
+			AM64X_IOPAD(0x0028, PIN_INPUT, 0)		/* OSPI0_D7.OSPI0_D7 */
+		>;
+	};
+
+	ospi0_flash0_pins_default: ospi0-flash0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0034, PIN_OUTPUT, 7)		/* OSPI0_CSn2.GPIO0_13 */
+			AM64X_IOPAD(0x0038, PIN_INPUT, 7)		/* OSPI0_CSn3.GPIO0_14 */
+		>;
+	};
+
+	pru1_mdio0_pins_default: pru1-mdio0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0)		/* PRG1_MDIO0_MDC.PRG1_MDIO0_MDC */
+			AM64X_IOPAD(0x0158, PIN_INPUT, 0)		/* PRG1_MDIO0_MDIO.PRG1_MDIO0_MDIO */
+		>;
+	};
+
+	pru_rgmii1_pins_default: pru-rgmii1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x00b8, PIN_INPUT, 2)		/* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
+			AM64X_IOPAD(0x00bc, PIN_INPUT, 2)		/* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
+			AM64X_IOPAD(0x00c0, PIN_INPUT, 2)		/* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
+			AM64X_IOPAD(0x00c4, PIN_INPUT, 2)		/* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
+			AM64X_IOPAD(0x00d0, PIN_INPUT, 2)		/* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
+			AM64X_IOPAD(0x00c8, PIN_INPUT, 2)		/* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
+			AM64X_IOPAD(0x00e4, PIN_OUTPUT, 2)		/* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
+			AM64X_IOPAD(0x00e8, PIN_OUTPUT, 2)		/* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
+			AM64X_IOPAD(0x00ec, PIN_OUTPUT, 2)		/* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
+			AM64X_IOPAD(0x00f0, PIN_OUTPUT, 2)		/* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
+			AM64X_IOPAD(0x00f8, PIN_INPUT, 2)		/* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
+			AM64X_IOPAD(0x00f4, PIN_OUTPUT, 2)		/* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
+		>;
+	};
+
+	pru_rgmii2_pins_default: pru-rgmii2-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0108, PIN_INPUT, 2)		/* PRG1_PRU1_GPO0.RGMII2_RD0 */
+			AM64X_IOPAD(0x010c, PIN_INPUT, 2)		/* PRG1_PRU1_GPO1.RGMII2_RD1 */
+			AM64X_IOPAD(0x0110, PIN_INPUT, 2)		/* PRG1_PRU1_GPO2.RGMII2_RD2 */
+			AM64X_IOPAD(0x0114, PIN_INPUT, 2)		/* PRG1_PRU1_GPO3.RGMII2_RD3 */
+			AM64X_IOPAD(0x0120, PIN_INPUT, 2)		/* PRG1_PRU1_GPO6.RGMII2_RXC */
+			AM64X_IOPAD(0x0118, PIN_INPUT, 2)		/* PRG1_PRU1_GPO4.RGMII2_RX_CTL */
+			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO11.RGMII2_TD0 */
+			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO12.RGMII2_TD1 */
+			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO13.RGMII2_TD2 */
+			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO14.RGMII2_TD3 */
+			AM64X_IOPAD(0x0148, PIN_INPUT, 2)		/* PRG1_PRU1_GPO16.RGMII2_TXC */
+			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO15.RGMII2_TX_CTL */
+		>;
+	};
+
+	rgmii1_pins_default: rgmii1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01cc, PIN_INPUT, 4)		/* PRG0_PRU1_GPO7.RGMII1_RD0 */
+			AM64X_IOPAD(0x01d4, PIN_INPUT, 4)		/* PRG0_PRU1_GPO9.RGMII1_RD1 */
+			AM64X_IOPAD(0x01d8, PIN_INPUT, 4)		/* PRG0_PRU1_GPO10.RGMII1_RD2 */
+			AM64X_IOPAD(0x01f4, PIN_INPUT, 4)		/* PRG0_PRU1_GPO17.RGMII1_RD3 */
+			AM64X_IOPAD(0x0188, PIN_INPUT, 4)		/* PRG0_PRU0_GPO10.RGMII1_RXC */
+			AM64X_IOPAD(0x0184, PIN_INPUT, 4)		/* PRG0_PRU0_GPO9.RGMII1_RX_CTL */
+			AM64X_IOPAD(0x0124, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO7.RGMII1_TD0 */
+			AM64X_IOPAD(0x012c, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO9.RGMII1_TD1 */
+			AM64X_IOPAD(0x0130, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO10.RGMII1_TD2 */
+			AM64X_IOPAD(0x014c, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO17.RGMII1_TD3 */
+			AM64X_IOPAD(0x00e0, PIN_INPUT, 4)		/* PRG1_PRU0_GPO10.RGMII1_TXC */
+			AM64X_IOPAD(0x00dc, PIN_OUTPUT, 4)		/* PRG1_PRU0_GPO9.RGMII1_TX_CTL */
+		>;
+	};
+
+	usb0_pins_default: usb0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0)		/* USB0_DRVVBUS.USB0_DRVVBUS */
+		>;
+	};
+};
+
+&main_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core0>;
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0_core1 {
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core1>;
+	memory-region = <&main_r5fss0_core1_dma_memory_region>,
+			<&main_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss1_core0 {
+	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core0>;
+	memory-region = <&main_r5fss1_core0_dma_memory_region>,
+			<&main_r5fss1_core0_memory_region>;
+};
+
+&main_r5fss1_core1 {
+	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core1>;
+	memory-region = <&main_r5fss1_core1_dma_memory_region>,
+			<&main_r5fss1_core1_memory_region>;
+};
+
+/* SoC default UART console */
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_pins_default>;
+	status = "okay";
+};
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_pins_default>;
+	num-cs = <1>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ospi0_flash0_pins_default>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <200000000>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
+		cdns,read-delay = <0>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&main_gpio0 13 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&sdhci0 {
+	/* mmc0 pins have no padconfig */
+	bus-width = <8>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+	non-removable;
+	cap-mmc-hw-reset;
+	no-sd;
+	/*
+	 * MMC controller supports switching between 1.8V and 3.3V signalling.
+	 * However MMC0 (unlike MMC1) does not integrate an LDO.
+	 * Explicitly link a regulator node for indicating to the driver which
+	 * voltages are actually usable.
+	 */
+	vqmmc-supply = <&vdd_mmc0>;
+};
+
+/*
+ * microSD is on carrier - however since SoC can boot from it,
+ * configure it just in case.
+ */
+&sdhci1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_pins_default>;
+	bus-width = <4>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+};
+
+/*
+ * USB settings are a carrier choice - however since SoC can boot from it,
+ * configure as USB-2.0 OTG here, keeping USB-3 serdes disabled.
+ */
+&usb0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins_default>;
+	dr_mode = "otg";
+	maximum-speed = "high-speed";
+};
+
+&usbss0 {
+	ti,vbus-divider;
+	ti,usb2-only;
+};

-- 
2.35.3



From dianders at chromium.org  Fri Feb  2 08:24:17 2024
From: dianders at chromium.org (Doug Anderson)
Date: Fri, 2 Feb 2024 08:24:17 -0800
Subject: [PATCH] regset: use vmalloc() for regset_get_alloc()
In-Reply-To: <20240202040503.GX2087318@ZenIV>
References: <20240201171159.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924@changeid>
 <20240202012249.GU2087318@ZenIV> <CAD=FV=X5dpMyCGg4Xn+ApRwmiLB5zB0LTMCoSfW_X6eAsfQy8w@mail.gmail.com>
 <20240202030438.GV2087318@ZenIV> <CAD=FV=Wbq7R9AirvxnW1aWoEnp2fWQrwBsxsDB46xbfTLHCZ4w@mail.gmail.com>
 <20240202034925.GW2087318@ZenIV> <20240202040503.GX2087318@ZenIV>
Message-ID: <CAD=FV=X93KNMF4NwQY8uh-L=1J8PrDFQYu-cqSd+KnY5+Pq+_w@mail.gmail.com>

Hi,

On Thu, Feb 1, 2024 at 8:05?PM Al Viro <viro at zeniv.linux.org.uk> wrote:
>
> On Fri, Feb 02, 2024 at 03:49:25AM +0000, Al Viro wrote:
> > On Thu, Feb 01, 2024 at 07:15:48PM -0800, Doug Anderson wrote:
> > > >
> > > > Well, the next step would be to see which regset it is - if you
> > > > see that kind of allocation, print regset->n, regset->size and
> > > > regset->core_note_type.
> > >
> > > Of course! Here are the big ones:
> > >
> > > [   45.875574] DOUG: Allocating 279584 bytes, n=17474, size=16,
> > > core_note_type=1029
> >
> > 0x405, NT_ARM_SVE
> >         [REGSET_SVE] = { /* Scalable Vector Extension */
> >                 .core_note_type = NT_ARM_SVE,
> >                 .n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE),
> >                                   SVE_VQ_BYTES),
> >                 .size = SVE_VQ_BYTES,
> >
> > IDGI.  Wasn't SVE up to 32 * 2Kbit, i.e. 8Kbyte max?  Any ARM folks around?
> > Sure, I understand that it's variable-sized and we want to allocate enough
> > for the worst case, but can we really get about 280Kb there?  Context switches
> > would be really unpleasant on such boxen...
>
> FWIW, this apparently intends to be "variable, up to SVE_PT_SIZE(...) bytes";
> no idea if SVE_PT_SIZE is the right thing to use here.

+folks from `./scripts/get_maintainer.pl -f arch/arm64/kernel/ptrace.c`

Trying to follow the macros to see where "n" comes from is a maze of
twisty little passages, all alike. Hopefully someone from the ARM
world can help tell if the value of 17474 for n here is correct or if
something is wonky.


From joey.gouly at arm.com  Fri Feb  2 08:26:03 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Fri, 2 Feb 2024 16:26:03 +0000
Subject: [PATCH v2 04/25] KVM: arm64: nv: Add sanitising to EL2
 configuration registers
In-Reply-To: <86cyte7vh9.wl-maz@kernel.org>
References: <20240130204533.693853-1-maz@kernel.org>
 <20240130204533.693853-5-maz@kernel.org>
 <20240201145607.GH2284078@e124191.cambridge.arm.com>
 <86cyte7vh9.wl-maz@kernel.org>
Message-ID: <20240202162603.GA2636885@e124191.cambridge.arm.com>

On Fri, Feb 02, 2024 at 03:10:26PM +0000, Marc Zyngier wrote:
> On Thu, 01 Feb 2024 14:56:07 +0000,
> Joey Gouly <joey.gouly at arm.com> wrote:
> > 
> > On Tue, Jan 30, 2024 at 08:45:11PM +0000, Marc Zyngier wrote:
> > > We can now start making use of our sanitising masks by setting them
> > > to values that depend on the guest's configuration.
> > > 
> > > First up are VTTBR_EL2, VTCR_EL2, VMPIDR_EL2 and HCR_EL2.
> > > 
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > ---
> > >  arch/arm64/kvm/nested.c | 56 ++++++++++++++++++++++++++++++++++++++++-
> > >  1 file changed, 55 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> > > index c976cd4b8379..ee461e630527 100644
> > > --- a/arch/arm64/kvm/nested.c
> > > +++ b/arch/arm64/kvm/nested.c
> > > @@ -181,7 +181,7 @@ u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg sr)
> > >  	return v;
> > >  }
> > >  
> > > -static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
> > > +static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
> > >  {
> > >  	int i = sr - __VNCR_START__;
> > >  
> > > @@ -191,6 +191,7 @@ static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u
> > >  
> > >  int kvm_init_nv_sysregs(struct kvm *kvm)
> > >  {
> > > +	u64 res0, res1;
> > >  	int ret = 0;
> > >  
> > >  	mutex_lock(&kvm->arch.config_lock);
> > > @@ -209,6 +210,59 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
> > >  		kvm->arch.id_regs[i] = limit_nv_id_reg(IDX_IDREG(i),
> > >  						       kvm->arch.id_regs[i]);
> > >  
> > > +	/* VTTBR_EL2 */
> > > +	res0 = res1 = 0;
> > > +	if (!kvm_has_feat_enum(kvm, ID_AA64MMFR1_EL1, VMIDBits, 16))
> > > +		res0 |= GENMASK(63, 56);
> > > +	set_sysreg_masks(kvm, VTTBR_EL2, res0, res1);
> > > +
> > > +	/* VTCR_EL2 */
> > > +	res0 = GENMASK(63, 32) | GENMASK(30, 20);
> > > +	res1 = BIT(31);
> > > +	set_sysreg_masks(kvm, VTCR_EL2, res0, res1);
> > > +
> > > +	/* VMPIDR_EL2 */
> > > +	res0 = GENMASK(63, 40) | GENMASK(30, 24);
> > > +	res1 = BIT(31);
> > > +	set_sysreg_masks(kvm, VMPIDR_EL2, res0, res1);
> > > +
> > > +	/* HCR_EL2 */
> > > +	res0 = BIT(48);
> > > +	res1 = HCR_RW;
> > 
> > Just want to clarify this bit actually, this is restricting the (first level
> > only?) nested EL1 to run as AArch64?
> 
> This is restricting it at all levels. The guest hypervisor will
> eventually write its own view of HCR_EL2.RW in the VNCR page, and if
> it has promised AArch32 to its own guest (at any level), it is in for
> a treat, because we will forcefully reset this bit to 1.

Alright, thanks, I'll have to work through that some more.

> 
> > Should we be sanitising ID_AA64PFR0_EL1.EL1=0b0001?
> 
> We already do. See limit_nv_id_reg() and how it constraints
> ID_AA64PFR0_EL1.ELx to 0b0001.
> 

I forgot about that, was looking at read_sanitised_id_aa64pfr0_el1() in the non-
NV parts.

Thanks,
Joey


From robh at kernel.org  Fri Feb  2 08:30:06 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 10:30:06 -0600
Subject: [PATCH v2 1/7] arm64: Unconditionally call
 unflatten_device_tree()
In-Reply-To: <efe6a7886c3491cc9c225a903efa2b1e.sboyd@kernel.org>
References: <20240130004508.1700335-1-sboyd@kernel.org>
 <20240130004508.1700335-2-sboyd@kernel.org>
 <20240131205405.GA2249327-robh@kernel.org>
 <efe6a7886c3491cc9c225a903efa2b1e.sboyd@kernel.org>
Message-ID: <20240202163006.GA209874-robh@kernel.org>

On Wed, Jan 31, 2024 at 02:59:53PM -0800, Stephen Boyd wrote:
> Quoting Rob Herring (2024-01-31 12:54:05)
> > On Mon, Jan 29, 2024 at 04:45:00PM -0800, Stephen Boyd wrote:
> > > Call this function unconditionally so that we can populate an empty DTB
> > > on platforms that don't boot with a firmware provided or builtin DTB.
> > > Override 'initial_boot_params' to NULL when ACPI is in use but the
> > > bootloader has loaded a DTB so that we don't allow both ACPI and DT to
> > > be used during boot. If there isn't a valid initial_boot_params dtb then
> > > unflatten_device_tree() returns early so this is fine.
> > > 
> > > Cc: Rob Herring <robh+dt at kernel.org>
> > > Cc: Frank Rowand <frowand.list 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: <linux-arm-kernel at lists.infradead.org>
> > > Signed-off-by: Stephen Boyd <sboyd at kernel.org>
> > > ---
> > >  arch/arm64/kernel/setup.c | 7 +++++--
> > >  1 file changed, 5 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> > > index 417a8a86b2db..ffb1942724ae 100644
> > > --- a/arch/arm64/kernel/setup.c
> > > +++ b/arch/arm64/kernel/setup.c
> > > @@ -351,8 +351,11 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
> > >       /* Parse the ACPI tables for possible boot-time configuration */
> > >       acpi_boot_table_init();
> > >  
> > > -     if (acpi_disabled)
> > > -             unflatten_device_tree();
> > > +     /* Don't use the FDT from boot if ACPI is in use */
> > > +     if (!acpi_disabled)
> > > +             initial_boot_params = NULL;
> > 
> > I still think this is a problem for kexec. See 
> > of_kexec_alloc_and_setup_fdt(). You see it uses initial_boot_params. At 
> > first glance it looks like it would just write out everything we need. 
> > But for UEFI boot, I think we need all the chosen properties like 
> > linux,uefi-mmap-start preserved from the current boot for the next 
> > kernel we kexec.
> 
> Ok, got it.
> 
> > 
> > I think you'll have to check acpi_disabled in unflatten_device_tree() 
> > and unflatten the empty tree leaving initial_boot_params alone. That 
> > means our FDT and unflattened tree will be different DTs, but I think 
> > that's fine.
> 
> It's sort of scary given that 'initial_boot_params' is an exported
> global. Maybe that should be hidden away and accessed with a function
> instead so that this mismatch doesn't break something later on?

What you see now is after I did a pass of minimizing the number of 
users.

BTW, I've now got another use for unconditionally calling 
unflatten_device_tree() with this[1].

Rob

[1] https://lore.kernel.org/all/20240201194653.GA1328565-robh at kernel.org/


From ardb at kernel.org  Fri Feb  2 08:32:33 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 2 Feb 2024 17:32:33 +0100
Subject: [PATCH] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <Zb0Qu5lR0iZUqImb@e133380.arm.com>
References: <20240201223545.728028-1-maskray@google.com> <Zb0Qu5lR0iZUqImb@e133380.arm.com>
Message-ID: <CAMj1kXGSQ4Xq68Cmq6BH37FPJ+R+N5cOfrdC+aVML4sGaNDopg@mail.gmail.com>

On Fri, 2 Feb 2024 at 16:56, Dave Martin <Dave.Martin at arm.com> wrote:
>
> On Thu, Feb 01, 2024 at 02:35:45PM -0800, Fangrui Song wrote:
> > The generic constraint "i" seems to be copied from x86 or arm (and with
> > a redundant generic operand modifier "c"). It works with -fno-PIE but
> > not with -fPIE/-fPIC in GCC's aarch64 port.
> >
> > The machine constraint "S", which denotes a symbol or label reference
> > with a constant offset, supports PIC and has been available in GCC since
> > 2012 and in Clang since 7.0. However, Clang before 19 does not support
> > "S" on a symbol with a constant offset [1] (e.g.
> > `static_key_false(&nf_hooks_needed[pf][hook])` in
> > include/linux/netfilter.h), so we use "i" as a fallback.
> >
> > Suggested-by: Ard Biesheuvel <ardb at kernel.org>
> > Signed-off-by: Fangrui Song <maskray at google.com>
> > Link: https://github.com/llvm/llvm-project/pull/80255 [1]
> >
> > ---
> > Changes from
> > arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
> >
> > * Use "Si" as Ard suggested to support Clang<19
> > * Make branch a separate operand
> > ---
> >  arch/arm64/include/asm/jump_label.h | 12 ++++++++----
> >  1 file changed, 8 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> > index 48ddc0f45d22..1f7d529be608 100644
> > --- a/arch/arm64/include/asm/jump_label.h
> > +++ b/arch/arm64/include/asm/jump_label.h
> > @@ -15,6 +15,10 @@
> >
> >  #define JUMP_LABEL_NOP_SIZE          AARCH64_INSN_SIZE
> >
> > +/*
> > + * Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
> > + * support "S" on a symbol with a constant offset, so we use "i" as a fallback.
> > + */
> >  static __always_inline bool arch_static_branch(struct static_key * const key,
> >                                              const bool branch)
> >  {
> > @@ -23,9 +27,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
> >                "      .pushsection    __jump_table, \"aw\"    \n\t"
> >                "      .align          3                       \n\t"
> >                "      .long           1b - ., %l[l_yes] - .   \n\t"
> > -              "      .quad           %c0 - .                 \n\t"
> > +              "      .quad           %0 + %1 - .             \n\t"
> >                "      .popsection                             \n\t"
> > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> > +              :  :  "Si"(key), "i"(branch) :  : l_yes);
>
> Is the meaning of multi-alternatives well defined if different arguments
> specify different numbers of alternatives?  The GCC documentation says:
>
> https://gcc.gnu.org/onlinedocs/gcc/Multi-Alternative.html:
>
> -8<-
>
> [...] All operands for a single instruction must have the same number of
> alternatives.
>
> ->8-
>

AIUI that does not apply here. That reasons about multiple arguments
having more than one constraint, where not all combinations of those
constraints are supported by the instruction.

> Also, I still think it may be redundant to move the addition inside the
> asm, so long as Clang is happy with the symbol having an offset.
>

Older Clang is not happy with the symbol having an offset.

And given that the key pointer and the 'branch' boolean are two
distinct inputs to this function, I struggle to understand why you
feel it is better to combine them in the argument. 'branch' is used to
decide whether or not to set bit 0, independently of the value of key.
Using array indexing to combine those values together to avoid an
addition in the asm obfuscates the code.


> I.e., leave the .quad the same and revert to the one-liner
>
> -                :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> +                :  :  "Si"(&((char *)key)[branch]) :  : l_yes);
>
> This remains a bit nasty, but splitting the arguments and adding them
> inside the asm is not really any cleaner.  Changing the way this works
> doesn't seem relevant to what this patch is fixing (and apologies if I
> created confusion here...)
>
> >
> >       return false;
> >  l_yes:
> > @@ -40,9 +44,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
> >                "      .pushsection    __jump_table, \"aw\"    \n\t"
> >                "      .align          3                       \n\t"
> >                "      .long           1b - ., %l[l_yes] - .   \n\t"
> > -              "      .quad           %c0 - .                 \n\t"
> > +              "      .quad           %0 + %1 - .             \n\t"
> >                "      .popsection                             \n\t"
> > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> > +              :  :  "Si"(key), "i"(branch) :  : l_yes);
>
> Ditto.
>
> [...]
>
> Cheers
> ---Dave


From daniel at makrotopia.org  Fri Feb  2 08:33:16 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Fri, 2 Feb 2024 16:33:16 +0000
Subject: [PATCH 2/2] phy: add driver for MediaTek XFI T-PHY
In-Reply-To: <3e9afc4b-4ad6-412b-bc4d-f3e3b1475657@collabora.com>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
 <dd6b40ea1f7f8459a9a2cfe7fa60c1108332ade6.1706823233.git.daniel@makrotopia.org>
 <3e9afc4b-4ad6-412b-bc4d-f3e3b1475657@collabora.com>
Message-ID: <Zb0ZTNnAa_x47En1@makrotopia.org>

Hi Angelo,

thank you for promptly reviewing my submission and providing valuable
feedback!

On Fri, Feb 02, 2024 at 02:21:48PM +0100, AngeloGioacchino Del Regno wrote:
> Il 01/02/24 22:53, Daniel Golle ha scritto:
> > Add driver for MediaTek's XFI T-PHY, 10 Gigabit/s Ethernet SerDes PHY
> > which can be found in the MT7988 SoC.
> > 
> > The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
> > PHY_INTERFACE_MODE_* corresponding to the supported modes:
> > 
> >   * USXGMII                 \
> >   * 10GBase-R                }- USXGMII PCS - XGDM  \
> >   * 5GBase-R                /                        \
> >                                                       }- Ethernet MAC
> >   * 2500Base-X              \                        /
> >   * 1000Base-X               }- LynxI PCS - GDM     /
> >   * Cisco SGMII (MAC side)  /
> > 
> > In order to work-around a performance issue present on the first of
> > two XFI T-PHYs present in MT7988, special tuning is applied which can be
> > selected by adding the 'mediatek,usxgmii-performance-errata' property to
> > the device tree node.
> > 
> > There is no documentation for most registers used for the
> > analog/tuning part, however, most of the registers have been partially
> > reverse-engineered from MediaTek's SDK implementation (an opaque
> > sequence of 32-bit register writes) and descriptions for all relevant
> > digital registers and bits such as resets and muxes have been supplied
> > by MediaTek.
> > 
> > Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> > ---
> >   MAINTAINERS                             |   1 +
> >   drivers/phy/mediatek/Kconfig            |  12 +
> >   drivers/phy/mediatek/Makefile           |   1 +
> >   drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 392 ++++++++++++++++++++++++
> >   4 files changed, 406 insertions(+)
> >   create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 52769631bdb1a..52e4192470bd9 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -13715,6 +13715,7 @@ L:	netdev at vger.kernel.org
> >   S:	Maintained
> >   F:	drivers/net/phy/mediatek-ge-soc.c
> >   F:	drivers/net/phy/mediatek-ge.c
> > +F:	drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> >   MEDIATEK I2C CONTROLLER DRIVER
> >   M:	Qii Wang <qii.wang at mediatek.com>
> > diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> > index 3125ecb5d119f..5161d130c7f8b 100644
> > --- a/drivers/phy/mediatek/Kconfig
> > +++ b/drivers/phy/mediatek/Kconfig
> > @@ -13,6 +13,18 @@ config PHY_MTK_PCIE
> >   	  callback for PCIe GEN3 port, it supports software efuse
> >   	  initialization.
> > +config PHY_MTK_XFI_TPHY
> > +	tristate "MediaTek XFI T-PHY Driver"
> > +	depends on ARCH_MEDIATEK || COMPILE_TEST
> > +	depends on OF && OF_ADDRESS
> > +	depends on HAS_IOMEM
> > +	select GENERIC_PHY
> > +	help
> > +	  Say 'Y' here to add support for MediaTek XFI T-PHY driver.
> > +	  The driver provides access to the Ethernet SerDes T-PHY supporting
> > +	  1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
> > +	  via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
> > +
> >   config PHY_MTK_TPHY
> >   	tristate "MediaTek T-PHY Driver"
> >   	depends on ARCH_MEDIATEK || COMPILE_TEST
> > diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> > index c9a50395533eb..fa7217178e7f4 100644
> > --- a/drivers/phy/mediatek/Makefile
> > +++ b/drivers/phy/mediatek/Makefile
> > @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
> >   obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
> >   obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
> >   obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
> > +obj-$(CONFIG_PHY_MTK_XFI_TPHY)		+= phy-mtk-xfi-tphy.o
> >   phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
> >   phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
> > diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> > new file mode 100644
> > index 0000000000000..d50e6320860e5
> > --- /dev/null
> > +++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> > @@ -0,0 +1,392 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/* MediaTek 10GE SerDes PHY driver
> 
> MediaTek 10GE SerDes XFI T-PHY driver ?

Ack. Will unify the name accross all files.

> 
> > + *
> > + * Copyright (c) 2024 Daniel Golle <daniel at makrotopia.org>
> > + *                    Bc-bocun Chen <bc-bocun.chen at mediatek.com>
> > + * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
> > + * Copyright (c) 2022 MediaTek Inc.
> > + * Author: Henry Yen <henry.yen at mediatek.com>
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/device.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/of.h>
> > +#include <linux/io.h>
> > +#include <linux/clk.h>
> > +#include <linux/reset.h>
> > +#include <linux/phy.h>
> > +#include <linux/phy/phy.h>
> > +
> > +#define MTK_XFI_TPHY_NUM_CLOCKS		2
> > +
> > +#define REG_DIG_GLB_70			0x0070
> > +#define  XTP_PCS_RX_EQ_IN_PROGRESS(x)	FIELD_PREP(GENMASK(25, 24), (x))
> > +#define  XTP_PCS_MODE_MASK		GENMASK(17, 16)
> > +#define  XTP_PCS_MODE(x)		FIELD_PREP(GENMASK(17, 16), (x))
> > +#define  XTP_PCS_RST_B			BIT(15)
> > +#define  XTP_FRC_PCS_RST_B		BIT(14)
> > +#define  XTP_PCS_PWD_SYNC_MASK		GENMASK(13, 12)
> > +#define  XTP_PCS_PWD_SYNC(x)		FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
> > +#define  XTP_PCS_PWD_ASYNC_MASK		GENMASK(11, 10)
> > +#define  XTP_PCS_PWD_ASYNC(x)		FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
> > +#define  XTP_FRC_PCS_PWD_ASYNC		BIT(8)
> > +#define  XTP_PCS_UPDT			BIT(4)
> > +#define  XTP_PCS_IN_FR_RG		BIT(0)
> > +
> > +#define REG_DIG_GLB_F4			0x00f4
> > +#define  XFI_DPHY_PCS_SEL		BIT(0)
> > +#define   XFI_DPHY_PCS_SEL_SGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 1)
> > +#define   XFI_DPHY_PCS_SEL_USXGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 0)
> > +#define  XFI_DPHY_AD_SGDT_FRC_EN	BIT(5)
> > +
> > +#define REG_DIG_LN_TRX_40		0x3040
> > +#define  XTP_LN_FRC_TX_DATA_EN		BIT(29)
> > +#define  XTP_LN_TX_DATA_EN		BIT(28)
> > +
> > +#define REG_DIG_LN_TRX_B0		0x30b0
> > +#define  XTP_LN_FRC_TX_MACCK_EN		BIT(5)
> > +#define  XTP_LN_TX_MACCK_EN		BIT(4)
> > +
> > +#define REG_ANA_GLB_D0			0x90d0
> > +#define  XTP_GLB_USXGMII_SEL_MASK	GENMASK(3, 1)
> > +#define  XTP_GLB_USXGMII_SEL(x)		FIELD_PREP(GENMASK(3, 1), (x))
> > +#define  XTP_GLB_USXGMII_EN		BIT(0)
> > +
> > +struct mtk_xfi_tphy {
> > +	void __iomem		*base;
> > +	struct device		*dev;
> > +	struct reset_control	*reset;
> > +	struct clk_bulk_data	clocks[MTK_XFI_TPHY_NUM_CLOCKS];
> > +	bool			da_war;
> > +};
> > +
> > +static void mtk_xfi_tphy_write(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
> > +			       u32 value)
> > +{
> > +	iowrite32(value, xfi_tphy->base + reg);
> > +}
> > +
> > +static void mtk_xfi_tphy_rmw(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
> > +			     u32 clr, u32 set)
> > +{
> > +	u32 val;
> > +
> > +	val = ioread32(xfi_tphy->base + reg);
> > +	val &= ~clr;
> > +	val |= set;
> > +	iowrite32(val, xfi_tphy->base + reg);
> > +}
> > +
> > +static void mtk_xfi_tphy_set(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
> > +			     u32 set)
> > +{
> > +	mtk_xfi_tphy_rmw(xfi_tphy, reg, 0, set);
> > +}
> > +
> > +static void mtk_xfi_tphy_clear(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
> > +			       u32 clr)
> > +{
> > +	mtk_xfi_tphy_rmw(xfi_tphy, reg, clr, 0);
> > +}
> > +
> > +static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
> > +			       phy_interface_t interface)
> > +{
> > +	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
> > +	bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
> > +		      interface == PHY_INTERFACE_MODE_SGMII);
> > +	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
> > +		       interface == PHY_INTERFACE_MODE_USXGMII);
> > +	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
> > +	bool is_xgmii = (is_10g || is_5g);
> 
> is_usxgmii, I'd say.

This boolean is mostly used to destinguish which path to use at the
T-junction of the PHY, ie. up to 2500Base-X goes to LynxI PCS while
5GBase-R, 10GBase-R and USXGMII go to USXGMII PCS (which handles all
three modes and not just USXGMII).

Calling the boolean 'is_usxgmii' is a bit confusing as it not only
means (interface == interface == PHY_INTERFACE_MODE_USXGMII) but
rather also covers (interface == PHY_INTERFACE_MODE_10GBASER) as well
as (interface == PHY_INTERFACE_MODE_5GBASER) which are not USXGMII.

Maybe we invert it and call it 'use_lynxi_pcs' instead?

> 
> > +
> > +	dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));
> > +
> > +	/* Setup PLL setting */
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2030, 0x500, is_1g ? 0x0 : 0x500);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2040, 0x340000, is_1g ? 0x200000 :
> > +							     0x140000);
> > +
> > +	/* Setup RXFE BW setting */
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50f0, 0xc10, is_1g ? 0x410 :
> > +							  is_5g ? 0x800 : 0x400);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
> > +
> > +	/* Setup RX CDR setting */
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5078, 0xf000400, is_5g ? 0x8000000 :
> > +							      0x7000400);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x507c, 0x5000500, is_5g ? 0x4000400 :
> > +							      0x1000100);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5080, 0x1410, is_1g ? 0x400 :
> > +							   is_5g ? 0x1010 : 0x0);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5084, 0x30300, is_1g ? 0x30300 :
> > +							    is_5g ? 0x30100 :
> > +								    0x100);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5088, 0x60200, is_1g ? 0x20200 :
> > +							 is_5g ? 0x40000 :
> > +								 0x20000);
> > +
> > +	/* Setting RXFE adaptation range setting */
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50a8, 0xee0000, is_5g ? 0x800000 :
> > +							     0x6e0000);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);
> > +	if (is_10g)
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x01423342);
> > +	else if (is_5g)
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00a132a1);
> > +	else if (is_2p5g)
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x009c329c);
> > +	else
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00fa32fa);
> > +
> > +	/* Force SGDT_OUT off and select PCS */
> > +	mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_F4,
> > +			 XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
> > +			 XFI_DPHY_AD_SGDT_FRC_EN |
> > +			 (is_xgmii ? XFI_DPHY_PCS_SEL_USXGMII :
> > +				     XFI_DPHY_PCS_SEL_SGMII));
> > +
> > +
> > +	/* Force GLB_CKDET_OUT */
> > +	mtk_xfi_tphy_set(xfi_tphy, 0x0030, 0xc00);
> > +
> > +	/* Force AEQ on */
> > +	mtk_xfi_tphy_write(xfi_tphy, REG_DIG_GLB_70,
> > +			   XTP_PCS_RX_EQ_IN_PROGRESS(2) |
> > +			   XTP_PCS_PWD_SYNC(2) |
> > +			   XTP_PCS_PWD_ASYNC(2));
> > +
> > +	usleep_range(1, 5);
> > +
> > +	/* Setup TX DA default value */
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x30b0, 0x30, 0x20);
> > +	mtk_xfi_tphy_write(xfi_tphy, 0x3028, 0x00008a01);
> > +	mtk_xfi_tphy_write(xfi_tphy, 0x302c, 0x0000a884);
> > +	mtk_xfi_tphy_write(xfi_tphy, 0x3024, 0x00083002);
> > +
> > +	/* Setup RG default value */
> > +	if (is_xgmii) {
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00022220);
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x5064, 0x0f020a01);
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x50b4, 0x06100600);
> > +		if (interface == PHY_INTERFACE_MODE_USXGMII)
> > +			mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
> > +		else
> > +			mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x47684100);
> > +	} else {
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00011110);
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
> > +	}
> > +
> > +	if (is_1g)
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x3064, 0x0000c000);
> > +
> > +	/* Setup RX EQ initial value */
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x3050, 0xa8000000,
> > +			 (interface != PHY_INTERFACE_MODE_10GBASER) ?
> > +			  0xa8000000 : 0x0);
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0x3054, 0xaa,
> > +			 (interface != PHY_INTERFACE_MODE_10GBASER) ?
> > +			  0xaa : 0x0);
> > +
> > +	if (is_xgmii)
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x00000f00);
> > +	else if (is_2p5g)
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x22000f00);
> > +	else
> > +		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x20200f00);
> > +
> > +	if (interface == PHY_INTERFACE_MODE_10GBASER && xfi_tphy->da_war)
> > +		mtk_xfi_tphy_rmw(xfi_tphy, 0xa008, 0x10000, 0x10000);
> > +
> > +	mtk_xfi_tphy_rmw(xfi_tphy, 0xa060, 0x50000, is_xgmii ? 0x40000 :
> > +							       0x50000);
> > +
> > +	/* Setup PHYA speed */
> > +	mtk_xfi_tphy_rmw(xfi_tphy, REG_ANA_GLB_D0,
> > +			 XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
> > +			 is_10g ?  XTP_GLB_USXGMII_SEL(0) :
> > +			 is_5g ?   XTP_GLB_USXGMII_SEL(1) :
> > +			 is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
> > +				   XTP_GLB_USXGMII_SEL(3));
> > +	mtk_xfi_tphy_set(xfi_tphy, REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
> > +
> > +	/* Release reset */
> > +	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_GLB_70,
> > +			 XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
> > +	usleep_range(150, 500);
> > +
> > +	/* Switch to P0 */
> > +	mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
> > +			 XTP_PCS_PWD_SYNC_MASK |
> > +			 XTP_PCS_PWD_ASYNC_MASK,
> > +			 XTP_FRC_PCS_PWD_ASYNC |
> > +			 XTP_PCS_UPDT | XTP_PCS_IN_FR_RG);
> > +	usleep_range(1, 5);
> > +
> > +	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
> > +	usleep_range(15, 50);
> > +
> > +	if (is_xgmii) {
> > +		/* Switch to Gen3 */
> > +		mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
> > +				 XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
> > +				 XTP_PCS_MODE(2) | XTP_PCS_UPDT);
> > +	} else {
> > +		/* Switch to Gen2 */
> > +		mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
> > +				 XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
> > +				 XTP_PCS_MODE(1) | XTP_PCS_UPDT);
> > +	}
> > +	usleep_range(1, 5);
> > +
> > +	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
> > +
> > +	usleep_range(100, 500);
> > +
> > +	/* Enable MAC CK */
> > +	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
> > +	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN);
> > +
> > +	/* Enable TX data */
> > +	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_40,
> > +			 XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
> > +	usleep_range(400, 1000);
> > +}
> > +
> > +static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int
> > +				 submode)
> > +{
> > +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> > +
> > +	if (mode != PHY_MODE_ETHERNET)
> > +		return -EINVAL;
> > +
> > +	switch (submode) {
> > +	case PHY_INTERFACE_MODE_1000BASEX:
> 
> fallthrough;

I don't think so. No other kernel drivers are doing that and also there
is no compiler warning what-so-ever when matching multiple cases in that
way.

> 
> > +	case PHY_INTERFACE_MODE_2500BASEX:
> 
> fallthrough;
> 
> > +	case PHY_INTERFACE_MODE_SGMII:
> 
> ... etc :-)
> 
> > +	case PHY_INTERFACE_MODE_5GBASER:
> > +	case PHY_INTERFACE_MODE_10GBASER:
> > +	case PHY_INTERFACE_MODE_USXGMII:
> 
> Does this PHY support PHY_INTERFACE_MODE_XGMII ?
> 
> > +		mtk_xfi_tphy_setup(xfi_tphy, submode);
> > +		return 0;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +}
> > +
> > +static int mtk_xfi_tphy_reset(struct phy *phy)
> > +{
> > +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> > +
> > +	reset_control_assert(xfi_tphy->reset);
> > +	usleep_range(100, 500);
> > +	reset_control_deassert(xfi_tphy->reset);
> > +	usleep_range(1, 10);
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_xfi_tphy_power_on(struct phy *phy)
> > +{
> > +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> > +
> > +	return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
> > +}
> > +
> > +static int mtk_xfi_tphy_power_off(struct phy *phy)
> > +{
> > +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> > +
> > +	clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct phy_ops mtk_xfi_tphy_ops = {
> > +	.power_on	= mtk_xfi_tphy_power_on,
> > +	.power_off	= mtk_xfi_tphy_power_off,
> > +	.set_mode	= mtk_xfi_tphy_set_mode,
> > +	.reset		= mtk_xfi_tphy_reset,
> > +	.owner		= THIS_MODULE,
> > +};
> > +
> > +static int mtk_xfi_tphy_probe(struct platform_device *pdev)
> > +{
> > +	struct device_node *np = pdev->dev.of_node;
> > +	struct phy_provider *phy_provider;
> > +	struct mtk_xfi_tphy *xfi_tphy;
> > +	struct phy *phy;
> > +
> > +	if (!np)
> > +		return -ENODEV;
> > +
> > +	xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
> > +	if (!xfi_tphy)
> > +		return -ENOMEM;
> > +
> > +	xfi_tphy->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
> 
> Why devm_of_iomap() and not devm_platform_ioremap_resource()?

True, I will make use of devm_platform_ioremap_resource().

> 
> > +	if (!xfi_tphy->base)
> > +		return -EIO;
> > +
> > +	xfi_tphy->dev = &pdev->dev;
> > +
> > +	xfi_tphy->clocks[0].id = "topxtal";
> 
> xfi_tphy->clocks[0].id = "topxtal";
> xfi_tphy->clocks[1].id = "xfipll";
> 
> ret = devm_clk_bulk_get(&pdev->dev, MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
> if (ret)
> 	return ret;
> 
> ...it's that simple :-P

Ok, thanks :)

> 
> > +	xfi_tphy->clocks[0].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[0].id);
> > +	if (IS_ERR(xfi_tphy->clocks[0].clk))
> > +		return PTR_ERR(xfi_tphy->clocks[0].clk);
> > +
> > +	xfi_tphy->clocks[1].id = "xfipll";
> > +	xfi_tphy->clocks[1].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[1].id);
> > +	if (IS_ERR(xfi_tphy->clocks[1].clk))
> > +		return PTR_ERR(xfi_tphy->clocks[1].clk);
> > +
> > +	xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> > +	if (IS_ERR(xfi_tphy->reset))
> > +		return PTR_ERR(xfi_tphy->reset);
> > +
> > +	xfi_tphy->da_war = of_property_read_bool(np,
> > +						 "mediatek,usxgmii-performance-errata");
> > +
> 
> One line please
> 
> > +	phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
> > +	if (IS_ERR(phy))
> > +		return PTR_ERR(phy);
> > +
> > +	phy_set_drvdata(phy, xfi_tphy);
> > +
> > +	phy_provider = devm_of_phy_provider_register(&pdev->dev,
> > +						     of_phy_simple_xlate);
> 
> ditto
> 
> > +
> > +	return PTR_ERR_OR_ZERO(phy_provider);
> > +}
> > +
> > +static const struct of_device_id mtk_xfi_tphy_match[] = {
> > +	{ .compatible = "mediatek,mt7988-xfi-tphy", },
> > +	{ }
> 
> 	{ .compatible = "mediatek,mt7988-xfi-tphy" },
> 	{ /* sentinel */ }

Ack.

> 
> > +};
> > +MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
> > +
> > +static struct platform_driver mtk_xfi_tphy_driver = {
> > +	.probe = mtk_xfi_tphy_probe,
> > +	.driver = {
> > +		.name = "mtk-xfi-tphy",
> > +		.of_match_table = mtk_xfi_tphy_match,
> > +	},
> > +};
> > +module_platform_driver(mtk_xfi_tphy_driver);
> > +
> > +MODULE_DESCRIPTION("MediaTek XFI T-PHY driver");
> 
> MODULE_DESCRIPTION("MediaTek 10GE SerDes XFI T-PHY driver");

Ack, will unify the name everywhere.

> 
> Cheers,
> Angelo
> 
> > +MODULE_AUTHOR("Daniel Golle <daniel at makrotopia.org>");
> > +MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen at mediatek.com>");
> > +MODULE_LICENSE("GPL");
> 
> 


From ville.syrjala at linux.intel.com  Fri Feb  2 08:35:06 2024
From: ville.syrjala at linux.intel.com (Ville =?iso-8859-1?Q?Syrj=E4l=E4?=)
Date: Fri, 2 Feb 2024 18:35:06 +0200
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB property
In-Reply-To: <c37e9225-3890-4f4d-b45c-919b907b184b@xs4all.nl>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <874jerf7ot.fsf@intel.com>
 <c37e9225-3890-4f4d-b45c-919b907b184b@xs4all.nl>
Message-ID: <Zb0ZujO9E_WH8Pm3@intel.com>

On Fri, Feb 02, 2024 at 12:20:21PM +0100, Hans Verkuil wrote:
> On 02/02/2024 12:04, Jani Nikula wrote:
> > On Mon, 15 Jan 2024, Sebastian Wick <sebastian.wick at redhat.com> wrote:
> >> On Thu, Dec 07, 2023 at 04:49:31PM +0100, Maxime Ripard wrote:
> >>> The i915 driver has a property to force the RGB range of an HDMI output.
> >>> The vc4 driver then implemented the same property with the same
> >>> semantics. KWin has support for it, and a PR for mutter is also there to
> >>> support it.
> >>>
> >>> Both drivers implementing the same property with the same semantics,
> >>> plus the userspace having support for it, is proof enough that it's
> >>> pretty much a de-facto standard now and we can provide helpers for it.
> >>>
> >>> Let's plumb it into the newly created HDMI connector.
> >>>
> >>> Signed-off-by: Maxime Ripard <mripard at kernel.org>
> > 
> > [snip]
> > 
> >>> @@ -1655,6 +1678,26 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
> >>>  /**
> >>>   * DOC: HDMI connector properties
> >>>   *
> >>> + * Broadcast RGB
> >>> + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> >>> + *      Infoframes will be generated according to that value.
> >>> + *
> >>> + *      The value of this property can be one of the following:
> >>> + *
> >>> + *      Automatic:
> >>> + *              RGB Range is selected automatically based on the mode
> >>> + *              according to the HDMI specifications.
> >>> + *
> >>> + *      Full:
> >>> + *              Full RGB Range is forced.
> >>> + *
> >>> + *      Limited 16:235:
> >>> + *              Limited RGB Range is forced. Unlike the name suggests,
> >>> + *              this works for any number of bits-per-component.
> >>> + *
> >>> + *      Drivers can set up this property by calling
> >>> + *      drm_connector_attach_broadcast_rgb_property().
> >>> + *
> >>
> >> This is a good time to document this in more detail. There might be two
> >> different things being affected:
> >>
> >> 1. The signalling (InfoFrame/SDP/...)
> >> 2. The color pipeline processing
> >>
> >> All values of Broadcast RGB always affect the color pipeline processing
> >> such that a full-range input to the CRTC is converted to either full- or
> >> limited-range, depending on what the monitor is supposed to accept.
> >>
> >> When automatic is selected, does that mean that there is no signalling,
> >> or that the signalling matches what the monitor is supposed to accept
> >> according to the spec? Also, is this really HDMI specific?
> > 
> > Automatic is based on the mode as described in the specs
> > below. Basically certain modes are expected to be broadcast range, and
> > others full range.
> > 
> > I don't remember why we don't use the full range if the display
> > indicates it supports selectable quantization range in Video
> > Capabilities Data Block. It's quite possible there are displays that
> > declare support but don't. Cc: Ville.
> 
> I have not seen such displays. Enabling RGB Selectable Quantization Range
> is something that a vendor has to do explicitly, so it is reasonable to
> expect that it works, otherwise there would be no point to that flag!
> 
> Transmitting full range if possible gives a better picture quality and
> so is recommended.
> 
> > 
> > - HDMI 1.4b section 6.6 Video Quantization Ranges
> > 
> > - HDMI 2.1 section 7.3 Video Quantization Ranges
> > 
> > - DP 2.1 (and earlier) section 5.1.1.1 Video Colorimetry
> > 
> > - CTA-861-H (and earlier) section 5.1 Default Encoding Parameters and
> >   section 6.4.3 Quantization Range
> 
> Note that CTA-861-H deprecated the use of Default Range in the AVI
> InfoFrame, instead the source should always signal limited or full range
> in the Q field.

Only because the QS=1 is now mandatory IIRC.
We do always set Q bit explicitly when QS==1.

But yeah, I guess we could always go for full range
by default when QS==1. Or maybe we even did that at
some point in the past and it broke some things?
Can't recall anymore.

Anyways, QS=1 being mandatory is a clear improvement
in CTA-861, but some other CTA-861 rule updates are
more or less pointless as you can't in general detect
which version of the spec the sink claims to implement.

Eg. we already had cases where following the new CTA-861-F
rules for the YQ bit when transmitting RGB broke some
displays. And we are now forced to use the presence of
HDMI 2.0+ capabilities as a heuristic to detect CTA-851-F+.
(see drm_hdmi_avi_infoframe_quant_range()). It's pretty
nasty.

And I think there is some other infoframe related issue
(something to do with VICs IIRC) where we'd need to derive
the CTA-861 version eg. from the set of advertised VICs
in the EDID. I might have even written some code for that
at some point but never finished it. So it's still
broken in the current code. Can't recall the specific
details right now unfortunately.

-- 
Ville Syrj?l?
Intel


From ville.syrjala at linux.intel.com  Fri Feb  2 08:37:52 2024
From: ville.syrjala at linux.intel.com (Ville =?iso-8859-1?Q?Syrj=E4l=E4?=)
Date: Fri, 2 Feb 2024 18:37:52 +0200
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB
 property
In-Reply-To: <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
Message-ID: <Zb0aYAapkxQ2kopt@intel.com>

On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > Hi,
> > > 
> > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > >  /**
> > > > > >   * DOC: HDMI connector properties
> > > > > >   *
> > > > > > + * Broadcast RGB
> > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > + *      Infoframes will be generated according to that value.
> > > > > > + *
> > > > > > + *      The value of this property can be one of the following:
> > > > > > + *
> > > > > > + *      Automatic:
> > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > + *              according to the HDMI specifications.
> > > > > > + *
> > > > > > + *      Full:
> > > > > > + *              Full RGB Range is forced.
> > > > > > + *
> > > > > > + *      Limited 16:235:
> > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > + *              this works for any number of bits-per-component.
> > > > > > + *
> > > > > > + *      Drivers can set up this property by calling
> > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > + *
> > > > > 
> > > > > This is a good time to document this in more detail. There might be two
> > > > > different things being affected:
> > > > > 
> > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > 2. The color pipeline processing
> > > > > 
> > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > 
> > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > according to the spec? Also, is this really HDMI specific?
> > > > > 
> > > > > When full or limited is selected and the monitor doesn't support the
> > > > > signalling, what happens?
> > > > 
> > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > YCbCr?
> > > 
> > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > we're using a YCbCr format, i915 will always use a limited range while
> > > vc4 will follow the value of the property.
> > 
> > The property is literally called "Broadcast *RGB*".
> > That should explain why it's only affecting RGB.
> 
> Right. And the limited range option is called "Limited 16:235" despite
> being usable on bpc > 8 bits. Naming errors occurs, and history happens
> to make names inconsistent too, that's fine and not an argument in
> itself.
> 
> > Full range YCbCr is a much rarer beast so we've never bothered
> > to enable it.
> 
> vc4 supports it.

Someone implemented it incorrectly then.

> 
> > Eg. with DP it only became possible with the introduction of the VSC
> > SDP (and I don't recall if there's additional capability checks that
> > are also required). With DP MSA signalling full range YCbCr is not
> > possible at all.
> 
> This is for HDMI only.
> 
> > I don't recall right now what the HDMI requirements are.
> 
> HDMI has supported it for a while, and it's defined (for example) in the
> HDMI 1.4 spec in Section 6.6 - Video Quantization Ranges. It supports
> limited and full range on both RGB and YCbCr, as long as the EDIDs state
> so and the Infoframes signal it.

I think a good reason for not using a simple boolean like this 
YCbCr is that it doesn't cover the color encoding part at all,
which is probably more important than the quantization range.
So we need a new property anyway.

-- 
Ville Syrj?l?
Intel


From conor at kernel.org  Fri Feb  2 08:39:16 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 2 Feb 2024 16:39:16 +0000
Subject: [PATCH v3 4/5] dt-bindings: usb/ti,am62-usb.yaml: Add PHY2
 register space
In-Reply-To: <dc3c93dc-74d9-4b1c-a771-3ee6f67b5dcc@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-5-rogerq@kernel.org>
 <20240201-viewpoint-upload-fb714f650ff5@spud>
 <20240201-violet-chalice-51a73f113e7b@spud>
 <20240201183522.ssj553rwefr2wuqi@iaqt7>
 <20240201-clad-unopposed-ccfdfe53b770@spud>
 <bc3ab60f-539b-41d0-8595-6e0b55f2763d@kernel.org>
 <20240202-unzip-whacky-bb2f151c618b@wendy>
 <dc3c93dc-74d9-4b1c-a771-3ee6f67b5dcc@kernel.org>
Message-ID: <20240202-hunchback-tapestry-16b1bcf16452@spud>

On Fri, Feb 02, 2024 at 12:13:22PM +0200, Roger Quadros wrote:
> 
> 
> On 02/02/2024 11:53, Conor Dooley wrote:
> > On Fri, Feb 02, 2024 at 11:36:55AM +0200, Roger Quadros wrote:
> >>
> >>
> >> On 01/02/2024 21:13, Conor Dooley wrote:
> >>> On Thu, Feb 01, 2024 at 12:35:22PM -0600, Bin Liu wrote:
> >>>> On Thu, Feb 01, 2024 at 06:18:05PM +0000, Conor Dooley wrote:
> >>>>> On Thu, Feb 01, 2024 at 06:15:20PM +0000, Conor Dooley wrote:
> >>>>>> On Thu, Feb 01, 2024 at 02:03:31PM +0200, Roger Quadros wrote:
> >>>>>>> So far this was not required but due to the newly identified
> >>>>>>> Errata i2409 [1] we need to poke this register space.
> >>>>>>>
> >>>>>>> [1] https://www.ti.com/lit/er/sprz487d/sprz487d.pdf
> >>>>>>>
> >>>>>>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> >>>>>>
> >>>>>> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> >>>>>
> >>>>> Actually, where is the user for this that actually pokes the register
> >>>>> space?
> >>
> >> https://lore.kernel.org/all/20240201121220.5523-5-rogerq at kernel.org/
> >>
> >>>>> You're adding another register region, so I went to check how you were
> >>>>> handling that in drivers, but there's no driver patch.
> >>>>
> >>>> See Roger's another patch set 'Add workaround for Errata i2409' posted
> >>>> on 16th.
> >>>
> >>> This patch should be with that series, not with these dts patches.
> >>>
> >>
> >> Why not? There should be no dependency between DTS and driver implementation.
> >>
> >> As DTS and driver will be merged by separate maintainers I thought it
> >> would be easier for maintainers this way.
> > 
> > dts and driver might be merged by different people, but dt-bindings and
> > drivers are merged by the same people. This is a bindings patch, not a
> 
> If we do that then I get a bunch of dtbs_check warnings
> 
> dwc3-usb at f900000: reg: [[0, 261095424, 0, 2048], [0, 261128192, 0, 1024]] is too long

I don't know what your platform maintainers view is, but to me it is fine
as long as linux-next is clean.
-------------- 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/20240202/7217cbf3/attachment.sig>

From broonie at kernel.org  Fri Feb  2 08:41:36 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 02 Feb 2024 16:41:36 +0000
Subject: [PATCH v4] regulator: dt-bindings: microchip,mcp16502: convert
 to YAML
In-Reply-To: <20240201161517.492162-1-andrei.simion@microchip.com>
References: <20240201161517.492162-1-andrei.simion@microchip.com>
Message-ID: <170689209683.101360.163113279723632505.b4-ty@kernel.org>

On Thu, 01 Feb 2024 18:15:17 +0200, Andrei Simion wrote:
> Convert devicetree binding mcp16502-regulator.txt to YAML format.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next

Thanks!

[1/1] regulator: dt-bindings: microchip,mcp16502: convert to YAML
      commit: 64db3e8d7be00462ad95dd81f11cf8e3f0968d70

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 a0501179 at ti.com  Fri Feb  2 08:43:45 2024
From: a0501179 at ti.com (Anwar, Md Danish)
Date: Fri, 2 Feb 2024 22:13:45 +0530
Subject: [PATCH v3 2/3] arm64: dts: ti: k3-am642-evm: add ICSSG1 Ethernet
 support
In-Reply-To: <156ae282-3052-45bd-be71-8220d04e73d1@kernel.org>
References: <20240122113045.1711818-1-danishanwar@ti.com>
 <20240122113045.1711818-3-danishanwar@ti.com>
 <156ae282-3052-45bd-be71-8220d04e73d1@kernel.org>
Message-ID: <58e2d55a-51cd-44ba-80b6-a6eaaf3ac85d@ti.com>

On 2/2/2024 5:17 PM, Roger Quadros wrote:
> 
> 
> On 22/01/2024 13:30, MD Danish Anwar wrote:
>> ICSSG1 provides dual Gigabit Ethernet support with proper FW loaded.
>>
>> The ICSSG1 MII0 (RGMII1) has DP83869 PHY attached to it. The ICSSG1 shares
>> MII1 (RGMII2) PHY DP83869 with CPSW3g and it's assigned by default to
>> CPSW3g. The MDIO access to MII1 (RGMII2) PHY DP83869 is controlled by MDIO
>> bus switch and also assigned to CPSW3g. Therefore the ICSSG1 MII1 (RGMII2)
>> port is kept disable and ICSSG1 is enabled in single MAC mode by
>> default.
>>
>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>> ---
>>  arch/arm64/boot/dts/ti/k3-am642-evm.dts | 102 ++++++++++++++++++++++++
>>  1 file changed, 102 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> index 8c5651d2cf5d..c08b0223be52 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> @@ -32,6 +32,8 @@ aliases {
>>  		mmc1 = &sdhci1;
>>  		ethernet0 = &cpsw_port1;
>>  		ethernet1 = &cpsw_port2;
>> +		ethernet2 = &icssg1_emac0;
>> +		ethernet3 = &icssg1_emac1;
> 
> If icssg1_emac1 is disabled by default there is no ethernet3 right?
> 

Yes. By default there isn't ethernet 3. I'll drop this alias from this
patch.

>>  	};
>>  
>>  	memory at 80000000 {
>> @@ -229,6 +231,70 @@ transceiver2: can-phy1 {
>>  		max-bitrate = <5000000>;
>>  		standby-gpios = <&exp1 9 GPIO_ACTIVE_HIGH>;
>>  	};
>> +
>> +	icssg1_eth: icssg1-eth {
>> +		compatible = "ti,am642-icssg-prueth";
>> +		pinctrl-names = "default";
>> +		pinctrl-0 = <&icssg1_rgmii1_pins_default>;
>> +
> please drop blank line.
> 
>> +		sram = <&oc_sram>;
>> +		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
>> +		firmware-name = "ti-pruss/am64x-sr2-pru0-prueth-fw.elf",
>> +				"ti-pruss/am64x-sr2-rtu0-prueth-fw.elf",
>> +				"ti-pruss/am64x-sr2-txpru0-prueth-fw.elf",
>> +				"ti-pruss/am64x-sr2-pru1-prueth-fw.elf",
>> +				"ti-pruss/am64x-sr2-rtu1-prueth-fw.elf",
>> +				"ti-pruss/am64x-sr2-txpru1-prueth-fw.elf";
>> +
>> +		ti,pruss-gp-mux-sel = <2>,	/* MII mode */
>> +				      <2>,
>> +				      <2>,
>> +				      <2>,	/* MII mode */
>> +				      <2>,
>> +				      <2>;
>> +
> 
> please drop blank line.
> 
>> +		ti,mii-g-rt = <&icssg1_mii_g_rt>;
>> +		ti,mii-rt = <&icssg1_mii_rt>;
>> +		ti,iep = <&icssg1_iep0>,  <&icssg1_iep1>;
>> +
> please drop blank line.
> 
>> +		interrupt-parent = <&icssg1_intc>;
>> +		interrupts = <24 0 2>, <25 1 3>;
>> +		interrupt-names = "tx_ts0", "tx_ts1";
>> +
> please drop blank line.
>

Will drop all the blank lines.


>> +		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
>> +		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
>> +		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
>> +		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
>> +		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
>> +		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
>> +		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
>> +		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
>> +		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
>> +		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
>> +		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
>> +			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
>> +			    "rx0", "rx1";
>> +
>> +		ethernet-ports {
>> +			#address-cells = <1>;
>> +			#size-cells = <0>;
>> +			icssg1_emac0: port at 0 {
>> +				reg = <0>;
>> +				phy-handle = <&icssg1_phy1>;
>> +				phy-mode = "rgmii-id";
>> +				ti,syscon-rgmii-delay = <&main_conf 0x4110>;
>> +				/* Filled in by bootloader */
>> +				local-mac-address = [00 00 00 00 00 00];
>> +			};
>> +			icssg1_emac1: port at 1 {
>> +				reg = <1>;
>> +				ti,syscon-rgmii-delay = <&main_conf 0x4114>;
>> +				/* Filled in by bootloader */
>> +				local-mac-address = [00 00 00 00 00 00];
>> +				status = "disabled";
>> +			};
>> +		};
>> +	};
>>  };
>>  
>>  &main_pmx0 {
>> @@ -383,6 +449,30 @@ ddr_vtt_pins_default: ddr-vtt-default-pins {
>>  			AM64X_IOPAD(0x0030, PIN_OUTPUT_PULLUP, 7) /* (L18) OSPI0_CSN1.GPIO0_12 */
>>  		>;
>>  	};
>> +
>> +	icssg1_mdio1_pins_default: icssg1-mdio1-default-pins {
>> +		pinctrl-single,pins = <
>> +			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0) /* (Y6) PRG1_MDIO0_MDC */
>> +			AM64X_IOPAD(0x0158, PIN_INPUT, 0) /* (AA6) PRG1_MDIO0_MDIO */
>> +		>;
>> +	};
>> +
>> +	icssg1_rgmii1_pins_default: icssg1-rgmii1-default-pins{
>> +		pinctrl-single,pins = <
>> +			AM64X_IOPAD(0x00b8, PIN_INPUT, 2) /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
>> +			AM64X_IOPAD(0x00bc, PIN_INPUT, 2) /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
>> +			AM64X_IOPAD(0x00c0, PIN_INPUT, 2) /* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
>> +			AM64X_IOPAD(0x00c4, PIN_INPUT, 2) /* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
>> +			AM64X_IOPAD(0x00d0, PIN_INPUT, 2) /* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
>> +			AM64X_IOPAD(0x00c8, PIN_INPUT, 2) /* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
>> +			AM64X_IOPAD(0x00e4, PIN_INPUT, 2) /* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
>> +			AM64X_IOPAD(0x00e8, PIN_INPUT, 2) /* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
>> +			AM64X_IOPAD(0x00ec, PIN_INPUT, 2) /* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
>> +			AM64X_IOPAD(0x00f0, PIN_INPUT, 2) /* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
>> +			AM64X_IOPAD(0x00f8, PIN_INPUT, 2) /* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
>> +			AM64X_IOPAD(0x00f4, PIN_INPUT, 2) /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
>> +		>;
>> +	};
>>  };
>>  
>>  &main_uart0 {
>> @@ -731,3 +821,15 @@ &main_mcan1 {
>>  	pinctrl-0 = <&main_mcan1_pins_default>;
>>  	phys = <&transceiver2>;
>>  };
>> +
>> +&icssg1_mdio {
>> +	status = "okay";
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&icssg1_mdio1_pins_default>;
>> +
>> +	icssg1_phy1: ethernet-phy at f {
>> +		reg = <0xf>;
>> +		tx-internal-delay-ps = <250>;
>> +		rx-internal-delay-ps = <2000>;
>> +	};
>> +};
> 

-- 
Thanks and Regards,
Md Danish Anwar


From Jonathan.Cameron at Huawei.com  Fri Feb  2 08:44:31 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Fri, 2 Feb 2024 16:44:31 +0000
Subject: [PATCH RFC v4 10/15] irqchip/gic-v3: Don't return errors from
 gic_acpi_match_gicc()
In-Reply-To: <E1rVDn9-0027ZB-QN@rmk-PC.armlinux.org.uk>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk>
	<E1rVDn9-0027ZB-QN@rmk-PC.armlinux.org.uk>
Message-ID: <20240202164431.00006f09@Huawei.com>

On Wed, 31 Jan 2024 16:50:27 +0000
Russell King (Oracle) <rmk+kernel at armlinux.org.uk> wrote:

> From: James Morse <james.morse at arm.com>
> 
> gic_acpi_match_gicc() is only called via gic_acpi_count_gicr_regions().
> It should only count the number of enabled redistributors, but it
> also tries to sanity check the GICC entry, currently returning an
> error if the Enabled bit is set, but the gicr_base_address is zero.
> 
> Adding support for the online-capable bit to the sanity check will
> complicate it, for no benefit. The existing check implicitly depends on
> gic_acpi_count_gicr_regions() previous failing to find any GICR regions
> (as it is valid to have gicr_base_address of zero if the redistributors
> are described via a GICR entry).
> 
> Instead of complicating the check, remove it. Failures that happen at
> this point cause the irqchip not to register, meaning no irqs can be
> requested. The kernel grinds to a panic() pretty quickly.
> 
> Without the check, MADT tables that exhibit this problem are still
> caught by gic_populate_rdist(), which helpfully also prints what went
> wrong:
> | CPU4: mpidr 100 has no re-distributor!
> 
> Signed-off-by: James Morse <james.morse at arm.com>
> Reviewed-by: Gavin Shan <gshan at redhat.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Does what it says on the tin.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>


From Jonathan.Cameron at Huawei.com  Fri Feb  2 08:47:02 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Fri, 2 Feb 2024 16:47:02 +0000
Subject: [PATCH RFC v4 11/15] irqchip/gic-v3: Add support for ACPI's
 disabled but 'online capable' CPUs
In-Reply-To: <E1rVDnE-0027ZI-VR@rmk-PC.armlinux.org.uk>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk>
	<E1rVDnE-0027ZI-VR@rmk-PC.armlinux.org.uk>
Message-ID: <20240202164702.00001c5b@Huawei.com>

On Wed, 31 Jan 2024 16:50:32 +0000
Russell King (Oracle) <rmk+kernel at armlinux.org.uk> wrote:

> From: James Morse <james.morse at arm.com>
> 
> To support virtual CPU hotplug, ACPI has added an 'online capable' bit
> to the MADT GICC entries. This indicates a disabled CPU entry may not
> be possible to online via PSCI until firmware has set enabled bit in
> _STA.
> 
> This means that a "usable" GIC is one that is marked as either enabled,
> or online capable. Therefore, change acpi_gicc_is_usable() to check both
> bits. However, we need to change the test in gic_acpi_match_gicc() back
> to testing just the enabled bit so the count of enabled distributors is
> correct.
> 
> What about the redistributor in the GICC entry? ACPI doesn't want to say.
> Assume the worst: When a redistributor is described in the GICC entry,
> but the entry is marked as disabled at boot, assume the redistributor
> is inaccessible.
> 
> The GICv3 driver doesn't support late online of redistributors, so this
> means the corresponding CPU can't be brought online either. Clear the
> possible and present bits.
> 
> Systems that want CPU hotplug in a VM can ensure their redistributors
> are always-on, and describe them that way with a GICR entry in the MADT.
> 
> When mapping redistributors found via GICC entries, handle the case
> where the arch code believes the CPU is present and possible, but it
> does not have an accessible redistributor. Print a warning and clear
> the present and possible bits.
> 
> Signed-off-by: James Morse <james.morse at arm.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>




From viro at zeniv.linux.org.uk  Fri Feb  2 08:49:47 2024
From: viro at zeniv.linux.org.uk (Al Viro)
Date: Fri, 2 Feb 2024 16:49:47 +0000
Subject: [PATCH] regset: use vmalloc() for regset_get_alloc()
In-Reply-To: <CAD=FV=X93KNMF4NwQY8uh-L=1J8PrDFQYu-cqSd+KnY5+Pq+_w@mail.gmail.com>
References: <20240201171159.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924@changeid>
 <20240202012249.GU2087318@ZenIV>
 <CAD=FV=X5dpMyCGg4Xn+ApRwmiLB5zB0LTMCoSfW_X6eAsfQy8w@mail.gmail.com>
 <20240202030438.GV2087318@ZenIV>
 <CAD=FV=Wbq7R9AirvxnW1aWoEnp2fWQrwBsxsDB46xbfTLHCZ4w@mail.gmail.com>
 <20240202034925.GW2087318@ZenIV>
 <20240202040503.GX2087318@ZenIV>
 <CAD=FV=X93KNMF4NwQY8uh-L=1J8PrDFQYu-cqSd+KnY5+Pq+_w@mail.gmail.com>
Message-ID: <20240202164947.GC2087318@ZenIV>

On Fri, Feb 02, 2024 at 08:24:17AM -0800, Doug Anderson wrote:
> Hi,
> 
> On Thu, Feb 1, 2024 at 8:05?PM Al Viro <viro at zeniv.linux.org.uk> wrote:
> >
> > On Fri, Feb 02, 2024 at 03:49:25AM +0000, Al Viro wrote:
> > > On Thu, Feb 01, 2024 at 07:15:48PM -0800, Doug Anderson wrote:
> > > > >
> > > > > Well, the next step would be to see which regset it is - if you
> > > > > see that kind of allocation, print regset->n, regset->size and
> > > > > regset->core_note_type.
> > > >
> > > > Of course! Here are the big ones:
> > > >
> > > > [   45.875574] DOUG: Allocating 279584 bytes, n=17474, size=16,
> > > > core_note_type=1029
> > >
> > > 0x405, NT_ARM_SVE
> > >         [REGSET_SVE] = { /* Scalable Vector Extension */
> > >                 .core_note_type = NT_ARM_SVE,
> > >                 .n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE),
> > >                                   SVE_VQ_BYTES),
> > >                 .size = SVE_VQ_BYTES,
> > >
> > > IDGI.  Wasn't SVE up to 32 * 2Kbit, i.e. 8Kbyte max?  Any ARM folks around?
> > > Sure, I understand that it's variable-sized and we want to allocate enough
> > > for the worst case, but can we really get about 280Kb there?  Context switches
> > > would be really unpleasant on such boxen...
> >
> > FWIW, this apparently intends to be "variable, up to SVE_PT_SIZE(...) bytes";
> > no idea if SVE_PT_SIZE is the right thing to use here.
> 
> +folks from `./scripts/get_maintainer.pl -f arch/arm64/kernel/ptrace.c`
> 
> Trying to follow the macros to see where "n" comes from is a maze of
> twisty little passages, all alike. Hopefully someone from the ARM
> world can help tell if the value of 17474 for n here is correct or if
> something is wonky.

It might be interesting to have it print the return value of __regset_get()
in those cases; if *that* is huge, we really have a problem.  If it ends up
small enough to fit into few pages, OTOH...

SVE_VQ_MAX is defined as 255; is that really in units of 128 bits?  IOW,
do we really expect to support 32Kbit registers?  That would drive the
size into that range, all right, but it would really suck on context
switches.

I could be misreading it, though - the macros in there are not easy to
follow and I've never dealt with SVE before, so take the above with
a cartload of salt.


From a0501179 at ti.com  Fri Feb  2 08:50:28 2024
From: a0501179 at ti.com (Anwar, Md Danish)
Date: Fri, 2 Feb 2024 22:20:28 +0530
Subject: [PATCH v3 3/3] arm64: dts: ti: k3-am642-evm: add overlay for
 icssg1 2nd port
In-Reply-To: <33e62844-a148-4374-aba8-481dc7799e15@kernel.org>
References: <20240122113045.1711818-1-danishanwar@ti.com>
 <20240122113045.1711818-4-danishanwar@ti.com>
 <33e62844-a148-4374-aba8-481dc7799e15@kernel.org>
Message-ID: <17d1cfd0-2962-4857-af1d-7f2126b37abf@ti.com>

On 2/2/2024 5:56 PM, Roger Quadros wrote:
> 
> 
> On 22/01/2024 13:30, MD Danish Anwar wrote:
>> The am642-evm doesn't allow to enable 2 x CPSW3g ports and 2 x ICSSG1 ports
>> all together, so base k3-am642-evm.dts enables by default 2 x CPSW3g ports
>> and 1 x ICSSG1 ports, but it also possible to support 1 x CPSW3g ports and
>> 2 x ICSSG1 ports configuration.
> 
> "it is also possible"
> 
> OK so there can only be 3 ethernet ports on this board. There is no "ethernet3" alias.
> 

Yes maximum there can be 3 ports only. By default 2 are cpsw and 1 icssg
but this parch introduces overlay to change the muxed port into icssg.

By default,
	ethernet0 = &cpsw_port1;
	ethernet1 = &cpsw_port2;
	ethernet2 = &icssg1_emac0;

When this overlay is applied, it should be something like this,
	ethernet0 = &cpsw_port1;
	ethernet1 = &icssg1_emac0;
	ethernet2 = &icssg1_emac1;

Let me know if this looks ok to you. I will modify the alias accordingly.

>>
>> This patch adds overlay to support 1 x CPSW3g ports and 2 x ICSSG1 ports
>> configuration:
>> - Add label name 'mdio_mux_1' for 'mdio-mux-1' node so that the node
>>   'mdio-mux-1' can be disabled in the overlay using the label name.
>> - disable 2nd CPSW3g port
>> - update CPSW3g pinmuxes to not use RGMII2
>> - disable mdio-mux-1 and define mdio-mux-2 to route ICSSG1 MDIO to the
>>   shared DP83869 PHY
>> - add and enable ICSSG1 RGMII2 pinmuxes
>> - enable ICSSG1 MII1 port
>>
>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>> ---
>>  arch/arm64/boot/dts/ti/Makefile               |  5 ++
>>  .../dts/ti/k3-am642-evm-icssg1-dualemac.dtso  | 75 +++++++++++++++++++
>>  arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  2 +-
>>  3 files changed, 81 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>>
>> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
>> index 52c1dc910308..320b2fae5730 100644
>> --- a/arch/arm64/boot/dts/ti/Makefile
>> +++ b/arch/arm64/boot/dts/ti/Makefile
>> @@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
>>  dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
>>  dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>>  dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
>> +dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac.dtbo
>>  
>>  # Boards with AM65x SoC
>>  k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
>> @@ -105,6 +106,8 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
>>  	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>>  k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
>>  	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
>> +k3-am642-evm-icssg1-dualemac-dtbs := \
>> +	k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
>>  k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
>>  	k3-j721e-evm-pcie0-ep.dtbo
>>  k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
>> @@ -120,6 +123,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
>>  	k3-am62a7-sk-csi2-ov5640.dtb \
>>  	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
>>  	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
>> +	k3-am642-evm-icssg1-dualemac.dtb \
>>  	k3-j721e-evm-pcie0-ep.dtb \
>>  	k3-j721s2-evm-pcie1-ep.dtb
>>  
>> @@ -129,6 +133,7 @@ DTC_FLAGS_k3-am625-sk += -@
>>  DTC_FLAGS_k3-am62-lp-sk += -@
>>  DTC_FLAGS_k3-am62a7-sk += -@
>>  DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
>> +DTC_FLAGS_k3-am642-evm += -@
>>  DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
>>  DTC_FLAGS_k3-j721e-common-proc-board += -@
>>  DTC_FLAGS_k3-j721s2-common-proc-board += -@
>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>> new file mode 100644
>> index 000000000000..b2b1a6252e73
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>> @@ -0,0 +1,75 @@
>> +// SPDX-License-Identifier: GPL-2.0
> 
> Don't you need to use updated licensing header like in the series [1]
> 
> [1] https://lore.kernel.org/all/20240110140903.4090946-1-nm at ti.com/
> 

Sure. I will update the header.

>> +/**
>> + * DT overlay for enabling 2nd ICSSG1 port on AM642 EVM
>> + *
>> + * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
>> + */
>> +
>> +/dts-v1/;
>> +/plugin/;
>> +
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include "k3-pinctrl.h"
>> +
>> +&{/} {
> 
> You need to fixup alias for ethernet1 to icssg1_emac1?
> 

Yes I will update the aliases accordingly.

>> +	mdio-mux-2 {
> 
> this should be mdio-mux at 0 ?
> 

The main mux in evm dts is defined as mdio-mux-1 so I was following the
same. I will change this to mdio-mux at 0

>> +		compatible = "mdio-mux-multiplexer";
>> +		mux-controls = <&mdio_mux>;
>> +		mdio-parent-bus = <&icssg1_mdio>;
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		mdio at 0 {
>> +			reg = <0x0>;
>> +			#address-cells = <1>;
>> +			#size-cells = <0>;
>> +
>> +			icssg1_phy2: ethernet-phy at 3 {
>> +				reg = <3>;
>> +				tx-internal-delay-ps = <250>;
>> +				rx-internal-delay-ps = <2000>;
>> +			};
>> +		};
>> +	};
>> +};
>> +
>> +&main_pmx0 {
>> +	icssg1_rgmii2_pins_default: icssg1-rgmii2-default-pins {
>> +		pinctrl-single,pins = <
>> +			AM64X_IOPAD(0x0108, PIN_INPUT, 2) /* (W11) PRG1_PRU1_GPO0.RGMII2_RD0 */
>> +			AM64X_IOPAD(0x010c, PIN_INPUT, 2) /* (V11) PRG1_PRU1_GPO1.RGMII2_RD1 */
>> +			AM64X_IOPAD(0x0110, PIN_INPUT, 2) /* (AA12) PRG1_PRU1_GPO2.RGMII2_RD2 */
>> +			AM64X_IOPAD(0x0114, PIN_INPUT, 2) /* (Y12) PRG1_PRU1_GPO3.RGMII2_RD3 */
>> +			AM64X_IOPAD(0x0120, PIN_INPUT, 2) /* (U11) PRG1_PRU1_GPO6.RGMII2_RXC */
>> +			AM64X_IOPAD(0x0118, PIN_INPUT, 2) /* (W12) PRG1_PRU1_GPO4.RGMII2_RX_CTL */
>> +			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2) /* (AA10) PRG1_PRU1_GPO11.RGMII2_TD0 */
>> +			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2) /* (V10) PRG1_PRU1_GPO12.RGMII2_TD1 */
>> +			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2) /* (U10) PRG1_PRU1_GPO13.RGMII2_TD2 */
>> +			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2) /* (AA11) PRG1_PRU1_GPO14.RGMII2_TD3 */
>> +			AM64X_IOPAD(0x0148, PIN_OUTPUT, 2) /* (Y10) PRG1_PRU1_GPO16.RGMII2_TXC */
>> +			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2) /* (Y11) PRG1_PRU1_GPO15.RGMII2_TX_CTL */
>> +		>;
>> +	};
>> +};
>> +
>> +&cpsw3g {
>> +	pinctrl-0 = <&rgmii1_pins_default>;
>> +};
>> +
>> +&cpsw_port2 {
>> +	status = "disabled";
>> +};
>> +
>> +&mdio_mux_1 {
>> +	status = "disabled";
>> +};
>> +
>> +&icssg1_eth {
>> +	pinctrl-0 = <&icssg1_rgmii1_pins_default>, <&icssg1_rgmii2_pins_default>;
>> +};
>> +
>> +&icssg1_emac1 {
>> +	status = "okay";
>> +	phy-handle = <&icssg1_phy2>;
>> +	phy-mode = "rgmii-id";
>> +};
>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> index c08b0223be52..6ae43c12419f 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> @@ -200,7 +200,7 @@ mdio_mux: mux-controller {
>>  		mux-gpios = <&exp1 12 GPIO_ACTIVE_HIGH>;
>>  	};
>>  
>> -	mdio-mux-1 {
>> +	mdio_mux_1: mdio-mux-1 {
> 
> mdio_mux_1: mdio-mux at 1
> 

Sure. I will update this.

>>  		compatible = "mdio-mux-multiplexer";
>>  		mux-controls = <&mdio_mux>;
>>  		mdio-parent-bus = <&cpsw3g_mdio>;
> 

-- 
Thanks and Regards,
Md Danish Anwar


From Dave.Martin at arm.com  Fri Feb  2 08:54:30 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Fri, 2 Feb 2024 16:54:30 +0000
Subject: [PATCH] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <CAMj1kXGSQ4Xq68Cmq6BH37FPJ+R+N5cOfrdC+aVML4sGaNDopg@mail.gmail.com>
References: <20240201223545.728028-1-maskray@google.com>
 <Zb0Qu5lR0iZUqImb@e133380.arm.com>
 <CAMj1kXGSQ4Xq68Cmq6BH37FPJ+R+N5cOfrdC+aVML4sGaNDopg@mail.gmail.com>
Message-ID: <Zb0eRogn3rjkeDAs@e133380.arm.com>

On Fri, Feb 02, 2024 at 05:32:33PM +0100, Ard Biesheuvel wrote:
> On Fri, 2 Feb 2024 at 16:56, Dave Martin <Dave.Martin at arm.com> wrote:
> >
> > On Thu, Feb 01, 2024 at 02:35:45PM -0800, Fangrui Song wrote:
> > > The generic constraint "i" seems to be copied from x86 or arm (and with
> > > a redundant generic operand modifier "c"). It works with -fno-PIE but
> > > not with -fPIE/-fPIC in GCC's aarch64 port.
> > >
> > > The machine constraint "S", which denotes a symbol or label reference
> > > with a constant offset, supports PIC and has been available in GCC since
> > > 2012 and in Clang since 7.0. However, Clang before 19 does not support
> > > "S" on a symbol with a constant offset [1] (e.g.
> > > `static_key_false(&nf_hooks_needed[pf][hook])` in
> > > include/linux/netfilter.h), so we use "i" as a fallback.
> > >
> > > Suggested-by: Ard Biesheuvel <ardb at kernel.org>
> > > Signed-off-by: Fangrui Song <maskray at google.com>
> > > Link: https://github.com/llvm/llvm-project/pull/80255 [1]
> > >
> > > ---
> > > Changes from
> > > arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
> > >
> > > * Use "Si" as Ard suggested to support Clang<19
> > > * Make branch a separate operand
> > > ---
> > >  arch/arm64/include/asm/jump_label.h | 12 ++++++++----
> > >  1 file changed, 8 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> > > index 48ddc0f45d22..1f7d529be608 100644
> > > --- a/arch/arm64/include/asm/jump_label.h
> > > +++ b/arch/arm64/include/asm/jump_label.h
> > > @@ -15,6 +15,10 @@
> > >
> > >  #define JUMP_LABEL_NOP_SIZE          AARCH64_INSN_SIZE
> > >
> > > +/*
> > > + * Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
> > > + * support "S" on a symbol with a constant offset, so we use "i" as a fallback.
> > > + */
> > >  static __always_inline bool arch_static_branch(struct static_key * const key,
> > >                                              const bool branch)
> > >  {
> > > @@ -23,9 +27,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
> > >                "      .pushsection    __jump_table, \"aw\"    \n\t"
> > >                "      .align          3                       \n\t"
> > >                "      .long           1b - ., %l[l_yes] - .   \n\t"
> > > -              "      .quad           %c0 - .                 \n\t"
> > > +              "      .quad           %0 + %1 - .             \n\t"
> > >                "      .popsection                             \n\t"
> > > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> > > +              :  :  "Si"(key), "i"(branch) :  : l_yes);
> >
> > Is the meaning of multi-alternatives well defined if different arguments
> > specify different numbers of alternatives?  The GCC documentation says:
> >
> > https://gcc.gnu.org/onlinedocs/gcc/Multi-Alternative.html:
> >
> > -8<-
> >
> > [...] All operands for a single instruction must have the same number of
> > alternatives.
> >
> > ->8-
> >
> 
> AIUI that does not apply here. That reasons about multiple arguments
> having more than one constraint, where not all combinations of those
> constraints are supported by the instruction.

Ah, scratch that: I'm confusing multi-alternatives with simple
constraints: all arguments must have the same number of comma-separated
lists of constraint letters, but each list can contain as many or as few
letters as are needed to match the operand.

So "Si"(), "i"() is fine.

> > Also, I still think it may be redundant to move the addition inside the
> > asm, so long as Clang is happy with the symbol having an offset.
> >
> 
> Older Clang is not happy with the symbol having an offset.
> 
> And given that the key pointer and the 'branch' boolean are two
> distinct inputs to this function, I struggle to understand why you
> feel it is better to combine them in the argument. 'branch' is used to
> decide whether or not to set bit 0, independently of the value of key.
> Using array indexing to combine those values together to avoid an
> addition in the asm obfuscates the code.

This was more about not making changes that don't need to be made,
unless it clearly makes the code better.

But if some verions of Clang accept "S" but choke if there's an offset,
then moving the addition into the asm seems the way to go.

(I may have misread the commit message on this point.)

[...]

Cheers
---Dave


From viro at zeniv.linux.org.uk  Fri Feb  2 08:55:24 2024
From: viro at zeniv.linux.org.uk (Al Viro)
Date: Fri, 2 Feb 2024 16:55:24 +0000
Subject: [PATCH] regset: use vmalloc() for regset_get_alloc()
In-Reply-To: <20240202164947.GC2087318@ZenIV>
References: <20240201171159.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924@changeid>
 <20240202012249.GU2087318@ZenIV>
 <CAD=FV=X5dpMyCGg4Xn+ApRwmiLB5zB0LTMCoSfW_X6eAsfQy8w@mail.gmail.com>
 <20240202030438.GV2087318@ZenIV>
 <CAD=FV=Wbq7R9AirvxnW1aWoEnp2fWQrwBsxsDB46xbfTLHCZ4w@mail.gmail.com>
 <20240202034925.GW2087318@ZenIV>
 <20240202040503.GX2087318@ZenIV>
 <CAD=FV=X93KNMF4NwQY8uh-L=1J8PrDFQYu-cqSd+KnY5+Pq+_w@mail.gmail.com>
 <20240202164947.GC2087318@ZenIV>
Message-ID: <20240202165524.GD2087318@ZenIV>

On Fri, Feb 02, 2024 at 04:49:47PM +0000, Al Viro wrote:
> > +folks from `./scripts/get_maintainer.pl -f arch/arm64/kernel/ptrace.c`
> > 
> > Trying to follow the macros to see where "n" comes from is a maze of
> > twisty little passages, all alike. Hopefully someone from the ARM
> > world can help tell if the value of 17474 for n here is correct or if
> > something is wonky.
> 
> It might be interesting to have it print the return value of __regset_get()
> in those cases; if *that* is huge, we really have a problem.  If it ends up
> small enough to fit into few pages, OTOH...
> 
> SVE_VQ_MAX is defined as 255; is that really in units of 128 bits?  IOW,
> do we really expect to support 32Kbit registers?  That would drive the
> size into that range, all right, but it would really suck on context
> switches.
> 
> I could be misreading it, though - the macros in there are not easy to
> follow and I've never dealt with SVE before, so take the above with
> a cartload of salt.

Worse - it's SVE_VQ_MAX is 512; sorry about the confusion.  OK, that would
certainly explain the size (header + 32 registers, each up to 512 * 16 bytes),
but... ouch.


From Jonathan.Cameron at Huawei.com  Fri Feb  2 09:04:13 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Fri, 2 Feb 2024 17:04:13 +0000
Subject: [PATCH RFC v4 14/15] arm64: document virtual CPU hotplug's
 expectations
In-Reply-To: <E1rVDnU-0027Zf-GF@rmk-PC.armlinux.org.uk>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk>
	<E1rVDnU-0027Zf-GF@rmk-PC.armlinux.org.uk>
Message-ID: <20240202170413.0000154e@Huawei.com>

On Wed, 31 Jan 2024 16:50:48 +0000
Russell King (Oracle) <rmk+kernel at armlinux.org.uk> wrote:

> From: James Morse <james.morse at arm.com>
> 
> Add a description of physical and virtual CPU hotplug, explain the
> differences and elaborate on what is required in ACPI for a working
> virtual hotplug system.
> 
> Signed-off-by: James Morse <james.morse at arm.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
> Outstanding comment:
>  https://lore.kernel.org/r/20230914174137.00000a62 at Huawei.com

Outstanding but an ACPI Spec question rather than one about this description.
I've finally regained access to Mantis etc so can follow that up at some point.

If we get clarify on how to tell that CPUs that are present and enabled at boot
can be removed later we can relax this text to allow for that.


>  https://lore.kernel.org/r/20231215170428.00000d81 at Huawei.com
That's a comment on the above comment to say I'm fine with it as is :)

This @Huawei guy is really annoying ;)

Jonathan

> ---
>  Documentation/arch/arm64/cpu-hotplug.rst | 79 ++++++++++++++++++++++++
>  Documentation/arch/arm64/index.rst       |  1 +
>  2 files changed, 80 insertions(+)
>  create mode 100644 Documentation/arch/arm64/cpu-hotplug.rst
> 
> diff --git a/Documentation/arch/arm64/cpu-hotplug.rst b/Documentation/arch/arm64/cpu-hotplug.rst
> new file mode 100644
> index 000000000000..76ba8d932c72
> --- /dev/null
> +++ b/Documentation/arch/arm64/cpu-hotplug.rst
> @@ -0,0 +1,79 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +.. _cpuhp_index:
> +
> +====================
> +CPU Hotplug and ACPI
> +====================
> +
> +CPU hotplug in the arm64 world is commonly used to describe the kernel taking
> +CPUs online/offline using PSCI. This document is about ACPI firmware allowing
> +CPUs that were not available during boot to be added to the system later.
> +
> +``possible`` and ``present`` refer to the state of the CPU as seen by linux.
> +
> +
> +CPU Hotplug on physical systems - CPUs not present at boot
> +----------------------------------------------------------
> +
> +Physical systems need to mark a CPU that is ``possible`` but not ``present`` as
> +being ``present``. An example would be a dual socket machine, where the package
> +in one of the sockets can be replaced while the system is running.
> +
> +This is not supported.
> +
> +In the arm64 world CPUs are not a single device but a slice of the system.
> +There are no systems that support the physical addition (or removal) of CPUs
> +while the system is running, and ACPI is not able to sufficiently describe
> +them.
> +
> +e.g. New CPUs come with new caches, but the platform's cache toplogy is
> +described in a static table, the PPTT. How caches are shared between CPUs is
> +not discoverable, and must be described by firmware.
> +
> +e.g. The GIC redistributor for each CPU must be accessed by the driver during
> +boot to discover the system wide supported features. ACPI's MADT GICC
> +structures can describe a redistributor associated with a disabled CPU, but
> +can't describe whether the redistributor is accessible, only that it is not
> +'always on'.
> +
> +arm64's ACPI tables assume that everything described is ``present``.
> +
> +
> +CPU Hotplug on virtual systems - CPUs not enabled at boot
> +---------------------------------------------------------
> +
> +Virtual systems have the advantage that all the properties the system will
> +ever have can be described at boot. There are no power-domain considerations
> +as such devices are emulated.
> +
> +CPU Hotplug on virtual systems is supported. It is distinct from physical
> +CPU Hotplug as all resources are described as ``present``, but CPUs may be
> +marked as disabled by firmware. Only the CPU's online/offline behaviour is
> +influenced by firmware. An example is where a virtual machine boots with a
> +single CPU, and additional CPUs are added once a cloud orchestrator deploys
> +the workload.
> +
> +For a virtual machine, the VMM (e.g. Qemu) plays the part of firmware.
> +
> +Virtual hotplug is implemented as a firmware policy affecting which CPUs can be
> +brought online. Firmware can enforce its policy via PSCI's return codes. e.g.
> +``DENIED``.
> +
> +The ACPI tables must describe all the resources of the virtual machine. CPUs
> +that firmware wishes to disable either from boot (or later) should not be
> +``enabled`` in the MADT GICC structures, but should have the ``online capable``
> +bit set, to indicate they can be enabled later. The boot CPU must be marked as
> +``enabled``.  The 'always on' GICR structure must be used to describe the
> +redistributors.
> +
> +CPUs described as ``online capable`` but not ``enabled`` can be set to enabled
> +by the DSDT's Processor object's _STA method. On virtual systems the _STA method
> +must always report the CPU as ``present``. Changes to the firmware policy can
> +be notified to the OS via device-check or eject-request.
> +
> +CPUs described as ``enabled`` in the static table, should not have their _STA
> +modified dynamically by firmware. Soft-restart features such as kexec will
> +re-read the static properties of the system from these static tables, and
> +may malfunction if these no longer describe the running system. Linux will
> +re-discover the dynamic properties of the system from the _STA method later
> +during boot.
> diff --git a/Documentation/arch/arm64/index.rst b/Documentation/arch/arm64/index.rst
> index d08e924204bf..78544de0a8a9 100644
> --- a/Documentation/arch/arm64/index.rst
> +++ b/Documentation/arch/arm64/index.rst
> @@ -13,6 +13,7 @@ ARM64 Architecture
>      asymmetric-32bit
>      booting
>      cpu-feature-registers
> +    cpu-hotplug
>      elf_hwcaps
>      hugetlbpage
>      kdump



From sebastian.reichel at collabora.com  Fri Feb  2 09:04:12 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Fri, 2 Feb 2024 18:04:12 +0100
Subject: [PATCH 03/12] power: reset: Add TI-SCI reboot driver
In-Reply-To: <20240201211534.dv6qu7ila54vqykn@cheating>
References: <20240131221957.213717-1-afd@ti.com>
 <20240131221957.213717-4-afd@ti.com>
 <20240201211534.dv6qu7ila54vqykn@cheating>
Message-ID: <xdrdaasaosjagr35ftb56yszwlrcf5bzpsnui5crut2ii7nu7n@apxciqrwluwr>

Hi,

On Thu, Feb 01, 2024 at 03:15:34PM -0600, Nishanth Menon wrote:
> On 16:19-20240131, Andrew Davis wrote:
> > This reboot driver calls into firmware using TI-SCI to reboot the system.
> > We register the handler with low priority as we want PSCI to remain the
> > main way these devices are rebooted. This driver acts as a fallback if
> > PSCI is not able to reboot the system.
> > 
> > Signed-off-by: Andrew Davis <afd at ti.com>
> > ---
> >  MAINTAINERS                         |  1 +
> >  drivers/power/reset/Kconfig         |  7 ++++
> >  drivers/power/reset/Makefile        |  1 +
> >  drivers/power/reset/ti-sci-reboot.c | 63 +++++++++++++++++++++++++++++
> >  4 files changed, 72 insertions(+)
> >  create mode 100644 drivers/power/reset/ti-sci-reboot.c
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 45983bb174fe4..ee67ea497fc56 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -21758,6 +21758,7 @@ F:	drivers/clk/keystone/sci-clk.c
> >  F:	drivers/firmware/ti_sci*
> >  F:	drivers/irqchip/irq-ti-sci-inta.c
> >  F:	drivers/irqchip/irq-ti-sci-intr.c
> > +F:	drivers/power/reset/ti-sci-reboot.c
> >  F:	drivers/reset/reset-ti-sci.c
> >  F:	drivers/soc/ti/ti_sci_inta_msi.c
> >  F:	drivers/pmdomain/ti/ti_sci_pm_domains.c
> > diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
> > index fece990af4a75..d3e91e54cae24 100644
> > --- a/drivers/power/reset/Kconfig
> > +++ b/drivers/power/reset/Kconfig
> > @@ -205,6 +205,13 @@ config POWER_RESET_ST
> >  	help
> >  	  Reset support for STMicroelectronics boards.
> >  
> > +config POWER_RESET_TI_SCI
> > +	tristate "TI System Control Interface (TI-SCI) reboot driver"
> > +	depends on TI_SCI_PROTOCOL
> > +	help
> > +	  This enables the reboot driver support over TI System Control
> > +	  Interface available on some TI's SoCs.
> > +
> >  config POWER_RESET_TPS65086
> >  	bool "TPS65086 restart driver"
> >  	depends on MFD_TPS65086
> > diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
> > index a95d1bd275d18..881ca58a43b9c 100644
> > --- a/drivers/power/reset/Makefile
> > +++ b/drivers/power/reset/Makefile
> > @@ -23,6 +23,7 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
> >  obj-$(CONFIG_POWER_RESET_REGULATOR) += regulator-poweroff.o
> >  obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
> >  obj-$(CONFIG_POWER_RESET_ST) += st-poweroff.o
> > +obj-$(CONFIG_POWER_RESET_TI_SCI) += ti-sci-reboot.o
> >  obj-$(CONFIG_POWER_RESET_TPS65086) += tps65086-restart.o
> >  obj-$(CONFIG_POWER_RESET_VERSATILE) += arm-versatile-reboot.o
> >  obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
> > diff --git a/drivers/power/reset/ti-sci-reboot.c b/drivers/power/reset/ti-sci-reboot.c
> > new file mode 100644
> > index 0000000000000..400bd5d740f8b
> > --- /dev/null
> > +++ b/drivers/power/reset/ti-sci-reboot.c
> > @@ -0,0 +1,63 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Texas Instrument's System Control Interface (TI-SCI) reboot driver
> > + *
> > + * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
> > + *	Andrew Davis <afd at ti.com>
> > + */
> > +
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/module.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/reboot.h>
> > +
> > +#include <linux/soc/ti/ti_sci_protocol.h>
> > +
> > +static int ti_sci_reboot_handler(struct sys_off_data *data)
> > +{
> > +	const struct ti_sci_handle *sci = data->cb_data;
> > +	const struct ti_sci_core_ops *core_ops = &sci->ops.core_ops;
> > +
> > +	core_ops->reboot_device(sci);
> > +
> > +	return NOTIFY_DONE;
> > +}
> > +
> > +static int ti_sci_reboot_probe(struct platform_device *pdev)
> > +{
> > +	const struct ti_sci_handle *sci;
> > +	int err;
> > +
> > +	sci = devm_ti_sci_get_handle(&pdev->dev);
> > +	if (IS_ERR(sci))
> > +		return PTR_ERR(sci);
> > +
> > +	err = devm_register_sys_off_handler(&pdev->dev,
> > +					    SYS_OFF_MODE_RESTART,
> > +					    SYS_OFF_PRIO_LOW,
> > +					    ti_sci_reboot_handler,
> > +					    (void *)sci);
> > +	if (err)
> > +		return dev_err_probe(&pdev->dev, err, "Cannot register restart handler\n");
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id ti_sci_reboot_of_match[] = {
> > +	{ .compatible = "ti,sci-reboot", },
> > +	{ /* sentinel */ },
> > +};
> > +MODULE_DEVICE_TABLE(of, ti_sci_reboot_of_match);
> > +
> > +static struct platform_driver ti_sci_reboot_driver = {
> > +	.probe = ti_sci_reboot_probe,
> > +	.driver = {
> > +		.name = "ti-sci-reboot",
> > +		.of_match_table = ti_sci_reboot_of_match,
> > +	},
> > +};
> > +module_platform_driver(ti_sci_reboot_driver);
> > +
> > +MODULE_AUTHOR("Andrew Davis <afd at ti.com>");
> > +MODULE_DESCRIPTION("TI System Control Interface (TI SCI) Reboot driver");
> > +MODULE_LICENSE("GPL");
> > -- 
> > 2.39.2
> 
> Will assume the patch to go via Sebastien. Will be good for the dts to
> go via SoC tree. So hoping Sebastien will just pick the driver and
> bindings.

I will wait for the DT binding discussion to have settled. The
driver itself LGTM.

-- Sebastian
-------------- 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/20240202/4e07fc43/attachment-0001.sig>

From adrian.hunter at intel.com  Fri Feb  2 09:05:42 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Fri, 2 Feb 2024 19:05:42 +0200
Subject: [PATCH 1/1] tools: perf: Expose sample ID / stream ID to python
 scripts
In-Reply-To: <20240123103137.1890779-2-ben.gainey@arm.com>
References: <20240123103137.1890779-1-ben.gainey@arm.com>
 <20240123103137.1890779-2-ben.gainey@arm.com>
Message-ID: <8cea7b3f-1cdf-41e7-a8fb-f5c276973ad6@intel.com>

On 23/01/24 12:31, Ben Gainey wrote:
> perf script exposes the evsel_name to python scripts as part of the data
> passed to the sample or tracepoint handler function, and it passes the id and
> stream_id to the throttled/unthrottled handler functions. This makes matching
> throttle events and samples difficult.
> 
> To make this possible, this change exposes the sample id and stream_id values
> to the script.
> 
> Signed-off-by: Ben Gainey <ben.gainey at arm.com>

Reviewed-by: Adrian Hunter <adrian.hunter at intel.com>

> ---
>  tools/perf/Documentation/perf-script-python.txt        | 4 ++--
>  tools/perf/util/scripting-engines/trace-event-python.c | 8 +++++++-
>  2 files changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/perf/Documentation/perf-script-python.txt b/tools/perf/Documentation/perf-script-python.txt
> index 6a8581012e162..13e37e9385ee4 100644
> --- a/tools/perf/Documentation/perf-script-python.txt
> +++ b/tools/perf/Documentation/perf-script-python.txt
> @@ -642,8 +642,8 @@ SUPPORTED FIELDS
>  
>  Currently supported fields:
>  
> -ev_name, comm, pid, tid, cpu, ip, time, period, phys_addr, addr,
> -symbol, symoff, dso, time_enabled, time_running, values, callchain,
> +ev_name, comm, id, stream_id, pid, tid, cpu, ip, time, period, phys_addr,
> +addr, symbol, symoff, dso, time_enabled, time_running, values, callchain,
>  brstack, brstacksym, datasrc, datasrc_decode, iregs, uregs,
>  weight, transaction, raw_buf, attr, cpumode.
>  
> diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
> index 860e1837ba969..d88966645b2f4 100644
> --- a/tools/perf/util/scripting-engines/trace-event-python.c
> +++ b/tools/perf/util/scripting-engines/trace-event-python.c
> @@ -858,6 +858,10 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample,
>  	pydict_set_item_string_decref(dict, "ev_name", _PyUnicode_FromString(evsel__name(evsel)));
>  	pydict_set_item_string_decref(dict, "attr", _PyBytes_FromStringAndSize((const char *)&evsel->core.attr, sizeof(evsel->core.attr)));
>  
> +	pydict_set_item_string_decref(dict_sample, "id",
> +			PyLong_FromUnsignedLongLong(sample->id));
> +	pydict_set_item_string_decref(dict_sample, "stream_id",
> +			PyLong_FromUnsignedLongLong(sample->stream_id));
>  	pydict_set_item_string_decref(dict_sample, "pid",
>  			_PyLong_FromLong(sample->pid));
>  	pydict_set_item_string_decref(dict_sample, "tid",
> @@ -1306,7 +1310,7 @@ static void python_export_sample_table(struct db_export *dbe,
>  	struct tables *tables = container_of(dbe, struct tables, dbe);
>  	PyObject *t;
>  
> -	t = tuple_new(25);
> +	t = tuple_new(27);
>  
>  	tuple_set_d64(t, 0, es->db_id);
>  	tuple_set_d64(t, 1, es->evsel->db_id);
> @@ -1333,6 +1337,8 @@ static void python_export_sample_table(struct db_export *dbe,
>  	tuple_set_d64(t, 22, es->sample->insn_cnt);
>  	tuple_set_d64(t, 23, es->sample->cyc_cnt);
>  	tuple_set_s32(t, 24, es->sample->flags);
> +	tuple_set_d64(t, 25, es->sample->id);
> +	tuple_set_d64(t, 26, es->sample->stream_id);
>  
>  	call_object(tables->sample_handler, t, "sample_table");
>  



From afd at ti.com  Fri Feb  2 09:09:52 2024
From: afd at ti.com (Andrew Davis)
Date: Fri, 2 Feb 2024 11:09:52 -0600
Subject: [PATCH v4 4/5] arm64: dts: add description for solidrun am642 som
 and evaluation board
In-Reply-To: <20240202-add-am64-som-v4-4-5f8b12af5e71@solid-run.com>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
 <20240202-add-am64-som-v4-4-5f8b12af5e71@solid-run.com>
Message-ID: <6b457759-9a2d-44a7-a1a4-7c7ac42aedae@ti.com>

On 2/2/24 10:10 AM, Josua Mayer wrote:
> Add description for the SolidRun AM642 SoM, and HummingBoard-T
> evaluation board.
> 
> The SoM features:
> - 1x cpsw ethernet with phy
> - 2x pru ethernet with phy
> - eMMC
> - spi flash (assembly option)
> 
> Additionally microSD and usb-2.0 otg are included in the SoM
> description as they are supported boot sources for the SOC boot-rom.
> 
> The Carrier provides:
> - 3x RJ45 connector
> - 2x M.2 connector
> - USB-2.0 Hub
> - USB-A Connector
> - LEDs
> - 2x CAN transceiver
> - 1x RS485 transceiver
> - sensors
> 
> The M.2 connectors support either USB-3.1 or PCI-E depending on status
> of a mux. By default the mux is switched off.
> 
> Signed-off-by: Josua Mayer <josua at solid-run.com>
> ---
>   arch/arm64/boot/dts/ti/Makefile                    |   1 +
>   arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
>   arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 592 +++++++++++++++++++++
>   3 files changed, 885 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
> index 77a347f9f47d..041c3b71155e 100644
> --- a/arch/arm64/boot/dts/ti/Makefile
> +++ b/arch/arm64/boot/dts/ti/Makefile
> @@ -32,6 +32,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb
>   
>   # Boards with AM64x SoC
>   dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
> +dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
> diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
> new file mode 100644
> index 000000000000..ebaf281e1e1e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
> @@ -0,0 +1,292 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
> + *
> + * DTS for SolidRun AM642 HummingBoard-T,
> + * running on Cortex A53.
> + *
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/leds/common.h>
> +#include <dt-bindings/phy/phy.h>
> +
> +#include "k3-am642.dtsi"
> +#include "k3-am642-sr-som.dtsi"
> +
> +/ {
> +	model = "SolidRun AM642 HummingBoard-T";
> +	compatible = "solidrun,am642-hummingboard-t", "solidrun,am642-sr-som", "ti,am642";
> +
> +	aliases {
> +		serial5 = &main_uart3;
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&leds_pins_default>;
> +
> +		/* D24 */
> +		led1: led-1 {
> +			label = "led1";
> +			gpios = <&main_gpio0 29 GPIO_ACTIVE_HIGH>;
> +			color = <LED_COLOR_ID_GREEN>;
> +		};
> +
> +		/* D25 */
> +		led2: led-2 {
> +			label = "led2";
> +			gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
> +			color = <LED_COLOR_ID_GREEN>;
> +		};
> +
> +		/* D26 */
> +		led3: led-3 {
> +			label = "led3";
> +			gpios = <&main_gpio0 33 GPIO_ACTIVE_HIGH>;
> +			color = <LED_COLOR_ID_GREEN>;
> +		};
> +	};
> +
> +	regulator-m2-3v3 {
> +		compatible = "regulator-fixed";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&regulator_pcie_3v3_pins_default>;
> +		regulator-name = "m2-3v3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		gpio = <&main_gpio1 17 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +		regulator-always-on;
> +	};
> +
> +	regulator-vpp-1v8 {
> +		compatible = "regulator-fixed";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&regulator_vpp_1v8_pins_default>;
> +		regulator-name = "vpp-1v8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		gpio = <&main_gpio1 78 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +	};
> +
> +	serdes_mux: mux-controller {
> +		compatible = "gpio-mux";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&serdes_mux_pins_default>;
> +		#mux-control-cells = <0>;
> +		/*
> +		 * Mux has 2 IOs:
> +		 * - select: 0 = USB-3 (M2); 1 = PCIE (M1)
> +		 * - shutdown: 0 = active; 1 = disabled (high impedance)
> +		 */
> +		mux-gpios = <&main_gpio1 40 GPIO_ACTIVE_HIGH>, <&main_gpio1 41 GPIO_ACTIVE_HIGH>;
> +		/* default disabled */
> +		idle-state = <2>;
> +	};
> +};
> +
> +&main_gpio0 {
> +	m2-reset-hog {
> +		gpio-hog;
> +		gpios = <12 GPIO_ACTIVE_LOW>;
> +		output-low; /* deasserted */
> +		line-name = "m2-reset";
> +	};
> +
> +	m1-m2-w-disable1-hog {
> +		gpio-hog;
> +		gpios = <32 GPIO_ACTIVE_LOW>;
> +		output-low; /* deasserted */
> +		line-name = "m1-m2-pcie-w-disable1";
> +	};
> +
> +	m1-m2-w-disable2-hog {
> +		gpio-hog;
> +		gpios = <34 GPIO_ACTIVE_LOW>;
> +		output-low; /* deasserted */
> +		line-name = "m1-m2-pcie-w-disable2";
> +	};
> +};
> +
> +&main_gpio1 {
> +	m1-pcie-clkreq0-hog {
> +		gpio-hog;
> +		gpios = <11 GPIO_ACTIVE_LOW>;
> +		input;
> +		line-name = "m1-pcie-clkreq0";
> +	};
> +
> +	m2-pcie-clkreq-hog {
> +		gpio-hog;
> +		gpios = <35 GPIO_ACTIVE_LOW>;
> +		input;
> +		line-name = "m2-pcie-clkreq";
> +	};
> +};
> +
> +&main_i2c0 {
> +	pinctrl-0 = <&main_i2c0_pins_default>, <&main_i2c0_int_pins_default>;
> +
> +	humidity-sensor at 41 {
> +		compatible = "ti,hdc2010";
> +		reg = <0x41>;
> +		interrupt-parent = <&main_gpio0>;
> +		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
> +	};
> +
> +	light-sensor at 44 {
> +		compatible = "ti,opt3001";
> +		reg = <0x44>;
> +		interrupt-parent = <&main_gpio0>;
> +		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
> +	};
> +
> +	/* charger at 6a */
> +};
> +
> +&main_i2c1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&main_i2c1_pins_default>;
> +	status = "okay";
> +
> +	rtc at 69 {
> +		compatible = "abracon,abx80x";
> +		reg = <0x69>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&rtc_int_pins_default>;
> +		abracon,tc-diode = "schottky";
> +		abracon,tc-resistor = <3>;
> +		interrupt-parent = <&main_gpio0>;
> +		interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
> +	};
> +};
> +
> +&main_mcan0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&main_mcan0_pins_default>;
> +	status = "okay";
> +
> +	can-transceiver {
> +		max-bitrate = <8000000>;
> +	};
> +};
> +
> +&main_mcan1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&main_mcan1_pins_default>;
> +	status = "okay";
> +
> +	can-transceiver {
> +		max-bitrate = <8000000>;
> +	};
> +};
> +
> +&main_pmx0 {
> +	leds_pins_default: leds-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x0074, PIN_OUTPUT, 7)	/* GPMC0_AD14.GPIO0_29 */
> +			AM64X_IOPAD(0x0078, PIN_OUTPUT, 7)	/* GPMC0_AD15.GPIO0_30 */
> +			AM64X_IOPAD(0x0088, PIN_OUTPUT, 7)	/* GPMC0_OEn_REn.GPIO0_33 */
> +		>;
> +	};
> +
> +	main_i2c0_int_pins_default: main-i2c0-pins-int-default {
> +		pinctrl-single,pins = <
> +			/* external pull-up on Carrier */
> +			AM64X_IOPAD(0x0098, PIN_INPUT, 7)	/* GPMC0_WAIT0.GPIO0_37 */
> +		>;
> +	};
> +
> +	main_i2c1_pins_default: main-i2c1-pins-default {
> +		pinctrl-single,pins = <
> +			/* external pull-up on SoM */
> +			AM64X_IOPAD(0x0268, PIN_INPUT, 0)	/* I2C1_SCL.I2C1_SCL */
> +			AM64X_IOPAD(0x026c, PIN_INPUT, 0)	/* I2C1_SDA.I2C1_SDA */
> +		>;
> +	};
> +
> +	main_mcan0_pins_default: main-mcan0-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x0254, PIN_INPUT, 0)	/* MCAN0_RX.MCAN0_RX */
> +			AM64X_IOPAD(0x0250, PIN_OUTPUT, 0)	/* MCAN0_TX.MCAN0_TX */
> +		>;
> +	};
> +
> +	main_mcan1_pins_default: main-mcan1-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x025c, PIN_INPUT, 0)	/* MCAN1_RX.MCAN1_RX */
> +			AM64X_IOPAD(0x0258, PIN_OUTPUT, 0)	/* MCAN1_TX.MCAN1_TX */
> +		>;
> +	};
> +
> +	main_uart3_pins_default: main-uart3-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x016c, PIN_INPUT, 10)	/* PRG0_PRU0_GPO3.UART3_CTSn */
> +			AM64X_IOPAD(0x0170, PIN_OUTPUT, 10)	/* PRG0_PRU0_GPO4.UART3_TXD */
> +			AM64X_IOPAD(0x0174, PIN_OUTPUT, 10)	/* PRG0_PRU0_GPO5.UART3_RTSn */
> +			AM64X_IOPAD(0x01ac, PIN_INPUT, 10)	/* PRG0_PRU0_GPO19.UART3_RXD */
> +		>;
> +	};
> +
> +	pcie0_pins_default: pcie0-pins-default {
> +		pinctrl-single,pins = <
> +			/* connector M2 RESET */
> +			AM64X_IOPAD(0x0030, PIN_OUTPUT, 7)	/* OSPI0_CSn1.GPIO0_12 */
> +			/* connectors M1 & M2 W_DISABLE1 */
> +			AM64X_IOPAD(0x0084, PIN_OUTPUT, 7)	/* GPMC0_ADVN_ALE.GPIO0_32 */
> +			/* connectors M1 & M2 W_DISABLE2 */
> +			AM64X_IOPAD(0x008c, PIN_OUTPUT, 7)	/* GPMC0_WEN.GPIO0_34 */
> +			/* connectors M1 & M2 PERST0 (PCI Reset) */
> +			AM64X_IOPAD(0x019c, PIN_OUTPUT, 7)	/* PRG0_PRU0_GPO15.GPIO1_15 */
> +			/* connector M1 CLKREQ0 */
> +			AM64X_IOPAD(0x018c, PIN_INPUT, 7)	/* PRG0_PRU0_GPO11.GPIO1_11 */
> +			/* connector M2 CLKREQ0 */
> +			AM64X_IOPAD(0x01ec, PIN_INPUT, 7)	/* PRG0_PRU1_GPO15.GPIO1_35 */
> +		>;
> +	};
> +
> +	regulator_pcie_3v3_pins_default: regulator-pcie-3v3-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x01a4, PIN_OUTPUT, 7)	/* PRG0_PRU0_GPO17.GPIO1_17 */
> +		>;
> +	};
> +
> +	regulator_vpp_1v8_pins_default: regulator-vpp-1v8-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x029c, PIN_OUTPUT, 7)	/* MMC1_SDWP.GPIO1_78 */
> +		>;
> +	};
> +
> +	rtc_int_pins_default: rtc-int-pins-default {
> +		pinctrl-single,pins = <
> +			/* external pull-up on Carrier */
> +			AM64X_IOPAD(0x00b4, PIN_INPUT, 7)	/* GPMC0_CSn3.GPIO0_44 */
> +		>;
> +	};
> +
> +	serdes_mux_pins_default: serdes-mux-pins-default {
> +		pinctrl-single,pins = <
> +			/* SEL, 10k pull-down on carrier, 2.2k pullup on SoM */
> +			AM64X_IOPAD(0x0200, PIN_OUTPUT, 7)	/* PRG0_MDIO0_MDIO.GPIO1_40 */
> +			/* EN */
> +			AM64X_IOPAD(0x0204, PIN_OUTPUT, 7)	/* PRG0_MDIO0_MDC.GPIO1_41 */
> +		>;
> +	};
> +};
> +
> +&main_uart3 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&main_uart3_pins_default>;
> +	uart-has-rtscts;
> +	rs485-rts-active-low;
> +	linux,rs485-enabled-at-boot-time;
> +	status = "okay";
> +};
> +
> +&usb0 {
> +	dr_mode = "host";
> +};
> diff --git a/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
> new file mode 100644
> index 000000000000..83b73d433508
> --- /dev/null
> +++ b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
> @@ -0,0 +1,592 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
> + *
> + */
> +
> +#include <dt-bindings/net/ti-dp83869.h>
> +
> +/ {
> +	model = "SolidRun AM642 SoM";
> +	compatible = "solidrun,am642-sr-som", "ti,am642";
> +
> +	aliases {
> +		ethernet0 = &cpsw_port1;
> +		ethernet1 = &icssg1_emac0;
> +		ethernet2 = &icssg1_emac1;
> +		mmc0 = &sdhci0;
> +		mmc1 = &sdhci1;
> +		serial2 = &main_uart0;
> +	};
> +
> +	chosen {
> +		/* SoC default UART console */
> +		stdout-path = "serial2:115200n8";
> +	};
> +
> +	/* PRU Ethernet Controller */
> +	ethernet {
> +		compatible = "ti,am642-icssg-prueth";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pru_rgmii1_pins_default>, <&pru_rgmii2_pins_default>;
> +
> +		sram = <&oc_sram>;
> +		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
> +		firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
> +				"ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
> +				"ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
> +				"ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
> +				"ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
> +				"ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
> +
> +		/* configure internal pinmux for mii mode */
> +		ti,pruss-gp-mux-sel = <2>, <2>, <2>, <2>, <2>, <2>;
> +
> +		ti,mii-g-rt = <&icssg1_mii_g_rt>;
> +		ti,mii-rt = <&icssg1_mii_rt>;
> +		ti,iep = <&icssg1_iep0>, <&icssg1_iep1>;
> +
> +		/*
> +		 * Configure icssg interrupt controller to map pru-internal
> +		 * interrupts 8/9 via channels 0/1 to host interrupts 0/1.
> +		 *
> +		 * For details see interrupt controller documentation:
> +		 * Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
> +		 */
> +		interrupt-parent = <&icssg1_intc>;
> +		interrupts = <24 0 2>, <25 1 3>;
> +		interrupt-names = "tx_ts0", "tx_ts1";
> +
> +		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
> +		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
> +		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
> +		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
> +		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
> +		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
> +		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
> +			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
> +			    "rx0", "rx1";
> +
> +		ethernet-ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			icssg1_emac0: port at 0 {
> +				reg = <0>;
> +				ti,syscon-rgmii-delay = <&main_conf 0x4110>;
> +				/* Filled in by bootloader */
> +				local-mac-address = [00 00 00 00 00 00];
> +				phy-handle = <&ethernet_phy2>;
> +				phy-mode = "rgmii-id";
> +			};
> +
> +			icssg1_emac1: port at 1 {
> +				reg = <1>;
> +				ti,syscon-rgmii-delay = <&main_conf 0x4114>;
> +				/* Filled in by bootloader */
> +				local-mac-address = [00 00 00 00 00 00];
> +				phy-handle = <&ethernet_phy1>;
> +				phy-mode = "rgmii-id";
> +			};
> +		};
> +	};
> +
> +	/* DDR16SS0:
> +	 * - Bank 1 @ 0x080000000-0x0FFFFFFFF: max. 2GB in 32-bit address space
> +	 * - Bank 2 @ 0x880000000-0x9FFFFFFFF: max. 6GB in 64-bit address space
> +	 */
> +	memory at 80000000 {
> +		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
> +		      <0x00000008 0x80000000 0x00000001 0x80000000>;
> +		device_type = "memory";
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		secure_ddr: optee at 9e800000 {
> +			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
> +			no-map;
> +		};
> +
> +		main_r5fss0_core0_dma_memory_region: r5f-dma-memory at a0000000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0x00 0xa0000000 0x00 0x100000>;
> +			no-map;
> +		};
> +
> +		main_r5fss0_core0_memory_region: r5f-memory at a0100000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0x00 0xa0100000 0x00 0xf00000>;
> +			no-map;
> +		};
> +
> +		main_r5fss0_core1_dma_memory_region: r5f-dma-memory at a1000000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0x00 0xa1000000 0x00 0x100000>;
> +			no-map;
> +		};
> +
> +		main_r5fss0_core1_memory_region: r5f-memory at a1100000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0x00 0xa1100000 0x00 0xf00000>;
> +			no-map;
> +		};
> +
> +		main_r5fss1_core0_dma_memory_region: r5f-dma-memory at a2000000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0x00 0xa2000000 0x00 0x100000>;
> +			no-map;
> +		};
> +
> +		main_r5fss1_core0_memory_region: r5f-memory at a2100000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0x00 0xa2100000 0x00 0xf00000>;
> +			no-map;
> +		};
> +
> +		main_r5fss1_core1_dma_memory_region: r5f-dma-memory at a3000000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0x00 0xa3000000 0x00 0x100000>;
> +			no-map;
> +		};
> +
> +		main_r5fss1_core1_memory_region: r5f-memory at a3100000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0x00 0xa3100000 0x00 0xf00000>;
> +			no-map;
> +		};
> +	};
> +
> +	vdd_mmc0: regulator-vdd-mmc0 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vdd-mmc0";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		regulator-always-on;
> +		regulator-boot-on;
> +	};
> +};
> +
> +&cpsw3g {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&rgmii1_pins_default>;
> +};
> +
> +&cpsw3g_mdio {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mdio0_pins_default>;
> +	status = "okay";
> +
> +	ethernet_phy0: ethernet-phy at 0 {
> +		compatible = "ethernet-phy-id2000.a0f1";
> +		reg = <0>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&ethernet_phy0_pins_default>;
> +		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
> +		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
> +		/*
> +		 * Disable interrupts because ISR never clears 0x0040
> +		 *
> +		 * interrupt-parent = <&main_gpio1>;
> +		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
> +		 */
> +		/*
> +		 * Disable HW Reset because clock signal is daisy-chained
> +		 *
> +		 * reset-gpios = <&main_gpio0 84 GPIO_ACTIVE_LOW>;
> +		 * reset-assert-us = <1>;
> +		 * reset-deassert-us = <30>;
> +		 */
> +	};
> +};
> +
> +&cpsw_port1 {
> +	phy-mode = "rgmii-id";
> +	phy-handle = <&ethernet_phy0>;
> +};
> +
> +&cpsw_port2 {
> +	status = "disabled";
> +};
> +
> +&icssg1_mdio {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pru1_mdio0_pins_default>;
> +	status = "okay";
> +
> +	ethernet_phy1: ethernet-phy at 3 {
> +		compatible = "ethernet-phy-id2000.a0f1";
> +		reg = <3>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&ethernet_phy1_pins_default>;
> +		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
> +		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
> +		/*
> +		 * Disable interrupts because ISR never clears 0x0040
> +		 *
> +		 * interrupt-parent = <&main_gpio1>;
> +		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
> +		 */
> +		/*
> +		 * Disable HW Reset because clock signal is daisy-chained
> +		 *
> +		 * reset-gpios = <&main_gpio0 20 GPIO_ACTIVE_LOW>;
> +		 * reset-assert-us = <1>;
> +		 * reset-deassert-us = <30>;
> +		 */
> +	};
> +
> +	ethernet_phy2: ethernet-phy at f {
> +		compatible = "ethernet-phy-id2000.a0f1";
> +		reg = <0xf>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&ethernet_phy2_pins_default>;
> +		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
> +		/*
> +		 * Disable interrupts because ISR never clears 0x0040
> +		 *
> +		 * interrupt-parent = <&main_gpio1>;
> +		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
> +		 */
> +		/*
> +		 * Disable HW Reset because clock signal is daisy-chained
> +		 *
> +		 * reset-gpios = <&main_gpio0 52 GPIO_ACTIVE_LOW>;
> +		 * reset-assert-us = <1>;
> +		 * reset-deassert-us = <30>;
> +		 */
> +	};
> +};
> +
> +&mailbox0_cluster2 {
> +	status = "okay";
> +
> +	mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
> +		ti,mbox-rx = <0 0 2>;
> +		ti,mbox-tx = <1 0 2>;
> +	};
> +
> +	mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
> +		ti,mbox-rx = <2 0 2>;
> +		ti,mbox-tx = <3 0 2>;
> +	};
> +};
> +
> +&mailbox0_cluster4 {
> +	status = "okay";
> +
> +	mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
> +		ti,mbox-rx = <0 0 2>;
> +		ti,mbox-tx = <1 0 2>;
> +	};
> +
> +	mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
> +		ti,mbox-rx = <2 0 2>;
> +		ti,mbox-tx = <3 0 2>;
> +	};
> +};
> +
> +&main_i2c0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&main_i2c0_pins_default>;
> +	status = "okay";
> +
> +	som_eeprom: eeprom at 50 {
> +		compatible = "atmel,24c01";
> +		reg = <0x50>;
> +		pagesize = <8>;
> +	};
> +};
> +
> +&main_pmx0 {
> +	/* hog global functions */
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&ethernet_phy_pins_default>;
> +
> +	ethernet_phy_pins_default: ethernet-phy-pins-default {
> +		pinctrl-single,pins = <
> +			/* interrupt / power-down, external pull-up on SoM */
> +			AM64X_IOPAD(0x0278, PIN_INPUT, 7)	/* EXTINTn.GPIO1_70 */
> +		>;
> +	};
> +
> +	ethernet_phy0_pins_default: ethernet-phy0-pins-default {
> +		pinctrl-single,pins = <
> +			/* reset */
> +			AM64X_IOPAD(0x0154, PIN_OUTPUT, 7)	/* PRG1_PRU1_GPO19.GPIO0_84 */
> +			/* reference clock */
> +			AM64X_IOPAD(0x0274, PIN_OUTPUT, 5)	/* EXT_REFCLK1.CLKOUT0 */
> +		>;
> +	};
> +
> +	ethernet_phy1_pins_default: ethernet-phy1-pins-default {
> +		pinctrl-single,pins = <
> +			/* reset */
> +			AM64X_IOPAD(0x0150, PIN_OUTPUT, 7)	/* PRG1_PRU1_GPO18.GPIO0_20 */
> +			/* led0, external pull-down on SoM */
> +			AM64X_IOPAD(0x0128, PIN_INPUT, 7)	/* PRG1_PRU1_GPO8.GPIO0_73 */
> +			/* led1/rxer */
> +			AM64X_IOPAD(0x011c, PIN_INPUT, 7)	/* PRG1_PRU1_GPO5.GPIO0_70 */
> +		>;
> +	};
> +
> +	ethernet_phy2_pins_default: ethernet-phy2-pins-default {
> +		pinctrl-single,pins = <
> +			/* reset */
> +			AM64X_IOPAD(0x00d4, PIN_OUTPUT, 7)	/* PRG1_PRU0_GPO7.GPIO0_52 */
> +			/* led0, external pull-down on SoM */
> +			AM64X_IOPAD(0x00d8, PIN_INPUT, 7)	/* PRG1_PRU0_GPO8.GPIO0_53 */
> +			/* led1/rxer */
> +			AM64X_IOPAD(0x00cc, PIN_INPUT, 7)	/* PRG1_PRU0_GPO5.GPIO0_50 */
> +		>;
> +	};
> +
> +	main_i2c0_pins_default: main-i2c0-pins-default {
> +		pinctrl-single,pins = <
> +			/* external pull-up on SoM */
> +			AM64X_IOPAD(0x0260, PIN_INPUT, 0)	/* I2C0_SCL.I2C0_SCL */
> +			AM64X_IOPAD(0x0264, PIN_INPUT, 0)	/* I2C0_SDA.I2C0_SDA */
> +		>;
> +	};
> +
> +	/*
> +	 * main_mmc0_pins_default: main-mmc0-pins-default
> +	 *
> +	 * MMC0_CMD: no padconfig
> +	 * MMC0_CLK: no padconfig, external pull-up on SoM
> +	 * MMC0_DAT0: no padconfig
> +	 * MMC0_DAT1: no padconfig
> +	 * MMC0_DAT2: no padconfig
> +	 * MMC0_DAT3: no padconfig
> +	 * MMC0_DAT4: no padconfig
> +	 * MMC0_DAT5: no padconfig
> +	 * MMC0_DAT6: no padconfig
> +	 * MMC0_DAT7: no padconfig
> +	 * MMC0_DS: no padconfig, external pull-down on SoM
> +	 */
> +
> +	main_mmc1_pins_default: main-mmc1-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x0294, PIN_INPUT_PULLUP, 0)	/* (J19) MMC1_CMD */
> +			AM64X_IOPAD(0x028c, PIN_INPUT, 0)		/* MMC1_CLK.MMC1_CLK */
> +			AM64X_IOPAD(0x0288, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT0.MMC1_DAT0 */
> +			AM64X_IOPAD(0x0284, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT1.MMC1_DAT1 */
> +			AM64X_IOPAD(0x0280, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT2.MMC1_DAT2 */
> +			AM64X_IOPAD(0x027c, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT3.MMC1_DAT3 */
> +			/* external pull-down on SoM & Carrier */
> +			AM64X_IOPAD(0x0298, PIN_INPUT_PULLUP, 0)	/* MMC1_SDCD.MMC1_SDCD */
> +			AM64X_IOPAD(0x0290, PIN_INPUT, 0)		/* MMC1_CLKLB: clock loopback */
> +		>;
> +	};
> +
> +	main_uart0_pins_default: main-uart0-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x0230, PIN_INPUT, 0)		/* UART0_RXD.UART0_RXD */
> +			AM64X_IOPAD(0x0234, PIN_OUTPUT, 0)		/* UART0_TXD.UART0_TXD */
> +		>;
> +	};
> +
> +	mdio0_pins_default: mdio0-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x01fc, PIN_OUTPUT, 4)		/* PRG0_PRU1_GPO19.MDIO0_MDC */
> +			AM64X_IOPAD(0x01f8, PIN_INPUT, 4)		/* PRG0_PRU1_GPO18.MDIO0_MDIO */
> +		>;
> +	};
> +
> +	ospi0_pins_default: ospi0-pins-default {
> +		pinctrl-single,pins = <
> +			/* external pull-down on SoM */
> +			AM64X_IOPAD(0x0000, PIN_OUTPUT, 0)		/* OSPI0_CLK.OSPI0_CLK */
> +			AM64X_IOPAD(0x0008, PIN_OUTPUT, 0)		/* OSPI0_DQS.OSPI0_DQS */
> +			/* external pull-up on SoM */
> +			AM64X_IOPAD(0x002c, PIN_OUTPUT, 0)		/* OSPI0_CSn0.OSPI0_CSn0 */
> +			AM64X_IOPAD(0x000c, PIN_INPUT, 0)		/* OSPI0_D0.OSPI0_D0 */
> +			AM64X_IOPAD(0x0010, PIN_INPUT, 0)		/* OSPI0_D1.OSPI0_D1 */
> +			AM64X_IOPAD(0x0014, PIN_INPUT, 0)		/* OSPI0_D2.OSPI0_D2 */
> +			AM64X_IOPAD(0x0018, PIN_INPUT, 0)		/* OSPI0_D3.OSPI0_D3 */
> +			AM64X_IOPAD(0x001c, PIN_INPUT, 0)		/* OSPI0_D4.OSPI0_D4 */
> +			AM64X_IOPAD(0x0020, PIN_INPUT, 0)		/* OSPI0_D5.OSPI0_D5 */
> +			AM64X_IOPAD(0x0024, PIN_INPUT, 0)		/* OSPI0_D6.OSPI0_D6 */
> +			AM64X_IOPAD(0x0028, PIN_INPUT, 0)		/* OSPI0_D7.OSPI0_D7 */
> +		>;
> +	};
> +
> +	ospi0_flash0_pins_default: ospi0-flash0-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x0034, PIN_OUTPUT, 7)		/* OSPI0_CSn2.GPIO0_13 */
> +			AM64X_IOPAD(0x0038, PIN_INPUT, 7)		/* OSPI0_CSn3.GPIO0_14 */
> +		>;
> +	};
> +
> +	pru1_mdio0_pins_default: pru1-mdio0-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0)		/* PRG1_MDIO0_MDC.PRG1_MDIO0_MDC */
> +			AM64X_IOPAD(0x0158, PIN_INPUT, 0)		/* PRG1_MDIO0_MDIO.PRG1_MDIO0_MDIO */
> +		>;
> +	};
> +
> +	pru_rgmii1_pins_default: pru-rgmii1-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x00b8, PIN_INPUT, 2)		/* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
> +			AM64X_IOPAD(0x00bc, PIN_INPUT, 2)		/* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
> +			AM64X_IOPAD(0x00c0, PIN_INPUT, 2)		/* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
> +			AM64X_IOPAD(0x00c4, PIN_INPUT, 2)		/* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
> +			AM64X_IOPAD(0x00d0, PIN_INPUT, 2)		/* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
> +			AM64X_IOPAD(0x00c8, PIN_INPUT, 2)		/* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
> +			AM64X_IOPAD(0x00e4, PIN_OUTPUT, 2)		/* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
> +			AM64X_IOPAD(0x00e8, PIN_OUTPUT, 2)		/* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
> +			AM64X_IOPAD(0x00ec, PIN_OUTPUT, 2)		/* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
> +			AM64X_IOPAD(0x00f0, PIN_OUTPUT, 2)		/* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
> +			AM64X_IOPAD(0x00f8, PIN_INPUT, 2)		/* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
> +			AM64X_IOPAD(0x00f4, PIN_OUTPUT, 2)		/* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
> +		>;
> +	};
> +
> +	pru_rgmii2_pins_default: pru-rgmii2-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x0108, PIN_INPUT, 2)		/* PRG1_PRU1_GPO0.RGMII2_RD0 */
> +			AM64X_IOPAD(0x010c, PIN_INPUT, 2)		/* PRG1_PRU1_GPO1.RGMII2_RD1 */
> +			AM64X_IOPAD(0x0110, PIN_INPUT, 2)		/* PRG1_PRU1_GPO2.RGMII2_RD2 */
> +			AM64X_IOPAD(0x0114, PIN_INPUT, 2)		/* PRG1_PRU1_GPO3.RGMII2_RD3 */
> +			AM64X_IOPAD(0x0120, PIN_INPUT, 2)		/* PRG1_PRU1_GPO6.RGMII2_RXC */
> +			AM64X_IOPAD(0x0118, PIN_INPUT, 2)		/* PRG1_PRU1_GPO4.RGMII2_RX_CTL */
> +			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO11.RGMII2_TD0 */
> +			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO12.RGMII2_TD1 */
> +			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO13.RGMII2_TD2 */
> +			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO14.RGMII2_TD3 */
> +			AM64X_IOPAD(0x0148, PIN_INPUT, 2)		/* PRG1_PRU1_GPO16.RGMII2_TXC */
> +			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO15.RGMII2_TX_CTL */
> +		>;
> +	};
> +
> +	rgmii1_pins_default: rgmii1-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x01cc, PIN_INPUT, 4)		/* PRG0_PRU1_GPO7.RGMII1_RD0 */
> +			AM64X_IOPAD(0x01d4, PIN_INPUT, 4)		/* PRG0_PRU1_GPO9.RGMII1_RD1 */
> +			AM64X_IOPAD(0x01d8, PIN_INPUT, 4)		/* PRG0_PRU1_GPO10.RGMII1_RD2 */
> +			AM64X_IOPAD(0x01f4, PIN_INPUT, 4)		/* PRG0_PRU1_GPO17.RGMII1_RD3 */
> +			AM64X_IOPAD(0x0188, PIN_INPUT, 4)		/* PRG0_PRU0_GPO10.RGMII1_RXC */
> +			AM64X_IOPAD(0x0184, PIN_INPUT, 4)		/* PRG0_PRU0_GPO9.RGMII1_RX_CTL */
> +			AM64X_IOPAD(0x0124, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO7.RGMII1_TD0 */
> +			AM64X_IOPAD(0x012c, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO9.RGMII1_TD1 */
> +			AM64X_IOPAD(0x0130, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO10.RGMII1_TD2 */
> +			AM64X_IOPAD(0x014c, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO17.RGMII1_TD3 */
> +			AM64X_IOPAD(0x00e0, PIN_INPUT, 4)		/* PRG1_PRU0_GPO10.RGMII1_TXC */
> +			AM64X_IOPAD(0x00dc, PIN_OUTPUT, 4)		/* PRG1_PRU0_GPO9.RGMII1_TX_CTL */
> +		>;
> +	};
> +
> +	usb0_pins_default: usb0-pins-default {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0)		/* USB0_DRVVBUS.USB0_DRVVBUS */
> +		>;
> +	};
> +};
> +
> +&main_r5fss0_core0 {
> +	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core0>;
> +	memory-region = <&main_r5fss0_core0_dma_memory_region>,
> +			<&main_r5fss0_core0_memory_region>;
> +};
> +
> +&main_r5fss0_core1 {
> +	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core1>;
> +	memory-region = <&main_r5fss0_core1_dma_memory_region>,
> +			<&main_r5fss0_core1_memory_region>;
> +};
> +
> +&main_r5fss1_core0 {
> +	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core0>;
> +	memory-region = <&main_r5fss1_core0_dma_memory_region>,
> +			<&main_r5fss1_core0_memory_region>;
> +};
> +
> +&main_r5fss1_core1 {
> +	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core1>;
> +	memory-region = <&main_r5fss1_core1_dma_memory_region>,
> +			<&main_r5fss1_core1_memory_region>;
> +};
> +
> +/* SoC default UART console */
> +&main_uart0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&main_uart0_pins_default>;
> +	status = "okay";
> +};
> +
> +&ospi0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&ospi0_pins_default>;
> +	num-cs = <1>;
> +	status = "okay";
> +
> +	flash at 0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&ospi0_flash0_pins_default>;
> +		spi-tx-bus-width = <8>;
> +		spi-rx-bus-width = <8>;
> +		spi-max-frequency = <200000000>;
> +		cdns,tshsl-ns = <50>;
> +		cdns,tsd2d-ns = <50>;
> +		cdns,tchsh-ns = <4>;
> +		cdns,tslch-ns = <4>;
> +		cdns,read-delay = <0>;
> +		interrupt-parent = <&main_gpio0>;
> +		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
> +		reset-gpios = <&main_gpio0 13 GPIO_ACTIVE_LOW>;
> +	};
> +};
> +
> +&sdhci0 {

These sdhci* nodes are disabled by default, you might
want to status = "okay" here. Rule of thumb is if you
needed to add info to the node here in the board file
it probably needs to be enabled here too.

Otherwise LGTM,

Reviewed-by: Andrew Davis <afd at ti.com>

> +	/* mmc0 pins have no padconfig */
> +	bus-width = <8>;
> +	ti,driver-strength-ohm = <50>;
> +	disable-wp;
> +	non-removable;
> +	cap-mmc-hw-reset;
> +	no-sd;
> +	/*
> +	 * MMC controller supports switching between 1.8V and 3.3V signalling.
> +	 * However MMC0 (unlike MMC1) does not integrate an LDO.
> +	 * Explicitly link a regulator node for indicating to the driver which
> +	 * voltages are actually usable.
> +	 */
> +	vqmmc-supply = <&vdd_mmc0>;
> +};
> +
> +/*
> + * microSD is on carrier - however since SoC can boot from it,
> + * configure it just in case.
> + */
> +&sdhci1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&main_mmc1_pins_default>;
> +	bus-width = <4>;
> +	ti,driver-strength-ohm = <50>;
> +	disable-wp;
> +};
> +
> +/*
> + * USB settings are a carrier choice - however since SoC can boot from it,
> + * configure as USB-2.0 OTG here, keeping USB-3 serdes disabled.
> + */
> +&usb0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&usb0_pins_default>;
> +	dr_mode = "otg";
> +	maximum-speed = "high-speed";
> +};
> +
> +&usbss0 {
> +	ti,vbus-divider;
> +	ti,usb2-only;
> +};
> 


From suzuki.poulose at arm.com  Fri Feb  2 09:13:07 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 2 Feb 2024 17:13:07 +0000
Subject: [PATCH v2 02/25] KVM: arm64: Add feature checking helpers
In-Reply-To: <20240130204533.693853-3-maz@kernel.org>
References: <20240130204533.693853-1-maz@kernel.org>
 <20240130204533.693853-3-maz@kernel.org>
Message-ID: <f47909b1-5e10-4149-8d2a-330bd0ceb2e0@arm.com>

Hi Marc,

On 30/01/2024 20:45, Marc Zyngier wrote:
> In order to make it easier to check whether a particular feature
> is exposed to a guest, add a new set of helpers, with kvm_has_feat()
> being the most useful.
> 
> Let's start making use of them in the PMU code (courtesy of Oliver).
> Follow-up work will intricude additional use patterns.

I think there is a bit of inconsistency in the macros for signed
and unsigned. The unsigned fields are extracted (i.e., as if they
were shifted to bit 0). But the signed fields are not shifted completely 
to bit '0' (in fact to different positions) and eventually we compare 
wrong things.

Using ID_AA64PFR0_EL1, fld=EL2, val=IMP for unsigned and
ID_AA64PFR0_EL1, AdvSIMD, NI for signed.

> 
> Co-developed--by: Oliver Upton <oliver.upton at linux.dev>
> Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   arch/arm64/include/asm/kvm_host.h | 53 +++++++++++++++++++++++++++++++
>   arch/arm64/kvm/pmu-emul.c         | 11 ++++---
>   arch/arm64/kvm/sys_regs.c         |  6 ++--
>   include/kvm/arm_pmu.h             | 11 -------
>   4 files changed, 61 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 21c57b812569..c0cf9c5f5e8d 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -1233,4 +1233,57 @@ static inline void kvm_hyp_reserve(void) { }
>   void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
>   bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
>   
> +#define __expand_field_sign_unsigned(id, fld, val)			\
> +	((u64)(id##_##fld##_##val))

For unsigned features we get the actual "field" value, not the value in 
position. e.g,: ID_AA64PFR0_EL1_EL2_IMP = (0x1)

> +
> +#define __expand_field_sign_signed(id, fld, val)			\
> +	({								\
> +		s64 __val = id##_##fld##_##val;				\
> +		__val <<= 64 - id##_##fld##_WIDTH;			\
> +		__val >>= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\

But for signed fields, we shift them back into the "position" as in the 
ID_REG. e.g.,

ID_AA64PFR0_EL1, AdvSIMD, NI we get:

	__val = ID_AA64PFR0_EL1_AdvSIMD_NI; /* = 0xf */
	__val <<= 64 - 4;		/* 0xf0_00_00_00_00_00_00_00 */
	__val >>= 64 - 20 - 4;		/* 0xff_ff_ff_ff_ff_f0_00_00 */

I think the last line instead should be:
	__val >>= 64 - id##_##fld##_WIDTH;

> +									\
> +		__val;							\
> +	})
> +
> +#define expand_field_sign(id, fld, val)					\
> +	(id##_##fld##_SIGNED ?						\
> +	 __expand_field_sign_signed(id, fld, val) :			\
> +	 __expand_field_sign_unsigned(id, fld, val))
> +
> +#define get_idreg_field_unsigned(kvm, id, fld)				\
> +	({								\
> +		u64 __val = IDREG(kvm, SYS_##id);			\
> +		__val &= id##_##fld##_MASK;				\
> +		__val >>= id##_##fld##_SHIFT;				\
> +									\

We extract the field value for unsigned field, i.e., shifted to bit"0" 
and that matches the expand_field_sign().

> +		__val;							\
> +	})
> +
> +#define get_idreg_field_signed(kvm, id, fld)				\
> +	({								\
> +		s64 __val = IDREG(kvm, SYS_##id);			\
> +		__val <<= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
> +		__val >>= id##_##fld##_SHIFT;				\

However, here we get (assuming value ID_AA64PFR0_EL1_ASIMD = 0xf, and
all other fields are 0 for clarity)
	
	__val = IDREG(kvm, SYS_ID_AA64PFR0_EL1); = 0xf0_00_00; 	/* 0xf << 20 */
	__val <<= 64 - 20 - 4;	/* = 0xf0_00_00_00_00_00_00_00 */
	__val >>= 20;		/* = 0xff_ff_ff_00_00_00_00_00 */

Thus they don;t match. Instead the last line should be :

	__val >>= id##_##fld##_WIDTH;


Suzuki


> +									\
> +		__val;							\
> +	})
> +
> +#define get_idreg_field_enum(kvm, id, fld)				\
> +	get_idreg_field_unsigned(kvm, id, fld)
> +
> +#define get_idreg_field(kvm, id, fld)					\
> +	(id##_##fld##_SIGNED ?						\
> +	 get_idreg_field_signed(kvm, id, fld) :				\
> +	 get_idreg_field_unsigned(kvm, id, fld))
> +
> +#define kvm_has_feat(kvm, id, fld, limit)				\
> +	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit))
> +
> +#define kvm_has_feat_enum(kvm, id, fld, limit)				\
> +	(get_idreg_field_unsigned((kvm), id, fld) == id##_##fld##_##limit)
> +
> +#define kvm_has_feat_range(kvm, id, fld, min, max)			\
> +	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
> +	 get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
> +
>   #endif /* __ARM64_KVM_HOST_H__ */
> diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> index 3d9467ff73bc..925522470b2b 100644
> --- a/arch/arm64/kvm/pmu-emul.c
> +++ b/arch/arm64/kvm/pmu-emul.c
> @@ -64,12 +64,11 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm)
>   {
>   	u64 mask = ARMV8_PMU_EXCLUDE_EL1 | ARMV8_PMU_EXCLUDE_EL0 |
>   		   kvm_pmu_event_mask(kvm);
> -	u64 pfr0 = IDREG(kvm, SYS_ID_AA64PFR0_EL1);
>   
> -	if (SYS_FIELD_GET(ID_AA64PFR0_EL1, EL2, pfr0))
> +	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL2, IMP))
>   		mask |= ARMV8_PMU_INCLUDE_EL2;
>   
> -	if (SYS_FIELD_GET(ID_AA64PFR0_EL1, EL3, pfr0))
> +	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL3, IMP))
>   		mask |= ARMV8_PMU_EXCLUDE_NS_EL0 |
>   			ARMV8_PMU_EXCLUDE_NS_EL1 |
>   			ARMV8_PMU_EXCLUDE_EL3;
> @@ -83,8 +82,10 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm)
>    */
>   static bool kvm_pmc_is_64bit(struct kvm_pmc *pmc)
>   {
> +	struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc);
> +
>   	return (pmc->idx == ARMV8_PMU_CYCLE_IDX ||
> -		kvm_pmu_is_3p5(kvm_pmc_to_vcpu(pmc)));
> +		kvm_has_feat(vcpu->kvm, ID_AA64DFR0_EL1, PMUVer, V3P5));
>   }
>   
>   static bool kvm_pmc_has_64bit_overflow(struct kvm_pmc *pmc)
> @@ -556,7 +557,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val)
>   		return;
>   
>   	/* Fixup PMCR_EL0 to reconcile the PMU version and the LP bit */
> -	if (!kvm_pmu_is_3p5(vcpu))
> +	if (!kvm_has_feat(vcpu->kvm, ID_AA64DFR0_EL1, PMUVer, V3P5))
>   		val &= ~ARMV8_PMU_PMCR_LP;
>   
>   	/* The reset bits don't indicate any state, and shouldn't be saved. */
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 041b11825578..3c31f8cb9eef 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -505,10 +505,9 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
>   			  struct sys_reg_params *p,
>   			  const struct sys_reg_desc *r)
>   {
> -	u64 val = IDREG(vcpu->kvm, SYS_ID_AA64MMFR1_EL1);
>   	u32 sr = reg_to_encoding(r);
>   
> -	if (!(val & (0xfUL << ID_AA64MMFR1_EL1_LO_SHIFT))) {
> +	if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR1_EL1, LO, IMP)) {
>   		kvm_inject_undefined(vcpu);
>   		return false;
>   	}
> @@ -2748,8 +2747,7 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
>   		return ignore_write(vcpu, p);
>   	} else {
>   		u64 dfr = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1);
> -		u64 pfr = IDREG(vcpu->kvm, SYS_ID_AA64PFR0_EL1);
> -		u32 el3 = !!SYS_FIELD_GET(ID_AA64PFR0_EL1, EL3, pfr);
> +		u32 el3 = kvm_has_feat(vcpu->kvm, ID_AA64PFR0_EL1, EL3, IMP);
>   
>   		p->regval = ((SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr) << 28) |
>   			     (SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, dfr) << 24) |
> diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
> index 4b9d8fb393a8..eb4c369a79eb 100644
> --- a/include/kvm/arm_pmu.h
> +++ b/include/kvm/arm_pmu.h
> @@ -90,16 +90,6 @@ void kvm_vcpu_pmu_resync_el0(void);
>   			vcpu->arch.pmu.events = *kvm_get_pmu_events();	\
>   	} while (0)
>   
> -/*
> - * Evaluates as true when emulating PMUv3p5, and false otherwise.
> - */
> -#define kvm_pmu_is_3p5(vcpu) ({						\
> -	u64 val = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1);		\
> -	u8 pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer, val);	\
> -									\
> -	pmuver >= ID_AA64DFR0_EL1_PMUVer_V3P5;				\
> -})
> -
>   u8 kvm_arm_pmu_get_pmuver_limit(void);
>   u64 kvm_pmu_evtyper_mask(struct kvm *kvm);
>   int kvm_arm_set_default_pmu(struct kvm *kvm);
> @@ -168,7 +158,6 @@ static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
>   }
>   
>   #define kvm_vcpu_has_pmu(vcpu)		({ false; })
> -#define kvm_pmu_is_3p5(vcpu)		({ false; })
>   static inline void kvm_pmu_update_vcpu_events(struct kvm_vcpu *vcpu) {}
>   static inline void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) {}
>   static inline void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) {}



From rafael at kernel.org  Fri Feb  2 09:13:41 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Fri, 2 Feb 2024 18:13:41 +0100
Subject: [PATCH v1 02/18] thermal: Add new structures and thermal_zone_device_register()
In-Reply-To: <e4359d2c-e686-4a97-9d21-d10908e9df61@moroto.mountain>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
 <20240130111250.185718-3-angelogioacchino.delregno@collabora.com>
 <CAJZ5v0jzaGpK8LnsFDtjuPoURrwrUgM1Z2QfZhK_FUzDeK3wcw@mail.gmail.com> <e4359d2c-e686-4a97-9d21-d10908e9df61@moroto.mountain>
Message-ID: <CAJZ5v0iYNPB2v7ZCynEOvWy+gz4DQUhuoJ8e7F1MXz13m_d7rw@mail.gmail.com>

On Fri, Feb 2, 2024 at 9:47?AM Dan Carpenter <dan.carpenter at linaro.org> wrote:
>
> On Thu, Feb 01, 2024 at 08:24:15PM +0100, Rafael J. Wysocki wrote:
> > On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
> > > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > > index 65d8f92a9a0d..7a540b746703 100644
> > > --- a/include/linux/thermal.h
> > > +++ b/include/linux/thermal.h
> > > @@ -149,7 +149,8 @@ struct thermal_cooling_device {
> > >                         passive trip point.
> > >   * @need_update:       if equals 1, thermal_zone_device_update needs to be invoked.
> > >   * @ops:       operations this &thermal_zone_device supports
> > > - * @tzp:       thermal zone parameters
> > > + * @tzp:               Thermal zone parameters
> > > + * @tgp:               Thermal zone governor parameters
> > >   * @governor:  pointer to the governor for this thermal zone
> > >   * @governor_data:     private pointer for governor data
> > >   * @thermal_instances: list of &struct thermal_instance of this thermal zone
> > > @@ -184,7 +185,8 @@ struct thermal_zone_device {
> > >         int prev_high_trip;
> > >         atomic_t need_update;
> > >         struct thermal_zone_device_ops *ops;
> > > -       struct thermal_zone_params *tzp;
> > > +       struct thermal_zone_platform_params *tzp;
> > > +       struct thermal_governor_params *tgp;
> >
> > I agree with doing a split here, but I'm not sure about moving items
> > from the arg list to struct thermal_zone_platform_params (as mentioned
> > above).
> >
> > Also the naming is quite inconsistent.  IMO it would be better to call
> > the first pointer "tzpp", rename struct thermal_governor_params to
> > struct thermal_zone_governor_params and call the second pointer
> > "tzgp".
> >
>
> The names "tzgp" and "tzpp" look almost identical at first glance.
> Could we increase the hamming distance somehow?

Good point.

They may as well be gov_params and platform_params AFAIAC.


From oliver.upton at linux.dev  Fri Feb  2 09:15:51 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 2 Feb 2024 17:15:51 +0000
Subject: [PATCH v2 06/25] KVM: arm64: nv: Add sanitising to VNCR-backed
 HCRX_EL2
In-Reply-To: <86h6iq7w3x.wl-maz@kernel.org>
References: <20240130204533.693853-1-maz@kernel.org>
 <20240130204533.693853-7-maz@kernel.org>
 <ZbytUKPFYiP2cdd8@linux.dev>
 <86h6iq7w3x.wl-maz@kernel.org>
Message-ID: <Zb0jRzTYyc0IxR00@linux.dev>

On Fri, Feb 02, 2024 at 02:56:50PM +0000, Marc Zyngier wrote:
> No amount of warnings will do, because people don't give a damn.
> 
> I'm actually in favour of something far more radical: we snapshot the
> raw value of all the used RES0/1, and put BUILD_BUG_ON()s that fire if
> any value has changed. They will have to touch the KVM code to fix
> that, and we catch them red-handed.

Oh I like that a lot more.

> > 
> > > +	if (!kvm_has_feat(kvm, ID_AA64ISAR3_EL1, PACM, TRIVIAL_IMP))
> > > +		res0 |= HCRX_EL2_PACMEn;
> > > +	if (!kvm_has_feat(kvm, ID_AA64PFR2_EL1, FPMR, IMP))
> > > +		res0 |= HCRX_EL2_EnFPM;
> > > +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
> > > +		res0 |= HCRX_EL2_GCSEn;
> > > +	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, SYSREG_128, IMP))
> > > +		res0 |= HCRX_EL2_EnIDCP128;
> > > +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, ADERR, DEV_ASYNC))
> > > +		res0 |= (HCRX_EL2_EnSDERR | HCRX_EL2_EnSNERR);
> > > +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, DF2, IMP))
> > > +		res0 |= HCRX_EL2_TMEA;
> > > +	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, D128, IMP))
> > > +		res0 |= HCRX_EL2_D128En;
> > > +	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
> > > +		res0 |= HCRX_EL2_PTTWI;
> > 
> > Ok, not fair. The latest public version of the ARM ARM doesn't have any
> > of this. Where are you getting it from?
> 
> The bloody XML, from which all of this should, in theory, be extracted
> without any human intervention. Sadly, it seems that we are not
> allowed to do so, from what I have been told.
> 
> The ARM ARM is, unfortunately, being quickly rendered obsolete by the
> lack of updates (FEAT_THE is part of the v9.4 architecture, released
> in 2022).

Ah, got it. Thanks both for the reference. That really sucks though!

-- 
Thanks,
Oliver


From sjg at chromium.org  Fri Feb  2 09:30:33 2024
From: sjg at chromium.org (Simon Glass)
Date: Fri,  2 Feb 2024 10:30:33 -0700
Subject: [PATCH v10 1/2] arm64: Add BOOT_TARGETS variable
In-Reply-To: <20240202173034.221790-1-sjg@chromium.org>
References: <20240202173034.221790-1-sjg@chromium.org>
Message-ID: <20240202173034.221790-2-sjg@chromium.org>

Add a new variable containing a list of possible targets. Mark them as
phony. This matches the approach taken for arch/arm

Signed-off-by: Simon Glass <sjg at chromium.org>
---

(no changes since v7)

Changes in v7:
- Drop the kbuild tag

Changes in v6:
- Drop the unwanted .gz suffix

 arch/arm64/Makefile | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 47ecc4cff9d2..83cd2b7234b9 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -150,6 +150,10 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 # Default target when executing plain make
 boot		:= arch/arm64/boot
 
+BOOT_TARGETS	:= Image vmlinuz.efi
+
+PHONY += $(BOOT_TARGETS)
+
 ifeq ($(CONFIG_EFI_ZBOOT),)
 KBUILD_IMAGE	:= $(boot)/Image.gz
 else
@@ -159,7 +163,7 @@ endif
 all:	$(notdir $(KBUILD_IMAGE))
 
 vmlinuz.efi: Image
-Image vmlinuz.efi: vmlinux
+$(BOOT_TARGETS): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 Image.%: Image
-- 
2.34.1



From sjg at chromium.org  Fri Feb  2 09:30:32 2024
From: sjg at chromium.org (Simon Glass)
Date: Fri,  2 Feb 2024 10:30:32 -0700
Subject: [PATCH v10 0/2] arm64: Add a build target for Flat Image Tree
Message-ID: <20240202173034.221790-1-sjg@chromium.org>

Flat Image Tree (FIT) is a widely used file format for packaging a
kernel and associated devicetree files[1]. It is not specific to any
one bootloader, as it is supported by U-Boot, coreboot, Linuxboot,
Tianocore and Barebox.

This series adds support for building a FIT as part of the kernel
build. This makes it easy to try out the kernel - just load the FIT
onto your tftp server and it will run automatically on any supported
arm64 board.

The script is written in Python, since it is easy to build a FIT using
the Python libfdt bindings. For now, no attempt is made to compress
files in parallel, so building the 900-odd files takes a while, about
6 seconds with my testing.

The series also includes a minor clean-up patch.

[1] https://github.com/open-source-firmware/flat-image-tree

Changes in v10:
- Make use of dtbs-list file
- Mention dtbs-list and FIT_COMPRESSION
- Update copyright year
- Update cover letter to take account of an applied patch

Changes in v9:
- Move the compression control into Makefile.lib

Changes in v8:
- Drop compatible string in FDT node
- Correct sorting of MAINTAINERS to before ARM64 PORT
- Turn compress part of the make_fit.py comment in to a sentence
- Add two blank lines before parse_args() and setup_fit()
- Use 'image.fit: dtbs' instead of BUILD_DTBS var
- Use '$(<D)/dts' instead of '$(dir $<)dts'
- Add 'mkimage' details Documentation/process/changes.rst
- Allow changing the compression used
- Tweak cover letter since there is only one clean-up patch

Changes in v7:
- Drop the kbuild tag
- Add Image as a dependency of image.fit
- Drop kbuild tag
- Add dependency on dtbs
- Drop unnecessary path separator for dtbs
- Rebase to -next

Changes in v6:
- Drop the unwanted .gz suffix

Changes in v5:
- Drop patch previously applied
- Correct compression rule which was broken in v4

Changes in v4:
- Use single quotes for UIMAGE_NAME

Changes in v3:
- Drop temporary file image.itk
- Drop patch 'Use double quotes for image name'
- Drop double quotes in use of UIMAGE_NAME
- Drop unnecessary CONFIG_EFI_ZBOOT condition for help
- Avoid hard-coding "arm64" for the DT architecture

Changes in v2:
- Drop patch previously applied
- Add .gitignore file
- Move fit rule to Makefile.lib using an intermediate file
- Drop dependency on CONFIG_EFI_ZBOOT
- Pick up .dtb files separately from the kernel
- Correct pylint too-many-args warning for write_kernel()
- Include the kernel image in the file count
- Add a pointer to the FIT spec and mention of its wide industry usage
- Mention the kernel version in the FIT description

Simon Glass (2):
  arm64: Add BOOT_TARGETS variable
  arm64: boot: Support Flat Image Tree

 Documentation/process/changes.rst |   9 +
 MAINTAINERS                       |   7 +
 arch/arm64/Makefile               |  11 +-
 arch/arm64/boot/.gitignore        |   1 +
 arch/arm64/boot/Makefile          |   6 +-
 scripts/Makefile.lib              |  16 ++
 scripts/make_fit.py               | 298 ++++++++++++++++++++++++++++++
 7 files changed, 345 insertions(+), 3 deletions(-)
 create mode 100755 scripts/make_fit.py

-- 
2.34.1



From sjg at chromium.org  Fri Feb  2 09:30:34 2024
From: sjg at chromium.org (Simon Glass)
Date: Fri,  2 Feb 2024 10:30:34 -0700
Subject: [PATCH v10 2/2] arm64: boot: Support Flat Image Tree
In-Reply-To: <20240202173034.221790-1-sjg@chromium.org>
References: <20240202173034.221790-1-sjg@chromium.org>
Message-ID: <20240202173034.221790-3-sjg@chromium.org>

Add a script which produces a Flat Image Tree (FIT), a single file
containing the built kernel and associated devicetree files.
Compression defaults to gzip which gives a good balance of size and
performance.

The files compress from about 86MB to 24MB using this approach.

The FIT can be used by bootloaders which support it, such as U-Boot
and Linuxboot. It permits automatic selection of the correct
devicetree, matching the compatible string of the running board with
the closest compatible string in the FIT. There is no need for
filenames or other workarounds.

Add a 'make image.fit' build target for arm64, as well.

The FIT can be examined using 'dumpimage -l'.

This uses the 'dtbs-list' file but processes only .dtb files, ignoring
the overlay .dtbo files.

This features requires pylibfdt (use 'pip install libfdt'). It also
requires compression utilities for the algorithm being used. Supported
compression options are the same as the Image.xxx files. Use
FIT_COMPRESSION to select an algorithm other than gzip.

While FIT supports a ramdisk / initrd, no attempt is made to support
this here, since it must be built separately from the Linux build.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v10:
- Make use of dtbs-list file
- Mention dtbs-list and FIT_COMPRESSION
- Update copyright year
- Update cover letter to take account of an applied patch

Changes in v9:
- Move the compression control into Makefile.lib

Changes in v8:
- Drop compatible string in FDT node
- Correct sorting of MAINTAINERS to before ARM64 PORT
- Turn compress part of the make_fit.py comment in to a sentence
- Add two blank lines before parse_args() and setup_fit()
- Use 'image.fit: dtbs' instead of BUILD_DTBS var
- Use '$(<D)/dts' instead of '$(dir $<)dts'
- Add 'mkimage' details Documentation/process/changes.rst
- Allow changing the compression used
- Tweak cover letter since there is only one clean-up patch

Changes in v7:
- Add Image as a dependency of image.fit
- Drop kbuild tag
- Add dependency on dtbs
- Drop unnecessary path separator for dtbs
- Rebase to -next

Changes in v5:
- Drop patch previously applied
- Correct compression rule which was broken in v4

Changes in v4:
- Use single quotes for UIMAGE_NAME

Changes in v3:
- Drop temporary file image.itk
- Drop patch 'Use double quotes for image name'
- Drop double quotes in use of UIMAGE_NAME
- Drop unnecessary CONFIG_EFI_ZBOOT condition for help
- Avoid hard-coding "arm64" for the DT architecture

Changes in v2:
- Drop patch previously applied
- Add .gitignore file
- Move fit rule to Makefile.lib using an intermediate file
- Drop dependency on CONFIG_EFI_ZBOOT
- Pick up .dtb files separately from the kernel
- Correct pylint too-many-args warning for write_kernel()
- Include the kernel image in the file count
- Add a pointer to the FIT spec and mention of its wide industry usage
- Mention the kernel version in the FIT description

 Documentation/process/changes.rst |   9 +
 MAINTAINERS                       |   7 +
 arch/arm64/Makefile               |   7 +-
 arch/arm64/boot/.gitignore        |   1 +
 arch/arm64/boot/Makefile          |   6 +-
 scripts/Makefile.lib              |  16 ++
 scripts/make_fit.py               | 298 ++++++++++++++++++++++++++++++
 7 files changed, 341 insertions(+), 3 deletions(-)
 create mode 100755 scripts/make_fit.py

diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
index 50b3d1cb1115..a8110965e4e1 100644
--- a/Documentation/process/changes.rst
+++ b/Documentation/process/changes.rst
@@ -62,6 +62,7 @@ Sphinx\ [#f1]_         2.4.4            sphinx-build --version
 cpio                   any              cpio --version
 GNU tar                1.28             tar --version
 gtags (optional)       6.6.5            gtags --version
+mkimage (optional)     2017.01          mkimage --version
 ====================== ===============  ========================================
 
 .. [#f1] Sphinx is needed only to build the Kernel documentation
@@ -189,6 +190,14 @@ The kernel build requires GNU GLOBAL version 6.6.5 or later to generate
 tag files through ``make gtags``.  This is due to its use of the gtags
 ``-C (--directory)`` flag.
 
+mkimage
+-------
+
+This tool is used when building a Flat Image Tree (FIT), commonly used on ARM
+platforms. The tool is available via the ``u-boot-tools`` package or can be
+built from the U-Boot source code. See the instructions at
+https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
+
 System utilities
 ****************
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 61117c3afa80..10c2753d7bcc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3026,6 +3026,13 @@ F:	drivers/mmc/host/sdhci-of-arasan.c
 N:	zynq
 N:	xilinx
 
+ARM64 FIT SUPPORT
+M:	Simon Glass <sjg at chromium.org>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	arch/arm64/boot/Makefile
+F:	scripts/make_fit.py
+
 ARM64 PORT (AARCH64 ARCHITECTURE)
 M:	Catalin Marinas <catalin.marinas at arm.com>
 M:	Will Deacon <will at kernel.org>
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 83cd2b7234b9..5de2b02f549a 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -150,7 +150,7 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 # Default target when executing plain make
 boot		:= arch/arm64/boot
 
-BOOT_TARGETS	:= Image vmlinuz.efi
+BOOT_TARGETS	:= Image vmlinuz.efi image.fit
 
 PHONY += $(BOOT_TARGETS)
 
@@ -162,7 +162,9 @@ endif
 
 all:	$(notdir $(KBUILD_IMAGE))
 
-vmlinuz.efi: Image
+image.fit: dtbs
+
+vmlinuz.efi image.fit: Image
 $(BOOT_TARGETS): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
@@ -215,6 +217,7 @@ virtconfig:
 define archhelp
   echo  '* Image.gz      - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
   echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
+  echo  '  image.fit     - Flat Image Tree (arch/$(ARCH)/boot/image.fit)'
   echo  '  install       - Install uncompressed kernel'
   echo  '  zinstall      - Install compressed kernel'
   echo  '                  Install using (your) ~/bin/installkernel or'
diff --git a/arch/arm64/boot/.gitignore b/arch/arm64/boot/.gitignore
index af5dc61f8b43..abaae9de1bdd 100644
--- a/arch/arm64/boot/.gitignore
+++ b/arch/arm64/boot/.gitignore
@@ -2,3 +2,4 @@
 Image
 Image.gz
 vmlinuz*
+image.fit
diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
index a5a787371117..ab21af82913e 100644
--- a/arch/arm64/boot/Makefile
+++ b/arch/arm64/boot/Makefile
@@ -16,7 +16,8 @@
 
 OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
 
-targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo Image.zst
+targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo \
+	Image.zst image.fit
 
 $(obj)/Image: vmlinux FORCE
 	$(call if_changed,objcopy)
@@ -39,6 +40,9 @@ $(obj)/Image.lzo: $(obj)/Image FORCE
 $(obj)/Image.zst: $(obj)/Image FORCE
 	$(call if_changed,zstd)
 
+$(obj)/image.fit: $(obj)/Image FORCE
+	$(call cmd,fit)
+
 EFI_ZBOOT_PAYLOAD	:= Image
 EFI_ZBOOT_BFD_TARGET	:= elf64-littleaarch64
 EFI_ZBOOT_MACH_TYPE	:= ARM64
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index b35d39022a30..4efb5ad07fd7 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -502,6 +502,22 @@ quiet_cmd_uimage = UIMAGE  $@
 			-a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \
 			-n '$(UIMAGE_NAME)' -d $< $@
 
+# Flat Image Tree (FIT)
+# This allows for packaging of a kernel and all devicetrees files, using
+# compression.
+# ---------------------------------------------------------------------------
+
+MAKE_FIT := $(srctree)/scripts/make_fit.py
+
+# Use this to override the compression algorithm
+FIT_COMPRESSION ?= gzip
+
+quiet_cmd_fit = FIT     $@
+      cmd_fit = $(MAKE_FIT) -f $@ --arch $(UIMAGE_ARCH) --os linux \
+			--name '$(UIMAGE_NAME)' \
+			--compress $(FIT_COMPRESSION) -k $< \
+			@arch/$(SRCARCH)/boot/dts/dtbs-list
+
 # XZ
 # ---------------------------------------------------------------------------
 # Use xzkern to compress the kernel image and xzmisc to compress other things.
diff --git a/scripts/make_fit.py b/scripts/make_fit.py
new file mode 100755
index 000000000000..69eee32960ae
--- /dev/null
+++ b/scripts/make_fit.py
@@ -0,0 +1,298 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2024 Google LLC
+# Written by Simon Glass <sjg at chromium.org>
+#
+
+"""Build a FIT containing a lot of devicetree files
+
+Usage:
+    make_fit.py -A arm64 -n 'Linux-6.6' -O linux
+        -f arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk
+        @arch/arm64/boot/dts/dtbs-list -E -c gzip
+
+Creates a FIT containing the supplied kernel and a set of devicetree files,
+either specified individually or listed in a file (with an '@' prefix). Files
+which don't end in '.dtb' are silently ignored.
+
+Use -E to generate an external FIT (where the data is placed after the
+FIT data structure). This allows parsing of the data without loading
+the entire FIT.
+
+Use -c to compress the data, using bzip2, gzip, lz4, lzma, lzo and
+zstd algorithms.
+
+The resulting FIT can be booted by bootloaders which support FIT, such
+as U-Boot, Linuxboot, Tianocore, etc.
+
+Note that this tool does not yet support adding a ramdisk / initrd.
+"""
+
+import argparse
+import collections
+import os
+import subprocess
+import sys
+import tempfile
+import time
+
+import libfdt
+
+
+# Tool extension and the name of the command-line tools
+CompTool = collections.namedtuple('CompTool', 'ext,tools')
+
+COMP_TOOLS = {
+    'bzip2': CompTool('.bz2', 'bzip2'),
+    'gzip': CompTool('.gz', 'pigz,gzip'),
+    'lz4': CompTool('.lz4', 'lz4'),
+    'lzma': CompTool('.lzma', 'lzma'),
+    'lzo': CompTool('.lzo', 'lzop'),
+    'zstd': CompTool('.zstd', 'zstd'),
+}
+
+
+def parse_args():
+    """Parse the program ArgumentParser
+
+    Returns:
+        Namespace object containing the arguments
+    """
+    epilog = 'Build a FIT from a directory tree containing .dtb files'
+    parser = argparse.ArgumentParser(epilog=epilog)
+    parser.add_argument('-A', '--arch', type=str, required=True,
+          help='Specifies the architecture')
+    parser.add_argument('-c', '--compress', type=str, default='none',
+          help='Specifies the compression')
+    parser.add_argument('-E', '--external', action='store_true',
+          help='Convert the FIT to use external data')
+    parser.add_argument('-n', '--name', type=str, required=True,
+          help='Specifies the name')
+    parser.add_argument('-O', '--os', type=str, required=True,
+          help='Specifies the operating system')
+    parser.add_argument('-f', '--fit', type=str, required=True,
+          help='Specifies the output file (.fit)')
+    parser.add_argument('-k', '--kernel', type=str, required=True,
+          help='Specifies the (uncompressed) kernel input file (.itk)')
+    parser.add_argument('srcdir', type=str, nargs='*',
+          help='Specifies the directory tree that contains .dtb files')
+
+    return parser.parse_args()
+
+
+def setup_fit(fsw, name):
+    """Make a start on writing the FIT
+
+    Outputs the root properties and the 'images' node
+
+    Args:
+        fsw (libfdt.FdtSw): Object to use for writing
+        name (str): Name of kernel image
+    """
+    fsw.INC_SIZE = 65536
+    fsw.finish_reservemap()
+    fsw.begin_node('')
+    fsw.property_string('description', f'{name} with devicetree set')
+    fsw.property_u32('#address-cells', 1)
+
+    fsw.property_u32('timestamp', int(time.time()))
+    fsw.begin_node('images')
+
+
+def write_kernel(fsw, data, args):
+    """Write out the kernel image
+
+    Writes a kernel node along with the required properties
+
+    Args:
+        fsw (libfdt.FdtSw): Object to use for writing
+        data (bytes): Data to write (possibly compressed)
+        args (Namespace): Contains necessary strings:
+            arch: FIT architecture, e.g. 'arm64'
+            fit_os: Operating Systems, e.g. 'linux'
+            name: Name of OS, e.g. 'Linux-6.6.0-rc7'
+            compress: Compression algorithm to use, e.g. 'gzip'
+    """
+    with fsw.add_node('kernel'):
+        fsw.property_string('description', args.name)
+        fsw.property_string('type', 'kernel_noload')
+        fsw.property_string('arch', args.arch)
+        fsw.property_string('os', args.os)
+        fsw.property_string('compression', args.compress)
+        fsw.property('data', data)
+        fsw.property_u32('load', 0)
+        fsw.property_u32('entry', 0)
+
+
+def finish_fit(fsw, entries):
+    """Finish the FIT ready for use
+
+    Writes the /configurations node and subnodes
+
+    Args:
+        fsw (libfdt.FdtSw): Object to use for writing
+        entries (list of tuple): List of configurations:
+            str: Description of model
+            str: Compatible stringlist
+    """
+    fsw.end_node()
+    seq = 0
+    with fsw.add_node('configurations'):
+        for model, compat in entries:
+            seq += 1
+            with fsw.add_node(f'conf-{seq}'):
+                fsw.property('compatible', bytes(compat))
+                fsw.property_string('description', model)
+                fsw.property_string('fdt', f'fdt-{seq}')
+                fsw.property_string('kernel', 'kernel')
+    fsw.end_node()
+
+
+def compress_data(inf, compress):
+    """Compress data using a selected algorithm
+
+    Args:
+        inf (IOBase): Filename containing the data to compress
+        compress (str): Compression algorithm, e.g. 'gzip'
+
+    Return:
+        bytes: Compressed data
+    """
+    if compress == 'none':
+        return inf.read()
+
+    comp = COMP_TOOLS.get(compress)
+    if not comp:
+        raise ValueError(f"Unknown compression algorithm '{compress}'")
+
+    with tempfile.NamedTemporaryFile() as comp_fname:
+        with open(comp_fname.name, 'wb') as outf:
+            done = False
+            for tool in comp.tools.split(','):
+                try:
+                    subprocess.call([tool, '-c'], stdin=inf, stdout=outf)
+                    done = True
+                    break
+                except FileNotFoundError:
+                    pass
+            if not done:
+                raise ValueError(f'Missing tool(s): {comp.tools}\n')
+            with open(comp_fname.name, 'rb') as compf:
+                comp_data = compf.read()
+    return comp_data
+
+
+def output_dtb(fsw, seq, fname, arch, compress):
+    """Write out a single devicetree to the FIT
+
+    Args:
+        fsw (libfdt.FdtSw): Object to use for writing
+        seq (int): Sequence number (1 for first)
+        fmame (str): Filename containing the DTB
+        arch: FIT architecture, e.g. 'arm64'
+        compress (str): Compressed algorithm, e.g. 'gzip'
+
+    Returns:
+        tuple:
+            str: Model name
+            bytes: Compatible stringlist
+    """
+    with fsw.add_node(f'fdt-{seq}'):
+        # Get the compatible / model information
+        with open(fname, 'rb') as inf:
+            data = inf.read()
+        fdt = libfdt.FdtRo(data)
+        model = fdt.getprop(0, 'model').as_str()
+        compat = fdt.getprop(0, 'compatible')
+
+        fsw.property_string('description', model)
+        fsw.property_string('type', 'flat_dt')
+        fsw.property_string('arch', arch)
+        fsw.property_string('compression', compress)
+        fsw.property('compatible', bytes(compat))
+
+        with open(fname, 'rb') as inf:
+            compressed = compress_data(inf, compress)
+        fsw.property('data', compressed)
+    return model, compat
+
+
+def build_fit(args):
+    """Build the FIT from the provided files and arguments
+
+    Args:
+        args (Namespace): Program arguments
+
+    Returns:
+        tuple:
+            bytes: FIT data
+            int: Number of configurations generated
+            size: Total uncompressed size of data
+    """
+    def add_file(fname):
+        nonlocal seq, size
+
+        if os.path.splitext(fname)[1] == '.dtb':
+            seq += 1
+            size += os.path.getsize(fname)
+            model, compat = output_dtb(fsw, seq, fname, args.arch,
+                                       args.compress)
+            entries.append([model, compat])
+            return True
+
+    seq = 0
+    size = 0
+    fsw = libfdt.FdtSw()
+    setup_fit(fsw, args.name)
+    entries = []
+
+    # Handle the kernel
+    with open(args.kernel, 'rb') as inf:
+        comp_data = compress_data(inf, args.compress)
+    size += os.path.getsize(args.kernel)
+    write_kernel(fsw, comp_data, args)
+
+    for path in args.srcdir:
+        # Handle a list of devicetree files
+        if path.startswith('@'):
+            with open(path[1:], 'r', encoding='utf-8') as inf:
+                for fname in inf.read().splitlines():
+                    add_file(fname)
+        else:
+            add_file(path)
+
+    finish_fit(fsw, entries)
+
+    # Include the kernel itself in the returned file count
+    return fsw.as_fdt().as_bytearray(), seq + 1, size
+
+
+def run_make_fit():
+    """Run the tool's main logic"""
+    args = parse_args()
+
+    out_data, count, size = build_fit(args)
+    with open(args.fit, 'wb') as outf:
+        outf.write(out_data)
+
+    ext_fit_size = None
+    if args.external:
+        mkimage = os.environ.get('MKIMAGE', 'mkimage')
+        subprocess.check_call([mkimage, '-E', '-F', args.fit],
+                              stdout=subprocess.DEVNULL)
+
+        with open(args.fit, 'rb') as inf:
+            data = inf.read()
+        ext_fit = libfdt.FdtRo(data)
+        ext_fit_size = ext_fit.totalsize()
+
+    comp_size = len(out_data)
+    print(f'FIT size {comp_size:#x}/{comp_size / 1024 / 1024:.1f} MB', end='')
+    if ext_fit_size:
+        print(f', header {ext_fit_size:#x}/{ext_fit_size / 1024:.1f} KB', end='')
+    print(f', {count} files, uncompressed {size / 1024 / 1024:.1f} MB')
+
+
+if __name__ == "__main__":
+    sys.exit(run_make_fit())
-- 
2.34.1



From fusibrandon13 at gmail.com  Fri Feb  2 09:32:01 2024
From: fusibrandon13 at gmail.com (Brandon Cheo Fusi)
Date: Fri,  2 Feb 2024 18:32:01 +0100
Subject: [PATCH v8 2/3] pwm: Add Allwinner's D1/T113-S3/R329 SoCs PWM support
In-Reply-To: <eynkbikmzcffid2jft3b6pmjfcbvda6mpzu7l5mefrw3za3iwh@ctgn57kb7ard>
References: <eynkbikmzcffid2jft3b6pmjfcbvda6mpzu7l5mefrw3za3iwh@ctgn57kb7ard>
Message-ID: <20240202173201.2564726-1-fusibrandon13@gmail.com>

On Thu, Feb 1, 2024 at 9:49?AM Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de> wrote:
>
> hello Aleksandr,
>
> On Wed, Jan 31, 2024 at 03:59:15PM +0300, Aleksandr Shubin wrote:
> > +#include <linux/bitfield.h>
> > +#include <linux/clk.h>
> > +#include <linux/err.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
>
> Some time ago there was some effort by Rob Herring to detangle the
> headers platform_device.h, of_device.h and of.h. See for example commit
> 87e51b76c9db8c29cde573af0faf5a3e13e23960. I think you should use
> linux/of.h instead of linux/of_device.h.
>
> > +#include <linux/platform_device.h>
> > +#include <linux/pwm.h>
> > +#include <linux/reset.h>
> > +
> > +#define SUN20I_PWM_CLK_CFG(chan) ? ? ? ? ? ? (0x20 + (((chan) >> 1) * 0x4))
> > +#define SUN20I_PWM_CLK_CFG_SRC ? ? ? ? ? ? ? ? ? ? ? GENMASK(8, 7)
> > +#define SUN20I_PWM_CLK_CFG_DIV_M ? ? ? ? ? ? GENMASK(3, 0)
> > +#define SUN20I_PWM_CLK_DIV_M_MAX ? ? ? ? ? ? 8
>
> SUN20I_PWM_CLK_CFG_DIV_M_MAX?
>

Yes. The manuals mark [0x9, 0xF] as reserved

> > +#define SUN20I_PWM_CLK_GATE ? ? ? ? ? ? ? ? ?0x40
> > +#define SUN20I_PWM_CLK_GATE_BYPASS(chan) ? ? BIT((chan) + 16)
> > +#define SUN20I_PWM_CLK_GATE_GATING(chan) ? ? BIT(chan)
> > +
> > +#define SUN20I_PWM_ENABLE ? ? ? ? ? ? ? ? ? ?0x80
> > +#define SUN20I_PWM_ENABLE_EN(chan) ? ? ? ? ? BIT(chan)
> > +
> > +#define SUN20I_PWM_CTL(chan) ? ? ? ? ? ? ? ? (0x100 + (chan) * 0x20)
> > +#define SUN20I_PWM_CTL_ACT_STA ? ? ? ? ? ? ? ? ? ? ? BIT(8)
> > +#define UN20I_PWM_CTL_PRESCAL_K ? ? ? ? ? ? ?GENMASK(7, 0)
> > +#define SUN20I_PWM_CTL_PRESCAL_K_MAX ? ? ? ? 0xff
>
> This matches the theoretical maximum for GENMASK(7,0), so you could make
> use of field_max(SUN20I_PWM_CTL_PRESCAL_K) here.
>
> > +#define SUN20I_PWM_PERIOD(chan) ? ? ? ? ? ? ? ? ? ? ?(0x104 + (chan) * 0x20)
> > +#define SUN20I_PWM_PERIOD_ENTIRE_CYCLE ? ? ? ? ? ? ? GENMASK(31, 16)
> > +#define SUN20I_PWM_PERIOD_ACT_CYCLE ? ? ? ? ?GENMASK(15, 0)
> > +
> > +#define SUN20I_PWM_PCNTR_SIZE ? ? ? ? ? ? ? ? ? ? ? ?BIT(16)
> > +
> > +/**
> > + * SUN20I_PWM_MAGIC is used to quickly compute the values of the clock dividers
> > + * div_m (SUN20I_PWM_CLK_CFG_DIV_M) & prescale_k (SUN20I_PWM_CTL_PRESCAL_K)
> > + * without using a loop. These dividers limit the # of cycles in a period
> > + * to SUN20I_PWM_PCNTR_SIZE by applying a scaling factor of
> > + * 1/(div_m * (prescale_k + 1)) to the clock source.
> > + *
> > + * SUN20I_PWM_MAGIC is derived by solving for div_m and prescale_k
> > + * such that for a given requested period,
> > + *
> > + * i) div_m is minimized for any prescale_k ? SUN20I_PWM_CTL_PRESCAL_K_MAX,
> > + * ii) prescale_k is minimized.
> > + *
> > + * The derivation proceeds as follows, with val = # of cycles for reqested
>
> s/reqested/requested/

Nice catch.

> > + * period:
> > + *
> > + * for a given value of div_m we want the smallest prescale_k such that
> > + *
> > + * (val >> div_m) // (prescale_k + 1) ? 65536 (SUN20I_PWM_PCNTR_SIZE)
> > + *
> > + * This is equivalent to:
> > + *
> > + * (val >> div_m) ? 65536 * (prescale_k + 1) + prescale_k
> > + * ? (val >> div_m) ? 65537 * prescale_k + 65536
> > + * ? (val >> div_m) - 65536 ? 65537 * prescale_k
> > + * ? ((val >> div_m) - 65536) / 65537 ? prescale_k
> > + *
> > + * As prescale_k is integer, this becomes
> > + *
> > + * ((val >> div_m) - 65536) // 65537 ? prescale_k
> > + *
> > + * And is minimized at
> > + *
> > + * ((val >> div_m) - 65536) // 65537
> > + *
> > + * Now we pick the smallest div_m that satifies prescale_k ? 255
> > + * (i.e SUN20I_PWM_CTL_PRESCAL_K_MAX),
> > + *
> > + * ((val >> div_m) - 65536) // 65537 ? 255
> > + * ? (val >> div_m) - 65536 ? 255 * 65537 + 65536
> > + * ? val >> div_m ? 255 * 65537 + 2 * 65536
> > + * ? val >> div_m < (255 * 65537 + 2 * 65536 + 1)
> > + * ? div_m = fls((val) / (255 * 65537 + 2 * 65536 + 1))
> > + *
> > + * Suggested by Uwe Kleine-K?nig
>
> Good man, I assume this is all sane then :-)

Credit should be given where it is due :-)

> > + */
> > +#define SUN20I_PWM_MAGIC ? ? ? ? ? ? ? ? ? ? (255 * 65537 + 2 * 65536 + 1)
> > +
> > +struct sun20i_pwm_chip {
> > + ? ? struct clk *clk_bus, *clk_hosc, *clk_apb0;
> > + ? ? struct reset_control *rst;
> > + ? ? struct pwm_chip chip;
> > + ? ? void __iomem *base;
> > + ? ? /* Mutex to protect pwm apply state */
> > + ? ? struct mutex mutex;
> > +};
> > +
> > +static inline struct sun20i_pwm_chip *to_sun20i_pwm_chip(struct pwm_chip *chip)
> > +{
> > + ? ? return container_of(chip, struct sun20i_pwm_chip, chip);
> > +}
> > +
> > +static inline u32 sun20i_pwm_readl(struct sun20i_pwm_chip *chip,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long offset)
> > +{
> > + ? ? return readl(chip->base + offset);
> > +}
> > +
> > +static inline void sun20i_pwm_writel(struct sun20i_pwm_chip *chip,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?u32 val, unsigned long offset)
> > +{
> > + ? ? writel(val, chip->base + offset);
> > +}
> > +
> > +static int sun20i_pwm_get_state(struct pwm_chip *chip,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct pwm_device *pwm,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct pwm_state *state)
> > +{
> > + ? ? struct sun20i_pwm_chip *sun20i_chip = to_sun20i_pwm_chip(chip);
> > + ? ? u16 ent_cycle, act_cycle, prescale_k;
> > + ? ? u64 clk_rate, tmp;
> > + ? ? u8 div_m;
> > + ? ? u32 val;
> > +
> > + ? ? mutex_lock(&sun20i_chip->mutex);
> > +
> > + ? ? val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_CLK_CFG(pwm->hwpwm));
> > + ? ? div_m = FIELD_GET(SUN20I_PWM_CLK_CFG_DIV_M, val);
> > + ? ? if (div_m > SUN20I_PWM_CLK_DIV_M_MAX)
> > + ? ? ? ? ? ? div_m = SUN20I_PWM_CLK_DIV_M_MAX;
> > +
> > + ? ? if (FIELD_GET(SUN20I_PWM_CLK_CFG_SRC, val) == 0)
> > + ? ? ? ? ? ? clk_rate = clk_get_rate(sun20i_chip->clk_hosc);
> > + ? ? else
> > + ? ? ? ? ? ? clk_rate = clk_get_rate(sun20i_chip->clk_apb0);
> > +
> > + ? ? val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_CTL(pwm->hwpwm));
> > + ? ? state->polarity = (SUN20I_PWM_CTL_ACT_STA & val) ?
> > + ? ? ? ? ? ? ? ? ? ? ? ?PWM_POLARITY_NORMAL : PWM_POLARITY_INVERSED;
> > +
> > + ? ? prescale_k = FIELD_GET(SUN20I_PWM_CTL_PRESCAL_K, val) + 1;
> > +
> > + ? ? val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_ENABLE);
> > + ? ? state->enabled = (SUN20I_PWM_ENABLE_EN(pwm->hwpwm) & val) ? true : false;
> > +
> > + ? ? val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_PERIOD(pwm->hwpwm));
> > +
> > + ? ? mutex_unlock(&sun20i_chip->mutex);
> > +
> > + ? ? act_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ACT_CYCLE, val);
> > + ? ? ent_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ENTIRE_CYCLE, val);
> > +
> > + ? ? /*
> > + ? ? ?* The duration of the active phase should not be longer
> > + ? ? ?* than the duration of the period
> > + ? ? ?*/
> > + ? ? if (act_cycle > ent_cycle)
> > + ? ? ? ? ? ? act_cycle = ent_cycle;
> > +
> > + ? ? tmp = ((u64)(act_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> > + ? ? state->duty_cycle = DIV_ROUND_UP_ULL(tmp, clk_rate);
> > + ? ? tmp = ((u64)(ent_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> > + ? ? state->period = DIV_ROUND_UP_ULL(tmp, clk_rate);
>
> Please add a comment above this block that justifies assuming that the
> multiplication doesn't overflow. Something like:
>
> ? ? ? ? We have act_cycle <= ent_cycle <= 0xffff, prescale_k <= 0x100,
> ? ? ? ? div_m <= 8. So the multiplication fits into an u64 without
> ? ? ? ? overflow.
>
> > +
> > + ? ? return 0;
> > +}
> > +
> > +static int sun20i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> > + ? ? ? ? ? ? ? ? ? ? ? ? const struct pwm_state *state)
> > +{
> > +...
> > +}
>
> I didn't recheck all the logic in .apply in detail and will assume it is
> sane for this round.

Please do recheck. This thing is already on v8 and we want to make sure
everyone is happy with v9.

> > +static const struct pwm_ops sun20i_pwm_ops = {
> > + ? ? .apply = sun20i_pwm_apply,
> > + ? ? .get_state = sun20i_pwm_get_state,
> > +};
> > +
> > +static const struct of_device_id sun20i_pwm_dt_ids[] = {
> > + ? ? { .compatible = "allwinner,sun20i-d1-pwm" },
> > + ? ? { },
> > +};
> > +MODULE_DEVICE_TABLE(of, sun20i_pwm_dt_ids);
> > +
> > +static int sun20i_pwm_probe(struct platform_device *pdev)
> > +{
> > + ? ? struct sun20i_pwm_chip *sun20i_chip;
> > + ? ? int ret;
> > +
> > + ? ? sun20i_chip = devm_kzalloc(&pdev->dev, sizeof(*sun20i_chip), GFP_KERNEL);
> > + ? ? if (!sun20i_chip)
> > + ? ? ? ? ? ? return -ENOMEM;
> > +
> > + ? ? sun20i_chip->base = devm_platform_ioremap_resource(pdev, 0);
> > + ? ? if (IS_ERR(sun20i_chip->base))
> > + ? ? ? ? ? ? return PTR_ERR(sun20i_chip->base);
> > +
> > + ? ? sun20i_chip->clk_bus = devm_clk_get_enabled(&pdev->dev, "bus");
> > + ? ? if (IS_ERR(sun20i_chip->clk_bus))
> > + ? ? ? ? ? ? return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_bus),
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"failed to get bus clock\n");
> > +
> > + ? ? sun20i_chip->clk_hosc = devm_clk_get_enabled(&pdev->dev, "hosc");
> > + ? ? if (IS_ERR(sun20i_chip->clk_hosc))
> > + ? ? ? ? ? ? return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_hosc),
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"failed to get hosc clock\n");
> > +
> > + ? ? sun20i_chip->clk_apb0 = devm_clk_get_enabled(&pdev->dev, "apb0");
> > + ? ? if (IS_ERR(sun20i_chip->clk_apb0))
> > + ? ? ? ? ? ? return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_apb0),
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"failed to get apb0 clock\n");
> > +
> > + ? ? sun20i_chip->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> > + ? ? if (IS_ERR(sun20i_chip->rst))
> > + ? ? ? ? ? ? return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->rst),
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"failed to get bus reset\n");
> > +
> > + ? ? ret = of_property_read_u32(pdev->dev.of_node, "allwinner,pwm-channels",
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&sun20i_chip->chip.npwm);
> > + ? ? if (ret)
> > + ? ? ? ? ? ? sun20i_chip->chip.npwm = 8;
> > +
> > + ? ? if (sun20i_chip->chip.npwm > 16)
> > + ? ? ? ? ? ? sun20i_chip->chip.npwm = 16;
>
> Is it worth to emit an error message here? Something like:
>
> ? ? ? ? Limiting number of PWM lines from %u to 16
>
> Best regards
> Uwe
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | Uwe Kleine-K?nig ? ? ? ? ? ?|
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | https://www.pengutronix.de/ |

Brandon.


From robh at kernel.org  Fri Feb  2 09:35:11 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 02 Feb 2024 11:35:11 -0600
Subject: [PATCH v4 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240202-add-am64-som-v4-2-5f8b12af5e71@solid-run.com>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
 <20240202-add-am64-som-v4-2-5f8b12af5e71@solid-run.com>
Message-ID: <170689531068.307758.9231002727463263124.robh@kernel.org>


On Fri, 02 Feb 2024 17:10:49 +0100, Josua Mayer wrote:
> Convert the abracon abx80x rtc text bindings to dt-schema format.
> 
> In addition to the text description reference generic interrupts
> properties and add an example.
> 
> Signed-off-by: Josua Mayer <josua at solid-run.com>
> ---
>  .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ---------
>  .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 74 ++++++++++++++++++++++
>  2 files changed, 74 insertions(+), 31 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:
Documentation/devicetree/bindings/rtc/abracon,abx80x.example.dts:28.13-26: Warning (reg_format): /example-0/rtc at 69:reg: property has invalid length (4 bytes) (#address-cells == 1, #size-cells == 1)
Documentation/devicetree/bindings/rtc/abracon,abx80x.example.dtb: Warning (pci_device_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/rtc/abracon,abx80x.example.dtb: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/rtc/abracon,abx80x.example.dtb: Warning (simple_bus_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/rtc/abracon,abx80x.example.dtb: Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/rtc/abracon,abx80x.example.dtb: Warning (spi_bus_reg): Failed prerequisite 'reg_format'

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240202-add-am64-som-v4-2-5f8b12af5e71 at solid-run.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From semen.protsenko at linaro.org  Fri Feb  2 09:35:42 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 2 Feb 2024 11:35:42 -0600
Subject: [PATCH v3 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <20240202145731.4082033-2-peter.griffin@linaro.org>
References: <20240202145731.4082033-1-peter.griffin@linaro.org> <20240202145731.4082033-2-peter.griffin@linaro.org>
Message-ID: <CAPLW+4=Cm36Q311Y7mCGgm+3fe5NNNc5XhNSMkbigTG2BVCTpA@mail.gmail.com>

On Fri, Feb 2, 2024 at 8:57?AM Peter Griffin <peter.griffin at linaro.org> wrote:
>
> Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> security hardening reasons so that they are only write accessible in el3
> via an SMC call.
>
> As most Exynos drivers that need to write PMU registers currently obtain a
> regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> is implemented in this driver using a custom regmap similar to syscon to
> handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> regmap like before. As regmaps abstract out the underlying register access
> changes to the leaf drivers are minimal.
>
> A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> that currently use syscon_regmap_lookup_by_phandle(). This also handles
> deferred probing.
>
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
> Changes since v2
>  - Add select REGMAP to Kconfig
>  - Add constant for SET/CLEAR bits
>  - Replace kerneldoc with one line comment
>  - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
>  - remove superflous extern keyword
>  - dev_err_probe() on probe error
>  - shorten regmcfg name
>  - no compatibles inside probe, use match data
>  - don't mix declarations with/without initializations
>  - tensor_sec_reg_read() use mmio to avoid access restrictions
>  - Collect up Reviewed-by
>  - const for regmap_config structs
> ---
>  drivers/soc/samsung/Kconfig            |   1 +
>  drivers/soc/samsung/exynos-pmu.c       | 233 ++++++++++++++++++++++++-
>  drivers/soc/samsung/exynos-pmu.h       |   1 +
>  include/linux/soc/samsung/exynos-pmu.h |  11 +-
>  4 files changed, 241 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 27ec99af77e3..1a5dfdc978dc 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -42,6 +42,7 @@ config EXYNOS_PMU
>         depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
>         select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
>         select MFD_CORE
> +       select REGMAP_MMIO
>
>  # There is no need to enable these drivers for ARMv8
>  config EXYNOS_PMU_ARM_DRIVERS
> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> index 250537d7cfd6..adf3549370d6 100644
> --- a/drivers/soc/samsung/exynos-pmu.c
> +++ b/drivers/soc/samsung/exynos-pmu.c
> @@ -5,6 +5,7 @@
>  //
>  // Exynos - CPU PMU(Power Management Unit) support
>
> +#include <linux/arm-smccc.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/mfd/core.h>
> @@ -12,19 +13,130 @@
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/delay.h>
> +#include <linux/regmap.h>
>
>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>  #include <linux/soc/samsung/exynos-pmu.h>
>
>  #include "exynos-pmu.h"
>
> +#define PMUALIVE_MASK GENMASK(14, 0)

Are you sure it's not GENMASK(13, 0)? Because SET_BITS has bit #14
set, which overlaps with bit #14 from PMUALIVE_MASK, when being added
in tensor_set_bit_atomic().

This also can be aligned with below definitions.

> +#define SET_BITS       0xc000
> +#define CLEAR_BITS     0x8000

All 3 above values seem to be gs101 specific. At least I can't find
any similar atomic registers in Exynos850 TRM, in PMU block. So I'd
suggest also adding TENSOR_ prefix to those to make it clear and to
prevent possible naming conflicts in future.

Also, not sure if it makes things better, but FWIW:

    #define CLEAR_BITS     BIT(15)
    #define SET_BITS       (BIT(15) | BIT(14))

Just to show that those two bits don't overlap with PMUALIVE_MASK (if
it can be fixed to 13:0), and show their relation. If I understand
correctly what's going on anyway.

> +
> +#define TENSOR_SMC_PMU_SEC_REG         0x82000504
> +#define TENSOR_PMUREG_READ             0
> +#define TENSOR_PMUREG_WRITE            1
> +#define TENSOR_PMUREG_RMW              2
> +
>  struct exynos_pmu_context {
>         struct device *dev;
>         const struct exynos_pmu_data *pmu_data;
> +       struct regmap *pmureg;
>  };
>
>  void __iomem *pmu_base_addr;
>  static struct exynos_pmu_context *pmu_context;
> +static struct platform_driver exynos_pmu_driver;

Just an idea: maybe add a comment saying it's a forward declaration,
and the variable is assigned below, as it might be confusing. Not sure
if it's worth it though.

> +
> +/*
> + * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
> + * from EL3, but are still read accessible. As Linux needs to write some of
> + * these registers, the following functions are provided and exposed via
> + * regmap.
> + *
> + * Note: This SMC interface is known to be implemented on gs101 and derivative
> + * SoCs.
> + */
> +
> +/* Write to a protected PMU register. */
> +static int tensor_sec_reg_write(void *base, unsigned int reg, unsigned int val)
> +{
> +       struct arm_smccc_res res;
> +       unsigned long pmu_base = (unsigned long)base;
> +
> +       arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> +                     TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
> +
> +       /* returns -EINVAL if access isn't allowed or 0 */
> +       if (res.a0)
> +               pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> +
> +       return (int)res.a0;
> +}
> +
> +/* Read/Modify/Write a protected PMU register. */
> +static int tensor_sec_reg_rmw(void *base, unsigned int reg,
> +                             unsigned int mask, unsigned int val)
> +{
> +       struct arm_smccc_res res;
> +       unsigned long pmu_base = (unsigned long)base;
> +
> +       arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> +                     TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
> +
> +       /* returns -EINVAL if access isn't allowed or 0*/
> +       if (res.a0)
> +               pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> +
> +       return (int)res.a0;
> +}
> +
> +/*
> + * Read a protected PMU register. All PMU registers can be read by Linux.
> + * Note: The SMC read register is not used, as only registers that can be
> + * written are readable via SMC.
> + */
> +static int tensor_sec_reg_read(void *base, unsigned int reg, unsigned int *val)
> +{
> +       *val = pmu_raw_readl(reg);
> +       return 0;
> +}
> +
> +/*
> + * For SoCs that have set/clear bit hardware this function can be used when
> + * the PMU register will be accessed by multiple masters.
> + *
> + * For example, to set bits 13:8 in PMU reg offset 0x3e80
> + * tensor_set_bit_atomic(0x3e80, 0x3f00, 0x3f00);
> + *
> + * To clear bits 13:8 in PMU offset 0x3e80
> + * tensor_set_bit_atomic(0x3e80, 0x0, 0x3f00);
> + */
> +static inline int tensor_set_bit_atomic(void *ctx, unsigned int offset,

set_bit -> set_bits?

> +                                       u32 val, u32 mask)
> +{
> +       int ret;
> +       unsigned int i;
> +
> +       for (i = 0; i < 32; i++) {
> +               if (mask & BIT(i)) {

Maybe replace it with:

    if (!(mask & BIT(i)))
        continue;

to reduce the indentation level?

> +                       if (val & BIT(i))
> +                               offset |= SET_BITS;
> +                       else
> +                               offset |= CLEAR_BITS;

What if someone calls this functions like this:

    tensor_set_bit_atomic(0x3e80, 0x100, 0x3f00);

which means "set bit #8, and clear bits 13:9). But because the offset
variable will hold SET_BITS set during bit #8 handling, bits 13:9 are
also going to be set, effectively making that call act like
tensor_set_bit_atomic(0x3e80, 0x3f00, 0x3f00) instead. So I'd add
something like:

    offset &= ~SET_BITS;

before doing |= operations.

> +
> +                       ret = tensor_sec_reg_write(ctx, offset, i);
> +                       if (ret)
> +                               goto out;

Maybe remove "out" and just do return ret here?

> +               }
> +       }
> +out:
> +       return ret;
> +}
> +
> +static int tensor_sec_update_bits(void *ctx, unsigned int reg,
> +                                 unsigned int mask, unsigned int val)
> +{
> +       /*
> +        * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
> +        * as the target registers can be accessed by multiple masters.
> +        */
> +       if (reg > PMUALIVE_MASK)
> +               return tensor_sec_reg_rmw(ctx, reg, mask, val);
> +
> +       return tensor_set_bit_atomic(ctx, reg, val, mask);
> +}
>
>  void pmu_raw_writel(u32 val, u32 offset)
>  {
> @@ -75,11 +187,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
>  #define exynos_pmu_data_arm_ptr(data)  NULL
>  #endif
>
> +static const struct regmap_config regmap_smccfg = {
> +       .name = "pmu_regs",
> +       .reg_bits = 32,
> +       .reg_stride = 4,
> +       .val_bits = 32,
> +       .fast_io = true,
> +       .use_single_read = true,
> +       .use_single_write = true,
> +       .reg_read = tensor_sec_reg_read,
> +       .reg_write = tensor_sec_reg_write,
> +       .reg_update_bits = tensor_sec_update_bits,
> +};
> +
> +static const struct regmap_config regmap_mmiocfg = {
> +       .name = "pmu_regs",
> +       .reg_bits = 32,
> +       .reg_stride = 4,
> +       .val_bits = 32,
> +       .fast_io = true,
> +       .use_single_read = true,
> +       .use_single_write = true,
> +};
> +
> +static const struct exynos_pmu_data gs101_pmu_data = {
> +       .pmu_secure = true
> +};
> +
>  /*
>   * PMU platform driver and devicetree bindings.
>   */
>  static const struct of_device_id exynos_pmu_of_device_ids[] = {
>         {
> +               .compatible = "google,gs101-pmu",
> +               .data = &gs101_pmu_data,
> +       }, {
>                 .compatible = "samsung,exynos3250-pmu",
>                 .data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
>         }, {
> @@ -113,19 +255,73 @@ static const struct mfd_cell exynos_pmu_devs[] = {
>         { .name = "exynos-clkout", },
>  };
>
> +/**
> + * exynos_get_pmu_regmap() - Obtain pmureg regmap
> + *
> + * Find the pmureg regmap previously configured in probe() and return regmap
> + * pointer.
> + *
> + * Return: A pointer to regmap if found or ERR_PTR error value.
> + */
>  struct regmap *exynos_get_pmu_regmap(void)
>  {
>         struct device_node *np = of_find_matching_node(NULL,
>                                                       exynos_pmu_of_device_ids);
>         if (np)
> -               return syscon_node_to_regmap(np);
> +               return exynos_get_pmu_regmap_by_phandle(np, NULL);
>         return ERR_PTR(-ENODEV);
>  }
>  EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
>
> +/**
> + * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
> + * @np: Pointer to device's Device Tree node
> + * @property: Device Tree property name which references the pmu
> + *
> + * Find the pmureg regmap previously configured in probe() and return regmap
> + * pointer.
> + *
> + * Return: A pointer to regmap if found or ERR_PTR error value.
> + */
> +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> +                                               const char *property)
> +{
> +       struct device *dev;
> +       struct exynos_pmu_context *ctx;
> +       struct device_node *pmu_np;
> +
> +       if (property)
> +               pmu_np = of_parse_phandle(np, property, 0);
> +       else
> +               pmu_np = np;
> +
> +       if (!pmu_np)
> +               return ERR_PTR(-ENODEV);
> +
> +       /*
> +        * Determine if exynos-pmu device has probed and therefore regmap
> +        * has been created and can be returned to the caller. Otherwise we
> +        * return -EPROBE_DEFER.
> +        */
> +       dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
> +                                           (void *)pmu_np);
> +
> +       of_node_put(pmu_np);
> +       if (!dev)
> +               return ERR_PTR(-EPROBE_DEFER);
> +
> +       ctx = dev_get_drvdata(dev);
> +
> +       return ctx->pmureg;
> +}
> +EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
> +
>  static int exynos_pmu_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> +       struct regmap_config pmu_regmcfg;
> +       struct regmap *regmap;
> +       struct resource *res;
>         int ret;
>
>         pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
> @@ -133,13 +329,42 @@ static int exynos_pmu_probe(struct platform_device *pdev)
>                 return PTR_ERR(pmu_base_addr);
>
>         pmu_context = devm_kzalloc(&pdev->dev,
> -                       sizeof(struct exynos_pmu_context),
> -                       GFP_KERNEL);
> +                                  sizeof(struct exynos_pmu_context),
> +                                  GFP_KERNEL);
>         if (!pmu_context)
>                 return -ENOMEM;
> -       pmu_context->dev = dev;
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!res)
> +               return -ENODEV;
> +
>         pmu_context->pmu_data = of_device_get_match_data(dev);
>
> +       /* For SoCs that secure PMU register writes use custom regmap */
> +       if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_secure) {
> +               pmu_regmcfg = regmap_smccfg;
> +               pmu_regmcfg.max_register = resource_size(res) -
> +                                          pmu_regmcfg.reg_stride;
> +               /* Need physical address for SMC call */
> +               regmap = devm_regmap_init(dev, NULL,
> +                                         (void *)(uintptr_t)res->start,
> +                                         &pmu_regmcfg);
> +       } else {
> +               /* all other SoCs use a MMIO regmap */

Suggest starting with a capital letter, for consistency with previous comments.

> +               pmu_regmcfg = regmap_mmiocfg;
> +               pmu_regmcfg.max_register = resource_size(res) -
> +                                          pmu_regmcfg.reg_stride;
> +               regmap = devm_regmap_init_mmio(dev, pmu_base_addr,
> +                                              &pmu_regmcfg);
> +       }
> +
> +       if (IS_ERR(regmap))
> +               dev_err_probe(&pdev->dev, PTR_ERR(regmap),
> +                             "regmap init failed\n");

Why not "return dev_err_probe()"? Is it ok to continue with no regmap created?

> +
> +       pmu_context->pmureg = regmap;
> +       pmu_context->dev = dev;
> +
>         if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init)
>                 pmu_context->pmu_data->pmu_init();
>
> diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
> index 1c652ffd79b4..0a49a2c9a08e 100644
> --- a/drivers/soc/samsung/exynos-pmu.h
> +++ b/drivers/soc/samsung/exynos-pmu.h
> @@ -21,6 +21,7 @@ struct exynos_pmu_conf {
>  struct exynos_pmu_data {
>         const struct exynos_pmu_conf *pmu_config;
>         const struct exynos_pmu_conf *pmu_config_extra;
> +       bool pmu_secure;
>
>         void (*pmu_init)(void);
>         void (*powerdown_conf)(enum sys_powerdown);
> diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
> index a4f5516cc956..406ed73614fd 100644
> --- a/include/linux/soc/samsung/exynos-pmu.h
> +++ b/include/linux/soc/samsung/exynos-pmu.h
> @@ -20,12 +20,21 @@ enum sys_powerdown {
>
>  extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
>  #ifdef CONFIG_EXYNOS_PMU
> -extern struct regmap *exynos_get_pmu_regmap(void);
> +struct regmap *exynos_get_pmu_regmap(void);
> +

Usually empty line delimeter is not needed in cases like that.

> +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> +                                               const char *property);
>  #else
>  static inline struct regmap *exynos_get_pmu_regmap(void)
>  {
>         return ERR_PTR(-ENODEV);
>  }
> +
> +static inline struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> +                                                             const char *property)
> +{
> +       return ERR_PTR(-ENODEV);
> +}
>  #endif
>
>  #endif /* __LINUX_SOC_EXYNOS_PMU_H */
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From dregan at broadcom.com  Fri Feb  2 09:38:22 2024
From: dregan at broadcom.com (David Regan)
Date: Fri, 2 Feb 2024 09:38:22 -0800
Subject: [PATCH v3 10/10] mtd: rawnand: brcmnand: allow for on-die ecc
In-Reply-To: <20240201092558.5499ee6a@xps-13>
References: <20240124030458.98408-1-dregan@broadcom.com> <20240124030458.98408-11-dregan@broadcom.com>
 <20240124184027.712b1e47@xps-13> <CAA_RMS42FaiN+Za1iY12o0YUANH9rJarBTBa=9jNn8x6_g-Fng@mail.gmail.com>
 <20240126071913.699c3795@xps-13> <CAA_RMS5gX88v_Qt1csgSL_ffMNsqo2G8B164EB_Hg=hXd620eg@mail.gmail.com>
 <20240129115228.06dc2292@xps-13> <2a3edcf5-7afc-410c-a402-3d8cd3feb1da@broadcom.com>
 <20240130120155.3cb6feed@xps-13> <CAA_RMS577vw=QWN9_NHfmWqt+_cDG22tA01aU019CPNjAgHqJQ@mail.gmail.com>
 <20240130195504.506fb446@xps-13> <bcd9f8a5-7dab-42e6-b860-8a56ebb51cb6@broadcom.com>
 <20240201092558.5499ee6a@xps-13>
Message-ID: <CAA_RMS4V=RBzQCxSDbKgqNbnZz+ca-XThyoowMHuFga3jRyUSw@mail.gmail.com>

Hi Miqu?l,

On Thu, Feb 1, 2024 at 12:26?AM Miquel Raynal <miquel.raynal at bootlin.com> wrote:
>
> Hi William,
>
> > >>>>>>>> This is a double check to turn on/off our hardware ECC.
> > >>>>>>>
> > >>>>>>> I expect the engine to be always disabled. Enable it only when you
> > >>>>>>> need (may require an additional patch before this one).
> > >>>>>>
> > >>>>>> We are already turning on the ECC enable at this point,
> > >>>>>> this is just adding the option to turn it off if the NAND chip
> > >>>>>> itself will be doing the ECC instead of our controller.
> > >>>>>
> > >>>>> Sorry if I have not been clear.
> > >>>>>
> > >>>>> This sequence:
> > >>>>> - init
> > >>>>> - enable hw ECC engine
> > >>>>> Is broken.
> > >>>>>   >>>> ECC engine is not enabled for all the cases. Here we only intended to enable it for the nand chip that is set to use NAND_ECC_ENGINE_TYPE_ON_HOST. The logic here should better change to:
> > >>>> if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST)
> > >>>>       brcmnand_set_ecc_enabled(host, 1);
> > >>>> else
> > >>>>       brcmnand_set_ecc_enabled(host, 0);
> > >>>>   >>>>> It *cannot* work as any operation going through exec_op now may
> > >>>>> perform page reads which should be unmodified by the ECC engine. You > driver *must* follow the following sequence:
> > >>>>> - init and disable (or keep disabled) the hw ECC engine
> > >>>>> - when you perform a page operation with correction you need to
> > >>>>>      - enable the engine
> > >>>>>      - perform the operation
> > >>>>>      - disable the engine
> > >>>>> Maybe I am missing something here but are you saying the exec_op can have different ecc type for page read/write at run time on the same nand chip? I don't see the op instr structure has the ecc type field and thought it is only bind to the nand chip and won't change at run time. So looks to me the init time setting to the engine based on ecc.engine_type should be sufficient.
> > >>>>
> > >>>> What you described here can work for the hw.ecc read path (ecc.read_page = brcmnand_read_page) which always assumes ecc is enabled. Although it is probably not too bad with these two extra operation, it would be better if we don't have to add anything as our current code does. For the brcmnand_read_page_raw,  we currently disable the engine and then re-enable it(but we need to fix it to only enable it with hw ecc engine type).  So it is just opposite of you logic but works the same with no impact on the most performance critical path.
> > >>>
> > >>> This is not "my" logic, this is the "core's" logic. I am saying: your
> > >>> approach is broken because that is not how the API is supposed to work,
> > >>> but it mostly works in the standard case.
> > >>
> > >> In the interest of minimizing register writes, would it be acceptable to
> > >> enable/disable ECC at the beginning of a standard
> > >> path transfer but not, after the transfer, turn off the ECC? This should not
> > >> affect other standard path operations nor affect the exec_op path as those
> > >> are low level transfers which our ECC engine would not touch and the NAND
> > >> device driver should be responsible for turning on/off its own ECC.
> > >
> > > Do you have legitimate concerns about this register write taking way
> > > more time than I could expect? Because compared to the transfer of a
> > > NAND page + tR/tPROG it should not be noticeable. I don't see how you
> > > could even measure such impact actually, unless the register write does
> > > way more than usual. I'm fine with the above idea if you show me it has
> > > an interest.
> > >
> > Dave did the mtd_speed test and we can see we get consistently ~35KB/s slower with the extra enable and disable ecc engine calls in ecc read page path.
> >
> > With the change:
> > [   28.148355] mtd_speedtest:   page read speed is 9857 KiB/s
> > [   31.754258] mtd_speedtest: 2 page read speed is 9865 KiB/s
> > Without the change
> > [   56.444735] mtd_speedtest:   page read speed is 9892 KiB/s
> > [   60.042262] mtd_speedtest: 2 page read speed is 9897 KiB/s
>
> I believe if you repeat this 10 times you'll get totally different
> results. I don't think this test on a non RT machine is precise enough
> so that a unique 35kiB difference can be interpreted as being
> significant.
>
> > Although it is only less than 1% drop, it is still something. I understand the procedure you laid out above is the preferred way but with our driver fully control the chip ecc read/write page, ecc read_raw/write_raw page function and exec_op path, I don't see where it may not work.
>
> I just told you, the exec_op path runs with ECC enabled. I don't know
> how this controller works. Now if you don't care and are 100% sure this
> is working and future proof, just keep it like this.

Thank you for all your help, it appears this will need further rework
and testing. Since it's not critical to this series I will most likely
pull this patch and take all your good information to prepare for
a future update.

>
> Cheers,
> Miqu?l

Thanks!

-Dave


From rmk+kernel at armlinux.org.uk  Fri Feb  2 09:41:45 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 02 Feb 2024 17:41:45 +0000
Subject: [PATCH net-next] net: phy: constify phydev->drv
Message-ID: <E1rVxXt-002YqY-9G@rmk-PC.armlinux.org.uk>

Device driver structures are shared between all devices that they
match, and thus nothing should never write to the device driver
structure through the phydev->drv pointer. Let's make this pointer
const to catch code that attempts to do so.

Suggested-by: Christian Marangi <ansuelsmth at gmail.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/phy/phy.c               | 3 +--
 drivers/net/phy/phy_device.c        | 6 +++---
 drivers/net/phy/xilinx_gmii2rgmii.c | 2 +-
 include/linux/phy.h                 | 2 +-
 4 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 3b9531143be1..14224e06d69f 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1290,7 +1290,6 @@ int phy_disable_interrupts(struct phy_device *phydev)
 static irqreturn_t phy_interrupt(int irq, void *phy_dat)
 {
 	struct phy_device *phydev = phy_dat;
-	struct phy_driver *drv = phydev->drv;
 	irqreturn_t ret;
 
 	/* Wakeup interrupts may occur during a system sleep transition.
@@ -1316,7 +1315,7 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
 	}
 
 	mutex_lock(&phydev->lock);
-	ret = drv->handle_interrupt(phydev);
+	ret = phydev->drv->handle_interrupt(phydev);
 	mutex_unlock(&phydev->lock);
 
 	return ret;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 52828d1c64f7..2eed8f03621d 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1413,7 +1413,7 @@ int phy_sfp_probe(struct phy_device *phydev,
 }
 EXPORT_SYMBOL(phy_sfp_probe);
 
-static bool phy_drv_supports_irq(struct phy_driver *phydrv)
+static bool phy_drv_supports_irq(const struct phy_driver *phydrv)
 {
 	return phydrv->config_intr && phydrv->handle_interrupt;
 }
@@ -1867,7 +1867,7 @@ int phy_suspend(struct phy_device *phydev)
 {
 	struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
 	struct net_device *netdev = phydev->attached_dev;
-	struct phy_driver *phydrv = phydev->drv;
+	const struct phy_driver *phydrv = phydev->drv;
 	int ret;
 
 	if (phydev->suspended)
@@ -1892,7 +1892,7 @@ EXPORT_SYMBOL(phy_suspend);
 
 int __phy_resume(struct phy_device *phydev)
 {
-	struct phy_driver *phydrv = phydev->drv;
+	const struct phy_driver *phydrv = phydev->drv;
 	int ret;
 
 	lockdep_assert_held(&phydev->lock);
diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c
index 7fd9fe6a602b..7b1bc5fcef9b 100644
--- a/drivers/net/phy/xilinx_gmii2rgmii.c
+++ b/drivers/net/phy/xilinx_gmii2rgmii.c
@@ -22,7 +22,7 @@
 
 struct gmii2rgmii {
 	struct phy_device *phy_dev;
-	struct phy_driver *phy_drv;
+	const struct phy_driver *phy_drv;
 	struct phy_driver conv_phy_drv;
 	struct mdio_device *mdio;
 };
diff --git a/include/linux/phy.h b/include/linux/phy.h
index a66f07d3f5f4..ad93f8b1b128 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -638,7 +638,7 @@ struct phy_device {
 
 	/* Information about the PHY type */
 	/* And management functions */
-	struct phy_driver *drv;
+	const struct phy_driver *drv;
 
 	struct device_link *devlink;
 
-- 
2.30.2



From rafael at kernel.org  Fri Feb  2 09:44:32 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Fri, 2 Feb 2024 18:44:32 +0100
Subject: [PATCH v1 08/18] thermal: intel: pch_thermal: Migrate to thermal_zone_device_register()
In-Reply-To: <eec1d1f7-6d8f-46e9-8ce5-4d7319da7d9e@collabora.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
 <20240130111250.185718-9-angelogioacchino.delregno@collabora.com>
 <CAJZ5v0ifn7eg9WrpNF2_PB62gE_BzV2Vx5_k7ebOoZWdQNVWaQ@mail.gmail.com> <eec1d1f7-6d8f-46e9-8ce5-4d7319da7d9e@collabora.com>
Message-ID: <CAJZ5v0iEWSbbouzRgzEg3sYJ63bRYCBSrCNfT-PrHbOwH0LYOg@mail.gmail.com>

On Fri, Feb 2, 2024 at 11:10?AM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Il 01/02/24 20:51, Rafael J. Wysocki ha scritto:
> > On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
> > <angelogioacchino.delregno at collabora.com> wrote:
> >>
> >> The thermal API has a new thermal_zone_device_register() function which
> >> is deprecating the older thermal_zone_device_register_with_trips() and
> >> thermal_tripless_zone_device_register().
> >>
> >> Migrate to the new thermal zone device registration function.
> >>
> >> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> >> ---
> >>   drivers/thermal/intel/intel_pch_thermal.c | 12 ++++++++----
> >>   1 file changed, 8 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/drivers/thermal/intel/intel_pch_thermal.c b/drivers/thermal/intel/intel_pch_thermal.c
> >> index b3905e34c507..73d7c2ac7dbc 100644
> >> --- a/drivers/thermal/intel/intel_pch_thermal.c
> >> +++ b/drivers/thermal/intel/intel_pch_thermal.c
> >> @@ -160,6 +160,7 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev,
> >>                                     const struct pci_device_id *id)
> >>   {
> >>          enum pch_board_ids board_id = id->driver_data;
> >> +       struct thermal_zone_device_params tzdp;
> >>          struct pch_thermal_device *ptd;
> >>          int nr_trips = 0;
> >>          u16 trip_temp;
> >> @@ -233,10 +234,13 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev,
> >>
> >>          nr_trips += pch_wpt_add_acpi_psv_trip(ptd, nr_trips);
> >>
> >> -       ptd->tzd = thermal_zone_device_register_with_trips(board_names[board_id],
> >> -                                                          ptd->trips, nr_trips,
> >> -                                                          0, ptd, &tzd_ops,
> >> -                                                          NULL, 0, 0);
> >> +       tzdp.tzp.type = board_names[board_id];
> >> +       tzdp.tzp.devdata = ptd;
> >> +       tzdp.tzp.trips = ptd->trips;
> >> +       tzdp.tzp.num_trips = nr_trips;
> >> +       tzdp.tzp.ops = &tzd_ops;
> >> +
> >> +       ptd->tzd = thermal_zone_device_register(&tzdp);
> >
> > IMV, this should be
> >
> > ptd->tzd = thermal_zone_device_register(board_names[board_id],
> > ptd->trips, nr_trips, &tzd_ops, ptd, NULL);
> >
> > and the tzdp variable is not necessary even.
> >
>
> The whole point of thermal_zone_device_register() taking just one parameter was
> that those older functions were taking a bit too many params, and with the
> introduction of Thermal Zone name we'd be adding even more.

That's fair.

However, as indicated elsewhere, there are at least a few arguments of
the registration function that fit into the argument list: trips[],
num_trips, ops, devdata.

I'd add the name to that list and put the rest (including type) into
the params struct.

> For intel_pch_thermal, things are more or less the same, assignments are done there
> line by line... but for most of the others, IMO it's easier and schematized as a
> single stack-initialized structure that could even be constified in the future.

Well, it's copied into the struct thermal_zone_device, so it's better
to put it one the stack, so the memory occupied by it gets freed when
not needed any more.


From arinc.unal at arinc9.com  Fri Feb  2 09:44:39 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Fri, 2 Feb 2024 20:44:39 +0300
Subject: [PATCH net-next v3 1/7] net: dsa: mt7530: empty default case on
 mt7530_setup_port5()
In-Reply-To: <ZbzUotyQm/FyKK7G@shell.armlinux.org.uk>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-1-63d5adae99ca@arinc9.com>
 <ZbzUotyQm/FyKK7G@shell.armlinux.org.uk>
Message-ID: <e3b4add6-425c-46ca-9da5-8713055fc422@arinc9.com>

On 2.02.2024 14:40, Russell King (Oracle) wrote:
> While reviewing this change, but not related to it, I notice that this
> function sets the TX delay based on the RGMII interface mode. This isn't
> correct. I've explained why this is this many times in the past, but
> essentially it comes down to the model:
> 
> 
> phy-mode in NIC node	Network driver	PCB		PHY
> rgmii			no delays	delays		no delays
> rgmii-id		no delays	no delays	tx/rx delays
> rgmii-txid		no delays	no delays	tx delays
> rgmii-rxid		no delays	no delays	rx delays
> 
> Then we have rx-internal-delay-ps and tx-internal-delay-ps in the NIC
> node which define the RGMII delays at the local end and similar
> properties for the PHY node.
> 
> 
> So, if we take the view that, when a switch is connected to a NIC in
> RGMII mode, then the phy-mode specified delays still should not impact
> the local NIC.
> 
> Now, for the switch, we specify the phy-mode in the port node as well.
> Consider the case of a switch port connected to a RGMII PHY. This has
> to operate in exactly the same way as a normal NIC - that is, the
> RGMII delays at the port should be ignored as it's the responsibility
> of a PHY.
> 
> The final scenario to examine is the case of a RGMII switch port
> connected to a NIC. The NIC's phy-mode has no way to be communicated
> to DSA or vice versa, so neither phy-mode can impact the other side
> of the RGMII link, but should only place the link into RGMII mode.
> Given everything I've said above, the only way to configure RGMII
> delays is via the rx-internal-delay-ps and tx-internal-delay-ps
> properties. So, DSA drivers should _not_ be configuring their ports
> with RGMII delays based on the RGMII phy interface mode.
> 
> The above is my purely logically reasoned point of view on this
> subject. Others may have other (to me completely illogical)
> interpretations that can only lead to interoperability issues.

I will address this with the next patch series. Thank you for explaining it
in detail.

Ar?n?


From horms at kernel.org  Fri Feb  2 09:46:15 2024
From: horms at kernel.org (Simon Horman)
Date: Fri, 2 Feb 2024 17:46:15 +0000
Subject: [PATCH net-next v3] net: stmmac: dwmac-qcom-ethqos: Add support
 for 2.5G SGMII
In-Reply-To: <20240130111234.1244-1-quic_snehshah@quicinc.com>
References: <20240130111234.1244-1-quic_snehshah@quicinc.com>
Message-ID: <20240202174615.GT530335@kernel.org>

On Tue, Jan 30, 2024 at 04:42:34PM +0530, Sneh Shah wrote:
> Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000
> mode for 1G/100M/10M speed.
> Added changes to configure serdes phy and mac based on link speed.
> Changing serdes phy speed involves multiple register writes for
> serdes block. To avoid redundant write opertions only update serdes
> phy when new speed is different.

nit: operations

...


From hnagalla at ti.com  Fri Feb  2 09:55:34 2024
From: hnagalla at ti.com (Hari Nagalla)
Date: Fri, 2 Feb 2024 11:55:34 -0600
Subject: [PATCH v7 1/5] dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs
In-Reply-To: <20240202175538.1705-1-hnagalla@ti.com>
References: <20240202175538.1705-1-hnagalla@ti.com>
Message-ID: <20240202175538.1705-2-hnagalla@ti.com>

K3 AM64x SoC has a Cortex M4F subsystem in the MCU voltage 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: Martyn Welch <martyn.welch at collabora.com>
Signed-off-by: Hari Nagalla <hnagalla at ti.com>
---
Changes since v1:
 - Spelling corrections
 - Corrected to pass DT checks

Changes since v2:
 - Missed spelling correction to commit message

Changes since v3:
 - Removed unnecessary descriptions and used generic memory region names
 - Made mboxes and memory-region optional
 - Removed unrelated items from examples

Changes since v4:
 - Rebased to the latest kernel-next tree
 - Added optional sram memory region for m4f device node

Changes since v5:
 - None

Changes since v6:
 - Removed blank line, fixed type for firm-ware property and binding check
   errors.

link to v6:
  https://lore.kernel.org/all/20230913111644.29889-2-hnagalla at ti.com/

 .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 138 ++++++++++++++++++
 1 file changed, 138 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..645dbce3773b
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
@@ -0,0 +1,138 @@
+# 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>
+  - Mathieu Poirier <mathieu.poirier at linaro.org>
+
+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 without an IPC. Where as some industrial and
+  home automation applications, may use the M4F core as a remote processor
+  with IPC communications.
+
+$ref: /schemas/arm/keystone/ti,k3-sci-common.yaml#
+
+properties:
+  compatible:
+    enum:
+      - ti,am64-m4fss
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 2
+
+  reg:
+    items:
+      - description: IRAM internal memory region
+      - description: DRAM internal memory region
+
+  reg-names:
+    items:
+      - const: iram
+      - const: dram
+
+  resets:
+    maxItems: 1
+
+  firmware-name:
+    maxItems: 1
+    description: Name of firmware to load for the M4F core
+
+  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. 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.yaml
+      Optional memory regions available for firmware specific purposes.
+    maxItems: 8
+    items:
+      - description: regions used for DMA allocations like vrings, vring buffers
+                     and memory dedicated to firmware's specific purposes.
+    additionalItems: true
+
+  sram:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 4
+    items:
+      maxItems: 1
+    description: |
+      phandles to reserved on-chip SRAM regions. The regions should be
+      defined as child nodes of the respective SRAM node, and
+      should be defined as per the generic bindings in,
+      Documentation/devicetree/bindings/sram/sram.yaml
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - ti,sci
+  - ti,sci-dev-id
+  - ti,sci-proc-ids
+  - resets
+  - firmware-name
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    reserved-memory {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        mcu_m4fss_dma_memory_region: m4f-dma-memory at 9cb00000 {
+            compatible = "shared-dma-pool";
+            reg = <0x00 0x9cb00000 0x00 0x100000>;
+            no-map;
+        };
+
+        mcu_m4fss_memory_region: m4f-memory at 9cc00000 {
+            compatible = "shared-dma-pool";
+            reg = <0x00 0x9cc00000 0x00 0xe00000>;
+            no-map;
+        };
+    };
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        mailbox0_cluster0: mailbox-0 {
+            #mbox-cells = <1>;
+        };
+
+        remoteproc 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 = "am62-mcu-m4f0_0-fw";
+            mboxes = <&mailbox0_cluster0>, <&mbox_m4_0>;
+            memory-region = <&mcu_m4fss_dma_memory_region>,
+                            <&mcu_m4fss_memory_region>;
+            sram = <&oc_sram>;
+         };
+    };
-- 
2.34.1



From hnagalla at ti.com  Fri Feb  2 09:55:33 2024
From: hnagalla at ti.com (Hari Nagalla)
Date: Fri, 2 Feb 2024 11:55:33 -0600
Subject: [PATCH v7 0/5] TI K3 M4F support on AM64x and AM62x SoCs
Message-ID: <20240202175538.1705-1-hnagalla@ti.com>

The following series introduces K3 M4F remoteproc driver support for
AM64x and AM62x SoC families. These SoCs have a ARM Cortex M4F core in
the 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

See AM62x Technical Reference Manual (SPRUIV7A ? MAY 2022) for
further details: https://www.ti.com/lit/pdf/SPRUIV7A

kernel build log: https://paste.sr.ht/~hnagalla/be9d1c45e176ea8fa274ab13a3da43a9853fcf7f
dt-binding-check log: https://paste.sr.ht/~hnagalla/25912c85f6a8c68e3da24053fc060f38024fb8ab 
kernel boot log: https://paste.sr.ht/~hnagalla/5ba77847343f22b5f9ec2b7aeabc410aaf8cdf45

Hari Nagalla (2):
  dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs
  arm64: defconfig: Enable TI K3 M4 remote proc driver

Martyn Welch (3):
  remoteproc: k3: Move out data structures common with M4 driver
  remoteproc: k3: Move out functions common with M4 driver
  remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem

 .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  |  138 ++
 arch/arm64/configs/defconfig                  |    1 +
 drivers/remoteproc/Kconfig                    |   13 +
 drivers/remoteproc/Makefile                   |    3 +-
 drivers/remoteproc/ti_k3_common.c             |  583 ++++++++
 drivers/remoteproc/ti_k3_common.h             |  107 ++
 drivers/remoteproc/ti_k3_dsp_remoteproc.c     | 1277 +++++------------
 drivers/remoteproc/ti_k3_m4_remoteproc.c      |  327 +++++
 8 files changed, 1539 insertions(+), 910 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
 create mode 100644 drivers/remoteproc/ti_k3_common.c
 create mode 100644 drivers/remoteproc/ti_k3_common.h
 rewrite drivers/remoteproc/ti_k3_dsp_remoteproc.c (67%)
 create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

-- 
2.34.1



From hnagalla at ti.com  Fri Feb  2 09:55:38 2024
From: hnagalla at ti.com (Hari Nagalla)
Date: Fri, 2 Feb 2024 11:55:38 -0600
Subject: [PATCH v7 5/5] arm64: defconfig: Enable TI K3 M4 remote proc driver
In-Reply-To: <20240202175538.1705-1-hnagalla@ti.com>
References: <20240202175538.1705-1-hnagalla@ti.com>
Message-ID: <20240202175538.1705-6-hnagalla@ti.com>

Enable CONFIG_TI_K3_M4_REMOTEPROC

Some K3 platform devices (AM64x, AM62x) have a Cortex M4 core. Build
the M4 remote proc driver as a module for these platforms.

Signed-off-by: Hari Nagalla <hnagalla at ti.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 2064e7bc529e..c3941821e812 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1337,6 +1337,7 @@ CONFIG_QCOM_Q6V5_PAS=m
 CONFIG_QCOM_SYSMON=m
 CONFIG_QCOM_WCNSS_PIL=m
 CONFIG_TI_K3_DSP_REMOTEPROC=m
+CONFIG_TI_K3_M4_REMOTEPROC=m
 CONFIG_TI_K3_R5_REMOTEPROC=m
 CONFIG_RPMSG_CHAR=m
 CONFIG_RPMSG_CTRL=m
-- 
2.34.1



From hnagalla at ti.com  Fri Feb  2 09:55:35 2024
From: hnagalla at ti.com (Hari Nagalla)
Date: Fri, 2 Feb 2024 11:55:35 -0600
Subject: [PATCH v7 2/5] remoteproc: k3: Move out data structures common with M4 driver
In-Reply-To: <20240202175538.1705-1-hnagalla@ti.com>
References: <20240202175538.1705-1-hnagalla@ti.com>
Message-ID: <20240202175538.1705-3-hnagalla@ti.com>

From: Martyn Welch <martyn.welch at collabora.com>

We will be adding the M4F driver which shares a lot of commonality
with the DSP driver. Common data structures are introduced here.

Signed-off-by: Martyn Welch <martyn.welch at collabora.com>
Signed-off-by: Hari Nagalla <hnagalla at ti.com>
---
Changes since v5:
 - Created a separate patch for data structures to ease review

Changes since v6:
 - Reworded 'split' to 'move' as the common data structures between
   DSP and M4 remote rpoc drivers are moved into common driver.

link to v6:
https://lore.kernel.org/all/20230913111644.29889-3-hnagalla at ti.com/

 drivers/remoteproc/ti_k3_common.h | 107 ++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 drivers/remoteproc/ti_k3_common.h

diff --git a/drivers/remoteproc/ti_k3_common.h b/drivers/remoteproc/ti_k3_common.h
new file mode 100644
index 000000000000..f1bab83dd0fc
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_common.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * TI K3 Remote Processor(s) driver common code
+ *
+ * Refactored from ti_k3_dsp_remoteproc.c.
+ *
+ * ti_k3_dsp_remoteproc.c:
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ *	Suman Anna <s-anna at ti.com>
+ */
+
+#ifndef REMOTEPROC_TI_K3_COMMON_H
+#define REMOTEPROC_TI_K3_COMMON_H
+
+#define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK	(SZ_16M - 1)
+
+/**
+ * struct k3_rproc_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 remote processor view
+ * @size: Size of the memory region
+ */
+struct k3_rproc_mem {
+	void __iomem *cpu_addr;
+	phys_addr_t bus_addr;
+	u32 dev_addr;
+	size_t size;
+};
+
+/**
+ * struct k3_rproc_mem_data - memory definitions for a remote processor
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_rproc_mem_data {
+	const char *name;
+	const u32 dev_addr;
+};
+
+/**
+ * struct k3_rproc_dev_data - device data structure for a remote processor
+ * @mems: pointer to memory definitions for a remote processor
+ * @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_rproc_dev_data {
+	const struct k3_rproc_mem_data *mems;
+	u32 num_mems;
+	u32 boot_align_addr;
+	bool uses_lreset;
+};
+
+/**
+ * struct k3_rproc - k3 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 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
+ */
+struct k3_rproc {
+	struct device *dev;
+	struct rproc *rproc;
+	struct k3_rproc_mem *mem;
+	int num_mems;
+	struct k3_rproc_mem *sram;
+	int num_sram;
+	struct k3_rproc_mem *rmem;
+	int num_rmems;
+	struct reset_control *reset;
+	const struct k3_rproc_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;
+};
+
+void k3_rproc_kick(struct rproc *rproc, int vqid);
+int k3_rproc_reset(struct k3_rproc *kproc);
+int k3_rproc_release(struct k3_rproc *kproc);
+int k3_rproc_request_mbox(struct rproc *rproc);
+int k3_rproc_prepare(struct rproc *rproc);
+int k3_rproc_unprepare(struct rproc *rproc);
+struct resource_table *k3_get_loaded_rsc_table(struct rproc *rproc,
+					       size_t *rsc_table_sz);
+void *k3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len,
+			bool *is_iomem);
+int k3_rproc_of_get_memories(struct platform_device *pdev,
+			     struct k3_rproc *kproc);
+int k3_rproc_of_get_sram_memories(struct platform_device *pdev,
+			     struct k3_rproc *kproc);
+int k3_reserved_mem_init(struct k3_rproc *kproc);
+void k3_reserved_mem_exit(struct k3_rproc *kproc);
+struct ti_sci_proc *k3_rproc_of_get_tsp(struct device *dev,
+					const struct ti_sci_handle *sci);
+#endif /* REMOTEPROC_TI_K3_COMMON_H */
-- 
2.34.1



From hnagalla at ti.com  Fri Feb  2 09:55:37 2024
From: hnagalla at ti.com (Hari Nagalla)
Date: Fri, 2 Feb 2024 11:55:37 -0600
Subject: [PATCH v7 4/5] remoteproc: k3-m4: Add a remoteproc driver for M4F subsystem
In-Reply-To: <20240202175538.1705-1-hnagalla@ti.com>
References: <20240202175538.1705-1-hnagalla@ti.com>
Message-ID: <20240202175538.1705-5-hnagalla@ti.com>

From: Martyn Welch <martyn.welch at collabora.com>

The AM62x and AM64x SoCs of the 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 remote processor driver is added to support this subsystem, including
being able to load and boot the M4F core. Loading includes to M4F
internal memories and predefined external code/data memories. The
carve outs 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 the other, a
local reset is only for the M4F processing core. When loading the image,
the driver first releases the subsystem reset, loads the firmware image
and then releases the local reset to let the M4F processing core run.

Signed-off-by: Martyn Welch <martyn.welch at collabora.com>
Signed-off-by: Hari Nagalla <hnagalla at ti.com>
---
changes since v6:
 - Added compile testing.
 - replaced 'dev_err' with 'dev_err_probe'
 - removed redundant calls to existing code

link to v6:
https://lore.kernel.org/all/20230913111644.29889-5-hnagalla at ti.com/

build logs: https://paste.sr.ht/~hnagalla/be9d1c45e176ea8fa274ab13a3da43a9853fcf7f 

 drivers/remoteproc/Kconfig               |  13 +
 drivers/remoteproc/Makefile              |   1 +
 drivers/remoteproc/ti_k3_m4_remoteproc.c | 327 +++++++++++++++++++++++
 3 files changed, 341 insertions(+)
 create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa85..1a7c0330c91a 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -339,6 +339,19 @@ config TI_K3_DSP_REMOTEPROC
 	  It's safe to say N here if you're not interested in utilizing
 	  the DSP slave processors.
 
+config TI_K3_M4_REMOTEPROC
+	tristate "TI K3 M4 remoteproc support"
+	depends on ARCH_K3 || COMPILE_TEST
+	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 remote processor.
+
 config TI_K3_R5_REMOTEPROC
 	tristate "TI K3 R5 remoteproc support"
 	depends on ARCH_K3
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 55c552e27a45..e30908ca4bfc 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -37,5 +37,6 @@ obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
 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 ti_k3_common.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)	+= ti_k3_m4_remoteproc.o ti_k3_common.o
 obj-$(CONFIG_TI_K3_R5_REMOTEPROC)	+= ti_k3_r5_remoteproc.o
 obj-$(CONFIG_XLNX_R5_REMOTEPROC)	+= xlnx_r5_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..9eb313ce0325
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c
@@ -0,0 +1,327 @@
+// 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"
+#include "ti_k3_common.h"
+
+/*
+ * 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. This callback is invoked only in remoteproc mode.
+ */
+static int k3_m4_rproc_start(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	u32 boot_addr;
+	int ret;
+
+	ret = k3_rproc_request_mbox(rproc);
+	if (ret)
+		return ret;
+
+	boot_addr = rproc->bootaddr;
+	ret = k3_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. This callback is invoked only in remoteproc mode.
+ */
+static int k3_m4_rproc_stop(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+
+	mbox_free_channel(kproc->mbox);
+
+	k3_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. This callback is used only in IPC-only mode.
+ */
+static int k3_m4_rproc_attach(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	int ret;
+
+	ret = k3_rproc_request_mbox(rproc);
+	if (ret)
+		return ret;
+
+	dev_info(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. This callback is invoked only in
+ * IPC-only mode.
+ */
+static int k3_m4_rproc_detach(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+
+	mbox_free_channel(kproc->mbox);
+	dev_info(dev, "M4 deinitialized in IPC-only mode\n");
+	return 0;
+}
+
+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_rproc_kick,
+	.da_to_va	= k3_rproc_da_to_va,
+	.get_loaded_rsc_table = k3_get_loaded_rsc_table,
+};
+
+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_rproc_dev_data *data;
+	struct k3_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_probe(dev, ret, "failed to parse firmware-name property\n");
+		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_rproc_prepare;
+		rproc->ops->unprepare = k3_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);
+		dev_err_probe(dev, ret, "failed to get ti-sci handle\n");
+		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_probe(dev, ret, "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_probe(dev, ret, "failed to get reset\n");
+		goto put_sci;
+	}
+
+	kproc->tsp = k3_rproc_of_get_tsp(dev, kproc->ti_sci);
+	if (IS_ERR(kproc->tsp)) {
+		dev_err_probe(dev, PTR_ERR(kproc->tsp), "failed to construct ti-sci proc control\n");
+		ret = PTR_ERR(kproc->tsp);
+		goto put_sci;
+	}
+
+	ret = ti_sci_proc_request(kproc->tsp);
+	if (ret < 0) {
+		dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
+		goto free_tsp;
+	}
+
+	ret = k3_rproc_of_get_memories(pdev, kproc);
+	if (ret)
+		goto release_tsp;
+
+	ret = k3_rproc_of_get_sram_memories(pdev, kproc);
+	if (ret)
+		goto release_tsp;
+
+	ret = k3_reserved_mem_init(kproc);
+	if (ret) {
+		dev_err_probe(dev, ret, "reserved memory init failed\n");
+		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_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
+		goto release_mem;
+	}
+
+	/* configure devices for either remoteproc or IPC-only mode */
+	if (p_state) {
+		dev_info(dev, "configured M4 for IPC-only mode\n");
+		rproc->state = RPROC_DETACHED;
+		/* override rproc ops with only required IPC-only mode ops */
+		rproc->ops->prepare = NULL;
+		rproc->ops->unprepare = NULL;
+		rproc->ops->start = NULL;
+		rproc->ops->stop = NULL;
+		rproc->ops->attach = k3_m4_rproc_attach;
+		rproc->ops->detach = k3_m4_rproc_detach;
+		rproc->ops->get_loaded_rsc_table = k3_get_loaded_rsc_table;
+	} else {
+		dev_info(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_probe(dev, ret, "failed to get reset status\n");
+				goto release_mem;
+			} else if (ret == 0) {
+				dev_warn(dev, "local reset is deasserted for device\n");
+				k3_rproc_reset(kproc);
+			}
+		}
+	}
+
+	ret = rproc_add(rproc);
+	if (ret) {
+		dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
+		goto release_mem;
+	}
+
+	platform_set_drvdata(pdev, kproc);
+
+	return 0;
+
+release_mem:
+	k3_reserved_mem_exit(kproc);
+release_tsp:
+	ret1 = ti_sci_proc_release(kproc->tsp);
+	if (ret1)
+		dev_err_probe(dev, ret1, "failed to release proc\n");
+free_tsp:
+	kfree(kproc->tsp);
+put_sci:
+	ret1 = ti_sci_put_handle(kproc->ti_sci);
+	if (ret1)
+		dev_err_probe(dev, ret1, "failed to put ti_sci handle\n");
+free_rproc:
+	rproc_free(rproc);
+	return ret;
+}
+
+static int k3_m4_rproc_remove(struct platform_device *pdev)
+{
+	struct k3_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_reserved_mem_exit(kproc);
+	rproc_free(kproc->rproc);
+
+	return 0;
+}
+
+static const struct k3_rproc_mem_data am64_m4_mems[] = {
+	{ .name = "iram", .dev_addr = 0x0 },
+	{ .name = "dram", .dev_addr = 0x30000 },
+};
+
+static const struct k3_rproc_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.34.1



From hnagalla at ti.com  Fri Feb  2 09:55:36 2024
From: hnagalla at ti.com (Hari Nagalla)
Date: Fri, 2 Feb 2024 11:55:36 -0600
Subject: [PATCH v7 3/5] remoteproc: k3: Move out functions common with M4 driver
In-Reply-To: <20240202175538.1705-1-hnagalla@ti.com>
References: <20240202175538.1705-1-hnagalla@ti.com>
Message-ID: <20240202175538.1705-4-hnagalla@ti.com>

From: Martyn Welch <martyn.welch at collabora.com>

In the next commit we will be adding the M4F driver which shares a lot of
commonality with the DSP driver. Move this shared functionality out so
that it can be used by both drivers.

Signed-off-by: Martyn Welch <martyn.welch at collabora.com>
Signed-off-by: Hari Nagalla <hnagalla at ti.com>
---
Changes since v2:
 - New patch (reordered refactored from v2)

Changes since v3:
 - Removed "ipc_only" element from k3_rproc structure
 - Refactored to bring 3 more common functions

Changes since v4:
 - None

Changes since v5:
 - Rearranged the functions order to match with the functions in
   ti_k3_dsp_remoteproc.c to ease review.

Changes since v6:
 - Generated patch with -M/-B/-C options

link to v6:
https://lore.kernel.org/all/20230913111644.29889-4-hnagalla at ti.com/

 drivers/remoteproc/Makefile               |    2 +-
 drivers/remoteproc/ti_k3_common.c         |  583 ++++++++++
 drivers/remoteproc/ti_k3_dsp_remoteproc.c | 1277 ++++++---------------
 3 files changed, 952 insertions(+), 910 deletions(-)
 create mode 100644 drivers/remoteproc/ti_k3_common.c
 rewrite drivers/remoteproc/ti_k3_dsp_remoteproc.c (67%)

diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43ce..55c552e27a45 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -36,6 +36,6 @@ obj-$(CONFIG_RCAR_REMOTEPROC)		+= rcar_rproc.o
 obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
 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_DSP_REMOTEPROC)	+= ti_k3_dsp_remoteproc.o ti_k3_common.o
 obj-$(CONFIG_TI_K3_R5_REMOTEPROC)	+= ti_k3_r5_remoteproc.o
 obj-$(CONFIG_XLNX_R5_REMOTEPROC)	+= xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_common.c b/drivers/remoteproc/ti_k3_common.c
new file mode 100644
index 000000000000..62c7c5dba78a
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_common.c
@@ -0,0 +1,583 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Remote Processor(s) driver common code
+ *
+ * Refactored from ti_k3_dsp_remoteproc.c.
+ *
+ * ti_k3_dsp_remoteproc.c:
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ *	Suman Anna <s-anna at ti.com>
+ */
+
+#include <linux/io.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_address.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"
+#include "ti_k3_common.h"
+
+/**
+ * k3_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 K3 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_rproc_mbox_callback(struct mbox_client *client, void *data)
+{
+	struct k3_rproc *kproc = container_of(client, struct k3_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 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.
+ */
+void k3_rproc_kick(struct rproc *rproc, int vqid)
+{
+	struct k3_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);
+}
+EXPORT_SYMBOL_GPL(k3_rproc_kick);
+
+/* Put the remote processor into reset */
+int k3_rproc_reset(struct k3_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;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_reset);
+
+/* Release the remote processor from reset */
+int k3_rproc_release(struct k3_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;
+	}
+
+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;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_release);
+
+int k3_rproc_request_mbox(struct rproc *rproc)
+{
+	struct k3_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_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;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_request_mbox);
+
+/*
+ * The DSP and MCU cores have a local reset that affects only the CPU, and a
+ * generic module reset that powers on the device and allows the internal
+ * memories to be accessed while the local reset is asserted. This function is
+ * used to release the global reset on remote cores to allow loading into the
+ * 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 remote cores to run. This callback is invoked only in
+ * remoteproc mode.
+ */
+int k3_rproc_prepare(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	int ret;
+
+	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;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_prepare);
+
+/*
+ * 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 DSP, MCU cores. This completes the second portion of
+ * powering down the remote core. 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. This callback is invoked only in remoteproc mode.
+ */
+int k3_rproc_unprepare(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	int 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);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_unprepare);
+
+/*
+ * This function implements the .get_loaded_rsc_table() callback and is used
+ * to provide the resource table for a booted remote processor in IPC-only
+ * mode. The remote processor 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.
+ */
+struct resource_table *k3_get_loaded_rsc_table(struct rproc *rproc,
+					       size_t *rsc_table_sz)
+{
+	struct k3_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;
+}
+EXPORT_SYMBOL_GPL(k3_get_loaded_rsc_table);
+
+/*
+ * Custom function to translate a remote processor device address (internal
+ * RAMs only) to a kernel virtual address.  The remote processors can access
+ * their RAMs at either an internal address visible only from a remote
+ * processor, 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.
+ */
+void *k3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
+{
+	struct k3_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 remote-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 any SRAM regions using SoC-view addresses */
+	for (i = 0; i < kproc->num_sram; i++) {
+		dev_addr = kproc->sram[i].dev_addr;
+		size = kproc->sram[i].size;
+
+		if (da >= dev_addr && ((da + len) <= (dev_addr + size))) {
+			offset = da - dev_addr;
+			va = kproc->sram[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;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_da_to_va);
+
+int k3_rproc_of_get_memories(struct platform_device *pdev,
+			     struct k3_rproc *kproc)
+{
+	const struct k3_rproc_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;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_of_get_memories);
+
+int k3_rproc_of_get_sram_memories(struct platform_device *pdev,
+					   struct k3_rproc *kproc)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct device_node *sram_np;
+	struct resource res;
+	int num_sram;
+	int i, ret;
+
+	num_sram = of_property_count_elems_of_size(np, "sram", sizeof(phandle));
+	if (num_sram <= 0) {
+		dev_dbg(dev, "device does not use reserved on-chip memories, num_sram = %d\n",
+			num_sram);
+		return 0;
+	}
+
+	kproc->sram = devm_kcalloc(dev, num_sram, sizeof(*kproc->sram), GFP_KERNEL);
+	if (!kproc->sram)
+		return -ENOMEM;
+
+	for (i = 0; i < num_sram; i++) {
+		sram_np = of_parse_phandle(np, "sram", i);
+		if (!sram_np)
+			return -EINVAL;
+
+		if (!of_device_is_available(sram_np)) {
+			of_node_put(sram_np);
+			return -EINVAL;
+		}
+
+		ret = of_address_to_resource(sram_np, 0, &res);
+		of_node_put(sram_np);
+		if (ret)
+			return -EINVAL;
+
+		kproc->sram[i].bus_addr = res.start;
+		kproc->sram[i].dev_addr = res.start;
+		kproc->sram[i].size = resource_size(&res);
+		kproc->sram[i].cpu_addr = devm_ioremap_wc(dev, res.start,
+							 resource_size(&res));
+		if (!kproc->sram[i].cpu_addr) {
+			dev_err(dev, "failed to parse and map sram%d memory at %pad\n",
+				i, &res.start);
+			return -ENOMEM;
+		}
+
+		dev_dbg(dev, "memory sram%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
+			i, &kproc->sram[i].bus_addr,
+			kproc->sram[i].size, kproc->sram[i].cpu_addr,
+			kproc->sram[i].dev_addr);
+	}
+	kproc->num_sram = num_sram;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_of_get_sram_memories);
+int k3_reserved_mem_init(struct k3_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;
+}
+EXPORT_SYMBOL_GPL(k3_reserved_mem_init);
+
+void k3_reserved_mem_exit(struct k3_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);
+}
+EXPORT_SYMBOL_GPL(k3_reserved_mem_exit);
+
+struct ti_sci_proc *k3_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;
+}
+EXPORT_SYMBOL_GPL(k3_rproc_of_get_tsp);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TI K3 common Remoteproc support");
diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
dissimilarity index 67%
index ab882e3b7130..ebe23fc5ca44 100644
--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
@@ -1,909 +1,368 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI K3 DSP Remote Processor(s) driver
- *
- * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
- *	Suman Anna <s-anna at ti.com>
- */
-
-#include <linux/io.h>
-#include <linux/mailbox_client.h>
-#include <linux/module.h>
-#include <linux/of.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_dsp_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_dsp_mem {
-	void __iomem *cpu_addr;
-	phys_addr_t bus_addr;
-	u32 dev_addr;
-	size_t size;
-};
-
-/**
- * struct k3_dsp_mem_data - memory definitions for a DSP
- * @name: name for this memory entry
- * @dev_addr: device address for the memory entry
- */
-struct k3_dsp_mem_data {
-	const char *name;
-	const u32 dev_addr;
-};
-
-/**
- * struct k3_dsp_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_dsp_dev_data {
-	const struct k3_dsp_mem_data *mems;
-	u32 num_mems;
-	u32 boot_align_addr;
-	bool uses_lreset;
-};
-
-/**
- * struct k3_dsp_rproc - k3 DSP 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 DSP-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
- */
-struct k3_dsp_rproc {
-	struct device *dev;
-	struct rproc *rproc;
-	struct k3_dsp_mem *mem;
-	int num_mems;
-	struct k3_dsp_mem *rmem;
-	int num_rmems;
-	struct reset_control *reset;
-	const struct k3_dsp_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;
-};
-
-/**
- * k3_dsp_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_dsp_rproc_mbox_callback(struct mbox_client *client, void *data)
-{
-	struct k3_dsp_rproc *kproc = container_of(client, struct k3_dsp_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 DSP 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_dsp_rproc_kick(struct rproc *rproc, int vqid)
-{
-	struct k3_dsp_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 (%pe)\n",
-			ERR_PTR(ret));
-}
-
-/* Put the DSP processor into reset */
-static int k3_dsp_rproc_reset(struct k3_dsp_rproc *kproc)
-{
-	struct device *dev = kproc->dev;
-	int ret;
-
-	ret = reset_control_assert(kproc->reset);
-	if (ret) {
-		dev_err(dev, "local-reset assert failed (%pe)\n", ERR_PTR(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 (%pe)\n", ERR_PTR(ret));
-		if (reset_control_deassert(kproc->reset))
-			dev_warn(dev, "local-reset deassert back failed\n");
-	}
-
-	return ret;
-}
-
-/* Release the DSP processor from reset */
-static int k3_dsp_rproc_release(struct k3_dsp_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 (%pe)\n", ERR_PTR(ret));
-		return ret;
-	}
-
-lreset:
-	ret = reset_control_deassert(kproc->reset);
-	if (ret) {
-		dev_err(dev, "local-reset deassert failed, (%pe)\n", ERR_PTR(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_dsp_rproc_request_mbox(struct rproc *rproc)
-{
-	struct k3_dsp_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_dsp_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 (%pe)\n", ERR_PTR(ret));
-		mbox_free_channel(kproc->mbox);
-		return ret;
-	}
-
-	return 0;
-}
-/*
- * The C66x DSP cores have a local reset that affects only the CPU, and a
- * generic module reset that powers on the device and allows the DSP internal
- * memories to be accessed while the local reset is asserted. This function is
- * used to release the global reset on C66x DSPs to allow loading into the DSP
- * 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 C66x DSP cores run. This callback is invoked only in
- * remoteproc mode.
- */
-static int k3_dsp_rproc_prepare(struct rproc *rproc)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	int ret;
-
-	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 (%pe)\n",
-			ERR_PTR(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 C66x cores. This completes the second portion of
- * powering down the C66x DSP 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. This callback is invoked only in remoteproc mode.
- */
-static int k3_dsp_rproc_unprepare(struct rproc *rproc)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	int 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 (%pe)\n", ERR_PTR(ret));
-
-	return ret;
-}
-
-/*
- * Power up the DSP 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. This callback is invoked only in remoteproc mode.
- */
-static int k3_dsp_rproc_start(struct rproc *rproc)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	u32 boot_addr;
-	int ret;
-
-	ret = k3_dsp_rproc_request_mbox(rproc);
-	if (ret)
-		return ret;
-
-	boot_addr = rproc->bootaddr;
-	if (boot_addr & (kproc->data->boot_align_addr - 1)) {
-		dev_err(dev, "invalid boot address 0x%x, must be aligned on a 0x%x boundary\n",
-			boot_addr, kproc->data->boot_align_addr);
-		ret = -EINVAL;
-		goto put_mbox;
-	}
-
-	dev_err(dev, "booting DSP core using boot addr = 0x%x\n", boot_addr);
-	ret = ti_sci_proc_set_config(kproc->tsp, boot_addr, 0, 0);
-	if (ret)
-		goto put_mbox;
-
-	ret = k3_dsp_rproc_release(kproc);
-	if (ret)
-		goto put_mbox;
-
-	return 0;
-
-put_mbox:
-	mbox_free_channel(kproc->mbox);
-	return ret;
-}
-
-/*
- * Stop the DSP remote processor.
- *
- * This function puts the DSP processor into reset, and finishes processing
- * of any pending messages. This callback is invoked only in remoteproc mode.
- */
-static int k3_dsp_rproc_stop(struct rproc *rproc)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-
-	mbox_free_channel(kproc->mbox);
-
-	k3_dsp_rproc_reset(kproc);
-
-	return 0;
-}
-
-/*
- * Attach to a running DSP 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 DSP core. This callback is invoked only in IPC-only
- * mode.
- */
-static int k3_dsp_rproc_attach(struct rproc *rproc)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-	int ret;
-
-	ret = k3_dsp_rproc_request_mbox(rproc);
-	if (ret)
-		return ret;
-
-	dev_info(dev, "DSP initialized in IPC-only mode\n");
-	return 0;
-}
-
-/*
- * Detach from a running DSP remote processor (IPC-only mode)
- *
- * This rproc detach callback performs the opposite operation to attach callback
- * and only needs to release the mailbox, the DSP core is not stopped and will
- * be left to continue to run its booted firmware. This callback is invoked only
- * in IPC-only mode.
- */
-static int k3_dsp_rproc_detach(struct rproc *rproc)
-{
-	struct k3_dsp_rproc *kproc = rproc->priv;
-	struct device *dev = kproc->dev;
-
-	mbox_free_channel(kproc->mbox);
-	dev_info(dev, "DSP 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 DSP in IPC-only mode. The K3 DSP
- * 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. This callback is invoked only in
- * IPC-only mode.
- */
-static struct resource_table *k3_dsp_get_loaded_rsc_table(struct rproc *rproc,
-							  size_t *rsc_table_sz)
-{
-	struct k3_dsp_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 DSP device address (internal RAMs only) to a
- * kernel virtual address.  The DSPs can access their RAMs at either an internal
- * address visible only from a DSP, 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_dsp_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
-{
-	struct k3_dsp_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 DSP-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_dsp_rproc_ops = {
-	.start		= k3_dsp_rproc_start,
-	.stop		= k3_dsp_rproc_stop,
-	.kick		= k3_dsp_rproc_kick,
-	.da_to_va	= k3_dsp_rproc_da_to_va,
-};
-
-static int k3_dsp_rproc_of_get_memories(struct platform_device *pdev,
-					struct k3_dsp_rproc *kproc)
-{
-	const struct k3_dsp_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_dsp_reserved_mem_init(struct k3_dsp_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 (%pe)\n",
-			ERR_PTR(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 (%pe)\n",
-			ERR_PTR(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_dsp_reserved_mem_exit(struct k3_dsp_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_dsp_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_dsp_rproc_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
-	const struct k3_dsp_dev_data *data;
-	struct k3_dsp_rproc *kproc;
-	struct rproc *rproc;
-	const char *fw_name;
-	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)
-		return dev_err_probe(dev, ret, "failed to parse firmware-name property\n");
-
-	rproc = rproc_alloc(dev, dev_name(dev), &k3_dsp_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_dsp_rproc_prepare;
-		rproc->ops->unprepare = k3_dsp_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 = dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
-				    "failed to get ti-sci handle\n");
-		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_probe(dev, ret, "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 = dev_err_probe(dev, PTR_ERR(kproc->reset),
-				    "failed to get reset\n");
-		goto put_sci;
-	}
-
-	kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci);
-	if (IS_ERR(kproc->tsp)) {
-		ret = dev_err_probe(dev, PTR_ERR(kproc->tsp),
-				    "failed to construct ti-sci proc control\n");
-		goto put_sci;
-	}
-
-	ret = ti_sci_proc_request(kproc->tsp);
-	if (ret < 0) {
-		dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
-		goto free_tsp;
-	}
-
-	ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
-	if (ret)
-		goto release_tsp;
-
-	ret = k3_dsp_reserved_mem_init(kproc);
-	if (ret) {
-		dev_err_probe(dev, ret, "reserved memory init failed\n");
-		goto release_tsp;
-	}
-
-	ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
-					       NULL, &p_state);
-	if (ret) {
-		dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
-		goto release_mem;
-	}
-
-	/* configure J721E devices for either remoteproc or IPC-only mode */
-	if (p_state) {
-		dev_info(dev, "configured DSP for IPC-only mode\n");
-		rproc->state = RPROC_DETACHED;
-		/* override rproc ops with only required IPC-only mode ops */
-		rproc->ops->prepare = NULL;
-		rproc->ops->unprepare = NULL;
-		rproc->ops->start = NULL;
-		rproc->ops->stop = NULL;
-		rproc->ops->attach = k3_dsp_rproc_attach;
-		rproc->ops->detach = k3_dsp_rproc_detach;
-		rproc->ops->get_loaded_rsc_table = k3_dsp_get_loaded_rsc_table;
-	} else {
-		dev_info(dev, "configured DSP for remoteproc mode\n");
-		/*
-		 * ensure the DSP local reset is asserted to ensure the DSP
-		 * 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_probe(dev, ret, "failed to get reset status\n");
-				goto release_mem;
-			} else if (ret == 0) {
-				dev_warn(dev, "local reset is deasserted for device\n");
-				k3_dsp_rproc_reset(kproc);
-			}
-		}
-	}
-
-	ret = rproc_add(rproc);
-	if (ret) {
-		dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
-		goto release_mem;
-	}
-
-	platform_set_drvdata(pdev, kproc);
-
-	return 0;
-
-release_mem:
-	k3_dsp_reserved_mem_exit(kproc);
-release_tsp:
-	ret1 = ti_sci_proc_release(kproc->tsp);
-	if (ret1)
-		dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(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 (%pe)\n", ERR_PTR(ret1));
-free_rproc:
-	rproc_free(rproc);
-	return ret;
-}
-
-static void k3_dsp_rproc_remove(struct platform_device *pdev)
-{
-	struct k3_dsp_rproc *kproc = platform_get_drvdata(pdev);
-	struct rproc *rproc = kproc->rproc;
-	struct device *dev = &pdev->dev;
-	int ret;
-
-	if (rproc->state == RPROC_ATTACHED) {
-		ret = rproc_detach(rproc);
-		if (ret) {
-			/* Note this error path leaks resources */
-			dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(ret));
-			return;
-		}
-	}
-
-	rproc_del(kproc->rproc);
-
-	ret = ti_sci_proc_release(kproc->tsp);
-	if (ret)
-		dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret));
-
-	kfree(kproc->tsp);
-
-	ret = ti_sci_put_handle(kproc->ti_sci);
-	if (ret)
-		dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret));
-
-	k3_dsp_reserved_mem_exit(kproc);
-	rproc_free(kproc->rproc);
-}
-
-static const struct k3_dsp_mem_data c66_mems[] = {
-	{ .name = "l2sram", .dev_addr = 0x800000 },
-	{ .name = "l1pram", .dev_addr = 0xe00000 },
-	{ .name = "l1dram", .dev_addr = 0xf00000 },
-};
-
-/* C71x cores only have a L1P Cache, there are no L1P SRAMs */
-static const struct k3_dsp_mem_data c71_mems[] = {
-	{ .name = "l2sram", .dev_addr = 0x800000 },
-	{ .name = "l1dram", .dev_addr = 0xe00000 },
-};
-
-static const struct k3_dsp_mem_data c7xv_mems[] = {
-	{ .name = "l2sram", .dev_addr = 0x800000 },
-};
-
-static const struct k3_dsp_dev_data c66_data = {
-	.mems = c66_mems,
-	.num_mems = ARRAY_SIZE(c66_mems),
-	.boot_align_addr = SZ_1K,
-	.uses_lreset = true,
-};
-
-static const struct k3_dsp_dev_data c71_data = {
-	.mems = c71_mems,
-	.num_mems = ARRAY_SIZE(c71_mems),
-	.boot_align_addr = SZ_2M,
-	.uses_lreset = false,
-};
-
-static const struct k3_dsp_dev_data c7xv_data = {
-	.mems = c7xv_mems,
-	.num_mems = ARRAY_SIZE(c7xv_mems),
-	.boot_align_addr = SZ_2M,
-	.uses_lreset = false,
-};
-
-static const struct of_device_id k3_dsp_of_match[] = {
-	{ .compatible = "ti,j721e-c66-dsp", .data = &c66_data, },
-	{ .compatible = "ti,j721e-c71-dsp", .data = &c71_data, },
-	{ .compatible = "ti,j721s2-c71-dsp", .data = &c71_data, },
-	{ .compatible = "ti,am62a-c7xv-dsp", .data = &c7xv_data, },
-	{ /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, k3_dsp_of_match);
-
-static struct platform_driver k3_dsp_rproc_driver = {
-	.probe	= k3_dsp_rproc_probe,
-	.remove_new = k3_dsp_rproc_remove,
-	.driver	= {
-		.name = "k3-dsp-rproc",
-		.of_match_table = k3_dsp_of_match,
-	},
-};
-
-module_platform_driver(k3_dsp_rproc_driver);
-
-MODULE_AUTHOR("Suman Anna <s-anna at ti.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("TI K3 DSP Remoteproc driver");
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 DSP Remote Processor(s) driver
+ *
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ *	Suman Anna <s-anna at ti.com>
+ */
+
+#include <linux/io.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of.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"
+#include "ti_k3_common.h"
+
+/*
+ * Power up the DSP 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. This callback is invoked only in remoteproc mode.
+ */
+static int k3_dsp_rproc_start(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	u32 boot_addr;
+	int ret;
+
+	ret = k3_rproc_request_mbox(rproc);
+	if (ret)
+		return ret;
+
+	boot_addr = rproc->bootaddr;
+	if (boot_addr & (kproc->data->boot_align_addr - 1)) {
+		dev_err(dev, "invalid boot address 0x%x, must be aligned on a 0x%x boundary\n",
+			boot_addr, kproc->data->boot_align_addr);
+		ret = -EINVAL;
+		goto put_mbox;
+	}
+
+	dev_err(dev, "booting DSP core using boot addr = 0x%x\n", boot_addr);
+	ret = ti_sci_proc_set_config(kproc->tsp, boot_addr, 0, 0);
+	if (ret)
+		goto put_mbox;
+
+	ret = k3_rproc_release(kproc);
+	if (ret)
+		goto put_mbox;
+
+	return 0;
+
+put_mbox:
+	mbox_free_channel(kproc->mbox);
+	return ret;
+}
+
+/*
+ * Stop the DSP remote processor.
+ *
+ * This function puts the DSP processor into reset, and finishes processing
+ * of any pending messages. This callback is invoked only in remoteproc mode.
+ */
+static int k3_dsp_rproc_stop(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+
+	mbox_free_channel(kproc->mbox);
+
+	k3_rproc_reset(kproc);
+
+	return 0;
+}
+
+/*
+ * Attach to a running DSP 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 DSP core. This callback is invoked only in IPC-only
+ * mode.
+ */
+static int k3_dsp_rproc_attach(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	int ret;
+
+	ret = k3_rproc_request_mbox(rproc);
+	if (ret)
+		return ret;
+
+	dev_info(dev, "DSP initialized in IPC-only mode\n");
+	return 0;
+}
+
+/*
+ * Detach from a running DSP remote processor (IPC-only mode)
+ *
+ * This rproc detach callback performs the opposite operation to attach callback
+ * and only needs to release the mailbox, the DSP core is not stopped and will
+ * be left to continue to run its booted firmware. This callback is invoked only
+ * in IPC-only mode.
+ */
+static int k3_dsp_rproc_detach(struct rproc *rproc)
+{
+	struct k3_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+
+	mbox_free_channel(kproc->mbox);
+	dev_info(dev, "DSP deinitialized in IPC-only mode\n");
+	return 0;
+}
+
+
+static const struct rproc_ops k3_dsp_rproc_ops = {
+	.start		= k3_dsp_rproc_start,
+	.stop		= k3_dsp_rproc_stop,
+	.kick		= k3_rproc_kick,
+	.da_to_va	= k3_rproc_da_to_va,
+};
+
+static int k3_dsp_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	const struct k3_rproc_dev_data *data;
+	struct k3_rproc *kproc;
+	struct rproc *rproc;
+	const char *fw_name;
+	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)
+		return dev_err_probe(dev, ret, "failed to parse firmware-name property\n");
+
+	rproc = rproc_alloc(dev, dev_name(dev), &k3_dsp_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_rproc_prepare;
+		rproc->ops->unprepare = k3_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 = dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
+				    "failed to get ti-sci handle\n");
+		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_probe(dev, ret, "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 = dev_err_probe(dev, PTR_ERR(kproc->reset),
+				    "failed to get reset\n");
+		goto put_sci;
+	}
+
+	kproc->tsp = k3_rproc_of_get_tsp(dev, kproc->ti_sci);
+	if (IS_ERR(kproc->tsp)) {
+		ret = dev_err_probe(dev, PTR_ERR(kproc->tsp),
+				    "failed to construct ti-sci proc control\n");
+		goto put_sci;
+	}
+
+	ret = ti_sci_proc_request(kproc->tsp);
+	if (ret < 0) {
+		dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
+		goto free_tsp;
+	}
+
+	ret = k3_rproc_of_get_memories(pdev, kproc);
+	if (ret)
+		goto release_tsp;
+
+	ret = k3_reserved_mem_init(kproc);
+	if (ret) {
+		dev_err_probe(dev, ret, "reserved memory init failed\n");
+		goto release_tsp;
+	}
+
+	ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
+					       NULL, &p_state);
+	if (ret) {
+		dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
+		goto release_mem;
+	}
+
+	/* configure J721E devices for either remoteproc or IPC-only mode */
+	if (p_state) {
+		dev_info(dev, "configured DSP for IPC-only mode\n");
+		rproc->state = RPROC_DETACHED;
+		/* override rproc ops with only required IPC-only mode ops */
+		rproc->ops->prepare = NULL;
+		rproc->ops->unprepare = NULL;
+		rproc->ops->start = NULL;
+		rproc->ops->stop = NULL;
+		rproc->ops->attach = k3_dsp_rproc_attach;
+		rproc->ops->detach = k3_dsp_rproc_detach;
+		rproc->ops->get_loaded_rsc_table = k3_get_loaded_rsc_table;
+	} else {
+		dev_info(dev, "configured DSP for remoteproc mode\n");
+		/*
+		 * ensure the DSP local reset is asserted to ensure the DSP
+		 * 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_probe(dev, ret, "failed to get reset status\n");
+				goto release_mem;
+			} else if (ret == 0) {
+				dev_warn(dev, "local reset is deasserted for device\n");
+				k3_rproc_reset(kproc);
+			}
+		}
+	}
+
+	ret = rproc_add(rproc);
+	if (ret) {
+		dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
+		goto release_mem;
+	}
+
+	platform_set_drvdata(pdev, kproc);
+
+	return 0;
+
+release_mem:
+	k3_reserved_mem_exit(kproc);
+release_tsp:
+	ret1 = ti_sci_proc_release(kproc->tsp);
+	if (ret1)
+		dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(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 (%pe)\n", ERR_PTR(ret1));
+free_rproc:
+	rproc_free(rproc);
+	return ret;
+}
+
+static void k3_dsp_rproc_remove(struct platform_device *pdev)
+{
+	struct k3_rproc *kproc = platform_get_drvdata(pdev);
+	struct rproc *rproc = kproc->rproc;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	if (rproc->state == RPROC_ATTACHED) {
+		ret = rproc_detach(rproc);
+		if (ret) {
+			/* Note this error path leaks resources */
+			dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(ret));
+			return;
+		}
+	}
+
+	rproc_del(kproc->rproc);
+
+	ret = ti_sci_proc_release(kproc->tsp);
+	if (ret)
+		dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret));
+
+	kfree(kproc->tsp);
+
+	ret = ti_sci_put_handle(kproc->ti_sci);
+	if (ret)
+		dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret));
+
+	k3_reserved_mem_exit(kproc);
+	rproc_free(kproc->rproc);
+}
+
+static const struct k3_rproc_mem_data c66_mems[] = {
+	{ .name = "l2sram", .dev_addr = 0x800000 },
+	{ .name = "l1pram", .dev_addr = 0xe00000 },
+	{ .name = "l1dram", .dev_addr = 0xf00000 },
+};
+
+/* C71x cores only have a L1P Cache, there are no L1P SRAMs */
+static const struct k3_rproc_mem_data c71_mems[] = {
+	{ .name = "l2sram", .dev_addr = 0x800000 },
+	{ .name = "l1dram", .dev_addr = 0xe00000 },
+};
+
+static const struct k3_rproc_mem_data c7xv_mems[] = {
+	{ .name = "l2sram", .dev_addr = 0x800000 },
+};
+
+static const struct k3_rproc_dev_data c66_data = {
+	.mems = c66_mems,
+	.num_mems = ARRAY_SIZE(c66_mems),
+	.boot_align_addr = SZ_1K,
+	.uses_lreset = true,
+};
+
+static const struct k3_rproc_dev_data c71_data = {
+	.mems = c71_mems,
+	.num_mems = ARRAY_SIZE(c71_mems),
+	.boot_align_addr = SZ_2M,
+	.uses_lreset = false,
+};
+
+static const struct k3_rproc_dev_data c7xv_data = {
+	.mems = c7xv_mems,
+	.num_mems = ARRAY_SIZE(c7xv_mems),
+	.boot_align_addr = SZ_2M,
+	.uses_lreset = false,
+};
+
+static const struct of_device_id k3_dsp_of_match[] = {
+	{ .compatible = "ti,j721e-c66-dsp", .data = &c66_data, },
+	{ .compatible = "ti,j721e-c71-dsp", .data = &c71_data, },
+	{ .compatible = "ti,j721s2-c71-dsp", .data = &c71_data, },
+	{ .compatible = "ti,am62a-c7xv-dsp", .data = &c7xv_data, },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, k3_dsp_of_match);
+
+static struct platform_driver k3_dsp_rproc_driver = {
+	.probe	= k3_dsp_rproc_probe,
+	.remove_new = k3_dsp_rproc_remove,
+	.driver	= {
+		.name = "k3-dsp-rproc",
+		.of_match_table = k3_dsp_of_match,
+	},
+};
+
+module_platform_driver(k3_dsp_rproc_driver);
+
+MODULE_AUTHOR("Suman Anna <s-anna at ti.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TI K3 DSP Remoteproc driver");
-- 
2.34.1



From lkp at intel.com  Fri Feb  2 10:02:15 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 3 Feb 2024 02:02:15 +0800
Subject: [RESEND PATCH v6 02/12] firmware: qcom: scm: enable the TZ mem
 allocator
In-Reply-To: <20240122102157.22761-3-brgl@bgdev.pl>
References: <20240122102157.22761-3-brgl@bgdev.pl>
Message-ID: <202402030101.nxmgLcAB-lkp@intel.com>

Hi Bartosz,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on krzk-dt/for-next v6.8-rc2 next-20240202]
[cannot apply to arm64/for-next/core]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Bartosz-Golaszewski/firmware-qcom-add-a-dedicated-TrustZone-buffer-allocator/20240122-182633
base:   linus/master
patch link:    https://lore.kernel.org/r/20240122102157.22761-3-brgl%40bgdev.pl
patch subject: [RESEND PATCH v6 02/12] firmware: qcom: scm: enable the TZ mem allocator
config: i386-buildonly-randconfig-004-20240202 (https://download.01.org/0day-ci/archive/20240203/202402030101.nxmgLcAB-lkp at intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240203/202402030101.nxmgLcAB-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402030101.nxmgLcAB-lkp at intel.com/

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: gen_pool_create
   >>> referenced by qcom_tzmem.c
   >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_new) in archive vmlinux.a
--
>> ld.lld: error: undefined symbol: gen_pool_best_fit
   >>> referenced by qcom_tzmem.c
   >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_new) in archive vmlinux.a
--
>> ld.lld: error: undefined symbol: gen_pool_set_algo
   >>> referenced by qcom_tzmem.c
   >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_new) in archive vmlinux.a
--
>> ld.lld: error: undefined symbol: gen_pool_add_owner
   >>> referenced by qcom_tzmem.c
   >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_new) in archive vmlinux.a
--
>> ld.lld: error: undefined symbol: gen_pool_destroy
   >>> referenced by qcom_tzmem.c
   >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_new) in archive vmlinux.a
   >>> referenced by qcom_tzmem.c
   >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_free) in archive vmlinux.a
--
>> ld.lld: error: undefined symbol: gen_pool_alloc_algo_owner
   >>> referenced by qcom_tzmem.c
   >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_alloc) in archive vmlinux.a
--
>> ld.lld: error: undefined symbol: gen_pool_virt_to_phys
   >>> referenced by qcom_tzmem.c
   >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_alloc) in archive vmlinux.a
--
>> ld.lld: error: undefined symbol: gen_pool_free_owner
   >>> referenced by qcom_tzmem.c
   >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_alloc) in archive vmlinux.a
   >>> referenced by qcom_tzmem.c
   >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_free) in archive vmlinux.a

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From linux at armlinux.org.uk  Fri Feb  2 10:05:36 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 2 Feb 2024 18:05:36 +0000
Subject: [PATCH net-next v3 1/7] net: dsa: mt7530: empty default case on
 mt7530_setup_port5()
In-Reply-To: <e3b4add6-425c-46ca-9da5-8713055fc422@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-1-63d5adae99ca@arinc9.com>
 <ZbzUotyQm/FyKK7G@shell.armlinux.org.uk>
 <e3b4add6-425c-46ca-9da5-8713055fc422@arinc9.com>
Message-ID: <Zb0u8NY0q6ay17j5@shell.armlinux.org.uk>

On Fri, Feb 02, 2024 at 08:44:39PM +0300, Ar?n? ?NAL wrote:
> On 2.02.2024 14:40, Russell King (Oracle) wrote:
> > While reviewing this change, but not related to it, I notice that this
> > function sets the TX delay based on the RGMII interface mode. This isn't
> > correct. I've explained why this is this many times in the past, but
> > essentially it comes down to the model:
> > 
> > 
> > phy-mode in NIC node	Network driver	PCB		PHY
> > rgmii			no delays	delays		no delays
> > rgmii-id		no delays	no delays	tx/rx delays
> > rgmii-txid		no delays	no delays	tx delays
> > rgmii-rxid		no delays	no delays	rx delays
> > 
> > Then we have rx-internal-delay-ps and tx-internal-delay-ps in the NIC
> > node which define the RGMII delays at the local end and similar
> > properties for the PHY node.
> > 
> > 
> > So, if we take the view that, when a switch is connected to a NIC in
> > RGMII mode, then the phy-mode specified delays still should not impact
> > the local NIC.
> > 
> > Now, for the switch, we specify the phy-mode in the port node as well.
> > Consider the case of a switch port connected to a RGMII PHY. This has
> > to operate in exactly the same way as a normal NIC - that is, the
> > RGMII delays at the port should be ignored as it's the responsibility
> > of a PHY.
> > 
> > The final scenario to examine is the case of a RGMII switch port
> > connected to a NIC. The NIC's phy-mode has no way to be communicated
> > to DSA or vice versa, so neither phy-mode can impact the other side
> > of the RGMII link, but should only place the link into RGMII mode.
> > Given everything I've said above, the only way to configure RGMII
> > delays is via the rx-internal-delay-ps and tx-internal-delay-ps
> > properties. So, DSA drivers should _not_ be configuring their ports
> > with RGMII delays based on the RGMII phy interface mode.
> > 
> > The above is my purely logically reasoned point of view on this
> > subject. Others may have other (to me completely illogical)
> > interpretations that can only lead to interoperability issues.
> 
> I will address this with the next patch series. Thank you for explaining it
> in detail.

This is a good time to point out not to rush with the next patch
series, as my email will _likely_ provoke some additional discussion
from Andrew and/or Vladimir. So please give it a few days (maybe
around the middle of next week) to give them time to consider my
email and respond.

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


From Dave.Martin at arm.com  Fri Feb  2 10:07:54 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Fri, 2 Feb 2024 18:07:54 +0000
Subject: [PATCH] regset: use vmalloc() for regset_get_alloc()
In-Reply-To: <20240202165524.GD2087318@ZenIV>
References: <20240201171159.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924@changeid>
 <20240202012249.GU2087318@ZenIV>
 <CAD=FV=X5dpMyCGg4Xn+ApRwmiLB5zB0LTMCoSfW_X6eAsfQy8w@mail.gmail.com>
 <20240202030438.GV2087318@ZenIV>
 <CAD=FV=Wbq7R9AirvxnW1aWoEnp2fWQrwBsxsDB46xbfTLHCZ4w@mail.gmail.com>
 <20240202034925.GW2087318@ZenIV>
 <20240202040503.GX2087318@ZenIV>
 <CAD=FV=X93KNMF4NwQY8uh-L=1J8PrDFQYu-cqSd+KnY5+Pq+_w@mail.gmail.com>
 <20240202164947.GC2087318@ZenIV>
 <20240202165524.GD2087318@ZenIV>
Message-ID: <Zb0vem7KC28gmT5U@e133380.arm.com>

On Fri, Feb 02, 2024 at 04:55:24PM +0000, Al Viro wrote:
> On Fri, Feb 02, 2024 at 04:49:47PM +0000, Al Viro wrote:
> > > +folks from `./scripts/get_maintainer.pl -f arch/arm64/kernel/ptrace.c`
> > > 
> > > Trying to follow the macros to see where "n" comes from is a maze of
> > > twisty little passages, all alike. Hopefully someone from the ARM
> > > world can help tell if the value of 17474 for n here is correct or if
> > > something is wonky.

Nope, that's the "correct" answer...

> > 
> > It might be interesting to have it print the return value of __regset_get()
> > in those cases; if *that* is huge, we really have a problem.  If it ends up
> > small enough to fit into few pages, OTOH...
> > 
> > SVE_VQ_MAX is defined as 255; is that really in units of 128 bits?  IOW,
> > do we really expect to support 32Kbit registers?  That would drive the
> > size into that range, all right, but it would really suck on context
> > switches.
> > 
> > I could be misreading it, though - the macros in there are not easy to
> > follow and I've never dealt with SVE before, so take the above with
> > a cartload of salt.
> 
> Worse - it's SVE_VQ_MAX is 512; sorry about the confusion.  OK, that would
> certainly explain the size (header + 32 registers, each up to 512 * 16 bytes),
> but... ouch.

Mark Brown [+ Cc] has been taking care of SVE in my absence, but
from memory:

The SVE architecture has a really big maximum vector size (16 * 128 =
2048 bits), and there is a theoretical possibility of it getting bigger
in the future, though unlikely.

Real platforms to date have a much smaller limit, though Qemu can go up
to 2048 bits IIUC.

My aim when working on the ABI was to future-proof it against
foreseeable expansion on the architecture side, but this does mean that
we cannot statically determine a sane limit for the vector size.


I suppose we could have had a more sane limit built into the kernel or a
Kconfig option for it, but it seemed simpler just to determine the size
dynamically depending on the task's current state.  This is not so
important for coredumps, but for the the gdbstub wire protocol etc. it
seemed undesirable to have the regset larger than needed.

Hence the reason for adding ->get_size() in
27e64b4be4b8 ("regset: Add support for dynamically sized regsets").

What I guess was not so obvious from the commit message is the
expected relationship between the actual and maximum possible size
of the regset: for SVE the actual size is in practice going to be *much*
smaller than the max, while the max is crazy large because of being an
ABI design limit chosen for futureproofing purposes.



So, if the only reason for trying to migrate to vmalloc() is to cope
with an insanely sized regset on arm64, I think somehow or other we can
avoid that.

Options:

 a) bring back ->get_size() so that we can allocate the correct size
before generating the regset data;

 b) make aarch64_regsets[] __ro_after_init and set
aarch64_regsets[REGSET_SVE].n based on the boot-time probed maximum size
(which will be sane); or

 c) allow membufs to grow if needed (sounds fragile though, and may be
hard to justify just for one arch?).


Thoughts?

If people don't want to bring back get_size(), then (b) doesn't look
too bad.

Cheers
---Dave


From bartosz.golaszewski at linaro.org  Fri Feb  2 10:10:38 2024
From: bartosz.golaszewski at linaro.org (Bartosz Golaszewski)
Date: Fri, 2 Feb 2024 19:10:38 +0100
Subject: [RESEND PATCH v6 02/12] firmware: qcom: scm: enable the TZ mem allocator
In-Reply-To: <202402030101.nxmgLcAB-lkp@intel.com>
References: <20240122102157.22761-3-brgl@bgdev.pl> <202402030101.nxmgLcAB-lkp@intel.com>
Message-ID: <CACMJSetk29BXrb2ywuWPCsvkDn9k6+0gTbcxmZBUyJteJG2=hA@mail.gmail.com>

On Fri, 2 Feb 2024 at 19:02, kernel test robot <lkp at intel.com> wrote:
>
> Hi Bartosz,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on krzk-dt/for-next v6.8-rc2 next-20240202]
> [cannot apply to arm64/for-next/core]
> [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#_base_tree_information]
>
> url:    https://github.com/intel-lab-lkp/linux/commits/Bartosz-Golaszewski/firmware-qcom-add-a-dedicated-TrustZone-buffer-allocator/20240122-182633
> base:   linus/master
> patch link:    https://lore.kernel.org/r/20240122102157.22761-3-brgl%40bgdev.pl
> patch subject: [RESEND PATCH v6 02/12] firmware: qcom: scm: enable the TZ mem allocator
> config: i386-buildonly-randconfig-004-20240202 (https://download.01.org/0day-ci/archive/20240203/202402030101.nxmgLcAB-lkp at intel.com/config)
> compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240203/202402030101.nxmgLcAB-lkp at intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp at intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202402030101.nxmgLcAB-lkp at intel.com/
>
> All errors (new ones prefixed by >>):
>
> >> ld.lld: error: undefined symbol: gen_pool_create
>    >>> referenced by qcom_tzmem.c
>    >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_new) in archive vmlinux.a
> --
> >> ld.lld: error: undefined symbol: gen_pool_best_fit
>    >>> referenced by qcom_tzmem.c
>    >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_new) in archive vmlinux.a
> --
> >> ld.lld: error: undefined symbol: gen_pool_set_algo
>    >>> referenced by qcom_tzmem.c
>    >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_new) in archive vmlinux.a
> --
> >> ld.lld: error: undefined symbol: gen_pool_add_owner
>    >>> referenced by qcom_tzmem.c
>    >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_new) in archive vmlinux.a
> --
> >> ld.lld: error: undefined symbol: gen_pool_destroy
>    >>> referenced by qcom_tzmem.c
>    >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_new) in archive vmlinux.a
>    >>> referenced by qcom_tzmem.c
>    >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_pool_free) in archive vmlinux.a
> --
> >> ld.lld: error: undefined symbol: gen_pool_alloc_algo_owner
>    >>> referenced by qcom_tzmem.c
>    >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_alloc) in archive vmlinux.a
> --
> >> ld.lld: error: undefined symbol: gen_pool_virt_to_phys
>    >>> referenced by qcom_tzmem.c
>    >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_alloc) in archive vmlinux.a
> --
> >> ld.lld: error: undefined symbol: gen_pool_free_owner
>    >>> referenced by qcom_tzmem.c
>    >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_alloc) in archive vmlinux.a
>    >>> referenced by qcom_tzmem.c
>    >>>               drivers/firmware/qcom/qcom_tzmem.o:(qcom_tzmem_free) in archive vmlinux.a
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki

Huh, strange that it took so long to report it. Seems like QCOM_TZMEM
needs to select GENERIC_ALLOCATOR in Kconfig.

Bart


From lkp at intel.com  Fri Feb  2 10:12:28 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 3 Feb 2024 02:12:28 +0800
Subject: [PATCH 3/5] media: mali-c55: Add Mali-C55 ISP driver
In-Reply-To: <20240131164709.810587-4-dan.scally@ideasonboard.com>
References: <20240131164709.810587-4-dan.scally@ideasonboard.com>
Message-ID: <202402030114.spgdRGpC-lkp@intel.com>

Hi Daniel,

kernel test robot noticed the following build warnings:

[auto build test WARNING on media-tree/master]
[also build test WARNING on linuxtv-media-stage/master linus/master v6.8-rc2 next-20240202]
[cannot apply to sailus-media-tree/streams]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Daniel-Scally/media-uapi-Add-MEDIA_BUS_FMT_RGB202020_1X60-format-code/20240201-005029
base:   git://linuxtv.org/media_tree.git master
patch link:    https://lore.kernel.org/r/20240131164709.810587-4-dan.scally%40ideasonboard.com
patch subject: [PATCH 3/5] media: mali-c55: Add Mali-C55 ISP driver
config: arc-randconfig-r132-20240202 (https://download.01.org/0day-ci/archive/20240203/202402030114.spgdRGpC-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20240203/202402030114.spgdRGpC-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402030114.spgdRGpC-lkp at intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/media/platform/arm/mali-c55/mali-c55-core.c:33:12: sparse: sparse: symbol 'mali_c55_interrupt_names' was not declared. Should it be static?
>> drivers/media/platform/arm/mali-c55/mali-c55-core.c:602:29: sparse: sparse: Using plain integer as NULL pointer

vim +/mali_c55_interrupt_names +33 drivers/media/platform/arm/mali-c55/mali-c55-core.c

    32	
  > 33	const char * const mali_c55_interrupt_names[] = {
    34		[MALI_C55_IRQ_ISP_START] = "ISP start",
    35		[MALI_C55_IRQ_ISP_DONE] = "ISP done",
    36		[MALI_C55_IRQ_MCM_ERROR] = "Multi-context management error",
    37		[MALI_C55_IRQ_BROKEN_FRAME_ERROR] = "Broken frame error",
    38		[MALI_C55_IRQ_MET_AF_DONE] = "AF metering done",
    39		[MALI_C55_IRQ_MET_AEXP_DONE] = "AEXP metering done",
    40		[MALI_C55_IRQ_MET_AWB_DONE] = "AWB metering done",
    41		[MALI_C55_IRQ_AEXP_1024_DONE] = "AEXP 1024-bit histogram done",
    42		[MALI_C55_IRQ_IRIDIX_MET_DONE] = "Iridix metering done",
    43		[MALI_C55_IRQ_LUT_INIT_DONE] = "LUT memory init done",
    44		[MALI_C55_IRQ_FR_Y_DONE] = "Full resolution Y plane DMA done",
    45		[MALI_C55_IRQ_FR_UV_DONE] = "Full resolution U/V plane DMA done",
    46		[MALI_C55_IRQ_DS_Y_DONE] = "Downscale Y plane DMA done",
    47		[MALI_C55_IRQ_DS_UV_DONE] = "Downscale U/V plane DMA done",
    48		[MALI_C55_IRQ_LINEARIZATION_DONE] = "Linearisation done",
    49		[MALI_C55_IRQ_RAW_FRONTEND_DONE] = "Raw frontend processing done",
    50		[MALI_C55_IRQ_NOISE_REDUCTION_DONE] = "Noise reduction done",
    51		[MALI_C55_IRQ_IRIDIX_DONE] = "Iridix done",
    52		[MALI_C55_IRQ_BAYER2RGB_DONE] = "Bayer to RGB conversion done",
    53		[MALI_C55_IRQ_WATCHDOG_TIMER] = "Watchdog timer timed out",
    54		[MALI_C55_IRQ_FRAME_COLLISION] = "Frame collision error",
    55		[MALI_C55_IRQ_UNUSED] = "IRQ bit unused",
    56		[MALI_C55_IRQ_DMA_ERROR] = "DMA error",
    57		[MALI_C55_IRQ_INPUT_STOPPED] = "Input port safely stopped",
    58		[MALI_C55_IRQ_MET_AWB_TARGET1_HIT] = "AWB metering target 1 address hit",
    59		[MALI_C55_IRQ_MET_AWB_TARGET2_HIT] = "AWB metering target 2 address hit"
    60	};
    61	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From rafael at kernel.org  Fri Feb  2 10:14:23 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Fri, 2 Feb 2024 19:14:23 +0100
Subject: [PATCH v1 01/18] thermal: core: Change governor name to const
 char pointer
In-Reply-To: <6f8021d5-50af-40c5-983e-cd203b1b3683@collabora.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
 <20240130111250.185718-2-angelogioacchino.delregno@collabora.com>
 <CAJZ5v0hOcS0Fm2-mKWtc1-0ym33XuH=B39GGL9b6MfGSqeERkQ@mail.gmail.com> <6f8021d5-50af-40c5-983e-cd203b1b3683@collabora.com>
Message-ID: <CAJZ5v0icS+JC9oZLYwYu=TUuNFDc+MMDYjijZe9LhT+2VHpXNQ@mail.gmail.com>

On Fri, Feb 2, 2024 at 11:01?AM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Il 01/02/24 19:37, Rafael J. Wysocki ha scritto:
> > On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
> > <angelogioacchino.delregno at collabora.com> wrote:
> >>
> >> All users are already assigning a const char * to the `governor_name`
> >> member of struct thermal_zone_params and to the `name` member of
> >> struct thermal_governor.
> >> Even if users are technically wrong, it just makes more sense to change
> >> this member to be a const char pointer instead of doing the other way
> >> around.
> >>
> >> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> >
> > Acked-by: Rafael J. Wysocki <rafael at kernel.org>
> >
> > or I can pick it up right away if you want me to do that.
> >
>
> I appreciate having less patches to carry over with new series versions.
>
> Whatever you can take, please feel free to pick directly :-)

OK, applied (as 6.9 material).

Thanks!


From arinc.unal at arinc9.com  Fri Feb  2 10:16:02 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Fri, 2 Feb 2024 21:16:02 +0300
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
 <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>
Message-ID: <5b744f7f-2f63-4219-a0e9-8f08267b1fdd@arinc9.com>

On 2.02.2024 14:48, Russell King (Oracle) wrote:
> On Fri, Feb 02, 2024 at 12:19:10PM +0300, Ar?n? ?NAL via B4 Relay wrote:
>> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
>>
>> The crystal frequency concerns the switch core. The frequency should be
>> checked when the switch is being set up so the driver can reject the
>> unsupported hardware earlier and without requiring port 6 to be used.
>>
>> Move it to mt7530_setup(). Drop the unnecessary function printing.
>>
>> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
>> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
>> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
> 
> I would prefer this to be earlier in the series, before patch 2 which
> moves mt7530_setup_port6() to be called from mac_config(). mac_config()
> is supposed to be configuration error-free - in other words, all state
> should have been checked before hand.

I agree but mt7530_mac_config() is not a void function yet. The
mac_port_config member of the mt753x_info structure points to this
function. My next patch series gets rid of all useless error returns on the
phylink path and change mac_port_config to void. So I don't think working
on this patch series further will worth the effort. I'd rather have this
version applied as is.

Ar?n?


From daniel at makrotopia.org  Fri Feb  2 10:39:18 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Fri, 2 Feb 2024 18:39:18 +0000
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <5b744f7f-2f63-4219-a0e9-8f08267b1fdd@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
 <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>
 <5b744f7f-2f63-4219-a0e9-8f08267b1fdd@arinc9.com>
Message-ID: <Zb021ozEQSbU-gPd@makrotopia.org>

On Fri, Feb 02, 2024 at 09:16:02PM +0300, Ar?n? ?NAL wrote:
> On 2.02.2024 14:48, Russell King (Oracle) wrote:
> > On Fri, Feb 02, 2024 at 12:19:10PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> > > From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> > > 
> > > The crystal frequency concerns the switch core. The frequency should be
> > > checked when the switch is being set up so the driver can reject the
> > > unsupported hardware earlier and without requiring port 6 to be used.
> > > 
> > > Move it to mt7530_setup(). Drop the unnecessary function printing.
> > > 
> > > Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> > > Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> > > Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
> > 
> > I would prefer this to be earlier in the series, before patch 2 which
> > moves mt7530_setup_port6() to be called from mac_config(). mac_config()
> > is supposed to be configuration error-free - in other words, all state
> > should have been checked before hand.
> 
> I agree but mt7530_mac_config() is not a void function yet. The
> mac_port_config member of the mt753x_info structure points to this
> function. My next patch series gets rid of all useless error returns on the
> phylink path and change mac_port_config to void. So I don't think working
> on this patch series further will worth the effort. I'd rather have this
> version applied as is.

I agree regarding not changing the patch itself, but I also agree
with Russell regarding the patch ordering. I know it's a 10-minute
git headache to rebase the patches on top of each other in a different
order, but you can easily compare the end result being identical to
what you had before and hence don't need to retest.


From sashal at kernel.org  Fri Feb  2 10:39:16 2024
From: sashal at kernel.org (Sasha Levin)
Date: Fri,  2 Feb 2024 13:39:16 -0500
Subject: [PATCH AUTOSEL 6.7 20/23] ARM: dts: Fix TPM schema violations
In-Reply-To: <20240202183926.540467-1-sashal@kernel.org>
References: <20240202183926.540467-1-sashal@kernel.org>
Message-ID: <20240202183926.540467-20-sashal@kernel.org>

From: Lukas Wunner <lukas at wunner.de>

[ Upstream commit 8412c47d68436b9f9a260039a4a773daa6824925 ]

Since commit 26c9d152ebf3 ("dt-bindings: tpm: Consolidate TCG TIS
bindings"), several issues are reported by "make dtbs_check" for ARM
devicetrees:

The nodename needs to be "tpm at 0" rather than "tpmdev at 0" and the
compatible property needs to contain the chip's name in addition to the
generic "tcg,tpm_tis-spi" or "tcg,tpm-tis-i2c":

  tpmdev at 0: $nodename:0: 'tpmdev at 0' does not match '^tpm(@[0-9a-f]+)?$'
        from schema $id: http://devicetree.org/schemas/tpm/tcg,tpm_tis-spi.yaml#

  tpm at 2e: compatible: 'oneOf' conditional failed, one must be fixed:
        ['tcg,tpm-tis-i2c'] is too short
        from schema $id: http://devicetree.org/schemas/tpm/tcg,tpm-tis-i2c.yaml#

Fix these schema violations.

Aspeed Facebook BMCs use an Infineon SLB9670:
https://lore.kernel.org/all/ZZSmMJ%2F%2Fl972Qbxu at fedora/
https://lore.kernel.org/all/ZZT4%2Fw2eVzMhtsPx at fedora/
https://lore.kernel.org/all/ZZTS0p1hdAchIbKp at heinlein.vulture-banana.ts.net/

Aspeed Tacoma uses a Nuvoton NPCT75X per commit 39d8a73c53a2 ("ARM: dts:
aspeed: tacoma: Add TPM").

phyGATE-Tauri uses an Infineon SLB9670:
https://lore.kernel.org/all/ab45c82485fa272f74adf560cbb58ee60cc42689.camel at phytec.de/

A single schema violation remains in am335x-moxa-uc-2100-common.dtsi
because it is unknown which chip is used on the board.  The devicetree's
author has been asked for clarification but has not responded so far:
https://lore.kernel.org/all/20231220090910.GA32182 at wunner.de/

Signed-off-by: Lukas Wunner <lukas at wunner.de>
Reviewed-by: Patrick Williams <patrick at stwcx.xyz>
Reviewed-by: Tao Ren <rentao.bupt at gmail.com>
Reviewed-by: Bruno Thomsen <bruno.thomsen at gmail.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-bletchley.dts   | 4 ++--
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400.dts    | 4 ++--
 arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts           | 2 +-
 arch/arm/boot/dts/aspeed/ast2600-facebook-netbmc-common.dtsi | 4 ++--
 arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi          | 2 +-
 arch/arm/boot/dts/nxp/imx/imx7d-flex-concentrator.dts        | 2 +-
 arch/arm/boot/dts/ti/omap/am335x-moxa-uc-2100-common.dtsi    | 2 +-
 7 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-bletchley.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-bletchley.dts
index e899de681f47..5be0e8fd2633 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-bletchley.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-bletchley.dts
@@ -45,8 +45,8 @@ spi1_gpio: spi1-gpio {
 		num-chipselects = <1>;
 		cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
 
-		tpmdev at 0 {
-			compatible = "tcg,tpm_tis-spi";
+		tpm at 0 {
+			compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
 			spi-max-frequency = <33000000>;
 			reg = <0>;
 		};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400.dts
index a677c827e758..5a8169bbda87 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400.dts
@@ -80,8 +80,8 @@ spi_gpio: spi {
 		gpio-miso = <&gpio ASPEED_GPIO(R, 5) GPIO_ACTIVE_HIGH>;
 		num-chipselects = <1>;
 
-		tpmdev at 0 {
-			compatible = "tcg,tpm_tis-spi";
+		tpm at 0 {
+			compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
 			spi-max-frequency = <33000000>;
 			reg = <0>;
 		};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts
index 3f6010ef2b86..213023bc5aec 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts
@@ -456,7 +456,7 @@ &i2c1 {
 	status = "okay";
 
 	tpm: tpm at 2e {
-		compatible = "tcg,tpm-tis-i2c";
+		compatible = "nuvoton,npct75x", "tcg,tpm-tis-i2c";
 		reg = <0x2e>;
 	};
 };
diff --git a/arch/arm/boot/dts/aspeed/ast2600-facebook-netbmc-common.dtsi b/arch/arm/boot/dts/aspeed/ast2600-facebook-netbmc-common.dtsi
index 31590d3186a2..00e5887c926f 100644
--- a/arch/arm/boot/dts/aspeed/ast2600-facebook-netbmc-common.dtsi
+++ b/arch/arm/boot/dts/aspeed/ast2600-facebook-netbmc-common.dtsi
@@ -35,8 +35,8 @@ spi_gpio: spi {
 		gpio-mosi = <&gpio0 ASPEED_GPIO(X, 4) GPIO_ACTIVE_HIGH>;
 		gpio-miso = <&gpio0 ASPEED_GPIO(X, 5) GPIO_ACTIVE_HIGH>;
 
-		tpmdev at 0 {
-			compatible = "tcg,tpm_tis-spi";
+		tpm at 0 {
+			compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
 			spi-max-frequency = <33000000>;
 			reg = <0>;
 		};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi
index 44cc4ff1d0df..d12fb44aeb14 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi
@@ -116,7 +116,7 @@ &ecspi1 {
 	tpm_tis: tpm at 1 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_tpm>;
-		compatible = "tcg,tpm_tis-spi";
+		compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
 		reg = <1>;
 		spi-max-frequency = <20000000>;
 		interrupt-parent = <&gpio5>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-flex-concentrator.dts b/arch/arm/boot/dts/nxp/imx/imx7d-flex-concentrator.dts
index 3a723843d562..9984b343cdf0 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d-flex-concentrator.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx7d-flex-concentrator.dts
@@ -130,7 +130,7 @@ &ecspi4 {
 	 * TCG specification - Section 6.4.1 Clocking:
 	 * TPM shall support a SPI clock frequency range of 10-24 MHz.
 	 */
-	st33htph: tpm-tis at 0 {
+	st33htph: tpm at 0 {
 		compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi";
 		reg = <0>;
 		spi-max-frequency = <24000000>;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-moxa-uc-2100-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-moxa-uc-2100-common.dtsi
index b8730aa52ce6..a59331aa58e5 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-moxa-uc-2100-common.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am335x-moxa-uc-2100-common.dtsi
@@ -217,7 +217,7 @@ &spi1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&spi1_pins>;
 
-	tpm_spi_tis at 0 {
+	tpm at 0 {
 		compatible = "tcg,tpm_tis-spi";
 		reg = <0>;
 		spi-max-frequency = <500000>;
-- 
2.43.0



From sashal at kernel.org  Fri Feb  2 10:40:06 2024
From: sashal at kernel.org (Sasha Levin)
Date: Fri,  2 Feb 2024 13:40:06 -0500
Subject: [PATCH AUTOSEL 6.6 19/21] ARM: dts: Fix TPM schema violations
In-Reply-To: <20240202184015.540966-1-sashal@kernel.org>
References: <20240202184015.540966-1-sashal@kernel.org>
Message-ID: <20240202184015.540966-19-sashal@kernel.org>

From: Lukas Wunner <lukas at wunner.de>

[ Upstream commit 8412c47d68436b9f9a260039a4a773daa6824925 ]

Since commit 26c9d152ebf3 ("dt-bindings: tpm: Consolidate TCG TIS
bindings"), several issues are reported by "make dtbs_check" for ARM
devicetrees:

The nodename needs to be "tpm at 0" rather than "tpmdev at 0" and the
compatible property needs to contain the chip's name in addition to the
generic "tcg,tpm_tis-spi" or "tcg,tpm-tis-i2c":

  tpmdev at 0: $nodename:0: 'tpmdev at 0' does not match '^tpm(@[0-9a-f]+)?$'
        from schema $id: http://devicetree.org/schemas/tpm/tcg,tpm_tis-spi.yaml#

  tpm at 2e: compatible: 'oneOf' conditional failed, one must be fixed:
        ['tcg,tpm-tis-i2c'] is too short
        from schema $id: http://devicetree.org/schemas/tpm/tcg,tpm-tis-i2c.yaml#

Fix these schema violations.

Aspeed Facebook BMCs use an Infineon SLB9670:
https://lore.kernel.org/all/ZZSmMJ%2F%2Fl972Qbxu at fedora/
https://lore.kernel.org/all/ZZT4%2Fw2eVzMhtsPx at fedora/
https://lore.kernel.org/all/ZZTS0p1hdAchIbKp at heinlein.vulture-banana.ts.net/

Aspeed Tacoma uses a Nuvoton NPCT75X per commit 39d8a73c53a2 ("ARM: dts:
aspeed: tacoma: Add TPM").

phyGATE-Tauri uses an Infineon SLB9670:
https://lore.kernel.org/all/ab45c82485fa272f74adf560cbb58ee60cc42689.camel at phytec.de/

A single schema violation remains in am335x-moxa-uc-2100-common.dtsi
because it is unknown which chip is used on the board.  The devicetree's
author has been asked for clarification but has not responded so far:
https://lore.kernel.org/all/20231220090910.GA32182 at wunner.de/

Signed-off-by: Lukas Wunner <lukas at wunner.de>
Reviewed-by: Patrick Williams <patrick at stwcx.xyz>
Reviewed-by: Tao Ren <rentao.bupt at gmail.com>
Reviewed-by: Bruno Thomsen <bruno.thomsen at gmail.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-bletchley.dts   | 4 ++--
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400.dts    | 4 ++--
 arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts           | 2 +-
 arch/arm/boot/dts/aspeed/ast2600-facebook-netbmc-common.dtsi | 4 ++--
 arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi          | 2 +-
 arch/arm/boot/dts/nxp/imx/imx7d-flex-concentrator.dts        | 2 +-
 arch/arm/boot/dts/ti/omap/am335x-moxa-uc-2100-common.dtsi    | 2 +-
 7 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-bletchley.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-bletchley.dts
index e899de681f47..5be0e8fd2633 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-bletchley.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-bletchley.dts
@@ -45,8 +45,8 @@ spi1_gpio: spi1-gpio {
 		num-chipselects = <1>;
 		cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
 
-		tpmdev at 0 {
-			compatible = "tcg,tpm_tis-spi";
+		tpm at 0 {
+			compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
 			spi-max-frequency = <33000000>;
 			reg = <0>;
 		};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400.dts
index a677c827e758..5a8169bbda87 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400.dts
@@ -80,8 +80,8 @@ spi_gpio: spi {
 		gpio-miso = <&gpio ASPEED_GPIO(R, 5) GPIO_ACTIVE_HIGH>;
 		num-chipselects = <1>;
 
-		tpmdev at 0 {
-			compatible = "tcg,tpm_tis-spi";
+		tpm at 0 {
+			compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
 			spi-max-frequency = <33000000>;
 			reg = <0>;
 		};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts
index 3f6010ef2b86..213023bc5aec 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-tacoma.dts
@@ -456,7 +456,7 @@ &i2c1 {
 	status = "okay";
 
 	tpm: tpm at 2e {
-		compatible = "tcg,tpm-tis-i2c";
+		compatible = "nuvoton,npct75x", "tcg,tpm-tis-i2c";
 		reg = <0x2e>;
 	};
 };
diff --git a/arch/arm/boot/dts/aspeed/ast2600-facebook-netbmc-common.dtsi b/arch/arm/boot/dts/aspeed/ast2600-facebook-netbmc-common.dtsi
index 31590d3186a2..00e5887c926f 100644
--- a/arch/arm/boot/dts/aspeed/ast2600-facebook-netbmc-common.dtsi
+++ b/arch/arm/boot/dts/aspeed/ast2600-facebook-netbmc-common.dtsi
@@ -35,8 +35,8 @@ spi_gpio: spi {
 		gpio-mosi = <&gpio0 ASPEED_GPIO(X, 4) GPIO_ACTIVE_HIGH>;
 		gpio-miso = <&gpio0 ASPEED_GPIO(X, 5) GPIO_ACTIVE_HIGH>;
 
-		tpmdev at 0 {
-			compatible = "tcg,tpm_tis-spi";
+		tpm at 0 {
+			compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
 			spi-max-frequency = <33000000>;
 			reg = <0>;
 		};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi
index ea627638e40c..7dd1fe5a2fb7 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-phytec-tauri.dtsi
@@ -121,7 +121,7 @@ &ecspi1 {
 	tpm_tis: tpm at 1 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_tpm>;
-		compatible = "tcg,tpm_tis-spi";
+		compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
 		reg = <1>;
 		spi-max-frequency = <20000000>;
 		interrupt-parent = <&gpio5>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-flex-concentrator.dts b/arch/arm/boot/dts/nxp/imx/imx7d-flex-concentrator.dts
index 3a723843d562..9984b343cdf0 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d-flex-concentrator.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx7d-flex-concentrator.dts
@@ -130,7 +130,7 @@ &ecspi4 {
 	 * TCG specification - Section 6.4.1 Clocking:
 	 * TPM shall support a SPI clock frequency range of 10-24 MHz.
 	 */
-	st33htph: tpm-tis at 0 {
+	st33htph: tpm at 0 {
 		compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi";
 		reg = <0>;
 		spi-max-frequency = <24000000>;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-moxa-uc-2100-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-moxa-uc-2100-common.dtsi
index b8730aa52ce6..a59331aa58e5 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-moxa-uc-2100-common.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am335x-moxa-uc-2100-common.dtsi
@@ -217,7 +217,7 @@ &spi1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&spi1_pins>;
 
-	tpm_spi_tis at 0 {
+	tpm at 0 {
 		compatible = "tcg,tpm_tis-spi";
 		reg = <0>;
 		spi-max-frequency = <500000>;
-- 
2.43.0



From mathieu.poirier at linaro.org  Fri Feb  2 10:41:19 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 2 Feb 2024 11:41:19 -0700
Subject: [PATCH 9/9] remoteproc: stm32: Use devm_rproc_alloc() helper
In-Reply-To: <20240123184632.725054-9-afd@ti.com>
References: <20240123184632.725054-1-afd@ti.com>
 <20240123184632.725054-9-afd@ti.com>
Message-ID: <Zb03T2Ti2v70NUMu@p14s>

On Tue, Jan 23, 2024 at 12:46:32PM -0600, Andrew Davis wrote:
> Use the device lifecycle managed allocation function. This helps prevent
> mistakes like freeing out of order in cleanup functions and forgetting to
> free on error paths.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  drivers/remoteproc/stm32_rproc.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
> index 4f469f0bcf8b2..fed0866de1819 100644
> --- a/drivers/remoteproc/stm32_rproc.c
> +++ b/drivers/remoteproc/stm32_rproc.c
> @@ -843,7 +843,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> -	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
> +	rproc = devm_rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
>  	if (!rproc)
>  		return -ENOMEM;
>  
> @@ -897,7 +897,6 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>  		dev_pm_clear_wake_irq(dev);
>  		device_init_wakeup(dev, false);
>  	}
> -	rproc_free(rproc);
>  	return ret;
>  }
>  
> @@ -918,7 +917,6 @@ static void stm32_rproc_remove(struct platform_device *pdev)
>  		dev_pm_clear_wake_irq(dev);
>  		device_init_wakeup(dev, false);
>  	}
> -	rproc_free(rproc);
>  }

I have applied patches 1, 2, 8 and 9 of this set.  Bjorn handles the QCOM
peripherals and will take care of the remaining ones.

Thanks,
Mathieu

>  
>  static int stm32_rproc_suspend(struct device *dev)
> -- 
> 2.39.2
> 


From abel.vesa at linaro.org  Fri Feb  2 10:45:37 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Fri, 2 Feb 2024 20:45:37 +0200
Subject: [PATCH] clk: imx: scu: Use common error handling code in
 __imx_clk_gpr_scu()
In-Reply-To: <0e906ec6-fe73-4dbd-b555-a2c03b6e1030@web.de>
References: <20231210171907.3410922-1-visitorckw@gmail.com>
 <0e906ec6-fe73-4dbd-b555-a2c03b6e1030@web.de>
Message-ID: <Zb04UUeE/cU9HtKZ@linaro.org>

On 23-12-22 10:23:13, Markus Elfring wrote:
> From: Markus Elfring <elfring at users.sourceforge.net>
> Date: Fri, 22 Dec 2023 10:05:32 +0100
> 
> Use another label so that a bit of exception handling can be better reused
> at the end of this function.

Please don't send patches as reply to other(s) patches.

> 
> Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
> ---
>  drivers/clk/imx/clk-scu.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
> index e48a904c0013..4ca9dccf3d3b 100644
> --- a/drivers/clk/imx/clk-scu.c
> +++ b/drivers/clk/imx/clk-scu.c
> @@ -882,19 +882,19 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na
>  		return ERR_PTR(-ENOMEM);
> 
>  	if (!imx_scu_clk_is_valid(rsrc_id)) {
> -		kfree(clk_node);
> -		return ERR_PTR(-EINVAL);
> +		ret = -EINVAL;
> +		goto free_clk_node;
>  	}
> 
>  	if (!imx_clk_is_resource_owned(rsrc_id)) {
> -		kfree(clk_node);
> -		return NULL;
> +		ret = 0;
> +		goto free_clk_node;
>  	}
> 
>  	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
>  	if (!clk) {
> -		kfree(clk_node);
> -		return ERR_PTR(-ENOMEM);
> +		ret = -ENOMEM;
> +		goto free_clk_node;
>  	}
> 
>  	clk->rsrc_id = rsrc_id;
> @@ -922,6 +922,7 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na
>  	ret = clk_hw_register(NULL, hw);
>  	if (ret) {
>  		kfree(clk);
> +free_clk_node:
>  		kfree(clk_node);
>  		hw = ERR_PTR(ret);
>  	} else {
> --
> 2.43.0
> 


From lpieralisi at kernel.org  Fri Feb  2 10:53:24 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Fri, 2 Feb 2024 19:53:24 +0100
Subject: [PATCH v9 05/16] PCI: imx6: Using "linux,pci-domain" as slot ID
In-Reply-To: <ZbztZkNQ+wydticD@lizhi-Precision-Tower-5810>
References: <20240119171122.3057511-1-Frank.Li@nxp.com>
 <20240119171122.3057511-6-Frank.Li@nxp.com>
 <ZbzcOarorCS1MPRc@lpieralisi>
 <ZbztZkNQ+wydticD@lizhi-Precision-Tower-5810>
Message-ID: <Zb06JL5X8EiHEyFD@lpieralisi>

On Fri, Feb 02, 2024 at 08:25:58AM -0500, Frank Li wrote:
> On Fri, Feb 02, 2024 at 01:12:41PM +0100, Lorenzo Pieralisi wrote:
> > "PCI: imx6: Use "linux,pci-domain" as slot ID"
> > 
> > On Fri, Jan 19, 2024 at 12:11:11PM -0500, Frank Li wrote:
> > > Avoid use get slot id by compared with register physical address. If there
> > > are more than 2 slots, compared logic will become complex.
> > > 
> > > "linux,pci-domain" already exist at dts since commit:
> > > 	commit (c0b70f05c87f3b arm64: dts: imx8mq: use_dt_domains for pci node).
> > > 
> > > So it is safe to remove compare basic address code:
> > > 	...
> > > 	if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> > > 		imx6_pcie->controller_id = 1;
> > 
> > No it is not unless you magically update all firmware out
> > there in the field.
> 
> commit c0b70f05c87f3b09b391027c6f056d0facf331ef
> Author:     Peng Fan <peng.fan at nxp.com>
> AuthorDate: Fri Jan 15 11:26:57 2021 +0800
> Commit:     Shawn Guo <shawnguo at kernel.org>
> CommitDate: Fri Jan 29 14:46:28 2021 +0800
> 
> I am not sure if it is neccesary to compatible with 2 years ago's dts.
> I think it may not boot at all with using 2 year agao dtb file directly.
> 
> Do you have other comments? I can remove it from this big patch series,

I will have a look at the full series first we can decide whether
to drop it later.

I am travelling so I am not sure I can review it before February
12th, FYI.

Lorenzo


From oliver.upton at linux.dev  Fri Feb  2 11:03:25 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 2 Feb 2024 19:03:25 +0000
Subject: [PATCH v4 00/10] arm64: Add support for FEAT_E2H0, or lack
 thereof
In-Reply-To: <20240122181344.258974-1-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
Message-ID: <Zb08fXz23JUiF4hD@linux.dev>

On Mon, Jan 22, 2024 at 06:13:34PM +0000, Marc Zyngier wrote:
> Since ARMv8.1, the architecture has grown the VHE feature, which makes
> EL2 a superset of EL1. With ARMv9.5 (and retroactively allowed from
> ARMv8.1), the architecture allows implementations to have VHE as the
> *only* implemented behaviour, meaning that HCR_EL2.E2H can be
> implemented as RES1. As a follow-up, HCR_EL2.NV1 can also be
> implemented as RES0, making the VHE-ness of the architecture
> recursive.
> 
> This has a number of consequences, both at boot time and for KVM,
> though the changes at that level are pretty minor.
> 
> The real meat of this series is on the cpufeature front, as FEAT_E2H0
> is a *negative* feature, where 0b1111 (-1) represents E2H being RES1
> and 0b1110 (-2) additionally indicates that NV1 is RES0. Fun, isn't
> it?

This looks good to me. Catalin + Will, are you comfortable with the
cpufeature changes at this point?

No strong opinions on which tree these patches get applied to. Most of
the series is non-KVM code, so I'd understand if y'all wanted it to go
through arm64. OTOH, there are some other KVM features that might appear
in 6.9 that build on top of this, so at minimum I'd probably need a
shared branch.

LMK what you think.

-- 
Thanks,
Oliver


From kuba at kernel.org  Fri Feb  2 11:05:11 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 2 Feb 2024 11:05:11 -0800
Subject: [PATCH v2 0/4] Add 8qm SMMU information
In-Reply-To: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
Message-ID: <20240202110511.135d26b7@kernel.org>

On Thu, 01 Feb 2024 15:22:40 -0500 Frank Li wrote:
>       dt-bindings: mmc: fsl-imx-esdhc: add iommus property
>       dt-bindings: net: fec: add iommus property
>       arm64: dts: imx8qm: add smmu node
>       arm64: dts: imx8qm: add smmu stream id information
> 
>  .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml     |  3 ++
>  Documentation/devicetree/bindings/net/fsl,fec.yaml |  3 ++
>  arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi  |  6 ++++
>  arch/arm64/boot/dts/freescale/imx8qm.dtsi          | 41 ++++++++++++++++++++++

Any preference on whether all these go via a platform tree,
or should we pick up the net patch to netdev? I guess taking
the DTB via netdev would be the usual way to handle this?


From dianders at chromium.org  Fri Feb  2 11:13:08 2024
From: dianders at chromium.org (Doug Anderson)
Date: Fri, 2 Feb 2024 11:13:08 -0800
Subject: [PATCH] regset: use vmalloc() for regset_get_alloc()
In-Reply-To: <Zb0vem7KC28gmT5U@e133380.arm.com>
References: <20240201171159.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924@changeid>
 <20240202012249.GU2087318@ZenIV> <CAD=FV=X5dpMyCGg4Xn+ApRwmiLB5zB0LTMCoSfW_X6eAsfQy8w@mail.gmail.com>
 <20240202030438.GV2087318@ZenIV> <CAD=FV=Wbq7R9AirvxnW1aWoEnp2fWQrwBsxsDB46xbfTLHCZ4w@mail.gmail.com>
 <20240202034925.GW2087318@ZenIV> <20240202040503.GX2087318@ZenIV>
 <CAD=FV=X93KNMF4NwQY8uh-L=1J8PrDFQYu-cqSd+KnY5+Pq+_w@mail.gmail.com>
 <20240202164947.GC2087318@ZenIV> <20240202165524.GD2087318@ZenIV> <Zb0vem7KC28gmT5U@e133380.arm.com>
Message-ID: <CAD=FV=XDg2Q2Gkv0pnngfUMJUOctXhe7f_33DW4TpLxTdG7KBw@mail.gmail.com>

Hi,

On Fri, Feb 2, 2024 at 10:08?AM Dave Martin <Dave.Martin at arm.com> wrote:
>
> So, if the only reason for trying to migrate to vmalloc() is to cope
> with an insanely sized regset on arm64, I think somehow or other we can
> avoid that.

Right. The only reason for the patch to switch to vmalloc() was in
reaction to seeing the order 7 memory allocation. If we can decrease
that to something sensible then I'm happy enough keeping the
allocation as kmalloc().


> Options:
>
>  a) bring back ->get_size() so that we can allocate the correct size
> before generating the regset data;
>
>  b) make aarch64_regsets[] __ro_after_init and set
> aarch64_regsets[REGSET_SVE].n based on the boot-time probed maximum size
> (which will be sane); or
>
>  c) allow membufs to grow if needed (sounds fragile though, and may be
> hard to justify just for one arch?).
>
>
> Thoughts?
>
> If people don't want to bring back get_size(), then (b) doesn't look
> too bad.

Either a) or b) sounds fine to me, but I'm just a visitor to this code
so maybe I'll let the adults in the room chime in with their opinions.
;-) Also: if you think it's fruitful for me to try to write a patch to
do either of those then I can, but I also wouldn't object at all to
someone else writing a patch to fix this and I can just provide a
Tested-by and/or Reviewed-by. Let me know.

-Doug


From robh at kernel.org  Fri Feb  2 11:15:29 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 02 Feb 2024 13:15:29 -0600
Subject: [PATCH v7 1/5] dt-bindings: remoteproc: k3-m4f: Add K3 AM64x
 SoCs
In-Reply-To: <20240202175538.1705-2-hnagalla@ti.com>
References: <20240202175538.1705-1-hnagalla@ti.com>
 <20240202175538.1705-2-hnagalla@ti.com>
Message-ID: <170690132805.611395.5930395618284837775.robh@kernel.org>


On Fri, 02 Feb 2024 11:55:34 -0600, Hari Nagalla wrote:
> K3 AM64x SoC has a Cortex M4F subsystem in the MCU voltage 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: Martyn Welch <martyn.welch at collabora.com>
> Signed-off-by: Hari Nagalla <hnagalla at ti.com>
> ---
> Changes since v1:
>  - Spelling corrections
>  - Corrected to pass DT checks
> 
> Changes since v2:
>  - Missed spelling correction to commit message
> 
> Changes since v3:
>  - Removed unnecessary descriptions and used generic memory region names
>  - Made mboxes and memory-region optional
>  - Removed unrelated items from examples
> 
> Changes since v4:
>  - Rebased to the latest kernel-next tree
>  - Added optional sram memory region for m4f device node
> 
> Changes since v5:
>  - None
> 
> Changes since v6:
>  - Removed blank line, fixed type for firm-ware property and binding check
>    errors.
> 
> link to v6:
>   https://lore.kernel.org/all/20230913111644.29889-2-hnagalla at ti.com/
> 
>  .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 138 ++++++++++++++++++
>  1 file changed, 138 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:


doc reference errors (make refcheckdocs):
Warning: Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml references a file that doesn't exist: Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml: Documentation/devicetree/bindings/reserved-memory/reserved-memory.yaml

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240202175538.1705-2-hnagalla at ti.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From oliver.upton at linux.dev  Fri Feb  2 11:17:37 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 2 Feb 2024 19:17:37 +0000
Subject: [PATCH v2 06/25] KVM: arm64: nv: Add sanitising to VNCR-backed
 HCRX_EL2
In-Reply-To: <Zb0jRzTYyc0IxR00@linux.dev>
References: <20240130204533.693853-1-maz@kernel.org>
 <20240130204533.693853-7-maz@kernel.org>
 <ZbytUKPFYiP2cdd8@linux.dev>
 <86h6iq7w3x.wl-maz@kernel.org>
 <Zb0jRzTYyc0IxR00@linux.dev>
Message-ID: <Zb0_0fq4E1_L7lC6@linux.dev>

On Fri, Feb 02, 2024 at 05:15:51PM +0000, Oliver Upton wrote:
> On Fri, Feb 02, 2024 at 02:56:50PM +0000, Marc Zyngier wrote:
> > No amount of warnings will do, because people don't give a damn.
> > 
> > I'm actually in favour of something far more radical: we snapshot the
> > raw value of all the used RES0/1, and put BUILD_BUG_ON()s that fire if
> > any value has changed. They will have to touch the KVM code to fix
> > that, and we catch them red-handed.
> 
> Oh I like that a lot more.

Unsure which registers you planned to give this treatment, but all of
the ID registers we know about should probably go in this bucket too.

-- 
Thanks,
Oliver


From robh at kernel.org  Fri Feb  2 11:38:08 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 13:38:08 -0600
Subject: [PATCH v3 2/2] dt-bindings: arm: Add device-name in the
 coresight components
In-Reply-To: <20240131082628.6288-3-quic_jinlmao@quicinc.com>
References: <20240131082628.6288-1-quic_jinlmao@quicinc.com>
 <20240131082628.6288-3-quic_jinlmao@quicinc.com>
Message-ID: <20240202193808.GA581322-robh@kernel.org>

On Wed, Jan 31, 2024 at 12:26:26AM -0800, Mao Jinlong wrote:
> Current name of coresight component's folder consists of prefix of
> the device and the id in the device list. When run 'ls' command,
> we can get the register address of the device. Take CTI for example,
> if we want to set the config for modem CTI, but we can't know which
> CTI is modem CTI from all current information.
> 
> cti_sys0 -> ../../../devices/platform/soc at 0/138f0000.cti/cti_sys0
> cti_sys1 -> ../../../devices/platform/soc at 0/13900000.cti/cti_sys1
> 
> Add device-name in device tree which can provide a better description
> of the coresight device. It can provide the info like the system or
> HW it belongs to.
> 
> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
> ---
>  .../devicetree/bindings/arm/arm,coresight-catu.yaml         | 6 ++++++
>  .../devicetree/bindings/arm/arm,coresight-cpu-debug.yaml    | 6 ++++++
>  .../devicetree/bindings/arm/arm,coresight-cti.yaml          | 6 ++++++
>  .../devicetree/bindings/arm/arm,coresight-dummy-sink.yaml   | 6 ++++++
>  .../devicetree/bindings/arm/arm,coresight-dummy-source.yaml | 6 ++++++
>  .../bindings/arm/arm,coresight-dynamic-funnel.yaml          | 6 ++++++
>  .../bindings/arm/arm,coresight-dynamic-replicator.yaml      | 6 ++++++
>  .../devicetree/bindings/arm/arm,coresight-etb10.yaml        | 6 ++++++
>  .../devicetree/bindings/arm/arm,coresight-etm.yaml          | 6 ++++++
>  .../bindings/arm/arm,coresight-static-funnel.yaml           | 6 ++++++
>  .../bindings/arm/arm,coresight-static-replicator.yaml       | 6 ++++++
>  .../devicetree/bindings/arm/arm,coresight-stm.yaml          | 6 ++++++
>  .../devicetree/bindings/arm/arm,coresight-tmc.yaml          | 6 ++++++
>  .../devicetree/bindings/arm/arm,coresight-tpiu.yaml         | 6 ++++++
>  .../devicetree/bindings/arm/qcom,coresight-tpda.yaml        | 6 ++++++
>  .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml        | 6 ++++++

Why do you need a name on everything? Funnels and replicators, for 
example, aren't a source of data, but just connected to things that are. 
ETM is tightly coupled to a CPU and you have a link to it. You have 
graph links to show connections. Limit this to where you actually need 
it. 

>  16 files changed, 96 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-catu.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-catu.yaml
> index 2bae06eed693..a4d20aad0c70 100644
> --- a/Documentation/devicetree/bindings/arm/arm,coresight-catu.yaml
> +++ b/Documentation/devicetree/bindings/arm/arm,coresight-catu.yaml
> @@ -44,6 +44,12 @@ properties:
>        - const: arm,coresight-catu
>        - const: arm,primecell
>  
> +  device-name:

This is too generic of a name. Make is something closer to how it is 
used or what it is for. Naming sysfs devices is not how it is used. 
That's just an intermediate step.

> +    $ref: /schemas/types.yaml#/definitions/string
> +    description:
> +      Define the name which can describe what kind of HW or system the
> +      device is for.
> +
>    reg:
>      maxItems: 1
>  
> diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-cpu-debug.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-cpu-debug.yaml
> index 0a6bc03ebe00..6094cc9cb834 100644
> --- a/Documentation/devicetree/bindings/arm/arm,coresight-cpu-debug.yaml
> +++ b/Documentation/devicetree/bindings/arm/arm,coresight-cpu-debug.yaml
> @@ -39,6 +39,12 @@ properties:
>        - const: arm,coresight-cpu-debug
>        - const: arm,primecell
>  
> +  device-name:
> +    $ref: /schemas/types.yaml#/definitions/string

If you are redefining the type multiple times, there's a problem in the 
structure of the schemas. Really, that's true for anything duplicated in 
the kernel.

Rob


From broonie at kernel.org  Fri Feb  2 11:42:58 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 2 Feb 2024 19:42:58 +0000
Subject: [PATCH] regset: use vmalloc() for regset_get_alloc()
In-Reply-To: <Zb0vem7KC28gmT5U@e133380.arm.com>
References: <20240202012249.GU2087318@ZenIV>
 <CAD=FV=X5dpMyCGg4Xn+ApRwmiLB5zB0LTMCoSfW_X6eAsfQy8w@mail.gmail.com>
 <20240202030438.GV2087318@ZenIV>
 <CAD=FV=Wbq7R9AirvxnW1aWoEnp2fWQrwBsxsDB46xbfTLHCZ4w@mail.gmail.com>
 <20240202034925.GW2087318@ZenIV>
 <20240202040503.GX2087318@ZenIV>
 <CAD=FV=X93KNMF4NwQY8uh-L=1J8PrDFQYu-cqSd+KnY5+Pq+_w@mail.gmail.com>
 <20240202164947.GC2087318@ZenIV>
 <20240202165524.GD2087318@ZenIV>
 <Zb0vem7KC28gmT5U@e133380.arm.com>
Message-ID: <d7154f86-d185-495d-aa84-63d4561f1e47@sirena.org.uk>

On Fri, Feb 02, 2024 at 06:07:54PM +0000, Dave Martin wrote:

> So, if the only reason for trying to migrate to vmalloc() is to cope
> with an insanely sized regset on arm64, I think somehow or other we can
> avoid that.

With SME we do routinely see the full glory of the 64K regset for ZA in
emulated systems so I think we have to treat it as an issue.

> Options:

>  a) bring back ->get_size() so that we can allocate the correct size
> before generating the regset data;

>  b) make aarch64_regsets[] __ro_after_init and set
> aarch64_regsets[REGSET_SVE].n based on the boot-time probed maximum size
> (which will be sane); or

Either of those seems sensible to me, a function would minimise the size
of allocations based on the process configuration which would be nice
and given that we're doing allocations it's probably reasonable
overhead.

>  c) allow membufs to grow if needed (sounds fragile though, and may be
> hard to justify just for one arch?).

I'm having a hard time getting enthusiastic about that one for the
reasons you mention.

We can also just lower the maximum size we tell the ptrace core to the
actual architectural maximum since AFAICT we don't expose that anywhere
external, I've got a patch in CI for that.  We'd still be allocating
more memory than we need for practical systems but less extravagantly
so.  It seems more suitable for an immediate fix for people to pick up
for production.

It did occur to me at some point in the past that we should avoid
telling the core about regsets that aren't physically supported on the
current system, I didn't get round to looking at that 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/20240202/a236b2a9/attachment.sig>

From robh at kernel.org  Fri Feb  2 11:50:24 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 13:50:24 -0600
Subject: [EXT] Re: [PATCH v5 4/8] dt-bindings: usb: ci-hdrc-usb2: add
 restrictions for reg, interrupts, clock and clock-names properties
In-Reply-To: <f62289f2-0f37-4e27-bc27-ab6d70dcc898@linaro.org>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-4-xu.yang_2@nxp.com>
 <a0134089-a283-488b-8d7f-3f59dd938b60@linaro.org>
 <DU2PR04MB88221602EB986D2C2A5BBF8D8C422@DU2PR04MB8822.eurprd04.prod.outlook.com>
 <f62289f2-0f37-4e27-bc27-ab6d70dcc898@linaro.org>
Message-ID: <20240202195024.GA846913-robh@kernel.org>

On Fri, Feb 02, 2024 at 12:04:51PM +0100, Krzysztof Kozlowski wrote:
> On 02/02/2024 10:10, Xu Yang wrote:
> > Hi Krzysztof,
> > 
> >>
> >> On 31/01/2024 12:43, Xu Yang wrote:
> >>> Change reg, interrupts, clock and clock-names as common properties and add
> >>> restrictions on them for different compatibles.
> >>>
> >>> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> >>>
> >>> ---
> >>> Changes in v4:
> >>>  - new patch since v3's discussion
> >>>  - split the reg, interrupts, clock and clock-names properties into
> >>>    common part and device-specific
> >>> Changes in v5:
> >>>  - keep common property unchanged
> >>>  - make if-then more readable
> >>>  - remove non imx part
> >>> ---
> >>>  .../devicetree/bindings/usb/ci-hdrc-usb2.yaml | 118 ++++++++++++++++++
> >>>  1 file changed, 118 insertions(+)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-
> >> hdrc-usb2.yaml
> >>> index 3b56e0edb1c6..6ad3582051b8 100644
> >>> --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> >>> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> >>> @@ -412,6 +412,124 @@ allOf:
> >>>          samsung,picophy-pre-emp-curr-control: false
> >>>          samsung,picophy-dc-vol-level-adjust: false
> >>>
> >>> +  - if:
> >>> +      properties:
> >>> +        compatible:
> >>> +          const: fsl,imx27-usb
> >>> +    then:
> >>> +      properties:
> >>> +        clocks:
> >>> +          minItems: 3
> >>> +          maxItems: 3
> >>> +        clock-names:
> >>> +          minItems: 3
> >>> +          maxItems: 3
> >>> +          items:
> >>> +            anyOf:
> >>> +              - const: ipg
> >>> +              - const: ahb
> >>> +              - const: per
> >>
> >> This would be just: enum: [ipg, ahb, per], but in both cases I question
> >> why the order should be flexible? Nothing in commit msg explains it.
> > 
> > The driver will get the clock by clock-name, then the order should not
> > matter. However, these three clock-names should be present at the same
> > time. I should use enum then.
> > 
> >>
> >> Plus I will repeat myself from your v4. I don't think this is helping,
> >> because the file will soon grow to umnanageable chunk. I prefer to fix
> >> it at beginning, before we reach snps-schema level of complexities.
> >>
> >> Please define common schema, reference in this file and move IMX to own
> >> file.
> > 
> > I'm not that familiar with dt-bindings architecture. If I define a common
> > schema, then should I create imx, qcom, nvidia and other dt-binding files
> > too? 
> 
> No, the rest you can leave here. Someone, maybe me, will move them some
> time. The point is to move at least IMX to its own file.

That will only work as long as i.MX doesn't define any extra properties 
which it already has. We have to have at a minium common, imx, and 
everything else schema docs.

Rob


From charles.perry at savoirfairelinux.com  Fri Feb  2 11:52:59 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Fri, 2 Feb 2024 14:52:59 -0500 (EST)
Subject: [PATCH 2/3] dt-bindings: fpga: xlnx,fpga-slave-selectmap: add
 DT schema
In-Reply-To: <4e9360cf-2952-45e9-8c85-caa4c0d92175@linaro.org>
References: <20240129225602.3832449-1-charles.perry@savoirfairelinux.com> <20240131230542.3993409-1-charles.perry@savoirfairelinux.com> <20240131230542.3993409-3-charles.perry@savoirfairelinux.com> <d5fe1ec2-b647-4902-a599-fb866e96e9cf@linaro.org> <1391244934.434321.1706811892834.JavaMail.zimbra@savoirfairelinux.com> <4e9360cf-2952-45e9-8c85-caa4c0d92175@linaro.org>
Message-ID: <689519725.467683.1706903579718.JavaMail.zimbra@savoirfairelinux.com>


----- On Feb 2, 2024, at 5:49 AM, Krzysztof Kozlowski krzysztof.kozlowski at linaro.org wrote:

> On 01/02/2024 19:24, Charles Perry wrote:
>> 
>> 
>> ----- On Feb 1, 2024, at 3:07 AM, Krzysztof Kozlowski
>> krzysztof.kozlowski at linaro.org wrote:
>> 
>>> On 01/02/2024 00:05, Charles Perry wrote:
>>>> Document the slave SelectMAP interface of Xilinx 7 series FPGA.
>>>>
>>>> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
>>>> ---
>>>>  .../bindings/fpga/xlnx,fpga-selectmap.yaml    | 83 +++++++++++++++++++
>>>>  1 file changed, 83 insertions(+)
>>>>  create mode 100644
>>>>  Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>>>> b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>>>> new file mode 100644
>>>> index 0000000000000..c9a446b43cdd9
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
>>>> @@ -0,0 +1,83 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/fpga/xlnx,fpga-selectmap.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: Xilinx SelectMAP FPGA interface
>>>> +
>>>> +maintainers:
>>>> +  - Charles Perry <charles.perry at savoirfairelinux.com>
>>>> +
>>>> +description: |
>>>> +  Xilinx 7 Series FPGAs support a method of loading the bitstream over a
>>>> +  parallel port named the SelectMAP interface in the documentation. Only
>>>> +  the x8 mode is supported where data is loaded at one byte per rising edge of
>>>> +  the clock, with the MSB of each byte presented to the D0 pin.
>>>> +
>>>> +  Datasheets:
>>>> +
>>>> https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf
>>>> +
>>>> +allOf:
>>>> +  - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml#
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    enum:
>>>> +      - xlnx,fpga-selectmap
>>>
>>> Your description mentions "7 Series" which is not present in compatible
>>> and title. What is exactly the product here? Interface usually is not
>>> the final binding, so is this specific to some particular FPGA or SoC?
>>>
>>>
>>> Best regards,
>>> Krzysztof
>> 
>> This is specific to the FPGA, the 7 series encompass the following part
>> family:
>>  * Spartan-7 (XC7S6, XC7S15, ... XC7S100)
>>  * Artix-7 (XC7A12T, XC7A15T, ... XC7A200T)
>>  * Kintex-7 (XC7K70T, XC7K160T, ... XC7K480T)
>>  * Virtex-7 (XC7V585T, XC7V2000T,
>>              XC7VX330T, XC7VX415T, ... XC7VX1140T,
>>              XC7VH580T, XC7VH870T)
>> 
>> 
>> The configuration guide of Xilinx [1] tells us that all those devices
>> share a common programming scheme.
>> 
>> I do agree that having a mention of "7 series" in the compatible name
>> would be beneficial as Xilinx has more FPGA than just the 7 series.
>> The name was inspired from "xlnx,fpga-slave-serial" which is the compatible
>> for the serial interface.
>> 
>> What about "xlnx,fpga-xc7-selectmap" ?
>> 
> 
> I am not sure what xc7 is and how Xilinx numbers it products, but
> compatibles are supposed to be device specific, not family. Common
> programming model could be denoted with generic fallback, but then the
> fallback could be device-specific as well, which usually we recommend.
> 
> Best regards,
> Krzysztof

XC7 is the common prefix for all 4 families of the 7 series.

Then we have XC7S, XC7A, XC7K and XC7V as the prefixes of those 4 family.

Following that is a number denoting the number of logic element, e.g.
XC7S6, XC7S15, XC7S100, ... I don't think that should be part of the
compatible.

Finally there will be another set of letters and numbers for the
temperature grade and physical package, but those are usually not part
of a compatible string.

I'll change it to four compatibles: "xlnx,fpga-xc7[sakv]-selectmap" so
that the driver can do device specific things if anomalies are found in
one of them.

Thanks again for the review!

Regards,
Charles


From mathieu.poirier at linaro.org  Fri Feb  2 11:53:34 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 2 Feb 2024 12:53:34 -0700
Subject: [PATCH v2 4/4] remoteproc: stm32: Add support of an OP-TEE TA to
 load the firmware
In-Reply-To: <a52e00c5-fb60-4a9e-85ff-0f9649850f48@foss.st.com>
References: <20240118100433.3984196-1-arnaud.pouliquen@foss.st.com>
 <20240118100433.3984196-5-arnaud.pouliquen@foss.st.com>
 <ZbPnsJm67G10+HQ3@p14s>
 <7ec6c9e8-9267-4e7c-81a4-abcdb2ab4239@foss.st.com>
 <ZbqW5YfDmEWG4G1X@p14s>
 <8ede77bb-0fbc-4de2-b51b-67674744b551@foss.st.com>
 <ZbvAmxHscnbUQGOD@p14s>
 <a52e00c5-fb60-4a9e-85ff-0f9649850f48@foss.st.com>
Message-ID: <Zb1IPlnbMp9Utu2y@p14s>

On Thu, Feb 01, 2024 at 07:33:35PM +0100, Arnaud POULIQUEN wrote:
> 
> 
> On 2/1/24 17:02, Mathieu Poirier wrote:
> > On Thu, Feb 01, 2024 at 04:06:37PM +0100, Arnaud POULIQUEN wrote:
> >> hello Mathieu,
> >>
> >> On 1/31/24 19:52, Mathieu Poirier wrote:
> >>> On Tue, Jan 30, 2024 at 10:13:48AM +0100, Arnaud POULIQUEN wrote:
> >>>>
> >>>>
> >>>> On 1/26/24 18:11, Mathieu Poirier wrote:
> >>>>> On Thu, Jan 18, 2024 at 11:04:33AM +0100, Arnaud Pouliquen wrote:
> >>>>>> The new TEE remoteproc device is used to manage remote firmware in a
> >>>>>> secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
> >>>>>> introduced to delegate the loading of the firmware to the trusted
> >>>>>> execution context. In such cases, the firmware should be signed and
> >>>>>> adhere to the image format defined by the TEE.
> >>>>>>
> >>>>>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
> >>>>>> ---
> >>>>>> V1 to V2 update:
> >>>>>> - remove the select "TEE_REMOTEPROC" in STM32_RPROC config as detected by
> >>>>>>   the kernel test robot:
> >>>>>>      WARNING: unmet direct dependencies detected for TEE_REMOTEPROC
> >>>>>>      Depends on [n]: REMOTEPROC [=y] && OPTEE [=n]
> >>>>>>      Selected by [y]:
> >>>>>>      - STM32_RPROC [=y] && (ARCH_STM32 || COMPILE_TEST [=y]) && REMOTEPROC [=y]
> >>>>>> - Fix initialized trproc variable in  stm32_rproc_probe
> >>>>>> ---
> >>>>>>  drivers/remoteproc/stm32_rproc.c | 149 +++++++++++++++++++++++++++++--
> >>>>>>  1 file changed, 144 insertions(+), 5 deletions(-)
> >>>>>>
> >>>>>> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
> >>>>>> index fcc0001e2657..cf6a21bac945 100644
> >>>>>> --- a/drivers/remoteproc/stm32_rproc.c
> >>>>>> +++ b/drivers/remoteproc/stm32_rproc.c
> >>>>>> @@ -20,6 +20,7 @@
> >>>>>>  #include <linux/remoteproc.h>
> >>>>>>  #include <linux/reset.h>
> >>>>>>  #include <linux/slab.h>
> >>>>>> +#include <linux/tee_remoteproc.h>
> >>>>>>  #include <linux/workqueue.h>
> >>>>>>  
> >>>>>>  #include "remoteproc_internal.h"
> >>>>>> @@ -49,6 +50,9 @@
> >>>>>>  #define M4_STATE_STANDBY	4
> >>>>>>  #define M4_STATE_CRASH		5
> >>>>>>  
> >>>>>> +/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
> >>>>>> +#define STM32_MP1_M4_PROC_ID    0
> >>>>>> +
> >>>>>>  struct stm32_syscon {
> >>>>>>  	struct regmap *map;
> >>>>>>  	u32 reg;
> >>>>>> @@ -90,6 +94,8 @@ struct stm32_rproc {
> >>>>>>  	struct stm32_mbox mb[MBOX_NB_MBX];
> >>>>>>  	struct workqueue_struct *workqueue;
> >>>>>>  	bool hold_boot_smc;
> >>>>>> +	bool fw_loaded;
> >>>>>> +	struct tee_rproc *trproc;
> >>>>>>  	void __iomem *rsc_va;
> >>>>>>  };
> >>>>>>  
> >>>>>> @@ -257,6 +263,91 @@ static int stm32_rproc_release(struct rproc *rproc)
> >>>>>>  	return err;
> >>>>>>  }
> >>>>>>  
> >>>>>> +static int stm32_rproc_tee_elf_sanity_check(struct rproc *rproc,
> >>>>>> +					    const struct firmware *fw)
> >>>>>> +{
> >>>>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>>>> +	unsigned int ret = 0;
> >>>>>> +
> >>>>>> +	if (rproc->state == RPROC_DETACHED)
> >>>>>> +		return 0;
> >>>>>> +
> >>>>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
> >>>>>> +	if (!ret)
> >>>>>> +		ddata->fw_loaded = true;
> >>>>>> +
> >>>>>> +	return ret;
> >>>>>> +}
> >>>>>> +
> >>>>>> +static int stm32_rproc_tee_elf_load(struct rproc *rproc,
> >>>>>> +				    const struct firmware *fw)
> >>>>>> +{
> >>>>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>>>> +	unsigned int ret;
> >>>>>> +
> >>>>>> +	/*
> >>>>>> +	 * This function can be called by remote proc for recovery
> >>>>>> +	 * without the sanity check. In this case we need to load the firmware
> >>>>>> +	 * else nothing done here as the firmware has been preloaded for the
> >>>>>> +	 * sanity check to be able to parse it for the resource table.
> >>>>>> +	 */
> >>>>>
> >>>>> This comment is very confusing - please consider refactoring.  
> >>>>>
> >>>>>> +	if (ddata->fw_loaded)
> >>>>>> +		return 0;
> >>>>>> +
> >>>>>
> >>>>> I'm not sure about keeping a flag to indicate the status of the loaded firmware.
> >>>>> It is not done for the non-secure method, I don't see why it would be needed for
> >>>>> the secure one.
> >>>>>
> >>>>
> >>>> The difference is on the sanity check.
> >>>> - in rproc_elf_sanity_check we  parse the elf file to verify that it is
> >>>> valid.
> >>>> - in stm32_rproc_tee_elf_sanity_check we have to do the same, that means to
> >>>> authenticate it. the authentication is done during the load.
> >>>>
> >>>> So this flag is used to avoid to reload it twice time.
> >>>> refactoring the comment should help to understand this flag
> >>>>
> >>>>
> >>>> An alternative would be to bypass the sanity check. But this lead to same
> >>>> limitation.
> >>>> Before loading the firmware in remoteproc_core, we call rproc_parse_fw() that is
> >>>> used to get the resource table address. To get it from tee we need to
> >>>> authenticate the firmware so load it...
> >>>>
> >>>
> >>> I spent a long time thinking about this patchset.  Looking at the code as it
> >>> is now, request_firmware() in rproc_boot() is called even when the TEE is
> >>> responsible for loading the firmware.  There should be some conditional code
> >>> that calls either request_firmware() or tee_rproc_load_fw().  The latter should
> >>> also be renamed to tee_rproc_request_firmware() to avoid confusion.
> >>
> >>
> >> The request_firmware() call is needed in both cases to get the image from the
> >> filesystem. The tee_rproc_load_fw() gets, as input, the struct firmware provided
> >> by request_firmware().
> > 
> > The cover letter clearly state the secure side is responsible for loading the
> > firmware image but here you're telling me it has to be loaded twice.  This is
> > very confusing.
> 
> Concerning the call of request_firmware()
> 
> By "both cases" I would say that the call of request_firmware() is needed in
> both modes:
> - the ELF firmware is parsed and loaded by linux (legacy)
> - the binary firmware is parsed and loaded by OP-TEE.
> 
> The Op-TEE is not able to get the firmware image from the file system.
>
> 
> Concerning the call of tee_rproc_load_fw twice time
> 
> There are 2 use cases:
> 
> - First boot of the remote processor:
> 
>   1) The Linux rproc gets the binary firmware image from the file system by
>      calling  request_firmware(). A copy is stored in memory.

Right.  And I think tee_rproc_load_fw() should be called right after
request_firmware() if rproc::tee_rproc_interface is valid.  At that point the TEE
app may or may not do the firmware authentication, that is application specific.

>   2) the linux performs a sanity check on the firmware calling
>      rproc_fw_sanity_check()
> 	=> from OP-TEE point of view this means to autenticate the firmware
> 	=> let consider in this exemple that we bypass this step
>            (ops->sanity_check = NULL)

Ok

> 		
>   3) the linux rproc call rproc_parse_fw() to get the resource table
> 	=> From OP-TEE point of view the resource table is available only when
>            the firmware is loaded

Right, and it should have been loaded already.  If it is not then the TEE should
return an error.

> 	=> We need to call tee_rproc_load_fw() to be able then to get the
>            address of the resource table.

See my comment above - at this point the TEE should already have the firmware.
As such the only thing left is to get the address of the resource table, which
you already do in rproc_tee_get_rsc_table().  The upper part of that function
should be spun off in a new static function to deal with the TEE API, something
like _rproc_tee_get_rsc_table().  The new function should also be called in
tee_rproc_get_loaded_rsc_table() rather than keeping a cache value in
trproc->rsc_va.

>   4) The Linux rproc calls rproc_handle_resources() to parse the resource table.
>   5) The linux rproc calls rproc_start()
> 	- load the firrmware calling rproc_load_segments()
> 		=> we don't want to call tee_rproc_load_fw() it a second time

And that is fine if the TEE app has already placed the program segments in
memory.

> 	- start the firmware calling ops->start()
> 
> - Reboot on crash recovery using rproc_boot_recovery()
> 
>   1)  The Linux rproc gets the binary firmware image from the file system by
>      calling request_firmware(). A copy is stored in memory.
>   5) The linux rproc calls rproc_start()
> 	- load the firrmware calling rproc_load_segments()
> 		=> we have to call tee_rproc_load_fw() to reload the firmware

Loading the firmware in the TEE should be done right after request_firmware()
has been called, the same way it is done in the boot path.  If there isn't a
need to reload the TEE firmware than the TEE application should ignore the
request.

> 	- start the firmware calling ops->start()
> 
> In first use case we have to load the firmware on rproc_parse_fw(), in second
> usecase on rproc_load_segments().
> 
> This is the point I have tried to solve with the ddata->fw_loaded variable.
> 
> > 
> > I'm also confused as to why stm32_rproc_tee_elf_sanity_check() is calling
> > tee_rproc_load_fw().  There should be one call to load the firmware and another
> > to perform a sanity check on it.  If the sanity check is done at load time by
> > the secure world then ops::sanity_check() is NULL.
> 
> Sure, make sense to remove the sanity_check ops
> 
> Thanks,
> Arnaud
> 
> > 
> > Most of what this patchset does makes sense, but some of it needs to be moved
> > around.  
> > 
> > Thanks,
> > Mathieu
> > 
> >>
> >> If we want to integrate in remoteproc_core the solution could probably have to
> >> create the equivalent of the rproc_fw_boot() to load the firmware with an
> >> external method. Here is an example based on a new rproc_ops ( not tested)
> >>
> >> + static int rproc_fw_ext_boot(struct rproc *rproc, const struct firmware *fw)
> >> + {
> >> + 	struct device *dev = &rproc->dev;
> >> + 	const char *name = rproc->firmware;
> >> + 	int ret;
> >> +
> >> +
> >> + 	dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size);
> >> + 	
> >> + 	/* ops to load and start the remoteprocessor */
> >> + 	ret = rproc->ops->boot(rproc, fw);
> >> + 	if (ret)
> >> + 		return ret;
> >> +
> >> + 	/*
> >> + 	 * if enabling an IOMMU isn't relevant for this rproc, this is
> >> + 	 * just a nop
> >> + 	 */
> >> + 	ret = rproc_enable_iommu(rproc);
> >> + 	if (ret) {
> >> + 		dev_err(dev, "can't enable iommu: %d\n", ret);
> >> + 		return ret;
> >> + 	}
> >> +
> >> + 	/* Prepare rproc for firmware loading if needed */
> >> + 	ret = rproc_prepare_device(rproc);
> >> + 	if (ret) {
> >> + 		dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
> >> + 		goto disable_iommu;
> >> + 	}
> >> +
> >> + 	ret = rproc_set_rsc_table(rproc);
> >> + 	if (ret) {
> >> + 		dev_err(dev, "can't load resource table: %d\n", ret);
> >> + 		goto unprepare_device;
> >> + 	}
> >> +
> >> +
> >> + 	/* reset max_notifyid */
> >> + 	rproc->max_notifyid = -1;
> >> +
> >> + 	/* reset handled vdev */
> >> + 	rproc->nb_vdev = 0;
> >> +
> >> + 	/* handle fw resources which are required to boot rproc */
> >> + 	ret = rproc_handle_resources(rproc, rproc_loading_handlers);
> >> + 	if (ret) {
> >> + 		dev_err(dev, "Failed to process resources: %d\n", ret);
> >> + 		goto clean_up_resources;
> >> + 	}
> >> +
> >> + 	/* Allocate carveout resources associated to rproc */
> >> + 	ret = rproc_alloc_registered_carveouts(rproc);
> >> + 	if (ret) {
> >> + 		dev_err(dev, "Failed to allocate associated carveouts: %d\n",
> >> + 			ret);
> >> + 		goto clean_up_resources;
> >> + 	}
> >> +
> >> + 	return 0;
> >> +
> >> + clean_up_resources:
> >> + 	rproc_resource_cleanup(rproc);
> >> + unprepare_rproc:
> >> + 	/* release HW resources if needed */
> >> + 	rproc_unprepare_device(rproc);
> >> + disable_iommu:
> >> + 	rproc_disable_iommu(rproc);
> >> + 	return ret;
> >> + }
> >>
> >>
> >> int rproc_boot(struct rproc *rproc)
> >> {
> >> [...]
> >>
> >> - 		ret = rproc_fw_boot(rproc, firmware_p);
> >> + 		if(rproc->ops->boot)
> >> + 			ret = rproc_fw_ext_boot(rproc, firmware_p);
> >> + 		else
> >> + 			ret = rproc_fw_boot(rproc, firmware_p);
> >>
> >> Another advantage of this solution is that it opens the framework to other
> >> formats. For instance it could be a way to support dtb format requested in [RFC]
> >> Passing device-tree to remoteproc [1].
> >>
> >> [1]
> >> https://lore.kernel.org/linux-remoteproc/f67cd822-4e29-71f2-7c42-e11dbaa6cd8c at kalrayinc.com/T/#t
> >>
> >> Thanks,
> >> Arnaud
> >>
> >>
> >>
> >>>
> >>> I touched on that before but please rename rproc_tee_get_rsc_table() to
> >>> rproc_tee_elf_load_rsc_table().  I also suggest to introduce a new function,
> >>> rproc_tee_get_loaded_rsc_table() that would be called from
> >>> rproc_tee_elf_load_rsc_table().  That way we don't need trproc->rsc_va.  
> >>>
> >>> I also think tee_rproc should be renamed to "rproc_tee_interface" and folded
> >>> under struct rproc.  
> >>>
> >>> With the above most of the problems with the current implementation should
> >>> naturally go away.
> >>>
> >>> Thanks,
> >>> Mathieu
> >>>
> >>>>
> >>>>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
> >>>>>> +	if (ret)
> >>>>>> +		return ret;
> >>>>>> +	ddata->fw_loaded = true;
> >>>>>> +
> >>>>>> +	/* Update the resource table parameters. */
> >>>>>> +	if (rproc_tee_get_rsc_table(ddata->trproc)) {
> >>>>>> +		/* No resource table: reset the related fields. */
> >>>>>> +		rproc->cached_table = NULL;
> >>>>>> +		rproc->table_ptr = NULL;
> >>>>>> +		rproc->table_sz = 0;
> >>>>>> +	}
> >>>>>> +
> >>>>>> +	return 0;
> >>>>>> +}
> >>>>>> +
> >>>>>> +static struct resource_table *
> >>>>>> +stm32_rproc_tee_elf_find_loaded_rsc_table(struct rproc *rproc,
> >>>>>> +					  const struct firmware *fw)
> >>>>>> +{
> >>>>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>>>> +
> >>>>>> +	return tee_rproc_get_loaded_rsc_table(ddata->trproc);
> >>>>>> +}
> >>>>>> +
> >>>>>> +static int stm32_rproc_tee_start(struct rproc *rproc)
> >>>>>> +{
> >>>>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>>>> +
> >>>>>> +	return tee_rproc_start(ddata->trproc);
> >>>>>> +}
> >>>>>> +
> >>>>>> +static int stm32_rproc_tee_attach(struct rproc *rproc)
> >>>>>> +{
> >>>>>> +	/* Nothing to do, remote proc already started by the secured context. */
> >>>>>> +	return 0;
> >>>>>> +}
> >>>>>> +
> >>>>>> +static int stm32_rproc_tee_stop(struct rproc *rproc)
> >>>>>> +{
> >>>>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>>>> +	int err;
> >>>>>> +
> >>>>>> +	stm32_rproc_request_shutdown(rproc);
> >>>>>> +
> >>>>>> +	err = tee_rproc_stop(ddata->trproc);
> >>>>>> +	if (err)
> >>>>>> +		return err;
> >>>>>> +
> >>>>>> +	ddata->fw_loaded = false;
> >>>>>> +
> >>>>>> +	return stm32_rproc_release(rproc);
> >>>>>> +}
> >>>>>> +
> >>>>>>  static int stm32_rproc_prepare(struct rproc *rproc)
> >>>>>>  {
> >>>>>>  	struct device *dev = rproc->dev.parent;
> >>>>>> @@ -319,7 +410,14 @@ static int stm32_rproc_prepare(struct rproc *rproc)
> >>>>>>  
> >>>>>>  static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
> >>>>>>  {
> >>>>>> -	if (rproc_elf_load_rsc_table(rproc, fw))
> >>>>>> +	struct stm32_rproc *ddata = rproc->priv;
> >>>>>> +	int ret;
> >>>>>> +
> >>>>>> +	if (ddata->trproc)
> >>>>>> +		ret = rproc_tee_get_rsc_table(ddata->trproc);
> >>>>>> +	else
> >>>>>> +		ret = rproc_elf_load_rsc_table(rproc, fw);
> >>>>>> +	if (ret)
> >>>>>>  		dev_warn(&rproc->dev, "no resource table found for this firmware\n");
> >>>>>>  
> >>>>>>  	return 0;
> >>>>>> @@ -693,8 +791,22 @@ static const struct rproc_ops st_rproc_ops = {
> >>>>>>  	.get_boot_addr	= rproc_elf_get_boot_addr,
> >>>>>>  };
> >>>>>>  
> >>>>>> +static const struct rproc_ops st_rproc_tee_ops = {
> >>>>>> +	.prepare	= stm32_rproc_prepare,
> >>>>>> +	.start		= stm32_rproc_tee_start,
> >>>>>> +	.stop		= stm32_rproc_tee_stop,
> >>>>>> +	.attach		= stm32_rproc_tee_attach,
> >>>>>> +	.kick		= stm32_rproc_kick,
> >>>>>> +	.parse_fw	= stm32_rproc_parse_fw,
> >>>>>> +	.find_loaded_rsc_table = stm32_rproc_tee_elf_find_loaded_rsc_table,
> >>>>>> +	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
> >>>>>> +	.sanity_check	= stm32_rproc_tee_elf_sanity_check,
> >>>>>> +	.load		= stm32_rproc_tee_elf_load,
> >>>>>> +};
> >>>>>> +
> >>>>>>  static const struct of_device_id stm32_rproc_match[] = {
> >>>>>> -	{ .compatible = "st,stm32mp1-m4" },
> >>>>>> +	{.compatible = "st,stm32mp1-m4",},
> >>>>>> +	{.compatible = "st,stm32mp1-m4-tee",},
> >>>>>>  	{},
> >>>>>>  };
> >>>>>>  MODULE_DEVICE_TABLE(of, stm32_rproc_match);
> >>>>>> @@ -853,6 +965,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>>>>>  	struct device *dev = &pdev->dev;
> >>>>>>  	struct stm32_rproc *ddata;
> >>>>>>  	struct device_node *np = dev->of_node;
> >>>>>> +	struct tee_rproc *trproc = NULL;
> >>>>>>  	struct rproc *rproc;
> >>>>>>  	unsigned int state;
> >>>>>>  	int ret;
> >>>>>> @@ -861,11 +974,31 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>>>>>  	if (ret)
> >>>>>>  		return ret;
> >>>>>>  
> >>>>>> -	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
> >>>>>> -	if (!rproc)
> >>>>>> -		return -ENOMEM;
> >>>>>> +	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
> >>>>>> +		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
> >>>>>> +		if (IS_ERR(trproc)) {
> >>>>>> +			dev_err_probe(dev, PTR_ERR(trproc),
> >>>>>> +				      "signed firmware not supported by TEE\n");
> >>>>>> +			return PTR_ERR(trproc);
> >>>>>> +		}
> >>>>>> +		/*
> >>>>>> +		 * Delegate the firmware management to the secure context.
> >>>>>> +		 * The firmware loaded has to be signed.
> >>>>>> +		 */
> >>>>>> +		dev_info(dev, "Support of signed firmware only\n");
> >>>>>
> >>>>> Not sure what this adds.  Please remove.
> >>>>
> >>>> This is used to inform the user that only a signed firmware can be loaded, not
> >>>> an ELF file.
> >>>> I have a patch in my pipe to provide the supported format in the debugfs. In a
> >>>> first step, I can suppress this message and we can revisit the issue when I push
> >>>> the debugfs proposal.
> >>>>
> >>>> Thanks,
> >>>> Arnaud
> >>>>
> >>>>>
> >>>>>> +	}
> >>>>>> +	rproc = rproc_alloc(dev, np->name,
> >>>>>> +			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
> >>>>>> +			    NULL, sizeof(*ddata));
> >>>>>> +	if (!rproc) {
> >>>>>> +		ret = -ENOMEM;
> >>>>>> +		goto free_tee;
> >>>>>> +	}
> >>>>>>  
> >>>>>>  	ddata = rproc->priv;
> >>>>>> +	ddata->trproc = trproc;
> >>>>>> +	if (trproc)
> >>>>>> +		trproc->rproc = rproc;
> >>>>>>  
> >>>>>>  	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
> >>>>>>  
> >>>>>> @@ -916,6 +1049,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>>>>>  		device_init_wakeup(dev, false);
> >>>>>>  	}
> >>>>>>  	rproc_free(rproc);
> >>>>>> +free_tee:
> >>>>>> +	if (trproc)
> >>>>>> +		tee_rproc_unregister(trproc);
> >>>>>> +
> >>>>>>  	return ret;
> >>>>>>  }
> >>>>>>  
> >>>>>> @@ -937,6 +1074,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
> >>>>>>  		device_init_wakeup(dev, false);
> >>>>>>  	}
> >>>>>>  	rproc_free(rproc);
> >>>>>> +	if (ddata->trproc)
> >>>>>> +		tee_rproc_unregister(ddata->trproc);
> >>>>>>  }
> >>>>>>  
> >>>>>>  static int stm32_rproc_suspend(struct device *dev)
> >>>>>> -- 
> >>>>>> 2.25.1
> >>>>>>


From sboyd at kernel.org  Fri Feb  2 11:59:01 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri,  2 Feb 2024 11:59:01 -0800
Subject: [PATCH v3 0/7] of: populate of_root node if bootloader doesn't
Message-ID: <20240202195909.3458162-1-sboyd@kernel.org>

Arch maintainers, please ack/review patches.

This is a resend of a series from Frank last year[1]. I worked in Rob's
review comments to unconditionally call unflatten_device_tree() and
fixup/audit calls to of_have_populated_dt() so that behavior doesn't
change.

I need this series so I can add DT based tests in the clk framework.
Either I can merge it through the clk tree once everyone is happy, or
Rob can merge it through the DT tree and provide some branch so I can
base clk patches on it.

Changes from Frank's series[1]:
 * Add a DTB loaded kunit test
 * Make of_have_populated_dt() return false if the DTB isn't from the
   bootloader
 * Architecture calls made unconditional so that a root node is always
   made

Changes from v2 (https://lore.kernel.org/r/20240130004508.1700335-1-sboyd at kernel.org):
 * Reorder patches to have OF changes largely first
 * No longer modify initial_boot_params if ACPI=y
 * Put arm64 patch back to v1

Changes from v1 (https://lore.kernel.org/r/20240112200750.4062441-1-sboyd at kernel.org):
 * x86 patch included
 * arm64 knocks out initial dtb if acpi is in use
 * keep Kconfig hidden but def_bool enabled otherwise

Frank Rowand (2):
  of: Create of_root if no dtb provided by firmware
  of: unittest: treat missing of_root as error instead of fixing up

Stephen Boyd (5):
  of: Always unflatten in unflatten_and_copy_device_tree()
  um: Unconditionally call unflatten_device_tree()
  x86/of: Unconditionally call unflatten_and_copy_device_tree()
  arm64: Unconditionally call unflatten_device_tree()
  of: Add KUnit test to confirm DTB is loaded

 arch/arm64/kernel/setup.c    |  3 +-
 arch/um/kernel/dtb.c         | 14 ++++----
 arch/x86/kernel/devicetree.c | 24 +++++++-------
 drivers/of/.kunitconfig      |  3 ++
 drivers/of/Kconfig           | 11 ++++++-
 drivers/of/Makefile          |  4 ++-
 drivers/of/empty_root.dts    |  6 ++++
 drivers/of/fdt.c             | 64 +++++++++++++++++++++++++++---------
 drivers/of/of_test.c         | 48 +++++++++++++++++++++++++++
 drivers/of/platform.c        |  3 --
 drivers/of/unittest.c        | 16 +++------
 include/linux/of.h           | 25 ++++++++------
 12 files changed, 158 insertions(+), 63 deletions(-)
 create mode 100644 drivers/of/.kunitconfig
 create mode 100644 drivers/of/empty_root.dts
 create mode 100644 drivers/of/of_test.c

Cc: Anton Ivanov <anton.ivanov at cambridgegreys.com>
Cc: Brendan Higgins <brendan.higgins at linux.dev>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: David Gow <davidgow at google.com>
Cc: Frank Rowand <frowand.list at gmail.com>
Cc: Johannes Berg <johannes at sipsolutions.net>
Cc: Richard Weinberger <richard at nod.at>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Will Deacon <will at kernel.org>
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: <x86 at kernel.org>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: Saurabh Sengar <ssengar at linux.microsoft.com>

[1] https://lore.kernel.org/r/20230317053415.2254616-1-frowand.list at gmail.com

base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb  2 11:59:03 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri,  2 Feb 2024 11:59:03 -0800
Subject: [PATCH v3 2/7] of: Create of_root if no dtb provided by firmware
In-Reply-To: <20240202195909.3458162-1-sboyd@kernel.org>
References: <20240202195909.3458162-1-sboyd@kernel.org>
Message-ID: <20240202195909.3458162-3-sboyd@kernel.org>

From: Frank Rowand <frowand.list at gmail.com>

When enabling CONFIG_OF on a platform where 'of_root' is not populated
by firmware, we end up without a root node. In order to apply overlays
and create subnodes of the root node, we need one. Create this root node
by unflattening an empty builtin dtb.

If firmware provides a flattened device tree (FDT) then the FDT is
unflattened via setup_arch(). Otherwise, the call to
unflatten(_and_copy)?_device_tree() will create an empty root node.

We make of_have_populated_dt() return true only if the DTB was loaded by
firmware so that existing callers don't change behavior after this
patch. The call in the of platform code is removed because it prevents
overlays from creating platform devices when the platform bus isn't
fully initialized.

Signed-off-by: Frank Rowand <frowand.list at gmail.com>
Link: https://lore.kernel.org/r/20230317053415.2254616-2-frowand.list at gmail.com
Cc: Rob Herring <robh+dt at kernel.org>
[sboyd at kernel.org: Update of_have_populated_dt() to treat this empty dtb
as not populated. Drop setup_of() initcall]
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 drivers/of/Kconfig        |  2 +-
 drivers/of/Makefile       |  2 +-
 drivers/of/empty_root.dts |  6 ++++++
 drivers/of/fdt.c          | 32 +++++++++++++++++++++++++++++++-
 drivers/of/platform.c     |  3 ---
 include/linux/of.h        | 25 +++++++++++++++----------
 6 files changed, 54 insertions(+), 16 deletions(-)
 create mode 100644 drivers/of/empty_root.dts

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index da9826accb1b..17733285b415 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -54,7 +54,7 @@ config OF_FLATTREE
 	select CRC32
 
 config OF_EARLY_FLATTREE
-	bool
+	def_bool OF && !SPARC
 	select DMA_DECLARE_COHERENT if HAS_DMA && HAS_IOMEM
 	select OF_FLATTREE
 
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index eff624854575..df305348d1cb 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -2,7 +2,7 @@
 obj-y = base.o cpu.o device.o module.o platform.o property.o
 obj-$(CONFIG_OF_KOBJ) += kobj.o
 obj-$(CONFIG_OF_DYNAMIC) += dynamic.o
-obj-$(CONFIG_OF_FLATTREE) += fdt.o
+obj-$(CONFIG_OF_FLATTREE) += fdt.o empty_root.dtb.o
 obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o
 obj-$(CONFIG_OF_PROMTREE) += pdt.o
 obj-$(CONFIG_OF_ADDRESS)  += address.o
diff --git a/drivers/of/empty_root.dts b/drivers/of/empty_root.dts
new file mode 100644
index 000000000000..cf9e97a60f48
--- /dev/null
+++ b/drivers/of/empty_root.dts
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/dts-v1/;
+
+/ {
+
+};
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index dfeba8b8ce94..e5a385285149 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -8,6 +8,7 @@
 
 #define pr_fmt(fmt)	"OF: fdt: " fmt
 
+#include <linux/acpi.h>
 #include <linux/crash_dump.h>
 #include <linux/crc32.h>
 #include <linux/kernel.h>
@@ -32,6 +33,13 @@
 
 #include "of_private.h"
 
+/*
+ * __dtb_empty_root_begin[] and __dtb_empty_root_end[] magically created by
+ * cmd_dt_S_dtb in scripts/Makefile.lib
+ */
+extern uint8_t __dtb_empty_root_begin[];
+extern uint8_t __dtb_empty_root_end[];
+
 /*
  * of_fdt_limit_memory - limit the number of regions in the /memory node
  * @limit: maximum entries
@@ -1343,7 +1351,29 @@ static void *__init copy_device_tree(void *fdt)
  */
 void __init unflatten_device_tree(void)
 {
-	__unflatten_device_tree(initial_boot_params, NULL, &of_root,
+	void *fdt = initial_boot_params;
+
+	/* Don't use the bootloader provided DTB if ACPI is enabled */
+	if (!acpi_disabled)
+		fdt = NULL;
+
+	/*
+	 * Populate an empty root node when ACPI is enabled or bootloader
+	 * doesn't provide one.
+	 */
+	if (!fdt) {
+		fdt = (void *) __dtb_empty_root_begin;
+		/* fdt_totalsize() will be used for copy size */
+		if (fdt_totalsize(fdt) >
+		    __dtb_empty_root_end - __dtb_empty_root_begin) {
+			pr_err("invalid size in dtb_empty_root\n");
+			return;
+		}
+		of_fdt_crc32 = crc32_be(~0, fdt, fdt_totalsize(fdt));
+		fdt = copy_device_tree(fdt);
+	}
+
+	__unflatten_device_tree(fdt, NULL, &of_root,
 				early_init_dt_alloc_memory_arch, false);
 
 	/* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 126d265aa7d8..20087bb8a46b 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -549,9 +549,6 @@ static int __init of_platform_default_populate_init(void)
 
 	device_links_supplier_sync_state_pause();
 
-	if (!of_have_populated_dt())
-		return -ENODEV;
-
 	if (IS_ENABLED(CONFIG_PPC)) {
 		struct device_node *boot_display = NULL;
 		struct platform_device *dev;
diff --git a/include/linux/of.h b/include/linux/of.h
index 6a9ddf20e79a..52f6ad6a1c8c 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -180,11 +180,6 @@ static inline bool is_of_node(const struct fwnode_handle *fwnode)
 			&__of_fwnode_handle_node->fwnode : NULL;	\
 	})
 
-static inline bool of_have_populated_dt(void)
-{
-	return of_root != NULL;
-}
-
 static inline bool of_node_is_root(const struct device_node *node)
 {
 	return node && (node->parent == NULL);
@@ -549,11 +544,6 @@ static inline struct device_node *of_find_node_with_property(
 
 #define of_fwnode_handle(node) NULL
 
-static inline bool of_have_populated_dt(void)
-{
-	return false;
-}
-
 static inline struct device_node *of_get_compatible_child(const struct device_node *parent,
 					const char *compatible)
 {
@@ -1634,6 +1624,21 @@ static inline bool of_device_is_system_power_controller(const struct device_node
 	return of_property_read_bool(np, "system-power-controller");
 }
 
+/**
+ * of_have_populated_dt() - Has DT been populated by bootloader
+ *
+ * Return: True if a DTB has been populated by the bootloader and it isn't the
+ * empty builtin one. False otherwise.
+ */
+static inline bool of_have_populated_dt(void)
+{
+#ifdef CONFIG_OF
+	return of_property_present(of_root, "compatible");
+#else
+	return false;
+#endif
+}
+
 /*
  * Overlay support
  */
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb  2 11:59:02 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri,  2 Feb 2024 11:59:02 -0800
Subject: [PATCH v3 1/7] of: Always unflatten in unflatten_and_copy_device_tree()
In-Reply-To: <20240202195909.3458162-1-sboyd@kernel.org>
References: <20240202195909.3458162-1-sboyd@kernel.org>
Message-ID: <20240202195909.3458162-2-sboyd@kernel.org>

We want to populate an empty DT whenever CONFIG_OF is enabled so that
overlays can be applied and the DT unit tests can be run. Make
unflatten_and_copy_device_tree() stop printing a warning if the
'initial_boot_params' pointer is NULL. Instead, simply copy the dtb if
there is one and then unflatten it. If there isn't a DT to copy, then
the call to unflatten_device_tree() is largely a no-op, so nothing
really changes here.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list at gmail.com>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 drivers/of/fdt.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index bf502ba8da95..dfeba8b8ce94 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1318,6 +1318,21 @@ bool __init early_init_dt_scan(void *params)
 	return true;
 }
 
+static void *__init copy_device_tree(void *fdt)
+{
+	int size;
+	void *dt;
+
+	size = fdt_totalsize(fdt);
+	dt = early_init_dt_alloc_memory_arch(size,
+					     roundup_pow_of_two(FDT_V17_SIZE));
+
+	if (dt)
+		memcpy(dt, fdt, size);
+
+	return dt;
+}
+
 /**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
@@ -1350,22 +1365,9 @@ void __init unflatten_device_tree(void)
  */
 void __init unflatten_and_copy_device_tree(void)
 {
-	int size;
-	void *dt;
+	if (initial_boot_params)
+		initial_boot_params = copy_device_tree(initial_boot_params);
 
-	if (!initial_boot_params) {
-		pr_warn("No valid device tree found, continuing without\n");
-		return;
-	}
-
-	size = fdt_totalsize(initial_boot_params);
-	dt = early_init_dt_alloc_memory_arch(size,
-					     roundup_pow_of_two(FDT_V17_SIZE));
-
-	if (dt) {
-		memcpy(dt, initial_boot_params, size);
-		initial_boot_params = dt;
-	}
 	unflatten_device_tree();
 }
 
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb  2 11:59:05 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri,  2 Feb 2024 11:59:05 -0800
Subject: [PATCH v3 4/7] x86/of: Unconditionally call unflatten_and_copy_device_tree()
In-Reply-To: <20240202195909.3458162-1-sboyd@kernel.org>
References: <20240202195909.3458162-1-sboyd@kernel.org>
Message-ID: <20240202195909.3458162-5-sboyd@kernel.org>

Call this function unconditionally so that we can populate an empty DTB
on platforms that don't boot with a firmware provided or builtin DTB.
There's no harm in calling unflatten_device_tree() unconditionally here.
If there isn't a non-NULL 'initial_boot_params' pointer then
unflatten_device_tree() returns early.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list at gmail.com>
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: <x86 at kernel.org>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: Saurabh Sengar <ssengar at linux.microsoft.com>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 arch/x86/kernel/devicetree.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index afd09924094e..650752d112a6 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -283,22 +283,24 @@ void __init x86_flattree_get_config(void)
 	u32 size, map_len;
 	void *dt;
 
-	if (!initial_dtb)
-		return;
+	if (initial_dtb) {
+		map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
 
-	map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
+		dt = early_memremap(initial_dtb, map_len);
+		size = fdt_totalsize(dt);
+		if (map_len < size) {
+			early_memunmap(dt, map_len);
+			dt = early_memremap(initial_dtb, size);
+			map_len = size;
+		}
 
-	dt = early_memremap(initial_dtb, map_len);
-	size = fdt_totalsize(dt);
-	if (map_len < size) {
-		early_memunmap(dt, map_len);
-		dt = early_memremap(initial_dtb, size);
-		map_len = size;
+		early_init_dt_verify(dt);
 	}
 
-	early_init_dt_verify(dt);
 	unflatten_and_copy_device_tree();
-	early_memunmap(dt, map_len);
+
+	if (initial_dtb)
+		early_memunmap(dt, map_len);
 }
 #endif
 
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb  2 11:59:06 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri,  2 Feb 2024 11:59:06 -0800
Subject: [PATCH v3 5/7] arm64: Unconditionally call unflatten_device_tree()
In-Reply-To: <20240202195909.3458162-1-sboyd@kernel.org>
References: <20240202195909.3458162-1-sboyd@kernel.org>
Message-ID: <20240202195909.3458162-6-sboyd@kernel.org>

Call this function unconditionally so that we can populate an empty DTB
on platforms that don't boot with a firmware provided or builtin DTB.
When ACPI is in use, unflatten_device_tree() ignores the
'initial_boot_params' pointer so the live DT on those systems won't be
whatever that's pointing to. Similarly, when kexec copies the DT data
the previous kernel to the new one on ACPI systems,
of_kexec_alloc_and_setup_fdt() will ignore the live DT (the empty root
one) and copy the 'initial_boot_params' data.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list 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: <linux-arm-kernel at lists.infradead.org>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 arch/arm64/kernel/setup.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 417a8a86b2db..ede3d59dabf0 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -351,8 +351,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 	/* Parse the ACPI tables for possible boot-time configuration */
 	acpi_boot_table_init();
 
-	if (acpi_disabled)
-		unflatten_device_tree();
+	unflatten_device_tree();
 
 	bootmem_init();
 
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb  2 11:59:04 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri,  2 Feb 2024 11:59:04 -0800
Subject: [PATCH v3 3/7] um: Unconditionally call unflatten_device_tree()
In-Reply-To: <20240202195909.3458162-1-sboyd@kernel.org>
References: <20240202195909.3458162-1-sboyd@kernel.org>
Message-ID: <20240202195909.3458162-4-sboyd@kernel.org>

Call this function unconditionally so that we can populate an empty DTB
on platforms that don't boot with a command line provided DTB.  There's
no harm in calling unflatten_device_tree() unconditionally. If there
isn't a valid initial_boot_params dtb then unflatten_device_tree()
returns early.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list at gmail.com>
Cc: Richard Weinberger <richard at nod.at>
Cc: Anton Ivanov <anton.ivanov at cambridgegreys.com>
Cc: Johannes Berg <johannes at sipsolutions.net>
Cc: <linux-um at lists.infradead.org>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 arch/um/kernel/dtb.c  | 14 +++++++-------
 drivers/of/unittest.c |  4 ----
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/arch/um/kernel/dtb.c b/arch/um/kernel/dtb.c
index 484141b06938..4954188a6a09 100644
--- a/arch/um/kernel/dtb.c
+++ b/arch/um/kernel/dtb.c
@@ -16,16 +16,16 @@ void uml_dtb_init(void)
 	void *area;
 
 	area = uml_load_file(dtb, &size);
-	if (!area)
-		return;
+	if (area) {
+		if (!early_init_dt_scan(area)) {
+			pr_err("invalid DTB %s\n", dtb);
+			memblock_free(area, size);
+			return;
+		}
 
-	if (!early_init_dt_scan(area)) {
-		pr_err("invalid DTB %s\n", dtb);
-		memblock_free(area, size);
-		return;
+		early_init_fdt_scan_reserved_mem();
 	}
 
-	early_init_fdt_scan_reserved_mem();
 	unflatten_device_tree();
 }
 
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index e9e90e96600e..a8b27dd16ecf 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -4075,10 +4075,6 @@ static int __init of_unittest(void)
 	add_taint(TAINT_TEST, LOCKDEP_STILL_OK);
 
 	/* adding data for unittest */
-
-	if (IS_ENABLED(CONFIG_UML))
-		unittest_unflatten_overlay_base();
-
 	res = unittest_data_add();
 	if (res)
 		return res;
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb  2 11:59:08 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri,  2 Feb 2024 11:59:08 -0800
Subject: [PATCH v3 7/7] of: Add KUnit test to confirm DTB is loaded
In-Reply-To: <20240202195909.3458162-1-sboyd@kernel.org>
References: <20240202195909.3458162-1-sboyd@kernel.org>
Message-ID: <20240202195909.3458162-8-sboyd@kernel.org>

Add a KUnit test that confirms a DTB has been loaded, i.e. there is a
root node, and that the of_have_populated_dt() API works properly.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list at gmail.com>
Cc: David Gow <davidgow at google.com>
Cc: Brendan Higgins <brendan.higgins at linux.dev>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 drivers/of/.kunitconfig |  3 +++
 drivers/of/Kconfig      |  9 ++++++++
 drivers/of/Makefile     |  2 ++
 drivers/of/of_test.c    | 48 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 62 insertions(+)
 create mode 100644 drivers/of/.kunitconfig
 create mode 100644 drivers/of/of_test.c

diff --git a/drivers/of/.kunitconfig b/drivers/of/.kunitconfig
new file mode 100644
index 000000000000..5a8fee11978c
--- /dev/null
+++ b/drivers/of/.kunitconfig
@@ -0,0 +1,3 @@
+CONFIG_KUNIT=y
+CONFIG_OF=y
+CONFIG_OF_KUNIT_TEST=y
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 17733285b415..53d1b5dd89e8 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -37,6 +37,15 @@ config OF_UNITTEST
 
 	  If unsure, say N here. This option is not safe to enable.
 
+config OF_KUNIT_TEST
+	tristate "Devicetree KUnit Test" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  This option builds KUnit unit tests for device tree infrastructure.
+
+	  If unsure, say N here, but this option is safe to enable.
+
 config OF_ALL_DTBS
 	bool "Build all Device Tree Blobs"
 	depends on COMPILE_TEST
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index df305348d1cb..251d33532148 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -19,4 +19,6 @@ obj-y	+= kexec.o
 endif
 endif
 
+obj-$(CONFIG_OF_KUNIT_TEST) += of_test.o
+
 obj-$(CONFIG_OF_UNITTEST) += unittest-data/
diff --git a/drivers/of/of_test.c b/drivers/of/of_test.c
new file mode 100644
index 000000000000..71a767b42b43
--- /dev/null
+++ b/drivers/of/of_test.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit tests for OF APIs
+ */
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include <kunit/test.h>
+
+/*
+ * Test that the root node "/" can be found by path.
+ */
+static void dtb_root_node_found_by_path(struct kunit *test)
+{
+	struct device_node *np;
+
+	np = of_find_node_by_path("/");
+	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, np);
+	of_node_put(np);
+}
+
+/*
+ * Test that the 'of_root' global variable is always populated when DT code is
+ * enabled.
+ */
+static void dtb_root_node_populates_of_root(struct kunit *test)
+{
+	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, of_root);
+}
+
+static struct kunit_case dtb_test_cases[] = {
+	KUNIT_CASE(dtb_root_node_found_by_path),
+	KUNIT_CASE(dtb_root_node_populates_of_root),
+	{}
+};
+
+/*
+ * Test suite to confirm a DTB is loaded.
+ */
+static struct kunit_suite dtb_suite = {
+	.name = "dtb",
+	.test_cases = dtb_test_cases,
+};
+
+kunit_test_suites(
+	&dtb_suite,
+);
+MODULE_LICENSE("GPL");
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb  2 11:59:07 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri,  2 Feb 2024 11:59:07 -0800
Subject: [PATCH v3 6/7] of: unittest: treat missing of_root as error instead of fixing up
In-Reply-To: <20240202195909.3458162-1-sboyd@kernel.org>
References: <20240202195909.3458162-1-sboyd@kernel.org>
Message-ID: <20240202195909.3458162-7-sboyd@kernel.org>

From: Frank Rowand <frowand.list at gmail.com>

unflatten_device_tree() now ensures that the 'of_root' node is populated
with the root of a default empty devicetree. Remove the unittest code
that created 'of_root' if it was missing. Verify that 'of_root' is valid
before attempting to attach the testcase-data subtree. Remove the
unittest code that unflattens the unittest overlay base if architecture
is UML because that is always done now.

Signed-off-by: Frank Rowand <frowand.list at gmail.com>
Link: https://lore.kernel.org/r/20230317053415.2254616-3-frowand.list at gmail.com
Cc: Rob Herring <robh+dt at kernel.org>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 drivers/of/unittest.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index a8b27dd16ecf..742d919e8ab4 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -1732,20 +1732,16 @@ static int __init unittest_data_add(void)
 		return -EINVAL;
 	}
 
+	/* attach the sub-tree to live tree */
 	if (!of_root) {
-		of_root = unittest_data_node;
-		for_each_of_allnodes(np)
-			__of_attach_node_sysfs(np);
-		of_aliases = of_find_node_by_path("/aliases");
-		of_chosen = of_find_node_by_path("/chosen");
-		of_overlay_mutex_unlock();
-		return 0;
+		pr_warn("%s: no live tree to attach sub-tree\n", __func__);
+		kfree(unittest_data);
+		return -ENODEV;
 	}
 
 	EXPECT_BEGIN(KERN_INFO,
 		     "Duplicate name in testcase-data, renamed to \"duplicate-name#1\"");
 
-	/* attach the sub-tree to live tree */
 	np = unittest_data_node->child;
 	while (np) {
 		struct device_node *next = np->sibling;
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From robh at kernel.org  Fri Feb  2 12:02:53 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 14:02:53 -0600
Subject: [PATCH v5] dt-bindings: misc: xlnx,sd-fec: convert bindings to
 yaml
In-Reply-To: <20240131170650.530079-1-dragan.cvetic@amd.com>
References: <20240131170650.530079-1-dragan.cvetic@amd.com>
Message-ID: <170690417008.874488.5757943525065117413.robh@kernel.org>


On Wed, 31 Jan 2024 17:06:45 +0000, Dragan Cvetic wrote:
> Convert AMD (Xilinx) sd-fec bindings to yaml format, so it can validate
> dt-entries as well as any future additions to yaml.
> Change in clocks is due to IP is itself configurable and
> only the first two clocks are in all combinations. The last
> 6 clocks can be present in some of them. It means order is
> not really fixed and any combination is possible.
> Interrupt may or may not be present.
> The documentation for sd-fec bindings is now YAML, so update the
> MAINTAINERS file.
> Update the link to the new yaml file in xilinx_sdfec.rst.
> 
> Signed-off-by: Dragan Cvetic <dragan.cvetic at amd.com>
> ---
> Changes in v2:
> ---
> Drop clocks description.
> Use "contains:" with enum for optional clock-names and update
> comment explaining diference from the original DT binding file.
> Remove trailing full stops.
> Add more details in sdfec-code description.
> Set sdfec-code to "string" not "string-array"
> ---
> Changes in v3:
> Fix a mistake in example, set interrupt type to 0.
> ---
> Changes in v4:
> Set interrupt type to high level sensitive.
> Remove '|' from descriptions, no need to preserve format.
> Remove not needed empty line.
> ---
> Changes in v5:
> Apply allOf to clock-names and put permanent clock items
> inside enum.
> ---
>  .../devicetree/bindings/misc/xlnx,sd-fec.txt  |  58 --------
>  .../devicetree/bindings/misc/xlnx,sd-fec.yaml | 140 ++++++++++++++++++
>  Documentation/misc-devices/xilinx_sdfec.rst   |   2 +-
>  MAINTAINERS                                   |   2 +-
>  4 files changed, 142 insertions(+), 60 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/misc/xlnx,sd-fec.txt
>  create mode 100644 Documentation/devicetree/bindings/misc/xlnx,sd-fec.yaml
> 

Applied, thanks!



From robh at kernel.org  Fri Feb  2 12:07:08 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 14:07:08 -0600
Subject: [PATCH v2 2/2] dt-bindings: mmp-dma: convert to YAML
In-Reply-To: <20240131-pxa-dma-yaml-v2-2-9611d0af0edc@skole.hr>
References: <20240131-pxa-dma-yaml-v2-0-9611d0af0edc@skole.hr>
 <20240131-pxa-dma-yaml-v2-2-9611d0af0edc@skole.hr>
Message-ID: <170690442812.903220.16045094080463776332.robh@kernel.org>


On Wed, 31 Jan 2024 22:26:03 +0100, Duje Mihanovi? wrote:
> Convert the Marvell MMP DMA binding to YAML.
> 
> The TXT binding mentions that the controller may have one IRQ per DMA
> channel. Examples of this were dropped in the YAML binding because of
> dt_binding_check complaints (either too many interrupt cells or
> interrupts) and the fact that this is not used in any of the in-tree
> device trees.
> 
> Signed-off-by: Duje Mihanovi? <duje.mihanovic at skole.hr>
> ---
>  .../devicetree/bindings/dma/marvell,mmp-dma.yaml   | 72 +++++++++++++++++++
>  Documentation/devicetree/bindings/dma/mmp-dma.txt  | 81 ----------------------
>  2 files changed, 72 insertions(+), 81 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From robin.murphy at arm.com  Fri Feb  2 12:11:48 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 2 Feb 2024 20:11:48 +0000
Subject: [PATCH v2] perf/hx_arm_ni: Support uncore ARM NI-700 PMU
In-Reply-To: <7C9733413A0F8F60+0214f04d-173d-4513-ac1e-681c2f2a8de4@shingroup.cn>
References: <20240131070821.11477-1-jialong.yang@shingroup.cn>
 <fe3e97c0-f641-48d6-9941-837e73ae3cfe@arm.com>
 <7C9733413A0F8F60+0214f04d-173d-4513-ac1e-681c2f2a8de4@shingroup.cn>
Message-ID: <8daf740f-f16b-49af-8da9-7c7750092539@arm.com>

On 2024-02-01 2:40 am, Yang Jialong ??? wrote:
> 
> 
> ? 2024/2/1 0:50, Robin Murphy ??:
>> On 31/01/2024 7:08 am, JiaLong.Yang wrote:
>>> This code is based on uncore PMUs arm_smmuv3_pmu and arm-cmn.
>>> One ni-700 can have many clock domains. Each of them has only one PMU.
>>> Here one PMU corresponds to one 'struct ni_pmu' instance.
>>> PMU name will be ni_pmu_N_M, which N means different NI-700s and M means
>>> different PMU in one NI-700. If only one NI-700 found in NI-700, name 
>>> will
>>> be ni_pmu_N.
>>> Node interface event name will be xxni_N_eventname, such as
>>> asni_0_rdreq_any. There are many kinds of type of nodes in one clock
>>> domain. Also means that there are many kinds of that in one PMU. So we
>>> distinguish them by xxni string. Besides, maybe there are many nodes
>>> have same type. So we have number N in event name.
>>> By ni_pmu_0_0/asni_0_rdreq_any/, we can pinpoint accurate bus traffic.
>>> Example1: perf stat -a -e 
>>> ni_pmu_0_0/asni_0_rdreq_any/,ni_pmu_0_0/cycles/
>>> EXample2: perf stat -a -e ni_pmu_0_0/asni,id=0,event=0x0/
>>
>> Oh! I've had a driver for this thing sat around for ages waiting to 
>> find someone with an interest in testing it. Given that from a quick 
>> skim of this patch I'd also have several concerns with this 
>> implementation, may I ask that you have a look at my branch and see if 
>> it works for you?
> 
> If permission I will test.

Thanks! I see you've also tried to support having the IRQs combined 
together - does your platform need that right away? That's another thing 
I've been anticipating but haven't got round to wiring up yet (it's a 
bit more fiddly than just IRQF_SHARED since perf has some expectations 
around affinity to event->cpu), but I can have a go at getting it done.

>>
>> https://gitlab.arm.com/linux-arm/linux-rm/-/tree/ni-dev?ref_type=heads
>>
>> In particular, after the pain of maintaining event aliases in arm-cmn 
>> I'd really like to get away from doing that again and instead move 
>> over to jevents this time (especially now that system PMU support is a 
>> bit more developed there) - I just haven't yet got round to hooking up 
>> the identifier and writing the JSON files, since it hasn't seemed like 
>> much of a priority before I know whether the code even works.
>>
> 
> It's a useful way.
> Uncore PMU is increasing. Not only CPU event can be writen in jevents.
> I have not considered it when writing code in a low version.
> 
> Finally, I have opened a case in arm suppport for linux ni pmu driver.
> They tell me no driver.

Oh dear, sorry about that - I'd have hoped that a question about a Linux 
PMU driver might have found its way to our team, even if they weren't 
aware that NI-700 has already been a specific item on our roadmap for 
some time :(

Thanks,
Robin.


From maz at kernel.org  Fri Feb  2 12:14:37 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 02 Feb 2024 20:14:37 +0000
Subject: [PATCH v2 06/25] KVM: arm64: nv: Add sanitising to VNCR-backed HCRX_EL2
In-Reply-To: <Zb0_0fq4E1_L7lC6@linux.dev>
References: <20240130204533.693853-1-maz@kernel.org>
	<20240130204533.693853-7-maz@kernel.org>
	<ZbytUKPFYiP2cdd8@linux.dev>
	<86h6iq7w3x.wl-maz@kernel.org>
	<Zb0jRzTYyc0IxR00@linux.dev>
	<Zb0_0fq4E1_L7lC6@linux.dev>
Message-ID: <86bk8y7hea.wl-maz@kernel.org>

On Fri, 02 Feb 2024 19:17:37 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Fri, Feb 02, 2024 at 05:15:51PM +0000, Oliver Upton wrote:
> > On Fri, Feb 02, 2024 at 02:56:50PM +0000, Marc Zyngier wrote:
> > > No amount of warnings will do, because people don't give a damn.
> > > 
> > > I'm actually in favour of something far more radical: we snapshot the
> > > raw value of all the used RES0/1, and put BUILD_BUG_ON()s that fire if
> > > any value has changed. They will have to touch the KVM code to fix
> > > that, and we catch them red-handed.
> > 
> > Oh I like that a lot more.
> 
> Unsure which registers you planned to give this treatment, but all of
> the ID registers we know about should probably go in this bucket too.

Yup. My current plan is to simply extract all RES0/RES1 values from
arch/arm64/include/generated/asm/sysreg-defs.h (currently 232
definitions), and assert on that. We can relax it for registers that
don't have any RES0 or RES1 bits, but that's about it.

	M.

-- 
Without deviation from the norm, progress is not possible.


From dsimic at manjaro.org  Fri Feb  2 12:14:58 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 02 Feb 2024 21:14:58 +0100
Subject: [PATCH v2 2/4] arm64: dts: rockchip: enable temperature driven
 fan control on Rock 5B
In-Reply-To: <CABjd4Yy0HYFEdW-XA4vmX4aMhCS-fKd7X_f=ar3qcm_4ROxk1A@mail.gmail.com>
References: <20240130-rk-dts-additions-v2-0-c6222c4c78df@gmail.com>
 <20240130-rk-dts-additions-v2-2-c6222c4c78df@gmail.com>
 <CAGb2v65--rgb2FqmG_0-w1-jUL0odqKXxiZJ-XPYA4uomfYmaQ@mail.gmail.com>
 <5e3e12d65e4919372e7fb02d56202393@manjaro.org>
 <CABjd4Yx0kQ67fScrFVavjObMLaNt_PJ3TVOhLpCmj00Dx9dOqA@mail.gmail.com>
 <a8aa04ca0061cd09c7b3eb5336e534a4@manjaro.org>
 <bd6e93cf907572e86697dc10a50bfe66@manjaro.org>
 <CABjd4Yy0HYFEdW-XA4vmX4aMhCS-fKd7X_f=ar3qcm_4ROxk1A@mail.gmail.com>
Message-ID: <4e7c2b5a938bd7c919b852699c951701@manjaro.org>

Hello Alexey,

On 2024-02-02 15:42, Alexey Charkov wrote:
> On Thu, Feb 1, 2024 at 11:43?PM Dragan Simic <dsimic at manjaro.org> 
> wrote:
>> On 2024-02-01 20:31, Dragan Simic wrote:
>>> On 2024-02-01 20:15, Alexey Charkov wrote:
>>>> On Thu, Feb 1, 2024 at 9:34?PM Dragan Simic <dsimic at manjaro.org> 
>>>> wrote:
>>>>> On 2024-02-01 15:26, Chen-Yu Tsai wrote:
>>>>>> Is there any reason this can't be enabled by default in the .dtsi 
>>>>>> file?
>>>>>> The thermal sensor doesn't depend on anything external, so there 
>>>>>> should
>>>>>> be no reason to push this down to the board level.
>>>>> 
>>>>> Actually, there is a reason.  Different boards can handle the
>>>>> critical overheating differently, by letting the CRU or the PMIC
>>>>> handle it.  This was also the case for the RK3399.
>>>>> 
>>>>> Please, have a look at the following DT properties, which are
>>>>> consumed by drivers/thermal/rockchip_thermal.c:
>>>>>    - "rockchip,hw-tshut-mode"
>>>>>    - "rockchip,hw-tshut-polarity"
>>>>> 
>>>>> See also page 1,372 of the RK3588 TRM v1.0.
>>>>> 
>>>>> This has also reminded me to check how is the Rock 5B actually 
>>>>> wired,
>>>>> just to make sure.  We actually need to provide the two DT 
>>>>> properties
>>>>> listed above, at least to avoid emitting the warnings.
>>>> 
>>>> Well the defaults are already provided in rk3588s.dtsi, so there 
>>>> won't
>>>> be any warnings (see lines 2222-2223 in Linus' master version), and
>>>> according to the vendor kernel those are also what Rock 5B uses.
>>> 
>>> Yes, I noticed the same a couple of minutes after sending my last
>>> message, but didn't want to make more noise about it. :)  I would've
>>> mentioned it in my next message, of course.
>> 
>> Just checked the Rock 5B schematic and it expects the CRU to be used
>> to perform the hardware reset in case of a thermal runaway, so the
>> defaults in the RK3588s dtsi are fine.  I had to double-check it. :)
> 
> I've just looked at Rock 5B, Rock 5A and NanoPC T6 schematics, and
> they all seem to have the TSADC_SHUT line connected to RESET_L.

Ah, I see it now in the Rock 5B schematic, thank you for the
correction.  I somehow managed to miss it initially;  here's
the link to a screenshot from the Rock 5B schematic v1.423, for
future reference:  https://i.imgur.com/IGAPPgl.png .

> At the same time, Radxa's device tree uses the default
> CRU-based option.

Here's the link to a screenshot from the RK3588 Hardware
Design Guide v1.0, which shows the recommended reset signal
paths for RK3588 boards:  https://i.imgur.com/DNqhjfP.png .

As visible in the Rock 5B schematic, it expectedly follows
this recommendation from Rockchip, so we should actually use
GPIO-based handling for the thermal runaways on the Rock 5B,
to have the PMIC reset as well.  Here's the link to another
screenshot from the Rock 5B schematic v1.423, for future
reference:  https://i.imgur.com/BdgZ30C.png .

Of course, it should be tested to make sure that the thermal
runaway resets work fine.

It isn't uncommon for downstream DTs to sometimes contain
some small mistakes that somehow remained undetected.

> To me this seems to imply that the CRU option should always work, by
> the virtue of CRU being on-chip. At the same time, if the right GPIOs
> are wired to the PMIC reset line for a particular board, the board
> may also choose to use the GPIO option - or stick with CRU.
> 
> If that interpretation is correct, then I suggest we enable TSADC by
> default in the .dtsi, and let it handle both throttling and CRU-based
> critical resets on all boards. Those who know what they are doing may
> then elect to switch their board to GPIO-PMIC based reset.
> 
> What do you think?

I think that, if we choose to enable CRU-based thermal runaway
resets without going into too much detail for each board (but
we should go into the publicly available board schematics, as
also noted in my last comment in this message), we should do
that in the board dts files, instead of just enabling the TSADC
in the RK3588(s) SoC dtsi.

That way, we would clearly indicate the TSADC to be a board-
specific feature, and hopefully gain more attention from the
people interested in the boards, to perform some additional
testing, etc.

>> However, now I have some open questions related to interrupt-driven
>> operation.  I'll research it further and come back with an update.
>> 
>>>> This made me think however: what if a board doesn't enable TSADC, 
>>>> but
>>>> has OPPs in place for higher voltage and frequency states? There 
>>>> won't
>>>> be any throttling (as there won't be any thermal monitoring) and 
>>>> there
>>>> might not be a critical shutdown at all if it heats up - possibly 
>>>> even
>>>> causing hardware damage. In this case it seems that having TSADC
>>>> enabled by default would at least trigger passive cooling, hopefully
>>>> avoiding the critical shutdown altogether and making those 
>>>> properties
>>>> irrelevant in 99% cases.
>>> 
>>> Those are very good questions.  Thumbs up!
>>> 
>>> The trouble is that the boards can use different wiring to handle the
>>> thermal runaways, by expecting the PMIC to handle it or not.  Thus,
>>> it's IMHO better to simply leave that to be tested and enabled on a
>>> board-by-board basis, whenever a new RK3588(s)-based board is added.
>>> 
>>> Thus, the only right way at this point would be to merge the addition
>>> of the OPPs and the enabling of the TSADC for all currently supported
>>> RK3588(s)-based boards at once, instead of just for the Rock 5B.
> 
> If we can agree on a workable 'default-on' configuration for TSADC to
> be included in the .dtsi I think that would be preferable, because it
> would enable all boards to benefit from higher OPPs and throttling.

Please, see my other comments.  I hope we can agree on that.

> This would also save us from a scenario when OPPs get included in the
> default .dtsi, but TSADC is off by default, and then some poor soul
> tries to add a new board with a minimal .dts, forgetting to enable
> TSADC and having their SoC fried under high load...

Well, those poor souls can't escape the need to know what are
they doing. :)  Also, I think it's much more likely that adding
a new RK3588-based board would actually start by editing the
board dts of some already supported RK3588 board, which the way
I propose this to be handled would already have the TSADC enabled,
eliminating the risks yout pointed out.

Please note that the TSADC has been disabled in the RK3399 SoC
dtsi and enabled on a per-RK3399-board-dtsi basis, so we'd also
have some consistency by following the same approach with the
RK3588(s) SoC dtsi.  Consistency is good, if you agree.

>>> I can handle the required changes for the QuartzPro64 dts file.  For
>>> other supported RK3588(s)-based boards, if there are no people having
>>> access to them and willing to perform the dts changes and the 
>>> testing,
>>> I'd be willing to go through the board schematics, to enable the
>>> TSADC for them as well.
>> 
>> Please, let me know are you fine with the above-described approach.
> 
> I believe it's great if we can go through the schematics no matter
> what! Although if we agree that CRU is an always-working default
> option for all, then why don't we just enable TSADC for all, and leave
> the conversion to GPIO-PMIC resets for later and for where it's
> needed?

Great!  We can surely go through the supported RK3588(s) boards
that make their schematics publicly available, and enable the
TSADC in their board dts files accordingly.

For the remaining RK3588(s) boards that remain "black boxes" to
us, we can enable the TSADC in their board dts files with the
let-the-CRU-handle-thermal-runaway defaults, and leave any future
refinements to the people interested in those boards.

That would be a rather clean approach, if you agree.


From nfraprado at collabora.com  Fri Feb  2 12:15:46 2024
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Fri, 2 Feb 2024 15:15:46 -0500
Subject: [PATCH 3/3] media: mediatek: vcodedc: Fix
 Wcast-function-type-strict warnings
In-Reply-To: <5658ec37-868f-454d-a149-467e6de139cd@collabora.com>
References: <20240128-fix-clang-warnings-v1-0-1d946013a421@chromium.org>
 <20240128-fix-clang-warnings-v1-3-1d946013a421@chromium.org>
 <20240201221654.GC2240065@dev-arch.thelio-3990X>
 <CABCJKudd3SUy3Qor7Tc0zyJsSAWy0PavbbBFALuWEpBa32pBCQ@mail.gmail.com>
 <5658ec37-868f-454d-a149-467e6de139cd@collabora.com>
Message-ID: <12d0c580-788d-4466-af8a-feb5ab3c6677@notapiano>

On Fri, Feb 02, 2024 at 01:58:05PM +0100, AngeloGioacchino Del Regno wrote:
> Il 01/02/24 23:25, Sami Tolvanen ha scritto:
> > On Thu, Feb 1, 2024 at 10:17?PM Nathan Chancellor <nathan at kernel.org> wrote:
> > > 
> > > On Sun, Jan 28, 2024 at 02:12:22AM +0000, Ricardo Ribalda wrote:
> > > > Building with LLVM=1 throws the following warning:
> > > > drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c:38:32: warning: cast from 'mtk_vcodec_ipi_handler' (aka 'void (*)(void *, unsigned int, void *)') to 'ipi_handler_t' (aka 'void (*)(const void *, unsigned int, void *)') converts to incompatible function type [-Wcast-function-type-strict]
> > > > 
> > > > Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
> > > 
> > > I am not positive because I don't have any hardware to test this driver
> > > but I suspect this patch is just hiding the warning without actually
> > > addressing the issue that it is pointing out.
> > 
> > Agreed, this won't fix the issue. The correct solution is to drop the
> > cast and change the handler type to match the pointer type (i.e. use
> > const void* for the first argument).
> > 
> 
> Even though I agree that the correct solution is to change the handler's type,
> I think that having a test on the actual hardware done is still valuable.
> 
> We scheduled a job on KernelCI to test this commit on our integration kernel,
> you'll get results for ChromeOS' tast decoders (MT8195 only) and Fluster tests
> on MT8183/8186/8192/8195.
> 
> 
> The results should be available in a couple of hours here, relative to
> commit `49955a84129dbe1f94fedf729690efcf28513828` on our tree:
> https://chromeos.kernelci.org/job/collabora-chromeos-kernel/branch/for-kernelci/
> 
> P.S.: If they don't, feel free to ping me or Nicolas (added to the loop) about it.

Hi,

the results are available at 

https://chromeos.kernelci.org/test/job/collabora-chromeos-kernel/branch/for-kernelci/kernel/v6.8-rc2-3109-g49955a84129d/

(You need to type "decoder" into the search bar to limit the results to only the
decoder tests)

The only regressions I see are due to infrastructure error or broken test
unrelated to this change (v4l2-decoder-conformance-h264-frext test on
MT8195-Tomato, and cros-tast-decoder-v4l2-sl-h264 test on MT8183-Juniper)

Otherwise, all platforms (MT8183/8186/8192/8195) and video codecs
(VP8/VP9/H264/H265/AV1) seem unaffected.

Note that these are GCC builds.

Thanks,
N?colas


From robh at kernel.org  Fri Feb  2 12:16:46 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 14:16:46 -0600
Subject: [PATCH 0/3] fpga: xilinx-selectmap: add new driver
In-Reply-To: <20240131230542.3993409-1-charles.perry@savoirfairelinux.com>
References: <20240129225602.3832449-1-charles.perry@savoirfairelinux.com>
 <20240131230542.3993409-1-charles.perry@savoirfairelinux.com>
Message-ID: <20240202201646.GA903809-robh@kernel.org>

On Wed, Jan 31, 2024 at 06:05:30PM -0500, Charles Perry wrote:
> Hello,
> 
> This patchset adds a new driver for the 7 series FPGA's SelectMAP
> interface.
> 
> The SelectMAP interface shares a common GPIO protocol with the SPI
> interface which is already in the kernel (drivers/fpga/xilinx-spi.c).
> The approach proposed in this patchset is to refactor xilinx-spi.c into
> xilinx-core.c which would handle the common GPIO protocol. This is then
> used to build two drivers, the already existing xilinx-spi.c driver and
> a newly added xilinx-selectmap.c driver.
> 
> The SelectMAP driver proposed only supports 8 bit mode. This is because
> the 16 and 32 bits mode have limitations with regards to compressed
> bitstream support as well as introducing endianness considerations.
> 
> I'm testing xilinx-selectmap.c on a custom i.MX6 board connected to an
> Artix 7 FPGA. Flashing a 913K bitstream takes 0.44 seconds.
> 
> v2: From Krzysztof Kozlowski review's:
>   * Use more conventional names for gpio DT bindings
>   * fix example in DT bindings
>   * add mc-peripheral-props.yaml to DT bindings
>   * fix various formatting mistakes
>   * Remove all occurences of the "slave" word.

Please label the series with the version number and don't send new 
versions as replies to the previous version.

Rob


From Markus.Elfring at web.de  Fri Feb  2 12:21:19 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Fri, 2 Feb 2024 21:21:19 +0100
Subject: clk: imx: scu: Use common error handling code in
 __imx_clk_gpr_scu()
In-Reply-To: <Zb04UUeE/cU9HtKZ@linaro.org>
References: <20231210171907.3410922-1-visitorckw@gmail.com>
 <0e906ec6-fe73-4dbd-b555-a2c03b6e1030@web.de> <Zb04UUeE/cU9HtKZ@linaro.org>
Message-ID: <1a3c05b8-45f8-4205-8cb5-3b8f2d791877@web.de>

>> Use another label so that a bit of exception handling can be better reused
>> at the end of this function.
>
> Please don't send patches as reply to other(s) patches.

This is a general possibility to connect an information sources with
a corresponding change idea.
Will the acceptance grow for the presented source code transformation?

Regards,
Markus


From robh at kernel.org  Fri Feb  2 12:26:03 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 14:26:03 -0600
Subject: [PATCH v3 1/5] dt-bindings: mfd: syscon: Add
 ti,am62-usb-phy-ctrl compatible
In-Reply-To: <20240201120332.4811-2-rogerq@kernel.org>
References: <20240201120332.4811-1-rogerq@kernel.org>
 <20240201120332.4811-2-rogerq@kernel.org>
Message-ID: <170690556320.1075006.3197540858856784438.robh@kernel.org>


On Thu, 01 Feb 2024 14:03:28 +0200, Roger Quadros wrote:
> Add the compatible for TI AM62 USB PHY Control register. This
> register is found in the TI AM62 WKUP_CTRL_MMR0 space [1]. It
> is used to indicate the USB PHY PLL reference clock rate and
> core voltage level to the USB controller.
> 
> [1] - https://www.ti.com/lit/pdf/spruiv7
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
> 
> Notes:
>     Changelog:
> 
>     v3 - add compatibles in alphabetical order
>     v2 - New patch
> 
>     Changelog:
> 
>     v2 - New patch
> 
>  Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>



From andrew at lunn.ch  Fri Feb  2 12:25:55 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 2 Feb 2024 21:25:55 +0100
Subject: [PATCH net-next v3 1/7] net: dsa: mt7530: empty default case on
 mt7530_setup_port5()
In-Reply-To: <Zb0u8NY0q6ay17j5@shell.armlinux.org.uk>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-1-63d5adae99ca@arinc9.com>
 <ZbzUotyQm/FyKK7G@shell.armlinux.org.uk>
 <e3b4add6-425c-46ca-9da5-8713055fc422@arinc9.com>
 <Zb0u8NY0q6ay17j5@shell.armlinux.org.uk>
Message-ID: <59e88b15-da57-4cff-83b3-91e38a185461@lunn.ch>

On Fri, Feb 02, 2024 at 06:05:36PM +0000, Russell King (Oracle) wrote:
> On Fri, Feb 02, 2024 at 08:44:39PM +0300, Ar?n? ?NAL wrote:
> > On 2.02.2024 14:40, Russell King (Oracle) wrote:
> > > While reviewing this change, but not related to it, I notice that this
> > > function sets the TX delay based on the RGMII interface mode. This isn't
> > > correct. I've explained why this is this many times in the past, but
> > > essentially it comes down to the model:
> > > 
> > > 
> > > phy-mode in NIC node	Network driver	PCB		PHY
> > > rgmii			no delays	delays		no delays
> > > rgmii-id		no delays	no delays	tx/rx delays
> > > rgmii-txid		no delays	no delays	tx delays
> > > rgmii-rxid		no delays	no delays	rx delays
> > > 
> > > Then we have rx-internal-delay-ps and tx-internal-delay-ps in the NIC
> > > node which define the RGMII delays at the local end and similar
> > > properties for the PHY node.
> > > 
> > > 
> > > So, if we take the view that, when a switch is connected to a NIC in
> > > RGMII mode, then the phy-mode specified delays still should not impact
> > > the local NIC.
> > > 
> > > Now, for the switch, we specify the phy-mode in the port node as well.
> > > Consider the case of a switch port connected to a RGMII PHY. This has
> > > to operate in exactly the same way as a normal NIC - that is, the
> > > RGMII delays at the port should be ignored as it's the responsibility
> > > of a PHY.

Not quite. It is unusual, but there are a few MAC drivers which do act
on phy-mode, to configure MAC delays. However, if they do this, they
then mask the value of phy-mode passed to the PHY in order to avoid
double delays. Its not something i recommend, we prefer the PHYs do
the delays. And it something i strongly suggest we avoid in DSA.

> > > The final scenario to examine is the case of a RGMII switch port
> > > connected to a NIC.

This should also extend to a port connected to a port of another
switch. For Marvell switches, these are so called DSA ports.

> > > The NIC's phy-mode has no way to be communicated
> > > to DSA or vice versa, so neither phy-mode can impact the other side
> > > of the RGMII link, but should only place the link into RGMII mode.
> > > Given everything I've said above, the only way to configure RGMII
> > > delays is via the rx-internal-delay-ps and tx-internal-delay-ps
> > > properties. So, DSA drivers should _not_ be configuring their ports
> > > with RGMII delays based on the RGMII phy interface mode.

Marvell goes against this. rx-internal-delay-ps and
tx-internal-delay-ps are pretty new, when compared to the age of
mv88e6xxx. I had the problem of a FEC connected to an mv88e6xxx using
RGMII and i needed to somehow configure RGMII delays, or packets did
not get through. So mv88e6xxx will apply phy-mode to ports being used
in CPU or DSA mode. So in the case of the FEC->switch, rgmii-id is
used by the switch. For DSA->DSA, there are DT blobs with rgmii-txid
on both ends of the link, which results in the needed delays.

> > > The above is my purely logically reasoned point of view on this
> > > subject. Others may have other (to me completely illogical)
> > > interpretations that can only lead to interoperability issues.

Now that rx-internal-delay-ps and tx-internal-delay-ps actually exist,
these are the best ways to handle such delays, for new drivers. But we
cannot change old drivers without causing regressions.

       Andrew


From dianders at chromium.org  Fri Feb  2 12:38:38 2024
From: dianders at chromium.org (Doug Anderson)
Date: Fri, 2 Feb 2024 12:38:38 -0800
Subject: [PATCH] regset: use vmalloc() for regset_get_alloc()
In-Reply-To: <d7154f86-d185-495d-aa84-63d4561f1e47@sirena.org.uk>
References: <20240202012249.GU2087318@ZenIV> <CAD=FV=X5dpMyCGg4Xn+ApRwmiLB5zB0LTMCoSfW_X6eAsfQy8w@mail.gmail.com>
 <20240202030438.GV2087318@ZenIV> <CAD=FV=Wbq7R9AirvxnW1aWoEnp2fWQrwBsxsDB46xbfTLHCZ4w@mail.gmail.com>
 <20240202034925.GW2087318@ZenIV> <20240202040503.GX2087318@ZenIV>
 <CAD=FV=X93KNMF4NwQY8uh-L=1J8PrDFQYu-cqSd+KnY5+Pq+_w@mail.gmail.com>
 <20240202164947.GC2087318@ZenIV> <20240202165524.GD2087318@ZenIV>
 <Zb0vem7KC28gmT5U@e133380.arm.com> <d7154f86-d185-495d-aa84-63d4561f1e47@sirena.org.uk>
Message-ID: <CAD=FV=ViEjvEevLq+1ZEVQB9qh4ofJHvLYfNu0XTQSjNRpZzAA@mail.gmail.com>

Hi,

On Fri, Feb 2, 2024 at 11:43?AM Mark Brown <broonie at kernel.org> wrote:
>
> On Fri, Feb 02, 2024 at 06:07:54PM +0000, Dave Martin wrote:
>
> > So, if the only reason for trying to migrate to vmalloc() is to cope
> > with an insanely sized regset on arm64, I think somehow or other we can
> > avoid that.
>
> With SME we do routinely see the full glory of the 64K regset for ZA in
> emulated systems so I think we have to treat it as an issue.

Ah, got it. 64K is much less likely to be as big of a problem (only an
order 4 allocation), but you're right that it's still a size where
kvmalloc() would be an improvement. With that in mind I'll plan to
send out a v2 of my patch where I use kvmalloc() instead of vmalloc()
and update the commit description a bit, including a link to this
thread. Then I will assume that others on this thread will move
forward with actually making the allocations smaller.

Please yell if the above sounds wrong. :-)

-Doug


From pr-tracker-bot at kernel.org  Fri Feb  2 12:43:34 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 02 Feb 2024 20:43:34 +0000
Subject: [GIT PULL] arm64 fixes for -rc3
In-Reply-To: <20240202111107.GA16598@willie-the-truck>
References: <20240202111107.GA16598@willie-the-truck>
Message-ID: <170690661450.32059.3284110650609579874.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 2 Feb 2024 11:11:08 +0000:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/ec86369c88f6794a6cfa0383f715f276305399ed

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From quic_uchalich at quicinc.com  Fri Feb  2 12:51:34 2024
From: quic_uchalich at quicinc.com (Unnathi Chalicheemala)
Date: Fri, 2 Feb 2024 12:51:34 -0800
Subject: [PATCH 6/9] remoteproc: qcom_q6v5_wcss: Use devm_rproc_alloc()
 helper
In-Reply-To: <20240123184632.725054-6-afd@ti.com>
References: <20240123184632.725054-1-afd@ti.com>
 <20240123184632.725054-6-afd@ti.com>
Message-ID: <256072b3-c1d0-4e11-9456-bbd50b84a310@quicinc.com>



On 1/23/2024 10:46 AM, Andrew Davis wrote:
> Use the device lifecycle managed allocation function. This helps prevent
> mistakes like freeing out of order in cleanup functions and forgetting to
> free on error paths.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  drivers/remoteproc/qcom_q6v5_wcss.c | 24 +++++++++---------------
>  1 file changed, 9 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
> index cff1fa07d1def..94f68c919ee62 100644
> --- a/drivers/remoteproc/qcom_q6v5_wcss.c
> +++ b/drivers/remoteproc/qcom_q6v5_wcss.c
> @@ -1011,8 +1011,8 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>  	if (!desc)
>  		return -EINVAL;
>  
> -	rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
> -			    desc->firmware_name, sizeof(*wcss));
> +	rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
> +				 desc->firmware_name, sizeof(*wcss));
>  	if (!rproc) {
>  		dev_err(&pdev->dev, "failed to allocate rproc\n");
>  		return -ENOMEM;
> @@ -1027,29 +1027,29 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>  
>  	ret = q6v5_wcss_init_mmio(wcss, pdev);
>  	if (ret)
> -		goto free_rproc;
> +		return ret;
>  
>  	ret = q6v5_alloc_memory_region(wcss);
>  	if (ret)
> -		goto free_rproc;
> +		return ret;
>  
>  	if (wcss->version == WCSS_QCS404) {
>  		ret = q6v5_wcss_init_clock(wcss);
>  		if (ret)
> -			goto free_rproc;
> +			return ret;
>  
>  		ret = q6v5_wcss_init_regulator(wcss);
>  		if (ret)
> -			goto free_rproc;
> +			return ret;
>  	}
>  
>  	ret = q6v5_wcss_init_reset(wcss, desc);
>  	if (ret)
> -		goto free_rproc;
> +		return ret;
>  
>  	ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, desc->crash_reason_smem, NULL, NULL);
>  	if (ret)
> -		goto free_rproc;
> +		return ret;
>  
>  	qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss");
>  	qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss");
> @@ -1061,16 +1061,11 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>  
>  	ret = rproc_add(rproc);
>  	if (ret)
> -		goto free_rproc;
> +		return ret;
>  
>  	platform_set_drvdata(pdev, rproc);
>  
>  	return 0;
> -
> -free_rproc:
> -	rproc_free(rproc);
> -
> -	return ret;

This return statement should stay, right?

>  }
>  
>  static void q6v5_wcss_remove(struct platform_device *pdev)
> @@ -1080,7 +1075,6 @@ static void q6v5_wcss_remove(struct platform_device *pdev)
>  
>  	qcom_q6v5_deinit(&wcss->q6v5);
>  	rproc_del(rproc);
> -	rproc_free(rproc);
>  }
>  
>  static const struct wcss_data wcss_ipq8074_res_init = {


From charles.perry at savoirfairelinux.com  Fri Feb  2 12:53:47 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Fri, 2 Feb 2024 15:53:47 -0500 (EST)
Subject: [PATCH 0/3] fpga: xilinx-selectmap: add new driver
In-Reply-To: <20240202201646.GA903809-robh@kernel.org>
References: <20240129225602.3832449-1-charles.perry@savoirfairelinux.com> <20240131230542.3993409-1-charles.perry@savoirfairelinux.com> <20240202201646.GA903809-robh@kernel.org>
Message-ID: <840358370.469058.1706907227423.JavaMail.zimbra@savoirfairelinux.com>

On Feb 2, 2024, at 3:16 PM, Rob Herring robh at kernel.org wrote:
> On Wed, Jan 31, 2024 at 06:05:30PM -0500, Charles Perry wrote:
>> Hello,
>> 
>> This patchset adds a new driver for the 7 series FPGA's SelectMAP
>> interface.
>> 
>> The SelectMAP interface shares a common GPIO protocol with the SPI
>> interface which is already in the kernel (drivers/fpga/xilinx-spi.c).
>> The approach proposed in this patchset is to refactor xilinx-spi.c into
>> xilinx-core.c which would handle the common GPIO protocol. This is then
>> used to build two drivers, the already existing xilinx-spi.c driver and
>> a newly added xilinx-selectmap.c driver.
>> 
>> The SelectMAP driver proposed only supports 8 bit mode. This is because
>> the 16 and 32 bits mode have limitations with regards to compressed
>> bitstream support as well as introducing endianness considerations.
>> 
>> I'm testing xilinx-selectmap.c on a custom i.MX6 board connected to an
>> Artix 7 FPGA. Flashing a 913K bitstream takes 0.44 seconds.
>> 
>> v2: From Krzysztof Kozlowski review's:
>>   * Use more conventional names for gpio DT bindings
>>   * fix example in DT bindings
>>   * add mc-peripheral-props.yaml to DT bindings
>>   * fix various formatting mistakes
>>   * Remove all occurences of the "slave" word.
> 
> Please label the series with the version number and don't send new
> versions as replies to the previous version.
> 
> Rob

Ok, will do.

Regards,
Charles


From lkp at intel.com  Fri Feb  2 13:08:39 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 3 Feb 2024 05:08:39 +0800
Subject: [PATCH v2 4/5] mm: ptdump: Have ptdump_check_wx() return bool
In-Reply-To: <7943149fe955458cb7b57cd483bf41a3aad94684.1706610398.git.christophe.leroy@csgroup.eu>
References: <7943149fe955458cb7b57cd483bf41a3aad94684.1706610398.git.christophe.leroy@csgroup.eu>
Message-ID: <202402030403.WAFc9HZO-lkp@intel.com>

Hi Christophe,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]

url:    https://github.com/intel-lab-lkp/linux/commits/Christophe-Leroy/arm-ptdump-Rename-CONFIG_DEBUG_WX-to-CONFIG_ARM_DEBUG_WX/20240130-183913
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/7943149fe955458cb7b57cd483bf41a3aad94684.1706610398.git.christophe.leroy%40csgroup.eu
patch subject: [PATCH v2 4/5] mm: ptdump: Have ptdump_check_wx() return bool
config: x86_64-defconfig (https://download.01.org/0day-ci/archive/20240203/202402030403.WAFc9HZO-lkp at intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240203/202402030403.WAFc9HZO-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402030403.WAFc9HZO-lkp at intel.com/

All errors (new ones prefixed by >>):

>> arch/x86/mm/dump_pagetables.c:365:6: error: two or more data types in declaration specifiers
     365 | bool void ptdump_walk_pgd_level_core(struct seq_file *m,
         |      ^~~~
   arch/x86/mm/dump_pagetables.c:365:11: warning: no previous prototype for 'ptdump_walk_pgd_level_core' [-Wmissing-prototypes]
     365 | bool void ptdump_walk_pgd_level_core(struct seq_file *m,
         |           ^~~~~~~~~~~~~~~~~~~~~~~~~~


vim +365 arch/x86/mm/dump_pagetables.c

   364	
 > 365	bool void ptdump_walk_pgd_level_core(struct seq_file *m,
   366					       struct mm_struct *mm, pgd_t *pgd,
   367					       bool checkwx, bool dmesg)
   368	{
   369		const struct ptdump_range ptdump_ranges[] = {
   370	#ifdef CONFIG_X86_64
   371		{0, PTRS_PER_PGD * PGD_LEVEL_MULT / 2},
   372		{GUARD_HOLE_END_ADDR, ~0UL},
   373	#else
   374		{0, ~0UL},
   375	#endif
   376		{0, 0}
   377	};
   378	
   379		struct pg_state st = {
   380			.ptdump = {
   381				.note_page	= note_page,
   382				.effective_prot = effective_prot,
   383				.range		= ptdump_ranges
   384			},
   385			.level = -1,
   386			.to_dmesg	= dmesg,
   387			.check_wx	= checkwx,
   388			.seq		= m
   389		};
   390	
   391		ptdump_walk_pgd(&st.ptdump, mm, pgd);
   392	
   393		if (!checkwx)
   394			return true;
   395		if (st.wx_pages) {
   396			pr_info("x86/mm: Checked W+X mappings: FAILED, %lu W+X pages found.\n",
   397				st.wx_pages);
   398	
   399			return false;
   400		} else {
   401			pr_info("x86/mm: Checked W+X mappings: passed, no W+X pages found.\n");
   402	
   403			return true;
   404		}
   405	}
   406	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From afd at ti.com  Fri Feb  2 13:14:20 2024
From: afd at ti.com (Andrew Davis)
Date: Fri, 2 Feb 2024 15:14:20 -0600
Subject: [PATCH 6/9] remoteproc: qcom_q6v5_wcss: Use devm_rproc_alloc()
 helper
In-Reply-To: <256072b3-c1d0-4e11-9456-bbd50b84a310@quicinc.com>
References: <20240123184632.725054-1-afd@ti.com>
 <20240123184632.725054-6-afd@ti.com>
 <256072b3-c1d0-4e11-9456-bbd50b84a310@quicinc.com>
Message-ID: <60d46d58-ad77-47e8-8ff6-bc05db7cf1be@ti.com>

On 2/2/24 2:51 PM, Unnathi Chalicheemala wrote:
> 
> 
> On 1/23/2024 10:46 AM, Andrew Davis wrote:
>> Use the device lifecycle managed allocation function. This helps prevent
>> mistakes like freeing out of order in cleanup functions and forgetting to
>> free on error paths.
>>
>> Signed-off-by: Andrew Davis <afd at ti.com>
>> ---
>>   drivers/remoteproc/qcom_q6v5_wcss.c | 24 +++++++++---------------
>>   1 file changed, 9 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
>> index cff1fa07d1def..94f68c919ee62 100644
>> --- a/drivers/remoteproc/qcom_q6v5_wcss.c
>> +++ b/drivers/remoteproc/qcom_q6v5_wcss.c
>> @@ -1011,8 +1011,8 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>>   	if (!desc)
>>   		return -EINVAL;
>>   
>> -	rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
>> -			    desc->firmware_name, sizeof(*wcss));
>> +	rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
>> +				 desc->firmware_name, sizeof(*wcss));
>>   	if (!rproc) {
>>   		dev_err(&pdev->dev, "failed to allocate rproc\n");
>>   		return -ENOMEM;
>> @@ -1027,29 +1027,29 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>>   
>>   	ret = q6v5_wcss_init_mmio(wcss, pdev);
>>   	if (ret)
>> -		goto free_rproc;
>> +		return ret;
>>   
>>   	ret = q6v5_alloc_memory_region(wcss);
>>   	if (ret)
>> -		goto free_rproc;
>> +		return ret;
>>   
>>   	if (wcss->version == WCSS_QCS404) {
>>   		ret = q6v5_wcss_init_clock(wcss);
>>   		if (ret)
>> -			goto free_rproc;
>> +			return ret;
>>   
>>   		ret = q6v5_wcss_init_regulator(wcss);
>>   		if (ret)
>> -			goto free_rproc;
>> +			return ret;
>>   	}
>>   
>>   	ret = q6v5_wcss_init_reset(wcss, desc);
>>   	if (ret)
>> -		goto free_rproc;
>> +		return ret;
>>   
>>   	ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, desc->crash_reason_smem, NULL, NULL);
>>   	if (ret)
>> -		goto free_rproc;
>> +		return ret;
>>   
>>   	qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss");
>>   	qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss");
>> @@ -1061,16 +1061,11 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>>   
>>   	ret = rproc_add(rproc);
>>   	if (ret)
>> -		goto free_rproc;
>> +		return ret;
>>   
>>   	platform_set_drvdata(pdev, rproc);
>>   
>>   	return 0;
>> -
>> -free_rproc:
>> -	rproc_free(rproc);
>> -
>> -	return ret;
> 
> This return statement should stay, right?
> 

No path goes to "free_rproc" anymore, so we always do the "return 0;"
above on non-error paths.

Andrew

>>   }
>>   
>>   static void q6v5_wcss_remove(struct platform_device *pdev)
>> @@ -1080,7 +1075,6 @@ static void q6v5_wcss_remove(struct platform_device *pdev)
>>   
>>   	qcom_q6v5_deinit(&wcss->q6v5);
>>   	rproc_del(rproc);
>> -	rproc_free(rproc);
>>   }
>>   
>>   static const struct wcss_data wcss_ipq8074_res_init = {


From robh at kernel.org  Fri Feb  2 13:17:49 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 15:17:49 -0600
Subject: [PATCH v4 01/10] dt-bindings: iommu: Add Translation Buffer Unit
 bindings
In-Reply-To: <20240201210529.7728-2-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
 <20240201210529.7728-2-quic_c_gdjako@quicinc.com>
Message-ID: <20240202211749.GA1467077-robh@kernel.org>

On Thu, Feb 01, 2024 at 01:05:20PM -0800, Georgi Djakov wrote:
> Add common bindings for the TBUs to describe their properties. The
> TBUs are modelled as child devices of the IOMMU and each of them is
> described with their compatible, reg and stream-id-range properties.
> There could be other implementation specific properties to describe
> any resources like clocks, regulators, power-domains, interconnects
> that would be needed for TBU operation. Such properties will be
> documented in a separate vendor-specific TBU schema.
> 
> Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
> ---
>  .../devicetree/bindings/iommu/arm,smmu.yaml   | 14 ++++++++++
>  .../devicetree/bindings/iommu/tbu-common.yaml | 28 +++++++++++++++++++
>  2 files changed, 42 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iommu/tbu-common.yaml
> 
> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> index a4042ae24770..ba3237023b39 100644
> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> @@ -235,6 +235,20 @@ properties:
>        enabled for any given device.
>      $ref: /schemas/types.yaml#/definitions/phandle
>  
> +  '#address-cells':
> +    enum: [ 1, 2 ]
> +
> +  '#size-cells':
> +    enum: [ 1, 2 ]
> +
> +  ranges: true
> +
> +patternProperties:
> +  "^tbu@[0-9a-f]+$":
> +    description: TBU child nodes
> +    type: object
> +    $ref: tbu-common.yaml#

       additionalProperties: false


However, that's going to break with the extra QCom properties. In 
json-schema, you can't have 2 schemas and extend the properties of 
their child nodes. The validator doesn't "see" the child node schemas at 
the same time. You are going to have to move QCom SMMU to its own schema 
and remove it from arm,smmu.yaml.

Rob


From robh at kernel.org  Fri Feb  2 13:24:20 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 15:24:20 -0600
Subject: [PATCH 1/2] dt-bindings: phy: mediatek,xfi-tphy: add new bindings
In-Reply-To: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
Message-ID: <20240202212420.GA1561174-robh@kernel.org>

On Thu, Feb 01, 2024 at 09:52:20PM +0000, Daniel Golle wrote:
> Add bindings for the MediaTek XFI T-PHY Ethernet SerDes PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:

This is v4 unless I'm confused[1]. Where's the revision history?

Rob

[1] https://lore.kernel.org/all/b875f693f6d4367a610a12ef324584f3bf3a1c1c.1702352117.git.daniel at makrotopia.org/

> 
> via USXGMII PCS:
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
> 
> via LynxI SGMII PCS:
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---
>  .../bindings/phy/mediatek,xfi-tphy.yaml       | 80 +++++++++++++++++++
>  1 file changed, 80 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> new file mode 100644
> index 0000000000000..e897118dcf7e6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> @@ -0,0 +1,80 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/mediatek,xfi-tphy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek XFI T-PHY
> +
> +maintainers:
> +  - Daniel Golle <daniel at makrotopia.org>
> +
> +description:
> +  The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes
> +  used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in
> +  MediaTek's 10G-capabale SoCs.
> +
> +properties:
> +  $nodename:
> +    pattern: "^phy@[0-9a-f]+$"
> +
> +  compatible:
> +    const: mediatek,mt7988-xfi-tphy
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: XFI PHY clock
> +      - description: XFI register clock
> +
> +  clock-names:
> +    items:
> +      - const: xfipll
> +      - const: topxtal
> +
> +  resets:
> +    items:
> +      - description: PEXTP reset

What is PEXTP?


From daniel at makrotopia.org  Fri Feb  2 13:36:39 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Fri, 2 Feb 2024 21:36:39 +0000
Subject: [PATCH 1/2] dt-bindings: phy: mediatek,xfi-tphy: add new bindings
In-Reply-To: <20240202212420.GA1561174-robh@kernel.org>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
 <20240202212420.GA1561174-robh@kernel.org>
Message-ID: <Zb1gZ7BjJlGCw13Z@makrotopia.org>

On Fri, Feb 02, 2024 at 03:24:20PM -0600, Rob Herring wrote:
> On Thu, Feb 01, 2024 at 09:52:20PM +0000, Daniel Golle wrote:
> > Add bindings for the MediaTek XFI T-PHY Ethernet SerDes PHY found in the
> > MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
> This is v4 unless I'm confused[1]. Where's the revision history?

It's a new series only covering the XFI T-PHY driver.
However, I should have written a cover letter referencing the previous
series to netdev. Sorry for that and thank you for pointing it out.

> 
> Rob
> 
> [1] https://lore.kernel.org/all/b875f693f6d4367a610a12ef324584f3bf3a1c1c.1702352117.git.daniel at makrotopia.org/
> 
> > 
> > via USXGMII PCS:
> >  * USXGMII
> >  * 10GBase-R
> >  * 5GBase-R
> > 
> > via LynxI SGMII PCS:
> >  * 2500Base-X
> >  * 1000Base-X
> >  * Cisco SGMII (MAC side)
> > 
> > Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> > ---
> >  .../bindings/phy/mediatek,xfi-tphy.yaml       | 80 +++++++++++++++++++
> >  1 file changed, 80 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> > new file mode 100644
> > index 0000000000000..e897118dcf7e6
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> > @@ -0,0 +1,80 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/phy/mediatek,xfi-tphy.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MediaTek XFI T-PHY
> > +
> > +maintainers:
> > +  - Daniel Golle <daniel at makrotopia.org>
> > +
> > +description:
> > +  The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes
> > +  used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in
> > +  MediaTek's 10G-capabale SoCs.
> > +
> > +properties:
> > +  $nodename:
> > +    pattern: "^phy@[0-9a-f]+$"
> > +
> > +  compatible:
> > +    const: mediatek,mt7988-xfi-tphy
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    items:
> > +      - description: XFI PHY clock
> > +      - description: XFI register clock
> > +
> > +  clock-names:
> > +    items:
> > +      - const: xfipll
> > +      - const: topxtal
> > +
> > +  resets:
> > +    items:
> > +      - description: PEXTP reset
> 
> What is PEXTP?
> 


From quic_uchalich at quicinc.com  Fri Feb  2 13:37:58 2024
From: quic_uchalich at quicinc.com (Unnathi Chalicheemala)
Date: Fri, 2 Feb 2024 13:37:58 -0800
Subject: [PATCH 6/9] remoteproc: qcom_q6v5_wcss: Use devm_rproc_alloc()
 helper
In-Reply-To: <60d46d58-ad77-47e8-8ff6-bc05db7cf1be@ti.com>
References: <20240123184632.725054-1-afd@ti.com>
 <20240123184632.725054-6-afd@ti.com>
 <256072b3-c1d0-4e11-9456-bbd50b84a310@quicinc.com>
 <60d46d58-ad77-47e8-8ff6-bc05db7cf1be@ti.com>
Message-ID: <073bcb5c-6718-4a64-8d14-281a589d2205@quicinc.com>

On 2/2/2024 1:14 PM, Andrew Davis wrote:
> On 2/2/24 2:51 PM, Unnathi Chalicheemala wrote:
>>
>>
>> On 1/23/2024 10:46 AM, Andrew Davis wrote:
>>> Use the device lifecycle managed allocation function. This helps prevent
>>> mistakes like freeing out of order in cleanup functions and forgetting to
>>> free on error paths.
>>>
>>> Signed-off-by: Andrew Davis <afd at ti.com>
>>> ---
>>> ? drivers/remoteproc/qcom_q6v5_wcss.c | 24 +++++++++---------------
>>> ? 1 file changed, 9 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
>>> index cff1fa07d1def..94f68c919ee62 100644
>>> --- a/drivers/remoteproc/qcom_q6v5_wcss.c
>>> +++ b/drivers/remoteproc/qcom_q6v5_wcss.c
>>> @@ -1011,8 +1011,8 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>>> ????? if (!desc)
>>> ????????? return -EINVAL;
>>> ? -??? rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
>>> -??????????????? desc->firmware_name, sizeof(*wcss));
>>> +??? rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
>>> +???????????????? desc->firmware_name, sizeof(*wcss));
>>> ????? if (!rproc) {
>>> ????????? dev_err(&pdev->dev, "failed to allocate rproc\n");
>>> ????????? return -ENOMEM;
>>> @@ -1027,29 +1027,29 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>>> ? ????? ret = q6v5_wcss_init_mmio(wcss, pdev);
>>> ????? if (ret)
>>> -??????? goto free_rproc;
>>> +??????? return ret;
>>> ? ????? ret = q6v5_alloc_memory_region(wcss);
>>> ????? if (ret)
>>> -??????? goto free_rproc;
>>> +??????? return ret;
>>> ? ????? if (wcss->version == WCSS_QCS404) {
>>> ????????? ret = q6v5_wcss_init_clock(wcss);
>>> ????????? if (ret)
>>> -??????????? goto free_rproc;
>>> +??????????? return ret;
>>> ? ????????? ret = q6v5_wcss_init_regulator(wcss);
>>> ????????? if (ret)
>>> -??????????? goto free_rproc;
>>> +??????????? return ret;
>>> ????? }
>>> ? ????? ret = q6v5_wcss_init_reset(wcss, desc);
>>> ????? if (ret)
>>> -??????? goto free_rproc;
>>> +??????? return ret;
>>> ? ????? ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, desc->crash_reason_smem, NULL, NULL);
>>> ????? if (ret)
>>> -??????? goto free_rproc;
>>> +??????? return ret;
>>> ? ????? qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss");
>>> ????? qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss");
>>> @@ -1061,16 +1061,11 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
>>> ? ????? ret = rproc_add(rproc);
>>> ????? if (ret)
>>> -??????? goto free_rproc;
>>> +??????? return ret;
>>> ? ????? platform_set_drvdata(pdev, rproc);
>>> ? ????? return 0;
>>> -
>>> -free_rproc:
>>> -??? rproc_free(rproc);
>>> -
>>> -??? return ret;
>>
>> This return statement should stay, right?
>>
> 
> No path goes to "free_rproc" anymore, so we always do the "return 0;"
> above on non-error paths.
> 
> Andrew
> 


You're right, thanks all QCOM peripheral patches LGTM.

>>> ? }
>>> ? ? static void q6v5_wcss_remove(struct platform_device *pdev)
>>> @@ -1080,7 +1075,6 @@ static void q6v5_wcss_remove(struct platform_device *pdev)
>>> ? ????? qcom_q6v5_deinit(&wcss->q6v5);
>>> ????? rproc_del(rproc);
>>> -??? rproc_free(rproc);
>>> ? }
>>> ? ? static const struct wcss_data wcss_ipq8074_res_init = {


From robh at kernel.org  Fri Feb  2 13:50:29 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 2 Feb 2024 15:50:29 -0600
Subject: [PATCH v7 1/5] dt-bindings: remoteproc: k3-m4f: Add K3 AM64x SoCs
In-Reply-To: <20240202175538.1705-2-hnagalla@ti.com>
References: <20240202175538.1705-1-hnagalla@ti.com>
 <20240202175538.1705-2-hnagalla@ti.com>
Message-ID: <20240202215029.GA1597859-robh@kernel.org>

On Fri, Feb 02, 2024 at 11:55:34AM -0600, Hari Nagalla wrote:
> K3 AM64x SoC has a Cortex M4F subsystem in the MCU voltage 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: Martyn Welch <martyn.welch at collabora.com>
> Signed-off-by: Hari Nagalla <hnagalla at ti.com>
> ---
> Changes since v1:
>  - Spelling corrections
>  - Corrected to pass DT checks
> 
> Changes since v2:
>  - Missed spelling correction to commit message
> 
> Changes since v3:
>  - Removed unnecessary descriptions and used generic memory region names
>  - Made mboxes and memory-region optional
>  - Removed unrelated items from examples
> 
> Changes since v4:
>  - Rebased to the latest kernel-next tree
>  - Added optional sram memory region for m4f device node
> 
> Changes since v5:
>  - None
> 
> Changes since v6:
>  - Removed blank line, fixed type for firm-ware property and binding check
>    errors.
> 
> link to v6:
>   https://lore.kernel.org/all/20230913111644.29889-2-hnagalla at ti.com/
> 
>  .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 138 ++++++++++++++++++
>  1 file changed, 138 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..645dbce3773b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
> @@ -0,0 +1,138 @@
> +# 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>
> +  - Mathieu Poirier <mathieu.poirier at linaro.org>
> +
> +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 without an IPC. Where as some industrial and
> +  home automation applications, may use the M4F core as a remote processor
> +  with IPC communications.
> +
> +$ref: /schemas/arm/keystone/ti,k3-sci-common.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - ti,am64-m4fss
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  "#address-cells":
> +    const: 2
> +
> +  "#size-cells":
> +    const: 2
> +
> +  reg:
> +    items:
> +      - description: IRAM internal memory region
> +      - description: DRAM internal memory region
> +
> +  reg-names:
> +    items:
> +      - const: iram
> +      - const: dram
> +
> +  resets:
> +    maxItems: 1
> +
> +  firmware-name:
> +    maxItems: 1
> +    description: Name of firmware to load for the M4F core
> +
> +  mboxes:
> +    description: |

Don't need '|' if no formatting.

> +      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. 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.yaml

This has moved to dtschema. I'd just drop the file name.

> +      Optional memory regions available for firmware specific purposes.
> +    maxItems: 8
> +    items:
> +      - description: regions used for DMA allocations like vrings, vring buffers
> +                     and memory dedicated to firmware's specific purposes.
> +    additionalItems: true

I think you want just:

minItems: 1
maxItems: 8

> +
> +  sram:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 4
> +    items:
> +      maxItems: 1
> +    description: |
> +      phandles to reserved on-chip SRAM regions. The regions should be
> +      defined as child nodes of the respective SRAM node, and
> +      should be defined as per the generic bindings in,
> +      Documentation/devicetree/bindings/sram/sram.yaml
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - ti,sci
> +  - ti,sci-dev-id
> +  - ti,sci-proc-ids
> +  - resets
> +  - firmware-name
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    reserved-memory {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        mcu_m4fss_dma_memory_region: m4f-dma-memory at 9cb00000 {
> +            compatible = "shared-dma-pool";
> +            reg = <0x00 0x9cb00000 0x00 0x100000>;
> +            no-map;
> +        };
> +
> +        mcu_m4fss_memory_region: m4f-memory at 9cc00000 {
> +            compatible = "shared-dma-pool";
> +            reg = <0x00 0x9cc00000 0x00 0xe00000>;
> +            no-map;
> +        };
> +    };
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        mailbox0_cluster0: mailbox-0 {
> +            #mbox-cells = <1>;
> +        };
> +
> +        remoteproc 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 = "am62-mcu-m4f0_0-fw";
> +            mboxes = <&mailbox0_cluster0>, <&mbox_m4_0>;
> +            memory-region = <&mcu_m4fss_dma_memory_region>,
> +                            <&mcu_m4fss_memory_region>;
> +            sram = <&oc_sram>;
> +         };
> +    };
> -- 
> 2.34.1
> 


From helgaas at kernel.org  Fri Feb  2 13:54:31 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 2 Feb 2024 15:54:31 -0600
Subject: [PATCH v9 05/16] PCI: imx6: Using "linux,pci-domain" as slot ID
In-Reply-To: <20240119171122.3057511-6-Frank.Li@nxp.com>
Message-ID: <20240202215431.GA728556@bhelgaas>

On Fri, Jan 19, 2024 at 12:11:11PM -0500, Frank Li wrote:
> Avoid use get slot id by compared with register physical address. If there
> are more than 2 slots, compared logic will become complex.
> 
> "linux,pci-domain" already exist at dts since commit:
> 	commit (c0b70f05c87f3b arm64: dts: imx8mq: use_dt_domains for pci node).
> 
> So it is safe to remove compare basic address code:
> 	...
> 	if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> 		imx6_pcie->controller_id = 1;
> 	...

I have no idea what this is telling me.  I guess you don't want to use
IMX8MQ_PCIE2_BASE_ADDR to decide something?  That much sounds good:
the *address* of some MMIO space doesn't tell us anything about the
function of that space.

I expect the "compatible" string to tell the driver what the
programming model of the device is.

> +	/* Using linux,pci-domain as PCI slot id */
> +	imx6_pcie->controller_id = of_get_pci_domain_nr(node);
> +	/*
> +	 * If there are no "linux,pci-domain" property specified in DT, then assume only one
> +	 * controller is available.
> +	 */
> +	if (imx6_pcie->controller_id == -EINVAL)
> +		imx6_pcie->controller_id = 0;
> +	else if (imx6_pcie->controller_id < 0)
> +		return dev_err_probe(dev, imx6_pcie->controller_id,
> +				     "linux,pci-domain have wrong value\n");

Maybe I'm missing something here.  It looks like this driver uses
controller_id to distinguish between hardware variants or maybe
between two Root Ports (slots?) in the same SoC?

  imx6_pcie_grp_offset
    return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;

  imx6_pcie_configure_type
    id = imx6_pcie->controller_id
    if (!drvdata->mode_mask[id])         # <-- looks unsafe
      id = 0;
    regmap_update_bits(drvdata->mode_off[id], ...)

(This "mode_mask[id]" looks like it will reference garbage if the DT
supplies "linux,pci-domain = <2>".  A bogus DT shouldn't be able to
cause a driver to misbehave like that.)

That doesn't seem related to "linux,pci-domain" at all.

Bjorn


From fancer.lancer at gmail.com  Fri Feb  2 13:58:39 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Sat, 3 Feb 2024 00:58:39 +0300
Subject: [PATCH net v3] net: stmmac: xgmac: fix handling of DPP safety
 error for DMA channels
In-Reply-To: <20240131020828.2007741-1-0x1207@gmail.com>
References: <20240131020828.2007741-1-0x1207@gmail.com>
Message-ID: <ksfs7uag4yukqbeygch7pxvr5axyrqz4gunq2xes3ppmtrgm5b@hwh5yx5qz3wl>

On Wed, Jan 31, 2024 at 10:08:28AM +0800, Furong Xu wrote:
> Commit 56e58d6c8a56 ("net: stmmac: Implement Safety Features in
> XGMAC core") checks and reports safety errors, but leaves the
> Data Path Parity Errors for each channel in DMA unhandled at all, lead to
> a storm of interrupt.
> Fix it by checking and clearing the DMA_DPP_Interrupt_Status register.
> 
> Fixes: 56e58d6c8a56 ("net: stmmac: Implement Safety Features in XGMAC core")
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> ---
> Changes in v3:
>  - code style fix, thanks Paolo Abeni
> 
> Changes in v2:
>   - explicit enable Data Path Parity Protection
>   - add new counters to stmmac_safety_stats
>   - add detailed log
> ---
>  drivers/net/ethernet/stmicro/stmmac/common.h  |  1 +
>  .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  3 +
>  .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 57 ++++++++++++++++++-
>  3 files changed, 60 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 721c1f8e892f..b4f60ab078d6 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -216,6 +216,7 @@ struct stmmac_safety_stats {
>  	unsigned long mac_errors[32];
>  	unsigned long mtl_errors[32];
>  	unsigned long dma_errors[32];
> +	unsigned long dma_dpp_errors[32];
>  };
>  
>  /* Number of fields in Safety Stats */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> index 207ff1799f2c..5c67a3f89f08 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> @@ -303,6 +303,8 @@
>  #define XGMAC_RXCEIE			BIT(4)
>  #define XGMAC_TXCEIE			BIT(0)
>  #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
> +#define XGMAC_MTL_DPP_CONTROL		0x000010e0

> +#define XGMAC_DDPP_DISABLE		BIT(0)

Is the double "D" a typo? Shouldn't this be XGMAC_DPP_DISABLE or just
XGMAC_DDPP (if the "DDPP" means "Disable DPP")?

If so, David/Jakub, is it possible to rebase the branch with the macro
fixed in the commit or a new cleanup patch is the only option?

Other than the nit above no more notes from my side:

Reviewed-by: Serge Semin <fancer.lancer at gmail.com>

-Serge(y)

>  #define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
>  #define XGMAC_TQS			GENMASK(25, 16)
>  #define XGMAC_TQS_SHIFT			16
> @@ -385,6 +387,7 @@
>  #define XGMAC_DCEIE			BIT(1)
>  #define XGMAC_TCEIE			BIT(0)
>  #define XGMAC_DMA_ECC_INT_STATUS	0x0000306c
> +#define XGMAC_DMA_DPP_INT_STATUS	0x00003074
>  #define XGMAC_DMA_CH_CONTROL(x)		(0x00003100 + (0x80 * (x)))
>  #define XGMAC_SPH			BIT(24)
>  #define XGMAC_PBLx8			BIT(16)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> index eb48211d9b0e..04d7c4dc2e35 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> @@ -830,6 +830,43 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
>  	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
>  };
>  
> +static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
> +static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
> +static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
> +	{ true, "TDPES0", dpp_tx_err },
> +	{ true, "TDPES1", dpp_tx_err },
> +	{ true, "TDPES2", dpp_tx_err },
> +	{ true, "TDPES3", dpp_tx_err },
> +	{ true, "TDPES4", dpp_tx_err },
> +	{ true, "TDPES5", dpp_tx_err },
> +	{ true, "TDPES6", dpp_tx_err },
> +	{ true, "TDPES7", dpp_tx_err },
> +	{ true, "TDPES8", dpp_tx_err },
> +	{ true, "TDPES9", dpp_tx_err },
> +	{ true, "TDPES10", dpp_tx_err },
> +	{ true, "TDPES11", dpp_tx_err },
> +	{ true, "TDPES12", dpp_tx_err },
> +	{ true, "TDPES13", dpp_tx_err },
> +	{ true, "TDPES14", dpp_tx_err },
> +	{ true, "TDPES15", dpp_tx_err },
> +	{ true, "RDPES0", dpp_rx_err },
> +	{ true, "RDPES1", dpp_rx_err },
> +	{ true, "RDPES2", dpp_rx_err },
> +	{ true, "RDPES3", dpp_rx_err },
> +	{ true, "RDPES4", dpp_rx_err },
> +	{ true, "RDPES5", dpp_rx_err },
> +	{ true, "RDPES6", dpp_rx_err },
> +	{ true, "RDPES7", dpp_rx_err },
> +	{ true, "RDPES8", dpp_rx_err },
> +	{ true, "RDPES9", dpp_rx_err },
> +	{ true, "RDPES10", dpp_rx_err },
> +	{ true, "RDPES11", dpp_rx_err },
> +	{ true, "RDPES12", dpp_rx_err },
> +	{ true, "RDPES13", dpp_rx_err },
> +	{ true, "RDPES14", dpp_rx_err },
> +	{ true, "RDPES15", dpp_rx_err },
> +};
> +
>  static void dwxgmac3_handle_dma_err(struct net_device *ndev,
>  				    void __iomem *ioaddr, bool correctable,
>  				    struct stmmac_safety_stats *stats)
> @@ -841,6 +878,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev,
>  
>  	dwxgmac3_log_error(ndev, value, correctable, "DMA",
>  			   dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats);
> +
> +	value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS);
> +	writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS);
> +
> +	dwxgmac3_log_error(ndev, value, false, "DMA_DPP",
> +			   dwxgmac3_dma_dpp_errors,
> +			   STAT_OFF(dma_dpp_errors), stats);
>  }
>  
>  static int
> @@ -881,6 +925,12 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
>  	value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */
>  	writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL);
>  
> +	/* 5. Enable Data Path Parity Protection */
> +	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
> +	/* already enabled by default, explicit enable it again */
> +	value &= ~XGMAC_DDPP_DISABLE;
> +	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
> +
>  	return 0;
>  }
>  
> @@ -914,7 +964,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev,
>  		ret |= !corr;
>  	}
>  
> -	err = dma & (XGMAC_DEUIS | XGMAC_DECIS);
> +	/* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in
> +	 * DMA_Safety_Interrupt_Status, so we handle DMA Data Path
> +	 * Parity Errors here
> +	 */
> +	err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS);
>  	corr = dma & XGMAC_DECIS;
>  	if (err) {
>  		dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats);
> @@ -930,6 +984,7 @@ static const struct dwxgmac3_error {
>  	{ dwxgmac3_mac_errors },
>  	{ dwxgmac3_mtl_errors },
>  	{ dwxgmac3_dma_errors },
> +	{ dwxgmac3_dma_dpp_errors },
>  };
>  
>  static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats,
> -- 
> 2.34.1
> 


From oliver.upton at linux.dev  Fri Feb  2 14:00:40 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 2 Feb 2024 22:00:40 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event
 state to hypervisor
In-Reply-To: <20240104162714.1062610-3-james.clark@arm.com>
References: <20240104162714.1062610-1-james.clark@arm.com>
 <20240104162714.1062610-3-james.clark@arm.com>
Message-ID: <Zb1mCCi13AJ_YjFZ@linux.dev>

On Thu, Jan 04, 2024 at 04:27:02PM +0000, James Clark wrote:

[...]

> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index c50f8459e4fc..89147a9dc38c 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -130,13 +130,18 @@ static void __hyp_vgic_restore_state(struct kvm_vcpu *vcpu)
>  	}
>  }
>  
> +static struct kvm_pmu_events *kvm_nvhe_get_pmu_events(struct kvm_vcpu *vcpu)
> +{
> +	return &kvm_host_global_state[vcpu->cpu].pmu_events;
> +}
> +
>  /*
>   * Disable host events, enable guest events
>   */
>  #ifdef CONFIG_HW_PERF_EVENTS
>  static bool __pmu_switch_to_guest(struct kvm_vcpu *vcpu)
>  {
> -	struct kvm_pmu_events *pmu = &vcpu->arch.pmu.events;
> +	struct kvm_pmu_events *pmu = kvm_nvhe_get_pmu_events(vcpu);
>  
>  	if (pmu->events_host)
>  		write_sysreg(pmu->events_host, pmcntenclr_el0);
> @@ -152,7 +157,7 @@ static bool __pmu_switch_to_guest(struct kvm_vcpu *vcpu)
>   */
>  static void __pmu_switch_to_host(struct kvm_vcpu *vcpu)
>  {
> -	struct kvm_pmu_events *pmu = &vcpu->arch.pmu.events;
> +	struct kvm_pmu_events *pmu = kvm_nvhe_get_pmu_events(vcpu);
>  
>  	if (pmu->events_guest)
>  		write_sysreg(pmu->events_guest, pmcntenclr_el0);

This now allows the host to program event counters for a protected
guest. That _might_ be a useful feature behind some debug option, but is
most definitely *not* something we want to do for pVMs generally.

Do we even need to make this shared data work at all for pKVM? The rest
of the shared data between pKVM and the kernel is system information,
which (importantly) doesn't have any guest context in it.

I'm perfectly happy leaving these sorts of features broken for pKVM and
using the 'normal' way of getting percpu data to the nVHE hypervisor
otherwise.

-- 
Thanks,
Oliver


From alexghiti at rivosinc.com  Fri Feb  2 14:05:44 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Fri, 2 Feb 2024 23:05:44 +0100
Subject: [PATCH RFC/RFT v2 4/4] riscv: Stop emitting preventive sfence.vma
 for new userspace mappings with Svvptc
In-Reply-To: <CAHVXubgw0PEZMhFmjA0cAFQ2+_JOYjVfk41qRC9TFdSJtej++w@mail.gmail.com>
References: <20240131155929.169961-1-alexghiti@rivosinc.com>
 <20240131155929.169961-5-alexghiti@rivosinc.com> <Zbuy1E7mz9Oui1Dl@andrea> <CAHVXubgw0PEZMhFmjA0cAFQ2+_JOYjVfk41qRC9TFdSJtej++w@mail.gmail.com>
Message-ID: <CAHVXubjzpTru3Tn+nmv=GwG0YWxnkeYYT1KOJW5a27H2EDAZ0Q@mail.gmail.com>

On Fri, Feb 2, 2024 at 4:42?PM Alexandre Ghiti <alexghiti at rivosinc.com> wrote:
>
> Hi Andrea,
>
> On Thu, Feb 1, 2024 at 4:03?PM Andrea Parri <parri.andrea at gmail.com> wrote:
> >
> > On Wed, Jan 31, 2024 at 04:59:29PM +0100, Alexandre Ghiti wrote:
> > > The preventive sfence.vma were emitted because new mappings must be made
> > > visible to the page table walker but Svvptc guarantees that xRET act as
> > > a fence, so no need to sfence.vma for the uarchs that implement this
> > > extension.
> >
> > AFAIU, your first submission shows that you don't need that xRET property.
> > Similarly for other archs.  What was rationale behind this Svvptc change?
>
> Actually, the ARC has just changed its mind and removed this new

The wording was incorrect here, the ARC did not state anything, the
author of Svvptc proposed an amended version of the spec that removes
this behaviour and that's under discussion.

> behaviour from the Svvptc extension, so we will take some gratuitous
> page faults (but that should be outliners), which makes riscv similar
> to x86 and arm64.
>
> >
> >
> > > This allows to drastically reduce the number of sfence.vma emitted:
> > >
> > > * Ubuntu boot to login:
> > > Before: ~630k sfence.vma
> > > After:  ~200k sfence.vma
> > >
> > > * ltp - mmapstress01
> > > Before: ~45k
> > > After:  ~6.3k
> > >
> > > * lmbench - lat_pagefault
> > > Before: ~665k
> > > After:   832 (!)
> > >
> > > * lmbench - lat_mmap
> > > Before: ~546k
> > > After:   718 (!)
> >
> > This Svvptc seems to move/add the "burden" of the synchronization to xRET:
> > Perhaps integrate the above counts w/ the perf gains in the cover letter?
>
> Yes, I'll copy that to the cover letter.
>
> Thanks for your interest!
>
> Alex
>
> >
> >   Andrea


From Frank.li at nxp.com  Fri Feb  2 14:22:07 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 2 Feb 2024 17:22:07 -0500
Subject: [PATCH v9 05/16] PCI: imx6: Using "linux,pci-domain" as slot ID
In-Reply-To: <20240202215431.GA728556@bhelgaas>
References: <20240119171122.3057511-6-Frank.Li@nxp.com>
 <20240202215431.GA728556@bhelgaas>
Message-ID: <Zb1rD4WK5D0ckKos@lizhi-Precision-Tower-5810>

On Fri, Feb 02, 2024 at 03:54:31PM -0600, Bjorn Helgaas wrote:
> On Fri, Jan 19, 2024 at 12:11:11PM -0500, Frank Li wrote:
> > Avoid use get slot id by compared with register physical address. If there
> > are more than 2 slots, compared logic will become complex.
> > 
> > "linux,pci-domain" already exist at dts since commit:
> > 	commit (c0b70f05c87f3b arm64: dts: imx8mq: use_dt_domains for pci node).
> > 
> > So it is safe to remove compare basic address code:
> > 	...
> > 	if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> > 		imx6_pcie->controller_id = 1;
> > 	...
> 
> I have no idea what this is telling me.  I guess you don't want to use
> IMX8MQ_PCIE2_BASE_ADDR to decide something?  That much sounds good:
> the *address* of some MMIO space doesn't tell us anything about the
> function of that space.

You are right. If there are more than two controller. The check logic
will be extremely complex.

There are some discussin at below thread about linux,pci-domain
https://lore.kernel.org/imx/20231206165953.GA717921 at bhelgaas/

https://lore.kernel.org/imx/20231217175158.GF6748 at thinkpad/

> 
> I expect the "compatible" string to tell the driver what the
> programming model of the device is.
> 
> > +	/* Using linux,pci-domain as PCI slot id */
> > +	imx6_pcie->controller_id = of_get_pci_domain_nr(node);
> > +	/*
> > +	 * If there are no "linux,pci-domain" property specified in DT, then assume only one
> > +	 * controller is available.
> > +	 */
> > +	if (imx6_pcie->controller_id == -EINVAL)
> > +		imx6_pcie->controller_id = 0;
> > +	else if (imx6_pcie->controller_id < 0)
> > +		return dev_err_probe(dev, imx6_pcie->controller_id,
> > +				     "linux,pci-domain have wrong value\n");
> 
> Maybe I'm missing something here.  It looks like this driver uses
> controller_id to distinguish between hardware variants or maybe
> between two Root Ports (slots?) in the same SoC?

Yes!

> 
>   imx6_pcie_grp_offset
>     return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
> 
>   imx6_pcie_configure_type
>     id = imx6_pcie->controller_id
>     if (!drvdata->mode_mask[id])         # <-- looks unsafe

I can add safe check here.

>       id = 0;
>     regmap_update_bits(drvdata->mode_off[id], ...)
> 
> (This "mode_mask[id]" looks like it will reference garbage if the DT
> supplies "linux,pci-domain = <2>".  A bogus DT shouldn't be able to
> cause a driver to misbehave like that.)

Suppose I can use dt-bind doc to force to 0,1 and safe check here.

> 
> That doesn't seem related to "linux,pci-domain" at all.

I added comments about
/* Using linux,pci-domain as PCI slot id */

We may add new property about controller-id, but there already have common
one "linux,pci-domain", which value in upstreamed dts exactly match our
expection, I also found other platform use it as slot id in kernel tree.

Any way, we can continue discuss the better solution here. But I hope
it was not block whole 16 patches. we can skip this one firstly.

I still have more than 10 clean up patches my local tree.

> 
> Bjorn


From Frank.li at nxp.com  Fri Feb  2 14:28:26 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 2 Feb 2024 17:28:26 -0500
Subject: [PATCH v2 0/4] Add 8qm SMMU information
In-Reply-To: <20240202110511.135d26b7@kernel.org>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240202110511.135d26b7@kernel.org>
Message-ID: <Zb1sijexWGLG5gcH@lizhi-Precision-Tower-5810>

On Fri, Feb 02, 2024 at 11:05:11AM -0800, Jakub Kicinski wrote:
> On Thu, 01 Feb 2024 15:22:40 -0500 Frank Li wrote:
> >       dt-bindings: mmc: fsl-imx-esdhc: add iommus property
> >       dt-bindings: net: fec: add iommus property
> >       arm64: dts: imx8qm: add smmu node
> >       arm64: dts: imx8qm: add smmu stream id information
> > 
> >  .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml     |  3 ++
> >  Documentation/devicetree/bindings/net/fsl,fec.yaml |  3 ++
> >  arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi  |  6 ++++
> >  arch/arm64/boot/dts/freescale/imx8qm.dtsi          | 41 ++++++++++++++++++++++
> 
> Any preference on whether all these go via a platform tree,
> or should we pick up the net patch to netdev? I guess taking
> the DTB via netdev would be the usual way to handle this?

Supposed dt-bindings go through netdev tree.

without dt-bindings, just DTB_CHECK warning. No strict dependence
relationship between dt-bindings doc and dts file. 

Frank


From maskray at google.com  Fri Feb  2 14:28:48 2024
From: maskray at google.com (Fangrui Song)
Date: Fri, 2 Feb 2024 14:28:48 -0800
Subject: [PATCH] arm64: jump_label: use constraint "S" instead of "i"
In-Reply-To: <Zb0NfWQAHth9GrpK@e133380.arm.com>
References: <20240201045551.ajg4iqcajyowl2rh@google.com>
 <CAMj1kXEBjumu3VUySg1cQ+SYm4MugJ5f6pd1f7C0XrLyOWAoOw@mail.gmail.com>
 <20240201091120.pbgr7ng6t2c36fut@google.com>
 <ZbuFWSRBntgm2ukJ@e133380.arm.com>
 <CAMj1kXGu76WHY8=Y-KhCxBq3xeHeCYQ9syqViSr9VRkjgWQ3BQ@mail.gmail.com>
 <ZbvVApJ2/+yca0u6@e133380.arm.com>
 <20240201205614.w3gcz6urfxtydr77@google.com>
 <CAMj1kXGAi94DuCYRPWQujGz7YVTS=53h_+FretCsYFbxznJVHw@mail.gmail.com>
 <CAFP8O3JB1miCHoGFh7UY6dCa4WS6+88mnB_qxXnvYp4wHnYgBw@mail.gmail.com>
 <Zb0NfWQAHth9GrpK@e133380.arm.com>
Message-ID: <20240202222848.udc6tisjwjtb3gso@google.com>

On 2024-02-02, Dave Martin wrote:
>On Thu, Feb 01, 2024 at 02:12:06PM -0800, Fangrui Song wrote:
>> On Thu, Feb 1, 2024 at 1:23?PM Ard Biesheuvel <ardb at kernel.org> wrote:
>> >
>> > On Thu, 1 Feb 2024 at 21:56, Fangrui Song <maskray at google.com> wrote:
>> > >
>> > > On 2024-02-01, Dave Martin wrote:
>> > > >On Thu, Feb 01, 2024 at 05:07:59PM +0100, Ard Biesheuvel wrote:
>> > > >> On Thu, 1 Feb 2024 at 12:50, Dave Martin <Dave.Martin at arm.com> wrote:
>> > > >> >
>> > > >> > On Thu, Feb 01, 2024 at 01:11:20AM -0800, Fangrui Song wrote:
>
>[...]
>
>> > > >> > Is a GCC version check needed?  Or is the minimum GCC version specified
>> > > >> > for building the kernel new enough?
>> > > >> >
>> > > >> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
>> > > >> > > +#else
>> > > >> > > +#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "S"
>> > > >> > > +#endif
>> > > >> > > +
>> > > >>
>> > > >> Can we use "Si" instead?
>> > > >
>> > > >I thought the point was to avoid "S" on compilers that would choke on
>> > > >it?  If so, those compilers would surely choke on "Si" too, no?
>> > >
>> > > "Si" is an invalid constraint. Unfortunately, GCC recognizes "S" as a
>> > > valid constraint and ignores trailing characters (asm_operand_ok). That
>> > > is, GCC would accept "Siiiii" as well...
>> > >
>> > > The GCC support for "S" is great. The initial aarch64 port in 2012 supports "S".
>
>Ah, no problem.
>
>
>> > So it is not possible to combine the S and i constraint, and let the
>> > compiler figure out whether it meets either? We rely on this elsewhere
>> > by combining r and Z into rZ. x86 uses "rm" for inline asm parameters
>> > that could be either register or memory operands.
>>
>> I did not realize that your "Si" suggestion meant this feature
>> https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
>>
>>     After the prefix, there must be one or more additional constraints
>> (see Constraints for asm Operands) that describe where the value
>> resides. Common constraints include ?r? for register and ?m? for
>> memory. When you list more than one possible location (for example,
>> "=rm"), the compiler chooses the most efficient one based on the
>> current context.
>>
>> After some debugging of both GCC and Clang, I think you are right and
>> "Si" will work. Thanks for the suggestion!
>>
>> GCC accepts "Si". Sorry for my incorrectly stating that GCC ignores
>> the trailing constraint. GCC does ignore an unknown constraint, as
>> long as one accepted constraint.
>>
>> Clang accepts "Si" as well. In the absence of
>> https://github.com/llvm/llvm-project/pull/80255 (constant offset
>> support for 'S'), in TargetLowering::ComputeConstraintToUse, 'S' is
>> skipped and 'i' will be picked. This is unrelated to the "rm" weakness
>> in Clang (https://github.com/llvm/llvm-project/issues/20571).
>>
>> I'll post a PATCH v2 removing JUMP_LABEL_STATIC_KEY_CONSTRAINT and
>> using "Si" unconditionally.
>
>If older Clang just ignores the "S" in "Si" as an unsatisfiable
>alternative and falls back on "i", that seems ideal.
>
>> > > >> > >  static __always_inline bool arch_static_branch(struct static_key * const key,
>> > > >> > >                                              const bool branch)
>> > > >> > >  {
>> > > >> > > @@ -23,9 +33,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
>> > > >> > >                "      .pushsection    __jump_table, \"aw\"    \n\t"
>> > > >> > >                "      .align          3                       \n\t"
>> > > >> > >                "      .long           1b - ., %l[l_yes] - .   \n\t"
>> > > >> > > -              "      .quad           %c0 - .                 \n\t"
>> > > >> > > +              "      .quad           %0 + %1 - .             \n\t"
>> > > >> > >                "      .popsection                             \n\t"
>> > > >> > > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
>> > > >> > > +              :  :  JUMP_LABEL_STATIC_KEY_CONSTRAINT(key), "i"(branch) :  : l_yes);
>
>[...]
>
>> > > >"S"(&((char *)key)[branch]) does indeed seem to do the right thing,
>> > > >at least with GCC.
>> > > >
>> > > >I probably didn't help by bikeshedding the way that expression was
>> > > >written, apologies for that.  It's orthogonal to what this patch is
>> > > >doing.
>> > >
>> > > Yes, "S"(&((char *)key)[branch])  would do the right thing.
>> > > I have compared assembly output. It's a matter of "s" vs "s + 0" and "s+1" vs "s + 1".
>
>[...]
>
>> > > >Is there a reason why we don't just build the whole kernel with
>> > > >-fvisibility=hidden today?
>> > >
>> > > This topic, loosely related to this patch, is about switching to PIC
>> > > compiles. I am not familiar with the Linux kernel, so I'll mostly leave
>> > > the discussion to you and Ard :)
>> > >
>> > > That said, I have done a lot of Clang work in visibility/symbol
>> > > preemptibility and linkers, so I am happy to add what I know.
>> > >
>> > > -fvisibility=hidden only applies to definitions, not non-definition
>> > > declarations.
>> > >
>> > > I've mentioned this at
>> > > https://lore.kernel.org/all/20220429070318.iwj3j5lpfkw4t7g2 at google.com/
>> > >
>> > >      `#pragma GCC visibility push(hidden)` is very similar to -fvisibility=hidden -fdirect-access-external-data with Clang.
>> > >      ...
>> > >      The kernel uses neither TLS nor -fno-plt, so -fvisibility=hidden
>> > >      -fdirect-access-external-data can replace `#pragma GCC visibility
>> > >      push(hidden)`.
>> > >
>> > > >> So building with -fPIC is currently not need in practice, and creates
>> > > >> some complications, which is why we have been avoiding it. But PIE
>> > > >> linking non-PIC objects is not guaranteed to remain supported going
>> > > >> forward, so it would be better to have a plan B, i.e., being able to
>> > > >> turn on -fpic without massive regressions due to GOT overhead, or
>> > > >> codegen problems with our asm hacks.
>> > > >
>> > > >Summarising all of this is it right that:
>> > > >
>> > > >1) ld -pie is how we get the reloc info into the kernel for KASLR
>> > > >today.
>> > > >
>> > > >2) We use gcc -fno-pic today, but this might break with ld -pie in the
>> > > >future, although it works for now.
>> > > >
>> > > >3) gcc -fno-pic and gcc -fPIC (or -fPIE) generate almost the same code,
>> > > >assuming we tweak symbol visibility and use a memory model that
>> > > >ADR+ADD/LDR can span.  So, moving to -fPIE is likely to be do-able.
>> > > >
>> > > >
>> > > >My point is that an alternative option would be to move to ld -no-pie.
>> >
>> > Why? What would that achieve?
>> >
>> > > >We would need another way to get relocs into the kernel, such as an
>> > > >intermediate step with ld --emit-relocs.  I have definitely seen this
>> > > >done before somewhere, but it would be extra work and not necessarily
>> > > >worth it, based on what you say about code gen.
>> >
>> > Relying on --emit-relocs is a terrible hack. It contains mostly
>> > relocations that we don't need at runtime, so we need to postprocess
>> > them. And linkers may not update these relocations in some cases after
>> > relaxation or other transformations (and sometimes, it is not even
>> > possible to do so, if the post-transformation situation cannot be
>> > described by a relocation).
>>
>> Agreed. I've filed
>> https://sourceware.org/bugzilla/show_bug.cgi?id=30844
>> ("ld riscv: --emit-relocs does not retain the original relocation
>> type") for a RISC-V version.
>>
>> --emit-relocs is under-specified and the linker behaviors are less tested.
>
>(Aside: This sounds like an interesting hole in the toolchain world.
>
>I guess if you want post-link-time relocatability, it sounds like all
>the focus from the compiler folks is on PIC code, and non-PIC linker
>output is not considered relocatable at all (baremetal software being an
>inconvenient truth).
>
>"Relocatable" and "PIC" are not really the same requirement, but the
>importance of the difference is arch-dependent, and I can see how we got
>here.  End aside.)

My background is about toolchains and I know very little about the
kernel.  When I saw CONFIG_RELOCATABLE the first time, I was (and am)
quite confused by term (I was thinking of relocatable linking).  I
believe CONFIG_RELOCATABLE in the kernel context does mean
position-independence.

>> > And with Fangrui's RELR optimization, the PIE relocation data is
>> > extremely dense.
>> >
>> > There is nothing to fix here, really.
>> >
>> > > >
>> > > >This may all have been discussed to death already -- I didn't mean to
>> > > >hijack this patch, so I'll stop digging here, but if I've misunderstood,
>> > > >please shout!
>> >
>> > No worries. Ramana and I spent some time 5+ years ago to document how
>> > PIC codegen for the kernel (or any freestanding executable, really)
>> > deviates from the typical PIC codegen for shared libraries and PIE
>> > executables, with the intention of adding a GCC compiler switch for
>> > it, but that never really materialized, mostly because things just
>> > work fine today.
>> >
>
>Right.  I was concerned that we would pay a significant runtime
>performance penalty when migrating to -fPIC, in which case it would be
>worth considering alernatives.  But from the discussion it sounds like
>this concern is misguided (or at least, you have found robust
>workarounds which mean that the real penalty is negligible).
>
>There's no underlying reason why a toolchain couldn't emit full static
>relocation information in a robust way, but since this info is hard to
>consume and would be used rarely and only for very specific use cases I
>can see why this support is rot-prone or even not considered a goal
>at all by many people...
>
>Cheers
>---Dave

I believe the PIC concept is built around dynamic shared library support
in 1980+, and therefore PIC and dynamic shared library are reall
tangled. Here are some notes from my archaeology
https://maskray.me/blog/2021-09-19-all-about-procedure-linkage-table#appendix

     In 1984 USENIX UniForum Conference Proceedings, Transparent
     Implementation of Shared Libraries described a library stub and link
     table scheme which is similar to .plt plus .got.plt used today.
   
     System V release 3 switched to the COFF format. In 1986 Summer USENIX
     Technical Conference & Exhibition Proceedings, Shared Libraries on
     UNIX System V from AT&T described a shared library design. Its shared
     library must have a fixed virtual address, which is called "static
     shared library" in Linkers and Loaders's term.
   
     In 1988, SunOS 4.0 was released with an extended a.out binary format
     with dynamic shared library support. Unlike previous static shared
     library schemes, the a.out shared libraries are position independent
     and can be loaded at different addresses. The GOT and PLT schemes are
     what we see today. In 1992, SunOS 5.0 (Solaris 2.0) switched to ELF.

Concepts like PLT and GOT have been ingrained in the design.  Therefore,
-fPIC compiles lead to PLT-generating and GOT-generating code by
default. Kernels, for security hardening, just need the "relocatable"
capability, not the dynamic library part, would find such code
inefficient.

The 1990+ introduction of ELF visibilities allows eliminating GOT/PLT,
if you use the hidden visibility. It is just not the toolchain defaults
and kernel folks would find themselves have to jump through hoops.

In addition, visibility-related options, if not used very carefully, can
easily shoot yourself in the foot. So there could be some tension
whether toolchain folks want to add extra options.


From eugenis at google.com  Fri Feb  2 14:30:00 2024
From: eugenis at google.com (Evgenii Stepanov)
Date: Fri, 2 Feb 2024 14:30:00 -0800
Subject: [PATCH RFC v3 22/35] arm64: mte: Enable tag storage if CMA areas
 have been activated
In-Reply-To: <20240125164256.4147-23-alexandru.elisei@arm.com>
References: <20240125164256.4147-1-alexandru.elisei@arm.com> <20240125164256.4147-23-alexandru.elisei@arm.com>
Message-ID: <CAFKCwrhNE5PR7cu7tN8qMmSEUhdJ7ensGGrB-oodh-J_fdoRcw@mail.gmail.com>

On Thu, Jan 25, 2024 at 8:44?AM Alexandru Elisei
<alexandru.elisei at arm.com> wrote:
>
> Before enabling MTE tag storage management, make sure that the CMA areas
> have been successfully activated. If a CMA area fails activation, the pages
> are kept as reserved. Reserved pages are never used by the page allocator.
>
> If this happens, the kernel would have to manage tag storage only for some
> of the memory, but not for all memory, and that would make the code
> unreasonably complicated.
>
> Choose to disable tag storage management altogether if a CMA area fails to
> be activated.
>
> Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> ---
>
> Changes since v2:
>
> * New patch.
>
>  arch/arm64/include/asm/mte_tag_storage.h | 12 ++++++
>  arch/arm64/kernel/mte_tag_storage.c      | 50 ++++++++++++++++++++++++
>  2 files changed, 62 insertions(+)
>
> diff --git a/arch/arm64/include/asm/mte_tag_storage.h b/arch/arm64/include/asm/mte_tag_storage.h
> index 3c2cd29e053e..7b3f6bff8e6f 100644
> --- a/arch/arm64/include/asm/mte_tag_storage.h
> +++ b/arch/arm64/include/asm/mte_tag_storage.h
> @@ -6,8 +6,20 @@
>  #define __ASM_MTE_TAG_STORAGE_H
>
>  #ifdef CONFIG_ARM64_MTE_TAG_STORAGE
> +
> +DECLARE_STATIC_KEY_FALSE(tag_storage_enabled_key);
> +
> +static inline bool tag_storage_enabled(void)
> +{
> +       return static_branch_likely(&tag_storage_enabled_key);
> +}
> +
>  void mte_init_tag_storage(void);
>  #else
> +static inline bool tag_storage_enabled(void)
> +{
> +       return false;
> +}
>  static inline void mte_init_tag_storage(void)
>  {
>  }
> diff --git a/arch/arm64/kernel/mte_tag_storage.c b/arch/arm64/kernel/mte_tag_storage.c
> index 9a1a8a45171e..d58c68b4a849 100644
> --- a/arch/arm64/kernel/mte_tag_storage.c
> +++ b/arch/arm64/kernel/mte_tag_storage.c
> @@ -19,6 +19,8 @@
>
>  #include <asm/mte_tag_storage.h>
>
> +__ro_after_init DEFINE_STATIC_KEY_FALSE(tag_storage_enabled_key);
> +
>  struct tag_region {
>         struct range mem_range; /* Memory associated with the tag storage, in PFNs. */
>         struct range tag_range; /* Tag storage memory, in PFNs. */
> @@ -314,3 +316,51 @@ void __init mte_init_tag_storage(void)
>         num_tag_regions = 0;
>         pr_info("MTE tag storage region management disabled");
>  }
> +
> +static int __init mte_enable_tag_storage(void)
> +{
> +       struct range *tag_range;
> +       struct cma *cma;
> +       int i, ret;
> +
> +       if (num_tag_regions == 0)
> +               return 0;
> +
> +       for (i = 0; i < num_tag_regions; i++) {
> +               tag_range = &tag_regions[i].tag_range;
> +               cma = tag_regions[i].cma;
> +               /*
> +                * CMA will keep the pages as reserved when the region fails
> +                * activation.
> +                */
> +               if (PageReserved(pfn_to_page(tag_range->start)))
> +                       goto out_disabled;
> +       }
> +
> +       static_branch_enable(&tag_storage_enabled_key);
> +       pr_info("MTE tag storage region management enabled");
> +
> +       return 0;
> +
> +out_disabled:
> +       for (i = 0; i < num_tag_regions; i++) {
> +               tag_range = &tag_regions[i].tag_range;
> +               cma = tag_regions[i].cma;
> +
> +               if (PageReserved(pfn_to_page(tag_range->start)))
> +                       continue;
> +
> +               /* Try really hard to reserve the tag storage. */
> +               ret = cma_alloc(cma, range_len(tag_range), 8, true);
> +               /*
> +                * Tag storage is still in use for data, memory and/or tag
> +                * corruption will ensue.
> +                */
> +               WARN_ON_ONCE(ret);

cma_alloc returns (page *), so this condition needs to be inverted,
and the type of `ret` changed.
Not sure how it slipped through, this is a compile error with clang.

> +       }
> +       num_tag_regions = 0;
> +       pr_info("MTE tag storage region management disabled");
> +
> +       return -EINVAL;
> +}
> +arch_initcall(mte_enable_tag_storage);
> --
> 2.43.0
>


From maskray at google.com  Fri Feb  2 14:51:04 2024
From: maskray at google.com (Fangrui Song)
Date: Fri, 2 Feb 2024 14:51:04 -0800
Subject: [PATCH] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <Zb0eRogn3rjkeDAs@e133380.arm.com>
References: <20240201223545.728028-1-maskray@google.com>
 <Zb0Qu5lR0iZUqImb@e133380.arm.com>
 <CAMj1kXGSQ4Xq68Cmq6BH37FPJ+R+N5cOfrdC+aVML4sGaNDopg@mail.gmail.com>
 <Zb0eRogn3rjkeDAs@e133380.arm.com>
Message-ID: <20240202225104.f4dsagfwf6gcnddy@google.com>

On 2024-02-02, Dave Martin wrote:
>On Fri, Feb 02, 2024 at 05:32:33PM +0100, Ard Biesheuvel wrote:
>> On Fri, 2 Feb 2024 at 16:56, Dave Martin <Dave.Martin at arm.com> wrote:
>> >
>> > On Thu, Feb 01, 2024 at 02:35:45PM -0800, Fangrui Song wrote:
>> > > The generic constraint "i" seems to be copied from x86 or arm (and with
>> > > a redundant generic operand modifier "c"). It works with -fno-PIE but
>> > > not with -fPIE/-fPIC in GCC's aarch64 port.
>> > >
>> > > The machine constraint "S", which denotes a symbol or label reference
>> > > with a constant offset, supports PIC and has been available in GCC since
>> > > 2012 and in Clang since 7.0. However, Clang before 19 does not support
>> > > "S" on a symbol with a constant offset [1] (e.g.
>> > > `static_key_false(&nf_hooks_needed[pf][hook])` in
>> > > include/linux/netfilter.h), so we use "i" as a fallback.
>> > >
>> > > Suggested-by: Ard Biesheuvel <ardb at kernel.org>
>> > > Signed-off-by: Fangrui Song <maskray at google.com>
>> > > Link: https://github.com/llvm/llvm-project/pull/80255 [1]
>> > >
>> > > ---
>> > > Changes from
>> > > arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
>> > >
>> > > * Use "Si" as Ard suggested to support Clang<19
>> > > * Make branch a separate operand
>> > > ---
>> > >  arch/arm64/include/asm/jump_label.h | 12 ++++++++----
>> > >  1 file changed, 8 insertions(+), 4 deletions(-)
>> > >
>> > > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
>> > > index 48ddc0f45d22..1f7d529be608 100644
>> > > --- a/arch/arm64/include/asm/jump_label.h
>> > > +++ b/arch/arm64/include/asm/jump_label.h
>> > > @@ -15,6 +15,10 @@
>> > >
>> > >  #define JUMP_LABEL_NOP_SIZE          AARCH64_INSN_SIZE
>> > >
>> > > +/*
>> > > + * Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
>> > > + * support "S" on a symbol with a constant offset, so we use "i" as a fallback.
>> > > + */
>> > >  static __always_inline bool arch_static_branch(struct static_key * const key,
>> > >                                              const bool branch)
>> > >  {
>> > > @@ -23,9 +27,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
>> > >                "      .pushsection    __jump_table, \"aw\"    \n\t"
>> > >                "      .align          3                       \n\t"
>> > >                "      .long           1b - ., %l[l_yes] - .   \n\t"
>> > > -              "      .quad           %c0 - .                 \n\t"
>> > > +              "      .quad           %0 + %1 - .             \n\t"
>> > >                "      .popsection                             \n\t"
>> > > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
>> > > +              :  :  "Si"(key), "i"(branch) :  : l_yes);
>> >
>> > Is the meaning of multi-alternatives well defined if different arguments
>> > specify different numbers of alternatives?  The GCC documentation says:
>> >
>> > https://gcc.gnu.org/onlinedocs/gcc/Multi-Alternative.html:
>> >
>> > -8<-
>> >
>> > [...] All operands for a single instruction must have the same number of
>> > alternatives.
>> >
>> > ->8-
>> >
>>
>> AIUI that does not apply here. That reasons about multiple arguments
>> having more than one constraint, where not all combinations of those
>> constraints are supported by the instruction.
>
>Ah, scratch that: I'm confusing multi-alternatives with simple
>constraints: all arguments must have the same number of comma-separated
>lists of constraint letters, but each list can contain as many or as few
>letters as are needed to match the operand.
>
>So "Si"(), "i"() is fine.

"Si" is fine for GCC and Clang.
"i" is fine for Clang but not for GCC PIC.

     https://maskray.me/blog/2024-01-30-raw-symbol-names-in-inline-assembly#aarch64

     In gcc/config/aarch64, LEGITIMATE_PIC_OPERAND_P(X) disallows any symbol
     reference, which means that "i" and "s" cannot be used for PIC. Instead,
     the constraint "S" has been supported since the initial port (2012) to
     reference a symbol or label.

I am also not familiar with
https://gcc.gnu.org/onlinedocs/gcc/Multi-Alternative.html (comma in a
constraint string). Thankfully we don't need this powerful construct:)

>> > Also, I still think it may be redundant to move the addition inside the
>> > asm, so long as Clang is happy with the symbol having an offset.
>> >
>>
>> Older Clang is not happy with the symbol having an offset.
>>
>> And given that the key pointer and the 'branch' boolean are two
>> distinct inputs to this function, I struggle to understand why you
>> feel it is better to combine them in the argument. 'branch' is used to
>> decide whether or not to set bit 0, independently of the value of key.
>> Using array indexing to combine those values together to avoid an
>> addition in the asm obfuscates the code.
>
>This was more about not making changes that don't need to be made,
>unless it clearly makes the code better.
>
>But if some verions of Clang accept "S" but choke if there's an offset,
>then moving the addition into the asm seems the way to go.
>
>(I may have misread the commit message on this point.)
>
>[...]
>
>Cheers
>---Dave

I am convinced by Ard' argument that two inputs (key, branch) deserve
two operands.
The existing "i"(&((char *)key)[branch]) is kinda ugly and also longer:)


From helgaas at kernel.org  Fri Feb  2 14:51:16 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 2 Feb 2024 16:51:16 -0600
Subject: [PATCH v9 05/16] PCI: imx6: Using "linux,pci-domain" as slot ID
In-Reply-To: <Zb1rD4WK5D0ckKos@lizhi-Precision-Tower-5810>
Message-ID: <20240202225116.GA732628@bhelgaas>

[Rob to to: line]

On Fri, Feb 02, 2024 at 05:22:07PM -0500, Frank Li wrote:
> On Fri, Feb 02, 2024 at 03:54:31PM -0600, Bjorn Helgaas wrote:
> > On Fri, Jan 19, 2024 at 12:11:11PM -0500, Frank Li wrote:
> > > Avoid use get slot id by compared with register physical address. If there
> > > are more than 2 slots, compared logic will become complex.
> > > 
> > > "linux,pci-domain" already exist at dts since commit:
> > > 	commit (c0b70f05c87f3b arm64: dts: imx8mq: use_dt_domains for pci node).
> > > 
> > > So it is safe to remove compare basic address code:
> > > 	...
> > > 	if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> > > 		imx6_pcie->controller_id = 1;
> > > 	...
> > 
> > I have no idea what this is telling me.  I guess you don't want to use
> > IMX8MQ_PCIE2_BASE_ADDR to decide something?  That much sounds good:
> > the *address* of some MMIO space doesn't tell us anything about the
> > function of that space.
> 
> You are right. If there are more than two controller. The check logic
> will be extremely complex.
> 
> There are some discussin at below thread about linux,pci-domain
> https://lore.kernel.org/imx/20231206165953.GA717921 at bhelgaas/

My response here was too low level, just about trivial syntactic and
style issues.  I should have seen the larger issue at the time; sorry
about that.

> https://lore.kernel.org/imx/20231217175158.GF6748 at thinkpad/

That's a good response from Mani, but again not relevant to my point.

My point here is that "compatible" should tell the driver how to
operate the device, i.e., the driver knows what registers are present
and how they work.

If you have two variant devices that both implement a register that
can be used to distinguish them, a single "compatible" string might be
enough because the driver can use that register to tell the
difference.

If the driver can't tell the difference by looking at the hardware
itself, I think you need a separate "compatible" string for it.  Of
course I'm far from a DT expert, so please correct this if necessary,
Rob, et al.

> > I expect the "compatible" string to tell the driver what the
> > programming model of the device is.
> > 
> > > +	/* Using linux,pci-domain as PCI slot id */
> > > +	imx6_pcie->controller_id = of_get_pci_domain_nr(node);
> > > +	/*
> > > +	 * If there are no "linux,pci-domain" property specified in DT, then assume only one
> > > +	 * controller is available.
> > > +	 */
> > > +	if (imx6_pcie->controller_id == -EINVAL)
> > > +		imx6_pcie->controller_id = 0;
> > > +	else if (imx6_pcie->controller_id < 0)
> > > +		return dev_err_probe(dev, imx6_pcie->controller_id,
> > > +				     "linux,pci-domain have wrong value\n");
> > 
> > Maybe I'm missing something here.  It looks like this driver uses
> > controller_id to distinguish between hardware variants or maybe
> > between two Root Ports (slots?) in the same SoC?
> 
> Yes!
> 
> >   imx6_pcie_grp_offset
> >     return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
> > 
> >   imx6_pcie_configure_type
> >     id = imx6_pcie->controller_id
> >     if (!drvdata->mode_mask[id])         # <-- looks unsafe
> 
> I can add safe check here.
> 
> >       id = 0;
> >     regmap_update_bits(drvdata->mode_off[id], ...)
> > 
> > (This "mode_mask[id]" looks like it will reference garbage if the DT
> > supplies "linux,pci-domain = <2>".  A bogus DT shouldn't be able to
> > cause a driver to misbehave like that.)
> 
> Suppose I can use dt-bind doc to force to 0,1 and safe check here.

Nope.  The driver must protect itself from garbage in the DT.

> > That doesn't seem related to "linux,pci-domain" at all.
> 
> I added comments about
> /* Using linux,pci-domain as PCI slot id */

That doesn't make it related :)

> We may add new property about controller-id, but there already have common
> one "linux,pci-domain", which value in upstreamed dts exactly match our
> expection, I also found other platform use it as slot id in kernel tree.
> 
> Any way, we can continue discuss the better solution here. But I hope
> it was not block whole 16 patches. we can skip this one firstly.
> 
> I still have more than 10 clean up patches my local tree.
> 
> > 
> > Bjorn


From chantr4 at gmail.com  Fri Feb  2 15:09:05 2024
From: chantr4 at gmail.com (Manu Bretelle)
Date: Fri, 2 Feb 2024 15:09:05 -0800
Subject: [PATCH bpf-next v4 0/3] Annotate kfuncs in .BTF_ids section
In-Reply-To: <cover.1706491398.git.dxu@dxuuu.xyz>
References: <cover.1706491398.git.dxu@dxuuu.xyz>
Message-ID: <Zb12EZt0BAKOPBk/@surya>

On Sun, Jan 28, 2024 at 06:24:05PM -0700, Daniel Xu wrote:
> === Description ===
> 
> This is a bpf-treewide change that annotates all kfuncs as such inside
> .BTF_ids. This annotation eventually allows us to automatically generate
> kfunc prototypes from bpftool.
> 
> We store this metadata inside a yet-unused flags field inside struct
> btf_id_set8 (thanks Kumar!). pahole will be taught where to look.
> 
> More details about the full chain of events are available in commit 3's
> description.
> 
> The accompanying pahole and bpftool changes can be viewed
> here on these "frozen" branches [0][1].
> 
> [0]: https://github.com/danobi/pahole/tree/kfunc_btf-v3-mailed
> [1]: https://github.com/danobi/linux/tree/kfunc_bpftool-mailed


I hit a similar issue to [0] on master
943b043aeecc ("selftests/bpf: Fix bench runner SIGSEGV")
 when cross-compiling on x86_64 (LE) to s390x (BE).
I do have CONFIG_DEBUG_INFO_BTF enable and the issue would not trigger if
I disabled CONFIG_DEBUG_INFO_BTF (and with the fix mentioned in [0]).

What seems to happen is that `tools/resolve_btfids` is ran in the context of the
host endianess and if I printk before the WARN_ON:
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index ef380e546952..a9ed7a1a4936 100644
  --- a/kernel/bpf/btf.c
  +++ b/kernel/bpf/btf.c
  @@ -8128,6 +8128,7 @@ int register_btf_kfunc_id_set(enum bpf_prog_type prog_type,
           * WARN() for initcall registrations that do not check errors.
           */
          if (!(kset->set->flags & BTF_SET8_KFUNCS)) {
  +        printk("Flag 0x%08X, expected 0x%08X\n", kset->set->flags, BTF_SET8_KFUNCS);
                  WARN_ON(!kset->owner);
                  return -EINVAL;
          }

the boot logs would show:
  Flag 0x01000000, expected 0x00000001

The issue did not happen prior to
6f3189f38a3e ("bpf: treewide: Annotate BPF kfuncs in BTF")
has only 0 was written before.

It seems [1] will be addressing cross-compilation, but it did not fix it as is
by just applying on top of master, so probably some of the changes will also need
to be ported to `tools/include/linux/btf_ids.h`?

A hacky workaround to cross-compilation I have is to apply:

  diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile
  index 4b8079f294f6..b706e7ab066f 100644
  --- a/tools/bpf/resolve_btfids/Makefile
  +++ b/tools/bpf/resolve_btfids/Makefile
  @@ -22,10 +22,10 @@ HOST_OVERRIDES := AR="$(HOSTAR)" CC="$(HOSTCC)" LD="$(HOSTLD)" ARCH="$(HOSTARCH)
                    CROSS_COMPILE="" EXTRA_CFLAGS="$(HOSTCFLAGS)"
   RM      ?= rm
  -HOSTCC  ?= gcc
  -HOSTLD  ?= ld
  -HOSTAR  ?= ar
  -CROSS_COMPILE =
  +HOSTCC  = $(CC)
  +HOSTLD  = $(LD)
  +HOSTAR  = $(AR)
  +#CROSS_COMPILE =
   OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/
  @@ -56,16 +56,16 @@ $(OUTPUT) $(OUTPUT)/libsubcmd $(LIBBPF_OUT):
   $(SUBCMDOBJ): fixdep FORCE | $(OUTPUT)/libsubcmd
          $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(SUBCMD_OUT) \
  -                   DESTDIR=$(SUBCMD_DESTDIR) $(HOST_OVERRIDES) prefix= subdir= \
  +                   DESTDIR=$(SUBCMD_DESTDIR) prefix= subdir= \
                      $(abspath $@) install_headers
   $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OUT)
          $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) OUTPUT=$(LIBBPF_OUT)    \
  -                   DESTDIR=$(LIBBPF_DESTDIR) $(HOST_OVERRIDES) prefix= subdir= \
  +                   DESTDIR=$(LIBBPF_DESTDIR) prefix= subdir= \
                      $(abspath $@) install_headers
  -LIBELF_FLAGS := $(shell $(HOSTPKG_CONFIG) libelf --cflags 2>/dev/null)
  -LIBELF_LIBS  := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf)
  +LIBELF_FLAGS := $(shell $(PKG_CONFIG) libelf --cflags 2>/dev/null)
  +LIBELF_LIBS  := $(shell $(PKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf)
   HOSTCFLAGS_resolve_btfids += -g \
             -I$(srctree)/tools/include \
  @@ -84,7 +84,7 @@ $(BINARY_IN): fixdep FORCE prepare | $(OUTPUT)
   $(BINARY): $(BPFOBJ) $(SUBCMDOBJ) $(BINARY_IN)
          $(call msg,LINK,$@)
  -       $(Q)$(HOSTCC) $(BINARY_IN) $(KBUILD_HOSTLDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS)
  +       $(Q)$(CC) $(BINARY_IN) $(KBUILD_HOSTLDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS)
   clean_objects := $(wildcard $(OUTPUT)/*.o                \
                               $(OUTPUT)/.*.o.cmd           \
  diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
  index a38a3001527c..5cd193c04448 100644
  --- a/tools/testing/selftests/bpf/Makefile
  +++ b/tools/testing/selftests/bpf/Makefile
  @@ -171,7 +171,7 @@ INCLUDE_DIR := $(SCRATCH_DIR)/include
   BPFOBJ := $(BUILD_DIR)/libbpf/libbpf.a
   ifneq ($(CROSS_COMPILE),)
   HOST_BUILD_DIR         := $(BUILD_DIR)/host
  -HOST_SCRATCH_DIR       := $(OUTPUT)/host-tools
  +HOST_SCRATCH_DIR       := $(SCRATCH_DIR)
   HOST_INCLUDE_DIR       := $(HOST_SCRATCH_DIR)/include
   else
   HOST_BUILD_DIR         := $(BUILD_DIR)

This causes `resolve_btfids` to be compiled in the target endianess and gets
magically run provided that the hosts has `qemu-s390x-static` and a functional
binfmt_misc [2] on the host, but having this using host architecture per [1]
is likely better.

Here are steps to reproduce the issue on Ubuntu 23.10 and assuming
danobi/vmtest [3] is installed:

  XPLATFORM="s390x"
  XARCH="s390"
  # Set up repo for s390x
  cat <<EOF >> /etc/apt/sources.list.d/s390x.list
  deb [arch=s390x] http://ports.ubuntu.com/ubuntu-ports  mantic main restricted
  deb [arch=s390x] http://ports.ubuntu.com/ubuntu-ports  mantic-updates main restricted
  EOF
  sudo dpkg --add-architecture s390x
  
  apt install qemu-system-s390x qemu-user-static g{cc,++}-"${XARCH}-linux-gnu" {libelf-dev,libssl-dev,pkgconf}:s390x
  
  KBUILD_OUTPUT_DIR="/tmp/kbuild-${XPLATFORM}"
  mkdir "${KBUILD_OUTPUT_DIR}"
  cat tools/testing/selftests/bpf/config{,.vm,.${XPLATFORM}} > ${KBUILD_OUTPUT_DIR}/.config
  
  make ARCH="${XARCH}" CROSS_COMPILE="${XPLATFORM}-linux-gnu-" O="${KBUILD_OUTPUT_DIR}"  -j$((4 * $(nproc))) olddefconfig
  make ARCH="${XARCH}" CROSS_COMPILE="${XPLATFORM}-linux-gnu-" O="${KBUILD_OUTPUT_DIR}"  -j$((4 * $(nproc))) all
  
  # No need for a s390x ubuntu 23.10 rootfs, we only care about booting the kernel
  vmtest -k "${KBUILD_OUTPUT_DIR}/arch/s390/boot/bzImage" -a s390x "uname -m" | cat


For the chroot route, see [4].

[0] https://lore.kernel.org/linux-kernel/20240201155339.2b5936be at canb.auug.org.au/T/
[1] https://lore.kernel.org/bpf/cover.1706717857.git.vmalik at redhat.com/
[2] https://en.wikipedia.org/wiki/Binfmt_misc
[3] https://github.com/danobi/vmtest
[4] https://chantra.github.io/bpfcitools/bpf-cross-compile.html

Manu

> 
> === Changelog ===
> 
> Changes from v3:
> * Rebase to bpf-next and add missing annotation on new kfunc
> 
> Changes from v2:
> * Only WARN() for vmlinux kfuncs
> 
> Changes from v1:
> * Move WARN_ON() up a call level
> * Also return error when kfunc set is not properly tagged
> * Use BTF_KFUNCS_START/END instead of flags
> * Rename BTF_SET8_KFUNC to BTF_SET8_KFUNCS
> 
> Daniel Xu (3):
>   bpf: btf: Support flags for BTF_SET8 sets
>   bpf: btf: Add BTF_KFUNCS_START/END macro pair
>   bpf: treewide: Annotate BPF kfuncs in BTF
> 
>  Documentation/bpf/kfuncs.rst                  |  8 +++----
>  drivers/hid/bpf/hid_bpf_dispatch.c            |  8 +++----
>  fs/verity/measure.c                           |  4 ++--
>  include/linux/btf_ids.h                       | 21 +++++++++++++++----
>  kernel/bpf/btf.c                              |  8 +++++++
>  kernel/bpf/cpumask.c                          |  4 ++--
>  kernel/bpf/helpers.c                          |  8 +++----
>  kernel/bpf/map_iter.c                         |  4 ++--
>  kernel/cgroup/rstat.c                         |  4 ++--
>  kernel/trace/bpf_trace.c                      |  8 +++----
>  net/bpf/test_run.c                            |  8 +++----
>  net/core/filter.c                             | 20 +++++++++---------
>  net/core/xdp.c                                |  4 ++--
>  net/ipv4/bpf_tcp_ca.c                         |  4 ++--
>  net/ipv4/fou_bpf.c                            |  4 ++--
>  net/ipv4/tcp_bbr.c                            |  4 ++--
>  net/ipv4/tcp_cubic.c                          |  4 ++--
>  net/ipv4/tcp_dctcp.c                          |  4 ++--
>  net/netfilter/nf_conntrack_bpf.c              |  4 ++--
>  net/netfilter/nf_nat_bpf.c                    |  4 ++--
>  net/xfrm/xfrm_interface_bpf.c                 |  4 ++--
>  net/xfrm/xfrm_state_bpf.c                     |  4 ++--
>  .../selftests/bpf/bpf_testmod/bpf_testmod.c   |  8 +++----
>  23 files changed, 87 insertions(+), 66 deletions(-)
> 
> -- 
> 2.42.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From irogers at google.com  Fri Feb  2 15:40:49 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  2 Feb 2024 15:40:49 -0800
Subject: [PATCH v3 0/8] Clean up libperf cpumap's empty function
Message-ID: <20240202234057.2085863-1-irogers@google.com>

Rename and clean up the use of libperf CPU map functions particularly
focussing on perf_cpu_map__empty that may return true for maps
containing CPUs but also with an "any CPU"/dummy value.

perf_cpu_map__nr is also troubling in that iterating an empty CPU map
will yield the "any CPU"/dummy value. Reduce the appearance of some
calls to this by using the perf_cpu_map__for_each_cpu macro.

v3: Address handling of "any" is arm-spe/cs-etm patch.
v2: 6 patches were merged by Arnaldo. New patch added ensure empty
    maps are allocated as NULL (suggested by James Clark). Hopefully a
    fix to "perf arm-spe/cs-etm: Directly iterate CPU maps".

Ian Rogers (8):
  libperf cpumap: Add any, empty and min helpers
  libperf cpumap: Ensure empty cpumap is NULL from alloc
  perf arm-spe/cs-etm: Directly iterate CPU maps
  perf intel-pt/intel-bts: Switch perf_cpu_map__has_any_cpu_or_is_empty
    use
  perf cpumap: Clean up use of perf_cpu_map__has_any_cpu_or_is_empty
  perf arm64 header: Remove unnecessary CPU map get and put
  perf stat: Remove duplicate cpus_map_matched function
  perf cpumap: Use perf_cpu_map__for_each_cpu when possible

 tools/lib/perf/cpumap.c                       |  33 ++++-
 tools/lib/perf/include/perf/cpumap.h          |  16 +++
 tools/lib/perf/libperf.map                    |   4 +
 tools/perf/arch/arm/util/cs-etm.c             | 114 ++++++++----------
 tools/perf/arch/arm64/util/arm-spe.c          |   4 +-
 tools/perf/arch/arm64/util/header.c           |  13 +-
 tools/perf/arch/x86/util/intel-bts.c          |   4 +-
 tools/perf/arch/x86/util/intel-pt.c           |  10 +-
 tools/perf/builtin-c2c.c                      |   6 +-
 tools/perf/builtin-stat.c                     |  31 +----
 tools/perf/tests/bitmap.c                     |  13 +-
 tools/perf/tests/topology.c                   |  46 +++----
 tools/perf/util/auxtrace.c                    |   4 +-
 tools/perf/util/bpf_kwork.c                   |  16 +--
 tools/perf/util/bpf_kwork_top.c               |  12 +-
 tools/perf/util/cpumap.c                      |  12 +-
 tools/perf/util/record.c                      |   2 +-
 .../scripting-engines/trace-event-python.c    |  12 +-
 tools/perf/util/session.c                     |   5 +-
 tools/perf/util/stat.c                        |   2 +-
 tools/perf/util/svghelper.c                   |  20 ++-
 21 files changed, 192 insertions(+), 187 deletions(-)

-- 
2.43.0.594.gd9cf4e227d-goog



From irogers at google.com  Fri Feb  2 15:40:50 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  2 Feb 2024 15:40:50 -0800
Subject: [PATCH v3 1/8] libperf cpumap: Add any, empty and min helpers
In-Reply-To: <20240202234057.2085863-1-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com>
Message-ID: <20240202234057.2085863-2-irogers@google.com>

Additional helpers to better replace
perf_cpu_map__has_any_cpu_or_is_empty.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/lib/perf/cpumap.c              | 27 +++++++++++++++++++++++++++
 tools/lib/perf/include/perf/cpumap.h | 16 ++++++++++++++++
 tools/lib/perf/libperf.map           |  4 ++++
 3 files changed, 47 insertions(+)

diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c
index 4adcd7920d03..ba49552952c5 100644
--- a/tools/lib/perf/cpumap.c
+++ b/tools/lib/perf/cpumap.c
@@ -316,6 +316,19 @@ bool perf_cpu_map__has_any_cpu_or_is_empty(const struct perf_cpu_map *map)
 	return map ? __perf_cpu_map__cpu(map, 0).cpu == -1 : true;
 }
 
+bool perf_cpu_map__is_any_cpu_or_is_empty(const struct perf_cpu_map *map)
+{
+	if (!map)
+		return true;
+
+	return __perf_cpu_map__nr(map) == 1 && __perf_cpu_map__cpu(map, 0).cpu == -1;
+}
+
+bool perf_cpu_map__is_empty(const struct perf_cpu_map *map)
+{
+	return map == NULL;
+}
+
 int perf_cpu_map__idx(const struct perf_cpu_map *cpus, struct perf_cpu cpu)
 {
 	int low, high;
@@ -372,6 +385,20 @@ bool perf_cpu_map__has_any_cpu(const struct perf_cpu_map *map)
 	return map && __perf_cpu_map__cpu(map, 0).cpu == -1;
 }
 
+struct perf_cpu perf_cpu_map__min(const struct perf_cpu_map *map)
+{
+	struct perf_cpu cpu, result = {
+		.cpu = -1
+	};
+	int idx;
+
+	perf_cpu_map__for_each_cpu_skip_any(cpu, idx, map) {
+		result = cpu;
+		break;
+	}
+	return result;
+}
+
 struct perf_cpu perf_cpu_map__max(const struct perf_cpu_map *map)
 {
 	struct perf_cpu result = {
diff --git a/tools/lib/perf/include/perf/cpumap.h b/tools/lib/perf/include/perf/cpumap.h
index 228c6c629b0c..90457d17fb2f 100644
--- a/tools/lib/perf/include/perf/cpumap.h
+++ b/tools/lib/perf/include/perf/cpumap.h
@@ -61,6 +61,22 @@ LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus);
  * perf_cpu_map__has_any_cpu_or_is_empty - is map either empty or has the "any CPU"/dummy value.
  */
 LIBPERF_API bool perf_cpu_map__has_any_cpu_or_is_empty(const struct perf_cpu_map *map);
+/**
+ * perf_cpu_map__is_any_cpu_or_is_empty - is map either empty or the "any CPU"/dummy value.
+ */
+LIBPERF_API bool perf_cpu_map__is_any_cpu_or_is_empty(const struct perf_cpu_map *map);
+/**
+ * perf_cpu_map__is_empty - does the map contain no values and it doesn't
+ *                          contain the special "any CPU"/dummy value.
+ */
+LIBPERF_API bool perf_cpu_map__is_empty(const struct perf_cpu_map *map);
+/**
+ * perf_cpu_map__min - the minimum CPU value or -1 if empty or just the "any CPU"/dummy value.
+ */
+LIBPERF_API struct perf_cpu perf_cpu_map__min(const struct perf_cpu_map *map);
+/**
+ * perf_cpu_map__max - the maximum CPU value or -1 if empty or just the "any CPU"/dummy value.
+ */
 LIBPERF_API struct perf_cpu perf_cpu_map__max(const struct perf_cpu_map *map);
 LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
 LIBPERF_API bool perf_cpu_map__equal(const struct perf_cpu_map *lhs,
diff --git a/tools/lib/perf/libperf.map b/tools/lib/perf/libperf.map
index 10b3f3722642..2aa79b696032 100644
--- a/tools/lib/perf/libperf.map
+++ b/tools/lib/perf/libperf.map
@@ -10,6 +10,10 @@ LIBPERF_0.0.1 {
 		perf_cpu_map__nr;
 		perf_cpu_map__cpu;
 		perf_cpu_map__has_any_cpu_or_is_empty;
+		perf_cpu_map__is_any_cpu_or_is_empty;
+		perf_cpu_map__is_empty;
+		perf_cpu_map__has_any_cpu;
+		perf_cpu_map__min;
 		perf_cpu_map__max;
 		perf_cpu_map__has;
 		perf_thread_map__new_array;
-- 
2.43.0.594.gd9cf4e227d-goog



From irogers at google.com  Fri Feb  2 15:40:51 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  2 Feb 2024 15:40:51 -0800
Subject: [PATCH v3 2/8] libperf cpumap: Ensure empty cpumap is NULL from alloc
In-Reply-To: <20240202234057.2085863-1-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com>
Message-ID: <20240202234057.2085863-3-irogers@google.com>

Potential corner cases could cause a cpumap to be allocated with size
0, but an empty cpumap should be represented as NULL. Add a path in
perf_cpu_map__alloc to ensure this.

Suggested-by: James Clark <james.clark at arm.com>
Closes: https://lore.kernel.org/lkml/2cd09e7c-eb88-6726-6169-647dcd0a8101 at arm.com/
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/lib/perf/cpumap.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c
index ba49552952c5..cae799ad44e1 100644
--- a/tools/lib/perf/cpumap.c
+++ b/tools/lib/perf/cpumap.c
@@ -18,9 +18,13 @@ void perf_cpu_map__set_nr(struct perf_cpu_map *map, int nr_cpus)
 
 struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus)
 {
-	RC_STRUCT(perf_cpu_map) *cpus = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
+	RC_STRUCT(perf_cpu_map) *cpus;
 	struct perf_cpu_map *result;
 
+	if (nr_cpus == 0)
+		return NULL;
+
+	cpus = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
 	if (ADD_RC_CHK(result, cpus)) {
 		cpus->nr = nr_cpus;
 		refcount_set(&cpus->refcnt, 1);
-- 
2.43.0.594.gd9cf4e227d-goog



From irogers at google.com  Fri Feb  2 15:40:52 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  2 Feb 2024 15:40:52 -0800
Subject: [PATCH v3 3/8] perf arm-spe/cs-etm: Directly iterate CPU maps
In-Reply-To: <20240202234057.2085863-1-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com>
Message-ID: <20240202234057.2085863-4-irogers@google.com>

Rather than iterate all CPUs and see if they are in CPU maps, directly
iterate the CPU map. Similarly make use of the intersect function
taking care for when "any" CPU is specified. Switch
perf_cpu_map__has_any_cpu_or_is_empty to more appropriate
alternatives.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm/util/cs-etm.c    | 114 ++++++++++++---------------
 tools/perf/arch/arm64/util/arm-spe.c |   4 +-
 2 files changed, 51 insertions(+), 67 deletions(-)

diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index 77e6663c1703..07be32d99805 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -197,38 +197,37 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr,
 static int cs_etm_validate_config(struct auxtrace_record *itr,
 				  struct evsel *evsel)
 {
-	int i, err = -EINVAL;
+	int idx, err = 0;
 	struct perf_cpu_map *event_cpus = evsel->evlist->core.user_requested_cpus;
-	struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
-
-	/* Set option of each CPU we have */
-	for (i = 0; i < cpu__max_cpu().cpu; i++) {
-		struct perf_cpu cpu = { .cpu = i, };
+	struct perf_cpu_map *intersect_cpus;
+	struct perf_cpu cpu;
 
-		/*
-		 * In per-cpu case, do the validation for CPUs to work with.
-		 * In per-thread case, the CPU map is empty.  Since the traced
-		 * program can run on any CPUs in this case, thus don't skip
-		 * validation.
-		 */
-		if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus) &&
-		    !perf_cpu_map__has(event_cpus, cpu))
-			continue;
+	/*
+	 * Set option of each CPU we have. In per-cpu case, do the validation
+	 * for CPUs to work with. In per-thread case, the CPU map has the "any"
+	 * CPU value. Since the traced program can run on any CPUs in this case,
+	 * thus don't skip validation.
+	 */
+	if (!perf_cpu_map__has_any_cpu(event_cpus)) {
+		struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
 
-		if (!perf_cpu_map__has(online_cpus, cpu))
-			continue;
+		intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
+		perf_cpu_map__put(online_cpus);
+	} else {
+		intersect_cpus = perf_cpu_map__new_online_cpus();
+	}
 
-		err = cs_etm_validate_context_id(itr, evsel, i);
+	perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
+		err = cs_etm_validate_context_id(itr, evsel, cpu.cpu);
 		if (err)
-			goto out;
-		err = cs_etm_validate_timestamp(itr, evsel, i);
+			break;
+
+		err = cs_etm_validate_timestamp(itr, evsel, cpu.cpu);
 		if (err)
-			goto out;
+			break;
 	}
 
-	err = 0;
-out:
-	perf_cpu_map__put(online_cpus);
+	perf_cpu_map__put(intersect_cpus);
 	return err;
 }
 
@@ -435,7 +434,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
 	 * Also the case of per-cpu mmaps, need the contextID in order to be notified
 	 * when a context switch happened.
 	 */
-	if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
+	if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
 		evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
 					   "timestamp", 1);
 		evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
@@ -461,7 +460,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
 	evsel->core.attr.sample_period = 1;
 
 	/* In per-cpu case, always need the time of mmap events etc */
-	if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus))
+	if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
 		evsel__set_sample_bit(evsel, TIME);
 
 	err = cs_etm_validate_config(itr, cs_etm_evsel);
@@ -533,45 +532,31 @@ static size_t
 cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
 		      struct evlist *evlist __maybe_unused)
 {
-	int i;
+	int idx;
 	int etmv3 = 0, etmv4 = 0, ete = 0;
 	struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus;
-	struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
-
-	/* cpu map is not empty, we have specific CPUs to work with */
-	if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
-		for (i = 0; i < cpu__max_cpu().cpu; i++) {
-			struct perf_cpu cpu = { .cpu = i, };
+	struct perf_cpu_map *intersect_cpus;
+	struct perf_cpu cpu;
 
-			if (!perf_cpu_map__has(event_cpus, cpu) ||
-			    !perf_cpu_map__has(online_cpus, cpu))
-				continue;
+	if (!perf_cpu_map__has_any_cpu(event_cpus)) {
+		/* cpu map is not "any" CPU , we have specific CPUs to work with */
+		struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
 
-			if (cs_etm_is_ete(itr, i))
-				ete++;
-			else if (cs_etm_is_etmv4(itr, i))
-				etmv4++;
-			else
-				etmv3++;
-		}
+		intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
+		perf_cpu_map__put(online_cpus);
 	} else {
-		/* get configuration for all CPUs in the system */
-		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))
-				ete++;
-			else if (cs_etm_is_etmv4(itr, i))
-				etmv4++;
-			else
-				etmv3++;
-		}
+		/* Event can be "any" CPU so count all online CPUs. */
+		intersect_cpus = perf_cpu_map__new_online_cpus();
 	}
-
-	perf_cpu_map__put(online_cpus);
+	perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
+		if (cs_etm_is_ete(itr, cpu.cpu))
+			ete++;
+		else if (cs_etm_is_etmv4(itr, cpu.cpu))
+			etmv4++;
+		else
+			etmv3++;
+	}
+	perf_cpu_map__put(intersect_cpus);
 
 	return (CS_ETM_HEADER_SIZE +
 	       (ete   * CS_ETE_PRIV_SIZE) +
@@ -813,16 +798,15 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
 	if (!session->evlist->core.nr_mmaps)
 		return -EINVAL;
 
-	/* If the cpu_map is empty all online CPUs are involved */
-	if (perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
+	/* If the cpu_map has the "any" CPU all online CPUs are involved */
+	if (perf_cpu_map__has_any_cpu(event_cpus)) {
 		cpu_map = online_cpus;
 	} else {
 		/* Make sure all specified CPUs are online */
-		for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) {
-			struct perf_cpu cpu = { .cpu = i, };
+		struct perf_cpu cpu;
 
-			if (perf_cpu_map__has(event_cpus, cpu) &&
-			    !perf_cpu_map__has(online_cpus, cpu))
+		perf_cpu_map__for_each_cpu(cpu, i, event_cpus) {
+			if (!perf_cpu_map__has(online_cpus, cpu))
 				return -EINVAL;
 		}
 
diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
index 51ccbfd3d246..0b52e67edb3b 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -232,7 +232,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
 	 * In the case of per-cpu mmaps, sample CPU for AUX event;
 	 * also enable the timestamp tracing for samples correlation.
 	 */
-	if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
+	if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
 		evsel__set_sample_bit(arm_spe_evsel, CPU);
 		evsel__set_config_if_unset(arm_spe_pmu, arm_spe_evsel,
 					   "ts_enable", 1);
@@ -265,7 +265,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
 	tracking_evsel->core.attr.sample_period = 1;
 
 	/* In per-cpu case, always need the time of mmap events etc */
-	if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
+	if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
 		evsel__set_sample_bit(tracking_evsel, TIME);
 		evsel__set_sample_bit(tracking_evsel, CPU);
 
-- 
2.43.0.594.gd9cf4e227d-goog



From irogers at google.com  Fri Feb  2 15:40:53 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  2 Feb 2024 15:40:53 -0800
Subject: [PATCH v3 4/8] perf intel-pt/intel-bts: Switch perf_cpu_map__has_any_cpu_or_is_empty
 use
In-Reply-To: <20240202234057.2085863-1-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com>
Message-ID: <20240202234057.2085863-5-irogers@google.com>

Switch perf_cpu_map__has_any_cpu_or_is_empty to
perf_cpu_map__is_any_cpu_or_is_empty as a CPU map may contain CPUs as
well as the dummy event and perf_cpu_map__is_any_cpu_or_is_empty is a
more correct alternative.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/x86/util/intel-bts.c |  4 ++--
 tools/perf/arch/x86/util/intel-pt.c  | 10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c
index af8ae4647585..34696f3d3d5d 100644
--- a/tools/perf/arch/x86/util/intel-bts.c
+++ b/tools/perf/arch/x86/util/intel-bts.c
@@ -143,7 +143,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr,
 	if (!opts->full_auxtrace)
 		return 0;
 
-	if (opts->full_auxtrace && !perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
+	if (opts->full_auxtrace && !perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
 		pr_err(INTEL_BTS_PMU_NAME " does not support per-cpu recording\n");
 		return -EINVAL;
 	}
@@ -224,7 +224,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr,
 		 * In the case of per-cpu mmaps, we need the CPU on the
 		 * AUX event.
 		 */
-		if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus))
+		if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
 			evsel__set_sample_bit(intel_bts_evsel, CPU);
 	}
 
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index d199619df3ab..6de7e2d21075 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -369,7 +369,7 @@ static int intel_pt_info_fill(struct auxtrace_record *itr,
 			ui__warning("Intel Processor Trace: TSC not available\n");
 	}
 
-	per_cpu_mmaps = !perf_cpu_map__has_any_cpu_or_is_empty(session->evlist->core.user_requested_cpus);
+	per_cpu_mmaps = !perf_cpu_map__is_any_cpu_or_is_empty(session->evlist->core.user_requested_cpus);
 
 	auxtrace_info->type = PERF_AUXTRACE_INTEL_PT;
 	auxtrace_info->priv[INTEL_PT_PMU_TYPE] = intel_pt_pmu->type;
@@ -774,7 +774,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 	 * Per-cpu recording needs sched_switch events to distinguish different
 	 * threads.
 	 */
-	if (have_timing_info && !perf_cpu_map__has_any_cpu_or_is_empty(cpus) &&
+	if (have_timing_info && !perf_cpu_map__is_any_cpu_or_is_empty(cpus) &&
 	    !record_opts__no_switch_events(opts)) {
 		if (perf_can_record_switch_events()) {
 			bool cpu_wide = !target__none(&opts->target) &&
@@ -832,7 +832,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 		 * In the case of per-cpu mmaps, we need the CPU on the
 		 * AUX event.
 		 */
-		if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus))
+		if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
 			evsel__set_sample_bit(intel_pt_evsel, CPU);
 	}
 
@@ -858,7 +858,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 			tracking_evsel->immediate = true;
 
 		/* In per-cpu case, always need the time of mmap events etc */
-		if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
+		if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
 			evsel__set_sample_bit(tracking_evsel, TIME);
 			/* And the CPU for switch events */
 			evsel__set_sample_bit(tracking_evsel, CPU);
@@ -870,7 +870,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 	 * Warn the user when we do not have enough information to decode i.e.
 	 * per-cpu with no sched_switch (except workload-only).
 	 */
-	if (!ptr->have_sched_switch && !perf_cpu_map__has_any_cpu_or_is_empty(cpus) &&
+	if (!ptr->have_sched_switch && !perf_cpu_map__is_any_cpu_or_is_empty(cpus) &&
 	    !target__none(&opts->target) &&
 	    !intel_pt_evsel->core.attr.exclude_user)
 		ui__warning("Intel Processor Trace decoding will not be possible except for kernel tracing!\n");
-- 
2.43.0.594.gd9cf4e227d-goog



From irogers at google.com  Fri Feb  2 15:40:54 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  2 Feb 2024 15:40:54 -0800
Subject: [PATCH v3 5/8] perf cpumap: Clean up use of perf_cpu_map__has_any_cpu_or_is_empty
In-Reply-To: <20240202234057.2085863-1-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com>
Message-ID: <20240202234057.2085863-6-irogers@google.com>

Most uses of what was perf_cpu_map__empty but is now
perf_cpu_map__has_any_cpu_or_is_empty want to do something with the
CPU map if it contains CPUs. Replace uses of
perf_cpu_map__has_any_cpu_or_is_empty with other helpers so that CPUs
within the map can be handled.

Signed-off-by: Ian Rogers <irogers at google.com>
Reviewed-by: James Clark <james.clark at arm.com>
---
 tools/perf/builtin-c2c.c   | 6 +-----
 tools/perf/builtin-stat.c  | 9 ++++-----
 tools/perf/util/auxtrace.c | 4 ++--
 tools/perf/util/record.c   | 2 +-
 tools/perf/util/stat.c     | 2 +-
 5 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 16b40f5d43db..24107062c43e 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -2319,11 +2319,7 @@ static int setup_nodes(struct perf_session *session)
 
 		nodes[node] = set;
 
-		/* empty node, skip */
-		if (perf_cpu_map__has_any_cpu_or_is_empty(map))
-			continue;
-
-		perf_cpu_map__for_each_cpu(cpu, idx, map) {
+		perf_cpu_map__for_each_cpu_skip_any(cpu, idx, map) {
 			__set_bit(cpu.cpu, set);
 
 			if (WARN_ONCE(cpu2node[cpu.cpu] != -1, "node/cpu topology bug"))
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 5fe9abc6a524..280eb0c99d2b 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1317,10 +1317,9 @@ static int cpu__get_cache_id_from_map(struct perf_cpu cpu, char *map)
 	 * be the first online CPU in the cache domain else use the
 	 * first online CPU of the cache domain as the ID.
 	 */
-	if (perf_cpu_map__has_any_cpu_or_is_empty(cpu_map))
+	id = perf_cpu_map__min(cpu_map).cpu;
+	if (id == -1)
 		id = cpu.cpu;
-	else
-		id = perf_cpu_map__cpu(cpu_map, 0).cpu;
 
 	/* Free the perf_cpu_map used to find the cache ID */
 	perf_cpu_map__put(cpu_map);
@@ -1623,7 +1622,7 @@ static int perf_stat_init_aggr_mode(void)
 	 * taking the highest cpu number to be the size of
 	 * the aggregation translate cpumap.
 	 */
-	if (!perf_cpu_map__has_any_cpu_or_is_empty(evsel_list->core.user_requested_cpus))
+	if (!perf_cpu_map__is_any_cpu_or_is_empty(evsel_list->core.user_requested_cpus))
 		nr = perf_cpu_map__max(evsel_list->core.user_requested_cpus).cpu;
 	else
 		nr = 0;
@@ -2290,7 +2289,7 @@ int process_stat_config_event(struct perf_session *session,
 
 	perf_event__read_stat_config(&stat_config, &event->stat_config);
 
-	if (perf_cpu_map__has_any_cpu_or_is_empty(st->cpus)) {
+	if (perf_cpu_map__is_empty(st->cpus)) {
 		if (st->aggr_mode != AGGR_UNSET)
 			pr_warning("warning: processing task data, aggregation mode not set\n");
 	} else if (st->aggr_mode != AGGR_UNSET) {
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 3684e6009b63..6b1d4bafad59 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -174,7 +174,7 @@ void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp,
 				   struct evlist *evlist,
 				   struct evsel *evsel, int idx)
 {
-	bool per_cpu = !perf_cpu_map__has_any_cpu_or_is_empty(evlist->core.user_requested_cpus);
+	bool per_cpu = !perf_cpu_map__has_any_cpu(evlist->core.user_requested_cpus);
 
 	mp->mmap_needed = evsel->needs_auxtrace_mmap;
 
@@ -648,7 +648,7 @@ int auxtrace_parse_snapshot_options(struct auxtrace_record *itr,
 
 static int evlist__enable_event_idx(struct evlist *evlist, struct evsel *evsel, int idx)
 {
-	bool per_cpu_mmaps = !perf_cpu_map__has_any_cpu_or_is_empty(evlist->core.user_requested_cpus);
+	bool per_cpu_mmaps = !perf_cpu_map__has_any_cpu(evlist->core.user_requested_cpus);
 
 	if (per_cpu_mmaps) {
 		struct perf_cpu evlist_cpu = perf_cpu_map__cpu(evlist->core.all_cpus, idx);
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 87e817b3cf7e..e867de8ddaaa 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -237,7 +237,7 @@ bool evlist__can_select_event(struct evlist *evlist, const char *str)
 
 	evsel = evlist__last(temp_evlist);
 
-	if (!evlist || perf_cpu_map__has_any_cpu_or_is_empty(evlist->core.user_requested_cpus)) {
+	if (!evlist || perf_cpu_map__is_any_cpu_or_is_empty(evlist->core.user_requested_cpus)) {
 		struct perf_cpu_map *cpus = perf_cpu_map__new_online_cpus();
 
 		if (cpus)
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index b0bcf92f0f9c..0bd5467389e4 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -315,7 +315,7 @@ static int check_per_pkg(struct evsel *counter, struct perf_counts_values *vals,
 	if (!counter->per_pkg)
 		return 0;
 
-	if (perf_cpu_map__has_any_cpu_or_is_empty(cpus))
+	if (perf_cpu_map__is_any_cpu_or_is_empty(cpus))
 		return 0;
 
 	if (!mask) {
-- 
2.43.0.594.gd9cf4e227d-goog



From irogers at google.com  Fri Feb  2 15:40:55 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  2 Feb 2024 15:40:55 -0800
Subject: [PATCH v3 6/8] perf arm64 header: Remove unnecessary CPU map get and put
In-Reply-To: <20240202234057.2085863-1-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com>
Message-ID: <20240202234057.2085863-7-irogers@google.com>

In both cases the CPU map is known owned by either the caller or a
PMU.

Signed-off-by: Ian Rogers <irogers at google.com>
Reviewed-by: James Clark <james.clark at arm.com>
---
 tools/perf/arch/arm64/util/header.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
index 97037499152e..a9de0b5187dd 100644
--- a/tools/perf/arch/arm64/util/header.c
+++ b/tools/perf/arch/arm64/util/header.c
@@ -25,8 +25,6 @@ static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus)
 	if (!sysfs || sz < MIDR_SIZE)
 		return EINVAL;
 
-	cpus = perf_cpu_map__get(cpus);
-
 	for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) {
 		char path[PATH_MAX];
 		FILE *file;
@@ -51,7 +49,6 @@ static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus)
 		break;
 	}
 
-	perf_cpu_map__put(cpus);
 	return ret;
 }
 
-- 
2.43.0.594.gd9cf4e227d-goog



From irogers at google.com  Fri Feb  2 15:40:56 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  2 Feb 2024 15:40:56 -0800
Subject: [PATCH v3 7/8] perf stat: Remove duplicate cpus_map_matched function
In-Reply-To: <20240202234057.2085863-1-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com>
Message-ID: <20240202234057.2085863-8-irogers@google.com>

Use libperf's perf_cpu_map__equal that performs the same function.

Signed-off-by: Ian Rogers <irogers at google.com>
Reviewed-by: James Clark <james.clark at arm.com>
---
 tools/perf/builtin-stat.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 280eb0c99d2b..d80bad7c73e4 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -164,26 +164,6 @@ static struct perf_stat_config stat_config = {
 	.iostat_run		= false,
 };
 
-static bool cpus_map_matched(struct evsel *a, struct evsel *b)
-{
-	if (!a->core.cpus && !b->core.cpus)
-		return true;
-
-	if (!a->core.cpus || !b->core.cpus)
-		return false;
-
-	if (perf_cpu_map__nr(a->core.cpus) != perf_cpu_map__nr(b->core.cpus))
-		return false;
-
-	for (int i = 0; i < perf_cpu_map__nr(a->core.cpus); i++) {
-		if (perf_cpu_map__cpu(a->core.cpus, i).cpu !=
-		    perf_cpu_map__cpu(b->core.cpus, i).cpu)
-			return false;
-	}
-
-	return true;
-}
-
 static void evlist__check_cpu_maps(struct evlist *evlist)
 {
 	struct evsel *evsel, *warned_leader = NULL;
@@ -194,7 +174,7 @@ static void evlist__check_cpu_maps(struct evlist *evlist)
 		/* Check that leader matches cpus with each member. */
 		if (leader == evsel)
 			continue;
-		if (cpus_map_matched(leader, evsel))
+		if (perf_cpu_map__equal(leader->core.cpus, evsel->core.cpus))
 			continue;
 
 		/* If there's mismatch disable the group and warn user. */
-- 
2.43.0.594.gd9cf4e227d-goog



From irogers at google.com  Fri Feb  2 15:40:57 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  2 Feb 2024 15:40:57 -0800
Subject: [PATCH v3 8/8] perf cpumap: Use perf_cpu_map__for_each_cpu when possible
In-Reply-To: <20240202234057.2085863-1-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com>
Message-ID: <20240202234057.2085863-9-irogers@google.com>

Rather than manually iterating the CPU map, use
perf_cpu_map__for_each_cpu. When possible tidy local variables.

Signed-off-by: Ian Rogers <irogers at google.com>
Reviewed-by: James Clark <james.clark at arm.com>
---
 tools/perf/arch/arm64/util/header.c           | 10 ++--
 tools/perf/tests/bitmap.c                     | 13 +++---
 tools/perf/tests/topology.c                   | 46 +++++++++----------
 tools/perf/util/bpf_kwork.c                   | 16 ++++---
 tools/perf/util/bpf_kwork_top.c               | 12 ++---
 tools/perf/util/cpumap.c                      | 12 ++---
 .../scripting-engines/trace-event-python.c    | 12 +++--
 tools/perf/util/session.c                     |  5 +-
 tools/perf/util/svghelper.c                   | 20 ++++----
 9 files changed, 72 insertions(+), 74 deletions(-)

diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
index a9de0b5187dd..741df3614a09 100644
--- a/tools/perf/arch/arm64/util/header.c
+++ b/tools/perf/arch/arm64/util/header.c
@@ -4,8 +4,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <perf/cpumap.h>
-#include <util/cpumap.h>
-#include <internal/cpumap.h>
 #include <api/fs/fs.h>
 #include <errno.h>
 #include "debug.h"
@@ -19,18 +17,18 @@
 static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus)
 {
 	const char *sysfs = sysfs__mountpoint();
-	int cpu;
-	int ret = EINVAL;
+	struct perf_cpu cpu;
+	int idx, ret = EINVAL;
 
 	if (!sysfs || sz < MIDR_SIZE)
 		return EINVAL;
 
-	for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) {
+	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
 		char path[PATH_MAX];
 		FILE *file;
 
 		scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d" MIDR,
-			  sysfs, RC_CHK_ACCESS(cpus)->map[cpu].cpu);
+			  sysfs, cpu.cpu);
 
 		file = fopen(path, "r");
 		if (!file) {
diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c
index 0173f5402a35..98956e0e0765 100644
--- a/tools/perf/tests/bitmap.c
+++ b/tools/perf/tests/bitmap.c
@@ -11,18 +11,19 @@
 static unsigned long *get_bitmap(const char *str, int nbits)
 {
 	struct perf_cpu_map *map = perf_cpu_map__new(str);
-	unsigned long *bm = NULL;
-	int i;
+	unsigned long *bm;
 
 	bm = bitmap_zalloc(nbits);
 
 	if (map && bm) {
-		for (i = 0; i < perf_cpu_map__nr(map); i++)
-			__set_bit(perf_cpu_map__cpu(map, i).cpu, bm);
+		int i;
+		struct perf_cpu cpu;
+
+		perf_cpu_map__for_each_cpu(cpu, i, map)
+			__set_bit(cpu.cpu, bm);
 	}
 
-	if (map)
-		perf_cpu_map__put(map);
+	perf_cpu_map__put(map);
 	return bm;
 }
 
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 2a842f53fbb5..a8cb5ba898ab 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -68,6 +68,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 	};
 	int i;
 	struct aggr_cpu_id id;
+	struct perf_cpu cpu;
 
 	session = perf_session__new(&data, NULL);
 	TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
@@ -113,8 +114,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++) {
-		struct perf_cpu cpu = { .cpu = i };
-
+		cpu.cpu = i;
 		if (!perf_cpu_map__has(map, cpu))
 			continue;
 		pr_debug("CPU %d, core %d, socket %d\n", i,
@@ -123,48 +123,48 @@ 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 < perf_cpu_map__nr(map); i++) {
-		id = aggr_cpu_id__cpu(perf_cpu_map__cpu(map, i), NULL);
+	perf_cpu_map__for_each_cpu(cpu, i, map) {
+		id = aggr_cpu_id__cpu(cpu, NULL);
 		TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match",
-				perf_cpu_map__cpu(map, i).cpu == id.cpu.cpu);
+				cpu.cpu == id.cpu.cpu);
 
 		TEST_ASSERT_VAL("Cpu map - Core ID doesn't match",
-			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].core_id == id.core);
+			session->header.env.cpu[cpu.cpu].core_id == id.core);
 		TEST_ASSERT_VAL("Cpu map - Socket ID doesn't match",
-			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
+			session->header.env.cpu[cpu.cpu].socket_id ==
 			id.socket);
 
 		TEST_ASSERT_VAL("Cpu map - Die ID doesn't match",
-			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id == id.die);
+			session->header.env.cpu[cpu.cpu].die_id == id.die);
 		TEST_ASSERT_VAL("Cpu map - Node ID is set", id.node == -1);
 		TEST_ASSERT_VAL("Cpu map - Thread IDX is set", id.thread_idx == -1);
 	}
 
 	// Test that core ID contains socket, die and core
-	for (i = 0; i < perf_cpu_map__nr(map); i++) {
-		id = aggr_cpu_id__core(perf_cpu_map__cpu(map, i), NULL);
+	perf_cpu_map__for_each_cpu(cpu, i, map) {
+		id = aggr_cpu_id__core(cpu, NULL);
 		TEST_ASSERT_VAL("Core map - Core ID doesn't match",
-			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].core_id == id.core);
+			session->header.env.cpu[cpu.cpu].core_id == id.core);
 
 		TEST_ASSERT_VAL("Core map - Socket ID doesn't match",
-			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
+			session->header.env.cpu[cpu.cpu].socket_id ==
 			id.socket);
 
 		TEST_ASSERT_VAL("Core map - Die ID doesn't match",
-			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id == id.die);
+			session->header.env.cpu[cpu.cpu].die_id == id.die);
 		TEST_ASSERT_VAL("Core map - Node ID is set", id.node == -1);
 		TEST_ASSERT_VAL("Core map - Thread IDX is set", id.thread_idx == -1);
 	}
 
 	// Test that die ID contains socket and die
-	for (i = 0; i < perf_cpu_map__nr(map); i++) {
-		id = aggr_cpu_id__die(perf_cpu_map__cpu(map, i), NULL);
+	perf_cpu_map__for_each_cpu(cpu, i, map) {
+		id = aggr_cpu_id__die(cpu, NULL);
 		TEST_ASSERT_VAL("Die map - Socket ID doesn't match",
-			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
+			session->header.env.cpu[cpu.cpu].socket_id ==
 			id.socket);
 
 		TEST_ASSERT_VAL("Die map - Die ID doesn't match",
-			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id == id.die);
+			session->header.env.cpu[cpu.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);
@@ -173,10 +173,10 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 	}
 
 	// Test that socket ID contains only socket
-	for (i = 0; i < perf_cpu_map__nr(map); i++) {
-		id = aggr_cpu_id__socket(perf_cpu_map__cpu(map, i), NULL);
+	perf_cpu_map__for_each_cpu(cpu, i, map) {
+		id = aggr_cpu_id__socket(cpu, NULL);
 		TEST_ASSERT_VAL("Socket map - Socket ID doesn't match",
-			session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
+			session->header.env.cpu[cpu.cpu].socket_id ==
 			id.socket);
 
 		TEST_ASSERT_VAL("Socket map - Node ID is set", id.node == -1);
@@ -187,10 +187,10 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 	}
 
 	// Test that node ID contains only node
-	for (i = 0; i < perf_cpu_map__nr(map); i++) {
-		id = aggr_cpu_id__node(perf_cpu_map__cpu(map, i), NULL);
+	perf_cpu_map__for_each_cpu(cpu, i, map) {
+		id = aggr_cpu_id__node(cpu, NULL);
 		TEST_ASSERT_VAL("Node map - Node ID doesn't match",
-				cpu__get_node(perf_cpu_map__cpu(map, i)) == id.node);
+				cpu__get_node(cpu) == id.node);
 		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);
diff --git a/tools/perf/util/bpf_kwork.c b/tools/perf/util/bpf_kwork.c
index 6eb2c78fd7f4..44f0f708a15d 100644
--- a/tools/perf/util/bpf_kwork.c
+++ b/tools/perf/util/bpf_kwork.c
@@ -147,12 +147,12 @@ static bool valid_kwork_class_type(enum kwork_class_type type)
 
 static int setup_filters(struct perf_kwork *kwork)
 {
-	u8 val = 1;
-	int i, nr_cpus, key, fd;
-	struct perf_cpu_map *map;
-
 	if (kwork->cpu_list != NULL) {
-		fd = bpf_map__fd(skel->maps.perf_kwork_cpu_filter);
+		int idx, nr_cpus;
+		struct perf_cpu_map *map;
+		struct perf_cpu cpu;
+		int fd = bpf_map__fd(skel->maps.perf_kwork_cpu_filter);
+
 		if (fd < 0) {
 			pr_debug("Invalid cpu filter fd\n");
 			return -1;
@@ -165,8 +165,8 @@ static int setup_filters(struct perf_kwork *kwork)
 		}
 
 		nr_cpus = libbpf_num_possible_cpus();
-		for (i = 0; i < perf_cpu_map__nr(map); i++) {
-			struct perf_cpu cpu = perf_cpu_map__cpu(map, i);
+		perf_cpu_map__for_each_cpu(cpu, idx, map) {
+			u8 val = 1;
 
 			if (cpu.cpu >= nr_cpus) {
 				perf_cpu_map__put(map);
@@ -181,6 +181,8 @@ static int setup_filters(struct perf_kwork *kwork)
 	}
 
 	if (kwork->profile_name != NULL) {
+		int key, fd;
+
 		if (strlen(kwork->profile_name) >= MAX_KWORKNAME) {
 			pr_err("Requested name filter %s too large, limit to %d\n",
 			       kwork->profile_name, MAX_KWORKNAME - 1);
diff --git a/tools/perf/util/bpf_kwork_top.c b/tools/perf/util/bpf_kwork_top.c
index 035e02272790..22a3b00a1e23 100644
--- a/tools/perf/util/bpf_kwork_top.c
+++ b/tools/perf/util/bpf_kwork_top.c
@@ -122,11 +122,11 @@ static bool valid_kwork_class_type(enum kwork_class_type type)
 
 static int setup_filters(struct perf_kwork *kwork)
 {
-	u8 val = 1;
-	int i, nr_cpus, fd;
-	struct perf_cpu_map *map;
-
 	if (kwork->cpu_list) {
+		int idx, nr_cpus, fd;
+		struct perf_cpu_map *map;
+		struct perf_cpu cpu;
+
 		fd = bpf_map__fd(skel->maps.kwork_top_cpu_filter);
 		if (fd < 0) {
 			pr_debug("Invalid cpu filter fd\n");
@@ -140,8 +140,8 @@ static int setup_filters(struct perf_kwork *kwork)
 		}
 
 		nr_cpus = libbpf_num_possible_cpus();
-		for (i = 0; i < perf_cpu_map__nr(map); i++) {
-			struct perf_cpu cpu = perf_cpu_map__cpu(map, i);
+		perf_cpu_map__for_each_cpu(cpu, idx, map) {
+			u8 val = 1;
 
 			if (cpu.cpu >= nr_cpus) {
 				perf_cpu_map__put(map);
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 0581ee0fa5f2..e2287187babd 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -629,10 +629,10 @@ static char hex_char(unsigned char val)
 
 size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size)
 {
-	int i, cpu;
+	int idx;
 	char *ptr = buf;
 	unsigned char *bitmap;
-	struct perf_cpu last_cpu = perf_cpu_map__cpu(map, perf_cpu_map__nr(map) - 1);
+	struct perf_cpu c, last_cpu = perf_cpu_map__max(map);
 
 	if (buf == NULL)
 		return 0;
@@ -643,12 +643,10 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size)
 		return 0;
 	}
 
-	for (i = 0; i < perf_cpu_map__nr(map); i++) {
-		cpu = perf_cpu_map__cpu(map, i).cpu;
-		bitmap[cpu / 8] |= 1 << (cpu % 8);
-	}
+	perf_cpu_map__for_each_cpu(c, idx, map)
+		bitmap[c.cpu / 8] |= 1 << (c.cpu % 8);
 
-	for (cpu = last_cpu.cpu / 4 * 4; cpu >= 0; cpu -= 4) {
+	for (int cpu = last_cpu.cpu / 4 * 4; cpu >= 0; cpu -= 4) {
 		unsigned char bits = bitmap[cpu / 8];
 
 		if (cpu % 8)
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 860e1837ba96..8ef0e5ac03c2 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -1693,13 +1693,15 @@ static void python_process_stat(struct perf_stat_config *config,
 {
 	struct perf_thread_map *threads = counter->core.threads;
 	struct perf_cpu_map *cpus = counter->core.cpus;
-	int cpu, thread;
 
-	for (thread = 0; thread < perf_thread_map__nr(threads); thread++) {
-		for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) {
-			process_stat(counter, perf_cpu_map__cpu(cpus, cpu),
+	for (int thread = 0; thread < perf_thread_map__nr(threads); thread++) {
+		int idx;
+		struct perf_cpu cpu;
+
+		perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
+			process_stat(counter, cpu,
 				     perf_thread_map__pid(threads, thread), tstamp,
-				     perf_counts(counter->counts, cpu, thread));
+				     perf_counts(counter->counts, idx, thread));
 		}
 	}
 }
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 199d3e8df315..d52b58344dbc 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -2738,6 +2738,7 @@ int perf_session__cpu_bitmap(struct perf_session *session,
 	int i, err = -1;
 	struct perf_cpu_map *map;
 	int nr_cpus = min(session->header.env.nr_cpus_avail, MAX_NR_CPUS);
+	struct perf_cpu cpu;
 
 	for (i = 0; i < PERF_TYPE_MAX; ++i) {
 		struct evsel *evsel;
@@ -2759,9 +2760,7 @@ int perf_session__cpu_bitmap(struct perf_session *session,
 		return -1;
 	}
 
-	for (i = 0; i < perf_cpu_map__nr(map); i++) {
-		struct perf_cpu cpu = perf_cpu_map__cpu(map, i);
-
+	perf_cpu_map__for_each_cpu(cpu, i, map) {
 		if (cpu.cpu >= nr_cpus) {
 			pr_err("Requested CPU %d too large. "
 			       "Consider raising MAX_NR_CPUS\n", cpu.cpu);
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index 1892e9b6aa7f..2b04f47f4db0 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -725,26 +725,24 @@ static void scan_core_topology(int *map, struct topology *t, int nr_cpus)
 
 static int str_to_bitmap(char *s, cpumask_t *b, int nr_cpus)
 {
-	int i;
-	int ret = 0;
-	struct perf_cpu_map *m;
-	struct perf_cpu c;
+	int idx, ret = 0;
+	struct perf_cpu_map *map;
+	struct perf_cpu cpu;
 
-	m = perf_cpu_map__new(s);
-	if (!m)
+	map = perf_cpu_map__new(s);
+	if (!map)
 		return -1;
 
-	for (i = 0; i < perf_cpu_map__nr(m); i++) {
-		c = perf_cpu_map__cpu(m, i);
-		if (c.cpu >= nr_cpus) {
+	perf_cpu_map__for_each_cpu(cpu, idx, map) {
+		if (cpu.cpu >= nr_cpus) {
 			ret = -1;
 			break;
 		}
 
-		__set_bit(c.cpu, cpumask_bits(b));
+		__set_bit(cpu.cpu, cpumask_bits(b));
 	}
 
-	perf_cpu_map__put(m);
+	perf_cpu_map__put(map);
 
 	return ret;
 }
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 15:46:03 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 15:46:03 -0800
Subject: [PATCH] KVM: selftests: Fix GUEST_PRINTF() format warnings in ARM code
Message-ID: <20240202234603.366925-1-seanjc@google.com>

Fix a pile of -Wformat warnings in the KVM ARM selftests code, almost all
of which are benign "long" versus "long long" issues (selftests are 64-bit
only, and the guest printf code treats "ll" the same as "l").  The code
itself isn't problematic, but the warnings make it impossible to build ARM
selftests with -Werror, which does detect real issues from time to time.

Opportunistically have GUEST_ASSERT_BITMAP_REG() interpret set_expected,
which is a bool, as an unsigned decimal value, i.e. have it print '0' or
'1' instead of '0x0' or '0x1'.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---

Compile tested only, mainly because I'm rushing through things on Friday
afternoon, not because testing on ARM is actually problematic for me.

 tools/testing/selftests/kvm/aarch64/arch_timer.c     |  4 ++--
 .../testing/selftests/kvm/aarch64/debug-exceptions.c |  2 +-
 tools/testing/selftests/kvm/aarch64/hypercalls.c     |  4 ++--
 .../testing/selftests/kvm/aarch64/page_fault_test.c  |  2 +-
 .../selftests/kvm/aarch64/vpmu_counter_access.c      | 12 ++++++------
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
index 274b8465b42a..d5e8f365aa01 100644
--- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
+++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
@@ -158,9 +158,9 @@ static void guest_validate_irq(unsigned int intid,
 
 	/* Basic 'timer condition met' check */
 	__GUEST_ASSERT(xcnt >= cval,
-		       "xcnt = 0x%llx, cval = 0x%llx, xcnt_diff_us = 0x%llx",
+		       "xcnt = 0x%lx, cval = 0x%lx, xcnt_diff_us = 0x%lx",
 		       xcnt, cval, xcnt_diff_us);
-	__GUEST_ASSERT(xctl & CTL_ISTATUS, "xcnt = 0x%llx", xcnt);
+	__GUEST_ASSERT(xctl & CTL_ISTATUS, "xcnt = 0x%lx", xcnt);
 
 	WRITE_ONCE(shared_data->nr_iter, shared_data->nr_iter + 1);
 }
diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
index 866002917441..2582c49e525a 100644
--- a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
+++ b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
@@ -365,7 +365,7 @@ static void guest_wp_handler(struct ex_regs *regs)
 
 static void guest_ss_handler(struct ex_regs *regs)
 {
-	__GUEST_ASSERT(ss_idx < 4, "Expected index < 4, got '%u'", ss_idx);
+	__GUEST_ASSERT(ss_idx < 4, "Expected index < 4, got '%lu'", ss_idx);
 	ss_addr[ss_idx++] = regs->pc;
 	regs->pstate |= SPSR_SS;
 }
diff --git a/tools/testing/selftests/kvm/aarch64/hypercalls.c b/tools/testing/selftests/kvm/aarch64/hypercalls.c
index 31f66ba97228..c62739d897d6 100644
--- a/tools/testing/selftests/kvm/aarch64/hypercalls.c
+++ b/tools/testing/selftests/kvm/aarch64/hypercalls.c
@@ -105,12 +105,12 @@ static void guest_test_hvc(const struct test_hvc_info *hc_info)
 		case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
 		case TEST_STAGE_HVC_IFACE_FALSE_INFO:
 			__GUEST_ASSERT(res.a0 == SMCCC_RET_NOT_SUPPORTED,
-				       "a0 = 0x%lx, func_id = 0x%x, arg1 = 0x%llx, stage = %u",
+				       "a0 = 0x%lx, func_id = 0x%x, arg1 = 0x%lx, stage = %u",
 					res.a0, hc_info->func_id, hc_info->arg1, stage);
 			break;
 		case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
 			__GUEST_ASSERT(res.a0 != SMCCC_RET_NOT_SUPPORTED,
-				       "a0 = 0x%lx, func_id = 0x%x, arg1 = 0x%llx, stage = %u",
+				       "a0 = 0x%lx, func_id = 0x%x, arg1 = 0x%lx, stage = %u",
 					res.a0, hc_info->func_id, hc_info->arg1, stage);
 			break;
 		default:
diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
index 08a5ca5bed56..7bbd9fb5c8d6 100644
--- a/tools/testing/selftests/kvm/aarch64/page_fault_test.c
+++ b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
@@ -292,7 +292,7 @@ static void guest_code(struct test_desc *test)
 
 static void no_dabt_handler(struct ex_regs *regs)
 {
-	GUEST_FAIL("Unexpected dabt, far_el1 = 0x%llx", read_sysreg(far_el1));
+	GUEST_FAIL("Unexpected dabt, far_el1 = 0x%lx", read_sysreg(far_el1));
 }
 
 static void no_iabt_handler(struct ex_regs *regs)
diff --git a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c b/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
index 9d51b5691349..f8f0c655c723 100644
--- a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
+++ b/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
@@ -195,11 +195,11 @@ struct pmc_accessor pmc_accessors[] = {
 										 \
 	if (set_expected)							 \
 		__GUEST_ASSERT((_tval & mask),					 \
-				"tval: 0x%lx; mask: 0x%lx; set_expected: 0x%lx", \
+				"tval: 0x%lx; mask: 0x%lx; set_expected: %u",	 \
 				_tval, mask, set_expected);			 \
 	else									 \
 		__GUEST_ASSERT(!(_tval & mask),					 \
-				"tval: 0x%lx; mask: 0x%lx; set_expected: 0x%lx", \
+				"tval: 0x%lx; mask: 0x%lx; set_expected: %u",	 \
 				_tval, mask, set_expected);			 \
 }
 
@@ -286,7 +286,7 @@ static void test_access_pmc_regs(struct pmc_accessor *acc, int pmc_idx)
 	acc->write_typer(pmc_idx, write_data);
 	read_data = acc->read_typer(pmc_idx);
 	__GUEST_ASSERT(read_data == write_data,
-		       "pmc_idx: 0x%lx; acc_idx: 0x%lx; read_data: 0x%lx; write_data: 0x%lx",
+		       "pmc_idx: 0x%x; acc_idx: 0x%lx; read_data: 0x%lx; write_data: 0x%lx",
 		       pmc_idx, PMC_ACC_TO_IDX(acc), read_data, write_data);
 
 	/*
@@ -297,14 +297,14 @@ static void test_access_pmc_regs(struct pmc_accessor *acc, int pmc_idx)
 
 	/* The count value must be 0, as it is disabled and reset */
 	__GUEST_ASSERT(read_data == 0,
-		       "pmc_idx: 0x%lx; acc_idx: 0x%lx; read_data: 0x%lx",
+		       "pmc_idx: 0x%x; acc_idx: 0x%lx; read_data: 0x%lx",
 		       pmc_idx, PMC_ACC_TO_IDX(acc), read_data);
 
 	write_data = read_data + pmc_idx + 0x12345;
 	acc->write_cntr(pmc_idx, write_data);
 	read_data = acc->read_cntr(pmc_idx);
 	__GUEST_ASSERT(read_data == write_data,
-		       "pmc_idx: 0x%lx; acc_idx: 0x%lx; read_data: 0x%lx; write_data: 0x%lx",
+		       "pmc_idx: 0x%x; acc_idx: 0x%lx; read_data: 0x%lx; write_data: 0x%lx",
 		       pmc_idx, PMC_ACC_TO_IDX(acc), read_data, write_data);
 }
 
@@ -379,7 +379,7 @@ static void guest_code(uint64_t expected_pmcr_n)
 	int i, pmc;
 
 	__GUEST_ASSERT(expected_pmcr_n <= ARMV8_PMU_MAX_GENERAL_COUNTERS,
-			"Expected PMCR.N: 0x%lx; ARMv8 general counters: 0x%lx",
+			"Expected PMCR.N: 0x%lx; ARMv8 general counters: 0x%x",
 			expected_pmcr_n, ARMV8_PMU_MAX_GENERAL_COUNTERS);
 
 	pmcr = read_sysreg(pmcr_el0);

base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:06 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:06 -0800
Subject: [PATCH v8 00/10] KVM: selftests: Add SEV smoke test
Message-ID: <20240203000917.376631-1-seanjc@google.com>

Add a basic SEV smoke test.  Unlike the intra-host migration tests, this
one actually runs a small chunk of code in the guest.

v8:
 - Undo the kvm.h uAPI breakage.
 - Take advantage of "struct vm_shape", introduced by the guest_memfd
   selftests, to simply tracking the SEV/SEV-ES subtypes.
 - Rename the test to "sev_smoke_test" instead of "sev_all_boot_test",
   as the "all" is rather nonsensical, and the test isn't booting anything
   in the traditional sense of the word.
 - Drop vm->protected and instead add an arch hook to query if the VM has
   protected memory.
 - Assert that the target memory region supports protected memory when
   allocating protected memory.
 - Allocate protected_phy_pages for memory regions if and only if the VM
   supports protected memory.
 - Rename kvm_host.h to kvm_util_arch.h, and move it to selftests/kvm where
   it belongs.
 - Fix up some SoB goofs.
 - Convert the intrahost SEV/SEV-ES migration tests to use common ioctl()
   wrappers.

V7
 * https://lore.kernel.org/all/20231218161146.3554657-1-pgonda at google.com
 * See https://github.com/sean-jc/linux/tree/x86/sev_selftests_for_peter.
 * I kept is_pt_protected because without it the page tables are never
 readable. Its used for the elf loading in kvm_vm_elf_load().

V6
 * Updated SEV VM create function based on Seanjc's feedback and new
   changes to VM creation functions.
 * Removed pte_me_mask based on feedback.
 * Fixed s_bit usage based on TDX
 * Fixed bugs and took Ackerly's code for enc_region setup code.

V5
 * Rebase onto seanjc@'s latest ucall pool series.
 * More review changes based on seanjc:
 ** use protected instead of encrypted outside of SEV specific files
 ** Swap memcrypt struct for kvm_vm_arch arch specific struct
 ** Make protected page table data agnostic of address bit stealing specifics
    of SEV
 ** Further clean up for SEV library to just vm_sev_create_one_vcpu()
 * Due to large changes moved more authorships from mroth@ to pgonda at . Gave
   originally-by tags to mroth@ as suggested by Seanjc for this.

V4
 * Rebase ontop of seanjc@'s latest Ucall Pool series:
   https://lore.kernel.org/linux-arm-kernel/20220825232522.3997340-8-seanjc at google.com/
 * Fix up review comments from seanjc
 * Switch authorship on 2 patches because of significant changes, added
 * Michael as suggested-by or originally-by.

V3
 * Addressed more of andrew.jones@ in ucall patches.
 * Fix build in non-x86 archs.

V2
 * Dropped RFC tag
 * Correctly separated Sean's ucall patches into 2 as originally
   intended.
 * Addressed andrew.jones@ in ucall patches.
 * Fixed ucall pool usage to work for other archs

V1
 * https://lore.kernel.org/all/20220715192956.1873315-1-pgonda at google.com/

Ackerley Tng (1):
  KVM: selftests: Add a macro to iterate over a sparsebit range

Michael Roth (2):
  KVM: selftests: Make sparsebit structs const where appropriate
  KVM: selftests: Add support for protected vm_vaddr_* allocations

Peter Gonda (5):
  KVM: selftests: Add support for allocating/managing protected guest
    memory
  KVM: selftests: Explicitly ucall pool from shared memory
  KVM: selftests: Allow tagging protected memory in guest page tables
  KVM: selftests: Add library for creating and interacting with SEV
    guests
  KVM: selftests: Add a basic SEV smoke test

Sean Christopherson (2):
  KVM: selftests: Extend VM creation's @shape to allow control of VM
    subtype
  KVM: selftests: Use the SEV library APIs in the intra-host migration
    test

 tools/testing/selftests/kvm/Makefile          |   2 +
 .../kvm/include/aarch64/kvm_util_arch.h       |   7 +
 .../selftests/kvm/include/kvm_util_base.h     |  50 ++++++-
 .../kvm/include/riscv/kvm_util_arch.h         |   7 +
 .../kvm/include/s390x/kvm_util_arch.h         |   7 +
 .../testing/selftests/kvm/include/sparsebit.h |  56 +++++---
 .../kvm/include/x86_64/kvm_util_arch.h        |  23 ++++
 .../selftests/kvm/include/x86_64/processor.h  |   8 ++
 .../selftests/kvm/include/x86_64/sev.h        | 110 +++++++++++++++
 tools/testing/selftests/kvm/lib/kvm_util.c    |  67 +++++++--
 tools/testing/selftests/kvm/lib/sparsebit.c   |  48 +++----
 .../testing/selftests/kvm/lib/ucall_common.c  |   3 +-
 .../selftests/kvm/lib/x86_64/processor.c      |  32 ++++-
 tools/testing/selftests/kvm/lib/x86_64/sev.c  | 128 ++++++++++++++++++
 .../selftests/kvm/x86_64/sev_migrate_tests.c  |  67 +++------
 .../selftests/kvm/x86_64/sev_smoke_test.c     |  58 ++++++++
 16 files changed, 570 insertions(+), 103 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/x86_64/sev.h
 create mode 100644 tools/testing/selftests/kvm/lib/x86_64/sev.c
 create mode 100644 tools/testing/selftests/kvm/x86_64/sev_smoke_test.c


base-commit: 60eedcfceda9db46f1b333e5e1aa9359793f04fb
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:07 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:07 -0800
Subject: [PATCH v8 01/10] KVM: selftests: Extend VM creation's @shape to allow
 control of VM subtype
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <20240203000917.376631-2-seanjc@google.com>

Carve out space in the @shape passed to the various VM creation helpers to
allow using the shape to control the subtype of VM, e.g. to identify x86's
SEV VMs (which are "regular" VMs as far as KVM is concerned).

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerley Tng <ackerleytng at google.com>
Cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/include/kvm_util_base.h | 9 +++++++--
 tools/testing/selftests/kvm/lib/kvm_util.c          | 1 +
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index 070f250036fc..d9dc31af2f96 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -90,6 +90,7 @@ enum kvm_mem_region_type {
 struct kvm_vm {
 	int mode;
 	unsigned long type;
+	uint8_t subtype;
 	int kvm_fd;
 	int fd;
 	unsigned int pgtable_levels;
@@ -191,10 +192,14 @@ enum vm_guest_mode {
 };
 
 struct vm_shape {
-	enum vm_guest_mode mode;
-	unsigned int type;
+	uint32_t type;
+	uint8_t  mode;
+	uint8_t  subtype;
+	uint16_t padding;
 };
 
+kvm_static_assert(sizeof(struct vm_shape) == sizeof(uint64_t));
+
 #define VM_TYPE_DEFAULT			0
 
 #define VM_SHAPE(__mode)			\
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 4994afbdab40..a53caf81eb87 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -276,6 +276,7 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
 
 	vm->mode = shape.mode;
 	vm->type = shape.type;
+	vm->subtype = shape.subtype;
 
 	vm->pa_bits = vm_guest_mode_params[vm->mode].pa_bits;
 	vm->va_bits = vm_guest_mode_params[vm->mode].va_bits;
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:08 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:08 -0800
Subject: [PATCH v8 02/10] KVM: selftests: Make sparsebit structs const where appropriate
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <20240203000917.376631-3-seanjc@google.com>

From: Michael Roth <michael.roth at amd.com>

Make all sparsebit struct pointers "const" where appropriate.  This will
allow adding a bitmap to track protected/encrypted physical memory that
tests can access in a read-only fashion.

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerley Tng <ackerleytng at google.com>
Cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Signed-off-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
[sean: massage changelog]
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../testing/selftests/kvm/include/sparsebit.h | 36 +++++++-------
 tools/testing/selftests/kvm/lib/sparsebit.c   | 48 +++++++++----------
 2 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/sparsebit.h b/tools/testing/selftests/kvm/include/sparsebit.h
index 12a9a4b9cead..fb5170d57fcb 100644
--- a/tools/testing/selftests/kvm/include/sparsebit.h
+++ b/tools/testing/selftests/kvm/include/sparsebit.h
@@ -30,26 +30,26 @@ typedef uint64_t sparsebit_num_t;
 
 struct sparsebit *sparsebit_alloc(void);
 void sparsebit_free(struct sparsebit **sbitp);
-void sparsebit_copy(struct sparsebit *dstp, struct sparsebit *src);
+void sparsebit_copy(struct sparsebit *dstp, const struct sparsebit *src);
 
-bool sparsebit_is_set(struct sparsebit *sbit, sparsebit_idx_t idx);
-bool sparsebit_is_set_num(struct sparsebit *sbit,
+bool sparsebit_is_set(const struct sparsebit *sbit, sparsebit_idx_t idx);
+bool sparsebit_is_set_num(const struct sparsebit *sbit,
 			  sparsebit_idx_t idx, sparsebit_num_t num);
-bool sparsebit_is_clear(struct sparsebit *sbit, sparsebit_idx_t idx);
-bool sparsebit_is_clear_num(struct sparsebit *sbit,
+bool sparsebit_is_clear(const struct sparsebit *sbit, sparsebit_idx_t idx);
+bool sparsebit_is_clear_num(const struct sparsebit *sbit,
 			    sparsebit_idx_t idx, sparsebit_num_t num);
-sparsebit_num_t sparsebit_num_set(struct sparsebit *sbit);
-bool sparsebit_any_set(struct sparsebit *sbit);
-bool sparsebit_any_clear(struct sparsebit *sbit);
-bool sparsebit_all_set(struct sparsebit *sbit);
-bool sparsebit_all_clear(struct sparsebit *sbit);
-sparsebit_idx_t sparsebit_first_set(struct sparsebit *sbit);
-sparsebit_idx_t sparsebit_first_clear(struct sparsebit *sbit);
-sparsebit_idx_t sparsebit_next_set(struct sparsebit *sbit, sparsebit_idx_t prev);
-sparsebit_idx_t sparsebit_next_clear(struct sparsebit *sbit, sparsebit_idx_t prev);
-sparsebit_idx_t sparsebit_next_set_num(struct sparsebit *sbit,
+sparsebit_num_t sparsebit_num_set(const struct sparsebit *sbit);
+bool sparsebit_any_set(const struct sparsebit *sbit);
+bool sparsebit_any_clear(const struct sparsebit *sbit);
+bool sparsebit_all_set(const struct sparsebit *sbit);
+bool sparsebit_all_clear(const struct sparsebit *sbit);
+sparsebit_idx_t sparsebit_first_set(const struct sparsebit *sbit);
+sparsebit_idx_t sparsebit_first_clear(const struct sparsebit *sbit);
+sparsebit_idx_t sparsebit_next_set(const struct sparsebit *sbit, sparsebit_idx_t prev);
+sparsebit_idx_t sparsebit_next_clear(const struct sparsebit *sbit, sparsebit_idx_t prev);
+sparsebit_idx_t sparsebit_next_set_num(const struct sparsebit *sbit,
 				       sparsebit_idx_t start, sparsebit_num_t num);
-sparsebit_idx_t sparsebit_next_clear_num(struct sparsebit *sbit,
+sparsebit_idx_t sparsebit_next_clear_num(const struct sparsebit *sbit,
 					 sparsebit_idx_t start, sparsebit_num_t num);
 
 void sparsebit_set(struct sparsebit *sbitp, sparsebit_idx_t idx);
@@ -62,9 +62,9 @@ void sparsebit_clear_num(struct sparsebit *sbitp,
 			 sparsebit_idx_t start, sparsebit_num_t num);
 void sparsebit_clear_all(struct sparsebit *sbitp);
 
-void sparsebit_dump(FILE *stream, struct sparsebit *sbit,
+void sparsebit_dump(FILE *stream, const struct sparsebit *sbit,
 		    unsigned int indent);
-void sparsebit_validate_internal(struct sparsebit *sbit);
+void sparsebit_validate_internal(const struct sparsebit *sbit);
 
 #ifdef __cplusplus
 }
diff --git a/tools/testing/selftests/kvm/lib/sparsebit.c b/tools/testing/selftests/kvm/lib/sparsebit.c
index 88cb6b84e6f3..cfed9d26cc71 100644
--- a/tools/testing/selftests/kvm/lib/sparsebit.c
+++ b/tools/testing/selftests/kvm/lib/sparsebit.c
@@ -202,7 +202,7 @@ static sparsebit_num_t node_num_set(struct node *nodep)
 /* Returns a pointer to the node that describes the
  * lowest bit index.
  */
-static struct node *node_first(struct sparsebit *s)
+static struct node *node_first(const struct sparsebit *s)
 {
 	struct node *nodep;
 
@@ -216,7 +216,7 @@ static struct node *node_first(struct sparsebit *s)
  * lowest bit index > the index of the node pointed to by np.
  * Returns NULL if no node with a higher index exists.
  */
-static struct node *node_next(struct sparsebit *s, struct node *np)
+static struct node *node_next(const struct sparsebit *s, struct node *np)
 {
 	struct node *nodep = np;
 
@@ -244,7 +244,7 @@ static struct node *node_next(struct sparsebit *s, struct node *np)
  * highest index < the index of the node pointed to by np.
  * Returns NULL if no node with a lower index exists.
  */
-static struct node *node_prev(struct sparsebit *s, struct node *np)
+static struct node *node_prev(const struct sparsebit *s, struct node *np)
 {
 	struct node *nodep = np;
 
@@ -273,7 +273,7 @@ static struct node *node_prev(struct sparsebit *s, struct node *np)
  * subtree and duplicates the bit settings to the newly allocated nodes.
  * Returns the newly allocated copy of subtree.
  */
-static struct node *node_copy_subtree(struct node *subtree)
+static struct node *node_copy_subtree(const struct node *subtree)
 {
 	struct node *root;
 
@@ -307,7 +307,7 @@ static struct node *node_copy_subtree(struct node *subtree)
  * index is within the bits described by the mask bits or the number of
  * contiguous bits set after the mask.  Returns NULL if there is no such node.
  */
-static struct node *node_find(struct sparsebit *s, sparsebit_idx_t idx)
+static struct node *node_find(const struct sparsebit *s, sparsebit_idx_t idx)
 {
 	struct node *nodep;
 
@@ -393,7 +393,7 @@ static struct node *node_add(struct sparsebit *s, sparsebit_idx_t idx)
 }
 
 /* Returns whether all the bits in the sparsebit array are set.  */
-bool sparsebit_all_set(struct sparsebit *s)
+bool sparsebit_all_set(const struct sparsebit *s)
 {
 	/*
 	 * If any nodes there must be at least one bit set.  Only case
@@ -775,7 +775,7 @@ static void node_reduce(struct sparsebit *s, struct node *nodep)
 /* Returns whether the bit at the index given by idx, within the
  * sparsebit array is set or not.
  */
-bool sparsebit_is_set(struct sparsebit *s, sparsebit_idx_t idx)
+bool sparsebit_is_set(const struct sparsebit *s, sparsebit_idx_t idx)
 {
 	struct node *nodep;
 
@@ -921,7 +921,7 @@ static inline sparsebit_idx_t node_first_clear(struct node *nodep, int start)
  * used by test cases after they detect an unexpected condition, as a means
  * to capture diagnostic information.
  */
-static void sparsebit_dump_internal(FILE *stream, struct sparsebit *s,
+static void sparsebit_dump_internal(FILE *stream, const struct sparsebit *s,
 	unsigned int indent)
 {
 	/* Dump the contents of s */
@@ -969,7 +969,7 @@ void sparsebit_free(struct sparsebit **sbitp)
  * sparsebit_alloc().  It can though already have bits set, which
  * if different from src will be cleared.
  */
-void sparsebit_copy(struct sparsebit *d, struct sparsebit *s)
+void sparsebit_copy(struct sparsebit *d, const struct sparsebit *s)
 {
 	/* First clear any bits already set in the destination */
 	sparsebit_clear_all(d);
@@ -981,7 +981,7 @@ void sparsebit_copy(struct sparsebit *d, struct sparsebit *s)
 }
 
 /* Returns whether num consecutive bits starting at idx are all set.  */
-bool sparsebit_is_set_num(struct sparsebit *s,
+bool sparsebit_is_set_num(const struct sparsebit *s,
 	sparsebit_idx_t idx, sparsebit_num_t num)
 {
 	sparsebit_idx_t next_cleared;
@@ -1005,14 +1005,14 @@ bool sparsebit_is_set_num(struct sparsebit *s,
 }
 
 /* Returns whether the bit at the index given by idx.  */
-bool sparsebit_is_clear(struct sparsebit *s,
+bool sparsebit_is_clear(const struct sparsebit *s,
 	sparsebit_idx_t idx)
 {
 	return !sparsebit_is_set(s, idx);
 }
 
 /* Returns whether num consecutive bits starting at idx are all cleared.  */
-bool sparsebit_is_clear_num(struct sparsebit *s,
+bool sparsebit_is_clear_num(const struct sparsebit *s,
 	sparsebit_idx_t idx, sparsebit_num_t num)
 {
 	sparsebit_idx_t next_set;
@@ -1041,13 +1041,13 @@ bool sparsebit_is_clear_num(struct sparsebit *s,
  * value.  Use sparsebit_any_set(), instead of sparsebit_num_set() > 0,
  * to determine if the sparsebit array has any bits set.
  */
-sparsebit_num_t sparsebit_num_set(struct sparsebit *s)
+sparsebit_num_t sparsebit_num_set(const struct sparsebit *s)
 {
 	return s->num_set;
 }
 
 /* Returns whether any bit is set in the sparsebit array.  */
-bool sparsebit_any_set(struct sparsebit *s)
+bool sparsebit_any_set(const struct sparsebit *s)
 {
 	/*
 	 * Nodes only describe set bits.  If any nodes then there
@@ -1070,20 +1070,20 @@ bool sparsebit_any_set(struct sparsebit *s)
 }
 
 /* Returns whether all the bits in the sparsebit array are cleared.  */
-bool sparsebit_all_clear(struct sparsebit *s)
+bool sparsebit_all_clear(const struct sparsebit *s)
 {
 	return !sparsebit_any_set(s);
 }
 
 /* Returns whether all the bits in the sparsebit array are set.  */
-bool sparsebit_any_clear(struct sparsebit *s)
+bool sparsebit_any_clear(const struct sparsebit *s)
 {
 	return !sparsebit_all_set(s);
 }
 
 /* Returns the index of the first set bit.  Abort if no bits are set.
  */
-sparsebit_idx_t sparsebit_first_set(struct sparsebit *s)
+sparsebit_idx_t sparsebit_first_set(const struct sparsebit *s)
 {
 	struct node *nodep;
 
@@ -1097,7 +1097,7 @@ sparsebit_idx_t sparsebit_first_set(struct sparsebit *s)
 /* Returns the index of the first cleared bit.  Abort if
  * no bits are cleared.
  */
-sparsebit_idx_t sparsebit_first_clear(struct sparsebit *s)
+sparsebit_idx_t sparsebit_first_clear(const struct sparsebit *s)
 {
 	struct node *nodep1, *nodep2;
 
@@ -1151,7 +1151,7 @@ sparsebit_idx_t sparsebit_first_clear(struct sparsebit *s)
 /* Returns index of next bit set within s after the index given by prev.
  * Returns 0 if there are no bits after prev that are set.
  */
-sparsebit_idx_t sparsebit_next_set(struct sparsebit *s,
+sparsebit_idx_t sparsebit_next_set(const struct sparsebit *s,
 	sparsebit_idx_t prev)
 {
 	sparsebit_idx_t lowest_possible = prev + 1;
@@ -1244,7 +1244,7 @@ sparsebit_idx_t sparsebit_next_set(struct sparsebit *s,
 /* Returns index of next bit cleared within s after the index given by prev.
  * Returns 0 if there are no bits after prev that are cleared.
  */
-sparsebit_idx_t sparsebit_next_clear(struct sparsebit *s,
+sparsebit_idx_t sparsebit_next_clear(const struct sparsebit *s,
 	sparsebit_idx_t prev)
 {
 	sparsebit_idx_t lowest_possible = prev + 1;
@@ -1300,7 +1300,7 @@ sparsebit_idx_t sparsebit_next_clear(struct sparsebit *s,
  * and returns the index of the first sequence of num consecutively set
  * bits.  Returns a value of 0 of no such sequence exists.
  */
-sparsebit_idx_t sparsebit_next_set_num(struct sparsebit *s,
+sparsebit_idx_t sparsebit_next_set_num(const struct sparsebit *s,
 	sparsebit_idx_t start, sparsebit_num_t num)
 {
 	sparsebit_idx_t idx;
@@ -1335,7 +1335,7 @@ sparsebit_idx_t sparsebit_next_set_num(struct sparsebit *s,
  * and returns the index of the first sequence of num consecutively cleared
  * bits.  Returns a value of 0 of no such sequence exists.
  */
-sparsebit_idx_t sparsebit_next_clear_num(struct sparsebit *s,
+sparsebit_idx_t sparsebit_next_clear_num(const struct sparsebit *s,
 	sparsebit_idx_t start, sparsebit_num_t num)
 {
 	sparsebit_idx_t idx;
@@ -1583,7 +1583,7 @@ static size_t display_range(FILE *stream, sparsebit_idx_t low,
  * contiguous bits.  This is done because '-' is used to specify command-line
  * options, and sometimes ranges are specified as command-line arguments.
  */
-void sparsebit_dump(FILE *stream, struct sparsebit *s,
+void sparsebit_dump(FILE *stream, const struct sparsebit *s,
 	unsigned int indent)
 {
 	size_t current_line_len = 0;
@@ -1681,7 +1681,7 @@ void sparsebit_dump(FILE *stream, struct sparsebit *s,
  * s.  On error, diagnostic information is printed to stderr and
  * abort is called.
  */
-void sparsebit_validate_internal(struct sparsebit *s)
+void sparsebit_validate_internal(const struct sparsebit *s)
 {
 	bool error_detected = false;
 	struct node *nodep, *prev = NULL;
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:09 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:09 -0800
Subject: [PATCH v8 03/10] KVM: selftests: Add a macro to iterate over a
 sparsebit range
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <20240203000917.376631-4-seanjc@google.com>

From: Ackerley Tng <ackerleytng at google.com>

Add sparsebit_for_each_set_range() to allow iterator over a range of set
bits in a range.  This will be used by x86 SEV guests to process protected
physical pages (each such page needs to be encrypted _after_ being "added"
to the VM).

Signed-off-by: Ackerley Tng <ackerleytng at google.com>
[sean: split to separate patch]
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../testing/selftests/kvm/include/sparsebit.h | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/sparsebit.h b/tools/testing/selftests/kvm/include/sparsebit.h
index fb5170d57fcb..bc760761e1a3 100644
--- a/tools/testing/selftests/kvm/include/sparsebit.h
+++ b/tools/testing/selftests/kvm/include/sparsebit.h
@@ -66,6 +66,26 @@ void sparsebit_dump(FILE *stream, const struct sparsebit *sbit,
 		    unsigned int indent);
 void sparsebit_validate_internal(const struct sparsebit *sbit);
 
+/*
+ * Iterate over an inclusive ranges within sparsebit @s. In each iteration,
+ * @range_begin and @range_end will take the beginning and end of the set
+ * range, which are of type sparsebit_idx_t.
+ *
+ * For example, if the range [3, 7] (inclusive) is set, within the
+ * iteration, at range_begin will take the value 3 and @range_end will take
+ * the value 7.
+ *
+ * Ensure that there is at least one bit set before using this macro with
+ * sparsebit_any_set(), because sparsebit_first_set() will abort if none
+ * are set.
+ */
+#define sparsebit_for_each_set_range(s, range_begin, range_end)         \
+	for (range_begin = sparsebit_first_set(s),                      \
+	     range_end = sparsebit_next_clear(s, range_begin) - 1;	\
+	     range_begin && range_end;                                  \
+	     range_begin = sparsebit_next_set(s, range_end),            \
+	     range_end = sparsebit_next_clear(s, range_begin) - 1)
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:10 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:10 -0800
Subject: [PATCH v8 04/10] KVM: selftests: Add support for allocating/managing
 protected guest memory
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <20240203000917.376631-5-seanjc@google.com>

From: Peter Gonda <pgonda at google.com>

Add support for differentiating between protected (a.k.a. private, a.k.a.
encrypted) memory and normal (a.k.a. shared) memory for VMs that support
protected guest memory, e.g. x86's SEV.  Provide and manage a common
bitmap for tracking whether a given physical page resides in protected
memory, as support for protected memory isn't x86 specific, i.e. adding a
arch hook would be a net negative now, and in the future.

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerley Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Originally-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
Co-developed-by: Sean Christopherson <seanjc at google.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../selftests/kvm/include/kvm_util_base.h     | 25 +++++++++++++++++--
 tools/testing/selftests/kvm/lib/kvm_util.c    | 22 +++++++++++++---
 2 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index d9dc31af2f96..a82149305349 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -46,6 +46,7 @@ typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */
 struct userspace_mem_region {
 	struct kvm_userspace_memory_region2 region;
 	struct sparsebit *unused_phy_pages;
+	struct sparsebit *protected_phy_pages;
 	int fd;
 	off_t offset;
 	enum vm_mem_backing_src_type backing_src_type;
@@ -573,6 +574,13 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,
 		uint64_t guest_paddr, uint32_t slot, uint64_t npages,
 		uint32_t flags, int guest_memfd_fd, uint64_t guest_memfd_offset);
 
+#ifndef vm_arch_has_protected_memory
+static inline bool vm_arch_has_protected_memory(struct kvm_vm *vm)
+{
+	return false;
+}
+#endif
+
 void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags);
 void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa);
 void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot);
@@ -836,10 +844,23 @@ const char *exit_reason_str(unsigned int exit_reason);
 
 vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm, vm_paddr_t paddr_min,
 			     uint32_t memslot);
-vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
-			      vm_paddr_t paddr_min, uint32_t memslot);
+vm_paddr_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
+				vm_paddr_t paddr_min, uint32_t memslot,
+				bool protected);
 vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm);
 
+static inline vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
+					    vm_paddr_t paddr_min, uint32_t memslot)
+{
+	/*
+	 * By default, allocate memory as protected for VMs that support
+	 * protected memory, as the majority of memory for such VMs is
+	 * protected, i.e. using shared memory is effectively opt-in.
+	 */
+	return __vm_phy_pages_alloc(vm, num, paddr_min, memslot,
+				    vm_arch_has_protected_memory(vm));
+}
+
 /*
  * ____vm_create() does KVM_CREATE_VM and little else.  __vm_create() also
  * loads the test binary into guest memory and creates an IRQ chip (x86 only).
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index a53caf81eb87..ea677aa019ef 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -717,6 +717,7 @@ static void __vm_mem_region_delete(struct kvm_vm *vm,
 	vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION2, &region->region);
 
 	sparsebit_free(&region->unused_phy_pages);
+	sparsebit_free(&region->protected_phy_pages);
 	ret = munmap(region->mmap_start, region->mmap_size);
 	TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("munmap()", ret));
 	if (region->fd >= 0) {
@@ -1098,6 +1099,8 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,
 	}
 
 	region->unused_phy_pages = sparsebit_alloc();
+	if (vm_arch_has_protected_memory(vm))
+		region->protected_phy_pages = sparsebit_alloc();
 	sparsebit_set_num(region->unused_phy_pages,
 		guest_paddr >> vm->page_shift, npages);
 	region->region.slot = slot;
@@ -1924,6 +1927,10 @@ void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
 			region->host_mem);
 		fprintf(stream, "%*sunused_phy_pages: ", indent + 2, "");
 		sparsebit_dump(stream, region->unused_phy_pages, 0);
+		if (region->protected_phy_pages) {
+			fprintf(stream, "%*sprotected_phy_pages: ", indent + 2, "");
+			sparsebit_dump(stream, region->protected_phy_pages, 0);
+		}
 	}
 	fprintf(stream, "%*sMapped Virtual Pages:\n", indent, "");
 	sparsebit_dump(stream, vm->vpages_mapped, indent + 2);
@@ -2025,6 +2032,7 @@ const char *exit_reason_str(unsigned int exit_reason)
  *   num - number of pages
  *   paddr_min - Physical address minimum
  *   memslot - Memory region to allocate page from
+ *   protected - True if the pages will be used as protected/private memory
  *
  * Output Args: None
  *
@@ -2036,8 +2044,9 @@ const char *exit_reason_str(unsigned int exit_reason)
  * and their base address is returned. A TEST_ASSERT failure occurs if
  * not enough pages are available at or above paddr_min.
  */
-vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
-			      vm_paddr_t paddr_min, uint32_t memslot)
+vm_paddr_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
+				vm_paddr_t paddr_min, uint32_t memslot,
+				bool protected)
 {
 	struct userspace_mem_region *region;
 	sparsebit_idx_t pg, base;
@@ -2050,8 +2059,10 @@ vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
 		paddr_min, vm->page_size);
 
 	region = memslot2region(vm, memslot);
+	TEST_ASSERT(!protected || region->protected_phy_pages,
+		    "Region doesn't support protected memory");
+
 	base = pg = paddr_min >> vm->page_shift;
-
 	do {
 		for (; pg < base + num; ++pg) {
 			if (!sparsebit_is_set(region->unused_phy_pages, pg)) {
@@ -2070,8 +2081,11 @@ vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
 		abort();
 	}
 
-	for (pg = base; pg < base + num; ++pg)
+	for (pg = base; pg < base + num; ++pg) {
 		sparsebit_clear(region->unused_phy_pages, pg);
+		if (protected)
+			sparsebit_set(region->protected_phy_pages, pg);
+	}
 
 	return base * vm->page_size;
 }
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:11 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:11 -0800
Subject: [PATCH v8 05/10] KVM: selftests: Add support for protected vm_vaddr_* allocations
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <20240203000917.376631-6-seanjc@google.com>

From: Michael Roth <michael.roth at amd.com>

Test programs may wish to allocate shared vaddrs for things like
sharing memory with the guest. Since protected vms will have their
memory encrypted by default an interface is needed to explicitly
request shared pages.

Implement this by splitting the common code out from vm_vaddr_alloc()
and introducing a new vm_vaddr_alloc_shared().

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerly Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Signed-off-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../selftests/kvm/include/kvm_util_base.h     |  3 +++
 tools/testing/selftests/kvm/lib/kvm_util.c    | 26 +++++++++++++++----
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index a82149305349..cb3159af6db3 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -590,6 +590,9 @@ vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_mi
 vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min);
 vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
 			    enum kvm_mem_region_type type);
+vm_vaddr_t vm_vaddr_alloc_shared(struct kvm_vm *vm, size_t sz,
+				 vm_vaddr_t vaddr_min,
+				 enum kvm_mem_region_type type);
 vm_vaddr_t vm_vaddr_alloc_pages(struct kvm_vm *vm, int nr_pages);
 vm_vaddr_t __vm_vaddr_alloc_page(struct kvm_vm *vm,
 				 enum kvm_mem_region_type type);
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index ea677aa019ef..e7f4f84f2e68 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1431,15 +1431,17 @@ vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz,
 	return pgidx_start * vm->page_size;
 }
 
-vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
-			    enum kvm_mem_region_type type)
+static vm_vaddr_t ____vm_vaddr_alloc(struct kvm_vm *vm, size_t sz,
+				     vm_vaddr_t vaddr_min,
+				     enum kvm_mem_region_type type,
+				     bool protected)
 {
 	uint64_t pages = (sz >> vm->page_shift) + ((sz % vm->page_size) != 0);
 
 	virt_pgd_alloc(vm);
-	vm_paddr_t paddr = vm_phy_pages_alloc(vm, pages,
-					      KVM_UTIL_MIN_PFN * vm->page_size,
-					      vm->memslots[type]);
+	vm_paddr_t paddr = __vm_phy_pages_alloc(vm, pages,
+						KVM_UTIL_MIN_PFN * vm->page_size,
+						vm->memslots[type], protected);
 
 	/*
 	 * Find an unused range of virtual page addresses of at least
@@ -1459,6 +1461,20 @@ vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
 	return vaddr_start;
 }
 
+vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
+			    enum kvm_mem_region_type type)
+{
+	return ____vm_vaddr_alloc(vm, sz, vaddr_min, type,
+				  vm_arch_has_protected_memory(vm));
+}
+
+vm_vaddr_t vm_vaddr_alloc_shared(struct kvm_vm *vm, size_t sz,
+				 vm_vaddr_t vaddr_min,
+				 enum kvm_mem_region_type type)
+{
+	return ____vm_vaddr_alloc(vm, sz, vaddr_min, type, false);
+}
+
 /*
  * VM Virtual Address Allocate
  *
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:12 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:12 -0800
Subject: [PATCH v8 06/10] KVM: selftests: Explicitly ucall pool from shared memory
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <20240203000917.376631-7-seanjc@google.com>

From: Peter Gonda <pgonda at google.com>

Allocate the common ucall pool using vm_vaddr_alloc_shared() so that the
ucall structures will be placed in shared (unencrypted) memory for VMs
with support for protected (encrypted) memory, e.g. x86's SEV.

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerly Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
[sean: massage changelog]
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/lib/ucall_common.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c b/tools/testing/selftests/kvm/lib/ucall_common.c
index 816a3fa109bf..f5af65a41c29 100644
--- a/tools/testing/selftests/kvm/lib/ucall_common.c
+++ b/tools/testing/selftests/kvm/lib/ucall_common.c
@@ -29,7 +29,8 @@ void ucall_init(struct kvm_vm *vm, vm_paddr_t mmio_gpa)
 	vm_vaddr_t vaddr;
 	int i;
 
-	vaddr = __vm_vaddr_alloc(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR, MEM_REGION_DATA);
+	vaddr = vm_vaddr_alloc_shared(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR,
+				      MEM_REGION_DATA);
 	hdr = (struct ucall_header *)addr_gva2hva(vm, vaddr);
 	memset(hdr, 0, sizeof(*hdr));
 
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:13 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:13 -0800
Subject: [PATCH v8 07/10] KVM: selftests: Allow tagging protected memory in
 guest page tables
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <20240203000917.376631-8-seanjc@google.com>

From: Peter Gonda <pgonda at google.com>

Add support for tagging and untagging guest physical address, e.g. to
allow x86's SEV and TDX guests to embed shared vs. private information in
the GPA.  SEV (encryption, a.k.a. C-bit) and TDX (shared, a.k.a. S-bit)
steal bits from the guest's physical address space that is consumed by the
CPU metadata, i.e. effectively aliases the "real" GPA.

Implement generic "tagging" so that the shared vs. private metadata can be
managed by x86 without bleeding too many details into common code.

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerly Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Originally-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../kvm/include/aarch64/kvm_util_arch.h       |  7 +++++++
 .../selftests/kvm/include/kvm_util_base.h     | 13 ++++++++++++
 .../kvm/include/riscv/kvm_util_arch.h         |  7 +++++++
 .../kvm/include/s390x/kvm_util_arch.h         |  7 +++++++
 .../kvm/include/x86_64/kvm_util_arch.h        | 21 +++++++++++++++++++
 tools/testing/selftests/kvm/lib/kvm_util.c    | 17 +++++++++++++++
 .../selftests/kvm/lib/x86_64/processor.c      | 15 ++++++++++++-
 7 files changed, 86 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h

diff --git a/tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
new file mode 100644
index 000000000000..218f5cdf0d86
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _TOOLS_LINUX_ASM_ARM64_KVM_HOST_H
+#define _TOOLS_LINUX_ASM_ARM64_KVM_HOST_H
+
+struct kvm_vm_arch {};
+
+#endif  // _TOOLS_LINUX_ASM_ARM64_KVM_HOST_H
diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index cb3159af6db3..4b266dc0c9bd 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -18,9 +18,11 @@
 #include <linux/types.h>
 
 #include <asm/atomic.h>
+#include <asm/kvm.h>
 
 #include <sys/ioctl.h>
 
+#include "kvm_util_arch.h"
 #include "sparsebit.h"
 
 /*
@@ -113,6 +115,9 @@ struct kvm_vm {
 	vm_vaddr_t idt;
 	vm_vaddr_t handlers;
 	uint32_t dirty_ring_size;
+	uint64_t gpa_tag_mask;
+
+	struct kvm_vm_arch arch;
 
 	/* Cache of information for binary stats interface */
 	int stats_fd;
@@ -605,6 +610,12 @@ void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva);
 vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva);
 void *addr_gpa2alias(struct kvm_vm *vm, vm_paddr_t gpa);
 
+
+static inline vm_paddr_t vm_untag_gpa(struct kvm_vm *vm, vm_paddr_t gpa)
+{
+	return gpa & ~vm->gpa_tag_mask;
+}
+
 void vcpu_run(struct kvm_vcpu *vcpu);
 int _vcpu_run(struct kvm_vcpu *vcpu);
 
@@ -1114,4 +1125,6 @@ void kvm_selftest_arch_init(void);
 
 void kvm_arch_vm_post_create(struct kvm_vm *vm);
 
+bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr);
+
 #endif /* SELFTEST_KVM_UTIL_BASE_H */
diff --git a/tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h b/tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
new file mode 100644
index 000000000000..c8280d5659ce
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _TOOLS_LINUX_ASM_RISCV_KVM_HOST_H
+#define _TOOLS_LINUX_ASM_RISCV_KVM_HOST_H
+
+struct kvm_vm_arch {};
+
+#endif  // _TOOLS_LINUX_ASM_RISCV_KVM_HOST_H
diff --git a/tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h b/tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
new file mode 100644
index 000000000000..4c4c1c1e4bf8
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _TOOLS_LINUX_ASM_S390_KVM_HOST_H
+#define _TOOLS_LINUX_ASM_S390_KVM_HOST_H
+
+struct kvm_vm_arch {};
+
+#endif  // _TOOLS_LINUX_ASM_S390_KVM_HOST_H
diff --git a/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
new file mode 100644
index 000000000000..17bb38236d97
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _TOOLS_LINUX_ASM_X86_KVM_HOST_H
+#define _TOOLS_LINUX_ASM_X86_KVM_HOST_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+struct kvm_vm_arch {
+	uint64_t c_bit;
+	uint64_t s_bit;
+};
+
+static inline bool __vm_arch_has_protected_memory(struct kvm_vm_arch *arch)
+{
+	return arch->c_bit || arch->s_bit;
+}
+
+#define vm_arch_has_protected_memory(vm) \
+	__vm_arch_has_protected_memory(&(vm)->arch)
+
+#endif  // _TOOLS_LINUX_ASM_X86_KVM_HOST_H
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index e7f4f84f2e68..19511137d1ae 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1597,6 +1597,8 @@ void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa)
 {
 	struct userspace_mem_region *region;
 
+	gpa = vm_untag_gpa(vm, gpa);
+
 	region = userspace_mem_region_find(vm, gpa, gpa);
 	if (!region) {
 		TEST_FAIL("No vm physical memory at 0x%lx", gpa);
@@ -2305,3 +2307,18 @@ void __attribute((constructor)) kvm_selftest_init(void)
 
 	kvm_selftest_arch_init();
 }
+
+bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr)
+{
+	sparsebit_idx_t pg = 0;
+	struct userspace_mem_region *region;
+
+	if (!vm_arch_has_protected_memory(vm))
+		return false;
+
+	region = userspace_mem_region_find(vm, paddr, paddr);
+	TEST_ASSERT(region, "No vm physical memory at 0x%lx", paddr);
+
+	pg = paddr >> vm->page_shift;
+	return sparsebit_is_set(region->protected_phy_pages, pg);
+}
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
index 615d05247470..6c1d2c0ec584 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
@@ -157,6 +157,8 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *vm,
 {
 	uint64_t *pte = virt_get_pte(vm, parent_pte, vaddr, current_level);
 
+	paddr = vm_untag_gpa(vm, paddr);
+
 	if (!(*pte & PTE_PRESENT_MASK)) {
 		*pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK;
 		if (current_level == target_level)
@@ -200,6 +202,8 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level)
 		    "Physical address beyond maximum supported,\n"
 		    "  paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
 		    paddr, vm->max_gfn, vm->page_size);
+	TEST_ASSERT(vm_untag_gpa(vm, paddr) == paddr,
+		    "Unexpected bits in paddr: %lx", paddr);
 
 	/*
 	 * Allocate upper level page tables, if not already present.  Return
@@ -222,6 +226,15 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level)
 	TEST_ASSERT(!(*pte & PTE_PRESENT_MASK),
 		    "PTE already present for 4k page at vaddr: 0x%lx", vaddr);
 	*pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MASK);
+
+	/*
+	 * Neither SEV nor TDX supports shared page tables, so only the final
+	 * leaf PTE needs manually set the C/S-bit.
+	 */
+	if (vm_is_gpa_protected(vm, paddr))
+		*pte |= vm->arch.c_bit;
+	else
+		*pte |= vm->arch.s_bit;
 }
 
 void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr)
@@ -496,7 +509,7 @@ vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva)
 	 * No need for a hugepage mask on the PTE, x86-64 requires the "unused"
 	 * address bits to be zero.
 	 */
-	return PTE_GET_PA(*pte) | (gva & ~HUGEPAGE_MASK(level));
+	return vm_untag_gpa(vm, PTE_GET_PA(*pte)) | (gva & ~HUGEPAGE_MASK(level));
 }
 
 static void kvm_setup_gdt(struct kvm_vm *vm, struct kvm_dtable *dt)
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:14 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:14 -0800
Subject: [PATCH v8 08/10] KVM: selftests: Add library for creating and
 interacting with SEV guests
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <20240203000917.376631-9-seanjc@google.com>

From: Peter Gonda <pgonda at google.com>

Add a library/APIs for creating and interfacing with SEV guests, all of
which need some amount of common functionality, e.g. an open file handle
for the SEV driver (/dev/sev), ioctl() wrappers to pass said file handle
to KVM, tracking of the C-bit, etc.

Add an x86-specific hook to initialize address properties, a.k.a. the
location of the C-bit.  An arch specific hook is rather gross, but x86
already has a dedicated #ifdef-protected kvm_get_cpu_address_width() hook,
i.e. the ugliest code already exists.

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerly Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Originally-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
Co-developed-by: Sean Christopherson <seanjc at google.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/include/x86_64/kvm_util_arch.h        |   2 +
 .../selftests/kvm/include/x86_64/processor.h  |   8 ++
 .../selftests/kvm/include/x86_64/sev.h        | 110 +++++++++++++++
 tools/testing/selftests/kvm/lib/kvm_util.c    |   1 +
 .../selftests/kvm/lib/x86_64/processor.c      |  17 +++
 tools/testing/selftests/kvm/lib/x86_64/sev.c  | 128 ++++++++++++++++++
 7 files changed, 267 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/include/x86_64/sev.h
 create mode 100644 tools/testing/selftests/kvm/lib/x86_64/sev.c

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index ce58098d80fd..169b6ee8f733 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -38,6 +38,7 @@ LIBKVM_x86_64 += lib/x86_64/hyperv.c
 LIBKVM_x86_64 += lib/x86_64/memstress.c
 LIBKVM_x86_64 += lib/x86_64/pmu.c
 LIBKVM_x86_64 += lib/x86_64/processor.c
+LIBKVM_x86_64 += lib/x86_64/sev.c
 LIBKVM_x86_64 += lib/x86_64/svm.c
 LIBKVM_x86_64 += lib/x86_64/ucall.c
 LIBKVM_x86_64 += lib/x86_64/vmx.c
diff --git a/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
index 17bb38236d97..205ed788aeb8 100644
--- a/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
+++ b/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
@@ -8,6 +8,8 @@
 struct kvm_vm_arch {
 	uint64_t c_bit;
 	uint64_t s_bit;
+	int sev_fd;
+	bool is_pt_protected;
 };
 
 static inline bool __vm_arch_has_protected_memory(struct kvm_vm_arch *arch)
diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h
index 0f4792083d01..3bd03b088dda 100644
--- a/tools/testing/selftests/kvm/include/x86_64/processor.h
+++ b/tools/testing/selftests/kvm/include/x86_64/processor.h
@@ -23,6 +23,12 @@
 extern bool host_cpu_is_intel;
 extern bool host_cpu_is_amd;
 
+enum vm_guest_x86_subtype {
+	VM_SUBTYPE_NONE = 0,
+	VM_SUBTYPE_SEV,
+	VM_SUBTYPE_SEV_ES,
+};
+
 /* Forced emulation prefix, used to invoke the emulator unconditionally. */
 #define KVM_FEP "ud2; .byte 'k', 'v', 'm';"
 
@@ -276,6 +282,7 @@ struct kvm_x86_cpu_property {
 #define X86_PROPERTY_MAX_EXT_LEAF		KVM_X86_CPU_PROPERTY(0x80000000, 0, EAX, 0, 31)
 #define X86_PROPERTY_MAX_PHY_ADDR		KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 0, 7)
 #define X86_PROPERTY_MAX_VIRT_ADDR		KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 8, 15)
+#define X86_PROPERTY_SEV_C_BIT			KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 0, 5)
 #define X86_PROPERTY_PHYS_ADDR_REDUCTION	KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 6, 11)
 
 #define X86_PROPERTY_MAX_CENTAUR_LEAF		KVM_X86_CPU_PROPERTY(0xC0000000, 0, EAX, 0, 31)
@@ -1093,6 +1100,7 @@ do {											\
 } while (0)
 
 void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits);
+void kvm_init_vm_address_properties(struct kvm_vm *vm);
 bool vm_is_unrestricted_guest(struct kvm_vm *vm);
 
 struct ex_regs {
diff --git a/tools/testing/selftests/kvm/include/x86_64/sev.h b/tools/testing/selftests/kvm/include/x86_64/sev.h
new file mode 100644
index 000000000000..262b16f574e9
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/x86_64/sev.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Helpers used for SEV guests
+ *
+ */
+#ifndef SELFTEST_KVM_SEV_H
+#define SELFTEST_KVM_SEV_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "linux/psp-sev.h"
+
+#include "kvm_util.h"
+#include "svm_util.h"
+#include "processor.h"
+
+#define SEV_FW_REQ_VER_MAJOR 0
+#define SEV_FW_REQ_VER_MINOR 17
+
+enum sev_guest_state {
+	SEV_GUEST_STATE_UNINITIALIZED = 0,
+	SEV_GUEST_STATE_LAUNCH_UPDATE,
+	SEV_GUEST_STATE_LAUNCH_SECRET,
+	SEV_GUEST_STATE_RUNNING,
+};
+
+#define SEV_POLICY_NO_DBG	(1UL << 0)
+#define SEV_POLICY_ES		(1UL << 2)
+
+bool is_kvm_sev_supported(void);
+
+void sev_vm_launch(struct kvm_vm *vm, uint32_t policy);
+void sev_vm_launch_measure(struct kvm_vm *vm, uint8_t *measurement);
+void sev_vm_launch_finish(struct kvm_vm *vm);
+
+struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t policy, void *guest_code,
+					   struct kvm_vcpu **cpu);
+
+kvm_static_assert(SEV_RET_SUCCESS == 0);
+
+/*
+ * The KVM_MEMORY_ENCRYPT_OP uAPI is utter garbage and takes an "unsigned long"
+ * instead of a proper struct.  The size of the parameter is embedded in the
+ * ioctl number, i.e. is ABI and thus immutable.  Hack around the mess by
+ * creating an overlay to pass in an "unsigned long" without a cast (casting
+ * will make the compiler unhappy due to dereferencing an aliased pointer).
+ */
+#define __vm_sev_ioctl(vm, cmd, arg)					\
+({									\
+	int r;								\
+									\
+	union {								\
+		struct kvm_sev_cmd c;					\
+		unsigned long raw;					\
+	} sev_cmd = { .c = {						\
+		.id = (cmd),						\
+		.data = (uint64_t)(arg),				\
+		.sev_fd = (vm)->arch.sev_fd,				\
+	} };								\
+									\
+	r = __vm_ioctl(vm, KVM_MEMORY_ENCRYPT_OP, &sev_cmd.raw);	\
+	r ?: sev_cmd.c.error;						\
+})
+
+#define vm_sev_ioctl(vm, cmd, arg)					\
+({									\
+	int ret = __vm_sev_ioctl(vm, cmd, arg);				\
+									\
+	__TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd,	ret, vm);		\
+})
+
+static inline void sev_vm_init(struct kvm_vm *vm)
+{
+	vm->arch.sev_fd = open_sev_dev_path_or_exit();
+
+	vm_sev_ioctl(vm, KVM_SEV_INIT, NULL);
+}
+
+
+static inline void sev_es_vm_init(struct kvm_vm *vm)
+{
+	vm->arch.sev_fd = open_sev_dev_path_or_exit();
+
+	vm_sev_ioctl(vm, KVM_SEV_ES_INIT, NULL);
+}
+
+static inline void sev_register_encrypted_memory(struct kvm_vm *vm,
+						 struct userspace_mem_region *region)
+{
+	struct kvm_enc_region range = {
+		.addr = region->region.userspace_addr,
+		.size = region->region.memory_size,
+	};
+
+	vm_ioctl(vm, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
+}
+
+static inline void sev_launch_update_data(struct kvm_vm *vm, vm_paddr_t gpa,
+					  uint64_t size)
+{
+	struct kvm_sev_launch_update_data update_data = {
+		.uaddr = (unsigned long)addr_gpa2hva(vm, gpa),
+		.len = size,
+	};
+
+	vm_sev_ioctl(vm, KVM_SEV_LAUNCH_UPDATE_DATA, &update_data);
+}
+
+#endif /* SELFTEST_KVM_SEV_H */
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 19511137d1ae..b2262b5fad9e 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -317,6 +317,7 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
 	case VM_MODE_PXXV48_4K:
 #ifdef __x86_64__
 		kvm_get_cpu_address_width(&vm->pa_bits, &vm->va_bits);
+		kvm_init_vm_address_properties(vm);
 		/*
 		 * Ignore KVM support for 5-level paging (vm->va_bits == 57),
 		 * it doesn't take effect unless a CR4.LA57 is set, which it
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
index 6c1d2c0ec584..aa92220bf5da 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
@@ -9,6 +9,7 @@
 #include "test_util.h"
 #include "kvm_util.h"
 #include "processor.h"
+#include "sev.h"
 
 #ifndef NUM_INTERRUPTS
 #define NUM_INTERRUPTS 256
@@ -278,6 +279,9 @@ uint64_t *__vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr,
 {
 	uint64_t *pml4e, *pdpe, *pde;
 
+	TEST_ASSERT(!vm->arch.is_pt_protected,
+		    "Walking page tables of protected guests is impossible");
+
 	TEST_ASSERT(*level >= PG_LEVEL_NONE && *level < PG_LEVEL_NUM,
 		    "Invalid PG_LEVEL_* '%d'", *level);
 
@@ -573,6 +577,11 @@ void kvm_arch_vm_post_create(struct kvm_vm *vm)
 	vm_create_irqchip(vm);
 	sync_global_to_guest(vm, host_cpu_is_intel);
 	sync_global_to_guest(vm, host_cpu_is_amd);
+
+	if (vm->subtype == VM_SUBTYPE_SEV)
+		sev_vm_init(vm);
+	else if (vm->subtype == VM_SUBTYPE_SEV_ES)
+		sev_es_vm_init(vm);
 }
 
 struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id,
@@ -1063,6 +1072,14 @@ void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits)
 	}
 }
 
+void kvm_init_vm_address_properties(struct kvm_vm *vm)
+{
+	if (vm->subtype == VM_SUBTYPE_SEV) {
+		vm->arch.c_bit = BIT_ULL(this_cpu_property(X86_PROPERTY_SEV_C_BIT));
+		vm->gpa_tag_mask = vm->arch.c_bit;
+	}
+}
+
 static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr,
 			  int dpl, unsigned short selector)
 {
diff --git a/tools/testing/selftests/kvm/lib/x86_64/sev.c b/tools/testing/selftests/kvm/lib/x86_64/sev.c
new file mode 100644
index 000000000000..f37b1a7247ad
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/x86_64/sev.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#define _GNU_SOURCE /* for program_invocation_short_name */
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "sev.h"
+
+bool is_kvm_sev_supported(void)
+{
+	int sev_fd = open_sev_dev_path_or_exit();
+	struct sev_user_data_status sev_status;
+
+	struct sev_issue_cmd arg = {
+		.cmd = SEV_PLATFORM_STATUS,
+		.data = (unsigned long)&sev_status,
+	};
+
+	kvm_ioctl(sev_fd, SEV_ISSUE_CMD, &arg);
+	close(sev_fd);
+
+	return sev_status.api_major > SEV_FW_REQ_VER_MAJOR ||
+	       (sev_status.api_major == SEV_FW_REQ_VER_MAJOR &&
+		sev_status.api_minor >= SEV_FW_REQ_VER_MINOR);
+}
+
+/*
+ * sparsebit_next_clear() can return 0 if [x, 2**64-1] are all set, and the
+ * -1 would then cause an underflow back to 2**64 - 1. This is expected and
+ * correct.
+ *
+ * If the last range in the sparsebit is [x, y] and we try to iterate,
+ * sparsebit_next_set() will return 0, and sparsebit_next_clear() will try
+ * and find the first range, but that's correct because the condition
+ * expression would cause us to quit the loop.
+ */
+static void encrypt_region(struct kvm_vm *vm, struct userspace_mem_region *region)
+{
+	const struct sparsebit *protected_phy_pages = region->protected_phy_pages;
+	const vm_paddr_t gpa_base = region->region.guest_phys_addr;
+	const sparsebit_idx_t lowest_page_in_region = gpa_base >> vm->page_shift;
+	sparsebit_idx_t i, j;
+
+	if (!sparsebit_any_set(protected_phy_pages))
+		return;
+
+	sev_register_encrypted_memory(vm, region);
+
+	sparsebit_for_each_set_range(protected_phy_pages, i, j) {
+		const uint64_t size = (j - i + 1) * vm->page_size;
+		const uint64_t offset = (i - lowest_page_in_region) * vm->page_size;
+
+		sev_launch_update_data(vm, gpa_base + offset, size);
+	}
+}
+
+void sev_vm_launch(struct kvm_vm *vm, uint32_t policy)
+{
+	struct kvm_sev_launch_start launch_start = {
+		.policy = policy,
+	};
+	struct userspace_mem_region *region;
+	struct kvm_sev_guest_status status;
+	int ctr;
+
+	vm_sev_ioctl(vm, KVM_SEV_LAUNCH_START, &launch_start);
+	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &status);
+
+	TEST_ASSERT_EQ(status.policy, policy);
+	TEST_ASSERT_EQ(status.state, SEV_GUEST_STATE_LAUNCH_UPDATE);
+
+	hash_for_each(vm->regions.slot_hash, ctr, region, slot_node)
+		encrypt_region(vm, region);
+
+	vm->arch.is_pt_protected = true;
+}
+
+void sev_vm_launch_measure(struct kvm_vm *vm, uint8_t *measurement)
+{
+	struct kvm_sev_launch_measure launch_measure;
+	struct kvm_sev_guest_status guest_status;
+
+	launch_measure.len = 256;
+	launch_measure.uaddr = (__u64)measurement;
+	vm_sev_ioctl(vm, KVM_SEV_LAUNCH_MEASURE, &launch_measure);
+
+	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &guest_status);
+	TEST_ASSERT_EQ(guest_status.state, SEV_GUEST_STATE_LAUNCH_SECRET);
+}
+
+void sev_vm_launch_finish(struct kvm_vm *vm)
+{
+	struct kvm_sev_guest_status status;
+
+	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &status);
+	TEST_ASSERT(status.state == SEV_GUEST_STATE_LAUNCH_UPDATE ||
+		    status.state == SEV_GUEST_STATE_LAUNCH_SECRET,
+		    "Unexpected guest state: %d", status.state);
+
+	vm_sev_ioctl(vm, KVM_SEV_LAUNCH_FINISH, NULL);
+
+	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &status);
+	TEST_ASSERT_EQ(status.state, SEV_GUEST_STATE_RUNNING);
+}
+
+struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t policy, void *guest_code,
+					   struct kvm_vcpu **cpu)
+{
+	struct vm_shape shape = {
+		.type = VM_TYPE_DEFAULT,
+		.mode = VM_MODE_DEFAULT,
+		.subtype = VM_SUBTYPE_SEV,
+	};
+	struct kvm_vm *vm;
+	struct kvm_vcpu *cpus[1];
+	uint8_t measurement[512];
+
+	vm = __vm_create_with_vcpus(shape, 1, 0, guest_code, cpus);
+	*cpu = cpus[0];
+
+	sev_vm_launch(vm, policy);
+
+	/* TODO: Validate the measurement is as expected. */
+	sev_vm_launch_measure(vm, measurement);
+
+	sev_vm_launch_finish(vm);
+
+	return vm;
+}
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:15 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:15 -0800
Subject: [PATCH v8 09/10] KVM: selftests: Use the SEV library APIs in the
 intra-host migration test
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <20240203000917.376631-10-seanjc@google.com>

Port the existing intra-host SEV(-ES) migration test to the recently added
SEV library, which handles much of the boilerplate needed to create and
configure SEV guests.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../selftests/kvm/x86_64/sev_migrate_tests.c  | 67 ++++++-------------
 1 file changed, 21 insertions(+), 46 deletions(-)

diff --git a/tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c b/tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c
index a49828adf294..d6f7428e42c6 100644
--- a/tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c
+++ b/tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c
@@ -10,11 +10,9 @@
 #include "test_util.h"
 #include "kvm_util.h"
 #include "processor.h"
-#include "svm_util.h"
+#include "sev.h"
 #include "kselftest.h"
 
-#define SEV_POLICY_ES 0b100
-
 #define NR_MIGRATE_TEST_VCPUS 4
 #define NR_MIGRATE_TEST_VMS 3
 #define NR_LOCK_TESTING_THREADS 3
@@ -22,46 +20,24 @@
 
 bool have_sev_es;
 
-static int __sev_ioctl(int vm_fd, int cmd_id, void *data, __u32 *fw_error)
-{
-	struct kvm_sev_cmd cmd = {
-		.id = cmd_id,
-		.data = (uint64_t)data,
-		.sev_fd = open_sev_dev_path_or_exit(),
-	};
-	int ret;
-
-	ret = ioctl(vm_fd, KVM_MEMORY_ENCRYPT_OP, &cmd);
-	*fw_error = cmd.error;
-	return ret;
-}
-
-static void sev_ioctl(int vm_fd, int cmd_id, void *data)
-{
-	int ret;
-	__u32 fw_error;
-
-	ret = __sev_ioctl(vm_fd, cmd_id, data, &fw_error);
-	TEST_ASSERT(ret == 0 && fw_error == SEV_RET_SUCCESS,
-		    "%d failed: return code: %d, errno: %d, fw error: %d",
-		    cmd_id, ret, errno, fw_error);
-}
-
 static struct kvm_vm *sev_vm_create(bool es)
 {
 	struct kvm_vm *vm;
-	struct kvm_sev_launch_start start = { 0 };
 	int i;
 
 	vm = vm_create_barebones();
-	sev_ioctl(vm->fd, es ? KVM_SEV_ES_INIT : KVM_SEV_INIT, NULL);
+	if (!es)
+		sev_vm_init(vm);
+	else
+		sev_es_vm_init(vm);
+
 	for (i = 0; i < NR_MIGRATE_TEST_VCPUS; ++i)
 		__vm_vcpu_add(vm, i);
+
+	sev_vm_launch(vm, es ? SEV_POLICY_ES : 0);
+
 	if (es)
-		start.policy |= SEV_POLICY_ES;
-	sev_ioctl(vm->fd, KVM_SEV_LAUNCH_START, &start);
-	if (es)
-		sev_ioctl(vm->fd, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL);
+		vm_sev_ioctl(vm, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL);
 	return vm;
 }
 
@@ -181,7 +157,7 @@ static void test_sev_migrate_parameters(void)
 	sev_vm = sev_vm_create(/* es= */ false);
 	sev_es_vm = sev_vm_create(/* es= */ true);
 	sev_es_vm_no_vmsa = vm_create_barebones();
-	sev_ioctl(sev_es_vm_no_vmsa->fd, KVM_SEV_ES_INIT, NULL);
+	sev_es_vm_init(sev_es_vm_no_vmsa);
 	__vm_vcpu_add(sev_es_vm_no_vmsa, 1);
 
 	ret = __sev_migrate_from(sev_vm, sev_es_vm);
@@ -230,13 +206,13 @@ static void sev_mirror_create(struct kvm_vm *dst, struct kvm_vm *src)
 	TEST_ASSERT(!ret, "Copying context failed, ret: %d, errno: %d", ret, errno);
 }
 
-static void verify_mirror_allowed_cmds(int vm_fd)
+static void verify_mirror_allowed_cmds(struct kvm_vm *vm)
 {
 	struct kvm_sev_guest_status status;
+	int cmd_id;
 
-	for (int cmd_id = KVM_SEV_INIT; cmd_id < KVM_SEV_NR_MAX; ++cmd_id) {
+	for (cmd_id = KVM_SEV_INIT; cmd_id < KVM_SEV_NR_MAX; ++cmd_id) {
 		int ret;
-		__u32 fw_error;
 
 		/*
 		 * These commands are allowed for mirror VMs, all others are
@@ -256,14 +232,13 @@ static void verify_mirror_allowed_cmds(int vm_fd)
 		 * These commands should be disallowed before the data
 		 * parameter is examined so NULL is OK here.
 		 */
-		ret = __sev_ioctl(vm_fd, cmd_id, NULL, &fw_error);
-		TEST_ASSERT(
-			ret == -1 && errno == EINVAL,
-			"Should not be able call command: %d. ret: %d, errno: %d",
-			cmd_id, ret, errno);
+		ret = __vm_sev_ioctl(vm, cmd_id, NULL);
+		TEST_ASSERT(ret == -1 && errno == EINVAL,
+			    "Should not be able call command: %d. ret: %d, errno: %d",
+			    cmd_id, ret, errno);
 	}
 
-	sev_ioctl(vm_fd, KVM_SEV_GUEST_STATUS, &status);
+	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &status);
 }
 
 static void test_sev_mirror(bool es)
@@ -281,9 +256,9 @@ static void test_sev_mirror(bool es)
 		__vm_vcpu_add(dst_vm, i);
 
 	if (es)
-		sev_ioctl(dst_vm->fd, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL);
+		vm_sev_ioctl(dst_vm, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL);
 
-	verify_mirror_allowed_cmds(dst_vm->fd);
+	verify_mirror_allowed_cmds(dst_vm);
 
 	kvm_vm_free(src_vm);
 	kvm_vm_free(dst_vm);
-- 
2.43.0.594.gd9cf4e227d-goog



From seanjc at google.com  Fri Feb  2 16:09:16 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri,  2 Feb 2024 16:09:16 -0800
Subject: [PATCH v8 10/10] KVM: selftests: Add a basic SEV smoke test
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <20240203000917.376631-11-seanjc@google.com>

From: Peter Gonda <pgonda at google.com>

Add a basic smoke test for SEV guests to verify that KVM can launch an
SEV guest and run a few instructions without exploding.  To verify that
SEV is indeed enabled, assert that SEV is reported as enabled in
MSR_AMD64_SEV, a.k.a. SEV_STATUS, which cannot be intercepted by KVM
(architecturally enforced).

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerly Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Suggested-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
[sean: rename to "sev_smoke_test"]
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/Makefile          |  1 +
 .../selftests/kvm/x86_64/sev_smoke_test.c     | 58 +++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/x86_64/sev_smoke_test.c

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 169b6ee8f733..da20e6bb43ed 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -120,6 +120,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/vmx_pmu_caps_test
 TEST_GEN_PROGS_x86_64 += x86_64/xen_shinfo_test
 TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test
 TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests
+TEST_GEN_PROGS_x86_64 += x86_64/sev_smoke_test
 TEST_GEN_PROGS_x86_64 += x86_64/amx_test
 TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test
 TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test
diff --git a/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c b/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
new file mode 100644
index 000000000000..c1534efab2be
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "processor.h"
+#include "svm_util.h"
+#include "linux/psp-sev.h"
+#include "sev.h"
+
+static void guest_sev_code(void)
+{
+	GUEST_ASSERT(this_cpu_has(X86_FEATURE_SEV));
+	GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ENABLED);
+
+	GUEST_DONE();
+}
+
+static void test_sev(void *guest_code, uint64_t policy)
+{
+	struct kvm_vcpu *vcpu;
+	struct kvm_vm *vm;
+	struct ucall uc;
+
+	vm = vm_sev_create_with_one_vcpu(policy, guest_code, &vcpu);
+
+	for (;;) {
+		vcpu_run(vcpu);
+
+		switch (get_ucall(vcpu, &uc)) {
+		case UCALL_SYNC:
+			continue;
+		case UCALL_DONE:
+			return;
+		case UCALL_ABORT:
+			REPORT_GUEST_ASSERT(uc);
+		default:
+			TEST_FAIL("Unexpected exit: %s",
+				  exit_reason_str(vcpu->run->exit_reason));
+		}
+	}
+
+	kvm_vm_free(vm);
+}
+
+int main(int argc, char *argv[])
+{
+	TEST_REQUIRE(is_kvm_sev_supported());
+
+	test_sev(guest_sev_code, SEV_POLICY_NO_DBG);
+	test_sev(guest_sev_code, 0);
+
+	return 0;
+}
-- 
2.43.0.594.gd9cf4e227d-goog



From nathan at kernel.org  Fri Feb  2 16:17:03 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri, 2 Feb 2024 17:17:03 -0700
Subject: [PATCH linux-next 1/3] x86, crash: don't nest CONFIG_CRASH_DUMP
 ifdef inside CONFIG_KEXEC_CODE ifdef scope
In-Reply-To: <20240129135033.157195-1-bhe@redhat.com>
References: <20240129135033.157195-1-bhe@redhat.com>
Message-ID: <20240203001703.GA3735093@dev-arch.thelio-3990X>

This series resolves the build issues I was seeing. Please feel free to
carry

  Tested-by: Nathan Chancellor <nathan at kernel.org> # build

forward if there are any more revisions without drastic changes.

On Mon, Jan 29, 2024 at 09:50:31PM +0800, Baoquan He wrote:
> Michael pointed out that the #ifdef CONFIG_CRASH_DUMP is nested inside
> arch/x86/xen/enlighten_hvm.c.
> 
> Although the nesting works well too since CONFIG_CRASH_DUMP has
> dependency on CONFIG_KEXEC_CORE, it may cause confuse because there
> are places where it's not nested, and people may think it need be nested
> even though it doesn't have to.
> 
> Fix that by moving  CONFIG_CRASH_DUMP ifdeffery of codes out of
> CONFIG_KEXEC_CODE ifdeffery scope.
> 
> And also fix a building error Nathan reported as below by replacing
> CONFIG_KEXEC_CORE ifdef with CONFIG_VMCORE_INFO ifdef.
> 
> ====
> $ curl -LSso .config https://git.alpinelinux.org/aports/plain/community/linux-edge/config-edge.x86_64
> $ make -skj"$(nproc)" ARCH=x86_64 CROSS_COMPILE=x86_64-linux- olddefconfig all
> ...
> x86_64-linux-ld: arch/x86/xen/mmu_pv.o: in function `paddr_vmcoreinfo_note':
> mmu_pv.c:(.text+0x3af3): undefined reference to `vmcoreinfo_note'
> ====
> 
> Link: https://lore.kernel.org/all/SN6PR02MB4157931105FA68D72E3D3DB8D47B2 at SN6PR02MB4157.namprd02.prod.outlook.com/T/#u
> Link: https://lore.kernel.org/all/20240126045551.GA126645 at dev-arch.thelio-3990X/T/#u
> Signed-off-by: Baoquan He <bhe at redhat.com>
> ---
>  arch/x86/kernel/cpu/mshyperv.c | 10 ++++++----
>  arch/x86/kernel/reboot.c       |  2 +-
>  arch/x86/xen/enlighten_hvm.c   |  4 ++--
>  arch/x86/xen/mmu_pv.c          |  2 +-
>  4 files changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
> index f8163a59026b..2e8cd5a4ae85 100644
> --- a/arch/x86/kernel/cpu/mshyperv.c
> +++ b/arch/x86/kernel/cpu/mshyperv.c
> @@ -209,6 +209,7 @@ static void hv_machine_shutdown(void)
>  	if (kexec_in_progress)
>  		hyperv_cleanup();
>  }
> +#endif /* CONFIG_KEXEC_CORE */
>  
>  #ifdef CONFIG_CRASH_DUMP
>  static void hv_machine_crash_shutdown(struct pt_regs *regs)
> @@ -222,8 +223,7 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs)
>  	/* Disable the hypercall page when there is only 1 active CPU. */
>  	hyperv_cleanup();
>  }
> -#endif
> -#endif /* CONFIG_KEXEC_CORE */
> +#endif /* CONFIG_CRASH_DUMP */
>  #endif /* CONFIG_HYPERV */
>  
>  static uint32_t  __init ms_hyperv_platform(void)
> @@ -497,9 +497,11 @@ static void __init ms_hyperv_init_platform(void)
>  	no_timer_check = 1;
>  #endif
>  
> -#if IS_ENABLED(CONFIG_HYPERV) && defined(CONFIG_KEXEC_CORE)
> +#if IS_ENABLED(CONFIG_HYPERV)
> +#if defined(CONFIG_KEXEC_CORE)
>  	machine_ops.shutdown = hv_machine_shutdown;
> -#ifdef CONFIG_CRASH_DUMP
> +#endif
> +#if defined(CONFIG_CRASH_DUMP)
>  	machine_ops.crash_shutdown = hv_machine_crash_shutdown;
>  #endif
>  #endif
> diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
> index 1287b0d5962f..f3130f762784 100644
> --- a/arch/x86/kernel/reboot.c
> +++ b/arch/x86/kernel/reboot.c
> @@ -826,7 +826,7 @@ void machine_halt(void)
>  	machine_ops.halt();
>  }
>  
> -#ifdef CONFIG_KEXEC_CORE
> +#ifdef CONFIG_CRASH_DUMP
>  void machine_crash_shutdown(struct pt_regs *regs)
>  {
>  	machine_ops.crash_shutdown(regs);
> diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
> index 09e3db7ff990..0b367c1e086d 100644
> --- a/arch/x86/xen/enlighten_hvm.c
> +++ b/arch/x86/xen/enlighten_hvm.c
> @@ -148,6 +148,7 @@ static void xen_hvm_shutdown(void)
>  	if (kexec_in_progress)
>  		xen_reboot(SHUTDOWN_soft_reset);
>  }
> +#endif
>  
>  #ifdef CONFIG_CRASH_DUMP
>  static void xen_hvm_crash_shutdown(struct pt_regs *regs)
> @@ -156,7 +157,6 @@ static void xen_hvm_crash_shutdown(struct pt_regs *regs)
>  	xen_reboot(SHUTDOWN_soft_reset);
>  }
>  #endif
> -#endif
>  
>  static int xen_cpu_up_prepare_hvm(unsigned int cpu)
>  {
> @@ -238,10 +238,10 @@ static void __init xen_hvm_guest_init(void)
>  
>  #ifdef CONFIG_KEXEC_CORE
>  	machine_ops.shutdown = xen_hvm_shutdown;
> +#endif
>  #ifdef CONFIG_CRASH_DUMP
>  	machine_ops.crash_shutdown = xen_hvm_crash_shutdown;
>  #endif
> -#endif
>  }
>  
>  static __init int xen_parse_nopv(char *arg)
> diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
> index 218773cfb009..e21974f2cf2d 100644
> --- a/arch/x86/xen/mmu_pv.c
> +++ b/arch/x86/xen/mmu_pv.c
> @@ -2520,7 +2520,7 @@ int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
>  }
>  EXPORT_SYMBOL_GPL(xen_remap_pfn);
>  
> -#ifdef CONFIG_KEXEC_CORE
> +#ifdef CONFIG_VMCORE_INFO
>  phys_addr_t paddr_vmcoreinfo_note(void)
>  {
>  	if (xen_pv_domain())
> -- 
> 2.41.0
> 


From william.zhang at broadcom.com  Fri Feb  2 16:28:21 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:21 -0800
Subject: [PATCH v4 00/12] dt-bindings: mtd: brcmnand: Updates for bcmbca SoCs
Message-ID: <20240203002834.171462-1-william.zhang@broadcom.com>

This patch series is an update from the previous version [1] after
exex_op support and fixes (patch 1 to 4 from the previous version.)

It updates all the BCMBCA SoC to support the nand controller and add
functions to handle BCMBCA specific needs on ECC and Write Protection
usage. The device tree document is also updated accordingly with the new
properties needed by the driver.

In addition there is a bug fix for exec_op helper functions and log
level adjustment on uncorrectable ECC error.

[1] https://lore.kernel.org/lkml/20230606231252.94838-1-william.zhang at broadcom.com/

Changes in v4:
- Split the yaml changes into three patches.
- Move the WP pin property to a new patch and change it to boolean type.
- Move ecc strap property to a new patch and remove some non-binding 
related text from the description
- Add a new patch for bcm4908 based router board dts update
- Move the board related dts setting from SoC dtsi to board dts
- Update the comments for ecc setting selection
- Use the new brcm,wp-not-connected property based on the dts binding
change
- Fix the commit id in the fixes tag
- Revert the log level change for correctable ecc error

Changes in v3:
- Update brcm,nand-use-wp description
- Revert the description change to BCM63168 SoC-specific NAND controller
- Updated bcmbca_read_data_bus comment

Changes in v2:
- Revert the new compatible string nand-bcmbca
- Drop the BCM63168 compatible fix to avoid any potential ABI
Incompatibility issue
- Simplify the explanation for brcm,nand-use-wp
- Keep the interrupt name requirement when interrupt number is specified
- Add nand controller node label for 4908 so it is consistent with other
SoC's and can be referenced by board dts file
- Drop the is_param argument to the read data bus function now that we
have the exec_op API to read the parameter page and ONFI data
- Minor cosmetic fixes
- Added patches 8, 9, 10 to patch series

David Regan (2):
  mtd: rawnand: brcmnand: exec_op helper functions return type fixes
  mtd: rawnand: brcmnand: update log level messages

William Zhang (10):
  dt-bindings: mtd: brcmnand: Updates for bcmbca SoCs
  dt-bindings: mtd: brcmnand: Add WP pin connection property
  dt-bindings: mtd: brcmnand: Add ecc strap property
  ARM: dts: broadcom: bcmbca: Add NAND controller node
  arm64: dts: broadcom: bcmbca: Add NAND controller node
  arm64: dts: broadcom: bcmbca: Update router boards
  mtd: rawnand: brcmnand: Rename bcm63138 nand driver
  mtd: rawnand: brcmnand: Add BCMBCA read data bus interface
  mtd: rawnand: brcmnand: Add support for getting ecc setting from strap
  mtd: rawnand: brcmnand: Support write protection setting from dts

 .../bindings/mtd/brcm,brcmnand.yaml           |  29 +++-
 arch/arm/boot/dts/broadcom/bcm47622.dtsi      |  14 ++
 arch/arm/boot/dts/broadcom/bcm63138.dtsi      |   7 +-
 arch/arm/boot/dts/broadcom/bcm63148.dtsi      |  14 ++
 arch/arm/boot/dts/broadcom/bcm63178.dtsi      |  14 ++
 arch/arm/boot/dts/broadcom/bcm6756.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm6846.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm6855.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm6878.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm947622.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm963138.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm963138dvt.dts   |  14 +-
 arch/arm/boot/dts/broadcom/bcm963148.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm963178.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm96756.dts       |  10 ++
 arch/arm/boot/dts/broadcom/bcm96846.dts       |  10 ++
 arch/arm/boot/dts/broadcom/bcm96855.dts       |  10 ++
 arch/arm/boot/dts/broadcom/bcm96878.dts       |  10 ++
 .../bcmbca/bcm4906-netgear-r8000p.dts         |   5 +
 .../bcmbca/bcm4906-tplink-archer-c2300-v1.dts |   5 +
 .../bcmbca/bcm4908-asus-gt-ac5300.dts         |   6 +-
 .../boot/dts/broadcom/bcmbca/bcm4908.dtsi     |   4 +-
 .../boot/dts/broadcom/bcmbca/bcm4912.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm63146.dtsi    |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm63158.dtsi    |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm6813.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm6856.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm6858.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm94908.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm94912.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm963146.dts    |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm963158.dts    |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm96813.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm96856.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm96858.dts     |  10 ++
 drivers/mtd/nand/raw/brcmnand/Makefile        |   2 +-
 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c |  99 --------------
 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c   | 126 ++++++++++++++++++
 drivers/mtd/nand/raw/brcmnand/brcmnand.c      | 126 +++++++++++++++---
 drivers/mtd/nand/raw/brcmnand/brcmnand.h      |   2 +
 40 files changed, 623 insertions(+), 134 deletions(-)
 delete mode 100644 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
 create mode 100644 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c

-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:22 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:22 -0800
Subject: [PATCH v4 01/12] dt-bindings: mtd: brcmnand: Updates for bcmbca SoCs
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-2-william.zhang@broadcom.com>

Update the descriptions to reflect different families of broadband SoC and
use the general name bcmbca for ARM based SoC.

Remove the requirement of interrupts property to reflect the driver
code and only require interrupt-names when interrupts property present.

Also add myself to the list of maintainers.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v4:
- Split the yaml changes into three patches. This is the first one.

Changes in v3:
- Update brcm,nand-use-wp description
- Revert the description change to BCM63168 SoC-specific NAND controller

Changes in v2:
- Revert the new compatible string nand-bcmbca
- Drop the BCM63168 compatible fix to avoid any potential ABI
incompatibility issue
- Simplify the explanation for brcm,nand-use-wp
- Keep the interrupt name requirement when interrupt number is specified

 .../devicetree/bindings/mtd/brcm,brcmnand.yaml      | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
index f57e96374e67..e54ca08a798a 100644
--- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
+++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
@@ -9,6 +9,7 @@ title: Broadcom STB NAND Controller
 maintainers:
   - Brian Norris <computersforpeace at gmail.com>
   - Kamal Dasu <kdasu.kdev at gmail.com>
+  - William Zhang <william.zhang at broadcom.com>
 
 description: |
   The Broadcom Set-Top Box NAND controller supports low-level access to raw NAND
@@ -18,9 +19,10 @@ description: |
   supports basic PROGRAM and READ functions, among other features.
 
   This controller was originally designed for STB SoCs (BCM7xxx) but is now
-  available on a variety of Broadcom SoCs, including some BCM3xxx, BCM63xx, and
-  iProc/Cygnus. Its history includes several similar (but not fully register
-  compatible) versions.
+  available on a variety of Broadcom SoCs, including some BCM3xxx, MIPS based
+  Broadband SoC (BCM63xx), ARM based Broadband SoC (BCMBCA) and iProc/Cygnus.
+  Its history includes several similar (but not fully register compatible)
+  versions.
 
   -- Additional SoC-specific NAND controller properties --
 
@@ -53,7 +55,7 @@ properties:
               - brcm,brcmnand-v7.2
               - brcm,brcmnand-v7.3
           - const: brcm,brcmnand
-      - description: BCM63138 SoC-specific NAND controller
+      - description: BCMBCA SoC-specific NAND controller
         items:
           - const: brcm,nand-bcm63138
           - enum:
@@ -177,6 +179,8 @@ allOf:
             - const: iproc-idm
             - const: iproc-ext
   - if:
+      required:
+        - interrupts
       properties:
         interrupts:
           minItems: 2
@@ -189,7 +193,6 @@ unevaluatedProperties: false
 required:
   - reg
   - reg-names
-  - interrupts
 
 examples:
   - |
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:23 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:23 -0800
Subject: [PATCH v4 02/12] dt-bindings: mtd: brcmnand: Add WP pin connection property
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-3-william.zhang@broadcom.com>

Add brcm,wp-not-connected property to have an option for disabling this
feature on broadband board design that does not connect WP pin.

Signed-off-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v4:
- Move the WP pin property to this separate patch and change it to
boolean type.

Changes in v3: None
Changes in v2: None

 Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
index e54ca08a798a..d0168d55c73e 100644
--- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
+++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
@@ -113,6 +113,14 @@ properties:
       earlier versions of this core that include WP
     type: boolean
 
+  brcm,wp-not-connected:
+    description:
+      Use this property when board design does not connect controller's
+      NAND_WPb pin to NAND chip's WP_L pin and disable the write
+      protection feature. By default, controller assumes the pin is
+      connected and feature is used.
+    $ref: /schemas/types.yaml#/definitions/flag
+
 patternProperties:
   "^nand@[a-f0-9]$":
     type: object
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:24 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:24 -0800
Subject: [PATCH v4 03/12] dt-bindings: mtd: brcmnand: Add ecc strap property
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-4-william.zhang@broadcom.com>

Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
board boot strap for broadband board designs because they do not specify
ecc setting in dts but rather using the strap setting.

Signed-off-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v4:
- Move ecc strap property to this separate patch and remove some
non-binding related text from the description

Changes in v3: None
Changes in v2: None

 Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
index d0168d55c73e..2599d902ec3a 100644
--- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
+++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
@@ -147,6 +147,14 @@ patternProperties:
           layout.
         $ref: /schemas/types.yaml#/definitions/uint32
 
+      brcm,nand-ecc-use-strap:
+        description:
+          This flag indicates the ecc strength and spare area size should
+          be retrieved from the SoC NAND boot strap setting instead of
+          nand-ecc-strength and brcm,nand-oob-sector-size or auto detection.
+          This is commonly used by the BCMBCA SoC board design.
+        $ref: /schemas/types.yaml#/definitions/flag
+
     unevaluatedProperties: false
 
 allOf:
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:25 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:25 -0800
Subject: [PATCH v4 04/12] ARM: dts: broadcom: bcmbca: Add NAND controller node
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-5-william.zhang@broadcom.com>

Add support for Broadcom STB NAND controller in BCMBCA ARMv7 chip dts
files.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v4:
- Move the board related dts setting from SoC dtsi to board dts

Changes in v3: None
Changes in v2: None

 arch/arm/boot/dts/broadcom/bcm47622.dtsi    | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm63138.dtsi    |  7 ++++++-
 arch/arm/boot/dts/broadcom/bcm63148.dtsi    | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm63178.dtsi    | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6756.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6846.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6855.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6878.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm947622.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm963138.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm963138dvt.dts | 14 +++++++-------
 arch/arm/boot/dts/broadcom/bcm963148.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm963178.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96756.dts     | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96846.dts     | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96855.dts     | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96878.dts     | 10 ++++++++++
 17 files changed, 191 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/broadcom/bcm47622.dtsi b/arch/arm/boot/dts/broadcom/bcm47622.dtsi
index 7cd38de118c3..485863f9c420 100644
--- a/arch/arm/boot/dts/broadcom/bcm47622.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm47622.dtsi
@@ -138,6 +138,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm63138.dtsi b/arch/arm/boot/dts/broadcom/bcm63138.dtsi
index 4ef02283612b..e74ba6bf370d 100644
--- a/arch/arm/boot/dts/broadcom/bcm63138.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63138.dtsi
@@ -229,7 +229,12 @@ nand_controller: nand-controller at 2000 {
 			reg-names = "nand", "nand-int-base";
 			status = "disabled";
 			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "nand";
+			interrupt-names = "nand_ctlrdy";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
 		};
 
 		serial at 4400 {
diff --git a/arch/arm/boot/dts/broadcom/bcm63148.dtsi b/arch/arm/boot/dts/broadcom/bcm63148.dtsi
index 24431de1810e..53703827ee3f 100644
--- a/arch/arm/boot/dts/broadcom/bcm63148.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63148.dtsi
@@ -119,5 +119,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 2000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x2000 0x600>, <0xf0 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/broadcom/bcm63178.dtsi b/arch/arm/boot/dts/broadcom/bcm63178.dtsi
index 3f9aed96babf..6d8d33498983 100644
--- a/arch/arm/boot/dts/broadcom/bcm63178.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63178.dtsi
@@ -129,6 +129,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6756.dtsi b/arch/arm/boot/dts/broadcom/bcm6756.dtsi
index 1d8d957d65dd..6433f8fa5eff 100644
--- a/arch/arm/boot/dts/broadcom/bcm6756.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6756.dtsi
@@ -139,6 +139,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6846.dtsi b/arch/arm/boot/dts/broadcom/bcm6846.dtsi
index cf92cf8c4693..ee361cb00b7c 100644
--- a/arch/arm/boot/dts/broadcom/bcm6846.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6846.dtsi
@@ -119,5 +119,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/broadcom/bcm6855.dtsi b/arch/arm/boot/dts/broadcom/bcm6855.dtsi
index 52d6bc89f9f8..52915ec6f339 100644
--- a/arch/arm/boot/dts/broadcom/bcm6855.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6855.dtsi
@@ -129,6 +129,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6878.dtsi b/arch/arm/boot/dts/broadcom/bcm6878.dtsi
index 2c5d706bac7e..70cf23a65fdb 100644
--- a/arch/arm/boot/dts/broadcom/bcm6878.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6878.dtsi
@@ -120,6 +120,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm947622.dts b/arch/arm/boot/dts/broadcom/bcm947622.dts
index 93b8ce22678d..6241485408d3 100644
--- a/arch/arm/boot/dts/broadcom/bcm947622.dts
+++ b/arch/arm/boot/dts/broadcom/bcm947622.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963138.dts b/arch/arm/boot/dts/broadcom/bcm963138.dts
index 1b405c249213..7fd87e05ec20 100644
--- a/arch/arm/boot/dts/broadcom/bcm963138.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963138.dts
@@ -29,3 +29,13 @@ &serial0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963138dvt.dts b/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
index b5af61853a07..f60d09908ab9 100644
--- a/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
@@ -32,15 +32,15 @@ &serial1 {
 };
 
 &nand_controller {
+	brcm,wp-not-connected;
 	status = "okay";
+};
 
-	nand at 0 {
-		compatible = "brcm,nandcs";
-		reg = <0>;
-		nand-ecc-strength = <4>;
-		nand-ecc-step-size = <512>;
-		brcm,nand-oob-sectors-size = <16>;
-	};
+&nandcs {
+	nand-ecc-strength = <4>;
+	nand-ecc-step-size = <512>;
+	brcm,nand-oob-sector-size = <16>;
+	nand-on-flash-bbt;
 };
 
 &ahci {
diff --git a/arch/arm/boot/dts/broadcom/bcm963148.dts b/arch/arm/boot/dts/broadcom/bcm963148.dts
index 1f5d6d783f09..44bca063a327 100644
--- a/arch/arm/boot/dts/broadcom/bcm963148.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963148.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963178.dts b/arch/arm/boot/dts/broadcom/bcm963178.dts
index d036e99dd8d1..098a222cd71a 100644
--- a/arch/arm/boot/dts/broadcom/bcm963178.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963178.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96756.dts b/arch/arm/boot/dts/broadcom/bcm96756.dts
index 8b104f3fb14a..402038d3cd0c 100644
--- a/arch/arm/boot/dts/broadcom/bcm96756.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96756.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96846.dts b/arch/arm/boot/dts/broadcom/bcm96846.dts
index 55852c229608..943896afb7cc 100644
--- a/arch/arm/boot/dts/broadcom/bcm96846.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96846.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96855.dts b/arch/arm/boot/dts/broadcom/bcm96855.dts
index 2ad880af2104..571663d9a1ea 100644
--- a/arch/arm/boot/dts/broadcom/bcm96855.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96855.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96878.dts b/arch/arm/boot/dts/broadcom/bcm96878.dts
index b7af8ade7a9d..8d6eddd54c6e 100644
--- a/arch/arm/boot/dts/broadcom/bcm96878.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96878.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:26 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:26 -0800
Subject: [PATCH v4 05/12] arm64: dts: broadcom: bcmbca: Add NAND controller node
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-6-william.zhang@broadcom.com>

Add support for Broadcom STB NAND controller in BCMBCA ARMv8 chip dts
files.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v4:
- Move the board related dts setting from SoC dtsi to board dts

Changes in v3: None
Changes in v2:
- Add nand controller node label for 4908 so it is consistent with other
SoCs and can be referenced by board dts file

 arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi  |  4 ++--
 arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts  | 10 ++++++++++
 14 files changed, 156 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
index 2f124b027bbf..336016e334d9 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
@@ -589,7 +589,7 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
-		nand-controller at 1800 {
+		nand_controller: nand-controller at 1800 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
@@ -597,7 +597,7 @@ nand-controller at 1800 {
 			reg-names = "nand", "nand-int-base";
 			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "nand_ctlrdy";
-			status = "okay";
+			status = "disabled";
 
 			nandcs: nand at 0 {
 				compatible = "brcm,nandcs";
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
index d658c81f7285..14b2adfb817c 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
@@ -138,6 +138,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
index 4f474d47022e..589b8a1efc72 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
@@ -119,6 +119,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
index 909f254dc47d..48d618e75866 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
@@ -137,6 +137,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
index 685ae32951c9..1d1303cf90f3 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
@@ -138,6 +138,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
index 820553ce541b..00c62c1e5df0 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
@@ -119,5 +119,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
index 0eb93c298297..caeaf428dc15 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
@@ -156,5 +156,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
index c4e6e71f6310..030ffa5364fb 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
index e69cd683211a..4b779e6c22e1 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
index db2c82d6dfd8..2851e8e41bf4 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
index 25c12bc63545..17dc594fe83f 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
index faba21f03120..34832a734734 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
index 9808331eede2..e1396b5544b7 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
index 1f561c8e13b0..30bbf6f2917e 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:27 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:27 -0800
Subject: [PATCH v4 06/12] arm64: dts: broadcom: bcmbca: Update router boards
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-7-william.zhang@broadcom.com>

Enable the nand controller and add WP pin connection property in actual
board dts as they are board level properties now that they are disabled
and moved out from SoC dtsi.

Also remove the unnecessary brcm,nand-has-wp property from AC5300 board.
This property is only needed for some old controller that this board
does not apply.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 .../boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts     | 5 +++++
 .../dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts  | 5 +++++
 .../boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts     | 6 +++++-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
index 78204d71ecd2..999d93730240 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
@@ -125,6 +125,11 @@ port at 7 {
 	};
 };
 
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
 &nandcs {
 	nand-ecc-strength = <4>;
 	nand-ecc-step-size = <512>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
index fcf092c81b59..19fc03ef47a0 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
@@ -155,6 +155,11 @@ port at 7 {
 	};
 };
 
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
 &nandcs {
 	nand-ecc-strength = <4>;
 	nand-ecc-step-size = <512>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
index d94a53d68320..52f928dbfa3c 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
@@ -166,11 +166,15 @@ led at 19 {
 	};
 };
 
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
 &nandcs {
 	nand-ecc-strength = <4>;
 	nand-ecc-step-size = <512>;
 	nand-on-flash-bbt;
-	brcm,nand-has-wp;
 
 	#address-cells = <1>;
 	#size-cells = <0>;
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:28 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:28 -0800
Subject: [PATCH v4 07/12] mtd: rawnand: brcmnand: Rename bcm63138 nand driver
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-8-william.zhang@broadcom.com>

In preparing to support multiple BCMBCA SoCs, rename bcm63138 to bcmbca
in the driver code and driver file name.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>
Acked-by: Florian Fainelli <florian.fainelli at broadcom.com>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/mtd/nand/raw/brcmnand/Makefile        |  2 +-
 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c | 99 -------------------
 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c   | 99 +++++++++++++++++++
 3 files changed, 100 insertions(+), 100 deletions(-)
 delete mode 100644 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
 create mode 100644 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c

diff --git a/drivers/mtd/nand/raw/brcmnand/Makefile b/drivers/mtd/nand/raw/brcmnand/Makefile
index 9907e3ec4bb2..0536568c6467 100644
--- a/drivers/mtd/nand/raw/brcmnand/Makefile
+++ b/drivers/mtd/nand/raw/brcmnand/Makefile
@@ -2,7 +2,7 @@
 # link order matters; don't link the more generic brcmstb_nand.o before the
 # more specific iproc_nand.o, for instance
 obj-$(CONFIG_MTD_NAND_BRCMNAND_IPROC)	+= iproc_nand.o
-obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMBCA)	+= bcm63138_nand.o
+obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMBCA)	+= bcmbca_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND_BCM63XX)	+= bcm6368_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND_BRCMSTB)	+= brcmstb_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmnand.o
diff --git a/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c b/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
deleted file mode 100644
index 968c5b674b08..000000000000
--- a/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
+++ /dev/null
@@ -1,99 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright ? 2015 Broadcom Corporation
- */
-
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include "brcmnand.h"
-
-struct bcm63138_nand_soc {
-	struct brcmnand_soc soc;
-	void __iomem *base;
-};
-
-#define BCM63138_NAND_INT_STATUS		0x00
-#define BCM63138_NAND_INT_EN			0x04
-
-enum {
-	BCM63138_CTLRDY		= BIT(4),
-};
-
-static bool bcm63138_nand_intc_ack(struct brcmnand_soc *soc)
-{
-	struct bcm63138_nand_soc *priv =
-			container_of(soc, struct bcm63138_nand_soc, soc);
-	void __iomem *mmio = priv->base + BCM63138_NAND_INT_STATUS;
-	u32 val = brcmnand_readl(mmio);
-
-	if (val & BCM63138_CTLRDY) {
-		brcmnand_writel(val & ~BCM63138_CTLRDY, mmio);
-		return true;
-	}
-
-	return false;
-}
-
-static void bcm63138_nand_intc_set(struct brcmnand_soc *soc, bool en)
-{
-	struct bcm63138_nand_soc *priv =
-			container_of(soc, struct bcm63138_nand_soc, soc);
-	void __iomem *mmio = priv->base + BCM63138_NAND_INT_EN;
-	u32 val = brcmnand_readl(mmio);
-
-	if (en)
-		val |= BCM63138_CTLRDY;
-	else
-		val &= ~BCM63138_CTLRDY;
-
-	brcmnand_writel(val, mmio);
-}
-
-static int bcm63138_nand_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct bcm63138_nand_soc *priv;
-	struct brcmnand_soc *soc;
-
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-	soc = &priv->soc;
-
-	priv->base = devm_platform_ioremap_resource_byname(pdev, "nand-int-base");
-	if (IS_ERR(priv->base))
-		return PTR_ERR(priv->base);
-
-	soc->ctlrdy_ack = bcm63138_nand_intc_ack;
-	soc->ctlrdy_set_enabled = bcm63138_nand_intc_set;
-
-	return brcmnand_probe(pdev, soc);
-}
-
-static const struct of_device_id bcm63138_nand_of_match[] = {
-	{ .compatible = "brcm,nand-bcm63138" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, bcm63138_nand_of_match);
-
-static struct platform_driver bcm63138_nand_driver = {
-	.probe			= bcm63138_nand_probe,
-	.remove_new		= brcmnand_remove,
-	.driver = {
-		.name		= "bcm63138_nand",
-		.pm		= &brcmnand_pm_ops,
-		.of_match_table	= bcm63138_nand_of_match,
-	}
-};
-module_platform_driver(bcm63138_nand_driver);
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Brian Norris");
-MODULE_DESCRIPTION("NAND driver for BCM63138");
diff --git a/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
new file mode 100644
index 000000000000..3e2f3b79788d
--- /dev/null
+++ b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright ? 2015 Broadcom Corporation
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "brcmnand.h"
+
+struct bcmbca_nand_soc {
+	struct brcmnand_soc soc;
+	void __iomem *base;
+};
+
+#define BCMBCA_NAND_INT_STATUS		0x00
+#define BCMBCA_NAND_INT_EN			0x04
+
+enum {
+	BCMBCA_CTLRDY		= BIT(4),
+};
+
+static bool bcmbca_nand_intc_ack(struct brcmnand_soc *soc)
+{
+	struct bcmbca_nand_soc *priv =
+			container_of(soc, struct bcmbca_nand_soc, soc);
+	void __iomem *mmio = priv->base + BCMBCA_NAND_INT_STATUS;
+	u32 val = brcmnand_readl(mmio);
+
+	if (val & BCMBCA_CTLRDY) {
+		brcmnand_writel(val & ~BCMBCA_CTLRDY, mmio);
+		return true;
+	}
+
+	return false;
+}
+
+static void bcmbca_nand_intc_set(struct brcmnand_soc *soc, bool en)
+{
+	struct bcmbca_nand_soc *priv =
+			container_of(soc, struct bcmbca_nand_soc, soc);
+	void __iomem *mmio = priv->base + BCMBCA_NAND_INT_EN;
+	u32 val = brcmnand_readl(mmio);
+
+	if (en)
+		val |= BCMBCA_CTLRDY;
+	else
+		val &= ~BCMBCA_CTLRDY;
+
+	brcmnand_writel(val, mmio);
+}
+
+static int bcmbca_nand_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct bcmbca_nand_soc *priv;
+	struct brcmnand_soc *soc;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	soc = &priv->soc;
+
+	priv->base = devm_platform_ioremap_resource_byname(pdev, "nand-int-base");
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	soc->ctlrdy_ack = bcmbca_nand_intc_ack;
+	soc->ctlrdy_set_enabled = bcmbca_nand_intc_set;
+
+	return brcmnand_probe(pdev, soc);
+}
+
+static const struct of_device_id bcmbca_nand_of_match[] = {
+	{ .compatible = "brcm,nand-bcm63138" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcmbca_nand_of_match);
+
+static struct platform_driver bcmbca_nand_driver = {
+	.probe			= bcmbca_nand_probe,
+	.remove_new		= brcmnand_remove,
+	.driver = {
+		.name		= "bcmbca_nand",
+		.pm		= &brcmnand_pm_ops,
+		.of_match_table	= bcmbca_nand_of_match,
+	}
+};
+module_platform_driver(bcmbca_nand_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Brian Norris");
+MODULE_DESCRIPTION("NAND driver for BCMBCA");
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:29 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:29 -0800
Subject: [PATCH v4 08/12] mtd: rawnand: brcmnand: Add BCMBCA read data bus interface
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-9-william.zhang@broadcom.com>

The BCMBCA broadband SoC integrates the NAND controller differently than
STB, iProc and other SoCs.  It has different endianness for NAND cache
data.

Add a SoC read data bus shim for BCMBCA to meet the specific SoC need
and performance improvement using the optimized memcpy function on NAND
cache memory.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v4: None
Changes in v3:
- Updated bcmbca_read_data_bus comment

Changes in v2:
- Drop the is_param argument to the read data bus function now that we
have the exec_op API to read the parameter page and ONFI data
- Remove be32_to_cpu from brcmnand_read_data_bus

 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c | 27 +++++++++++++++++++++
 drivers/mtd/nand/raw/brcmnand/brcmnand.c    | 20 ++++++++++++---
 drivers/mtd/nand/raw/brcmnand/brcmnand.h    |  2 ++
 3 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
index 3e2f3b79788d..7ad3e7a98f97 100644
--- a/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
+++ b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
@@ -26,6 +26,18 @@ enum {
 	BCMBCA_CTLRDY		= BIT(4),
 };
 
+#if defined(CONFIG_ARM64)
+#define ALIGN_REQ		8
+#else
+#define ALIGN_REQ		4
+#endif
+
+static inline bool bcmbca_nand_is_buf_aligned(void *flash_cache,  void *buffer)
+{
+	return IS_ALIGNED((uintptr_t)buffer, ALIGN_REQ) &&
+				IS_ALIGNED((uintptr_t)flash_cache, ALIGN_REQ);
+}
+
 static bool bcmbca_nand_intc_ack(struct brcmnand_soc *soc)
 {
 	struct bcmbca_nand_soc *priv =
@@ -56,6 +68,20 @@ static void bcmbca_nand_intc_set(struct brcmnand_soc *soc, bool en)
 	brcmnand_writel(val, mmio);
 }
 
+static void bcmbca_read_data_bus(struct brcmnand_soc *soc,
+				 void __iomem *flash_cache,  u32 *buffer, int fc_words)
+{
+	/*
+	 * memcpy can do unaligned aligned access depending on source
+	 * and dest address, which is incompatible with nand cache. Fallback
+	 * to the memcpy_fromio in such case
+	 */
+	if (bcmbca_nand_is_buf_aligned((void *)flash_cache, buffer))
+		memcpy((void *)buffer, (void *)flash_cache, fc_words * 4);
+	else
+		memcpy_fromio((void *)buffer, flash_cache, fc_words * 4);
+}
+
 static int bcmbca_nand_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -73,6 +99,7 @@ static int bcmbca_nand_probe(struct platform_device *pdev)
 
 	soc->ctlrdy_ack = bcmbca_nand_intc_ack;
 	soc->ctlrdy_set_enabled = bcmbca_nand_intc_set;
+	soc->read_data_bus = bcmbca_read_data_bus;
 
 	return brcmnand_probe(pdev, soc);
 }
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 8faca43ae1ff..73fdf7ce21aa 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -851,6 +851,20 @@ static inline u32 edu_readl(struct brcmnand_controller *ctrl,
 	return brcmnand_readl(ctrl->edu_base + offs);
 }
 
+static inline void brcmnand_read_data_bus(struct brcmnand_controller *ctrl,
+					  void __iomem *flash_cache, u32 *buffer, int fc_words)
+{
+	struct brcmnand_soc *soc = ctrl->soc;
+	int i;
+
+	if (soc->read_data_bus) {
+		soc->read_data_bus(soc, flash_cache, buffer, fc_words);
+	} else {
+		for (i = 0; i < fc_words; i++)
+			buffer[i] = brcmnand_read_fc(ctrl, i);
+	}
+}
+
 static void brcmnand_clear_ecc_addr(struct brcmnand_controller *ctrl)
 {
 
@@ -1975,7 +1989,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	struct brcmnand_host *host = nand_get_controller_data(chip);
 	struct brcmnand_controller *ctrl = host->ctrl;
-	int i, j, ret = 0;
+	int i, ret = 0;
 
 	brcmnand_clear_ecc_addr(ctrl);
 
@@ -1988,8 +2002,8 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
 		if (likely(buf)) {
 			brcmnand_soc_data_bus_prepare(ctrl->soc, false);
 
-			for (j = 0; j < FC_WORDS; j++, buf++)
-				*buf = brcmnand_read_fc(ctrl, j);
+			brcmnand_read_data_bus(ctrl, ctrl->nand_fc, buf, FC_WORDS);
+			buf += FC_WORDS;
 
 			brcmnand_soc_data_bus_unprepare(ctrl->soc, false);
 		}
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.h b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
index 928114c0be5e..7261a69989fe 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
@@ -24,6 +24,8 @@ struct brcmnand_soc {
 	void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
 	void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
 				 bool is_param);
+	void (*read_data_bus)(struct brcmnand_soc *soc, void __iomem *flash_cache,
+				  u32 *buffer, int fc_words);
 	const struct brcmnand_io_ops *ops;
 };
 
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:31 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:31 -0800
Subject: [PATCH v4 10/12] mtd: rawnand: brcmnand: Support write protection setting from dts
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-11-william.zhang@broadcom.com>

The write protection feature is controlled by the module parameter wp_on
with default set to enabled. But not all the board use this feature
especially in BCMBCA broadband board. And module parameter is not
sufficient as different board can have different option.  Add a device
tree property and allow this feature to be configured through the board
dts on per board basis.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
Reviewed-by: Kamal Dasu <kamal.dasu at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v4:
- Use the new brcm,wp-not-connected property based on the dts binding
change

Changes in v3: None
Changes in v2: None

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index efeee9e80213..8c1489ff7bd6 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -3218,6 +3218,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 	/* Disable XOR addressing */
 	brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0);
 
+	/* Check if the board connects the WP pin */
+	if (of_property_read_bool(dn, "brcm,wp-not-connected"))
+		wp_on = 0;
+
 	if (ctrl->features & BRCMNAND_HAS_WP) {
 		/* Permanently disable write protection */
 		if (wp_on == 2)
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:32 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:32 -0800
Subject: [PATCH v4 11/12] mtd: rawnand: brcmnand: exec_op helper functions return type fixes
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-12-william.zhang@broadcom.com>

From: David Regan <dregan at broadcom.com>

fix return type for exec_op reset and status detect helper functions

Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
Signed-off-by: David Regan <dregan at broadcom.com>
Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v4:
- Fix the commit id in the fixes tag

Changes in v3: None
Changes in v2:
- Added to patch series

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 8c1489ff7bd6..7ce2b267676f 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -625,7 +625,7 @@ enum {
 /* Only for v7.2 */
 #define	ACC_CONTROL_ECC_EXT_SHIFT		13
 
-static u8 brcmnand_status(struct brcmnand_host *host);
+static int brcmnand_status(struct brcmnand_host *host);
 
 static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
 {
@@ -1749,7 +1749,7 @@ static int brcmnand_waitfunc(struct nand_chip *chip)
 				 INTFC_FLASH_STATUS;
 }
 
-static u8 brcmnand_status(struct brcmnand_host *host)
+static int brcmnand_status(struct brcmnand_host *host)
 {
 	struct nand_chip *chip = &host->chip;
 	struct mtd_info *mtd = nand_to_mtd(chip);
@@ -1760,7 +1760,7 @@ static u8 brcmnand_status(struct brcmnand_host *host)
 	return brcmnand_waitfunc(chip);
 }
 
-static u8 brcmnand_reset(struct brcmnand_host *host)
+static int brcmnand_reset(struct brcmnand_host *host)
 {
 	struct nand_chip *chip = &host->chip;
 
@@ -2492,11 +2492,14 @@ static int brcmnand_exec_op(struct nand_chip *chip,
 
 	if (brcmnand_op_is_status(op)) {
 		status = op->instrs[1].ctx.data.buf.in;
-		*status = brcmnand_status(host);
+		ret = brcmnand_status(host);
+		if (ret < 0)
+			return ret;
+
+		*status = ret & 0xFF;
 
 		return 0;
-	}
-	else if (brcmnand_op_is_reset(op)) {
+	} else if (brcmnand_op_is_reset(op)) {
 		ret = brcmnand_reset(host);
 		if (ret < 0)
 			return ret;
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:30 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:30 -0800
Subject: [PATCH v4 09/12] mtd: rawnand: brcmnand: Add support for getting ecc setting from strap
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-10-william.zhang@broadcom.com>

BCMBCA broadband SoC based board design does not specify ecc setting in
dts but rather use the SoC NAND strap info to obtain the ecc strength
and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
this purpose and update driver to support this option.

The generic nand ecc settings still take precedence over this flag. For
example, if nand-ecc-strength is set in the dts, the driver ignores the
strap setting and falls back to original behavior. This makes sure that
the existing BCMBCA board dts still works the old way even the strap
flag is set in the BCMBCA chip dtsi.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v4:
- Update the comments for ecc setting selection

Changes in v3: None
Changes in v2:
- Minor cosmetic fixes

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 83 ++++++++++++++++++++++--
 1 file changed, 76 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 73fdf7ce21aa..efeee9e80213 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1038,6 +1038,19 @@ static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl)
 		return -1;
 }
 
+static int brcmnand_get_sector_size_1k(struct brcmnand_host *host)
+{
+	struct brcmnand_controller *ctrl = host->ctrl;
+	int shift = brcmnand_sector_1k_shift(ctrl);
+	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+						  BRCMNAND_CS_ACC_CONTROL);
+
+	if (shift < 0)
+		return 0;
+
+	return (nand_readreg(ctrl, acc_control_offs) >> shift) & 0x1;
+}
+
 static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
 {
 	struct brcmnand_controller *ctrl = host->ctrl;
@@ -1055,6 +1068,38 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
 	nand_writereg(ctrl, acc_control_offs, tmp);
 }
 
+static int brcmnand_get_spare_size(struct brcmnand_host *host)
+{
+	struct brcmnand_controller *ctrl = host->ctrl;
+	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+						  BRCMNAND_CS_ACC_CONTROL);
+	u32 acc = nand_readreg(ctrl, acc_control_offs);
+
+	return (acc & brcmnand_spare_area_mask(ctrl));
+}
+
+static int brcmnand_get_ecc_strength(struct brcmnand_host *host)
+{
+	struct brcmnand_controller *ctrl = host->ctrl;
+	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+						  BRCMNAND_CS_ACC_CONTROL);
+	int sector_size_1k = brcmnand_get_sector_size_1k(host);
+	int spare_area_size, ecc_level, ecc_strength;
+	u32 acc;
+
+	spare_area_size = brcmnand_get_spare_size(host);
+	acc = nand_readreg(ctrl, acc_control_offs);
+	ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl->ecc_level_shift;
+	if (sector_size_1k)
+		ecc_strength = ecc_level * 2;
+	else if (spare_area_size == 16 && ecc_level == 15)
+		ecc_strength = 1; /* hamming */
+	else
+		ecc_strength = ecc_level;
+
+	return ecc_strength;
+}
+
 /***********************************************************************
  * CS_NAND_SELECT
  ***********************************************************************/
@@ -2622,19 +2667,43 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
 		nanddev_get_memorg(&chip->base);
 	struct brcmnand_controller *ctrl = host->ctrl;
 	struct brcmnand_cfg *cfg = &host->hwcfg;
-	char msg[128];
+	struct device_node *np = nand_get_flash_node(chip);
 	u32 offs, tmp, oob_sector;
-	int ret;
+	int ret, sector_size_1k = 0;
+	bool use_strap = false;
+	char msg[128];
 
 	memset(cfg, 0, sizeof(*cfg));
+	use_strap = of_property_read_bool(np, "brcm,nand-ecc-use-strap");
 
-	ret = of_property_read_u32(nand_get_flash_node(chip),
-				   "brcm,nand-oob-sector-size",
+	/*
+	 * Set ECC size and strength based on hw configuration from strap
+	 * if brcm,nand-ecc-use-strap is set. However if nand-ecc-strength
+	 * is set, its value will be used and ignore the strap setting.
+	 */
+	if (chip->ecc.strength)
+		use_strap = 0;
+
+	if (use_strap) {
+		chip->ecc.strength = brcmnand_get_ecc_strength(host);
+		sector_size_1k = brcmnand_get_sector_size_1k(host);
+		if (chip->ecc.size == 0) {
+			if (sector_size_1k < 0)
+				chip->ecc.size = 512;
+			else
+				chip->ecc.size = 512 << sector_size_1k;
+		}
+	}
+
+	ret = of_property_read_u32(np, "brcm,nand-oob-sector-size",
 				   &oob_sector);
 	if (ret) {
-		/* Use detected size */
-		cfg->spare_area_size = mtd->oobsize /
-					(mtd->writesize >> FC_SHIFT);
+		if (use_strap)
+			cfg->spare_area_size = brcmnand_get_spare_size(host);
+		else
+			/* Use detected size */
+			cfg->spare_area_size = mtd->oobsize /
+						(mtd->writesize >> FC_SHIFT);
 	} else {
 		cfg->spare_area_size = oob_sector;
 	}
-- 
2.37.3



From william.zhang at broadcom.com  Fri Feb  2 16:28:33 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri,  2 Feb 2024 16:28:33 -0800
Subject: [PATCH v4 12/12] mtd: rawnand: brcmnand: update log level messages
In-Reply-To: <20240203002834.171462-1-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
Message-ID: <20240203002834.171462-13-william.zhang@broadcom.com>

From: David Regan <dregan at broadcom.com>

Update log level messages so that more critical messages
can be seen.

Signed-off-by: David Regan <dregan at broadcom.com>
Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v4:
- Revert the log level change for correctable ecc error

Changes in v3: None
Changes in v2:
- Added to patch series

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 7ce2b267676f..e50582b45182 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1143,7 +1143,7 @@ static int bcmnand_ctrl_poll_status(struct brcmnand_host *host,
 	if ((val & mask) == expected_val)
 		return 0;
 
-	dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
+	dev_err(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
 		 expected_val, val & mask);
 
 	return -ETIMEDOUT;
@@ -2196,7 +2196,7 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
 				return err;
 		}
 
-		dev_dbg(ctrl->dev, "uncorrectable error at 0x%llx\n",
+		dev_err(ctrl->dev, "uncorrectable error at 0x%llx\n",
 			(unsigned long long)err_addr);
 		mtd->ecc_stats.failed++;
 		/* NAND layer expects zero on ECC errors */
-- 
2.37.3



From kuba at kernel.org  Fri Feb  2 16:56:27 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 2 Feb 2024 16:56:27 -0800
Subject: [PATCH net v3] net: stmmac: xgmac: fix handling of DPP safety
 error for DMA channels
In-Reply-To: <ksfs7uag4yukqbeygch7pxvr5axyrqz4gunq2xes3ppmtrgm5b@hwh5yx5qz3wl>
References: <20240131020828.2007741-1-0x1207@gmail.com>
	<ksfs7uag4yukqbeygch7pxvr5axyrqz4gunq2xes3ppmtrgm5b@hwh5yx5qz3wl>
Message-ID: <20240202165627.64e0a628@kernel.org>

On Sat, 3 Feb 2024 00:58:39 +0300 Serge Semin wrote:
> If so, David/Jakub, is it possible to rebase the branch with the macro
> fixed in the commit or a new cleanup patch is the only option?

Cleanup patch is the only option :(


From Frank.li at nxp.com  Fri Feb  2 17:01:05 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 2 Feb 2024 20:01:05 -0500
Subject: [PATCH v9 05/16] PCI: imx6: Using "linux,pci-domain" as slot ID
In-Reply-To: <20240202225116.GA732628@bhelgaas>
References: <Zb1rD4WK5D0ckKos@lizhi-Precision-Tower-5810>
 <20240202225116.GA732628@bhelgaas>
Message-ID: <Zb2QUTenlj3kEeE/@lizhi-Precision-Tower-5810>

On Fri, Feb 02, 2024 at 04:51:16PM -0600, Bjorn Helgaas wrote:
> [Rob to to: line]
> 
> On Fri, Feb 02, 2024 at 05:22:07PM -0500, Frank Li wrote:
> > On Fri, Feb 02, 2024 at 03:54:31PM -0600, Bjorn Helgaas wrote:
> > > On Fri, Jan 19, 2024 at 12:11:11PM -0500, Frank Li wrote:
> > > > Avoid use get slot id by compared with register physical address. If there
> > > > are more than 2 slots, compared logic will become complex.
> > > > 
> > > > "linux,pci-domain" already exist at dts since commit:
> > > > 	commit (c0b70f05c87f3b arm64: dts: imx8mq: use_dt_domains for pci node).
> > > > 
> > > > So it is safe to remove compare basic address code:
> > > > 	...
> > > > 	if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> > > > 		imx6_pcie->controller_id = 1;
> > > > 	...
> > > 
> > > I have no idea what this is telling me.  I guess you don't want to use
> > > IMX8MQ_PCIE2_BASE_ADDR to decide something?  That much sounds good:
> > > the *address* of some MMIO space doesn't tell us anything about the
> > > function of that space.
> > 
> > You are right. If there are more than two controller. The check logic
> > will be extremely complex.
> > 
> > There are some discussin at below thread about linux,pci-domain
> > https://lore.kernel.org/imx/20231206165953.GA717921 at bhelgaas/
> 
> My response here was too low level, just about trivial syntactic and
> style issues.  I should have seen the larger issue at the time; sorry
> about that.
> 
> > https://lore.kernel.org/imx/20231217175158.GF6748 at thinkpad/
> 
> That's a good response from Mani, but again not relevant to my point.
> 
> My point here is that "compatible" should tell the driver how to
> operate the device, i.e., the driver knows what registers are present
> and how they work.
> 
> If you have two variant devices that both implement a register that
> can be used to distinguish them, a single "compatible" string might be
> enough because the driver can use that register to tell the
> difference.
> 
> If the driver can't tell the difference by looking at the hardware
> itself, I think you need a separate "compatible" string for it.  Of
> course I'm far from a DT expert, so please correct this if necessary,
> Rob, et al.
> 
> > > I expect the "compatible" string to tell the driver what the
> > > programming model of the device is.
> > > 
> > > > +	/* Using linux,pci-domain as PCI slot id */
> > > > +	imx6_pcie->controller_id = of_get_pci_domain_nr(node);
> > > > +	/*
> > > > +	 * If there are no "linux,pci-domain" property specified in DT, then assume only one
> > > > +	 * controller is available.
> > > > +	 */
> > > > +	if (imx6_pcie->controller_id == -EINVAL)
> > > > +		imx6_pcie->controller_id = 0;
> > > > +	else if (imx6_pcie->controller_id < 0)
> > > > +		return dev_err_probe(dev, imx6_pcie->controller_id,
> > > > +				     "linux,pci-domain have wrong value\n");
> > > 
> > > Maybe I'm missing something here.  It looks like this driver uses
> > > controller_id to distinguish between hardware variants or maybe
> > > between two Root Ports (slots?) in the same SoC?
> > 
> > Yes!
> > 
> > >   imx6_pcie_grp_offset
> > >     return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
> > > 
> > >   imx6_pcie_configure_type
> > >     id = imx6_pcie->controller_id
> > >     if (!drvdata->mode_mask[id])         # <-- looks unsafe
> > 
> > I can add safe check here.
> > 
> > >       id = 0;
> > >     regmap_update_bits(drvdata->mode_off[id], ...)
> > > 
> > > (This "mode_mask[id]" looks like it will reference garbage if the DT
> > > supplies "linux,pci-domain = <2>".  A bogus DT shouldn't be able to
> > > cause a driver to misbehave like that.)
> > 
> > Suppose I can use dt-bind doc to force to 0,1 and safe check here.
> 
> Nope.  The driver must protect itself from garbage in the DT.
> 
> > > That doesn't seem related to "linux,pci-domain" at all.
> > 
> > I added comments about
> > /* Using linux,pci-domain as PCI slot id */
> 
> That doesn't make it related :)

Okay, linux,pci-domain is not good method for this. Anyways, previous
implement is wrong.

Let me skip it and think a better method to fix this problem later.

Frank 
> 
> > We may add new property about controller-id, but there already have common
> > one "linux,pci-domain", which value in upstreamed dts exactly match our
> > expection, I also found other platform use it as slot id in kernel tree.
> > 
> > Any way, we can continue discuss the better solution here. But I hope
> > it was not block whole 16 patches. we can skip this one firstly.
> > 
> > I still have more than 10 clean up patches my local tree.
> > 
> > > 
> > > Bjorn


From florian.fainelli at broadcom.com  Fri Feb  2 17:17:56 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Fri, 2 Feb 2024 17:17:56 -0800
Subject: [PATCH net-next 4/6] net: bcmgenet: remove eee_enabled/eee_active
 in bcmgenet_get_eee()
In-Reply-To: <E1rVpvs-002Pe6-1w@rmk-PC.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvs-002Pe6-1w@rmk-PC.armlinux.org.uk>
Message-ID: <e04888df-adba-49fc-b7f3-3b930e80af81@broadcom.com>



On 2/2/2024 1:34 AM, Russell King (Oracle) wrote:
> bcmgenet_get_eee() sets edata->eee_active and edata->eee_enabled from
> its own copy, and then calls phy_ethtool_get_eee() which in turn will
> call genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Therefore, setting these members in bcmgenet_get_eee() is redundant,
> and can be removed. This also makes priv->eee.eee_active unnecessary,
> so remove this and use a local variable where appropriate.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>

Is not there an opportunity for no longer overriding eee_enabled as well 
since genphy_c45_ethtool_get_eee() will set that variable too?
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240202/b8308f57/attachment.p7s>

From florian.fainelli at broadcom.com  Fri Feb  2 17:18:49 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Fri, 2 Feb 2024 17:18:49 -0800
Subject: [PATCH net-next 5/6] net: bcmasp: remove eee_enabled/eee_active
 in bcmasp_get_eee()
In-Reply-To: <E1rVpvx-002PeD-71@rmk-PC.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvx-002PeD-71@rmk-PC.armlinux.org.uk>
Message-ID: <56c88486-e576-4dca-9bf3-8dc6880e0899@broadcom.com>



On 2/2/2024 1:34 AM, Russell King (Oracle) wrote:
> bcmasp_get_eee() sets edata->eee_active and edata->eee_enabled from
> its own copy, and then calls phy_ethtool_get_eee() which in turn will
> call genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Therefore, setting these members in bcmasp_get_eee() is redundant, and
> can be removed. This also makes intf->eee.eee_active unnecessary, so
> remove this and use a local variable where appropriate.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240202/5ef29be5/attachment-0001.p7s>

From florian.fainelli at broadcom.com  Fri Feb  2 17:21:57 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Fri, 2 Feb 2024 17:21:57 -0800
Subject: [PATCH net-next 4/6] net: bcmgenet: remove eee_enabled/eee_active
 in bcmgenet_get_eee()
In-Reply-To: <e04888df-adba-49fc-b7f3-3b930e80af81@broadcom.com>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvs-002Pe6-1w@rmk-PC.armlinux.org.uk>
 <e04888df-adba-49fc-b7f3-3b930e80af81@broadcom.com>
Message-ID: <4586d004-a7b7-4e60-9493-0a1bbe7d79ba@broadcom.com>



On 2/2/2024 5:17 PM, Florian Fainelli wrote:
> 
> 
> On 2/2/2024 1:34 AM, Russell King (Oracle) wrote:
>> bcmgenet_get_eee() sets edata->eee_active and edata->eee_enabled from
>> its own copy, and then calls phy_ethtool_get_eee() which in turn will
>> call genphy_c45_ethtool_get_eee().
>>
>> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
>> with its own interpretation from the PHYs settings and negotiation
>> result.
>>
>> Therefore, setting these members in bcmgenet_get_eee() is redundant,
>> and can be removed. This also makes priv->eee.eee_active unnecessary,
>> so remove this and use a local variable where appropriate.
>>
>> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> 
> Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
> 
> Is not there an opportunity for no longer overriding eee_enabled as well 
> since genphy_c45_ethtool_get_eee() will set that variable too?

Scratch that comment, you are doing it in the getter.
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240202/fe278b8f/attachment.p7s>

From florian.fainelli at broadcom.com  Fri Feb  2 17:22:27 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Fri, 2 Feb 2024 17:22:27 -0800
Subject: [PATCH net-next 6/6] net: dsa: b53: remove eee_enabled/eee_active
 in b53_get_mac_eee()
In-Reply-To: <E1rVpw2-002PeJ-Bh@rmk-PC.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpw2-002PeJ-Bh@rmk-PC.armlinux.org.uk>
Message-ID: <4e5384a7-063a-470d-a9b5-e31154dd851f@broadcom.com>



On 2/2/2024 1:34 AM, Russell King (Oracle) wrote:
> b53_get_mac_eee() sets both eee_enabled and eee_active, and then
> returns zero.
> 
> dsa_slave_get_eee(), which calls this function, will then continue to
> call phylink_ethtool_get_eee(), which will return -EOPNOTSUPP if there
> is no PHY present, otherwise calling phy_ethtool_get_eee() which in
> turn will call genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Thus, when there is no PHY, dsa_slave_get_eee() will fail with
> -EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
> userspace. When there is a PHY, eee_enabled and eee_active will be
> overwritten by phylib, making the setting of these members in
> b53_get_mac_eee() entirely unnecessary.
> 
> Remove this code, thus simplifying b53_get_mac_eee().
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240202/0fb9988b/attachment-0001.p7s>

From florian.fainelli at broadcom.com  Fri Feb  2 17:22:49 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Fri, 2 Feb 2024 17:22:49 -0800
Subject: [PATCH net-next 1/6] net: stmmac: remove eee_enabled/eee_active
 in stmmac_ethtool_op_get_eee()
In-Reply-To: <E1rVpvc-002Pdp-Jj@rmk-PC.armlinux.org.uk>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvc-002Pdp-Jj@rmk-PC.armlinux.org.uk>
Message-ID: <67554a72-42f3-4c69-96b5-adc63e76c4cb@broadcom.com>



On 2/2/2024 1:33 AM, Russell King (Oracle) wrote:
> stmmac_ethtool_op_get_eee() sets both eee_enabled and eee_active, and
> then goes on to call phylink_ethtool_get_eee().
> 
> phylink_ethtool_get_eee() will return -EOPNOTSUPP if there is no PHY
> present, otherwise calling phy_ethtool_get_eee() which in turn will call
> genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Thus, when there is no PHY, stmmac_ethtool_op_get_eee() will fail with
> -EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
> userspace. When there is a PHY, eee_enabled and eee_active will be
> overwritten by phylib, making the setting of these members in
> stmmac_ethtool_op_get_eee() entirely unnecessary.
> 
> Remove this code, thus simplifying stmmac_ethtool_op_get_eee().
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240202/2773e5d4/attachment.p7s>

From eugenis at google.com  Fri Feb  2 17:32:07 2024
From: eugenis at google.com (Evgenii Stepanov)
Date: Fri, 2 Feb 2024 17:32:07 -0800
Subject: [PATCH RFC v3 28/35] arm64: mte: swap: Handle tag restoring when
 missing tag storage
In-Reply-To: <Zb0CRYSmQxJ_N4Sr@raptor>
References: <20240125164256.4147-1-alexandru.elisei@arm.com>
 <20240125164256.4147-29-alexandru.elisei@arm.com> <CAMn1gO7M51QtxPxkRO3ogH1zasd2-vErWqoPTqGoPiEvr8Pvcw@mail.gmail.com>
 <Zb0CRYSmQxJ_N4Sr@raptor>
Message-ID: <CAFKCwrg=+KEwPoc2FXshe2qF9kQJZDT0yit4+vJ5JhNUT8+sVA@mail.gmail.com>

On Fri, Feb 2, 2024 at 6:56?AM Alexandru Elisei
<alexandru.elisei at arm.com> wrote:
>
> Hi Peter,
>
> On Thu, Feb 01, 2024 at 08:02:40PM -0800, Peter Collingbourne wrote:
> > On Thu, Jan 25, 2024 at 8:45?AM Alexandru Elisei
> > <alexandru.elisei at arm.com> wrote:
> > >
> > > Linux restores tags when a page is swapped in and there are tags associated
> > > with the swap entry which the new page will replace. The saved tags are
> > > restored even if the page will not be mapped as tagged, to protect against
> > > cases where the page is shared between different VMAs, and is tagged in
> > > some, but untagged in others. By using this approach, the process can still
> > > access the correct tags following an mprotect(PROT_MTE) on the non-MTE
> > > enabled VMA.
> > >
> > > But this poses a challenge for managing tag storage: in the scenario above,
> > > when a new page is allocated to be swapped in for the process where it will
> > > be mapped as untagged, the corresponding tag storage block is not reserved.
> > > mte_restore_page_tags_by_swp_entry(), when it restores the saved tags, will
> > > overwrite data in the tag storage block associated with the new page,
> > > leading to data corruption if the block is in use by a process.
> > >
> > > Get around this issue by saving the tags in a new xarray, this time indexed
> > > by the page pfn, and then restoring them when tag storage is reserved for
> > > the page.
> > >
> > > Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> > > ---
> > >
> > > Changes since rfc v2:
> > >
> > > * Restore saved tags **before** setting the PG_tag_storage_reserved bit to
> > > eliminate a brief window of opportunity where userspace can access uninitialized
> > > tags (Peter Collingbourne).
> > >
> > >  arch/arm64/include/asm/mte_tag_storage.h |   8 ++
> > >  arch/arm64/include/asm/pgtable.h         |  11 +++
> > >  arch/arm64/kernel/mte_tag_storage.c      |  12 ++-
> > >  arch/arm64/mm/mteswap.c                  | 110 +++++++++++++++++++++++
> > >  4 files changed, 140 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm64/include/asm/mte_tag_storage.h b/arch/arm64/include/asm/mte_tag_storage.h
> > > index 50bdae94cf71..40590a8c3748 100644
> > > --- a/arch/arm64/include/asm/mte_tag_storage.h
> > > +++ b/arch/arm64/include/asm/mte_tag_storage.h
> > > @@ -36,6 +36,14 @@ bool page_is_tag_storage(struct page *page);
> > >
> > >  vm_fault_t handle_folio_missing_tag_storage(struct folio *folio, struct vm_fault *vmf,
> > >                                             bool *map_pte);
> > > +vm_fault_t mte_try_transfer_swap_tags(swp_entry_t entry, struct page *page);
> > > +
> > > +void tags_by_pfn_lock(void);
> > > +void tags_by_pfn_unlock(void);
> > > +
> > > +void *mte_erase_tags_for_pfn(unsigned long pfn);
> > > +bool mte_save_tags_for_pfn(void *tags, unsigned long pfn);
> > > +void mte_restore_tags_for_pfn(unsigned long start_pfn, int order);
> > >  #else
> > >  static inline bool tag_storage_enabled(void)
> > >  {
> > > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> > > index 0174e292f890..87ae59436162 100644
> > > --- a/arch/arm64/include/asm/pgtable.h
> > > +++ b/arch/arm64/include/asm/pgtable.h
> > > @@ -1085,6 +1085,17 @@ static inline void arch_swap_invalidate_area(int type)
> > >                 mte_invalidate_tags_area_by_swp_entry(type);
> > >  }
> > >
> > > +#ifdef CONFIG_ARM64_MTE_TAG_STORAGE
> > > +#define __HAVE_ARCH_SWAP_PREPARE_TO_RESTORE
> > > +static inline vm_fault_t arch_swap_prepare_to_restore(swp_entry_t entry,
> > > +                                                     struct folio *folio)
> > > +{
> > > +       if (tag_storage_enabled())
> > > +               return mte_try_transfer_swap_tags(entry, &folio->page);
> > > +       return 0;
> > > +}
> > > +#endif
> > > +
> > >  #define __HAVE_ARCH_SWAP_RESTORE
> > >  static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
> > >  {
> > > diff --git a/arch/arm64/kernel/mte_tag_storage.c b/arch/arm64/kernel/mte_tag_storage.c
> > > index afe2bb754879..ac7b9c9c585c 100644
> > > --- a/arch/arm64/kernel/mte_tag_storage.c
> > > +++ b/arch/arm64/kernel/mte_tag_storage.c
> > > @@ -567,6 +567,7 @@ int reserve_tag_storage(struct page *page, int order, gfp_t gfp)
> > >                 }
> > >         }
> > >
> > > +       mte_restore_tags_for_pfn(page_to_pfn(page), order);
> > >         page_set_tag_storage_reserved(page, order);
> > >  out_unlock:
> > >         mutex_unlock(&tag_blocks_lock);
> > > @@ -595,7 +596,8 @@ void free_tag_storage(struct page *page, int order)
> > >         struct tag_region *region;
> > >         unsigned long page_va;
> > >         unsigned long flags;
> > > -       int ret;
> > > +       void *tags;
> > > +       int i, ret;
> > >
> > >         ret = tag_storage_find_block(page, &start_block, &region);
> > >         if (WARN_ONCE(ret, "Missing tag storage block for pfn 0x%lx", page_to_pfn(page)))
> > > @@ -605,6 +607,14 @@ void free_tag_storage(struct page *page, int order)
> > >         /* Avoid writeback of dirty tag cache lines corrupting data. */
> > >         dcache_inval_tags_poc(page_va, page_va + (PAGE_SIZE << order));
> > >
> > > +       tags_by_pfn_lock();
> > > +       for (i = 0; i < (1 << order); i++) {
> > > +               tags = mte_erase_tags_for_pfn(page_to_pfn(page + i));
> > > +               if (unlikely(tags))
> > > +                       mte_free_tag_buf(tags);
> > > +       }
> > > +       tags_by_pfn_unlock();
> > > +
> > >         end_block = start_block + order_to_num_blocks(order, region->block_size_pages);
> > >
> > >         xa_lock_irqsave(&tag_blocks_reserved, flags);
> > > diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
> > > index 2a43746b803f..e11495fa3c18 100644
> > > --- a/arch/arm64/mm/mteswap.c
> > > +++ b/arch/arm64/mm/mteswap.c
> > > @@ -20,6 +20,112 @@ void mte_free_tag_buf(void *buf)
> > >         kfree(buf);
> > >  }
> > >
> > > +#ifdef CONFIG_ARM64_MTE_TAG_STORAGE
> > > +static DEFINE_XARRAY(tags_by_pfn);
> > > +
> > > +void tags_by_pfn_lock(void)
> > > +{
> > > +       xa_lock(&tags_by_pfn);
> > > +}
> > > +
> > > +void tags_by_pfn_unlock(void)
> > > +{
> > > +       xa_unlock(&tags_by_pfn);
> > > +}
> > > +
> > > +void *mte_erase_tags_for_pfn(unsigned long pfn)
> > > +{
> > > +       return __xa_erase(&tags_by_pfn, pfn);
> > > +}
> > > +
> > > +bool mte_save_tags_for_pfn(void *tags, unsigned long pfn)
> > > +{
> > > +       void *entry;
> > > +       int ret;
> > > +
> > > +       ret = xa_reserve(&tags_by_pfn, pfn, GFP_KERNEL);
> >
> > copy_highpage can be called from an atomic context, so it isn't
> > currently valid to pass GFP_KERNEL here.
> >
> > To give one example of a possible atomic context call, copy_pte_range
> > will take a PTE spinlock and can call copy_present_pte, which can call
> > copy_present_page, which will call copy_user_highpage.
> >
> > To give another example, __buffer_migrate_folio can call
> > spin_lock(&mapping->private_lock), then call folio_migrate_copy, which
> > will call folio_copy.
>
> That is very unfortunate from my part. I distinctly remember looking
> precisely at copy_page_range() to double check that it doesn't call
> copy_*highpage() from an atomic context, I can only assume that I missed
> that it's called with the ptl lock held.
>
> With your two examples, and the khugepaged case in patch #31 ("khugepaged:
> arm64: Don't collapse MTE enabled VMAs"), it's crystal clear that the
> convention for copy_*highpage() is that the function cannot sleep.
>
> There are two issues here: allocating the buffer in memory where the tags
> will be copied, and xarray allocating memory for a new entry.
>
> One fix would be to allocate an entire page with __GFP_ATOMIC, and use that
> as a cache for tag buffers (storing the tags for a page uses 1/32th of a
> page). From what little I know about xarray, xarray stores would still have
> to be GFP_ATOMIC. This should fix the sleeping in atomic context bug. But
> the issue I see with this is that a memory allocation can fail, while
> copy_*highpage() cannot. Send a fatal signal to the process if memory
> allocation fails?
>
> Another approach would be to preallocate memory in a preemptible context,
> something like copy_*highpage_prepare(), but that would mean a lot more
> work: finding all the places where copy_*highpage is used and add
> copy_*highpage_prepare() outside the critical section, releasing the memory
> in case of failure (like in the copy_pte_range() case - maybe
> copy_*highpage_end()?). That's a pretty big maintenance burden for the MM
> code. Although maybe other architectures can find a use for it?
>
> And yet another approach is reserve the needed memory (for the buffer and
> in the xarray) when the page is allocated, if it doesn't have tag storage
> reserved, regardless of the page being allocated as tagged or not. Then in
> set_pte_at() free this memory if it's unused. But this would mean reserving
> memory for possibly all memory allocations in the system (including for tag
> storage pages) if userspace doesn't use tags at all, though not all pages
> in the system will have this memory reserved at the same time. Pretty big
> downside.
>
> Out of the three, I prefer the first, but it's definitely not perfect. I'll
> try to think of something else, maybe I can come up with something better.
>
> What are your thoughts?
>
> Thanks,
> Alex
>
> >
> > Peter
> >
> > > +       if (ret)
> > > +               return true;
> > > +
> > > +       tags_by_pfn_lock();
> > > +
> > > +       if (page_tag_storage_reserved(pfn_to_page(pfn))) {
> > > +               xa_release(&tags_by_pfn, pfn);
> > > +               tags_by_pfn_unlock();
> > > +               return false;
> > > +       }
> > > +
> > > +       entry = __xa_store(&tags_by_pfn, pfn, tags, GFP_ATOMIC);
> > > +       if (xa_is_err(entry)) {
> > > +               xa_release(&tags_by_pfn, pfn);
> > > +               goto out_unlock;
> > > +       } else if (entry) {
> > > +               mte_free_tag_buf(entry);
> > > +       }
> > > +
> > > +out_unlock:
> > > +       tags_by_pfn_unlock();
> > > +       return true;
> > > +}
> > > +
> > > +void mte_restore_tags_for_pfn(unsigned long start_pfn, int order)
> > > +{
> > > +       struct page *page = pfn_to_page(start_pfn);
> > > +       unsigned long pfn;
> > > +       void *tags;
> > > +
> > > +       tags_by_pfn_lock();
> > > +
> > > +       for (pfn = start_pfn; pfn < start_pfn + (1 << order); pfn++, page++) {
> > > +               tags = mte_erase_tags_for_pfn(pfn);
> > > +               if (unlikely(tags)) {
> > > +                       /*
> > > +                        * Mark the page as tagged so mte_sync_tags() doesn't
> > > +                        * clear the tags.
> > > +                        */
> > > +                       WARN_ON_ONCE(!try_page_mte_tagging(page));
> > > +                       mte_copy_page_tags_from_buf(page_address(page), tags);
> > > +                       set_page_mte_tagged(page);

I hit a WARN_ON_ONCE inside `set_page_mte_tagged` at this call site,
because the page does not have PG_tag_storage_reserved yet.
Swap the order of calls in reserve_tag_storage?

> > > +                       mte_free_tag_buf(tags);
> > > +               }
> > > +       }
> > > +
> > > +       tags_by_pfn_unlock();
> > > +}
> > > +
> > > +/*
> > > + * Note on locking: swap in/out is done with the folio locked, which eliminates
> > > + * races with mte_save/restore_page_tags_by_swp_entry.
> > > + */
> > > +vm_fault_t mte_try_transfer_swap_tags(swp_entry_t entry, struct page *page)
> > > +{
> > > +       void *swap_tags, *pfn_tags;
> > > +       bool saved;
> > > +
> > > +       /*
> > > +        * mte_restore_page_tags_by_swp_entry() will take care of copying the
> > > +        * tags over.
> > > +        */
> > > +       if (likely(page_mte_tagged(page) || page_tag_storage_reserved(page)))
> > > +               return 0;
> > > +
> > > +       swap_tags = xa_load(&tags_by_swp_entry, entry.val);
> > > +       if (!swap_tags)
> > > +               return 0;
> > > +
> > > +       pfn_tags = mte_allocate_tag_buf();
> > > +       if (!pfn_tags)
> > > +               return VM_FAULT_OOM;
> > > +
> > > +       memcpy(pfn_tags, swap_tags, MTE_PAGE_TAG_STORAGE_SIZE);
> > > +       saved = mte_save_tags_for_pfn(pfn_tags, page_to_pfn(page));
> > > +       if (!saved)
> > > +               mte_free_tag_buf(pfn_tags);
> > > +
> > > +       return 0;
> > > +}
> > > +#endif
> > > +
> > >  int mte_save_page_tags_by_swp_entry(struct page *page)
> > >  {
> > >         void *tags, *ret;
> > > @@ -54,6 +160,10 @@ void mte_restore_page_tags_by_swp_entry(swp_entry_t entry, struct page *page)
> > >         if (!tags)
> > >                 return;
> > >
> > > +       /* Tags will be restored when tag storage is reserved. */
> > > +       if (tag_storage_enabled() && unlikely(!page_tag_storage_reserved(page)))
> > > +               return;
> > > +
> > >         if (try_page_mte_tagging(page)) {
> > >                 mte_copy_page_tags_from_buf(page_address(page), tags);
> > >                 set_page_mte_tagged(page);
> > > --
> > > 2.43.0
> > >


From dxu at dxuuu.xyz  Fri Feb  2 17:34:40 2024
From: dxu at dxuuu.xyz (Daniel Xu)
Date: Fri, 2 Feb 2024 18:34:40 -0700
Subject: [PATCH bpf-next v4 0/3] Annotate kfuncs in .BTF_ids section
In-Reply-To: <Zb12EZt0BAKOPBk/@surya>
References: <cover.1706491398.git.dxu@dxuuu.xyz>
 <Zb12EZt0BAKOPBk/@surya>
Message-ID: <fq7iecmqkibtexsbgvv5gyu5nva6ig7gcww56oskk2rvmoxfno@uohfy2x57tch>

Hi Manu,

On Fri, Feb 02, 2024 at 03:09:05PM -0800, Manu Bretelle wrote:
> On Sun, Jan 28, 2024 at 06:24:05PM -0700, Daniel Xu wrote:
> > === Description ===
> > 
> > This is a bpf-treewide change that annotates all kfuncs as such inside
> > .BTF_ids. This annotation eventually allows us to automatically generate
> > kfunc prototypes from bpftool.
> > 
> > We store this metadata inside a yet-unused flags field inside struct
> > btf_id_set8 (thanks Kumar!). pahole will be taught where to look.
> > 
> > More details about the full chain of events are available in commit 3's
> > description.
> > 
> > The accompanying pahole and bpftool changes can be viewed
> > here on these "frozen" branches [0][1].
> > 
> > [0]: https://github.com/danobi/pahole/tree/kfunc_btf-v3-mailed
> > [1]: https://github.com/danobi/linux/tree/kfunc_bpftool-mailed
> 
> 
> I hit a similar issue to [0] on master
> 943b043aeecc ("selftests/bpf: Fix bench runner SIGSEGV")
>  when cross-compiling on x86_64 (LE) to s390x (BE).
> I do have CONFIG_DEBUG_INFO_BTF enable and the issue would not trigger if
> I disabled CONFIG_DEBUG_INFO_BTF (and with the fix mentioned in [0]).
> 
> What seems to happen is that `tools/resolve_btfids` is ran in the context of the
> host endianess and if I printk before the WARN_ON:
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index ef380e546952..a9ed7a1a4936 100644
>   --- a/kernel/bpf/btf.c
>   +++ b/kernel/bpf/btf.c
>   @@ -8128,6 +8128,7 @@ int register_btf_kfunc_id_set(enum bpf_prog_type prog_type,
>            * WARN() for initcall registrations that do not check errors.
>            */
>           if (!(kset->set->flags & BTF_SET8_KFUNCS)) {
>   +        printk("Flag 0x%08X, expected 0x%08X\n", kset->set->flags, BTF_SET8_KFUNCS);
>                   WARN_ON(!kset->owner);
>                   return -EINVAL;
>           }
> 
> the boot logs would show:
>   Flag 0x01000000, expected 0x00000001
> 
> The issue did not happen prior to
> 6f3189f38a3e ("bpf: treewide: Annotate BPF kfuncs in BTF")
> has only 0 was written before.
> 
> It seems [1] will be addressing cross-compilation, but it did not fix it as is
> by just applying on top of master, so probably some of the changes will also need
> to be ported to `tools/include/linux/btf_ids.h`?
> 
> A hacky workaround to cross-compilation I have is to apply:
> 
>   diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile
>   index 4b8079f294f6..b706e7ab066f 100644
>   --- a/tools/bpf/resolve_btfids/Makefile
>   +++ b/tools/bpf/resolve_btfids/Makefile
>   @@ -22,10 +22,10 @@ HOST_OVERRIDES := AR="$(HOSTAR)" CC="$(HOSTCC)" LD="$(HOSTLD)" ARCH="$(HOSTARCH)
>                     CROSS_COMPILE="" EXTRA_CFLAGS="$(HOSTCFLAGS)"
>    RM      ?= rm
>   -HOSTCC  ?= gcc
>   -HOSTLD  ?= ld
>   -HOSTAR  ?= ar
>   -CROSS_COMPILE =
>   +HOSTCC  = $(CC)
>   +HOSTLD  = $(LD)
>   +HOSTAR  = $(AR)
>   +#CROSS_COMPILE =
>    OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/
>   @@ -56,16 +56,16 @@ $(OUTPUT) $(OUTPUT)/libsubcmd $(LIBBPF_OUT):
>    $(SUBCMDOBJ): fixdep FORCE | $(OUTPUT)/libsubcmd
>           $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(SUBCMD_OUT) \
>   -                   DESTDIR=$(SUBCMD_DESTDIR) $(HOST_OVERRIDES) prefix= subdir= \
>   +                   DESTDIR=$(SUBCMD_DESTDIR) prefix= subdir= \
>                       $(abspath $@) install_headers
>    $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OUT)
>           $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) OUTPUT=$(LIBBPF_OUT)    \
>   -                   DESTDIR=$(LIBBPF_DESTDIR) $(HOST_OVERRIDES) prefix= subdir= \
>   +                   DESTDIR=$(LIBBPF_DESTDIR) prefix= subdir= \
>                       $(abspath $@) install_headers
>   -LIBELF_FLAGS := $(shell $(HOSTPKG_CONFIG) libelf --cflags 2>/dev/null)
>   -LIBELF_LIBS  := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf)
>   +LIBELF_FLAGS := $(shell $(PKG_CONFIG) libelf --cflags 2>/dev/null)
>   +LIBELF_LIBS  := $(shell $(PKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf)
>    HOSTCFLAGS_resolve_btfids += -g \
>              -I$(srctree)/tools/include \
>   @@ -84,7 +84,7 @@ $(BINARY_IN): fixdep FORCE prepare | $(OUTPUT)
>    $(BINARY): $(BPFOBJ) $(SUBCMDOBJ) $(BINARY_IN)
>           $(call msg,LINK,$@)
>   -       $(Q)$(HOSTCC) $(BINARY_IN) $(KBUILD_HOSTLDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS)
>   +       $(Q)$(CC) $(BINARY_IN) $(KBUILD_HOSTLDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS)
>    clean_objects := $(wildcard $(OUTPUT)/*.o                \
>                                $(OUTPUT)/.*.o.cmd           \
>   diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
>   index a38a3001527c..5cd193c04448 100644
>   --- a/tools/testing/selftests/bpf/Makefile
>   +++ b/tools/testing/selftests/bpf/Makefile
>   @@ -171,7 +171,7 @@ INCLUDE_DIR := $(SCRATCH_DIR)/include
>    BPFOBJ := $(BUILD_DIR)/libbpf/libbpf.a
>    ifneq ($(CROSS_COMPILE),)
>    HOST_BUILD_DIR         := $(BUILD_DIR)/host
>   -HOST_SCRATCH_DIR       := $(OUTPUT)/host-tools
>   +HOST_SCRATCH_DIR       := $(SCRATCH_DIR)
>    HOST_INCLUDE_DIR       := $(HOST_SCRATCH_DIR)/include
>    else
>    HOST_BUILD_DIR         := $(BUILD_DIR)
> 
> This causes `resolve_btfids` to be compiled in the target endianess and gets
> magically run provided that the hosts has `qemu-s390x-static` and a functional
> binfmt_misc [2] on the host, but having this using host architecture per [1]
> is likely better.

This is kinda surprising to me. I don't recall seeing any code inside
resolve_btfids that touches the set8 flags field -- only the ids in the
flexible array member. Would be interested to see what the value of the
set8 flags field is before resolve_btfids is run.

I'm a bit busy until Sunday afternoon but I'll try to take a look around
then. Might be a good opportunity to play with poke [0].

Thanks,
Daniel


[0]: http://www.jemarch.net/poke


From pcc at google.com  Fri Feb  2 17:52:45 2024
From: pcc at google.com (Peter Collingbourne)
Date: Fri, 2 Feb 2024 17:52:45 -0800
Subject: [PATCH RFC v3 28/35] arm64: mte: swap: Handle tag restoring when
 missing tag storage
In-Reply-To: <Zb0CRYSmQxJ_N4Sr@raptor>
References: <20240125164256.4147-1-alexandru.elisei@arm.com>
 <20240125164256.4147-29-alexandru.elisei@arm.com> <CAMn1gO7M51QtxPxkRO3ogH1zasd2-vErWqoPTqGoPiEvr8Pvcw@mail.gmail.com>
 <Zb0CRYSmQxJ_N4Sr@raptor>
Message-ID: <CAMn1gO5H6A71zEHLzPyuDfF5xaeej_Q2eCb54jeJ8eAG=yVgiA@mail.gmail.com>

On Fri, Feb 2, 2024 at 6:56?AM Alexandru Elisei
<alexandru.elisei at arm.com> wrote:
>
> Hi Peter,
>
> On Thu, Feb 01, 2024 at 08:02:40PM -0800, Peter Collingbourne wrote:
> > On Thu, Jan 25, 2024 at 8:45?AM Alexandru Elisei
> > <alexandru.elisei at arm.com> wrote:
> > >
> > > Linux restores tags when a page is swapped in and there are tags associated
> > > with the swap entry which the new page will replace. The saved tags are
> > > restored even if the page will not be mapped as tagged, to protect against
> > > cases where the page is shared between different VMAs, and is tagged in
> > > some, but untagged in others. By using this approach, the process can still
> > > access the correct tags following an mprotect(PROT_MTE) on the non-MTE
> > > enabled VMA.
> > >
> > > But this poses a challenge for managing tag storage: in the scenario above,
> > > when a new page is allocated to be swapped in for the process where it will
> > > be mapped as untagged, the corresponding tag storage block is not reserved.
> > > mte_restore_page_tags_by_swp_entry(), when it restores the saved tags, will
> > > overwrite data in the tag storage block associated with the new page,
> > > leading to data corruption if the block is in use by a process.
> > >
> > > Get around this issue by saving the tags in a new xarray, this time indexed
> > > by the page pfn, and then restoring them when tag storage is reserved for
> > > the page.
> > >
> > > Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> > > ---
> > >
> > > Changes since rfc v2:
> > >
> > > * Restore saved tags **before** setting the PG_tag_storage_reserved bit to
> > > eliminate a brief window of opportunity where userspace can access uninitialized
> > > tags (Peter Collingbourne).
> > >
> > >  arch/arm64/include/asm/mte_tag_storage.h |   8 ++
> > >  arch/arm64/include/asm/pgtable.h         |  11 +++
> > >  arch/arm64/kernel/mte_tag_storage.c      |  12 ++-
> > >  arch/arm64/mm/mteswap.c                  | 110 +++++++++++++++++++++++
> > >  4 files changed, 140 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm64/include/asm/mte_tag_storage.h b/arch/arm64/include/asm/mte_tag_storage.h
> > > index 50bdae94cf71..40590a8c3748 100644
> > > --- a/arch/arm64/include/asm/mte_tag_storage.h
> > > +++ b/arch/arm64/include/asm/mte_tag_storage.h
> > > @@ -36,6 +36,14 @@ bool page_is_tag_storage(struct page *page);
> > >
> > >  vm_fault_t handle_folio_missing_tag_storage(struct folio *folio, struct vm_fault *vmf,
> > >                                             bool *map_pte);
> > > +vm_fault_t mte_try_transfer_swap_tags(swp_entry_t entry, struct page *page);
> > > +
> > > +void tags_by_pfn_lock(void);
> > > +void tags_by_pfn_unlock(void);
> > > +
> > > +void *mte_erase_tags_for_pfn(unsigned long pfn);
> > > +bool mte_save_tags_for_pfn(void *tags, unsigned long pfn);
> > > +void mte_restore_tags_for_pfn(unsigned long start_pfn, int order);
> > >  #else
> > >  static inline bool tag_storage_enabled(void)
> > >  {
> > > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> > > index 0174e292f890..87ae59436162 100644
> > > --- a/arch/arm64/include/asm/pgtable.h
> > > +++ b/arch/arm64/include/asm/pgtable.h
> > > @@ -1085,6 +1085,17 @@ static inline void arch_swap_invalidate_area(int type)
> > >                 mte_invalidate_tags_area_by_swp_entry(type);
> > >  }
> > >
> > > +#ifdef CONFIG_ARM64_MTE_TAG_STORAGE
> > > +#define __HAVE_ARCH_SWAP_PREPARE_TO_RESTORE
> > > +static inline vm_fault_t arch_swap_prepare_to_restore(swp_entry_t entry,
> > > +                                                     struct folio *folio)
> > > +{
> > > +       if (tag_storage_enabled())
> > > +               return mte_try_transfer_swap_tags(entry, &folio->page);
> > > +       return 0;
> > > +}
> > > +#endif
> > > +
> > >  #define __HAVE_ARCH_SWAP_RESTORE
> > >  static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
> > >  {
> > > diff --git a/arch/arm64/kernel/mte_tag_storage.c b/arch/arm64/kernel/mte_tag_storage.c
> > > index afe2bb754879..ac7b9c9c585c 100644
> > > --- a/arch/arm64/kernel/mte_tag_storage.c
> > > +++ b/arch/arm64/kernel/mte_tag_storage.c
> > > @@ -567,6 +567,7 @@ int reserve_tag_storage(struct page *page, int order, gfp_t gfp)
> > >                 }
> > >         }
> > >
> > > +       mte_restore_tags_for_pfn(page_to_pfn(page), order);
> > >         page_set_tag_storage_reserved(page, order);
> > >  out_unlock:
> > >         mutex_unlock(&tag_blocks_lock);
> > > @@ -595,7 +596,8 @@ void free_tag_storage(struct page *page, int order)
> > >         struct tag_region *region;
> > >         unsigned long page_va;
> > >         unsigned long flags;
> > > -       int ret;
> > > +       void *tags;
> > > +       int i, ret;
> > >
> > >         ret = tag_storage_find_block(page, &start_block, &region);
> > >         if (WARN_ONCE(ret, "Missing tag storage block for pfn 0x%lx", page_to_pfn(page)))
> > > @@ -605,6 +607,14 @@ void free_tag_storage(struct page *page, int order)
> > >         /* Avoid writeback of dirty tag cache lines corrupting data. */
> > >         dcache_inval_tags_poc(page_va, page_va + (PAGE_SIZE << order));
> > >
> > > +       tags_by_pfn_lock();
> > > +       for (i = 0; i < (1 << order); i++) {
> > > +               tags = mte_erase_tags_for_pfn(page_to_pfn(page + i));
> > > +               if (unlikely(tags))
> > > +                       mte_free_tag_buf(tags);
> > > +       }
> > > +       tags_by_pfn_unlock();
> > > +
> > >         end_block = start_block + order_to_num_blocks(order, region->block_size_pages);
> > >
> > >         xa_lock_irqsave(&tag_blocks_reserved, flags);
> > > diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
> > > index 2a43746b803f..e11495fa3c18 100644
> > > --- a/arch/arm64/mm/mteswap.c
> > > +++ b/arch/arm64/mm/mteswap.c
> > > @@ -20,6 +20,112 @@ void mte_free_tag_buf(void *buf)
> > >         kfree(buf);
> > >  }
> > >
> > > +#ifdef CONFIG_ARM64_MTE_TAG_STORAGE
> > > +static DEFINE_XARRAY(tags_by_pfn);
> > > +
> > > +void tags_by_pfn_lock(void)
> > > +{
> > > +       xa_lock(&tags_by_pfn);
> > > +}
> > > +
> > > +void tags_by_pfn_unlock(void)
> > > +{
> > > +       xa_unlock(&tags_by_pfn);
> > > +}
> > > +
> > > +void *mte_erase_tags_for_pfn(unsigned long pfn)
> > > +{
> > > +       return __xa_erase(&tags_by_pfn, pfn);
> > > +}
> > > +
> > > +bool mte_save_tags_for_pfn(void *tags, unsigned long pfn)
> > > +{
> > > +       void *entry;
> > > +       int ret;
> > > +
> > > +       ret = xa_reserve(&tags_by_pfn, pfn, GFP_KERNEL);
> >
> > copy_highpage can be called from an atomic context, so it isn't
> > currently valid to pass GFP_KERNEL here.
> >
> > To give one example of a possible atomic context call, copy_pte_range
> > will take a PTE spinlock and can call copy_present_pte, which can call
> > copy_present_page, which will call copy_user_highpage.
> >
> > To give another example, __buffer_migrate_folio can call
> > spin_lock(&mapping->private_lock), then call folio_migrate_copy, which
> > will call folio_copy.
>
> That is very unfortunate from my part. I distinctly remember looking
> precisely at copy_page_range() to double check that it doesn't call
> copy_*highpage() from an atomic context, I can only assume that I missed
> that it's called with the ptl lock held.
>
> With your two examples, and the khugepaged case in patch #31 ("khugepaged:
> arm64: Don't collapse MTE enabled VMAs"), it's crystal clear that the
> convention for copy_*highpage() is that the function cannot sleep.
>
> There are two issues here: allocating the buffer in memory where the tags
> will be copied, and xarray allocating memory for a new entry.
>
> One fix would be to allocate an entire page with __GFP_ATOMIC, and use that
> as a cache for tag buffers (storing the tags for a page uses 1/32th of a
> page). From what little I know about xarray, xarray stores would still have
> to be GFP_ATOMIC. This should fix the sleeping in atomic context bug. But
> the issue I see with this is that a memory allocation can fail, while
> copy_*highpage() cannot. Send a fatal signal to the process if memory
> allocation fails?

Right, I think I'd have stability concerns about an approach like this.

> Another approach would be to preallocate memory in a preemptible context,
> something like copy_*highpage_prepare(), but that would mean a lot more
> work: finding all the places where copy_*highpage is used and add
> copy_*highpage_prepare() outside the critical section, releasing the memory
> in case of failure (like in the copy_pte_range() case - maybe
> copy_*highpage_end()?). That's a pretty big maintenance burden for the MM
> code. Although maybe other architectures can find a use for it?

This one might not be too bad. There are only a handful of calls to
this function, so it might not be a major ongoing burden. We can
implement copy_highpage() like this:

copy_highpage() {
  might_sleep();
  copy_highpage_atomic();
}

rename the existing implementations to copy_highpage_atomic() and
change atomic context callers to call copy_highpage_atomic(). That
way, kernels with CONFIG_DEBUG_ATOMIC_SLEEP will detect errors on all
architectures. Then in a later patch, introduce
copy_highpage_prepare() (or whatever) and update the
copy_highpage_atomic() callers.

Peter

> And yet another approach is reserve the needed memory (for the buffer and
> in the xarray) when the page is allocated, if it doesn't have tag storage
> reserved, regardless of the page being allocated as tagged or not. Then in
> set_pte_at() free this memory if it's unused. But this would mean reserving
> memory for possibly all memory allocations in the system (including for tag
> storage pages) if userspace doesn't use tags at all, though not all pages
> in the system will have this memory reserved at the same time. Pretty big
> downside.
>
> Out of the three, I prefer the first, but it's definitely not perfect. I'll
> try to think of something else, maybe I can come up with something better.
>
> What are your thoughts?
>
> Thanks,
> Alex
>
> >
> > Peter
> >
> > > +       if (ret)
> > > +               return true;
> > > +
> > > +       tags_by_pfn_lock();
> > > +
> > > +       if (page_tag_storage_reserved(pfn_to_page(pfn))) {
> > > +               xa_release(&tags_by_pfn, pfn);
> > > +               tags_by_pfn_unlock();
> > > +               return false;
> > > +       }
> > > +
> > > +       entry = __xa_store(&tags_by_pfn, pfn, tags, GFP_ATOMIC);
> > > +       if (xa_is_err(entry)) {
> > > +               xa_release(&tags_by_pfn, pfn);
> > > +               goto out_unlock;
> > > +       } else if (entry) {
> > > +               mte_free_tag_buf(entry);
> > > +       }
> > > +
> > > +out_unlock:
> > > +       tags_by_pfn_unlock();
> > > +       return true;
> > > +}
> > > +
> > > +void mte_restore_tags_for_pfn(unsigned long start_pfn, int order)
> > > +{
> > > +       struct page *page = pfn_to_page(start_pfn);
> > > +       unsigned long pfn;
> > > +       void *tags;
> > > +
> > > +       tags_by_pfn_lock();
> > > +
> > > +       for (pfn = start_pfn; pfn < start_pfn + (1 << order); pfn++, page++) {
> > > +               tags = mte_erase_tags_for_pfn(pfn);
> > > +               if (unlikely(tags)) {
> > > +                       /*
> > > +                        * Mark the page as tagged so mte_sync_tags() doesn't
> > > +                        * clear the tags.
> > > +                        */
> > > +                       WARN_ON_ONCE(!try_page_mte_tagging(page));
> > > +                       mte_copy_page_tags_from_buf(page_address(page), tags);
> > > +                       set_page_mte_tagged(page);
> > > +                       mte_free_tag_buf(tags);
> > > +               }
> > > +       }
> > > +
> > > +       tags_by_pfn_unlock();
> > > +}
> > > +
> > > +/*
> > > + * Note on locking: swap in/out is done with the folio locked, which eliminates
> > > + * races with mte_save/restore_page_tags_by_swp_entry.
> > > + */
> > > +vm_fault_t mte_try_transfer_swap_tags(swp_entry_t entry, struct page *page)
> > > +{
> > > +       void *swap_tags, *pfn_tags;
> > > +       bool saved;
> > > +
> > > +       /*
> > > +        * mte_restore_page_tags_by_swp_entry() will take care of copying the
> > > +        * tags over.
> > > +        */
> > > +       if (likely(page_mte_tagged(page) || page_tag_storage_reserved(page)))
> > > +               return 0;
> > > +
> > > +       swap_tags = xa_load(&tags_by_swp_entry, entry.val);
> > > +       if (!swap_tags)
> > > +               return 0;
> > > +
> > > +       pfn_tags = mte_allocate_tag_buf();
> > > +       if (!pfn_tags)
> > > +               return VM_FAULT_OOM;
> > > +
> > > +       memcpy(pfn_tags, swap_tags, MTE_PAGE_TAG_STORAGE_SIZE);
> > > +       saved = mte_save_tags_for_pfn(pfn_tags, page_to_pfn(page));
> > > +       if (!saved)
> > > +               mte_free_tag_buf(pfn_tags);
> > > +
> > > +       return 0;
> > > +}
> > > +#endif
> > > +
> > >  int mte_save_page_tags_by_swp_entry(struct page *page)
> > >  {
> > >         void *tags, *ret;
> > > @@ -54,6 +160,10 @@ void mte_restore_page_tags_by_swp_entry(swp_entry_t entry, struct page *page)
> > >         if (!tags)
> > >                 return;
> > >
> > > +       /* Tags will be restored when tag storage is reserved. */
> > > +       if (tag_storage_enabled() && unlikely(!page_tag_storage_reserved(page)))
> > > +               return;
> > > +
> > >         if (try_page_mte_tagging(page)) {
> > >                 mte_copy_page_tags_from_buf(page_address(page), tags);
> > >                 set_page_mte_tagged(page);
> > > --
> > > 2.43.0
> > >


From namhyung at kernel.org  Fri Feb  2 17:54:33 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Fri, 2 Feb 2024 17:54:33 -0800
Subject: [PATCH 0/1] tools: perf: Expose sample ID / stream ID to python scripts
In-Reply-To: <20240123103137.1890779-1-ben.gainey@arm.com>
References: <20240123103137.1890779-1-ben.gainey@arm.com>
Message-ID: <CAM9d7cjTm0y9cPy7RpRVGaphD6TBEbnRANc+8kRAvjrBtfq6NQ@mail.gmail.com>

Hello,

On Tue, Jan 23, 2024 at 2:32?AM Ben Gainey <ben.gainey at arm.com> wrote:
>
> This patch modifies the perf python scripting engine so that the ID and
> STREAM_ID are exposed as part of the sample so that they may be
> correlated to the corresponding throttle/unthrottle event (for example).
>
> NB: For scripts where perf_db_export_mode = True, this may be a breaking
> change depending on how the script is constructed. Each field is passed
> to `sample_table` as an argument so any script that is written as:
>
>     def sample_table(db_id, evsel_id, machine_id, ..., cyc_cnt, flags)
>
> will now fail due to the changed number of arguments with:
>
>     TypeError: sample_table() takes 25 positional arguments but 27 were given
>
> Scripts that use:
>
>     def sample_table(*args)
>
> or some variation thereof will not be affected.
>
> When `perf_db_export_mode = False`, the script should be unaffected as
> all the arguments are inserted into a dictionary.
>
> The export-to-xxx.py scripts use the (..., *x) form so are not affected.

As long as all in-tree users are fine, I think it's ok.

Thanks,
Namhyung

>
>
> Ben Gainey (1):
>   tools: perf: Expose sample ID / stream ID to python scripts
>
>  tools/perf/Documentation/perf-script-python.txt        | 4 ++--
>  tools/perf/util/scripting-engines/trace-event-python.c | 8 +++++++-
>  2 files changed, 9 insertions(+), 3 deletions(-)
>
> --
> 2.43.0
>


From m.shams at samsung.com  Fri Feb  2 13:24:47 2024
From: m.shams at samsung.com (Tamseel Shams)
Date: Sat,  3 Feb 2024 02:54:47 +0530
Subject: [PATCH 1/2] serial: samsung: honor fifosize from dts at first
References: <CGME20240202212456epcas5p15589813cd79526e9d0c444082e2f0e51@epcas5p1.samsung.com>
Message-ID: <20240202212448.74840-1-m.shams@samsung.com>

Currently for platforms which passes UART fifosize from DT gets
override by local driver structure "s3c24xx_serial_drv_data",
which is not indentded. Change the code to honor fifosize from
device tree at first.

Signed-off-by: Tamseel Shams <m.shams at samsung.com>
---
 drivers/tty/serial/samsung_tty.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 71d17d804fda..e4c4c9f4f9b0 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -1990,8 +1990,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 	}
 
 	if (np) {
-		of_property_read_u32(np,
-			"samsung,uart-fifosize", &ourport->port.fifosize);
+		ret = of_property_read_u32(np, "samsung,uart-fifosize", &ourport->port.fifosize);
 
 		if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
 			switch (prop) {
@@ -2009,10 +2008,13 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (ourport->drv_data->fifosize[index])
-		ourport->port.fifosize = ourport->drv_data->fifosize[index];
-	else if (ourport->info->fifosize)
-		ourport->port.fifosize = ourport->info->fifosize;
+	if (ret) {
+		if (ourport->drv_data->fifosize[index])
+			ourport->port.fifosize = ourport->drv_data->fifosize[index];
+		else if (ourport->info->fifosize)
+			ourport->port.fifosize = ourport->info->fifosize;
+	}
+
 	ourport->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_SAMSUNG_CONSOLE);
 
 	/*
-- 
2.17.1



From m.shams at samsung.com  Fri Feb  2 13:24:48 2024
From: m.shams at samsung.com (Tamseel Shams)
Date: Sat,  3 Feb 2024 02:54:48 +0530
Subject: [PATCH 2/2] arm64: dts: fsd: Add fifosize for UART in Device Tree
In-Reply-To: <20240202212448.74840-1-m.shams@samsung.com>
References: <20240202212448.74840-1-m.shams@samsung.com>
	<CGME20240202212459epcas5p2e1703c35ebe9302ac5b2f3d3fcd853c0@epcas5p2.samsung.com>
Message-ID: <20240202212448.74840-2-m.shams@samsung.com>

UART in FSD SoC has fifosize of 64 bytes.
Set fifosize as 64 bytes for UART from Device Tree.

Signed-off-by: Tamseel Shams <m.shams at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index aaffb50b8b60..047a83cee603 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -601,6 +601,7 @@
 			clocks = <&clock_peric PERIC_PCLK_UART0>,
 				 <&clock_peric PERIC_SCLK_UART0>;
 			clock-names = "uart", "clk_uart_baud0";
+			samsung,uart-fifosize = <64>;
 			status = "disabled";
 		};
 
@@ -613,6 +614,7 @@
 			clocks = <&clock_peric PERIC_PCLK_UART1>,
 				 <&clock_peric PERIC_SCLK_UART1>;
 			clock-names = "uart", "clk_uart_baud0";
+			samsung,uart-fifosize = <64>;
 			status = "disabled";
 		};
 
-- 
2.17.1



From gregkh at linuxfoundation.org  Fri Feb  2 20:05:31 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Fri,  2 Feb 2024 20:05:31 -0800
Subject: [PATCH 6.1 158/219] perf cs-etm: Bump minimum OpenCSD version to ensure a bugfix is present
In-Reply-To: <20240203035317.354186483@linuxfoundation.org>
References: <20240203035317.354186483@linuxfoundation.org>
Message-ID: <20240203035338.872706817@linuxfoundation.org>

6.1-stable review patch.  If anyone has any objections, please let me know.

------------------

From: James Clark <james.clark at arm.com>

[ Upstream commit 2dbba30fd69b604802a9535b74bddb5bcca23793 ]

Since commit d927ef5004ef ("perf cs-etm: Add exception level consistency
check"), the exception that was added to Perf will be triggered unless
the following bugfix from OpenCSD is present:

 - _Version 1.2.1_:
  - __Bugfix__:
    ETM4x / ETE - output of context elements to client can in some
    circumstances be delayed until after subsequent atoms have been
    processed leading to incorrect memory decode access via the client
    callbacks. Fixed to flush context elements immediately they are
    committed.

Rather than remove the assert and silently fail, just increase the
minimum version requirement to avoid hard to debug issues and
regressions.

Reviewed-by: Ian Rogers <irogers at google.com>
Signed-off-by: James Clark <james.clark at arm.com>
Tested-by: Leo Yan <leo.yan at linaro.org>
Cc: John Garry <john.g.garry at oracle.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Link: https://lore.kernel.org/r/20230901133716.677499-1-james.clark at arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme at redhat.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/build/feature/test-libopencsd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/build/feature/test-libopencsd.c b/tools/build/feature/test-libopencsd.c
index eb6303ff446e..4cfcef9da3e4 100644
--- a/tools/build/feature/test-libopencsd.c
+++ b/tools/build/feature/test-libopencsd.c
@@ -4,9 +4,9 @@
 /*
  * Check OpenCSD library version is sufficient to provide required features
  */
-#define OCSD_MIN_VER ((1 << 16) | (1 << 8) | (1))
+#define OCSD_MIN_VER ((1 << 16) | (2 << 8) | (1))
 #if !defined(OCSD_VER_NUM) || (OCSD_VER_NUM < OCSD_MIN_VER)
-#error "OpenCSD >= 1.1.1 is required"
+#error "OpenCSD >= 1.2.1 is required"
 #endif
 
 int main(void)
-- 
2.43.0





From davidgow at google.com  Fri Feb  2 20:10:17 2024
From: davidgow at google.com (David Gow)
Date: Sat, 3 Feb 2024 12:10:17 +0800
Subject: [PATCH v3 7/7] of: Add KUnit test to confirm DTB is loaded
In-Reply-To: <20240202195909.3458162-8-sboyd@kernel.org>
References: <20240202195909.3458162-1-sboyd@kernel.org> <20240202195909.3458162-8-sboyd@kernel.org>
Message-ID: <CABVgOS=A8BQ6HHpBKFqg-N10ckk2XYavaS-MPXvZ0wenrVm=1g@mail.gmail.com>

On Sat, 3 Feb 2024 at 03:59, Stephen Boyd <sboyd at kernel.org> wrote:
>
> Add a KUnit test that confirms a DTB has been loaded, i.e. there is a
> root node, and that the of_have_populated_dt() API works properly.
>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Frank Rowand <frowand.list at gmail.com>
> Cc: David Gow <davidgow at google.com>
> Cc: Brendan Higgins <brendan.higgins at linux.dev>
> Signed-off-by: Stephen Boyd <sboyd at kernel.org>
> ---

This looks pretty good to me test-wise, though it still fails on m68k.
(Everything else I tried it on works, though I've definitely not tried
_every_ architecture.)

aarch64: PASSED
i386: PASSED
x86_64: PASSED
x86_64 KASAN: PASSED
powerpc64: PASSED
UML: PASSED
UML LLVM: PASSED
m68k: FAILED
> $ qemu-system-m68k -nodefaults -m 1024 -kernel .kunit-all-m68k/vmlinux -append 'kunit.enable=1 console=hvc0 kunit_shutdown=reboot' -no-reboot -nographic -serial stdio -machine virt
> [11:55:05] ===================== dtb (2 subtests) =====================
> [11:55:05] # dtb_root_node_found_by_path: EXPECTATION FAILED at drivers/of/of_test.c:18
> [11:55:05] Expected np is not null, but is
> [11:55:05] [FAILED] dtb_root_node_found_by_path
> [11:55:05] # dtb_root_node_populates_of_root: EXPECTATION FAILED at drivers/of/of_test.c:28
> [11:55:05] Expected of_root is not null, but is
> [11:55:05] [FAILED] dtb_root_node_populates_of_root
> [11:55:05]     # module: of_test
> [11:55:05] # dtb: pass:0 fail:2 skip:0 total:2
> [11:55:05] # Totals: pass:0 fail:2 skip:0 total:2
> [11:55:05] ======================= [FAILED] dtb =======================


My only other question is about the test names: the mix of 'of' and
'dtb' can be a bit confusing. As is, we have:
kconfig name: OF_KUNIT_TEST
module name: of_test
suite name: dtb
test names: all start with dtb_

Given KUnit only really deals with the suite/test names directly, it's
not trivial to see that 'dtb.dtb_*' is controlled by OF_KUNIT_TEST and
in of_test if built as a module. (This is getting a bit easier now
that we have the 'module' attribute in the output, but still.)

Would 'of_dtb' work as a suite name if it's important to keep both
'of' and 'dtb'?

In general, though, this test looks good to me. Particularly if m68k
can be fixed.

Reviewed-by: David Gow <davidgow at google.com>

Cheers,
-- David

>  drivers/of/.kunitconfig |  3 +++
>  drivers/of/Kconfig      |  9 ++++++++
>  drivers/of/Makefile     |  2 ++
>  drivers/of/of_test.c    | 48 +++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 62 insertions(+)
>  create mode 100644 drivers/of/.kunitconfig
>  create mode 100644 drivers/of/of_test.c
>
> diff --git a/drivers/of/.kunitconfig b/drivers/of/.kunitconfig
> new file mode 100644
> index 000000000000..5a8fee11978c
> --- /dev/null
> +++ b/drivers/of/.kunitconfig
> @@ -0,0 +1,3 @@
> +CONFIG_KUNIT=y
> +CONFIG_OF=y
> +CONFIG_OF_KUNIT_TEST=y
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index 17733285b415..53d1b5dd89e8 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -37,6 +37,15 @@ config OF_UNITTEST
>
>           If unsure, say N here. This option is not safe to enable.
>
> +config OF_KUNIT_TEST
> +       tristate "Devicetree KUnit Test" if !KUNIT_ALL_TESTS
> +       depends on KUNIT
> +       default KUNIT_ALL_TESTS
> +       help
> +         This option builds KUnit unit tests for device tree infrastructure.
> +
> +         If unsure, say N here, but this option is safe to enable.
> +
>  config OF_ALL_DTBS
>         bool "Build all Device Tree Blobs"
>         depends on COMPILE_TEST
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index df305348d1cb..251d33532148 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -19,4 +19,6 @@ obj-y += kexec.o
>  endif
>  endif
>
> +obj-$(CONFIG_OF_KUNIT_TEST) += of_test.o
> +
>  obj-$(CONFIG_OF_UNITTEST) += unittest-data/
> diff --git a/drivers/of/of_test.c b/drivers/of/of_test.c
> new file mode 100644
> index 000000000000..71a767b42b43
> --- /dev/null
> +++ b/drivers/of/of_test.c
> @@ -0,0 +1,48 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * KUnit tests for OF APIs
> + */
> +#include <linux/module.h>
> +#include <linux/of.h>
> +
> +#include <kunit/test.h>
> +
> +/*
> + * Test that the root node "/" can be found by path.
> + */
> +static void dtb_root_node_found_by_path(struct kunit *test)
> +{
> +       struct device_node *np;
> +
> +       np = of_find_node_by_path("/");
> +       KUNIT_EXPECT_NOT_ERR_OR_NULL(test, np);
> +       of_node_put(np);
> +}
> +
> +/*
> + * Test that the 'of_root' global variable is always populated when DT code is
> + * enabled.
> + */
> +static void dtb_root_node_populates_of_root(struct kunit *test)
> +{
> +       KUNIT_EXPECT_NOT_ERR_OR_NULL(test, of_root);
> +}
> +
> +static struct kunit_case dtb_test_cases[] = {
> +       KUNIT_CASE(dtb_root_node_found_by_path),
> +       KUNIT_CASE(dtb_root_node_populates_of_root),
> +       {}
> +};
> +
> +/*
> + * Test suite to confirm a DTB is loaded.
> + */
> +static struct kunit_suite dtb_suite = {
> +       .name = "dtb",
> +       .test_cases = dtb_test_cases,
> +};
> +
> +kunit_test_suites(
> +       &dtb_suite,
> +);
> +MODULE_LICENSE("GPL");
> --
> https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
> https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
>
> --
> You received this message because you are subscribed to the Google Groups "KUnit Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to kunit-dev+unsubscribe at googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/kunit-dev/20240202195909.3458162-8-sboyd%40kernel.org.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4014 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240203/b5859eae/attachment.p7s>

From gregkh at linuxfoundation.org  Fri Feb  2 20:05:28 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Fri,  2 Feb 2024 20:05:28 -0800
Subject: [PATCH 6.6 231/322] perf cs-etm: Bump minimum OpenCSD version to ensure a bugfix is present
In-Reply-To: <20240203035359.041730947@linuxfoundation.org>
References: <20240203035359.041730947@linuxfoundation.org>
Message-ID: <20240203035406.665227222@linuxfoundation.org>

6.6-stable review patch.  If anyone has any objections, please let me know.

------------------

From: James Clark <james.clark at arm.com>

[ Upstream commit 2dbba30fd69b604802a9535b74bddb5bcca23793 ]

Since commit d927ef5004ef ("perf cs-etm: Add exception level consistency
check"), the exception that was added to Perf will be triggered unless
the following bugfix from OpenCSD is present:

 - _Version 1.2.1_:
  - __Bugfix__:
    ETM4x / ETE - output of context elements to client can in some
    circumstances be delayed until after subsequent atoms have been
    processed leading to incorrect memory decode access via the client
    callbacks. Fixed to flush context elements immediately they are
    committed.

Rather than remove the assert and silently fail, just increase the
minimum version requirement to avoid hard to debug issues and
regressions.

Reviewed-by: Ian Rogers <irogers at google.com>
Signed-off-by: James Clark <james.clark at arm.com>
Tested-by: Leo Yan <leo.yan at linaro.org>
Cc: John Garry <john.g.garry at oracle.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Link: https://lore.kernel.org/r/20230901133716.677499-1-james.clark at arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme at redhat.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/build/feature/test-libopencsd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/build/feature/test-libopencsd.c b/tools/build/feature/test-libopencsd.c
index eb6303ff446e..4cfcef9da3e4 100644
--- a/tools/build/feature/test-libopencsd.c
+++ b/tools/build/feature/test-libopencsd.c
@@ -4,9 +4,9 @@
 /*
  * Check OpenCSD library version is sufficient to provide required features
  */
-#define OCSD_MIN_VER ((1 << 16) | (1 << 8) | (1))
+#define OCSD_MIN_VER ((1 << 16) | (2 << 8) | (1))
 #if !defined(OCSD_VER_NUM) || (OCSD_VER_NUM < OCSD_MIN_VER)
-#error "OpenCSD >= 1.1.1 is required"
+#error "OpenCSD >= 1.2.1 is required"
 #endif
 
 int main(void)
-- 
2.43.0





From gregkh at linuxfoundation.org  Fri Feb  2 20:06:10 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Fri,  2 Feb 2024 20:06:10 -0800
Subject: [PATCH 6.7 252/353] perf cs-etm: Bump minimum OpenCSD version to ensure a bugfix is present
In-Reply-To: <20240203035403.657508530@linuxfoundation.org>
References: <20240203035403.657508530@linuxfoundation.org>
Message-ID: <20240203035411.706914415@linuxfoundation.org>

6.7-stable review patch.  If anyone has any objections, please let me know.

------------------

From: James Clark <james.clark at arm.com>

[ Upstream commit 2dbba30fd69b604802a9535b74bddb5bcca23793 ]

Since commit d927ef5004ef ("perf cs-etm: Add exception level consistency
check"), the exception that was added to Perf will be triggered unless
the following bugfix from OpenCSD is present:

 - _Version 1.2.1_:
  - __Bugfix__:
    ETM4x / ETE - output of context elements to client can in some
    circumstances be delayed until after subsequent atoms have been
    processed leading to incorrect memory decode access via the client
    callbacks. Fixed to flush context elements immediately they are
    committed.

Rather than remove the assert and silently fail, just increase the
minimum version requirement to avoid hard to debug issues and
regressions.

Reviewed-by: Ian Rogers <irogers at google.com>
Signed-off-by: James Clark <james.clark at arm.com>
Tested-by: Leo Yan <leo.yan at linaro.org>
Cc: John Garry <john.g.garry at oracle.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Link: https://lore.kernel.org/r/20230901133716.677499-1-james.clark at arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme at redhat.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/build/feature/test-libopencsd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/build/feature/test-libopencsd.c b/tools/build/feature/test-libopencsd.c
index eb6303ff446e..4cfcef9da3e4 100644
--- a/tools/build/feature/test-libopencsd.c
+++ b/tools/build/feature/test-libopencsd.c
@@ -4,9 +4,9 @@
 /*
  * Check OpenCSD library version is sufficient to provide required features
  */
-#define OCSD_MIN_VER ((1 << 16) | (1 << 8) | (1))
+#define OCSD_MIN_VER ((1 << 16) | (2 << 8) | (1))
 #if !defined(OCSD_VER_NUM) || (OCSD_VER_NUM < OCSD_MIN_VER)
-#error "OpenCSD >= 1.1.1 is required"
+#error "OpenCSD >= 1.2.1 is required"
 #endif
 
 int main(void)
-- 
2.43.0





From lkp at intel.com  Fri Feb  2 20:20:06 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 3 Feb 2024 12:20:06 +0800
Subject: [PATCH 09/18] power: reset: rmobile-reset: Use
 devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240201180102.70395-10-afd@ti.com>
References: <20240201180102.70395-10-afd@ti.com>
Message-ID: <202402031246.nZHDnDnf-lkp@intel.com>

Hi Andrew,

kernel test robot noticed the following build warnings:

[auto build test WARNING on sre-power-supply/for-next]
[also build test WARNING on mani-mhi/mhi-next soc/for-next linus/master v6.8-rc2 next-20240202]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrew-Davis/power-reset-atc260x-poweroff-Use-devm_register_sys_off_handler-RESTART/20240202-020809
base:   https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git for-next
patch link:    https://lore.kernel.org/r/20240201180102.70395-10-afd%40ti.com
patch subject: [PATCH 09/18] power: reset: rmobile-reset: Use devm_register_sys_off_handler(RESTART)
config: hexagon-randconfig-r122-20240202 (https://download.01.org/0day-ci/archive/20240203/202402031246.nZHDnDnf-lkp at intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 7dd790db8b77c4a833c06632e903dc4f13877a64)
reproduce: (https://download.01.org/0day-ci/archive/20240203/202402031246.nZHDnDnf-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402031246.nZHDnDnf-lkp at intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/power/reset/rmobile-reset.c:24:40: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected void [noderef] __iomem *sysc_base2 @@     got void *cb_data @@
   drivers/power/reset/rmobile-reset.c:24:40: sparse:     expected void [noderef] __iomem *sysc_base2
   drivers/power/reset/rmobile-reset.c:24:40: sparse:     got void *cb_data
>> drivers/power/reset/rmobile-reset.c:45:47: sparse: sparse: incorrect type in argument 5 (different address spaces) @@     expected void *cb_data @@     got void [noderef] __iomem *[assigned] sysc_base2 @@
   drivers/power/reset/rmobile-reset.c:45:47: sparse:     expected void *cb_data
   drivers/power/reset/rmobile-reset.c:45:47: sparse:     got void [noderef] __iomem *[assigned] sysc_base2

vim +24 drivers/power/reset/rmobile-reset.c

    21	
    22	static int rmobile_reset_handler(struct sys_off_data *data)
    23	{
  > 24		void __iomem *sysc_base2 = data->cb_data;
    25	
    26		/* Let's assume we have acquired the HPB semaphore */
    27		writel(RESCNT2_PRES, sysc_base2 + RESCNT2);
    28	
    29		return NOTIFY_DONE;
    30	}
    31	
    32	static int rmobile_reset_probe(struct platform_device *pdev)
    33	{
    34		void __iomem *sysc_base2;
    35		int error;
    36	
    37		sysc_base2 = devm_platform_ioremap_resource(pdev, 0);
    38		if (IS_ERR(sysc_base2))
    39			return PTR_ERR(sysc_base2);
    40	
    41		error = devm_register_sys_off_handler(&pdev->dev,
    42						      SYS_OFF_MODE_RESTART,
    43						      SYS_OFF_PRIO_HIGH,
    44						      rmobile_reset_handler,
  > 45						      sysc_base2);
    46		if (error) {
    47			dev_err(&pdev->dev,
    48				"cannot register restart handler (err=%d)\n", error);
    49			return error;
    50		}
    51	
    52		return 0;
    53	}
    54	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From lkp at intel.com  Fri Feb  2 21:06:55 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 03 Feb 2024 13:06:55 +0800
Subject: [linux-next:master] BUILD REGRESSION
 076d56d74f17e625b3d63cf4743b3d7d02180379
Message-ID: <202402031349.faJAWJvP-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: 076d56d74f17e625b3d63cf4743b3d7d02180379  Add linux-next specific files for 20240202

Error/Warning reports:

https://lore.kernel.org/oe-kbuild-all/202402030006.2bwG9hee-lkp at intel.com
https://lore.kernel.org/oe-kbuild-all/202402030306.l4idnFyz-lkp at intel.com
https://lore.kernel.org/oe-kbuild-all/202402030631.6mCz0axA-lkp at intel.com

Error/Warning: (recently discovered and may have been fixed)

or1k-linux-ld: sound_kunit.c:(.text+0x118): undefined reference to `snd_pcm_format_name'
or1k-linux-ld: sound_kunit.c:(.text+0x410): undefined reference to `snd_pcm_format_unsigned'
or1k-linux-ld: sound_kunit.c:(.text+0x490): undefined reference to `snd_pcm_format_width'
or1k-linux-ld: sound_kunit.c:(.text+0x794): undefined reference to `snd_pcm_format_big_endian'
or1k-linux-ld: sound_kunit.c:(.text+0x814): undefined reference to `snd_pcm_format_little_endian'
or1k-linux-ld: sound_kunit.c:(.text+0xa50): undefined reference to `snd_pcm_format_physical_width'
or1k-linux-ld: sound_kunit.c:(.text+0xc48): undefined reference to `snd_pcm_format_set_silence'
sound_kunit.c:(.text+0x258): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `snd_pcm_format_set_silence'
sound_kunit.c:(.text+0x258): undefined reference to `snd_pcm_format_set_silence'
sound_kunit.c:(.text+0x3b0): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `snd_pcm_format_signed'
sound_kunit.c:(.text+0x3b0): undefined reference to `snd_pcm_format_signed'
sound_kunit.c:(.text+0x410): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `snd_pcm_format_unsigned'
sound_kunit.c:(.text+0x490): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `snd_pcm_format_width'
sound_kunit.c:(.text+0x54): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `snd_pcm_format_name'
sound_kunit.c:(.text+0x54): undefined reference to `snd_pcm_format_name'
sound_kunit.c:(.text+0x5b4): undefined reference to `snd_pcm_format_width'
sound_kunit.c:(.text+0x734): undefined reference to `snd_pcm_format_little_endian'
sound_kunit.c:(.text+0x9ec): undefined reference to `snd_pcm_format_physical_width'

Unverified Error/Warning (likely false positive, please contact us if interested):

{standard input}:671: Warning: overflow in branch to .L87; converted into longer instruction sequence

Error/Warning ids grouped by kconfigs:

gcc_recent_errors
|-- arm-allmodconfig
|   |-- drivers-dma-at_hdmac.c:warning:Enum-value-ATC_IS_CYCLIC-not-described-in-enum-atc_status
|   `-- drivers-dma-at_hdmac.c:warning:Enum-value-ATC_IS_PAUSED-not-described-in-enum-atc_status
|-- arm-allyesconfig
|   |-- drivers-dma-at_hdmac.c:warning:Enum-value-ATC_IS_CYCLIC-not-described-in-enum-atc_status
|   `-- drivers-dma-at_hdmac.c:warning:Enum-value-ATC_IS_PAUSED-not-described-in-enum-atc_status
|-- arm-randconfig-002-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- arm64-randconfig-004-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-001-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-006-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-011-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- loongarch-randconfig-001-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- m68k-randconfig-r063-20240203
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- mips-allyesconfig
|   |-- (.ref.text):relocation-truncated-to-fit:R_MIPS_26-against-start_secondary
|   `-- (.text):relocation-truncated-to-fit:R_MIPS_26-against-kernel_entry
|-- nios2-randconfig-002-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- openrisc-randconfig-r013-20211230
|   |-- or1k-linux-ld:sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_big_endian
|   |-- or1k-linux-ld:sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_little_endian
|   |-- or1k-linux-ld:sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_name
|   |-- or1k-linux-ld:sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_physical_width
|   |-- or1k-linux-ld:sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_set_silence
|   |-- or1k-linux-ld:sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_unsigned
|   |-- or1k-linux-ld:sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_width
|   |-- sound_kunit.c:(.text):relocation-truncated-to-fit:R_OR1K_INSN_REL_26-against-undefined-symbol-snd_pcm_format_name
|   |-- sound_kunit.c:(.text):relocation-truncated-to-fit:R_OR1K_INSN_REL_26-against-undefined-symbol-snd_pcm_format_set_silence
|   |-- sound_kunit.c:(.text):relocation-truncated-to-fit:R_OR1K_INSN_REL_26-against-undefined-symbol-snd_pcm_format_signed
|   |-- sound_kunit.c:(.text):relocation-truncated-to-fit:R_OR1K_INSN_REL_26-against-undefined-symbol-snd_pcm_format_unsigned
|   |-- sound_kunit.c:(.text):relocation-truncated-to-fit:R_OR1K_INSN_REL_26-against-undefined-symbol-snd_pcm_format_width
|   |-- sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_little_endian
|   |-- sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_name
|   |-- sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_physical_width
|   |-- sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_set_silence
|   |-- sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_signed
|   `-- sound_kunit.c:(.text):undefined-reference-to-snd_pcm_format_width
|-- parisc-randconfig-001-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- parisc-randconfig-002-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- sh-allmodconfig
|   `-- standard-input:Error:unknown-pseudo-op:cfi_def_
|-- sh-randconfig-002-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- sh-randconfig-r024-20230511
|   `-- standard-input:Warning:overflow-in-branch-to-.L87-converted-into-longer-instruction-sequence
|-- sh-randconfig-r062-20240203
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-buildonly-randconfig-005-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-005-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-102-20240203
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-103-20240203
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-r123-20240201
|   `-- mm-mempolicy.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-got-unsigned-char-noderef-usertype-__rcu-weights
`-- xtensa-randconfig-r052-20240203
    `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
clang_recent_errors
|-- arm-defconfig
|   |-- drivers-dma-at_hdmac.c:warning:Enum-value-ATC_IS_CYCLIC-not-described-in-enum-atc_status
|   `-- drivers-dma-at_hdmac.c:warning:Enum-value-ATC_IS_PAUSED-not-described-in-enum-atc_status
|-- hexagon-randconfig-r122-20240202
|   `-- net-ipv4-inet_diag.c:sparse:sparse:Using-plain-integer-as-NULL-pointer
|-- powerpc64-randconfig-003-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- s390-randconfig-r133-20240202
|   |-- mm-mempolicy.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-src-got-unsigned-char-noderef-usertype-__rcu-table
|   `-- mm-mempolicy.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-dest-got-unsigned-char-noderef-usertype-__rcu-weights
|-- x86_64-buildonly-randconfig-001-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-buildonly-randconfig-004-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-012-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-014-20240202
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
`-- x86_64-randconfig-072-20240202
    `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size

elapsed time: 1456m

configs tested: 178
configs skipped: 3

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                   randconfig-001-20240202   gcc  
arc                   randconfig-002-20240202   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm                         nhk8815_defconfig   clang
arm                          pxa168_defconfig   clang
arm                   randconfig-001-20240202   gcc  
arm                   randconfig-002-20240202   gcc  
arm                   randconfig-003-20240202   gcc  
arm                   randconfig-004-20240202   clang
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240202   gcc  
arm64                 randconfig-002-20240202   clang
arm64                 randconfig-003-20240202   gcc  
arm64                 randconfig-004-20240202   gcc  
csky                             alldefconfig   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240202   gcc  
csky                  randconfig-002-20240202   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
hexagon               randconfig-001-20240202   clang
hexagon               randconfig-002-20240202   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-001-20240202   gcc  
i386         buildonly-randconfig-002-20240202   clang
i386         buildonly-randconfig-003-20240202   gcc  
i386         buildonly-randconfig-004-20240202   clang
i386         buildonly-randconfig-005-20240202   clang
i386         buildonly-randconfig-006-20240202   gcc  
i386                                defconfig   clang
i386                  randconfig-001-20240202   gcc  
i386                  randconfig-002-20240202   gcc  
i386                  randconfig-003-20240202   clang
i386                  randconfig-004-20240202   gcc  
i386                  randconfig-005-20240202   gcc  
i386                  randconfig-006-20240202   gcc  
i386                  randconfig-011-20240202   gcc  
i386                  randconfig-012-20240202   gcc  
i386                  randconfig-013-20240202   gcc  
i386                  randconfig-014-20240202   clang
i386                  randconfig-015-20240202   gcc  
i386                  randconfig-016-20240202   clang
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240202   gcc  
loongarch             randconfig-002-20240202   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
m68k                       m5208evb_defconfig   gcc  
m68k                            mac_defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                           ip27_defconfig   gcc  
mips                     loongson1c_defconfig   gcc  
mips                      maltaaprp_defconfig   clang
mips                  maltasmvp_eva_defconfig   gcc  
mips                        maltaup_defconfig   clang
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240202   gcc  
nios2                 randconfig-002-20240202   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                generic-64bit_defconfig   gcc  
parisc                randconfig-001-20240202   gcc  
parisc                randconfig-002-20240202   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc                      ep88xc_defconfig   gcc  
powerpc                      pcm030_defconfig   clang
powerpc               randconfig-001-20240202   clang
powerpc               randconfig-002-20240202   clang
powerpc               randconfig-003-20240202   clang
powerpc64             randconfig-001-20240202   clang
powerpc64             randconfig-002-20240202   gcc  
powerpc64             randconfig-003-20240202   clang
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                 randconfig-001-20240202   gcc  
riscv                 randconfig-002-20240202   gcc  
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240202   clang
s390                  randconfig-002-20240202   clang
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                        edosk7760_defconfig   gcc  
sh                    randconfig-001-20240202   gcc  
sh                    randconfig-002-20240202   gcc  
sh                      rts7751r2d1_defconfig   gcc  
sh                   rts7751r2dplus_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240202   gcc  
sparc64               randconfig-002-20240202   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                    randconfig-001-20240202   clang
um                    randconfig-002-20240202   gcc  
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240202   clang
x86_64       buildonly-randconfig-002-20240202   clang
x86_64       buildonly-randconfig-003-20240202   clang
x86_64       buildonly-randconfig-004-20240202   clang
x86_64       buildonly-randconfig-005-20240202   gcc  
x86_64       buildonly-randconfig-006-20240202   gcc  
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240202   clang
x86_64                randconfig-002-20240202   clang
x86_64                randconfig-003-20240202   gcc  
x86_64                randconfig-004-20240202   gcc  
x86_64                randconfig-005-20240202   gcc  
x86_64                randconfig-006-20240202   gcc  
x86_64                randconfig-011-20240202   clang
x86_64                randconfig-012-20240202   clang
x86_64                randconfig-013-20240202   gcc  
x86_64                randconfig-014-20240202   clang
x86_64                randconfig-015-20240202   clang
x86_64                randconfig-016-20240202   clang
x86_64                randconfig-071-20240202   gcc  
x86_64                randconfig-072-20240202   clang
x86_64                randconfig-073-20240202   gcc  
x86_64                randconfig-074-20240202   clang
x86_64                randconfig-075-20240202   gcc  
x86_64                randconfig-076-20240202   clang
x86_64                          rhel-8.3-rust   clang
xtensa                            allnoconfig   gcc  
xtensa                randconfig-001-20240202   gcc  
xtensa                randconfig-002-20240202   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From 0x1207 at gmail.com  Fri Feb  2 21:11:54 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Sat, 3 Feb 2024 13:11:54 +0800
Subject: [PATCH net v3] net: stmmac: xgmac: fix handling of DPP safety
 error for DMA channels
In-Reply-To: <ksfs7uag4yukqbeygch7pxvr5axyrqz4gunq2xes3ppmtrgm5b@hwh5yx5qz3wl>
References: <20240131020828.2007741-1-0x1207@gmail.com>
	<ksfs7uag4yukqbeygch7pxvr5axyrqz4gunq2xes3ppmtrgm5b@hwh5yx5qz3wl>
Message-ID: <20240203131154.00005898@gmail.com>

On Sat, 3 Feb 2024 00:58:39 +0300
Serge Semin <fancer.lancer at gmail.com> wrote:

> On Wed, Jan 31, 2024 at 10:08:28AM +0800, Furong Xu wrote:
> > Commit 56e58d6c8a56 ("net: stmmac: Implement Safety Features in
> > XGMAC core") checks and reports safety errors, but leaves the
> > Data Path Parity Errors for each channel in DMA unhandled at all, lead to
> > a storm of interrupt.
> > Fix it by checking and clearing the DMA_DPP_Interrupt_Status register.
> > 
> > Fixes: 56e58d6c8a56 ("net: stmmac: Implement Safety Features in XGMAC core")
> > Signed-off-by: Furong Xu <0x1207 at gmail.com>
> > ---
> > Changes in v3:
> >  - code style fix, thanks Paolo Abeni
> > 
> > Changes in v2:
> >   - explicit enable Data Path Parity Protection
> >   - add new counters to stmmac_safety_stats
> >   - add detailed log
> > ---
> >  drivers/net/ethernet/stmicro/stmmac/common.h  |  1 +
> >  .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  3 +
> >  .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 57 ++++++++++++++++++-
> >  3 files changed, 60 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> > index 721c1f8e892f..b4f60ab078d6 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> > +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> > @@ -216,6 +216,7 @@ struct stmmac_safety_stats {
> >  	unsigned long mac_errors[32];
> >  	unsigned long mtl_errors[32];
> >  	unsigned long dma_errors[32];
> > +	unsigned long dma_dpp_errors[32];
> >  };
> >  
> >  /* Number of fields in Safety Stats */
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> > index 207ff1799f2c..5c67a3f89f08 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> > @@ -303,6 +303,8 @@
> >  #define XGMAC_RXCEIE			BIT(4)
> >  #define XGMAC_TXCEIE			BIT(0)
> >  #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
> > +#define XGMAC_MTL_DPP_CONTROL		0x000010e0  
> 
> > +#define XGMAC_DDPP_DISABLE		BIT(0)  
> 
> Is the double "D" a typo? Shouldn't this be XGMAC_DPP_DISABLE or just
> XGMAC_DDPP (if the "DDPP" means "Disable DPP")?
> 
> If so, David/Jakub, is it possible to rebase the branch with the macro
> fixed in the commit or a new cleanup patch is the only option?
> 
> Other than the nit above no more notes from my side:
> 
> Reviewed-by: Serge Semin <fancer.lancer at gmail.com>
> 
> -Serge(y)
> 

Hi Serge:

Sorry for my mistake.

DDPP is copied from Synopsys Data book: Disable Data path Parity Protection.
When it is 0x0, Data path Parity Protection is enabled.
When it is 0x1, Data path Parity Protection is disabled.

I will send a new patch.

> >  #define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
> >  #define XGMAC_TQS			GENMASK(25, 16)
> >  #define XGMAC_TQS_SHIFT			16
> > @@ -385,6 +387,7 @@
> >  #define XGMAC_DCEIE			BIT(1)
> >  #define XGMAC_TCEIE			BIT(0)
> >  #define XGMAC_DMA_ECC_INT_STATUS	0x0000306c
> > +#define XGMAC_DMA_DPP_INT_STATUS	0x00003074
> >  #define XGMAC_DMA_CH_CONTROL(x)		(0x00003100 + (0x80 * (x)))
> >  #define XGMAC_SPH			BIT(24)
> >  #define XGMAC_PBLx8			BIT(16)
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > index eb48211d9b0e..04d7c4dc2e35 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > @@ -830,6 +830,43 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
> >  	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
> >  };
> >  
> > +static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
> > +static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
> > +static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
> > +	{ true, "TDPES0", dpp_tx_err },
> > +	{ true, "TDPES1", dpp_tx_err },
> > +	{ true, "TDPES2", dpp_tx_err },
> > +	{ true, "TDPES3", dpp_tx_err },
> > +	{ true, "TDPES4", dpp_tx_err },
> > +	{ true, "TDPES5", dpp_tx_err },
> > +	{ true, "TDPES6", dpp_tx_err },
> > +	{ true, "TDPES7", dpp_tx_err },
> > +	{ true, "TDPES8", dpp_tx_err },
> > +	{ true, "TDPES9", dpp_tx_err },
> > +	{ true, "TDPES10", dpp_tx_err },
> > +	{ true, "TDPES11", dpp_tx_err },
> > +	{ true, "TDPES12", dpp_tx_err },
> > +	{ true, "TDPES13", dpp_tx_err },
> > +	{ true, "TDPES14", dpp_tx_err },
> > +	{ true, "TDPES15", dpp_tx_err },
> > +	{ true, "RDPES0", dpp_rx_err },
> > +	{ true, "RDPES1", dpp_rx_err },
> > +	{ true, "RDPES2", dpp_rx_err },
> > +	{ true, "RDPES3", dpp_rx_err },
> > +	{ true, "RDPES4", dpp_rx_err },
> > +	{ true, "RDPES5", dpp_rx_err },
> > +	{ true, "RDPES6", dpp_rx_err },
> > +	{ true, "RDPES7", dpp_rx_err },
> > +	{ true, "RDPES8", dpp_rx_err },
> > +	{ true, "RDPES9", dpp_rx_err },
> > +	{ true, "RDPES10", dpp_rx_err },
> > +	{ true, "RDPES11", dpp_rx_err },
> > +	{ true, "RDPES12", dpp_rx_err },
> > +	{ true, "RDPES13", dpp_rx_err },
> > +	{ true, "RDPES14", dpp_rx_err },
> > +	{ true, "RDPES15", dpp_rx_err },
> > +};
> > +
> >  static void dwxgmac3_handle_dma_err(struct net_device *ndev,
> >  				    void __iomem *ioaddr, bool correctable,
> >  				    struct stmmac_safety_stats *stats)
> > @@ -841,6 +878,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev,
> >  
> >  	dwxgmac3_log_error(ndev, value, correctable, "DMA",
> >  			   dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats);
> > +
> > +	value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS);
> > +	writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS);
> > +
> > +	dwxgmac3_log_error(ndev, value, false, "DMA_DPP",
> > +			   dwxgmac3_dma_dpp_errors,
> > +			   STAT_OFF(dma_dpp_errors), stats);
> >  }
> >  
> >  static int
> > @@ -881,6 +925,12 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
> >  	value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */
> >  	writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL);
> >  
> > +	/* 5. Enable Data Path Parity Protection */
> > +	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
> > +	/* already enabled by default, explicit enable it again */
> > +	value &= ~XGMAC_DDPP_DISABLE;
> > +	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
> > +
> >  	return 0;
> >  }
> >  
> > @@ -914,7 +964,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev,
> >  		ret |= !corr;
> >  	}
> >  
> > -	err = dma & (XGMAC_DEUIS | XGMAC_DECIS);
> > +	/* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in
> > +	 * DMA_Safety_Interrupt_Status, so we handle DMA Data Path
> > +	 * Parity Errors here
> > +	 */
> > +	err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS);
> >  	corr = dma & XGMAC_DECIS;
> >  	if (err) {
> >  		dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats);
> > @@ -930,6 +984,7 @@ static const struct dwxgmac3_error {
> >  	{ dwxgmac3_mac_errors },
> >  	{ dwxgmac3_mtl_errors },
> >  	{ dwxgmac3_dma_errors },
> > +	{ dwxgmac3_dma_dpp_errors },
> >  };
> >  
> >  static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats,
> > -- 
> > 2.34.1
> >   



From 0x1207 at gmail.com  Fri Feb  2 21:14:39 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Sat,  3 Feb 2024 13:14:39 +0800
Subject: [PATCH net v4] net: stmmac: xgmac: fix handling of DPP safety error for DMA channels
Message-ID: <20240203051439.1127090-1-0x1207@gmail.com>

Commit 56e58d6c8a56 ("net: stmmac: Implement Safety Features in
XGMAC core") checks and reports safety errors, but leaves the
Data Path Parity Errors for each channel in DMA unhandled at all, lead to
a storm of interrupt.
Fix it by checking and clearing the DMA_DPP_Interrupt_Status register.

Fixes: 56e58d6c8a56 ("net: stmmac: Implement Safety Features in XGMAC core")
Signed-off-by: Furong Xu <0x1207 at gmail.com>
Reviewed-by: Simon Horman <horms at kernel.org>
Reviewed-by: Serge Semin <fancer.lancer at gmail.com>
---
Changes in v4:
 - fix a typo name of DDPP bit, thanks Serge Semin

Changes in v3:
 - code style fix, thanks Paolo Abeni

Changes in v2:
  - explicit enable Data Path Parity Protection
  - add new counters to stmmac_safety_stats
  - add detailed log
---
 drivers/net/ethernet/stmicro/stmmac/common.h  |  1 +
 .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  3 +
 .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 57 ++++++++++++++++++-
 3 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 721c1f8e892f..b4f60ab078d6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -216,6 +216,7 @@ struct stmmac_safety_stats {
 	unsigned long mac_errors[32];
 	unsigned long mtl_errors[32];
 	unsigned long dma_errors[32];
+	unsigned long dma_dpp_errors[32];
 };
 
 /* Number of fields in Safety Stats */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 207ff1799f2c..5c67a3f89f08 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -303,6 +303,8 @@
 #define XGMAC_RXCEIE			BIT(4)
 #define XGMAC_TXCEIE			BIT(0)
 #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
+#define XGMAC_MTL_DPP_CONTROL		0x000010e0
+#define XGMAC_DPP_DISABLE		BIT(0)
 #define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
 #define XGMAC_TQS			GENMASK(25, 16)
 #define XGMAC_TQS_SHIFT			16
@@ -385,6 +387,7 @@
 #define XGMAC_DCEIE			BIT(1)
 #define XGMAC_TCEIE			BIT(0)
 #define XGMAC_DMA_ECC_INT_STATUS	0x0000306c
+#define XGMAC_DMA_DPP_INT_STATUS	0x00003074
 #define XGMAC_DMA_CH_CONTROL(x)		(0x00003100 + (0x80 * (x)))
 #define XGMAC_SPH			BIT(24)
 #define XGMAC_PBLx8			BIT(16)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index eb48211d9b0e..04d7c4dc2e35 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -830,6 +830,43 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
 	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
 };
 
+static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
+static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
+static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
+	{ true, "TDPES0", dpp_tx_err },
+	{ true, "TDPES1", dpp_tx_err },
+	{ true, "TDPES2", dpp_tx_err },
+	{ true, "TDPES3", dpp_tx_err },
+	{ true, "TDPES4", dpp_tx_err },
+	{ true, "TDPES5", dpp_tx_err },
+	{ true, "TDPES6", dpp_tx_err },
+	{ true, "TDPES7", dpp_tx_err },
+	{ true, "TDPES8", dpp_tx_err },
+	{ true, "TDPES9", dpp_tx_err },
+	{ true, "TDPES10", dpp_tx_err },
+	{ true, "TDPES11", dpp_tx_err },
+	{ true, "TDPES12", dpp_tx_err },
+	{ true, "TDPES13", dpp_tx_err },
+	{ true, "TDPES14", dpp_tx_err },
+	{ true, "TDPES15", dpp_tx_err },
+	{ true, "RDPES0", dpp_rx_err },
+	{ true, "RDPES1", dpp_rx_err },
+	{ true, "RDPES2", dpp_rx_err },
+	{ true, "RDPES3", dpp_rx_err },
+	{ true, "RDPES4", dpp_rx_err },
+	{ true, "RDPES5", dpp_rx_err },
+	{ true, "RDPES6", dpp_rx_err },
+	{ true, "RDPES7", dpp_rx_err },
+	{ true, "RDPES8", dpp_rx_err },
+	{ true, "RDPES9", dpp_rx_err },
+	{ true, "RDPES10", dpp_rx_err },
+	{ true, "RDPES11", dpp_rx_err },
+	{ true, "RDPES12", dpp_rx_err },
+	{ true, "RDPES13", dpp_rx_err },
+	{ true, "RDPES14", dpp_rx_err },
+	{ true, "RDPES15", dpp_rx_err },
+};
+
 static void dwxgmac3_handle_dma_err(struct net_device *ndev,
 				    void __iomem *ioaddr, bool correctable,
 				    struct stmmac_safety_stats *stats)
@@ -841,6 +878,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev,
 
 	dwxgmac3_log_error(ndev, value, correctable, "DMA",
 			   dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats);
+
+	value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS);
+	writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS);
+
+	dwxgmac3_log_error(ndev, value, false, "DMA_DPP",
+			   dwxgmac3_dma_dpp_errors,
+			   STAT_OFF(dma_dpp_errors), stats);
 }
 
 static int
@@ -881,6 +925,12 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
 	value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */
 	writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL);
 
+	/* 5. Enable Data Path Parity Protection */
+	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
+	/* already enabled by default, explicit enable it again */
+	value &= ~XGMAC_DPP_DISABLE;
+	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
+
 	return 0;
 }
 
@@ -914,7 +964,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev,
 		ret |= !corr;
 	}
 
-	err = dma & (XGMAC_DEUIS | XGMAC_DECIS);
+	/* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in
+	 * DMA_Safety_Interrupt_Status, so we handle DMA Data Path
+	 * Parity Errors here
+	 */
+	err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS);
 	corr = dma & XGMAC_DECIS;
 	if (err) {
 		dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats);
@@ -930,6 +984,7 @@ static const struct dwxgmac3_error {
 	{ dwxgmac3_mac_errors },
 	{ dwxgmac3_mtl_errors },
 	{ dwxgmac3_dma_errors },
+	{ dwxgmac3_dma_dpp_errors },
 };
 
 static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats,
-- 
2.34.1



From 0x1207 at gmail.com  Fri Feb  2 21:31:33 2024
From: 0x1207 at gmail.com (Furong Xu)
Date: Sat,  3 Feb 2024 13:31:33 +0800
Subject: [PATCH net] net: stmmac: xgmac: fix a typo of register name in DPP safety handling
Message-ID: <20240203053133.1129236-1-0x1207@gmail.com>

DDPP is copied from Synopsys Data book:

DDPP: Disable Data path Parity Protection.
    When it is 0x0, Data path Parity Protection is enabled.
    When it is 0x1, Data path Parity Protection is disabled.

The macro name should be XGMAC_DPP_DISABLE.

Fixes: 46eba193d04f ("net: stmmac: xgmac: fix handling of DPP safety error for DMA channels")
Signed-off-by: Furong Xu <0x1207 at gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h      | 2 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 5c67a3f89f08..6a2c7d22df1e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -304,7 +304,7 @@
 #define XGMAC_TXCEIE			BIT(0)
 #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
 #define XGMAC_MTL_DPP_CONTROL		0x000010e0
-#define XGMAC_DDPP_DISABLE		BIT(0)
+#define XGMAC_DPP_DISABLE		BIT(0)
 #define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
 #define XGMAC_TQS			GENMASK(25, 16)
 #define XGMAC_TQS_SHIFT			16
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index 04d7c4dc2e35..323c57f03c93 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -928,7 +928,7 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
 	/* 5. Enable Data Path Parity Protection */
 	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
 	/* already enabled by default, explicit enable it again */
-	value &= ~XGMAC_DDPP_DISABLE;
+	value &= ~XGMAC_DPP_DISABLE;
 	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
 
 	return 0;
-- 
2.34.1



From mshavit at google.com  Sat Feb  3 00:02:29 2024
From: mshavit at google.com (Michael Shavit)
Date: Sat, 3 Feb 2024 17:02:29 +0900
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
In-Reply-To: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
Message-ID: <CAKHBV24xmJqH0NFv3M2pDwbY3fRK1tJxP2=50VHXsPma-PLNHA@mail.gmail.com>

On Fri, Feb 2, 2024 at 11:28?PM Jason Gunthorpe <jgg at nvidia.com> wrote:
>
> If the SMMU is configured to use a two level CD table then
> arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
> GFP_KERNEL. Due to recent changes this is being done under a spinlock to
> iterate over the device list - thus it will trigger a sleeping while
> atomic warning:
>
>   arm_smmu_sva_set_dev_pasid()
>     mutex_lock(&sva_lock);
>     __arm_smmu_sva_bind()
>      arm_smmu_mmu_notifier_get()
>       spin_lock_irqsave()
>       arm_smmu_write_ctx_desc()
>         arm_smmu_get_cd_ptr()
>          arm_smmu_alloc_cd_leaf_table()
>           dmam_alloc_coherent(GFP_KERNEL)
>
> This is a 64K high order allocation and really should not be done
> atomically.
>
> The proper answer is to sequence CD programming in a way that does not
> require the device list or a spinlock. Part two of my lager series does
> this and already solves this bug.
>
> In the mean time we can solve the functional issue by preallocating the CD
> entry outside any locking. CD leafs are effectively never freed so this
> guarantees the arm_smmu_write_ctx_desc() inside the lock will not take the
> allocation path.
>
> Fixes: 24503148c545 ("iommu/arm-smmu-v3: Refactor write_ctx_desc")
> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> Closes: https://lore.kernel.org/all/4e25d161-0cf8-4050-9aa3-dfa21cd63e56 at moroto.mountain/
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 5 +++++
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c     | 2 +-
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h     | 2 ++
>  3 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> index 05722121f00e70..068d60732e6481 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> @@ -588,6 +588,11 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
>  {
>         int ret = 0;
>         struct mm_struct *mm = domain->mm;
> +       struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> +
> +       /* Preallocate the required leafs outside locks */
> +       if (!arm_smmu_get_cd_ptr(master, id))
> +               return -ENOMEM;
>
>         mutex_lock(&sva_lock);
>         ret = __arm_smmu_sva_bind(dev, mm);
> 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 0ffb1cf17e0b2e..ec2bb8685bb50e 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1019,7 +1019,7 @@ static void arm_smmu_write_cd_l1_desc(__le64 *dst,
>         WRITE_ONCE(*dst, cpu_to_le64(val));
>  }
>
> -static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
> +__le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
>  {
>         __le64 *l1ptr;
>         unsigned int idx;
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index 65fb388d51734d..fa0eeb3519ef28 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -748,6 +748,8 @@ extern struct xarray arm_smmu_asid_xa;
>  extern struct mutex arm_smmu_asid_lock;
>  extern struct arm_smmu_ctx_desc quiet_cd;
>
> +__le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid);
> +
>  int arm_smmu_write_ctx_desc(struct arm_smmu_master *smmu_master, int ssid,
>                             struct arm_smmu_ctx_desc *cd);
>  void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid);
>
> base-commit: c76c50cd425e574df5a071cd7e1805d0764aabff
> --
> 2.43.0
>

Reviewed-by: Michael Shavit <mshavit at google.com>


From ardb at kernel.org  Sat Feb  3 01:50:44 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sat, 3 Feb 2024 10:50:44 +0100
Subject: [PATCH] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <20240202225104.f4dsagfwf6gcnddy@google.com>
References: <20240201223545.728028-1-maskray@google.com> <Zb0Qu5lR0iZUqImb@e133380.arm.com>
 <CAMj1kXGSQ4Xq68Cmq6BH37FPJ+R+N5cOfrdC+aVML4sGaNDopg@mail.gmail.com>
 <Zb0eRogn3rjkeDAs@e133380.arm.com> <20240202225104.f4dsagfwf6gcnddy@google.com>
Message-ID: <CAMj1kXGN-nKSzxJoyM9peBTDevuPkH-+P2UzH746P-F913Dg-g@mail.gmail.com>

On Fri, 2 Feb 2024 at 23:51, Fangrui Song <maskray at google.com> wrote:
>
> On 2024-02-02, Dave Martin wrote:
> >On Fri, Feb 02, 2024 at 05:32:33PM +0100, Ard Biesheuvel wrote:
> >> On Fri, 2 Feb 2024 at 16:56, Dave Martin <Dave.Martin at arm.com> wrote:
> >> >
> >> > On Thu, Feb 01, 2024 at 02:35:45PM -0800, Fangrui Song wrote:
> >> > > The generic constraint "i" seems to be copied from x86 or arm (and with
> >> > > a redundant generic operand modifier "c"). It works with -fno-PIE but
> >> > > not with -fPIE/-fPIC in GCC's aarch64 port.
> >> > >
> >> > > The machine constraint "S", which denotes a symbol or label reference
> >> > > with a constant offset, supports PIC and has been available in GCC since
> >> > > 2012 and in Clang since 7.0. However, Clang before 19 does not support
> >> > > "S" on a symbol with a constant offset [1] (e.g.
> >> > > `static_key_false(&nf_hooks_needed[pf][hook])` in
> >> > > include/linux/netfilter.h), so we use "i" as a fallback.
> >> > >
> >> > > Suggested-by: Ard Biesheuvel <ardb at kernel.org>
> >> > > Signed-off-by: Fangrui Song <maskray at google.com>
> >> > > Link: https://github.com/llvm/llvm-project/pull/80255 [1]
> >> > >
> >> > > ---
> >> > > Changes from
> >> > > arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
> >> > >
> >> > > * Use "Si" as Ard suggested to support Clang<19
> >> > > * Make branch a separate operand
> >> > > ---
> >> > >  arch/arm64/include/asm/jump_label.h | 12 ++++++++----
> >> > >  1 file changed, 8 insertions(+), 4 deletions(-)
> >> > >
> >> > > diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> >> > > index 48ddc0f45d22..1f7d529be608 100644
> >> > > --- a/arch/arm64/include/asm/jump_label.h
> >> > > +++ b/arch/arm64/include/asm/jump_label.h
> >> > > @@ -15,6 +15,10 @@
> >> > >
> >> > >  #define JUMP_LABEL_NOP_SIZE          AARCH64_INSN_SIZE
> >> > >
> >> > > +/*
> >> > > + * Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
> >> > > + * support "S" on a symbol with a constant offset, so we use "i" as a fallback.
> >> > > + */
> >> > >  static __always_inline bool arch_static_branch(struct static_key * const key,
> >> > >                                              const bool branch)
> >> > >  {
> >> > > @@ -23,9 +27,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
> >> > >                "      .pushsection    __jump_table, \"aw\"    \n\t"
> >> > >                "      .align          3                       \n\t"
> >> > >                "      .long           1b - ., %l[l_yes] - .   \n\t"
> >> > > -              "      .quad           %c0 - .                 \n\t"
> >> > > +              "      .quad           %0 + %1 - .             \n\t"
> >> > >                "      .popsection                             \n\t"
> >> > > -              :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> >> > > +              :  :  "Si"(key), "i"(branch) :  : l_yes);
> >> >
> >> > Is the meaning of multi-alternatives well defined if different arguments
> >> > specify different numbers of alternatives?  The GCC documentation says:
> >> >
> >> > https://gcc.gnu.org/onlinedocs/gcc/Multi-Alternative.html:
> >> >
> >> > -8<-
> >> >
> >> > [...] All operands for a single instruction must have the same number of
> >> > alternatives.
> >> >
> >> > ->8-
> >> >
> >>
> >> AIUI that does not apply here. That reasons about multiple arguments
> >> having more than one constraint, where not all combinations of those
> >> constraints are supported by the instruction.
> >
> >Ah, scratch that: I'm confusing multi-alternatives with simple
> >constraints: all arguments must have the same number of comma-separated
> >lists of constraint letters, but each list can contain as many or as few
> >letters as are needed to match the operand.
> >
> >So "Si"(), "i"() is fine.
>
> "Si" is fine for GCC and Clang.
> "i" is fine for Clang but not for GCC PIC.
>
>      https://maskray.me/blog/2024-01-30-raw-symbol-names-in-inline-assembly#aarch64
>
>      In gcc/config/aarch64, LEGITIMATE_PIC_OPERAND_P(X) disallows any symbol
>      reference, which means that "i" and "s" cannot be used for PIC. Instead,
>      the constraint "S" has been supported since the initial port (2012) to
>      reference a symbol or label.
>
> I am also not familiar with
> https://gcc.gnu.org/onlinedocs/gcc/Multi-Alternative.html (comma in a
> constraint string). Thankfully we don't need this powerful construct:)
>
> >> > Also, I still think it may be redundant to move the addition inside the
> >> > asm, so long as Clang is happy with the symbol having an offset.
> >> >
> >>
> >> Older Clang is not happy with the symbol having an offset.
> >>
> >> And given that the key pointer and the 'branch' boolean are two
> >> distinct inputs to this function, I struggle to understand why you
> >> feel it is better to combine them in the argument. 'branch' is used to
> >> decide whether or not to set bit 0, independently of the value of key.
> >> Using array indexing to combine those values together to avoid an
> >> addition in the asm obfuscates the code.
> >
> >This was more about not making changes that don't need to be made,
> >unless it clearly makes the code better.
> >
> >But if some verions of Clang accept "S" but choke if there's an offset,
> >then moving the addition into the asm seems the way to go.
> >
> >(I may have misread the commit message on this point.)
> >
> >[...]
> >
> >Cheers
> >---Dave
>
> I am convinced by Ard' argument that two inputs (key, branch) deserve
> two operands.
> The existing "i"(&((char *)key)[branch]) is kinda ugly and also longer:)

If it helps clarify things, we might do something like

".quad  (%[key]  - .) + %[bit0]"

: : [key]"Si"(key), [bit0]"i"(branch) :  : l_yes);


From lkp at intel.com  Sat Feb  3 03:59:18 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 3 Feb 2024 19:59:18 +0800
Subject: [PATCH net-next 2/3] net: stmmac: Allow drivers to provide a
 default AXI configuration
In-Reply-To: <20240201-stmmac-axi-config-v1-2-822e97b2d26e@nvidia.com>
References: <20240201-stmmac-axi-config-v1-2-822e97b2d26e@nvidia.com>
Message-ID: <202402031948.IySiUm4u-lkp@intel.com>

Hi Thierry,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 51b70ff55ed88edd19b080a524063446bcc34b62]

url:    https://github.com/intel-lab-lkp/linux/commits/Thierry-Reding/net-stmmac-Pass-resources-to-DT-parsing-code/20240202-025357
base:   51b70ff55ed88edd19b080a524063446bcc34b62
patch link:    https://lore.kernel.org/r/20240201-stmmac-axi-config-v1-2-822e97b2d26e%40nvidia.com
patch subject: [PATCH net-next 2/3] net: stmmac: Allow drivers to provide a default AXI configuration
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20240203/202402031948.IySiUm4u-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240203/202402031948.IySiUm4u-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402031948.IySiUm4u-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c:96: warning: Function parameter or struct member 'res' not described in 'stmmac_axi_setup'


vim +96 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c

3b57de958e2aa3 Vince Bridgers     2014-07-31   86  
afea03656add70 Giuseppe Cavallaro 2016-02-29   87  /**
afea03656add70 Giuseppe Cavallaro 2016-02-29   88   * stmmac_axi_setup - parse DT parameters for programming the AXI register
afea03656add70 Giuseppe Cavallaro 2016-02-29   89   * @pdev: platform device
afea03656add70 Giuseppe Cavallaro 2016-02-29   90   * Description:
afea03656add70 Giuseppe Cavallaro 2016-02-29   91   * if required, from device-tree the AXI internal register can be tuned
afea03656add70 Giuseppe Cavallaro 2016-02-29   92   * by using platform parameters.
afea03656add70 Giuseppe Cavallaro 2016-02-29   93   */
af49f82367c1e3 Thierry Reding     2024-02-01   94  static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev,
af49f82367c1e3 Thierry Reding     2024-02-01   95  					   struct stmmac_resources *res)
afea03656add70 Giuseppe Cavallaro 2016-02-29  @96  {
afea03656add70 Giuseppe Cavallaro 2016-02-29   97  	struct device_node *np;
afea03656add70 Giuseppe Cavallaro 2016-02-29   98  	struct stmmac_axi *axi;
afea03656add70 Giuseppe Cavallaro 2016-02-29   99  
afea03656add70 Giuseppe Cavallaro 2016-02-29  100  	np = of_parse_phandle(pdev->dev.of_node, "snps,axi-config", 0);
af49f82367c1e3 Thierry Reding     2024-02-01  101  	if (!np && !res->axi)
afea03656add70 Giuseppe Cavallaro 2016-02-29  102  		return NULL;
afea03656add70 Giuseppe Cavallaro 2016-02-29  103  
64f48e593a54a8 Joao Pinto         2017-03-07  104  	axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
4613b279bee795 Peter Chen         2016-08-01  105  	if (!axi) {
af49f82367c1e3 Thierry Reding     2024-02-01  106  		if (np)
4613b279bee795 Peter Chen         2016-08-01  107  			of_node_put(np);
af49f82367c1e3 Thierry Reding     2024-02-01  108  
afea03656add70 Giuseppe Cavallaro 2016-02-29  109  		return ERR_PTR(-ENOMEM);
4613b279bee795 Peter Chen         2016-08-01  110  	}
afea03656add70 Giuseppe Cavallaro 2016-02-29  111  
af49f82367c1e3 Thierry Reding     2024-02-01  112  	if (res->axi)
af49f82367c1e3 Thierry Reding     2024-02-01  113  		*axi = *res->axi;
af49f82367c1e3 Thierry Reding     2024-02-01  114  
af49f82367c1e3 Thierry Reding     2024-02-01  115  	if (np) {
afea03656add70 Giuseppe Cavallaro 2016-02-29  116  		axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
afea03656add70 Giuseppe Cavallaro 2016-02-29  117  		axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
61d4f140943c47 Jisheng Zhang      2022-12-03  118  		axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
61d4f140943c47 Jisheng Zhang      2022-12-03  119  		axi->axi_fb = of_property_read_bool(np, "snps,fb");
61d4f140943c47 Jisheng Zhang      2022-12-03  120  		axi->axi_mb = of_property_read_bool(np, "snps,mb");
61d4f140943c47 Jisheng Zhang      2022-12-03  121  		axi->axi_rb =  of_property_read_bool(np, "snps,rb");
afea03656add70 Giuseppe Cavallaro 2016-02-29  122  
af49f82367c1e3 Thierry Reding     2024-02-01  123  		if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt)) {
af49f82367c1e3 Thierry Reding     2024-02-01  124  			if (!res->axi)
6b3374cb1c0bd4 Niklas Cassel      2016-12-05  125  				axi->axi_wr_osr_lmt = 1;
af49f82367c1e3 Thierry Reding     2024-02-01  126  		}
af49f82367c1e3 Thierry Reding     2024-02-01  127  
af49f82367c1e3 Thierry Reding     2024-02-01  128  		if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt)) {
af49f82367c1e3 Thierry Reding     2024-02-01  129  			if (!res->axi)
6b3374cb1c0bd4 Niklas Cassel      2016-12-05  130  				axi->axi_rd_osr_lmt = 1;
af49f82367c1e3 Thierry Reding     2024-02-01  131  		}
af49f82367c1e3 Thierry Reding     2024-02-01  132  
afea03656add70 Giuseppe Cavallaro 2016-02-29  133  		of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
af49f82367c1e3 Thierry Reding     2024-02-01  134  
4613b279bee795 Peter Chen         2016-08-01  135  		of_node_put(np);
af49f82367c1e3 Thierry Reding     2024-02-01  136  	}
afea03656add70 Giuseppe Cavallaro 2016-02-29  137  
afea03656add70 Giuseppe Cavallaro 2016-02-29  138  	return axi;
afea03656add70 Giuseppe Cavallaro 2016-02-29  139  }
afea03656add70 Giuseppe Cavallaro 2016-02-29  140  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From broonie at kernel.org  Sat Feb  3 04:16:49 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:16:49 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE ptrace
 regset
Message-ID: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>

Doug Anderson observed that ChromeOS crashes are being reported which
include failing allocations of order 7 during core dumps due to ptrace
allocating storage for regsets:

  chrome: page allocation failure: order:7,
          mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
          nodemask=(null),cpuset=urgent,mems_allowed=0
   ...
  regset_get_alloc+0x1c/0x28
  elf_core_dump+0x3d8/0xd8c
  do_coredump+0xeb8/0x1378

with further investigation showing that this is:

   [   66.957385] DOUG: Allocating 279584 bytes

which is the maximum size of the SVE regset. As Doug observes it is not
entirely surprising that such a large allocation of contiguous memory might
fail on a long running system.

The SVE regset is currently sized to hold SVE registers with a VQ of
SVE_VQ_MAX which is 512, substantially more than the architectural maximum
of 16 which we might see even in a system emulating the limits of the
architecture. Since we don't expose the size we tell the regset core
externally let's define ARCH_SVE_VQ_MAX with the actual architectural
maximum and use that for the regset, we'll still overallocate most of the
time but much less so which will be helpful even if the core is fixed to
not require contiguous allocations.

We could also teach the ptrace core about runtime discoverable regset sizes
but that would be a more invasive change and this is being observed in
practical systems.

Reported-by: Doug Anderson <dianders at chromium.org>
Signed-off-by: Mark Brown <broonie at kernel.org>
---
We should probably also use the actual architectural limit for the
bitmasks we use in the VL enumeration code, though that's both a little
bit more involved and less immediately a problem.
---
 arch/arm64/include/asm/fpsimd.h | 10 +++++-----
 arch/arm64/kernel/ptrace.c      |  3 ++-
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 50e5f25d3024..cf5f31181bc8 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -62,12 +62,12 @@ static inline void cpacr_restore(unsigned long cpacr)
  * When we defined the maximum SVE vector length we defined the ABI so
  * that the maximum vector length included all the reserved for future
  * expansion bits in ZCR rather than those just currently defined by
- * the architecture. While SME follows a similar pattern the fact that
- * it includes a square matrix means that any allocations that attempt
- * to cover the maximum potential vector length (such as happen with
- * the regset used for ptrace) end up being extremely large. Define
- * the much lower actual limit for use in such situations.
+ * the architecture.  Using this length to allocate worst size buffers
+ * results in excessively large allocations, and this effect is even
+ * more pronounced for SME due to ZA.  Define more suitable VLs for
+ * these situations.
  */
+#define ARCH_SVE_VQ_MAX 16
 #define SME_VQ_MAX	16
 
 struct task_struct;
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index dc6cf0e37194..e3bef38fc2e2 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1500,7 +1500,8 @@ static const struct user_regset aarch64_regsets[] = {
 #ifdef CONFIG_ARM64_SVE
 	[REGSET_SVE] = { /* Scalable Vector Extension */
 		.core_note_type = NT_ARM_SVE,
-		.n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE),
+		.n = DIV_ROUND_UP(SVE_PT_SIZE(ARCH_SVE_VQ_MAX,
+					      SVE_PT_REGS_SVE),
 				  SVE_VQ_BYTES),
 		.size = SVE_VQ_BYTES,
 		.align = SVE_VQ_BYTES,

---
base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
change-id: 20240202-arm64-sve-ptrace-regset-size-21b0928969e1

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From broonie at kernel.org  Sat Feb  3 04:25:26 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:26 +0000
Subject: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in userspace
Message-ID: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>

The arm64 Guarded Control Stack (GCS) feature provides support for
hardware protected stacks of return addresses, intended to provide
hardening against return oriented programming (ROP) attacks and to make
it easier to gather call stacks for applications such as profiling.

When GCS is active a secondary stack called the Guarded Control Stack is
maintained, protected with a memory attribute which means that it can
only be written with specific GCS operations.  The current GCS pointer
can not be directly written to by userspace.  When a BL is executed the
value stored in LR is also pushed onto the GCS, and when a RET is
executed the top of the GCS is popped and compared to LR with a fault
being raised if the values do not match.  GCS operations may only be
performed on GCS pages, a data abort is generated if they are not.

The combination of hardware enforcement and lack of extra instructions
in the function entry and exit paths should result in something which
has less overhead and is more difficult to attack than a purely software
implementation like clang's shadow stacks.

This series implements support for use of GCS by userspace, along with
support for use of GCS within KVM guests.  It does not enable use of GCS
by either EL1 or EL2, this will be implemented separately.  Executables
are started without GCS and must use a prctl() to enable it, it is
expected that this will be done very early in application execution by
the dynamic linker or other startup code.  For dynamic linking this will
be done by checking that everything in the executable is marked as GCS
compatible.

x86 has an equivalent feature called shadow stacks, this series depends
on the x86 patches for generic memory management support for the new
guarded/shadow stack page type and shares APIs as much as possible.  As
there has been extensive discussion with the wider community around the
ABI for shadow stacks I have as far as practical kept implementation
decisions close to those for x86, anticipating that review would lead to
similar conclusions in the absence of strong reasoning for divergence.

The main divergence I am concious of is that x86 allows shadow stack to
be enabled and disabled repeatedly, freeing the shadow stack for the
thread whenever disabled, while this implementation keeps the GCS
allocated after disable but refuses to reenable it.  This is to avoid
races with things actively walking the GCS during a disable, we do
anticipate that some systems will wish to disable GCS at runtime but are
not aware of any demand for subsequently reenabling it.

x86 uses an arch_prctl() to manage enable and disable, since only x86
and S/390 use arch_prctl() a generic prctl() was proposed[1] as part of a
patch set for the equivalent RISC-V Zicfiss feature which I initially
adopted fairly directly but following review feedback has been revised
quite a bit.

We currently maintain the x86 pattern of implicitly allocating a shadow
stack for threads started with shadow stack enabled, there has been some
discussion of removing this support and requiring the use of clone3()
with explicit allocation of shadow stacks instead.  I have no strong
feelings either way, implicit allocation is not really consistent with
anything else we do and creates the potential for errors around thread
exit but on the other hand it is existing ABI on x86 and minimises the
changes needed in userspace code.

There is an open issue with support for CRIU, on x86 this required the
ability to set the GCS mode via ptrace.  This series supports
configuring mode bits other than enable/disable via ptrace but it needs
to be confirmed if this is sufficient.

The series depends on support for shadow stacks in clone3(), that series
includes the addition of ARCH_HAS_USER_SHADOW_STACK.

   https://lore.kernel.org/r/20231120-clone3-shadow-stack-v3-0-a7b8ed3e2acc at kernel.org

It also depends on the addition of more waitpid() flags to nolibc:

   https://lore.kernel.org/r/20231023-nolibc-waitpid-flags-v2-1-b09d096f091f at kernel.org

You can see a branch with the full set of dependencies against Linus'
tree at:

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc.git arm64-gcs

[1] https://lore.kernel.org/lkml/20230213045351.3945824-1-debug at rivosinc.com/

Signed-off-by: Mark Brown <broonie at kernel.org>
---
Changes in v8:
- Invalidate signal cap token on stack when consuming.
- Typo and other trivial fixes.
- Don't try to use process_vm_write() on GCS, it intentionally does not
  work.
- Fix leak of thread GCSs.
- Rebase onto latest clone3() series.
- Link to v7: https://lore.kernel.org/r/20231122-arm64-gcs-v7-0-201c483bd775 at kernel.org

Changes in v7:
- Rebase onto v6.7-rc2 via the clone3() patch series.
- Change the token used to cap the stack during signal handling to be
  compatible with GCSPOPM.
- Fix flags for new page types.
- Fold in support for clone3().
- Replace copy_to_user_gcs() with put_user_gcs().
- Link to v6: https://lore.kernel.org/r/20231009-arm64-gcs-v6-0-78e55deaa4dd at kernel.org

Changes in v6:
- Rebase onto v6.6-rc3.
- Add some more gcsb_dsync() barriers following spec clarifications.
- Due to ongoing discussion around clone()/clone3() I've not updated
  anything there, the behaviour is the same as on previous versions.
- Link to v5: https://lore.kernel.org/r/20230822-arm64-gcs-v5-0-9ef181dd6324 at kernel.org

Changes in v5:
- Don't map any permissions for user GCSs, we always use EL0 accessors
  or use a separate mapping of the page.
- Reduce the standard size of the GCS to RLIMIT_STACK/2.
- Enforce a PAGE_SIZE alignment requirement on map_shadow_stack().
- Clarifications and fixes to documentation.
- More tests.
- Link to v4: https://lore.kernel.org/r/20230807-arm64-gcs-v4-0-68cfa37f9069 at kernel.org

Changes in v4:
- Implement flags for map_shadow_stack() allowing the cap and end of
  stack marker to be enabled independently or not at all.
- Relax size and alignment requirements for map_shadow_stack().
- Add more blurb explaining the advantages of hardware enforcement.
- Link to v3: https://lore.kernel.org/r/20230731-arm64-gcs-v3-0-cddf9f980d98 at kernel.org

Changes in v3:
- Rebase onto v6.5-rc4.
- Add a GCS barrier on context switch.
- Add a GCS stress test.
- Link to v2: https://lore.kernel.org/r/20230724-arm64-gcs-v2-0-dc2c1d44c2eb at kernel.org

Changes in v2:
- Rebase onto v6.5-rc3.
- Rework prctl() interface to allow each bit to be locked independently.
- map_shadow_stack() now places the cap token based on the size
  requested by the caller not the actual space allocated.
- Mode changes other than enable via ptrace are now supported.
- Expand test coverage.
- Various smaller fixes and adjustments.
- Link to v1: https://lore.kernel.org/r/20230716-arm64-gcs-v1-0-bf567f93bba6 at kernel.org

---
Mark Brown (38):
      arm64/mm: Restructure arch_validate_flags() for extensibility
      prctl: arch-agnostic prctl for shadow stack
      mman: Add map_shadow_stack() flags
      arm64: Document boot requirements for Guarded Control Stacks
      arm64/gcs: Document the ABI for Guarded Control Stacks
      arm64/sysreg: Add definitions for architected GCS caps
      arm64/gcs: Add manual encodings of GCS instructions
      arm64/gcs: Provide put_user_gcs()
      arm64/cpufeature: Runtime detection of Guarded Control Stack (GCS)
      arm64/mm: Allocate PIE slots for EL0 guarded control stack
      mm: Define VM_SHADOW_STACK for arm64 when we support GCS
      arm64/mm: Map pages for guarded control stack
      KVM: arm64: Manage GCS registers for guests
      arm64/gcs: Allow GCS usage at EL0 and EL1
      arm64/idreg: Add overrride for GCS
      arm64/hwcap: Add hwcap for GCS
      arm64/traps: Handle GCS exceptions
      arm64/mm: Handle GCS data aborts
      arm64/gcs: Context switch GCS state for EL0
      arm64/gcs: Ensure that new threads have a GCS
      arm64/gcs: Implement shadow stack prctl() interface
      arm64/mm: Implement map_shadow_stack()
      arm64/signal: Set up and restore the GCS context for signal handlers
      arm64/signal: Expose GCS state in signal frames
      arm64/ptrace: Expose GCS via ptrace and core files
      arm64: Add Kconfig for Guarded Control Stack (GCS)
      kselftest/arm64: Verify the GCS hwcap
      kselftest/arm64: Add GCS as a detected feature in the signal tests
      kselftest/arm64: Add framework support for GCS to signal handling tests
      kselftest/arm64: Allow signals tests to specify an expected si_code
      kselftest/arm64: Always run signals tests with GCS enabled
      kselftest/arm64: Add very basic GCS test program
      kselftest/arm64: Add a GCS test program built with the system libc
      kselftest/arm64: Add test coverage for GCS mode locking
      selftests/arm64: Add GCS signal tests
      kselftest/arm64: Add a GCS stress test
      kselftest/arm64: Enable GCS for the FP stress tests
      kselftest: Provide shadow stack enable helpers for arm64

 Documentation/admin-guide/kernel-parameters.txt    |   6 +
 Documentation/arch/arm64/booting.rst               |  22 +
 Documentation/arch/arm64/elf_hwcaps.rst            |   3 +
 Documentation/arch/arm64/gcs.rst                   | 233 +++++++
 Documentation/arch/arm64/index.rst                 |   1 +
 Documentation/filesystems/proc.rst                 |   2 +-
 arch/arm64/Kconfig                                 |  20 +
 arch/arm64/include/asm/cpufeature.h                |   6 +
 arch/arm64/include/asm/el2_setup.h                 |  17 +
 arch/arm64/include/asm/esr.h                       |  28 +-
 arch/arm64/include/asm/exception.h                 |   2 +
 arch/arm64/include/asm/gcs.h                       | 107 +++
 arch/arm64/include/asm/hwcap.h                     |   1 +
 arch/arm64/include/asm/kvm_arm.h                   |   4 +-
 arch/arm64/include/asm/kvm_host.h                  |  12 +
 arch/arm64/include/asm/mman.h                      |  23 +-
 arch/arm64/include/asm/pgtable-prot.h              |  14 +-
 arch/arm64/include/asm/processor.h                 |   7 +
 arch/arm64/include/asm/sysreg.h                    |  20 +
 arch/arm64/include/asm/uaccess.h                   |  40 ++
 arch/arm64/include/uapi/asm/hwcap.h                |   1 +
 arch/arm64/include/uapi/asm/ptrace.h               |   8 +
 arch/arm64/include/uapi/asm/sigcontext.h           |   9 +
 arch/arm64/kernel/cpufeature.c                     |  19 +
 arch/arm64/kernel/cpuinfo.c                        |   1 +
 arch/arm64/kernel/entry-common.c                   |  23 +
 arch/arm64/kernel/idreg-override.c                 |   2 +
 arch/arm64/kernel/process.c                        |  85 +++
 arch/arm64/kernel/ptrace.c                         |  59 ++
 arch/arm64/kernel/signal.c                         | 242 ++++++-
 arch/arm64/kernel/traps.c                          |  11 +
 arch/arm64/kvm/emulate-nested.c                    |   4 +
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h         |  17 +
 arch/arm64/kvm/sys_regs.c                          |  22 +
 arch/arm64/mm/Makefile                             |   1 +
 arch/arm64/mm/fault.c                              |  79 ++-
 arch/arm64/mm/gcs.c                                | 300 +++++++++
 arch/arm64/mm/mmap.c                               |  13 +-
 arch/arm64/tools/cpucaps                           |   1 +
 arch/x86/include/uapi/asm/mman.h                   |   3 -
 fs/proc/task_mmu.c                                 |   3 +
 include/linux/mm.h                                 |  16 +-
 include/uapi/asm-generic/mman.h                    |   4 +
 include/uapi/linux/elf.h                           |   1 +
 include/uapi/linux/prctl.h                         |  22 +
 kernel/sys.c                                       |  30 +
 tools/testing/selftests/arm64/Makefile             |   2 +-
 tools/testing/selftests/arm64/abi/hwcap.c          |  19 +
 tools/testing/selftests/arm64/fp/assembler.h       |  15 +
 tools/testing/selftests/arm64/fp/fpsimd-test.S     |   2 +
 tools/testing/selftests/arm64/fp/sve-test.S        |   2 +
 tools/testing/selftests/arm64/fp/za-test.S         |   2 +
 tools/testing/selftests/arm64/fp/zt-test.S         |   2 +
 tools/testing/selftests/arm64/gcs/.gitignore       |   5 +
 tools/testing/selftests/arm64/gcs/Makefile         |  24 +
 tools/testing/selftests/arm64/gcs/asm-offsets.h    |   0
 tools/testing/selftests/arm64/gcs/basic-gcs.c      | 428 ++++++++++++
 tools/testing/selftests/arm64/gcs/gcs-locking.c    | 200 ++++++
 .../selftests/arm64/gcs/gcs-stress-thread.S        | 311 +++++++++
 tools/testing/selftests/arm64/gcs/gcs-stress.c     | 532 +++++++++++++++
 tools/testing/selftests/arm64/gcs/gcs-util.h       | 100 +++
 tools/testing/selftests/arm64/gcs/libc-gcs.c       | 736 +++++++++++++++++++++
 tools/testing/selftests/arm64/signal/.gitignore    |   1 +
 .../testing/selftests/arm64/signal/test_signals.c  |  17 +-
 .../testing/selftests/arm64/signal/test_signals.h  |   6 +
 .../selftests/arm64/signal/test_signals_utils.c    |  32 +-
 .../selftests/arm64/signal/test_signals_utils.h    |  39 ++
 .../arm64/signal/testcases/gcs_exception_fault.c   |  62 ++
 .../selftests/arm64/signal/testcases/gcs_frame.c   |  88 +++
 .../arm64/signal/testcases/gcs_write_fault.c       |  67 ++
 .../selftests/arm64/signal/testcases/testcases.c   |   7 +
 .../selftests/arm64/signal/testcases/testcases.h   |   1 +
 tools/testing/selftests/ksft_shstk.h               |  37 ++
 73 files changed, 4241 insertions(+), 40 deletions(-)
---
base-commit: 50abefbf1bc07f5c4e403fd28f71dcee855100f7
change-id: 20230303-arm64-gcs-e311ab0d8729

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From broonie at kernel.org  Sat Feb  3 04:25:27 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:27 +0000
Subject: [PATCH v8 01/38] arm64/mm: Restructure arch_validate_flags() for
 extensibility
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-1-c9fec77673ef@kernel.org>

Currently arch_validate_flags() is written in a very non-extensible
fashion, returning immediately if MTE is not supported and writing the MTE
check as a direct return. Since we will want to add more checks for GCS
refactor the existing code to be more extensible, no functional change
intended.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/mman.h | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h
index 5966ee4a6154..c21849ffdd88 100644
--- a/arch/arm64/include/asm/mman.h
+++ b/arch/arm64/include/asm/mman.h
@@ -52,11 +52,17 @@ static inline bool arch_validate_prot(unsigned long prot,
 
 static inline bool arch_validate_flags(unsigned long vm_flags)
 {
-	if (!system_supports_mte())
-		return true;
+	if (system_supports_mte()) {
+		/*
+		 * only allow VM_MTE if VM_MTE_ALLOWED has been set
+		 * previously
+		 */
+		if ((vm_flags & VM_MTE) && !(vm_flags & VM_MTE_ALLOWED))
+			return false;
+	}
+
+	return true;
 
-	/* only allow VM_MTE if VM_MTE_ALLOWED has been set previously */
-	return !(vm_flags & VM_MTE) || (vm_flags & VM_MTE_ALLOWED);
 }
 #define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags)
 

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:28 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:28 +0000
Subject: [PATCH v8 02/38] prctl: arch-agnostic prctl for shadow stack
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-2-c9fec77673ef@kernel.org>

Three architectures (x86, aarch64, riscv) have announced support for
shadow stacks with fairly similar functionality.  While x86 is using
arch_prctl() to control the functionality neither arm64 nor riscv uses
that interface so this patch adds arch-agnostic prctl() support to
get and set status of shadow stacks and lock the current configuation to
prevent further changes, with support for turning on and off individual
subfeatures so applications can limit their exposure to features that
they do not need.  The features are:

  - PR_SHADOW_STACK_ENABLE: Tracking and enforcement of shadow stacks,
    including allocation of a shadow stack if one is not already
    allocated.
  - PR_SHADOW_STACK_WRITE: Writes to specific addresses in the shadow
    stack.
  - PR_SHADOW_STACK_PUSH: Push additional values onto the shadow stack.

These features are expected to be inherited by new threads and cleared
on exec(), unknown features should be rejected for enable but accepted
for locking (in order to allow for future proofing).

This is based on a patch originally written by Deepak Gupta but modified
fairly heavily, support for indirect landing pads is removed, additional
modes added and the locking interface reworked.  The set status prctl()
is also reworked to just set flags, if setting/reading the shadow stack
pointer is required this could be a separate prctl.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 include/linux/mm.h         |  4 ++++
 include/uapi/linux/prctl.h | 22 ++++++++++++++++++++++
 kernel/sys.c               | 30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index c0a782eda803..0b1139c5df60 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -4182,4 +4182,8 @@ static inline bool pfn_is_unaccepted_memory(unsigned long pfn)
 	return range_contains_unaccepted_memory(paddr, paddr + PAGE_SIZE);
 }
 
+int arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *status);
+int arch_set_shadow_stack_status(struct task_struct *t, unsigned long status);
+int arch_lock_shadow_stack_status(struct task_struct *t, unsigned long status);
+
 #endif /* _LINUX_MM_H */
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index 370ed14b1ae0..3c66ed8f46d8 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -306,4 +306,26 @@ struct prctl_mm_map {
 # define PR_RISCV_V_VSTATE_CTRL_NEXT_MASK	0xc
 # define PR_RISCV_V_VSTATE_CTRL_MASK		0x1f
 
+/*
+ * Get the current shadow stack configuration for the current thread,
+ * this will be the value configured via PR_SET_SHADOW_STACK_STATUS.
+ */
+#define PR_GET_SHADOW_STACK_STATUS      71
+
+/*
+ * Set the current shadow stack configuration.  Enabling the shadow
+ * stack will cause a shadow stack to be allocated for the thread.
+ */
+#define PR_SET_SHADOW_STACK_STATUS      72
+# define PR_SHADOW_STACK_ENABLE         (1UL << 0)
+# define PR_SHADOW_STACK_WRITE		(1UL << 1)
+# define PR_SHADOW_STACK_PUSH		(1UL << 2)
+
+/*
+ * Prevent further changes to the specified shadow stack
+ * configuration.  All bits may be locked via this call, including
+ * undefined bits.
+ */
+#define PR_LOCK_SHADOW_STACK_STATUS      73
+
 #endif /* _LINUX_PRCTL_H */
diff --git a/kernel/sys.c b/kernel/sys.c
index e219fcfa112d..96e8a6b5993a 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2301,6 +2301,21 @@ int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which,
 	return -EINVAL;
 }
 
+int __weak arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *status)
+{
+	return -EINVAL;
+}
+
+int __weak arch_set_shadow_stack_status(struct task_struct *t, unsigned long status)
+{
+	return -EINVAL;
+}
+
+int __weak arch_lock_shadow_stack_status(struct task_struct *t, unsigned long status)
+{
+	return -EINVAL;
+}
+
 #define PR_IO_FLUSHER (PF_MEMALLOC_NOIO | PF_LOCAL_THROTTLE)
 
 #ifdef CONFIG_ANON_VMA_NAME
@@ -2743,6 +2758,21 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 	case PR_RISCV_V_GET_CONTROL:
 		error = RISCV_V_GET_CONTROL();
 		break;
+	case PR_GET_SHADOW_STACK_STATUS:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_get_shadow_stack_status(me, (unsigned long __user *) arg2);
+		break;
+	case PR_SET_SHADOW_STACK_STATUS:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_set_shadow_stack_status(me, arg2);
+		break;
+	case PR_LOCK_SHADOW_STACK_STATUS:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_lock_shadow_stack_status(me, arg2);
+		break;
 	default:
 		error = -EINVAL;
 		break;

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:29 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:29 +0000
Subject: [PATCH v8 03/38] mman: Add map_shadow_stack() flags
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-3-c9fec77673ef@kernel.org>

In preparation for adding arm64 GCS support make the map_shadow_stack()
SHADOW_STACK_SET_TOKEN flag generic and add _SET_MARKER. The existing
flag indicats that a token usable for stack switch should be added to
the top of the newly mapped GCS region while the new flag indicates that
a top of stack marker suitable for use by unwinders should be added
above that.

For arm64 the top of stack marker is all bits 0.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/x86/include/uapi/asm/mman.h | 3 ---
 include/uapi/asm-generic/mman.h  | 4 ++++
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/uapi/asm/mman.h b/arch/x86/include/uapi/asm/mman.h
index 46cdc941f958..ac1e6277212b 100644
--- a/arch/x86/include/uapi/asm/mman.h
+++ b/arch/x86/include/uapi/asm/mman.h
@@ -5,9 +5,6 @@
 #define MAP_32BIT	0x40		/* only give out 32bit addresses */
 #define MAP_ABOVE4G	0x80		/* only map above 4GB */
 
-/* Flags for map_shadow_stack(2) */
-#define SHADOW_STACK_SET_TOKEN	(1ULL << 0)	/* Set up a restore token in the shadow stack */
-
 #include <asm-generic/mman.h>
 
 #endif /* _ASM_X86_MMAN_H */
diff --git a/include/uapi/asm-generic/mman.h b/include/uapi/asm-generic/mman.h
index 57e8195d0b53..d6a282687af5 100644
--- a/include/uapi/asm-generic/mman.h
+++ b/include/uapi/asm-generic/mman.h
@@ -19,4 +19,8 @@
 #define MCL_FUTURE	2		/* lock all future mappings */
 #define MCL_ONFAULT	4		/* lock all pages that are faulted in */
 
+#define SHADOW_STACK_SET_TOKEN (1ULL << 0)     /* Set up a restore token in the shadow stack */
+#define SHADOW_STACK_SET_MARKER (1ULL << 1)     /* Set up a top of stack merker in the shadow stack */
+
+
 #endif /* __ASM_GENERIC_MMAN_H */

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:30 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:30 +0000
Subject: [PATCH v8 04/38] arm64: Document boot requirements for Guarded
 Control Stacks
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-4-c9fec77673ef@kernel.org>

FEAT_GCS introduces a number of new system registers, we require that
access to these registers is not trapped when we identify that the feature
is detected.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arch/arm64/booting.rst | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
index b57776a68f15..de3679770c64 100644
--- a/Documentation/arch/arm64/booting.rst
+++ b/Documentation/arch/arm64/booting.rst
@@ -411,6 +411,28 @@ Before jumping into the kernel, the following conditions must be met:
 
     - HFGRWR_EL2.nPIRE0_EL1 (bit 57) must be initialised to 0b1.
 
+ - For features with Guarded Control Stacks (FEAT_GCS):
+
+  - If EL3 is present:
+
+    - SCR_EL3.GCSEn (bit 39) must be initialised to 0b1.
+
+ - If the kernel is entered at EL1 and EL2 is present:
+
+    - HFGITR_EL2.nGCSEPP (bit 59) must be initialised to 0b1.
+
+    - HFGITR_EL2.nGCSSTR_EL1 (bit 58) must be initialised to 0b1.
+
+    - HFGITR_EL2.nGCSPUSHM_EL1 (bit 57) must be initialised to 0b1.
+
+    - HFGRTR_EL2.nGCS_EL1 (bit 53) must be initialised to 0b1.
+
+    - HFGRTR_EL2.nGCS_EL0 (bit 52) must be initialised to 0b1.
+
+    - HFGWTR_EL2.nGCS_EL1 (bit 53) must be initialised to 0b1.
+
+    - HFGWTR_EL2.nGCS_EL0 (bit 52) must be initialised to 0b1.
+
 The requirements described above for CPU mode, caches, MMUs, architected
 timers, coherency and system registers apply to all CPUs.  All CPUs must
 enter the kernel in the same exception level.  Where the values documented

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:31 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:31 +0000
Subject: [PATCH v8 05/38] arm64/gcs: Document the ABI for Guarded Control
 Stacks
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-5-c9fec77673ef@kernel.org>

Add some documentation of the userspace ABI for Guarded Control Stacks.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arch/arm64/gcs.rst   | 233 +++++++++++++++++++++++++++++++++++++
 Documentation/arch/arm64/index.rst |   1 +
 2 files changed, 234 insertions(+)

diff --git a/Documentation/arch/arm64/gcs.rst b/Documentation/arch/arm64/gcs.rst
new file mode 100644
index 000000000000..c45c0326836a
--- /dev/null
+++ b/Documentation/arch/arm64/gcs.rst
@@ -0,0 +1,233 @@
+===============================================
+Guarded Control Stack support for AArch64 Linux
+===============================================
+
+This document outlines briefly the interface provided to userspace by Linux in
+order to support use of the ARM Guarded Control Stack (GCS) feature.
+
+This is an outline of the most important features and issues only and not
+intended to be exhaustive.
+
+
+
+1.  General
+-----------
+
+* GCS is an architecture feature intended to provide greater protection
+  against return oriented programming (ROP) attacks and to simplify the
+  implementation of features that need to collect stack traces such as
+  profiling.
+
+* When GCS is enabled a separate guarded control stack is maintained by the
+  PE which is writeable only through specific GCS operations.  This
+  stores the call stack only, when a procedure call instruction is
+  performed the current PC is pushed onto the GCS and on RET the
+  address in the LR is verified against that on the top of the GCS.
+
+* When active current GCS pointer is stored in the system register
+  GCSPR_EL0.  This is readable by userspace but can only be updated
+  via specific GCS instructions.
+
+* The architecture provides instructions for switching between guarded
+  control stacks with checks to ensure that the new stack is a valid
+  target for switching.
+
+* The functionality of GCS is similar to that provided by the x86 Shadow
+  Stack feature, due to sharing of userspace interfaces the ABI refers to
+  shadow stacks rather than GCS.
+
+* Support for GCS is reported to userspace via HWCAP2_GCS in the aux vector
+  AT_HWCAP2 entry.
+
+* GCS is enabled per thread.  While there is support for disabling GCS
+  at runtime this should be done with great care.
+
+* GCS memory access faults are reported as normal memory access faults.
+
+* GCS specific errors (those reported with EC 0x2d) will be reported as
+  SIGSEGV with a si_code of SEGV_CPERR (control protection error).
+
+* GCS is supported only for AArch64.
+
+* On systems where GCS is supported GCSPR_EL0 is always readable by EL0
+  regardless of the GCS configuration for the thread.
+
+* The architecture supports enabling GCS without verifying that return values
+  in LR match those in the GCS, the LR will be ignored.  This is not supported
+  by Linux.
+
+* EL0 GCS entries with bit 63 set are reserved for use, one such use is defined
+  below for signals and should be ignored when parsing the stack if not
+  understood.
+
+
+2.  Enabling and disabling Guarded Control Stacks
+-------------------------------------------------
+
+* GCS is enabled and disabled for a thread via the PR_SET_SHADOW_STACK_STATUS
+  prctl(), this takes a single flags argument specifying which GCS features
+  should be used.
+
+* When set PR_SHADOW_STACK_ENABLE flag allocates a Guarded Control Stack
+  and enables GCS for the thread, enabling the functionality controlled by
+  GCSCRE0_EL1.{nTR, RVCHKEN, PCRSEL}.
+
+* When set the PR_SHADOW_STACK_PUSH flag enables the functionality controlled
+  by GCSCRE0_EL1.PUSHMEn, allowing explicit GCS pushes.
+
+* When set the PR_SHADOW_STACK_WRITE flag enables the functionality controlled
+  by GCSCRE0_EL1.STREn, allowing explicit stores to the Guarded Control Stack.
+
+* Any unknown flags will cause PR_SET_SHADOW_STACK_STATUS to return -EINVAL.
+
+* PR_LOCK_SHADOW_STACK_STATUS is passed a bitmask of features with the same
+  values as used for PR_SET_SHADOW_STACK_STATUS.  Any future changes to the
+  status of the specified GCS mode bits will be rejected.
+
+* PR_LOCK_SHADOW_STACK_STATUS allows any bit to be locked, this allows
+  userspace to prevent changes to any future features.
+
+* There is no support for a process to remove a lock that has been set for
+  it.
+
+* PR_SET_SHADOW_STACK_STATUS and PR_LOCK_SHADOW_STACK_STATUS affect only the
+  thread that called them, any other running threads will be unaffected.
+
+* New threads inherit the GCS configuration of the thread that created them.
+
+* GCS is disabled on exec().
+
+* The current GCS configuration for a thread may be read with the
+  PR_GET_SHADOW_STACK_STATUS prctl(), this returns the same flags that
+  are passed to PR_SET_SHADOW_STACK_STATUS.
+
+* If GCS is disabled for a thread after having previously been enabled then
+  the stack will remain allocated for the lifetime of the thread.  At present
+  any attempt to reenable GCS for the thread will be rejected, this may be
+  revisited in future.
+
+* It should be noted that since enabling GCS will result in GCS becoming
+  active immediately it is not normally possible to return from the function
+  that invoked the prctl() that enabled GCS.  It is expected that the normal
+  usage will be that GCS is enabled very early in execution of a program.
+
+
+
+3.  Allocation of Guarded Control Stacks
+----------------------------------------
+
+* When GCS is enabled for a thread a new Guarded Control Stack will be
+  allocated for it of size RLIMIT_STACK or 4 gigabytes, whichever is
+  smaller.
+
+* When a new thread is created by a thread which has GCS enabled then a
+  new Guarded Control Stack will be allocated for the new thread with
+  half the size of the standard stack.
+
+* When a stack is allocated by enabling GCS or during thread creation then
+  the top 8 bytes of the stack will be initialised to 0 and GCSPR_EL0 will
+  be set to point to the address of this 0 value, this can be used to
+  detect the top of the stack.
+
+* Additional Guarded Control Stacks can be allocated using the
+  map_shadow_stack() system call.
+
+* Stacks allocated using map_shadow_stack() can optionally have an end of
+  stack marker and cap placed at the top of the stack.  If the flag
+  SHADOW_STACK_SET_TOKEN is specified a cap will be placed on the stack,
+  if SHADOW_STACK_SET_MARKER is not specified the cap will be the top 8
+  bytes of the stack and if it is specified then the cap will be the next
+  8 bytes.  While specifying just SHADOW_STACK_SET_MARKER by itself is
+  valid since the marker is all bits 0 it has no observable effect.
+
+* Stacks allocated using map_shadow_stack() must have a size which is a
+  multiple of 8 bytes larger than 8 bytes and must be 8 bytes aligned.
+
+* An address can be specified to map_shadow_stack(), if one is provided then
+  it must be aligned to a page boundary.
+
+* When a thread is freed the Guarded Control Stack initially allocated for
+  that thread will be freed.  Note carefully that if the stack has been
+  switched this may not be the stack currently in use by the thread.
+
+
+4.  Signal handling
+--------------------
+
+* A new signal frame record gcs_context encodes the current GCS mode and
+  pointer for the interrupted context on signal delivery.  This will always
+  be present on systems that support GCS.
+
+* The record contains a flag field which reports the current GCS configuration
+  for the interrupted context as PR_GET_SHADOW_STACK_STATUS would.
+
+* The signal handler is run with the same GCS configuration as the interrupted
+  context.
+
+* When GCS is enabled for the interrupted thread a signal handling specific
+  GCS cap token will be written to the GCS, this is an architectural GCS cap
+  token with bit 63 set and the token type (bits 0..11) all clear.  The
+  GCSPR_EL0 reported in the signal frame will point to this cap token.
+
+* The signal handler will use the same GCS as the interrupted context.
+
+* When GCS is enabled on signal entry a frame with the address of the signal
+  return handler will be pushed onto the GCS, allowing return from the signal
+  handler via RET as normal.  This will not be reported in the gcs_context in
+  the signal frame.
+
+
+5.  Signal return
+-----------------
+
+When returning from a signal handler:
+
+* If there is a gcs_context record in the signal frame then the GCS flags
+  and GCSPR_EL0 will be restored from that context prior to further
+  validation.
+
+* If there is no gcs_context record in the signal frame then the GCS
+  configuration will be unchanged.
+
+* If GCS is enabled on return from a signal handler then GCSPR_EL0 must
+  point to a valid GCS signal cap record, this will be popped from the
+  GCS prior to signal return.
+
+* If the GCS configuration is locked when returning from a signal then any
+  attempt to change the GCS configuration will be treated as an error.  This
+  is true even if GCS was not enabled prior to signal entry.
+
+* GCS may be disabled via signal return but any attempt to enable GCS via
+  signal return will be rejected.
+
+
+6.  ptrace extensions
+---------------------
+
+* A new regset NT_ARM_GCS is defined for use with PTRACE_GETREGSET and
+  PTRACE_SETREGSET.
+
+* Due to the complexity surrounding allocation and deallocation of stacks and
+  lack of practical application it is not possible to enable GCS via ptrace.
+  GCS may be disabled via the ptrace interface.
+
+* Other GCS modes may be configured via ptrace.
+
+* Configuration via ptrace ignores locking of GCS mode bits.
+
+
+7.  ELF coredump extensions
+---------------------------
+
+* NT_ARM_GCS 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.
+
+
+
+8.  /proc extensions
+--------------------
+
+* Guarded Control Stack pages will include "ss" in their VmFlags in
+  /proc/<pid>/smaps.
diff --git a/Documentation/arch/arm64/index.rst b/Documentation/arch/arm64/index.rst
index d08e924204bf..dcf3ee3eb8c0 100644
--- a/Documentation/arch/arm64/index.rst
+++ b/Documentation/arch/arm64/index.rst
@@ -14,6 +14,7 @@ ARM64 Architecture
     booting
     cpu-feature-registers
     elf_hwcaps
+    gcs
     hugetlbpage
     kdump
     legacy_instructions

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:32 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:32 +0000
Subject: [PATCH v8 06/38] arm64/sysreg: Add definitions for architected GCS
 caps
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-6-c9fec77673ef@kernel.org>

The architecture defines a format for guarded control stack caps, used
to mark the top of an unused GCS in order to limit the potential for
exploitation via stack switching. Add definitions associated with these.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/sysreg.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index c3b19b376c86..6ed813e856c1 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1064,6 +1064,26 @@
 #define POE_RXW		UL(0x7)
 #define POE_MASK	UL(0xf)
 
+/*
+ * Definitions for Guarded Control Stack
+ */
+
+#define GCS_CAP_ADDR_MASK		GENMASK(63, 12)
+#define GCS_CAP_ADDR_SHIFT		12
+#define GCS_CAP_ADDR_WIDTH		52
+#define GCS_CAP_ADDR(x)			FIELD_GET(GCS_CAP_ADDR_MASK, x)
+
+#define GCS_CAP_TOKEN_MASK		GENMASK(11, 0)
+#define GCS_CAP_TOKEN_SHIFT		0
+#define GCS_CAP_TOKEN_WIDTH		12
+#define GCS_CAP_TOKEN(x)		FIELD_GET(GCS_CAP_TOKEN_MASK, x)
+
+#define GCS_CAP_VALID_TOKEN		0x1
+#define GCS_CAP_IN_PROGRESS_TOKEN	0x5
+
+#define GCS_CAP(x)	((((unsigned long)x) & GCS_CAP_ADDR_MASK) | \
+					       GCS_CAP_VALID_TOKEN)
+
 #define ARM64_FEATURE_FIELD_BITS	4
 
 /* Defined for compatibility only, do not add new users. */

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:33 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:33 +0000
Subject: [PATCH v8 07/38] arm64/gcs: Add manual encodings of GCS
 instructions
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-7-c9fec77673ef@kernel.org>

Define C callable functions for GCS instructions used by the kernel. In
order to avoid ambitious toolchain requirements for GCS support these are
manually encoded, this means we have fixed register numbers which will be
a bit limiting for the compiler but none of these should be used in
sufficiently fast paths for this to be a problem.

Note that GCSSTTR is used to store to EL0.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/gcs.h     | 51 ++++++++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/uaccess.h | 22 +++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h
new file mode 100644
index 000000000000..7c5e95218db6
--- /dev/null
+++ b/arch/arm64/include/asm/gcs.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+#ifndef __ASM_GCS_H
+#define __ASM_GCS_H
+
+#include <asm/types.h>
+#include <asm/uaccess.h>
+
+static inline void gcsb_dsync(void)
+{
+	asm volatile(".inst 0xd503227f" : : : "memory");
+}
+
+static inline void gcsstr(u64 *addr, u64 val)
+{
+	register u64 *_addr __asm__ ("x0") = addr;
+	register long _val __asm__ ("x1") = val;
+
+	/* GCSSTTR x1, x0 */
+	asm volatile(
+		".inst 0xd91f1c01\n"
+		:
+		: "rZ" (_val), "r" (_addr)
+		: "memory");
+}
+
+static inline void gcsss1(u64 Xt)
+{
+	asm volatile (
+		"sys #3, C7, C7, #2, %0\n"
+		:
+		: "rZ" (Xt)
+		: "memory");
+}
+
+static inline u64 gcsss2(void)
+{
+	u64 Xt;
+
+	asm volatile(
+		"SYSL %0, #3, C7, C7, #3\n"
+		: "=r" (Xt)
+		:
+		: "memory");
+
+	return Xt;
+}
+
+#endif
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 14be5000c5a0..22e10e79f56a 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -425,4 +425,26 @@ static inline size_t probe_subpage_writeable(const char __user *uaddr,
 
 #endif /* CONFIG_ARCH_HAS_SUBPAGE_FAULTS */
 
+#ifdef CONFIG_ARM64_GCS
+
+static inline int gcssttr(unsigned long __user *addr, unsigned long val)
+{
+	register unsigned long __user *_addr __asm__ ("x0") = addr;
+	register unsigned long _val __asm__ ("x1") = val;
+	int err = 0;
+
+	/* GCSSTTR x1, x0 */
+	asm volatile(
+		"1: .inst 0xd91f1c01\n"
+		"2: \n"
+		_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %w0)
+		: "+r" (err)
+		: "rZ" (_val), "r" (_addr)
+		: "memory");
+
+	return err;
+}
+
+#endif /* CONFIG_ARM64_GCS */
+
 #endif /* __ASM_UACCESS_H */

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:34 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:34 +0000
Subject: [PATCH v8 08/38] arm64/gcs: Provide put_user_gcs()
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-8-c9fec77673ef@kernel.org>

In order for EL1 to write to an EL0 GCS it must use the GCSSTTR instruction
rather than a normal STTR. Provide a put_user_gcs() which does this.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/uaccess.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 22e10e79f56a..e118c3d772c8 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -445,6 +445,24 @@ static inline int gcssttr(unsigned long __user *addr, unsigned long val)
 	return err;
 }
 
+static inline void put_user_gcs(unsigned long val, unsigned long __user *addr,
+				int *err)
+{
+	int ret;
+
+	if (!access_ok((char __user *)addr, sizeof(u64))) {
+		*err = -EFAULT;
+		return;
+	}
+
+	uaccess_ttbr0_enable();
+	ret = gcssttr(addr, val);
+	if (ret != 0)
+		*err = ret;
+	uaccess_ttbr0_disable();
+}
+
+
 #endif /* CONFIG_ARM64_GCS */
 
 #endif /* __ASM_UACCESS_H */

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:35 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:35 +0000
Subject: [PATCH v8 09/38] arm64/cpufeature: Runtime detection of Guarded
 Control Stack (GCS)
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-9-c9fec77673ef@kernel.org>

Add a cpufeature for GCS, allowing other code to conditionally support it
at runtime.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/cpufeature.h |  6 ++++++
 arch/arm64/kernel/cpufeature.c      | 16 ++++++++++++++++
 arch/arm64/tools/cpucaps            |  1 +
 3 files changed, 23 insertions(+)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 21c824edf8ce..3f3a685fa6e2 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -825,6 +825,12 @@ static inline bool system_supports_lpa2(void)
 	return cpus_have_final_cap(ARM64_HAS_LPA2);
 }
 
+static inline bool system_supports_gcs(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_GCS) &&
+		alternative_has_cap_unlikely(ARM64_HAS_GCS);
+}
+
 int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
 bool try_emulate_mrs(struct pt_regs *regs, u32 isn);
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 8d1a634a403e..b606842ab8c1 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -255,6 +255,8 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_GCS),
+		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_EL1_GCS_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
 		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_EL1_SME_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_EL1_MPAM_frac_SHIFT, 4, 0),
@@ -2250,6 +2252,12 @@ static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused)
 	sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_MSCEn);
 }
 
+static void cpu_enable_gcs(const struct arm64_cpu_capabilities *__unused)
+{
+	/* GCS is not currently used at EL1 */
+	write_sysreg_s(0, SYS_GCSCR_EL1);
+}
+
 /* Internal helper functions to match cpu capability type */
 static bool
 cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap)
@@ -2739,6 +2747,14 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
 		.matches = has_lpa2,
 	},
+	{
+		.desc = "Guarded Control Stack (GCS)",
+		.capability = ARM64_HAS_GCS,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.cpu_enable = cpu_enable_gcs,
+		.matches = has_cpuid_feature,
+		ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, GCS, IMP)
+	},
 	{},
 };
 
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index b912b1409fc0..148734504295 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -28,6 +28,7 @@ HAS_EPAN
 HAS_EVT
 HAS_FGT
 HAS_FPSIMD
+HAS_GCS
 HAS_GENERIC_AUTH
 HAS_GENERIC_AUTH_ARCH_QARMA3
 HAS_GENERIC_AUTH_ARCH_QARMA5

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:36 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:36 +0000
Subject: [PATCH v8 10/38] arm64/mm: Allocate PIE slots for EL0 guarded
 control stack
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-10-c9fec77673ef@kernel.org>

Pages used for guarded control stacks need to be described to the hardware
using the Permission Indirection Extension, GCS is not supported without
PIE. In order to support copy on write for guarded stacks we allocate two
values, one for active GCSs and one for GCS pages marked as read only prior
to copy.

Since the actual effect is defined using PIE the specific bit pattern used
does not matter to the hardware but we choose two values which differ only
in PTE_WRITE in order to help share code with non-PIE cases.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/pgtable-prot.h | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 483dbfa39c4c..14a33e0bece3 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -129,15 +129,23 @@ extern bool arm64_use_ng_mappings;
 /* 6:                                PTE_PXN | PTE_WRITE            */
 /* 7: PAGE_SHARED_EXEC               PTE_PXN | PTE_WRITE | PTE_USER */
 /* 8: PAGE_KERNEL_ROX      PTE_UXN                                  */
-/* 9:                      PTE_UXN |                       PTE_USER */
+/* 9: PAGE_GCS_RO          PTE_UXN |                       PTE_USER */
 /* a: PAGE_KERNEL_EXEC     PTE_UXN |           PTE_WRITE            */
-/* b:                      PTE_UXN |           PTE_WRITE | PTE_USER */
+/* b: PAGE_GCS             PTE_UXN |           PTE_WRITE | PTE_USER */
 /* c: PAGE_KERNEL_RO       PTE_UXN | PTE_PXN                        */
 /* d: PAGE_READONLY        PTE_UXN | PTE_PXN |             PTE_USER */
 /* e: PAGE_KERNEL          PTE_UXN | PTE_PXN | PTE_WRITE            */
 /* f: PAGE_SHARED          PTE_UXN | PTE_PXN | PTE_WRITE | PTE_USER */
 
+#define _PAGE_GCS	(_PAGE_DEFAULT | PTE_NG | PTE_UXN | PTE_WRITE | PTE_USER)
+#define _PAGE_GCS_RO	(_PAGE_DEFAULT | PTE_NG | PTE_UXN | PTE_USER)
+
+#define PAGE_GCS	__pgprot(_PAGE_GCS)
+#define PAGE_GCS_RO	__pgprot(_PAGE_GCS_RO)
+
 #define PIE_E0	( \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_GCS),           PIE_GCS)  | \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_GCS_RO),        PIE_R)   | \
 	PIRx_ELx_PERM(pte_pi_index(_PAGE_EXECONLY),      PIE_X_O) | \
 	PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY_EXEC), PIE_RX)  | \
 	PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED_EXEC),   PIE_RWX) | \
@@ -145,6 +153,8 @@ extern bool arm64_use_ng_mappings;
 	PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED),        PIE_RW))
 
 #define PIE_E1	( \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_GCS),           PIE_NONE_O) | \
+	PIRx_ELx_PERM(pte_pi_index(_PAGE_GCS_RO),        PIE_NONE_O) | \
 	PIRx_ELx_PERM(pte_pi_index(_PAGE_EXECONLY),      PIE_NONE_O) | \
 	PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY_EXEC), PIE_R)      | \
 	PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED_EXEC),   PIE_RW)     | \

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:37 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:37 +0000
Subject: [PATCH v8 11/38] mm: Define VM_SHADOW_STACK for arm64 when we
 support GCS
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-11-c9fec77673ef@kernel.org>

Use VM_HIGH_ARCH_5 for guarded control stack pages.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/filesystems/proc.rst |  2 +-
 fs/proc/task_mmu.c                 |  3 +++
 include/linux/mm.h                 | 12 +++++++++++-
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst
index 104c6d047d9b..0392c3b74650 100644
--- a/Documentation/filesystems/proc.rst
+++ b/Documentation/filesystems/proc.rst
@@ -570,7 +570,7 @@ encoded manner. The codes are the following:
     mt    arm64 MTE allocation tags are enabled
     um    userfaultfd missing tracking
     uw    userfaultfd wr-protect tracking
-    ss    shadow stack page
+    ss    shadow/guarded control stack page
     ==    =======================================
 
 Note that there is no guarantee that every flag and associated mnemonic will
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index ff2c601f7d1c..fb0633d8e309 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -702,6 +702,9 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
 #ifdef CONFIG_ARCH_HAS_USER_SHADOW_STACK
 		[ilog2(VM_SHADOW_STACK)] = "ss",
+#endif
+#ifdef CONFIG_ARM64_GCS
+		[ilog2(VM_SHADOW_STACK)] = "ss",
 #endif
 	};
 	size_t i;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 0b1139c5df60..6cc304c90c63 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -352,7 +352,17 @@ extern unsigned int kobjsize(const void *objp);
  * for more details on the guard size.
  */
 # define VM_SHADOW_STACK	VM_HIGH_ARCH_5
-#else
+#endif
+
+#if defined(CONFIG_ARM64_GCS)
+/*
+ * arm64's Guarded Control Stack implements similar functionality and
+ * has similar constraints to shadow stacks.
+ */
+# define VM_SHADOW_STACK	VM_HIGH_ARCH_5
+#endif
+
+#ifndef VM_SHADOW_STACK
 # define VM_SHADOW_STACK	VM_NONE
 #endif
 

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:38 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:38 +0000
Subject: [PATCH v8 12/38] arm64/mm: Map pages for guarded control stack
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-12-c9fec77673ef@kernel.org>

Map pages flagged as being part of a GCS as such rather than using the
full set of generic VM flags.

This is done using a conditional rather than extending the size of
protection_map since that would make for a very sparse array.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/mman.h |  9 +++++++++
 arch/arm64/mm/mmap.c          | 13 ++++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h
index c21849ffdd88..6d3fe6433a62 100644
--- a/arch/arm64/include/asm/mman.h
+++ b/arch/arm64/include/asm/mman.h
@@ -61,6 +61,15 @@ static inline bool arch_validate_flags(unsigned long vm_flags)
 			return false;
 	}
 
+	if (system_supports_gcs() && (vm_flags & VM_SHADOW_STACK)) {
+		/*
+		 * An executable GCS isn't a good idea, and the mm
+		 * core can't cope with a shared GCS.
+		 */
+		if (vm_flags & (VM_EXEC | VM_ARM64_BTI | VM_SHARED))
+			return false;
+	}
+
 	return true;
 
 }
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 645fe60d000f..e44ce6fcfad9 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -79,9 +79,20 @@ arch_initcall(adjust_protection_map);
 
 pgprot_t vm_get_page_prot(unsigned long vm_flags)
 {
-	pteval_t prot = pgprot_val(protection_map[vm_flags &
+	pteval_t prot;
+
+	/* If this is a GCS then only interpret VM_WRITE. */
+	if (system_supports_gcs() && (vm_flags & VM_SHADOW_STACK)) {
+		if (vm_flags & VM_WRITE)
+			prot = _PAGE_GCS;
+		else
+			prot = _PAGE_GCS_RO;
+	} else {
+		prot = pgprot_val(protection_map[vm_flags &
 				   (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]);
+	}
 
+	/* VM_ARM64_BTI on a GCS is rejected in arch_validate_flags() */
 	if (vm_flags & VM_ARM64_BTI)
 		prot |= PTE_GP;
 

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:39 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:39 +0000
Subject: [PATCH v8 13/38] KVM: arm64: Manage GCS registers for guests
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-13-c9fec77673ef@kernel.org>

GCS introduces a number of system registers for EL1 and EL0, on systems
with GCS we need to context switch them and expose them to VMMs to allow
guests to use GCS, as well as describe their fine grained traps to
nested virtualisation.  Traps are already disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h          | 12 ++++++++++++
 arch/arm64/kvm/emulate-nested.c            |  4 ++++
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 17 +++++++++++++++++
 arch/arm64/kvm/sys_regs.c                  | 22 ++++++++++++++++++++++
 4 files changed, 55 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 21c57b812569..6c7ea7f9cd92 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -388,6 +388,12 @@ enum vcpu_sysreg {
 	GCR_EL1,	/* Tag Control Register */
 	TFSRE0_EL1,	/* Tag Fault Status Register (EL0) */
 
+	/* Guarded Control Stack registers */
+	GCSCRE0_EL1,	/* Guarded Control Stack Control (EL0) */
+	GCSCR_EL1,	/* Guarded Control Stack Control (EL1) */
+	GCSPR_EL0,	/* Guarded Control Stack Pointer (EL0) */
+	GCSPR_EL1,	/* Guarded Control Stack Pointer (EL1) */
+
 	/* 32bit specific registers. */
 	DACR32_EL2,	/* Domain Access Control Register */
 	IFSR32_EL2,	/* Instruction Fault Status Register */
@@ -1221,6 +1227,12 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)
 
 #define vcpu_has_feature(v, f)	__vcpu_has_feature(&(v)->kvm->arch, (f))
 
+static inline bool has_gcs(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_GCS) &&
+		cpus_have_final_cap(ARM64_HAS_GCS);
+}
+
 int kvm_trng_call(struct kvm_vcpu *vcpu);
 #ifdef CONFIG_KVM
 extern phys_addr_t hyp_mem_base;
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 431fd429932d..24eb7eccbae4 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1098,8 +1098,12 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
 	SR_FGT(SYS_ESR_EL1, 		HFGxTR, ESR_EL1, 1),
 	SR_FGT(SYS_DCZID_EL0, 		HFGxTR, DCZID_EL0, 1),
 	SR_FGT(SYS_CTR_EL0, 		HFGxTR, CTR_EL0, 1),
+	SR_FGT(SYS_GCSPR_EL0,		HFGxTR, nGCS_EL0, 1),
 	SR_FGT(SYS_CSSELR_EL1, 		HFGxTR, CSSELR_EL1, 1),
 	SR_FGT(SYS_CPACR_EL1, 		HFGxTR, CPACR_EL1, 1),
+	SR_FGT(SYS_GCSCR_EL1,		HFGxTR, nGCS_EL1, 1),
+	SR_FGT(SYS_GCSPR_EL1,		HFGxTR, nGCS_EL1, 1),
+	SR_FGT(SYS_GCSCRE0_EL1,		HFGxTR, nGCS_EL0, 1),
 	SR_FGT(SYS_CONTEXTIDR_EL1, 	HFGxTR, CONTEXTIDR_EL1, 1),
 	SR_FGT(SYS_CLIDR_EL1, 		HFGxTR, CLIDR_EL1, 1),
 	SR_FGT(SYS_CCSIDR_EL1, 		HFGxTR, CCSIDR_EL1, 1),
diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index bb6b571ec627..ec34d4a90717 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -25,6 +25,8 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt)
 {
 	ctxt_sys_reg(ctxt, TPIDR_EL0)	= read_sysreg(tpidr_el0);
 	ctxt_sys_reg(ctxt, TPIDRRO_EL0)	= read_sysreg(tpidrro_el0);
+	if (has_gcs())
+		ctxt_sys_reg(ctxt, GCSPR_EL0) = read_sysreg_s(SYS_GCSPR_EL0);
 }
 
 static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt)
@@ -62,6 +64,12 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
 	ctxt_sys_reg(ctxt, PAR_EL1)	= read_sysreg_par();
 	ctxt_sys_reg(ctxt, TPIDR_EL1)	= read_sysreg(tpidr_el1);
 
+	if (has_gcs()) {
+		ctxt_sys_reg(ctxt, GCSPR_EL1)	= read_sysreg_el1(SYS_GCSPR);
+		ctxt_sys_reg(ctxt, GCSCR_EL1)	= read_sysreg_el1(SYS_GCSCR);
+		ctxt_sys_reg(ctxt, GCSCRE0_EL1)	= read_sysreg_s(SYS_GCSCRE0_EL1);
+	}
+
 	if (ctxt_has_mte(ctxt)) {
 		ctxt_sys_reg(ctxt, TFSR_EL1) = read_sysreg_el1(SYS_TFSR);
 		ctxt_sys_reg(ctxt, TFSRE0_EL1) = read_sysreg_s(SYS_TFSRE0_EL1);
@@ -95,6 +103,8 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt)
 {
 	write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL0),	tpidr_el0);
 	write_sysreg(ctxt_sys_reg(ctxt, TPIDRRO_EL0),	tpidrro_el0);
+	if (has_gcs())
+		write_sysreg_s(ctxt_sys_reg(ctxt, GCSPR_EL0), SYS_GCSPR_EL0);
 }
 
 static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
@@ -138,6 +148,13 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
 	write_sysreg(ctxt_sys_reg(ctxt, PAR_EL1),	par_el1);
 	write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL1),	tpidr_el1);
 
+	if (has_gcs()) {
+		write_sysreg_el1(ctxt_sys_reg(ctxt, GCSPR_EL1),	SYS_GCSPR);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, GCSCR_EL1),	SYS_GCSCR);
+		write_sysreg_s(ctxt_sys_reg(ctxt, GCSCRE0_EL1),
+			       SYS_GCSCRE0_EL1);
+	}
+
 	if (ctxt_has_mte(ctxt)) {
 		write_sysreg_el1(ctxt_sys_reg(ctxt, TFSR_EL1), SYS_TFSR);
 		write_sysreg_s(ctxt_sys_reg(ctxt, TFSRE0_EL1), SYS_TFSRE0_EL1);
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 30253bd19917..83ba767e75d2 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2000,6 +2000,23 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu,
 	.visibility = mte_visibility,		\
 }
 
+static unsigned int gcs_visibility(const struct kvm_vcpu *vcpu,
+				   const struct sys_reg_desc *rd)
+{
+	if (has_gcs())
+		return 0;
+
+	return REG_HIDDEN;
+}
+
+#define GCS_REG(name) {				\
+	SYS_DESC(SYS_##name),			\
+	.access = undef_access,			\
+	.reset = reset_unknown,			\
+	.reg = name,				\
+	.visibility = gcs_visibility,		\
+}
+
 static unsigned int el2_visibility(const struct kvm_vcpu *vcpu,
 				   const struct sys_reg_desc *rd)
 {
@@ -2376,6 +2393,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	PTRAUTH_KEY(APDB),
 	PTRAUTH_KEY(APGA),
 
+	GCS_REG(GCSCR_EL1),
+	GCS_REG(GCSPR_EL1),
+	GCS_REG(GCSCRE0_EL1),
+
 	{ SYS_DESC(SYS_SPSR_EL1), access_spsr},
 	{ SYS_DESC(SYS_ELR_EL1), access_elr},
 
@@ -2462,6 +2483,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ 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 },
+	GCS_REG(GCSPR_EL0),
 	{ SYS_DESC(SYS_SVCR), undef_access },
 
 	{ PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, .reset = reset_pmcr,

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:40 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:40 +0000
Subject: [PATCH v8 14/38] arm64/gcs: Allow GCS usage at EL0 and EL1
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-14-c9fec77673ef@kernel.org>

There is a control HCRX_EL2.GCSEn which must be set to allow GCS
features to take effect at lower ELs and also fine grained traps for GCS
usage at EL0 and EL1.  Configure all these to allow GCS usage by EL0 and
EL1.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/el2_setup.h | 17 +++++++++++++++++
 arch/arm64/include/asm/kvm_arm.h   |  4 ++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index b7afaa026842..17672563e333 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -27,6 +27,14 @@
 	ubfx	x0, x0, #ID_AA64MMFR1_EL1_HCX_SHIFT, #4
 	cbz	x0, .Lskip_hcrx_\@
 	mov_q	x0, HCRX_HOST_FLAGS
+
+        /* Enable GCS if supported */
+	mrs_s	x1, SYS_ID_AA64PFR1_EL1
+	ubfx	x1, x1, #ID_AA64PFR1_EL1_GCS_SHIFT, #4
+	cbz	x1, .Lset_hcrx_\@
+	orr	x0, x0, #HCRX_EL2_GCSEn
+
+.Lset_hcrx_\@:
 	msr_s	SYS_HCRX_EL2, x0
 .Lskip_hcrx_\@:
 .endm
@@ -190,6 +198,15 @@
 	orr	x0, x0, #HFGxTR_EL2_nPIR_EL1
 	orr	x0, x0, #HFGxTR_EL2_nPIRE0_EL1
 
+	/* GCS depends on PIE so we don't check it if PIE is absent */
+	mrs_s	x1, SYS_ID_AA64PFR1_EL1
+	ubfx	x1, x1, #ID_AA64PFR1_EL1_GCS_SHIFT, #4
+	cbz	x1, .Lset_fgt_\@
+
+	/* Disable traps of access to GCS registers at EL0 and EL1 */
+	orr	x0, x0, #HFGxTR_EL2_nGCS_EL1_MASK
+	orr	x0, x0, #HFGxTR_EL2_nGCS_EL0_MASK
+
 .Lset_fgt_\@:
 	msr_s	SYS_HFGRTR_EL2, x0
 	msr_s	SYS_HFGWTR_EL2, x0
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3c6f8ba1e479..a9354c237a97 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -103,9 +103,9 @@
 #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
 
 #define HCRX_GUEST_FLAGS \
-	(HCRX_EL2_SMPME | HCRX_EL2_TCR2En | \
+	(HCRX_EL2_SMPME | HCRX_EL2_TCR2En | HCRX_EL2_GCSEn |\
 	 (cpus_have_final_cap(ARM64_HAS_MOPS) ? (HCRX_EL2_MSCEn | HCRX_EL2_MCE2) : 0))
-#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En)
+#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En | HCRX_EL2_GCSEn)
 
 /* TCR_EL2 Registers bits */
 #define TCR_EL2_DS		(1UL << 32)

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:41 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:41 +0000
Subject: [PATCH v8 15/38] arm64/idreg: Add overrride for GCS
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-15-c9fec77673ef@kernel.org>

Hook up an override for GCS, allowing it to be disabled from the command
line by specifying arm64.nogcs in case there are problems.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/admin-guide/kernel-parameters.txt | 6 ++++++
 arch/arm64/kernel/idreg-override.c              | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 31b3a25680d0..e86160251d23 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -429,9 +429,15 @@
 	arm64.nobti	[ARM64] Unconditionally disable Branch Target
 			Identification support
 
+	arm64.nogcs	[ARM64] Unconditionally disable Guarded Control Stack
+			support
+
 	arm64.nomops	[ARM64] Unconditionally disable Memory Copy and Memory
 			Set instructions support
 
+	arm64.nopauth	[ARM64] Unconditionally disable Pointer Authentication
+			support
+
 	arm64.nomte	[ARM64] Unconditionally disable Memory Tagging Extension
 			support
 
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index e30fd9e32ef3..00bcdad53ba9 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -110,6 +110,7 @@ static const struct ftr_set_desc pfr1 __prel64_initconst = {
 	.override	= &id_aa64pfr1_override,
 	.fields		= {
 		FIELD("bt", ID_AA64PFR1_EL1_BT_SHIFT, NULL ),
+		FIELD("gcs", ID_AA64PFR1_EL1_GCS_SHIFT, NULL),
 		FIELD("mte", ID_AA64PFR1_EL1_MTE_SHIFT, NULL),
 		FIELD("sme", ID_AA64PFR1_EL1_SME_SHIFT, pfr1_sme_filter),
 		{}
@@ -190,6 +191,7 @@ static const struct {
 	{ "arm64.nosve",		"id_aa64pfr0.sve=0" },
 	{ "arm64.nosme",		"id_aa64pfr1.sme=0" },
 	{ "arm64.nobti",		"id_aa64pfr1.bt=0" },
+	{ "arm64.nogcs",		"id_aa64pfr1.gcs=0" },
 	{ "arm64.nopauth",
 	  "id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 "
 	  "id_aa64isar1.api=0 id_aa64isar1.apa=0 "

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:42 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:42 +0000
Subject: [PATCH v8 16/38] arm64/hwcap: Add hwcap for GCS
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-16-c9fec77673ef@kernel.org>

Provide a hwcap to enable userspace to detect support for GCS.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arch/arm64/elf_hwcaps.rst | 3 +++
 arch/arm64/include/asm/hwcap.h          | 1 +
 arch/arm64/include/uapi/asm/hwcap.h     | 1 +
 arch/arm64/kernel/cpufeature.c          | 3 +++
 arch/arm64/kernel/cpuinfo.c             | 1 +
 5 files changed, 9 insertions(+)

diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst
index ced7b335e2e0..86d4ace9c75c 100644
--- a/Documentation/arch/arm64/elf_hwcaps.rst
+++ b/Documentation/arch/arm64/elf_hwcaps.rst
@@ -317,6 +317,9 @@ HWCAP2_LRCPC3
 HWCAP2_LSE128
     Functionality implied by ID_AA64ISAR0_EL1.Atomic == 0b0011.
 
+HWCAP2_GCS
+    Functionality implied by ID_AA64PFR1_EL1.GCS == 0b1
+
 4. Unused AT_HWCAP bits
 -----------------------
 
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index cd71e09ea14d..e01e6b72a839 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -142,6 +142,7 @@
 #define KERNEL_HWCAP_SVE_B16B16		__khwcap2_feature(SVE_B16B16)
 #define KERNEL_HWCAP_LRCPC3		__khwcap2_feature(LRCPC3)
 #define KERNEL_HWCAP_LSE128		__khwcap2_feature(LSE128)
+#define KERNEL_HWCAP_GCS		__khwcap2_feature(GCS)
 
 /*
  * 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 5023599fa278..996b5b5d4c4e 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -107,5 +107,6 @@
 #define HWCAP2_SVE_B16B16	(1UL << 45)
 #define HWCAP2_LRCPC3		(1UL << 46)
 #define HWCAP2_LSE128		(1UL << 47)
+#define HWCAP2_GCS		(1UL << 48)
 
 #endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index b606842ab8c1..1a92c4502a0b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2867,6 +2867,9 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64ZFR0_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, F32MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
 	HWCAP_CAP(ID_AA64ZFR0_EL1, F64MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
+#endif
+#ifdef CONFIG_ARM64_GCS
+	HWCAP_CAP(ID_AA64PFR1_EL1, GCS, IMP, CAP_HWCAP, KERNEL_HWCAP_GCS),
 #endif
 	HWCAP_CAP(ID_AA64PFR1_EL1, SSBS, SSBS2, CAP_HWCAP, KERNEL_HWCAP_SSBS),
 #ifdef CONFIG_ARM64_BTI
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 47043c0d95ec..b3ec0b89c9e0 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -128,6 +128,7 @@ static const char *const hwcap_str[] = {
 	[KERNEL_HWCAP_SVE_B16B16]	= "sveb16b16",
 	[KERNEL_HWCAP_LRCPC3]		= "lrcpc3",
 	[KERNEL_HWCAP_LSE128]		= "lse128",
+	[KERNEL_HWCAP_GCS]		= "gcs",
 };
 
 #ifdef CONFIG_COMPAT

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:43 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:43 +0000
Subject: [PATCH v8 17/38] arm64/traps: Handle GCS exceptions
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-17-c9fec77673ef@kernel.org>

A new exception code is defined for GCS specific faults other than
standard load/store faults, for example GCS token validation failures,
add handling for this. These faults are reported to userspace as
segfaults with code SEGV_CPERR (protection error), mirroring the
reporting for x86 shadow stack errors.

GCS faults due to memory load/store operations generate data aborts with
a flag set, these will be handled separately as part of the data abort
handling.

Since we do not currently enable GCS for EL1 we should not get any faults
there but while we're at it we wire things up there, treating any GCS
fault as fatal.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/esr.h       | 28 +++++++++++++++++++++++++++-
 arch/arm64/include/asm/exception.h |  2 ++
 arch/arm64/kernel/entry-common.c   | 23 +++++++++++++++++++++++
 arch/arm64/kernel/traps.c          | 11 +++++++++++
 4 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 353fe08546cf..20ee9f531864 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -51,7 +51,8 @@
 #define ESR_ELx_EC_FP_EXC32	(0x28)
 /* Unallocated EC: 0x29 - 0x2B */
 #define ESR_ELx_EC_FP_EXC64	(0x2C)
-/* Unallocated EC: 0x2D - 0x2E */
+#define ESR_ELx_EC_GCS		(0x2D)
+/* Unallocated EC: 0x2E */
 #define ESR_ELx_EC_SERROR	(0x2F)
 #define ESR_ELx_EC_BREAKPT_LOW	(0x30)
 #define ESR_ELx_EC_BREAKPT_CUR	(0x31)
@@ -382,6 +383,31 @@
 #define ESR_ELx_MOPS_ISS_SRCREG(esr)	(((esr) & (UL(0x1f) << 5)) >> 5)
 #define ESR_ELx_MOPS_ISS_SIZEREG(esr)	(((esr) & (UL(0x1f) << 0)) >> 0)
 
+/* ISS field definitions for GCS */
+#define ESR_ELx_ExType_SHIFT	(20)
+#define ESR_ELx_ExType_MASK		GENMASK(23, 20)
+#define ESR_ELx_Raddr_SHIFT		(10)
+#define ESR_ELx_Raddr_MASK		GENMASK(14, 10)
+#define ESR_ELx_Rn_SHIFT		(5)
+#define ESR_ELx_Rn_MASK			GENMASK(9, 5)
+#define ESR_ELx_Rvalue_SHIFT		5
+#define ESR_ELx_Rvalue_MASK		GENMASK(9, 5)
+#define ESR_ELx_IT_SHIFT		(0)
+#define ESR_ELx_IT_MASK			GENMASK(4, 0)
+
+#define ESR_ELx_ExType_DATA_CHECK	0
+#define ESR_ELx_ExType_EXLOCK		1
+#define ESR_ELx_ExType_STR		2
+
+#define ESR_ELx_IT_RET			0
+#define ESR_ELx_IT_GCSPOPM		1
+#define ESR_ELx_IT_RET_KEYA		2
+#define ESR_ELx_IT_RET_KEYB		3
+#define ESR_ELx_IT_GCSSS1		4
+#define ESR_ELx_IT_GCSSS2		5
+#define ESR_ELx_IT_GCSPOPCX		6
+#define ESR_ELx_IT_GCSPOPX		7
+
 #ifndef __ASSEMBLY__
 #include <asm/types.h>
 
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index ad688e157c9b..99caff458e20 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -57,6 +57,8 @@ void do_el0_undef(struct pt_regs *regs, unsigned long esr);
 void do_el1_undef(struct pt_regs *regs, unsigned long esr);
 void do_el0_bti(struct pt_regs *regs);
 void do_el1_bti(struct pt_regs *regs, unsigned long esr);
+void do_el0_gcs(struct pt_regs *regs, unsigned long esr);
+void do_el1_gcs(struct pt_regs *regs, unsigned long esr);
 void do_debug_exception(unsigned long addr_if_watchpoint, unsigned long esr,
 			struct pt_regs *regs);
 void do_fpsimd_acc(unsigned long esr, struct pt_regs *regs);
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 0fc94207e69a..52d78ce63a4e 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -429,6 +429,15 @@ static void noinstr el1_bti(struct pt_regs *regs, unsigned long esr)
 	exit_to_kernel_mode(regs);
 }
 
+static void noinstr el1_gcs(struct pt_regs *regs, unsigned long esr)
+{
+	enter_from_kernel_mode(regs);
+	local_daif_inherit(regs);
+	do_el1_gcs(regs, esr);
+	local_daif_mask();
+	exit_to_kernel_mode(regs);
+}
+
 static void noinstr el1_dbg(struct pt_regs *regs, unsigned long esr)
 {
 	unsigned long far = read_sysreg(far_el1);
@@ -471,6 +480,9 @@ asmlinkage void noinstr el1h_64_sync_handler(struct pt_regs *regs)
 	case ESR_ELx_EC_BTI:
 		el1_bti(regs, esr);
 		break;
+	case ESR_ELx_EC_GCS:
+		el1_gcs(regs, esr);
+		break;
 	case ESR_ELx_EC_BREAKPT_CUR:
 	case ESR_ELx_EC_SOFTSTP_CUR:
 	case ESR_ELx_EC_WATCHPT_CUR:
@@ -650,6 +662,14 @@ static void noinstr el0_mops(struct pt_regs *regs, unsigned long esr)
 	exit_to_user_mode(regs);
 }
 
+static void noinstr el0_gcs(struct pt_regs *regs, unsigned long esr)
+{
+	enter_from_user_mode(regs);
+	local_daif_restore(DAIF_PROCCTX);
+	do_el0_gcs(regs, esr);
+	exit_to_user_mode(regs);
+}
+
 static void noinstr el0_inv(struct pt_regs *regs, unsigned long esr)
 {
 	enter_from_user_mode(regs);
@@ -732,6 +752,9 @@ asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs)
 	case ESR_ELx_EC_MOPS:
 		el0_mops(regs, esr);
 		break;
+	case ESR_ELx_EC_GCS:
+		el0_gcs(regs, esr);
+		break;
 	case ESR_ELx_EC_BREAKPT_LOW:
 	case ESR_ELx_EC_SOFTSTP_LOW:
 	case ESR_ELx_EC_WATCHPT_LOW:
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 215e6d7f2df8..fb867c6526a6 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -500,6 +500,16 @@ void do_el1_bti(struct pt_regs *regs, unsigned long esr)
 	die("Oops - BTI", regs, esr);
 }
 
+void do_el0_gcs(struct pt_regs *regs, unsigned long esr)
+{
+	force_signal_inject(SIGSEGV, SEGV_CPERR, regs->pc, 0);
+}
+
+void do_el1_gcs(struct pt_regs *regs, unsigned long esr)
+{
+	die("Oops - GCS", regs, esr);
+}
+
 void do_el0_fpac(struct pt_regs *regs, unsigned long esr)
 {
 	force_signal_inject(SIGILL, ILL_ILLOPN, regs->pc, esr);
@@ -838,6 +848,7 @@ static const char *esr_class_str[] = {
 	[ESR_ELx_EC_MOPS]		= "MOPS",
 	[ESR_ELx_EC_FP_EXC32]		= "FP (AArch32)",
 	[ESR_ELx_EC_FP_EXC64]		= "FP (AArch64)",
+	[ESR_ELx_EC_GCS]		= "Guarded Control Stack",
 	[ESR_ELx_EC_SERROR]		= "SError",
 	[ESR_ELx_EC_BREAKPT_LOW]	= "Breakpoint (lower EL)",
 	[ESR_ELx_EC_BREAKPT_CUR]	= "Breakpoint (current EL)",

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:44 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:44 +0000
Subject: [PATCH v8 18/38] arm64/mm: Handle GCS data aborts
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-18-c9fec77673ef@kernel.org>

All GCS operations at EL0 must happen on a page which is marked as
having UnprivGCS access, including read operations.  If a GCS operation
attempts to access a page without this then it will generate a data
abort with the GCS bit set in ESR_EL1.ISS2.

EL0 may validly generate such faults, for example due to copy on write
which will cause the GCS data to be stored in a read only page with no
GCS permissions until the actual copy happens.  Since UnprivGCS allows
both reads and writes to the GCS (though only through GCS operations) we
need to ensure that the memory management subsystem handles GCS accesses
as writes at all times.  Do this by adding FAULT_FLAG_WRITE to any GCS
page faults, adding handling to ensure that invalid cases are identfied
as such early so the memory management core does not think they will
succeed.  The core cannot distinguish between VMAs which are generally
writeable and VMAs which are only writeable through GCS operations.

EL1 may validly write to EL0 GCS for management purposes (eg, while
initialising with cap tokens).

We also report any GCS faults in VMAs not marked as part of a GCS as
access violations, causing a fault to be delivered to userspace if it
attempts to do GCS operations outside a GCS.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/mm/fault.c | 79 +++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 71 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 55f6455a8284..5303d4e3457d 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -494,13 +494,30 @@ static void do_bad_area(unsigned long far, unsigned long esr,
 	}
 }
 
+/*
+ * Note: not valid for EL1 DC IVAC, but we never use that such that it
+ * should fault. EL0 cannot issue DC IVAC (undef).
+ */
+static bool is_write_abort(unsigned long esr)
+{
+	return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM);
+}
+
+static bool is_gcs_fault(unsigned long esr)
+{
+	if (!esr_is_data_abort(esr))
+		return false;
+
+	return ESR_ELx_ISS2(esr) & ESR_ELx_GCS;
+}
+
 #define VM_FAULT_BADMAP		((__force vm_fault_t)0x010000)
 #define VM_FAULT_BADACCESS	((__force vm_fault_t)0x020000)
 
 static vm_fault_t __do_page_fault(struct mm_struct *mm,
 				  struct vm_area_struct *vma, unsigned long addr,
 				  unsigned int mm_flags, unsigned long vm_flags,
-				  struct pt_regs *regs)
+				  unsigned long esr, struct pt_regs *regs)
 {
 	/*
 	 * Ok, we have a good vm_area for this memory access, so we can handle
@@ -510,6 +527,26 @@ static vm_fault_t __do_page_fault(struct mm_struct *mm,
 	 */
 	if (!(vma->vm_flags & vm_flags))
 		return VM_FAULT_BADACCESS;
+
+	if (vma->vm_flags & VM_SHADOW_STACK) {
+		/*
+		 * Writes to a GCS must either be generated by a GCS
+		 * operation or be from EL1.
+		 */
+		if (is_write_abort(esr) &&
+		    !(is_gcs_fault(esr) || is_el1_data_abort(esr)))
+			return VM_FAULT_BADACCESS;
+	} else {
+		/*
+		 * GCS faults should never happen for pages that are
+		 * not part of a GCS and the operation being attempted
+		 * can never succeed.
+		 */
+		if (is_gcs_fault(esr))
+			return VM_FAULT_BADACCESS;
+	}
+
+
 	return handle_mm_fault(vma, addr, mm_flags, regs);
 }
 
@@ -518,13 +555,18 @@ static bool is_el0_instruction_abort(unsigned long esr)
 	return ESR_ELx_EC(esr) == ESR_ELx_EC_IABT_LOW;
 }
 
-/*
- * Note: not valid for EL1 DC IVAC, but we never use that such that it
- * should fault. EL0 cannot issue DC IVAC (undef).
- */
-static bool is_write_abort(unsigned long esr)
+static bool is_invalid_el0_gcs_access(struct vm_area_struct *vma, u64 esr)
 {
-	return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM);
+	if (!system_supports_gcs())
+		return false;
+	if (likely(!(vma->vm_flags & VM_SHADOW_STACK))) {
+		if (is_gcs_fault(esr))
+			return true;
+		return false;
+	}
+	if (is_gcs_fault(esr))
+		return false;
+	return is_write_abort(esr);
 }
 
 static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
@@ -573,6 +615,13 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
 		/* If EPAN is absent then exec implies read */
 		if (!alternative_has_cap_unlikely(ARM64_HAS_EPAN))
 			vm_flags |= VM_EXEC;
+		/*
+		 * Upgrade read faults to write faults, GCS reads must
+		 * occur on a page marked as GCS so we need to trigger
+		 * copy on write always.
+		 */
+		if (is_gcs_fault(esr))
+			mm_flags |= FAULT_FLAG_WRITE;
 	}
 
 	if (is_ttbr0_addr(addr) && is_el1_permission_fault(addr, esr, regs)) {
@@ -594,6 +643,20 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
 	if (!vma)
 		goto lock_mmap;
 
+	/*
+	 * We get legitimate write faults for GCS pages from GCS
+	 * operations, even when the initial operation was a read, as
+	 * a result of upgrading GCS accesses to writes for CoW but
+	 * GCS acceses outside of a GCS must fail.  Specifically check
+	 * for this since the mm core isn't able to distinguish
+	 * invalid GCS access from valid ones and will try to resolve
+	 * the fault.
+	 */
+	if (is_invalid_el0_gcs_access(vma, esr)) {
+		vma_end_read(vma);
+		goto lock_mmap;
+	}
+
 	if (!(vma->vm_flags & vm_flags)) {
 		vma_end_read(vma);
 		goto lock_mmap;
@@ -625,7 +688,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
 		goto done;
 	}
 
-	fault = __do_page_fault(mm, vma, addr, mm_flags, vm_flags, regs);
+	fault = __do_page_fault(mm, vma, addr, mm_flags, vm_flags, esr, regs);
 
 	/* Quick path to respond to signals */
 	if (fault_signal_pending(fault, regs)) {

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:45 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:45 +0000
Subject: [PATCH v8 19/38] arm64/gcs: Context switch GCS state for EL0
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-19-c9fec77673ef@kernel.org>

There are two registers controlling the GCS state of EL0, GCSPR_EL0 which
is the current GCS pointer and GCSCRE0_EL1 which has enable bits for the
specific GCS functionality enabled for EL0. Manage these on context switch
and process lifetime events, GCS is reset on exec().  Also ensure that
any changes to the GCS memory are visible to other PEs and that changes
from other PEs are visible on this one by issuing a GCSB DSYNC when
moving to or from a thread with GCS.

Since the current GCS configuration of a thread will be visible to
userspace we store the configuration in the format used with userspace
and provide a helper which configures the system register as needed.

On systems that support GCS we always allow access to GCSPR_EL0, this
facilitates reporting of GCS faults if userspace implements disabling of
GCS on error - the GCS can still be discovered and examined even if GCS
has been disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/gcs.h       | 24 ++++++++++++++++
 arch/arm64/include/asm/processor.h |  6 ++++
 arch/arm64/kernel/process.c        | 56 ++++++++++++++++++++++++++++++++++++++
 arch/arm64/mm/Makefile             |  1 +
 arch/arm64/mm/gcs.c                | 39 ++++++++++++++++++++++++++
 5 files changed, 126 insertions(+)

diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h
index 7c5e95218db6..04594ef59dad 100644
--- a/arch/arm64/include/asm/gcs.h
+++ b/arch/arm64/include/asm/gcs.h
@@ -48,4 +48,28 @@ static inline u64 gcsss2(void)
 	return Xt;
 }
 
+#ifdef CONFIG_ARM64_GCS
+
+static inline bool task_gcs_el0_enabled(struct task_struct *task)
+{
+	return current->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE;
+}
+
+void gcs_set_el0_mode(struct task_struct *task);
+void gcs_free(struct task_struct *task);
+void gcs_preserve_current_state(void);
+
+#else
+
+static inline bool task_gcs_el0_enabled(struct task_struct *task)
+{
+	return false;
+}
+
+static inline void gcs_set_el0_mode(struct task_struct *task) { }
+static inline void gcs_free(struct task_struct *task) { }
+static inline void gcs_preserve_current_state(void) { }
+
+#endif
+
 #endif
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 5b0a04810b23..6fc6dcbd494c 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -182,6 +182,12 @@ struct thread_struct {
 	u64			sctlr_user;
 	u64			svcr;
 	u64			tpidr2_el0;
+#ifdef CONFIG_ARM64_GCS
+	unsigned int		gcs_el0_mode;
+	u64			gcspr_el0;
+	u64			gcs_base;
+	u64			gcs_size;
+#endif
 };
 
 static inline unsigned int thread_get_vl(struct thread_struct *thread,
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 7387b68c745b..fd80b43c2969 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -48,6 +48,7 @@
 #include <asm/cacheflush.h>
 #include <asm/exec.h>
 #include <asm/fpsimd.h>
+#include <asm/gcs.h>
 #include <asm/mmu_context.h>
 #include <asm/mte.h>
 #include <asm/processor.h>
@@ -271,12 +272,32 @@ static void flush_tagged_addr_state(void)
 		clear_thread_flag(TIF_TAGGED_ADDR);
 }
 
+#ifdef CONFIG_ARM64_GCS
+
+static void flush_gcs(void)
+{
+	if (!system_supports_gcs())
+		return;
+
+	gcs_free(current);
+	current->thread.gcs_el0_mode = 0;
+	write_sysreg_s(0, SYS_GCSCRE0_EL1);
+	write_sysreg_s(0, SYS_GCSPR_EL0);
+}
+
+#else
+
+static void flush_gcs(void) { }
+
+#endif
+
 void flush_thread(void)
 {
 	fpsimd_flush_thread();
 	tls_thread_flush();
 	flush_ptrace_hw_breakpoint(current);
 	flush_tagged_addr_state();
+	flush_gcs();
 }
 
 void arch_release_task_struct(struct task_struct *tsk)
@@ -474,6 +495,40 @@ static void entry_task_switch(struct task_struct *next)
 	__this_cpu_write(__entry_task, next);
 }
 
+#ifdef CONFIG_ARM64_GCS
+
+void gcs_preserve_current_state(void)
+{
+	if (task_gcs_el0_enabled(current))
+		current->thread.gcspr_el0 = read_sysreg_s(SYS_GCSPR_EL0);
+}
+
+static void gcs_thread_switch(struct task_struct *next)
+{
+	if (!system_supports_gcs())
+		return;
+
+	gcs_preserve_current_state();
+
+	gcs_set_el0_mode(next);
+	write_sysreg_s(next->thread.gcspr_el0, SYS_GCSPR_EL0);
+
+	/*
+	 * Ensure that GCS changes are observable by/from other PEs in
+	 * case of migration.
+	 */
+	if (task_gcs_el0_enabled(current) || task_gcs_el0_enabled(next))
+		gcsb_dsync();
+}
+
+#else
+
+static void gcs_thread_switch(struct task_struct *next)
+{
+}
+
+#endif
+
 /*
  * ARM erratum 1418040 handling, affecting the 32bit view of CNTVCT.
  * Ensure access is disabled when switching to a 32bit task, ensure
@@ -533,6 +588,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
 	ssbs_thread_switch(next);
 	erratum_1418040_thread_switch(next);
 	ptrauth_thread_switch_user(next);
+	gcs_thread_switch(next);
 
 	/*
 	 * Complete any pending TLB or cache maintenance on this CPU in case
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index dbd1bc95967d..4e7cb2f02999 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_TRANS_TABLE)	+= trans_pgd.o
 obj-$(CONFIG_TRANS_TABLE)	+= trans_pgd-asm.o
 obj-$(CONFIG_DEBUG_VIRTUAL)	+= physaddr.o
 obj-$(CONFIG_ARM64_MTE)		+= mteswap.o
+obj-$(CONFIG_ARM64_GCS)		+= gcs.o
 KASAN_SANITIZE_physaddr.o	+= n
 
 obj-$(CONFIG_KASAN)		+= kasan_init.o
diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c
new file mode 100644
index 000000000000..b0a67efc522b
--- /dev/null
+++ b/arch/arm64/mm/gcs.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/syscalls.h>
+#include <linux/types.h>
+
+#include <asm/cpufeature.h>
+#include <asm/page.h>
+
+/*
+ * Apply the GCS mode configured for the specified task to the
+ * hardware.
+ */
+void gcs_set_el0_mode(struct task_struct *task)
+{
+	u64 gcscre0_el1 = GCSCRE0_EL1_nTR;
+
+	if (task->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE)
+		gcscre0_el1 |= GCSCRE0_EL1_RVCHKEN | GCSCRE0_EL1_PCRSEL;
+
+	if (task->thread.gcs_el0_mode & PR_SHADOW_STACK_WRITE)
+		gcscre0_el1 |= GCSCRE0_EL1_STREn;
+
+	if (task->thread.gcs_el0_mode & PR_SHADOW_STACK_PUSH)
+		gcscre0_el1 |= GCSCRE0_EL1_PUSHMEn;
+
+	write_sysreg_s(gcscre0_el1, SYS_GCSCRE0_EL1);
+}
+
+void gcs_free(struct task_struct *task)
+{
+	if (task->thread.gcs_base)
+		vm_munmap(task->thread.gcs_base, task->thread.gcs_size);
+
+	task->thread.gcspr_el0 = 0;
+	task->thread.gcs_base = 0;
+	task->thread.gcs_size = 0;
+}

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:46 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:46 +0000
Subject: [PATCH v8 20/38] arm64/gcs: Ensure that new threads have a GCS
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-20-c9fec77673ef@kernel.org>

When a new thread is created by a thread with GCS enabled the GCS needs
to be specified along with the regular stack.  clone3() has been
extended to support this case, allowing userspace to explicitly specify
the size and location of the GCS.  The specified GCS must have a valid
GCS token at the top of the stack, as though userspace were pivoting to
the new GCS.  This will be consumed on use.  At present we do not
atomically consume the token, this will be addressed in a future
revision.

Unfortunately plain clone() is not extensible and existing clone3()
users will not specify a stack so all existing code would be broken if
we mandated specifying the stack explicitly.  For compatibility with
these cases and also x86 (which did not initially implement clone3()
support for shadow stacks) if no GCS is specified we will allocate one
thread so when a thread is created which has GCS enabled allocate one
for it.  We follow the extensively discussed x86 implementation and
allocate min(RLIMIT_STACK, 4G).  Since the GCS only stores the call
stack and not any variables this should be more than sufficient for most
applications.

GCSs allocated via this mechanism then it will be freed when the thread
exits, those explicitly configured by the user will not.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/gcs.h |   9 ++++
 arch/arm64/kernel/process.c  |  29 +++++++++++
 arch/arm64/mm/gcs.c          | 117 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+)

diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h
index 04594ef59dad..c1f274fdb9c0 100644
--- a/arch/arm64/include/asm/gcs.h
+++ b/arch/arm64/include/asm/gcs.h
@@ -8,6 +8,8 @@
 #include <asm/types.h>
 #include <asm/uaccess.h>
 
+struct kernel_clone_args;
+
 static inline void gcsb_dsync(void)
 {
 	asm volatile(".inst 0xd503227f" : : : "memory");
@@ -58,6 +60,8 @@ static inline bool task_gcs_el0_enabled(struct task_struct *task)
 void gcs_set_el0_mode(struct task_struct *task);
 void gcs_free(struct task_struct *task);
 void gcs_preserve_current_state(void);
+unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
+				     const struct kernel_clone_args *args);
 
 #else
 
@@ -69,6 +73,11 @@ static inline bool task_gcs_el0_enabled(struct task_struct *task)
 static inline void gcs_set_el0_mode(struct task_struct *task) { }
 static inline void gcs_free(struct task_struct *task) { }
 static inline void gcs_preserve_current_state(void) { }
+static inline unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
+						   const struct kernel_clone_args *args)
+{
+	return -ENOTSUPP;
+}
 
 #endif
 
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index fd80b43c2969..8bd66cde0a86 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -285,9 +285,32 @@ static void flush_gcs(void)
 	write_sysreg_s(0, SYS_GCSPR_EL0);
 }
 
+static int copy_thread_gcs(struct task_struct *p,
+			   const struct kernel_clone_args *args)
+{
+	unsigned long gcs;
+
+	gcs = gcs_alloc_thread_stack(p, args);
+	if (IS_ERR_VALUE(gcs))
+		return PTR_ERR((void *)gcs);
+
+	p->thread.gcs_el0_mode = current->thread.gcs_el0_mode;
+	p->thread.gcs_el0_locked = current->thread.gcs_el0_locked;
+
+	/* Ensure the current state of the GCS is seen by CoW */
+	gcsb_dsync();
+
+	return 0;
+}
+
 #else
 
 static void flush_gcs(void) { }
+static int copy_thread_gcs(struct task_struct *p,
+			   const struct kernel_clone_args *args)
+{
+	return 0;
+}
 
 #endif
 
@@ -303,6 +326,7 @@ void flush_thread(void)
 void arch_release_task_struct(struct task_struct *tsk)
 {
 	fpsimd_release_task(tsk);
+	gcs_free(tsk);
 }
 
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
@@ -369,6 +393,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 	unsigned long stack_start = args->stack;
 	unsigned long tls = args->tls;
 	struct pt_regs *childregs = task_pt_regs(p);
+	int ret;
 
 	memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
 
@@ -410,6 +435,10 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 			p->thread.uw.tp_value = tls;
 			p->thread.tpidr2_el0 = 0;
 		}
+
+		ret = copy_thread_gcs(p, args);
+		if (ret != 0)
+			return ret;
 	} else {
 		/*
 		 * A kthread has no context to ERET to, so ensure any buggy
diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c
index b0a67efc522b..3cbc3a3d4bc7 100644
--- a/arch/arm64/mm/gcs.c
+++ b/arch/arm64/mm/gcs.c
@@ -8,6 +8,113 @@
 #include <asm/cpufeature.h>
 #include <asm/page.h>
 
+static unsigned long alloc_gcs(unsigned long addr, unsigned long size,
+			       unsigned long token_offset, bool set_res_tok)
+{
+	int flags = MAP_ANONYMOUS | MAP_PRIVATE;
+	struct mm_struct *mm = current->mm;
+	unsigned long mapped_addr, unused;
+
+	if (addr)
+		flags |= MAP_FIXED_NOREPLACE;
+
+	mmap_write_lock(mm);
+	mapped_addr = do_mmap(NULL, addr, size, PROT_READ | PROT_WRITE, flags,
+			      VM_SHADOW_STACK, 0, &unused, NULL);
+	mmap_write_unlock(mm);
+
+	return mapped_addr;
+}
+
+static unsigned long gcs_size(unsigned long size)
+{
+	if (size)
+		return PAGE_ALIGN(size);
+
+	/* Allocate RLIMIT_STACK/2 with limits of PAGE_SIZE..2G */
+	size = PAGE_ALIGN(min_t(unsigned long long,
+				rlimit(RLIMIT_STACK) / 2, SZ_2G));
+	return max(PAGE_SIZE, size);
+}
+
+static bool gcs_consume_token(struct task_struct *tsk, unsigned long user_addr)
+{
+	unsigned long expected = GCS_CAP(user_addr);
+	unsigned long val;
+	int ret = 0;
+
+	/* This should really be an atomic cpmxchg.  It is not. */
+	__get_user_error(val, (__user unsigned long *)user_addr, ret);
+	if (ret != 0)
+		return false;
+
+	if (val != expected)
+		return false;
+
+	put_user_gcs(0, (__user unsigned long*)user_addr, &ret);
+
+	return ret == 0;
+}
+
+unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
+				     const struct kernel_clone_args *args)
+{
+	unsigned long addr, size, gcspr_el0;
+
+	/* If the user specified a GCS use it. */
+	if (args->shadow_stack_size) {
+		if (!system_supports_gcs())
+			return (unsigned long)ERR_PTR(-EINVAL);
+
+		addr = args->shadow_stack;
+		size = args->shadow_stack_size;
+
+		/*
+		 * There should be a token, there might be an end of
+		 * stack marker.
+		 */
+		gcspr_el0 = addr + size - (2 * sizeof(u64));
+		if (!gcs_consume_token(tsk, gcspr_el0)) {
+			gcspr_el0 += sizeof(u64);
+			if (!gcs_consume_token(tsk, gcspr_el0))
+				return (unsigned long)ERR_PTR(-EINVAL);
+		}
+
+		/* Userspace is responsible for unmapping */
+		tsk->thread.gcspr_el0 = gcspr_el0 + sizeof(u64);
+	} else {
+
+		/*
+		 * Otherwise fall back to legacy clone() support and
+		 * implicitly allocate a GCS if we need a new one.
+		 */
+
+		if (!system_supports_gcs())
+			return 0;
+
+		if (!task_gcs_el0_enabled(tsk))
+			return 0;
+
+		if ((args->flags & (CLONE_VFORK | CLONE_VM)) != CLONE_VM) {
+			tsk->thread.gcspr_el0 = read_sysreg_s(SYS_GCSPR_EL0);
+			return 0;
+		}
+
+		size = args->stack_size;
+
+		size = gcs_size(size);
+		addr = alloc_gcs(0, size, 0, 0);
+		if (IS_ERR_VALUE(addr))
+			return addr;
+
+		tsk->thread.gcs_base = addr;
+		tsk->thread.gcs_size = size;
+		tsk->thread.gcspr_el0 = addr + size - sizeof(u64);
+	}
+
+	return addr;
+}
+
 /*
  * Apply the GCS mode configured for the specified task to the
  * hardware.
@@ -30,6 +137,16 @@ void gcs_set_el0_mode(struct task_struct *task)
 
 void gcs_free(struct task_struct *task)
 {
+
+	/*
+	 * When fork() with CLONE_VM fails, the child (tsk) already
+	 * has a GCS allocated, and exit_thread() calls this function
+	 * to free it.  In this case the parent (current) and the
+	 * child share the same mm struct.
+	 */
+	if (!task->mm || task->mm != current->mm)
+		return;
+
 	if (task->thread.gcs_base)
 		vm_munmap(task->thread.gcs_base, task->thread.gcs_size);
 

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:48 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:48 +0000
Subject: [PATCH v8 22/38] arm64/mm: Implement map_shadow_stack()
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-22-c9fec77673ef@kernel.org>

As discussed extensively in the changelog for the addition of this
syscall on x86 ("x86/shstk: Introduce map_shadow_stack syscall") the
existing mmap() and madvise() syscalls do not map entirely well onto the
security requirements for guarded control stacks since they lead to
windows where memory is allocated but not yet protected or stacks which
are not properly and safely initialised. Instead a new syscall
map_shadow_stack() has been defined which allocates and initialises a
shadow stack page.

Implement this for arm64.  Two flags are provided, allowing applications
to request that the stack be initialised with a valid cap token at the
top of the stack and optionally also an end of stack marker above that.
We support requesting an end of stack marker alone but since this is a
NULL pointer it is indistinguishable from not initialising anything by
itself.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/mm/gcs.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c
index 95f5cf599bc6..f34821d98d85 100644
--- a/arch/arm64/mm/gcs.c
+++ b/arch/arm64/mm/gcs.c
@@ -115,6 +115,67 @@ unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
 	return addr;
 }
 
+SYSCALL_DEFINE3(map_shadow_stack, unsigned long, addr, unsigned long, size, unsigned int, flags)
+{
+	unsigned long alloc_size;
+	unsigned long __user *cap_ptr;
+	unsigned long cap_val;
+	int ret = 0;
+	int cap_offset;
+
+	if (!system_supports_gcs())
+		return -EOPNOTSUPP;
+
+	if (flags & ~(SHADOW_STACK_SET_TOKEN | SHADOW_STACK_SET_MARKER))
+		return -EINVAL;
+
+	if (addr && (addr % PAGE_SIZE))
+		return -EINVAL;
+
+	if (size == 8 || size % 8)
+		return -EINVAL;
+
+	/*
+	 * An overflow would result in attempting to write the restore token
+	 * to the wrong location. Not catastrophic, but just return the right
+	 * error code and block it.
+	 */
+	alloc_size = PAGE_ALIGN(size);
+	if (alloc_size < size)
+		return -EOVERFLOW;
+
+	addr = alloc_gcs(addr, alloc_size, 0, false);
+	if (IS_ERR_VALUE(addr))
+		return addr;
+
+	/*
+	 * Put a cap token at the end of the allocated region so it
+	 * can be switched to.
+	 */
+	if (flags & SHADOW_STACK_SET_TOKEN) {
+		/* Leave an extra empty frame as a top of stack marker? */
+		if (flags & SHADOW_STACK_SET_MARKER)
+			cap_offset = 2;
+		else
+			cap_offset = 1;
+
+		cap_ptr = (unsigned long __user *)(addr + size -
+						   (cap_offset * sizeof(unsigned long)));
+		cap_val = GCS_CAP(cap_ptr);
+
+		put_user_gcs(cap_val, cap_ptr, &ret);
+		if (ret != 0) {
+			vm_munmap(addr, size);
+			return -EFAULT;
+		}
+
+		/* Ensure the new cap is viaible for GCS */
+		gcsb_dsync();
+	}
+
+	return addr;
+}
+
 /*
  * Apply the GCS mode configured for the specified task to the
  * hardware.

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:47 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:47 +0000
Subject: [PATCH v8 21/38] arm64/gcs: Implement shadow stack prctl()
 interface
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-21-c9fec77673ef@kernel.org>

Implement the architecture neutral prtctl() interface for setting the
shadow stack status, this supports setting and reading the current GCS
configuration for the current thread.

Userspace can enable basic GCS functionality and additionally also
support for GCS pushes and arbitrary GCS stores.  It is expected that
this prctl() will be called very early in application startup, for
example by the dynamic linker, and not subsequently adjusted during
normal operation.  Users should carefully note that after enabling GCS
for a thread GCS will become active with no call stack so it is not
normally possible to return from the function that invoked the prctl().

State is stored per thread, enabling GCS for a thread causes a GCS to be
allocated for that thread.

Userspace may lock the current GCS configuration by specifying
PR_SHADOW_STACK_ENABLE_LOCK, this prevents any further changes to the
GCS configuration via any means.

If GCS is not being enabled then all flags other than _LOCK are ignored,
it is not possible to enable stores or pops without enabling GCS.

When disabling the GCS we do not free the allocated stack, this allows
for inspection of the GCS after disabling as part of fault reporting.
Since it is not an expected use case and since it presents some
complications in determining what to do with previously initialsed data
on the GCS attempts to reenable GCS after this are rejected.  This can
be revisted if a use case arises.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/gcs.h       | 22 ++++++++++
 arch/arm64/include/asm/processor.h |  1 +
 arch/arm64/mm/gcs.c                | 82 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 105 insertions(+)

diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h
index c1f274fdb9c0..48c97e63e56a 100644
--- a/arch/arm64/include/asm/gcs.h
+++ b/arch/arm64/include/asm/gcs.h
@@ -50,6 +50,9 @@ static inline u64 gcsss2(void)
 	return Xt;
 }
 
+#define PR_SHADOW_STACK_SUPPORTED_STATUS_MASK \
+	(PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | PR_SHADOW_STACK_PUSH)
+
 #ifdef CONFIG_ARM64_GCS
 
 static inline bool task_gcs_el0_enabled(struct task_struct *task)
@@ -63,6 +66,20 @@ void gcs_preserve_current_state(void);
 unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
 				     const struct kernel_clone_args *args);
 
+static inline int gcs_check_locked(struct task_struct *task,
+				   unsigned long new_val)
+{
+	unsigned long cur_val = task->thread.gcs_el0_mode;
+
+	cur_val &= task->thread.gcs_el0_locked;
+	new_val &= task->thread.gcs_el0_locked;
+
+	if (cur_val != new_val)
+		return -EBUSY;
+
+	return 0;
+}
+
 #else
 
 static inline bool task_gcs_el0_enabled(struct task_struct *task)
@@ -78,6 +95,11 @@ static inline unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
 {
 	return -ENOTSUPP;
 }
+static inline int gcs_check_locked(struct task_struct *task,
+				   unsigned long new_val)
+{
+	return 0;
+}
 
 #endif
 
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6fc6dcbd494c..6a3091ec0f03 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -184,6 +184,7 @@ struct thread_struct {
 	u64			tpidr2_el0;
 #ifdef CONFIG_ARM64_GCS
 	unsigned int		gcs_el0_mode;
+	unsigned int		gcs_el0_locked;
 	u64			gcspr_el0;
 	u64			gcs_base;
 	u64			gcs_size;
diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c
index 3cbc3a3d4bc7..95f5cf599bc6 100644
--- a/arch/arm64/mm/gcs.c
+++ b/arch/arm64/mm/gcs.c
@@ -154,3 +154,85 @@ void gcs_free(struct task_struct *task)
 	task->thread.gcs_base = 0;
 	task->thread.gcs_size = 0;
 }
+
+int arch_set_shadow_stack_status(struct task_struct *task, unsigned long arg)
+{
+	unsigned long gcs, size;
+	int ret;
+
+	if (!system_supports_gcs())
+		return -EINVAL;
+
+	if (is_compat_thread(task_thread_info(task)))
+		return -EINVAL;
+
+	/* Reject unknown flags */
+	if (arg & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK)
+		return -EINVAL;
+
+	ret = gcs_check_locked(task, arg);
+	if (ret != 0)
+		return ret;
+
+	/* If we are enabling GCS then make sure we have a stack */
+	if (arg & PR_SHADOW_STACK_ENABLE) {
+		if (!task_gcs_el0_enabled(task)) {
+			/* Do not allow GCS to be reenabled */
+			if (task->thread.gcs_base)
+				return -EINVAL;
+
+			if (task != current)
+				return -EBUSY;
+
+			size = gcs_size(0);
+			gcs = alloc_gcs(task->thread.gcspr_el0, size,
+					0, 0);
+			if (!gcs)
+				return -ENOMEM;
+
+			task->thread.gcspr_el0 = gcs + size - sizeof(u64);
+			task->thread.gcs_base = gcs;
+			task->thread.gcs_size = size;
+			if (task == current)
+				write_sysreg_s(task->thread.gcspr_el0,
+					       SYS_GCSPR_EL0);
+
+		}
+	}
+
+	task->thread.gcs_el0_mode = arg;
+	if (task == current)
+		gcs_set_el0_mode(task);
+
+	return 0;
+}
+
+int arch_get_shadow_stack_status(struct task_struct *task,
+				 unsigned long __user *arg)
+{
+	if (!system_supports_gcs())
+		return -EINVAL;
+
+	if (is_compat_thread(task_thread_info(task)))
+		return -EINVAL;
+
+	return put_user(task->thread.gcs_el0_mode, arg);
+}
+
+int arch_lock_shadow_stack_status(struct task_struct *task,
+				  unsigned long arg)
+{
+	if (!system_supports_gcs())
+		return -EINVAL;
+
+	if (is_compat_thread(task_thread_info(task)))
+		return -EINVAL;
+
+	/*
+	 * We support locking unknown bits so applications can prevent
+	 * any changes in a future proof manner.
+	 */
+	task->thread.gcs_el0_locked |= arg;
+
+	return 0;
+}

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:49 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:49 +0000
Subject: [PATCH v8 23/38] arm64/signal: Set up and restore the GCS context
 for signal handlers
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-23-c9fec77673ef@kernel.org>

When invoking a signal handler we use the GCS configuration and stack
for the current thread.

Since we implement signal return by calling the signal handler with a
return address set up pointing to a trampoline in the vDSO we need to
also configure any active GCS for this by pushing a frame for the
trampoline onto the GCS.  If we do not do this then signal return will
generate a GCS protection fault.

In order to guard against attempts to bypass GCS protections via signal
return we only allow returning with GCSPR_EL0 pointing to an address
where it was previously preempted by a signal.  We do this by pushing a
cap onto the GCS, this takes the form of an architectural GCS cap token
with the top bit set and token type of 0 which we add on signal entry
and validate and pop off on signal return.  The combination of the top
bit being set and the token type mean that this can't be interpreted as
a valid token or address.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/gcs.h |   1 +
 arch/arm64/kernel/signal.c   | 134 +++++++++++++++++++++++++++++++++++++++++--
 arch/arm64/mm/gcs.c          |   1 +
 3 files changed, 131 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h
index 48c97e63e56a..f50660603ecf 100644
--- a/arch/arm64/include/asm/gcs.h
+++ b/arch/arm64/include/asm/gcs.h
@@ -9,6 +9,7 @@
 #include <asm/uaccess.h>
 
 struct kernel_clone_args;
+struct ksignal;
 
 static inline void gcsb_dsync(void)
 {
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 0e8beb3349ea..1cca646a7479 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -25,6 +25,7 @@
 #include <asm/elf.h>
 #include <asm/exception.h>
 #include <asm/cacheflush.h>
+#include <asm/gcs.h>
 #include <asm/ucontext.h>
 #include <asm/unistd.h>
 #include <asm/fpsimd.h>
@@ -34,6 +35,37 @@
 #include <asm/traps.h>
 #include <asm/vdso.h>
 
+#ifdef CONFIG_ARM64_GCS
+/* Extra bit set in the address distinguishing a signal cap token. */
+#define GCS_SIGNAL_CAP_FLAG BIT(63)
+
+#define GCS_SIGNAL_CAP(addr) ((((unsigned long)addr) & GCS_CAP_ADDR_MASK) | \
+			      GCS_SIGNAL_CAP_FLAG)
+
+static bool gcs_signal_cap_valid(u64 addr, u64 val)
+{
+	/*
+	 * The top bit should be set, this is an invalid address for
+	 * EL0 and will only be set for caps created by signals.
+	 */
+	if (!(val & GCS_SIGNAL_CAP_FLAG))
+		return false;
+
+	/* The rest should be a standard architectural cap token. */
+	val &= ~GCS_SIGNAL_CAP_FLAG;
+
+	/* The cap must not have a token set */
+	if (GCS_CAP_TOKEN(val) != 0)
+		return false;
+
+	/* The cap must store the VA the cap was stored at */
+	if (GCS_CAP_ADDR(addr) != GCS_CAP_ADDR(val))
+		return false;
+
+	return true;
+}
+#endif
+
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
  */
@@ -815,6 +847,50 @@ static int restore_sigframe(struct pt_regs *regs,
 	return err;
 }
 
+#ifdef CONFIG_ARM64_GCS
+static int gcs_restore_signal(void)
+{
+	u64 gcspr_el0, cap;
+	int ret;
+
+	if (!system_supports_gcs())
+		return 0;
+
+	if (!(current->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE))
+		return 0;
+
+	gcspr_el0 = read_sysreg_s(SYS_GCSPR_EL0);
+
+	/*
+	 * GCSPR_EL0 should be pointing at a capped GCS, read the cap...
+	 */
+	gcsb_dsync();
+	ret = copy_from_user(&cap, (__user void*)gcspr_el0, sizeof(cap));
+	if (ret)
+		return -EFAULT;
+
+	/*
+	 * ...then check that the cap is the actual GCS before
+	 * restoring it.
+	 */
+	if (!gcs_signal_cap_valid(gcspr_el0, cap))
+		return -EINVAL;
+
+	/* Invalidate the token to prevent reuse */
+	put_user_gcs(0, (__user void*)gcspr_el0, &ret);
+	if (ret != 0)
+		return -EFAULT;
+
+	current->thread.gcspr_el0 = gcspr_el0 + sizeof(cap);
+	write_sysreg_s(current->thread.gcspr_el0, SYS_GCSPR_EL0);
+
+	return 0;
+}
+
+#else
+static int gcs_restore_signal(void) { return 0; }
+#endif
+
 SYSCALL_DEFINE0(rt_sigreturn)
 {
 	struct pt_regs *regs = current_pt_regs();
@@ -841,6 +917,9 @@ SYSCALL_DEFINE0(rt_sigreturn)
 	if (restore_altstack(&frame->uc.uc_stack))
 		goto badframe;
 
+	if (gcs_restore_signal())
+		goto badframe;
+
 	return regs->regs[0];
 
 badframe:
@@ -1071,7 +1150,50 @@ static int get_sigframe(struct rt_sigframe_user_layout *user,
 	return 0;
 }
 
-static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
+#ifdef CONFIG_ARM64_GCS
+
+static int gcs_signal_entry(__sigrestore_t sigtramp, struct ksignal *ksig)
+{
+	unsigned long __user *gcspr_el0;
+	int ret = 0;
+
+	if (!system_supports_gcs())
+		return 0;
+
+	if (!task_gcs_el0_enabled(current))
+		return 0;
+
+	/*
+	 * We are entering a signal handler, current register state is
+	 * active.
+	 */
+	gcspr_el0 = (unsigned long __user *)read_sysreg_s(SYS_GCSPR_EL0);
+
+	/*
+	 * Push a cap and the GCS entry for the trampoline onto the GCS.
+	 */
+	put_user_gcs((unsigned long)sigtramp, gcspr_el0 - 2, &ret);
+	put_user_gcs(GCS_SIGNAL_CAP(gcspr_el0 - 1), gcspr_el0 - 1, &ret);
+	if (ret != 0)
+		return ret;
+
+	gcsb_dsync();
+
+	gcspr_el0 -= 2;
+	write_sysreg_s((unsigned long)gcspr_el0, SYS_GCSPR_EL0);
+
+	return 0;
+}
+#else
+
+static int gcs_signal_entry(__sigrestore_t sigtramp, struct ksignal *ksig)
+{
+	return 0;
+}
+
+#endif
+
+static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
 			 struct rt_sigframe_user_layout *user, int usig)
 {
 	__sigrestore_t sigtramp;
@@ -1079,7 +1201,7 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 	regs->regs[0] = usig;
 	regs->sp = (unsigned long)user->sigframe;
 	regs->regs[29] = (unsigned long)&user->next_frame->fp;
-	regs->pc = (unsigned long)ka->sa.sa_handler;
+	regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
 
 	/*
 	 * Signal delivery is a (wacky) indirect function call in
@@ -1119,12 +1241,14 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 		sme_smstop();
 	}
 
-	if (ka->sa.sa_flags & SA_RESTORER)
-		sigtramp = ka->sa.sa_restorer;
+	if (ksig->ka.sa.sa_flags & SA_RESTORER)
+		sigtramp = ksig->ka.sa.sa_restorer;
 	else
 		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
 
 	regs->regs[30] = (unsigned long)sigtramp;
+
+	return gcs_signal_entry(sigtramp, ksig);
 }
 
 static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
@@ -1147,7 +1271,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
 	err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
 	err |= setup_sigframe(&user, regs, set);
 	if (err == 0) {
-		setup_return(regs, &ksig->ka, &user, usig);
+		err = setup_return(regs, ksig, &user, usig);
 		if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
 			err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 			regs->regs[1] = (unsigned long)&frame->info;
diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c
index f34821d98d85..2d8e54316fe2 100644
--- a/arch/arm64/mm/gcs.c
+++ b/arch/arm64/mm/gcs.c
@@ -6,6 +6,7 @@
 #include <linux/types.h>
 
 #include <asm/cpufeature.h>
+#include <asm/gcs.h>
 #include <asm/page.h>
 
 static unsigned long alloc_gcs(unsigned long addr, unsigned long size,

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:50 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:50 +0000
Subject: [PATCH v8 24/38] arm64/signal: Expose GCS state in signal frames
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-24-c9fec77673ef@kernel.org>

Add a context for the GCS state and include it in the signal context when
running on a system that supports GCS. We reuse the same flags that the
prctl() uses to specify which GCS features are enabled and also provide the
current GCS pointer.

We do not support enabling GCS via signal return, there is a conflict
between specifying GCSPR_EL0 and allocation of a new GCS and this is not
an ancticipated use case.  We also enforce GCS configuration locking on
signal return.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/sigcontext.h |   9 +++
 arch/arm64/kernel/signal.c               | 108 +++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
index f23c1dc3f002..7b66d245f2d2 100644
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -168,6 +168,15 @@ struct zt_context {
 	__u16 __reserved[3];
 };
 
+#define GCS_MAGIC	0x47435300
+
+struct gcs_context {
+	struct _aarch64_ctx head;
+	__u64 gcspr;
+	__u64 features_enabled;
+	__u64 reserved;
+};
+
 #endif /* !__ASSEMBLY__ */
 
 #include <asm/sve_context.h>
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 1cca646a7479..91bfb315bfd3 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -88,6 +88,7 @@ struct rt_sigframe_user_layout {
 
 	unsigned long fpsimd_offset;
 	unsigned long esr_offset;
+	unsigned long gcs_offset;
 	unsigned long sve_offset;
 	unsigned long tpidr2_offset;
 	unsigned long za_offset;
@@ -214,6 +215,8 @@ struct user_ctxs {
 	u32 za_size;
 	struct zt_context __user *zt;
 	u32 zt_size;
+	struct gcs_context __user *gcs;
+	u32 gcs_size;
 };
 
 static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
@@ -606,6 +609,83 @@ extern int restore_zt_context(struct user_ctxs *user);
 
 #endif /* ! CONFIG_ARM64_SME */
 
+#ifdef CONFIG_ARM64_GCS
+
+static int preserve_gcs_context(struct gcs_context __user *ctx)
+{
+	int err = 0;
+	u64 gcspr;
+
+	/*
+	 * We will add a cap token to the frame, include it in the
+	 * GCSPR_EL0 we report to support stack switching via
+	 * sigreturn.
+	 */
+	gcs_preserve_current_state();
+	gcspr = current->thread.gcspr_el0;
+	if (task_gcs_el0_enabled(current))
+		gcspr -= 8;
+
+	__put_user_error(GCS_MAGIC, &ctx->head.magic, err);
+	__put_user_error(sizeof(*ctx), &ctx->head.size, err);
+	__put_user_error(gcspr, &ctx->gcspr, err);
+	__put_user_error(0, &ctx->reserved, err);
+	__put_user_error(current->thread.gcs_el0_mode,
+			 &ctx->features_enabled, err);
+
+	return err;
+}
+
+static int restore_gcs_context(struct user_ctxs *user)
+{
+	u64 gcspr, enabled;
+	int err = 0;
+
+	if (user->gcs_size != sizeof(*user->gcs))
+		return -EINVAL;
+
+	__get_user_error(gcspr, &user->gcs->gcspr, err);
+	__get_user_error(enabled, &user->gcs->features_enabled, err);
+	if (err)
+		return err;
+
+	/* Don't allow unknown modes */
+	if (enabled & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK)
+		return -EINVAL;
+
+	err = gcs_check_locked(current, enabled);
+	if (err != 0)
+		return err;
+
+	/* Don't allow enabling */
+	if (!task_gcs_el0_enabled(current) &&
+	    (enabled & PR_SHADOW_STACK_ENABLE))
+		return -EINVAL;
+
+	/* If we are disabling disable everything */
+	if (!(enabled & PR_SHADOW_STACK_ENABLE))
+		enabled = 0;
+
+	current->thread.gcs_el0_mode = enabled;
+
+	/*
+	 * We let userspace set GCSPR_EL0 to anything here, we will
+	 * validate later in gcs_restore_signal().
+	 */
+	current->thread.gcspr_el0 = gcspr;
+	write_sysreg_s(current->thread.gcspr_el0, SYS_GCSPR_EL0);
+
+	return 0;
+}
+
+#else /* ! CONFIG_ARM64_GCS */
+
+/* Turn any non-optimised out attempts to use these into a link error: */
+extern int preserve_gcs_context(void __user *ctx);
+extern int restore_gcs_context(struct user_ctxs *user);
+
+#endif /* ! CONFIG_ARM64_GCS */
+
 static int parse_user_sigframe(struct user_ctxs *user,
 			       struct rt_sigframe __user *sf)
 {
@@ -622,6 +702,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
 	user->tpidr2 = NULL;
 	user->za = NULL;
 	user->zt = NULL;
+	user->gcs = NULL;
 
 	if (!IS_ALIGNED((unsigned long)base, 16))
 		goto invalid;
@@ -716,6 +797,17 @@ static int parse_user_sigframe(struct user_ctxs *user,
 			user->zt_size = size;
 			break;
 
+		case GCS_MAGIC:
+			if (!system_supports_gcs())
+				goto invalid;
+
+			if (user->gcs)
+				goto invalid;
+
+			user->gcs = (struct gcs_context __user *)head;
+			user->gcs_size = size;
+			break;
+
 		case EXTRA_MAGIC:
 			if (have_extra_context)
 				goto invalid;
@@ -835,6 +927,9 @@ static int restore_sigframe(struct pt_regs *regs,
 			err = restore_fpsimd_context(&user);
 	}
 
+	if (err == 0 && system_supports_gcs() && user.gcs)
+		err = restore_gcs_context(&user);
+
 	if (err == 0 && system_supports_tpidr2() && user.tpidr2)
 		err = restore_tpidr2_context(&user);
 
@@ -954,6 +1049,13 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
 			return err;
 	}
 
+	if (system_supports_gcs()) {
+		err = sigframe_alloc(user, &user->gcs_offset,
+				     sizeof(struct gcs_context));
+		if (err)
+			return err;
+	}
+
 	if (system_supports_sve() || system_supports_sme()) {
 		unsigned int vq = 0;
 
@@ -1047,6 +1149,12 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
 		__put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
 	}
 
+	if (system_supports_gcs() && err == 0 && user->gcs_offset) {
+		struct gcs_context __user *gcs_ctx =
+			apply_user_offset(user, user->gcs_offset);
+		err |= preserve_gcs_context(gcs_ctx);
+	}
+
 	/* Scalable Vector Extension state (including streaming), if present */
 	if ((system_supports_sve() || system_supports_sme()) &&
 	    err == 0 && user->sve_offset) {

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:51 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:51 +0000
Subject: [PATCH v8 25/38] arm64/ptrace: Expose GCS via ptrace and core
 files
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-25-c9fec77673ef@kernel.org>

Provide a new register type NT_ARM_GCS reporting the current GCS mode
and pointer for EL0.  Due to the interactions with allocation and
deallocation of Guarded Control Stacks we do not permit any changes to
the GCS mode via ptrace, only GCSPR_EL0 may be changed.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/ptrace.h |  8 +++++
 arch/arm64/kernel/ptrace.c           | 59 ++++++++++++++++++++++++++++++++++++
 include/uapi/linux/elf.h             |  1 +
 3 files changed, 68 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 7fa2f7036aa7..0f39ba4f3efd 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -324,6 +324,14 @@ struct user_za_header {
 #define ZA_PT_SIZE(vq)						\
 	(ZA_PT_ZA_OFFSET + ZA_PT_ZA_SIZE(vq))
 
+/* GCS state (NT_ARM_GCS) */
+
+struct user_gcs {
+	__u64 features_enabled;
+	__u64 features_locked;
+	__u64 gcspr_el0;
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _UAPI__ASM_PTRACE_H */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index dc6cf0e37194..c8dd489cfca8 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -34,6 +34,7 @@
 #include <asm/cpufeature.h>
 #include <asm/debug-monitors.h>
 #include <asm/fpsimd.h>
+#include <asm/gcs.h>
 #include <asm/mte.h>
 #include <asm/pointer_auth.h>
 #include <asm/stacktrace.h>
@@ -1411,6 +1412,51 @@ static int tagged_addr_ctrl_set(struct task_struct *target, const struct
 }
 #endif
 
+#ifdef CONFIG_ARM64_GCS
+static int gcs_get(struct task_struct *target,
+		   const struct user_regset *regset,
+		   struct membuf to)
+{
+	struct user_gcs user_gcs;
+
+	if (target == current)
+		gcs_preserve_current_state();
+
+	user_gcs.features_enabled = target->thread.gcs_el0_mode;
+	user_gcs.features_locked = target->thread.gcs_el0_locked;
+	user_gcs.gcspr_el0 = target->thread.gcspr_el0;
+
+	return membuf_write(&to, &user_gcs, sizeof(user_gcs));
+}
+
+static int gcs_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_gcs user_gcs;
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &user_gcs, 0, -1);
+	if (ret)
+		return ret;
+
+	if (user_gcs.features_enabled & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK)
+		return -EINVAL;
+
+	/* Do not allow enable via ptrace */
+	if ((user_gcs.features_enabled & PR_SHADOW_STACK_ENABLE) &&
+	    !(target->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE))
+		return -EBUSY;
+
+	target->thread.gcs_el0_mode = user_gcs.features_enabled;
+	target->thread.gcs_el0_locked = user_gcs.features_locked;
+	target->thread.gcspr_el0 = user_gcs.gcspr_el0;
+
+	return 0;
+}
+#endif
+
 enum aarch64_regset {
 	REGSET_GPR,
 	REGSET_FPR,
@@ -1439,6 +1485,9 @@ enum aarch64_regset {
 #ifdef CONFIG_ARM64_TAGGED_ADDR_ABI
 	REGSET_TAGGED_ADDR_CTRL,
 #endif
+#ifdef CONFIG_ARM64_GCS
+	REGSET_GCS,
+#endif
 };
 
 static const struct user_regset aarch64_regsets[] = {
@@ -1589,6 +1638,16 @@ static const struct user_regset aarch64_regsets[] = {
 		.set = tagged_addr_ctrl_set,
 	},
 #endif
+#ifdef CONFIG_ARM64_GCS
+	[REGSET_GCS] = {
+		.core_note_type = NT_ARM_GCS,
+		.n = sizeof(struct user_gcs) / sizeof(u64),
+		.size = sizeof(u64),
+		.align = sizeof(u64),
+		.regset_get = gcs_get,
+		.set = gcs_set,
+	},
+#endif
 };
 
 static const struct user_regset_view user_aarch64_view = {
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 9417309b7230..436dfc359f61 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -440,6 +440,7 @@ typedef struct elf64_shdr {
 #define NT_ARM_SSVE	0x40b		/* ARM Streaming SVE registers */
 #define NT_ARM_ZA	0x40c		/* ARM SME ZA registers */
 #define NT_ARM_ZT	0x40d		/* ARM SME ZT registers */
+#define NT_ARM_GCS	0x40e		/* ARM GCS state */
 #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  Sat Feb  3 04:25:52 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:52 +0000
Subject: [PATCH v8 26/38] arm64: Add Kconfig for Guarded Control Stack
 (GCS)
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-26-c9fec77673ef@kernel.org>

Provide a Kconfig option allowing the user to select if GCS support is
built into the kernel.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/Kconfig | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aa7c1d435139..e0048e4660cf 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2098,6 +2098,26 @@ config ARM64_EPAN
 	  if the cpu does not implement the feature.
 endmenu # "ARMv8.7 architectural features"
 
+menu "v9.4 architectural features"
+
+config ARM64_GCS
+	bool "Enable support for Guarded Control Stack (GCS)"
+	default y
+	select ARCH_HAS_USER_SHADOW_STACK
+	select ARCH_USES_HIGH_VMA_FLAGS
+	help
+	  Guarded Control Stack (GCS) provides support for a separate
+	  stack with restricted access which contains only return
+	  addresses.  This can be used to harden against some attacks
+	  by comparing return address used by the program with what is
+	  stored in the GCS, and may also be used to efficiently obtain
+	  the call stack for applications such as profiling.
+
+	  The feature is detected at runtime, and will remain disabled
+	  if the system does not implement the feature.
+
+endmenu # "v9.4 architectural features"
+
 config ARM64_SVE
 	bool "ARM Scalable Vector Extension support"
 	default y

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:54 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:54 +0000
Subject: [PATCH v8 28/38] kselftest/arm64: Add GCS as a detected feature in
 the signal tests
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-28-c9fec77673ef@kernel.org>

In preparation for testing GCS related signal handling add it as a feature
we check for in the signal handling support code.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/signal/test_signals.h       | 2 ++
 tools/testing/selftests/arm64/signal/test_signals_utils.c | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
index 1e6273d81575..7ada43688c02 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.h
+++ b/tools/testing/selftests/arm64/signal/test_signals.h
@@ -35,6 +35,7 @@ enum {
 	FSME_BIT,
 	FSME_FA64_BIT,
 	FSME2_BIT,
+	FGCS_BIT,
 	FMAX_END
 };
 
@@ -43,6 +44,7 @@ enum {
 #define FEAT_SME		(1UL << FSME_BIT)
 #define FEAT_SME_FA64		(1UL << FSME_FA64_BIT)
 #define FEAT_SME2		(1UL << FSME2_BIT)
+#define FEAT_GCS		(1UL << FGCS_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 0dc948db3a4a..89ef95c1af0e 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -30,6 +30,7 @@ static char const *const feats_names[FMAX_END] = {
 	" SME ",
 	" FA64 ",
 	" SME2 ",
+	" GCS ",
 };
 
 #define MAX_FEATS_SZ	128
@@ -329,6 +330,8 @@ int test_init(struct tdescr *td)
 			td->feats_supported |= FEAT_SME_FA64;
 		if (getauxval(AT_HWCAP2) & HWCAP2_SME2)
 			td->feats_supported |= FEAT_SME2;
+		if (getauxval(AT_HWCAP2) & HWCAP2_GCS)
+			td->feats_supported |= FEAT_GCS;
 		if (feats_ok(td)) {
 			if (td->feats_required & td->feats_supported)
 				fprintf(stderr,

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:53 +0000
Subject: [PATCH v8 27/38] kselftest/arm64: Verify the GCS hwcap
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-27-c9fec77673ef@kernel.org>

Add coverage of the GCS hwcap to the hwcap selftest, using a read of
GCSPR_EL0 to generate SIGILL without having to worry about enabling GCS.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/abi/hwcap.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c
index 1189e77c8152..bc9e3250a9df 100644
--- a/tools/testing/selftests/arm64/abi/hwcap.c
+++ b/tools/testing/selftests/arm64/abi/hwcap.c
@@ -63,6 +63,17 @@ static void fp_sigill(void)
 	asm volatile("fmov s0, #1");
 }
 
+static void gcs_sigill(void)
+{
+	unsigned long *gcspr;
+
+	asm volatile(
+		"mrs	%0, S3_3_C2_C5_1"
+	: "=r" (gcspr)
+	:
+	: "cc");
+}
+
 static void ilrcpc_sigill(void)
 {
 	/* LDAPUR W0, [SP, #8] */
@@ -360,6 +371,14 @@ static const struct hwcap_data {
 		.cpuinfo = "fp",
 		.sigill_fn = fp_sigill,
 	},
+	{
+		.name = "GCS",
+		.at_hwcap = AT_HWCAP2,
+		.hwcap_bit = HWCAP2_GCS,
+		.cpuinfo = "gcs",
+		.sigill_fn = gcs_sigill,
+		.sigill_reliable = true,
+	},
 	{
 		.name = "JSCVT",
 		.at_hwcap = AT_HWCAP,

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:55 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:55 +0000
Subject: [PATCH v8 29/38] kselftest/arm64: Add framework support for GCS to
 signal handling tests
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-29-c9fec77673ef@kernel.org>

Teach the framework about the GCS signal context, avoiding warnings on
the unknown context.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/signal/testcases/testcases.c | 7 +++++++
 tools/testing/selftests/arm64/signal/testcases/testcases.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c
index 9f580b55b388..1cd124732be4 100644
--- a/tools/testing/selftests/arm64/signal/testcases/testcases.c
+++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c
@@ -209,6 +209,13 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 			zt = (struct zt_context *)head;
 			new_flags |= ZT_CTX;
 			break;
+		case GCS_MAGIC:
+			if (flags & GCS_CTX)
+				*err = "Multiple GCS_MAGIC";
+			if (head->size != sizeof(struct gcs_context))
+				*err = "Bad size for gcs_context";
+			new_flags |= GCS_CTX;
+			break;
 		case EXTRA_MAGIC:
 			if (flags & EXTRA_CTX)
 				*err = "Multiple EXTRA_MAGIC";
diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.h b/tools/testing/selftests/arm64/signal/testcases/testcases.h
index a08ab0d6207a..9b2599745c29 100644
--- a/tools/testing/selftests/arm64/signal/testcases/testcases.h
+++ b/tools/testing/selftests/arm64/signal/testcases/testcases.h
@@ -19,6 +19,7 @@
 #define ZA_CTX		(1 << 2)
 #define EXTRA_CTX	(1 << 3)
 #define ZT_CTX		(1 << 4)
+#define GCS_CTX		(1 << 5)
 
 #define KSFT_BAD_MAGIC	0xdeadbeef
 

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:56 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:56 +0000
Subject: [PATCH v8 30/38] kselftest/arm64: Allow signals tests to specify
 an expected si_code
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-30-c9fec77673ef@kernel.org>

Currently we ignore si_code unless the expected signal is a SIGSEGV, in
which case we enforce it being SEGV_ACCERR. Allow test cases to specify
exactly which si_code should be generated so we can validate this, and
test for other segfault codes.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../testing/selftests/arm64/signal/test_signals.h  |  4 +++
 .../selftests/arm64/signal/test_signals_utils.c    | 29 ++++++++++++++--------
 2 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
index 7ada43688c02..ee75a2c25ce7 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.h
+++ b/tools/testing/selftests/arm64/signal/test_signals.h
@@ -71,6 +71,10 @@ struct tdescr {
 	 * Zero when no signal is expected on success
 	 */
 	int			sig_ok;
+	/*
+	 * expected si_code for sig_ok, or 0 to not check
+	 */
+	int			sig_ok_code;
 	/* signum expected on unsupported CPU features. */
 	int			sig_unsupp;
 	/* a timeout in second for test completion */
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 89ef95c1af0e..63deca32b0df 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -143,16 +143,25 @@ static bool handle_signal_ok(struct tdescr *td,
 			"current->token ZEROED...test is probably broken!\n");
 		abort();
 	}
-	/*
-	 * Trying to narrow down the SEGV to the ones generated by Kernel itself
-	 * via arm64_notify_segfault(). This is a best-effort check anyway, and
-	 * the si_code check may need to change if this aspect of the kernel
-	 * ABI changes.
-	 */
-	if (td->sig_ok == SIGSEGV && si->si_code != SEGV_ACCERR) {
-		fprintf(stdout,
-			"si_code != SEGV_ACCERR...test is probably broken!\n");
-		abort();
+	if (td->sig_ok_code) {
+		if (si->si_code != td->sig_ok_code) {
+			fprintf(stdout, "si_code is %d not %d\n",
+				si->si_code, td->sig_ok_code);
+			abort();
+		}
+	} else {
+		/*
+		 * Trying to narrow down the SEGV to the ones
+		 * generated by Kernel itself via
+		 * arm64_notify_segfault(). This is a best-effort
+		 * check anyway, and the si_code check may need to
+		 * change if this aspect of the kernel ABI changes.
+		 */
+		if (td->sig_ok == SIGSEGV && si->si_code != SEGV_ACCERR) {
+			fprintf(stdout,
+				"si_code != SEGV_ACCERR...test is probably broken!\n");
+			abort();
+		}
 	}
 	td->pass = 1;
 	/*

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:57 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:57 +0000
Subject: [PATCH v8 31/38] kselftest/arm64: Always run signals tests with
 GCS enabled
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-31-c9fec77673ef@kernel.org>

Since it is not possible to return from the function that enabled GCS
without disabling GCS it is very inconvenient to use the signal handling
tests to cover GCS when GCS is not enabled by the toolchain and runtime,
something that no current distribution does. Since none of the testcases
do anything with stacks that would cause problems with GCS we can sidestep
this issue by unconditionally enabling GCS on startup and exiting with a
call to exit() rather than a return from main().

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../testing/selftests/arm64/signal/test_signals.c  | 17 ++++++++++++-
 .../selftests/arm64/signal/test_signals_utils.h    | 29 ++++++++++++++++++++++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/signal/test_signals.c b/tools/testing/selftests/arm64/signal/test_signals.c
index 00051b40d71e..30e95f50db19 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.c
+++ b/tools/testing/selftests/arm64/signal/test_signals.c
@@ -7,6 +7,10 @@
  * Each test provides its own tde struct tdescr descriptor to link with
  * this wrapper. Framework provides common helpers.
  */
+
+#include <sys/auxv.h>
+#include <sys/prctl.h>
+
 #include <kselftest.h>
 
 #include "test_signals.h"
@@ -16,6 +20,16 @@ struct tdescr *current = &tde;
 
 int main(int argc, char *argv[])
 {
+	/*
+	 * Ensure GCS is at least enabled throughout the tests if
+	 * supported, otherwise the inability to return from the
+	 * function that enabled GCS makes it very inconvenient to set
+	 * up test cases.  The prctl() may fail if GCS was locked by
+	 * libc setup code.
+	 */
+	if (getauxval(AT_HWCAP2) & HWCAP2_GCS)
+		gcs_set_state(PR_SHADOW_STACK_ENABLE);
+
 	ksft_print_msg("%s :: %s\n", current->name, current->descr);
 	if (test_setup(current) && test_init(current)) {
 		test_run(current);
@@ -23,5 +37,6 @@ int main(int argc, char *argv[])
 	}
 	test_result(current);
 
-	return current->result;
+	/* Do not return in case GCS was enabled */
+	exit(current->result);
 }
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
index 762c8fe9c54a..1e80808ee105 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.h
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
@@ -18,6 +18,35 @@ void test_cleanup(struct tdescr *td);
 int test_run(struct tdescr *td);
 void test_result(struct tdescr *td);
 
+#ifndef __NR_prctl
+#define __NR_prctl 167
+#endif
+
+/*
+ * The prctl takes 1 argument but we need to ensure that the other
+ * values passed in registers to the syscall are zero since the kernel
+ * validates them.
+ */
+#define gcs_set_state(state)					\
+	({								\
+		register long _num  __asm__ ("x8") = __NR_prctl;	\
+		register long _arg1 __asm__ ("x0") =  PR_SET_SHADOW_STACK_STATUS; \
+		register long _arg2 __asm__ ("x1") = (long)(state);	\
+		register long _arg3 __asm__ ("x2") = 0;			\
+		register long _arg4 __asm__ ("x3") = 0;			\
+		register long _arg5 __asm__ ("x4") = 0;			\
+	                                                                      \
+		__asm__  volatile (					\
+			"svc #0\n"					\
+			: "=r"(_arg1)					\
+			: "r"(_arg1), "r"(_arg2),			\
+			  "r"(_arg3), "r"(_arg4),			\
+			  "r"(_arg5), "r"(_num)				\
+			: "memory", "cc"				\
+			);						\
+		_arg1;							\
+	})
+
 static inline bool feats_ok(struct tdescr *td)
 {
 	if (td->feats_incompatible & td->feats_supported)

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:58 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:58 +0000
Subject: [PATCH v8 32/38] kselftest/arm64: Add very basic GCS test program
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-32-c9fec77673ef@kernel.org>

This test program just covers the basic GCS ABI, covering aspects of the
ABI as standalone features without attempting to integrate things.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/Makefile        |   2 +-
 tools/testing/selftests/arm64/gcs/.gitignore  |   1 +
 tools/testing/selftests/arm64/gcs/Makefile    |  18 ++
 tools/testing/selftests/arm64/gcs/basic-gcs.c | 428 ++++++++++++++++++++++++++
 tools/testing/selftests/arm64/gcs/gcs-util.h  |  90 ++++++
 5 files changed, 538 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile
index 28b93cab8c0d..22029e60eff3 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 gcs
 else
 ARM64_SUBTARGETS :=
 endif
diff --git a/tools/testing/selftests/arm64/gcs/.gitignore b/tools/testing/selftests/arm64/gcs/.gitignore
new file mode 100644
index 000000000000..0e5e695ecba5
--- /dev/null
+++ b/tools/testing/selftests/arm64/gcs/.gitignore
@@ -0,0 +1 @@
+basic-gcs
diff --git a/tools/testing/selftests/arm64/gcs/Makefile b/tools/testing/selftests/arm64/gcs/Makefile
new file mode 100644
index 000000000000..61a30f483429
--- /dev/null
+++ b/tools/testing/selftests/arm64/gcs/Makefile
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2023 ARM Limited
+#
+# In order to avoid interaction with the toolchain and dynamic linker the
+# portions of these tests that interact with the GCS are implemented using
+# nolibc.
+#
+
+TEST_GEN_PROGS := basic-gcs
+
+include ../../lib.mk
+
+$(OUTPUT)/basic-gcs: basic-gcs.c
+	$(CC) -g -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
+		-static -include ../../../../include/nolibc/nolibc.h \
+		-I../../../../../usr/include \
+		-std=gnu99 -I../.. -g \
+		-ffreestanding -Wall $^ -o $@ -lgcc
diff --git a/tools/testing/selftests/arm64/gcs/basic-gcs.c b/tools/testing/selftests/arm64/gcs/basic-gcs.c
new file mode 100644
index 000000000000..3ef957e0065f
--- /dev/null
+++ b/tools/testing/selftests/arm64/gcs/basic-gcs.c
@@ -0,0 +1,428 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 ARM Limited.
+ */
+
+#include <limits.h>
+#include <stdbool.h>
+
+#include <linux/prctl.h>
+
+#include <sys/mman.h>
+#include <asm/mman.h>
+#include <linux/sched.h>
+
+#include "kselftest.h"
+#include "gcs-util.h"
+
+/* nolibc doesn't have sysconf(), just hard code the maximum */
+static size_t page_size = 65536;
+
+static  __attribute__((noinline)) void valid_gcs_function(void)
+{
+	/* Do something the compiler can't optimise out */
+	my_syscall1(__NR_prctl, PR_SVE_GET_VL);
+}
+
+static inline int gcs_set_status(unsigned long mode)
+{
+	bool enabling = mode & PR_SHADOW_STACK_ENABLE;
+	int ret;
+	unsigned long new_mode;
+
+	/*
+	 * The prctl takes 1 argument but we need to ensure that the
+	 * other 3 values passed in registers to the syscall are zero
+	 * since the kernel validates them.
+	 */
+	ret = my_syscall5(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, mode,
+			  0, 0, 0);
+
+	if (ret == 0) {
+		ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS,
+				  &new_mode, 0, 0, 0);
+		if (ret == 0) {
+			if (new_mode != mode) {
+				ksft_print_msg("Mode set to %x not %x\n",
+					       new_mode, mode);
+				ret = -EINVAL;
+			}
+		} else {
+			ksft_print_msg("Failed to validate mode: %d\n", ret);
+		}
+
+		if (enabling != chkfeat_gcs()) {
+			ksft_print_msg("%senabled by prctl but %senabled in CHKFEAT\n",
+				       enabling ? "" : "not ",
+				       chkfeat_gcs() ? "" : "not ");
+			ret = -EINVAL;
+		}
+	}
+
+	return ret;
+}
+
+/* Try to read the status */
+static bool read_status(void)
+{
+	unsigned long state;
+	int ret;
+
+	ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS,
+			  &state, 0, 0, 0);
+	if (ret != 0) {
+		ksft_print_msg("Failed to read state: %d\n", ret);
+		return false;
+	}
+
+	return state & PR_SHADOW_STACK_ENABLE;
+}
+
+/* Just a straight enable */
+static bool base_enable(void)
+{
+	int ret;
+
+	ret = gcs_set_status(PR_SHADOW_STACK_ENABLE);
+	if (ret) {
+		ksft_print_msg("PR_SHADOW_STACK_ENABLE failed %d\n", ret);
+		return false;
+	}
+
+	return true;
+}
+
+/* Check we can read GCSPR_EL0 when GCS is enabled */
+static bool read_gcspr_el0(void)
+{
+	unsigned long *gcspr_el0;
+
+	ksft_print_msg("GET GCSPR\n");
+	gcspr_el0 = get_gcspr();
+	ksft_print_msg("GCSPR_EL0 is %p\n", gcspr_el0);
+
+	return true;
+}
+
+/* Also allow writes to stack */
+static bool enable_writeable(void)
+{
+	int ret;
+
+	ret = gcs_set_status(PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE);
+	if (ret) {
+		ksft_print_msg("PR_SHADOW_STACK_ENABLE writeable failed: %d\n", ret);
+		return false;
+	}
+
+	ret = gcs_set_status(PR_SHADOW_STACK_ENABLE);
+	if (ret) {
+		ksft_print_msg("failed to restore plain enable %d\n", ret);
+		return false;
+	}
+
+	return true;
+}
+
+/* Also allow writes to stack */
+static bool enable_push_pop(void)
+{
+	int ret;
+
+	ret = gcs_set_status(PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_PUSH);
+	if (ret) {
+		ksft_print_msg("PR_SHADOW_STACK_ENABLE with push failed: %d\n",
+			       ret);
+		return false;
+	}
+
+	ret = gcs_set_status(PR_SHADOW_STACK_ENABLE);
+	if (ret) {
+		ksft_print_msg("failed to restore plain enable %d\n", ret);
+		return false;
+	}
+
+	return true;
+}
+
+/* Enable GCS and allow everything */
+static bool enable_all(void)
+{
+	int ret;
+
+	ret = gcs_set_status(PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_PUSH |
+			     PR_SHADOW_STACK_WRITE);
+	if (ret) {
+		ksft_print_msg("PR_SHADOW_STACK_ENABLE with everything failed: %d\n",
+			       ret);
+		return false;
+	}
+
+	ret = gcs_set_status(PR_SHADOW_STACK_ENABLE);
+	if (ret) {
+		ksft_print_msg("failed to restore plain enable %d\n", ret);
+		return false;
+	}
+
+	return true;
+}
+
+static bool enable_invalid(void)
+{
+	int ret = gcs_set_status(ULONG_MAX);
+	if (ret == 0) {
+		ksft_print_msg("GCS_SET_STATUS %lx succeeded\n", ULONG_MAX);
+		return false;
+	}
+
+	return true;
+}
+
+/* Map a GCS */
+static bool map_guarded_stack(void)
+{
+	int ret;
+	uint64_t *buf;
+	uint64_t expected_cap;
+	int elem;
+	bool pass = true;
+
+	buf = (void *)my_syscall3(__NR_map_shadow_stack, 0, page_size,
+				  SHADOW_STACK_SET_MARKER |
+				  SHADOW_STACK_SET_TOKEN);
+	if (buf == MAP_FAILED) {
+		ksft_print_msg("Failed to map %d byte GCS: %d\n",
+			       page_size, errno);
+		return false;
+	}
+	ksft_print_msg("Mapped GCS at %p-%p\n", buf,
+		       (uint64_t)buf + page_size);
+
+	/* The top of the newly allocated region should be 0 */
+	elem = (page_size / sizeof(uint64_t)) - 1;
+	if (buf[elem]) {
+		ksft_print_msg("Last entry is 0x%lx not 0x0\n", buf[elem]);
+		pass = false;
+	}
+
+	/* Then a valid cap token */
+	elem--;
+	expected_cap = ((uint64_t)buf + page_size - 16);
+	expected_cap &= GCS_CAP_ADDR_MASK;
+	expected_cap |= GCS_CAP_VALID_TOKEN;
+	if (buf[elem] != expected_cap) {
+		ksft_print_msg("Cap entry is 0x%lx not 0x%lx\n",
+			       buf[elem], expected_cap);
+		pass = false;
+	}
+	ksft_print_msg("cap token is 0x%lx\n", buf[elem]);
+
+	/* The rest should be zeros */
+	for (elem = 0; elem < page_size / sizeof(uint64_t) - 2; elem++) {
+		if (!buf[elem])
+			continue;
+		ksft_print_msg("GCS slot %d is 0x%lx not 0x0\n",
+			       elem, buf[elem]);
+		pass = false;
+	}
+
+	ret = munmap(buf, page_size);
+	if (ret != 0) {
+		ksft_print_msg("Failed to unmap %d byte GCS: %d\n",
+			       page_size, errno);
+		pass = false;
+	}
+
+	return pass;
+}
+
+/* A fork()ed process can run */
+static bool test_fork(void)
+{
+	unsigned long child_mode;
+	int ret, status;
+	pid_t pid;
+	bool pass = true;
+
+	pid = fork();
+	if (pid == -1) {
+		ksft_print_msg("fork() failed: %d\n", errno);
+		pass = false;
+		goto out;
+	}
+	if (pid == 0) {
+		/* In child, make sure we can call a function, read
+		 * the GCS pointer and status and then exit */
+		valid_gcs_function();
+		get_gcspr();
+
+		ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS,
+				  &child_mode, 0, 0, 0);
+		if (ret == 0 && !(child_mode & PR_SHADOW_STACK_ENABLE)) {
+			ksft_print_msg("GCS not enabled in child\n");
+			ret = -EINVAL;
+		}
+
+		exit(ret);
+	}
+
+	/*
+	 * In parent, check we can still do function calls then block
+	 * for the child.
+	 */
+	valid_gcs_function();
+
+	ksft_print_msg("Waiting for child %d\n", pid);
+
+	ret = waitpid(pid, &status, 0);
+	if (ret == -1) {
+		ksft_print_msg("Failed to wait for child: %d\n",
+			       errno);
+		return false;
+	}
+
+	if (!WIFEXITED(status)) {
+		ksft_print_msg("Child exited due to signal %d\n",
+			       WTERMSIG(status));
+		pass = false;
+	} else {
+		if (WEXITSTATUS(status)) {
+			ksft_print_msg("Child exited with status %d\n",
+				       WEXITSTATUS(status));
+			pass = false;
+		}
+	}
+
+out:
+
+	return pass;
+}
+
+/* Check that we can explicitly specify a GCS via clone3() */
+static bool test_clone3(void)
+{
+	struct clone_args args;
+	unsigned long child_mode;
+	pid_t pid = -1;
+	int status, ret;
+	bool pass;
+
+	memset(&args, 0, sizeof(args));
+	args.flags = CLONE_VM;
+	args.shadow_stack_size = page_size;
+
+	pid = my_syscall2(__NR_clone3, &args, sizeof(args));
+	if (pid < 0) {
+		ksft_print_msg("clone3() failed: %d\n", errno);
+		pass = false;
+		goto out;
+	}
+
+	/* In child? */
+	if (pid == 0) {
+		/* Do we have GCS enabled? */
+		ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS,
+				  &child_mode, 0, 0, 0);
+		if (ret != 0) {
+			ksft_print_msg("PR_GET_SHADOW_STACK_STATUS failed: %d\n",
+				       ret);
+			exit(EXIT_FAILURE);
+		}
+
+		if (!(child_mode & PR_SHADOW_STACK_ENABLE)) {
+			ksft_print_msg("GCS not enabled in child\n");
+			exit(EXIT_FAILURE);
+		}
+
+		ksft_print_msg("GCS enabled in child\n");
+
+		/* We've probably already called a function but make sure */
+		valid_gcs_function();
+
+		exit(EXIT_SUCCESS);
+	}
+
+	if (waitpid(-1, &status, __WALL) < 0) {
+		ksft_print_msg("waitpid() failed %d\n", errno);
+		pass = false;
+		goto out;
+	}
+	if (WIFEXITED(status)) {
+		if (WEXITSTATUS(status) == EXIT_SUCCESS) {
+			pass = true;
+		} else {
+			ksft_print_msg("Child returned status %d\n",
+				       WEXITSTATUS(status));
+			pass = false;
+		}
+	} else if (WIFSIGNALED(status)) {
+		ksft_print_msg("Child exited due to signal %d\n",
+			       WTERMSIG(status));
+		pass = false;
+	} else {
+		ksft_print_msg("Child exited uncleanly\n");
+		pass = false;
+	}
+
+out:
+	return pass;
+}
+
+typedef bool (*gcs_test)(void);
+
+static struct {
+	char *name;
+	gcs_test test;
+	bool needs_enable;
+} tests[] = {
+	{ "read_status", read_status },
+	{ "base_enable", base_enable, true },
+	{ "read_gcspr_el0", read_gcspr_el0 },
+	{ "enable_writeable", enable_writeable, true },
+	{ "enable_push_pop", enable_push_pop, true },
+	{ "enable_all", enable_all, true },
+	{ "enable_invalid", enable_invalid, true },
+	{ "map_guarded_stack", map_guarded_stack },
+	{ "fork", test_fork },
+	{ "clone3", test_clone3 },
+};
+
+int main(void)
+{
+	int i, ret;
+	unsigned long gcs_mode;
+
+	ksft_print_header();
+
+	/*
+	 * We don't have getauxval() with nolibc so treat a failure to
+	 * read GCS state as a lack of support and skip.
+	 */
+	ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS,
+			  &gcs_mode, 0, 0, 0);
+	if (ret != 0)
+		ksft_exit_skip("Failed to read GCS state: %d\n", ret);
+
+	if (!(gcs_mode & PR_SHADOW_STACK_ENABLE)) {
+		gcs_mode = PR_SHADOW_STACK_ENABLE;
+		ret = my_syscall5(__NR_prctl, PR_SET_SHADOW_STACK_STATUS,
+				  gcs_mode, 0, 0, 0);
+		if (ret != 0)
+			ksft_exit_fail_msg("Failed to enable GCS: %d\n", ret);
+	}
+
+	ksft_set_plan(ARRAY_SIZE(tests));
+
+	for (i = 0; i < ARRAY_SIZE(tests); i++) {
+		ksft_test_result((*tests[i].test)(), "%s\n", tests[i].name);
+	}
+
+	/* One last test: disable GCS, we can do this one time */
+	my_syscall5(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, 0, 0, 0, 0);
+	if (ret != 0)
+		ksft_print_msg("Failed to disable GCS: %d\n", ret);
+
+	ksft_finished();
+
+	return 0;
+}
diff --git a/tools/testing/selftests/arm64/gcs/gcs-util.h b/tools/testing/selftests/arm64/gcs/gcs-util.h
new file mode 100644
index 000000000000..b37801c95604
--- /dev/null
+++ b/tools/testing/selftests/arm64/gcs/gcs-util.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 ARM Limited.
+ */
+
+#ifndef GCS_UTIL_H
+#define GCS_UTIL_H
+
+#include <stdbool.h>
+
+#ifndef __NR_map_shadow_stack
+#define __NR_map_shadow_stack 453
+#endif
+
+#ifndef __NR_prctl
+#define __NR_prctl 167
+#endif
+
+/* Shadow Stack/Guarded Control Stack interface */
+#define PR_GET_SHADOW_STACK_STATUS	71
+#define PR_SET_SHADOW_STACK_STATUS      72
+#define PR_LOCK_SHADOW_STACK_STATUS     73
+
+# define PR_SHADOW_STACK_ENABLE         (1UL << 0)
+# define PR_SHADOW_STACK_WRITE		(1UL << 1)
+# define PR_SHADOW_STACK_PUSH		(1UL << 2)
+
+#define PR_SHADOW_STACK_ALL_MODES \
+	PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE | PR_SHADOW_STACK_PUSH
+
+#define SHADOW_STACK_SET_TOKEN (1ULL << 0)     /* Set up a restore token in the shadow stack */
+#define SHADOW_STACK_SET_MARKER (1ULL << 1)     /* Set up a top of stack merker in the shadow stack */
+
+#define GCS_CAP_ADDR_MASK		(0xfffffffffffff000UL)
+#define GCS_CAP_TOKEN_MASK		(0x0000000000000fffUL)
+#define GCS_CAP_VALID_TOKEN		1
+#define GCS_CAP_IN_PROGRESS_TOKEN	5
+
+#define GCS_CAP(x) (((unsigned long)(x) & GCS_CAP_ADDR_MASK) | \
+		    GCS_CAP_VALID_TOKEN)
+
+static inline unsigned long *get_gcspr(void)
+{
+	unsigned long *gcspr;
+
+	asm volatile(
+		"mrs	%0, S3_3_C2_C5_1"
+	: "=r" (gcspr)
+	:
+	: "cc");
+
+	return gcspr;
+}
+
+static inline void __attribute__((always_inline)) gcsss1(unsigned long *Xt)
+{
+	asm volatile (
+		"sys #3, C7, C7, #2, %0\n"
+		:
+		: "rZ" (Xt)
+		: "memory");
+}
+
+static inline unsigned long __attribute__((always_inline)) *gcsss2(void)
+{
+	unsigned long *Xt;
+
+	asm volatile(
+		"SYSL %0, #3, C7, C7, #3\n"
+		: "=r" (Xt)
+		:
+		: "memory");
+
+	return Xt;
+}
+
+static inline bool chkfeat_gcs(void)
+{
+	register long val __asm__ ("x16") = 1;
+
+	/* CHKFEAT x16 */
+	asm volatile(
+		"hint #0x28\n"
+		: "=r" (val)
+		: "r" (val));
+
+	return val != 1;
+}
+
+#endif

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:26:02 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:26:02 +0000
Subject: [PATCH v8 36/38] kselftest/arm64: Add a GCS stress test
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-36-c9fec77673ef@kernel.org>

Add a stress test which runs one more process than we have CPUs spinning
through a very recursive function with frequent syscalls immediately prior
to return and signals being injected every 100ms. The goal is to flag up
any scheduling related issues, for example failure to ensure that barriers
are inserted when moving a GCS using task to another CPU. The test runs for
a configurable amount of time, defaulting to 10 seconds.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/gcs/.gitignore       |   2 +
 tools/testing/selftests/arm64/gcs/Makefile         |   6 +-
 tools/testing/selftests/arm64/gcs/asm-offsets.h    |   0
 .../selftests/arm64/gcs/gcs-stress-thread.S        | 311 ++++++++++++
 tools/testing/selftests/arm64/gcs/gcs-stress.c     | 532 +++++++++++++++++++++
 5 files changed, 850 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/gcs/.gitignore b/tools/testing/selftests/arm64/gcs/.gitignore
index 0c86f53f68ad..1e8d1f6b27f2 100644
--- a/tools/testing/selftests/arm64/gcs/.gitignore
+++ b/tools/testing/selftests/arm64/gcs/.gitignore
@@ -1,3 +1,5 @@
 basic-gcs
 libc-gcs
 gcs-locking
+gcs-stress
+gcs-stress-thread
diff --git a/tools/testing/selftests/arm64/gcs/Makefile b/tools/testing/selftests/arm64/gcs/Makefile
index 2173d6275956..d8b06ca51e22 100644
--- a/tools/testing/selftests/arm64/gcs/Makefile
+++ b/tools/testing/selftests/arm64/gcs/Makefile
@@ -6,7 +6,8 @@
 # nolibc.
 #
 
-TEST_GEN_PROGS := basic-gcs libc-gcs gcs-locking
+TEST_GEN_PROGS := basic-gcs libc-gcs gcs-locking gcs-stress
+TEST_GEN_PROGS_EXTENDED := gcs-stress-thread
 
 LDLIBS+=-lpthread
 
@@ -18,3 +19,6 @@ $(OUTPUT)/basic-gcs: basic-gcs.c
 		-I../../../../../usr/include \
 		-std=gnu99 -I../.. -g \
 		-ffreestanding -Wall $^ -o $@ -lgcc
+
+$(OUTPUT)/gcs-stress-thread: gcs-stress-thread.S
+	$(CC) -nostdlib $^ -o $@
diff --git a/tools/testing/selftests/arm64/gcs/asm-offsets.h b/tools/testing/selftests/arm64/gcs/asm-offsets.h
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tools/testing/selftests/arm64/gcs/gcs-stress-thread.S b/tools/testing/selftests/arm64/gcs/gcs-stress-thread.S
new file mode 100644
index 000000000000..2a08d6bf1ced
--- /dev/null
+++ b/tools/testing/selftests/arm64/gcs/gcs-stress-thread.S
@@ -0,0 +1,311 @@
+// Program that loops for ever doing lots of recursions and system calls,
+// intended to be used as part of a stress test for GCS context switching.
+//
+// Copyright 2015-2023 Arm Ltd
+
+#include <asm/unistd.h>
+
+#define sa_sz 32
+#define sa_flags 8
+#define sa_handler 0
+#define sa_mask_sz 8
+
+#define si_code 8
+
+#define SIGINT 2
+#define SIGABRT 6
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGTERM 15
+#define SEGV_CPERR 10
+
+#define SA_NODEFER 1073741824
+#define SA_SIGINFO 4
+#define ucontext_regs 184
+
+#define PR_SET_SHADOW_STACK_STATUS      72
+# define PR_SHADOW_STACK_ENABLE         (1UL << 0)
+
+#define	GCSPR_EL0 S3_3_C2_C5_1
+
+.macro function name
+	.macro endfunction
+		.type \name, @function
+		.purgem endfunction
+	.endm
+\name:
+.endm
+
+// Print a single character x0 to stdout
+// Clobbers x0-x2,x8
+function putc
+	str	x0, [sp, #-16]!
+
+	mov	x0, #1			// STDOUT_FILENO
+	mov	x1, sp
+	mov	x2, #1
+	mov	x8, #__NR_write
+	svc	#0
+
+	add	sp, sp, #16
+	ret
+endfunction
+.globl	putc
+
+// Print a NUL-terminated string starting at address x0 to stdout
+// Clobbers x0-x3,x8
+function puts
+	mov	x1, x0
+
+	mov	x2, #0
+0:	ldrb	w3, [x0], #1
+	cbz	w3, 1f
+	add	x2, x2, #1
+	b	0b
+
+1:	mov	w0, #1			// STDOUT_FILENO
+	mov	x8, #__NR_write
+	svc	#0
+
+	ret
+endfunction
+.globl	puts
+
+// Utility macro to print a literal string
+// Clobbers x0-x4,x8
+.macro puts string
+	.pushsection .rodata.str1.1, "aMS", @progbits, 1
+.L__puts_literal\@: .string "\string"
+	.popsection
+
+	ldr	x0, =.L__puts_literal\@
+	bl	puts
+.endm
+
+// Print an unsigned decimal number x0 to stdout
+// Clobbers x0-x4,x8
+function putdec
+	mov	x1, sp
+	str	x30, [sp, #-32]!	// Result can't be > 20 digits
+
+	mov	x2, #0
+	strb	w2, [x1, #-1]!		// Write the NUL terminator
+
+	mov	x2, #10
+0:	udiv	x3, x0, x2		// div-mod loop to generate the digits
+	msub	x0, x3, x2, x0
+	add	w0, w0, #'0'
+	strb	w0, [x1, #-1]!
+	mov	x0, x3
+	cbnz	x3, 0b
+
+	ldrb	w0, [x1]
+	cbnz	w0, 1f
+	mov	w0, #'0'		// Print "0" for 0, not ""
+	strb	w0, [x1, #-1]!
+
+1:	mov	x0, x1
+	bl	puts
+
+	ldr	x30, [sp], #32
+	ret
+endfunction
+.globl	putdec
+
+// Print an unsigned decimal number x0 to stdout, followed by a newline
+// Clobbers x0-x5,x8
+function putdecn
+	mov	x5, x30
+
+	bl	putdec
+	mov	x0, #'\n'
+	bl	putc
+
+	ret	x5
+endfunction
+.globl	putdecn
+
+// Fill x1 bytes starting at x0 with 0.
+// Clobbers x1, x2.
+function memclr
+	mov	w2, #0
+endfunction
+.globl	memclr
+	// fall through to memfill
+
+// Trivial memory fill: fill x1 bytes starting at address x0 with byte w2
+// Clobbers x1
+function memfill
+	cmp	x1, #0
+	b.eq	1f
+
+0:	strb	w2, [x0], #1
+	subs	x1, x1, #1
+	b.ne	0b
+
+1:	ret
+endfunction
+.globl	memfill
+
+// 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	abort
+
+1:	ldr	x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
+	ret
+endfunction
+
+
+function tickle_handler
+	// Perhaps collect GCSPR_EL0 here in future?
+	ret
+endfunction
+
+function terminate_handler
+	mov	w21, w0
+	mov	x20, x2
+
+	puts	"Terminated by signal "
+	mov	w0, w21
+	bl	putdec
+	puts	", no error\n"
+
+	mov	x0, #0
+	mov	x8, #__NR_exit
+	svc	#0
+endfunction
+
+function segv_handler
+	// stash the siginfo_t *
+	mov	x20, x1
+
+	// Disable GCS, we don't want additional faults logging things
+	mov	x0, PR_SET_SHADOW_STACK_STATUS
+	mov	x1, xzr
+	mov	x2, xzr
+	mov	x3, xzr
+	mov	x4, xzr
+	mov	x5, xzr
+	mov	x8, #__NR_prctl
+	svc	#0
+
+	puts	"Got SIGSEGV code "
+
+	ldr	x21, [x20, #si_code]
+	mov	x0, x21
+	bl	putdec
+
+	// GCS faults should have si_code SEGV_CPERR
+	cmp	x21, #SEGV_CPERR
+	bne	1f
+
+	puts	" (GCS violation)"
+1:
+	mov	x0, '\n'
+	bl	putc
+	b	abort
+endfunction
+
+// Recurse x20 times
+.macro recurse id
+function recurse\id
+	stp	x29, x30, [sp, #-16]!
+	mov	x29, sp
+
+	cmp	x20, 0
+	beq	1f
+	sub	x20, x20, 1
+	bl	recurse\id
+
+1:
+	ldp	x29, x30, [sp], #16
+
+	// Do a syscall immediately prior to returning to try to provoke
+	// scheduling and migration at a point where coherency issues
+	// might trigger.
+	mov	x8, #__NR_getpid
+	svc	#0
+
+	ret
+endfunction
+.endm
+
+// Generate and use two copies so we're changing the GCS contents
+recurse 1
+recurse 2
+
+.globl _start
+function _start
+	// Run with GCS
+	mov	x0, PR_SET_SHADOW_STACK_STATUS
+	mov	x1, PR_SHADOW_STACK_ENABLE
+	mov	x2, xzr
+	mov	x3, xzr
+	mov	x4, xzr
+	mov	x5, xzr
+	mov	x8, #__NR_prctl
+	svc	#0
+	cbz	x0, 1f
+	puts	"Failed to enable GCS\n"
+	b	abort
+1:
+
+	mov	w0, #SIGTERM
+	adr	x1, terminate_handler
+	mov	w2, #SA_SIGINFO
+	bl	setsignal
+
+	mov	w0, #SIGUSR1
+	adr	x1, tickle_handler
+	mov	w2, #SA_SIGINFO
+	orr	w2, w2, #SA_NODEFER
+	bl	setsignal
+
+	mov	w0, #SIGSEGV
+	adr	x1, segv_handler
+	mov	w2, #SA_SIGINFO
+	orr	w2, w2, #SA_NODEFER
+	bl	setsignal
+
+	puts	"Running\n"
+
+loop:
+	// Small recursion depth so we're frequently flipping between
+	// the two recursors and changing what's on the stack
+	mov	x20, #5
+	bl	recurse1
+	mov	x20, #5
+	bl	recurse2
+	b	loop
+endfunction
+
+abort:
+	mov	x0, #255
+	mov	x8, #__NR_exit
+	svc	#0
diff --git a/tools/testing/selftests/arm64/gcs/gcs-stress.c b/tools/testing/selftests/arm64/gcs/gcs-stress.c
new file mode 100644
index 000000000000..23fd8ec37bdc
--- /dev/null
+++ b/tools/testing/selftests/arm64/gcs/gcs-stress.c
@@ -0,0 +1,532 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-3 ARM Limited.
+ */
+
+#define _GNU_SOURCE
+#define _POSIX_C_SOURCE 199309L
+
+#include <errno.h>
+#include <getopt.h>
+#include <poll.h>
+#include <signal.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/epoll.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <asm/hwcap.h>
+
+#include "../../kselftest.h"
+
+struct child_data {
+	char *name, *output;
+	pid_t pid;
+	int stdout;
+	bool output_seen;
+	bool exited;
+	int exit_status;
+	int exit_signal;
+};
+
+static int epoll_fd;
+static struct child_data *children;
+static struct epoll_event *evs;
+static int tests;
+static int num_children;
+static bool terminate;
+
+static int startup_pipe[2];
+
+static int num_processors(void)
+{
+	long nproc = sysconf(_SC_NPROCESSORS_CONF);
+	if (nproc < 0) {
+		perror("Unable to read number of processors\n");
+		exit(EXIT_FAILURE);
+	}
+
+	return nproc;
+}
+
+static void start_thread(struct child_data *child)
+{
+	int ret, pipefd[2], i;
+	struct epoll_event ev;
+
+	ret = pipe(pipefd);
+	if (ret != 0)
+		ksft_exit_fail_msg("Failed to create stdout pipe: %s (%d)\n",
+				   strerror(errno), errno);
+
+	child->pid = fork();
+	if (child->pid == -1)
+		ksft_exit_fail_msg("fork() failed: %s (%d)\n",
+				   strerror(errno), errno);
+
+	if (!child->pid) {
+		/*
+		 * In child, replace stdout with the pipe, errors to
+		 * stderr from here as kselftest prints to stdout.
+		 */
+		ret = dup2(pipefd[1], 1);
+		if (ret == -1) {
+			fprintf(stderr, "dup2() %d\n", errno);
+			exit(EXIT_FAILURE);
+		}
+
+		/*
+		 * Duplicate the read side of the startup pipe to
+		 * FD 3 so we can close everything else.
+		 */
+		ret = dup2(startup_pipe[0], 3);
+		if (ret == -1) {
+			fprintf(stderr, "dup2() %d\n", errno);
+			exit(EXIT_FAILURE);
+		}
+
+		/*
+		 * Very dumb mechanism to clean open FDs other than
+		 * stdio. We don't want O_CLOEXEC for the pipes...
+		 */
+		for (i = 4; i < 8192; i++)
+			close(i);
+
+		/*
+		 * Read from the startup pipe, there should be no data
+		 * and we should block until it is closed.  We just
+		 * carry on on error since this isn't super critical.
+		 */
+		ret = read(3, &i, sizeof(i));
+		if (ret < 0)
+			fprintf(stderr, "read(startp pipe) failed: %s (%d)\n",
+				strerror(errno), errno);
+		if (ret > 0)
+			fprintf(stderr, "%d bytes of data on startup pipe\n",
+				ret);
+		close(3);
+
+		ret = execl("gcs-stress-thread", "gcs-stress-thread", NULL);
+		fprintf(stderr, "execl(gcs-stress-thread) failed: %d (%s)\n",
+			errno, strerror(errno));
+
+		exit(EXIT_FAILURE);
+	} else {
+		/*
+		 * In parent, remember the child and close our copy of the
+		 * write side of stdout.
+		 */
+		close(pipefd[1]);
+		child->stdout = pipefd[0];
+		child->output = NULL;
+		child->exited = false;
+		child->output_seen = false;
+
+		ev.events = EPOLLIN | EPOLLHUP;
+		ev.data.ptr = child;
+
+		ret = asprintf(&child->name, "Thread-%d", child->pid);
+		if (ret == -1)
+			ksft_exit_fail_msg("asprintf() failed\n");
+
+		ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, child->stdout, &ev);
+		if (ret < 0) {
+			ksft_exit_fail_msg("%s EPOLL_CTL_ADD failed: %s (%d)\n",
+					   child->name, strerror(errno), errno);
+		}
+	}
+
+	ksft_print_msg("Started %s\n", child->name);
+	num_children++;
+}
+
+static bool child_output_read(struct child_data *child)
+{
+	char read_data[1024];
+	char work[1024];
+	int ret, len, cur_work, cur_read;
+
+	ret = read(child->stdout, read_data, sizeof(read_data));
+	if (ret < 0) {
+		if (errno == EINTR)
+			return true;
+
+		ksft_print_msg("%s: read() failed: %s (%d)\n",
+			       child->name, strerror(errno),
+			       errno);
+		return false;
+	}
+	len = ret;
+
+	child->output_seen = true;
+
+	/* Pick up any partial read */
+	if (child->output) {
+		strncpy(work, child->output, sizeof(work) - 1);
+		cur_work = strnlen(work, sizeof(work));
+		free(child->output);
+		child->output = NULL;
+	} else {
+		cur_work = 0;
+	}
+
+	cur_read = 0;
+	while (cur_read < len) {
+		work[cur_work] = read_data[cur_read++];
+
+		if (work[cur_work] == '\n') {
+			work[cur_work] = '\0';
+			ksft_print_msg("%s: %s\n", child->name, work);
+			cur_work = 0;
+		} else {
+			cur_work++;
+		}
+	}
+
+	if (cur_work) {
+		work[cur_work] = '\0';
+		ret = asprintf(&child->output, "%s", work);
+		if (ret == -1)
+			ksft_exit_fail_msg("Out of memory\n");
+	}
+
+	return false;
+}
+
+static void child_output(struct child_data *child, uint32_t events,
+			 bool flush)
+{
+	bool read_more;
+
+	if (events & EPOLLIN) {
+		do {
+			read_more = child_output_read(child);
+		} while (read_more);
+	}
+
+	if (events & EPOLLHUP) {
+		close(child->stdout);
+		child->stdout = -1;
+		flush = true;
+	}
+
+	if (flush && child->output) {
+		ksft_print_msg("%s: %s<EOF>\n", child->name, child->output);
+		free(child->output);
+		child->output = NULL;
+	}
+}
+
+static void child_tickle(struct child_data *child)
+{
+	if (child->output_seen && !child->exited)
+		kill(child->pid, SIGUSR1);
+}
+
+static void child_stop(struct child_data *child)
+{
+	if (!child->exited)
+		kill(child->pid, SIGTERM);
+}
+
+static void child_cleanup(struct child_data *child)
+{
+	pid_t ret;
+	int status;
+	bool fail = false;
+
+	if (!child->exited) {
+		do {
+			ret = waitpid(child->pid, &status, 0);
+			if (ret == -1 && errno == EINTR)
+				continue;
+
+			if (ret == -1) {
+				ksft_print_msg("waitpid(%d) failed: %s (%d)\n",
+					       child->pid, strerror(errno),
+					       errno);
+				fail = true;
+				break;
+			}
+
+			if (WIFEXITED(status)) {
+				child->exit_status = WEXITSTATUS(status);
+				child->exited = true;
+			}
+
+			if (WIFSIGNALED(status)) {
+				child->exit_signal = WTERMSIG(status);
+				ksft_print_msg("%s: Exited due to signal %d\n",
+					       child->name);
+				fail = true;
+				child->exited = true;
+			}
+		} while (!child->exited);
+	}
+
+	if (!child->output_seen) {
+		ksft_print_msg("%s no output seen\n", child->name);
+		fail = true;
+	}
+
+	if (child->exit_status != 0) {
+		ksft_print_msg("%s exited with error code %d\n",
+			       child->name, child->exit_status);
+		fail = true;
+	}
+
+	ksft_test_result(!fail, "%s\n", child->name);
+}
+
+static void handle_child_signal(int sig, siginfo_t *info, void *context)
+{
+	int i;
+	bool found = false;
+
+	for (i = 0; i < num_children; i++) {
+		if (children[i].pid == info->si_pid) {
+			children[i].exited = true;
+			children[i].exit_status = info->si_status;
+			found = true;
+			break;
+		}
+	}
+
+	if (!found)
+		ksft_print_msg("SIGCHLD for unknown PID %d with status %d\n",
+			       info->si_pid, info->si_status);
+}
+
+static void handle_exit_signal(int sig, siginfo_t *info, void *context)
+{
+	int i;
+
+	/* If we're already exiting then don't signal again */
+	if (terminate)
+		return;
+
+	ksft_print_msg("Got signal, exiting...\n");
+
+	terminate = true;
+
+	/*
+	 * This should be redundant, the main loop should clean up
+	 * after us, but for safety stop everything we can here.
+	 */
+	for (i = 0; i < num_children; i++)
+		child_stop(&children[i]);
+}
+
+/* Handle any pending output without blocking */
+static void drain_output(bool flush)
+{
+	int ret = 1;
+	int i;
+
+	while (ret > 0) {
+		ret = epoll_wait(epoll_fd, evs, tests, 0);
+		if (ret < 0) {
+			if (errno == EINTR)
+				continue;
+			ksft_print_msg("epoll_wait() failed: %s (%d)\n",
+				       strerror(errno), errno);
+		}
+
+		for (i = 0; i < ret; i++)
+			child_output(evs[i].data.ptr, evs[i].events, flush);
+	}
+}
+
+static const struct option options[] = {
+	{ "timeout",	required_argument, NULL, 't' },
+	{ }
+};
+
+int main(int argc, char **argv)
+{
+	int seen_children;
+	bool all_children_started = false;
+	int gcs_threads;
+	int timeout = 10;
+	int ret, cpus, i, c;
+	struct sigaction sa;
+
+	while ((c = getopt_long(argc, argv, "t:", options, NULL)) != -1) {
+		switch (c) {
+		case 't':
+			ret = sscanf(optarg, "%d", &timeout);
+			if (ret != 1)
+				ksft_exit_fail_msg("Failed to parse timeout %s\n",
+						   optarg);
+			break;
+		default:
+			ksft_exit_fail_msg("Unknown argument\n");
+		}
+	}
+
+	cpus = num_processors();
+	tests = 0;
+
+	if (getauxval(AT_HWCAP2) & HWCAP2_GCS) {
+		/* One extra thread, trying to trigger migrations */
+		gcs_threads = cpus + 1;
+		tests += gcs_threads;
+	} else {
+		gcs_threads = 0;
+	}
+
+	ksft_print_header();
+	ksft_set_plan(tests);
+
+	ksft_print_msg("%d CPUs, %d GCS threads\n",
+		       cpus, gcs_threads);
+
+	if (!tests)
+		ksft_exit_skip("No tests scheduled\n");
+
+	if (timeout > 0)
+		ksft_print_msg("Will run for %ds\n", timeout);
+	else
+		ksft_print_msg("Will run until terminated\n");
+
+	children = calloc(sizeof(*children), tests);
+	if (!children)
+		ksft_exit_fail_msg("Unable to allocate child data\n");
+
+	ret = epoll_create1(EPOLL_CLOEXEC);
+	if (ret < 0)
+		ksft_exit_fail_msg("epoll_create1() failed: %s (%d)\n",
+				   strerror(errno), ret);
+	epoll_fd = ret;
+
+	/* Create a pipe which children will block on before execing */
+	ret = pipe(startup_pipe);
+	if (ret != 0)
+		ksft_exit_fail_msg("Failed to create startup pipe: %s (%d)\n",
+				   strerror(errno), errno);
+
+	/* Get signal handers ready before we start any children */
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_sigaction = handle_exit_signal;
+	sa.sa_flags = SA_RESTART | SA_SIGINFO;
+	sigemptyset(&sa.sa_mask);
+	ret = sigaction(SIGINT, &sa, NULL);
+	if (ret < 0)
+		ksft_print_msg("Failed to install SIGINT handler: %s (%d)\n",
+			       strerror(errno), errno);
+	ret = sigaction(SIGTERM, &sa, NULL);
+	if (ret < 0)
+		ksft_print_msg("Failed to install SIGTERM handler: %s (%d)\n",
+			       strerror(errno), errno);
+	sa.sa_sigaction = handle_child_signal;
+	ret = sigaction(SIGCHLD, &sa, NULL);
+	if (ret < 0)
+		ksft_print_msg("Failed to install SIGCHLD handler: %s (%d)\n",
+			       strerror(errno), errno);
+
+	evs = calloc(tests, sizeof(*evs));
+	if (!evs)
+		ksft_exit_fail_msg("Failed to allocated %d epoll events\n",
+				   tests);
+
+	for (i = 0; i < gcs_threads; i++)
+		start_thread(&children[i]);
+
+	/*
+	 * All children started, close the startup pipe and let them
+	 * run.
+	 */
+	close(startup_pipe[0]);
+	close(startup_pipe[1]);
+
+	timeout *= 10;
+	for (;;) {
+		/* Did we get a signal asking us to exit? */
+		if (terminate)
+			break;
+
+		/*
+		 * Timeout is counted in 100ms with no output, the
+		 * tests print during startup then are silent when
+		 * running so this should ensure they all ran enough
+		 * to install the signal handler, this is especially
+		 * useful in emulation where we will both be slow and
+		 * likely to have a large set of VLs.
+		 */
+		ret = epoll_wait(epoll_fd, evs, tests, 100);
+		if (ret < 0) {
+			if (errno == EINTR)
+				continue;
+			ksft_exit_fail_msg("epoll_wait() failed: %s (%d)\n",
+					   strerror(errno), errno);
+		}
+
+		/* Output? */
+		if (ret > 0) {
+			for (i = 0; i < ret; i++) {
+				child_output(evs[i].data.ptr, evs[i].events,
+					     false);
+			}
+			continue;
+		}
+
+		/* Otherwise epoll_wait() timed out */
+
+		/*
+		 * If the child processes have not produced output they
+		 * aren't actually running the tests yet.
+		 */
+		if (!all_children_started) {
+			seen_children = 0;
+
+			for (i = 0; i < num_children; i++)
+				if (children[i].output_seen ||
+				    children[i].exited)
+					seen_children++;
+
+			if (seen_children != num_children) {
+				ksft_print_msg("Waiting for %d children\n",
+					       num_children - seen_children);
+				continue;
+			}
+
+			all_children_started = true;
+		}
+
+		ksft_print_msg("Sending signals, timeout remaining: %d00ms\n",
+			       timeout);
+
+		for (i = 0; i < num_children; i++)
+			child_tickle(&children[i]);
+
+		/* Negative timeout means run indefinitely */
+		if (timeout < 0)
+			continue;
+		if (--timeout == 0)
+			break;
+	}
+
+	ksft_print_msg("Finishing up...\n");
+	terminate = true;
+
+	for (i = 0; i < tests; i++)
+		child_stop(&children[i]);
+
+	drain_output(false);
+
+	for (i = 0; i < tests; i++)
+		child_cleanup(&children[i]);
+
+	drain_output(true);
+
+	ksft_print_cnts();
+
+	return 0;
+}

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:25:59 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:25:59 +0000
Subject: [PATCH v8 33/38] kselftest/arm64: Add a GCS test program built
 with the system libc
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-33-c9fec77673ef@kernel.org>

There are things like threads which nolibc struggles with which we want
to add coverage for, and the ABI allows us to test most of these even if
libc itself does not understand GCS so add a test application built
using the system libc.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/gcs/.gitignore |   1 +
 tools/testing/selftests/arm64/gcs/Makefile   |   4 +-
 tools/testing/selftests/arm64/gcs/gcs-util.h |  10 +
 tools/testing/selftests/arm64/gcs/libc-gcs.c | 736 +++++++++++++++++++++++++++
 4 files changed, 750 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/gcs/.gitignore b/tools/testing/selftests/arm64/gcs/.gitignore
index 0e5e695ecba5..5810c4a163d4 100644
--- a/tools/testing/selftests/arm64/gcs/.gitignore
+++ b/tools/testing/selftests/arm64/gcs/.gitignore
@@ -1 +1,2 @@
 basic-gcs
+libc-gcs
diff --git a/tools/testing/selftests/arm64/gcs/Makefile b/tools/testing/selftests/arm64/gcs/Makefile
index 61a30f483429..a8fdf21e9a47 100644
--- a/tools/testing/selftests/arm64/gcs/Makefile
+++ b/tools/testing/selftests/arm64/gcs/Makefile
@@ -6,7 +6,9 @@
 # nolibc.
 #
 
-TEST_GEN_PROGS := basic-gcs
+TEST_GEN_PROGS := basic-gcs libc-gcs
+
+LDLIBS+=-lpthread
 
 include ../../lib.mk
 
diff --git a/tools/testing/selftests/arm64/gcs/gcs-util.h b/tools/testing/selftests/arm64/gcs/gcs-util.h
index b37801c95604..4bafd1d7feb5 100644
--- a/tools/testing/selftests/arm64/gcs/gcs-util.h
+++ b/tools/testing/selftests/arm64/gcs/gcs-util.h
@@ -16,6 +16,16 @@
 #define __NR_prctl 167
 #endif
 
+#ifndef NT_ARM_GCS
+#define NT_ARM_GCS 0x40e
+
+struct user_gcs {
+	__u64 features_enabled;
+	__u64 features_locked;
+	__u64 gcspr_el0;
+};
+#endif
+
 /* Shadow Stack/Guarded Control Stack interface */
 #define PR_GET_SHADOW_STACK_STATUS	71
 #define PR_SET_SHADOW_STACK_STATUS      72
diff --git a/tools/testing/selftests/arm64/gcs/libc-gcs.c b/tools/testing/selftests/arm64/gcs/libc-gcs.c
new file mode 100644
index 000000000000..937f8bee7bdd
--- /dev/null
+++ b/tools/testing/selftests/arm64/gcs/libc-gcs.c
@@ -0,0 +1,736 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 ARM Limited.
+ */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdbool.h>
+
+#include <sys/auxv.h>
+#include <sys/mman.h>
+#include <sys/prctl.h>
+#include <sys/ptrace.h>
+#include <sys/uio.h>
+
+#include <asm/hwcap.h>
+#include <asm/mman.h>
+
+#include <linux/compiler.h>
+
+#include "kselftest_harness.h"
+
+#include "gcs-util.h"
+
+#define my_syscall2(num, arg1, arg2)                                          \
+({                                                                            \
+	register long _num  __asm__ ("x8") = (num);                           \
+	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
+	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
+	register long _arg3 __asm__ ("x2") = 0;                               \
+	register long _arg4 __asm__ ("x3") = 0;                               \
+	register long _arg5 __asm__ ("x4") = 0;                               \
+	                                                                      \
+	__asm__  volatile (                                                   \
+		"svc #0\n"                                                    \
+		: "=r"(_arg1)                                                 \
+		: "r"(_arg1), "r"(_arg2),                                     \
+		  "r"(_arg3), "r"(_arg4),                                     \
+		  "r"(_arg5), "r"(_num)					      \
+		: "memory", "cc"                                              \
+	);                                                                    \
+	_arg1;                                                                \
+})
+
+static noinline void gcs_recurse(int depth)
+{
+	if (depth)
+		gcs_recurse(depth - 1);
+
+	/* Prevent tail call optimization so we actually recurse */
+	asm volatile("dsb sy" : : : "memory");
+}
+
+/* Smoke test that a function call and return works*/
+TEST(can_call_function)
+{
+	gcs_recurse(0);
+}
+
+static void *gcs_test_thread(void *arg)
+{
+	int ret;
+	unsigned long mode;
+
+	/*
+	 * Some libcs don't seem to fill unused arguments with 0 but
+	 * the kernel validates this so we supply all 5 arguments.
+	 */
+	ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0);
+	if (ret != 0) {
+		ksft_print_msg("PR_GET_SHADOW_STACK_STATUS failed: %d\n", ret);
+		return NULL;
+	}
+
+	if (!(mode & PR_SHADOW_STACK_ENABLE)) {
+		ksft_print_msg("GCS not enabled in thread, mode is %u\n",
+			       mode);
+		return NULL;
+	}
+
+	/* Just in case... */
+	gcs_recurse(0);
+
+	/* Use a non-NULL value to indicate a pass */
+	return &gcs_test_thread;
+}
+
+/* Verify that if we start a new thread it has GCS enabled */
+TEST(gcs_enabled_thread)
+{
+	pthread_t thread;
+	void *thread_ret;
+	int ret;
+
+	ret = pthread_create(&thread, NULL, gcs_test_thread, NULL);
+	ASSERT_TRUE(ret == 0);
+	if (ret != 0)
+		return;
+
+	ret = pthread_join(thread, &thread_ret);
+	ASSERT_TRUE(ret == 0);
+	if (ret != 0)
+		return;
+
+	ASSERT_TRUE(thread_ret != NULL);
+}
+
+/* Read the GCS until we find the terminator */
+TEST(gcs_find_terminator)
+{
+	unsigned long *gcs, *cur;
+
+	gcs = get_gcspr();
+	cur = gcs;
+	while (*cur)
+		cur++;
+
+	ksft_print_msg("GCS in use from %p-%p\n", gcs, cur);
+
+	/*
+	 * We should have at least whatever called into this test so
+	 * the two pointer should differ.
+	 */
+	ASSERT_TRUE(gcs != cur);
+}
+
+/*
+ * We can access a GCS via ptrace
+ *
+ * This could usefully have a fixture but note that each test is
+ * fork()ed into a new child whcih causes issues.  Might be better to
+ * lift at least some of this out into a separate, non-harness, test
+ * program.
+ */
+TEST(ptrace_read_write)
+{
+	pid_t child, pid;
+	int ret, status;
+	siginfo_t si;
+	uint64_t val, rval, gcspr;
+	struct user_gcs child_gcs;
+	struct iovec iov, local_iov, remote_iov;
+
+	child = fork();
+	if (child == -1) {
+		ksft_print_msg("fork() failed: %d (%s)\n",
+			       errno, strerror(errno));
+		ASSERT_NE(child, -1);
+	}
+
+	if (child == 0) {
+		/*
+		 * In child, make sure there's something on the stack and
+		 * ask to be traced.
+		 */
+		gcs_recurse(0);
+		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;
+	}
+
+	ksft_print_msg("Child: %d\n", child);
+
+	/* Attach to the child */
+	while (1) {
+		int sig;
+
+		pid = wait(&status);
+		if (pid == -1) {
+			ksft_print_msg("wait() failed: %s",
+				       strerror(errno));
+			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) {
+				ASSERT_NE(errno, ESRCH);
+				return;
+			}
+
+			if (errno == EINVAL) {
+				sig = 0; /* bust group-stop */
+				goto cont;
+			}
+
+			ksft_print_msg("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) {
+				ASSERT_NE(errno, ESRCH);
+				return;
+			}
+
+			ksft_print_msg("PTRACE_CONT: %s\n", strerror(errno));
+			goto error;
+		}
+	}
+
+	/* Where is the child GCS? */
+	iov.iov_base = &child_gcs;
+	iov.iov_len = sizeof(child_gcs);
+	ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_GCS, &iov);
+	if (ret != 0) {
+		ksft_print_msg("Failed to read child GCS state: %s (%d)\n",
+			       strerror(errno), errno);
+		goto error;
+	}
+
+	/* We should have inherited GCS over fork(), confirm */
+	if (!(child_gcs.features_enabled & PR_SHADOW_STACK_ENABLE)) {
+		ASSERT_TRUE(child_gcs.features_enabled &
+			    PR_SHADOW_STACK_ENABLE);
+		goto error;
+	}
+
+	gcspr = child_gcs.gcspr_el0;
+	ksft_print_msg("Child GCSPR 0x%lx, flags %x, locked %x\n",
+		       gcspr, child_gcs.features_enabled,
+		       child_gcs.features_locked);
+
+	/* Ideally we'd cross check with the child memory map */
+
+	errno = 0;
+	val = ptrace(PTRACE_PEEKDATA, child, (void *)gcspr, NULL);
+	ret = errno;
+	if (ret != 0)
+		ksft_print_msg("PTRACE_PEEKDATA failed: %s (%d)\n",
+			       strerror(ret), ret);
+	EXPECT_EQ(ret, 0);
+
+	/* The child should be in a function, the GCSPR shouldn't be 0 */
+	EXPECT_NE(val, 0);
+
+	/* Same thing via process_vm_readv() */
+	local_iov.iov_base = &rval;
+	local_iov.iov_len = sizeof(rval);
+	remote_iov.iov_base = (void *)gcspr;
+	remote_iov.iov_len = sizeof(rval);
+	ret = process_vm_readv(child, &local_iov, 1, &remote_iov, 1, 0);
+	if (ret == -1)
+		ksft_print_msg("process_vm_readv() failed: %s (%d)\n",
+			       strerror(errno), errno);
+	EXPECT_EQ(ret, sizeof(rval));
+	EXPECT_EQ(val, rval);
+
+	/* Write data via a peek */
+	ret = ptrace(PTRACE_POKEDATA, child, (void *)gcspr, NULL);
+	if (ret == -1)
+		ksft_print_msg("PTRACE_POKEDATA failed: %s (%d)\n",
+			       strerror(errno), errno);
+	EXPECT_EQ(ret, 0);
+	EXPECT_EQ(0, ptrace(PTRACE_PEEKDATA, child, (void *)gcspr, NULL));
+
+	/* Restore what we had before */
+	ret = ptrace(PTRACE_POKEDATA, child, (void *)gcspr, val);
+	if (ret == -1)
+		ksft_print_msg("PTRACE_POKEDATA failed: %s (%d)\n",
+			       strerror(errno), errno);
+	EXPECT_EQ(ret, 0);
+	EXPECT_EQ(val, ptrace(PTRACE_PEEKDATA, child, (void *)gcspr, NULL));
+
+	/* That's all, folks */
+	kill(child, SIGKILL);
+	return;
+
+error:
+	kill(child, SIGKILL);
+	ASSERT_FALSE(true);
+}
+
+FIXTURE(map_gcs)
+{
+	unsigned long *stack;
+};
+
+FIXTURE_VARIANT(map_gcs)
+{
+	size_t stack_size;
+	unsigned long flags;
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s2k_cap_marker)
+{
+	.stack_size = 2 * 1024,
+	.flags = SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s2k_cap)
+{
+	.stack_size = 2 * 1024,
+	.flags = SHADOW_STACK_SET_TOKEN,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s2k_marker)
+{
+	.stack_size = 2 * 1024,
+	.flags = SHADOW_STACK_SET_MARKER,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s2k)
+{
+	.stack_size = 2 * 1024,
+	.flags = 0,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s4k_cap_marker)
+{
+	.stack_size = 4 * 1024,
+	.flags = SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s4k_cap)
+{
+	.stack_size = 4 * 1024,
+	.flags = SHADOW_STACK_SET_TOKEN,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s3k_marker)
+{
+	.stack_size = 4 * 1024,
+	.flags = SHADOW_STACK_SET_MARKER,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s4k)
+{
+	.stack_size = 4 * 1024,
+	.flags = 0,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s16k_cap_marker)
+{
+	.stack_size = 16 * 1024,
+	.flags = SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s16k_cap)
+{
+	.stack_size = 16 * 1024,
+	.flags = SHADOW_STACK_SET_TOKEN,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s16k_marker)
+{
+	.stack_size = 16 * 1024,
+	.flags = SHADOW_STACK_SET_MARKER,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s16k)
+{
+	.stack_size = 16 * 1024,
+	.flags = 0,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s64k_cap_marker)
+{
+	.stack_size = 64 * 1024,
+	.flags = SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s64k_cap)
+{
+	.stack_size = 64 * 1024,
+	.flags = SHADOW_STACK_SET_TOKEN,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s64k_marker)
+{
+	.stack_size = 64 * 1024,
+	.flags = SHADOW_STACK_SET_MARKER,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s64k)
+{
+	.stack_size = 64 * 1024,
+	.flags = 0,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s128k_cap_marker)
+{
+	.stack_size = 128 * 1024,
+	.flags = SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s128k_cap)
+{
+	.stack_size = 128 * 1024,
+	.flags = SHADOW_STACK_SET_TOKEN,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s128k_marker)
+{
+	.stack_size = 128 * 1024,
+	.flags = SHADOW_STACK_SET_MARKER,
+};
+
+FIXTURE_VARIANT_ADD(map_gcs, s128k)
+{
+	.stack_size = 128 * 1024,
+	.flags = 0,
+};
+
+FIXTURE_SETUP(map_gcs)
+{
+	self->stack = (void *)syscall(__NR_map_shadow_stack, 0,
+				      variant->stack_size, 
+				      variant->flags);
+	ASSERT_FALSE(self->stack == MAP_FAILED);
+	ksft_print_msg("Allocated stack from %p-%p\n", self->stack,
+		       (unsigned long)self->stack + variant->stack_size);
+}
+
+FIXTURE_TEARDOWN(map_gcs)
+{
+	int ret;
+
+	if (self->stack != MAP_FAILED) {
+		ret = munmap(self->stack, variant->stack_size);
+		ASSERT_EQ(ret, 0);
+	}
+}
+
+/* The stack has a cap token */
+TEST_F(map_gcs, stack_capped)
+{
+	unsigned long *stack = self->stack;
+	size_t cap_index;
+
+	cap_index = (variant->stack_size / sizeof(unsigned long));
+
+	switch (variant->flags & (SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN)) {
+	case SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN:
+		cap_index -= 2;
+		break;
+	case SHADOW_STACK_SET_TOKEN:
+		cap_index -= 1;
+		break;
+	case SHADOW_STACK_SET_MARKER:
+	case 0:
+		/* No cap, no test */
+		return;
+	}
+
+	ASSERT_EQ(stack[cap_index], GCS_CAP(&stack[cap_index]));
+}
+
+/* The top of the stack is 0 */
+TEST_F(map_gcs, stack_terminated)
+{
+	unsigned long *stack = self->stack;
+	size_t term_index;
+
+	if (!(variant->flags & SHADOW_STACK_SET_MARKER))
+		return;
+
+	term_index = (variant->stack_size / sizeof(unsigned long)) - 1;
+
+	ASSERT_EQ(stack[term_index], 0);
+}
+
+/* Writes should fault */
+TEST_F_SIGNAL(map_gcs, not_writeable, SIGSEGV)
+{
+	self->stack[0] = 0;
+}
+
+/* Put it all together, we can safely switch to and from the stack */
+TEST_F(map_gcs, stack_switch)
+{
+	size_t cap_index;
+	cap_index = (variant->stack_size / sizeof(unsigned long));
+	unsigned long *orig_gcspr_el0, *pivot_gcspr_el0;
+
+	/* Skip over the stack terminator and point at the cap */
+	switch (variant->flags & (SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN)) {
+	case SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN:
+		cap_index -= 2;
+		break;
+	case SHADOW_STACK_SET_TOKEN:
+		cap_index -= 1;
+		break;
+	case SHADOW_STACK_SET_MARKER:
+	case 0:
+		/* No cap, no test */
+		return;
+	}
+	pivot_gcspr_el0 = &self->stack[cap_index];
+
+	/* Pivot to the new GCS */
+	ksft_print_msg("Pivoting to %p from %p, target has value 0x%lx\n",
+		       pivot_gcspr_el0, get_gcspr(),
+		       *pivot_gcspr_el0);
+	gcsss1(pivot_gcspr_el0);
+	orig_gcspr_el0 = gcsss2();
+	ksft_print_msg("Pivoted to %p from %p, target has value 0x%lx\n",
+		       get_gcspr(), orig_gcspr_el0,
+		       *pivot_gcspr_el0);
+
+	ksft_print_msg("Pivoted, GCSPR_EL0 now %p\n", get_gcspr());
+
+	/* New GCS must be in the new buffer */
+	ASSERT_TRUE((unsigned long)get_gcspr() > (unsigned long)self->stack);
+	ASSERT_TRUE((unsigned long)get_gcspr() <=
+		    (unsigned long)self->stack + variant->stack_size);
+
+	/* We should be able to use all but 2 slots of the new stack */
+	ksft_print_msg("Recursing %d levels\n", cap_index - 1);
+	gcs_recurse(cap_index - 1);
+
+	/* Pivot back to the original GCS */
+	gcsss1(orig_gcspr_el0);
+	pivot_gcspr_el0 = gcsss2();
+
+	gcs_recurse(0);
+	ksft_print_msg("Pivoted back to GCSPR_EL0 0x%lx\n", get_gcspr());
+}
+
+/* We fault if we try to go beyond the end of the stack */
+TEST_F_SIGNAL(map_gcs, stack_overflow, SIGSEGV)
+{
+	size_t cap_index;
+	cap_index = (variant->stack_size / sizeof(unsigned long));
+	unsigned long *orig_gcspr_el0, *pivot_gcspr_el0;
+
+	/* Skip over the stack terminator and point at the cap */
+	switch (variant->flags & (SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN)) {
+	case SHADOW_STACK_SET_MARKER | SHADOW_STACK_SET_TOKEN:
+		cap_index -= 2;
+		break;
+	case SHADOW_STACK_SET_TOKEN:
+		cap_index -= 1;
+		break;
+	case SHADOW_STACK_SET_MARKER:
+	case 0:
+		/* No cap, no test but we need to SEGV to avoid a false fail */
+		orig_gcspr_el0 = get_gcspr();
+		*orig_gcspr_el0 = 0;
+		return;
+	}
+	pivot_gcspr_el0 = &self->stack[cap_index];
+
+	/* Pivot to the new GCS */
+	ksft_print_msg("Pivoting to %p from %p, target has value 0x%lx\n",
+		       pivot_gcspr_el0, get_gcspr(),
+		       *pivot_gcspr_el0);
+	gcsss1(pivot_gcspr_el0);
+	orig_gcspr_el0 = gcsss2();
+	ksft_print_msg("Pivoted to %p from %p, target has value 0x%lx\n",
+		       pivot_gcspr_el0, orig_gcspr_el0,
+		       *pivot_gcspr_el0);
+
+	ksft_print_msg("Pivoted, GCSPR_EL0 now %p\n", get_gcspr());
+
+	/* New GCS must be in the new buffer */
+	ASSERT_TRUE((unsigned long)get_gcspr() > (unsigned long)self->stack);
+	ASSERT_TRUE((unsigned long)get_gcspr() <=
+		    (unsigned long)self->stack + variant->stack_size);
+
+	/* Now try to recurse, we should fault doing this. */
+	ksft_print_msg("Recursing %d levels...\n", cap_index + 1);
+	gcs_recurse(cap_index + 1);
+	ksft_print_msg("...done\n");
+
+	/* Clean up properly to try to guard against spurious passes. */
+	gcsss1(orig_gcspr_el0);
+	pivot_gcspr_el0 = gcsss2();
+	ksft_print_msg("Pivoted back to GCSPR_EL0 0x%lx\n", get_gcspr());
+}
+
+FIXTURE(map_invalid_gcs)
+{
+};
+
+FIXTURE_VARIANT(map_invalid_gcs)
+{
+	size_t stack_size;
+};
+
+FIXTURE_SETUP(map_invalid_gcs)
+{
+}
+
+FIXTURE_TEARDOWN(map_invalid_gcs)
+{
+}
+
+/* GCS must be larger than 16 bytes */
+FIXTURE_VARIANT_ADD(map_invalid_gcs, too_small)
+{
+	.stack_size = 8,
+};
+
+/* GCS size must be 16 byte aligned */
+FIXTURE_VARIANT_ADD(map_invalid_gcs, unligned_1)  { .stack_size = 1024 + 1  };
+FIXTURE_VARIANT_ADD(map_invalid_gcs, unligned_2)  { .stack_size = 1024 + 2  };
+FIXTURE_VARIANT_ADD(map_invalid_gcs, unligned_3)  { .stack_size = 1024 + 3  };
+FIXTURE_VARIANT_ADD(map_invalid_gcs, unligned_4)  { .stack_size = 1024 + 4  };
+FIXTURE_VARIANT_ADD(map_invalid_gcs, unligned_5)  { .stack_size = 1024 + 5  };
+FIXTURE_VARIANT_ADD(map_invalid_gcs, unligned_6)  { .stack_size = 1024 + 6  };
+FIXTURE_VARIANT_ADD(map_invalid_gcs, unligned_7)  { .stack_size = 1024 + 7  };
+
+TEST_F(map_invalid_gcs, do_map)
+{
+	void *stack;
+
+	stack = (void *)syscall(__NR_map_shadow_stack, 0,
+				variant->stack_size, 0);
+	ASSERT_TRUE(stack == MAP_FAILED);
+	if (stack != MAP_FAILED)
+		munmap(stack, variant->stack_size);
+}
+
+FIXTURE(invalid_mprotect)
+{
+	unsigned long *stack;
+	size_t stack_size;
+};
+
+FIXTURE_VARIANT(invalid_mprotect)
+{
+	unsigned long flags;
+};
+
+FIXTURE_SETUP(invalid_mprotect)
+{
+	self->stack_size = sysconf(_SC_PAGE_SIZE);
+	self->stack = (void *)syscall(__NR_map_shadow_stack, 0,
+				      self->stack_size, 0);
+	ASSERT_FALSE(self->stack == MAP_FAILED);
+	ksft_print_msg("Allocated stack from %p-%p\n", self->stack,
+		       (unsigned long)self->stack + self->stack_size);
+}
+
+FIXTURE_TEARDOWN(invalid_mprotect)
+{
+	int ret;
+
+	if (self->stack != MAP_FAILED) {
+		ret = munmap(self->stack, self->stack_size);
+		ASSERT_EQ(ret, 0);
+	}
+}
+
+FIXTURE_VARIANT_ADD(invalid_mprotect, exec)
+{
+	.flags = PROT_EXEC,
+};
+
+FIXTURE_VARIANT_ADD(invalid_mprotect, bti)
+{
+	.flags = PROT_BTI,
+};
+
+FIXTURE_VARIANT_ADD(invalid_mprotect, exec_bti)
+{
+	.flags = PROT_EXEC | PROT_BTI,
+};
+
+TEST_F(invalid_mprotect, do_map)
+{
+	int ret;
+
+	ret = mprotect(self->stack, self->stack_size, variant->flags);
+	ASSERT_EQ(ret, -1);
+}
+
+TEST_F(invalid_mprotect, do_map_read)
+{
+	int ret;
+
+	ret = mprotect(self->stack, self->stack_size,
+		       variant->flags | PROT_READ);
+	ASSERT_EQ(ret, -1);
+}
+
+int main(int argc, char **argv)
+{
+	unsigned long gcs_mode;
+	int ret;
+
+	if (!(getauxval(AT_HWCAP2) & HWCAP2_GCS))
+		ksft_exit_skip("SKIP GCS not supported\n");
+
+	/* 
+	 * Force shadow stacks on, our tests *should* be fine with or
+	 * without libc support and with or without this having ended
+	 * up tagged for GCS and enabled by the dynamic linker.  We
+	 * can't use the libc prctl() function since we can't return
+	 * from enabling the stack.
+	 */
+	ret = my_syscall2(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, &gcs_mode);
+	if (ret) {
+		ksft_print_msg("Failed to read GCS state: %d\n", ret);
+		return EXIT_FAILURE;
+	}
+	
+	if (!(gcs_mode & PR_SHADOW_STACK_ENABLE)) {
+		gcs_mode = PR_SHADOW_STACK_ENABLE;
+		ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS,
+				  gcs_mode);
+		if (ret) {
+			ksft_print_msg("Failed to configure GCS: %d\n", ret);
+			return EXIT_FAILURE;
+		}
+	}
+
+	/* Avoid returning in case libc doesn't understand GCS */
+	exit(test_harness_run(argc, argv));
+}

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:26:03 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:26:03 +0000
Subject: [PATCH v8 37/38] kselftest/arm64: Enable GCS for the FP stress
 tests
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-37-c9fec77673ef@kernel.org>

While it's a bit off topic for them the floating point stress tests do give
us some coverage of context thrashing cases, and also of active signal
delivery separate to the relatively complicated framework in the actual
signals tests. Have the tests enable GCS on startup, ignoring failures so
they continue to work as before on systems without GCS.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/assembler.h   | 15 +++++++++++++++
 tools/testing/selftests/arm64/fp/fpsimd-test.S |  2 ++
 tools/testing/selftests/arm64/fp/sve-test.S    |  2 ++
 tools/testing/selftests/arm64/fp/za-test.S     |  2 ++
 tools/testing/selftests/arm64/fp/zt-test.S     |  2 ++
 5 files changed, 23 insertions(+)

diff --git a/tools/testing/selftests/arm64/fp/assembler.h b/tools/testing/selftests/arm64/fp/assembler.h
index 9b38a0da407d..7012f9f796de 100644
--- a/tools/testing/selftests/arm64/fp/assembler.h
+++ b/tools/testing/selftests/arm64/fp/assembler.h
@@ -65,4 +65,19 @@ endfunction
 	bl	puts
 .endm
 
+#define PR_SET_SHADOW_STACK_STATUS      72
+# define PR_SHADOW_STACK_ENABLE         (1UL << 0)
+
+.macro enable_gcs
+	// Run with GCS
+	mov	x0, PR_SET_SHADOW_STACK_STATUS
+	mov	x1, PR_SHADOW_STACK_ENABLE
+	mov	x2, xzr
+	mov	x3, xzr
+	mov	x4, xzr
+	mov	x5, xzr
+	mov	x8, #__NR_prctl
+	svc	#0
+.endm
+
 #endif /* ! ASSEMBLER_H */
diff --git a/tools/testing/selftests/arm64/fp/fpsimd-test.S b/tools/testing/selftests/arm64/fp/fpsimd-test.S
index 8b960d01ed2e..b16fb7f42e3e 100644
--- a/tools/testing/selftests/arm64/fp/fpsimd-test.S
+++ b/tools/testing/selftests/arm64/fp/fpsimd-test.S
@@ -215,6 +215,8 @@ endfunction
 // Main program entry point
 .globl _start
 function _start
+	enable_gcs
+
 	mov	x23, #0		// signal count
 
 	mov	w0, #SIGINT
diff --git a/tools/testing/selftests/arm64/fp/sve-test.S b/tools/testing/selftests/arm64/fp/sve-test.S
index fff60e2a25ad..2fb4f0b84476 100644
--- a/tools/testing/selftests/arm64/fp/sve-test.S
+++ b/tools/testing/selftests/arm64/fp/sve-test.S
@@ -378,6 +378,8 @@ endfunction
 // Main program entry point
 .globl _start
 function _start
+	enable_gcs
+
 	mov	x23, #0		// Irritation signal count
 
 	mov	w0, #SIGINT
diff --git a/tools/testing/selftests/arm64/fp/za-test.S b/tools/testing/selftests/arm64/fp/za-test.S
index 095b45531640..b2603aba99de 100644
--- a/tools/testing/selftests/arm64/fp/za-test.S
+++ b/tools/testing/selftests/arm64/fp/za-test.S
@@ -231,6 +231,8 @@ endfunction
 // Main program entry point
 .globl _start
 function _start
+	enable_gcs
+
 	mov	x23, #0		// signal count
 
 	mov	w0, #SIGINT
diff --git a/tools/testing/selftests/arm64/fp/zt-test.S b/tools/testing/selftests/arm64/fp/zt-test.S
index b5c81e81a379..8d9609a49008 100644
--- a/tools/testing/selftests/arm64/fp/zt-test.S
+++ b/tools/testing/selftests/arm64/fp/zt-test.S
@@ -200,6 +200,8 @@ endfunction
 // Main program entry point
 .globl _start
 function _start
+	enable_gcs
+
 	mov	x23, #0		// signal count
 
 	mov	w0, #SIGINT

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:26:00 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:26:00 +0000
Subject: [PATCH v8 34/38] kselftest/arm64: Add test coverage for GCS mode
 locking
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-34-c9fec77673ef@kernel.org>

Verify that we can lock individual GCS mode bits, that other modes
aren't affected and as a side effect also that every combination of
modes can be enabled.

Normally the inability to reenable GCS after disabling it would be an
issue with testing but fortunately the kselftest_harness runs each test
within a fork()ed child.  This can be inconvenient for some kinds of
testing but here it means that each test is in a separate thread and
therefore won't be affected by other tests in the suite.

Once we get toolchains with support for enabling GCS by default we will
need to take care to not do that in the build system but there are no
such toolchains yet so it is not yet an issue.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/gcs/.gitignore    |   1 +
 tools/testing/selftests/arm64/gcs/Makefile      |   2 +-
 tools/testing/selftests/arm64/gcs/gcs-locking.c | 200 ++++++++++++++++++++++++
 3 files changed, 202 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/gcs/.gitignore b/tools/testing/selftests/arm64/gcs/.gitignore
index 5810c4a163d4..0c86f53f68ad 100644
--- a/tools/testing/selftests/arm64/gcs/.gitignore
+++ b/tools/testing/selftests/arm64/gcs/.gitignore
@@ -1,2 +1,3 @@
 basic-gcs
 libc-gcs
+gcs-locking
diff --git a/tools/testing/selftests/arm64/gcs/Makefile b/tools/testing/selftests/arm64/gcs/Makefile
index a8fdf21e9a47..2173d6275956 100644
--- a/tools/testing/selftests/arm64/gcs/Makefile
+++ b/tools/testing/selftests/arm64/gcs/Makefile
@@ -6,7 +6,7 @@
 # nolibc.
 #
 
-TEST_GEN_PROGS := basic-gcs libc-gcs
+TEST_GEN_PROGS := basic-gcs libc-gcs gcs-locking
 
 LDLIBS+=-lpthread
 
diff --git a/tools/testing/selftests/arm64/gcs/gcs-locking.c b/tools/testing/selftests/arm64/gcs/gcs-locking.c
new file mode 100644
index 000000000000..f6a73254317e
--- /dev/null
+++ b/tools/testing/selftests/arm64/gcs/gcs-locking.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 ARM Limited.
+ *
+ * Tests for GCS mode locking.  These tests rely on both having GCS
+ * unconfigured on entry and on the kselftest harness running each
+ * test in a fork()ed process which will have it's own mode.
+ */
+
+#include <limits.h>
+
+#include <sys/auxv.h>
+#include <sys/prctl.h>
+
+#include <asm/hwcap.h>
+
+#include "kselftest_harness.h"
+
+#include "gcs-util.h"
+
+#define my_syscall2(num, arg1, arg2)                                          \
+({                                                                            \
+	register long _num  __asm__ ("x8") = (num);                           \
+	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
+	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
+	register long _arg3 __asm__ ("x2") = 0;                               \
+	register long _arg4 __asm__ ("x3") = 0;                               \
+	register long _arg5 __asm__ ("x4") = 0;                               \
+	                                                                      \
+	__asm__  volatile (                                                   \
+		"svc #0\n"                                                    \
+		: "=r"(_arg1)                                                 \
+		: "r"(_arg1), "r"(_arg2),                                     \
+		  "r"(_arg3), "r"(_arg4),                                     \
+		  "r"(_arg5), "r"(_num)					      \
+		: "memory", "cc"                                              \
+	);                                                                    \
+	_arg1;                                                                \
+})
+
+/* No mode bits are rejected for locking */
+TEST(lock_all_modes)
+{
+	int ret;
+
+	ret = prctl(PR_LOCK_SHADOW_STACK_STATUS, ULONG_MAX, 0, 0, 0);
+	ASSERT_EQ(ret, 0);
+}
+
+FIXTURE(valid_modes)
+{
+};
+
+FIXTURE_VARIANT(valid_modes)
+{
+	unsigned long mode;
+};
+
+FIXTURE_VARIANT_ADD(valid_modes, enable)
+{
+	.mode = PR_SHADOW_STACK_ENABLE,
+};
+
+FIXTURE_VARIANT_ADD(valid_modes, enable_write)
+{
+	.mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE,
+};
+
+FIXTURE_VARIANT_ADD(valid_modes, enable_push)
+{
+	.mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_PUSH,
+};
+
+FIXTURE_VARIANT_ADD(valid_modes, enable_write_push)
+{
+	.mode = PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE |
+		PR_SHADOW_STACK_PUSH,
+};
+
+FIXTURE_SETUP(valid_modes)
+{
+}
+
+FIXTURE_TEARDOWN(valid_modes)
+{
+}
+
+/* We can set the mode at all */
+TEST_F(valid_modes, set)
+{
+	int ret;
+
+	ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS,
+			  variant->mode);
+	ASSERT_EQ(ret, 0);
+
+	_exit(0);
+}
+
+/* Enabling, locking then disabling is rejected */
+TEST_F(valid_modes, enable_lock_disable)
+{
+	unsigned long mode;
+	int ret;
+
+	ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS,
+			  variant->mode);
+	ASSERT_EQ(ret, 0);
+
+	ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0);
+	ASSERT_EQ(ret, 0);
+	ASSERT_EQ(mode, variant->mode);
+
+	ret = prctl(PR_LOCK_SHADOW_STACK_STATUS, variant->mode, 0, 0, 0);
+	ASSERT_EQ(ret, 0);
+
+	ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, 0);
+	ASSERT_EQ(ret, -EBUSY);
+
+	_exit(0);
+}
+
+/* Locking then enabling is rejected */
+TEST_F(valid_modes, lock_enable)
+{
+	unsigned long mode;
+	int ret;
+
+	ret = prctl(PR_LOCK_SHADOW_STACK_STATUS, variant->mode, 0, 0, 0);
+	ASSERT_EQ(ret, 0);
+
+	ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS,
+			  variant->mode);
+	ASSERT_EQ(ret, -EBUSY);
+
+	ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0);
+	ASSERT_EQ(ret, 0);
+	ASSERT_EQ(mode, 0);
+
+	_exit(0);
+}
+
+/* Locking then changing other modes is fine */
+TEST_F(valid_modes, lock_enable_disable_others)
+{
+	unsigned long mode;
+	int ret;
+
+	ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS,
+			  variant->mode);
+	ASSERT_EQ(ret, 0);
+
+	ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0);
+	ASSERT_EQ(ret, 0);
+	ASSERT_EQ(mode, variant->mode);
+
+	ret = prctl(PR_LOCK_SHADOW_STACK_STATUS, variant->mode, 0, 0, 0);
+	ASSERT_EQ(ret, 0);
+
+	ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS,
+			  PR_SHADOW_STACK_ALL_MODES);
+	ASSERT_EQ(ret, 0);
+
+	ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0);
+	ASSERT_EQ(ret, 0);
+	ASSERT_EQ(mode, PR_SHADOW_STACK_ALL_MODES);
+
+
+	ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS,
+			  variant->mode);
+	ASSERT_EQ(ret, 0);
+
+	ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0);
+	ASSERT_EQ(ret, 0);
+	ASSERT_EQ(mode, variant->mode);
+
+	_exit(0);
+}
+
+int main(int argc, char **argv)
+{
+	unsigned long mode;
+	int ret;
+
+	if (!(getauxval(AT_HWCAP2) & HWCAP2_GCS))
+		ksft_exit_skip("SKIP GCS not supported\n");
+
+	ret = prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0);
+	if (ret) {
+		ksft_print_msg("Failed to read GCS state: %d\n", ret);
+		return EXIT_FAILURE;
+	}
+
+	if (mode & PR_SHADOW_STACK_ENABLE) {
+		ksft_print_msg("GCS was enabled, test unsupported\n");
+		return KSFT_SKIP;
+	}
+
+	return test_harness_run(argc, argv);
+}

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:26:01 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:26:01 +0000
Subject: [PATCH v8 35/38] selftests/arm64: Add GCS signal tests
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-35-c9fec77673ef@kernel.org>

Do some testing of the signal handling for GCS, checking that a GCS
frame has the expected information in it and that the expected signals
are delivered with invalid operations.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/signal/.gitignore    |  1 +
 .../selftests/arm64/signal/test_signals_utils.h    | 10 +++
 .../arm64/signal/testcases/gcs_exception_fault.c   | 62 +++++++++++++++
 .../selftests/arm64/signal/testcases/gcs_frame.c   | 88 ++++++++++++++++++++++
 .../arm64/signal/testcases/gcs_write_fault.c       | 67 ++++++++++++++++
 5 files changed, 228 insertions(+)

diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
index 839e3a252629..26de12918890 100644
--- a/tools/testing/selftests/arm64/signal/.gitignore
+++ b/tools/testing/selftests/arm64/signal/.gitignore
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 mangle_*
 fake_sigreturn_*
+gcs_*
 sme_*
 ssve_*
 sve_*
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
index 1e80808ee105..36fc12b3cd60 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.h
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <linux/compiler.h>
@@ -47,6 +48,15 @@ void test_result(struct tdescr *td);
 		_arg1;							\
 	})
 
+static inline __attribute__((always_inline)) uint64_t get_gcspr_el0(void)
+{
+	uint64_t val;
+
+	asm volatile("mrs %0, S3_3_C2_C5_1" : "=r" (val));
+
+	return val;
+}
+
 static inline bool feats_ok(struct tdescr *td)
 {
 	if (td->feats_incompatible & td->feats_supported)
diff --git a/tools/testing/selftests/arm64/signal/testcases/gcs_exception_fault.c b/tools/testing/selftests/arm64/signal/testcases/gcs_exception_fault.c
new file mode 100644
index 000000000000..6228448b2ae7
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/gcs_exception_fault.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 ARM Limited
+ */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+/*
+ * We should get this from asm/siginfo.h but the testsuite is being
+ * clever with redefining siginfo_t.
+ */
+#ifndef SEGV_CPERR
+#define SEGV_CPERR 10
+#endif
+
+static inline void gcsss1(uint64_t Xt)
+{
+	asm volatile (
+		"sys #3, C7, C7, #2, %0\n"
+		:
+		: "rZ" (Xt)
+		: "memory");
+}
+
+static int gcs_op_fault_trigger(struct tdescr *td)
+{
+	/*
+	 * The slot below our current GCS should be in a valid GCS but
+	 * must not have a valid cap in it.
+	 */
+	gcsss1(get_gcspr_el0() - 8);
+
+	return 0;
+}
+
+static int gcs_op_fault_signal(struct tdescr *td, siginfo_t *si,
+				  ucontext_t *uc)
+{
+	ASSERT_GOOD_CONTEXT(uc);
+
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "Invalid GCS operation",
+	.descr = "An invalid GCS operation generates the expected signal",
+	.feats_required = FEAT_GCS,
+	.timeout = 3,
+	.sig_ok = SIGSEGV,
+	.sig_ok_code = SEGV_CPERR,
+	.sanity_disabled = true,
+	.trigger = gcs_op_fault_trigger,
+	.run = gcs_op_fault_signal,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/gcs_frame.c b/tools/testing/selftests/arm64/signal/testcases/gcs_frame.c
new file mode 100644
index 000000000000..b405d82321da
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/gcs_frame.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 ARM Limited
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+static union {
+	ucontext_t uc;
+	char buf[1024 * 64];
+} context;
+
+static int gcs_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	size_t offset;
+	struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context);
+	struct gcs_context *gcs;
+	unsigned long expected, gcspr;
+	uint64_t *u64_val;
+	int ret;
+
+	ret = prctl(PR_GET_SHADOW_STACK_STATUS, &expected, 0, 0, 0);
+	if (ret != 0) {
+		fprintf(stderr, "Unable to query GCS status\n");
+		return 1;
+	}
+
+	/* We expect a cap to be added to the GCS in the signal frame */
+	gcspr = get_gcspr_el0();
+	gcspr -= 8;
+	fprintf(stderr, "Expecting GCSPR_EL0 %lx\n", gcspr);
+
+	if (!get_current_context(td, &context.uc, sizeof(context))) {
+		fprintf(stderr, "Failed getting context\n");
+		return 1;
+	}
+
+	/* Ensure that the signal restore token was consumed */
+	u64_val = (uint64_t *)get_gcspr_el0() + 1;
+	if (*u64_val) {
+		fprintf(stderr, "GCS value at %p is %lx not 0\n",
+			u64_val, *u64_val);
+		return 1;
+	}
+
+	fprintf(stderr, "Got context\n");
+
+	head = get_header(head, GCS_MAGIC, GET_BUF_RESV_SIZE(context),
+			  &offset);
+	if (!head) {
+		fprintf(stderr, "No GCS context\n");
+		return 1;
+	}
+
+	gcs = (struct gcs_context *)head;
+
+	/* Basic size validation is done in get_current_context() */
+
+	if (gcs->features_enabled != expected) {
+		fprintf(stderr, "Features enabled %llx but expected %lx\n",
+			gcs->features_enabled, expected);
+		return 1;
+	}
+
+	if (gcs->gcspr != gcspr) {
+		fprintf(stderr, "Got GCSPR %llx but expected %lx\n",
+			gcs->gcspr, gcspr);
+		return 1;
+	}
+
+	fprintf(stderr, "GCS context validated\n");
+	td->pass = 1;
+
+	return 0;
+}
+
+struct tdescr tde = {
+	.name = "GCS basics",
+	.descr = "Validate a GCS signal context",
+	.feats_required = FEAT_GCS,
+	.timeout = 3,
+	.run = gcs_regs,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c b/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c
new file mode 100644
index 000000000000..faeabb18c4b2
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 ARM Limited
+ */
+
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+static uint64_t *gcs_page;
+
+#ifndef __NR_map_shadow_stack
+#define __NR_map_shadow_stack 453
+#endif
+
+static bool alloc_gcs(struct tdescr *td)
+{
+	long page_size = sysconf(_SC_PAGE_SIZE);
+
+	gcs_page = (void *)syscall(__NR_map_shadow_stack, 0,
+				   page_size, 0);
+	if (gcs_page == MAP_FAILED) {
+		fprintf(stderr, "Failed to map %ld byte GCS: %d\n",
+			page_size, errno);
+		return false;
+	}
+
+	return true;
+}
+
+static int gcs_write_fault_trigger(struct tdescr *td)
+{
+	/* Verify that the page is readable (ie, not completely unmapped) */
+	fprintf(stderr, "Read value 0x%lx\n", gcs_page[0]);
+
+	/* A regular write should trigger a fault */
+	gcs_page[0] = EINVAL;
+
+	return 0;
+}
+
+static int gcs_write_fault_signal(struct tdescr *td, siginfo_t *si,
+				  ucontext_t *uc)
+{
+	ASSERT_GOOD_CONTEXT(uc);
+
+	return 1;
+}
+
+
+struct tdescr tde = {
+	.name = "GCS write fault",
+	.descr = "Normal writes to a GCS segfault",
+	.feats_required = FEAT_GCS,
+	.timeout = 3,
+	.sig_ok = SIGSEGV,
+	.sanity_disabled = true,
+	.init = alloc_gcs,
+	.trigger = gcs_write_fault_trigger,
+	.run = gcs_write_fault_signal,
+};

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 04:26:04 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 12:26:04 +0000
Subject: [PATCH v8 38/38] kselftest: Provide shadow stack enable helpers
 for arm64
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <20240203-arm64-gcs-v8-38-c9fec77673ef@kernel.org>

Allow test programs to use the shadow stack helpers on arm64.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/ksft_shstk.h | 37 ++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/tools/testing/selftests/ksft_shstk.h b/tools/testing/selftests/ksft_shstk.h
index 85d0747c1802..223e24b4eb80 100644
--- a/tools/testing/selftests/ksft_shstk.h
+++ b/tools/testing/selftests/ksft_shstk.h
@@ -50,6 +50,43 @@ static inline __attribute__((always_inline)) void enable_shadow_stack(void)
 
 #endif
 
+#ifdef __aarch64__
+#define PR_SET_SHADOW_STACK_STATUS      72
+# define PR_SHADOW_STACK_ENABLE         (1UL << 0)
+
+#define my_syscall2(num, arg1, arg2)                                          \
+({                                                                            \
+	register long _num  __asm__ ("x8") = (num);                           \
+	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
+	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
+	register long _arg3 __asm__ ("x2") = 0;                               \
+	register long _arg4 __asm__ ("x3") = 0;                               \
+	register long _arg5 __asm__ ("x4") = 0;                               \
+	                                                                      \
+	__asm__  volatile (                                                   \
+		"svc #0\n"                                                    \
+		: "=r"(_arg1)                                                 \
+		: "r"(_arg1), "r"(_arg2),                                     \
+		  "r"(_arg3), "r"(_arg4),                                     \
+		  "r"(_arg5), "r"(_num)					      \
+		: "memory", "cc"                                              \
+	);                                                                    \
+	_arg1;                                                                \
+})
+
+#define ENABLE_SHADOW_STACK
+static inline __attribute__((always_inline))  void enable_shadow_stack(void)
+{
+	int ret;
+
+	ret = my_syscall2(__NR_prctl, PR_SET_SHADOW_STACK_STATUS,
+			  PR_SHADOW_STACK_ENABLE);
+	if (ret == 0)
+		shadow_stack_enabled = true;
+}
+
+#endif
+
 #ifndef __NR_map_shadow_stack
 #define __NR_map_shadow_stack 453
 #endif

-- 
2.30.2



From jszhang at kernel.org  Sat Feb  3 04:24:59 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sat,  3 Feb 2024 20:24:59 +0800
Subject: [PATCH v2 0/2] arm64: dts: allwinner: h618: Add Sipeed Longan SoM 3H and Pi 3H board
Message-ID: <20240203122502.1259-1-jszhang@kernel.org>

Add Sipeed Longan SoM 3H and Longan Pi 3H board support.

The Sipeed Longan SoM 3H is a system on module based on the Allwinner
H618 SoC. The SoM features:

- Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
- 2/4 GiB LPDDR4 DRAM SoMs
- AXP313a PMIC
- eMMC

The Sipeed Longan PI 3H is a development board based on the above SoM.
The board features:
- Longan SoM 3H
- Raspberry-Pi-1 compatible GPIO header
- 2 USB 2.0 host port
- 1 USB 2.0 type C port (power supply + OTG)
- MicroSD slot
- 1Gbps Ethernet port (via RTL8211 PHY)
- HDMI port
- WiFi/BT chip

Since v1:
  - Use const rather than enum for "sipeed,longan-pi-3h" dt-binding
  - remove dts-v1, model and compatible from SoM dtsi
  - add interrupt related properties to axp313 dt node
  - use "vcc-1v8-pll" and "vcc-3v3-io" as regulator name
  - add dt node for board's discrete 5V->3.3V regulator and use it for
    eth\tfcard 3.3v supply
  - add usb2_vbus-supply property

Jisheng Zhang (2):
  dt-bindings: arm: sunxi: Add Sipeed Longan Module 3H and Longan Pi 3H
  arm64: dts: allwinner: h616: Add Sipeed Longan SoM 3H and Pi 3H board
    support

 .../devicetree/bindings/arm/sunxi.yaml        |   6 +
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../sun50i-h618-longan-module-3h.dtsi         |  77 ++++++++++
 .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 143 ++++++++++++++++++
 4 files changed, 227 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts

-- 
2.43.0



From jszhang at kernel.org  Sat Feb  3 04:25:00 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sat,  3 Feb 2024 20:25:00 +0800
Subject: [PATCH v2 1/2] dt-bindings: arm: sunxi: Add Sipeed Longan Module 3H and Longan Pi 3H
In-Reply-To: <20240203122502.1259-1-jszhang@kernel.org>
References: <20240203122502.1259-1-jszhang@kernel.org>
Message-ID: <20240203122502.1259-2-jszhang@kernel.org>

Add name & compatible for the Sipeed Longan Module 3H and Longan PI 3H
board.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index a9d8e85565b8..a97d44ba10ac 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -835,6 +835,12 @@ properties:
           - const: sinlinx,sina33
           - const: allwinner,sun8i-a33
 
+      - description: Sipeed Longan Pi 3H board for the Sipeed Longan Module 3H
+        items:
+          - const: sipeed,longan-pi-3h
+          - const: sipeed,longan-module-3h
+          - const: allwinner,sun50i-h618
+
       - description: SourceParts PopStick v1.1
         items:
           - const: sourceparts,popstick-v1.1
-- 
2.43.0



From jszhang at kernel.org  Sat Feb  3 04:25:01 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sat,  3 Feb 2024 20:25:01 +0800
Subject: [PATCH v2 2/2] arm64: dts: allwinner: h616: Add Sipeed Longan SoM 3H and Pi 3H board support
In-Reply-To: <20240203122502.1259-1-jszhang@kernel.org>
References: <20240203122502.1259-1-jszhang@kernel.org>
Message-ID: <20240203122502.1259-3-jszhang@kernel.org>

The Sipeed Longan SoM 3H is a system on module based on the Allwinner
H618 SoC. The SoM features:

- Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
- 2/4 GiB LPDDR4 DRAM SoMs
- AXP313a PMIC
- eMMC

The Sipeed Longan PI 3H is a development board based on the above SoM.
The board features:
- Longan SoM 3H
- Raspberry-Pi-1 compatible GPIO header
- 2 USB 2.0 host port
- 1 USB 2.0 type C port (power supply + OTG)
- MicroSD slot
- 1Gbps Ethernet port (via RTL8211 PHY)
- HDMI port
- WiFi/BT chip

Add the devicetree file describing the currently supported features,
namely PMIC, LEDs, UART, SD card, eMMC, USB and Ethernet.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../sun50i-h618-longan-module-3h.dtsi         |  77 ++++++++++
 .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 143 ++++++++++++++++++
 3 files changed, 221 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 91d505b385de..4b9173a16efe 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -42,5 +42,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
new file mode 100644
index 000000000000..5f0f48cf4f01
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
+ */
+
+#include "sun50i-h616.dtsi"
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins>;
+	vmmc-supply = <&reg_dldo1>;
+	vqmmc-supply = <&reg_aldo1>;
+	bus-width = <8>;
+	non-removable;
+	cap-mmc-hw-reset;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	status = "okay";
+};
+
+&r_i2c {
+	status = "okay";
+
+	axp313: pmic at 36 {
+		compatible = "x-powers,axp313a";
+		reg = <0x36>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		interrupt-parent = <&pio>;
+		interrupts = <3 11 IRQ_TYPE_LEVEL_LOW>;	/* PD11 */
+
+		regulators {
+			reg_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc-1v8-pll";
+			};
+
+			reg_dldo1: dldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-3v3-io";
+			};
+
+			reg_dcdc1: dcdc1 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <990000>;
+				regulator-name = "vdd-gpu-sys";
+			};
+
+			reg_dcdc2: dcdc2 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-cpu";
+			};
+
+			reg_dcdc3: dcdc3 {
+				regulator-always-on;
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-dram";
+			};
+		};
+	};
+};
+
+&pio {
+	vcc-pc-supply = <&reg_dldo1>;
+	vcc-pf-supply = <&reg_dldo1>;
+	vcc-pg-supply = <&reg_aldo1>;
+	vcc-ph-supply = <&reg_dldo1>;
+	vcc-pi-supply = <&reg_dldo1>;
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
new file mode 100644
index 000000000000..08d3ad7114fb
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h618-longan-module-3h.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "Sipeed Longan Pi 3H";
+	compatible = "sipeed,longan-pi-3h", "sipeed,longan-module-3h", "allwinner,sun50i-h618";
+
+	aliases {
+		ethernet0 = &emac0;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			color = <LED_COLOR_ID_ORANGE>;
+			function = LED_FUNCTION_INDICATOR;
+			function-enumerator = <0>;
+			gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */
+		};
+
+		led-1 {
+			color = <LED_COLOR_ID_ORANGE>;
+			function = LED_FUNCTION_INDICATOR;
+			function-enumerator = <1>;
+			gpios = <&pio 6 4 GPIO_ACTIVE_LOW>; /* PG4 */
+		};
+	};
+
+	reg_vcc5v: regulator-vcc5v {
+		/* board wide 5V supply directly from the USB-C socket */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	reg_vcc3v3: regulator-vcc3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-3v3";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+};
+
+&axp313 {
+	vin1-supply = <&reg_vcc5v>;
+	vin2-supply = <&reg_vcc5v>;
+	vin3-supply = <&reg_vcc5v>;
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&ehci2 {
+	status = "okay";
+};
+
+&ohci2 {
+	status = "okay";
+};
+
+/* WiFi & BT combo module is connected to this Host */
+&ehci3 {
+	status = "okay";
+};
+
+&ohci3 {
+	status = "okay";
+};
+
+&emac0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ext_rgmii_pins>;
+	phy-mode = "rgmii";
+	phy-handle = <&ext_rgmii_phy>;
+	allwinner,rx-delay-ps = <3100>;
+	allwinner,tx-delay-ps = <700>;
+	phy-supply = <&reg_vcc3v3>;
+	status = "okay";
+};
+
+&mdio0 {
+	ext_rgmii_phy: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <1>;
+	};
+};
+
+&mmc0 {
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;	/* PF6 */
+	vmmc-supply = <&reg_vcc3v3>;
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&usbotg {
+	/*
+	 * PHY0 pins are connected to a USB-C socket, but a role switch
+	 * is not implemented: both CC pins are pulled to GND.
+	 * The VBUS pins power the device, so a fixed peripheral mode
+	 * is the best choice.
+	 * The board can be powered via GPIOs, in this case port0 *can*
+	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
+	 * then provided by the GPIOs. Any user of this setup would
+	 * need to adjust the DT accordingly: dr_mode set to "host",
+	 * enabling OHCI0 and EHCI0.
+	 */
+	dr_mode = "peripheral";
+	status = "okay";
+};
+
+&usbphy {
+	usb1_vbus-supply = <&reg_vcc5v>;
+	usb2_vbus-supply = <&reg_vcc5v>;
+	status = "okay";
+};
-- 
2.43.0



From jszhang at kernel.org  Sat Feb  3 04:25:02 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sat,  3 Feb 2024 20:25:02 +0800
Subject: [PATCH 2/2] arm64: dts: allwinner: h616: Add Sipeed Longan SoM 3H and Pi 3H board support
In-Reply-To: <20240203122502.1259-1-jszhang@kernel.org>
References: <20240203122502.1259-1-jszhang@kernel.org>
Message-ID: <20240203122502.1259-4-jszhang@kernel.org>

The Sipeed Longan SoM 3H is a system on module based on the Allwinner
H618 SoC. The SoM features:

- Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
- 2/4 GiB LPDDR4 DRAM SoMs
- AXP313a PMIC
- eMMC

The Sipeed Longan PI 3H is a development board based on the above SoM.
The board features:
- Longan SoM 3H
- Raspberry-Pi-1 compatible GPIO header
- 2 USB 2.0 host port
- 1 USB 2.0 type C port (power supply + OTG)
- MicroSD slot
- 1Gbps Ethernet port (via RTL8211 PHY)
- HDMI port
- WiFi/BT chip

Add the devicetree file describing the currently supported features,
namely PMIC, LEDs, UART, SD card, eMMC, USB and Ethernet.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../sun50i-h618-longan-module-3h.dtsi         |  82 +++++++++++
 .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 133 ++++++++++++++++++
 3 files changed, 216 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 3aca6787a167..00db504a9b8c 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -42,4 +42,5 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
new file mode 100644
index 000000000000..88a7d287b73c
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+/ {
+	model = "Sipeed Longan Module 3H";
+	compatible = "sipeed,longan-module-3h", "allwinner,sun50i-h618";
+};
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins>;
+	vmmc-supply = <&reg_dldo1>;
+	vqmmc-supply = <&reg_aldo1>;
+	bus-width = <8>;
+	non-removable;
+	cap-mmc-hw-reset;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	status = "okay";
+};
+
+&r_i2c {
+	status = "okay";
+
+	axp313: pmic at 36 {
+		compatible = "x-powers,axp313a";
+		reg = <0x36>;
+
+		regulators {
+			/* Supplies VCC-PLL, so needs to be always on. */
+			reg_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc1v8";
+			};
+
+			/* Supplies VCC-IO, so needs to be always on. */
+			reg_dldo1: dldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc3v3";
+			};
+
+			reg_dcdc1: dcdc1 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <990000>;
+				regulator-name = "vdd-gpu-sys";
+			};
+
+			reg_dcdc2: dcdc2 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-cpu";
+			};
+
+			reg_dcdc3: dcdc3 {
+				regulator-always-on;
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-dram";
+			};
+		};
+	};
+};
+
+&pio {
+	vcc-pc-supply = <&reg_dldo1>;
+	vcc-pf-supply = <&reg_dldo1>;
+	vcc-pg-supply = <&reg_aldo1>;
+	vcc-ph-supply = <&reg_dldo1>;
+	vcc-pi-supply = <&reg_dldo1>;
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
new file mode 100644
index 000000000000..245583881549
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h618-longan-module-3h.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "Sipeed Longan Pi 3H";
+	compatible = "sipeed,longan-pi-3h", "sipeed,longan-module-3h", "allwinner,sun50i-h618";
+
+	aliases {
+		ethernet0 = &emac0;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			color = <LED_COLOR_ID_ORANGE>;
+			function = LED_FUNCTION_INDICATOR;
+			function-enumerator = <0>;
+			gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */
+		};
+
+		led-1 {
+			color = <LED_COLOR_ID_ORANGE>;
+			function = LED_FUNCTION_INDICATOR;
+			function-enumerator = <1>;
+			gpios = <&pio 6 4 GPIO_ACTIVE_LOW>; /* PG4 */
+		};
+	};
+
+	reg_vcc5v: vcc5v {
+		/* board wide 5V supply directly from the USB-C socket */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+};
+
+&axp313 {
+	vin1-supply = <&reg_vcc5v>;
+	vin2-supply = <&reg_vcc5v>;
+	vin3-supply = <&reg_vcc5v>;
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&ehci2 {
+	status = "okay";
+};
+
+&ohci2 {
+	status = "okay";
+};
+
+&ehci3 {
+	status = "okay";
+};
+
+&ohci3 {
+	status = "okay";
+};
+
+&emac0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ext_rgmii_pins>;
+	phy-mode = "rgmii";
+	phy-handle = <&ext_rgmii_phy>;
+	allwinner,rx-delay-ps = <3100>;
+	allwinner,tx-delay-ps = <700>;
+	phy-supply = <&reg_dldo1>;
+	status = "okay";
+};
+
+&mdio0 {
+	ext_rgmii_phy: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <1>;
+	};
+};
+
+&mmc0 {
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;	/* PF6 */
+	vmmc-supply = <&reg_dldo1>;
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&usbotg {
+	/*
+	 * PHY0 pins are connected to a USB-C socket, but a role switch
+	 * is not implemented: both CC pins are pulled to GND.
+	 * The VBUS pins power the device, so a fixed peripheral mode
+	 * is the best choice.
+	 * The board can be powered via GPIOs, in this case port0 *can*
+	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
+	 * then provided by the GPIOs. Any user of this setup would
+	 * need to adjust the DT accordingly: dr_mode set to "host",
+	 * enabling OHCI0 and EHCI0.
+	 */
+	dr_mode = "peripheral";
+	status = "okay";
+};
+
+&usbphy {
+	usb1_vbus-supply = <&reg_vcc5v>;
+	status = "okay";
+};
-- 
2.40.0



From jszhang at kernel.org  Sat Feb  3 04:29:46 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sat, 3 Feb 2024 20:29:46 +0800
Subject: [PATCH 2/2] arm64: dts: allwinner: h616: Add Sipeed Longan SoM
 3H and Pi 3H board support
In-Reply-To: <20231229235543.7548cafa@minigeek.lan>
References: <20231228145647.1470-1-jszhang@kernel.org>
 <20231228145647.1470-3-jszhang@kernel.org>
 <20231229235543.7548cafa@minigeek.lan>
Message-ID: <Zb4xui9QtKvilSZh@xhacker>

On Fri, Dec 29, 2023 at 11:55:43PM +0000, Andre Przywara wrote:
> On Thu, 28 Dec 2023 22:56:47 +0800
> Jisheng Zhang <jszhang at kernel.org> wrote:
> 
> Hi,
> 
> > The Sipeed Longan SoM 3H is a system on module based on the Allwinner
> > H618 SoC. The SoM features:
> > 
> > - Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
> > - 2/4 GiB LPDDR4 DRAM SoMs
> > - AXP313a PMIC
> > - eMMC
> > 
> > The Sipeed Longan PI 3H is a development board based on the above SoM.
> > The board features:
> > - Longan SoM 3H
> > - Raspberry-Pi-1 compatible GPIO header
> > - 2 USB 2.0 host port
> > - 1 USB 2.0 type C port (power supply + OTG)
> > - MicroSD slot
> > - 1Gbps Ethernet port (via RTL8211 PHY)
> > - HDMI port
> > - WiFi/BT chip
> > 
> > Add the devicetree file describing the currently supported features,
> > namely PMIC, LEDs, UART, SD card, eMMC, USB and Ethernet.
> > 
> > Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> > ---
> >  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
> >  .../sun50i-h618-longan-module-3h.dtsi         |  82 +++++++++++
> >  .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 133 ++++++++++++++++++
> >  3 files changed, 216 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> > index 3aca6787a167..00db504a9b8c 100644
> > --- a/arch/arm64/boot/dts/allwinner/Makefile
> > +++ b/arch/arm64/boot/dts/allwinner/Makefile
> > @@ -42,4 +42,5 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
> > +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> > new file mode 100644
> > index 000000000000..88a7d287b73c
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> > @@ -0,0 +1,82 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
> > + */
> > +
> > +/dts-v1/;
> 
> I don't see how the SoM could be used on its own, without a hosting
> board. So we don't need the dts version tag in the .dtsi, that would
> just be double when we are going to compile any actual .dtb.
> 
> > +
> > +#include "sun50i-h616.dtsi"
> > +
> > +/ {
> > +	model = "Sipeed Longan Module 3H";
> > +	compatible = "sipeed,longan-module-3h", "allwinner,sun50i-h618";
> 
> Same here, any model or compatible string would only be overwritten by
> the board versions, so you don't need those two in the SoM .dtsi.
> Compare the SoPine and BTT CB1 .dtsi files.
> 
> > +};
> > +
> > +&mmc2 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&mmc2_pins>;
> 
> Can you please add the DS pin here? At the moment the sunxi Linux
> driver doesn't support HS-400, but that can a) change and b) doesn't
> affect the DT anyway, since that describes the hardware. The connection
> is definitely there, according to the schematics.

Hi Andre,

Thank you so much for the review and comments, could you please review?
Except DS pin, other comments are adopted and updated in v2.
DS pin is already there, IIUC, PC0 is emmc DS pin

Thanks

> 
> > +	vmmc-supply = <&reg_dldo1>;
> > +	vqmmc-supply = <&reg_aldo1>;
> > +	bus-width = <8>;
> > +	non-removable;
> > +	cap-mmc-hw-reset;
> > +	mmc-ddr-1_8v;
> > +	mmc-hs200-1_8v;
> > +	status = "okay";
> > +};
> > +
> > +&r_i2c {
> > +	status = "okay";
> > +
> > +	axp313: pmic at 36 {
> > +		compatible = "x-powers,axp313a";
> 
> According to the bindings you need:
> 
> 	interrupt-controller;
> 	#interrupt-cells = <1>;
> 
> Even without the IRQ line connected. dt-validate complains about that.
> 
> Actually, do you know of any reason why it is not connected? I see it on
> the SoM pins, is the idea that any *board* could dedicate a GPIO pin for
> it, if needed?
> 
> > +		reg = <0x36>;
> > +
> > +		regulators {
> > +			/* Supplies VCC-PLL, so needs to be always on. */
> > +			reg_aldo1: aldo1 {
> > +				regulator-always-on;
> > +				regulator-min-microvolt = <1800000>;
> > +				regulator-max-microvolt = <1800000>;
> > +				regulator-name = "vcc1v8";
> 
> Can you please use "vcc-1v8-pll" instead? Then you don't need the
> comment.
> 
> > +			};
> > +
> > +			/* Supplies VCC-IO, so needs to be always on. */
> > +			reg_dldo1: dldo1 {
> > +				regulator-always-on;
> > +				regulator-min-microvolt = <3300000>;
> > +				regulator-max-microvolt = <3300000>;
> > +				regulator-name = "vcc3v3";
> 
> Same here, "vcc-3v3-io" is the name we used lately, to avoid the
> comment.
> 
> > +			};
> > +
> > +			reg_dcdc1: dcdc1 {
> > +				regulator-always-on;
> > +				regulator-min-microvolt = <810000>;
> > +				regulator-max-microvolt = <990000>;
> > +				regulator-name = "vdd-gpu-sys";
> > +			};
> > +
> > +			reg_dcdc2: dcdc2 {
> > +				regulator-always-on;
> > +				regulator-min-microvolt = <810000>;
> > +				regulator-max-microvolt = <1100000>;
> > +				regulator-name = "vdd-cpu";
> > +			};
> > +
> > +			reg_dcdc3: dcdc3 {
> > +				regulator-always-on;
> > +				regulator-min-microvolt = <1100000>;
> > +				regulator-max-microvolt = <1100000>;
> > +				regulator-name = "vdd-dram";
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&pio {
> > +	vcc-pc-supply = <&reg_dldo1>;
> > +	vcc-pf-supply = <&reg_dldo1>;
> > +	vcc-pg-supply = <&reg_aldo1>;
> > +	vcc-ph-supply = <&reg_dldo1>;
> > +	vcc-pi-supply = <&reg_dldo1>;
> > +};
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> > new file mode 100644
> > index 000000000000..245583881549
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> > @@ -0,0 +1,133 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "sun50i-h618-longan-module-3h.dtsi"
> > +
> > +#include <dt-bindings/gpio/gpio.h>
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/leds/common.h>
> > +
> > +/ {
> > +	model = "Sipeed Longan Pi 3H";
> > +	compatible = "sipeed,longan-pi-3h", "sipeed,longan-module-3h", "allwinner,sun50i-h618";
> > +
> > +	aliases {
> > +		ethernet0 = &emac0;
> > +		serial0 = &uart0;
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +
> > +	leds {
> > +		compatible = "gpio-leds";
> > +
> > +		led-0 {
> > +			color = <LED_COLOR_ID_ORANGE>;
> > +			function = LED_FUNCTION_INDICATOR;
> > +			function-enumerator = <0>;
> > +			gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */
> > +		};
> > +
> > +		led-1 {
> > +			color = <LED_COLOR_ID_ORANGE>;
> > +			function = LED_FUNCTION_INDICATOR;
> > +			function-enumerator = <1>;
> > +			gpios = <&pio 6 4 GPIO_ACTIVE_LOW>; /* PG4 */
> > +		};
> > +	};
> > +
> > +	reg_vcc5v: vcc5v {
> > +		/* board wide 5V supply directly from the USB-C socket */
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "vcc-5v";
> > +		regulator-min-microvolt = <5000000>;
> > +		regulator-max-microvolt = <5000000>;
> > +		regulator-always-on;
> > +	};
> 
> According to the schematic, there is a discrete 5V->3.3V regulator, can
> you please describe this here as well?
> 
> > +};
> > +
> > +&axp313 {
> > +	vin1-supply = <&reg_vcc5v>;
> > +	vin2-supply = <&reg_vcc5v>;
> > +	vin3-supply = <&reg_vcc5v>;
> > +};
> > +
> > +&ehci1 {
> > +	status = "okay";
> > +};
> > +
> > +&ohci1 {
> > +	status = "okay";
> > +};
> > +
> > +&ehci2 {
> > +	status = "okay";
> > +};
> > +
> > +&ohci2 {
> > +	status = "okay";
> > +};
> > +
> 
> Maybe worth adding a comment here that there is a USB WiFi chip
> connected to those pins.
> 
> > +&ehci3 {
> > +	status = "okay";
> > +};
> > +
> > +&ohci3 {
> > +	status = "okay";
> > +};
> > +
> > +&emac0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&ext_rgmii_pins>;
> > +	phy-mode = "rgmii";
> > +	phy-handle = <&ext_rgmii_phy>;
> > +	allwinner,rx-delay-ps = <3100>;
> > +	allwinner,tx-delay-ps = <700>;
> > +	phy-supply = <&reg_dldo1>;
> 
> If I get the schematic correctly, the PHY is powered from the discrete
> 3.3V regulator? In fact, the 3V3-DLDO-OUT/1V8-ALDO-OUT pins on the SoM
> do not seem to be connected, so anything using 3.3V or 1.8V on the
> board needs to be fed from this regulator, and everything on the SoM is
> supplied by the AXP?
> 
> > +	status = "okay";
> > +};
> > +
> > +&mdio0 {
> > +	ext_rgmii_phy: ethernet-phy at 1 {
> > +		compatible = "ethernet-phy-ieee802.3-c22";
> > +		reg = <1>;
> > +	};
> > +};
> > +
> > +&mmc0 {
> > +	bus-width = <4>;
> > +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;	/* PF6 */
> > +	vmmc-supply = <&reg_dldo1>;
> 
> According to the schematic, the SD card is supplied by the discrete
> 3.3V regulator on the board.
> 
> > +	status = "okay";
> > +};
> > +
> > +&uart0 {
> > +	status = "okay";
> > +};
> > +
> > +&usbotg {
> > +	/*
> > +	 * PHY0 pins are connected to a USB-C socket, but a role switch
> > +	 * is not implemented: both CC pins are pulled to GND.
> > +	 * The VBUS pins power the device, so a fixed peripheral mode
> > +	 * is the best choice.
> > +	 * The board can be powered via GPIOs, in this case port0 *can*
> > +	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
> > +	 * then provided by the GPIOs. Any user of this setup would
> > +	 * need to adjust the DT accordingly: dr_mode set to "host",
> > +	 * enabling OHCI0 and EHCI0.
> > +	 */
> > +	dr_mode = "peripheral";
> > +	status = "okay";
> > +};
> > +
> > +&usbphy {
> > +	usb1_vbus-supply = <&reg_vcc5v>;
> 
> The same seems to be true for USB2 as well, and the WiFi chip on USB3 is
> powered by the discrete 3.3V regulator. But I think we don't need these
> properties at all if it's directly connected to the input and so always
> powered. Or maybe we should do this anyway, and be it to make it clear
> where the bus power is coming from?
> 
> Cheers,
> Andre
> 
> P.S. I saw some U-Boot patches on some github. Most of them are
> merged, but feel free to post the DT (same ones as here) and the
> defconfig to the U-Boot list as well. You can use "make savedefconfig"
> when you have configured the board, this will create a file "defconfig"
> in the build directory that contains the minimal items, this can be
> directly used as a defconfig.
> 
> > +	status = "okay";
> > +};
> 


From jszhang at kernel.org  Sat Feb  3 04:36:42 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sat, 3 Feb 2024 20:36:42 +0800
Subject: [PATCH 2/2] arm64: dts: allwinner: h616: Add Sipeed Longan SoM
 3H and Pi 3H board support
In-Reply-To: <2589997.Lt9SDvczpP@jernej-laptop>
References: <20231228145647.1470-1-jszhang@kernel.org>
 <20231228145647.1470-3-jszhang@kernel.org>
 <2589997.Lt9SDvczpP@jernej-laptop>
Message-ID: <Zb4zWsfzgJkZa2KQ@xhacker>

On Tue, Jan 09, 2024 at 09:37:03PM +0100, Jernej ?krabec wrote:
> Hi Jisheng,

Hi Jernej,

> 
> Andre gave you thorough review already, so just one additional comment
> below.
> 
> Dne ?etrtek, 28. december 2023 ob 15:56:47 CET je Jisheng Zhang napisal(a):
> > The Sipeed Longan SoM 3H is a system on module based on the Allwinner
> > H618 SoC. The SoM features:
> > 
> > - Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
> > - 2/4 GiB LPDDR4 DRAM SoMs
> > - AXP313a PMIC
> > - eMMC
> > 
> > The Sipeed Longan PI 3H is a development board based on the above SoM.
> > The board features:
> > - Longan SoM 3H
> > - Raspberry-Pi-1 compatible GPIO header
> > - 2 USB 2.0 host port
> > - 1 USB 2.0 type C port (power supply + OTG)
> > - MicroSD slot
> > - 1Gbps Ethernet port (via RTL8211 PHY)
> > - HDMI port
> > - WiFi/BT chip
> > 
> > Add the devicetree file describing the currently supported features,
> > namely PMIC, LEDs, UART, SD card, eMMC, USB and Ethernet.
> > 
> > Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> > ---
> >  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
> >  .../sun50i-h618-longan-module-3h.dtsi         |  82 +++++++++++
> >  .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 133 ++++++++++++++++++
> >  3 files changed, 216 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> > index 3aca6787a167..00db504a9b8c 100644
> > --- a/arch/arm64/boot/dts/allwinner/Makefile
> > +++ b/arch/arm64/boot/dts/allwinner/Makefile
> > @@ -42,4 +42,5 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
> > +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> > new file mode 100644
> > index 000000000000..88a7d287b73c
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> > @@ -0,0 +1,82 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "sun50i-h616.dtsi"
> > +
> > +/ {
> > +	model = "Sipeed Longan Module 3H";
> > +	compatible = "sipeed,longan-module-3h", "allwinner,sun50i-h618";
> > +};
> > +
> > +&mmc2 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&mmc2_pins>;
> > +	vmmc-supply = <&reg_dldo1>;
> > +	vqmmc-supply = <&reg_aldo1>;
> > +	bus-width = <8>;
> > +	non-removable;
> > +	cap-mmc-hw-reset;
> > +	mmc-ddr-1_8v;
> 
> I think above is superfluous if hs200 is also defined.

I read the mmc code again, IMHO, mmc-ddr-1_8v and mmc-hs200-1_8v
are for different caps, the former is for MMC_CAP_1_8V_DDR and
the later is for MMC_CAP2_HS200_1_8V_SDR, I must admit that
mmc-hs200-1_8v does imply mmc-ddr-1_8v in normal host controllers
but they are different, and I found other dts files also contain
both, so I kept this as is in v2.

Thanks

> 
> > +	mmc-hs200-1_8v;
> > +	status = "okay";
> > +};
> > +
 


From ardb+git at google.com  Sat Feb  3 04:53:06 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Sat,  3 Feb 2024 13:53:06 +0100
Subject: [PATCH] x86/sev: Fix position dependent variable references in
 startup code
Message-ID: <20240203125306.1887331-2-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The early startup code executes from a 1:1 mapping of memory, which
differs from the mapping that the code was linked and/or relocated to
run at. The latter mapping is not active yet at this point, and so
symbol references that rely on it will fault. Given that the core kernel
is built without -fPIC, symbol references are typically emitted as
absolute, and so any such references occuring in the early startup code
will therefore crash the kernel.

While an attempt was made to work around this for the early SEV/SME
startup code, by forcing RIP-relative addressing for certain global
SEV/SME variables via inline assembly (see snp_cpuid_get_table() for
example), RIP-relative addressing must be pervasively enforced for
SEV/SME global variables when accessed prior to page table fixups.

__startup_64() already handles this issue for select non-SEV/SME global
variables using fixup_pointer(), which adjusts the pointer relative to a
`physaddr` argument. To avoid having to pass around this `physaddr`
argument across all functions needing to apply pointer fixups, this
patch introduces the macro RIP_RELATIVE_REF(), which generates a
RIP-relative reference to a given global variable. The macro is used
where necessary to force RIP-relative accesses to global variables.

For backporting purposes, this patch makes no attempt at cleaning up
other occurrences of this pattern, involving either inline asm or
fixup_pointer(). Those will be addressed by subsequent patches.

Link: https://lore.kernel.org/all/20240130220845.1978329-1-kevinloughlin at google.com/
Co-developed-by: Kevin Loughlin <kevinloughlin at google.com>
Signed-off-by: Kevin Loughlin <kevinloughlin at google.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/x86/coco/core.c               |  7 +----
 arch/x86/include/asm/asm.h         | 13 ++++++++++
 arch/x86/include/asm/coco.h        |  8 +++++-
 arch/x86/include/asm/mem_encrypt.h | 13 ++++++----
 arch/x86/kernel/sev-shared.c       | 12 ++++-----
 arch/x86/kernel/sev.c              |  4 +--
 arch/x86/mm/mem_encrypt_identity.c | 27 +++++++++-----------
 7 files changed, 49 insertions(+), 35 deletions(-)

diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index eeec9986570e..d07be9d05cd0 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -14,7 +14,7 @@
 #include <asm/processor.h>
 
 enum cc_vendor cc_vendor __ro_after_init = CC_VENDOR_NONE;
-static u64 cc_mask __ro_after_init;
+u64 cc_mask __ro_after_init;
 
 static bool noinstr intel_cc_platform_has(enum cc_attr attr)
 {
@@ -148,8 +148,3 @@ u64 cc_mkdec(u64 val)
 	}
 }
 EXPORT_SYMBOL_GPL(cc_mkdec);
-
-__init void cc_set_mask(u64 mask)
-{
-	cc_mask = mask;
-}
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index fbcfec4dc4cc..41b408b3dfb6 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -113,6 +113,19 @@
 
 #endif
 
+#ifndef __ASSEMBLY__
+#ifndef __pic__
+static inline __pure void *rip_relative_ptr(void *p)
+{
+	asm("leaq %c1(%%rip), %0" : "=r"(p) : "i"(p));
+	return p;
+}
+#define RIP_RELATIVE_REF(var)	(*(typeof(&(var)))rip_relative_ptr(&(var)))
+#else
+#define RIP_RELATIVE_REF(var)	(var)
+#endif
+#endif
+
 /*
  * Macros to generate condition code outputs from inline assembly,
  * The output operand must be type "bool".
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
index 6ae2d16a7613..d6865e0f7587 100644
--- a/arch/x86/include/asm/coco.h
+++ b/arch/x86/include/asm/coco.h
@@ -2,6 +2,7 @@
 #ifndef _ASM_X86_COCO_H
 #define _ASM_X86_COCO_H
 
+#include <asm/asm.h>
 #include <asm/types.h>
 
 enum cc_vendor {
@@ -11,9 +12,14 @@ enum cc_vendor {
 };
 
 extern enum cc_vendor cc_vendor;
+extern u64 cc_mask;
 
 #ifdef CONFIG_ARCH_HAS_CC_PLATFORM
-void cc_set_mask(u64 mask);
+static inline void cc_set_mask(u64 mask)
+{
+	RIP_RELATIVE_REF(cc_mask) = mask;
+}
+
 u64 cc_mkenc(u64 val);
 u64 cc_mkdec(u64 val);
 #else
diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h
index 359ada486fa9..1427b5fc416c 100644
--- a/arch/x86/include/asm/mem_encrypt.h
+++ b/arch/x86/include/asm/mem_encrypt.h
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/cc_platform.h>
 
+#include <asm/asm.h>
 #include <asm/bootparam.h>
 
 #ifdef CONFIG_X86_MEM_ENCRYPT
@@ -58,6 +59,11 @@ void __init mem_encrypt_free_decrypted_mem(void);
 
 void __init sev_es_init_vc_handling(void);
 
+static inline u64 sme_get_me_mask(void)
+{
+	return RIP_RELATIVE_REF(sme_me_mask);
+}
+
 #define __bss_decrypted __section(".bss..decrypted")
 
 #else	/* !CONFIG_AMD_MEM_ENCRYPT */
@@ -89,6 +95,8 @@ early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool en
 
 static inline void mem_encrypt_free_decrypted_mem(void) { }
 
+static inline u64 sme_get_me_mask(void) { return 0; }
+
 #define __bss_decrypted
 
 #endif	/* CONFIG_AMD_MEM_ENCRYPT */
@@ -106,11 +114,6 @@ void add_encrypt_protection_map(void);
 
 extern char __start_bss_decrypted[], __end_bss_decrypted[], __start_bss_decrypted_unused[];
 
-static inline u64 sme_get_me_mask(void)
-{
-	return sme_me_mask;
-}
-
 #endif	/* __ASSEMBLY__ */
 
 #endif	/* __X86_MEM_ENCRYPT_H__ */
diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
index 5db24d0fc557..df3a89cbca46 100644
--- a/arch/x86/kernel/sev-shared.c
+++ b/arch/x86/kernel/sev-shared.c
@@ -560,9 +560,9 @@ static int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_le
 		leaf->eax = leaf->ebx = leaf->ecx = leaf->edx = 0;
 
 		/* Skip post-processing for out-of-range zero leafs. */
-		if (!(leaf->fn <= cpuid_std_range_max ||
-		      (leaf->fn >= 0x40000000 && leaf->fn <= cpuid_hyp_range_max) ||
-		      (leaf->fn >= 0x80000000 && leaf->fn <= cpuid_ext_range_max)))
+		if (!(leaf->fn <= RIP_RELATIVE_REF(cpuid_std_range_max) ||
+		      (leaf->fn >= 0x40000000 && leaf->fn <= RIP_RELATIVE_REF(cpuid_hyp_range_max)) ||
+		      (leaf->fn >= 0x80000000 && leaf->fn <= RIP_RELATIVE_REF(cpuid_ext_range_max))))
 			return 0;
 	}
 
@@ -1072,11 +1072,11 @@ static void __init setup_cpuid_table(const struct cc_blob_sev_info *cc_info)
 		const struct snp_cpuid_fn *fn = &cpuid_table->fn[i];
 
 		if (fn->eax_in == 0x0)
-			cpuid_std_range_max = fn->eax;
+			RIP_RELATIVE_REF(cpuid_std_range_max) = fn->eax;
 		else if (fn->eax_in == 0x40000000)
-			cpuid_hyp_range_max = fn->eax;
+			RIP_RELATIVE_REF(cpuid_hyp_range_max) = fn->eax;
 		else if (fn->eax_in == 0x80000000)
-			cpuid_ext_range_max = fn->eax;
+			RIP_RELATIVE_REF(cpuid_ext_range_max) = fn->eax;
 	}
 }
 
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index 002af6c30601..1cf348e19556 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -748,7 +748,7 @@ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long padd
 	 * This eliminates worries about jump tables or checking boot_cpu_data
 	 * in the cc_platform_has() function.
 	 */
-	if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
+	if (!(RIP_RELATIVE_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED))
 		return;
 
 	 /*
@@ -767,7 +767,7 @@ void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr
 	 * This eliminates worries about jump tables or checking boot_cpu_data
 	 * in the cc_platform_has() function.
 	 */
-	if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
+	if (!(RIP_RELATIVE_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED))
 		return;
 
 	 /* Ask hypervisor to mark the memory pages shared in the RMP table. */
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index efe9f217fcf9..d8d14133b654 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -304,7 +304,8 @@ void __init sme_encrypt_kernel(struct boot_params *bp)
 	 * instrumentation or checking boot_cpu_data in the cc_platform_has()
 	 * function.
 	 */
-	if (!sme_get_me_mask() || sev_status & MSR_AMD64_SEV_ENABLED)
+	if (!sme_get_me_mask() ||
+	    RIP_RELATIVE_REF(sev_status) & MSR_AMD64_SEV_ENABLED)
 		return;
 
 	/*
@@ -541,11 +542,11 @@ void __init sme_enable(struct boot_params *bp)
 	me_mask = 1UL << (ebx & 0x3f);
 
 	/* Check the SEV MSR whether SEV or SME is enabled */
-	sev_status   = __rdmsr(MSR_AMD64_SEV);
-	feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
+	RIP_RELATIVE_REF(sev_status) = msr = __rdmsr(MSR_AMD64_SEV);
+	feature_mask = (msr & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
 
 	/* The SEV-SNP CC blob should never be present unless SEV-SNP is enabled. */
-	if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
+	if (snp && !(msr & MSR_AMD64_SEV_SNP_ENABLED))
 		snp_abort();
 
 	/* Check if memory encryption is enabled */
@@ -571,7 +572,6 @@ void __init sme_enable(struct boot_params *bp)
 			return;
 	} else {
 		/* SEV state cannot be controlled by a command line option */
-		sme_me_mask = me_mask;
 		goto out;
 	}
 
@@ -590,16 +590,13 @@ void __init sme_enable(struct boot_params *bp)
 	cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr |
 				     ((u64)bp->ext_cmd_line_ptr << 32));
 
-	if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0)
-		goto out;
-
-	if (!strncmp(buffer, cmdline_on, sizeof(buffer)))
-		sme_me_mask = me_mask;
+	if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0 ||
+	    strncmp(buffer, cmdline_on, sizeof(buffer)))
+		return;
 
 out:
-	if (sme_me_mask) {
-		physical_mask &= ~sme_me_mask;
-		cc_vendor = CC_VENDOR_AMD;
-		cc_set_mask(sme_me_mask);
-	}
+	RIP_RELATIVE_REF(sme_me_mask) = me_mask;
+	physical_mask &= ~me_mask;
+	cc_vendor = CC_VENDOR_AMD;
+	cc_set_mask(me_mask);
 }

base-commit: f9e6f00d93d34f60f90b42c24e80194b11a72bb2
-- 
2.43.0.594.gd9cf4e227d-goog



From claudiu.beznea at tuxon.dev  Sat Feb  3 05:00:28 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 3 Feb 2024 15:00:28 +0200
Subject: [PATCH RESEND v7 1/7] drm: atmel-hlcdc: add flag and driver ops
 to differentiate XLCDC and HLCDC IP
In-Reply-To: <20240129092319.199365-2-manikandan.m@microchip.com>
References: <20240129092319.199365-1-manikandan.m@microchip.com>
 <20240129092319.199365-2-manikandan.m@microchip.com>
Message-ID: <397c97ce-2912-42c1-823a-7ad151d73307@tuxon.dev>

Hi, Manikandan,

On 29.01.2024 11:23, Manikandan Muralidharan wrote:
> Add is_xlcdc flag and LCD IP specific ops in driver data to differentiate
> XLCDC and HLCDC code within the atmel-hlcdc driver files.

I would first prepare the current code base for the addition of XLCDC by
first adding the struct atmel_lcdc_dc_ops, update current code to use it
and after that add XLCDC.

> 
> Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 37 ++++++++++++++++++++
>  1 file changed, 37 insertions(+)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> index 5b5c774e0edf..d5e01ff8c7f9 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> @@ -177,6 +177,9 @@ struct atmel_hlcdc_layer_cfg_layout {
>  	int csc;
>  };
>  
> +struct atmel_hlcdc_plane_state;

You can move this forward declaration close the the structure that needs it
(struct atmel_lcdc_dc_ops).

> +struct atmel_hlcdc_dc;

And you can get rid if this one if you move struct atmel_lcdc_dc_ops after
struct atmel_hlcdc_dc definition.

> +
>  /**
>   * Atmel HLCDC DMA descriptor structure
>   *
> @@ -288,6 +291,36 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer)
>  	return container_of(layer, struct atmel_hlcdc_plane, layer);
>  }
>  
> +/**
> + * struct atmel_lcdc_dc_ops - describes atmel_lcdc ops group
> + * to differentiate HLCDC and XLCDC IP code support.
> + * @plane_setup_scaler: update the vertical and horizontal scaling factors
> + * @update_lcdc_buffers: update the each LCDC layers DMA registers.
> + * @lcdc_atomic_disable: disable LCDC interrupts and layers
> + * @lcdc_update_general_settings: update each LCDC layers general
> + * confiugration register.
s/confiugration/configuration

> + * @lcdc_atomic_update: enable the LCDC layers and interrupts.

You may want to keep consistency by adding or not '.' at the end of the
documentation statement (I consider '.' is useless)

> + * @lcdc_csc_init: update the color space conversion co-efficient of
> + * High-end overlay register.
> + * @lcdc_irq_dbg: to raise alert incase of interrupt overrun in any LCDC layer.

s/incase/in case

> + */
> +struct atmel_lcdc_dc_ops {
> +	void (*plane_setup_scaler)(struct atmel_hlcdc_plane *plane,
> +				   struct atmel_hlcdc_plane_state *state);
> +	void (*update_lcdc_buffers)(struct atmel_hlcdc_plane *plane,
> +				    struct atmel_hlcdc_plane_state *state,
> +				    u32 sr, int i);
> +	void (*lcdc_atomic_disable)(struct atmel_hlcdc_plane *plane);
> +	void (*lcdc_update_general_settings)(struct atmel_hlcdc_plane *plane,
> +					     struct atmel_hlcdc_plane_state *state);
> +	void (*lcdc_atomic_update)(struct atmel_hlcdc_plane *plane,
> +				   struct atmel_hlcdc_dc *dc);
> +	void (*lcdc_csc_init)(struct atmel_hlcdc_plane *plane,
> +			      const struct atmel_hlcdc_layer_desc *desc);
> +	void (*lcdc_irq_dbg)(struct atmel_hlcdc_plane *plane,
> +			     const struct atmel_hlcdc_layer_desc *desc);
> +};
> +
>  /**
>   * Atmel HLCDC Display Controller description structure.
>   *
> @@ -304,8 +337,10 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer)
>   * @conflicting_output_formats: true if RGBXXX output formats conflict with
>   *				each other.
>   * @fixed_clksrc: true if clock source is fixed
> + * @is_xlcdc: true if XLCDC IP is supported
>   * @layers: a layer description table describing available layers
>   * @nlayers: layer description table size
> + * @ops: atmel lcdc dc ops
>   */
>  struct atmel_hlcdc_dc_desc {
>  	int min_width;
> @@ -317,8 +352,10 @@ struct atmel_hlcdc_dc_desc {
>  	int max_hpw;
>  	bool conflicting_output_formats;
>  	bool fixed_clksrc;
> +	bool is_xlcdc;
>  	const struct atmel_hlcdc_layer_desc *layers;
>  	int nlayers;
> +	const struct atmel_lcdc_dc_ops *ops;
>  };
>  
>  /**


From claudiu.beznea at tuxon.dev  Sat Feb  3 05:00:34 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 3 Feb 2024 15:00:34 +0200
Subject: [PATCH RESEND v7 2/7] drm: atmel-hlcdc: add LCD controller layer
 definition for sam9x75
In-Reply-To: <20240129092319.199365-3-manikandan.m@microchip.com>
References: <20240129092319.199365-1-manikandan.m@microchip.com>
 <20240129092319.199365-3-manikandan.m@microchip.com>
Message-ID: <a6e3f9b7-2ff4-4c07-ad4c-675a7e1a0ae1@tuxon.dev>



On 29.01.2024 11:23, Manikandan Muralidharan wrote:
> Add the LCD controller layer definition and descriptor structure for
> sam9x75 for the following layers:
> - Base Layer
> - Overlay1 Layer
> - Overlay2 Layer
> - High End Overlay
> 
> Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 97 ++++++++++++++++++++
>  1 file changed, 97 insertions(+)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> index fa0f9a93d50d..d30aec174aa2 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> @@ -462,6 +462,99 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = {
>  	.layers = atmel_hlcdc_sam9x60_layers,
>  };
>  
> +static const struct atmel_hlcdc_layer_desc atmel_xlcdc_sam9x75_layers[] = {
> +	{
> +		.name = "base",
> +		.formats = &atmel_hlcdc_plane_rgb_formats,
> +		.regs_offset = 0x60,
> +		.id = 0,
> +		.type = ATMEL_HLCDC_BASE_LAYER,
> +		.cfgs_offset = 0x1c,
> +		.layout = {
> +			.xstride = { 2 },
> +			.default_color = 3,
> +			.general_config = 4,
> +			.disc_pos = 5,
> +			.disc_size = 6,
> +		},
> +		.clut_offset = 0x700,
> +	},
> +	{
> +		.name = "overlay1",
> +		.formats = &atmel_hlcdc_plane_rgb_formats,
> +		.regs_offset = 0x160,
> +		.id = 1,
> +		.type = ATMEL_HLCDC_OVERLAY_LAYER,
> +		.cfgs_offset = 0x1c,
> +		.layout = {
> +			.pos = 2,
> +			.size = 3,
> +			.xstride = { 4 },
> +			.pstride = { 5 },
> +			.default_color = 6,
> +			.chroma_key = 7,
> +			.chroma_key_mask = 8,
> +			.general_config = 9,
> +		},
> +		.clut_offset = 0xb00,
> +	},
> +	{
> +		.name = "overlay2",
> +		.formats = &atmel_hlcdc_plane_rgb_formats,
> +		.regs_offset = 0x260,
> +		.id = 2,
> +		.type = ATMEL_HLCDC_OVERLAY_LAYER,
> +		.cfgs_offset = 0x1c,
> +		.layout = {
> +			.pos = 2,
> +			.size = 3,
> +			.xstride = { 4 },
> +			.pstride = { 5 },
> +			.default_color = 6,
> +			.chroma_key = 7,
> +			.chroma_key_mask = 8,
> +			.general_config = 9,
> +		},
> +		.clut_offset = 0xf00,
> +	},
> +	{
> +		.name = "high-end-overlay",
> +		.formats = &atmel_hlcdc_plane_rgb_and_yuv_formats,
> +		.regs_offset = 0x360,
> +		.id = 3,
> +		.type = ATMEL_HLCDC_OVERLAY_LAYER,
> +		.cfgs_offset = 0x30,
> +		.layout = {
> +			.pos = 2,
> +			.size = 3,
> +			.memsize = 4,
> +			.xstride = { 5, 7 },
> +			.pstride = { 6, 8 },
> +			.default_color = 9,
> +			.chroma_key = 10,
> +			.chroma_key_mask = 11,
> +			.general_config = 12,
> +			.csc = 16,
> +			.scaler_config = 23,
> +		},
> +		.clut_offset = 0x1300,
> +	},
> +};
> +
> +static const struct atmel_hlcdc_dc_desc atmel_xlcdc_dc_sam9x75 = {
> +	.min_width = 0,
> +	.min_height = 0,
> +	.max_width = 2048,
> +	.max_height = 2048,
> +	.max_spw = 0xff,
> +	.max_vpw = 0xff,
> +	.max_hpw = 0x3ff,
> +	.fixed_clksrc = true,
> +	.is_xlcdc = true,
> +	.nlayers = ARRAY_SIZE(atmel_xlcdc_sam9x75_layers),
> +	.layers = atmel_xlcdc_sam9x75_layers,
> +};
> +
>  static const struct of_device_id atmel_hlcdc_of_match[] = {
>  	{
>  		.compatible = "atmel,at91sam9n12-hlcdc",
> @@ -487,6 +580,10 @@ static const struct of_device_id atmel_hlcdc_of_match[] = {
>  		.compatible = "microchip,sam9x60-hlcdc",
>  		.data = &atmel_hlcdc_dc_sam9x60,
>  	},
> +	{
> +		.compatible = "microchip,sam9x75-xlcdc",
> +		.data = &atmel_xlcdc_dc_sam9x75,

Will SAM9X75 XLCDC work only with this patch and the previous one? If not
then, organize the patches such that the SAM9X75 will work when introduced.

> +	},
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, atmel_hlcdc_of_match);


From claudiu.beznea at tuxon.dev  Sat Feb  3 05:00:43 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 3 Feb 2024 15:00:43 +0200
Subject: [PATCH RESEND v7 4/7] drm: atmel_hlcdc: Add support for XLCDC in
 atmel LCD driver
In-Reply-To: <20240129092319.199365-5-manikandan.m@microchip.com>
References: <20240129092319.199365-1-manikandan.m@microchip.com>
 <20240129092319.199365-5-manikandan.m@microchip.com>
Message-ID: <ff4fdb85-f89e-4c51-a99a-79d2e18e73ab@tuxon.dev>



On 29.01.2024 11:23, Manikandan Muralidharan wrote:
> XLCDC in SAM9X7 has different sets of registers and additional
> configuration bits when compared to previous HLCDC IP. Read/write
> operation on the controller registers is now separated using the
> XLCDC status flag and with HLCDC and XLCDC IP specific ops.
> HEO scaling, window resampling, Alpha blending, YUV-to-RGB
> conversion in XLCDC is derived and handled using additional
> configuration bits and registers. Writing one to the Enable fields
> of each layer in LCD_ATTRE is required to reflect the values set
> in Configuration, FBA, Enable registers of each layer.
> 
> Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
> Co-developed-by: Hari Prasath Gujulan Elango <Hari.PrasathGE at microchip.com>
> Signed-off-by: Hari Prasath Gujulan Elango <Hari.PrasathGE at microchip.com>
> Co-developed-by: Durai Manickam KR <durai.manickamkr at microchip.com>
> Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
> ---
>  .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c    |  33 +-
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c  |   6 +
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h  |   3 +
>  .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   | 349 +++++++++++++++---
>  4 files changed, 329 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> index cc5cf4c2faf7..1ac31c0c474a 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> @@ -79,6 +79,7 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
>  	unsigned int mask = ATMEL_HLCDC_CLKDIV_MASK | ATMEL_HLCDC_CLKPOL;
>  	unsigned int cfg = 0;
>  	int div, ret;
> +	bool is_xlcdc = crtc->dc->desc->is_xlcdc;

You may want to keep reverse christmass tree order, with this, though the
mask variable breaks it.

>  
>  	/* get encoder from crtc */
>  	drm_for_each_encoder(en_iter, ddev) {
> @@ -164,10 +165,10 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
>  	state = drm_crtc_state_to_atmel_hlcdc_crtc_state(c->state);
>  	cfg = state->output_mode << 8;
>  
> -	if (adj->flags & DRM_MODE_FLAG_NVSYNC)
> +	if (!is_xlcdc && (adj->flags & DRM_MODE_FLAG_NVSYNC))
>  		cfg |= ATMEL_HLCDC_VSPOL;
>  
> -	if (adj->flags & DRM_MODE_FLAG_NHSYNC)
> +	if (!is_xlcdc && (adj->flags & DRM_MODE_FLAG_NHSYNC))
>  		cfg |= ATMEL_HLCDC_HSPOL;

Instead of checking 2 times the !is_xlcdc you can have on check: e.g.:

if (!is_xlcdc) {
        if (adj->flags & DRM_MODE_FLAG_NVSYNC)
 		cfg |= ATMEL_HLCDC_VSPOL;

	if (adj->flags & DRM_MODE_FLAG_NHSYNC)
 		cfg |= ATMEL_HLCDC_HSPOL;
}

>  
>  	regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5),
> @@ -202,6 +203,20 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,
>  
>  	pm_runtime_get_sync(dev->dev);
>  
> +	if (crtc->dc->desc->is_xlcdc) {
> +		regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_CM);
> +		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +					     !(status & ATMEL_XLCDC_CM),
> +					     10, 1000))
> +			dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
> +
> +		regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_SD);
> +		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +					     status & ATMEL_XLCDC_SD,
> +					     10, 1000))
> +			dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
> +	}
> +
>  	regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_DISP);
>  	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&

Not related to this patch: it may worth implementing the same approach
accross all bits polling instructions in this function.

>  	       (status & ATMEL_HLCDC_DISP))
> @@ -256,6 +271,20 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
>  	       !(status & ATMEL_HLCDC_DISP))
>  		cpu_relax();
>  
> +	if (crtc->dc->desc->is_xlcdc) {
> +		regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_CM);
> +		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +					     status & ATMEL_XLCDC_CM,
> +					     10, 1000))
> +			dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
> +
> +		regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_SD);
> +		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +					     !(status & ATMEL_XLCDC_SD),
> +					     10, 1000))
> +			dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
> +	}
> +
>  	pm_runtime_put_sync(dev->dev);
>  
>  }
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> index d30aec174aa2..18a3a95f94be 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> @@ -58,6 +58,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9n12 = {
>  	.conflicting_output_formats = true,
>  	.nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9n12_layers),
>  	.layers = atmel_hlcdc_at91sam9n12_layers,
> +	.ops = &atmel_hlcdc_ops,
>  };
>  
>  static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
> @@ -151,6 +152,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9x5 = {
>  	.conflicting_output_formats = true,
>  	.nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9x5_layers),
>  	.layers = atmel_hlcdc_at91sam9x5_layers,
> +	.ops = &atmel_hlcdc_ops,
>  };
>  
>  static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
> @@ -269,6 +271,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d3 = {
>  	.conflicting_output_formats = true,
>  	.nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d3_layers),
>  	.layers = atmel_hlcdc_sama5d3_layers,
> +	.ops = &atmel_hlcdc_ops,
>  };
>  
>  static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
> @@ -364,6 +367,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d4 = {
>  	.max_hpw = 0x3ff,
>  	.nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d4_layers),
>  	.layers = atmel_hlcdc_sama5d4_layers,
> +	.ops = &atmel_hlcdc_ops,
>  };
>  
>  static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sam9x60_layers[] = {
> @@ -460,6 +464,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = {
>  	.fixed_clksrc = true,
>  	.nlayers = ARRAY_SIZE(atmel_hlcdc_sam9x60_layers),
>  	.layers = atmel_hlcdc_sam9x60_layers,
> +	.ops = &atmel_hlcdc_ops,
>  };
>  
>  static const struct atmel_hlcdc_layer_desc atmel_xlcdc_sam9x75_layers[] = {
> @@ -553,6 +558,7 @@ static const struct atmel_hlcdc_dc_desc atmel_xlcdc_dc_sam9x75 = {
>  	.is_xlcdc = true,
>  	.nlayers = ARRAY_SIZE(atmel_xlcdc_sam9x75_layers),
>  	.layers = atmel_xlcdc_sam9x75_layers,
> +	.ops = &atmel_xlcdc_ops,
>  };
>  
>  static const struct of_device_id atmel_hlcdc_of_match[] = {
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> index e6b4b0bb11b9..1ef15f2d536c 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> @@ -424,6 +424,9 @@ struct atmel_hlcdc_dc {
>  	} suspend;
>  };
>  
> +extern const struct atmel_lcdc_dc_ops atmel_hlcdc_ops;
> +extern const struct atmel_lcdc_dc_ops atmel_xlcdc_ops;
> +
>  extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats;
>  extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats;
>  
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index daa508504f47..59ddd743ce92 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -282,8 +282,9 @@ atmel_hlcdc_plane_scaler_set_phicoeff(struct atmel_hlcdc_plane *plane,
>  					    coeff_tab[i]);
>  }
>  
> -static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
> -					   struct atmel_hlcdc_plane_state *state)
> +static
> +void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
> +				    struct atmel_hlcdc_plane_state *state)
>  {
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
>  	u32 xfactor, yfactor;
> @@ -330,11 +331,61 @@ static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
>  								     yfactor));
>  }
>  
> +static
> +void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
> +				    struct atmel_hlcdc_plane_state *state)
> +{
> +	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	u32 xfactor, yfactor;
> +
> +	if (!desc->layout.scaler_config)
> +		return;
> +
> +	if (state->crtc_w == state->src_w && state->crtc_h == state->src_h) {
> +		atmel_hlcdc_layer_write_cfg(&plane->layer,
> +					    desc->layout.scaler_config, 0);
> +		return;
> +	}
> +
> +	/* xfactor = round[(2^20 * XMEMSIZE)/XSIZE)] */
> +	xfactor = (u32)(((1 << 20) * state->src_w) / state->crtc_w);
> +
> +	/* yfactor = round[(2^20 * YMEMSIZE)/YSIZE)] */
> +	yfactor = (u32)(((1 << 20) * state->src_h) / state->crtc_h);
> +
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config,
> +				    ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE |
> +				    ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE |
> +				    ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE |
> +				    ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE);
> +
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 1,
> +				    yfactor);
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 3,
> +				    xfactor);
> +
> +	/*
> +	 * With YCbCr 4:2:2 and YCbYcr 4:2:0 window resampling, configuration
> +	 * register LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT is half
> +	 * the value of yfactor and xfactor.
> +	 */
> +	if (state->base.fb->format->format == DRM_FORMAT_YUV420) {
> +		yfactor /= 2;
> +		xfactor /= 2;
> +	}
> +
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 2,
> +				    yfactor);
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 4,
> +				    xfactor);
> +}
> +
>  static void
>  atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
>  				      struct atmel_hlcdc_plane_state *state)
>  {
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
>  
>  	if (desc->layout.size)
>  		atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.size,
> @@ -352,12 +403,12 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
>  					ATMEL_HLCDC_LAYER_POS(state->crtc_x,
>  							      state->crtc_y));
>  
> -	atmel_hlcdc_plane_setup_scaler(plane, state);
> +	dc->desc->ops->plane_setup_scaler(plane, state);
>  }
>  
> -static void
> -atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> -					struct atmel_hlcdc_plane_state *state)
> +static
> +void atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> +					       struct atmel_hlcdc_plane_state *state)
>  {
>  	unsigned int cfg = ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id;
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> @@ -393,6 +444,40 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
>  				    cfg);
>  }
>  
> +static
> +void atmel_xlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> +					       struct atmel_hlcdc_plane_state *state)
> +{
> +	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	const struct drm_format_info *format = state->base.fb->format;
> +	unsigned int cfg;
> +
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, ATMEL_XLCDC_LAYER_DMA_CFG,
> +				    ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id);
> +
> +	cfg = ATMEL_XLCDC_LAYER_DMA | ATMEL_XLCDC_LAYER_REP;
> +
> +	if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) {
> +		/*
> +		 * Alpha Blending bits specific to SAM9X7 SoC
> +		 */
> +		cfg |= ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS |
> +		       ATMEL_XLCDC_LAYER_SFACTA_ONE |
> +		       ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS |
> +		       ATMEL_XLCDC_LAYER_DFACTA_ONE;
> +		if (format->has_alpha)
> +			cfg |= ATMEL_XLCDC_LAYER_A0(0xff);
> +		else
> +			cfg |= ATMEL_XLCDC_LAYER_A0(state->base.alpha);
> +	}
> +
> +	if (state->disc_h && state->disc_w)
> +		cfg |= ATMEL_XLCDC_LAYER_DISCEN;
> +
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.general_config,
> +				    cfg);
> +}
> +
>  static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
>  					struct atmel_hlcdc_plane_state *state)
>  {
> @@ -437,36 +522,55 @@ static void atmel_hlcdc_plane_update_clut(struct atmel_hlcdc_plane *plane,
>  	}
>  }
>  
> +static void update_hlcdc_buffers(struct atmel_hlcdc_plane *plane,
> +				 struct atmel_hlcdc_plane_state *state,
> +				 u32 sr, int i)
> +{
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
> +				    state->dscrs[i]->self);
> +
> +	if (sr & ATMEL_HLCDC_LAYER_EN)
> +		return;
> +
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
> +				    state->dscrs[i]->addr);
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
> +				    state->dscrs[i]->ctrl);
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
> +				    state->dscrs[i]->self);
> +}
> +
> +static void update_xlcdc_buffers(struct atmel_hlcdc_plane *plane,
> +				 struct atmel_hlcdc_plane_state *state,
> +				 u32 sr, int i)
> +{
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_XLCDC_LAYER_PLANE_ADDR(i),
> +				    state->dscrs[i]->addr);
> +}
> +
>  static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
> -					struct atmel_hlcdc_plane_state *state)
> +					     struct atmel_hlcdc_plane_state *state)
>  {
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	u32 sr;
>  	int i;
>  
> -	sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
> +	if (!dc->desc->is_xlcdc)
> +		sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
>  
>  	for (i = 0; i < state->nplanes; i++) {
>  		struct drm_gem_dma_object *gem = drm_fb_dma_get_gem_obj(fb, i);
>  
>  		state->dscrs[i]->addr = gem->dma_addr + state->offsets[i];
>  
> -		atmel_hlcdc_layer_write_reg(&plane->layer,
> -					    ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
> -					    state->dscrs[i]->self);
> -
> -		if (!(sr & ATMEL_HLCDC_LAYER_EN)) {
> -			atmel_hlcdc_layer_write_reg(&plane->layer,
> -					ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
> -					state->dscrs[i]->addr);
> -			atmel_hlcdc_layer_write_reg(&plane->layer,
> -					ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
> -					state->dscrs[i]->ctrl);
> -			atmel_hlcdc_layer_write_reg(&plane->layer,
> -					ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
> -					state->dscrs[i]->self);
> -		}
> +		dc->desc->ops->update_lcdc_buffers(plane, state, sr, i);
>  
>  		if (desc->layout.xstride[i])
>  			atmel_hlcdc_layer_write_cfg(&plane->layer,
> @@ -712,11 +816,8 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
>  	return 0;
>  }
>  
> -static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
> -					     struct drm_atomic_state *state)
> +static void hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
>  {
> -	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
> -
>  	/* Disable interrupts */
>  	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IDR,
>  				    0xffffffff);
> @@ -731,6 +832,70 @@ static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
>  	atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
>  }
>  
> +static void xlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
> +{
> +	/* Disable interrupts */
> +	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IDR,
> +				    0xffffffff);
> +
> +	/* Disable the layer */
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_XLCDC_LAYER_ENR, 0);
> +
> +	/* Clear all pending interrupts */
> +	atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
> +}
> +
> +static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
> +					     struct drm_atomic_state *state)
> +{
> +	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
> +	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
> +
> +	dc->desc->ops->lcdc_atomic_disable(plane);
> +}
> +
> +static void hlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
> +				struct atmel_hlcdc_dc *dc)
> +{
> +	u32 sr;
> +
> +	/* Enable the overrun interrupts. */
> +	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
> +				    ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
> +				    ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
> +				    ATMEL_HLCDC_LAYER_OVR_IRQ(2));
> +
> +	/* Apply the new config at the next SOF event. */
> +	sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
> +	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
> +				    ATMEL_HLCDC_LAYER_UPDATE |
> +				    (sr & ATMEL_HLCDC_LAYER_EN ?
> +				    ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
> +}
> +
> +static void xlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
> +				struct atmel_hlcdc_dc *dc)
> +{
> +	/* Enable the overrun interrupts. */
> +	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IER,
> +				    ATMEL_XLCDC_LAYER_OVR_IRQ(0) |
> +				    ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
> +				    ATMEL_XLCDC_LAYER_OVR_IRQ(2));
> +
> +	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_ENR,
> +				    ATMEL_XLCDC_LAYER_EN);
> +
> +	/*
> +	 * Updating XLCDC_xxxCFGx, XLCDC_xxxFBA and XLCDC_xxxEN,
> +	 * (where xxx indicates each layer) requires writing one to the
> +	 * Update Attribute field for each layer in LCDC_ATTRE register for SAM9X7.
> +	 */
> +	regmap_write(dc->hlcdc->regmap, ATMEL_XLCDC_ATTRE, ATMEL_XLCDC_BASE_UPDATE |
> +		     ATMEL_XLCDC_OVR1_UPDATE | ATMEL_XLCDC_OVR3_UPDATE |
> +		     ATMEL_XLCDC_HEO_UPDATE);
> +}
> +
>  static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
>  					    struct drm_atomic_state *state)
>  {
> @@ -739,7 +904,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
>  	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
>  	struct atmel_hlcdc_plane_state *hstate =
>  			drm_plane_state_to_atmel_hlcdc_plane_state(new_s);
> -	u32 sr;
> +	struct atmel_hlcdc_dc *dc = p->dev->dev_private;
>  
>  	if (!new_s->crtc || !new_s->fb)
>  		return;
> @@ -750,29 +915,63 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
>  	}
>  
>  	atmel_hlcdc_plane_update_pos_and_size(plane, hstate);
> -	atmel_hlcdc_plane_update_general_settings(plane, hstate);
> +	dc->desc->ops->lcdc_update_general_settings(plane, hstate);
>  	atmel_hlcdc_plane_update_format(plane, hstate);
>  	atmel_hlcdc_plane_update_clut(plane, hstate);
>  	atmel_hlcdc_plane_update_buffers(plane, hstate);
>  	atmel_hlcdc_plane_update_disc_area(plane, hstate);
>  
> -	/* Enable the overrun interrupts. */
> -	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
> -				    ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
> -				    ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
> -				    ATMEL_HLCDC_LAYER_OVR_IRQ(2));
> +	dc->desc->ops->lcdc_atomic_update(plane, dc);
> +}
>  
> -	/* Apply the new config at the next SOF event. */
> -	sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
> -	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
> -			ATMEL_HLCDC_LAYER_UPDATE |
> -			(sr & ATMEL_HLCDC_LAYER_EN ?
> -			 ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
> +static void hlcdc_csc_init(struct atmel_hlcdc_plane *plane,
> +			   const struct atmel_hlcdc_layer_desc *desc)
> +{
> +	/*
> +	 * TODO: declare a "yuv-to-rgb-conv-factors" property to let
> +	 * userspace modify these factors (using a BLOB property ?).
> +	 */
> +	static const u32 hlcdc_csc_coeffs[] = {
> +		0x4c900091,
> +		0x7a5f5090,
> +		0x40040890
> +	};
> +
> +	for (int i = 0; i < ARRAY_SIZE(hlcdc_csc_coeffs); i++) {
> +		atmel_hlcdc_layer_write_cfg(&plane->layer,
> +					    desc->layout.csc + i,
> +					    hlcdc_csc_coeffs[i]);
> +	}
> +}
> +
> +static void xlcdc_csc_init(struct atmel_hlcdc_plane *plane,
> +			   const struct atmel_hlcdc_layer_desc *desc)
> +{
> +	/*
> +	 * yuv-to-rgb-conv-factors are now defined from LCDC_HEOCFG16 to
> +	 * LCDC_HEOCFG21 registers in SAM9X7.
> +	 */
> +	static const u32 xlcdc_csc_coeffs[] = {
> +		0x00000488,
> +		0x00000648,
> +		0x1EA00480,
> +		0x00001D28,
> +		0x08100480,
> +		0x00000000,
> +		0x00000007
> +	};
> +
> +	for (int i = 0; i < ARRAY_SIZE(xlcdc_csc_coeffs); i++) {
> +		atmel_hlcdc_layer_write_cfg(&plane->layer,
> +					    desc->layout.csc + i,
> +					    xlcdc_csc_coeffs[i]);
> +	}
>  }
>  
>  static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
>  {
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
>  
>  	if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
>  	    desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
> @@ -796,31 +995,16 @@ static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
>  			return ret;
>  	}
>  
> -	if (desc->layout.csc) {
> -		/*
> -		 * TODO: decare a "yuv-to-rgb-conv-factors" property to let
> -		 * userspace modify these factors (using a BLOB property ?).
> -		 */
> -		atmel_hlcdc_layer_write_cfg(&plane->layer,
> -					    desc->layout.csc,
> -					    0x4c900091);
> -		atmel_hlcdc_layer_write_cfg(&plane->layer,
> -					    desc->layout.csc + 1,
> -					    0x7a5f5090);
> -		atmel_hlcdc_layer_write_cfg(&plane->layer,
> -					    desc->layout.csc + 2,
> -					    0x40040890);
> -	}
> +	if (desc->layout.csc)
> +		dc->desc->ops->lcdc_csc_init(plane, desc);
>  
>  	return 0;
>  }
>  
> -void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
> +static void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
> +			  const struct atmel_hlcdc_layer_desc *desc)
>  {
> -	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> -	u32 isr;
> -
> -	isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
> +	u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
>  
>  	/*
>  	 * There's not much we can do in case of overrun except informing
> @@ -834,6 +1018,51 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
>  			desc->name);
>  }
>  
> +static void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
> +			  const struct atmel_hlcdc_layer_desc *desc)
> +{
> +	u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
> +
> +	/*
> +	 * There's not much we can do in case of overrun except informing
> +	 * the user. However, we are in interrupt context here, hence the
> +	 * use of dev_dbg().
> +	 */
> +	if (isr &
> +	    (ATMEL_XLCDC_LAYER_OVR_IRQ(0) | ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
> +	     ATMEL_XLCDC_LAYER_OVR_IRQ(2)))
> +		dev_dbg(plane->base.dev->dev, "overrun on plane %s\n",
> +			desc->name);
> +}
> +
> +void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
> +{
> +	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
> +
> +	dc->desc->ops->lcdc_irq_dbg(plane, desc);
> +}
> +
> +const struct atmel_lcdc_dc_ops atmel_hlcdc_ops = {
> +	.plane_setup_scaler = atmel_hlcdc_plane_setup_scaler,
> +	.update_lcdc_buffers = update_hlcdc_buffers,
> +	.lcdc_atomic_disable = hlcdc_atomic_disable,
> +	.lcdc_update_general_settings = atmel_hlcdc_plane_update_general_settings,
> +	.lcdc_atomic_update = hlcdc_atomic_update,
> +	.lcdc_csc_init = hlcdc_csc_init,
> +	.lcdc_irq_dbg = hlcdc_irq_dbg,
> +};

All the changes related to HLCDC (this new object, changes in
atmel_hlcdc_dc.{c,h}, hlcdc changes in atmel_hlcdc_plane.c) should go in a
separate patch (I think patch 1 is the good candidate but remove xlcdc
specific changes from there) where you update current code to use this new
object and then the next patches will be XLCDC support.

> +
> +const struct atmel_lcdc_dc_ops atmel_xlcdc_ops = {
> +	.plane_setup_scaler = atmel_xlcdc_plane_setup_scaler,
> +	.update_lcdc_buffers = update_xlcdc_buffers,
> +	.lcdc_atomic_disable = xlcdc_atomic_disable,
> +	.lcdc_update_general_settings = atmel_xlcdc_plane_update_general_settings,
> +	.lcdc_atomic_update = xlcdc_atomic_update,
> +	.lcdc_csc_init = xlcdc_csc_init,
> +	.lcdc_irq_dbg = xlcdc_irq_dbg,
> +};
> +
>  static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
>  	.atomic_check = atmel_hlcdc_plane_atomic_check,
>  	.atomic_update = atmel_hlcdc_plane_atomic_update,


From claudiu.beznea at tuxon.dev  Sat Feb  3 05:00:56 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 3 Feb 2024 15:00:56 +0200
Subject: [PATCH RESEND v7 7/7] drm: atmel-hlcdc: add support for DSI
 output formats
In-Reply-To: <20240129092319.199365-8-manikandan.m@microchip.com>
References: <20240129092319.199365-1-manikandan.m@microchip.com>
 <20240129092319.199365-8-manikandan.m@microchip.com>
Message-ID: <d78559db-65c4-4a1b-9921-4c0217b5e2f7@tuxon.dev>



On 29.01.2024 11:23, Manikandan Muralidharan wrote:
> Add support for the following DPI mode if the encoder type
> is DSI as per the XLCDC IP datasheet:
> - 16BPPCFG1
> - 16BPPCFG2
> - 16BPPCFG3
> - 18BPPCFG1
> - 18BPPCFG2
> - 24BPP
> 
> Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
> [durai.manickamkr at microchip.com: update output format using is_xlcdc flag]
> Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
> ---
>  .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c    | 123 +++++++++++++-----
>  1 file changed, 88 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> index 1899be2eb6a3..6f529769b036 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> @@ -295,11 +295,18 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
>  
>  }
>  
> -#define ATMEL_HLCDC_RGB444_OUTPUT	BIT(0)
> -#define ATMEL_HLCDC_RGB565_OUTPUT	BIT(1)
> -#define ATMEL_HLCDC_RGB666_OUTPUT	BIT(2)
> -#define ATMEL_HLCDC_RGB888_OUTPUT	BIT(3)
> -#define ATMEL_HLCDC_OUTPUT_MODE_MASK	GENMASK(3, 0)
> +#define ATMEL_HLCDC_RGB444_OUTPUT		BIT(0)
> +#define ATMEL_HLCDC_RGB565_OUTPUT		BIT(1)
> +#define ATMEL_HLCDC_RGB666_OUTPUT		BIT(2)
> +#define ATMEL_HLCDC_RGB888_OUTPUT		BIT(3)
> +#define ATMEL_HLCDC_DPI_RGB565C1_OUTPUT		BIT(4)
> +#define ATMEL_HLCDC_DPI_RGB565C2_OUTPUT		BIT(5)
> +#define ATMEL_HLCDC_DPI_RGB565C3_OUTPUT		BIT(6)
> +#define ATMEL_HLCDC_DPI_RGB666C1_OUTPUT		BIT(7)
> +#define ATMEL_HLCDC_DPI_RGB666C2_OUTPUT		BIT(8)
> +#define ATMEL_HLCDC_DPI_RGB888_OUTPUT		BIT(9)
> +#define ATMEL_HLCDC_OUTPUT_MODE_MASK		GENMASK(3, 0)
> +#define ATMEL_XLCDC_OUTPUT_MODE_MASK		GENMASK(9, 0)
>  
>  static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
>  {
> @@ -313,53 +320,99 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
>  	if (!encoder)
>  		encoder = connector->encoder;
>  
> -	switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
> -	case 0:
> -		break;
> -	case MEDIA_BUS_FMT_RGB444_1X12:
> -		return ATMEL_HLCDC_RGB444_OUTPUT;
> -	case MEDIA_BUS_FMT_RGB565_1X16:
> -		return ATMEL_HLCDC_RGB565_OUTPUT;
> -	case MEDIA_BUS_FMT_RGB666_1X18:
> -		return ATMEL_HLCDC_RGB666_OUTPUT;
> -	case MEDIA_BUS_FMT_RGB888_1X24:
> -		return ATMEL_HLCDC_RGB888_OUTPUT;
> -	default:
> -		return -EINVAL;
> -	}
> -
> -	for (j = 0; j < info->num_bus_formats; j++) {
> -		switch (info->bus_formats[j]) {
> -		case MEDIA_BUS_FMT_RGB444_1X12:
> -			supported_fmts |= ATMEL_HLCDC_RGB444_OUTPUT;

To generate less diff here and have a cleaner code you can move all this
DSI specific code in a different function and have here something like:

	if (encoder->encoder_type == DRM_MODE_ENCODER_DSI)
		return atmel_hlcdc_connector_output_dsi();

> +	if (encoder->encoder_type == DRM_MODE_ENCODER_DSI) {
> +		/*
> +		 * atmel-hlcdc to support DSI formats with DSI video pipeline
> +		 * when DRM_MODE_ENCODER_DSI type is set by
> +		 * connector driver component.
> +		 */
> +		switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
> +		case 0:
>  			break;
>  		case MEDIA_BUS_FMT_RGB565_1X16:
> -			supported_fmts |= ATMEL_HLCDC_RGB565_OUTPUT;
> -			break;
> +			return ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
>  		case MEDIA_BUS_FMT_RGB666_1X18:
> -			supported_fmts |= ATMEL_HLCDC_RGB666_OUTPUT;
> -			break;
> +			return ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
> +		case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
> +			return ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
>  		case MEDIA_BUS_FMT_RGB888_1X24:
> -			supported_fmts |= ATMEL_HLCDC_RGB888_OUTPUT;
> -			break;
> +			return ATMEL_HLCDC_DPI_RGB888_OUTPUT;
>  		default:
> +			return -EINVAL;
> +		}
> +
> +		for (j = 0; j < info->num_bus_formats; j++) {
> +			switch (info->bus_formats[j]) {
> +			case MEDIA_BUS_FMT_RGB565_1X16:
> +				supported_fmts |=
> +					ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
> +				break;
> +			case MEDIA_BUS_FMT_RGB666_1X18:
> +				supported_fmts |=
> +					ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
> +				break;
> +			case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
> +				supported_fmts |=
> +					ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
> +				break;
> +			case MEDIA_BUS_FMT_RGB888_1X24:
> +				supported_fmts |=
> +					ATMEL_HLCDC_DPI_RGB888_OUTPUT;
> +				break;
> +			default:
> +				break;
> +			}
> +		}
> +	} else {
> +		switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
> +		case 0:
>  			break;
> +		case MEDIA_BUS_FMT_RGB444_1X12:
> +			return ATMEL_HLCDC_RGB444_OUTPUT;
> +		case MEDIA_BUS_FMT_RGB565_1X16:
> +			return ATMEL_HLCDC_RGB565_OUTPUT;
> +		case MEDIA_BUS_FMT_RGB666_1X18:
> +			return ATMEL_HLCDC_RGB666_OUTPUT;
> +		case MEDIA_BUS_FMT_RGB888_1X24:
> +			return ATMEL_HLCDC_RGB888_OUTPUT;
> +		default:
> +			return -EINVAL;
>  		}
> -	}
>  
> +		for (j = 0; j < info->num_bus_formats; j++) {
> +			switch (info->bus_formats[j]) {
> +			case MEDIA_BUS_FMT_RGB444_1X12:
> +				supported_fmts |= ATMEL_HLCDC_RGB444_OUTPUT;
> +				break;
> +			case MEDIA_BUS_FMT_RGB565_1X16:
> +				supported_fmts |= ATMEL_HLCDC_RGB565_OUTPUT;
> +				break;
> +			case MEDIA_BUS_FMT_RGB666_1X18:
> +				supported_fmts |= ATMEL_HLCDC_RGB666_OUTPUT;
> +				break;
> +			case MEDIA_BUS_FMT_RGB888_1X24:
> +				supported_fmts |= ATMEL_HLCDC_RGB888_OUTPUT;
> +				break;
> +			default:
> +				break;
> +			}
> +		}
> +	}
>  	return supported_fmts;
>  }
>  
>  static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
>  {
> -	unsigned int output_fmts = ATMEL_HLCDC_OUTPUT_MODE_MASK;
> +	unsigned int output_fmts;
>  	struct atmel_hlcdc_crtc_state *hstate;
>  	struct drm_connector_state *cstate;
>  	struct drm_connector *connector;
> -	struct atmel_hlcdc_crtc *crtc;
> +	struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc);

Previous code uses reverse christmass tree order for variable, thus, try to
keep it the same.

>  	int i;
> +	bool is_xlcdc = crtc->dc->desc->is_xlcdc;
>  
> -	crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc);
> +	output_fmts = is_xlcdc ? ATMEL_XLCDC_OUTPUT_MODE_MASK :
> +		      ATMEL_HLCDC_OUTPUT_MODE_MASK;
>  
>  	for_each_new_connector_in_state(state->state, connector, cstate, i) {
>  		unsigned int supported_fmts = 0;
> @@ -380,7 +433,7 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
>  
>  	hstate = drm_crtc_state_to_atmel_hlcdc_crtc_state(state);
>  	hstate->output_mode = fls(output_fmts) - 1;
> -	if (crtc->dc->desc->is_xlcdc) {
> +	if (is_xlcdc) {
>  		/* check if MIPI DPI bit needs to be set */
>  		if (fls(output_fmts) > 3) {
>  			hstate->output_mode -= 4;


From broonie at kernel.org  Sat Feb  3 05:00:40 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 13:00:40 +0000
Subject: [PATCH v2 1/2] arm64/sme: Restore SMCR on exit from suspend
In-Reply-To: <20240203-arm64-sme-resume-v2-0-a1fbaddc4425@kernel.org>
References: <20240203-arm64-sme-resume-v2-0-a1fbaddc4425@kernel.org>
Message-ID: <20240203-arm64-sme-resume-v2-1-a1fbaddc4425@kernel.org>

The fields in SMCR_EL1 reset to an architecturally UNKNOWN value. Since we
do not otherwise manage the traps configured in this register at runtime we
need to reconfigure them after a suspend in case nothing else was kind
enough to preserve them for us.

The vector length will be restored as part of restoring the SME state for
the next SME using task.

Fixes: a1f4ccd25cc2 (arm64/sme: Provide Kconfig for SME)
Reported-by: Jackson Cooper-Driver <Jackson.Cooper-Driver at arm.com>
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h |  2 ++
 arch/arm64/kernel/fpsimd.c      | 14 ++++++++++++++
 arch/arm64/kernel/suspend.c     |  3 +++
 3 files changed, 19 insertions(+)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 50e5f25d3024..7780d343ef08 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -386,6 +386,7 @@ extern void sme_alloc(struct task_struct *task, bool flush);
 extern unsigned int sme_get_vl(void);
 extern int sme_set_current_vl(unsigned long arg);
 extern int sme_get_current_vl(void);
+extern void sme_suspend_exit(void);
 
 /*
  * Return how many bytes of memory are required to store the full SME
@@ -421,6 +422,7 @@ 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; }
+static inline void sme_suspend_exit(void) { }
 
 static inline size_t sme_state_size(struct task_struct const *task)
 {
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a5dc6f764195..8d2a5824d5d3 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1311,6 +1311,20 @@ void __init sme_setup(void)
 		get_sme_default_vl());
 }
 
+void sme_suspend_exit(void)
+{
+	u64 smcr = 0;
+
+	if (!system_supports_sme())
+		return;
+
+	if (system_supports_fa64())
+		smcr |= SMCR_ELx_FA64;
+
+	write_sysreg_s(smcr, SYS_SMCR_EL1);
+	write_sysreg_s(0, SYS_SMPRI_EL1);
+}
+
 #endif /* CONFIG_ARM64_SME */
 
 static void sve_init_regs(void)
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index eca4d0435211..eaaff94329cd 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -12,6 +12,7 @@
 #include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/exec.h>
+#include <asm/fpsimd.h>
 #include <asm/mte.h>
 #include <asm/memory.h>
 #include <asm/mmu_context.h>
@@ -80,6 +81,8 @@ void notrace __cpu_suspend_exit(void)
 	 */
 	spectre_v4_enable_mitigation(NULL);
 
+	sme_suspend_exit();
+
 	/* Restore additional feature-specific configuration */
 	ptrauth_suspend_exit();
 }

-- 
2.30.2



From broonie at kernel.org  Sat Feb  3 05:00:39 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 13:00:39 +0000
Subject: [PATCH v2 0/2] arm64/sme: Fix handling of traps on resume
Message-ID: <20240203-arm64-sme-resume-v2-0-a1fbaddc4425@kernel.org>

The fast model was recently changed to reset system registers to 0 on
resume, exposing the fact that for SME we do not restore the
configuration of traps for extensions that add state.  Fix this.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
Changes in v2:
- Also reinitialise SMPRI_EL1.
- Link to v1: https://lore.kernel.org/r/20240130-arm64-sme-resume-v1-0-0e60ebba18df at kernel.org

---
Mark Brown (2):
      arm64/sme: Restore SMCR on exit from suspend
      arm64/sme: Restore SMCR_EL1.EZT0 on exit from suspend

 arch/arm64/include/asm/fpsimd.h |  2 ++
 arch/arm64/kernel/fpsimd.c      | 16 ++++++++++++++++
 arch/arm64/kernel/suspend.c     |  3 +++
 3 files changed, 21 insertions(+)
---
base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
change-id: 20240129-arm64-sme-resume-3266150292b6

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From broonie at kernel.org  Sat Feb  3 05:00:41 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 03 Feb 2024 13:00:41 +0000
Subject: [PATCH v2 2/2] arm64/sme: Restore SMCR_EL1.EZT0 on exit from
 suspend
In-Reply-To: <20240203-arm64-sme-resume-v2-0-a1fbaddc4425@kernel.org>
References: <20240203-arm64-sme-resume-v2-0-a1fbaddc4425@kernel.org>
Message-ID: <20240203-arm64-sme-resume-v2-2-a1fbaddc4425@kernel.org>

The fields in SMCR_EL1 reset to an architecturally UNKNOWN value. Since we
do not otherwise manage the traps configured in this register at runtime we
need to reconfigure them after a suspend in case nothing else was kind
enough to preserve them for us. Do so for SMCR_EL1.EZT0.

Fixes: d4913eee152d (arm64/sme: Add basic enumeration for SME2)
Reported-by: Jackson Cooper-Driver <Jackson.Cooper-Driver at arm.com>
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 8d2a5824d5d3..7a7c056f0647 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1320,6 +1320,8 @@ void sme_suspend_exit(void)
 
 	if (system_supports_fa64())
 		smcr |= SMCR_ELx_FA64;
+	if (system_supports_sme2())
+		smcr |= SMCR_ELx_EZT0;
 
 	write_sysreg_s(smcr, SYS_SMCR_EL1);
 	write_sysreg_s(0, SYS_SMPRI_EL1);

-- 
2.30.2



From jiri at resnulli.us  Sat Feb  3 05:18:43 2024
From: jiri at resnulli.us (Jiri Pirko)
Date: Sat, 3 Feb 2024 14:18:43 +0100
Subject: [PATCH net] net: stmmac: xgmac: fix a typo of register name in
 DPP safety handling
In-Reply-To: <20240203053133.1129236-1-0x1207@gmail.com>
References: <20240203053133.1129236-1-0x1207@gmail.com>
Message-ID: <Zb49M9fKRR2HeGhR@nanopsycho>

Sat, Feb 03, 2024 at 06:31:33AM CET, 0x1207 at gmail.com wrote:
>DDPP is copied from Synopsys Data book:
>
>DDPP: Disable Data path Parity Protection.
>    When it is 0x0, Data path Parity Protection is enabled.
>    When it is 0x1, Data path Parity Protection is disabled.
>
>The macro name should be XGMAC_DPP_DISABLE.
>
>Fixes: 46eba193d04f ("net: stmmac: xgmac: fix handling of DPP safety error for DMA channels")
>Signed-off-by: Furong Xu <0x1207 at gmail.com>

Looks okay, but this is net-next material.


>---
> drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h      | 2 +-
> drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
>index 5c67a3f89f08..6a2c7d22df1e 100644
>--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
>+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
>@@ -304,7 +304,7 @@
> #define XGMAC_TXCEIE			BIT(0)
> #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
> #define XGMAC_MTL_DPP_CONTROL		0x000010e0
>-#define XGMAC_DDPP_DISABLE		BIT(0)
>+#define XGMAC_DPP_DISABLE		BIT(0)
> #define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
> #define XGMAC_TQS			GENMASK(25, 16)
> #define XGMAC_TQS_SHIFT			16
>diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>index 04d7c4dc2e35..323c57f03c93 100644
>--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>@@ -928,7 +928,7 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
> 	/* 5. Enable Data Path Parity Protection */
> 	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
> 	/* already enabled by default, explicit enable it again */
>-	value &= ~XGMAC_DDPP_DISABLE;
>+	value &= ~XGMAC_DPP_DISABLE;
> 	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
> 
> 	return 0;
>-- 
>2.34.1
>
>


From shawn.gsc at gmail.com  Sat Feb  3 06:13:18 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Sat, 3 Feb 2024 22:13:18 +0800
Subject: [PATCH 00/23] TQMa7x/MBa7x DT fixes
In-Reply-To: <20231218125459.2769733-1-alexander.stein@ew.tq-group.com>
References: <20231218125459.2769733-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240203044123.GG463595@dragon>

On Mon, Dec 18, 2023 at 01:54:36PM +0100, Alexander Stein wrote:
> Hi,
> 
> this series fixes several issues on TQMa7x DT files in various aspects.
> Probably most notabe one is disabling PCIe due to missing support for internal
> PHY refclock.
> 
> Best regards,
> Alexander
> 
> Alexander Stein (23):
>   ARM: dts: imx7-tqma7/mba7: convert fsl,pins to uint32-matrix
>   ARM: dts: imx7[d]-mba7: Move ethernet PHY reset into PHY node
>   ARM: dts: imx7[d]-mba7: disable USB OC on USB host and USB OTG2
>   ARM: dts: imx7[d]-mba7: disable PCIe interface
>   ARM: dts: imx7[d]-mba7: hog Mini PCIe signals
>   ARM: dts: imx7-mba7: Mark gpio-buttons as wakeup-source
>   ARM: dts: imx7-mba7: Enable SNVS power key
>   ARM: dts: imx7-mba7: Add RTC aliases
>   ARM: dts: imx7-mba7: Add SPI1_SS0 as chip select 3
>   ARM: dts: imx7-tqma7: Add i2c bus recovery
>   ARM: dts: imx7-mba7: Add i2c bus recovery
>   ARM: dts: imx7-tqma7: fix EEPROM compatible for SE97BTP
>   ARM: dts: imx7-mba7: Fix iomuxc node names
>   ARM: dts: imx7-tqma7: Fix iomuxc node names
>   ARM: dts: imx7-mba7: restrict usdhc interface modes
>   ARM: dts: imx7-tqma7: restrict usdhc interface modes
>   ARM: dts: imx7-tqma7: remove superfluous status property
>   ARM: dts: imx7-tqma7: mark system data eeprom as read-only
>   ARM: dts: imx7-tqma7: rename node for SE97BTP
>   ARM: dts: imx7d-mba7: Remove USB OTG related properties on USB node
>   ARM: dts: imx7-tqma7: Add missing vcc supply to i2c eeproms
>   ARM: dts: imx7-mba7: Add missing vcc supply to i2c devices
>   ARM: dts: imx7-tqma7: Fix PMIC v33 rail voltage range

Applied all, thanks!


From shawn.gsc at gmail.com  Sat Feb  3 06:15:04 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Sat, 3 Feb 2024 22:15:04 +0800
Subject: [PATCH] arm64: dts: imx8mp: Disable UART4 by default on Data
 Modul i.MX8M Plus eDM SBC
In-Reply-To: <20231220000345.42593-1-marex@denx.de>
References: <20231220000345.42593-1-marex@denx.de>
Message-ID: <20240203141504.GH463595@dragon>

On Wed, Dec 20, 2023 at 01:02:42AM +0100, Marek Vasut wrote:
> UART4 is used as CM7 coprocessor debug UART and may not be accessible from
> Linux in case it is protected by RDC. The RDC protection is set up by the
> platform firmware. UART4 is not used on this platform by Linux. Disable
> UART4 by default to prevent boot hangs, which occur when the RDC protection
> is in place.
> 
> Fixes: 562d222f23f0 ("arm64: dts: imx8mp: Add support for Data Modul i.MX8M Plus eDM SBC")
> Signed-off-by: Marek Vasut <marex at denx.de>

Applied, thanks!


From conor at kernel.org  Sat Feb  3 06:40:19 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 3 Feb 2024 14:40:19 +0000
Subject: [PATCH v2 1/2] dt-bindings: arm: sunxi: Add Sipeed Longan Module
 3H and Longan Pi 3H
In-Reply-To: <20240203122502.1259-2-jszhang@kernel.org>
References: <20240203122502.1259-1-jszhang@kernel.org>
 <20240203122502.1259-2-jszhang@kernel.org>
Message-ID: <20240203-bullfrog-dropout-ce76e339b379@spud>

On Sat, Feb 03, 2024 at 08:25:00PM +0800, Jisheng Zhang wrote:
> Add name & compatible for the Sipeed Longan Module 3H and Longan PI 3H
> board.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Thanks,
Conor.
-------------- 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/20240203/e4596bd4/attachment.sig>

From olsajiri at gmail.com  Sat Feb  3 06:40:24 2024
From: olsajiri at gmail.com (Jiri Olsa)
Date: Sat, 3 Feb 2024 15:40:24 +0100
Subject: [PATCH bpf-next v4 0/3] Annotate kfuncs in .BTF_ids section
In-Reply-To: <Zb12EZt0BAKOPBk/@surya>
References: <cover.1706491398.git.dxu@dxuuu.xyz>
 <Zb12EZt0BAKOPBk/@surya>
Message-ID: <Zb5QWCw3Tg26_MDa@krava>

On Fri, Feb 02, 2024 at 03:09:05PM -0800, Manu Bretelle wrote:
> On Sun, Jan 28, 2024 at 06:24:05PM -0700, Daniel Xu wrote:
> > === Description ===
> > 
> > This is a bpf-treewide change that annotates all kfuncs as such inside
> > .BTF_ids. This annotation eventually allows us to automatically generate
> > kfunc prototypes from bpftool.
> > 
> > We store this metadata inside a yet-unused flags field inside struct
> > btf_id_set8 (thanks Kumar!). pahole will be taught where to look.
> > 
> > More details about the full chain of events are available in commit 3's
> > description.
> > 
> > The accompanying pahole and bpftool changes can be viewed
> > here on these "frozen" branches [0][1].
> > 
> > [0]: https://github.com/danobi/pahole/tree/kfunc_btf-v3-mailed
> > [1]: https://github.com/danobi/linux/tree/kfunc_bpftool-mailed
> 
> 
> I hit a similar issue to [0] on master
> 943b043aeecc ("selftests/bpf: Fix bench runner SIGSEGV")
>  when cross-compiling on x86_64 (LE) to s390x (BE).
> I do have CONFIG_DEBUG_INFO_BTF enable and the issue would not trigger if
> I disabled CONFIG_DEBUG_INFO_BTF (and with the fix mentioned in [0]).
> 
> What seems to happen is that `tools/resolve_btfids` is ran in the context of the
> host endianess and if I printk before the WARN_ON:
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index ef380e546952..a9ed7a1a4936 100644
>   --- a/kernel/bpf/btf.c
>   +++ b/kernel/bpf/btf.c
>   @@ -8128,6 +8128,7 @@ int register_btf_kfunc_id_set(enum bpf_prog_type prog_type,
>            * WARN() for initcall registrations that do not check errors.
>            */
>           if (!(kset->set->flags & BTF_SET8_KFUNCS)) {
>   +        printk("Flag 0x%08X, expected 0x%08X\n", kset->set->flags, BTF_SET8_KFUNCS);
>                   WARN_ON(!kset->owner);
>                   return -EINVAL;
>           }
> 
> the boot logs would show:
>   Flag 0x01000000, expected 0x00000001
> 
> The issue did not happen prior to
> 6f3189f38a3e ("bpf: treewide: Annotate BPF kfuncs in BTF")
> has only 0 was written before.
> 
> It seems [1] will be addressing cross-compilation, but it did not fix it as is
> by just applying on top of master, so probably some of the changes will also need
> to be ported to `tools/include/linux/btf_ids.h`?

the fix in [1] is fixing flags in set8's pairs, but not the global flags

it looks like Viktor's fix should now also swap that as well? like in the
change below on top of Viktor's changes (untested)

jirka


---
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index d01603ef6283..c44d57fec390 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -706,6 +706,8 @@ static int sets_patch(struct object *obj)
 			 * correctly translate everything.
 			 */
 			if (need_bswap) {
+				set8->flags = bswap_32(set8->flags);
+
 				for (i = 0; i < cnt; i++) {
 					set8->pairs[i].flags =
 						bswap_32(set8->pairs[i].flags);



From conor at kernel.org  Sat Feb  3 06:49:50 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 3 Feb 2024 14:49:50 +0000
Subject: [PATCH v4 03/12] dt-bindings: mtd: brcmnand: Add ecc strap
 property
In-Reply-To: <20240203002834.171462-4-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
 <20240203002834.171462-4-william.zhang@broadcom.com>
Message-ID: <20240203-expenses-tarmac-c564bc7ae34f@spud>

On Fri, Feb 02, 2024 at 04:28:24PM -0800, William Zhang wrote:
> Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
> board boot strap for broadband board designs because they do not specify
> ecc setting in dts but rather using the strap setting.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> 
> ---
> 
> Changes in v4:
> - Move ecc strap property to this separate patch and remove some
> non-binding related text from the description
> 
> Changes in v3: None
> Changes in v2: None
> 
>  Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> index d0168d55c73e..2599d902ec3a 100644
> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> @@ -147,6 +147,14 @@ patternProperties:
>            layout.
>          $ref: /schemas/types.yaml#/definitions/uint32
>  
> +      brcm,nand-ecc-use-strap:
> +        description:
> +          This flag indicates the ecc strength and spare area size should
> +          be retrieved from the SoC NAND boot strap setting instead of
> +          nand-ecc-strength and brcm,nand-oob-sector-size or auto detection.

I'm still on the fence about this being overly prescriptive about the
operating systems behaviour. I think it would be good to say why the
strap values are better than those explicitly provided in DT rather than
just saying "these strap values should be used".

> +          This is commonly used by the BCMBCA SoC board design.
> +        $ref: /schemas/types.yaml#/definitions/flag
> +
>      unevaluatedProperties: false
>  
>  allOf:
> -- 
> 2.37.3
> 
-------------- 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/20240203/15daa64f/attachment.sig>

From conor at kernel.org  Sat Feb  3 06:51:01 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 3 Feb 2024 14:51:01 +0000
Subject: [PATCH v4 02/12] dt-bindings: mtd: brcmnand: Add WP pin
 connection property
In-Reply-To: <20240203002834.171462-3-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
 <20240203002834.171462-3-william.zhang@broadcom.com>
Message-ID: <20240203-unselfish-rewire-78cc0d3db0db@spud>

On Fri, Feb 02, 2024 at 04:28:23PM -0800, William Zhang wrote:
> Add brcm,wp-not-connected property to have an option for disabling this
> feature on broadband board design that does not connect WP pin.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Thanks,
Conor.
-------------- 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/20240203/697f1755/attachment.sig>

From p.sakharov at ispras.ru  Sat Feb  3 07:03:21 2024
From: p.sakharov at ispras.ru (Pavel Sakharov)
Date: Sat,  3 Feb 2024 18:03:21 +0300
Subject: [PATCH] stmmac: Fix incorrect dereference in stmmac_*_interrupt()
Message-ID: <20240203150323.1041736-1-p.sakharov@ispras.ru>

If 'dev' is NULL, the 'priv' variable has an incorrect address when
dereferencing calling netdev_err().

Pass 'dev' instead of 'priv->dev" to the function.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Signed-off-by: Pavel Sakharov <p.sakharov at ispras.ru>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 4727f7be4f86..5ab5148013cd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5848,7 +5848,7 @@ static irqreturn_t stmmac_mac_interrupt(int irq, void *dev_id)
 	struct stmmac_priv *priv = netdev_priv(dev);

 	if (unlikely(!dev)) {
-		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
+		netdev_err(dev, "%s: invalid dev pointer\n", __func__);
 		return IRQ_NONE;
 	}

@@ -5868,7 +5868,7 @@ static irqreturn_t stmmac_safety_interrupt(int irq, void *dev_id)
 	struct stmmac_priv *priv = netdev_priv(dev);

 	if (unlikely(!dev)) {
-		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
+		netdev_err(dev, "%s: invalid dev pointer\n", __func__);
 		return IRQ_NONE;
 	}



From lkp at intel.com  Sat Feb  3 07:04:47 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 3 Feb 2024 23:04:47 +0800
Subject: [PATCH v8 2/3] pwm: Add Allwinner's D1/T113-S3/R329 SoCs PWM
 support
In-Reply-To: <20240131125920.2879433-3-privatesub2@gmail.com>
References: <20240131125920.2879433-3-privatesub2@gmail.com>
Message-ID: <202402032222.BiIrD3g4-lkp@intel.com>

Hi Aleksandr,

kernel test robot noticed the following build warnings:

[auto build test WARNING on robh/for-next]
[also build test WARNING on sunxi/sunxi/for-next linus/master v6.8-rc2 next-20240202]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Aleksandr-Shubin/dt-bindings-pwm-Add-binding-for-Allwinner-D1-T113-S3-R329-PWM-controller/20240131-210313
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20240131125920.2879433-3-privatesub2%40gmail.com
patch subject: [PATCH v8 2/3] pwm: Add Allwinner's D1/T113-S3/R329 SoCs PWM support
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20240203/202402032222.BiIrD3g4-lkp at intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240203/202402032222.BiIrD3g4-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402032222.BiIrD3g4-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/pwm/pwm-sun20i.c:47: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
    * SUN20I_PWM_MAGIC is used to quickly compute the values of the clock dividers


vim +47 drivers/pwm/pwm-sun20i.c

    45	
    46	/**
  > 47	 * SUN20I_PWM_MAGIC is used to quickly compute the values of the clock dividers
    48	 * div_m (SUN20I_PWM_CLK_CFG_DIV_M) & prescale_k (SUN20I_PWM_CTL_PRESCAL_K)
    49	 * without using a loop. These dividers limit the # of cycles in a period
    50	 * to SUN20I_PWM_PCNTR_SIZE by applying a scaling factor of
    51	 * 1/(div_m * (prescale_k + 1)) to the clock source.
    52	 *
    53	 * SUN20I_PWM_MAGIC is derived by solving for div_m and prescale_k
    54	 * such that for a given requested period,
    55	 *
    56	 * i) div_m is minimized for any prescale_k ? SUN20I_PWM_CTL_PRESCAL_K_MAX,
    57	 * ii) prescale_k is minimized.
    58	 *
    59	 * The derivation proceeds as follows, with val = # of cycles for reqested
    60	 * period:
    61	 *
    62	 * for a given value of div_m we want the smallest prescale_k such that
    63	 *
    64	 * (val >> div_m) // (prescale_k + 1) ? 65536 (SUN20I_PWM_PCNTR_SIZE)
    65	 *
    66	 * This is equivalent to:
    67	 *
    68	 * (val >> div_m) ? 65536 * (prescale_k + 1) + prescale_k
    69	 * ? (val >> div_m) ? 65537 * prescale_k + 65536
    70	 * ? (val >> div_m) - 65536 ? 65537 * prescale_k
    71	 * ? ((val >> div_m) - 65536) / 65537 ? prescale_k
    72	 *
    73	 * As prescale_k is integer, this becomes
    74	 *
    75	 * ((val >> div_m) - 65536) // 65537 ? prescale_k
    76	 *
    77	 * And is minimized at
    78	 *
    79	 * ((val >> div_m) - 65536) // 65537
    80	 *
    81	 * Now we pick the smallest div_m that satifies prescale_k ? 255
    82	 * (i.e SUN20I_PWM_CTL_PRESCAL_K_MAX),
    83	 *
    84	 * ((val >> div_m) - 65536) // 65537 ? 255
    85	 * ? (val >> div_m) - 65536 ? 255 * 65537 + 65536
    86	 * ? val >> div_m ? 255 * 65537 + 2 * 65536
    87	 * ? val >> div_m < (255 * 65537 + 2 * 65536 + 1)
    88	 * ? div_m = fls((val) / (255 * 65537 + 2 * 65536 + 1))
    89	 *
    90	 * Suggested by Uwe Kleine-K?nig
    91	 */
    92	#define SUN20I_PWM_MAGIC			(255 * 65537 + 2 * 65536 + 1)
    93	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From conor at kernel.org  Sat Feb  3 07:08:59 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 3 Feb 2024 15:08:59 +0000
Subject: [PATCH v4 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240202-add-am64-som-v4-2-5f8b12af5e71@solid-run.com>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
 <20240202-add-am64-som-v4-2-5f8b12af5e71@solid-run.com>
Message-ID: <20240203-prolonged-backfield-c659e0016d70@spud>

Hey,

On Fri, Feb 02, 2024 at 05:10:49PM +0100, Josua Mayer wrote:
> Convert the abracon abx80x rtc text bindings to dt-schema format.
> 
> In addition to the text description reference generic interrupts
> properties and add an example.
> 
> Signed-off-by: Josua Mayer <josua at solid-run.com>
> ---
>  .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ---------
>  .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 74 ++++++++++++++++++++++
>  2 files changed, 74 insertions(+), 31 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
> deleted file mode 100644
> index 2405e35a1bc0..000000000000
> --- a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -Abracon ABX80X I2C ultra low power RTC/Alarm chip
> -
> -The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
> -ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
> -is the superset of ab180x.
> -
> -Required properties:
> -
> - - "compatible": should one of:
> -        "abracon,abx80x"
> -        "abracon,ab0801"
> -        "abracon,ab0803"
> -        "abracon,ab0804"
> -        "abracon,ab0805"
> -        "abracon,ab1801"
> -        "abracon,ab1803"
> -        "abracon,ab1804"
> -        "abracon,ab1805"
> -        "microcrystal,rv1805"
> -	Using "abracon,abx80x" will enable chip autodetection.
> - - "reg": I2C bus address of the device
> -
> -Optional properties:
> -
> -The abx804 and abx805 have a trickle charger that is able to charge the
> -connected battery or supercap. Both the following properties have to be defined
> -and valid to enable charging:
> -
> - - "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
> - - "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
> -                          resistor, the other values are in kOhm.
> diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
> new file mode 100644
> index 000000000000..405b386a54b0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
> @@ -0,0 +1,74 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Abracon ABX80X I2C ultra low power RTC/Alarm chip
> +
> +maintainers:
> +  - devicetree at vger.kernel.org

Ideally you put someone here, not the DT list. Usually the original
author is a good choice, which I think happens to be the subsystem
maintainer... Failing that, the rtc subsystem list is likely a better
choice than the DT one.

> +
> +allOf:
> +  - $ref: rtc.yaml#

> +  - $ref: /schemas/interrupts.yaml#

This should not be need.

> +
> +properties:
> +  compatible:
> +    description:
> +      Select a specific compatible chip.

I'd drop this line.

> +      'abracon,abx80x' has special meaning,
> +      it provides auto-dection based on ID register.

And reword this. The compatible itself does not provide auto-detection,
it's the opposite - the driver must perform auto detection if this
compatible is used.

> +    enum:
> +      - abracon,abx80x
> +      - abracon,ab0801
> +      - abracon,ab0803
> +      - abracon,ab0804
> +      - abracon,ab0805
> +      - abracon,ab1801
> +      - abracon,ab1803
> +      - abracon,ab1804
> +      - abracon,ab1805
> +      - microcrystal,rv1805
> +
> +  reg:
> +    maxItems: 1
> +
> +  abracon,tc-diode:
> +    description:
> +      Trickle-charge diode type.
> +      Required to enable charging backup battery.
> +
> +      Supported are 'standard' diodes with a 0.6V drop
> +      and 'schottky' diodes with a 0.3V drop.
> +    $ref: /schemas/types.yaml#/definitions/string
> +    enum:
> +      - standard
> +      - schottky
> +
> +  abracon,tc-resistor:
> +    description:
> +      Trickle-charge resistor value in kOhm.
> +      Required to enable charging backup battery.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [0, 3, 6, 11]
> +
> +required:
> +  - compatible
> +  - reg
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +
> +    rtc at 69 {
> +        compatible = "abracon,abx80x";
> +        reg = <0x69>;

You'll have to make a "fake" i2c bus here to satisfy the tooling. There
should be lots of examples for how to do this in other rtc bindings.

Thanks,
Conor.

> +        abracon,tc-diode = "schottky";
> +        abracon,tc-resistor = <3>;
> +        interrupt-parent = <&fake_intc0>;
> +        interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
> +    };
> 
> -- 
> 2.35.3
> 
-------------- 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/20240203/4adf6a5f/attachment-0001.sig>

From conor at kernel.org  Sat Feb  3 07:10:50 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 3 Feb 2024 15:10:50 +0000
Subject: [PATCH v4 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240203-prolonged-backfield-c659e0016d70@spud>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
 <20240202-add-am64-som-v4-2-5f8b12af5e71@solid-run.com>
 <20240203-prolonged-backfield-c659e0016d70@spud>
Message-ID: <20240203-tummy-egomaniac-5aba55889a83@spud>

On Sat, Feb 03, 2024 at 03:08:59PM +0000, Conor Dooley wrote:
> Hey,
> 
> On Fri, Feb 02, 2024 at 05:10:49PM +0100, Josua Mayer wrote:
> > Convert the abracon abx80x rtc text bindings to dt-schema format.
> > 
> > In addition to the text description reference generic interrupts
> > properties and add an example.
> > 
> > Signed-off-by: Josua Mayer <josua at solid-run.com>
> > ---
> >  .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ---------
> >  .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 74 ++++++++++++++++++++++
> >  2 files changed, 74 insertions(+), 31 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
> > deleted file mode 100644
> > index 2405e35a1bc0..000000000000
> > --- a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
> > +++ /dev/null
> > @@ -1,31 +0,0 @@
> > -Abracon ABX80X I2C ultra low power RTC/Alarm chip
> > -
> > -The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
> > -ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
> > -is the superset of ab180x.
> > -
> > -Required properties:
> > -
> > - - "compatible": should one of:
> > -        "abracon,abx80x"
> > -        "abracon,ab0801"
> > -        "abracon,ab0803"
> > -        "abracon,ab0804"
> > -        "abracon,ab0805"
> > -        "abracon,ab1801"
> > -        "abracon,ab1803"
> > -        "abracon,ab1804"
> > -        "abracon,ab1805"
> > -        "microcrystal,rv1805"
> > -	Using "abracon,abx80x" will enable chip autodetection.
> > - - "reg": I2C bus address of the device
> > -
> > -Optional properties:
> > -
> > -The abx804 and abx805 have a trickle charger that is able to charge the
> > -connected battery or supercap. Both the following properties have to be defined
> > -and valid to enable charging:
> > -
> > - - "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
> > - - "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
> > -                          resistor, the other values are in kOhm.
> > diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
> > new file mode 100644
> > index 000000000000..405b386a54b0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
> > @@ -0,0 +1,74 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Abracon ABX80X I2C ultra low power RTC/Alarm chip
> > +
> > +maintainers:
> > +  - devicetree at vger.kernel.org
> 
> Ideally you put someone here, not the DT list. Usually the original
> author is a good choice, which I think happens to be the subsystem
> maintainer... Failing that, the rtc subsystem list is likely a better
> choice than the DT one.
> 
> > +
> > +allOf:
> > +  - $ref: rtc.yaml#
> 
> > +  - $ref: /schemas/interrupts.yaml#
> 
> This should not be need.

Ahh I now realise what your intent was here. All you need to do is add
| interrupts:
|   maxItems: 1
to your binding and it should do what you're looking for.
-------------- 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/20240203/667653c6/attachment.sig>

From linux at roeck-us.net  Sat Feb  3 07:13:08 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 3 Feb 2024 07:13:08 -0800
Subject: [PATCH v13 1/3] dt-bindings: hwmon: fan: Add fan binding to
 schema
In-Reply-To: <20240124060705.1342461-2-billy_tsai@aspeedtech.com>
References: <20240124060705.1342461-1-billy_tsai@aspeedtech.com>
 <20240124060705.1342461-2-billy_tsai@aspeedtech.com>
Message-ID: <e1b1c69f-a2ff-4fa5-80a6-3ff0a3de6ce6@roeck-us.net>

On Wed, Jan 24, 2024 at 02:07:03PM +0800, Billy Tsai wrote:
> From: Naresh Solanki <naresh.solanki at 9elements.com>
> 
> Add common fan properties bindings to a schema.
> 
> Bindings for fan controllers can reference the common schema for the
> fan
> 
> child nodes:
> 
>   patternProperties:
>     "^fan@[0-2]":
>       type: object
>       $ref: fan-common.yaml#
>       unevaluatedProperties: false
> 
> Signed-off-by: Naresh Solanki <naresh.solanki at 9elements.com>
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>

v12 of this patch got a Reviewed-by: tag from Rob.
The tag is gone in this version, presumably meaning that there
was a substantial change.

I don't normally do this, but I downloaded v12 and v13 and did not
find a single change. Why did you drop Rob's Reviewed-by: tag ?

Guenter


From linux at roeck-us.net  Sat Feb  3 07:14:58 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 3 Feb 2024 07:14:58 -0800
Subject: [PATCH v1 1/1] hwmon: (aspeed-pwm-tacho) mutex for tach reading
In-Reply-To: <121d888762a1232ef403cf35230ccf7b3887083a.1699007401.git.alexander.hansen@9elements.com>
References: <121d888762a1232ef403cf35230ccf7b3887083a.1699007401.git.alexander.hansen@9elements.com>
Message-ID: <a70d020a-6289-4087-81eb-a4d6ea339b92@roeck-us.net>

On Fri, Nov 03, 2023 at 11:30:55AM +0100, Alexander Hansen wrote:
> From: Loic Prylli <lprylli at netflix.com>
> 
> the ASPEED_PTCR_RESULT Register can only hold the result for a
> single fan input. Adding a mutex to protect the register until the
> reading is done.
> 
> Signed-off-by: Loic Prylli <lprylli at netflix.com>
> Signed-off-by: Alexander Hansen <alexander.hansen at 9elements.com>

Somehow this patch got lost. Sorry for that. Applied.

Guenter


From claudiu.beznea at tuxon.dev  Sat Feb  3 07:46:13 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 3 Feb 2024 17:46:13 +0200
Subject: [PATCH] pwm: atmel: Don't use pwm consumer API
In-Reply-To: <20240129085627.2386470-2-u.kleine-koenig@pengutronix.de>
References: <20240129085627.2386470-2-u.kleine-koenig@pengutronix.de>
Message-ID: <9e5c0d29-dc4e-4864-ab1c-e65bbc25430f@tuxon.dev>



On 29.01.2024 10:56, Uwe Kleine-K?nig wrote:
> Lowlevel driver callbacks are not supposed to use the consumer API
> functions. Currently this works, but with the upcoming locking changes
> this probably results in dead locks.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>

> ---
>  drivers/pwm/pwm-atmel.c | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
> index 47bcc8a3bf9d..26573829e391 100644
> --- a/drivers/pwm/pwm-atmel.c
> +++ b/drivers/pwm/pwm-atmel.c
> @@ -294,19 +294,16 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>  			   const struct pwm_state *state)
>  {
>  	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
> -	struct pwm_state cstate;
>  	unsigned long cprd, cdty;
>  	u32 pres, val;
>  	int ret;
>  
> -	pwm_get_state(pwm, &cstate);
> -
>  	if (state->enabled) {
>  		unsigned long clkrate = clk_get_rate(atmel_pwm->clk);
>  
> -		if (cstate.enabled &&
> -		    cstate.polarity == state->polarity &&
> -		    cstate.period == state->period) {
> +		if (pwm->state.enabled &&
> +		    pwm->state.polarity == state->polarity &&
> +		    pwm->state.period == state->period) {
>  			u32 cmr = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
>  
>  			cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
> @@ -328,7 +325,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>  
>  		atmel_pwm_calculate_cdty(state, clkrate, cprd, pres, &cdty);
>  
> -		if (cstate.enabled) {
> +		if (pwm->state.enabled) {
>  			atmel_pwm_disable(chip, pwm, false);
>  		} else {
>  			ret = clk_enable(atmel_pwm->clk);
> @@ -348,7 +345,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>  		atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
>  		atmel_pwm_set_cprd_cdty(chip, pwm, cprd, cdty);
>  		atmel_pwm_writel(atmel_pwm, PWM_ENA, 1 << pwm->hwpwm);
> -	} else if (cstate.enabled) {
> +	} else if (pwm->state.enabled) {
>  		atmel_pwm_disable(chip, pwm, true);
>  	}
>  


From claudiu.beznea at tuxon.dev  Sat Feb  3 07:47:21 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 3 Feb 2024 17:47:21 +0200
Subject: [PATCH 1/2] pwm: atmel-hlcdc: Fix clock imbalance related to
 suspend support
In-Reply-To: <b51ea92b0a45eff3dc83b08adefd43d930df996c.1706269232.git.u.kleine-koenig@pengutronix.de>
References: <cover.1706269232.git.u.kleine-koenig@pengutronix.de>
 <b51ea92b0a45eff3dc83b08adefd43d930df996c.1706269232.git.u.kleine-koenig@pengutronix.de>
Message-ID: <18179a0b-8ac1-4ec3-9c58-c334356df37d@tuxon.dev>



On 26.01.2024 14:04, Uwe Kleine-K?nig wrote:
> The suspend callback disables the periph clock when the PWM is enabled
> and resume reenables this clock if the PWM was disabled before. Judging
> from the code comment it's suspend that is wrong here. Fix accordingly.
> 
> Fixes: f9bb9da7c09d ("pwm: atmel-hlcdc: Implement the suspend/resume hooks")
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

I don't have the HW to check it but it looks good to me:
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>

> ---
>  drivers/pwm/pwm-atmel-hlcdc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c
> index 3f2c5031a3ba..1f6fc9a9fcf3 100644
> --- a/drivers/pwm/pwm-atmel-hlcdc.c
> +++ b/drivers/pwm/pwm-atmel-hlcdc.c
> @@ -185,7 +185,7 @@ static int atmel_hlcdc_pwm_suspend(struct device *dev)
>  	struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev);
>  
>  	/* Keep the periph clock enabled if the PWM is still running. */
> -	if (pwm_is_enabled(&atmel->chip.pwms[0]))
> +	if (!pwm_is_enabled(&atmel->chip.pwms[0]))
>  		clk_disable_unprepare(atmel->hlcdc->periph_clk);
>  
>  	return 0;


From claudiu.beznea at tuxon.dev  Sat Feb  3 07:47:45 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 3 Feb 2024 17:47:45 +0200
Subject: [PATCH 2/2] pwm: atmel-hlcdc: Don't use pwm consumer API
In-Reply-To: <6e34607828b290cd64ca9f82df40872853069f07.1706269232.git.u.kleine-koenig@pengutronix.de>
References: <cover.1706269232.git.u.kleine-koenig@pengutronix.de>
 <6e34607828b290cd64ca9f82df40872853069f07.1706269232.git.u.kleine-koenig@pengutronix.de>
Message-ID: <9e337e19-9aaf-45c4-b2ee-09f77e1680fd@tuxon.dev>



On 26.01.2024 14:04, Uwe Kleine-K?nig wrote:
> Lowlevel driver callbacks are not supposed to use the consumer API
> functions. Currently this works, but with the upcoming locking changes
> this probably results in dead locks.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>

> ---
>  drivers/pwm/pwm-atmel-hlcdc.c | 12 +++++-------
>  1 file changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c
> index 1f6fc9a9fcf3..2d64af045fc5 100644
> --- a/drivers/pwm/pwm-atmel-hlcdc.c
> +++ b/drivers/pwm/pwm-atmel-hlcdc.c
> @@ -183,9 +183,10 @@ static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_sama5d3_errata = {
>  static int atmel_hlcdc_pwm_suspend(struct device *dev)
>  {
>  	struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev);
> +	struct pwm_device *pwm = &atmel->chip.pwms[0];
>  
>  	/* Keep the periph clock enabled if the PWM is still running. */
> -	if (!pwm_is_enabled(&atmel->chip.pwms[0]))
> +	if (!pwm->state.enabled)
>  		clk_disable_unprepare(atmel->hlcdc->periph_clk);
>  
>  	return 0;
> @@ -194,20 +195,17 @@ static int atmel_hlcdc_pwm_suspend(struct device *dev)
>  static int atmel_hlcdc_pwm_resume(struct device *dev)
>  {
>  	struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev);
> -	struct pwm_state state;
> +	struct pwm_device *pwm = &atmel->chip.pwms[0];
>  	int ret;
>  
> -	pwm_get_state(&atmel->chip.pwms[0], &state);
> -
>  	/* Re-enable the periph clock it was stopped during suspend. */
> -	if (!state.enabled) {
> +	if (!pwm->state.enabled) {
>  		ret = clk_prepare_enable(atmel->hlcdc->periph_clk);
>  		if (ret)
>  			return ret;
>  	}
>  
> -	return atmel_hlcdc_pwm_apply(&atmel->chip, &atmel->chip.pwms[0],
> -				     &state);
> +	return atmel_hlcdc_pwm_apply(&atmel->chip, pwm, &pwm->state);
>  }
>  
>  static DEFINE_SIMPLE_DEV_PM_OPS(atmel_hlcdc_pwm_pm_ops,


From aford173 at gmail.com  Sat Feb  3 08:52:40 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:40 -0600
Subject: [PATCH V8 00/12] soc: imx8mp: Add support for HDMI
Message-ID: <20240203165307.7806-1-aford173@gmail.com>

The i.MX8M Plus has an HDMI controller, but it depends on two
other systems, the Parallel Video Interface (PVI) and the
HDMI PHY from Samsung. The LCDIF controller generates the display
and routes it to the PVI which converts passes the parallel video
to the HDMI bridge.  The HDMI system has a corresponding power
domain controller whose driver was partially written, but the
device tree for it was never applied, so some changes to the
power domain should be harmless because they've not really been
used yet.

This series is adapted from multiple series from Lucas Stach with
edits and suggestions from feedback from various series, but it
since it's difficult to use and test them independently,
I merged them into on unified series.  The version history is a
bit ambiguous since different components were submitted at different
times and had different amount of retries.  In an effort to merge them
I used the highest version attempt.

Adam Ford (3):
  dt-bindings: soc: imx: add missing clock and power-domains to
    imx8mp-hdmi-blk-ctrl
  pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix
    domain
  arm64: defconfig: Enable DRM_IMX8MP_DW_HDMI_BRIDGE as module

Lucas Stach (9):
  dt-bindings: phy: add binding for the i.MX8MP HDMI PHY
  phy: freescale: add Samsung HDMI PHY
  arm64: dts: imx8mp: add HDMI power-domains
  arm64: dts: imx8mp: add HDMI irqsteer
  dt-bindings: display: imx: add binding for i.MX8MP HDMI PVI
  drm/bridge: imx: add driver for HDMI TX Parallel Video Interface
  dt-bindings: display: imx: add binding for i.MX8MP HDMI TX
  drm/bridge: imx: add bridge wrapper driver for i.MX8MP DWC HDMI
  arm64: dts: imx8mp: add HDMI display pipeline

 .../display/bridge/fsl,imx8mp-hdmi-tx.yaml    |  102 ++
 .../display/imx/fsl,imx8mp-hdmi-pvi.yaml      |   84 ++
 .../bindings/phy/fsl,imx8mp-hdmi-phy.yaml     |   62 +
 .../soc/imx/fsl,imx8mp-hdmi-blk-ctrl.yaml     |   22 +-
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     |  145 +++
 arch/arm64/configs/defconfig                  |    1 +
 drivers/gpu/drm/bridge/imx/Kconfig            |   18 +
 drivers/gpu/drm/bridge/imx/Makefile           |    2 +
 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c  |  207 ++++
 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c   |  154 +++
 drivers/phy/freescale/Kconfig                 |    6 +
 drivers/phy/freescale/Makefile                |    1 +
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c  | 1075 +++++++++++++++++
 drivers/pmdomain/imx/imx8mp-blk-ctrl.c        |   10 +-
 14 files changed, 1876 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml
 create mode 100644 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
 create mode 100644 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c
 create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c

-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:41 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:41 -0600
Subject: [PATCH V8 01/12] dt-bindings: phy: add binding for the i.MX8MP HDMI PHY
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-2-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

Add a DT binding for the HDMI PHY found on the i.MX8MP SoC.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
V3:  Removed mintems at the request of Krzysztof and add his
     reviewed-by

V2:  I tried to help move this along, so I took Lucas' patch and
     attempted to apply fixes based on feedback.  I don't have
     all the history, so apologies for that.

     Added phy-cells to the required list and fixed an error due
     to the word 'binding' being in the title.
---
 .../bindings/phy/fsl,imx8mp-hdmi-phy.yaml     | 62 +++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml
new file mode 100644
index 000000000000..c43e86a8c2e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,imx8mp-hdmi-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8MP HDMI PHY
+
+maintainers:
+  - Lucas Stach <l.stach at pengutronix.de>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mp-hdmi-phy
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 0
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: apb
+      - const: ref
+
+  "#phy-cells":
+    const: 0
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - "#phy-cells"
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mp-clock.h>
+    #include <dt-bindings/power/imx8mp-power.h>
+
+    phy at 32fdff00 {
+        compatible = "fsl,imx8mp-hdmi-phy";
+        reg = <0x32fdff00 0x100>;
+        clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+                 <&clk IMX8MP_CLK_HDMI_24M>;
+        clock-names = "apb", "ref";
+        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>;
+        #clock-cells = <0>;
+        #phy-cells = <0>;
+    };
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:42 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:42 -0600
Subject: [PATCH V8 02/12] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-3-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the driver for the Samsung HDMI PHY found on the
i.MX8MP SoC.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
V4:  Make lookup table hex values lower case.

V3:  Re-order the Makefile to keep it alphabetical
     Remove unused defines

V2:  Fixed some whitespace found from checkpatch
     Change error handling when enabling apbclk to use dev_err_probe
     Rebase on Linux-Next

     I (Adam) tried to help move this along, so I took Lucas' patch and
     attempted to apply fixes based on feedback.  I don't have
     all the history, so apologies for that.
---
 drivers/phy/freescale/Kconfig                |    6 +
 drivers/phy/freescale/Makefile               |    1 +
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 1075 ++++++++++++++++++
 3 files changed, 1082 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index 853958fb2c06..5c2b73042dfc 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -35,6 +35,12 @@ config PHY_FSL_IMX8M_PCIE
 	  Enable this to add support for the PCIE PHY as found on
 	  i.MX8M family of SOCs.
 
+config PHY_FSL_SAMSUNG_HDMI_PHY
+	tristate "Samsung HDMI PHY support"
+	depends on OF && HAS_IOMEM
+	help
+	  Enable this to add support for the Samsung HDMI PHY in i.MX8MP.
+
 endif
 
 config PHY_FSL_LYNX_28G
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index cedb328bc4d2..79e5f16d3ce8 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
 obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)	+= phy-fsl-imx8m-pcie.o
 obj-$(CONFIG_PHY_FSL_LYNX_28G)		+= phy-fsl-lynx-28g.o
+obj-$(CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY)  += phy-fsl-samsung-hdmi.o
diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
new file mode 100644
index 000000000000..bf0e2299d00f
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -0,0 +1,1075 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 NXP
+ * Copyright 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#define PHY_REG_33		0x84
+#define  REG33_MODE_SET_DONE	BIT(7)
+#define  REG33_FIX_DA		BIT(1)
+
+#define PHY_REG_34		0x88
+#define  REG34_PHY_READY	BIT(7)
+#define  REG34_PLL_LOCK		BIT(6)
+#define  REG34_PHY_CLK_READY	BIT(5)
+
+
+#define PHY_PLL_REGS_NUM 48
+
+struct phy_config {
+	u32	clk_rate;
+	u8 regs[PHY_PLL_REGS_NUM];
+};
+
+const struct phy_config phy_pll_cfg[] = {
+	{	22250000, {
+			0x00, 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0x15, 0x25, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		23750000, {
+			0x00, 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0x03, 0x25, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		24000000, {
+			0x00, 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0x01, 0x25, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		24024000, {
+			0x00, 0xd1, 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0x00, 0x25, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		25175000, {
+			0x00, 0xd1, 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xf5, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		25200000, {
+			0x00, 0xd1, 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xf4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		26750000, {
+			0x00, 0xd1, 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xe6, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		27000000, {
+			0x00, 0xd1, 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xe4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		27027000, {
+			0x00, 0xd1, 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xe4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		29500000, {
+			0x00, 0xd1, 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xd1, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		30750000, {
+			0x00, 0xd1, 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xc8, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		30888000, {
+			0x00, 0xd1, 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xc7, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		33750000, {
+			0x00, 0xd1, 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xb7, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		35000000, {
+			0x00, 0xd1, 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xb0, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8b, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		36000000, {
+			0x00, 0xd1, 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xab, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8b, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		36036000, {
+			0x00, 0xd1, 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0xab, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8b, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		40000000, {
+			0x00, 0xd1, 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0x9a, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8b, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		43200000, {
+			0x00, 0xd1, 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0x8f, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x89, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		43243200, {
+			0x00, 0xd1, 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0x8f, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x89, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		44500000, {
+			0x00, 0xd1, 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0x8b, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x89, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		47000000, {
+			0x00, 0xd1, 0x62, 0x94, 0x95, 0x82, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0x83, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x89, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		47500000, {
+			0x00, 0xd1, 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x00, 0x82, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x89, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		50349650, {
+			0x00, 0xd1, 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xf5, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		50400000, {
+			0x00, 0xd1, 0x54, 0x70, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xf4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		53250000, {
+			0x00, 0xd1, 0x58, 0x72, 0x84, 0x03, 0x82, 0x41,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xe7, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		53500000, {
+			0x00, 0xd1, 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xe6, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		54000000, {
+			0x00, 0xd1, 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xe4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		54054000, {
+			0x00, 0xd1, 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xe4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		59000000, {
+			0x00, 0xd1, 0x62, 0x74, 0x95, 0x08, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xd1, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		59340659, {
+			0x00, 0xd1, 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xd0, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		59400000, {
+			0x00, 0xd1, 0x63, 0x70, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xcf, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		61500000, {
+			0x00, 0xd1, 0x66, 0x74, 0x82, 0x01, 0x88, 0x45,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xc8, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		63500000, {
+			0x00, 0xd1, 0x69, 0x74, 0x89, 0x08, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xc2, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x87, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		67500000, {
+			0x00, 0xd1, 0x54, 0x52, 0x87, 0x03, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xb7, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		70000000, {
+			0x00, 0xd1, 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xb0, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		72000000, {
+			0x00, 0xd1, 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xab, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		72072000, {
+			0x00, 0xd1, 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xab, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		74176000, {
+			0x00, 0xd1, 0x5d, 0x58, 0xdb, 0xa2, 0x88, 0x41,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xa6, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		74250000, {
+			0x00, 0xd1, 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0xa6, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		78500000, {
+			0x00, 0xd1, 0x62, 0x54, 0x87, 0x01, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0x9d, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		80000000, {
+			0x00, 0xd1, 0x64, 0x50, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0x9a, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		82000000, {
+			0x00, 0xd1, 0x66, 0x54, 0x82, 0x01, 0x88, 0x45,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0x96, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		82500000, {
+			0x00, 0xd1, 0x67, 0x54, 0x88, 0x01, 0x90, 0x49,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0x95, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		89000000, {
+			0x00, 0xd1, 0x70, 0x54, 0x84, 0x83, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0x8b, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		90000000, {
+			0x00, 0xd1, 0x70, 0x54, 0x82, 0x01, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0x89, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x85, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		94000000, {
+			0x00, 0xd1, 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0x83, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		95000000, {
+			0x00, 0xd1, 0x50, 0x31, 0x86, 0x85, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0x82, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		98901099, {
+			0x00, 0xd1, 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0x7d, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		99000000, {
+			0x00, 0xd1, 0x52, 0x32, 0x82, 0x01, 0x88, 0x47,
+			0x4f, 0x30, 0x33, 0x65, 0x10, 0x7d, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		100699300, {
+			0x00, 0xd1, 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xf5, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		100800000, {
+			0x00, 0xd1, 0x54, 0x30, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xf4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		102500000, {
+			0x00, 0xd1, 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xf0, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		104750000, {
+			0x00, 0xd1, 0x57, 0x32, 0x98, 0x07, 0x90, 0x49,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xeb, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		106500000, {
+			0x00, 0xd1, 0x58, 0x32, 0x84, 0x03, 0x82, 0x41,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xe7, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		107000000, {
+			0x00, 0xd1, 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xe6, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		108000000, {
+			0x00, 0xd1, 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xe4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		108108000, {
+			0x00, 0xd1, 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xe4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		118000000, {
+			0x00, 0xd1, 0x62, 0x34, 0x95, 0x08, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xd1, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		118800000, {
+			0x00, 0xd1, 0x63, 0x30, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xcf, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		123000000, {
+			0x00, 0xd1, 0x66, 0x34, 0x82, 0x01, 0x88, 0x45,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xc8, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		127000000, {
+			0x00, 0xd1, 0x69, 0x34, 0x89, 0x08, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xc2, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		135000000, {
+			0x00, 0xd1, 0x70, 0x34, 0x82, 0x01, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xb7, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		135580000, {
+			0x00, 0xd1, 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xb6, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		137520000, {
+			0x00, 0xd1, 0x72, 0x38, 0x99, 0x10, 0x85, 0x41,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xb3, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		138750000, {
+			0x00, 0xd1, 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xb2, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		140000000, {
+			0x00, 0xd1, 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xb0, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		144000000, {
+			0x00, 0xd1, 0x78, 0x30, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xab, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		148352000, {
+			0x00, 0xd1, 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xa6, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		148500000, {
+			0x00, 0xd1, 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xa6, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x83, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		154000000, {
+			0x00, 0xd1, 0x40, 0x18, 0x83, 0x01, 0x00, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0xa0, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		157000000, {
+			0x00, 0xd1, 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0x9d, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		160000000, {
+			0x00, 0xd1, 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0x9a, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		162000000, {
+			0x00, 0xd1, 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0x98, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		164000000, {
+			0x00, 0xd1, 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0x96, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		165000000, {
+			0x00, 0xd1, 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0x95, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		180000000, {
+			0x00, 0xd1, 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0x89, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		185625000, {
+			0x00, 0xd1, 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0x85, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		188000000, {
+			0x00, 0xd1, 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0x83, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		198000000, {
+			0x00, 0xd1, 0x52, 0x12, 0x82, 0x01, 0x88, 0x47,
+			0x4f, 0x30, 0x33, 0x65, 0x20, 0x7d, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		205000000, {
+			0x00, 0xd1, 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b,
+			0x4f, 0x30, 0x33, 0x65, 0x30, 0xf0, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		209500000, {
+			0x00, 0xd1, 0x57, 0x12, 0x98, 0x07, 0x90, 0x49,
+			0x4f, 0x30, 0x33, 0x65, 0x30, 0xeb, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		213000000, {
+			0x00, 0xd1, 0x58, 0x12, 0x84, 0x03, 0x82, 0x41,
+			0x4f, 0x30, 0x33, 0x65, 0x30, 0xe7, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		216000000, {
+			0x00, 0xd1, 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x30, 0xe4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		216216000, {
+			0x00, 0xd1, 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x30, 0xe4, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		237600000, {
+			0x00, 0xd1, 0x63, 0x10, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x30, 0xcf, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		254000000, {
+			0x00, 0xd1, 0x69, 0x14, 0x89, 0x08, 0x80, 0x40,
+			0x4f, 0x30, 0x33, 0x65, 0x30, 0xc2, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		277500000, {
+			0x00, 0xd1, 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d,
+			0x4f, 0x30, 0x33, 0x65, 0x30, 0xb2, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		288000000, {
+			0x00, 0xd1, 0x78, 0x10, 0x00, 0x00, 0x80, 0x00,
+			0x4f, 0x30, 0x33, 0x65, 0x30, 0xab, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	}, {
+		297000000, {
+			0x00, 0xd1, 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45,
+			0x4f, 0x30, 0x33, 0x65, 0x30, 0xa6, 0x24, 0x80,
+			0x6c, 0xf2, 0x67, 0x00, 0x10, 0x81, 0x30, 0x32,
+			0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
+		},
+	},
+};
+
+struct fsl_samsung_hdmi_phy {
+	struct device *dev;
+	void __iomem *regs;
+	struct clk *apbclk;
+	struct clk *refclk;
+
+	/* clk provider */
+	struct clk_hw hw;
+	const struct phy_config *cur_cfg;
+};
+
+static inline struct fsl_samsung_hdmi_phy *
+to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
+{
+	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
+}
+
+static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
+					  const struct phy_config *cfg)
+{
+	int i, ret;
+	u8 val;
+
+	/* HDMI PHY init */
+	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
+
+	for (i = 0; i < PHY_PLL_REGS_NUM; i++)
+		writeb(cfg->regs[i], phy->regs + i * 4);
+
+	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
+
+	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
+					 val & REG34_PLL_LOCK,
+					 50, 20000);
+	if (ret)
+		dev_err(phy->dev, "PLL failed to lock\n");
+
+	return ret;
+}
+
+static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
+
+	if (!phy->cur_cfg)
+		return 74250000;
+
+	return phy->cur_cfg->clk_rate;
+}
+
+static long phy_clk_round_rate(struct clk_hw *hw,
+			       unsigned long rate, unsigned long *parent_rate)
+{
+	int i;
+
+	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
+		if (phy_pll_cfg[i].clk_rate <= rate)
+			return phy_pll_cfg[i].clk_rate;
+
+	return -EINVAL;
+}
+
+static int phy_clk_set_rate(struct clk_hw *hw,
+			    unsigned long rate, unsigned long parent_rate)
+{
+	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
+	int i;
+
+	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
+		if (phy_pll_cfg[i].clk_rate <= rate)
+			break;
+
+	if (i < 0)
+		return -EINVAL;
+
+	phy->cur_cfg = &phy_pll_cfg[i];
+
+	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+}
+
+static const struct clk_ops phy_clk_ops = {
+	.recalc_rate = phy_clk_recalc_rate,
+	.round_rate = phy_clk_round_rate,
+	.set_rate = phy_clk_set_rate,
+};
+
+static int phy_clk_register(struct fsl_samsung_hdmi_phy *phy)
+{
+	struct device *dev = phy->dev;
+	struct device_node *np = dev->of_node;
+	struct clk_init_data init;
+	const char *parent_name;
+	struct clk *phyclk;
+	int ret;
+
+	parent_name = __clk_get_name(phy->refclk);
+
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	init.flags = 0;
+	init.name = "hdmi_pclk";
+	init.ops = &phy_clk_ops;
+
+	phy->hw.init = &init;
+
+	phyclk = devm_clk_register(dev, &phy->hw);
+	if (IS_ERR(phyclk))
+		return dev_err_probe(dev, PTR_ERR(phyclk),
+				     "failed to register clock\n");
+
+	ret = of_clk_add_provider(np, of_clk_src_simple_get, phyclk);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to register clock provider\n");
+
+	return 0;
+}
+
+static int fsl_samsung_hdmi_phy_probe(struct platform_device *pdev)
+{
+	struct fsl_samsung_hdmi_phy *phy;
+	int ret;
+
+	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, phy);
+	phy->dev = &pdev->dev;
+
+	phy->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->regs))
+		return PTR_ERR(phy->regs);
+
+	phy->apbclk = devm_clk_get(phy->dev, "apb");
+	if (IS_ERR(phy->apbclk))
+		return dev_err_probe(phy->dev, PTR_ERR(phy->apbclk),
+				     "failed to get apb clk\n");
+
+	phy->refclk = devm_clk_get(phy->dev, "ref");
+	if (IS_ERR(phy->refclk))
+		return dev_err_probe(phy->dev, PTR_ERR(phy->refclk),
+				     "failed to get ref clk\n");
+
+	ret = clk_prepare_enable(phy->apbclk);
+	if (ret) {
+		dev_err(phy->dev, "failed to enable apbclk\n");
+		return ret;
+	}
+
+	pm_runtime_get_noresume(phy->dev);
+	pm_runtime_set_active(phy->dev);
+	pm_runtime_enable(phy->dev);
+
+	ret = phy_clk_register(phy);
+	if (ret) {
+		dev_err(&pdev->dev, "register clk failed\n");
+		goto register_clk_failed;
+	}
+
+	pm_runtime_put(phy->dev);
+
+	return 0;
+
+register_clk_failed:
+	clk_disable_unprepare(phy->apbclk);
+
+	return ret;
+}
+
+static int fsl_samsung_hdmi_phy_remove(struct platform_device *pdev)
+{
+	of_clk_del_provider(pdev->dev.of_node);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsl_samsung_hdmi_phy_suspend(struct device *dev)
+{
+	struct fsl_samsung_hdmi_phy *phy = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(phy->apbclk);
+
+	return 0;
+}
+
+static int fsl_samsung_hdmi_phy_resume(struct device *dev)
+{
+	struct fsl_samsung_hdmi_phy *phy = dev_get_drvdata(dev);
+	int ret = 0;
+
+	ret = clk_prepare_enable(phy->apbclk);
+	if (ret) {
+		dev_err(phy->dev, "failed to enable apbclk\n");
+		return ret;
+	}
+
+	if (phy->cur_cfg)
+		ret = fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+
+	return ret;
+
+}
+#endif
+
+static const struct dev_pm_ops fsl_samsung_hdmi_phy_pm_ops = {
+	SET_RUNTIME_PM_OPS(fsl_samsung_hdmi_phy_suspend,
+			   fsl_samsung_hdmi_phy_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
+static const struct of_device_id fsl_samsung_hdmi_phy_of_match[] = {
+	{
+		.compatible = "fsl,imx8mp-hdmi-phy",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, fsl_samsung_hdmi_phy_of_match);
+
+static struct platform_driver fsl_samsung_hdmi_phy_driver = {
+	.probe  = fsl_samsung_hdmi_phy_probe,
+	.remove = fsl_samsung_hdmi_phy_remove,
+	.driver = {
+		.name = "fsl-samsung-hdmi-phy",
+		.of_match_table = fsl_samsung_hdmi_phy_of_match,
+		.pm = &fsl_samsung_hdmi_phy_pm_ops,
+	},
+};
+module_platform_driver(fsl_samsung_hdmi_phy_driver);
+
+MODULE_AUTHOR("Sandor Yu <Sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("SAMSUNG HDMI 2.0 Transmitter PHY Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:43 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:43 -0600
Subject: [PATCH V8 03/12] dt-bindings: soc: imx: add missing clock and power-domains to imx8mp-hdmi-blk-ctrl
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-4-aford173@gmail.com>

Per guidance from the NXP downstream kernel, if the clock is
disabled before HDMI/LCDIF probe, LCDIF will not get pixel
clock from HDMI PHY and throw an error:

[CRTC:39:crtc-2] vblank wait timed out
    WARNING: CPU: 2 PID: 9 at drivers/gpu/drm/drm_atomic_helper.c:
        1634 drm_atomic_helper_wait_for_vblanks.part.0+0x23c/0x260

Fix this by adding the fdcc clock to the hdmi_blk_ctrl.  This
should be safe, since neither this power domain nor the dependent
HDMI and LCDIF drivers been enabled or added to the SoC device
tree yet.

According to Sandor Yu from NXP, "the FDCC clock is not for HDMITX
in desgin, but it is part of HDMI domain that needed by HDMITX.
So I think it is reasonable added it to the power domain driver."

The driver also supports two power domains which are missing from the binding
that also fix an issue with resuming from suspend.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V2:  Update commit message to both show error and give a bit more
     background.
     Add missing power domains hdcp and hdrv as pointed out by Marek Vasut
---
 .../soc/imx/fsl,imx8mp-hdmi-blk-ctrl.yaml     | 22 ++++++++++++-------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hdmi-blk-ctrl.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hdmi-blk-ctrl.yaml
index 1be4ce2a45e8..bd1cdaa4f54b 100644
--- a/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hdmi-blk-ctrl.yaml
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hdmi-blk-ctrl.yaml
@@ -27,8 +27,8 @@ properties:
     const: 1
 
   power-domains:
-    minItems: 8
-    maxItems: 8
+    minItems: 10
+    maxItems: 10
 
   power-domain-names:
     items:
@@ -40,10 +40,12 @@ properties:
       - const: trng
       - const: hdmi-tx
       - const: hdmi-tx-phy
+      - const: hdcp
+      - const: hrv
 
   clocks:
-    minItems: 4
-    maxItems: 4
+    minItems: 5
+    maxItems: 5
 
   clock-names:
     items:
@@ -51,6 +53,7 @@ properties:
       - const: axi
       - const: ref_266m
       - const: ref_24m
+      - const: fdcc
 
   interconnects:
     maxItems: 3
@@ -82,12 +85,15 @@ examples:
         clocks = <&clk IMX8MP_CLK_HDMI_APB>,
                  <&clk IMX8MP_CLK_HDMI_ROOT>,
                  <&clk IMX8MP_CLK_HDMI_REF_266M>,
-                 <&clk IMX8MP_CLK_HDMI_24M>;
-        clock-names = "apb", "axi", "ref_266m", "ref_24m";
+                 <&clk IMX8MP_CLK_HDMI_24M>,
+                 <&clk IMX8MP_CLK_HDMI_FDCC_TST>;
+        clock-names = "apb", "axi", "ref_266m", "ref_24m", "fdcc";
         power-domains = <&pgc_hdmimix>, <&pgc_hdmimix>, <&pgc_hdmimix>,
                         <&pgc_hdmimix>, <&pgc_hdmimix>, <&pgc_hdmimix>,
-                        <&pgc_hdmimix>, <&pgc_hdmi_phy>;
+                        <&pgc_hdmimix>, <&pgc_hdmi_phy>,
+                        <&pgc_hdmimix>, <&pgc_hdmimix>;
         power-domain-names = "bus", "irqsteer", "lcdif", "pai", "pvi", "trng",
-                             "hdmi-tx", "hdmi-tx-phy";
+                             "hdmi-tx", "hdmi-tx-phy",
+                             "hdcp", "hrv";
         #power-domain-cells = <1>;
     };
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:44 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:44 -0600
Subject: [PATCH V8 04/12] pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix domain
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-5-aford173@gmail.com>

According to i.MX8MP RM and HDMI ADD, the fdcc clock is part of
hdmi rx verification IP that should not enable for HDMI TX.
But actually if the clock is disabled before HDMI/LCDIF probe,
LCDIF will not get pixel clock from HDMI PHY and print the error
logs:

[CRTC:39:crtc-2] vblank wait timed out
WARNING: CPU: 2 PID: 9 at drivers/gpu/drm/drm_atomic_helper.c:1634 drm_atomic_helper_wait_for_vblanks.part.0+0x23c/0x260

Add fdcc clock to LCDIF and HDMI TX power domains to fix the issue.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Jacky Bai <ping.bai at nxp.com>
Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
---
V2:  No Change
---
 drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
index e488cf79b800..77e889165eed 100644
--- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
+++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
@@ -55,7 +55,7 @@ struct imx8mp_blk_ctrl_domain_data {
 	const char *gpc_name;
 };
 
-#define DOMAIN_MAX_CLKS 2
+#define DOMAIN_MAX_CLKS 3
 #define DOMAIN_MAX_PATHS 3
 
 struct imx8mp_blk_ctrl_domain {
@@ -457,8 +457,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
 	},
 	[IMX8MP_HDMIBLK_PD_LCDIF] = {
 		.name = "hdmiblk-lcdif",
-		.clk_names = (const char *[]){ "axi", "apb" },
-		.num_clks = 2,
+		.clk_names = (const char *[]){ "axi", "apb", "fdcc" },
+		.num_clks = 3,
 		.gpc_name = "lcdif",
 		.path_names = (const char *[]){"lcdif-hdmi"},
 		.num_paths = 1,
@@ -483,8 +483,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
 	},
 	[IMX8MP_HDMIBLK_PD_HDMI_TX] = {
 		.name = "hdmiblk-hdmi-tx",
-		.clk_names = (const char *[]){ "apb", "ref_266m" },
-		.num_clks = 2,
+		.clk_names = (const char *[]){ "apb", "ref_266m", "fdcc" },
+		.num_clks = 3,
 		.gpc_name = "hdmi-tx",
 	},
 	[IMX8MP_HDMIBLK_PD_HDMI_TX_PHY] = {
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:45 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:45 -0600
Subject: [PATCH V8 05/12] arm64: dts: imx8mp: add HDMI power-domains
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-6-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the PGC and HDMI blk-ctrl nodes providing power control for
HDMI subsystem peripherals.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
V2:  Add missing power-domains hdcp and hrv
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 38 +++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 76c73daf546b..5c54073de615 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -836,6 +836,23 @@ pgc_mediamix: power-domain at 10 {
 							 <&clk IMX8MP_CLK_MEDIA_APB_ROOT>;
 					};
 
+					pgc_hdmimix: power-domains at 14 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_HDMIMIX>;
+						clocks = <&clk IMX8MP_CLK_HDMI_ROOT>,
+							 <&clk IMX8MP_CLK_HDMI_APB>;
+						assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>,
+								  <&clk IMX8MP_CLK_HDMI_APB>;
+						assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>,
+									 <&clk IMX8MP_SYS_PLL1_133M>;
+						assigned-clock-rates = <500000000>, <133000000>;
+					};
+
+					pgc_hdmi_phy: power-domains at 15 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_HDMI_PHY>;
+					};
+
 					pgc_mipi_phy2: power-domain at 16 {
 						#power-domain-cells = <0>;
 						reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
@@ -1361,6 +1378,27 @@ eqos: ethernet at 30bf0000 {
 				intf_mode = <&gpr 0x4>;
 				status = "disabled";
 			};
+
+			hdmi_blk_ctrl: blk-ctrl at 32fc0000 {
+				compatible = "fsl,imx8mp-hdmi-blk-ctrl", "syscon";
+				reg = <0x32fc0000 0x23c>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_ROOT>,
+					 <&clk IMX8MP_CLK_HDMI_REF_266M>,
+					 <&clk IMX8MP_CLK_HDMI_24M>,
+					 <&clk IMX8MP_CLK_HDMI_FDCC_TST>;
+				clock-names = "apb", "axi", "ref_266m", "ref_24m", "fdcc";
+				power-domains = <&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmi_phy>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>;
+				power-domain-names = "bus", "irqsteer", "lcdif",
+						     "pai", "pvi", "trng",
+						     "hdmi-tx", "hdmi-tx-phy",
+						     "hdcp", "hrv";
+				#power-domain-cells = <1>;
+			};
 		};
 
 		aips5: bus at 30c00000 {
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:46 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:46 -0600
Subject: [PATCH V8 06/12] arm64: dts: imx8mp: add HDMI irqsteer
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-7-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

The HDMI irqsteer is a secondary interrupt controller within the HDMI
subsystem that maps all HDMI peripheral IRQs into a single upstream
IRQ line.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 5c54073de615..5e51a766f3d9 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1399,6 +1399,19 @@ hdmi_blk_ctrl: blk-ctrl at 32fc0000 {
 						     "hdcp", "hrv";
 				#power-domain-cells = <1>;
 			};
+
+			irqsteer_hdmi: interrupt-controller at 32fc2000 {
+				compatible = "fsl,imx-irqsteer";
+				reg = <0x32fc2000 0x44>;
+				interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				fsl,channel = <1>;
+				fsl,num-irqs = <64>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>;
+				clock-names = "ipg";
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>;
+			};
 		};
 
 		aips5: bus at 30c00000 {
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:47 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:47 -0600
Subject: [PATCH V8 07/12] dt-bindings: display: imx: add binding for i.MX8MP HDMI PVI
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-8-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

Add binding for the i.MX8MP HDMI parallel video interface block.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V8:  Add interrupt-parent

V7:  No Change

V6:  Add s-o-b message for myself (Adam)

V5:  I tried to help move this along, so I took Lucas' patch and
     attempted to apply fixes based on feedback.  I don't have
     all the history, so apologies for that.
     Removed the pipe character from the Description.
     Increased the register size from 0x40 to 0x44.
---
 .../display/imx/fsl,imx8mp-hdmi-pvi.yaml      | 84 +++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml
new file mode 100644
index 000000000000..56da1636014c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx8mp-hdmi-pvi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8MP HDMI Parallel Video Interface
+
+maintainers:
+  - Lucas Stach <l.stach at pengutronix.de>
+
+description:
+  The HDMI parallel video interface is a timing and sync generator block in the
+  i.MX8MP SoC, that sits between the video source and the HDMI TX controller.
+
+properties:
+  compatible:
+    const: fsl,imx8mp-hdmi-pvi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Input from the LCDIF controller.
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Output to the HDMI TX controller.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/imx8mp-power.h>
+
+    display-bridge at 32fc4000 {
+        compatible = "fsl,imx8mp-hdmi-pvi";
+        reg = <0x32fc4000 0x44>;
+        interrupt-parent = <&irqsteer_hdmi>;
+        interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+                pvi_from_lcdif3: endpoint {
+                    remote-endpoint = <&lcdif3_to_pvi>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+                pvi_to_hdmi_tx: endpoint {
+                    remote-endpoint = <&hdmi_tx_from_pvi>;
+                };
+            };
+        };
+    };
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:48 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:48 -0600
Subject: [PATCH V8 08/12] drm/bridge: imx: add driver for HDMI TX Parallel Video Interface
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-9-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This IP block is found in the HDMI subsystem of the i.MX8MP SoC. It has a
full timing generator and can switch between different video sources. On
the i.MX8MP however the only supported source is the LCDIF. The block
just needs to be powered up and told about the polarity of the video
sync signals to act in bypass mode.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v7)
Tested-by: Marek Vasut <marex at denx.de> (v1)
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v7)
Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> (v2)
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com> (v3)
Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
Tested-by: Fabio Estevam <festevam at gmail.com>
Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V8:  No Change

V7:  Re-do some includes to address build issues after rebasing from
     Linux-next

V6:  No change.

V5:  I (Adam) tried to help move this along, so I took Lucas' patch and
     attempted to apply fixes based on feedback.  I don't have
     all the history, so apologies for that.
     No changes from V4 to V5
---
 drivers/gpu/drm/bridge/imx/Kconfig           |   7 +
 drivers/gpu/drm/bridge/imx/Makefile          |   1 +
 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c | 207 +++++++++++++++++++
 3 files changed, 215 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c

diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig
index 5a4f3d58501e..a4d13331e320 100644
--- a/drivers/gpu/drm/bridge/imx/Kconfig
+++ b/drivers/gpu/drm/bridge/imx/Kconfig
@@ -3,6 +3,13 @@ if ARCH_MXC || COMPILE_TEST
 config DRM_IMX_LDB_HELPER
 	tristate
 
+config DRM_IMX8MP_HDMI_PVI
+	tristate "Freescale i.MX8MP HDMI PVI bridge support"
+	depends on OF
+	help
+	  Choose this to enable support for the internal HDMI TX Parallel
+	  Video Interface found on the Freescale i.MX8MP SoC.
+
 config DRM_IMX8QM_LDB
 	tristate "Freescale i.MX8QM LVDS display bridge"
 	depends on OF
diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile
index 2b0c2e44aa1b..e2c2106509fa 100644
--- a/drivers/gpu/drm/bridge/imx/Makefile
+++ b/drivers/gpu/drm/bridge/imx/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_DRM_IMX_LDB_HELPER) += imx-ldb-helper.o
+obj-$(CONFIG_DRM_IMX8MP_HDMI_PVI) += imx8mp-hdmi-pvi.o
 obj-$(CONFIG_DRM_IMX8QM_LDB) += imx8qm-ldb.o
 obj-$(CONFIG_DRM_IMX8QXP_LDB) += imx8qxp-ldb.o
 obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-combiner.o
diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
new file mode 100644
index 000000000000..a76b7669fe8a
--- /dev/null
+++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright (C) 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <linux/bitfield.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#define HTX_PVI_CTRL			0x0
+#define  PVI_CTRL_OP_VSYNC_POL		BIT(18)
+#define  PVI_CTRL_OP_HSYNC_POL		BIT(17)
+#define  PVI_CTRL_OP_DE_POL		BIT(16)
+#define  PVI_CTRL_INP_VSYNC_POL		BIT(14)
+#define  PVI_CTRL_INP_HSYNC_POL		BIT(13)
+#define  PVI_CTRL_INP_DE_POL		BIT(12)
+#define  PVI_CTRL_MODE_MASK		GENMASK(2, 1)
+#define  PVI_CTRL_MODE_LCDIF		2
+#define  PVI_CTRL_EN			BIT(0)
+
+struct imx8mp_hdmi_pvi {
+	struct drm_bridge	bridge;
+	struct device		*dev;
+	struct drm_bridge	*next_bridge;
+	void __iomem		*regs;
+};
+
+static inline struct imx8mp_hdmi_pvi *
+to_imx8mp_hdmi_pvi(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct imx8mp_hdmi_pvi, bridge);
+}
+
+static int imx8mp_hdmi_pvi_bridge_attach(struct drm_bridge *bridge,
+					 enum drm_bridge_attach_flags flags)
+{
+	struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);
+
+	return drm_bridge_attach(bridge->encoder, pvi->next_bridge,
+				 bridge, flags);
+}
+
+static void imx8mp_hdmi_pvi_bridge_enable(struct drm_bridge *bridge,
+					  struct drm_bridge_state *bridge_state)
+{
+	struct drm_atomic_state *state = bridge_state->base.state;
+	struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);
+	struct drm_connector_state *conn_state;
+	const struct drm_display_mode *mode;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector *connector;
+	u32 bus_flags, val;
+
+	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+
+	if (WARN_ON(pm_runtime_resume_and_get(pvi->dev)))
+		return;
+
+	mode = &crtc_state->adjusted_mode;
+
+	val = FIELD_PREP(PVI_CTRL_MODE_MASK, PVI_CTRL_MODE_LCDIF) | PVI_CTRL_EN;
+
+	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+		val |= PVI_CTRL_OP_VSYNC_POL | PVI_CTRL_INP_VSYNC_POL;
+
+	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
+		val |= PVI_CTRL_OP_HSYNC_POL | PVI_CTRL_INP_HSYNC_POL;
+
+	if (pvi->next_bridge->timings)
+		bus_flags = pvi->next_bridge->timings->input_bus_flags;
+	else if (bridge_state)
+		bus_flags = bridge_state->input_bus_cfg.flags;
+
+	if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
+		val |= PVI_CTRL_OP_DE_POL | PVI_CTRL_INP_DE_POL;
+
+	writel(val, pvi->regs + HTX_PVI_CTRL);
+}
+
+static void imx8mp_hdmi_pvi_bridge_disable(struct drm_bridge *bridge,
+					   struct drm_bridge_state *bridge_state)
+{
+	struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);
+
+	writel(0x0, pvi->regs + HTX_PVI_CTRL);
+
+	pm_runtime_put(pvi->dev);
+}
+
+static u32 *
+imx8mp_hdmi_pvi_bridge_get_input_bus_fmts(struct drm_bridge *bridge,
+					  struct drm_bridge_state *bridge_state,
+					  struct drm_crtc_state *crtc_state,
+					  struct drm_connector_state *conn_state,
+					  u32 output_fmt,
+					  unsigned int *num_input_fmts)
+{
+	struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);
+	struct drm_bridge *next_bridge = pvi->next_bridge;
+	struct drm_bridge_state *next_state;
+
+	if (!next_bridge->funcs->atomic_get_input_bus_fmts)
+		return 0;
+
+	next_state = drm_atomic_get_new_bridge_state(crtc_state->state,
+						     next_bridge);
+
+	return next_bridge->funcs->atomic_get_input_bus_fmts(next_bridge,
+							     next_state,
+							     crtc_state,
+							     conn_state,
+							     output_fmt,
+							     num_input_fmts);
+}
+
+static const struct drm_bridge_funcs imx_hdmi_pvi_bridge_funcs = {
+	.attach		= imx8mp_hdmi_pvi_bridge_attach,
+	.atomic_enable	= imx8mp_hdmi_pvi_bridge_enable,
+	.atomic_disable	= imx8mp_hdmi_pvi_bridge_disable,
+	.atomic_get_input_bus_fmts = imx8mp_hdmi_pvi_bridge_get_input_bus_fmts,
+	.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,
+};
+
+static int imx8mp_hdmi_pvi_probe(struct platform_device *pdev)
+{
+	struct device_node *remote;
+	struct imx8mp_hdmi_pvi *pvi;
+
+	pvi = devm_kzalloc(&pdev->dev, sizeof(*pvi), GFP_KERNEL);
+	if (!pvi)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pvi);
+	pvi->dev = &pdev->dev;
+
+	pvi->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(pvi->regs))
+		return PTR_ERR(pvi->regs);
+
+	/* Get the next bridge in the pipeline. */
+	remote = of_graph_get_remote_node(pdev->dev.of_node, 1, -1);
+	if (!remote)
+		return -EINVAL;
+
+	pvi->next_bridge = of_drm_find_bridge(remote);
+	of_node_put(remote);
+
+	if (!pvi->next_bridge)
+		return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
+				     "could not find next bridge\n");
+
+	pm_runtime_enable(&pdev->dev);
+
+	/* Register the bridge. */
+	pvi->bridge.funcs = &imx_hdmi_pvi_bridge_funcs;
+	pvi->bridge.of_node = pdev->dev.of_node;
+	pvi->bridge.timings = pvi->next_bridge->timings;
+
+	drm_bridge_add(&pvi->bridge);
+
+	return 0;
+}
+
+static int imx8mp_hdmi_pvi_remove(struct platform_device *pdev)
+{
+	struct imx8mp_hdmi_pvi *pvi = platform_get_drvdata(pdev);
+
+	drm_bridge_remove(&pvi->bridge);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id imx8mp_hdmi_pvi_match[] = {
+	{
+		.compatible = "fsl,imx8mp-hdmi-pvi",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, imx8mp_hdmi_pvi_match);
+
+static struct platform_driver imx8mp_hdmi_pvi_driver = {
+	.probe	= imx8mp_hdmi_pvi_probe,
+	.remove	= imx8mp_hdmi_pvi_remove,
+	.driver		= {
+		.name = "imx-hdmi-pvi",
+		.of_match_table	= imx8mp_hdmi_pvi_match,
+	},
+};
+module_platform_driver(imx8mp_hdmi_pvi_driver);
+
+MODULE_DESCRIPTION("i.MX8MP HDMI TX Parallel Video Interface bridge driver");
+MODULE_LICENSE("GPL");
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:49 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:49 -0600
Subject: [PATCH V8 09/12] dt-bindings: display: imx: add binding for i.MX8MP HDMI TX
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-10-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

The HDMI TX controller on the i.MX8MP SoC is a Synopsys designware IP
core with a little bit of SoC integration around it.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>

---
V3:  Change name and location to better idenfity as a bridge and
     HDMI 2.0a transmitter

     Fix typos and feedback from Rob and added ports.
---
 .../display/bridge/fsl,imx8mp-hdmi-tx.yaml    | 102 ++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml

diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
new file mode 100644
index 000000000000..3791c9f4ebab
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
@@ -0,0 +1,102 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/fsl,imx8mp-hdmi-tx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8MP DWC HDMI TX Encoder
+
+maintainers:
+  - Lucas Stach <l.stach at pengutronix.de>
+
+description:
+  The i.MX8MP HDMI transmitter is a Synopsys DesignWare
+  HDMI 2.0a TX controller IP.
+
+allOf:
+  - $ref: /schemas/display/bridge/synopsys,dw-hdmi.yaml#
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mp-hdmi-tx
+
+  reg-io-width:
+    const: 1
+
+  clocks:
+    maxItems: 4
+
+  clock-names:
+    items:
+      - const: iahb
+      - const: isfr
+      - const: cec
+      - const: pix
+
+  power-domains:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Parallel RGB input port
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: HDMI output port
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - power-domains
+  - ports
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mp-clock.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/imx8mp-power.h>
+
+    hdmi at 32fd8000 {
+        compatible = "fsl,imx8mp-hdmi-tx";
+        reg = <0x32fd8000 0x7eff>;
+        interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+                 <&clk IMX8MP_CLK_HDMI_REF_266M>,
+                 <&clk IMX8MP_CLK_32K>,
+                 <&hdmi_tx_phy>;
+        clock-names = "iahb", "isfr", "cec", "pix";
+        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
+        reg-io-width = <1>;
+        ports {
+           #address-cells = <1>;
+           #size-cells = <0>;
+           port at 0 {
+             reg = <0>;
+
+             hdmi_tx_from_pvi: endpoint {
+               remote-endpoint = <&pvi_to_hdmi_tx>;
+             };
+          };
+
+          port at 1 {
+            reg = <1>;
+              hdmi_tx_out: endpoint {
+                remote-endpoint = <&hdmi0_con>;
+              };
+          };
+        };
+    };
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:51 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:51 -0600
Subject: [PATCH V8 11/12] arm64: dts: imx8mp: add HDMI display pipeline
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-12-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the DT nodes for all the peripherals that make up the
HDMI display pipeline.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>

---
V2:  I took this from Lucas' original submission with the following:
     Removed extra clock from HDMI-TX since it is now part of the
     power domain
     Added interrupt-parent to PVI
     Changed the name of the HDMI tranmitter to fsl,imx8mp-hdmi-tx
     Added ports to HDMI-tx
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 94 +++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 5e51a766f3d9..e84b4f40e570 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1412,6 +1412,100 @@ irqsteer_hdmi: interrupt-controller at 32fc2000 {
 				clock-names = "ipg";
 				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>;
 			};
+
+			hdmi_pvi: display-bridge at 32fc4000 {
+				compatible = "fsl,imx8mp-hdmi-pvi";
+				reg = <0x32fc4000 0x40>;
+				interrupt-parent = <&irqsteer_hdmi>;
+				interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port at 0 {
+						reg = <0>;
+						pvi_from_lcdif3: endpoint {
+							remote-endpoint = <&lcdif3_to_pvi>;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+						pvi_to_hdmi_tx: endpoint {
+							remote-endpoint = <&hdmi_tx_from_pvi>;
+						};
+					};
+				};
+			};
+
+			lcdif3: display-controller at 32fc6000 {
+				compatible = "fsl,imx8mp-lcdif";
+				reg = <0x32fc6000 0x238>;
+				interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-parent = <&irqsteer_hdmi>;
+				clocks = <&hdmi_tx_phy>,
+					 <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_ROOT>;
+				clock-names = "pix", "axi", "disp_axi";
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_LCDIF>;
+
+				port {
+					lcdif3_to_pvi: endpoint {
+						remote-endpoint = <&pvi_from_lcdif3>;
+					};
+				};
+			};
+
+			hdmi_tx: hdmi at 32fd8000 {
+				compatible = "fsl,imx8mp-hdmi-tx";
+				reg = <0x32fd8000 0x7eff>;
+				interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-parent = <&irqsteer_hdmi>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_REF_266M>,
+					 <&clk IMX8MP_CLK_32K>,
+					 <&hdmi_tx_phy>;
+				clock-names = "iahb", "isfr", "cec", "pix";
+				assigned-clocks = <&clk IMX8MP_CLK_HDMI_REF_266M>;
+				assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>;
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
+				reg-io-width = <1>;
+				status = "disabled";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port at 0 {
+						reg = <0>;
+
+						hdmi_tx_from_pvi: endpoint {
+							remote-endpoint = <&pvi_to_hdmi_tx>;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+						/* Point endpoint to the HDMI connector */
+					};
+				};
+			};
+
+			hdmi_tx_phy: phy at 32fdff00 {
+				compatible = "fsl,imx8mp-hdmi-phy";
+				reg = <0x32fdff00 0x100>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_24M>;
+				clock-names = "apb", "ref";
+				assigned-clocks = <&clk IMX8MP_CLK_HDMI_24M>;
+				assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>;
+				#clock-cells = <0>;
+				#phy-cells = <0>;
+				status = "disabled";
+			};
 		};
 
 		aips5: bus at 30c00000 {
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:50 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:50 -0600
Subject: [PATCH V8 10/12] drm/bridge: imx: add bridge wrapper driver for i.MX8MP DWC HDMI
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-11-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

Add a simple wrapper driver for the DWC HDMI bridge driver that
implements the few bits that are necessary to abstract the i.MX8MP
SoC integration.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Tested-by: Marek Vasut <marex at denx.de>
Tested-by: Adam Ford <aford173 at gmail.com> #imx8mp-beacon
Tested-by: Richard Leitner <richard.leitner at skidata.com>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
Signed-off-by:  Adam Ford <aford173 at gmail.com>

---
v3:  To move this along, I (Adam) took Lucas' V2 and attempted
     to address concerns:

     Changed name to imx8mp-hdmi-tx
     Re-ordered includes to make drm come after linux
     Removed unused variable build warning
     Removed fdcc clock since it's part of the power domain now
     set the phy_force_vendor = true
     Removed comma after sentinel

     Also added suspend/resume functions from Marek Vasut

     Configured Kconfig to select the PVI and PHY automatically
     since the HDMI-tx is useless without the other two components

     I apologize that don't have the version history prior to V2.
---
 drivers/gpu/drm/bridge/imx/Kconfig          |  11 ++
 drivers/gpu/drm/bridge/imx/Makefile         |   1 +
 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c | 154 ++++++++++++++++++++
 3 files changed, 166 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c

diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig
index a4d13331e320..5965e8027529 100644
--- a/drivers/gpu/drm/bridge/imx/Kconfig
+++ b/drivers/gpu/drm/bridge/imx/Kconfig
@@ -3,6 +3,17 @@ if ARCH_MXC || COMPILE_TEST
 config DRM_IMX_LDB_HELPER
 	tristate
 
+config DRM_IMX8MP_DW_HDMI_BRIDGE
+	tristate "Freescale i.MX8MP HDMI-TX bridge support"
+	depends on OF
+	depends on COMMON_CLK
+	select DRM_DW_HDMI
+	select DRM_IMX8MP_HDMI_PVI
+	select PHY_FSL_SAMSUNG_HDMI_PHY
+	help
+	  Choose this to enable support for the internal HDMI encoder found
+	  on the i.MX8MP SoC.
+
 config DRM_IMX8MP_HDMI_PVI
 	tristate "Freescale i.MX8MP HDMI PVI bridge support"
 	depends on OF
diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile
index e2c2106509fa..edb0a7b71b30 100644
--- a/drivers/gpu/drm/bridge/imx/Makefile
+++ b/drivers/gpu/drm/bridge/imx/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_DRM_IMX_LDB_HELPER) += imx-ldb-helper.o
+obj-$(CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE) += imx8mp-hdmi-tx.o
 obj-$(CONFIG_DRM_IMX8MP_HDMI_PVI) += imx8mp-hdmi-pvi.o
 obj-$(CONFIG_DRM_IMX8QM_LDB) += imx8qm-ldb.o
 obj-$(CONFIG_DRM_IMX8QXP_LDB) += imx8qxp-ldb.o
diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c
new file mode 100644
index 000000000000..89fc432ac611
--- /dev/null
+++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright (C) 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
+ */
+
+#include <linux/clk.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <drm/bridge/dw_hdmi.h>
+#include <drm/drm_modes.h>
+
+struct imx8mp_hdmi {
+	struct dw_hdmi_plat_data plat_data;
+	struct dw_hdmi *dw_hdmi;
+	struct clk *pixclk;
+};
+
+static enum drm_mode_status
+imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
+		       const struct drm_display_info *info,
+		       const struct drm_display_mode *mode)
+{
+	struct imx8mp_hdmi *hdmi = (struct imx8mp_hdmi *)data;
+
+	if (mode->clock < 13500)
+		return MODE_CLOCK_LOW;
+
+	if (mode->clock > 297000)
+		return MODE_CLOCK_HIGH;
+
+	if (clk_round_rate(hdmi->pixclk, mode->clock * 1000) !=
+	    mode->clock * 1000)
+		return MODE_CLOCK_RANGE;
+
+	/* We don't support double-clocked and Interlaced modes */
+	if ((mode->flags & DRM_MODE_FLAG_DBLCLK) ||
+	    (mode->flags & DRM_MODE_FLAG_INTERLACE))
+		return MODE_BAD;
+
+	return MODE_OK;
+}
+
+static int imx8mp_hdmi_phy_init(struct dw_hdmi *dw_hdmi, void *data,
+				const struct drm_display_info *display,
+				const struct drm_display_mode *mode)
+{
+	return 0;
+}
+
+static void imx8mp_hdmi_phy_disable(struct dw_hdmi *dw_hdmi, void *data)
+{
+}
+
+static void im8mp_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data)
+{
+	/*
+	 * Just release PHY core from reset, all other power management is done
+	 * by the PHY driver.
+	 */
+	dw_hdmi_phy_gen1_reset(hdmi);
+
+	dw_hdmi_phy_setup_hpd(hdmi, data);
+}
+
+static const struct dw_hdmi_phy_ops imx8mp_hdmi_phy_ops = {
+	.init		= imx8mp_hdmi_phy_init,
+	.disable	= imx8mp_hdmi_phy_disable,
+	.setup_hpd	= im8mp_hdmi_phy_setup_hpd,
+	.read_hpd	= dw_hdmi_phy_read_hpd,
+	.update_hpd	= dw_hdmi_phy_update_hpd,
+};
+
+static int imx8mp_dw_hdmi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct dw_hdmi_plat_data *plat_data;
+	struct imx8mp_hdmi *hdmi;
+
+	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return -ENOMEM;
+
+	plat_data = &hdmi->plat_data;
+
+	hdmi->pixclk = devm_clk_get(dev, "pix");
+	if (IS_ERR(hdmi->pixclk))
+		return dev_err_probe(dev, PTR_ERR(hdmi->pixclk),
+				     "Unable to get pixel clock\n");
+
+	plat_data->mode_valid = imx8mp_hdmi_mode_valid;
+	plat_data->phy_ops = &imx8mp_hdmi_phy_ops;
+	plat_data->phy_name = "SAMSUNG HDMI TX PHY";
+	plat_data->priv_data = hdmi;
+	plat_data->phy_force_vendor = true;
+
+	hdmi->dw_hdmi = dw_hdmi_probe(pdev, plat_data);
+	if (IS_ERR(hdmi->dw_hdmi))
+		return PTR_ERR(hdmi->dw_hdmi);
+
+	platform_set_drvdata(pdev, hdmi);
+
+	return 0;
+}
+
+static int imx8mp_dw_hdmi_remove(struct platform_device *pdev)
+{
+	struct imx8mp_hdmi *hdmi = platform_get_drvdata(pdev);
+
+	dw_hdmi_remove(hdmi->dw_hdmi);
+
+	return 0;
+}
+
+static int __maybe_unused imx8mp_dw_hdmi_pm_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused imx8mp_dw_hdmi_pm_resume(struct device *dev)
+{
+	struct imx8mp_hdmi *hdmi = dev_get_drvdata(dev);
+
+	dw_hdmi_resume(hdmi->dw_hdmi);
+
+	return 0;
+}
+
+static const struct dev_pm_ops imx8mp_dw_hdmi_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(imx8mp_dw_hdmi_pm_suspend,
+				imx8mp_dw_hdmi_pm_resume)
+};
+
+static const struct of_device_id imx8mp_dw_hdmi_of_table[] = {
+	{ .compatible = "fsl,imx8mp-hdmi-tx" },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx8mp_dw_hdmi_of_table);
+
+static struct platform_driver imx8mp_dw_hdmi_platform_driver = {
+	.probe		= imx8mp_dw_hdmi_probe,
+	.remove		= imx8mp_dw_hdmi_remove,
+	.driver		= {
+		.name	= "imx8mp-dw-hdmi-tx",
+		.of_match_table = imx8mp_dw_hdmi_of_table,
+		.pm = &imx8mp_dw_hdmi_pm_ops,
+	},
+};
+
+module_platform_driver(imx8mp_dw_hdmi_platform_driver);
+
+MODULE_DESCRIPTION("i.MX8MP HDMI encoder driver");
+MODULE_LICENSE("GPL");
-- 
2.43.0



From aford173 at gmail.com  Sat Feb  3 08:52:52 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat,  3 Feb 2024 10:52:52 -0600
Subject: [PATCH V8 12/12] arm64: defconfig: Enable DRM_IMX8MP_DW_HDMI_BRIDGE as module
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240203165307.7806-13-aford173@gmail.com>

The i.MX8M Plus has support for an HDMI transmitter.  The
video is genereated by lcdif3, routed to the hdmi parallel
video interface, then fed to a DW HDMI bridge to support
up to 4K video output.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e6cf3e5d63c3..3e33825f0ed7 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -880,6 +880,7 @@ CONFIG_DRM_ANALOGIX_ANX7625=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_DRM_CDNS_MHDP8546=m
+CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE=m
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
 CONFIG_DRM_DW_HDMI_CEC=m
 CONFIG_DRM_IMX_DCSS=m
-- 
2.43.0



From claudiu.beznea at tuxon.dev  Sat Feb  3 08:55:30 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 3 Feb 2024 18:55:30 +0200
Subject: [PATCH 1/8] ARM: dts: microchip: sam9x60_curiosity: Add
 power-supply properties for sdmmc nodes
In-Reply-To: <PH8PR11MB68047F3DD9D23C6749D7F86082742@PH8PR11MB6804.namprd11.prod.outlook.com>
References: <20240123083158.7339-1-mihai.sain@microchip.com>
 <20240123083158.7339-2-mihai.sain@microchip.com>
 <c289a167-031a-44cc-ab62-0fb0adcab2bb@linaro.org>
 <PH8PR11MB68047F3DD9D23C6749D7F86082742@PH8PR11MB6804.namprd11.prod.outlook.com>
Message-ID: <76ccbfd5-ed5e-4443-b741-d7b2e90f6c18@tuxon.dev>

Hi, Mihai,

On 23.01.2024 11:07, Mihai.Sain at microchip.com wrote:
> Hi Krzysztof,
> 
> I'm sorry for quoting (email is sent from Outlook).
> The sdmmc controller from SAM9 MPUs doesn't support the IO voltage signaling/switching required by the UHS sd-card.
> On the electrical schematics of the boards the controller and sd-card power pins are connected to 3V3 regulator.
> On the SAMA5 MPUs there is support for IO voltage switching but since we have issues with the tuning procedure required but the UHS cards,
> we want to keep vqmmc at 3V3 in order to use high-speed mode.

Can you capture this information in each patch description?

> 
> Best regards,
> Mihai Sain
> 
> ----------------------------------------------------------------------
> 
>> diff --git a/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts 
>> b/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
>> index c6fbdd29019f..457c54dde0b7 100644
>> --- a/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
>> +++ b/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
>> @@ -452,6 +452,8 @@ &sdmmc0 {
>>       pinctrl-0 = <&pinctrl_sdmmc0_default &pinctrl_sdmmc0_cd>;
>>       cd-gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
>>       disable-wp;
>> +     vmmc-supply = <&vdd1_3v3>;
>> +     vqmmc-supply = <&vdd1_3v3>;
> 
> For this and all other patches:
> 
> It is surprising that you use the same supply for both. Looks like inaccurate description. It is possible, but I think unlikely because usually VQMMC has lower voltage than 3.3V.
> 
> Best regards,
> Krzysztof
> 


From andrew at lunn.ch  Sat Feb  3 08:56:19 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Sat, 3 Feb 2024 17:56:19 +0100
Subject: [PATCH net-next] net: phy: constify phydev->drv
In-Reply-To: <E1rVxXt-002YqY-9G@rmk-PC.armlinux.org.uk>
References: <E1rVxXt-002YqY-9G@rmk-PC.armlinux.org.uk>
Message-ID: <7f4f7fc2-6bf3-4ecb-9c13-763e2d4f176f@lunn.ch>

On Fri, Feb 02, 2024 at 05:41:45PM +0000, Russell King (Oracle) wrote:
> Device driver structures are shared between all devices that they
> match, and thus nothing should never write to the device driver

nothing should never ???

I guess the never should be ever?

> diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c
> index 7fd9fe6a602b..7b1bc5fcef9b 100644
> --- a/drivers/net/phy/xilinx_gmii2rgmii.c
> +++ b/drivers/net/phy/xilinx_gmii2rgmii.c
> @@ -22,7 +22,7 @@
>  
>  struct gmii2rgmii {
>  	struct phy_device *phy_dev;
> -	struct phy_driver *phy_drv;
> +	const struct phy_driver *phy_drv;
>  	struct phy_driver conv_phy_drv;
>  	struct mdio_device *mdio;
>  };

Did you build testing include xilinx_gmii2rgmii.c ? It does funky
things with phy_driver structures.

Thanks
	Andrew


From ansuelsmth at gmail.com  Sat Feb  3 09:04:14 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Sat, 3 Feb 2024 18:04:14 +0100
Subject: [PATCH net-next] net: phy: constify phydev->drv
In-Reply-To: <7f4f7fc2-6bf3-4ecb-9c13-763e2d4f176f@lunn.ch>
References: <E1rVxXt-002YqY-9G@rmk-PC.armlinux.org.uk>
 <7f4f7fc2-6bf3-4ecb-9c13-763e2d4f176f@lunn.ch>
Message-ID: <65be7212.050a0220.d2de9.e25c@mx.google.com>

On Sat, Feb 03, 2024 at 05:56:19PM +0100, Andrew Lunn wrote:
> On Fri, Feb 02, 2024 at 05:41:45PM +0000, Russell King (Oracle) wrote:
> > Device driver structures are shared between all devices that they
> > match, and thus nothing should never write to the device driver
> 
> nothing should never ???
> 
> I guess the never should be ever?
> 
> > diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c
> > index 7fd9fe6a602b..7b1bc5fcef9b 100644
> > --- a/drivers/net/phy/xilinx_gmii2rgmii.c
> > +++ b/drivers/net/phy/xilinx_gmii2rgmii.c
> > @@ -22,7 +22,7 @@
> >  
> >  struct gmii2rgmii {
> >  	struct phy_device *phy_dev;
> > -	struct phy_driver *phy_drv;
> > +	const struct phy_driver *phy_drv;
> >  	struct phy_driver conv_phy_drv;
> >  	struct mdio_device *mdio;
> >  };
> 
> Did you build testing include xilinx_gmii2rgmii.c ? It does funky
> things with phy_driver structures.
>

Looking at the probe function it seems they only swap phy_drv with
conv_phy_drv but it doesn't seems they touch stuff in the phy_dev
struct. Looks like the thing while hackish, seems clean enough to follow
the rule of not touching the OPs and causing side effects.

-- 
	Ansuel


From andersson at kernel.org  Sat Feb  3 09:06:19 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat,  3 Feb 2024 11:06:19 -0600
Subject: [PATCH] arm64: defconfig: Enable Qualcomm interconnect providers
In-Reply-To: <20240201-enable-icc-8250-2290-v1-1-8ded02750521@quicinc.com>
References: <20240201-enable-icc-8250-2290-v1-1-8ded02750521@quicinc.com>
Message-ID: <170697997761.332807.15662247521680250940.b4-ty@kernel.org>


On Thu, 01 Feb 2024 13:31:19 -0800, Bjorn Andersson wrote:
> With interconnect providers built as modules Qualcomm SM8250 and QCM2290
> platforms launches init without /dev/console being backed by the debug
> UART.
> 
> Build there drivers into the kernel, to make sure the dependencies for
> the UART driver are available and thereby give userspace access to the
> UART without having to re-open the console, once the deferred UART
> driver has probed.
> 
> [...]

Applied, thanks!

[1/1] arm64: defconfig: Enable Qualcomm interconnect providers
      commit: f2eace2b4db5037c617168152c9bfc5421026d3d

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From andersson at kernel.org  Sat Feb  3 09:06:18 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat,  3 Feb 2024 11:06:18 -0600
Subject: (subset) [PATCH v3 0/2] arm64: qcom: sm8650: add support for USB-C Altmode
In-Reply-To: <20240123-topic-sm8650-upstream-altmode-v3-0-300a5ac80e1e@linaro.org>
References: <20240123-topic-sm8650-upstream-altmode-v3-0-300a5ac80e1e@linaro.org>
Message-ID: <170697997764.332807.12206368060165117821.b4-ty@kernel.org>


On Tue, 23 Jan 2024 14:21:14 +0100, Neil Armstrong wrote:
> This adds the missing bits to support Display Port external
> display over the USB-C Altmode support using the Redriver/Retimer
> and WCD939x USBSS Mux/Switch to provide the correct switching.
> 
> 

Applied, thanks!

[1/2] arm64: dts: qcom: sm8650-qrd: add USB-C Altmode Support
      commit: 63b78ca1a7b83113c0147325013746dd2c2992a3

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From christophe.jaillet at wanadoo.fr  Sat Feb  3 09:12:27 2024
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat, 3 Feb 2024 18:12:27 +0100
Subject: [PATCH V8 02/12] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240203165307.7806-3-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-3-aford173@gmail.com>
Message-ID: <9dd39fe9-9e9d-4093-b914-13006ac99792@wanadoo.fr>

Le 03/02/2024 ? 17:52, Adam Ford a ?crit?:
> From: Lucas Stach <l.stach-bIcnvbaLZ9MEGnE8C9+IrQ at public.gmane.org>
> 
> This adds the driver for the Samsung HDMI PHY found on the
> i.MX8MP SoC.
> 
> Signed-off-by: Lucas Stach <l.stach-bIcnvbaLZ9MEGnE8C9+IrQ at public.gmane.org>
> Signed-off-by: Adam Ford <aford173-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org>
> Tested-by: Alexander Stein <alexander.stein-W3o+9BuWjQaZox4op4iWzw at public.gmane.org>
> ---

...

> +static int fsl_samsung_hdmi_phy_probe(struct platform_device *pdev)
> +{
> +	struct fsl_samsung_hdmi_phy *phy;
> +	int ret;
> +
> +	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
> +	if (!phy)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, phy);
> +	phy->dev = &pdev->dev;
> +
> +	phy->regs = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(phy->regs))
> +		return PTR_ERR(phy->regs);
> +
> +	phy->apbclk = devm_clk_get(phy->dev, "apb");
> +	if (IS_ERR(phy->apbclk))
> +		return dev_err_probe(phy->dev, PTR_ERR(phy->apbclk),
> +				     "failed to get apb clk\n");
> +
> +	phy->refclk = devm_clk_get(phy->dev, "ref");
> +	if (IS_ERR(phy->refclk))
> +		return dev_err_probe(phy->dev, PTR_ERR(phy->refclk),
> +				     "failed to get ref clk\n");
> +
> +	ret = clk_prepare_enable(phy->apbclk);
> +	if (ret) {
> +		dev_err(phy->dev, "failed to enable apbclk\n");
> +		return ret;
> +	}
> +
> +	pm_runtime_get_noresume(phy->dev);
> +	pm_runtime_set_active(phy->dev);
> +	pm_runtime_enable(phy->dev);
> +
> +	ret = phy_clk_register(phy);
> +	if (ret) {
> +		dev_err(&pdev->dev, "register clk failed\n");
> +		goto register_clk_failed;
> +	}
> +
> +	pm_runtime_put(phy->dev);
> +
> +	return 0;
> +
> +register_clk_failed:
> +	clk_disable_unprepare(phy->apbclk);
> +
> +	return ret;
> +}
> +
> +static int fsl_samsung_hdmi_phy_remove(struct platform_device *pdev)
> +{
> +	of_clk_del_provider(pdev->dev.of_node);

A clk_disable_unprepare(phy->apbclk) call seems to be missing here.
Or maybe devm_clk_get_enabled() should be used for 'apbclk'?

CJ

> +
> +	return 0;
> +}

...


From linux at armlinux.org.uk  Sat Feb  3 09:23:56 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sat, 3 Feb 2024 17:23:56 +0000
Subject: [PATCH net-next] net: phy: constify phydev->drv
In-Reply-To: <7f4f7fc2-6bf3-4ecb-9c13-763e2d4f176f@lunn.ch>
References: <E1rVxXt-002YqY-9G@rmk-PC.armlinux.org.uk>
 <7f4f7fc2-6bf3-4ecb-9c13-763e2d4f176f@lunn.ch>
Message-ID: <Zb52rPnYmkmqTTr4@shell.armlinux.org.uk>

On Sat, Feb 03, 2024 at 05:56:19PM +0100, Andrew Lunn wrote:
> On Fri, Feb 02, 2024 at 05:41:45PM +0000, Russell King (Oracle) wrote:
> > Device driver structures are shared between all devices that they
> > match, and thus nothing should never write to the device driver
> 
> nothing should never ???
> 
> I guess the never should be ever?

Yes, thanks for spotting that.

> >  struct gmii2rgmii {
> >  	struct phy_device *phy_dev;
> > -	struct phy_driver *phy_drv;
> > +	const struct phy_driver *phy_drv;
> >  	struct phy_driver conv_phy_drv;
> >  	struct mdio_device *mdio;
> >  };
> 
> Did you build testing include xilinx_gmii2rgmii.c ? It does funky
> things with phy_driver structures.

CONFIG_XILINX_GMII2RGMII=m

So yes.

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


From wsa at kernel.org  Sat Feb  3 09:42:19 2024
From: wsa at kernel.org (Wolfram Sang)
Date: Sat, 3 Feb 2024 18:42:19 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: r8a779h0: Add RWDT node
In-Reply-To: <43bb03f3baa87b4be8ce953b1955df6b89387e4c.1706790320.git.geert+renesas@glider.be>
References: <cover.1706790320.git.geert+renesas@glider.be>
 <43bb03f3baa87b4be8ce953b1955df6b89387e4c.1706790320.git.geert+renesas@glider.be>
Message-ID: <Zb56-wfc6emQuXfU@shikoro>

On Thu, Feb 01, 2024 at 03:09:16PM +0100, Geert Uytterhoeven wrote:
> From: Minh Le <minh.le.aj at renesas.com>
> 
> Add a device node for the RCLK Watchdog Timer (RWDT) on the Renesas
> R-Car V4M (R8A779H0) SoC.
> 
> Signed-off-by: Minh Le <minh.le.aj at renesas.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

Reviewed-by: Wolfram Sang <wsa+renesas at sang-engineering.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/20240203/a333a51c/attachment.sig>

From wsa at kernel.org  Sat Feb  3 09:45:58 2024
From: wsa at kernel.org (Wolfram Sang)
Date: Sat, 3 Feb 2024 18:45:58 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: gray-hawk-single: Enable
 watchdog timer
In-Reply-To: <cf6effafd9e0472a457eed9d84a834abc3e1c833.1706790320.git.geert+renesas@glider.be>
References: <cover.1706790320.git.geert+renesas@glider.be>
 <cf6effafd9e0472a457eed9d84a834abc3e1c833.1706790320.git.geert+renesas@glider.be>
Message-ID: <Zb571mpzRXdop0ej@shikoro>

On Thu, Feb 01, 2024 at 03:09:17PM +0100, Geert Uytterhoeven wrote:
> Enable the watchdog timer on the Gray Hawk Single board.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

Reviewed-by: Wolfram Sang <wsa+renesas at sang-engineering.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/20240203/7486bb03/attachment-0001.sig>

From wsa at kernel.org  Sat Feb  3 09:52:49 2024
From: wsa at kernel.org (Wolfram Sang)
Date: Sat, 3 Feb 2024 18:52:49 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: r8a779h0: Add I2C nodes
In-Reply-To: <7dbbe13428273c5786ddff6ea7af6724fcdd4de8.1706796660.git.geert+renesas@glider.be>
References: <cover.1706796660.git.geert+renesas@glider.be>
 <7dbbe13428273c5786ddff6ea7af6724fcdd4de8.1706796660.git.geert+renesas@glider.be>
Message-ID: <Zb59ceHI7FrUqjhg@shikoro>

On Thu, Feb 01, 2024 at 03:14:33PM +0100, Geert Uytterhoeven wrote:
> From: Hai Pham <hai.pham.ud at renesas.com>
> 
> Add device nodes for the I2C Bus Interfaces on the Renesas R-Car V4M
> (R8A779H0) SoC.
> 
> Signed-off-by: Hai Pham <hai.pham.ud at renesas.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

So far so good...

Reviewed-by: Wolfram Sang <wsa+renesas at sang-engineering.com>

I assume DMA nodes are not there yet because you use these nodes for
testing DMA when you enable the DMACs?

-------------- 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/20240203/3784ece3/attachment.sig>

From wsa at kernel.org  Sat Feb  3 09:53:33 2024
From: wsa at kernel.org (Wolfram Sang)
Date: Sat, 3 Feb 2024 18:53:33 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: gray-hawk-single: Add I2C0 and
 EEPROMs
In-Reply-To: <960595394a274b675f1ec9ec1c324e4cc1ac1f77.1706796660.git.geert+renesas@glider.be>
References: <cover.1706796660.git.geert+renesas@glider.be>
 <960595394a274b675f1ec9ec1c324e4cc1ac1f77.1706796660.git.geert+renesas@glider.be>
Message-ID: <Zb59ne5Y4YJZ_RlT@shikoro>

On Thu, Feb 01, 2024 at 03:14:34PM +0100, Geert Uytterhoeven wrote:
> Enable the I2C0 bus on the Gray Hawk Single board, and describe the I2C
> EEPROMs present.
> 
> Based on patches for Gray Hawk in the BSP by Hai Pham.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

Reviewed-by: Wolfram Sang <wsa+renesas at sang-engineering.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/20240203/78c57553/attachment.sig>

From chantr4 at gmail.com  Sat Feb  3 10:45:11 2024
From: chantr4 at gmail.com (Manu Bretelle)
Date: Sat, 3 Feb 2024 10:45:11 -0800
Subject: [PATCH bpf-next v4 0/3] Annotate kfuncs in .BTF_ids section
In-Reply-To: <Zb5QWCw3Tg26_MDa@krava>
References: <cover.1706491398.git.dxu@dxuuu.xyz>
 <Zb12EZt0BAKOPBk/@surya>
 <Zb5QWCw3Tg26_MDa@krava>
Message-ID: <Zb6Jt30bNcNhM6zR@surya>

On Sat, Feb 03, 2024 at 03:40:24PM +0100, Jiri Olsa wrote:
> On Fri, Feb 02, 2024 at 03:09:05PM -0800, Manu Bretelle wrote:
> > On Sun, Jan 28, 2024 at 06:24:05PM -0700, Daniel Xu wrote:
> > > === Description ===
> > > 
> > > This is a bpf-treewide change that annotates all kfuncs as such inside
> > > .BTF_ids. This annotation eventually allows us to automatically generate
> > > kfunc prototypes from bpftool.
> > > 
> > > We store this metadata inside a yet-unused flags field inside struct
> > > btf_id_set8 (thanks Kumar!). pahole will be taught where to look.
> > > 
> > > More details about the full chain of events are available in commit 3's
> > > description.
> > > 
> > > The accompanying pahole and bpftool changes can be viewed
> > > here on these "frozen" branches [0][1].
> > > 
> > > [0]: https://github.com/danobi/pahole/tree/kfunc_btf-v3-mailed
> > > [1]: https://github.com/danobi/linux/tree/kfunc_bpftool-mailed
> > 
> > 
> > I hit a similar issue to [0] on master
> > 943b043aeecc ("selftests/bpf: Fix bench runner SIGSEGV")
> >  when cross-compiling on x86_64 (LE) to s390x (BE).
> > I do have CONFIG_DEBUG_INFO_BTF enable and the issue would not trigger if
> > I disabled CONFIG_DEBUG_INFO_BTF (and with the fix mentioned in [0]).
> > 
> > What seems to happen is that `tools/resolve_btfids` is ran in the context of the
> > host endianess and if I printk before the WARN_ON:
> > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> > index ef380e546952..a9ed7a1a4936 100644
> >   --- a/kernel/bpf/btf.c
> >   +++ b/kernel/bpf/btf.c
> >   @@ -8128,6 +8128,7 @@ int register_btf_kfunc_id_set(enum bpf_prog_type prog_type,
> >            * WARN() for initcall registrations that do not check errors.
> >            */
> >           if (!(kset->set->flags & BTF_SET8_KFUNCS)) {
> >   +        printk("Flag 0x%08X, expected 0x%08X\n", kset->set->flags, BTF_SET8_KFUNCS);
> >                   WARN_ON(!kset->owner);
> >                   return -EINVAL;
> >           }
> > 
> > the boot logs would show:
> >   Flag 0x01000000, expected 0x00000001
> > 
> > The issue did not happen prior to
> > 6f3189f38a3e ("bpf: treewide: Annotate BPF kfuncs in BTF")
> > has only 0 was written before.
> > 
> > It seems [1] will be addressing cross-compilation, but it did not fix it as is
> > by just applying on top of master, so probably some of the changes will also need
> > to be ported to `tools/include/linux/btf_ids.h`?
> 
> the fix in [1] is fixing flags in set8's pairs, but not the global flags
> 
> it looks like Viktor's fix should now also swap that as well? like in the
> change below on top of Viktor's changes (untested)
> 
> jirka
> 
> 
> ---
> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> index d01603ef6283..c44d57fec390 100644
> --- a/tools/bpf/resolve_btfids/main.c
> +++ b/tools/bpf/resolve_btfids/main.c
> @@ -706,6 +706,8 @@ static int sets_patch(struct object *obj)
>  			 * correctly translate everything.
>  			 */
>  			if (need_bswap) {
> +				set8->flags = bswap_32(set8->flags);
> +
>  				for (i = 0; i < cnt; i++) {
>  					set8->pairs[i].flags =
>  						bswap_32(set8->pairs[i].flags);
> 

That should work. Here are a few tests I ran:

$ md5sum /tmp/kbuild-s390x/vmlinux.*
eb658e51e089f3c5b2c8909a29dc9997  /tmp/kbuild-s390x/vmlinux.a
# plain vmlinux before running resolv_btfids (all 0s)
ea907cd46a1a73b8276b5f2a82af00ca  /tmp/kbuild-s390x/vmlinux.before_resolv
# x86_64 resolv_btfids on master without Viktor's patch
980a40c3a3ff563d1c2d1ebdd5071a23  /tmp/kbuild-s390x/vmlinux.resolv_native
# x86_64 resolv_btfids on master with Viktor's patch
b986d19e242719ebea41c578235da662  /tmp/kbuild-s390x/vmlinux.resolv_native_patch_viktor
# x86_64 resolv_btfids on master with Viktor's patch and your suggested patch
4edd8752ff01129945bd442689b1927b  /tmp/kbuild-s390x/vmlinux.resolv_native_patch_viktor_patched
# s390x resolv_btfids run with qemu-s390x-static
4edd8752ff01129945bd442689b1927b  /tmp/kbuild-s390x/vmlinux.resolv_s390x


and some hexdiff of those binaries:


# difference between master's native build and s390x build.... has byte swapping for set8 and others
diff -ruN <(xxd /tmp/kbuild-s390x/vmlinux.resolv_s390x) <(xxd /tmp/kbuild-s390x/vmlinux.resolv_native) > diff_s390x_native.diff
https://gist.github.com/chantra/c3d58637a08a6f7340953dc155bb18cc

# difference betwee Viktor's version and  s390x build.... squinting my eyes I only see the global set8 is missing
diff -ruN <(xxd /tmp/kbuild-s390x/vmlinux.resolv_s390x) <(xxd /tmp/kbuild-s390x/vmlinux.resolv_native_patch_viktor) > diff_s390x_native_viktor.diff
https://gist.github.com/chantra/61cfff02b456ae72d3c0161ce1897097

Have a good weekend all!

Manu


From petr at tesarici.cz  Sat Feb  3 11:09:27 2024
From: petr at tesarici.cz (Petr Tesarik)
Date: Sat,  3 Feb 2024 20:09:27 +0100
Subject: [PATCH net v3] net: stmmac: protect updates of 64-bit statistics counters
Message-ID: <20240203190927.19669-1-petr@tesarici.cz>

As explained by a comment in <linux/u64_stats_sync.h>, write side of struct
u64_stats_sync must ensure mutual exclusion, or one seqcount update could
be lost on 32-bit platforms, thus blocking readers forever. Such lockups
have been observed in real world after stmmac_xmit() on one CPU raced with
stmmac_napi_poll_tx() on another CPU.

To fix the issue without introducing a new lock, split the statics into
three parts:

1. fields updated only under the tx queue lock,
2. fields updated only during NAPI poll,
3. fields updated only from interrupt context,

Updates to fields in the first two groups are already serialized through
other locks. It is sufficient to split the existing struct u64_stats_sync
so that each group has its own.

Note that tx_set_ic_bit is updated from both contexts. Split this counter
so that each context gets its own, and calculate their sum to get the total
value in stmmac_get_ethtool_stats().

For the third group, multiple interrupts may be processed by different CPUs
at the same time, but interrupts on the same CPU will not nest. Move fields
from this group to a newly created per-cpu struct stmmac_pcpu_stats.

Fixes: 133466c3bbe1 ("net: stmmac: use per-queue 64 bit statistics where necessary")
Link: https://lore.kernel.org/netdev/Za173PhviYg-1qIn at torres.zugschlus.de/t/
Cc: stable at vger.kernel.org
Signed-off-by: Petr Tesarik <petr at tesarici.cz>
---
 drivers/net/ethernet/stmicro/stmmac/common.h  |  56 +++++---
 .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c |  15 +-
 .../net/ethernet/stmicro/stmmac/dwmac4_lib.c  |  15 +-
 .../net/ethernet/stmicro/stmmac/dwmac_lib.c   |  15 +-
 .../ethernet/stmicro/stmmac/dwxgmac2_dma.c    |  15 +-
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 129 +++++++++++------
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 133 +++++++++---------
 7 files changed, 221 insertions(+), 157 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 721c1f8e892f..4aca20feb4b7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -59,28 +59,51 @@
 #undef FRAME_FILTER_DEBUG
 /* #define FRAME_FILTER_DEBUG */
 
+struct stmmac_q_tx_stats {
+	u64_stats_t tx_bytes;
+	u64_stats_t tx_set_ic_bit;
+	u64_stats_t tx_tso_frames;
+	u64_stats_t tx_tso_nfrags;
+};
+
+struct stmmac_napi_tx_stats {
+	u64_stats_t tx_packets;
+	u64_stats_t tx_pkt_n;
+	u64_stats_t poll;
+	u64_stats_t tx_clean;
+	u64_stats_t tx_set_ic_bit;
+};
+
 struct stmmac_txq_stats {
-	u64 tx_bytes;
-	u64 tx_packets;
-	u64 tx_pkt_n;
-	u64 tx_normal_irq_n;
-	u64 napi_poll;
-	u64 tx_clean;
-	u64 tx_set_ic_bit;
-	u64 tx_tso_frames;
-	u64 tx_tso_nfrags;
-	struct u64_stats_sync syncp;
+	/* Updates protected by tx queue lock. */
+	struct u64_stats_sync q_syncp;
+	struct stmmac_q_tx_stats q;
+
+	/* Updates protected by NAPI poll logic. */
+	struct u64_stats_sync napi_syncp;
+	struct stmmac_napi_tx_stats napi;
 } ____cacheline_aligned_in_smp;
 
+struct stmmac_napi_rx_stats {
+	u64_stats_t rx_bytes;
+	u64_stats_t rx_packets;
+	u64_stats_t rx_pkt_n;
+	u64_stats_t poll;
+};
+
 struct stmmac_rxq_stats {
-	u64 rx_bytes;
-	u64 rx_packets;
-	u64 rx_pkt_n;
-	u64 rx_normal_irq_n;
-	u64 napi_poll;
-	struct u64_stats_sync syncp;
+	/* Updates protected by NAPI poll logic. */
+	struct u64_stats_sync napi_syncp;
+	struct stmmac_napi_rx_stats napi;
 } ____cacheline_aligned_in_smp;
 
+/* Updates on each CPU protected by not allowing nested irqs. */
+struct stmmac_pcpu_stats {
+	struct u64_stats_sync syncp;
+	u64_stats_t rx_normal_irq_n[MTL_MAX_TX_QUEUES];
+	u64_stats_t tx_normal_irq_n[MTL_MAX_RX_QUEUES];
+};
+
 /* Extra statistic and debug information exposed by ethtool */
 struct stmmac_extra_stats {
 	/* Transmit errors */
@@ -205,6 +228,7 @@ struct stmmac_extra_stats {
 	/* per queue statistics */
 	struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES];
 	struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES];
+	struct stmmac_pcpu_stats __percpu *pcpu_stats;
 	unsigned long rx_dropped;
 	unsigned long rx_errors;
 	unsigned long tx_dropped;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 137741b94122..b21d99faa2d0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -441,8 +441,7 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
 				     struct stmmac_extra_stats *x, u32 chan,
 				     u32 dir)
 {
-	struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
-	struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
+	struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
 	int ret = 0;
 	u32 v;
 
@@ -455,9 +454,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
 
 	if (v & EMAC_TX_INT) {
 		ret |= handle_tx;
-		u64_stats_update_begin(&txq_stats->syncp);
-		txq_stats->tx_normal_irq_n++;
-		u64_stats_update_end(&txq_stats->syncp);
+		u64_stats_update_begin(&stats->syncp);
+		u64_stats_inc(&stats->tx_normal_irq_n[chan]);
+		u64_stats_update_end(&stats->syncp);
 	}
 
 	if (v & EMAC_TX_DMA_STOP_INT)
@@ -479,9 +478,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
 
 	if (v & EMAC_RX_INT) {
 		ret |= handle_rx;
-		u64_stats_update_begin(&rxq_stats->syncp);
-		rxq_stats->rx_normal_irq_n++;
-		u64_stats_update_end(&rxq_stats->syncp);
+		u64_stats_update_begin(&stats->syncp);
+		u64_stats_inc(&stats->rx_normal_irq_n[chan]);
+		u64_stats_update_end(&stats->syncp);
 	}
 
 	if (v & EMAC_RX_BUF_UA_INT)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index 9470d3fd2ded..0d185e54eb7e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -171,8 +171,7 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
 	const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
 	u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan));
 	u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
-	struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
-	struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
+	struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
 	int ret = 0;
 
 	if (dir == DMA_DIR_RX)
@@ -201,15 +200,15 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
 	}
 	/* TX/RX NORMAL interrupts */
 	if (likely(intr_status & DMA_CHAN_STATUS_RI)) {
-		u64_stats_update_begin(&rxq_stats->syncp);
-		rxq_stats->rx_normal_irq_n++;
-		u64_stats_update_end(&rxq_stats->syncp);
+		u64_stats_update_begin(&stats->syncp);
+		u64_stats_inc(&stats->rx_normal_irq_n[chan]);
+		u64_stats_update_end(&stats->syncp);
 		ret |= handle_rx;
 	}
 	if (likely(intr_status & DMA_CHAN_STATUS_TI)) {
-		u64_stats_update_begin(&txq_stats->syncp);
-		txq_stats->tx_normal_irq_n++;
-		u64_stats_update_end(&txq_stats->syncp);
+		u64_stats_update_begin(&stats->syncp);
+		u64_stats_inc(&stats->tx_normal_irq_n[chan]);
+		u64_stats_update_end(&stats->syncp);
 		ret |= handle_tx;
 	}
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index 7907d62d3437..85e18f9a22f9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -162,8 +162,7 @@ static void show_rx_process_state(unsigned int status)
 int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
 			struct stmmac_extra_stats *x, u32 chan, u32 dir)
 {
-	struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
-	struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
+	struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
 	int ret = 0;
 	/* read the status register (CSR5) */
 	u32 intr_status = readl(ioaddr + DMA_STATUS);
@@ -215,16 +214,16 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
 			u32 value = readl(ioaddr + DMA_INTR_ENA);
 			/* to schedule NAPI on real RIE event. */
 			if (likely(value & DMA_INTR_ENA_RIE)) {
-				u64_stats_update_begin(&rxq_stats->syncp);
-				rxq_stats->rx_normal_irq_n++;
-				u64_stats_update_end(&rxq_stats->syncp);
+				u64_stats_update_begin(&stats->syncp);
+				u64_stats_inc(&stats->rx_normal_irq_n[chan]);
+				u64_stats_update_end(&stats->syncp);
 				ret |= handle_rx;
 			}
 		}
 		if (likely(intr_status & DMA_STATUS_TI)) {
-			u64_stats_update_begin(&txq_stats->syncp);
-			txq_stats->tx_normal_irq_n++;
-			u64_stats_update_end(&txq_stats->syncp);
+			u64_stats_update_begin(&stats->syncp);
+			u64_stats_inc(&stats->tx_normal_irq_n[chan]);
+			u64_stats_update_end(&stats->syncp);
 			ret |= handle_tx;
 		}
 		if (unlikely(intr_status & DMA_STATUS_ERI))
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
index 3cde695fec91..dd2ab6185c40 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -337,8 +337,7 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
 				  struct stmmac_extra_stats *x, u32 chan,
 				  u32 dir)
 {
-	struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
-	struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
+	struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
 	u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
 	u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
 	int ret = 0;
@@ -367,15 +366,15 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
 	/* TX/RX NORMAL interrupts */
 	if (likely(intr_status & XGMAC_NIS)) {
 		if (likely(intr_status & XGMAC_RI)) {
-			u64_stats_update_begin(&rxq_stats->syncp);
-			rxq_stats->rx_normal_irq_n++;
-			u64_stats_update_end(&rxq_stats->syncp);
+			u64_stats_update_begin(&stats->syncp);
+			u64_stats_inc(&stats->rx_normal_irq_n[chan]);
+			u64_stats_update_end(&stats->syncp);
 			ret |= handle_rx;
 		}
 		if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) {
-			u64_stats_update_begin(&txq_stats->syncp);
-			txq_stats->tx_normal_irq_n++;
-			u64_stats_update_end(&txq_stats->syncp);
+			u64_stats_update_begin(&stats->syncp);
+			u64_stats_inc(&stats->tx_normal_irq_n[chan]);
+			u64_stats_update_end(&stats->syncp);
 			ret |= handle_tx;
 		}
 	}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 42d27b97dd1d..ec44becf0e2d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -549,44 +549,79 @@ stmmac_set_pauseparam(struct net_device *netdev,
 	}
 }
 
+static u64 stmmac_get_rx_normal_irq_n(struct stmmac_priv *priv, int q)
+{
+	u64 total;
+	int cpu;
+
+	total = 0;
+	for_each_possible_cpu(cpu) {
+		struct stmmac_pcpu_stats *pcpu;
+		unsigned int start;
+		u64 irq_n;
+
+		pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu);
+		do {
+			start = u64_stats_fetch_begin(&pcpu->syncp);
+			irq_n = u64_stats_read(&pcpu->rx_normal_irq_n[q]);
+		} while (u64_stats_fetch_retry(&pcpu->syncp, start));
+		total += irq_n;
+	}
+	return total;
+}
+
+static u64 stmmac_get_tx_normal_irq_n(struct stmmac_priv *priv, int q)
+{
+	u64 total;
+	int cpu;
+
+	total = 0;
+	for_each_possible_cpu(cpu) {
+		struct stmmac_pcpu_stats *pcpu;
+		unsigned int start;
+		u64 irq_n;
+
+		pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu);
+		do {
+			start = u64_stats_fetch_begin(&pcpu->syncp);
+			irq_n = u64_stats_read(&pcpu->tx_normal_irq_n[q]);
+		} while (u64_stats_fetch_retry(&pcpu->syncp, start));
+		total += irq_n;
+	}
+	return total;
+}
+
 static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
 {
 	u32 tx_cnt = priv->plat->tx_queues_to_use;
 	u32 rx_cnt = priv->plat->rx_queues_to_use;
 	unsigned int start;
-	int q, stat;
-	char *p;
+	int q;
 
 	for (q = 0; q < tx_cnt; q++) {
 		struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q];
-		struct stmmac_txq_stats snapshot;
+		u64 pkt_n;
 
 		do {
-			start = u64_stats_fetch_begin(&txq_stats->syncp);
-			snapshot = *txq_stats;
-		} while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+			start = u64_stats_fetch_begin(&txq_stats->napi_syncp);
+			pkt_n = u64_stats_read(&txq_stats->napi.tx_pkt_n);
+		} while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));
 
-		p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n);
-		for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
-			*data++ = (*(u64 *)p);
-			p += sizeof(u64);
-		}
+		*data++ = pkt_n;
+		*data++ = stmmac_get_tx_normal_irq_n(priv, q);
 	}
 
 	for (q = 0; q < rx_cnt; q++) {
 		struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q];
-		struct stmmac_rxq_stats snapshot;
+		u64 pkt_n;
 
 		do {
-			start = u64_stats_fetch_begin(&rxq_stats->syncp);
-			snapshot = *rxq_stats;
-		} while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+			start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);
+			pkt_n = u64_stats_read(&rxq_stats->napi.rx_pkt_n);
+		} while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));
 
-		p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n);
-		for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
-			*data++ = (*(u64 *)p);
-			p += sizeof(u64);
-		}
+		*data++ = pkt_n;
+		*data++ = stmmac_get_rx_normal_irq_n(priv, q);
 	}
 }
 
@@ -645,39 +680,49 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
 	pos = j;
 	for (i = 0; i < rx_queues_count; i++) {
 		struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[i];
-		struct stmmac_rxq_stats snapshot;
+		struct stmmac_napi_rx_stats snapshot;
+		u64 n_irq;
 
 		j = pos;
 		do {
-			start = u64_stats_fetch_begin(&rxq_stats->syncp);
-			snapshot = *rxq_stats;
-		} while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
-
-		data[j++] += snapshot.rx_pkt_n;
-		data[j++] += snapshot.rx_normal_irq_n;
-		normal_irq_n += snapshot.rx_normal_irq_n;
-		napi_poll += snapshot.napi_poll;
+			start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);
+			snapshot = rxq_stats->napi;
+		} while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));
+
+		data[j++] += u64_stats_read(&snapshot.rx_pkt_n);
+		n_irq = stmmac_get_rx_normal_irq_n(priv, i);
+		data[j++] += n_irq;
+		normal_irq_n += n_irq;
+		napi_poll += u64_stats_read(&snapshot.poll);
 	}
 
 	pos = j;
 	for (i = 0; i < tx_queues_count; i++) {
 		struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[i];
-		struct stmmac_txq_stats snapshot;
+		struct stmmac_napi_tx_stats napi_snapshot;
+		struct stmmac_q_tx_stats q_snapshot;
+		u64 n_irq;
 
 		j = pos;
 		do {
-			start = u64_stats_fetch_begin(&txq_stats->syncp);
-			snapshot = *txq_stats;
-		} while (u64_stats_fetch_retry(&txq_stats->syncp, start));
-
-		data[j++] += snapshot.tx_pkt_n;
-		data[j++] += snapshot.tx_normal_irq_n;
-		normal_irq_n += snapshot.tx_normal_irq_n;
-		data[j++] += snapshot.tx_clean;
-		data[j++] += snapshot.tx_set_ic_bit;
-		data[j++] += snapshot.tx_tso_frames;
-		data[j++] += snapshot.tx_tso_nfrags;
-		napi_poll += snapshot.napi_poll;
+			start = u64_stats_fetch_begin(&txq_stats->q_syncp);
+			q_snapshot = txq_stats->q;
+		} while (u64_stats_fetch_retry(&txq_stats->q_syncp, start));
+		do {
+			start = u64_stats_fetch_begin(&txq_stats->napi_syncp);
+			napi_snapshot = txq_stats->napi;
+		} while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));
+
+		data[j++] += u64_stats_read(&napi_snapshot.tx_pkt_n);
+		n_irq = stmmac_get_tx_normal_irq_n(priv, i);
+		data[j++] += n_irq;
+		normal_irq_n += n_irq;
+		data[j++] += u64_stats_read(&napi_snapshot.tx_clean);
+		data[j++] += u64_stats_read(&q_snapshot.tx_set_ic_bit) +
+			u64_stats_read(&napi_snapshot.tx_set_ic_bit);
+		data[j++] += u64_stats_read(&q_snapshot.tx_tso_frames);
+		data[j++] += u64_stats_read(&q_snapshot.tx_tso_nfrags);
+		napi_poll += u64_stats_read(&napi_snapshot.poll);
 	}
 	normal_irq_n += priv->xstats.rx_early_irq;
 	data[j++] = normal_irq_n;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 25519952f754..75d029704503 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2482,7 +2482,6 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
 	struct xdp_desc xdp_desc;
 	bool work_done = true;
 	u32 tx_set_ic_bit = 0;
-	unsigned long flags;
 
 	/* Avoids TX time-out as we are sharing with slow path */
 	txq_trans_cond_update(nq);
@@ -2566,9 +2565,9 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
 		tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
 		entry = tx_q->cur_tx;
 	}
-	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
-	txq_stats->tx_set_ic_bit += tx_set_ic_bit;
-	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+	u64_stats_update_begin(&txq_stats->napi_syncp);
+	u64_stats_add(&txq_stats->napi.tx_set_ic_bit, tx_set_ic_bit);
+	u64_stats_update_end(&txq_stats->napi_syncp);
 
 	if (tx_desc) {
 		stmmac_flush_tx_descriptors(priv, queue);
@@ -2616,7 +2615,6 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue,
 	unsigned int bytes_compl = 0, pkts_compl = 0;
 	unsigned int entry, xmits = 0, count = 0;
 	u32 tx_packets = 0, tx_errors = 0;
-	unsigned long flags;
 
 	__netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue));
 
@@ -2782,11 +2780,11 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue,
 	if (tx_q->dirty_tx != tx_q->cur_tx)
 		*pending_packets = true;
 
-	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
-	txq_stats->tx_packets += tx_packets;
-	txq_stats->tx_pkt_n += tx_packets;
-	txq_stats->tx_clean++;
-	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+	u64_stats_update_begin(&txq_stats->napi_syncp);
+	u64_stats_add(&txq_stats->napi.tx_packets, tx_packets);
+	u64_stats_add(&txq_stats->napi.tx_pkt_n, tx_packets);
+	u64_stats_inc(&txq_stats->napi.tx_clean);
+	u64_stats_update_end(&txq_stats->napi_syncp);
 
 	priv->xstats.tx_errors += tx_errors;
 
@@ -4213,7 +4211,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct stmmac_tx_queue *tx_q;
 	bool has_vlan, set_ic;
 	u8 proto_hdr_len, hdr;
-	unsigned long flags;
 	u32 pay_len, mss;
 	dma_addr_t des;
 	int i;
@@ -4378,13 +4375,13 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 		netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue));
 	}
 
-	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
-	txq_stats->tx_bytes += skb->len;
-	txq_stats->tx_tso_frames++;
-	txq_stats->tx_tso_nfrags += nfrags;
+	u64_stats_update_begin(&txq_stats->q_syncp);
+	u64_stats_add(&txq_stats->q.tx_bytes, skb->len);
+	u64_stats_inc(&txq_stats->q.tx_tso_frames);
+	u64_stats_add(&txq_stats->q.tx_tso_nfrags, nfrags);
 	if (set_ic)
-		txq_stats->tx_set_ic_bit++;
-	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+		u64_stats_inc(&txq_stats->q.tx_set_ic_bit);
+	u64_stats_update_end(&txq_stats->q_syncp);
 
 	if (priv->sarc_type)
 		stmmac_set_desc_sarc(priv, first, priv->sarc_type);
@@ -4483,7 +4480,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct stmmac_tx_queue *tx_q;
 	bool has_vlan, set_ic;
 	int entry, first_tx;
-	unsigned long flags;
 	dma_addr_t des;
 
 	tx_q = &priv->dma_conf.tx_queue[queue];
@@ -4653,11 +4649,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
 		netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue));
 	}
 
-	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
-	txq_stats->tx_bytes += skb->len;
+	u64_stats_update_begin(&txq_stats->q_syncp);
+	u64_stats_add(&txq_stats->q.tx_bytes, skb->len);
 	if (set_ic)
-		txq_stats->tx_set_ic_bit++;
-	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+		u64_stats_inc(&txq_stats->q.tx_set_ic_bit);
+	u64_stats_update_end(&txq_stats->q_syncp);
 
 	if (priv->sarc_type)
 		stmmac_set_desc_sarc(priv, first, priv->sarc_type);
@@ -4921,12 +4917,11 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
 		set_ic = false;
 
 	if (set_ic) {
-		unsigned long flags;
 		tx_q->tx_count_frames = 0;
 		stmmac_set_tx_ic(priv, tx_desc);
-		flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
-		txq_stats->tx_set_ic_bit++;
-		u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+		u64_stats_update_begin(&txq_stats->q_syncp);
+		u64_stats_inc(&txq_stats->q.tx_set_ic_bit);
+		u64_stats_update_end(&txq_stats->q_syncp);
 	}
 
 	stmmac_enable_dma_transmission(priv, priv->ioaddr);
@@ -5076,7 +5071,6 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
 	unsigned int len = xdp->data_end - xdp->data;
 	enum pkt_hash_types hash_type;
 	int coe = priv->hw->rx_csum;
-	unsigned long flags;
 	struct sk_buff *skb;
 	u32 hash;
 
@@ -5106,10 +5100,10 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
 	skb_record_rx_queue(skb, queue);
 	napi_gro_receive(&ch->rxtx_napi, skb);
 
-	flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
-	rxq_stats->rx_pkt_n++;
-	rxq_stats->rx_bytes += len;
-	u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
+	u64_stats_update_begin(&rxq_stats->napi_syncp);
+	u64_stats_inc(&rxq_stats->napi.rx_pkt_n);
+	u64_stats_add(&rxq_stats->napi.rx_bytes, len);
+	u64_stats_update_end(&rxq_stats->napi_syncp);
 }
 
 static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
@@ -5191,7 +5185,6 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
 	unsigned int desc_size;
 	struct bpf_prog *prog;
 	bool failure = false;
-	unsigned long flags;
 	int xdp_status = 0;
 	int status = 0;
 
@@ -5346,9 +5339,9 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
 
 	stmmac_finalize_xdp_rx(priv, xdp_status);
 
-	flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
-	rxq_stats->rx_pkt_n += count;
-	u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
+	u64_stats_update_begin(&rxq_stats->napi_syncp);
+	u64_stats_add(&rxq_stats->napi.rx_pkt_n, count);
+	u64_stats_update_end(&rxq_stats->napi_syncp);
 
 	priv->xstats.rx_dropped += rx_dropped;
 	priv->xstats.rx_errors += rx_errors;
@@ -5386,7 +5379,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 	unsigned int desc_size;
 	struct sk_buff *skb = NULL;
 	struct stmmac_xdp_buff ctx;
-	unsigned long flags;
 	int xdp_status = 0;
 	int buf_sz;
 
@@ -5646,11 +5638,11 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 
 	stmmac_rx_refill(priv, queue);
 
-	flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
-	rxq_stats->rx_packets += rx_packets;
-	rxq_stats->rx_bytes += rx_bytes;
-	rxq_stats->rx_pkt_n += count;
-	u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
+	u64_stats_update_begin(&rxq_stats->napi_syncp);
+	u64_stats_add(&rxq_stats->napi.rx_packets, rx_packets);
+	u64_stats_add(&rxq_stats->napi.rx_bytes, rx_bytes);
+	u64_stats_add(&rxq_stats->napi.rx_pkt_n, count);
+	u64_stats_update_end(&rxq_stats->napi_syncp);
 
 	priv->xstats.rx_dropped += rx_dropped;
 	priv->xstats.rx_errors += rx_errors;
@@ -5665,13 +5657,12 @@ static int stmmac_napi_poll_rx(struct napi_struct *napi, int budget)
 	struct stmmac_priv *priv = ch->priv_data;
 	struct stmmac_rxq_stats *rxq_stats;
 	u32 chan = ch->index;
-	unsigned long flags;
 	int work_done;
 
 	rxq_stats = &priv->xstats.rxq_stats[chan];
-	flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
-	rxq_stats->napi_poll++;
-	u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
+	u64_stats_update_begin(&rxq_stats->napi_syncp);
+	u64_stats_inc(&rxq_stats->napi.poll);
+	u64_stats_update_end(&rxq_stats->napi_syncp);
 
 	work_done = stmmac_rx(priv, budget, chan);
 	if (work_done < budget && napi_complete_done(napi, work_done)) {
@@ -5693,13 +5684,12 @@ static int stmmac_napi_poll_tx(struct napi_struct *napi, int budget)
 	struct stmmac_txq_stats *txq_stats;
 	bool pending_packets = false;
 	u32 chan = ch->index;
-	unsigned long flags;
 	int work_done;
 
 	txq_stats = &priv->xstats.txq_stats[chan];
-	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
-	txq_stats->napi_poll++;
-	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+	u64_stats_update_begin(&txq_stats->napi_syncp);
+	u64_stats_inc(&txq_stats->napi.poll);
+	u64_stats_update_end(&txq_stats->napi_syncp);
 
 	work_done = stmmac_tx_clean(priv, budget, chan, &pending_packets);
 	work_done = min(work_done, budget);
@@ -5729,17 +5719,16 @@ static int stmmac_napi_poll_rxtx(struct napi_struct *napi, int budget)
 	struct stmmac_rxq_stats *rxq_stats;
 	struct stmmac_txq_stats *txq_stats;
 	u32 chan = ch->index;
-	unsigned long flags;
 
 	rxq_stats = &priv->xstats.rxq_stats[chan];
-	flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
-	rxq_stats->napi_poll++;
-	u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
+	u64_stats_update_begin(&rxq_stats->napi_syncp);
+	u64_stats_inc(&rxq_stats->napi.poll);
+	u64_stats_update_end(&rxq_stats->napi_syncp);
 
 	txq_stats = &priv->xstats.txq_stats[chan];
-	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
-	txq_stats->napi_poll++;
-	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
+	u64_stats_update_begin(&txq_stats->napi_syncp);
+	u64_stats_inc(&txq_stats->napi.poll);
+	u64_stats_update_end(&txq_stats->napi_syncp);
 
 	tx_done = stmmac_tx_clean(priv, budget, chan, &tx_pending_packets);
 	tx_done = min(tx_done, budget);
@@ -7065,10 +7054,13 @@ static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64
 		u64 tx_bytes;
 
 		do {
-			start = u64_stats_fetch_begin(&txq_stats->syncp);
-			tx_packets = txq_stats->tx_packets;
-			tx_bytes   = txq_stats->tx_bytes;
-		} while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+			start = u64_stats_fetch_begin(&txq_stats->q_syncp);
+			tx_bytes   = u64_stats_read(&txq_stats->q.tx_bytes);
+		} while (u64_stats_fetch_retry(&txq_stats->q_syncp, start));
+		do {
+			start = u64_stats_fetch_begin(&txq_stats->napi_syncp);
+			tx_packets = u64_stats_read(&txq_stats->napi.tx_packets);
+		} while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));
 
 		stats->tx_packets += tx_packets;
 		stats->tx_bytes += tx_bytes;
@@ -7080,10 +7072,10 @@ static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64
 		u64 rx_bytes;
 
 		do {
-			start = u64_stats_fetch_begin(&rxq_stats->syncp);
-			rx_packets = rxq_stats->rx_packets;
-			rx_bytes   = rxq_stats->rx_bytes;
-		} while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+			start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);
+			rx_packets = u64_stats_read(&rxq_stats->napi.rx_packets);
+			rx_bytes   = u64_stats_read(&rxq_stats->napi.rx_bytes);
+		} while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));
 
 		stats->rx_packets += rx_packets;
 		stats->rx_bytes += rx_bytes;
@@ -7477,9 +7469,16 @@ int stmmac_dvr_probe(struct device *device,
 	priv->dev = ndev;
 
 	for (i = 0; i < MTL_MAX_RX_QUEUES; i++)
-		u64_stats_init(&priv->xstats.rxq_stats[i].syncp);
-	for (i = 0; i < MTL_MAX_TX_QUEUES; i++)
-		u64_stats_init(&priv->xstats.txq_stats[i].syncp);
+		u64_stats_init(&priv->xstats.rxq_stats[i].napi_syncp);
+	for (i = 0; i < MTL_MAX_TX_QUEUES; i++) {
+		u64_stats_init(&priv->xstats.txq_stats[i].q_syncp);
+		u64_stats_init(&priv->xstats.txq_stats[i].napi_syncp);
+	}
+
+	priv->xstats.pcpu_stats =
+		devm_netdev_alloc_pcpu_stats(device, struct stmmac_pcpu_stats);
+	if (!priv->xstats.pcpu_stats)
+		return -ENOMEM;
 
 	stmmac_set_ethtool_ops(ndev);
 	priv->pause = pause;
-- 
2.43.0



From neil.armstrong at linaro.org  Sat Feb  3 12:20:17 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Sat, 03 Feb 2024 21:20:17 +0100
Subject: [PATCH] arm64: deconfig: enable Goodix Berlin SPI touchscreen
 driver as module
Message-ID: <20240203-topic-sm8x50-upstream-goodix-spi-defconfig-v1-1-b69ed85ddd05@linaro.org>

enable Goodix Berlin SPI driver as module since used on the
Qualcomm SM8550 QRD and SM8650 QRD platforms.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 2064e7bc529e..ea000c333e50 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -432,6 +432,7 @@ CONFIG_MOUSE_ELAN_I2C=m
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=m
 CONFIG_TOUCHSCREEN_GOODIX=m
+CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI=m
 CONFIG_TOUCHSCREEN_ELAN=m
 CONFIG_TOUCHSCREEN_EDT_FT5X06=m
 CONFIG_INPUT_MISC=y

---
base-commit: 076d56d74f17e625b3d63cf4743b3d7d02180379
change-id: 20240203-topic-sm8x50-upstream-goodix-spi-defconfig-5b69c3e9f61f

Best regards,
-- 
Neil Armstrong <neil.armstrong at linaro.org>



From wsa at kernel.org  Sat Feb  3 12:47:39 2024
From: wsa at kernel.org (Wolfram Sang)
Date: Sat, 3 Feb 2024 21:47:39 +0100
Subject: [PATCH v8 02/13] dt-bindings: treewide: add access-controllers
 description
In-Reply-To: <20231212152356.345703-3-gatien.chevallier@foss.st.com>
References: <20231212152356.345703-1-gatien.chevallier@foss.st.com>
 <20231212152356.345703-3-gatien.chevallier@foss.st.com>
Message-ID: <Zb6ma9lHMu3SAe0U@shikoro>

On Tue, Dec 12, 2023 at 04:23:45PM +0100, Gatien Chevallier wrote:
> access-controllers is an optional property that allows a peripheral to
> refer to one or more domain access controller(s).
> 
> Description of this property is added to all peripheral binding files of
> the peripheral under the STM32 firewall controller. It allows an accurate
> representation of the hardware, where various peripherals are connected
> to a firewall bus. The firewall can then check the peripheral accesses
> before allowing its device to probe.
> 
> Signed-off-by: Gatien Chevallier <gatien.chevallier at foss.st.com>

Acked-by: Wolfram Sang <wsa+renesas at sang-engineering.com> # for I2C

-------------- 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/20240203/f4100f80/attachment.sig>

From oliver.upton at linux.dev  Sat Feb  3 14:26:55 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Sat, 3 Feb 2024 14:26:55 -0800
Subject: [PATCH] KVM: selftests: Fix GUEST_PRINTF() format warnings in
 ARM code
In-Reply-To: <20240202234603.366925-1-seanjc@google.com>
References: <20240202234603.366925-1-seanjc@google.com>
Message-ID: <Zb69ryhz_mDw9UK4@linux.dev>

On Fri, Feb 02, 2024 at 03:46:03PM -0800, Sean Christopherson wrote:
> Fix a pile of -Wformat warnings in the KVM ARM selftests code, almost all
> of which are benign "long" versus "long long" issues (selftests are 64-bit
> only, and the guest printf code treats "ll" the same as "l").  The code
> itself isn't problematic, but the warnings make it impossible to build ARM
> selftests with -Werror, which does detect real issues from time to time.
> 
> Opportunistically have GUEST_ASSERT_BITMAP_REG() interpret set_expected,
> which is a bool, as an unsigned decimal value, i.e. have it print '0' or
> '1' instead of '0x0' or '0x1'.
> 
> Signed-off-by: Sean Christopherson <seanjc at google.com>

This all looks good to me. Just want to confirm before applying: you're
not planning any other patches that'll go through your tree that depend
on this right?

Figured not since you sent it separately, but just want to be sure.

-- 
Thanks,
Oliver


From quic_taozha at quicinc.com  Sat Feb  3 17:58:01 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 09:58:01 +0800
Subject: [PATCH v6 05/10] coresight-tpda: Add support to configure CMB
 element
In-Reply-To: <265086d1-8398-49f8-b873-36194c44505a@arm.com>
References: <1706866364-19861-1-git-send-email-quic_taozha@quicinc.com>
 <1706866364-19861-6-git-send-email-quic_taozha@quicinc.com>
 <58e91497-1794-46d9-a935-fc23f327f32b@arm.com>
 <265086d1-8398-49f8-b873-36194c44505a@arm.com>
Message-ID: <54292059-9ecf-4e9d-b1ca-4c4ff2425189@quicinc.com>


On 2/2/2024 6:06 PM, Suzuki K Poulose wrote:
> On 02/02/2024 09:45, Suzuki K Poulose wrote:
>> On 02/02/2024 09:32, Tao Zhang wrote:
>>> Read the CMB element size from the device tree. Set the register
>>> bit that controls the CMB element size of the corresponding port.
>>>
>>> Reviewed-by: James Clark <james.clark at arm.com>
>>> Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
>>> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
>>> ---
>>> ? drivers/hwtracing/coresight/coresight-tpda.c | 125 
>>> +++++++++++--------
>>> ? drivers/hwtracing/coresight/coresight-tpda.h |?? 6 +
>>> ? 2 files changed, 81 insertions(+), 50 deletions(-)
>>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c 
>>> b/drivers/hwtracing/coresight/coresight-tpda.c
>>> index 4ac954f4bc13..27d567f4c8bf 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>>> @@ -18,6 +18,7 @@
>>> ? #include "coresight-priv.h"
>>> ? #include "coresight-tpda.h"
>>> ? #include "coresight-trace-id.h"
>>> +#include "coresight-tpdm.h"
>>> ? DEFINE_CORESIGHT_DEVLIST(tpda_devs, "tpda");
>>> @@ -28,24 +29,59 @@ static bool coresight_device_is_tpdm(struct 
>>> coresight_device *csdev)
>>> ????????????? CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
>>> ? }
>>> +static void tpdm_clear_element_size(struct coresight_device *csdev)
>>
>> I just noticed this anomaly. This is supposed to be :
>>
>> tpda_clear_element_size() ? I can fix it up locally.
>>
>>
>> Suzuki
>>
>>
>>> +{
>>> +??? struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>>> +
>>> +??? drvdata->dsb_esize = 0;
>>> +??? drvdata->cmb_esize = 0;
>>> +}
>>> +
>>> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 
>>> *val)
>>> +{
>>> +??? /* Clear all relevant fields */
>>> +??? *val &= ~(TPDA_Pn_CR_DSBSIZE | TPDA_Pn_CR_CMBSIZE);
>>> +
>>> +??? if (drvdata->dsb_esize == 64)
>>> +??????? *val |= TPDA_Pn_CR_DSBSIZE;
>>> +??? else if (drvdata->dsb_esize == 32)
>>> +??????? *val &= ~TPDA_Pn_CR_DSBSIZE;
>>> +
>>> +??? if (drvdata->cmb_esize == 64)
>>> +??????? *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
>>> +??? else if (drvdata->cmb_esize == 32)
>>> +??????? *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
>>> +??? else if (drvdata->cmb_esize == 8)
>>> +??????? *val &= ~TPDA_Pn_CR_CMBSIZE;
>>> +}
>>> +
>>> ? /*
>>> - * Read the DSB element size from the TPDM device
>>> + * Read the element size from the TPDM device. One TPDM must have 
>>> at least one of the
>>> + * element size property.
>>> ?? * Returns
>>> - *??? The dsb element size read from the devicetree if available.
>>> - *??? 0 - Otherwise, with a warning once.
>>> + *??? 0 - The element size property is read
>>> + *??? Others - Cannot read the property of the element size
>>> ?? */
>>> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
>>> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
>>> +????????????????? struct coresight_device *csdev)
>>> ? {
>>> -??? int rc = 0;
>>> -??? u8 size = 0;
>>> +??? int rc = -EINVAL;
>>> +??? struct tpdm_drvdata *tpdm_data = 
>>> dev_get_drvdata(csdev->dev.parent);
>>> +
>>> +??? if (tpdm_has_dsb_dataset(tpdm_data)) {
>>> +??????? rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>> +??????????????? "qcom,dsb-element-size", &drvdata->dsb_esize);
>>> +??? }
>>> +??? if (tpdm_has_cmb_dataset(tpdm_data)) {
>>> +??????? rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
>>> +??????????????? "qcom,cmb-element-bits", &drvdata->cmb_esize);
>>> +??? }
>>> -??? rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>> -??????????? "qcom,dsb-element-size", &size);
>>> ????? if (rc)
>>> ????????? dev_warn_once(&csdev->dev,
>>> -??????????? "Failed to read TPDM DSB Element size: %d\n", rc);
>>> +??????????? "Failed to read TPDM Element size: %d\n", rc);
>>> -??? return size;
>>> +??? return rc;
>>> ? }
>>> ? /*
>>> @@ -56,11 +92,12 @@ static int tpdm_read_dsb_element_size(struct 
>>> coresight_device *csdev)
>>> ?? * Parameter "inport" is used to pass in the input port number
>>> ?? * of TPDA, and it is set to -1 in the recursize call.
>>> ?? */
>>> -static int tpda_get_element_size(struct coresight_device *csdev,
>>> +static int tpda_get_element_size(struct tpda_drvdata *drvdata,
>>> +???????????????? struct coresight_device *csdev,
>>> ?????????????????? int inport)
>>> ? {
>>> -??? int dsb_size = -ENOENT;
>>> -??? int i, size;
>>> +??? int rc = 0;
>>> +??? int i;
>>> ????? struct coresight_device *in;
>>> ????? for (i = 0; i < csdev->pdata->nr_inconns; i++) {
>>> @@ -69,30 +106,26 @@ static int tpda_get_element_size(struct 
>>> coresight_device *csdev,
>>> ????????????? continue;
>>> ????????? /* Ignore the paths that do not match port */
>>> -??????? if (inport > 0 &&
>>> +??????? if (inport >= 0 &&
>>> ????????????? csdev->pdata->in_conns[i]->dest_port != inport)
>>> ????????????? continue;
>>> ????????? if (coresight_device_is_tpdm(in)) {
>>> -??????????? size = tpdm_read_dsb_element_size(in);
>>> +??????????? if (drvdata->dsb_esize || drvdata->cmb_esize)
>>> +??????????????? return -EEXIST;
>>> +??????????? rc = tpdm_read_element_size(drvdata, in);
>>> +??????????? if (rc)
>>> +??????????????? return rc;
>>> ????????? } else {
>>> ????????????? /* Recurse down the path */
>>> -??????????? size = tpda_get_element_size(in, -1);
>>> -??????? }
>>> -
>>> -??????? if (size < 0)
>>> -??????????? return size;
>>> -
>>> -??????? if (dsb_size < 0) {
>>> -??????????? /* Found a size, save it. */
>>> -??????????? dsb_size = size;
>>> -??????? } else {
>>> -??????????? /* Found duplicate TPDMs */
>>> -??????????? return -EEXIST;
>>> +??????????? rc = tpda_get_element_size(drvdata, in, -1);
>>> +??????????? if (rc)
>>> +??????????????? return rc;
>>> ????????? }
>>> ????? }
>>> -??? return dsb_size;
>>> +
>>> +??? return rc;
>>> ? }
>>> ? /* Settings pre enabling port control register */
>>> @@ -109,7 +142,7 @@ static void tpda_enable_pre_port(struct 
>>> tpda_drvdata *drvdata)
>>> ? static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
>>> ? {
>>> ????? u32 val;
>>> -??? int size;
>>> +??? int rc;
>>> ????? val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
>>> ????? /*
>>> @@ -117,29 +150,21 @@ static int tpda_enable_port(struct 
>>> tpda_drvdata *drvdata, int port)
>>> ?????? * Set the bit to 0 if the size is 32
>>> ?????? * Set the bit to 1 if the size is 64
>>> ?????? */
>
> The comment above is stale, you need to remove it. I noticed it
> after I applied the series for my build tests.
>
> Please could you respin the series with the two issues above fixed ?

Sure, I will update them to the new patch series soon.


Best,

Tao

>
> Suzuki
>
>
>>> -??? size = tpda_get_element_size(drvdata->csdev, port);
>>> -??? switch (size) {
>>> -??? case 32:
>>> -??????? val &= ~TPDA_Pn_CR_DSBSIZE;
>>> -??????? break;
>>> -??? case 64:
>>> -??????? val |= TPDA_Pn_CR_DSBSIZE;
>>> -??????? break;
>>> -??? case 0:
>>> -??????? return -EEXIST;
>>> -??? case -EEXIST:
>>> +??? tpdm_clear_element_size(drvdata->csdev);
>>> +??? rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
>>> +??? if (!rc && (drvdata->dsb_esize || drvdata->cmb_esize)) {
>>> +??????? tpda_set_element_size(drvdata, &val);
>>> +??????? /* Enable the port */
>>> +??????? val |= TPDA_Pn_CR_ENA;
>>> +??????? writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>>> +??? } else if (rc == -EEXIST)
>>> ????????? dev_warn_once(&drvdata->csdev->dev,
>>> -??????????? "Detected multiple TPDMs on port %d", -EEXIST);
>>> -??????? return -EEXIST;
>>> -??? default:
>>> -??????? return -EINVAL;
>>> -??? }
>>> -
>>> -??? /* Enable the port */
>>> -??? val |= TPDA_Pn_CR_ENA;
>>> -??? writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>>> +????????????????? "Detected multiple TPDMs on port %d", port);
>>> +??? else
>>> +??????? dev_warn_once(&drvdata->csdev->dev,
>>> +????????????????? "Didn't find TPDM element size");
>>> -??? return 0;
>>> +??? return rc;
>>> ? }
>>> ? static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h 
>>> b/drivers/hwtracing/coresight/coresight-tpda.h
>>> index b3b38fd41b64..19af64120fcf 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>>> @@ -10,6 +10,8 @@
>>> ? #define TPDA_Pn_CR(n)??????? (0x004 + (n * 4))
>>> ? /* Aggregator port enable bit */
>>> ? #define TPDA_Pn_CR_ENA??????? BIT(0)
>>> +/* Aggregator port CMB data set element size bit */
>>> +#define TPDA_Pn_CR_CMBSIZE??????? GENMASK(7, 6)
>>> ? /* Aggregator port DSB data set element size bit */
>>> ? #define TPDA_Pn_CR_DSBSIZE??????? BIT(8)
>>> @@ -25,6 +27,8 @@
>>> ?? * @csdev:????? component vitals needed by the framework.
>>> ?? * @spinlock:?? lock for the drvdata value.
>>> ?? * @enable:???? enable status of the component.
>>> + * @dsb_esize?? Record the DSB element size.
>>> + * @cmb_esize?? Record the CMB element size.
>>> ?? */
>>> ? struct tpda_drvdata {
>>> ????? void __iomem??????? *base;
>>> @@ -32,6 +36,8 @@ struct tpda_drvdata {
>>> ????? struct coresight_device??? *csdev;
>>> ????? spinlock_t??????? spinlock;
>>> ????? u8??????????? atid;
>>> +??? u8??????????? dsb_esize;
>>> +??? u32??????????? cmb_esize;
>>> ? };
>>> ? #endif? /* _CORESIGHT_CORESIGHT_TPDA_H */
>>
>


From bhe at redhat.com  Sat Feb  3 19:26:12 2024
From: bhe at redhat.com (Baoquan He)
Date: Sun, 4 Feb 2024 11:26:12 +0800
Subject: [PATCH v2 00/14] Split crash out from kexec and clean up related
 config items
In-Reply-To: <9101bb07-70f1-476c-bec9-ec67e9899744@linux.ibm.com>
References: <20240119145241.769622-1-bhe@redhat.com>
 <9101bb07-70f1-476c-bec9-ec67e9899744@linux.ibm.com>
Message-ID: <Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv>

On 02/02/24 at 10:53am, Hari Bathini wrote:
> Hi Baoquan,
> 
> On 19/01/24 8:22 pm, Baoquan He wrote:
> > Motivation:
> > =============
> > Previously, LKP reported a building error. When investigating, it can't
> > be resolved reasonablly with the present messy kdump config items.
> > 
> >   https://lore.kernel.org/oe-kbuild-all/202312182200.Ka7MzifQ-lkp at intel.com/
> > 
> > The kdump (crash dumping) related config items could causes confusions:
> > 
> > Firstly,
> > ---
> > CRASH_CORE enables codes including
> >   - crashkernel reservation;
> >   - elfcorehdr updating;
> >   - vmcoreinfo exporting;
> >   - crash hotplug handling;
> > 
> > Now fadump of powerpc, kcore dynamic debugging and kdump all selects
> > CRASH_CORE, while fadump
> >   - fadump needs crashkernel parsing, vmcoreinfo exporting, and accessing
> >     global variable 'elfcorehdr_addr';
> >   - kcore only needs vmcoreinfo exporting;
> >   - kdump needs all of the current kernel/crash_core.c.
> > 
> > So only enabling PROC_CORE or FA_DUMP will enable CRASH_CORE, this
> > mislead people that we enable crash dumping, actual it's not.
> > 
> > Secondly,
> > ---
> > It's not reasonable to allow KEXEC_CORE select CRASH_CORE.
> > 
> > Because KEXEC_CORE enables codes which allocate control pages, copy
> > kexec/kdump segments, and prepare for switching. These codes are
> > shared by both kexec reboot and kdump. We could want kexec reboot,
> > but disable kdump. In that case, CRASH_CORE should not be selected.
> > 
> >   --------------------
> >   CONFIG_CRASH_CORE=y
> >   CONFIG_KEXEC_CORE=y
> >   CONFIG_KEXEC=y
> >   CONFIG_KEXEC_FILE=y
> >      ---------------------
> > 
> > Thirdly,
> > ---
> > It's not reasonable to allow CRASH_DUMP select KEXEC_CORE.
> > 
> > That could make KEXEC_CORE, CRASH_DUMP are enabled independently from
> > KEXEC or KEXEC_FILE. However, w/o KEXEC or KEXEC_FILE, the KEXEC_CORE
> > code built in doesn't make any sense because no kernel loading or
> > switching will happen to utilize the KEXEC_CORE code.
> >   ---------------------
> >   CONFIG_CRASH_CORE=y
> >   CONFIG_KEXEC_CORE=y
> >   CONFIG_CRASH_DUMP=y
> >   ---------------------
> > 
> > In this case, what is worse, on arch sh and arm, KEXEC relies on MMU,
> > while CRASH_DUMP can still be enabled when !MMU, then compiling error is
> > seen as the lkp test robot reported in above link.
> > 
> >   ------arch/sh/Kconfig------
> >   config ARCH_SUPPORTS_KEXEC
> >           def_bool MMU
> > 
> >   config ARCH_SUPPORTS_CRASH_DUMP
> >           def_bool BROKEN_ON_SMP
> >   ---------------------------
> > 
> > Changes:
> > ===========
> > 1, split out crash_reserve.c from crash_core.c;
> > 2, split out vmcore_infoc. from crash_core.c;
> > 3, move crash related codes in kexec_core.c into crash_core.c;
> > 4, remove dependency of FA_DUMP on CRASH_DUMP;
> > 5, clean up kdump related config items;
> > 6, wrap up crash codes in crash related ifdefs on all 9 arch-es
> >     which support crash dumping;
> > 
> > Achievement:
> > ===========
> > With above changes, I can rearrange the config item logic as below (the right
> > item depends on or is selected by the left item):
> > 
> >      PROC_KCORE -----------> VMCORE_INFO
> > 
> >                 |----------> VMCORE_INFO
> >      FA_DUMP----|
> >                 |----------> CRASH_RESERVE
> 
> FA_DUMP also needs PROC_VMCORE (CRASH_DUMP by dependency, I guess).
> So, the FA_DUMP related changes here will need a relook..

Thanks for checking this.

So FA_DUMP needs vmcoreinfo exporting, crashkernel reservation,
/proc/vmcore. Then it's easy to adjust the kernel config item of FA_DUMP
to make it select CRASH_DUMP. Except of this, do you have concern about
the current code and Kconfig refactorying?


                           ---->VMCORE_INFO
                         /|
FA_DUMP--> CRASH_DUMP-->/-|---->CRASH_RESERVE
                        \ |
                          \---->PROC_VMCORE


> 
> 
> >                                                      ---->VMCORE_INFO
> >                                                     /
> >                                                     |---->CRASH_RESERVE
> >      KEXEC      --|                                /|
> >                   |--> KEXEC_CORE--> CRASH_DUMP-->/-|---->PROC_VMCORE
> >      KEXEC_FILE --|                               \ |
> >                                                     \---->CRASH_HOTPLUG
> > 
> > 
> >      KEXEC      --|
> >                   |--> KEXEC_CORE (for kexec reboot only)
> >      KEXEC_FILE --|
> > 
> > Test
> > ========
> > On all 8 architectures, including x86_64, arm64, s390x, sh, arm, mips,
> > riscv, loongarch, I did below three cases of config item setting and
> > building all passed. Let me take configs on x86_64 as exampmle here:
> > 
> > (1) Both CONFIG_KEXEC and KEXEC_FILE is unset, then all kexec/kdump
> > items are unset automatically:
> > # Kexec and crash features
> > # CONFIG_KEXEC is not set
> > # CONFIG_KEXEC_FILE is not set
> > # end of Kexec and crash features
> > 
> > (2) set CONFIG_KEXEC_FILE and 'make olddefconfig':
> > ---------------
> > # Kexec and crash features
> > CONFIG_CRASH_RESERVE=y
> > CONFIG_VMCORE_INFO=y
> > CONFIG_KEXEC_CORE=y
> > CONFIG_KEXEC_FILE=y
> > CONFIG_CRASH_DUMP=y
> > CONFIG_CRASH_HOTPLUG=y
> > CONFIG_CRASH_MAX_MEMORY_RANGES=8192
> > # end of Kexec and crash features
> > ---------------
> > 
> > (3) unset CONFIG_CRASH_DUMP in case 2 and execute 'make olddefconfig':
> > ------------------------
> > # Kexec and crash features
> > CONFIG_KEXEC_CORE=y
> > CONFIG_KEXEC_FILE=y
> > # end of Kexec and crash features
> > ------------------------
> > 
> > Note:
> > For ppc, it needs investigation to make clear how to split out crash
> > code in arch folder.
> 
> On powerpc, both kdump and fadump need PROC_VMCORE & CRASH_DUMP.
> Hope that clears things. So, patch 3/14 breaks things for FA_DUMP..

I see it now. We can easily fix that with below patch. What do you
think?

By the way, do you have chance to help test these on powerpc system?
I can find ppc64le machine, while I don't know how to operate to test
fadump.

>From fa8e6c3930d4f22f2b3768399c5bf0523c17adde Mon Sep 17 00:00:00 2001
From: Baoquan He <bhe at redhat.com>
Date: Sun, 4 Feb 2024 11:06:54 +0800
Subject: [PATCH] power/fadump: make FA_DUMP select CRASH_DUMP
Content-type: text/plain

FA_DUMP which is similar with kdump needs vmcoreinfo exporting,
crashkernel reservation and /proc/vmcore file . After refactoring crash
related codes and Kconfig items, make FA_DUMP select CRASH_DUMP. Now
the dependency layout is like below:

                           ---->VMCORE_INFO
                         /|
FA_DUMP--> CRASH_DUMP-->/-|---->CRASH_RESERVE
                        \ |
                          \---->PROC_VMCORE

Signed-off-by: Baoquan He <bhe at redhat.com>
---
 arch/powerpc/Kconfig | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index f182fb354bef..d5d4c890f010 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -695,8 +695,7 @@ config ARCH_SELECTS_CRASH_DUMP
 config FA_DUMP
 	bool "Firmware-assisted dump"
 	depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
-	select VMCORE_INFO
-	select CRASH_RESERVE
+	select CRASH_DUMP
 	help
 	  A robust mechanism to get reliable kernel crash dump with
 	  assistance from firmware. This approach does not use kexec,
-- 
2.41.0


> 
> > Hope Hari and Pingfan can help have a look, see if
> > it's doable. Now, I make it either have both kexec and crash enabled, or
> > disable both of them altogether.
> 
> 
> Sure. I will take a closer look...

Thanks a lot. Please feel free to post patches to make that, or I can do
it with your support or suggestion.



From lkp at intel.com  Sat Feb  3 20:04:48 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 4 Feb 2024 12:04:48 +0800
Subject: [PATCH 4/5] firmware: imx: support BBM module
In-Reply-To: <20240202-imx95-bbm-misc-v1-4-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-4-3cb743020933@nxp.com>
Message-ID: <202402041140.l2qPp6Gn-lkp@intel.com>

Hi Peng,

kernel test robot noticed the following build errors:

[auto build test ERROR on 51b70ff55ed88edd19b080a524063446bcc34b62]

url:    https://github.com/intel-lab-lkp/linux/commits/Peng-Fan-OSS/dt-bindings-firmware-add-i-MX-SCMI-Extension-protocol/20240202-143439
base:   51b70ff55ed88edd19b080a524063446bcc34b62
patch link:    https://lore.kernel.org/r/20240202-imx95-bbm-misc-v1-4-3cb743020933%40nxp.com
patch subject: [PATCH 4/5] firmware: imx: support BBM module
config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20240204/202402041140.l2qPp6Gn-lkp at intel.com/config)
compiler: s390-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240204/202402041140.l2qPp6Gn-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402041140.l2qPp6Gn-lkp at intel.com/

All errors (new ones prefixed by >>):

   s390-linux-ld: drivers/firmware/imx/sm-bbm.o: in function `scmi_imx_bbm_probe':
>> sm-bbm.c:(.text+0xbdc): undefined reference to `devm_rtc_allocate_device'
>> s390-linux-ld: sm-bbm.c:(.text+0xc90): undefined reference to `__devm_rtc_register_device'
   s390-linux-ld: drivers/firmware/imx/sm-bbm.o: in function `scmi_imx_bbm_notifier':
>> sm-bbm.c:(.text+0xeb6): undefined reference to `rtc_update_irq'

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From jszhang at kernel.org  Sat Feb  3 20:21:22 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sun, 4 Feb 2024 12:21:22 +0800
Subject: [PATCH net v3] net: stmmac: protect updates of 64-bit statistics
 counters
In-Reply-To: <20240203190927.19669-1-petr@tesarici.cz>
References: <20240203190927.19669-1-petr@tesarici.cz>
Message-ID: <Zb8QwgYSh9sX8zBi@xhacker>

On Sat, Feb 03, 2024 at 08:09:27PM +0100, Petr Tesarik wrote:
> As explained by a comment in <linux/u64_stats_sync.h>, write side of struct
> u64_stats_sync must ensure mutual exclusion, or one seqcount update could
> be lost on 32-bit platforms, thus blocking readers forever. Such lockups
> have been observed in real world after stmmac_xmit() on one CPU raced with
> stmmac_napi_poll_tx() on another CPU.
> 
> To fix the issue without introducing a new lock, split the statics into
> three parts:
> 
> 1. fields updated only under the tx queue lock,
> 2. fields updated only during NAPI poll,
> 3. fields updated only from interrupt context,
> 
> Updates to fields in the first two groups are already serialized through
> other locks. It is sufficient to split the existing struct u64_stats_sync
> so that each group has its own.
> 
> Note that tx_set_ic_bit is updated from both contexts. Split this counter
> so that each context gets its own, and calculate their sum to get the total
> value in stmmac_get_ethtool_stats().
> 
> For the third group, multiple interrupts may be processed by different CPUs
> at the same time, but interrupts on the same CPU will not nest. Move fields
> from this group to a newly created per-cpu struct stmmac_pcpu_stats.
> 
> Fixes: 133466c3bbe1 ("net: stmmac: use per-queue 64 bit statistics where necessary")
> Link: https://lore.kernel.org/netdev/Za173PhviYg-1qIn at torres.zugschlus.de/t/
> Cc: stable at vger.kernel.org
> Signed-off-by: Petr Tesarik <petr at tesarici.cz>

Reviewed-by: Jisheng Zhang <jszhang at kernel.org>

> ---
>  drivers/net/ethernet/stmicro/stmmac/common.h  |  56 +++++---
>  .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c |  15 +-
>  .../net/ethernet/stmicro/stmmac/dwmac4_lib.c  |  15 +-
>  .../net/ethernet/stmicro/stmmac/dwmac_lib.c   |  15 +-
>  .../ethernet/stmicro/stmmac/dwxgmac2_dma.c    |  15 +-
>  .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 129 +++++++++++------
>  .../net/ethernet/stmicro/stmmac/stmmac_main.c | 133 +++++++++---------
>  7 files changed, 221 insertions(+), 157 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 721c1f8e892f..4aca20feb4b7 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -59,28 +59,51 @@
>  #undef FRAME_FILTER_DEBUG
>  /* #define FRAME_FILTER_DEBUG */
>  
> +struct stmmac_q_tx_stats {
> +	u64_stats_t tx_bytes;
> +	u64_stats_t tx_set_ic_bit;
> +	u64_stats_t tx_tso_frames;
> +	u64_stats_t tx_tso_nfrags;
> +};
> +
> +struct stmmac_napi_tx_stats {
> +	u64_stats_t tx_packets;
> +	u64_stats_t tx_pkt_n;
> +	u64_stats_t poll;
> +	u64_stats_t tx_clean;
> +	u64_stats_t tx_set_ic_bit;
> +};
> +
>  struct stmmac_txq_stats {
> -	u64 tx_bytes;
> -	u64 tx_packets;
> -	u64 tx_pkt_n;
> -	u64 tx_normal_irq_n;
> -	u64 napi_poll;
> -	u64 tx_clean;
> -	u64 tx_set_ic_bit;
> -	u64 tx_tso_frames;
> -	u64 tx_tso_nfrags;
> -	struct u64_stats_sync syncp;
> +	/* Updates protected by tx queue lock. */
> +	struct u64_stats_sync q_syncp;
> +	struct stmmac_q_tx_stats q;
> +
> +	/* Updates protected by NAPI poll logic. */
> +	struct u64_stats_sync napi_syncp;
> +	struct stmmac_napi_tx_stats napi;
>  } ____cacheline_aligned_in_smp;
>  
> +struct stmmac_napi_rx_stats {
> +	u64_stats_t rx_bytes;
> +	u64_stats_t rx_packets;
> +	u64_stats_t rx_pkt_n;
> +	u64_stats_t poll;
> +};
> +
>  struct stmmac_rxq_stats {
> -	u64 rx_bytes;
> -	u64 rx_packets;
> -	u64 rx_pkt_n;
> -	u64 rx_normal_irq_n;
> -	u64 napi_poll;
> -	struct u64_stats_sync syncp;
> +	/* Updates protected by NAPI poll logic. */
> +	struct u64_stats_sync napi_syncp;
> +	struct stmmac_napi_rx_stats napi;
>  } ____cacheline_aligned_in_smp;
>  
> +/* Updates on each CPU protected by not allowing nested irqs. */
> +struct stmmac_pcpu_stats {
> +	struct u64_stats_sync syncp;
> +	u64_stats_t rx_normal_irq_n[MTL_MAX_TX_QUEUES];
> +	u64_stats_t tx_normal_irq_n[MTL_MAX_RX_QUEUES];
> +};
> +
>  /* Extra statistic and debug information exposed by ethtool */
>  struct stmmac_extra_stats {
>  	/* Transmit errors */
> @@ -205,6 +228,7 @@ struct stmmac_extra_stats {
>  	/* per queue statistics */
>  	struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES];
>  	struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES];
> +	struct stmmac_pcpu_stats __percpu *pcpu_stats;
>  	unsigned long rx_dropped;
>  	unsigned long rx_errors;
>  	unsigned long tx_dropped;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> index 137741b94122..b21d99faa2d0 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> @@ -441,8 +441,7 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
>  				     struct stmmac_extra_stats *x, u32 chan,
>  				     u32 dir)
>  {
> -	struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
> -	struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
> +	struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
>  	int ret = 0;
>  	u32 v;
>  
> @@ -455,9 +454,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
>  
>  	if (v & EMAC_TX_INT) {
>  		ret |= handle_tx;
> -		u64_stats_update_begin(&txq_stats->syncp);
> -		txq_stats->tx_normal_irq_n++;
> -		u64_stats_update_end(&txq_stats->syncp);
> +		u64_stats_update_begin(&stats->syncp);
> +		u64_stats_inc(&stats->tx_normal_irq_n[chan]);
> +		u64_stats_update_end(&stats->syncp);
>  	}
>  
>  	if (v & EMAC_TX_DMA_STOP_INT)
> @@ -479,9 +478,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
>  
>  	if (v & EMAC_RX_INT) {
>  		ret |= handle_rx;
> -		u64_stats_update_begin(&rxq_stats->syncp);
> -		rxq_stats->rx_normal_irq_n++;
> -		u64_stats_update_end(&rxq_stats->syncp);
> +		u64_stats_update_begin(&stats->syncp);
> +		u64_stats_inc(&stats->rx_normal_irq_n[chan]);
> +		u64_stats_update_end(&stats->syncp);
>  	}
>  
>  	if (v & EMAC_RX_BUF_UA_INT)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> index 9470d3fd2ded..0d185e54eb7e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> @@ -171,8 +171,7 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
>  	const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
>  	u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan));
>  	u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
> -	struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
> -	struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
> +	struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
>  	int ret = 0;
>  
>  	if (dir == DMA_DIR_RX)
> @@ -201,15 +200,15 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
>  	}
>  	/* TX/RX NORMAL interrupts */
>  	if (likely(intr_status & DMA_CHAN_STATUS_RI)) {
> -		u64_stats_update_begin(&rxq_stats->syncp);
> -		rxq_stats->rx_normal_irq_n++;
> -		u64_stats_update_end(&rxq_stats->syncp);
> +		u64_stats_update_begin(&stats->syncp);
> +		u64_stats_inc(&stats->rx_normal_irq_n[chan]);
> +		u64_stats_update_end(&stats->syncp);
>  		ret |= handle_rx;
>  	}
>  	if (likely(intr_status & DMA_CHAN_STATUS_TI)) {
> -		u64_stats_update_begin(&txq_stats->syncp);
> -		txq_stats->tx_normal_irq_n++;
> -		u64_stats_update_end(&txq_stats->syncp);
> +		u64_stats_update_begin(&stats->syncp);
> +		u64_stats_inc(&stats->tx_normal_irq_n[chan]);
> +		u64_stats_update_end(&stats->syncp);
>  		ret |= handle_tx;
>  	}
>  
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> index 7907d62d3437..85e18f9a22f9 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> @@ -162,8 +162,7 @@ static void show_rx_process_state(unsigned int status)
>  int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
>  			struct stmmac_extra_stats *x, u32 chan, u32 dir)
>  {
> -	struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
> -	struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
> +	struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
>  	int ret = 0;
>  	/* read the status register (CSR5) */
>  	u32 intr_status = readl(ioaddr + DMA_STATUS);
> @@ -215,16 +214,16 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
>  			u32 value = readl(ioaddr + DMA_INTR_ENA);
>  			/* to schedule NAPI on real RIE event. */
>  			if (likely(value & DMA_INTR_ENA_RIE)) {
> -				u64_stats_update_begin(&rxq_stats->syncp);
> -				rxq_stats->rx_normal_irq_n++;
> -				u64_stats_update_end(&rxq_stats->syncp);
> +				u64_stats_update_begin(&stats->syncp);
> +				u64_stats_inc(&stats->rx_normal_irq_n[chan]);
> +				u64_stats_update_end(&stats->syncp);
>  				ret |= handle_rx;
>  			}
>  		}
>  		if (likely(intr_status & DMA_STATUS_TI)) {
> -			u64_stats_update_begin(&txq_stats->syncp);
> -			txq_stats->tx_normal_irq_n++;
> -			u64_stats_update_end(&txq_stats->syncp);
> +			u64_stats_update_begin(&stats->syncp);
> +			u64_stats_inc(&stats->tx_normal_irq_n[chan]);
> +			u64_stats_update_end(&stats->syncp);
>  			ret |= handle_tx;
>  		}
>  		if (unlikely(intr_status & DMA_STATUS_ERI))
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
> index 3cde695fec91..dd2ab6185c40 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
> @@ -337,8 +337,7 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
>  				  struct stmmac_extra_stats *x, u32 chan,
>  				  u32 dir)
>  {
> -	struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan];
> -	struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan];
> +	struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
>  	u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
>  	u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
>  	int ret = 0;
> @@ -367,15 +366,15 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
>  	/* TX/RX NORMAL interrupts */
>  	if (likely(intr_status & XGMAC_NIS)) {
>  		if (likely(intr_status & XGMAC_RI)) {
> -			u64_stats_update_begin(&rxq_stats->syncp);
> -			rxq_stats->rx_normal_irq_n++;
> -			u64_stats_update_end(&rxq_stats->syncp);
> +			u64_stats_update_begin(&stats->syncp);
> +			u64_stats_inc(&stats->rx_normal_irq_n[chan]);
> +			u64_stats_update_end(&stats->syncp);
>  			ret |= handle_rx;
>  		}
>  		if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) {
> -			u64_stats_update_begin(&txq_stats->syncp);
> -			txq_stats->tx_normal_irq_n++;
> -			u64_stats_update_end(&txq_stats->syncp);
> +			u64_stats_update_begin(&stats->syncp);
> +			u64_stats_inc(&stats->tx_normal_irq_n[chan]);
> +			u64_stats_update_end(&stats->syncp);
>  			ret |= handle_tx;
>  		}
>  	}
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> index 42d27b97dd1d..ec44becf0e2d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> @@ -549,44 +549,79 @@ stmmac_set_pauseparam(struct net_device *netdev,
>  	}
>  }
>  
> +static u64 stmmac_get_rx_normal_irq_n(struct stmmac_priv *priv, int q)
> +{
> +	u64 total;
> +	int cpu;
> +
> +	total = 0;
> +	for_each_possible_cpu(cpu) {
> +		struct stmmac_pcpu_stats *pcpu;
> +		unsigned int start;
> +		u64 irq_n;
> +
> +		pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu);
> +		do {
> +			start = u64_stats_fetch_begin(&pcpu->syncp);
> +			irq_n = u64_stats_read(&pcpu->rx_normal_irq_n[q]);
> +		} while (u64_stats_fetch_retry(&pcpu->syncp, start));
> +		total += irq_n;
> +	}
> +	return total;
> +}
> +
> +static u64 stmmac_get_tx_normal_irq_n(struct stmmac_priv *priv, int q)
> +{
> +	u64 total;
> +	int cpu;
> +
> +	total = 0;
> +	for_each_possible_cpu(cpu) {
> +		struct stmmac_pcpu_stats *pcpu;
> +		unsigned int start;
> +		u64 irq_n;
> +
> +		pcpu = per_cpu_ptr(priv->xstats.pcpu_stats, cpu);
> +		do {
> +			start = u64_stats_fetch_begin(&pcpu->syncp);
> +			irq_n = u64_stats_read(&pcpu->tx_normal_irq_n[q]);
> +		} while (u64_stats_fetch_retry(&pcpu->syncp, start));
> +		total += irq_n;
> +	}
> +	return total;
> +}
> +
>  static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
>  {
>  	u32 tx_cnt = priv->plat->tx_queues_to_use;
>  	u32 rx_cnt = priv->plat->rx_queues_to_use;
>  	unsigned int start;
> -	int q, stat;
> -	char *p;
> +	int q;
>  
>  	for (q = 0; q < tx_cnt; q++) {
>  		struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q];
> -		struct stmmac_txq_stats snapshot;
> +		u64 pkt_n;
>  
>  		do {
> -			start = u64_stats_fetch_begin(&txq_stats->syncp);
> -			snapshot = *txq_stats;
> -		} while (u64_stats_fetch_retry(&txq_stats->syncp, start));
> +			start = u64_stats_fetch_begin(&txq_stats->napi_syncp);
> +			pkt_n = u64_stats_read(&txq_stats->napi.tx_pkt_n);
> +		} while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));
>  
> -		p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n);
> -		for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
> -			*data++ = (*(u64 *)p);
> -			p += sizeof(u64);
> -		}
> +		*data++ = pkt_n;
> +		*data++ = stmmac_get_tx_normal_irq_n(priv, q);
>  	}
>  
>  	for (q = 0; q < rx_cnt; q++) {
>  		struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q];
> -		struct stmmac_rxq_stats snapshot;
> +		u64 pkt_n;
>  
>  		do {
> -			start = u64_stats_fetch_begin(&rxq_stats->syncp);
> -			snapshot = *rxq_stats;
> -		} while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
> +			start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);
> +			pkt_n = u64_stats_read(&rxq_stats->napi.rx_pkt_n);
> +		} while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));
>  
> -		p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n);
> -		for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
> -			*data++ = (*(u64 *)p);
> -			p += sizeof(u64);
> -		}
> +		*data++ = pkt_n;
> +		*data++ = stmmac_get_rx_normal_irq_n(priv, q);
>  	}
>  }
>  
> @@ -645,39 +680,49 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
>  	pos = j;
>  	for (i = 0; i < rx_queues_count; i++) {
>  		struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[i];
> -		struct stmmac_rxq_stats snapshot;
> +		struct stmmac_napi_rx_stats snapshot;
> +		u64 n_irq;
>  
>  		j = pos;
>  		do {
> -			start = u64_stats_fetch_begin(&rxq_stats->syncp);
> -			snapshot = *rxq_stats;
> -		} while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
> -
> -		data[j++] += snapshot.rx_pkt_n;
> -		data[j++] += snapshot.rx_normal_irq_n;
> -		normal_irq_n += snapshot.rx_normal_irq_n;
> -		napi_poll += snapshot.napi_poll;
> +			start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);
> +			snapshot = rxq_stats->napi;
> +		} while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));
> +
> +		data[j++] += u64_stats_read(&snapshot.rx_pkt_n);
> +		n_irq = stmmac_get_rx_normal_irq_n(priv, i);
> +		data[j++] += n_irq;
> +		normal_irq_n += n_irq;
> +		napi_poll += u64_stats_read(&snapshot.poll);
>  	}
>  
>  	pos = j;
>  	for (i = 0; i < tx_queues_count; i++) {
>  		struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[i];
> -		struct stmmac_txq_stats snapshot;
> +		struct stmmac_napi_tx_stats napi_snapshot;
> +		struct stmmac_q_tx_stats q_snapshot;
> +		u64 n_irq;
>  
>  		j = pos;
>  		do {
> -			start = u64_stats_fetch_begin(&txq_stats->syncp);
> -			snapshot = *txq_stats;
> -		} while (u64_stats_fetch_retry(&txq_stats->syncp, start));
> -
> -		data[j++] += snapshot.tx_pkt_n;
> -		data[j++] += snapshot.tx_normal_irq_n;
> -		normal_irq_n += snapshot.tx_normal_irq_n;
> -		data[j++] += snapshot.tx_clean;
> -		data[j++] += snapshot.tx_set_ic_bit;
> -		data[j++] += snapshot.tx_tso_frames;
> -		data[j++] += snapshot.tx_tso_nfrags;
> -		napi_poll += snapshot.napi_poll;
> +			start = u64_stats_fetch_begin(&txq_stats->q_syncp);
> +			q_snapshot = txq_stats->q;
> +		} while (u64_stats_fetch_retry(&txq_stats->q_syncp, start));
> +		do {
> +			start = u64_stats_fetch_begin(&txq_stats->napi_syncp);
> +			napi_snapshot = txq_stats->napi;
> +		} while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));
> +
> +		data[j++] += u64_stats_read(&napi_snapshot.tx_pkt_n);
> +		n_irq = stmmac_get_tx_normal_irq_n(priv, i);
> +		data[j++] += n_irq;
> +		normal_irq_n += n_irq;
> +		data[j++] += u64_stats_read(&napi_snapshot.tx_clean);
> +		data[j++] += u64_stats_read(&q_snapshot.tx_set_ic_bit) +
> +			u64_stats_read(&napi_snapshot.tx_set_ic_bit);
> +		data[j++] += u64_stats_read(&q_snapshot.tx_tso_frames);
> +		data[j++] += u64_stats_read(&q_snapshot.tx_tso_nfrags);
> +		napi_poll += u64_stats_read(&napi_snapshot.poll);
>  	}
>  	normal_irq_n += priv->xstats.rx_early_irq;
>  	data[j++] = normal_irq_n;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 25519952f754..75d029704503 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -2482,7 +2482,6 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
>  	struct xdp_desc xdp_desc;
>  	bool work_done = true;
>  	u32 tx_set_ic_bit = 0;
> -	unsigned long flags;
>  
>  	/* Avoids TX time-out as we are sharing with slow path */
>  	txq_trans_cond_update(nq);
> @@ -2566,9 +2565,9 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
>  		tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
>  		entry = tx_q->cur_tx;
>  	}
> -	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
> -	txq_stats->tx_set_ic_bit += tx_set_ic_bit;
> -	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
> +	u64_stats_update_begin(&txq_stats->napi_syncp);
> +	u64_stats_add(&txq_stats->napi.tx_set_ic_bit, tx_set_ic_bit);
> +	u64_stats_update_end(&txq_stats->napi_syncp);
>  
>  	if (tx_desc) {
>  		stmmac_flush_tx_descriptors(priv, queue);
> @@ -2616,7 +2615,6 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue,
>  	unsigned int bytes_compl = 0, pkts_compl = 0;
>  	unsigned int entry, xmits = 0, count = 0;
>  	u32 tx_packets = 0, tx_errors = 0;
> -	unsigned long flags;
>  
>  	__netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue));
>  
> @@ -2782,11 +2780,11 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue,
>  	if (tx_q->dirty_tx != tx_q->cur_tx)
>  		*pending_packets = true;
>  
> -	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
> -	txq_stats->tx_packets += tx_packets;
> -	txq_stats->tx_pkt_n += tx_packets;
> -	txq_stats->tx_clean++;
> -	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
> +	u64_stats_update_begin(&txq_stats->napi_syncp);
> +	u64_stats_add(&txq_stats->napi.tx_packets, tx_packets);
> +	u64_stats_add(&txq_stats->napi.tx_pkt_n, tx_packets);
> +	u64_stats_inc(&txq_stats->napi.tx_clean);
> +	u64_stats_update_end(&txq_stats->napi_syncp);
>  
>  	priv->xstats.tx_errors += tx_errors;
>  
> @@ -4213,7 +4211,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>  	struct stmmac_tx_queue *tx_q;
>  	bool has_vlan, set_ic;
>  	u8 proto_hdr_len, hdr;
> -	unsigned long flags;
>  	u32 pay_len, mss;
>  	dma_addr_t des;
>  	int i;
> @@ -4378,13 +4375,13 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>  		netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue));
>  	}
>  
> -	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
> -	txq_stats->tx_bytes += skb->len;
> -	txq_stats->tx_tso_frames++;
> -	txq_stats->tx_tso_nfrags += nfrags;
> +	u64_stats_update_begin(&txq_stats->q_syncp);
> +	u64_stats_add(&txq_stats->q.tx_bytes, skb->len);
> +	u64_stats_inc(&txq_stats->q.tx_tso_frames);
> +	u64_stats_add(&txq_stats->q.tx_tso_nfrags, nfrags);
>  	if (set_ic)
> -		txq_stats->tx_set_ic_bit++;
> -	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
> +		u64_stats_inc(&txq_stats->q.tx_set_ic_bit);
> +	u64_stats_update_end(&txq_stats->q_syncp);
>  
>  	if (priv->sarc_type)
>  		stmmac_set_desc_sarc(priv, first, priv->sarc_type);
> @@ -4483,7 +4480,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
>  	struct stmmac_tx_queue *tx_q;
>  	bool has_vlan, set_ic;
>  	int entry, first_tx;
> -	unsigned long flags;
>  	dma_addr_t des;
>  
>  	tx_q = &priv->dma_conf.tx_queue[queue];
> @@ -4653,11 +4649,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
>  		netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue));
>  	}
>  
> -	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
> -	txq_stats->tx_bytes += skb->len;
> +	u64_stats_update_begin(&txq_stats->q_syncp);
> +	u64_stats_add(&txq_stats->q.tx_bytes, skb->len);
>  	if (set_ic)
> -		txq_stats->tx_set_ic_bit++;
> -	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
> +		u64_stats_inc(&txq_stats->q.tx_set_ic_bit);
> +	u64_stats_update_end(&txq_stats->q_syncp);
>  
>  	if (priv->sarc_type)
>  		stmmac_set_desc_sarc(priv, first, priv->sarc_type);
> @@ -4921,12 +4917,11 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
>  		set_ic = false;
>  
>  	if (set_ic) {
> -		unsigned long flags;
>  		tx_q->tx_count_frames = 0;
>  		stmmac_set_tx_ic(priv, tx_desc);
> -		flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
> -		txq_stats->tx_set_ic_bit++;
> -		u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
> +		u64_stats_update_begin(&txq_stats->q_syncp);
> +		u64_stats_inc(&txq_stats->q.tx_set_ic_bit);
> +		u64_stats_update_end(&txq_stats->q_syncp);
>  	}
>  
>  	stmmac_enable_dma_transmission(priv, priv->ioaddr);
> @@ -5076,7 +5071,6 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
>  	unsigned int len = xdp->data_end - xdp->data;
>  	enum pkt_hash_types hash_type;
>  	int coe = priv->hw->rx_csum;
> -	unsigned long flags;
>  	struct sk_buff *skb;
>  	u32 hash;
>  
> @@ -5106,10 +5100,10 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
>  	skb_record_rx_queue(skb, queue);
>  	napi_gro_receive(&ch->rxtx_napi, skb);
>  
> -	flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
> -	rxq_stats->rx_pkt_n++;
> -	rxq_stats->rx_bytes += len;
> -	u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
> +	u64_stats_update_begin(&rxq_stats->napi_syncp);
> +	u64_stats_inc(&rxq_stats->napi.rx_pkt_n);
> +	u64_stats_add(&rxq_stats->napi.rx_bytes, len);
> +	u64_stats_update_end(&rxq_stats->napi_syncp);
>  }
>  
>  static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
> @@ -5191,7 +5185,6 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
>  	unsigned int desc_size;
>  	struct bpf_prog *prog;
>  	bool failure = false;
> -	unsigned long flags;
>  	int xdp_status = 0;
>  	int status = 0;
>  
> @@ -5346,9 +5339,9 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
>  
>  	stmmac_finalize_xdp_rx(priv, xdp_status);
>  
> -	flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
> -	rxq_stats->rx_pkt_n += count;
> -	u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
> +	u64_stats_update_begin(&rxq_stats->napi_syncp);
> +	u64_stats_add(&rxq_stats->napi.rx_pkt_n, count);
> +	u64_stats_update_end(&rxq_stats->napi_syncp);
>  
>  	priv->xstats.rx_dropped += rx_dropped;
>  	priv->xstats.rx_errors += rx_errors;
> @@ -5386,7 +5379,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
>  	unsigned int desc_size;
>  	struct sk_buff *skb = NULL;
>  	struct stmmac_xdp_buff ctx;
> -	unsigned long flags;
>  	int xdp_status = 0;
>  	int buf_sz;
>  
> @@ -5646,11 +5638,11 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
>  
>  	stmmac_rx_refill(priv, queue);
>  
> -	flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
> -	rxq_stats->rx_packets += rx_packets;
> -	rxq_stats->rx_bytes += rx_bytes;
> -	rxq_stats->rx_pkt_n += count;
> -	u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
> +	u64_stats_update_begin(&rxq_stats->napi_syncp);
> +	u64_stats_add(&rxq_stats->napi.rx_packets, rx_packets);
> +	u64_stats_add(&rxq_stats->napi.rx_bytes, rx_bytes);
> +	u64_stats_add(&rxq_stats->napi.rx_pkt_n, count);
> +	u64_stats_update_end(&rxq_stats->napi_syncp);
>  
>  	priv->xstats.rx_dropped += rx_dropped;
>  	priv->xstats.rx_errors += rx_errors;
> @@ -5665,13 +5657,12 @@ static int stmmac_napi_poll_rx(struct napi_struct *napi, int budget)
>  	struct stmmac_priv *priv = ch->priv_data;
>  	struct stmmac_rxq_stats *rxq_stats;
>  	u32 chan = ch->index;
> -	unsigned long flags;
>  	int work_done;
>  
>  	rxq_stats = &priv->xstats.rxq_stats[chan];
> -	flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
> -	rxq_stats->napi_poll++;
> -	u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
> +	u64_stats_update_begin(&rxq_stats->napi_syncp);
> +	u64_stats_inc(&rxq_stats->napi.poll);
> +	u64_stats_update_end(&rxq_stats->napi_syncp);
>  
>  	work_done = stmmac_rx(priv, budget, chan);
>  	if (work_done < budget && napi_complete_done(napi, work_done)) {
> @@ -5693,13 +5684,12 @@ static int stmmac_napi_poll_tx(struct napi_struct *napi, int budget)
>  	struct stmmac_txq_stats *txq_stats;
>  	bool pending_packets = false;
>  	u32 chan = ch->index;
> -	unsigned long flags;
>  	int work_done;
>  
>  	txq_stats = &priv->xstats.txq_stats[chan];
> -	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
> -	txq_stats->napi_poll++;
> -	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
> +	u64_stats_update_begin(&txq_stats->napi_syncp);
> +	u64_stats_inc(&txq_stats->napi.poll);
> +	u64_stats_update_end(&txq_stats->napi_syncp);
>  
>  	work_done = stmmac_tx_clean(priv, budget, chan, &pending_packets);
>  	work_done = min(work_done, budget);
> @@ -5729,17 +5719,16 @@ static int stmmac_napi_poll_rxtx(struct napi_struct *napi, int budget)
>  	struct stmmac_rxq_stats *rxq_stats;
>  	struct stmmac_txq_stats *txq_stats;
>  	u32 chan = ch->index;
> -	unsigned long flags;
>  
>  	rxq_stats = &priv->xstats.rxq_stats[chan];
> -	flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp);
> -	rxq_stats->napi_poll++;
> -	u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags);
> +	u64_stats_update_begin(&rxq_stats->napi_syncp);
> +	u64_stats_inc(&rxq_stats->napi.poll);
> +	u64_stats_update_end(&rxq_stats->napi_syncp);
>  
>  	txq_stats = &priv->xstats.txq_stats[chan];
> -	flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
> -	txq_stats->napi_poll++;
> -	u64_stats_update_end_irqrestore(&txq_stats->syncp, flags);
> +	u64_stats_update_begin(&txq_stats->napi_syncp);
> +	u64_stats_inc(&txq_stats->napi.poll);
> +	u64_stats_update_end(&txq_stats->napi_syncp);
>  
>  	tx_done = stmmac_tx_clean(priv, budget, chan, &tx_pending_packets);
>  	tx_done = min(tx_done, budget);
> @@ -7065,10 +7054,13 @@ static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64
>  		u64 tx_bytes;
>  
>  		do {
> -			start = u64_stats_fetch_begin(&txq_stats->syncp);
> -			tx_packets = txq_stats->tx_packets;
> -			tx_bytes   = txq_stats->tx_bytes;
> -		} while (u64_stats_fetch_retry(&txq_stats->syncp, start));
> +			start = u64_stats_fetch_begin(&txq_stats->q_syncp);
> +			tx_bytes   = u64_stats_read(&txq_stats->q.tx_bytes);
> +		} while (u64_stats_fetch_retry(&txq_stats->q_syncp, start));
> +		do {
> +			start = u64_stats_fetch_begin(&txq_stats->napi_syncp);
> +			tx_packets = u64_stats_read(&txq_stats->napi.tx_packets);
> +		} while (u64_stats_fetch_retry(&txq_stats->napi_syncp, start));
>  
>  		stats->tx_packets += tx_packets;
>  		stats->tx_bytes += tx_bytes;
> @@ -7080,10 +7072,10 @@ static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64
>  		u64 rx_bytes;
>  
>  		do {
> -			start = u64_stats_fetch_begin(&rxq_stats->syncp);
> -			rx_packets = rxq_stats->rx_packets;
> -			rx_bytes   = rxq_stats->rx_bytes;
> -		} while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
> +			start = u64_stats_fetch_begin(&rxq_stats->napi_syncp);
> +			rx_packets = u64_stats_read(&rxq_stats->napi.rx_packets);
> +			rx_bytes   = u64_stats_read(&rxq_stats->napi.rx_bytes);
> +		} while (u64_stats_fetch_retry(&rxq_stats->napi_syncp, start));
>  
>  		stats->rx_packets += rx_packets;
>  		stats->rx_bytes += rx_bytes;
> @@ -7477,9 +7469,16 @@ int stmmac_dvr_probe(struct device *device,
>  	priv->dev = ndev;
>  
>  	for (i = 0; i < MTL_MAX_RX_QUEUES; i++)
> -		u64_stats_init(&priv->xstats.rxq_stats[i].syncp);
> -	for (i = 0; i < MTL_MAX_TX_QUEUES; i++)
> -		u64_stats_init(&priv->xstats.txq_stats[i].syncp);
> +		u64_stats_init(&priv->xstats.rxq_stats[i].napi_syncp);
> +	for (i = 0; i < MTL_MAX_TX_QUEUES; i++) {
> +		u64_stats_init(&priv->xstats.txq_stats[i].q_syncp);
> +		u64_stats_init(&priv->xstats.txq_stats[i].napi_syncp);
> +	}
> +
> +	priv->xstats.pcpu_stats =
> +		devm_netdev_alloc_pcpu_stats(device, struct stmmac_pcpu_stats);
> +	if (!priv->xstats.pcpu_stats)
> +		return -ENOMEM;
>  
>  	stmmac_set_ethtool_ops(ndev);
>  	priv->pause = pause;
> -- 
> 2.43.0
> 


From quic_taozha at quicinc.com  Sat Feb  3 21:30:32 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:32 +0800
Subject: [PATCH v7 01/10] coresight-tpdm: Optimize the store function of tpdm simple dataset
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1707024641-22460-2-git-send-email-quic_taozha@quicinc.com>

Replace spin lock/unlock to avoid forgetting to unlock when the
function exits. And refine methods for handling various conditions.

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpdm.c | 39 ++++++++++----------
 1 file changed, 19 insertions(+), 20 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index bd13a548375c..0427c0fc0bf3 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -77,51 +77,50 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
 					 size_t size)
 {
 	unsigned long val;
-	ssize_t ret = size;
+	ssize_t ret = -EINVAL;
 
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct tpdm_dataset_attribute *tpdm_attr =
 		container_of(attr, struct tpdm_dataset_attribute, attr);
 
 	if (kstrtoul(buf, 0, &val))
-		return -EINVAL;
+		return ret;
 
-	spin_lock(&drvdata->spinlock);
+	guard(spinlock)(&drvdata->spinlock);
 	switch (tpdm_attr->mem) {
 	case DSB_TRIG_PATT:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_TRIG_PATT_MASK:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_PATT:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->patt_val[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_PATT_MASK:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->patt_mask[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_MSR:
-		if (tpdm_attr->idx < drvdata->dsb_msr_num)
+		if (tpdm_attr->idx < drvdata->dsb_msr_num) {
 			drvdata->dsb->msr[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	default:
-		ret = -EINVAL;
+		break;
 	}
-	spin_unlock(&drvdata->spinlock);
 
 	return ret;
 }
-- 
2.17.1



From quic_taozha at quicinc.com  Sat Feb  3 21:30:31 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:31 +0800
Subject: [PATCH v7 00/10] Add support to configure TPDM CMB subunit
Message-ID: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>

Introduction of TPDM CMB(Continuous Multi Bit) subunit
CMB subunit is responsible for creating a dataset element, and is also
optionally responsible for packing it to fit multiple elements on a
single ATB transfer if possible in the configuration. The TPDM Core
Datapath requests timestamps be stored by the TPDA and then delivering
ATB sized data (depending on ATB width and element size, this could
be smaller or larger than a dataset element) to the ATB Mast FSM.
The CMB makes trace elements in two modes. In ?continuous? mode, every
valid data cycle creates an element. In ?trace on change? mode, when
valid data changes on the bus, a trace element is created. In
continuous mode, all cycles where this condition is true create trace
elements. In trace on change mode, a data element is only when the
previously sampled input is different from the current sampled input.

The CMB subunit must be configured prior to enablement. This series
adds support for TPDM to configure the configure CMB subunit.

Once this series patches are applied properly, the new tpdm nodes for
should be observed at the tpdm path /sys/bus/coresight/devices/tpdm*
which supports CMB subunit.
e.g.
root at qemuarm64:/sys/devices/platform/soc at 0/684c000.tpdm/tpdm0# ls -l
-rw-r--r--    1 root     root          4096 Jan  1 00:00 cmb_mode
drwxr-xr-x    2 root     root             0 Jan  1 00:00 cmb_msr
drwxr-xr-x    2 root     root             0 Jan  1 00:00 cmb_patt
drwxr-xr-x    2 root     root             0 Jan  1 00:00 cmb_trig_patt
-rw-r--r--    1 root     root          4096 Jan  1 00:00 cmb_trig_ts
-rw-r--r--    1 root     root          4096 Jan  1 00:00 cmb_ts_all
drwxr-xr-x    2 root     root             0 Jan  1 00:00 connections
drwxr-xr-x    2 root     root             0 Jan  1 00:00 dsb_edge
drwxr-xr-x    2 root     root             0 Jan  1 00:00 dsb_msr
drwxr-xr-x    2 root     root             0 Jan  1 00:00 dsb_patt
drwxr-xr-x    2 root     root             0 Jan  1 00:00 dsb_trig_patt
-rw-r--r--    1 root     root          4096 Jan  1 00:00 enable_source
--w-------    1 root     root          4096 Jan  1 00:00 integration_test
drwxr-xr-x    2 root     root             0 Ja?  1 00:00 power
--w-------    1 root     root          4096 Jan  1 00:00 reset_dataset
lrwxrwxrwx    1 root     root             0 Apr  5  2021 subsystem -> ../../../../../bus/coresight
-rw-r--r--    1 root     root          4096 Apr  5  2021 uevent
-r--r--r--    1 root     root          4096 Jan  1 00:00 waiting_for_supplier

We can use the commands are similar to the below to configure the
TPDMs which support CMB subunit. Enable coresight sink first.
echo 1 > /sys/bus/coresight/devices/tmc_etf0/enable_sink
echo 1 > /sys/bus/coresight/devices/tpdm0/reset_dataset
echo 1 > /sys/bus/coresight/devices/tpdm0/cmb_mode
echo 1 > /sys/bus/coresight/devices/tpdm0/cmb_patt/enable_ts
echo 0xFFFFFFFF > /sys/bus/coresight/devices/tpdm0/cmb_patt/tpmr0
echo 0 > /sys/bus/coresight/devices/tpdm0/cmb_trig_ts
echo 0xFFFFFFFF > /sys/bus/coresight/devices/tpdm0/cmb_trig_patt/xpr1
echo 1 > /sys/bus/coresight/devices/tpdm0/enable_source

codelinaro link:
https://git.codelinaro.org/clo/linux-kernel/coresight/-/commits/tpdm-cmb-v7

Changes in V7:
1. Rename "tpdm_clear_element_size" to "tpda_clear_element_size" in
the patch#5.
-- Suzuki K Poulose
2. Remove the stale comments in "tpda_enable_port".
-- Suzuki K Poulose

Changes in V6:
1. Clear all the relevant fields before setting them in the function
"tpda_set_element_size". In patch#5.
-- Suzuki K Poulose

2. Leave a space after/before '/*' & '*/'. In patch#7 #8.
-- Suzuki K Poulose

Changes in V5:
1. Return directly to refine the process of "tpdm_enable_dsb" and
"tpdm_disable_dsb" if the TPDM does not support DSB dataset.
-- Suzuki K Poulose
2. Change the new property name from "qcom,cmb-element-size" to
"qcom,cmb-element-bits". And update the property name to the new
tpdm example which supports the CMB dataset.
-- Krzysztof
3. Drop unnecessary () around the drvdata member access in patch#5.
-- Suzuki K Poulose
4. Replace the error code "-EEXIST" with the port number in detecting
multiple TPDMs on one input port. In patch#5.
-- Suzuki K Poulose
5. Due to the modification of the new property name, the searched
property name was changed from "qcom,cmb-element-size" to
"qcom,cmb-element-bits". In patch#5.
6. Replace the judgement "tpdm_has_cmb_dataset(drvdata)" with
"drvdata->cmb" in the function "tpdm_reset_datasets". In patch#6.
-- Suzuki K Poulose
7. Drop unnecessary () around kstrtoul() in the function
"cmb_mode_store". In patch#6.
-- Suzuki K Poulose
8. Update the date and the kernel version in the Document.
-- Suzuki K Poulose
9. Initialize the return value to "-EINVAL" and remove the unnecessary
code in the function "enable_ts_show". In patch#8.
-- Suzuki K Poulose
10. Replace spin lock/unlock with guard(spinlock). In patch#8.
-- Suzuki K Poulose
11. Drop _rw from the macro "tpdm_patt_enable_ts_rw". In patch#8.
-- Suzuki K Poulose

Changes in V4:
1. Replace spin lock/unlock to avoid forgetting to unlock when the
function exits.
-- Suzuki K Poulose
2. Move the helper "tpdm_has_dsb_dataset" to the header file.
-- Suzuki K Poulose
3. Fix the incorrect property of the sample in the documents.
-- James Clark
4. Clear the dsb/cmb element size directly in the clear helper.
-- Suzuki K Poulose
5. Correct the comment of "tpdm_read_element_size".
-- Suzuki K Poulose
6. Call the helper "tpdm_has_dsb/cmb_dataset" in TPDA driver to
check what dataset the TPDM supports.
-- Suzuki K Poulose
7. Refine the dsb/cmb dataset support check in enable/disable functions.
-- Suzuki K Poulose
8. Get rid of redundant code in function "set_cmb_tier".
-- Suzuki K Poulose
9. Since one SysFs file should follow "one value", use "dev_ext_attribute"
to instead of the previous "enable_ts" Sysfs file approach.
-- Suzuki K Poulose
10. Change the kernel version to 6.9 for the MSR related SysFs file.
-- James Clark
11. Refine the function "tpdm_simple_dataset_store".
-- Suzuki K Poulose

Changes in V3:
1. Add 8-bit support to the description in the TPDM devicetree document.
-- Rob Herring
2. Change how the result is produced in "tpdm_read_element_size".
-- James Clark
3. Calling "tpdm_clear_element_size" at the beginning of
"tpda_enable_port".
-- James Clark
4. Use "dsb_esize" and "cmb_esize" to determine whether multiple TPDMs
are detected on a TPDA input port in "tpda_get_element_size".
-- James Clark
5. Modify the judgment logic in "tpda_enable_port".
-- James Clark
6. Add more description of "cmb_mode" to TPDM SysFS document.
-- James Clark

Changes in V2:
1. Optimizate and modify this patch series based on the patch series
"Add support to configure TPDM CMB subunit".
2. Modify the functions that read the element size of DSB/CMB in TPDA driver.

Tao Zhang (10):
  coresight-tpdm: Optimize the store function of tpdm simple dataset
  coresight-tpdm: Optimize the useage of tpdm_has_dsb_dataset
  dt-bindings: arm: qcom,coresight-tpdm: Add support for CMB element
    size
  coresight-tpdm: Add CMB dataset support
  coresight-tpda: Add support to configure CMB element
  coresight-tpdm: Add support to configure CMB
  coresight-tpdm: Add pattern registers support for CMB
  coresight-tpdm: Add timestamp control register support for the CMB
  dt-bindings: arm: qcom,coresight-tpdm: Add support for TPDM CMB MSR
    register
  coresight-tpdm: Add msr register support for CMB

 .../testing/sysfs-bus-coresight-devices-tpdm  |  87 ++++
 .../bindings/arm/qcom,coresight-tpdm.yaml     |  35 ++
 drivers/hwtracing/coresight/coresight-tpda.c  | 130 ++---
 drivers/hwtracing/coresight/coresight-tpda.h  |   6 +
 drivers/hwtracing/coresight/coresight-tpdm.c  | 455 ++++++++++++++++--
 drivers/hwtracing/coresight/coresight-tpdm.h  | 113 +++++
 6 files changed, 729 insertions(+), 97 deletions(-)

-- 
2.17.1



From quic_taozha at quicinc.com  Sat Feb  3 21:30:33 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:33 +0800
Subject: [PATCH v7 02/10] coresight-tpdm: Optimize the useage of tpdm_has_dsb_dataset
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1707024641-22460-3-git-send-email-quic_taozha@quicinc.com>

Since the function tpdm_has_dsb_dataset will be called by TPDA
driver in subsequent patches, it is moved to the header file.
And move this judgement form the function __tpdm_{enable/disable}
to the beginning of the function tpdm_{enable/disable}_dsb.

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpdm.c | 30 +++++++++-----------
 drivers/hwtracing/coresight/coresight-tpdm.h |  4 +++
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 0427c0fc0bf3..4b1296d11360 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -125,11 +125,6 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
 	return ret;
 }
 
-static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
-{
-	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
-}
-
 static umode_t tpdm_dsb_is_visible(struct kobject *kobj,
 				   struct attribute *attr, int n)
 {
@@ -232,25 +227,27 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
 {
 	u32 val, i;
 
+	if (!tpdm_has_dsb_dataset(drvdata))
+		return;
+
 	for (i = 0; i < TPDM_DSB_MAX_EDCR; i++)
 		writel_relaxed(drvdata->dsb->edge_ctrl[i],
-			   drvdata->base + TPDM_DSB_EDCR(i));
+			       drvdata->base + TPDM_DSB_EDCR(i));
 	for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++)
 		writel_relaxed(drvdata->dsb->edge_ctrl_mask[i],
-			   drvdata->base + TPDM_DSB_EDCMR(i));
+			       drvdata->base + TPDM_DSB_EDCMR(i));
 	for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
 		writel_relaxed(drvdata->dsb->patt_val[i],
-			   drvdata->base + TPDM_DSB_TPR(i));
+			       drvdata->base + TPDM_DSB_TPR(i));
 		writel_relaxed(drvdata->dsb->patt_mask[i],
-			   drvdata->base + TPDM_DSB_TPMR(i));
+			       drvdata->base + TPDM_DSB_TPMR(i));
 		writel_relaxed(drvdata->dsb->trig_patt[i],
-			   drvdata->base + TPDM_DSB_XPR(i));
+			       drvdata->base + TPDM_DSB_XPR(i));
 		writel_relaxed(drvdata->dsb->trig_patt_mask[i],
-			   drvdata->base + TPDM_DSB_XPMR(i));
+			       drvdata->base + TPDM_DSB_XPMR(i));
 	}
 
 	set_dsb_tier(drvdata);
-
 	set_dsb_msr(drvdata);
 
 	val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
@@ -278,8 +275,7 @@ static void __tpdm_enable(struct tpdm_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
-	if (tpdm_has_dsb_dataset(drvdata))
-		tpdm_enable_dsb(drvdata);
+	tpdm_enable_dsb(drvdata);
 
 	CS_LOCK(drvdata->base);
 }
@@ -307,6 +303,9 @@ static void tpdm_disable_dsb(struct tpdm_drvdata *drvdata)
 {
 	u32 val;
 
+	if (!tpdm_has_dsb_dataset(drvdata))
+		return;
+
 	/* Set the enable bit of DSB control register to 0 */
 	val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
 	val &= ~TPDM_DSB_CR_ENA;
@@ -318,8 +317,7 @@ static void __tpdm_disable(struct tpdm_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
-	if (tpdm_has_dsb_dataset(drvdata))
-		tpdm_disable_dsb(drvdata);
+	tpdm_disable_dsb(drvdata);
 
 	CS_LOCK(drvdata->base);
 }
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index 4115b2a17b8d..ddaf333fa1c2 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -220,4 +220,8 @@ struct tpdm_dataset_attribute {
 	u32 idx;
 };
 
+static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
+{
+	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
+}
 #endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
-- 
2.17.1



From quic_taozha at quicinc.com  Sat Feb  3 21:30:34 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:34 +0800
Subject: [PATCH v7 03/10] dt-bindings: arm: qcom,coresight-tpdm: Add support for CMB element size
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1707024641-22460-4-git-send-email-quic_taozha@quicinc.com>

Add property "qcom,cmb-elem-bits" to support CMB(Continuous
Multi-Bit) element for TPDM. The associated aggregator will read
this size before it is enabled. CMB element size currently only
supports 8-bit, 32-bit and 64-bit. Because the existing example
tpdm "tpdm at 684c000" which only supports dsb sub-unit, I introduce
a new example "tpdm at 6c29000" to describe the usage of this new
property.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../bindings/arm/qcom,coresight-tpdm.yaml     | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
index 61ddc3b5b247..2320b5445900 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
@@ -52,6 +52,14 @@ properties:
     $ref: /schemas/types.yaml#/definitions/uint8
     enum: [32, 64]
 
+  qcom,cmb-element-bits:
+    description:
+      Specifies the CMB(Continuous Multi-Bit) element size supported by
+      the monitor. The associated aggregator will read this size before it
+      is enabled. CMB element size currently only supports 8-bit, 32-bit
+      and 64-bit.
+    enum: [8, 32, 64]
+
   qcom,dsb-msrs-num:
     description:
       Specifies the number of DSB(Discrete Single Bit) MSR(mux select register)
@@ -110,4 +118,21 @@ examples:
       };
     };
 
+    tpdm at 6c29000 {
+      compatible = "qcom,coresight-tpdm", "arm,primecell";
+      reg = <0x06c29000 0x1000>;
+
+      qcom,cmb-element-bits = <64>;
+
+      clocks = <&aoss_qmp>;
+      clock-names = "apb_pclk";
+
+      out-ports {
+        port {
+          tpdm_ipcc_out_funnel_center: endpoint {
+            remote-endpoint = <&funnel_center_in_tpdm_ipcc>;
+          };
+        };
+      };
+    };
 ...
-- 
2.17.1



From quic_taozha at quicinc.com  Sat Feb  3 21:30:35 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:35 +0800
Subject: [PATCH v7 04/10] coresight-tpdm: Add CMB dataset support
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1707024641-22460-5-git-send-email-quic_taozha@quicinc.com>

CMB (continuous multi-bit) is one of TPDM's dataset type. CMB subunit
can be enabled for data collection by writing 1 to the first bit of
CMB_CR register. This change is to add enable/disable function for
CMB dataset by writing CMB_CR register.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Jinlong Mao <quic_jinlmao at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpdm.c | 28 ++++++++++++++++++++
 drivers/hwtracing/coresight/coresight-tpdm.h | 13 +++++++++
 2 files changed, 41 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 4b1296d11360..1bb1d8e83501 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -263,6 +263,19 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
 	writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
 }
 
+static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
+{
+	u32 val;
+
+	if (!tpdm_has_cmb_dataset(drvdata))
+		return;
+
+	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
+	/* Set the enable bit of CMB control register to 1 */
+	val |= TPDM_CMB_CR_ENA;
+	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
+}
+
 /*
  * TPDM enable operations
  * The TPDM or Monitor serves as data collection component for various
@@ -276,6 +289,7 @@ static void __tpdm_enable(struct tpdm_drvdata *drvdata)
 	CS_UNLOCK(drvdata->base);
 
 	tpdm_enable_dsb(drvdata);
+	tpdm_enable_cmb(drvdata);
 
 	CS_LOCK(drvdata->base);
 }
@@ -312,12 +326,26 @@ static void tpdm_disable_dsb(struct tpdm_drvdata *drvdata)
 	writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
 }
 
+static void tpdm_disable_cmb(struct tpdm_drvdata *drvdata)
+{
+	u32 val;
+
+	if (!tpdm_has_cmb_dataset(drvdata))
+		return;
+
+	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
+	/* Set the enable bit of CMB control register to 0 */
+	val &= ~TPDM_CMB_CR_ENA;
+	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
+}
+
 /* TPDM disable operations */
 static void __tpdm_disable(struct tpdm_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
 	tpdm_disable_dsb(drvdata);
+	tpdm_disable_cmb(drvdata);
 
 	CS_LOCK(drvdata->base);
 }
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index ddaf333fa1c2..a442d9c6e4ac 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -9,6 +9,12 @@
 /* The max number of the datasets that TPDM supports */
 #define TPDM_DATASETS       7
 
+/* CMB Subunit Registers */
+#define TPDM_CMB_CR		(0xA00)
+
+/* Enable bit for CMB subunit */
+#define TPDM_CMB_CR_ENA		BIT(0)
+
 /* DSB Subunit Registers */
 #define TPDM_DSB_CR		(0x780)
 #define TPDM_DSB_TIER		(0x784)
@@ -79,10 +85,12 @@
  *
  * PERIPHIDR0[0] : Fix to 1 if ImplDef subunit present, else 0
  * PERIPHIDR0[1] : Fix to 1 if DSB subunit present, else 0
+ * PERIPHIDR0[2] : Fix to 1 if CMB subunit present, else 0
  */
 
 #define TPDM_PIDR0_DS_IMPDEF	BIT(0)
 #define TPDM_PIDR0_DS_DSB	BIT(1)
+#define TPDM_PIDR0_DS_CMB	BIT(2)
 
 #define TPDM_DSB_MAX_LINES	256
 /* MAX number of EDCR registers */
@@ -224,4 +232,9 @@ static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
 {
 	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
 }
+
+static bool tpdm_has_cmb_dataset(struct tpdm_drvdata *drvdata)
+{
+	return (drvdata->datasets & TPDM_PIDR0_DS_CMB);
+}
 #endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
-- 
2.17.1



From quic_taozha at quicinc.com  Sat Feb  3 21:30:36 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:36 +0800
Subject: [PATCH v7 05/10] coresight-tpda: Add support to configure CMB element
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1707024641-22460-6-git-send-email-quic_taozha@quicinc.com>

Read the CMB element size from the device tree. Set the register
bit that controls the CMB element size of the corresponding port.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpda.c | 130 +++++++++++--------
 drivers/hwtracing/coresight/coresight-tpda.h |   6 +
 2 files changed, 81 insertions(+), 55 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 4ac954f4bc13..2d35059ec697 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -18,6 +18,7 @@
 #include "coresight-priv.h"
 #include "coresight-tpda.h"
 #include "coresight-trace-id.h"
+#include "coresight-tpdm.h"
 
 DEFINE_CORESIGHT_DEVLIST(tpda_devs, "tpda");
 
@@ -28,24 +29,59 @@ static bool coresight_device_is_tpdm(struct coresight_device *csdev)
 			CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
 }
 
+static void tpda_clear_element_size(struct coresight_device *csdev)
+{
+	struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	drvdata->dsb_esize = 0;
+	drvdata->cmb_esize = 0;
+}
+
+static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 *val)
+{
+	/* Clear all relevant fields */
+	*val &= ~(TPDA_Pn_CR_DSBSIZE | TPDA_Pn_CR_CMBSIZE);
+
+	if (drvdata->dsb_esize == 64)
+		*val |= TPDA_Pn_CR_DSBSIZE;
+	else if (drvdata->dsb_esize == 32)
+		*val &= ~TPDA_Pn_CR_DSBSIZE;
+
+	if (drvdata->cmb_esize == 64)
+		*val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
+	else if (drvdata->cmb_esize == 32)
+		*val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
+	else if (drvdata->cmb_esize == 8)
+		*val &= ~TPDA_Pn_CR_CMBSIZE;
+}
+
 /*
- * Read the DSB element size from the TPDM device
+ * Read the element size from the TPDM device. One TPDM must have at least one of the
+ * element size property.
  * Returns
- *    The dsb element size read from the devicetree if available.
- *    0 - Otherwise, with a warning once.
+ *    0 - The element size property is read
+ *    Others - Cannot read the property of the element size
  */
-static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
+static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
+				  struct coresight_device *csdev)
 {
-	int rc = 0;
-	u8 size = 0;
+	int rc = -EINVAL;
+	struct tpdm_drvdata *tpdm_data = dev_get_drvdata(csdev->dev.parent);
+
+	if (tpdm_has_dsb_dataset(tpdm_data)) {
+		rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
+				"qcom,dsb-element-size", &drvdata->dsb_esize);
+	}
+	if (tpdm_has_cmb_dataset(tpdm_data)) {
+		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
+				"qcom,cmb-element-bits", &drvdata->cmb_esize);
+	}
 
-	rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
-			"qcom,dsb-element-size", &size);
 	if (rc)
 		dev_warn_once(&csdev->dev,
-			"Failed to read TPDM DSB Element size: %d\n", rc);
+			"Failed to read TPDM Element size: %d\n", rc);
 
-	return size;
+	return rc;
 }
 
 /*
@@ -56,11 +92,12 @@ static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
  * Parameter "inport" is used to pass in the input port number
  * of TPDA, and it is set to -1 in the recursize call.
  */
-static int tpda_get_element_size(struct coresight_device *csdev,
+static int tpda_get_element_size(struct tpda_drvdata *drvdata,
+				 struct coresight_device *csdev,
 				 int inport)
 {
-	int dsb_size = -ENOENT;
-	int i, size;
+	int rc = 0;
+	int i;
 	struct coresight_device *in;
 
 	for (i = 0; i < csdev->pdata->nr_inconns; i++) {
@@ -69,30 +106,26 @@ static int tpda_get_element_size(struct coresight_device *csdev,
 			continue;
 
 		/* Ignore the paths that do not match port */
-		if (inport > 0 &&
+		if (inport >= 0 &&
 		    csdev->pdata->in_conns[i]->dest_port != inport)
 			continue;
 
 		if (coresight_device_is_tpdm(in)) {
-			size = tpdm_read_dsb_element_size(in);
+			if (drvdata->dsb_esize || drvdata->cmb_esize)
+				return -EEXIST;
+			rc = tpdm_read_element_size(drvdata, in);
+			if (rc)
+				return rc;
 		} else {
 			/* Recurse down the path */
-			size = tpda_get_element_size(in, -1);
-		}
-
-		if (size < 0)
-			return size;
-
-		if (dsb_size < 0) {
-			/* Found a size, save it. */
-			dsb_size = size;
-		} else {
-			/* Found duplicate TPDMs */
-			return -EEXIST;
+			rc = tpda_get_element_size(drvdata, in, -1);
+			if (rc)
+				return rc;
 		}
 	}
 
-	return dsb_size;
+
+	return rc;
 }
 
 /* Settings pre enabling port control register */
@@ -109,37 +142,24 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
 static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
 {
 	u32 val;
-	int size;
+	int rc;
 
 	val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
-	/*
-	 * Configure aggregator port n DSB data set element size
-	 * Set the bit to 0 if the size is 32
-	 * Set the bit to 1 if the size is 64
-	 */
-	size = tpda_get_element_size(drvdata->csdev, port);
-	switch (size) {
-	case 32:
-		val &= ~TPDA_Pn_CR_DSBSIZE;
-		break;
-	case 64:
-		val |= TPDA_Pn_CR_DSBSIZE;
-		break;
-	case 0:
-		return -EEXIST;
-	case -EEXIST:
+	tpda_clear_element_size(drvdata->csdev);
+	rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
+	if (!rc && (drvdata->dsb_esize || drvdata->cmb_esize)) {
+		tpda_set_element_size(drvdata, &val);
+		/* Enable the port */
+		val |= TPDA_Pn_CR_ENA;
+		writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
+	} else if (rc == -EEXIST)
 		dev_warn_once(&drvdata->csdev->dev,
-			"Detected multiple TPDMs on port %d", -EEXIST);
-		return -EEXIST;
-	default:
-		return -EINVAL;
-	}
-
-	/* Enable the port */
-	val |= TPDA_Pn_CR_ENA;
-	writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
+			      "Detected multiple TPDMs on port %d", port);
+	else
+		dev_warn_once(&drvdata->csdev->dev,
+			      "Didn't find TPDM element size");
 
-	return 0;
+	return rc;
 }
 
 static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
index b3b38fd41b64..19af64120fcf 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.h
+++ b/drivers/hwtracing/coresight/coresight-tpda.h
@@ -10,6 +10,8 @@
 #define TPDA_Pn_CR(n)		(0x004 + (n * 4))
 /* Aggregator port enable bit */
 #define TPDA_Pn_CR_ENA		BIT(0)
+/* Aggregator port CMB data set element size bit */
+#define TPDA_Pn_CR_CMBSIZE		GENMASK(7, 6)
 /* Aggregator port DSB data set element size bit */
 #define TPDA_Pn_CR_DSBSIZE		BIT(8)
 
@@ -25,6 +27,8 @@
  * @csdev:      component vitals needed by the framework.
  * @spinlock:   lock for the drvdata value.
  * @enable:     enable status of the component.
+ * @dsb_esize   Record the DSB element size.
+ * @cmb_esize   Record the CMB element size.
  */
 struct tpda_drvdata {
 	void __iomem		*base;
@@ -32,6 +36,8 @@ struct tpda_drvdata {
 	struct coresight_device	*csdev;
 	spinlock_t		spinlock;
 	u8			atid;
+	u8			dsb_esize;
+	u32			cmb_esize;
 };
 
 #endif  /* _CORESIGHT_CORESIGHT_TPDA_H */
-- 
2.17.1



From quic_taozha at quicinc.com  Sat Feb  3 21:30:37 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:37 +0800
Subject: [PATCH v7 06/10] coresight-tpdm: Add support to configure CMB
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1707024641-22460-7-git-send-email-quic_taozha@quicinc.com>

TPDM CMB subunits support two forms of CMB data set element creation:
continuous and trace-on-change collection mode. Continuous change
creates CMB data set elements on every CMBCLK edge. Trace-on-change
creates CMB data set elements only when a new data set element differs
in value from the previous element in a CMB data set. Set CMB_CR.MODE
to 0 for continuous CMB collection mode. Set CMB_CR.MODE to 1 for
trace-on-change CMB collection mode.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Jinlong Mao <quic_jinlmao at quicinc.com>
---
 .../testing/sysfs-bus-coresight-devices-tpdm  | 14 +++++
 drivers/hwtracing/coresight/coresight-tpdm.c  | 60 +++++++++++++++++++
 drivers/hwtracing/coresight/coresight-tpdm.h  | 12 ++++
 3 files changed, 86 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index 4dd49b159543..6dfb18d6d64a 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -170,3 +170,17 @@ Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_t
 Description:
 		(RW) Set/Get the MSR(mux select register) for the DSB subunit
 		TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_mode
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:	(Write) Set the data collection mode of CMB tpdm. Continuous
+		change creates CMB data set elements on every CMBCLK edge.
+		Trace-on-change creates CMB data set elements only when a new
+		data set element differs in value from the previous element
+		in a CMB data set.
+
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Continuous CMB collection mode.
+		1 : Trace-on-change CMB collection mode.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 1bb1d8e83501..b20071460375 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -137,6 +137,18 @@ static umode_t tpdm_dsb_is_visible(struct kobject *kobj,
 	return 0;
 }
 
+static umode_t tpdm_cmb_is_visible(struct kobject *kobj,
+				   struct attribute *attr, int n)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (drvdata && tpdm_has_cmb_dataset(drvdata))
+		return attr->mode;
+
+	return 0;
+}
+
 static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj,
 				       struct attribute *attr, int n)
 {
@@ -161,6 +173,9 @@ static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
 		drvdata->dsb->trig_ts = true;
 		drvdata->dsb->trig_type = false;
 	}
+
+	if (drvdata->cmb)
+		memset(drvdata->cmb, 0, sizeof(struct cmb_dataset));
 }
 
 static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val)
@@ -391,6 +406,12 @@ static int tpdm_datasets_setup(struct tpdm_drvdata *drvdata)
 		if (!drvdata->dsb)
 			return -ENOMEM;
 	}
+	if (tpdm_has_cmb_dataset(drvdata) && (!drvdata->cmb)) {
+		drvdata->cmb = devm_kzalloc(drvdata->dev,
+						sizeof(*drvdata->cmb), GFP_KERNEL);
+		if (!drvdata->cmb)
+			return -ENOMEM;
+	}
 	tpdm_reset_datasets(drvdata);
 
 	return 0;
@@ -729,6 +750,34 @@ static ssize_t dsb_trig_ts_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(dsb_trig_ts);
 
+static ssize_t cmb_mode_show(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return sysfs_emit(buf, "%x\n", drvdata->cmb->trace_mode);
+
+}
+
+static ssize_t cmb_mode_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf,
+			      size_t size)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long trace_mode;
+
+	if (kstrtoul(buf, 0, &trace_mode) || (trace_mode & ~1UL))
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	drvdata->cmb->trace_mode = trace_mode;
+	spin_unlock(&drvdata->spinlock);
+	return size;
+}
+static DEVICE_ATTR_RW(cmb_mode);
+
 static struct attribute *tpdm_dsb_edge_attrs[] = {
 	&dev_attr_ctrl_idx.attr,
 	&dev_attr_ctrl_val.attr,
@@ -845,6 +894,11 @@ static struct attribute *tpdm_dsb_attrs[] = {
 	NULL,
 };
 
+static struct attribute *tpdm_cmb_attrs[] = {
+	&dev_attr_cmb_mode.attr,
+	NULL,
+};
+
 static struct attribute_group tpdm_dsb_attr_grp = {
 	.attrs = tpdm_dsb_attrs,
 	.is_visible = tpdm_dsb_is_visible,
@@ -874,6 +928,11 @@ static struct attribute_group tpdm_dsb_msr_grp = {
 	.name = "dsb_msr",
 };
 
+static struct attribute_group tpdm_cmb_attr_grp = {
+	.attrs = tpdm_cmb_attrs,
+	.is_visible = tpdm_cmb_is_visible,
+};
+
 static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_attr_grp,
 	&tpdm_dsb_attr_grp,
@@ -881,6 +940,7 @@ static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_dsb_trig_patt_grp,
 	&tpdm_dsb_patt_grp,
 	&tpdm_dsb_msr_grp,
+	&tpdm_cmb_attr_grp,
 	NULL,
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index a442d9c6e4ac..2af92c270ed1 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -14,6 +14,8 @@
 
 /* Enable bit for CMB subunit */
 #define TPDM_CMB_CR_ENA		BIT(0)
+/* Trace collection mode for CMB subunit */
+#define TPDM_CMB_CR_MODE	BIT(1)
 
 /* DSB Subunit Registers */
 #define TPDM_DSB_CR		(0x780)
@@ -181,6 +183,14 @@ struct dsb_dataset {
 	bool			trig_type;
 };
 
+/**
+ * struct cmb_dataset
+ * @trace_mode:       Dataset collection mode
+ */
+struct cmb_dataset {
+	u32			trace_mode;
+};
+
 /**
  * struct tpdm_drvdata - specifics associated to an TPDM component
  * @base:       memory mapped base address for this component.
@@ -190,6 +200,7 @@ struct dsb_dataset {
  * @enable:     enable status of the component.
  * @datasets:   The datasets types present of the TPDM.
  * @dsb         Specifics associated to TPDM DSB.
+ * @cmb         Specifics associated to TPDM CMB.
  * @dsb_msr_num Number of MSR supported by DSB TPDM
  */
 
@@ -201,6 +212,7 @@ struct tpdm_drvdata {
 	bool			enable;
 	unsigned long		datasets;
 	struct dsb_dataset	*dsb;
+	struct cmb_dataset	*cmb;
 	u32			dsb_msr_num;
 };
 
-- 
2.17.1



From quic_taozha at quicinc.com  Sat Feb  3 21:30:38 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:38 +0800
Subject: [PATCH v7 07/10] coresight-tpdm: Add pattern registers support for CMB
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1707024641-22460-8-git-send-email-quic_taozha@quicinc.com>

Timestamps are requested if the monitor?s CMB data set unit input
data matches the value in the Monitor CMB timestamp pattern and mask
registers (M_CMB_TPR and M_CMB_TPMR) when CMB timestamp enabled
via the timestamp insertion enable register bit(CMB_TIER.PATT_TSENAB).
The pattern match trigger output is achieved via setting values into
the CMB trigger pattern and mask registers (CMB_XPR and CMB_XPMR).
After configuring a pattern through these registers, the TPDM subunit
will assert an output trigger every time it receives new input data
that matches the configured pattern value. Values in a given bit
number of the mask register correspond to the same bit number in
the corresponding pattern register.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Jinlong Mao <quic_jinlmao at quicinc.com>
---
 .../testing/sysfs-bus-coresight-devices-tpdm  | 30 ++++++
 drivers/hwtracing/coresight/coresight-tpdm.c  | 96 ++++++++++++++++++-
 drivers/hwtracing/coresight/coresight-tpdm.h  | 39 ++++++++
 3 files changed, 164 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index 6dfb18d6d64a..b6cf050861ed 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -184,3 +184,33 @@ Description:	(Write) Set the data collection mode of CMB tpdm. Continuous
 		Accepts only one of the 2 values -  0 or 1.
 		0 : Continuous CMB collection mode.
 		1 : Trace-on-change CMB collection mode.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the value of the trigger pattern for the CMB
+		subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpmr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the mask of the trigger pattern for the CMB
+		subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the value of the pattern for the CMB subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpmr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index b20071460375..07587287d9fa 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -66,6 +66,26 @@ static ssize_t tpdm_simple_dataset_show(struct device *dev,
 			return -EINVAL;
 		return sysfs_emit(buf, "0x%x\n",
 				drvdata->dsb->msr[tpdm_attr->idx]);
+	case CMB_TRIG_PATT:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->trig_patt[tpdm_attr->idx]);
+	case CMB_TRIG_PATT_MASK:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->trig_patt_mask[tpdm_attr->idx]);
+	case CMB_PATT:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->patt_val[tpdm_attr->idx]);
+	case CMB_PATT_MASK:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->patt_mask[tpdm_attr->idx]);
 	}
 	return -EINVAL;
 }
@@ -118,6 +138,30 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
 			ret = size;
 		}
 		break;
+	case CMB_TRIG_PATT:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->trig_patt[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
+	case CMB_TRIG_PATT_MASK:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->trig_patt_mask[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
+	case CMB_PATT:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->patt_val[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
+	case CMB_PATT_MASK:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->patt_mask[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
 	default:
 		break;
 	}
@@ -280,12 +324,32 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
 
 static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 {
-	u32 val;
+	u32 val, i;
 
 	if (!tpdm_has_cmb_dataset(drvdata))
 		return;
 
+	/* Configure pattern registers */
+	for (i = 0; i < TPDM_CMB_MAX_PATT; i++) {
+		writel_relaxed(drvdata->cmb->patt_val[i],
+			drvdata->base + TPDM_CMB_TPR(i));
+		writel_relaxed(drvdata->cmb->patt_mask[i],
+			drvdata->base + TPDM_CMB_TPMR(i));
+		writel_relaxed(drvdata->cmb->trig_patt[i],
+			drvdata->base + TPDM_CMB_XPR(i));
+		writel_relaxed(drvdata->cmb->trig_patt_mask[i],
+			drvdata->base + TPDM_CMB_XPMR(i));
+	}
+
 	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
+	/*
+	 * Set to 0 for continuous CMB collection mode,
+	 * 1 for trace-on-change CMB collection mode.
+	 */
+	if (drvdata->cmb->trace_mode)
+		val |= TPDM_CMB_CR_MODE;
+	else
+		val &= ~TPDM_CMB_CR_MODE;
 	/* Set the enable bit of CMB control register to 1 */
 	val |= TPDM_CMB_CR_ENA;
 	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
@@ -887,6 +951,22 @@ static struct attribute *tpdm_dsb_msr_attrs[] = {
 	NULL,
 };
 
+static struct attribute *tpdm_cmb_trig_patt_attrs[] = {
+	CMB_TRIG_PATT_ATTR(0),
+	CMB_TRIG_PATT_ATTR(1),
+	CMB_TRIG_PATT_MASK_ATTR(0),
+	CMB_TRIG_PATT_MASK_ATTR(1),
+	NULL,
+};
+
+static struct attribute *tpdm_cmb_patt_attrs[] = {
+	CMB_PATT_ATTR(0),
+	CMB_PATT_ATTR(1),
+	CMB_PATT_MASK_ATTR(0),
+	CMB_PATT_MASK_ATTR(1),
+	NULL,
+};
+
 static struct attribute *tpdm_dsb_attrs[] = {
 	&dev_attr_dsb_mode.attr,
 	&dev_attr_dsb_trig_ts.attr,
@@ -933,6 +1013,18 @@ static struct attribute_group tpdm_cmb_attr_grp = {
 	.is_visible = tpdm_cmb_is_visible,
 };
 
+static struct attribute_group tpdm_cmb_trig_patt_grp = {
+	.attrs = tpdm_cmb_trig_patt_attrs,
+	.is_visible = tpdm_cmb_is_visible,
+	.name = "cmb_trig_patt",
+};
+
+static struct attribute_group tpdm_cmb_patt_grp = {
+	.attrs = tpdm_cmb_patt_attrs,
+	.is_visible = tpdm_cmb_is_visible,
+	.name = "cmb_patt",
+};
+
 static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_attr_grp,
 	&tpdm_dsb_attr_grp,
@@ -941,6 +1033,8 @@ static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_dsb_patt_grp,
 	&tpdm_dsb_msr_grp,
 	&tpdm_cmb_attr_grp,
+	&tpdm_cmb_trig_patt_grp,
+	&tpdm_cmb_patt_grp,
 	NULL,
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index 2af92c270ed1..e5d4c22cd38c 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -11,12 +11,23 @@
 
 /* CMB Subunit Registers */
 #define TPDM_CMB_CR		(0xA00)
+/* CMB subunit timestamp pattern registers */
+#define TPDM_CMB_TPR(n)		(0xA08 + (n * 4))
+/* CMB subunit timestamp pattern mask registers */
+#define TPDM_CMB_TPMR(n)	(0xA10 + (n * 4))
+/* CMB subunit trigger pattern registers */
+#define TPDM_CMB_XPR(n)		(0xA18 + (n * 4))
+/* CMB subunit trigger pattern mask registers */
+#define TPDM_CMB_XPMR(n)	(0xA20 + (n * 4))
 
 /* Enable bit for CMB subunit */
 #define TPDM_CMB_CR_ENA		BIT(0)
 /* Trace collection mode for CMB subunit */
 #define TPDM_CMB_CR_MODE	BIT(1)
 
+/* Patten register number */
+#define TPDM_CMB_MAX_PATT		2
+
 /* DSB Subunit Registers */
 #define TPDM_DSB_CR		(0x780)
 #define TPDM_DSB_TIER		(0x784)
@@ -151,6 +162,22 @@
 		tpdm_simple_dataset_rw(msr##nr,			\
 		DSB_MSR, nr)
 
+#define CMB_TRIG_PATT_ATTR(nr)					\
+		tpdm_simple_dataset_rw(xpr##nr,			\
+		CMB_TRIG_PATT, nr)
+
+#define CMB_TRIG_PATT_MASK_ATTR(nr)				\
+		tpdm_simple_dataset_rw(xpmr##nr,		\
+		CMB_TRIG_PATT_MASK, nr)
+
+#define CMB_PATT_ATTR(nr)					\
+		tpdm_simple_dataset_rw(tpr##nr,			\
+		CMB_PATT, nr)
+
+#define CMB_PATT_MASK_ATTR(nr)					\
+		tpdm_simple_dataset_rw(tpmr##nr,		\
+		CMB_PATT_MASK, nr)
+
 /**
  * struct dsb_dataset - specifics associated to dsb dataset
  * @mode:             DSB programming mode
@@ -186,9 +213,17 @@ struct dsb_dataset {
 /**
  * struct cmb_dataset
  * @trace_mode:       Dataset collection mode
+ * @patt_val:         Save value for pattern
+ * @patt_mask:        Save value for pattern mask
+ * @trig_patt:        Save value for trigger pattern
+ * @trig_patt_mask:   Save value for trigger pattern mask
  */
 struct cmb_dataset {
 	u32			trace_mode;
+	u32			patt_val[TPDM_CMB_MAX_PATT];
+	u32			patt_mask[TPDM_CMB_MAX_PATT];
+	u32			trig_patt[TPDM_CMB_MAX_PATT];
+	u32			trig_patt_mask[TPDM_CMB_MAX_PATT];
 };
 
 /**
@@ -225,6 +260,10 @@ enum dataset_mem {
 	DSB_PATT,
 	DSB_PATT_MASK,
 	DSB_MSR,
+	CMB_TRIG_PATT,
+	CMB_TRIG_PATT_MASK,
+	CMB_PATT,
+	CMB_PATT_MASK
 };
 
 /**
-- 
2.17.1



From quic_taozha at quicinc.com  Sat Feb  3 21:30:39 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:39 +0800
Subject: [PATCH v7 08/10] coresight-tpdm: Add timestamp control register support for the CMB
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1707024641-22460-9-git-send-email-quic_taozha@quicinc.com>

CMB_TIER register is CMB subunit timestamp insertion enable register.
Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
Set this bit to 1 to request a timestamp following a CMB CTI timestamp
request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
for all packets.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Jinlong Mao <quic_jinlmao at quicinc.com>
---
 .../testing/sysfs-bus-coresight-devices-tpdm  |  35 +++++
 drivers/hwtracing/coresight/coresight-tpdm.c  | 121 +++++++++++++++++-
 drivers/hwtracing/coresight/coresight-tpdm.h  |  31 +++++
 3 files changed, 180 insertions(+), 7 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index b6cf050861ed..e8c76ce4dd15 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -214,3 +214,38 @@ KernelVersion	6.9
 Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
 Description:
 		(RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(Write) Set the pattern timestamp of CMB tpdm. Read
+		the pattern timestamp of CMB tpdm.
+
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Disable CMB pattern timestamp.
+		1 : Enable CMB pattern timestamp.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the trigger timestamp of the CMB for tpdm.
+
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Set the CMB trigger type to false
+		1 : Set the CMB trigger type to true
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Read or write the status of timestamp upon all interface.
+		Only value 0 and 1  can be written to this node. Set this node to 1 to requeset
+		timestamp to all trace packet.
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Disable the timestamp of all trace packets.
+		1 : Enable the timestamp of all trace packets.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 07587287d9fa..22966d541230 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -322,6 +322,31 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
 	writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
 }
 
+static void set_cmb_tier(struct tpdm_drvdata *drvdata)
+{
+	u32 val;
+
+	val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
+
+	/* Clear all relevant fields */
+	val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
+		 TPDM_CMB_TIER_XTRIG_TSENAB);
+
+	/* Set pattern timestamp type and enablement */
+	if (drvdata->cmb->patt_ts)
+		val |= TPDM_CMB_TIER_PATT_TSENAB;
+
+	/* Set trigger timestamp */
+	if (drvdata->cmb->trig_ts)
+		val |= TPDM_CMB_TIER_XTRIG_TSENAB;
+
+	/* Set all timestamp enablement*/
+	if (drvdata->cmb->ts_all)
+		val |= TPDM_CMB_TIER_TS_ALL;
+
+	writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
+}
+
 static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 {
 	u32 val, i;
@@ -341,6 +366,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 			drvdata->base + TPDM_CMB_XPMR(i));
 	}
 
+	set_cmb_tier(drvdata);
+
 	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
 	/*
 	 * Set to 0 for continuous CMB collection mode,
@@ -687,9 +714,18 @@ static ssize_t enable_ts_show(struct device *dev,
 			      char *buf)
 {
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct tpdm_dataset_attribute *tpdm_attr =
+		container_of(attr, struct tpdm_dataset_attribute, attr);
+	ssize_t size = -EINVAL;
 
-	return sysfs_emit(buf, "%u\n",
-			 (unsigned int)drvdata->dsb->patt_ts);
+	if (tpdm_attr->mem == DSB_PATT)
+		size = sysfs_emit(buf, "%u\n",
+				  (unsigned int)drvdata->dsb->patt_ts);
+	else if (tpdm_attr->mem == CMB_PATT)
+		size = sysfs_emit(buf, "%u\n",
+				  (unsigned int)drvdata->cmb->patt_ts);
+
+	return size;
 }
 
 /*
@@ -701,17 +737,23 @@ static ssize_t enable_ts_store(struct device *dev,
 			       size_t size)
 {
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct tpdm_dataset_attribute *tpdm_attr =
+		container_of(attr, struct tpdm_dataset_attribute, attr);
 	unsigned long val;
 
 	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
-	drvdata->dsb->patt_ts = !!val;
-	spin_unlock(&drvdata->spinlock);
+	guard(spinlock)(&drvdata->spinlock);
+	if (tpdm_attr->mem == DSB_PATT)
+		drvdata->dsb->patt_ts = !!val;
+	else if (tpdm_attr->mem == CMB_PATT)
+		drvdata->cmb->patt_ts = !!val;
+	else
+		return -EINVAL;
+
 	return size;
 }
-static DEVICE_ATTR_RW(enable_ts);
 
 static ssize_t set_type_show(struct device *dev,
 			     struct device_attribute *attr,
@@ -842,6 +884,68 @@ static ssize_t cmb_mode_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(cmb_mode);
 
+static ssize_t cmb_ts_all_show(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return sysfs_emit(buf, "%u\n",
+			  (unsigned int)drvdata->cmb->ts_all);
+}
+
+static ssize_t cmb_ts_all_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf,
+				size_t size)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
+		return -EINVAL;
+
+	guard(spinlock)(&drvdata->spinlock);
+	if (val)
+		drvdata->cmb->ts_all = true;
+	else
+		drvdata->cmb->ts_all = false;
+
+	return size;
+}
+static DEVICE_ATTR_RW(cmb_ts_all);
+
+static ssize_t cmb_trig_ts_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return sysfs_emit(buf, "%u\n",
+			  (unsigned int)drvdata->cmb->trig_ts);
+}
+
+static ssize_t cmb_trig_ts_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t size)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
+		return -EINVAL;
+
+	guard(spinlock)(&drvdata->spinlock);
+	if (val)
+		drvdata->cmb->trig_ts = true;
+	else
+		drvdata->cmb->trig_ts = false;
+
+	return size;
+}
+static DEVICE_ATTR_RW(cmb_trig_ts);
+
 static struct attribute *tpdm_dsb_edge_attrs[] = {
 	&dev_attr_ctrl_idx.attr,
 	&dev_attr_ctrl_val.attr,
@@ -910,7 +1014,7 @@ static struct attribute *tpdm_dsb_patt_attrs[] = {
 	DSB_PATT_MASK_ATTR(5),
 	DSB_PATT_MASK_ATTR(6),
 	DSB_PATT_MASK_ATTR(7),
-	&dev_attr_enable_ts.attr,
+	DSB_PATT_ENABLE_TS,
 	&dev_attr_set_type.attr,
 	NULL,
 };
@@ -964,6 +1068,7 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
 	CMB_PATT_ATTR(1),
 	CMB_PATT_MASK_ATTR(0),
 	CMB_PATT_MASK_ATTR(1),
+	CMB_PATT_ENABLE_TS,
 	NULL,
 };
 
@@ -976,6 +1081,8 @@ static struct attribute *tpdm_dsb_attrs[] = {
 
 static struct attribute *tpdm_cmb_attrs[] = {
 	&dev_attr_cmb_mode.attr,
+	&dev_attr_cmb_ts_all.attr,
+	&dev_attr_cmb_trig_ts.attr,
 	NULL,
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index e5d4c22cd38c..6d1fe4aed7d0 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -11,6 +11,8 @@
 
 /* CMB Subunit Registers */
 #define TPDM_CMB_CR		(0xA00)
+/* CMB subunit timestamp insertion enable register */
+#define TPDM_CMB_TIER		(0xA04)
 /* CMB subunit timestamp pattern registers */
 #define TPDM_CMB_TPR(n)		(0xA08 + (n * 4))
 /* CMB subunit timestamp pattern mask registers */
@@ -24,6 +26,12 @@
 #define TPDM_CMB_CR_ENA		BIT(0)
 /* Trace collection mode for CMB subunit */
 #define TPDM_CMB_CR_MODE	BIT(1)
+/* Timestamp control for pattern match */
+#define TPDM_CMB_TIER_PATT_TSENAB	BIT(0)
+/* CMB CTI timestamp request */
+#define TPDM_CMB_TIER_XTRIG_TSENAB	BIT(1)
+/* For timestamp fo all trace */
+#define TPDM_CMB_TIER_TS_ALL		BIT(2)
 
 /* Patten register number */
 #define TPDM_CMB_MAX_PATT		2
@@ -134,6 +142,15 @@
 	   }								\
 	})[0].attr.attr)
 
+#define tpdm_patt_enable_ts(name, mem)				\
+	(&((struct tpdm_dataset_attribute[]) {			\
+	   {							\
+		__ATTR(name, 0644, enable_ts_show,		\
+		enable_ts_store),		\
+		mem,						\
+	   }							\
+	})[0].attr.attr)
+
 #define DSB_EDGE_CTRL_ATTR(nr)					\
 		tpdm_simple_dataset_ro(edcr##nr,		\
 		DSB_EDGE_CTRL, nr)
@@ -158,6 +175,10 @@
 		tpdm_simple_dataset_rw(tpmr##nr,		\
 		DSB_PATT_MASK, nr)
 
+#define DSB_PATT_ENABLE_TS					\
+		tpdm_patt_enable_ts(enable_ts,			\
+		DSB_PATT)
+
 #define DSB_MSR_ATTR(nr)					\
 		tpdm_simple_dataset_rw(msr##nr,			\
 		DSB_MSR, nr)
@@ -178,6 +199,10 @@
 		tpdm_simple_dataset_rw(tpmr##nr,		\
 		CMB_PATT_MASK, nr)
 
+#define CMB_PATT_ENABLE_TS					\
+		tpdm_patt_enable_ts(enable_ts,			\
+		CMB_PATT)
+
 /**
  * struct dsb_dataset - specifics associated to dsb dataset
  * @mode:             DSB programming mode
@@ -217,6 +242,9 @@ struct dsb_dataset {
  * @patt_mask:        Save value for pattern mask
  * @trig_patt:        Save value for trigger pattern
  * @trig_patt_mask:   Save value for trigger pattern mask
+ * @patt_ts:          Indicates if pattern match for timestamp is enabled.
+ * @trig_ts:          Indicates if CTI trigger for timestamp is enabled.
+ * @ts_all:           Indicates if timestamp is enabled for all packets.
  */
 struct cmb_dataset {
 	u32			trace_mode;
@@ -224,6 +252,9 @@ struct cmb_dataset {
 	u32			patt_mask[TPDM_CMB_MAX_PATT];
 	u32			trig_patt[TPDM_CMB_MAX_PATT];
 	u32			trig_patt_mask[TPDM_CMB_MAX_PATT];
+	bool			patt_ts;
+	bool			trig_ts;
+	bool			ts_all;
 };
 
 /**
-- 
2.17.1



From quic_taozha at quicinc.com  Sat Feb  3 21:30:41 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:41 +0800
Subject: [PATCH v7 10/10] coresight-tpdm: Add msr register support for CMB
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1707024641-22460-11-git-send-email-quic_taozha@quicinc.com>

Add the nodes for CMB subunit MSR(mux select register) support.
CMB MSRs(mux select registers) is to separate mux, arbitration,
interleaving,data packing control from stream filtering control.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
 drivers/hwtracing/coresight/coresight-tpdm.c  | 85 +++++++++++++++++++
 drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
 3 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index e8c76ce4dd15..b4d0fc8d319d 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -249,3 +249,11 @@ Description:
 		Accepts only one of the 2 values -  0 or 1.
 		0 : Disable the timestamp of all trace packets.
 		1 : Enable the timestamp of all trace packets.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao at quicinc.com>, Tao Zhang (QUIC) <quic_taozha at quicinc.com>
+Description:
+		(RW) Set/Get the MSR(mux select register) for the CMB subunit
+		TPDM.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 22966d541230..a9708ab0d488 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct device *dev,
 			return -EINVAL;
 		return sysfs_emit(buf, "0x%x\n",
 			drvdata->cmb->patt_mask[tpdm_attr->idx]);
+	case CMB_MSR:
+		if (tpdm_attr->idx >= drvdata->cmb_msr_num)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+				drvdata->cmb->msr[tpdm_attr->idx]);
 	}
 	return -EINVAL;
 }
@@ -162,6 +167,12 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
 			ret = size;
 		}
 		break;
+	case CMB_MSR:
+		if (tpdm_attr->idx < drvdata->cmb_msr_num) {
+			drvdata->cmb->msr[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
 	default:
 		break;
 	}
@@ -209,6 +220,23 @@ static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj,
 	return 0;
 }
 
+static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj,
+				       struct attribute *attr, int n)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	struct device_attribute *dev_attr =
+		container_of(attr, struct device_attribute, attr);
+	struct tpdm_dataset_attribute *tpdm_attr =
+		container_of(dev_attr, struct tpdm_dataset_attribute, attr);
+
+	if (tpdm_attr->idx < drvdata->cmb_msr_num)
+		return attr->mode;
+
+	return 0;
+}
+
 static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
 {
 	if (tpdm_has_dsb_dataset(drvdata)) {
@@ -347,6 +375,15 @@ static void set_cmb_tier(struct tpdm_drvdata *drvdata)
 	writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
 }
 
+static void set_cmb_msr(struct tpdm_drvdata *drvdata)
+{
+	int i;
+
+	for (i = 0; i < drvdata->cmb_msr_num; i++)
+		writel_relaxed(drvdata->cmb->msr[i],
+			   drvdata->base + TPDM_CMB_MSR(i));
+}
+
 static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 {
 	u32 val, i;
@@ -367,6 +404,7 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 	}
 
 	set_cmb_tier(drvdata);
+	set_cmb_msr(drvdata);
 
 	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
 	/*
@@ -1072,6 +1110,42 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
 	NULL,
 };
 
+static struct attribute *tpdm_cmb_msr_attrs[] = {
+	CMB_MSR_ATTR(0),
+	CMB_MSR_ATTR(1),
+	CMB_MSR_ATTR(2),
+	CMB_MSR_ATTR(3),
+	CMB_MSR_ATTR(4),
+	CMB_MSR_ATTR(5),
+	CMB_MSR_ATTR(6),
+	CMB_MSR_ATTR(7),
+	CMB_MSR_ATTR(8),
+	CMB_MSR_ATTR(9),
+	CMB_MSR_ATTR(10),
+	CMB_MSR_ATTR(11),
+	CMB_MSR_ATTR(12),
+	CMB_MSR_ATTR(13),
+	CMB_MSR_ATTR(14),
+	CMB_MSR_ATTR(15),
+	CMB_MSR_ATTR(16),
+	CMB_MSR_ATTR(17),
+	CMB_MSR_ATTR(18),
+	CMB_MSR_ATTR(19),
+	CMB_MSR_ATTR(20),
+	CMB_MSR_ATTR(21),
+	CMB_MSR_ATTR(22),
+	CMB_MSR_ATTR(23),
+	CMB_MSR_ATTR(24),
+	CMB_MSR_ATTR(25),
+	CMB_MSR_ATTR(26),
+	CMB_MSR_ATTR(27),
+	CMB_MSR_ATTR(28),
+	CMB_MSR_ATTR(29),
+	CMB_MSR_ATTR(30),
+	CMB_MSR_ATTR(31),
+	NULL,
+};
+
 static struct attribute *tpdm_dsb_attrs[] = {
 	&dev_attr_dsb_mode.attr,
 	&dev_attr_dsb_trig_ts.attr,
@@ -1132,6 +1206,12 @@ static struct attribute_group tpdm_cmb_patt_grp = {
 	.name = "cmb_patt",
 };
 
+static struct attribute_group tpdm_cmb_msr_grp = {
+	.attrs = tpdm_cmb_msr_attrs,
+	.is_visible = tpdm_cmb_msr_is_visible,
+	.name = "cmb_msr",
+};
+
 static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_attr_grp,
 	&tpdm_dsb_attr_grp,
@@ -1142,6 +1222,7 @@ static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_cmb_attr_grp,
 	&tpdm_cmb_trig_patt_grp,
 	&tpdm_cmb_patt_grp,
+	&tpdm_cmb_msr_grp,
 	NULL,
 };
 
@@ -1180,6 +1261,10 @@ static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
 		of_property_read_u32(drvdata->dev->of_node,
 			   "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
 
+	if (drvdata && tpdm_has_cmb_dataset(drvdata))
+		of_property_read_u32(drvdata->dev->of_node,
+			   "qcom,cmb-msrs-num", &drvdata->cmb_msr_num);
+
 	/* Set up coresight component description */
 	desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
 	if (!desc.name)
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index 6d1fe4aed7d0..f3a8f56d0fe7 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -21,6 +21,8 @@
 #define TPDM_CMB_XPR(n)		(0xA18 + (n * 4))
 /* CMB subunit trigger pattern mask registers */
 #define TPDM_CMB_XPMR(n)	(0xA20 + (n * 4))
+/* CMB MSR register */
+#define TPDM_CMB_MSR(n)		(0xA80 + (n * 4))
 
 /* Enable bit for CMB subunit */
 #define TPDM_CMB_CR_ENA		BIT(0)
@@ -36,6 +38,9 @@
 /* Patten register number */
 #define TPDM_CMB_MAX_PATT		2
 
+/* MAX number of DSB MSR */
+#define TPDM_CMB_MAX_MSR 32
+
 /* DSB Subunit Registers */
 #define TPDM_DSB_CR		(0x780)
 #define TPDM_DSB_TIER		(0x784)
@@ -203,6 +208,10 @@
 		tpdm_patt_enable_ts(enable_ts,			\
 		CMB_PATT)
 
+#define CMB_MSR_ATTR(nr)					\
+		tpdm_simple_dataset_rw(msr##nr,			\
+		CMB_MSR, nr)
+
 /**
  * struct dsb_dataset - specifics associated to dsb dataset
  * @mode:             DSB programming mode
@@ -242,6 +251,7 @@ struct dsb_dataset {
  * @patt_mask:        Save value for pattern mask
  * @trig_patt:        Save value for trigger pattern
  * @trig_patt_mask:   Save value for trigger pattern mask
+ * @msr               Save value for MSR
  * @patt_ts:          Indicates if pattern match for timestamp is enabled.
  * @trig_ts:          Indicates if CTI trigger for timestamp is enabled.
  * @ts_all:           Indicates if timestamp is enabled for all packets.
@@ -252,6 +262,7 @@ struct cmb_dataset {
 	u32			patt_mask[TPDM_CMB_MAX_PATT];
 	u32			trig_patt[TPDM_CMB_MAX_PATT];
 	u32			trig_patt_mask[TPDM_CMB_MAX_PATT];
+	u32			msr[TPDM_CMB_MAX_MSR];
 	bool			patt_ts;
 	bool			trig_ts;
 	bool			ts_all;
@@ -268,6 +279,7 @@ struct cmb_dataset {
  * @dsb         Specifics associated to TPDM DSB.
  * @cmb         Specifics associated to TPDM CMB.
  * @dsb_msr_num Number of MSR supported by DSB TPDM
+ * @cmb_msr_num Number of MSR supported by CMB TPDM
  */
 
 struct tpdm_drvdata {
@@ -280,6 +292,7 @@ struct tpdm_drvdata {
 	struct dsb_dataset	*dsb;
 	struct cmb_dataset	*cmb;
 	u32			dsb_msr_num;
+	u32			cmb_msr_num;
 };
 
 /* Enumerate members of various datasets */
@@ -294,7 +307,8 @@ enum dataset_mem {
 	CMB_TRIG_PATT,
 	CMB_TRIG_PATT_MASK,
 	CMB_PATT,
-	CMB_PATT_MASK
+	CMB_PATT_MASK,
+	CMB_MSR
 };
 
 /**
-- 
2.17.1



From quic_taozha at quicinc.com  Sat Feb  3 21:30:40 2024
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Sun, 4 Feb 2024 13:30:40 +0800
Subject: [PATCH v7 09/10] dt-bindings: arm: qcom,coresight-tpdm: Add support for TPDM CMB MSR register
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1707024641-22460-10-git-send-email-quic_taozha@quicinc.com>

Add property "qcom,cmb_msr_num" to support CMB MSR(mux select register)
for TPDM. It specifies the number of CMB MSR registers supported by
the TDPM.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml   | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
index 2320b5445900..d0647ffaed71 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
@@ -69,6 +69,15 @@ properties:
     minimum: 0
     maximum: 32
 
+  qcom,cmb-msrs-num:
+    description:
+      Specifies the number of CMB MSR(mux select register) registers supported
+      by the monitor. If this property is not configured or set to 0, it means
+      this TPDM doesn't support CMB MSR.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 32
+
   clocks:
     maxItems: 1
 
@@ -123,6 +132,7 @@ examples:
       reg = <0x06c29000 0x1000>;
 
       qcom,cmb-element-bits = <64>;
+      qcom,cmb-msrs-num = <32>;
 
       clocks = <&aoss_qmp>;
       clock-names = "apb_pclk";
-- 
2.17.1



From Chunfeng.Yun at mediatek.com  Sat Feb  3 22:03:18 2024
From: Chunfeng.Yun at mediatek.com (=?utf-8?B?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?=)
Date: Sun, 4 Feb 2024 06:03:18 +0000
Subject: [PATCH v2 2/2] usb: mtu3: Add MT8195 MTU3 ip-sleep wakeup support
In-Reply-To: <20240122111809.148546-2-angelogioacchino.delregno@collabora.com>
References: <20240122111809.148546-1-angelogioacchino.delregno@collabora.com>
	 <20240122111809.148546-2-angelogioacchino.delregno@collabora.com>
Message-ID: <0f96aac2ee16c31808f22853fdf746678f5284e8.camel@mediatek.com>

On Mon, 2024-01-22 at 12:18 +0100, AngeloGioacchino Del Regno wrote:
> Add support for the ip-sleep wakeup functionality on the three MTU3
> controllers found on the MT8195 SoC.
> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
> 
> Changes in v2:
>  - Dropped unused definition for WC0_IS_EN_P1_95
> 
>  drivers/usb/mtu3/mtu3_host.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/usb/mtu3/mtu3_host.c
> b/drivers/usb/mtu3/mtu3_host.c
> index 9f2be22af844..7c657ea2dabd 100644
> --- a/drivers/usb/mtu3/mtu3_host.c
> +++ b/drivers/usb/mtu3/mtu3_host.c
> @@ -34,6 +34,18 @@
>  #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 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)
> @@ -44,6 +56,9 @@ enum ssusb_uwk_vers {
>  	SSUSB_UWK_V2,
>  	SSUSB_UWK_V1_1 = 101,	/* specific revision 1.01 */
>  	SSUSB_UWK_V1_2,		/* specific revision 1.02 */
> +	SSUSB_UWK_V1_3,		/* mt8195 IP0 */
> +	SSUSB_UWK_V1_5 = 105,	/* mt8195 IP2 */
> +	SSUSB_UWK_V1_6,		/* mt8195 IP3 */
>  };
>  
>  /*
> @@ -70,6 +85,21 @@ static void ssusb_wakeup_ip_sleep_set(struct
> ssusb_mtk *ssusb, bool enable)
>  		msk = WC0_SSUSB0_CDEN | WC0_IS_SPM_EN;
>  		val = enable ? msk : 0;
>  		break;
> +	case SSUSB_UWK_V1_3:
> +		reg = ssusb->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_5:
> +		reg = ssusb->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 = ssusb->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 = ssusb->uwk_reg_base + PERI_SSUSB_SPM_CTRL;
>  		msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN;

which project will use ip-sleep wakeup for mt8195? only use device
mode?

As I know, when use upstream code to support dual-role mode on mt8195,
there is a bug caused by hw limitation;



From zhi.mao at mediatek.com  Sat Feb  3 22:15:37 2024
From: zhi.mao at mediatek.com (Zhi Mao)
Date: Sun, 4 Feb 2024 14:15:37 +0800
Subject: [PATCH v4 1/2] media: dt-bindings: i2c: add GalaxyCore GC08A3 image sensor
In-Reply-To: <20240204061538.2105-1-zhi.mao@mediatek.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
Message-ID: <20240204061538.2105-2-zhi.mao@mediatek.com>

Add YAML device tree binding for GC08A3 CMOS image sensor,
and the relevant MAINTAINERS entries.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
---
 .../bindings/media/i2c/galaxycore,gc08a3.yaml | 112 ++++++++++++++++++
 1 file changed, 112 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml

diff --git a/Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml
new file mode 100644
index 000000000000..8c09e8c121e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (c) 2023 MediaTek Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/galaxycore,gc08a3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GalaxyCore gc08a3 1/4" 8M Pixel MIPI CSI-2 sensor
+
+maintainers:
+  - Zhi Mao <zhi.mao at mediatek.com>
+
+description:
+  The gc08a3 is a raw image sensor with an MIPI CSI-2 image data
+  interface and CCI (I2C compatible) control bus. The output format
+  is raw Bayer.
+
+properties:
+  compatible:
+    const: galaxycore,gc08a3
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  dovdd-supply: true
+
+  avdd-supply: true
+
+  dvdd-supply: true
+
+  reset-gpios:
+    description: Reference to the GPIO connected to the RESETB pin.
+    maxItems: 1
+
+  port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    additionalProperties: false
+    description:
+      Output port node, single endpoint describing the CSI-2 transmitter.
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          data-lanes:
+            oneOf:
+              - items:
+                  - const: 1
+                  - const: 2
+                  - const: 3
+                  - const: 4
+              - items:
+                  - const: 1
+                  - const: 2
+
+          link-frequencies: true
+
+        required:
+          - data-lanes
+          - link-frequencies
+
+    required:
+      - endpoint
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - dovdd-supply
+  - avdd-supply
+  - dvdd-supply
+  - reset-gpios
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        sensor at 31 {
+            compatible = "galaxycore,gc08a3";
+            reg = <0x31>;
+
+            clocks = <&gc08a3_clk>;
+
+            reset-gpios = <&pio 19 GPIO_ACTIVE_HIGH>;
+
+            avdd-supply = <&gc08a3_avdd>;
+            dovdd-supply = <&gc08a3_dovdd>;
+            dvdd-supply = <&gc08a3_dvdd>;
+
+            port {
+                sensor_out: endpoint {
+                    data-lanes = <1 2 3 4>;
+                    link-frequencies = /bits/ 64 <336000000 207000000>;
+                    remote-endpoint = <&seninf_csi_port_0_in>;
+                };
+            };
+        };
+    };
+
+...
-- 
2.25.1



From zhi.mao at mediatek.com  Sat Feb  3 22:15:38 2024
From: zhi.mao at mediatek.com (Zhi Mao)
Date: Sun, 4 Feb 2024 14:15:38 +0800
Subject: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <20240204061538.2105-1-zhi.mao@mediatek.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
Message-ID: <20240204061538.2105-3-zhi.mao@mediatek.com>

Add a V4L2 sub-device driver for Galaxycore GC08A3 image sensor.

Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
---
 drivers/media/i2c/Kconfig  |   10 +
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/gc08a3.c | 1448 ++++++++++++++++++++++++++++++++++++
 3 files changed, 1459 insertions(+)
 create mode 100644 drivers/media/i2c/gc08a3.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 56f276b920ab..e4da68835683 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -70,6 +70,16 @@ config VIDEO_GC0308
 	  To compile this driver as a module, choose M here: the
 	  module will be called gc0308.
 
+config VIDEO_GC08A3
+	tristate "GalaxyCore gc08a3 sensor support"
+	select V4L2_CCI_I2C
+	help
+	  This is a Video4Linux2 sensor driver for the GalaxyCore gc08a3
+	  camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gc08a3.
+
 config VIDEO_GC2145
 	select V4L2_CCI_I2C
 	tristate "GalaxyCore GC2145 sensor support"
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index dfbe6448b549..b82e99ca7578 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
 obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
 obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
 obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
+obj-$(CONFIG_VIDEO_GC08A3) += gc08a3.o
 obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
 obj-$(CONFIG_VIDEO_HI556) += hi556.o
 obj-$(CONFIG_VIDEO_HI846) += hi846.o
diff --git a/drivers/media/i2c/gc08a3.c b/drivers/media/i2c/gc08a3.c
new file mode 100644
index 000000000000..3fc7fffb815c
--- /dev/null
+++ b/drivers/media/i2c/gc08a3.c
@@ -0,0 +1,1448 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * gc08a3.c - gc08a3 sensor driver
+ *
+ * Copyright 2023 MediaTek
+ *
+ * Zhi Mao <zhi.mao at mediatek.com>
+ */
+
+#include <asm/unaligned.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-cci.h>
+#include <media/v4l2-event.h>
+
+#define GC08A3_REG_CHIP_ID CCI_REG16(0x03f0)
+#define GC08A3_CHIP_ID 0x08a3
+
+#define GC08A3_NATIVE_WIDTH 3264
+#define GC08A3_NATIVE_HEIGHT 2448
+
+#define GC08A3_REG_TEST_PATTERN_EN CCI_REG8(0x008c)
+#define GC08A3_REG_TEST_PATTERN_IDX CCI_REG8(0x008d)
+#define GC08A3_TEST_PATTERN_EN 0x01
+
+#define GC08A3_STRAEMING_REG CCI_REG8(0x0100)
+
+#define GC08A3_DEFAULT_CLK_FREQ 24000000
+#define GC08A3_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
+#define GC08A3_DATA_LANES 4
+
+/* for 1920*1080 */
+#define GC08A3_LINK_FREQ_207MHZ 207000000ULL
+/* for 3264*2448 */
+#define GC08A3_LINK_FREQ_336MHZ 336000000ULL
+
+#define GC08A3_RGB_DEPTH 10
+
+#define GC08A3_FRAME_LENGTH_REG CCI_REG16(0x0340)
+#define GC08A3_VTS_30FPS 2548
+#define GC08A3_VTS_30FPS_MIN 2548
+#define GC08A3_VTS_60FPS 1276
+#define GC08A3_VTS_60FPS_MIN 1276
+#define GC08A3_VTS_MAX 0xfff0
+
+#define GC08A3_HTS_30FPS 3640
+#define GC08A3_HTS_60FPS 3640
+
+#define GC08A3_EXP_REG CCI_REG16(0x0202)
+#define GC08A3_EXP_MARGIN 16
+#define GC08A3_EXP_MIN 4
+#define GC08A3_EXP_STEP 1
+
+#define GC08A3_FLIP_REG CCI_REG8(0x0101)
+#define GC08A3_FLIP_H_MASK 0x1
+#define GC08A3_FLIP_V_MASK 0x2
+
+#define GC08A3_AGAIN_REG CCI_REG16(0x0204)
+#define GC08A3_AGAIN_MIN 1024
+#define GC08A3_AGAIN_MAX (1024 * 16)
+#define GC08A3_AGAIN_STEP 1
+
+#define GC08A3_MIN_SLEEP_US  2000
+#define GC08A3_MAX_SLEEP_US  3000
+
+static const char *const gc08a3_test_pattern_menu[] = {
+	"No Pattern", "Solid Black", "Colour Bar", "Solid White",
+	"Solid Red", "Solid Green", "Solid Blue", "Solid Yellow",
+};
+
+enum {
+	GC08A3_LINK_FREQ_336MHZ_INDEX,
+	GC08A3_LINK_FREQ_207MHZ_INDEX,
+};
+
+static const s64 link_freq_menu_items[] = {
+	GC08A3_LINK_FREQ_336MHZ,
+	GC08A3_LINK_FREQ_207MHZ,
+};
+
+static const char *const gc08a3_supply_name[] = {
+	"avdd",
+	"dvdd",
+	"dovdd",
+};
+
+struct gc08a3 {
+	struct device *dev;
+	struct v4l2_subdev sd;
+	struct media_pad pad;
+	struct i2c_client *client;
+
+	struct clk *xclk;
+	struct regulator_bulk_data supplies[ARRAY_SIZE(gc08a3_supply_name)];
+	struct gpio_desc *reset_gpio;
+
+	struct v4l2_ctrl_handler ctrls;
+	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *link_freq;
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *hblank;
+
+	struct regmap *regmap;
+
+	bool streaming;
+	unsigned long link_freq_bitmap;
+
+	/* Current mode */
+	const struct gc08a3_mode *cur_mode;
+};
+
+struct gc08a3_reg_list {
+	u32 num_of_regs;
+	const struct cci_reg_sequence *regs;
+};
+
+struct gc08a3_link_freq_config {
+	const struct gc08a3_reg_list reg_list;
+};
+
+static const struct cci_reg_sequence mode_3264x2448[] = {
+	/* system */
+	{ CCI_REG8(0x0336), 0x70 },
+	{ CCI_REG8(0x0383), 0xbb },
+	{ CCI_REG8(0x0344), 0x00 },
+	{ CCI_REG8(0x0345), 0x06 },
+	{ CCI_REG8(0x0346), 0x00 },
+	{ CCI_REG8(0x0347), 0x04 },
+	{ CCI_REG8(0x0348), 0x0c },
+	{ CCI_REG8(0x0349), 0xd0 },
+	{ CCI_REG8(0x034a), 0x09 },
+	{ CCI_REG8(0x034b), 0x9c },
+	{ CCI_REG8(0x0202), 0x09 },
+	{ CCI_REG8(0x0203), 0x04 },
+	{ CCI_REG8(0x0340), 0x09 },
+	{ CCI_REG8(0x0341), 0xf4 },
+	{ CCI_REG8(0x0342), 0x07 },
+	{ CCI_REG8(0x0343), 0x1c },
+
+	{ CCI_REG8(0x0226), 0x00 },
+	{ CCI_REG8(0x0227), 0x28 },
+	{ CCI_REG8(0x0e38), 0x49 },
+	{ CCI_REG8(0x0210), 0x13 },
+	{ CCI_REG8(0x0218), 0x00 },
+	{ CCI_REG8(0x0241), 0x88 },
+	{ CCI_REG8(0x0392), 0x60 },
+
+	/* ISP */
+	{ CCI_REG8(0x00a2), 0x00 },
+	{ CCI_REG8(0x00a3), 0x00 },
+	{ CCI_REG8(0x00ab), 0x00 },
+	{ CCI_REG8(0x00ac), 0x00 },
+
+	/* GAIN */
+	{ CCI_REG8(0x0204), 0x04 },
+	{ CCI_REG8(0x0205), 0x00 },
+	{ CCI_REG8(0x0050), 0x5c },
+	{ CCI_REG8(0x0051), 0x44 },
+
+	/* out window */
+	{ CCI_REG8(0x009a), 0x66 },
+	{ CCI_REG8(0x0351), 0x00 },
+	{ CCI_REG8(0x0352), 0x06 },
+	{ CCI_REG8(0x0353), 0x00 },
+	{ CCI_REG8(0x0354), 0x08 },
+	{ CCI_REG8(0x034c), 0x0c },
+	{ CCI_REG8(0x034d), 0xc0 },
+	{ CCI_REG8(0x034e), 0x09 },
+	{ CCI_REG8(0x034f), 0x90 },
+
+	/* MIPI */
+	{ CCI_REG8(0x0114), 0x03 },
+	{ CCI_REG8(0x0180), 0x65 },
+	{ CCI_REG8(0x0181), 0xf0 },
+	{ CCI_REG8(0x0185), 0x01 },
+	{ CCI_REG8(0x0115), 0x30 },
+	{ CCI_REG8(0x011b), 0x12 },
+	{ CCI_REG8(0x011c), 0x12 },
+	{ CCI_REG8(0x0121), 0x06 },
+	{ CCI_REG8(0x0122), 0x06 },
+	{ CCI_REG8(0x0123), 0x15 },
+	{ CCI_REG8(0x0124), 0x01 },
+	{ CCI_REG8(0x0125), 0x0b },
+	{ CCI_REG8(0x0126), 0x08 },
+	{ CCI_REG8(0x0129), 0x06 },
+	{ CCI_REG8(0x012a), 0x08 },
+	{ CCI_REG8(0x012b), 0x08 },
+
+	{ CCI_REG8(0x0a73), 0x60 },
+	{ CCI_REG8(0x0a70), 0x11 },
+	{ CCI_REG8(0x0313), 0x80 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0a70), 0x00 },
+	{ CCI_REG8(0x00a4), 0x80 },
+	{ CCI_REG8(0x0316), 0x01 },
+	{ CCI_REG8(0x0a67), 0x00 },
+	{ CCI_REG8(0x0084), 0x10 },
+	{ CCI_REG8(0x0102), 0x09 },
+};
+
+static const struct cci_reg_sequence mode_1920x1080[] = {
+	/* system */
+	{ CCI_REG8(0x0336), 0x45 },
+	{ CCI_REG8(0x0383), 0x8b },
+	{ CCI_REG8(0x0344), 0x02 },
+	{ CCI_REG8(0x0345), 0xa6 },
+	{ CCI_REG8(0x0346), 0x02 },
+	{ CCI_REG8(0x0347), 0xb0 },
+	{ CCI_REG8(0x0348), 0x07 },
+	{ CCI_REG8(0x0349), 0x90 },
+	{ CCI_REG8(0x034a), 0x04 },
+	{ CCI_REG8(0x034b), 0x44 },
+	{ CCI_REG8(0x0202), 0x03 },
+	{ CCI_REG8(0x0203), 0x00 },
+	{ CCI_REG8(0x0340), 0x04 },
+	{ CCI_REG8(0x0341), 0xfc },
+	{ CCI_REG8(0x0342), 0x07 },
+	{ CCI_REG8(0x0343), 0x1c },
+	{ CCI_REG8(0x0226), 0x00 },
+	{ CCI_REG8(0x0227), 0x88 },
+	{ CCI_REG8(0x0e38), 0x49 },
+	{ CCI_REG8(0x0210), 0x13 },
+	{ CCI_REG8(0x0218), 0x00 },
+	{ CCI_REG8(0x0241), 0x88 },
+	{ CCI_REG8(0x0392), 0x60 },
+
+	/* ISP */
+	{ CCI_REG8(0x00a2), 0xac },
+	{ CCI_REG8(0x00a3), 0x02 },
+	{ CCI_REG8(0x00ab), 0xa0 },
+	{ CCI_REG8(0x00ac), 0x02 },
+
+	/* GAIN */
+	{ CCI_REG8(0x0204), 0x04 },
+	{ CCI_REG8(0x0205), 0x00 },
+	{ CCI_REG8(0x0050), 0x38 },
+	{ CCI_REG8(0x0051), 0x20 },
+
+	/* out window */
+	{ CCI_REG8(0x009a), 0x66 },
+	{ CCI_REG8(0x0351), 0x00 },
+	{ CCI_REG8(0x0352), 0x06 },
+	{ CCI_REG8(0x0353), 0x00 },
+	{ CCI_REG8(0x0354), 0x08 },
+	{ CCI_REG8(0x034c), 0x07 },
+	{ CCI_REG8(0x034d), 0x80 },
+	{ CCI_REG8(0x034e), 0x04 },
+	{ CCI_REG8(0x034f), 0x38 },
+
+	/* MIPI */
+	{ CCI_REG8(0x0114), 0x03 },
+	{ CCI_REG8(0x0180), 0x65 },
+	{ CCI_REG8(0x0181), 0xf0 },
+	{ CCI_REG8(0x0185), 0x01 },
+	{ CCI_REG8(0x0115), 0x30 },
+	{ CCI_REG8(0x011b), 0x12 },
+	{ CCI_REG8(0x011c), 0x12 },
+	{ CCI_REG8(0x0121), 0x02 },
+	{ CCI_REG8(0x0122), 0x03 },
+	{ CCI_REG8(0x0123), 0x0c },
+	{ CCI_REG8(0x0124), 0x00 },
+	{ CCI_REG8(0x0125), 0x09 },
+	{ CCI_REG8(0x0126), 0x06 },
+	{ CCI_REG8(0x0129), 0x04 },
+	{ CCI_REG8(0x012a), 0x03 },
+	{ CCI_REG8(0x012b), 0x06 },
+
+	{ CCI_REG8(0x0a73), 0x60 },
+	{ CCI_REG8(0x0a70), 0x11 },
+	{ CCI_REG8(0x0313), 0x80 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0a70), 0x00 },
+	{ CCI_REG8(0x00a4), 0x80 },
+	{ CCI_REG8(0x0316), 0x01 },
+	{ CCI_REG8(0x0a67), 0x00 },
+	{ CCI_REG8(0x0084), 0x10 },
+	{ CCI_REG8(0x0102), 0x09 },
+};
+
+static const struct cci_reg_sequence mode_table_common[] = {
+	{ GC08A3_STRAEMING_REG, 0x00 },
+	/* system */
+	{ CCI_REG8(0x031c), 0x60 },
+	{ CCI_REG8(0x0337), 0x04 },
+	{ CCI_REG8(0x0335), 0x51 },
+	{ CCI_REG8(0x0336), 0x70 },
+	{ CCI_REG8(0x0383), 0xbb },
+	{ CCI_REG8(0x031a), 0x00 },
+	{ CCI_REG8(0x0321), 0x10 },
+	{ CCI_REG8(0x0327), 0x03 },
+	{ CCI_REG8(0x0325), 0x40 },
+	{ CCI_REG8(0x0326), 0x23 },
+	{ CCI_REG8(0x0314), 0x11 },
+	{ CCI_REG8(0x0315), 0xd6 },
+	{ CCI_REG8(0x0316), 0x01 },
+	{ CCI_REG8(0x0334), 0x40 },
+	{ CCI_REG8(0x0324), 0x42 },
+	{ CCI_REG8(0x031c), 0x00 },
+	{ CCI_REG8(0x031c), 0x9f },
+	{ CCI_REG8(0x039a), 0x13 },
+	{ CCI_REG8(0x0084), 0x30 },
+	{ CCI_REG8(0x02b3), 0x08 },
+	{ CCI_REG8(0x0057), 0x0c },
+	{ CCI_REG8(0x05c3), 0x50 },
+	{ CCI_REG8(0x0311), 0x90 },
+	{ CCI_REG8(0x05a0), 0x02 },
+	{ CCI_REG8(0x0074), 0x0a },
+	{ CCI_REG8(0x0059), 0x11 },
+	{ CCI_REG8(0x0070), 0x05 },
+	{ CCI_REG8(0x0101), 0x00 },
+
+	/* analog */
+	{ CCI_REG8(0x0344), 0x00 },
+	{ CCI_REG8(0x0345), 0x06 },
+	{ CCI_REG8(0x0346), 0x00 },
+	{ CCI_REG8(0x0347), 0x04 },
+	{ CCI_REG8(0x0348), 0x0c },
+	{ CCI_REG8(0x0349), 0xd0 },
+	{ CCI_REG8(0x034a), 0x09 },
+	{ CCI_REG8(0x034b), 0x9c },
+	{ CCI_REG8(0x0202), 0x09 },
+	{ CCI_REG8(0x0203), 0x04 },
+
+	{ CCI_REG8(0x0219), 0x05 },
+	{ CCI_REG8(0x0226), 0x00 },
+	{ CCI_REG8(0x0227), 0x28 },
+	{ CCI_REG8(0x0e0a), 0x00 },
+	{ CCI_REG8(0x0e0b), 0x00 },
+	{ CCI_REG8(0x0e24), 0x04 },
+	{ CCI_REG8(0x0e25), 0x04 },
+	{ CCI_REG8(0x0e26), 0x00 },
+	{ CCI_REG8(0x0e27), 0x10 },
+	{ CCI_REG8(0x0e01), 0x74 },
+	{ CCI_REG8(0x0e03), 0x47 },
+	{ CCI_REG8(0x0e04), 0x33 },
+	{ CCI_REG8(0x0e05), 0x44 },
+	{ CCI_REG8(0x0e06), 0x44 },
+	{ CCI_REG8(0x0e0c), 0x1e },
+	{ CCI_REG8(0x0e17), 0x3a },
+	{ CCI_REG8(0x0e18), 0x3c },
+	{ CCI_REG8(0x0e19), 0x40 },
+	{ CCI_REG8(0x0e1a), 0x42 },
+	{ CCI_REG8(0x0e28), 0x21 },
+	{ CCI_REG8(0x0e2b), 0x68 },
+	{ CCI_REG8(0x0e2c), 0x0d },
+	{ CCI_REG8(0x0e2d), 0x08 },
+	{ CCI_REG8(0x0e34), 0xf4 },
+	{ CCI_REG8(0x0e35), 0x44 },
+	{ CCI_REG8(0x0e36), 0x07 },
+	{ CCI_REG8(0x0e38), 0x49 },
+	{ CCI_REG8(0x0210), 0x13 },
+	{ CCI_REG8(0x0218), 0x00 },
+	{ CCI_REG8(0x0241), 0x88 },
+	{ CCI_REG8(0x0e32), 0x00 },
+	{ CCI_REG8(0x0e33), 0x18 },
+	{ CCI_REG8(0x0e42), 0x03 },
+	{ CCI_REG8(0x0e43), 0x80 },
+	{ CCI_REG8(0x0e44), 0x04 },
+	{ CCI_REG8(0x0e45), 0x00 },
+	{ CCI_REG8(0x0e4f), 0x04 },
+	{ CCI_REG8(0x057a), 0x20 },
+	{ CCI_REG8(0x0381), 0x7c },
+	{ CCI_REG8(0x0382), 0x9b },
+	{ CCI_REG8(0x0384), 0xfb },
+	{ CCI_REG8(0x0389), 0x38 },
+	{ CCI_REG8(0x038a), 0x03 },
+	{ CCI_REG8(0x0390), 0x6a },
+	{ CCI_REG8(0x0391), 0x0b },
+	{ CCI_REG8(0x0392), 0x60 },
+	{ CCI_REG8(0x0393), 0xc1 },
+	{ CCI_REG8(0x0396), 0xff },
+	{ CCI_REG8(0x0398), 0x62 },
+
+	/* cisctl reset */
+	{ CCI_REG8(0x031c), 0x80 },
+	{ CCI_REG8(0x03fe), 0x10 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x031c), 0x9f },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x031c), 0x80 },
+	{ CCI_REG8(0x03fe), 0x10 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x031c), 0x9f },
+	{ CCI_REG8(0x0360), 0x01 },
+	{ CCI_REG8(0x0360), 0x00 },
+	{ CCI_REG8(0x0316), 0x09 },
+	{ CCI_REG8(0x0a67), 0x80 },
+	{ CCI_REG8(0x0313), 0x00 },
+	{ CCI_REG8(0x0a53), 0x0e },
+	{ CCI_REG8(0x0a65), 0x17 },
+	{ CCI_REG8(0x0a68), 0xa1 },
+	{ CCI_REG8(0x0a58), 0x00 },
+	{ CCI_REG8(0x0ace), 0x0c },
+	{ CCI_REG8(0x00a4), 0x00 },
+	{ CCI_REG8(0x00a5), 0x01 },
+	{ CCI_REG8(0x00a7), 0x09 },
+	{ CCI_REG8(0x00a8), 0x9c },
+	{ CCI_REG8(0x00a9), 0x0c },
+	{ CCI_REG8(0x00aa), 0xd0 },
+	{ CCI_REG8(0x0a8a), 0x00 },
+	{ CCI_REG8(0x0a8b), 0xe0 },
+	{ CCI_REG8(0x0a8c), 0x13 },
+	{ CCI_REG8(0x0a8d), 0xe8 },
+	{ CCI_REG8(0x0a90), 0x0a },
+	{ CCI_REG8(0x0a91), 0x10 },
+	{ CCI_REG8(0x0a92), 0xf8 },
+	{ CCI_REG8(0x0a71), 0xf2 },
+	{ CCI_REG8(0x0a72), 0x12 },
+	{ CCI_REG8(0x0a73), 0x64 },
+	{ CCI_REG8(0x0a75), 0x41 },
+	{ CCI_REG8(0x0a70), 0x07 },
+	{ CCI_REG8(0x0313), 0x80 },
+
+	/* ISP */
+	{ CCI_REG8(0x00a0), 0x01 },
+	{ CCI_REG8(0x0080), 0xd2 },
+	{ CCI_REG8(0x0081), 0x3f },
+	{ CCI_REG8(0x0087), 0x51 },
+	{ CCI_REG8(0x0089), 0x03 },
+	{ CCI_REG8(0x009b), 0x40 },
+	{ CCI_REG8(0x05a0), 0x82 },
+	{ CCI_REG8(0x05ac), 0x00 },
+	{ CCI_REG8(0x05ad), 0x01 },
+	{ CCI_REG8(0x05ae), 0x00 },
+	{ CCI_REG8(0x0800), 0x0a },
+	{ CCI_REG8(0x0801), 0x14 },
+	{ CCI_REG8(0x0802), 0x28 },
+	{ CCI_REG8(0x0803), 0x34 },
+	{ CCI_REG8(0x0804), 0x0e },
+	{ CCI_REG8(0x0805), 0x33 },
+	{ CCI_REG8(0x0806), 0x03 },
+	{ CCI_REG8(0x0807), 0x8a },
+	{ CCI_REG8(0x0808), 0x50 },
+	{ CCI_REG8(0x0809), 0x00 },
+	{ CCI_REG8(0x080a), 0x34 },
+	{ CCI_REG8(0x080b), 0x03 },
+	{ CCI_REG8(0x080c), 0x26 },
+	{ CCI_REG8(0x080d), 0x03 },
+	{ CCI_REG8(0x080e), 0x18 },
+	{ CCI_REG8(0x080f), 0x03 },
+	{ CCI_REG8(0x0810), 0x10 },
+	{ CCI_REG8(0x0811), 0x03 },
+	{ CCI_REG8(0x0812), 0x00 },
+	{ CCI_REG8(0x0813), 0x00 },
+	{ CCI_REG8(0x0814), 0x01 },
+	{ CCI_REG8(0x0815), 0x00 },
+	{ CCI_REG8(0x0816), 0x01 },
+	{ CCI_REG8(0x0817), 0x00 },
+	{ CCI_REG8(0x0818), 0x00 },
+	{ CCI_REG8(0x0819), 0x0a },
+	{ CCI_REG8(0x081a), 0x01 },
+	{ CCI_REG8(0x081b), 0x6c },
+	{ CCI_REG8(0x081c), 0x00 },
+	{ CCI_REG8(0x081d), 0x0b },
+	{ CCI_REG8(0x081e), 0x02 },
+	{ CCI_REG8(0x081f), 0x00 },
+	{ CCI_REG8(0x0820), 0x00 },
+	{ CCI_REG8(0x0821), 0x0c },
+	{ CCI_REG8(0x0822), 0x02 },
+	{ CCI_REG8(0x0823), 0xd9 },
+	{ CCI_REG8(0x0824), 0x00 },
+	{ CCI_REG8(0x0825), 0x0d },
+	{ CCI_REG8(0x0826), 0x03 },
+	{ CCI_REG8(0x0827), 0xf0 },
+	{ CCI_REG8(0x0828), 0x00 },
+	{ CCI_REG8(0x0829), 0x0e },
+	{ CCI_REG8(0x082a), 0x05 },
+	{ CCI_REG8(0x082b), 0x94 },
+	{ CCI_REG8(0x082c), 0x09 },
+	{ CCI_REG8(0x082d), 0x6e },
+	{ CCI_REG8(0x082e), 0x07 },
+	{ CCI_REG8(0x082f), 0xe6 },
+	{ CCI_REG8(0x0830), 0x10 },
+	{ CCI_REG8(0x0831), 0x0e },
+	{ CCI_REG8(0x0832), 0x0b },
+	{ CCI_REG8(0x0833), 0x2c },
+	{ CCI_REG8(0x0834), 0x14 },
+	{ CCI_REG8(0x0835), 0xae },
+	{ CCI_REG8(0x0836), 0x0f },
+	{ CCI_REG8(0x0837), 0xc4 },
+	{ CCI_REG8(0x0838), 0x18 },
+	{ CCI_REG8(0x0839), 0x0e },
+	{ CCI_REG8(0x05ac), 0x01 },
+	{ CCI_REG8(0x059a), 0x00 },
+	{ CCI_REG8(0x059b), 0x00 },
+	{ CCI_REG8(0x059c), 0x01 },
+	{ CCI_REG8(0x0598), 0x00 },
+	{ CCI_REG8(0x0597), 0x14 },
+	{ CCI_REG8(0x05ab), 0x09 },
+	{ CCI_REG8(0x05a4), 0x02 },
+	{ CCI_REG8(0x05a3), 0x05 },
+	{ CCI_REG8(0x05a0), 0xc2 },
+	{ CCI_REG8(0x0207), 0xc4 },
+
+	/* GAIN */
+	{ CCI_REG8(0x0208), 0x01 },
+	{ CCI_REG8(0x0209), 0x72 },
+	{ CCI_REG8(0x0204), 0x04 },
+	{ CCI_REG8(0x0205), 0x00 },
+
+	{ CCI_REG8(0x0040), 0x22 },
+	{ CCI_REG8(0x0041), 0x20 },
+	{ CCI_REG8(0x0043), 0x10 },
+	{ CCI_REG8(0x0044), 0x00 },
+	{ CCI_REG8(0x0046), 0x08 },
+	{ CCI_REG8(0x0047), 0xf0 },
+	{ CCI_REG8(0x0048), 0x0f },
+	{ CCI_REG8(0x004b), 0x0f },
+	{ CCI_REG8(0x004c), 0x00 },
+	{ CCI_REG8(0x0050), 0x5c },
+	{ CCI_REG8(0x0051), 0x44 },
+	{ CCI_REG8(0x005b), 0x03 },
+	{ CCI_REG8(0x00c0), 0x00 },
+	{ CCI_REG8(0x00c1), 0x80 },
+	{ CCI_REG8(0x00c2), 0x31 },
+	{ CCI_REG8(0x00c3), 0x00 },
+	{ CCI_REG8(0x0460), 0x04 },
+	{ CCI_REG8(0x0462), 0x08 },
+	{ CCI_REG8(0x0464), 0x0e },
+	{ CCI_REG8(0x0466), 0x0a },
+	{ CCI_REG8(0x0468), 0x12 },
+	{ CCI_REG8(0x046a), 0x12 },
+	{ CCI_REG8(0x046c), 0x10 },
+	{ CCI_REG8(0x046e), 0x0c },
+	{ CCI_REG8(0x0461), 0x03 },
+	{ CCI_REG8(0x0463), 0x03 },
+	{ CCI_REG8(0x0465), 0x03 },
+	{ CCI_REG8(0x0467), 0x03 },
+	{ CCI_REG8(0x0469), 0x04 },
+	{ CCI_REG8(0x046b), 0x04 },
+	{ CCI_REG8(0x046d), 0x04 },
+	{ CCI_REG8(0x046f), 0x04 },
+	{ CCI_REG8(0x0470), 0x04 },
+	{ CCI_REG8(0x0472), 0x10 },
+	{ CCI_REG8(0x0474), 0x26 },
+	{ CCI_REG8(0x0476), 0x38 },
+	{ CCI_REG8(0x0478), 0x20 },
+	{ CCI_REG8(0x047a), 0x30 },
+	{ CCI_REG8(0x047c), 0x38 },
+	{ CCI_REG8(0x047e), 0x60 },
+	{ CCI_REG8(0x0471), 0x05 },
+	{ CCI_REG8(0x0473), 0x05 },
+	{ CCI_REG8(0x0475), 0x05 },
+	{ CCI_REG8(0x0477), 0x05 },
+	{ CCI_REG8(0x0479), 0x04 },
+	{ CCI_REG8(0x047b), 0x04 },
+	{ CCI_REG8(0x047d), 0x04 },
+	{ CCI_REG8(0x047f), 0x04 },
+};
+
+static const struct gc08a3_link_freq_config gc08a3_link_freq_336m_configs = {
+	.reg_list = {
+		.num_of_regs = ARRAY_SIZE(mode_table_common),
+		.regs = mode_table_common,
+	}
+};
+
+static const struct gc08a3_link_freq_config gc08a3_link_freq_207m_configs = {
+	.reg_list = {
+		.num_of_regs = ARRAY_SIZE(mode_table_common),
+		.regs = mode_table_common,
+	}
+};
+
+struct gc08a3_mode {
+	u32 width;
+	u32 height;
+	const struct gc08a3_reg_list reg_list;
+
+	u32 hts; /* Horizontal timining size */
+	u32 vts_def; /* Default vertical timining size */
+	u32 vts_min; /* Min vertical timining size */
+	u32 max_framerate;
+	const struct gc08a3_link_freq_config *link_freq_configs;
+};
+
+/*
+ * Declare modes in order, from biggest
+ * to smallest height.
+ */
+static const struct gc08a3_mode gc08a3_modes[] = {
+	{
+		.width = GC08A3_NATIVE_WIDTH,
+		.height = GC08A3_NATIVE_HEIGHT,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_3264x2448),
+			.regs = mode_3264x2448,
+		},
+		.link_freq_configs = &gc08a3_link_freq_336m_configs,
+
+		.hts = GC08A3_HTS_30FPS,
+		.vts_def = GC08A3_VTS_30FPS,
+		.vts_min = GC08A3_VTS_30FPS_MIN,
+		.max_framerate = 300,
+	},
+	{
+		.width = 1920,
+		.height = 1080,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_1920x1080),
+			.regs = mode_1920x1080,
+		},
+		.link_freq_configs = &gc08a3_link_freq_207m_configs,
+
+		.hts = GC08A3_HTS_60FPS,
+		.vts_def = GC08A3_VTS_60FPS,
+		.vts_min = GC08A3_VTS_60FPS_MIN,
+		.max_framerate = 600,
+	},
+};
+
+static u64 to_pixel_rate(u32 f_index)
+{
+	u64 pixel_rate = link_freq_menu_items[f_index] * 2 * GC08A3_DATA_LANES;
+
+	do_div(pixel_rate, GC08A3_RGB_DEPTH);
+
+	return pixel_rate;
+}
+
+static int gc08a3_identify_module(struct gc08a3 *gc08a3)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
+	u64 val = 0;
+	int ret;
+
+	ret = cci_read(gc08a3->regmap, GC08A3_REG_CHIP_ID, &val, NULL);
+	if (ret) {
+		dev_err(&client->dev,
+			"failed to read chip id: 0x%x", GC08A3_CHIP_ID);
+		return ret;
+	}
+
+	if (val != GC08A3_CHIP_ID) {
+		dev_err(&client->dev, "chip id mismatch: 0x%x!=0x%llx",
+			GC08A3_CHIP_ID, val);
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static inline struct gc08a3 *to_gc08a3(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct gc08a3, sd);
+}
+
+static int gc08a3_power_on(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct gc08a3 *gc08a3 = to_gc08a3(sd);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(gc08a3_supply_name),
+				    gc08a3->supplies);
+	if (ret < 0) {
+		dev_err(gc08a3->dev, "failed to enable regulators: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(gc08a3->xclk);
+	if (ret < 0) {
+		regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
+				       gc08a3->supplies);
+		dev_err(gc08a3->dev, "clk prepare enable failed\n");
+		return ret;
+	}
+
+	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
+
+	gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
+	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
+
+	return 0;
+}
+
+static int gc08a3_power_off(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct gc08a3 *gc08a3 = to_gc08a3(sd);
+
+	clk_disable_unprepare(gc08a3->xclk);
+
+	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
+
+	gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);
+	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
+
+	regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
+			       gc08a3->supplies);
+	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
+
+	return 0;
+}
+
+static int gc08a3_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index > 0)
+		return -EINVAL;
+
+	code->code = GC08A3_MBUS_CODE;
+
+	return 0;
+}
+
+static int gc08a3_enum_frame_size(struct v4l2_subdev *subdev,
+				  struct v4l2_subdev_state *sd_state,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->code != GC08A3_MBUS_CODE)
+		return -EINVAL;
+
+	if (fse->index >= ARRAY_SIZE(gc08a3_modes))
+		return -EINVAL;
+
+	fse->min_width = gc08a3_modes[fse->index].width;
+	fse->max_width = gc08a3_modes[fse->index].width;
+	fse->min_height = gc08a3_modes[fse->index].height;
+	fse->max_height = gc08a3_modes[fse->index].height;
+
+	return 0;
+}
+
+static int gc08a3_update_cur_mode_controls(struct gc08a3 *gc08a3,
+					   const struct gc08a3_mode *mode)
+{
+	s64 exposure_max, h_blank;
+	int ret = 0;
+
+	ret = __v4l2_ctrl_modify_range(gc08a3->vblank,
+				       mode->vts_min - mode->height,
+				       GC08A3_VTS_MAX - mode->height, 1,
+				       mode->vts_def - mode->height);
+	if (ret)
+		dev_err(gc08a3->dev, "VB ctrl range update failed\n");
+
+	h_blank = mode->hts - mode->width;
+	ret = __v4l2_ctrl_modify_range(gc08a3->hblank, h_blank, h_blank, 1,
+				       h_blank);
+	if (ret)
+		dev_err(gc08a3->dev, "HB ctrl range update failed\n");
+
+	exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
+	ret = __v4l2_ctrl_modify_range(gc08a3->exposure, GC08A3_EXP_MIN,
+				       exposure_max, GC08A3_EXP_STEP,
+				       exposure_max);
+	if (ret)
+		dev_err(gc08a3->dev, "exposure ctrl range update failed\n");
+
+	return ret;
+}
+
+static void gc08a3_update_pad_format(struct gc08a3 *gc08a3,
+				     const struct gc08a3_mode *mode,
+				     struct v4l2_mbus_framefmt *fmt)
+{
+	fmt->width = mode->width;
+	fmt->height = mode->height;
+	fmt->code = GC08A3_MBUS_CODE;
+	fmt->field = V4L2_FIELD_NONE;
+	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);
+}
+
+static int gc08a3_set_format(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct gc08a3 *gc08a3 = to_gc08a3(sd);
+	struct v4l2_mbus_framefmt *mbus_fmt;
+	struct v4l2_rect *crop;
+	const struct gc08a3_mode *mode;
+
+	mode = v4l2_find_nearest_size(gc08a3_modes, ARRAY_SIZE(gc08a3_modes),
+				      width, height, fmt->format.width,
+				      fmt->format.height);
+
+	/*update crop info to subdev state*/
+	crop = v4l2_subdev_state_get_crop(state, 0);
+	crop->width = mode->width;
+	crop->height = mode->height;
+
+	/*update fmt info to subdev state*/
+	gc08a3_update_pad_format(gc08a3, mode, &fmt->format);
+	mbus_fmt = v4l2_subdev_state_get_format(state, 0);
+	*mbus_fmt = fmt->format;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+		return 0;
+
+	gc08a3->cur_mode = mode;
+	gc08a3_update_cur_mode_controls(gc08a3, mode);
+
+	return 0;
+}
+
+static int gc08a3_get_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *state,
+				struct v4l2_subdev_selection *sel)
+{
+	struct gc08a3 *gc08a3 = to_gc08a3(sd);
+
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP:
+		sel->r = *v4l2_subdev_state_get_crop(state, 0);
+		break;
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r.top = 0;
+		sel->r.left = 0;
+		sel->r.width = GC08A3_NATIVE_WIDTH;
+		sel->r.height = GC08A3_NATIVE_HEIGHT;
+		break;
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+		if (gc08a3->cur_mode->width == GC08A3_NATIVE_WIDTH) {
+			sel->r.top = 0;
+			sel->r.left = 0;
+			sel->r.width = gc08a3_modes[0].width;
+			sel->r.height = gc08a3_modes[0].height;
+		} else {
+			sel->r.top = 0;
+			sel->r.left = 0;
+			sel->r.width = gc08a3_modes[1].width;
+			sel->r.height = gc08a3_modes[1].height;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int gc08a3_init_state(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_format fmt = {
+		.which = V4L2_SUBDEV_FORMAT_TRY,
+		.pad = 0,
+		.format = {
+			.code = GC08A3_MBUS_CODE,
+			.width = gc08a3_modes[0].width,
+			.height = gc08a3_modes[0].height,
+		},
+	};
+
+	gc08a3_set_format(sd, state, &fmt);
+
+	return 0;
+}
+
+static int gc08a3_set_ctrl_hflip(struct gc08a3 *gc08a3, u32 ctrl_val)
+{
+	int ret;
+	u64 val;
+
+	ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
+	if (ret) {
+		dev_err(gc08a3->dev, "read hflip register failed: %d\n", ret);
+		return ret;
+	}
+
+	val = ctrl_val ? (val | GC08A3_FLIP_H_MASK) :
+			   (val & ~GC08A3_FLIP_H_MASK);
+	ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
+	if (ret < 0)
+		dev_err(gc08a3->dev, "Error %d\n", ret);
+
+	return ret;
+}
+
+static int gc08a3_set_ctrl_vflip(struct gc08a3 *gc08a3, u32 ctrl_val)
+{
+	int ret;
+	u64 val;
+
+	ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
+	if (ret) {
+		dev_err(gc08a3->dev, "read vflip register failed: %d\n", ret);
+		return ret;
+	}
+
+	val = ctrl_val ? (val | GC08A3_FLIP_V_MASK) :
+			   (val & ~GC08A3_FLIP_V_MASK);
+	ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
+	if (ret < 0)
+		dev_err(gc08a3->dev, "Error %d\n", ret);
+
+	return ret;
+}
+
+static int gc08a3_test_pattern(struct gc08a3 *gc08a3, u32 pattern_menu)
+{
+	u32 pattern = 0;
+	int ret;
+
+	if (pattern_menu) {
+		switch (pattern_menu) {
+		case 1:
+			pattern = 0x00;
+			break;
+		case 2:
+			pattern = 0x10;
+			break;
+		case 3:
+		case 4:
+		case 5:
+		case 6:
+		case 7:
+			pattern = pattern_menu + 1;
+			break;
+		}
+
+		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
+				GC08A3_TEST_PATTERN_EN, NULL);
+		if (ret)
+			return ret;
+
+		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_IDX,
+				pattern, NULL);
+
+	} else {
+		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
+				0x00, NULL);
+	}
+
+	return ret;
+}
+
+static int gc08a3_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct gc08a3 *gc08a3 =
+		container_of(ctrl->handler, struct gc08a3, ctrls);
+	int ret = 0;
+	s64 exposure_max;
+
+	if (ctrl->id == V4L2_CID_VBLANK) {
+		/* Update max exposure while meeting expected vblanking */
+		exposure_max = gc08a3->cur_mode->height + ctrl->val -
+			       GC08A3_EXP_MARGIN;
+		__v4l2_ctrl_modify_range(gc08a3->exposure,
+					 gc08a3->exposure->minimum,
+					 exposure_max, gc08a3->exposure->step,
+					 exposure_max);
+	}
+
+	/*
+	 * Applying V4L2 control value only happens
+	 * when power is on for streaming
+	 */
+	if (!pm_runtime_get_if_in_use(gc08a3->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		ret = cci_write(gc08a3->regmap, GC08A3_EXP_REG,
+				ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = cci_write(gc08a3->regmap, GC08A3_AGAIN_REG,
+				ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_VBLANK:
+		ret = cci_write(gc08a3->regmap, GC08A3_FRAME_LENGTH_REG,
+				gc08a3->cur_mode->height + ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_HFLIP:
+		ret = gc08a3_set_ctrl_hflip(gc08a3, ctrl->val);
+		break;
+
+	case V4L2_CID_VFLIP:
+		ret = gc08a3_set_ctrl_vflip(gc08a3, ctrl->val);
+		break;
+
+	case V4L2_CID_TEST_PATTERN:
+		ret = gc08a3_test_pattern(gc08a3, ctrl->val);
+		break;
+
+	default:
+		break;
+	}
+
+	pm_runtime_put(gc08a3->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops gc08a3_ctrl_ops = {
+	.s_ctrl = gc08a3_set_ctrl,
+};
+
+static int gc08a3_start_streaming(struct gc08a3 *gc08a3)
+{
+	const struct gc08a3_mode *mode;
+	const struct gc08a3_reg_list *reg_list;
+	const struct gc08a3_link_freq_config *link_freq_cfg;
+	int ret;
+
+	ret = pm_runtime_resume_and_get(gc08a3->dev);
+	if (ret < 0)
+		return ret;
+
+	link_freq_cfg = gc08a3->cur_mode->link_freq_configs;
+
+	reg_list = &link_freq_cfg->reg_list;
+	ret = cci_multi_reg_write(gc08a3->regmap,
+				  reg_list->regs, reg_list->num_of_regs, NULL);
+	if (ret) {
+		dev_err(gc08a3->dev, "could not sent common table %d\n", ret);
+		goto err_rpm_put;
+	}
+
+	mode = gc08a3->cur_mode;
+	reg_list = &mode->reg_list;
+	ret = cci_multi_reg_write(gc08a3->regmap,
+				  reg_list->regs, reg_list->num_of_regs, NULL);
+	if (ret < 0) {
+		dev_err(gc08a3->dev, "could not sent mode table %d\n", ret);
+		goto err_rpm_put;
+	}
+
+	ret = __v4l2_ctrl_handler_setup(&gc08a3->ctrls);
+	if (ret < 0) {
+		dev_err(gc08a3->dev, "could not sync v4l2 controls\n");
+		goto err_rpm_put;
+	}
+
+	ret = cci_write(gc08a3->regmap, GC08A3_STRAEMING_REG, 1, NULL);
+	if (ret < 0) {
+		dev_err(gc08a3->dev, "write STRAEMING_REG failed: %d\n", ret);
+		goto err_rpm_put;
+	}
+
+	return 0;
+
+err_rpm_put:
+	pm_runtime_put(gc08a3->dev);
+	return ret;
+}
+
+static int gc08a3_stop_streaming(struct gc08a3 *gc08a3)
+{
+	int ret;
+
+	ret = cci_write(gc08a3->regmap, GC08A3_STRAEMING_REG, 0, NULL);
+	if (ret < 0)
+		dev_err(gc08a3->dev, "could not sent stop streaming %d\n", ret);
+
+	pm_runtime_put(gc08a3->dev);
+	return ret;
+}
+
+static int gc08a3_s_stream(struct v4l2_subdev *subdev, int enable)
+{
+	struct gc08a3 *gc08a3 = to_gc08a3(subdev);
+	struct v4l2_subdev_state *state;
+	int ret;
+
+	state = v4l2_subdev_lock_and_get_active_state(subdev);
+
+	if (enable)
+		ret = gc08a3_start_streaming(gc08a3);
+	else
+		ret = gc08a3_stop_streaming(gc08a3);
+
+	gc08a3->streaming = enable;
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int
+gc08a3_enum_frame_interval(struct v4l2_subdev *subdev,
+			   struct v4l2_subdev_state *sd_state,
+			   struct v4l2_subdev_frame_interval_enum *fie)
+{
+	unsigned int index = fie->index;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(gc08a3_modes); i++) {
+		if (fie->width != gc08a3_modes[i].width ||
+		    fie->height != gc08a3_modes[i].height)
+			continue;
+
+		if (index-- == 0) {
+			fie->interval.numerator = 1;
+			fie->interval.denominator =
+				gc08a3_modes[i].max_framerate / 10;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static const struct v4l2_subdev_video_ops gc08a3_video_ops = {
+	.s_stream = gc08a3_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops gc08a3_subdev_pad_ops = {
+	.enum_mbus_code = gc08a3_enum_mbus_code,
+	.enum_frame_size = gc08a3_enum_frame_size,
+	.enum_frame_interval = gc08a3_enum_frame_interval,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = gc08a3_set_format,
+	.get_selection = gc08a3_get_selection,
+};
+
+static const struct v4l2_subdev_core_ops gc08a3_core_ops = {
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_ops gc08a3_subdev_ops = {
+	.core = &gc08a3_core_ops,
+	.video = &gc08a3_video_ops,
+	.pad = &gc08a3_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops gc08a3_internal_ops = {
+	.init_state = gc08a3_init_state,
+};
+
+static int gc08a3_get_regulators(struct device *dev, struct gc08a3 *gc08a3)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(gc08a3_supply_name); i++)
+		gc08a3->supplies[i].supply = gc08a3_supply_name[i];
+
+	return devm_regulator_bulk_get(dev, ARRAY_SIZE(gc08a3_supply_name),
+				       gc08a3->supplies);
+}
+
+static int gc08a3_parse_fwnode(struct device *dev, struct gc08a3 *gc08a3)
+{
+	struct fwnode_handle *endpoint;
+	struct v4l2_fwnode_endpoint bus_cfg = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY,
+	};
+	int ret;
+
+	endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
+	if (!endpoint) {
+		dev_err(dev, "endpoint node not found\n");
+		return -EINVAL;
+	}
+
+	ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
+	if (ret) {
+		dev_err(dev, "parsing endpoint node failed\n");
+		goto done;
+	}
+
+	ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
+				       bus_cfg.nr_of_link_frequencies,
+				       link_freq_menu_items,
+				       ARRAY_SIZE(link_freq_menu_items),
+				       &gc08a3->link_freq_bitmap);
+	if (ret)
+		goto done;
+
+done:
+	v4l2_fwnode_endpoint_free(&bus_cfg);
+	fwnode_handle_put(endpoint);
+	return ret;
+}
+
+static int gc08a3_init_controls(struct gc08a3 *gc08a3)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
+	const struct gc08a3_mode *mode = &gc08a3_modes[0];
+	const struct v4l2_ctrl_ops *ops = &gc08a3_ctrl_ops;
+	struct v4l2_fwnode_device_properties props;
+	struct v4l2_ctrl_handler *ctrl_hdlr;
+	s64 exposure_max, h_blank;
+	int ret;
+
+	ctrl_hdlr = &gc08a3->ctrls;
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
+	if (ret)
+		return ret;
+
+	gc08a3->link_freq =
+		v4l2_ctrl_new_int_menu(ctrl_hdlr,
+				       &gc08a3_ctrl_ops,
+				       V4L2_CID_LINK_FREQ,
+				       ARRAY_SIZE(link_freq_menu_items) - 1,
+				       0, link_freq_menu_items);
+	if (gc08a3->link_freq)
+		gc08a3->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	gc08a3->pixel_rate =
+		v4l2_ctrl_new_std(ctrl_hdlr,
+				  &gc08a3_ctrl_ops,
+				  V4L2_CID_PIXEL_RATE, 0,
+				  to_pixel_rate(GC08A3_LINK_FREQ_336MHZ_INDEX),
+				  1,
+				  to_pixel_rate(GC08A3_LINK_FREQ_336MHZ_INDEX));
+
+	gc08a3->vblank =
+		v4l2_ctrl_new_std(ctrl_hdlr,
+				  &gc08a3_ctrl_ops, V4L2_CID_VBLANK,
+				  mode->vts_min - mode->height,
+				  GC08A3_VTS_MAX - mode->height, 1,
+				  mode->vts_def - mode->height);
+
+	h_blank = mode->hts - mode->width;
+	gc08a3->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
+					   V4L2_CID_HBLANK, h_blank, h_blank, 1,
+					   h_blank);
+	if (gc08a3->hblank)
+		gc08a3->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
+			  V4L2_CID_ANALOGUE_GAIN, GC08A3_AGAIN_MIN,
+			  GC08A3_AGAIN_MAX, GC08A3_AGAIN_STEP,
+			  GC08A3_AGAIN_MIN);
+
+	exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
+	gc08a3->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
+					     V4L2_CID_EXPOSURE, GC08A3_EXP_MIN,
+					     exposure_max, GC08A3_EXP_STEP,
+					     exposure_max);
+
+	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &gc08a3_ctrl_ops,
+				     V4L2_CID_TEST_PATTERN,
+				     ARRAY_SIZE(gc08a3_test_pattern_menu) - 1,
+				     0, 0, gc08a3_test_pattern_menu);
+
+	v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops, V4L2_CID_HFLIP, 0,
+			  1, 1, 0);
+
+	v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops, V4L2_CID_VFLIP, 0,
+			  1, 1, 0);
+
+	/* register properties to fwnode (e.g. rotation, orientation) */
+	ret = v4l2_fwnode_device_parse(&client->dev, &props);
+	if (ret)
+		goto error_ctrls;
+
+	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, ops, &props);
+	if (ret)
+		goto error_ctrls;
+
+	if (ctrl_hdlr->error) {
+		ret = ctrl_hdlr->error;
+		goto error_ctrls;
+	}
+
+	gc08a3->sd.ctrl_handler = ctrl_hdlr;
+
+	return 0;
+
+error_ctrls:
+	v4l2_ctrl_handler_free(ctrl_hdlr);
+
+	return ret;
+}
+
+static int gc08a3_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct gc08a3 *gc08a3;
+	int ret;
+
+	gc08a3 = devm_kzalloc(dev, sizeof(*gc08a3), GFP_KERNEL);
+	if (!gc08a3)
+		return -ENOMEM;
+
+	gc08a3->dev = dev;
+
+	ret = gc08a3_parse_fwnode(dev, gc08a3);
+	if (ret)
+		return ret;
+
+	gc08a3->regmap = devm_cci_regmap_init_i2c(client, 16);
+	if (IS_ERR(gc08a3->regmap))
+		return dev_err_probe(dev, PTR_ERR(gc08a3->regmap),
+				     "failed to init CCI\n");
+
+	gc08a3->xclk = devm_clk_get(dev, NULL);
+	if (IS_ERR(gc08a3->xclk))
+		return dev_err_probe(dev, PTR_ERR(gc08a3->xclk),
+				     "failed to get xclk\n");
+
+	ret = clk_set_rate(gc08a3->xclk, GC08A3_DEFAULT_CLK_FREQ);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to set xclk frequency\n");
+
+	ret = gc08a3_get_regulators(dev, gc08a3);
+	if (ret < 0)
+		return dev_err_probe(dev, ret,
+				     "failed to get regulators\n");
+
+	gc08a3->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(gc08a3->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(gc08a3->reset_gpio),
+				     "failed to get gpio\n");
+
+	v4l2_i2c_subdev_init(&gc08a3->sd, client, &gc08a3_subdev_ops);
+	gc08a3->sd.internal_ops = &gc08a3_internal_ops;
+	gc08a3->cur_mode = &gc08a3_modes[0];
+
+	ret = gc08a3_power_on(gc08a3->dev);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to sensor power on\n");
+
+	ret = gc08a3_identify_module(gc08a3);
+	if (ret) {
+		dev_err(&client->dev, "failed to find sensor: %d\n", ret);
+		goto err_power_off;
+	}
+
+	ret = gc08a3_init_controls(gc08a3);
+	if (ret) {
+		dev_err(&client->dev, "failed to init controls: %d", ret);
+		goto err_power_off;
+	}
+
+	gc08a3->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+			    V4L2_SUBDEV_FL_HAS_EVENTS;
+	gc08a3->pad.flags = MEDIA_PAD_FL_SOURCE;
+	gc08a3->sd.dev = &client->dev;
+	gc08a3->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+	ret = media_entity_pads_init(&gc08a3->sd.entity, 1, &gc08a3->pad);
+	if (ret < 0) {
+		dev_err(dev, "could not register media entity\n");
+		goto err_v4l2_ctrl_handler_free;
+	}
+
+	gc08a3->sd.state_lock = gc08a3->ctrls.lock;
+	ret = v4l2_subdev_init_finalize(&gc08a3->sd);
+	if (ret < 0) {
+		dev_err(dev, "v4l2 subdev init error: %d\n", ret);
+		goto err_media_entity_cleanup;
+	}
+
+	pm_runtime_set_active(gc08a3->dev);
+	pm_runtime_enable(gc08a3->dev);
+	pm_runtime_idle(gc08a3->dev);
+
+	ret = v4l2_async_register_subdev_sensor(&gc08a3->sd);
+	if (ret < 0) {
+		dev_err(dev, "could not register v4l2 device\n");
+		goto err_rpm;
+	}
+
+	return 0;
+
+err_rpm:
+	pm_runtime_disable(gc08a3->dev);
+	v4l2_subdev_cleanup(&gc08a3->sd);
+
+err_media_entity_cleanup:
+	media_entity_cleanup(&gc08a3->sd.entity);
+
+err_v4l2_ctrl_handler_free:
+	v4l2_ctrl_handler_free(gc08a3->sd.ctrl_handler);
+
+err_power_off:
+	gc08a3_power_off(gc08a3->dev);
+
+	return ret;
+}
+
+static void gc08a3_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct gc08a3 *gc08a3 = to_gc08a3(sd);
+
+	v4l2_async_unregister_subdev(&gc08a3->sd);
+	v4l2_subdev_cleanup(sd);
+	media_entity_cleanup(&gc08a3->sd.entity);
+	v4l2_ctrl_handler_free(&gc08a3->ctrls);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		gc08a3_power_off(gc08a3->dev);
+	pm_runtime_set_suspended(&client->dev);
+}
+
+static const struct of_device_id gc08a3_of_match[] = {
+	{ .compatible = "galaxycore,gc08a3" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, gc08a3_of_match);
+
+static const struct dev_pm_ops gc08a3_pm_ops = {
+	SET_RUNTIME_PM_OPS(gc08a3_power_off, gc08a3_power_on, NULL)
+};
+
+static struct i2c_driver gc08a3_i2c_driver = {
+	.driver = {
+		.of_match_table = gc08a3_of_match,
+		.pm = &gc08a3_pm_ops,
+		.name  = "gc08a3",
+	},
+	.probe  = gc08a3_probe,
+	.remove = gc08a3_remove,
+};
+
+module_i2c_driver(gc08a3_i2c_driver);
+
+MODULE_DESCRIPTION("GalaxyCore gc08a3 Camera driver");
+MODULE_AUTHOR("Zhi Mao <zhi.mao at mediatek.com>");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From zhi.mao at mediatek.com  Sat Feb  3 22:15:36 2024
From: zhi.mao at mediatek.com (Zhi Mao)
Date: Sun, 4 Feb 2024 14:15:36 +0800
Subject: [PATCH v4 0/2] media: i2c: Add support for GC08A3 sensor
Message-ID: <20240204061538.2105-1-zhi.mao@mediatek.com>

This series adds YAML DT binding and V4L2 sub-device driver for Galaxycore's
GC08A3 8-megapixel 10-bit RAW CMOS 1/4" sensor, with an MIPI CSI-2 image data
interface and the I2C control bus.

The driver is implemented with V4L2 framework.
 - Async registered as a V4L2 sub-device.
 - As the first component of camera system including Seninf, ISP pipeline.
 - A media entity that provides one source pad in common.
 - Used in camera features on ChromeOS application.

Also this driver supports following features:
 - manual exposure and analog gain control support
 - vertical blanking control support
 - test pattern support
 - media controller support
 - runtime PM support
 - support resolution: 3264x2448 at 30fps, 1920x1080 at 60fps

Previous versions of this patch-set can be found here:
v3: https://lore.kernel.org/linux-media/20240109022715.30278-1-zhi.mao at mediatek.com/
v2: https://lore.kernel.org/linux-media/20231207052016.25954-1-zhi.mao at mediatek.com/
v1: https://lore.kernel.org/linux-media/20231123115104.32094-1-zhi.mao at mediatek.com/

This series is based on linux-next, tag: next-20240202
Changes in v4:
- dts-binding files?
-- rename the titile of patch "dt-bindings"
-- use "sensor at 31" as device node,according to Krzysztof's suggestion

- gc08a sensor driver?
-- use "ARRAY_SIZE(...)" directly in driver code, instead of macros
-- use pointer to corresponds an array entry of link_frequency
-- use variable of struc "mode" in function:gc08a3_get_selection()
-- declare ret as last in function:gc08a3_test_pattern()
-- fix some coding style by "checkpatch.pl --strict --max-line-length=80"
-- remove function:gc08a3_g_mbus_config()
-- use "v4l2_link_freq_to_bitmap()" API to parse driver-supported link frequencies
-- move runtime PM API before registering the sub-device in function:probe()

Thanks

Zhi Mao (2):
  media: dt-bindings: i2c: add GalaxyCore GC08A3 image sensor
  media: i2c: Add GC08A3 image sensor driver

 .../bindings/media/i2c/galaxycore,gc08a3.yaml |  112 ++
 drivers/media/i2c/Kconfig                     |   10 +
 drivers/media/i2c/Makefile                    |    1 +
 drivers/media/i2c/gc08a3.c                    | 1448 +++++++++++++++++
 4 files changed, 1571 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml
 create mode 100644 drivers/media/i2c/gc08a3.c

-- 
2.25.1






From Chunfeng.Yun at mediatek.com  Sat Feb  3 22:17:53 2024
From: Chunfeng.Yun at mediatek.com (=?utf-8?B?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?=)
Date: Sun, 4 Feb 2024 06:17:53 +0000
Subject: [PATCH 1/2] dt-bindings: phy: mediatek,xfi-tphy: add new bindings
In-Reply-To: <adf20671-2f1d-43ea-8584-df0c0b095865@linaro.org>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
	 <adf20671-2f1d-43ea-8584-df0c0b095865@linaro.org>
Message-ID: <031944545677573672000aee8f97149e56c15f83.camel@mediatek.com>

On Fri, 2024-02-02 at 09:21 +0100, Krzysztof Kozlowski wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  On 01/02/2024 22:52, Daniel Golle wrote:
> > Add bindings for the MediaTek XFI T-PHY Ethernet SerDes PHY found
> in the
> > MediaTek MT7988 SoC which can operate at various interfaces modes:
> > 
> > via USXGMII PCS:
> >  * USXGMII
> >  * 10GBase-R
> >  * 5GBase-R
> > 
> > via LynxI SGMII PCS:
> >  * 2500Base-X
> >  * 1000Base-X
> >  * Cisco SGMII (MAC side)
> > 
> > Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> > ---
> >  .../bindings/phy/mediatek,xfi-tphy.yaml       | 80
> +++++++++++++++++++
> >  1 file changed, 80 insertions(+)
> >  create mode 100644
> Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-
> tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-
> tphy.yaml
> > new file mode 100644
> > index 0000000000000..e897118dcf7e6
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
> > @@ -0,0 +1,80 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/phy/mediatek,xfi-tphy.yaml#
> 
> Please use compatible as filename. Your binding says only one is
> possible (const, not enum), so there is no reasoning for different
> filename.
> 
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MediaTek XFI T-PHY
> > +
> > +maintainers:
> > +  - Daniel Golle <daniel at makrotopia.org>
> > +
> > +description:
> > +  The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes
> > +  used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found
> in
> > +  MediaTek's 10G-capabale SoCs.
> > +
> > +properties:
> > +  $nodename:
> > +    pattern: "^phy@[0-9a-f]+$"
> 
> No need for nodename in individual bindings file.
> 
> > +
> > +  compatible:
> > +    const: mediatek,mt7988-xfi-tphy
Add a generic compatible "mediatek,xfi-tphy"?

Other socs also use this phy but not upstream.

> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    items:
> > +      - description: XFI PHY clock
> > +      - description: XFI register clock
> > +
> > +  clock-names:
> > +    items:
> > +      - const: xfipll
> > +      - const: topxtal
> > +
> > +  resets:
> > +    items:
> > +      - description: PEXTP reset
> > +
> > +  mediatek,usxgmii-performance-errata:
> > +    $ref: /schemas/types.yaml#/definitions/flag
> > +    description:
> > +      One instance of the T-PHY on MT7988 suffers from a
> performance
> > +      problem in 10GBase-R mode which needs a work-around in the
> driver.
> 
> Can you explain what is this issue and errata about (except
> performance)?
> 
> > +      The work-around is enabled using this flag.
> > +
> > +  "#phy-cells":
> > +    const: 0
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - clocks
> > +  - clock-names
> > +  - resets
> > +  - "#phy-cells"
> > +
> > +additionalProperties: false
> 
> 
> Best regards,
> Krzysztof
> 

From zhi.mao at mediatek.com  Sat Feb  3 22:34:41 2024
From: zhi.mao at mediatek.com (=?utf-8?B?WmhpIE1hbyAo5q+b5pm6KQ==?=)
Date: Sun, 4 Feb 2024 06:34:41 +0000
Subject: [PATCH v3 1/2] media: dt-bindings: media: i2c: Document GC08A3
 bindings
In-Reply-To: <7dbe0235-43f3-4060-b7ac-4c429c5aff4e@linaro.org>
References: <20240109022715.30278-1-zhi.mao@mediatek.com>
	 <20240109022715.30278-2-zhi.mao@mediatek.com>
	 <7dbe0235-43f3-4060-b7ac-4c429c5aff4e@linaro.org>
Message-ID: <1abe92bbe6e93f119a735e41dfdc0eac7f0a5080.camel@mediatek.com>

Hi Krzysztof,

Thanks for your review.


On Tue, 2024-01-09 at 10:24 +0100, Krzysztof Kozlowski wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  On 09/01/2024 03:27, Zhi Mao wrote:
> > Add YAML device tree binding for GC08A3 CMOS image sensor,
> > and the relevant MAINTAINERS entries.
> > 
> 
> A nit, subject: drop second/last, redundant "bindings". The
> "dt-bindings" prefix is already stating that these are bindings.
> See also:
> 
https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18
> 
> Subject: only one "media", so:
> media: dt-bindings: i2c: add GalaxyCore GC08A3 image sensor
> 
fixed in patch:v4.

> > Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> 
> ...
> 
> > +examples:
> > +  - |
> > +    #include <dt-bindings/gpio/gpio.h>
> > +
> > +    i2c {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        sensor0 at 31 {
> 
> sensor at 31
> 
> With above fixed:
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
fixed in patch:v4. 

> Before you reply, fix your email client. It's impossible to read your
> responses.
> 
> Best regards,
> Krzysztof
> 

From pratikmanvar09 at gmail.com  Sat Feb  3 22:36:26 2024
From: pratikmanvar09 at gmail.com (pratikmanvar09 at gmail.com)
Date: Sun,  4 Feb 2024 12:06:26 +0530
Subject: [PATCH v2] pwm: imx27: workaround of the pwm output bug
In-Reply-To: <20240103063454.1795-1-pratikmanvar09@gmail.com>
References: <9b5f9e1b-645a-4b44-a30c-fe93e7bf3532@gmx.net>
Message-ID: <65bf307d.170a0220.4d544.f32b@mx.google.com>

Hi Stefan,

Thanks for your review.
Please see my reply below inline.

>> From: Clark Wang <xiaoning.wang at nxp.com>
>>
>> This fixes the pwm output bug when decrease the duty cycle.
>> This is a limited workaround for the PWM IP issue TKT0577206.
>this looks like a patch from the vendor tree.

[Pratik]: Yes, this is the patch from NXP. Please see original link of the patch https://github.com/nxp-imx/linux-imx/commit/16181cc4eee61d87cbaba0e5a479990507816317

>Could you please provide a link to the origin or at least to the
>document which describes TKT0577206?
[Pratik]: Please refer i.MX8MN errata #ERR051198 in https://www.nxp.com/docs/en/errata/IMX8MN_0N14Y.pdf.

>As a i.MX6ULL user i couldn't find this issue in the chip errata. So are
>you sure that every PWM IP handled by this driver is affected?
[Pratik]: Yes, looks like this issue is on all platforms which uses this PWM IP.

>> Root cause:
>> When the SAR FIFO is empty, the new write value will be directly applied
>> to SAR even the current period is not over.
>> If the new SAR value is less than the old one, and the counter is
>> greater than the new SAR value, the current period will not filp the
>s/filp/flip/ ?
>> level. This will result in a pulse with a duty cycle of 100%.
>>
>> Workaround:
>> Add an old value SAR write before updating the new duty cycle to SAR.
>> This will keep the new value is always in a not empty fifo, and can be
>> wait to update after a period finished.
>>
>> Limitation:
>> This workaround can only solve this issue when the PWM period is longer
>> than 2us(or <500KHz).
>>
>> Reviewed-by: Jun Li <jun.li at nxp.com>
>> Signed-off-by: Clark Wang <xiaoning.wang at nxp.com>
>> Link: https://github.com/nxp-imx/linux-imx/commit/16181cc4eee61d87cbaba0e5a479990507816317
>> Tested-by: Pratik Manvar <pratik.manvar at ifm.com>
>> ---
>>   V1 -> V2: fix sparse warnings reported-by: kernel test robot <lkp at intel.com>
>>             Closes: https://lore.kernel.org/oe-kbuild-all/202312300907.RGtYsKxb-lkp at intel.com/
>>
>>   drivers/pwm/pwm-imx27.c | 67 ++++++++++++++++++++++++++++++++++++++---
>>   1 file changed, 62 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
>> index 7d9bc43f12b0..1e500a5bf564 100644
>> --- a/drivers/pwm/pwm-imx27.c
>> +++ b/drivers/pwm/pwm-imx27.c
>> @@ -21,11 +21,13 @@
>>   #include <linux/platform_device.h>
>>   #include <linux/pwm.h>
>>   #include <linux/slab.h>
>> +#include <linux/spinlock.h>
>>
>>   #define MX3_PWMCR			0x00    /* PWM Control Register */
>>   #define MX3_PWMSR			0x04    /* PWM Status Register */
>>   #define MX3_PWMSAR			0x0C    /* PWM Sample Register */
>>   #define MX3_PWMPR			0x10    /* PWM Period Register */
>> +#define MX3_PWMCNR			0x14    /* PWM Counter Register */
>>
>>   #define MX3_PWMCR_FWM			GENMASK(27, 26)
>>   #define MX3_PWMCR_STOPEN		BIT(25)
>> @@ -91,6 +93,7 @@ struct pwm_imx27_chip {
>>   	 * value to return in that case.
>>   	 */
>>   	unsigned int duty_cycle;
>> +	spinlock_t lock;
>>   };
>>
>>   #define to_pwm_imx27_chip(chip)	container_of(chip, struct pwm_imx27_chip, chip)
>> @@ -203,10 +206,10 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
>>
>>   	sr = readl(imx->mmio_base + MX3_PWMSR);
>>   	fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr);
>> -	if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) {
>> +	if (fifoav >= MX3_PWMSR_FIFOAV_3WORDS) {
>>   		period_ms = DIV_ROUND_UP_ULL(pwm_get_period(pwm),
>>   					 NSEC_PER_MSEC);
>> -		msleep(period_ms);
>> +		msleep(period_ms * (fifoav - 2));
>This touches a different workaround ("pwm: imx: Avoid sample FIFO
>overflow for i.MX PWM version2") without any explanation.
[Pratik]: Sure, I will look into this. Thanks!
>>
>>   		sr = readl(imx->mmio_base + MX3_PWMSR);
>>   		if (fifoav == FIELD_GET(MX3_PWMSR_FIFOAV, sr))
>> @@ -217,13 +220,15 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
>>   static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>>   			   const struct pwm_state *state)
>>   {
>> -	unsigned long period_cycles, duty_cycles, prescale;
>> +	unsigned long period_cycles, duty_cycles, prescale, counter_check, flags;
>>   	struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
>> +	void __iomem *reg_sar = imx->mmio_base + MX3_PWMSAR;
>> +	__force u32 sar_last, sar_current;
>>   	struct pwm_state cstate;
>>   	unsigned long long c;
>>   	unsigned long long clkrate;
>>   	int ret;
>> -	u32 cr;
>> +	u32 cr, timeout = 1000;
>>
>>   	pwm_get_state(pwm, &cstate);
>>
>> @@ -264,7 +269,57 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>>   		pwm_imx27_sw_reset(chip);
>>   	}
>>
>> -	writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
>> +	/*
>> +	 * This is a limited workaround. When the SAR FIFO is empty, the new
>> +	 * write value will be directly applied to SAR even the current period
>> +	 * is not over.
>> +	 * If the new SAR value is less than the old one, and the counter is
>> +	 * greater than the new SAR value, the current period will not filp
>The same typo as in the commit message.
>> +	 * the level. This will result in a pulse with a duty cycle of 100%.
>> +	 * So, writing the current value of the SAR to SAR here before updating
>> +	 * the new SAR value can avoid this issue.
>> +	 *
>> +	 * Add a spin lock and turn off the interrupt to ensure that the
>> +	 * real-time performance can be guaranteed as much as possible when
>> +	 * operating the following operations.
>> +	 *
>> +	 * 1. Add a threshold of 1.5us. If the time T between the read current
>> +	 * count value CNR and the end of the cycle is less than 1.5us, wait
>> +	 * for T to be longer than 1.5us before updating the SAR register.
>> +	 * This is to avoid the situation that when the first SAR is written,
>> +	 * the current cycle just ends and the SAR FIFO that just be written
>> +	 * is emptied again.
>> +	 *
>> +	 * 2. Use __raw_writel() to minimize the interval between two writes to
>> +	 * the SAR register to increase the fastest pwm frequency supported.
>> +	 *
>> +	 * When the PWM period is longer than 2us(or <500KHz), this workaround
>> +	 * can solve this problem.
>> +	 */
>> +	if (duty_cycles < imx->duty_cycle) {
>> +		c = clkrate * 1500;
>> +		do_div(c, NSEC_PER_SEC);
>> +		counter_check = c;
>> +		sar_last = (__force u32) cpu_to_le32(imx->duty_cycle);
>> +		sar_current = (__force u32) cpu_to_le32(duty_cycles);
>> +
>> +		spin_lock_irqsave(&imx->lock, flags);
>> +		if (state->period >= 2000) {
>> +			while ((period_cycles -
>> +				readl_relaxed(imx->mmio_base + MX3_PWMCNR))
>> +				< counter_check) {
>> +				if (!--timeout)
>> +					break;
>> +			};
>> +		}
>> +		if (!(MX3_PWMSR_FIFOAV &
>> +		      readl_relaxed(imx->mmio_base + MX3_PWMSR)))
>> +			__raw_writel(sar_last, reg_sar);
>> +		__raw_writel(sar_current, reg_sar);
>> +		spin_unlock_irqrestore(&imx->lock, flags);
>> +	} else
>> +		writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
>> +
>This is hard to believe that checkpatch.pl is fine with this patch.
>Please use it before submission.
[Pratik]: I used the checkpatch.pl in this patch and that runs without any warnings/errors!

>>   	writel(period_cycles, imx->mmio_base + MX3_PWMPR);
>>
>>   	/*
>> @@ -324,6 +379,8 @@ static int pwm_imx27_probe(struct platform_device *pdev)
>>   		return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_per),
>>   				     "failed to get peripheral clock\n");
>>
>> +	spin_lock_init(&imx->lock);
>> +	imx->duty_cycle = 0;
>This line looks unrelated and unnecessary.
[Pratik]: Right. I will remove this line in next patch version.

>Best regards
>>   	imx->chip.ops = &pwm_imx27_ops;
>>   	imx->chip.dev = &pdev->dev;
>>   	imx->chip.npwm = 1;

From Chunfeng.Yun at mediatek.com  Sat Feb  3 22:29:00 2024
From: Chunfeng.Yun at mediatek.com (=?utf-8?B?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?=)
Date: Sun, 4 Feb 2024 06:29:00 +0000
Subject: [PATCH 2/2] phy: add driver for MediaTek XFI T-PHY
In-Reply-To: <dd6b40ea1f7f8459a9a2cfe7fa60c1108332ade6.1706823233.git.daniel@makrotopia.org>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
	 <dd6b40ea1f7f8459a9a2cfe7fa60c1108332ade6.1706823233.git.daniel@makrotopia.org>
Message-ID: <a2641a62703bcd33115689544001cdbd26e84bbb.camel@mediatek.com>

On Thu, 2024-02-01 at 21:53 +0000, Daniel Golle wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  Add driver for MediaTek's XFI T-PHY, 10 Gigabit/s Ethernet SerDes
> PHY
> which can be found in the MT7988 SoC.
> 
> The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
> PHY_INTERFACE_MODE_* corresponding to the supported modes:
> 
>  * USXGMII                 \
>  * 10GBase-R                }- USXGMII PCS - XGDM  \
>  * 5GBase-R                /                        \
>                                                      }- Ethernet MAC
>  * 2500Base-X              \                        /
>  * 1000Base-X               }- LynxI PCS - GDM     /
>  * Cisco SGMII (MAC side)  /
> 
> In order to work-around a performance issue present on the first of
> two XFI T-PHYs present in MT7988, special tuning is applied which can
> be
> selected by adding the 'mediatek,usxgmii-performance-errata' property
> to
> the device tree node.
> 
> There is no documentation for most registers used for the
> analog/tuning part, however, most of the registers have been
> partially
> reverse-engineered from MediaTek's SDK implementation (an opaque
> sequence of 32-bit register writes) and descriptions for all relevant
> digital registers and bits such as resets and muxes have been
> supplied
> by MediaTek.
> 
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---
>  MAINTAINERS                             |   1 +
>  drivers/phy/mediatek/Kconfig            |  12 +
>  drivers/phy/mediatek/Makefile           |   1 +
>  drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 392
> ++++++++++++++++++++++++
>  4 files changed, 406 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 52769631bdb1a..52e4192470bd9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -13715,6 +13715,7 @@ L:netdev at vger.kernel.org
>  S:Maintained
>  F:drivers/net/phy/mediatek-ge-soc.c
>  F:drivers/net/phy/mediatek-ge.c
> +F:drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>  
>  MEDIATEK I2C CONTROLLER DRIVER
>  M:Qii Wang <qii.wang at mediatek.com>
> diff --git a/drivers/phy/mediatek/Kconfig
> b/drivers/phy/mediatek/Kconfig
> index 3125ecb5d119f..5161d130c7f8b 100644
> --- a/drivers/phy/mediatek/Kconfig
> +++ b/drivers/phy/mediatek/Kconfig
> @@ -13,6 +13,18 @@ config PHY_MTK_PCIE
>    callback for PCIe GEN3 port, it supports software efuse
>    initialization.
>  
> +config PHY_MTK_XFI_TPHY
> +tristate "MediaTek XFI T-PHY Driver"
> +depends on ARCH_MEDIATEK || COMPILE_TEST
> +depends on OF && OF_ADDRESS
> +depends on HAS_IOMEM
> +select GENERIC_PHY
> +help
> +  Say 'Y' here to add support for MediaTek XFI T-PHY driver.
> +  The driver provides access to the Ethernet SerDes T-PHY supporting
> +  1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
> +  via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
> +
>  config PHY_MTK_TPHY
>  tristate "MediaTek T-PHY Driver"
>  depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/phy/mediatek/Makefile
> b/drivers/phy/mediatek/Makefile
> index c9a50395533eb..fa7217178e7f4 100644
> --- a/drivers/phy/mediatek/Makefile
> +++ b/drivers/phy/mediatek/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)+= phy-mtk-pcie.o
>  obj-$(CONFIG_PHY_MTK_TPHY)+= phy-mtk-tphy.o
>  obj-$(CONFIG_PHY_MTK_UFS)+= phy-mtk-ufs.o
>  obj-$(CONFIG_PHY_MTK_XSPHY)+= phy-mtk-xsphy.o
> +obj-$(CONFIG_PHY_MTK_XFI_TPHY)+= phy-mtk-xfi-tphy.o
>  
>  phy-mtk-hdmi-drv-y:= phy-mtk-hdmi.o
>  phy-mtk-hdmi-drv-y+= phy-mtk-hdmi-mt2701.o
> diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> new file mode 100644
> index 0000000000000..d50e6320860e5
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> @@ -0,0 +1,392 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/* MediaTek 10GE SerDes PHY driver
> + *
> + * Copyright (c) 2024 Daniel Golle <daniel at makrotopia.org>
> + *                    Bc-bocun Chen <bc-bocun.chen at mediatek.com>
> + * based on mtk_usxgmii.c found in MediaTek's SDK released under
> GPL-2.0
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Henry Yen <henry.yen at mediatek.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/io.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
> +#include <linux/phy.h>
> +#include <linux/phy/phy.h>
> +
> +#define MTK_XFI_TPHY_NUM_CLOCKS2
> +
> +#define REG_DIG_GLB_700x0070
> +#define  XTP_PCS_RX_EQ_IN_PROGRESS(x)FIELD_PREP(GENMASK(25, 24),
> (x))
> +#define  XTP_PCS_MODE_MASKGENMASK(17, 16)
> +#define  XTP_PCS_MODE(x)FIELD_PREP(GENMASK(17, 16), (x))
> +#define  XTP_PCS_RST_BBIT(15)
> +#define  XTP_FRC_PCS_RST_BBIT(14)
> +#define  XTP_PCS_PWD_SYNC_MASKGENMASK(13, 12)
> +#define  XTP_PCS_PWD_SYNC(x)FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
> +#define  XTP_PCS_PWD_ASYNC_MASKGENMASK(11, 10)
> +#define  XTP_PCS_PWD_ASYNC(x)FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
> +#define  XTP_FRC_PCS_PWD_ASYNCBIT(8)
> +#define  XTP_PCS_UPDTBIT(4)
> +#define  XTP_PCS_IN_FR_RGBIT(0)
> +
> +#define REG_DIG_GLB_F40x00f4
> +#define  XFI_DPHY_PCS_SELBIT(0)
> +#define   XFI_DPHY_PCS_SEL_SGMIIFIELD_PREP(XFI_DPHY_PCS_SEL, 1)
> +#define   XFI_DPHY_PCS_SEL_USXGMIIFIELD_PREP(XFI_DPHY_PCS_SEL, 0)
> +#define  XFI_DPHY_AD_SGDT_FRC_ENBIT(5)
> +
> +#define REG_DIG_LN_TRX_400x3040
> +#define  XTP_LN_FRC_TX_DATA_ENBIT(29)
> +#define  XTP_LN_TX_DATA_ENBIT(28)
> +
> +#define REG_DIG_LN_TRX_B00x30b0
> +#define  XTP_LN_FRC_TX_MACCK_ENBIT(5)
> +#define  XTP_LN_TX_MACCK_ENBIT(4)
> +
> +#define REG_ANA_GLB_D00x90d0
> +#define  XTP_GLB_USXGMII_SEL_MASKGENMASK(3, 1)
> +#define  XTP_GLB_USXGMII_SEL(x)FIELD_PREP(GENMASK(3, 1), (x))
> +#define  XTP_GLB_USXGMII_ENBIT(0)
> +
> +struct mtk_xfi_tphy {
> +void __iomem*base;
> +struct device*dev;
> +struct reset_control*reset;
> +struct clk_bulk_dataclocks[MTK_XFI_TPHY_NUM_CLOCKS];
> +boolda_war;
> +};
> +
> +static void mtk_xfi_tphy_write(struct mtk_xfi_tphy *xfi_tphy, u16
> reg,
> +       u32 value)
> +{
> +iowrite32(value, xfi_tphy->base + reg);
> +}
> +
> +static void mtk_xfi_tphy_rmw(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
> +     u32 clr, u32 set)
> +{
> +u32 val;
> +
> +val = ioread32(xfi_tphy->base + reg);
> +val &= ~clr;
> +val |= set;
> +iowrite32(val, xfi_tphy->base + reg);
> +}
> +
> +static void mtk_xfi_tphy_set(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
> +     u32 set)
> +{
> +mtk_xfi_tphy_rmw(xfi_tphy, reg, 0, set);
> +}
> +
> +static void mtk_xfi_tphy_clear(struct mtk_xfi_tphy *xfi_tphy, u16
> reg,
> +       u32 clr)
> +{
> +mtk_xfi_tphy_rmw(xfi_tphy, reg, clr, 0);
> +}

Helpers defined in phy-mtk-io.h can be used instead?

> +
> +static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
> +       phy_interface_t interface)
> +{
> +bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
> +bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
> +      interface == PHY_INTERFACE_MODE_SGMII);
> +bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
> +       interface == PHY_INTERFACE_MODE_USXGMII);
> +bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
> +bool is_xgmii = (is_10g || is_5g);
> +
> +dev_dbg(xfi_tphy->dev, "setting up for mode %s\n",
> phy_modes(interface));
> +
> +/* Setup PLL setting */
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x9024, 0x100000, is_10g ? 0x0 :
> 0x100000);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x2020, 0x202000, is_5g ? 0x202000 :
> 0x0);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x2030, 0x500, is_1g ? 0x0 : 0x500);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x2040, 0x340000, is_1g ? 0x200000 :
> +     0x140000);
> +
> +/* Setup RXFE BW setting */
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50f0, 0xc10, is_1g ? 0x410 :
> +  is_5g ? 0x800 : 0x400);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
> +
> +/* Setup RX CDR setting */
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5070, 0x670000, is_5g ? 0x620000 :
> 0x50000);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5074, 0x180000, is_5g ? 0x180000 :
> 0x0);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5078, 0xf000400, is_5g ? 0x8000000 :
> +      0x7000400);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x507c, 0x5000500, is_5g ? 0x4000400 :
> +      0x1000100);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5080, 0x1410, is_1g ? 0x400 :
> +   is_5g ? 0x1010 : 0x0);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5084, 0x30300, is_1g ? 0x30300 :
> +    is_5g ? 0x30100 :
> +    0x100);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5088, 0x60200, is_1g ? 0x20200 :
> + is_5g ? 0x40000 :
> + 0x20000);
> +
> +/* Setting RXFE adaptation range setting */
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50a8, 0xee0000, is_5g ? 0x800000 :
> +     0x6e0000);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x6004, 0x190000, is_5g ? 0x0 :
> 0x190000);
> +if (is_10g)
> +mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x01423342);
> +else if (is_5g)
> +mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00a132a1);
> +else if (is_2p5g)
> +mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x009c329c);
> +else
> +mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00fa32fa);
Still have many magic number.

> +
> +/* Force SGDT_OUT off and select PCS */
> +mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_F4,
> + XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
> + XFI_DPHY_AD_SGDT_FRC_EN |
> + (is_xgmii ? XFI_DPHY_PCS_SEL_USXGMII :
> +     XFI_DPHY_PCS_SEL_SGMII));
> +
> +
> +/* Force GLB_CKDET_OUT */
> +mtk_xfi_tphy_set(xfi_tphy, 0x0030, 0xc00);
> +
> +/* Force AEQ on */
> +mtk_xfi_tphy_write(xfi_tphy, REG_DIG_GLB_70,
> +   XTP_PCS_RX_EQ_IN_PROGRESS(2) |
> +   XTP_PCS_PWD_SYNC(2) |
> +   XTP_PCS_PWD_ASYNC(2));
> +
> +usleep_range(1, 5);
> +
> +/* Setup TX DA default value */
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x30b0, 0x30, 0x20);
> +mtk_xfi_tphy_write(xfi_tphy, 0x3028, 0x00008a01);
> +mtk_xfi_tphy_write(xfi_tphy, 0x302c, 0x0000a884);
> +mtk_xfi_tphy_write(xfi_tphy, 0x3024, 0x00083002);
> +
> +/* Setup RG default value */
> +if (is_xgmii) {
> +mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00022220);
> +mtk_xfi_tphy_write(xfi_tphy, 0x5064, 0x0f020a01);
> +mtk_xfi_tphy_write(xfi_tphy, 0x50b4, 0x06100600);
> +if (interface == PHY_INTERFACE_MODE_USXGMII)
> +mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
> +else
> +mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x47684100);
> +} else {
> +mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00011110);
> +mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
> +}
> +
> +if (is_1g)
> +mtk_xfi_tphy_write(xfi_tphy, 0x3064, 0x0000c000);
> +
> +/* Setup RX EQ initial value */
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x3050, 0xa8000000,
> + (interface != PHY_INTERFACE_MODE_10GBASER) ?
> +  0xa8000000 : 0x0);
> +mtk_xfi_tphy_rmw(xfi_tphy, 0x3054, 0xaa,
> + (interface != PHY_INTERFACE_MODE_10GBASER) ?
> +  0xaa : 0x0);
> +
> +if (is_xgmii)
> +mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x00000f00);
> +else if (is_2p5g)
> +mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x22000f00);
> +else
> +mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x20200f00);
> +
> +if (interface == PHY_INTERFACE_MODE_10GBASER && xfi_tphy->da_war)
> +mtk_xfi_tphy_rmw(xfi_tphy, 0xa008, 0x10000, 0x10000);
> +
> +mtk_xfi_tphy_rmw(xfi_tphy, 0xa060, 0x50000, is_xgmii ? 0x40000 :
> +       0x50000);
> +
> +/* Setup PHYA speed */
> +mtk_xfi_tphy_rmw(xfi_tphy, REG_ANA_GLB_D0,
> + XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
> + is_10g ?  XTP_GLB_USXGMII_SEL(0) :
> + is_5g ?   XTP_GLB_USXGMII_SEL(1) :
> + is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
> +   XTP_GLB_USXGMII_SEL(3));
> +mtk_xfi_tphy_set(xfi_tphy, REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
> +
> +/* Release reset */
> +mtk_xfi_tphy_set(xfi_tphy, REG_DIG_GLB_70,
> + XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
> +usleep_range(150, 500);
> +
> +/* Switch to P0 */
> +mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
> + XTP_PCS_PWD_SYNC_MASK |
> + XTP_PCS_PWD_ASYNC_MASK,
> + XTP_FRC_PCS_PWD_ASYNC |
> + XTP_PCS_UPDT | XTP_PCS_IN_FR_RG);
> +usleep_range(1, 5);
> +
> +mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
> +usleep_range(15, 50);
> +
> +if (is_xgmii) {
> +/* Switch to Gen3 */
> +mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
> + XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
> + XTP_PCS_MODE(2) | XTP_PCS_UPDT);
> +} else {
> +/* Switch to Gen2 */
> +mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
> + XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
> + XTP_PCS_MODE(1) | XTP_PCS_UPDT);
> +}
> +usleep_range(1, 5);
> +
> +mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
> +
> +usleep_range(100, 500);
> +
> +/* Enable MAC CK */
> +mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
> +mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_F4,
> XFI_DPHY_AD_SGDT_FRC_EN);
> +
> +/* Enable TX data */
> +mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_40,
> + XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
> +usleep_range(400, 1000);
> +}
> +
> +static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode
> mode, int
> + submode)
> +{
> +struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> +
> +if (mode != PHY_MODE_ETHERNET)
> +return -EINVAL;
> +
> +switch (submode) {
> +case PHY_INTERFACE_MODE_1000BASEX:
> +case PHY_INTERFACE_MODE_2500BASEX:
> +case PHY_INTERFACE_MODE_SGMII:
> +case PHY_INTERFACE_MODE_5GBASER:
> +case PHY_INTERFACE_MODE_10GBASER:
> +case PHY_INTERFACE_MODE_USXGMII:
> +mtk_xfi_tphy_setup(xfi_tphy, submode);
> +return 0;
> +default:
> +return -EINVAL;
> +}
> +}
> +
> +static int mtk_xfi_tphy_reset(struct phy *phy)
> +{
> +struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> +
> +reset_control_assert(xfi_tphy->reset);
> +usleep_range(100, 500);
> +reset_control_deassert(xfi_tphy->reset);
> +usleep_range(1, 10);
> +
> +return 0;
> +}
> +
> +static int mtk_xfi_tphy_power_on(struct phy *phy)
> +{
> +struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> +
> +return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy-
> >clocks);
> +}
> +
> +static int mtk_xfi_tphy_power_off(struct phy *phy)
> +{
> +struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> +
> +clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy-
> >clocks);
> +
> +return 0;
> +}
> +
> +static const struct phy_ops mtk_xfi_tphy_ops = {
> +.power_on= mtk_xfi_tphy_power_on,
> +.power_off= mtk_xfi_tphy_power_off,
> +.set_mode= mtk_xfi_tphy_set_mode,
> +.reset= mtk_xfi_tphy_reset,
> +.owner= THIS_MODULE,
> +};
> +
> +static int mtk_xfi_tphy_probe(struct platform_device *pdev)
> +{
> +struct device_node *np = pdev->dev.of_node;
> +struct phy_provider *phy_provider;
> +struct mtk_xfi_tphy *xfi_tphy;
> +struct phy *phy;
> +
> +if (!np)
> +return -ENODEV;
> +
> +xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
> +if (!xfi_tphy)
> +return -ENOMEM;
> +
> +xfi_tphy->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
> +if (!xfi_tphy->base)
> +return -EIO;
> +
> +xfi_tphy->dev = &pdev->dev;
> +
> +xfi_tphy->clocks[0].id = "topxtal";
> +xfi_tphy->clocks[0].clk = devm_clk_get(&pdev->dev, xfi_tphy-
> >clocks[0].id);
> +if (IS_ERR(xfi_tphy->clocks[0].clk))
> +return PTR_ERR(xfi_tphy->clocks[0].clk);
> +
> +xfi_tphy->clocks[1].id = "xfipll";
> +xfi_tphy->clocks[1].clk = devm_clk_get(&pdev->dev, xfi_tphy-
> >clocks[1].id);
> +if (IS_ERR(xfi_tphy->clocks[1].clk))
> +return PTR_ERR(xfi_tphy->clocks[1].clk);
> +
> +xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev,
> NULL);
> +if (IS_ERR(xfi_tphy->reset))
> +return PTR_ERR(xfi_tphy->reset);
> +
> +xfi_tphy->da_war = of_property_read_bool(np,
> + "mediatek,usxgmii-performance-errata");
> +
> +phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
> +if (IS_ERR(phy))
> +return PTR_ERR(phy);
> +
> +phy_set_drvdata(phy, xfi_tphy);
> +
> +phy_provider = devm_of_phy_provider_register(&pdev->dev,
> +     of_phy_simple_xlate);
> +
> +return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id mtk_xfi_tphy_match[] = {
> +{ .compatible = "mediatek,mt7988-xfi-tphy", },
> +{ }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
> +
> +static struct platform_driver mtk_xfi_tphy_driver = {
> +.probe = mtk_xfi_tphy_probe,
> +.driver = {
> +.name = "mtk-xfi-tphy",
> +.of_match_table = mtk_xfi_tphy_match,
> +},
> +};
> +module_platform_driver(mtk_xfi_tphy_driver);
> +
> +MODULE_DESCRIPTION("MediaTek XFI T-PHY driver");
> +MODULE_AUTHOR("Daniel Golle <daniel at makrotopia.org>");
> +MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen at mediatek.com>");
> +MODULE_LICENSE("GPL");
> -- 
> 2.43.0

From zhi.mao at mediatek.com  Sat Feb  3 22:38:31 2024
From: zhi.mao at mediatek.com (=?utf-8?B?WmhpIE1hbyAo5q+b5pm6KQ==?=)
Date: Sun, 4 Feb 2024 06:38:31 +0000
Subject: [PATCH v3 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <ZZ0dcTEqxjYCohac@kekkonen.localdomain>
References: <20240109022715.30278-1-zhi.mao@mediatek.com>
	 <20240109022715.30278-3-zhi.mao@mediatek.com>
	 <ZZ0dcTEqxjYCohac@kekkonen.localdomain>
Message-ID: <ad6c915e474134d7861b00effacce7b1f0327899.camel@mediatek.com>

Hi Sakari

Thanks for your review.

On Tue, 2024-01-09 at 10:18 +0000, Sakari Ailus wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  Hi Zhi,
> 
> Thanks for the update.
> 
> On Tue, Jan 09, 2024 at 10:27:15AM +0800, Zhi Mao wrote:
> > Add a V4L2 sub-device driver for Galaxycore GC08A3 image sensor.
> > 
> > Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> > ---
> >  drivers/media/i2c/Kconfig  |   10 +
> >  drivers/media/i2c/Makefile |    1 +
> >  drivers/media/i2c/gc08a3.c | 1467
> ++++++++++++++++++++++++++++++++++++
> >  3 files changed, 1478 insertions(+)
> >  create mode 100644 drivers/media/i2c/gc08a3.c
> > 
> > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > index 78a87331686e..2e5bd751534b 100644
> > --- a/drivers/media/i2c/Kconfig
> > +++ b/drivers/media/i2c/Kconfig
> > @@ -70,6 +70,16 @@ config VIDEO_GC0308
> >    To compile this driver as a module, choose M here: the
> >    module will be called gc0308.
> >  
> > +config VIDEO_GC08A3
> > +tristate "GalaxyCore gc08a3 sensor support"
> > +select V4L2_CCI_I2C
> > +help
> > +  This is a Video4Linux2 sensor driver for the GalaxyCore gc08a3
> > +  camera.
> > +
> > +  To compile this driver as a module, choose M here: the
> > +  module will be called gc08a3.
> > +
> >  config VIDEO_GC2145
> >  select V4L2_CCI_I2C
> >  tristate "GalaxyCore GC2145 sensor support"
> > diff --git a/drivers/media/i2c/Makefile
> b/drivers/media/i2c/Makefile
> > index dfbe6448b549..b82e99ca7578 100644
> > --- a/drivers/media/i2c/Makefile
> > +++ b/drivers/media/i2c/Makefile
> > @@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
> >  obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
> >  obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
> >  obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
> > +obj-$(CONFIG_VIDEO_GC08A3) += gc08a3.o
> >  obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
> >  obj-$(CONFIG_VIDEO_HI556) += hi556.o
> >  obj-$(CONFIG_VIDEO_HI846) += hi846.o
> > diff --git a/drivers/media/i2c/gc08a3.c
> b/drivers/media/i2c/gc08a3.c
> > new file mode 100644
> > index 000000000000..eea304f0f84d
> > --- /dev/null
> > +++ b/drivers/media/i2c/gc08a3.c
> > @@ -0,0 +1,1467 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * gc08a3.c - gc08a3 sensor driver
> > + *
> > + * Copyright 2023 MediaTek
> > + *
> > + * Zhi Mao <zhi.mao at mediatek.com>
> > + */
> > +
> > +#include <asm/unaligned.h>
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/gpio/consumer.h>
> > +#include <linux/i2c.h>
> > +#include <linux/module.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/regulator/consumer.h>
> > +#include <media/media-entity.h>
> > +#include <media/v4l2-ctrls.h>
> > +#include <media/v4l2-fwnode.h>
> > +#include <media/v4l2-subdev.h>
> > +#include <media/v4l2-cci.h>
> > +#include <media/v4l2-event.h>
> > +
> > +#define GC08A3_REG_CHIP_ID CCI_REG16(0x03f0)
> > +#define GC08A3_CHIP_ID 0x08a3
> > +
> > +#define GC08A3_NATIVE_WIDTH 3264
> > +#define GC08A3_NATIVE_HEIGHT 2448
> > +
> > +#define GC08A3_REG_TEST_PATTERN_EN CCI_REG8(0x008c)
> > +#define GC08A3_REG_TEST_PATTERN_IDX CCI_REG8(0x008d)
> > +#define GC08A3_TEST_PATTERN_EN 0x01
> > +
> > +#define GC08A3_STRAEMING_REG CCI_REG8(0x0100)
> > +
> > +#define GC08A3_DEFAULT_CLK_FREQ 24000000
> > +#define GC08A3_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
> > +#define GC08A3_DATA_LANES 4
> > +
> > +/* for 1920*1080 */
> > +#define GC08A3_LINK_FREQ_207MHZ 207000000ULL
> > +/* for 3264*2448 */
> > +#define GC08A3_LINK_FREQ_336MHZ 336000000ULL
> > +
> > +#define GC08A3_RGB_DEPTH 10
> > +
> > +#define GC08A3_FRAME_LENGTH_REG CCI_REG16(0x0340)
> > +#define GC08A3_VTS_30FPS 2548
> > +#define GC08A3_VTS_30FPS_MIN 2548
> > +#define GC08A3_VTS_60FPS 1276
> > +#define GC08A3_VTS_60FPS_MIN 1276
> > +#define GC08A3_VTS_MAX 0xfff0
> > +
> > +#define GC08A3_HTS_30FPS 3640
> > +#define GC08A3_HTS_60FPS 3640
> > +
> > +#define GC08A3_EXP_REG CCI_REG16(0x0202)
> > +#define GC08A3_EXP_MARGIN 16
> > +#define GC08A3_EXP_MIN 4
> > +#define GC08A3_EXP_STEP 1
> > +
> > +#define GC08A3_FLIP_REG CCI_REG8(0x0101)
> > +#define GC08A3_FLIP_H_MASK 0x1
> > +#define GC08A3_FLIP_V_MASK 0x2
> > +
> > +#define GC08A3_AGAIN_REG CCI_REG16(0x0204)
> > +#define GC08A3_AGAIN_MIN 1024
> > +#define GC08A3_AGAIN_MAX (1024 * 16)
> > +#define GC08A3_AGAIN_STEP 1
> > +
> > +#define GC08A3_MIN_SLEEP_US  2000
> > +#define GC08A3_MAX_SLEEP_US  3000
> > +
> > +static const char *const gc08a3_test_pattern_menu[] = {
> > +"No Pattern", "Solid Black", "Colour Bar", "Solid White",
> > +"Solid Red", "Solid Green", "Solid Blue", "Solid Yellow",
> > +};
> > +
> > +enum {
> > +GC08A3_LINK_FREQ_336MHZ_INDEX,
> > +GC08A3_LINK_FREQ_207MHZ_INDEX,
> > +};
> > +
> > +static const s64 link_freq_menu_items[] = {
> > +GC08A3_LINK_FREQ_336MHZ,
> > +GC08A3_LINK_FREQ_207MHZ,
> > +};
> > +
> > +static const char *const gc08a3_supply_name[] = {
> > +"avdd",
> > +"dvdd",
> > +"dovdd",
> > +};
> > +
> > +#define GC08A3_NUM_SUPPLIES ARRAY_SIZE(gc08a3_supply_name)
> 
> Please don't add such macros, use ARRAY_SIZE(...) directly.
> 
fixed in patch:v4.

> > +
> > +struct gc08a3 {
> > +struct device *dev;
> > +struct v4l2_subdev sd;
> > +struct media_pad pad;
> > +struct i2c_client *client;
> > +
> > +struct clk *xclk;
> > +struct regulator_bulk_data supplies[GC08A3_NUM_SUPPLIES];
> > +struct gpio_desc *reset_gpio;
> > +
> > +struct v4l2_ctrl_handler ctrls;
> > +struct v4l2_ctrl *pixel_rate;
> > +struct v4l2_ctrl *link_freq;
> > +struct v4l2_ctrl *exposure;
> > +struct v4l2_ctrl *vblank;
> > +struct v4l2_ctrl *hblank;
> > +
> > +struct regmap *regmap;
> > +
> > +bool streaming;
> > +
> > +/* Current mode */
> > +const struct gc08a3_mode *cur_mode;
> > +};
> > +
> > +struct gc08a3_reg_list {
> > +u32 num_of_regs;
> > +const struct cci_reg_sequence *regs;
> > +};
> > +
> > +struct gc08a3_link_freq_config {
> > +const struct gc08a3_reg_list reg_list;
> > +};
> > +
> > +static const struct cci_reg_sequence mode_3264x2448[] = {
> > +/* system */
> > +{ CCI_REG8(0x0336), 0x70 },
> > +{ CCI_REG8(0x0383), 0xbb },
> > +{ CCI_REG8(0x0344), 0x00 },
> > +{ CCI_REG8(0x0345), 0x06 },
> > +{ CCI_REG8(0x0346), 0x00 },
> > +{ CCI_REG8(0x0347), 0x04 },
> > +{ CCI_REG8(0x0348), 0x0c },
> > +{ CCI_REG8(0x0349), 0xd0 },
> > +{ CCI_REG8(0x034a), 0x09 },
> > +{ CCI_REG8(0x034b), 0x9c },
> > +{ CCI_REG8(0x0202), 0x09 },
> > +{ CCI_REG8(0x0203), 0x04 },
> > +{ CCI_REG8(0x0340), 0x09 },
> > +{ CCI_REG8(0x0341), 0xf4 },
> > +{ CCI_REG8(0x0342), 0x07 },
> > +{ CCI_REG8(0x0343), 0x1c },
> > +
> > +{ CCI_REG8(0x0226), 0x00 },
> > +{ CCI_REG8(0x0227), 0x28 },
> > +{ CCI_REG8(0x0e38), 0x49 },
> > +{ CCI_REG8(0x0210), 0x13 },
> > +{ CCI_REG8(0x0218), 0x00 },
> > +{ CCI_REG8(0x0241), 0x88 },
> > +{ CCI_REG8(0x0392), 0x60 },
> > +
> > +/* ISP */
> > +{ CCI_REG8(0x00a2), 0x00 },
> > +{ CCI_REG8(0x00a3), 0x00 },
> > +{ CCI_REG8(0x00ab), 0x00 },
> > +{ CCI_REG8(0x00ac), 0x00 },
> > +
> > +/* GAIN */
> > +{ CCI_REG8(0x0204), 0x04 },
> > +{ CCI_REG8(0x0205), 0x00 },
> > +{ CCI_REG8(0x0050), 0x5c },
> > +{ CCI_REG8(0x0051), 0x44 },
> > +
> > +/* out window */
> > +{ CCI_REG8(0x009a), 0x66 },
> > +{ CCI_REG8(0x0351), 0x00 },
> > +{ CCI_REG8(0x0352), 0x06 },
> > +{ CCI_REG8(0x0353), 0x00 },
> > +{ CCI_REG8(0x0354), 0x08 },
> > +{ CCI_REG8(0x034c), 0x0c },
> > +{ CCI_REG8(0x034d), 0xc0 },
> > +{ CCI_REG8(0x034e), 0x09 },
> > +{ CCI_REG8(0x034f), 0x90 },
> > +
> > +/* MIPI */
> > +{ CCI_REG8(0x0114), 0x03 },
> > +{ CCI_REG8(0x0180), 0x65 },
> > +{ CCI_REG8(0x0181), 0xf0 },
> > +{ CCI_REG8(0x0185), 0x01 },
> > +{ CCI_REG8(0x0115), 0x30 },
> > +{ CCI_REG8(0x011b), 0x12 },
> > +{ CCI_REG8(0x011c), 0x12 },
> > +{ CCI_REG8(0x0121), 0x06 },
> > +{ CCI_REG8(0x0122), 0x06 },
> > +{ CCI_REG8(0x0123), 0x15 },
> > +{ CCI_REG8(0x0124), 0x01 },
> > +{ CCI_REG8(0x0125), 0x0b },
> > +{ CCI_REG8(0x0126), 0x08 },
> > +{ CCI_REG8(0x0129), 0x06 },
> > +{ CCI_REG8(0x012a), 0x08 },
> > +{ CCI_REG8(0x012b), 0x08 },
> > +
> > +{ CCI_REG8(0x0a73), 0x60 },
> > +{ CCI_REG8(0x0a70), 0x11 },
> > +{ CCI_REG8(0x0313), 0x80 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0a70), 0x00 },
> > +{ CCI_REG8(0x00a4), 0x80 },
> > +{ CCI_REG8(0x0316), 0x01 },
> > +{ CCI_REG8(0x0a67), 0x00 },
> > +{ CCI_REG8(0x0084), 0x10 },
> > +{ CCI_REG8(0x0102), 0x09 },
> > +};
> > +
> > +static const struct cci_reg_sequence mode_1920x1080[] = {
> > +/* system */
> > +{ CCI_REG8(0x0336), 0x45 },
> > +{ CCI_REG8(0x0383), 0x8b },
> > +{ CCI_REG8(0x0344), 0x02 },
> > +{ CCI_REG8(0x0345), 0xa6 },
> > +{ CCI_REG8(0x0346), 0x02 },
> > +{ CCI_REG8(0x0347), 0xb0 },
> > +{ CCI_REG8(0x0348), 0x07 },
> > +{ CCI_REG8(0x0349), 0x90 },
> > +{ CCI_REG8(0x034a), 0x04 },
> > +{ CCI_REG8(0x034b), 0x44 },
> > +{ CCI_REG8(0x0202), 0x03 },
> > +{ CCI_REG8(0x0203), 0x00 },
> > +{ CCI_REG8(0x0340), 0x04 },
> > +{ CCI_REG8(0x0341), 0xfc },
> > +{ CCI_REG8(0x0342), 0x07 },
> > +{ CCI_REG8(0x0343), 0x1c },
> > +{ CCI_REG8(0x0226), 0x00 },
> > +{ CCI_REG8(0x0227), 0x88 },
> > +{ CCI_REG8(0x0e38), 0x49 },
> > +{ CCI_REG8(0x0210), 0x13 },
> > +{ CCI_REG8(0x0218), 0x00 },
> > +{ CCI_REG8(0x0241), 0x88 },
> > +{ CCI_REG8(0x0392), 0x60 },
> > +
> > +/* ISP */
> > +{ CCI_REG8(0x00a2), 0xac },
> > +{ CCI_REG8(0x00a3), 0x02 },
> > +{ CCI_REG8(0x00ab), 0xa0 },
> > +{ CCI_REG8(0x00ac), 0x02 },
> > +
> > +/* GAIN */
> > +{ CCI_REG8(0x0204), 0x04 },
> > +{ CCI_REG8(0x0205), 0x00 },
> > +{ CCI_REG8(0x0050), 0x38 },
> > +{ CCI_REG8(0x0051), 0x20 },
> > +
> > +/* out window */
> > +{ CCI_REG8(0x009a), 0x66 },
> > +{ CCI_REG8(0x0351), 0x00 },
> > +{ CCI_REG8(0x0352), 0x06 },
> > +{ CCI_REG8(0x0353), 0x00 },
> > +{ CCI_REG8(0x0354), 0x08 },
> > +{ CCI_REG8(0x034c), 0x07 },
> > +{ CCI_REG8(0x034d), 0x80 },
> > +{ CCI_REG8(0x034e), 0x04 },
> > +{ CCI_REG8(0x034f), 0x38 },
> > +
> > +/* MIPI */
> > +{ CCI_REG8(0x0114), 0x03 },
> > +{ CCI_REG8(0x0180), 0x65 },
> > +{ CCI_REG8(0x0181), 0xf0 },
> > +{ CCI_REG8(0x0185), 0x01 },
> > +{ CCI_REG8(0x0115), 0x30 },
> > +{ CCI_REG8(0x011b), 0x12 },
> > +{ CCI_REG8(0x011c), 0x12 },
> > +{ CCI_REG8(0x0121), 0x02 },
> > +{ CCI_REG8(0x0122), 0x03 },
> > +{ CCI_REG8(0x0123), 0x0c },
> > +{ CCI_REG8(0x0124), 0x00 },
> > +{ CCI_REG8(0x0125), 0x09 },
> > +{ CCI_REG8(0x0126), 0x06 },
> > +{ CCI_REG8(0x0129), 0x04 },
> > +{ CCI_REG8(0x012a), 0x03 },
> > +{ CCI_REG8(0x012b), 0x06 },
> > +
> > +{ CCI_REG8(0x0a73), 0x60 },
> > +{ CCI_REG8(0x0a70), 0x11 },
> > +{ CCI_REG8(0x0313), 0x80 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0a70), 0x00 },
> > +{ CCI_REG8(0x00a4), 0x80 },
> > +{ CCI_REG8(0x0316), 0x01 },
> > +{ CCI_REG8(0x0a67), 0x00 },
> > +{ CCI_REG8(0x0084), 0x10 },
> > +{ CCI_REG8(0x0102), 0x09 },
> > +};
> > +
> > +static const struct cci_reg_sequence mode_table_common[] = {
> > +{ GC08A3_STRAEMING_REG, 0x00 },
> > +/* system */
> > +{ CCI_REG8(0x031c), 0x60 },
> > +{ CCI_REG8(0x0337), 0x04 },
> > +{ CCI_REG8(0x0335), 0x51 },
> > +{ CCI_REG8(0x0336), 0x70 },
> > +{ CCI_REG8(0x0383), 0xbb },
> > +{ CCI_REG8(0x031a), 0x00 },
> > +{ CCI_REG8(0x0321), 0x10 },
> > +{ CCI_REG8(0x0327), 0x03 },
> > +{ CCI_REG8(0x0325), 0x40 },
> > +{ CCI_REG8(0x0326), 0x23 },
> > +{ CCI_REG8(0x0314), 0x11 },
> > +{ CCI_REG8(0x0315), 0xd6 },
> > +{ CCI_REG8(0x0316), 0x01 },
> > +{ CCI_REG8(0x0334), 0x40 },
> > +{ CCI_REG8(0x0324), 0x42 },
> > +{ CCI_REG8(0x031c), 0x00 },
> > +{ CCI_REG8(0x031c), 0x9f },
> > +{ CCI_REG8(0x039a), 0x13 },
> > +{ CCI_REG8(0x0084), 0x30 },
> > +{ CCI_REG8(0x02b3), 0x08 },
> > +{ CCI_REG8(0x0057), 0x0c },
> > +{ CCI_REG8(0x05c3), 0x50 },
> > +{ CCI_REG8(0x0311), 0x90 },
> > +{ CCI_REG8(0x05a0), 0x02 },
> > +{ CCI_REG8(0x0074), 0x0a },
> > +{ CCI_REG8(0x0059), 0x11 },
> > +{ CCI_REG8(0x0070), 0x05 },
> > +{ CCI_REG8(0x0101), 0x00 },
> > +
> > +/* analog */
> > +{ CCI_REG8(0x0344), 0x00 },
> > +{ CCI_REG8(0x0345), 0x06 },
> > +{ CCI_REG8(0x0346), 0x00 },
> > +{ CCI_REG8(0x0347), 0x04 },
> > +{ CCI_REG8(0x0348), 0x0c },
> > +{ CCI_REG8(0x0349), 0xd0 },
> > +{ CCI_REG8(0x034a), 0x09 },
> > +{ CCI_REG8(0x034b), 0x9c },
> > +{ CCI_REG8(0x0202), 0x09 },
> > +{ CCI_REG8(0x0203), 0x04 },
> > +
> > +{ CCI_REG8(0x0219), 0x05 },
> > +{ CCI_REG8(0x0226), 0x00 },
> > +{ CCI_REG8(0x0227), 0x28 },
> > +{ CCI_REG8(0x0e0a), 0x00 },
> > +{ CCI_REG8(0x0e0b), 0x00 },
> > +{ CCI_REG8(0x0e24), 0x04 },
> > +{ CCI_REG8(0x0e25), 0x04 },
> > +{ CCI_REG8(0x0e26), 0x00 },
> > +{ CCI_REG8(0x0e27), 0x10 },
> > +{ CCI_REG8(0x0e01), 0x74 },
> > +{ CCI_REG8(0x0e03), 0x47 },
> > +{ CCI_REG8(0x0e04), 0x33 },
> > +{ CCI_REG8(0x0e05), 0x44 },
> > +{ CCI_REG8(0x0e06), 0x44 },
> > +{ CCI_REG8(0x0e0c), 0x1e },
> > +{ CCI_REG8(0x0e17), 0x3a },
> > +{ CCI_REG8(0x0e18), 0x3c },
> > +{ CCI_REG8(0x0e19), 0x40 },
> > +{ CCI_REG8(0x0e1a), 0x42 },
> > +{ CCI_REG8(0x0e28), 0x21 },
> > +{ CCI_REG8(0x0e2b), 0x68 },
> > +{ CCI_REG8(0x0e2c), 0x0d },
> > +{ CCI_REG8(0x0e2d), 0x08 },
> > +{ CCI_REG8(0x0e34), 0xf4 },
> > +{ CCI_REG8(0x0e35), 0x44 },
> > +{ CCI_REG8(0x0e36), 0x07 },
> > +{ CCI_REG8(0x0e38), 0x49 },
> > +{ CCI_REG8(0x0210), 0x13 },
> > +{ CCI_REG8(0x0218), 0x00 },
> > +{ CCI_REG8(0x0241), 0x88 },
> > +{ CCI_REG8(0x0e32), 0x00 },
> > +{ CCI_REG8(0x0e33), 0x18 },
> > +{ CCI_REG8(0x0e42), 0x03 },
> > +{ CCI_REG8(0x0e43), 0x80 },
> > +{ CCI_REG8(0x0e44), 0x04 },
> > +{ CCI_REG8(0x0e45), 0x00 },
> > +{ CCI_REG8(0x0e4f), 0x04 },
> > +{ CCI_REG8(0x057a), 0x20 },
> > +{ CCI_REG8(0x0381), 0x7c },
> > +{ CCI_REG8(0x0382), 0x9b },
> > +{ CCI_REG8(0x0384), 0xfb },
> > +{ CCI_REG8(0x0389), 0x38 },
> > +{ CCI_REG8(0x038a), 0x03 },
> > +{ CCI_REG8(0x0390), 0x6a },
> > +{ CCI_REG8(0x0391), 0x0b },
> > +{ CCI_REG8(0x0392), 0x60 },
> > +{ CCI_REG8(0x0393), 0xc1 },
> > +{ CCI_REG8(0x0396), 0xff },
> > +{ CCI_REG8(0x0398), 0x62 },
> > +
> > +/* cisctl reset */
> > +{ CCI_REG8(0x031c), 0x80 },
> > +{ CCI_REG8(0x03fe), 0x10 },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x031c), 0x9f },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x031c), 0x80 },
> > +{ CCI_REG8(0x03fe), 0x10 },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x031c), 0x9f },
> > +{ CCI_REG8(0x0360), 0x01 },
> > +{ CCI_REG8(0x0360), 0x00 },
> > +{ CCI_REG8(0x0316), 0x09 },
> > +{ CCI_REG8(0x0a67), 0x80 },
> > +{ CCI_REG8(0x0313), 0x00 },
> > +{ CCI_REG8(0x0a53), 0x0e },
> > +{ CCI_REG8(0x0a65), 0x17 },
> > +{ CCI_REG8(0x0a68), 0xa1 },
> > +{ CCI_REG8(0x0a58), 0x00 },
> > +{ CCI_REG8(0x0ace), 0x0c },
> > +{ CCI_REG8(0x00a4), 0x00 },
> > +{ CCI_REG8(0x00a5), 0x01 },
> > +{ CCI_REG8(0x00a7), 0x09 },
> > +{ CCI_REG8(0x00a8), 0x9c },
> > +{ CCI_REG8(0x00a9), 0x0c },
> > +{ CCI_REG8(0x00aa), 0xd0 },
> > +{ CCI_REG8(0x0a8a), 0x00 },
> > +{ CCI_REG8(0x0a8b), 0xe0 },
> > +{ CCI_REG8(0x0a8c), 0x13 },
> > +{ CCI_REG8(0x0a8d), 0xe8 },
> > +{ CCI_REG8(0x0a90), 0x0a },
> > +{ CCI_REG8(0x0a91), 0x10 },
> > +{ CCI_REG8(0x0a92), 0xf8 },
> > +{ CCI_REG8(0x0a71), 0xf2 },
> > +{ CCI_REG8(0x0a72), 0x12 },
> > +{ CCI_REG8(0x0a73), 0x64 },
> > +{ CCI_REG8(0x0a75), 0x41 },
> > +{ CCI_REG8(0x0a70), 0x07 },
> > +{ CCI_REG8(0x0313), 0x80 },
> > +
> > +/* ISP */
> > +{ CCI_REG8(0x00a0), 0x01 },
> > +{ CCI_REG8(0x0080), 0xd2 },
> > +{ CCI_REG8(0x0081), 0x3f },
> > +{ CCI_REG8(0x0087), 0x51 },
> > +{ CCI_REG8(0x0089), 0x03 },
> > +{ CCI_REG8(0x009b), 0x40 },
> > +{ CCI_REG8(0x05a0), 0x82 },
> > +{ CCI_REG8(0x05ac), 0x00 },
> > +{ CCI_REG8(0x05ad), 0x01 },
> > +{ CCI_REG8(0x05ae), 0x00 },
> > +{ CCI_REG8(0x0800), 0x0a },
> > +{ CCI_REG8(0x0801), 0x14 },
> > +{ CCI_REG8(0x0802), 0x28 },
> > +{ CCI_REG8(0x0803), 0x34 },
> > +{ CCI_REG8(0x0804), 0x0e },
> > +{ CCI_REG8(0x0805), 0x33 },
> > +{ CCI_REG8(0x0806), 0x03 },
> > +{ CCI_REG8(0x0807), 0x8a },
> > +{ CCI_REG8(0x0808), 0x50 },
> > +{ CCI_REG8(0x0809), 0x00 },
> > +{ CCI_REG8(0x080a), 0x34 },
> > +{ CCI_REG8(0x080b), 0x03 },
> > +{ CCI_REG8(0x080c), 0x26 },
> > +{ CCI_REG8(0x080d), 0x03 },
> > +{ CCI_REG8(0x080e), 0x18 },
> > +{ CCI_REG8(0x080f), 0x03 },
> > +{ CCI_REG8(0x0810), 0x10 },
> > +{ CCI_REG8(0x0811), 0x03 },
> > +{ CCI_REG8(0x0812), 0x00 },
> > +{ CCI_REG8(0x0813), 0x00 },
> > +{ CCI_REG8(0x0814), 0x01 },
> > +{ CCI_REG8(0x0815), 0x00 },
> > +{ CCI_REG8(0x0816), 0x01 },
> > +{ CCI_REG8(0x0817), 0x00 },
> > +{ CCI_REG8(0x0818), 0x00 },
> > +{ CCI_REG8(0x0819), 0x0a },
> > +{ CCI_REG8(0x081a), 0x01 },
> > +{ CCI_REG8(0x081b), 0x6c },
> > +{ CCI_REG8(0x081c), 0x00 },
> > +{ CCI_REG8(0x081d), 0x0b },
> > +{ CCI_REG8(0x081e), 0x02 },
> > +{ CCI_REG8(0x081f), 0x00 },
> > +{ CCI_REG8(0x0820), 0x00 },
> > +{ CCI_REG8(0x0821), 0x0c },
> > +{ CCI_REG8(0x0822), 0x02 },
> > +{ CCI_REG8(0x0823), 0xd9 },
> > +{ CCI_REG8(0x0824), 0x00 },
> > +{ CCI_REG8(0x0825), 0x0d },
> > +{ CCI_REG8(0x0826), 0x03 },
> > +{ CCI_REG8(0x0827), 0xf0 },
> > +{ CCI_REG8(0x0828), 0x00 },
> > +{ CCI_REG8(0x0829), 0x0e },
> > +{ CCI_REG8(0x082a), 0x05 },
> > +{ CCI_REG8(0x082b), 0x94 },
> > +{ CCI_REG8(0x082c), 0x09 },
> > +{ CCI_REG8(0x082d), 0x6e },
> > +{ CCI_REG8(0x082e), 0x07 },
> > +{ CCI_REG8(0x082f), 0xe6 },
> > +{ CCI_REG8(0x0830), 0x10 },
> > +{ CCI_REG8(0x0831), 0x0e },
> > +{ CCI_REG8(0x0832), 0x0b },
> > +{ CCI_REG8(0x0833), 0x2c },
> > +{ CCI_REG8(0x0834), 0x14 },
> > +{ CCI_REG8(0x0835), 0xae },
> > +{ CCI_REG8(0x0836), 0x0f },
> > +{ CCI_REG8(0x0837), 0xc4 },
> > +{ CCI_REG8(0x0838), 0x18 },
> > +{ CCI_REG8(0x0839), 0x0e },
> > +{ CCI_REG8(0x05ac), 0x01 },
> > +{ CCI_REG8(0x059a), 0x00 },
> > +{ CCI_REG8(0x059b), 0x00 },
> > +{ CCI_REG8(0x059c), 0x01 },
> > +{ CCI_REG8(0x0598), 0x00 },
> > +{ CCI_REG8(0x0597), 0x14 },
> > +{ CCI_REG8(0x05ab), 0x09 },
> > +{ CCI_REG8(0x05a4), 0x02 },
> > +{ CCI_REG8(0x05a3), 0x05 },
> > +{ CCI_REG8(0x05a0), 0xc2 },
> > +{ CCI_REG8(0x0207), 0xc4 },
> > +
> > +/* GAIN */
> > +{ CCI_REG8(0x0208), 0x01 },
> > +{ CCI_REG8(0x0209), 0x72 },
> > +{ CCI_REG8(0x0204), 0x04 },
> > +{ CCI_REG8(0x0205), 0x00 },
> > +
> > +{ CCI_REG8(0x0040), 0x22 },
> > +{ CCI_REG8(0x0041), 0x20 },
> > +{ CCI_REG8(0x0043), 0x10 },
> > +{ CCI_REG8(0x0044), 0x00 },
> > +{ CCI_REG8(0x0046), 0x08 },
> > +{ CCI_REG8(0x0047), 0xf0 },
> > +{ CCI_REG8(0x0048), 0x0f },
> > +{ CCI_REG8(0x004b), 0x0f },
> > +{ CCI_REG8(0x004c), 0x00 },
> > +{ CCI_REG8(0x0050), 0x5c },
> > +{ CCI_REG8(0x0051), 0x44 },
> > +{ CCI_REG8(0x005b), 0x03 },
> > +{ CCI_REG8(0x00c0), 0x00 },
> > +{ CCI_REG8(0x00c1), 0x80 },
> > +{ CCI_REG8(0x00c2), 0x31 },
> > +{ CCI_REG8(0x00c3), 0x00 },
> > +{ CCI_REG8(0x0460), 0x04 },
> > +{ CCI_REG8(0x0462), 0x08 },
> > +{ CCI_REG8(0x0464), 0x0e },
> > +{ CCI_REG8(0x0466), 0x0a },
> > +{ CCI_REG8(0x0468), 0x12 },
> > +{ CCI_REG8(0x046a), 0x12 },
> > +{ CCI_REG8(0x046c), 0x10 },
> > +{ CCI_REG8(0x046e), 0x0c },
> > +{ CCI_REG8(0x0461), 0x03 },
> > +{ CCI_REG8(0x0463), 0x03 },
> > +{ CCI_REG8(0x0465), 0x03 },
> > +{ CCI_REG8(0x0467), 0x03 },
> > +{ CCI_REG8(0x0469), 0x04 },
> > +{ CCI_REG8(0x046b), 0x04 },
> > +{ CCI_REG8(0x046d), 0x04 },
> > +{ CCI_REG8(0x046f), 0x04 },
> > +{ CCI_REG8(0x0470), 0x04 },
> > +{ CCI_REG8(0x0472), 0x10 },
> > +{ CCI_REG8(0x0474), 0x26 },
> > +{ CCI_REG8(0x0476), 0x38 },
> > +{ CCI_REG8(0x0478), 0x20 },
> > +{ CCI_REG8(0x047a), 0x30 },
> > +{ CCI_REG8(0x047c), 0x38 },
> > +{ CCI_REG8(0x047e), 0x60 },
> > +{ CCI_REG8(0x0471), 0x05 },
> > +{ CCI_REG8(0x0473), 0x05 },
> > +{ CCI_REG8(0x0475), 0x05 },
> > +{ CCI_REG8(0x0477), 0x05 },
> > +{ CCI_REG8(0x0479), 0x04 },
> > +{ CCI_REG8(0x047b), 0x04 },
> > +{ CCI_REG8(0x047d), 0x04 },
> > +{ CCI_REG8(0x047f), 0x04 },
> > +};
> > +
> > +static const struct gc08a3_link_freq_config link_freq_configs[] =
> {
> 
> Instead of adding such arrays and indices to them, please instead use
> a
> pointer to what corresponds an array entry here. It's easier and less
> error-prone.
> 
fixed in patch:v4.

> > +[GC08A3_LINK_FREQ_336MHZ_INDEX] = {
> > +.reg_list = {
> > +.num_of_regs = ARRAY_SIZE(mode_table_common),
> > +.regs = mode_table_common,
> > +}
> > +},
> > +[GC08A3_LINK_FREQ_207MHZ_INDEX] = {
> > +.reg_list = {
> > +.num_of_regs = ARRAY_SIZE(mode_table_common),
> > +.regs = mode_table_common,
> > +}
> > +},
> > +};
> > +
> > +struct gc08a3_mode {
> > +u32 width;
> > +u32 height;
> > +const struct gc08a3_reg_list reg_list;
> > +
> > +u32 hts; /* Horizontal timining size */
> > +u32 vts_def; /* Default vertical timining size */
> > +u32 vts_min; /* Min vertical timining size */
> > +u32 link_freq_index; /* Link frequency needed for this resolution
> */
> > +u32 max_framerate;
> > +};
> > +
> > +/*
> > + * Declare modes in order, from biggest
> > + * to smallest height.
> > + */
> > +static const struct gc08a3_mode gc08a3_modes[] = {
> > +{
> > +.width = GC08A3_NATIVE_WIDTH,
> > +.height = GC08A3_NATIVE_HEIGHT,
> > +.reg_list = {
> > +.num_of_regs = ARRAY_SIZE(mode_3264x2448),
> > +.regs = mode_3264x2448,
> > +},
> > +.link_freq_index = GC08A3_LINK_FREQ_336MHZ_INDEX,
> 
> This should be a reference to a data structure specific to 366 MHz
> link
> frequency.
> 
fixed in patch:v4.

> > +
> > +.hts = GC08A3_HTS_30FPS,
> > +.vts_def = GC08A3_VTS_30FPS,
> > +.vts_min = GC08A3_VTS_30FPS_MIN,
> > +.max_framerate = 300,
> > +},
> > +{
> > +.width = 1920,
> > +.height = 1080,
> > +.reg_list = {
> > +.num_of_regs = ARRAY_SIZE(mode_1920x1080),
> > +.regs = mode_1920x1080,
> > +},
> > +.link_freq_index = GC08A3_LINK_FREQ_207MHZ_INDEX,
> > +
> > +.hts = GC08A3_HTS_60FPS,
> > +.vts_def = GC08A3_VTS_60FPS,
> > +.vts_min = GC08A3_VTS_60FPS_MIN,
> > +.max_framerate = 600,
> > +},
> > +};
> > +
> > +static u64 to_pixel_rate(u32 f_index)
> > +{
> > +u64 pixel_rate = link_freq_menu_items[f_index] * 2 *
> GC08A3_DATA_LANES;
> > +
> > +do_div(pixel_rate, GC08A3_RGB_DEPTH);
> > +
> > +return pixel_rate;
> > +}
> > +
> > +static int gc08a3_identify_module(struct gc08a3 *gc08a3)
> > +{
> > +struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
> > +u64 val = 0;
> > +int ret;
> > +
> > +ret = cci_read(gc08a3->regmap, GC08A3_REG_CHIP_ID, &val, NULL);
> > +if (ret) {
> > +dev_err(&client->dev, "failed to read chip id: 0x%x",
> GC08A3_CHIP_ID);
> > +return ret;
> > +}
> > +
> > +if (val != GC08A3_CHIP_ID) {
> > +dev_err(&client->dev, "chip id mismatch: 0x%x!=0x%llx",
> > +GC08A3_CHIP_ID, val);
> > +return -ENXIO;
> > +}
> > +
> > +return 0;
> > +}
> > +
> > +static inline struct gc08a3 *to_gc08a3(struct v4l2_subdev *sd)
> > +{
> > +return container_of(sd, struct gc08a3, sd);
> > +}
> > +
> > +static int gc08a3_power_on(struct device *dev)
> > +{
> > +struct i2c_client *client = to_i2c_client(dev);
> > +struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +int ret;
> > +
> > +ret = regulator_bulk_enable(GC08A3_NUM_SUPPLIES, gc08a3-
> >supplies);
> > +if (ret < 0) {
> > +dev_err(gc08a3->dev, "failed to enable regulators: %d\n", ret);
> > +return ret;
> > +}
> > +
> > +ret = clk_prepare_enable(gc08a3->xclk);
> > +if (ret < 0) {
> > +regulator_bulk_disable(GC08A3_NUM_SUPPLIES, gc08a3->supplies);
> > +dev_err(gc08a3->dev, "clk prepare enable failed\n");
> > +return ret;
> > +}
> > +
> > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > +
> > +gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_power_off(struct device *dev)
> > +{
> > +struct i2c_client *client = to_i2c_client(dev);
> > +struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +
> > +clk_disable_unprepare(gc08a3->xclk);
> > +
> > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > +
> > +gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);
> > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > +
> > +regulator_bulk_disable(GC08A3_NUM_SUPPLIES, gc08a3->supplies);
> > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_enum_mbus_code(struct v4l2_subdev *sd,
> > + struct v4l2_subdev_state *sd_state,
> > + struct v4l2_subdev_mbus_code_enum *code)
> > +{
> > +if (code->index > 0)
> > +return -EINVAL;
> > +
> > +code->code = GC08A3_MBUS_CODE;
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_enum_frame_size(struct v4l2_subdev *subdev,
> > +  struct v4l2_subdev_state *sd_state,
> > +  struct v4l2_subdev_frame_size_enum *fse)
> > +{
> > +if (fse->code != GC08A3_MBUS_CODE)
> > +return -EINVAL;
> > +
> > +if (fse->index >= ARRAY_SIZE(gc08a3_modes))
> > +return -EINVAL;
> > +
> > +fse->min_width = gc08a3_modes[fse->index].width;
> > +fse->max_width = gc08a3_modes[fse->index].width;
> > +fse->min_height = gc08a3_modes[fse->index].height;
> > +fse->max_height = gc08a3_modes[fse->index].height;
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_update_cur_mode_controls(struct gc08a3 *gc08a3,
> const struct gc08a3_mode *mode)
> > +{
> > +s64 exposure_max, h_blank;
> > +int ret = 0;
> > +
> > +ret = __v4l2_ctrl_modify_range(gc08a3->vblank,
> > +       mode->vts_min - mode->height,
> > +       GC08A3_VTS_MAX - mode->height, 1,
> > +       mode->vts_def - mode->height);
> > +if (ret)
> > +dev_err(gc08a3->dev, "VB ctrl range update failed\n");
> > +
> > +h_blank = mode->hts - mode->width;
> > +ret = __v4l2_ctrl_modify_range(gc08a3->hblank, h_blank, h_blank,
> 1,
> > +       h_blank);
> > +if (ret)
> > +dev_err(gc08a3->dev, "HB ctrl range update failed\n");
> > +
> > +exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
> > +ret = __v4l2_ctrl_modify_range(gc08a3->exposure, GC08A3_EXP_MIN,
> > +       exposure_max, GC08A3_EXP_STEP,
> > +       exposure_max);
> > +if (ret)
> > +dev_err(gc08a3->dev, "exposure ctrl range update failed\n");
> > +
> > +return ret;
> > +}
> > +
> > +static void gc08a3_update_pad_format(struct gc08a3 *gc08a3,
> > +     const struct gc08a3_mode *mode,
> > +     struct v4l2_mbus_framefmt *fmt)
> > +{
> > +fmt->width = mode->width;
> > +fmt->height = mode->height;
> > +fmt->code = GC08A3_MBUS_CODE;
> > +fmt->field = V4L2_FIELD_NONE;
> > +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);
> > +}
> > +
> > +static int gc08a3_set_format(struct v4l2_subdev *sd,
> > +     struct v4l2_subdev_state *state,
> > +     struct v4l2_subdev_format *fmt)
> > +{
> > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +struct v4l2_mbus_framefmt *mbus_fmt;
> > +struct v4l2_rect *crop;
> > +const struct gc08a3_mode *mode;
> > +
> > +mode = v4l2_find_nearest_size(gc08a3_modes,
> ARRAY_SIZE(gc08a3_modes),
> > +      width, height, fmt->format.width,
> > +      fmt->format.height);
> > +
> > +/*update crop info to subdev state*/
> > +crop = v4l2_subdev_state_get_crop(state, 0);
> > +crop->width = mode->width;
> > +crop->height = mode->height;
> > +
> > +/*update fmt info to subdev state*/
> > +gc08a3_update_pad_format(gc08a3, mode, &fmt->format);
> > +mbus_fmt = v4l2_subdev_state_get_format(state, 0);
> > +*mbus_fmt = fmt->format;
> > +
> > +if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
> > +return 0;
> > +
> > +gc08a3->cur_mode = mode;
> > +gc08a3_update_cur_mode_controls(gc08a3, mode);
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_get_selection(struct v4l2_subdev *sd,
> > +struct v4l2_subdev_state *state,
> > +struct v4l2_subdev_selection *sel)
> > +{
> > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +
> > +switch (sel->target) {
> > +case V4L2_SEL_TGT_CROP:
> > +sel->r = *v4l2_subdev_state_get_crop(state, 0);
> > +break;
> > +case V4L2_SEL_TGT_CROP_BOUNDS:
> > +sel->r.top = 0;
> > +sel->r.left = 0;
> > +sel->r.width = GC08A3_NATIVE_WIDTH;
> > +sel->r.height = GC08A3_NATIVE_HEIGHT;
> > +break;
> > +case V4L2_SEL_TGT_CROP_DEFAULT:
> > +if (gc08a3->cur_mode->width == GC08A3_NATIVE_WIDTH) {
> > +sel->r.top = 0;
> > +sel->r.left = 0;
> > +sel->r.width = GC08A3_NATIVE_WIDTH;
> > +sel->r.height = GC08A3_NATIVE_HEIGHT;
> 
> Couuld you obtain these from the mode?
> 
fixed in patch:v4.

> > +} else {
> > +sel->r.top = 0;
> > +sel->r.left = 0;
> > +sel->r.width = 1920;
> > +sel->r.height = 1080;
> 
> This, too?
> 
fixed in patch:v4.

> > +}
> > +break;
> > +default:
> > +return -EINVAL;
> > +}
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_init_state(struct v4l2_subdev *sd,
> > +     struct v4l2_subdev_state *state)
> > +{
> > +struct v4l2_subdev_format fmt = {
> > +.which = V4L2_SUBDEV_FORMAT_TRY,
> > +.pad = 0,
> > +.format = {
> > +.code = GC08A3_MBUS_CODE,
> > +.width = gc08a3_modes[0].width,
> > +.height = gc08a3_modes[0].height,
> > +},
> > +};
> > +
> > +gc08a3_set_format(sd, state, &fmt);
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_set_ctrl_hflip(struct gc08a3 *gc08a3, u32
> ctrl_val)
> > +{
> > +int ret;
> > +u64 val;
> > +
> > +ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
> > +if (ret) {
> > +dev_err(gc08a3->dev, "read hflip register failed: %d\n", ret);
> > +return ret;
> > +}
> > +
> > +val = ctrl_val ? (val | GC08A3_FLIP_H_MASK) :
> > +   (val & ~GC08A3_FLIP_H_MASK);
> > +ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
> > +if (ret < 0)
> > +dev_err(gc08a3->dev, "Error %d\n", ret);
> > +
> > +return ret;
> > +}
> > +
> > +static int gc08a3_set_ctrl_vflip(struct gc08a3 *gc08a3, u32
> ctrl_val)
> > +{
> > +int ret;
> > +u64 val;
> > +
> > +ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
> > +if (ret) {
> > +dev_err(gc08a3->dev, "read vflip register failed: %d\n", ret);
> > +return ret;
> > +}
> > +
> > +val = ctrl_val ? (val | GC08A3_FLIP_V_MASK) :
> > +   (val & ~GC08A3_FLIP_V_MASK);
> > +ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
> > +if (ret < 0)
> > +dev_err(gc08a3->dev, "Error %d\n", ret);
> > +
> > +return ret;
> > +}
> > +
> > +static int gc08a3_test_pattern(struct gc08a3 *gc08a3, u32
> pattern_menu)
> > +{
> > +int ret = 0;
> 
> Please declare ret as last. Elsewhere, too.
> 
fixed in patch:v4.

> > +u32 pattern = 0;
> > +
> > +if (pattern_menu) {
> > +switch (pattern_menu) {
> > +case 1:
> > +pattern = 0x00;
> > +break;
> > +case 2:
> > +pattern = 0x10;
> > +break;
> > +case 3:
> > +case 4:
> > +case 5:
> > +case 6:
> > +case 7:
> > +pattern = pattern_menu + 1;
> > +break;
> > +}
> > +
> > +ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
> > +GC08A3_TEST_PATTERN_EN, NULL);
> > +if (ret) {
> > +dev_err(gc08a3->dev, "test pattern enable failed: %d\n", ret);
> 
> I'm not sure how useful these separate debug prints are. Error
> handling
> could be simplified without them nonetheless.
> 
fixed in patch:v4.

> > +return ret;
> > +}
> > +
> > +ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_IDX,
> > +pattern, NULL);
> > +if (ret < 0)
> > +dev_err(gc08a3->dev, "Error %d\n", ret);
> > +
> > +} else {
> > +ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
> > +0x00, NULL);
> > +if (ret < 0)
> > +dev_err(gc08a3->dev, "test pattern disable failed: %d\n", ret);
> > +}
> > +
> > +return ret;
> > +}
> > +
> > +static int gc08a3_set_ctrl(struct v4l2_ctrl *ctrl)
> > +{
> > +struct gc08a3 *gc08a3 =
> > +container_of(ctrl->handler, struct gc08a3, ctrls);
> > +int ret = 0;
> > +s64 exposure_max;
> > +
> > +if (ctrl->id == V4L2_CID_VBLANK) {
> > +/* Update max exposure while meeting expected vblanking */
> > +exposure_max = gc08a3->cur_mode->height + ctrl->val -
> > +       GC08A3_EXP_MARGIN;
> > +__v4l2_ctrl_modify_range(gc08a3->exposure,
> > + gc08a3->exposure->minimum,
> > + exposure_max, gc08a3->exposure->step,
> > + exposure_max);
> > +}
> > +
> > +/*
> > + * Applying V4L2 control value only happens
> > + * when power is on for streaming
> > + */
> > +if (!pm_runtime_get_if_in_use(gc08a3->dev))
> > +return 0;
> > +
> > +switch (ctrl->id) {
> > +case V4L2_CID_EXPOSURE:
> > +ret = cci_write(gc08a3->regmap, GC08A3_EXP_REG, ctrl->val, NULL);
> > +break;
> > +
> > +case V4L2_CID_ANALOGUE_GAIN:
> > +ret = cci_write(gc08a3->regmap, GC08A3_AGAIN_REG, ctrl->val,
> NULL);
> 
> Please run:
> 
> ./scripts/checkpatch.pl --strict --max-line-length=80
> 
fixed in patch:v4.

> > +break;
> > +
> > +case V4L2_CID_VBLANK:
> > +ret = cci_write(gc08a3->regmap, GC08A3_FRAME_LENGTH_REG,
> > +gc08a3->cur_mode->height + ctrl->val, NULL);
> > +break;
> > +
> > +case V4L2_CID_HFLIP:
> > +ret = gc08a3_set_ctrl_hflip(gc08a3, ctrl->val);
> > +break;
> > +
> > +case V4L2_CID_VFLIP:
> > +ret = gc08a3_set_ctrl_vflip(gc08a3, ctrl->val);
> > +break;
> > +
> > +case V4L2_CID_TEST_PATTERN:
> > +ret = gc08a3_test_pattern(gc08a3, ctrl->val);
> > +break;
> > +
> > +default:
> > +break;
> > +}
> > +
> > +pm_runtime_put(gc08a3->dev);
> > +
> > +return ret;
> > +}
> > +
> > +static const struct v4l2_ctrl_ops gc08a3_ctrl_ops = {
> > +.s_ctrl = gc08a3_set_ctrl,
> > +};
> > +
> > +static int gc08a3_start_streaming(struct gc08a3 *gc08a3)
> > +{
> > +const struct gc08a3_mode *mode;
> > +const struct gc08a3_reg_list *reg_list;
> > +int link_freq_index;
> > +int ret;
> > +
> > +ret = pm_runtime_resume_and_get(gc08a3->dev);
> > +if (ret < 0)
> > +return ret;
> > +
> > +link_freq_index = gc08a3->cur_mode->link_freq_index;
> > +
> > +reg_list = &link_freq_configs[link_freq_index].reg_list;
> > +ret = cci_multi_reg_write(gc08a3->regmap,
> > +  reg_list->regs, reg_list->num_of_regs, NULL);
> > +if (ret) {
> > +dev_err(gc08a3->dev, "could not sent common table %d\n", ret);
> > +goto err_rpm_put;
> > +}
> > +
> > +mode = gc08a3->cur_mode;
> > +reg_list = &mode->reg_list;
> > +ret = cci_multi_reg_write(gc08a3->regmap,
> > +  reg_list->regs, reg_list->num_of_regs, NULL);
> > +if (ret < 0) {
> > +dev_err(gc08a3->dev, "could not sent mode table %d\n", ret);
> > +goto err_rpm_put;
> > +}
> > +
> > +ret = __v4l2_ctrl_handler_setup(&gc08a3->ctrls);
> > +if (ret < 0) {
> > +dev_err(gc08a3->dev, "could not sync v4l2 controls\n");
> > +goto err_rpm_put;
> > +}
> > +
> > +ret = cci_write(gc08a3->regmap, GC08A3_STRAEMING_REG, 1, NULL);
> > +if (ret < 0) {
> > +dev_err(gc08a3->dev, "write STRAEMING_REG failed: %d\n", ret);
> > +goto err_rpm_put;
> > +}
> > +
> > +return 0;
> > +
> > +err_rpm_put:
> > +pm_runtime_put(gc08a3->dev);
> > +return ret;
> > +}
> > +
> > +static int gc08a3_stop_streaming(struct gc08a3 *gc08a3)
> > +{
> > +int ret;
> > +
> > +ret = cci_write(gc08a3->regmap, GC08A3_STRAEMING_REG, 0, NULL);
> > +if (ret < 0)
> > +dev_err(gc08a3->dev, "could not sent stop streaming %d\n", ret);
> > +
> > +pm_runtime_put(gc08a3->dev);
> > +return ret;
> > +}
> > +
> > +static int gc08a3_s_stream(struct v4l2_subdev *subdev, int enable)
> > +{
> > +struct gc08a3 *gc08a3 = to_gc08a3(subdev);
> > +struct v4l2_subdev_state *state;
> > +int ret;
> > +
> > +state = v4l2_subdev_lock_and_get_active_state(subdev);
> > +
> > +if (enable)
> > +ret = gc08a3_start_streaming(gc08a3);
> > +else
> > +ret = gc08a3_stop_streaming(gc08a3);
> > +
> > +gc08a3->streaming = enable;
> > +v4l2_subdev_unlock_state(state);
> > +
> > +return ret;
> > +}
> > +
> > +static int gc08a3_g_mbus_config(struct v4l2_subdev *sd, unsigned
> int pad,
> > +struct v4l2_mbus_config *config)
> > +{
> > +config->type = V4L2_MBUS_CSI2_DPHY;
> > +config->bus.mipi_csi2.num_data_lanes = 4;
> > +config->bus.mipi_csi2.flags = 0;
> > +return 0;
> 
> Please drop this, the downstream sub-device can obtain the
> configuration
> from the endpoint.
> 
fixed in patch:v4.

> > +}
> > +
> > +static int gc08a3_enum_frame_interval(struct v4l2_subdev *subdev,
> > +      struct v4l2_subdev_state *sd_state,
> > +      struct v4l2_subdev_frame_interval_enum *fie)
> > +{
> > +unsigned int index = fie->index;
> > +unsigned int i;
> > +
> > +for (i = 0; i < ARRAY_SIZE(gc08a3_modes); i++) {
> > +if (fie->width != gc08a3_modes[i].width ||
> > +    fie->height != gc08a3_modes[i].height)
> > +continue;
> > +
> > +if (index-- == 0) {
> > +fie->interval.numerator = 1;
> > +fie->interval.denominator = gc08a3_modes[i].max_framerate / 10;
> > +return 0;
> > +}
> > +}
> > +
> > +return -EINVAL;
> > +}
> > +
> > +static const struct v4l2_subdev_video_ops gc08a3_video_ops = {
> > +.s_stream = gc08a3_s_stream,
> > +};
> > +
> > +static const struct v4l2_subdev_pad_ops gc08a3_subdev_pad_ops = {
> > +.enum_mbus_code = gc08a3_enum_mbus_code,
> > +.enum_frame_size = gc08a3_enum_frame_size,
> > +.enum_frame_interval = gc08a3_enum_frame_interval,
> > +.get_fmt = v4l2_subdev_get_fmt,
> > +.set_fmt = gc08a3_set_format,
> > +.get_selection = gc08a3_get_selection,
> > +.get_mbus_config = gc08a3_g_mbus_config,
> > +};
> > +
> > +static const struct v4l2_subdev_core_ops gc08a3_core_ops = {
> > +.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> > +.unsubscribe_event = v4l2_event_subdev_unsubscribe,
> > +};
> > +
> > +static const struct v4l2_subdev_ops gc08a3_subdev_ops = {
> > +.core = &gc08a3_core_ops,
> > +.video = &gc08a3_video_ops,
> > +.pad = &gc08a3_subdev_pad_ops,
> > +};
> > +
> > +static const struct v4l2_subdev_internal_ops gc08a3_internal_ops =
> {
> > +.init_state = gc08a3_init_state,
> > +};
> > +
> > +static int gc08a3_get_regulators(struct device *dev, struct gc08a3
> *gc08a3)
> > +{
> > +unsigned int i;
> > +
> > +for (i = 0; i < GC08A3_NUM_SUPPLIES; i++)
> > +gc08a3->supplies[i].supply = gc08a3_supply_name[i];
> > +
> > +return devm_regulator_bulk_get(dev, GC08A3_NUM_SUPPLIES,
> > +       gc08a3->supplies);
> > +}
> > +
> > +static int gc08a3_parse_fwnode(struct device *dev)
> > +{
> > +struct fwnode_handle *endpoint;
> > +struct v4l2_fwnode_endpoint bus_cfg = {
> > +.bus_type = V4L2_MBUS_CSI2_DPHY,
> > +};
> > +unsigned int i, j;
> > +int ret;
> > +
> > +endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
> > +if (!endpoint) {
> > +dev_err(dev, "endpoint node not found\n");
> > +return -EINVAL;
> > +}
> > +
> > +ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
> > +if (ret) {
> > +dev_err(dev, "parsing endpoint node failed\n");
> > +goto done;
> > +}
> > +
> > +if (!bus_cfg.nr_of_link_frequencies) {
> > +dev_err(dev, "no link frequencies defined");
> > +ret = -EINVAL;
> > +goto done;
> > +}
> > +
> > +for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {
> > +for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
> > +if (link_freq_menu_items[i] ==
> > +    bus_cfg.link_frequencies[j])
> > +break;
> > +}
> > +
> > +if (j == bus_cfg.nr_of_link_frequencies) {
> > +dev_err(dev,
> > +"no link frequency %lld supported, please check DT",
> > +link_freq_menu_items[i]);
> > +ret = -EINVAL;
> > +goto done;
> > +}
> > +}
> 
> Please use v4l2_link_freq_to_bitmap() available here
> <URL:
> https://lore.kernel.org/linux-media/20240108151805.55584-2-sakari.ailus at linux.intel.com/T/#u>
> ;.
> We'll then merge both at the same time.
> 
fixed in patch:v4.

> > +
> > +done:
> > +v4l2_fwnode_endpoint_free(&bus_cfg);
> > +fwnode_handle_put(endpoint);
> > +return ret;
> > +}
> > +
> > +static int gc08a3_init_controls(struct gc08a3 *gc08a3)
> > +{
> > +struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
> > +const struct gc08a3_mode *mode = &gc08a3_modes[0];
> > +const struct v4l2_ctrl_ops *ops = &gc08a3_ctrl_ops;
> > +struct v4l2_fwnode_device_properties props;
> > +struct v4l2_ctrl_handler *ctrl_hdlr;
> > +s64 exposure_max, h_blank;
> > +int ret;
> > +
> > +ctrl_hdlr = &gc08a3->ctrls;
> > +ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
> > +if (ret)
> > +return ret;
> > +
> > +gc08a3->link_freq =
> > +v4l2_ctrl_new_int_menu(ctrl_hdlr,
> > +       &gc08a3_ctrl_ops,
> > +       V4L2_CID_LINK_FREQ,
> > +       ARRAY_SIZE(link_freq_menu_items) - 1,
> > +       0, link_freq_menu_items);
> > +if (gc08a3->link_freq)
> > +gc08a3->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > +gc08a3->pixel_rate =
> > +v4l2_ctrl_new_std(ctrl_hdlr,
> > +  &gc08a3_ctrl_ops,
> > +  V4L2_CID_PIXEL_RATE, 0,
> > +  to_pixel_rate(GC08A3_LINK_FREQ_336MHZ_INDEX), 1,
> > +  to_pixel_rate(GC08A3_LINK_FREQ_336MHZ_INDEX));
> > +
> > +gc08a3->vblank =
> > +v4l2_ctrl_new_std(ctrl_hdlr,
> > +  &gc08a3_ctrl_ops, V4L2_CID_VBLANK,
> > +  mode->vts_min - mode->height,
> > +  GC08A3_VTS_MAX - mode->height, 1,
> > +  mode->vts_def - mode->height);
> > +
> > +h_blank = mode->hts - mode->width;
> > +gc08a3->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
> > +   V4L2_CID_HBLANK, h_blank, h_blank, 1,
> > +   h_blank);
> > +if (gc08a3->hblank)
> > +gc08a3->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > +v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
> > +  V4L2_CID_ANALOGUE_GAIN, GC08A3_AGAIN_MIN,
> > +  GC08A3_AGAIN_MAX, GC08A3_AGAIN_STEP,
> > +  GC08A3_AGAIN_MIN);
> > +
> > +exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
> > +gc08a3->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
> > +     V4L2_CID_EXPOSURE, GC08A3_EXP_MIN,
> > +     exposure_max, GC08A3_EXP_STEP,
> > +     exposure_max);
> > +
> > +v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &gc08a3_ctrl_ops,
> > +     V4L2_CID_TEST_PATTERN,
> > +     ARRAY_SIZE(gc08a3_test_pattern_menu) - 1,
> > +     0, 0, gc08a3_test_pattern_menu);
> > +
> > +v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops, V4L2_CID_HFLIP, 0,
> > +  1, 1, 0);
> > +
> > +v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops, V4L2_CID_VFLIP, 0,
> > +  1, 1, 0);
> > +
> > +/* register properties to fwnode (e.g. rotation, orientation) */
> > +ret = v4l2_fwnode_device_parse(&client->dev, &props);
> > +if (ret)
> > +goto error_ctrls;
> > +
> > +ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, ops, &props);
> > +if (ret)
> > +goto error_ctrls;
> > +
> > +if (ctrl_hdlr->error) {
> > +ret = ctrl_hdlr->error;
> > +goto error_ctrls;
> > +}
> > +
> > +gc08a3->sd.ctrl_handler = ctrl_hdlr;
> > +
> > +return 0;
> > +
> > +error_ctrls:
> > +v4l2_ctrl_handler_free(ctrl_hdlr);
> > +
> > +return ret;
> > +}
> > +
> > +static int gc08a3_probe(struct i2c_client *client)
> > +{
> > +struct device *dev = &client->dev;
> > +struct gc08a3 *gc08a3;
> > +int ret;
> > +
> > +ret = gc08a3_parse_fwnode(dev);
> > +if (ret)
> > +return ret;
> > +
> > +gc08a3 = devm_kzalloc(dev, sizeof(*gc08a3), GFP_KERNEL);
> > +if (!gc08a3)
> > +return -ENOMEM;
> > +
> > +gc08a3->dev = dev;
> > +
> > +gc08a3->regmap = devm_cci_regmap_init_i2c(client, 16);
> > +if (IS_ERR(gc08a3->regmap))
> > +return dev_err_probe(dev, PTR_ERR(gc08a3->regmap),
> > +     "failed to init CCI\n");
> > +
> > +gc08a3->xclk = devm_clk_get(dev, NULL);
> > +if (IS_ERR(gc08a3->xclk))
> > +return dev_err_probe(dev, PTR_ERR(gc08a3->xclk),
> > +     "failed to get xclk\n");
> > +
> > +ret = clk_set_rate(gc08a3->xclk, GC08A3_DEFAULT_CLK_FREQ);
> > +if (ret)
> > +return dev_err_probe(dev, ret,
> > +     "failed to set xclk frequency\n");
> > +
> > +ret = gc08a3_get_regulators(dev, gc08a3);
> > +if (ret < 0)
> > +return dev_err_probe(dev, ret,
> > +     "failed to get regulators\n");
> > +
> > +gc08a3->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> > +if (IS_ERR(gc08a3->reset_gpio))
> > +return dev_err_probe(dev, PTR_ERR(gc08a3->reset_gpio),
> > +     "failed to get gpio\n");
> > +
> > +v4l2_i2c_subdev_init(&gc08a3->sd, client, &gc08a3_subdev_ops);
> > +gc08a3->sd.internal_ops = &gc08a3_internal_ops;
> > +gc08a3->cur_mode = &gc08a3_modes[0];
> > +
> > +ret = gc08a3_power_on(gc08a3->dev);
> > +if (ret)
> > +return dev_err_probe(dev, ret,
> > +     "failed to sensor power on\n");
> > +
> > +ret = gc08a3_identify_module(gc08a3);
> > +if (ret) {
> > +dev_err(&client->dev, "failed to find sensor: %d\n", ret);
> > +goto err_power_off;
> > +}
> > +
> > +ret = gc08a3_init_controls(gc08a3);
> > +if (ret) {
> > +dev_err(&client->dev, "failed to init controls: %d", ret);
> > +goto err_power_off;
> > +}
> > +
> > +gc08a3->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> V4L2_SUBDEV_FL_HAS_EVENTS;
> > +gc08a3->pad.flags = MEDIA_PAD_FL_SOURCE;
> > +gc08a3->sd.dev = &client->dev;
> > +gc08a3->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> > +
> > +ret = media_entity_pads_init(&gc08a3->sd.entity, 1, &gc08a3->pad);
> > +if (ret < 0) {
> > +dev_err(dev, "could not register media entity\n");
> > +goto err_v4l2_ctrl_handler_free;
> > +}
> > +
> > +gc08a3->sd.state_lock = gc08a3->ctrls.lock;
> > +ret = v4l2_subdev_init_finalize(&gc08a3->sd);
> > +if (ret < 0) {
> > +dev_err(dev, "v4l2 subdev init error: %d\n", ret);
> > +goto err_media_entity_cleanup;
> > +}
> > +
> > +ret = v4l2_async_register_subdev_sensor(&gc08a3->sd);
> > +if (ret < 0) {
> > +dev_err(dev, "could not register v4l2 device\n");
> > +goto err_subdev_cleanup;
> > +}
> > +
> > +pm_runtime_set_active(gc08a3->dev);
> > +pm_runtime_enable(gc08a3->dev);
> > +pm_runtime_idle(gc08a3->dev);
> 
> You'll need to enable runtime PM before registering the sub-device,
> please
> move all these calls before v4l2_async_register_subdev_sensor().
> 
fixed in patch:v4.

> > +
> > +return 0;
> > +
> > +err_subdev_cleanup:
> > +v4l2_subdev_cleanup(&gc08a3->sd);
> > +
> > +err_media_entity_cleanup:
> > +media_entity_cleanup(&gc08a3->sd.entity);
> > +
> > +err_v4l2_ctrl_handler_free:
> > +v4l2_ctrl_handler_free(gc08a3->sd.ctrl_handler);
> > +
> > +err_power_off:
> > +gc08a3_power_off(gc08a3->dev);
> > +
> > +return ret;
> > +}
> > +
> > +static void gc08a3_remove(struct i2c_client *client)
> > +{
> > +struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +
> > +v4l2_async_unregister_subdev(&gc08a3->sd);
> > +v4l2_subdev_cleanup(sd);
> > +media_entity_cleanup(&gc08a3->sd.entity);
> > +v4l2_ctrl_handler_free(&gc08a3->ctrls);
> > +
> > +pm_runtime_disable(&client->dev);
> > +if (!pm_runtime_status_suspended(&client->dev))
> > +gc08a3_power_off(gc08a3->dev);
> > +pm_runtime_set_suspended(&client->dev);
> > +}
> > +
> > +static const struct of_device_id gc08a3_of_match[] = {
> > +{ .compatible = "galaxycore,gc08a3" },
> > +{}
> > +};
> > +MODULE_DEVICE_TABLE(of, gc08a3_of_match);
> > +
> > +static const struct dev_pm_ops gc08a3_pm_ops = {
> > +SET_RUNTIME_PM_OPS(gc08a3_power_off, gc08a3_power_on, NULL)
> > +};
> > +
> > +static struct i2c_driver gc08a3_i2c_driver = {
> > +.driver = {
> > +.of_match_table = gc08a3_of_match,
> > +.pm = &gc08a3_pm_ops,
> > +.name  = "gc08a3",
> > +},
> > +.probe  = gc08a3_probe,
> > +.remove = gc08a3_remove,
> > +};
> > +
> > +module_i2c_driver(gc08a3_i2c_driver);
> > +
> > +MODULE_DESCRIPTION("GalaxyCore gc08a3 Camera driver");
> > +MODULE_AUTHOR("Zhi Mao <zhi.mao at mediatek.com>");
> > +MODULE_LICENSE("GPL");
> 
> -- 
> Regards,
> 
> Sakari Ailus

From xu.yang_2 at nxp.com  Sat Feb  3 22:42:40 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Sun, 4 Feb 2024 06:42:40 +0000
Subject: [EXT] Re: [PATCH v5 2/8] arm64: dts: imx8ulp: add usb nodes
In-Reply-To: <20240201225139.GA1885965-robh@kernel.org>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-2-xu.yang_2@nxp.com>
 <20240201225139.GA1885965-robh@kernel.org>
Message-ID: <DU2PR04MB8822A46A819FCB9B121E1D658C402@DU2PR04MB8822.eurprd04.prod.outlook.com>

Hi Rob,

> 
> On Wed, Jan 31, 2024 at 07:43:18PM +0800, Xu Yang wrote:
> > Add USB nodes on i.MX8ULP platform which has 2 USB controllers.
> >
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> >
> > ---
> > Changes in v2:
> >  - no changes
> > Changes in v3:
> >  - no changes
> > Changes in v4:
> >  - no changes
> > Changes in v5:
> >  - no changes
> > ---
> >  arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 64 ++++++++++++++++++++++
> >  1 file changed, 64 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
> > index c4a0082f30d3..ead1f57e08ef 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
> > @@ -28,6 +28,8 @@ aliases {
> >               serial1 = &lpuart5;
> >               serial2 = &lpuart6;
> >               serial3 = &lpuart7;
> > +             usbphy0 = &usbphy1;
> > +             usbphy1 = &usbphy2;
> 
> Drop these. We have no use for aliases to phys.

Checked again. Yes, these two alias can be removed.

> 
> >       };
> >
> >       cpus {
> > @@ -472,6 +474,68 @@ usdhc2: mmc at 298f0000 {
> >                               status = "disabled";
> >                       };
> >
> > +                     usbotg1: usb at 29900000 {
> > +                             compatible = "fsl,imx8ulp-usb", "fsl,imx7ulp-usb", "fsl,imx6ul-usb";
> > +                             reg = <0x29900000 0x200>;
> > +                             interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> > +                             clocks = <&pcc4 IMX8ULP_CLK_USB0>;
> > +                             power-domains = <&scmi_devpd IMX8ULP_PD_USB0>;
> > +                             phys = <&usbphy1>;
> > +                             fsl,usbmisc = <&usbmisc1 0>;
> > +                             ahb-burst-config = <0x0>;
> > +                             tx-burst-size-dword = <0x8>;
> > +                             rx-burst-size-dword = <0x8>;
> > +                             status = "disabled";
> > +                     };
> > +
> > +                     usbmisc1: usbmisc at 29900200 {
> > +                             compatible = "fsl,imx8ulp-usbmisc", "fsl,imx7d-usbmisc",
> > +                                             "fsl,imx6q-usbmisc";
> > +                             #index-cells = <1>;
> 
> Deprecated. Why are you using this?

Do you mean "#index-cells"? 
We are using it all the time.
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/tree/drivers/usb/chipidea/ci_hdrc_imx.c?h=linux-6.7.y#n137

Thanks,
Xu Yang


From xu.yang_2 at nxp.com  Sat Feb  3 22:56:38 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Sun, 4 Feb 2024 06:56:38 +0000
Subject: [EXT] Re: [PATCH v5 4/8] dt-bindings: usb: ci-hdrc-usb2: add
 restrictions for reg, interrupts, clock and clock-names properties
In-Reply-To: <bcd733ab-ea9e-4ef0-a521-8e6c2023479f@linaro.org>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-4-xu.yang_2@nxp.com>
 <a0134089-a283-488b-8d7f-3f59dd938b60@linaro.org>
 <DU2PR04MB88221602EB986D2C2A5BBF8D8C422@DU2PR04MB8822.eurprd04.prod.outlook.com>
 <bcd733ab-ea9e-4ef0-a521-8e6c2023479f@linaro.org>
Message-ID: <DU2PR04MB88221841F66A22B5A5DE47258C402@DU2PR04MB8822.eurprd04.prod.outlook.com>


> 
> On 02/02/2024 10:10, Xu Yang wrote:
> > Hi Krzysztof,
> >
> >>
> >> On 31/01/2024 12:43, Xu Yang wrote:
> >>> Change reg, interrupts, clock and clock-names as common properties and add
> >>> restrictions on them for different compatibles.
> >>>
> >>> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> >>>
> >>> ---
> >>> Changes in v4:
> >>>  - new patch since v3's discussion
> >>>  - split the reg, interrupts, clock and clock-names properties into
> >>>    common part and device-specific
> >>> Changes in v5:
> >>>  - keep common property unchanged
> >>>  - make if-then more readable
> >>>  - remove non imx part
> >>> ---
> >>>  .../devicetree/bindings/usb/ci-hdrc-usb2.yaml | 118 ++++++++++++++++++
> >>>  1 file changed, 118 insertions(+)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-
> >> hdrc-usb2.yaml
> >>> index 3b56e0edb1c6..6ad3582051b8 100644
> >>> --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> >>> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> >>> @@ -412,6 +412,124 @@ allOf:
> >>>          samsung,picophy-pre-emp-curr-control: false
> >>>          samsung,picophy-dc-vol-level-adjust: false
> >>>
> >>> +  - if:
> >>> +      properties:
> >>> +        compatible:
> >>> +          const: fsl,imx27-usb
> >>> +    then:
> >>> +      properties:
> >>> +        clocks:
> >>> +          minItems: 3
> >>> +          maxItems: 3
> >>> +        clock-names:
> >>> +          minItems: 3
> >>> +          maxItems: 3
> >>> +          items:
> >>> +            anyOf:
> >>> +              - const: ipg
> >>> +              - const: ahb
> >>> +              - const: per
> >>
> >> This would be just: enum: [ipg, ahb, per], but in both cases I question
> >> why the order should be flexible? Nothing in commit msg explains it.
> >
> > The driver will get the clock by clock-name, then the order should not
> > matter. However, these three clock-names should be present at the same
> > time. I should use enum then.
> 
> Forgot to answer to this.
> 
> Which driver? U-boot? OpenBSD? The one in my custom Linux kernel fork
> (open-source and published on github)? Did you check all of them?

I mean below driver in linux kernel tree.
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/tree/drivers/usb/chipidea/ci_hdrc_imx.c?h=linux-6.1.y#n191

Thanks,
Xu Yang

From andrea.porta at suse.com  Sat Feb  3 22:59:37 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:37 +0100
Subject: [PATCH 09/12] dmaengine: bcm2835: Add BCM2712 support
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <eb48d7f35252c7a2ddeda54fb326210c4bef8f18.1706948717.git.andrea.porta@suse.com>

From: Phil Elwell <phil at raspberrypi.com>

BCM2712 has 6 40-bit channels - DMA6 to DMA11. Add a new compatible
string to indicate that the current platform is BCM2712.

Signed-off-by: Phil Elwell <phil at raspberrypi.com>
---
 drivers/dma/bcm2835-dma.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 1b3f470274b2..548cf7343d83 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -326,6 +326,12 @@ static const struct bcm2835_dma_cfg_data bcm2711_dma_cfg = {
 	.dma_mask = DMA_BIT_MASK(36),
 };
 
+static const struct bcm2835_dma_cfg_data bcm2712_dma_cfg = {
+	.chan_40bit_mask = BIT(6) | BIT(7) | BIT(8) | BIT(9) |
+				 BIT(10) | BIT(11),
+	.dma_mask = DMA_BIT_MASK(40),
+};
+
 static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c)
 {
 	/* lite and normal channels have different max frame length */
@@ -1250,6 +1256,7 @@ EXPORT_SYMBOL(bcm2711_dma40_memcpy);
 static const struct of_device_id bcm2835_dma_of_match[] = {
 	{ .compatible = "brcm,bcm2835-dma", .data = &bcm2835_dma_cfg },
 	{ .compatible = "brcm,bcm2711-dma", .data = &bcm2711_dma_cfg },
+	{ .compatible = "brcm,bcm2712-dma", .data = &bcm2712_dma_cfg },
 	{},
 };
 MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match);
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:32 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:32 +0100
Subject: [PATCH 04/12] bcm2835-dma: Advertise the full DMA range
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <a56a6d24066a64598efe4343090e51e2223475b8.1706948717.git.andrea.porta@suse.com>

From: Phil Elwell <phil at raspberrypi.com>

Unless the DMA mask is set wider than 32 bits, DMA mapping will use a
bounce buffer.

Signed-off-by: Phil Elwell <phil at raspberrypi.com>
---
 drivers/dma/bcm2835-dma.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 36bad198b655..237dcdb8d726 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -39,6 +39,7 @@
 #define BCM2711_DMA_MEMCPY_CHAN 14
 
 struct bcm2835_dma_cfg_data {
+	u64	dma_mask;
 	u32	chan_40bit_mask;
 };
 
@@ -308,10 +309,12 @@ DEFINE_SPINLOCK(memcpy_lock);
 
 static const struct bcm2835_dma_cfg_data bcm2835_dma_cfg = {
 	.chan_40bit_mask = 0,
+	.dma_mask = DMA_BIT_MASK(32),
 };
 
 static const struct bcm2835_dma_cfg_data bcm2711_dma_cfg = {
 	.chan_40bit_mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
+	.dma_mask = DMA_BIT_MASK(36),
 };
 
 static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c)
@@ -1263,6 +1266,8 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
 
 static int bcm2835_dma_probe(struct platform_device *pdev)
 {
+	const struct bcm2835_dma_cfg_data *cfg_data;
+	const struct of_device_id *of_id;
 	struct bcm2835_dmadev *od;
 	struct resource *res;
 	void __iomem *base;
@@ -1272,13 +1277,20 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 	int irq_flags;
 	uint32_t chans_available;
 	char chan_name[BCM2835_DMA_CHAN_NAME_SIZE];
-	const struct of_device_id *of_id;
 	int chan_count, chan_start, chan_end;
 
+	of_id = of_match_node(bcm2835_dma_of_match, pdev->dev.of_node);
+	if (!of_id) {
+		dev_err(&pdev->dev, "Failed to match compatible string\n");
+		return -EINVAL;
+	}
+
+	cfg_data = of_id->data;
+
 	if (!pdev->dev.dma_mask)
 		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
 
-	rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+	rc = dma_set_mask_and_coherent(&pdev->dev, cfg_data->dma_mask);
 	if (rc) {
 		dev_err(&pdev->dev, "Unable to set DMA mask\n");
 		return rc;
@@ -1342,7 +1354,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	od->cfg_data = of_id->data;
+	od->cfg_data = cfg_data;
 
 	/* Request DMA channel mask from device tree */
 	if (of_property_read_u32(pdev->dev.of_node,
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:29 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:29 +0100
Subject: [PATCH 01/12] bcm2835-dma: Add support for per-channel flags
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <ca23b0dcaa1b5f70ff5f0a9bef4ed0a6ea014a48.1706948717.git.andrea.porta@suse.com>

From: Phil Elwell <phil at raspberrypi.org>

Add the ability to interpret the high bits of the dreq specifier as
flags to be included in the DMA_CS register. The motivation for this
change is the ability to set the DISDEBUG flag for SD card transfers
to avoid corruption when using the VPU debugger.

Signed-off-by: Phil Elwell <phil at raspberrypi.org>
Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 drivers/dma/bcm2835-dma.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 9d74fe97452e..2704e2578e23 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -137,6 +137,10 @@ struct bcm2835_desc {
 #define BCM2835_DMA_S_DREQ	BIT(10) /* enable SREQ for source */
 #define BCM2835_DMA_S_IGNORE	BIT(11) /* ignore source reads - read 0 */
 #define BCM2835_DMA_BURST_LENGTH(x) ((x & 15) << 12)
+#define BCM2835_DMA_CS_FLAGS(x) ((x) & (BCM2835_DMA_PRIORITY(15) | \
+				      BCM2835_DMA_PANIC_PRIORITY(15) | \
+				      BCM2835_DMA_WAIT_FOR_WRITES | \
+				      BCM2835_DMA_DIS_DEBUG))
 #define BCM2835_DMA_PER_MAP(x)	((x & 31) << 16) /* REQ source */
 #define BCM2835_DMA_WAIT(x)	((x & 31) << 21) /* add DMA-wait cycles */
 #define BCM2835_DMA_NO_WIDE_BURSTS BIT(26) /* no 2 beat write bursts */
@@ -450,7 +454,8 @@ static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
 	c->desc = d = to_bcm2835_dma_desc(&vd->tx);
 
 	writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
-	writel(BCM2835_DMA_ACTIVE, c->chan_base + BCM2835_DMA_CS);
+	writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
+	       c->chan_base + BCM2835_DMA_CS);
 }
 
 static irqreturn_t bcm2835_dma_callback(int irq, void *data)
@@ -477,7 +482,8 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
 	 * if this IRQ handler is threaded.) If the channel is finished, it
 	 * will remain idle despite the ACTIVE flag being set.
 	 */
-	writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE,
+	writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE |
+	       BCM2835_DMA_CS_FLAGS(c->dreq),
 	       c->chan_base + BCM2835_DMA_CS);
 
 	d = c->desc;
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:31 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:31 +0100
Subject: [PATCH 03/12] bcm2835-dma: Add NO_WAIT_RESP, DMA_WIDE_SOURCE and DMA_WIDE_DEST flag
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <14ef0b836c93152d5cb2229ba89ebab457db42cf.1706948717.git.andrea.porta@suse.com>

From: Phil Elwell <phil at raspberrypi.com>

Use bit 27 of the dreq value (the second cell of the DT DMA descriptor)
to request that the WAIT_RESP bit is not set.

Use (reserved) bits 24 and 25 of the dreq value
(the second cell of the DT DMA descriptor) to request
that wide source reads or wide dest writes are required

Cc: Dom Cobley <popcornmix at gmail.com>
Cc: Phil Elwell <phil at raspberrypi.com>
Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 drivers/dma/bcm2835-dma.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 11c6bf7d8a4b..36bad198b655 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -163,6 +163,21 @@ struct bcm2835_desc {
 #define BCM2835_DMA_WAIT(x)	((x & 31) << 21) /* add DMA-wait cycles */
 #define BCM2835_DMA_NO_WIDE_BURSTS BIT(26) /* no 2 beat write bursts */
 
+/* A fake bit to request that the driver doesn't set the WAIT_RESP bit. */
+#define BCM2835_DMA_NO_WAIT_RESP BIT(27)
+#define WAIT_RESP(x) (((x) & BCM2835_DMA_NO_WAIT_RESP) ? \
+		      0 : BCM2835_DMA_WAIT_RESP)
+
+/* A fake bit to request that the driver requires wide reads */
+#define BCM2835_DMA_WIDE_SOURCE BIT(24)
+#define WIDE_SOURCE(x) (((x) & BCM2835_DMA_WIDE_SOURCE) ? \
+		      BCM2835_DMA_S_WIDTH : 0)
+
+/* A fake bit to request that the driver requires wide writes */
+#define BCM2835_DMA_WIDE_DEST BIT(25)
+#define WIDE_DEST(x) (((x) & BCM2835_DMA_WIDE_DEST) ? \
+		      BCM2835_DMA_D_WIDTH : 0)
+
 /* debug register bits */
 #define BCM2835_DMA_DEBUG_LAST_NOT_SET_ERR	BIT(0)
 #define BCM2835_DMA_DEBUG_FIFO_ERR		BIT(1)
@@ -913,8 +928,9 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_memcpy(
 {
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
-	u32 info = BCM2835_DMA_D_INC | BCM2835_DMA_S_INC;
-	u32 extra = BCM2835_DMA_INT_EN | BCM2835_DMA_WAIT_RESP;
+	u32 info = BCM2835_DMA_D_INC | BCM2835_DMA_S_INC |
+		   WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) | WIDE_DEST(c->dreq);
+	u32 extra = BCM2835_DMA_INT_EN;
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 	size_t frames;
 
@@ -944,7 +960,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	dma_addr_t src = 0, dst = 0;
-	u32 info = BCM2835_DMA_WAIT_RESP;
+	u32 info = WAIT_RESP(c->dreq) |
+		   WIDE_SOURCE(c->dreq) | WIDE_DEST(c->dreq);
 	u32 extra = BCM2835_DMA_INT_EN;
 	size_t frames;
 
@@ -1006,7 +1023,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	dma_addr_t src, dst;
-	u32 info = BCM2835_DMA_WAIT_RESP;
+	u32 info = WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) | WIDE_DEST(c->dreq);
 	u32 extra = 0;
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 	size_t frames;
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:28 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:28 +0100
Subject: [PATCH 00/12] Add support for BCM2712 DMA engine
Message-ID: <cover.1706948717.git.andrea.porta@suse.com>

This patchset aims to update the dma engine for BCM* chipset with respect
to current advancements in downstream vendor tree. In particular:

* Added support for BCM2712 DMA.
* Extended DMA addressing to 40 bit. Since BCM2711 also supports 40 bit addressing,
it will also benefit from the update.
* Handled the devicetree node from vendor dts (e.g. "dma40").

The only difference between the application of this patch and the relative code
in vendor tree is the dropping of channel reservation for BCM2708 DMA legacy
driver, that seems to have not made its way to upstream anyway, and it's
probably used only from deprecated subsystems.

Compile tested and runtime tested on RPi4B only.

Dom Cobley (4):
  bcm2835-dma: Support dma flags for multi-beat burst
  bcm2835-dma: Need to keep PROT bits set in CS on 40bit controller
  dmaengine: bcm2835: Rename to_bcm2711_cbaddr to to_40bit_cbaddr
  bcm2835-dma: Fixes for dma_abort

Maxime Ripard (2):
  dmaengine: bcm2835: Use to_bcm2711_cbaddr where relevant
  dmaengine: bcm2835: Support DMA-Lite channels

Phil Elwell (6):
  bcm2835-dma: Add support for per-channel flags
  bcm2835-dma: Add proper 40-bit DMA support
  bcm2835-dma: Add NO_WAIT_RESP, DMA_WIDE_SOURCE and DMA_WIDE_DEST flag
  bcm2835-dma: Advertise the full DMA range
  bcm2835-dma: Derive slave DMA addresses correctly
  dmaengine: bcm2835: Add BCM2712 support

 drivers/dma/bcm2835-dma.c | 701 ++++++++++++++++++++++++++++++++------
 1 file changed, 588 insertions(+), 113 deletions(-)

-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:30 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:30 +0100
Subject: [PATCH 02/12] bcm2835-dma: Add proper 40-bit DMA support
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <eeb94204c30c2182f5ffd3ec083c04399ecdee32.1706948717.git.andrea.porta@suse.com>

From: Phil Elwell <phil at raspberrypi.org>

BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
to access the full 4GB of memory on a Pi 4.

Cc: Phil Elwell <phil at raspberrypi.org>
Cc: Maxime Ripard <maxime at cerno.tech>
Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 drivers/dma/bcm2835-dma.c | 601 ++++++++++++++++++++++++++++++++------
 1 file changed, 505 insertions(+), 96 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 2704e2578e23..11c6bf7d8a4b 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -36,6 +36,11 @@
 
 #define BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED 14
 #define BCM2835_DMA_CHAN_NAME_SIZE 8
+#define BCM2711_DMA_MEMCPY_CHAN 14
+
+struct bcm2835_dma_cfg_data {
+	u32	chan_40bit_mask;
+};
 
 /**
  * struct bcm2835_dmadev - BCM2835 DMA controller
@@ -48,6 +53,7 @@ struct bcm2835_dmadev {
 	struct dma_device ddev;
 	void __iomem *base;
 	dma_addr_t zero_page;
+	const struct bcm2835_dma_cfg_data *cfg_data;
 };
 
 struct bcm2835_dma_cb {
@@ -60,6 +66,17 @@ struct bcm2835_dma_cb {
 	uint32_t pad[2];
 };
 
+struct bcm2711_dma40_scb {
+	u32 ti;
+	u32 src;
+	u32 srci;
+	u32 dst;
+	u32 dsti;
+	u32 len;
+	u32 next_cb;
+	u32 rsvd;
+};
+
 struct bcm2835_cb_entry {
 	struct bcm2835_dma_cb *cb;
 	dma_addr_t paddr;
@@ -80,6 +97,7 @@ struct bcm2835_chan {
 	unsigned int irq_flags;
 
 	bool is_lite_channel;
+	bool is_40bit_channel;
 };
 
 struct bcm2835_desc {
@@ -169,13 +187,118 @@ struct bcm2835_desc {
 #define BCM2835_DMA_DATA_TYPE_S128	16
 
 /* Valid only for channels 0 - 14, 15 has its own base address */
-#define BCM2835_DMA_CHAN(n)	((n) << 8) /* Base address */
+#define BCM2835_DMA_CHAN_SIZE	0x100
+#define BCM2835_DMA_CHAN(n)	((n) * BCM2835_DMA_CHAN_SIZE) /* Base address */
 #define BCM2835_DMA_CHANIO(base, n) ((base) + BCM2835_DMA_CHAN(n))
 
 /* the max dma length for different channels */
 #define MAX_DMA_LEN SZ_1G
 #define MAX_LITE_DMA_LEN (SZ_64K - 4)
 
+/* 40-bit DMA support */
+#define BCM2711_DMA40_CS	0x00
+#define BCM2711_DMA40_CB	0x04
+#define BCM2711_DMA40_DEBUG	0x0c
+#define BCM2711_DMA40_TI	0x10
+#define BCM2711_DMA40_SRC	0x14
+#define BCM2711_DMA40_SRCI	0x18
+#define BCM2711_DMA40_DEST	0x1c
+#define BCM2711_DMA40_DESTI	0x20
+#define BCM2711_DMA40_LEN	0x24
+#define BCM2711_DMA40_NEXT_CB	0x28
+#define BCM2711_DMA40_DEBUG2	0x2c
+
+#define BCM2711_DMA40_ACTIVE		BIT(0)
+#define BCM2711_DMA40_END		BIT(1)
+#define BCM2711_DMA40_INT		BIT(2)
+#define BCM2711_DMA40_DREQ		BIT(3)  /* DREQ state */
+#define BCM2711_DMA40_RD_PAUSED		BIT(4)  /* Reading is paused */
+#define BCM2711_DMA40_WR_PAUSED		BIT(5)  /* Writing is paused */
+#define BCM2711_DMA40_DREQ_PAUSED	BIT(6)  /* Is paused by DREQ flow control */
+#define BCM2711_DMA40_WAITING_FOR_WRITES BIT(7)  /* Waiting for last write */
+#define BCM2711_DMA40_ERR		BIT(10)
+#define BCM2711_DMA40_QOS(x)		(((x) & 0x1f) << 16)
+#define BCM2711_DMA40_PANIC_QOS(x)	(((x) & 0x1f) << 20)
+#define BCM2711_DMA40_WAIT_FOR_WRITES	BIT(28)
+#define BCM2711_DMA40_DISDEBUG		BIT(29)
+#define BCM2711_DMA40_ABORT		BIT(30)
+#define BCM2711_DMA40_HALT		BIT(31)
+#define BCM2711_DMA40_CS_FLAGS(x) ((x) & (BCM2711_DMA40_QOS(15) | \
+					BCM2711_DMA40_PANIC_QOS(15) | \
+					BCM2711_DMA40_WAIT_FOR_WRITES |	\
+					BCM2711_DMA40_DISDEBUG))
+
+/* Transfer information bits */
+#define BCM2711_DMA40_INTEN		BIT(0)
+#define BCM2711_DMA40_TDMODE		BIT(1) /* 2D-Mode */
+#define BCM2711_DMA40_WAIT_RESP		BIT(2) /* wait for AXI write to be acked */
+#define BCM2711_DMA40_WAIT_RD_RESP	BIT(3) /* wait for AXI read to complete */
+#define BCM2711_DMA40_PER_MAP(x)	(((x) & 31) << 9) /* REQ source */
+#define BCM2711_DMA40_S_DREQ		BIT(14) /* enable SREQ for source */
+#define BCM2711_DMA40_D_DREQ		BIT(15) /* enable DREQ for destination */
+#define BCM2711_DMA40_S_WAIT(x)		(((x) & 0xff) << 16) /* add DMA read-wait cycles */
+#define BCM2711_DMA40_D_WAIT(x)		(((x) & 0xff) << 24) /* add DMA write-wait cycles */
+
+/* debug register bits */
+#define BCM2711_DMA40_DEBUG_WRITE_ERR		BIT(0)
+#define BCM2711_DMA40_DEBUG_FIFO_ERR		BIT(1)
+#define BCM2711_DMA40_DEBUG_READ_ERR		BIT(2)
+#define BCM2711_DMA40_DEBUG_READ_CB_ERR		BIT(3)
+#define BCM2711_DMA40_DEBUG_IN_ON_ERR		BIT(8)
+#define BCM2711_DMA40_DEBUG_ABORT_ON_ERR	BIT(9)
+#define BCM2711_DMA40_DEBUG_HALT_ON_ERR		BIT(10)
+#define BCM2711_DMA40_DEBUG_DISABLE_CLK_GATE	BIT(11)
+#define BCM2711_DMA40_DEBUG_RSTATE_SHIFT	14
+#define BCM2711_DMA40_DEBUG_RSTATE_BITS		4
+#define BCM2711_DMA40_DEBUG_WSTATE_SHIFT	18
+#define BCM2711_DMA40_DEBUG_WSTATE_BITS		4
+#define BCM2711_DMA40_DEBUG_RESET		BIT(23)
+#define BCM2711_DMA40_DEBUG_ID_SHIFT		24
+#define BCM2711_DMA40_DEBUG_ID_BITS		4
+#define BCM2711_DMA40_DEBUG_VERSION_SHIFT	28
+#define BCM2711_DMA40_DEBUG_VERSION_BITS	4
+
+/* Valid only for channels 0 - 3 (11 - 14) */
+#define BCM2711_DMA40_CHAN(n)	(((n) + 11) << 8) /* Base address */
+#define BCM2711_DMA40_CHANIO(base, n) ((base) + BCM2711_DMA_CHAN(n))
+
+/* the max dma length for different channels */
+#define MAX_DMA40_LEN SZ_1G
+
+#define BCM2711_DMA40_BURST_LEN(x)	((min(x, 16) - 1) << 8)
+#define BCM2711_DMA40_INC		BIT(12)
+#define BCM2711_DMA40_SIZE_32		(0 << 13)
+#define BCM2711_DMA40_SIZE_64		(1 << 13)
+#define BCM2711_DMA40_SIZE_128		(2 << 13)
+#define BCM2711_DMA40_SIZE_256		(3 << 13)
+#define BCM2711_DMA40_IGNORE		BIT(15)
+#define BCM2711_DMA40_STRIDE(x)		((x) << 16) /* For 2D mode */
+
+#define BCM2711_DMA40_MEMCPY_FLAGS \
+	(BCM2711_DMA40_QOS(0) | \
+	 BCM2711_DMA40_PANIC_QOS(0) | \
+	 BCM2711_DMA40_WAIT_FOR_WRITES | \
+	 BCM2711_DMA40_DISDEBUG)
+
+#define BCM2711_DMA40_MEMCPY_XFER_INFO \
+	(BCM2711_DMA40_SIZE_128 | \
+	 BCM2711_DMA40_INC | \
+	 BCM2711_DMA40_BURST_LEN(16))
+
+struct bcm2835_dmadev *memcpy_parent;
+static void __iomem *memcpy_chan;
+static struct bcm2711_dma40_scb *memcpy_scb;
+static dma_addr_t memcpy_scb_dma;
+DEFINE_SPINLOCK(memcpy_lock);
+
+static const struct bcm2835_dma_cfg_data bcm2835_dma_cfg = {
+	.chan_40bit_mask = 0,
+};
+
+static const struct bcm2835_dma_cfg_data bcm2711_dma_cfg = {
+	.chan_40bit_mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
+};
+
 static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c)
 {
 	/* lite and normal channels have different max frame length */
@@ -205,6 +328,32 @@ static inline struct bcm2835_desc *to_bcm2835_dma_desc(
 	return container_of(t, struct bcm2835_desc, vd.tx);
 }
 
+static inline uint32_t to_bcm2711_ti(uint32_t info)
+{
+	return ((info & BCM2835_DMA_INT_EN) ? BCM2711_DMA40_INTEN : 0) |
+		((info & BCM2835_DMA_WAIT_RESP) ? BCM2711_DMA40_WAIT_RESP : 0) |
+		((info & BCM2835_DMA_S_DREQ) ?
+		 (BCM2711_DMA40_S_DREQ | BCM2711_DMA40_WAIT_RD_RESP) : 0) |
+		((info & BCM2835_DMA_D_DREQ) ? BCM2711_DMA40_D_DREQ : 0) |
+		BCM2711_DMA40_PER_MAP((info >> 16) & 0x1f);
+}
+
+static inline uint32_t to_bcm2711_srci(uint32_t info)
+{
+	return ((info & BCM2835_DMA_S_INC) ? BCM2711_DMA40_INC : 0);
+}
+
+static inline uint32_t to_bcm2711_dsti(uint32_t info)
+{
+	return ((info & BCM2835_DMA_D_INC) ? BCM2711_DMA40_INC : 0);
+}
+
+static inline uint32_t to_bcm2711_cbaddr(dma_addr_t addr)
+{
+	WARN_ON_ONCE(addr & 0x1f);
+	return (addr >> 5);
+}
+
 static void bcm2835_dma_free_cb_chain(struct bcm2835_desc *desc)
 {
 	size_t i;
@@ -223,45 +372,53 @@ static void bcm2835_dma_desc_free(struct virt_dma_desc *vd)
 }
 
 static void bcm2835_dma_create_cb_set_length(
-	struct bcm2835_chan *chan,
+	struct bcm2835_chan *c,
 	struct bcm2835_dma_cb *control_block,
 	size_t len,
 	size_t period_len,
 	size_t *total_len,
 	u32 finalextrainfo)
 {
-	size_t max_len = bcm2835_dma_max_frame_length(chan);
+	size_t max_len = bcm2835_dma_max_frame_length(c);
+	u32 cb_len;
 
 	/* set the length taking lite-channel limitations into account */
-	control_block->length = min_t(u32, len, max_len);
+	cb_len = min_t(u32, len, max_len);
 
-	/* finished if we have no period_length */
-	if (!period_len)
-		return;
+	if (period_len) {
+		/*
+		 * period_len means: that we need to generate
+		 * transfers that are terminating at every
+		 * multiple of period_len - this is typically
+		 * used to set the interrupt flag in info
+		 * which is required during cyclic transfers
+		 */
 
-	/*
-	 * period_len means: that we need to generate
-	 * transfers that are terminating at every
-	 * multiple of period_len - this is typically
-	 * used to set the interrupt flag in info
-	 * which is required during cyclic transfers
-	 */
+		/* have we filled in period_length yet? */
+		if (*total_len + cb_len < period_len) {
+			/* update number of bytes in this period so far */
+			*total_len += cb_len;
+		} else {
+			/* calculate the length that remains to reach period_len */
+			cb_len = period_len - *total_len;
 
-	/* have we filled in period_length yet? */
-	if (*total_len + control_block->length < period_len) {
-		/* update number of bytes in this period so far */
-		*total_len += control_block->length;
-		return;
+			/* reset total_length for next period */
+			*total_len = 0;
+		}
 	}
 
-	/* calculate the length that remains to reach period_length */
-	control_block->length = period_len - *total_len;
-
-	/* reset total_length for next period */
-	*total_len = 0;
+	if (c->is_40bit_channel) {
+		struct bcm2711_dma40_scb *scb =
+			(struct bcm2711_dma40_scb *)control_block;
 
-	/* add extrainfo bits in info */
-	control_block->info |= finalextrainfo;
+		scb->len = cb_len;
+		/* add extrainfo bits to ti */
+		scb->ti |= to_bcm2711_ti(finalextrainfo);
+	} else {
+		control_block->length = cb_len;
+		/* add extrainfo bits to info */
+		control_block->info |= finalextrainfo;
+	}
 }
 
 static inline size_t bcm2835_dma_count_frames_for_sg(
@@ -284,7 +441,7 @@ static inline size_t bcm2835_dma_count_frames_for_sg(
 /**
  * bcm2835_dma_create_cb_chain - create a control block and fills data in
  *
- * @chan:           the @dma_chan for which we run this
+ * @c:              the @bcm2835_chan for which we run this
  * @direction:      the direction in which we transfer
  * @cyclic:         it is a cyclic transfer
  * @info:           the default info bits to apply per controlblock
@@ -302,12 +459,11 @@ static inline size_t bcm2835_dma_count_frames_for_sg(
  * @gfp:            the GFP flag to use for allocation
  */
 static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
-	struct dma_chan *chan, enum dma_transfer_direction direction,
+	struct bcm2835_chan *c, enum dma_transfer_direction direction,
 	bool cyclic, u32 info, u32 finalextrainfo, size_t frames,
 	dma_addr_t src, dma_addr_t dst, size_t buf_len,
 	size_t period_len, gfp_t gfp)
 {
-	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	size_t len = buf_len, total_len;
 	size_t frame;
 	struct bcm2835_desc *d;
@@ -339,11 +495,23 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 
 		/* fill in the control block */
 		control_block = cb_entry->cb;
-		control_block->info = info;
-		control_block->src = src;
-		control_block->dst = dst;
-		control_block->stride = 0;
-		control_block->next = 0;
+		if (c->is_40bit_channel) {
+			struct bcm2711_dma40_scb *scb =
+				(struct bcm2711_dma40_scb *)control_block;
+			scb->ti = to_bcm2711_ti(info);
+			scb->src = lower_32_bits(src);
+			scb->srci = upper_32_bits(src) | to_bcm2711_srci(info);
+			scb->dst = lower_32_bits(dst);
+			scb->dsti = upper_32_bits(dst) | to_bcm2711_dsti(info);
+			scb->next_cb = 0;
+		} else {
+			control_block->info = info;
+			control_block->src = src;
+			control_block->dst = dst;
+			control_block->stride = 0;
+			control_block->next = 0;
+		}
+
 		/* set up length in control_block if requested */
 		if (buf_len) {
 			/* calculate length honoring period_length */
@@ -353,25 +521,51 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 				cyclic ? finalextrainfo : 0);
 
 			/* calculate new remaining length */
-			len -= control_block->length;
+			if (c->is_40bit_channel)
+				len -= ((struct bcm2711_dma40_scb *)control_block)->len;
+			else
+				len -= control_block->length;
 		}
 
 		/* link this the last controlblock */
-		if (frame)
+		if (frame && c->is_40bit_channel)
+			((struct bcm2711_dma40_scb *)
+			 d->cb_list[frame - 1].cb)->next_cb =
+				to_bcm2711_cbaddr(cb_entry->paddr);
+		if (frame && !c->is_40bit_channel)
 			d->cb_list[frame - 1].cb->next = cb_entry->paddr;
 
 		/* update src and dst and length */
-		if (src && (info & BCM2835_DMA_S_INC))
-			src += control_block->length;
-		if (dst && (info & BCM2835_DMA_D_INC))
-			dst += control_block->length;
+		if (src && (info & BCM2835_DMA_S_INC)) {
+			if (c->is_40bit_channel)
+				src += ((struct bcm2711_dma40_scb *)control_block)->len;
+			else
+				src += control_block->length;
+		}
+
+		if (dst && (info & BCM2835_DMA_D_INC)) {
+			if (c->is_40bit_channel)
+				dst += ((struct bcm2711_dma40_scb *)control_block)->len;
+			else
+				dst += control_block->length;
+		}
 
 		/* Length of total transfer */
-		d->size += control_block->length;
+		if (c->is_40bit_channel)
+			d->size += ((struct bcm2711_dma40_scb *)control_block)->len;
+		else
+			d->size += control_block->length;
 	}
 
 	/* the last frame requires extra flags */
-	d->cb_list[d->frames - 1].cb->info |= finalextrainfo;
+	if (c->is_40bit_channel) {
+		struct bcm2711_dma40_scb *scb =
+			(struct bcm2711_dma40_scb *)d->cb_list[d->frames - 1].cb;
+
+		scb->ti |= to_bcm2711_ti(finalextrainfo);
+	} else {
+		d->cb_list[d->frames - 1].cb->info |= finalextrainfo;
+	}
 
 	/* detect a size missmatch */
 	if (buf_len && (d->size != buf_len))
@@ -385,13 +579,12 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 }
 
 static void bcm2835_dma_fill_cb_chain_with_sg(
-	struct dma_chan *chan,
+	struct bcm2835_chan *c,
 	enum dma_transfer_direction direction,
 	struct bcm2835_cb_entry *cb,
 	struct scatterlist *sgl,
 	unsigned int sg_len)
 {
-	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	size_t len, max_len;
 	unsigned int i;
 	dma_addr_t addr;
@@ -399,14 +592,35 @@ static void bcm2835_dma_fill_cb_chain_with_sg(
 
 	max_len = bcm2835_dma_max_frame_length(c);
 	for_each_sg(sgl, sgent, sg_len, i) {
-		for (addr = sg_dma_address(sgent), len = sg_dma_len(sgent);
-		     len > 0;
-		     addr += cb->cb->length, len -= cb->cb->length, cb++) {
-			if (direction == DMA_DEV_TO_MEM)
-				cb->cb->dst = addr;
-			else
-				cb->cb->src = addr;
-			cb->cb->length = min(len, max_len);
+		if (c->is_40bit_channel) {
+			struct bcm2711_dma40_scb *scb;
+
+			for (addr = sg_dma_address(sgent),
+			     len = sg_dma_len(sgent);
+			     len > 0;
+			     addr += scb->len, len -= scb->len, cb++) {
+				scb = (struct bcm2711_dma40_scb *)cb->cb;
+				if (direction == DMA_DEV_TO_MEM) {
+					scb->dst = lower_32_bits(addr);
+					scb->dsti = upper_32_bits(addr) | BCM2711_DMA40_INC;
+				} else {
+					scb->src = lower_32_bits(addr);
+					scb->srci = upper_32_bits(addr) | BCM2711_DMA40_INC;
+				}
+				scb->len = min(len, max_len);
+			}
+		} else {
+			for (addr = sg_dma_address(sgent),
+			     len = sg_dma_len(sgent);
+			     len > 0;
+			     addr += cb->cb->length, len -= cb->cb->length,
+			     cb++) {
+				if (direction == DMA_DEV_TO_MEM)
+					cb->cb->dst = addr;
+				else
+					cb->cb->src = addr;
+				cb->cb->length = min(len, max_len);
+			}
 		}
 	}
 }
@@ -423,20 +637,60 @@ static void bcm2835_dma_abort(struct bcm2835_chan *c)
 	if (!readl(chan_base + BCM2835_DMA_ADDR))
 		return;
 
-	/* Write 0 to the active bit - Pause the DMA */
-	writel(0, chan_base + BCM2835_DMA_CS);
+	if (c->is_40bit_channel) {
+		/* Halt the current DMA */
+		writel(readl(chan_base + BCM2711_DMA40_CS) | BCM2711_DMA40_HALT,
+		       chan_base + BCM2711_DMA40_CS);
 
-	/* Wait for any current AXI transfer to complete */
-	while ((readl(chan_base + BCM2835_DMA_CS) &
-		BCM2835_DMA_WAITING_FOR_WRITES) && --timeout)
-		cpu_relax();
+		while ((readl(chan_base + BCM2711_DMA40_CS) & BCM2711_DMA40_HALT) && --timeout)
+			cpu_relax();
 
-	/* Peripheral might be stuck and fail to signal AXI write responses */
-	if (!timeout)
-		dev_err(c->vc.chan.device->dev,
-			"failed to complete outstanding writes\n");
+		/* Peripheral might be stuck and fail to halt */
+		if (!timeout)
+			dev_err(c->vc.chan.device->dev,
+				"failed to halt dma\n");
 
-	writel(BCM2835_DMA_RESET, chan_base + BCM2835_DMA_CS);
+		writel(0, chan_base + BCM2711_DMA40_CS);
+		writel(0, chan_base + BCM2711_DMA40_CB);
+	} else {
+		/*
+		 * A zero control block address means the channel is idle.
+		 * (The ACTIVE flag in the CS register is not a reliable indicator.)
+		 */
+		if (!readl(chan_base + BCM2835_DMA_ADDR))
+			return;
+
+		/* Write 0 to the active bit - Pause the DMA */
+		writel(readl(chan_base + BCM2835_DMA_CS) & ~BCM2835_DMA_ACTIVE,
+		       chan_base + BCM2835_DMA_CS);
+
+		/* wait for DMA to be paused */
+		while ((readl(chan_base + BCM2835_DMA_CS) & BCM2835_DMA_WAITING_FOR_WRITES) &&
+		       --timeout)
+			cpu_relax();
+
+		/* Peripheral might be stuck and fail to signal AXI write responses */
+		if (!timeout)
+			dev_err(c->vc.chan.device->dev,
+				"failed to pause dma\n");
+
+		/* We need to clear the next DMA block pending */
+		writel(0, chan_base + BCM2835_DMA_NEXTCB);
+
+		/* Abort the DMA, which needs to be enabled to complete */
+		writel(readl(chan_base + BCM2835_DMA_CS) | BCM2835_DMA_ABORT | BCM2835_DMA_ACTIVE,
+		       chan_base + BCM2835_DMA_CS);
+
+		/* wait for DMA to have been aborted */
+		timeout = 10000;
+		while ((readl(chan_base + BCM2835_DMA_CS) & BCM2835_DMA_ABORT) && --timeout)
+			cpu_relax();
+
+		/* Peripheral might be stuck and fail to signal AXI write responses */
+		if (!timeout)
+			dev_err(c->vc.chan.device->dev,
+				"failed to abort dma\n");
+	}
 }
 
 static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
@@ -453,9 +707,16 @@ static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
 
 	c->desc = d = to_bcm2835_dma_desc(&vd->tx);
 
-	writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
-	writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
-	       c->chan_base + BCM2835_DMA_CS);
+	if (c->is_40bit_channel) {
+		writel(to_bcm2711_cbaddr(d->cb_list[0].paddr),
+		       c->chan_base + BCM2711_DMA40_CB);
+		writel(BCM2711_DMA40_ACTIVE | BCM2711_DMA40_CS_FLAGS(c->dreq),
+		       c->chan_base + BCM2711_DMA40_CS);
+	} else {
+		writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
+		writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
+		       c->chan_base + BCM2835_DMA_CS);
+	}
 }
 
 static irqreturn_t bcm2835_dma_callback(int irq, void *data)
@@ -482,8 +743,7 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
 	 * if this IRQ handler is threaded.) If the channel is finished, it
 	 * will remain idle despite the ACTIVE flag being set.
 	 */
-	writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE |
-	       BCM2835_DMA_CS_FLAGS(c->dreq),
+	writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
 	       c->chan_base + BCM2835_DMA_CS);
 
 	d = c->desc;
@@ -546,20 +806,39 @@ static size_t bcm2835_dma_desc_size_pos(struct bcm2835_desc *d, dma_addr_t addr)
 	unsigned int i;
 	size_t size;
 
-	for (size = i = 0; i < d->frames; i++) {
-		struct bcm2835_dma_cb *control_block = d->cb_list[i].cb;
-		size_t this_size = control_block->length;
-		dma_addr_t dma;
+	if (d->c->is_40bit_channel) {
+		for (size = i = 0; i < d->frames; i++) {
+			struct bcm2711_dma40_scb *control_block =
+				(struct bcm2711_dma40_scb *)d->cb_list[i].cb;
+			size_t this_size = control_block->len;
+			dma_addr_t dma;
 
-		if (d->dir == DMA_DEV_TO_MEM)
-			dma = control_block->dst;
-		else
-			dma = control_block->src;
+			if (d->dir == DMA_DEV_TO_MEM)
+				dma = control_block->dst;
+			else
+				dma = control_block->src;
 
-		if (size)
-			size += this_size;
-		else if (addr >= dma && addr < dma + this_size)
-			size += dma + this_size - addr;
+			if (size)
+				size += this_size;
+			else if (addr >= dma && addr < dma + this_size)
+				size += dma + this_size - addr;
+		}
+	} else {
+		for (size = i = 0; i < d->frames; i++) {
+			struct bcm2835_dma_cb *control_block = d->cb_list[i].cb;
+			size_t this_size = control_block->length;
+			dma_addr_t dma;
+
+			if (d->dir == DMA_DEV_TO_MEM)
+				dma = control_block->dst;
+			else
+				dma = control_block->src;
+
+			if (size)
+				size += this_size;
+			else if (addr >= dma && addr < dma + this_size)
+				size += dma + this_size - addr;
+		}
 	}
 
 	return size;
@@ -586,12 +865,25 @@ static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan,
 		struct bcm2835_desc *d = c->desc;
 		dma_addr_t pos;
 
-		if (d->dir == DMA_MEM_TO_DEV)
+		if (d->dir == DMA_MEM_TO_DEV && c->is_40bit_channel) {
+			u64 lo_bits, hi_bits;
+
+			lo_bits = readl(c->chan_base + BCM2711_DMA40_SRC);
+			hi_bits = readl(c->chan_base + BCM2711_DMA40_SRCI) & 0xff;
+			pos = (hi_bits << 32) | lo_bits;
+		} else if (d->dir == DMA_MEM_TO_DEV && !c->is_40bit_channel) {
 			pos = readl(c->chan_base + BCM2835_DMA_SOURCE_AD);
-		else if (d->dir == DMA_DEV_TO_MEM)
+		} else if (d->dir == DMA_DEV_TO_MEM && c->is_40bit_channel) {
+			u64 lo_bits, hi_bits;
+
+			lo_bits = readl(c->chan_base + BCM2711_DMA40_DEST);
+			hi_bits = readl(c->chan_base + BCM2711_DMA40_DESTI) & 0xff;
+			pos = (hi_bits << 32) | lo_bits;
+		} else if (d->dir == DMA_DEV_TO_MEM && !c->is_40bit_channel) {
 			pos = readl(c->chan_base + BCM2835_DMA_DEST_AD);
-		else
+		} else {
 			pos = 0;
+		}
 
 		txstate->residue = bcm2835_dma_desc_size_pos(d, pos);
 	} else {
@@ -634,7 +926,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_memcpy(
 	frames = bcm2835_dma_frames_for_length(len, max_len);
 
 	/* allocate the CB chain - this also fills in the pointers */
-	d = bcm2835_dma_create_cb_chain(chan, DMA_MEM_TO_MEM, false,
+	d = bcm2835_dma_create_cb_chain(c, DMA_MEM_TO_MEM, false,
 					info, extra, frames,
 					src, dst, len, 0, GFP_KERNEL);
 	if (!d)
@@ -669,11 +961,21 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 		if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
 		src = c->cfg.src_addr;
+		/*
+		 * One would think it ought to be possible to get the physical
+		 * to dma address mapping information from the dma-ranges DT
+		 * property, but I've not found a way yet that doesn't involve
+		 * open-coding the whole thing.
+		 */
+		if (c->is_40bit_channel)
+			src |= 0x400000000ull;
 		info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC;
 	} else {
 		if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
 		dst = c->cfg.dst_addr;
+		if (c->is_40bit_channel)
+			dst |= 0x400000000ull;
 		info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
 	}
 
@@ -681,7 +983,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 	frames = bcm2835_dma_count_frames_for_sg(c, sgl, sg_len);
 
 	/* allocate the CB chain */
-	d = bcm2835_dma_create_cb_chain(chan, direction, false,
+	d = bcm2835_dma_create_cb_chain(c, direction, false,
 					info, extra,
 					frames, src, dst, 0, 0,
 					GFP_NOWAIT);
@@ -689,7 +991,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 		return NULL;
 
 	/* fill in frames with scatterlist pointers */
-	bcm2835_dma_fill_cb_chain_with_sg(chan, direction, d->cb_list,
+	bcm2835_dma_fill_cb_chain_with_sg(c, direction, d->cb_list,
 					  sgl, sg_len);
 
 	return vchan_tx_prep(&c->vc, &d->vd, flags);
@@ -743,12 +1045,16 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 		if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
 		src = c->cfg.src_addr;
+		if (c->is_40bit_channel)
+			src |= 0x400000000ull;
 		dst = buf_addr;
 		info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC;
 	} else {
 		if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
 		dst = c->cfg.dst_addr;
+		if (c->is_40bit_channel)
+			dst |= 0x400000000ull;
 		src = buf_addr;
 		info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
 
@@ -768,7 +1074,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	 * note that we need to use GFP_NOWAIT, as the ALSA i2s dmaengine
 	 * implementation calls prep_dma_cyclic with interrupts disabled.
 	 */
-	d = bcm2835_dma_create_cb_chain(chan, direction, true,
+	d = bcm2835_dma_create_cb_chain(c, direction, true,
 					info, extra,
 					frames, src, dst, buf_len,
 					period_len, GFP_NOWAIT);
@@ -776,7 +1082,12 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 		return NULL;
 
 	/* wrap around into a loop */
-	d->cb_list[d->frames - 1].cb->next = d->cb_list[0].paddr;
+	if (c->is_40bit_channel)
+		((struct bcm2711_dma40_scb *)
+		 d->cb_list[frames - 1].cb)->next_cb =
+			to_bcm2711_cbaddr(d->cb_list[0].paddr);
+	else
+		d->cb_list[d->frames - 1].cb->next = d->cb_list[0].paddr;
 
 	return vchan_tx_prep(&c->vc, &d->vd, flags);
 }
@@ -837,9 +1148,11 @@ static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id,
 	c->irq_number = irq;
 	c->irq_flags = irq_flags;
 
-	/* check in DEBUG register if this is a LITE channel */
-	if (readl(c->chan_base + BCM2835_DMA_DEBUG) &
-		BCM2835_DMA_DEBUG_LITE)
+	/* check for 40bit and lite channels */
+	if (d->cfg_data->chan_40bit_mask & BIT(chan_id))
+		c->is_40bit_channel = true;
+	else if (readl(c->chan_base + BCM2835_DMA_DEBUG) &
+		 BCM2835_DMA_DEBUG_LITE)
 		c->is_lite_channel = true;
 
 	return 0;
@@ -859,8 +1172,58 @@ static void bcm2835_dma_free(struct bcm2835_dmadev *od)
 			     DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
 }
 
+int bcm2711_dma40_memcpy_init(void)
+{
+	if (!memcpy_parent)
+		return -EPROBE_DEFER;
+
+	if (!memcpy_chan)
+		return -EINVAL;
+
+	if (!memcpy_scb)
+		return -ENOMEM;
+
+	return 0;
+}
+EXPORT_SYMBOL(bcm2711_dma40_memcpy_init);
+
+void bcm2711_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size)
+{
+	struct bcm2711_dma40_scb *scb = memcpy_scb;
+	unsigned long flags;
+
+	if (!scb) {
+		pr_err("%s not initialised!\n", __func__);
+		return;
+	}
+
+	spin_lock_irqsave(&memcpy_lock, flags);
+
+	scb->ti = 0;
+	scb->src = lower_32_bits(src);
+	scb->srci = upper_32_bits(src) | BCM2711_DMA40_MEMCPY_XFER_INFO;
+	scb->dst = lower_32_bits(dst);
+	scb->dsti = upper_32_bits(dst) | BCM2711_DMA40_MEMCPY_XFER_INFO;
+	scb->len = size;
+	scb->next_cb = 0;
+
+	writel((u32)(memcpy_scb_dma >> 5), memcpy_chan + BCM2711_DMA40_CB);
+	writel(BCM2711_DMA40_MEMCPY_FLAGS + BCM2711_DMA40_ACTIVE,
+	       memcpy_chan + BCM2711_DMA40_CS);
+
+	/* Poll for completion */
+	while (!(readl(memcpy_chan + BCM2711_DMA40_CS) & BCM2711_DMA40_END))
+		cpu_relax();
+
+	writel(BCM2711_DMA40_END, memcpy_chan + BCM2711_DMA40_CS);
+
+	spin_unlock_irqrestore(&memcpy_lock, flags);
+}
+EXPORT_SYMBOL(bcm2711_dma40_memcpy);
+
 static const struct of_device_id bcm2835_dma_of_match[] = {
-	{ .compatible = "brcm,bcm2835-dma", },
+	{ .compatible = "brcm,bcm2835-dma", .data = &bcm2835_dma_cfg },
+	{ .compatible = "brcm,bcm2711-dma", .data = &bcm2711_dma_cfg },
 	{},
 };
 MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match);
@@ -884,6 +1247,7 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
 static int bcm2835_dma_probe(struct platform_device *pdev)
 {
 	struct bcm2835_dmadev *od;
+	struct resource *res;
 	void __iomem *base;
 	int rc;
 	int i, j;
@@ -891,6 +1255,8 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 	int irq_flags;
 	uint32_t chans_available;
 	char chan_name[BCM2835_DMA_CHAN_NAME_SIZE];
+	const struct of_device_id *of_id;
+	int chan_count, chan_start, chan_end;
 
 	if (!pdev->dev.dma_mask)
 		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
@@ -907,10 +1273,17 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 
 	dma_set_max_seg_size(&pdev->dev, 0x3FFFFFFF);
 
-	base = devm_platform_ioremap_resource(pdev, 0);
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
+	/* The set of channels can be split across multiple instances. */
+	chan_start = ((u32)(uintptr_t)base / BCM2835_DMA_CHAN_SIZE) & 0xf;
+	base -= BCM2835_DMA_CHAN(chan_start);
+	chan_count = resource_size(res) / BCM2835_DMA_CHAN_SIZE;
+	chan_end = min(chan_start + chan_count,
+		       BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED + 1);
+
 	od->base = base;
 
 	dma_cap_set(DMA_SLAVE, od->ddev.cap_mask);
@@ -946,6 +1319,14 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	of_id = of_match_node(bcm2835_dma_of_match, pdev->dev.of_node);
+	if (!of_id) {
+		dev_err(&pdev->dev, "Failed to match compatible string\n");
+		return -EINVAL;
+	}
+
+	od->cfg_data = of_id->data;
+
 	/* Request DMA channel mask from device tree */
 	if (of_property_read_u32(pdev->dev.of_node,
 			"brcm,dma-channel-mask",
@@ -955,8 +1336,23 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 		goto err_no_dma;
 	}
 
+	/* One channel is reserved for the 40-bit DMA memcpy API */
+	if (chans_available & od->cfg_data->chan_40bit_mask &
+	    BIT(BCM2711_DMA_MEMCPY_CHAN)) {
+		memcpy_parent = od;
+		memcpy_chan = BCM2835_DMA_CHANIO(base, BCM2711_DMA_MEMCPY_CHAN);
+		memcpy_scb = dma_alloc_coherent(memcpy_parent->ddev.dev,
+						sizeof(*memcpy_scb),
+						&memcpy_scb_dma, GFP_KERNEL);
+		if (!memcpy_scb)
+			dev_warn(&pdev->dev,
+				 "Failed to allocated memcpy scb\n");
+
+		chans_available &= ~BIT(BCM2711_DMA_MEMCPY_CHAN);
+	}
+
 	/* get irqs for each channel that we support */
-	for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) {
+	for (i = chan_start; i < chan_end; i++) {
 		/* skip masked out channels */
 		if (!(chans_available & (1 << i))) {
 			irq[i] = -1;
@@ -979,13 +1375,18 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 		irq[i] = platform_get_irq(pdev, i < 11 ? i : 11);
 	}
 
+	chan_count = 0;
+
 	/* get irqs for each channel */
-	for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) {
+	for (i = chan_start; i < chan_end; i++) {
 		/* skip channels without irq */
 		if (irq[i] < 0)
 			continue;
 
 		/* check if there are other channels that also use this irq */
+		/* FIXME: This will fail if interrupts are shared across
+		 * instances
+		 */
 		irq_flags = 0;
 		for (j = 0; j <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; j++)
 			if ((i != j) && (irq[j] == irq[i])) {
@@ -997,9 +1398,10 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
 		rc = bcm2835_dma_chan_init(od, i, irq[i], irq_flags);
 		if (rc)
 			goto err_no_dma;
+		chan_count++;
 	}
 
-	dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", i);
+	dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", chan_count);
 
 	/* Device-tree DMA controller registration */
 	rc = of_dma_controller_register(pdev->dev.of_node,
@@ -1030,6 +1432,13 @@ static void bcm2835_dma_remove(struct platform_device *pdev)
 	struct bcm2835_dmadev *od = platform_get_drvdata(pdev);
 
 	dma_async_device_unregister(&od->ddev);
+	if (memcpy_parent == od) {
+		dma_free_coherent(&pdev->dev, sizeof(*memcpy_scb), memcpy_scb,
+				  memcpy_scb_dma);
+		memcpy_parent = NULL;
+		memcpy_scb = NULL;
+		memcpy_chan = NULL;
+	}
 	bcm2835_dma_free(od);
 }
 
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:33 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:33 +0100
Subject: [PATCH 05/12] bcm2835-dma: Derive slave DMA addresses correctly
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <30da53ebdf43b712da790fd2ae0f0040f71762b8.1706948717.git.andrea.porta@suse.com>

From: Phil Elwell <phil at raspberrypi.com>

Slave addresses for DMA are meant to be supplied as physical addresses
(contrary to what struct snd_dmaengine_dai_dma_data does). It is up to
the DMA controller driver to perform the translation based on its own
view of the world, as described in Device Tree.

Now that the Pi Device Trees have the correct peripheral mappings,
replace the hacky address munging with phys_to_dma().

Signed-off-by: Phil Elwell <phil at raspberrypi.com>
---
 drivers/dma/bcm2835-dma.c | 23 +++++------------------
 1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 237dcdb8d726..077812eda609 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -18,6 +18,7 @@
  *	Copyright 2012 Marvell International Ltd.
  */
 #include <linux/dmaengine.h>
+#include <linux/dma-direct.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmapool.h>
 #include <linux/err.h>
@@ -980,22 +981,12 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 	if (direction == DMA_DEV_TO_MEM) {
 		if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
-		src = c->cfg.src_addr;
-		/*
-		 * One would think it ought to be possible to get the physical
-		 * to dma address mapping information from the dma-ranges DT
-		 * property, but I've not found a way yet that doesn't involve
-		 * open-coding the whole thing.
-		 */
-		if (c->is_40bit_channel)
-			src |= 0x400000000ull;
+		src = phys_to_dma(chan->device->dev, c->cfg.src_addr);
 		info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC;
 	} else {
 		if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
-		dst = c->cfg.dst_addr;
-		if (c->is_40bit_channel)
-			dst |= 0x400000000ull;
+		dst = phys_to_dma(chan->device->dev, c->cfg.dst_addr);
 		info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
 	}
 
@@ -1064,17 +1055,13 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	if (direction == DMA_DEV_TO_MEM) {
 		if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
-		src = c->cfg.src_addr;
-		if (c->is_40bit_channel)
-			src |= 0x400000000ull;
+		src = phys_to_dma(chan->device->dev, c->cfg.src_addr);
 		dst = buf_addr;
 		info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC;
 	} else {
 		if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
 			return NULL;
-		dst = c->cfg.dst_addr;
-		if (c->is_40bit_channel)
-			dst |= 0x400000000ull;
+		dst = phys_to_dma(chan->device->dev, c->cfg.dst_addr);
 		src = buf_addr;
 		info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
 
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:34 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:34 +0100
Subject: [PATCH 06/12] dmaengine: bcm2835: Use to_bcm2711_cbaddr where relevant
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <b8962397fa4e77f6f82067c44bcf89e70050d4d4.1706948717.git.andrea.porta@suse.com>

From: Maxime Ripard <maxime at cerno.tech>

bcm2711_dma40_memcpy has some code strictly equivalent to the
to_bcm2711_cbaddr() function. Let's use it instead.

Signed-off-by: Maxime Ripard <maxime at cerno.tech>
---
 drivers/dma/bcm2835-dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 077812eda609..d8d1f9ba2572 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -1214,7 +1214,7 @@ void bcm2711_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size)
 	scb->len = size;
 	scb->next_cb = 0;
 
-	writel((u32)(memcpy_scb_dma >> 5), memcpy_chan + BCM2711_DMA40_CB);
+	writel(to_bcm2711_cbaddr(memcpy_scb_dma), memcpy_chan + BCM2711_DMA40_CB);
 	writel(BCM2711_DMA40_MEMCPY_FLAGS + BCM2711_DMA40_ACTIVE,
 	       memcpy_chan + BCM2711_DMA40_CS);
 
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:36 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:36 +0100
Subject: [PATCH 08/12] bcm2835-dma: Need to keep PROT bits set in CS on 40bit controller
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <98d536c4d9789e176ab83ab3d2257c08f0075bdb.1706948717.git.andrea.porta@suse.com>

From: Dom Cobley <popcornmix at gmail.com>

Resetting them to zero puts DMA channel into secure mode
which makes further accesses impossible

Cc: Dom Cobley <popcornmix at gmail.com>
Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 drivers/dma/bcm2835-dma.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index a20700a400a2..1b3f470274b2 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -239,6 +239,8 @@ struct bcm2835_desc {
 #define BCM2711_DMA40_WR_PAUSED		BIT(5)  /* Writing is paused */
 #define BCM2711_DMA40_DREQ_PAUSED	BIT(6)  /* Is paused by DREQ flow control */
 #define BCM2711_DMA40_WAITING_FOR_WRITES BIT(7)  /* Waiting for last write */
+// we always want to run in supervisor mode
+#define BCM2711_DMA40_PROT		(BIT(8) | BIT(9))
 #define BCM2711_DMA40_ERR		BIT(10)
 #define BCM2711_DMA40_QOS(x)		(((x) & 0x1f) << 16)
 #define BCM2711_DMA40_PANIC_QOS(x)	(((x) & 0x1f) << 20)
@@ -246,10 +248,10 @@ struct bcm2835_desc {
 #define BCM2711_DMA40_DISDEBUG		BIT(29)
 #define BCM2711_DMA40_ABORT		BIT(30)
 #define BCM2711_DMA40_HALT		BIT(31)
-#define BCM2711_DMA40_CS_FLAGS(x) ((x) & (BCM2711_DMA40_QOS(15) | \
-					BCM2711_DMA40_PANIC_QOS(15) | \
-					BCM2711_DMA40_WAIT_FOR_WRITES |	\
-					BCM2711_DMA40_DISDEBUG))
+#define BCM2711_DMA40_CS_FLAGS(x)	((x) & (BCM2711_DMA40_QOS(15) | \
+					 BCM2711_DMA40_PANIC_QOS(15) | \
+					 BCM2711_DMA40_WAIT_FOR_WRITES | \
+					 BCM2711_DMA40_DISDEBUG))
 
 /* Transfer information bits */
 #define BCM2711_DMA40_INTEN		BIT(0)
@@ -679,7 +681,7 @@ static void bcm2835_dma_abort(struct bcm2835_chan *c)
 			dev_err(c->vc.chan.device->dev,
 				"failed to halt dma\n");
 
-		writel(0, chan_base + BCM2711_DMA40_CS);
+		writel(BCM2711_DMA40_PROT, chan_base + BCM2711_DMA40_CS);
 		writel(0, chan_base + BCM2711_DMA40_CB);
 	} else {
 		/*
@@ -739,7 +741,7 @@ static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
 	if (c->is_40bit_channel) {
 		writel(to_bcm2711_cbaddr(d->cb_list[0].paddr),
 		       c->chan_base + BCM2711_DMA40_CB);
-		writel(BCM2711_DMA40_ACTIVE | BCM2711_DMA40_CS_FLAGS(c->dreq),
+		writel(BCM2711_DMA40_ACTIVE | BCM2711_DMA40_PROT | BCM2711_DMA40_CS_FLAGS(c->dreq),
 		       c->chan_base + BCM2711_DMA40_CS);
 	} else {
 		writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
@@ -772,8 +774,13 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
 	 * if this IRQ handler is threaded.) If the channel is finished, it
 	 * will remain idle despite the ACTIVE flag being set.
 	 */
-	writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
-	       c->chan_base + BCM2835_DMA_CS);
+	if (c->is_40bit_channel)
+		writel(BCM2835_DMA_INT | BCM2711_DMA40_ACTIVE | BCM2711_DMA40_PROT |
+		       BCM2711_DMA40_CS_FLAGS(c->dreq),
+		       c->chan_base + BCM2711_DMA40_CS);
+	else
+		writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
+		       c->chan_base + BCM2835_DMA_CS);
 
 	d = c->desc;
 
@@ -1227,14 +1234,14 @@ void bcm2711_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size)
 	scb->next_cb = 0;
 
 	writel(to_bcm2711_cbaddr(memcpy_scb_dma), memcpy_chan + BCM2711_DMA40_CB);
-	writel(BCM2711_DMA40_MEMCPY_FLAGS + BCM2711_DMA40_ACTIVE,
+	writel(BCM2711_DMA40_MEMCPY_FLAGS | BCM2711_DMA40_ACTIVE | BCM2711_DMA40_PROT,
 	       memcpy_chan + BCM2711_DMA40_CS);
 
 	/* Poll for completion */
 	while (!(readl(memcpy_chan + BCM2711_DMA40_CS) & BCM2711_DMA40_END))
 		cpu_relax();
 
-	writel(BCM2711_DMA40_END, memcpy_chan + BCM2711_DMA40_CS);
+	writel(BCM2711_DMA40_END | BCM2711_DMA40_PROT, memcpy_chan + BCM2711_DMA40_CS);
 
 	spin_unlock_irqrestore(&memcpy_lock, flags);
 }
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:35 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:35 +0100
Subject: [PATCH 07/12] bcm2835-dma: Support dma flags for multi-beat burst
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <570953f9532e2dc46568674d3c1348cdf26488b6.1706948717.git.andrea.porta@suse.com>

From: Dom Cobley <popcornmix at gmail.com>

Add a control bit to enable a multi-beat burst on a DMA.
This improves DMA performance and is required for HDMI audio.

Signed-off-by: Dom Cobley <popcornmix at gmail.com>
Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 drivers/dma/bcm2835-dma.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index d8d1f9ba2572..a20700a400a2 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -156,7 +156,8 @@ struct bcm2835_desc {
 #define BCM2835_DMA_S_WIDTH	BIT(9) /* 128bit writes if set */
 #define BCM2835_DMA_S_DREQ	BIT(10) /* enable SREQ for source */
 #define BCM2835_DMA_S_IGNORE	BIT(11) /* ignore source reads - read 0 */
-#define BCM2835_DMA_BURST_LENGTH(x) ((x & 15) << 12)
+#define BCM2835_DMA_BURST_LENGTH(x) (((x) & 15) << 12)
+#define BCM2835_DMA_GET_BURST_LENGTH(x) (((x) >> 12) & 15)
 #define BCM2835_DMA_CS_FLAGS(x) ((x) & (BCM2835_DMA_PRIORITY(15) | \
 				      BCM2835_DMA_PANIC_PRIORITY(15) | \
 				      BCM2835_DMA_WAIT_FOR_WRITES | \
@@ -180,6 +181,11 @@ struct bcm2835_desc {
 #define WIDE_DEST(x) (((x) & BCM2835_DMA_WIDE_DEST) ? \
 		      BCM2835_DMA_D_WIDTH : 0)
 
+/* A fake bit to request that the driver requires multi-beat burst */
+#define BCM2835_DMA_BURST BIT(30)
+#define BURST_LENGTH(x) (((x) & BCM2835_DMA_BURST) ? \
+			 BCM2835_DMA_BURST_LENGTH(3) : 0)
+
 /* debug register bits */
 #define BCM2835_DMA_DEBUG_LAST_NOT_SET_ERR	BIT(0)
 #define BCM2835_DMA_DEBUG_FIFO_ERR		BIT(1)
@@ -282,7 +288,7 @@ struct bcm2835_desc {
 /* the max dma length for different channels */
 #define MAX_DMA40_LEN SZ_1G
 
-#define BCM2711_DMA40_BURST_LEN(x)	((min(x, 16) - 1) << 8)
+#define BCM2711_DMA40_BURST_LEN(x)	(((x) & 15) << 8)
 #define BCM2711_DMA40_INC		BIT(12)
 #define BCM2711_DMA40_SIZE_32		(0 << 13)
 #define BCM2711_DMA40_SIZE_64		(1 << 13)
@@ -359,12 +365,16 @@ static inline uint32_t to_bcm2711_ti(uint32_t info)
 
 static inline uint32_t to_bcm2711_srci(uint32_t info)
 {
-	return ((info & BCM2835_DMA_S_INC) ? BCM2711_DMA40_INC : 0);
+	return ((info & BCM2835_DMA_S_INC) ? BCM2711_DMA40_INC : 0) |
+	       ((info & BCM2835_DMA_S_WIDTH) ? BCM2711_DMA40_SIZE_128 : 0) |
+	       BCM2711_DMA40_BURST_LEN(BCM2835_DMA_GET_BURST_LENGTH(info));
 }
 
 static inline uint32_t to_bcm2711_dsti(uint32_t info)
 {
-	return ((info & BCM2835_DMA_D_INC) ? BCM2711_DMA40_INC : 0);
+	return ((info & BCM2835_DMA_D_INC) ? BCM2711_DMA40_INC : 0) |
+	       ((info & BCM2835_DMA_D_WIDTH) ? BCM2711_DMA40_SIZE_128 : 0) |
+	       BCM2711_DMA40_BURST_LEN(BCM2835_DMA_GET_BURST_LENGTH(info));
 }
 
 static inline uint32_t to_bcm2711_cbaddr(dma_addr_t addr)
@@ -933,7 +943,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_memcpy(
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	u32 info = BCM2835_DMA_D_INC | BCM2835_DMA_S_INC |
-		   WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) | WIDE_DEST(c->dreq);
+		   WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) |
+		   WIDE_DEST(c->dreq) | BURST_LENGTH(c->dreq);
 	u32 extra = BCM2835_DMA_INT_EN;
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 	size_t frames;
@@ -964,8 +975,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	dma_addr_t src = 0, dst = 0;
-	u32 info = WAIT_RESP(c->dreq) |
-		   WIDE_SOURCE(c->dreq) | WIDE_DEST(c->dreq);
+	u32 info = WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) |
+		   WIDE_DEST(c->dreq) | BURST_LENGTH(c->dreq);
 	u32 extra = BCM2835_DMA_INT_EN;
 	size_t frames;
 
@@ -1017,7 +1028,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
 	struct bcm2835_desc *d;
 	dma_addr_t src, dst;
-	u32 info = WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) | WIDE_DEST(c->dreq);
+	u32 info = WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) |
+		   WIDE_DEST(c->dreq) | BURST_LENGTH(c->dreq);
 	u32 extra = 0;
 	size_t max_len = bcm2835_dma_max_frame_length(c);
 	size_t frames;
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:39 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:39 +0100
Subject: [PATCH 11/12] dmaengine: bcm2835: Rename to_bcm2711_cbaddr to to_40bit_cbaddr
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <a6e1aee2e719745ead7402684df4ab0fd840cc07.1706948717.git.andrea.porta@suse.com>

From: Dom Cobley <popcornmix at gmail.com>

As the shifted address also applies to bcm2712,
give the function a more specific name.

Signed-off-by: Dom Cobley <popcornmix at gmail.com>
---
 drivers/dma/bcm2835-dma.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 055c558caa0e..40df0a165992 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -386,7 +386,7 @@ static inline uint32_t to_bcm2711_dsti(uint32_t info)
 	       BCM2711_DMA40_BURST_LEN(BCM2835_DMA_GET_BURST_LENGTH(info));
 }
 
-static inline uint32_t to_bcm2711_cbaddr(dma_addr_t addr)
+static inline uint32_t to_40bit_cbaddr(dma_addr_t addr)
 {
 	WARN_ON_ONCE(addr & 0x1f);
 	return (addr >> 5);
@@ -573,10 +573,10 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 		if (frame && c->is_40bit_channel)
 			((struct bcm2711_dma40_scb *)
 			 d->cb_list[frame - 1].cb)->next_cb =
-				to_bcm2711_cbaddr(cb_entry->paddr);
+				to_40bit_cbaddr(cb_entry->paddr);
 		if (frame && !c->is_40bit_channel)
 			d->cb_list[frame - 1].cb->next = c->is_2712 ?
-			to_bcm2711_cbaddr(cb_entry->paddr) : cb_entry->paddr;
+			to_40bit_cbaddr(cb_entry->paddr) : cb_entry->paddr;
 
 		/* update src and dst and length */
 		if (src && (info & BCM2835_DMA_S_INC)) {
@@ -751,14 +751,14 @@ static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
 	c->desc = d = to_bcm2835_dma_desc(&vd->tx);
 
 	if (c->is_40bit_channel) {
-		writel(to_bcm2711_cbaddr(d->cb_list[0].paddr),
+		writel(to_40bit_cbaddr(d->cb_list[0].paddr),
 		       c->chan_base + BCM2711_DMA40_CB);
 		writel(BCM2711_DMA40_ACTIVE | BCM2711_DMA40_PROT | BCM2711_DMA40_CS_FLAGS(c->dreq),
 		       c->chan_base + BCM2711_DMA40_CS);
 	} else {
 		writel(BIT(31), c->chan_base + BCM2835_DMA_CS);
 
-		writel(c->is_2712 ? to_bcm2711_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr,
+		writel(c->is_2712 ? to_40bit_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr,
 		       c->chan_base + BCM2835_DMA_ADDR);
 		writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
 		       c->chan_base + BCM2835_DMA_CS);
@@ -1126,10 +1126,10 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 	if (c->is_40bit_channel)
 		((struct bcm2711_dma40_scb *)
 		 d->cb_list[frames - 1].cb)->next_cb =
-			to_bcm2711_cbaddr(d->cb_list[0].paddr);
+			to_40bit_cbaddr(d->cb_list[0].paddr);
 	else
 		d->cb_list[d->frames - 1].cb->next = c->is_2712 ?
-		to_bcm2711_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr;
+		to_40bit_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr;
 
 	return vchan_tx_prep(&c->vc, &d->vd, flags);
 }
@@ -1251,7 +1251,7 @@ void bcm2711_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size)
 	scb->len = size;
 	scb->next_cb = 0;
 
-	writel(to_bcm2711_cbaddr(memcpy_scb_dma), memcpy_chan + BCM2711_DMA40_CB);
+	writel(to_40bit_cbaddr(memcpy_scb_dma), memcpy_chan + BCM2711_DMA40_CB);
 	writel(BCM2711_DMA40_MEMCPY_FLAGS | BCM2711_DMA40_ACTIVE | BCM2711_DMA40_PROT,
 	       memcpy_chan + BCM2711_DMA40_CS);
 
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:38 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:38 +0100
Subject: [PATCH 10/12] dmaengine: bcm2835: Support DMA-Lite channels
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <ca956587595954525fca0b635a66ca78b7000bf4.1706948717.git.andrea.porta@suse.com>

From: Maxime Ripard <maxime at cerno.tech>

The BCM2712 has a DMA-Lite controller that is basically a BCM2835-style
DMA controller that supports 40 bits DMA addresses.

We need it for HDMI audio to work.

Cc: Maxime Ripard <maxime at cerno.tech>
Cc: Dom Cobley <popcornmix at gmail.com>
Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 drivers/dma/bcm2835-dma.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 548cf7343d83..055c558caa0e 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -100,6 +100,7 @@ struct bcm2835_chan {
 
 	bool is_lite_channel;
 	bool is_40bit_channel;
+	bool is_2712;
 };
 
 struct bcm2835_desc {
@@ -545,7 +546,11 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 			control_block->info = info;
 			control_block->src = src;
 			control_block->dst = dst;
-			control_block->stride = 0;
+			if (c->is_2712)
+				control_block->stride = (upper_32_bits(dst) << 8) |
+							upper_32_bits(src);
+			else
+				control_block->stride = 0;
 			control_block->next = 0;
 		}
 
@@ -570,7 +575,8 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
 			 d->cb_list[frame - 1].cb)->next_cb =
 				to_bcm2711_cbaddr(cb_entry->paddr);
 		if (frame && !c->is_40bit_channel)
-			d->cb_list[frame - 1].cb->next = cb_entry->paddr;
+			d->cb_list[frame - 1].cb->next = c->is_2712 ?
+			to_bcm2711_cbaddr(cb_entry->paddr) : cb_entry->paddr;
 
 		/* update src and dst and length */
 		if (src && (info & BCM2835_DMA_S_INC)) {
@@ -750,7 +756,10 @@ static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
 		writel(BCM2711_DMA40_ACTIVE | BCM2711_DMA40_PROT | BCM2711_DMA40_CS_FLAGS(c->dreq),
 		       c->chan_base + BCM2711_DMA40_CS);
 	} else {
-		writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
+		writel(BIT(31), c->chan_base + BCM2835_DMA_CS);
+
+		writel(c->is_2712 ? to_bcm2711_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr,
+		       c->chan_base + BCM2835_DMA_ADDR);
 		writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
 		       c->chan_base + BCM2835_DMA_CS);
 	}
@@ -1119,7 +1128,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
 		 d->cb_list[frames - 1].cb)->next_cb =
 			to_bcm2711_cbaddr(d->cb_list[0].paddr);
 	else
-		d->cb_list[d->frames - 1].cb->next = d->cb_list[0].paddr;
+		d->cb_list[d->frames - 1].cb->next = c->is_2712 ?
+		to_bcm2711_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr;
 
 	return vchan_tx_prep(&c->vc, &d->vd, flags);
 }
@@ -1186,6 +1196,8 @@ static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id,
 	else if (readl(c->chan_base + BCM2835_DMA_DEBUG) &
 		 BCM2835_DMA_DEBUG_LITE)
 		c->is_lite_channel = true;
+	if (d->cfg_data->dma_mask == DMA_BIT_MASK(40))
+		c->is_2712 = true;
 
 	return 0;
 }
-- 
2.41.0



From andrea.porta at suse.com  Sat Feb  3 22:59:40 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Sun,  4 Feb 2024 07:59:40 +0100
Subject: [PATCH 12/12] bcm2835-dma: Fixes for dma_abort
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <3d0dcc017339f7a78cd9840103db75f5be4034c6.1706948717.git.andrea.porta@suse.com>

From: Dom Cobley <popcornmix at gmail.com>

There is a problem with the current abort scheme
when dma is blocked on a DREQ which prevents halting.

This is triggered by SPI driver which aborts dma
in this state and so leads to a halt timeout.

Discussion with Broadcom suggests the sequence:

CS.ACTIVE=0
while (CS.OUTSTANDING_TRANSACTIONS == 0)
  wait()
DEBUG.RESET=1

should be safe on a dma40 channel.

Unfortunately the non-dma40 channels don't have
OUTSTANDING_TRANSACTIONS, so we need a more
complicated scheme.

We attempt to abort the channel, which will work
if there is no blocked DREQ.

It it times out, we can assume there is no AXI
transfer in progress and reset anyway.

The length of the timeout is observed at ~20us.

Signed-off-by: Dom Cobley <popcornmix at gmail.com>
Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 drivers/dma/bcm2835-dma.c | 72 +++++++++++++++++++++------------------
 1 file changed, 39 insertions(+), 33 deletions(-)

diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 40df0a165992..5751d1c6ff94 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -245,6 +245,7 @@ struct bcm2835_desc {
 #define BCM2711_DMA40_ERR		BIT(10)
 #define BCM2711_DMA40_QOS(x)		(((x) & 0x1f) << 16)
 #define BCM2711_DMA40_PANIC_QOS(x)	(((x) & 0x1f) << 20)
+#define BCM2711_DMA40_TRANSACTIONS	BIT(25)
 #define BCM2711_DMA40_WAIT_FOR_WRITES	BIT(28)
 #define BCM2711_DMA40_DISDEBUG		BIT(29)
 #define BCM2711_DMA40_ABORT		BIT(30)
@@ -671,30 +672,37 @@ static void bcm2835_dma_fill_cb_chain_with_sg(
 static void bcm2835_dma_abort(struct bcm2835_chan *c)
 {
 	void __iomem *chan_base = c->chan_base;
-	long int timeout = 10000;
-
-	/*
-	 * A zero control block address means the channel is idle.
-	 * (The ACTIVE flag in the CS register is not a reliable indicator.)
-	 */
-	if (!readl(chan_base + BCM2835_DMA_ADDR))
-		return;
+	long timeout = 100;
 
 	if (c->is_40bit_channel) {
-		/* Halt the current DMA */
-		writel(readl(chan_base + BCM2711_DMA40_CS) | BCM2711_DMA40_HALT,
+		/*
+		 * A zero control block address means the channel is idle.
+		 * (The ACTIVE flag in the CS register is not a reliable indicator.)
+		 */
+		if (!readl(chan_base + BCM2711_DMA40_CB))
+			return;
+
+		/* Pause the current DMA */
+		writel(readl(chan_base + BCM2711_DMA40_CS) & ~BCM2711_DMA40_ACTIVE,
 		       chan_base + BCM2711_DMA40_CS);
 
-		while ((readl(chan_base + BCM2711_DMA40_CS) & BCM2711_DMA40_HALT) && --timeout)
+		/* wait for outstanding transactions to complete */
+		while ((readl(chan_base + BCM2711_DMA40_CS) & BCM2711_DMA40_TRANSACTIONS) &&
+		       --timeout)
 			cpu_relax();
 
-		/* Peripheral might be stuck and fail to halt */
+		/* Peripheral might be stuck and fail to complete */
 		if (!timeout)
 			dev_err(c->vc.chan.device->dev,
-				"failed to halt dma\n");
+				"failed to complete pause on dma %d (CS:%08x)\n", c->ch,
+				readl(chan_base + BCM2711_DMA40_CS));
 
+		/* Set CS back to default state */
 		writel(BCM2711_DMA40_PROT, chan_base + BCM2711_DMA40_CS);
-		writel(0, chan_base + BCM2711_DMA40_CB);
+
+		/* Reset the DMA */
+		writel(readl(chan_base + BCM2711_DMA40_DEBUG) | BCM2711_DMA40_DEBUG_RESET,
+		       chan_base + BCM2711_DMA40_DEBUG);
 	} else {
 		/*
 		 * A zero control block address means the channel is idle.
@@ -703,20 +711,6 @@ static void bcm2835_dma_abort(struct bcm2835_chan *c)
 		if (!readl(chan_base + BCM2835_DMA_ADDR))
 			return;
 
-		/* Write 0 to the active bit - Pause the DMA */
-		writel(readl(chan_base + BCM2835_DMA_CS) & ~BCM2835_DMA_ACTIVE,
-		       chan_base + BCM2835_DMA_CS);
-
-		/* wait for DMA to be paused */
-		while ((readl(chan_base + BCM2835_DMA_CS) & BCM2835_DMA_WAITING_FOR_WRITES) &&
-		       --timeout)
-			cpu_relax();
-
-		/* Peripheral might be stuck and fail to signal AXI write responses */
-		if (!timeout)
-			dev_err(c->vc.chan.device->dev,
-				"failed to pause dma\n");
-
 		/* We need to clear the next DMA block pending */
 		writel(0, chan_base + BCM2835_DMA_NEXTCB);
 
@@ -724,15 +718,27 @@ static void bcm2835_dma_abort(struct bcm2835_chan *c)
 		writel(readl(chan_base + BCM2835_DMA_CS) | BCM2835_DMA_ABORT | BCM2835_DMA_ACTIVE,
 		       chan_base + BCM2835_DMA_CS);
 
-		/* wait for DMA to have been aborted */
-		timeout = 10000;
+		/* wait for DMA to be aborted */
 		while ((readl(chan_base + BCM2835_DMA_CS) & BCM2835_DMA_ABORT) && --timeout)
 			cpu_relax();
 
-		/* Peripheral might be stuck and fail to signal AXI write responses */
-		if (!timeout)
+		/* Write 0 to the active bit - Pause the DMA */
+		writel(readl(chan_base + BCM2835_DMA_CS) & ~BCM2835_DMA_ACTIVE,
+		       chan_base + BCM2835_DMA_CS);
+
+		/*
+		 * Peripheral might be stuck and fail to complete
+		 * This is expected when dreqs are enabled but not asserted
+		 * so only report error in non dreq case
+		 */
+		if (!timeout && !(readl(chan_base + BCM2835_DMA_TI) &
+		   (BCM2835_DMA_S_DREQ | BCM2835_DMA_D_DREQ)))
 			dev_err(c->vc.chan.device->dev,
-				"failed to abort dma\n");
+				"failed to complete pause on dma %d (CS:%08x)\n", c->ch,
+				readl(chan_base + BCM2835_DMA_CS));
+
+		/* Set CS back to default state and reset the DMA */
+		writel(BCM2835_DMA_RESET, chan_base + BCM2835_DMA_CS);
 	}
 }
 
-- 
2.41.0



From masahiroy at kernel.org  Sat Feb  3 23:43:05 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Sun,  4 Feb 2024 16:43:05 +0900
Subject: [PATCH] KVM: arm64: do not source virt/lib/Kconfig twice
Message-ID: <20240204074305.31492-1-masahiroy@kernel.org>

For ARCH=arm64, virt/lib/Kconfig is sourced twice,
from arch/arm64/kvm/Kconfig and from drivers/vfio/Kconfig.
There is no good reason to parse virt/lib/Kconfig twice.

Commit 2412405b3141 ("KVM: arm/arm64: register irq bypass consumer
on ARM/ARM64") should not have added this 'source' directive.

Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
---

 arch/arm64/kvm/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6c3c8ca73e7f..27ca89b628a0 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -3,7 +3,6 @@
 # KVM configuration
 #
 
-source "virt/lib/Kconfig"
 source "virt/kvm/Kconfig"
 
 menuconfig VIRTUALIZATION
-- 
2.40.1



From yangyicong at huawei.com  Sat Feb  3 23:45:21 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Sun, 4 Feb 2024 15:45:21 +0800
Subject: [PATCH 1/7] drivers/perf: hisi_pcie: Introduce hisi_pcie_pmu_get_filter()
In-Reply-To: <20240204074527.47110-1-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
Message-ID: <20240204074527.47110-2-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Factor out retrieving of the register value for the
corresponding event from hisi_pcie_config_filter() into a
new function hisi_pcie_pmu_get_filter() allowing future reuse.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index b90ba8aca3fa..11a819cd07f2 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -216,10 +216,8 @@ static void hisi_pcie_pmu_writeq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
 	writeq_relaxed(val, pcie_pmu->base + offset);
 }
 
-static void hisi_pcie_pmu_config_filter(struct perf_event *event)
+static u64 hisi_pcie_pmu_get_filter(struct perf_event *event)
 {
-	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
-	struct hw_perf_event *hwc = &event->hw;
 	u64 port, trig_len, thr_len, len_mode;
 	u64 reg = HISI_PCIE_INIT_SET;
 
@@ -256,6 +254,15 @@ static void hisi_pcie_pmu_config_filter(struct perf_event *event)
 	else
 		reg |= FIELD_PREP(HISI_PCIE_LEN_M, HISI_PCIE_LEN_M_DEFAULT);
 
+	return reg;
+}
+
+static void hisi_pcie_pmu_config_filter(struct perf_event *event)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u64 reg = hisi_pcie_pmu_get_filter(event);
+
 	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
 }
 
-- 
2.24.0



From yangyicong at huawei.com  Sat Feb  3 23:45:20 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Sun, 4 Feb 2024 15:45:20 +0800
Subject: [PATCH 0/7] Several updates for HiSilicon PCIe PMU driver
Message-ID: <20240204074527.47110-1-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

This series mainly fix and optimize the several usage of the driver:
- Add more events to complement the TLP bandwidth counting
- Fix the wrong counting on using the event group
- Properly check the target filter to avoid invalid filter value
- Optimize the handling of related events which are not in an event group
- Update the docs

Junhao He (4):
  drivers/perf: hisi_pcie: Check the target filter properly
  drivers/perf: hisi_pcie: Relax the check on related events
  drivers/perf: hisi_pcie: Merge find_related_event() and
    get_event_idx()
  docs: perf: Update usage for target filter of hisi-pcie-pmu

Yicong Yang (3):
  drivers/perf: hisi_pcie: Introduce hisi_pcie_pmu_get_filter()
  drivers/perf: hisi_pcie: Fix incorrect counting under metric mode
  drivers/perf: hisi_pcie: Add more events for counting TLP bandwidth

 .../admin-guide/perf/hisi-pcie-pmu.rst        | 31 ++++--
 drivers/perf/hisilicon/hisi_pcie_pmu.c        | 99 ++++++++++---------
 2 files changed, 74 insertions(+), 56 deletions(-)

-- 
2.24.0



From yangyicong at huawei.com  Sat Feb  3 23:45:25 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Sun, 4 Feb 2024 15:45:25 +0800
Subject: [PATCH 5/7] drivers/perf: hisi_pcie: Relax the check on related events
In-Reply-To: <20240204074527.47110-1-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
Message-ID: <20240204074527.47110-6-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

If we use two events with the same filter and related event type
(see the following example), the driver check whether they are related
events and are in the same group, otherwise the function
hisi_pcie_pmu_find_related_event() return -EINVAL, then the 2nd event
cannot count but the 1st event is running, although the PCIe PMU has
other idle counters.

In this case, The perf event scheduler will make the two events to
multiplex a counter, if the user use the formula
(1st event_value / 2nd event_value) to calculate the bandwidth, he/she
won't get the correct value, because they are not counting at the
same period.

This patch tries to fix this by making the related events to use
different idle counters if they are not in the same event group.

And finally, I'm going to say. The related events are best used in the
same group [1]. There are two ways to know if they are related events.
a) By event name, such as the latency events "xxx_latency, xxx_cnt" or
bandwidth events "xxx_flux, xxx_time".
b) By event type, such as "event=0xXXXX, event=0x1XXXX".

Use group to count the related events:
  [1] -e "{pmu_name/xxx_latency,port=1/,pmu_name/xxx_cnt,port=1/}"

  example:
    1st event: hisi_pcie0_core1/event=0x804,port=1
    2nd event: hisi_pcie0_core1/event=0x10804,port=1

  test cmd:
    perf stata -e hisi_pcie0_core1/event=0x804,port=1/ \
               -e hisi_pcie0_core1/event=0x10804,port=1/

  before patch:
            25,281      hisi_pcie0_core1/event=0x804,port=1/    (49.91%)
           470,598      hisi_pcie0_core1/event=0x10804,port=1/    (50.09%)

  after patch:
            24,147      hisi_pcie0_core1/event=0x804,port=1/
           474,558      hisi_pcie0_core1/event=0x10804,port=1/

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index b91f03c02c57..1b45aeb82859 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -408,14 +408,10 @@ static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
 		if (!sibling)
 			continue;
 
-		if (!hisi_pcie_pmu_cmp_event(sibling, event))
-			continue;
-
 		/* Related events must be used in group */
-		if (sibling->group_leader == event->group_leader)
+		if (hisi_pcie_pmu_cmp_event(sibling, event) &&
+		    sibling->group_leader == event->group_leader)
 			return idx;
-		else
-			return -EINVAL;
 	}
 
 	return idx;
-- 
2.24.0



From yangyicong at huawei.com  Sat Feb  3 23:45:27 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Sun, 4 Feb 2024 15:45:27 +0800
Subject: [PATCH 7/7] docs: perf: Update usage for target filter of hisi-pcie-pmu
In-Reply-To: <20240204074527.47110-1-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
Message-ID: <20240204074527.47110-8-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

One of the "port" and "bdf" target filter interface must be set, and
the related events should preferably used in the same group.
Update the usage in the documentation.

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 .../admin-guide/perf/hisi-pcie-pmu.rst        | 31 ++++++++++++++-----
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
index 7e863662e2d4..c98ea4b0f0d4 100644
--- a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
+++ b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
@@ -37,9 +37,20 @@ Example usage of perf::
   hisi_pcie0_core0/rx_mwr_cnt/ [kernel PMU event]
   ------------------------------------------
 
-  $# perf stat -e hisi_pcie0_core0/rx_mwr_latency/
-  $# perf stat -e hisi_pcie0_core0/rx_mwr_cnt/
-  $# perf stat -g -e hisi_pcie0_core0/rx_mwr_latency/ -e hisi_pcie0_core0/rx_mwr_cnt/
+  $# perf stat -e hisi_pcie0_core0/rx_mwr_latency,port=0xffff/
+  $# perf stat -e hisi_pcie0_core0/rx_mwr_cnt,port=0xffff/
+
+The related events usually used to calculate the bandwidth, latency or others.
+They need to start and end counting at the same time, therefore related events
+are best used in the same event group to get the expected value. There are two
+ways to know if they are related events:
+a) By event name, such as the latency events "xxx_latency, xxx_cnt" or
+   bandwidth events "xxx_flux, xxx_time".
+b) By event type, such as "event=0xXXXX, event=0x1XXXX".
+
+Example usage of perf group::
+
+  $# perf stat -e "{hisi_pcie0_core0/rx_mwr_latency,port=0xffff/,hisi_pcie0_core0/rx_mwr_cnt,port=0xffff/}"
 
 The current driver does not support sampling. So "perf record" is unsupported.
 Also attach to a task is unsupported for PCIe PMU.
@@ -51,8 +62,12 @@ Filter options
 
    PMU could only monitor the performance of traffic downstream target Root
    Ports or downstream target Endpoint. PCIe PMU driver support "port" and
-   "bdf" interfaces for users, and these two interfaces aren't supported at the
-   same time.
+   "bdf" interfaces for users.
+   Please notice that, one of these two interfaces must be set, and can not
+   be supported at the same time. If they are both set, only "port" filter is
+   valid.
+   If "port" filter not being set or is set explicitly to zero (default), the
+   "bdf" filter will be in effect, because "bdf=0" meaning 0000:000:00.0.
 
    - port
 
@@ -95,7 +110,7 @@ Filter options
 
    Example usage of perf::
 
-     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,trig_len=0x4,trig_mode=1/ sleep 5
+     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,port=0xffff,trig_len=0x4,trig_mode=1/ sleep 5
 
 3. Threshold filter
 
@@ -109,7 +124,7 @@ Filter options
 
    Example usage of perf::
 
-     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,thr_len=0x4,thr_mode=1/ sleep 5
+     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,port=0xffff,thr_len=0x4,thr_mode=1/ sleep 5
 
 4. TLP Length filter
 
@@ -127,4 +142,4 @@ Filter options
 
    Example usage of perf::
 
-     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,len_mode=0x1/ sleep 5
+     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,port=0xffff,len_mode=0x1/ sleep 5
-- 
2.24.0



From yangyicong at huawei.com  Sat Feb  3 23:45:23 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Sun, 4 Feb 2024 15:45:23 +0800
Subject: [PATCH 3/7] drivers/perf: hisi_pcie: Add more events for counting TLP bandwidth
In-Reply-To: <20240204074527.47110-1-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
Message-ID: <20240204074527.47110-4-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

A typical PCIe transaction is consisted of various TLP packets in both
direction. For counting bandwidth only memory read events are exported
currently. Add memory write and completion counting events of both
direction to complementation.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 9623bed93876..83be3390686c 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -726,10 +726,18 @@ static struct attribute *hisi_pcie_pmu_events_attr[] = {
 	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
 	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
 	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_flux, 0x0104),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_time, 0x10104),
 	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x0804),
 	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x10804),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_cpl_flux, 0x2004),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_cpl_time, 0x12004),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_mwr_flux, 0x0105),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_mwr_time, 0x10105),
 	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x0405),
 	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x10405),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_cpl_flux, 0x1005),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_cpl_time, 0x11005),
 	NULL
 };
 
-- 
2.24.0



From yangyicong at huawei.com  Sat Feb  3 23:45:22 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Sun, 4 Feb 2024 15:45:22 +0800
Subject: [PATCH 2/7] drivers/perf: hisi_pcie: Fix incorrect counting under metric mode
In-Reply-To: <20240204074527.47110-1-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
Message-ID: <20240204074527.47110-3-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

The metric counting shows incorrect results if the events in the
metric group using the same event but different filter options.
This is because we only judge the event code to decide whether
the event in the metric group should share the same hardware
counter, but ignore the settings of the filter.

For example, on a platform of 2 ports 0x1 and 0x2 but only port
0x1 has a downstream PCIe NVME device. The metric counting
shows both ports have the same counts because we misassign these
two events to one same hardware counter:
[root at localhost perf-iostat]# ./perf stat -e '{hisi_pcie0_core1/event=0x0104,port=0x2/,hisi_pcie0_core1/event=0x0104,port=0x1/}'

 Performance counter stats for 'system wide':

        7907484924      hisi_pcie0_core1/event=0x0104,port=0x2/
        7907484924      hisi_pcie0_core1/event=0x0104,port=0x1/

      10.153863691 seconds time elapsed

Fix this by using the whole config rather than the event only
to judge whether two events are the same and should share the
same hardware counter. With this patch, the metric counting in
the above case tends to be corrected:

[root at localhost perf-iostat]# ./perf stat -e '{hisi_pcie0_core1/event=0x0104,port=0x2/,hisi_pcie0_core1/event=0x0104,port=0x1/}'

 Performance counter stats for 'system wide':

                 0      hisi_pcie0_core1/event=0x0104,port=0x2/
        8123122077      hisi_pcie0_core1/event=0x0104,port=0x1/

      10.152875631 seconds time elapsed

Fixes: 8404b0fbc7fb ("drivers/perf: hisi: Add driver for HiSilicon PCIe PMU")
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 11a819cd07f2..9623bed93876 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -314,10 +314,15 @@ static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
 	return true;
 }
 
+/*
+ * Check Whether two events share the same config. The same config means not
+ * only the event code, but also the filter settings of the two events are
+ * the same.
+ */
 static bool hisi_pcie_pmu_cmp_event(struct perf_event *target,
 					struct perf_event *event)
 {
-	return hisi_pcie_get_real_event(target) == hisi_pcie_get_real_event(event);
+	return hisi_pcie_pmu_get_filter(target) == hisi_pcie_pmu_get_filter(event);
 }
 
 static bool hisi_pcie_pmu_validate_event_group(struct perf_event *event)
-- 
2.24.0



From yangyicong at huawei.com  Sat Feb  3 23:45:24 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Sun, 4 Feb 2024 15:45:24 +0800
Subject: [PATCH 4/7] drivers/perf: hisi_pcie: Check the target filter properly
In-Reply-To: <20240204074527.47110-1-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
Message-ID: <20240204074527.47110-5-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

The PMU can monitor traffic of certain target Root Port or downstream
target Endpoint. User can specify the target filter by the "port" or
"bdf" option respectively. The PMU can only monitor the Root Port or
Endpoint on the same PCIe core so the value of "port" or "bdf" should
be valid and will be checked by the driver.

Currently at least and only one of "port" and "bdf" option must be set.
If "port" filter is not set or is set explicitly to zero (default),
driver will regard the user specifies a "bdf" option since "port" option
is a bitmask of the target Root Ports and zero is not a valid
value.

If user not explicitly set "port" or "bdf" filter, the driver uses "bdf"
default value (zero) to set target filter, but driver will skip the
check of bdf=0, although it's a valid value (meaning 0000:000:00.0).
Then the user just gets zero.

Therefore, we need to check if both "port" and "bdf" are invalid, then
return failure and report warning.

Testing:
before the patch:
                   0      hisi_pcie0_core1/rx_mrd_flux/
                   0      hisi_pcie0_core1/rx_mrd_flux,port=0/
              24,124      hisi_pcie0_core1/rx_mrd_flux,port=1/
                   0      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/

after the patch:
     <not supported>      hisi_pcie0_core1/rx_mrd_flux/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,port=0/
              24,153      hisi_pcie0_core1/rx_mrd_flux,port=1/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 83be3390686c..b91f03c02c57 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -306,10 +306,10 @@ static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
 	if (hisi_pcie_get_trig_len(event) > HISI_PCIE_TRIG_MAX_VAL)
 		return false;
 
-	if (requester_id) {
-		if (!hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
-			return false;
-	}
+	/* Need to explicitly set filter of "port" or "bdf" */
+	if (!hisi_pcie_get_port(event) &&
+	    !hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
+		return false;
 
 	return true;
 }
-- 
2.24.0



From yangyicong at huawei.com  Sat Feb  3 23:45:26 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Sun, 4 Feb 2024 15:45:26 +0800
Subject: [PATCH 6/7] drivers/perf: hisi_pcie: Merge find_related_event() and get_event_idx()
In-Reply-To: <20240204074527.47110-1-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
Message-ID: <20240204074527.47110-7-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

The function xxx_find_related_event() scan all working events to find
related events. During this process, we also can find the idle counters.
If not found related events, return the first idle counter to simplify
the code.

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 55 ++++++++++----------------
 1 file changed, 21 insertions(+), 34 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 1b45aeb82859..2edde66675e7 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -397,16 +397,24 @@ static u64 hisi_pcie_pmu_read_counter(struct perf_event *event)
 	return hisi_pcie_pmu_readq(pcie_pmu, event->hw.event_base, idx);
 }
 
-static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
-					    struct perf_event *event)
+/*
+ * Check all work events, if a relevant event is found then we return it
+ * first, otherwise return the first idle counter (need to reset).
+ */
+static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu,
+					struct perf_event *event)
 {
+	int first_idle = HISI_PCIE_MAX_COUNTERS;
 	struct perf_event *sibling;
 	int idx;
 
 	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
 		sibling = pcie_pmu->hw_events[idx];
-		if (!sibling)
+		if (!sibling) {
+			if (first_idle == HISI_PCIE_MAX_COUNTERS)
+				first_idle = idx;
 			continue;
+		}
 
 		/* Related events must be used in group */
 		if (hisi_pcie_pmu_cmp_event(sibling, event) &&
@@ -414,19 +422,7 @@ static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
 			return idx;
 	}
 
-	return idx;
-}
-
-static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu)
-{
-	int idx;
-
-	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
-		if (!pcie_pmu->hw_events[idx])
-			return idx;
-	}
-
-	return -EINVAL;
+	return first_idle;
 }
 
 static void hisi_pcie_pmu_event_update(struct perf_event *event)
@@ -552,27 +548,18 @@ static int hisi_pcie_pmu_add(struct perf_event *event, int flags)
 
 	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
 
-	/* Check all working events to find a related event. */
-	idx = hisi_pcie_pmu_find_related_event(pcie_pmu, event);
-	if (idx < 0)
-		return idx;
-
-	/* Current event shares an enabled counter with the related event */
-	if (idx < HISI_PCIE_MAX_COUNTERS) {
-		hwc->idx = idx;
-		goto start_count;
-	}
-
-	idx = hisi_pcie_pmu_get_event_idx(pcie_pmu);
-	if (idx < 0)
-		return idx;
+	idx = hisi_pcie_pmu_get_event_idx(pcie_pmu, event);
+	if (idx == HISI_PCIE_MAX_COUNTERS)
+		return -EAGAIN;
 
 	hwc->idx = idx;
-	pcie_pmu->hw_events[idx] = event;
-	/* Reset Counter to avoid previous statistic interference. */
-	hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
 
-start_count:
+	/* No enabled counter found with related event, reset it */
+	if (!pcie_pmu->hw_events[idx]) {
+		hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
+		pcie_pmu->hw_events[idx] = event;
+	}
+
 	if (flags & PERF_EF_START)
 		hisi_pcie_pmu_start(event, PERF_EF_RELOAD);
 
-- 
2.24.0



From yilun.xu at linux.intel.com  Sun Feb  4 00:10:57 2024
From: yilun.xu at linux.intel.com (Xu Yilun)
Date: Sun, 4 Feb 2024 16:10:57 +0800
Subject: [PATCH 3/3] fpga: xilinx-selectmap: add new driver
In-Reply-To: <20240131230542.3993409-4-charles.perry@savoirfairelinux.com>
References: <20240129225602.3832449-1-charles.perry@savoirfairelinux.com>
 <20240131230542.3993409-1-charles.perry@savoirfairelinux.com>
 <20240131230542.3993409-4-charles.perry@savoirfairelinux.com>
Message-ID: <Zb9GkY6cMtR+4xOX@yilunxu-OptiPlex-7050>

On Wed, Jan 31, 2024 at 06:05:33PM -0500, Charles Perry wrote:
> Xilinx 7 series FPGA can be programmed using a slave parallel port named
> the SelectMAP interface in the datasheet. This slave interface is
> compatible with the i.MX6 EIM bus controller but other types of external
> memory mapped parallel bus might work.
> 
> xilinx-selectmap currently only supports the x8 mode where data is loaded
> at one byte per rising edge of the clock, with the MSb of each byte
> presented to the D0 pin.
> 
> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
> ---
>  drivers/fpga/Kconfig            |   8 +++
>  drivers/fpga/Makefile           |   1 +
>  drivers/fpga/xilinx-core.c      |  11 +++-
>  drivers/fpga/xilinx-core.h      |   3 +-
>  drivers/fpga/xilinx-selectmap.c | 106 ++++++++++++++++++++++++++++++++
>  drivers/fpga/xilinx-spi.c       |   3 +-
>  6 files changed, 127 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/fpga/xilinx-selectmap.c
> 
> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
> index d27a1ebf40838..37b35f58f0dfb 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -67,6 +67,14 @@ config FPGA_MGR_STRATIX10_SOC
>  config FPGA_MGR_XILINX_CORE
>  	tristate
>  
> +config FPGA_MGR_XILINX_SELECTMAP
> +	tristate "Xilinx Configuration over SelectMAP"
> +	depends on HAS_IOMEM
> +	select FPGA_MGR_XILINX_CORE
> +	help
> +	  FPGA manager driver support for Xilinx FPGA configuration
> +	  over SelectMAP interface.
> +
>  config FPGA_MGR_XILINX_SPI
>  	tristate "Xilinx Configuration over Slave Serial (SPI)"
>  	depends on SPI
> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
> index 7ec795b6a5a70..aeb89bb13517e 100644
> --- a/drivers/fpga/Makefile
> +++ b/drivers/fpga/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
>  obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC)	+= stratix10-soc.o
>  obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
>  obj-$(CONFIG_FPGA_MGR_XILINX_CORE)	+= xilinx-core.o
> +obj-$(CONFIG_FPGA_MGR_XILINX_SELECTMAP)	+= xilinx-selectmap.o
>  obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
>  obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
>  obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA)	+= zynqmp-fpga.o
> diff --git a/drivers/fpga/xilinx-core.c b/drivers/fpga/xilinx-core.c
> index aff40e9394085..64117759be100 100644
> --- a/drivers/fpga/xilinx-core.c
> +++ b/drivers/fpga/xilinx-core.c
> @@ -180,21 +180,26 @@ static const struct fpga_manager_ops xilinx_core_ops = {
>  
>  int xilinx_core_probe(struct xilinx_fpga_core *core, struct device *dev,
>  		      xilinx_write_func write,
> -		      xilinx_write_one_dummy_byte_func write_one_dummy_byte)
> +		      xilinx_write_one_dummy_byte_func write_one_dummy_byte,
> +		      const char *prog_con_id, const char *init_con_id)

These gpio name inputs are not necessary except for DTS format concern.
Is it possible we don't change the names?

>  {
>  	struct fpga_manager *mgr;
>  
> +	if (!core || !dev || !write || !write_one_dummy_byte || !prog_con_id ||
> +	    !init_con_id)
> +		return -EINVAL;

These checks belong to Patch #1.

> +
>  	core->dev = dev;
>  	core->write = write;
>  	core->write_one_dummy_byte = write_one_dummy_byte;
>  
>  	/* PROGRAM_B is active low */
> -	core->prog_b = devm_gpiod_get(dev, "prog_b", GPIOD_OUT_LOW);
> +	core->prog_b = devm_gpiod_get(dev, prog_con_id, GPIOD_OUT_LOW);
>  	if (IS_ERR(core->prog_b))
>  		return dev_err_probe(dev, PTR_ERR(core->prog_b),
>  				     "Failed to get PROGRAM_B gpio\n");
>  
> -	core->init_b = devm_gpiod_get_optional(dev, "init-b", GPIOD_IN);
> +	core->init_b = devm_gpiod_get_optional(dev, init_con_id, GPIOD_IN);
>  	if (IS_ERR(core->init_b))
>  		return dev_err_probe(dev, PTR_ERR(core->init_b),
>  				     "Failed to get INIT_B gpio\n");
> diff --git a/drivers/fpga/xilinx-core.h b/drivers/fpga/xilinx-core.h
> index 40e120945ba70..817f0e551d093 100644
> --- a/drivers/fpga/xilinx-core.h
> +++ b/drivers/fpga/xilinx-core.h
> @@ -22,6 +22,7 @@ struct xilinx_fpga_core {
>  
>  int xilinx_core_probe(struct xilinx_fpga_core *core, struct device *dev,
>  		      xilinx_write_func write,
> -		      xilinx_write_one_dummy_byte_func write_one_dummy_byte);
> +		      xilinx_write_one_dummy_byte_func write_one_dummy_byte,
> +		      const char *prog_con_id, const char *init_con_id);
>  
>  #endif /* __XILINX_CORE_H */
> diff --git a/drivers/fpga/xilinx-selectmap.c b/drivers/fpga/xilinx-selectmap.c
> new file mode 100644
> index 0000000000000..08054e19bb498
> --- /dev/null
> +++ b/drivers/fpga/xilinx-selectmap.c
> @@ -0,0 +1,106 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Xilinx Spartan6 and 7 Series SelectMAP interface driver
> + *
> + * (C) 2024 Charles Perry <charles.perry at savoirfairelinux.com>
> + *
> + * Manage Xilinx FPGA firmware loaded over the SelectMAP configuration
> + * interface.
> + */
> +
> +#include "xilinx-core.h"
> +
> +#include <linux/platform_device.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/of.h>
> +#include <linux/io.h>
> +
> +struct xilinx_selectmap_conf {
> +	struct xilinx_fpga_core core;
> +	void __iomem *base;
> +	struct gpio_desc *csi_b;
> +	struct gpio_desc *rdwr_b;

These 2 gpio_desc are not used globally, maybe remove them here.

> +};
> +
> +#define to_xilinx_selectmap_conf(obj) \
> +	container_of(obj, struct xilinx_selectmap_conf, core)
> +
> +static int xilinx_selectmap_write(struct xilinx_fpga_core *core,
> +				  const char *buf, size_t count)
> +{
> +	struct xilinx_selectmap_conf *conf = to_xilinx_selectmap_conf(core);
> +	u32 i;
> +
> +	for (i = 0; i < count; ++i)
> +		writeb(buf[i], conf->base);
> +
> +	return 0;
> +}
> +
> +static int xilinx_selectmap_apply_padding(struct xilinx_fpga_core *core)
> +{
> +	struct xilinx_selectmap_conf *conf = to_xilinx_selectmap_conf(core);
> +
> +	writeb(0xFF, conf->base);

Seems only one callback needed. Just use write() to xfer 1 byte?

Thanks,
Yilun

> +	return 0;
> +}
> +
> +static int xilinx_selectmap_probe(struct platform_device *pdev)
> +{
> +	struct xilinx_selectmap_conf *conf;
> +	struct resource *r;
> +	void __iomem *base;
> +
> +	conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL);
> +	if (!conf)
> +		return -ENOMEM;
> +
> +	base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
> +	if (IS_ERR(base))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(base),
> +				     "ioremap error\n");
> +	conf->base = base;
> +
> +	/* CSI_B is active low */
> +	conf->csi_b =
> +		devm_gpiod_get_optional(&pdev->dev, "csi", GPIOD_OUT_HIGH);
> +	if (IS_ERR(conf->csi_b))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(conf->csi_b),
> +				     "Failed to get CSI_B gpio\n");
> +
> +	/* RDWR_B is active low */
> +	conf->rdwr_b =
> +		devm_gpiod_get_optional(&pdev->dev, "rdwr", GPIOD_OUT_HIGH);
> +	if (IS_ERR(conf->rdwr_b))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(conf->rdwr_b),
> +				     "Failed to get RDWR_B gpio\n");
> +
> +	return xilinx_core_probe(&conf->core, &pdev->dev,
> +				 xilinx_selectmap_write,
> +				 xilinx_selectmap_apply_padding, "prog",
> +				 "init");
> +}
> +
> +static const struct of_device_id xlnx_selectmap_of_match[] = {
> +	{
> +		.compatible = "xlnx,fpga-selectmap",
> +	},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, xlnx_selectmap_of_match);
> +
> +static struct platform_driver xilinx_selectmap_driver = {
> +	.driver = {
> +		.name = "xilinx-selectmap",
> +		.of_match_table = xlnx_selectmap_of_match,
> +	},
> +	.probe  = xilinx_selectmap_probe,
> +};
> +
> +module_platform_driver(xilinx_selectmap_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Charles Perry <charles.perry at savoirfairelinux.com>");
> +MODULE_DESCRIPTION("Load Xilinx FPGA firmware over SelectMap");
> diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c
> index ec128dee97312..b9ab3d5da004c 100644
> --- a/drivers/fpga/xilinx-spi.c
> +++ b/drivers/fpga/xilinx-spi.c
> @@ -74,7 +74,8 @@ static int xilinx_spi_probe(struct spi_device *spi)
>  	conf->spi = spi;
>  
>  	return xilinx_core_probe(&conf->core, &spi->dev, xilinx_spi_write,
> -				 xilinx_spi_apply_cclk_cycles);
> +				 xilinx_spi_apply_cclk_cycles, "prog_b",
> +				 "init-b");
>  }
>  
>  #ifdef CONFIG_OF
> -- 
> 2.43.0
> 
> 


From yilun.xu at linux.intel.com  Sun Feb  4 00:22:40 2024
From: yilun.xu at linux.intel.com (Xu Yilun)
Date: Sun, 4 Feb 2024 16:22:40 +0800
Subject: [PATCH 1/3] fpga: xilinx-spi: extract a common driver core
In-Reply-To: <20240131230542.3993409-2-charles.perry@savoirfairelinux.com>
References: <20240129225602.3832449-1-charles.perry@savoirfairelinux.com>
 <20240131230542.3993409-1-charles.perry@savoirfairelinux.com>
 <20240131230542.3993409-2-charles.perry@savoirfairelinux.com>
Message-ID: <Zb9JUMcGkbbPXPcE@yilunxu-OptiPlex-7050>

On Wed, Jan 31, 2024 at 06:05:31PM -0500, Charles Perry wrote:
> Factor out the gpio handshaking (using PROGRAM_B, INIT_B and DONE)
> protocol in xilinx-core so that it can be reused for another driver.
> This commit does not change anything functionally to xilinx-spi.
> 
> xilinx-core expects drivers to provide two operations:
> 
>  * ->write(const char* buf, size_t count): write to the device
>  * ->write_one_dummy_byte(): write 0xFF to the device
> 
> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
> ---
>  drivers/fpga/Kconfig       |   4 +
>  drivers/fpga/Makefile      |   1 +
>  drivers/fpga/xilinx-core.c | 210 +++++++++++++++++++++++++++++++++++++
>  drivers/fpga/xilinx-core.h |  27 +++++
>  drivers/fpga/xilinx-spi.c  | 204 +++--------------------------------
>  5 files changed, 257 insertions(+), 189 deletions(-)
>  create mode 100644 drivers/fpga/xilinx-core.c
>  create mode 100644 drivers/fpga/xilinx-core.h
> 
> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
> index 2f689ac4ba3a3..d27a1ebf40838 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -64,9 +64,13 @@ config FPGA_MGR_STRATIX10_SOC
>  	help
>  	  FPGA manager driver support for the Intel Stratix10 SoC.
>  
> +config FPGA_MGR_XILINX_CORE
> +	tristate
> +
>  config FPGA_MGR_XILINX_SPI
>  	tristate "Xilinx Configuration over Slave Serial (SPI)"
>  	depends on SPI
> +	select FPGA_MGR_XILINX_CORE
>  	help
>  	  FPGA manager driver support for Xilinx FPGA configuration
>  	  over slave serial interface.
> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
> index 352a2612623e0..7ec795b6a5a70 100644
> --- a/drivers/fpga/Makefile
> +++ b/drivers/fpga/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
>  obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
>  obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC)	+= stratix10-soc.o
>  obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
> +obj-$(CONFIG_FPGA_MGR_XILINX_CORE)	+= xilinx-core.o
>  obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
>  obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
>  obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA)	+= zynqmp-fpga.o
> diff --git a/drivers/fpga/xilinx-core.c b/drivers/fpga/xilinx-core.c
> new file mode 100644
> index 0000000000000..aff40e9394085
> --- /dev/null
> +++ b/drivers/fpga/xilinx-core.c
> @@ -0,0 +1,210 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Common parts of the Xilinx Spartan6 and 7 Series FPGA manager drivers.
> + *
> + * Copyright (C) 2017 DENX Software Engineering
> + *
> + * Anatolij Gustschin <agust at denx.de>
> + */
> +
> +#include "xilinx-core.h"
> +
> +#include <linux/delay.h>
> +#include <linux/fpga/fpga-mgr.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/of.h>
> +
> +static int get_done_gpio(struct fpga_manager *mgr)
> +{
> +	struct xilinx_fpga_core *core = mgr->priv;
> +	int ret;
> +
> +	ret = gpiod_get_value(core->done);
> +

remove the line.

> +	if (ret < 0)
> +		dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret);
> +
> +	return ret;
> +}
> +
> +static enum fpga_mgr_states xilinx_core_state(struct fpga_manager *mgr)
> +{
> +	if (!get_done_gpio(mgr))
> +		return FPGA_MGR_STATE_RESET;
> +
> +	return FPGA_MGR_STATE_UNKNOWN;
> +}
> +
> +/**
> + * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
> + * a given delay if the pin is unavailable
> + *
> + * @mgr:        The FPGA manager object
> + * @value:      Value INIT_B to wait for (1 = asserted = low)
> + * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
> + *
> + * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
> + * too much time passed waiting for that. If no INIT_B GPIO is available
> + * then always return 0.
> + */
> +static int wait_for_init_b(struct fpga_manager *mgr, int value,
> +			   unsigned long alt_udelay)
> +{
> +	struct xilinx_fpga_core *core = mgr->priv;
> +	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
> +
> +	if (core->init_b) {
> +		while (time_before(jiffies, timeout)) {
> +			int ret = gpiod_get_value(core->init_b);
> +
> +			if (ret == value)
> +				return 0;
> +
> +			if (ret < 0) {
> +				dev_err(&mgr->dev,
> +					"Error reading INIT_B (%d)\n", ret);
> +				return ret;
> +			}
> +
> +			usleep_range(100, 400);
> +		}
> +
> +		dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n",
> +			value ? "assert" : "deassert");
> +		return -ETIMEDOUT;
> +	}
> +
> +	udelay(alt_udelay);
> +
> +	return 0;
> +}
> +
> +static int xilinx_core_write_init(struct fpga_manager *mgr,
> +				  struct fpga_image_info *info, const char *buf,
> +				  size_t count)
> +{
> +	struct xilinx_fpga_core *core = mgr->priv;
> +	int err;
> +
> +	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
> +		dev_err(&mgr->dev, "Partial reconfiguration not supported\n");
> +		return -EINVAL;
> +	}
> +
> +	gpiod_set_value(core->prog_b, 1);
> +
> +	err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */
> +	if (err) {
> +		gpiod_set_value(core->prog_b, 0);
> +		return err;
> +	}
> +
> +	gpiod_set_value(core->prog_b, 0);
> +
> +	err = wait_for_init_b(mgr, 0, 0);
> +	if (err)
> +		return err;
> +
> +	if (get_done_gpio(mgr)) {
> +		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
> +		return -EIO;
> +	}
> +
> +	/* program latency */
> +	usleep_range(7500, 7600);
> +	return 0;
> +}
> +
> +static int xilinx_core_write(struct fpga_manager *mgr, const char *buf,
> +			     size_t count)
> +{
> +	struct xilinx_fpga_core *core = mgr->priv;
> +
> +	return core->write(core, buf, count);
> +}
> +
> +static int xilinx_core_write_complete(struct fpga_manager *mgr,
> +				      struct fpga_image_info *info)
> +{
> +	struct xilinx_fpga_core *core = mgr->priv;
> +	unsigned long timeout =
> +		jiffies + usecs_to_jiffies(info->config_complete_timeout_us);
> +	bool expired = false;
> +	int done;
> +	int ret;
> +
> +	/*
> +	 * This loop is carefully written such that if the driver is
> +	 * scheduled out for more than 'timeout', we still check for DONE
> +	 * before giving up and we apply 8 extra CCLK cycles in all cases.
> +	 */
> +	while (!expired) {
> +		expired = time_after(jiffies, timeout);
> +
> +		done = get_done_gpio(mgr);
> +		if (done < 0)
> +			return done;
> +
> +		ret = core->write_one_dummy_byte(core);
> +		if (ret)
> +			return ret;
> +
> +		if (done)
> +			return 0;
> +	}
> +
> +	if (core->init_b) {
> +		ret = gpiod_get_value(core->init_b);
> +
> +		if (ret < 0) {
> +			dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
> +			return ret;
> +		}
> +
> +		dev_err(&mgr->dev,
> +			ret ? "CRC error or invalid device\n" :
> +			      "Missing sync word or incomplete bitstream\n");
> +	} else {
> +		dev_err(&mgr->dev, "Timeout after config data transfer\n");
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static const struct fpga_manager_ops xilinx_core_ops = {
> +	.state = xilinx_core_state,
> +	.write_init = xilinx_core_write_init,
> +	.write = xilinx_core_write,
> +	.write_complete = xilinx_core_write_complete,
> +};
> +
> +int xilinx_core_probe(struct xilinx_fpga_core *core, struct device *dev,
> +		      xilinx_write_func write,
> +		      xilinx_write_one_dummy_byte_func write_one_dummy_byte)

I prefer to move these parameters in xilinx_fpga_core structure. I don't
want the param list becomes longer and longer when we have more inputs.

> +{
> +	struct fpga_manager *mgr;
> +
> +	core->dev = dev;
> +	core->write = write;
> +	core->write_one_dummy_byte = write_one_dummy_byte;

Could the write() writes one dummy byte? Maybe one write callback is enough.

> +
> +	/* PROGRAM_B is active low */
> +	core->prog_b = devm_gpiod_get(dev, "prog_b", GPIOD_OUT_LOW);
> +	if (IS_ERR(core->prog_b))
> +		return dev_err_probe(dev, PTR_ERR(core->prog_b),
> +				     "Failed to get PROGRAM_B gpio\n");
> +
> +	core->init_b = devm_gpiod_get_optional(dev, "init-b", GPIOD_IN);
> +	if (IS_ERR(core->init_b))
> +		return dev_err_probe(dev, PTR_ERR(core->init_b),
> +				     "Failed to get INIT_B gpio\n");
> +
> +	core->done = devm_gpiod_get(dev, "done", GPIOD_IN);
> +	if (IS_ERR(core->done))
> +		return dev_err_probe(dev, PTR_ERR(core->done),
> +				     "Failed to get DONE gpio\n");
> +
> +	mgr = devm_fpga_mgr_register(dev, "Xilinx Slave Serial FPGA Manager",
> +				     &xilinx_core_ops, core);
> +	return PTR_ERR_OR_ZERO(mgr);
> +}
> diff --git a/drivers/fpga/xilinx-core.h b/drivers/fpga/xilinx-core.h
> new file mode 100644
> index 0000000000000..40e120945ba70
> --- /dev/null
> +++ b/drivers/fpga/xilinx-core.h
> @@ -0,0 +1,27 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __XILINX_CORE_H
> +#define __XILINX_CORE_H
> +
> +#include <linux/device.h>
> +
> +struct xilinx_fpga_core;
> +
> +typedef int (*xilinx_write_func)(struct xilinx_fpga_core *core, const char *buf,
> +				 size_t count);
> +typedef int (*xilinx_write_one_dummy_byte_func)(struct xilinx_fpga_core *core);

No need to typedef.

Thanks,
Yilun

> +
> +struct xilinx_fpga_core {
> +	struct device *dev;
> +	xilinx_write_func write;
> +	xilinx_write_one_dummy_byte_func write_one_dummy_byte;
> +	struct gpio_desc *prog_b;
> +	struct gpio_desc *init_b;
> +	struct gpio_desc *done;
> +};
> +
> +int xilinx_core_probe(struct xilinx_fpga_core *core, struct device *dev,
> +		      xilinx_write_func write,
> +		      xilinx_write_one_dummy_byte_func write_one_dummy_byte);
> +
> +#endif /* __XILINX_CORE_H */
> diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c
> index e1a227e7ff2ae..ec128dee97312 100644
> --- a/drivers/fpga/xilinx-spi.c
> +++ b/drivers/fpga/xilinx-spi.c
> @@ -10,127 +10,24 @@
>   * the slave serial configuration interface.
>   */
>  
> -#include <linux/delay.h>
> -#include <linux/device.h>
> -#include <linux/fpga/fpga-mgr.h>
> -#include <linux/gpio/consumer.h>
> +#include "xilinx-core.h"
> +
>  #include <linux/module.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/of.h>
>  #include <linux/spi/spi.h>
> -#include <linux/sizes.h>
>  
>  struct xilinx_spi_conf {
> +	struct xilinx_fpga_core core;
>  	struct spi_device *spi;
> -	struct gpio_desc *prog_b;
> -	struct gpio_desc *init_b;
> -	struct gpio_desc *done;
>  };
>  
> -static int get_done_gpio(struct fpga_manager *mgr)
> -{
> -	struct xilinx_spi_conf *conf = mgr->priv;
> -	int ret;
> -
> -	ret = gpiod_get_value(conf->done);
> -
> -	if (ret < 0)
> -		dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret);
> -
> -	return ret;
> -}
> -
> -static enum fpga_mgr_states xilinx_spi_state(struct fpga_manager *mgr)
> -{
> -	if (!get_done_gpio(mgr))
> -		return FPGA_MGR_STATE_RESET;
> -
> -	return FPGA_MGR_STATE_UNKNOWN;
> -}
> -
> -/**
> - * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
> - * a given delay if the pin is unavailable
> - *
> - * @mgr:        The FPGA manager object
> - * @value:      Value INIT_B to wait for (1 = asserted = low)
> - * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
> - *
> - * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
> - * too much time passed waiting for that. If no INIT_B GPIO is available
> - * then always return 0.
> - */
> -static int wait_for_init_b(struct fpga_manager *mgr, int value,
> -			   unsigned long alt_udelay)
> -{
> -	struct xilinx_spi_conf *conf = mgr->priv;
> -	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
> -
> -	if (conf->init_b) {
> -		while (time_before(jiffies, timeout)) {
> -			int ret = gpiod_get_value(conf->init_b);
> -
> -			if (ret == value)
> -				return 0;
> -
> -			if (ret < 0) {
> -				dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
> -				return ret;
> -			}
> -
> -			usleep_range(100, 400);
> -		}
> -
> -		dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n",
> -			value ? "assert" : "deassert");
> -		return -ETIMEDOUT;
> -	}
> -
> -	udelay(alt_udelay);
> -
> -	return 0;
> -}
> -
> -static int xilinx_spi_write_init(struct fpga_manager *mgr,
> -				 struct fpga_image_info *info,
> -				 const char *buf, size_t count)
> -{
> -	struct xilinx_spi_conf *conf = mgr->priv;
> -	int err;
> -
> -	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
> -		dev_err(&mgr->dev, "Partial reconfiguration not supported\n");
> -		return -EINVAL;
> -	}
> -
> -	gpiod_set_value(conf->prog_b, 1);
> +#define to_xilinx_spi_conf(obj) container_of(obj, struct xilinx_spi_conf, core)
>  
> -	err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */
> -	if (err) {
> -		gpiod_set_value(conf->prog_b, 0);
> -		return err;
> -	}
> -
> -	gpiod_set_value(conf->prog_b, 0);
> -
> -	err = wait_for_init_b(mgr, 0, 0);
> -	if (err)
> -		return err;
> -
> -	if (get_done_gpio(mgr)) {
> -		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
> -		return -EIO;
> -	}
> -
> -	/* program latency */
> -	usleep_range(7500, 7600);
> -	return 0;
> -}
> -
> -static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
> +static int xilinx_spi_write(struct xilinx_fpga_core *core, const char *buf,
>  			    size_t count)
>  {
> -	struct xilinx_spi_conf *conf = mgr->priv;
> +	struct xilinx_spi_conf *conf = to_xilinx_spi_conf(core);
>  	const char *fw_data = buf;
>  	const char *fw_data_end = fw_data + count;
>  
> @@ -143,7 +40,7 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
>  
>  		ret = spi_write(conf->spi, fw_data, stride);
>  		if (ret) {
> -			dev_err(&mgr->dev, "SPI error in firmware write: %d\n",
> +			dev_err(core->dev, "SPI error in firmware write: %d\n",
>  				ret);
>  			return ret;
>  		}
> @@ -153,77 +50,22 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
>  	return 0;
>  }
>  
> -static int xilinx_spi_apply_cclk_cycles(struct xilinx_spi_conf *conf)
> +static int xilinx_spi_apply_cclk_cycles(struct xilinx_fpga_core *core)
>  {
> -	struct spi_device *spi = conf->spi;
> +	struct xilinx_spi_conf *conf = to_xilinx_spi_conf(core);
>  	const u8 din_data[1] = { 0xff };
>  	int ret;
>  
>  	ret = spi_write(conf->spi, din_data, sizeof(din_data));
>  	if (ret)
> -		dev_err(&spi->dev, "applying CCLK cycles failed: %d\n", ret);
> +		dev_err(core->dev, "applying CCLK cycles failed: %d\n", ret);
>  
>  	return ret;
>  }
>  
> -static int xilinx_spi_write_complete(struct fpga_manager *mgr,
> -				     struct fpga_image_info *info)
> -{
> -	struct xilinx_spi_conf *conf = mgr->priv;
> -	unsigned long timeout = jiffies + usecs_to_jiffies(info->config_complete_timeout_us);
> -	bool expired = false;
> -	int done;
> -	int ret;
> -
> -	/*
> -	 * This loop is carefully written such that if the driver is
> -	 * scheduled out for more than 'timeout', we still check for DONE
> -	 * before giving up and we apply 8 extra CCLK cycles in all cases.
> -	 */
> -	while (!expired) {
> -		expired = time_after(jiffies, timeout);
> -
> -		done = get_done_gpio(mgr);
> -		if (done < 0)
> -			return done;
> -
> -		ret = xilinx_spi_apply_cclk_cycles(conf);
> -		if (ret)
> -			return ret;
> -
> -		if (done)
> -			return 0;
> -	}
> -
> -	if (conf->init_b) {
> -		ret = gpiod_get_value(conf->init_b);
> -
> -		if (ret < 0) {
> -			dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
> -			return ret;
> -		}
> -
> -		dev_err(&mgr->dev,
> -			ret ? "CRC error or invalid device\n"
> -			: "Missing sync word or incomplete bitstream\n");
> -	} else {
> -		dev_err(&mgr->dev, "Timeout after config data transfer\n");
> -	}
> -
> -	return -ETIMEDOUT;
> -}
> -
> -static const struct fpga_manager_ops xilinx_spi_ops = {
> -	.state = xilinx_spi_state,
> -	.write_init = xilinx_spi_write_init,
> -	.write = xilinx_spi_write,
> -	.write_complete = xilinx_spi_write_complete,
> -};
> -
>  static int xilinx_spi_probe(struct spi_device *spi)
>  {
>  	struct xilinx_spi_conf *conf;
> -	struct fpga_manager *mgr;
>  
>  	conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL);
>  	if (!conf)
> @@ -231,31 +73,15 @@ static int xilinx_spi_probe(struct spi_device *spi)
>  
>  	conf->spi = spi;
>  
> -	/* PROGRAM_B is active low */
> -	conf->prog_b = devm_gpiod_get(&spi->dev, "prog_b", GPIOD_OUT_LOW);
> -	if (IS_ERR(conf->prog_b))
> -		return dev_err_probe(&spi->dev, PTR_ERR(conf->prog_b),
> -				     "Failed to get PROGRAM_B gpio\n");
> -
> -	conf->init_b = devm_gpiod_get_optional(&spi->dev, "init-b", GPIOD_IN);
> -	if (IS_ERR(conf->init_b))
> -		return dev_err_probe(&spi->dev, PTR_ERR(conf->init_b),
> -				     "Failed to get INIT_B gpio\n");
> -
> -	conf->done = devm_gpiod_get(&spi->dev, "done", GPIOD_IN);
> -	if (IS_ERR(conf->done))
> -		return dev_err_probe(&spi->dev, PTR_ERR(conf->done),
> -				     "Failed to get DONE gpio\n");
> -
> -	mgr = devm_fpga_mgr_register(&spi->dev,
> -				     "Xilinx Slave Serial FPGA Manager",
> -				     &xilinx_spi_ops, conf);
> -	return PTR_ERR_OR_ZERO(mgr);
> +	return xilinx_core_probe(&conf->core, &spi->dev, xilinx_spi_write,
> +				 xilinx_spi_apply_cclk_cycles);
>  }
>  
>  #ifdef CONFIG_OF
>  static const struct of_device_id xlnx_spi_of_match[] = {
> -	{ .compatible = "xlnx,fpga-slave-serial", },
> +	{
> +		.compatible = "xlnx,fpga-slave-serial",
> +	},
>  	{}
>  };
>  MODULE_DEVICE_TABLE(of, xlnx_spi_of_match);
> -- 
> 2.43.0
> 
> 


From masahiroy at kernel.org  Sun Feb  4 01:02:23 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Sun,  4 Feb 2024 18:02:23 +0900
Subject: [PATCH] sound: remove duplicated CONFIG_SND_PXA2XX_AC97 entry
Message-ID: <20240204090223.37621-1-masahiroy@kernel.org>

'config SND_PXA2XX_AC97' is already present in sound/arm/Kconfig with
a prompt.

Commit 734c2d4bb7cf ("[ALSA] ASoC pxa2xx build support") redundantly
added the second one to sound/soc/pxa/Kconfig.

Remove it.

Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
---

 sound/soc/pxa/Kconfig | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index f03c74809324..e05d6ce4c8fa 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -8,9 +8,6 @@ config SND_PXA2XX_SOC
 	  the PXA2xx AC97, I2S or SSP interface. You will also need
 	  to select the audio interfaces to support below.
 
-config SND_PXA2XX_AC97
-	tristate
-
 config SND_PXA2XX_SOC_AC97
 	tristate "SoC AC97 support for PXA2xx"
 	depends on SND_PXA2XX_SOC
-- 
2.40.1



From s-vadapalli at ti.com  Sun Feb  4 01:03:36 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Sun, 4 Feb 2024 14:33:36 +0530
Subject: [PATCH v2] dt-bindings: mfd: syscon: Add ti,j784s4-pcie-ctrl compatible
Message-ID: <20240204090336.3209063-1-s-vadapalli@ti.com>

The PCIE_CTRL registers within the CTRL_MMR space of TI's J784S4 SoC
are used to configure the link speed, lane count and mode of operation
of the respective PCIe instance. Add compatible for allowing the PCIe
driver to obtain a regmap for the PCIE_CTRL register within the System
Controller device-tree node in order to configure the PCIe instance
accordingly.

The Technical Reference Manual for J784S4 SoC with details of the
PCIE_CTRL registers is available at: https://www.ti.com/lit/zip/spruj52

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---
Hello,

This patch is based on linux-next tagged next-20240202.
v1:
https://lore.kernel.org/r/20240131112342.1300893-1-s-vadapalli at ti.com/
Changes since v1:
- Changed compatible to be SoC specific.
- Updated commit message to be SoC specific.

Regards,
Siddharth.

 Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index 084b5c2a2a3c..2376b612f94e 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -73,6 +73,7 @@ properties:
               - rockchip,rv1126-qos
               - starfive,jh7100-sysmain
               - ti,am654-dss-oldi-io-ctrl
+              - ti,j784s4-pcie-ctrl
 
           - const: syscon
 
-- 
2.34.1



From masahiroy at kernel.org  Sun Feb  4 01:04:32 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Sun, 4 Feb 2024 18:04:32 +0900
Subject: [PATCH] sound: remove duplicated CONFIG_SND_PXA2XX_AC97 entry
In-Reply-To: <20240204090223.37621-1-masahiroy@kernel.org>
References: <20240204090223.37621-1-masahiroy@kernel.org>
Message-ID: <CAK7LNAQExdrSmucgzj8UHcgvXjKjdLqkiww+cuUN6EBzkJAy3w@mail.gmail.com>

Maybe, the patch subject "ASoC: pxa:" might be better than "sound:"
so it matches the change history in this directory.



On Sun, Feb 4, 2024 at 6:02?PM Masahiro Yamada <masahiroy at kernel.org> wrote:
>
> 'config SND_PXA2XX_AC97' is already present in sound/arm/Kconfig with
> a prompt.
>
> Commit 734c2d4bb7cf ("[ALSA] ASoC pxa2xx build support") redundantly
> added the second one to sound/soc/pxa/Kconfig.
>
> Remove it.
>
> Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
> ---
>
>  sound/soc/pxa/Kconfig | 3 ---
>  1 file changed, 3 deletions(-)
>
> diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
> index f03c74809324..e05d6ce4c8fa 100644
> --- a/sound/soc/pxa/Kconfig
> +++ b/sound/soc/pxa/Kconfig
> @@ -8,9 +8,6 @@ config SND_PXA2XX_SOC
>           the PXA2xx AC97, I2S or SSP interface. You will also need
>           to select the audio interfaces to support below.
>
> -config SND_PXA2XX_AC97
> -       tristate
> -
>  config SND_PXA2XX_SOC_AC97
>         tristate "SoC AC97 support for PXA2xx"
>         depends on SND_PXA2XX_SOC
> --
> 2.40.1
>


-- 
Best Regards
Masahiro Yamada


From tiwai at suse.de  Sun Feb  4 01:08:28 2024
From: tiwai at suse.de (Takashi Iwai)
Date: Sun, 04 Feb 2024 10:08:28 +0100
Subject: [PATCH] sound: remove duplicated CONFIG_SND_PXA2XX_AC97 entry
In-Reply-To: <CAK7LNAQExdrSmucgzj8UHcgvXjKjdLqkiww+cuUN6EBzkJAy3w@mail.gmail.com>
References: <20240204090223.37621-1-masahiroy@kernel.org>
	<CAK7LNAQExdrSmucgzj8UHcgvXjKjdLqkiww+cuUN6EBzkJAy3w@mail.gmail.com>
Message-ID: <87a5ogbnqr.wl-tiwai@suse.de>

On Sun, 04 Feb 2024 10:04:32 +0100,
Masahiro Yamada wrote:
> 
> Maybe, the patch subject "ASoC: pxa:" might be better than "sound:"
> so it matches the change history in this directory.

Yes, care to resubmit with that prefix?


thanks,

Takashi


From masahiroy at kernel.org  Sun Feb  4 01:09:45 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Sun, 4 Feb 2024 18:09:45 +0900
Subject: [PATCH] sound: remove duplicated CONFIG_SND_PXA2XX_AC97 entry
In-Reply-To: <87a5ogbnqr.wl-tiwai@suse.de>
References: <20240204090223.37621-1-masahiroy@kernel.org> <CAK7LNAQExdrSmucgzj8UHcgvXjKjdLqkiww+cuUN6EBzkJAy3w@mail.gmail.com>
 <87a5ogbnqr.wl-tiwai@suse.de>
Message-ID: <CAK7LNATb1xxCRsdMJONWvT0-h8+H-wxm9h-eXH_SUSVYQPEJMQ@mail.gmail.com>

On Sun, Feb 4, 2024 at 6:08?PM Takashi Iwai <tiwai at suse.de> wrote:
>
> On Sun, 04 Feb 2024 10:04:32 +0100,
> Masahiro Yamada wrote:
> >
> > Maybe, the patch subject "ASoC: pxa:" might be better than "sound:"
> > so it matches the change history in this directory.
>
> Yes, care to resubmit with that prefix?
>


Sure.


-- 
Best Regards
Masahiro Yamada


From carlos.song at nxp.com  Sun Feb  4 01:12:05 2024
From: carlos.song at nxp.com (Carlos Song)
Date: Sun, 4 Feb 2024 09:12:05 +0000
Subject: [EXT] Re: [PATCH v4] spi: imx: fix the burst length at DMA mode
 and CPU mode
In-Reply-To: <c7326b50ce3fe2a660638e1eb2c11519ad82feee.camel@bigler.one>
References: <20240201105451.507005-1-carlos.song@nxp.com>
 <c7326b50ce3fe2a660638e1eb2c11519ad82feee.camel@bigler.one>
Message-ID: <DB7PR04MB50035B2C0BFCD427F280ECEEE8402@DB7PR04MB5003.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Benjamin Bigler <benjamin at bigler.one>
> Sent: Friday, February 2, 2024 4:15 AM
> To: Carlos Song <carlos.song at nxp.com>; broonie at kernel.org;
> shawnguo at kernel.org; s.hauer at pengutronix.de; kernel at pengutronix.de;
> dl-linux-imx <linux-imx at nxp.com>; stefanmoring at gmail.com
> Cc: linux-spi at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> linux-kernel at vger.kernel.org
> Subject: [EXT] Re: [PATCH v4] spi: imx: fix the burst length at DMA mode and
> CPU mode
>
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report this
> email' button
>
>
> On Thu, 2024-02-01 at 18:54 +0800, carlos.song at nxp.com wrote:
> > From: Carlos Song <carlos.song at nxp.com>
> >
> > For DMA mode, the bus width of the DMA is equal to the size of data
> > word, so burst length should be configured as bits per word.
> >
> > For CPU mode, because of the spi transfer len is in byte, so burst
> > length should be configured as bits per byte * spi_imx->count.
> >
> > Signed-off-by: Carlos Song <carlos.song at nxp.com>
> > Reviewed-by: Clark Wang <xiaoning.wang at nxp.com>
> > Fixes: e9b220aeacf1 ("spi: spi-imx: correctly configure burst length
> > when using dma")
> > Fixes: 5f66db08cbd3 ("spi: imx: Take in account bits per word instead
> > of assuming 8-bits")
> > ---
> > Changes for V3:
> > - include <linux/bits.h>
> > Changes for V4:
> > - keep the includes sorted alphabetically.
> > ---
> >  drivers/spi/spi-imx.c | 8 ++++----
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index
> > 546cdce525fc..f7990ac2c654 100644
> > --- a/drivers/spi/spi-imx.c
> > +++ b/drivers/spi/spi-imx.c
> > @@ -2,6 +2,7 @@
> >  // Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> >  // Copyright (C) 2008 Juergen Beisert
> >
> > +#include <linux/bits.h>
> >  #include <linux/clk.h>
> >  #include <linux/completion.h>
> >  #include <linux/delay.h>
> > @@ -660,15 +661,14 @@ static int mx51_ecspi_prepare_transfer(struct
> spi_imx_data *spi_imx,
> >                       << MX51_ECSPI_CTRL_BL_OFFSET;
> >       else {
> >               if (spi_imx->usedma) {
> > -                     ctrl |= (spi_imx->bits_per_word *
> > -
> spi_imx_bytes_per_word(spi_imx->bits_per_word) - 1)
> > +                     ctrl |= (spi_imx->bits_per_word - 1)
> >                               << MX51_ECSPI_CTRL_BL_OFFSET;
> >               } else {
> >                       if (spi_imx->count >=
> MX51_ECSPI_CTRL_MAX_BURST)
> > -                             ctrl |= (MX51_ECSPI_CTRL_MAX_BURST -
> 1)
> > +                             ctrl |= (MX51_ECSPI_CTRL_MAX_BURST *
> > + BITS_PER_BYTE - 1)
> >                                               <<
> MX51_ECSPI_CTRL_BL_OFFSET;
> >                       else
> > -                             ctrl |= (spi_imx->count *
> spi_imx->bits_per_word - 1)
> > +                             ctrl |= (spi_imx->count * BITS_PER_BYTE
> > + - 1)


Hi,

Thank you! You re right. I have get the patch history that spi->bits_per_word = 9 will
break the driver, this is a special case.

So burst length should be calculated by the number of words, instead of the number of bytes, otherwise the transmission of these non-byte-aligned word will break the driver.

the burst length can be set by:
spi_imx->count/DIV_ROUND_UP(spi_imx->bits_per_word, BITS_PER_BYTE) * spi_imx->bits_per_word.

I will set V5 later.
> I think that will not work for drivers which dont use bits_per_word=8.
> https://lore.ker/
> nel.org%2Fall%2F20230917164037.29284-1-stefanmoring%40gmail.com%2F&
> data=05%7C02%7Ccarlos.song%40nxp.com%7C6f52557285a34b97c6f508dc2
> 3626f51%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638424152
> 883113184%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoi
> V2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=2RerZ6
> 2kHdgiwqi5yxnDPLwWViplttHA2E05WFZmTuw%3D&reserved=0
> >                                               <<
> MX51_ECSPI_CTRL_BL_OFFSET;
> >               }
> >       }
>
> Best regards,
> Benjamin Bigler



From carlos.song at nxp.com  Sun Feb  4 01:19:12 2024
From: carlos.song at nxp.com (carlos.song at nxp.com)
Date: Sun,  4 Feb 2024 17:19:12 +0800
Subject: [PATCH v5] spi: imx: fix the burst length at DMA mode and CPU mode
Message-ID: <20240204091912.36488-1-carlos.song@nxp.com>

From: Carlos Song <carlos.song at nxp.com>

For DMA mode, the bus width of the DMA is equal to the size of data
word, so burst length should be configured as bits per word.

For CPU mode, because of the spi transfer len is in byte, so calculate
the total number of words according to spi transfer len and bits per
word, burst length should be configured as total data bits.

Signed-off-by: Carlos Song <carlos.song at nxp.com>
Reviewed-by: Clark Wang <xiaoning.wang at nxp.com>
Fixes: e9b220aeacf1 ("spi: spi-imx: correctly configure burst length when using dma")
Fixes: 5f66db08cbd3 ("spi: imx: Take in account bits per word instead of assuming 8-bits")
---
Changes for V5:
- fix the the method of burst length calculation compatible with non-byte aligned wordsize.
---
 drivers/spi/spi-imx.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 546cdce525fc..833a1bb7a914 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -2,6 +2,7 @@
 // Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
 // Copyright (C) 2008 Juergen Beisert
 
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
@@ -660,15 +661,15 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx,
 			<< MX51_ECSPI_CTRL_BL_OFFSET;
 	else {
 		if (spi_imx->usedma) {
-			ctrl |= (spi_imx->bits_per_word *
-				spi_imx_bytes_per_word(spi_imx->bits_per_word) - 1)
+			ctrl |= (spi_imx->bits_per_word - 1)
 				<< MX51_ECSPI_CTRL_BL_OFFSET;
 		} else {
 			if (spi_imx->count >= MX51_ECSPI_CTRL_MAX_BURST)
-				ctrl |= (MX51_ECSPI_CTRL_MAX_BURST - 1)
+				ctrl |= (MX51_ECSPI_CTRL_MAX_BURST * BITS_PER_BYTE - 1)
 						<< MX51_ECSPI_CTRL_BL_OFFSET;
 			else
-				ctrl |= (spi_imx->count * spi_imx->bits_per_word - 1)
+				ctrl |= spi_imx->count / DIV_ROUND_UP(spi_imx->bits_per_word,
+						BITS_PER_BYTE) * spi_imx->bits_per_word
 						<< MX51_ECSPI_CTRL_BL_OFFSET;
 		}
 	}
-- 
2.34.1



From masahiroy at kernel.org  Sun Feb  4 01:14:24 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Sun,  4 Feb 2024 18:14:24 +0900
Subject: [PATCH v2] ASoC: pxa: remove duplicated CONFIG_SND_PXA2XX_AC97 entry
Message-ID: <20240204091424.38306-1-masahiroy@kernel.org>

'config SND_PXA2XX_AC97' is already present in sound/arm/Kconfig with
a prompt.

Commit 734c2d4bb7cf ("[ALSA] ASoC pxa2xx build support") redundantly
added the second one to sound/soc/pxa/Kconfig.

Remove it.

Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
---

Changes in v2:
  - Change the commit subject

 sound/soc/pxa/Kconfig | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index f03c74809324..e05d6ce4c8fa 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -8,9 +8,6 @@ config SND_PXA2XX_SOC
 	  the PXA2xx AC97, I2S or SSP interface. You will also need
 	  to select the audio interfaces to support below.
 
-config SND_PXA2XX_AC97
-	tristate
-
 config SND_PXA2XX_SOC_AC97
 	tristate "SoC AC97 support for PXA2xx"
 	depends on SND_PXA2XX_SOC
-- 
2.40.1



From dmitry.baryshkov at linaro.org  Sun Feb  4 01:23:02 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sun, 4 Feb 2024 10:23:02 +0100
Subject: [PATCH V8 02/12] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240203165307.7806-3-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com> <20240203165307.7806-3-aford173@gmail.com>
Message-ID: <CAA8EJpo4omXogg48urEMzxQ+CA7DNTSf66pA6hoO8wpmtn_-MQ@mail.gmail.com>

On Sat, 3 Feb 2024 at 17:53, Adam Ford <aford173 at gmail.com> wrote:
>
> From: Lucas Stach <l.stach at pengutronix.de>
>
> This adds the driver for the Samsung HDMI PHY found on the
> i.MX8MP SoC.
>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> ---
> V4:  Make lookup table hex values lower case.
>
> V3:  Re-order the Makefile to keep it alphabetical
>      Remove unused defines
>
> V2:  Fixed some whitespace found from checkpatch
>      Change error handling when enabling apbclk to use dev_err_probe
>      Rebase on Linux-Next
>
>      I (Adam) tried to help move this along, so I took Lucas' patch and
>      attempted to apply fixes based on feedback.  I don't have
>      all the history, so apologies for that.
> ---
>  drivers/phy/freescale/Kconfig                |    6 +
>  drivers/phy/freescale/Makefile               |    1 +
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 1075 ++++++++++++++++++
>  3 files changed, 1082 insertions(+)
>  create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>
> diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> index 853958fb2c06..5c2b73042dfc 100644
> --- a/drivers/phy/freescale/Kconfig
> +++ b/drivers/phy/freescale/Kconfig
> @@ -35,6 +35,12 @@ config PHY_FSL_IMX8M_PCIE
>           Enable this to add support for the PCIE PHY as found on
>           i.MX8M family of SOCs.
>
> +config PHY_FSL_SAMSUNG_HDMI_PHY
> +       tristate "Samsung HDMI PHY support"
> +       depends on OF && HAS_IOMEM
> +       help
> +         Enable this to add support for the Samsung HDMI PHY in i.MX8MP.
> +
>  endif
>
>  config PHY_FSL_LYNX_28G
> diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
> index cedb328bc4d2..79e5f16d3ce8 100644
> --- a/drivers/phy/freescale/Makefile
> +++ b/drivers/phy/freescale/Makefile
> @@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)        += phy-fsl-imx8qm-lvds-phy.o
>  obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)      += phy-fsl-imx8-mipi-dphy.o
>  obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)       += phy-fsl-imx8m-pcie.o
>  obj-$(CONFIG_PHY_FSL_LYNX_28G)         += phy-fsl-lynx-28g.o
> +obj-$(CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY)  += phy-fsl-samsung-hdmi.o
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> new file mode 100644
> index 000000000000..bf0e2299d00f
> --- /dev/null
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -0,0 +1,1075 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2020 NXP
> + * Copyright 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +
> +#define PHY_REG_33             0x84
> +#define  REG33_MODE_SET_DONE   BIT(7)
> +#define  REG33_FIX_DA          BIT(1)
> +
> +#define PHY_REG_34             0x88
> +#define  REG34_PHY_READY       BIT(7)
> +#define  REG34_PLL_LOCK                BIT(6)
> +#define  REG34_PHY_CLK_READY   BIT(5)
> +
> +
> +#define PHY_PLL_REGS_NUM 48
> +
> +struct phy_config {
> +       u32     clk_rate;
> +       u8 regs[PHY_PLL_REGS_NUM];
> +};
> +
> +const struct phy_config phy_pll_cfg[] = {
> +       {       22250000, {
> +                       0x00, 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40,
> +                       0x4f, 0x30, 0x33, 0x65, 0x00, 0x15, 0x25, 0x80,
> +                       0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
> +                       0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
> +                       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +                       0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
> +               },
> +       }, {
> +               23750000, {
> +                       0x00, 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40,
> +                       0x4f, 0x30, 0x33, 0x65, 0x00, 0x03, 0x25, 0x80,
> +                       0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
> +                       0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
> +                       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +                       0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
> +               },

Generally I see that these entries contain a high level of duplication.
Could you please extract the common part and a rate-dependent part.
Next, it would be best if instead of writing the register values via
the rate LUT, the driver could calculate those values.
This allows us to support other HDMI modes if the need arises at some point.

> +       }, {
> +               24000000, {
> +                       0x00, 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00,
> +                       0x4f, 0x30, 0x33, 0x65, 0x00, 0x01, 0x25, 0x80,
> +                       0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
> +                       0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
> +                       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +                       0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
> +               },


-- 
With best wishes
Dmitry


From peng.fan at nxp.com  Sun Feb  4 01:29:25 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Sun, 4 Feb 2024 09:29:25 +0000
Subject: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <Zbt-QkWhz5d9P-v6@pluto>
References: <20240121-pinctrl-scmi-v3-0-8d94ba79dca8@nxp.com>
 <f88d07ef-83b2-4d14-976a-6dbbd71e036f@oss.nxp.com>
 <CACRpkdYV=qYQ9qDUWYTLDAV1niay30gYH5S=zjfi31GpeY5o-A@mail.gmail.com>
 <DU0PR04MB9417A9074C5DC49AE689E65288432@DU0PR04MB9417.eurprd04.prod.outlook.com>
 <Zbt-QkWhz5d9P-v6@pluto>
Message-ID: <DU0PR04MB9417CA6CF089B264112C32A088402@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
> protocol basic support
> 
> On Thu, Feb 01, 2024 at 07:14:17AM +0000, Peng Fan wrote:
> > > Subject: Re: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2
> > > pincontrol protocol basic support
> > >
> 
> Hi Peng,
> 
> > > On Mon, Jan 29, 2024 at 1:37?PM Peng Fan <peng.fan at oss.nxp.com>
> wrote:
> > >
> > > > And for i.MX95 OEM extenstion, do you have any suggestions?
> > > > I have two points:
> > > > 1. use vendor compatible. This would also benefit when supporting
> > > > vendor protocol.
> > > > 2. Introduce a property saying supporting-generic-pinconf
> > > >
> > > > How do you think?
> > >
> > > While I don't know how OEM extensions to SCMI were designed, the pin
> > > control subsystem has the philosophy that extensions are for minor
> > > fringe stuff, such as a pin config option that no other silicon is
> > > using and thus have no use for anyone else. Well that is actually
> > > all the custom extensions we have.
> > > (This notion is even carried over to SCMI pinctrl.)
> > >
> > > The i.MX95 OEM extension is really odd to me, it looks like a
> > > reimplementation of the core aspects of SCMI pin control, and looks
> > > much more like the old i.MX drivers than like the SCMI driver.
> >
> > i.MX SCMI pin protocol conf settings follows non-SCMI pin conf settings.
> >
> 
> It is not just a matter of using custom SCMI OEM types, it is the whole
> layout/definitions of the i.MX pin/groups/funcs DT bindings that deviates
> from the generic DT bindings layout as handled and expected by the Linux
> Pinctrl subsystem (AFAIU), while the SCMI Pinctrl driver as it stands in this
> series, was conceived, designed and implemented originally by Oleksii to just
> use the generic existing Pinctrl DT bindings; as a consequence, in your i.MX
> extensions, you had to add a dedicated i.MX DT parser to interpret the
> protocol at 19 DT snippet in a completely different way, to try to stick your
> custom solution on top of the generic one.

The two links shows the drop of i.MX generic pinconf
https://patchwork.ozlabs.org/project/linux-gpio/patch/1541149669-10857-7-git-send-email-aisheng.dong at nxp.com/
https://lore.kernel.org/all/20230302072132.1051590-1-linux at rasmusvillemoes.dk/

For non-scmi platforms, the generic pinconf was supported
for i.MX7ULP for a while, and then dropped in the end per i.MX maintainers
and agreed by Linus.

For i.MX95 SCMI platforms, the firmware design is simple and use similar
programming model to simplify firmware design.

Using generic pinconf means the firmware needs exporting groups/functions/pins
and etc, the firmware design will be complicated and code size enlarged.

I have no better ideas without introducing a compatible for dt map hook.

Build exclusive is not acceptable for distro support.

So the last options is i.MX95 switch back to VENDOR protocol ID saying
0x82. But this means to exports functions of pinctrl-scmi.c and reused
by pinctrl-scmi-imx.c.  If you agree, I will ask firmware developer
switch back to a new SCMI ID, and I will use new ID for i.mx pinctrl
driver.

But in the end I would think when more SCMI vendor protocols
comes in, saying vendor A and vendor B both use ID 0x81,
both use 0x81 as RTC functions, same issue will come back.

Thanks,
Peng.

> 
> Thanks,
> Cristian
> 
> > >
> > > But I sure cannot speak of what is allowed in SCMI OEM extensions or not.
> >
> > + SPEC owner, Souvik. Any comments?
> >
> > Thanks,
> > Peng.
> >
> > >
> > > Yours,
> > > Linus Walleij

From lkp at intel.com  Sun Feb  4 01:31:47 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 4 Feb 2024 17:31:47 +0800
Subject: [PATCH v2 2/2] arm64: dts: mediatek: Introduce the MT8395 Radxa
 NIO 12L board
In-Reply-To: <20240202114821.79227-3-angelogioacchino.delregno@collabora.com>
References: <20240202114821.79227-3-angelogioacchino.delregno@collabora.com>
Message-ID: <202402041754.SHJCpnEP-lkp@intel.com>

Hi AngeloGioacchino,

kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.8-rc2 next-20240202]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/AngeloGioacchino-Del-Regno/dt-bindings-arm64-mediatek-Add-MT8395-Radxa-NIO-12L-board-compatible/20240202-195207
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20240202114821.79227-3-angelogioacchino.delregno%40collabora.com
patch subject: [PATCH v2 2/2] arm64: dts: mediatek: Introduce the MT8395 Radxa NIO 12L board
config: arm64-defconfig (https://download.01.org/0day-ci/archive/20240204/202402041754.SHJCpnEP-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240204/202402041754.SHJCpnEP-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402041754.SHJCpnEP-lkp at intel.com/

All errors (new ones prefixed by >>):

>> Error: arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts:791.1-8 Label or path ssusb0 not found
>> Error: arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts:804.1-8 Label or path ssusb2 not found
   FATAL ERROR: Syntax error parsing input tree

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From andre.przywara at arm.com  Sun Feb  4 01:32:53 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun,  4 Feb 2024 10:32:53 +0100
Subject: [PATCH 0/2] arm64: dts: allwinner: Add Transpeed WiFi nodes
Message-ID: <20240204093255.148972-1-andre.przywara@arm.com>

This adds the WiFi DT nodes for the Transpeed 8K618T TV box. It uses a
Murata module with a Broadcom 4335 chip, which works fine with the
mainline driver, given you provide the proper firmware files. We found
some in some LibreELEC repository.

Patch 1 adds the pinctrl node for the 32KHz clock fanout pin, patch 2
adds the actual SDIO WiFi node.

Please have a look!

Cheers,
Andre

Andre Przywara (2):
  arm64: dts: allwinner: h616: Add 32K fanout pin
  arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes

 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi |  5 ++++
 .../sun50i-h618-transpeed-8k618-t.dts         | 23 +++++++++++++++++++
 2 files changed, 28 insertions(+)

-- 
2.25.1



From andre.przywara at arm.com  Sun Feb  4 01:32:54 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun,  4 Feb 2024 10:32:54 +0100
Subject: [PATCH 1/2] arm64: dts: allwinner: h616: Add 32K fanout pin
In-Reply-To: <20240204093255.148972-1-andre.przywara@arm.com>
References: <20240204093255.148972-1-andre.przywara@arm.com>
Message-ID: <20240204093255.148972-2-andre.przywara@arm.com>

On some boards the designers saved on a 32KHz crystal for some external
chips, so the SoC has to help out, with providing a 32 KHz clock signal.

Add a pinctrl group node to allow DT nodes to reference this fanout signal.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index d549d277d972..107256eeedc3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -256,6 +256,11 @@ uart1_rts_cts_pins: uart1-rts-cts-pins {
 				pins = "PG8", "PG9";
 				function = "uart1";
 			};
+
+			x32clk_fanout_pin: x32clk-fanout-pin {
+				pins = "PG10";
+				function = "clock";
+			};
 		};
 
 		gic: interrupt-controller at 3021000 {
-- 
2.25.1



From andre.przywara at arm.com  Sun Feb  4 01:32:55 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun,  4 Feb 2024 10:32:55 +0100
Subject: [PATCH 2/2] arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes
In-Reply-To: <20240204093255.148972-1-andre.przywara@arm.com>
References: <20240204093255.148972-1-andre.przywara@arm.com>
Message-ID: <20240204093255.148972-3-andre.przywara@arm.com>

In contrast to other devices using Allwinner SoCs, the Transpeed 8K618-T
TV box uses a mainline supported WiFi chip: it's a Broadcom 4335
compatible, packaged by a company called Murata.
It works nicely with the Linux driver, when providing the respective
firmware files.

Add the required DT nodes to let the kernel find the SDIO device.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 .../sun50i-h618-transpeed-8k618-t.dts         | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
index 8ea1fd41aeba..7ec4098e707b 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
@@ -16,6 +16,7 @@ / {
 
 	aliases {
 		serial0 = &uart0;
+		ethernet1 = &sdio_wifi;
 	};
 
 	chosen {
@@ -39,6 +40,15 @@ reg_vcc3v3: vcc3v3 {
 		regulator-max-microvolt = <3300000>;
 		regulator-always-on;
 	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&rtc CLK_OSC32K_FANOUT>;
+		clock-names = "ext_clock";
+		pinctrl-0 = <&x32clk_fanout_pin>;
+		pinctrl-names = "default";
+		reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
+	};
 };
 
 &ehci0 {
@@ -60,6 +70,19 @@ &mmc0 {
 	status = "okay";
 };
 
+&mmc1 {
+	vmmc-supply = <&reg_dldo1>;
+	vqmmc-supply = <&reg_aldo1>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	sdio_wifi: wifi at 1 {
+		reg = <1>;
+	};
+};
+
 &mmc2 {
 	vmmc-supply = <&reg_dldo1>;
 	vqmmc-supply = <&reg_aldo1>;
-- 
2.25.1



From andre.przywara at arm.com  Sun Feb  4 01:44:01 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun,  4 Feb 2024 10:44:01 +0100
Subject: [PATCH 0/3] arm64: dts: allwinner: Add Remix Mini PC support
Message-ID: <20240204094404.149776-1-andre.przywara@arm.com>

These are the DT support patches for the Jide Remix Mini PC, a now
somewhat dated Mini-PC, once shipped with some kind of desktop Android OS.
It sports an Allwinner H64 SoC, which is basically the same as the
venerable A64.
To make it stick out of the crowd, the SoC has "secure boot" enabled,
which just means it needs a different (signed) boot code package, already
supported by mainline U-Boot. Fortunately there is no public key burned
into the SoC, so any key can be used: the U-Boot build system will just
make one up.
Apart from Ethernet (blocked by the AC200 PHY) everything should work,
including WiFi and Bluetooth.

Please have a look!

Cheers,
Andre

Andre Przywara (3):
  dt-bindings: vendor-prefixes: add Jide
  dt-bindings: arm: sunxi: document Remix Mini PC name
  arm64: dts: allwinner: Add Jide Remix Mini PC support

 .../devicetree/bindings/arm/sunxi.yaml        |   6 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../allwinner/sun50i-h64-remix-mini-pc.dts    | 357 ++++++++++++++++++
 4 files changed, 366 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts

-- 
2.25.1



From andre.przywara at arm.com  Sun Feb  4 01:44:02 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun,  4 Feb 2024 10:44:02 +0100
Subject: [PATCH 1/3] dt-bindings: vendor-prefixes: add Jide
In-Reply-To: <20240204094404.149776-1-andre.przywara@arm.com>
References: <20240204094404.149776-1-andre.przywara@arm.com>
Message-ID: <20240204094404.149776-2-andre.przywara@arm.com>

Jide tech once create the Remix OS Android system, and shipped it on
some custom hardware. Add their name to the bindings.

Signed-off-by: Andre Przywara <andre.przywara at arm.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 1a0dc04f1db4..dfb834a9279f 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -719,6 +719,8 @@ patternProperties:
     description: JetHome (IP Sokolov P.A.)
   "^jianda,.*":
     description: Jiandangjing Technology Co., Ltd.
+  "^jide,.*":
+    description: Jide Tech
   "^joz,.*":
     description: JOZ BV
   "^kam,.*":
-- 
2.25.1



From andre.przywara at arm.com  Sun Feb  4 01:44:03 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun,  4 Feb 2024 10:44:03 +0100
Subject: [PATCH 2/3] dt-bindings: arm: sunxi: document Remix Mini PC name
In-Reply-To: <20240204094404.149776-1-andre.przywara@arm.com>
References: <20240204094404.149776-1-andre.przywara@arm.com>
Message-ID: <20240204094404.149776-3-andre.przywara@arm.com>

The Jide Remix Mini PC is a mini computer that ships with the Remix OS
Android based system. The SoC is an Allwinner H64, which is very close,
if not identical to the Allwinner A64.

Add the board/SoC compatible string pair to the list of known boards.
There are some drivers that look explicitly for the A64 compatible name,
so retain this name to increase compatibility.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index a9d8e85565b8..dab7a248c88d 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -815,6 +815,12 @@ properties:
           - const: allwinner,r7-tv-dongle
           - const: allwinner,sun5i-a10s
 
+      - description: Remix Mini PC
+        items:
+          - const: jide,remix-mini-pc
+          - const: allwinner,sun50i-h64
+          - const: allwinner,sun50i-a64
+
       - description: RerVision H3-DVK
         items:
           - const: rervision,h3-dvk
-- 
2.25.1



From andre.przywara at arm.com  Sun Feb  4 01:44:04 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun,  4 Feb 2024 10:44:04 +0100
Subject: [PATCH 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC support
In-Reply-To: <20240204094404.149776-1-andre.przywara@arm.com>
References: <20240204094404.149776-1-andre.przywara@arm.com>
Message-ID: <20240204094404.149776-4-andre.przywara@arm.com>

The Remix Mini PC is a "mini computer" using the Allwinner H64 SoC,
which appears to be just a relabelled A64. It was launched in 2015 by
the now defunct company Jide, and shipped with a desktop optimised
version of Android. It features
	- Allwinner H64 Soc (4 * Arm Cortex-A53 cores)
	- 1 or 2 GB DRAM
	- 8 or 16 GB eMMC flash
	- 100 MBit Ethernet port (using an X-Powers AC200 PHY)
	- RTL8723BS WiFi & Bluetooth chip
	- HDMI port
	- two USB 2.0 ports
	- 3.5mm AV port
	- microSD card slot

The devicetree covers most peripherals, though there is no agreed
binding for the PHY chip yet, so this is left out.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../allwinner/sun50i-h64-remix-mini-pc.dts    | 357 ++++++++++++++++++
 2 files changed, 358 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 91d505b385de..2db3b15ad09f 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -16,6 +16,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab-early-adopter.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
new file mode 100644
index 000000000000..537923a541a8
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
@@ -0,0 +1,357 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2018 ARM Ltd.
+
+/dts-v1/;
+
+#include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "Remix Mini PC";
+	compatible = "jide,remix-mini-pc", "allwinner,sun50i-h64",
+		     "allwinner,sun50i-a64";
+
+	aliases {
+		ethernet1 = &rtl8723bs;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	reg_vcc5v: regulator-5v {
+		/* board wide 5V supply directly from the DC input */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
+		post-power-on-delay-ms = <200>;
+	};
+};
+
+&codec {
+	status = "okay";
+};
+
+&codec_analog {
+	cpvdd-supply = <&reg_eldo1>;
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&dai {
+	status = "okay";
+};
+
+&de {
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&hdmi {
+	hvcc-supply = <&reg_dldo1>;
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+/* Connects to the AC200 chip */
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	status = "okay";
+};
+
+&i2c0_pins {
+	bias-pull-up;
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins>;
+	vmmc-supply = <&reg_dcdc1>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	vmmc-supply = <&reg_aldo1>;
+	vqmmc-supply = <&reg_dldo4>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	rtl8723bs: wifi at 1 {
+		reg = <1>;
+		interrupt-parent = <&r_pio>;
+		interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
+		interrupt-names = "host-wake";
+	};
+};
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
+	vmmc-supply = <&reg_dcdc1>;
+	vqmmc-supply = <&reg_eldo1>;
+	bus-width = <8>;
+	non-removable;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	cap-mmc-hw-reset;
+	status = "okay";
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&pio {
+	vcc-pb-supply = <&reg_dcdc1>;
+	vcc-pc-supply = <&reg_dcdc1>;
+	vcc-pd-supply = <&reg_dcdc1>;
+	vcc-pe-supply = <&reg_dcdc1>;
+	vcc-pf-supply = <&reg_dcdc1>;
+	vcc-pg-supply = <&reg_dldo4>;
+	vcc-ph-supply = <&reg_dcdc1>;
+};
+
+&r_ir {
+	status = "okay";
+};
+
+&r_pio {
+	/*
+	 * We cannot add that supply for now since it would create a circular
+	 * dependency between pinctrl, the regulator and the RSB Bus.
+	 *
+	 * vcc-pl-supply = <&reg_aldo2>;
+	 */
+};
+
+&r_rsb {
+	status = "okay";
+
+	axp803: pmic at 3a3 {
+		compatible = "x-powers,axp803";
+		reg = <0x3a3>;
+		interrupt-parent = <&r_intc>;
+		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
+		x-powers,drive-vbus-en;
+
+		vin1-supply = <&reg_vcc5v>;
+		vin2-supply = <&reg_vcc5v>;
+		vin3-supply = <&reg_vcc5v>;
+		vin5-supply = <&reg_vcc5v>;
+		vin6-supply = <&reg_vcc5v>;
+		aldoin-supply = <&reg_vcc5v>;
+		dldoin-supply = <&reg_vcc5v>;
+		eldoin-supply = <&reg_vcc5v>;
+		fldoin-supply = <&reg_vcc5v>;
+		drivevbus-supply = <&reg_vcc5v>;
+		ips-supply = <&reg_vcc5v>;
+
+		status = "okay";
+	};
+};
+
+#include "axp803.dtsi"
+
+&ac_power_supply {
+	status = "okay";
+};
+
+&reg_dcdc1 {
+	regulator-always-on;
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-3v3";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1040000>;
+	regulator-max-microvolt = <1300000>;
+	regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+&reg_dcdc5 {
+	regulator-always-on;
+	regulator-min-microvolt = <1500000>;
+	regulator-max-microvolt = <1500000>;
+	regulator-name = "vcc-dram";
+};
+
+/* Deviates from the reset default of 1.1V. */
+&reg_dcdc6 {
+	regulator-always-on;
+	regulator-min-microvolt = <1200000>;
+	regulator-max-microvolt = <1200000>;
+	regulator-name = "vdd-sys";
+};
+
+&reg_aldo1 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-wifi";
+};
+
+&reg_aldo2 {
+	/* Specifying R_PIO consumer would create circular dependency. */
+	regulator-always-on;
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-pl";
+};
+
+&reg_aldo3 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "vcc-pll-avcc";
+};
+
+/* AC200 power supply */
+&reg_dldo1 {
+	regulator-always-on;
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-ave-33";
+};
+
+&reg_dldo4 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-wifi-io";
+};
+
+&reg_drivevbus {
+	regulator-name = "usb0-vbus";
+	status = "okay";
+};
+
+&reg_eldo1 {
+	regulator-always-on;
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-name = "vcc-cpvdd-dram-emmc";
+};
+
+/* Supplies the arisc management core, needed by TF-A to power off cores. */
+&reg_fldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1100000>;
+	regulator-max-microvolt = <1100000>;
+	regulator-name = "vdd-cpus";
+};
+
+&reg_rtc_ldo {
+	regulator-name = "vcc-rtc";
+};
+
+&simplefb_hdmi {
+	vcc-hdmi-supply = <&reg_dcdc1>;
+};
+
+&sound {
+	simple-audio-card,aux-devs = <&codec_analog>;
+	simple-audio-card,widgets = "Microphone", "Microphone Jack",
+				    "Headphone", "Headphone Jack";
+	simple-audio-card,routing =
+			"Left DAC", "DACL",
+			"Right DAC", "DACR",
+			"Headphone Jack", "HP",
+			"ADCL", "Left ADC",
+			"ADCR", "Right ADC",
+			"MIC2", "Microphone Jack";
+	status = "okay";
+};
+
+/* On the (unpopulated) UART pads. */
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pb_pins>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+	uart-has-rtscts;
+	status = "okay";
+
+	bluetooth {
+		compatible = "realtek,rtl8723bs-bt";
+		enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
+		max-speed = <1500000>;
+	};
+};
+
+&usb_otg {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy {
+	usb0_vbus-supply = <&reg_drivevbus>;
+	usb1_vbus-supply = <&reg_drivevbus>;
+	status = "okay";
+};
-- 
2.25.1



From laurent.pinchart at ideasonboard.com  Sun Feb  4 01:56:18 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sun, 4 Feb 2024 11:56:18 +0200
Subject: [PATCH 0/4] Fixing live video input in ZynqMP DPSUB
In-Reply-To: <2ytxhpti53e743b5pca3oa5jmscffi4vpsyeh727bcoh4v6cuw@zkz5pqkcv7v2>
References: <20240112234222.913138-1-anatoliy.klymenko@amd.com>
 <6jhwss2wego6yoo5mwmphwawhsj5bbj62gwrzcpapoixwkrkli@g4fbxdooopby>
 <20240117142343.GD17920@pendragon.ideasonboard.com>
 <u5mngxudtdgy3vqkfbpgqng6tdahijnet2jtj345hrowbt47ce@t3e7hul45mr3>
 <MW4PR12MB7165D35189BEECA8769552AFE6792@MW4PR12MB7165.namprd12.prod.outlook.com>
 <2ytxhpti53e743b5pca3oa5jmscffi4vpsyeh727bcoh4v6cuw@zkz5pqkcv7v2>
Message-ID: <20240204095618.GJ3094@pendragon.ideasonboard.com>

On Thu, Feb 01, 2024 at 06:01:01PM +0100, Maxime Ripard wrote:
> On Fri, Jan 26, 2024 at 11:18:30PM +0000, Klymenko, Anatoliy wrote:
> > On Friday, January 26, 2024 4:26 AM, Maxime Ripard wrote:
> > > On Wed, Jan 17, 2024 at 04:23:43PM +0200, Laurent Pinchart wrote:
> > > > On Mon, Jan 15, 2024 at 09:28:39AM +0100, Maxime Ripard wrote:
> > > > > On Fri, Jan 12, 2024 at 03:42:18PM -0800, Anatoliy Klymenko wrote:
> > > > > > Patches 1/4,2/4,3/4 are minor fixes.
> > > > > >
> > > > > > DPSUB requires input live video format to be configured.
> > > > > > Patch 4/4: The DP Subsystem requires the input live video format to be
> > > > > > configured. In this patch we are assuming that the CRTC's bus format is fixed
> > > > > > and comes from the device tree. This is a proposed solution, as there are no api
> > > > > > to query CRTC output bus format.
> > > > > >
> > > > > > Is this a good approach to go with?
> > > > >
> > > > > I guess you would need to expand a bit on what "live video input" is? Is
> > > > > it some kind of mechanism to bypass memory and take your pixels straight
> > > > > from a FIFO from another device, or something else?
> > > >
> > > > Yes and no.
> > > >
> > > > The DPSUB integrates DMA engines, a blending engine (two planes), and a
> > > > DP encoder. The dpsub driver supports all of this, and creates a DRM
> > > > device. The DP encoder hardware always takes its input data from the
> > > > output of the blending engine.
> > > >
> > > > The blending engine can optionally take input data from a bus connected
> > > > to the FPGA fabric, instead of taking it from the DPSUB internal DMA
> > > > engines. When operating in that mode, the dpsub driver exposes the DP
> > > > encoder as a bridge, and internally programs the blending engine to
> > > > disable blending. Typically, the FPGA fabric will then contain a CRTC of
> > > > some sort, with a driver that will acquire the DP encoder bridge as
> > > > usually done.
> > > >
> > > > In this mode of operation, it is typical for the IP cores in FPGA fabric
> > > > to be synthesized with a fixed format (as that saves resources), while
> > > > the DPSUB supports multiple input formats.
> > > 
> > > Where is that CRTC driver? It's not clear to me why the format would
> > > need to be in the device tree at all. Format negociation between the
> > > CRTC and whatever comes next is already done in a number of drivers so
> > > it would be useful to have that kind of API outside of the bridge
> > > support.
> >
> > One example of such CRTC driver:
> > https://github.com/Xilinx/linux-xlnx/blob/master/drivers/gpu/drm/xlnx/xlnx_mixer.c It's not
> > upstreamed yet. Bus format negotiations here are handled by utilizing Xilinx-specific bridge
> > framework. Ideally, it would be nice to rework this to comply with the upstream DRM bridge
> > framework.
> >
> > > > Bridge drivers in the upstream kernel work the other way around, with
> > > > the bridge hardware supporting a limited set of formats, and the CRTC
> > > > then being programmed with whatever the bridges chain needs. Here, the
> > > > negotiation needs to go the other way around, as the CRTC is the
> > > > limiting factor, not the bridge.
> > > 
> > > Sounds like there's something to rework in the API then?
> > > 
> > Adding an optional CRTC callback imposing CRTC specific bus format restrictions, which may be
> > called from here https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/drm_bridge.c#L935
> > would solve the problem.
> 
> CRTCs and bridges are orthogonal. If anything, I'd expect that callback
> to be set at the CRTC, encoder and connector levels and filled by the
> drm_bridge code if relevant.

I'm thinking about a new CRTC operation that would be called by the
bridge chain format negotiation helper
drm_atomic_bridge_chain_select_bus_fmts() (or one of the functions it
calls), to filter the list of formats supported by the chain based on
what the CRTC supports, or possibly to pick a format in that list. This
needs to be prototyped

-- 
Regards,

Laurent Pinchart


From wahrenst at gmx.net  Sun Feb  4 02:02:39 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Sun, 4 Feb 2024 11:02:39 +0100
Subject: [PATCH v2] pwm: imx27: workaround of the pwm output bug
In-Reply-To: <65bf307d.170a0220.4d544.f32b@mx.google.com>
References: <9b5f9e1b-645a-4b44-a30c-fe93e7bf3532@gmx.net>
 <65bf307d.170a0220.4d544.f32b@mx.google.com>
Message-ID: <d72d1ae5-0378-4bac-8b77-0bb69f55accd@gmx.net>

Hi Pratik,

Am 04.02.24 um 07:36 schrieb pratikmanvar09 at gmail.com:
> Hi Stefan,
>
> Thanks for your review.
> Please see my reply below inline.
>
>>> From: Clark Wang <xiaoning.wang at nxp.com>
>>>
>>> This fixes the pwm output bug when decrease the duty cycle.
>>> This is a limited workaround for the PWM IP issue TKT0577206.
>> this looks like a patch from the vendor tree.
> [Pratik]: Yes, this is the patch from NXP. Please see original link of the patch https://github.com/nxp-imx/linux-imx/commit/16181cc4eee61d87cbaba0e5a479990507816317
>
>> Could you please provide a link to the origin or at least to the
>> document which describes TKT0577206?
> [Pratik]: Please refer i.MX8MN errata #ERR051198 in https://www.nxp.com/docs/en/errata/IMX8MN_0N14Y.pdf.
Thanks, i think this ERR... reference is better than TKT... because it's
links to the errata documents and other Freescale/NXP drivers use them
too. So having this code in a comment would be great.
>
>> As a i.MX6ULL user i couldn't find this issue in the chip errata. So are
>> you sure that every PWM IP handled by this driver is affected?
> [Pratik]: Yes, looks like this issue is on all platforms which uses this PWM IP.
>
>>> Root cause:
>>> When the SAR FIFO is empty, the new write value will be directly applied
>>> to SAR even the current period is not over.
>>> If the new SAR value is less than the old one, and the counter is
>>> greater than the new SAR value, the current period will not filp the
>> s/filp/flip/ ?
>>> level. This will result in a pulse with a duty cycle of 100%.
>>>
>>> Workaround:
>>> Add an old value SAR write before updating the new duty cycle to SAR.
>>> This will keep the new value is always in a not empty fifo, and can be
>>> wait to update after a period finished.
>>>
>>> Limitation:
>>> This workaround can only solve this issue when the PWM period is longer
>>> than 2us(or <500KHz).
>>>
>>> Reviewed-by: Jun Li <jun.li at nxp.com>
>>> Signed-off-by: Clark Wang <xiaoning.wang at nxp.com>
>>> Link: https://github.com/nxp-imx/linux-imx/commit/16181cc4eee61d87cbaba0e5a479990507816317
>>> Tested-by: Pratik Manvar <pratik.manvar at ifm.com>
>>> ---
>>>    V1 -> V2: fix sparse warnings reported-by: kernel test robot <lkp at intel.com>
>>>              Closes: https://lore.kernel.org/oe-kbuild-all/202312300907.RGtYsKxb-lkp at intel.com/
>>>
>>>    drivers/pwm/pwm-imx27.c | 67 ++++++++++++++++++++++++++++++++++++++---
>>>    1 file changed, 62 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
>>> index 7d9bc43f12b0..1e500a5bf564 100644
>>> --- a/drivers/pwm/pwm-imx27.c
>>> +++ b/drivers/pwm/pwm-imx27.c
>>> @@ -21,11 +21,13 @@
>>>    #include <linux/platform_device.h>
>>>    #include <linux/pwm.h>
>>>    #include <linux/slab.h>
>>> +#include <linux/spinlock.h>
>>>
>>>    #define MX3_PWMCR			0x00    /* PWM Control Register */
>>>    #define MX3_PWMSR			0x04    /* PWM Status Register */
>>>    #define MX3_PWMSAR			0x0C    /* PWM Sample Register */
>>>    #define MX3_PWMPR			0x10    /* PWM Period Register */
>>> +#define MX3_PWMCNR			0x14    /* PWM Counter Register */
>>>
>>>    #define MX3_PWMCR_FWM			GENMASK(27, 26)
>>>    #define MX3_PWMCR_STOPEN		BIT(25)
>>> @@ -91,6 +93,7 @@ struct pwm_imx27_chip {
>>>    	 * value to return in that case.
>>>    	 */
>>>    	unsigned int duty_cycle;
>>> +	spinlock_t lock;
>>>    };
>>>
>>>    #define to_pwm_imx27_chip(chip)	container_of(chip, struct pwm_imx27_chip, chip)
>>> @@ -203,10 +206,10 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
>>>
>>>    	sr = readl(imx->mmio_base + MX3_PWMSR);
>>>    	fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr);
>>> -	if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) {
>>> +	if (fifoav >= MX3_PWMSR_FIFOAV_3WORDS) {
>>>    		period_ms = DIV_ROUND_UP_ULL(pwm_get_period(pwm),
>>>    					 NSEC_PER_MSEC);
>>> -		msleep(period_ms);
>>> +		msleep(period_ms * (fifoav - 2));
>> This touches a different workaround ("pwm: imx: Avoid sample FIFO
>> overflow for i.MX PWM version2") without any explanation.
> [Pratik]: Sure, I will look into this. Thanks!
>>>    		sr = readl(imx->mmio_base + MX3_PWMSR);
>>>    		if (fifoav == FIELD_GET(MX3_PWMSR_FIFOAV, sr))
>>> @@ -217,13 +220,15 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
>>>    static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>>>    			   const struct pwm_state *state)
>>>    {
>>> -	unsigned long period_cycles, duty_cycles, prescale;
>>> +	unsigned long period_cycles, duty_cycles, prescale, counter_check, flags;
>>>    	struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
>>> +	void __iomem *reg_sar = imx->mmio_base + MX3_PWMSAR;
>>> +	__force u32 sar_last, sar_current;
>>>    	struct pwm_state cstate;
>>>    	unsigned long long c;
>>>    	unsigned long long clkrate;
>>>    	int ret;
>>> -	u32 cr;
>>> +	u32 cr, timeout = 1000;
>>>
>>>    	pwm_get_state(pwm, &cstate);
>>>
>>> @@ -264,7 +269,57 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>>>    		pwm_imx27_sw_reset(chip);
>>>    	}
>>>
>>> -	writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
>>> +	/*
>>> +	 * This is a limited workaround. When the SAR FIFO is empty, the new
>>> +	 * write value will be directly applied to SAR even the current period
>>> +	 * is not over.
>>> +	 * If the new SAR value is less than the old one, and the counter is
>>> +	 * greater than the new SAR value, the current period will not filp
>> The same typo as in the commit message.
>>> +	 * the level. This will result in a pulse with a duty cycle of 100%.
>>> +	 * So, writing the current value of the SAR to SAR here before updating
>>> +	 * the new SAR value can avoid this issue.
>>> +	 *
>>> +	 * Add a spin lock and turn off the interrupt to ensure that the
>>> +	 * real-time performance can be guaranteed as much as possible when
>>> +	 * operating the following operations.
>>> +	 *
>>> +	 * 1. Add a threshold of 1.5us. If the time T between the read current
>>> +	 * count value CNR and the end of the cycle is less than 1.5us, wait
>>> +	 * for T to be longer than 1.5us before updating the SAR register.
>>> +	 * This is to avoid the situation that when the first SAR is written,
>>> +	 * the current cycle just ends and the SAR FIFO that just be written
>>> +	 * is emptied again.
>>> +	 *
>>> +	 * 2. Use __raw_writel() to minimize the interval between two writes to
>>> +	 * the SAR register to increase the fastest pwm frequency supported.
>>> +	 *
>>> +	 * When the PWM period is longer than 2us(or <500KHz), this workaround
>>> +	 * can solve this problem.
>>> +	 */
>>> +	if (duty_cycles < imx->duty_cycle) {
>>> +		c = clkrate * 1500;
>>> +		do_div(c, NSEC_PER_SEC);
>>> +		counter_check = c;
>>> +		sar_last = (__force u32) cpu_to_le32(imx->duty_cycle);
>>> +		sar_current = (__force u32) cpu_to_le32(duty_cycles);
>>> +
>>> +		spin_lock_irqsave(&imx->lock, flags);
>>> +		if (state->period >= 2000) {
>>> +			while ((period_cycles -
>>> +				readl_relaxed(imx->mmio_base + MX3_PWMCNR))
>>> +				< counter_check) {
>>> +				if (!--timeout)
>>> +					break;
>>> +			};
>>> +		}
>>> +		if (!(MX3_PWMSR_FIFOAV &
>>> +		      readl_relaxed(imx->mmio_base + MX3_PWMSR)))
>>> +			__raw_writel(sar_last, reg_sar);
>>> +		__raw_writel(sar_current, reg_sar);
>>> +		spin_unlock_irqrestore(&imx->lock, flags);
>>> +	} else
>>> +		writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
>>> +
>> This is hard to believe that checkpatch.pl is fine with this patch.
>> Please use it before submission.
> [Pratik]: I used the checkpatch.pl in this patch and that runs without any warnings/errors!
Okay, AFAIR the coding style suggests braces for the else case.
>
>>>    	writel(period_cycles, imx->mmio_base + MX3_PWMPR);
>>>
>>>    	/*
>>> @@ -324,6 +379,8 @@ static int pwm_imx27_probe(struct platform_device *pdev)
>>>    		return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_per),
>>>    				     "failed to get peripheral clock\n");
>>>
>>> +	spin_lock_init(&imx->lock);
>>> +	imx->duty_cycle = 0;
>> This line looks unrelated and unnecessary.
> [Pratik]: Right. I will remove this line in next patch version.
Could you also please look at Uwe's comments [1]?

Thanks

[1] -
https://lore.kernel.org/all/20211220105555.zwq22vip7onafrck at pengutronix.de/
>
>> Best regards
>>>    	imx->chip.ops = &pwm_imx27_ops;
>>>    	imx->chip.dev = &pdev->dev;
>>>    	imx->chip.npwm = 1;



From kever.yang at rock-chips.com  Sun Feb  4 01:56:34 2024
From: kever.yang at rock-chips.com (Kever Yang)
Date: Sun, 4 Feb 2024 17:56:34 +0800
Subject: [PATCH] arm64: dts: rockchip: rk3588: remove redundant cd-gpios
 in sdmmc node
In-Reply-To: <4514845.zXnORWrf4K@diego>
References: <20240201034621.1970279-1-kever.yang@rock-chips.com>
 <4514845.zXnORWrf4K@diego>
Message-ID: <546543ec-7817-4422-8717-82aaf46f2a3b@rock-chips.com>

Hi Heiko,

On 2024/2/1 16:41, Heiko St?bner wrote:
> Hi Kever,
>
> Am Donnerstag, 1. Februar 2024, 04:46:21 CET schrieb Kever Yang:
>> The sdmmc node already have a "&sdmmc_det" for pinctrl which switch the
>> GPIO0A4 to sdmmc detect function, no need to define a separate "cd-gpios".
> just to make sure, did you test this on actual hardware?
> Because there might be differences in behaviour.

We use this feature in vendor kernel for many boards.

For mainline support, there are 15 rk3588/rk3588 boards available, and 
10 of them

enable sdmmc node in dts, and 4 boards define "cd-gpios" while the 
hardware do use GPIO0A4,

and 1 board(rk3588-jaguar) using "broken-cd", and the other 5 boards are 
using default "&sdmmc_det"

 ?with the same hardware design.

If the hardware is using GPIO0A4(SDMMC_DET function IO) for sdmmc 
detect, then no need to define "cd-gpios";

if the hardware is not using GPIO0A4 for sdmmc detect, then the 
"cd-gpios" or "broken-cd" is needed.

So this patch is to sync up to use the "&sdmmc_det" when the IO is using 
the one has SDMMC_DET function.

>> RK3588 has force_jtage feature which is enable JTAG function via sdmmc
>> pins automatically when there is no SD card insert, this feature will
>> need the GPIO0A4 works in sdmmc_det function like other mmc signal instead
>> of GPIO function, or else the force_jtag can not auto be disabled when
>> SD card insert.
> We disable the jtag switching by default [0] ;-) .
> And there are very good reasons for it too:

I know you have disable the force_jtag by default, and I didn't want to 
change this.

As you have said we may need to enable it for debug, we suppose to only 
have to revert

the disable force_jtag patch and then it works without affect the 
default sdmmc function.

The sdmmc function is broken if we enable force_jtag for debug, and this 
patch can fix it.

> (1) JTAG is very much a debug feature, that the normal user will not need.
> Especially not in a finished product. If a developer is debugging _that_
> deep and needs jtag, they can enable it in their debug build.
>
>
> (2) Randomly enabling features that may compromise security.
> Why go through all the hoops of doing things like secure boot, signed
> images and everything, just to have the kernel then export direct access
> to the hardware on sd-card pins. If one wants to expose JTAG somewhere
> this should be conscious choice and devs should not need to fork their
> kernel just to shut down unwanted security-critical functionality.
>
>
> (3) It affects board layouts _not following_ the standard layout.
> Nobody is forcing board-designers to use Rockchip's desired pin
> for card-detection. Some designer may just select a different pin
> or a board could go without card-detect at all - see rk3588-jaguar.

You are right, "cd-gpios" and "broken-cd" are available for boards have 
different design,

and this patch is for the boards with SDMMC_DET(GPIO0A4) as sdmmc 
detect, they should go to

the default "&sdmmc_det" in sdmmc node.


Thanks,

- Kever

> These are both valid use-cases that need to be supported.
>
>
> Heiko
>
>
> [0]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6f6878ec6faf16a5f36761c93da6ea9cf09adb33
>
>
>> ---
>>
>>   arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 1 -
>>   arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts     | 1 -
>>   arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts         | 1 -
>>   arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts        | 1 -
>>   4 files changed, 4 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
>> index 3e660ff6cd5ff..1b606ea5b6cf2 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
>> @@ -444,7 +444,6 @@ &sdhci {
>>   &sdmmc {
>>   	bus-width = <4>;
>>   	cap-sd-highspeed;
>> -	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>>   	disable-wp;
>>   	max-frequency = <150000000>;
>>   	no-sdio;
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
>> index 87a0abf95f7d4..67414d72e2b6e 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
>> @@ -429,7 +429,6 @@ &sdhci {
>>   &sdmmc {
>>   	bus-width = <4>;
>>   	cap-sd-highspeed;
>> -	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>>   	disable-wp;
>>   	max-frequency = <150000000>;
>>   	no-sdio;
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> index a0e303c3a1dc6..25a82008e4f76 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> @@ -371,7 +371,6 @@ &sdmmc {
>>   	bus-width = <4>;
>>   	cap-mmc-highspeed;
>>   	cap-sd-highspeed;
>> -	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>>   	disable-wp;
>>   	sd-uhs-sdr104;
>>   	vmmc-supply = <&vcc_3v3_s3>;
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
>> index 2002fd0221fa3..00afb90d4eb10 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
>> @@ -366,7 +366,6 @@ &sdmmc {
>>   	bus-width = <4>;
>>   	cap-mmc-highspeed;
>>   	cap-sd-highspeed;
>> -	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>>   	disable-wp;
>>   	max-frequency = <150000000>;
>>   	no-sdio;
>>
>


From andre.przywara at arm.com  Sun Feb  4 02:10:52 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun,  4 Feb 2024 11:10:52 +0100
Subject: [PATCH v2 0/2] arm64: dts: allwinner: Add BananaPi M4 Berry
Message-ID: <20240204101054.152012-1-andre.przywara@arm.com>

Minor update of the series, addressing the comments from Jernej and
Krzysztof (thanks for the review!), for a changelog see below.
==============================================

The BananaPi M4 Berry is a development board with the Allwinner H618
SoC. It comes with 2GB DRAM and 8GB eMMC flash, with the usual suspects
like HDMI, SD card, GPIO headers. There are four USB ports connected
via an on-board hub chip, and a Gigabit Ethernet socket. Also there is
a USB WiFi chip soldered on the board.
More details: https://linux-sunxi.org/Sinovoip_Banana_Pi_M4_Berry

I don't have this board, so this is a "call for testing".
One thing to consider:
- The USB WiFi chip has a CHIP_EN pin, which can turn the chip off.
  It is pulled up by a resistor, so works out of the box, but is also
  connected to a GPIO (PC2), so the chip can be disabled or reset via
  this pin. Since this is a USB device, we don't have a DT node to
  announce this pin. Any ideas how this should be handled? At the moment
  I ignore it, but it could also be modelled as a USB VBUS regulator for
  USB port 1, to which it is connected.

When testing this, please have a look at:
- Does the eMMC work in HS200 mode? The vendor DT described that as a
  3.3V controlled eMMC only, but clearly the schematic uses 1.8V, which
  allows faster transfer modes. "hdparm -t" should suffice for a quick
  test.
- Do USB full-speed (aka USB v1.1) peripherals like keyboard or mouse
  work on the USB ports? I disabled the OHCI node, since the hub should
  not need this, but it would be good to double check.
- Similarly the USB WiFi chip probably doesn't need USB 1.1 modes, so
  please check this still works.

Apart from the missing audio and video support (which are due to missing
bindings for the H616/H618 SoC), most of the peripherals are supported.

Patch 1/2 adds the board compatible string to the bindings, patch 2/2
adds the actual .dts file.

Please have a look!

Changelog v1 .. v2:
- rename 5V regulator node
- rename switch node
- remove unused USB2 port
- Add ACK on patch 1

Andre Przywara (2):
  dt-bindings: arm: sunxi: document BananaPi M4 Berry board name
  arm64: dts: allwinner: h618: add BananaPi M4 Berry board

 .../devicetree/bindings/arm/sunxi.yaml        |   5 +
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../sun50i-h618-bananapi-m4-berry.dts         | 223 ++++++++++++++++++
 3 files changed, 229 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts

-- 
2.25.1



From andre.przywara at arm.com  Sun Feb  4 02:10:53 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun,  4 Feb 2024 11:10:53 +0100
Subject: [PATCH v2 1/2] dt-bindings: arm: sunxi: document BananaPi M4 Berry board name
In-Reply-To: <20240204101054.152012-1-andre.przywara@arm.com>
References: <20240204101054.152012-1-andre.przywara@arm.com>
Message-ID: <20240204101054.152012-2-andre.przywara@arm.com>

The Bananapi M4 Berry is a development board with the Allwinner H618 SoC.

Add the board/SoC compatible string pair to the list of known boards.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 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 dab7a248c88d..aa87c83124e2 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -136,6 +136,11 @@ properties:
           - const: sinovoip,bpi-m3
           - const: allwinner,sun8i-a83t
 
+      - description: BananaPi M4 Berry
+        items:
+          - const: sinovoip,bananapi-m4-berry
+          - const: allwinner,sun50i-h618
+
       - description: BananaPi M64
         items:
           - const: sinovoip,bananapi-m64
-- 
2.25.1



From andre.przywara at arm.com  Sun Feb  4 02:10:54 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun,  4 Feb 2024 11:10:54 +0100
Subject: [PATCH v2 2/2] arm64: dts: allwinner: h618: add BananaPi M4 Berry board
In-Reply-To: <20240204101054.152012-1-andre.przywara@arm.com>
References: <20240204101054.152012-1-andre.przywara@arm.com>
Message-ID: <20240204101054.152012-3-andre.przywara@arm.com>

The BananaPi M4 Berry is a development board using the Allwinner H618
SoC. It comes with the following specs:
	- Allwinner H618 SoC (4 * Arm Cortex-A53 cores, 1MB L2 cache)
	- 2 GiB LPDDR4 DRAM
	- 8 GiB eMMC flash
	- AXP313a PMIC
	- Gigabit Ethernet, using RTL8211 PHY
	- RTL8821CU USB WiFi chip
	- HDMI port
	- 4 * USB 2.0 ports, via an on-board hub chip
	- microSD card slot
	- 3.5mm A/V port
	- power supply and USB-OTG via USB-C connector

Add a devicetree file describing the components that we already have
bindings for, that excludes audio and video at the moment.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../sun50i-h618-bananapi-m4-berry.dts         | 223 ++++++++++++++++++
 2 files changed, 224 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 2db3b15ad09f..1c5c204a109b 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -43,5 +43,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-bananapi-m4-berry.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
new file mode 100644
index 000000000000..a3f8ff75db42
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2023 Arm Ltd.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "BananaPi M4 Berry";
+	compatible = "sinovoip,bananapi-m4-berry", "allwinner,sun50i-h618";
+
+	aliases {
+		ethernet0 = &emac0;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			function = LED_FUNCTION_STATUS;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&pio 2 12 GPIO_ACTIVE_LOW>; /* PC12 */
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		key-sw3 {
+			label = "sw3";
+			linux,code = <BTN_0>;
+			gpios = <&pio 2 7 GPIO_ACTIVE_LOW>;	/* PC7 */
+		};
+	};
+
+	reg_vcc5v: regulator-5v {
+		/* board wide 5V supply directly from the USB-C socket */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	reg_usb_vbus: regulator-usb-vbus {
+		/* separate discrete regulator for the USB ports */
+		compatible = "regulator-fixed";
+		regulator-name = "usb-vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&reg_vcc5v>;
+	};
+
+	reg_3v3: regulator-3v3 {
+		/* separate discrete regulator for WiFi and Ethernet PHY */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&reg_vcc5v>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+/* Connected to an on-board RTL8821CU USB WiFi chip. */
+&ehci1 {
+	status = "okay";
+};
+
+/* EHCI2 is on unpopulated pins */
+
+/* Connected to an on-board FE1.1s USB hub chip, supplying 4 USB-A ports. */
+&ehci3 {
+	status = "okay";
+};
+
+&emac0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ext_rgmii_pins>;
+	phy-mode = "rgmii";
+	phy-handle = <&ext_rgmii_phy>;
+	phy-supply = <&reg_3v3>;
+	allwinner,rx-delay-ps = <3100>;
+	allwinner,tx-delay-ps = <700>;
+	status = "okay";
+};
+
+&ir {
+	status = "okay";
+};
+
+&mdio0 {
+	ext_rgmii_phy: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <1>;
+		reset-gpios = <&pio 8 16 GPIO_ACTIVE_LOW>;	/* PI16 */
+	};
+};
+
+&mmc0 {
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;	/* PF6 */
+	vmmc-supply = <&reg_dldo1>;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&mmc2 {
+	vmmc-supply = <&reg_dldo1>;
+	vqmmc-supply = <&reg_aldo1>;
+	bus-width = <8>;
+	non-removable;
+	cap-mmc-hw-reset;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	status = "okay";
+};
+
+/* USB ports 1 and 3 connect to onboard devices that are high-speed only. */
+
+/* OHCI2 is on unpopulated pins */
+
+&pio {
+	vcc-pc-supply = <&reg_aldo1>;
+	vcc-pf-supply = <&reg_dldo1>;
+	vcc-pg-supply = <&reg_dldo1>;
+	vcc-ph-supply = <&reg_dldo1>;
+	vcc-pi-supply = <&reg_dldo1>;
+};
+
+&r_i2c {
+	status = "okay";
+
+	axp313: pmic at 36 {
+		compatible = "x-powers,axp313a";
+		reg = <0x36>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		interrupt-parent = <&pio>;
+
+		vin1-supply = <&reg_vcc5v>;
+		vin2-supply = <&reg_vcc5v>;
+		vin3-supply = <&reg_vcc5v>;
+
+		regulators {
+			reg_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc-1v8-pll";
+			};
+
+			reg_dldo1: dldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-3v3-io";
+			};
+
+			reg_dcdc1: dcdc1 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <990000>;
+				regulator-name = "vdd-gpu-sys";
+			};
+
+			reg_dcdc2: dcdc2 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-cpu";
+			};
+
+			reg_dcdc3: dcdc3 {
+				regulator-always-on;
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-dram";
+			};
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ph_pins>;
+	status = "okay";
+};
+
+&usbotg {
+	/*
+	 * PHY0 pins are connected to a USB-C socket, but a role switch is not
+	 * implemented: both CC pins are pulled to GND via a 5.1K resistor.
+	 * The VBUS pins power the device, so a fixed peripheral mode
+	 * is the best choice.
+	 * The board can be powered via GPIOs, in this case port0 *can*
+	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
+	 * then provided by the GPIOs. Any user of this setup would
+	 * need to adjust the DT accordingly: dr_mode set to "host",
+	 * enabling OHCI0 and EHCI0.
+	 */
+	dr_mode = "peripheral";
+	status = "okay";
+};
+
+&usbphy {
+	usb3_vbus-supply = <&reg_usb_vbus>;
+	status = "okay";
+};
-- 
2.25.1



From Sandor.yu at nxp.com  Sun Feb  4 02:21:45 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Sun,  4 Feb 2024 18:21:45 +0800
Subject: [PATCH v13 0/7] Initial support Cadence MHDP8501(HDMI/DP) for i.MX8MQ
Message-ID: <cover.1707040881.git.Sandor.yu@nxp.com>

The patch set initial support Cadence MHDP8501(HDMI/DP) DRM bridge
driver and Cadence HDP-TX PHY(HDMI/DP) drivers for Freescale i.MX8MQ.

The patch set compose of DRM bridge drivers and PHY drivers.

Both of them need by patch #1 and #2 to pass build.

DRM bridges driver patches:
  #1: drm: bridge: Cadence: Creat mhdp helper driver
  #2: phy: Add HDMI configuration options
  #3: dt-bindings: display: bridge: Add Cadence MHDP8501
  #4: drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver

PHY driver patches:
  #1: drm: bridge: Cadence: Creat mhdp helper driver
  #2: phy: Add HDMI configuration options
  #5: dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
  #6: phy: freescale: Add DisplayPort PHY driver for i.MX8MQ
  #7: phy: freescale: Add HDMI PHY driver for i.MX8MQ

v12->v13:
Patch #4:
- Explicitly include linux/platform_device.h for cdns-mhdp8501-core.c
- Fix build warning
- Order bit bpc and color_space in descending shit. 
Patch #7:
- Fix build warning

v11->v12:
Patch #1: 
- Move status initialize out of mbox_mutex.
- Reorder API functions in alphabetical.
- Add notes for malibox access functions.
- Add year 2024 to copyright.
Patch #4:
- Replace DRM_INFO with dev_info or dev_warn.
- Replace DRM_ERROR with dev_err.
- Return ret when cdns_mhdp_dpcd_read failed in function cdns_dp_aux_transferi().
- Remove unused parmeter in function cdns_dp_get_msa_misc
  and use two separate variables for color space and bpc.
- Add year 2024 to copyright.
Patch #6:
- Return error code to replace -1 for function wait_for_ack().
- Set cdns_phy->power_up = false in phy_power_down function.
- Remove "RATE_8_1 = 810000", it is not used in driver.
- Add year 2024 to copyright.
Patch #7:
- Adjust clk disable order.
- Return error code to replace -1 for function wait_for_ack().
- Use bool for variable pclk_in.
- Add year 2024 to copyright.

v10->v11:
- rewrite cdns_mhdp_set_firmware_active() in mhdp8546 core driver,
use cdns_mhdp_mailbox_send() to replace cdns_mhdp_mailbox_write()
same as the other mailbox access functions.
- use static for cdns_mhdp_mailbox_write() and cdns_mhdp_mailbox_read()
and remove them from EXPORT_SYMBOL_GPL().
- remove MODULE_ALIAS() from mhdp8501 driver.

v9->v10:
- Create mhdp helper driver to replace macro functions,
move all mhdp mailbox access functions and common functions
into the helper driver.
Patch #1:drm: bridge: Cadence: Creat mhdp helper driver
it is totaly different with v9.

v8->v9:
- Remove compatible string "cdns,mhdp8501" that had removed
  from dt-bindings file in v8.
- Add Dmitry's R-b tag to patch #2
- Add Krzysztof's R-b tag to patch #3

v7->v8:
MHDP8501 HDMI/DP:
- Correct DT node name to "display-bridge".
- Remove "cdns,mhdp8501" from mhdp8501 dt-binding doc.

HDMI/DP PHY:
- Introduced functions `wait_for_ack` and `wait_for_ack_clear` to handle
  waiting with acknowledgment bits set and cleared respectively.
- Use FIELD_PRE() to set bitfields for both HDMI and DP PHY.

v6->v7:
MHDP8501 HDMI/DP:
- Combine HDMI and DP driver into one mhdp8501 driver.
  Use the connector type to load the corresponding functions.
- Remove connector init functions.
- Add <linux/hdmi.h> in phy_hdmi.h to reuse ?enum hdmi_colorspace?.

HDMI/DP PHY:
- Lowercase hex values
- Fix parameters indent issue on some functions
- Replace ?udelay? with ?usleep_range?

v5->v6:
HDMI/DP bridge driver
- 8501 is the part number of Cadence MHDP on i.MX8MQ.
  Use MHDP8501 to name hdmi/dp drivers and files. 
- Add compatible "fsl,imx8mq-mhdp8501-dp" for i.MX8MQ DP driver
- Add compatible "fsl,imx8mq-mhdp8501-hdmi" for i.MX8MQ HDMI driver
- Combine HDMI and DP dt-bindings into one file cdns,mhdp8501.yaml
- Fix HDMI scrambling is not enable issue when driver working in 4Kp60
  mode.
- Add HDMI/DP PHY API mailbox protect.

HDMI/DP PHY driver:
- Rename DP and HDMI PHY files and move to folder phy/freescale/
- Remove properties num_lanes and link_rate from DP PHY driver.
- Combine HDMI and DP dt-bindings into one file fsl,imx8mq-dp-hdmi-phy.yaml
- Update compatible string to "fsl,imx8mq-dp-phy".
- Update compatible string to "fsl,imx8mq-hdmi-phy".

v4->v5:
- Drop "clk" suffix in clock name.
- Add output port property in the example of hdmi/dp.

v3->v4:
dt-bindings:
- Correct dt-bindings coding style and address review comments.
- Add apb_clk description.
- Add output port for HDMI/DP connector
PHY:
- Alphabetically sorted in Kconfig and Makefile for DP and HDMI PHY
- Remove unused registers define from HDMI and DP PHY drivers.
- More description in phy_hdmi.h.
- Add apb_clk to HDMI and DP phy driver.
HDMI/DP:
- Use get_unaligned_le32() to replace hardcode type conversion
  in HDMI AVI infoframe data fill function.
- Add mailbox mutex lock in HDMI/DP driver for phy functions
  to reslove race conditions between HDMI/DP and PHY drivers.
- Add apb_clk to both HDMI and DP driver.
- Rename some function names and add prefix with "cdns_hdmi/cdns_dp".
- Remove bpc 12 and 16 optional that not supported.

v2->v3:
Address comments for dt-bindings files.
- Correct dts-bindings file names 
  Rename phy-cadence-hdptx-dp.yaml to cdns,mhdp-imx8mq-dp.yaml
  Rename phy-cadence-hdptx-hdmi.yaml to cdns,mhdp-imx8mq-hdmi.yaml
- Drop redundant words and descriptions.
- Correct hdmi/dp node name.

v2 is a completely different version compared to v1.
Previous v1 can be available here [1].

v1->v2:
- Reuse Cadence mailbox access functions from mhdp8546 instead of
  rockchip DP.
- Mailbox access functions be convert to marco functions
  that will be referenced by HDP-TX PHY(HDMI/DP) driver too.
- Plain bridge instead of component driver.
- Standalone Cadence HDP-TX PHY(HDMI/DP) driver.
- Audio driver are removed from the patch set, it will be add in another
  patch set later.

[1] https://patchwork.kernel.org/project/linux-rockchip/cover/cover.1590982881.git.Sandor.yu at nxp.com/
Sandor Yu (7):
  drm: bridge: Cadence: Create mhdp helper driver
  phy: Add HDMI configuration options
  dt-bindings: display: bridge: Add Cadence MHDP8501
  drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
  dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
  phy: freescale: Add DisplayPort PHY driver for i.MX8MQ
  phy: freescale: Add HDMI PHY driver for i.MX8MQ

 .../display/bridge/cdns,mhdp8501.yaml         | 104 ++
 .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  |  53 +
 drivers/gpu/drm/bridge/cadence/Kconfig        |  20 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   3 +
 .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c | 304 ++++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 316 ++++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 365 +++++++
 .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 699 +++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 679 +++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 403 ++------
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  44 +-
 drivers/phy/freescale/Kconfig                 |  20 +
 drivers/phy/freescale/Makefile                |   2 +
 drivers/phy/freescale/phy-fsl-imx8mq-dp.c     | 726 +++++++++++++
 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c   | 960 ++++++++++++++++++
 include/drm/bridge/cdns-mhdp-helper.h         |  97 ++
 include/linux/phy/phy-hdmi.h                  |  24 +
 include/linux/phy/phy.h                       |   7 +-
 18 files changed, 4451 insertions(+), 375 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-dp.c
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
 create mode 100644 include/drm/bridge/cdns-mhdp-helper.h
 create mode 100644 include/linux/phy/phy-hdmi.h

-- 
2.34.1



From Sandor.yu at nxp.com  Sun Feb  4 02:21:46 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Sun,  4 Feb 2024 18:21:46 +0800
Subject: [PATCH v13 1/7] drm: bridge: Cadence: Create mhdp helper driver
In-Reply-To: <cover.1707040881.git.Sandor.yu@nxp.com>
References: <cover.1707040881.git.Sandor.yu@nxp.com>
Message-ID: <39925d02479498f81836a7854707301ca6d2de73.1707040881.git.Sandor.yu@nxp.com>

MHDP8546 mailbox access functions will be share to other mhdp driver
and Cadence HDP-TX HDMI/DP PHY drivers.
Create a new mhdp helper driver and move all those functions into.

cdns_mhdp_reg_write() is renamed to cdns_mhdp_dp_reg_write(),
because it use the DPTX command ID DPTX_WRITE_REGISTER.

New cdns_mhdp_reg_write() is created with the general command ID
GENERAL_REGISTER_WRITE.

rewrite cdns_mhdp_set_firmware_active() in mhdp8546 core driver,
use cdns_mhdp_mailbox_send() to replace cdns_mhdp_mailbox_write()
same as the other mailbox access functions.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
---
v12->v13:
 *No change.

V11->v12:
- Move status initialize out of mbox_mutex.
- Reorder API functions in alphabetical.
- Add notes for malibox access functions.
- Add year 2024 to copyright.

 drivers/gpu/drm/bridge/cadence/Kconfig        |   4 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   1 +
 .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c | 304 +++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 403 +++---------------
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  44 +-
 include/drm/bridge/cdns-mhdp-helper.h         |  97 +++++
 6 files changed, 479 insertions(+), 374 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
 create mode 100644 include/drm/bridge/cdns-mhdp-helper.h

diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig
index cced81633ddcd..e0973339e9e33 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -21,6 +21,9 @@ config DRM_CDNS_DSI_J721E
 	  the routing of the DSS DPI signal to the Cadence DSI.
 endif
 
+config CDNS_MHDP_HELPER
+	tristate
+
 config DRM_CDNS_MHDP8546
 	tristate "Cadence DPI/DP bridge"
 	select DRM_DISPLAY_DP_HELPER
@@ -28,6 +31,7 @@ config DRM_CDNS_MHDP8546
 	select DRM_DISPLAY_HELPER
 	select DRM_KMS_HELPER
 	select DRM_PANEL_BRIDGE
+	select CDNS_MHDP_HELPER
 	depends on OF
 	help
 	  Support Cadence DPI to DP bridge. This is an internal
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile
index c95fd5b81d137..087dc074820d7 100644
--- a/drivers/gpu/drm/bridge/cadence/Makefile
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
 cdns-dsi-y := cdns-dsi-core.o
 cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o
+obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
 cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
new file mode 100644
index 0000000000000..ba31695b483ac
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <linux/dev_printk.h>
+#include <linux/module.h>
+
+/* Mailbox helper functions */
+static int cdns_mhdp_mailbox_read(struct cdns_mhdp_base *base)
+{
+	int ret, empty;
+
+	WARN_ON(!mutex_is_locked(base->mbox_mutex));
+
+	ret = readx_poll_timeout(readl, base->regs + CDNS_MAILBOX_EMPTY,
+				 empty, !empty, MAILBOX_RETRY_US,
+				 MAILBOX_TIMEOUT_US);
+	if (ret < 0)
+		return ret;
+
+	return readl(base->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
+}
+
+static int cdns_mhdp_mailbox_write(struct cdns_mhdp_base *base, u8 val)
+{
+	int ret, full;
+
+	WARN_ON(!mutex_is_locked(base->mbox_mutex));
+
+	ret = readx_poll_timeout(readl, base->regs + CDNS_MAILBOX_FULL,
+				 full, !full, MAILBOX_RETRY_US,
+				 MAILBOX_TIMEOUT_US);
+	if (ret < 0)
+		return ret;
+
+	writel(val, base->regs + CDNS_MAILBOX_TX_DATA);
+
+	return 0;
+}
+
+int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_base *base,
+				  u8 module_id, u8 opcode,
+				  u16 req_size)
+{
+	u32 mbox_size, i;
+	u8 header[4];
+	int ret;
+
+	/* read the header of the message */
+	for (i = 0; i < sizeof(header); i++) {
+		ret = cdns_mhdp_mailbox_read(base);
+		if (ret < 0)
+			return ret;
+
+		header[i] = ret;
+	}
+
+	mbox_size = get_unaligned_be16(header + 2);
+
+	if (opcode != header[0] || module_id != header[1] ||
+	    req_size != mbox_size) {
+		/*
+		 * If the message in mailbox is not what we want, we need to
+		 * clear the mailbox by reading its contents.
+		 */
+		for (i = 0; i < mbox_size; i++)
+			if (cdns_mhdp_mailbox_read(base) < 0)
+				break;
+
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_recv_header);
+
+int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_base *base,
+				u8 *buff, u16 buff_size)
+{
+	u32 i;
+	int ret;
+
+	for (i = 0; i < buff_size; i++) {
+		ret = cdns_mhdp_mailbox_read(base);
+		if (ret < 0)
+			return ret;
+
+		buff[i] = ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_recv_data);
+
+int cdns_mhdp_mailbox_send(struct cdns_mhdp_base *base, u8 module_id,
+			   u8 opcode, u16 size, u8 *message)
+{
+	u8 header[4];
+	int ret, i;
+
+	header[0] = opcode;
+	header[1] = module_id;
+	put_unaligned_be16(size, header + 2);
+
+	for (i = 0; i < sizeof(header); i++) {
+		ret = cdns_mhdp_mailbox_write(base, header[i]);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < size; i++) {
+		ret = cdns_mhdp_mailbox_write(base, message[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_send);
+
+/* General helper functions */
+int cdns_mhdp_reg_read(struct cdns_mhdp_base *base, u32 addr, u32 *value)
+{
+	u8 msg[4], resp[8];
+	int ret;
+
+	put_unaligned_be32(addr, msg);
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_GENERAL,
+				     GENERAL_REGISTER_READ,
+				     sizeof(msg), msg);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_header(base, MB_MODULE_ID_GENERAL,
+					    GENERAL_REGISTER_READ,
+					    sizeof(resp));
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, resp, sizeof(resp));
+	if (ret)
+		goto out;
+
+	/* Returned address value should be the same as requested */
+	if (memcmp(msg, resp, sizeof(msg))) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	*value = get_unaligned_be32(resp + 4);
+
+out:
+	mutex_unlock(base->mbox_mutex);
+	if (ret) {
+		dev_err(base->dev, "Failed to read register\n");
+		*value = 0;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_reg_read);
+
+int cdns_mhdp_reg_write(struct cdns_mhdp_base *base, u32 addr, u32 val)
+{
+	u8 msg[8];
+	int ret;
+
+	put_unaligned_be32(addr, msg);
+	put_unaligned_be32(val, msg + 4);
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_GENERAL,
+				     GENERAL_REGISTER_WRITE,
+				     sizeof(msg), msg);
+
+	mutex_unlock(base->mbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_reg_write);
+
+/* DPTX helper functions */
+int cdns_mhdp_dp_reg_write(struct cdns_mhdp_base *base, u16 addr, u32 val)
+{
+	u8 msg[6];
+	int ret;
+
+	put_unaligned_be16(addr, msg);
+	put_unaligned_be32(val, msg + 2);
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_WRITE_REGISTER, sizeof(msg), msg);
+
+	mutex_unlock(base->mbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dp_reg_write);
+
+int cdns_mhdp_dp_reg_write_bit(struct cdns_mhdp_base *base, u16 addr,
+			       u8 start_bit, u8 bits_no, u32 val)
+{
+	u8 field[8];
+	int ret;
+
+	put_unaligned_be16(addr, field);
+	field[2] = start_bit;
+	field[3] = bits_no;
+	put_unaligned_be32(val, field + 4);
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_WRITE_FIELD, sizeof(field), field);
+
+	mutex_unlock(base->mbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dp_reg_write_bit);
+
+int cdns_mhdp_dpcd_read(struct cdns_mhdp_base *base,
+			u32 addr, u8 *data, u16 len)
+{
+	u8 msg[5], reg[5];
+	int ret;
+
+	put_unaligned_be16(len, msg);
+	put_unaligned_be24(addr, msg + 2);
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_READ_DPCD, sizeof(msg), msg);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_header(base, MB_MODULE_ID_DP_TX,
+					    DPTX_READ_DPCD,
+					    sizeof(reg) + len);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, reg, sizeof(reg));
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, data, len);
+
+out:
+	mutex_unlock(base->mbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dpcd_read);
+
+int cdns_mhdp_dpcd_write(struct cdns_mhdp_base *base, u32 addr, u8 value)
+{
+	u8 msg[6], reg[5];
+	int ret;
+
+	put_unaligned_be16(1, msg);
+	put_unaligned_be24(addr, msg + 2);
+	msg[5] = value;
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_WRITE_DPCD, sizeof(msg), msg);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_header(base, MB_MODULE_ID_DP_TX,
+					    DPTX_WRITE_DPCD, sizeof(reg));
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, reg, sizeof(reg));
+	if (ret)
+		goto out;
+
+	if (addr != get_unaligned_be24(reg + 2))
+		ret = -EINVAL;
+
+out:
+	mutex_unlock(base->mbox_mutex);
+
+	if (ret)
+		dev_err(base->dev, "dpcd write failed: %d\n", ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dpcd_write);
+
+MODULE_DESCRIPTION("Cadence MHDP Helper driver");
+MODULE_AUTHOR("Sandor Yu <Sandor.yu at nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index 7d470527455b1..a3c5b7f1c94e5 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -73,298 +73,28 @@ static void cdns_mhdp_bridge_hpd_disable(struct drm_bridge *bridge)
 	       mhdp->regs + CDNS_APB_INT_MASK);
 }
 
-static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
-{
-	int ret, empty;
-
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
-
-	ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_EMPTY,
-				 empty, !empty, MAILBOX_RETRY_US,
-				 MAILBOX_TIMEOUT_US);
-	if (ret < 0)
-		return ret;
-
-	return readl(mhdp->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
-}
-
-static int cdns_mhdp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val)
-{
-	int ret, full;
-
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
-
-	ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_FULL,
-				 full, !full, MAILBOX_RETRY_US,
-				 MAILBOX_TIMEOUT_US);
-	if (ret < 0)
-		return ret;
-
-	writel(val, mhdp->regs + CDNS_MAILBOX_TX_DATA);
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_device *mhdp,
-					 u8 module_id, u8 opcode,
-					 u16 req_size)
-{
-	u32 mbox_size, i;
-	u8 header[4];
-	int ret;
-
-	/* read the header of the message */
-	for (i = 0; i < sizeof(header); i++) {
-		ret = cdns_mhdp_mailbox_read(mhdp);
-		if (ret < 0)
-			return ret;
-
-		header[i] = ret;
-	}
-
-	mbox_size = get_unaligned_be16(header + 2);
-
-	if (opcode != header[0] || module_id != header[1] ||
-	    req_size != mbox_size) {
-		/*
-		 * If the message in mailbox is not what we want, we need to
-		 * clear the mailbox by reading its contents.
-		 */
-		for (i = 0; i < mbox_size; i++)
-			if (cdns_mhdp_mailbox_read(mhdp) < 0)
-				break;
-
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_device *mhdp,
-				       u8 *buff, u16 buff_size)
-{
-	u32 i;
-	int ret;
-
-	for (i = 0; i < buff_size; i++) {
-		ret = cdns_mhdp_mailbox_read(mhdp);
-		if (ret < 0)
-			return ret;
-
-		buff[i] = ret;
-	}
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id,
-				  u8 opcode, u16 size, u8 *message)
-{
-	u8 header[4];
-	int ret, i;
-
-	header[0] = opcode;
-	header[1] = module_id;
-	put_unaligned_be16(size, header + 2);
-
-	for (i = 0; i < sizeof(header); i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, header[i]);
-		if (ret)
-			return ret;
-	}
-
-	for (i = 0; i < size; i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, message[i]);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-static
-int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr, u32 *value)
-{
-	u8 msg[4], resp[8];
-	int ret;
-
-	put_unaligned_be32(addr, msg);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL,
-				     GENERAL_REGISTER_READ,
-				     sizeof(msg), msg);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_GENERAL,
-					    GENERAL_REGISTER_READ,
-					    sizeof(resp));
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, resp, sizeof(resp));
-	if (ret)
-		goto out;
-
-	/* Returned address value should be the same as requested */
-	if (memcmp(msg, resp, sizeof(msg))) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	*value = get_unaligned_be32(resp + 4);
-
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
-	if (ret) {
-		dev_err(mhdp->dev, "Failed to read register\n");
-		*value = 0;
-	}
-
-	return ret;
-}
-
-static
-int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u16 addr, u32 val)
-{
-	u8 msg[6];
-	int ret;
-
-	put_unaligned_be16(addr, msg);
-	put_unaligned_be32(val, msg + 2);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_REGISTER, sizeof(msg), msg);
-
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
 static
-int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr,
-			    u8 start_bit, u8 bits_no, u32 val)
-{
-	u8 field[8];
-	int ret;
-
-	put_unaligned_be16(addr, field);
-	field[2] = start_bit;
-	field[3] = bits_no;
-	put_unaligned_be32(val, field + 4);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_FIELD, sizeof(field), field);
-
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
-static
-int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp,
-			u32 addr, u8 *data, u16 len)
-{
-	u8 msg[5], reg[5];
-	int ret;
-
-	put_unaligned_be16(len, msg);
-	put_unaligned_be24(addr, msg + 2);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_READ_DPCD, sizeof(msg), msg);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
-					    DPTX_READ_DPCD,
-					    sizeof(reg) + len);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, data, len);
-
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
-static
-int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value)
+int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable)
 {
-	u8 msg[6], reg[5];
+	u8 status;
 	int ret;
 
-	put_unaligned_be16(1, msg);
-	put_unaligned_be24(addr, msg + 2);
-	msg[5] = value;
+	status = enable ? FW_ACTIVE : FW_STANDBY;
 
 	mutex_lock(&mhdp->mbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_DPCD, sizeof(msg), msg);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
-					    DPTX_WRITE_DPCD, sizeof(reg));
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_GENERAL,
+				     GENERAL_MAIN_CONTROL, sizeof(status), &status);
 	if (ret)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
-	if (ret)
-		goto out;
-
-	if (addr != get_unaligned_be24(reg + 2))
-		ret = -EINVAL;
-
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	if (ret)
-		dev_err(mhdp->dev, "dpcd write failed: %d\n", ret);
-	return ret;
-}
-
-static
-int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable)
-{
-	u8 msg[5];
-	int ret, i;
-
-	msg[0] = GENERAL_MAIN_CONTROL;
-	msg[1] = MB_MODULE_ID_GENERAL;
-	msg[2] = 0;
-	msg[3] = 1;
-	msg[4] = enable ? FW_ACTIVE : FW_STANDBY;
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	for (i = 0; i < sizeof(msg); i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, msg[i]);
-		if (ret)
-			goto out;
-	}
-
-	/* read the firmware state */
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, msg, sizeof(msg));
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_GENERAL,
+					    GENERAL_MAIN_CONTROL,
+					    sizeof(status));
 	if (ret)
 		goto out;
 
-	ret = 0;
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
 
 out:
 	mutex_unlock(&mhdp->mbox_mutex);
@@ -382,18 +112,18 @@ int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp)
 
 	mutex_lock(&mhdp->mbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 				     DPTX_HPD_STATE, 0, NULL);
 	if (ret)
 		goto err_get_hpd;
 
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 					    DPTX_HPD_STATE,
 					    sizeof(status));
 	if (ret)
 		goto err_get_hpd;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, &status, sizeof(status));
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
 	if (ret)
 		goto err_get_hpd;
 
@@ -424,22 +154,22 @@ int cdns_mhdp_get_edid_block(void *data, u8 *edid,
 		msg[0] = block / 2;
 		msg[1] = block % 2;
 
-		ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 					     DPTX_GET_EDID, sizeof(msg), msg);
 		if (ret)
 			continue;
 
-		ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 						    DPTX_GET_EDID,
 						    sizeof(reg) + length);
 		if (ret)
 			continue;
 
-		ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
 		if (ret)
 			continue;
 
-		ret = cdns_mhdp_mailbox_recv_data(mhdp, edid, length);
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid, length);
 		if (ret)
 			continue;
 
@@ -464,17 +194,17 @@ int cdns_mhdp_read_hpd_event(struct cdns_mhdp_device *mhdp)
 
 	mutex_lock(&mhdp->mbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 				     DPTX_READ_EVENT, 0, NULL);
 	if (ret)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 					    DPTX_READ_EVENT, sizeof(event));
 	if (ret < 0)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, &event, sizeof(event));
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &event, sizeof(event));
 out:
 	mutex_unlock(&mhdp->mbox_mutex);
 
@@ -512,20 +242,20 @@ int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, unsigned int nlanes,
 
 	mutex_lock(&mhdp->mbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 				     DPTX_ADJUST_LT,
 				     sizeof(payload), payload);
 	if (ret)
 		goto out;
 
 	/* Yes, read the DPCD read command response */
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 					    DPTX_READ_DPCD,
 					    sizeof(hdr) + DP_LINK_STATUS_SIZE);
 	if (ret)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, hdr, sizeof(hdr));
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, hdr, sizeof(hdr));
 	if (ret)
 		goto out;
 
@@ -533,7 +263,7 @@ int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, unsigned int nlanes,
 	if (addr != DP_LANE0_1_STATUS)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, link_status,
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, link_status,
 					  DP_LINK_STATUS_SIZE);
 
 out:
@@ -847,7 +577,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux,
 		unsigned int i;
 
 		for (i = 0; i < msg->size; ++i) {
-			ret = cdns_mhdp_dpcd_write(mhdp,
+			ret = cdns_mhdp_dpcd_write(&mhdp->base,
 						   msg->address + i, buf[i]);
 			if (!ret)
 				continue;
@@ -859,7 +589,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux,
 			return ret;
 		}
 	} else {
-		ret = cdns_mhdp_dpcd_read(mhdp, msg->address,
+		ret = cdns_mhdp_dpcd_read(&mhdp->base, msg->address,
 					  msg->buffer, msg->size);
 		if (ret) {
 			dev_err(mhdp->dev,
@@ -887,12 +617,12 @@ static int cdns_mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 	if (!mhdp->host.scrambler)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_ENHNCD,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_ENHNCD,
 			    mhdp->sink.enhanced & mhdp->host.enhanced);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_LANE_EN,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_LANE_EN,
 			    CDNS_DP_LANE_EN_LANES(mhdp->link.num_lanes));
 
 	cdns_mhdp_link_configure(&mhdp->aux, &mhdp->link);
@@ -913,7 +643,7 @@ static int cdns_mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 		return ret;
 	}
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG,
 			    CDNS_PHY_COMMON_CONFIG |
 			    CDNS_PHY_TRAINING_EN |
 			    CDNS_PHY_TRAINING_TYPE(1) |
@@ -1058,7 +788,7 @@ static bool cdns_mhdp_link_training_channel_eq(struct cdns_mhdp_device *mhdp,
 		CDNS_PHY_TRAINING_TYPE(eq_tps);
 	if (eq_tps != 4)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
 	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 			   (eq_tps != 4) ? eq_tps | DP_LINK_SCRAMBLING_DISABLE :
@@ -1322,7 +1052,7 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp,
 			   mhdp->host.scrambler ? 0 :
 			   DP_LINK_SCRAMBLING_DISABLE);
 
-	ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &reg32);
+	ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &reg32);
 	if (ret < 0) {
 		dev_err(mhdp->dev,
 			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
@@ -1333,13 +1063,13 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp,
 	reg32 |= CDNS_DP_NUM_LANES(mhdp->link.num_lanes);
 	reg32 |= CDNS_DP_WR_FAILING_EDGE_VSYNC;
 	reg32 |= CDNS_DP_FRAMER_EN;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg32);
 
 	/* Reset PHY config */
 	reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
 	if (!mhdp->host.scrambler)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
 	return 0;
 err:
@@ -1347,7 +1077,7 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp,
 	reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
 	if (!mhdp->host.scrambler)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
 	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 			   DP_TRAINING_PATTERN_DISABLE);
@@ -1461,7 +1191,7 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
 	mhdp->link.num_lanes = cdns_mhdp_max_num_lanes(mhdp);
 
 	/* Disable framer for link training */
-	err = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
+	err = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
 	if (err < 0) {
 		dev_err(mhdp->dev,
 			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
@@ -1470,7 +1200,7 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
 	}
 
 	resp &= ~CDNS_DP_FRAMER_EN;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
 
 	/* Spread AMP if required, enable 8b/10b coding */
 	amp[0] = cdns_mhdp_get_ssc_supported(mhdp) ? DP_SPREAD_AMP_0_5 : 0;
@@ -1837,7 +1567,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 		bnd_hsync2vsync |= CDNS_IP_DET_INTERLACE_FORMAT;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_BND_HSYNC2VSYNC(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_BND_HSYNC2VSYNC(stream_id),
 			    bnd_hsync2vsync);
 
 	hsync2vsync_pol_ctrl = 0;
@@ -1845,10 +1575,10 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 		hsync2vsync_pol_ctrl |= CDNS_H2V_HSYNC_POL_ACTIVE_LOW;
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 		hsync2vsync_pol_ctrl |= CDNS_H2V_VSYNC_POL_ACTIVE_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_HSYNC2VSYNC_POL_CTRL(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_HSYNC2VSYNC_POL_CTRL(stream_id),
 			    hsync2vsync_pol_ctrl);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_PXL_REPR(stream_id), pxl_repr);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_PXL_REPR(stream_id), pxl_repr);
 
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 		dp_framer_sp |= CDNS_DP_FRAMER_INTERLACE;
@@ -1856,19 +1586,19 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 		dp_framer_sp |= CDNS_DP_FRAMER_HSYNC_POL_LOW;
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 		dp_framer_sp |= CDNS_DP_FRAMER_VSYNC_POL_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_SP(stream_id), dp_framer_sp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_SP(stream_id), dp_framer_sp);
 
 	front_porch = mode->crtc_hsync_start - mode->crtc_hdisplay;
 	back_porch = mode->crtc_htotal - mode->crtc_hsync_end;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRONT_BACK_PORCH(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRONT_BACK_PORCH(stream_id),
 			    CDNS_DP_FRONT_PORCH(front_porch) |
 			    CDNS_DP_BACK_PORCH(back_porch));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_BYTE_COUNT(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_BYTE_COUNT(stream_id),
 			    mode->crtc_hdisplay * bpp / 8);
 
 	msa_h0 = mode->crtc_htotal - mode->crtc_hsync_start;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_0(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_HORIZONTAL_0(stream_id),
 			    CDNS_DP_MSAH0_H_TOTAL(mode->crtc_htotal) |
 			    CDNS_DP_MSAH0_HSYNC_START(msa_h0));
 
@@ -1877,11 +1607,11 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 			   CDNS_DP_MSAH1_HDISP_WIDTH(mode->crtc_hdisplay);
 	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 		msa_horizontal_1 |= CDNS_DP_MSAH1_HSYNC_POL_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_1(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_HORIZONTAL_1(stream_id),
 			    msa_horizontal_1);
 
 	msa_v0 = mode->crtc_vtotal - mode->crtc_vsync_start;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_0(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_VERTICAL_0(stream_id),
 			    CDNS_DP_MSAV0_V_TOTAL(mode->crtc_vtotal) |
 			    CDNS_DP_MSAV0_VSYNC_START(msa_v0));
 
@@ -1890,7 +1620,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 			 CDNS_DP_MSAV1_VDISP_WIDTH(mode->crtc_vdisplay);
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 		msa_vertical_1 |= CDNS_DP_MSAV1_VSYNC_POL_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_1(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_VERTICAL_1(stream_id),
 			    msa_vertical_1);
 
 	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
@@ -1902,14 +1632,14 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	if (pxlfmt == DRM_COLOR_FORMAT_YCBCR420)
 		misc1 = CDNS_DP_TEST_VSC_SDP;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_MISC(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_MISC(stream_id),
 			    misc0 | (misc1 << 8));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_HORIZONTAL(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_HORIZONTAL(stream_id),
 			    CDNS_DP_H_HSYNC_WIDTH(hsync) |
 			    CDNS_DP_H_H_TOTAL(mode->crtc_hdisplay));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_0(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_VERTICAL_0(stream_id),
 			    CDNS_DP_V0_VHEIGHT(mode->crtc_vdisplay) |
 			    CDNS_DP_V0_VSTART(msa_v0));
 
@@ -1918,13 +1648,13 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	    mode->crtc_vtotal % 2 == 0)
 		dp_vertical_1 |= CDNS_DP_V1_VTOTAL_EVEN;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_1(stream_id), dp_vertical_1);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_VERTICAL_1(stream_id), dp_vertical_1);
 
-	cdns_mhdp_reg_write_bit(mhdp, CDNS_DP_VB_ID(stream_id), 2, 1,
-				(mode->flags & DRM_MODE_FLAG_INTERLACE) ?
-				CDNS_DP_VB_ID_INTERLACED : 0);
+	cdns_mhdp_dp_reg_write_bit(&mhdp->base, CDNS_DP_VB_ID(stream_id), 2, 1,
+				   (mode->flags & DRM_MODE_FLAG_INTERLACE) ?
+				   CDNS_DP_VB_ID_INTERLACED : 0);
 
-	ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer);
+	ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer);
 	if (ret < 0) {
 		dev_err(mhdp->dev,
 			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
@@ -1933,7 +1663,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	}
 	framer |= CDNS_DP_FRAMER_EN;
 	framer &= ~CDNS_DP_NO_VIDEO_MODE;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer);
 }
 
 static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp,
@@ -1966,15 +1696,15 @@ static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp,
 
 	mhdp->stream_id = 0;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_TU,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_TU,
 			    CDNS_DP_FRAMER_TU_VS(vs) |
 			    CDNS_DP_FRAMER_TU_SIZE(tu_size) |
 			    CDNS_DP_FRAMER_TU_CNT_RST_EN);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_LINE_THRESH(0),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_LINE_THRESH(0),
 			    line_thresh & GENMASK(5, 0));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_STREAM_CONFIG_2(0),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_STREAM_CONFIG_2(0),
 			    CDNS_DP_SC2_TU_VS_DIFF((tu_size - vs > 3) ?
 						   0 : tu_size - vs));
 
@@ -2009,13 +1739,13 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
 		mhdp->info->ops->enable(mhdp);
 
 	/* Enable VIF clock for stream 0 */
-	ret = cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
+	ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DPTX_CAR, &resp);
 	if (ret < 0) {
 		dev_err(mhdp->dev, "Failed to read CDNS_DPTX_CAR %d\n", ret);
 		goto out;
 	}
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_CAR,
 			    resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN);
 
 	connector = drm_atomic_get_new_connector_for_encoder(state,
@@ -2083,16 +1813,16 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
 		cdns_mhdp_hdcp_disable(mhdp);
 
 	mhdp->bridge_enabled = false;
-	cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
+	cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
 	resp &= ~CDNS_DP_FRAMER_EN;
 	resp |= CDNS_DP_NO_VIDEO_MODE;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
 
 	cdns_mhdp_link_down(mhdp);
 
 	/* Disable VIF clock for stream 0 */
-	cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
+	cdns_mhdp_reg_read(&mhdp->base, CDNS_DPTX_CAR, &resp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_CAR,
 			    resp & ~(CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN));
 
 	if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable)
@@ -2502,6 +2232,11 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, mhdp);
 
+	/* init base struct for access mailbox  */
+	mhdp->base.dev = mhdp->dev;
+	mhdp->base.regs = mhdp->regs;
+	mhdp->base.mbox_mutex = &mhdp->mbox_mutex;
+
 	mhdp->info = of_device_get_match_data(dev);
 
 	clk_prepare_enable(clk);
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
index bad2fc0c73066..f08db38c82bbd 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
@@ -15,6 +15,7 @@
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 
+#include <drm/bridge/cdns-mhdp-helper.h>
 #include <drm/display/drm_dp_helper.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_connector.h>
@@ -27,10 +28,6 @@ struct phy;
 #define CDNS_APB_CTRL				0x00000
 #define CDNS_CPU_STALL				BIT(3)
 
-#define CDNS_MAILBOX_FULL			0x00008
-#define CDNS_MAILBOX_EMPTY			0x0000c
-#define CDNS_MAILBOX_TX_DATA			0x00010
-#define CDNS_MAILBOX_RX_DATA			0x00014
 #define CDNS_KEEP_ALIVE				0x00018
 #define CDNS_KEEP_ALIVE_MASK			GENMASK(7, 0)
 
@@ -198,45 +195,10 @@ struct phy;
 #define CDNS_DP_BYTE_COUNT(s)			(CDNS_DPTX_STREAM(s) + 0x7c)
 #define CDNS_DP_BYTE_COUNT_BYTES_IN_CHUNK_SHIFT	16
 
-/* mailbox */
-#define MAILBOX_RETRY_US			1000
-#define MAILBOX_TIMEOUT_US			2000000
-
-#define MB_OPCODE_ID				0
-#define MB_MODULE_ID				1
-#define MB_SIZE_MSB_ID				2
-#define MB_SIZE_LSB_ID				3
-#define MB_DATA_ID				4
-
-#define MB_MODULE_ID_DP_TX			0x01
-#define MB_MODULE_ID_HDCP_TX			0x07
-#define MB_MODULE_ID_HDCP_RX			0x08
-#define MB_MODULE_ID_HDCP_GENERAL		0x09
-#define MB_MODULE_ID_GENERAL			0x0a
-
-/* firmware and opcodes */
+/* firmware */
 #define FW_NAME					"cadence/mhdp8546.bin"
 #define CDNS_MHDP_IMEM				0x10000
 
-#define GENERAL_MAIN_CONTROL			0x01
-#define GENERAL_TEST_ECHO			0x02
-#define GENERAL_BUS_SETTINGS			0x03
-#define GENERAL_TEST_ACCESS			0x04
-#define GENERAL_REGISTER_READ			0x07
-
-#define DPTX_SET_POWER_MNG			0x00
-#define DPTX_GET_EDID				0x02
-#define DPTX_READ_DPCD				0x03
-#define DPTX_WRITE_DPCD				0x04
-#define DPTX_ENABLE_EVENT			0x05
-#define DPTX_WRITE_REGISTER			0x06
-#define DPTX_READ_REGISTER			0x07
-#define DPTX_WRITE_FIELD			0x08
-#define DPTX_READ_EVENT				0x0a
-#define DPTX_GET_LAST_AUX_STAUS			0x0e
-#define DPTX_HPD_STATE				0x11
-#define DPTX_ADJUST_LT				0x12
-
 #define FW_STANDBY				0
 #define FW_ACTIVE				1
 
@@ -352,6 +314,8 @@ struct cdns_mhdp_hdcp {
 };
 
 struct cdns_mhdp_device {
+	struct cdns_mhdp_base base;
+
 	void __iomem *regs;
 	void __iomem *sapb_regs;
 	void __iomem *j721e_regs;
diff --git a/include/drm/bridge/cdns-mhdp-helper.h b/include/drm/bridge/cdns-mhdp-helper.h
new file mode 100644
index 0000000000000..8fc74cf2799d3
--- /dev/null
+++ b/include/drm/bridge/cdns-mhdp-helper.h
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 NXP Semiconductor, Inc.
+ */
+#ifndef __CDNS_MHDP_HELPER_H__
+#define __CDNS_MHDP_HELPER_H__
+
+#include <asm/unaligned.h>
+#include <linux/iopoll.h>
+
+/* mailbox regs offset */
+#define CDNS_MAILBOX_FULL			0x00008
+#define CDNS_MAILBOX_EMPTY			0x0000c
+#define CDNS_MAILBOX_TX_DATA			0x00010
+#define CDNS_MAILBOX_RX_DATA			0x00014
+
+#define MAILBOX_RETRY_US			1000
+#define MAILBOX_TIMEOUT_US			2000000
+
+/* Module ID Code */
+#define MB_MODULE_ID_DP_TX			0x01
+#define MB_MODULE_ID_HDMI_TX			0x03
+#define MB_MODULE_ID_HDCP_TX			0x07
+#define MB_MODULE_ID_HDCP_RX			0x08
+#define MB_MODULE_ID_HDCP_GENERAL		0x09
+#define MB_MODULE_ID_GENERAL			0x0A
+
+/* General Commands */
+#define GENERAL_MAIN_CONTROL			0x01
+#define GENERAL_TEST_ECHO			0x02
+#define GENERAL_BUS_SETTINGS			0x03
+#define GENERAL_TEST_ACCESS			0x04
+#define GENERAL_REGISTER_WRITE			0x05
+#define GENERAL_WRITE_FIELD			0x06
+#define GENERAL_REGISTER_READ			0x07
+#define GENERAL_GET_HPD_STATE			0x11
+
+/* DPTX Commands */
+#define DPTX_SET_POWER_MNG			0x00
+#define DPTX_SET_HOST_CAPABILITIES		0x01
+#define DPTX_GET_EDID				0x02
+#define DPTX_READ_DPCD				0x03
+#define DPTX_WRITE_DPCD				0x04
+#define DPTX_ENABLE_EVENT			0x05
+#define DPTX_WRITE_REGISTER			0x06
+#define DPTX_READ_REGISTER			0x07
+#define DPTX_WRITE_FIELD			0x08
+#define DPTX_TRAINING_CONTROL			0x09
+#define DPTX_READ_EVENT				0x0a
+#define DPTX_READ_LINK_STAT			0x0b
+#define DPTX_SET_VIDEO				0x0c
+#define DPTX_SET_AUDIO				0x0d
+#define DPTX_GET_LAST_AUX_STAUS			0x0e
+#define DPTX_SET_LINK_BREAK_POINT		0x0f
+#define DPTX_FORCE_LANES			0x10
+#define DPTX_HPD_STATE				0x11
+#define DPTX_ADJUST_LT				0x12
+
+/* HDMI TX Commands */
+#define HDMI_TX_READ				0x00
+#define HDMI_TX_WRITE				0x01
+#define HDMI_TX_UPDATE_READ			0x02
+#define HDMI_TX_EDID				0x03
+#define HDMI_TX_EVENTS				0x04
+#define HDMI_TX_HPD_STATUS			0x05
+
+struct cdns_mhdp_base {
+	struct device *dev;
+	void __iomem *regs;
+	/* protect mailbox communications with the firmware */
+	struct mutex *mbox_mutex;
+};
+
+/* Mailbox helper functions
+ * mbox_mutex in struct cdns_mhdp_base should locked
+ * when access these functions.
+ */
+int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_base *base,
+				u8 *buff, u16 buff_size);
+int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_base *base,
+				  u8 module_id, u8 opcode, u16 req_size);
+int cdns_mhdp_mailbox_send(struct cdns_mhdp_base *base, u8 module_id,
+			   u8 opcode, u16 size, u8 *message);
+
+/* General commands helper functions */
+int cdns_mhdp_reg_read(struct cdns_mhdp_base *base, u32 addr, u32 *value);
+int cdns_mhdp_reg_write(struct cdns_mhdp_base *base, u32 addr, u32 val);
+
+/* DPTX commands helper functions */
+int cdns_mhdp_dp_reg_write(struct cdns_mhdp_base *base, u16 addr, u32 val);
+int cdns_mhdp_dp_reg_write_bit(struct cdns_mhdp_base *base, u16 addr,
+			       u8 start_bit, u8 bits_no, u32 val);
+int cdns_mhdp_dpcd_read(struct cdns_mhdp_base *base,
+			u32 addr, u8 *data, u16 len);
+int cdns_mhdp_dpcd_write(struct cdns_mhdp_base *base, u32 addr, u8 value);
+
+#endif /* __CDNS_MHDP_HELPER_H__ */
-- 
2.34.1



From Sandor.yu at nxp.com  Sun Feb  4 02:21:47 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Sun,  4 Feb 2024 18:21:47 +0800
Subject: [PATCH v13 2/7] phy: Add HDMI configuration options
In-Reply-To: <cover.1707040881.git.Sandor.yu@nxp.com>
References: <cover.1707040881.git.Sandor.yu@nxp.com>
Message-ID: <59d5595a24bbcca897e814440179fa2caf3dff38.1707040881.git.Sandor.yu@nxp.com>

Allow HDMI PHYs to be configured through the generic
functions through a custom structure added to the generic union.

The parameters added here are based on HDMI PHY
implementation practices.  The current set of parameters
should cover the potential users.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Acked-by: Vinod Koul <vkoul at kernel.org>
---
v9->v13:
 *No change.

 include/linux/phy/phy-hdmi.h | 24 ++++++++++++++++++++++++
 include/linux/phy/phy.h      |  7 ++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/phy/phy-hdmi.h

diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
new file mode 100644
index 0000000000000..b7de88e9090f0
--- /dev/null
+++ b/include/linux/phy/phy-hdmi.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022 NXP
+ */
+
+#ifndef __PHY_HDMI_H_
+#define __PHY_HDMI_H_
+
+#include <linux/hdmi.h>
+/**
+ * struct phy_configure_opts_hdmi - HDMI configuration set
+ * @pixel_clk_rate: Pixel clock of video modes in KHz.
+ * @bpc: Maximum bits per color channel.
+ * @color_space: Colorspace in enum hdmi_colorspace.
+ *
+ * This structure is used to represent the configuration state of a HDMI phy.
+ */
+struct phy_configure_opts_hdmi {
+	unsigned int pixel_clk_rate;
+	unsigned int bpc;
+	enum hdmi_colorspace color_space;
+};
+
+#endif /* __PHY_HDMI_H_ */
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index aa76609ba2580..0731b8b707f7c 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -17,6 +17,7 @@
 #include <linux/regulator/consumer.h>
 
 #include <linux/phy/phy-dp.h>
+#include <linux/phy/phy-hdmi.h>
 #include <linux/phy/phy-lvds.h>
 #include <linux/phy/phy-mipi-dphy.h>
 
@@ -42,7 +43,8 @@ enum phy_mode {
 	PHY_MODE_MIPI_DPHY,
 	PHY_MODE_SATA,
 	PHY_MODE_LVDS,
-	PHY_MODE_DP
+	PHY_MODE_DP,
+	PHY_MODE_HDMI,
 };
 
 enum phy_media {
@@ -60,11 +62,14 @@ enum phy_media {
  *		the DisplayPort protocol.
  * @lvds:	Configuration set applicable for phys supporting
  *		the LVDS phy mode.
+ * @hdmi:	Configuration set applicable for phys supporting
+ *		the HDMI phy mode.
  */
 union phy_configure_opts {
 	struct phy_configure_opts_mipi_dphy	mipi_dphy;
 	struct phy_configure_opts_dp		dp;
 	struct phy_configure_opts_lvds		lvds;
+	struct phy_configure_opts_hdmi		hdmi;
 };
 
 /**
-- 
2.34.1



From Sandor.yu at nxp.com  Sun Feb  4 02:21:48 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Sun,  4 Feb 2024 18:21:48 +0800
Subject: [PATCH v13 3/7] dt-bindings: display: bridge: Add Cadence MHDP8501
In-Reply-To: <cover.1707040881.git.Sandor.yu@nxp.com>
References: <cover.1707040881.git.Sandor.yu@nxp.com>
Message-ID: <84e90f01aabfae52d1e1506417d2dd31aa302964.1707040881.git.Sandor.yu@nxp.com>

Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
v9->v13:
 *No change.

 .../display/bridge/cdns,mhdp8501.yaml         | 104 ++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml

diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
new file mode 100644
index 0000000000000..3ae643845cfee
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
@@ -0,0 +1,104 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/cdns,mhdp8501.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence MHDP8501 DP/HDMI bridge
+
+maintainers:
+  - Sandor Yu <Sandor.yu at nxp.com>
+
+description:
+  Cadence MHDP8501 DisplayPort/HDMI interface.
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mq-mhdp8501
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: MHDP8501 DP/HDMI APB clock.
+
+  phys:
+    maxItems: 1
+    description:
+      phandle to the DisplayPort or HDMI PHY
+
+  interrupts:
+    items:
+      - description: Hotplug cable plugin.
+      - description: Hotplug cable plugout.
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Input port from display controller output.
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output port to DisplayPort or HDMI connector.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+  - phys
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    mhdp: display-bridge at 32c00000 {
+        compatible = "fsl,imx8mq-mhdp8501";
+        reg = <0x32c00000 0x100000>;
+        interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "plug_in", "plug_out";
+        clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        phys = <&dp_phy>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+
+                mhdp_in: endpoint {
+                    remote-endpoint = <&dcss_out>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+
+                mhdp_out: endpoint {
+                    remote-endpoint = <&dp_connector>;
+                };
+            };
+        };
+    };
-- 
2.34.1



From Sandor.yu at nxp.com  Sun Feb  4 02:21:49 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Sun,  4 Feb 2024 18:21:49 +0800
Subject: [PATCH v13 4/7] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <cover.1707040881.git.Sandor.yu@nxp.com>
References: <cover.1707040881.git.Sandor.yu@nxp.com>
Message-ID: <5bd01470cf971e2385ecd169c3d5ac659a020973.1707040881.git.Sandor.yu@nxp.com>

Add a new DRM DisplayPort and HDMI bridge driver for Candence MHDP8501
used in i.MX8MQ SOC. MHDP8501 could support HDMI or DisplayPort
standards according embedded Firmware running in the uCPU.

For iMX8MQ SOC, the DisplayPort/HDMI FW was loaded and activated by
SOC's ROM code. Bootload binary included respective specific firmware
is required.

Driver will check display connector type and
then load the corresponding driver.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
v12->v13:
- Explicitly include linux/platform_device.h for cdns-mhdp8501-core.c
- Fix build warning
- Order bit bpc and color_space in descending shit. 

v11->v12:
- Replace DRM_INFO with dev_info or dev_warn.
- Replace DRM_ERROR with dev_err.
- Return ret when cdns_mhdp_dpcd_read failed in function cdns_dp_aux_transferi().
- Remove unused parmeter in function cdns_dp_get_msa_misc
  and use two separate variables for color space and bpc.
- Add year 2024 to copyright.

 drivers/gpu/drm/bridge/cadence/Kconfig        |  16 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   2 +
 .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 316 ++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 365 +++++++++
 .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 699 ++++++++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 679 +++++++++++++++++
 6 files changed, 2077 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c

diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig
index e0973339e9e33..45848e741f5f4 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -51,3 +51,19 @@ config DRM_CDNS_MHDP8546_J721E
 	  initializes the J721E Display Port and sets up the
 	  clock and data muxes.
 endif
+
+config DRM_CDNS_MHDP8501
+	tristate "Cadence MHDP8501 DP/HDMI bridge"
+	select DRM_KMS_HELPER
+	select DRM_PANEL_BRIDGE
+	select DRM_DISPLAY_DP_HELPER
+	select DRM_DISPLAY_HELPER
+	select CDNS_MHDP_HELPER
+	select DRM_CDNS_AUDIO
+	depends on OF
+	help
+	  Support Cadence MHDP8501 DisplayPort/HDMI bridge.
+	  Cadence MHDP8501 support one or more protocols,
+	  including DisplayPort and HDMI.
+	  To use the DP and HDMI drivers, their respective
+	  specific firmware is required.
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile
index 087dc074820d7..02c1a9f3cf6fc 100644
--- a/drivers/gpu/drm/bridge/cadence/Makefile
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
 cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
+obj-$(CONFIG_DRM_CDNS_MHDP8501) += cdns-mhdp8501.o
+cdns-mhdp8501-y := cdns-mhdp8501-core.o cdns-mhdp8501-dp.o cdns-mhdp8501-hdmi.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
new file mode 100644
index 0000000000000..bc36797b39fdb
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence Display Port Interface (DP) driver
+ *
+ * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/drm_of.h>
+#include <drm/drm_print.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+
+#include "cdns-mhdp8501-core.h"
+
+static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 status;
+	int ret;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_GENERAL,
+				     GENERAL_GET_HPD_STATE, 0, NULL);
+	if (ret)
+		goto err_get_hpd;
+
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_GENERAL,
+					    GENERAL_GET_HPD_STATE,
+					    sizeof(status));
+	if (ret)
+		goto err_get_hpd;
+
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
+	if (ret)
+		goto err_get_hpd;
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	return status;
+
+err_get_hpd:
+	dev_err(mhdp->dev, "read hpd  failed: %d\n", ret);
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	return ret;
+}
+
+enum drm_connector_status cdns_mhdp8501_detect(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 hpd = 0xf;
+
+	hpd = cdns_mhdp8501_read_hpd(mhdp);
+	if (hpd == 1)
+		return connector_status_connected;
+	else if (hpd == 0)
+		return connector_status_disconnected;
+
+	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n", hpd);
+	return connector_status_unknown;
+}
+
+static void hotplug_work_func(struct work_struct *work)
+{
+	struct cdns_mhdp8501_device *mhdp = container_of(work,
+						     struct cdns_mhdp8501_device,
+						     hotplug_work.work);
+	enum drm_connector_status status = cdns_mhdp8501_detect(mhdp);
+
+	drm_bridge_hpd_notify(&mhdp->bridge, status);
+
+	if (status == connector_status_connected) {
+		/* Cable connected  */
+		DRM_INFO("HDMI/DP Cable Plug In\n");
+		enable_irq(mhdp->irq[IRQ_OUT]);
+	} else if (status == connector_status_disconnected) {
+		/* Cable Disconnected  */
+		DRM_INFO("HDMI/DP Cable Plug Out\n");
+		enable_irq(mhdp->irq[IRQ_IN]);
+	}
+}
+
+static irqreturn_t cdns_mhdp8501_irq_thread(int irq, void *data)
+{
+	struct cdns_mhdp8501_device *mhdp = data;
+
+	disable_irq_nosync(irq);
+
+	mod_delayed_work(system_wq, &mhdp->hotplug_work,
+			 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
+
+	return IRQ_HANDLED;
+}
+
+static int cdns_mhdp8501_dt_parse(struct cdns_mhdp8501_device *mhdp,
+				  struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *remote;
+
+	remote = of_graph_get_remote_node(np, 1, 0);
+	if (!remote) {
+		dev_err(dev, "fail to get remote node\n");
+		of_node_put(remote);
+		return -EINVAL;
+	}
+
+	/* get connector type */
+	if (of_device_is_compatible(remote, "hdmi-connector")) {
+		mhdp->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+
+	} else if (of_device_is_compatible(remote, "dp-connector")) {
+		mhdp->connector_type = DRM_MODE_CONNECTOR_DisplayPort;
+
+	} else {
+		dev_err(dev, "Unknown connector type\n");
+		of_node_put(remote);
+		return -EINVAL;
+	}
+
+	of_node_put(remote);
+	return true;
+}
+
+static void cdns_mhdp8501_add_bridge(struct cdns_mhdp8501_device *mhdp)
+{
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+		mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs;
+	} else if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+		mhdp->bridge.funcs = &cdns_dp_bridge_funcs;
+	} else {
+		dev_err(mhdp->dev, "Unsupported connector type!\n");
+		return;
+	}
+
+	mhdp->bridge.type = mhdp->connector_type;
+	mhdp->bridge.driver_private = mhdp;
+	mhdp->bridge.of_node = mhdp->dev->of_node;
+	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
+			   DRM_BRIDGE_OP_HPD;
+	drm_bridge_add(&mhdp->bridge);
+}
+
+static int cdns_mhdp8501_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cdns_mhdp8501_device *mhdp;
+	struct resource *res;
+	u32 reg;
+	int ret;
+
+	mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
+	if (!mhdp)
+		return -ENOMEM;
+
+	mutex_init(&mhdp->mbox_mutex);
+	mhdp->dev = dev;
+
+	INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	mhdp->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(mhdp->regs))
+		return PTR_ERR(mhdp->regs);
+
+	ret = cdns_mhdp8501_dt_parse(mhdp, pdev);
+	if (ret < 0)
+		return -EINVAL;
+
+	mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node, 0);
+	if (IS_ERR(mhdp->phy))
+		return dev_err_probe(dev, PTR_ERR(mhdp->phy), "no PHY configured\n");
+
+	mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
+	if (mhdp->irq[IRQ_IN] < 0)
+		return dev_err_probe(dev, mhdp->irq[IRQ_IN], "No plug_in irq number\n");
+
+	mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
+	if (mhdp->irq[IRQ_OUT] < 0)
+		return dev_err_probe(dev, mhdp->irq[IRQ_OUT], "No plug_out irq number\n");
+
+	irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
+					NULL, cdns_mhdp8501_irq_thread,
+					IRQF_ONESHOT, dev_name(dev), mhdp);
+	if (ret < 0) {
+		dev_err(dev, "can't claim irq %d\n", mhdp->irq[IRQ_IN]);
+		return -EINVAL;
+	}
+
+	irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
+					NULL, cdns_mhdp8501_irq_thread,
+					IRQF_ONESHOT, dev_name(dev), mhdp);
+	if (ret < 0) {
+		dev_err(dev, "can't claim irq %d\n", mhdp->irq[IRQ_OUT]);
+		return -EINVAL;
+	}
+
+	/* set default lane mapping */
+	mhdp->lane_mapping = LANE_MAPPING_NORMAL;
+
+	mhdp->plat_data = of_device_get_match_data(dev);
+	if (mhdp->plat_data) {
+		if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
+			mhdp->lane_mapping = mhdp->plat_data->dp_lane_mapping;
+		else if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA)
+			mhdp->lane_mapping = mhdp->plat_data->hdmi_lane_mapping;
+	}
+
+	dev_set_drvdata(dev, mhdp);
+
+	/* init base struct for access mhdp mailbox */
+	mhdp->base.dev = mhdp->dev;
+	mhdp->base.regs = mhdp->regs;
+	mhdp->base.mbox_mutex = &mhdp->mbox_mutex;
+
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+		drm_dp_aux_init(&mhdp->dp.aux);
+		mhdp->dp.aux.name = "mhdp8501_dp_aux";
+		mhdp->dp.aux.dev = dev;
+		mhdp->dp.aux.transfer = cdns_dp_aux_transfer;
+	}
+
+	/* Enable APB clock */
+	mhdp->apb_clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(mhdp->apb_clk))
+		return dev_err_probe(dev, PTR_ERR(mhdp->apb_clk),
+				     "couldn't get apb clk\n");
+
+	clk_prepare_enable(mhdp->apb_clk);
+
+	/*
+	 * Wait for the KEEP_ALIVE "message" on the first 8 bits.
+	 * Updated each sched "tick" (~2ms)
+	 */
+	ret = readl_poll_timeout(mhdp->regs + KEEP_ALIVE, reg,
+				 reg & CDNS_KEEP_ALIVE_MASK, 500,
+				 CDNS_KEEP_ALIVE_TIMEOUT);
+	if (ret) {
+		dev_err(dev, "device didn't give any life sign: reg %d\n", reg);
+		goto clk_disable;
+	}
+
+	/* Mailbox protect for HDMI PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	ret = phy_init(mhdp->phy);
+	mutex_unlock(&mhdp->mbox_mutex);
+	if (ret) {
+		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
+		goto clk_disable;
+	}
+
+	/* Enable cable hotplug detect */
+	if (cdns_mhdp8501_read_hpd(mhdp))
+		enable_irq(mhdp->irq[IRQ_OUT]);
+	else
+		enable_irq(mhdp->irq[IRQ_IN]);
+
+	cdns_mhdp8501_add_bridge(mhdp);
+
+	return 0;
+
+clk_disable:
+	clk_disable_unprepare(mhdp->apb_clk);
+
+	return -EINVAL;
+}
+
+static int cdns_mhdp8501_remove(struct platform_device *pdev)
+{
+	struct cdns_mhdp8501_device *mhdp = platform_get_drvdata(pdev);
+
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
+		cdns_dp_aux_destroy(mhdp);
+
+	drm_bridge_remove(&mhdp->bridge);
+	clk_disable_unprepare(mhdp->apb_clk);
+
+	return 0;
+}
+
+static struct mhdp8501_plat_data imx8mq_mhdp_drv_data = {
+	.hdmi_lane_mapping = LANE_MAPPING_FLIPPED,
+	.dp_lane_mapping = LANE_MAPPING_IMX8MQ_DP,
+};
+
+static const struct of_device_id cdns_mhdp8501_dt_ids[] = {
+	{ .compatible = "fsl,imx8mq-mhdp8501",
+	  .data = &imx8mq_mhdp_drv_data
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, cdns_mhdp8501_dt_ids);
+
+static struct platform_driver cdns_mhdp8501_driver = {
+	.probe = cdns_mhdp8501_probe,
+	.remove = cdns_mhdp8501_remove,
+	.driver = {
+		.name = "cdns-mhdp8501",
+		.of_match_table = cdns_mhdp8501_dt_ids,
+	},
+};
+
+module_platform_driver(cdns_mhdp8501_driver);
+
+MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("Cadence MHDP8501 bridge driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
new file mode 100644
index 0000000000000..f8a5774bc50ce
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
@@ -0,0 +1,365 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Cadence MHDP 8501 Common head file
+ *
+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
+ *
+ */
+
+#ifndef _CDNS_MHDP8501_CORE_H_
+#define _CDNS_MHDP8501_CORE_H_
+
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_connector.h>
+#include <drm/display/drm_dp_helper.h>
+#include <linux/bitops.h>
+
+#define ADDR_IMEM			0x10000
+#define ADDR_DMEM			0x20000
+
+/* APB CFG addr */
+#define APB_CTRL			0
+#define XT_INT_CTRL			0x04
+#define MAILBOX_FULL_ADDR		0x08
+#define MAILBOX_EMPTY_ADDR		0x0c
+#define MAILBOX0_WR_DATA		0x10
+#define MAILBOX0_RD_DATA		0x14
+#define KEEP_ALIVE			0x18
+#define VER_L				0x1c
+#define VER_H				0x20
+#define VER_LIB_L_ADDR			0x24
+#define VER_LIB_H_ADDR			0x28
+#define SW_DEBUG_L			0x2c
+#define SW_DEBUG_H			0x30
+#define MAILBOX_INT_MASK		0x34
+#define MAILBOX_INT_STATUS		0x38
+#define SW_CLK_L			0x3c
+#define SW_CLK_H			0x40
+#define SW_EVENTS0			0x44
+#define SW_EVENTS1			0x48
+#define SW_EVENTS2			0x4c
+#define SW_EVENTS3			0x50
+#define XT_OCD_CTRL			0x60
+#define APB_INT_MASK			0x6c
+#define APB_STATUS_MASK			0x70
+
+/* Source phy comp */
+#define PHY_DATA_SEL			0x0818
+#define LANES_CONFIG			0x0814
+
+/* Source CAR Addr */
+#define SOURCE_HDTX_CAR			0x0900
+#define SOURCE_DPTX_CAR			0x0904
+#define SOURCE_PHY_CAR			0x0908
+#define SOURCE_CEC_CAR			0x090c
+#define SOURCE_CBUS_CAR			0x0910
+#define SOURCE_PKT_CAR			0x0918
+#define SOURCE_AIF_CAR			0x091c
+#define SOURCE_CIPHER_CAR		0x0920
+#define SOURCE_CRYPTO_CAR		0x0924
+
+/* clock meters addr */
+#define CM_CTRL				0x0a00
+#define CM_I2S_CTRL			0x0a04
+#define CM_SPDIF_CTRL			0x0a08
+#define CM_VID_CTRL			0x0a0c
+#define CM_LANE_CTRL			0x0a10
+#define I2S_NM_STABLE			0x0a14
+#define I2S_NCTS_STABLE			0x0a18
+#define SPDIF_NM_STABLE			0x0a1c
+#define SPDIF_NCTS_STABLE		0x0a20
+#define NMVID_MEAS_STABLE		0x0a24
+#define I2S_MEAS			0x0a40
+#define SPDIF_MEAS			0x0a80
+#define NMVID_MEAS			0x0ac0
+
+/* source vif addr */
+#define BND_HSYNC2VSYNC			0x0b00
+#define HSYNC2VSYNC_F1_L1		0x0b04
+#define HSYNC2VSYNC_STATUS		0x0b0c
+#define HSYNC2VSYNC_POL_CTRL		0x0b10
+
+/* MHDP TX_top_comp */
+#define SCHEDULER_H_SIZE		0x1000
+#define SCHEDULER_V_SIZE		0x1004
+#define HDTX_SIGNAL_FRONT_WIDTH		0x100c
+#define HDTX_SIGNAL_SYNC_WIDTH		0x1010
+#define HDTX_SIGNAL_BACK_WIDTH		0x1014
+#define HDTX_CONTROLLER			0x1018
+#define HDTX_HPD			0x1020
+#define HDTX_CLOCK_REG_0		0x1024
+#define HDTX_CLOCK_REG_1		0x1028
+
+/* DPTX hpd addr */
+#define HPD_IRQ_DET_MIN_TIMER		0x2100
+#define HPD_IRQ_DET_MAX_TIMER		0x2104
+#define HPD_UNPLGED_DET_MIN_TIMER	0x2108
+#define HPD_STABLE_TIMER		0x210c
+#define HPD_FILTER_TIMER		0x2110
+#define HPD_EVENT_MASK			0x211c
+#define HPD_EVENT_DET			0x2120
+
+/* DPTX framer addr */
+#define DP_FRAMER_GLOBAL_CONFIG		0x2200
+#define DP_SW_RESET			0x2204
+#define DP_FRAMER_TU			0x2208
+#define DP_FRAMER_PXL_REPR		0x220c
+#define DP_FRAMER_SP			0x2210
+#define AUDIO_PACK_CONTROL		0x2214
+#define DP_VC_TABLE(x)			(0x2218 + ((x) << 2))
+#define DP_VB_ID			0x2258
+#define DP_MTPH_LVP_CONTROL		0x225c
+#define DP_MTPH_SYMBOL_VALUES		0x2260
+#define DP_MTPH_ECF_CONTROL		0x2264
+#define DP_MTPH_ACT_CONTROL		0x2268
+#define DP_MTPH_STATUS			0x226c
+#define DP_INTERRUPT_SOURCE		0x2270
+#define DP_INTERRUPT_MASK		0x2274
+#define DP_FRONT_BACK_PORCH		0x2278
+#define DP_BYTE_COUNT			0x227c
+
+/* DPTX stream addr */
+#define MSA_HORIZONTAL_0		0x2280
+#define MSA_HORIZONTAL_1		0x2284
+#define MSA_VERTICAL_0			0x2288
+#define MSA_VERTICAL_1			0x228c
+#define MSA_MISC			0x2290
+#define STREAM_CONFIG			0x2294
+#define AUDIO_PACK_STATUS		0x2298
+#define VIF_STATUS			0x229c
+#define PCK_STUFF_STATUS_0		0x22a0
+#define PCK_STUFF_STATUS_1		0x22a4
+#define INFO_PACK_STATUS		0x22a8
+#define RATE_GOVERNOR_STATUS		0x22ac
+#define DP_HORIZONTAL			0x22b0
+#define DP_VERTICAL_0			0x22b4
+#define DP_VERTICAL_1			0x22b8
+#define DP_BLOCK_SDP			0x22bc
+
+/* DPTX glbl addr */
+#define DPTX_LANE_EN			0x2300
+#define DPTX_ENHNCD			0x2304
+#define DPTX_INT_MASK			0x2308
+#define DPTX_INT_STATUS			0x230c
+
+/* DP AUX Addr */
+#define DP_AUX_HOST_CONTROL		0x2800
+#define DP_AUX_INTERRUPT_SOURCE		0x2804
+#define DP_AUX_INTERRUPT_MASK		0x2808
+#define DP_AUX_SWAP_INVERSION_CONTROL	0x280c
+#define DP_AUX_SEND_NACK_TRANSACTION	0x2810
+#define DP_AUX_CLEAR_RX			0x2814
+#define DP_AUX_CLEAR_TX			0x2818
+#define DP_AUX_TIMER_STOP		0x281c
+#define DP_AUX_TIMER_CLEAR		0x2820
+#define DP_AUX_RESET_SW			0x2824
+#define DP_AUX_DIVIDE_2M		0x2828
+#define DP_AUX_TX_PREACHARGE_LENGTH	0x282c
+#define DP_AUX_FREQUENCY_1M_MAX		0x2830
+#define DP_AUX_FREQUENCY_1M_MIN		0x2834
+#define DP_AUX_RX_PRE_MIN		0x2838
+#define DP_AUX_RX_PRE_MAX		0x283c
+#define DP_AUX_TIMER_PRESET		0x2840
+#define DP_AUX_NACK_FORMAT		0x2844
+#define DP_AUX_TX_DATA			0x2848
+#define DP_AUX_RX_DATA			0x284c
+#define DP_AUX_TX_STATUS		0x2850
+#define DP_AUX_RX_STATUS		0x2854
+#define DP_AUX_RX_CYCLE_COUNTER		0x2858
+#define DP_AUX_MAIN_STATES		0x285c
+#define DP_AUX_MAIN_TIMER		0x2860
+#define DP_AUX_AFE_OUT			0x2864
+
+/* source pif addr */
+#define SOURCE_PIF_WR_ADDR		0x30800
+#define SOURCE_PIF_WR_REQ		0x30804
+#define SOURCE_PIF_RD_ADDR		0x30808
+#define SOURCE_PIF_RD_REQ		0x3080c
+#define SOURCE_PIF_DATA_WR		0x30810
+#define SOURCE_PIF_DATA_RD		0x30814
+#define SOURCE_PIF_FIFO1_FLUSH		0x30818
+#define SOURCE_PIF_FIFO2_FLUSH		0x3081c
+#define SOURCE_PIF_STATUS		0x30820
+#define SOURCE_PIF_INTERRUPT_SOURCE	0x30824
+#define SOURCE_PIF_INTERRUPT_MASK	0x30828
+#define SOURCE_PIF_PKT_ALLOC_REG	0x3082c
+#define SOURCE_PIF_PKT_ALLOC_WR_EN	0x30830
+#define SOURCE_PIF_SW_RESET		0x30834
+
+#define LINK_TRAINING_NOT_ACTIV		0
+#define LINK_TRAINING_RUN		1
+#define LINK_TRAINING_RESTART		2
+
+#define CONTROL_VIDEO_IDLE		0
+#define CONTROL_VIDEO_VALID		1
+
+#define INTERLACE_FMT_DET		BIT(12)
+#define VIF_BYPASS_INTERLACE		BIT(13)
+#define TU_CNT_RST_EN			BIT(15)
+#define INTERLACE_DTCT_WIN		0x20
+
+#define DP_FRAMER_SP_INTERLACE_EN	BIT(2)
+#define DP_FRAMER_SP_HSP		BIT(1)
+#define DP_FRAMER_SP_VSP		BIT(0)
+
+/* Capability */
+#define AUX_HOST_INVERT			3
+#define FAST_LT_SUPPORT			1
+#define FAST_LT_NOT_SUPPORT		0
+#define LANE_MAPPING_NORMAL		0x1b
+#define LANE_MAPPING_FLIPPED		0xe4
+#define LANE_MAPPING_IMX8MQ_DP		0xc6
+#define ENHANCED			1
+#define SCRAMBLER_EN			BIT(4)
+
+#define FULL_LT_STARTED			BIT(0)
+#define FASE_LT_STARTED			BIT(1)
+#define CLK_RECOVERY_FINISHED		BIT(2)
+#define EQ_PHASE_FINISHED		BIT(3)
+#define FASE_LT_START_FINISHED		BIT(4)
+#define CLK_RECOVERY_FAILED		BIT(5)
+#define EQ_PHASE_FAILED			BIT(6)
+#define FASE_LT_FAILED			BIT(7)
+
+#define TU_SIZE				30
+#define CDNS_DP_MAX_LINK_RATE		540000
+
+#define F_HDMI_ENCODING(x) (((x) & ((1 << 2) - 1)) << 16)
+#define F_VIF_DATA_WIDTH(x) (((x) & ((1 << 2) - 1)) << 2)
+#define F_HDMI_MODE(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_GCP_EN(x) (((x) & ((1 << 1) - 1)) << 12)
+#define F_DATA_EN(x) (((x) & ((1 << 1) - 1)) << 15)
+#define F_HDMI2_PREAMBLE_EN(x) (((x) & ((1 << 1) - 1)) << 18)
+#define F_PIC_3D(x) (((x) & ((1 << 4) - 1)) << 7)
+#define F_BCH_EN(x) (((x) & ((1 << 1) - 1)) << 11)
+#define F_SOURCE_PHY_MHDP_SEL(x) (((x) & ((1 << 2) - 1)) << 3)
+#define F_HPD_VALID_WIDTH(x) (((x) & ((1 << 12) - 1)) << 0)
+#define F_HPD_GLITCH_WIDTH(x) (((x) & ((1 << 8) - 1)) << 12)
+#define F_HDMI2_CTRL_IL_MODE(x) (((x) & ((1 << 1) - 1)) << 19)
+#define F_SOURCE_PHY_LANE0_SWAP(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_SOURCE_PHY_LANE1_SWAP(x) (((x) & ((1 << 2) - 1)) << 2)
+#define F_SOURCE_PHY_LANE2_SWAP(x) (((x) & ((1 << 2) - 1)) << 4)
+#define F_SOURCE_PHY_LANE3_SWAP(x) (((x) & ((1 << 2) - 1)) << 6)
+#define F_SOURCE_PHY_COMB_BYPASS(x) (((x) & ((1 << 1) - 1)) << 21)
+#define F_SOURCE_PHY_20_10(x) (((x) & ((1 << 1) - 1)) << 22)
+#define F_PKT_ALLOC_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_ACTIVE_IDLE_TYPE(x) (((x) & ((1 << 1) - 1)) << 17)
+#define F_FIFO1_FLUSH(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_PKT_ALLOC_WR_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_DATA_WR(x) (x)
+#define F_WR_ADDR(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_HOST_WR(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_TYPE_VALID(x) (((x) & ((1 << 1) - 1)) << 16)
+#define F_PACKET_TYPE(x) (((x) & ((1 << 8) - 1)) << 8)
+
+/* Reference cycles when using lane clock as reference */
+#define LANE_REF_CYC			0x8000
+
+/* HPD Debounce */
+#define HOTPLUG_DEBOUNCE_MS		200
+
+/* HPD IRQ Index */
+#define IRQ_IN    0
+#define IRQ_OUT   1
+#define IRQ_NUM   2
+
+/* FW check alive timeout */
+#define CDNS_KEEP_ALIVE_TIMEOUT		2000
+#define CDNS_KEEP_ALIVE_MASK		GENMASK(7, 0)
+
+enum voltage_swing_level {
+	VOLTAGE_LEVEL_0,
+	VOLTAGE_LEVEL_1,
+	VOLTAGE_LEVEL_2,
+	VOLTAGE_LEVEL_3,
+};
+
+enum pre_emphasis_level {
+	PRE_EMPHASIS_LEVEL_0,
+	PRE_EMPHASIS_LEVEL_1,
+	PRE_EMPHASIS_LEVEL_2,
+	PRE_EMPHASIS_LEVEL_3,
+};
+
+enum pattern_set {
+	PTS1 = BIT(0),
+	PTS2 = BIT(1),
+	PTS3 = BIT(2),
+	PTS4 = BIT(3),
+	DP_NONE	= BIT(4)
+};
+
+enum vic_color_depth {
+	BCS_6 = 0x1,
+	BCS_8 = 0x2,
+	BCS_10 = 0x4,
+	BCS_12 = 0x8,
+	BCS_16 = 0x10,
+};
+
+enum vic_bt_type {
+	BT_601 = 0x0,
+	BT_709 = 0x1,
+};
+
+enum {
+	MODE_DVI,
+	MODE_HDMI_1_4,
+	MODE_HDMI_2_0,
+};
+
+struct video_info {
+	int bpc;
+	int color_fmt;
+};
+
+struct mhdp8501_plat_data {
+	int hdmi_lane_mapping;
+	int dp_lane_mapping;
+};
+
+struct cdns_mhdp8501_device {
+	struct cdns_mhdp_base base;
+
+	struct device *dev;
+	void __iomem *regs;
+	struct drm_connector *curr_conn;
+	struct drm_bridge bridge;
+	struct clk *apb_clk;
+	struct phy *phy;
+
+	struct video_info video_info;
+	struct drm_display_mode mode;
+
+	int irq[IRQ_NUM];
+	struct delayed_work hotplug_work;
+	int connector_type;
+	u32 lane_mapping;
+
+	/* protect mailbox communications with the firmware */
+	struct mutex mbox_mutex;
+
+	const struct mhdp8501_plat_data *plat_data;
+
+	union {
+		struct _dp_data {
+			u32 rate;
+			u8 num_lanes;
+			struct drm_dp_aux aux;
+			u8 dpcd[DP_RECEIVER_CAP_SIZE];
+		} dp;
+		struct _hdmi_data {
+			u32 hdmi_type;
+		} hdmi;
+	};
+};
+
+extern const struct drm_bridge_funcs cdns_dp_bridge_funcs;
+extern const struct drm_bridge_funcs cdns_hdmi_bridge_funcs;
+
+ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg);
+enum drm_connector_status cdns_mhdp8501_detect(struct cdns_mhdp8501_device *mhdp);
+int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp);
+
+#endif
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
new file mode 100644
index 0000000000000..0117cddb85694
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
@@ -0,0 +1,699 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence MHDP8501 DisplayPort(DP) bridge driver
+ *
+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-dp.h>
+
+#include "cdns-mhdp8501-core.h"
+
+#define LINK_TRAINING_TIMEOUT_MS	500
+#define LINK_TRAINING_RETRY_MS		20
+
+ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux,
+			     struct drm_dp_aux_msg *msg)
+{
+	struct cdns_mhdp8501_device *mhdp = dev_get_drvdata(aux->dev);
+	bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
+	int ret;
+
+	/* Ignore address only message */
+	if (!msg->size || !msg->buffer) {
+		msg->reply = native ?
+			DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
+		return msg->size;
+	}
+
+	if (!native) {
+		dev_err(mhdp->dev, "%s: only native messages supported\n", __func__);
+		return -EINVAL;
+	}
+
+	/* msg sanity check */
+	if (msg->size > DP_AUX_MAX_PAYLOAD_BYTES) {
+		dev_err(mhdp->dev, "%s: invalid msg: size(%zu), request(%x)\n",
+			__func__, msg->size, (unsigned int)msg->request);
+		return -EINVAL;
+	}
+
+	if (msg->request == DP_AUX_NATIVE_WRITE) {
+		const u8 *buf = msg->buffer;
+		int i;
+
+		for (i = 0; i < msg->size; ++i) {
+			ret = cdns_mhdp_dpcd_write(&mhdp->base,
+						   msg->address + i, buf[i]);
+			if (ret < 0) {
+				dev_err(mhdp->dev, "Failed to write DPCD\n");
+				return ret;
+			}
+		}
+		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+		return msg->size;
+	}
+
+	if (msg->request == DP_AUX_NATIVE_READ) {
+		ret = cdns_mhdp_dpcd_read(&mhdp->base, msg->address,
+					  msg->buffer, msg->size);
+		if (ret < 0)
+			return ret;
+		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+		return msg->size;
+	}
+	return 0;
+}
+
+int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp)
+{
+	drm_dp_aux_unregister(&mhdp->dp.aux);
+
+	return 0;
+}
+
+static int cdns_dp_get_msa_misc(struct video_info *video)
+{
+	u32 msa_misc;
+	u8 color_space = 0;
+	u8 bpc = 0;
+
+	switch (video->color_fmt) {
+	/* set YUV default color space conversion to BT601 */
+	case DRM_COLOR_FORMAT_YCBCR444:
+		color_space = 6 + BT_601 * 8;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		color_space = 5 + BT_601 * 8;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		color_space = 5;
+		break;
+	case DRM_COLOR_FORMAT_RGB444:
+	default:
+		color_space = 0;
+		break;
+	};
+
+	switch (video->bpc) {
+	case 6:
+		bpc = 0;
+		break;
+	case 10:
+		bpc = 2;
+		break;
+	case 12:
+		bpc = 3;
+		break;
+	case 16:
+		bpc = 4;
+		break;
+	case 8:
+	default:
+		bpc = 1;
+		break;
+	};
+
+	msa_misc = (bpc << 5) | (color_space << 1);
+
+	return msa_misc;
+}
+
+static int cdns_dp_config_video(struct cdns_mhdp8501_device *mhdp)
+{
+	struct video_info *video = &mhdp->video_info;
+	struct drm_display_mode *mode = &mhdp->mode;
+	bool h_sync_polarity, v_sync_polarity;
+	u64 symbol;
+	u32 val, link_rate, rem;
+	u8 bit_per_pix, tu_size_reg = TU_SIZE;
+	int ret;
+
+	bit_per_pix = (video->color_fmt == DRM_COLOR_FORMAT_YCBCR422) ?
+		      (video->bpc * 2) : (video->bpc * 3);
+
+	link_rate = mhdp->dp.rate / 1000;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE);
+	if (ret)
+		goto err_config_video;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HSYNC2VSYNC_POL_CTRL, 0);
+	if (ret)
+		goto err_config_video;
+
+	/*
+	 * get a best tu_size and valid symbol:
+	 * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32
+	 * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes)
+	 * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set
+	 *    TU += 2 and repeat 2nd step.
+	 */
+	do {
+		tu_size_reg += 2;
+		symbol = tu_size_reg * mode->clock * bit_per_pix;
+		do_div(symbol, mhdp->dp.num_lanes * link_rate * 8);
+		rem = do_div(symbol, 1000);
+		if (tu_size_reg > 64) {
+			ret = -EINVAL;
+			dev_err(mhdp->dev, "tu error, clk:%d, lanes:%d, rate:%d\n",
+				mode->clock, mhdp->dp.num_lanes, link_rate);
+			goto err_config_video;
+		}
+	} while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
+		 (rem > 850) || (rem < 100));
+
+	val = symbol + (tu_size_reg << 8);
+	val |= TU_CNT_RST_EN;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_TU, val);
+	if (ret)
+		goto err_config_video;
+
+	/* set the FIFO Buffer size */
+	val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
+	val /= (mhdp->dp.num_lanes * link_rate);
+	val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
+	val += 2;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_VC_TABLE(15), val);
+
+	switch (video->bpc) {
+	case 6:
+		val = BCS_6;
+		break;
+	case 10:
+		val = BCS_10;
+		break;
+	case 12:
+		val = BCS_12;
+		break;
+	case 16:
+		val = BCS_16;
+		break;
+	case 8:
+	default:
+		val = BCS_8;
+		break;
+	};
+
+	val += video->color_fmt << 8;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_PXL_REPR, val);
+	if (ret)
+		goto err_config_video;
+
+	v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+	h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+
+	val = h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
+	val |= v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_SP, val);
+	if (ret)
+		goto err_config_video;
+
+	val = (mode->hsync_start - mode->hdisplay) << 16;
+	val |= mode->htotal - mode->hsync_end;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRONT_BACK_PORCH, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->hdisplay * bit_per_pix / 8;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_BYTE_COUNT, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_HORIZONTAL_0, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->hsync_end - mode->hsync_start;
+	val |= (mode->hdisplay << 16) | (h_sync_polarity << 15);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_HORIZONTAL_1, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vtotal;
+	val |= (mode->vtotal - mode->vsync_start) << 16;
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_VERTICAL_0, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vsync_end - mode->vsync_start;
+	val |= (mode->vdisplay << 16) | (v_sync_polarity << 15);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_VERTICAL_1, val);
+	if (ret)
+		goto err_config_video;
+
+	val = cdns_dp_get_msa_misc(video);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_MISC, val);
+	if (ret)
+		goto err_config_video;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, STREAM_CONFIG, 1);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->hsync_end - mode->hsync_start;
+	val |= mode->hdisplay << 16;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_HORIZONTAL, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vdisplay;
+	val |= (mode->vtotal - mode->vsync_start) << 16;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_VERTICAL_0, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vtotal;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_VERTICAL_1, val);
+	if (ret)
+		goto err_config_video;
+
+	ret = cdns_mhdp_dp_reg_write_bit(&mhdp->base, DP_VB_ID, 2, 1, 0);
+
+err_config_video:
+	if (ret)
+		dev_err(mhdp->dev, "config video failed: %d\n", ret);
+	return ret;
+}
+
+static void cdns_dp_pixel_clk_reset(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 val;
+
+	/* reset pixel clk */
+	cdns_mhdp_reg_read(&mhdp->base, SOURCE_HDTX_CAR, &val);
+	cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, val & 0xFD);
+	cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, val);
+}
+
+static int cdns_dp_set_video_status(struct cdns_mhdp8501_device *mhdp, int active)
+{
+	u8 msg;
+	int ret;
+
+	msg = !!active;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
+				     sizeof(msg), &msg);
+	if (ret)
+		dev_err(mhdp->dev, "set video status failed: %d\n", ret);
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	return ret;
+}
+
+static int cdns_dp_training_start(struct cdns_mhdp8501_device *mhdp)
+{
+	unsigned long timeout;
+	u8 msg, event[2];
+	int ret;
+
+	msg = LINK_TRAINING_RUN;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	/* start training */
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_TRAINING_CONTROL, sizeof(msg), &msg);
+	if (ret)
+		goto err_training_start;
+
+	timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
+	while (time_before(jiffies, timeout)) {
+		msleep(LINK_TRAINING_RETRY_MS);
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+					     DPTX_READ_EVENT, 0, NULL);
+		if (ret)
+			goto err_training_start;
+
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
+						    DPTX_READ_EVENT, sizeof(event));
+		if (ret)
+			goto err_training_start;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, event, sizeof(event));
+		if (ret)
+			goto err_training_start;
+
+		if (event[1] & CLK_RECOVERY_FAILED) {
+			dev_err(mhdp->dev, "clock recovery failed\n");
+		} else if (event[1] & EQ_PHASE_FINISHED) {
+			mutex_unlock(&mhdp->mbox_mutex);
+			return 0;
+		}
+	}
+
+	ret = -ETIMEDOUT;
+
+err_training_start:
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	dev_err(mhdp->dev, "training failed: %d\n", ret);
+	return ret;
+}
+
+static int cdns_dp_get_training_status(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 status[13];
+	int ret;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_READ_LINK_STAT, 0, NULL);
+	if (ret)
+		goto err_get_training_status;
+
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
+					    DPTX_READ_LINK_STAT,
+					    sizeof(status));
+	if (ret)
+		goto err_get_training_status;
+
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, status, sizeof(status));
+	if (ret)
+		goto err_get_training_status;
+
+	mhdp->dp.rate = drm_dp_bw_code_to_link_rate(status[0]);
+	mhdp->dp.num_lanes = status[1];
+
+err_get_training_status:
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "get training status failed: %d\n", ret);
+	return ret;
+}
+
+static int cdns_dp_train_link(struct cdns_mhdp8501_device *mhdp)
+{
+	int ret;
+
+	ret = cdns_dp_training_start(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to start training %d\n", ret);
+		return ret;
+	}
+
+	ret = cdns_dp_get_training_status(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to get training stat %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(mhdp->dev, "rate:0x%x, lanes:%d\n", mhdp->dp.rate,
+		mhdp->dp.num_lanes);
+	return ret;
+}
+
+static int cdns_dp_set_host_cap(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 msg[8];
+	int ret;
+
+	msg[0] = drm_dp_link_rate_to_bw_code(mhdp->dp.rate);
+	msg[1] = mhdp->dp.num_lanes | SCRAMBLER_EN;
+	msg[2] = VOLTAGE_LEVEL_2;
+	msg[3] = PRE_EMPHASIS_LEVEL_3;
+	msg[4] = PTS1 | PTS2 | PTS3 | PTS4;
+	msg[5] = FAST_LT_NOT_SUPPORT;
+	msg[6] = mhdp->lane_mapping;
+	msg[7] = ENHANCED;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_SET_HOST_CAPABILITIES,
+				     sizeof(msg), msg);
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "set host cap failed: %d\n", ret);
+
+	return ret;
+}
+
+static int cdns_dp_get_edid_block(void *data, u8 *edid,
+				  unsigned int block, size_t length)
+{
+	struct cdns_mhdp8501_device *mhdp = data;
+	u8 msg[2], reg[2], i;
+	int ret;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	for (i = 0; i < 4; i++) {
+		msg[0] = block / 2;
+		msg[1] = block % 2;
+
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+					     DPTX_GET_EDID, sizeof(msg), msg);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
+						    DPTX_GET_EDID,
+						    sizeof(reg) + length);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid, length);
+		if (ret)
+			continue;
+
+		if (reg[0] == length && reg[1] == block / 2)
+			break;
+	}
+
+	if (ret)
+		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", block, ret);
+
+	mutex_unlock(&mhdp->mbox_mutex);
+	return ret;
+}
+
+static void cdns_dp_mode_set(struct cdns_mhdp8501_device *mhdp)
+{
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	cdns_dp_pixel_clk_reset(mhdp);
+
+	/* Get DP Caps  */
+	ret = drm_dp_dpcd_read(&mhdp->dp.aux, DP_DPCD_REV, mhdp->dp.dpcd,
+			       DP_RECEIVER_CAP_SIZE);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "Failed to get caps %d\n", ret);
+		return;
+	}
+
+	mhdp->dp.rate = drm_dp_max_link_rate(mhdp->dp.dpcd);
+	mhdp->dp.num_lanes = drm_dp_max_lane_count(mhdp->dp.dpcd);
+
+	/* check the max link rate */
+	if (mhdp->dp.rate > CDNS_DP_MAX_LINK_RATE)
+		mhdp->dp.rate = CDNS_DP_MAX_LINK_RATE;
+
+	phy_cfg.dp.lanes = mhdp->dp.num_lanes;
+	phy_cfg.dp.link_rate = mhdp->dp.rate;
+	phy_cfg.dp.set_lanes = false;
+	phy_cfg.dp.set_rate = false;
+	phy_cfg.dp.set_voltages = true;
+
+	/* Mailbox protect for DP PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	ret = phy_configure(mhdp->phy, &phy_cfg);
+	mutex_unlock(&mhdp->mbox_mutex);
+	if (ret) {
+		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+			__func__, ret);
+		return;
+	}
+
+	/* Video off */
+	ret = cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_IDLE);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to valid video %d\n", ret);
+		return;
+	}
+
+	/* Line swapping */
+	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
+
+	/* Set DP host capability */
+	ret = cdns_dp_set_host_cap(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to set host cap %d\n", ret);
+		return;
+	}
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_AUX_SWAP_INVERSION_CONTROL,
+				  AUX_HOST_INVERT);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to set host invert %d\n", ret);
+		return;
+	}
+
+	ret = cdns_dp_config_video(mhdp);
+	if (ret)
+		dev_err(mhdp->dev, "Failed to config video %d\n", ret);
+}
+
+static int cdns_dp_bridge_attach(struct drm_bridge *bridge,
+				 enum drm_bridge_attach_flags flags)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mhdp->dev, "do not support creating a drm_connector\n");
+		return -EINVAL;
+	}
+
+	mhdp->dp.aux.drm_dev = bridge->dev;
+
+	return drm_dp_aux_register(&mhdp->dp.aux);
+}
+
+static enum drm_mode_status
+cdns_dp_bridge_mode_valid(struct drm_bridge *bridge,
+			  const struct drm_display_info *info,
+			  const struct drm_display_mode *mode)
+{
+	enum drm_mode_status mode_status = MODE_OK;
+
+	/* We don't support double-clocked modes */
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
+	    mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_BAD;
+
+	/* MAX support pixel clock rate 594MHz */
+	if (mode->clock > 594000)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->hdisplay > 3840)
+		return MODE_BAD_HVALUE;
+
+	if (mode->vdisplay > 2160)
+		return MODE_BAD_VVALUE;
+
+	return mode_status;
+}
+
+static enum drm_connector_status
+cdns_dp_bridge_detect(struct drm_bridge *bridge)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return cdns_mhdp8501_detect(mhdp);
+}
+
+static struct edid *cdns_dp_bridge_get_edid(struct drm_bridge *bridge,
+					    struct drm_connector *connector)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return drm_do_get_edid(connector, cdns_dp_get_edid_block, mhdp);
+}
+
+static void cdns_dp_bridge_atomic_disable(struct drm_bridge *bridge,
+					  struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_IDLE);
+	mhdp->curr_conn = NULL;
+
+	/* Mailbox protect for DP PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	phy_power_off(mhdp->phy);
+	mutex_unlock(&mhdp->mbox_mutex);
+}
+
+static void cdns_dp_bridge_atomic_enable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	struct drm_atomic_state *state = old_state->base.state;
+	struct drm_connector *connector;
+	struct video_info *video = &mhdp->video_info;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector_state *conn_state;
+	const struct drm_display_mode *mode;
+	int ret;
+
+	connector = drm_atomic_get_new_connector_for_encoder(state,
+							     bridge->encoder);
+	if (WARN_ON(!connector))
+		return;
+
+	mhdp->curr_conn = connector;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (WARN_ON(!conn_state))
+		return;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return;
+
+	mode = &crtc_state->adjusted_mode;
+
+	switch (connector->display_info.bpc) {
+	case 10:
+		video->bpc = 10;
+		break;
+	case 6:
+		video->bpc = 6;
+		break;
+	default:
+		video->bpc = 8;
+		break;
+	}
+
+	/* The only currently supported format */
+	video->color_fmt = DRM_COLOR_FORMAT_RGB444;
+
+	dev_dbg(mhdp->dev, "Mode: %dx%dp%d\n",
+		mode->hdisplay, mode->vdisplay, mode->clock);
+	memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
+
+	cdns_dp_mode_set(mhdp);
+
+	/* Link trainning */
+	ret = cdns_dp_train_link(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed link train %d\n", ret);
+		return;
+	}
+
+	ret = cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_VALID);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to valid video %d\n", ret);
+		return;
+	}
+}
+
+const struct drm_bridge_funcs cdns_dp_bridge_funcs = {
+	.attach = cdns_dp_bridge_attach,
+	.detect = cdns_dp_bridge_detect,
+	.get_edid = cdns_dp_bridge_get_edid,
+	.mode_valid = cdns_dp_bridge_mode_valid,
+	.atomic_enable = cdns_dp_bridge_atomic_enable,
+	.atomic_disable = cdns_dp_bridge_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,
+};
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
new file mode 100644
index 0000000000000..e6ed13b9f9ca3
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
@@ -0,0 +1,679 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence MHDP8501 HDMI bridge driver
+ *
+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_scdc_helper.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-hdmi.h>
+
+#include "cdns-mhdp8501-core.h"
+
+/**
+ * cdns_hdmi_infoframe_set() - fill the HDMI AVI infoframe
+ * @mhdp: phandle to mhdp device.
+ * @entry_id: The packet memory address in which the data is written.
+ * @packet_len: 32, only 32 bytes now.
+ * @packet: point to InfoFrame Packet.
+ *          packet[0] = 0
+ *          packet[1-3] = HB[0-2]  InfoFrame Packet Header
+ *          packet[4-31 = PB[0-27] InfoFrame Packet Contents
+ * @packet_type: Packet Type of InfoFrame in HDMI Specification.
+ *
+ */
+static void cdns_hdmi_infoframe_set(struct cdns_mhdp8501_device *mhdp,
+				    u8 entry_id, u8 packet_len,
+				    u8 *packet, u8 packet_type)
+{
+	u32 packet32, len32;
+	u32 val, i;
+
+	/* only support 32 bytes now */
+	if (packet_len != 32)
+		return;
+
+	/* invalidate entry */
+	val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id);
+	writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+	writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + SOURCE_PIF_PKT_ALLOC_WR_EN);
+
+	/* flush fifo 1 */
+	writel(F_FIFO1_FLUSH(1), mhdp->regs + SOURCE_PIF_FIFO1_FLUSH);
+
+	/* write packet into memory */
+	len32 = packet_len / 4;
+	for (i = 0; i < len32; i++) {
+		packet32 = get_unaligned_le32(packet + 4 * i);
+		writel(F_DATA_WR(packet32), mhdp->regs + SOURCE_PIF_DATA_WR);
+	}
+
+	/* write entry id */
+	writel(F_WR_ADDR(entry_id), mhdp->regs + SOURCE_PIF_WR_ADDR);
+
+	/* write request */
+	writel(F_HOST_WR(1), mhdp->regs + SOURCE_PIF_WR_REQ);
+
+	/* update entry */
+	val = F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) |
+		F_PACKET_TYPE(packet_type) | F_PKT_ALLOC_ADDRESS(entry_id);
+	writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+
+	writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + SOURCE_PIF_PKT_ALLOC_WR_EN);
+}
+
+static int cdns_hdmi_get_edid_block(void *data, u8 *edid,
+				    u32 block, size_t length)
+{
+	struct cdns_mhdp8501_device *mhdp = data;
+	u8 msg[2], reg[5], i;
+	int ret;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	for (i = 0; i < 4; i++) {
+		msg[0] = block / 2;
+		msg[1] = block % 2;
+
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_HDMI_TX, HDMI_TX_EDID,
+					     sizeof(msg), msg);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_HDMI_TX,
+						    HDMI_TX_EDID, sizeof(reg) + length);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid, length);
+		if (ret)
+			continue;
+
+		if ((reg[3] << 8 | reg[4]) == length)
+			break;
+	}
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", block, ret);
+	return ret;
+}
+
+static int cdns_hdmi_scdc_write(struct cdns_mhdp8501_device *mhdp, u8 addr, u8 value)
+{
+	u8 msg[5], reg[5];
+	int ret;
+
+	msg[0] = 0x54;
+	msg[1] = addr;
+	msg[2] = 0;
+	msg[3] = 1;
+	msg[4] = value;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
+				     sizeof(msg), msg);
+	if (ret)
+		goto err_scdc_write;
+
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_HDMI_TX,
+					    HDMI_TX_WRITE, sizeof(reg));
+	if (ret)
+		goto err_scdc_write;
+
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
+	if (ret)
+		goto err_scdc_write;
+
+	if (reg[0] != 0)
+		ret = -EINVAL;
+
+err_scdc_write:
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "scdc write failed: %d\n", ret);
+	return ret;
+}
+
+static int cdns_hdmi_ctrl_init(struct cdns_mhdp8501_device *mhdp, int protocol)
+{
+	u32 reg0, reg1, val;
+	int ret;
+
+	/* Set PHY to HDMI data */
+	ret = cdns_mhdp_reg_write(&mhdp->base, PHY_DATA_SEL, F_SOURCE_PHY_MHDP_SEL(1));
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_HPD,
+				  F_HPD_VALID_WIDTH(4) | F_HPD_GLITCH_WIDTH(0));
+	if (ret < 0)
+		return ret;
+
+	/* open CARS */
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_PHY_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, 0xFF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_PKT_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_AIF_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CIPHER_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CRYPTO_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CEC_CAR, 3);
+	if (ret < 0)
+		return ret;
+
+	reg0 = 0x7c1f;
+	reg1 = 0x7c1f;
+	if (protocol == MODE_HDMI_2_0) {
+		reg0 = 0;
+		reg1 = 0xFFFFF;
+	}
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0, reg0);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1, reg1);
+	if (ret < 0)
+		return ret;
+
+	/* set HDMI mode and preemble mode data enable */
+	val = F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) |  F_DATA_EN(1) |
+			F_HDMI2_CTRL_IL_MODE(1) | F_BCH_EN(1) | F_PIC_3D(0XF);
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+
+	return ret;
+}
+
+static int cdns_hdmi_mode_config(struct cdns_mhdp8501_device *mhdp,
+				 struct drm_display_mode *mode,
+				 struct video_info *video_info)
+{
+	int ret;
+	u32 val;
+	u32 vsync_lines = mode->vsync_end - mode->vsync_start;
+	u32 eof_lines = mode->vsync_start - mode->vdisplay;
+	u32 sof_lines = mode->vtotal - mode->vsync_end;
+	u32 hblank = mode->htotal - mode->hdisplay;
+	u32 hactive = mode->hdisplay;
+	u32 vblank = mode->vtotal - mode->vdisplay;
+	u32 vactive = mode->vdisplay;
+	u32 hfront = mode->hsync_start - mode->hdisplay;
+	u32 hback = mode->htotal - mode->hsync_end;
+	u32 vfront = eof_lines;
+	u32 hsync = hblank - hfront - hback;
+	u32 vsync = vsync_lines;
+	u32 vback = sof_lines;
+	u32 v_h_polarity = ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1) +
+			((mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : 2);
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, SCHEDULER_H_SIZE, (hactive << 16) + hblank);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, SCHEDULER_V_SIZE, (vactive << 16) + vblank);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_FRONT_WIDTH, (vfront << 16) + hfront);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_SYNC_WIDTH, (vsync << 16) + hsync);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_BACK_WIDTH, (vback << 16) + hback);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HSYNC2VSYNC_POL_CTRL, v_h_polarity);
+	if (ret < 0)
+		return ret;
+
+	/* Reset Data Enable */
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+	val &= ~F_DATA_EN(1);
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+	if (ret < 0)
+		return ret;
+
+	/* Set bpc */
+	val &= ~F_VIF_DATA_WIDTH(3);
+	switch (video_info->bpc) {
+	case 10:
+		val |= F_VIF_DATA_WIDTH(1);
+		break;
+	case 12:
+		val |= F_VIF_DATA_WIDTH(2);
+		break;
+	case 16:
+		val |= F_VIF_DATA_WIDTH(3);
+		break;
+	case 8:
+	default:
+		val |= F_VIF_DATA_WIDTH(0);
+		break;
+	}
+
+	/* select color encoding */
+	val &= ~F_HDMI_ENCODING(3);
+	switch (video_info->color_fmt) {
+	case DRM_COLOR_FORMAT_YCBCR444:
+		val |= F_HDMI_ENCODING(2);
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		val |= F_HDMI_ENCODING(1);
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		val |= F_HDMI_ENCODING(3);
+		break;
+	case DRM_COLOR_FORMAT_RGB444:
+	default:
+		val |= F_HDMI_ENCODING(0);
+		break;
+	}
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+	if (ret < 0)
+		return ret;
+
+	/* set data enable */
+	val |= F_DATA_EN(1);
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+
+	return ret;
+}
+
+static int cdns_hdmi_disable_gcp(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 val;
+
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+	val &= ~F_GCP_EN(1);
+
+	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+}
+
+static int cdns_hdmi_enable_gcp(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 val;
+
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+	val |= F_GCP_EN(1);
+
+	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+}
+
+static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_scdc *scdc = &mhdp->curr_conn->display_info.hdmi.scdc;
+	u32 char_rate = mhdp->mode.clock * mhdp->video_info.bpc / 8;
+	u8 buff = 0;
+
+	/* Default work in HDMI1.4 */
+	mhdp->hdmi.hdmi_type = MODE_HDMI_1_4;
+
+	/* check sink support SCDC or not */
+	if (!scdc->supported) {
+		dev_info(mhdp->dev, "Sink Not Support SCDC\n");
+		return;
+	}
+
+	if (char_rate > 340000) {
+		/*
+		 * TMDS Character Rate above 340MHz should working in HDMI2.0
+		 * Enable scrambling and TMDS_Bit_Clock_Ratio
+		 */
+		buff = SCDC_TMDS_BIT_CLOCK_RATIO_BY_40 | SCDC_SCRAMBLING_ENABLE;
+		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+	} else if (scdc->scrambling.low_rates) {
+		/*
+		 * Enable scrambling and HDMI2.0 when scrambling capability of sink
+		 * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit
+		 */
+		buff = SCDC_SCRAMBLING_ENABLE;
+		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+	}
+
+	/* TMDS config */
+	cdns_hdmi_scdc_write(mhdp, SCDC_TMDS_CONFIG, buff);
+}
+
+static void cdns_hdmi_lanes_config(struct cdns_mhdp8501_device *mhdp)
+{
+	/* Line swapping */
+	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
+}
+
+static int cdns_hdmi_colorspace(int color_fmt)
+{
+	int color_space;
+
+	switch (color_fmt) {
+	case DRM_COLOR_FORMAT_YCBCR444:
+		color_space = HDMI_COLORSPACE_YUV444;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		color_space = HDMI_COLORSPACE_YUV422;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		color_space = HDMI_COLORSPACE_YUV420;
+		break;
+	case DRM_COLOR_FORMAT_RGB444:
+	default:
+		color_space = HDMI_COLORSPACE_RGB;
+		break;
+	}
+
+	return color_space;
+}
+
+static int cdns_hdmi_avi_info_set(struct cdns_mhdp8501_device *mhdp,
+				  struct drm_display_mode *mode)
+{
+	struct hdmi_avi_infoframe frame;
+	struct drm_connector_state *conn_state = mhdp->curr_conn->state;
+	struct drm_display_mode *adj_mode;
+	enum hdmi_quantization_range qr;
+	u8 buf[32];
+	int ret;
+
+	/* Initialise info frame from DRM mode */
+	drm_hdmi_avi_infoframe_from_display_mode(&frame, mhdp->curr_conn, mode);
+
+	frame.colorspace = cdns_hdmi_colorspace(mhdp->video_info.color_fmt);
+
+	drm_hdmi_avi_infoframe_colorimetry(&frame, conn_state);
+
+	adj_mode = &mhdp->bridge.encoder->crtc->state->adjusted_mode;
+
+	qr = drm_default_rgb_quant_range(adj_mode);
+
+	drm_hdmi_avi_infoframe_quant_range(&frame, mhdp->curr_conn,
+					   adj_mode, qr);
+
+	ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "failed to pack AVI infoframe: %d\n", ret);
+		return -1;
+	}
+
+	buf[0] = 0;
+	cdns_hdmi_infoframe_set(mhdp, 0, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_AVI);
+
+	return 0;
+}
+
+static void cdns_hdmi_vendor_info_set(struct cdns_mhdp8501_device *mhdp,
+				      struct drm_display_mode *mode)
+{
+	struct hdmi_vendor_infoframe frame;
+	u8 buf[32];
+	int ret;
+
+	/* Initialise vendor frame from DRM mode */
+	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mhdp->curr_conn, mode);
+	if (ret < 0) {
+		dev_info(mhdp->dev, "No vendor infoframe\n");
+		return;
+	}
+
+	ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+	if (ret < 0) {
+		dev_warn(mhdp->dev, "Unable to pack vendor infoframe: %d\n", ret);
+		return;
+	}
+
+	buf[0] = 0;
+	cdns_hdmi_infoframe_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_VENDOR);
+}
+
+static void cdns_hdmi_drm_info_set(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_connector_state *conn_state;
+	struct hdmi_drm_infoframe frame;
+	u8 buf[32];
+	int ret;
+
+	conn_state = mhdp->curr_conn->state;
+
+	if (!conn_state->hdr_output_metadata)
+		return;
+
+	ret = drm_hdmi_infoframe_set_hdr_metadata(&frame, conn_state);
+	if (ret < 0) {
+		dev_dbg(mhdp->dev, "couldn't set HDR metadata in infoframe\n");
+		return;
+	}
+
+	ret = hdmi_drm_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+	if (ret < 0) {
+		dev_dbg(mhdp->dev, "couldn't pack HDR infoframe\n");
+		return;
+	}
+
+	buf[0] = 0;
+	cdns_hdmi_infoframe_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_DRM);
+}
+
+static void cdns_hdmi_mode_set(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_display_mode *mode = &mhdp->mode;
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	/* video mode check */
+	if (mode->clock == 0 || mode->hdisplay == 0 || mode->vdisplay == 0)
+		return;
+
+	cdns_hdmi_lanes_config(mhdp);
+
+	phy_cfg.hdmi.pixel_clk_rate = mode->clock;
+	phy_cfg.hdmi.bpc = mhdp->video_info.bpc;
+	phy_cfg.hdmi.color_space = cdns_hdmi_colorspace(mhdp->video_info.color_fmt);
+
+	/* Mailbox protect for HDMI PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	ret = phy_configure(mhdp->phy, &phy_cfg);
+	mutex_unlock(&mhdp->mbox_mutex);
+	if (ret) {
+		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+			__func__, ret);
+		return;
+	}
+
+	cdns_hdmi_sink_config(mhdp);
+
+	ret = cdns_hdmi_ctrl_init(mhdp, mhdp->hdmi.hdmi_type);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "%s, ret = %d\n", __func__, ret);
+		return;
+	}
+
+	/* Config GCP */
+	if (mhdp->video_info.bpc == 8)
+		cdns_hdmi_disable_gcp(mhdp);
+	else
+		cdns_hdmi_enable_gcp(mhdp);
+
+	ret = cdns_hdmi_avi_info_set(mhdp, mode);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "%s ret = %d\n", __func__, ret);
+		return;
+	}
+
+	/* vendor info frame is enabled only for HDMI1.4 4K mode */
+	cdns_hdmi_vendor_info_set(mhdp, mode);
+
+	cdns_hdmi_drm_info_set(mhdp);
+
+	ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
+		return;
+	}
+}
+
+static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge,
+				   enum drm_bridge_attach_flags flags)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mhdp->dev, "do not support creating a drm_connector\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum drm_mode_status
+cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
+			    const struct drm_display_info *info,
+			    const struct drm_display_mode *mode)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	enum drm_mode_status mode_status = MODE_OK;
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	/* We don't support double-clocked and Interlaced modes */
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
+	    mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_BAD;
+
+	/* MAX support pixel clock rate 594MHz */
+	if (mode->clock > 594000)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->hdisplay > 3840)
+		return MODE_BAD_HVALUE;
+
+	if (mode->vdisplay > 2160)
+		return MODE_BAD_VVALUE;
+
+	/* Check modes supported by PHY */
+	phy_cfg.hdmi.pixel_clk_rate = mode->clock;
+
+	/* Mailbox protect for HDMI PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
+	mutex_unlock(&mhdp->mbox_mutex);
+	if (ret < 0)
+		return MODE_CLOCK_RANGE;
+
+	return mode_status;
+}
+
+static bool
+cdns_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+			    const struct drm_display_mode *mode,
+			    struct drm_display_mode *adjusted_mode)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	struct video_info *video = &mhdp->video_info;
+
+	/* The only currently supported format */
+	video->bpc = 8;
+	video->color_fmt = DRM_COLOR_FORMAT_RGB444;
+
+	return true;
+}
+
+static enum drm_connector_status
+cdns_hdmi_bridge_detect(struct drm_bridge *bridge)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return cdns_mhdp8501_detect(mhdp);
+}
+
+static struct edid *cdns_hdmi_bridge_get_edid(struct drm_bridge *bridge,
+					      struct drm_connector *connector)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return drm_do_get_edid(connector, cdns_hdmi_get_edid_block, mhdp);
+}
+
+static void cdns_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	mhdp->curr_conn = NULL;
+
+	/* Mailbox protect for HDMI PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	phy_power_off(mhdp->phy);
+	mutex_unlock(&mhdp->mbox_mutex);
+}
+
+static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
+					   struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	struct drm_atomic_state *state = old_state->base.state;
+	struct drm_connector *connector;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector_state *conn_state;
+	const struct drm_display_mode *mode;
+
+	connector = drm_atomic_get_new_connector_for_encoder(state,
+							     bridge->encoder);
+	if (WARN_ON(!connector))
+		return;
+
+	mhdp->curr_conn = connector;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (WARN_ON(!conn_state))
+		return;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return;
+
+	mode = &crtc_state->adjusted_mode;
+	dev_dbg(mhdp->dev, "Mode: %dx%dp%d\n",
+		mode->hdisplay, mode->vdisplay, mode->clock);
+	memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
+
+	cdns_hdmi_mode_set(mhdp);
+}
+
+const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
+	.attach = cdns_hdmi_bridge_attach,
+	.detect = cdns_hdmi_bridge_detect,
+	.get_edid = cdns_hdmi_bridge_get_edid,
+	.mode_valid = cdns_hdmi_bridge_mode_valid,
+	.mode_fixup = cdns_hdmi_bridge_mode_fixup,
+	.atomic_enable = cdns_hdmi_bridge_atomic_enable,
+	.atomic_disable = cdns_hdmi_bridge_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,
+};
-- 
2.34.1



From Sandor.yu at nxp.com  Sun Feb  4 02:21:50 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Sun,  4 Feb 2024 18:21:50 +0800
Subject: [PATCH v13 5/7] dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
In-Reply-To: <cover.1707040881.git.Sandor.yu@nxp.com>
References: <cover.1707040881.git.Sandor.yu@nxp.com>
Message-ID: <dba21f64c916eab451a04bdae24cce4980ca9101.1707040881.git.Sandor.yu@nxp.com>

Add bindings for Freescale iMX8MQ DP and HDMI PHY.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
v9->v13:
 *No change.

 .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  | 53 +++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
new file mode 100644
index 0000000000000..917f113503dca
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,imx8mq-dp-hdmi-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence HDP-TX DP/HDMI PHY for Freescale i.MX8MQ SoC
+
+maintainers:
+  - Sandor Yu <sandor.yu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mq-dp-phy
+      - fsl,imx8mq-hdmi-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PHY reference clock.
+      - description: APB clock.
+
+  clock-names:
+    items:
+      - const: ref
+      - const: apb
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/phy/phy.h>
+    dp_phy: phy at 32c00000 {
+        compatible = "fsl,imx8mq-dp-phy";
+        reg = <0x32c00000 0x100000>;
+        #phy-cells = <0>;
+        clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        clock-names = "ref", "apb";
+    };
-- 
2.34.1



From Sandor.yu at nxp.com  Sun Feb  4 02:21:51 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Sun,  4 Feb 2024 18:21:51 +0800
Subject: [PATCH v13 6/7] phy: freescale: Add DisplayPort PHY driver for i.MX8MQ
In-Reply-To: <cover.1707040881.git.Sandor.yu@nxp.com>
References: <cover.1707040881.git.Sandor.yu@nxp.com>
Message-ID: <014905946ca00b6ed6e59fb4997f4ec1b431b83b.1707040881.git.Sandor.yu@nxp.com>

Add Cadence HDP-TX DisplayPort PHY driver for i.MX8MQ

Cadence HDP-TX PHY could be put in either DP mode or
HDMI mode base on the configuration chosen.
DisplayPort PHY mode is configurated in the driver.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
---
v12->v13:
 *No change.

v11->v12:
- Return error code to replace -1 for function wait_for_ack().
- Set cdns_phy->power_up = false in phy_power_down function.
- Remove "RATE_8_1 = 810000", it is not used in driver.
- Add year 2024 to copyright.

 drivers/phy/freescale/Kconfig             |  10 +
 drivers/phy/freescale/Makefile            |   1 +
 drivers/phy/freescale/phy-fsl-imx8mq-dp.c | 726 ++++++++++++++++++++++
 3 files changed, 737 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-dp.c

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index 853958fb2c063..c39709fd700ac 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -35,6 +35,16 @@ config PHY_FSL_IMX8M_PCIE
 	  Enable this to add support for the PCIE PHY as found on
 	  i.MX8M family of SOCs.
 
+config PHY_FSL_IMX8MQ_DP
+	tristate "Freescale i.MX8MQ DP PHY support"
+	depends on OF && HAS_IOMEM
+	depends on COMMON_CLK
+	select GENERIC_PHY
+	select CDNS_MHDP_HELPER
+	help
+	  Enable this to support the Cadence HDPTX DP PHY driver
+	  on i.MX8MQ SOC.
+
 endif
 
 config PHY_FSL_LYNX_28G
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index cedb328bc4d28..47e5285209fa8 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_PHY_FSL_IMX8MQ_DP)		+= phy-fsl-imx8mq-dp.o
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)	+= phy-fsl-imx8mq-usb.o
 obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-dp.c b/drivers/phy/freescale/phy-fsl-imx8mq-dp.c
new file mode 100644
index 0000000000000..2e24ca04c5980
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-dp.c
@@ -0,0 +1,726 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence HDP-TX Display Port Interface (DP) PHY driver
+ *
+ * Copyright (C) 2022-2024 NXP Semiconductor, Inc.
+ */
+#include <asm/unaligned.h>
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#define ADDR_PHY_AFE	0x80000
+
+/* PHY registers */
+#define CMN_SSM_BIAS_TMR			0x0022
+#define CMN_PLLSM0_PLLEN_TMR			0x0029
+#define CMN_PLLSM0_PLLPRE_TMR			0x002a
+#define CMN_PLLSM0_PLLVREF_TMR			0x002b
+#define CMN_PLLSM0_PLLLOCK_TMR			0x002c
+#define CMN_PLLSM0_USER_DEF_CTRL		0x002f
+#define CMN_PSM_CLK_CTRL			0x0061
+#define CMN_PLL0_VCOCAL_START			0x0081
+#define CMN_PLL0_VCOCAL_INIT_TMR		0x0084
+#define CMN_PLL0_VCOCAL_ITER_TMR		0x0085
+#define CMN_PLL0_INTDIV				0x0094
+#define CMN_PLL0_FRACDIV			0x0095
+#define CMN_PLL0_HIGH_THR			0x0096
+#define CMN_PLL0_DSM_DIAG			0x0097
+#define CMN_PLL0_SS_CTRL2			0x0099
+#define CMN_ICAL_INIT_TMR			0x00c4
+#define CMN_ICAL_ITER_TMR			0x00c5
+#define CMN_RXCAL_INIT_TMR			0x00d4
+#define CMN_RXCAL_ITER_TMR			0x00d5
+#define CMN_TXPUCAL_INIT_TMR			0x00e4
+#define CMN_TXPUCAL_ITER_TMR			0x00e5
+#define CMN_TXPDCAL_INIT_TMR			0x00f4
+#define CMN_TXPDCAL_ITER_TMR			0x00f5
+#define CMN_ICAL_ADJ_INIT_TMR			0x0102
+#define CMN_ICAL_ADJ_ITER_TMR			0x0103
+#define CMN_RX_ADJ_INIT_TMR			0x0106
+#define CMN_RX_ADJ_ITER_TMR			0x0107
+#define CMN_TXPU_ADJ_INIT_TMR			0x010a
+#define CMN_TXPU_ADJ_ITER_TMR			0x010b
+#define CMN_TXPD_ADJ_INIT_TMR			0x010e
+#define CMN_TXPD_ADJ_ITER_TMR			0x010f
+#define CMN_DIAG_PLL0_FBH_OVRD			0x01c0
+#define CMN_DIAG_PLL0_FBL_OVRD			0x01c1
+#define CMN_DIAG_PLL0_OVRD			0x01c2
+#define CMN_DIAG_PLL0_TEST_MODE			0x01c4
+#define CMN_DIAG_PLL0_V2I_TUNE			0x01c5
+#define CMN_DIAG_PLL0_CP_TUNE			0x01c6
+#define CMN_DIAG_PLL0_LF_PROG			0x01c7
+#define CMN_DIAG_PLL0_PTATIS_TUNE1		0x01c8
+#define CMN_DIAG_PLL0_PTATIS_TUNE2		0x01c9
+#define CMN_DIAG_HSCLK_SEL			0x01e0
+#define CMN_DIAG_PER_CAL_ADJ			0x01ec
+#define CMN_DIAG_CAL_CTRL			0x01ed
+#define CMN_DIAG_ACYA				0x01ff
+#define XCVR_PSM_RCTRL				0x4001
+#define XCVR_PSM_CAL_TMR			0x4002
+#define XCVR_PSM_A0IN_TMR			0x4003
+#define TX_TXCC_CAL_SCLR_MULT_0			0x4047
+#define TX_TXCC_CPOST_MULT_00_0			0x404c
+#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
+#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
+#define XCVR_DIAG_HSCLK_SEL			0x40e1
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR		0x40f2
+#define TX_PSC_A0				0x4100
+#define TX_PSC_A1				0x4101
+#define TX_PSC_A2				0x4102
+#define TX_PSC_A3				0x4103
+#define TX_RCVDET_EN_TMR			0x4122
+#define TX_RCVDET_ST_TMR			0x4123
+#define TX_DIAG_BGREF_PREDRV_DELAY		0x41e7
+#define TX_DIAG_BGREF_PREDRV_DELAY		0x41e7
+#define TX_DIAG_ACYA_0				0x41ff
+#define TX_DIAG_ACYA_1				0x43ff
+#define TX_DIAG_ACYA_2				0x45ff
+#define TX_DIAG_ACYA_3				0x47ff
+#define TX_ANA_CTRL_REG_1			0x5020
+#define TX_ANA_CTRL_REG_2			0x5021
+#define TX_DIG_CTRL_REG_1			0x5023
+#define TX_DIG_CTRL_REG_2			0x5024
+#define TXDA_CYA_AUXDA_CYA			0x5025
+#define TX_ANA_CTRL_REG_3			0x5026
+#define TX_ANA_CTRL_REG_4			0x5027
+#define TX_ANA_CTRL_REG_5			0x5029
+#define RX_PSC_A0				0x8000
+#define RX_PSC_CAL				0x8006
+#define PHY_HDP_MODE_CTRL			0xc008
+#define PHY_HDP_CLK_CTL				0xc009
+#define PHY_PMA_CMN_CTRL1			0xc800
+
+/* PHY_PMA_CMN_CTRL1 */
+#define CMA_REF_CLK_SEL_MASK			GENMASK(6, 4)
+#define CMA_REF_CLK_RCV_EN_MASK			BIT(3)
+#define CMA_REF_CLK_RCV_EN			1
+
+/* PHY_HDP_CLK_CTL */
+#define PLL_DATA_RATE_CLK_DIV_MASK		GENMASK(15, 8)
+#define PLL_DATA_RATE_CLK_DIV_HBR		0x24
+#define PLL_DATA_RATE_CLK_DIV_HBR2		0x12
+#define PLL_CLK_EN_ACK				BIT(3)
+#define PLL_CLK_EN				BIT(2)
+#define PLL_READY				BIT(1)
+#define PLL_EN					BIT(0)
+
+/* CMN_DIAG_HSCLK_SEL */
+#define HSCLK1_SEL_MASK				GENMASK(5, 4)
+#define HSCLK0_SEL_MASK				GENMASK(1, 0)
+#define HSCLK_PLL0_DIV2				1
+
+/* XCVR_DIAG_HSCLK_SEL */
+#define HSCLK_SEL_MODE3_MASK			GENMASK(13, 12)
+#define HSCLK_SEL_MODE3_HSCLK1			1
+
+/* XCVR_DIAG_PLLDRC_CTRL */
+#define DPLL_CLK_SEL_MODE3			BIT(14)
+#define DPLL_DATA_RATE_DIV_MODE3_MASK		GENMASK(13, 12)
+
+/* PHY_HDP_MODE_CTRL */
+#define POWER_STATE_A3_ACK			BIT(7)
+#define POWER_STATE_A2_ACK			BIT(6)
+#define POWER_STATE_A1_ACK			BIT(5)
+#define POWER_STATE_A0_ACK			BIT(4)
+#define POWER_STATE_A3				BIT(3)
+#define POWER_STATE_A2				BIT(2)
+#define POWER_STATE_A1				BIT(1)
+#define POWER_STATE_A0				BIT(0)
+
+#define REF_CLK_27MHZ		27000000
+
+enum dp_link_rate {
+	RATE_1_6 = 162000,
+	RATE_2_1 = 216000,
+	RATE_2_4 = 243000,
+	RATE_2_7 = 270000,
+	RATE_3_2 = 324000,
+	RATE_4_3 = 432000,
+	RATE_5_4 = 540000,
+};
+
+#define MAX_LINK_RATE RATE_5_4
+
+struct phy_pll_reg {
+	u16 val[7];
+	u32 addr;
+};
+
+static const struct phy_pll_reg phy_pll_27m_cfg[] = {
+	/*  1.62    2.16    2.43    2.7     3.24    4.32    5.4      register address */
+	{{ 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e }, CMN_PLL0_VCOCAL_INIT_TMR },
+	{{ 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b }, CMN_PLL0_VCOCAL_ITER_TMR },
+	{{ 0x30b9, 0x3087, 0x3096, 0x30b4, 0x30b9, 0x3087, 0x30b4 }, CMN_PLL0_VCOCAL_START },
+	{{ 0x0077, 0x009f, 0x00b3, 0x00c7, 0x0077, 0x009f, 0x00c7 }, CMN_PLL0_INTDIV },
+	{{ 0xf9da, 0xf7cd, 0xf6c7, 0xf5c1, 0xf9da, 0xf7cd, 0xf5c1 }, CMN_PLL0_FRACDIV },
+	{{ 0x001e, 0x0028, 0x002d, 0x0032, 0x001e, 0x0028, 0x0032 }, CMN_PLL0_HIGH_THR },
+	{{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_PLL0_DSM_DIAG },
+	{{ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000 }, CMN_PLLSM0_USER_DEF_CTRL },
+	{{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_OVRD },
+	{{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBH_OVRD },
+	{{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBL_OVRD },
+	{{ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007 }, CMN_DIAG_PLL0_V2I_TUNE },
+	{{ 0x0043, 0x0043, 0x0043, 0x0042, 0x0043, 0x0043, 0x0042 }, CMN_DIAG_PLL0_CP_TUNE },
+	{{ 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008 }, CMN_DIAG_PLL0_LF_PROG },
+	{{ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE1 },
+	{{ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE2 },
+	{{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_DIAG_PLL0_TEST_MODE},
+	{{ 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016 }, CMN_PSM_CLK_CTRL }
+};
+
+struct cdns_hdptx_dp_phy {
+	struct cdns_mhdp_base base;
+
+	void __iomem *regs;	/* DPTX registers base */
+	struct device *dev;
+	struct phy *phy;
+	struct mutex mbox_mutex;	/* mutex to protect mailbox */
+	struct clk *ref_clk, *apb_clk;
+	u32 ref_clk_rate;
+	u32 num_lanes;
+	u32 link_rate;
+	bool power_up;
+};
+
+static int cdns_phy_reg_write(struct cdns_hdptx_dp_phy *cdns_phy, u32 addr, u32 val)
+{
+	return cdns_mhdp_reg_write(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), val);
+}
+
+static u32 cdns_phy_reg_read(struct cdns_hdptx_dp_phy *cdns_phy, u32 addr)
+{
+	u32 reg32;
+
+	cdns_mhdp_reg_read(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), &reg32);
+	return reg32;
+}
+
+static int link_rate_index(u32 rate)
+{
+	switch (rate) {
+	case RATE_1_6:
+		return 0;
+	case RATE_2_1:
+		return 1;
+	case RATE_2_4:
+		return 2;
+	case RATE_2_7:
+		return 3;
+	case RATE_3_2:
+		return 4;
+	case RATE_4_3:
+		return 5;
+	case RATE_5_4:
+		return 6;
+	default:
+		return -1;
+	}
+}
+
+static int hdptx_dp_clk_enable(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	struct device *dev = cdns_phy->dev;
+	u32 ref_clk_rate;
+	int ret;
+
+	cdns_phy->ref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(cdns_phy->ref_clk)) {
+		dev_err(dev, "phy ref clock not found\n");
+		return PTR_ERR(cdns_phy->ref_clk);
+	}
+
+	cdns_phy->apb_clk = devm_clk_get(dev, "apb");
+	if (IS_ERR(cdns_phy->apb_clk)) {
+		dev_err(dev, "phy apb clock not found\n");
+		return PTR_ERR(cdns_phy->apb_clk);
+	}
+
+	ret = clk_prepare_enable(cdns_phy->ref_clk);
+	if (ret) {
+		dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+		return ret;
+	}
+
+	ref_clk_rate = clk_get_rate(cdns_phy->ref_clk);
+	if (!ref_clk_rate) {
+		dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
+		goto err_ref_clk;
+	}
+
+	if (ref_clk_rate == REF_CLK_27MHZ) {
+		cdns_phy->ref_clk_rate = ref_clk_rate;
+	} else {
+		dev_err(cdns_phy->dev, "Not support Ref Clock Rate(%dHz)\n", ref_clk_rate);
+		goto err_ref_clk;
+	}
+
+	ret = clk_prepare_enable(cdns_phy->apb_clk);
+	if (ret) {
+		dev_err(cdns_phy->dev, "Failed to prepare apb clock\n");
+		goto err_ref_clk;
+	}
+
+	return 0;
+
+err_ref_clk:
+	clk_disable_unprepare(cdns_phy->ref_clk);
+	return -EINVAL;
+}
+
+static void hdptx_dp_clk_disable(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	clk_disable_unprepare(cdns_phy->ref_clk);
+	clk_disable_unprepare(cdns_phy->apb_clk);
+}
+
+static void hdptx_dp_aux_cfg(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	/* Power up Aux */
+	cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 1);
+
+	cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_1, 0x3);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, 36);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa018);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0000);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x1001);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa098);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa198);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f);
+}
+
+/* PMA common configuration for 27MHz */
+static void hdptx_dp_phy_pma_cmn_cfg_27mhz(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	u32 num_lanes = cdns_phy->num_lanes;
+	u16 val;
+	int k;
+
+	/* Enable PMA input ref clk(CMN_REF_CLK_RCV_EN) */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_RCV_EN_MASK;
+	val |= FIELD_PREP(CMA_REF_CLK_RCV_EN_MASK, CMA_REF_CLK_RCV_EN);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	/* Startup state machine registers */
+	cdns_phy_reg_write(cdns_phy, CMN_SSM_BIAS_TMR, 0x0087);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLEN_TMR, 0x001b);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLPRE_TMR, 0x0036);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLVREF_TMR, 0x001b);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLLOCK_TMR, 0x006c);
+
+	/* Current calibration registers */
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_INIT_TMR, 0x0044);
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_ITER_TMR, 0x0006);
+
+	/* Resistor calibration registers */
+	cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_RXCAL_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_RXCAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_ITER_TMR, 0x0006);
+
+	for (k = 0; k < num_lanes; k = k + 1) {
+		/* Power state machine registers */
+		cdns_phy_reg_write(cdns_phy, XCVR_PSM_CAL_TMR  | (k << 9), 0x016d);
+		cdns_phy_reg_write(cdns_phy, XCVR_PSM_A0IN_TMR | (k << 9), 0x016d);
+		/* Transceiver control and diagnostic registers */
+		cdns_phy_reg_write(cdns_phy, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9), 0x00a2);
+		cdns_phy_reg_write(cdns_phy, TX_DIAG_BGREF_PREDRV_DELAY | (k << 9), 0x0097);
+		/* Transmitter receiver detect registers */
+		cdns_phy_reg_write(cdns_phy, TX_RCVDET_EN_TMR | (k << 9), 0x0a8c);
+		cdns_phy_reg_write(cdns_phy, TX_RCVDET_ST_TMR | (k << 9), 0x0036);
+	}
+
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1);
+}
+
+static void hdptx_dp_phy_pma_cmn_pll0_27mhz(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	u32 num_lanes = cdns_phy->num_lanes;
+	u32 link_rate = cdns_phy->link_rate;
+	u16 val;
+	int index, i, k;
+
+	/* DP PLL data rate 0/1 clock divider value */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_DATA_RATE_CLK_DIV_MASK;
+	if (link_rate <= RATE_2_7)
+		val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
+				  PLL_DATA_RATE_CLK_DIV_HBR);
+	else
+		val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
+				  PLL_DATA_RATE_CLK_DIV_HBR2);
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+
+	/* High speed clock 0/1 div */
+	val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL);
+	val &= ~(HSCLK1_SEL_MASK | HSCLK0_SEL_MASK);
+	if (link_rate <= RATE_2_7) {
+		val |= FIELD_PREP(HSCLK1_SEL_MASK, HSCLK_PLL0_DIV2);
+		val |= FIELD_PREP(HSCLK0_SEL_MASK, HSCLK_PLL0_DIV2);
+	}
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val);
+
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+		val &= ~HSCLK_SEL_MODE3_MASK;
+		if (link_rate <= RATE_2_7)
+			val |= FIELD_PREP(HSCLK_SEL_MODE3_MASK, HSCLK_SEL_MODE3_HSCLK1);
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val);
+	}
+
+	/* DP PHY PLL 27MHz configuration */
+	index = link_rate_index(link_rate);
+	for (i = 0; i < ARRAY_SIZE(phy_pll_27m_cfg); i++)
+		cdns_phy_reg_write(cdns_phy, phy_pll_27m_cfg[i].addr,
+				   phy_pll_27m_cfg[i].val[index]);
+
+	/* Transceiver control and diagnostic registers */
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+		val &= ~(DPLL_DATA_RATE_DIV_MODE3_MASK | DPLL_CLK_SEL_MODE3);
+		if (link_rate <= RATE_2_7)
+			val |= FIELD_PREP(DPLL_DATA_RATE_DIV_MODE3_MASK, 2);
+		else
+			val |= FIELD_PREP(DPLL_DATA_RATE_DIV_MODE3_MASK, 1);
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val);
+	}
+
+	for (k = 0; k < num_lanes; k = k + 1) {
+		/* Power state machine registers */
+		cdns_phy_reg_write(cdns_phy, (XCVR_PSM_RCTRL | (k << 9)), 0xbefc);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A0 | (k << 9)), 0x6799);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A1 | (k << 9)), 0x6798);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A2 | (k << 9)), 0x0098);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A3 | (k << 9)), 0x0098);
+		/* Receiver calibration power state definition register */
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, (RX_PSC_CAL | (k << 9)), val);
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, (RX_PSC_A0 | (k << 9)), val);
+	}
+}
+
+static void hdptx_dp_phy_ref_clock_type(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	u32 val;
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_SEL_MASK;
+	/*
+	 * single ended reference clock (val |= 0x0030);
+	 * differential clock  (val |= 0x0000);
+	 *
+	 * for differential clock on the refclk_p and
+	 * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1
+	 * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100);
+	 */
+	val |= FIELD_PREP(CMA_REF_CLK_SEL_MASK, 3);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+}
+
+static int wait_for_ack(struct cdns_hdptx_dp_phy *cdns_phy, u32 reg, u32 mask,
+			const char *err_msg)
+{
+	u32 val, i;
+
+	for (i = 0; i < 10; i++) {
+		val = cdns_phy_reg_read(cdns_phy, reg);
+		if (val & mask)
+			return 0;
+		msleep(20);
+	}
+
+	dev_err(cdns_phy->dev, "%s\n", err_msg);
+	return -ETIMEDOUT;
+}
+
+static int wait_for_ack_clear(struct cdns_hdptx_dp_phy *cdns_phy, u32 reg, u32 mask,
+			      const char *err_msg)
+{
+	u32 val, i;
+
+	for (i = 0; i < 10; i++) {
+		val = cdns_phy_reg_read(cdns_phy, reg);
+		if (!(val & mask))
+			return 0;
+		msleep(20);
+	}
+
+	dev_err(cdns_phy->dev, "%s\n", err_msg);
+	return -ETIMEDOUT;
+}
+
+static int hdptx_dp_phy_power_up(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	u32 val;
+	int ret = 0;
+
+	/* Enable HDP PLL?s for high speed clocks */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val |= PLL_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_CLK_CTL, PLL_READY,
+			   "Wait PLL Ack failed");
+	if (ret < 0)
+		return ret;
+
+	/* Enable HDP PLL?s data rate and full rate clocks out of PMA. */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val |= PLL_CLK_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_CLK_CTL, PLL_CLK_EN_ACK,
+			   "Wait PLL clock enable ACK failed");
+	if (ret < 0)
+		return ret;
+
+	/* Configure PHY in A2 Mode */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2_ACK,
+			   "Wait A2 Ack failed");
+	if (ret < 0)
+		return ret;
+
+	/* Configure PHY in A0 mode (PHY must be in the A0 power
+	 * state in order to transmit data)
+	 */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0_ACK,
+			   "Wait A0 Ack failed");
+	if (ret < 0)
+		return ret;
+
+	cdns_phy->power_up = true;
+
+	return ret;
+}
+
+static void hdptx_dp_phy_power_down(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	u16 val;
+
+	if (!cdns_phy->power_up)
+		return;
+
+	/* Place the PHY lanes in the A3 power state. */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3);
+	if (wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3_ACK,
+			 "Wait A3 Ack failed"))
+		return;
+
+	/* Disable HDP PLL?s data rate and full rate clocks out of PMA. */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_CLK_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	if (wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL, PLL_CLK_EN_ACK,
+			       "Wait PLL clock Ack clear failed"))
+		return;
+
+	/* Disable HDP PLL?s for high speed clocks */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	if (wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL, PLL_READY,
+			       "Wait PLL Ack clear failed"))
+		return;
+
+	cdns_phy->power_up = false;
+}
+
+static int cdns_hdptx_dp_phy_on(struct phy *phy)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy);
+
+	return hdptx_dp_phy_power_up(cdns_phy);
+}
+
+static int cdns_hdptx_dp_phy_off(struct phy *phy)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy);
+
+	hdptx_dp_phy_power_down(cdns_phy);
+
+	return 0;
+}
+
+static int cdns_hdptx_dp_phy_init(struct phy *phy)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy);
+	int ret;
+
+	hdptx_dp_phy_ref_clock_type(cdns_phy);
+
+	/* PHY power up */
+	ret = hdptx_dp_phy_power_up(cdns_phy);
+	if (ret < 0)
+		return ret;
+
+	hdptx_dp_aux_cfg(cdns_phy);
+
+	return ret;
+}
+
+static int cdns_hdptx_dp_configure(struct phy *phy,
+				   union phy_configure_opts *opts)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy);
+	int ret;
+
+	cdns_phy->link_rate = opts->dp.link_rate;
+	cdns_phy->num_lanes = opts->dp.lanes;
+
+	if (cdns_phy->link_rate > MAX_LINK_RATE) {
+		dev_err(cdns_phy->dev, "Link Rate(%d) Not supported\n", cdns_phy->link_rate);
+		return false;
+	}
+
+	/* Disable phy clock if PHY in power up state */
+	hdptx_dp_phy_power_down(cdns_phy);
+
+	if (cdns_phy->ref_clk_rate == REF_CLK_27MHZ) {
+		hdptx_dp_phy_pma_cmn_cfg_27mhz(cdns_phy);
+		hdptx_dp_phy_pma_cmn_pll0_27mhz(cdns_phy);
+	} else {
+		dev_err(cdns_phy->dev, "Not support ref clock rate\n");
+	}
+
+	/* PHY power up */
+	ret = hdptx_dp_phy_power_up(cdns_phy);
+
+	return ret;
+}
+
+static const struct phy_ops cdns_hdptx_dp_phy_ops = {
+	.init = cdns_hdptx_dp_phy_init,
+	.configure = cdns_hdptx_dp_configure,
+	.power_on = cdns_hdptx_dp_phy_on,
+	.power_off = cdns_hdptx_dp_phy_off,
+	.owner = THIS_MODULE,
+};
+
+static int cdns_hdptx_dp_phy_probe(struct platform_device *pdev)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy;
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct phy_provider *phy_provider;
+	struct resource *res;
+	struct phy *phy;
+	int ret;
+
+	cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
+	if (!cdns_phy)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, cdns_phy);
+	cdns_phy->dev = dev;
+	mutex_init(&cdns_phy->mbox_mutex);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(cdns_phy->regs))
+		return PTR_ERR(cdns_phy->regs);
+
+	phy = devm_phy_create(dev, node, &cdns_hdptx_dp_phy_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	phy->attrs.mode = PHY_MODE_DP;
+	cdns_phy->phy = phy;
+	phy_set_drvdata(phy, cdns_phy);
+
+	/* init base struct for access mhdp mailbox */
+	cdns_phy->base.dev = cdns_phy->dev;
+	cdns_phy->base.regs = cdns_phy->regs;
+	cdns_phy->base.mbox_mutex = &cdns_phy->mbox_mutex;
+
+	ret = hdptx_dp_clk_enable(cdns_phy);
+	if (ret) {
+		dev_err(dev, "Init clk fail\n");
+		return -EINVAL;
+	}
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider)) {
+		ret = PTR_ERR(phy_provider);
+		goto clk_disable;
+	}
+
+	return 0;
+
+clk_disable:
+	hdptx_dp_clk_disable(cdns_phy);
+
+	return -EINVAL;
+}
+
+static int cdns_hdptx_dp_phy_remove(struct platform_device *pdev)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy = platform_get_drvdata(pdev);
+
+	hdptx_dp_clk_disable(cdns_phy);
+
+	return 0;
+}
+
+static const struct of_device_id cdns_hdptx_dp_phy_of_match[] = {
+	{.compatible = "fsl,imx8mq-dp-phy" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cdns_hdptx_dp_phy_of_match);
+
+static struct platform_driver cdns_hdptx_dp_phy_driver = {
+	.probe = cdns_hdptx_dp_phy_probe,
+	.remove = cdns_hdptx_dp_phy_remove,
+	.driver = {
+		.name	= "cdns-hdptx-dp-phy",
+		.of_match_table	= cdns_hdptx_dp_phy_of_match,
+	}
+};
+module_platform_driver(cdns_hdptx_dp_phy_driver);
+
+MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("Cadence HDP-TX DisplayPort PHY driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From Sandor.yu at nxp.com  Sun Feb  4 02:21:52 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Sun,  4 Feb 2024 18:21:52 +0800
Subject: [PATCH v13 7/7] phy: freescale: Add HDMI PHY driver for i.MX8MQ
In-Reply-To: <cover.1707040881.git.Sandor.yu@nxp.com>
References: <cover.1707040881.git.Sandor.yu@nxp.com>
Message-ID: <4b738ea9ff234fc125a82062c5797a40a20eb6b6.1707040881.git.Sandor.yu@nxp.com>

Add Cadence HDP-TX HDMI PHY driver for i.MX8MQ.

Cadence HDP-TX PHY could be put in either DP mode or
HDMI mode base on the configuration chosen.
HDMI PHY mode is configurated in the driver.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
v12->v13:
- Fix build warning

v11->v12:
- Adjust clk disable order.
- Return error code to replace -1 for function wait_for_ack().
- Use bool for variable pclk_in.
- Add year 2024 to copyright.

 drivers/phy/freescale/Kconfig               |  10 +
 drivers/phy/freescale/Makefile              |   1 +
 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c | 960 ++++++++++++++++++++
 3 files changed, 971 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index c39709fd700ac..14f47b7cc77ab 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -45,6 +45,16 @@ config PHY_FSL_IMX8MQ_DP
 	  Enable this to support the Cadence HDPTX DP PHY driver
 	  on i.MX8MQ SOC.
 
+config PHY_FSL_IMX8MQ_HDMI
+	tristate "Freescale i.MX8MQ HDMI PHY support"
+	depends on OF && HAS_IOMEM
+	depends on COMMON_CLK
+	select GENERIC_PHY
+	select CDNS_MHDP_HELPER
+	help
+	  Enable this to support the Cadence HDPTX HDMI PHY driver
+	  on i.MX8MQ SOC.
+
 endif
 
 config PHY_FSL_LYNX_28G
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index 47e5285209fa8..1380ac31c2ead 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_FSL_IMX8MQ_DP)		+= phy-fsl-imx8mq-dp.o
+obj-$(CONFIG_PHY_FSL_IMX8MQ_HDMI)	+= phy-fsl-imx8mq-hdmi.o
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)	+= phy-fsl-imx8mq-usb.o
 obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
new file mode 100644
index 0000000000000..537b1f45c91cc
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
@@ -0,0 +1,960 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence High-Definition Multimedia Interface (HDMI) PHY driver
+ *
+ * Copyright (C) 2022-2024 NXP Semiconductor, Inc.
+ */
+#include <asm/unaligned.h>
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#define ADDR_PHY_AFE	0x80000
+
+/* PHY registers */
+#define CMN_SSM_BIAS_TMR			0x0022
+#define CMN_PLLSM0_USER_DEF_CTRL		0x002f
+#define CMN_PSM_CLK_CTRL			0x0061
+#define CMN_CDIAG_REFCLK_CTRL			0x0062
+#define CMN_PLL0_VCOCAL_START			0x0081
+#define CMN_PLL0_VCOCAL_INIT_TMR		0x0084
+#define CMN_PLL0_VCOCAL_ITER_TMR		0x0085
+#define CMN_TXPUCAL_CTRL			0x00e0
+#define CMN_TXPDCAL_CTRL			0x00f0
+#define CMN_TXPU_ADJ_CTRL			0x0108
+#define CMN_TXPD_ADJ_CTRL			0x010c
+#define CMN_DIAG_PLL0_FBH_OVRD			0x01c0
+#define CMN_DIAG_PLL0_FBL_OVRD			0x01c1
+#define CMN_DIAG_PLL0_OVRD			0x01c2
+#define CMN_DIAG_PLL0_TEST_MODE			0x01c4
+#define CMN_DIAG_PLL0_V2I_TUNE			0x01c5
+#define CMN_DIAG_PLL0_CP_TUNE			0x01c6
+#define CMN_DIAG_PLL0_LF_PROG			0x01c7
+#define CMN_DIAG_PLL0_PTATIS_TUNE1		0x01c8
+#define CMN_DIAG_PLL0_PTATIS_TUNE2		0x01c9
+#define CMN_DIAG_PLL0_INCLK_CTRL		0x01ca
+#define CMN_DIAG_PLL0_PXL_DIVH			0x01cb
+#define CMN_DIAG_PLL0_PXL_DIVL			0x01cc
+#define CMN_DIAG_HSCLK_SEL			0x01e0
+#define XCVR_PSM_RCTRL				0x4001
+#define TX_TXCC_CAL_SCLR_MULT_0			0x4047
+#define TX_TXCC_CPOST_MULT_00_0			0x404c
+#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
+#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
+#define XCVR_DIAG_HSCLK_SEL			0x40e1
+#define XCVR_DIAG_BIDI_CTRL			0x40e8
+#define TX_PSC_A0				0x4100
+#define TX_PSC_A1				0x4101
+#define TX_PSC_A2				0x4102
+#define TX_PSC_A3				0x4103
+#define TX_DIAG_TX_CTRL				0x41e0
+#define TX_DIAG_TX_DRV				0x41e1
+#define TX_DIAG_BGREF_PREDRV_DELAY		0x41e7
+#define TX_DIAG_ACYA_0				0x41ff
+#define TX_DIAG_ACYA_1				0x43ff
+#define TX_DIAG_ACYA_2				0x45ff
+#define TX_DIAG_ACYA_3				0x47ff
+#define TX_ANA_CTRL_REG_1			0x5020
+#define TX_ANA_CTRL_REG_2			0x5021
+#define TX_DIG_CTRL_REG_2			0x5024
+#define TXDA_CYA_AUXDA_CYA			0x5025
+#define TX_ANA_CTRL_REG_3			0x5026
+#define TX_ANA_CTRL_REG_4			0x5027
+#define TX_ANA_CTRL_REG_5			0x5029
+#define RX_PSC_A0				0x8000
+#define RX_PSC_CAL				0x8006
+#define PHY_HDP_MODE_CTRL			0xc008
+#define PHY_HDP_CLK_CTL				0xc009
+#define PHY_ISO_CMN_CTRL			0xc010
+#define PHY_PMA_CMN_CTRL1			0xc800
+#define PHY_PMA_ISO_CMN_CTRL			0xc810
+#define PHY_PMA_ISO_PLL_CTRL1			0xc812
+#define PHY_PMA_ISOLATION_CTRL			0xc81f
+
+/* PHY_HDP_CLK_CTL */
+#define PLL_DATA_RATE_CLK_DIV_MASK		GENMASK(15, 8)
+#define PLL_DATA_RATE_CLK_DIV_HBR		0x24
+#define PLL_DATA_RATE_CLK_DIV_HBR2		0x12
+#define PLL_CLK_EN_ACK_EN			BIT(3)
+#define PLL_CLK_EN				BIT(2)
+#define PLL_READY				BIT(1)
+#define PLL_EN					BIT(0)
+
+/* PHY_PMA_CMN_CTRL1 */
+#define CMA_REF_CLK_DIG_DIV_MASK		GENMASK(13, 12)
+#define CMA_REF_CLK_SEL_MASK			GENMASK(6, 4)
+#define CMA_REF_CLK_RCV_EN_MASK			BIT(3)
+#define CMA_REF_CLK_RCV_EN			1
+#define CMN_READY				BIT(0)
+
+/* PHY_PMA_ISO_PLL_CTRL1 */
+#define CMN_PLL0_CLK_DATART_DIV_MASK		GENMASK(7, 0)
+
+/* TX_DIAG_TX_DRV */
+#define TX_DRIVER_PROG_BOOST_ENABLE		BIT(10)
+#define TX_DRIVER_PROG_BOOST_LEVEL_MASK		GENMASK(9, 8)
+#define TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE	BIT(7)
+#define TX_DRIVER_LDO_BANDGAP_REF_ENABLE	BIT(6)
+
+/* TX_TXCC_CAL_SCLR_MULT_0 */
+#define SCALED_RESISTOR_CALIBRATION_CODE_ADD	BIT(8)
+#define RESISTOR_CAL_MULT_VAL_32_128		BIT(5)
+
+/* CMN_CDIAG_REFCLK_CTRL */
+#define DIG_REF_CLK_DIV_SCALER_MASK		GENMASK(14, 12)
+#define REFCLK_TERMINATION_EN_OVERRIDE_EN	BIT(7)
+#define REFCLK_TERMINATION_EN_OVERRIDE		BIT(6)
+
+/* CMN_DIAG_HSCLK_SEL */
+#define HSCLK1_SEL_MASK				GENMASK(5, 4)
+#define HSCLK0_SEL_MASK				GENMASK(1, 0)
+
+/* XCVR_DIAG_HSCLK_SEL */
+#define HSCLK_SEL_MODE3_MASK			GENMASK(13, 12)
+#define HSCLK_SEL_MODE3_HSCLK1			1
+
+/* CMN_PLL0_VCOCAL_START */
+#define VCO_CALIB_CODE_START_POINT_VAL_MASK	GENMASK(8, 0)
+
+/* CMN_DIAG_PLL0_FBH_OVRD */
+#define PLL_FEEDBACK_DIV_HI_OVERRIDE_EN		BIT(15)
+
+/* CMN_DIAG_PLL0_FBL_OVRD */
+#define PLL_FEEDBACK_DIV_LO_OVERRIDE_EN		BIT(15)
+
+/* CMN_DIAG_PLL0_PXL_DIVH */
+#define PLL_PCLK_DIV_EN				BIT(15)
+
+/* XCVR_DIAG_PLLDRC_CTRL */
+#define DPLL_CLK_SEL_MODE3			BIT(14)
+
+/* TX_DIAG_TX_CTRL */
+#define TX_IF_SUBRATE_MODE3_MASK		GENMASK(7, 6)
+
+/* PHY_HDP_MODE_CTRL */
+#define POWER_STATE_A3_ACK			BIT(7)
+#define POWER_STATE_A2_ACK			BIT(6)
+#define POWER_STATE_A1_ACK			BIT(5)
+#define POWER_STATE_A0_ACK			BIT(4)
+#define POWER_STATE_A3				BIT(3)
+#define POWER_STATE_A2				BIT(2)
+#define POWER_STATE_A1				BIT(1)
+#define POWER_STATE_A0				BIT(0)
+
+/* PHY_PMA_ISO_CMN_CTRL */
+#define CMN_MACRO_PWR_EN_ACK			BIT(5)
+
+#define KEEP_ALIVE		0x18
+
+#define REF_CLK_27MHZ		27000000
+
+/* HDMI TX clock control settings */
+struct hdptx_hdmi_ctrl {
+	u32 pixel_clk_freq_min;
+	u32 pixel_clk_freq_max;
+	u32 feedback_factor;
+	u32 data_range_kbps_min;
+	u32 data_range_kbps_max;
+	u32 cmnda_pll0_ip_div;
+	u32 cmn_ref_clk_dig_div;
+	u32 ref_clk_divider_scaler;
+	u32 pll_fb_div_total;
+	u32 cmnda_pll0_fb_div_low;
+	u32 cmnda_pll0_fb_div_high;
+	u32 pixel_div_total;
+	u32 cmnda_pll0_pxdiv_low;
+	u32 cmnda_pll0_pxdiv_high;
+	u32 vco_freq_min;
+	u32 vco_freq_max;
+	u32 vco_ring_select;
+	u32 cmnda_hs_clk_0_sel;
+	u32 cmnda_hs_clk_1_sel;
+	u32 hsclk_div_at_xcvr;
+	u32 hsclk_div_tx_sub_rate;
+	u32 cmnda_pll0_hs_sym_div_sel;
+	u32 cmnda_pll0_clk_freq_min;
+	u32 cmnda_pll0_clk_freq_max;
+};
+
+struct cdns_hdptx_hdmi_phy {
+	struct cdns_mhdp_base base;
+
+	void __iomem *regs;	/* DPTX registers base */
+	struct mutex mbox_mutex; /* mutex to protect mailbox */
+	struct device *dev;
+	struct phy *phy;
+	struct clk *ref_clk, *apb_clk;
+	u32 ref_clk_rate;
+	u32 pixel_clk_rate;
+	enum hdmi_colorspace color_space;
+	u32 bpc;
+};
+
+/* HDMI TX clock control settings, pixel clock is output */
+static const struct hdptx_hdmi_ctrl pixel_clk_output_ctrl_table[] = {
+/*Minclk  Maxclk Fdbak  DR_min   DR_max  ip_d  dig  DS    Totl */
+{ 27000,  27000, 1000,  270000,  270000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x3,  27000,  27000},
+{ 27000,  27000, 1250,  337500,  337500, 0x03, 0x1, 0x1,  300, 0x0ec, 0x03c, 100, 0x030, 0x030, 2700000, 2700000, 0, 2, 2, 2, 4, 0x3,  33750,  33750},
+{ 27000,  27000, 1500,  405000,  405000, 0x03, 0x1, 0x1,  360, 0x11c, 0x048, 120, 0x03a, 0x03a, 3240000, 3240000, 0, 2, 2, 2, 4, 0x3,  40500,  40500},
+{ 27000,  27000, 2000,  540000,  540000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x2,  54000,  54000},
+{ 54000,  54000, 1000,  540000,  540000, 0x03, 0x1, 0x1,  480, 0x17c, 0x060,  80, 0x026, 0x026, 4320000, 4320000, 1, 2, 2, 2, 4, 0x3,  54000,  54000},
+{ 54000,  54000, 1250,  675000,  675000, 0x04, 0x1, 0x1,  400, 0x13c, 0x050,  50, 0x017, 0x017, 2700000, 2700000, 0, 1, 1, 2, 4, 0x2,  67500,  67500},
+{ 54000,  54000, 1500,  810000,  810000, 0x04, 0x1, 0x1,  480, 0x17c, 0x060,  60, 0x01c, 0x01c, 3240000, 3240000, 0, 2, 2, 2, 2, 0x2,  81000,  81000},
+{ 54000,  54000, 2000, 1080000, 1080000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  40, 0x012, 0x012, 2160000, 2160000, 0, 2, 2, 2, 1, 0x1, 108000, 108000},
+{ 74250,  74250, 1000,  742500,  742500, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  80, 0x026, 0x026, 5940000, 5940000, 1, 2, 2, 2, 4, 0x3,  74250,  74250},
+{ 74250,  74250, 1250,  928125,  928125, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  50, 0x017, 0x017, 3712500, 3712500, 1, 1, 1, 2, 4, 0x2,  92812,  92812},
+{ 74250,  74250, 1500, 1113750, 1113750, 0x04, 0x1, 0x1,  660, 0x20c, 0x084,  60, 0x01c, 0x01c, 4455000, 4455000, 1, 2, 2, 2, 2, 0x2, 111375, 111375},
+{ 74250,  74250, 2000, 1485000, 1485000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  40, 0x012, 0x012, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1, 148500, 148500},
+{ 99000,  99000, 1000,  990000,  990000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  40, 0x012, 0x012, 3960000, 3960000, 1, 2, 2, 2, 2, 0x2,  99000,  99000},
+{ 99000,  99000, 1250, 1237500, 1237500, 0x03, 0x1, 0x1,  275, 0x0d8, 0x037,  25, 0x00b, 0x00a, 2475000, 2475000, 0, 1, 1, 2, 2, 0x1, 123750, 123750},
+{ 99000,  99000, 1500, 1485000, 1485000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  30, 0x00d, 0x00d, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1, 148500, 148500},
+{ 99000,  99000, 2000, 1980000, 1980000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  40, 0x012, 0x012, 3960000, 3960000, 1, 2, 2, 2, 1, 0x1, 198000, 198000},
+{148500, 148500, 1000, 1485000, 1485000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  40, 0x012, 0x012, 5940000, 5940000, 1, 2, 2, 2, 2, 0x2, 148500, 148500},
+{148500, 148500, 1250, 1856250, 1856250, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  25, 0x00b, 0x00a, 3712500, 3712500, 1, 1, 1, 2, 2, 0x1, 185625, 185625},
+{148500, 148500, 1500, 2227500, 2227500, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  30, 0x00d, 0x00d, 4455000, 4455000, 1, 1, 1, 2, 2, 0x1, 222750, 222750},
+{148500, 148500, 2000, 2970000, 2970000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  40, 0x012, 0x012, 5940000, 5940000, 1, 2, 2, 2, 1, 0x1, 297000, 297000},
+{198000, 198000, 1000, 1980000, 1980000, 0x03, 0x1, 0x1,  220, 0x0ac, 0x02c,  10, 0x003, 0x003, 1980000, 1980000, 0, 1, 1, 2, 1, 0x0, 198000, 198000},
+{198000, 198000, 1250, 2475000, 2475000, 0x03, 0x1, 0x1,  550, 0x1b4, 0x06e,  25, 0x00b, 0x00a, 4950000, 4950000, 1, 1, 1, 2, 2, 0x1, 247500, 247500},
+{198000, 198000, 1500, 2970000, 2970000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  15, 0x006, 0x005, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000, 297000},
+{198000, 198000, 2000, 3960000, 3960000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  20, 0x008, 0x008, 3960000, 3960000, 1, 1, 1, 2, 1, 0x0, 396000, 396000},
+{297000, 297000, 1000, 2970000, 2970000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  10, 0x003, 0x003, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000, 297000},
+{297000, 297000, 1500, 4455000, 4455000, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  15, 0x006, 0x005, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0, 445500, 445500},
+{297000, 297000, 2000, 5940000, 5940000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  20, 0x008, 0x008, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000},
+{594000, 594000, 1000, 5940000, 5940000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  10, 0x003, 0x003, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000},
+{594000, 594000,  750, 4455000, 4455000, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  10, 0x003, 0x003, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0, 445500, 445500},
+{594000, 594000,  625, 3712500, 3712500, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  10, 0x003, 0x003, 3712500, 3712500, 1, 1, 1, 2, 1, 0x0, 371250, 371250},
+{594000, 594000,  500, 2970000, 2970000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  10, 0x003, 0x003, 5940000, 5940000, 1, 1, 1, 2, 2, 0x1, 297000, 297000},
+};
+
+/* HDMI TX PLL tuning settings */
+struct hdptx_hdmi_pll_tuning {
+	u32 vco_freq_bin;
+	u32 vco_freq_min;
+	u32 vco_freq_max;
+	u32 volt_to_current_coarse;
+	u32 volt_to_current;
+	u32 ndac_ctrl;
+	u32 pmos_ctrl;
+	u32 ptat_ndac_ctrl;
+	u32 feedback_div_total;
+	u32 charge_pump_gain;
+	u32 coarse_code;
+	u32 v2i_code;
+	u32 vco_cal_code;
+};
+
+/* HDMI TX PLL tuning settings, pixel clock is output */
+static const struct hdptx_hdmi_pll_tuning pixel_clk_output_pll_table[] = {
+/*bin VCO_freq min/max  coar  cod NDAC  PMOS PTAT div-T P-Gain Coa V2I CAL */
+{  1, 1980000, 1980000, 0x4, 0x3, 0x0, 0x09, 0x09, 220, 0x42, 160, 5, 183 },
+{  2, 2160000, 2160000, 0x4, 0x3, 0x0, 0x09, 0x09, 240, 0x42, 166, 6, 208 },
+{  3, 2475000, 2475000, 0x5, 0x3, 0x1, 0x00, 0x07, 275, 0x42, 167, 6, 209 },
+{  4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 300, 0x42, 188, 6, 230 },
+{  4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 400, 0x4c, 188, 6, 230 },
+{  5, 2970000, 2970000, 0x6, 0x3, 0x1, 0x00, 0x07, 330, 0x42, 183, 6, 225 },
+{  6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 360, 0x42, 203, 7, 256 },
+{  6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 480, 0x4c, 203, 7, 256 },
+{  7, 3712500, 3712500, 0x4, 0x3, 0x0, 0x07, 0x0F, 550, 0x4c, 212, 7, 257 },
+{  8, 3960000, 3960000, 0x5, 0x3, 0x0, 0x07, 0x0F, 440, 0x42, 184, 6, 226 },
+{  9, 4320000, 4320000, 0x5, 0x3, 0x1, 0x07, 0x0F, 480, 0x42, 205, 7, 258 },
+{ 10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 495, 0x42, 219, 7, 272 },
+{ 10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 660, 0x4c, 219, 7, 272 },
+{ 11, 4950000, 4950000, 0x6, 0x3, 0x1, 0x00, 0x07, 550, 0x42, 213, 7, 258 },
+{ 12, 5940000, 5940000, 0x7, 0x3, 0x1, 0x00, 0x07, 660, 0x42, 244, 8, 292 },
+};
+
+static int cdns_phy_reg_write(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 addr, u32 val)
+{
+	return cdns_mhdp_reg_write(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), val);
+}
+
+static u32 cdns_phy_reg_read(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 addr)
+{
+	u32 reg32;
+
+	cdns_mhdp_reg_read(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), &reg32);
+
+	return reg32;
+}
+
+static int wait_for_ack(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 reg, u32 mask,
+			const char *err_msg)
+{
+	u32 val, i;
+
+	for (i = 0; i < 10; i++) {
+		val = cdns_phy_reg_read(cdns_phy, reg);
+		if (val & mask)
+			return 0;
+		msleep(20);
+	}
+
+	dev_err(cdns_phy->dev, "%s\n", err_msg);
+	return -ETIMEDOUT;
+}
+
+static bool hdptx_phy_check_alive(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	u32  alive, newalive;
+	u8 retries_left = 50;
+
+	alive = readl(cdns_phy->regs + KEEP_ALIVE);
+
+	while (retries_left--) {
+		udelay(2);
+
+		newalive = readl(cdns_phy->regs + KEEP_ALIVE);
+		if (alive == newalive)
+			continue;
+		return true;
+	}
+	return false;
+}
+
+static int hdptx_hdmi_clk_enable(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	struct device *dev = cdns_phy->dev;
+	u32 ref_clk_rate;
+	int ret;
+
+	cdns_phy->ref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(cdns_phy->ref_clk)) {
+		dev_err(dev, "phy ref clock not found\n");
+		return PTR_ERR(cdns_phy->ref_clk);
+	}
+
+	cdns_phy->apb_clk = devm_clk_get(dev, "apb");
+	if (IS_ERR(cdns_phy->apb_clk)) {
+		dev_err(dev, "phy apb clock not found\n");
+		return PTR_ERR(cdns_phy->apb_clk);
+	}
+
+	ret = clk_prepare_enable(cdns_phy->ref_clk);
+	if (ret) {
+		dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+		return ret;
+	}
+
+	ref_clk_rate = clk_get_rate(cdns_phy->ref_clk);
+	if (!ref_clk_rate) {
+		dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
+		goto err_ref_clk;
+	}
+
+	if (ref_clk_rate == REF_CLK_27MHZ) {
+		cdns_phy->ref_clk_rate = ref_clk_rate;
+	} else {
+		dev_err(cdns_phy->dev, "Not support Ref Clock Rate(%dHz)\n", ref_clk_rate);
+		goto err_ref_clk;
+	}
+
+	ret = clk_prepare_enable(cdns_phy->apb_clk);
+	if (ret) {
+		dev_err(cdns_phy->dev, "Failed to prepare apb clock\n");
+		goto err_ref_clk;
+	}
+
+	return 0;
+
+err_ref_clk:
+	clk_disable_unprepare(cdns_phy->ref_clk);
+	return -EINVAL;
+}
+
+static void hdptx_hdmi_clk_disable(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	clk_disable_unprepare(cdns_phy->apb_clk);
+	clk_disable_unprepare(cdns_phy->ref_clk);
+}
+
+static void hdptx_hdmi_arc_config(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	u16 txpu_calib_code;
+	u16 txpd_calib_code;
+	u16 txpu_adj_calib_code;
+	u16 txpd_adj_calib_code;
+	u16 prev_calib_code;
+	u16 new_calib_code;
+	u16 rdata;
+
+	/* Power ARC */
+	cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 0x0001);
+
+	prev_calib_code = cdns_phy_reg_read(cdns_phy, TX_DIG_CTRL_REG_2);
+	txpu_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPUCAL_CTRL);
+	txpd_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPDCAL_CTRL);
+	txpu_adj_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPU_ADJ_CTRL);
+	txpd_adj_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPD_ADJ_CTRL);
+
+	new_calib_code = ((txpu_calib_code + txpd_calib_code) / 2)
+		+ txpu_adj_calib_code + txpd_adj_calib_code;
+
+	if (new_calib_code != prev_calib_code) {
+		rdata = cdns_phy_reg_read(cdns_phy, TX_ANA_CTRL_REG_1);
+		rdata &= 0xdfff;
+		cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, rdata);
+		cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, new_calib_code);
+		mdelay(10);
+		rdata |= 0x2000;
+		cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, rdata);
+		usleep_range(150, 250);
+	}
+
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2098);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0010);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x4001);
+	mdelay(5);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2198);
+	mdelay(5);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f);
+}
+
+static void hdptx_hdmi_phy_set_vswing(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	u32 k;
+	const u32 num_lanes = 4;
+
+	for (k = 0; k < num_lanes; k++) {
+		cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_DRV | (k << 9)),
+				   TX_DRIVER_PROG_BOOST_ENABLE |
+				   FIELD_PREP(TX_DRIVER_PROG_BOOST_LEVEL_MASK, 3) |
+				   TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE |
+				   TX_DRIVER_LDO_BANDGAP_REF_ENABLE);
+		cdns_phy_reg_write(cdns_phy, (TX_TXCC_CPOST_MULT_00_0 | (k << 9)), 0x0);
+		cdns_phy_reg_write(cdns_phy, (TX_TXCC_CAL_SCLR_MULT_0 | (k << 9)),
+				   SCALED_RESISTOR_CALIBRATION_CODE_ADD |
+				   RESISTOR_CAL_MULT_VAL_32_128);
+	}
+}
+
+static int hdptx_hdmi_feedback_factor(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	u32 feedback_factor;
+
+	switch (cdns_phy->color_space) {
+	case HDMI_COLORSPACE_YUV422:
+		feedback_factor = 1000;
+		break;
+
+	case HDMI_COLORSPACE_YUV420:
+		switch (cdns_phy->bpc) {
+		case 8:
+			feedback_factor = 500;
+			break;
+		case 10:
+			feedback_factor = 625;
+			break;
+		case 12:
+			feedback_factor = 750;
+			break;
+		case 16:
+			feedback_factor = 1000;
+			break;
+		default:
+			dev_dbg(cdns_phy->dev, "Invalid ColorDepth\n");
+			return 0;
+		}
+		break;
+
+	default:
+		/* Assume RGB/YUV444 */
+		switch (cdns_phy->bpc) {
+		case 10:
+			feedback_factor = 1250;
+			break;
+		case 12:
+			feedback_factor = 1500;
+			break;
+		case 16:
+			feedback_factor = 2000;
+			break;
+		default:
+			feedback_factor = 1000;
+		}
+	}
+
+	return feedback_factor;
+}
+
+static int hdptx_hdmi_phy_config(struct cdns_hdptx_hdmi_phy *cdns_phy,
+				 const struct hdptx_hdmi_ctrl *p_ctrl_table,
+				 const struct hdptx_hdmi_pll_tuning *p_pll_table,
+				 bool pclk_in)
+{
+	const u32 num_lanes = 4;
+	u32 val, k;
+	int ret;
+
+	/* enable PHY isolation mode only for CMN */
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISOLATION_CTRL, 0xd000);
+
+	/* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div dividers */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_ISO_PLL_CTRL1);
+	val &= ~CMN_PLL0_CLK_DATART_DIV_MASK;
+	val |= FIELD_PREP(CMN_PLL0_CLK_DATART_DIV_MASK, 0x12);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_PLL_CTRL1, val);
+
+	/* assert PHY reset from isolation register */
+	cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0000);
+	/* assert PMA CMN reset */
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0000);
+
+	/* register XCVR_DIAG_BIDI_CTRL */
+	for (k = 0; k < num_lanes; k++)
+		cdns_phy_reg_write(cdns_phy, XCVR_DIAG_BIDI_CTRL | (k << 9), 0x00ff);
+
+	/* Describing Task phy_cfg_hdp */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_RCV_EN_MASK;
+	val |= FIELD_PREP(CMA_REF_CLK_RCV_EN_MASK, CMA_REF_CLK_RCV_EN);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	/* PHY Registers */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_DIG_DIV_MASK;
+	val |= FIELD_PREP(CMA_REF_CLK_DIG_DIV_MASK, p_ctrl_table->cmn_ref_clk_dig_div);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_DATA_RATE_CLK_DIV_MASK;
+	val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
+			  PLL_DATA_RATE_CLK_DIV_HBR2);
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+
+	/* Common control module control and diagnostic registers */
+	val = cdns_phy_reg_read(cdns_phy, CMN_CDIAG_REFCLK_CTRL);
+	val &= ~DIG_REF_CLK_DIV_SCALER_MASK;
+	val |= FIELD_PREP(DIG_REF_CLK_DIV_SCALER_MASK, p_ctrl_table->ref_clk_divider_scaler);
+	val |= REFCLK_TERMINATION_EN_OVERRIDE_EN | REFCLK_TERMINATION_EN_OVERRIDE;
+	cdns_phy_reg_write(cdns_phy, CMN_CDIAG_REFCLK_CTRL, val);
+
+	/* High speed clock used */
+	val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL);
+	val &= ~(HSCLK1_SEL_MASK | HSCLK0_SEL_MASK);
+	val |= FIELD_PREP(HSCLK1_SEL_MASK, (p_ctrl_table->cmnda_hs_clk_1_sel >> 1));
+	val |= FIELD_PREP(HSCLK0_SEL_MASK, (p_ctrl_table->cmnda_hs_clk_0_sel >> 1));
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val);
+
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+		val &= ~HSCLK_SEL_MODE3_MASK;
+		val |= FIELD_PREP(HSCLK_SEL_MODE3_MASK,
+				  (p_ctrl_table->cmnda_hs_clk_0_sel >> 1));
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val);
+	}
+
+	/* PLL 0 control state machine registers */
+	val = p_ctrl_table->vco_ring_select << 12;
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_USER_DEF_CTRL, val);
+
+	if (pclk_in) {
+		val = 0x30a0;
+	} else {
+		val = cdns_phy_reg_read(cdns_phy, CMN_PLL0_VCOCAL_START);
+		val &= ~VCO_CALIB_CODE_START_POINT_VAL_MASK;
+		val |= FIELD_PREP(VCO_CALIB_CODE_START_POINT_VAL_MASK,
+				  p_pll_table->vco_cal_code);
+	}
+	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_START, val);
+
+	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_INIT_TMR, 0x0064);
+	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_ITER_TMR, 0x000a);
+
+	/* Common functions control and diagnostics registers */
+	val = p_ctrl_table->cmnda_pll0_hs_sym_div_sel << 8;
+	val |= p_ctrl_table->cmnda_pll0_ip_div;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_INCLK_CTRL, val);
+
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_OVRD, 0x0000);
+
+	val = p_ctrl_table->cmnda_pll0_fb_div_high;
+	val |= PLL_FEEDBACK_DIV_HI_OVERRIDE_EN;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBH_OVRD, val);
+
+	val = p_ctrl_table->cmnda_pll0_fb_div_low;
+	val |= PLL_FEEDBACK_DIV_LO_OVERRIDE_EN;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBL_OVRD, val);
+
+	if (!pclk_in) {
+		val = p_ctrl_table->cmnda_pll0_pxdiv_low;
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PXL_DIVL, val);
+
+		val = p_ctrl_table->cmnda_pll0_pxdiv_high;
+		val |= PLL_PCLK_DIV_EN;
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PXL_DIVH, val);
+	}
+
+	val = p_pll_table->volt_to_current_coarse;
+	val |= (p_pll_table->volt_to_current) << 4;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_V2I_TUNE, val);
+
+	val = p_pll_table->charge_pump_gain;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_CP_TUNE, val);
+
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_LF_PROG, 0x0008);
+
+	val = p_pll_table->pmos_ctrl;
+	val |= (p_pll_table->ndac_ctrl) << 8;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE1, val);
+
+	val = p_pll_table->ptat_ndac_ctrl;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE2, val);
+
+	if (pclk_in)
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_TEST_MODE, 0x0022);
+	else
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_TEST_MODE, 0x0020);
+
+	cdns_phy_reg_write(cdns_phy, CMN_PSM_CLK_CTRL, 0x0016);
+
+	/* Transceiver control and diagnostic registers */
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+		val &= ~DPLL_CLK_SEL_MODE3;
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val);
+	}
+
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (TX_DIAG_TX_CTRL | (k << 9)));
+		val &= ~TX_IF_SUBRATE_MODE3_MASK;
+		val |= FIELD_PREP(TX_IF_SUBRATE_MODE3_MASK,
+				  (p_ctrl_table->hsclk_div_tx_sub_rate >> 1));
+		cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_CTRL | (k << 9)), val);
+	}
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_SEL_MASK;
+	/*
+	 * single ended reference clock (val |= 0x0030);
+	 * differential clock  (val |= 0x0000);
+	 * for differential clock on the refclk_p and
+	 * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1
+	 * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100);
+	 */
+	val |= FIELD_PREP(CMA_REF_CLK_SEL_MASK, 3);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	/* Deassert PHY reset */
+	cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0001);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0003);
+
+	/* Power state machine registers */
+	for (k = 0; k < num_lanes; k++)
+		cdns_phy_reg_write(cdns_phy, XCVR_PSM_RCTRL | (k << 9), 0xfefc);
+
+	/* Assert cmn_macro_pwr_en */
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0013);
+
+	/* wait for cmn_macro_pwr_en_ack */
+	ret = wait_for_ack(cdns_phy, PHY_PMA_ISO_CMN_CTRL, CMN_MACRO_PWR_EN_ACK,
+			   "MA output macro power up failed");
+	if (ret < 0)
+		return ret;
+
+	/* wait for cmn_ready */
+	ret = wait_for_ack(cdns_phy, PHY_PMA_CMN_CTRL1, CMN_READY,
+			   "PMA output ready failed");
+	if (ret < 0)
+		return ret;
+
+	for (k = 0; k < num_lanes; k++) {
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A0 | (k << 9), 0x6791);
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A1 | (k << 9), 0x6790);
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A2 | (k << 9), 0x0090);
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A3 | (k << 9), 0x0090);
+
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, RX_PSC_CAL | (k << 9), val);
+
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, RX_PSC_A0 | (k << 9), val);
+	}
+
+	return 0;
+}
+
+static int hdptx_hdmi_phy_cfg(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 rate)
+{
+	const struct hdptx_hdmi_ctrl *p_ctrl_table;
+	const struct hdptx_hdmi_pll_tuning *p_pll_table;
+	const u32 refclk_freq_khz = cdns_phy->ref_clk_rate / 1000;
+	const bool pclk_in = false;
+	u32 pixel_freq = rate;
+	u32 vco_freq, char_freq;
+	u32 div_total, feedback_factor;
+	u32 i;
+
+	feedback_factor = hdptx_hdmi_feedback_factor(cdns_phy);
+
+	char_freq = pixel_freq * feedback_factor / 1000;
+
+	dev_dbg(cdns_phy->dev,
+		"Pixel clock: (%d KHz), character clock: %d, bpc is (%0d-bit)\n",
+		pixel_freq, char_freq, cdns_phy->bpc);
+
+	/* Get right row from the ctrl_table table.
+	 * Check if 'pixel_freq_khz' value matches the PIXEL_CLK_FREQ column.
+	 * Consider only the rows with FEEDBACK_FACTOR column matching feedback_factor.
+	 */
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++) {
+		if (feedback_factor == pixel_clk_output_ctrl_table[i].feedback_factor &&
+		    pixel_freq == pixel_clk_output_ctrl_table[i].pixel_clk_freq_min) {
+			p_ctrl_table = &pixel_clk_output_ctrl_table[i];
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(pixel_clk_output_ctrl_table)) {
+		dev_warn(cdns_phy->dev,
+			 "Pixel clk (%d KHz) not supported, bpc is (%0d-bit)\n",
+			 pixel_freq, cdns_phy->bpc);
+		return -EINVAL;
+	}
+
+	div_total = p_ctrl_table->pll_fb_div_total;
+	vco_freq = refclk_freq_khz * div_total / p_ctrl_table->cmnda_pll0_ip_div;
+
+	/* Get right row from the pixel_clk_output_pll_table table.
+	 * Check if vco_freq_khz and feedback_div_total
+	 * column matching with pixel_clk_output_pll_table.
+	 */
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_pll_table); i++) {
+		if (vco_freq == pixel_clk_output_pll_table[i].vco_freq_min &&
+		    div_total == pixel_clk_output_pll_table[i].feedback_div_total) {
+			p_pll_table = &pixel_clk_output_pll_table[i];
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(pixel_clk_output_pll_table)) {
+		dev_warn(cdns_phy->dev, "VCO (%d KHz) not supported\n", vco_freq);
+		return -EINVAL;
+	}
+	dev_dbg(cdns_phy->dev, "VCO frequency is (%d KHz)\n", vco_freq);
+
+	return hdptx_hdmi_phy_config(cdns_phy, p_ctrl_table, p_pll_table, pclk_in);
+}
+
+static int hdptx_hdmi_phy_power_up(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	int ret = 0;
+
+	/* set Power State to A2 */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2);
+
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1);
+
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2_ACK,
+			   "Wait A2 Ack failed");
+	if (ret < 0)
+		return ret;
+
+	/* Power up ARC */
+	hdptx_hdmi_arc_config(cdns_phy);
+
+	/* Configure PHY in A0 mode (PHY must be in the A0 power
+	 * state in order to transmit data)
+	 */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0);
+
+	return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0_ACK,
+			    "Wait A0 Ack failed");
+}
+
+static int hdptx_hdmi_phy_power_down(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	u32 val;
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL);
+	val &= ~(POWER_STATE_A0 | POWER_STATE_A1 | POWER_STATE_A2 | POWER_STATE_A3);
+	/* PHY_DP_MODE_CTL set to A3 power state */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, val | POWER_STATE_A3);
+
+	return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3_ACK,
+			    "Wait A3 Ack failed");
+}
+
+static int cdns_hdptx_hdmi_phy_on(struct phy *phy)
+{
+	struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
+
+	return hdptx_hdmi_phy_power_up(cdns_phy);
+}
+
+static int cdns_hdptx_hdmi_phy_off(struct phy *phy)
+{
+	struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
+
+	hdptx_hdmi_phy_power_down(cdns_phy);
+	return 0;
+}
+
+static int
+cdns_hdptx_hdmi_phy_valid(struct phy *phy, enum phy_mode mode,
+			  int submode, union phy_configure_opts *opts)
+{
+	u32 rate = opts->hdmi.pixel_clk_rate;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++)
+		if (rate == pixel_clk_output_ctrl_table[i].pixel_clk_freq_min)
+			return 0;
+
+	return -EINVAL;
+}
+
+static int cdns_hdptx_hdmi_phy_init(struct phy *phy)
+{
+	return 0;
+}
+
+static int cdns_hdptx_hdmi_configure(struct phy *phy,
+				     union phy_configure_opts *opts)
+{
+	struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
+	int ret;
+
+	cdns_phy->pixel_clk_rate = opts->hdmi.pixel_clk_rate;
+	cdns_phy->color_space = opts->hdmi.color_space;
+	cdns_phy->bpc = opts->hdmi.bpc;
+
+	/* Check HDMI FW alive before HDMI PHY init */
+	ret = hdptx_phy_check_alive(cdns_phy);
+	if (!ret) {
+		dev_err(cdns_phy->dev, "NO HDMI FW running\n");
+		return -ENXIO;
+	}
+
+	/* Configure PHY */
+	if (hdptx_hdmi_phy_cfg(cdns_phy, cdns_phy->pixel_clk_rate) < 0) {
+		dev_err(cdns_phy->dev, "failed to set phy pclock\n");
+		return -EINVAL;
+	}
+
+	ret = hdptx_hdmi_phy_power_up(cdns_phy);
+	if (ret < 0)
+		return ret;
+
+	hdptx_hdmi_phy_set_vswing(cdns_phy);
+
+	return 0;
+}
+
+static const struct phy_ops cdns_hdptx_hdmi_phy_ops = {
+	.init = cdns_hdptx_hdmi_phy_init,
+	.configure = cdns_hdptx_hdmi_configure,
+	.power_on = cdns_hdptx_hdmi_phy_on,
+	.power_off = cdns_hdptx_hdmi_phy_off,
+	.validate = cdns_hdptx_hdmi_phy_valid,
+	.owner = THIS_MODULE,
+};
+
+static int cdns_hdptx_hdmi_phy_probe(struct platform_device *pdev)
+{
+	struct cdns_hdptx_hdmi_phy *cdns_phy;
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct phy_provider *phy_provider;
+	struct resource *res;
+	struct phy *phy;
+	int ret;
+
+	cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
+	if (!cdns_phy)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, cdns_phy);
+	cdns_phy->dev = dev;
+	mutex_init(&cdns_phy->mbox_mutex);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(cdns_phy->regs))
+		return PTR_ERR(cdns_phy->regs);
+
+	phy = devm_phy_create(dev, node, &cdns_hdptx_hdmi_phy_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	phy->attrs.mode = PHY_MODE_HDMI;
+
+	cdns_phy->phy = phy;
+	phy_set_drvdata(phy, cdns_phy);
+
+	/* init base struct for access mhdp mailbox */
+	cdns_phy->base.dev = cdns_phy->dev;
+	cdns_phy->base.regs = cdns_phy->regs;
+	cdns_phy->base.mbox_mutex = &cdns_phy->mbox_mutex;
+
+	ret = hdptx_hdmi_clk_enable(cdns_phy);
+	if (ret) {
+		dev_err(dev, "Init clk fail\n");
+		return -EINVAL;
+	}
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider)) {
+		ret = PTR_ERR(phy_provider);
+		goto clk_disable;
+	}
+
+	dev_dbg(dev, "probe success!\n");
+
+	return 0;
+
+clk_disable:
+	hdptx_hdmi_clk_disable(cdns_phy);
+
+	return -EINVAL;
+}
+
+static int cdns_hdptx_hdmi_phy_remove(struct platform_device *pdev)
+{
+	struct cdns_hdptx_hdmi_phy *cdns_phy = platform_get_drvdata(pdev);
+
+	hdptx_hdmi_clk_disable(cdns_phy);
+
+	return 0;
+}
+
+static const struct of_device_id cdns_hdptx_hdmi_phy_of_match[] = {
+	{.compatible = "fsl,imx8mq-hdmi-phy" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cdns_hdptx_hdmi_phy_of_match);
+
+static struct platform_driver cdns_hdptx_hdmi_phy_driver = {
+	.probe = cdns_hdptx_hdmi_phy_probe,
+	.remove = cdns_hdptx_hdmi_phy_remove,
+	.driver = {
+		.name	= "cdns-hdptx-hdmi-phy",
+		.of_match_table	= cdns_hdptx_hdmi_phy_of_match,
+	}
+};
+module_platform_driver(cdns_hdptx_hdmi_phy_driver);
+
+MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("Cadence HDP-TX HDMI PHY driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From maz at kernel.org  Sun Feb  4 03:08:45 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 04 Feb 2024 11:08:45 +0000
Subject: [PATCH v2 02/25] KVM: arm64: Add feature checking helpers
In-Reply-To: <f47909b1-5e10-4149-8d2a-330bd0ceb2e0@arm.com>
References: <20240130204533.693853-1-maz@kernel.org>
	<20240130204533.693853-3-maz@kernel.org>
	<f47909b1-5e10-4149-8d2a-330bd0ceb2e0@arm.com>
Message-ID: <87mssgwkoy.wl-maz@kernel.org>

On Fri, 02 Feb 2024 17:13:07 +0000,
Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
> 
> Hi Marc,
> 
> On 30/01/2024 20:45, Marc Zyngier wrote:
> > In order to make it easier to check whether a particular feature
> > is exposed to a guest, add a new set of helpers, with kvm_has_feat()
> > being the most useful.
> > 
> > Let's start making use of them in the PMU code (courtesy of Oliver).
> > Follow-up work will intricude additional use patterns.
> 
> I think there is a bit of inconsistency in the macros for signed
> and unsigned. The unsigned fields are extracted (i.e., as if they
> were shifted to bit 0). But the signed fields are not shifted
> completely to bit '0' (in fact to different positions) and eventually
> we compare wrong things.
> 
> Using ID_AA64PFR0_EL1, fld=EL2, val=IMP for unsigned and
> ID_AA64PFR0_EL1, AdvSIMD, NI for signed.
> 
> > 
> > Co-developed--by: Oliver Upton <oliver.upton at linux.dev>
> > Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >   arch/arm64/include/asm/kvm_host.h | 53 +++++++++++++++++++++++++++++++
> >   arch/arm64/kvm/pmu-emul.c         | 11 ++++---
> >   arch/arm64/kvm/sys_regs.c         |  6 ++--
> >   include/kvm/arm_pmu.h             | 11 -------
> >   4 files changed, 61 insertions(+), 20 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 21c57b812569..c0cf9c5f5e8d 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -1233,4 +1233,57 @@ static inline void kvm_hyp_reserve(void) { }
> >   void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
> >   bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
> >   +#define __expand_field_sign_unsigned(id, fld, val)
> > \
> > +	((u64)(id##_##fld##_##val))
> 
> For unsigned features we get the actual "field" value, not the value
> in position. e.g,: ID_AA64PFR0_EL1_EL2_IMP = (0x1)
> 
> > +
> > +#define __expand_field_sign_signed(id, fld, val)			\
> > +	({								\
> > +		s64 __val = id##_##fld##_##val;				\
> > +		__val <<= 64 - id##_##fld##_WIDTH;			\
> > +		__val >>= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
> 
> But for signed fields, we shift them back into the "position" as in
> the ID_REG. e.g.,
> 
> ID_AA64PFR0_EL1, AdvSIMD, NI we get:
> 
> 	__val = ID_AA64PFR0_EL1_AdvSIMD_NI; /* = 0xf */
> 	__val <<= 64 - 4;		/* 0xf0_00_00_00_00_00_00_00 */
> 	__val >>= 64 - 20 - 4;		/* 0xff_ff_ff_ff_ff_f0_00_00 */
> 
> I think the last line instead should be:
> 	__val >>= 64 - id##_##fld##_WIDTH;

Huh, you're absolutely right.

> 
> > +									\
> > +		__val;							\
> > +	})
> > +
> > +#define expand_field_sign(id, fld, val)					\
> > +	(id##_##fld##_SIGNED ?						\
> > +	 __expand_field_sign_signed(id, fld, val) :			\
> > +	 __expand_field_sign_unsigned(id, fld, val))
> > +
> > +#define get_idreg_field_unsigned(kvm, id, fld)				\
> > +	({								\
> > +		u64 __val = IDREG(kvm, SYS_##id);			\
> > +		__val &= id##_##fld##_MASK;				\
> > +		__val >>= id##_##fld##_SHIFT;				\
> > +									\
> 
> We extract the field value for unsigned field, i.e., shifted to bit"0"
> and that matches the expand_field_sign().
> 
> > +		__val;							\
> > +	})
> > +
> > +#define get_idreg_field_signed(kvm, id, fld)				\
> > +	({								\
> > +		s64 __val = IDREG(kvm, SYS_##id);			\
> > +		__val <<= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
> > +		__val >>= id##_##fld##_SHIFT;				\
> 
> However, here we get (assuming value ID_AA64PFR0_EL1_ASIMD = 0xf, and
> all other fields are 0 for clarity)
> 	
> 	__val = IDREG(kvm, SYS_ID_AA64PFR0_EL1); = 0xf0_00_00; 	/* 0xf << 20 */
> 	__val <<= 64 - 20 - 4;	/* = 0xf0_00_00_00_00_00_00_00 */
> 	__val >>= 20;		/* = 0xff_ff_ff_00_00_00_00_00 */

Gah... again!

>
> Thus they don;t match. Instead the last line should be :
> 
> 	__val >>= id##_##fld##_WIDTH;

Shouldn't this be (64 - WIDTH) instead, since we want the value to be
shifted to bit 0? Otherwise, you get 0xff_00_00_00_00_00_00_00 (as per
your example).

Thanks a lot for spotting those, much appreciated.

	M.

-- 
Without deviation from the norm, progress is not possible.


From heiko at sntech.de  Sun Feb  4 03:17:06 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun,  4 Feb 2024 12:17:06 +0100
Subject: [PATCH] arm64: dts: rockchip: drop unneeded status from rk3588-jaguar gpio-leds
In-Reply-To: <20240129114851.2019861-1-heiko@sntech.de>
References: <20240129114851.2019861-1-heiko@sntech.de>
Message-ID: <170704542197.2517832.3939294124436389366.b4-ty@sntech.de>

On Mon, 29 Jan 2024 12:48:51 +0100, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> The default status is okay, so it is definitly not necessary to set
> it on a newly added node.
> 
> 

Applied, thanks!

[1/1] arm64: dts: rockchip: drop unneeded status from rk3588-jaguar gpio-leds
      commit: bab7ec1d80fe5998ce5ab4480f15e7cce43e2cdf

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Sun Feb  4 03:17:09 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun,  4 Feb 2024 12:17:09 +0100
Subject: [PATCH] ARM: dts: rockchip: Drop interrupts property from pwm-rockchip nodes
In-Reply-To: <20240129113205.2453029-2-u.kleine-koenig@pengutronix.de>
References: <20240129113205.2453029-2-u.kleine-koenig@pengutronix.de>
Message-ID: <170704542195.2517832.659994399742833718.b4-ty@sntech.de>

On Mon, 29 Jan 2024 12:32:02 +0100, Uwe Kleine-K?nig wrote:
> The binding doesn't define interrupts and adding such a definition was
> refused because it's unclear how they should ever be used and the
> relevant registers are outside the PWM range. So drop them fixing
> several dtbs_check warnings like:
> 
> 	arch/arm/boot/dts/rockchip/rv1108-elgin-r1.dtb: pwm at 10280030: 'interrupts' does not match any of the regexes: 'pinctrl-[0-9]+'
> 	from schema $id: http://devicetree.org/schemas/pwm/pwm-rockchip.yaml#
> 
> [...]

Applied, thanks!

[1/1] ARM: dts: rockchip: Drop interrupts property from pwm-rockchip nodes
      commit: f98643d8daf3443e3b414a82d0cb3d745f8c8bbc

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Sun Feb  4 03:17:05 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun,  4 Feb 2024 12:17:05 +0100
Subject: [PATCH v2 1/4] arm64: dts: rockchip: aliase sdmmc as mmc1 for Cool Pi 4B
In-Reply-To: <20240201121106.1471301-1-andyshrk@163.com>
References: <20240201121106.1471301-1-andyshrk@163.com>
Message-ID: <170704542189.2517832.10645480852416416649.b4-ty@sntech.de>

On Thu, 1 Feb 2024 20:11:03 +0800, Andy Yan wrote:
> Follow others rk3588 based boards, and u-boot only use mmc0/1
> as mmc boot targets, so aliase sdmmc as mmc1.
> 
> 

Applied, thanks!

[1/4] arm64: dts: rockchip: aliase sdmmc as mmc1 for Cool Pi 4B
      commit: a41f91b4da1490b90ae5859f3464e94d418fea2c
[2/4] arm64: dts: rockchip: aliase sdmmc as mmc1 for Cool Pi CM5 EVB
      commit: cebda3dd36bebb11d3e6df4d1944a1cdcf3cd4cf
[3/4] arm64: dts: rockchip: rename vcc5v0_usb30_host regulator for Cool Pi CM5 EVB
      commit: c7e8dbb3bc12f389d617e6c0e9537f11a1fa6eb1
[4/4] arm64: dts: rockchip: Fix the num-lanes of pcie3x4 on Cool Pi CM5 EVB
      commit: 5556a8c3af8b4ee648b0fd4cdb4a1356d92de07b

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Sun Feb  4 03:17:08 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun,  4 Feb 2024 12:17:08 +0100
Subject: (subset) [PATCH v4 0/4] arm64: rockchip: Pine64 PineTab2 support
In-Reply-To: <20240127-pinetab2-v4-0-37aab1c39194@mecka.net>
References: <20240127-pinetab2-v4-0-37aab1c39194@mecka.net>
Message-ID: <170704542194.2517832.14847139781169519437.b4-ty@sntech.de>

On Sat, 27 Jan 2024 10:48:41 +0100, Manuel Traut wrote:
> This adds support for the BOE TH101MB31IG002 LCD Panel used in PineTab2 [1] and
> PineTab-V [2] as well as the devictrees for the PineTab2 v0.1 and v2.0.
> 
> The BOE LCD Panel patch was retrieved from [3]. The function-name prefix has
> been adapted and the LCD init section was simplified.
> 
> The PineTab2 devicetree patch was retrieved from [4]. Some renaming was needed
> to pass the dtb-checks, the brightness-levels are specified as range and steps
> instead of a list of values.
> 
> [...]

Applied, thanks!

[3/4] dt-bindings: arm64: rockchip: Add Pine64 PineTab2
      commit: 6a0a5a2a71b3e3c4ae1ee0b34a496cbf2d980832
[4/4] arm64: dts: rockchip: Add devicetree for Pine64 PineTab2
      commit: 1b7e19448f8fbeee23111795f67a003431c40b27

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From danct12 at riseup.net  Sun Feb  4 03:21:05 2024
From: danct12 at riseup.net (Dang Huynh)
Date: Sun, 04 Feb 2024 11:21:05 +0000
Subject: [PATCH v4 4/4] arm64: dts: rockchip: Add devicetree for Pine64 PineTab2
In-Reply-To: <20240127-pinetab2-v4-4-37aab1c39194@mecka.net>
References: <20240127-pinetab2-v4-0-37aab1c39194@mecka.net>
 <20240127-pinetab2-v4-4-37aab1c39194@mecka.net>
Message-ID: <2724385.mvXUDI8C0e@melttower>

Tested-by: Dang Huynh <danct12 at riseup.net>

On Saturday, January 27, 2024 9:48:45 AM UTC Manuel Traut wrote:
> This includes support for both the v0.1 units that were sent to developers
> and the v2.0 units from production.




From maz at kernel.org  Sun Feb  4 03:44:58 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 04 Feb 2024 11:44:58 +0000
Subject: [PATCH v2 02/25] KVM: arm64: Add feature checking helpers
In-Reply-To: <87mssgwkoy.wl-maz@kernel.org>
References: <20240130204533.693853-1-maz@kernel.org>
	<20240130204533.693853-3-maz@kernel.org>
	<f47909b1-5e10-4149-8d2a-330bd0ceb2e0@arm.com>
	<87mssgwkoy.wl-maz@kernel.org>
Message-ID: <87le80wj0l.wl-maz@kernel.org>

On Sun, 04 Feb 2024 11:08:45 +0000,
Marc Zyngier <maz at kernel.org> wrote:
> 
> On Fri, 02 Feb 2024 17:13:07 +0000,
> Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
> > 
> > Hi Marc,
> > 
> > On 30/01/2024 20:45, Marc Zyngier wrote:
> > > In order to make it easier to check whether a particular feature
> > > is exposed to a guest, add a new set of helpers, with kvm_has_feat()
> > > being the most useful.
> > > 
> > > Let's start making use of them in the PMU code (courtesy of Oliver).
> > > Follow-up work will intricude additional use patterns.
> > 
> > I think there is a bit of inconsistency in the macros for signed
> > and unsigned. The unsigned fields are extracted (i.e., as if they
> > were shifted to bit 0). But the signed fields are not shifted
> > completely to bit '0' (in fact to different positions) and eventually
> > we compare wrong things.
> > 
> > Using ID_AA64PFR0_EL1, fld=EL2, val=IMP for unsigned and
> > ID_AA64PFR0_EL1, AdvSIMD, NI for signed.
> > 
> > > 
> > > Co-developed--by: Oliver Upton <oliver.upton at linux.dev>
> > > Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > ---
> > >   arch/arm64/include/asm/kvm_host.h | 53 +++++++++++++++++++++++++++++++
> > >   arch/arm64/kvm/pmu-emul.c         | 11 ++++---
> > >   arch/arm64/kvm/sys_regs.c         |  6 ++--
> > >   include/kvm/arm_pmu.h             | 11 -------
> > >   4 files changed, 61 insertions(+), 20 deletions(-)
> > > 
> > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > > index 21c57b812569..c0cf9c5f5e8d 100644
> > > --- a/arch/arm64/include/asm/kvm_host.h
> > > +++ b/arch/arm64/include/asm/kvm_host.h
> > > @@ -1233,4 +1233,57 @@ static inline void kvm_hyp_reserve(void) { }
> > >   void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
> > >   bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
> > >   +#define __expand_field_sign_unsigned(id, fld, val)
> > > \
> > > +	((u64)(id##_##fld##_##val))
> > 
> > For unsigned features we get the actual "field" value, not the value
> > in position. e.g,: ID_AA64PFR0_EL1_EL2_IMP = (0x1)
> > 
> > > +
> > > +#define __expand_field_sign_signed(id, fld, val)			\
> > > +	({								\
> > > +		s64 __val = id##_##fld##_##val;				\
> > > +		__val <<= 64 - id##_##fld##_WIDTH;			\
> > > +		__val >>= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
> > 
> > But for signed fields, we shift them back into the "position" as in
> > the ID_REG. e.g.,
> > 
> > ID_AA64PFR0_EL1, AdvSIMD, NI we get:
> > 
> > 	__val = ID_AA64PFR0_EL1_AdvSIMD_NI; /* = 0xf */
> > 	__val <<= 64 - 4;		/* 0xf0_00_00_00_00_00_00_00 */
> > 	__val >>= 64 - 20 - 4;		/* 0xff_ff_ff_ff_ff_f0_00_00 */
> > 
> > I think the last line instead should be:
> > 	__val >>= 64 - id##_##fld##_WIDTH;
> 
> Huh, you're absolutely right.
> 
> > 
> > > +									\
> > > +		__val;							\
> > > +	})
> > > +
> > > +#define expand_field_sign(id, fld, val)					\
> > > +	(id##_##fld##_SIGNED ?						\
> > > +	 __expand_field_sign_signed(id, fld, val) :			\
> > > +	 __expand_field_sign_unsigned(id, fld, val))
> > > +
> > > +#define get_idreg_field_unsigned(kvm, id, fld)				\
> > > +	({								\
> > > +		u64 __val = IDREG(kvm, SYS_##id);			\
> > > +		__val &= id##_##fld##_MASK;				\
> > > +		__val >>= id##_##fld##_SHIFT;				\
> > > +									\
> > 
> > We extract the field value for unsigned field, i.e., shifted to bit"0"
> > and that matches the expand_field_sign().
> > 
> > > +		__val;							\
> > > +	})
> > > +
> > > +#define get_idreg_field_signed(kvm, id, fld)				\
> > > +	({								\
> > > +		s64 __val = IDREG(kvm, SYS_##id);			\
> > > +		__val <<= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
> > > +		__val >>= id##_##fld##_SHIFT;				\
> > 
> > However, here we get (assuming value ID_AA64PFR0_EL1_ASIMD = 0xf, and
> > all other fields are 0 for clarity)
> > 	
> > 	__val = IDREG(kvm, SYS_ID_AA64PFR0_EL1); = 0xf0_00_00; 	/* 0xf << 20 */
> > 	__val <<= 64 - 20 - 4;	/* = 0xf0_00_00_00_00_00_00_00 */
> > 	__val >>= 20;		/* = 0xff_ff_ff_00_00_00_00_00 */
> 
> Gah... again!
> 
> >
> > Thus they don;t match. Instead the last line should be :
> > 
> > 	__val >>= id##_##fld##_WIDTH;
> 
> Shouldn't this be (64 - WIDTH) instead, since we want the value to be
> shifted to bit 0? Otherwise, you get 0xff_00_00_00_00_00_00_00 (as per
> your example).
> 
> Thanks a lot for spotting those, much appreciated.

And since it is now obvious to anyone that I can't shift properly,
let's just not do that. As it turns out, the kernel already has the
required macros, and I can stop being clever with these:

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index ea8acc1914aa..3457fa313bad 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1290,11 +1290,8 @@ bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
 
 #define __expand_field_sign_signed(id, fld, val)			\
 	({								\
-		s64 __val = id##_##fld##_##val;				\
-		__val <<= 64 - id##_##fld##_WIDTH;			\
-		__val >>= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
-									\
-		__val;							\
+		u64 __val = id##_##fld##_##val;				\
+		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
 	})
 
 #define expand_field_sign(id, fld, val)					\
@@ -1313,11 +1310,9 @@ bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
 
 #define get_idreg_field_signed(kvm, id, fld)				\
 	({								\
-		s64 __val = IDREG(kvm, SYS_##id);			\
-		__val <<= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
-		__val >>= id##_##fld##_SHIFT;				\
-									\
-		__val;							\
+		u64 __val = IDREG(kvm, SYS_##id);			\
+		__val = FIELD_GET(id##_##fld##_MASK, __val);		\
+		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
 	})
 
 #define get_idreg_field_enum(kvm, id, fld)				\

Thoughts?

	M.

-- 
Without deviation from the norm, progress is not possible.


From francesco at dolcini.it  Sun Feb  4 04:00:33 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Sun, 4 Feb 2024 13:00:33 +0100
Subject: [PATCH V8 06/12] arm64: dts: imx8mp: add HDMI irqsteer
In-Reply-To: <20240203165307.7806-7-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-7-aford173@gmail.com>
Message-ID: <20240204120033.GA4656@francesco-nb>

On Sat, Feb 03, 2024 at 10:52:46AM -0600, Adam Ford wrote:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> The HDMI irqsteer is a secondary interrupt controller within the HDMI
> subsystem that maps all HDMI peripheral IRQs into a single upstream
> IRQ line.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

This is missing your signed-off-by, and in other patches of this series
your signed-off-by is not the last, as it should be.

Please have a look and fix this and the other instances.

Thanks for this work!

Francesco



From linux at armlinux.org.uk  Sun Feb  4 04:02:28 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 4 Feb 2024 12:02:28 +0000
Subject: [PATCH net-next 4/6] net: bcmgenet: remove
 eee_enabled/eee_active in bcmgenet_get_eee()
In-Reply-To: <4586d004-a7b7-4e60-9493-0a1bbe7d79ba@broadcom.com>
References: <Zby24IKSgzpvRDNF@shell.armlinux.org.uk>
 <E1rVpvs-002Pe6-1w@rmk-PC.armlinux.org.uk>
 <e04888df-adba-49fc-b7f3-3b930e80af81@broadcom.com>
 <4586d004-a7b7-4e60-9493-0a1bbe7d79ba@broadcom.com>
Message-ID: <Zb981J0wwFYhXPEo@shell.armlinux.org.uk>

On Fri, Feb 02, 2024 at 05:21:57PM -0800, Florian Fainelli wrote:
> 
> 
> On 2/2/2024 5:17 PM, Florian Fainelli wrote:
> > 
> > 
> > On 2/2/2024 1:34 AM, Russell King (Oracle) wrote:
> > > bcmgenet_get_eee() sets edata->eee_active and edata->eee_enabled from
> > > its own copy, and then calls phy_ethtool_get_eee() which in turn will
> > > call genphy_c45_ethtool_get_eee().
> > > 
> > > genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> > > with its own interpretation from the PHYs settings and negotiation
> > > result.
> > > 
> > > Therefore, setting these members in bcmgenet_get_eee() is redundant,
> > > and can be removed. This also makes priv->eee.eee_active unnecessary,
> > > so remove this and use a local variable where appropriate.
> > > 
> > > Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> > 
> > Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
> > 
> > Is not there an opportunity for no longer overriding eee_enabled as well
> > since genphy_c45_ethtool_get_eee() will set that variable too?
> 
> Scratch that comment, you are doing it in the getter.

Also, priv->eee.eee_enabled is used in bcmmii.c, so we can't get rid of
it in the setter.

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


From linux at armlinux.org.uk  Sun Feb  4 04:12:43 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 4 Feb 2024 12:12:43 +0000
Subject: [PATCH net-next v2 0/6] net: eee network driver cleanups
Message-ID: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>

Hi,

Since commit d1420bb99515 ("net: phy: improve generic EEE ethtool
functions") changed phylib to set eee->eee_active and eee->eee_enabled,
overriding anything that drivers have set these to prior to calling
phy_ethtool_get_eee().

Therefore, drivers setting these members becomes redundant, since
phylib overwrites the values they set. This series finishes off
Heiner's work in the referenced commit by removing these redundant
writes in various drivers and any associated code or structure members
that become unnecessary.

v2: Address Andrew's comment on fec_main.c

 drivers/net/dsa/b53/b53_common.c                     | 6 ------
 drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c  | 4 ----
 drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c     | 5 +++--
 drivers/net/ethernet/broadcom/genet/bcmgenet.c       | 8 +++-----
 drivers/net/ethernet/broadcom/genet/bcmmii.c         | 5 +++--
 drivers/net/ethernet/freescale/fec_main.c            | 4 ----
 drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h    | 1 -
 drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c   | 2 --
 drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c      | 1 -
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 --
 10 files changed, 9 insertions(+), 29 deletions(-)
-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


From rmk+kernel at armlinux.org.uk  Sun Feb  4 04:13:07 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 04 Feb 2024 12:13:07 +0000
Subject: [PATCH net-next v2 2/6] net: sxgbe: remove eee_enabled/eee_active in
 sxgbe_get_eee()
In-Reply-To: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
Message-ID: <E1rWbMx-002cCb-IU@rmk-PC.armlinux.org.uk>

sxgbe_get_eee() sets edata->eee_active and edata->eee_enabled from its
own copy, and then calls phy_ethtool_get_eee() which in turn will call
genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Therefore, setting these members in sxgbe_get_eee() is redundant.
Remove this, and remove the priv->eee_active member which then becomes
a write-only variable.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h  | 1 -
 drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c | 2 --
 drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c    | 1 -
 3 files changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h
index d14e0cfc3a6b..1458939c3bf5 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h
@@ -503,7 +503,6 @@ struct sxgbe_priv_data {
 	bool tx_path_in_lpi_mode;
 	int lpi_irq;
 	int eee_enabled;
-	int eee_active;
 	int tx_lpi_timer;
 };
 
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
index d93b628b7046..4a439b34114d 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
@@ -140,8 +140,6 @@ static int sxgbe_get_eee(struct net_device *dev,
 	if (!priv->hw_cap.eee)
 		return -EOPNOTSUPP;
 
-	edata->eee_enabled = priv->eee_enabled;
-	edata->eee_active = priv->eee_active;
 	edata->tx_lpi_timer = priv->tx_lpi_timer;
 
 	return phy_ethtool_get_eee(dev->phydev, edata);
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 71439825ea4e..ecbe3994f2b1 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -130,7 +130,6 @@ bool sxgbe_eee_init(struct sxgbe_priv_data * const priv)
 		if (phy_init_eee(ndev->phydev, true))
 			return false;
 
-		priv->eee_active = 1;
 		timer_setup(&priv->eee_ctrl_timer, sxgbe_eee_ctrl_timer, 0);
 		priv->eee_ctrl_timer.expires = SXGBE_LPI_TIMER(eee_timer);
 		add_timer(&priv->eee_ctrl_timer);
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Sun Feb  4 04:13:12 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 04 Feb 2024 12:13:12 +0000
Subject: [PATCH net-next v2 3/6] net: fec: remove eee_enabled/eee_active in
 fec_enet_get_eee()
In-Reply-To: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
Message-ID: <E1rWbN2-002cCh-MY@rmk-PC.armlinux.org.uk>

fec_enet_get_eee() sets edata->eee_active and edata->eee_enabled from
its own copy, and then calls phy_ethtool_get_eee() which in turn will
call genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Therefore, setting these members in fec_enet_get_eee() is redundant.
Remove this, and remove the setting of fep->eee.eee_active member which
becomes a write-only variable.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/freescale/fec_main.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 63707e065141..42bdc01a304e 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -3139,8 +3139,6 @@ static int fec_enet_eee_mode_set(struct net_device *ndev, bool enable)
 	}
 
 	p->tx_lpi_enabled = enable;
-	p->eee_enabled = enable;
-	p->eee_active = enable;
 
 	writel(sleep_cycle, fep->hwp + FEC_LPI_SLEEP);
 	writel(wake_cycle, fep->hwp + FEC_LPI_WAKE);
@@ -3160,8 +3158,6 @@ fec_enet_get_eee(struct net_device *ndev, struct ethtool_keee *edata)
 	if (!netif_running(ndev))
 		return -ENETDOWN;
 
-	edata->eee_enabled = p->eee_enabled;
-	edata->eee_active = p->eee_active;
 	edata->tx_lpi_timer = p->tx_lpi_timer;
 	edata->tx_lpi_enabled = p->tx_lpi_enabled;
 
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Sun Feb  4 04:13:17 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 04 Feb 2024 12:13:17 +0000
Subject: [PATCH net-next v2 4/6] net: bcmgenet: remove eee_enabled/eee_active
 in bcmgenet_get_eee()
In-Reply-To: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
Message-ID: <E1rWbN7-002cCn-RO@rmk-PC.armlinux.org.uk>

bcmgenet_get_eee() sets edata->eee_active and edata->eee_enabled from
its own copy, and then calls phy_ethtool_get_eee() which in turn will
call genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Therefore, setting these members in bcmgenet_get_eee() is redundant,
and can be removed. This also makes priv->eee.eee_active unnecessary,
so remove this and use a local variable where appropriate.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 8 +++-----
 drivers/net/ethernet/broadcom/genet/bcmmii.c   | 5 +++--
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 051c31fb17c2..7396e2823e32 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1313,7 +1313,6 @@ void bcmgenet_eee_enable_set(struct net_device *dev, bool enable,
 	}
 
 	priv->eee.eee_enabled = enable;
-	priv->eee.eee_active = enable;
 	priv->eee.tx_lpi_enabled = tx_lpi_enabled;
 }
 
@@ -1328,8 +1327,6 @@ static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_keee *e)
 	if (!dev->phydev)
 		return -ENODEV;
 
-	e->eee_enabled = p->eee_enabled;
-	e->eee_active = p->eee_active;
 	e->tx_lpi_enabled = p->tx_lpi_enabled;
 	e->tx_lpi_timer = bcmgenet_umac_readl(priv, UMAC_EEE_LPI_TIMER);
 
@@ -1340,6 +1337,7 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_keee *e)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 	struct ethtool_keee *p = &priv->eee;
+	bool active;
 
 	if (GENET_IS_V1(priv))
 		return -EOPNOTSUPP;
@@ -1352,9 +1350,9 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_keee *e)
 	if (!p->eee_enabled) {
 		bcmgenet_eee_enable_set(dev, false, false);
 	} else {
-		p->eee_active = phy_init_eee(dev->phydev, false) >= 0;
+		active = phy_init_eee(dev->phydev, false) >= 0;
 		bcmgenet_umac_writel(priv, e->tx_lpi_timer, UMAC_EEE_LPI_TIMER);
-		bcmgenet_eee_enable_set(dev, p->eee_active, e->tx_lpi_enabled);
+		bcmgenet_eee_enable_set(dev, active, e->tx_lpi_enabled);
 	}
 
 	return phy_ethtool_set_eee(dev->phydev, e);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index 97ea76d443ab..cbbe004621bc 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -30,6 +30,7 @@ static void bcmgenet_mac_config(struct net_device *dev)
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 	struct phy_device *phydev = dev->phydev;
 	u32 reg, cmd_bits = 0;
+	bool active;
 
 	/* speed */
 	if (phydev->speed == SPEED_1000)
@@ -88,9 +89,9 @@ static void bcmgenet_mac_config(struct net_device *dev)
 	}
 	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
 
-	priv->eee.eee_active = phy_init_eee(phydev, 0) >= 0;
+	active = phy_init_eee(phydev, 0) >= 0;
 	bcmgenet_eee_enable_set(dev,
-				priv->eee.eee_enabled && priv->eee.eee_active,
+				priv->eee.eee_enabled && active,
 				priv->eee.tx_lpi_enabled);
 }
 
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Sun Feb  4 04:13:22 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 04 Feb 2024 12:13:22 +0000
Subject: [PATCH net-next v2 5/6] net: bcmasp: remove eee_enabled/eee_active in
 bcmasp_get_eee()
In-Reply-To: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
Message-ID: <E1rWbNC-002cCt-W7@rmk-PC.armlinux.org.uk>

bcmasp_get_eee() sets edata->eee_active and edata->eee_enabled from
its own copy, and then calls phy_ethtool_get_eee() which in turn will
call genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Therefore, setting these members in bcmasp_get_eee() is redundant, and
can be removed. This also makes intf->eee.eee_active unnecessary, so
remove this and use a local variable where appropriate.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c | 4 ----
 drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c    | 5 +++--
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
index 2851bed153e6..484fc2b5626f 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
@@ -360,7 +360,6 @@ void bcmasp_eee_enable_set(struct bcmasp_intf *intf, bool enable)
 	umac_wl(intf, reg, UMC_EEE_CTRL);
 
 	intf->eee.eee_enabled = enable;
-	intf->eee.eee_active = enable;
 }
 
 static int bcmasp_get_eee(struct net_device *dev, struct ethtool_keee *e)
@@ -371,8 +370,6 @@ static int bcmasp_get_eee(struct net_device *dev, struct ethtool_keee *e)
 	if (!dev->phydev)
 		return -ENODEV;
 
-	e->eee_enabled = p->eee_enabled;
-	e->eee_active = p->eee_active;
 	e->tx_lpi_enabled = p->tx_lpi_enabled;
 	e->tx_lpi_timer = umac_rl(intf, UMC_EEE_LPI_TIMER);
 
@@ -399,7 +396,6 @@ static int bcmasp_set_eee(struct net_device *dev, struct ethtool_keee *e)
 		}
 
 		umac_wl(intf, e->tx_lpi_timer, UMC_EEE_LPI_TIMER);
-		intf->eee.eee_active = ret >= 0;
 		intf->eee.tx_lpi_enabled = e->tx_lpi_enabled;
 		bcmasp_eee_enable_set(intf, true);
 	}
diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
index 53e542881255..3a15f269c7d1 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
@@ -607,6 +607,7 @@ static void bcmasp_adj_link(struct net_device *dev)
 	struct phy_device *phydev = dev->phydev;
 	u32 cmd_bits = 0, reg;
 	int changed = 0;
+	bool active;
 
 	if (intf->old_link != phydev->link) {
 		changed = 1;
@@ -658,8 +659,8 @@ static void bcmasp_adj_link(struct net_device *dev)
 		reg |= cmd_bits;
 		umac_wl(intf, reg, UMC_CMD);
 
-		intf->eee.eee_active = phy_init_eee(phydev, 0) >= 0;
-		bcmasp_eee_enable_set(intf, intf->eee.eee_active);
+		active = phy_init_eee(phydev, 0) >= 0;
+		bcmasp_eee_enable_set(intf, active);
 	}
 
 	reg = rgmii_rl(intf, RGMII_OOB_CNTRL);
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Sun Feb  4 04:13:28 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 04 Feb 2024 12:13:28 +0000
Subject: [PATCH net-next v2 6/6] net: dsa: b53: remove eee_enabled/eee_active
 in b53_get_mac_eee()
In-Reply-To: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
Message-ID: <E1rWbNI-002cCz-4x@rmk-PC.armlinux.org.uk>

b53_get_mac_eee() sets both eee_enabled and eee_active, and then
returns zero.

dsa_slave_get_eee(), which calls this function, will then continue to
call phylink_ethtool_get_eee(), which will return -EOPNOTSUPP if there
is no PHY present, otherwise calling phy_ethtool_get_eee() which in
turn will call genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Thus, when there is no PHY, dsa_slave_get_eee() will fail with
-EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
userspace. When there is a PHY, eee_enabled and eee_active will be
overwritten by phylib, making the setting of these members in
b53_get_mac_eee() entirely unnecessary.

Remove this code, thus simplifying b53_get_mac_eee().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/dsa/b53/b53_common.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index adc93abf4551..9e4c9bd6abcc 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -2227,16 +2227,10 @@ EXPORT_SYMBOL(b53_eee_init);
 int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e)
 {
 	struct b53_device *dev = ds->priv;
-	struct ethtool_keee *p = &dev->ports[port].eee;
-	u16 reg;
 
 	if (is5325(dev) || is5365(dev))
 		return -EOPNOTSUPP;
 
-	b53_read16(dev, B53_EEE_PAGE, B53_EEE_LPI_INDICATE, &reg);
-	e->eee_enabled = p->eee_enabled;
-	e->eee_active = !!(reg & BIT(port));
-
 	return 0;
 }
 EXPORT_SYMBOL(b53_get_mac_eee);
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Sun Feb  4 04:13:02 2024
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 04 Feb 2024 12:13:02 +0000
Subject: [PATCH net-next v2 1/6] net: stmmac: remove eee_enabled/eee_active in
 stmmac_ethtool_op_get_eee()
In-Reply-To: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
Message-ID: <E1rWbMs-002cCV-EE@rmk-PC.armlinux.org.uk>

stmmac_ethtool_op_get_eee() sets both eee_enabled and eee_active, and
then goes on to call phylink_ethtool_get_eee().

phylink_ethtool_get_eee() will return -EOPNOTSUPP if there is no PHY
present, otherwise calling phy_ethtool_get_eee() which in turn will call
genphy_c45_ethtool_get_eee().

genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
with its own interpretation from the PHYs settings and negotiation
result.

Thus, when there is no PHY, stmmac_ethtool_op_get_eee() will fail with
-EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
userspace. When there is a PHY, eee_enabled and eee_active will be
overwritten by phylib, making the setting of these members in
stmmac_ethtool_op_get_eee() entirely unnecessary.

Remove this code, thus simplifying stmmac_ethtool_op_get_eee().

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index bbecb3b89535..411c3ac8cb17 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -859,8 +859,6 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev,
 	if (!priv->dma_cap.eee)
 		return -EOPNOTSUPP;
 
-	edata->eee_enabled = priv->eee_enabled;
-	edata->eee_active = priv->eee_active;
 	edata->tx_lpi_timer = priv->tx_lpi_timer;
 	edata->tx_lpi_enabled = priv->tx_lpi_enabled;
 
-- 
2.30.2



From masahiroy at kernel.org  Sun Feb  4 04:57:16 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Sun,  4 Feb 2024 21:57:16 +0900
Subject: [PATCH] arm: omap1: remove duplicated 'select ARCH_OMAP'
Message-ID: <20240204125716.56756-1-masahiroy@kernel.org>

Commit 980a637d11fe ("ARM: omap1: fix !ARCH_OMAP1_ANY link failures")
added one more 'select ARCH_OMAP'.

Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
---

 arch/arm/mach-omap1/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index cbf703f0d850..a643b71e30a3 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -4,7 +4,6 @@ menuconfig ARCH_OMAP1
 	depends on ARCH_MULTI_V4T || ARCH_MULTI_V5
 	depends on CPU_LITTLE_ENDIAN
 	depends on ATAGS
-	select ARCH_OMAP
 	select ARCH_HAS_HOLES_MEMORYMODEL
 	select ARCH_OMAP
 	select CLKSRC_MMIO
-- 
2.40.1



From maz at kernel.org  Sun Feb  4 05:09:35 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun,  4 Feb 2024 13:09:35 +0000
Subject: [PATCH] KVM: arm64: do not source virt/lib/Kconfig twice
In-Reply-To: <20240204074305.31492-1-masahiroy@kernel.org>
References: <20240204074305.31492-1-masahiroy@kernel.org>
Message-ID: <170705216023.856444.15648014100978026603.b4-ty@kernel.org>

On Sun, 4 Feb 2024 16:43:05 +0900, Masahiro Yamada wrote:
> For ARCH=arm64, virt/lib/Kconfig is sourced twice,
> from arch/arm64/kvm/Kconfig and from drivers/vfio/Kconfig.
> There is no good reason to parse virt/lib/Kconfig twice.
> 
> Commit 2412405b3141 ("KVM: arm/arm64: register irq bypass consumer
> on ARM/ARM64") should not have added this 'source' directive.

Applied to fixes, thanks!

[1/1] KVM: arm64: do not source virt/lib/Kconfig twice
      commit: 42dfa94d802a48c871e2017cbf86153270c86632

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From masahiroy at kernel.org  Sun Feb  4 05:18:53 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Sun, 4 Feb 2024 22:18:53 +0900
Subject: [PATCH] arm: omap1: remove duplicated 'select ARCH_OMAP'
In-Reply-To: <20240204125716.56756-1-masahiroy@kernel.org>
References: <20240204125716.56756-1-masahiroy@kernel.org>
Message-ID: <CAK7LNASC4xh5WrEaHkqFg49xzJsQMQnjLV8sCea8uceNp5EUdQ@mail.gmail.com>

Just a nit.

The commit subject "arm:" should be capitalized to "ARM:"
because it is a convention for changes under arch/arm/.

Maybe, the maintainer can cater to it?


On Sun, Feb 4, 2024 at 9:57?PM Masahiro Yamada <masahiroy at kernel.org> wrote:
>
> Commit 980a637d11fe ("ARM: omap1: fix !ARCH_OMAP1_ANY link failures")
> added one more 'select ARCH_OMAP'.
>
> Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
> ---
>
>  arch/arm/mach-omap1/Kconfig | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
> index cbf703f0d850..a643b71e30a3 100644
> --- a/arch/arm/mach-omap1/Kconfig
> +++ b/arch/arm/mach-omap1/Kconfig
> @@ -4,7 +4,6 @@ menuconfig ARCH_OMAP1
>         depends on ARCH_MULTI_V4T || ARCH_MULTI_V5
>         depends on CPU_LITTLE_ENDIAN
>         depends on ATAGS
> -       select ARCH_OMAP
>         select ARCH_HAS_HOLES_MEMORYMODEL
>         select ARCH_OMAP
>         select CLKSRC_MMIO
> --
> 2.40.1
>


-- 
Best Regards
Masahiro Yamada


From laurent.pinchart at ideasonboard.com  Sun Feb  4 05:50:56 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sun, 4 Feb 2024 15:50:56 +0200
Subject: [PATCH v4 1/2] media: dt-bindings: i2c: add GalaxyCore GC08A3
 image sensor
In-Reply-To: <20240204061538.2105-2-zhi.mao@mediatek.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
 <20240204061538.2105-2-zhi.mao@mediatek.com>
Message-ID: <20240204135056.GA6804@pendragon.ideasonboard.com>

Hi Zhi,

Thank you for the patch.

On Sun, Feb 04, 2024 at 02:15:37PM +0800, Zhi Mao wrote:
> Add YAML device tree binding for GC08A3 CMOS image sensor,
> and the relevant MAINTAINERS entries.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
>  .../bindings/media/i2c/galaxycore,gc08a3.yaml | 112 ++++++++++++++++++
>  1 file changed, 112 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml
> new file mode 100644
> index 000000000000..8c09e8c121e5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml
> @@ -0,0 +1,112 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright (c) 2023 MediaTek Inc.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/i2c/galaxycore,gc08a3.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: GalaxyCore gc08a3 1/4" 8M Pixel MIPI CSI-2 sensor
> +
> +maintainers:
> +  - Zhi Mao <zhi.mao at mediatek.com>
> +
> +description:
> +  The gc08a3 is a raw image sensor with an MIPI CSI-2 image data
> +  interface and CCI (I2C compatible) control bus. The output format
> +  is raw Bayer.
> +
> +properties:
> +  compatible:
> +    const: galaxycore,gc08a3
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  dovdd-supply: true
> +
> +  avdd-supply: true
> +
> +  dvdd-supply: true
> +
> +  reset-gpios:
> +    description: Reference to the GPIO connected to the RESETB pin.
> +    maxItems: 1
> +
> +  port:
> +    $ref: /schemas/graph.yaml#/$defs/port-base
> +    additionalProperties: false
> +    description:
> +      Output port node, single endpoint describing the CSI-2 transmitter.
> +
> +    properties:
> +      endpoint:
> +        $ref: /schemas/media/video-interfaces.yaml#
> +        unevaluatedProperties: false
> +
> +        properties:
> +          data-lanes:
> +            oneOf:
> +              - items:
> +                  - const: 1
> +                  - const: 2
> +                  - const: 3
> +                  - const: 4
> +              - items:
> +                  - const: 1
> +                  - const: 2
> +
> +          link-frequencies: true
> +
> +        required:
> +          - data-lanes
> +          - link-frequencies
> +
> +    required:
> +      - endpoint
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - dovdd-supply
> +  - avdd-supply
> +  - dvdd-supply
> +  - reset-gpios
> +  - port
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        sensor at 31 {
> +            compatible = "galaxycore,gc08a3";
> +            reg = <0x31>;
> +
> +            clocks = <&gc08a3_clk>;
> +
> +            reset-gpios = <&pio 19 GPIO_ACTIVE_HIGH>;
> +
> +            avdd-supply = <&gc08a3_avdd>;
> +            dovdd-supply = <&gc08a3_dovdd>;
> +            dvdd-supply = <&gc08a3_dvdd>;
> +
> +            port {
> +                sensor_out: endpoint {
> +                    data-lanes = <1 2 3 4>;
> +                    link-frequencies = /bits/ 64 <336000000 207000000>;
> +                    remote-endpoint = <&seninf_csi_port_0_in>;
> +                };
> +            };
> +        };
> +    };
> +
> +...

-- 
Regards,

Laurent Pinchart


From arinc.unal at arinc9.com  Sun Feb  4 05:55:40 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Sun, 4 Feb 2024 16:55:40 +0300
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <Zb021ozEQSbU-gPd@makrotopia.org>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
 <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>
 <5b744f7f-2f63-4219-a0e9-8f08267b1fdd@arinc9.com>
 <Zb021ozEQSbU-gPd@makrotopia.org>
Message-ID: <f6234b46-ce30-4b2a-9681-15633a06feff@arinc9.com>

On 2.02.2024 21:39, Daniel Golle wrote:
> On Fri, Feb 02, 2024 at 09:16:02PM +0300, Ar?n? ?NAL wrote:
>> On 2.02.2024 14:48, Russell King (Oracle) wrote:
>>> On Fri, Feb 02, 2024 at 12:19:10PM +0300, Ar?n? ?NAL via B4 Relay wrote:
>>>> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
>>>>
>>>> The crystal frequency concerns the switch core. The frequency should be
>>>> checked when the switch is being set up so the driver can reject the
>>>> unsupported hardware earlier and without requiring port 6 to be used.
>>>>
>>>> Move it to mt7530_setup(). Drop the unnecessary function printing.
>>>>
>>>> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
>>>> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
>>>> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
>>>
>>> I would prefer this to be earlier in the series, before patch 2 which
>>> moves mt7530_setup_port6() to be called from mac_config(). mac_config()
>>> is supposed to be configuration error-free - in other words, all state
>>> should have been checked before hand.
>>
>> I agree but mt7530_mac_config() is not a void function yet. The
>> mac_port_config member of the mt753x_info structure points to this
>> function. My next patch series gets rid of all useless error returns on the
>> phylink path and change mac_port_config to void. So I don't think working
>> on this patch series further will worth the effort. I'd rather have this
>> version applied as is.
> 
> I agree regarding not changing the patch itself, but I also agree
> with Russell regarding the patch ordering. I know it's a 10-minute
> git headache to rebase the patches on top of each other in a different
> order, but you can easily compare the end result being identical to
> what you had before and hence don't need to retest.

This is not about laziness. This is before patch 2:

phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
-> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
    -> mt753x_mac_config()
       -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
          -> mt7530_setup_port5()
    -> mt753x_pad_setup()
       -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()

This is after:

phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
-> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
    -> mt753x_mac_config()
       -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
          -> mt7530_setup_port5()
          -> mt7530_setup_port6()

Patch 2 does not move mt7530_setup_port6() to be called from
phylink_mac_ops :: mac_config(), it already is. There is no valid reason to
reorder the patches.

My response to Russell should've stated this instead of focusing on his
second sentence.

pw-bot: under-review

Ar?n?


From horms at kernel.org  Sun Feb  4 06:15:41 2024
From: horms at kernel.org (Simon Horman)
Date: Sun, 4 Feb 2024 14:15:41 +0000
Subject: [PATCH net-next v2 2/3] net: stmmac: Allow drivers to provide a
 default AXI configuration
In-Reply-To: <20240202-stmmac-axi-config-v2-2-64eab2bab17b@nvidia.com>
References: <20240202-stmmac-axi-config-v2-0-64eab2bab17b@nvidia.com>
 <20240202-stmmac-axi-config-v2-2-64eab2bab17b@nvidia.com>
Message-ID: <20240204141541.GA927333@kernel.org>

On Fri, Feb 02, 2024 at 12:53:34PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding at nvidia.com>
> 
> In many cases the AXI configuration can be derived from the compatible
> string, so there's no need to add the configuration to DT. Allow drivers
> to pass in the default AXI configuration so they can be properly set up
> without extra data in DT.
> 
> Signed-off-by: Thierry Reding <treding at nvidia.com>

...

> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> index 650ec8d2f5d7..0d5f2cebd6fc 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> @@ -91,34 +91,49 @@ static int dwmac1000_validate_ucast_entries(struct device *dev,
>   * if required, from device-tree the AXI internal register can be tuned
>   * by using platform parameters.
>   */
> -static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
> +static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev,
> +					   struct stmmac_resources *res)

Hi Thierry,

Please consider adding @res to the kernel doc for stmmac_axi_setup,
just a few lines above this hunk.

...


From linux at armlinux.org.uk  Sun Feb  4 06:18:28 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 4 Feb 2024 14:18:28 +0000
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <f6234b46-ce30-4b2a-9681-15633a06feff@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
 <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>
 <5b744f7f-2f63-4219-a0e9-8f08267b1fdd@arinc9.com>
 <Zb021ozEQSbU-gPd@makrotopia.org>
 <f6234b46-ce30-4b2a-9681-15633a06feff@arinc9.com>
Message-ID: <Zb+ctEe9TVA3zhv8@shell.armlinux.org.uk>

On Sun, Feb 04, 2024 at 04:55:40PM +0300, Ar?n? ?NAL wrote:
> On 2.02.2024 21:39, Daniel Golle wrote:
> > On Fri, Feb 02, 2024 at 09:16:02PM +0300, Ar?n? ?NAL wrote:
> > > On 2.02.2024 14:48, Russell King (Oracle) wrote:
> > > > On Fri, Feb 02, 2024 at 12:19:10PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> > > > > From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> > > > > 
> > > > > The crystal frequency concerns the switch core. The frequency should be
> > > > > checked when the switch is being set up so the driver can reject the
> > > > > unsupported hardware earlier and without requiring port 6 to be used.
> > > > > 
> > > > > Move it to mt7530_setup(). Drop the unnecessary function printing.
> > > > > 
> > > > > Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> > > > > Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> > > > > Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
> > > > 
> > > > I would prefer this to be earlier in the series, before patch 2 which
> > > > moves mt7530_setup_port6() to be called from mac_config(). mac_config()
> > > > is supposed to be configuration error-free - in other words, all state
> > > > should have been checked before hand.
> > > 
> > > I agree but mt7530_mac_config() is not a void function yet. The
> > > mac_port_config member of the mt753x_info structure points to this
> > > function. My next patch series gets rid of all useless error returns on the
> > > phylink path and change mac_port_config to void. So I don't think working
> > > on this patch series further will worth the effort. I'd rather have this
> > > version applied as is.
> > 
> > I agree regarding not changing the patch itself, but I also agree
> > with Russell regarding the patch ordering. I know it's a 10-minute
> > git headache to rebase the patches on top of each other in a different
> > order, but you can easily compare the end result being identical to
> > what you had before and hence don't need to retest.
> 
> This is not about laziness. This is before patch 2:
> 
> phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
> -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
>    -> mt753x_mac_config()
>       -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
>          -> mt7530_setup_port5()
>    -> mt753x_pad_setup()
>       -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()
> 
> This is after:
> 
> phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
> -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
>    -> mt753x_mac_config()
>       -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
>          -> mt7530_setup_port5()
>          -> mt7530_setup_port6()
> 
> Patch 2 does not move mt7530_setup_port6() to be called from
> phylink_mac_ops :: mac_config(), it already is. There is no valid reason to
> reorder the patches.
> 
> My response to Russell should've stated this instead of focusing on his
> second sentence.

This patch moves the test for a 20MHz crystal to mt7530_setup(),
which is something that is entirely orthogonal to patch 2, which
can be done cleanly (I've just applied the patches in the original
order and then reordered them:

98c481f5d706 net: dsa: mt7530: do not clear config->supported_interfaces
93c6b53b17f4 net: dsa: mt7530: correct port capabilities of MT7988
c9c6d4c51a1d net: dsa: mt7530: simplify mt7530_setup_port6() and change to void
adfa948253e0 net: dsa: mt7530: remove pad_setup function pointer
57e21e6c2fc0 net: dsa: mt7530: call port 6 setup from mt7530_mac_config()
959a0f9323c8 net: dsa: mt7530: move XTAL check to mt7530_setup()
856ab64a22ef net: dsa: mt7530: empty default case on mt7530_setup_port5()

No problems. The end result is identical comparing the git tree at the
original "move XTAL" patch with adfa948253e0.

Now, if we look at "net: dsa: mt7530: remove pad_setup function pointer"
we can see that yes, the pad_setup() method was called from mac_confing,
but this is the exact contents of that patch removing the callsite:

-               mt753x_pad_setup(ds, state);

This returns an integer, which may be an error code, which is ignored.
Therefore, if the XTAL frequency check fires, and mt753x_pad_setup()
returns an error, it is ignored today.

After "net: dsa: mt7530: call port 6 setup from mt7530_mac_config()"
the renamed pad_setup() method is now called from mac_config() thusly:

+               ret = mt7530_setup_port6(priv->ds, interface);
+               if (ret)
+                       return ret;

So now the error checks cause mt7530_mac_config() to return an error
which in turn causes mt753x_mac_config() to fail, and therefore
mt753x_phylink_mac_config() has different behaviour.

So, patch 2 changes the driver behaviour in the case of a 20MHz XTAL,
which is then changed again by patch 4.

It would be better to have only one change of behaviour by moving
patch 4 before patch 2.

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


From sandor.yu at nxp.com  Sun Feb  4 06:29:01 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Sun, 4 Feb 2024 14:29:01 +0000
Subject: [EXT] Re: [PATCH v12 7/7] phy: freescale: Add HDMI PHY driver for
 i.MX8MQ
In-Reply-To: <3204157.5fSG56mABF@steina-w>
References: <cover.1704785836.git.Sandor.yu@nxp.com>
 <176920a13c11129f61c1f550bb64e7ddb7ef1b14.1704785836.git.Sandor.yu@nxp.com>
 <3204157.5fSG56mABF@steina-w>
Message-ID: <PAXPR04MB9448DECE01834E8DC9717E87F4402@PAXPR04MB9448.eurprd04.prod.outlook.com>

Hi Alexander,

Thanks your comments,

> -----Original Message-----
> From: Alexander Stein <alexander.stein at ew.tq-group.com>
> Sent: 2024?1?17? 17:47
> To: dmitry.baryshkov at linaro.org; andrzej.hajda at intel.com;
> neil.armstrong at linaro.org; Laurent Pinchart
> <laurent.pinchart at ideasonboard.com>; jonas at kwiboo.se;
> jernej.skrabec at gmail.com; airlied at gmail.com; daniel at ffwll.ch;
> robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org;
> shawnguo at kernel.org; s.hauer at pengutronix.de; festevam at gmail.com;
> vkoul at kernel.org; dri-devel at lists.freedesktop.org;
> devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> linux-kernel at vger.kernel.org; linux-phy at lists.infradead.org; Sandor Yu
> <sandor.yu at nxp.com>
> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>; Sandor Yu
> <sandor.yu at nxp.com>; Oliver Brown <oliver.brown at nxp.com>;
> sam at ravnborg.org
> Subject: [EXT] Re: [PATCH v12 7/7] phy: freescale: Add HDMI PHY driver for
> i.MX8MQ
>
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
>
>
> Hi Sandor,
>
> thanks for the update.
>
> Am Mittwoch, 10. Januar 2024, 02:08:48 CET schrieb Sandor Yu:
> > Add Cadence HDP-TX HDMI PHY driver for i.MX8MQ.
> >
> > Cadence HDP-TX PHY could be put in either DP mode or HDMI mode base
> on
> > the configuration chosen.
> > HDMI PHY mode is configurated in the driver.
> >
> > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> > v11->v12:
> > - Adjust clk disable order.
> > - Return error code to replace -1 for function wait_for_ack().
> > - Use bool for variable pclk_in.
> > - Add year 2024 to copyright.
> >
> >  drivers/phy/freescale/Kconfig               |  10 +
> >  drivers/phy/freescale/Makefile              |   1 +
> >  drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c | 959
> > ++++++++++++++++++++
> >  3 files changed, 970 insertions(+)
> >  create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> >
> > diff --git a/drivers/phy/freescale/Kconfig
> > b/drivers/phy/freescale/Kconfig index c39709fd700ac..14f47b7cc77ab
> > 100644
> > --- a/drivers/phy/freescale/Kconfig
> > +++ b/drivers/phy/freescale/Kconfig
> > @@ -45,6 +45,16 @@ config PHY_FSL_IMX8MQ_DP
> >         Enable this to support the Cadence HDPTX DP PHY driver
> >         on i.MX8MQ SOC.
> >
> > +config PHY_FSL_IMX8MQ_HDMI
> > +     tristate "Freescale i.MX8MQ HDMI PHY support"
> > +     depends on OF && HAS_IOMEM
> > +     depends on COMMON_CLK
> > +     select GENERIC_PHY
> > +     select CDNS_MHDP_HELPER
> > +     help
> > +       Enable this to support the Cadence HDPTX HDMI PHY driver
> > +       on i.MX8MQ SOC.
> > +
> >  endif
> >
> >  config PHY_FSL_LYNX_28G
> > diff --git a/drivers/phy/freescale/Makefile
> > b/drivers/phy/freescale/Makefile index 47e5285209fa8..1380ac31c2ead
> > 100644
> > --- a/drivers/phy/freescale/Makefile
> > +++ b/drivers/phy/freescale/Makefile
> > @@ -1,5 +1,6 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >  obj-$(CONFIG_PHY_FSL_IMX8MQ_DP)              +=
> phy-fsl-imx8mq-dp.o
> > +obj-$(CONFIG_PHY_FSL_IMX8MQ_HDMI)    += phy-fsl-imx8mq-hdmi.o
> >  obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)     += phy-fsl-imx8mq-usb.o
> >  obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)     += phy-fsl-imx8qm-lvds-phy.o
> >  obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)    += phy-fsl-imx8-mipi-dphy.o
> > diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> > b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c new file mode 100644
> > index 0000000000000..9e03c726f290c
> > --- /dev/null
> > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> > @@ -0,0 +1,959 @@
> > [snip]
> > +int cdns_hdptx_hdmi_phy_valid(struct phy *phy, enum phy_mode mode,
> > +int
> > submode, +                          union phy_configure_opts
> *opts)
>
> This function can be made static.
>

OK, thanks!

B.R
Sandor

> Thanks and best regards,
> Alexander
>
> > +{
> > +     u32 rate = opts->hdmi.pixel_clk_rate;
> > +     int i;
> > +
> > +     for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++)
> > +             if (rate ==
> pixel_clk_output_ctrl_table[i].pixel_clk_freq_min)
> > +                     return 0;
> > +
> > +     return -EINVAL;
> > +}
> > +
> > +static int cdns_hdptx_hdmi_phy_init(struct phy *phy) {
> > +     return 0;
> > +}
> > +
> > +static int cdns_hdptx_hdmi_configure(struct phy *phy,
> > +                                  union phy_configure_opts *opts)
> {
> > +     struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
> > +     int ret;
> > +
> > +     cdns_phy->pixel_clk_rate = opts->hdmi.pixel_clk_rate;
> > +     cdns_phy->color_space = opts->hdmi.color_space;
> > +     cdns_phy->bpc = opts->hdmi.bpc;
> > +
> > +     /* Check HDMI FW alive before HDMI PHY init */
> > +     ret = hdptx_phy_check_alive(cdns_phy);
> > +     if (!ret) {
> > +             dev_err(cdns_phy->dev, "NO HDMI FW running\n");
> > +             return -ENXIO;
> > +     }
> > +
> > +     /* Configure PHY */
> > +     if (hdptx_hdmi_phy_cfg(cdns_phy, cdns_phy->pixel_clk_rate) < 0) {
> > +             dev_err(cdns_phy->dev, "failed to set phy pclock\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = hdptx_hdmi_phy_power_up(cdns_phy);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     hdptx_hdmi_phy_set_vswing(cdns_phy);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct phy_ops cdns_hdptx_hdmi_phy_ops = {
> > +     .init = cdns_hdptx_hdmi_phy_init,
> > +     .configure = cdns_hdptx_hdmi_configure,
> > +     .power_on = cdns_hdptx_hdmi_phy_on,
> > +     .power_off = cdns_hdptx_hdmi_phy_off,
> > +     .validate = cdns_hdptx_hdmi_phy_valid,
> > +     .owner = THIS_MODULE,
> > +};
> > +
> > +static int cdns_hdptx_hdmi_phy_probe(struct platform_device *pdev) {
> > +     struct cdns_hdptx_hdmi_phy *cdns_phy;
> > +     struct device *dev = &pdev->dev;
> > +     struct device_node *node = dev->of_node;
> > +     struct phy_provider *phy_provider;
> > +     struct resource *res;
> > +     struct phy *phy;
> > +     int ret;
> > +
> > +     cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
> > +     if (!cdns_phy)
> > +             return -ENOMEM;
> > +
> > +     dev_set_drvdata(dev, cdns_phy);
> > +     cdns_phy->dev = dev;
> > +     mutex_init(&cdns_phy->mbox_mutex);
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     if (!res)
> > +             return -ENODEV;
> > +     cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res));
> > +     if (IS_ERR(cdns_phy->regs))
> > +             return PTR_ERR(cdns_phy->regs);
> > +
> > +     phy = devm_phy_create(dev, node, &cdns_hdptx_hdmi_phy_ops);
> > +     if (IS_ERR(phy))
> > +             return PTR_ERR(phy);
> > +
> > +     phy->attrs.mode = PHY_MODE_HDMI;
> > +
> > +     cdns_phy->phy = phy;
> > +     phy_set_drvdata(phy, cdns_phy);
> > +
> > +     /* init base struct for access mhdp mailbox */
> > +     cdns_phy->base.dev = cdns_phy->dev;
> > +     cdns_phy->base.regs = cdns_phy->regs;
> > +     cdns_phy->base.mbox_mutex = &cdns_phy->mbox_mutex;
> > +
> > +     ret = hdptx_hdmi_clk_enable(cdns_phy);
> > +     if (ret) {
> > +             dev_err(dev, "Init clk fail\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     phy_provider = devm_of_phy_provider_register(dev,
> of_phy_simple_xlate);
> > +     if (IS_ERR(phy_provider)) {
> > +             ret = PTR_ERR(phy_provider);
> > +             goto clk_disable;
> > +     }
> > +
> > +     dev_dbg(dev, "probe success!\n");
> > +
> > +     return 0;
> > +
> > +clk_disable:
> > +     hdptx_hdmi_clk_disable(cdns_phy);
> > +
> > +     return -EINVAL;
> > +}
> > +
> > +static int cdns_hdptx_hdmi_phy_remove(struct platform_device *pdev) {
> > +     struct cdns_hdptx_hdmi_phy *cdns_phy =
> > +platform_get_drvdata(pdev);
> > +
> > +     hdptx_hdmi_clk_disable(cdns_phy);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct of_device_id cdns_hdptx_hdmi_phy_of_match[] = {
> > +     {.compatible = "fsl,imx8mq-hdmi-phy" },
> > +     { /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, cdns_hdptx_hdmi_phy_of_match);
> > +
> > +static struct platform_driver cdns_hdptx_hdmi_phy_driver = {
> > +     .probe = cdns_hdptx_hdmi_phy_probe,
> > +     .remove = cdns_hdptx_hdmi_phy_remove,
> > +     .driver = {
> > +             .name   = "cdns-hdptx-hdmi-phy",
> > +             .of_match_table = cdns_hdptx_hdmi_phy_of_match,
> > +     }
> > +};
> > +module_platform_driver(cdns_hdptx_hdmi_phy_driver);
> > +
> > +MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
> > +MODULE_DESCRIPTION("Cadence HDP-TX HDMI PHY driver");
> > +MODULE_LICENSE("GPL");
>
>
> --
> TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht M?nchen, HRB 105018
> Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> http://www.tq-/
> group.com%2F&data=05%7C02%7CSandor.yu%40nxp.com%7Cb17a4addce1e4
> 8b54f8a08dc17414379%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
> %7C638410816282055456%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjA
> wMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7
> C%7C&sdata=YFO2ShpepVs%2B%2FTSDfzLdZjkPc7s0VHrqjX9jxsqSXok%3D&res
> erved=0
>


From sandor.yu at nxp.com  Sun Feb  4 06:29:05 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Sun, 4 Feb 2024 14:29:05 +0000
Subject: [EXT] Re: [PATCH v12 4/7] drm: bridge: Cadence: Add MHDP8501
 DP/HDMI driver
In-Reply-To: <9223210.CDJkKcVGEf@steina-w>
References: <cover.1704785836.git.Sandor.yu@nxp.com>
 <d2d5d5bbde972eee5417c3e04db33895cf5ee88b.1704785836.git.Sandor.yu@nxp.com>
 <9223210.CDJkKcVGEf@steina-w>
Message-ID: <PAXPR04MB94485C09E619D404CBF96891F4402@PAXPR04MB9448.eurprd04.prod.outlook.com>

Hi Alexander,

Thanks your comments,

>
>
> Hi Sandor,
>
> thanks for the update.
>
> Am Mittwoch, 10. Januar 2024, 02:08:45 CET schrieb Sandor Yu:
> > Add a new DRM DisplayPort and HDMI bridge driver for Candence
> MHDP8501
> > used in i.MX8MQ SOC. MHDP8501 could support HDMI or DisplayPort
> > standards according embedded Firmware running in the uCPU.
> >
> > For iMX8MQ SOC, the DisplayPort/HDMI FW was loaded and activated by
> > SOC's ROM code. Bootload binary included respective specific firmware
> > is required.
> >
> > Driver will check display connector type and then load the
> > corresponding driver.
> >
> > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> > v11->v12:
> > - Replace DRM_INFO with dev_info or dev_warn.
> > - Replace DRM_ERROR with dev_err.
> > - Return ret when cdns_mhdp_dpcd_read failed in function
> > cdns_dp_aux_transferi(). - Remove unused parmeter in function
> > cdns_dp_get_msa_misc
> >   and use two separate variables for color space and bpc.
> > - Add year 2024 to copyright.
> >
> >  drivers/gpu/drm/bridge/cadence/Kconfig        |  16 +
> >  drivers/gpu/drm/bridge/cadence/Makefile       |   2 +
> >  .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 315 ++++++++
> >  .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 365 +++++++++
> >  .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 699
> ++++++++++++++++++
> >  .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 678
> +++++++++++++++++
> >  6 files changed, 2075 insertions(+)
> >  create mode 100644
> > drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> >  create mode 100644
> > drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
> >  create mode 100644
> drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> >  create mode 100644
> > drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> >
> > diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig
> > b/drivers/gpu/drm/bridge/cadence/Kconfig index
> > e0973339e9e33..45848e741f5f4
> > 100644
> > --- a/drivers/gpu/drm/bridge/cadence/Kconfig
> > +++ b/drivers/gpu/drm/bridge/cadence/Kconfig
> > @@ -51,3 +51,19 @@ config DRM_CDNS_MHDP8546_J721E
> >         initializes the J721E Display Port and sets up the
> >         clock and data muxes.
> >  endif
> > +
> > +config DRM_CDNS_MHDP8501
> > +     tristate "Cadence MHDP8501 DP/HDMI bridge"
> > +     select DRM_KMS_HELPER
> > +     select DRM_PANEL_BRIDGE
> > +     select DRM_DISPLAY_DP_HELPER
> > +     select DRM_DISPLAY_HELPER
> > +     select CDNS_MHDP_HELPER
> > +     select DRM_CDNS_AUDIO
> > +     depends on OF
> > +     help
> > +       Support Cadence MHDP8501 DisplayPort/HDMI bridge.
> > +       Cadence MHDP8501 support one or more protocols,
> > +       including DisplayPort and HDMI.
> > +       To use the DP and HDMI drivers, their respective
> > +       specific firmware is required.
> > diff --git a/drivers/gpu/drm/bridge/cadence/Makefile
> > b/drivers/gpu/drm/bridge/cadence/Makefile index
> > 087dc074820d7..02c1a9f3cf6fc 100644
> > --- a/drivers/gpu/drm/bridge/cadence/Makefile
> > +++ b/drivers/gpu/drm/bridge/cadence/Makefile
> > @@ -6,3 +6,5 @@ obj-$(CONFIG_CDNS_MHDP_HELPER) +=
> cdns-mhdp-helper.o
> >  obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
> cdns-mhdp8546-y
> > := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
> >  cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) +=
> > cdns-mhdp8546-j721e.o
> > +obj-$(CONFIG_DRM_CDNS_MHDP8501) += cdns-mhdp8501.o
> cdns-mhdp8501-y :=
> > +cdns-mhdp8501-core.o cdns-mhdp8501-dp.o
> > cdns-mhdp8501-hdmi.o diff --git
> > a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> > b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c new file mode
> > 100644 index 0000000000000..3080c7507a012
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> > @@ -0,0 +1,315 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Cadence Display Port Interface (DP) driver
> > + *
> > + * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
> > + *
> > + */
> > +#include <drm/drm_of.h>
> > +#include <drm/drm_print.h>
> > +#include <linux/clk.h>
> > +#include <linux/irq.h>
> > +#include <linux/mutex.h>
> > +#include <linux/of_device.h>
>
> Since commit d57d584ef69de ("of: Stop circularly including of_device.h and
> of_platform.h") you to explicitly include linux/platform_device.h here. Please
> compile against next tree.

OK, I will check it on next tree.

>
> > +#include <linux/phy/phy.h>
> > +
> > +#include "cdns-mhdp8501-core.h"
> > +
> > [snip]
> > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> > b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c new file mode
> > 100644 index 0000000000000..6963c7143a3b0
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> > @@ -0,0 +1,699 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Cadence MHDP8501 DisplayPort(DP) bridge driver
> > + *
> > + * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
> > + *
> > + */
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_edid.h>
> > +#include <drm/drm_print.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/phy/phy-dp.h>
> > +
> > +#include "cdns-mhdp8501-core.h"
> > +
> > +#define LINK_TRAINING_TIMEOUT_MS     500
> > +#define LINK_TRAINING_RETRY_MS               20
> > +
> > +ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux,
> > +                          struct drm_dp_aux_msg *msg) {
> > +     struct cdns_mhdp8501_device *mhdp = dev_get_drvdata(aux->dev);
> > +     bool native = msg->request & (DP_AUX_NATIVE_WRITE &
> DP_AUX_NATIVE_READ);
> > +     int ret;
> > +
> > +     /* Ignore address only message */
> > +     if (!msg->size || !msg->buffer) {
> > +             msg->reply = native ?
> > +                     DP_AUX_NATIVE_REPLY_ACK :
> DP_AUX_I2C_REPLY_ACK;
> > +             return msg->size;
> > +     }
> > +
> > +     if (!native) {
> > +             dev_err(mhdp->dev, "%s: only native messages
> > + supported\n",
> __func__);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* msg sanity check */
> > +     if (msg->size > DP_AUX_MAX_PAYLOAD_BYTES) {
> > +             dev_err(mhdp->dev, "%s: invalid msg: size(%zu),
> request(%x)\n",
> > +                     __func__, msg->size, (unsigned int)msg-
> >request);
> > +             return -EINVAL;
> > +     }
> > +
> > +     if (msg->request == DP_AUX_NATIVE_WRITE) {
> > +             const u8 *buf = msg->buffer;
> > +             int i;
> > +
> > +             for (i = 0; i < msg->size; ++i) {
> > +                     ret = cdns_mhdp_dpcd_write(&mhdp->base,
> > +                                                msg->address +
> i, buf[i]);
> > +                     if (ret < 0) {
> > +                             dev_err(mhdp->dev, "Failed to write
> DPCD\n");
> > +                             return ret;
> > +                     }
> > +             }
> > +             msg->reply = DP_AUX_NATIVE_REPLY_ACK;
> > +             return msg->size;
> > +     }
> > +
> > +     if (msg->request == DP_AUX_NATIVE_READ) {
> > +             ret = cdns_mhdp_dpcd_read(&mhdp->base, msg->address,
> > +                                       msg->buffer, msg->size);
> > +             if (ret < 0)
> > +                     return ret;
> > +             msg->reply = DP_AUX_NATIVE_REPLY_ACK;
> > +             return msg->size;
> > +     }
> > +     return 0;
> > +}
> > +
> > +int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp) {
> > +     drm_dp_aux_unregister(&mhdp->dp.aux);
> > +
> > +     return 0;
> > +}
> > +
> > +static int cdns_dp_get_msa_misc(struct video_info *video) {
> > +     u32 msa_misc;
> > +     u8 color_space = 0;
> > +     u8 bpc = 0;
> > +
> > +     switch (video->color_fmt) {
> > +     /* set YUV default color space conversion to BT601 */
> > +     case DRM_COLOR_FORMAT_YCBCR444:
> > +             color_space = 6 + BT_601 * 8;
> > +             break;
> > +     case DRM_COLOR_FORMAT_YCBCR422:
> > +             color_space = 5 + BT_601 * 8;
> > +             break;
> > +     case DRM_COLOR_FORMAT_YCBCR420:
> > +             color_space = 5;
> > +             break;
> > +     case DRM_COLOR_FORMAT_RGB444:
> > +     default:
> > +             color_space = 0;
> > +             break;
> > +     };
> > +
> > +     switch (video->bpc) {
> > +     case 6:
> > +             bpc = 0;
> > +             break;
> > +     case 10:
> > +             bpc = 2;
> > +             break;
> > +     case 12:
> > +             bpc = 3;
> > +             break;
> > +     case 16:
> > +             bpc = 4;
> > +             break;
> > +     case 8:
> > +     default:
> > +             bpc = 1;
> > +             break;
> > +     };
> > +
> > +     msa_misc = (color_space << 1) | (bpc << 5);
>
> This looks much nicer, thanks. But please order them in descending shift
> width: bpc first then color_space.
>

OK.

> > +
> > +     return msa_misc;
> > +}
> > +
> > [snip]
> > +int cdns_dp_set_host_cap(struct cdns_mhdp8501_device *mhdp)
>
> This can be made static.

OK.

>
> > +{
> > +     u8 msg[8];
> > +     int ret;
> > +
> > +     msg[0] = drm_dp_link_rate_to_bw_code(mhdp->dp.rate);
> > +     msg[1] = mhdp->dp.num_lanes | SCRAMBLER_EN;
> > +     msg[2] = VOLTAGE_LEVEL_2;
> > +     msg[3] = PRE_EMPHASIS_LEVEL_3;
> > +     msg[4] = PTS1 | PTS2 | PTS3 | PTS4;
> > +     msg[5] = FAST_LT_NOT_SUPPORT;
> > +     msg[6] = mhdp->lane_mapping;
> > +     msg[7] = ENHANCED;
> > +
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +
> > +     ret = cdns_mhdp_mailbox_send(&mhdp->base,
> MB_MODULE_ID_DP_TX,
> > +                                  DPTX_SET_HOST_CAPABILITIES,
> > +                                  sizeof(msg), msg);
> > +
> > +     mutex_unlock(&mhdp->mbox_mutex);
> > +
> > +     if (ret)
> > +             dev_err(mhdp->dev, "set host cap failed: %d\n", ret);
> > +
> > +     return ret;
> > +}
> > [snip]
> > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> > b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c new file mode
> > 100644 index 0000000000000..ae21f7dfe5e94
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> > @@ -0,0 +1,678 @@
> > [snip]
> > +bool cdns_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
> > +                              const struct drm_display_mode
> *mode,
> > +                              struct drm_display_mode
> *adjusted_mode)
>
> This can be made static.

OK, thanks!

Sandor

>
> Thanks and best regards,
> Alexander
>
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +     struct video_info *video = &mhdp->video_info;
> > +
> > +     /* The only currently supported format */
> > +     video->bpc = 8;
> > +     video->color_fmt = DRM_COLOR_FORMAT_RGB444;
> > +
> > +     return true;
> > +}
> > +
> > +static enum drm_connector_status
> > +cdns_hdmi_bridge_detect(struct drm_bridge *bridge) {
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     return cdns_mhdp8501_detect(mhdp); }
> > +
> > +static struct edid *cdns_hdmi_bridge_get_edid(struct drm_bridge *bridge,
> > +                                           struct drm_connector
> *connector)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     return drm_do_get_edid(connector, cdns_hdmi_get_edid_block,
> > +mhdp); }
> > +
> > +static void cdns_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
> > +                                         struct drm_bridge_state
> *old_state)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +
> > +     mhdp->curr_conn = NULL;
> > +
> > +     /* Mailbox protect for HDMI PHY access */
> > +     mutex_lock(&mhdp->mbox_mutex);
> > +     phy_power_off(mhdp->phy);
> > +     mutex_unlock(&mhdp->mbox_mutex); }
> > +
> > +static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
> > +                                        struct drm_bridge_state
> *old_state)
> > +{
> > +     struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
> > +     struct drm_atomic_state *state = old_state->base.state;
> > +     struct drm_connector *connector;
> > +     struct drm_crtc_state *crtc_state;
> > +     struct drm_connector_state *conn_state;
> > +     const struct drm_display_mode *mode;
> > +
> > +     connector = drm_atomic_get_new_connector_for_encoder(state,
> > +
> bridge->encoder);
> > +     if (WARN_ON(!connector))
> > +             return;
> > +
> > +     mhdp->curr_conn = connector;
> > +
> > +     conn_state = drm_atomic_get_new_connector_state(state,
> connector);
> > +     if (WARN_ON(!conn_state))
> > +             return;
> > +
> > +     crtc_state = drm_atomic_get_new_crtc_state(state,
> conn_state->crtc);
> > +     if (WARN_ON(!crtc_state))
> > +             return;
> > +
> > +     mode = &crtc_state->adjusted_mode;
> > +     dev_dbg(mhdp->dev, "Mode: %dx%dp%d\n",
> > +             mode->hdisplay, mode->vdisplay, mode->clock);
> > +     memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
> > +
> > +     cdns_hdmi_mode_set(mhdp);
> > +}
> > +
> > +const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
> > +     .attach = cdns_hdmi_bridge_attach,
> > +     .detect = cdns_hdmi_bridge_detect,
> > +     .get_edid = cdns_hdmi_bridge_get_edid,
> > +     .mode_valid = cdns_hdmi_bridge_mode_valid,
> > +     .mode_fixup = cdns_hdmi_bridge_mode_fixup,
> > +     .atomic_enable = cdns_hdmi_bridge_atomic_enable,
> > +     .atomic_disable = cdns_hdmi_bridge_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, };
>
>
> --
> TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht M?nchen, HRB 105018
> Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> http://www.tq-/
> group.com%2F&data=05%7C02%7CSandor.yu%40nxp.com%7Cb23e376f27494
> 9cdb46c08dc17413d46%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
> %7C638410816178929125%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjA
> wMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7
> C%7C&sdata=tYc81WajNJAOmUvSD06cto0i%2FhVe%2BuLFxIeYm0uyMDM%3
> D&reserved=0
>



From ricardo at marliere.net  Sun Feb  4 06:46:21 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 04 Feb 2024 11:46:21 -0300
Subject: [PATCH] arm: s3c64xx: make s3c64xx_subsys const
Message-ID: <20240204-bus_cleanup-arm-v1-1-41d651dd8411@marliere.net>

Now that the driver core can properly handle constant struct bus_type,
move the s3c64xx_subsys variable to be a constant structure as well,
placing it into read-only memory which can not be modified at runtime.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 arch/arm/mach-s3c/s3c64xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-s3c/s3c64xx.c b/arch/arm/mach-s3c/s3c64xx.c
index 9f9717874d67..6c70ea7f2931 100644
--- a/arch/arm/mach-s3c/s3c64xx.c
+++ b/arch/arm/mach-s3c/s3c64xx.c
@@ -149,7 +149,7 @@ static struct map_desc s3c_iodesc[] __initdata = {
 	},
 };
 
-static struct bus_type s3c64xx_subsys = {
+static const struct bus_type s3c64xx_subsys = {
 	.name		= "s3c64xx-core",
 	.dev_name	= "s3c64xx-core",
 };

---
base-commit: 8f5b7dbc644d6217a2fd35cb82594b215818eb16
change-id: 20240204-bus_cleanup-arm-391704e66efc

Best regards,
-- 
Ricardo B. Marliere <ricardo at marliere.net>



From gregkh at linuxfoundation.org  Sun Feb  4 06:52:24 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Sun, 4 Feb 2024 06:52:24 -0800
Subject: [PATCH] arm: s3c64xx: make s3c64xx_subsys const
In-Reply-To: <20240204-bus_cleanup-arm-v1-1-41d651dd8411@marliere.net>
References: <20240204-bus_cleanup-arm-v1-1-41d651dd8411@marliere.net>
Message-ID: <2024020419-vertebrae-twistable-2995@gregkh>

On Sun, Feb 04, 2024 at 11:46:21AM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the s3c64xx_subsys variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
> ---
>  arch/arm/mach-s3c/s3c64xx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From aford173 at gmail.com  Sun Feb  4 06:54:13 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 4 Feb 2024 08:54:13 -0600
Subject: [PATCH V8 06/12] arm64: dts: imx8mp: add HDMI irqsteer
In-Reply-To: <20240204120033.GA4656@francesco-nb>
References: <20240203165307.7806-1-aford173@gmail.com> <20240203165307.7806-7-aford173@gmail.com>
 <20240204120033.GA4656@francesco-nb>
Message-ID: <CAHCN7xKGMNpiTxy_7vMKd+rSsS6aya7N+duVVwFNKnpG0M0gBQ@mail.gmail.com>

On Sun, Feb 4, 2024 at 6:00?AM Francesco Dolcini <francesco at dolcini.it> wrote:
>
> On Sat, Feb 03, 2024 at 10:52:46AM -0600, Adam Ford wrote:
> > From: Lucas Stach <l.stach at pengutronix.de>
> >
> > The HDMI irqsteer is a secondary interrupt controller within the HDMI
> > subsystem that maps all HDMI peripheral IRQs into a single upstream
> > IRQ line.
> >
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
>
> This is missing your signed-off-by, and in other patches of this series

Opps.  I thought I caught all those.

> your signed-off-by is not the last, as it should be.
>
> Please have a look and fix this and the other instances.
>

OK.  I have some work to do on some other portions, so I'll clean up that too.

adam
> Thanks for this work!

Thanks for the feedback.

adam
>
> Francesco
>


From andrew at lunn.ch  Sun Feb  4 07:23:47 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 4 Feb 2024 16:23:47 +0100
Subject: [PATCH net-next v2 3/6] net: fec: remove eee_enabled/eee_active
 in fec_enet_get_eee()
In-Reply-To: <E1rWbN2-002cCh-MY@rmk-PC.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
 <E1rWbN2-002cCh-MY@rmk-PC.armlinux.org.uk>
Message-ID: <d3d427e4-1d45-4527-98f4-959fcfc13391@lunn.ch>

On Sun, Feb 04, 2024 at 12:13:12PM +0000, Russell King (Oracle) wrote:
> fec_enet_get_eee() sets edata->eee_active and edata->eee_enabled from
> its own copy, and then calls phy_ethtool_get_eee() which in turn will
> call genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Therefore, setting these members in fec_enet_get_eee() is redundant.
> Remove this, and remove the setting of fep->eee.eee_active member which
> becomes a write-only variable.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

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

    Andrew


From arinc.unal at arinc9.com  Sun Feb  4 07:55:14 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Sun, 4 Feb 2024 18:55:14 +0300
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <Zb+ctEe9TVA3zhv8@shell.armlinux.org.uk>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
 <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>
 <5b744f7f-2f63-4219-a0e9-8f08267b1fdd@arinc9.com>
 <Zb021ozEQSbU-gPd@makrotopia.org>
 <f6234b46-ce30-4b2a-9681-15633a06feff@arinc9.com>
 <Zb+ctEe9TVA3zhv8@shell.armlinux.org.uk>
Message-ID: <4fa2ff0d-2804-4a58-980f-162e62b3dc9c@arinc9.com>

On 4.02.2024 17:18, Russell King (Oracle) wrote:
> On Sun, Feb 04, 2024 at 04:55:40PM +0300, Ar?n? ?NAL wrote:
>> This is not about laziness. This is before patch 2:
>>
>> phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
>> -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
>>     -> mt753x_mac_config()
>>        -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
>>           -> mt7530_setup_port5()
>>     -> mt753x_pad_setup()
>>        -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()
>>
>> This is after:
>>
>> phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
>> -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
>>     -> mt753x_mac_config()
>>        -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
>>           -> mt7530_setup_port5()
>>           -> mt7530_setup_port6()
>>
>> Patch 2 does not move mt7530_setup_port6() to be called from
>> phylink_mac_ops :: mac_config(), it already is. There is no valid reason to
>> reorder the patches.
>>
>> My response to Russell should've stated this instead of focusing on his
>> second sentence.
> 
> This patch moves the test for a 20MHz crystal to mt7530_setup(),
> which is something that is entirely orthogonal to patch 2, which
> can be done cleanly (I've just applied the patches in the original
> order and then reordered them:
> 
> 98c481f5d706 net: dsa: mt7530: do not clear config->supported_interfaces
> 93c6b53b17f4 net: dsa: mt7530: correct port capabilities of MT7988
> c9c6d4c51a1d net: dsa: mt7530: simplify mt7530_setup_port6() and change to void
> adfa948253e0 net: dsa: mt7530: remove pad_setup function pointer
> 57e21e6c2fc0 net: dsa: mt7530: call port 6 setup from mt7530_mac_config()
> 959a0f9323c8 net: dsa: mt7530: move XTAL check to mt7530_setup()
> 856ab64a22ef net: dsa: mt7530: empty default case on mt7530_setup_port5()
> 
> No problems. The end result is identical comparing the git tree at the
> original "move XTAL" patch with adfa948253e0.
> 
> Now, if we look at "net: dsa: mt7530: remove pad_setup function pointer"
> we can see that yes, the pad_setup() method was called from mac_confing,
> but this is the exact contents of that patch removing the callsite:
> 
> -               mt753x_pad_setup(ds, state);
> 
> This returns an integer, which may be an error code, which is ignored.
> Therefore, if the XTAL frequency check fires, and mt753x_pad_setup()
> returns an error, it is ignored today.
> 
> After "net: dsa: mt7530: call port 6 setup from mt7530_mac_config()"
> the renamed pad_setup() method is now called from mac_config() thusly:
> 
> +               ret = mt7530_setup_port6(priv->ds, interface);
> +               if (ret)
> +                       return ret;
> 
> So now the error checks cause mt7530_mac_config() to return an error
> which in turn causes mt753x_mac_config() to fail, and therefore
> mt753x_phylink_mac_config() has different behaviour.
> 
> So, patch 2 changes the driver behaviour in the case of a 20MHz XTAL,
> which is then changed again by patch 4.
> 
> It would be better to have only one change of behaviour by moving
> patch 4 before patch 2.

If the idea is to not bring any more error returns to mt753x_mac_config()
because the return code is actually checked for that, I should do a bit
more effort and put patch 5 before patch 2 as well, to live up to what you
originally requested. Because, to get rid of all error returns on
mt7530_setup_port6(), both "net: dsa: mt7530: move XTAL check to
mt7530_setup()" and "net: dsa: mt7530: simplify mt7530_setup_port6() and
change to void" patches are needed. After these patches, I can move
mt7530_setup_port6() to mt7530_mac_config() and there won't be any error
returns being brought under mt753x_mac_config().

pw-bot: cr

Ar?n?


From ricardo at marliere.net  Sun Feb  4 07:56:44 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 04 Feb 2024 12:56:44 -0300
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
Message-ID: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>

Now that the driver core can properly handle constant struct bus_type,
move the sunxi_rsb_bus variable to be a constant structure as well,
placing it into read-only memory which can not be modified at runtime.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 drivers/bus/sunxi-rsb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
index fd3e9d82340a..1e29ba76615d 100644
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@@ -128,7 +128,7 @@ struct sunxi_rsb {
 };
 
 /* bus / slave device related functions */
-static struct bus_type sunxi_rsb_bus;
+static const struct bus_type sunxi_rsb_bus;
 
 static int sunxi_rsb_device_match(struct device *dev, struct device_driver *drv)
 {
@@ -177,7 +177,7 @@ static int sunxi_rsb_device_modalias(const struct device *dev, struct kobj_ueven
 	return of_device_uevent_modalias(dev, env);
 }
 
-static struct bus_type sunxi_rsb_bus = {
+static const struct bus_type sunxi_rsb_bus = {
 	.name		= RSB_CTRL_NAME,
 	.match		= sunxi_rsb_device_match,
 	.probe		= sunxi_rsb_device_probe,

---
base-commit: 38ed19495066966979ba821b9e0f549ad5ea620d
change-id: 20240204-bus_cleanup-bus-de90b25d7ce6

Best regards,
-- 
Ricardo B. Marliere <ricardo at marliere.net>



From andy.shevchenko at gmail.com  Sun Feb  4 08:32:27 2024
From: andy.shevchenko at gmail.com (andy.shevchenko at gmail.com)
Date: Sun, 4 Feb 2024 18:32:27 +0200
Subject: [PATCH v7 01/39] ARM: ep93xx: Add terminator to
 gpiod_lookup_table
In-Reply-To: <20240118-ep93xx-v7-1-d953846ae771@maquefel.me>
References: <20240118-ep93xx-v7-0-d953846ae771@maquefel.me>
 <20240118-ep93xx-v7-1-d953846ae771@maquefel.me>
Message-ID: <Zb-8G_Tgd7l4TCab@surfacebook.localdomain>

Thu, Jan 18, 2024 at 11:20:44AM +0300, Nikita Shubin kirjoitti:
> Without the terminator, if a con_id is passed to gpio_find() that
> does not exist in the lookup table the function will not stop looping
> correctly, and eventually cause an oops.
> 
> Fixes: b2e63555592f ("i2c: gpio: Convert to use descriptors")
> Reported-by: Andy Shevchenko <andriy.shevchenko at intel.com>

I prefer @linux.intel.com (sorry if I haven't used that one for the report).

Reviewed-by: Andy Shevchenko <andy.shevchenko at gmail.com>

-- 
With Best Regards,
Andy Shevchenko




From devnull+arinc.unal.arinc9.com at kernel.org  Sun Feb  4 08:34:20 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Sun, 04 Feb 2024 19:34:20 +0300
Subject: [PATCH net-next v4 2/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
References: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
Message-ID: <20240204-for-netnext-mt7530-improvements-2-v4-2-02bf0abaadb8@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

The crystal frequency concerns the switch core. The frequency should be
checked when the switch is being set up so the driver can reject the
unsupported hardware earlier and without requiring port 6 to be used.

Move it to mt7530_setup(). Drop the unnecessary function printing.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
---
 drivers/net/dsa/mt7530.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 330e22abc076..8b8469eba863 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -422,13 +422,6 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 
 	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
 
-	if (xtal == HWTRAP_XTAL_20MHZ) {
-		dev_err(priv->dev,
-			"%s: MT7530 with a 20MHz XTAL is not supported!\n",
-			__func__);
-		return -EINVAL;
-	}
-
 	switch (interface) {
 	case PHY_INTERFACE_MODE_RGMII:
 		trgint = 0;
@@ -2259,6 +2252,12 @@ mt7530_setup(struct dsa_switch *ds)
 		return -ENODEV;
 	}
 
+	if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_20MHZ) {
+		dev_err(priv->dev,
+			"MT7530 with a 20MHz XTAL is not supported!\n");
+		return -EINVAL;
+	}
+
 	/* Reset the switch through internal reset */
 	mt7530_write(priv, MT7530_SYS_CTRL,
 		     SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Sun Feb  4 08:34:24 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Sun, 04 Feb 2024 19:34:24 +0300
Subject: [PATCH net-next v4 6/7] net: dsa: mt7530: correct port
 capabilities of MT7988
In-Reply-To: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
References: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
Message-ID: <20240204-for-netnext-mt7530-improvements-2-v4-6-02bf0abaadb8@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

On the switch on the MT7988 SoC, as shown in Block Diagram 8.1.1.3 on page
125 of "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open
Version) v0.1", there are only 4 PHYs. That's port 0 to 3. Set the case for
ports which connect to switch PHYs to '0 ... 3'.

Port 4 and 5 are not used at all in this design.

Link: https://wiki.banana-pi.org/Banana_Pi_BPI-R4#Documents [1]
Acked-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 8a6312b3bb06..08d5d7dd5969 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2577,7 +2577,7 @@ static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 
 	switch (port) {
 	/* Ports which are connected to switch PHYs. There is no MII pinout. */
-	case 0 ... 4:
+	case 0 ... 3:
 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 			  config->supported_interfaces);
 		break;

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Sun Feb  4 08:34:21 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Sun, 04 Feb 2024 19:34:21 +0300
Subject: [PATCH net-next v4 3/7] net: dsa: mt7530: simplify
 mt7530_pad_clk_setup()
In-Reply-To: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
References: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
Message-ID: <20240204-for-netnext-mt7530-improvements-2-v4-3-02bf0abaadb8@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

This code is from before this driver was converted to phylink API. Phylink
deals with the unsupported interface cases before mt7530_pad_clk_setup() is
run. Therefore, the default case would never run. However, it must be
defined nonetheless to handle all the remaining enumeration values, the
phy-modes.

Switch to if statement for RGMII and return which simplifies the code and
saves an indent.

Set P6_INTF_MODE, which is the three least significant bits of the
MT7530_P6ECR register, to 0 for RGMII even though it will already be 0
after reset. This is to keep supporting dynamic reconfiguration of the port
in the case the interface changes from TRGMII to RGMII.

Disable the TRGMII clocks for all cases. They will be enabled if TRGMII is
being used.

Read XTAL after checking for RGMII as it's only needed for the TRGMII
interface mode.

Reviewed-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 91 +++++++++++++++++++++---------------------------
 1 file changed, 40 insertions(+), 51 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 8b8469eba863..82e90da1e52b 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -418,64 +418,53 @@ static int
 mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 {
 	struct mt7530_priv *priv = ds->priv;
-	u32 ncpo1, ssc_delta, trgint, xtal;
+	u32 ncpo1, ssc_delta, xtal;
 
-	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
+	/* Disable the MT7530 TRGMII clocks */
+	core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 
-	switch (interface) {
-	case PHY_INTERFACE_MODE_RGMII:
-		trgint = 0;
-		break;
-	case PHY_INTERFACE_MODE_TRGMII:
-		trgint = 1;
-		if (xtal == HWTRAP_XTAL_25MHZ)
-			ssc_delta = 0x57;
-		else
-			ssc_delta = 0x87;
-		if (priv->id == ID_MT7621) {
-			/* PLL frequency: 125MHz: 1.0GBit */
-			if (xtal == HWTRAP_XTAL_40MHZ)
-				ncpo1 = 0x0640;
-			if (xtal == HWTRAP_XTAL_25MHZ)
-				ncpo1 = 0x0a00;
-		} else { /* PLL frequency: 250MHz: 2.0Gbit */
-			if (xtal == HWTRAP_XTAL_40MHZ)
-				ncpo1 = 0x0c80;
-			if (xtal == HWTRAP_XTAL_25MHZ)
-				ncpo1 = 0x1400;
-		}
-		break;
-	default:
-		dev_err(priv->dev, "xMII interface %d not supported\n",
-			interface);
-		return -EINVAL;
+	if (interface == PHY_INTERFACE_MODE_RGMII) {
+		mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
+			   P6_INTF_MODE(0));
+		return;
 	}
 
-	mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
-		   P6_INTF_MODE(trgint));
+	mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
 
-	if (trgint) {
-		/* Disable the MT7530 TRGMII clocks */
-		core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
+	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
 
-		/* Setup the MT7530 TRGMII Tx Clock */
-		core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
-		core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
-		core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
-		core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
-		core_write(priv, CORE_PLL_GROUP4,
-			   RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN |
-			   RG_SYSPLL_BIAS_LPF_EN);
-		core_write(priv, CORE_PLL_GROUP2,
-			   RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
-			   RG_SYSPLL_POSDIV(1));
-		core_write(priv, CORE_PLL_GROUP7,
-			   RG_LCDDS_PCW_NCPO_CHG | RG_LCCDS_C(3) |
-			   RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
+	if (xtal == HWTRAP_XTAL_25MHZ)
+		ssc_delta = 0x57;
+	else
+		ssc_delta = 0x87;
 
-		/* Enable the MT7530 TRGMII clocks */
-		core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
-	}
+	if (priv->id == ID_MT7621) {
+		/* PLL frequency: 125MHz: 1.0GBit */
+		if (xtal == HWTRAP_XTAL_40MHZ)
+			ncpo1 = 0x0640;
+		if (xtal == HWTRAP_XTAL_25MHZ)
+			ncpo1 = 0x0a00;
+	} else { /* PLL frequency: 250MHz: 2.0Gbit */
+		if (xtal == HWTRAP_XTAL_40MHZ)
+			ncpo1 = 0x0c80;
+		if (xtal == HWTRAP_XTAL_25MHZ)
+			ncpo1 = 0x1400;
+	}
+
+	/* Setup the MT7530 TRGMII Tx Clock */
+	core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
+	core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
+	core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
+	core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
+	core_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN |
+		   RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
+	core_write(priv, CORE_PLL_GROUP2, RG_SYSPLL_EN_NORMAL |
+		   RG_SYSPLL_VODEN | RG_SYSPLL_POSDIV(1));
+	core_write(priv, CORE_PLL_GROUP7, RG_LCDDS_PCW_NCPO_CHG |
+		   RG_LCCDS_C(3) | RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
+
+	/* Enable the MT7530 TRGMII clocks */
+	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 
 	return 0;
 }

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Sun Feb  4 08:34:22 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Sun, 04 Feb 2024 19:34:22 +0300
Subject: [PATCH net-next v4 4/7] net: dsa: mt7530: call port 6 setup from
 mt7530_mac_config()
In-Reply-To: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
References: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
Message-ID: <20240204-for-netnext-mt7530-improvements-2-v4-4-02bf0abaadb8@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

mt7530_pad_clk_setup() is called if port 6 is enabled. It used to do more
things than setting up port 6. That part was moved to more appropriate
locations, mt7530_setup() and mt7530_pll_setup().

Now that all it does is set up port 6, rename it to mt7530_setup_port6(),
and move it to a more appropriate location, under mt7530_mac_config().

Change mt7530_setup_port6() to void as there're no error cases.

Leave an empty mt7530_pad_clk_setup() to satisfy the pad_setup function
pointer.

This is the code path for setting up the ports before:

dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
-> mt753x_mac_config()
   -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
      -> mt7530_setup_port5()
-> mt753x_pad_setup()
   -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()

This is after:

dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
-> mt753x_mac_config()
   -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
      -> mt7530_setup_port5()
      -> mt7530_setup_port6()

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 82e90da1e52b..18842c759b63 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -414,8 +414,8 @@ mt753x_preferred_default_local_cpu_port(struct dsa_switch *ds)
 }
 
 /* Setup port 6 interface mode and TRGMII TX circuit */
-static int
-mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
+static void
+mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
 {
 	struct mt7530_priv *priv = ds->priv;
 	u32 ncpo1, ssc_delta, xtal;
@@ -465,7 +465,11 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 
 	/* Enable the MT7530 TRGMII clocks */
 	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
+}
 
+static int
+mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
+{
 	return 0;
 }
 
@@ -2613,11 +2617,10 @@ mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 {
 	struct mt7530_priv *priv = ds->priv;
 
-	/* Only need to setup port5. */
-	if (port != 5)
-		return 0;
-
-	mt7530_setup_port5(priv->ds, interface);
+	if (port == 5) {
+		mt7530_setup_port5(priv->ds, interface);
+	else if (port == 6)
+		mt7530_setup_port6(priv->ds, interface);
 
 	return 0;
 }

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Sun Feb  4 08:34:25 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Sun, 04 Feb 2024 19:34:25 +0300
Subject: [PATCH net-next v4 7/7] net: dsa: mt7530: do not clear
 config->supported_interfaces
In-Reply-To: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
References: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
Message-ID: <20240204-for-netnext-mt7530-improvements-2-v4-7-02bf0abaadb8@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

There's no need to clear the config->supported_interfaces bitmap before
reporting the supported interfaces as all bits in the bitmap will already
be initialized to zero when the phylink_config structure is allocated. The
"config" pointer points to &dp->phylink_config, and "dp" is allocated by
dsa_port_touch() with kzalloc(), so all its fields are filled with zeroes.

There's no code that would change the bitmap beforehand. Remove it.

Acked-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 08d5d7dd5969..c7e1af1ea4bb 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2573,8 +2573,6 @@ static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
 static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 				     struct phylink_config *config)
 {
-	phy_interface_zero(config->supported_interfaces);
-
 	switch (port) {
 	/* Ports which are connected to switch PHYs. There is no MII pinout. */
 	case 0 ... 3:

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Sun Feb  4 08:34:18 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Sun, 04 Feb 2024 19:34:18 +0300
Subject: [PATCH net-next v4 0/7] MT7530 DSA Subdriver Improvements Act II
Message-ID: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>

Hello!

This is the second patch series with the goal of simplifying the MT7530 DSA
subdriver and improving support for MT7530, MT7531, and the switch on the
MT7988 SoC.

I have done a simple ping test to confirm basic communication on all switch
ports on MCM and standalone MT7530, and MT7531 switch with this patch
series applied.

MT7621 Unielec, MCM MT7530:

rgmii-only-gmac0-mt7621-unielec-u7621-06-16m.dtb
gmac0-and-gmac1-mt7621-unielec-u7621-06-16m.dtb

tftpboot 0x80008000 mips-uzImage.bin; tftpboot 0x83000000 mips-rootfs.cpio.uboot; tftpboot 0x83f00000 $dtb; bootm 0x80008000 0x83000000 0x83f00000

MT7622 Bananapi, MT7531:

gmac0-and-gmac1-mt7622-bananapi-bpi-r64.dtb

tftpboot 0x40000000 arm64-Image; tftpboot 0x45000000 arm64-rootfs.cpio.uboot; tftpboot 0x4a000000 $dtb; booti 0x40000000 0x45000000 0x4a000000

MT7623 Bananapi, standalone MT7530:

rgmii-only-gmac0-mt7623n-bananapi-bpi-r2.dtb
gmac0-and-gmac1-mt7623n-bananapi-bpi-r2.dtb

tftpboot 0x80008000 arm-zImage; tftpboot 0x83000000 arm-rootfs.cpio.uboot; tftpboot 0x83f00000 $dtb; bootz 0x80008000 0x83000000 0x83f00000

This patch series is the continuation of the patch series linked below.

https://lore.kernel.org/r/20230522121532.86610-1-arinc.unal at arinc9.com

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
Changes in v4:
- Update the patches with the latest received trailers.
- Leave no error returns on mt7530_pad_clk_setup() before renaming it to
  mt7530_setup_port6() and moving it to under mt7530_mac_config().
- Link to v3: https://lore.kernel.org/r/20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca at arinc9.com

Changes in v3:
- Update the patches with the latest received trailers.
- Patch 5
  - Disable TRGMII clocks for all cases.
- Link to v2: https://lore.kernel.org/r/20240130-for-netnext-mt7530-improvements-2-v2-0-ba06f5dd9eb0 at arinc9.com

Changes in v2:
- Update the patches with the latest received trailers.
- Remove 'net: dsa: mt7530: move enabling port 6 to mt7530_setup_port6()'
  which was patch 5. I will bring a more appropriate change with a later
  patch series.
- Patch 5
  - Set P6_INTF_MODE(0) and explain why on the patch log.
- Patch 6
  - Mention the MT7988 document and explain more on the patch log.
- Patch 7
  - Explain more on the patch log.
- Link to v1: https://lore.kernel.org/r/20240113102529.80371-1-arinc.unal at arinc9.com

---
Ar?n? ?NAL (7):
      net: dsa: mt7530: empty default case on mt7530_setup_port5()
      net: dsa: mt7530: move XTAL check to mt7530_setup()
      net: dsa: mt7530: simplify mt7530_pad_clk_setup()
      net: dsa: mt7530: call port 6 setup from mt7530_mac_config()
      net: dsa: mt7530: remove pad_setup function pointer
      net: dsa: mt7530: correct port capabilities of MT7988
      net: dsa: mt7530: do not clear config->supported_interfaces

 drivers/net/dsa/mt7530.c | 152 +++++++++++++++++------------------------------
 drivers/net/dsa/mt7530.h |   3 -
 2 files changed, 53 insertions(+), 102 deletions(-)
---
base-commit: 4acf4e62cd572b0c806035046b3698f5585ab821
change-id: 20240121-for-netnext-mt7530-improvements-2-b4f43661b485

Best regards,
-- 
Ar?n? ?NAL <arinc.unal at arinc9.com>



From devnull+arinc.unal.arinc9.com at kernel.org  Sun Feb  4 08:34:19 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Sun, 04 Feb 2024 19:34:19 +0300
Subject: [PATCH net-next v4 1/7] net: dsa: mt7530: empty default case on
 mt7530_setup_port5()
In-Reply-To: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
References: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
Message-ID: <20240204-for-netnext-mt7530-improvements-2-v4-1-02bf0abaadb8@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

There're two code paths for setting up port 5:

mt7530_setup()
-> mt7530_setup_port5()

mt753x_phylink_mac_config()
-> mt753x_mac_config()
   -> mt7530_mac_config()
      -> mt7530_setup_port5()

On the first code path, priv->p5_intf_sel is either set to
P5_INTF_SEL_PHY_P0 or P5_INTF_SEL_PHY_P4 when mt7530_setup_port5() is run.

On the second code path, priv->p5_intf_sel is set to P5_INTF_SEL_GMAC5 when
mt7530_setup_port5() is run.

Empty the default case which will never run but is needed nonetheless to
handle all the remaining enumeration values.

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 68be38ae66e0..330e22abc076 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -943,9 +943,7 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
 		val &= ~MHWTRAP_P5_DIS;
 		break;
 	default:
-		dev_err(ds->dev, "Unsupported p5_intf_sel %d\n",
-			priv->p5_intf_sel);
-		goto unlock_exit;
+		break;
 	}
 
 	/* Setup RGMII settings */
@@ -975,7 +973,6 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
 	dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
 		val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface));
 
-unlock_exit:
 	mutex_unlock(&priv->reg_mutex);
 }
 

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Sun Feb  4 08:34:23 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Sun, 04 Feb 2024 19:34:23 +0300
Subject: [PATCH net-next v4 5/7] net: dsa: mt7530: remove pad_setup
 function pointer
In-Reply-To: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
References: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
Message-ID: <20240204-for-netnext-mt7530-improvements-2-v4-5-02bf0abaadb8@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

The pad_setup function pointer was introduced with 88bdef8be9f6 ("net: dsa:
mt7530: Extend device data ready for adding a new hardware"). It was being
used to set up the core clock and port 6 of the MT7530 switch, and pll of
the MT7531 switch.

All of these were moved to more appropriate locations, and it was never
used for the switch on the MT7988 SoC. Therefore, this function pointer
hasn't got a use anymore. Remove it.

Acked-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 36 ++----------------------------------
 drivers/net/dsa/mt7530.h |  3 ---
 2 files changed, 2 insertions(+), 37 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 18842c759b63..8a6312b3bb06 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -467,18 +467,6 @@ mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
 	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 }
 
-static int
-mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
-{
-	return 0;
-}
-
-static int
-mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
-{
-	return 0;
-}
-
 static void
 mt7531_pll_setup(struct mt7530_priv *priv)
 {
@@ -2603,14 +2591,6 @@ static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 	}
 }
 
-static int
-mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
-{
-	struct mt7530_priv *priv = ds->priv;
-
-	return priv->info->pad_setup(ds, state->interface);
-}
-
 static int
 mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
@@ -2776,8 +2756,6 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		if (priv->p6_interface == state->interface)
 			break;
 
-		mt753x_pad_setup(ds, state);
-
 		if (mt753x_mac_config(ds, port, mode, state) < 0)
 			goto unsupported;
 
@@ -3095,11 +3073,6 @@ mt753x_conduit_state_change(struct dsa_switch *ds,
 	mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val);
 }
 
-static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
-{
-	return 0;
-}
-
 static int mt7988_setup(struct dsa_switch *ds)
 {
 	struct mt7530_priv *priv = ds->priv;
@@ -3163,7 +3136,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7530_phy_write_c22,
 		.phy_read_c45 = mt7530_phy_read_c45,
 		.phy_write_c45 = mt7530_phy_write_c45,
-		.pad_setup = mt7530_pad_clk_setup,
 		.mac_port_get_caps = mt7530_mac_port_get_caps,
 		.mac_port_config = mt7530_mac_config,
 	},
@@ -3175,7 +3147,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7530_phy_write_c22,
 		.phy_read_c45 = mt7530_phy_read_c45,
 		.phy_write_c45 = mt7530_phy_write_c45,
-		.pad_setup = mt7530_pad_clk_setup,
 		.mac_port_get_caps = mt7530_mac_port_get_caps,
 		.mac_port_config = mt7530_mac_config,
 	},
@@ -3187,7 +3158,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7531_ind_c22_phy_write,
 		.phy_read_c45 = mt7531_ind_c45_phy_read,
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
-		.pad_setup = mt7531_pad_setup,
 		.cpu_port_config = mt7531_cpu_port_config,
 		.mac_port_get_caps = mt7531_mac_port_get_caps,
 		.mac_port_config = mt7531_mac_config,
@@ -3200,7 +3170,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7531_ind_c22_phy_write,
 		.phy_read_c45 = mt7531_ind_c45_phy_read,
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
-		.pad_setup = mt7988_pad_setup,
 		.cpu_port_config = mt7988_cpu_port_config,
 		.mac_port_get_caps = mt7988_mac_port_get_caps,
 		.mac_port_config = mt7988_mac_config,
@@ -3230,9 +3199,8 @@ mt7530_probe_common(struct mt7530_priv *priv)
 	/* Sanity check if these required device operations are filled
 	 * properly.
 	 */
-	if (!priv->info->sw_setup || !priv->info->pad_setup ||
-	    !priv->info->phy_read_c22 || !priv->info->phy_write_c22 ||
-	    !priv->info->mac_port_get_caps ||
+	if (!priv->info->sw_setup || !priv->info->phy_read_c22 ||
+	    !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps ||
 	    !priv->info->mac_port_config)
 		return -EINVAL;
 
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 80060cc740d2..26a6d2160c08 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -704,8 +704,6 @@ struct mt753x_pcs {
  * @phy_write_c22:	Holding the way writing PHY port using C22
  * @phy_read_c45:	Holding the way reading PHY port using C45
  * @phy_write_c45:	Holding the way writing PHY port using C45
- * @pad_setup:		Holding the way setting up the bus pad for a certain
- *			MAC port
  * @phy_mode_supported:	Check if the PHY type is being supported on a certain
  *			port
  * @mac_port_validate:	Holding the way to set addition validate type for a
@@ -726,7 +724,6 @@ struct mt753x_info {
 			    int regnum);
 	int (*phy_write_c45)(struct mt7530_priv *priv, int port, int devad,
 			     int regnum, u16 val);
-	int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
 	int (*cpu_port_config)(struct dsa_switch *ds, int port);
 	void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
 				  struct phylink_config *config);

-- 
2.40.1



From linux at armlinux.org.uk  Sun Feb  4 08:38:37 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 4 Feb 2024 16:38:37 +0000
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <4fa2ff0d-2804-4a58-980f-162e62b3dc9c@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
 <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>
 <5b744f7f-2f63-4219-a0e9-8f08267b1fdd@arinc9.com>
 <Zb021ozEQSbU-gPd@makrotopia.org>
 <f6234b46-ce30-4b2a-9681-15633a06feff@arinc9.com>
 <Zb+ctEe9TVA3zhv8@shell.armlinux.org.uk>
 <4fa2ff0d-2804-4a58-980f-162e62b3dc9c@arinc9.com>
Message-ID: <Zb+9jQUqaha3Idsi@shell.armlinux.org.uk>

On Sun, Feb 04, 2024 at 06:55:14PM +0300, Ar?n? ?NAL wrote:
> On 4.02.2024 17:18, Russell King (Oracle) wrote:
> > On Sun, Feb 04, 2024 at 04:55:40PM +0300, Ar?n? ?NAL wrote:
> > > This is not about laziness. This is before patch 2:
> > > 
> > > phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
> > > -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
> > >     -> mt753x_mac_config()
> > >        -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
> > >           -> mt7530_setup_port5()
> > >     -> mt753x_pad_setup()
> > >        -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()
> > > 
> > > This is after:
> > > 
> > > phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
> > > -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
> > >     -> mt753x_mac_config()
> > >        -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
> > >           -> mt7530_setup_port5()
> > >           -> mt7530_setup_port6()
> > > 
> > > Patch 2 does not move mt7530_setup_port6() to be called from
> > > phylink_mac_ops :: mac_config(), it already is. There is no valid reason to
> > > reorder the patches.
> > > 
> > > My response to Russell should've stated this instead of focusing on his
> > > second sentence.
> > 
> > This patch moves the test for a 20MHz crystal to mt7530_setup(),
> > which is something that is entirely orthogonal to patch 2, which
> > can be done cleanly (I've just applied the patches in the original
> > order and then reordered them:
> > 
> > 98c481f5d706 net: dsa: mt7530: do not clear config->supported_interfaces
> > 93c6b53b17f4 net: dsa: mt7530: correct port capabilities of MT7988
> > c9c6d4c51a1d net: dsa: mt7530: simplify mt7530_setup_port6() and change to void
> > adfa948253e0 net: dsa: mt7530: remove pad_setup function pointer
> > 57e21e6c2fc0 net: dsa: mt7530: call port 6 setup from mt7530_mac_config()
> > 959a0f9323c8 net: dsa: mt7530: move XTAL check to mt7530_setup()
> > 856ab64a22ef net: dsa: mt7530: empty default case on mt7530_setup_port5()
> > 
> > No problems. The end result is identical comparing the git tree at the
> > original "move XTAL" patch with adfa948253e0.
> > 
> > Now, if we look at "net: dsa: mt7530: remove pad_setup function pointer"
> > we can see that yes, the pad_setup() method was called from mac_confing,
> > but this is the exact contents of that patch removing the callsite:
> > 
> > -               mt753x_pad_setup(ds, state);
> > 
> > This returns an integer, which may be an error code, which is ignored.
> > Therefore, if the XTAL frequency check fires, and mt753x_pad_setup()
> > returns an error, it is ignored today.
> > 
> > After "net: dsa: mt7530: call port 6 setup from mt7530_mac_config()"
> > the renamed pad_setup() method is now called from mac_config() thusly:
> > 
> > +               ret = mt7530_setup_port6(priv->ds, interface);
> > +               if (ret)
> > +                       return ret;
> > 
> > So now the error checks cause mt7530_mac_config() to return an error
> > which in turn causes mt753x_mac_config() to fail, and therefore
> > mt753x_phylink_mac_config() has different behaviour.
> > 
> > So, patch 2 changes the driver behaviour in the case of a 20MHz XTAL,
> > which is then changed again by patch 4.
> > 
> > It would be better to have only one change of behaviour by moving
> > patch 4 before patch 2.
> 
> If the idea is to not bring any more error returns to mt753x_mac_config()
> because the return code is actually checked for that, I should do a bit
> more effort and put patch 5 before patch 2 as well, to live up to what you
> originally requested.

I assume you are referring to getting rid of the default case in
mt7530_pad_clk_setup().

In patch "net: dsa: mt7530: call port 6 setup from mt7530_mac_config()"
where you move this to be called from mt7530_mac_config(), you add it
as:

+       } else if (port == 6) {
+               ret = mt7530_setup_port6(priv->ds, interface);
+               if (ret)
+                       return ret;
+       }

So it is only called for port 6. The switch within the called function
deals with PHY_INTERFACE_MODE_RGMII and PHY_INTERFACE_MODE_TRGMII.
Anything else results in the use of the default case, and thus
returning an error.

Since mt7530_mac_port_get_caps() does this for port 6:

                __set_bit(PHY_INTERFACE_MODE_RGMII,
                          config->supported_interfaces);
                __set_bit(PHY_INTERFACE_MODE_TRGMII,
                          config->supported_interfaces);

mt7530_setup_port6() will only ever be called for these two modes,
which means that the default case is unreachable, thus we will never
execute that path, thus whether that path returns an error or not is
completely irrelevant.

The only case in mt7530_setup_port6() / mt7530_pad_clk_setup() which
can today return an error is the XTAL check.

Therefore, my suggestion makes complete sense, and there is no need
to also move patch 5.

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


From arinc.unal at arinc9.com  Sun Feb  4 08:51:49 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Sun, 4 Feb 2024 19:51:49 +0300
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <Zb+9jQUqaha3Idsi@shell.armlinux.org.uk>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
 <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>
 <5b744f7f-2f63-4219-a0e9-8f08267b1fdd@arinc9.com>
 <Zb021ozEQSbU-gPd@makrotopia.org>
 <f6234b46-ce30-4b2a-9681-15633a06feff@arinc9.com>
 <Zb+ctEe9TVA3zhv8@shell.armlinux.org.uk>
 <4fa2ff0d-2804-4a58-980f-162e62b3dc9c@arinc9.com>
 <Zb+9jQUqaha3Idsi@shell.armlinux.org.uk>
Message-ID: <850064fb-59c6-4e07-962a-6a213e9e7f90@arinc9.com>

On 4.02.2024 19:38, Russell King (Oracle) wrote:
> On Sun, Feb 04, 2024 at 06:55:14PM +0300, Ar?n? ?NAL wrote:
>> On 4.02.2024 17:18, Russell King (Oracle) wrote:
>>> On Sun, Feb 04, 2024 at 04:55:40PM +0300, Ar?n? ?NAL wrote:
>>>> This is not about laziness. This is before patch 2:
>>>>
>>>> phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
>>>> -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
>>>>      -> mt753x_mac_config()
>>>>         -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
>>>>            -> mt7530_setup_port5()
>>>>      -> mt753x_pad_setup()
>>>>         -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()
>>>>
>>>> This is after:
>>>>
>>>> phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
>>>> -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
>>>>      -> mt753x_mac_config()
>>>>         -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
>>>>            -> mt7530_setup_port5()
>>>>            -> mt7530_setup_port6()
>>>>
>>>> Patch 2 does not move mt7530_setup_port6() to be called from
>>>> phylink_mac_ops :: mac_config(), it already is. There is no valid reason to
>>>> reorder the patches.
>>>>
>>>> My response to Russell should've stated this instead of focusing on his
>>>> second sentence.
>>>
>>> This patch moves the test for a 20MHz crystal to mt7530_setup(),
>>> which is something that is entirely orthogonal to patch 2, which
>>> can be done cleanly (I've just applied the patches in the original
>>> order and then reordered them:
>>>
>>> 98c481f5d706 net: dsa: mt7530: do not clear config->supported_interfaces
>>> 93c6b53b17f4 net: dsa: mt7530: correct port capabilities of MT7988
>>> c9c6d4c51a1d net: dsa: mt7530: simplify mt7530_setup_port6() and change to void
>>> adfa948253e0 net: dsa: mt7530: remove pad_setup function pointer
>>> 57e21e6c2fc0 net: dsa: mt7530: call port 6 setup from mt7530_mac_config()
>>> 959a0f9323c8 net: dsa: mt7530: move XTAL check to mt7530_setup()
>>> 856ab64a22ef net: dsa: mt7530: empty default case on mt7530_setup_port5()
>>>
>>> No problems. The end result is identical comparing the git tree at the
>>> original "move XTAL" patch with adfa948253e0.
>>>
>>> Now, if we look at "net: dsa: mt7530: remove pad_setup function pointer"
>>> we can see that yes, the pad_setup() method was called from mac_confing,
>>> but this is the exact contents of that patch removing the callsite:
>>>
>>> -               mt753x_pad_setup(ds, state);
>>>
>>> This returns an integer, which may be an error code, which is ignored.
>>> Therefore, if the XTAL frequency check fires, and mt753x_pad_setup()
>>> returns an error, it is ignored today.
>>>
>>> After "net: dsa: mt7530: call port 6 setup from mt7530_mac_config()"
>>> the renamed pad_setup() method is now called from mac_config() thusly:
>>>
>>> +               ret = mt7530_setup_port6(priv->ds, interface);
>>> +               if (ret)
>>> +                       return ret;
>>>
>>> So now the error checks cause mt7530_mac_config() to return an error
>>> which in turn causes mt753x_mac_config() to fail, and therefore
>>> mt753x_phylink_mac_config() has different behaviour.
>>>
>>> So, patch 2 changes the driver behaviour in the case of a 20MHz XTAL,
>>> which is then changed again by patch 4.
>>>
>>> It would be better to have only one change of behaviour by moving
>>> patch 4 before patch 2.
>>
>> If the idea is to not bring any more error returns to mt753x_mac_config()
>> because the return code is actually checked for that, I should do a bit
>> more effort and put patch 5 before patch 2 as well, to live up to what you
>> originally requested.
> 
> I assume you are referring to getting rid of the default case in
> mt7530_pad_clk_setup().
> 
> In patch "net: dsa: mt7530: call port 6 setup from mt7530_mac_config()"
> where you move this to be called from mt7530_mac_config(), you add it
> as:
> 
> +       } else if (port == 6) {
> +               ret = mt7530_setup_port6(priv->ds, interface);
> +               if (ret)
> +                       return ret;
> +       }
> 
> So it is only called for port 6. The switch within the called function
> deals with PHY_INTERFACE_MODE_RGMII and PHY_INTERFACE_MODE_TRGMII.
> Anything else results in the use of the default case, and thus
> returning an error.
> 
> Since mt7530_mac_port_get_caps() does this for port 6:
> 
>                  __set_bit(PHY_INTERFACE_MODE_RGMII,
>                            config->supported_interfaces);
>                  __set_bit(PHY_INTERFACE_MODE_TRGMII,
>                            config->supported_interfaces);
> 
> mt7530_setup_port6() will only ever be called for these two modes,
> which means that the default case is unreachable, thus we will never
> execute that path, thus whether that path returns an error or not is
> completely irrelevant.
> 
> The only case in mt7530_setup_port6() / mt7530_pad_clk_setup() which
> can today return an error is the XTAL check.
> 
> Therefore, my suggestion makes complete sense, and there is no need
> to also move patch 5.

Understood. I've already submitted v4 which moves patch 5. The remaining
benefit is that there're fewer code changes as I don't need to add an error
return for mt7530_setup_port6() and then remove it.

Ar?n?


From wahrenst at gmx.net  Sun Feb  4 08:58:51 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Sun,  4 Feb 2024 17:58:51 +0100
Subject: [PATCH RFC 1/2] pinctrl: bcm2835: Implement bcm2835_pinconf_get
In-Reply-To: <20240204165852.166157-1-wahrenst@gmx.net>
References: <20240204165852.166157-1-wahrenst@gmx.net>
Message-ID: <20240204165852.166157-2-wahrenst@gmx.net>

Even the driver already has implemented pin_dbg_show, it could
be helpful to implement pin_conf_get for a more generic behavior.
Contrary to the BCM2711, the BCM2835 SOC doesn't allow to read
the bias config, so the implementation is limited to the basics.

Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 35 ++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 1489191a213f..b37c86ec6915 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -1003,7 +1003,40 @@ static const struct pinmux_ops bcm2835_pmx_ops = {
 static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev,
 			unsigned pin, unsigned long *config)
 {
-	/* No way to read back config in HW */
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, pin);
+	u32 val;
+
+	/* No way to read back bias config in HW */
+
+	switch (param) {
+	case PIN_CONFIG_INPUT_ENABLE:
+		if (fsel != BCM2835_FSEL_GPIO_IN)
+			return -EINVAL;
+
+		*config = pinconf_to_config_packed(param, 1);
+		return 0;
+
+	case PIN_CONFIG_OUTPUT_ENABLE:
+		if (fsel != BCM2835_FSEL_GPIO_OUT)
+			return -EINVAL;
+
+		*config = pinconf_to_config_packed(param, 1);
+		return 0;
+
+	case PIN_CONFIG_OUTPUT:
+		if (fsel != BCM2835_FSEL_GPIO_OUT)
+			return -EINVAL;
+
+		val = bcm2835_gpio_get_bit(pc, GPLEV0, pin);
+		*config = pinconf_to_config_packed(param, val);
+		return 0;
+
+	default:
+		break;
+	}
+
 	return -ENOTSUPP;
 }

--
2.34.1



From wahrenst at gmx.net  Sun Feb  4 08:58:50 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Sun,  4 Feb 2024 17:58:50 +0100
Subject: [PATCH RFC 0/2] pinctrl: bcm2835: Implement pin_conf_get
Message-ID: <20240204165852.166157-1-wahrenst@gmx.net>

For years, the Raspberry Pi users relied on userspace programs to read
the pin configuration. In the meantime, it has become apparent that this
approach has reached its limits for various reasons.

This patch series now attempts to improve the debugging possibilities on
the kernel side in order to reduce the dependency on these userspace
programs.

Stefan Wahren (2):
  pinctrl: bcm2835: Implement bcm2835_pinconf_get
  pinctrl: bcm2835: Implement bcm2711_pinconf_get

 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 78 ++++++++++++++++++++++++++-
 1 file changed, 76 insertions(+), 2 deletions(-)

--
2.34.1



From wahrenst at gmx.net  Sun Feb  4 08:58:52 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Sun,  4 Feb 2024 17:58:52 +0100
Subject: [PATCH RFC 2/2] pinctrl: bcm2835: Implement bcm2711_pinconf_get
In-Reply-To: <20240204165852.166157-1-wahrenst@gmx.net>
References: <20240204165852.166157-1-wahrenst@gmx.net>
Message-ID: <20240204165852.166157-3-wahrenst@gmx.net>

The BCM2711 allows to read the bias config. So implement pin_conf_get
accordingly. The pull resistor values has been taken from the CM4
datasheet.

This implementation assumes that BCM7211 behaves the same way.

Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 43 ++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index b37c86ec6915..fcb9ab6729c0 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -1112,6 +1112,47 @@ static const struct pinconf_ops bcm2835_pinconf_ops = {
 	.pin_config_set = bcm2835_pinconf_set,
 };

+static int bcm2711_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
+			       unsigned long *config)
+{
+	struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	u32 offset, shift, val;
+
+	offset = PUD_2711_REG_OFFSET(pin);
+	shift = PUD_2711_REG_SHIFT(pin);
+	val = bcm2835_gpio_rd(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (offset * 4));
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (((val >> shift) & PUD_2711_MASK) == BCM2711_PULL_NONE)
+			return 0;
+		else
+			return -EINVAL;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (((val >> shift) & PUD_2711_MASK) == BCM2711_PULL_UP) {
+			*config = pinconf_to_config_packed(param, 47000);
+			return 0;
+		} else {
+			return -EINVAL;
+		}
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (((val >> shift) & PUD_2711_MASK) == BCM2711_PULL_DOWN) {
+			*config = pinconf_to_config_packed(param, 47000);
+			return 0;
+		} else {
+			return -EINVAL;
+		}
+
+	default:
+		break;
+	}
+
+	return bcm2835_pinconf_get(pctldev, pin, config);
+}
+
 static void bcm2711_pull_config_set(struct bcm2835_pinctrl *pc,
 				    unsigned int pin, unsigned int arg)
 {
@@ -1179,7 +1220,7 @@ static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev,

 static const struct pinconf_ops bcm2711_pinconf_ops = {
 	.is_generic = true,
-	.pin_config_get = bcm2835_pinconf_get,
+	.pin_config_get = bcm2711_pinconf_get,
 	.pin_config_set = bcm2711_pinconf_set,
 };

--
2.34.1



From florian.fainelli at broadcom.com  Sun Feb  4 09:04:46 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Sun, 4 Feb 2024 09:04:46 -0800
Subject: [PATCH 06/12] dmaengine: bcm2835: Use to_bcm2711_cbaddr where
 relevant
In-Reply-To: <b8962397fa4e77f6f82067c44bcf89e70050d4d4.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
 <b8962397fa4e77f6f82067c44bcf89e70050d4d4.1706948717.git.andrea.porta@suse.com>
Message-ID: <04fa6114-3394-4e1e-84b8-9552f3ec398d@broadcom.com>



On 2/3/2024 10:59 PM, 'Andrea della Porta' via 
BCM-KERNEL-FEEDBACK-LIST,PDL wrote:
> From: Maxime Ripard <maxime at cerno.tech>
> 
> bcm2711_dma40_memcpy has some code strictly equivalent to the
> to_bcm2711_cbaddr() function. Let's use it instead.
> 
> Signed-off-by: Maxime Ripard <maxime at cerno.tech>

Where is the full patch series?
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240204/caaa9390/attachment.p7s>

From linux at armlinux.org.uk  Sun Feb  4 09:07:49 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 4 Feb 2024 17:07:49 +0000
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <850064fb-59c6-4e07-962a-6a213e9e7f90@arinc9.com>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
 <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>
 <5b744f7f-2f63-4219-a0e9-8f08267b1fdd@arinc9.com>
 <Zb021ozEQSbU-gPd@makrotopia.org>
 <f6234b46-ce30-4b2a-9681-15633a06feff@arinc9.com>
 <Zb+ctEe9TVA3zhv8@shell.armlinux.org.uk>
 <4fa2ff0d-2804-4a58-980f-162e62b3dc9c@arinc9.com>
 <Zb+9jQUqaha3Idsi@shell.armlinux.org.uk>
 <850064fb-59c6-4e07-962a-6a213e9e7f90@arinc9.com>
Message-ID: <Zb/EZSqwChexAuso@shell.armlinux.org.uk>

On Sun, Feb 04, 2024 at 07:51:49PM +0300, Ar?n? ?NAL wrote:
> On 4.02.2024 19:38, Russell King (Oracle) wrote:
> > On Sun, Feb 04, 2024 at 06:55:14PM +0300, Ar?n? ?NAL wrote:
> > > On 4.02.2024 17:18, Russell King (Oracle) wrote:
> > > > On Sun, Feb 04, 2024 at 04:55:40PM +0300, Ar?n? ?NAL wrote:
> > > > > This is not about laziness. This is before patch 2:
> > > > > 
> > > > > phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
> > > > > -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
> > > > >      -> mt753x_mac_config()
> > > > >         -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
> > > > >            -> mt7530_setup_port5()
> > > > >      -> mt753x_pad_setup()
> > > > >         -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()
> > > > > 
> > > > > This is after:
> > > > > 
> > > > > phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
> > > > > -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
> > > > >      -> mt753x_mac_config()
> > > > >         -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
> > > > >            -> mt7530_setup_port5()
> > > > >            -> mt7530_setup_port6()
> > > > > 
> > > > > Patch 2 does not move mt7530_setup_port6() to be called from
> > > > > phylink_mac_ops :: mac_config(), it already is. There is no valid reason to
> > > > > reorder the patches.
> > > > > 
> > > > > My response to Russell should've stated this instead of focusing on his
> > > > > second sentence.
> > > > 
> > > > This patch moves the test for a 20MHz crystal to mt7530_setup(),
> > > > which is something that is entirely orthogonal to patch 2, which
> > > > can be done cleanly (I've just applied the patches in the original
> > > > order and then reordered them:
> > > > 
> > > > 98c481f5d706 net: dsa: mt7530: do not clear config->supported_interfaces
> > > > 93c6b53b17f4 net: dsa: mt7530: correct port capabilities of MT7988
> > > > c9c6d4c51a1d net: dsa: mt7530: simplify mt7530_setup_port6() and change to void
> > > > adfa948253e0 net: dsa: mt7530: remove pad_setup function pointer
> > > > 57e21e6c2fc0 net: dsa: mt7530: call port 6 setup from mt7530_mac_config()
> > > > 959a0f9323c8 net: dsa: mt7530: move XTAL check to mt7530_setup()
> > > > 856ab64a22ef net: dsa: mt7530: empty default case on mt7530_setup_port5()
> > > > 
> > > > No problems. The end result is identical comparing the git tree at the
> > > > original "move XTAL" patch with adfa948253e0.
> > > > 
> > > > Now, if we look at "net: dsa: mt7530: remove pad_setup function pointer"
> > > > we can see that yes, the pad_setup() method was called from mac_confing,
> > > > but this is the exact contents of that patch removing the callsite:
> > > > 
> > > > -               mt753x_pad_setup(ds, state);
> > > > 
> > > > This returns an integer, which may be an error code, which is ignored.
> > > > Therefore, if the XTAL frequency check fires, and mt753x_pad_setup()
> > > > returns an error, it is ignored today.
> > > > 
> > > > After "net: dsa: mt7530: call port 6 setup from mt7530_mac_config()"
> > > > the renamed pad_setup() method is now called from mac_config() thusly:
> > > > 
> > > > +               ret = mt7530_setup_port6(priv->ds, interface);
> > > > +               if (ret)
> > > > +                       return ret;
> > > > 
> > > > So now the error checks cause mt7530_mac_config() to return an error
> > > > which in turn causes mt753x_mac_config() to fail, and therefore
> > > > mt753x_phylink_mac_config() has different behaviour.
> > > > 
> > > > So, patch 2 changes the driver behaviour in the case of a 20MHz XTAL,
> > > > which is then changed again by patch 4.
> > > > 
> > > > It would be better to have only one change of behaviour by moving
> > > > patch 4 before patch 2.
> > > 
> > > If the idea is to not bring any more error returns to mt753x_mac_config()
> > > because the return code is actually checked for that, I should do a bit
> > > more effort and put patch 5 before patch 2 as well, to live up to what you
> > > originally requested.
> > 
> > I assume you are referring to getting rid of the default case in
> > mt7530_pad_clk_setup().
> > 
> > In patch "net: dsa: mt7530: call port 6 setup from mt7530_mac_config()"
> > where you move this to be called from mt7530_mac_config(), you add it
> > as:
> > 
> > +       } else if (port == 6) {
> > +               ret = mt7530_setup_port6(priv->ds, interface);
> > +               if (ret)
> > +                       return ret;
> > +       }
> > 
> > So it is only called for port 6. The switch within the called function
> > deals with PHY_INTERFACE_MODE_RGMII and PHY_INTERFACE_MODE_TRGMII.
> > Anything else results in the use of the default case, and thus
> > returning an error.
> > 
> > Since mt7530_mac_port_get_caps() does this for port 6:
> > 
> >                  __set_bit(PHY_INTERFACE_MODE_RGMII,
> >                            config->supported_interfaces);
> >                  __set_bit(PHY_INTERFACE_MODE_TRGMII,
> >                            config->supported_interfaces);
> > 
> > mt7530_setup_port6() will only ever be called for these two modes,
> > which means that the default case is unreachable, thus we will never
> > execute that path, thus whether that path returns an error or not is
> > completely irrelevant.
> > 
> > The only case in mt7530_setup_port6() / mt7530_pad_clk_setup() which
> > can today return an error is the XTAL check.
> > 
> > Therefore, my suggestion makes complete sense, and there is no need
> > to also move patch 5.
> 
> Understood. I've already submitted v4 which moves patch 5. The remaining
> benefit is that there're fewer code changes as I don't need to add an error
> return for mt7530_setup_port6() and then remove it.

I'm pretty sure netdev has a rule _not_ to submit the next version of
a patch series if discussion about the previous is still ongoing...
but I can't find any of the netdev rules in Documentation/networking
anymore, and nothing stands out in Documentation/process... ah,
Documentation/process/maintainer-netdev.rst, and here we are:

"Make sure you address all the feedback in your new posting. Do not post
a new
version of the code if the discussion about the previous version is
still
ongoing, unless directly instructed by a reviewer."

Discussion was still ongoing over this point, so ideally you should
have waited instead of presenting a fait-accompli _during_ the
ongoing discussion.

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


From arinc.unal at arinc9.com  Sun Feb  4 09:14:27 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Sun, 4 Feb 2024 20:14:27 +0300
Subject: [PATCH net-next v3 4/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <Zb/EZSqwChexAuso@shell.armlinux.org.uk>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-4-63d5adae99ca@arinc9.com>
 <ZbzWpmZrukknMsYf@shell.armlinux.org.uk>
 <5b744f7f-2f63-4219-a0e9-8f08267b1fdd@arinc9.com>
 <Zb021ozEQSbU-gPd@makrotopia.org>
 <f6234b46-ce30-4b2a-9681-15633a06feff@arinc9.com>
 <Zb+ctEe9TVA3zhv8@shell.armlinux.org.uk>
 <4fa2ff0d-2804-4a58-980f-162e62b3dc9c@arinc9.com>
 <Zb+9jQUqaha3Idsi@shell.armlinux.org.uk>
 <850064fb-59c6-4e07-962a-6a213e9e7f90@arinc9.com>
 <Zb/EZSqwChexAuso@shell.armlinux.org.uk>
Message-ID: <24ce3ff9-22b3-4d5d-ade4-3b8521aeadfe@arinc9.com>

On 4.02.2024 20:07, Russell King (Oracle) wrote:
> On Sun, Feb 04, 2024 at 07:51:49PM +0300, Ar?n? ?NAL wrote:
>> On 4.02.2024 19:38, Russell King (Oracle) wrote:
>>> On Sun, Feb 04, 2024 at 06:55:14PM +0300, Ar?n? ?NAL wrote:
>>>> On 4.02.2024 17:18, Russell King (Oracle) wrote:
>>>>> On Sun, Feb 04, 2024 at 04:55:40PM +0300, Ar?n? ?NAL wrote:
>>>>>> This is not about laziness. This is before patch 2:
>>>>>>
>>>>>> phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
>>>>>> -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
>>>>>>       -> mt753x_mac_config()
>>>>>>          -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
>>>>>>             -> mt7530_setup_port5()
>>>>>>       -> mt753x_pad_setup()
>>>>>>          -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()
>>>>>>
>>>>>> This is after:
>>>>>>
>>>>>> phylink_mac_ops :: mac_config() -> dsa_port_phylink_mac_config()
>>>>>> -> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
>>>>>>       -> mt753x_mac_config()
>>>>>>          -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
>>>>>>             -> mt7530_setup_port5()
>>>>>>             -> mt7530_setup_port6()
>>>>>>
>>>>>> Patch 2 does not move mt7530_setup_port6() to be called from
>>>>>> phylink_mac_ops :: mac_config(), it already is. There is no valid reason to
>>>>>> reorder the patches.
>>>>>>
>>>>>> My response to Russell should've stated this instead of focusing on his
>>>>>> second sentence.
>>>>>
>>>>> This patch moves the test for a 20MHz crystal to mt7530_setup(),
>>>>> which is something that is entirely orthogonal to patch 2, which
>>>>> can be done cleanly (I've just applied the patches in the original
>>>>> order and then reordered them:
>>>>>
>>>>> 98c481f5d706 net: dsa: mt7530: do not clear config->supported_interfaces
>>>>> 93c6b53b17f4 net: dsa: mt7530: correct port capabilities of MT7988
>>>>> c9c6d4c51a1d net: dsa: mt7530: simplify mt7530_setup_port6() and change to void
>>>>> adfa948253e0 net: dsa: mt7530: remove pad_setup function pointer
>>>>> 57e21e6c2fc0 net: dsa: mt7530: call port 6 setup from mt7530_mac_config()
>>>>> 959a0f9323c8 net: dsa: mt7530: move XTAL check to mt7530_setup()
>>>>> 856ab64a22ef net: dsa: mt7530: empty default case on mt7530_setup_port5()
>>>>>
>>>>> No problems. The end result is identical comparing the git tree at the
>>>>> original "move XTAL" patch with adfa948253e0.
>>>>>
>>>>> Now, if we look at "net: dsa: mt7530: remove pad_setup function pointer"
>>>>> we can see that yes, the pad_setup() method was called from mac_confing,
>>>>> but this is the exact contents of that patch removing the callsite:
>>>>>
>>>>> -               mt753x_pad_setup(ds, state);
>>>>>
>>>>> This returns an integer, which may be an error code, which is ignored.
>>>>> Therefore, if the XTAL frequency check fires, and mt753x_pad_setup()
>>>>> returns an error, it is ignored today.
>>>>>
>>>>> After "net: dsa: mt7530: call port 6 setup from mt7530_mac_config()"
>>>>> the renamed pad_setup() method is now called from mac_config() thusly:
>>>>>
>>>>> +               ret = mt7530_setup_port6(priv->ds, interface);
>>>>> +               if (ret)
>>>>> +                       return ret;
>>>>>
>>>>> So now the error checks cause mt7530_mac_config() to return an error
>>>>> which in turn causes mt753x_mac_config() to fail, and therefore
>>>>> mt753x_phylink_mac_config() has different behaviour.
>>>>>
>>>>> So, patch 2 changes the driver behaviour in the case of a 20MHz XTAL,
>>>>> which is then changed again by patch 4.
>>>>>
>>>>> It would be better to have only one change of behaviour by moving
>>>>> patch 4 before patch 2.
>>>>
>>>> If the idea is to not bring any more error returns to mt753x_mac_config()
>>>> because the return code is actually checked for that, I should do a bit
>>>> more effort and put patch 5 before patch 2 as well, to live up to what you
>>>> originally requested.
>>>
>>> I assume you are referring to getting rid of the default case in
>>> mt7530_pad_clk_setup().
>>>
>>> In patch "net: dsa: mt7530: call port 6 setup from mt7530_mac_config()"
>>> where you move this to be called from mt7530_mac_config(), you add it
>>> as:
>>>
>>> +       } else if (port == 6) {
>>> +               ret = mt7530_setup_port6(priv->ds, interface);
>>> +               if (ret)
>>> +                       return ret;
>>> +       }
>>>
>>> So it is only called for port 6. The switch within the called function
>>> deals with PHY_INTERFACE_MODE_RGMII and PHY_INTERFACE_MODE_TRGMII.
>>> Anything else results in the use of the default case, and thus
>>> returning an error.
>>>
>>> Since mt7530_mac_port_get_caps() does this for port 6:
>>>
>>>                   __set_bit(PHY_INTERFACE_MODE_RGMII,
>>>                             config->supported_interfaces);
>>>                   __set_bit(PHY_INTERFACE_MODE_TRGMII,
>>>                             config->supported_interfaces);
>>>
>>> mt7530_setup_port6() will only ever be called for these two modes,
>>> which means that the default case is unreachable, thus we will never
>>> execute that path, thus whether that path returns an error or not is
>>> completely irrelevant.
>>>
>>> The only case in mt7530_setup_port6() / mt7530_pad_clk_setup() which
>>> can today return an error is the XTAL check.
>>>
>>> Therefore, my suggestion makes complete sense, and there is no need
>>> to also move patch 5.
>>
>> Understood. I've already submitted v4 which moves patch 5. The remaining
>> benefit is that there're fewer code changes as I don't need to add an error
>> return for mt7530_setup_port6() and then remove it.
> 
> I'm pretty sure netdev has a rule _not_ to submit the next version of
> a patch series if discussion about the previous is still ongoing...
> but I can't find any of the netdev rules in Documentation/networking
> anymore, and nothing stands out in Documentation/process... ah,
> Documentation/process/maintainer-netdev.rst, and here we are:
> 
> "Make sure you address all the feedback in your new posting. Do not post
> a new
> version of the code if the discussion about the previous version is
> still
> ongoing, unless directly instructed by a reviewer."
> 
> Discussion was still ongoing over this point, so ideally you should
> have waited instead of presenting a fait-accompli _during_ the
> ongoing discussion.

Thank you for bringing this to my attention. Next time I will be more
careful when deciding whether the discussion was over.

Ar?n?


From arinc.unal at arinc9.com  Sun Feb  4 10:03:12 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Sun, 4 Feb 2024 21:03:12 +0300
Subject: [PATCH net-next v4 3/7] net: dsa: mt7530: simplify
 mt7530_pad_clk_setup()
In-Reply-To: <20240204-for-netnext-mt7530-improvements-2-v4-3-02bf0abaadb8@arinc9.com>
References: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
 <20240204-for-netnext-mt7530-improvements-2-v4-3-02bf0abaadb8@arinc9.com>
Message-ID: <d8838049-b0f3-4531-8ae0-83a7a7f14526@arinc9.com>

On 4.02.2024 19:34, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> This code is from before this driver was converted to phylink API. Phylink
> deals with the unsupported interface cases before mt7530_pad_clk_setup() is
> run. Therefore, the default case would never run. However, it must be
> defined nonetheless to handle all the remaining enumeration values, the
> phy-modes.
> 
> Switch to if statement for RGMII and return which simplifies the code and
> saves an indent.
> 
> Set P6_INTF_MODE, which is the three least significant bits of the
> MT7530_P6ECR register, to 0 for RGMII even though it will already be 0
> after reset. This is to keep supporting dynamic reconfiguration of the port
> in the case the interface changes from TRGMII to RGMII.
> 
> Disable the TRGMII clocks for all cases. They will be enabled if TRGMII is
> being used.
> 
> Read XTAL after checking for RGMII as it's only needed for the TRGMII
> interface mode.
> 
> Reviewed-by: Daniel Golle <daniel at makrotopia.org>
> Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> ---
>   drivers/net/dsa/mt7530.c | 91 +++++++++++++++++++++---------------------------
>   1 file changed, 40 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index 8b8469eba863..82e90da1e52b 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -418,64 +418,53 @@ static int
>   mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
>   {
>   	struct mt7530_priv *priv = ds->priv;
> -	u32 ncpo1, ssc_delta, trgint, xtal;
> +	u32 ncpo1, ssc_delta, xtal;
>   
> -	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
> +	/* Disable the MT7530 TRGMII clocks */
> +	core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
>   
> -	switch (interface) {
> -	case PHY_INTERFACE_MODE_RGMII:
> -		trgint = 0;
> -		break;
> -	case PHY_INTERFACE_MODE_TRGMII:
> -		trgint = 1;
> -		if (xtal == HWTRAP_XTAL_25MHZ)
> -			ssc_delta = 0x57;
> -		else
> -			ssc_delta = 0x87;
> -		if (priv->id == ID_MT7621) {
> -			/* PLL frequency: 125MHz: 1.0GBit */
> -			if (xtal == HWTRAP_XTAL_40MHZ)
> -				ncpo1 = 0x0640;
> -			if (xtal == HWTRAP_XTAL_25MHZ)
> -				ncpo1 = 0x0a00;
> -		} else { /* PLL frequency: 250MHz: 2.0Gbit */
> -			if (xtal == HWTRAP_XTAL_40MHZ)
> -				ncpo1 = 0x0c80;
> -			if (xtal == HWTRAP_XTAL_25MHZ)
> -				ncpo1 = 0x1400;
> -		}
> -		break;
> -	default:
> -		dev_err(priv->dev, "xMII interface %d not supported\n",
> -			interface);
> -		return -EINVAL;
> +	if (interface == PHY_INTERFACE_MODE_RGMII) {
> +		mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
> +			   P6_INTF_MODE(0));
> +		return;

This should be "return 0;". I will address this.

pw-bot: cr

Ar?n?


From arinc.unal at arinc9.com  Sun Feb  4 10:10:04 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Sun, 4 Feb 2024 21:10:04 +0300
Subject: [PATCH net-next v4 4/7] net: dsa: mt7530: call port 6 setup from
 mt7530_mac_config()
In-Reply-To: <20240204-for-netnext-mt7530-improvements-2-v4-4-02bf0abaadb8@arinc9.com>
References: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
 <20240204-for-netnext-mt7530-improvements-2-v4-4-02bf0abaadb8@arinc9.com>
Message-ID: <e7371ff0-0c45-4c41-8baa-31cef01fbf0d@arinc9.com>

On 4.02.2024 19:34, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> mt7530_pad_clk_setup() is called if port 6 is enabled. It used to do more
> things than setting up port 6. That part was moved to more appropriate
> locations, mt7530_setup() and mt7530_pll_setup().
> 
> Now that all it does is set up port 6, rename it to mt7530_setup_port6(),
> and move it to a more appropriate location, under mt7530_mac_config().
> 
> Change mt7530_setup_port6() to void as there're no error cases.
> 
> Leave an empty mt7530_pad_clk_setup() to satisfy the pad_setup function
> pointer.
> 
> This is the code path for setting up the ports before:
> 
> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
> -> mt753x_mac_config()
>     -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
>        -> mt7530_setup_port5()
> -> mt753x_pad_setup()
>     -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()
> 
> This is after:
> 
> dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
> -> mt753x_mac_config()
>     -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
>        -> mt7530_setup_port5()
>        -> mt7530_setup_port6()
> 
> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
> Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> ---
>   drivers/net/dsa/mt7530.c | 17 ++++++++++-------
>   1 file changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index 82e90da1e52b..18842c759b63 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -414,8 +414,8 @@ mt753x_preferred_default_local_cpu_port(struct dsa_switch *ds)
>   }
>   
>   /* Setup port 6 interface mode and TRGMII TX circuit */
> -static int
> -mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
> +static void
> +mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
>   {
>   	struct mt7530_priv *priv = ds->priv;
>   	u32 ncpo1, ssc_delta, xtal;
> @@ -465,7 +465,11 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
>   
>   	/* Enable the MT7530 TRGMII clocks */
>   	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
> +}
>   
> +static int
> +mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
> +{
>   	return 0;
>   }
>   
> @@ -2613,11 +2617,10 @@ mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
>   {
>   	struct mt7530_priv *priv = ds->priv;
>   
> -	/* Only need to setup port5. */
> -	if (port != 5)
> -		return 0;
> -
> -	mt7530_setup_port5(priv->ds, interface);
> +	if (port == 5) {

Stray brace, will remove.

Ar?n?


From linus.walleij at linaro.org  Sun Feb  4 10:58:59 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 4 Feb 2024 19:58:59 +0100
Subject: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <DU0PR04MB9417CA6CF089B264112C32A088402@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20240121-pinctrl-scmi-v3-0-8d94ba79dca8@nxp.com>
 <f88d07ef-83b2-4d14-976a-6dbbd71e036f@oss.nxp.com> <CACRpkdYV=qYQ9qDUWYTLDAV1niay30gYH5S=zjfi31GpeY5o-A@mail.gmail.com>
 <DU0PR04MB9417A9074C5DC49AE689E65288432@DU0PR04MB9417.eurprd04.prod.outlook.com>
 <Zbt-QkWhz5d9P-v6@pluto> <DU0PR04MB9417CA6CF089B264112C32A088402@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <CACRpkdYCrbNB8wu4rO3Yx0qomxR3kTt0P7YH7kc2HPCbrgt=tg@mail.gmail.com>

On Sun, Feb 4, 2024 at 10:29?AM Peng Fan <peng.fan at nxp.com> wrote:

> Using generic pinconf means the firmware needs exporting groups/functions/pins
> and etc, the firmware design will be complicated and code size enlarged.

This is very much to the core of the problem isn't it?

So the argument is to save code effort and size in the firmware.

This reflects some of the reasoning behind the device tree bindings
that encode "magic numbers" in the DT nodes to mux and configure
pins. Often the argument is that it saves space and effort.

When the i.MX driver was first discussed it used the standard scheme actually.
Look at i.MX 53 for example:
https://lore.kernel.org/linux-kernel/1322999384-7886-2-git-send-email-b29396 at freescale.com/

Groups and functions! As strings!

Then the DT bindings were discussed back and forth between Dong
Aisheng (the original driver author), Sasha Hauer and Shawn Guo
before arriving at the fsl,pins scheme.

Back in the day I was pretty much clueless about device tree and
relied on others to review the bindings, which ended up like this:
Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt

This was in 2011/2012 so many things were not considered. It is
clear that this scheme with a number of integers that get poked into
registers is convenient for some DT authors, also pinctrl-single uses
this as well as I think Mediatek and maybe a few others.

Over the years I have come to regret it a bit, I think insisting on
groups and functions as strings is better for abstraction. And the point
of firmware is to abstract things so they work the same on all systems.

Yours,
Linus Walleij


From fancer.lancer at gmail.com  Sun Feb  4 12:33:12 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Sun, 4 Feb 2024 23:33:12 +0300
Subject: [PATCH net-next v2 1/6] net: stmmac: remove
 eee_enabled/eee_active in stmmac_ethtool_op_get_eee()
In-Reply-To: <E1rWbMs-002cCV-EE@rmk-PC.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
 <E1rWbMs-002cCV-EE@rmk-PC.armlinux.org.uk>
Message-ID: <ximzpxurwkawprzuxkfdczrtvzyzjsfhk4taz4pxbzbj5kg6lv@4nqiycwcrgcr>

On Sun, Feb 04, 2024 at 12:13:02PM +0000, Russell King (Oracle) wrote:
> stmmac_ethtool_op_get_eee() sets both eee_enabled and eee_active, and
> then goes on to call phylink_ethtool_get_eee().
> 
> phylink_ethtool_get_eee() will return -EOPNOTSUPP if there is no PHY
> present, otherwise calling phy_ethtool_get_eee() which in turn will call
> genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Thus, when there is no PHY, stmmac_ethtool_op_get_eee() will fail with
> -EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
> userspace. When there is a PHY, eee_enabled and eee_active will be
> overwritten by phylib, making the setting of these members in
> stmmac_ethtool_op_get_eee() entirely unnecessary.
> 
> Remove this code, thus simplifying stmmac_ethtool_op_get_eee().

Right. and AFAICS stmmac_priv::{eee_active,eee_enabled} will be in
sync with the ethtool_eee::{eee_active,eee_enabled} values since they
are basically determined by means of the genphy_c45_eee_is_active()
method too. But damn it wasn't that easy to figure out... Anyway
thanks for the patch:

Reviewed-by: Serge Semin <fancer.lancer at gmail.com>

-Serge(y)

> 
> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> index bbecb3b89535..411c3ac8cb17 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> @@ -859,8 +859,6 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev,
>  	if (!priv->dma_cap.eee)
>  		return -EOPNOTSUPP;
>  
> -	edata->eee_enabled = priv->eee_enabled;
> -	edata->eee_active = priv->eee_active;
>  	edata->tx_lpi_timer = priv->tx_lpi_timer;
>  	edata->tx_lpi_enabled = priv->tx_lpi_enabled;
>  
> -- 
> 2.30.2
> 
> 


From nathan at kernel.org  Sun Feb  4 12:55:49 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Sun, 4 Feb 2024 13:55:49 -0700
Subject: [PATCH 3/3] media: mediatek: vcodedc: Fix
 Wcast-function-type-strict warnings
In-Reply-To: <12d0c580-788d-4466-af8a-feb5ab3c6677@notapiano>
References: <20240128-fix-clang-warnings-v1-0-1d946013a421@chromium.org>
 <20240128-fix-clang-warnings-v1-3-1d946013a421@chromium.org>
 <20240201221654.GC2240065@dev-arch.thelio-3990X>
 <CABCJKudd3SUy3Qor7Tc0zyJsSAWy0PavbbBFALuWEpBa32pBCQ@mail.gmail.com>
 <5658ec37-868f-454d-a149-467e6de139cd@collabora.com>
 <12d0c580-788d-4466-af8a-feb5ab3c6677@notapiano>
Message-ID: <20240204205549.GA2892810@dev-fedora.aadp>

On Fri, Feb 02, 2024 at 03:15:46PM -0500, N?colas F. R. A. Prado wrote:
> On Fri, Feb 02, 2024 at 01:58:05PM +0100, AngeloGioacchino Del Regno wrote:
> > Il 01/02/24 23:25, Sami Tolvanen ha scritto:
> > > On Thu, Feb 1, 2024 at 10:17?PM Nathan Chancellor <nathan at kernel.org> wrote:
> > > > 
> > > > On Sun, Jan 28, 2024 at 02:12:22AM +0000, Ricardo Ribalda wrote:
> > > > > Building with LLVM=1 throws the following warning:
> > > > > drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c:38:32: warning: cast from 'mtk_vcodec_ipi_handler' (aka 'void (*)(void *, unsigned int, void *)') to 'ipi_handler_t' (aka 'void (*)(const void *, unsigned int, void *)') converts to incompatible function type [-Wcast-function-type-strict]
> > > > > 
> > > > > Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
> > > > 
> > > > I am not positive because I don't have any hardware to test this driver
> > > > but I suspect this patch is just hiding the warning without actually
> > > > addressing the issue that it is pointing out.
> > > 
> > > Agreed, this won't fix the issue. The correct solution is to drop the
> > > cast and change the handler type to match the pointer type (i.e. use
> > > const void* for the first argument).
> > > 
> > 
> > Even though I agree that the correct solution is to change the handler's type,
> > I think that having a test on the actual hardware done is still valuable.
> > 
> > We scheduled a job on KernelCI to test this commit on our integration kernel,
> > you'll get results for ChromeOS' tast decoders (MT8195 only) and Fluster tests
> > on MT8183/8186/8192/8195.
> > 
> > 
> > The results should be available in a couple of hours here, relative to
> > commit `49955a84129dbe1f94fedf729690efcf28513828` on our tree:
> > https://chromeos.kernelci.org/job/collabora-chromeos-kernel/branch/for-kernelci/
> > 
> > P.S.: If they don't, feel free to ping me or Nicolas (added to the loop) about it.
> 
> Hi,
> 
> the results are available at 
> 
> https://chromeos.kernelci.org/test/job/collabora-chromeos-kernel/branch/for-kernelci/kernel/v6.8-rc2-3109-g49955a84129d/
> 
> (You need to type "decoder" into the search bar to limit the results to only the
> decoder tests)
> 
> The only regressions I see are due to infrastructure error or broken test
> unrelated to this change (v4l2-decoder-conformance-h264-frext test on
> MT8195-Tomato, and cros-tast-decoder-v4l2-sl-h264 test on MT8183-Juniper)
> 
> Otherwise, all platforms (MT8183/8186/8192/8195) and video codecs
> (VP8/VP9/H264/H265/AV1) seem unaffected.
> 
> Note that these are GCC builds.

Thank you for running the tests to make sure this series does not
regress anything. If possible, it would be good to try and build with
LLVM and enable kernel Control Flow Integrity (kCFI, CONFIG_CFI_CLANG)
to see if my theory that this is currently broken is correct. I have
prebuilt LLVM toolchains on kernel.org but if it is too much of a
hassle, I would not worry about it.

https://mirrors.edge.kernel.org/pub/tools/llvm/

Cheers,
Nathan


From william.zhang at broadcom.com  Sun Feb  4 13:56:59 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Sun, 4 Feb 2024 13:56:59 -0800
Subject: [PATCH v4 03/12] dt-bindings: mtd: brcmnand: Add ecc strap
 property
In-Reply-To: <20240203-expenses-tarmac-c564bc7ae34f@spud>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
 <20240203002834.171462-4-william.zhang@broadcom.com>
 <20240203-expenses-tarmac-c564bc7ae34f@spud>
Message-ID: <dd043b05-6fc0-4a17-bf39-05368d430426@broadcom.com>



On 2/3/24 06:49, Conor Dooley wrote:
> On Fri, Feb 02, 2024 at 04:28:24PM -0800, William Zhang wrote:
>> Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
>> board boot strap for broadband board designs because they do not specify
>> ecc setting in dts but rather using the strap setting.
>>
>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>>
>> ---
>>
>> Changes in v4:
>> - Move ecc strap property to this separate patch and remove some
>> non-binding related text from the description
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>>   Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 8 ++++++++
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>> index d0168d55c73e..2599d902ec3a 100644
>> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>> @@ -147,6 +147,14 @@ patternProperties:
>>             layout.
>>           $ref: /schemas/types.yaml#/definitions/uint32
>>   
>> +      brcm,nand-ecc-use-strap:
>> +        description:
>> +          This flag indicates the ecc strength and spare area size should
>> +          be retrieved from the SoC NAND boot strap setting instead of
>> +          nand-ecc-strength and brcm,nand-oob-sector-size or auto detection.
> 
> I'm still on the fence about this being overly prescriptive about the
> operating systems behaviour. I think it would be good to say why the
> strap values are better than those explicitly provided in DT rather than
> just saying "these strap values should be used".
> 
This is a board/SoC design choice.  I wouldn't advise it as better 
choice as other board/SoC may not have that option. But definitively for 
BCMBCA SoC board design, it is better and much easier and convenient 
option than explicit dt setting. How about: This property provides a 
choice for retrieving ecc strength and spare area size from the SoC NAND 
boot strap setting. It is commonly used by the BCMBCA SoC board design.

>> +          This is commonly used by the BCMBCA SoC board design.
>> +        $ref: /schemas/types.yaml#/definitions/flag
>> +
>>       unevaluatedProperties: false
>>   
>>   allOf:
>> -- 
>> 2.37.3
>>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240204/352d3991/attachment-0001.p7s>

From fancer.lancer at gmail.com  Sun Feb  4 13:57:41 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Mon, 5 Feb 2024 00:57:41 +0300
Subject: [PATCH net] net: stmmac: xgmac: fix a typo of register name in
 DPP safety handling
In-Reply-To: <20240203053133.1129236-1-0x1207@gmail.com>
References: <20240203053133.1129236-1-0x1207@gmail.com>
Message-ID: <pn2xm3hecdo3vts7zfrpnd6xh4st6acobwlk6mzj4vvqeivcsl@5q6mrvgrmtti>

On Sat, Feb 03, 2024 at 01:31:33PM +0800, Furong Xu wrote:
> DDPP is copied from Synopsys Data book:
> 
> DDPP: Disable Data path Parity Protection.
>     When it is 0x0, Data path Parity Protection is enabled.
>     When it is 0x1, Data path Parity Protection is disabled.
> 
> The macro name should be XGMAC_DPP_DISABLE.

Thanks!

Reviewed-by: Serge Semin <fancer.lancer at gmail.com>

-Serge(y)

> 
> Fixes: 46eba193d04f ("net: stmmac: xgmac: fix handling of DPP safety error for DMA channels")
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h      | 2 +-
>  drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> index 5c67a3f89f08..6a2c7d22df1e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> @@ -304,7 +304,7 @@
>  #define XGMAC_TXCEIE			BIT(0)
>  #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
>  #define XGMAC_MTL_DPP_CONTROL		0x000010e0
> -#define XGMAC_DDPP_DISABLE		BIT(0)
> +#define XGMAC_DPP_DISABLE		BIT(0)
>  #define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
>  #define XGMAC_TQS			GENMASK(25, 16)
>  #define XGMAC_TQS_SHIFT			16
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> index 04d7c4dc2e35..323c57f03c93 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> @@ -928,7 +928,7 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
>  	/* 5. Enable Data Path Parity Protection */
>  	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
>  	/* already enabled by default, explicit enable it again */
> -	value &= ~XGMAC_DDPP_DISABLE;
> +	value &= ~XGMAC_DPP_DISABLE;
>  	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
>  
>  	return 0;
> -- 
> 2.34.1
> 


From jbx6244 at gmail.com  Sun Feb  4 15:16:43 2024
From: jbx6244 at gmail.com (Johan Jonker)
Date: Mon, 5 Feb 2024 00:16:43 +0100
Subject: [PATCH v1] arm64: dts: rockchip: rk3328: Drop interrupts property
 from pwm-rockchip nodes
Message-ID: <5551846d-62cd-4b72-94f4-07541e726c37@gmail.com>

The binding doesn't define interrupts and adding such a definition was
refused because it's unclear how they should ever be used and the
relevant registers are outside the PWM range. So drop them fixing
several dtbs_check warnings.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index a73234b11ff1..b6f045069ee2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -488,7 +488,6 @@ pwm2: pwm at ff1b0020 {
 	pwm3: pwm at ff1b0030 {
 		compatible = "rockchip,rk3328-pwm";
 		reg = <0x0 0xff1b0030 0x0 0x10>;
-		interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>;
 		clock-names = "pwm", "pclk";
 		pinctrl-names = "default";
--
2.39.2



From shawn.gsc at gmail.com  Sun Feb  4 15:51:34 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 07:51:34 +0800
Subject: [PATCH 1/2] arm64: dts: imx8mm-evk: Add PDM micphone sound card
 support
In-Reply-To: <1703136188-7222-1-git-send-email-shengjiu.wang@nxp.com>
References: <1703136188-7222-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <20240204235134.GA804317@dragon>

On Thu, Dec 21, 2023 at 01:23:07PM +0800, Shengjiu Wang wrote:
> Add PDM micphone sound card support, configure the pinmux.
> 
> This sound card supports recording sound from PDM micphone
> and convert the PDM format data to PCM data.
> 
> Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 34 +++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
> index b53104ed8919..9679786dac51 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
> @@ -151,6 +151,18 @@ simple-audio-card,codec {
>  			clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
>  		};
>  	};
> +
> +	sound-micfil {
> +		compatible = "fsl,imx-audio-card";
> +		model = "micfil-audio";

Have a newline between properties and child node.

> +		pri-dai-link {
> +			link-name = "micfil hifi";
> +			format = "i2s";

Ditto

Shawn

> +			cpu {
> +				sound-dai = <&micfil>;
> +			};
> +		};
> +	};
>  };
>  
>  &A53_0 {
> @@ -434,6 +446,16 @@ &lcdif {
>  	status = "okay";
>  };
>  
> +&micfil {
> +	#sound-dai-cells = <0>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_pdm>;
> +	assigned-clocks = <&clk IMX8MM_CLK_PDM>;
> +	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
> +	assigned-clock-rates = <196608000>;
> +	status = "okay";
> +};
> +
>  &mipi_csi {
>  	status = "okay";
>  
> @@ -636,6 +658,18 @@ MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5       0x41
>  		>;
>  	};
>  
> +	pinctrl_pdm: pdmgrp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK        0xd6
> +			MX8MM_IOMUXC_SAI5_RXC_PDM_CLK           0xd6
> +			MX8MM_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC     0xd6
> +			MX8MM_IOMUXC_SAI5_RXD0_PDM_DATA0        0xd6
> +			MX8MM_IOMUXC_SAI5_RXD1_PDM_DATA1        0xd6
> +			MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2        0xd6
> +			MX8MM_IOMUXC_SAI5_RXD3_PDM_DATA3        0xd6
> +		>;
> +	};
> +
>  	pinctrl_pmic: pmicirqgrp {
>  		fsl,pins = <
>  			MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x141
> -- 
> 2.34.1
> 


From fancer.lancer at gmail.com  Sun Feb  4 16:44:10 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Mon, 5 Feb 2024 03:44:10 +0300
Subject: [PATCH net-next v2 3/3] net: stmmac: Configure AXI on Tegra234
 MGBE
In-Reply-To: <20240202-stmmac-axi-config-v2-3-64eab2bab17b@nvidia.com>
References: <20240202-stmmac-axi-config-v2-0-64eab2bab17b@nvidia.com>
 <20240202-stmmac-axi-config-v2-3-64eab2bab17b@nvidia.com>
Message-ID: <uzzzxx3mv6yoslijhhzdzyossvcvi52jgbulza54uqh2wrm5kd@ddd5o56b2dhu>

On Fri, Feb 02, 2024 at 12:53:35PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding at nvidia.com>
> 
> Allow the device to use bursts and increase the maximum number of
> outstanding requests to improve performance. Measurements show an
> increase in throughput of around 5x on a 1 Gbps link.
> 
> Signed-off-by: Thierry Reding <treding at nvidia.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> index bab57d1675df..b6bfa48f279d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> @@ -199,6 +199,12 @@ static void mgbe_uphy_lane_bringup_serdes_down(struct net_device *ndev, void *mg
>  	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
>  }
>  
> +static const struct stmmac_axi tegra234_mgbe_axi = {
> +	.axi_wr_osr_lmt = 63,
> +	.axi_rd_osr_lmt = 63,
> +	.axi_blen = { 256, },
> +};
> +
>  static int tegra_mgbe_probe(struct platform_device *pdev)
>  {
>  	struct plat_stmmacenet_data *plat;
> @@ -284,6 +290,9 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
>  	if (err < 0)
>  		goto disable_clks;
>  
> +	/* setup default AXI configuration */
> +	res.axi = &tegra234_mgbe_axi;
> +
>  	plat = devm_stmmac_probe_config_dt(pdev, &res);
>  	if (IS_ERR(plat)) {
>  		err = PTR_ERR(plat);

The entire series can be converted to just a few lines of change:

 	plat = devm_stmmac_probe_config_dt(pdev, res.mac);
 	if (IS_ERR(plat)) {
 		err = PTR_ERR(plat);
 		goto disable_clks;
 	}
+
+	if (IS_ERR_OR_NULL(plat->axi)) {
+		plat->axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
+		if (!plat->axi) {
+			ret = -ENOMEM;
+			goto disable_clks;
+		}
+	} /* else memset plat->axi with zeros if you wish */
+
+	plat->axi->axi_wr_osr_lmt = 63;
+	plat->axi->axi_rd_osr_lmt = 63;
+	plat->axi->axi_blen[0] = 256;
 
 	plat->has_xgmac = 1;
 	plat->flags |= STMMAC_FLAG_TSO_EN;
 	plat->pmt = 1;

Please don't overcomplicate the already overcomplicated driver with a
functionality which can be reached by the default one. In this case
the easiest way is to let the generic code work and then
override/replace/fix/etc the retrieved values. Thus there won't be
need in adding the redundant functionality and keep the generic
DT-platform code a bit simpler to read.

-Serge(y)

> 
> -- 
> 2.43.0
> 
> 


From tzungbi at kernel.org  Sun Feb  4 17:37:29 2024
From: tzungbi at kernel.org (Tzung-Bi Shih)
Date: Mon, 5 Feb 2024 09:37:29 +0800
Subject: [PATCH v3 1/4] firmware: coreboot: Generate modalias uevent for
 devices
In-Reply-To: <20240117-coreboot-mod-defconfig-v3-1-049565a27bba@collabora.com>
References: <20240117-coreboot-mod-defconfig-v3-0-049565a27bba@collabora.com>
 <20240117-coreboot-mod-defconfig-v3-1-049565a27bba@collabora.com>
Message-ID: <ZcA72dyYd9ZR8k_J@google.com>

On Wed, Jan 17, 2024 at 04:03:22PM -0300, N?colas F. R. A. Prado wrote:
> Generate a modalias uevent for devices in the coreboot bus to allow
> userspace to automatically load the corresponding modules.
>
> [...]

Applied, thanks!

[1/4] firmware: coreboot: Generate modalias uevent for devices
      commit: c6b0a4ceb7c9d8bb014d2967c97c8c7cbf60b006


From peter.chen at kernel.org  Sun Feb  4 17:54:03 2024
From: peter.chen at kernel.org (Peter Chen)
Date: Mon, 5 Feb 2024 09:54:03 +0800
Subject: [PATCH v5 8/8] usb: chipidea: ci_hdrc_imx: align usb wakeup
 clock name with dt-bindings
In-Reply-To: <20240131114324.3722428-8-xu.yang_2@nxp.com>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-8-xu.yang_2@nxp.com>
Message-ID: <20240205015403.GA1200221@nchen-desktop>

On 24-01-31 19:43:24, Xu Yang wrote:
> The dt-bindings is going to use "usb_wakeup" as wakup clock name. This will
> align the change with dt-bindings.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v5:
>  - new patch
> ---
>  drivers/usb/chipidea/ci_hdrc_imx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
> index ae9a6a17ec6e..a17b6d619305 100644
> --- a/drivers/usb/chipidea/ci_hdrc_imx.c
> +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
> @@ -212,7 +212,7 @@ static int imx_get_clks(struct device *dev)
>  		/* Get wakeup clock. Not all of the platforms need to
>  		 * handle this clock. So make it optional.
>  		 */
> -		data->clk_wakeup = devm_clk_get_optional(dev, "usb_wakeup_clk");
> +		data->clk_wakeup = devm_clk_get_optional(dev, "usb_wakeup");
>  		if (IS_ERR(data->clk_wakeup))
>  			ret = dev_err_probe(dev, PTR_ERR(data->clk_wakeup),
>  					"Failed to get wakeup clk\n");
> -- 
> 2.34.1
> 

Acked-by: Peter Chen <peter.chen at kernel.org>

-- 

Thanks,
Peter Chen


From shengjiu.wang at nxp.com  Sun Feb  4 18:21:26 2024
From: shengjiu.wang at nxp.com (S.J. Wang)
Date: Mon, 5 Feb 2024 02:21:26 +0000
Subject: [PATCH 1/2] arm64: dts: imx8mm-evk: Add PDM micphone sound card
 support
In-Reply-To: <20240204235134.GA804317@dragon>
References: <1703136188-7222-1-git-send-email-shengjiu.wang@nxp.com>
 <20240204235134.GA804317@dragon>
Message-ID: <PA4PR04MB9248F03E085EDB1B1A5F414EE3472@PA4PR04MB9248.eurprd04.prod.outlook.com>

> > Add PDM micphone sound card support, configure the pinmux.
> >
> > This sound card supports recording sound from PDM micphone and
> convert
> > the PDM format data to PCM data.
> >
> > Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
> > ---
> >  arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 34
> > +++++++++++++++++++
> >  1 file changed, 34 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
> > index b53104ed8919..9679786dac51 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
> > @@ -151,6 +151,18 @@ simple-audio-card,codec {
> >                       clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
> >               };
> >       };
> > +
> > +     sound-micfil {
> > +             compatible = "fsl,imx-audio-card";
> > +             model = "micfil-audio";
> 
> Have a newline between properties and child node.
> 
> > +             pri-dai-link {
> > +                     link-name = "micfil hifi";
> > +                     format = "i2s";
> 
> Ditto
> 
Ok,  will update in v2.

Best regards
Wang shengjiu

> Shawn
> 
> > +                     cpu {
> > +                             sound-dai = <&micfil>;
> > +                     };
> > +             };
> > +     };
> >  };
> >
> >  &A53_0 {
> > @@ -434,6 +446,16 @@ &lcdif {
> >       status = "okay";
> >  };
> >
> > +&micfil {
> > +     #sound-dai-cells = <0>;
> > +     pinctrl-names = "default";
> > +     pinctrl-0 = <&pinctrl_pdm>;
> > +     assigned-clocks = <&clk IMX8MM_CLK_PDM>;
> > +     assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
> > +     assigned-clock-rates = <196608000>;
> > +     status = "okay";
> > +};
> > +
> >  &mipi_csi {
> >       status = "okay";
> >
> > @@ -636,6 +658,18 @@ MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5
> 0x41
> >               >;
> >       };
> >
> > +     pinctrl_pdm: pdmgrp {
> > +             fsl,pins = <
> > +                     MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK        0xd6
> > +                     MX8MM_IOMUXC_SAI5_RXC_PDM_CLK           0xd6
> > +                     MX8MM_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC     0xd6
> > +                     MX8MM_IOMUXC_SAI5_RXD0_PDM_DATA0        0xd6
> > +                     MX8MM_IOMUXC_SAI5_RXD1_PDM_DATA1        0xd6
> > +                     MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2        0xd6
> > +                     MX8MM_IOMUXC_SAI5_RXD3_PDM_DATA3        0xd6
> > +             >;
> > +     };
> > +
> >       pinctrl_pmic: pmicirqgrp {
> >               fsl,pins = <
> >                       MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3               0x141
> > --
> > 2.34.1
> >


From shengjiu.wang at nxp.com  Sun Feb  4 18:04:24 2024
From: shengjiu.wang at nxp.com (Shengjiu Wang)
Date: Mon,  5 Feb 2024 10:04:24 +0800
Subject: [PATCH v2 2/2] arm64: dts: imx8mn-evk: Add PDM micphone sound card support
In-Reply-To: <1707098664-23265-1-git-send-email-shengjiu.wang@nxp.com>
References: <1707098664-23265-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <1707098664-23265-2-git-send-email-shengjiu.wang@nxp.com>

Add PDM micphone sound card support, configure the pinmux.

This sound card supports recording sound from PDM micphone
and convert the PDM format data to PCM data.

Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
---
changes in v2:
- add newline between properties and child node

 arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
index a0e13d3324ed..269e70f66a13 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
@@ -110,6 +110,20 @@ sound-spdif {
 		spdif-out;
 		spdif-in;
 	};
+
+	sound-micfil {
+		compatible = "fsl,imx-audio-card";
+		model = "micfil-audio";
+
+		pri-dai-link {
+			link-name = "micfil hifi";
+			format = "i2s";
+
+			cpu {
+				sound-dai = <&micfil>;
+			};
+		};
+	};
 };
 
 &easrc {
@@ -285,6 +299,16 @@ &isi {
 	status = "okay";
 };
 
+&micfil {
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pdm>;
+	assigned-clocks = <&clk IMX8MN_CLK_PDM>;
+	assigned-clock-parents = <&clk IMX8MN_AUDIO_PLL1_OUT>;
+	assigned-clock-rates = <196608000>;
+	status = "okay";
+};
+
 &mipi_csi {
 	status = "okay";
 
@@ -522,6 +546,18 @@ MX8MN_IOMUXC_I2C3_SDA_GPIO5_IO19	0x1c3
 		>;
 	};
 
+	pinctrl_pdm: pdmgrp {
+		fsl,pins = <
+			MX8MN_IOMUXC_SAI5_MCLK_SAI5_MCLK	0xd6
+			MX8MN_IOMUXC_SAI5_RXC_PDM_CLK		0xd6
+			MX8MN_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC	0xd6
+			MX8MN_IOMUXC_SAI5_RXD0_PDM_BIT_STREAM0	0xd6
+			MX8MN_IOMUXC_SAI5_RXD1_PDM_BIT_STREAM1	0xd6
+			MX8MN_IOMUXC_SAI5_RXD2_PDM_BIT_STREAM2	0xd6
+			MX8MN_IOMUXC_SAI5_RXD3_PDM_BIT_STREAM3	0xd6
+		>;
+	};
+
 	pinctrl_pmic: pmicirqgrp {
 		fsl,pins = <
 			MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3	0x141
-- 
2.34.1



From shengjiu.wang at nxp.com  Sun Feb  4 18:04:23 2024
From: shengjiu.wang at nxp.com (Shengjiu Wang)
Date: Mon,  5 Feb 2024 10:04:23 +0800
Subject: [PATCH v2 1/2] arm64: dts: imx8mm-evk: Add PDM micphone sound card support
Message-ID: <1707098664-23265-1-git-send-email-shengjiu.wang@nxp.com>

Add PDM micphone sound card support, configure the pinmux.

This sound card supports recording sound from PDM micphone
and convert the PDM format data to PCM data.

Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
---
changes in v2:
- add newline between properties and child node

 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index b53104ed8919..9b39458f3fa5 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -151,6 +151,20 @@ simple-audio-card,codec {
 			clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
 		};
 	};
+
+	sound-micfil {
+		compatible = "fsl,imx-audio-card";
+		model = "micfil-audio";
+
+		pri-dai-link {
+			link-name = "micfil hifi";
+			format = "i2s";
+
+			cpu {
+				sound-dai = <&micfil>;
+			};
+		};
+	};
 };
 
 &A53_0 {
@@ -434,6 +448,16 @@ &lcdif {
 	status = "okay";
 };
 
+&micfil {
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pdm>;
+	assigned-clocks = <&clk IMX8MM_CLK_PDM>;
+	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+	assigned-clock-rates = <196608000>;
+	status = "okay";
+};
+
 &mipi_csi {
 	status = "okay";
 
@@ -636,6 +660,18 @@ MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5       0x41
 		>;
 	};
 
+	pinctrl_pdm: pdmgrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK        0xd6
+			MX8MM_IOMUXC_SAI5_RXC_PDM_CLK           0xd6
+			MX8MM_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC     0xd6
+			MX8MM_IOMUXC_SAI5_RXD0_PDM_DATA0        0xd6
+			MX8MM_IOMUXC_SAI5_RXD1_PDM_DATA1        0xd6
+			MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2        0xd6
+			MX8MM_IOMUXC_SAI5_RXD3_PDM_DATA3        0xd6
+		>;
+	};
+
 	pinctrl_pmic: pmicirqgrp {
 		fsl,pins = <
 			MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x141
-- 
2.34.1



From peng.fan at oss.nxp.com  Sun Feb  4 19:17:56 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 05 Feb 2024 11:17:56 +0800
Subject: [PATCH v4 0/3] clocksource: imx-sysctr: support i.MX95
Message-ID: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>

i.MX95 System Counter module control register space is blocked
by SCMI firmware, so we use Read Register space to get the counter.

V2:
  - imx95 is not compatible with the existing hardware, so add a
    seperate entry for i.MX95 in dt-binding.
  - Per Marco's comments, the global variables was removed except
    to_sysctr. And add a new TIMER_OF_DECLARE entry for i.MX95

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Changes in v4:
- Add A-b in patch 1
- Include slab.h in patch 2 to fix kernel build failure for i386 compile
test.
- Link to v3: https://lore.kernel.org/r/20240126-imx-sysctr-v3-0-33fe801d5f31 at nxp.com

Changes in v3:
- Drop items in patch 1 per Conor's comments
- Link to v2: https://lore.kernel.org/r/20240125-imx-sysctr-v2-0-7332470cd7ae at nxp.com

---
Peng Fan (3):
      dt-bindings: timer: nxp,sysctr-timer: support i.MX95
      clocksource/drivers/imx-sysctr: drop use global variables
      clocksource/drivers/imx-sysctr: support i.MX95

 .../bindings/timer/nxp,sysctr-timer.yaml           |   4 +-
 drivers/clocksource/timer-imx-sysctr.c             | 117 +++++++++++++++------
 2 files changed, 90 insertions(+), 31 deletions(-)
---
base-commit: 01af33cc9894b4489fb68fa35c40e9fe85df63dc
change-id: 20240125-imx-sysctr-3a89a0852376

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Sun Feb  4 19:17:57 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 05 Feb 2024 11:17:57 +0800
Subject: [PATCH v4 1/3] dt-bindings: timer: nxp,sysctr-timer: support
 i.MX95
In-Reply-To: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>
References: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>
Message-ID: <20240205-imx-sysctr-v4-1-ca5a6e1552e7@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add i.MX95 System counter module compatible string, the SCMI
firmware blocks access to control register, so should not
add "nxp,sysctr-timer" as fallback.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 Documentation/devicetree/bindings/timer/nxp,sysctr-timer.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/timer/nxp,sysctr-timer.yaml b/Documentation/devicetree/bindings/timer/nxp,sysctr-timer.yaml
index 2b9653dafab8..891cca009528 100644
--- a/Documentation/devicetree/bindings/timer/nxp,sysctr-timer.yaml
+++ b/Documentation/devicetree/bindings/timer/nxp,sysctr-timer.yaml
@@ -18,7 +18,9 @@ description: |
 
 properties:
   compatible:
-    const: nxp,sysctr-timer
+    enum:
+      - nxp,imx95-sysctr-timer
+      - nxp,sysctr-timer
 
   reg:
     maxItems: 1

-- 
2.37.1



From peng.fan at oss.nxp.com  Sun Feb  4 19:17:58 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 05 Feb 2024 11:17:58 +0800
Subject: [PATCH v4 2/3] clocksource/drivers/imx-sysctr: drop use global
 variables
In-Reply-To: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>
References: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>
Message-ID: <20240205-imx-sysctr-v4-2-ca5a6e1552e7@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Clean up code to not use global variables and introduce sysctr_private
structure to prepare the support for i.MX95.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/clocksource/timer-imx-sysctr.c | 76 ++++++++++++++++++++--------------
 1 file changed, 44 insertions(+), 32 deletions(-)

diff --git a/drivers/clocksource/timer-imx-sysctr.c b/drivers/clocksource/timer-imx-sysctr.c
index 5a7a951c4efc..c075ea89a214 100644
--- a/drivers/clocksource/timer-imx-sysctr.c
+++ b/drivers/clocksource/timer-imx-sysctr.c
@@ -4,6 +4,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/clockchips.h>
+#include <linux/slab.h>
 
 #include "timer-of.h"
 
@@ -20,32 +21,39 @@
 
 #define SYS_CTR_CLK_DIV		0x3
 
-static void __iomem *sys_ctr_base __ro_after_init;
-static u32 cmpcr __ro_after_init;
+struct sysctr_private {
+	u32 cmpcr;
+};
 
-static void sysctr_timer_enable(bool enable)
+static void sysctr_timer_enable(struct clock_event_device *evt, bool enable)
 {
-	writel(enable ? cmpcr | SYS_CTR_EN : cmpcr, sys_ctr_base + CMPCR);
+	struct timer_of *to = to_timer_of(evt);
+	struct sysctr_private *priv = to->private_data;
+	void __iomem *base = timer_of_base(to);
+
+	writel(enable ? priv->cmpcr | SYS_CTR_EN : priv->cmpcr, base + CMPCR);
 }
 
-static void sysctr_irq_acknowledge(void)
+static void sysctr_irq_acknowledge(struct clock_event_device *evt)
 {
 	/*
 	 * clear the enable bit(EN =0) will clear
 	 * the status bit(ISTAT = 0), then the interrupt
 	 * signal will be negated(acknowledged).
 	 */
-	sysctr_timer_enable(false);
+	sysctr_timer_enable(evt, false);
 }
 
-static inline u64 sysctr_read_counter(void)
+static inline u64 sysctr_read_counter(struct clock_event_device *evt)
 {
+	struct timer_of *to = to_timer_of(evt);
+	void __iomem *base = timer_of_base(to);
 	u32 cnt_hi, tmp_hi, cnt_lo;
 
 	do {
-		cnt_hi = readl_relaxed(sys_ctr_base + CNTCV_HI);
-		cnt_lo = readl_relaxed(sys_ctr_base + CNTCV_LO);
-		tmp_hi = readl_relaxed(sys_ctr_base + CNTCV_HI);
+		cnt_hi = readl_relaxed(base + CNTCV_HI);
+		cnt_lo = readl_relaxed(base + CNTCV_LO);
+		tmp_hi = readl_relaxed(base + CNTCV_HI);
 	} while (tmp_hi != cnt_hi);
 
 	return  ((u64) cnt_hi << 32) | cnt_lo;
@@ -54,22 +62,24 @@ static inline u64 sysctr_read_counter(void)
 static int sysctr_set_next_event(unsigned long delta,
 				 struct clock_event_device *evt)
 {
+	struct timer_of *to = to_timer_of(evt);
+	void __iomem *base = timer_of_base(to);
 	u32 cmp_hi, cmp_lo;
 	u64 next;
 
-	sysctr_timer_enable(false);
+	sysctr_timer_enable(evt, false);
 
-	next = sysctr_read_counter();
+	next = sysctr_read_counter(evt);
 
 	next += delta;
 
 	cmp_hi = (next >> 32) & 0x00fffff;
 	cmp_lo = next & 0xffffffff;
 
-	writel_relaxed(cmp_hi, sys_ctr_base + CMPCV_HI);
-	writel_relaxed(cmp_lo, sys_ctr_base + CMPCV_LO);
+	writel_relaxed(cmp_hi, base + CMPCV_HI);
+	writel_relaxed(cmp_lo, base + CMPCV_LO);
 
-	sysctr_timer_enable(true);
+	sysctr_timer_enable(evt, true);
 
 	return 0;
 }
@@ -81,7 +91,7 @@ static int sysctr_set_state_oneshot(struct clock_event_device *evt)
 
 static int sysctr_set_state_shutdown(struct clock_event_device *evt)
 {
-	sysctr_timer_enable(false);
+	sysctr_timer_enable(evt, false);
 
 	return 0;
 }
@@ -90,7 +100,7 @@ static irqreturn_t sysctr_timer_interrupt(int irq, void *dev_id)
 {
 	struct clock_event_device *evt = dev_id;
 
-	sysctr_irq_acknowledge();
+	sysctr_irq_acknowledge(evt);
 
 	evt->event_handler(evt);
 
@@ -117,34 +127,36 @@ static struct timer_of to_sysctr = {
 	},
 };
 
-static void __init sysctr_clockevent_init(void)
-{
-	to_sysctr.clkevt.cpumask = cpu_possible_mask;
-
-	clockevents_config_and_register(&to_sysctr.clkevt,
-					timer_of_rate(&to_sysctr),
-					0xff, 0x7fffffff);
-}
-
 static int __init sysctr_timer_init(struct device_node *np)
 {
-	int ret = 0;
+	struct sysctr_private *priv;
+	void __iomem *base;
+	int ret;
+
+	priv = kzalloc(sizeof(struct sysctr_private), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
 
 	ret = timer_of_init(np, &to_sysctr);
-	if (ret)
+	if (ret) {
+		kfree(priv);
 		return ret;
+	}
 
 	if (!of_property_read_bool(np, "nxp,no-divider")) {
 		/* system counter clock is divided by 3 internally */
 		to_sysctr.of_clk.rate /= SYS_CTR_CLK_DIV;
 	}
 
-	sys_ctr_base = timer_of_base(&to_sysctr);
-	cmpcr = readl(sys_ctr_base + CMPCR);
-	cmpcr &= ~SYS_CTR_EN;
+	to_sysctr.clkevt.cpumask = cpu_possible_mask;
+	to_sysctr.private_data = priv;
 
-	sysctr_clockevent_init();
+	base = timer_of_base(&to_sysctr);
+	priv->cmpcr = readl(base + CMPCR) & ~SYS_CTR_EN;
 
+	clockevents_config_and_register(&to_sysctr.clkevt,
+					timer_of_rate(&to_sysctr),
+					0xff, 0x7fffffff);
 	return 0;
 }
 TIMER_OF_DECLARE(sysctr_timer, "nxp,sysctr-timer", sysctr_timer_init);

-- 
2.37.1



From peng.fan at oss.nxp.com  Sun Feb  4 19:17:59 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 05 Feb 2024 11:17:59 +0800
Subject: [PATCH v4 3/3] clocksource/drivers/imx-sysctr: support i.MX95
In-Reply-To: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>
References: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>
Message-ID: <20240205-imx-sysctr-v4-3-ca5a6e1552e7@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

To i.MX95 System counter module, we use Read register space to get
the counter, not the Control register space to get the counter, because
System Manager firmware not allow Linux to read Control register space,
so add a new TIMER_OF_DECLARE entry for i.MX95.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/clocksource/timer-imx-sysctr.c | 53 +++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/clocksource/timer-imx-sysctr.c b/drivers/clocksource/timer-imx-sysctr.c
index c075ea89a214..44525813be1e 100644
--- a/drivers/clocksource/timer-imx-sysctr.c
+++ b/drivers/clocksource/timer-imx-sysctr.c
@@ -9,12 +9,15 @@
 #include "timer-of.h"
 
 #define CMP_OFFSET	0x10000
+#define RD_OFFSET	0x20000
 
 #define CNTCV_LO	0x8
 #define CNTCV_HI	0xc
 #define CMPCV_LO	(CMP_OFFSET + 0x20)
 #define CMPCV_HI	(CMP_OFFSET + 0x24)
 #define CMPCR		(CMP_OFFSET + 0x2c)
+#define CNTCV_LO_IMX95	(RD_OFFSET + 0x8)
+#define CNTCV_HI_IMX95	(RD_OFFSET + 0xc)
 
 #define SYS_CTR_EN		0x1
 #define SYS_CTR_IRQ_MASK	0x2
@@ -23,6 +26,8 @@
 
 struct sysctr_private {
 	u32 cmpcr;
+	u32 lo_off;
+	u32 hi_off;
 };
 
 static void sysctr_timer_enable(struct clock_event_device *evt, bool enable)
@@ -47,13 +52,14 @@ static void sysctr_irq_acknowledge(struct clock_event_device *evt)
 static inline u64 sysctr_read_counter(struct clock_event_device *evt)
 {
 	struct timer_of *to = to_timer_of(evt);
+	struct sysctr_private *priv = to->private_data;
 	void __iomem *base = timer_of_base(to);
 	u32 cnt_hi, tmp_hi, cnt_lo;
 
 	do {
-		cnt_hi = readl_relaxed(base + CNTCV_HI);
-		cnt_lo = readl_relaxed(base + CNTCV_LO);
-		tmp_hi = readl_relaxed(base + CNTCV_HI);
+		cnt_hi = readl_relaxed(base + priv->hi_off);
+		cnt_lo = readl_relaxed(base + priv->lo_off);
+		tmp_hi = readl_relaxed(base + priv->hi_off);
 	} while (tmp_hi != cnt_hi);
 
 	return  ((u64) cnt_hi << 32) | cnt_lo;
@@ -127,7 +133,7 @@ static struct timer_of to_sysctr = {
 	},
 };
 
-static int __init sysctr_timer_init(struct device_node *np)
+static int __init __sysctr_timer_init(struct device_node *np)
 {
 	struct sysctr_private *priv;
 	void __iomem *base;
@@ -154,9 +160,48 @@ static int __init sysctr_timer_init(struct device_node *np)
 	base = timer_of_base(&to_sysctr);
 	priv->cmpcr = readl(base + CMPCR) & ~SYS_CTR_EN;
 
+	return 0;
+}
+
+static int __init sysctr_timer_init(struct device_node *np)
+{
+	struct sysctr_private *priv;
+	int ret;
+
+	ret = __sysctr_timer_init(np);
+	if (ret)
+		return ret;
+
+	priv = to_sysctr.private_data;
+	priv->lo_off = CNTCV_LO;
+	priv->hi_off = CNTCV_HI;
+
 	clockevents_config_and_register(&to_sysctr.clkevt,
 					timer_of_rate(&to_sysctr),
 					0xff, 0x7fffffff);
+
 	return 0;
 }
+
+static int __init sysctr_timer_imx95_init(struct device_node *np)
+{
+	struct sysctr_private *priv;
+	int ret;
+
+	ret = __sysctr_timer_init(np);
+	if (ret)
+		return ret;
+
+	priv = to_sysctr.private_data;
+	priv->lo_off = CNTCV_LO_IMX95;
+	priv->hi_off = CNTCV_HI_IMX95;
+
+	clockevents_config_and_register(&to_sysctr.clkevt,
+					timer_of_rate(&to_sysctr),
+					0xff, 0x7fffffff);
+
+	return 0;
+}
+
 TIMER_OF_DECLARE(sysctr_timer, "nxp,sysctr-timer", sysctr_timer_init);
+TIMER_OF_DECLARE(sysctr_timer_imx95, "nxp,imx95-sysctr-timer", sysctr_timer_imx95_init);

-- 
2.37.1



From u-kumar1 at ti.com  Sun Feb  4 20:45:58 2024
From: u-kumar1 at ti.com (Udit Kumar)
Date: Mon, 5 Feb 2024 10:15:58 +0530
Subject: [PATCH v1] clk: keystone: sci-clk: Adding support for non contiguous clocks
Message-ID: <20240205044557.3340848-1-u-kumar1@ti.com>

Most of clocks and their parents are defined in contiguous range,
But in few cases, there is gap in clock numbers[0].

Driver assumes clocks to be in contiguous range, and assigns
accordingly.

New firmware started returning error in case of
non-available clock id.  Therefore drivers throws error while
re-calculate and other functions.

In this fix, before assigning and adding clock in list,
driver checks if given clock is valid or not.

Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")

[0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
Section Clocks for NAVSS0_CPTS_0 Device,
clock id 12-15 and 18-19 not present

Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
---
Original logs
https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
Line 2630 for error

Logs with fix
https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-with-fix
Line 2594 

 drivers/clk/keystone/sci-clk.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 35fe197dd303..d417ec018d82 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -517,6 +517,8 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
 	int num_clks = 0;
 	int num_parents;
 	int clk_id;
+	int max_clk_id;
+	u64 freq;
 	const char * const clk_names[] = {
 		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
 	};
@@ -584,6 +586,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
 				}
 
 				clk_id = args.args[1] + 1;
+				max_clk_id = clk_id + num_parents;
 
 				while (num_parents--) {
 					sci_clk = devm_kzalloc(dev,
@@ -592,11 +595,20 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
 					if (!sci_clk)
 						return -ENOMEM;
 					sci_clk->dev_id = args.args[0];
-					sci_clk->clk_id = clk_id++;
-					sci_clk->provider = provider;
-					list_add_tail(&sci_clk->node, &clks);
+					/* check if given clock id is valid by calling get_freq */
+					/* loop over max possible ids */
+					do {
+						sci_clk->clk_id = clk_id++;
 
-					num_clks++;
+						ret = provider->ops->get_freq(provider->sci,
+							   sci_clk->dev_id, sci_clk->clk_id, &freq);
+					} while (ret != 0 && clk_id < max_clk_id);
+
+					sci_clk->provider = provider;
+					if (ret == 0) {
+						list_add_tail(&sci_clk->node, &clks);
+						num_clks++;
+					}
 				}
 			}
 
-- 
2.34.1



From shawn.gsc at gmail.com  Sun Feb  4 21:51:39 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 13:51:39 +0800
Subject: [PATCH] ARM: dts: imx6ull-dhcor: Remove 900MHz operating point
In-Reply-To: <20231221164633.2029-1-cniedermaier@dh-electronics.com>
References: <20231221164633.2029-1-cniedermaier@dh-electronics.com>
Message-ID: <20240205054917.GB804317@dragon>

On Thu, Dec 21, 2023 at 05:46:33PM +0100, Christoph Niedermaier wrote:
> Due to CPU lifetime consideration of the SoC manufacturer [1] and
> the preferred area of operation in the industrial related
> environment, set the maximum frequency for each DHCOM i.MX6ULL to
> 792MHz, as with the industrial type. This is done by removing the
> operating point at 900MHz and set the clock-frequency to 792000000.
> 
> [1] https://www.nxp.com/docs/en/application-note/AN5337.pdf
> 
> Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>

Applied, thanks!


From mac.shen at mediatek.com  Sun Feb  4 21:50:35 2024
From: mac.shen at mediatek.com (mac.shen)
Date: Mon, 5 Feb 2024 13:50:35 +0800
Subject: [PATCH v2 0/3] Add HDCP feature for DisplayPort
Message-ID: <20240205055055.25340-1-mac.shen@mediatek.com>

Add tee client application, HDCP 1.x and 2.x authentication for DisplayPort
to support the HDCP feature.

mac.shen (3):
  Subject: [PATCH] drm/mediatek/dp: Add tee client application for HDCP
    feature
  Subject: [PATCH] drm/mediatek/dp: Add HDCP2.x feature for DisplayPort
  Subject: [PATCH] drm/mediatek/dp: Add HDCP1.x feature for DisplayPort

 drivers/gpu/drm/mediatek/Makefile        |    7 +-
 drivers/gpu/drm/mediatek/mtk_dp.c        |  324 +++++--
 drivers/gpu/drm/mediatek/mtk_dp.h        |   99 +++
 drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.c |  589 +++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.h |   46 +
 drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c  | 1021 ++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h  |   52 ++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h    |    7 +-
 drivers/gpu/drm/mediatek/mtk_dpi.c       |    3 +
 drivers/gpu/drm/mediatek/tci.h           |  156 ++++
 drivers/gpu/drm/mediatek/tlc_dp_hdcp.c   |  598 +++++++++++++
 drivers/gpu/drm/mediatek/tlc_dp_hdcp.h   |  414 +++++++++
 12 files changed, 3230 insertions(+), 86 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h
 create mode 100644 drivers/gpu/drm/mediatek/tci.h
 create mode 100644 drivers/gpu/drm/mediatek/tlc_dp_hdcp.c
 create mode 100644 drivers/gpu/drm/mediatek/tlc_dp_hdcp.h

-- 
2.43.0



From mac.shen at mediatek.com  Sun Feb  4 21:50:38 2024
From: mac.shen at mediatek.com (mac.shen)
Date: Mon, 5 Feb 2024 13:50:38 +0800
Subject: [PATCH v2 3/3] Subject: [PATCH] drm/mediatek/dp: Add HDCP1.x feature for DisplayPort
In-Reply-To: <20240205055055.25340-1-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
Message-ID: <20240205055055.25340-4-mac.shen@mediatek.com>

Add HDCP1.x feature for DisplayPort.
If the sink support HDCP1.X only, the feature will do HDCP1.x
authentication when userspace request the kernel protect with
HDCP_Content_Type property as DRM_MODE_HDCP_CONTENT_TYPE0.

Changes in v2:
- remove useless code
- remove the prefix 'mdrv'
- do HDCP1.x authentication when userspace request the
  kernel protect future content communicated
per suggestion from the previous thread:
https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8
fa9218a545c46.camel at mediatek.com/

Signed-off-by: mac.shen <mac.shen at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile        |   1 +
 drivers/gpu/drm/mediatek/mtk_dp.c        |  33 +-
 drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.c | 589 +++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.h |  46 ++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h    |   3 +
 5 files changed, 669 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.h

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 50ea069b047e..9738235f76b8 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -27,6 +27,7 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
 
 mtk-dp-objs := tlc_dp_hdcp.o \
+		  mtk_dp_hdcp1x.o \
 		  mtk_dp_hdcp2.o \
 		  mtk_dp.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index 7ff72f15528b..8cd7562dab7a 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -33,6 +33,7 @@
 
 #include "mtk_dp.h"
 #include "mtk_dp_reg.h"
+#include "mtk_dp_hdcp1x.h"
 #include "mtk_dp_hdcp2.h"
 
 #define MTK_DP_SIP_CONTROL_AARCH32	MTK_SIP_SMC_CMD(0x523)
@@ -1811,6 +1812,9 @@ void mtk_dp_check_hdcp_version(struct mtk_dp *mtk_dp, bool only_hdcp1x)
 	if (!only_hdcp1x && dp_tx_hdcp2_support(&mtk_dp->hdcp_info))
 		return;
 
+	if (dp_tx_hdcp1x_support(&mtk_dp->hdcp_info))
+		return;
+
 	if (tee_add_device(&mtk_dp->hdcp_info, HDCP_NONE) != RET_SUCCESS)
 		mtk_dp->hdcp_info.auth_status = AUTH_FAIL;
 }
@@ -1860,15 +1864,34 @@ static void mtk_dp_hdcp_handle(struct work_struct *data)
 		mtk_dp_check_hdcp_version(mtk_dp, false);
 		if (mtk_dp->hdcp_info.hdcp2_info.enable)
 			dp_tx_hdcp2_set_start_auth(&mtk_dp->hdcp_info, true);
+		else if (mtk_dp->hdcp_info.hdcp1x_info.enable &&
+			 mtk_dp->hdcp_info.hdcp_content_type != DRM_MODE_HDCP_CONTENT_TYPE1)
+			dp_tx_hdcp1x_set_start_auth(&mtk_dp->hdcp_info, true);
 		else
 			mtk_dp->hdcp_info.auth_status = AUTH_ZERO;
 	}
 
-	while (mtk_dp->hdcp_info.hdcp2_info.enable &&
-	       mtk_dp->hdcp_info.auth_status != AUTH_FAIL &&
+	while ((mtk_dp->hdcp_info.hdcp1x_info.enable ||
+		mtk_dp->hdcp_info.hdcp2_info.enable) &&
+			mtk_dp->hdcp_info.auth_status != AUTH_FAIL &&
 			mtk_dp->hdcp_info.auth_status != AUTH_PASS) {
-		if (mtk_dp->hdcp_info.hdcp2_info.enable)
+		if (mtk_dp->hdcp_info.hdcp2_info.enable) {
 			dp_tx_hdcp2_fsm(&mtk_dp->hdcp_info);
+			if (mtk_dp->hdcp_info.auth_status == AUTH_FAIL) {
+				tee_remove_device(&mtk_dp->hdcp_info);
+				mtk_dp_check_hdcp_version(mtk_dp, true);
+				if (mtk_dp->hdcp_info.hdcp1x_info.enable &&
+				    mtk_dp->hdcp_info.hdcp_content_type !=
+					DRM_MODE_HDCP_CONTENT_TYPE1) {
+					mtk_dp->hdcp_info.hdcp2_info.enable = false;
+					dp_tx_hdcp1x_set_start_auth(&mtk_dp->hdcp_info, true);
+				}
+			}
+		}
+
+		if (mtk_dp->hdcp_info.hdcp1x_info.enable &&
+		    mtk_dp->hdcp_info.hdcp_content_type != DRM_MODE_HDCP_CONTENT_TYPE1)
+			dp_tx_hdcp1x_fsm(&mtk_dp->hdcp_info);
 	}
 }
 
@@ -1924,6 +1947,8 @@ static void mtk_dp_hdcp_atomic_check(struct mtk_dp *mtk_dp, struct drm_connector
 		dev_dbg(mtk_dp->dev, "disable HDCP\n");
 		if (mtk_dp->hdcp_info.hdcp2_info.enable)
 			dp_tx_hdcp2_set_start_auth(&mtk_dp->hdcp_info, false);
+		else if (mtk_dp->hdcp_info.hdcp1x_info.enable)
+			dp_tx_hdcp1x_set_start_auth(&mtk_dp->hdcp_info, false);
 
 		drm_hdcp_update_content_protection(mtk_dp->conn,
 						   mtk_dp->hdcp_info.content_protection);
@@ -2394,6 +2419,8 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
 
 	if (mtk_dp->hdcp_info.hdcp2_info.enable)
 		dp_tx_hdcp2_set_start_auth(&mtk_dp->hdcp_info, false);
+	else if (mtk_dp->hdcp_info.hdcp1x_info.enable)
+		dp_tx_hdcp1x_set_start_auth(&mtk_dp->hdcp_info, false);
 
 	if (mtk_dp->hdcp_info.content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
 		mtk_dp->hdcp_info.content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
diff --git a/drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.c b/drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.c
new file mode 100644
index 000000000000..33b6cad39714
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019-2024 MediaTek Inc.
+ */
+
+#include "mtk_dp_hdcp1x.h"
+#include "mtk_dp_reg.h"
+#include "mtk_dp.h"
+
+static void dp_tx_hdcp1x_start_cipher(struct mtk_hdcp_info *hdcp_info, bool enable)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+
+	if (enable) {
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3480, REQ_BLOCK_CIPHER_AUTH,
+				   REQ_BLOCK_CIPHER_AUTH);
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3480, KM_GENERATED, KM_GENERATED);
+	} else {
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3480, 0, KM_GENERATED);
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3480, 0, REQ_BLOCK_CIPHER_AUTH);
+	}
+}
+
+static bool dp_tx_hdcp1x_get_r0_available(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	bool R0_available;
+	u32 ret;
+
+	ret = mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_34A4);
+	if (ret & BIT(12))
+		R0_available = true;
+	else
+		R0_available = false;
+
+	return R0_available;
+}
+
+static void dp_tx_hdcp1x_set_repeater(struct mtk_hdcp_info *hdcp_info, bool enable)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+
+	if (enable)
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4, BIT(15), BIT(15));
+	else
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4, 0,  BIT(15));
+}
+
+void dp_tx_hdcp1x_set_start_auth(struct mtk_hdcp_info *hdcp_info, bool enable)
+{
+	hdcp_info->hdcp1x_info.enable = enable;
+
+	if (enable) {
+		hdcp_info->auth_status = AUTH_INIT;
+		hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A0;
+		hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_IDLE;
+	} else {
+		hdcp_info->auth_status = AUTH_ZERO;
+		hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_H2;
+		hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_IDLE;
+		tee_hdcp_enable_encrypt(hdcp_info, false, HDCP_NONE);
+		dp_tx_hdcp1x_start_cipher(hdcp_info, false);
+		tee_hdcp1x_soft_rst(hdcp_info);
+	}
+
+	hdcp_info->hdcp1x_info.retry_count = 0;
+}
+
+bool dp_tx_hdcp1x_support(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 tmp[2];
+	int ret;
+
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_BCAPS, tmp, 0x1);
+
+	hdcp_info->hdcp1x_info.enable = tmp[0x0] & BIT(0);
+	hdcp_info->hdcp1x_info.repeater = (tmp[0x0] & BIT(1)) >> 1;
+
+	DPTXHDCPMSG("1.x: CAPABLE: %d, Reapeater: %d\n",
+		    hdcp_info->hdcp1x_info.enable,
+		hdcp_info->hdcp1x_info.repeater);
+
+	if (!hdcp_info->hdcp1x_info.enable)
+		return false;
+
+	ret = tee_add_device(hdcp_info, HDCP_VERSION_1X);
+	if (ret != RET_SUCCESS) {
+		DPTXHDCPERR("1.x: HDCP TA has some error\n");
+		hdcp_info->hdcp1x_info.enable = false;
+	}
+
+	return hdcp_info->hdcp1x_info.enable;
+}
+
+static bool dp_tx_hdcp1x_init(struct mtk_hdcp_info *hdcp_info)
+{
+	u8 i;
+
+	hdcp_info->hdcp1x_info.ksv_ready = false;
+	hdcp_info->hdcp1x_info.r0_read = false;
+	hdcp_info->hdcp1x_info.b_status = 0x00;
+	for (i = 0; i < 5; i++) {
+		hdcp_info->hdcp1x_info.b_ksv[i] = 0x00;
+		hdcp_info->hdcp1x_info.a_ksv[i] = 0x00;
+	}
+
+	for (i = 0; i < 5; i++)
+		hdcp_info->hdcp1x_info.v[i] = 0x00;
+
+	hdcp_info->hdcp1x_info.b_info[0] = 0x00;
+	hdcp_info->hdcp1x_info.b_info[1] = 0x00;
+	hdcp_info->hdcp1x_info.max_cascade = false;
+	hdcp_info->hdcp1x_info.max_devs = false;
+	hdcp_info->hdcp1x_info.device_count = 0x00;
+
+	tee_hdcp_enable_encrypt(hdcp_info, false, HDCP_NONE);
+	dp_tx_hdcp1x_start_cipher(hdcp_info, false);
+	tee_hdcp1x_soft_rst(hdcp_info);
+
+	return true;
+}
+
+static bool dp_tx_hdcp1x_read_sink_b_ksv(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 read_buffer[DRM_HDCP_KSV_LEN], i;
+
+	if (hdcp_info->hdcp1x_info.enable) {
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_BKSV, read_buffer, DRM_HDCP_KSV_LEN);
+
+		for (i = 0; i < DRM_HDCP_KSV_LEN; i++) {
+			hdcp_info->hdcp1x_info.b_ksv[i] = read_buffer[i];
+			DPTXHDCPMSG("1.x: Bksv = 0x%x\n", read_buffer[i]);
+		}
+	}
+
+	return true;
+}
+
+static bool dp_tx_hdcp1x_check_sink_ksv_ready(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 read_buffer;
+
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_BSTATUS, &read_buffer, 1);
+
+	hdcp_info->hdcp1x_info.ksv_ready = (read_buffer & BIT(0))  ? true : false;
+
+	return hdcp_info->hdcp1x_info.ksv_ready;
+}
+
+static bool dp_tx_hdcp1x_check_sink_cap(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8  read_buffer[0x2];
+
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_BCAPS, read_buffer, 1);
+
+	hdcp_info->hdcp1x_info.repeater = (read_buffer[0] & BIT(1)) ? true : false;
+
+	return true;
+}
+
+static bool dp_tx_hdcp1x_read_sink_b_info(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 read_buffer[DRM_HDCP_BSTATUS_LEN];
+
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_BINFO, read_buffer, DRM_HDCP_BSTATUS_LEN);
+
+	hdcp_info->hdcp1x_info.b_info[0] = read_buffer[0];
+	hdcp_info->hdcp1x_info.b_info[1] = read_buffer[1];
+	hdcp_info->hdcp1x_info.max_cascade = (read_buffer[1] & BIT(3)) ? true : false;
+	hdcp_info->hdcp1x_info.max_devs = (read_buffer[0] & BIT(7)) ? true : false;
+	hdcp_info->hdcp1x_info.device_count = read_buffer[0] & 0x7F;
+
+	DPTXHDCPMSG("1.x: Binfo max_cascade_EXCEEDED = %d\n", hdcp_info->hdcp1x_info.max_cascade);
+	DPTXHDCPMSG("1.x: Binfo DEPTH = %d\n", read_buffer[1] & 0x07);
+	DPTXHDCPMSG("1.x: Binfo max_devs_EXCEEDED = %d\n", hdcp_info->hdcp1x_info.max_devs);
+	DPTXHDCPMSG("1.x: Binfo device_count = %d\n", hdcp_info->hdcp1x_info.device_count);
+	return true;
+}
+
+static bool dp_tx_hdcp1x_read_sink_ksv(struct mtk_hdcp_info *hdcp_info, u8 dev_count)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 i;
+	u8 times = dev_count / 3;
+	u8 remain = dev_count % 3;
+
+	if (times > 0) {
+		for (i = 0; i < times; i++)
+			drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_KSV_FIFO,
+					 hdcp_info->hdcp1x_info.ksvfifo + i * 15, 15);
+	}
+
+	if (remain > 0)
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_KSV_FIFO,
+				 hdcp_info->hdcp1x_info.ksvfifo + times * 15, remain * 5);
+
+	DPTXHDCPMSG("1.x: Read ksvfifo = %x\n",	hdcp_info->hdcp1x_info.ksvfifo[0]);
+	DPTXHDCPMSG("1.x: Read ksvfifo = %x\n",	hdcp_info->hdcp1x_info.ksvfifo[1]);
+	DPTXHDCPMSG("1.x: Read ksvfifo = %x\n",	hdcp_info->hdcp1x_info.ksvfifo[2]);
+	DPTXHDCPMSG("1.x: Read ksvfifo = %x\n",	hdcp_info->hdcp1x_info.ksvfifo[3]);
+	DPTXHDCPMSG("1.x: Read ksvfifo = %x\n",	hdcp_info->hdcp1x_info.ksvfifo[4]);
+
+	return true;
+}
+
+static bool dp_tx_hdcp1x_read_sink_sha_v(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 read_buffer[4], i, j;
+
+	for (i = 0; i < 5; i++) {
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_V_PRIME(i), read_buffer, 4);
+		for (j = 0; j < 4; j++) {
+			hdcp_info->hdcp1x_info.v[(i * 4) + j] = read_buffer[3 - j];
+			DPTXHDCPMSG("1.x: Read sink V = %x\n",
+				    hdcp_info->hdcp1x_info.v[(i * 4) + j]);
+		}
+	}
+
+	return true;
+}
+
+static bool dp_tx_hdcp1x_auth_with_repeater(struct mtk_hdcp_info *hdcp_info)
+{
+	bool ret = false;
+	u8 *buffer = NULL;
+	u32 len = 0;
+	int tmp = 0;
+
+	if (hdcp_info->hdcp1x_info.device_count > HDCP1X_REP_MAXDEVS) {
+		DPTXHDCPERR("1.x: Repeater: %d DEVs!\n", hdcp_info->hdcp1x_info.device_count);
+		return false;
+	}
+
+	dp_tx_hdcp1x_read_sink_ksv(hdcp_info, hdcp_info->hdcp1x_info.device_count);
+	dp_tx_hdcp1x_read_sink_sha_v(hdcp_info);
+
+	len = hdcp_info->hdcp1x_info.device_count * DRM_HDCP_KSV_LEN + HDCP1X_B_INFO_LEN;
+	buffer = kmalloc(len, GFP_KERNEL);
+	if (!buffer) {
+		DPTXHDCPERR("1.x: Out of Memory\n");
+		return false;
+	}
+
+	memcpy(buffer, hdcp_info->hdcp1x_info.ksvfifo, len - HDCP1X_B_INFO_LEN);
+	memcpy(buffer + (len - HDCP1X_B_INFO_LEN), hdcp_info->hdcp1x_info.b_info,
+	       HDCP1X_B_INFO_LEN);
+	tmp = tee_hdcp1x_compute_compare_v(hdcp_info, buffer, len, hdcp_info->hdcp1x_info.v);
+	if (tmp == RET_COMPARE_PASS) {
+		DPTXHDCPMSG("1.x: Check V' PASS\n");
+		ret = true;
+	} else {
+		DPTXHDCPMSG("1.x: Check V' Fail\n");
+	}
+
+	kfree(buffer);
+	return ret;
+}
+
+static bool dp_tx_hdcp1x_verify_b_ksv(struct mtk_hdcp_info *hdcp_info)
+{
+	int i, j, k = 0;
+	u8 ksv;
+
+	for (i = 0; i < DRM_HDCP_KSV_LEN; i++) {
+		ksv = hdcp_info->hdcp1x_info.b_ksv[i];
+		for (j = 0; j < 8; j++)
+			k += (ksv >> j) & 0x01;
+	}
+
+	if (k != 20) {
+		DPTXHDCPERR("1.x: Check BKSV 20'1' 20'0' Fail\n");
+		return false;
+	}
+
+	return true;
+}
+
+static bool dp_tx_hdcp1x_write_a_ksv(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 tmp;
+	int i, k, j;
+
+	tee_get_aksv(hdcp_info, hdcp_info->hdcp1x_info.a_ksv);
+	drm_dp_dpcd_write(&mtk_dp->aux, DP_AUX_HDCP_AKSV, hdcp_info->hdcp1x_info.a_ksv,
+			  DRM_HDCP_KSV_LEN);
+
+	for (i = 0, k = 0; i < DRM_HDCP_KSV_LEN; i++) {
+		tmp = hdcp_info->hdcp1x_info.a_ksv[i];
+
+		for (j = 0; j < 8; j++)
+			k += (tmp >> j) & 0x01;
+		DPTXHDCPMSG("1.x: Aksv 0x%x\n", tmp);
+	}
+
+	if (k != 20) {
+		DPTXHDCPERR("1.x: Check AKSV 20'1' 20'0' Fail\n");
+		return false;
+	}
+
+	return true;
+}
+
+static void dp_tx_hdcp1x_write_an(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 an_value[DRM_HDCP_AN_LEN] = { /* on DP Spec p99 */
+		0x03, 0x04, 0x07, 0x0C, 0x13, 0x1C, 0x27, 0x34};
+
+	tee_hdcp1x_set_tx_an(hdcp_info, an_value);
+	drm_dp_dpcd_write(&mtk_dp->aux, DP_AUX_HDCP_AN, an_value, DRM_HDCP_AN_LEN);
+	mdelay(5);
+}
+
+static bool dp_tx_hdcp1x_check_r0(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 value[DRM_HDCP_BSTATUS_LEN];
+	u8 retry_count = 0;
+	bool sink_R0_available = false;
+	bool ret;
+	int tmp;
+
+	ret = dp_tx_hdcp1x_get_r0_available(hdcp_info);
+	if (!ret) {
+		DPTXHDCPERR("1.x: ERR: R0 No Available\n");
+		return false;
+	}
+
+	if (!hdcp_info->hdcp1x_info.r0_read) {
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_BSTATUS, value, 1);
+		sink_R0_available = ((value[0x0] & BIT(1)) == BIT(1)) ? true : false;
+
+		if (!sink_R0_available) {
+			drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_BSTATUS, value, 1);
+			sink_R0_available = ((value[0x0] & BIT(1)) == BIT(1)) ? true : false;
+
+			if (!sink_R0_available)
+				return false;
+		}
+	}
+
+	while (retry_count < 3) {
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_AUX_HDCP_RI_PRIME, value, DRM_HDCP_RI_LEN);
+
+		tmp = tee_compare_r0(hdcp_info, value, DRM_HDCP_RI_LEN);
+		if (tmp == RET_COMPARE_PASS)
+			return true;
+
+		DPTXHDCPMSG("1.x: R0 check FAIL:Rx_R0=0x%x%x\n", value[0x1], value[0x0]);
+		mdelay(5);
+
+		retry_count++;
+	}
+	return false;
+}
+
+static void dp_tx_hdcp1x_state_rst(struct mtk_hdcp_info *hdcp_info)
+{
+	DPTXHDCPMSG("1.x: Before State Reset:(M : S)= (%d, %d)",
+		    hdcp_info->hdcp1x_info.main_states,
+		hdcp_info->hdcp1x_info.sub_states);
+	hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A0;
+	hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_IDLE;
+}
+
+void dp_tx_hdcp1x_fsm(struct mtk_hdcp_info *hdcp_info)
+{
+	static int pre_main, pre_sub;
+	static u32 pre_time;
+	u32 time;
+	bool ret;
+
+	if (pre_main != hdcp_info->hdcp1x_info.main_states ||
+	    hdcp_info->hdcp1x_info.sub_states != pre_sub) {
+		DPTXHDCPMSG("1.x: State(M : S)= (%d, %d)",
+			    hdcp_info->hdcp1x_info.main_states,
+			hdcp_info->hdcp1x_info.sub_states);
+		pre_main = hdcp_info->hdcp1x_info.main_states;
+		pre_sub = hdcp_info->hdcp1x_info.sub_states;
+	}
+
+	switch (hdcp_info->hdcp1x_info.main_states) {
+	case HDCP1X_main_state_H2:
+		/* HDCP1X_main_state_H2 */
+		/* HDCP1X_sub_FSM_auth_fail */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_auth_fail) {
+			tee_hdcp_enable_encrypt(hdcp_info, false, HDCP_NONE);
+			DPTXHDCPMSG("1.x: Authentication Fail\n");
+			hdcp_info->auth_status = AUTH_FAIL;
+			hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_H2;
+			hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_IDLE;
+		}
+		break;
+
+	case HDCP1X_main_state_A0:
+		/* HDCP1X_main_state_A0 */
+		/* HDCP1X_sub_FSM_IDLE */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_IDLE) {
+			if (hdcp_info->hdcp1x_info.retry_count > HDCP1X_REAUNTH_COUNT) {
+				DPTXHDCPMSG("1.x: Too much retry!\n");
+				hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_H2;
+				hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_auth_fail;
+				break;
+			}
+
+			dp_tx_hdcp1x_init(hdcp_info);
+			hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A0;
+			hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_CHECKHDCPCAPABLE;
+		}
+
+		/* HDCP1X_main_state_A0 */
+		/* HDCP1X_sub_FSM_CHECKHDCPCAPABLE */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_CHECKHDCPCAPABLE) {
+			if (!hdcp_info->hdcp1x_info.enable) {
+				dp_tx_hdcp1x_state_rst(hdcp_info);
+				break;
+			}
+
+			hdcp_info->hdcp1x_info.retry_count++;
+			hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A1;
+			hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_exchange_KSV;
+		}
+		break;
+
+	case HDCP1X_main_state_A1:
+		/* HDCP1X_main_state_A1 */
+		/* HDCP1X_sub_FSM_exchange_KSV */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_exchange_KSV) {
+			dp_tx_hdcp1x_write_an(hdcp_info);
+			ret = dp_tx_hdcp1x_write_a_ksv(hdcp_info);
+			if (!ret) {
+				dp_tx_hdcp1x_state_rst(hdcp_info);
+				break;
+			}
+
+			pre_time = mtk_dp_get_system_time();
+			hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A1;
+			hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_verify_bksv;
+		}
+
+		/* HDCP1X_main_state_A1 */
+		/* HDCP1X_sub_FSM_verify_bksv */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_verify_bksv) {
+			dp_tx_hdcp1x_read_sink_b_ksv(hdcp_info);
+			dp_tx_hdcp1x_set_repeater(hdcp_info, hdcp_info->hdcp1x_info.repeater);
+
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time >= HDCP1X_BSTATUS_TIMEOUT_CNT) {
+				dp_tx_hdcp1x_state_rst(hdcp_info);
+				break;
+			}
+
+			pre_time = mtk_dp_get_system_time();
+			ret = dp_tx_hdcp1x_verify_b_ksv(hdcp_info);
+			if (!ret) {
+				dp_tx_hdcp1x_state_rst(hdcp_info);
+				DPTXHDCPMSG("1.x: Invalid BKSV!!\n");
+				break;
+			}
+
+			hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A2;
+			hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_computation;
+		}
+		break;
+
+	case HDCP1X_main_state_A2:
+		/* HDCP1X_main_state_A2 */
+		/* HDCP1X_sub_FSM_computation */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_computation) {
+			tee_calculate_lm(hdcp_info, hdcp_info->hdcp1x_info.b_ksv);
+			dp_tx_hdcp1x_start_cipher(hdcp_info, true);
+			hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A3;
+			hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_check_R0;
+			pre_time = mtk_dp_get_system_time();
+		}
+		break;
+
+	case HDCP1X_main_state_A3:
+		/* HDCP1X_main_state_A3 */
+		/* HDCP1X_sub_FSM_check_R0 */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_check_R0) {
+			/* Wait 100ms(at least) before check R0 */
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time < HDCP1X_R0_WDT && !hdcp_info->hdcp1x_info.r0_read) {
+				mdelay(10);
+				break;
+			}
+
+			ret = dp_tx_hdcp1x_check_r0(hdcp_info);
+			if (!ret) {
+				dp_tx_hdcp1x_state_rst(hdcp_info);
+				break;
+			}
+
+			tee_hdcp_enable_encrypt(hdcp_info, true, HDCP_V1);
+			hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A5;
+			hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_IDLE;
+		}
+		break;
+
+	case HDCP1X_main_state_A4:
+		/* HDCP1X_main_state_A4 */
+		/* HDCP1X_sub_FSM_auth_done */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_auth_done) {
+			DPTXHDCPMSG("1.x: Authentication done!\n");
+			hdcp_info->hdcp1x_info.retry_count = 0;
+			hdcp_info->auth_status = AUTH_PASS;
+			hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A4;
+			hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_IDLE;
+
+			/* unmute */
+		}
+		break;
+
+	case HDCP1X_main_state_A5:
+		/* HDCP1X_main_state_A5 */
+		/* HDCP1X_sub_FSM_IDLE */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_IDLE) {
+			dp_tx_hdcp1x_check_sink_cap(hdcp_info);
+			if (!hdcp_info->hdcp1x_info.repeater) {
+				DPTXHDCPMSG("1.x: No Repeater!\n");
+				hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A4;
+				hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_auth_done;
+				break;
+			}
+
+			DPTXHDCPMSG("1.x: Repeater!\n");
+			pre_time = mtk_dp_get_system_time();
+			hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A6;
+			hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_polling_rdy_bit;
+		}
+		break;
+
+	case HDCP1X_main_state_A6:
+		/* HDCP1X_main_state_A6 */
+		/* HDCP1X_sub_FSM_polling_rdy_bit */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_polling_rdy_bit) {
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time > HDCP1X_REP_RDY_WDT) {
+				dp_tx_hdcp1x_state_rst(hdcp_info);
+				break;
+			}
+
+			time = mtk_dp_get_time_diff(pre_time);
+			if (!hdcp_info->hdcp1x_info.ksv_ready && time > HDCP1X_REP_RDY_WDT / 2)
+				dp_tx_hdcp1x_check_sink_ksv_ready(hdcp_info);
+
+			if (hdcp_info->hdcp1x_info.ksv_ready) {
+				dp_tx_hdcp1x_read_sink_b_info(hdcp_info);
+				hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A7;
+				hdcp_info->hdcp1x_info.sub_states =
+					HDCP1X_sub_FSM_auth_with_repeater;
+				hdcp_info->hdcp1x_info.ksv_ready = false;
+			}
+		}
+		break;
+
+	case HDCP1X_main_state_A7:
+		/* HDCP1X_main_state_A7 */
+		/* HDCP1X_sub_FSM_auth_with_repeater */
+		if (hdcp_info->hdcp1x_info.sub_states == HDCP1X_sub_FSM_auth_with_repeater) {
+			if (hdcp_info->hdcp1x_info.max_cascade || hdcp_info->hdcp1x_info.max_devs) {
+				DPTXHDCPERR("1.x: MAX CASCADE or MAX DEVS!\n");
+				dp_tx_hdcp1x_state_rst(hdcp_info);
+				break;
+			}
+
+			ret = dp_tx_hdcp1x_auth_with_repeater(hdcp_info);
+			if (!ret) {
+				dp_tx_hdcp1x_state_rst(hdcp_info);
+				break;
+			}
+
+			hdcp_info->hdcp1x_info.main_states = HDCP1X_main_state_A4;
+			hdcp_info->hdcp1x_info.sub_states = HDCP1X_sub_FSM_auth_done;
+		}
+		break;
+
+	default:
+		break;
+	}
+}
diff --git a/drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.h b/drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.h
new file mode 100644
index 000000000000..4787c5bd876a
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp_hdcp1x.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019-2024 MediaTek Inc.
+ */
+
+#ifndef _MTK_DP_HDCP1X_H_
+#define _MTK_DP_HDCP1X_H_
+
+#include "tlc_dp_hdcp.h"
+
+#define HDCP1X_BSTATUS_TIMEOUT_CNT              600
+#define HDCP1X_R0_WDT                           100
+#define HDCP1X_REP_RDY_WDT                      5000
+
+#define HDCP1X_REAUNTH_COUNT          3
+
+enum DPTX_DRV_HDCP1X_main_states {
+	HDCP1X_main_state_H2 = 0,
+	HDCP1X_main_state_A0 = 1,
+	HDCP1X_main_state_A1 = 2,
+	HDCP1X_main_state_A2 = 3,
+	HDCP1X_main_state_A3 = 4,
+	HDCP1X_main_state_A4 = 5,
+	HDCP1X_main_state_A5 = 6,
+	HDCP1X_main_state_A6 = 7,
+	HDCP1X_main_state_A7 = 8,
+};
+
+enum DPTX_DRV_HDCP1X_sub_states {
+	HDCP1X_sub_FSM_IDLE              = 0,
+	HDCP1X_sub_FSM_CHECKHDCPCAPABLE	= 1,
+	HDCP1X_sub_FSM_exchange_KSV       = 2,
+	HDCP1X_sub_FSM_verify_bksv        = 3,
+	HDCP1X_sub_FSM_computation       = 4,
+	HDCP1X_sub_FSM_check_R0           = 5,
+	HDCP1X_sub_FSM_auth_done          = 6,
+	HDCP1X_sub_FSM_polling_rdy_bit     = 7,
+	HDCP1X_sub_FSM_auth_with_repeater  = 8,
+	HDCP1X_sub_FSM_auth_fail          = 9,
+};
+
+bool dp_tx_hdcp1x_support(struct mtk_hdcp_info *hdcp_info);
+void dp_tx_hdcp1x_fsm(struct mtk_hdcp_info *hdcp_info);
+void dp_tx_hdcp1x_set_start_auth(struct mtk_hdcp_info *hdcp_info, bool enable);
+
+#endif /* _MTK_DP_HDCP1X_H_ */
diff --git a/drivers/gpu/drm/mediatek/mtk_dp_reg.h b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
index 5cf5059762ed..4481c853c375 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp_reg.h
+++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
@@ -276,6 +276,9 @@
 #define MTK_DP_TRANS_P0_3430				0x3430
 #define HPD_INT_THD_ECO_DP_TRANS_P0_MASK			GENMASK(1, 0)
 #define HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT		BIT(1)
+#define MTK_DP_TRANS_P0_3480                0x3480
+#define REQ_BLOCK_CIPHER_AUTH                           BIT(12)
+#define KM_GENERATED                                    BIT(4)
 #define MTK_DP_TRANS_P0_34A4				0x34a4
 #define LANE_NUM_DP_TRANS_P0_MASK				GENMASK(3, 2)
 #define MTK_DP_TRANS_P0_34D0                0x34D0
-- 
2.43.0



From mac.shen at mediatek.com  Sun Feb  4 21:50:36 2024
From: mac.shen at mediatek.com (mac.shen)
Date: Mon, 5 Feb 2024 13:50:36 +0800
Subject: [PATCH v2 1/3] Subject: [PATCH] drm/mediatek/dp: Add tee client application for HDCP feature
In-Reply-To: <20240205055055.25340-1-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
Message-ID: <20240205055055.25340-2-mac.shen@mediatek.com>

Add tee client application which will be used for
HDCP 1.x and 2.x authentication in DisplayPort.

Changes in v2:
- remove ca folder, and change file name with lower case
- refine the tci_t structure to make the data to tee can
  through this structure
- remove aux and regs from mtk_hdcp_info structure
- remove some definitions, and use the definitions in
  include/drm/drm_hdcp.h
- remove useless code
per suggestion from the previous thread:
https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
9218a545c46.camel at mediatek.com/

Signed-off-by: mac.shen <mac.shen at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile      |   5 +-
 drivers/gpu/drm/mediatek/tci.h         | 156 +++++++
 drivers/gpu/drm/mediatek/tlc_dp_hdcp.c | 598 +++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/tlc_dp_hdcp.h | 414 +++++++++++++++++
 4 files changed, 1172 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/tci.h
 create mode 100644 drivers/gpu/drm/mediatek/tlc_dp_hdcp.c
 create mode 100644 drivers/gpu/drm/mediatek/tlc_dp_hdcp.h

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index d4d193f60271..c80e6c2f9336 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -26,4 +26,7 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
 
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
 
-obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o
+mtk-dp-objs := tlc_dp_hdcp.o \
+		  mtk_dp.o
+
+obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk-dp.o
diff --git a/drivers/gpu/drm/mediatek/tci.h b/drivers/gpu/drm/mediatek/tci.h
new file mode 100644
index 000000000000..f2239ea3ffbf
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/tci.h
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019-2024 MediaTek Inc.
+ */
+
+#ifndef _TCI_H_
+#define _TCI_H_
+
+#include <drm/display/drm_hdcp.h>
+
+#define CMD_DEVICE_ADDED        1
+#define CMD_DEVICE_REMOVE       2
+#define CMD_WRITE_VAL           3
+#define CMD_DEVICE_CLEAN        4
+#define CMD_ENABLE_ENCRYPT      5
+
+/* V1.3 */
+#define CMD_CALCULATE_LM        11
+#define CMD_COMPARE_R0          12
+#define CMD_COMPARE_V1          13
+#define CMD_GET_AKSV            14
+
+/* V2.2 */
+#define CMD_AKE_CERTIFICATE     20
+#define CMD_ENC_KM              21
+#define CMD_AKE_H_PRIME         22
+#define CMD_AKE_PARING          23
+#define CMD_LC_L_PRIME          24
+#define CMD_COMPARE_L           25
+#define CMD_SKE_CAL_EKS         26
+
+#define CMD_COMPARE_V2          27
+#define CMD_COMPARE_M           28
+
+/* Need remove in furture */
+#define CMD_LOAD_KEY            50
+
+#define RET_COMPARE_PASS 0
+#define RET_COMPARE_FAIL 1
+#define RET_NEW_DEVICE 2
+#define RET_STORED_DEVICE 3
+
+#define TYPE_HDCP_PARAM_AN 10
+#define TYPE_HDCP_PARAM_RST_1 11
+#define TYPE_HDCP_PARAM_RST_2 12
+#define TYPE_HDCP_ENABLE_ENCRYPT 13
+#define TYPE_HDCP_DISABLE_ENCRYPT 14
+
+#define TYPE_HDCP13_KEY 20
+#define TYPE_HDCP22_KEY 21
+
+// reserved:2
+#define HDCP2_CERTRX_LEN (HDCP_2_2_RECEIVER_ID_LEN + HDCP_2_2_K_PUB_RX_LEN + \
+	2 + HDCP_2_2_DCP_LLC_SIG_LEN)
+// version:1
+#define HDCP_2_2_TXCAPS_LEN (HDCP_2_2_TXCAP_MASK_LEN + 1)
+#define PARAM_LEN 1024
+
+#define TCI_LENGTH sizeof(struct tci_t)
+
+struct cmd_hdcp_init_for_verion_t {
+	u32 version;
+	bool need_load_key;
+};
+
+struct cmd_hdcp_write_val_t {
+	u8 type;
+	u8 len;
+	u8 val[DRM_HDCP_AN_LEN];
+};
+
+struct cmd_hdcp_calculate_lm_t {
+	u8 bksv[DRM_HDCP_KSV_LEN];
+};
+
+struct cmd_hdcp_get_aksv_t {
+	u8 aksv[DRM_HDCP_KSV_LEN];
+};
+
+struct cmd_hdcp_ake_certificate_t {
+	u8 certification[HDCP2_CERTRX_LEN];
+	bool stored;
+	u8 m[HDCP_2_2_E_KH_KM_M_LEN - HDCP_2_2_E_KH_KM_LEN];
+	u8 ekm[HDCP_2_2_E_KH_KM_LEN];
+};
+
+struct cmd_hdcp_ake_paring_t {
+	u8 ekm[HDCP_2_2_E_KH_KM_LEN];
+};
+
+struct cmd_hdcp_enc_km_t {
+	u8 enc_km[HDCP_2_2_E_KPUB_KM_LEN];
+};
+
+struct cmd_hdcp_ake_h_prime_t {
+	u8 rtx[HDCP_2_2_RTX_LEN];
+	u8 rrx[HDCP_2_2_RRX_LEN];
+	u8 rx_caps[HDCP_2_2_RXCAPS_LEN];
+	u8 tx_caps[HDCP_2_2_TXCAPS_LEN];
+	u32 rx_h_len;
+	u8 rx_h[HDCP_2_2_H_PRIME_LEN];
+};
+
+struct cmd_hdcp_lc_l_prime_t {
+	u8 rn[HDCP_2_2_RN_LEN];
+	u32 rx_l_len;
+	u8 rx_l[HDCP_2_2_L_PRIME_LEN];
+};
+
+struct cmd_hdcp_ske_eks_t {
+	u8 riv[HDCP_2_2_RIV_LEN];
+	u32 eks_len;
+	u32 eks;
+};
+
+struct cmd_hdcp_compare_t {
+	u32 rx_val_len;
+	u8 rx_val[HDCP_2_2_MPRIME_LEN];
+	u32 param_len;
+	u8 param[PARAM_LEN];
+	u32 out_len;
+	u32 out;
+};
+
+union tci_cmd_body_t {
+	/* Init with special HDCP version */
+	struct cmd_hdcp_init_for_verion_t cmd_hdcp_init_for_verion;
+	/* Write uint32 data to hw */
+	struct cmd_hdcp_write_val_t cmd_hdcp_write_val;
+	/* Get aksv */
+	struct cmd_hdcp_get_aksv_t cmd_hdcp_get_aksv;
+	/* Calculate r0 */
+	struct cmd_hdcp_calculate_lm_t cmd_hdcp_calculate_lm;
+	/* Generate signature for certificate */
+	struct cmd_hdcp_ake_certificate_t cmd_hdcp_ake_certificate;
+	/* To store ekm */
+	struct cmd_hdcp_ake_paring_t cmd_hdcp_ake_paring;
+	/* Encrypt km for V2.2 */
+	struct cmd_hdcp_enc_km_t cmd_hdcp_enc_km;
+	/* Compute H prime */
+	struct cmd_hdcp_ake_h_prime_t cmd_hdcp_ake_h_prime;
+	/* Compute L prime */
+	struct cmd_hdcp_lc_l_prime_t cmd_hdcp_lc_l_prime;
+	/* Compute eks */
+	struct cmd_hdcp_ske_eks_t cmd_hdcp_ske_eks;
+	/* Compare */
+	struct cmd_hdcp_compare_t cmd_hdcp_compare;
+} __packed;
+
+struct tci_t {
+	u32 command_id;
+	u32 return_code;
+	union tci_cmd_body_t cmd_body;
+};
+
+#endif /* _TCI_H_ */
diff --git a/drivers/gpu/drm/mediatek/tlc_dp_hdcp.c b/drivers/gpu/drm/mediatek/tlc_dp_hdcp.c
new file mode 100644
index 000000000000..147329324648
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/tlc_dp_hdcp.c
@@ -0,0 +1,598 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019-2024 MediaTek Inc.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include "tlc_dp_hdcp.h"
+
+#define DEFAULT_WRITE_VAL_LEN 1
+#define DEFAULT_WRITE_VAL 0
+
+/*
+ * TA_FTPM_UUID: 99975014-3c7c-54ea-8487-a80d215ea92c
+ *
+ * Randomly generated, and must correspond to the GUID on the TA side.
+ * Defined here in the reference implementation:
+ * https://github.com/microsoft/ms-tpm-20-ref/blob/master/Samples/ARM32-FirmwareTPM/optee_ta/fTPM/include/fTPM.h#L42
+ */
+static const uuid_t dp_ta_uuid =
+	UUID_INIT(0x99975014, 0x3c7c, 0x54ea,
+		  0x84, 0x87, 0xa8, 0x0d, 0x21, 0x5e, 0xa9, 0x2c);
+
+/**
+ * dp_tee_op_send() - send dp commands through the TEE shared memory.
+ * @len:	the number of bytes to send.
+ *
+ * Return:
+ *	In case of success, returns 0.
+ *	On failure, -errno
+ */
+static int dp_tee_op_send(struct dp_tee_private *dp_tee_priv, size_t len, u32 cmd_id)
+{
+	int rc;
+	u8 *temp_buf;
+	struct tee_ioctl_invoke_arg transceive_args;
+	struct tee_param command_params[4];
+	struct tee_shm *shm = dp_tee_priv->shm;
+
+	if (len > MAX_COMMAND_SIZE) {
+		TLCERR("%s: len=%zd exceeds MAX_COMMAND_SIZE supported by dp TA\n", __func__, len);
+		return -EIO;
+	}
+
+	memset(&transceive_args, 0, sizeof(transceive_args));
+	memset(command_params, 0, sizeof(command_params));
+	dp_tee_priv->resp_len = 0;
+
+	/* Invoke FTPM_OPTEE_TA_SUBMIT_COMMAND function of dp TA */
+	transceive_args = (struct tee_ioctl_invoke_arg) {
+		.func = cmd_id,
+		.session = dp_tee_priv->session,
+		.num_params = 4,
+	};
+
+	/* Fill FTPM_OPTEE_TA_SUBMIT_COMMAND parameters */
+	command_params[0] = (struct tee_param) {
+		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
+		.u.memref = {
+			.shm = shm,
+			.size = len,
+			.shm_offs = 0,
+		},
+	};
+
+	command_params[1] = (struct tee_param) {
+		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
+		.u.memref = {
+			.shm = shm,
+			.size = MAX_RESPONSE_SIZE,
+			.shm_offs = MAX_COMMAND_SIZE,
+		},
+	};
+
+	rc = tee_client_invoke_func(dp_tee_priv->ctx, &transceive_args, command_params);
+	if (rc < 0 || transceive_args.ret != 0) {
+		TLCERR("%s: invoke error: 0x%x\n", __func__, transceive_args.ret);
+		return (rc < 0) ? rc : transceive_args.ret;
+	}
+
+	temp_buf = tee_shm_get_va(shm, command_params[1].u.memref.shm_offs);
+	if (IS_ERR(temp_buf)) {
+		TLCERR("%s: tee_shm_get_va failed for receive\n", __func__);
+		return PTR_ERR(temp_buf);
+	}
+
+	/* Sanity checks look good, cache the response */
+	memcpy(dp_tee_priv->resp_buf, temp_buf, MAX_RESPONSE_SIZE / 2);
+	dp_tee_priv->resp_len = MAX_RESPONSE_SIZE / 2;
+
+	return 0;
+}
+
+/*
+ * Check whether this driver supports the dp TA in the TEE instance
+ * represented by the params (ver/data) to this function.
+ */
+static int dp_tee_match(struct tee_ioctl_version_data *ver, const void *data)
+{
+	/*
+	 * Currently this driver only support GP Complaint OPTEE based dp TA
+	 */
+	if (ver->impl_id == TEE_IMPL_ID_OPTEE && ver->gen_caps & TEE_GEN_CAP_GP)
+		return 1;
+	else
+		return 0;
+}
+
+int tee_add_device(struct mtk_hdcp_info *hdcp_info, u32 version)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = NULL;
+	struct tee_ioctl_open_session_arg sess_arg;
+	struct tci_t *tci;
+
+	if (hdcp_info->g_init)
+		tee_remove_device(hdcp_info);
+
+	dp_tee_priv = kzalloc(sizeof(*dp_tee_priv), GFP_KERNEL);
+	if (!dp_tee_priv) {
+		kfree(dp_tee_priv);
+		TLCERR("%s: tee_alloc_memory failed\n", __func__);
+		return -ENOMEM;
+	}
+	hdcp_info->g_dp_tee_priv = dp_tee_priv;
+
+	/* Open context with TEE driver */
+	dp_tee_priv->ctx = tee_client_open_context(NULL, dp_tee_match, NULL, NULL);
+	if (IS_ERR(dp_tee_priv->ctx)) {
+		if (PTR_ERR(dp_tee_priv->ctx) == -ENOENT) {
+			kfree(dp_tee_priv);
+			return -EPROBE_DEFER;
+		}
+		kfree(dp_tee_priv);
+		TLCERR("%s: tee_client_open_context failed\n", __func__);
+		return PTR_ERR(dp_tee_priv->ctx);
+	}
+
+	/* Open a session with dp TA */
+	memset(&sess_arg, 0, sizeof(sess_arg));
+	export_uuid(sess_arg.uuid, &dp_ta_uuid);
+	sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
+	sess_arg.num_params = 0;
+
+	rc = tee_client_open_session(dp_tee_priv->ctx, &sess_arg, NULL);
+	if (rc < 0 || sess_arg.ret != 0) {
+		kfree(dp_tee_priv);
+		TLCERR("tee_client_open_session failed, err=%x\n", sess_arg.ret);
+		rc = -EINVAL;
+		goto out_tee_session;
+	}
+	dp_tee_priv->session = sess_arg.session;
+
+	/* Allocate dynamic shared memory with dp TA */
+	dp_tee_priv->shm = tee_shm_alloc_kernel_buf(dp_tee_priv->ctx, MAX_COMMAND_SIZE
+	 + MAX_RESPONSE_SIZE);
+	if (IS_ERR(dp_tee_priv->shm)) {
+		kfree(dp_tee_priv);
+		TLCERR("%s: tee_shm_alloc_kernel_buf failed\n", __func__);
+		rc = -ENOMEM;
+		goto out_shm_alloc;
+	}
+	TLCINFO("Register 8k share memory successfully, (%p)",
+		dp_tee_priv->shm->kaddr);
+
+	/* Copy parameter for add new device */
+	tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+	memset(tci, 0, TCI_LENGTH);
+	tci->command_id = CMD_DEVICE_ADDED;
+	tci->cmd_body.cmd_hdcp_init_for_verion.version = version;
+	tci->cmd_body.cmd_hdcp_init_for_verion.need_load_key = true;
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_DEVICE_ADDED);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		tee_remove_device(hdcp_info);
+		return rc;
+	}
+
+	hdcp_info->g_init = true;
+
+	return rc;
+
+out_shm_alloc:
+	tee_client_close_session(dp_tee_priv->ctx, dp_tee_priv->session);
+out_tee_session:
+	tee_client_close_context(dp_tee_priv->ctx);
+
+	return rc;
+}
+
+void tee_remove_device(struct mtk_hdcp_info *hdcp_info)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	if (!hdcp_info->g_init)
+		return;
+
+	hdcp_info->g_init = false;
+	memset(tci, 0, TCI_LENGTH);
+	tci->command_id = CMD_DEVICE_REMOVE;
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_DEVICE_REMOVE);
+	if (rc != 0)
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+
+	/* Free the shared memory pool */
+	tee_shm_free(dp_tee_priv->shm);
+
+	/* Close the existing session with fTPM TA */
+	tee_client_close_session(dp_tee_priv->ctx, dp_tee_priv->session);
+
+	/* Close the context with TEE driver */
+	tee_client_close_context(dp_tee_priv->ctx);
+
+	/* Free the memory */
+	kfree(dp_tee_priv);
+}
+
+int tee_clear_paring(struct mtk_hdcp_info *hdcp_info)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	memset(tci, 0, TCI_LENGTH);
+	tci->command_id = CMD_DEVICE_CLEAN;
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_DEVICE_CLEAN);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+int tee_hdcp1x_set_tx_an(struct mtk_hdcp_info *hdcp_info, u8 *an_code)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_WRITE_VAL;
+	tci->cmd_body.cmd_hdcp_write_val.len = DRM_HDCP_AN_LEN;
+	tci->cmd_body.cmd_hdcp_write_val.type = TYPE_HDCP_PARAM_AN;
+	memcpy(tci->cmd_body.cmd_hdcp_write_val.val, an_code, DRM_HDCP_AN_LEN);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_WRITE_VAL);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+int tee_hdcp_enable_encrypt(struct mtk_hdcp_info *hdcp_info, bool enable, u8 version)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_ENABLE_ENCRYPT;
+	if (enable)
+		tci->cmd_body.cmd_hdcp_write_val.type = TYPE_HDCP_ENABLE_ENCRYPT;
+	else
+		tci->cmd_body.cmd_hdcp_write_val.type = TYPE_HDCP_DISABLE_ENCRYPT;
+
+	/* Set HDCP version supportted by device */
+	tci->cmd_body.cmd_hdcp_write_val.len = 1;
+	tci->cmd_body.cmd_hdcp_write_val.val[0] = version;
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_ENABLE_ENCRYPT);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+int tee_hdcp1x_soft_rst(struct mtk_hdcp_info *hdcp_info)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_WRITE_VAL;
+	tci->cmd_body.cmd_hdcp_write_val.type = TYPE_HDCP_PARAM_RST_1;
+	/* No need input. Set default value 0 for check */
+	tci->cmd_body.cmd_hdcp_write_val.len = DEFAULT_WRITE_VAL_LEN;
+	memset(tci->cmd_body.cmd_hdcp_write_val.val, DEFAULT_WRITE_VAL, DEFAULT_WRITE_VAL_LEN);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_WRITE_VAL);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+int tee_hdcp2_soft_rst(struct mtk_hdcp_info *hdcp_info)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	tci->command_id = CMD_WRITE_VAL;
+	tci->cmd_body.cmd_hdcp_write_val.type = TYPE_HDCP_PARAM_RST_2;
+	/* No need input. Set default value 0 for check */
+	tci->cmd_body.cmd_hdcp_write_val.len =
+		DEFAULT_WRITE_VAL_LEN;
+	memset(tci->cmd_body.cmd_hdcp_write_val.val, DEFAULT_WRITE_VAL, DEFAULT_WRITE_VAL_LEN);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_WRITE_VAL);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+/** V1.X **/
+int tee_get_aksv(struct mtk_hdcp_info *hdcp_info, u8 *aksv)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_GET_AKSV;
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_GET_AKSV);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	tci = (struct tci_t *)dp_tee_priv->resp_buf;
+	memcpy(aksv, tci->cmd_body.cmd_hdcp_get_aksv.aksv, DRM_HDCP_KSV_LEN);
+
+	return rc;
+}
+
+int tee_calculate_lm(struct mtk_hdcp_info *hdcp_info, u8 *bksv)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_CALCULATE_LM;
+	memcpy(tci->cmd_body.cmd_hdcp_calculate_lm.bksv, bksv, DRM_HDCP_KSV_LEN);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_CALCULATE_LM);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+int tee_compare_r0(struct mtk_hdcp_info *hdcp_info, u8 *r0, u32 len)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_COMPARE_R0;
+	tci->cmd_body.cmd_hdcp_compare.rx_val_len = len;
+	memcpy(tci->cmd_body.cmd_hdcp_compare.rx_val, r0, len);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_COMPARE_R0);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+int tee_hdcp1x_compute_compare_v(struct mtk_hdcp_info *hdcp_info,
+				 u8 *crypto_param, u32 param_len, u8 *rx_v)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_COMPARE_V1;
+	tci->cmd_body.cmd_hdcp_compare.rx_val_len = 20;
+	tci->cmd_body.cmd_hdcp_compare.param_len = param_len;
+	memcpy(tci->cmd_body.cmd_hdcp_compare.rx_val, rx_v, 20);
+	memcpy(tci->cmd_body.cmd_hdcp_compare.param, crypto_param, param_len);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_COMPARE_V1);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+/** V2.X **/
+int tee_ake_certificate(struct mtk_hdcp_info *hdcp_info,
+			u8 *certificate, bool *stored, u8 *out_m, u8 *out_ekm)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_AKE_CERTIFICATE;
+	memcpy(tci->cmd_body.cmd_hdcp_ake_certificate.certification,
+	       certificate, HDCP2_CERTRX_LEN);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_AKE_CERTIFICATE);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	TLCINFO("verify signature: result %d", rc);
+	tci = (struct tci_t *)dp_tee_priv->resp_buf;
+	*stored = tci->cmd_body.cmd_hdcp_ake_certificate.stored;
+	memcpy(out_m, tci->cmd_body.cmd_hdcp_ake_certificate.m,
+	       HDCP_2_2_E_KH_KM_M_LEN - HDCP_2_2_E_KH_KM_LEN);
+	memcpy(out_ekm, tci->cmd_body.cmd_hdcp_ake_certificate.ekm, HDCP_2_2_E_KH_KM_LEN);
+
+	return rc;
+}
+
+int tee_enc_rsaes_oaep(struct mtk_hdcp_info *hdcp_info, u8 *ekm)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_ENC_KM;
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_ENC_KM);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	tci = (struct tci_t *)dp_tee_priv->resp_buf;
+	memcpy(ekm, tci->cmd_body.cmd_hdcp_enc_km.enc_km, HDCP_2_2_E_KPUB_KM_LEN);
+
+	return rc;
+}
+
+int tee_ake_h_prime(struct mtk_hdcp_info *hdcp_info,
+		    u8 *rtx, u8 *rrx, u8 *rx_caps, u8 *tx_caps, u8 *rx_h, u32 rx_h_len)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_AKE_H_PRIME;
+	tci->cmd_body.cmd_hdcp_ake_h_prime.rx_h_len = rx_h_len;
+
+	memcpy(tci->cmd_body.cmd_hdcp_ake_h_prime.rtx, rtx, HDCP_2_2_RTX_LEN);
+	memcpy(tci->cmd_body.cmd_hdcp_ake_h_prime.rrx, rrx, HDCP_2_2_RRX_LEN);
+	memcpy(tci->cmd_body.cmd_hdcp_ake_h_prime.rx_caps, rx_caps, HDCP_2_2_RXCAPS_LEN);
+	memcpy(tci->cmd_body.cmd_hdcp_ake_h_prime.tx_caps, tx_caps, HDCP_2_2_TXCAPS_LEN);
+	memcpy(tci->cmd_body.cmd_hdcp_ake_h_prime.rx_h, rx_h, rx_h_len);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_AKE_H_PRIME);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	tci = (struct tci_t *)dp_tee_priv->resp_buf;
+	return tci->return_code;
+}
+
+int tee_ake_paring(struct mtk_hdcp_info *hdcp_info, u8 *rx_ekm)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_AKE_PARING;
+	memcpy(tci->cmd_body.cmd_hdcp_ake_paring.ekm, rx_ekm, HDCP_2_2_E_KH_KM_LEN);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_AKE_PARING);
+	if (rc != 0)
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+
+	return rc;
+}
+
+int tee_lc_l_prime(struct mtk_hdcp_info *hdcp_info, u8 *rn, u8 *rx_l, u32 len)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_LC_L_PRIME;
+	memcpy(tci->cmd_body.cmd_hdcp_lc_l_prime.rn, rn, HDCP_2_2_RN_LEN);
+	tci->cmd_body.cmd_hdcp_lc_l_prime.rx_l_len = len;
+	memcpy(tci->cmd_body.cmd_hdcp_lc_l_prime.rx_l, rx_l, len);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_LC_L_PRIME);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	tci = (struct tci_t *)dp_tee_priv->resp_buf;
+	return tci->return_code;
+}
+
+int tee_ske_enc_ks(struct mtk_hdcp_info *hdcp_info, u8 *riv, u8 *eks)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+	u8 *share_buffer = NULL;
+
+	/* Copy parameters */
+	tci->command_id = CMD_SKE_CAL_EKS;
+	memcpy(tci->cmd_body.cmd_hdcp_ske_eks.riv, riv, HDCP_2_2_RIV_LEN);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH + 16, CMD_SKE_CAL_EKS);
+	if (rc != 0)
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+
+	share_buffer = (u8 *)dp_tee_priv->resp_buf;
+	memcpy(eks, share_buffer + TCI_LENGTH, 16);
+
+	return rc;
+}
+
+int tee_hdcp2_compute_compare_v(struct mtk_hdcp_info *hdcp_info,
+				u8 *crypto_param, u32 param_len, u8 *rx_v, u8 *tx_v)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+	u8 *share_buffer = NULL;
+
+	/* Copy parameters */
+	tci->command_id = CMD_COMPARE_V2;
+	tci->cmd_body.cmd_hdcp_compare.rx_val_len = 16;
+	tci->cmd_body.cmd_hdcp_compare.param_len = param_len;
+	memcpy(tci->cmd_body.cmd_hdcp_compare.rx_val, rx_v, 16);
+	memcpy(tci->cmd_body.cmd_hdcp_compare.param, crypto_param, param_len);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_COMPARE_V2);
+	if (rc != 0) {
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+		return rc;
+	}
+
+	share_buffer = (u8 *)dp_tee_priv->resp_buf;
+	memcpy(tx_v, share_buffer + TCI_LENGTH, 16);
+
+	return rc;
+}
+
+int tee_hdcp2_compute_compare_m(struct mtk_hdcp_info *hdcp_info,
+				u8 *crypto_param, u32 param_len, u8 *rx_m)
+{
+	int rc;
+	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
+	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
+
+	/* Copy parameters */
+	tci->command_id = CMD_COMPARE_M;
+	tci->cmd_body.cmd_hdcp_compare.rx_val_len = HDCP_2_2_MPRIME_LEN;
+	tci->cmd_body.cmd_hdcp_compare.param_len = param_len;
+	memcpy(tci->cmd_body.cmd_hdcp_compare.rx_val, rx_m, HDCP_2_2_MPRIME_LEN);
+	memcpy(tci->cmd_body.cmd_hdcp_compare.param, crypto_param, param_len);
+
+	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_COMPARE_M);
+	if (rc != 0)
+		TLCERR("tee_op_send failed, error=%x\n", rc);
+
+	return rc;
+}
diff --git a/drivers/gpu/drm/mediatek/tlc_dp_hdcp.h b/drivers/gpu/drm/mediatek/tlc_dp_hdcp.h
new file mode 100644
index 000000000000..493d3c51a7a0
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/tlc_dp_hdcp.h
@@ -0,0 +1,414 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019-2024 MediaTek Inc.
+ */
+
+#ifndef _TLC_DP_HDCP_H_
+#define _TLC_DP_HDCP_H_
+
+#include <linux/printk.h>
+#include <linux/tee_drv.h>
+#include <linux/uuid.h>
+#include <linux/types.h>
+#include <linux/sched/clock.h>
+#include <drm/display/drm_dp_helper.h>
+#include "tci.h"
+
+#define TLCINFO(string, args...) pr_info("[TLC_HDCP]info: "string, ##args)
+#define TLCERR(string, args...) pr_info("[TLC_HDCP]line:%d,err:%s:"string,\
+	__LINE__, __func__, ##args)
+
+#define DPTXHDCPFUNC(fmt, arg...)		\
+	pr_info("[DPTXHDCP][%s line:%d]"pr_fmt(fmt), __func__, __LINE__, ##arg)
+#define DPTXHDCPMSG(fmt, arg...)                                  \
+		pr_info("[DPTXHDCP]"pr_fmt(fmt), ##arg)
+#define DPTXHDCPERR(fmt, arg...)                                  \
+		pr_err("[DPTXHDCP]"pr_fmt(fmt), ##arg)
+
+#define RET_SUCCESS 0
+
+/**
+ * hdcp version definitions
+ */
+#define HDCP_NONE                0x0 // No HDCP supported, no secure data path
+#define HDCP_V1                  0x1 // HDCP version 1.0
+#define HDCP_V2                  0x2 // HDCP version 2.0 Type 1
+#define HDCP_V2_1                0x3 // HDCP version 2.1 Type 1
+#define HDCP_V2_2                0x4 // HDCP version 2.2 Type 1
+#define HDCP_V2_3                0x5 // HDCP version 2.3 Type 1
+
+/* Local display only(content required version use only) */
+#define HDCP_LOCAL_DISPLAY_ONLY  0xf
+#define HDCP_NO_DIGITAL_OUTPUT   0xff // No digital output
+#define HDCP_DEFAULT             HDCP_NO_DIGITAL_OUTPUT // Default value
+
+#define HDCP_VERSION_1X 1
+#define HDCP_VERSION_2X 2
+
+/* max. buffer size supported by dp  */
+#define MAX_COMMAND_SIZE       4096
+#define MAX_RESPONSE_SIZE      4096
+
+#define HDCP1X_REP_MAXDEVS 128
+#define HDCP1X_V_LEN 20
+#define HDCP1X_B_INFO_LEN 2
+
+#define HDCP2_K_LEN 2
+#define HDCP2_STREAMID_TYPE_LEN 2
+
+enum HDCP_RESULT {
+	AUTH_ZERO = 0,
+	AUTH_PREPARE = 1,
+	AUTH_INIT = 2,
+	AUTH_PASS = 3,
+	AUTH_FAIL = 4,
+};
+
+struct dp_header {
+	__be16 tag;
+	__be32 length;
+	union {
+		__be32 ordinal;
+		__be32 return_code;
+	};
+} __packed;
+
+/**
+ * struct dp_tee_private - fTPM's private data
+ * @session:  dp TA session identifier.
+ * @resp_len: cached response buffer length.
+ * @resp_buf: cached response buffer.
+ * @ctx:      TEE context handler.
+ * @shm:      Memory pool shared with fTPM TA in TEE.
+ */
+struct dp_tee_private {
+	u32 session;
+	size_t resp_len;
+	u8 resp_buf[MAX_RESPONSE_SIZE];
+	struct tee_context *ctx;
+	struct tee_shm *shm;
+};
+
+struct hdcp2_info_tx {
+	struct hdcp2_ake_init ake_init;
+	struct hdcp2_ake_no_stored_km no_stored_km;
+	struct hdcp2_ske_send_eks send_eks;
+	struct hdcp2_lc_init lc_init;
+	struct hdcp2_rep_stream_manage stream_manage;
+	struct hdcp2_rep_send_ack send_ack;
+	struct hdcp2_tx_caps tx_caps;
+	u8 k[HDCP2_K_LEN];
+	u8 stream_id_type[HDCP2_STREAMID_TYPE_LEN];
+};
+
+struct hdcp2_info_rx {
+	struct hdcp2_cert_rx cert_rx;
+	struct hdcp2_ake_send_cert send_cert;
+	struct hdcp2_rep_send_receiverid_list receiverid_list;
+	struct hdcp2_ake_send_pairing_info pairing_info;
+	struct hdcp2_rep_stream_ready stream_ready;
+	struct hdcp2_ake_send_hprime send_hprime;
+	struct hdcp2_lc_send_lprime send_lprime;
+};
+
+struct hdcp2_handler {
+	u8 main_state;
+	u8 sub_state;
+	u8 down_stream_dev_cnt;
+	u8 hdcp_rx_ver;
+	bool send_ake_init:1;
+	bool get_recv_id_list:1;
+	bool stored_km:1;
+	bool send_lc_init:1;
+	bool send_ack:1;
+	bool sink_is_repeater:1;
+	bool recv_msg:1;
+	bool send_pair:1;
+	u32 seq_num_v_cnt;
+	u32 retry_cnt;
+};
+
+struct hdcp1x_info {
+	bool enable;
+	bool repeater;
+	bool r0_read;
+	bool ksv_ready;
+	bool max_cascade;
+	bool max_devs;
+	u8 b_status;
+	u8 b_ksv[DRM_HDCP_KSV_LEN];
+	u8 a_ksv[DRM_HDCP_KSV_LEN];
+	u8 v[HDCP1X_V_LEN];
+	u8 b_info[HDCP1X_B_INFO_LEN];
+	u8 ksvfifo[DRM_HDCP_KSV_LEN * (HDCP1X_REP_MAXDEVS - 1)];
+	u8 device_count;
+	u8 retry_count;
+	int main_states;
+	int sub_states;
+};
+
+struct hdcp2_info {
+	struct hdcp2_info_tx hdcp_tx;
+	struct hdcp2_info_rx hdcp_rx;
+	struct hdcp2_ake_stored_km ake_stored_km;
+	struct hdcp2_handler hdcp_handler;
+	bool enable;
+	bool repeater;
+	bool read_certrx;
+	bool read_h_prime;
+	bool read_pairing;
+	bool read_l_prime;
+	bool ks_exchange_done;
+	bool read_v_prime;
+	u8 retry_count;
+	u8 device_count;
+	u8 stream_id_type;
+};
+
+struct mtk_hdcp_info {
+	u8 auth_status;
+	bool g_init;
+	u32 hdcp_content_type;
+	u32 content_protection;
+	struct dp_tee_private *g_dp_tee_priv;
+	struct hdcp1x_info hdcp1x_info;
+	struct hdcp2_info hdcp2_info;
+};
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ *Description:
+ *  A device connect and do some initializations.
+ *
+ *Input:
+ *  version: HDCP version
+ *
+ *Returns:
+ *  TEEC_SUCCESS success*
+ */
+int tee_add_device(struct mtk_hdcp_info *hdcp_info, u32 version);
+
+/*
+ *Description:
+ *  Device disconnect.
+ *
+ *Returns:
+ *  N/A
+ */
+void tee_remove_device(struct mtk_hdcp_info *hdcp_info);
+
+/*
+ *Description:
+ *  Clearing paring info.
+ *
+ *Returns:
+ *  TEEC_SUCCESS success*
+ */
+int tee_clear_paring(struct mtk_hdcp_info *hdcp_info);
+
+/*
+ *Description:
+ *  Calculate Km base on Bksv and write it to HW.
+ *
+ *Input:
+ *  bksv[5] input
+ *
+ *Returns:
+ *  TEEC_SUCCESS success
+ */
+int tee_calculate_lm(struct mtk_hdcp_info *hdcp_info, u8 *bksv);
+
+/*
+ *Description:
+ *  Get Aksv from TEE.
+ *
+ *Output:
+ *  aksv[5]
+ *
+ *Returns:
+ *  TEEC_SUCCESS success
+ */
+int tee_get_aksv(struct mtk_hdcp_info *hdcp_info, u8 *aksv);
+
+/*
+ *Description:
+ *  Get r0 from HW and compare to rx_r0.
+ *
+ *Parameters:
+ *  r0[len] input
+ *
+ *Returns:
+ *  TEEC_SUCCESS success
+ */
+int tee_compare_r0(struct mtk_hdcp_info *hdcp_info, u8 *r0, u32 len);
+
+/*
+ *Description:
+ *  Compute and compare v value.
+ *
+ *Input:
+ *  crypto_param[param_len] params used to calculate
+ *  rx_v[20] v value from rx
+ *
+ *Returns:
+ *  RET_COMPARE_PASS verify pass
+ */
+int tee_hdcp1x_compute_compare_v(struct mtk_hdcp_info *hdcp_info,
+				 u8 *crypto_param, u32 param_len, u8 *rx_v);
+
+/*
+ *Description:
+ *  Write An to HW.
+ *
+ *Input:
+ *  an_code[8]
+ *
+ *Returns:
+ *  TEEC_SUCCESS success
+ */
+int tee_hdcp1x_set_tx_an(struct mtk_hdcp_info *hdcp_info, u8 *an_code);
+
+/*
+ *Description:
+ *  Write RST to HW.
+ *
+ *Returns:
+ *  TEEC_SUCCESS success
+ */
+int tee_hdcp1x_soft_rst(struct mtk_hdcp_info *hdcp_info);
+int tee_hdcp2_soft_rst(struct mtk_hdcp_info *hdcp_info);
+
+/*
+ *Description:
+ *  Set enable or disable to HW.
+ *
+ *Returns:
+ *  TEEC_SUCCESS success
+ */
+int tee_hdcp_enable_encrypt(struct mtk_hdcp_info *hdcp_info, bool enable, u8 version);
+
+/*
+ *Description:
+ *  AKE cetificate verify.
+ *
+ *Input:
+ *  certificate[522]: cert use to calculate
+ *output:
+ *  stored: whether be stored before
+ *  out_m[16]
+ *  out_ekm[16]
+ *
+ *Returns:
+ *  TEEC_SUCCESS success*
+ */
+int tee_ake_certificate(struct mtk_hdcp_info *hdcp_info,
+			u8 *certificate, bool *stored, u8 *out_m, u8 *out_ekm);
+
+/*
+ *Description:
+ *  Encrypt km.
+ *
+ *Output:
+ *  ekm[128]: encrypted km
+ *
+ *Returns:
+ *  TEEC_SUCCESS success*
+ */
+int tee_enc_rsaes_oaep(struct mtk_hdcp_info *hdcp_info, u8 *ekm);
+
+/*
+ *Description:
+ *  Calculate h prime and compare to rx_h
+ *
+ *Input:
+ *  rtx[8]
+ *  rrx[8]
+ *  rx_caps[3]
+ *  tx_caps[3]
+ *  rx_h[rx_h_len]
+ *
+ *Returns:
+ *  RET_COMPARE_PASS: compare pass
+ */
+int tee_ake_h_prime(struct mtk_hdcp_info *hdcp_info,
+		    u8 *rtx, u8 *rrx, u8 *rx_caps, u8 *tx_caps, u8 *rx_h, u32 rx_h_len);
+
+/*
+ *Description:
+ *  Store paring info.
+ *
+ *Input:
+ *  rx_ekm[16]
+ *
+ *Returns:
+ *  TEEC_SUCCESS success*
+ */
+int tee_ake_paring(struct mtk_hdcp_info *hdcp_info, u8 *rx_ekm);
+
+/*
+ *Description:
+ *  Calculate l prime and compare.
+ *
+ *Input:
+ *  rn[8]
+ *  rx_l[len]
+ *
+ *Returns:
+ *  RET_COMPARE_PASS compare pass
+ */
+int tee_lc_l_prime(struct mtk_hdcp_info *hdcp_info, u8 *rn, u8 *rx_l, u32 len);
+
+/*
+ *Description:
+ *  Encrypt ks
+ *  Write contentkey and riv to hw
+ *
+ *Input:
+ *  riv[8]
+ *Output:
+ *  eks[16]
+ *
+ *Returns:
+ *  TEEC_SUCCESS success*
+ */
+int tee_ske_enc_ks(struct mtk_hdcp_info *hdcp_info, u8 *riv, u8 *eks);
+
+/*
+ *Description:
+ *  Calculate and compare v prime for repeater.
+ *
+ *Input:
+ *  crypto_param[param_len] params used to calculate
+ *  rx_v[16] v value from rx
+ *Output:
+ *  tx_v[16]
+ *
+ *Returns:
+ *  TEEC_SUCCESS success*
+ */
+int tee_hdcp2_compute_compare_v(struct mtk_hdcp_info *hdcp_info,
+				u8 *crypto_param, u32 param_len, u8 *rx_v, u8 *tx_v);
+
+/*
+ *Description:
+ *  Calculate and compare m prime for repeater.
+ *
+ *Input:
+ *  crypto_param[param_len] params used to calculate
+ *  rx_m[32] m value from rx
+ *
+ *Returns:
+ *  RET_COMPARE_PASS verify pass
+ */
+int tee_hdcp2_compute_compare_m(struct mtk_hdcp_info *hdcp_info,
+				u8 *crypto_param, u32 param_len, u8 *rx_m);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TLC_DP_HDCP_H_ */
-- 
2.43.0



From mac.shen at mediatek.com  Sun Feb  4 21:50:37 2024
From: mac.shen at mediatek.com (mac.shen)
Date: Mon, 5 Feb 2024 13:50:37 +0800
Subject: [PATCH v2 2/3] Subject: [PATCH] drm/mediatek/dp: Add HDCP2.x feature for DisplayPort
In-Reply-To: <20240205055055.25340-1-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
Message-ID: <20240205055055.25340-3-mac.shen@mediatek.com>

Add HDCP2.x feature for DisplayPort.
When userspace request the kernel protect future content communicated
over the link with Content_Protection property, the feature will do
HDCP2.x authentication if the sink support HDCP2.X.

Changes in v2:
- remove switch case, and refine code to make more clear
- remove some definitions, and use the definitions in
  include/drm/drm_hdcp.h
- use the struct which defined in include/drm/drm_hdcp.h
- do HDCP2.x authentication when userspace request the
  kernel protect future content communicated
per suggestion from the previous thread:
https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
9218a545c46.camel at mediatek.com/

Signed-off-by: mac.shen <mac.shen at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile       |    1 +
 drivers/gpu/drm/mediatek/mtk_dp.c       |  297 +++++--
 drivers/gpu/drm/mediatek/mtk_dp.h       |   99 +++
 drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c | 1021 +++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h |   52 ++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h   |    4 +-
 drivers/gpu/drm/mediatek/mtk_dpi.c      |    3 +
 7 files changed, 1392 insertions(+), 85 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index c80e6c2f9336..50ea069b047e 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -27,6 +27,7 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
 
 mtk-dp-objs := tlc_dp_hdcp.o \
+		  mtk_dp_hdcp2.o \
 		  mtk_dp.o
 
 obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk-dp.o
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index e4c16ba9902d..7ff72f15528b 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2019-2022 MediaTek Inc.
+ * Copyright (c) 2019-2024 MediaTek Inc.
  * Copyright (c) 2022 BayLibre
  */
 
@@ -8,13 +8,13 @@
 #include <drm/display/drm_dp.h>
 #include <drm/display/drm_dp_helper.h>
 #include <drm/drm_atomic_helper.h>
-#include <drm/drm_bridge.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/display/drm_hdcp_helper.h>
 #include <linux/arm-smccc.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
@@ -30,10 +30,10 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/soc/mediatek/mtk_sip_svc.h>
-#include <sound/hdmi-codec.h>
-#include <video/videomode.h>
 
+#include "mtk_dp.h"
 #include "mtk_dp_reg.h"
+#include "mtk_dp_hdcp2.h"
 
 #define MTK_DP_SIP_CONTROL_AARCH32	MTK_SIP_SMC_CMD(0x523)
 #define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE	(BIT(0) | BIT(5))
@@ -52,43 +52,6 @@
 #define MTK_DP_VERSION 0x11
 #define MTK_DP_SDP_AUI 0x4
 
-enum {
-	MTK_DP_CAL_GLB_BIAS_TRIM = 0,
-	MTK_DP_CAL_CLKTX_IMPSE,
-	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_0,
-	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_1,
-	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_2,
-	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_3,
-	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_0,
-	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_1,
-	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_2,
-	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_3,
-	MTK_DP_CAL_MAX,
-};
-
-struct mtk_dp_train_info {
-	bool sink_ssc;
-	bool cable_plugged_in;
-	/* link_rate is in multiple of 0.27Gbps */
-	int link_rate;
-	int lane_count;
-	unsigned int channel_eq_pattern;
-};
-
-struct mtk_dp_audio_cfg {
-	bool detect_monitor;
-	int sad_count;
-	int sample_rate;
-	int word_length_bits;
-	int channels;
-};
-
-struct mtk_dp_info {
-	enum dp_pixelformat format;
-	struct videomode vm;
-	struct mtk_dp_audio_cfg audio_cur_cfg;
-};
-
 struct mtk_dp_efuse_fmt {
 	unsigned short idx;
 	unsigned short shift;
@@ -98,44 +61,6 @@ struct mtk_dp_efuse_fmt {
 	unsigned short default_val;
 };
 
-struct mtk_dp {
-	bool enabled;
-	bool need_debounce;
-	int irq;
-	u8 max_lanes;
-	u8 max_linkrate;
-	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
-	u32 cal_data[MTK_DP_CAL_MAX];
-	u32 irq_thread_handle;
-	/* irq_thread_lock is used to protect irq_thread_handle */
-	spinlock_t irq_thread_lock;
-
-	struct device *dev;
-	struct drm_bridge bridge;
-	struct drm_bridge *next_bridge;
-	struct drm_connector *conn;
-	struct drm_device *drm_dev;
-	struct drm_dp_aux aux;
-
-	const struct mtk_dp_data *data;
-	struct mtk_dp_info info;
-	struct mtk_dp_train_info train_info;
-
-	struct platform_device *phy_dev;
-	struct phy *phy;
-	struct regmap *regs;
-	struct timer_list debounce_timer;
-
-	/* For audio */
-	bool audio_enable;
-	hdmi_codec_plugged_cb plugged_cb;
-	struct platform_device *audio_pdev;
-
-	struct device *codec_dev;
-	/* protect the plugged_cb as it's used in both bridge ops and audio */
-	struct mutex update_plugged_status_lock;
-};
-
 struct mtk_dp_data {
 	int bridge_type;
 	unsigned int smc_cmd;
@@ -319,12 +244,28 @@ static struct regmap_config mtk_dp_regmap_config = {
 	.name = "mtk-dp-registers",
 };
 
+u32 mtk_dp_get_system_time(void)
+{
+	u32 tms = (u32)((sched_clock() / 1000000) % 1000000);
+	return tms;
+}
+
+u32 mtk_dp_get_time_diff(u32 pre_time)
+{
+	u32 post_time = mtk_dp_get_system_time();
+
+	if (pre_time > post_time)
+		return ((1000000 - pre_time) + post_time);
+	else
+		return (post_time - pre_time);
+}
+
 static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
 {
 	return container_of(b, struct mtk_dp, bridge);
 }
 
-static u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
+u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
 {
 	u32 read_val;
 	int ret;
@@ -350,8 +291,8 @@ static int mtk_dp_write(struct mtk_dp *mtk_dp, u32 offset, u32 val)
 	return ret;
 }
 
-static int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset,
-			      u32 val, u32 mask)
+int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset,
+		       u32 val, u32 mask)
 {
 	int ret = regmap_update_bits(mtk_dp->regs, offset, mask, val);
 
@@ -1865,6 +1806,160 @@ static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
 	mtk_dp_digital_sw_reset(mtk_dp);
 }
 
+void mtk_dp_check_hdcp_version(struct mtk_dp *mtk_dp, bool only_hdcp1x)
+{
+	if (!only_hdcp1x && dp_tx_hdcp2_support(&mtk_dp->hdcp_info))
+		return;
+
+	if (tee_add_device(&mtk_dp->hdcp_info, HDCP_NONE) != RET_SUCCESS)
+		mtk_dp->hdcp_info.auth_status = AUTH_FAIL;
+}
+
+static void mtk_dp_check_sink_esi(struct mtk_dp *mtk_dp)
+{
+	u8 clear_cp_irq = BIT(2);
+
+	if (mtk_dp->hdcp_info.hdcp2_info.enable) {
+		dp_tx_hdcp2_irq(&mtk_dp->hdcp_info);
+		drm_dp_dpcd_write(&mtk_dp->aux,
+				  DP_DEVICE_SERVICE_IRQ_VECTOR, &clear_cp_irq, 0x1);
+	}
+	/*hdcp 1.x do not need irq*/
+}
+
+static void mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
+{
+	ssize_t ret;
+	u8 sink_count;
+	u8 sink_count_200;
+
+	ret = drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT_ESI, &sink_count);
+	if (ret < 0) {
+		drm_info(mtk_dp->drm_dev, "Read sink count failed: %ld\n", ret);
+		return;
+	}
+
+	ret = drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count_200);
+	if (ret < 0) {
+		drm_info(mtk_dp->drm_dev,
+			 "Read DP_SINK_COUNT_ESI failed: %ld\n", ret);
+		return;
+	}
+
+	mtk_dp_check_sink_esi(mtk_dp);
+}
+
+static void mtk_dp_hdcp_handle(struct work_struct *data)
+{
+	struct mtk_dp *mtk_dp = container_of(data, struct mtk_dp, hdcp_work);
+
+	if (!mtk_dp->train_info.cable_plugged_in)
+		return;
+
+	if (mtk_dp->hdcp_info.auth_status == AUTH_PREPARE) {
+		mtk_dp_check_hdcp_version(mtk_dp, false);
+		if (mtk_dp->hdcp_info.hdcp2_info.enable)
+			dp_tx_hdcp2_set_start_auth(&mtk_dp->hdcp_info, true);
+		else
+			mtk_dp->hdcp_info.auth_status = AUTH_ZERO;
+	}
+
+	while (mtk_dp->hdcp_info.hdcp2_info.enable &&
+	       mtk_dp->hdcp_info.auth_status != AUTH_FAIL &&
+			mtk_dp->hdcp_info.auth_status != AUTH_PASS) {
+		if (mtk_dp->hdcp_info.hdcp2_info.enable)
+			dp_tx_hdcp2_fsm(&mtk_dp->hdcp_info);
+	}
+}
+
+static void mtk_dp_hdcp_prop_work(struct work_struct *work)
+{
+	struct mtk_dp *mtk_dp;
+	struct delayed_work *dework;
+	struct drm_device *drm_dev;
+
+	dework = to_delayed_work(work);
+	mtk_dp = container_of(dework, struct mtk_dp, prop_work);
+
+	if (!mtk_dp->conn) {
+		dev_err(mtk_dp->dev, "connector is null!");
+		return;
+	}
+
+	drm_dev = mtk_dp->conn->dev;
+
+	drm_modeset_lock(&drm_dev->mode_config.connection_mutex, NULL);
+
+	if (mtk_dp->hdcp_info.content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+		mtk_dp->hdcp_info.content_protection =
+		(mtk_dp->hdcp_info.auth_status == AUTH_PASS) ? DRM_MODE_CONTENT_PROTECTION_ENABLED :
+		DRM_MODE_CONTENT_PROTECTION_DESIRED;
+	else
+		mtk_dp->hdcp_info.content_protection =
+		(mtk_dp->hdcp_info.auth_status == AUTH_PASS) ? DRM_MODE_CONTENT_PROTECTION_ENABLED :
+		DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
+
+	dev_info(mtk_dp->dev, "update CP, content protection: %d, auth status:%d\n",
+		 mtk_dp->hdcp_info.content_protection, mtk_dp->hdcp_info.auth_status);
+	drm_hdcp_update_content_protection(mtk_dp->conn, mtk_dp->hdcp_info.content_protection);
+
+	drm_modeset_unlock(&drm_dev->mode_config.connection_mutex);
+}
+
+static void mtk_dp_hdcp_atomic_check(struct mtk_dp *mtk_dp, struct drm_connector_state *state)
+{
+	unsigned int hdcp_content_type = state->hdcp_content_type;
+	unsigned int content_protection = state->content_protection;
+
+	dev_dbg(mtk_dp->dev, "CP type and protection, atomic: %d, %d, driver:%d, %d\n",
+		hdcp_content_type, content_protection,
+		mtk_dp->hdcp_info.hdcp_content_type, mtk_dp->hdcp_info.content_protection);
+
+	if ((content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
+	     mtk_dp->hdcp_info.content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
+		(hdcp_content_type != mtk_dp->hdcp_info.hdcp_content_type &&
+		 content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
+		mtk_dp->hdcp_info.content_protection = content_protection;
+
+		dev_dbg(mtk_dp->dev, "disable HDCP\n");
+		if (mtk_dp->hdcp_info.hdcp2_info.enable)
+			dp_tx_hdcp2_set_start_auth(&mtk_dp->hdcp_info, false);
+
+		drm_hdcp_update_content_protection(mtk_dp->conn,
+						   mtk_dp->hdcp_info.content_protection);
+	}
+
+	if (content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED ||
+	    (hdcp_content_type != mtk_dp->hdcp_info.hdcp_content_type &&
+		 content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
+		mtk_dp->hdcp_info.content_protection = content_protection;
+		mtk_dp->hdcp_info.hdcp_content_type = hdcp_content_type;
+		mtk_dp->hdcp_info.hdcp2_info.stream_id_type = hdcp_content_type;
+
+		if (mtk_dp->hdcp_info.auth_status == AUTH_FAIL ||
+		    mtk_dp->hdcp_info.auth_status == AUTH_ZERO) {
+			dev_dbg(mtk_dp->dev, "enable HDCP\n");
+			mtk_dp_authentication(&mtk_dp->hdcp_info);
+
+			queue_delayed_work(mtk_dp->hdcp_workqueue,
+					   &mtk_dp->prop_work, msecs_to_jiffies(2000));
+		}
+	}
+}
+
+void mtk_dp_authentication(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+
+	if (!mtk_dp->train_info.cable_plugged_in)
+		return;
+
+	hdcp_info->auth_status = AUTH_PREPARE;
+
+	dev_info(mtk_dp->dev, "dp start HDCP work");
+	queue_work(mtk_dp->hdcp_workqueue, &mtk_dp->hdcp_work);
+}
+
 static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 {
 	struct mtk_dp *mtk_dp = dev;
@@ -1894,9 +1989,11 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 		}
 	}
 
-	if (status & MTK_DP_THREAD_HPD_EVENT)
+	if (status & MTK_DP_THREAD_HPD_EVENT) {
 		dev_dbg(mtk_dp->dev, "Receive IRQ from sink devices\n");
-
+		/*check if need clear hpd irq*/
+		mtk_dp_hpd_sink_event(mtk_dp);
+	}
 	return IRQ_HANDLED;
 }
 
@@ -2233,6 +2330,7 @@ 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 *connector_state;
 	int ret;
 
 	mtk_dp->conn = drm_atomic_get_new_connector_for_encoder(old_state->base.state,
@@ -2243,6 +2341,8 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
 		return;
 	}
 
+	connector_state = drm_atomic_get_connector_state(old_state->base.state, mtk_dp->conn);
+
 	mtk_dp_aux_panel_poweron(mtk_dp, true);
 
 	/* Training */
@@ -2272,6 +2372,14 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
 	mtk_dp->enabled = true;
 	mtk_dp_update_plugged_status(mtk_dp);
 
+	/* Enable hdcp if it's desired */
+	dev_info(mtk_dp->dev, "hdcp_content_type:%d, content protection: %d",
+		 connector_state->hdcp_content_type, connector_state->content_protection);
+	if (connector_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
+		mtk_dp->hdcp_info.hdcp_content_type = connector_state->hdcp_content_type;
+		mtk_dp_authentication(&mtk_dp->hdcp_info);
+	}
+
 	return;
 power_off_aux:
 	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
@@ -2284,6 +2392,17 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
 {
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
 
+	if (mtk_dp->hdcp_info.hdcp2_info.enable)
+		dp_tx_hdcp2_set_start_auth(&mtk_dp->hdcp_info, false);
+
+	if (mtk_dp->hdcp_info.content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
+		mtk_dp->hdcp_info.content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+		dev_info(mtk_dp->dev, "update CP, content protection: %d\n",
+			 mtk_dp->hdcp_info.content_protection);
+		drm_hdcp_update_content_protection(mtk_dp->conn,
+						   mtk_dp->hdcp_info.content_protection);
+	}
+
 	mtk_dp->enabled = false;
 	mtk_dp_update_plugged_status(mtk_dp);
 	mtk_dp_video_enable(mtk_dp, false);
@@ -2418,6 +2537,8 @@ static int mtk_dp_bridge_atomic_check(struct drm_bridge *bridge,
 
 	drm_display_mode_to_videomode(&crtc_state->adjusted_mode, &mtk_dp->info.vm);
 
+	mtk_dp_hdcp_atomic_check(mtk_dp, conn_state);
+
 	return 0;
 }
 
@@ -2657,6 +2778,14 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	INIT_WORK(&mtk_dp->hdcp_work, mtk_dp_hdcp_handle);
+	INIT_DELAYED_WORK(&mtk_dp->prop_work, mtk_dp_hdcp_prop_work);
+	mtk_dp->hdcp_workqueue = create_workqueue("mtk_dp_hdcp_work");
+	if (!mtk_dp->hdcp_workqueue) {
+		dev_err(mtk_dp->dev, "failed to create hdcp work queue");
+		return -ENOMEM;
+	}
+
 	mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs;
 	mtk_dp->bridge.of_node = dev->of_node;
 	mtk_dp->bridge.type = mtk_dp->data->bridge_type;
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.h b/drivers/gpu/drm/mediatek/mtk_dp.h
new file mode 100644
index 000000000000..85c0cf0005c0
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019-2024 MediaTek Inc.
+ */
+
+#ifndef _MTK_DP_H_
+#define _MTK_DP_H_
+
+#include "tlc_dp_hdcp.h"
+#include <drm/drm_bridge.h>
+#include <sound/hdmi-codec.h>
+#include <video/videomode.h>
+
+enum {
+	MTK_DP_CAL_GLB_BIAS_TRIM = 0,
+	MTK_DP_CAL_CLKTX_IMPSE,
+	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_0,
+	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_1,
+	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_2,
+	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_3,
+	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_0,
+	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_1,
+	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_2,
+	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_3,
+	MTK_DP_CAL_MAX,
+};
+
+struct mtk_dp_audio_cfg {
+	bool detect_monitor;
+	int sad_count;
+	int sample_rate;
+	int word_length_bits;
+	int channels;
+};
+
+struct mtk_dp_info {
+	enum dp_pixelformat format;
+	struct videomode vm;
+	struct mtk_dp_audio_cfg audio_cur_cfg;
+};
+
+struct mtk_dp_train_info {
+	bool sink_ssc;
+	bool cable_plugged_in;
+	/* link_rate is in multiple of 0.27Gbps */
+	int link_rate;
+	int lane_count;
+	unsigned int channel_eq_pattern;
+};
+
+struct mtk_dp {
+	bool enabled;
+	bool need_debounce;
+	int irq;
+	u8 max_lanes;
+	u8 max_linkrate;
+	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
+	u32 cal_data[MTK_DP_CAL_MAX];
+	u32 irq_thread_handle;
+	/* irq_thread_lock is used to protect irq_thread_handle */
+	spinlock_t irq_thread_lock;
+
+	struct device *dev;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct drm_connector *conn;
+	struct drm_device *drm_dev;
+	struct drm_dp_aux aux;
+
+	const struct mtk_dp_data *data;
+	struct mtk_dp_info info;
+	struct mtk_dp_train_info train_info;
+	struct mtk_hdcp_info hdcp_info;
+	struct work_struct hdcp_work;
+	struct delayed_work prop_work;
+	struct workqueue_struct *hdcp_workqueue;
+
+	struct platform_device *phy_dev;
+	struct phy *phy;
+	struct regmap *regs;
+	struct timer_list debounce_timer;
+
+	/* For audio */
+	bool audio_enable;
+	hdmi_codec_plugged_cb plugged_cb;
+	struct platform_device *audio_pdev;
+
+	struct device *codec_dev;
+	/* protect the plugged_cb as it's used in both bridge ops and audio */
+	struct mutex update_plugged_status_lock;
+};
+
+u32 mtk_dp_get_system_time(void);
+u32 mtk_dp_get_time_diff(u32 pre_time);
+u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset);
+int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset, u32 val, u32 mask);
+void mtk_dp_authentication(struct mtk_hdcp_info *hdcp_info);
+
+#endif /* _MTK_DP_H_ */
diff --git a/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c b/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c
new file mode 100644
index 000000000000..8528e33f3f49
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c
@@ -0,0 +1,1021 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019-2024 MediaTek Inc.
+ */
+
+#include "mtk_dp_hdcp2.h"
+#include "mtk_dp_reg.h"
+#include "mtk_dp.h"
+
+u8 t_rtx[HDCP_2_2_RTX_LEN] = {
+	0x18, 0xfa, 0xe4, 0x20, 0x6a, 0xfb, 0x51, 0x49
+};
+
+u8 t_tx_caps[HDCP_2_2_TXCAPS_LEN] = {
+	0x02, 0x00, 0x00
+};
+
+u8 t_rn[HDCP_2_2_RN_LEN] = {
+	0x32, 0x75, 0x3e, 0xa8, 0x78, 0xa6, 0x38, 0x1c
+};
+
+u8 t_riv[HDCP_2_2_RIV_LEN] = {
+	0x40, 0x2b, 0x6b, 0x43, 0xc5, 0xe8, 0x86, 0xd8
+};
+
+static void dp_tx_hdcp2_fill_stream_type(struct mtk_hdcp_info *hdcp_info, u8 uc_type)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+
+	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34D0, uc_type, 0xff);
+}
+
+static void dp_tx_hdcp2_set_state(struct mtk_hdcp_info *hdcp_info, u8 main_state, u8 sub_state)
+{
+	hdcp_info->hdcp2_info.hdcp_handler.main_state = main_state;
+	hdcp_info->hdcp2_info.hdcp_handler.sub_state = sub_state;
+}
+
+static void dp_tx_hdcp2_set_auth_pass(struct mtk_hdcp_info *hdcp_info, bool enable)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+
+	if (enable) {
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3400, BIT(11), BIT(11));
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4, BIT(4), BIT(4));
+	} else {
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3400, 0, BIT(11));
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4, 0, BIT(4));
+	}
+}
+
+static void dp_tx_hdcp2_enable_auth(struct mtk_hdcp_info *hdcp_info, bool enable)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+
+	DPTXHDCPFUNC();
+	dp_tx_hdcp2_set_auth_pass(hdcp_info, enable);
+	if (enable) {
+		u32 version = HDCP_V2_3;
+
+		if (hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info[1] & BIT(0))
+			version = HDCP_V1;
+		else if (hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info[1] & BIT(1))
+			version = HDCP_V2;
+
+		tee_hdcp_enable_encrypt(hdcp_info, enable, version);
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, BIT(5), BIT(5));
+	} else {
+		tee_hdcp_enable_encrypt(hdcp_info, enable, HDCP_NONE);
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, 0, BIT(5));
+	}
+}
+
+static int dp_tx_hdcp2_init(struct mtk_hdcp_info *hdcp_info)
+{
+	int err_code = HDCP_ERR_NONE;
+
+	DPTXHDCPFUNC();
+
+	memset(&hdcp_info->hdcp2_info.hdcp_tx, 0, sizeof(struct hdcp2_info_tx));
+	memset(&hdcp_info->hdcp2_info.hdcp_rx, 0, sizeof(struct hdcp2_info_rx));
+	memcpy(hdcp_info->hdcp2_info.hdcp_tx.ake_init.r_tx, t_rtx, HDCP_2_2_RTX_LEN);
+	memcpy(&hdcp_info->hdcp2_info.hdcp_tx.tx_caps, t_tx_caps, HDCP_2_2_TXCAPS_LEN);
+	memcpy(hdcp_info->hdcp2_info.hdcp_tx.lc_init.r_n, t_rn, HDCP_2_2_RN_LEN);
+	memcpy(hdcp_info->hdcp2_info.hdcp_tx.send_eks.riv, t_riv, HDCP_2_2_RIV_LEN);
+
+	memset(&hdcp_info->hdcp2_info.hdcp_handler, 0, sizeof(struct hdcp2_handler));
+	memset(&hdcp_info->hdcp2_info.ake_stored_km, 0, sizeof(struct hdcp2_ake_stored_km));
+
+	dp_tx_hdcp2_enable_auth(hdcp_info, false);
+
+	return err_code;
+}
+
+static bool dp_tx_hdcp2_inc_seq_num_m(struct mtk_hdcp_info *hdcp_info)
+{
+	u32 tmp = 0;
+
+	tmp = drm_hdcp_be24_to_cpu(hdcp_info->hdcp2_info.hdcp_tx.stream_manage.seq_num_m);
+
+	if (tmp == 0xFFFFFF)
+		return false;
+
+	tmp++;
+
+	drm_hdcp_cpu_to_be24(hdcp_info->hdcp2_info.hdcp_tx.stream_manage.seq_num_m, tmp);
+	return true;
+}
+
+static bool dp_tx_hdcp2_process_rep_auth_stream_manage(struct mtk_hdcp_info *hdcp_info)
+{
+	bool ret = false;
+
+	hdcp_info->hdcp2_info.hdcp_tx.k[0] = 0x00;
+	hdcp_info->hdcp2_info.hdcp_tx.k[1] = 0x01;
+
+	hdcp_info->hdcp2_info.hdcp_tx.stream_id_type[0] = 0x00; //Payload ID
+	hdcp_info->hdcp2_info.hdcp_tx.stream_id_type[1] = hdcp_info->hdcp2_info.stream_id_type;
+
+	ret = dp_tx_hdcp2_inc_seq_num_m(hdcp_info);
+
+	return ret;
+}
+
+static bool dp_tx_hdcp2_recv_rep_auth_send_recv_id_list(struct mtk_hdcp_info *hdcp_info)
+{
+	bool ret = false;
+	u8 *buffer = NULL;
+	u32 len = 0, len_recv_id_list = 0;
+	int rc = 0;
+
+	len_recv_id_list = hdcp_info->hdcp2_info.device_count * HDCP_2_2_RECEIVER_ID_LEN;
+	len = len_recv_id_list + HDCP_2_2_RXINFO_LEN + HDCP_2_2_SEQ_NUM_LEN;
+	buffer = kmalloc(len, GFP_KERNEL);
+	if (!buffer) {
+		pr_err("2.x: Out of Memory\n");
+		return ret;
+	}
+
+	memcpy(buffer, hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.receiver_ids,
+	       len_recv_id_list);
+	memcpy(buffer + len_recv_id_list,
+	       hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info, HDCP_2_2_RXINFO_LEN);
+	memcpy(buffer + len_recv_id_list + HDCP_2_2_RXINFO_LEN,
+	       hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v, HDCP_2_2_SEQ_NUM_LEN);
+
+	rc = tee_hdcp2_compute_compare_v(hdcp_info, buffer, len,
+					 hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.v_prime,
+		hdcp_info->hdcp2_info.hdcp_tx.send_ack.v);
+
+	if (rc == RET_COMPARE_PASS) {
+		ret = true;
+		DPTXHDCPMSG("2.x: V' is PASS!!\n");
+	} else {
+		DPTXHDCPMSG("2.x: V' is FAIL!!\n");
+	}
+
+	kfree(buffer);
+	return ret;
+}
+
+static bool dp_tx_hdcp2_recv_rep_auth_stream_ready(struct mtk_hdcp_info *hdcp_info)
+{
+	bool ret = false;
+	u8 *buffer = NULL;
+	u32 len = 0;
+	int tmp = 0;
+
+	len = HDCP2_STREAMID_TYPE_LEN + HDCP_2_2_SEQ_NUM_LEN;
+	buffer = kmalloc(len, GFP_KERNEL);
+	if (!buffer) {
+		pr_err("2.x: Out of Memory\n");
+		return ret;
+	}
+
+	memcpy(buffer, hdcp_info->hdcp2_info.hdcp_tx.stream_id_type, HDCP2_STREAMID_TYPE_LEN);
+	memcpy(buffer + HDCP2_STREAMID_TYPE_LEN,
+	       hdcp_info->hdcp2_info.hdcp_tx.stream_manage.seq_num_m,
+	       HDCP_2_2_SEQ_NUM_LEN);
+	tmp = tee_hdcp2_compute_compare_m(hdcp_info, buffer, len,
+					  hdcp_info->hdcp2_info.hdcp_rx.stream_ready.m_prime);
+
+	if (tmp == RET_COMPARE_PASS) {
+		ret = true;
+		DPTXHDCPMSG("2.x: M' is PASS!!\n");
+	} else {
+		DPTXHDCPMSG("2.x: M' is FAIL!!\n");
+	}
+
+	kfree(buffer);
+	return ret;
+}
+
+static bool dp_tx_hdcp2_check_seq_num_v(struct mtk_hdcp_info *hdcp_info)
+{
+	if ((hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[0] == 0x00 &&
+	     hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[1] == 0x00 &&
+			hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[2] == 0x00) &&
+		hdcp_info->hdcp2_info.hdcp_handler.seq_num_v_cnt > 0xFFFFFF) {
+		DPTXHDCPMSG("2.x: SeqNumV Rollover!\n");
+		return false;
+	}
+
+	if ((hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[0]
+		!= (u8)((hdcp_info->hdcp2_info.hdcp_handler.seq_num_v_cnt & 0xFF0000) >> 16)) ||
+			(hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[1]
+		!= (u8)((hdcp_info->hdcp2_info.hdcp_handler.seq_num_v_cnt & 0x00FF00) >> 8)) ||
+			(hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[2]
+		!= (u8)((hdcp_info->hdcp2_info.hdcp_handler.seq_num_v_cnt & 0x0000FF)))) {
+		DPTXHDCPMSG("2.x: Invalid Seq_num_V!\n");
+		return false;
+	}
+
+	hdcp_info->hdcp2_info.hdcp_handler.seq_num_v_cnt++;
+	return true;
+}
+
+static void dp_tx_hdcp2_err_handle(struct mtk_hdcp_info *hdcp_info, int err_msg, int line)
+{
+	pr_err("2.x: MainState:%d; SubState:%d;\n", hdcp_info->hdcp2_info.hdcp_handler.main_state,
+	       hdcp_info->hdcp2_info.hdcp_handler.sub_state);
+
+	switch (err_msg) {
+	case HDCP_ERR_UNKNOWN_STATE:
+		pr_err("2.x: Unknown State, line:%d\n", line);
+		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_H1P1, HDCP_2_2_AUTH_FAIL);
+		break;
+
+	case HDCP_ERR_SEND_MSG_FAIL:
+		pr_err("2.x: Send Msg Fail, line:%d\n", line);
+		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0, HDCP_2_2_NULL_MSG);
+		break;
+	case HDCP_ERR_RESPONSE_TIMEROUT:
+		pr_err("2.x: Response Timeout, line:%d!\n", line);
+		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0, HDCP_2_2_NULL_MSG);
+		break;
+
+	case HDCP_ERR_PROCESS_FAIL:
+		pr_err("2.x: Process Fail, line:%d!\n", line);
+		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0, HDCP_2_2_NULL_MSG);
+		break;
+
+	default:
+		pr_err("2.x: NO ERROR!");
+		break;
+	}
+}
+
+static bool dp_tx_hdcp2_read_msg(struct mtk_hdcp_info *hdcp_info, u8 cmd_ID)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	bool ret = false;
+	u8 size = 0;
+
+	switch (cmd_ID) {
+	case HDCP_2_2_AKE_SEND_CERT:
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_CERT_RX_OFFSET,
+				 (void *)&hdcp_info->hdcp2_info.hdcp_rx.cert_rx, HDCP2_CERTRX_LEN);
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RRX_OFFSET,
+				 hdcp_info->hdcp2_info.hdcp_rx.send_cert.r_rx, HDCP_2_2_RRX_LEN);
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
+				 hdcp_info->hdcp2_info.hdcp_rx.send_cert.rx_caps,
+				 HDCP_2_2_RXCAPS_LEN);
+
+		hdcp_info->hdcp2_info.read_certrx = false;
+		hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
+		ret = true;
+		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_SEND_CERT\n");
+		break;
+
+	case HDCP_2_2_AKE_SEND_HPRIME:
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_HPRIME_OFFSET,
+				 hdcp_info->hdcp2_info.hdcp_rx.send_hprime.h_prime,
+				 HDCP_2_2_H_PRIME_LEN);
+
+		hdcp_info->hdcp2_info.read_h_prime = false;
+		hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
+		ret = true;
+
+		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_SEND_HPRIME\n");
+		break;
+
+	case HDCP_2_2_AKE_SEND_PAIRING_INFO:
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_EKH_KM_RD_OFFSET,
+				 hdcp_info->hdcp2_info.hdcp_rx.pairing_info.e_kh_km,
+				 HDCP_2_2_E_KH_KM_LEN);
+		hdcp_info->hdcp2_info.read_pairing = false;
+		hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
+		ret = true;
+		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_SEND_PAIRING_INFO\n");
+		break;
+
+	case HDCP_2_2_LC_SEND_LPRIME:
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_LPRIME_OFFSET,
+				 hdcp_info->hdcp2_info.hdcp_rx.send_lprime.l_prime,
+				 HDCP_2_2_L_PRIME_LEN);
+
+		hdcp_info->hdcp2_info.read_l_prime = false;
+		hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
+		ret = true;
+		DPTXHDCPMSG("2.x: HDCP_2_2_LC_SEND_LPRIME\n");
+		break;
+
+	case HDCP_2_2_REP_SEND_RECVID_LIST:
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RXINFO_OFFSET,
+				 hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info,
+				 HDCP_2_2_RXINFO_LEN);
+		hdcp_info->hdcp2_info.device_count =
+			((hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info[1] & 0xf0) >> 4)
+				| ((hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info[0]
+				& BIT(0)) << 4);
+
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_SEQ_NUM_V_OFFSET,
+				 hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v,
+				 HDCP_2_2_SEQ_NUM_LEN);
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_VPRIME_OFFSET,
+				 hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.v_prime,
+				 HDCP_2_2_V_PRIME_HALF_LEN);
+		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RECV_ID_LIST_OFFSET,
+				 hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.receiver_ids,
+			hdcp_info->hdcp2_info.device_count * HDCP_2_2_RECEIVER_ID_LEN);
+
+		hdcp_info->hdcp2_info.read_v_prime = false;
+		hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
+		ret = true;
+		DPTXHDCPMSG("2.x: HDCP_2_2_REP_SEND_RECVID_LIST\n");
+		break;
+
+	case HDCP_2_2_REP_STREAM_READY:
+		size = drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_MPRIME_OFFSET,
+					hdcp_info->hdcp2_info.hdcp_rx.stream_ready.m_prime,
+					HDCP_2_2_MPRIME_LEN);
+
+		if (size == HDCP_2_2_MPRIME_LEN)
+			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
+		ret = true;
+		DPTXHDCPMSG("2.x: HDCP_2_2_REP_STREAM_READY\n");
+		break;
+
+	default:
+		DPTXHDCPMSG("2.x: Invalid DPTX_HDCP2_OffSETADDR_ReadMessage !\n");
+		break;
+	}
+
+	return ret;
+}
+
+static bool dp_tx_hdcp2_write_msg(struct mtk_hdcp_info *hdcp_info, u8 cmd_ID)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	bool ret = false;
+
+	switch (cmd_ID) {
+	case HDCP_2_2_AKE_INIT:
+		tee_hdcp2_soft_rst(hdcp_info);
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_RTX_OFFSET,
+				  hdcp_info->hdcp2_info.hdcp_tx.ake_init.r_tx, HDCP_2_2_RTX_LEN);
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_TXCAPS_OFFSET,
+				  (void *)&hdcp_info->hdcp2_info.hdcp_tx.tx_caps,
+				  HDCP_2_2_TXCAPS_LEN);
+
+		ret = true;
+		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_Init !\n");
+		break;
+
+	case HDCP_2_2_AKE_NO_STORED_KM:
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_EKPUB_KM_OFFSET,
+				  hdcp_info->hdcp2_info.hdcp_tx.no_stored_km.e_kpub_km,
+				  HDCP_2_2_E_KPUB_KM_LEN);
+
+		ret = true;
+
+		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_NO_STORED_KM !\n");
+		break;
+
+	case HDCP_2_2_AKE_STORED_KM:
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_EKH_KM_WR_OFFSET,
+				  hdcp_info->hdcp2_info.ake_stored_km.e_kh_km_m,
+				  HDCP_2_2_E_KH_KM_LEN);
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_M_OFFSET,
+				  hdcp_info->hdcp2_info.ake_stored_km.e_kh_km_m +
+				  HDCP_2_2_E_KH_KM_LEN,
+				  HDCP_2_2_E_KH_KM_M_LEN - HDCP_2_2_E_KH_KM_LEN);
+
+		ret = true;
+
+		DPTXHDCPMSG("2.x: DPTX_HDCP_2_2_AKE_STORED_KM !\n");
+		break;
+
+	case HDCP_2_2_LC_INIT:
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_RN_OFFSET,
+				  hdcp_info->hdcp2_info.hdcp_tx.lc_init.r_n, HDCP_2_2_RN_LEN);
+
+		hdcp_info->hdcp2_info.read_l_prime = true;
+		ret = true;
+
+		DPTXHDCPMSG("2.x: HDCP_2_2_LC_INIT !\n");
+		break;
+
+	case HDCP_2_2_SKE_SEND_EKS:
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_EDKEY_KS_OFFSET,
+				  hdcp_info->hdcp2_info.hdcp_tx.send_eks.e_dkey_ks,
+				  HDCP_2_2_E_DKEY_KS_LEN);
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_RIV_OFFSET,
+				  hdcp_info->hdcp2_info.hdcp_tx.send_eks.riv, HDCP_2_2_RIV_LEN);
+
+		hdcp_info->hdcp2_info.ks_exchange_done = true;
+
+		ret = true;
+		DPTXHDCPMSG("2.x: HDCP_2_2_SKE_SEND_EKS !\n");
+		break;
+
+	case HDCP_2_2_STREAM_TYPE:
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET,
+				  hdcp_info->hdcp2_info.hdcp_tx.stream_id_type, 1);
+
+		ret = true;
+		DPTXHDCPMSG("HDCP2_MSG_DP_STREAM_TYPE !\n");
+		break;
+
+	case HDCP_2_2_REP_SEND_ACK:
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_V_OFFSET,
+				  hdcp_info->hdcp2_info.hdcp_tx.send_ack.v,
+				  HDCP_2_2_V_PRIME_HALF_LEN);
+
+		ret = true;
+		DPTXHDCPMSG("2.x: HDCP_2_2_SEND_ACK !\n");
+		break;
+
+	case HDCP_2_2_REP_STREAM_MANAGE:
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_SEQ_NUM_M_OFFSET,
+				  hdcp_info->hdcp2_info.hdcp_tx.stream_manage.seq_num_m,
+				  HDCP_2_2_SEQ_NUM_LEN);
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_K_OFFSET,
+				  hdcp_info->hdcp2_info.hdcp_tx.k, HDCP2_K_LEN);
+		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_STREAM_ID_TYPE_OFFSET,
+				  hdcp_info->hdcp2_info.hdcp_tx.stream_id_type,
+				  HDCP2_STREAMID_TYPE_LEN);
+
+		dp_tx_hdcp2_fill_stream_type(hdcp_info, hdcp_info->hdcp2_info.stream_id_type);
+
+		ret = true;
+		DPTXHDCPMSG("2.x: HDCP_2_2_STREAM_MANAGE !\n");
+		break;
+
+	default:
+		DPTXHDCPMSG("2.x: Invalid HDCP2_OffSETADDR_WriteMessage !\n");
+		break;
+	}
+
+	return ret;
+}
+
+static void dp_tx_hdcp2_rest_variable(struct mtk_hdcp_info *hdcp_info)
+{
+	hdcp_info->hdcp2_info.read_certrx = false;
+	hdcp_info->hdcp2_info.read_h_prime = false;
+	hdcp_info->hdcp2_info.read_pairing = false;
+	hdcp_info->hdcp2_info.read_l_prime = false;
+	hdcp_info->hdcp2_info.ks_exchange_done = false;
+	hdcp_info->hdcp2_info.read_v_prime = false;
+}
+
+int dp_tx_hdcp2_fsm(struct mtk_hdcp_info *hdcp_info)
+{
+	static u32 timeout_value;
+	static u8 pre_main;
+	static u8 pre_sub;
+	static u32 pre_time;
+	int err_code = HDCP_ERR_NONE;
+	bool stored = false;
+	u32 time;
+	int ret = 0;
+	bool tmp = false;
+
+	if (pre_main != hdcp_info->hdcp2_info.hdcp_handler.main_state ||
+	    hdcp_info->hdcp2_info.hdcp_handler.sub_state != pre_sub) {
+		DPTXHDCPMSG("2.x: Port(M : S)= (%d, %d)",
+			    hdcp_info->hdcp2_info.hdcp_handler.main_state,
+			    hdcp_info->hdcp2_info.hdcp_handler.sub_state);
+		pre_main = hdcp_info->hdcp2_info.hdcp_handler.main_state;
+		pre_sub = hdcp_info->hdcp2_info.hdcp_handler.sub_state;
+	}
+
+	switch (hdcp_info->hdcp2_info.hdcp_handler.main_state) {
+	case HDCP2_MS_H1P1:
+		/* HDCP2_MS_H1P1 */
+		/* HDCP_2_2_AUTH_FAIL */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AUTH_FAIL) {
+			pr_err("2.x: Authentication Fail!\n");
+			dp_tx_hdcp2_enable_auth(hdcp_info, false);
+			hdcp_info->auth_status = AUTH_FAIL;
+		}
+		break;
+
+	case HDCP2_MS_A0F0:
+		/* HDCP2_MS_A0F0 */
+		/* HDCP_2_2_NULL_MSG */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_NULL_MSG) {
+			if (!hdcp_info->hdcp2_info.enable) {
+				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_H1P1, HDCP_2_2_AUTH_FAIL);
+				DPTXHDCPMSG("2.x: Sink Doesn't Support Hdcp2x!\n");
+				break;
+			}
+
+			dp_tx_hdcp2_init(hdcp_info);
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1, HDCP_2_2_NULL_MSG);
+			DPTXHDCPMSG("2.x: Sink Support Hdcp2x!\n");
+		}
+		break;
+
+	case HDCP2_MS_A1F1:
+		/* HDCP2_MS_A1F1 */
+		/* HDCP_2_2_NULL_MSG */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_NULL_MSG) {
+			if (hdcp_info->hdcp2_info.retry_count >= HDCP2_TX_RETRY_CNT) {
+				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_H1P1, HDCP_2_2_AUTH_FAIL);
+				pr_err("2.x: Try Max Count\n");
+				break;
+			}
+
+			hdcp_info->hdcp2_info.retry_count++;
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1, HDCP_2_2_AKE_INIT);
+		}
+
+		/* HDCP2_MS_A1F1 */
+		/* HDCP_2_2_AKE_INIT */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AKE_INIT) {
+			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_AKE_INIT);
+			if (!tmp) {
+				err_code = HDCP_ERR_SEND_MSG_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+			dp_tx_hdcp2_rest_variable(hdcp_info);
+			hdcp_info->hdcp2_info.read_certrx = true;
+
+			hdcp_info->hdcp2_info.hdcp_handler.send_ake_init = true;
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1, HDCP_2_2_AKE_SEND_CERT);
+			pre_time = mtk_dp_get_system_time();
+		}
+
+		/* HDCP2_MS_A1F1 */
+		/* HDCP_2_2_AKE_SEND_CERT */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AKE_SEND_CERT) {
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time < HDCP_2_2_CERT_TIMEOUT_MS) {
+				msleep(20);
+				break;
+			}
+			if (hdcp_info->hdcp2_info.read_certrx)
+				dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_AKE_SEND_CERT);
+
+			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg)
+				break;
+
+			ret = tee_ake_certificate(hdcp_info,
+						  (u8 *)&hdcp_info->hdcp2_info.hdcp_rx.cert_rx,
+						  &stored,
+				hdcp_info->hdcp2_info.ake_stored_km.e_kh_km_m +
+				HDCP_2_2_E_KH_KM_LEN,
+				hdcp_info->hdcp2_info.ake_stored_km.e_kh_km_m);
+
+			if (ret != RET_COMPARE_PASS) {
+				err_code = HDCP_ERR_PROCESS_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			hdcp_info->hdcp2_info.hdcp_handler.stored_km = stored;
+			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
+					      hdcp_info->hdcp2_info.hdcp_handler.stored_km ?
+					HDCP_2_2_AKE_STORED_KM :
+					HDCP_2_2_AKE_NO_STORED_KM);
+		}
+
+		/* HDCP2_MS_A1F1 */
+		/* HDCP_2_2_AKE_NO_STORED_KM */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AKE_NO_STORED_KM) {
+			DPTXHDCPMSG("2.x: Get Km, derive Ekpub(km)\n");
+
+			tee_enc_rsaes_oaep(hdcp_info,
+					   hdcp_info->hdcp2_info.hdcp_tx.no_stored_km.e_kpub_km);
+			/* Prepare e_kpub_km to send */
+			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_AKE_NO_STORED_KM);
+			if (!tmp) {
+				err_code = HDCP_ERR_SEND_MSG_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1, HDCP_2_2_AKE_SEND_HPRIME);
+			timeout_value = HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS;
+			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
+			pre_time = mtk_dp_get_system_time();
+		}
+
+		/* HDCP2_MS_A1F1 */
+		/* HDCP_2_2_AKE_STORED_KM */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AKE_STORED_KM) {
+			/* Prepare ekh_km & M to send */
+			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_AKE_STORED_KM);
+			if (!tmp) {
+				err_code = HDCP_ERR_SEND_MSG_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			err_code = HDCP_ERR_NONE;
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1, HDCP_2_2_AKE_SEND_HPRIME);
+			timeout_value = HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS;
+			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
+			pre_time = mtk_dp_get_system_time();
+		}
+
+		/* HDCP2_MS_A1F1 */
+		/* HDCP_2_2_AKE_SEND_HPRIME */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AKE_SEND_HPRIME) {
+			if (hdcp_info->hdcp2_info.read_h_prime)
+				dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_AKE_SEND_HPRIME);
+
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time > timeout_value) {
+				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg)
+				break;
+
+			ret = tee_ake_h_prime(hdcp_info,
+					      hdcp_info->hdcp2_info.hdcp_tx.ake_init.r_tx,
+					      hdcp_info->hdcp2_info.hdcp_rx.send_cert.r_rx,
+				hdcp_info->hdcp2_info.hdcp_rx.send_cert.rx_caps,
+				(u8 *)&hdcp_info->hdcp2_info.hdcp_tx.tx_caps,
+				hdcp_info->hdcp2_info.hdcp_rx.send_hprime.h_prime,
+				HDCP_2_2_H_PRIME_LEN);
+			if (ret != RET_COMPARE_PASS) {
+				if (hdcp_info->hdcp2_info.hdcp_handler.stored_km)
+					tee_clear_paring(hdcp_info);
+				err_code = HDCP_ERR_PROCESS_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			if (hdcp_info->hdcp2_info.hdcp_handler.stored_km)
+				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A2F2, HDCP_2_2_LC_INIT);
+			else
+				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
+						      HDCP_2_2_AKE_SEND_PAIRING_INFO);
+
+			pre_time = mtk_dp_get_system_time();
+			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
+		}
+
+		/* HDCP2_MS_A1F1 */
+		/* HDCP_2_2_AKE_SEND_PAIRING_INFO */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
+			HDCP_2_2_AKE_SEND_PAIRING_INFO) {
+			if (hdcp_info->hdcp2_info.read_pairing)
+				dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_AKE_SEND_PAIRING_INFO);
+
+			/* Ekh_Km must be available less than 200ms, Give mode time for some Rx */
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time >	HDCP_2_2_PAIRING_TIMEOUT_MS * 2) {
+				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg)
+				break;
+
+			/* Store m, km, Ekh(km) */
+			tee_ake_paring(hdcp_info,
+				       hdcp_info->hdcp2_info.hdcp_rx.pairing_info.e_kh_km);
+
+			hdcp_info->hdcp2_info.hdcp_handler.send_pair = true;
+			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A2F2, HDCP_2_2_LC_INIT);
+			pre_time = mtk_dp_get_system_time();
+		}
+		break;
+
+	case HDCP2_MS_A2F2:
+		/* HDCP2_MS_A2F2 */
+		/* HDCP_2_2_LC_INIT */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_LC_INIT) {
+			/* prepare Rn to send */
+			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_LC_INIT);
+			if (!tmp) {
+				err_code = HDCP_ERR_SEND_MSG_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+			hdcp_info->hdcp2_info.hdcp_handler.send_lc_init = true;
+
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A2F2, HDCP_2_2_LC_SEND_LPRIME);
+			pre_time = mtk_dp_get_system_time();
+		}
+
+		/* HDCP2_MS_A2F2 */
+		/* HDCP_2_2_LC_SEND_LPRIME */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_LC_SEND_LPRIME) {
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time < HDCP_2_2_DP_HPRIME_READ_TIMEOUT_MS)
+				break;
+
+			if (hdcp_info->hdcp2_info.read_l_prime)
+				dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_LC_SEND_LPRIME);
+
+			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg)
+				break;
+
+			ret = tee_lc_l_prime(hdcp_info, hdcp_info->hdcp2_info.hdcp_tx.lc_init.r_n,
+					     hdcp_info->hdcp2_info.hdcp_rx.send_lprime.l_prime,
+					     HDCP_2_2_L_PRIME_LEN);
+			if (ret != RET_COMPARE_PASS) {
+				err_code = HDCP_ERR_PROCESS_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			DPTXHDCPMSG("2.x: L' is PASS!!\n");
+			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A3F3, HDCP_2_2_NULL_MSG);
+			pre_time = mtk_dp_get_system_time();
+		}
+		break;
+
+	case HDCP2_MS_A3F3:
+		/* HDCP2_MS_A3F3 */
+		/* HDCP_2_2_NULL_MSG */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_NULL_MSG) {
+			tee_ske_enc_ks(hdcp_info, hdcp_info->hdcp2_info.hdcp_tx.send_eks.riv,
+				       hdcp_info->hdcp2_info.hdcp_tx.send_eks.e_dkey_ks);
+
+			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_SKE_SEND_EKS);
+			if (!tmp) {
+				err_code = HDCP_ERR_SEND_MSG_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			if (!hdcp_info->hdcp2_info.repeater)
+				dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_STREAM_TYPE);
+
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A3F3, HDCP_2_2_SKE_SEND_EKS);
+			pre_time = mtk_dp_get_system_time();
+		}
+
+		/* HDCP2_MS_A3F3 */
+		/* HDCP_2_2_SKE_SEND_EKS */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_SKE_SEND_EKS) {
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time >= HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN)
+				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A4F4, HDCP_2_2_NULL_MSG);
+		}
+		break;
+
+	case HDCP2_MS_A4F4:
+		/* HDCP2_MS_A4F4 */
+		/* HDCP_2_2_NULL_MSG */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_NULL_MSG) {
+			if (!hdcp_info->hdcp2_info.repeater) {
+				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A5F5, HDCP_2_2_AUTH_DONE);
+				break;
+			}
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A6F6,
+					      HDCP_2_2_REP_SEND_RECVID_LIST);
+			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
+			pre_time = mtk_dp_get_system_time();
+		}
+		break;
+
+	case HDCP2_MS_A5F5:
+		/* HDCP2_MS_A5F5 */
+		/* HDCP_2_2_AUTH_DONE */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AUTH_DONE) {
+			DPTXHDCPMSG("2.x: Authentication done!\n");
+			hdcp_info->auth_status = AUTH_PASS;
+			hdcp_info->hdcp2_info.retry_count = 0;
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A5F5, HDCP_2_2_NULL_MSG);
+			dp_tx_hdcp2_enable_auth(hdcp_info, true);
+		}
+		break;
+
+	case HDCP2_MS_A6F6:
+		/* HDCP2_MS_A6F6 */
+		/* HDCP_2_2_REP_SEND_RECVID_LIST */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
+			HDCP_2_2_REP_SEND_RECVID_LIST) {
+			if (hdcp_info->hdcp2_info.read_v_prime)
+				dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_REP_SEND_RECVID_LIST);
+
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time > HDCP_2_2_RECVID_LIST_TIMEOUT_MS) {
+				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg)
+				break;
+
+			pre_time = mtk_dp_get_system_time();
+			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A7F7,
+					      HDCP_2_2_REP_VERIFY_RECVID_LIST);
+		}
+		break;
+
+	case HDCP2_MS_A7F7:
+		/* HDCP2_MS_A7F7 */
+		/* HDCP_2_2_REP_VERIFY_RECVID_LIST */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
+			HDCP_2_2_REP_VERIFY_RECVID_LIST) {
+			if ((hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info[1]
+				& (BIT(2) | BIT(3))) != 0) {
+				pr_err("2.x: DEVS_EXCEEDED or CASCADE_EXCEDDED!\n");
+				err_code = HDCP_ERR_PROCESS_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			/* check seqNumV here */
+			tmp = dp_tx_hdcp2_check_seq_num_v(hdcp_info);
+			if (!tmp) {
+				err_code = HDCP_ERR_PROCESS_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			tmp = dp_tx_hdcp2_recv_rep_auth_send_recv_id_list(hdcp_info);
+			if (!tmp) {
+				err_code = HDCP_ERR_PROCESS_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A8F8, HDCP_2_2_REP_SEND_ACK);
+		}
+		break;
+
+	case HDCP2_MS_A8F8:
+		/* HDCP2_MS_A8F8 */
+		/* HDCP_2_2_REP_SEND_ACK */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_REP_SEND_ACK) {
+			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_REP_SEND_ACK);
+			if (!tmp) {
+				err_code = HDCP_ERR_SEND_MSG_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time > HDCP2_REP_SEND_ACK) {
+				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A9F9, HDCP_2_2_REP_STREAM_MANAGE);
+			hdcp_info->hdcp2_info.hdcp_handler.retry_cnt = 0;
+		}
+		break;
+
+	case HDCP2_MS_A9F9:
+		/* HDCP2_MS_A9F9 */
+		/* HDCP_2_2_REP_STREAM_MANAGE */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_REP_STREAM_MANAGE) {
+			tmp = dp_tx_hdcp2_process_rep_auth_stream_manage(hdcp_info);
+			if (!tmp) {
+				err_code = HDCP_ERR_PROCESS_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_REP_STREAM_MANAGE);
+			if (!tmp) {
+				err_code = HDCP_ERR_SEND_MSG_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			pre_time = mtk_dp_get_system_time();
+			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A9F9,
+					      HDCP_2_2_REP_STREAM_READY);
+		}
+
+		/* HDCP2_MS_A9F9 */
+		/* HDCP_2_2_REP_STREAM_READY */
+		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_REP_STREAM_READY) {
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time <= HDCP_2_2_STREAM_READY_TIMEOUT_MS / 2)
+				break;
+
+			dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_REP_STREAM_READY);
+
+			time = mtk_dp_get_time_diff(pre_time);
+			if (time > HDCP_2_2_STREAM_READY_TIMEOUT_MS) {
+				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg) {
+				if (hdcp_info->hdcp2_info.hdcp_handler.retry_cnt
+					>= HDCP2_STREAM_MANAGE_RETRY_CNT) {
+					err_code = HDCP_ERR_RESPONSE_TIMEROUT;
+					dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+					break;
+				}
+
+				hdcp_info->hdcp2_info.hdcp_handler.retry_cnt++;
+
+				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A9F9,
+						      HDCP_2_2_REP_STREAM_READY);
+				break;
+			}
+
+			tmp = dp_tx_hdcp2_recv_rep_auth_stream_ready(hdcp_info);
+			if (!tmp) {
+				err_code = HDCP_ERR_PROCESS_FAIL;
+				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+				break;
+			}
+
+			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A5F5, HDCP_2_2_AUTH_DONE);
+		}
+		break;
+
+	default:
+		err_code = HDCP_ERR_UNKNOWN_STATE;
+		dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
+		break;
+	}
+
+	return err_code;
+}
+
+void dp_tx_hdcp2_set_start_auth(struct mtk_hdcp_info *hdcp_info, bool enable)
+{
+	hdcp_info->hdcp2_info.enable = enable;
+
+	if (enable) {
+		hdcp_info->auth_status = AUTH_INIT;
+		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0, HDCP_2_2_NULL_MSG);
+	} else {
+		hdcp_info->auth_status = AUTH_ZERO;
+		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_H1P1, HDCP_2_2_NULL_MSG);
+		dp_tx_hdcp2_enable_auth(hdcp_info, false);
+	}
+
+	hdcp_info->hdcp2_info.retry_count = 0;
+}
+
+bool dp_tx_hdcp2_support(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 tmp[3];
+	int ret;
+
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RX_CAPS_OFFSET, tmp, HDCP_2_2_RXCAPS_LEN);
+
+	if (HDCP_2_2_DP_HDCP_CAPABLE(tmp[2]) && tmp[0] == HDCP_2_2_RX_CAPS_VERSION_VAL) {
+		hdcp_info->hdcp2_info.enable = true;
+		hdcp_info->hdcp2_info.repeater = tmp[2] & BIT(0);
+	} else {
+		hdcp_info->hdcp2_info.enable = false;
+	}
+
+	DPTXHDCPMSG("2.x: CAPABLE: %d, Reapeater: %d\n", hdcp_info->hdcp2_info.enable,
+		    hdcp_info->hdcp2_info.repeater);
+
+	if (!hdcp_info->hdcp2_info.enable)
+		return false;
+
+	ret = tee_add_device(hdcp_info, HDCP_VERSION_2X);
+	if (ret != RET_SUCCESS) {
+		pr_err("2.x: HDCP TA has some error\n");
+		hdcp_info->hdcp2_info.enable = false;
+	}
+
+	return hdcp_info->hdcp2_info.enable;
+}
+
+bool dp_tx_hdcp2_irq(struct mtk_hdcp_info *hdcp_info)
+{
+	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
+	u8 rx_status = 0;
+
+	drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RXSTATUS_OFFSET, &rx_status,
+			 HDCP_2_2_DP_RXSTATUS_LEN);
+
+	if (rx_status & BIT(0)) {
+		DPTXHDCPMSG("2.x: READY_BIT0 Ready!\n");
+		hdcp_info->hdcp2_info.read_v_prime = true;
+	}
+
+	if (rx_status & BIT(1)) {
+		DPTXHDCPMSG("2.x: H'_AVAILABLE Ready!\n");
+		hdcp_info->hdcp2_info.read_h_prime = true;
+	}
+
+	if (rx_status & BIT(2)) {
+		DPTXHDCPMSG("2.x: PAIRING_AVAILABLE Ready!\n");
+		hdcp_info->hdcp2_info.read_pairing = true;
+	}
+
+	if (rx_status & BIT(4) || rx_status & BIT(3)) {
+		DPTXHDCPMSG("2.x: Re-Auth HDCP2X!\n");
+		dp_tx_hdcp2_set_start_auth(hdcp_info, true);
+		mtk_dp_authentication(hdcp_info);
+	}
+
+	return true;
+}
diff --git a/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h b/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h
new file mode 100644
index 000000000000..df309d3dcc6e
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019-2024 MediaTek Inc.
+ */
+
+#ifndef _MTK_dp_HDCP2_H_
+#define _MTK_dp_HDCP2_H_
+
+#include "tlc_dp_hdcp.h"
+
+/* Timeout relative */
+#define HDCP2_REP_SEND_ACK 2000
+
+/* Patch for QD980 LLCTS */
+#define HDCP2_TX_RETRY_CNT 3
+#define HDCP2_TX_LC_RETRY_CNT 1023
+#define HDCP2_STREAM_MANAGE_RETRY_CNT 8
+
+/* HDCP2.2 Msg IDs */
+#define HDCP_2_2_STREAM_TYPE 20
+#define HDCP_2_2_REP_VERIFY_RECVID_LIST 21
+#define HDCP_2_2_AUTH_FAIL 22
+#define HDCP_2_2_AUTH_DONE 23
+
+enum ENUM_HDCP2TX_MAIN_STATE {
+	HDCP2_MS_H1P1 = 0,
+	HDCP2_MS_A0F0 = 1,
+	HDCP2_MS_A1F1 = 2,
+	HDCP2_MS_A2F2 = 3,
+	HDCP2_MS_A3F3 = 4,
+	HDCP2_MS_A4F4 = 5,
+	HDCP2_MS_A5F5 = 6,
+	HDCP2_MS_A6F6 = 7,
+	HDCP2_MS_A7F7 = 8,
+	HDCP2_MS_A8F8 = 9,
+	HDCP2_MS_A9F9 = 10
+};
+
+enum ENUM_HDCP_ERR_CODE {
+	HDCP_ERR_NONE = 0,
+	HDCP_ERR_UNKNOWN_STATE,
+	HDCP_ERR_SEND_MSG_FAIL,
+	HDCP_ERR_RESPONSE_TIMEROUT,
+	HDCP_ERR_PROCESS_FAIL
+};
+
+int dp_tx_hdcp2_fsm(struct mtk_hdcp_info *hdcp_info);
+void dp_tx_hdcp2_set_start_auth(struct mtk_hdcp_info *hdcp_info, bool enable);
+bool dp_tx_hdcp2_support(struct mtk_hdcp_info *hdcp_info);
+bool dp_tx_hdcp2_irq(struct mtk_hdcp_info *hdcp_info);
+
+#endif /* _MTK_dp_HDCP2_H_ */
diff --git a/drivers/gpu/drm/mediatek/mtk_dp_reg.h b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
index 709b79480693..5cf5059762ed 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp_reg.h
+++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
@@ -1,8 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Copyright (c) 2019-2022 MediaTek Inc.
+ * Copyright (c) 2019-2024 MediaTek Inc.
  * Copyright (c) 2022 BayLibre
  */
+
 #ifndef _MTK_DP_REG_H_
 #define _MTK_DP_REG_H_
 
@@ -277,6 +278,7 @@
 #define HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT		BIT(1)
 #define MTK_DP_TRANS_P0_34A4				0x34a4
 #define LANE_NUM_DP_TRANS_P0_MASK				GENMASK(3, 2)
+#define MTK_DP_TRANS_P0_34D0                0x34D0
 #define MTK_DP_TRANS_P0_3540				0x3540
 #define FEC_EN_DP_TRANS_P0_MASK					BIT(0)
 #define FEC_CLOCK_EN_MODE_DP_TRANS_P0				BIT(3)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4e3d9f7b4d8c..7f4a8f7dfce2 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -25,6 +25,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/drm_simple_kms_helper.h>
+#include <drm/display/drm_hdcp_helper.h>
 
 #include "mtk_disp_drv.h"
 #include "mtk_dpi_regs.h"
@@ -820,6 +821,8 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
 	}
 	drm_connector_attach_encoder(dpi->connector, &dpi->encoder);
 
+	drm_connector_attach_content_protection_property(dpi->connector, true);
+
 	return 0;
 
 err_cleanup:
-- 
2.43.0



From rdunlap at infradead.org  Sun Feb  4 21:53:49 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Sun,  4 Feb 2024 21:53:49 -0800
Subject: [PATCH v2] soc: fsl: fix kernel-doc warnings and typos
Message-ID: <20240205055349.24410-1-rdunlap@infradead.org>

Correct spelling of "list".

Fix a kernel-doc warning by describing the nested structure completely:

include/soc/fsl/dpaa2-fd.h:52: warning: Function parameter or member 'simple' not described in 'dpaa2_fd'

Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
Cc: Li Yang <leoyang.li at nxp.com>
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: Frank Li <Frank.Li at nxp.com>
Cc: Guanhua Gao <guanhua.gao at nxp.com>
Cc: Roy Pledge <Roy.Pledge at nxp.com>
---
v2:  update Cc: list, rebase

 include/soc/fsl/dpaa2-fd.h |   19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff -- a/include/soc/fsl/dpaa2-fd.h b/include/soc/fsl/dpaa2-fd.h
--- a/include/soc/fsl/dpaa2-fd.h
+++ b/include/soc/fsl/dpaa2-fd.h
@@ -25,14 +25,15 @@
 
 /**
  * struct dpaa2_fd - Struct describing FDs
- * @words:         for easier/faster copying the whole FD structure
- * @addr:          address in the FD
- * @len:           length in the FD
- * @bpid:          buffer pool ID
- * @format_offset: format, offset, and short-length fields
- * @frc:           frame context
- * @ctrl:          control bits...including dd, sc, va, err, etc
- * @flc:           flow context address
+ * @words:                for easier/faster copying the whole FD structure
+ * @simple:               struct for the FD fields
+ * @simple.addr:          address in the FD
+ * @simple.len:           length in the FD
+ * @simple.bpid:          buffer pool ID
+ * @simple.format_offset: format, offset, and short-length fields
+ * @simple.frc:           frame context
+ * @simple.ctrl:          control bits...including dd, sc, va, err, etc
+ * @simple.flc:           flow context address
  *
  * This structure represents the basic Frame Descriptor used in the system.
  */
@@ -497,7 +498,7 @@ static inline void dpaa2_fl_set_addr(str
  * dpaa2_fl_get_frc() - Get the frame context in the FLE
  * @fle: the given frame list entry
  *
- * Return the frame context field in the frame lsit entry.
+ * Return the frame context field in the frame list entry.
  */
 static inline u32 dpaa2_fl_get_frc(const struct dpaa2_fl_entry *fle)
 {


From rdunlap at infradead.org  Sun Feb  4 21:53:55 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Sun,  4 Feb 2024 21:53:55 -0800
Subject: [PATCH v2] soc: fsl: dpio: fix kernel-doc typos
Message-ID: <20240205055355.24844-1-rdunlap@infradead.org>

Correct spelling of 2 words.

Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
Cc: Li Yang <leoyang.li at nxp.com>
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: Frank Li <Frank.Li at nxp.com>
Cc: Guanhua Gao <guanhua.gao at nxp.com>
Cc: Roy Pledge <Roy.Pledge at nxp.com>
---
v2:  update Cc: list, rebase

 include/soc/fsl/dpaa2-io.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff -- a/include/soc/fsl/dpaa2-io.h b/include/soc/fsl/dpaa2-io.h
--- a/include/soc/fsl/dpaa2-io.h
+++ b/include/soc/fsl/dpaa2-io.h
@@ -22,7 +22,7 @@ struct device;
  * DOC: DPIO Service
  *
  * The DPIO service provides APIs for users to interact with the datapath
- * by enqueueing and dequeing frame descriptors.
+ * by enqueueing and dequeueing frame descriptors.
  *
  * The following set of APIs can be used to enqueue and dequeue frames
  * as well as producing notification callbacks when data is available
@@ -33,7 +33,7 @@ struct device;
 
 /**
  * struct dpaa2_io_desc - The DPIO descriptor
- * @receives_notifications: Use notificaton mode. Non-zero if the DPIO
+ * @receives_notifications: Use notification mode. Non-zero if the DPIO
  *                  has a channel.
  * @has_8prio:      Set to non-zero for channel with 8 priority WQs.  Ignored
  *                  unless receives_notification is TRUE.


From shawn.gsc at gmail.com  Sun Feb  4 22:35:33 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 14:35:33 +0800
Subject: [PATCH v3 4/4] ARM: dts: imx6sl-tolino-shine2hd: fix touchscreen
 rotation
In-Reply-To: <20231223221213.774868-5-andreas@kemnade.info>
References: <20231223221213.774868-1-andreas@kemnade.info>
 <20231223221213.774868-5-andreas@kemnade.info>
Message-ID: <20240205063031.GC804317@dragon>

On Sat, Dec 23, 2023 at 11:12:13PM +0100, Andreas Kemnade wrote:
> The display is in landscape orientation, but the touchscreen is in portrait
> orientation. Specify that properly in the devicetree.
> 
> Signed-off-by: Andreas Kemnade <andreas at kemnade.info>

Applied, thanks!


From ghennadi.procopciuc at oss.nxp.com  Sun Feb  4 22:34:49 2024
From: ghennadi.procopciuc at oss.nxp.com (Ghennadi Procopciuc)
Date: Mon, 5 Feb 2024 08:34:49 +0200
Subject: [PATCH 1/3] dt-bindings: clock: s32g: add uSDHC clock IDs
In-Reply-To: <f45e02bb-1353-4c03-9a3d-294c3b78e8dd@oss.nxp.com>
References: <20240119130231.2854146-1-ghennadi.procopciuc@oss.nxp.com>
 <20240119130231.2854146-2-ghennadi.procopciuc@oss.nxp.com>
 <20240119-magnetic-racing-0adf8e5fbd4a@spud>
 <20240119-cattle-antarctic-432fa8e1c0ef@spud>
 <75a16ac3-39eb-4874-9100-d605b2cfadfc@oss.nxp.com>
 <20240121-statutory-endurance-6d03d7e734c9@spud>
 <f45e02bb-1353-4c03-9a3d-294c3b78e8dd@oss.nxp.com>
Message-ID: <f54d947c-58dc-498f-8871-b472f97be4a8@oss.nxp.com>

On 1/22/24 12:09, Ghennadi Procopciuc wrote:
> On 1/21/24 15:32, Conor Dooley wrote:
>> On Fri, Jan 19, 2024 at 11:25:57PM +0200, Ghennadi Procopciuc wrote:
>>> On 1/19/24 18:14, Conor Dooley wrote:
>>>> On Fri, Jan 19, 2024 at 04:11:37PM +0000, Conor Dooley wrote:
>>>>> On Fri, Jan 19, 2024 at 03:02:28PM +0200, Ghennadi Procopciuc (OSS) wrote:
>>>>>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>>>>>
>>>>>> Add the SCMI clock IDs for the uSDHC controller present on
>>>>>> S32G SoCs.
>>>>>>
>>>>>> Signed-off-by: Ciprian Costea <ciprianmarian.costea at nxp.com>
>>>>>> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>>>>> ---
>>>>>>  include/dt-bindings/clock/s32g-scmi-clock.h | 14 ++++++++++++++
>>>>>>  1 file changed, 14 insertions(+)
>>>>>>  create mode 100644 include/dt-bindings/clock/s32g-scmi-clock.h
>>>>>>
>>>>>> diff --git a/include/dt-bindings/clock/s32g-scmi-clock.h b/include/dt-bindings/clock/s32g-scmi-clock.h
>>>>>> new file mode 100644
>>>>>> index 000000000000..739f98a924c3
>>>>>> --- /dev/null
>>>>>> +++ b/include/dt-bindings/clock/s32g-scmi-clock.h
>>>>>> @@ -0,0 +1,14 @@
>>>>>> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
>>>>>> +/*
>>>>>> + * Copyright 2020-2024 NXP
>>>>>> + */
>>>>>> +#ifndef _DT_BINDINGS_SCMI_CLK_S32G_H
>>>>>> +#define _DT_BINDINGS_SCMI_CLK_S32G_H
>>>>>> +
>>>>>> +/* uSDHC */
>>>>>> +#define S32G_SCMI_CLK_USDHC_AHB		31
>>>>>> +#define S32G_SCMI_CLK_USDHC_MODULE	32
>>>>>> +#define S32G_SCMI_CLK_USDHC_CORE	33
>>>>>> +#define S32G_SCMI_CLK_USDHC_MOD32K	34
>>>>>
>>>>> Why do these numbers not start at 0?
>>>>
>>>> Ah, because these are the SCMI IDs directly. If these are numbers that
>>>> are in the TRM, just use the numbers directly - there's no need to
>>>> create bindings for that.
>>>>
>>>
>>> Hi Conor,
>>>
>>> I appreciate you taking the time to review the proposed changes. I
>>> wanted to clarify that the IDs mentioned in the header are SCMI IDs
>>> exported by the TF-A and are utilized by the second patch of this
>>> series. These IDs are for the uSDHC controller to control its clocks. As
>>> other SoCs use this model, I have included all the necessary IDs in a
>>> dedicated header file:
>>> - rk3588s     (arch/arm64/boot/dts/rockchip/rk3588s.dtsi:97 [0])
>>> - stm32mp157c (arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts:73 [1])
>>> - stm32mp131  (arch/arm/boot/dts/st/stm32mp131.dtsi:1372 [2])
>>>
>>> Should I remove the header and use raw numbers in the uSDHC node?
>>
>> IMO, yes. There's no abstraction/binding being created here if they're
>> the SCMI IDs.


I included the suggestion in the second version of this patchset.

>> Thanks,
>> conor.
> 
> Thank you for letting me know. I will make sure to include this change
> in the second version of the patchset.
> 
>>> For
>>> example:
>>>> +		usdhc0: mmc at 402f0000 {
>>>> +			compatible = "nxp,s32g2-usdhc";
>>>> +			reg = <0x402f0000 0x1000>;
>>>> +			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
>>>> +			clocks = <&clks 32>,
>>>> +				 <&clks 31>,
>>>> +				 <&clks 33>;
>>>> +			clock-names = "ipg", "ahb", "per";
>>>> +			bus-width = <8>;
>>>> +			status = "disabled";
>>>> +		};
>>>
>>> [0]
>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588s.dtsi#n97
>>> [1]
>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts#n73
>>> [2]
>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/st/stm32mp131.dtsi#n1372
>>>
>>> -- 
>>> Regards,
>>> Ghennadi



From senozhatsky at chromium.org  Sun Feb  4 22:48:25 2024
From: senozhatsky at chromium.org (Sergey Senozhatsky)
Date: Mon, 5 Feb 2024 15:48:25 +0900
Subject: [PATCH] zram: use copy_page for full page copy
In-Reply-To: <99a493e1e906637a179a80b1f27a4b6bd2a0a671.camel@mediatek.com>
References: <20231007070554.8657-1-mark-pk.tsai@mediatek.com>
 <20231008043855.GA2738554@google.com>
 <99a493e1e906637a179a80b1f27a4b6bd2a0a671.camel@mediatek.com>
Message-ID: <20240205064825.GD69174@google.com>

On (24/02/05 06:43), Mark-PK Tsai (???) wrote:
> On Sun, 2023-10-08 at 13:38 +0900, Sergey Senozhatsky wrote:
> >  	 
> > External email : Please do not click links or open attachments until
> > you have verified the sender or the content.
> >  On (23/10/07 15:05), Mark-PK Tsai wrote:
> > > 
> > > Some architectures, such as arm, have implemented
> > > optimized copy_page for full page copying.
> > > 
> > > Replace the full page memcpy with copy_page to
> > > take advantage of the optimization.
> > > 
> > > Signed-off-by: Mark-PK Tsai <mark-pk.tsai at mediatek.com>
> > 
> > Reviewed-by: Sergey Senozhatsky <senozhatsky at chromium.org>
> 
> I guess this patch may have been overlooked.
> Could someone please help to review it?

Oh, yes. Let me take care of that.


From senozhatsky at chromium.org  Sun Feb  4 22:50:24 2024
From: senozhatsky at chromium.org (Sergey Senozhatsky)
Date: Mon, 5 Feb 2024 15:50:24 +0900
Subject: [PATCH] zram: use copy_page for full page copy
In-Reply-To: <20231007070554.8657-1-mark-pk.tsai@mediatek.com>
References: <20231007070554.8657-1-mark-pk.tsai@mediatek.com>
Message-ID: <20240205065024.GE69174@google.com>

Cc-ing Andrew on this

On (23/10/07 15:05), Mark-PK Tsai wrote:
> Some architectures, such as arm, have implemented
> optimized copy_page for full page copying.
> 
> Replace the full page memcpy with copy_page to
> take advantage of the optimization.
> 
> Signed-off-by: Mark-PK Tsai <mark-pk.tsai at mediatek.com>

Reviewed-by: Sergey Senozhatsky <senozhatsky at chromium.org>

> ---
>  drivers/block/zram/zram_drv.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index d77d3664ca08..58700dd73d1d 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -1338,7 +1338,7 @@ static int zram_read_from_zspool(struct zram *zram, struct page *page,
>  	src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO);
>  	if (size == PAGE_SIZE) {
>  		dst = kmap_atomic(page);
> -		memcpy(dst, src, PAGE_SIZE);
> +		copy_page(dst, src);
>  		kunmap_atomic(dst);
>  		ret = 0;
>  	} else {
> -- 
> 2.18.0


From Mark-PK.Tsai at mediatek.com  Sun Feb  4 22:43:35 2024
From: Mark-PK.Tsai at mediatek.com (=?utf-8?B?TWFyay1QSyBUc2FpICjolKHmspvliZsp?=)
Date: Mon, 5 Feb 2024 06:43:35 +0000
Subject: [PATCH] zram: use copy_page for full page copy
In-Reply-To: <20231008043855.GA2738554@google.com>
References: <20231007070554.8657-1-mark-pk.tsai@mediatek.com>
	 <20231008043855.GA2738554@google.com>
Message-ID: <99a493e1e906637a179a80b1f27a4b6bd2a0a671.camel@mediatek.com>

On Sun, 2023-10-08 at 13:38 +0900, Sergey Senozhatsky wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  On (23/10/07 15:05), Mark-PK Tsai wrote:
> > 
> > Some architectures, such as arm, have implemented
> > optimized copy_page for full page copying.
> > 
> > Replace the full page memcpy with copy_page to
> > take advantage of the optimization.
> > 
> > Signed-off-by: Mark-PK Tsai <mark-pk.tsai at mediatek.com>
> 
> Reviewed-by: Sergey Senozhatsky <senozhatsky at chromium.org>

I guess this patch may have been overlooked.
Could someone please help to review it?

Thanks,
Mark

From billy_tsai at aspeedtech.com  Sun Feb  4 22:59:27 2024
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 5 Feb 2024 06:59:27 +0000
Subject: [PATCH v13 1/3] dt-bindings: hwmon: fan: Add fan binding to
 schema
In-Reply-To: <e1b1c69f-a2ff-4fa5-80a6-3ff0a3de6ce6@roeck-us.net>
References: <20240124060705.1342461-1-billy_tsai@aspeedtech.com>
 <20240124060705.1342461-2-billy_tsai@aspeedtech.com>
 <e1b1c69f-a2ff-4fa5-80a6-3ff0a3de6ce6@roeck-us.net>
Message-ID: <OSQPR06MB72522452AF463172AD54D4EA8B472@OSQPR06MB7252.apcprd06.prod.outlook.com>

> > From: Naresh Solanki <naresh.solanki at 9elements.com>
> >
> > Add common fan properties bindings to a schema.
> >
> > Bindings for fan controllers can reference the common schema for the
> > fan
> >
> > child nodes:
> >
> >   patternProperties:
> >     "^fan@[0-2]":
> >       type: object
> >       $ref: fan-common.yaml#
> >       unevaluatedProperties: false
> >
> > Signed-off-by: Naresh Solanki <naresh.solanki at 9elements.com>
> > Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>

> v12 of this patch got a Reviewed-by: tag from Rob.
> The tag is gone in this version, presumably meaning that there
> was a substantial change.

> I don't normally do this, but I downloaded v12 and v13 and did not
> find a single change. Why did you drop Rob's Reviewed-by: tag ?

Hi Guenter,

The fan DT-binding for version 12 is identical to that of version 13. I
apologize for forgetting to include the 'Reviewed-by' from Rob when
preparing version 13. I will make sure to include it when sending
version 14.

Thanks


From tony at atomide.com  Sun Feb  4 22:58:48 2024
From: tony at atomide.com (Tony Lindgren)
Date: Mon, 5 Feb 2024 08:58:48 +0200
Subject: [PATCH v2 01/15] gpio: pca953x: move suspend()/resume() to
 suspend_noirq()/resume_noirq()
In-Reply-To: <20240102-j7200-pcie-s2r-v2-1-8e4f7d228ec2@bootlin.com>
References: <20240102-j7200-pcie-s2r-v2-0-8e4f7d228ec2@bootlin.com>
 <20240102-j7200-pcie-s2r-v2-1-8e4f7d228ec2@bootlin.com>
Message-ID: <20240205065848.GC5185@atomide.com>

* Thomas Richard <thomas.richard at bootlin.com> [240126 14:37]:
> Some IOs can be needed during suspend_noirq()/resume_noirq().
> So move suspend()/resume() to noirq.

Hmm so what happened to the earlier i2c transfer at noirq level comments
from me and Linus W here? It seems the cover letter mentions it but I
don't see the related changes in this patch?

Regards,

Tony


From shawn.gsc at gmail.com  Sun Feb  4 23:02:23 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 15:02:23 +0800
Subject: [PATCH] arm64: dts: ls1046a: Remove big-endian from thermal
In-Reply-To: <20240103225942.1899784-1-festevam@gmail.com>
References: <20240103225942.1899784-1-festevam@gmail.com>
Message-ID: <ZcCH/9naj+ZO6yVp@t480>

On Wed, Jan 03, 2024 at 07:59:42PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> Per qoriq-thermal.yaml, 'big-endian' is not a valid property.
> 
> When the 'little-endian' property is absent, the default is big endian.
> 
> Remove it to fix the following schema warning:
> 
> tmu at 1f00000: 'big-endian' does not match any of the regexes: 'pinctrl-[0-9]+'
> from schema $id: http://devicetree.org/schemas/thermal/qoriq-thermal.yaml#
> 
> Signed-off-by: Fabio Estevam <festevam at denx.de>

Applied, thanks!


From michal.simek at amd.com  Sun Feb  4 23:02:49 2024
From: michal.simek at amd.com (Michal Simek)
Date: Mon, 5 Feb 2024 08:02:49 +0100
Subject: [PATCH V4 1/4] firmware: xilinx: Add ZynqMP efuse access API
In-Reply-To: <20240202113843.17999-2-praveen.teja.kundanala@amd.com>
References: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
 <20240202113843.17999-2-praveen.teja.kundanala@amd.com>
Message-ID: <39fbe614-82c0-4ec1-87b8-dacf72628220@amd.com>



On 2/2/24 12:38, Praveen Teja Kundanala wrote:
> Add zynqmp_pm_efuse_access API in the ZynqMP
> firmware for read/write access of efuse memory.
> 
> Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
> ---
>   drivers/firmware/xilinx/zynqmp.c     | 25 +++++++++++++++++++++++++
>   include/linux/firmware/xlnx-zynqmp.h |  8 ++++++++
>   2 files changed, 33 insertions(+)
> 
> diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
> index 79789f0563f6..9bc45357e1a8 100644
> --- a/drivers/firmware/xilinx/zynqmp.c
> +++ b/drivers/firmware/xilinx/zynqmp.c
> @@ -3,6 +3,7 @@
>    * Xilinx Zynq MPSoC Firmware layer
>    *
>    *  Copyright (C) 2014-2022 Xilinx, Inc.
> + *  Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
>    *
>    *  Michal Simek <michal.simek at amd.com>
>    *  Davorin Mista <davorin.mista at aggios.com>
> @@ -1384,6 +1385,30 @@ int zynqmp_pm_aes_engine(const u64 address, u32 *out)
>   }
>   EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine);
>   
> +/**
> + * zynqmp_pm_efuse_access - Provides access to efuse memory.
> + * @address:	Address of the efuse params structure
> + * @out:		Returned output value
> + *
> + * Return:	Returns status, either success or error code.
> + */
> +int zynqmp_pm_efuse_access(const u64 address, u32 *out)
> +{
> +	u32 ret_payload[PAYLOAD_ARG_CNT];
> +	int ret;
> +
> +	if (!out)
> +		return -EINVAL;
> +
> +	ret = zynqmp_pm_invoke_fn(PM_EFUSE_ACCESS, ret_payload, 2,
> +				  upper_32_bits(address),
> +				  lower_32_bits(address));
> +	*out = ret_payload[1];
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(zynqmp_pm_efuse_access);
> +
>   /**
>    * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash
>    * @address:	Address of the data/ Address of output buffer where
> diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
> index 9a7e52739251..1a069a56c961 100644
> --- a/include/linux/firmware/xlnx-zynqmp.h
> +++ b/include/linux/firmware/xlnx-zynqmp.h
> @@ -3,6 +3,7 @@
>    * Xilinx Zynq MPSoC Firmware layer
>    *
>    *  Copyright (C) 2014-2021 Xilinx
> + *  Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
>    *
>    *  Michal Simek <michal.simek at amd.com>
>    *  Davorin Mista <davorin.mista at aggios.com>
> @@ -171,6 +172,7 @@ enum pm_api_id {
>   	PM_CLOCK_GETPARENT = 44,
>   	PM_FPGA_READ = 46,
>   	PM_SECURE_AES = 47,
> +	PM_EFUSE_ACCESS = 53,
>   	PM_FEATURE_CHECK = 63,
>   };
>   
> @@ -562,6 +564,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_efuse_access(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);
> @@ -749,6 +752,11 @@ static inline int zynqmp_pm_aes_engine(const u64 address, u32 *out)
>   	return -ENODEV;
>   }
>   
> +static inline int zynqmp_pm_efuse_access(const u64 address, u32 *out)
> +{
> +	return -ENODEV;
> +}
> +
>   static inline int zynqmp_pm_sha_hash(const u64 address, const u32 size,
>   				     const u32 flags)
>   {

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

Thanks,
Michal


From shawn.gsc at gmail.com  Sun Feb  4 23:18:54 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 15:18:54 +0800
Subject: [PATCH v7 0/2] Add Variscite VAR-SOM-MX93 support
In-Reply-To: <20240108110241.8555-1-othacehe@gnu.org>
References: <20240108110241.8555-1-othacehe@gnu.org>
Message-ID: <ZcCL3vG2JwDkU8Aq@t480>

On Mon, Jan 08, 2024 at 12:02:39PM +0100, Mathieu Othacehe wrote:
> Mathieu Othacehe (2):
>   dt-bindings: arm: fsl: Add VAR-SOM-MX93 with Symphony
>   arm64: dts: imx93-var-som: Add Variscite VAR-SOM-MX93

Applied both, thanks!


From tony at atomide.com  Sun Feb  4 23:21:11 2024
From: tony at atomide.com (Tony Lindgren)
Date: Mon, 5 Feb 2024 09:21:11 +0200
Subject: [PATCH v2 02/15] pinctrl: pinctrl-single: move
 suspend()/resume() callbacks to noirq
In-Reply-To: <6hyubhrho6xbki6yxtmqedylc2gpeyj4yu5gtrjrq4nsthcr7g@elfukmqeve2a>
References: <20240102-j7200-pcie-s2r-v2-0-8e4f7d228ec2@bootlin.com>
 <20240102-j7200-pcie-s2r-v2-2-8e4f7d228ec2@bootlin.com>
 <CACRpkdYBnQ6xh2yNsnvquTOq5r7NeDhot6To9myfuNbonKcgzQ@mail.gmail.com>
 <6hyubhrho6xbki6yxtmqedylc2gpeyj4yu5gtrjrq4nsthcr7g@elfukmqeve2a>
Message-ID: <20240205072111.GD5185@atomide.com>

* Andi Shyti <andi.shyti at kernel.org> [240129 22:49]:
> On Sat, Jan 27, 2024 at 11:31:11PM +0100, Linus Walleij wrote:
> > On Fri, Jan 26, 2024 at 3:37?PM Thomas Richard
> > <thomas.richard at bootlin.com> wrote:
> > 
> > > The goal is to extend the active period of pinctrl.
> > > Some devices may need active pinctrl after suspend() and/or before
> > > resume().
> > > So move suspend()/resume() to suspend_noirq()/resume_noirq() in order to
> > > have active pinctrl until suspend_noirq() (included), and from
> > > resume_noirq() (included).
> > >
> > > The deprecated API has been removed to use the new one (dev_pm_ops struct).
> > >
> > > Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
> > 
> > Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> > 
> > Do you want to merge this as a series or is this something I
> > should just apply?
> 
> there is still a comment from me pending.

FYI I gave this a brief test and things seem to work fine for me. Sounds
like there will be another revision though so I'll test again then.

Regards,

Tony



From shawn.gsc at gmail.com  Sun Feb  4 23:24:42 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 15:24:42 +0800
Subject: [PATCH v1] arm64: dts: imx8mp-verdin: Label ldo5 and link to
 usdhc2
In-Reply-To: <20240109121627.223017-1-dev@pschenker.ch>
References: <20240109121627.223017-1-dev@pschenker.ch>
Message-ID: <ZcCNOjbPrDKaKiYv@t480>

On Tue, Jan 09, 2024 at 01:16:27PM +0100, Philippe Schenker wrote:
> From: Philippe Schenker <philippe.schenker at impulsing.ch>
> 
> This commit labels LDO5 as `reg_vdd_sdio` in `imx8mp-verdin.dtsi` to
> facilitate changing its voltage to 1.8V, necessary for an SDIO
> peripheral that requires 1.8V at default and high-speed modes.
> 
> Additionally, it links `reg_vdd_sdio` to `&usdhc2`, aligning with the
> hardware configuration specified in the datasheet.
> 
> Signed-off-by: Philippe Schenker <philippe.schenker at impulsing.ch>

Applied, thanks!


From shawn.gsc at gmail.com  Sun Feb  4 23:25:42 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 15:25:42 +0800
Subject: [PATCH 1/1] ARM: dts: imx6ul: Add missing #thermal-sensor-cells
 to tempmon
In-Reply-To: <20240110081059.414156-1-alexander.stein@ew.tq-group.com>
References: <20240110081059.414156-1-alexander.stein@ew.tq-group.com>
Message-ID: <ZcCNdrQPb10i4rl2@t480>

On Wed, Jan 10, 2024 at 09:10:59AM +0100, Alexander Stein wrote:
> Fixes the dtbs_check warning:
>   tempmon: '#thermal-sensor-cells' is a required property
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied, thanks!


From alexander.stein at ew.tq-group.com  Sun Feb  4 23:26:12 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Mon, 05 Feb 2024 08:26:12 +0100
Subject: [PATCH V8 05/12] arm64: dts: imx8mp: add HDMI power-domains
In-Reply-To: <20240203165307.7806-6-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com> <20240203165307.7806-6-aford173@gmail.com>
Message-ID: <1880028.tdWV9SEqCh@steina-w>

Hi Adam,

thanks for working on this.

Am Samstag, 3. Februar 2024, 17:52:45 CET schrieb Adam Ford:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the PGC and HDMI blk-ctrl nodes providing power control for
> HDMI subsystem peripherals.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
> V2:  Add missing power-domains hdcp and hrv
> ---
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 38 +++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index
> 76c73daf546b..5c54073de615 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -836,6 +836,23 @@ pgc_mediamix: power-domain at 10 {
>  							 <&clk 
IMX8MP_CLK_MEDIA_APB_ROOT>;
>  					};
> 
> +					pgc_hdmimix: power-
domains at 14 {

As per Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml the node 
should be called power-domain at .

> +						#power-domain-
cells = <0>;
> +						reg = 
<IMX8MP_POWER_DOMAIN_HDMIMIX>;
> +						clocks = <&clk 
IMX8MP_CLK_HDMI_ROOT>,
> +							 <&clk 
IMX8MP_CLK_HDMI_APB>;
> +						assigned-clocks = 
<&clk IMX8MP_CLK_HDMI_AXI>,
> +								
  <&clk IMX8MP_CLK_HDMI_APB>;
> +						assigned-clock-
parents = <&clk IMX8MP_SYS_PLL2_500M>,
> +								
	 <&clk IMX8MP_SYS_PLL1_133M>;
> +						assigned-clock-
rates = <500000000>, <133000000>;
> +					};
> +
> +					pgc_hdmi_phy: power-
domains at 15 {

As per Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml the node 
should be called power-domain at .

> +						#power-domain-
cells = <0>;
> +						reg = 
<IMX8MP_POWER_DOMAIN_HDMI_PHY>;
> +					};
> +
>  					pgc_mipi_phy2: power-
domain at 16 {
>  						#power-domain-
cells = <0>;
>  						reg = 
<IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
> @@ -1361,6 +1378,27 @@ eqos: ethernet at 30bf0000 {
>  				intf_mode = <&gpr 0x4>;
>  				status = "disabled";
>  			};
> +
> +			hdmi_blk_ctrl: blk-ctrl at 32fc0000 {
> +				compatible = "fsl,imx8mp-hdmi-blk-
ctrl", "syscon";
> +				reg = <0x32fc0000 0x23c>;
> +				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
> +					 <&clk 
IMX8MP_CLK_HDMI_ROOT>,
> +					 <&clk 
IMX8MP_CLK_HDMI_REF_266M>,
> +					 <&clk IMX8MP_CLK_HDMI_24M>,
> +					 <&clk 
IMX8MP_CLK_HDMI_FDCC_TST>;
> +				clock-names = "apb", "axi", 
"ref_266m", "ref_24m", "fdcc";
> +				power-domains = <&pgc_hdmimix>, 
<&pgc_hdmimix>,
> +						<&pgc_hdmimix>, 
<&pgc_hdmimix>,
> +						<&pgc_hdmimix>, 
<&pgc_hdmimix>,
> +						<&pgc_hdmimix>, 
<&pgc_hdmi_phy>,
> +						<&pgc_hdmimix>, 
<&pgc_hdmimix>;
> +				power-domain-names = "bus", 
"irqsteer", "lcdif",
> +						     "pai", "pvi", 
"trng",
> +						     "hdmi-tx", 
"hdmi-tx-phy",
> +						     "hdcp", 
"hrv";
> +				#power-domain-cells = <1>;
> +			};
>  		};
> 

According to RM this block is part of AIPS4, so it should be below 
hsio_blk_ctrl.

Best regards,
Alexander

>  		aips5: bus at 30c00000 {


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From laurent.pinchart at ideasonboard.com  Sun Feb  4 23:29:08 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 5 Feb 2024 09:29:08 +0200
Subject: [PATCH v3 0/5] Fixing live video input in ZynqMP DPSUB
In-Reply-To: <20240124025402.373620-1-anatoliy.klymenko@amd.com>
References: <20240124025402.373620-1-anatoliy.klymenko@amd.com>
Message-ID: <20240205072908.GE6804@pendragon.ideasonboard.com>

Hello,

This series looks good. Tomi, could you get it merged through drm-misc ?

On Tue, Jan 23, 2024 at 06:53:57PM -0800, Anatoliy Klymenko wrote:
> Add few missing pieces to support ZynqMP DPSUB live video in mode.
> 
> ZynqMP DPSUB supports 2 modes of operations in regard to video data
> input.
>     
> In the first mode, DPSUB uses DMA engine to pull video data from memory
> buffers. To support this the driver implements CRTC and DRM bridge
> representing DP encoder.
>     
> In the second mode, DPSUB acquires video data pushed from FPGA and 
> passes it downstream to DP output. This mode of operation is modeled in
> the driver as a DRM bridge that should be attached to some external
> CRTC.
> 
> Patches 1/5,2/5,3/5,4/5 are minor fixes.
> 
> DPSUB requires input live video format to be configured.
> Patch 5/5: The DP Subsystem requires the input live video format to be
> configured. In this patch, we are assuming that the CRTC's bus format is
> fixed (typical for FPGA CRTC) and comes from the device tree. This is a
> proposed solution, as there is no API to query CRTC output bus format
> or negotiate it in any other way.
> 
> Changes in v2: 
> - Address reviewers' comments:
>   - More elaborate and consistent comments / commit messages
>   - Fix includes' order
>   - Replace of_property_read_u32_index() with of_property_read_u32()
> 
> Changes in v3:
> - Split patch #3 into 3) moving status register clear immediately after
>   read; 4) masking status against interrupts' mask
> 
> Link to v1: https://lore.kernel.org/all/20240112234222.913138-1-anatoliy.klymenko at amd.com/
> Link to v2: https://lore.kernel.org/all/20240119055437.2549149-1-anatoliy.klymenko at amd.com/
> 
> Anatoliy Klymenko (5):
>   drm: xlnx: zynqmp_dpsub: Make drm bridge discoverable
>   drm: xlnx: zynqmp_dpsub: Fix timing for live mode
>   drm: xlnx: zynqmp_dpsub: Clear status register ASAP
>   drm: xlnx: zynqmp_dpsub: Filter interrupts against mask
>   drm: xlnx: zynqmp_dpsub: Set live video in format
> 
>  drivers/gpu/drm/xlnx/zynqmp_disp.c      | 111 +++++++++++++++++++++---
>  drivers/gpu/drm/xlnx/zynqmp_disp.h      |   3 +-
>  drivers/gpu/drm/xlnx/zynqmp_disp_regs.h |   8 +-
>  drivers/gpu/drm/xlnx/zynqmp_dp.c        |  16 +++-
>  drivers/gpu/drm/xlnx/zynqmp_kms.c       |   2 +-
>  5 files changed, 119 insertions(+), 21 deletions(-)

-- 
Regards,

Laurent Pinchart


From alexander.stein at ew.tq-group.com  Sun Feb  4 23:29:50 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Mon, 05 Feb 2024 08:29:50 +0100
Subject: [PATCH V8 11/12] arm64: dts: imx8mp: add HDMI display pipeline
In-Reply-To: <20240203165307.7806-12-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com> <20240203165307.7806-12-aford173@gmail.com>
Message-ID: <2924284.e9J7NaK4W3@steina-w>

Hi Adam,

thanks for working on this.

Am Samstag, 3. Februar 2024, 17:52:51 CET schrieb Adam Ford:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the DT nodes for all the peripherals that make up the
> HDMI display pipeline.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 
> ---
> V2:  I took this from Lucas' original submission with the following:
>      Removed extra clock from HDMI-TX since it is now part of the
>      power domain
>      Added interrupt-parent to PVI
>      Changed the name of the HDMI tranmitter to fsl,imx8mp-hdmi-tx
>      Added ports to HDMI-tx
> ---
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 94 +++++++++++++++++++++++
>  1 file changed, 94 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index
> 5e51a766f3d9..e84b4f40e570 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -1412,6 +1412,100 @@ irqsteer_hdmi: interrupt-controller at 32fc2000 {
>  				clock-names = "ipg";
>  				power-domains = <&hdmi_blk_ctrl 
IMX8MP_HDMIBLK_PD_IRQSTEER>;
>  			};
> +
> +			hdmi_pvi: display-bridge at 32fc4000 {
> +				compatible = "fsl,imx8mp-hdmi-pvi";
> +				reg = <0x32fc4000 0x40>;
> +				interrupt-parent = <&irqsteer_hdmi>;
> +				interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;

irqsteer_hdmi has #interrupt-cells = <1>, so IRQ flags should be removed. 
dtbs_check also warns about this.

> +				power-domains = <&hdmi_blk_ctrl 
IMX8MP_HDMIBLK_PD_PVI>;
> +
> +				ports {
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +
> +					port at 0 {
> +						reg = <0>;
> +						pvi_from_lcdif3: 
endpoint {
> +							remote-
endpoint = <&lcdif3_to_pvi>;
> +						};
> +					};
> +
> +					port at 1 {
> +						reg = <1>;
> +						pvi_to_hdmi_tx: 
endpoint {
> +							remote-
endpoint = <&hdmi_tx_from_pvi>;
> +						};
> +					};
> +				};
> +			};
> +
> +			lcdif3: display-controller at 32fc6000 {
> +				compatible = "fsl,imx8mp-lcdif";
> +				reg = <0x32fc6000 0x238>;
> +				interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;

irqsteer_hdmi has #interrupt-cells = <1>, so IRQ flags should be removed. 
dtbs_check also warns about this.

> +				interrupt-parent = <&irqsteer_hdmi>;
> +				clocks = <&hdmi_tx_phy>,
> +					 <&clk IMX8MP_CLK_HDMI_APB>,
> +					 <&clk 
IMX8MP_CLK_HDMI_ROOT>;
> +				clock-names = "pix", "axi", 
"disp_axi";
> +				power-domains = <&hdmi_blk_ctrl 
IMX8MP_HDMIBLK_PD_LCDIF>;
> +
> +				port {
> +					lcdif3_to_pvi: endpoint {
> +						remote-endpoint = 
<&pvi_from_lcdif3>;
> +					};
> +				};
> +			};
> +
> +			hdmi_tx: hdmi at 32fd8000 {
> +				compatible = "fsl,imx8mp-hdmi-tx";
> +				reg = <0x32fd8000 0x7eff>;
> +				interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;

irqsteer_hdmi has #interrupt-cells = <1>, so IRQ flags should be removed. 
dtbs_check also warns about this.

> +				interrupt-parent = <&irqsteer_hdmi>;
> +				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
> +					 <&clk 
IMX8MP_CLK_HDMI_REF_266M>,
> +					 <&clk IMX8MP_CLK_32K>,
> +					 <&hdmi_tx_phy>;
> +				clock-names = "iahb", "isfr", "cec", 
"pix";
> +				assigned-clocks = <&clk 
IMX8MP_CLK_HDMI_REF_266M>;
> +				assigned-clock-parents = <&clk 
IMX8MP_SYS_PLL1_266M>;
> +				power-domains = <&hdmi_blk_ctrl 
IMX8MP_HDMIBLK_PD_HDMI_TX>;
> +				reg-io-width = <1>;
> +				status = "disabled";
> +
> +				ports {
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +
> +					port at 0 {
> +						reg = <0>;
> +
> +						hdmi_tx_from_pvi: 
endpoint {
> +							remote-
endpoint = <&pvi_to_hdmi_tx>;
> +						};
> +					};
> +
> +					port at 1 {
> +						reg = <1>;
> +						/* Point endpoint 
to the HDMI connector */
> +					};
> +				};
> +			};
> +
> +			hdmi_tx_phy: phy at 32fdff00 {
> +				compatible = "fsl,imx8mp-hdmi-phy";
> +				reg = <0x32fdff00 0x100>;
> +				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
> +					 <&clk IMX8MP_CLK_HDMI_24M>;
> +				clock-names = "apb", "ref";
> +				assigned-clocks = <&clk 
IMX8MP_CLK_HDMI_24M>;
> +				assigned-clock-parents = <&clk 
IMX8MP_CLK_24M>;
> +				power-domains = <&hdmi_blk_ctrl 
IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>;
> +				#clock-cells = <0>;
> +				#phy-cells = <0>;
> +				status = "disabled";
> +			};

According to RM these blocks are part of AIPS4, so it should be below 
hsio_blk_ctrl.

Best regards,
Alexander

>  		};
> 
>  		aips5: bus at 30c00000 {


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From laurent.pinchart at ideasonboard.com  Sun Feb  4 23:33:57 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 5 Feb 2024 09:33:57 +0200
Subject: [PATCH v3 3/5] drm: xlnx: zynqmp_dpsub: Clear status register
 ASAP
In-Reply-To: <20240124025402.373620-4-anatoliy.klymenko@amd.com>
References: <20240124025402.373620-1-anatoliy.klymenko@amd.com>
 <20240124025402.373620-4-anatoliy.klymenko@amd.com>
Message-ID: <20240205073357.GF6804@pendragon.ideasonboard.com>

Hi Anatoliy,

Thank you for the patch.

On Tue, Jan 23, 2024 at 06:54:00PM -0800, Anatoliy Klymenko wrote:
> Clear status register as soon as we read it.
> 
> Addressing comments from
> https://lore.kernel.org/dri-devel/beb551c7-bb7e-4cd0-b166-e9aad90c4620 at ideasonboard.com/
> 
> Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko at amd.com>
> ---
>  drivers/gpu/drm/xlnx/zynqmp_dp.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index d60b7431603f..5a3335e1fffa 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -1624,6 +1624,8 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data)
>  	u32 status, mask;
>  
>  	status = zynqmp_dp_read(dp, ZYNQMP_DP_INT_STATUS);
> +	/* clear status register as soon as we read it */

I don't think a comment is strictly required, but I don't mind it.

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> +	zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status);
>  	mask = zynqmp_dp_read(dp, ZYNQMP_DP_INT_MASK);
>  	if (!(status & ~mask))
>  		return IRQ_NONE;
> @@ -1634,8 +1636,6 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data)
>  	if (status & ZYNQMP_DP_INT_CHBUF_OVERFLW_MASK)
>  		dev_dbg_ratelimited(dp->dev, "overflow interrupt\n");
>  
> -	zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status);
> -
>  	if (status & ZYNQMP_DP_INT_VBLANK_START)
>  		zynqmp_dpsub_drm_handle_vblank(dp->dpsub);
>  

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Sun Feb  4 23:35:22 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 5 Feb 2024 09:35:22 +0200
Subject: [PATCH v3 4/5] drm: xlnx: zynqmp_dpsub: Filter interrupts
 against mask
In-Reply-To: <20240124025402.373620-5-anatoliy.klymenko@amd.com>
References: <20240124025402.373620-1-anatoliy.klymenko@amd.com>
 <20240124025402.373620-5-anatoliy.klymenko@amd.com>
Message-ID: <20240205073522.GG6804@pendragon.ideasonboard.com>

Hi Anatoliy,

Thank you for the patch.

On Tue, Jan 23, 2024 at 06:54:01PM -0800, Anatoliy Klymenko wrote:
> Filter out status register against the interrupts' mask.
> 
> Some events are being reported via DP status register, even if
> corresponding interrupts have been disabled. One instance of such event
> leads to generation of VBLANK when the driver is in DRM bridge mode,
> which in turn results in NULL pointer dereferencing. We should avoid
> processing such events in an interrupt handler context.
> 
> This problem is less noticeable when the driver operates in DMA mode, as
> in this case we have DRM CRTC object instantiated and DRM framework
> simply discards unwanted VBLANKs in drm_handle_vblank().
> 
> Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko at amd.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
>  drivers/gpu/drm/xlnx/zynqmp_dp.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index 5a3335e1fffa..9f48e5bbcdec 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -1627,7 +1627,14 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data)
>  	/* clear status register as soon as we read it */
>  	zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status);
>  	mask = zynqmp_dp_read(dp, ZYNQMP_DP_INT_MASK);
> -	if (!(status & ~mask))
> +
> +	/*
> +	 * Status register may report some events, which corresponding interrupts
> +	 * have been disabled. Filter out those events against interrupts' mask.
> +	 */
> +	status &= ~mask;
> +
> +	if (!status)
>  		return IRQ_NONE;
>  
>  	/* dbg for diagnostic, but not much that the driver can do */

-- 
Regards,

Laurent Pinchart


From krzysztof.kozlowski at linaro.org  Sun Feb  4 23:35:22 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 08:35:22 +0100
Subject: [PATCH] arm: s3c64xx: make s3c64xx_subsys const
In-Reply-To: <20240204-bus_cleanup-arm-v1-1-41d651dd8411@marliere.net>
References: <20240204-bus_cleanup-arm-v1-1-41d651dd8411@marliere.net>
Message-ID: <792c737f-cefb-4d1b-93f8-c1d2dd2573f6@linaro.org>

On 04/02/2024 15:46, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,

Is there any dependency?

> move the s3c64xx_subsys variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb  4 23:40:24 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 08:40:24 +0100
Subject: [PATCH 1/2] serial: samsung: honor fifosize from dts at first
In-Reply-To: <20240202212448.74840-1-m.shams@samsung.com>
References: <CGME20240202212456epcas5p15589813cd79526e9d0c444082e2f0e51@epcas5p1.samsung.com>
 <20240202212448.74840-1-m.shams@samsung.com>
Message-ID: <bd253c6d-999c-4ba6-a80d-c7e077d1261a@linaro.org>

On 02/02/2024 22:24, Tamseel Shams wrote:
> Currently for platforms which passes UART fifosize from DT gets
> override by local driver structure "s3c24xx_serial_drv_data",
> which is not indentded. Change the code to honor fifosize from
> device tree at first.
> 
> Signed-off-by: Tamseel Shams <m.shams at samsung.com>
> ---
>  drivers/tty/serial/samsung_tty.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
> index 71d17d804fda..e4c4c9f4f9b0 100644
> --- a/drivers/tty/serial/samsung_tty.c
> +++ b/drivers/tty/serial/samsung_tty.c
> @@ -1990,8 +1990,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
>  	}
>  
>  	if (np) {
> -		of_property_read_u32(np,
> -			"samsung,uart-fifosize", &ourport->port.fifosize);
> +		ret = of_property_read_u32(np, "samsung,uart-fifosize", &ourport->port.fifosize);
>  
>  		if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
>  			switch (prop) {
> @@ -2009,10 +2008,13 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (ourport->drv_data->fifosize[index])
> -		ourport->port.fifosize = ourport->drv_data->fifosize[index];
> -	else if (ourport->info->fifosize)
> -		ourport->port.fifosize = ourport->info->fifosize;

I think ret is not initialized here.



Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb  4 23:41:22 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 08:41:22 +0100
Subject: [PATCH 2/2] arm64: dts: fsd: Add fifosize for UART in Device Tree
In-Reply-To: <20240202212448.74840-2-m.shams@samsung.com>
References: <20240202212448.74840-1-m.shams@samsung.com>
 <CGME20240202212459epcas5p2e1703c35ebe9302ac5b2f3d3fcd853c0@epcas5p2.samsung.com>
 <20240202212448.74840-2-m.shams@samsung.com>
Message-ID: <6980c4d5-78a2-4c14-b21e-a5ed1e4d5675@linaro.org>

On 02/02/2024 22:24, Tamseel Shams wrote:
> UART in FSD SoC has fifosize of 64 bytes.
> Set fifosize as 64 bytes for UART from Device Tree.
> 
> Signed-off-by: Tamseel Shams <m.shams at samsung.com>
> ---
>  arch/arm64/boot/dts/tesla/fsd.dtsi | 2 ++

Please split SoC changes from patches sent to serial, so it will be easy
to apply for Greg and others.

Unless you want to say that there is dependency, but there cannot be
such - it would be a NAK.

Best regards,
Krzysztof



From ming.qian at nxp.com  Sun Feb  4 23:25:56 2024
From: ming.qian at nxp.com (Ming Qian)
Date: Mon,  5 Feb 2024 16:25:56 +0900
Subject: [PATCH] media: imx-jpeg: Support for negotiating bytesperline with client
Message-ID: <20240205072556.804809-1-ming.qian@nxp.com>

This mxc-jpeg driver doesn't allow the client to set the bytesperline,
but for some android cts case, it need to negotiate the bytesperline
between decoder and display, and fail the case if driver doesn't support
negotiating bytesperline

The jpegdec and jpegenc does support to set bytesperline which is
multiple of 2, and greater than the value calulated by driver.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
---
 drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 16 ++++++++++++++++
 drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h |  1 +
 2 files changed, 17 insertions(+)

diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
index 64112b63298c..cc97790ed30f 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
@@ -1373,6 +1373,8 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
 		q_data_cap->crop.top = 0;
 		q_data_cap->crop.width = jpeg_src_buf->w;
 		q_data_cap->crop.height = jpeg_src_buf->h;
+		q_data_cap->bytesperline[0] = 0;
+		q_data_cap->bytesperline[1] = 0;
 
 		/*
 		 * align up the resolution for CAST IP,
@@ -1752,6 +1754,14 @@ static u32 mxc_jpeg_get_image_format(struct device *dev,
 
 static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision)
 {
+	u32 bytesperline[2];
+
+	bytesperline[0] = q->bytesperline[0];
+	bytesperline[1] = q->bytesperline[0];	/*imx-jpeg only support the same line pitch*/
+	v4l_bound_align_image(&bytesperline[0], 0, MXC_JPEG_MAX_LINE, 2,
+			      &bytesperline[1], 0, MXC_JPEG_MAX_LINE, 2,
+			      0);
+
 	/* Bytes distance between the leftmost pixels in two adjacent lines */
 	if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
 		/* bytesperline unused for compressed formats */
@@ -1775,6 +1785,12 @@ static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision)
 		q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8);
 		q->bytesperline[1] = 0;
 	}
+
+	if (q->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
+		q->bytesperline[0] = max(q->bytesperline[0], bytesperline[0]);
+		if (q->fmt->mem_planes > 1)
+			q->bytesperline[1] = max(q->bytesperline[1], bytesperline[1]);
+	}
 }
 
 static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
index dc4afeeff5b6..86e324b21aed 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
@@ -22,6 +22,7 @@
 #define MXC_JPEG_MIN_HEIGHT		64
 #define MXC_JPEG_MAX_WIDTH		0x2000
 #define MXC_JPEG_MAX_HEIGHT		0x2000
+#define MXC_JPEG_MAX_LINE		0x8000
 #define MXC_JPEG_MAX_CFG_STREAM		0x1000
 #define MXC_JPEG_H_ALIGN		3
 #define MXC_JPEG_W_ALIGN		3
-- 
2.43.0-rc1



From krzysztof.kozlowski at linaro.org  Sun Feb  4 23:50:36 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 08:50:36 +0100
Subject: [EXT] Re: [PATCH v5 4/8] dt-bindings: usb: ci-hdrc-usb2: add
 restrictions for reg, interrupts, clock and clock-names properties
In-Reply-To: <DU2PR04MB88221841F66A22B5A5DE47258C402@DU2PR04MB8822.eurprd04.prod.outlook.com>
References: <20240131114324.3722428-1-xu.yang_2@nxp.com>
 <20240131114324.3722428-4-xu.yang_2@nxp.com>
 <a0134089-a283-488b-8d7f-3f59dd938b60@linaro.org>
 <DU2PR04MB88221602EB986D2C2A5BBF8D8C422@DU2PR04MB8822.eurprd04.prod.outlook.com>
 <bcd733ab-ea9e-4ef0-a521-8e6c2023479f@linaro.org>
 <DU2PR04MB88221841F66A22B5A5DE47258C402@DU2PR04MB8822.eurprd04.prod.outlook.com>
Message-ID: <454616d4-19f6-408c-ba12-fa48cc04bce6@linaro.org>

On 04/02/2024 07:56, Xu Yang wrote:
> 
>>
>> On 02/02/2024 10:10, Xu Yang wrote:
>>> Hi Krzysztof,
>>>
>>>>
>>>> On 31/01/2024 12:43, Xu Yang wrote:
>>>>> Change reg, interrupts, clock and clock-names as common properties and add
>>>>> restrictions on them for different compatibles.
>>>>>
>>>>> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
>>>>>
>>>>> ---
>>>>> Changes in v4:
>>>>>  - new patch since v3's discussion
>>>>>  - split the reg, interrupts, clock and clock-names properties into
>>>>>    common part and device-specific
>>>>> Changes in v5:
>>>>>  - keep common property unchanged
>>>>>  - make if-then more readable
>>>>>  - remove non imx part
>>>>> ---
>>>>>  .../devicetree/bindings/usb/ci-hdrc-usb2.yaml | 118 ++++++++++++++++++
>>>>>  1 file changed, 118 insertions(+)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-
>>>> hdrc-usb2.yaml
>>>>> index 3b56e0edb1c6..6ad3582051b8 100644
>>>>> --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
>>>>> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
>>>>> @@ -412,6 +412,124 @@ allOf:
>>>>>          samsung,picophy-pre-emp-curr-control: false
>>>>>          samsung,picophy-dc-vol-level-adjust: false
>>>>>
>>>>> +  - if:
>>>>> +      properties:
>>>>> +        compatible:
>>>>> +          const: fsl,imx27-usb
>>>>> +    then:
>>>>> +      properties:
>>>>> +        clocks:
>>>>> +          minItems: 3
>>>>> +          maxItems: 3
>>>>> +        clock-names:
>>>>> +          minItems: 3
>>>>> +          maxItems: 3
>>>>> +          items:
>>>>> +            anyOf:
>>>>> +              - const: ipg
>>>>> +              - const: ahb
>>>>> +              - const: per
>>>>
>>>> This would be just: enum: [ipg, ahb, per], but in both cases I question
>>>> why the order should be flexible? Nothing in commit msg explains it.
>>>
>>> The driver will get the clock by clock-name, then the order should not
>>> matter. However, these three clock-names should be present at the same
>>> time. I should use enum then.
>>
>> Forgot to answer to this.
>>
>> Which driver? U-boot? OpenBSD? The one in my custom Linux kernel fork
>> (open-source and published on github)? Did you check all of them?
> 
> I mean below driver in linux kernel tree.
> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/tree/drivers/usb/chipidea/ci_hdrc_imx.c?h=linux-6.1.y#n191

What about others? How about driver in other upstream projects? My
comment should make you think...

Best regards,
Krzysztof



From mihai.sain at microchip.com  Mon Feb  5 00:00:18 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Mon, 5 Feb 2024 10:00:18 +0200
Subject: [PATCH v2 0/8] Add power-supply properties for sdmmc nodes on Microchip boards
Message-ID: <20240205080027.4565-1-mihai.sain@microchip.com>

This patch series adds power-supply properties for sdmmc nodes on Microchip boards.

Changes in v2:
--------------

* Update the commit description for each board.
* The goal is to keep the vqmmc at 3V3 in order to use the sd high-speed mode.

Mihai Sain (8):
  ARM: dts: microchip: sam9x60_curiosity: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sam9x60ek: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sama5d27_som1_ek: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sama5d27_wlsom1: Add power-supply property for sdmmc1 node
  ARM: dts: microchip: sama5d27_wlsom1_ek: Add power-supply property for sdmmc0 node
  ARM: dts: microchip: sama5d29_curiosity: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sama5d2_icp: Add power-supply property for sdmmc0 node
  ARM: dts: microchip: sama5d2_xplained: Add power-supply property for sdmmc0 node

 arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts  | 4 ++++
 arch/arm/boot/dts/microchip/at91-sam9x60ek.dts          | 4 ++++
 arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts   | 4 ++++
 arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi   | 2 ++
 arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts | 2 ++
 arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts | 4 ++++
 arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts        | 2 ++
 arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts   | 2 ++
 8 files changed, 24 insertions(+)

-- 
2.43.0



From mihai.sain at microchip.com  Mon Feb  5 00:00:19 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Mon, 5 Feb 2024 10:00:19 +0200
Subject: [PATCH v2 1/8] ARM: dts: microchip: sam9x60_curiosity: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240205080027.4565-1-mihai.sain@microchip.com>
References: <20240205080027.4565-1-mihai.sain@microchip.com>
Message-ID: <20240205080027.4565-2-mihai.sain@microchip.com>

The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
The sdmmc controller from SAM9X60 MPU doesn't support the IO voltage signaling/switching required by the UHS sd-card.
In order to use the sd high-speed mode, keep vqmmc at 3V3.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
index c6fbdd29019f..457c54dde0b7 100644
--- a/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
+++ b/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
@@ -452,6 +452,8 @@ &sdmmc0 {
 	pinctrl-0 = <&pinctrl_sdmmc0_default &pinctrl_sdmmc0_cd>;
 	cd-gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
 	disable-wp;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 	status = "okay";
 };
 
@@ -460,6 +462,8 @@ &sdmmc1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc1_default>;
 	disable-wp;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 	status = "okay";
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Mon Feb  5 00:00:20 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Mon, 5 Feb 2024 10:00:20 +0200
Subject: [PATCH v2 2/8] ARM: dts: microchip: sam9x60ek: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240205080027.4565-1-mihai.sain@microchip.com>
References: <20240205080027.4565-1-mihai.sain@microchip.com>
Message-ID: <20240205080027.4565-3-mihai.sain@microchip.com>

The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
The sdmmc controller from SAM9X60 MPU doesn't support the IO voltage signaling/switching required by the UHS sd-card.
In order to use the sd high-speed mode, keep vqmmc at 3V3.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sam9x60ek.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts b/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
index f3cbb675cea4..b19a0956dc97 100644
--- a/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
+++ b/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
@@ -560,6 +560,8 @@ &sdmmc0 {
 	status = "okay";
 	cd-gpios = <&pioA 23 GPIO_ACTIVE_LOW>;
 	disable-wp;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 };
 
 &sdmmc1 {
@@ -568,6 +570,8 @@ &sdmmc1 {
 	pinctrl-0 = <&pinctrl_sdmmc1_default>;
 	no-1-8-v;
 	non-removable;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 	status = "disabled"; /* Conflict with flx4. */
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Mon Feb  5 00:00:21 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Mon, 5 Feb 2024 10:00:21 +0200
Subject: [PATCH v2 3/8] ARM: dts: microchip: sama5d27_som1_ek: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240205080027.4565-1-mihai.sain@microchip.com>
References: <20240205080027.4565-1-mihai.sain@microchip.com>
Message-ID: <20240205080027.4565-4-mihai.sain@microchip.com>

The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
The sdmmc controller from SAMA5D2 MPU has support for IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by the UHS cards,
keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts b/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
index f3ffb8f01d8a..255ee0640133 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
@@ -56,6 +56,8 @@ sdmmc0: sdio-host at a0000000 {
 			bus-width = <8>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_sdmmc0_default>;
+			vmmc-supply = <&vddin_3v3>;
+			vqmmc-supply = <&vddin_3v3>;
 			status = "okay";
 		};
 
@@ -63,6 +65,8 @@ sdmmc1: sdio-host at b0000000 {
 			bus-width = <4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_sdmmc1_default>;
+			vmmc-supply = <&vddin_3v3>;
+			vqmmc-supply = <&vddin_3v3>;
 			status = "okay";
 		};
 
-- 
2.43.0



From mihai.sain at microchip.com  Mon Feb  5 00:00:22 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Mon, 5 Feb 2024 10:00:22 +0200
Subject: [PATCH v2 4/8] ARM: dts: microchip: sama5d27_wlsom1: Add power-supply property for sdmmc1 node
In-Reply-To: <20240205080027.4565-1-mihai.sain@microchip.com>
References: <20240205080027.4565-1-mihai.sain@microchip.com>
Message-ID: <20240205080027.4565-5-mihai.sain@microchip.com>

The sdmmc1 controller is powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc1 node.
The sdmmc controller from SAMA5D2 MPU has support for IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by the UHS cards,
keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi
index 4617805c7748..96819ea24cbd 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi
+++ b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi
@@ -368,6 +368,8 @@ &sdmmc1 {
 	no-1-8-v;
 	non-removable;
 	bus-width = <4>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 
 	wilc: wifi at 0 {
-- 
2.43.0



From mihai.sain at microchip.com  Mon Feb  5 00:00:23 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Mon, 5 Feb 2024 10:00:23 +0200
Subject: [PATCH v2 5/8] ARM: dts: microchip: sama5d27_wlsom1_ek: Add power-supply property for sdmmc0 node
In-Reply-To: <20240205080027.4565-1-mihai.sain@microchip.com>
References: <20240205080027.4565-1-mihai.sain@microchip.com>
Message-ID: <20240205080027.4565-6-mihai.sain@microchip.com>

The sdmmc0 controller is powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.
The sdmmc controller from SAMA5D2 MPU has support for IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by the UHS cards,
keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
index 15239834d886..7b36e1970bb7 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
@@ -199,6 +199,8 @@ &sdmmc0 {
 	bus-width = <4>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Mon Feb  5 00:00:24 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Mon, 5 Feb 2024 10:00:24 +0200
Subject: [PATCH v2 6/8] ARM: dts: microchip: sama5d29_curiosity: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240205080027.4565-1-mihai.sain@microchip.com>
References: <20240205080027.4565-1-mihai.sain@microchip.com>
Message-ID: <20240205080027.4565-7-mihai.sain@microchip.com>

The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
The sdmmc controller from SAMA5D2 MPU has support for IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by the UHS cards,
keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
index 6b02b7bcfd49..4a86597d089a 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
@@ -504,6 +504,8 @@ &sdmmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
 	disable-wp;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 };
 
@@ -512,6 +514,8 @@ &sdmmc1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc1_default>;
 	disable-wp;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Mon Feb  5 00:00:26 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Mon, 5 Feb 2024 10:00:26 +0200
Subject: [PATCH v2 8/8] ARM: dts: microchip: sama5d2_xplained: Add power-supply property for sdmmc0 node
In-Reply-To: <20240205080027.4565-1-mihai.sain@microchip.com>
References: <20240205080027.4565-1-mihai.sain@microchip.com>
Message-ID: <20240205080027.4565-9-mihai.sain@microchip.com>

The sdmmc0 controller is powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.
The sdmmc controller from SAMA5D2 MPU has support for IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by the UHS cards,
keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
index 6680031387e8..9b7e56790a5a 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
@@ -67,6 +67,8 @@ sdmmc0: sdio-host at a0000000 {
 			pinctrl-0 = <&pinctrl_sdmmc0_default>;
 			non-removable;
 			mmc-ddr-3_3v;
+			vmmc-supply = <&vdd_3v3_reg>;
+			vqmmc-supply = <&vdd_3v3_reg>;
 			status = "okay";
 		};
 
-- 
2.43.0



From mihai.sain at microchip.com  Mon Feb  5 00:00:25 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Mon, 5 Feb 2024 10:00:25 +0200
Subject: [PATCH v2 7/8] ARM: dts: microchip: sama5d2_icp: Add power-supply property for sdmmc0 node
In-Reply-To: <20240205080027.4565-1-mihai.sain@microchip.com>
References: <20240205080027.4565-1-mihai.sain@microchip.com>
Message-ID: <20240205080027.4565-8-mihai.sain@microchip.com>

The sdmmc0 controller is powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.
The sdmmc controller from SAMA5D2 MPU has support for IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by the UHS cards,
keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts b/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts
index 999adeca6f33..adcb3240e5f5 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts
@@ -712,6 +712,8 @@ &sdmmc0 {
 	bus-width = <4>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
+	vmmc-supply = <&vdd_io_reg>;	// 3.3V
+	vqmmc-supply = <&vdd_io_reg>;	// 3.3V
 	status = "okay";
 };
 
-- 
2.43.0



From krzysztof.kozlowski at linaro.org  Mon Feb  5 00:08:00 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 09:08:00 +0100
Subject: [PATCH 1/2] dt-bindings: phy: mediatek,xfi-tphy: add new bindings
In-Reply-To: <031944545677573672000aee8f97149e56c15f83.camel@mediatek.com>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
 <adf20671-2f1d-43ea-8584-df0c0b095865@linaro.org>
 <031944545677573672000aee8f97149e56c15f83.camel@mediatek.com>
Message-ID: <d6f787e6-a243-410f-ac6e-c57ea5309838@linaro.org>

On 04/02/2024 07:17, Chunfeng Yun (???) wrote:
> On Fri, 2024-02-02 at 09:21 +0100, Krzysztof Kozlowski wrote:
>>  	 
>> External email : Please do not click links or open attachments until
>> you have verified the sender or the content.
>>  On 01/02/2024 22:52, Daniel Golle wrote:
>>> Add bindings for the MediaTek XFI T-PHY Ethernet SerDes PHY found
>> in the
>>> MediaTek MT7988 SoC which can operate at various interfaces modes:
>>>
>>> via USXGMII PCS:
>>>  * USXGMII
>>>  * 10GBase-R
>>>  * 5GBase-R
>>>
>>> via LynxI SGMII PCS:
>>>  * 2500Base-X
>>>  * 1000Base-X
>>>  * Cisco SGMII (MAC side)
>>>
>>> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
>>> ---
>>>  .../bindings/phy/mediatek,xfi-tphy.yaml       | 80
>> +++++++++++++++++++
>>>  1 file changed, 80 insertions(+)
>>>  create mode 100644
>> Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-
>> tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-
>> tphy.yaml
>>> new file mode 100644
>>> index 0000000000000..e897118dcf7e6
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml
>>> @@ -0,0 +1,80 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/phy/mediatek,xfi-tphy.yaml#
>>
>> Please use compatible as filename. Your binding says only one is
>> possible (const, not enum), so there is no reasoning for different
>> filename.
>>
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: MediaTek XFI T-PHY
>>> +
>>> +maintainers:
>>> +  - Daniel Golle <daniel at makrotopia.org>
>>> +
>>> +description:
>>> +  The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes
>>> +  used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found
>> in
>>> +  MediaTek's 10G-capabale SoCs.
>>> +
>>> +properties:
>>> +  $nodename:
>>> +    pattern: "^phy@[0-9a-f]+$"
>>
>> No need for nodename in individual bindings file.
>>
>>> +
>>> +  compatible:
>>> +    const: mediatek,mt7988-xfi-tphy
> Add a generic compatible "mediatek,xfi-tphy"?
> 
> Other socs also use this phy but not upstream.

Are they here? No... They will use this one as fallback. Stop insisting
on some generic fallbacks just because you do not like using other SoCs
as fallbacks.

You ignored other comments, so I understand you agree with them 100%.

Best regards,
Krzysztof



From laurent.pinchart at ideasonboard.com  Mon Feb  5 00:08:24 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 5 Feb 2024 10:08:24 +0200
Subject: [PATCH v3 2/5] drm: xlnx: zynqmp_dpsub: Fix timing for live mode
In-Reply-To: <20240124025402.373620-3-anatoliy.klymenko@amd.com>
References: <20240124025402.373620-1-anatoliy.klymenko@amd.com>
 <20240124025402.373620-3-anatoliy.klymenko@amd.com>
Message-ID: <20240205080824.GH6804@pendragon.ideasonboard.com>

Hi Anatoliy,

Thank you for the patch.

On Tue, Jan 23, 2024 at 06:53:59PM -0800, Anatoliy Klymenko wrote:
> Expect external video timing in live video input mode, program
> DPSUB acordingly.

Are there no designs where the DPSUB operates in non-live mode, but uses
a video clock from the PL, for instance to use a different clock
frequency ?

I don't think that use case is very common, so I'm fine with this patch
in order to properly support the more common use case of live input, and
leave the PL clock without live input use case for later.

> 
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> 

No need for a blank line here.

> Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko at amd.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
>  drivers/gpu/drm/xlnx/zynqmp_disp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> index 407bc07cec69..8a39b3accce5 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> @@ -1166,7 +1166,7 @@ void zynqmp_disp_enable(struct zynqmp_disp *disp)
>  	/* Choose clock source based on the DT clock handle. */
>  	zynqmp_disp_avbuf_set_clocks_sources(disp, disp->dpsub->vid_clk_from_ps,
>  					     disp->dpsub->aud_clk_from_ps,
> -					     true);
> +					     disp->dpsub->vid_clk_from_ps);
>  	zynqmp_disp_avbuf_enable_channels(disp);
>  	zynqmp_disp_avbuf_enable_audio(disp);
>  

-- 
Regards,

Laurent Pinchart


From m.felsch at pengutronix.de  Mon Feb  5 00:17:19 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Mon, 5 Feb 2024 09:17:19 +0100
Subject: [PATCH V8 02/12] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <CAA8EJpo4omXogg48urEMzxQ+CA7DNTSf66pA6hoO8wpmtn_-MQ@mail.gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-3-aford173@gmail.com>
 <CAA8EJpo4omXogg48urEMzxQ+CA7DNTSf66pA6hoO8wpmtn_-MQ@mail.gmail.com>
Message-ID: <20240205081719.z2uqa4dwn5ucsymv@pengutronix.de>

On 24-02-04, Dmitry Baryshkov wrote:
> On Sat, 3 Feb 2024 at 17:53, Adam Ford <aford173 at gmail.com> wrote:
> >
> > From: Lucas Stach <l.stach at pengutronix.de>
> >
> > This adds the driver for the Samsung HDMI PHY found on the
> > i.MX8MP SoC.
> >
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
> > Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> > V4:  Make lookup table hex values lower case.
> >
> > V3:  Re-order the Makefile to keep it alphabetical
> >      Remove unused defines
> >
> > V2:  Fixed some whitespace found from checkpatch
> >      Change error handling when enabling apbclk to use dev_err_probe
> >      Rebase on Linux-Next
> >
> >      I (Adam) tried to help move this along, so I took Lucas' patch and
> >      attempted to apply fixes based on feedback.  I don't have
> >      all the history, so apologies for that.
> > ---
> >  drivers/phy/freescale/Kconfig                |    6 +
> >  drivers/phy/freescale/Makefile               |    1 +
> >  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 1075 ++++++++++++++++++
> >  3 files changed, 1082 insertions(+)
> >  create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> >
> > diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> > index 853958fb2c06..5c2b73042dfc 100644
> > --- a/drivers/phy/freescale/Kconfig
> > +++ b/drivers/phy/freescale/Kconfig
> > @@ -35,6 +35,12 @@ config PHY_FSL_IMX8M_PCIE
> >           Enable this to add support for the PCIE PHY as found on
> >           i.MX8M family of SOCs.
> >
> > +config PHY_FSL_SAMSUNG_HDMI_PHY
> > +       tristate "Samsung HDMI PHY support"
> > +       depends on OF && HAS_IOMEM
> > +       help
> > +         Enable this to add support for the Samsung HDMI PHY in i.MX8MP.
> > +
> >  endif
> >
> >  config PHY_FSL_LYNX_28G
> > diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
> > index cedb328bc4d2..79e5f16d3ce8 100644
> > --- a/drivers/phy/freescale/Makefile
> > +++ b/drivers/phy/freescale/Makefile
> > @@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)        += phy-fsl-imx8qm-lvds-phy.o
> >  obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)      += phy-fsl-imx8-mipi-dphy.o
> >  obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)       += phy-fsl-imx8m-pcie.o
> >  obj-$(CONFIG_PHY_FSL_LYNX_28G)         += phy-fsl-lynx-28g.o
> > +obj-$(CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY)  += phy-fsl-samsung-hdmi.o
> > diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > new file mode 100644
> > index 000000000000..bf0e2299d00f
> > --- /dev/null
> > +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > @@ -0,0 +1,1075 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright 2020 NXP
> > + * Copyright 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/io.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pm_runtime.h>
> > +
> > +#define PHY_REG_33             0x84
> > +#define  REG33_MODE_SET_DONE   BIT(7)
> > +#define  REG33_FIX_DA          BIT(1)
> > +
> > +#define PHY_REG_34             0x88
> > +#define  REG34_PHY_READY       BIT(7)
> > +#define  REG34_PLL_LOCK                BIT(6)
> > +#define  REG34_PHY_CLK_READY   BIT(5)
> > +
> > +
> > +#define PHY_PLL_REGS_NUM 48
> > +
> > +struct phy_config {
> > +       u32     clk_rate;
> > +       u8 regs[PHY_PLL_REGS_NUM];
> > +};
> > +
> > +const struct phy_config phy_pll_cfg[] = {
> > +       {       22250000, {
> > +                       0x00, 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40,
> > +                       0x4f, 0x30, 0x33, 0x65, 0x00, 0x15, 0x25, 0x80,
> > +                       0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
> > +                       0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
> > +                       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +                       0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
> > +               },
> > +       }, {
> > +               23750000, {
> > +                       0x00, 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40,
> > +                       0x4f, 0x30, 0x33, 0x65, 0x00, 0x03, 0x25, 0x80,
> > +                       0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
> > +                       0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
> > +                       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +                       0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
> > +               },
> 
> Generally I see that these entries contain a high level of duplication.
> Could you please extract the common part and a rate-dependent part.
> Next, it would be best if instead of writing the register values via
> the rate LUT, the driver could calculate those values.
> This allows us to support other HDMI modes if the need arises at some point.

Hi Adam,

can you please have a look at: https://lore.kernel.org/all/4830698.GXAFRqVoOG at steina-w/

there we have fixed this already. Not sure which version you picked for
your work.

Regards,
  Marco

> 
> > +       }, {
> > +               24000000, {
> > +                       0x00, 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00,
> > +                       0x4f, 0x30, 0x33, 0x65, 0x00, 0x01, 0x25, 0x80,
> > +                       0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
> > +                       0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
> > +                       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +                       0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
> > +               },
> 
> 
> -- 
> With best wishes
> Dmitry
> 
> 


From geert at linux-m68k.org  Mon Feb  5 00:17:31 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 5 Feb 2024 09:17:31 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: r8a779h0: Add I2C nodes
In-Reply-To: <Zb59ceHI7FrUqjhg@shikoro>
References: <cover.1706796660.git.geert+renesas@glider.be> <7dbbe13428273c5786ddff6ea7af6724fcdd4de8.1706796660.git.geert+renesas@glider.be>
 <Zb59ceHI7FrUqjhg@shikoro>
Message-ID: <CAMuHMdVq7T21R=stUSKMiC+XTaM1MSPngrDppzaaU3MXFLo-tw@mail.gmail.com>

Hi Wolfram,

On Sat, Feb 3, 2024 at 6:52?PM Wolfram Sang <wsa at kernel.org> wrote:
> On Thu, Feb 01, 2024 at 03:14:33PM +0100, Geert Uytterhoeven wrote:
> > From: Hai Pham <hai.pham.ud at renesas.com>
> >
> > Add device nodes for the I2C Bus Interfaces on the Renesas R-Car V4M
> > (R8A779H0) SoC.
> >
> > Signed-off-by: Hai Pham <hai.pham.ud at renesas.com>
> > Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
>
> So far so good...
>
> Reviewed-by: Wolfram Sang <wsa+renesas at sang-engineering.com>

Thanks!

> I assume DMA nodes are not there yet because you use these nodes for
> testing DMA when you enable the DMACs?

Indeed, DMAC support is not yet included.

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 ming.qian at nxp.com  Mon Feb  5 00:17:58 2024
From: ming.qian at nxp.com (Ming Qian)
Date: Mon,  5 Feb 2024 17:17:58 +0900
Subject: [PATCH] media: amphion: Abort vpu parsing directly in seek
Message-ID: <20240205081758.923878-1-ming.qian@nxp.com>

Driver abort vpu decoding when both output and capture queues are off,
but if seek in parsing the sequence header, driver may miss aborting the
parsing. so just abort the vpu parsing directly in seek.

Meanwhile if capture is off unexpectedly, we still need to abort the
decoding and return capture buffers.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
---
 drivers/media/platform/amphion/vdec.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
index 133d77d1ea0c..a57f9f4f3b87 100644
--- a/drivers/media/platform/amphion/vdec.c
+++ b/drivers/media/platform/amphion/vdec.c
@@ -1595,9 +1595,11 @@ static int vdec_stop_session(struct vpu_inst *inst, u32 type)
 	if (V4L2_TYPE_IS_OUTPUT(type)) {
 		vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0);
 		vdec->drain = 0;
+		vdec_abort(inst);
 	} else {
 		if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) {
-			vdec_abort(inst);
+			if (vb2_is_streaming(v4l2_m2m_get_src_vq(inst->fh.m2m_ctx)))
+				vdec_abort(inst);
 			vdec->eos_received = 0;
 		}
 		vdec_clear_slots(inst);
-- 
2.43.0-rc1



From laurent.pinchart at ideasonboard.com  Mon Feb  5 00:26:52 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 5 Feb 2024 10:26:52 +0200
Subject: [PATCH v3 0/5] Fixing live video input in ZynqMP DPSUB
In-Reply-To: <20240205072908.GE6804@pendragon.ideasonboard.com>
References: <20240124025402.373620-1-anatoliy.klymenko@amd.com>
 <20240205072908.GE6804@pendragon.ideasonboard.com>
Message-ID: <20240205082652.GI6804@pendragon.ideasonboard.com>

On Mon, Feb 05, 2024 at 09:29:09AM +0200, Laurent Pinchart wrote:
> Hello,
> 
> This series looks good. Tomi, could you get it merged through drm-misc ?

I got things mixed up, sorry. Patches 1/5 to 4/5 are fine, but 5/5 needs
a different approach. I've reviewed the first four patches, which I
think are fine and can be applied already.

> On Tue, Jan 23, 2024 at 06:53:57PM -0800, Anatoliy Klymenko wrote:
> > Add few missing pieces to support ZynqMP DPSUB live video in mode.
> > 
> > ZynqMP DPSUB supports 2 modes of operations in regard to video data
> > input.
> >     
> > In the first mode, DPSUB uses DMA engine to pull video data from memory
> > buffers. To support this the driver implements CRTC and DRM bridge
> > representing DP encoder.
> >     
> > In the second mode, DPSUB acquires video data pushed from FPGA and 
> > passes it downstream to DP output. This mode of operation is modeled in
> > the driver as a DRM bridge that should be attached to some external
> > CRTC.
> > 
> > Patches 1/5,2/5,3/5,4/5 are minor fixes.
> > 
> > DPSUB requires input live video format to be configured.
> > Patch 5/5: The DP Subsystem requires the input live video format to be
> > configured. In this patch, we are assuming that the CRTC's bus format is
> > fixed (typical for FPGA CRTC) and comes from the device tree. This is a
> > proposed solution, as there is no API to query CRTC output bus format
> > or negotiate it in any other way.
> > 
> > Changes in v2: 
> > - Address reviewers' comments:
> >   - More elaborate and consistent comments / commit messages
> >   - Fix includes' order
> >   - Replace of_property_read_u32_index() with of_property_read_u32()
> > 
> > Changes in v3:
> > - Split patch #3 into 3) moving status register clear immediately after
> >   read; 4) masking status against interrupts' mask
> > 
> > Link to v1: https://lore.kernel.org/all/20240112234222.913138-1-anatoliy.klymenko at amd.com/
> > Link to v2: https://lore.kernel.org/all/20240119055437.2549149-1-anatoliy.klymenko at amd.com/
> > 
> > Anatoliy Klymenko (5):
> >   drm: xlnx: zynqmp_dpsub: Make drm bridge discoverable
> >   drm: xlnx: zynqmp_dpsub: Fix timing for live mode
> >   drm: xlnx: zynqmp_dpsub: Clear status register ASAP
> >   drm: xlnx: zynqmp_dpsub: Filter interrupts against mask
> >   drm: xlnx: zynqmp_dpsub: Set live video in format
> > 
> >  drivers/gpu/drm/xlnx/zynqmp_disp.c      | 111 +++++++++++++++++++++---
> >  drivers/gpu/drm/xlnx/zynqmp_disp.h      |   3 +-
> >  drivers/gpu/drm/xlnx/zynqmp_disp_regs.h |   8 +-
> >  drivers/gpu/drm/xlnx/zynqmp_dp.c        |  16 +++-
> >  drivers/gpu/drm/xlnx/zynqmp_kms.c       |   2 +-
> >  5 files changed, 119 insertions(+), 21 deletions(-)

-- 
Regards,

Laurent Pinchart


From david at sigma-star.at  Mon Feb  5 00:39:07 2024
From: david at sigma-star.at (David Gstir)
Date: Mon, 5 Feb 2024 09:39:07 +0100
Subject: [PATCH v5 0/6] DCP as trusted keys backend
In-Reply-To: <20231215110639.45522-1-david@sigma-star.at>
References: <20231215110639.45522-1-david@sigma-star.at>
Message-ID: <7AED262F-9387-446D-B11A-C549C02542F9@sigma-star.at>

Hi,

> On 15.12.2023, at 12:06, David Gstir <david at sigma-star.at> wrote:
> 
> This is a revival of the previous patch set submitted by Richard Weinberger:
> https://lore.kernel.org/linux-integrity/20210614201620.30451-1-richard at nod.at/
> 
> v4 is here:
> https://lore.kernel.org/keyrings/20231024162024.51260-1-david at sigma-star.at/
> 
> v4 -> v5:
> - Make Kconfig for trust source check scalable as suggested by Jarkko Sakkinen
> - Add Acked-By from Herbert Xu to patch #1 - thanks!
> v3 -> v4:
> - Split changes on MAINTAINERS and documentation into dedicated patches
> - Use more concise wording in commit messages as suggested by Jarkko Sakkinen
> v2 -> v3:
> - Addressed review comments from Jarkko Sakkinen
> v1 -> v2:
> - Revive and rebase to latest version
> - Include review comments from Ahmad Fatoum
> 
> The Data CoProcessor (DCP) is an IP core built into many NXP SoCs such
> as i.mx6ull.
> 
> Similar to the CAAM engine used in more powerful SoCs, DCP can AES-
> encrypt/decrypt user data using a unique, never-disclosed,
> device-specific key. Unlike CAAM though, it cannot directly wrap and
> unwrap blobs in hardware. As DCP offers only the bare minimum feature
> set and a blob mechanism needs aid from software. A blob in this case
> is a piece of sensitive data (e.g. a key) that is encrypted and
> authenticated using the device-specific key so that unwrapping can only
> be done on the hardware where the blob was wrapped.
> 
> This patch series adds a DCP based, trusted-key backend and is similar
> in spirit to the one by Ahmad Fatoum [0] that does the same for CAAM.
> It is of interest for similar use cases as the CAAM patch set, but for
> lower end devices, where CAAM is not available.
> 
> Because constructing and parsing the blob has to happen in software,
> we needed to decide on a blob format and chose the following:
> 
> struct dcp_blob_fmt {
> __u8 fmt_version;
> __u8 blob_key[AES_KEYSIZE_128];
> __u8 nonce[AES_KEYSIZE_128];
> __le32 payload_len;
> __u8 payload[];
> } __packed;
> 
> The `fmt_version` is currently 1.
> 
> The encrypted key is stored in the payload area. It is AES-128-GCM
> encrypted using `blob_key` and `nonce`, GCM auth tag is attached at
> the end of the payload (`payload_len` does not include the size of
> the auth tag).
> 
> The `blob_key` itself is encrypted in AES-128-ECB mode by DCP using
> the OTP or UNIQUE device key. A new `blob_key` and `nonce` are generated
> randomly, when sealing/exporting the DCP blob.
> 
> This patchset was tested with dm-crypt on an i.MX6ULL board.
> 
> [0] https://lore.kernel.org/keyrings/20220513145705.2080323-1-a.fatoum at pengutronix.de/
> 
> David Gstir (6):
>  crypto: mxs-dcp: Add support for hardware-bound keys
>  KEYS: trusted: improve scalability of trust source config
>  KEYS: trusted: Introduce NXP DCP-backed trusted keys
>  MAINTAINERS: add entry for DCP-based trusted keys
>  docs: document DCP-backed trusted keys kernel params
>  docs: trusted-encrypted: add DCP as new trust source
> 
> .../admin-guide/kernel-parameters.txt         |  13 +
> .../security/keys/trusted-encrypted.rst       |  85 +++++
> MAINTAINERS                                   |   9 +
> drivers/crypto/mxs-dcp.c                      | 104 +++++-
> include/keys/trusted_dcp.h                    |  11 +
> include/soc/fsl/dcp.h                         |  17 +
> security/keys/trusted-keys/Kconfig            |  18 +-
> security/keys/trusted-keys/Makefile           |   2 +
> security/keys/trusted-keys/trusted_core.c     |   6 +-
> security/keys/trusted-keys/trusted_dcp.c      | 311 ++++++++++++++++++
> 10 files changed, 562 insertions(+), 14 deletions(-)
> create mode 100644 include/keys/trusted_dcp.h
> create mode 100644 include/soc/fsl/dcp.h
> create mode 100644 security/keys/trusted-keys/trusted_dcp.c

Jarkko, Mimi, David do you need anything from my side for these patches to get them merged?

Thanks,
- David



From krzysztof.kozlowski at linaro.org  Mon Feb  5 00:44:49 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 09:44:49 +0100
Subject: [PATCH 1/3] dt-bindings: vendor-prefixes: add Jide
In-Reply-To: <20240204094404.149776-2-andre.przywara@arm.com>
References: <20240204094404.149776-1-andre.przywara@arm.com>
 <20240204094404.149776-2-andre.przywara@arm.com>
Message-ID: <be380e8b-b5b9-45f7-ac8b-699cb3a37c4c@linaro.org>

On 04/02/2024 10:44, Andre Przywara wrote:
> Jide tech once create the Remix OS Android system, and shipped it on
> some custom hardware. Add their name to the bindings.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Mon Feb  5 00:45:01 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 09:45:01 +0100
Subject: [PATCH 2/3] dt-bindings: arm: sunxi: document Remix Mini PC name
In-Reply-To: <20240204094404.149776-3-andre.przywara@arm.com>
References: <20240204094404.149776-1-andre.przywara@arm.com>
 <20240204094404.149776-3-andre.przywara@arm.com>
Message-ID: <17232561-5f1a-41fc-9002-e7482b0fdee0@linaro.org>

On 04/02/2024 10:44, Andre Przywara wrote:
> The Jide Remix Mini PC is a mini computer that ships with the Remix OS
> Android based system. The SoC is an Allwinner H64, which is very close,
> if not identical to the Allwinner A64.
> 
> Add the board/SoC compatible string pair to the list of known boards.
> There are some drivers that look explicitly for the A64 compatible name,
> so retain this name to increase compatibility.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From u.kleine-koenig at pengutronix.de  Mon Feb  5 00:52:06 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Mon, 5 Feb 2024 09:52:06 +0100
Subject: [PATCH v7 01/39] ARM: ep93xx: Add terminator to
 gpiod_lookup_table
In-Reply-To: <20240118-ep93xx-v7-1-d953846ae771@maquefel.me>
References: <20240118-ep93xx-v7-0-d953846ae771@maquefel.me>
 <20240118-ep93xx-v7-1-d953846ae771@maquefel.me>
Message-ID: <way2lxzhgnjjq4dnjucivo3aj2egnmtikgvtijbh65rkqnctta@ubtgdncaequj>

On Thu, Jan 18, 2024 at 11:20:44AM +0300, Nikita Shubin via B4 Relay wrote:
> From: Nikita Shubin <nikita.shubin at maquefel.me>
> 
> Without the terminator, if a con_id is passed to gpio_find() that
> does not exist in the lookup table the function will not stop looping
> correctly, and eventually cause an oops.
> 
> Fixes: b2e63555592f ("i2c: gpio: Convert to use descriptors")
> Reported-by: Andy Shevchenko <andriy.shevchenko at intel.com>
> Signed-off-by: Nikita Shubin <nikita.shubin at maquefel.me>

I don't know how's the state of the series and when it's expected to go
in. Given this is a fix preventing a possible oops, I wonder if this one
should be taken already now?

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/20240205/ea9a0e3d/attachment.sig>

From krzysztof.kozlowski at linaro.org  Mon Feb  5 00:54:47 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 09:54:47 +0100
Subject: [PATCH v2] dt-bindings: mfd: syscon: Add ti,j784s4-pcie-ctrl
 compatible
In-Reply-To: <20240204090336.3209063-1-s-vadapalli@ti.com>
References: <20240204090336.3209063-1-s-vadapalli@ti.com>
Message-ID: <abbd450d-8707-4daf-9a31-493c36dbc99c@linaro.org>

On 04/02/2024 10:03, Siddharth Vadapalli wrote:
> The PCIE_CTRL registers within the CTRL_MMR space of TI's J784S4 SoC
> are used to configure the link speed, lane count and mode of operation
> of the respective PCIe instance. Add compatible for allowing the PCIe
> driver to obtain a regmap for the PCIE_CTRL register within the System
> Controller device-tree node in order to configure the PCIe instance
> accordingly.
> 

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From yangyicong at huawei.com  Mon Feb  5 01:01:35 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 5 Feb 2024 17:01:35 +0800
Subject: [PATCH] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <20240123071201.30914-1-yangyicong@huawei.com>
References: <20240123071201.30914-1-yangyicong@huawei.com>
Message-ID: <ed2e65de-1d12-0284-a5ec-03f170fdff83@huawei.com>

Hi Perf and ARM folks,

A gentle ping...

Thanks.

On 2024/1/23 15:12, Yicong Yang wrote:
> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
> throughout and latency of PCIe traffic. With the support of PCIe PMU
> we can enable the perf iostat mode.
> 
> The HiSilicon PCIe PMU can support measuring the throughout of certain
> TLP types and of certian root port. Totally 6 metrics are provided in
> the unit of MB:
> 
> - Inbound MWR: The memory write TLPs from the devices downstream the root port
> - Inbound MRD: The memory read TLPs from the devices downstream the root port
> - Inbound CPL: The completion TLPs from the devices downstream the root port
> - Outbound MWR: The memory write TLPs from the CPU to the downstream devices
> - Outbound MRD: The memory read TLPs from the CPU to the downstream devices
> - Outbound CPL: The completions TLPs from the CPU to the downstream devices
> 
> Since the PMU measures the throughout with unit of DWords. So we need to
> calculate the throughout in MB like:
>   Count * 4B / 1024 / 1024
> 
> Some of the display of the `perf iostat` will be like:
> [root at localhost tmp]# ./perf iostat list
> hisi_pcie0_core2<0000:40:00.0>
> hisi_pcie2_core2<0000:5f:00.0>
> hisi_pcie0_core1<0000:16:00.0>
> hisi_pcie0_core1<0000:16:04.0>
> [root at localhost tmp]# ./perf iostat --timeout 10000
> 
>  Performance counter stats for 'system wide':
> 
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
> 
>       10.008227512 seconds time elapsed
> 
> [root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
> -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
> -norandommap -group_reporting -runtime=10 -time_based -bs=64k
> 
>  Performance counter stats for 'system wide':
> 
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
> 
>       10.168561767 seconds time elapsed
> 
>        0.465373000 seconds user
>        1.952948000 seconds sys
> 
> More information of the HiSilicon PCIe PMU can be found at
> Documentation/admin-guide/perf/hisi-pcie-pmu.rst.
> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
>  tools/perf/arch/arm64/util/Build         |   1 +
>  tools/perf/arch/arm64/util/hisi-iostat.c | 433 +++++++++++++++++++++++
>  2 files changed, 434 insertions(+)
>  create mode 100644 tools/perf/arch/arm64/util/hisi-iostat.c
> 
> diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
> index 78ef7115be3d..4e8dabf98b29 100644
> --- a/tools/perf/arch/arm64/util/Build
> +++ b/tools/perf/arch/arm64/util/Build
> @@ -3,6 +3,7 @@ perf-y += machine.o
>  perf-y += perf_regs.o
>  perf-y += tsc.o
>  perf-y += pmu.o
> +perf-y += hisi-iostat.o
>  perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
>  perf-$(CONFIG_DWARF)     += dwarf-regs.o
>  perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
> diff --git a/tools/perf/arch/arm64/util/hisi-iostat.c b/tools/perf/arch/arm64/util/hisi-iostat.c
> new file mode 100644
> index 000000000000..418eebece184
> --- /dev/null
> +++ b/tools/perf/arch/arm64/util/hisi-iostat.c
> @@ -0,0 +1,433 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * perf iostat support for HiSilicon PCIe PMU.
> + * Partly derived from tools/perf/arch/x86/util/iostat.c.
> + *
> + * Copyright (c) 2024 HiSilicon Technologies Co., Ltd.
> + * Author: Yicong Yang <yangyicong at hisilicon.com>
> + */
> +
> +#include <api/fs/fs.h>
> +#include <linux/err.h>
> +#include <linux/zalloc.h>
> +#include <linux/limits.h>
> +#include <dirent.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +
> +#include "util/counts.h"
> +#include "util/cpumap.h"
> +#include "util/debug.h"
> +#include "util/iostat.h"
> +#include "util/pmu.h"
> +
> +#define PCI_DEFAULT_DOMAIN		0
> +#define PCI_DEVICE_NAME_PATTERN		"%04x:%02hhx:%02hhx.%hhu"
> +#define PCI_ROOT_BUS_DEVICES_PATH	"bus/pci/devices"
> +
> +static const char * const hisi_iostat_metrics[] = {
> +	"Inbound MWR(MB)",
> +	"Inbound MRD(MB)",
> +	"Inbound CPL(MB)",
> +	"Outbound MWR(MB)",
> +	"Outbound MRD(MB)",
> +	"Outbound CPL(MB)",
> +};
> +
> +static const char * const hisi_iostat_cmd_template[] = {
> +	/* Inbound Memory Write */
> +	"hisi_pcie%hu_core%hu/event=0x0104,port=0x%hx/",
> +	/* Inbound Memory Read */
> +	"hisi_pcie%hu_core%hu/event=0x0804,port=0x%hx/",
> +	/* Inbound Memory Completion */
> +	"hisi_pcie%hu_core%hu/event=0x2004,port=0x%hx/",
> +	/* Outbound Memory Write */
> +	"hisi_pcie%hu_core%hu/event=0x0105,port=0x%hx/",
> +	/* Outbound Memory Read */
> +	"hisi_pcie%hu_core%hu/event=0x0405,port=0x%hx/",
> +	/* Outbound Memory Completion */
> +	"hisi_pcie%hu_core%hu/event=0x1005,port=0x%hx/",
> +};
> +
> +struct hisi_pcie_root_port {
> +	struct list_head list;
> +	/* Is this Root Port selected for monitoring */
> +	bool selected;
> +	/* IDs to locate the PMU */
> +	u16 sicl_id;
> +	u16 core_id;
> +	/* Filter mask for this Root Port */
> +	u16 mask;
> +	/* PCIe Root Port's <domain>:<bus>:<device>.<function> */
> +	u32 domain;
> +	u8 bus;
> +	u8 dev;
> +	u8 fn;
> +};
> +
> +LIST_HEAD(hisi_pcie_root_ports_list);
> +static int hisi_pcie_root_ports_num;
> +
> +static void hisi_pcie_init_root_port_mask(struct hisi_pcie_root_port *rp)
> +{
> +	rp->mask = BIT(rp->dev << 1);
> +}
> +
> +/*
> + * Select specific Root Port to monitor. Return 0 if successfully find the
> + * Root Port, Otherwise -EINVAL.
> + */
> +static int hisi_pcie_root_ports_select_one(u32 domain, u8 bus, u8 dev, u8 fn)
> +{
> +	struct hisi_pcie_root_port *rp;
> +
> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list)
> +		if (domain == rp->domain && bus == rp->bus &&
> +		    dev == rp->dev && fn == rp->fn) {
> +			rp->selected = true;
> +			return 0;
> +		}
> +
> +	return -EINVAL;
> +}
> +
> +static void hisi_pcie_root_ports_select_all(void)
> +{
> +	struct hisi_pcie_root_port *rp;
> +
> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list)
> +		rp->selected = true;
> +}
> +
> +static void hisi_pcie_root_ports_add(u16 sicl_id, u16 core_id, u8 target_bus)
> +{
> +	const char *sysfs = sysfs__mountpoint();
> +	struct hisi_pcie_root_port *rp;
> +	struct dirent *dent;
> +	char path[PATH_MAX];
> +	u8 bus, dev, fn;
> +	u32 domain;
> +	DIR *dir;
> +	int ret;
> +
> +	snprintf(path, PATH_MAX, "%s/%s", sysfs, PCI_ROOT_BUS_DEVICES_PATH);
> +	dir = opendir(path);
> +	if (!dir)
> +		return;
> +
> +	/* Scan the PCI root bus to find the match root port on @target_bus */
> +	while ((dent = readdir(dir))) {
> +		ret = sscanf(dent->d_name, PCI_DEVICE_NAME_PATTERN,
> +			     &domain, &bus, &dev, &fn);
> +		if (ret != 4 || bus != target_bus)
> +			continue;
> +
> +		rp = zalloc(sizeof(*rp));
> +		if (!rp)
> +			continue;
> +
> +		rp->selected = false;
> +		rp->sicl_id = sicl_id;
> +		rp->core_id = core_id;
> +		rp->domain = domain;
> +		rp->bus = bus;
> +		rp->dev = dev;
> +		rp->fn = fn;
> +
> +		hisi_pcie_init_root_port_mask(rp);
> +
> +		list_add(&rp->list, &hisi_pcie_root_ports_list);
> +		hisi_pcie_root_ports_num++;
> +
> +		pr_debug3("Found root port %s\n", dent->d_name);
> +	}
> +
> +	closedir(dir);
> +}
> +
> +/* Scan the PMUs and build the mapping of the Root Ports to the PMU */
> +static int hisi_pcie_root_ports_init(void)
> +{
> +	char event_source[PATH_MAX], bus_path[PATH_MAX];
> +	unsigned long long bus;
> +	u16 sicl_id, core_id;
> +	struct dirent *dent;
> +	DIR *dir;
> +
> +	perf_pmu__event_source_devices_scnprintf(event_source, sizeof(event_source));
> +	dir = opendir(event_source);
> +	if (!dir)
> +		return -ENOENT;
> +
> +	while ((dent = readdir(dir))) {
> +		/*
> +		 * This HiSilicon PCIe PMU will be named as:
> +		 *   hisi_pcie<sicl_id>_core<core_id>
> +		 */
> +		if ((sscanf(dent->d_name, "hisi_pcie%hu_core%hu", &sicl_id, &core_id)) != 2)
> +			continue;
> +
> +		/*
> +		 * Driver will export the root port it can monitor through
> +		 * the "bus" sysfs attribute.
> +		 */
> +		scnprintf(bus_path, sizeof(bus_path), "%s/hisi_pcie%hu_core%hu/bus",
> +			  event_source, sicl_id, core_id);
> +
> +		/*
> +		 * Per PCIe spec the bus should be 8bit, use unsigned long long
> +		 * for the convience of the library function.
> +		 */
> +		if (filename__read_ull(bus_path, &bus))
> +			continue;
> +
> +		pr_debug3("Found pmu %s bus 0x%llx\n", dent->d_name, bus);
> +
> +		hisi_pcie_root_ports_add(sicl_id, core_id, (u8)bus);
> +	}
> +
> +	closedir(dir);
> +	return hisi_pcie_root_ports_num > 0 ? 0 : -ENOENT;
> +}
> +
> +static void hisi_pcie_root_ports_free(void)
> +{
> +	struct hisi_pcie_root_port *rp, *tmp;
> +
> +	if (hisi_pcie_root_ports_num == 0)
> +		return;
> +
> +	list_for_each_entry_safe(rp, tmp, &hisi_pcie_root_ports_list, list) {
> +		list_del(&rp->list);
> +		zfree(&rp);
> +		hisi_pcie_root_ports_num--;
> +	}
> +}
> +
> +static int hisi_iostat_add_events(struct evlist *evl)
> +{
> +	struct hisi_pcie_root_port *rp;
> +	struct evsel *evsel;
> +	unsigned int i, j;
> +	char *iostat_cmd;
> +	int pos = 0;
> +	int ret;
> +
> +	if (!hisi_pcie_root_ports_num)
> +		return -ENOENT;
> +
> +	iostat_cmd = zalloc(PATH_MAX);
> +	if (!iostat_cmd)
> +		return -ENOMEM;
> +
> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list) {
> +		if (!rp->selected)
> +			continue;
> +
> +		iostat_cmd[pos++] = '{';
> +		for (j = 0; j < ARRAY_SIZE(hisi_iostat_cmd_template); j++) {
> +			pos += snprintf(iostat_cmd + pos, ARG_MAX - pos - 1,
> +					hisi_iostat_cmd_template[j],
> +					rp->sicl_id, rp->core_id, rp->mask);
> +
> +			if (j == ARRAY_SIZE(hisi_iostat_cmd_template) - 1)
> +				iostat_cmd[pos++] = '}';
> +			else
> +				iostat_cmd[pos++] = ',';
> +		}
> +
> +		ret = parse_event(evl, iostat_cmd);
> +		if (ret)
> +			break;
> +
> +		i = 0;
> +		evlist__for_each_entry_reverse(evl, evsel) {
> +			if (i == ARRAY_SIZE(hisi_iostat_cmd_template))
> +				break;
> +
> +			evsel->priv = rp;
> +			i++;
> +		}
> +
> +		memset(iostat_cmd, 0, PATH_MAX);
> +		pos = 0;
> +	}
> +
> +	zfree(&iostat_cmd);
> +	return ret;
> +}
> +
> +int iostat_prepare(struct evlist *evlist,
> +		   struct perf_stat_config *config)
> +{
> +	if (evlist->core.nr_entries > 0) {
> +		pr_warning("The -e and -M options are not supported."
> +			   "All chosen events/metrics will be dropped\n");
> +		evlist__delete(evlist);
> +		evlist = evlist__new();
> +		if (!evlist)
> +			return -ENOMEM;
> +	}
> +
> +	config->metric_only = true;
> +	config->aggr_mode = AGGR_GLOBAL;
> +
> +	return hisi_iostat_add_events(evlist);
> +}
> +
> +static int hisi_pcie_root_ports_list_filter(const char *str)
> +{
> +	char *tok, *tmp, *copy = NULL;
> +	u8 bus, dev, fn;
> +	u32 domain;
> +	int ret;
> +
> +	copy = strdup(str);
> +	if (!copy)
> +		return -ENOMEM;
> +
> +	for (tok = strtok_r(copy, ",", &tmp); tok; tok = strtok_r(NULL, ",", &tmp)) {
> +		ret = sscanf(tok, PCI_DEVICE_NAME_PATTERN, &domain, &bus, &dev, &fn);
> +		if (ret != 4) {
> +			ret = -EINVAL;
> +			break;
> +		}
> +
> +		ret = hisi_pcie_root_ports_select_one(domain, bus, dev, fn);
> +		if (ret)
> +			break;
> +	}
> +
> +	zfree(&copy);
> +	return ret;
> +}
> +
> +int iostat_parse(const struct option *opt, const char *str, int unset __maybe_unused)
> +{
> +	struct perf_stat_config *config = (struct perf_stat_config *)opt->data;
> +	int ret;
> +
> +	ret = hisi_pcie_root_ports_init();
> +	if (!ret) {
> +		config->iostat_run = true;
> +
> +		if (!str) {
> +			iostat_mode = IOSTAT_RUN;
> +			hisi_pcie_root_ports_select_all();
> +		} else if (!strcmp(str, "list")) {
> +			iostat_mode = IOSTAT_LIST;
> +			hisi_pcie_root_ports_select_all();
> +		} else {
> +			iostat_mode = IOSTAT_RUN;
> +			ret = hisi_pcie_root_ports_list_filter(str);
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static void hisi_pcie_root_port_show(FILE *output,
> +				     const struct hisi_pcie_root_port * const rp)
> +{
> +	if (output && rp)
> +		fprintf(output, "hisi_pcie%hu_core%hu<" PCI_DEVICE_NAME_PATTERN ">\n",
> +			rp->sicl_id, rp->core_id, rp->domain, rp->bus, rp->dev, rp->fn);
> +}
> +
> +void iostat_list(struct evlist *evlist __maybe_unused, struct perf_stat_config *config)
> +{
> +	struct hisi_pcie_root_port *rp = NULL;
> +	struct evsel *evsel;
> +
> +	evlist__for_each_entry(evlist, evsel) {
> +		if (rp != evsel->priv) {
> +			hisi_pcie_root_port_show(config->output, evsel->priv);
> +			rp = evsel->priv;
> +		}
> +	}
> +}
> +
> +void iostat_release(struct evlist *evlist)
> +{
> +	struct evsel *evsel;
> +
> +	evlist__for_each_entry(evlist, evsel)
> +		evsel->priv = NULL;
> +
> +	hisi_pcie_root_ports_free();
> +}
> +
> +void iostat_print_header_prefix(struct perf_stat_config *config)
> +{
> +	if (config->csv_output)
> +		fputs("port,", config->output);
> +	else if (config->interval)
> +		fprintf(config->output, "#          time    port         ");
> +	else
> +		fprintf(config->output, "   port         ");
> +}
> +
> +void iostat_print_metric(struct perf_stat_config *config, struct evsel *evsel,
> +			 struct perf_stat_output_ctx *out)
> +{
> +	struct perf_counts_values *count;
> +	const char *iostat_metric;
> +	double iostat_value;
> +
> +	iostat_metric = hisi_iostat_metrics[evsel->core.idx % ARRAY_SIZE(hisi_iostat_metrics)];
> +
> +	/* We're using AGGR_GLOBAL so there's only one aggr counts aggr[0]. */
> +	count = &evsel->stats->aggr[0].counts;
> +
> +	/* The counts has been scaled, we can use it directly. */
> +	iostat_value = (double)count->val;
> +
> +	/*
> +	 * Display two digits after decimal point for better accuracy if the
> +	 * value is non-zero.
> +	 */
> +	out->print_metric(config, out->ctx, NULL,
> +			  iostat_value > 0 ? "%8.2f" : "%8.0f",
> +			  iostat_metric, iostat_value / (256 * 1024));
> +}
> +
> +void iostat_prefix(struct evlist *evlist, struct perf_stat_config *config,
> +		   char *prefix, struct timespec *ts)
> +{
> +	struct hisi_pcie_root_port *rp = evlist->selected->priv;
> +
> +	if (rp) {
> +		if (ts)
> +			sprintf(prefix, "%6lu.%09lu%s" PCI_DEVICE_NAME_PATTERN "%s",
> +				ts->tv_sec, ts->tv_nsec, config->csv_sep,
> +				rp->domain, rp->bus, rp->dev, rp->fn,
> +				config->csv_sep);
> +		else
> +			sprintf(prefix, PCI_DEVICE_NAME_PATTERN "%s",
> +				rp->domain, rp->bus, rp->dev, rp->fn,
> +				config->csv_sep);
> +	}
> +}
> +
> +void iostat_print_counters(struct evlist *evlist, struct perf_stat_config *config,
> +			   struct timespec *ts, char *prefix,
> +			   iostat_print_counter_t print_cnt_cb, void *arg)
> +{
> +	struct evsel *counter = evlist__first(evlist);
> +	void *perf_device;
> +
> +	evlist__set_selected(evlist, counter);
> +	iostat_prefix(evlist, config, prefix, ts);
> +	fprintf(config->output, "%s", prefix);
> +	evlist__for_each_entry(evlist, counter) {
> +		perf_device = evlist->selected->priv;
> +		if (perf_device && perf_device != counter->priv) {
> +			evlist__set_selected(evlist, counter);
> +			iostat_prefix(evlist, config, prefix, ts);
> +			fprintf(config->output, "\n%s", prefix);
> +		}
> +		print_cnt_cb(config, counter, arg);
> +	}
> +	fputc('\n', config->output);
> +}
> 


From jbrunet at baylibre.com  Mon Feb  5 01:02:01 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 05 Feb 2024 10:02:01 +0100
Subject: [PATCH] clk: meson: Add missing clocks to axg_clk_regmaps
In-Reply-To: <20240202172537.1.I64656c75d84284bc91e6126b50b33c502be7c42a@changeid>
References: <20240202172537.1.I64656c75d84284bc91e6126b50b33c502be7c42a@changeid>
Message-ID: <1j7cjji8mu.fsf@starbuckisacylon.baylibre.com>


On Fri 02 Feb 2024 at 17:25, Igor Prusov <ivprusov at salutedevices.com> wrote:

> Some clocks were missing from axg_clk_regmaps, which caused kernel panic
> during cat /sys/kernel/debug/clk/clk_summary
>
> [   57.349402] Unable to handle kernel NULL pointer dereference at virtual address 00000000000001fc
> ...
> [   57.430002] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [   57.436900] pc : regmap_read+0x1c/0x88
> [   57.440608] lr : clk_regmap_gate_is_enabled+0x3c/0xb0
> [   57.445611] sp : ffff800082f1b690
> [   57.448888] x29: ffff800082f1b690 x28: 0000000000000000 x27: ffff800080eb9a70
> [   57.455961] x26: 0000000000000007 x25: 0000000000000016 x24: 0000000000000000
> [   57.463033] x23: ffff800080e8b488 x22: 0000000000000015 x21: ffff00000e7e7000
> [   57.470106] x20: ffff00000400ec00 x19: 0000000000000000 x18: ffffffffffffffff
> [   57.477178] x17: 0000000000000000 x16: 0000000000000000 x15: ffff0000042a3000
> [   57.484251] x14: 0000000000000000 x13: ffff0000042a2fec x12: 0000000005f5e100
> [   57.491323] x11: abcc77118461cefd x10: 0000000000000020 x9 : ffff8000805e4b24
> [   57.498396] x8 : ffff0000028063c0 x7 : ffff800082f1b710 x6 : ffff800082f1b710
> [   57.505468] x5 : 00000000ffffffd0 x4 : ffff800082f1b6e0 x3 : 0000000000001000
> [   57.512541] x2 : ffff800082f1b6e4 x1 : 000000000000012c x0 : 0000000000000000
> [   57.519615] Call trace:
> [   57.522030]  regmap_read+0x1c/0x88
> [   57.525393]  clk_regmap_gate_is_enabled+0x3c/0xb0
> [   57.530050]  clk_core_is_enabled+0x44/0x120
> [   57.534190]  clk_summary_show_subtree+0x154/0x2f0
> [   57.538847]  clk_summary_show_subtree+0x220/0x2f0
> [   57.543505]  clk_summary_show_subtree+0x220/0x2f0
> [   57.548162]  clk_summary_show_subtree+0x220/0x2f0
> [   57.552820]  clk_summary_show_subtree+0x220/0x2f0
> [   57.557477]  clk_summary_show_subtree+0x220/0x2f0
> [   57.562135]  clk_summary_show_subtree+0x220/0x2f0
> [   57.566792]  clk_summary_show_subtree+0x220/0x2f0
> [   57.571450]  clk_summary_show+0x84/0xb8
> [   57.575245]  seq_read_iter+0x1bc/0x4b8
> [   57.578954]  seq_read+0x8c/0xd0
> [   57.582059]  full_proxy_read+0x68/0xc8
> [   57.585767]  vfs_read+0xb0/0x268
> [   57.588959]  ksys_read+0x70/0x108
> [   57.592236]  __arm64_sys_read+0x24/0x38
> [   57.596031]  invoke_syscall+0x50/0x128
> [   57.599740]  el0_svc_common.constprop.0+0x48/0xf8
> [   57.604397]  do_el0_svc+0x28/0x40
> [   57.607675]  el0_svc+0x34/0xb8
> [   57.610694]  el0t_64_sync_handler+0x13c/0x158
> [   57.615006]  el0t_64_sync+0x190/0x198
> [   57.618635] Code: a9bd7bfd 910003fd a90153f3 aa0003f3 (b941fc00)
> [   57.624668] ---[ end trace 0000000000000000 ]---
>
> Signed-off-by: Igor Prusov <ivprusov at salutedevices.com>

This has gone un-noticed for a while :/
Thanks Igor.

Please remember to add an appropriate Fixes tag for patches like this.
It is important to help stable releases.

Fixes: 14ebb3154b8f ("clk: meson: axg: add Video Clocks")

> ---
>
>  drivers/clk/meson/axg.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
> index c12f81dfa674..5f60f2bcca59 100644
> --- a/drivers/clk/meson/axg.c
> +++ b/drivers/clk/meson/axg.c
> @@ -2142,7 +2142,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>  	&axg_vclk_input,
>  	&axg_vclk2_input,
>  	&axg_vclk_div,
> +	&axg_vclk_div1,
>  	&axg_vclk2_div,
> +	&axg_vclk2_div1,
>  	&axg_vclk_div2_en,
>  	&axg_vclk_div4_en,
>  	&axg_vclk_div6_en,


-- 
Jerome


From danishanwar at ti.com  Mon Feb  5 01:05:44 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 5 Feb 2024 14:35:44 +0530
Subject: [PATCH v4 1/3] arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
In-Reply-To: <20240205090546.4000446-1-danishanwar@ti.com>
References: <20240205090546.4000446-1-danishanwar@ti.com>
Message-ID: <20240205090546.4000446-2-danishanwar@ti.com>

From: Suman Anna <s-anna at ti.com>

The ICSSG IP on AM64x SoCs have two Industrial Ethernet Peripherals (IEPs)
to manage/generate Industrial Ethernet functions such as time stamping.
Each IEP sub-module is sourced from an internal clock mux that can be
derived from either of the IP instance's ICSSG_IEP_GCLK or from another
internal ICSSG CORE_CLK mux. Add both the IEP nodes for both the ICSSG
instances. The IEP clock is currently configured to be derived
indirectly from the ICSSG_ICLK running at 250 MHz.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
Signed-off-by: Suman Anna <s-anna at ti.com>
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Reviewed-by: Ravi Gunasekaran <r-gunasekaran at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index e348114f42e0..9d2dad8ae8df 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -1244,6 +1244,18 @@ icssg0_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg0_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
+		icssg0_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
 		icssg0_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
@@ -1385,6 +1397,18 @@ icssg1_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg1_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
+		icssg1_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
 		icssg1_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
-- 
2.34.1



From danishanwar at ti.com  Mon Feb  5 01:05:45 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 5 Feb 2024 14:35:45 +0530
Subject: [PATCH v4 2/3] arm64: dts: ti: k3-am642-evm: add ICSSG1 Ethernet support
In-Reply-To: <20240205090546.4000446-1-danishanwar@ti.com>
References: <20240205090546.4000446-1-danishanwar@ti.com>
Message-ID: <20240205090546.4000446-3-danishanwar@ti.com>

ICSSG1 provides dual Gigabit Ethernet support with proper FW loaded.

The ICSSG1 MII0 (RGMII1) has DP83869 PHY attached to it. The ICSSG1 shares
MII1 (RGMII2) PHY DP83869 with CPSW3g and it's assigned by default to
CPSW3g. The MDIO access to MII1 (RGMII2) PHY DP83869 is controlled by MDIO
bus switch and also assigned to CPSW3g. Therefore the ICSSG1 MII1 (RGMII2)
port is kept disable and ICSSG1 is enabled in single MAC mode by
default.

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Reviewed-by: Ravi Gunasekaran <r-gunasekaran at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am642-evm.dts | 97 +++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 8c5651d2cf5d..6b97e447c486 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -32,6 +32,7 @@ aliases {
 		mmc1 = &sdhci1;
 		ethernet0 = &cpsw_port1;
 		ethernet1 = &cpsw_port2;
+		ethernet2 = &icssg1_emac0;
 	};
 
 	memory at 80000000 {
@@ -229,6 +230,66 @@ transceiver2: can-phy1 {
 		max-bitrate = <5000000>;
 		standby-gpios = <&exp1 9 GPIO_ACTIVE_HIGH>;
 	};
+
+	icssg1_eth: icssg1-eth {
+		compatible = "ti,am642-icssg-prueth";
+		pinctrl-names = "default";
+		pinctrl-0 = <&icssg1_rgmii1_pins_default>;
+		sram = <&oc_sram>;
+		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
+		firmware-name = "ti-pruss/am64x-sr2-pru0-prueth-fw.elf",
+				"ti-pruss/am64x-sr2-rtu0-prueth-fw.elf",
+				"ti-pruss/am64x-sr2-txpru0-prueth-fw.elf",
+				"ti-pruss/am64x-sr2-pru1-prueth-fw.elf",
+				"ti-pruss/am64x-sr2-rtu1-prueth-fw.elf",
+				"ti-pruss/am64x-sr2-txpru1-prueth-fw.elf";
+
+		ti,pruss-gp-mux-sel = <2>,	/* MII mode */
+				      <2>,
+				      <2>,
+				      <2>,	/* MII mode */
+				      <2>,
+				      <2>;
+		ti,mii-g-rt = <&icssg1_mii_g_rt>;
+		ti,mii-rt = <&icssg1_mii_rt>;
+		ti,iep = <&icssg1_iep0>,  <&icssg1_iep1>;
+		interrupt-parent = <&icssg1_intc>;
+		interrupts = <24 0 2>, <25 1 3>;
+		interrupt-names = "tx_ts0", "tx_ts1";
+		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
+		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
+		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
+		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+			    "rx0", "rx1";
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			icssg1_emac0: port at 0 {
+				reg = <0>;
+				phy-handle = <&icssg1_phy1>;
+				phy-mode = "rgmii-id";
+				ti,syscon-rgmii-delay = <&main_conf 0x4110>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+			};
+			icssg1_emac1: port at 1 {
+				reg = <1>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4114>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				status = "disabled";
+			};
+		};
+	};
 };
 
 &main_pmx0 {
@@ -383,6 +444,30 @@ ddr_vtt_pins_default: ddr-vtt-default-pins {
 			AM64X_IOPAD(0x0030, PIN_OUTPUT_PULLUP, 7) /* (L18) OSPI0_CSN1.GPIO0_12 */
 		>;
 	};
+
+	icssg1_mdio1_pins_default: icssg1-mdio1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0) /* (Y6) PRG1_MDIO0_MDC */
+			AM64X_IOPAD(0x0158, PIN_INPUT, 0) /* (AA6) PRG1_MDIO0_MDIO */
+		>;
+	};
+
+	icssg1_rgmii1_pins_default: icssg1-rgmii1-default-pins{
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x00b8, PIN_INPUT, 2) /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
+			AM64X_IOPAD(0x00bc, PIN_INPUT, 2) /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
+			AM64X_IOPAD(0x00c0, PIN_INPUT, 2) /* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
+			AM64X_IOPAD(0x00c4, PIN_INPUT, 2) /* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
+			AM64X_IOPAD(0x00d0, PIN_INPUT, 2) /* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
+			AM64X_IOPAD(0x00c8, PIN_INPUT, 2) /* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
+			AM64X_IOPAD(0x00e4, PIN_INPUT, 2) /* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
+			AM64X_IOPAD(0x00e8, PIN_INPUT, 2) /* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
+			AM64X_IOPAD(0x00ec, PIN_INPUT, 2) /* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
+			AM64X_IOPAD(0x00f0, PIN_INPUT, 2) /* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
+			AM64X_IOPAD(0x00f8, PIN_INPUT, 2) /* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
+			AM64X_IOPAD(0x00f4, PIN_INPUT, 2) /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
+		>;
+	};
 };
 
 &main_uart0 {
@@ -731,3 +816,15 @@ &main_mcan1 {
 	pinctrl-0 = <&main_mcan1_pins_default>;
 	phys = <&transceiver2>;
 };
+
+&icssg1_mdio {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&icssg1_mdio1_pins_default>;
+
+	icssg1_phy1: ethernet-phy at f {
+		reg = <0xf>;
+		tx-internal-delay-ps = <250>;
+		rx-internal-delay-ps = <2000>;
+	};
+};
-- 
2.34.1



From danishanwar at ti.com  Mon Feb  5 01:05:46 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 5 Feb 2024 14:35:46 +0530
Subject: [PATCH v4 3/3] arm64: dts: ti: k3-am642-evm: add overlay for icssg1 2nd port
In-Reply-To: <20240205090546.4000446-1-danishanwar@ti.com>
References: <20240205090546.4000446-1-danishanwar@ti.com>
Message-ID: <20240205090546.4000446-4-danishanwar@ti.com>

The am642-evm doesn't allow to enable 2 x CPSW3g ports and 2 x ICSSG1 ports
all together, so base k3-am642-evm.dts enables by default 2 x CPSW3g ports
and 1 x ICSSG1 ports, but it is also possible to support 1 x CPSW3g ports
and 2 x ICSSG1 ports configuration.

This patch adds overlay to support 1 x CPSW3g ports and 2 x ICSSG1 ports
configuration:
- Renames 'mdio-mux-1' node to 'mdio-mux at 1'
- Add label name 'mdio_mux_1' for 'mdio-mux at 1' node so that the node
  'mdio-mux at 1' can be disabled in the overlay using the label name.
- disable 2nd CPSW3g port
- update CPSW3g pinmuxes to not use RGMII2
- disable mdio-mux-1 and define mdio-mux-2 to route ICSSG1 MDIO to the
  shared DP83869 PHY
- add and enable ICSSG1 RGMII2 pinmuxes
- enable ICSSG1 MII1 port

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Reviewed-by: Ravi Gunasekaran <r-gunasekaran at ti.com>
---
 arch/arm64/boot/dts/ti/Makefile               |  5 ++
 .../dts/ti/k3-am642-evm-icssg1-dualemac.dtso  | 79 +++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  2 +-
 3 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..320b2fae5730 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac.dtbo
 
 # Boards with AM65x SoC
 k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
@@ -105,6 +106,8 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
+k3-am642-evm-icssg1-dualemac-dtbs := \
+	k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
 k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
 	k3-j721e-evm-pcie0-ep.dtbo
 k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
@@ -120,6 +123,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am62a7-sk-csi2-ov5640.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
+	k3-am642-evm-icssg1-dualemac.dtb \
 	k3-j721e-evm-pcie0-ep.dtb \
 	k3-j721s2-evm-pcie1-ep.dtb
 
@@ -129,6 +133,7 @@ DTC_FLAGS_k3-am625-sk += -@
 DTC_FLAGS_k3-am62-lp-sk += -@
 DTC_FLAGS_k3-am62a7-sk += -@
 DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
+DTC_FLAGS_k3-am642-evm += -@
 DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
 DTC_FLAGS_k3-j721e-common-proc-board += -@
 DTC_FLAGS_k3-j721s2-common-proc-board += -@
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
new file mode 100644
index 000000000000..f653a8eb820e
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT overlay for enabling 2nd ICSSG1 port on AM642 EVM
+ *
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	aliases {
+		ethernet1 = "/icssg1-eth/ethernet-ports/port at 1";
+	};
+
+	mdio-mux at 0 {
+		compatible = "mdio-mux-multiplexer";
+		mux-controls = <&mdio_mux>;
+		mdio-parent-bus = <&icssg1_mdio>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		mdio at 0 {
+			reg = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			icssg1_phy2: ethernet-phy at 3 {
+				reg = <3>;
+				tx-internal-delay-ps = <250>;
+				rx-internal-delay-ps = <2000>;
+			};
+		};
+	};
+};
+
+&main_pmx0 {
+	icssg1_rgmii2_pins_default: icssg1-rgmii2-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0108, PIN_INPUT, 2) /* (W11) PRG1_PRU1_GPO0.RGMII2_RD0 */
+			AM64X_IOPAD(0x010c, PIN_INPUT, 2) /* (V11) PRG1_PRU1_GPO1.RGMII2_RD1 */
+			AM64X_IOPAD(0x0110, PIN_INPUT, 2) /* (AA12) PRG1_PRU1_GPO2.RGMII2_RD2 */
+			AM64X_IOPAD(0x0114, PIN_INPUT, 2) /* (Y12) PRG1_PRU1_GPO3.RGMII2_RD3 */
+			AM64X_IOPAD(0x0120, PIN_INPUT, 2) /* (U11) PRG1_PRU1_GPO6.RGMII2_RXC */
+			AM64X_IOPAD(0x0118, PIN_INPUT, 2) /* (W12) PRG1_PRU1_GPO4.RGMII2_RX_CTL */
+			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2) /* (AA10) PRG1_PRU1_GPO11.RGMII2_TD0 */
+			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2) /* (V10) PRG1_PRU1_GPO12.RGMII2_TD1 */
+			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2) /* (U10) PRG1_PRU1_GPO13.RGMII2_TD2 */
+			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2) /* (AA11) PRG1_PRU1_GPO14.RGMII2_TD3 */
+			AM64X_IOPAD(0x0148, PIN_OUTPUT, 2) /* (Y10) PRG1_PRU1_GPO16.RGMII2_TXC */
+			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2) /* (Y11) PRG1_PRU1_GPO15.RGMII2_TX_CTL */
+		>;
+	};
+};
+
+&cpsw3g {
+	pinctrl-0 = <&rgmii1_pins_default>;
+};
+
+&cpsw_port2 {
+	status = "disabled";
+};
+
+&mdio_mux_1 {
+	status = "disabled";
+};
+
+&icssg1_eth {
+	pinctrl-0 = <&icssg1_rgmii1_pins_default>, <&icssg1_rgmii2_pins_default>;
+};
+
+&icssg1_emac1 {
+	status = "okay";
+	phy-handle = <&icssg1_phy2>;
+	phy-mode = "rgmii-id";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 6b97e447c486..35ed5b5aab63 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -199,7 +199,7 @@ mdio_mux: mux-controller {
 		mux-gpios = <&exp1 12 GPIO_ACTIVE_HIGH>;
 	};
 
-	mdio-mux-1 {
+	mdio_mux_1: mdio-mux at 1 {
 		compatible = "mdio-mux-multiplexer";
 		mux-controls = <&mdio_mux>;
 		mdio-parent-bus = <&cpsw3g_mdio>;
-- 
2.34.1



From konrad.zielinski at synergyflux.pl  Mon Feb  5 01:05:33 2024
From: konrad.zielinski at synergyflux.pl (=?UTF-8?Q? Konrad_Zieli=C5=84ski_ ?=)
Date: Mon,  5 Feb 2024 09:05:33 GMT
Subject: Instalacja pv
Message-ID: <20240205074500-0.1.9m.1w5rz.0.j4qlba9bkv@synergyflux.pl>

Dzie? dobry,

czy s? Pa?stwo otwarci na niezobowi?zuj?c? rozmow? na temat fotowoltaiki?

Jako firma specjalizuj?ca si? w instalacji i serwisie najlepszych jako?ciowo paneli s?onecznych na rynku chcia?bym przedstawi? propozycj?, jak? wsp?lnie z zespo?em przygotowali?my dla Pa?stwa obiektu.

B?d? wdzi?czny za wiadomo?? od Pa?stwa czy mo?emy porozmawia?.


Pozdrawiam
Konrad Zieli?ski 


From raphael.gallais-pou at foss.st.com  Mon Feb  5 01:06:52 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Mon, 5 Feb 2024 10:06:52 +0100
Subject: [PATCH 2/5] ARM: dts: stm32: add LTDC pinctrl on STM32MP13x SoC
 family
In-Reply-To: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
Message-ID: <20240205-ltdc_mp13-v1-2-072d24bf1b36@foss.st.com>

Adds LTDC pinctrl support and assigns dedicated GPIO pins.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 57 +++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
index 27e0c3826789..32c5d8a1e06a 100644
--- a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
@@ -47,6 +47,63 @@ pins {
 		};
 	};
 
+	ltdc_pins_a: ltdc-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D',  9, AF13)>, /* LCD_CLK */
+				 <STM32_PINMUX('C',  6, AF14)>, /* LCD_HSYNC */
+				 <STM32_PINMUX('G',  4, AF11)>, /* LCD_VSYNC */
+				 <STM32_PINMUX('H',  9, AF11)>, /* LCD_DE */
+				 <STM32_PINMUX('G',  7, AF14)>, /* LCD_R2 */
+				 <STM32_PINMUX('B', 12, AF13)>, /* LCD_R3 */
+				 <STM32_PINMUX('D', 14, AF14)>, /* LCD_R4 */
+				 <STM32_PINMUX('E',  7, AF14)>, /* LCD_R5 */
+				 <STM32_PINMUX('E', 13, AF14)>, /* LCD_R6 */
+				 <STM32_PINMUX('E',  9, AF14)>, /* LCD_R7 */
+				 <STM32_PINMUX('H', 13, AF14)>, /* LCD_G2 */
+				 <STM32_PINMUX('F',  3, AF14)>, /* LCD_G3 */
+				 <STM32_PINMUX('D',  5, AF14)>, /* LCD_G4 */
+				 <STM32_PINMUX('G',  0, AF14)>, /* LCD_G5 */
+				 <STM32_PINMUX('C',  7, AF14)>, /* LCD_G6 */
+				 <STM32_PINMUX('A', 15, AF11)>, /* LCD_G7 */
+				 <STM32_PINMUX('D', 10, AF14)>, /* LCD_B2 */
+				 <STM32_PINMUX('F',  2, AF14)>, /* LCD_B3 */
+				 <STM32_PINMUX('H', 14, AF11)>, /* LCD_B4 */
+				 <STM32_PINMUX('E',  0, AF14)>, /* LCD_B5 */
+				 <STM32_PINMUX('B',  6, AF7)>,  /* LCD_B6 */
+				 <STM32_PINMUX('F',  1, AF13)>; /* LCD_B7 */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	ltdc_sleep_pins_a: ltdc-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D',  9, ANALOG)>, /* LCD_CLK */
+				 <STM32_PINMUX('C',  6, ANALOG)>, /* LCD_HSYNC */
+				 <STM32_PINMUX('G',  4, ANALOG)>, /* LCD_VSYNC */
+				 <STM32_PINMUX('H',  9, ANALOG)>, /* LCD_DE */
+				 <STM32_PINMUX('G',  7, ANALOG)>, /* LCD_R2 */
+				 <STM32_PINMUX('B', 12, ANALOG)>, /* LCD_R3 */
+				 <STM32_PINMUX('D', 14, ANALOG)>, /* LCD_R4 */
+				 <STM32_PINMUX('E',  7, ANALOG)>, /* LCD_R5 */
+				 <STM32_PINMUX('E', 13, ANALOG)>, /* LCD_R6 */
+				 <STM32_PINMUX('E',  9, ANALOG)>, /* LCD_R7 */
+				 <STM32_PINMUX('H', 13, ANALOG)>, /* LCD_G2 */
+				 <STM32_PINMUX('F',  3, ANALOG)>, /* LCD_G3 */
+				 <STM32_PINMUX('D',  5, ANALOG)>, /* LCD_G4 */
+				 <STM32_PINMUX('G',  0, ANALOG)>, /* LCD_G5 */
+				 <STM32_PINMUX('C',  7, ANALOG)>, /* LCD_G6 */
+				 <STM32_PINMUX('A', 15, ANALOG)>, /* LCD_G7 */
+				 <STM32_PINMUX('D', 10, ANALOG)>, /* LCD_B2 */
+				 <STM32_PINMUX('F',  2, ANALOG)>, /* LCD_B3 */
+				 <STM32_PINMUX('H', 14, ANALOG)>, /* LCD_B4 */
+				 <STM32_PINMUX('E',  0, ANALOG)>, /* LCD_B5 */
+				 <STM32_PINMUX('B',  6, ANALOG)>, /* LCD_B6 */
+				 <STM32_PINMUX('F',  1, ANALOG)>; /* LCD_B7 */
+		};
+	};
+
 	mcp23017_pins_a: mcp23017-0 {
 		pins {
 			pinmux = <STM32_PINMUX('G', 12, GPIO)>;

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Mon Feb  5 01:06:53 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Mon, 5 Feb 2024 10:06:53 +0100
Subject: [PATCH 3/5] ARM: dts: stm32: enable display support on
 stm32mp135f-dk board
In-Reply-To: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
Message-ID: <20240205-ltdc_mp13-v1-3-072d24bf1b36@foss.st.com>

Link panel and display controller.
Enable panel, backlight and display controller.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp135f-dk.dts | 55 +++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
index eea740d097c7..4a52d314c46d 100644
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -66,6 +66,48 @@ led-blue {
 			default-state = "off";
 		};
 	};
+
+	panel_backlight: panel-backlight {
+		compatible = "gpio-backlight";
+		gpios = <&gpioe 12 GPIO_ACTIVE_HIGH>;
+		default-on;
+		default-brightness-level = <0>;
+		status = "okay";
+	};
+
+	panel_rgb: panel-rgb {
+		compatible = "rocktech,rk043fn48h", "panel-dpi";
+		enable-gpios = <&gpioi 7 GPIO_ACTIVE_HIGH>;
+		backlight = <&panel_backlight>;
+		power-supply = <&scmi_v3v3_sw>;
+		data-mapping = "bgr666";
+		status = "okay";
+
+		width-mm = <105>;
+		height-mm = <67>;
+
+		panel-timing {
+			clock-frequency = <10000000>;
+			hactive = <480>;
+			hback-porch = <43>;
+			hfront-porch = <10>;
+			hsync-len = <1>;
+			hsync-active = <0>;
+			vactive = <272>;
+			vback-porch = <26>;
+			vfront-porch = <4>;
+			vsync-len = <10>;
+			vsync-active = <0>;
+			de-active = <1>;
+			pixelclk-active = <1>;
+		};
+
+		port {
+			panel_in_rgb: endpoint {
+				remote-endpoint = <&ltdc_out_rgb>;
+			};
+		};
+	};
 };
 
 &adc_1 {
@@ -160,6 +202,19 @@ &iwdg2 {
 	status = "okay";
 };
 
+&ltdc {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&ltdc_pins_a>;
+	pinctrl-1 = <&ltdc_sleep_pins_a>;
+	status = "okay";
+
+	port {
+		ltdc_out_rgb: endpoint {
+			remote-endpoint = <&panel_in_rgb>;
+		};
+	};
+};
+
 &rtc {
 	status = "okay";
 };

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Mon Feb  5 01:06:51 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Mon, 5 Feb 2024 10:06:51 +0100
Subject: [PATCH 1/5] ARM: dts: stm32: add LTDC support for STM32MP13x SoC
 family
In-Reply-To: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
Message-ID: <20240205-ltdc_mp13-v1-1-072d24bf1b36@foss.st.com>

STM32MP13x SoC family embeds a new version of LTDC (Liquid crystal
display - Thin film transistor) Display Controller.

It provides a parallel digital RGB (red, green, blue) and signals for
horizontal, vertical synchronization, pixel clock and data enable as
output to interface directly to a variety of LCD-TFT panels.

Main features
  * 2 input layers blended together to compose the display
  * Cropping of layers from any input size and location
  * Multiple input pixel formats:
    ? Predefined ARGB, with 7 formats: ARGB8888, ABGR8888, RGBA8888,
    BGRA8888, RGB565, BGR565, RGB888packed.
    ? Flexible ARGB, allowing any width and location for A,R,G,B
    components.
    ? Predefined YUV, with 3 formats: YUV422-1L (FourCC: YUYV,
    Interleaved), YUV420-2L (FourCC: NV12, semi planar), YUV420-3L
    (FourCC: Yxx, full planar) with some flexibility on the sequence of
    the component.
  * Color look-up table (CLUT) up to 256 colors (256x24 bits) per layer
  * Color transparency keying
  * Composition with flexible window position and size versus output
  display
  * Blending with flexible layer order and alpha value (per pixel or
  constant)
  * Background underlying color
  * Gamma with non-linear configurable table
  * Dithering for output with less bits per component (pseudo-random on
  2 bits)
  * Polarity inversion for HSync, VSync, and DataEnable outputs
  * Output as RGB888 24 bpp or YUV422 16 bpp
  * Secure layer (using Layer2) capability, with grouped regs and
  additional interrupt set
  * Interrupts based on 7 different events
  * AXI master interface with long efficient bursts (64 or 128 bytes)

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp135.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp135.dtsi b/arch/arm/boot/dts/st/stm32mp135.dtsi
index 68d32f9f5314..834a4d545fe4 100644
--- a/arch/arm/boot/dts/st/stm32mp135.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp135.dtsi
@@ -19,5 +19,16 @@ dcmipp: dcmipp at 5a000000 {
 			port {
 			};
 		};
+
+		ltdc: display-controller at 5a001000 {
+			compatible = "st,stm32-ltdc";
+			reg = <0x5a001000 0x400>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&rcc LTDC_PX>;
+			clock-names = "lcd";
+			resets = <&scmi_reset RST_SCMI_LTDC>;
+			status = "disabled";
+		};
 	};
 };

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Mon Feb  5 01:06:54 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Mon, 5 Feb 2024 10:06:54 +0100
Subject: [PATCH 4/5] drm/panel: simple: fix flags on RK043FN48H
In-Reply-To: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
Message-ID: <20240205-ltdc_mp13-v1-4-072d24bf1b36@foss.st.com>

DISPLAY_FLAGS_SYNC_POSEDGE is missing in the flags on the default
timings. When overriding the default mode with one described in the
device tree, the mode does not get acked because of this missing flag.
Moreover since the panel is driven by the positive edge it makes sense
to add it here.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
 drivers/gpu/drm/panel/panel-simple.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 2214cb09678c..7b286382ffb4 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -3523,7 +3523,8 @@ static const struct display_timing rocktech_rk043fn48h_timing = {
 	.vfront_porch = { 1, 4, 4 },
 	.vsync_len = { 1, 10, 10 },
 	.flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW |
-		 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE,
+		 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
+		 DISPLAY_FLAGS_SYNC_POSEDGE,
 };
 
 static const struct panel_desc rocktech_rk043fn48h = {

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Mon Feb  5 01:06:50 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Mon, 5 Feb 2024 10:06:50 +0100
Subject: [PATCH 0/5] Add display support for stm32mp135f-dk board
Message-ID: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>

This serie aims to enable display support for the stm32mp135f-dk board

Those are only patches of the device-tree since the driver support has
already been added [1].

It respectivelly:
	- adds support for the display controller on stm32mp135
	- adds pinctrl for the display controller
	- enables panel, backlight and display controller on
	  stm32mp135f-dk

Finally it fixes the flags on the panel default mode in the
'panel-simple' driver, allowing to override the default mode by one
described in the device tree, and push further the blanking limit on the
panel.

[1] commit 1726cee3d053 ("drm/stm: ltdc: support of new hardware version")

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Raphael Gallais-Pou (5):
      ARM: dts: stm32: add LTDC support for STM32MP13x SoC family
      ARM: dts: stm32: add LTDC pinctrl on STM32MP13x SoC family
      ARM: dts: stm32: enable display support on stm32mp135f-dk board
      drm/panel: simple: fix flags on RK043FN48H
      drm/panel: simple: push blanking limit on RK32FN48H

 arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 57 +++++++++++++++++++++++++++++
 arch/arm/boot/dts/st/stm32mp135.dtsi        | 11 ++++++
 arch/arm/boot/dts/st/stm32mp135f-dk.dts     | 55 ++++++++++++++++++++++++++++
 drivers/gpu/drm/panel/panel-simple.c        |  7 ++--
 4 files changed, 127 insertions(+), 3 deletions(-)
---
base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
change-id: 20240124-ltdc_mp13-2f86a782424c

Best regards,
-- 
Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>



From danishanwar at ti.com  Mon Feb  5 01:05:43 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 5 Feb 2024 14:35:43 +0530
Subject: [PATCH v4 0/3] Add AM64x ICSSG Ethernet support
Message-ID: <20240205090546.4000446-1-danishanwar@ti.com>

Hi All,

This series adds support for ICSSG ethernet on AM64x. 
This series is based on the latest next-20240205 linux-next.

AM64x EVM has three ethernet ports. One is dedicated to CPSW and one is
dedicated to ICSSG1. The remaining port is muxed between CPSW and ICSSG1
ICSSG1 ports. The ICSSG1 node is added in the k3-am642-evm.dts. By default
the muxed port is used by CPSW so 2nd ICSSG1 port is disabled in the
k3-am642-evm.dts. But overlay k3-am642-evm-icssg1-dualemac.dtso can be
applied to use muxed port as ICSSG1.

This is the v4 of the series [v1].

Changes from v3 to v4:
*) Dropped ethernet3 alias from k3-am642-evm.dts as suggested by Roger.
*) Dropped extra blank lines from k3-am642-evm.dts.
*) Updated commit message of patch 3/3
*) Updated licensing header in k3-am642-evm-icssg1-dualemac.dtso.
*) Fixed up alias for ethernet1 to icssg1_emac1 in
   k3-am642-evm-icssg1-dualemac.dtso as suggested by Roger.
*) Renamed 'mdio-mux-1' and 'mdio-mux-2' to 'mdio-mux at 1' and 'mdio-mux at 0'
   respectively as suggested by Roger.

Changes from v2 to v3:
*) No functional changes.
*) Rebased on latest linux-next (next-20240122) after 6.8-rc1.

Changes from v1 to v2:
*) Fixed aliases section in k3-am642-evm.dts
*) Fixed firmware-names in k3-am642-evm.dts
*) Changed icssg1_phy1 to ethernet-phy at f from ethernet-phy at 0 as suggested
   by Andrew L.
*) Changed makefile to handle overlays using CONFIG_OF_ALL_DTBS as
   suggested by Nishant and Andrew Davis.
*) Fixed aliases section in k3-am642-evm-icssg1-dualemac.dtso
*) Fixed pinctrl in k3-am642-evm-icssg1-dualemac.dtso
*) Updated commit message of patch 3/3 of the series to warn about adding
   label name to 'mdio-mux-1' node.

[v1] https://lore.kernel.org/all/20231207081917.340167-1-danishanwar at ti.com/
[v2] https://lore.kernel.org/all/20231212165832.3933335-1-danishanwar at ti.com/
[v3] https://lore.kernel.org/all/20240122113045.1711818-1-danishanwar at ti.com/

Thanks and Regards,
MD Danish Anwar

MD Danish Anwar (2):
  arm64: dts: ti: k3-am642-evm: add ICSSG1 Ethernet support
  arm64: dts: ti: k3-am642-evm: add overlay for icssg1 2nd port

Suman Anna (1):
  arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes

 arch/arm64/boot/dts/ti/Makefile               |  5 +
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi      | 24 +++++
 .../dts/ti/k3-am642-evm-icssg1-dualemac.dtso  | 79 +++++++++++++++
 arch/arm64/boot/dts/ti/k3-am642-evm.dts       | 99 ++++++++++++++++++-
 4 files changed, 206 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso

base-commit: 23e11d0318521e8693459b0e4d23aec614b3b68b
-- 
2.34.1



From peng.fan at nxp.com  Mon Feb  5 01:11:33 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 5 Feb 2024 09:11:33 +0000
Subject: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <CACRpkdYCrbNB8wu4rO3Yx0qomxR3kTt0P7YH7kc2HPCbrgt=tg@mail.gmail.com>
References: <20240121-pinctrl-scmi-v3-0-8d94ba79dca8@nxp.com>
 <f88d07ef-83b2-4d14-976a-6dbbd71e036f@oss.nxp.com>
 <CACRpkdYV=qYQ9qDUWYTLDAV1niay30gYH5S=zjfi31GpeY5o-A@mail.gmail.com>
 <DU0PR04MB9417A9074C5DC49AE689E65288432@DU0PR04MB9417.eurprd04.prod.outlook.com>
 <Zbt-QkWhz5d9P-v6@pluto>
 <DU0PR04MB9417CA6CF089B264112C32A088402@DU0PR04MB9417.eurprd04.prod.outlook.com>
 <CACRpkdYCrbNB8wu4rO3Yx0qomxR3kTt0P7YH7kc2HPCbrgt=tg@mail.gmail.com>
Message-ID: <DU0PR04MB9417335A3A41BE4E373B915188472@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
> protocol basic support
>
> On Sun, Feb 4, 2024 at 10:29?AM Peng Fan <peng.fan at nxp.com> wrote:
>
> > Using generic pinconf means the firmware needs exporting
> > groups/functions/pins and etc, the firmware design will be complicated and
> code size enlarged.
>
> This is very much to the core of the problem isn't it?

Yes. Code size should be as small as possible.

And using SCMI generic pinconf, there will be multiple
SCMI calls(not MMIO access), such as setting mux(ops->set_mux)
needs an SCMI call, pad settings(ops->pin_config_set) needs an SCMI call.
And maybe ops->get_function_name  needs an extra SCMI call.

With current i.MX design, only one SCMI call is used, which
use less time.

>
> So the argument is to save code effort and size in the firmware.
>
> This reflects some of the reasoning behind the device tree bindings that
> encode "magic numbers" in the DT nodes to mux and configure pins. Often
> the argument is that it saves space and effort.
>
> When the i.MX driver was first discussed it used the standard scheme actually.
> Look at i.MX 53 for example:
> https://lore.ke/
> rnel.org%2Flinux-kernel%2F1322999384-7886-2-git-send-email-
> b29396%40freescale.com%2F&data=05%7C02%7Cpeng.fan%40nxp.com%7C
> db0604b1366346a0da1108dc25b3607d%7C686ea1d3bc2b4c6fa92cd99c5c3
> 01635%7C0%7C0%7C638426699551848076%7CUnknown%7CTWFpbGZsb3
> d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0
> %3D%7C0%7C%7C%7C&sdata=j%2FA%2BagoL2EXUzDSkg1wtSENPkuxb0YL1
> nTTB7xCIBTE%3D&reserved=0
>
> Groups and functions! As strings!
>
> Then the DT bindings were discussed back and forth between Dong Aisheng
> (the original driver author), Sasha Hauer and Shawn Guo before arriving at
> the fsl,pins scheme.
>
> Back in the day I was pretty much clueless about device tree and relied on
> others to review the bindings, which ended up like this:
> Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
>
> This was in 2011/2012 so many things were not considered. It is clear that
> this scheme with a number of integers that get poked into registers is
> convenient for some DT authors, also pinctrl-single uses this as well as I think
> Mediatek and maybe a few others.
>
> Over the years I have come to regret it a bit, I think insisting on groups and
> functions as strings is better for abstraction. And the point of firmware is to
> abstract things so they work the same on all systems.

With current:
        pinctrl_uart1: uart1grp {
                fsl,pins = <
                        IMX95_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX      0x31e
                        IMX95_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX      0x31e
                >;
        };

It is very easy for people to know the meaning from reading reference manual.

If using generic pinconf, the dt node will be like
Uartgrp {
        pins = "uart1txd", "uart1rxd";
        functions = "uart1";
        bias-xx
        drive-strength =
};

The firmware needs add more code to export functions, pack the conf settings,
each pins needs a function name per current i.MX HW logic.

And as I said above, more SCMI calls needed for configure a pin.

So it is not a good fit for i.MX platform using SCP processor to use generic
pinconf for SCMI as I think.

Thanks,
Peng.

>
> Yours,
> Linus Walleij

From jbrunet at baylibre.com  Mon Feb  5 01:13:28 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 05 Feb 2024 10:13:28 +0100
Subject: [PATCH] clk: meson: Add missing clocks to axg_clk_regmaps
In-Reply-To: <20240202172537.1.I64656c75d84284bc91e6126b50b33c502be7c42a@changeid>
References: <20240202172537.1.I64656c75d84284bc91e6126b50b33c502be7c42a@changeid>
Message-ID: <170712440863.617794.2380345437565943814.b4-ty@baylibre.com>

Applied to clk-meson (v6.9/drivers), thanks!

[1/1] clk: meson: Add missing clocks to axg_clk_regmaps
      https://github.com/BayLibre/clk-meson/commit/ba535bce57e7

Best regards,
--
Jerome



From arnaud.pouliquen at foss.st.com  Mon Feb  5 01:13:43 2024
From: arnaud.pouliquen at foss.st.com (Arnaud POULIQUEN)
Date: Mon, 5 Feb 2024 10:13:43 +0100
Subject: [PATCH v2 4/4] remoteproc: stm32: Add support of an OP-TEE TA to
 load the firmware
In-Reply-To: <Zb1IPlnbMp9Utu2y@p14s>
References: <20240118100433.3984196-1-arnaud.pouliquen@foss.st.com>
 <20240118100433.3984196-5-arnaud.pouliquen@foss.st.com>
 <ZbPnsJm67G10+HQ3@p14s> <7ec6c9e8-9267-4e7c-81a4-abcdb2ab4239@foss.st.com>
 <ZbqW5YfDmEWG4G1X@p14s> <8ede77bb-0fbc-4de2-b51b-67674744b551@foss.st.com>
 <ZbvAmxHscnbUQGOD@p14s> <a52e00c5-fb60-4a9e-85ff-0f9649850f48@foss.st.com>
 <Zb1IPlnbMp9Utu2y@p14s>
Message-ID: <36c0368b-94f3-40bd-9273-33ab2c9bf913@foss.st.com>



On 2/2/24 20:53, Mathieu Poirier wrote:
> On Thu, Feb 01, 2024 at 07:33:35PM +0100, Arnaud POULIQUEN wrote:
>>
>>
>> On 2/1/24 17:02, Mathieu Poirier wrote:
>>> On Thu, Feb 01, 2024 at 04:06:37PM +0100, Arnaud POULIQUEN wrote:
>>>> hello Mathieu,
>>>>
>>>> On 1/31/24 19:52, Mathieu Poirier wrote:
>>>>> On Tue, Jan 30, 2024 at 10:13:48AM +0100, Arnaud POULIQUEN wrote:
>>>>>>
>>>>>>
>>>>>> On 1/26/24 18:11, Mathieu Poirier wrote:
>>>>>>> On Thu, Jan 18, 2024 at 11:04:33AM +0100, Arnaud Pouliquen wrote:
>>>>>>>> The new TEE remoteproc device is used to manage remote firmware in a
>>>>>>>> secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
>>>>>>>> introduced to delegate the loading of the firmware to the trusted
>>>>>>>> execution context. In such cases, the firmware should be signed and
>>>>>>>> adhere to the image format defined by the TEE.
>>>>>>>>
>>>>>>>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
>>>>>>>> ---
>>>>>>>> V1 to V2 update:
>>>>>>>> - remove the select "TEE_REMOTEPROC" in STM32_RPROC config as detected by
>>>>>>>>   the kernel test robot:
>>>>>>>>      WARNING: unmet direct dependencies detected for TEE_REMOTEPROC
>>>>>>>>      Depends on [n]: REMOTEPROC [=y] && OPTEE [=n]
>>>>>>>>      Selected by [y]:
>>>>>>>>      - STM32_RPROC [=y] && (ARCH_STM32 || COMPILE_TEST [=y]) && REMOTEPROC [=y]
>>>>>>>> - Fix initialized trproc variable in  stm32_rproc_probe
>>>>>>>> ---
>>>>>>>>  drivers/remoteproc/stm32_rproc.c | 149 +++++++++++++++++++++++++++++--
>>>>>>>>  1 file changed, 144 insertions(+), 5 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
>>>>>>>> index fcc0001e2657..cf6a21bac945 100644
>>>>>>>> --- a/drivers/remoteproc/stm32_rproc.c
>>>>>>>> +++ b/drivers/remoteproc/stm32_rproc.c
>>>>>>>> @@ -20,6 +20,7 @@
>>>>>>>>  #include <linux/remoteproc.h>
>>>>>>>>  #include <linux/reset.h>
>>>>>>>>  #include <linux/slab.h>
>>>>>>>> +#include <linux/tee_remoteproc.h>
>>>>>>>>  #include <linux/workqueue.h>
>>>>>>>>  
>>>>>>>>  #include "remoteproc_internal.h"
>>>>>>>> @@ -49,6 +50,9 @@
>>>>>>>>  #define M4_STATE_STANDBY	4
>>>>>>>>  #define M4_STATE_CRASH		5
>>>>>>>>  
>>>>>>>> +/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
>>>>>>>> +#define STM32_MP1_M4_PROC_ID    0
>>>>>>>> +
>>>>>>>>  struct stm32_syscon {
>>>>>>>>  	struct regmap *map;
>>>>>>>>  	u32 reg;
>>>>>>>> @@ -90,6 +94,8 @@ struct stm32_rproc {
>>>>>>>>  	struct stm32_mbox mb[MBOX_NB_MBX];
>>>>>>>>  	struct workqueue_struct *workqueue;
>>>>>>>>  	bool hold_boot_smc;
>>>>>>>> +	bool fw_loaded;
>>>>>>>> +	struct tee_rproc *trproc;
>>>>>>>>  	void __iomem *rsc_va;
>>>>>>>>  };
>>>>>>>>  
>>>>>>>> @@ -257,6 +263,91 @@ static int stm32_rproc_release(struct rproc *rproc)
>>>>>>>>  	return err;
>>>>>>>>  }
>>>>>>>>  
>>>>>>>> +static int stm32_rproc_tee_elf_sanity_check(struct rproc *rproc,
>>>>>>>> +					    const struct firmware *fw)
>>>>>>>> +{
>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>> +	unsigned int ret = 0;
>>>>>>>> +
>>>>>>>> +	if (rproc->state == RPROC_DETACHED)
>>>>>>>> +		return 0;
>>>>>>>> +
>>>>>>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
>>>>>>>> +	if (!ret)
>>>>>>>> +		ddata->fw_loaded = true;
>>>>>>>> +
>>>>>>>> +	return ret;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static int stm32_rproc_tee_elf_load(struct rproc *rproc,
>>>>>>>> +				    const struct firmware *fw)
>>>>>>>> +{
>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>> +	unsigned int ret;
>>>>>>>> +
>>>>>>>> +	/*
>>>>>>>> +	 * This function can be called by remote proc for recovery
>>>>>>>> +	 * without the sanity check. In this case we need to load the firmware
>>>>>>>> +	 * else nothing done here as the firmware has been preloaded for the
>>>>>>>> +	 * sanity check to be able to parse it for the resource table.
>>>>>>>> +	 */
>>>>>>>
>>>>>>> This comment is very confusing - please consider refactoring.  
>>>>>>>
>>>>>>>> +	if (ddata->fw_loaded)
>>>>>>>> +		return 0;
>>>>>>>> +
>>>>>>>
>>>>>>> I'm not sure about keeping a flag to indicate the status of the loaded firmware.
>>>>>>> It is not done for the non-secure method, I don't see why it would be needed for
>>>>>>> the secure one.
>>>>>>>
>>>>>>
>>>>>> The difference is on the sanity check.
>>>>>> - in rproc_elf_sanity_check we  parse the elf file to verify that it is
>>>>>> valid.
>>>>>> - in stm32_rproc_tee_elf_sanity_check we have to do the same, that means to
>>>>>> authenticate it. the authentication is done during the load.
>>>>>>
>>>>>> So this flag is used to avoid to reload it twice time.
>>>>>> refactoring the comment should help to understand this flag
>>>>>>
>>>>>>
>>>>>> An alternative would be to bypass the sanity check. But this lead to same
>>>>>> limitation.
>>>>>> Before loading the firmware in remoteproc_core, we call rproc_parse_fw() that is
>>>>>> used to get the resource table address. To get it from tee we need to
>>>>>> authenticate the firmware so load it...
>>>>>>
>>>>>
>>>>> I spent a long time thinking about this patchset.  Looking at the code as it
>>>>> is now, request_firmware() in rproc_boot() is called even when the TEE is
>>>>> responsible for loading the firmware.  There should be some conditional code
>>>>> that calls either request_firmware() or tee_rproc_load_fw().  The latter should
>>>>> also be renamed to tee_rproc_request_firmware() to avoid confusion.
>>>>
>>>>
>>>> The request_firmware() call is needed in both cases to get the image from the
>>>> filesystem. The tee_rproc_load_fw() gets, as input, the struct firmware provided
>>>> by request_firmware().
>>>
>>> The cover letter clearly state the secure side is responsible for loading the
>>> firmware image but here you're telling me it has to be loaded twice.  This is
>>> very confusing.
>>
>> Concerning the call of request_firmware()
>>
>> By "both cases" I would say that the call of request_firmware() is needed in
>> both modes:
>> - the ELF firmware is parsed and loaded by linux (legacy)
>> - the binary firmware is parsed and loaded by OP-TEE.
>>
>> The Op-TEE is not able to get the firmware image from the file system.
>>
>>
>> Concerning the call of tee_rproc_load_fw twice time
>>
>> There are 2 use cases:
>>
>> - First boot of the remote processor:
>>
>>   1) The Linux rproc gets the binary firmware image from the file system by
>>      calling  request_firmware(). A copy is stored in memory.
> 
> Right.  And I think tee_rproc_load_fw() should be called right after
> request_firmware() if rproc::tee_rproc_interface is valid.  At that point the TEE
> app may or may not do the firmware authentication, that is application specific.
> 
>>   2) the linux performs a sanity check on the firmware calling
>>      rproc_fw_sanity_check()
>> 	=> from OP-TEE point of view this means to autenticate the firmware
>> 	=> let consider in this exemple that we bypass this step
>>            (ops->sanity_check = NULL)
> 
> Ok
> 
>> 		
>>   3) the linux rproc call rproc_parse_fw() to get the resource table
>> 	=> From OP-TEE point of view the resource table is available only when
>>            the firmware is loaded
> 
> Right, and it should have been loaded already.  If it is not then the TEE should
> return an error.
> 
>> 	=> We need to call tee_rproc_load_fw() to be able then to get the
>>            address of the resource table.
> 
> See my comment above - at this point the TEE should already have the firmware.
> As such the only thing left is to get the address of the resource table, which
> you already do in rproc_tee_get_rsc_table().  The upper part of that function
> should be spun off in a new static function to deal with the TEE API, something
> like _rproc_tee_get_rsc_table().  The new function should also be called in
> tee_rproc_get_loaded_rsc_table() rather than keeping a cache value in
> trproc->rsc_va.
> 
>>   4) The Linux rproc calls rproc_handle_resources() to parse the resource table.
>>   5) The linux rproc calls rproc_start()
>> 	- load the firrmware calling rproc_load_segments()
>> 		=> we don't want to call tee_rproc_load_fw() it a second time
> 
> And that is fine if the TEE app has already placed the program segments in
> memory.
> 
>> 	- start the firmware calling ops->start()
>>
>> - Reboot on crash recovery using rproc_boot_recovery()
>>
>>   1)  The Linux rproc gets the binary firmware image from the file system by
>>      calling request_firmware(). A copy is stored in memory.
>>   5) The linux rproc calls rproc_start()
>> 	- load the firrmware calling rproc_load_segments()
>> 		=> we have to call tee_rproc_load_fw() to reload the firmware
> 
> Loading the firmware in the TEE should be done right after request_firmware()
> has been called, the same way it is done in the boot path.  If there isn't a
> need to reload the TEE firmware than the TEE application should ignore the
> request.

I need to prototype to verify this proposal.
I will come back with a V3.

Thank you for the advice and review!

Regard,
Arnaud

> 
>> 	- start the firmware calling ops->start()
>>
>> In first use case we have to load the firmware on rproc_parse_fw(), in second
>> usecase on rproc_load_segments().
>>
>> This is the point I have tried to solve with the ddata->fw_loaded variable.
>>
>>>
>>> I'm also confused as to why stm32_rproc_tee_elf_sanity_check() is calling
>>> tee_rproc_load_fw().  There should be one call to load the firmware and another
>>> to perform a sanity check on it.  If the sanity check is done at load time by
>>> the secure world then ops::sanity_check() is NULL.
>>
>> Sure, make sense to remove the sanity_check ops
>>
>> Thanks,
>> Arnaud
>>
>>>
>>> Most of what this patchset does makes sense, but some of it needs to be moved
>>> around.  
>>>
>>> Thanks,
>>> Mathieu
>>>
>>>>
>>>> If we want to integrate in remoteproc_core the solution could probably have to
>>>> create the equivalent of the rproc_fw_boot() to load the firmware with an
>>>> external method. Here is an example based on a new rproc_ops ( not tested)
>>>>
>>>> + static int rproc_fw_ext_boot(struct rproc *rproc, const struct firmware *fw)
>>>> + {
>>>> + 	struct device *dev = &rproc->dev;
>>>> + 	const char *name = rproc->firmware;
>>>> + 	int ret;
>>>> +
>>>> +
>>>> + 	dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size);
>>>> + 	
>>>> + 	/* ops to load and start the remoteprocessor */
>>>> + 	ret = rproc->ops->boot(rproc, fw);
>>>> + 	if (ret)
>>>> + 		return ret;
>>>> +
>>>> + 	/*
>>>> + 	 * if enabling an IOMMU isn't relevant for this rproc, this is
>>>> + 	 * just a nop
>>>> + 	 */
>>>> + 	ret = rproc_enable_iommu(rproc);
>>>> + 	if (ret) {
>>>> + 		dev_err(dev, "can't enable iommu: %d\n", ret);
>>>> + 		return ret;
>>>> + 	}
>>>> +
>>>> + 	/* Prepare rproc for firmware loading if needed */
>>>> + 	ret = rproc_prepare_device(rproc);
>>>> + 	if (ret) {
>>>> + 		dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
>>>> + 		goto disable_iommu;
>>>> + 	}
>>>> +
>>>> + 	ret = rproc_set_rsc_table(rproc);
>>>> + 	if (ret) {
>>>> + 		dev_err(dev, "can't load resource table: %d\n", ret);
>>>> + 		goto unprepare_device;
>>>> + 	}
>>>> +
>>>> +
>>>> + 	/* reset max_notifyid */
>>>> + 	rproc->max_notifyid = -1;
>>>> +
>>>> + 	/* reset handled vdev */
>>>> + 	rproc->nb_vdev = 0;
>>>> +
>>>> + 	/* handle fw resources which are required to boot rproc */
>>>> + 	ret = rproc_handle_resources(rproc, rproc_loading_handlers);
>>>> + 	if (ret) {
>>>> + 		dev_err(dev, "Failed to process resources: %d\n", ret);
>>>> + 		goto clean_up_resources;
>>>> + 	}
>>>> +
>>>> + 	/* Allocate carveout resources associated to rproc */
>>>> + 	ret = rproc_alloc_registered_carveouts(rproc);
>>>> + 	if (ret) {
>>>> + 		dev_err(dev, "Failed to allocate associated carveouts: %d\n",
>>>> + 			ret);
>>>> + 		goto clean_up_resources;
>>>> + 	}
>>>> +
>>>> + 	return 0;
>>>> +
>>>> + clean_up_resources:
>>>> + 	rproc_resource_cleanup(rproc);
>>>> + unprepare_rproc:
>>>> + 	/* release HW resources if needed */
>>>> + 	rproc_unprepare_device(rproc);
>>>> + disable_iommu:
>>>> + 	rproc_disable_iommu(rproc);
>>>> + 	return ret;
>>>> + }
>>>>
>>>>
>>>> int rproc_boot(struct rproc *rproc)
>>>> {
>>>> [...]
>>>>
>>>> - 		ret = rproc_fw_boot(rproc, firmware_p);
>>>> + 		if(rproc->ops->boot)
>>>> + 			ret = rproc_fw_ext_boot(rproc, firmware_p);
>>>> + 		else
>>>> + 			ret = rproc_fw_boot(rproc, firmware_p);
>>>>
>>>> Another advantage of this solution is that it opens the framework to other
>>>> formats. For instance it could be a way to support dtb format requested in [RFC]
>>>> Passing device-tree to remoteproc [1].
>>>>
>>>> [1]
>>>> https://lore.kernel.org/linux-remoteproc/f67cd822-4e29-71f2-7c42-e11dbaa6cd8c at kalrayinc.com/T/#t
>>>>
>>>> Thanks,
>>>> Arnaud
>>>>
>>>>
>>>>
>>>>>
>>>>> I touched on that before but please rename rproc_tee_get_rsc_table() to
>>>>> rproc_tee_elf_load_rsc_table().  I also suggest to introduce a new function,
>>>>> rproc_tee_get_loaded_rsc_table() that would be called from
>>>>> rproc_tee_elf_load_rsc_table().  That way we don't need trproc->rsc_va.  
>>>>>
>>>>> I also think tee_rproc should be renamed to "rproc_tee_interface" and folded
>>>>> under struct rproc.  
>>>>>
>>>>> With the above most of the problems with the current implementation should
>>>>> naturally go away.
>>>>>
>>>>> Thanks,
>>>>> Mathieu
>>>>>
>>>>>>
>>>>>>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
>>>>>>>> +	if (ret)
>>>>>>>> +		return ret;
>>>>>>>> +	ddata->fw_loaded = true;
>>>>>>>> +
>>>>>>>> +	/* Update the resource table parameters. */
>>>>>>>> +	if (rproc_tee_get_rsc_table(ddata->trproc)) {
>>>>>>>> +		/* No resource table: reset the related fields. */
>>>>>>>> +		rproc->cached_table = NULL;
>>>>>>>> +		rproc->table_ptr = NULL;
>>>>>>>> +		rproc->table_sz = 0;
>>>>>>>> +	}
>>>>>>>> +
>>>>>>>> +	return 0;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static struct resource_table *
>>>>>>>> +stm32_rproc_tee_elf_find_loaded_rsc_table(struct rproc *rproc,
>>>>>>>> +					  const struct firmware *fw)
>>>>>>>> +{
>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>> +
>>>>>>>> +	return tee_rproc_get_loaded_rsc_table(ddata->trproc);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static int stm32_rproc_tee_start(struct rproc *rproc)
>>>>>>>> +{
>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>> +
>>>>>>>> +	return tee_rproc_start(ddata->trproc);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static int stm32_rproc_tee_attach(struct rproc *rproc)
>>>>>>>> +{
>>>>>>>> +	/* Nothing to do, remote proc already started by the secured context. */
>>>>>>>> +	return 0;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static int stm32_rproc_tee_stop(struct rproc *rproc)
>>>>>>>> +{
>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>> +	int err;
>>>>>>>> +
>>>>>>>> +	stm32_rproc_request_shutdown(rproc);
>>>>>>>> +
>>>>>>>> +	err = tee_rproc_stop(ddata->trproc);
>>>>>>>> +	if (err)
>>>>>>>> +		return err;
>>>>>>>> +
>>>>>>>> +	ddata->fw_loaded = false;
>>>>>>>> +
>>>>>>>> +	return stm32_rproc_release(rproc);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>  static int stm32_rproc_prepare(struct rproc *rproc)
>>>>>>>>  {
>>>>>>>>  	struct device *dev = rproc->dev.parent;
>>>>>>>> @@ -319,7 +410,14 @@ static int stm32_rproc_prepare(struct rproc *rproc)
>>>>>>>>  
>>>>>>>>  static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
>>>>>>>>  {
>>>>>>>> -	if (rproc_elf_load_rsc_table(rproc, fw))
>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>> +	int ret;
>>>>>>>> +
>>>>>>>> +	if (ddata->trproc)
>>>>>>>> +		ret = rproc_tee_get_rsc_table(ddata->trproc);
>>>>>>>> +	else
>>>>>>>> +		ret = rproc_elf_load_rsc_table(rproc, fw);
>>>>>>>> +	if (ret)
>>>>>>>>  		dev_warn(&rproc->dev, "no resource table found for this firmware\n");
>>>>>>>>  
>>>>>>>>  	return 0;
>>>>>>>> @@ -693,8 +791,22 @@ static const struct rproc_ops st_rproc_ops = {
>>>>>>>>  	.get_boot_addr	= rproc_elf_get_boot_addr,
>>>>>>>>  };
>>>>>>>>  
>>>>>>>> +static const struct rproc_ops st_rproc_tee_ops = {
>>>>>>>> +	.prepare	= stm32_rproc_prepare,
>>>>>>>> +	.start		= stm32_rproc_tee_start,
>>>>>>>> +	.stop		= stm32_rproc_tee_stop,
>>>>>>>> +	.attach		= stm32_rproc_tee_attach,
>>>>>>>> +	.kick		= stm32_rproc_kick,
>>>>>>>> +	.parse_fw	= stm32_rproc_parse_fw,
>>>>>>>> +	.find_loaded_rsc_table = stm32_rproc_tee_elf_find_loaded_rsc_table,
>>>>>>>> +	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
>>>>>>>> +	.sanity_check	= stm32_rproc_tee_elf_sanity_check,
>>>>>>>> +	.load		= stm32_rproc_tee_elf_load,
>>>>>>>> +};
>>>>>>>> +
>>>>>>>>  static const struct of_device_id stm32_rproc_match[] = {
>>>>>>>> -	{ .compatible = "st,stm32mp1-m4" },
>>>>>>>> +	{.compatible = "st,stm32mp1-m4",},
>>>>>>>> +	{.compatible = "st,stm32mp1-m4-tee",},
>>>>>>>>  	{},
>>>>>>>>  };
>>>>>>>>  MODULE_DEVICE_TABLE(of, stm32_rproc_match);
>>>>>>>> @@ -853,6 +965,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>>>>>  	struct device *dev = &pdev->dev;
>>>>>>>>  	struct stm32_rproc *ddata;
>>>>>>>>  	struct device_node *np = dev->of_node;
>>>>>>>> +	struct tee_rproc *trproc = NULL;
>>>>>>>>  	struct rproc *rproc;
>>>>>>>>  	unsigned int state;
>>>>>>>>  	int ret;
>>>>>>>> @@ -861,11 +974,31 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>>>>>  	if (ret)
>>>>>>>>  		return ret;
>>>>>>>>  
>>>>>>>> -	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
>>>>>>>> -	if (!rproc)
>>>>>>>> -		return -ENOMEM;
>>>>>>>> +	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
>>>>>>>> +		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
>>>>>>>> +		if (IS_ERR(trproc)) {
>>>>>>>> +			dev_err_probe(dev, PTR_ERR(trproc),
>>>>>>>> +				      "signed firmware not supported by TEE\n");
>>>>>>>> +			return PTR_ERR(trproc);
>>>>>>>> +		}
>>>>>>>> +		/*
>>>>>>>> +		 * Delegate the firmware management to the secure context.
>>>>>>>> +		 * The firmware loaded has to be signed.
>>>>>>>> +		 */
>>>>>>>> +		dev_info(dev, "Support of signed firmware only\n");
>>>>>>>
>>>>>>> Not sure what this adds.  Please remove.
>>>>>>
>>>>>> This is used to inform the user that only a signed firmware can be loaded, not
>>>>>> an ELF file.
>>>>>> I have a patch in my pipe to provide the supported format in the debugfs. In a
>>>>>> first step, I can suppress this message and we can revisit the issue when I push
>>>>>> the debugfs proposal.
>>>>>>
>>>>>> Thanks,
>>>>>> Arnaud
>>>>>>
>>>>>>>
>>>>>>>> +	}
>>>>>>>> +	rproc = rproc_alloc(dev, np->name,
>>>>>>>> +			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
>>>>>>>> +			    NULL, sizeof(*ddata));
>>>>>>>> +	if (!rproc) {
>>>>>>>> +		ret = -ENOMEM;
>>>>>>>> +		goto free_tee;
>>>>>>>> +	}
>>>>>>>>  
>>>>>>>>  	ddata = rproc->priv;
>>>>>>>> +	ddata->trproc = trproc;
>>>>>>>> +	if (trproc)
>>>>>>>> +		trproc->rproc = rproc;
>>>>>>>>  
>>>>>>>>  	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
>>>>>>>>  
>>>>>>>> @@ -916,6 +1049,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>>>>>  		device_init_wakeup(dev, false);
>>>>>>>>  	}
>>>>>>>>  	rproc_free(rproc);
>>>>>>>> +free_tee:
>>>>>>>> +	if (trproc)
>>>>>>>> +		tee_rproc_unregister(trproc);
>>>>>>>> +
>>>>>>>>  	return ret;
>>>>>>>>  }
>>>>>>>>  
>>>>>>>> @@ -937,6 +1074,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
>>>>>>>>  		device_init_wakeup(dev, false);
>>>>>>>>  	}
>>>>>>>>  	rproc_free(rproc);
>>>>>>>> +	if (ddata->trproc)
>>>>>>>> +		tee_rproc_unregister(ddata->trproc);
>>>>>>>>  }
>>>>>>>>  
>>>>>>>>  static int stm32_rproc_suspend(struct device *dev)
>>>>>>>> -- 
>>>>>>>> 2.25.1
>>>>>>>>


From shawn.gsc at gmail.com  Mon Feb  5 01:16:17 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 17:16:17 +0800
Subject: [PATCH 1/1] arm64: dts: tqma8mpql: fix audio codec iov-supply
In-Reply-To: <20240110090849.463270-1-alexander.stein@ew.tq-group.com>
References: <20240110090849.463270-1-alexander.stein@ew.tq-group.com>
Message-ID: <ZcCnYd6mLr3uH1fF@t480>

On Wed, Jan 10, 2024 at 10:08:49AM +0100, Alexander Stein wrote:
> IOVDD is supplied by 1.8V, fix the referenced regulator.
> 
> Fixes: d8f9d8126582d ("arm64: dts: imx8mp: Add analog audio output on i.MX8MP TQMa8MPxL/MBa8MPxL")
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied, thanks!


From shawn.gsc at gmail.com  Mon Feb  5 01:18:23 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 17:18:23 +0800
Subject: [PATCH 1/1] arm64: dts: imx8mp: reparent MEDIA_MIPI_PHY1_REF to
 CLK_24M
In-Reply-To: <20240110100048.478001-1-alexander.stein@ew.tq-group.com>
References: <20240110100048.478001-1-alexander.stein@ew.tq-group.com>
Message-ID: <ZcCn33sNLofPNVWQ@t480>

On Wed, Jan 10, 2024 at 11:00:48AM +0100, Alexander Stein wrote:
> This is already done in dsi node, introduced in commit eda09fe149df4
> ("arm64: dts: imx8mp: Add display pipeline components").
> This needs to be applied to csi nodes as well or the clock might be busy
> if both csi and dsi nodes are enabled.
> Fixes error:
>  clk: failed to reparent media_mipi_phy1_ref to osc_24m: -16
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied, thanks!


From shawn.gsc at gmail.com  Mon Feb  5 01:19:15 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 17:19:15 +0800
Subject: [PATCH 1/1] arm64: dts: freescale: tqma9352: Update I2C eeprom
 compatible
In-Reply-To: <20240110100526.478771-1-alexander.stein@ew.tq-group.com>
References: <20240110100526.478771-1-alexander.stein@ew.tq-group.com>
Message-ID: <ZcCoE4Ss72hvDf2w@t480>

On Wed, Jan 10, 2024 at 11:05:26AM +0100, Alexander Stein wrote:
> Now that there is a dedicated compatible for the idendification page use
> that instead. This also allows the removal the size and pagesize
> properties.
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied, thanks!


From m.szyprowski at samsung.com  Mon Feb  5 01:19:16 2024
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Mon, 5 Feb 2024 10:19:16 +0100
Subject: [PATCH v4 1/2] clk: Provide managed helper to get and enable
 bulk clocks
In-Reply-To: <08a901da55cf$4ee48000$ecad8000$@samsung.com>
References: <20240124103838.32478-1-shradha.t@samsung.com>
	<CGME20240124103855epcas5p27400bd95df42f36b9547a4e28aa26f5d@epcas5p2.samsung.com>
	<20240124103838.32478-2-shradha.t@samsung.com>
	<20240129065448.GC2971@thinkpad>
	<08a901da55cf$4ee48000$ecad8000$@samsung.com>
Message-ID: <8e336720-ce08-4391-ad36-b83fea246cab@samsung.com>

On 02.02.2024 12:59, Shradha Todi wrote:
>> -----Original Message-----
>> From: Manivannan Sadhasivam<manivannan.sadhasivam at linaro.org>
>> Sent: 29 January 2024 12:25
>> To: Shradha Todi<shradha.t at samsung.com>
>> Subject: Re: [PATCH v4 1/2] clk: Provide managed helper to get and enable bulk
>> clocks
>>
>> On Wed, Jan 24, 2024 at 04:08:37PM +0530, Shradha Todi wrote:
>>> Provide a managed devm_clk_bulk* wrapper to get and enable all bulk
>>> clocks in order to simplify drivers that keeps all clocks enabled for
>>> the time of driver operation.
>>>
>>> Suggested-by: Marek Szyprowski<m.szyprowski at samsung.com>
>>> Signed-off-by: Shradha Todi<shradha.t at samsung.com>
>>> ---
>>>   drivers/clk/clk-devres.c | 40
>> ++++++++++++++++++++++++++++++++++++++++
>>>   include/linux/clk.h      | 24 ++++++++++++++++++++++++
>>>   2 files changed, 64 insertions(+)
>>>
>>> diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c index
>>> 4fb4fd4b06bd..cbbd2cc339c3 100644
>>> --- a/drivers/clk/clk-devres.c
>>> +++ b/drivers/clk/clk-devres.c
>>> @@ -182,6 +182,46 @@ int __must_check devm_clk_bulk_get_all(struct
>>> device *dev,  }  EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all);
>>>
>>> +static void devm_clk_bulk_release_all_enable(struct device *dev, void
>>> +*res) {
>>> +	struct clk_bulk_devres *devres = res;
>>> +
>>> +	clk_bulk_disable_unprepare(devres->num_clks, devres->clks);
>>> +	clk_bulk_put_all(devres->num_clks, devres->clks); }
>>> +
>>> +int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
>>> +					      struct clk_bulk_data **clks) {
>>> +	struct clk_bulk_devres *devres;
>>> +	int ret;
>>> +
>>> +	devres = devres_alloc(devm_clk_bulk_release_all_enable,
>>> +			      sizeof(*devres), GFP_KERNEL);
>>> +	if (!devres)
>>> +		return -ENOMEM;
>>> +
>>> +	ret = clk_bulk_get_all(dev, &devres->clks);
>>> +	if (ret > 0) {
>>> +		*clks = devres->clks;
>>> +		devres->num_clks = ret;
>>> +	} else {
>>> +		devres_free(devres);
>>> +		return ret;
>>> +	}
>> How about:
>>
>> 	ret = clk_bulk_get_all(dev, &devres->clks);
>> 	if (ret <= 0) {
>> 		devres_free(devres);
>> 		return ret;
>> 	}
>>
>> 	*clks = devres->clks;
>> 	devres->num_clks = ret;
>>
>> Even though this patch follows the pattern used by the rest of the APIs in the
>> driver, IMO above makes it more readable.
>>
> Since I have usually seen that maintainers suggest to maintain the coding style of the file, I followed the same.
> If you have a stronger reason to change this, please let me know
> Marek, Michael, Stephen please let us know what do you think about this?

I suggest to keep the same style as is used in the modified file (if it 
doesn't conflict with the rules enforced by checkpatch and kernel's 
coding style).

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From shawn.gsc at gmail.com  Mon Feb  5 01:23:46 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 17:23:46 +0800
Subject: [PATCH] ARM: imx: Remove usage of the deprecated ida_simple_xx()
 API
In-Reply-To: <5807287732785d81b9c3ef9e6a25e4f3bc2e2159.1705005016.git.christophe.jaillet@wanadoo.fr>
References: <5807287732785d81b9c3ef9e6a25e4f3bc2e2159.1705005016.git.christophe.jaillet@wanadoo.fr>
Message-ID: <ZcCpIli/KGRDJi5d@t480>

On Thu, Jan 11, 2024 at 09:31:55PM +0100, Christophe JAILLET wrote:
> ida_alloc() and ida_free() should be preferred to the deprecated
> ida_simple_get() and ida_simple_remove().
> 
> This is less verbose.
> 
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>

Applied, thanks!


From krzysztof.kozlowski at linaro.org  Mon Feb  5 01:25:46 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 10:25:46 +0100
Subject: [PATCH v2 0/4] Add 8qm SMMU information
In-Reply-To: <Zb1sijexWGLG5gcH@lizhi-Precision-Tower-5810>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240202110511.135d26b7@kernel.org>
 <Zb1sijexWGLG5gcH@lizhi-Precision-Tower-5810>
Message-ID: <65097032-74d4-4617-8ef6-e1f76b41cce6@linaro.org>

On 02/02/2024 23:28, Frank Li wrote:
> On Fri, Feb 02, 2024 at 11:05:11AM -0800, Jakub Kicinski wrote:
>> On Thu, 01 Feb 2024 15:22:40 -0500 Frank Li wrote:
>>>       dt-bindings: mmc: fsl-imx-esdhc: add iommus property
>>>       dt-bindings: net: fec: add iommus property
>>>       arm64: dts: imx8qm: add smmu node
>>>       arm64: dts: imx8qm: add smmu stream id information
>>>
>>>  .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml     |  3 ++
>>>  Documentation/devicetree/bindings/net/fsl,fec.yaml |  3 ++
>>>  arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi  |  6 ++++
>>>  arch/arm64/boot/dts/freescale/imx8qm.dtsi          | 41 ++++++++++++++++++++++
>>
>> Any preference on whether all these go via a platform tree,
>> or should we pick up the net patch to netdev? I guess taking
>> the DTB via netdev would be the usual way to handle this?
> 
> Supposed dt-bindings go through netdev tree.
> 
> without dt-bindings, just DTB_CHECK warning. No strict dependence
> relationship between dt-bindings doc and dts file. 

Please make it easier for maintainers and sent entirely independent
patches for different subsystems in SEPARATE patchsets.

There is no dependency here between anything. Combining it, OTOH, brings
the questions about such dependency and makes it a bit more difficult to
apply for each maintainer.

Best regards,
Krzysztof



From shawn.gsc at gmail.com  Mon Feb  5 01:32:14 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 17:32:14 +0800
Subject: [PATCH 1/2] Revert "arm64: dts: imx8mp-dhcom-pdk3: Describe the
 USB-C connector"
In-Reply-To: <20240113224333.2442248-1-festevam@gmail.com>
References: <20240113224333.2442248-1-festevam@gmail.com>
Message-ID: <ZcCrHkZuooPiOk2O@t480>

On Sat, Jan 13, 2024 at 07:43:32PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> This reverts commit a4dca89fe8a1585af73e362f5f4e3189a00abf8e.
> 
> Marek reported:
> 
> "This patch breaks USB-C port on this board.
> 
> If I plug in USB-C storage device, it is not detected. If I revert this
> patch, it is detected.
> 
> Please drop this patch for now."
> 
> Revert it to avoid the regression.
> 
> Reported-by: Marek Vasut <marex at denx.de>
> Closes: https://lore.kernel.org/linux-arm-kernel/623c294a-5c53-4e01-acbf-104acc180e14 at denx.de/T/#u
> Fixes: a4dca89fe8a1 ("arm64: dts: imx8mp-dhcom-pdk3: Describe the USB-C connector")
> Signed-off-by: Fabio Estevam <festevam at denx.de>

Applied both, thanks!


From Markus.Elfring at web.de  Mon Feb  5 01:32:11 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Mon, 5 Feb 2024 10:32:11 +0100
Subject: [PATCH] drm/mediatek: Use devm_platform_get_and_ioremap_resource() in
 mtk_hdmi_ddc_probe()
Message-ID: <2a4ecf78-20e7-4678-a67d-0d66956b07cc@web.de>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Mon, 5 Feb 2024 10:18:47 +0100

A wrapper function is available since the commit 890cc39a879906b63912482dfc41944579df2dc6
("drivers: provide devm_platform_get_and_ioremap_resource()").
Thus reuse existing functionality instead of keeping duplicate source code.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c
index 54e46e440e0f..52d55861f954 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c
@@ -284,8 +284,7 @@ static int mtk_hdmi_ddc_probe(struct platform_device *pdev)
 		return PTR_ERR(ddc->clk);
 	}

-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ddc->regs = devm_ioremap_resource(&pdev->dev, mem);
+	ddc->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
 	if (IS_ERR(ddc->regs))
 		return PTR_ERR(ddc->regs);

--
2.43.0



From alexghiti at rivosinc.com  Mon Feb  5 01:32:28 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Mon, 5 Feb 2024 10:32:28 +0100
Subject: Fwd: [PATCH v8 0/4] riscv: Use PUD/P4D/PGD pages for the linear mapping
In-Reply-To: <CAHh=Yk-WCMbNWg7UCbXtZZzPmOHnh1-pv4fqykwnpJGtwTcc=A@mail.gmail.com>
References: <20230316131711.1284451-1-alexghiti@rivosinc.com>
 <CAK9=C2XJtSG2d_nsyDv7kU1v7Jj0chdevqrMc0MpJswukcEABA@mail.gmail.com>
 <CAHVXubhhxpzHDM-n91V_rceY5t_VqLvrwZj3RP_tNL2=F9mqjQ@mail.gmail.com>
 <CAK9=C2WVOpSqtt8r1U4hnzSZ=cc1PocpukgQjNyahP2XuPhozw@mail.gmail.com>
 <d0087922-4721-ccf1-80bf-9f74099d0948@ghiti.fr> <CAPqJEFr6MgUyARfbWAo7EeQKLVd4xRJz_LOYN68UC-kPD1Hr5A@mail.gmail.com>
 <20240118082346.GB31078@hsinchu15> <CAHVXubiQ5N+ngdy=Fk3j-hS_KkOEg272b++-hB4-oGeSSZKtNQ@mail.gmail.com>
 <CAHh=Yk-WCMbNWg7UCbXtZZzPmOHnh1-pv4fqykwnpJGtwTcc=A@mail.gmail.com>
Message-ID: <CAHVXubhE=RmFQ5gGo7J+H-mOEZKZQbCCH6F43UYMOy=Kgw+nug@mail.gmail.com>

Hi Nylon,

On Fri, Jan 19, 2024 at 10:27?AM Nylon Chen <nylon.chen at sifive.com> wrote:
>
> Alexandre Ghiti <alexghiti at rivosinc.com> ? 2024?1?18? ?? ??9:01???
> >
> > Hi Nylon,
> Hi Alexandre, thanks for your feedback,
> >
> > On Thu, Jan 18, 2024 at 9:23?AM Nylon Chen <nylon.chen at sifive.com> wrote:
> > >
> > > > On 3/23/23 15:55, Anup Patel wrote:
> > > > > On Thu, Mar 23, 2023 at 6:24?PM Alexandre Ghiti <alexghiti at rivosinc.com> wrote:
> > > > >> Hi Anup,
> > > > >>
> > > > >> On Thu, Mar 23, 2023 at 1:18?PM Anup Patel <apatel at ventanamicro.com> wrote:
> > > > >>> Hi Alex,
> > > > >>>
> > > > >>> On Thu, Mar 16, 2023 at 6:48?PM Alexandre Ghiti <alexghiti at rivosinc.com> wrote:
> > > > >>>> This patchset intends to improve tlb utilization by using hugepages for
> > > > >>>> the linear mapping.
> > > > >>>>
> > > > >>>> As reported by Anup in v6, when STRICT_KERNEL_RWX is enabled, we must
> > > > >>>> take care of isolating the kernel text and rodata so that they are not
> > > > >>>> mapped with a PUD mapping which would then assign wrong permissions to
> > > > >>>> the whole region: it is achieved by introducing a new memblock API.
> > > > >>>>
> > > > >>>> Another patch makes use of this new API in arm64 which used some sort of
> > > > >>>> hack to solve this issue: it was built/boot tested successfully.
> > > > >>>>
> > > > >>>> base-commit-tag: v6.3-rc1
> > > > >>>>
> > > > >>>> v8:
> > > > >>>> - Fix rv32, as reported by Anup
> > > > >>>> - Do not modify memblock_isolate_range and fixes comment, as suggested by Mike
> > > > >>>> - Use the new memblock API for crash kernel too in arm64, as suggested by Andrew
> > > > >>>> - Fix arm64 double mapping (which to me did not work in v7), but ends up not
> > > > >>>>    being pretty at all, will wait for comments from arm64 reviewers, but
> > > > >>>>    this patch can easily be dropped if they do not want it.
> > > > >>>>
> > > > >>>> v7:
> > > > >>>> - Fix Anup bug report by introducing memblock_isolate_memory which
> > > > >>>>    allows us to split the memblock mappings and then avoid to map the
> > > > >>>>    the PUD which contains the kernel as read only
> > > > >>>> - Add a patch to arm64 to use this newly introduced API
> > > > >>>>
> > > > >>>> v6:
> > > > >>>> - quiet LLVM warning by casting phys_ram_base into an unsigned long
> > > > >>>>
> > > > >>>> v5:
> > > > >>>> - Fix nommu builds by getting rid of riscv_pfn_base in patch 1, thanks
> > > > >>>>    Conor
> > > > >>>> - Add RB from Andrew
> > > > >>>>
> > > > >>>> v4:
> > > > >>>> - Rebase on top of v6.2-rc3, as noted by Conor
> > > > >>>> - Add Acked-by Rob
> > > > >>>>
> > > > >>>> v3:
> > > > >>>> - Change the comment about initrd_start VA conversion so that it fits
> > > > >>>>    ARM64 and RISCV64 (and others in the future if needed), as suggested
> > > > >>>>    by Rob
> > > > >>>>
> > > > >>>> v2:
> > > > >>>> - Add a comment on why RISCV64 does not need to set initrd_start/end that
> > > > >>>>    early in the boot process, as asked by Rob
> > > > >>>>
> > > > >>>> Alexandre Ghiti (4):
> > > > >>>>    riscv: Get rid of riscv_pfn_base variable
> > > > >>>>    mm: Introduce memblock_isolate_memory
> > > > >>>>    arm64: Make use of memblock_isolate_memory for the linear mapping
> > > > >>>>    riscv: Use PUD/P4D/PGD pages for the linear mapping
> > > > >>> Kernel boot fine on RV64 but there is a failure which is still not
> > > > >>> addressed. You can see this failure as following message in
> > > > >>> kernel boot log:
> > > > >>>      0.000000] Failed to add a System RAM resource at 80200000
> > > > >> Hmmm I don't get that in any of my test configs, would you mind
> > > > >> sharing yours and your qemu command line?
> > > > > Try alexghiti_test branch at
> > > > > https://github.com/avpatel/linux.git
> > > > >
> > > > > I am building the kernel using defconfig and my rootfs is
> > > > > based on busybox.
> > > > >
> > > > > My QEMU command is:
> > > > > qemu-system-riscv64 -M virt -m 512M -nographic -bios
> > > > > opensbi/build/platform/generic/firmware/fw_dynamic.bin -kernel
> > > > > ./build-riscv64/arch/riscv/boot/Image -append "root=/dev/ram rw
> > > > > console=ttyS0 earlycon" -initrd ./rootfs_riscv64.img -smp 4
> > > >
> > > >
> > > > So splitting memblock.memory is the culprit, it "confuses" the resources
> > > > addition and I can only find hacky ways to fix that...
> > > Hi Alexandre,
> > >
> > > We encountered the same error as Anup. After adding your patch
> > > (3335068f87217ea59d08f462187dc856652eea15), we will not encounter the
> > > error again.
> > >
> > > What I have observed so far is
> > >
> > > - before your patch
> > > When merging consecutive memblocks, if the memblock types are different,
> > > they will be merged into reserved
> > > - after your patch
> > > When consecutive memblocks are merged, if the memblock types are
> > > different, they will be merged into memory.
> > >
> > > Such a result will cause the memory location of OpenSBI to be changed
> > > from reserved to memory. Will this have any side effects?
> >
> > I guess it will end up in the memory pool and pages from openSBI
> > region will be allocated, so we should see very quickly bad stuff
> > happening (either PMP violation or M-mode ecall never
> > returning/trapping/etc).
> >
> > But I don't observe the same thing, I always see the openSBI region
> > being reserved:
> >
> > reserved[0x0] [0x0000000080000000-0x000000008007ffff],
> > 0x0000000000080000 bytes flags: 0x0
> >
> > Can you elaborate a bit more about "When consecutive memblocks are
> > merged, if the memblock types are different, they will be merged into
> > memory"? Where/when does this merge happen? Can you give me a config
> > file and a kernel revision so that I can take a look?
> Ok, If you want to reproduce the same results you just need to modify OpenSBI
>
> [ lib/sbi/sbi_domain.c ]
> +#define TEST_SIZE 0x200000
>
> -                                 (scratch->fw_size - scratch->fw_rw_offset),
> +                                 (TEST_SIZE - scratch->fw_rw_offset),
>
> In addition, you can insert checks in the kernel merged function
> [ mm/memblock.c ]
> static void __init_memblock memblock_merge_regions(struct memblock_type *type)
>         while (i < type->cnt - 1) {
>          ...
>                 /* move forward from next + 1, index of which is i + 2 */
>                 memmove(next, next + 1, (type->cnt - (i + 2)) * sizeof(*next));
>                 type->cnt--;
>         }
> +       pr_info("Merged memblock_type: cnt = %lu, max = %lu,
> total_size = 0x%llx\n",type->cnt, type->max, type->total_size);
> +       for (i = 0; i < type->cnt; i++) {
> +               const char *region_type =
> memblock_is_memory(type->regions[i].base) ? "memory" : "reserve";
> +               pr_info("Region %d: base = 0x%llx, size = 0x%llx, type
> = %s\n", i, type->regions[i].base, type->regions[i].size,
> region_type);
> +       }
>  }
> This is kernel boot log
> - before your patch
> ...
> [    0.000000] OF: fdt: Reserving memory: base = 0x80000000, size = 0x200000
> [    0.000000] Merged memblock_type: cnt = 4, max = 128, total_size = 0x1628501
> [    0.000000] Region 0: base = 0x80000000, size = 0x1600000, type = reserve
> ...
>
> - after your patch
> ...
> [    0.000000] OF: fdt: Reserving memory: base = 0x80000000, size = 0x200000
> [    0.000000] Merged memblock_type: cnt = 4, max = 128, total_size = 0x180c42e
> [    0.000000] Region 0: base = 0x80000000, size = 0x1800000, type = memory

So the openSBI region is marked as memory, and not reserved because
this region is now described as nomap, and memblock_mark_nomap() does
not move this region into the reserved memblock list, but keep it in
the memory list with the nomap flag
(https://elixir.bootlin.com/linux/latest/source/drivers/of/fdt.c#L479).
But as stated in the description of memblock_mark_nomap()
(https://elixir.bootlin.com/linux/latest/source/mm/memblock.c#L969),
the pages associated with the region will be marked as PageReserved
and the region will not be covered in the linear mapping.

So to me, this is normal and we are safe. Let me know if I made a mistake.

And sorry for the long delay, that slipped my mind!

Thanks,

Alex

> ...
> [    0.000000] Failed to add a system RAM resource at 80200000
> ...
> >
> > Thanks,
> >
> > Alex
> >
> > > >
> > > > So given that the arm64 patch with the new API is not pretty and that
> > > > the simplest solution is to re-merge the memblock regions afterwards
> > > > (which is done by memblock_clear_nomap), I'll drop the new API and the
> > > > arm64 patch to use the nomap API like arm64: I'll take advantage of that
> > > > to clean setup_vm_final which I have wanted to do for a long time.
> > > >
> > > > @Mike Thanks for you reviews!
> > > >
> > > > @Anup Thanks for all your bug reports on this patchset, I have to
> > > > improve my test flow (it is in the work :)).
> > > >
> > > >
> > > > > Regards,
> > > > > Anup
> > > > >
> > > > >> Thanks
> > > > >>
> > > > >>> Regards,
> > > > >>> Anup
> > > > >>>
> > > > >>>>   arch/arm64/mm/mmu.c           | 25 +++++++++++------
> > > > >>>>   arch/riscv/include/asm/page.h | 19 +++++++++++--
> > > > >>>>   arch/riscv/mm/init.c          | 53 ++++++++++++++++++++++++++++-------
> > > > >>>>   arch/riscv/mm/physaddr.c      | 16 +++++++++++
> > > > >>>>   drivers/of/fdt.c              | 11 ++++----
> > > > >>>>   include/linux/memblock.h      |  1 +
> > > > >>>>   mm/memblock.c                 | 20 +++++++++++++
> > > > >>>>   7 files changed, 119 insertions(+), 26 deletions(-)
> > > > >>>>
> > > > >>>> --
> > > > >>>> 2.37.2
> > > > >>>>
> > > > > _______________________________________________
> > > > > linux-riscv mailing list
> > > > > linux-riscv at lists.infradead.org
> > > > > http://lists.infradead.org/mailman/listinfo/linux-riscv
> > > >
> > > > _______________________________________________
> > > > linux-riscv mailing list
> > > > linux-riscv at lists.infradead.org
> > > > http://lists.infradead.org/mailman/listinfo/linux-riscv


From raphael.gallais-pou at foss.st.com  Mon Feb  5 01:26:50 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Mon, 5 Feb 2024 10:26:50 +0100
Subject: [PATCH 5/5] drm/panel: simple: push blanking limit on RK32FN48H
In-Reply-To: <20240205-ltdc_mp13-v1-0-116d43ebba75@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-116d43ebba75@foss.st.com>
Message-ID: <20240205-ltdc_mp13-v1-5-116d43ebba75@foss.st.com>

Push horizontal front porch and vertical back porch blanking limit.
This allows to get a 60 fps sharp.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
 drivers/gpu/drm/panel/panel-simple.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 7b286382ffb4..10b361d603be 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -3516,10 +3516,10 @@ static const struct display_timing rocktech_rk043fn48h_timing = {
 	.pixelclock = { 6000000, 9000000, 12000000 },
 	.hactive = { 480, 480, 480 },
 	.hback_porch = { 8, 43, 43 },
-	.hfront_porch = { 2, 8, 8 },
+	.hfront_porch = { 2, 8, 10 },
 	.hsync_len = { 1, 1, 1 },
 	.vactive = { 272, 272, 272 },
-	.vback_porch = { 2, 12, 12 },
+	.vback_porch = { 2, 12, 26 },
 	.vfront_porch = { 1, 4, 4 },
 	.vsync_len = { 1, 10, 10 },
 	.flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW |

-- 
2.25.1



From mripard at kernel.org  Mon Feb  5 01:39:38 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 5 Feb 2024 10:39:38 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast
 RGB property
In-Reply-To: <Zb0aYAapkxQ2kopt@intel.com>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
Message-ID: <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>

On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > Hi,
> > > > 
> > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > >  /**
> > > > > > >   * DOC: HDMI connector properties
> > > > > > >   *
> > > > > > > + * Broadcast RGB
> > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > + *
> > > > > > > + *      The value of this property can be one of the following:
> > > > > > > + *
> > > > > > > + *      Automatic:
> > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > + *              according to the HDMI specifications.
> > > > > > > + *
> > > > > > > + *      Full:
> > > > > > > + *              Full RGB Range is forced.
> > > > > > > + *
> > > > > > > + *      Limited 16:235:
> > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > + *
> > > > > > > + *      Drivers can set up this property by calling
> > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > + *
> > > > > > 
> > > > > > This is a good time to document this in more detail. There might be two
> > > > > > different things being affected:
> > > > > > 
> > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > 2. The color pipeline processing
> > > > > > 
> > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > 
> > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > 
> > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > signalling, what happens?
> > > > > 
> > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > YCbCr?
> > > > 
> > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > vc4 will follow the value of the property.
> > > 
> > > The property is literally called "Broadcast *RGB*".
> > > That should explain why it's only affecting RGB.
> > 
> > Right. And the limited range option is called "Limited 16:235" despite
> > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > to make names inconsistent too, that's fine and not an argument in
> > itself.
> > 
> > > Full range YCbCr is a much rarer beast so we've never bothered
> > > to enable it.
> > 
> > vc4 supports it.
> 
> Someone implemented it incorrectly then.

Incorrectly according to what documentation / specification? I'm sorry,
but I find it super ironic that i915 gets to do its own thing, not
document any of it, and when people try to clean things up they get told
that we got it all wrong.

> > > Eg. with DP it only became possible with the introduction of the VSC
> > > SDP (and I don't recall if there's additional capability checks that
> > > are also required). With DP MSA signalling full range YCbCr is not
> > > possible at all.
> > 
> > This is for HDMI only.
> > 
> > > I don't recall right now what the HDMI requirements are.
> > 
> > HDMI has supported it for a while, and it's defined (for example) in the
> > HDMI 1.4 spec in Section 6.6 - Video Quantization Ranges. It supports
> > limited and full range on both RGB and YCbCr, as long as the EDIDs state
> > so and the Infoframes signal it.
> 
> I think a good reason for not using a simple boolean like this 
> YCbCr is that it doesn't cover the color encoding part at all,
> which is probably more important than the quantization range.
> So we need a new property anyway.

This isn't what is being discussed here, and as I've shown you, is
completely orthogonal as far as HDMI is concerned.

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/20240205/bd485fe0/attachment.sig>

From alexander.sverdlin at gmail.com  Mon Feb  5 01:42:16 2024
From: alexander.sverdlin at gmail.com (Alexander Sverdlin)
Date: Mon, 05 Feb 2024 10:42:16 +0100
Subject: [PATCH v7 01/39] ARM: ep93xx: Add terminator to
 gpiod_lookup_table
In-Reply-To: <CACRpkdYDmx9qrkCo5mad_w1e0MKNYrVirg=qi+R4Q907SLdRwg@mail.gmail.com>
References: <20240118-ep93xx-v7-0-d953846ae771@maquefel.me>
	 <20240118-ep93xx-v7-1-d953846ae771@maquefel.me>
	 <CACRpkdYDmx9qrkCo5mad_w1e0MKNYrVirg=qi+R4Q907SLdRwg@mail.gmail.com>
Message-ID: <f00582bf4d19b539cc1427706ee9a07fd3992bc3.camel@gmail.com>

Hi Arnd and all,

On Fri, 2024-01-19 at 00:52 +0100, Linus Walleij wrote:
> On Thu, Jan 18, 2024 at 9:22?AM Nikita Shubin via B4 Relay
> <devnull+nikita.shubin.maquefel.me at kernel.org> wrote:
> 
> > From: Nikita Shubin <nikita.shubin at maquefel.me>
> > 
> > Without the terminator, if a con_id is passed to gpio_find() that
> > does not exist in the lookup table the function will not stop looping
> > correctly, and eventually cause an oops.
> > 
> > Fixes: b2e63555592f ("i2c: gpio: Convert to use descriptors")
> > Reported-by: Andy Shevchenko <andriy.shevchenko at intel.com>
> > Signed-off-by: Nikita Shubin <nikita.shubin at maquefel.me>
> 
> Sorry, my bug...
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Cc: stable at vger.kernel.org
Acked-by: Alexander Sverdlin <alexander.sverdlin at gmail.com>

Arnd, could you please take this into arm-soc?
I can send a PR, but this probably makes little sense for one patch?

-- 
Alexander Sverdlin.



From tudor.ambarus at linaro.org  Mon Feb  5 01:42:21 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 5 Feb 2024 11:42:21 +0200
Subject: [PATCH v2 05/28] spi: dt-bindings: samsung: add
 samsung,spi-fifosize property
In-Reply-To: <20240130222536.GA2523173-robh@kernel.org>
References: <20240125145007.748295-1-tudor.ambarus@linaro.org>
 <20240125145007.748295-6-tudor.ambarus@linaro.org>
 <7ef86704-3e40-4d39-a69d-a30719c96660@sirena.org.uk>
 <1c58deef-bc0f-4889-bf40-54168ce9ff7c@linaro.org>
 <55af5d4a-7bc9-4ae7-88c5-5acae4666450@sirena.org.uk>
 <f2ec664b-cd67-4cae-9c0d-5a435c72f121@linaro.org>
 <f44d5c58-234d-45ec-8027-47df079e2f16@sirena.org.uk>
 <96f9306f-3445-484b-bd3c-82e708681f1b@linaro.org>
 <20240130222536.GA2523173-robh@kernel.org>
Message-ID: <144a0bed-6ba2-480c-b377-16364522845c@linaro.org>

Hi, Rob,

On 31.01.2024 00:25, Rob Herring wrote:
> On Thu, Jan 25, 2024 at 07:01:10PM +0000, Tudor Ambarus wrote:
>>
>>
>> On 1/25/24 17:45, Mark Brown wrote:
>>> On Thu, Jan 25, 2024 at 05:30:53PM +0000, Tudor Ambarus wrote:
>>>> On 1/25/24 17:26, Mark Brown wrote:
>>>
>>>>> OK, so just the compatible is enough information then?
>>>
>>>> For gs101, yes. All the gs101 SPI instances are configured with 64 bytes
>>>> FIFO depths. So instead of specifying the FIFO depth for each SPI node,
>>>> we can infer the FIFO depth from the compatible.
>>>
>>> But this is needed for other SoCs?  This change is scattered through a
>>
>> There are SoCs that have multiple instances of the SPI IP, and they
>> configure them with different FIFO depths. See
>> "samsung,exynosautov9-spi" for example: SPI0, SPI1, and SPI6 are
>> configured by the SoC to use 256 bytes FIFO depths, while all the other
>> 8 SPI instances use 64 bytes FIFOs. I tried to explain the entire logic
>> of the series in another reply, see it here:
>> https://lore.kernel.org/linux-arm-kernel/40ba9481-4aea-4a72-87bd-c2db319be069 at linaro.org/T/#u
> 
> We have some common properties for fifo size. In fact, there was just a 
> discussion recently on Samsung UART (Is that the same block?) about 

It is the same block, I'll take a look.

> this. So if you do use a property here, use a common one.

Will do. Thanks, Rob!
Cheers,
ta


From shawn.gsc at gmail.com  Mon Feb  5 01:43:33 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 17:43:33 +0800
Subject: [PATCH v2 0/3] ARM: dts: imx6dl: Add support for Sielaff i.MX6
 Solo board
In-Reply-To: <20240116181100.382388-1-frieder@fris.de>
References: <20240116181100.382388-1-frieder@fris.de>
Message-ID: <ZcCsbnNVKJk95cij@t480>

On Tue, Jan 16, 2024 at 07:10:25PM +0100, Frieder Schrempf wrote:
> From: Frieder Schrempf <frieder.schrempf at kontron.de>
> 
> This series adds upstream support for the Sielaff i.MX6 Solo board.
> It is used as controller and user interface in vending machines. It
> is based on the i.MX6 Solo SoC and features the following
> peripherals and interfaces:
> 
> * 512 MB DDR3 RAM
> * 512 MB NAND Flash
> * 1 MB NOR Flash
> * SD card
> * Debug LED
> * Debug UART
> * Key Inputs
> * RTC
> * RS232
> * 100 MBit Ethernet
> * USB Hub
> * USB OTG
> * HDMI
> * 7" LVDS IPS panel
> * PWM Backlight
> * Optional Extension Board with USB Ethernet NIC
> 
> Patch 1 adds the vendor prefix, patch 2 adds the DT bindings and
> patch 3 adds the DT.
> 
> Changes in v2:
> * Add Acked-by from Conor (Thanks!)
> * Fix touchscreen node names (Thanks Fabio!)
> 
> Frieder Schrempf (3):
>   dt-bindings: vendor-prefixes: Add Sielaff

>   dt-bindings: arm: fsl: Add Sielaff i.MX6 Solo board
>   ARM: dts: imx6dl: Add support for Sielaff i.MX6 Solo board

Applied both, thanks!


From maz at kernel.org  Mon Feb  5 01:46:16 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 05 Feb 2024 09:46:16 +0000
Subject: [PATCH v8 13/38] KVM: arm64: Manage GCS registers for guests
In-Reply-To: <20240203-arm64-gcs-v8-13-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
	<20240203-arm64-gcs-v8-13-c9fec77673ef@kernel.org>
Message-ID: <868r3z6y6v.wl-maz@kernel.org>

On Sat, 03 Feb 2024 12:25:39 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> GCS introduces a number of system registers for EL1 and EL0, on systems

and EL2.

> with GCS we need to context switch them and expose them to VMMs to allow
> guests to use GCS, as well as describe their fine grained traps to
> nested virtualisation.  Traps are already disabled.

The latter is not true with NV, since the guest is in control of the
FGT registers.

> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_host.h          | 12 ++++++++++++
>  arch/arm64/kvm/emulate-nested.c            |  4 ++++
>  arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 17 +++++++++++++++++
>  arch/arm64/kvm/sys_regs.c                  | 22 ++++++++++++++++++++++
>  4 files changed, 55 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 21c57b812569..6c7ea7f9cd92 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -388,6 +388,12 @@ enum vcpu_sysreg {
>  	GCR_EL1,	/* Tag Control Register */
>  	TFSRE0_EL1,	/* Tag Fault Status Register (EL0) */
>  
> +	/* Guarded Control Stack registers */
> +	GCSCRE0_EL1,	/* Guarded Control Stack Control (EL0) */
> +	GCSCR_EL1,	/* Guarded Control Stack Control (EL1) */

This is subjected to VNCR (0x8D0).

> +	GCSPR_EL0,	/* Guarded Control Stack Pointer (EL0) */
> +	GCSPR_EL1,	/* Guarded Control Stack Pointer (EL1) */

So is this one (0x8C0). And how about the *_EL2 versions?

> +
>  	/* 32bit specific registers. */
>  	DACR32_EL2,	/* Domain Access Control Register */
>  	IFSR32_EL2,	/* Instruction Fault Status Register */
> @@ -1221,6 +1227,12 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)
>  
>  #define vcpu_has_feature(v, f)	__vcpu_has_feature(&(v)->kvm->arch, (f))
>  
> +static inline bool has_gcs(void)
> +{
> +	return IS_ENABLED(CONFIG_ARM64_GCS) &&
> +		cpus_have_final_cap(ARM64_HAS_GCS);
> +}
> +
>  int kvm_trng_call(struct kvm_vcpu *vcpu);
>  #ifdef CONFIG_KVM
>  extern phys_addr_t hyp_mem_base;
> diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
> index 431fd429932d..24eb7eccbae4 100644
> --- a/arch/arm64/kvm/emulate-nested.c
> +++ b/arch/arm64/kvm/emulate-nested.c
> @@ -1098,8 +1098,12 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
>  	SR_FGT(SYS_ESR_EL1, 		HFGxTR, ESR_EL1, 1),
>  	SR_FGT(SYS_DCZID_EL0, 		HFGxTR, DCZID_EL0, 1),
>  	SR_FGT(SYS_CTR_EL0, 		HFGxTR, CTR_EL0, 1),
> +	SR_FGT(SYS_GCSPR_EL0,		HFGxTR, nGCS_EL0, 1),
>  	SR_FGT(SYS_CSSELR_EL1, 		HFGxTR, CSSELR_EL1, 1),
>  	SR_FGT(SYS_CPACR_EL1, 		HFGxTR, CPACR_EL1, 1),
> +	SR_FGT(SYS_GCSCR_EL1,		HFGxTR, nGCS_EL1, 1),
> +	SR_FGT(SYS_GCSPR_EL1,		HFGxTR, nGCS_EL1, 1),
> +	SR_FGT(SYS_GCSCRE0_EL1,		HFGxTR, nGCS_EL0, 1),

This is clearly wrong on all 4 counts (the n prefix gives it away...).

>  	SR_FGT(SYS_CONTEXTIDR_EL1, 	HFGxTR, CONTEXTIDR_EL1, 1),
>  	SR_FGT(SYS_CLIDR_EL1, 		HFGxTR, CLIDR_EL1, 1),
>  	SR_FGT(SYS_CCSIDR_EL1, 		HFGxTR, CCSIDR_EL1, 1),
> diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> index bb6b571ec627..ec34d4a90717 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> @@ -25,6 +25,8 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt)
>  {
>  	ctxt_sys_reg(ctxt, TPIDR_EL0)	= read_sysreg(tpidr_el0);
>  	ctxt_sys_reg(ctxt, TPIDRRO_EL0)	= read_sysreg(tpidrro_el0);
> +	if (has_gcs())
> +		ctxt_sys_reg(ctxt, GCSPR_EL0) = read_sysreg_s(SYS_GCSPR_EL0);

We have had this discussion in the past. This must be based on the
VM's configuration. Guarding the check with the host capability is a
valuable optimisation, but that's nowhere near enough. See the series
that I have posted on this very subject (you're on Cc), but you are
welcome to invent your own mechanism in the meantime.

>  }
>  
>  static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt)
> @@ -62,6 +64,12 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
>  	ctxt_sys_reg(ctxt, PAR_EL1)	= read_sysreg_par();
>  	ctxt_sys_reg(ctxt, TPIDR_EL1)	= read_sysreg(tpidr_el1);
>  
> +	if (has_gcs()) {
> +		ctxt_sys_reg(ctxt, GCSPR_EL1)	= read_sysreg_el1(SYS_GCSPR);
> +		ctxt_sys_reg(ctxt, GCSCR_EL1)	= read_sysreg_el1(SYS_GCSCR);
> +		ctxt_sys_reg(ctxt, GCSCRE0_EL1)	= read_sysreg_s(SYS_GCSCRE0_EL1);
> +	}
> +

Same thing.

>  	if (ctxt_has_mte(ctxt)) {
>  		ctxt_sys_reg(ctxt, TFSR_EL1) = read_sysreg_el1(SYS_TFSR);
>  		ctxt_sys_reg(ctxt, TFSRE0_EL1) = read_sysreg_s(SYS_TFSRE0_EL1);
> @@ -95,6 +103,8 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt)
>  {
>  	write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL0),	tpidr_el0);
>  	write_sysreg(ctxt_sys_reg(ctxt, TPIDRRO_EL0),	tpidrro_el0);
> +	if (has_gcs())
> +		write_sysreg_s(ctxt_sys_reg(ctxt, GCSPR_EL0), SYS_GCSPR_EL0);
>  }
>  
>  static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
> @@ -138,6 +148,13 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
>  	write_sysreg(ctxt_sys_reg(ctxt, PAR_EL1),	par_el1);
>  	write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL1),	tpidr_el1);
>  
> +	if (has_gcs()) {
> +		write_sysreg_el1(ctxt_sys_reg(ctxt, GCSPR_EL1),	SYS_GCSPR);
> +		write_sysreg_el1(ctxt_sys_reg(ctxt, GCSCR_EL1),	SYS_GCSCR);
> +		write_sysreg_s(ctxt_sys_reg(ctxt, GCSCRE0_EL1),
> +			       SYS_GCSCRE0_EL1);
> +	}
> +

For the benefit of the unsuspecting reviewers, and in the absence of a
public specification (which the XML drop isn't), it would be good to
have the commit message explaining the rationale of what gets saved
when.

>  	if (ctxt_has_mte(ctxt)) {
>  		write_sysreg_el1(ctxt_sys_reg(ctxt, TFSR_EL1), SYS_TFSR);
>  		write_sysreg_s(ctxt_sys_reg(ctxt, TFSRE0_EL1), SYS_TFSRE0_EL1);
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 30253bd19917..83ba767e75d2 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -2000,6 +2000,23 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu,
>  	.visibility = mte_visibility,		\
>  }
>  
> +static unsigned int gcs_visibility(const struct kvm_vcpu *vcpu,
> +				   const struct sys_reg_desc *rd)
> +{
> +	if (has_gcs())
> +		return 0;

Yet another case of exposing potentially unwanted state, to the VMM
this time.

> +
> +	return REG_HIDDEN;
> +}
> +
> +#define GCS_REG(name) {				\
> +	SYS_DESC(SYS_##name),			\
> +	.access = undef_access,			\
> +	.reset = reset_unknown,			\
> +	.reg = name,				\
> +	.visibility = gcs_visibility,		\
> +}
> +
>  static unsigned int el2_visibility(const struct kvm_vcpu *vcpu,
>  				   const struct sys_reg_desc *rd)
>  {
> @@ -2376,6 +2393,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	PTRAUTH_KEY(APDB),
>  	PTRAUTH_KEY(APGA),
>  
> +	GCS_REG(GCSCR_EL1),
> +	GCS_REG(GCSPR_EL1),
> +	GCS_REG(GCSCRE0_EL1),
> +
>  	{ SYS_DESC(SYS_SPSR_EL1), access_spsr},
>  	{ SYS_DESC(SYS_ELR_EL1), access_elr},
>  
> @@ -2462,6 +2483,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ 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 },
> +	GCS_REG(GCSPR_EL0),
>  	{ SYS_DESC(SYS_SVCR), undef_access },
>  
>  	{ PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, .reset = reset_pmcr,
> 


Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From shawn.gsc at gmail.com  Mon Feb  5 01:50:08 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 17:50:08 +0800
Subject: [PATCH 2/3] arm64: dts: imx93: drop "master" I3C node name suffix
In-Reply-To: <20240117075618.81932-2-krzysztof.kozlowski@linaro.org>
References: <20240117075618.81932-1-krzysztof.kozlowski@linaro.org>
 <20240117075618.81932-2-krzysztof.kozlowski@linaro.org>
Message-ID: <ZcCvUJNslxafvCab@t480>

On Wed, Jan 17, 2024 at 08:56:17AM +0100, Krzysztof Kozlowski wrote:
> Following change in the I3C bindings, the "master" suffix in I3C
> controller node name is discouraged (it is "controller" now) and not
> accurate (if device supports also target mode).
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Applied, thanks!


From luca.weiss at fairphone.com  Mon Feb  5 01:51:37 2024
From: luca.weiss at fairphone.com (Luca Weiss)
Date: Mon, 05 Feb 2024 10:51:37 +0100
Subject: [PATCH 0/3] Add PPG support for PMI632 LPG dtsi
Message-ID: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>

Hook up the PBS & SDAM to the PMI632 LPG so that we can use the
hw_pattern for the LEDs.

Signed-off-by: Luca Weiss <luca.weiss at fairphone.com>
---
Luca Weiss (3):
      dt-bindings: mfd: qcom,spmi-pmic: Add pbs to SPMI device types
      arm64: dts: qcom: pmi632: Add PBS client and use in LPG node
      arm64: defconfig: Enable QCOM PBS

 Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++
 arch/arm64/boot/dts/qcom/pmi632.dtsi                      | 9 +++++++++
 arch/arm64/configs/defconfig                              | 1 +
 3 files changed, 14 insertions(+)
---
base-commit: 1f790ac9c84028d89ef4dbb28ecc5771fc352e25
change-id: 20240117-pmi632-ppg-f1efb4318722

Best regards,
-- 
Luca Weiss <luca.weiss at fairphone.com>



From luca.weiss at fairphone.com  Mon Feb  5 01:51:38 2024
From: luca.weiss at fairphone.com (Luca Weiss)
Date: Mon, 05 Feb 2024 10:51:38 +0100
Subject: [PATCH 1/3] dt-bindings: mfd: qcom,spmi-pmic: Add pbs to SPMI
 device types
In-Reply-To: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
References: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
Message-ID: <20240205-pmi632-ppg-v1-1-e236c95a2099@fairphone.com>

Add the PBS (Programmable Boot Sequencer) to the list of devices.

Signed-off-by: Luca Weiss <luca.weiss at fairphone.com>
---
 Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
index 8103fb61a16c..b7f01cbb8fff 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
@@ -160,6 +160,10 @@ patternProperties:
     type: object
     $ref: /schemas/nvmem/qcom,spmi-sdam.yaml#
 
+  "^pbs@[0-9a-f]+$":
+    type: object
+    $ref: /schemas/soc/qcom/qcom,pbs.yaml#
+
   "phy@[0-9a-f]+$":
     type: object
     $ref: /schemas/phy/qcom,snps-eusb2-repeater.yaml#

-- 
2.43.0



From luca.weiss at fairphone.com  Mon Feb  5 01:51:39 2024
From: luca.weiss at fairphone.com (Luca Weiss)
Date: Mon, 05 Feb 2024 10:51:39 +0100
Subject: [PATCH 2/3] arm64: dts: qcom: pmi632: Add PBS client and use in
 LPG node
In-Reply-To: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
References: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
Message-ID: <20240205-pmi632-ppg-v1-2-e236c95a2099@fairphone.com>

With SDAM + PBS the LPG driver can configure the LED pattern in
hardware.

Signed-off-by: Luca Weiss <luca.weiss at fairphone.com>
---
 arch/arm64/boot/dts/qcom/pmi632.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
index 4eb79e0ce40a..d2bb49a619d7 100644
--- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
@@ -127,6 +127,11 @@ pmi632_adc_tm: adc-tm at 3500 {
 			status = "disabled";
 		};
 
+		pmi632_pbs_client3: pbs at 7400 {
+			compatible = "qcom,pmi632-pbs", "qcom,pbs";
+			reg = <0x7400>;
+		};
+
 		pmi632_sdam_7: nvram at b600 {
 			compatible = "qcom,spmi-sdam";
 			reg = <0xb600>;
@@ -155,6 +160,10 @@ pmic at 3 {
 		pmi632_lpg: pwm {
 			compatible = "qcom,pmi632-lpg";
 
+			nvmem = <&pmi632_sdam_7>;
+			nvmem-names = "lpg_chan_sdam";
+			qcom,pbs = <&pmi632_pbs_client3>;
+
 			#address-cells = <1>;
 			#size-cells = <0>;
 			#pwm-cells = <2>;

-- 
2.43.0



From luca.weiss at fairphone.com  Mon Feb  5 01:51:40 2024
From: luca.weiss at fairphone.com (Luca Weiss)
Date: Mon, 05 Feb 2024 10:51:40 +0100
Subject: [PATCH 3/3] arm64: defconfig: Enable QCOM PBS
In-Reply-To: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
References: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
Message-ID: <20240205-pmi632-ppg-v1-3-e236c95a2099@fairphone.com>

Enable the PBS driver used on e.g. PMI632.

Signed-off-by: Luca Weiss <luca.weiss at fairphone.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index cfa3e00def09..e92a5fd9f660 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1375,6 +1375,7 @@ CONFIG_QCOM_STATS=m
 CONFIG_QCOM_WCNSS_CTRL=m
 CONFIG_QCOM_APR=m
 CONFIG_QCOM_ICC_BWMON=m
+CONFIG_QCOM_PBS=m
 CONFIG_ARCH_R8A77995=y
 CONFIG_ARCH_R8A77990=y
 CONFIG_ARCH_R8A77951=y

-- 
2.43.0



From tudor.ambarus at linaro.org  Mon Feb  5 01:54:03 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 5 Feb 2024 11:54:03 +0200
Subject: [PATCH v2 23/28] spi: s3c64xx: retrieve the FIFO size from the
 device tree
In-Reply-To: <CAPLW+4mQ=q1c061Zv=dxnHwMJtjH5sbQsvg25x5uzxL3UCAuTA@mail.gmail.com>
References: <20240125145007.748295-1-tudor.ambarus@linaro.org>
 <20240125145007.748295-24-tudor.ambarus@linaro.org>
 <1e117c5c-1e82-47ae-82f4-cdcf0a087f5f@sirena.org.uk>
 <CAPLW+4kTUmG=uPQadJC5pyfDvydvr1dKnJY6UxQva2Ch-x7v3g@mail.gmail.com>
 <e4b76c3d-f710-4b32-aa30-23cb54346d15@app.fastmail.com>
 <CAPLW+4mQ=q1c061Zv=dxnHwMJtjH5sbQsvg25x5uzxL3UCAuTA@mail.gmail.com>
Message-ID: <03f335d6-80ed-4dfd-9bc7-c959431c7420@linaro.org>



On 26.01.2024 22:20, Sam Protsenko wrote:
> On Fri, Jan 26, 2024 at 2:17?PM Arnd Bergmann <arnd at arndb.de> wrote:
>>
>> On Fri, Jan 26, 2024, at 20:23, Sam Protsenko wrote:
>>> On Thu, Jan 25, 2024 at 11:33?AM Mark Brown <broonie at kernel.org> wrote:
>>>>
>>>> On Thu, Jan 25, 2024 at 02:50:01PM +0000, Tudor Ambarus wrote:
>>>>
>>>>> Allow SoCs that have multiple instances of the SPI IP with different
>>>>> FIFO sizes to specify their FIFO size via the "samsung,spi-fifosize"
>>>>> device tree property. With this we can break the dependency between the
>>>>> SPI alias, the fifo_lvl_mask and the FIFO size.
>>>>
>>>> OK, so we do actually have SoCs with multiple instances of the IP with
>>>> different FIFO depths (and who knows what else other differences)?
>>>
>>> I think that's why we can see .fifo_lvl_mask[] with different values
>>> for different IP instances. For example, ExynosAutoV9 has this (in
>>> upstream driver, yes):
>>>
>>>     .fifo_lvl_mask = { 0x1ff, 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff,
>>> 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
>>>
>>
>> That sounds like the same bug as in the serial port driver,
>> by assuming that the alias values in the devicetree have
>> a particular meaning in identifying instances. This immediately
>> breaks when there is a dtb file that does not use the same
>> alias values, e.g. because it only needs some of the SPI
>> ports.
>>
> 
> Exactly. I guess that's exactly what Tudor mentioned in his commit
> message, and he's trying to fix that very problem by relying on
> corresponding dts property (in his patch series) rather than on
> .fifo_lvl_mask.
> 

Yes, all from above are correct. I'll split the FIFO size patches into a
smaller series to be easier to review.

Cheers,
ta


From shawn.gsc at gmail.com  Mon Feb  5 01:56:24 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Mon, 5 Feb 2024 17:56:24 +0800
Subject: [PATCH] ARM: dts: imx6qdl-hummingboard: Add rtc0 and rtc1
 aliases to fix hctosys
In-Reply-To: <20240118-imx6-hb-primary-rtc-v1-1-81b87935c557@solid-run.com>
References: <20240118-imx6-hb-primary-rtc-v1-1-81b87935c557@solid-run.com>
Message-ID: <ZcCwyKQ4KrtlCCkv@t480>

On Thu, Jan 18, 2024 at 04:01:10PM +0100, Josua Mayer wrote:
> HummingBoard has two RTCs, first integrated within SoC that can be used to
> wake up from sleep - and a second on the carrier board including back-up
> battery which is intended for keeping time during power-off.
> 
> Add aliases for both, ensuring that the battery-backed clock is primary
> rtc and used by default during boot for restoring system time.
> 
> Fixes keeping time across power-cycle observed on Debian,
> which sets RTC_HCTOSYS_DEVICE="rtc0".
> 
> Signed-off-by: Josua Mayer <josua at solid-run.com>

Applied, thanks!


From richard.xnu.clark at gmail.com  Mon Feb  5 01:57:29 2024
From: richard.xnu.clark at gmail.com (richard clark)
Date: Mon, 5 Feb 2024 17:57:29 +0800
Subject: Question about the ipi_raise filter usage and output
Message-ID: <CAJNi4rMpt88Gz+149wR9crzApmfUEfpS05sbOgAvOhzh2+Brbg@mail.gmail.com>

Hi guys,

With the ipi_raise event enabled and filtered with:
echo 'reason == "Function call interrupts"' > filter, then the 'cat
trace' output below messages:
...
insmod-3355    [010] ....1.. 24479.230381: ipi_raise:
target_mask=00000000,00000bff (Function call interrupts)
...
The above output is triggered by my kernel module where it will smp
cross call a remote function from cpu#10 to cpu#11, for the
'target_mask' value, what does the '00000000,00000bff' mean?
 ~~~~~~~~~~~~~~

Another question is for the filter, I'd like to catch the IPI only
happening on cpu#11 *AND* a remote function call, so how to write the
'target_cpus' in the filter expression?

I try to write below:
echo 'target_cpus == 11 && reason == "Function call interrupts"' >
events/ipi/ipi_raise/filter

But the 'cat trace' doesn't show anything about cpu#11 IPI info,
although both the /proc/interrupts and the smp_processor_id() in the
remote function shows there's IPI sent to the cpu#11.

Any suggestions?

Thank you!


From linux at armlinux.org.uk  Mon Feb  5 01:59:53 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 5 Feb 2024 09:59:53 +0000
Subject: [PATCH net-next v4 2/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <20240204-for-netnext-mt7530-improvements-2-v4-2-02bf0abaadb8@arinc9.com>
References: <20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8@arinc9.com>
 <20240204-for-netnext-mt7530-improvements-2-v4-2-02bf0abaadb8@arinc9.com>
Message-ID: <ZcCxmUwxfmKIXh/U@shell.armlinux.org.uk>

On Sun, Feb 04, 2024 at 07:34:20PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> The crystal frequency concerns the switch core. The frequency should be
> checked when the switch is being set up so the driver can reject the
> unsupported hardware earlier and without requiring port 6 to be used.
> 
> Move it to mt7530_setup(). Drop the unnecessary function printing.
> 
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>

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! 80Mbps down 10Mbps up. Decent connectivity at last!


From arnd at arndb.de  Mon Feb  5 02:02:06 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 05 Feb 2024 10:02:06 +0000
Subject: [PATCH v7 01/39] ARM: ep93xx: Add terminator to gpiod_lookup_table
In-Reply-To: <f00582bf4d19b539cc1427706ee9a07fd3992bc3.camel@gmail.com>
References: <20240118-ep93xx-v7-0-d953846ae771@maquefel.me>
 <20240118-ep93xx-v7-1-d953846ae771@maquefel.me>
 <CACRpkdYDmx9qrkCo5mad_w1e0MKNYrVirg=qi+R4Q907SLdRwg@mail.gmail.com>
 <f00582bf4d19b539cc1427706ee9a07fd3992bc3.camel@gmail.com>
Message-ID: <86ae775b-b3ab-45db-9541-95fcc0e17b5e@app.fastmail.com>

On Mon, Feb 5, 2024, at 09:42, Alexander Sverdlin wrote:
> Hi Arnd and all,
>
> On Fri, 2024-01-19 at 00:52 +0100, Linus Walleij wrote:
>> On Thu, Jan 18, 2024 at 9:22?AM Nikita Shubin via B4 Relay
>> <devnull+nikita.shubin.maquefel.me at kernel.org> wrote:
>> 
>> > From: Nikita Shubin <nikita.shubin at maquefel.me>
>> > 
>> > Without the terminator, if a con_id is passed to gpio_find() that
>> > does not exist in the lookup table the function will not stop looping
>> > correctly, and eventually cause an oops.
>> > 
>> > Fixes: b2e63555592f ("i2c: gpio: Convert to use descriptors")
>> > Reported-by: Andy Shevchenko <andriy.shevchenko at intel.com>
>> > Signed-off-by: Nikita Shubin <nikita.shubin at maquefel.me>
>> 
>> Sorry, my bug...
>> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
>
> Cc: stable at vger.kernel.org
> Acked-by: Alexander Sverdlin <alexander.sverdlin at gmail.com>
>
> Arnd, could you please take this into arm-soc?
> I can send a PR, but this probably makes little sense for one patch?

I'm travelling at the moment, but can take it when I get back.

If you want to be sure it doesn't get lost, please send the
patch (with the Acks) to soc at kernel.org and it will end up
in patchwork.

   Arnd


From suzuki.poulose at arm.com  Mon Feb  5 02:10:41 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 5 Feb 2024 10:10:41 +0000
Subject: [PATCH v2 02/25] KVM: arm64: Add feature checking helpers
In-Reply-To: <87le80wj0l.wl-maz@kernel.org>
References: <20240130204533.693853-1-maz@kernel.org>
 <20240130204533.693853-3-maz@kernel.org>
 <f47909b1-5e10-4149-8d2a-330bd0ceb2e0@arm.com> <87mssgwkoy.wl-maz@kernel.org>
 <87le80wj0l.wl-maz@kernel.org>
Message-ID: <5abfe1dc-bf52-4cbc-9d3d-6f5b83c1e48f@arm.com>

On 04/02/2024 11:44, Marc Zyngier wrote:
> On Sun, 04 Feb 2024 11:08:45 +0000,
> Marc Zyngier <maz at kernel.org> wrote:
>>
>> On Fri, 02 Feb 2024 17:13:07 +0000,
>> Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>>>
>>> Hi Marc,
>>>
>>> On 30/01/2024 20:45, Marc Zyngier wrote:
>>>> In order to make it easier to check whether a particular feature
>>>> is exposed to a guest, add a new set of helpers, with kvm_has_feat()
>>>> being the most useful.
>>>>
>>>> Let's start making use of them in the PMU code (courtesy of Oliver).
>>>> Follow-up work will intricude additional use patterns.
>>>
>>> I think there is a bit of inconsistency in the macros for signed
>>> and unsigned. The unsigned fields are extracted (i.e., as if they
>>> were shifted to bit 0). But the signed fields are not shifted
>>> completely to bit '0' (in fact to different positions) and eventually
>>> we compare wrong things.
>>>
>>> Using ID_AA64PFR0_EL1, fld=EL2, val=IMP for unsigned and
>>> ID_AA64PFR0_EL1, AdvSIMD, NI for signed.
>>>
>>>>
>>>> Co-developed--by: Oliver Upton <oliver.upton at linux.dev>
>>>> Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
>>>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>>>> ---
>>>>    arch/arm64/include/asm/kvm_host.h | 53 +++++++++++++++++++++++++++++++
>>>>    arch/arm64/kvm/pmu-emul.c         | 11 ++++---
>>>>    arch/arm64/kvm/sys_regs.c         |  6 ++--
>>>>    include/kvm/arm_pmu.h             | 11 -------
>>>>    4 files changed, 61 insertions(+), 20 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>>>> index 21c57b812569..c0cf9c5f5e8d 100644
>>>> --- a/arch/arm64/include/asm/kvm_host.h
>>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>>> @@ -1233,4 +1233,57 @@ static inline void kvm_hyp_reserve(void) { }
>>>>    void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
>>>>    bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
>>>>    +#define __expand_field_sign_unsigned(id, fld, val)
>>>> \
>>>> +	((u64)(id##_##fld##_##val))
>>>
>>> For unsigned features we get the actual "field" value, not the value
>>> in position. e.g,: ID_AA64PFR0_EL1_EL2_IMP = (0x1)
>>>
>>>> +
>>>> +#define __expand_field_sign_signed(id, fld, val)			\
>>>> +	({								\
>>>> +		s64 __val = id##_##fld##_##val;				\
>>>> +		__val <<= 64 - id##_##fld##_WIDTH;			\
>>>> +		__val >>= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
>>>
>>> But for signed fields, we shift them back into the "position" as in
>>> the ID_REG. e.g.,
>>>
>>> ID_AA64PFR0_EL1, AdvSIMD, NI we get:
>>>
>>> 	__val = ID_AA64PFR0_EL1_AdvSIMD_NI; /* = 0xf */
>>> 	__val <<= 64 - 4;		/* 0xf0_00_00_00_00_00_00_00 */
>>> 	__val >>= 64 - 20 - 4;		/* 0xff_ff_ff_ff_ff_f0_00_00 */
>>>
>>> I think the last line instead should be:
>>> 	__val >>= 64 - id##_##fld##_WIDTH;
>>
>> Huh, you're absolutely right.
>>
>>>
>>>> +									\
>>>> +		__val;							\
>>>> +	})
>>>> +
>>>> +#define expand_field_sign(id, fld, val)					\
>>>> +	(id##_##fld##_SIGNED ?						\
>>>> +	 __expand_field_sign_signed(id, fld, val) :			\
>>>> +	 __expand_field_sign_unsigned(id, fld, val))
>>>> +
>>>> +#define get_idreg_field_unsigned(kvm, id, fld)				\
>>>> +	({								\
>>>> +		u64 __val = IDREG(kvm, SYS_##id);			\
>>>> +		__val &= id##_##fld##_MASK;				\
>>>> +		__val >>= id##_##fld##_SHIFT;				\
>>>> +									\
>>>
>>> We extract the field value for unsigned field, i.e., shifted to bit"0"
>>> and that matches the expand_field_sign().
>>>
>>>> +		__val;							\
>>>> +	})
>>>> +
>>>> +#define get_idreg_field_signed(kvm, id, fld)				\
>>>> +	({								\
>>>> +		s64 __val = IDREG(kvm, SYS_##id);			\
>>>> +		__val <<= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
>>>> +		__val >>= id##_##fld##_SHIFT;				\
>>>
>>> However, here we get (assuming value ID_AA64PFR0_EL1_ASIMD = 0xf, and
>>> all other fields are 0 for clarity)
>>> 	
>>> 	__val = IDREG(kvm, SYS_ID_AA64PFR0_EL1); = 0xf0_00_00; 	/* 0xf << 20 */
>>> 	__val <<= 64 - 20 - 4;	/* = 0xf0_00_00_00_00_00_00_00 */
>>> 	__val >>= 20;		/* = 0xff_ff_ff_00_00_00_00_00 */
>>
>> Gah... again!
>>
>>>
>>> Thus they don;t match. Instead the last line should be :
>>>
>>> 	__val >>= id##_##fld##_WIDTH;
>>
>> Shouldn't this be (64 - WIDTH) instead, since we want the value to be
>> shifted to bit 0? Otherwise, you get 0xff_00_00_00_00_00_00_00 (as per
>> your example).

Bah, You're right. See, its so easy to mess it up ;-)

>>
>> Thanks a lot for spotting those, much appreciated.
> 
> And since it is now obvious to anyone that I can't shift properly,
> let's just not do that. As it turns out, the kernel already has the
> required macros, and I can stop being clever with these:
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index ea8acc1914aa..3457fa313bad 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -1290,11 +1290,8 @@ bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
>   
>   #define __expand_field_sign_signed(id, fld, val)			\
>   	({								\
> -		s64 __val = id##_##fld##_##val;				\
> -		__val <<= 64 - id##_##fld##_WIDTH;			\
> -		__val >>= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
> -									\
> -		__val;							\
> +		u64 __val = id##_##fld##_##val;				\
> +		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
>   	})
> 



>   #define expand_field_sign(id, fld, val)					\
> @@ -1313,11 +1310,9 @@ bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
>   
>   #define get_idreg_field_signed(kvm, id, fld)				\
>   	({								\
> -		s64 __val = IDREG(kvm, SYS_##id);			\
> -		__val <<= 64 - id##_##fld##_SHIFT - id##_##fld##_WIDTH;	\
> -		__val >>= id##_##fld##_SHIFT;				\
> -									\
> -		__val;							\
> +		u64 __val = IDREG(kvm, SYS_##id);			\
> +		__val = FIELD_GET(id##_##fld##_MASK, __val);		\
> +		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
>   	})
>   
>   #define get_idreg_field_enum(kvm, id, fld)				\
> 
> Thoughts?

Thats much much better and saves you some staring at the screen. Didn't
know that existed. Thanks for that.

Suzuki


> 
> 	M.
> 



From alexander.sverdlin at gmail.com  Mon Feb  5 02:13:40 2024
From: alexander.sverdlin at gmail.com (Alexander Sverdlin)
Date: Mon, 05 Feb 2024 11:13:40 +0100
Subject: [PATCH v7 01/39] ARM: ep93xx: Add terminator to
 gpiod_lookup_table
In-Reply-To: <86ae775b-b3ab-45db-9541-95fcc0e17b5e@app.fastmail.com>
References: <20240118-ep93xx-v7-0-d953846ae771@maquefel.me>
	 <20240118-ep93xx-v7-1-d953846ae771@maquefel.me>
	 <CACRpkdYDmx9qrkCo5mad_w1e0MKNYrVirg=qi+R4Q907SLdRwg@mail.gmail.com>
	 <f00582bf4d19b539cc1427706ee9a07fd3992bc3.camel@gmail.com>
	 <86ae775b-b3ab-45db-9541-95fcc0e17b5e@app.fastmail.com>
Message-ID: <c93bf062dca07191bd76330eac6580355ab65a57.camel@gmail.com>

Thanks Arnd,

On Mon, 2024-02-05 at 10:02 +0000, Arnd Bergmann wrote:
> I'm travelling at the moment, but can take it when I get back.
> 
> If you want to be sure it doesn't get lost, please send the
> patch (with the Acks) to soc at kernel.org?and it will end up
> in patchwork.

I'll do it!

-- 
Alexander Sverdlin.



From andrea.porta at suse.com  Mon Feb  5 02:25:06 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Mon,  5 Feb 2024 11:25:06 +0100
Subject: [PATCH 06/12] dmaengine: bcm2835: Use to_bcm2711_cbaddr where relevant
In-Reply-To: <04fa6114-3394-4e1e-84b8-9552f3ec398d@broadcom.com>
References: <04fa6114-3394-4e1e-84b8-9552f3ec398d@broadcom.com>
Message-ID: <20240205102506.30039-1-andrea.porta@suse.com>

>> From: Maxime Ripard <maxime at cerno.tech>
>> 
>> bcm2711_dma40_memcpy has some code strictly equivalent to the
>> to_bcm2711_cbaddr() function. Let's use it instead.
>> 
>> Signed-off-by: Maxime Ripard <maxime at cerno.tech>

>Where is the full patch series?

Hi Florian,
sorry, what do you mean with 'where is the full patch series', exactly?


From mark.rutland at arm.com  Mon Feb  5 02:28:57 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 5 Feb 2024 10:28:57 +0000
Subject: Question about the ipi_raise filter usage and output
In-Reply-To: <CAJNi4rMpt88Gz+149wR9crzApmfUEfpS05sbOgAvOhzh2+Brbg@mail.gmail.com>
References: <CAJNi4rMpt88Gz+149wR9crzApmfUEfpS05sbOgAvOhzh2+Brbg@mail.gmail.com>
Message-ID: <ZcC4aWWKFU1NgrZM@FVFF77S0Q05N>

On Mon, Feb 05, 2024 at 05:57:29PM +0800, richard clark wrote:
> Hi guys,
> 
> With the ipi_raise event enabled and filtered with:
> echo 'reason == "Function call interrupts"' > filter, then the 'cat
> trace' output below messages:
> ...
> insmod-3355    [010] ....1.. 24479.230381: ipi_raise:
> target_mask=00000000,00000bff (Function call interrupts)
> ...
> The above output is triggered by my kernel module where it will smp
> cross call a remote function from cpu#10 to cpu#11, for the
> 'target_mask' value, what does the '00000000,00000bff' mean?

That's a cpumask bitmap: 0xbff is 0b1011_1111_1111, which is:

     ,- CPU 10
     |
    1011_1111_1111
    | '__________'
    |      |
    |      `- CPUs 9 to 0
    |
    `- CPU 11

Note that bitmap has CPUs 0-9 and CPU 11 set, but CPU 10 is not set.

I suspect your kernel module has generated the bitmap incorrectly; it looks
like you have a mask for CPUs 0-11 minus a mask for CPU 10?

For CPUs 10 and 11, that should be 0xc00 / 0b1100_0000_0000.

>  ~~~~~~~~~~~~~~
> 
> Another question is for the filter, I'd like to catch the IPI only
> happening on cpu#11 *AND* a remote function call, so how to write the
> 'target_cpus' in the filter expression?
> 
> I try to write below:
> echo 'target_cpus == 11 && reason == "Function call interrupts"' >
> events/ipi/ipi_raise/filter

The '=' checks if the target_cpus bitmap *only* contains CPU 11. If the cpumask
contains other CPUs, the filter will skip the call.

I believe you can use '&' to check whether a cpumask contains a CPU, e.g.

	'target_cpus & 11'

Thanks,
Mark.


From hverkuil-cisco at xs4all.nl  Mon Feb  5 02:29:01 2024
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Mon, 5 Feb 2024 11:29:01 +0100
Subject: [PATCH 17/17] linux: v4l2-vp9.h: Fix kerneldoc
In-Reply-To: <ZbTTb-SdK-EubGdc@valkosipuli.retiisi.eu>
References: <20240126-gix-mtk-warnings-v1-0-eed7865fce18@chromium.org>
 <20240126-gix-mtk-warnings-v1-17-eed7865fce18@chromium.org>
 <ZbTTb-SdK-EubGdc@valkosipuli.retiisi.eu>
Message-ID: <201ae1d1-1e03-40e2-9cc4-49df70abb8da@xs4all.nl>

On 27/01/2024 10:57, Sakari Ailus wrote:
> Hi Ricardo,
> 
> On Fri, Jan 26, 2024 at 11:16:16PM +0000, Ricardo Ribalda wrote:
>> Kerneldoc cannot understand arrays defined like
>> v4l2_frame_symbol_counts.
>>
>> Adding an asterisk to the name does do the trick.
>>
>> Disable the kerneldoc notation for now, it is already ignored:
>> https://docs.kernel.org/search.html?q=v4l2_vp9_frame_symbol_counts
> 
> Wouldn't it be nicer to fix kerneldoc instead? It might not be difficult at
> all.
> 
> Feel free to, but I can also give it a try.
> 

It would be nice to have this fixed in kerneldoc itself. I'm holding this
patch back for two weeks to see if someone wants to work on kerneldoc.

If not, then I'll take this anyway to fix the noise in our build.

Note that while this header is indeed ignored in the documentation, that
is really more a bug and it would be nice to actually include this header
somewhere in our documentation. So fixing these kerneldoc warnings one way
or another is something that we should do.

Regards,

	Hans


From m.shams at samsung.com  Mon Feb  5 00:11:54 2024
From: m.shams at samsung.com (Tamseel Shams)
Date: Mon, 5 Feb 2024 13:41:54 +0530
Subject: [PATCH 1/2] serial: samsung: honor fifosize from dts at first
In-Reply-To: <bd253c6d-999c-4ba6-a80d-c7e077d1261a@linaro.org>
References: <CGME20240202212456epcas5p15589813cd79526e9d0c444082e2f0e51@epcas5p1.samsung.com>
	<20240202212448.74840-1-m.shams@samsung.com>
	<bd253c6d-999c-4ba6-a80d-c7e077d1261a@linaro.org>
Message-ID: <0b2201da580a$fcb94b10$f62be130$@samsung.com>



> -----Original Message-----
> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at linaro.org]
> Sent: 05 February 2024 13:10
> To: Tamseel Shams <m.shams at samsung.com>; alim.akhtar at samsung.com;
> linux-fsd at tesla.com; robh+dt at kernel.org;
> krzysztof.kozlowski+dt at linaro.org; conor+dt at kernel.org;
> gregkh at linuxfoundation.org; jirislaby at kernel.org
> Cc: linux-arm-kernel at lists.infradead.org; linux-samsung-
> soc at vger.kernel.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-serial at vger.kernel.org
> Subject: Re: [PATCH 1/2] serial: samsung: honor fifosize from dts at first
> 
> On 02/02/2024 22:24, Tamseel Shams wrote:
> > Currently for platforms which passes UART fifosize from DT gets
> > override by local driver structure "s3c24xx_serial_drv_data", which is
> > not indentded. Change the code to honor fifosize from device tree at
> > first.
> >
> > Signed-off-by: Tamseel Shams <m.shams at samsung.com>
> > ---
> >  drivers/tty/serial/samsung_tty.c | 14 ++++++++------
> >  1 file changed, 8 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/tty/serial/samsung_tty.c
> > b/drivers/tty/serial/samsung_tty.c
> > index 71d17d804fda..e4c4c9f4f9b0 100644
> > --- a/drivers/tty/serial/samsung_tty.c
> > +++ b/drivers/tty/serial/samsung_tty.c
> > @@ -1990,8 +1990,7 @@ static int s3c24xx_serial_probe(struct
> platform_device *pdev)
> >  	}
> >
> >  	if (np) {
> > -		of_property_read_u32(np,
> > -			"samsung,uart-fifosize", &ourport->port.fifosize);
> > +		ret = of_property_read_u32(np, "samsung,uart-fifosize",
> > +&ourport->port.fifosize);
> >
> >  		if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
> >  			switch (prop) {
> > @@ -2009,10 +2008,13 @@ static int s3c24xx_serial_probe(struct
> platform_device *pdev)
> >  		}
> >  	}
> >
> > -	if (ourport->drv_data->fifosize[index])
> > -		ourport->port.fifosize = ourport->drv_data->fifosize[index];
> > -	else if (ourport->info->fifosize)
> > -		ourport->port.fifosize = ourport->info->fifosize;
> 
> I think ret is not initialized here.
> 
> 
Thanks for review. Will fix it in the version.


Thanks & Regards
Tamseel Shams 





From m.shams at samsung.com  Mon Feb  5 00:12:49 2024
From: m.shams at samsung.com (Tamseel Shams)
Date: Mon, 5 Feb 2024 13:42:49 +0530
Subject: [PATCH 2/2] arm64: dts: fsd: Add fifosize for UART in Device
 Tree
In-Reply-To: <6980c4d5-78a2-4c14-b21e-a5ed1e4d5675@linaro.org>
References: <20240202212448.74840-1-m.shams@samsung.com>
	<CGME20240202212459epcas5p2e1703c35ebe9302ac5b2f3d3fcd853c0@epcas5p2.samsung.com>
	<20240202212448.74840-2-m.shams@samsung.com>
	<6980c4d5-78a2-4c14-b21e-a5ed1e4d5675@linaro.org>
Message-ID: <0dc501da580b$1dde1870$599a4950$@samsung.com>



> -----Original Message-----
> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at linaro.org]
> Sent: 05 February 2024 13:11
> To: Tamseel Shams <m.shams at samsung.com>; alim.akhtar at samsung.com;
> linux-fsd at tesla.com; robh+dt at kernel.org;
> krzysztof.kozlowski+dt at linaro.org; conor+dt at kernel.org;
> gregkh at linuxfoundation.org; jirislaby at kernel.org
> Cc: linux-arm-kernel at lists.infradead.org; linux-samsung-
> soc at vger.kernel.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-serial at vger.kernel.org
> Subject: Re: [PATCH 2/2] arm64: dts: fsd: Add fifosize for UART in Device Tree
> 
> On 02/02/2024 22:24, Tamseel Shams wrote:
> > UART in FSD SoC has fifosize of 64 bytes.
> > Set fifosize as 64 bytes for UART from Device Tree.
> >
> > Signed-off-by: Tamseel Shams <m.shams at samsung.com>
> > ---
> >  arch/arm64/boot/dts/tesla/fsd.dtsi | 2 ++
> 
> Please split SoC changes from patches sent to serial, so it will be easy to apply
> for Greg and others.
> 
> Unless you want to say that there is dependency, but there cannot be such -
> it would be a NAK.
> 
Thanks for review. Will take care of this the next version.

Thanks & Regards,
Tamseel Shams



From m.shams at samsung.com  Mon Feb  5 00:24:34 2024
From: m.shams at samsung.com (Tamseel Shams)
Date: Mon,  5 Feb 2024 13:54:34 +0530
Subject: [PATCH v2] serial: samsung: honor fifosize from dts at first
References: <CGME20240205082441epcas5p1e904f4f95852de3fd8663742ed5131df@epcas5p1.samsung.com>
Message-ID: <20240205082434.36531-1-m.shams@samsung.com>

Currently for platforms which passes UART fifosize from DT gets
override by local driver structure "s3c24xx_serial_drv_data",
which is not intended. Change the code to honor fifosize from
device tree at first.

Signed-off-by: Tamseel Shams <m.shams at samsung.com>
---
Change Log:
v1 -> v2:
Acknowledged Krzysztof's comments
Initialized "ret" variable

 drivers/tty/serial/samsung_tty.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 71d17d804fda..e5dc2c32b1bd 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -1952,7 +1952,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	struct s3c24xx_uart_port *ourport;
 	int index = probe_index;
-	int ret, prop = 0;
+	int ret = 1, prop = 0;
 
 	if (np) {
 		ret = of_alias_get_id(np, "serial");
@@ -1990,8 +1990,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 	}
 
 	if (np) {
-		of_property_read_u32(np,
-			"samsung,uart-fifosize", &ourport->port.fifosize);
+		ret = of_property_read_u32(np, "samsung,uart-fifosize", &ourport->port.fifosize);
 
 		if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
 			switch (prop) {
@@ -2009,10 +2008,13 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (ourport->drv_data->fifosize[index])
-		ourport->port.fifosize = ourport->drv_data->fifosize[index];
-	else if (ourport->info->fifosize)
-		ourport->port.fifosize = ourport->info->fifosize;
+	if (ret) {
+		if (ourport->drv_data->fifosize[index])
+			ourport->port.fifosize = ourport->drv_data->fifosize[index];
+		else if (ourport->info->fifosize)
+			ourport->port.fifosize = ourport->info->fifosize;
+	}
+
 	ourport->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_SAMSUNG_CONSOLE);
 
 	/*
-- 
2.17.1



From m.shams at samsung.com  Mon Feb  5 00:26:25 2024
From: m.shams at samsung.com (Tamseel Shams)
Date: Mon,  5 Feb 2024 13:56:25 +0530
Subject: [PATCH v2] arm64: dts: fsd: Add fifosize for UART in Device Tree
References: <CGME20240205082631epcas5p170b45d20431bfe0b9410caf470216e92@epcas5p1.samsung.com>
Message-ID: <20240205082625.39259-1-m.shams@samsung.com>

UART in FSD SoC has fifosize of 64 bytes.
Set fifosize as 64 bytes for UART from Device Tree.

Signed-off-by: Tamseel Shams <m.shams at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index aaffb50b8b60..047a83cee603 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -601,6 +601,7 @@
 			clocks = <&clock_peric PERIC_PCLK_UART0>,
 				 <&clock_peric PERIC_SCLK_UART0>;
 			clock-names = "uart", "clk_uart_baud0";
+			samsung,uart-fifosize = <64>;
 			status = "disabled";
 		};
 
@@ -613,6 +614,7 @@
 			clocks = <&clock_peric PERIC_PCLK_UART1>,
 				 <&clock_peric PERIC_SCLK_UART1>;
 			clock-names = "uart", "clk_uart_baud0";
+			samsung,uart-fifosize = <64>;
 			status = "disabled";
 		};
 
-- 
2.17.1



From maz at kernel.org  Mon Feb  5 02:34:07 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:07 +0000
Subject: [PATCH v3 02/26] KVM: arm64: Add feature checking helpers
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-3-maz@kernel.org>

In order to make it easier to check whether a particular feature
is exposed to a guest, add a new set of helpers, with kvm_has_feat()
being the most useful.

Let's start making use of them in the PMU code (courtesy of Oliver).
Follow-up changes will introduce additional use patterns.

Co-developed--by: Oliver Upton <oliver.upton at linux.dev>
Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 44 +++++++++++++++++++++++++++++++
 arch/arm64/kvm/pmu-emul.c         | 11 ++++----
 arch/arm64/kvm/sys_regs.c         |  6 ++---
 include/kvm/arm_pmu.h             | 11 --------
 4 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 21c57b812569..527da3d2cedb 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1233,4 +1233,48 @@ static inline void kvm_hyp_reserve(void) { }
 void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
 bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
 
+#define __expand_field_sign_unsigned(id, fld, val)			\
+	((u64)SYS_FIELD_VALUE(id, fld, val))
+
+#define __expand_field_sign_signed(id, fld, val)			\
+	({								\
+		u64 __val = SYS_FIELD_VALUE(id, fld, val);		\
+		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
+	})
+
+#define expand_field_sign(id, fld, val)					\
+	(id##_##fld##_SIGNED ?						\
+	 __expand_field_sign_signed(id, fld, val) :			\
+	 __expand_field_sign_unsigned(id, fld, val))
+
+#define get_idreg_field_unsigned(kvm, id, fld)				\
+	({								\
+		u64 __val = IDREG((kvm), SYS_##id);			\
+		FIELD_GET(id##_##fld##_MASK, __val);			\
+	})
+
+#define get_idreg_field_signed(kvm, id, fld)				\
+	({								\
+		u64 __val = get_idreg_field_unsigned(kvm, id, fld);	\
+		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
+	})
+
+#define get_idreg_field_enum(kvm, id, fld)				\
+	get_idreg_field_unsigned(kvm, id, fld)
+
+#define get_idreg_field(kvm, id, fld)					\
+	(id##_##fld##_SIGNED ?						\
+	 get_idreg_field_signed(kvm, id, fld) :				\
+	 get_idreg_field_unsigned(kvm, id, fld))
+
+#define kvm_has_feat(kvm, id, fld, limit)				\
+	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit))
+
+#define kvm_has_feat_enum(kvm, id, fld, val)				\
+	(get_idreg_field_unsigned((kvm), id, fld) == __expand_field_sign_unsigned(id, fld, val))
+
+#define kvm_has_feat_range(kvm, id, fld, min, max)			\
+	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
+	 get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 3d9467ff73bc..925522470b2b 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -64,12 +64,11 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm)
 {
 	u64 mask = ARMV8_PMU_EXCLUDE_EL1 | ARMV8_PMU_EXCLUDE_EL0 |
 		   kvm_pmu_event_mask(kvm);
-	u64 pfr0 = IDREG(kvm, SYS_ID_AA64PFR0_EL1);
 
-	if (SYS_FIELD_GET(ID_AA64PFR0_EL1, EL2, pfr0))
+	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL2, IMP))
 		mask |= ARMV8_PMU_INCLUDE_EL2;
 
-	if (SYS_FIELD_GET(ID_AA64PFR0_EL1, EL3, pfr0))
+	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL3, IMP))
 		mask |= ARMV8_PMU_EXCLUDE_NS_EL0 |
 			ARMV8_PMU_EXCLUDE_NS_EL1 |
 			ARMV8_PMU_EXCLUDE_EL3;
@@ -83,8 +82,10 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm)
  */
 static bool kvm_pmc_is_64bit(struct kvm_pmc *pmc)
 {
+	struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc);
+
 	return (pmc->idx == ARMV8_PMU_CYCLE_IDX ||
-		kvm_pmu_is_3p5(kvm_pmc_to_vcpu(pmc)));
+		kvm_has_feat(vcpu->kvm, ID_AA64DFR0_EL1, PMUVer, V3P5));
 }
 
 static bool kvm_pmc_has_64bit_overflow(struct kvm_pmc *pmc)
@@ -556,7 +557,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val)
 		return;
 
 	/* Fixup PMCR_EL0 to reconcile the PMU version and the LP bit */
-	if (!kvm_pmu_is_3p5(vcpu))
+	if (!kvm_has_feat(vcpu->kvm, ID_AA64DFR0_EL1, PMUVer, V3P5))
 		val &= ~ARMV8_PMU_PMCR_LP;
 
 	/* The reset bits don't indicate any state, and shouldn't be saved. */
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 041b11825578..3c31f8cb9eef 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -505,10 +505,9 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
 			  struct sys_reg_params *p,
 			  const struct sys_reg_desc *r)
 {
-	u64 val = IDREG(vcpu->kvm, SYS_ID_AA64MMFR1_EL1);
 	u32 sr = reg_to_encoding(r);
 
-	if (!(val & (0xfUL << ID_AA64MMFR1_EL1_LO_SHIFT))) {
+	if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR1_EL1, LO, IMP)) {
 		kvm_inject_undefined(vcpu);
 		return false;
 	}
@@ -2748,8 +2747,7 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
 		return ignore_write(vcpu, p);
 	} else {
 		u64 dfr = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1);
-		u64 pfr = IDREG(vcpu->kvm, SYS_ID_AA64PFR0_EL1);
-		u32 el3 = !!SYS_FIELD_GET(ID_AA64PFR0_EL1, EL3, pfr);
+		u32 el3 = kvm_has_feat(vcpu->kvm, ID_AA64PFR0_EL1, EL3, IMP);
 
 		p->regval = ((SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr) << 28) |
 			     (SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, dfr) << 24) |
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 4b9d8fb393a8..eb4c369a79eb 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -90,16 +90,6 @@ void kvm_vcpu_pmu_resync_el0(void);
 			vcpu->arch.pmu.events = *kvm_get_pmu_events();	\
 	} while (0)
 
-/*
- * Evaluates as true when emulating PMUv3p5, and false otherwise.
- */
-#define kvm_pmu_is_3p5(vcpu) ({						\
-	u64 val = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1);		\
-	u8 pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer, val);	\
-									\
-	pmuver >= ID_AA64DFR0_EL1_PMUVer_V3P5;				\
-})
-
 u8 kvm_arm_pmu_get_pmuver_limit(void);
 u64 kvm_pmu_evtyper_mask(struct kvm *kvm);
 int kvm_arm_set_default_pmu(struct kvm *kvm);
@@ -168,7 +158,6 @@ static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
 }
 
 #define kvm_vcpu_has_pmu(vcpu)		({ false; })
-#define kvm_pmu_is_3p5(vcpu)		({ false; })
 static inline void kvm_pmu_update_vcpu_events(struct kvm_vcpu *vcpu) {}
 static inline void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) {}
 static inline void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) {}
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:08 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:08 +0000
Subject: [PATCH v3 03/26] KVM: arm64: nv: Add sanitising to VNCR-backed sysregs
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-4-maz@kernel.org>

VNCR-backed "registers" are actually only memory. Which means that
there is zero control over what the guest can write, and that it
is the hypervisor's job to actually sanitise the content of the
backing store. Yeah, this is fun.

In order to preserve some form of sanity, add a repainting mechanism
that makes use of a per-VM set of RES0/RES1 masks, one pair per VNCR
register. These masks get applied on access to the backing store via
__vcpu_sys_reg(), ensuring that the state that is consumed by KVM is
correct.

So far, nothing populates these masks, but stay tuned.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 22 ++++++++++++++++-
 arch/arm64/kvm/arm.c              |  1 +
 arch/arm64/kvm/nested.c           | 41 ++++++++++++++++++++++++++++++-
 3 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 527da3d2cedb..8cda003d6267 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -238,6 +238,8 @@ static inline u16 kvm_mpidr_index(struct kvm_mpidr_data *data, u64 mpidr)
 	return index;
 }
 
+struct kvm_sysreg_masks;
+
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
 
@@ -312,6 +314,9 @@ struct kvm_arch {
 #define KVM_ARM_ID_REG_NUM	(IDREG_IDX(sys_reg(3, 0, 0, 7, 7)) + 1)
 	u64 id_regs[KVM_ARM_ID_REG_NUM];
 
+	/* Masks for VNCR-baked sysregs */
+	struct kvm_sysreg_masks	*sysreg_masks;
+
 	/*
 	 * For an untrusted host VM, 'pkvm.handle' is used to lookup
 	 * the associated pKVM instance in the hypervisor.
@@ -474,6 +479,13 @@ enum vcpu_sysreg {
 	NR_SYS_REGS	/* Nothing after this line! */
 };
 
+struct kvm_sysreg_masks {
+	struct {
+		u64	res0;
+		u64	res1;
+	} mask[NR_SYS_REGS - __VNCR_START__];
+};
+
 struct kvm_cpu_context {
 	struct user_pt_regs regs;	/* sp = sp_el0 */
 
@@ -868,7 +880,15 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
 
 #define ctxt_sys_reg(c,r)	(*__ctxt_sys_reg(c,r))
 
-#define __vcpu_sys_reg(v,r)	(ctxt_sys_reg(&(v)->arch.ctxt, (r)))
+u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg);
+#define __vcpu_sys_reg(v,r)						\
+	(*({								\
+		const struct kvm_cpu_context *ctxt = &(v)->arch.ctxt;	\
+		u64 *__r = __ctxt_sys_reg(ctxt, (r));			\
+		if (vcpu_has_nv((v)) && (r) >= __VNCR_START__)		\
+			*__r = kvm_vcpu_sanitise_vncr_reg((v), (r));	\
+		__r;							\
+	}))
 
 u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg);
 void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a25265aca432..c063e84fc72c 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -206,6 +206,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 		pkvm_destroy_hyp_vm(kvm);
 
 	kfree(kvm->arch.mpidr_data);
+	kfree(kvm->arch.sysreg_masks);
 	kvm_destroy_vcpus(kvm);
 
 	kvm_unshare_hyp(kvm, kvm + 1);
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index d55e809e26cb..c976cd4b8379 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -163,15 +163,54 @@ static u64 limit_nv_id_reg(u32 id, u64 val)
 
 	return val;
 }
+
+u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg sr)
+{
+	u64 v = ctxt_sys_reg(&vcpu->arch.ctxt, sr);
+	struct kvm_sysreg_masks *masks;
+
+	masks = vcpu->kvm->arch.sysreg_masks;
+
+	if (masks) {
+		sr -= __VNCR_START__;
+
+		v &= ~masks->mask[sr].res0;
+		v |= masks->mask[sr].res1;
+	}
+
+	return v;
+}
+
+static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
+{
+	int i = sr - __VNCR_START__;
+
+	kvm->arch.sysreg_masks->mask[i].res0 = res0;
+	kvm->arch.sysreg_masks->mask[i].res1 = res1;
+}
+
 int kvm_init_nv_sysregs(struct kvm *kvm)
 {
+	int ret = 0;
+
 	mutex_lock(&kvm->arch.config_lock);
 
+	if (kvm->arch.sysreg_masks)
+		goto out;
+
+	kvm->arch.sysreg_masks = kzalloc(sizeof(*(kvm->arch.sysreg_masks)),
+					 GFP_KERNEL);
+	if (!kvm->arch.sysreg_masks) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
 	for (int i = 0; i < KVM_ARM_ID_REG_NUM; i++)
 		kvm->arch.id_regs[i] = limit_nv_id_reg(IDX_IDREG(i),
 						       kvm->arch.id_regs[i]);
 
+out:
 	mutex_unlock(&kvm->arch.config_lock);
 
-	return 0;
+	return ret;
 }
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:14 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:14 +0000
Subject: [PATCH v3 09/26] KVM: arm64: nv: Correctly handle negative polarity FGTs
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-10-maz@kernel.org>

Negative trap bits are a massive pain. They are, on the surface,
indistinguishable from RES0 bits. Do you trap? or do you ignore?

Thankfully, we now have the right infrastructure to check for RES0
bits as long as the register is backed by VNCR, which is the case
for the FGT registers.

Use that information as a discriminant when handling a trap that
is potentially caused by a FGT.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 59 +++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 8a1cfcf553a2..ef46c2e45307 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1892,9 +1892,61 @@ static enum trap_behaviour compute_trap_behaviour(struct kvm_vcpu *vcpu,
 	return __compute_trap_behaviour(vcpu, tc.cgt, b);
 }
 
-static bool check_fgt_bit(u64 val, const union trap_config tc)
+static u64 kvm_get_sysreg_res0(struct kvm *kvm, enum vcpu_sysreg sr)
 {
-	return ((val >> tc.bit) & 1) == tc.pol;
+	struct kvm_sysreg_masks *masks;
+
+	/* Only handle the VNCR-backed regs for now */
+	if (sr < __VNCR_START__)
+		return 0;
+
+	masks = kvm->arch.sysreg_masks;
+
+	return masks->mask[sr - __VNCR_START__].res0;
+}
+
+static bool check_fgt_bit(struct kvm *kvm, bool is_read,
+			  u64 val, const union trap_config tc)
+{
+	enum vcpu_sysreg sr;
+
+	if (tc.pol)
+		return (val & BIT(tc.bit));
+
+	/*
+	 * FGTs with negative polarities are an absolute nightmare, as
+	 * we need to evaluate the bit in the light of the feature
+	 * that defines it. WTF were they thinking?
+	 *
+	 * So let's check if the bit has been earmarked as RES0, as
+	 * this indicates an unimplemented feature.
+	 */
+	if (val & BIT(tc.bit))
+		return false;
+
+	switch ((enum fgt_group_id)tc.fgt) {
+	case HFGxTR_GROUP:
+		sr = is_read ? HFGRTR_EL2 : HFGWTR_EL2;
+		break;
+
+	case HDFGRTR_GROUP:
+		sr = is_read ? HDFGRTR_EL2 : HDFGWTR_EL2;
+		break;
+
+	case HAFGRTR_GROUP:
+		sr = HAFGRTR_EL2;
+		break;
+
+	case HFGITR_GROUP:
+		sr = HFGITR_EL2;
+		break;
+
+	default:
+		WARN_ONCE(1, "Unhandled FGT group");
+		return false;
+	}
+
+	return !(kvm_get_sysreg_res0(kvm, sr) & BIT(tc.bit));
 }
 
 bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
@@ -1969,7 +2021,8 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 		return false;
 	}
 
-	if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(val, tc))
+	if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(vcpu->kvm, is_read,
+							val, tc))
 		goto inject;
 
 	b = compute_trap_behaviour(vcpu, tc);
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:11 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:11 +0000
Subject: [PATCH v3 06/26] KVM: arm64: nv: Add sanitising to VNCR-backed HCRX_EL2
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-7-maz@kernel.org>

Just like its little friends, HCRX_EL2 gets the feature set treatment
when backed by VNCR.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/nested.c | 42 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 31c4ce0439d6..f035a80d9fda 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -265,6 +265,48 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		res1 |= HCR_E2H;
 	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
 
+	/* HCRX_EL2 */
+	res0 = HCRX_EL2_RES0;
+	res1 = HCRX_EL2_RES1;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR3_EL1, PACM, TRIVIAL_IMP))
+		res0 |= HCRX_EL2_PACMEn;
+	if (!kvm_has_feat(kvm, ID_AA64PFR2_EL1, FPMR, IMP))
+		res0 |= HCRX_EL2_EnFPM;
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
+		res0 |= HCRX_EL2_GCSEn;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, SYSREG_128, IMP))
+		res0 |= HCRX_EL2_EnIDCP128;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, ADERR, DEV_ASYNC))
+		res0 |= (HCRX_EL2_EnSDERR | HCRX_EL2_EnSNERR);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, DF2, IMP))
+		res0 |= HCRX_EL2_TMEA;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, D128, IMP))
+		res0 |= HCRX_EL2_D128En;
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
+		res0 |= HCRX_EL2_PTTWI;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, SCTLRX, IMP))
+		res0 |= HCRX_EL2_SCTLR2En;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, TCRX, IMP))
+		res0 |= HCRX_EL2_TCR2En;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, MOPS, IMP))
+		res0 |= (HCRX_EL2_MSCEn | HCRX_EL2_MCE2);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, CMOW, IMP))
+		res0 |= HCRX_EL2_CMOW;
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, NMI, IMP))
+		res0 |= (HCRX_EL2_VFNMI | HCRX_EL2_VINMI | HCRX_EL2_TALLINT);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP) ||
+	    !(read_sysreg_s(SYS_SMIDR_EL1) & SMIDR_EL1_SMPS))
+		res0 |= HCRX_EL2_SMPME;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, XS, IMP))
+		res0 |= (HCRX_EL2_FGTnXS | HCRX_EL2_FnXS);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_V))
+		res0 |= HCRX_EL2_EnASR;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64))
+		res0 |= HCRX_EL2_EnALS;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA))
+		res0 |= HCRX_EL2_EnAS0;
+	set_sysreg_masks(kvm, HCRX_EL2, res0, res1);
+
 	/* HFG[RW]TR_EL2 */
 	res0 = res1 = 0;
 	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:10 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:10 +0000
Subject: [PATCH v3 05/26] KVM: arm64: nv: Add sanitising to VNCR-backed FGT sysregs
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-6-maz@kernel.org>

Fine Grained Traps are controlled by a whole bunch of features.
Each one of them must be checked and the corresponding masks
computed so that we don't let the guest apply traps it shouldn't
be using.

This takes care of HFG[IRW]TR_EL2, HDFG[RW]TR_EL2, and HAFGRTR_EL2.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/kvm/nested.c | 128 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index a8fe0f970e04..31c4ce0439d6 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -265,6 +265,134 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		res1 |= HCR_E2H;
 	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
 
+	/* HFG[RW]TR_EL2 */
+	res0 = res1 = 0;
+	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
+	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS)))
+		res0 |= (HFGxTR_EL2_APDAKey | HFGxTR_EL2_APDBKey |
+			 HFGxTR_EL2_APGAKey | HFGxTR_EL2_APIAKey |
+			 HFGxTR_EL2_APIBKey);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
+		res0 |= (HFGxTR_EL2_LORC_EL1 | HFGxTR_EL2_LOREA_EL1 |
+			 HFGxTR_EL2_LORID_EL1 | HFGxTR_EL2_LORN_EL1 |
+			 HFGxTR_EL2_LORSA_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, CSV2, CSV2_2) &&
+	    !kvm_has_feat(kvm, ID_AA64PFR1_EL1, CSV2_frac, CSV2_1p2))
+		res0 |= (HFGxTR_EL2_SCXTNUM_EL1 | HFGxTR_EL2_SCXTNUM_EL0);
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, GIC, IMP))
+		res0 |= HFGxTR_EL2_ICC_IGRPENn_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP))
+		res0 |= (HFGxTR_EL2_ERRIDR_EL1 | HFGxTR_EL2_ERRSELR_EL1 |
+			 HFGxTR_EL2_ERXFR_EL1 | HFGxTR_EL2_ERXCTLR_EL1 |
+			 HFGxTR_EL2_ERXSTATUS_EL1 | HFGxTR_EL2_ERXMISCn_EL1 |
+			 HFGxTR_EL2_ERXPFGF_EL1 | HFGxTR_EL2_ERXPFGCTL_EL1 |
+			 HFGxTR_EL2_ERXPFGCDN_EL1 | HFGxTR_EL2_ERXADDR_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA))
+		res0 |= HFGxTR_EL2_nACCDATA_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
+		res0 |= (HFGxTR_EL2_nGCS_EL0 | HFGxTR_EL2_nGCS_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
+		res0 |= (HFGxTR_EL2_nSMPRI_EL1 | HFGxTR_EL2_nTPIDR2_EL0);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
+		res0 |= HFGxTR_EL2_nRCWMASK_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
+		res0 |= (HFGxTR_EL2_nPIRE0_EL1 | HFGxTR_EL2_nPIR_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1POE, IMP))
+		res0 |= (HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nPOR_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
+		res0 |= HFGxTR_EL2_nS2POR_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, AIE, IMP))
+		res0 |= (HFGxTR_EL2_nMAIR2_EL1 | HFGxTR_EL2_nAMAIR2_EL1);
+	set_sysreg_masks(kvm, HFGRTR_EL2, res0 | __HFGRTR_EL2_RES0, res1);
+	set_sysreg_masks(kvm, HFGWTR_EL2, res0 | __HFGWTR_EL2_RES0, res1);
+
+	/* HDFG[RW]TR_EL2 */
+	res0 = res1 = 0;
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
+		res0 |= HDFGRTR_EL2_OSDLR_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
+		res0 |= (HDFGRTR_EL2_PMEVCNTRn_EL0 | HDFGRTR_EL2_PMEVTYPERn_EL0 |
+			 HDFGRTR_EL2_PMCCFILTR_EL0 | HDFGRTR_EL2_PMCCNTR_EL0 |
+			 HDFGRTR_EL2_PMCNTEN | HDFGRTR_EL2_PMINTEN |
+			 HDFGRTR_EL2_PMOVS | HDFGRTR_EL2_PMSELR_EL0 |
+			 HDFGRTR_EL2_PMMIR_EL1 | HDFGRTR_EL2_PMUSERENR_EL0 |
+			 HDFGRTR_EL2_PMCEIDn_EL0);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, IMP))
+		res0 |= (HDFGRTR_EL2_PMBLIMITR_EL1 | HDFGRTR_EL2_PMBPTR_EL1 |
+			 HDFGRTR_EL2_PMBSR_EL1 | HDFGRTR_EL2_PMSCR_EL1 |
+			 HDFGRTR_EL2_PMSEVFR_EL1 | HDFGRTR_EL2_PMSFCR_EL1 |
+			 HDFGRTR_EL2_PMSICR_EL1 | HDFGRTR_EL2_PMSIDR_EL1 |
+			 HDFGRTR_EL2_PMSIRR_EL1 | HDFGRTR_EL2_PMSLATFR_EL1 |
+			 HDFGRTR_EL2_PMBIDR_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP))
+		res0 |= (HDFGRTR_EL2_TRC | HDFGRTR_EL2_TRCAUTHSTATUS |
+			 HDFGRTR_EL2_TRCAUXCTLR | HDFGRTR_EL2_TRCCLAIM |
+			 HDFGRTR_EL2_TRCCNTVRn | HDFGRTR_EL2_TRCID |
+			 HDFGRTR_EL2_TRCIMSPECn | HDFGRTR_EL2_TRCOSLSR |
+			 HDFGRTR_EL2_TRCPRGCTLR | HDFGRTR_EL2_TRCSEQSTR |
+			 HDFGRTR_EL2_TRCSSCSRn | HDFGRTR_EL2_TRCSTATR |
+			 HDFGRTR_EL2_TRCVICTLR);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
+		res0 |= (HDFGRTR_EL2_TRBBASER_EL1 | HDFGRTR_EL2_TRBIDR_EL1 |
+			 HDFGRTR_EL2_TRBLIMITR_EL1 | HDFGRTR_EL2_TRBMAR_EL1 |
+			 HDFGRTR_EL2_TRBPTR_EL1 | HDFGRTR_EL2_TRBSR_EL1 |
+			 HDFGRTR_EL2_TRBTRG_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, BRBE, IMP))
+		res0 |= (HDFGRTR_EL2_nBRBIDR | HDFGRTR_EL2_nBRBCTL |
+			 HDFGRTR_EL2_nBRBDATA);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, V1P2))
+		res0 |= HDFGRTR_EL2_nPMSNEVFR_EL1;
+	set_sysreg_masks(kvm, HDFGRTR_EL2, res0 | HDFGRTR_EL2_RES0, res1);
+
+	/* Reuse the bits from the read-side and add the write-specific stuff */
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
+		res0 |= (HDFGWTR_EL2_PMCR_EL0 | HDFGWTR_EL2_PMSWINC_EL0);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP))
+		res0 |= HDFGWTR_EL2_TRCOSLAR;
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
+		res0 |= HDFGWTR_EL2_TRFCR_EL1;
+	set_sysreg_masks(kvm, HFGWTR_EL2, res0 | HDFGWTR_EL2_RES0, res1);
+
+	/* HFGITR_EL2 */
+	res0 = HFGITR_EL2_RES0;
+	res1 = HFGITR_EL2_RES1;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, DPB, DPB2))
+		res0 |= HFGITR_EL2_DCCVADP;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, PAN, PAN2))
+		res0 |= (HFGITR_EL2_ATS1E1RP | HFGITR_EL2_ATS1E1WP);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+		res0 |= (HFGITR_EL2_TLBIRVAALE1OS | HFGITR_EL2_TLBIRVALE1OS |
+			 HFGITR_EL2_TLBIRVAAE1OS | HFGITR_EL2_TLBIRVAE1OS |
+			 HFGITR_EL2_TLBIVAALE1OS | HFGITR_EL2_TLBIVALE1OS |
+			 HFGITR_EL2_TLBIVAAE1OS | HFGITR_EL2_TLBIASIDE1OS |
+			 HFGITR_EL2_TLBIVAE1OS | HFGITR_EL2_TLBIVMALLE1OS);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
+		res0 |= (HFGITR_EL2_TLBIRVAALE1 | HFGITR_EL2_TLBIRVALE1 |
+			 HFGITR_EL2_TLBIRVAAE1 | HFGITR_EL2_TLBIRVAE1 |
+			 HFGITR_EL2_TLBIRVAALE1IS | HFGITR_EL2_TLBIRVALE1IS |
+			 HFGITR_EL2_TLBIRVAAE1IS | HFGITR_EL2_TLBIRVAE1IS |
+			 HFGITR_EL2_TLBIRVAALE1OS | HFGITR_EL2_TLBIRVALE1OS |
+			 HFGITR_EL2_TLBIRVAAE1OS | HFGITR_EL2_TLBIRVAE1OS);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, SPECRES, IMP))
+		res0 |= (HFGITR_EL2_CFPRCTX | HFGITR_EL2_DVPRCTX |
+			 HFGITR_EL2_CPPRCTX);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, BRBE, IMP))
+		res0 |= (HFGITR_EL2_nBRBINJ | HFGITR_EL2_nBRBIALL);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
+		res0 |= (HFGITR_EL2_nGCSPUSHM_EL1 | HFGITR_EL2_nGCSSTR_EL1 |
+			 HFGITR_EL2_nGCSEPP);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, SPECRES, COSP_RCTX))
+		res0 |= HFGITR_EL2_COSPRCTX;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, ATS1A, IMP))
+		res0 |= HFGITR_EL2_ATS1E1A;
+	set_sysreg_masks(kvm, HFGITR_EL2, res0, res1);
+
+	/* HAFGRTR_EL2 - not a lot to see here */
+	res0 = HAFGRTR_EL2_RES0;
+	res1 = HAFGRTR_EL2_RES1;
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1))
+		res0 |= ~(res0 | res1);
+	set_sysreg_masks(kvm, HAFGRTR_EL2, res0, res1);
 out:
 	mutex_unlock(&kvm->arch.config_lock);
 
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:05 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:05 +0000
Subject: [PATCH v3 00/26] KVM/arm64: VM configuration enforcement
Message-ID: <20240205103431.1104133-1-maz@kernel.org>

This is the third version of this configurationm enforcement series
after some heroic reviewing from Joey (again) and Suzuki. Many thanks
to both.

I think I have taken most of the feedback into account, but please
shout if I have ignored something.

* From v2: [2]

  - Fix totally broken handling of negative features by delegating the
    work that requires a functionnal brain to other people

  - Fix handling of HCR_ENSCXT as RES0 instead of RES1 (and its
    consequences...)

  - Add handling of VTTBR_EL2.CNP being RES0

  - Add a snapshot of all RES0/RES1 fields so that we can catch them
    being changed behind our backs

  - Various cleanups

* From v1: [1]
  - Fix embarrassing crash with FEAT_MOPS

  - Better error handling in the FGT code

  - Added/Fixed comments

  - Simplified the __vcpu_sys_reg() macro

  - Fixed FEAT_PIR handling

  - Folded in Oliver's PMU rework

[1] https://lore.kernel.org/all/20240122201852.262057-1-maz at kernel.org
[2] https://lore.kernel.org/all/20240130204533.693853-1-maz at kernel.org

Marc Zyngier (26):
  arm64: sysreg: Add missing ID_AA64ISAR[13]_EL1 fields and variants
  KVM: arm64: Add feature checking helpers
  KVM: arm64: nv: Add sanitising to VNCR-backed sysregs
  KVM: arm64: nv: Add sanitising to EL2 configuration registers
  KVM: arm64: nv: Add sanitising to VNCR-backed FGT sysregs
  KVM: arm64: nv: Add sanitising to VNCR-backed HCRX_EL2
  KVM: arm64: nv: Drop sanitised_sys_reg() helper
  KVM: arm64: Unify HDFG[WR]TR_GROUP FGT identifiers
  KVM: arm64: nv: Correctly handle negative polarity FGTs
  KVM: arm64: nv: Turn encoding ranges into discrete XArray stores
  KVM: arm64: Drop the requirement for XARRAY_MULTI
  KVM: arm64: nv: Move system instructions to their own sys_reg_desc
    array
  KVM: arm64: Always populate the trap configuration xarray
  KVM: arm64: Register AArch64 system register entries with the sysreg
    xarray
  KVM: arm64: Use the xarray as the primary sysreg/sysinsn walker
  KVM: arm64: Rename __check_nv_sr_forward() to triage_sysreg_trap()
  KVM: arm64: Add Fine-Grained UNDEF tracking information
  KVM: arm64: Propagate and handle Fine-Grained UNDEF bits
  KVM: arm64: Move existing feature disabling over to FGU infrastructure
  KVM: arm64: Streamline save/restore of HFG[RW]TR_EL2
  KVM: arm64: Make TLBI OS/Range UNDEF if not advertised to the guest
  KVM: arm64: Make PIR{,E0}_EL1 UNDEF if S1PIE is not advertised to the
    guest
  KVM: arm64: Make AMU sysreg UNDEF if FEAT_AMU is not advertised to the
    guest
  KVM: arm64: Make FEAT_MOPS UNDEF if not advertised to the guest
  KVM: arm64: Snapshot all non-zero RES0/RES1 sysreg fields for later
    checking
  KVM: arm64: Add debugfs file for guest's ID registers

 arch/arm64/include/asm/kvm_arm.h           |   4 +-
 arch/arm64/include/asm/kvm_host.h          |  98 +++++++-
 arch/arm64/include/asm/kvm_nested.h        |   1 -
 arch/arm64/kvm/Kconfig                     |   1 -
 arch/arm64/kvm/arm.c                       |   7 +
 arch/arm64/kvm/check-res-bits.h            | 121 ++++++++++
 arch/arm64/kvm/emulate-nested.c            | 231 +++++++++++++-----
 arch/arm64/kvm/hyp/include/hyp/switch.h    | 130 +++++-----
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h |  24 +-
 arch/arm64/kvm/nested.c                    | 267 ++++++++++++++++++++-
 arch/arm64/kvm/pmu-emul.c                  |  11 +-
 arch/arm64/kvm/sys_regs.c                  | 238 +++++++++++++++---
 arch/arm64/kvm/sys_regs.h                  |   2 +
 arch/arm64/tools/sysreg                    |   8 +-
 include/kvm/arm_pmu.h                      |  11 -
 15 files changed, 973 insertions(+), 181 deletions(-)
 create mode 100644 arch/arm64/kvm/check-res-bits.h

-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:16 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:16 +0000
Subject: [PATCH v3 11/26] KVM: arm64: Drop the requirement for XARRAY_MULTI
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-12-maz@kernel.org>

Now that we don't use xa_store_range() anymore, drop the added
complexity of XARRAY_MULTI for KVM. It is likely still pulled
in by other bits of the kernel though.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6c3c8ca73e7f..5c2a672c06a8 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -39,7 +39,6 @@ menuconfig KVM
 	select HAVE_KVM_VCPU_RUN_PID_CHANGE
 	select SCHED_INFO
 	select GUEST_PERF_EVENTS if PERF_EVENTS
-	select XARRAY_MULTI
 	help
 	  Support hosting virtualized guest machines.
 
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:09 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:09 +0000
Subject: [PATCH v3 04/26] KVM: arm64: nv: Add sanitising to EL2 configuration registers
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-5-maz@kernel.org>

We can now start making use of our sanitising masks by setting them
to values that depend on the guest's configuration.

First up are VTTBR_EL2, VTCR_EL2, VMPIDR_EL2 and HCR_EL2.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/nested.c | 58 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index c976cd4b8379..a8fe0f970e04 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -181,7 +181,7 @@ u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg sr)
 	return v;
 }
 
-static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
+static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
 {
 	int i = sr - __VNCR_START__;
 
@@ -191,6 +191,7 @@ static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u
 
 int kvm_init_nv_sysregs(struct kvm *kvm)
 {
+	u64 res0, res1;
 	int ret = 0;
 
 	mutex_lock(&kvm->arch.config_lock);
@@ -209,6 +210,61 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		kvm->arch.id_regs[i] = limit_nv_id_reg(IDX_IDREG(i),
 						       kvm->arch.id_regs[i]);
 
+	/* VTTBR_EL2 */
+	res0 = res1 = 0;
+	if (!kvm_has_feat_enum(kvm, ID_AA64MMFR1_EL1, VMIDBits, 16))
+		res0 |= GENMASK(63, 56);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, CnP, IMP))
+		res0 |= VTTBR_CNP_BIT;
+	set_sysreg_masks(kvm, VTTBR_EL2, res0, res1);
+
+	/* VTCR_EL2 */
+	res0 = GENMASK(63, 32) | GENMASK(30, 20);
+	res1 = BIT(31);
+	set_sysreg_masks(kvm, VTCR_EL2, res0, res1);
+
+	/* VMPIDR_EL2 */
+	res0 = GENMASK(63, 40) | GENMASK(30, 24);
+	res1 = BIT(31);
+	set_sysreg_masks(kvm, VMPIDR_EL2, res0, res1);
+
+	/* HCR_EL2 */
+	res0 = BIT(48);
+	res1 = HCR_RW;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, TWED, IMP))
+		res0 |= GENMASK(63, 59);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, MTE, MTE2))
+		res0 |= (HCR_TID5 | HCR_DCT | HCR_ATA);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, EVT, TTLBxS))
+		res0 |= (HCR_TTLBIS | HCR_TTLBOS);
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, CSV2, CSV2_2) &&
+	    !kvm_has_feat(kvm, ID_AA64PFR1_EL1, CSV2_frac, CSV2_1p2))
+		res0 |= HCR_ENSCXT;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, EVT, IMP))
+		res0 |= (HCR_TOCU | HCR_TICAB | HCR_TID4);
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1))
+		res0 |= HCR_AMVOFFEN;
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1))
+		res0 |= HCR_FIEN;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, FWB, IMP))
+		res0 |= HCR_FWB;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, NV2))
+		res0 |= HCR_NV2;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, IMP))
+		res0 |= (HCR_AT | HCR_NV1 | HCR_NV);
+	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
+	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS)))
+		res0 |= (HCR_API | HCR_APK);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TME, IMP))
+		res0 |= BIT(39);
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP))
+		res0 |= (HCR_TEA | HCR_TERR);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
+		res0 |= HCR_TLOR;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR4_EL1, E2H0, IMP))
+		res1 |= HCR_E2H;
+	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
+
 out:
 	mutex_unlock(&kvm->arch.config_lock);
 
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:15 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:15 +0000
Subject: [PATCH v3 10/26] KVM: arm64: nv: Turn encoding ranges into discrete XArray stores
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-11-maz@kernel.org>

In order to be able to store different values for member of an
encoding range, replace xa_store_range() calls with discrete
xa_store() calls and an encoding iterator.

We end-up using a bit more memory, but we gain some flexibility
that we will make use of shortly.

Take this opportunity to tidy up the error handling path.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/kvm/emulate-nested.c | 49 ++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index ef46c2e45307..42f5b4483c80 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1757,6 +1757,28 @@ static __init void print_nv_trap_error(const struct encoding_to_trap_config *tc,
 		err);
 }
 
+static u32 encoding_next(u32 encoding)
+{
+	u8 op0, op1, crn, crm, op2;
+
+	op0 = sys_reg_Op0(encoding);
+	op1 = sys_reg_Op1(encoding);
+	crn = sys_reg_CRn(encoding);
+	crm = sys_reg_CRm(encoding);
+	op2 = sys_reg_Op2(encoding);
+
+	if (op2 < Op2_mask)
+		return sys_reg(op0, op1, crn, crm, op2 + 1);
+	if (crm < CRm_mask)
+		return sys_reg(op0, op1, crn, crm + 1, 0);
+	if (crn < CRn_mask)
+		return sys_reg(op0, op1, crn + 1, 0, 0);
+	if (op1 < Op1_mask)
+		return sys_reg(op0, op1 + 1, 0, 0, 0);
+
+	return sys_reg(op0 + 1, 0, 0, 0, 0);
+}
+
 int __init populate_nv_trap_config(void)
 {
 	int ret = 0;
@@ -1775,23 +1797,18 @@ int __init populate_nv_trap_config(void)
 			ret = -EINVAL;
 		}
 
-		if (cgt->encoding != cgt->end) {
-			prev = xa_store_range(&sr_forward_xa,
-					      cgt->encoding, cgt->end,
-					      xa_mk_value(cgt->tc.val),
-					      GFP_KERNEL);
-		} else {
-			prev = xa_store(&sr_forward_xa, cgt->encoding,
+		for (u32 enc = cgt->encoding; enc <= cgt->end; enc = encoding_next(enc)) {
+			prev = xa_store(&sr_forward_xa, enc,
 					xa_mk_value(cgt->tc.val), GFP_KERNEL);
 			if (prev && !xa_is_err(prev)) {
 				ret = -EINVAL;
 				print_nv_trap_error(cgt, "Duplicate CGT", ret);
 			}
-		}
 
-		if (xa_is_err(prev)) {
-			ret = xa_err(prev);
-			print_nv_trap_error(cgt, "Failed CGT insertion", ret);
+			if (xa_is_err(prev)) {
+				ret = xa_err(prev);
+				print_nv_trap_error(cgt, "Failed CGT insertion", ret);
+			}
 		}
 	}
 
@@ -1804,6 +1821,7 @@ int __init populate_nv_trap_config(void)
 	for (int i = 0; i < ARRAY_SIZE(encoding_to_fgt); i++) {
 		const struct encoding_to_trap_config *fgt = &encoding_to_fgt[i];
 		union trap_config tc;
+		void *prev;
 
 		if (fgt->tc.fgt >= __NR_FGT_GROUP_IDS__) {
 			ret = -EINVAL;
@@ -1818,8 +1836,13 @@ int __init populate_nv_trap_config(void)
 		}
 
 		tc.val |= fgt->tc.val;
-		xa_store(&sr_forward_xa, fgt->encoding,
-			 xa_mk_value(tc.val), GFP_KERNEL);
+		prev = xa_store(&sr_forward_xa, fgt->encoding,
+				xa_mk_value(tc.val), GFP_KERNEL);
+
+		if (xa_is_err(prev)) {
+			ret = xa_err(prev);
+			print_nv_trap_error(fgt, "Failed FGT insertion", ret);
+		}
 	}
 
 	kvm_info("nv: %ld fine grained trap handlers\n",
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:18 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:18 +0000
Subject: [PATCH v3 13/26] KVM: arm64: Always populate the trap configuration xarray
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-14-maz@kernel.org>

As we are going to rely more and more on the global xarray that
contains the trap configuration, always populate it, even in the
non-NV case.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 70043bd78cd4..57f3d0c53fc3 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3995,8 +3995,5 @@ int __init kvm_sys_reg_table_init(void)
 	if (!first_idreg)
 		return -EINVAL;
 
-	if (kvm_get_mode() == KVM_MODE_NV)
-		return populate_nv_trap_config();
-
-	return 0;
+	return populate_nv_trap_config();
 }
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:17 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:17 +0000
Subject: [PATCH v3 12/26] KVM: arm64: nv: Move system instructions to their own sys_reg_desc array
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-13-maz@kernel.org>

As NV results in a bunch of system instructions being trapped, it makes
sense to pull the system instructions into their own little array, where
they will eventually be joined by AT, TLBI and a bunch of other CMOs.

Based on an initial patch by Jintack Lim.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 59 +++++++++++++++++++++++++++++----------
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 3c31f8cb9eef..70043bd78cd4 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2196,16 +2196,6 @@ static u64 reset_hcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
  * guest...
  */
 static const struct sys_reg_desc sys_reg_descs[] = {
-	{ SYS_DESC(SYS_DC_ISW), access_dcsw },
-	{ SYS_DESC(SYS_DC_IGSW), access_dcgsw },
-	{ SYS_DESC(SYS_DC_IGDSW), access_dcgsw },
-	{ SYS_DESC(SYS_DC_CSW), access_dcsw },
-	{ SYS_DESC(SYS_DC_CGSW), access_dcgsw },
-	{ SYS_DESC(SYS_DC_CGDSW), access_dcgsw },
-	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
-	{ SYS_DESC(SYS_DC_CIGSW), access_dcgsw },
-	{ SYS_DESC(SYS_DC_CIGDSW), access_dcgsw },
-
 	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 },
@@ -2737,6 +2727,18 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(SP_EL2, NULL, reset_unknown, 0),
 };
 
+static struct sys_reg_desc sys_insn_descs[] = {
+	{ SYS_DESC(SYS_DC_ISW), access_dcsw },
+	{ SYS_DESC(SYS_DC_IGSW), access_dcgsw },
+	{ SYS_DESC(SYS_DC_IGDSW), access_dcgsw },
+	{ SYS_DESC(SYS_DC_CSW), access_dcsw },
+	{ SYS_DESC(SYS_DC_CGSW), access_dcgsw },
+	{ SYS_DESC(SYS_DC_CGDSW), access_dcgsw },
+	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
+	{ SYS_DESC(SYS_DC_CIGSW), access_dcgsw },
+	{ SYS_DESC(SYS_DC_CIGDSW), access_dcgsw },
+};
+
 static const struct sys_reg_desc *first_idreg;
 
 static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
@@ -3429,6 +3431,24 @@ static bool emulate_sys_reg(struct kvm_vcpu *vcpu,
 	return false;
 }
 
+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;
+}
+
 static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
 {
 	const struct sys_reg_desc *idreg = first_idreg;
@@ -3476,7 +3496,8 @@ 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_reg -- 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)
@@ -3493,12 +3514,19 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
 	params = esr_sys64_to_params(esr);
 	params.regval = vcpu_get_reg(vcpu, Rt);
 
-	if (!emulate_sys_reg(vcpu, &params))
+	/* System registers have Op0=={2,3}, as per DDI487 J.a C5.1.2 */
+	if (params.Op0 == 2 || params.Op0 == 3) {
+		if (!emulate_sys_reg(vcpu, &params))
+			return 1;
+
+		if (!params.is_write)
+			vcpu_set_reg(vcpu, Rt, params.regval);
+
 		return 1;
+	}
 
-	if (!params.is_write)
-		vcpu_set_reg(vcpu, Rt, params.regval);
-	return 1;
+	/* Hints, PSTATE (Op0 == 0) and System instructions (Op0 == 1) */
+	return emulate_sys_instr(vcpu, &params);
 }
 
 /******************************************************************************
@@ -3952,6 +3980,7 @@ int __init kvm_sys_reg_table_init(void)
 	valid &= check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs), true);
 	valid &= check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs), true);
 	valid &= check_sysreg_table(invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs), false);
+	valid &= check_sysreg_table(sys_insn_descs, ARRAY_SIZE(sys_insn_descs), false);
 
 	if (!valid)
 		return -EINVAL;
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:19 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:19 +0000
Subject: [PATCH v3 14/26] KVM: arm64: Register AArch64 system register entries with the sysreg xarray
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-15-maz@kernel.org>

In order to reduce the number of lookups that we have to perform
when handling a sysreg, register each AArch64 sysreg descriptor
with the global xarray. The index of the descriptor is stored
as a 10 bit field in the data word.

Subsequent patches will retrieve and use the stored index.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  3 +++
 arch/arm64/kvm/emulate-nested.c   | 39 +++++++++++++++++++++++++++++--
 arch/arm64/kvm/sys_regs.c         | 11 ++++++++-
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 8cda003d6267..914fd54179bb 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1078,6 +1078,9 @@ int kvm_handle_cp10_id(struct kvm_vcpu *vcpu);
 void kvm_reset_sys_regs(struct kvm_vcpu *vcpu);
 
 int __init kvm_sys_reg_table_init(void);
+struct sys_reg_desc;
+int __init populate_sysreg_config(const struct sys_reg_desc *sr,
+				  unsigned int idx);
 int __init populate_nv_trap_config(void);
 
 bool lock_all_vcpus(struct kvm *kvm);
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 42f5b4483c80..ddf760b4dda5 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -427,12 +427,14 @@ static const complex_condition_check ccc[] = {
  * [19:14]	bit number in the FGT register (6 bits)
  * [20]		trap polarity (1 bit)
  * [25:21]	FG filter (5 bits)
- * [62:26]	Unused (37 bits)
+ * [35:26]	Main SysReg table index (10 bits)
+ * [62:36]	Unused (27 bits)
  * [63]		RES0 - Must be zero, as lost on insertion in the xarray
  */
 #define TC_CGT_BITS	10
 #define TC_FGT_BITS	4
 #define TC_FGF_BITS	5
+#define TC_SRI_BITS	10
 
 union trap_config {
 	u64	val;
@@ -442,7 +444,8 @@ union trap_config {
 		unsigned long	bit:6;		 /* Bit number */
 		unsigned long	pol:1;		 /* Polarity */
 		unsigned long	fgf:TC_FGF_BITS; /* Fine Grained Filter */
-		unsigned long	unused:37;	 /* Unused, should be zero */
+		unsigned long	sri:TC_SRI_BITS; /* SysReg Index */
+		unsigned long	unused:27;	 /* Unused, should be zero */
 		unsigned long	mbz:1;		 /* Must Be Zero */
 	};
 };
@@ -1868,6 +1871,38 @@ int __init populate_nv_trap_config(void)
 	return ret;
 }
 
+int __init populate_sysreg_config(const struct sys_reg_desc *sr,
+				  unsigned int idx)
+{
+	union trap_config tc;
+	u32 encoding;
+	void *ret;
+
+	/*
+	 * 0 is a valid value for the index, but not for the storage.
+	 * We'll store (idx+1), so check against an offset'd limit.
+	 */
+	if (idx >= (BIT(TC_SRI_BITS) - 1)) {
+		kvm_err("sysreg %s (%d) out of range\n", sr->name, idx);
+		return -EINVAL;
+	}
+
+	encoding = sys_reg(sr->Op0, sr->Op1, sr->CRn, sr->CRm, sr->Op2);
+	tc = get_trap_config(encoding);
+
+	if (tc.sri) {
+		kvm_err("sysreg %s (%d) duplicate entry (%d)\n",
+			sr->name, idx - 1, tc.sri);
+		return -EINVAL;
+	}
+
+	tc.sri = idx + 1;
+	ret = xa_store(&sr_forward_xa, encoding,
+		       xa_mk_value(tc.val), GFP_KERNEL);
+
+	return xa_err(ret);
+}
+
 static enum trap_behaviour get_behaviour(struct kvm_vcpu *vcpu,
 					 const struct trap_bits *tb)
 {
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 57f3d0c53fc3..a410e99f827e 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3972,6 +3972,7 @@ int __init kvm_sys_reg_table_init(void)
 	struct sys_reg_params params;
 	bool valid = true;
 	unsigned int i;
+	int ret = 0;
 
 	/* Make sure tables are unique and in order. */
 	valid &= check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs), false);
@@ -3995,5 +3996,13 @@ int __init kvm_sys_reg_table_init(void)
 	if (!first_idreg)
 		return -EINVAL;
 
-	return populate_nv_trap_config();
+	ret = populate_nv_trap_config();
+
+	for (i = 0; !ret && i < ARRAY_SIZE(sys_reg_descs); i++)
+		ret = populate_sysreg_config(sys_reg_descs + i, i);
+
+	for (i = 0; !ret && i < ARRAY_SIZE(sys_insn_descs); i++)
+		ret = populate_sysreg_config(sys_insn_descs + i, i);
+
+	return ret;
 }
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:13 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:13 +0000
Subject: [PATCH v3 08/26] KVM: arm64: Unify HDFG[WR]TR_GROUP FGT identifiers
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-9-maz@kernel.org>

There is no reason to have separate FGT group identifiers for
the debug fine grain trapping. The sole requirement is to provide
the *names* so that the SR_FGF() macro can do its magic of picking
the correct bit definition.

So let's alias HDFGWTR_GROUP and HDFGRTR_GROUP.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 7a4a886adb9d..8a1cfcf553a2 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1010,7 +1010,7 @@ enum fgt_group_id {
 	__NO_FGT_GROUP__,
 	HFGxTR_GROUP,
 	HDFGRTR_GROUP,
-	HDFGWTR_GROUP,
+	HDFGWTR_GROUP = HDFGRTR_GROUP,
 	HFGITR_GROUP,
 	HAFGRTR_GROUP,
 
@@ -1938,7 +1938,6 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 		break;
 
 	case HDFGRTR_GROUP:
-	case HDFGWTR_GROUP:
 		if (is_read)
 			val = __vcpu_sys_reg(vcpu, HDFGRTR_EL2);
 		else
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:20 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:20 +0000
Subject: [PATCH v3 15/26] KVM: arm64: Use the xarray as the primary sysreg/sysinsn walker
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-16-maz@kernel.org>

Since we always start sysreg/sysinsn handling by searching the
xarray, use it as the source of the index in the correct sys_reg_desc
array.

This allows some cleanup, such as moving the handling of unknown
sysregs in a single location.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h |  2 +-
 arch/arm64/kvm/emulate-nested.c     | 40 +++++++++++++-----
 arch/arm64/kvm/sys_regs.c           | 63 +++++++++--------------------
 3 files changed, 50 insertions(+), 55 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 4882905357f4..68465f87d308 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -60,7 +60,7 @@ static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
 	return ttbr0 & ~GENMASK_ULL(63, 48);
 }
 
-extern bool __check_nv_sr_forward(struct kvm_vcpu *vcpu);
+extern bool __check_nv_sr_forward(struct kvm_vcpu *vcpu, int *sr_idx);
 
 int kvm_init_nv_sysregs(struct kvm *kvm);
 
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index ddf760b4dda5..5aeaa688755f 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2007,7 +2007,7 @@ static bool check_fgt_bit(struct kvm *kvm, bool is_read,
 	return !(kvm_get_sysreg_res0(kvm, sr) & BIT(tc.bit));
 }
 
-bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
+bool __check_nv_sr_forward(struct kvm_vcpu *vcpu, int *sr_index)
 {
 	union trap_config tc;
 	enum trap_behaviour b;
@@ -2015,9 +2015,6 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 	u32 sysreg;
 	u64 esr, val;
 
-	if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
-		return false;
-
 	esr = kvm_vcpu_get_esr(vcpu);
 	sysreg = esr_sys64_to_sysreg(esr);
 	is_read = (esr & ESR_ELx_SYS64_ISS_DIR_MASK) == ESR_ELx_SYS64_ISS_DIR_READ;
@@ -2028,13 +2025,16 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 	 * A value of 0 for the whole entry means that we know nothing
 	 * for this sysreg, and that it cannot be re-injected into the
 	 * nested hypervisor. In this situation, let's cut it short.
-	 *
-	 * Note that ultimately, we could also make use of the xarray
-	 * to store the index of the sysreg in the local descriptor
-	 * array, avoiding another search... Hint, hint...
 	 */
 	if (!tc.val)
-		return false;
+		goto local;
+
+	/*
+	 * If we're not nesting, immediately return to the caller, with the
+	 * sysreg index, should we have it.
+	 */
+	if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
+		goto local;
 
 	switch ((enum fgt_group_id)tc.fgt) {
 	case __NO_FGT_GROUP__:
@@ -2076,7 +2076,7 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 	case __NR_FGT_GROUP_IDS__:
 		/* Something is really wrong, bail out */
 		WARN_ONCE(1, "__NR_FGT_GROUP_IDS__");
-		return false;
+		goto local;
 	}
 
 	if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(vcpu->kvm, is_read,
@@ -2089,6 +2089,26 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 	    ((b & BEHAVE_FORWARD_WRITE) && !is_read))
 		goto inject;
 
+local:
+	if (!tc.sri) {
+		struct sys_reg_params params;
+
+		params = esr_sys64_to_params(esr);
+
+		/*
+		 * Check for the IMPDEF range, as per DDI0487 J.a,
+		 * D18.3.2 Reserved encodings for IMPLEMENTATION
+		 * DEFINED registers.
+		 */
+		if (!(params.Op0 == 3 && (params.CRn & 0b1011) == 0b1011))
+			print_sys_reg_msg(&params,
+					  "Unsupported guest access at: %lx\n",
+					  *vcpu_pc(vcpu));
+		kvm_inject_undefined(vcpu);
+		return true;
+	}
+
+	*sr_index = tc.sri - 1;
 	return false;
 
 inject:
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index a410e99f827e..bc076ef8440b 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3395,12 +3395,6 @@ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu)
 	return kvm_handle_cp_32(vcpu, &params, cp14_regs, ARRAY_SIZE(cp14_regs));
 }
 
-static bool is_imp_def_sys_reg(struct sys_reg_params *params)
-{
-	// See ARM DDI 0487E.a, section D12.3.2
-	return params->Op0 == 3 && (params->CRn & 0b1011) == 0b1011;
-}
-
 /**
  * emulate_sys_reg - Emulate a guest access to an AArch64 system register
  * @vcpu: The VCPU pointer
@@ -3409,44 +3403,22 @@ static bool is_imp_def_sys_reg(struct sys_reg_params *params)
  * Return: true if the system register access was successful, false otherwise.
  */
 static bool emulate_sys_reg(struct kvm_vcpu *vcpu,
-			   struct sys_reg_params *params)
+			    struct sys_reg_params *params)
 {
 	const struct sys_reg_desc *r;
 
 	r = find_reg(params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
-
 	if (likely(r)) {
 		perform_access(vcpu, params, r);
 		return true;
 	}
 
-	if (is_imp_def_sys_reg(params)) {
-		kvm_inject_undefined(vcpu);
-	} else {
-		print_sys_reg_msg(params,
-				  "Unsupported guest sys_reg access at: %lx [%08lx]\n",
-				  *vcpu_pc(vcpu), *vcpu_cpsr(vcpu));
-		kvm_inject_undefined(vcpu);
-	}
-	return false;
-}
-
-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));
+	print_sys_reg_msg(params,
+			  "Unsupported guest sys_reg access at: %lx [%08lx]\n",
+			  *vcpu_pc(vcpu), *vcpu_cpsr(vcpu));
+	kvm_inject_undefined(vcpu);
 
-	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;
+	return false;
 }
 
 static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
@@ -3502,31 +3474,34 @@ void kvm_reset_sys_regs(struct kvm_vcpu *vcpu)
  */
 int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
 {
+	const struct sys_reg_desc *desc = NULL;
 	struct sys_reg_params params;
 	unsigned long esr = kvm_vcpu_get_esr(vcpu);
 	int Rt = kvm_vcpu_sys_get_rt(vcpu);
+	int sr_idx;
 
 	trace_kvm_handle_sys_reg(esr);
 
-	if (__check_nv_sr_forward(vcpu))
+	if (__check_nv_sr_forward(vcpu, &sr_idx))
 		return 1;
 
 	params = esr_sys64_to_params(esr);
 	params.regval = vcpu_get_reg(vcpu, Rt);
 
 	/* System registers have Op0=={2,3}, as per DDI487 J.a C5.1.2 */
-	if (params.Op0 == 2 || params.Op0 == 3) {
-		if (!emulate_sys_reg(vcpu, &params))
-			return 1;
+	if (params.Op0 == 2 || params.Op0 == 3)
+		desc = &sys_reg_descs[sr_idx];
+	else
+		desc = &sys_insn_descs[sr_idx];
 
-		if (!params.is_write)
-			vcpu_set_reg(vcpu, Rt, params.regval);
+	perform_access(vcpu, &params, desc);
 
-		return 1;
-	}
+	/* Read from system register? */
+	if (!params.is_write &&
+	    (params.Op0 == 2 || params.Op0 == 3))
+		vcpu_set_reg(vcpu, Rt, params.regval);
 
-	/* Hints, PSTATE (Op0 == 0) and System instructions (Op0 == 1) */
-	return emulate_sys_instr(vcpu, &params);
+	return 1;
 }
 
 /******************************************************************************
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:06 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:06 +0000
Subject: [PATCH v3 01/26] arm64: sysreg: Add missing ID_AA64ISAR[13]_EL1 fields and variants
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-2-maz@kernel.org>

Despite having the control bits for FEAT_SPECRES and FEAT_PACM,
the ID registers fields are either incomplete or missing.

Fix it.

Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/tools/sysreg | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index fa3fe0856880..53daaaef46cb 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1366,6 +1366,7 @@ EndEnum
 UnsignedEnum	43:40	SPECRES
 	0b0000	NI
 	0b0001	IMP
+	0b0010	COSP_RCTX
 EndEnum
 UnsignedEnum	39:36	SB
 	0b0000	NI
@@ -1492,7 +1493,12 @@ EndEnum
 EndSysreg
 
 Sysreg	ID_AA64ISAR3_EL1	3	0	0	6	3
-Res0	63:12
+Res0	63:16
+UnsignedEnum	15:12	PACM
+	0b0000	NI
+	0b0001	TRIVIAL_IMP
+	0b0010	FULL_IMP
+EndEnum
 UnsignedEnum	11:8	TLBIW
 	0b0000	NI
 	0b0001	IMP
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:12 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:12 +0000
Subject: [PATCH v3 07/26] KVM: arm64: nv: Drop sanitised_sys_reg() helper
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-8-maz@kernel.org>

Now that we have the infrastructure to enforce a sanitised register
value depending on the VM configuration, drop the helper that only
used the architectural RES0 value.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 22 +++++++---------------
 1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 431fd429932d..7a4a886adb9d 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1897,14 +1897,6 @@ static bool check_fgt_bit(u64 val, const union trap_config tc)
 	return ((val >> tc.bit) & 1) == tc.pol;
 }
 
-#define sanitised_sys_reg(vcpu, reg)			\
-	({						\
-		u64 __val;				\
-		__val = __vcpu_sys_reg(vcpu, reg);	\
-		__val &= ~__ ## reg ## _RES0;		\
-		(__val);				\
-	})
-
 bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 {
 	union trap_config tc;
@@ -1940,25 +1932,25 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 
 	case HFGxTR_GROUP:
 		if (is_read)
-			val = sanitised_sys_reg(vcpu, HFGRTR_EL2);
+			val = __vcpu_sys_reg(vcpu, HFGRTR_EL2);
 		else
-			val = sanitised_sys_reg(vcpu, HFGWTR_EL2);
+			val = __vcpu_sys_reg(vcpu, HFGWTR_EL2);
 		break;
 
 	case HDFGRTR_GROUP:
 	case HDFGWTR_GROUP:
 		if (is_read)
-			val = sanitised_sys_reg(vcpu, HDFGRTR_EL2);
+			val = __vcpu_sys_reg(vcpu, HDFGRTR_EL2);
 		else
-			val = sanitised_sys_reg(vcpu, HDFGWTR_EL2);
+			val = __vcpu_sys_reg(vcpu, HDFGWTR_EL2);
 		break;
 
 	case HAFGRTR_GROUP:
-		val = sanitised_sys_reg(vcpu, HAFGRTR_EL2);
+		val = __vcpu_sys_reg(vcpu, HAFGRTR_EL2);
 		break;
 
 	case HFGITR_GROUP:
-		val = sanitised_sys_reg(vcpu, HFGITR_EL2);
+		val = __vcpu_sys_reg(vcpu, HFGITR_EL2);
 		switch (tc.fgf) {
 			u64 tmp;
 
@@ -1966,7 +1958,7 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 			break;
 
 		case HCRX_FGTnXS:
-			tmp = sanitised_sys_reg(vcpu, HCRX_EL2);
+			tmp = __vcpu_sys_reg(vcpu, HCRX_EL2);
 			if (tmp & HCRX_EL2_FGTnXS)
 				tc.fgt = __NO_FGT_GROUP__;
 		}
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:22 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:22 +0000
Subject: [PATCH v3 17/26] KVM: arm64: Add Fine-Grained UNDEF tracking information
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-18-maz@kernel.org>

In order to efficiently handle system register access being disabled,
and this resulting in an UNDEF exception being injected, we introduce
the (slightly dubious) concept of Fine-Grained UNDEF, modeled after
the architectural Fine-Grained Traps.

For each FGT group, we keep a 64 bit word that has the exact same
bit assignment as the corresponding FGT register, where a 1 indicates
that trapping this register should result in an UNDEF exception being
reinjected.

So far, nothing populates this information, nor sets the corresponding
trap bits.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 21 +++++++++++++++++++++
 arch/arm64/kvm/emulate-nested.c   | 12 ------------
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 914fd54179bb..c69b258fc989 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -240,9 +240,30 @@ static inline u16 kvm_mpidr_index(struct kvm_mpidr_data *data, u64 mpidr)
 
 struct kvm_sysreg_masks;
 
+enum fgt_group_id {
+	__NO_FGT_GROUP__,
+	HFGxTR_GROUP,
+	HDFGRTR_GROUP,
+	HDFGWTR_GROUP = HDFGRTR_GROUP,
+	HFGITR_GROUP,
+	HAFGRTR_GROUP,
+
+	/* Must be last */
+	__NR_FGT_GROUP_IDS__
+};
+
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
 
+	/*
+	 * Fine-Grained UNDEF, mimicking the FGT layout defined by the
+	 * architecture. We track them globally, as we present the
+	 * same feature-set to all vcpus.
+	 *
+	 * Index 0 is currently spare.
+	 */
+	u64 fgu[__NR_FGT_GROUP_IDS__];
+
 	/* Interrupt controller */
 	struct vgic_dist	vgic;
 
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 4f2a32a8f247..b67078b8271b 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1009,18 +1009,6 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
 
 static DEFINE_XARRAY(sr_forward_xa);
 
-enum fgt_group_id {
-	__NO_FGT_GROUP__,
-	HFGxTR_GROUP,
-	HDFGRTR_GROUP,
-	HDFGWTR_GROUP = HDFGRTR_GROUP,
-	HFGITR_GROUP,
-	HAFGRTR_GROUP,
-
-	/* Must be last */
-	__NR_FGT_GROUP_IDS__
-};
-
 enum fg_filter_id {
 	__NO_FGF__,
 	HCRX_FGTnXS,
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:21 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:21 +0000
Subject: [PATCH v3 16/26] KVM: arm64: Rename __check_nv_sr_forward() to triage_sysreg_trap()
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-17-maz@kernel.org>

__check_nv_sr_forward() is not specific to NV anymore, and does
a lot more. Rename it to triage_sysreg_trap(), making it plain
that its role is to handle where an exception is to be handled.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h | 1 -
 arch/arm64/kvm/emulate-nested.c     | 2 +-
 arch/arm64/kvm/sys_regs.c           | 2 +-
 arch/arm64/kvm/sys_regs.h           | 2 ++
 4 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 68465f87d308..c77d795556e1 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -60,7 +60,6 @@ static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
 	return ttbr0 & ~GENMASK_ULL(63, 48);
 }
 
-extern bool __check_nv_sr_forward(struct kvm_vcpu *vcpu, int *sr_idx);
 
 int kvm_init_nv_sysregs(struct kvm *kvm);
 
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 5aeaa688755f..4f2a32a8f247 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2007,7 +2007,7 @@ static bool check_fgt_bit(struct kvm *kvm, bool is_read,
 	return !(kvm_get_sysreg_res0(kvm, sr) & BIT(tc.bit));
 }
 
-bool __check_nv_sr_forward(struct kvm_vcpu *vcpu, int *sr_index)
+bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
 {
 	union trap_config tc;
 	enum trap_behaviour b;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index bc076ef8440b..938df5dc3684 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3482,7 +3482,7 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
 
 	trace_kvm_handle_sys_reg(esr);
 
-	if (__check_nv_sr_forward(vcpu, &sr_idx))
+	if (triage_sysreg_trap(vcpu, &sr_idx))
 		return 1;
 
 	params = esr_sys64_to_params(esr);
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index c65c129b3500..997eea21ba2a 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -233,6 +233,8 @@ int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
 int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
 			 const struct sys_reg_desc table[], unsigned int num);
 
+bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index);
+
 #define AA32(_x)	.aarch32_map = AA32_##_x
 #define Op0(_x) 	.Op0 = _x
 #define Op1(_x) 	.Op1 = _x
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:24 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:24 +0000
Subject: [PATCH v3 19/26] KVM: arm64: Move existing feature disabling over to FGU infrastructure
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-20-maz@kernel.org>

We already trap a bunch of existing features for the purpose of
disabling them (MAIR2, POR, ACCDATA, SME...).

Let's move them over to our brand new FGU infrastructure.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h       |  4 ++++
 arch/arm64/kvm/arm.c                    |  6 ++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h | 17 +++--------------
 arch/arm64/kvm/sys_regs.c               | 23 +++++++++++++++++++++++
 4 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index c69b258fc989..968a997b3f02 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -297,6 +297,8 @@ struct kvm_arch {
 #define KVM_ARCH_FLAG_TIMER_PPIS_IMMUTABLE		6
 	/* Initial ID reg values loaded */
 #define KVM_ARCH_FLAG_ID_REGS_INITIALIZED		7
+	/* Fine-Grained UNDEF initialised */
+#define KVM_ARCH_FLAG_FGU_INITIALIZED			8
 	unsigned long flags;
 
 	/* VM-wide vCPU feature set */
@@ -1107,6 +1109,8 @@ int __init populate_nv_trap_config(void);
 bool lock_all_vcpus(struct kvm *kvm);
 void unlock_all_vcpus(struct kvm *kvm);
 
+void kvm_init_sysreg(struct kvm_vcpu *);
+
 /* MMIO helpers */
 void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
 unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index c063e84fc72c..9f806c9b7d5d 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -675,6 +675,12 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
 			return ret;
 	}
 
+	/*
+	 * This needs to happen after NV has imposed its own restrictions on
+	 * the feature set
+	 */
+	kvm_init_sysreg(vcpu);
+
 	ret = kvm_timer_enable(vcpu);
 	if (ret)
 		return ret;
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index a09149fd91ed..245f9c1ca666 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -157,7 +157,7 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
 	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
-	u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0, tmp;
+	u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0;
 	u64 r_val, w_val;
 
 	CHECK_FGT_MASKS(HFGRTR_EL2);
@@ -174,13 +174,6 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	ctxt_sys_reg(hctxt, HFGRTR_EL2) = read_sysreg_s(SYS_HFGRTR_EL2);
 	ctxt_sys_reg(hctxt, HFGWTR_EL2) = read_sysreg_s(SYS_HFGWTR_EL2);
 
-	if (cpus_have_final_cap(ARM64_SME)) {
-		tmp = HFGxTR_EL2_nSMPRI_EL1_MASK | HFGxTR_EL2_nTPIDR2_EL0_MASK;
-
-		r_clr |= tmp;
-		w_clr |= tmp;
-	}
-
 	/*
 	 * Trap guest writes to TCR_EL1 to prevent it from enabling HA or HD.
 	 */
@@ -195,15 +188,11 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	compute_undef_clr_set(vcpu, kvm, HFGRTR_EL2, r_clr, r_set);
 	compute_undef_clr_set(vcpu, kvm, HFGWTR_EL2, w_clr, w_set);
 
-	/* The default to trap everything not handled or supported in KVM. */
-	tmp = HFGxTR_EL2_nAMAIR2_EL1 | HFGxTR_EL2_nMAIR2_EL1 | HFGxTR_EL2_nS2POR_EL1 |
-	      HFGxTR_EL2_nPOR_EL1 | HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nACCDATA_EL1;
-
-	r_val = __HFGRTR_EL2_nMASK & ~tmp;
+	r_val = __HFGRTR_EL2_nMASK;
 	r_val |= r_set;
 	r_val &= ~r_clr;
 
-	w_val = __HFGWTR_EL2_nMASK & ~tmp;
+	w_val = __HFGWTR_EL2_nMASK;
 	w_val |= w_set;
 	w_val &= ~w_clr;
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 938df5dc3684..39e7c7f74717 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3942,6 +3942,29 @@ int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm, struct reg_mask_range *
 	return 0;
 }
 
+void kvm_init_sysreg(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+
+	mutex_lock(&kvm->arch.config_lock);
+
+	if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags))
+		goto out;
+
+	kvm->arch.fgu[HFGxTR_GROUP] = (HFGxTR_EL2_nAMAIR2_EL1		|
+				       HFGxTR_EL2_nMAIR2_EL1		|
+				       HFGxTR_EL2_nS2POR_EL1		|
+				       HFGxTR_EL2_nPOR_EL1		|
+				       HFGxTR_EL2_nPOR_EL0		|
+				       HFGxTR_EL2_nACCDATA_EL1		|
+				       HFGxTR_EL2_nSMPRI_EL1_MASK	|
+				       HFGxTR_EL2_nTPIDR2_EL0_MASK);
+
+	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
+out:
+	mutex_unlock(&kvm->arch.config_lock);
+}
+
 int __init kvm_sys_reg_table_init(void)
 {
 	struct sys_reg_params params;
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:25 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:25 +0000
Subject: [PATCH v3 20/26] KVM: arm64: Streamline save/restore of HFG[RW]TR_EL2
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-21-maz@kernel.org>

The way we save/restore HFG[RW]TR_EL2 can now be simplified, and
the Ampere erratum hack is the only thing that still stands out.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 42 ++++++-------------------
 1 file changed, 9 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 245f9c1ca666..2d5891518006 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -157,8 +157,6 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
 	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
-	u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0;
-	u64 r_val, w_val;
 
 	CHECK_FGT_MASKS(HFGRTR_EL2);
 	CHECK_FGT_MASKS(HFGWTR_EL2);
@@ -171,34 +169,10 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	if (!cpus_have_final_cap(ARM64_HAS_FGT))
 		return;
 
-	ctxt_sys_reg(hctxt, HFGRTR_EL2) = read_sysreg_s(SYS_HFGRTR_EL2);
-	ctxt_sys_reg(hctxt, HFGWTR_EL2) = read_sysreg_s(SYS_HFGWTR_EL2);
-
-	/*
-	 * Trap guest writes to TCR_EL1 to prevent it from enabling HA or HD.
-	 */
-	if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
-		w_set |= HFGxTR_EL2_TCR_EL1_MASK;
-
-	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
-		compute_clr_set(vcpu, HFGRTR_EL2, r_clr, r_set);
-		compute_clr_set(vcpu, HFGWTR_EL2, w_clr, w_set);
-	}
-
-	compute_undef_clr_set(vcpu, kvm, HFGRTR_EL2, r_clr, r_set);
-	compute_undef_clr_set(vcpu, kvm, HFGWTR_EL2, w_clr, w_set);
-
-	r_val = __HFGRTR_EL2_nMASK;
-	r_val |= r_set;
-	r_val &= ~r_clr;
-
-	w_val = __HFGWTR_EL2_nMASK;
-	w_val |= w_set;
-	w_val &= ~w_clr;
-
-	write_sysreg_s(r_val, SYS_HFGRTR_EL2);
-	write_sysreg_s(w_val, SYS_HFGWTR_EL2);
-
+	update_fgt_traps(hctxt, vcpu, kvm, HFGRTR_EL2);
+	update_fgt_traps_cs(hctxt, vcpu, kvm, HFGWTR_EL2, 0,
+			    cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38) ?
+			    HFGxTR_EL2_TCR_EL1_MASK : 0);
 	update_fgt_traps(hctxt, vcpu, kvm, HFGITR_EL2);
 	update_fgt_traps(hctxt, vcpu, kvm, HDFGRTR_EL2);
 	update_fgt_traps(hctxt, vcpu, kvm, HDFGWTR_EL2);
@@ -223,9 +197,11 @@ static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	if (!cpus_have_final_cap(ARM64_HAS_FGT))
 		return;
 
-	write_sysreg_s(ctxt_sys_reg(hctxt, HFGRTR_EL2), SYS_HFGRTR_EL2);
-	write_sysreg_s(ctxt_sys_reg(hctxt, HFGWTR_EL2), SYS_HFGWTR_EL2);
-
+	__deactivate_fgt(hctxt, vcpu, kvm, HFGRTR_EL2);
+	if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
+		write_sysreg_s(ctxt_sys_reg(hctxt, HFGWTR_EL2), SYS_HFGWTR_EL2);
+	else
+		__deactivate_fgt(hctxt, vcpu, kvm, HFGWTR_EL2);
 	__deactivate_fgt(hctxt, vcpu, kvm, HFGITR_EL2);
 	__deactivate_fgt(hctxt, vcpu, kvm, HDFGRTR_EL2);
 	__deactivate_fgt(hctxt, vcpu, kvm, HDFGWTR_EL2);
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:26 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:26 +0000
Subject: [PATCH v3 21/26] KVM: arm64: Make TLBI OS/Range UNDEF if not advertised to the guest
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-22-maz@kernel.org>

Outer Shareable and Range TLBI instructions shouldn't be made available
to the guest if they are not advertised. Use FGU to disable those,
and set HCR_EL2.TLBIOS in the case the host doesn't have FGT. Note
that in that later case, we cannot efficiently disable TLBI Range
instructions, as this would require to trap all TLBIs.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/kvm/sys_regs.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 39e7c7f74717..f07ee7c89822 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3948,6 +3948,14 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
 
 	mutex_lock(&kvm->arch.config_lock);
 
+	/*
+	 * In the absence of FGT, we cannot independently trap TLBI
+	 * Range instructions. This isn't great, but trapping all
+	 * TLBIs would be far worse. Live with it...
+	 */
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+		vcpu->arch.hcr_el2 |= HCR_TTLBOS;
+
 	if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags))
 		goto out;
 
@@ -3960,6 +3968,32 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
 				       HFGxTR_EL2_nSMPRI_EL1_MASK	|
 				       HFGxTR_EL2_nTPIDR2_EL0_MASK);
 
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+		kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1OS|
+						HFGITR_EL2_TLBIRVALE1OS	|
+						HFGITR_EL2_TLBIRVAAE1OS	|
+						HFGITR_EL2_TLBIRVAE1OS	|
+						HFGITR_EL2_TLBIVAALE1OS	|
+						HFGITR_EL2_TLBIVALE1OS	|
+						HFGITR_EL2_TLBIVAAE1OS	|
+						HFGITR_EL2_TLBIASIDE1OS	|
+						HFGITR_EL2_TLBIVAE1OS	|
+						HFGITR_EL2_TLBIVMALLE1OS);
+
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
+		kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1	|
+						HFGITR_EL2_TLBIRVALE1	|
+						HFGITR_EL2_TLBIRVAAE1	|
+						HFGITR_EL2_TLBIRVAE1	|
+						HFGITR_EL2_TLBIRVAALE1IS|
+						HFGITR_EL2_TLBIRVALE1IS	|
+						HFGITR_EL2_TLBIRVAAE1IS	|
+						HFGITR_EL2_TLBIRVAE1IS	|
+						HFGITR_EL2_TLBIRVAALE1OS|
+						HFGITR_EL2_TLBIRVALE1OS	|
+						HFGITR_EL2_TLBIRVAAE1OS	|
+						HFGITR_EL2_TLBIRVAE1OS);
+
 	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
 out:
 	mutex_unlock(&kvm->arch.config_lock);
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:29 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:29 +0000
Subject: [PATCH v3 24/26] KVM: arm64: Make FEAT_MOPS UNDEF if not advertised to the guest
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-25-maz@kernel.org>

We unconditionally enable FEAT_MOPS, which is obviously wrong.

So let's only do that when it is advertised to the guest.
Which means we need to rely on a per-vcpu HCRX_EL2 shadow register.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/include/asm/kvm_arm.h        | 4 +---
 arch/arm64/include/asm/kvm_host.h       | 1 +
 arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +-
 arch/arm64/kvm/sys_regs.c               | 7 +++++++
 4 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3c6f8ba1e479..a1769e415d72 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -102,9 +102,7 @@
 #define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
 #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
 
-#define HCRX_GUEST_FLAGS \
-	(HCRX_EL2_SMPME | HCRX_EL2_TCR2En | \
-	 (cpus_have_final_cap(ARM64_HAS_MOPS) ? (HCRX_EL2_MSCEn | HCRX_EL2_MCE2) : 0))
+#define HCRX_GUEST_FLAGS (HCRX_EL2_SMPME | HCRX_EL2_TCR2En)
 #define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En)
 
 /* TCR_EL2 Registers bits */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 968a997b3f02..3feabde9c926 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -584,6 +584,7 @@ struct kvm_vcpu_arch {
 
 	/* Values of trap registers for the guest. */
 	u64 hcr_el2;
+	u64 hcrx_el2;
 	u64 mdcr_el2;
 	u64 cptr_el2;
 
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 2d5891518006..e3fcf8c4d5b4 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -236,7 +236,7 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
 	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
 
 	if (cpus_have_final_cap(ARM64_HAS_HCX)) {
-		u64 hcrx = HCRX_GUEST_FLAGS;
+		u64 hcrx = vcpu->arch.hcrx_el2;
 		if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
 			u64 clr = 0, set = 0;
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 38ed47bd29db..2cb69efac1dc 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3956,6 +3956,13 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
 	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
 		vcpu->arch.hcr_el2 |= HCR_TTLBOS;
 
+	if (cpus_have_final_cap(ARM64_HAS_HCX)) {
+		vcpu->arch.hcrx_el2 = HCRX_GUEST_FLAGS;
+
+		if (kvm_has_feat(kvm, ID_AA64ISAR2_EL1, MOPS, IMP))
+			vcpu->arch.hcrx_el2 |= (HCRX_EL2_MSCEn | HCRX_EL2_MCE2);
+	}
+
 	if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags))
 		goto out;
 
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:28 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:28 +0000
Subject: [PATCH v3 23/26] KVM: arm64: Make AMU sysreg UNDEF if FEAT_AMU is not advertised to the guest
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-24-maz@kernel.org>

No AMU? No AMU! IF we see an AMU-related trap, let's turn it into
an UNDEF!

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index da9db99c77e7..38ed47bd29db 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3998,6 +3998,10 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
 		kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 |
 						HFGxTR_EL2_nPIR_EL1);
 
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
+		kvm->arch.fgu[HAFGRTR_GROUP] |= ~(HAFGRTR_EL2_RES0 |
+						  HAFGRTR_EL2_RES1);
+
 	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
 out:
 	mutex_unlock(&kvm->arch.config_lock);
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:31 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:31 +0000
Subject: [PATCH v3 26/26] KVM: arm64: Add debugfs file for guest's ID registers
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-27-maz@kernel.org>

Debugging ID register setup can be a complicated affair. Give the
kernel hacker a way to dump that state in an easy to parse way.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  3 ++
 arch/arm64/kvm/sys_regs.c         | 81 +++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 3feabde9c926..181fef12e8e8 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -319,6 +319,9 @@ struct kvm_arch {
 	/* PMCR_EL0.N value for the guest */
 	u8 pmcr_n;
 
+	/* Iterator for idreg debugfs */
+	u8	idreg_debugfs_iter;
+
 	/* Hypercall features firmware registers' descriptor */
 	struct kvm_smccc_features smccc_feat;
 	struct maple_tree smccc_filter;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index b5335e5a6e6e..e3faedc8b7a3 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -12,6 +12,7 @@
 #include <linux/bitfield.h>
 #include <linux/bsearch.h>
 #include <linux/cacheinfo.h>
+#include <linux/debugfs.h>
 #include <linux/kvm_host.h>
 #include <linux/mm.h>
 #include <linux/printk.h>
@@ -3422,6 +3423,81 @@ static bool emulate_sys_reg(struct kvm_vcpu *vcpu,
 	return false;
 }
 
+static void *idregs_debug_start(struct seq_file *s, loff_t *pos)
+{
+	struct kvm *kvm = s->private;
+	u8 *iter;
+
+	mutex_lock(&kvm->arch.config_lock);
+
+	iter = &kvm->arch.idreg_debugfs_iter;
+	if (*iter == (u8)~0) {
+		*iter = *pos;
+		if (*iter >= KVM_ARM_ID_REG_NUM)
+			iter = NULL;
+	} else {
+		iter = ERR_PTR(-EBUSY);
+	}
+
+	mutex_unlock(&kvm->arch.config_lock);
+
+	return iter;
+}
+
+static void *idregs_debug_next(struct seq_file *s, void *v, loff_t *pos)
+{
+	struct kvm *kvm = s->private;
+
+	(*pos)++;
+
+	if ((kvm->arch.idreg_debugfs_iter + 1) < KVM_ARM_ID_REG_NUM) {
+		kvm->arch.idreg_debugfs_iter++;
+
+		return &kvm->arch.idreg_debugfs_iter;
+	}
+
+	return NULL;
+}
+
+static void idregs_debug_stop(struct seq_file *s, void *v)
+{
+	struct kvm *kvm = s->private;
+
+	if (IS_ERR(v))
+		return;
+
+	mutex_lock(&kvm->arch.config_lock);
+
+	kvm->arch.idreg_debugfs_iter = ~0;
+
+	mutex_unlock(&kvm->arch.config_lock);
+}
+
+static int idregs_debug_show(struct seq_file *s, void *v)
+{
+	struct kvm *kvm = s->private;
+	const struct sys_reg_desc *desc;
+
+	desc = first_idreg + kvm->arch.idreg_debugfs_iter;
+
+	if (!desc->name)
+		return 0;
+
+	seq_printf(s, "%20s:\t%016llx\n",
+		   desc->name, IDREG(kvm, IDX_IDREG(kvm->arch.idreg_debugfs_iter)));
+
+	return 0;
+}
+
+static const struct seq_operations idregs_debug_sops = {
+	.start	= idregs_debug_start,
+	.next	= idregs_debug_next,
+	.stop	= idregs_debug_stop,
+	.show	= idregs_debug_show,
+};
+
+DEFINE_SEQ_ATTRIBUTE(idregs_debug);
+
 static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
 {
 	const struct sys_reg_desc *idreg = first_idreg;
@@ -3441,6 +3517,11 @@ static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
 		id = reg_to_encoding(idreg);
 	}
 
+	kvm->arch.idreg_debugfs_iter = ~0;
+
+	debugfs_create_file("idregs", 0444, kvm->debugfs_dentry, kvm,
+			    &idregs_debug_fops);
+
 	set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags);
 }
 
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:23 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:23 +0000
Subject: [PATCH v3 18/26] KVM: arm64: Propagate and handle Fine-Grained UNDEF bits
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-19-maz@kernel.org>

In order to correctly honor our FGU bits, they must be converted
into a set of FGT bits. They get merged as part of the existing
FGT setting.

Similarly, the UNDEF injection phase takes place when handling
the trap.

This results in a bit of rework in the FGT macros in order to
help with the code generation, as burying per-CPU accesses in
macros results in a lot of expansion, not to mention the vcpu->kvm
access on nvhe (kern_hyp_va() is not optimisation-friendly).

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c         | 11 ++++
 arch/arm64/kvm/hyp/include/hyp/switch.h | 81 +++++++++++++++++++------
 2 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index b67078b8271b..4697ba41b3a9 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2017,6 +2017,17 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
 	if (!tc.val)
 		goto local;
 
+	/*
+	 * If a sysreg can be trapped using a FGT, first check whether we
+	 * trap for the purpose of forbidding the feature. In that case,
+	 * inject an UNDEF.
+	 */
+	if (tc.fgt != __NO_FGT_GROUP__ &&
+	    (vcpu->kvm->arch.fgu[tc.fgt] & BIT(tc.bit))) {
+		kvm_inject_undefined(vcpu);
+		return true;
+	}
+
 	/*
 	 * If we're not nesting, immediately return to the caller, with the
 	 * sysreg index, should we have it.
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index a038320cdb08..a09149fd91ed 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -79,14 +79,48 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
 		clr |= ~hfg & __ ## reg ## _nMASK; 			\
 	} while(0)
 
-#define update_fgt_traps_cs(vcpu, reg, clr, set)			\
+#define reg_to_fgt_group_id(reg)					\
+	({								\
+		enum fgt_group_id id;					\
+		switch(reg) {						\
+		case HFGRTR_EL2:					\
+		case HFGWTR_EL2:					\
+			id = HFGxTR_GROUP;				\
+			break;						\
+		case HFGITR_EL2:					\
+			id = HFGITR_GROUP;				\
+			break;						\
+		case HDFGRTR_EL2:					\
+		case HDFGWTR_EL2:					\
+			id = HDFGRTR_GROUP;				\
+			break;						\
+		case HAFGRTR_EL2:					\
+			id = HAFGRTR_GROUP;				\
+			break;						\
+		default:						\
+			BUILD_BUG_ON(1);				\
+		}							\
+									\
+		id;							\
+	})
+
+#define compute_undef_clr_set(vcpu, kvm, reg, clr, set)			\
+	do {								\
+		u64 hfg = kvm->arch.fgu[reg_to_fgt_group_id(reg)];	\
+		set |= hfg & __ ## reg ## _MASK;			\
+		clr |= hfg & __ ## reg ## _nMASK; 			\
+	} while(0)
+
+#define update_fgt_traps_cs(hctxt, vcpu, kvm, reg, clr, set)		\
 	do {								\
-		struct kvm_cpu_context *hctxt =				\
-			&this_cpu_ptr(&kvm_host_data)->host_ctxt;	\
 		u64 c = 0, s = 0;					\
 									\
 		ctxt_sys_reg(hctxt, reg) = read_sysreg_s(SYS_ ## reg);	\
-		compute_clr_set(vcpu, reg, c, s);			\
+		if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu))		\
+			compute_clr_set(vcpu, reg, c, s);		\
+									\
+		compute_undef_clr_set(vcpu, kvm, reg, c, s);		\
+									\
 		s |= set;						\
 		c |= clr;						\
 		if (c || s) {						\
@@ -97,8 +131,8 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
 		}							\
 	} while(0)
 
-#define update_fgt_traps(vcpu, reg)		\
-	update_fgt_traps_cs(vcpu, reg, 0, 0)
+#define update_fgt_traps(hctxt, vcpu, kvm, reg)		\
+	update_fgt_traps_cs(hctxt, vcpu, kvm, reg, 0, 0)
 
 /*
  * Validate the fine grain trap masks.
@@ -122,6 +156,7 @@ static inline bool cpu_has_amu(void)
 static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
 	u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0, tmp;
 	u64 r_val, w_val;
 
@@ -157,6 +192,9 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 		compute_clr_set(vcpu, HFGWTR_EL2, w_clr, w_set);
 	}
 
+	compute_undef_clr_set(vcpu, kvm, HFGRTR_EL2, r_clr, r_set);
+	compute_undef_clr_set(vcpu, kvm, HFGWTR_EL2, w_clr, w_set);
+
 	/* The default to trap everything not handled or supported in KVM. */
 	tmp = HFGxTR_EL2_nAMAIR2_EL1 | HFGxTR_EL2_nMAIR2_EL1 | HFGxTR_EL2_nS2POR_EL1 |
 	      HFGxTR_EL2_nPOR_EL1 | HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nACCDATA_EL1;
@@ -172,20 +210,26 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	write_sysreg_s(r_val, SYS_HFGRTR_EL2);
 	write_sysreg_s(w_val, SYS_HFGWTR_EL2);
 
-	if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
-		return;
-
-	update_fgt_traps(vcpu, HFGITR_EL2);
-	update_fgt_traps(vcpu, HDFGRTR_EL2);
-	update_fgt_traps(vcpu, HDFGWTR_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HFGITR_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HDFGRTR_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HDFGWTR_EL2);
 
 	if (cpu_has_amu())
-		update_fgt_traps(vcpu, HAFGRTR_EL2);
+		update_fgt_traps(hctxt, vcpu, kvm, HAFGRTR_EL2);
 }
 
+#define __deactivate_fgt(htcxt, vcpu, kvm, reg)				\
+	do {								\
+		if ((vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) ||	\
+		    kvm->arch.fgu[reg_to_fgt_group_id(reg)])		\
+			write_sysreg_s(ctxt_sys_reg(hctxt, reg),	\
+				       SYS_ ## reg);			\
+	} while(0)
+
 static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
 
 	if (!cpus_have_final_cap(ARM64_HAS_FGT))
 		return;
@@ -193,15 +237,12 @@ static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	write_sysreg_s(ctxt_sys_reg(hctxt, HFGRTR_EL2), SYS_HFGRTR_EL2);
 	write_sysreg_s(ctxt_sys_reg(hctxt, HFGWTR_EL2), SYS_HFGWTR_EL2);
 
-	if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
-		return;
-
-	write_sysreg_s(ctxt_sys_reg(hctxt, HFGITR_EL2), SYS_HFGITR_EL2);
-	write_sysreg_s(ctxt_sys_reg(hctxt, HDFGRTR_EL2), SYS_HDFGRTR_EL2);
-	write_sysreg_s(ctxt_sys_reg(hctxt, HDFGWTR_EL2), SYS_HDFGWTR_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HFGITR_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HDFGRTR_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HDFGWTR_EL2);
 
 	if (cpu_has_amu())
-		write_sysreg_s(ctxt_sys_reg(hctxt, HAFGRTR_EL2), SYS_HAFGRTR_EL2);
+		__deactivate_fgt(hctxt, vcpu, kvm, HAFGRTR_EL2);
 }
 
 static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:27 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:27 +0000
Subject: [PATCH v3 22/26] KVM: arm64: Make PIR{,E0}_EL1 UNDEF if S1PIE is not advertised to the guest
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-23-maz@kernel.org>

As part of the ongoing effort to honor the guest configuration,
add the necessary checks to make PIR_EL1 and co UNDEF if not
advertised to the guest, and avoid context switching them.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 24 +++++++++++++++++++---
 arch/arm64/kvm/sys_regs.c                  |  4 ++++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index bb6b571ec627..4be6a7fa0070 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -27,16 +27,34 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt)
 	ctxt_sys_reg(ctxt, TPIDRRO_EL0)	= read_sysreg(tpidrro_el0);
 }
 
-static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt)
+static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt)
 {
 	struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu;
 
 	if (!vcpu)
 		vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt);
 
+	return vcpu;
+}
+
+static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt)
+{
+	struct kvm_vcpu *vcpu = ctxt_to_vcpu(ctxt);
+
 	return kvm_has_mte(kern_hyp_va(vcpu->kvm));
 }
 
+static inline bool ctxt_has_s1pie(struct kvm_cpu_context *ctxt)
+{
+	struct kvm_vcpu *vcpu;
+
+	if (!cpus_have_final_cap(ARM64_HAS_S1PIE))
+		return false;
+
+	vcpu = ctxt_to_vcpu(ctxt);
+	return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, S1PIE, IMP);
+}
+
 static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
 {
 	ctxt_sys_reg(ctxt, SCTLR_EL1)	= read_sysreg_el1(SYS_SCTLR);
@@ -55,7 +73,7 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
 	ctxt_sys_reg(ctxt, CONTEXTIDR_EL1) = read_sysreg_el1(SYS_CONTEXTIDR);
 	ctxt_sys_reg(ctxt, AMAIR_EL1)	= read_sysreg_el1(SYS_AMAIR);
 	ctxt_sys_reg(ctxt, CNTKCTL_EL1)	= read_sysreg_el1(SYS_CNTKCTL);
-	if (cpus_have_final_cap(ARM64_HAS_S1PIE)) {
+	if (ctxt_has_s1pie(ctxt)) {
 		ctxt_sys_reg(ctxt, PIR_EL1)	= read_sysreg_el1(SYS_PIR);
 		ctxt_sys_reg(ctxt, PIRE0_EL1)	= read_sysreg_el1(SYS_PIRE0);
 	}
@@ -131,7 +149,7 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
 	write_sysreg_el1(ctxt_sys_reg(ctxt, CONTEXTIDR_EL1), SYS_CONTEXTIDR);
 	write_sysreg_el1(ctxt_sys_reg(ctxt, AMAIR_EL1),	SYS_AMAIR);
 	write_sysreg_el1(ctxt_sys_reg(ctxt, CNTKCTL_EL1), SYS_CNTKCTL);
-	if (cpus_have_final_cap(ARM64_HAS_S1PIE)) {
+	if (ctxt_has_s1pie(ctxt)) {
 		write_sysreg_el1(ctxt_sys_reg(ctxt, PIR_EL1),	SYS_PIR);
 		write_sysreg_el1(ctxt_sys_reg(ctxt, PIRE0_EL1),	SYS_PIRE0);
 	}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index f07ee7c89822..da9db99c77e7 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3994,6 +3994,10 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
 						HFGITR_EL2_TLBIRVAAE1OS	|
 						HFGITR_EL2_TLBIRVAE1OS);
 
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
+		kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 |
+						HFGxTR_EL2_nPIR_EL1);
+
 	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
 out:
 	mutex_unlock(&kvm->arch.config_lock);
-- 
2.39.2



From maz at kernel.org  Mon Feb  5 02:34:30 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  5 Feb 2024 10:34:30 +0000
Subject: [PATCH v3 25/26] KVM: arm64: Snapshot all non-zero RES0/RES1 sysreg fields for later checking
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <20240205103431.1104133-26-maz@kernel.org>

As KVM now strongly relies on accurately handling the RES0/RES1 bits
on a number of paths, add a compile-time checker that will blow in
the face of the innocent bystander, should they try to sneak in an
update that changes any of these RES0/RES1 fields.

It is expected that such an update will come with the relevant
KVM update if needed.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/check-res-bits.h | 121 ++++++++++++++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c       |   3 +
 2 files changed, 124 insertions(+)
 create mode 100644 arch/arm64/kvm/check-res-bits.h

diff --git a/arch/arm64/kvm/check-res-bits.h b/arch/arm64/kvm/check-res-bits.h
new file mode 100644
index 000000000000..967b5d171d53
--- /dev/null
+++ b/arch/arm64/kvm/check-res-bits.h
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 - Google LLC
+ * Author: Marc Zyngier <maz at kernel.org>
+ */
+
+#include <asm/sysreg-defs.h>
+
+/*
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * If any of these BUILD_BUG_ON() fails, that's because some bits that
+ * were reserved have gained some other meaning, and KVM needs to know
+ * about those.
+ *
+ * In such case, do *NOT* blindly change the assertion so that it
+ * passes, but also teach the rest of the code about the actual
+ * change.
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+static inline void check_res_bits(void)
+{
+	BUILD_BUG_ON(OSDTRRX_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(MDCCINT_EL1_RES0		!= (GENMASK_ULL(63, 31) | GENMASK_ULL(28, 0)));
+	BUILD_BUG_ON(MDSCR_EL1_RES0		!= (GENMASK_ULL(63, 36) | GENMASK_ULL(28, 28) | GENMASK_ULL(25, 24) | GENMASK_ULL(20, 20) | GENMASK_ULL(18, 16) | GENMASK_ULL(11, 7) | GENMASK_ULL(5, 1)));
+	BUILD_BUG_ON(OSDTRTX_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(OSECCR_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(OSLAR_EL1_RES0		!= (GENMASK_ULL(63, 1)));
+	BUILD_BUG_ON(ID_PFR0_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_PFR1_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_DFR0_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_AFR0_EL1_RES0		!= (GENMASK_ULL(63, 16)));
+	BUILD_BUG_ON(ID_MMFR0_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_MMFR1_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_MMFR2_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_MMFR3_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_ISAR0_EL1_RES0		!= (GENMASK_ULL(63, 28)));
+	BUILD_BUG_ON(ID_ISAR1_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_ISAR2_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_ISAR3_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_ISAR4_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_ISAR5_EL1_RES0		!= (GENMASK_ULL(63, 32) | GENMASK_ULL(23, 20)));
+	BUILD_BUG_ON(ID_ISAR6_EL1_RES0		!= (GENMASK_ULL(63, 28)));
+	BUILD_BUG_ON(ID_MMFR4_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(MVFR0_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(MVFR1_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(MVFR2_EL1_RES0		!= (GENMASK_ULL(63, 8)));
+	BUILD_BUG_ON(ID_PFR2_EL1_RES0		!= (GENMASK_ULL(63, 12)));
+	BUILD_BUG_ON(ID_DFR1_EL1_RES0		!= (GENMASK_ULL(63, 8)));
+	BUILD_BUG_ON(ID_MMFR5_EL1_RES0		!= (GENMASK_ULL(63, 8)));
+	BUILD_BUG_ON(ID_AA64PFR1_EL1_RES0	!= (GENMASK_ULL(23, 20)));
+	BUILD_BUG_ON(ID_AA64PFR2_EL1_RES0	!= (GENMASK_ULL(63, 36) | GENMASK_ULL(31, 12)));
+	BUILD_BUG_ON(ID_AA64ZFR0_EL1_RES0	!= (GENMASK_ULL(63, 60) | GENMASK_ULL(51, 48) | GENMASK_ULL(39, 36) | GENMASK_ULL(31, 28) | GENMASK_ULL(15, 8)));
+	BUILD_BUG_ON(ID_AA64SMFR0_EL1_RES0	!= (GENMASK_ULL(62, 61) | GENMASK_ULL(51, 49) | GENMASK_ULL(31, 31) | GENMASK_ULL(27, 0)));
+	BUILD_BUG_ON(ID_AA64FPFR0_EL1_RES0	!= (GENMASK_ULL(63, 32) | GENMASK_ULL(27, 2)));
+	BUILD_BUG_ON(ID_AA64DFR0_EL1_RES0	!= (GENMASK_ULL(27, 24) | GENMASK_ULL(19, 16)));
+	BUILD_BUG_ON(ID_AA64DFR1_EL1_RES0	!= (GENMASK_ULL(63, 0)));
+	BUILD_BUG_ON(ID_AA64AFR0_EL1_RES0	!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_AA64AFR1_EL1_RES0	!= (GENMASK_ULL(63, 0)));
+	BUILD_BUG_ON(ID_AA64ISAR0_EL1_RES0	!= (GENMASK_ULL(3, 0)));
+	BUILD_BUG_ON(ID_AA64ISAR2_EL1_RES0	!= (GENMASK_ULL(47, 44)));
+	BUILD_BUG_ON(ID_AA64ISAR3_EL1_RES0	!= (GENMASK_ULL(63, 16)));
+	BUILD_BUG_ON(ID_AA64MMFR0_EL1_RES0	!= (GENMASK_ULL(55, 48)));
+	BUILD_BUG_ON(ID_AA64MMFR2_EL1_RES0	!= (GENMASK_ULL(47, 44)));
+	BUILD_BUG_ON(ID_AA64MMFR3_EL1_RES0	!= (GENMASK_ULL(51, 48)));
+	BUILD_BUG_ON(ID_AA64MMFR4_EL1_RES0	!= (GENMASK_ULL(63, 40) | GENMASK_ULL(35, 28) | GENMASK_ULL(3, 0)));
+	BUILD_BUG_ON(SCTLR_EL1_RES0		!= (GENMASK_ULL(17, 17)));
+	BUILD_BUG_ON(CPACR_ELx_RES0		!= (GENMASK_ULL(63, 30) | GENMASK_ULL(27, 26) | GENMASK_ULL(23, 22) | GENMASK_ULL(19, 18) | GENMASK_ULL(15, 0)));
+	BUILD_BUG_ON(SMPRI_EL1_RES0		!= (GENMASK_ULL(63, 4)));
+	BUILD_BUG_ON(ZCR_ELx_RES0		!= (GENMASK_ULL(63, 9)));
+	BUILD_BUG_ON(SMCR_ELx_RES0		!= (GENMASK_ULL(63, 32) | GENMASK_ULL(29, 9)));
+	BUILD_BUG_ON(GCSCR_ELx_RES0		!= (GENMASK_ULL(63, 10) | GENMASK_ULL(7, 7) | GENMASK_ULL(4, 1)));
+	BUILD_BUG_ON(GCSPR_ELx_RES0		!= (GENMASK_ULL(2, 0)));
+	BUILD_BUG_ON(GCSCRE0_EL1_RES0		!= (GENMASK_ULL(63, 11) | GENMASK_ULL(7, 6) | GENMASK_ULL(4, 1)));
+	BUILD_BUG_ON(ALLINT_RES0		!= (GENMASK_ULL(63, 14) | GENMASK_ULL(12, 0)));
+	BUILD_BUG_ON(PMSCR_EL1_RES0		!= (GENMASK_ULL(63, 8) | GENMASK_ULL(2, 2)));
+	BUILD_BUG_ON(PMSICR_EL1_RES0		!= (GENMASK_ULL(55, 32)));
+	BUILD_BUG_ON(PMSIRR_EL1_RES0		!= (GENMASK_ULL(63, 32) | GENMASK_ULL(7, 1)));
+	BUILD_BUG_ON(PMSFCR_EL1_RES0		!= (GENMASK_ULL(63, 19) | GENMASK_ULL(15, 4)));
+	BUILD_BUG_ON(PMSLATFR_EL1_RES0		!= (GENMASK_ULL(63, 16)));
+	BUILD_BUG_ON(PMSIDR_EL1_RES0		!= (GENMASK_ULL(63, 25) | GENMASK_ULL(7, 7)));
+	BUILD_BUG_ON(PMBLIMITR_EL1_RES0		!= (GENMASK_ULL(11, 6) | GENMASK_ULL(4, 3)));
+	BUILD_BUG_ON(PMBSR_EL1_RES0		!= (GENMASK_ULL(63, 32) | GENMASK_ULL(25, 20)));
+	BUILD_BUG_ON(PMBIDR_EL1_RES0		!= (GENMASK_ULL(63, 12) | GENMASK_ULL(7, 6)));
+	BUILD_BUG_ON(CONTEXTIDR_ELx_RES0	!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(CCSIDR_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(CLIDR_EL1_RES0		!= (GENMASK_ULL(63, 47)));
+	BUILD_BUG_ON(CCSIDR2_EL1_RES0		!= (GENMASK_ULL(63, 24)));
+	BUILD_BUG_ON(GMID_EL1_RES0		!= (GENMASK_ULL(63, 4)));
+	BUILD_BUG_ON(SMIDR_EL1_RES0		!= (GENMASK_ULL(63, 32) | GENMASK_ULL(14, 12)));
+	BUILD_BUG_ON(CSSELR_EL1_RES0		!= (GENMASK_ULL(63, 5)));
+	BUILD_BUG_ON(CTR_EL0_RES0		!= (GENMASK_ULL(63, 38) | GENMASK_ULL(30, 30) | GENMASK_ULL(13, 4)));
+	BUILD_BUG_ON(CTR_EL0_RES1       	!= (GENMASK_ULL(31, 31)));
+	BUILD_BUG_ON(DCZID_EL0_RES0		!= (GENMASK_ULL(63, 5)));
+	BUILD_BUG_ON(SVCR_RES0			!= (GENMASK_ULL(63, 2)));
+	BUILD_BUG_ON(FPMR_RES0			!= (GENMASK_ULL(63, 38) | GENMASK_ULL(23, 23) | GENMASK_ULL(13, 9)));
+	BUILD_BUG_ON(HFGxTR_EL2_RES0		!= (GENMASK_ULL(51, 51)));
+	BUILD_BUG_ON(HFGITR_EL2_RES0		!= (GENMASK_ULL(63, 63) | GENMASK_ULL(61, 61)));
+	BUILD_BUG_ON(HDFGRTR_EL2_RES0		!= (GENMASK_ULL(49, 49) | GENMASK_ULL(42, 42) | GENMASK_ULL(39, 38) | GENMASK_ULL(21, 20) | GENMASK_ULL(8, 8)));
+	BUILD_BUG_ON(HDFGWTR_EL2_RES0		!= (GENMASK_ULL(63, 63) | GENMASK_ULL(59, 58) | GENMASK_ULL(51, 51) | GENMASK_ULL(47, 47) | GENMASK_ULL(43, 43) | GENMASK_ULL(40, 38) | GENMASK_ULL(34, 34) | GENMASK_ULL(30, 30) | GENMASK_ULL(22, 22) | GENMASK_ULL(9, 9) | GENMASK_ULL(6, 6)));
+	BUILD_BUG_ON(HAFGRTR_EL2_RES0		!= (GENMASK_ULL(63, 50) | GENMASK_ULL(16, 5)));
+	BUILD_BUG_ON(HCRX_EL2_RES0		!= (GENMASK_ULL(63, 25) | GENMASK_ULL(13, 12)));
+	BUILD_BUG_ON(DACR32_EL2_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(PMSCR_EL2_RES0		!= (GENMASK_ULL(63, 8) | GENMASK_ULL(2, 2)));
+	BUILD_BUG_ON(TCR2_EL1x_RES0		!= (GENMASK_ULL(63, 16) | GENMASK_ULL(13, 12) | GENMASK_ULL(9, 6)));
+	BUILD_BUG_ON(TCR2_EL2_RES0		!= (GENMASK_ULL(63, 16)));
+	BUILD_BUG_ON(LORSA_EL1_RES0		!= (GENMASK_ULL(63, 52) | GENMASK_ULL(15, 1)));
+	BUILD_BUG_ON(LOREA_EL1_RES0		!= (GENMASK_ULL(63, 52) | GENMASK_ULL(15, 0)));
+	BUILD_BUG_ON(LORN_EL1_RES0		!= (GENMASK_ULL(63, 8)));
+	BUILD_BUG_ON(LORC_EL1_RES0		!= (GENMASK_ULL(63, 10) | GENMASK_ULL(1, 1)));
+	BUILD_BUG_ON(LORID_EL1_RES0		!= (GENMASK_ULL(63, 24) | GENMASK_ULL(15, 8)));
+	BUILD_BUG_ON(ISR_EL1_RES0		!= (GENMASK_ULL(63, 11) | GENMASK_ULL(5, 0)));
+	BUILD_BUG_ON(ICC_NMIAR1_EL1_RES0	!= (GENMASK_ULL(63, 24)));
+	BUILD_BUG_ON(TRBLIMITR_EL1_RES0		!= (GENMASK_ULL(11, 7)));
+	BUILD_BUG_ON(TRBBASER_EL1_RES0		!= (GENMASK_ULL(11, 0)));
+	BUILD_BUG_ON(TRBSR_EL1_RES0		!= (GENMASK_ULL(63, 56) | GENMASK_ULL(25, 24) | GENMASK_ULL(19, 19) | GENMASK_ULL(16, 16)));
+	BUILD_BUG_ON(TRBMAR_EL1_RES0		!= (GENMASK_ULL(63, 12)));
+	BUILD_BUG_ON(TRBTRG_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(TRBIDR_EL1_RES0		!= (GENMASK_ULL(63, 12) | GENMASK_ULL(7, 6)));
+}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 2cb69efac1dc..b5335e5a6e6e 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -31,6 +31,7 @@
 
 #include <trace/events/kvm.h>
 
+#include "check-res-bits.h"
 #include "sys_regs.h"
 
 #include "trace.h"
@@ -4021,6 +4022,8 @@ int __init kvm_sys_reg_table_init(void)
 	unsigned int i;
 	int ret = 0;
 
+	check_res_bits();
+
 	/* Make sure tables are unique and in order. */
 	valid &= check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs), false);
 	valid &= check_sysreg_table(cp14_regs, ARRAY_SIZE(cp14_regs), true);
-- 
2.39.2



From rostedt at goodmis.org  Mon Feb  5 02:38:19 2024
From: rostedt at goodmis.org (Steven Rostedt)
Date: Mon, 5 Feb 2024 05:38:19 -0500
Subject: Question about the ipi_raise filter usage and output
In-Reply-To: <CAJNi4rMpt88Gz+149wR9crzApmfUEfpS05sbOgAvOhzh2+Brbg@mail.gmail.com>
References: <CAJNi4rMpt88Gz+149wR9crzApmfUEfpS05sbOgAvOhzh2+Brbg@mail.gmail.com>
Message-ID: <20240205053819.3cf848f0@rorschach.local.home>

On Mon, 5 Feb 2024 17:57:29 +0800
richard clark <richard.xnu.clark at gmail.com> wrote:

> Hi guys,
> 
> With the ipi_raise event enabled and filtered with:
> echo 'reason == "Function call interrupts"' > filter, then the 'cat
> trace' output below messages:
> ...
> insmod-3355    [010] ....1.. 24479.230381: ipi_raise:
> target_mask=00000000,00000bff (Function call interrupts)
> ...
> The above output is triggered by my kernel module where it will smp
> cross call a remote function from cpu#10 to cpu#11, for the
> 'target_mask' value, what does the '00000000,00000bff' mean?
>  ~~~~~~~~~~~~~~

It's the CPU mask. bff is bits 101111111111 or CPUs = 0-9,11.


> 
> Another question is for the filter, I'd like to catch the IPI only
> happening on cpu#11 *AND* a remote function call, so how to write the
> 'target_cpus' in the filter expression?
> 
> I try to write below:
> echo 'target_cpus == 11 && reason == "Function call interrupts"' >
> events/ipi/ipi_raise/filter

You mean when it is sent only to CPU 11? Not when the event is
happening on CPU 11. Like the above example, the event was triggered on
CPU 10, but the mask was for all the other CPUs.

If you are looking for just CPU 11, you can do:

  echo 'target_cpus == 0x800 && reason == "Function call interrupts"'


> 
> But the 'cat trace' doesn't show anything about cpu#11 IPI info,
> although both the /proc/interrupts and the smp_processor_id() in the
> remote function shows there's IPI sent to the cpu#11.
> 


-- Steve


From rdunlap at infradead.org  Mon Feb  5 02:39:53 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Mon, 5 Feb 2024 02:39:53 -0800
Subject: [PATCH 17/17] linux: v4l2-vp9.h: Fix kerneldoc
In-Reply-To: <201ae1d1-1e03-40e2-9cc4-49df70abb8da@xs4all.nl>
References: <20240126-gix-mtk-warnings-v1-0-eed7865fce18@chromium.org>
 <20240126-gix-mtk-warnings-v1-17-eed7865fce18@chromium.org>
 <ZbTTb-SdK-EubGdc@valkosipuli.retiisi.eu>
 <201ae1d1-1e03-40e2-9cc4-49df70abb8da@xs4all.nl>
Message-ID: <8f3bab1f-8697-40c0-91f2-de934b4b9ddb@infradead.org>



On 2/5/24 02:29, Hans Verkuil wrote:
> On 27/01/2024 10:57, Sakari Ailus wrote:
>> Hi Ricardo,
>>
>> On Fri, Jan 26, 2024 at 11:16:16PM +0000, Ricardo Ribalda wrote:
>>> Kerneldoc cannot understand arrays defined like
>>> v4l2_frame_symbol_counts.
>>>
>>> Adding an asterisk to the name does do the trick.
>>>
>>> Disable the kerneldoc notation for now, it is already ignored:
>>> https://docs.kernel.org/search.html?q=v4l2_vp9_frame_symbol_counts
>>
>> Wouldn't it be nicer to fix kerneldoc instead? It might not be difficult at
>> all.
>>
>> Feel free to, but I can also give it a try.
>>
> 
> It would be nice to have this fixed in kerneldoc itself. I'm holding this
> patch back for two weeks to see if someone wants to work on kerneldoc.
> 
> If not, then I'll take this anyway to fix the noise in our build.
> 
> Note that while this header is indeed ignored in the documentation, that
> is really more a bug and it would be nice to actually include this header
> somewhere in our documentation. So fixing these kerneldoc warnings one way
> or another is something that we should do.
> 

It's just waiting for Jon to apply it: (from Sakari)

https://lore.kernel.org/all/20240131084934.191226-1-sakari.ailus at linux.intel.com/

Thanks.

-- 
#Randy


From hverkuil-cisco at xs4all.nl  Mon Feb  5 02:44:13 2024
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Mon, 5 Feb 2024 11:44:13 +0100
Subject: [PATCH 17/17] linux: v4l2-vp9.h: Fix kerneldoc
In-Reply-To: <8f3bab1f-8697-40c0-91f2-de934b4b9ddb@infradead.org>
References: <20240126-gix-mtk-warnings-v1-0-eed7865fce18@chromium.org>
 <20240126-gix-mtk-warnings-v1-17-eed7865fce18@chromium.org>
 <ZbTTb-SdK-EubGdc@valkosipuli.retiisi.eu>
 <201ae1d1-1e03-40e2-9cc4-49df70abb8da@xs4all.nl>
 <8f3bab1f-8697-40c0-91f2-de934b4b9ddb@infradead.org>
Message-ID: <e565f8bd-19d2-4574-8c6d-5573733a8185@xs4all.nl>

On 05/02/2024 11:39, Randy Dunlap wrote:
> 
> 
> On 2/5/24 02:29, Hans Verkuil wrote:
>> On 27/01/2024 10:57, Sakari Ailus wrote:
>>> Hi Ricardo,
>>>
>>> On Fri, Jan 26, 2024 at 11:16:16PM +0000, Ricardo Ribalda wrote:
>>>> Kerneldoc cannot understand arrays defined like
>>>> v4l2_frame_symbol_counts.
>>>>
>>>> Adding an asterisk to the name does do the trick.
>>>>
>>>> Disable the kerneldoc notation for now, it is already ignored:
>>>> https://docs.kernel.org/search.html?q=v4l2_vp9_frame_symbol_counts
>>>
>>> Wouldn't it be nicer to fix kerneldoc instead? It might not be difficult at
>>> all.
>>>
>>> Feel free to, but I can also give it a try.
>>>
>>
>> It would be nice to have this fixed in kerneldoc itself. I'm holding this
>> patch back for two weeks to see if someone wants to work on kerneldoc.
>>
>> If not, then I'll take this anyway to fix the noise in our build.
>>
>> Note that while this header is indeed ignored in the documentation, that
>> is really more a bug and it would be nice to actually include this header
>> somewhere in our documentation. So fixing these kerneldoc warnings one way
>> or another is something that we should do.
>>
> 
> It's just waiting for Jon to apply it: (from Sakari)
> 
> https://lore.kernel.org/all/20240131084934.191226-1-sakari.ailus at linux.intel.com/

Ah, that patch was CCed to me but not to linux-media, and I only searched linux-media
for it so I missed it. Good news that this is fixed in the right place.

I marked this 17/17 patch as Obsoleted in patchwork.

Regards,

	Hans


From alice.chao at mediatek.com  Mon Feb  5 02:49:04 2024
From: alice.chao at mediatek.com (alice.chao at mediatek.com)
Date: Mon, 5 Feb 2024 18:49:04 +0800
Subject: [PATCH v1 1/1] ufs: core: fix shift issue in ufshcd_clear_cmd
Message-ID: <20240205104905.24929-1-alice.chao@mediatek.com>

From: Alice Chao <alice.chao at mediatek.com>

When task_tag > 32 (in mcq mode), 1U << task_tag will out of bound
for u32 mask. Fix this bug to prevent SHIFT_ISSUE (Bitwise shifts
that are out of bounds for their data type).

[name:debug_monitors&]Unexpected kernel BRK exception at EL1
[name:traps&]Internal error: BRK handler: 00000000f2005514 [#1] PREEMPT SMP
[name:mediatek_cpufreq_hw&]cpufreq stop DVFS log done
[name:mrdump&]Kernel Offset: 0x1ba5800000 from 0xffffffc008000000
[name:mrdump&]PHYS_OFFSET: 0x80000000
[name:mrdump&]pstate: 22400005 (nzCv daif +PAN -UAO)
[name:mrdump&]pc : [0xffffffdbaf52bb2c] ufshcd_clear_cmd+0x280/0x288
[name:mrdump&]lr : [0xffffffdbaf52a774] ufshcd_wait_for_dev_cmd+0x3e4/0x82c
[name:mrdump&]sp : ffffffc0081471b0
<snip>
Workqueue: ufs_eh_wq_0 ufshcd_err_handler
Call trace:
 dump_backtrace+0xf8/0x144
 show_stack+0x18/0x24
 dump_stack_lvl+0x78/0x9c
 dump_stack+0x18/0x44
 mrdump_common_die+0x254/0x480 [mrdump]
 ipanic_die+0x20/0x30 [mrdump]
 notify_die+0x15c/0x204
 die+0x10c/0x5f8
 arm64_notify_die+0x74/0x13c
 do_debug_exception+0x164/0x26c
 el1_dbg+0x64/0x80
 el1h_64_sync_handler+0x3c/0x90
 el1h_64_sync+0x68/0x6c
 ufshcd_clear_cmd+0x280/0x288
 ufshcd_wait_for_dev_cmd+0x3e4/0x82c
 ufshcd_exec_dev_cmd+0x5bc/0x9ac
 ufshcd_verify_dev_init+0x84/0x1c8
 ufshcd_probe_hba+0x724/0x1ce0
 ufshcd_host_reset_and_restore+0x260/0x574
 ufshcd_reset_and_restore+0x138/0xbd0
 ufshcd_err_handler+0x1218/0x2f28
 process_one_work+0x5fc/0x1140
 worker_thread+0x7d8/0xe20
 kthread+0x25c/0x468
 ret_from_fork+0x10/0x20

Signed-off-by: Alice Chao <alice.chao at mediatek.com>
---
 drivers/ufs/core/ufshcd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 029d017fc1b6..c6cff4aa440a 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -3057,7 +3057,7 @@ bool ufshcd_cmd_inflight(struct scsi_cmnd *cmd)
  */
 static int ufshcd_clear_cmd(struct ufs_hba *hba, u32 task_tag)
 {
-	u32 mask = 1U << task_tag;
+	u32 mask;
 	unsigned long flags;
 	int err;
 
@@ -3075,6 +3075,8 @@ static int ufshcd_clear_cmd(struct ufs_hba *hba, u32 task_tag)
 		return 0;
 	}
 
+	mask = 1U << task_tag;
+
 	/* clear outstanding transaction before retry */
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	ufshcd_utrl_clear(hba, mask);
-- 
2.18.0



From Hari.PrasathGE at microchip.com  Mon Feb  5 02:52:01 2024
From: Hari.PrasathGE at microchip.com (Hari Prasath Gujulan Elango)
Date: Mon, 5 Feb 2024 16:22:01 +0530
Subject: [PATCH] dt-bindings: ata: atmel: remove at91 compact flash documentation
Message-ID: <20240205105201.81060-1-Hari.PrasathGE@microchip.com>

The compatible "at91rm9200-cf" is not used by any driver,hence remove the
corresponding documentation.

Signed-off-by: Hari Prasath Gujulan Elango <Hari.PrasathGE at microchip.com>
---
 .../devicetree/bindings/ata/atmel-at91_cf.txt | 19 -------------------
 1 file changed, 19 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/ata/atmel-at91_cf.txt

diff --git a/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt b/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt
deleted file mode 100644
index c1d22b3ae134..000000000000
--- a/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Atmel AT91RM9200 CompactFlash
-
-Required properties:
-- compatible : "atmel,at91rm9200-cf".
-- reg : should specify localbus address and size used.
-- gpios : specifies the gpio pins to control the CF device. Detect
-  and reset gpio's are mandatory while irq and vcc gpio's are
-  optional and may be set to 0 if not present.
-
-Example:
-compact-flash at 50000000 {
-	compatible = "atmel,at91rm9200-cf";
-	reg = <0x50000000 0x30000000>;
-	gpios = <&pioC 13 0	/* irq */
-		 &pioC 15 0 	/* detect */
-		 0		/* vcc */
-		 &pioC  5 0	/* reset */
-		>;
-};
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Mon Feb  5 03:03:28 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 12:03:28 +0100
Subject: [PATCH v2 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <CADrjBPrNryfccFkrZWY9_4EfDF1h3VyqKcxh8vim9Hp8D_AhkQ@mail.gmail.com>
References: <20240129211912.3068411-1-peter.griffin@linaro.org>
 <20240129211912.3068411-2-peter.griffin@linaro.org>
 <fb530eb8-e32b-4faf-81f3-efc334ebf241@linaro.org>
 <CADrjBPrNryfccFkrZWY9_4EfDF1h3VyqKcxh8vim9Hp8D_AhkQ@mail.gmail.com>
Message-ID: <8124a8f7-23c0-4773-aec2-0a3f70ee7e11@linaro.org>

On 01/02/2024 12:29, Peter Griffin wrote:
>>>       int ret;
>>>
>>>       pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
>>> @@ -137,6 +333,35 @@ static int exynos_pmu_probe(struct platform_device *pdev)
>>>                       GFP_KERNEL);
>>>       if (!pmu_context)
>>>               return -ENOMEM;
>>> +
>>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> +     if (!res)
>>> +             return -ENODEV;
>>> +
>>> +     pmuregmap_config.max_register = resource_size(res) -
>>> +                                  pmuregmap_config.reg_stride;
>>> +
>>> +     if (of_device_is_compatible(np, "google,gs101-pmu")) {
>>
>> No compatibles inside the probe. Use driver match data. This applies to
>> all drivers in all subsystems.
> 
> Noted, will fix in v3.
> 
>>
>>> +             pmuregmap_config.reg_read = tensor_sec_reg_read;
>>> +             pmuregmap_config.reg_write = tensor_sec_reg_write;
>>> +             pmuregmap_config.reg_update_bits = tensor_sec_update_bits;
>>
>> No, regmap_config should be const and please use match data.
> 
> Are you sure you want the regmap_config struct const?
> 
> In my draft v3 I have implemented it so far having a regmap_smccfg
> struct which sets all the configuration apart from max_register field
> (used by gs101) and a regmap_mmiocfg struct (used by all other
> exynos-pmu SoCs). The choice over which regmap_config to register is
> made via match data exynos_pmu_data flag 'pmu_secure' which is set
> only for gs101. That avoids having to define exynos_pmu_data structs
> for the other exynos SoCs that currently don't really need them
> (exynos7, exynos850, exynos5443, exyno5410 etc).
> 
> But I still wish to set at runtime the regmap_config.max_register
> field based on the resource size coming from DT. Having the structs
> const would prohibit that and mean we need to specify many more
> regmap_config structs where the only difference is the max_register
> field.
> 
> Is the above approach acceptable for you?

Having it non-const is one more step of supporting only one instance of
PMU device, but we already rely on such design choice, so I guess it is
fine. If ever needed, this can be easily converted to devm_kmemdup...


Best regards,
Krzysztof



From neil.armstrong at linaro.org  Mon Feb  5 03:17:57 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 5 Feb 2024 12:17:57 +0100
Subject: [PATCH V8 09/12] dt-bindings: display: imx: add binding for
 i.MX8MP HDMI TX
In-Reply-To: <20240203165307.7806-10-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-10-aford173@gmail.com>
Message-ID: <fabde8a2-1fab-45bd-8250-898254e0ba8d@linaro.org>

On 03/02/2024 17:52, Adam Ford wrote:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> The HDMI TX controller on the i.MX8MP SoC is a Synopsys designware IP
> core with a little bit of SoC integration around it.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 
> ---
> V3:  Change name and location to better idenfity as a bridge and
>       HDMI 2.0a transmitter
> 
>       Fix typos and feedback from Rob and added ports.
> ---
>   .../display/bridge/fsl,imx8mp-hdmi-tx.yaml    | 102 ++++++++++++++++++
>   1 file changed, 102 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> new file mode 100644
> index 000000000000..3791c9f4ebab
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> @@ -0,0 +1,102 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/bridge/fsl,imx8mp-hdmi-tx.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX8MP DWC HDMI TX Encoder
> +
> +maintainers:
> +  - Lucas Stach <l.stach at pengutronix.de>
> +
> +description:
> +  The i.MX8MP HDMI transmitter is a Synopsys DesignWare
> +  HDMI 2.0a TX controller IP.
> +
> +allOf:
> +  - $ref: /schemas/display/bridge/synopsys,dw-hdmi.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - fsl,imx8mp-hdmi-tx
> +
> +  reg-io-width:
> +    const: 1
> +
> +  clocks:
> +    maxItems: 4
> +
> +  clock-names:
> +    items:
> +      - const: iahb
> +      - const: isfr
> +      - const: cec
> +      - const: pix
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Parallel RGB input port
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: HDMI output port
> +
> +    required:
> +      - port at 0
> +      - port at 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - interrupts
> +  - power-domains
> +  - ports
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/imx8mp-clock.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/power/imx8mp-power.h>
> +
> +    hdmi at 32fd8000 {
> +        compatible = "fsl,imx8mp-hdmi-tx";
> +        reg = <0x32fd8000 0x7eff>;
> +        interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
> +        clocks = <&clk IMX8MP_CLK_HDMI_APB>,
> +                 <&clk IMX8MP_CLK_HDMI_REF_266M>,
> +                 <&clk IMX8MP_CLK_32K>,
> +                 <&hdmi_tx_phy>;
> +        clock-names = "iahb", "isfr", "cec", "pix";
> +        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
> +        reg-io-width = <1>;
> +        ports {
> +           #address-cells = <1>;
> +           #size-cells = <0>;
> +           port at 0 {
> +             reg = <0>;
> +
> +             hdmi_tx_from_pvi: endpoint {
> +               remote-endpoint = <&pvi_to_hdmi_tx>;
> +             };
> +          };
> +
> +          port at 1 {
> +            reg = <1>;
> +              hdmi_tx_out: endpoint {
> +                remote-endpoint = <&hdmi0_con>;
> +              };
> +          };
> +        };
> +    };

I'll apply patches 9 & 10 once this one is properly reviewed

Thanks,
Neil


From neil.armstrong at linaro.org  Mon Feb  5 03:19:11 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 05 Feb 2024 12:19:11 +0100
Subject: (subset) [PATCH V8 00/12] soc: imx8mp: Add support for HDMI
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <170713195198.1366121.9704774035651608603.b4-ty@linaro.org>

Hi,

On Sat, 03 Feb 2024 10:52:40 -0600, Adam Ford wrote:
> The i.MX8M Plus has an HDMI controller, but it depends on two
> other systems, the Parallel Video Interface (PVI) and the
> HDMI PHY from Samsung. The LCDIF controller generates the display
> and routes it to the PVI which converts passes the parallel video
> to the HDMI bridge.  The HDMI system has a corresponding power
> domain controller whose driver was partially written, but the
> device tree for it was never applied, so some changes to the
> power domain should be harmless because they've not really been
> used yet.
> 
> [...]

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git (drm-misc-next)

[07/12] dt-bindings: display: imx: add binding for i.MX8MP HDMI PVI
        https://cgit.freedesktop.org/drm/drm-misc/commit/?id=f490d0cb9360466f6df0def3eccc47fabba9775b
[08/12] drm/bridge: imx: add driver for HDMI TX Parallel Video Interface
        https://cgit.freedesktop.org/drm/drm-misc/commit/?id=059c53e877ca6e723e10490c27c1487a63e66efe

-- 
Neil



From cristian.ciocaltea at collabora.com  Mon Feb  5 03:24:23 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 05 Feb 2024 13:24:23 +0200
Subject: [PATCH v2 0/2] Add support for RK3588 HDMI/eDP Combo PHY
Message-ID: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>

Add driver and bindings to add initial support the Rockchip HDMI/eDP TX
Combo PHY found on RK3588 SoC.

The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
and eDP links.

Please note that currently only the TMDS related functionality has been
implemented.  This has been tested on Radxa ROCK 5B and Rockchip EVB1
boards.

Changes in v2:
- Rebased series onto next-20240129
- Removed patch 'dt-bindings: soc: rockchip: Add rk3588 hdptxphy syscon'
  already applied by Heiko
- For consistency with SoC TRM, replaced all references to DP with eDP
- Updated PHY schema per Krzysztof's review; also collected his R-b tag
- Dropped FRL, EARC and 10-bit color depth functionality until the HDMI
  configuration options become available in PHY API
- Squashed lots of regmap_write operations via regmap_multi_reg_write
  (Sebastian)
- Introduced parametrized {CMN|SB|LNTOP|LANE}_REG() macros to replace
  the long list of register defines
- Optimized handling of the config arrays by using ARRAY_SIZE() (Sascha)
- Link to v1:
  https://lore.kernel.org/r/20240119193806.1030214-1-cristian.ciocaltea at collabora.com

---
Cristian Ciocaltea (2):
      dt-bindings: phy: Add Rockchip HDMI/eDP Combo PHY schema
      phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver

 .../bindings/phy/rockchip,rk3588-hdptx-phy.yaml    |   91 ++
 drivers/phy/rockchip/Kconfig                       |    8 +
 drivers/phy/rockchip/Makefile                      |    1 +
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c  | 1040 ++++++++++++++++++++
 4 files changed, 1140 insertions(+)
---
base-commit: 596764183be8ebb13352b281a442a1f1151c9b06
change-id: 20240128-phy-hdptx-8a98ab60d18e



From cristian.ciocaltea at collabora.com  Mon Feb  5 03:24:24 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 05 Feb 2024 13:24:24 +0200
Subject: [PATCH v2 1/2] dt-bindings: phy: Add Rockchip HDMI/eDP Combo PHY
 schema
In-Reply-To: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
References: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
Message-ID: <20240205-phy-hdptx-v2-1-a7150814c047@collabora.com>

Add dt-binding schema for the HDMI/eDP Transmitter Combo PHY found on
Rockchip RK3588 SoC.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 .../bindings/phy/rockchip,rk3588-hdptx-phy.yaml    | 91 ++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml
new file mode 100644
index 000000000000..54e822c715f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml
@@ -0,0 +1,91 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/rockchip,rk3588-hdptx-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC HDMI/eDP Transmitter Combo PHY
+
+maintainers:
+  - Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3588-hdptx-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Reference clock
+      - description: APB clock
+
+  clock-names:
+    items:
+      - const: ref
+      - const: apb
+
+  "#phy-cells":
+    const: 0
+
+  resets:
+    items:
+      - description: PHY reset line
+      - description: APB reset line
+      - description: INIT reset line
+      - description: CMN reset line
+      - description: LANE reset line
+      - description: ROPLL reset line
+      - description: LCPLL reset line
+
+  reset-names:
+    items:
+      - const: phy
+      - const: apb
+      - const: init
+      - const: cmn
+      - const: lane
+      - const: ropll
+      - const: lcpll
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: Some PHY related data is accessed through GRF regs.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+  - resets
+  - reset-names
+  - rockchip,grf
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
+    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      phy at fed60000 {
+        compatible = "rockchip,rk3588-hdptx-phy";
+        reg = <0x0 0xfed60000 0x0 0x2000>;
+        clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
+        clock-names = "ref", "apb";
+        #phy-cells = <0>;
+        resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
+                 <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
+                 <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
+                 <&cru SRST_HDPTX0_LCPLL>;
+        reset-names = "phy", "apb", "init", "cmn", "lane", "ropll", "lcpll";
+        rockchip,grf = <&hdptxphy_grf>;
+      };
+    };

-- 
2.43.0



From cristian.ciocaltea at collabora.com  Mon Feb  5 03:24:25 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 05 Feb 2024 13:24:25 +0200
Subject: [PATCH v2 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
References: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
Message-ID: <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>

Add driver for the HDMI/eDP TX Combo PHY found on Rockchip RK3588 SoC.

The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
and eDP links.  The maximum data rate is 12Gbps (FRL), while the minimum
is 250Mbps (TMDS).

Only the TMDS link is currently supported.

Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/Kconfig                      |    8 +
 drivers/phy/rockchip/Makefile                     |    1 +
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 1040 +++++++++++++++++++++
 3 files changed, 1049 insertions(+)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 94360fc96a6f..a34f67bb7e61 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -83,6 +83,14 @@ config PHY_ROCKCHIP_PCIE
 	help
 	  Enable this to support the Rockchip PCIe PHY.
 
+config PHY_ROCKCHIP_SAMSUNG_HDPTX
+	tristate "Rockchip Samsung HDMI/eDP Combo PHY driver"
+	depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
+	select GENERIC_PHY
+	help
+	  Enable this to support the Rockchip HDMI/eDP Combo PHY
+	  with Samsung IP block.
+
 config PHY_ROCKCHIP_SNPS_PCIE3
 	tristate "Rockchip Snps PCIe3 PHY Driver"
 	depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
index 7eab129230d1..3d911304e654 100644
--- a/drivers/phy/rockchip/Makefile
+++ b/drivers/phy/rockchip/Makefile
@@ -8,6 +8,7 @@ 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_SAMSUNG_HDPTX)	+= phy-rockchip-samsung-hdptx.o
 obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3)	+= phy-rockchip-snps-pcie3.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-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
new file mode 100644
index 000000000000..744bbe8280a8
--- /dev/null
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -0,0 +1,1040 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2024 Collabora Ltd.
+ *
+ * Author: Algea Cao <algea.cao at rock-chips.com>
+ * Author: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/rational.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#define GRF_HDPTX_CON0			0x00
+#define HDPTX_I_PLL_EN			BIT(7)
+#define HDPTX_I_BIAS_EN			BIT(6)
+#define HDPTX_I_BGR_EN			BIT(5)
+#define GRF_HDPTX_STATUS		0x80
+#define HDPTX_O_PLL_LOCK_DONE		BIT(3)
+#define HDPTX_O_PHY_CLK_RDY		BIT(2)
+#define HDPTX_O_PHY_RDY			BIT(1)
+#define HDPTX_O_SB_RDY			BIT(0)
+
+#define HDTPX_REG(_n, _min, _max)				\
+	(							\
+		BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) +	\
+		BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) +	\
+		((0x##_n) * 4)					\
+	)
+
+#define CMN_REG(n)			HDTPX_REG(n, 0000, 00A7)
+#define SB_REG(n)			HDTPX_REG(n, 0100, 0129)
+#define LNTOP_REG(n)			HDTPX_REG(n, 0200, 0229)
+#define LANE_REG(n)			HDTPX_REG(n, 0300, 062D)
+
+/* CMN_REG(0008) */
+#define LCPLL_EN_MASK			BIT(6)
+#define LCPLL_LCVCO_MODE_EN_MASK	BIT(4)
+/* CMN_REG(001E) */
+#define LCPLL_PI_EN_MASK		BIT(5)
+#define LCPLL_100M_CLK_EN_MASK		BIT(0)
+/* CMN_REG(0025) */
+#define LCPLL_PMS_IQDIV_RSTN		BIT(4)
+/* CMN_REG(0028) */
+#define LCPLL_SDC_FRAC_EN		BIT(2)
+#define LCPLL_SDC_FRAC_RSTN		BIT(0)
+/* CMN_REG(002D) */
+#define LCPLL_SDC_N_MASK		GENMASK(3, 1)
+/* CMN_REG(002E) */
+#define LCPLL_SDC_NUMBERATOR_MASK	GENMASK(5, 0)
+/* CMN_REG(002F) */
+#define LCPLL_SDC_DENOMINATOR_MASK	GENMASK(7, 2)
+#define LCPLL_SDC_NDIV_RSTN		BIT(0)
+/* CMN_REG(003D) */
+#define ROPLL_LCVCO_EN			BIT(4)
+/* CMN_REG(004E) */
+#define ROPLL_PI_EN			BIT(5)
+/* CMN_REG(005C) */
+#define ROPLL_PMS_IQDIV_RSTN		BIT(5)
+/* CMN_REG(005E) */
+#define ROPLL_SDM_EN_MASK		BIT(6)
+#define ROPLL_SDM_FRAC_EN_RBR		BIT(3)
+#define ROPLL_SDM_FRAC_EN_HBR		BIT(2)
+#define ROPLL_SDM_FRAC_EN_HBR2		BIT(1)
+#define ROPLL_SDM_FRAC_EN_HBR3		BIT(0)
+/* CMN_REG(0064) */
+#define ROPLL_SDM_NUM_SIGN_RBR_MASK	BIT(3)
+/* CMN_REG(0069) */
+#define ROPLL_SDC_N_RBR_MASK		GENMASK(2, 0)
+/* CMN_REG(0074) */
+#define ROPLL_SDC_NDIV_RSTN		BIT(2)
+#define ROPLL_SSC_EN			BIT(0)
+/* CMN_REG(0081) */
+#define OVRD_PLL_CD_CLK_EN		BIT(8)
+#define PLL_CD_HSCLK_EAST_EN		BIT(0)
+/* CMN_REG(0086) */
+#define PLL_PCG_POSTDIV_SEL_MASK	GENMASK(7, 4)
+#define PLL_PCG_CLK_SEL_MASK		GENMASK(3, 1)
+#define PLL_PCG_CLK_EN			BIT(0)
+/* CMN_REG(0087) */
+#define PLL_FRL_MODE_EN			BIT(3)
+#define PLL_TX_HS_CLK_EN		BIT(2)
+/* CMN_REG(0089) */
+#define LCPLL_ALONE_MODE		BIT(1)
+/* CMN_REG(0097) */
+#define DIG_CLK_SEL			BIT(1)
+#define ROPLL_REF			BIT(1)
+#define LCPLL_REF			0
+/* CMN_REG(0099) */
+#define CMN_ROPLL_ALONE_MODE		BIT(2)
+#define ROPLL_ALONE_MODE		BIT(2)
+/* CMN_REG(009A) */
+#define HS_SPEED_SEL			BIT(0)
+#define DIV_10_CLOCK			BIT(0)
+/* CMN_REG(009B) */
+#define IS_SPEED_SEL			BIT(4)
+#define LINK_SYMBOL_CLOCK		BIT(4)
+#define LINK_SYMBOL_CLOCK1_2		0
+
+/* SB_REG(0102) */
+#define OVRD_SB_RXTERM_EN_MASK		BIT(5)
+#define SB_RXTERM_EN_MASK		BIT(4)
+#define ANA_SB_RXTERM_OFFSP_MASK	GENMASK(3, 0)
+/* SB_REG(0103) */
+#define ANA_SB_RXTERM_OFFSN_MASK	GENMASK(6, 3)
+#define OVRD_SB_RX_RESCAL_DONE_MASK	BIT(1)
+#define SB_RX_RESCAL_DONE_MASK		BIT(0)
+/* SB_REG(0104) */
+#define OVRD_SB_EN_MASK			BIT(5)
+#define SB_EN_MASK			BIT(4)
+/* SB_REG(0105) */
+#define OVRD_SB_EARC_CMDC_EN_MASK	BIT(6)
+#define SB_EARC_CMDC_EN_MASK		BIT(5)
+#define ANA_SB_TX_HLVL_PROG_MASK	GENMASK(2, 0)
+/* SB_REG(0106) */
+#define ANA_SB_TX_LLVL_PROG_MASK	GENMASK(6, 4)
+/* SB_REG(0109) */
+#define ANA_SB_DMRX_AFC_DIV_RATIO_MASK	GENMASK(2, 0)
+/* SB_REG(010F) */
+#define OVRD_SB_VREG_EN_MASK		BIT(7)
+#define SB_VREG_EN_MASK			BIT(6)
+#define OVRD_SB_VREG_LPF_BYPASS_MASK	BIT(5)
+#define SB_VREG_LPF_BYPASS_MASK		BIT(4)
+#define ANA_SB_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
+/* SB_REG(0110) */
+#define ANA_SB_VREG_REF_SEL_MASK	BIT(0)
+/* SB_REG(0113) */
+#define SB_RX_RCAL_OPT_CODE_MASK	GENMASK(5, 4)
+#define SB_RX_RTERM_CTRL_MASK		GENMASK(3, 0)
+/* SB_REG(0114) */
+#define SB_TG_SB_EN_DELAY_TIME_MASK	GENMASK(5, 3)
+#define SB_TG_RXTERM_EN_DELAY_TIME_MASK	GENMASK(2, 0)
+/* SB_REG(0115) */
+#define SB_READY_DELAY_TIME_MASK	GENMASK(5, 3)
+#define SB_TG_OSC_EN_DELAY_TIME_MASK	GENMASK(2, 0)
+/* SB_REG(0116) */
+#define AFC_RSTN_DELAY_TIME_MASK	GENMASK(6, 4)
+/* SB_REG(0117) */
+#define FAST_PULSE_TIME_MASK		GENMASK(3, 0)
+/* SB_REG(011B) */
+#define SB_EARC_SIG_DET_BYPASS_MASK	BIT(4)
+#define SB_AFC_TOL_MASK			GENMASK(3, 0)
+/* SB_REG(011F) */
+#define SB_PWM_AFC_CTRL_MASK		GENMASK(7, 2)
+#define SB_RCAL_RSTN_MASK		BIT(1)
+/* SB_REG(0120) */
+#define SB_EARC_EN_MASK			BIT(1)
+#define SB_EARC_AFC_EN_MASK		BIT(2)
+/* SB_REG(0123) */
+#define OVRD_SB_READY_MASK		BIT(5)
+#define SB_READY_MASK			BIT(4)
+
+/* LNTOP_REG(0200) */
+#define PROTOCOL_SEL			BIT(2)
+#define HDMI_MODE			BIT(2)
+#define HDMI_TMDS_FRL_SEL		BIT(1)
+/* LNTOP_REG(0206) */
+#define DATA_BUS_SEL			BIT(0)
+#define DATA_BUS_36_40			BIT(0)
+/* LNTOP_REG(0207) */
+#define LANE_EN				0xf
+#define ALL_LANE_EN			0xf
+
+/* LANE_REG(0312) */
+#define LN0_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN0_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN0_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN0_TX_SER_RATE_SEL_HBR3	BIT(2)
+/* LANE_REG(0412) */
+#define LN1_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN1_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN1_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN1_TX_SER_RATE_SEL_HBR3	BIT(2)
+/* LANE_REG(0512) */
+#define LN2_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN2_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN2_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN2_TX_SER_RATE_SEL_HBR3	BIT(2)
+/* LANE_REG(0612) */
+#define LN3_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN3_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN3_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN3_TX_SER_RATE_SEL_HBR3	BIT(2)
+
+struct lcpll_config {
+	u32 bit_rate;
+	u8 lcvco_mode_en;
+	u8 pi_en;
+	u8 clk_en_100m;
+	u8 pms_mdiv;
+	u8 pms_mdiv_afc;
+	u8 pms_pdiv;
+	u8 pms_refdiv;
+	u8 pms_sdiv;
+	u8 pi_cdiv_rstn;
+	u8 pi_cdiv_sel;
+	u8 sdm_en;
+	u8 sdm_rstn;
+	u8 sdc_frac_en;
+	u8 sdc_rstn;
+	u8 sdm_deno;
+	u8 sdm_num_sign;
+	u8 sdm_num;
+	u8 sdc_n;
+	u8 sdc_n2;
+	u8 sdc_num;
+	u8 sdc_deno;
+	u8 sdc_ndiv_rstn;
+	u8 ssc_en;
+	u8 ssc_fm_dev;
+	u8 ssc_fm_freq;
+	u8 ssc_clk_div_sel;
+	u8 cd_tx_ser_rate_sel;
+};
+
+struct ropll_config {
+	u32 bit_rate;
+	u8 pms_mdiv;
+	u8 pms_mdiv_afc;
+	u8 pms_pdiv;
+	u8 pms_refdiv;
+	u8 pms_sdiv;
+	u8 pms_iqdiv_rstn;
+	u8 ref_clk_sel;
+	u8 sdm_en;
+	u8 sdm_rstn;
+	u8 sdc_frac_en;
+	u8 sdc_rstn;
+	u8 sdm_clk_div;
+	u8 sdm_deno;
+	u8 sdm_num_sign;
+	u8 sdm_num;
+	u8 sdc_n;
+	u8 sdc_num;
+	u8 sdc_deno;
+	u8 sdc_ndiv_rstn;
+	u8 ssc_en;
+	u8 ssc_fm_dev;
+	u8 ssc_fm_freq;
+	u8 ssc_clk_div_sel;
+	u8 ana_cpp_ctrl;
+	u8 ana_lpf_c_sel;
+	u8 cd_tx_ser_rate_sel;
+};
+
+enum rockchip_hdptx_reset {
+	RST_PHY = 0,
+	RST_APB,
+	RST_INIT,
+	RST_CMN,
+	RST_LANE,
+	RST_ROPLL,
+	RST_LCPLL,
+	RST_MAX
+};
+
+struct rockchip_hdptx_phy {
+	struct device *dev;
+	struct regmap *regmap;
+	struct regmap *grf;
+
+	struct phy *phy;
+	struct phy_config *phy_cfg;
+	struct clk_bulk_data *clks;
+	int nr_clks;
+	struct reset_control_bulk_data rsts[RST_MAX];
+};
+
+static const struct ropll_config ropll_tmds_cfg[] = {
+	{ 5940000, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 3712500, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 2970000, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1620000, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1856250, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1540000, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1485000, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5,
+	  0x10, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1462500, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1190000, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1065000, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1080000, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 855000, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 835000, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 928125, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 742500, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 650000, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 337500, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5,
+	  1, 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 400000, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 270000, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 251750, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+};
+
+static const struct reg_sequence hdtpx_common_cmn_init_seq[] = {
+	REG_SEQ0(CMN_REG(0009), 0x0c),
+	REG_SEQ0(CMN_REG(000A), 0x83),
+	REG_SEQ0(CMN_REG(000B), 0x06),
+	REG_SEQ0(CMN_REG(000C), 0x20),
+	REG_SEQ0(CMN_REG(000D), 0xb8),
+	REG_SEQ0(CMN_REG(000E), 0x0f),
+	REG_SEQ0(CMN_REG(000F), 0x0f),
+	REG_SEQ0(CMN_REG(0010), 0x04),
+	REG_SEQ0(CMN_REG(0011), 0x00),
+	REG_SEQ0(CMN_REG(0012), 0x26),
+	REG_SEQ0(CMN_REG(0013), 0x22),
+	REG_SEQ0(CMN_REG(0014), 0x24),
+	REG_SEQ0(CMN_REG(0015), 0x77),
+	REG_SEQ0(CMN_REG(0016), 0x08),
+	REG_SEQ0(CMN_REG(0017), 0x00),
+	REG_SEQ0(CMN_REG(0018), 0x04),
+	REG_SEQ0(CMN_REG(0019), 0x48),
+	REG_SEQ0(CMN_REG(001A), 0x01),
+	REG_SEQ0(CMN_REG(001B), 0x00),
+	REG_SEQ0(CMN_REG(001C), 0x01),
+	REG_SEQ0(CMN_REG(001D), 0x64),
+	REG_SEQ0(CMN_REG(001F), 0x00),
+	REG_SEQ0(CMN_REG(0026), 0x53),
+	REG_SEQ0(CMN_REG(0029), 0x01),
+	REG_SEQ0(CMN_REG(0030), 0x00),
+	REG_SEQ0(CMN_REG(0031), 0x20),
+	REG_SEQ0(CMN_REG(0032), 0x30),
+	REG_SEQ0(CMN_REG(0033), 0x0b),
+	REG_SEQ0(CMN_REG(0034), 0x23),
+	REG_SEQ0(CMN_REG(0035), 0x00),
+	REG_SEQ0(CMN_REG(0038), 0x00),
+	REG_SEQ0(CMN_REG(0039), 0x00),
+	REG_SEQ0(CMN_REG(003A), 0x00),
+	REG_SEQ0(CMN_REG(003B), 0x00),
+	REG_SEQ0(CMN_REG(003C), 0x80),
+	REG_SEQ0(CMN_REG(003E), 0x0c),
+	REG_SEQ0(CMN_REG(003F), 0x83),
+	REG_SEQ0(CMN_REG(0040), 0x06),
+	REG_SEQ0(CMN_REG(0041), 0x20),
+	REG_SEQ0(CMN_REG(0042), 0xb8),
+	REG_SEQ0(CMN_REG(0043), 0x00),
+	REG_SEQ0(CMN_REG(0044), 0x46),
+	REG_SEQ0(CMN_REG(0045), 0x24),
+	REG_SEQ0(CMN_REG(0046), 0xff),
+	REG_SEQ0(CMN_REG(0047), 0x00),
+	REG_SEQ0(CMN_REG(0048), 0x44),
+	REG_SEQ0(CMN_REG(0049), 0xfa),
+	REG_SEQ0(CMN_REG(004A), 0x08),
+	REG_SEQ0(CMN_REG(004B), 0x00),
+	REG_SEQ0(CMN_REG(004C), 0x01),
+	REG_SEQ0(CMN_REG(004D), 0x64),
+	REG_SEQ0(CMN_REG(004E), 0x14),
+	REG_SEQ0(CMN_REG(004F), 0x00),
+	REG_SEQ0(CMN_REG(0050), 0x00),
+	REG_SEQ0(CMN_REG(005D), 0x0c),
+	REG_SEQ0(CMN_REG(005F), 0x01),
+	REG_SEQ0(CMN_REG(006B), 0x04),
+	REG_SEQ0(CMN_REG(0073), 0x30),
+	REG_SEQ0(CMN_REG(0074), 0x00),
+	REG_SEQ0(CMN_REG(0075), 0x20),
+	REG_SEQ0(CMN_REG(0076), 0x30),
+	REG_SEQ0(CMN_REG(0077), 0x08),
+	REG_SEQ0(CMN_REG(0078), 0x0c),
+	REG_SEQ0(CMN_REG(0079), 0x00),
+	REG_SEQ0(CMN_REG(007B), 0x00),
+	REG_SEQ0(CMN_REG(007C), 0x00),
+	REG_SEQ0(CMN_REG(007D), 0x00),
+	REG_SEQ0(CMN_REG(007E), 0x00),
+	REG_SEQ0(CMN_REG(007F), 0x00),
+	REG_SEQ0(CMN_REG(0080), 0x00),
+	REG_SEQ0(CMN_REG(0081), 0x09),
+	REG_SEQ0(CMN_REG(0082), 0x04),
+	REG_SEQ0(CMN_REG(0083), 0x24),
+	REG_SEQ0(CMN_REG(0084), 0x20),
+	REG_SEQ0(CMN_REG(0085), 0x03),
+	REG_SEQ0(CMN_REG(0086), 0x01),
+	REG_SEQ0(CMN_REG(0087), 0x0c),
+	REG_SEQ0(CMN_REG(008A), 0x55),
+	REG_SEQ0(CMN_REG(008B), 0x25),
+	REG_SEQ0(CMN_REG(008C), 0x2c),
+	REG_SEQ0(CMN_REG(008D), 0x22),
+	REG_SEQ0(CMN_REG(008E), 0x14),
+	REG_SEQ0(CMN_REG(008F), 0x20),
+	REG_SEQ0(CMN_REG(0090), 0x00),
+	REG_SEQ0(CMN_REG(0091), 0x00),
+	REG_SEQ0(CMN_REG(0092), 0x00),
+	REG_SEQ0(CMN_REG(0093), 0x00),
+	REG_SEQ0(CMN_REG(009A), 0x11),
+	REG_SEQ0(CMN_REG(009B), 0x10),
+};
+
+static const struct reg_sequence hdtpx_tmds_cmn_init_seq[] = {
+	REG_SEQ0(CMN_REG(0008), 0x00),
+	REG_SEQ0(CMN_REG(0011), 0x01),
+	REG_SEQ0(CMN_REG(0017), 0x20),
+	REG_SEQ0(CMN_REG(001E), 0x14),
+	REG_SEQ0(CMN_REG(0020), 0x00),
+	REG_SEQ0(CMN_REG(0021), 0x00),
+	REG_SEQ0(CMN_REG(0022), 0x11),
+	REG_SEQ0(CMN_REG(0023), 0x00),
+	REG_SEQ0(CMN_REG(0024), 0x00),
+	REG_SEQ0(CMN_REG(0025), 0x53),
+	REG_SEQ0(CMN_REG(0026), 0x00),
+	REG_SEQ0(CMN_REG(0027), 0x00),
+	REG_SEQ0(CMN_REG(0028), 0x01),
+	REG_SEQ0(CMN_REG(002A), 0x00),
+	REG_SEQ0(CMN_REG(002B), 0x00),
+	REG_SEQ0(CMN_REG(002C), 0x00),
+	REG_SEQ0(CMN_REG(002D), 0x00),
+	REG_SEQ0(CMN_REG(002E), 0x04),
+	REG_SEQ0(CMN_REG(002F), 0x00),
+	REG_SEQ0(CMN_REG(0030), 0x20),
+	REG_SEQ0(CMN_REG(0031), 0x30),
+	REG_SEQ0(CMN_REG(0032), 0x0b),
+	REG_SEQ0(CMN_REG(0033), 0x23),
+	REG_SEQ0(CMN_REG(0034), 0x00),
+	REG_SEQ0(CMN_REG(003D), 0x40),
+	REG_SEQ0(CMN_REG(0042), 0x78),
+	REG_SEQ0(CMN_REG(004E), 0x34),
+	REG_SEQ0(CMN_REG(005C), 0x25),
+	REG_SEQ0(CMN_REG(005E), 0x4f),
+	REG_SEQ0(CMN_REG(0074), 0x04),
+	REG_SEQ0(CMN_REG(0081), 0x01),
+	REG_SEQ0(CMN_REG(0087), 0x04),
+	REG_SEQ0(CMN_REG(0089), 0x00),
+	REG_SEQ0(CMN_REG(0095), 0x00),
+	REG_SEQ0(CMN_REG(0097), 0x02),
+	REG_SEQ0(CMN_REG(0099), 0x04),
+	REG_SEQ0(CMN_REG(009B), 0x00),
+};
+
+static const struct reg_sequence hdtpx_common_sb_init_seq[] = {
+	REG_SEQ0(SB_REG(0114), 0x00),
+	REG_SEQ0(SB_REG(0115), 0x00),
+	REG_SEQ0(SB_REG(0116), 0x00),
+	REG_SEQ0(SB_REG(0117), 0x00),
+};
+
+static const struct reg_sequence hdtpx_tmds_lntop_highbr_seq[] = {
+	REG_SEQ0(LNTOP_REG(0201), 0x00),
+	REG_SEQ0(LNTOP_REG(0202), 0x00),
+	REG_SEQ0(LNTOP_REG(0203), 0x0f),
+	REG_SEQ0(LNTOP_REG(0204), 0xff),
+	REG_SEQ0(LNTOP_REG(0205), 0xff),
+};
+
+static const struct reg_sequence hdtpx_tmds_lntop_lowbr_seq[] = {
+	REG_SEQ0(LNTOP_REG(0201), 0x07),
+	REG_SEQ0(LNTOP_REG(0202), 0xc1),
+	REG_SEQ0(LNTOP_REG(0203), 0xf0),
+	REG_SEQ0(LNTOP_REG(0204), 0x7c),
+	REG_SEQ0(LNTOP_REG(0205), 0x1f),
+};
+
+static const struct reg_sequence hdtpx_common_lane_init_seq[] = {
+	REG_SEQ0(LANE_REG(0303), 0x0c),
+	REG_SEQ0(LANE_REG(0307), 0x20),
+	REG_SEQ0(LANE_REG(030A), 0x17),
+	REG_SEQ0(LANE_REG(030B), 0x77),
+	REG_SEQ0(LANE_REG(030C), 0x77),
+	REG_SEQ0(LANE_REG(030D), 0x77),
+	REG_SEQ0(LANE_REG(030E), 0x38),
+	REG_SEQ0(LANE_REG(0310), 0x03),
+	REG_SEQ0(LANE_REG(0311), 0x0f),
+	REG_SEQ0(LANE_REG(0316), 0x02),
+	REG_SEQ0(LANE_REG(031B), 0x01),
+	REG_SEQ0(LANE_REG(031F), 0x15),
+	REG_SEQ0(LANE_REG(0320), 0xa0),
+	REG_SEQ0(LANE_REG(0403), 0x0c),
+	REG_SEQ0(LANE_REG(0407), 0x20),
+	REG_SEQ0(LANE_REG(040A), 0x17),
+	REG_SEQ0(LANE_REG(040B), 0x77),
+	REG_SEQ0(LANE_REG(040C), 0x77),
+	REG_SEQ0(LANE_REG(040D), 0x77),
+	REG_SEQ0(LANE_REG(040E), 0x38),
+	REG_SEQ0(LANE_REG(0410), 0x03),
+	REG_SEQ0(LANE_REG(0411), 0x0f),
+	REG_SEQ0(LANE_REG(0416), 0x02),
+	REG_SEQ0(LANE_REG(041B), 0x01),
+	REG_SEQ0(LANE_REG(041F), 0x15),
+	REG_SEQ0(LANE_REG(0420), 0xa0),
+	REG_SEQ0(LANE_REG(0503), 0x0c),
+	REG_SEQ0(LANE_REG(0507), 0x20),
+	REG_SEQ0(LANE_REG(050A), 0x17),
+	REG_SEQ0(LANE_REG(050B), 0x77),
+	REG_SEQ0(LANE_REG(050C), 0x77),
+	REG_SEQ0(LANE_REG(050D), 0x77),
+	REG_SEQ0(LANE_REG(050E), 0x38),
+	REG_SEQ0(LANE_REG(0510), 0x03),
+	REG_SEQ0(LANE_REG(0511), 0x0f),
+	REG_SEQ0(LANE_REG(0516), 0x02),
+	REG_SEQ0(LANE_REG(051B), 0x01),
+	REG_SEQ0(LANE_REG(051F), 0x15),
+	REG_SEQ0(LANE_REG(0520), 0xa0),
+	REG_SEQ0(LANE_REG(0603), 0x0c),
+	REG_SEQ0(LANE_REG(0607), 0x20),
+	REG_SEQ0(LANE_REG(060A), 0x17),
+	REG_SEQ0(LANE_REG(060B), 0x77),
+	REG_SEQ0(LANE_REG(060C), 0x77),
+	REG_SEQ0(LANE_REG(060D), 0x77),
+	REG_SEQ0(LANE_REG(060E), 0x38),
+	REG_SEQ0(LANE_REG(0610), 0x03),
+	REG_SEQ0(LANE_REG(0611), 0x0f),
+	REG_SEQ0(LANE_REG(0616), 0x02),
+	REG_SEQ0(LANE_REG(061B), 0x01),
+	REG_SEQ0(LANE_REG(061F), 0x15),
+	REG_SEQ0(LANE_REG(0620), 0xa0),
+};
+
+static const struct reg_sequence hdtpx_tmds_lane_init_seq[] = {
+	REG_SEQ0(LANE_REG(0312), 0x00),
+	REG_SEQ0(LANE_REG(031E), 0x00),
+	REG_SEQ0(LANE_REG(0412), 0x00),
+	REG_SEQ0(LANE_REG(041E), 0x00),
+	REG_SEQ0(LANE_REG(0512), 0x00),
+	REG_SEQ0(LANE_REG(051E), 0x00),
+	REG_SEQ0(LANE_REG(0612), 0x00),
+	REG_SEQ0(LANE_REG(061E), 0x08),
+	REG_SEQ0(LANE_REG(0303), 0x2f),
+	REG_SEQ0(LANE_REG(0403), 0x2f),
+	REG_SEQ0(LANE_REG(0503), 0x2f),
+	REG_SEQ0(LANE_REG(0603), 0x2f),
+	REG_SEQ0(LANE_REG(0305), 0x03),
+	REG_SEQ0(LANE_REG(0405), 0x03),
+	REG_SEQ0(LANE_REG(0505), 0x03),
+	REG_SEQ0(LANE_REG(0605), 0x03),
+	REG_SEQ0(LANE_REG(0306), 0x1c),
+	REG_SEQ0(LANE_REG(0406), 0x1c),
+	REG_SEQ0(LANE_REG(0506), 0x1c),
+	REG_SEQ0(LANE_REG(0606), 0x1c),
+};
+
+static bool rockchip_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case 0x0000 ... 0x029c:
+	case 0x0400 ... 0x04a4:
+	case 0x0800 ... 0x08a4:
+	case 0x0c00 ... 0x0cb4:
+	case 0x1000 ... 0x10b4:
+	case 0x1400 ... 0x14b4:
+	case 0x1800 ... 0x18b4:
+		return true;
+	}
+
+	return false;
+}
+
+static const struct regmap_config rockchip_hdptx_phy_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.writeable_reg = rockchip_hdptx_phy_is_rw_reg,
+	.readable_reg = rockchip_hdptx_phy_is_rw_reg,
+	.fast_io = true,
+	.max_register = 0x18b4,
+};
+
+static int hdptx_write(struct rockchip_hdptx_phy *hdptx, u32 reg, u8 val)
+{
+	return regmap_write(hdptx->regmap, reg, val);
+}
+
+#define hdptx_multi_reg_write(hdptx, seq) \
+	regmap_multi_reg_write((hdptx)->regmap, seq, ARRAY_SIZE(seq))
+
+static int hdptx_update_bits(struct rockchip_hdptx_phy *hdptx, u32 reg,
+			     u8 mask, u8 val)
+{
+	return regmap_update_bits(hdptx->regmap, reg, mask, val);
+}
+
+static int hdptx_grf_write(struct rockchip_hdptx_phy *hdptx, u32 reg, u32 val)
+{
+	return regmap_write(hdptx->grf, reg, val);
+}
+
+static u8 hdptx_grf_read(struct rockchip_hdptx_phy *hdptx, u32 reg)
+{
+	u32 val;
+
+	regmap_read(hdptx->grf, reg, &val);
+
+	return val;
+}
+
+static void hdptx_pre_power_up(struct rockchip_hdptx_phy *hdptx)
+{
+	u32 val;
+
+	reset_control_assert(hdptx->rsts[RST_APB].rstc);
+	usleep_range(20, 25);
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+
+	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
+
+	val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
+	hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val);
+}
+
+static int hdptx_post_enable_lane(struct rockchip_hdptx_phy *hdptx)
+{
+	u32 val;
+	int ret;
+
+	reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
+
+	val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
+	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
+	hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val);
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
+				       (val & HDPTX_O_PHY_RDY) &&
+				       (val & HDPTX_O_PLL_LOCK_DONE),
+				       100, 5000);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get PHY lane lock: %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(hdptx->dev, "PHY lane locked\n");
+
+	return 0;
+}
+
+static int hdptx_post_enable_pll(struct rockchip_hdptx_phy *hdptx)
+{
+	u32 val;
+	int ret;
+
+	val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
+	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
+	hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val);
+
+	usleep_range(10, 15);
+	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
+
+	usleep_range(10, 15);
+	val = HDPTX_I_PLL_EN << 16 | HDPTX_I_PLL_EN;
+	hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val);
+
+	usleep_range(10, 15);
+	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
+				       val & HDPTX_O_PHY_CLK_RDY, 20, 400);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get PHY clk ready: %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(hdptx->dev, "PHY clk ready\n");
+
+	return 0;
+}
+
+static void hdptx_phy_disable(struct rockchip_hdptx_phy *hdptx)
+{
+	u32 val;
+
+	/* reset phy and apb, or phy locked flag may keep 1 */
+	reset_control_assert(hdptx->rsts[RST_PHY].rstc);
+	usleep_range(20, 30);
+	reset_control_deassert(hdptx->rsts[RST_PHY].rstc);
+
+	reset_control_assert(hdptx->rsts[RST_APB].rstc);
+	usleep_range(20, 30);
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+
+	hdptx_write(hdptx, LANE_REG(0300), 0x82);
+	hdptx_write(hdptx, SB_REG(010F), 0xc1);
+	hdptx_write(hdptx, SB_REG(0110), 0x1);
+	hdptx_write(hdptx, LANE_REG(0301), 0x80);
+	hdptx_write(hdptx, LANE_REG(0401), 0x80);
+	hdptx_write(hdptx, LANE_REG(0501), 0x80);
+	hdptx_write(hdptx, LANE_REG(0601), 0x80);
+
+	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
+
+	val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
+	hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val);
+}
+
+static bool hdptx_phy_clk_pll_calc(unsigned int data_rate,
+				   struct ropll_config *cfg)
+{
+	const unsigned int fout = data_rate / 2, fref = 24000;
+	unsigned long k = 0, lc, k_sub, lc_sub;
+	unsigned int fvco, sdc;
+	u32 mdiv, sdiv, n = 8;
+
+	for (sdiv = 16; sdiv >= 1; sdiv--) {
+		if (sdiv % 2 && sdiv != 1)
+			continue;
+
+		fvco = fout * sdiv;
+
+		if (fvco < 2000000 || fvco > 4000000)
+			continue;
+
+		mdiv = DIV_ROUND_UP(fvco, fref);
+		if (mdiv < 20 || mdiv > 255)
+			continue;
+
+		if (fref * mdiv - fvco) {
+			for (sdc = 264000; sdc <= 750000; sdc += fref)
+				if (sdc * n > fref * mdiv)
+					break;
+
+			if (sdc > 750000)
+				continue;
+
+			rational_best_approximation(fref * mdiv - fvco,
+						    sdc / 16,
+						    GENMASK(6, 0),
+						    GENMASK(7, 0),
+						    &k, &lc);
+
+			rational_best_approximation(sdc * n - fref * mdiv,
+						    sdc,
+						    GENMASK(6, 0),
+						    GENMASK(7, 0),
+						    &k_sub, &lc_sub);
+		}
+
+		break;
+	}
+
+	if (sdiv < 1)
+		return false;
+
+	if (cfg) {
+		cfg->pms_mdiv = mdiv;
+		cfg->pms_mdiv_afc = mdiv;
+		cfg->pms_pdiv = 1;
+		cfg->pms_refdiv = 1;
+		cfg->pms_sdiv = sdiv - 1;
+
+		cfg->sdm_en = k > 0 ? 1 : 0;
+		if (cfg->sdm_en) {
+			cfg->sdm_deno = lc;
+			cfg->sdm_num_sign = 1;
+			cfg->sdm_num = k;
+			cfg->sdc_n = n - 3;
+			cfg->sdc_num = k_sub;
+			cfg->sdc_deno = lc_sub;
+		}
+	}
+
+	return true;
+}
+
+static int hdptx_ropll_tmds_cmn_config(struct rockchip_hdptx_phy *hdptx,
+				       unsigned int rate)
+{
+	const struct ropll_config *cfg = NULL;
+	struct ropll_config rc = {0};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
+		if (rate == ropll_tmds_cfg[i].bit_rate) {
+			cfg = &ropll_tmds_cfg[i];
+			break;
+		}
+
+	if (!cfg) {
+		if (hdptx_phy_clk_pll_calc(rate, &rc)) {
+			cfg = &rc;
+		} else {
+			dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	dev_dbg(hdptx->dev, "mdiv=%u, sdiv=%u, sdm_en=%u, k_sign=%u, k=%u, lc=%u\n",
+		cfg->pms_mdiv, cfg->pms_sdiv + 1, cfg->sdm_en,
+		cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno);
+
+	hdptx_pre_power_up(hdptx);
+
+	reset_control_assert(hdptx->rsts[RST_ROPLL].rstc);
+	usleep_range(20, 30);
+	reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc);
+
+	hdptx_multi_reg_write(hdptx, hdtpx_common_cmn_init_seq);
+	hdptx_multi_reg_write(hdptx, hdtpx_tmds_cmn_init_seq);
+
+	hdptx_write(hdptx, CMN_REG(0051), cfg->pms_mdiv);
+	hdptx_write(hdptx, CMN_REG(0055), cfg->pms_mdiv_afc);
+	hdptx_write(hdptx, CMN_REG(0059), (cfg->pms_pdiv << 4) | cfg->pms_refdiv);
+	hdptx_write(hdptx, CMN_REG(005A), cfg->pms_sdiv << 4);
+
+	hdptx_update_bits(hdptx, CMN_REG(005E), ROPLL_SDM_EN_MASK,
+			  FIELD_PREP(ROPLL_SDM_EN_MASK, cfg->sdm_en));
+	if (!cfg->sdm_en)
+		hdptx_update_bits(hdptx, CMN_REG(005E), 0xf, 0);
+
+	hdptx_update_bits(hdptx, CMN_REG(0064), ROPLL_SDM_NUM_SIGN_RBR_MASK,
+			  FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, cfg->sdm_num_sign));
+
+	hdptx_write(hdptx, CMN_REG(0060), cfg->sdm_deno);
+	hdptx_write(hdptx, CMN_REG(0065), cfg->sdm_num);
+
+	hdptx_update_bits(hdptx, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,
+			  FIELD_PREP(ROPLL_SDC_N_RBR_MASK, cfg->sdc_n));
+
+	hdptx_write(hdptx, CMN_REG(006C), cfg->sdc_num);
+	hdptx_write(hdptx, CMN_REG(0070), cfg->sdc_deno);
+
+	hdptx_update_bits(hdptx, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,
+			  FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));
+
+	hdptx_update_bits(hdptx, CMN_REG(0086), PLL_PCG_CLK_EN, PLL_PCG_CLK_EN);
+
+	return hdptx_post_enable_pll(hdptx);
+}
+
+static int hdptx_ropll_tmds_mode_config(struct rockchip_hdptx_phy *hdptx,
+					unsigned int rate)
+{
+	int ret;
+
+	if (!(hdptx_grf_read(hdptx, GRF_HDPTX_STATUS) & HDPTX_O_PLL_LOCK_DONE)) {
+		ret = hdptx_ropll_tmds_cmn_config(hdptx, rate);
+		if (ret)
+			return ret;
+	}
+
+	hdptx_multi_reg_write(hdptx, hdtpx_common_sb_init_seq);
+
+	hdptx_write(hdptx, LNTOP_REG(0200), 0x06);
+
+	if (rate >= 3400000) {
+		/* For 1/40 bitrate clk */
+		hdptx_multi_reg_write(hdptx, hdtpx_tmds_lntop_highbr_seq);
+	} else {
+		/* For 1/10 bitrate clk */
+		hdptx_multi_reg_write(hdptx, hdtpx_tmds_lntop_lowbr_seq);
+	}
+
+	hdptx_write(hdptx, LNTOP_REG(0206), 0x07);
+	hdptx_write(hdptx, LNTOP_REG(0207), 0x0f);
+
+	hdptx_multi_reg_write(hdptx, hdtpx_common_lane_init_seq);
+	hdptx_multi_reg_write(hdptx, hdtpx_tmds_lane_init_seq);
+
+	return hdptx_post_enable_lane(hdptx);
+}
+
+static int rockchip_hdptx_phy_power_on(struct phy *phy)
+{
+	struct rockchip_hdptx_phy *hdptx = phy_get_drvdata(phy);
+	int ret, bus_width = phy_get_bus_width(hdptx->phy);
+	/*
+	 * FIXME: Temporary workaround to pass pixel_clk_rate
+	 * from the HDMI bridge driver until phy_configure_opts_hdmi
+	 * becomes available in the PHY API.
+	 */
+	unsigned int rate = bus_width & 0xFFFFFFF;
+
+	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
+		__func__, bus_width, rate);
+
+	ret = pm_runtime_resume_and_get(hdptx->dev);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to resume phy: %d\n", ret);
+		return ret;
+	}
+
+	ret = hdptx_ropll_tmds_mode_config(hdptx, rate);
+	if (ret)
+		pm_runtime_put(hdptx->dev);
+
+	return ret;
+}
+
+static int rockchip_hdptx_phy_power_off(struct phy *phy)
+{
+	struct rockchip_hdptx_phy *hdptx = phy_get_drvdata(phy);
+
+	if (hdptx_grf_read(hdptx, GRF_HDPTX_STATUS) & HDPTX_O_PLL_LOCK_DONE)
+		hdptx_phy_disable(hdptx);
+
+	pm_runtime_put(hdptx->dev);
+
+	return 0;
+}
+
+static const struct phy_ops rockchip_hdptx_phy_ops = {
+	.power_on  = rockchip_hdptx_phy_power_on,
+	.power_off = rockchip_hdptx_phy_power_off,
+	.owner	   = THIS_MODULE,
+};
+
+static int rockchip_hdptx_phy_runtime_suspend(struct device *dev)
+{
+	struct rockchip_hdptx_phy *hdptx = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(hdptx->nr_clks, hdptx->clks);
+
+	return 0;
+}
+
+static int rockchip_hdptx_phy_runtime_resume(struct device *dev)
+{
+	struct rockchip_hdptx_phy *hdptx = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(hdptx->nr_clks, hdptx->clks);
+	if (ret)
+		dev_err(hdptx->dev, "Failed to enable clocks: %d\n", ret);
+
+	return ret;
+}
+
+static int rockchip_hdptx_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rockchip_hdptx_phy *hdptx;
+	struct phy_provider *phy_provider;
+	void __iomem *regs;
+	int ret;
+
+	hdptx = devm_kzalloc(dev, sizeof(*hdptx), GFP_KERNEL);
+	if (!hdptx)
+		return -ENOMEM;
+
+	hdptx->dev = dev;
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return dev_err_probe(dev, PTR_ERR(regs),
+				     "Failed to ioremap resource\n");
+
+	ret = devm_clk_bulk_get_all(dev, &hdptx->clks);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to get clocks\n");
+	if (ret == 0)
+		return dev_err_probe(dev, -EINVAL, "Missing clocks\n");
+
+	hdptx->nr_clks = ret;
+
+	hdptx->regmap = devm_regmap_init_mmio(dev, regs,
+					      &rockchip_hdptx_phy_regmap_config);
+	if (IS_ERR(hdptx->regmap))
+		return dev_err_probe(dev, PTR_ERR(hdptx->regmap),
+				     "Failed to init regmap\n");
+
+	hdptx->rsts[RST_PHY].id = "phy";
+	hdptx->rsts[RST_APB].id = "apb";
+	hdptx->rsts[RST_INIT].id = "init";
+	hdptx->rsts[RST_CMN].id = "cmn";
+	hdptx->rsts[RST_LANE].id = "lane";
+	hdptx->rsts[RST_ROPLL].id = "ropll";
+	hdptx->rsts[RST_LCPLL].id = "lcpll";
+
+	ret = devm_reset_control_bulk_get_exclusive(dev, RST_MAX, hdptx->rsts);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to get resets\n");
+
+	hdptx->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+						     "rockchip,grf");
+	if (IS_ERR(hdptx->grf))
+		return dev_err_probe(dev, PTR_ERR(hdptx->grf),
+				     "Could not get GRF syscon\n");
+
+	hdptx->phy = devm_phy_create(dev, NULL, &rockchip_hdptx_phy_ops);
+	if (IS_ERR(hdptx->phy))
+		return dev_err_probe(dev, PTR_ERR(hdptx->phy),
+				     "Failed to create HDMI PHY\n");
+
+	platform_set_drvdata(pdev, hdptx);
+	phy_set_drvdata(hdptx->phy, hdptx);
+	phy_set_bus_width(hdptx->phy, 8);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider))
+		return dev_err_probe(dev, PTR_ERR(phy_provider),
+				     "Failed to register PHY provider\n");
+
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
+
+	return 0;
+}
+
+static const struct dev_pm_ops rockchip_hdptx_phy_pm_ops = {
+	RUNTIME_PM_OPS(rockchip_hdptx_phy_runtime_suspend,
+		       rockchip_hdptx_phy_runtime_resume, NULL)
+};
+
+static const struct of_device_id rockchip_hdptx_phy_of_match[] = {
+	{ .compatible = "rockchip,rk3588-hdptx-phy", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, rockchip_hdptx_phy_of_match);
+
+static struct platform_driver rockchip_hdptx_phy_driver = {
+	.probe  = rockchip_hdptx_phy_probe,
+	.driver = {
+		.name = "rockchip-hdptx-phy",
+		.pm = &rockchip_hdptx_phy_pm_ops,
+		.of_match_table = rockchip_hdptx_phy_of_match,
+	},
+};
+module_platform_driver(rockchip_hdptx_phy_driver);
+
+MODULE_AUTHOR("Algea Cao <algea.cao at rock-chips.com>");
+MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea at collabora.com>");
+MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver");
+MODULE_LICENSE("GPL");

-- 
2.43.0



From hverkuil-cisco at xs4all.nl  Mon Feb  5 04:00:05 2024
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Mon, 5 Feb 2024 13:00:05 +0100
Subject: [PATCH] media: cec: core: remove length check of Timer Status
In-Reply-To: <20240125132850.10430-1-nini.song@mediatek.com>
References: <20240125132850.10430-1-nini.song@mediatek.com>
Message-ID: <8a4447ba-d4ac-40ac-9d6b-796db37f3100@xs4all.nl>

On 25/01/2024 14:28, nini.song at mediatek.com wrote:
> From: "nini.song" <nini.song at mediatek.com>
> 
> The valid_la is used to check the length requirements,
> including special cases of Timer Status. If the length is
> shorter than 5, that means no Duration Available is returned,
> the message will be forced to be invalid.
> 
> However, the description of Duration Available in the spec
> is that this parameter may be returned when these cases, or
> that it can be optionally return when these cases. The key
> words in the spec description are flexible choices.

Good catch, the spec indeed says 'may', so dropping the check
in this patch is the correct thing to do.

It's merged in our staging tree and it will appear in v6.9.

Regards,

	Hans

> 
> Remove the special length check of Timer Status to fit the
> spec which is not compulsory about that.
> 
> Signed-off-by: Nini Song <nini.song at mediatek.com>
> ---
>  drivers/media/cec/core/cec-adap.c | 14 --------------
>  1 file changed, 14 deletions(-)
> 
> diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
> index 5741adf09a2e..559a172ebc6c 100644
> --- a/drivers/media/cec/core/cec-adap.c
> +++ b/drivers/media/cec/core/cec-adap.c
> @@ -1151,20 +1151,6 @@ void cec_received_msg_ts(struct cec_adapter *adap,
>  	if (valid_la && min_len) {
>  		/* These messages have special length requirements */
>  		switch (cmd) {
> -		case CEC_MSG_TIMER_STATUS:
> -			if (msg->msg[2] & 0x10) {
> -				switch (msg->msg[2] & 0xf) {
> -				case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE:
> -				case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE:
> -					if (msg->len < 5)
> -						valid_la = false;
> -					break;
> -				}
> -			} else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) {
> -				if (msg->len < 5)
> -					valid_la = false;
> -			}
> -			break;
>  		case CEC_MSG_RECORD_ON:
>  			switch (msg->msg[2]) {
>  			case CEC_OP_RECORD_SRC_OWN:



From mark.rutland at arm.com  Mon Feb  5 04:06:18 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 5 Feb 2024 12:06:18 +0000
Subject: [PATCH] arm64: remove unneeded BUILD_BUG_ON assertion
In-Reply-To: <20240202040211.3118918-1-dawei.li@shingroup.cn>
References: <20240202040211.3118918-1-dawei.li@shingroup.cn>
Message-ID: <ZcDPOgoQE8IncTHY@FVFF77S0Q05N>

On Fri, Feb 02, 2024 at 12:02:11PM +0800, Dawei Li wrote:
> Since commit c02433dd6de3 ("arm64: split thread_info from task stack"),
> CONFIG_THREAD_INFO_IN_TASK is enabled unconditionally for arm64. So
> remove this always-true assertion from arch_dup_task_struct.
> 
> Signed-off-by: Dawei Li <dawei.li at shingroup.cn>
> ---
>  arch/arm64/kernel/process.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 7387b68c745b..4ae31b7af6c3 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -290,9 +290,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
>  		fpsimd_preserve_current_state();
>  	*dst = *src;
>  
> -	/* We rely on the above assignment to initialize dst's thread_flags: */
> -	BUILD_BUG_ON(!IS_ENABLED(CONFIG_THREAD_INFO_IN_TASK));
> -

Does the above cause any problem today, or is this patch just a cleanup?

For the benefit of other reviewers, the assertion and comment were added in
commit:

  4585fc59c0e8 ("arm64/sve: Fix wrong free for task->thread.sve_state")

... back in 2019, 3 years after commit:

  c02433dd6de3 ("arm64: split thread_info from task stack")

The comment and assertion were a safety-net for backports, since commit
4585fc59c0e8 was a fix which dependend upon the thread_info being contained
within task_struct, and couldn't be backported to kernels without
CONFIG_THREAD_INFO_IN_TASK.

I'm sure that we currently have plenty of other code with a similar (but
undocumented) dependency. Given we've unconditionally selected
CONFIG_THREAD_INFO_IN_TASK since v4.10, and the oldest longterm stable kernel
is v4.19 (with v4.14 having EOL'd last month), I think it makes sense to delete
the assertion and comment.

So FWIW:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.


From peter.griffin at linaro.org  Mon Feb  5 04:16:35 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 5 Feb 2024 12:16:35 +0000
Subject: [PATCH 1/4] dt-bindings: hwinfo: samsung,exynos-chipid: add
 gs101-chipid compatible
In-Reply-To: <20240201172224.574238-1-alexey.klimov@linaro.org>
References: <20240201172224.574238-1-alexey.klimov@linaro.org>
Message-ID: <CADrjBPpm1LrZNxd+uA_xrBp7_vojCnKKEeyQ5ambcBE=snPJOg@mail.gmail.com>

Hi Alexey,

On Thu, 1 Feb 2024 at 17:22, Alexey Klimov <alexey.klimov at linaro.org> wrote:
>
> Add "google,gs101-chipid" compatible string to binding document.
>
> Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
> ---

Thanks for your contribution.
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>






>  .../devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml        | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml
> index 780ccb5ee9b4..b1d933808b6c 100644
> --- a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml
> +++ b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml
> @@ -13,6 +13,7 @@ properties:
>    compatible:
>      oneOf:
>        - enum:
> +          - google,gs101-chipid
>            - samsung,exynos4210-chipid
>            - samsung,exynos850-chipid
>        - items:
> --
> 2.43.0
>


From james.clark at arm.com  Mon Feb  5 04:16:53 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 5 Feb 2024 12:16:53 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event
 state to hypervisor
In-Reply-To: <Zb1mCCi13AJ_YjFZ@linux.dev>
References: <20240104162714.1062610-1-james.clark@arm.com>
 <20240104162714.1062610-3-james.clark@arm.com> <Zb1mCCi13AJ_YjFZ@linux.dev>
Message-ID: <8a908ee8-620a-d9c2-734b-5a6402950072@arm.com>



On 02/02/2024 22:00, Oliver Upton wrote:
> On Thu, Jan 04, 2024 at 04:27:02PM +0000, James Clark wrote:
> 
> [...]
> 
>> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
>> index c50f8459e4fc..89147a9dc38c 100644
>> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
>> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
>> @@ -130,13 +130,18 @@ static void __hyp_vgic_restore_state(struct kvm_vcpu *vcpu)
>>  	}
>>  }
>>  
>> +static struct kvm_pmu_events *kvm_nvhe_get_pmu_events(struct kvm_vcpu *vcpu)
>> +{
>> +	return &kvm_host_global_state[vcpu->cpu].pmu_events;
>> +}
>> +
>>  /*
>>   * Disable host events, enable guest events
>>   */
>>  #ifdef CONFIG_HW_PERF_EVENTS
>>  static bool __pmu_switch_to_guest(struct kvm_vcpu *vcpu)
>>  {
>> -	struct kvm_pmu_events *pmu = &vcpu->arch.pmu.events;
>> +	struct kvm_pmu_events *pmu = kvm_nvhe_get_pmu_events(vcpu);
>>  
>>  	if (pmu->events_host)
>>  		write_sysreg(pmu->events_host, pmcntenclr_el0);
>> @@ -152,7 +157,7 @@ static bool __pmu_switch_to_guest(struct kvm_vcpu *vcpu)
>>   */
>>  static void __pmu_switch_to_host(struct kvm_vcpu *vcpu)
>>  {
>> -	struct kvm_pmu_events *pmu = &vcpu->arch.pmu.events;
>> +	struct kvm_pmu_events *pmu = kvm_nvhe_get_pmu_events(vcpu);
>>  
>>  	if (pmu->events_guest)
>>  		write_sysreg(pmu->events_guest, pmcntenclr_el0);
> 
> This now allows the host to program event counters for a protected
> guest. That _might_ be a useful feature behind some debug option, but is
> most definitely *not* something we want to do for pVMs generally.

Unless I'm missing something, using PMUs on protected guests was added
by 722625c6f4c5b ("KVM: arm64: Reenable pmu in Protected Mode"). This
change is just a refactor that will allow us to add the same behavior
for a similar feature (tracing) without adding yet another copy of some
state before the guest switch.

> 
> Do we even need to make this shared data work at all for pKVM? The rest
> of the shared data between pKVM and the kernel is system information,
> which (importantly) doesn't have any guest context in it.
> 

Probably not, Marc actually mentioned on one of the first versions of
that this could be hidden behind a debug flag. To be honest one of the
reasons I didn't do that was because I wasn't sure what the appropriate
debug setting was. NVHE_EL2_DEBUG didn't seem quite right. DEBUG_KERNEL
maybe? Or a new one?

And then I suppose I got distracted by trying to make it have feature
parity with PMUs and forgot about the debug only thing.


> I'm perfectly happy leaving these sorts of features broken for pKVM and
> using the 'normal' way of getting percpu data to the nVHE hypervisor
> otherwise.
> 

I can do that. But do I also disable PMU at the same time in a new
commit? Now that both PMU and tracing is working maybe it would be a
waste to throw that away and hiding it behind an option is better. Or I
can leave the PMU as it is and just keep tracing disabled in pKVM.

I don't mind either way, my main goal was to get exclude/include guest
tracing working for normal VMs. For pKVM I don't have a strong opinion.


From mihai.carabas at oracle.com  Mon Feb  5 04:28:13 2024
From: mihai.carabas at oracle.com (Mihai Carabas)
Date: Mon, 5 Feb 2024 14:28:13 +0200
Subject: [PATCH 7/7] cpuidle/poll_state: replace cpu_relax with
 smp_cond_load_relaxed
In-Reply-To: <20240129181547.GA12305@willie-the-truck>
References: <1700488898-12431-1-git-send-email-mihai.carabas@oracle.com>
 <1700488898-12431-8-git-send-email-mihai.carabas@oracle.com>
 <20231211114642.GB24899@willie-the-truck>
 <1b3650c5-822e-4789-81d2-0304573cabd9@oracle.com>
 <20240129181547.GA12305@willie-the-truck>
Message-ID: <1b25b492-b9e7-4411-90d1-463d44084043@oracle.com>

>>>> cpu_relax on ARM64 does a simple "yield". Thus we replace it with
>>>> smp_cond_load_relaxed which basically does a "wfe".
>>>>
>>>> Suggested-by: Peter Zijlstra <peterz at infradead.org>
>>>> Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
>>>> ---
>>>>    drivers/cpuidle/poll_state.c | 14 +++++++++-----
>>>>    1 file changed, 9 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c
>>>> index 9b6d90a72601..440cd713e39a 100644
>>>> --- a/drivers/cpuidle/poll_state.c
>>>> +++ b/drivers/cpuidle/poll_state.c
>>>> @@ -26,12 +26,16 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev,
>>>>    		limit = cpuidle_poll_time(drv, dev);
>>>> -		while (!need_resched()) {
>>>> -			cpu_relax();
>>>> -			if (loop_count++ < POLL_IDLE_RELAX_COUNT)
>>>> -				continue;
>>>> -
>>>> +		for (;;) {
>>>>    			loop_count = 0;
>>>> +
>>>> +			smp_cond_load_relaxed(&current_thread_info()->flags,
>>>> +					      (VAL & _TIF_NEED_RESCHED) ||
>>>> +					      (loop_count++ >= POLL_IDLE_RELAX_COUNT));
>>>> +
>>>> +			if (loop_count < POLL_IDLE_RELAX_COUNT)
>>>> +				break;
>>>> +
>>>>    			if (local_clock_noinstr() - time_start > limit) {
>>>>    				dev->poll_time_limit = true;
>>>>    				break;
>>> Doesn't this make ARCH_HAS_CPU_RELAX a complete misnomer?
>> This controls the build of poll_state.c and the generic definition of
>> smp_cond_load_relaxed (used by x86) is using cpu_relax(). Do you propose
>> other approach here?
> Give it a better name? Having ARCH_HAS_CPU_RELAX control a piece of code
> that doesn't use cpu_relax() doesn't make sense to me.

The generic code for smp_cond_load_relaxed is using cpu_relax and this 
one is used on x86 - so ARCH_HAS_CPU_RELAX is a prerequisite on x86 when 
using haltpoll. Only on ARM64 this is overwritten. Moreover 
ARCH_HAS_CPU_RELAX is controlling the function definition for 
cpuidle_poll_state_init (this is how it was originally designed).

Thanks,
Mihai


From krzysztof.kozlowski at linaro.org  Mon Feb  5 04:32:05 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 05 Feb 2024 13:32:05 +0100
Subject: [PATCH] arm: s3c64xx: make s3c64xx_subsys const
In-Reply-To: <20240204-bus_cleanup-arm-v1-1-41d651dd8411@marliere.net>
References: <20240204-bus_cleanup-arm-v1-1-41d651dd8411@marliere.net>
Message-ID: <170713632561.37217.11792751448407951770.b4-ty@linaro.org>


On Sun, 04 Feb 2024 11:46:21 -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the s3c64xx_subsys variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> 

Applied, thanks!

[1/1] arm: s3c64xx: make s3c64xx_subsys const
      https://git.kernel.org/krzk/linux/c/db085a6c66337799ad5983c5c6d4b1d8386f4256

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From broonie at kernel.org  Mon Feb  5 04:35:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 5 Feb 2024 12:35:53 +0000
Subject: [PATCH v8 13/38] KVM: arm64: Manage GCS registers for guests
In-Reply-To: <868r3z6y6v.wl-maz@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <20240203-arm64-gcs-v8-13-c9fec77673ef@kernel.org>
 <868r3z6y6v.wl-maz@kernel.org>
Message-ID: <825d2b35-fa10-43ad-b3b3-b29a77f3fed0@sirena.org.uk>

On Mon, Feb 05, 2024 at 09:46:16AM +0000, Marc Zyngier wrote:
> On Sat, 03 Feb 2024 12:25:39 +0000,
> Mark Brown <broonie at kernel.org> wrote:

> > +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> > @@ -25,6 +25,8 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt)
> >  {
> >  	ctxt_sys_reg(ctxt, TPIDR_EL0)	= read_sysreg(tpidr_el0);
> >  	ctxt_sys_reg(ctxt, TPIDRRO_EL0)	= read_sysreg(tpidrro_el0);
> > +	if (has_gcs())
> > +		ctxt_sys_reg(ctxt, GCSPR_EL0) = read_sysreg_s(SYS_GCSPR_EL0);

> We have had this discussion in the past. This must be based on the
> VM's configuration. Guarding the check with the host capability is a
> valuable optimisation, but that's nowhere near enough. See the series
> that I have posted on this very subject (you're on Cc), but you are
> welcome to invent your own mechanism in the meantime.

Right, which postdates the version you're replying to and isn't merged
yet - the current code was what you were asking for at the time.  I'm
expecting to update all these feature series to work with that once it
gets finalised and merged but it's not there yet, I do see I forgot to
put a note in v9 about that like I did for dpISA - sorry about that, I
was too focused on the clone3() rework when rebasing onto the new
kernel.

This particular series isn't going to get merged for a while yet anyway
due to the time it'll take for userspace testing, I'm expecting your
series to be in by the time it becomes an issue.

> > +	if (has_gcs()) {
> > +		write_sysreg_el1(ctxt_sys_reg(ctxt, GCSPR_EL1),	SYS_GCSPR);
> > +		write_sysreg_el1(ctxt_sys_reg(ctxt, GCSCR_EL1),	SYS_GCSCR);
> > +		write_sysreg_s(ctxt_sys_reg(ctxt, GCSCRE0_EL1),
> > +			       SYS_GCSCRE0_EL1);
> > +	}

> For the benefit of the unsuspecting reviewers, and in the absence of a
> public specification (which the XML drop isn't), it would be good to
> have the commit message explaining the rationale of what gets saved
> when.

What are you looking for in terms of rationale here?  The KVM house
style is often very reliant on reader context so it would be good to
know what considerations you'd like to see explicitly addressed.  These
registers shouldn't do anything when we aren't running the guest so
they're not terribly ordering sensitive, the EL2 ones will need a bit
more consideration in the face of nested virt.
-------------- 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/20240205/c62a8abd/attachment.sig>

From tudor.ambarus at linaro.org  Mon Feb  5 04:44:57 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:44:57 +0000
Subject: [PATCH v4 00/16] spi: s3c64xx: straightforward cleanup
Message-ID: <20240205124513.447875-1-tudor.ambarus@linaro.org>

Simple, straightforward patches that were compiled tested.

v4:
- drop "spi: s3c64xx: use bitfield access macros" patch as there was
  no agreement on how the reg fields should be handled.
- don't change the style in s3c64xx_spi_dt_match(), drop just the
  unneeded casts
- collect Sam's R-b  tags

v3:
- reworked the bitfied access macros patch so that the bit operations
  are the same as before the patch. Fix S3C64XX_SPI_PSR_MASK value,
  drop S3C64XX_SPI_CS_NSC_CNT_MASK.
- add a new patches to explicitly remove a duplicated definition and to
  drop a superfluous bitwise NOT operation.
- collect R-b tags

v2:
https://lore.kernel.org/linux-arm-kernel/36a664b1-666d-4fc4-90d9-35b42e56973d at linaro.org/

Tudor Ambarus (16):
  spi: s3c64xx: explicitly include <linux/io.h>
  spi: s3c64xx: explicitly include <linux/bits.h>
  spi: s3c64xx: avoid possible negative array index
  spi: s3c64xx: fix typo, s/configuartion/configuration
  spi: s3c64xx: sort headers alphabetically
  spi: s3c64xx: remove unneeded (void *) casts in of_match_table
  spi: s3c64xx: remove else after return
  spi: s3c64xx: move common code outside if else
  spi: s3c64xx: check return code of dmaengine_slave_config()
  spi: s3c64xx: propagate the dma_submit_error() error code
  spi: s3c64xx: rename prepare_dma() to s3c64xx_prepare_dma()
  spi: s3c64xx: return ETIMEDOUT for wait_for_completion_timeout()
  spi: s3c64xx: drop blank line between declarations
  spi: s3c64xx: downgrade dev_warn to dev_dbg for optional dt props
  spi: s3c64xx: remove duplicated definition
  spi: s3c64xx: drop a superfluous bitwise NOT operation

 drivers/spi/spi-s3c64xx.c | 80 +++++++++++++++++++--------------------
 1 file changed, 40 insertions(+), 40 deletions(-)

-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:44:58 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:44:58 +0000
Subject: [PATCH v4 01/16] spi: s3c64xx: explicitly include <linux/io.h>
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-2-tudor.ambarus@linaro.org>

The driver uses readl() but does not include <linux/io.h>.

It is good practice to directly include all headers used, it avoids
implicit dependencies and spurious breakage if someone rearranges
headers and causes the implicit include to vanish.

Include the missing header.

Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver")
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 7f7eb8f742e4..c1cbc4780a3b 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
+#include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/spi/spi.h>
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:44:59 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:44:59 +0000
Subject: [PATCH v4 02/16] spi: s3c64xx: explicitly include <linux/bits.h>
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-3-tudor.ambarus@linaro.org>

The driver uses GENMASK() but does not include <linux/bits.h>.

It is good practice to directly include all headers used, it avoids
implicit dependencies and spurious breakage if someone rearranges
headers and causes the implicit include to vanish.

Include the missing header.

Fixes: 1224e29572f6 ("spi: s3c64xx: Fix large transfers with DMA")
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index c1cbc4780a3b..2b5bb7604526 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -3,6 +3,7 @@
 // Copyright (c) 2009 Samsung Electronics Co., Ltd.
 //      Jaswinder Singh <jassi.brar at samsung.com>
 
+#include <linux/bits.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:00 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:00 +0000
Subject: [PATCH v4 03/16] spi: s3c64xx: avoid possible negative array index
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-4-tudor.ambarus@linaro.org>

The platform id is used as an index into the fifo_lvl_mask array.
Platforms can come with a negative device ID, PLATFORM_DEVID_NONE (-1),
thus we risked a negative array index. Catch such cases and fail to
probe.

Fixes: 2b90807549e5 ("spi: s3c64xx: add device tree support")
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 2b5bb7604526..c3176a510643 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1189,6 +1189,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 					     "Failed to get alias id\n");
 		sdd->port_id = ret;
 	} else {
+		if (pdev->id < 0)
+			return dev_err_probe(&pdev->dev, -EINVAL,
+					     "Negative platform ID is not allowed\n");
 		sdd->port_id = pdev->id;
 	}
 
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:01 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:01 +0000
Subject: [PATCH v4 04/16] spi: s3c64xx: fix typo, s/configuartion/configuration
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-5-tudor.ambarus@linaro.org>

Fix typo, s/configuartion/configuration.

Fixes: 6b8d1e4739f4 ("spi: spi-s3c64xx: Add missing entries for structs 's3c64xx_spi_dma_data' and 's3c64xx_spi_dma_data'")
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index c3176a510643..3df4906bba34 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -180,7 +180,7 @@ struct s3c64xx_spi_port_config {
  * @cur_speed: Current clock speed
  * @rx_dma: Local receive DMA data (e.g. chan and direction)
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
- * @port_conf: Local SPI port configuartion data
+ * @port_conf: Local SPI port configuration data
  * @port_id: Port identification number
  */
 struct s3c64xx_spi_driver_data {
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:02 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:02 +0000
Subject: [PATCH v4 05/16] spi: s3c64xx: sort headers alphabetically
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-6-tudor.ambarus@linaro.org>

Sorting headers alphabetically helps locating duplicates,
and makes it easier to figure out where to insert new headers.

Reviewed-by: Andi Shyti <andi.shyti at kernel.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 3df4906bba34..ccb700312d64 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -4,20 +4,19 @@
 //      Jaswinder Singh <jassi.brar at samsung.com>
 
 #include <linux/bits.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_data/spi-s3c64xx.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/spi/spi.h>
-#include <linux/of.h>
-
-#include <linux/platform_data/spi-s3c64xx.h>
 
 #define MAX_SPI_PORTS		12
 #define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1)
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:03 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:03 +0000
Subject: [PATCH v4 06/16] spi: s3c64xx: remove unneeded (void *) casts in of_match_table
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-7-tudor.ambarus@linaro.org>

of_device_id::data is an opaque pointer. No explicit cast is needed.
Remove unneeded (void *) casts in of_match_table.

Reviewed-by: Andi Shyti <andi.shyti at kernel.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index ccb700312d64..807270ec3c8a 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1512,31 +1512,31 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
 
 static const struct of_device_id s3c64xx_spi_dt_match[] = {
 	{ .compatible = "samsung,s3c2443-spi",
-			.data = (void *)&s3c2443_spi_port_config,
+			.data = &s3c2443_spi_port_config,
 	},
 	{ .compatible = "samsung,s3c6410-spi",
-			.data = (void *)&s3c6410_spi_port_config,
+			.data = &s3c6410_spi_port_config,
 	},
 	{ .compatible = "samsung,s5pv210-spi",
-			.data = (void *)&s5pv210_spi_port_config,
+			.data = &s5pv210_spi_port_config,
 	},
 	{ .compatible = "samsung,exynos4210-spi",
-			.data = (void *)&exynos4_spi_port_config,
+			.data = &exynos4_spi_port_config,
 	},
 	{ .compatible = "samsung,exynos7-spi",
-			.data = (void *)&exynos7_spi_port_config,
+			.data = &exynos7_spi_port_config,
 	},
 	{ .compatible = "samsung,exynos5433-spi",
-			.data = (void *)&exynos5433_spi_port_config,
+			.data = &exynos5433_spi_port_config,
 	},
 	{ .compatible = "samsung,exynos850-spi",
-			.data = (void *)&exynos850_spi_port_config,
+			.data = &exynos850_spi_port_config,
 	},
 	{ .compatible = "samsung,exynosautov9-spi",
-			.data = (void *)&exynosautov9_spi_port_config,
+			.data = &exynosautov9_spi_port_config,
 	},
 	{ .compatible = "tesla,fsd-spi",
-			.data = (void *)&fsd_spi_port_config,
+			.data = &fsd_spi_port_config,
 	},
 	{ },
 };
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:04 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:04 +0000
Subject: [PATCH v4 07/16] spi: s3c64xx: remove else after return
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-8-tudor.ambarus@linaro.org>

Else case is not needed after a return, remove it.

Reviewed-by: Andi Shyti <andi.shyti at kernel.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 807270ec3c8a..3139a703f942 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -407,12 +407,10 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
 {
 	struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
 
-	if (sdd->rx_dma.ch && sdd->tx_dma.ch) {
+	if (sdd->rx_dma.ch && sdd->tx_dma.ch)
 		return xfer->len > FIFO_DEPTH(sdd);
-	} else {
-		return false;
-	}
 
+	return false;
 }
 
 static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:05 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:05 +0000
Subject: [PATCH v4 08/16] spi: s3c64xx: move common code outside if else
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-9-tudor.ambarus@linaro.org>

Move common code outside if else to avoid code duplication.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 3139a703f942..fcc1f16d3ad1 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -291,20 +291,18 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
 	if (dma->direction == DMA_DEV_TO_MEM) {
 		sdd = container_of((void *)dma,
 			struct s3c64xx_spi_driver_data, rx_dma);
-		config.direction = dma->direction;
 		config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
 		config.src_addr_width = sdd->cur_bpw / 8;
 		config.src_maxburst = 1;
-		dmaengine_slave_config(dma->ch, &config);
 	} else {
 		sdd = container_of((void *)dma,
 			struct s3c64xx_spi_driver_data, tx_dma);
-		config.direction = dma->direction;
 		config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
 		config.dst_addr_width = sdd->cur_bpw / 8;
 		config.dst_maxburst = 1;
-		dmaengine_slave_config(dma->ch, &config);
 	}
+	config.direction = dma->direction;
+	dmaengine_slave_config(dma->ch, &config);
 
 	desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents,
 				       dma->direction, DMA_PREP_INTERRUPT);
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:08 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:08 +0000
Subject: [PATCH v4 11/16] spi: s3c64xx: rename prepare_dma() to s3c64xx_prepare_dma()
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-12-tudor.ambarus@linaro.org>

Don't monopolize the name. Prepend the driver prefix to the function
name.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 7a37f5d0abd9..a51b5ff27d5a 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -278,8 +278,8 @@ static void s3c64xx_spi_dmacb(void *data)
 	spin_unlock_irqrestore(&sdd->lock, flags);
 }
 
-static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
-			struct sg_table *sgt)
+static int s3c64xx_prepare_dma(struct s3c64xx_spi_dma_data *dma,
+			       struct sg_table *sgt)
 {
 	struct s3c64xx_spi_driver_data *sdd;
 	struct dma_slave_config config;
@@ -444,7 +444,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 		chcfg |= S3C64XX_SPI_CH_TXCH_ON;
 		if (dma_mode) {
 			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
-			ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
+			ret = s3c64xx_prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
 		} else {
 			switch (sdd->cur_bpw) {
 			case 32:
@@ -476,7 +476,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 			writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
 					| S3C64XX_SPI_PACKET_CNT_EN,
 					regs + S3C64XX_SPI_PACKET_CNT);
-			ret = prepare_dma(&sdd->rx_dma, &xfer->rx_sg);
+			ret = s3c64xx_prepare_dma(&sdd->rx_dma, &xfer->rx_sg);
 		}
 	}
 
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:06 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:06 +0000
Subject: [PATCH v4 09/16] spi: s3c64xx: check return code of dmaengine_slave_config()
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-10-tudor.ambarus@linaro.org>

Check the return code of dmaengine_slave_config().

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index fcc1f16d3ad1..43b9792988b6 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -302,7 +302,9 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
 		config.dst_maxburst = 1;
 	}
 	config.direction = dma->direction;
-	dmaengine_slave_config(dma->ch, &config);
+	ret = dmaengine_slave_config(dma->ch, &config);
+	if (ret)
+		return ret;
 
 	desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents,
 				       dma->direction, DMA_PREP_INTERRUPT);
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:10 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:10 +0000
Subject: [PATCH v4 13/16] spi: s3c64xx: drop blank line between declarations
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-14-tudor.ambarus@linaro.org>

Drop the blank line and move the logical operation in the body of the
function rather than in initialization list.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index fff430b9e849..1b84f5fdebce 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1320,8 +1320,9 @@ static int s3c64xx_spi_suspend(struct device *dev)
 {
 	struct spi_controller *host = dev_get_drvdata(dev);
 	struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
+	int ret;
 
-	int ret = spi_controller_suspend(host);
+	ret = spi_controller_suspend(host);
 	if (ret)
 		return ret;
 
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:07 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:07 +0000
Subject: [PATCH v4 10/16] spi: s3c64xx: propagate the dma_submit_error() error code
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-11-tudor.ambarus@linaro.org>

DMA submit should just add the dma descriptor to a queue, without firing
it. EIO is misleading and hides what happens in DMA. Propagate the
dma_submit_error() error code, don't overwrite it.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 43b9792988b6..7a37f5d0abd9 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -321,7 +321,7 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
 	ret = dma_submit_error(dma->cookie);
 	if (ret) {
 		dev_err(&sdd->pdev->dev, "DMA submission failed");
-		return -EIO;
+		return ret;
 	}
 
 	dma_async_issue_pending(dma->ch);
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:09 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:09 +0000
Subject: [PATCH v4 12/16] spi: s3c64xx: return ETIMEDOUT for wait_for_completion_timeout()
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-13-tudor.ambarus@linaro.org>

ETIMEDOUT is more specific than EIO, use it for
wait_for_completion_timeout().

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index a51b5ff27d5a..fff430b9e849 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -526,7 +526,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
 
 	/*
 	 * If the previous xfer was completed within timeout, then
-	 * proceed further else return -EIO.
+	 * proceed further else return -ETIMEDOUT.
 	 * DmaTx returns after simply writing data in the FIFO,
 	 * w/o waiting for real transmission on the bus to finish.
 	 * DmaRx returns only after Dma read data from FIFO which
@@ -547,7 +547,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
 
 	/* If timed out while checking rx/tx status return error */
 	if (!val)
-		return -EIO;
+		return -ETIMEDOUT;
 
 	return 0;
 }
@@ -577,7 +577,7 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
 	if (use_irq) {
 		val = msecs_to_jiffies(ms);
 		if (!wait_for_completion_timeout(&sdd->xfer_completion, val))
-			return -EIO;
+			return -ETIMEDOUT;
 	}
 
 	val = msecs_to_loops(ms);
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:12 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:12 +0000
Subject: [PATCH v4 15/16] spi: s3c64xx: remove duplicated definition
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-16-tudor.ambarus@linaro.org>

S3C64XX_SPI_TRAILCNT brings no benefit in terms of name over
S3C64XX_SPI_MAX_TRAILCNT. Remove the duplicated definition.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index a103d9e125b1..ed0b5cf8fb4d 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -115,8 +115,6 @@
 #define S3C64XX_SPI_MAX_TRAILCNT	0x3ff
 #define S3C64XX_SPI_TRAILCNT_OFF	19
 
-#define S3C64XX_SPI_TRAILCNT		S3C64XX_SPI_MAX_TRAILCNT
-
 #define S3C64XX_SPI_POLLING_SIZE	32
 
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
@@ -1092,7 +1090,7 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd)
 	val = readl(regs + S3C64XX_SPI_MODE_CFG);
 	val &= ~S3C64XX_SPI_MODE_4BURST;
 	val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
-	val |= (S3C64XX_SPI_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
+	val |= (S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
 	writel(val, regs + S3C64XX_SPI_MODE_CFG);
 
 	s3c64xx_flush_fifo(sdd);
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:11 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:11 +0000
Subject: [PATCH v4 14/16] spi: s3c64xx: downgrade dev_warn to dev_dbg for optional dt props
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-15-tudor.ambarus@linaro.org>

"samsung,spi-src-clk" and "num-cs" are optional dt properties. Downgrade
the message from warning to debug message.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 1b84f5fdebce..a103d9e125b1 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1109,14 +1109,14 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
 		return ERR_PTR(-ENOMEM);
 
 	if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) {
-		dev_warn(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n");
+		dev_dbg(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n");
 		sci->src_clk_nr = 0;
 	} else {
 		sci->src_clk_nr = temp;
 	}
 
 	if (of_property_read_u32(dev->of_node, "num-cs", &temp)) {
-		dev_warn(dev, "number of chip select lines not specified, assuming 1 chip select line\n");
+		dev_dbg(dev, "number of chip select lines not specified, assuming 1 chip select line\n");
 		sci->num_cs = 1;
 	} else {
 		sci->num_cs = temp;
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Mon Feb  5 04:45:13 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon,  5 Feb 2024 12:45:13 +0000
Subject: [PATCH v4 16/16] spi: s3c64xx: drop a superfluous bitwise NOT operation
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <20240205124513.447875-17-tudor.ambarus@linaro.org>

val &= ~mask;
val |= mask;

is equivalent to:
val |= mask;

Drop the superfluous bitwise NOT operation.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index ed0b5cf8fb4d..72c35dbe53b2 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1089,7 +1089,6 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd)
 
 	val = readl(regs + S3C64XX_SPI_MODE_CFG);
 	val &= ~S3C64XX_SPI_MODE_4BURST;
-	val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
 	val |= (S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
 	writel(val, regs + S3C64XX_SPI_MODE_CFG);
 
-- 
2.43.0.594.gd9cf4e227d-goog



From linyunsheng at huawei.com  Mon Feb  5 04:45:00 2024
From: linyunsheng at huawei.com (Yunsheng Lin)
Date: Mon, 5 Feb 2024 20:45:00 +0800
Subject: [PATCH net-next v5 0/5] remove page frag implementation in vhost_net
Message-ID: <20240205124506.57670-1-linyunsheng@huawei.com>

Currently there are three implementations for page frag:

1. mm/page_alloc.c: net stack seems to be using it in the
   rx part with 'struct page_frag_cache' and the main API
   being page_frag_alloc_align().
2. net/core/sock.c: net stack seems to be using it in the
   tx part with 'struct page_frag' and the main API being
   skb_page_frag_refill().
3. drivers/vhost/net.c: vhost seems to be using it to build
   xdp frame, and it's implementation seems to be a mix of
   the above two.

This patchset tries to unfiy the page frag implementation a
little bit by unifying gfp bit for order 3 page allocation
and replacing page frag implementation in vhost.c with the
one in page_alloc.c.

After this patchset, we are not only able to unify the page
frag implementation a little, but also able to have about
0.5% performance boost testing by using the vhost_net_test
introduced in the last patch.

Before this patchset:
Performance counter stats for './vhost_net_test' (10 runs):

     305325.78 msec task-clock                       #    1.738 CPUs utilized               ( +-  0.12% )
       1048668      context-switches                 #    3.435 K/sec                       ( +-  0.00% )
            11      cpu-migrations                   #    0.036 /sec                        ( +- 17.64% )
            33      page-faults                      #    0.108 /sec                        ( +-  0.49% )
  244651819491      cycles                           #    0.801 GHz                         ( +-  0.43% )  (64)
   64714638024      stalled-cycles-frontend          #   26.45% frontend cycles idle        ( +-  2.19% )  (67)
   30774313491      stalled-cycles-backend           #   12.58% backend cycles idle         ( +-  7.68% )  (70)
  201749748680      instructions                     #    0.82  insn per cycle
                                              #    0.32  stalled cycles per insn     ( +-  0.41% )  (66.76%)
   65494787909      branches                         #  214.508 M/sec                       ( +-  0.35% )  (64)
    4284111313      branch-misses                    #    6.54% of all branches             ( +-  0.45% )  (66)

       175.699 +- 0.189 seconds time elapsed  ( +-  0.11% )


After this patchset:
Performance counter stats for './vhost_net_test' (10 runs):

     303974.38 msec task-clock                       #    1.739 CPUs utilized               ( +-  0.14% )
       1048807      context-switches                 #    3.450 K/sec                       ( +-  0.00% )
            14      cpu-migrations                   #    0.046 /sec                        ( +- 12.86% )
            33      page-faults                      #    0.109 /sec                        ( +-  0.46% )
  251289376347      cycles                           #    0.827 GHz                         ( +-  0.32% )  (60)
   67885175415      stalled-cycles-frontend          #   27.01% frontend cycles idle        ( +-  0.48% )  (63)
   27809282600      stalled-cycles-backend           #   11.07% backend cycles idle         ( +-  0.36% )  (71)
  195543234672      instructions                     #    0.78  insn per cycle
                                              #    0.35  stalled cycles per insn     ( +-  0.29% )  (69.04%)
   62423183552      branches                         #  205.357 M/sec                       ( +-  0.48% )  (67)
    4135666632      branch-misses                    #    6.63% of all branches             ( +-  0.63% )  (67)

       174.764 +- 0.214 seconds time elapsed  ( +-  0.12% )

Changelog:
V5: Address the comment from jason in vhost_net_test.c and the
    comment about leaving out the gfp change for page frag in
    sock.c as suggested by Paolo.

V4: Resend based on latest net-next branch.

V3:
1. Add __page_frag_alloc_align() which is passed with the align mask
   the original function expected as suggested by Alexander.
2. Drop patch 3 in v2 suggested by Alexander.
3. Reorder patch 4 & 5 in v2 suggested by Alexander.

Note that placing this gfp flags handing for order 3 page in an inline
function is not considered, as we may be able to unify the page_frag
and page_frag_cache handling.

V2: Change 'xor'd' to 'masked off', add vhost tx testing for
    vhost_net_test.

V1: Fix some typo, drop RFC tag and rebase on latest net-next.


Yunsheng Lin (5):
  mm/page_alloc: modify page_frag_alloc_align() to accept align as an
    argument
  page_frag: unify gfp bits for order 3 page allocation
  net: introduce page_frag_cache_drain()
  vhost/net: remove vhost_net_page_frag_refill()
  tools: virtio: introduce vhost_net_test

 drivers/net/ethernet/google/gve/gve_main.c |  11 +-
 drivers/net/ethernet/mediatek/mtk_wed_wo.c |  17 +-
 drivers/nvme/host/tcp.c                    |   7 +-
 drivers/nvme/target/tcp.c                  |   4 +-
 drivers/vhost/net.c                        |  91 ++--
 include/linux/gfp.h                        |  16 +-
 mm/page_alloc.c                            |  22 +-
 net/core/skbuff.c                          |   9 +-
 tools/virtio/.gitignore                    |   1 +
 tools/virtio/Makefile                      |   8 +-
 tools/virtio/linux/virtio_config.h         |   4 +
 tools/virtio/vhost_net_test.c              | 536 +++++++++++++++++++++
 12 files changed, 613 insertions(+), 113 deletions(-)
 create mode 100644 tools/virtio/vhost_net_test.c

-- 
2.33.0



From linyunsheng at huawei.com  Mon Feb  5 04:45:03 2024
From: linyunsheng at huawei.com (Yunsheng Lin)
Date: Mon, 5 Feb 2024 20:45:03 +0800
Subject: [PATCH net-next v5 3/5] net: introduce page_frag_cache_drain()
In-Reply-To: <20240205124506.57670-1-linyunsheng@huawei.com>
References: <20240205124506.57670-1-linyunsheng@huawei.com>
Message-ID: <20240205124506.57670-4-linyunsheng@huawei.com>

When draining a page_frag_cache, most user are doing
the similar steps, so introduce an API to avoid code
duplication.

Signed-off-by: Yunsheng Lin <linyunsheng at huawei.com>
Acked-by: Jason Wang <jasowang at redhat.com>
Reviewed-by: Alexander Duyck <alexanderduyck at fb.com>
---
 drivers/net/ethernet/google/gve/gve_main.c | 11 ++---------
 drivers/net/ethernet/mediatek/mtk_wed_wo.c | 17 ++---------------
 drivers/nvme/host/tcp.c                    |  7 +------
 drivers/nvme/target/tcp.c                  |  4 +---
 include/linux/gfp.h                        |  1 +
 mm/page_alloc.c                            | 10 ++++++++++
 6 files changed, 17 insertions(+), 33 deletions(-)

diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index db6d9ae7cd78..dec6458bb8d7 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -1276,17 +1276,10 @@ static void gve_unreg_xdp_info(struct gve_priv *priv)
 
 static void gve_drain_page_cache(struct gve_priv *priv)
 {
-	struct page_frag_cache *nc;
 	int i;
 
-	for (i = 0; i < priv->rx_cfg.num_queues; i++) {
-		nc = &priv->rx[i].page_cache;
-		if (nc->va) {
-			__page_frag_cache_drain(virt_to_page(nc->va),
-						nc->pagecnt_bias);
-			nc->va = NULL;
-		}
-	}
+	for (i = 0; i < priv->rx_cfg.num_queues; i++)
+		page_frag_cache_drain(&priv->rx[i].page_cache);
 }
 
 static void gve_qpls_get_curr_alloc_cfg(struct gve_priv *priv,
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.c b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
index d58b07e7e123..7063c78bd35f 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
@@ -286,7 +286,6 @@ mtk_wed_wo_queue_free(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
 static void
 mtk_wed_wo_queue_tx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
 {
-	struct page *page;
 	int i;
 
 	for (i = 0; i < q->n_desc; i++) {
@@ -301,19 +300,12 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
 		entry->buf = NULL;
 	}
 
-	if (!q->cache.va)
-		return;
-
-	page = virt_to_page(q->cache.va);
-	__page_frag_cache_drain(page, q->cache.pagecnt_bias);
-	memset(&q->cache, 0, sizeof(q->cache));
+	page_frag_cache_drain(&q->cache);
 }
 
 static void
 mtk_wed_wo_queue_rx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
 {
-	struct page *page;
-
 	for (;;) {
 		void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true);
 
@@ -323,12 +315,7 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q)
 		skb_free_frag(buf);
 	}
 
-	if (!q->cache.va)
-		return;
-
-	page = virt_to_page(q->cache.va);
-	__page_frag_cache_drain(page, q->cache.pagecnt_bias);
-	memset(&q->cache, 0, sizeof(q->cache));
+	page_frag_cache_drain(&q->cache);
 }
 
 static void
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index d058d990532b..22e1fb9c9c0f 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -1344,7 +1344,6 @@ static int nvme_tcp_alloc_async_req(struct nvme_tcp_ctrl *ctrl)
 
 static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid)
 {
-	struct page *page;
 	struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
 	struct nvme_tcp_queue *queue = &ctrl->queues[qid];
 	unsigned int noreclaim_flag;
@@ -1355,11 +1354,7 @@ static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid)
 	if (queue->hdr_digest || queue->data_digest)
 		nvme_tcp_free_crypto(queue);
 
-	if (queue->pf_cache.va) {
-		page = virt_to_head_page(queue->pf_cache.va);
-		__page_frag_cache_drain(page, queue->pf_cache.pagecnt_bias);
-		queue->pf_cache.va = NULL;
-	}
+	page_frag_cache_drain(&queue->pf_cache);
 
 	noreclaim_flag = memalloc_noreclaim_save();
 	/* ->sock will be released by fput() */
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 6a1e6bb80062..56224dc59f17 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -1591,7 +1591,6 @@ static void nvmet_tcp_free_cmd_data_in_buffers(struct nvmet_tcp_queue *queue)
 
 static void nvmet_tcp_release_queue_work(struct work_struct *w)
 {
-	struct page *page;
 	struct nvmet_tcp_queue *queue =
 		container_of(w, struct nvmet_tcp_queue, release_work);
 
@@ -1615,8 +1614,7 @@ static void nvmet_tcp_release_queue_work(struct work_struct *w)
 	if (queue->hdr_digest || queue->data_digest)
 		nvmet_tcp_free_crypto(queue);
 	ida_free(&nvmet_tcp_queue_ida, queue->idx);
-	page = virt_to_head_page(queue->pf_cache.va);
-	__page_frag_cache_drain(page, queue->pf_cache.pagecnt_bias);
+	page_frag_cache_drain(&queue->pf_cache);
 	kfree(queue);
 }
 
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 28aea17fa59b..6cef1c241180 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -311,6 +311,7 @@ extern void __free_pages(struct page *page, unsigned int order);
 extern void free_pages(unsigned long addr, unsigned int order);
 
 struct page_frag_cache;
+void page_frag_cache_drain(struct page_frag_cache *nc);
 extern void __page_frag_cache_drain(struct page *page, unsigned int count);
 void *__page_frag_alloc_align(struct page_frag_cache *nc, unsigned int fragsz,
 			      gfp_t gfp_mask, unsigned int align_mask);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 636145c29f70..06aa1ebbd21c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4699,6 +4699,16 @@ static struct page *__page_frag_cache_refill(struct page_frag_cache *nc,
 	return page;
 }
 
+void page_frag_cache_drain(struct page_frag_cache *nc)
+{
+	if (!nc->va)
+		return;
+
+	__page_frag_cache_drain(virt_to_head_page(nc->va), nc->pagecnt_bias);
+	nc->va = NULL;
+}
+EXPORT_SYMBOL(page_frag_cache_drain);
+
 void __page_frag_cache_drain(struct page *page, unsigned int count)
 {
 	VM_BUG_ON_PAGE(page_ref_count(page) == 0, page);
-- 
2.33.0



From nicolas.ferre at microchip.com  Mon Feb  5 04:50:01 2024
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Mon, 5 Feb 2024 13:50:01 +0100
Subject: [PATCH] dt-bindings: ata: atmel: remove at91 compact flash
 documentation
In-Reply-To: <20240205105201.81060-1-Hari.PrasathGE@microchip.com>
References: <20240205105201.81060-1-Hari.PrasathGE@microchip.com>
Message-ID: <399c1ecd-c4fb-481f-b95a-afd71fb2d4fa@microchip.com>

On 05/02/2024 at 11:52, Hari Prasath G E - I63539 wrote:
> The compatible "at91rm9200-cf" is not used by any driver,hence remove the
> corresponding documentation.
> 
> Signed-off-by: Hari Prasath Gujulan Elango <Hari.PrasathGE at microchip.com>

Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>

> ---
>   .../devicetree/bindings/ata/atmel-at91_cf.txt | 19 -------------------
>   1 file changed, 19 deletions(-)
>   delete mode 100644 Documentation/devicetree/bindings/ata/atmel-at91_cf.txt
> 
> diff --git a/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt b/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt
> deleted file mode 100644
> index c1d22b3ae134..000000000000
> --- a/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -Atmel AT91RM9200 CompactFlash
> -
> -Required properties:
> -- compatible : "atmel,at91rm9200-cf".
> -- reg : should specify localbus address and size used.
> -- gpios : specifies the gpio pins to control the CF device. Detect
> -  and reset gpio's are mandatory while irq and vcc gpio's are
> -  optional and may be set to 0 if not present.
> -
> -Example:
> -compact-flash at 50000000 {
> -	compatible = "atmel,at91rm9200-cf";
> -	reg = <0x50000000 0x30000000>;
> -	gpios = <&pioC 13 0	/* irq */
> -		 &pioC 15 0 	/* detect */
> -		 0		/* vcc */
> -		 &pioC  5 0	/* reset */
> -		>;
> -};



From mark.rutland at arm.com  Mon Feb  5 04:55:53 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 5 Feb 2024 12:55:53 +0000
Subject: [PATCH] arm64: Print provenance information for addresses in
 registers
In-Reply-To: <20240201153811.1793120-1-stefan.wiehler@nokia.com>
References: <20240201153811.1793120-1-stefan.wiehler@nokia.com>
Message-ID: <ZcDa2RXC6z7XuwAD@FVFF77S0Q05N>

On Thu, Feb 01, 2024 at 04:38:11PM +0100, Stefan Wiehler wrote:
> Like commit 5aa6b70ed182 ("arm: print alloc free paths for address in
> registers") already does for 32-bit ARM, print available provenance information
> for addresses in registers in case of internal error as a debugging aid:
> 
>   Unable to handle kernel write to read-only memory at virtual address ffffffc00117cd5c
>   ...
>   x2 : 0000000000001b98 x1 : 0000000000000000 x0 : ffffffc00117cd5c
>   ...
>   Register x0 information: 14-page vmalloc region starting at 0xffffffc00117a000 allocated at load_module+0x15c4/0x2bc0
>   Register x1 information: NULL pointer
>   Register x2 information: non-paged memory
>   ...

Regardless of what 32-bit ARM does, I don't think it makes sense to dump this
for all the GPRs. It's incredibly verbose and not all that helpful, e.g.
testing with the LKDTM WRITE_RO test I get:

| # echo WRITE_RO > /sys/kernel/debug/provoke-crash/DIRECT
| lkdtm: Performing direct entry WRITE_RO
| lkdtm: attempting bad rodata write at ffffadee958c1bf0
| Unable to handle kernel write to read-only memory at virtual address ffffadee958c1bf0
| Mem abort info:
|   ESR = 0x000000009600004e
|   EC = 0x25: DABT (current EL), IL = 32 bits
|   SET = 0, FnV = 0
|   EA = 0, S1PTW = 0
|   FSC = 0x0e: level 2 permission fault
| Data abort info:
|   ISV = 0, ISS = 0x0000004e, ISS2 = 0x00000000
|   CM = 0, WnR = 1, TnD = 0, TagAccess = 0
|   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
| swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000041d6d000
| [ffffadee958c1bf0] pgd=100000043ffff803, p4d=100000043ffff803, pud=100000043fffe803, pmd=0060000041600f81
| Internal error: Oops: 000000009600004e [#1] PREEMPT SMP
| Modules linked in:
| CPU: 4 PID: 147 Comm: sh Not tainted 6.8.0-rc3-00001-gc66454d88811 #1
| Hardware name: linux,dummy-virt (DT)
| pstate: 61400009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
| pc : lkdtm_WRITE_RO+0x3c/0x54
| lr : lkdtm_WRITE_RO+0x24/0x54
| sp : ffff800080913c80
| x29: ffff800080913c80 x28: ffff0000c09ca200 x27: 0000000000000000
| x26: 0000000000000000 x25: 0000000000000000 x24: 0000aaaaee418930
| x23: ffff0000c0645780 x22: ffff800080913df0 x21: ffffadee96c957a0
| x20: 0000000000000009 x19: ffffadee958c1000 x18: 0000000000000006
| x17: 0000000000000000 x16: 0000000000000000 x15: ffff800080913720
| x14: 0000000000000000 x13: ffffadee969310b0 x12: 0000000000000432
| x11: 0000000000000166 x10: ffffadee969890b0 x9 : ffffadee969310b0
| x8 : 00000000ffffefff x7 : ffffadee969890b0 x6 : 80000000fffff000
| x5 : ffff0003fdfb5cc8 x4 : 0000000000000000 x3 : 0000000000000000
| x2 : 00000000abcd1234 x1 : 000000000198b861 x0 : ffffadee95e334a0
| Call trace:
|  lkdtm_WRITE_RO+0x3c/0x54
|  lkdtm_do_action+0x1c/0x30
|  direct_entry+0xbc/0x144
|  full_proxy_write+0x60/0xb4
|  vfs_write+0xd0/0x35c
|  ksys_write+0x70/0x104
|  __arm64_sys_write+0x1c/0x28
|  invoke_syscall+0x48/0x110
|  el0_svc_common.constprop.0+0x40/0xe0
|  do_el0_svc+0x1c/0x28
|  el0_svc+0x34/0xb4
|  el0t_64_sync_handler+0x120/0x12c
|  el0t_64_sync+0x190/0x194
| Register x0 information: 0-page vmalloc region starting at 0xffffadee95470000 allocated at paging_init+0x148/0x6f4
| Register x1 information: non-paged memory
| Register x2 information: non-paged memory
| Register x3 information: NULL pointer
| Register x4 information: NULL pointer
| Register x5 information: non-slab/vmalloc memory
| Register x6 information: non-paged memory
| Register x7 information: 0-page vmalloc region starting at 0xffffadee96910000 allocated at paging_init+0x1d8/0x6f4
| Register x8 information: non-paged memory
| Register x9 information: 0-page vmalloc region starting at 0xffffadee96910000 allocated at paging_init+0x1d8/0x6f4
| Register x10 information: 0-page vmalloc region starting at 0xffffadee96910000 allocated at paging_init+0x1d8/0x6f4
| Register x11 information: non-paged memory
| Register x12 information: non-paged memory
| Register x13 information: 0-page vmalloc region starting at 0xffffadee96910000 allocated at paging_init+0x1d8/0x6f4
| Register x14 information: NULL pointer
| Register x15 information: 4-page vmalloc region starting at 0xffff800080910000 allocated at kernel_clone+0x64/0x360
| Register x16 information: NULL pointer
| Register x17 information: NULL pointer
| Register x18 information: non-paged memory
| Register x19 information: 0-page vmalloc region starting at 0xffffadee95470000 allocated at paging_init+0x148/0x6f4
| Register x20 information: non-paged memory
| Register x21 information: 0-page vmalloc region starting at 0xffffadee96910000 allocated at paging_init+0x1d8/0x6f4
| Register x22 information: 4-page vmalloc region starting at 0xffff800080910000 allocated at kernel_clone+0x64/0x360
| Register x23 information: slab dentry start ffff0000c0645780 pointer offset 0 size 192
| Register x24 information: non-paged memory
| Register x25 information: NULL pointer
| Register x26 information: NULL pointer
| Register x27 information: NULL pointer
| Register x28 information: slab task_struct start ffff0000c09ca200 pointer offset 0 size 4352
| Register x29 information: 4-page vmalloc region starting at 0xffff800080910000 allocated at kernel_clone+0x64/0x360
| Code: f2b579a2 900089c0 ca020021 91128000 (f905fa61)
| ---[ end trace 0000000000000000 ]---

Looking at the dump, the vast majority of those "Register X?? information:"
lines are irrelevant, and it's difficult to see the wood for the trees.

Why do we need this for (almost) all registers, rather than just the faulting
address?

In die_kernel_fault() we already print some information regarding the psecific
faulting address:

| static void die_kernel_fault(const char *msg, unsigned long addr,
|                              unsigned long esr, struct pt_regs *regs)
| {
|         bust_spinlocks(1);
| 
|         pr_alert("Unable to handle kernel %s at virtual address %016lx\n", msg,
|                  addr);
| 
|         kasan_non_canonical_hook(addr);
| 
|         mem_abort_decode(esr);
| 
|         show_pte(addr);
|         die("Oops", regs, esr);
|         bust_spinlocks(0);
|         make_task_dead(SIGKILL);
| }

... and IMO it'd make more sense to call mem_dump_obj() there, e.g.

| static void die_kernel_fault(const char *msg, unsigned long addr,
|                              unsigned long esr, struct pt_regs *regs)
| {
|         bust_spinlocks(1);
| 
|         pr_alert("Unable to handle kernel %s at virtual address %016lx\n", msg,
|                  addr);
| 
|         pr_alert("Fauling address:");
|         mem_dump_obj((void *)addr);
|         kasan_non_canonical_hook(addr);
| 
|         mem_abort_decode(esr);
| 
|         show_pte(addr);
|         die("Oops", regs, esr);
|         bust_spinlocks(0);
|         make_task_dead(SIGKILL);
| }

... which produces significantly more legible output, e.g.

| # echo WRITE_RO > /sys/kernel/debug/provoke-crash/DIRECT 
| lkdtm: Performing direct entry WRITE_RO
| lkdtm: attempting bad rodata write at ffffa66f5e2c1bf0
| Unable to handle kernel write to read-only memory at virtual address ffffa66f5e2c1bf0
| Fauling address: 0-page vmalloc region starting at 0xffffa66f5de70000 allocated at paging_init+0x148/0x6f4
| Mem abort info:
|   ESR = 0x000000009600004e
|   EC = 0x25: DABT (current EL), IL = 32 bits
|   SET = 0, FnV = 0
|   EA = 0, S1PTW = 0
|   FSC = 0x0e: level 2 permission fault
| Data abort info:
|   ISV = 0, ISS = 0x0000004e, ISS2 = 0x00000000
|   CM = 0, WnR = 1, TnD = 0, TagAccess = 0
|   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
| swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000041d6d000
| [ffffa66f5e2c1bf0] pgd=100000043ffff803, p4d=100000043ffff803, pud=100000043fffe803, pmd=0060000041600f81
| Internal error: Oops: 000000009600004e [#1] PREEMPT SMP
| Modules linked in:
| CPU: 3 PID: 148 Comm: sh Not tainted 6.8.0-rc3-00002-gf95e3bd06270-dirty #2
| Hardware name: linux,dummy-virt (DT)
| pstate: 61400009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
| pc : lkdtm_WRITE_RO+0x3c/0x54
| lr : lkdtm_WRITE_RO+0x24/0x54
| sp : ffff80008098bc80
| x29: ffff80008098bc80 x28: ffff0000c144a200 x27: 0000000000000000
| x26: 0000000000000000 x25: 0000000000000000 x24: 0000aaab235e21d0
| x23: ffff0000c06459c0 x22: ffff80008098bdf0 x21: ffffa66f5f6957a0
| x20: 0000000000000009 x19: ffffa66f5e2c1000 x18: 0000000000000006
| x17: 0000000000000000 x16: 0000000000000000 x15: ffff80008098b720
| x14: 0000000000000000 x13: ffffa66f5f3310b0 x12: 0000000000000432
| x11: 0000000000000166 x10: ffffa66f5f3890b0 x9 : ffffa66f5f3310b0
| x8 : 00000000ffffefff x7 : ffffa66f5f3890b0 x6 : 80000000fffff000
| x5 : ffff0003fdf9fcc8 x4 : 0000000000000000 x3 : 0000000000000000
| x2 : 00000000abcd1234 x1 : 000000000198b861 x0 : ffffa66f5e8334b0
| Call trace:
|  lkdtm_WRITE_RO+0x3c/0x54
|  lkdtm_do_action+0x1c/0x30
|  direct_entry+0xbc/0x144
|  full_proxy_write+0x60/0xb4
|  vfs_write+0xd0/0x35c
|  ksys_write+0x70/0x104
|  __arm64_sys_write+0x1c/0x28
|  invoke_syscall+0x48/0x110
|  el0_svc_common.constprop.0+0x40/0xe0
|  do_el0_svc+0x1c/0x28
|  el0_svc+0x34/0xb4
|  el0t_64_sync_handler+0x120/0x12c
|  el0t_64_sync+0x190/0x194
| Code: f2b579a2 900089c0 ca020021 9112c000 (f905fa61) 
| ---[ end trace 0000000000000000 ]---

... and likewise even when we hit addresses without KASAN shadow:

| # echo ACCESS_NULL > /sys/kernel/debug/provoke-crash/DIRECT 
| lkdtm: Performing direct entry ACCESS_NULL
| lkdtm: attempting bad read at 0000000000000000
| Unable to handle kernel paging request at virtual address dfff800000000000
| Fauling address: non-paged memory
| KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
| Mem abort info:
|   ESR = 0x0000000096000005
|   EC = 0x25: DABT (current EL), IL = 32 bits
|   SET = 0, FnV = 0
|   EA = 0, S1PTW = 0
|   FSC = 0x05: level 1 translation fault
| Data abort info:
|   ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
|   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
|   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
| [dfff800000000000] address between user and kernel address ranges
| Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
| Modules linked in:
| CPU: 2 PID: 149 Comm: sh Not tainted 6.8.0-rc3-00002-gf95e3bd06270-dirty #3
| Hardware name: linux,dummy-virt (DT)
| pstate: 61400009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
| pc : lkdtm_ACCESS_NULL+0x2c/0xa4
| lr : lkdtm_ACCESS_NULL+0x24/0xa4
| sp : ffff800080d87ab0
| x29: ffff800080d87ab0 x28: ffff0000c5296f14 x27: 1fffe00018a52df5
| x26: ffff0000c5296fa0 x25: 1fffe00018a52df4 x24: ffff0000c8fcda00
| x23: 0000aaaadb0a7040 x22: ffff800080d87d70 x21: ffffcb98b050dae0
| x20: 000000000000000c x19: ffffcb98acd53f40 x18: ffff0003fdff56c0
| x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
| x14: 0000000000000000 x13: 3030303030303030 x12: ffff7000101b0ee1
| x11: 1ffff000101b0ee0 x10: ffff7000101b0ee0 x9 : dfff800000000000
| x8 : 00008fffefe4f120 x7 : ffff800080d87707 x6 : 0000000000000001
| x5 : ffff800080d87700 x4 : 1fffe000191f9b41 x3 : 0000000000000000
| x2 : 0000000000000000 x1 : ffff0000c8fcda00 x0 : dfff800000000000
| Call trace:
|  lkdtm_ACCESS_NULL+0x2c/0xa4
|  lkdtm_do_action+0x3c/0x68
|  direct_entry+0x130/0x228
|  full_proxy_write+0xd4/0x140
|  vfs_write+0x1e4/0x8ec
|  ksys_write+0xf4/0x1e0
|  __arm64_sys_write+0x6c/0x9c
|  invoke_syscall+0x6c/0x254
|  el0_svc_common.constprop.0+0xac/0x230
|  do_el0_svc+0x40/0x58
|  el0_svc+0x38/0x70
|  el0t_64_sync_handler+0x120/0x12c
|  el0t_64_sync+0x190/0x194
| Code: aa1303e0 97adbc11 d2d00000 f2fbffe0 (39c00000) 
| ---[ end trace 0000000000000000 ]---

> Signed-off-by: Stefan Wiehler <stefan.wiehler at nokia.com>
> ---
>  arch/arm64/include/asm/system_misc.h |  1 +
>  arch/arm64/kernel/process.c          | 11 +++++++++++
>  arch/arm64/kernel/traps.c            |  1 +
>  3 files changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
> index c34344256762..5b9b02fee988 100644
> --- a/arch/arm64/include/asm/system_misc.h
> +++ b/arch/arm64/include/asm/system_misc.h
> @@ -31,6 +31,7 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned long,
>  
>  struct mm_struct;
>  extern void __show_regs(struct pt_regs *);
> +extern void __show_regs_alloc_free(struct pt_regs *);
>  
>  #endif	/* __ASSEMBLY__ */
>  
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 7387b68c745b..b6fc2ac6e007 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -197,6 +197,17 @@ static void print_pstate(struct pt_regs *regs)
>  	}
>  }
>  
> +void __show_regs_alloc_free(struct pt_regs *regs)
> +{
> +	int i;
> +
> +	/* check for x0 - x29 only */
> +	for (i = 0; i < 30; i++) {
> +		pr_alert("Register x%d information:", i);
> +		mem_dump_obj((void *)regs->regs[i]);
> +	}
> +}

As above, I don't think it makes sense to dump this for a bunch of GPRs, and
I'd strongly prefer that we just do this for the faulting address.

I would also note that X30 can be used as a scratch register in the body of
functions and might hold an interesting address, whereas x2 *should* always
point to a frame record on the stack. So I don't understand why we'd both
dumping x29 but skip x30.

>  void __show_regs(struct pt_regs *regs)
>  {
>  	int i, top_reg;
> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> index 215e6d7f2df8..b7bf22f1b33f 100644
> --- a/arch/arm64/kernel/traps.c
> +++ b/arch/arm64/kernel/traps.c
> @@ -197,6 +197,7 @@ static int __die(const char *str, long err, struct pt_regs *regs)
>  
>  	print_modules();
>  	show_regs(regs);
> +	__show_regs_alloc_free(regs);
>  
>  	dump_kernel_instr(KERN_EMERG, regs);

We call die() (and consequently __die()) for a number of errors where the
provenance information isn't interesting (e.g. UNDEF, BTI, FPAC, BUG). As above
I think it makes more sense to only dump this in die_kernel_fault(), and only
for the actual faulting address.

Thanks,
Mark.


From rogerq at kernel.org  Mon Feb  5 04:57:32 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 5 Feb 2024 14:57:32 +0200
Subject: [PATCH v3 3/3] arm64: dts: ti: k3-am642-evm: add overlay for
 icssg1 2nd port
In-Reply-To: <17d1cfd0-2962-4857-af1d-7f2126b37abf@ti.com>
References: <20240122113045.1711818-1-danishanwar@ti.com>
 <20240122113045.1711818-4-danishanwar@ti.com>
 <33e62844-a148-4374-aba8-481dc7799e15@kernel.org>
 <17d1cfd0-2962-4857-af1d-7f2126b37abf@ti.com>
Message-ID: <6c5e2ca5-9b47-4a08-817c-e4bb1d10032f@kernel.org>



On 02/02/2024 18:50, Anwar, Md Danish wrote:
> On 2/2/2024 5:56 PM, Roger Quadros wrote:
>>
>>
>> On 22/01/2024 13:30, MD Danish Anwar wrote:
>>> The am642-evm doesn't allow to enable 2 x CPSW3g ports and 2 x ICSSG1 ports
>>> all together, so base k3-am642-evm.dts enables by default 2 x CPSW3g ports
>>> and 1 x ICSSG1 ports, but it also possible to support 1 x CPSW3g ports and
>>> 2 x ICSSG1 ports configuration.
>>
>> "it is also possible"
>>
>> OK so there can only be 3 ethernet ports on this board. There is no "ethernet3" alias.
>>
> 
> Yes maximum there can be 3 ports only. By default 2 are cpsw and 1 icssg
> but this parch introduces overlay to change the muxed port into icssg.
> 
> By default,
> 	ethernet0 = &cpsw_port1;
> 	ethernet1 = &cpsw_port2;
> 	ethernet2 = &icssg1_emac0;
> 
> When this overlay is applied, it should be something like this,
> 	ethernet0 = &cpsw_port1;
> 	ethernet1 = &icssg1_emac0;
> 	ethernet2 = &icssg1_emac1;
> 
> Let me know if this looks ok to you. I will modify the alias accordingly.

ethernet0 is ok

As per schematics: icssg1_emac0 is fixed to J21A port. so I'd call this ethernet1

J21B port can be switched between cpsw_port2 and icssg1_emac1. so I'd call this ethernet2

This way ethernet1 definition is fixed regardless and you are only switching ethernet2
definition.

> 
>>>
>>> This patch adds overlay to support 1 x CPSW3g ports and 2 x ICSSG1 ports
>>> configuration:
>>> - Add label name 'mdio_mux_1' for 'mdio-mux-1' node so that the node
>>>   'mdio-mux-1' can be disabled in the overlay using the label name.
>>> - disable 2nd CPSW3g port
>>> - update CPSW3g pinmuxes to not use RGMII2
>>> - disable mdio-mux-1 and define mdio-mux-2 to route ICSSG1 MDIO to the
>>>   shared DP83869 PHY
>>> - add and enable ICSSG1 RGMII2 pinmuxes
>>> - enable ICSSG1 MII1 port
>>>
>>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>>> ---
>>>  arch/arm64/boot/dts/ti/Makefile               |  5 ++
>>>  .../dts/ti/k3-am642-evm-icssg1-dualemac.dtso  | 75 +++++++++++++++++++
>>>  arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  2 +-
>>>  3 files changed, 81 insertions(+), 1 deletion(-)
>>>  create mode 100644 arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>>>
>>> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
>>> index 52c1dc910308..320b2fae5730 100644
>>> --- a/arch/arm64/boot/dts/ti/Makefile
>>> +++ b/arch/arm64/boot/dts/ti/Makefile
>>> @@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
>>>  dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
>>>  dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>>>  dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
>>> +dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac.dtbo
>>>  
>>>  # Boards with AM65x SoC
>>>  k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
>>> @@ -105,6 +106,8 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
>>>  	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>>>  k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
>>>  	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
>>> +k3-am642-evm-icssg1-dualemac-dtbs := \
>>> +	k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
>>>  k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
>>>  	k3-j721e-evm-pcie0-ep.dtbo
>>>  k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
>>> @@ -120,6 +123,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
>>>  	k3-am62a7-sk-csi2-ov5640.dtb \
>>>  	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
>>>  	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
>>> +	k3-am642-evm-icssg1-dualemac.dtb \
>>>  	k3-j721e-evm-pcie0-ep.dtb \
>>>  	k3-j721s2-evm-pcie1-ep.dtb
>>>  
>>> @@ -129,6 +133,7 @@ DTC_FLAGS_k3-am625-sk += -@
>>>  DTC_FLAGS_k3-am62-lp-sk += -@
>>>  DTC_FLAGS_k3-am62a7-sk += -@
>>>  DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
>>> +DTC_FLAGS_k3-am642-evm += -@
>>>  DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
>>>  DTC_FLAGS_k3-j721e-common-proc-board += -@
>>>  DTC_FLAGS_k3-j721s2-common-proc-board += -@
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>>> new file mode 100644
>>> index 000000000000..b2b1a6252e73
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>>> @@ -0,0 +1,75 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>
>> Don't you need to use updated licensing header like in the series [1]
>>
>> [1] https://lore.kernel.org/all/20240110140903.4090946-1-nm at ti.com/
>>
> 
> Sure. I will update the header.
> 
>>> +/**
>>> + * DT overlay for enabling 2nd ICSSG1 port on AM642 EVM
>>> + *
>>> + * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
>>> + */
>>> +
>>> +/dts-v1/;
>>> +/plugin/;
>>> +
>>> +#include <dt-bindings/gpio/gpio.h>
>>> +#include "k3-pinctrl.h"
>>> +
>>> +&{/} {
>>
>> You need to fixup alias for ethernet1 to icssg1_emac1?
>>
> 
> Yes I will update the aliases accordingly.
> 
>>> +	mdio-mux-2 {
>>
>> this should be mdio-mux at 0 ?
>>
> 
> The main mux in evm dts is defined as mdio-mux-1 so I was following the
> same. I will change this to mdio-mux at 0
> 
>>> +		compatible = "mdio-mux-multiplexer";
>>> +		mux-controls = <&mdio_mux>;
>>> +		mdio-parent-bus = <&icssg1_mdio>;
>>> +		#address-cells = <1>;
>>> +		#size-cells = <0>;
>>> +
>>> +		mdio at 0 {
>>> +			reg = <0x0>;
>>> +			#address-cells = <1>;
>>> +			#size-cells = <0>;
>>> +
>>> +			icssg1_phy2: ethernet-phy at 3 {
>>> +				reg = <3>;
>>> +				tx-internal-delay-ps = <250>;
>>> +				rx-internal-delay-ps = <2000>;
>>> +			};
>>> +		};
>>> +	};
>>> +};
>>> +
>>> +&main_pmx0 {
>>> +	icssg1_rgmii2_pins_default: icssg1-rgmii2-default-pins {
>>> +		pinctrl-single,pins = <
>>> +			AM64X_IOPAD(0x0108, PIN_INPUT, 2) /* (W11) PRG1_PRU1_GPO0.RGMII2_RD0 */
>>> +			AM64X_IOPAD(0x010c, PIN_INPUT, 2) /* (V11) PRG1_PRU1_GPO1.RGMII2_RD1 */
>>> +			AM64X_IOPAD(0x0110, PIN_INPUT, 2) /* (AA12) PRG1_PRU1_GPO2.RGMII2_RD2 */
>>> +			AM64X_IOPAD(0x0114, PIN_INPUT, 2) /* (Y12) PRG1_PRU1_GPO3.RGMII2_RD3 */
>>> +			AM64X_IOPAD(0x0120, PIN_INPUT, 2) /* (U11) PRG1_PRU1_GPO6.RGMII2_RXC */
>>> +			AM64X_IOPAD(0x0118, PIN_INPUT, 2) /* (W12) PRG1_PRU1_GPO4.RGMII2_RX_CTL */
>>> +			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2) /* (AA10) PRG1_PRU1_GPO11.RGMII2_TD0 */
>>> +			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2) /* (V10) PRG1_PRU1_GPO12.RGMII2_TD1 */
>>> +			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2) /* (U10) PRG1_PRU1_GPO13.RGMII2_TD2 */
>>> +			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2) /* (AA11) PRG1_PRU1_GPO14.RGMII2_TD3 */
>>> +			AM64X_IOPAD(0x0148, PIN_OUTPUT, 2) /* (Y10) PRG1_PRU1_GPO16.RGMII2_TXC */
>>> +			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2) /* (Y11) PRG1_PRU1_GPO15.RGMII2_TX_CTL */
>>> +		>;
>>> +	};
>>> +};
>>> +
>>> +&cpsw3g {
>>> +	pinctrl-0 = <&rgmii1_pins_default>;
>>> +};
>>> +
>>> +&cpsw_port2 {
>>> +	status = "disabled";
>>> +};
>>> +
>>> +&mdio_mux_1 {
>>> +	status = "disabled";
>>> +};
>>> +
>>> +&icssg1_eth {
>>> +	pinctrl-0 = <&icssg1_rgmii1_pins_default>, <&icssg1_rgmii2_pins_default>;
>>> +};
>>> +
>>> +&icssg1_emac1 {
>>> +	status = "okay";
>>> +	phy-handle = <&icssg1_phy2>;
>>> +	phy-mode = "rgmii-id";
>>> +};
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>>> index c08b0223be52..6ae43c12419f 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>>> @@ -200,7 +200,7 @@ mdio_mux: mux-controller {
>>>  		mux-gpios = <&exp1 12 GPIO_ACTIVE_HIGH>;
>>>  	};
>>>  
>>> -	mdio-mux-1 {
>>> +	mdio_mux_1: mdio-mux-1 {
>>
>> mdio_mux_1: mdio-mux at 1
>>
> 
> Sure. I will update this.
> 
>>>  		compatible = "mdio-mux-multiplexer";
>>>  		mux-controls = <&mdio_mux>;
>>>  		mdio-parent-bus = <&cpsw3g_mdio>;
>>
> 

-- 
cheers,
-roger


From oliver.upton at linux.dev  Mon Feb  5 05:04:51 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 5 Feb 2024 13:04:51 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event
 state to hypervisor
In-Reply-To: <8a908ee8-620a-d9c2-734b-5a6402950072@arm.com>
References: <20240104162714.1062610-1-james.clark@arm.com>
 <20240104162714.1062610-3-james.clark@arm.com>
 <Zb1mCCi13AJ_YjFZ@linux.dev>
 <8a908ee8-620a-d9c2-734b-5a6402950072@arm.com>
Message-ID: <ZcDc8-FQo8wKavA4@linux.dev>

On Mon, Feb 05, 2024 at 12:16:53PM +0000, James Clark wrote:
> > This now allows the host to program event counters for a protected
> > guest. That _might_ be a useful feature behind some debug option, but is
> > most definitely *not* something we want to do for pVMs generally.
> 
> Unless I'm missing something, using PMUs on protected guests was added
> by 722625c6f4c5b ("KVM: arm64: Reenable pmu in Protected Mode"). This
> change is just a refactor that will allow us to add the same behavior
> for a similar feature (tracing) without adding yet another copy of some
> state before the guest switch.

Ha, I had forgotten about that patch (and I had reviewed it!)

My interpretation of the intent for that change was to enable the usage
of vPMU for non-protected VMs. The situation has changed since then, as
we use the shadow state for vCPUs unconditionally in protected mode as
of commit  be66e67f1750 ("KVM: arm64: Use the pKVM hyp vCPU structure
in handle___kvm_vcpu_run()")

Protected mode is well understood at this point to be a WIP feature, and
that not all things are expected to work with it. Eventually we will
need a way to distinguish between 'normal' VMs and true pVMs (i.e. the
VMM selected full isolation) in nVHE, but right now what we have enables
testing of some isolation features.

> > I'm perfectly happy leaving these sorts of features broken for pKVM and
> > using the 'normal' way of getting percpu data to the nVHE hypervisor
> > otherwise.
> > 
> 
> I can do that. But do I also disable PMU at the same time in a new
> commit? Now that both PMU and tracing is working maybe it would be a
> waste to throw that away and hiding it behind an option is better. Or I
> can leave the PMU as it is and just keep tracing disabled in pKVM.
> 
> I don't mind either way, my main goal was to get exclude/include guest
> tracing working for normal VMs. For pKVM I don't have a strong opinion.

Unless someone has strong opinions about making this work in protected
mode, I am happy to see tracing support limited to the 'normal' nVHE
configuration. The protected feature as a whole is just baggage until
upstream support is completed.

-- 
Thanks,
Oliver


From rostedt at goodmis.org  Mon Feb  5 05:06:09 2024
From: rostedt at goodmis.org (Steven Rostedt)
Date: Mon, 5 Feb 2024 08:06:09 -0500
Subject: Question about the ipi_raise filter usage and output
In-Reply-To: <ZcC4aWWKFU1NgrZM@FVFF77S0Q05N>
References: <CAJNi4rMpt88Gz+149wR9crzApmfUEfpS05sbOgAvOhzh2+Brbg@mail.gmail.com>
	<ZcC4aWWKFU1NgrZM@FVFF77S0Q05N>
Message-ID: <20240205080609.563df00f@rorschach.local.home>

On Mon, 5 Feb 2024 10:28:57 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> > I try to write below:
> > echo 'target_cpus == 11 && reason == "Function call interrupts"' >
> > events/ipi/ipi_raise/filter  
> 
> The '=' checks if the target_cpus bitmap *only* contains CPU 11. If the cpumask
> contains other CPUs, the filter will skip the call.
> 
> I believe you can use '&' to check whether a cpumask contains a CPU, e.g.
> 
> 	'target_cpus & 11'

11 == 0xb = b1011

So the above would only be true for CPUs 0,1 and 3 ;-)

I think you meant: 'target_cpus & 0x800' 

I tried "1 << 11' but it appears to not allow shifts. I wonder if we should add that?

-- Steve


From xiaobo55x at gmail.com  Mon Feb  5 05:10:26 2024
From: xiaobo55x at gmail.com (Haibo Xu)
Date: Mon, 5 Feb 2024 21:10:26 +0800
Subject: [PATCH v5 00/12] RISCV: Add kvm Sstc timer selftests
In-Reply-To: <cover.1705916069.git.haibo1.xu@intel.com>
References: <cover.1705916069.git.haibo1.xu@intel.com>
Message-ID: <CAJve8onDbX44Ph6a-FdO2+p7QOQLah-7OyF+yUc06wud+SvmQQ@mail.gmail.com>

Hi Marc,

Could you help review the first 3 patches in this series?

Thanks,
Haibo

On Mon, Jan 22, 2024 at 5:45?PM Haibo Xu <haibo1.xu at intel.com> wrote:
>
> The RISC-V arch_timer selftests is used to validate Sstc timer
> functionality in a guest, which sets up periodic timer interrupts
> and check the basic interrupt status upon its receipt.
>
> This KVM selftests was ported from aarch64 arch_timer and tested
> with Linux v6.7-rc8 on a Qemu riscv64 virt machine.
>
> ---
> Changed since v4:
>   * Rebased to Linux 6.7-rc8
>   * Added new patch(2/12) to clean up the data type in struct test_args
>   * Re-ordered patch(11/11) in v4 to patch(3/12)
>   * Changed the timer_err_margin_us type from int to uint32_t
>
> Haibo Xu (11):
>   KVM: arm64: selftests: Data type cleanup for arch_timer test
>   KVM: arm64: selftests: Enable tuning of error margin in arch_timer
>     test
>   KVM: arm64: selftests: Split arch_timer test code
>   KVM: selftests: Add CONFIG_64BIT definition for the build
>   tools: riscv: Add header file csr.h
>   tools: riscv: Add header file vdso/processor.h
>   KVM: riscv: selftests: Switch to use macro from csr.h
>   KVM: riscv: selftests: Add exception handling support
>   KVM: riscv: selftests: Add guest helper to get vcpu id
>   KVM: riscv: selftests: Change vcpu_has_ext to a common function
>   KVM: riscv: selftests: Add sstc timer test
>
> Paolo Bonzini (1):
>   selftests/kvm: Fix issues with $(SPLIT_TESTS)
>
>  tools/arch/riscv/include/asm/csr.h            | 541 ++++++++++++++++++
>  tools/arch/riscv/include/asm/vdso/processor.h |  32 ++
>  tools/testing/selftests/kvm/Makefile          |  27 +-
>  .../selftests/kvm/aarch64/arch_timer.c        | 295 +---------
>  tools/testing/selftests/kvm/arch_timer.c      | 259 +++++++++
>  .../selftests/kvm/include/aarch64/processor.h |   4 -
>  .../selftests/kvm/include/kvm_util_base.h     |   9 +
>  .../selftests/kvm/include/riscv/arch_timer.h  |  71 +++
>  .../selftests/kvm/include/riscv/processor.h   |  65 ++-
>  .../testing/selftests/kvm/include/test_util.h |   2 +
>  .../selftests/kvm/include/timer_test.h        |  45 ++
>  .../selftests/kvm/lib/riscv/handlers.S        | 101 ++++
>  .../selftests/kvm/lib/riscv/processor.c       |  87 +++
>  .../testing/selftests/kvm/riscv/arch_timer.c  | 111 ++++
>  .../selftests/kvm/riscv/get-reg-list.c        |  11 +-
>  15 files changed, 1353 insertions(+), 307 deletions(-)
>  create mode 100644 tools/arch/riscv/include/asm/csr.h
>  create mode 100644 tools/arch/riscv/include/asm/vdso/processor.h
>  create mode 100644 tools/testing/selftests/kvm/arch_timer.c
>  create mode 100644 tools/testing/selftests/kvm/include/riscv/arch_timer.h
>  create mode 100644 tools/testing/selftests/kvm/include/timer_test.h
>  create mode 100644 tools/testing/selftests/kvm/lib/riscv/handlers.S
>  create mode 100644 tools/testing/selftests/kvm/riscv/arch_timer.c
>
> --
> 2.34.1
>


From krzysztof.kozlowski at linaro.org  Mon Feb  5 05:13:13 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 5 Feb 2024 14:13:13 +0100
Subject: [PATCH v2 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <CADrjBPoQmTRsFYRtxBxdvAoKK816O8XN3=hOJ3vBt8wbbbk-=Q@mail.gmail.com>
References: <20240129211912.3068411-1-peter.griffin@linaro.org>
 <20240129211912.3068411-2-peter.griffin@linaro.org>
 <fb530eb8-e32b-4faf-81f3-efc334ebf241@linaro.org>
 <CADrjBPoQmTRsFYRtxBxdvAoKK816O8XN3=hOJ3vBt8wbbbk-=Q@mail.gmail.com>
Message-ID: <99828589-c0b5-456d-b250-6ad3e6085a91@linaro.org>

On 01/02/2024 13:51, Peter Griffin wrote:
> Hi Krzysztof,
> 
> On Tue, 30 Jan 2024 at 16:01, Krzysztof Kozlowski
> <krzysztof.kozlowski at linaro.org> wrote:
>>
>> On 29/01/2024 22:19, Peter Griffin wrote:
>>> Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
>>> security hardening reasons so that they are only accessible in el3 via an
>>> SMC call.
>>>
>>> As most Exynos drivers that need to write PMU registers currently obtain a
>>> regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
>>> is implemented in this driver using a custom regmap similar to syscon to
>>> handle the SMC call. Platforms that don't secure PMU registers, get a mmio
>>> regmap like before. As regmaps abstract out the underlying register access
>>> changes to the leaf drivers are minimal.
>>>
>>> A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
>>> that currently use syscon_regmap_lookup_by_phandle(). This also handles
>>> deferred probing.
>>>
>>> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
>>> ---
>>>  drivers/soc/samsung/exynos-pmu.c       | 227 ++++++++++++++++++++++++-
>>>  include/linux/soc/samsung/exynos-pmu.h |  10 ++
>>>  2 files changed, 236 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
>>> index 250537d7cfd6..7bcc144e53a2 100644
>>> --- a/drivers/soc/samsung/exynos-pmu.c
>>> +++ b/drivers/soc/samsung/exynos-pmu.c
>>> @@ -5,6 +5,7 @@
>>>  //
>>>  // Exynos - CPU PMU(Power Management Unit) support
>>>
>>> +#include <linux/arm-smccc.h>
>>>  #include <linux/of.h>
>>>  #include <linux/of_address.h>
>>>  #include <linux/mfd/core.h>
>>> @@ -12,20 +13,159 @@
>>>  #include <linux/of_platform.h>
>>>  #include <linux/platform_device.h>
>>>  #include <linux/delay.h>
>>> +#include <linux/regmap.h>
>>>
>>>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>>>  #include <linux/soc/samsung/exynos-pmu.h>
>>>
>>>  #include "exynos-pmu.h"
>>>
>>> +static struct platform_driver exynos_pmu_driver;
>>
>> I don't understand why do you need it. You can have only one
>> pmu_context. The moment you probe second one, previous becomes invalid.
>>
>> I guess you want to parse phandle and check if just in case if it points
>> to the right device, but still the original code is not ready for two
>> PMU devices. I say either this problem should be solved entirely,
>> allowing two devices, or just compare device node from phandle with
>> device node of exynos_pmu_context->dev and return -EINVAL on mismatches.
> 
> Apologies I didn't answer your original question. This wasn't about
> having partial support for multiple pmu devices. It is being used by
> driver_find_device_by_of_node() in exynos_get_pmu_regmap_by_phandle()
> to determine that the exynos-pmu device has probed and therefore a
> pmu_context exists and a regmap has been created and can be returned
> to the caller (as opposed to doing a -EPROBE_DEFER).
> 
> Is there some better/other API you recommend for this purpose? Just
> checking pmu_context directly seems racy, so I don't think we should
> do that.

Hm, I don't quite get why you cannot use of_find_device_by_node()?

Best regards,
Krzysztof



From oliver.upton at linux.dev  Mon Feb  5 05:14:27 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 5 Feb 2024 13:14:27 +0000
Subject: [PATCH v4 02/10] KVM: arm64: Add ptdump registration with
 debugfs for the stage-2 pagetables
In-Reply-To: <Zbt-leieTD64ZefR@google.com>
References: <20231218135859.2513568-2-sebastianene@google.com>
 <20231218135859.2513568-4-sebastianene@google.com>
 <ZYSAfORj2-cXo5t_@linux.dev>
 <Zbt-leieTD64ZefR@google.com>
Message-ID: <ZcDfM2VRiTETM04I@linux.dev>

On Thu, Feb 01, 2024 at 11:20:53AM +0000, Sebastian Ene wrote:
> On Thu, Dec 21, 2023 at 06:14:20PM +0000, Oliver Upton wrote:
> 
> Hi Oliver,
> 
> I am planning to split the series based on your suggestion and I
> wanted to make sure that I understand your feedback.
> 
> > On Mon, Dec 18, 2023 at 01:58:52PM +0000, Sebastian Ene wrote:
> > > +config PTDUMP_STAGE2_DEBUGFS
> > > +       bool "Present the stage-2 pagetables to debugfs"
> > > +       depends on PTDUMP_DEBUGFS && KVM
> > > +       default n
> > > +       help
> > > +         Say Y here if you want to show the stage-2 kernel pagetables
> > > +         layout in a debugfs file. This information is only useful for kernel developers
> > > +         who are working in architecture specific areas of the kernel.
> > > +         It is probably not a good idea to enable this feature in a production
> > > +         kernel.
> > 
> > It isn't really a good idea to mount debugfs at all in a production
> > system. There are already plenty worse interfaces lurking in that
> > filesystem. The pKVM portions already depend on CONFIG_NVHE_EL2_DEBUG,
> > so I don't see a need for this Kconfig option.
> > 
> 
> I created a separate option because I wanted to re-use the parsing
> functionality from the already existing ptdump code for EL1. This option
> is turned off in production and only enabled for debug.
> 
> I was thinking to make use of the `CONFIG_NVHE_EL2_DEBUG` but then I abandoned 
> this ideea as one can use ptdump for vHE as well.

Fair enough. I was going to say we could just have KVM follow
CONFIG_PTDUMP_DEBUGFS, but it doesn't matter either way.

> > > +void kvm_ptdump_register_host(void)
> > > +{
> > > +	if (!is_protected_kvm_enabled())
> > > +		return;
> > > +
> > > +	kvm_ptdump_debugfs_register(&host_reg, "host_page_tables",
> > > +				    kvm_debugfs_dir);
> > > +}
> > > +
> > > +static int __init kvm_host_ptdump_init(void)
> > > +{
> > > +	host_reg.priv = (void *)host_s2_pgtable_pages();
> > > +	return 0;
> > > +}
> > > +
> > > +device_initcall(kvm_host_ptdump_init);
> > 
> > Why can't all of this be called from finalize_pkvm()?
> > 
> 
> I guess it can be called from finalize_pkvm before the is_protected_kvm_enabled
> check. This should work for nvhe & vhe as well.

What does nvhe and vhe modes have to do with it? I thought this was for
hooking up the host's S2, which does not exist outside protected mode.

-- 
Thanks,
Oliver


From maz at kernel.org  Mon Feb  5 05:15:36 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 05 Feb 2024 13:15:36 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event state to hypervisor
In-Reply-To: <ZcDc8-FQo8wKavA4@linux.dev>
References: <20240104162714.1062610-1-james.clark@arm.com>
	<20240104162714.1062610-3-james.clark@arm.com>
	<Zb1mCCi13AJ_YjFZ@linux.dev>
	<8a908ee8-620a-d9c2-734b-5a6402950072@arm.com>
	<ZcDc8-FQo8wKavA4@linux.dev>
Message-ID: <867cjj6ohz.wl-maz@kernel.org>

On Mon, 05 Feb 2024 13:04:51 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> Unless someone has strong opinions about making this work in protected
> mode, I am happy to see tracing support limited to the 'normal' nVHE
> configuration. The protected feature as a whole is just baggage until
> upstream support is completed.

Limiting tracing to non-protected mode is a must IMO. Allowing tracing
when pKVM is enabled is a sure way to expose secrets that should
stay... secret. The only exception I can think of is when
CONFIG_NVHE_EL2_DEBUG is enabled, at which point all bets are off.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From oliver.upton at linux.dev  Mon Feb  5 05:21:26 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 5 Feb 2024 13:21:26 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event
 state to hypervisor
In-Reply-To: <867cjj6ohz.wl-maz@kernel.org>
References: <20240104162714.1062610-1-james.clark@arm.com>
 <20240104162714.1062610-3-james.clark@arm.com>
 <Zb1mCCi13AJ_YjFZ@linux.dev>
 <8a908ee8-620a-d9c2-734b-5a6402950072@arm.com>
 <ZcDc8-FQo8wKavA4@linux.dev>
 <867cjj6ohz.wl-maz@kernel.org>
Message-ID: <ZcDg1sP3EYZG-i_3@linux.dev>

On Mon, Feb 05, 2024 at 01:15:36PM +0000, Marc Zyngier wrote:
> On Mon, 05 Feb 2024 13:04:51 +0000,
> Oliver Upton <oliver.upton at linux.dev> wrote:
> > 
> > Unless someone has strong opinions about making this work in protected
> > mode, I am happy to see tracing support limited to the 'normal' nVHE
> > configuration. The protected feature as a whole is just baggage until
> > upstream support is completed.
> 
> Limiting tracing to non-protected mode is a must IMO. Allowing tracing
> when pKVM is enabled is a sure way to expose secrets that should
> stay... secret. The only exception I can think of is when
> CONFIG_NVHE_EL2_DEBUG is enabled, at which point all bets are off.

Zero argument there :) I left off the "and PMU" part of what I was
saying, because that was a feature that semi-worked in protected mode
before VM/VCPU shadowing support landed.

-- 
Thanks,
Oliver


From miquel.raynal at bootlin.com  Mon Feb  5 05:26:39 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 5 Feb 2024 14:26:39 +0100
Subject: [PATCH v4 03/12] dt-bindings: mtd: brcmnand: Add ecc strap
 property
In-Reply-To: <20240203-expenses-tarmac-c564bc7ae34f@spud>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
	<20240203002834.171462-4-william.zhang@broadcom.com>
	<20240203-expenses-tarmac-c564bc7ae34f@spud>
Message-ID: <20240205142639.5d7c70f0@xps-13>

Hi,

conor at kernel.org wrote on Sat, 3 Feb 2024 14:49:50 +0000:

> On Fri, Feb 02, 2024 at 04:28:24PM -0800, William Zhang wrote:
> > Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
> > board boot strap for broadband board designs because they do not specify
> > ecc setting in dts but rather using the strap setting.
> > 
> > Signed-off-by: William Zhang <william.zhang at broadcom.com>
> > 
> > ---
> > 
> > Changes in v4:
> > - Move ecc strap property to this separate patch and remove some
> > non-binding related text from the description
> > 
> > Changes in v3: None
> > Changes in v2: None
> > 
> >  Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> > index d0168d55c73e..2599d902ec3a 100644
> > --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> > +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> > @@ -147,6 +147,14 @@ patternProperties:
> >            layout.
> >          $ref: /schemas/types.yaml#/definitions/uint32
> >  
> > +      brcm,nand-ecc-use-strap:
> > +        description:
> > +          This flag indicates the ecc strength and spare area size should
> > +          be retrieved from the SoC NAND boot strap setting instead of
> > +          nand-ecc-strength and brcm,nand-oob-sector-size or auto detection.  
> 
> I'm still on the fence about this being overly prescriptive about the
> operating systems behaviour. I think it would be good to say why the
> strap values are better than those explicitly provided in DT rather than
> just saying "these strap values should be used".

I don't know if there is a point is saying why they would be better, as
they are not. It is a -questionable- design choice. However I would
just get rid of any mention to other properties. Just say one should
expect the strap value to be read and applied by the system when this
property is present.

> > +          This is commonly used by the BCMBCA SoC board design.
> > +        $ref: /schemas/types.yaml#/definitions/flag
> > +
> >      unevaluatedProperties: false
> >  
> >  allOf:
> > -- 
> > 2.37.3
> >   


Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Mon Feb  5 05:32:46 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 5 Feb 2024 14:32:46 +0100
Subject: [PATCH v4 02/12] dt-bindings: mtd: brcmnand: Add WP pin
 connection property
In-Reply-To: <20240203002834.171462-3-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
	<20240203002834.171462-3-william.zhang@broadcom.com>
Message-ID: <20240205143246.52ee97ec@xps-13>

Hi William,

william.zhang at broadcom.com wrote on Fri,  2 Feb 2024 16:28:23 -0800:

> Add brcm,wp-not-connected property to have an option for disabling this
> feature on broadband board design that does not connect WP pin.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> 
> ---
> 
> Changes in v4:
> - Move the WP pin property to this separate patch and change it to
> boolean type.
> 
> Changes in v3: None
> Changes in v2: None
> 
>  Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> index e54ca08a798a..d0168d55c73e 100644
> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> @@ -113,6 +113,14 @@ properties:
>        earlier versions of this core that include WP
>      type: boolean
>  
> +  brcm,wp-not-connected:
> +    description:
> +      Use this property when board design does not connect controller's
> +      NAND_WPb pin to NAND chip's WP_L pin and disable the write
> +      protection feature. By default, controller assumes the pin is
> +      connected and feature is used.

I would rephrase slightly. What about:

	 WP pin is not physically wired to the NAND chip. Write
	 protection feature cannot be used.
 
> +    $ref: /schemas/types.yaml#/definitions/flag
> +
>  patternProperties:
>    "^nand@[a-f0-9]$":
>      type: object


Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Mon Feb  5 05:37:45 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 5 Feb 2024 14:37:45 +0100
Subject: [PATCH v4 12/12] mtd: rawnand: brcmnand: update log level
 messages
In-Reply-To: <20240203002834.171462-13-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
	<20240203002834.171462-13-william.zhang@broadcom.com>
Message-ID: <20240205143745.5a1036c6@xps-13>

Hi William,

william.zhang at broadcom.com wrote on Fri,  2 Feb 2024 16:28:33 -0800:

> From: David Regan <dregan at broadcom.com>
> 
> Update log level messages so that more critical messages
> can be seen.

This commit log does not convince me. Warning messages are visible,
they are in dmesg. If you want them on your console, lower your default
console level by 1 and they will appear. I'm fine increasing the log
level on error messages, but the justification cannot be specific to
your own setup.

> 
> Signed-off-by: David Regan <dregan at broadcom.com>
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: William Zhang <william.zhang at broadcom.com>
> 
> ---
> 
> Changes in v4:
> - Revert the log level change for correctable ecc error
> 
> Changes in v3: None
> Changes in v2:
> - Added to patch series
> 
>  drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index 7ce2b267676f..e50582b45182 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -1143,7 +1143,7 @@ static int bcmnand_ctrl_poll_status(struct brcmnand_host *host,
>  	if ((val & mask) == expected_val)
>  		return 0;
>  
> -	dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
> +	dev_err(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
>  		 expected_val, val & mask);
>  
>  	return -ETIMEDOUT;
> @@ -2196,7 +2196,7 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
>  				return err;
>  		}
>  
> -		dev_dbg(ctrl->dev, "uncorrectable error at 0x%llx\n",
> +		dev_err(ctrl->dev, "uncorrectable error at 0x%llx\n",
>  			(unsigned long long)err_addr);
>  		mtd->ecc_stats.failed++;
>  		/* NAND layer expects zero on ECC errors */


Thanks,
Miqu?l


From robh at kernel.org  Mon Feb  5 05:46:45 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 05 Feb 2024 13:46:45 +0000
Subject: [PATCH 1/3] dt-bindings: mfd: qcom,spmi-pmic: Add pbs to SPMI
 device types
In-Reply-To: <20240205-pmi632-ppg-v1-1-e236c95a2099@fairphone.com>
References: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
 <20240205-pmi632-ppg-v1-1-e236c95a2099@fairphone.com>
Message-ID: <170714066275.3239944.3114776132620071326.robh@kernel.org>


On Mon, 05 Feb 2024 10:51:38 +0100, Luca Weiss wrote:
> Add the PBS (Programmable Boot Sequencer) to the list of devices.
> 
> Signed-off-by: Luca Weiss <luca.weiss at fairphone.com>
> ---
>  Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
> 

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/dt-review-ci/linux/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml:
Error in referenced schema matching $id: http://devicetree.org/schemas/soc/qcom/qcom,pbs.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240205-pmi632-ppg-v1-1-e236c95a2099 at fairphone.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From cristian.marussi at arm.com  Mon Feb  5 05:52:27 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 5 Feb 2024 13:52:27 +0000
Subject: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <DU0PR04MB9417CA6CF089B264112C32A088402@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20240121-pinctrl-scmi-v3-0-8d94ba79dca8@nxp.com>
 <f88d07ef-83b2-4d14-976a-6dbbd71e036f@oss.nxp.com>
 <CACRpkdYV=qYQ9qDUWYTLDAV1niay30gYH5S=zjfi31GpeY5o-A@mail.gmail.com>
 <DU0PR04MB9417A9074C5DC49AE689E65288432@DU0PR04MB9417.eurprd04.prod.outlook.com>
 <Zbt-QkWhz5d9P-v6@pluto>
 <DU0PR04MB9417CA6CF089B264112C32A088402@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <ZcDoG6FTiNgChQJF@pluto>

On Sun, Feb 04, 2024 at 09:29:25AM +0000, Peng Fan wrote:
> > Subject: Re: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
> > protocol basic support
> > 
> > On Thu, Feb 01, 2024 at 07:14:17AM +0000, Peng Fan wrote:
> > > > Subject: Re: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2
> > > > pincontrol protocol basic support
> > > >
> > 
> > Hi Peng,
> > 
> > > > On Mon, Jan 29, 2024 at 1:37?PM Peng Fan <peng.fan at oss.nxp.com>
> > wrote:
> > > >
> > > > > And for i.MX95 OEM extenstion, do you have any suggestions?
> > > > > I have two points:
> > > > > 1. use vendor compatible. This would also benefit when supporting
> > > > > vendor protocol.
> > > > > 2. Introduce a property saying supporting-generic-pinconf
> > > > >
> > > > > How do you think?
> > > >
> > > > While I don't know how OEM extensions to SCMI were designed, the pin
> > > > control subsystem has the philosophy that extensions are for minor
> > > > fringe stuff, such as a pin config option that no other silicon is
> > > > using and thus have no use for anyone else. Well that is actually
> > > > all the custom extensions we have.
> > > > (This notion is even carried over to SCMI pinctrl.)
> > > >
> > > > The i.MX95 OEM extension is really odd to me, it looks like a
> > > > reimplementation of the core aspects of SCMI pin control, and looks
> > > > much more like the old i.MX drivers than like the SCMI driver.
> > >
> > > i.MX SCMI pin protocol conf settings follows non-SCMI pin conf settings.
> > >
> > 
> > It is not just a matter of using custom SCMI OEM types, it is the whole
> > layout/definitions of the i.MX pin/groups/funcs DT bindings that deviates
> > from the generic DT bindings layout as handled and expected by the Linux
> > Pinctrl subsystem (AFAIU), while the SCMI Pinctrl driver as it stands in this
> > series, was conceived, designed and implemented originally by Oleksii to just
> > use the generic existing Pinctrl DT bindings; as a consequence, in your i.MX
> > extensions, you had to add a dedicated i.MX DT parser to interpret the
> > protocol at 19 DT snippet in a completely different way, to try to stick your
> > custom solution on top of the generic one.
> 
> The two links shows the drop of i.MX generic pinconf
> https://patchwork.ozlabs.org/project/linux-gpio/patch/1541149669-10857-7-git-send-email-aisheng.dong at nxp.com/
> https://lore.kernel.org/all/20230302072132.1051590-1-linux at rasmusvillemoes.dk/
> 
> For non-scmi platforms, the generic pinconf was supported
> for i.MX7ULP for a while, and then dropped in the end per i.MX maintainers
> and agreed by Linus.
> 
> For i.MX95 SCMI platforms, the firmware design is simple and use similar
> programming model to simplify firmware design.
> 
> Using generic pinconf means the firmware needs exporting groups/functions/pins
> and etc, the firmware design will be complicated and code size enlarged.
> 

Understood.

> I have no better ideas without introducing a compatible for dt map hook.
> 
> Build exclusive is not acceptable for distro support.
> 

Indeed, and I understand that, but in any case it wont be required for
both the generic pinconf and the IMX way to coexist and live together on
the same system/platform at runtime, right ?

So, I was thinking as an alternative, while still building all
(generic+IMX) in defconfig, wouldn't be possible to detect at runtime in the
pinctrl-scmi probe() which is the type of binding used in the DT (i.e.
generic VS imx), before registering with the core Pinctrl subsystem, and so
act accordingly parsing and providing different callbacks based on that ?

I mean, without any compatible addition, just looking up the protocol at 19
node content @probe and switch to iMX callbacks if the fsl,pins binding
is found ?

Not sure is this is totally viable, nor clean or that it is not less horrific
from the Pinctrl_subsystem/DT point of view for Linus ... just an idea to think
about or discard.

> So the last options is i.MX95 switch back to VENDOR protocol ID saying
> 0x82. But this means to exports functions of pinctrl-scmi.c and reused
> by pinctrl-scmi-imx.c.  If you agree, I will ask firmware developer
> switch back to a new SCMI ID, and I will use new ID for i.mx pinctrl
> driver.
> 

I dont think there is really any chance to upstream a vendor protocol that
is a bare copy of a standard protocol just to workaround this...and if
this is going to be the end-result you can just keep your current 2
small 'IMX custom-compatible' patches downstream.

> But in the end I would think when more SCMI vendor protocols
> comes in, saying vendor A and vendor B both use ID 0x81,
> both use 0x81 as RTC functions, same issue will come back.
>

This wont be a problem once the RFC[1] I posted last week is in...unless
someone objects, you will have to identify your vendor protocol module
at build time ALSO with the vendor/sub_vendor ID string exposed by your fw...
...so each vendor will effectively have the full vendor protocol space
number at their disposal.

Indeed this week, I hope to review your series about custom protocols
and the qualcomm ones and ask both for feedback on [1] and then to
rework those series on some non-RFC similar to 1 that I will post
afterwards.

Thanks,
Cristian

[1]: https://lore.kernel.org/linux-arm-kernel/20240122122437.546621-1-cristian.marussi at arm.com/


From Markus.Elfring at web.de  Mon Feb  5 05:55:23 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Mon, 5 Feb 2024 14:55:23 +0100
Subject: [PATCH] net: emaclite: Use devm_platform_get_and_ioremap_resource()
 in xemaclite_of_probe()
Message-ID: <f87065d0-e398-4ffa-bfa4-9ff99d73f206@web.de>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Mon, 5 Feb 2024 14:44:20 +0100

A wrapper function is available since the commit 890cc39a879906b63912482dfc41944579df2dc6
("drivers: provide devm_platform_get_and_ioremap_resource()").
Thus reuse existing functionality instead of keeping duplicate source code.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/net/ethernet/xilinx/xilinx_emaclite.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 765aa516aada..940452d0a4d2 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -1114,8 +1114,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev)

 	ndev->irq = rc;

-	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
-	lp->base_addr = devm_ioremap_resource(&ofdev->dev, res);
+	lp->base_addr = devm_platform_get_and_ioremap_resource(ofdev, 0, &res);
 	if (IS_ERR(lp->base_addr)) {
 		rc = PTR_ERR(lp->base_addr);
 		goto error;
--
2.43.0



From rogerq at kernel.org  Mon Feb  5 05:59:06 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon,  5 Feb 2024 15:59:06 +0200
Subject: [PATCH v4 1/3] dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl compatible
In-Reply-To: <20240205135908.54656-1-rogerq@kernel.org>
References: <20240205135908.54656-1-rogerq@kernel.org>
Message-ID: <20240205135908.54656-2-rogerq@kernel.org>

Add the compatible for TI AM62 USB PHY Control register. This
register is found in the TI AM62 WKUP_CTRL_MMR0 space [1]. It
is used to indicate the USB PHY PLL reference clock rate and
core voltage level to the USB controller.

[1] - https://www.ti.com/lit/pdf/spruiv7

Signed-off-by: Roger Quadros <rogerq at kernel.org>
Acked-by: Rob Herring <robh at kernel.org>
---

Notes:
    Changelog:
    
    v4 - no change. Added Rob's Acked-by
    
    v3 - add compatibles in alphabetical order
    https://lore.kernel.org/all/20240201120332.4811-2-rogerq at kernel.org/
    
    v2 - New patch

 Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index 084b5c2a2a3c..9437705af92f 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -72,6 +72,7 @@ properties:
               - rockchip,rk3588-qos
               - rockchip,rv1126-qos
               - starfive,jh7100-sysmain
+              - ti,am62-usb-phy-ctrl
               - ti,am654-dss-oldi-io-ctrl
 
           - const: syscon
-- 
2.34.1



From rogerq at kernel.org  Mon Feb  5 05:59:05 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon,  5 Feb 2024 15:59:05 +0200
Subject: [PATCH v4 0/3] arm64: dts: ti: am62: Add USB support for k3-am62p
Message-ID: <20240205135908.54656-1-rogerq@kernel.org>

Hi,

This series first adds device nodes for USB0_PHY_CTRL and USB1_PHY_CTRL
in the wkup_conf node and fixus up the USB nodes to use the newly
added nodes.

Then it adds USB support for AM62P SoC and AM62P5-SK board.

In v4, we drop the 2 new patches that were added in v3 to add the
missing PHY2 register space to the USB controller wrapper node.

Changelog in each patch.

cheers,
-roger

Roger Quadros (3):
  dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl compatible
  arm64: dts: ti: k3-am62/a: use sub-node for USB_PHY_CTRL registers
  arm64: dts: ti: k3-am62p: add the USB sub-system

 .../devicetree/bindings/mfd/syscon.yaml       |  1 +
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi      |  4 +-
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi    | 10 +++
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi     |  4 +-
 arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi   | 10 +++
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi     | 46 +++++++++++++
 arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi   | 10 +++
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts       | 67 +++++++++++++++++++
 8 files changed, 148 insertions(+), 4 deletions(-)


base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
-- 
2.34.1



From rogerq at kernel.org  Mon Feb  5 05:59:07 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon,  5 Feb 2024 15:59:07 +0200
Subject: [PATCH v4 2/3] arm64: dts: ti: k3-am62/a: use sub-node for USB_PHY_CTRL registers
In-Reply-To: <20240205135908.54656-1-rogerq@kernel.org>
References: <20240205135908.54656-1-rogerq@kernel.org>
Message-ID: <20240205135908.54656-3-rogerq@kernel.org>

Exposing the entire CTRL_MMR space to syscon is not a good idea.
Add sub-nodes for USB0_PHY_CTRL and USB1_PHY_CTRL and use them
in the USB0/USB1 nodes.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
Reviewed-by: Andrew Davis <afd at ti.com>
---

Notes:
    Changelog:
    
    v4 - no change. Added Andrew's Reviewed-by
    
    v3 - no change
    https://lore.kernel.org/all/20240201120332.4811-3-rogerq at kernel.org/
    
    v2:
    - moved am62p changes to next patch
    - use new compatible for USB PHY CTRL node

 arch/arm64/boot/dts/ti/k3-am62-main.dtsi    |  4 ++--
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi  | 10 ++++++++++
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi   |  4 ++--
 arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi | 10 ++++++++++
 4 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 464b7565d085..9432ed344d52 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -625,7 +625,7 @@ usbss0: dwc3-usb at f900000 {
 		reg = <0x00 0x0f900000 0x00 0x800>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
@@ -648,7 +648,7 @@ usbss1: dwc3-usb at f910000 {
 		reg = <0x00 0x0f910000 0x00 0x800>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
index fef76f52a52e..817700b2eacf 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -19,6 +19,16 @@ chipid: chipid at 14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	wkup_uart0: serial at 2b300000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index f0b8c9ab1459..8311c7c44cd3 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -566,7 +566,7 @@ usbss0: dwc3-usb at f900000 {
 		reg = <0x00 0x0f900000 0x00 0x800>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
@@ -589,7 +589,7 @@ usbss1: dwc3-usb at f910000 {
 		reg = <0x00 0x0f910000 0x00 0x800>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
index 4e8279fa01e1..4a375f5e0c19 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
@@ -17,6 +17,16 @@ chipid: chipid at 14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	wkup_uart0: serial at 2b300000 {
-- 
2.34.1



From rogerq at kernel.org  Mon Feb  5 05:59:08 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon,  5 Feb 2024 15:59:08 +0200
Subject: [PATCH v4 3/3] arm64: dts: ti: k3-am62p: add the USB sub-system
In-Reply-To: <20240205135908.54656-1-rogerq@kernel.org>
References: <20240205135908.54656-1-rogerq@kernel.org>
Message-ID: <20240205135908.54656-4-rogerq@kernel.org>

There are two USB instances available on the am62p5 starter kit. Include
and enable them for use on the board.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Roger Quadros <rogerq at kernel.org>
---

Notes:
    Changelog:
    
    v4 - no change
    
    v3 - no change
    https://lore.kernel.org/all/20240201120332.4811-4-rogerq at kernel.org/
    
    v2:
    - added USB PHY CTRL node changes here
    - changed USB wrapper node names to usb@
    - changed Type-C chip node name to usb-power-control@

 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi   | 46 ++++++++++++++
 arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi | 10 +++
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts     | 67 +++++++++++++++++++++
 3 files changed, 123 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 4c51bae06b57..17d28390d587 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -560,6 +560,52 @@ sdhci2: mmc at fa20000 {
 		status = "disabled";
 	};
 
+	usbss0: usb at f900000 {
+		compatible = "ti,am62-usb";
+		reg = <0x00 0x0f900000 0x00 0x800>;
+		clocks = <&k3_clks 161 3>;
+		clock-names = "ref";
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
+		ranges;
+		status = "disabled";
+
+		usb0: usb at 31000000 {
+			compatible = "snps,dwc3";
+			reg = <0x00 0x31000000 0x00 0x50000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+			<GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+			interrupt-names = "host", "peripheral";
+			maximum-speed = "high-speed";
+			dr_mode = "otg";
+		};
+	};
+
+	usbss1: usb at f910000 {
+		compatible = "ti,am62-usb";
+		reg = <0x00 0x0f910000 0x00 0x800>;
+		clocks = <&k3_clks 162 3>;
+		clock-names = "ref";
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
+		ranges;
+		status = "disabled";
+
+		usb1: usb at 31100000 {
+			compatible = "snps,dwc3";
+			reg = <0x00 0x31100000 0x00 0x50000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+			<GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+			interrupt-names = "host", "peripheral";
+			maximum-speed = "high-speed";
+			dr_mode = "otg";
+		};
+	};
+
 	fss: bus at fc00000 {
 		compatible = "simple-bus";
 		reg = <0x00 0x0fc00000 0x00 0x70000>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
index 19f42b39394e..00dd38b02a52 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
@@ -18,6 +18,16 @@ chipid: chipid at 14 {
 			reg = <0x14 0x4>;
 			bootph-all;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	wkup_uart0: serial at 2b300000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 1773c05f752c..80be56c0a4e0 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -27,6 +27,8 @@ aliases {
 		spi0 = &ospi0;
 		ethernet0 = &cpsw_port1;
 		ethernet1 = &cpsw_port2;
+		usb0 = &usb0;
+		usb1 = &usb1;
 	};
 
 	chosen {
@@ -297,6 +299,12 @@ AM62PX_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (G20) MCASP0_ACLKR.UART1_TXD */
 		bootph-all;
 	};
 
+	main_usb1_pins_default: main-usb1-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
+		>;
+	};
+
 	main_wlirq_pins_default: main-wlirq-default-pins {
 		pinctrl-single,pins = <
 			AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
@@ -340,6 +348,36 @@ AM62PX_IOPAD(0x0124, PIN_INPUT, 7) /* (J25) MMC2_SDCD.GPIO0_71 */
 	};
 };
 
+&main_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+
+	typec_pd0: usb-power-controller at 3f {
+		compatible = "ti,tps6598x";
+		reg = <0x3f>;
+
+		connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			self-powered;
+			data-role = "dual";
+			power-role = "sink";
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port at 0 {
+					reg = <0>;
+					usb_con_hs: endpoint {
+						remote-endpoint = <&usb0_hs_ep>;
+					};
+				};
+			};
+		};
+	};
+};
+
 &main_i2c1 {
 	status = "okay";
 	pinctrl-names = "default";
@@ -460,6 +498,35 @@ cpsw3g_phy1: ethernet-phy at 1 {
 	};
 };
 
+&usbss0 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usbss1 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usb0 {
+	usb-role-switch;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port at 0 {
+		reg = <0>;
+		usb0_hs_ep: endpoint {
+			remote-endpoint = <&usb_con_hs>;
+		};
+	};
+};
+
+&usb1 {
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_usb1_pins_default>;
+};
+
 &mcasp1 {
 	status = "okay";
 	#sound-dai-cells = <0>;
-- 
2.34.1



From nm at ti.com  Mon Feb  5 06:04:59 2024
From: nm at ti.com (Nishanth Menon)
Date: Mon, 5 Feb 2024 08:04:59 -0600
Subject: [PATCH v1] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240205044557.3340848-1-u-kumar1@ti.com>
References: <20240205044557.3340848-1-u-kumar1@ti.com>
Message-ID: <20240205140459.orjvjqqtiugmyosc@obscurity>

On 10:15-20240205, Udit Kumar wrote:
> Most of clocks and their parents are defined in contiguous range,
> But in few cases, there is gap in clock numbers[0].
> 
> Driver assumes clocks to be in contiguous range, and assigns
> accordingly.
> 
> New firmware started returning error in case of
> non-available clock id.  Therefore drivers throws error while
> re-calculate and other functions.

What changed here? started returning error for what API? also please fix
up 70 char alignment -> there extra spaces in your commit message.
> 
> In this fix, before assigning and adding clock in list,
> driver checks if given clock is valid or not.
> 
> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
> 
> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> Section Clocks for NAVSS0_CPTS_0 Device,
> clock id 12-15 and 18-19 not present
> 
> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
> ---
> Original logs
> https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
> Line 2630 for error
> 
> Logs with fix
> https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-with-fix
> Line 2594 
> 
>  drivers/clk/keystone/sci-clk.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> index 35fe197dd303..d417ec018d82 100644
> --- a/drivers/clk/keystone/sci-clk.c
> +++ b/drivers/clk/keystone/sci-clk.c
> @@ -517,6 +517,8 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  	int num_clks = 0;
>  	int num_parents;
>  	int clk_id;
> +	int max_clk_id;
> +	u64 freq;
>  	const char * const clk_names[] = {
>  		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
>  	};
> @@ -584,6 +586,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  				}
>  
>  				clk_id = args.args[1] + 1;
> +				max_clk_id = clk_id + num_parents;
>  
>  				while (num_parents--) {
>  					sci_clk = devm_kzalloc(dev,
> @@ -592,11 +595,20 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  					if (!sci_clk)
>  						return -ENOMEM;
>  					sci_clk->dev_id = args.args[0];
> -					sci_clk->clk_id = clk_id++;
> -					sci_clk->provider = provider;
> -					list_add_tail(&sci_clk->node, &clks);
> +					/* check if given clock id is valid by calling get_freq */
> +					/* loop over max possible ids */
> +					do {
> +						sci_clk->clk_id = clk_id++;
>  
> -					num_clks++;
> +						ret = provider->ops->get_freq(provider->sci,
> +							   sci_clk->dev_id, sci_clk->clk_id, &freq);
> +					} while (ret != 0 && clk_id < max_clk_id);

take clock ids 0 1 2 3 -> Say 2 is reserved.
num_parents = 4
while(num_parents) Loop 1 ->  clk ID 0 is valid, list_add_tail
while(num_parents) Loop 2 ->  clk ID 1 is valid, list_add_tail
while(num_parents) Loop 3 ->  clk ID 2 is invalid.. so we scan forward
	to clk ID 3 -> list_add_tail
while(num_parents) Loop 4 ->  clk ID 4 is invalid.. but 5 is out of
	range, so we break off loop. sci_clk is still devm_kzalloced ->
	but since clk_id > max_clk_id, we jump off loop, and we dont add
	it to tail. so one extra allocation?
If we have multiple reserved intermediate ones, then we'd have as many
allocations that aren't linked? Could we not improve the logic a bit to
allocate just what is necessary?

> +
> +					sci_clk->provider = provider;
> +					if (ret == 0) {
> +						list_add_tail(&sci_clk->node, &clks);
> +						num_clks++;
> +					}
>  				}
>  			}
>  
> -- 
> 2.34.1
> 

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From vigneshr at ti.com  Mon Feb  5 06:05:20 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Mon, 5 Feb 2024 19:35:20 +0530
Subject: [PATCH 1/2] dt-bindings: mfd: syscon: Add ti,am654-serdes-ctrl
 compatible
In-Reply-To: <20240130195128.58748-1-afd@ti.com>
References: <20240130195128.58748-1-afd@ti.com>
Message-ID: <a50c5731-b328-4bf1-9449-ad15eb0f9ea6@ti.com>



On 31/01/24 01:21, Andrew Davis wrote:
> Add TI SERDES control registers compatible. This is a region found in the
> TI AM65 CTRL_MMR0 register space[0]. Each instance is used to control a
> SERDES clock and lane select mux.
> 
> [0] https://www.ti.com/lit/pdf/spruid7
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>  Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
> index 084b5c2a2a3c2..d8679a2ad4b10 100644
> --- a/Documentation/devicetree/bindings/mfd/syscon.yaml
> +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
> @@ -73,6 +73,7 @@ properties:
>                - rockchip,rv1126-qos
>                - starfive,jh7100-sysmain
>                - ti,am654-dss-oldi-io-ctrl
> +              - ti,am654-serdes-ctrl
>  
>            - const: syscon
>  

This needs to go via mfd tree (or at least need an ACK). Please cc
appropriate maintainer  (Lee Jones <lee at kernel.org>). So, I recommended
to split 2/2 out into separate series and post once this patch is merged.

-- 
Regards
Vignesh


From nfraprado at collabora.com  Mon Feb  5 06:13:51 2024
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Mon, 5 Feb 2024 09:13:51 -0500
Subject: [PATCH v3 1/4] firmware: coreboot: Generate modalias uevent for
 devices
In-Reply-To: <ZcA72dyYd9ZR8k_J@google.com>
References: <20240117-coreboot-mod-defconfig-v3-0-049565a27bba@collabora.com>
 <20240117-coreboot-mod-defconfig-v3-1-049565a27bba@collabora.com>
 <ZcA72dyYd9ZR8k_J@google.com>
Message-ID: <2a2736e5-8788-4643-8d19-a79b9a9ec776@notapiano>

On Mon, Feb 05, 2024 at 09:37:29AM +0800, Tzung-Bi Shih wrote:
> On Wed, Jan 17, 2024 at 04:03:22PM -0300, N?colas F. R. A. Prado wrote:
> > Generate a modalias uevent for devices in the coreboot bus to allow
> > userspace to automatically load the corresponding modules.
> >
> > [...]
> 
> Applied, thanks!
> 
> [1/4] firmware: coreboot: Generate modalias uevent for devices
>       commit: c6b0a4ceb7c9d8bb014d2967c97c8c7cbf60b006

Hi Tzung-Bi,

I was going to send a v4 with tag changed into 64 bit long as suggested by Greg:
https://lore.kernel.org/all/2024020105-dash-antiquity-a56b at gregkh

And that includes this commit, as the modalias field would need to be 16 hex
long.

But since you already merged this, would you prefer a change on top of this
making it 64 bit long, or do you want to keep it 32 bits?

Thanks,
N?colas


From maz at kernel.org  Mon Feb  5 06:16:07 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 05 Feb 2024 14:16:07 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event state to hypervisor
In-Reply-To: <ZcDg1sP3EYZG-i_3@linux.dev>
References: <20240104162714.1062610-1-james.clark@arm.com>
	<20240104162714.1062610-3-james.clark@arm.com>
	<Zb1mCCi13AJ_YjFZ@linux.dev>
	<8a908ee8-620a-d9c2-734b-5a6402950072@arm.com>
	<ZcDc8-FQo8wKavA4@linux.dev>
	<867cjj6ohz.wl-maz@kernel.org>
	<ZcDg1sP3EYZG-i_3@linux.dev>
Message-ID: <865xz36lp4.wl-maz@kernel.org>

On Mon, 05 Feb 2024 13:21:26 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Mon, Feb 05, 2024 at 01:15:36PM +0000, Marc Zyngier wrote:
> > On Mon, 05 Feb 2024 13:04:51 +0000,
> > Oliver Upton <oliver.upton at linux.dev> wrote:
> > > 
> > > Unless someone has strong opinions about making this work in protected
> > > mode, I am happy to see tracing support limited to the 'normal' nVHE
> > > configuration. The protected feature as a whole is just baggage until
> > > upstream support is completed.
> > 
> > Limiting tracing to non-protected mode is a must IMO. Allowing tracing
> > when pKVM is enabled is a sure way to expose secrets that should
> > stay... secret. The only exception I can think of is when
> > CONFIG_NVHE_EL2_DEBUG is enabled, at which point all bets are off.
> 
> Zero argument there :) I left off the "and PMU" part of what I was
> saying, because that was a feature that semi-worked in protected mode
> before VM/VCPU shadowing support landed.

Indeed. The goal is that as far as userspace is concerned, the host
running in protected mode shouldn't impair the ability to run
non-protected VMs, and it should all be hunky-dory, unless you
explicitly ask for a protected guest (at which point you are facing a
lot of restrictions).

PMU definitely falls into that last bucket, although I would hope that
we eventually get some support by context-switching the whole of the
PMU state. Don't worry, it's going to be cheap...

Thanks,

	M.


-- 
Without deviation from the norm, progress is not possible.


From james.clark at arm.com  Mon Feb  5 06:17:10 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 5 Feb 2024 14:17:10 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event
 state to hypervisor
In-Reply-To: <ZcDg1sP3EYZG-i_3@linux.dev>
References: <20240104162714.1062610-1-james.clark@arm.com>
 <20240104162714.1062610-3-james.clark@arm.com> <Zb1mCCi13AJ_YjFZ@linux.dev>
 <8a908ee8-620a-d9c2-734b-5a6402950072@arm.com> <ZcDc8-FQo8wKavA4@linux.dev>
 <867cjj6ohz.wl-maz@kernel.org> <ZcDg1sP3EYZG-i_3@linux.dev>
Message-ID: <a7cc7791-c476-fd81-b79d-a151293b8302@arm.com>



On 05/02/2024 13:21, Oliver Upton wrote:
> On Mon, Feb 05, 2024 at 01:15:36PM +0000, Marc Zyngier wrote:
>> On Mon, 05 Feb 2024 13:04:51 +0000,
>> Oliver Upton <oliver.upton at linux.dev> wrote:
>>>
>>> Unless someone has strong opinions about making this work in protected
>>> mode, I am happy to see tracing support limited to the 'normal' nVHE
>>> configuration. The protected feature as a whole is just baggage until
>>> upstream support is completed.
>>
>> Limiting tracing to non-protected mode is a must IMO. Allowing tracing
>> when pKVM is enabled is a sure way to expose secrets that should
>> stay... secret. The only exception I can think of is when
>> CONFIG_NVHE_EL2_DEBUG is enabled, at which point all bets are off.
> 
> Zero argument there :) I left off the "and PMU" part of what I was
> saying, because that was a feature that semi-worked in protected mode
> before VM/VCPU shadowing support landed.
> 

In that case I can hide all this behind CONFIG_NVHE_EL2_DEBUG for pKVM.
This will also have the effect of disabling PMU again for pKVM because I
moved that into this new shared area.

The same place will be used to store the state for normal nVHE and at
least then there is some code re-use and flexibility to use trace and
PMU for debugging if needed. And the copy on every switch gets deleted.


From vigneshr at ti.com  Mon Feb  5 06:22:38 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Mon, 5 Feb 2024 19:52:38 +0530
Subject: [PATCH v2 0/7] arm64: dts: iot2050: Add support for new SM
 variant
In-Reply-To: <cover.1704305544.git.jan.kiszka@siemens.com>
References: <cover.1704305544.git.jan.kiszka@siemens.com>
Message-ID: <a7ff712e-0454-4c73-89a2-a507e4d34b1a@ti.com>



On 03/01/24 23:42, Jan Kiszka wrote:
> Changes in v2:
>  - LED improvements
>  - factor out DP and USB3 dtsi files
>  - fix subject of last patch
> 
> This bring support for yet another IOT2050 device variant, see last
> patch for details. The rest is binding and refactoring to make that
> happen. Plus, LED nodes are improved by adding function and color
> properties.
> 
> This series needs to go on top of
> https://lore.kernel.org/lkml/cover.1699087938.git.jan.kiszka at siemens.com/
> 
> Jan
> 
> Baocheng Su (2):
>   arm64: dts: ti: iot2050: Disable R5 lockstep for all PG2 boards
>   arm64: dts: ti: iot2050: Support IOT2050-SM variant
> 
> Jan Kiszka (4):
>   arm64: dts: ti: iot2050: Factor out arduino connector bits
>   arm64: dts: ti: iot2050: Factor out enabling of USB3 support
>   arm64: dts: ti: iot2050: Factor out DP related bits
>   arm64: dts: ti: iot2050: Annotate LED nodes
> 
> Su Bao Cheng (1):
>   dt-bindings: arm: ti: Add binding for Siemens IOT2050 SM variant

Sorry, this doesn't apply cleanly on v6.8-rc1 or linux-next.
Please rebase.

-- 
Regards
Vignesh


From Markus.Elfring at web.de  Mon Feb  5 06:23:18 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Mon, 5 Feb 2024 15:23:18 +0100
Subject: [PATCH] pmdomain: mediatek: Use
 devm_platform_get_and_ioremap_resource() in init_scp()
Message-ID: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Mon, 5 Feb 2024 15:08:27 +0100

A wrapper function is available since the commit 890cc39a879906b63912482dfc41944579df2dc6
("drivers: provide devm_platform_get_and_ioremap_resource()").
Thus reuse existing functionality instead of keeping duplicate source code.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index b374d01fdac7..9e7f0771e7e4 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -441,8 +441,7 @@ static struct scp *init_scp(struct platform_device *pdev,

 	scp->dev = &pdev->dev;

-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	scp->base = devm_ioremap_resource(&pdev->dev, res);
+	scp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(scp->base))
 		return ERR_CAST(scp->base);

--
2.43.0



From vigneshr at ti.com  Mon Feb  5 06:35:28 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Mon, 5 Feb 2024 20:05:28 +0530
Subject: [PATCH 0/3] Add PCIe DT support for TI's J784S4 SoC
In-Reply-To: <20240129114749.1197579-1-s-vadapalli@ti.com>
References: <20240129114749.1197579-1-s-vadapalli@ti.com>
Message-ID: <ffeb1902-332c-445b-a16a-7fc293cad2eb@ti.com>



On 29/01/24 17:17, Siddharth Vadapalli wrote:
> Hello,
> 
> TI's J784S4 SoC has two Gen3 x4 Lane PCIe Controllers. This series adds
> the necessary device-tree support to enable both PCIe instances in Root
> Complex mode of operation by default. The device-tree overlay to enable
> both instances in Endpoint mode of operation is also present in this
> series.
> 
> **NOTE**
> This series depends on:
> 1. https://patchwork.kernel.org/project/linux-arm-kernel/patch/20240124122936.816142-1-s-vadapalli at ti.com/
>    for adding the Device ID in the bindings for J784S4 SoC.
> 
> 2. https://patchwork.kernel.org/project/linux-arm-kernel/patch/20240129104958.1139787-1-s-vadapalli at ti.com/
>    for enabling support for configuring the PCIe mode of operation,
>    number of lanes and link speed when the System Controller node
>    in the device-tree is modelled as a "simple-bus" which happens to
>    be the case for J784S4 SoC:
>    https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi#L45
> 
> 3. https://patchwork.kernel.org/project/linux-arm-kernel/patch/20240125100501.4137977-2-c-vankar at ti.com/
>    for fixing the "serdes_ln_ctrl" node in order to ensure that the PCIe
>    lanes are mapped correctly to the corresponding Serdes Lanes.

Sorry, too many dependencies for me to keep track of. I am ignoring  the
 series, please resubmit once dependencies are resolved.

-- 
Regards
Vignesh


From peter.griffin at linaro.org  Mon Feb  5 06:36:48 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 5 Feb 2024 14:36:48 +0000
Subject: [PATCH 2/4] arm64: dts: exynos: gs101: add chipid node
In-Reply-To: <20240201172224.574238-2-alexey.klimov@linaro.org>
References: <20240201172224.574238-1-alexey.klimov@linaro.org> <20240201172224.574238-2-alexey.klimov@linaro.org>
Message-ID: <CADrjBPpqHx1uoVZCYDX51kW+JdOr_-+4oryOjXcUMFkmLGTBLw@mail.gmail.com>

Hi Alexey & Krysztof,

On Thu, 1 Feb 2024 at 17:22, Alexey Klimov <alexey.klimov at linaro.org> wrote:
>
> Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
> ---
>  arch/arm64/boot/dts/exynos/google/gs101.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> index d838e3a7af6e..156fec2575bc 100644
> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> @@ -283,6 +283,11 @@ soc: soc at 0 {
>                 #size-cells = <1>;
>                 ranges = <0x0 0x0 0x0 0x40000000>;
>
> +               chipid at 10000000 {
> +                       compatible = "google,gs101-chipid";
> +                       reg = <0x10000000 0xd000>;
> +               };
> +

I was wondering about the 0xd000 size here, as most upstream platforms
use a chipid size of 0x100 or 0x24. I see the downstream gs101 kernel
also uses 0xd000. Looking a bit more, that is because gs-chipid.c also
has support for dumping other areas of the OTP SFR bank like asv table
(offset 0x9000) hpm_asv (offset 0xa000) and hw_tune (0xc000).

I checked Exynos850 and that also has ASV tables at those same offsets
above, but it currently uses a chipid size of 0x100 upstream.
Exynos-asv.c driver is part of exynos-chipid.c upstream so it seems
reasonable to have the increased size including those SFR registers.
Currently exynos-asv.c driver only supports Exynos5422 upstream.

@Krzysztof - From a process PoV what is the best/correct thing to do
here? Have the increased size in DT that includes ASV parts of the OTP
bank from the get-go?

Thanks,

Peter.


From mark.rutland at arm.com  Mon Feb  5 06:39:31 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 5 Feb 2024 14:39:31 +0000
Subject: Question about the ipi_raise filter usage and output
In-Reply-To: <20240205080609.563df00f@rorschach.local.home>
Message-ID: <ZcDwoce6Ok25K6Dm@FVFF77S0Q05N>

[adding Valentin]

On Mon, Feb 05, 2024 at 08:06:09AM -0500, Steven Rostedt wrote:
> On Mon, 5 Feb 2024 10:28:57 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> > > I try to write below:
> > > echo 'target_cpus == 11 && reason == "Function call interrupts"' >
> > > events/ipi/ipi_raise/filter  
> > 
> > The '=' checks if the target_cpus bitmap *only* contains CPU 11. If the cpumask
> > contains other CPUs, the filter will skip the call.
> > 
> > I believe you can use '&' to check whether a cpumask contains a CPU, e.g.
> > 
> > 	'target_cpus & 11'
> 
> 11 == 0xb = b1011
> 
> So the above would only be true for CPUs 0,1 and 3 ;-)

Sorry, I misunderstood the scalar logic and thought that we treated:

	'$mask $OP $scalar', e.g. 'target_cpus & 11'

... as a special case meaning a cpumask with that scalar bit set, i.e.

	'$mask $OP CPUS{$scalar}', e.g. 'target_cpus & CPUS{11}'

... but evidently I was wrong.

> I think you meant: 'target_cpus & 0x800' 
> 
> I tried "1 << 11' but it appears to not allow shifts. I wonder if we should add that?

Hmm... shouldn't we make 'CPUS{11}' work for that?

>From a quick test (below), that doesn't seem to work, though I think it
probably should?

  # cat /sys/devices/system/cpu/online 
  0-3
  # echo 1 > /sys/kernel/tracing/events/ipi/ipi_raise/enable 
  # echo 'target_cpus & CPUS{3}' > /sys/kernel/tracing/events/ipi/ipi_raise/filter 
  # grep IPI /proc/interrupts 
  IPI0:        54         41         32         42       Rescheduling interrupts
  IPI1:      1202       1035        893        909       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:         0          0          0          0       IRQ work interrupts
  # sleep 1
  # grep IPI /proc/interrupts 
  IPI0:        54         42         32         42       Rescheduling interrupts
  IPI1:      1209       1037        912        927       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:         0          0          0          0       IRQ work interrupts
  # cat /sys/devices/system/cpu/online 
  0-3
  # cat /sys/kernel/tracing/trace
  # tracer: nop
  #
  # entries-in-buffer/entries-written: 0/0   #P:4
  #
  #                                _-----=> irqs-off/BH-disabled
  #                               / _----=> need-resched
  #                              | / _---=> hardirq/softirq
  #                              || / _--=> preempt-depth
  #                              ||| / _-=> migrate-disable
  #                              |||| /     delay
  #           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
  #              | |         |   |||||     |         |
  # 

More confusingly, if I use '8', I get events with cpumasks which shouldn't
match AFAICT:

  echo 'target_cpus & 8' > /sys/kernel/tracing/events/ipi/ipi_raise/filter 
  # echo '' > /sys/kernel/tracing/trace
  # grep IPI /proc/interrupts 
  IPI0:        55         46         34         43       Rescheduling interrupts
  IPI1:      1358       1155        994       1021       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:         0          0          0          0       IRQ work interrupts
  # sleep 1
  # grep IPI /proc/interrupts 
  IPI0:        56         46         34         43       Rescheduling interrupts
  IPI1:      1366       1158       1005       1038       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:         0          0          0          0       IRQ work interrupts
  # cat /sys/kernel/tracing/trace
  # tracer: nop
  #
  # entries-in-buffer/entries-written: 91/91   #P:4
  #
  #                                _-----=> irqs-off/BH-disabled
  #                               / _----=> need-resched
  #                              | / _---=> hardirq/softirq
  #                              || / _--=> preempt-depth
  #                              ||| / _-=> migrate-disable
  #                              |||| /     delay
  #           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
  #              | |         |   |||||     |         |
            <idle>-0       [000] d.h4.   480.720312: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   480.720763: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
                sh-144     [003] d.h1.   480.721584: ipi_raise: target_mask=00000000,00000001 (Function call interrupts)
            <idle>-0       [000] d.h4.   481.552179: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   481.552742: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
            <idle>-0       [000] dNs4.   481.553728: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
                sh-144     [003] d.h1.   481.553742: ipi_raise: target_mask=00000000,00000002 (Function call interrupts)
            <idle>-0       [000] d.h4.   481.730502: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   481.730917: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
            <idle>-0       [000] d.h4.   481.800820: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   481.801249: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
      kworker/u8:1-37      [002] d.h2.   481.801483: ipi_raise: target_mask=00000000,00000001 (Function call interrupts)
            <idle>-0       [000] d.h4.   481.916178: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   481.916610: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
                sh-144     [003] d.h1.   481.917581: ipi_raise: target_mask=00000000,00000001 (Function call interrupts)
            <idle>-0       [000] d.h4.   482.280864: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   482.281310: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
      kworker/u8:1-37      [002] d.h2.   482.281514: ipi_raise: target_mask=00000000,00000001 (Function call interrupts)
                sh-144     [003] d.h1.   482.285681: ipi_raise: target_mask=00000000,00000001 (Function call interrupts)
                sh-144     [003] d..2.   482.287634: ipi_raise: target_mask=00000000,00000001 (Rescheduling interrupts)
                sh-144     [003] d.h1.   482.289705: ipi_raise: target_mask=00000000,00000002 (Function call interrupts)
              grep-183     [000] d.h1.   482.293649: ipi_raise: target_mask=00000000,00000002 (Function call interrupts)
              grep-183     [000] d.s3.   482.301758: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
              grep-183     [000] d.h1.   482.325713: ipi_raise: target_mask=00000000,00000002 (Function call interrupts)
              grep-183     [000] d..4.   482.349025: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
            <idle>-0       [000] d.h4.   482.701197: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   482.701856: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
            <idle>-0       [000] d.h4.   482.921567: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   482.921998: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
            <idle>-0       [000] d.h4.   483.044683: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   483.045123: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
            <idle>-0       [000] d.h4.   483.154449: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   483.154896: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
            <idle>-0       [000] d.h4.   483.296925: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)
      kworker/u8:1-37      [002] d.h2.   483.297455: ipi_raise: target_mask=00000000,00000001 (Function call interrupts)
      kworker/u8:1-37      [002] d..3.   483.297719: ipi_raise: target_mask=00000000,00000008 (Function call interrupts)
            <idle>-0       [000] d.h4.   483.602777: ipi_raise: target_mask=00000000,00000004 (Function call interrupts)

Have I completely misunderstood how this is supposed to work, or is that a bug?

Mark.


From chu.stanley at gmail.com  Mon Feb  5 06:43:53 2024
From: chu.stanley at gmail.com (Stanley Jhu)
Date: Mon, 5 Feb 2024 22:43:53 +0800
Subject: [PATCH v1 1/1] ufs: core: fix shift issue in ufshcd_clear_cmd
In-Reply-To: <20240205104905.24929-1-alice.chao@mediatek.com>
References: <20240205104905.24929-1-alice.chao@mediatek.com>
Message-ID: <CAGaU9a8EQDdrrgzuaqBYk6h-r4u6spozH3cHeHO-98dNjEv-AA@mail.gmail.com>

On Mon, Feb 5, 2024 at 7:27?PM <alice.chao at mediatek.com> wrote:
>
> From: Alice Chao <alice.chao at mediatek.com>
>
> When task_tag > 32 (in mcq mode), 1U << task_tag will out of bound
> for u32 mask. Fix this bug to prevent SHIFT_ISSUE (Bitwise shifts
> that are out of bounds for their data type).
>
> [name:debug_monitors&]Unexpected kernel BRK exception at EL1
> [name:traps&]Internal error: BRK handler: 00000000f2005514 [#1] PREEMPT SMP
> [name:mediatek_cpufreq_hw&]cpufreq stop DVFS log done
> [name:mrdump&]Kernel Offset: 0x1ba5800000 from 0xffffffc008000000
> [name:mrdump&]PHYS_OFFSET: 0x80000000
> [name:mrdump&]pstate: 22400005 (nzCv daif +PAN -UAO)
> [name:mrdump&]pc : [0xffffffdbaf52bb2c] ufshcd_clear_cmd+0x280/0x288
> [name:mrdump&]lr : [0xffffffdbaf52a774] ufshcd_wait_for_dev_cmd+0x3e4/0x82c
> [name:mrdump&]sp : ffffffc0081471b0
> <snip>
> Workqueue: ufs_eh_wq_0 ufshcd_err_handler
> Call trace:
>  dump_backtrace+0xf8/0x144
>  show_stack+0x18/0x24
>  dump_stack_lvl+0x78/0x9c
>  dump_stack+0x18/0x44
>  mrdump_common_die+0x254/0x480 [mrdump]
>  ipanic_die+0x20/0x30 [mrdump]
>  notify_die+0x15c/0x204
>  die+0x10c/0x5f8
>  arm64_notify_die+0x74/0x13c
>  do_debug_exception+0x164/0x26c
>  el1_dbg+0x64/0x80
>  el1h_64_sync_handler+0x3c/0x90
>  el1h_64_sync+0x68/0x6c
>  ufshcd_clear_cmd+0x280/0x288
>  ufshcd_wait_for_dev_cmd+0x3e4/0x82c
>  ufshcd_exec_dev_cmd+0x5bc/0x9ac
>  ufshcd_verify_dev_init+0x84/0x1c8
>  ufshcd_probe_hba+0x724/0x1ce0
>  ufshcd_host_reset_and_restore+0x260/0x574
>  ufshcd_reset_and_restore+0x138/0xbd0
>  ufshcd_err_handler+0x1218/0x2f28
>  process_one_work+0x5fc/0x1140
>  worker_thread+0x7d8/0xe20
>  kthread+0x25c/0x468
>  ret_from_fork+0x10/0x20
>
> Signed-off-by: Alice Chao <alice.chao at mediatek.com>

Reviewed-by: Stanley Jhu <chu.stanley at gmail.com>


From vigneshr at ti.com  Mon Feb  5 06:46:45 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Mon, 5 Feb 2024 20:16:45 +0530
Subject: [PATCH 3/3] arm64: dts: ti: Add DT overlay for PCIe + USB3.0
 SERDES personality card
In-Reply-To: <20240126114530.40913-4-rogerq@kernel.org>
References: <20240126114530.40913-1-rogerq@kernel.org>
 <20240126114530.40913-4-rogerq@kernel.org>
Message-ID: <547d7069-3457-4ee3-ad1c-fedc9db5da62@ti.com>



On 26/01/24 17:15, Roger Quadros wrote:
> From: Kishon Vijay Abraham I <kishon at ti.com>
> 

[...]

>  # Boards with J7200 SoC
>  k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo
> diff --git a/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso
> new file mode 100644
> index 000000000000..c63b7241c005
> --- /dev/null
> +++ b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso
> @@ -0,0 +1,67 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +/**
> + * DT overlay for SERDES personality card: 1lane PCIe + USB3.0 DRD on AM654 EVM
> + *
> + * Copyright (C) 2018-2024 Texas Instruments Incorporated - http://www.ti.com/
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/phy/phy.h>
> +#include <dt-bindings/phy/phy-am654-serdes.h>
> +
> +#include "k3-pinctrl.h"
> +
> +&serdes1 {
> +	status = "okay";
> +};
> +
> +&pcie1_rc {
> +	num-lanes = <1>;
> +	phys = <&serdes1 PHY_TYPE_PCIE 0>;
> +	phy-names = "pcie-phy0";
> +	reset-gpios = <&pca9555 5 GPIO_ACTIVE_HIGH>;
> +	status = "okay";
> +};
> +
> +&pcie1_ep {
> +	num-lanes = <1>;
> +	phys = <&serdes1 PHY_TYPE_PCIE 0>;
> +	phy-names = "pcie-phy0";
> +};
> +
> +&main_pmx0 {
> +	usb0_pins_default: usb0_pins_default {

No underscores in node-name and also should end with -pins

> +		pinctrl-single,pins = <
> +			AM65X_IOPAD(0x02bc, PIN_OUTPUT, 0) /* (AD9) USB0_DRVVBUS */
> +		>;
> +	};
> +};
> +
> +&serdes0 {
> +	status = "okay";
> +	assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
> +	assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
> +	assigned-clock-parents = <&k3_clks 151 4>,      /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
> +	<&k3_clks 151 8>;      /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */
> +	phys = <&serdes0 PHY_TYPE_USB3 0>;
> +	phy-names = "usb3-phy";
> +};
> +
> +&usb0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&usb0_pins_default>;
> +	dr_mode = "host";
> +	maximum-speed = "super-speed";
> +	snps,dis-u1-entry-quirk;
> +	snps,dis-u2-entry-quirk;
> +};
> +
> +&usb0_phy {
> +	status = "okay";
> +};


BTW, this breaks build on 6.8-rc1


  DTOVL   arch/arm64/boot/dts/ti/k3-am654-gp-evm.dtb

Failed to apply 'arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtbo': FDT_ERR_NOTFOUND


-- 
Regards
Vignesh


From nm at ti.com  Mon Feb  5 06:50:05 2024
From: nm at ti.com (Nishanth Menon)
Date: Mon, 5 Feb 2024 08:50:05 -0600
Subject: [PATCH] clk: keystone: sci-clk: match func name comment to actual
In-Reply-To: <20240115001255.4124-1-rdunlap@infradead.org>
References: <20240115001255.4124-1-rdunlap@infradead.org>
Message-ID: <20240205145005.6yauznc7qbfbrs4l@banana>

On 16:12-20240114, Randy Dunlap wrote:
> Correct the function name in the kernel-doc comment to match the
> actual function name to avoid a kernel-doc warning:
> 
> drivers/clk/keystone/sci-clk.c:287: warning: expecting prototype for _sci_clk_get(). Prototype was for _sci_clk_build() instead
> 
> Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
> Cc: Nishanth Menon <nm at ti.com>
> Cc: Tero Kristo <kristo at kernel.org>
> Cc: Santosh Shilimkar <ssantosh at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: Michael Turquette <mturquette at baylibre.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> ---

Reviewed-by: Nishanth Menon <nm at ti.com>

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From maz at kernel.org  Mon Feb  5 06:52:29 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 05 Feb 2024 14:52:29 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event state to hypervisor
In-Reply-To: <a7cc7791-c476-fd81-b79d-a151293b8302@arm.com>
References: <20240104162714.1062610-1-james.clark@arm.com>
	<20240104162714.1062610-3-james.clark@arm.com>
	<Zb1mCCi13AJ_YjFZ@linux.dev>
	<8a908ee8-620a-d9c2-734b-5a6402950072@arm.com>
	<ZcDc8-FQo8wKavA4@linux.dev>
	<867cjj6ohz.wl-maz@kernel.org>
	<ZcDg1sP3EYZG-i_3@linux.dev>
	<a7cc7791-c476-fd81-b79d-a151293b8302@arm.com>
Message-ID: <864jen6k0i.wl-maz@kernel.org>

On Mon, 05 Feb 2024 14:17:10 +0000,
James Clark <james.clark at arm.com> wrote:
>
> On 05/02/2024 13:21, Oliver Upton wrote:
> > On Mon, Feb 05, 2024 at 01:15:36PM +0000, Marc Zyngier wrote:
> >> On Mon, 05 Feb 2024 13:04:51 +0000,
> >> Oliver Upton <oliver.upton at linux.dev> wrote:
> >>>
> >>> Unless someone has strong opinions about making this work in protected
> >>> mode, I am happy to see tracing support limited to the 'normal' nVHE
> >>> configuration. The protected feature as a whole is just baggage until
> >>> upstream support is completed.
> >>
> >> Limiting tracing to non-protected mode is a must IMO. Allowing tracing
> >> when pKVM is enabled is a sure way to expose secrets that should
> >> stay... secret. The only exception I can think of is when
> >> CONFIG_NVHE_EL2_DEBUG is enabled, at which point all bets are off.
> > 
> > Zero argument there :) I left off the "and PMU" part of what I was
> > saying, because that was a feature that semi-worked in protected mode
> > before VM/VCPU shadowing support landed.
> > 
> 
> In that case I can hide all this behind CONFIG_NVHE_EL2_DEBUG for pKVM.
> This will also have the effect of disabling PMU again for pKVM because I
> moved that into this new shared area.

I'm not sure what you have in mind, but dropping PMU support for
non-protected guests when protected-mode is enabled is not an
acceptable outcome.

Hiding the trace behind a debug option is fine as this is a global
setting that has no userspace impact, but impacting guests isn't.

	M.

-- 
Without deviation from the norm, progress is not possible.


From nfraprado at collabora.com  Mon Feb  5 06:53:19 2024
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Mon, 5 Feb 2024 09:53:19 -0500
Subject: [PATCH 3/3] media: mediatek: vcodedc: Fix
 Wcast-function-type-strict warnings
In-Reply-To: <20240204205549.GA2892810@dev-fedora.aadp>
References: <20240128-fix-clang-warnings-v1-0-1d946013a421@chromium.org>
 <20240128-fix-clang-warnings-v1-3-1d946013a421@chromium.org>
 <20240201221654.GC2240065@dev-arch.thelio-3990X>
 <CABCJKudd3SUy3Qor7Tc0zyJsSAWy0PavbbBFALuWEpBa32pBCQ@mail.gmail.com>
 <5658ec37-868f-454d-a149-467e6de139cd@collabora.com>
 <12d0c580-788d-4466-af8a-feb5ab3c6677@notapiano>
 <20240204205549.GA2892810@dev-fedora.aadp>
Message-ID: <e75a0207-1f95-427c-8d72-e6a86505522e@notapiano>

On Sun, Feb 04, 2024 at 01:55:49PM -0700, Nathan Chancellor wrote:
> On Fri, Feb 02, 2024 at 03:15:46PM -0500, N?colas F. R. A. Prado wrote:
> > On Fri, Feb 02, 2024 at 01:58:05PM +0100, AngeloGioacchino Del Regno wrote:
> > > Il 01/02/24 23:25, Sami Tolvanen ha scritto:
> > > > On Thu, Feb 1, 2024 at 10:17?PM Nathan Chancellor <nathan at kernel.org> wrote:
> > > > > 
> > > > > On Sun, Jan 28, 2024 at 02:12:22AM +0000, Ricardo Ribalda wrote:
> > > > > > Building with LLVM=1 throws the following warning:
> > > > > > drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c:38:32: warning: cast from 'mtk_vcodec_ipi_handler' (aka 'void (*)(void *, unsigned int, void *)') to 'ipi_handler_t' (aka 'void (*)(const void *, unsigned int, void *)') converts to incompatible function type [-Wcast-function-type-strict]
> > > > > > 
> > > > > > Signed-off-by: Ricardo Ribalda <ribalda at chromium.org>
> > > > > 
> > > > > I am not positive because I don't have any hardware to test this driver
> > > > > but I suspect this patch is just hiding the warning without actually
> > > > > addressing the issue that it is pointing out.
> > > > 
> > > > Agreed, this won't fix the issue. The correct solution is to drop the
> > > > cast and change the handler type to match the pointer type (i.e. use
> > > > const void* for the first argument).
> > > > 
> > > 
> > > Even though I agree that the correct solution is to change the handler's type,
> > > I think that having a test on the actual hardware done is still valuable.
> > > 
> > > We scheduled a job on KernelCI to test this commit on our integration kernel,
> > > you'll get results for ChromeOS' tast decoders (MT8195 only) and Fluster tests
> > > on MT8183/8186/8192/8195.
> > > 
> > > 
> > > The results should be available in a couple of hours here, relative to
> > > commit `49955a84129dbe1f94fedf729690efcf28513828` on our tree:
> > > https://chromeos.kernelci.org/job/collabora-chromeos-kernel/branch/for-kernelci/
> > > 
> > > P.S.: If they don't, feel free to ping me or Nicolas (added to the loop) about it.
> > 
> > Hi,
> > 
> > the results are available at 
> > 
> > https://chromeos.kernelci.org/test/job/collabora-chromeos-kernel/branch/for-kernelci/kernel/v6.8-rc2-3109-g49955a84129d/
> > 
> > (You need to type "decoder" into the search bar to limit the results to only the
> > decoder tests)
> > 
> > The only regressions I see are due to infrastructure error or broken test
> > unrelated to this change (v4l2-decoder-conformance-h264-frext test on
> > MT8195-Tomato, and cros-tast-decoder-v4l2-sl-h264 test on MT8183-Juniper)
> > 
> > Otherwise, all platforms (MT8183/8186/8192/8195) and video codecs
> > (VP8/VP9/H264/H265/AV1) seem unaffected.
> > 
> > Note that these are GCC builds.
> 
> Thank you for running the tests to make sure this series does not
> regress anything. If possible, it would be good to try and build with
> LLVM and enable kernel Control Flow Integrity (kCFI, CONFIG_CFI_CLANG)
> to see if my theory that this is currently broken is correct. I have
> prebuilt LLVM toolchains on kernel.org but if it is too much of a
> hassle, I would not worry about it.

We don't have a way in KernelCI to run a one-off test, instead we need to make a
PR adding a build definition that will be triggered for every update on a given
tree. The results I reported above were for configurations that we already had
in place.

That said, maybe we should be running with LLVM and CONFIG_CFI_CLANG enabled on
a regular basis, if you think it is useful as a general tool for identifying
issues. I'd also be interested in hearing more from you on what other kind of
clang configs you think might be good to enable in CI to provide value to the
community.

Thanks,
N?colas


From nm at ti.com  Mon Feb  5 06:53:32 2024
From: nm at ti.com (Nishanth Menon)
Date: Mon, 5 Feb 2024 08:53:32 -0600
Subject: [PATCH] ARM: dts: keystone: Replace http urls with https
In-Reply-To: <20240109195612.3833281-1-nm@ti.com>
References: <20240109195612.3833281-1-nm@ti.com>
Message-ID: <170714480140.2498423.7719139696153373286.b4-ty@ti.com>

Hi Nishanth Menon,

On Tue, 09 Jan 2024 13:56:12 -0600, Nishanth Menon wrote:
> Replace http url instances with https.
> 
> 

I have applied the following to branch ti-keystone-dts-next on [1].
Thank you!

[1/1] ARM: dts: keystone: Replace http urls with https
      commit: 11621bedc016578e0b025b6f23458e9fe3f3caad

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D



From peter.griffin at linaro.org  Mon Feb  5 06:55:24 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 5 Feb 2024 14:55:24 +0000
Subject: [PATCH 3/4] soc: samsung: exynos-chipid: add Google Tensor gs101
 SoC support
In-Reply-To: <20240201172224.574238-3-alexey.klimov@linaro.org>
References: <20240201172224.574238-1-alexey.klimov@linaro.org> <20240201172224.574238-3-alexey.klimov@linaro.org>
Message-ID: <CADrjBPrEL-4DqMX-MnzTO7f3=gWnwrWrDSuXCOt0ugkhDUNV=g@mail.gmail.com>

On Thu, 1 Feb 2024 at 17:22, Alexey Klimov <alexey.klimov at linaro.org> wrote:
>
> Add GS101 information to soc_ids table and related entries to other
> places. This SoC product id is "0x09845000".
>
> Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>



>  drivers/soc/samsung/exynos-chipid.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
> index b1118d37779e..7fee6094db12 100644
> --- a/drivers/soc/samsung/exynos-chipid.c
> +++ b/drivers/soc/samsung/exynos-chipid.c
> @@ -60,6 +60,8 @@ static const struct exynos_soc_id {
>         { "EXYNOS850", 0xE3830000 },
>         { "EXYNOSAUTOV9", 0xAAA80000 },
>         { "EXYNOSAUTOV920", 0x0A920000 },
> +       /* Compatible with: google,gs101-chipid */
> +       { "GS101", 0x09845000 },
>  };
>
>  static const char *product_id_to_soc_id(unsigned int product_id)
> @@ -178,8 +180,17 @@ static const struct exynos_chipid_variant exynos850_chipid_drv_data = {
>         .sub_rev_shift  = 16,
>  };
>
> +static const struct exynos_chipid_variant gs101_chipid_drv_data = {
> +       .rev_reg        = 0x10,
> +       .main_rev_shift = 0,
> +       .sub_rev_shift  = 16,
> +};
> +
>  static const struct of_device_id exynos_chipid_of_device_ids[] = {
>         {
> +               .compatible     = "google,gs101-chipid",
> +               .data           = &gs101_chipid_drv_data,
> +       }, {
>                 .compatible     = "samsung,exynos4210-chipid",
>                 .data           = &exynos4210_chipid_drv_data,
>         }, {
> --
> 2.43.0
>


From nm at ti.com  Mon Feb  5 06:56:18 2024
From: nm at ti.com (Nishanth Menon)
Date: Mon, 5 Feb 2024 08:56:18 -0600
Subject: [PATCH v2] ARM: multi_v7_defconfig: Add more TI Keystone support
In-Reply-To: <20240125163145.87055-1-afd@ti.com>
References: <20240125163145.87055-1-afd@ti.com>
Message-ID: <170714487232.2498590.16765370636323778041.b4-ty@ti.com>

Hi Andrew Davis,

On Thu, 25 Jan 2024 10:31:45 -0600, Andrew Davis wrote:
> The Keystone platforms used their own keystone_defconfig mostly to
> enable CONFIG_ARM_LPAE which could not be added to the multi_v7 config.
> Now that we have multi_v7_lpae_defconfig/lpae.config target we can and
> should use that defconfig for Keystone. Add the remaining must-have
> options for Keystone support to multi_v7_defconfig.
> 
> TI_SCI_*:
> TI_MESSAGE_MANAGER:
>  Allows TI-SCI communication with system control firmware (PMMC) on K2G.
> 
> [...]

I have applied the following to branch ti-k3-config-next (branch name
is a bit confusing, but since changes are very infrequent, I didn't
want to spin off another branch) on [1].

Thank you!

[1/1] ARM: multi_v7_defconfig: Add more TI Keystone support
      commit: 69cd52b92782a466b18ea66a1f8b5f9f956e1648

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D



From peter.griffin at linaro.org  Mon Feb  5 07:14:55 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 5 Feb 2024 15:14:55 +0000
Subject: [PATCH 4/4] soc: samsung: exynos-chipid: fix revision calculation
 for gs101
In-Reply-To: <20240201172224.574238-4-alexey.klimov@linaro.org>
References: <20240201172224.574238-1-alexey.klimov@linaro.org> <20240201172224.574238-4-alexey.klimov@linaro.org>
Message-ID: <CADrjBPpWXHhRhid77=utZuaQVzw8aaXUV_EKwwn0=rp7-Jt+NQ@mail.gmail.com>

Hi Alexey,

On Thu, 1 Feb 2024 at 17:22, Alexey Klimov <alexey.klimov at linaro.org> wrote:
>
> The main revision for gs101 SoC is not reported in the CHIPID_REV
> register. The gs101 Product ID and revisions registers have a behaviour
> split between old Exynos SoCs and new SoCs. The sub-revision is
> reported in CHIPID_REV register in [19:16] bits but main revision
> is still present in Product ID [7:0].
>
> To construct soc_info->revision correctly for gs101 the main_rev
> should not be reset from a value read from CHIPID_REV.
>

I think it would also be worth adding in the commit message how the
main_rev and sub_rev relate to the a0, b0, b1 reported by the
bootloader.

> Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
> ---
>  drivers/soc/samsung/exynos-chipid.c       | 20 ++++++++++++++++----
>  include/linux/soc/samsung/exynos-chipid.h |  1 +
>  2 files changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
> index 7fee6094db12..3b952ffd8cf7 100644
> --- a/drivers/soc/samsung/exynos-chipid.c
> +++ b/drivers/soc/samsung/exynos-chipid.c
> @@ -87,14 +87,26 @@ static int exynos_chipid_get_chipid_info(struct regmap *regmap,
>         soc_info->product_id = val & EXYNOS_MASK;
>
>         if (data->rev_reg != EXYNOS_CHIPID_REG_PRO_ID) {
> -               ret = regmap_read(regmap, data->rev_reg, &val);
> +               unsigned int val2;
> +
> +               ret = regmap_read(regmap, data->rev_reg, &val2);
>                 if (ret < 0)
>                         return ret;
> +
> +               if (data->main_rev_shift == 0)
> +                       main_rev = (val >> data->main_rev_shift)
> +                                  & EXYNOS_REV_PART_MASK_GS101;

Looks like it can be simplified to
main_rev = val & EXYNOS_REV_PART_MASK_GS101;

Peter


From Dave.Martin at arm.com  Mon Feb  5 07:19:47 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Mon, 5 Feb 2024 15:19:47 +0000
Subject: [PATCH] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <CAMj1kXGN-nKSzxJoyM9peBTDevuPkH-+P2UzH746P-F913Dg-g@mail.gmail.com>
References: <20240201223545.728028-1-maskray@google.com>
 <Zb0Qu5lR0iZUqImb@e133380.arm.com>
 <CAMj1kXGSQ4Xq68Cmq6BH37FPJ+R+N5cOfrdC+aVML4sGaNDopg@mail.gmail.com>
 <Zb0eRogn3rjkeDAs@e133380.arm.com>
 <20240202225104.f4dsagfwf6gcnddy@google.com>
 <CAMj1kXGN-nKSzxJoyM9peBTDevuPkH-+P2UzH746P-F913Dg-g@mail.gmail.com>
Message-ID: <ZcD8k2UTs3wyk9Dx@e133380.arm.com>

On Sat, Feb 03, 2024 at 10:50:44AM +0100, Ard Biesheuvel wrote:
> On Fri, 2 Feb 2024 at 23:51, Fangrui Song <maskray at google.com> wrote:

[...]

> > "Si" is fine for GCC and Clang.
> > "i" is fine for Clang but not for GCC PIC.
> >
> >      https://maskray.me/blog/2024-01-30-raw-symbol-names-in-inline-assembly#aarch64
> >
> >      In gcc/config/aarch64, LEGITIMATE_PIC_OPERAND_P(X) disallows any symbol
> >      reference, which means that "i" and "s" cannot be used for PIC. Instead,
> >      the constraint "S" has been supported since the initial port (2012) to
> >      reference a symbol or label.
> >
> > I am also not familiar with
> > https://gcc.gnu.org/onlinedocs/gcc/Multi-Alternative.html (comma in a
> > constraint string). Thankfully we don't need this powerful construct:)

Ack, I had thought that this was relevant, but it is not,
and "Si" seems right.

[...]

> > I am convinced by Ard' argument that two inputs (key, branch) deserve
> > two operands.
> > The existing "i"(&((char *)key)[branch]) is kinda ugly and also longer:)
> 
> If it helps clarify things, we might do something like
> 
> ".quad  (%[key]  - .) + %[bit0]"
> 
> : : [key]"Si"(key), [bit0]"i"(branch) :  : l_yes);

I don't have a strong opinion on the naming, but something like this
seems fine.

Cheers
---Dave


From frank at oltmanns.dev  Mon Feb  5 07:22:23 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 05 Feb 2024 16:22:23 +0100
Subject: [PATCH v2 0/6] Pinephone video out fixes (flipping between two
 frames)
Message-ID: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>

On some pinephones the video output sometimes freezes (flips between two
frames) [1]. It seems to be that the reason for this behaviour is that
PLL-MIPI, PLL-GPU and GPU are operating outside their limits.

In this patch series I propose the followin changes:
  1. sunxi-ng: Adhere to the following constraints given in the
     Allwinner A64 Manual regarding PLL-MIPI:
      * M/N <= 3
      * (PLL_VIDEO0)/M >= 24MHz
      * 500MHz <= clockrate <= 1400MHz

  2. Choose a higher clock rate for the ST7703 based XDB599 panel, so
     that the panel function well with the Allwinner A64 SOC. PLL-MIPI
     must run between 500 MHz and 1.4 GHz. As PLL-MIPI runs at 6 times
     the panel's clock rate, we need the panel's clock to be at least
     83.333 MHz.

  3. Increase the minimum frequency in the A64 DTS OPPs from 120 MHz to
     192 MHz. This further reduces the issue.

Unfortunately, with these patches the issue [1] is not completely gone,
but becomes less likely.

Note, that when pinning the GPU to 432 MHz the issue completely
disappears for me. I've searched the BSP and could not find any
indication that supports the idea of having the three OPPs. The only
frequency I found in the BPSs for A64 is 432 MHz, that has also proven
stable for me. So, while increasing the minimum frequency to 192 MHz
reduces the issue, should we maybe instead set the GPU to a fixed 432
MHz instead?

I very much appreciate your feedback!

[1] https://gitlab.com/postmarketOS/pmaports/-/issues/805

Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
---
Changes in v2:
- dts: Increase minimum GPU frequency to 192 MHz.
- nkm and a64: Add minimum and maximum rate for PLL-MIPI.
- nkm: Use the same approach for skipping invalid rates in
  ccu_nkm_find_best() as in ccu_nkm_find_best_with_parent_adj().
- nkm: Improve names for ratio struct members and hence get rid of
  describing comments.
- nkm and a64: Correct description in the commit messages: M/N <= 3
- Remove patches for nm as they were not needed.
- st7703: Rework the commit message to cover more background for the
  change.
- Link to v1: https://lore.kernel.org/r/20231218-pinephone-pll-fixes-v1-0-e238b6ed6dc1 at oltmanns.dev

---
Frank Oltmanns (6):
      clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate
      clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate
      clk: sunxi-ng: nkm: Support minimum and maximum rate
      clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
      drm/panel: st7703: Drive XBD599 panel at higher clock rate
      arm64: dts: allwinner: a64: Fix minimum GPU OPP rate

 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  4 ++--
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c         | 14 +++++++----
 drivers/clk/sunxi-ng/ccu_nkm.c                | 34 +++++++++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu_nkm.h                |  4 ++++
 drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++++------
 5 files changed, 56 insertions(+), 14 deletions(-)
---
base-commit: 059c53e877ca6e723e10490c27c1487a63e66efe
change-id: 20231218-pinephone-pll-fixes-0ccdfde273e4

Best regards,
-- 
Frank Oltmanns <frank at oltmanns.dev>



From frank at oltmanns.dev  Mon Feb  5 07:22:24 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 05 Feb 2024 16:22:24 +0100
Subject: [PATCH v2 1/6] clk: sunxi-ng: nkm: Support constraints on m/n
 ratio and parent rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
Message-ID: <20240205-pinephone-pll-fixes-v2-1-96a46a2d8c9b@oltmanns.dev>

The Allwinner A64 manual lists the following constraints for the
PLL-MIPI clock:
 - M/N <= 3
 - (PLL_VIDEO0)/M >= 24MHz

The PLL-MIPI clock is implemented as ccu_nkm. Therefore, add support for
these constraints.

Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
---
 drivers/clk/sunxi-ng/ccu_nkm.c | 21 +++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
 2 files changed, 23 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index 853f84398e2b..1168d894d636 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -16,6 +16,20 @@ struct _ccu_nkm {
 	unsigned long	m, min_m, max_m;
 };
 
+static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned long parent,
+				  unsigned long n, unsigned long m)
+{
+	struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common);
+
+	if (nkm->max_m_n_ratio && (m > nkm->max_m_n_ratio * n))
+		return false;
+
+	if (nkm->min_parent_m_ratio && (parent < nkm->min_parent_m_ratio * m))
+		return false;
+
+	return true;
+}
+
 static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common,
 						       struct clk_hw *parent_hw,
 						       unsigned long *parent, unsigned long rate,
@@ -31,6 +45,10 @@ static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common
 				unsigned long tmp_rate, tmp_parent;
 
 				tmp_parent = clk_hw_round_rate(parent_hw, rate * _m / (_n * _k));
+
+				if (!ccu_nkm_is_valid_rate(common, tmp_parent, _n, _m))
+					continue;
+
 				tmp_rate = tmp_parent * _n * _k / _m;
 
 				if (ccu_is_better_rate(common, rate, tmp_rate, best_rate) ||
@@ -64,6 +82,9 @@ static unsigned long ccu_nkm_find_best(unsigned long parent, unsigned long rate,
 	for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
 		for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
 			for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
+				if (!ccu_nkm_is_valid_rate(common, parent, _n, _m))
+					continue;
+
 				unsigned long tmp_rate;
 
 				tmp_rate = parent * _n * _k / _m;
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
index 6601defb3f38..c409212ee40e 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.h
+++ b/drivers/clk/sunxi-ng/ccu_nkm.h
@@ -27,6 +27,8 @@ struct ccu_nkm {
 	struct ccu_mux_internal	mux;
 
 	unsigned int		fixed_post_div;
+	unsigned long		max_m_n_ratio;
+	unsigned long		min_parent_m_ratio;
 
 	struct ccu_common	common;
 };

-- 
2.43.0



From frank at oltmanns.dev  Mon Feb  5 07:22:25 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 05 Feb 2024 16:22:25 +0100
Subject: [PATCH v2 2/6] clk: sunxi-ng: a64: Add constraints on PLL-MIPI's
 n/m ratio and parent rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
Message-ID: <20240205-pinephone-pll-fixes-v2-2-96a46a2d8c9b@oltmanns.dev>

The Allwinner A64 manual lists the following constraints for the
PLL-MIPI clock:
 - M/N <= 3
 - (PLL_VIDEO0)/M >= 24MHz

Use these constraints.

Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 8951ffc14ff5..df679dada792 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -171,11 +171,13 @@ static struct ccu_nkm pll_mipi_clk = {
 	 * user manual, and by experiments the PLL doesn't work without
 	 * these bits toggled.
 	 */
-	.enable		= BIT(31) | BIT(23) | BIT(22),
-	.lock		= BIT(28),
-	.n		= _SUNXI_CCU_MULT(8, 4),
-	.k		= _SUNXI_CCU_MULT_MIN(4, 2, 2),
-	.m		= _SUNXI_CCU_DIV(0, 4),
+	.enable			= BIT(31) | BIT(23) | BIT(22),
+	.lock			= BIT(28),
+	.n			= _SUNXI_CCU_MULT(8, 4),
+	.k			= _SUNXI_CCU_MULT_MIN(4, 2, 2),
+	.m			= _SUNXI_CCU_DIV(0, 4),
+	.max_m_n_ratio		= 3,
+	.min_parent_m_ratio	= 24000000,
 	.common		= {
 		.reg		= 0x040,
 		.hw.init	= CLK_HW_INIT("pll-mipi", "pll-video0",

-- 
2.43.0



From frank at oltmanns.dev  Mon Feb  5 07:22:26 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 05 Feb 2024 16:22:26 +0100
Subject: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum
 rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
Message-ID: <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>

According to the Allwinner User Manual, the Allwinner A64 requires
PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.

Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
---
 drivers/clk/sunxi-ng/ccu_nkm.c | 13 +++++++++++++
 drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index 1168d894d636..7d135908d6e0 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -181,6 +181,12 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
 	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
 		rate *= nkm->fixed_post_div;
 
+	if (nkm->min_rate && rate < nkm->min_rate)
+		rate = nkm->min_rate;
+
+	if (nkm->max_rate && rate > nkm->max_rate)
+		rate = nkm->max_rate;
+
 	if (!clk_hw_can_set_rate_parent(&nkm->common.hw))
 		rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm->common);
 	else
@@ -220,6 +226,13 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
 	_nkm.min_m = 1;
 	_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
 
+
+	if (nkm->min_rate && rate < nkm->min_rate)
+		rate = nkm->min_rate;
+
+	if (nkm->max_rate && rate > nkm->max_rate)
+		rate = nkm->max_rate;
+
 	ccu_nkm_find_best(parent_rate, rate, &_nkm, &nkm->common);
 
 	spin_lock_irqsave(nkm->common.lock, flags);
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
index c409212ee40e..358a9df6b6a0 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.h
+++ b/drivers/clk/sunxi-ng/ccu_nkm.h
@@ -27,6 +27,8 @@ struct ccu_nkm {
 	struct ccu_mux_internal	mux;
 
 	unsigned int		fixed_post_div;
+	unsigned long		min_rate;
+	unsigned long		max_rate;
 	unsigned long		max_m_n_ratio;
 	unsigned long		min_parent_m_ratio;
 

-- 
2.43.0



From frank at oltmanns.dev  Mon Feb  5 07:22:27 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 05 Feb 2024 16:22:27 +0100
Subject: [PATCH v2 4/6] clk: sunxi-ng: a64: Set minimum and maximum rate
 for PLL-MIPI
In-Reply-To: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
Message-ID: <20240205-pinephone-pll-fixes-v2-4-96a46a2d8c9b@oltmanns.dev>

Set the minimum and maximum rate of Allwinner A64's PLL-MIPI according
to the Allwinner User Manual.

Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index df679dada792..99c2ce11da74 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -178,6 +178,8 @@ static struct ccu_nkm pll_mipi_clk = {
 	.m			= _SUNXI_CCU_DIV(0, 4),
 	.max_m_n_ratio		= 3,
 	.min_parent_m_ratio	= 24000000,
+	.min_rate		= 500000000,
+	.max_rate		= 1400000000,
 	.common		= {
 		.reg		= 0x040,
 		.hw.init	= CLK_HW_INIT("pll-mipi", "pll-video0",

-- 
2.43.0



From frank at oltmanns.dev  Mon Feb  5 07:22:28 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 05 Feb 2024 16:22:28 +0100
Subject: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher
 clock rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
Message-ID: <20240205-pinephone-pll-fixes-v2-5-96a46a2d8c9b@oltmanns.dev>

This panel is used in the pinephone that runs on a Allwinner A64 SOC.
The SOC requires pll-mipi to run at more than 500 MHz.

This is the relevant clock tree:
 pll-mipi
    tcon0
       tcon-data-clock

tcon-data-clock has to run at 1/4 the DSI per-lane bit rate. The XBD599
has 24 bpp and 4 lanes. Therefore, the resulting requested
tcon-data-clock rate is:
    crtc_clock * 1000 * (24 / 4) / 4

tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it requests a
parent rate of
    4 * (crtc_clock * 1000 * (24 / 4) / 4)

Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate of pll-mipi.

pll-mipi's constraint to run at 500MHz or higher forces us to have a
crtc_clock >= 83333 kHz if we want a 60 Hz vertical refresh rate.

Change [hv]sync_(start|end) so that we reach a clock rate of 83502 kHz
so that it is high enough to align with pll-pipi limits.

Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
---
 drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
index b55bafd1a8be..6886fd7f765e 100644
--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
+++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
@@ -320,14 +320,14 @@ static int xbd599_init_sequence(struct st7703 *ctx)
 
 static const struct drm_display_mode xbd599_mode = {
 	.hdisplay    = 720,
-	.hsync_start = 720 + 40,
-	.hsync_end   = 720 + 40 + 40,
-	.htotal	     = 720 + 40 + 40 + 40,
+	.hsync_start = 720 + 65,
+	.hsync_end   = 720 + 65 + 65,
+	.htotal      = 720 + 65 + 65 + 65,
 	.vdisplay    = 1440,
-	.vsync_start = 1440 + 18,
-	.vsync_end   = 1440 + 18 + 10,
-	.vtotal	     = 1440 + 18 + 10 + 17,
-	.clock	     = 69000,
+	.vsync_start = 1440 + 30,
+	.vsync_end   = 1440 + 30 + 22,
+	.vtotal	     = 1440 + 30 + 22 + 29,
+	.clock	     = (720 + 65 + 65 + 65) * (1440 + 30 + 22 + 29) * 60 / 1000,
 	.flags	     = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
 	.width_mm    = 68,
 	.height_mm   = 136,

-- 
2.43.0



From frank at oltmanns.dev  Mon Feb  5 07:22:29 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 05 Feb 2024 16:22:29 +0100
Subject: [PATCH v2 6/6] arm64: dts: allwinner: a64: Fix minimum GPU OPP
 rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
Message-ID: <20240205-pinephone-pll-fixes-v2-6-96a46a2d8c9b@oltmanns.dev>

The PLL-GPU has a minimum rate of 192 MHz according to the A64 manual.

If run at less than 192 MHz the pinephone (based on the A64) sometimes
replays the last few frames that were displayed over and over (see first
link below).

Note, that running PLL-GPU at 240 MHz and using a divisor of 2 *should*
circumvent this problem as well. But unfortunately, the GPU shows the
erratic behaviour even more often, even though its parent is driven at a
supported range. This might be due to a similar issue to the one
observed on the Allwinner H6 (see second link).

Running both the GPU and PLL-GPU at more then 192 MHz reduces the
occurrenc of the issue.

Therefore, increase the minimum rate in the GPU OPP table to 192 MHz.

Link: https://gitlab.com/postmarketOS/pmaports/-/issues/805
Link: https://lore.kernel.org/linux-arm-kernel/2562485.k3LOHGUjKi at kista/T/
Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 57ac18738c99..448d7fbdd1a9 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -107,8 +107,8 @@ de: display-engine {
 	gpu_opp_table: opp-table-gpu {
 		compatible = "operating-points-v2";
 
-		opp-120000000 {
-			opp-hz = /bits/ 64 <120000000>;
+		opp-192000000 {
+			opp-hz = /bits/ 64 <192000000>;
 		};
 
 		opp-312000000 {

-- 
2.43.0



From peter.griffin at linaro.org  Mon Feb  5 07:24:51 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 5 Feb 2024 15:24:51 +0000
Subject: [PATCH v4 01/16] spi: s3c64xx: explicitly include <linux/io.h>
In-Reply-To: <20240205124513.447875-2-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org> <20240205124513.447875-2-tudor.ambarus@linaro.org>
Message-ID: <CADrjBPpZzdO8VtPexWJOjHh_t+4CwSF=tcn+sC-i6eLcrxYhfQ@mail.gmail.com>

On Mon, 5 Feb 2024 at 12:45, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> The driver uses readl() but does not include <linux/io.h>.
>
> It is good practice to directly include all headers used, it avoids
> implicit dependencies and spurious breakage if someone rearranges
> headers and causes the implicit include to vanish.
>
> Include the missing header.
>
> Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver")
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>


From peter.griffin at linaro.org  Mon Feb  5 07:25:14 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 5 Feb 2024 15:25:14 +0000
Subject: [PATCH v4 02/16] spi: s3c64xx: explicitly include <linux/bits.h>
In-Reply-To: <20240205124513.447875-3-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org> <20240205124513.447875-3-tudor.ambarus@linaro.org>
Message-ID: <CADrjBPoBTAQdKTyBUkM7rLMZUY-YEc9P20HbSwNNrkYao2V+-g@mail.gmail.com>

On Mon, 5 Feb 2024 at 12:45, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> The driver uses GENMASK() but does not include <linux/bits.h>.
>
> It is good practice to directly include all headers used, it avoids
> implicit dependencies and spurious breakage if someone rearranges
> headers and causes the implicit include to vanish.
>
> Include the missing header.
>
> Fixes: 1224e29572f6 ("spi: s3c64xx: Fix large transfers with DMA")
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>


From angelogioacchino.delregno at collabora.com  Mon Feb  5 07:26:36 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 5 Feb 2024 16:26:36 +0100
Subject: [PATCH 2/2] phy: add driver for MediaTek XFI T-PHY
In-Reply-To: <Zb0ZTNnAa_x47En1@makrotopia.org>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
 <dd6b40ea1f7f8459a9a2cfe7fa60c1108332ade6.1706823233.git.daniel@makrotopia.org>
 <3e9afc4b-4ad6-412b-bc4d-f3e3b1475657@collabora.com>
 <Zb0ZTNnAa_x47En1@makrotopia.org>
Message-ID: <d1eb440e-53e4-41f4-8d5b-bc86f9aff32a@collabora.com>

Il 02/02/24 17:33, Daniel Golle ha scritto:
> Hi Angelo,
> 
> thank you for promptly reviewing my submission and providing valuable
> feedback!
> 
> On Fri, Feb 02, 2024 at 02:21:48PM +0100, AngeloGioacchino Del Regno wrote:
>> Il 01/02/24 22:53, Daniel Golle ha scritto:
>>> Add driver for MediaTek's XFI T-PHY, 10 Gigabit/s Ethernet SerDes PHY
>>> which can be found in the MT7988 SoC.
>>>
>>> The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
>>> PHY_INTERFACE_MODE_* corresponding to the supported modes:
>>>
>>>    * USXGMII                 \
>>>    * 10GBase-R                }- USXGMII PCS - XGDM  \
>>>    * 5GBase-R                /                        \
>>>                                                        }- Ethernet MAC
>>>    * 2500Base-X              \                        /
>>>    * 1000Base-X               }- LynxI PCS - GDM     /
>>>    * Cisco SGMII (MAC side)  /
>>>
>>> In order to work-around a performance issue present on the first of
>>> two XFI T-PHYs present in MT7988, special tuning is applied which can be
>>> selected by adding the 'mediatek,usxgmii-performance-errata' property to
>>> the device tree node.
>>>
>>> There is no documentation for most registers used for the
>>> analog/tuning part, however, most of the registers have been partially
>>> reverse-engineered from MediaTek's SDK implementation (an opaque
>>> sequence of 32-bit register writes) and descriptions for all relevant
>>> digital registers and bits such as resets and muxes have been supplied
>>> by MediaTek.
>>>
>>> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
>>> ---
>>>    MAINTAINERS                             |   1 +
>>>    drivers/phy/mediatek/Kconfig            |  12 +
>>>    drivers/phy/mediatek/Makefile           |   1 +
>>>    drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 392 ++++++++++++++++++++++++
>>>    4 files changed, 406 insertions(+)
>>>    create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 52769631bdb1a..52e4192470bd9 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -13715,6 +13715,7 @@ L:	netdev at vger.kernel.org
>>>    S:	Maintained
>>>    F:	drivers/net/phy/mediatek-ge-soc.c
>>>    F:	drivers/net/phy/mediatek-ge.c
>>> +F:	drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>>>    MEDIATEK I2C CONTROLLER DRIVER
>>>    M:	Qii Wang <qii.wang at mediatek.com>
>>> diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
>>> index 3125ecb5d119f..5161d130c7f8b 100644
>>> --- a/drivers/phy/mediatek/Kconfig
>>> +++ b/drivers/phy/mediatek/Kconfig
>>> @@ -13,6 +13,18 @@ config PHY_MTK_PCIE
>>>    	  callback for PCIe GEN3 port, it supports software efuse
>>>    	  initialization.
>>> +config PHY_MTK_XFI_TPHY
>>> +	tristate "MediaTek XFI T-PHY Driver"
>>> +	depends on ARCH_MEDIATEK || COMPILE_TEST
>>> +	depends on OF && OF_ADDRESS
>>> +	depends on HAS_IOMEM
>>> +	select GENERIC_PHY
>>> +	help
>>> +	  Say 'Y' here to add support for MediaTek XFI T-PHY driver.
>>> +	  The driver provides access to the Ethernet SerDes T-PHY supporting
>>> +	  1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
>>> +	  via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
>>> +
>>>    config PHY_MTK_TPHY
>>>    	tristate "MediaTek T-PHY Driver"
>>>    	depends on ARCH_MEDIATEK || COMPILE_TEST
>>> diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
>>> index c9a50395533eb..fa7217178e7f4 100644
>>> --- a/drivers/phy/mediatek/Makefile
>>> +++ b/drivers/phy/mediatek/Makefile
>>> @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
>>>    obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
>>>    obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
>>>    obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
>>> +obj-$(CONFIG_PHY_MTK_XFI_TPHY)		+= phy-mtk-xfi-tphy.o
>>>    phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
>>>    phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
>>> diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>>> new file mode 100644
>>> index 0000000000000..d50e6320860e5
>>> --- /dev/null
>>> +++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>>> @@ -0,0 +1,392 @@
>>> +// SPDX-License-Identifier: GPL-2.0-or-later
>>> +/* MediaTek 10GE SerDes PHY driver
>>
>> MediaTek 10GE SerDes XFI T-PHY driver ?
> 
> Ack. Will unify the name accross all files.
> 
>>
>>> + *
>>> + * Copyright (c) 2024 Daniel Golle <daniel at makrotopia.org>
>>> + *                    Bc-bocun Chen <bc-bocun.chen at mediatek.com>
>>> + * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
>>> + * Copyright (c) 2022 MediaTek Inc.
>>> + * Author: Henry Yen <henry.yen at mediatek.com>
>>> + */
>>> +
>>> +#include <linux/module.h>
>>> +#include <linux/device.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/of.h>
>>> +#include <linux/io.h>
>>> +#include <linux/clk.h>
>>> +#include <linux/reset.h>
>>> +#include <linux/phy.h>
>>> +#include <linux/phy/phy.h>
>>> +
>>> +#define MTK_XFI_TPHY_NUM_CLOCKS		2
>>> +
>>> +#define REG_DIG_GLB_70			0x0070
>>> +#define  XTP_PCS_RX_EQ_IN_PROGRESS(x)	FIELD_PREP(GENMASK(25, 24), (x))
>>> +#define  XTP_PCS_MODE_MASK		GENMASK(17, 16)
>>> +#define  XTP_PCS_MODE(x)		FIELD_PREP(GENMASK(17, 16), (x))
>>> +#define  XTP_PCS_RST_B			BIT(15)
>>> +#define  XTP_FRC_PCS_RST_B		BIT(14)
>>> +#define  XTP_PCS_PWD_SYNC_MASK		GENMASK(13, 12)
>>> +#define  XTP_PCS_PWD_SYNC(x)		FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
>>> +#define  XTP_PCS_PWD_ASYNC_MASK		GENMASK(11, 10)
>>> +#define  XTP_PCS_PWD_ASYNC(x)		FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
>>> +#define  XTP_FRC_PCS_PWD_ASYNC		BIT(8)
>>> +#define  XTP_PCS_UPDT			BIT(4)
>>> +#define  XTP_PCS_IN_FR_RG		BIT(0)
>>> +
>>> +#define REG_DIG_GLB_F4			0x00f4
>>> +#define  XFI_DPHY_PCS_SEL		BIT(0)
>>> +#define   XFI_DPHY_PCS_SEL_SGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 1)
>>> +#define   XFI_DPHY_PCS_SEL_USXGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 0)
>>> +#define  XFI_DPHY_AD_SGDT_FRC_EN	BIT(5)
>>> +
>>> +#define REG_DIG_LN_TRX_40		0x3040
>>> +#define  XTP_LN_FRC_TX_DATA_EN		BIT(29)
>>> +#define  XTP_LN_TX_DATA_EN		BIT(28)
>>> +
>>> +#define REG_DIG_LN_TRX_B0		0x30b0
>>> +#define  XTP_LN_FRC_TX_MACCK_EN		BIT(5)
>>> +#define  XTP_LN_TX_MACCK_EN		BIT(4)
>>> +
>>> +#define REG_ANA_GLB_D0			0x90d0
>>> +#define  XTP_GLB_USXGMII_SEL_MASK	GENMASK(3, 1)
>>> +#define  XTP_GLB_USXGMII_SEL(x)		FIELD_PREP(GENMASK(3, 1), (x))
>>> +#define  XTP_GLB_USXGMII_EN		BIT(0)
>>> +
>>> +struct mtk_xfi_tphy {
>>> +	void __iomem		*base;
>>> +	struct device		*dev;
>>> +	struct reset_control	*reset;
>>> +	struct clk_bulk_data	clocks[MTK_XFI_TPHY_NUM_CLOCKS];
>>> +	bool			da_war;
>>> +};
>>> +
>>> +static void mtk_xfi_tphy_write(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
>>> +			       u32 value)
>>> +{
>>> +	iowrite32(value, xfi_tphy->base + reg);
>>> +}
>>> +
>>> +static void mtk_xfi_tphy_rmw(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
>>> +			     u32 clr, u32 set)
>>> +{
>>> +	u32 val;
>>> +
>>> +	val = ioread32(xfi_tphy->base + reg);
>>> +	val &= ~clr;
>>> +	val |= set;
>>> +	iowrite32(val, xfi_tphy->base + reg);
>>> +}
>>> +
>>> +static void mtk_xfi_tphy_set(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
>>> +			     u32 set)
>>> +{
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, reg, 0, set);
>>> +}
>>> +
>>> +static void mtk_xfi_tphy_clear(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
>>> +			       u32 clr)
>>> +{
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, reg, clr, 0);
>>> +}
>>> +
>>> +static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
>>> +			       phy_interface_t interface)
>>> +{
>>> +	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
>>> +	bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
>>> +		      interface == PHY_INTERFACE_MODE_SGMII);
>>> +	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
>>> +		       interface == PHY_INTERFACE_MODE_USXGMII);
>>> +	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
>>> +	bool is_xgmii = (is_10g || is_5g);
>>
>> is_usxgmii, I'd say.
> 
> This boolean is mostly used to destinguish which path to use at the
> T-junction of the PHY, ie. up to 2500Base-X goes to LynxI PCS while
> 5GBase-R, 10GBase-R and USXGMII go to USXGMII PCS (which handles all
> three modes and not just USXGMII).
> 
> Calling the boolean 'is_usxgmii' is a bit confusing as it not only
> means (interface == interface == PHY_INTERFACE_MODE_USXGMII) but
> rather also covers (interface == PHY_INTERFACE_MODE_10GBASER) as well
> as (interface == PHY_INTERFACE_MODE_5GBASER) which are not USXGMII.
> 
> Maybe we invert it and call it 'use_lynxi_pcs' instead?
> 

Since you were able to provide such a good explanation of that, I wonder why
you didn't add that as a comment in the code?

That way, there will be no confusion for sure, even if you keep "is_xgmii" :-)

>>
>>> +
>>> +	dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));
>>> +
>>> +	/* Setup PLL setting */
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2030, 0x500, is_1g ? 0x0 : 0x500);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x2040, 0x340000, is_1g ? 0x200000 :
>>> +							     0x140000);
>>> +
>>> +	/* Setup RXFE BW setting */
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50f0, 0xc10, is_1g ? 0x410 :
>>> +							  is_5g ? 0x800 : 0x400);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
>>> +
>>> +	/* Setup RX CDR setting */
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5078, 0xf000400, is_5g ? 0x8000000 :
>>> +							      0x7000400);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x507c, 0x5000500, is_5g ? 0x4000400 :
>>> +							      0x1000100);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5080, 0x1410, is_1g ? 0x400 :
>>> +							   is_5g ? 0x1010 : 0x0);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5084, 0x30300, is_1g ? 0x30300 :
>>> +							    is_5g ? 0x30100 :
>>> +								    0x100);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x5088, 0x60200, is_1g ? 0x20200 :
>>> +							 is_5g ? 0x40000 :
>>> +								 0x20000);
>>> +
>>> +	/* Setting RXFE adaptation range setting */
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x50a8, 0xee0000, is_5g ? 0x800000 :
>>> +							     0x6e0000);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);
>>> +	if (is_10g)
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x01423342);
>>> +	else if (is_5g)
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00a132a1);
>>> +	else if (is_2p5g)
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x009c329c);
>>> +	else
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00fa32fa);
>>> +
>>> +	/* Force SGDT_OUT off and select PCS */
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_F4,
>>> +			 XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
>>> +			 XFI_DPHY_AD_SGDT_FRC_EN |
>>> +			 (is_xgmii ? XFI_DPHY_PCS_SEL_USXGMII :
>>> +				     XFI_DPHY_PCS_SEL_SGMII));
>>> +
>>> +
>>> +	/* Force GLB_CKDET_OUT */
>>> +	mtk_xfi_tphy_set(xfi_tphy, 0x0030, 0xc00);
>>> +
>>> +	/* Force AEQ on */
>>> +	mtk_xfi_tphy_write(xfi_tphy, REG_DIG_GLB_70,
>>> +			   XTP_PCS_RX_EQ_IN_PROGRESS(2) |
>>> +			   XTP_PCS_PWD_SYNC(2) |
>>> +			   XTP_PCS_PWD_ASYNC(2));
>>> +
>>> +	usleep_range(1, 5);
>>> +
>>> +	/* Setup TX DA default value */
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x30b0, 0x30, 0x20);
>>> +	mtk_xfi_tphy_write(xfi_tphy, 0x3028, 0x00008a01);
>>> +	mtk_xfi_tphy_write(xfi_tphy, 0x302c, 0x0000a884);
>>> +	mtk_xfi_tphy_write(xfi_tphy, 0x3024, 0x00083002);
>>> +
>>> +	/* Setup RG default value */
>>> +	if (is_xgmii) {
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00022220);
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x5064, 0x0f020a01);
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x50b4, 0x06100600);
>>> +		if (interface == PHY_INTERFACE_MODE_USXGMII)
>>> +			mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
>>> +		else
>>> +			mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x47684100);
>>> +	} else {
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00011110);
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000);
>>> +	}
>>> +
>>> +	if (is_1g)
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x3064, 0x0000c000);
>>> +
>>> +	/* Setup RX EQ initial value */
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x3050, 0xa8000000,
>>> +			 (interface != PHY_INTERFACE_MODE_10GBASER) ?
>>> +			  0xa8000000 : 0x0);
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0x3054, 0xaa,
>>> +			 (interface != PHY_INTERFACE_MODE_10GBASER) ?
>>> +			  0xaa : 0x0);
>>> +
>>> +	if (is_xgmii)
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x00000f00);
>>> +	else if (is_2p5g)
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x22000f00);
>>> +	else
>>> +		mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x20200f00);
>>> +
>>> +	if (interface == PHY_INTERFACE_MODE_10GBASER && xfi_tphy->da_war)
>>> +		mtk_xfi_tphy_rmw(xfi_tphy, 0xa008, 0x10000, 0x10000);
>>> +
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, 0xa060, 0x50000, is_xgmii ? 0x40000 :
>>> +							       0x50000);
>>> +
>>> +	/* Setup PHYA speed */
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, REG_ANA_GLB_D0,
>>> +			 XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
>>> +			 is_10g ?  XTP_GLB_USXGMII_SEL(0) :
>>> +			 is_5g ?   XTP_GLB_USXGMII_SEL(1) :
>>> +			 is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
>>> +				   XTP_GLB_USXGMII_SEL(3));
>>> +	mtk_xfi_tphy_set(xfi_tphy, REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
>>> +
>>> +	/* Release reset */
>>> +	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_GLB_70,
>>> +			 XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
>>> +	usleep_range(150, 500);
>>> +
>>> +	/* Switch to P0 */
>>> +	mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
>>> +			 XTP_PCS_PWD_SYNC_MASK |
>>> +			 XTP_PCS_PWD_ASYNC_MASK,
>>> +			 XTP_FRC_PCS_PWD_ASYNC |
>>> +			 XTP_PCS_UPDT | XTP_PCS_IN_FR_RG);
>>> +	usleep_range(1, 5);
>>> +
>>> +	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
>>> +	usleep_range(15, 50);
>>> +
>>> +	if (is_xgmii) {
>>> +		/* Switch to Gen3 */
>>> +		mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
>>> +				 XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
>>> +				 XTP_PCS_MODE(2) | XTP_PCS_UPDT);
>>> +	} else {
>>> +		/* Switch to Gen2 */
>>> +		mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70,
>>> +				 XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
>>> +				 XTP_PCS_MODE(1) | XTP_PCS_UPDT);
>>> +	}
>>> +	usleep_range(1, 5);
>>> +
>>> +	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT);
>>> +
>>> +	usleep_range(100, 500);
>>> +
>>> +	/* Enable MAC CK */
>>> +	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
>>> +	mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN);
>>> +
>>> +	/* Enable TX data */
>>> +	mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_40,
>>> +			 XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
>>> +	usleep_range(400, 1000);
>>> +}
>>> +
>>> +static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int
>>> +				 submode)
>>> +{
>>> +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
>>> +
>>> +	if (mode != PHY_MODE_ETHERNET)
>>> +		return -EINVAL;
>>> +
>>> +	switch (submode) {
>>> +	case PHY_INTERFACE_MODE_1000BASEX:
>>
>> fallthrough;
> 
> I don't think so. No other kernel drivers are doing that and also there
> is no compiler warning what-so-ever when matching multiple cases in that
> way.
> 

Right. Just verified. Keep it like that then.

>>
>>> +	case PHY_INTERFACE_MODE_2500BASEX:
>>
>> fallthrough;
>>
>>> +	case PHY_INTERFACE_MODE_SGMII:
>>
>> ... etc :-)
>>
>>> +	case PHY_INTERFACE_MODE_5GBASER:
>>> +	case PHY_INTERFACE_MODE_10GBASER:
>>> +	case PHY_INTERFACE_MODE_USXGMII:
>>
>> Does this PHY support PHY_INTERFACE_MODE_XGMII ?
>>
>>> +		mtk_xfi_tphy_setup(xfi_tphy, submode);
>>> +		return 0;
>>> +	default:
>>> +		return -EINVAL;
>>> +	}
>>> +}
>>> +
>>> +static int mtk_xfi_tphy_reset(struct phy *phy)
>>> +{
>>> +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
>>> +
>>> +	reset_control_assert(xfi_tphy->reset);
>>> +	usleep_range(100, 500);
>>> +	reset_control_deassert(xfi_tphy->reset);
>>> +	usleep_range(1, 10);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int mtk_xfi_tphy_power_on(struct phy *phy)
>>> +{
>>> +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
>>> +
>>> +	return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
>>> +}
>>> +
>>> +static int mtk_xfi_tphy_power_off(struct phy *phy)
>>> +{
>>> +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
>>> +
>>> +	clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static const struct phy_ops mtk_xfi_tphy_ops = {
>>> +	.power_on	= mtk_xfi_tphy_power_on,
>>> +	.power_off	= mtk_xfi_tphy_power_off,
>>> +	.set_mode	= mtk_xfi_tphy_set_mode,
>>> +	.reset		= mtk_xfi_tphy_reset,
>>> +	.owner		= THIS_MODULE,
>>> +};
>>> +
>>> +static int mtk_xfi_tphy_probe(struct platform_device *pdev)
>>> +{
>>> +	struct device_node *np = pdev->dev.of_node;
>>> +	struct phy_provider *phy_provider;
>>> +	struct mtk_xfi_tphy *xfi_tphy;
>>> +	struct phy *phy;
>>> +
>>> +	if (!np)
>>> +		return -ENODEV;
>>> +
>>> +	xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
>>> +	if (!xfi_tphy)
>>> +		return -ENOMEM;
>>> +
>>> +	xfi_tphy->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
>>
>> Why devm_of_iomap() and not devm_platform_ioremap_resource()?
> 
> True, I will make use of devm_platform_ioremap_resource().
> 
>>
>>> +	if (!xfi_tphy->base)
>>> +		return -EIO;
>>> +
>>> +	xfi_tphy->dev = &pdev->dev;
>>> +
>>> +	xfi_tphy->clocks[0].id = "topxtal";
>>
>> xfi_tphy->clocks[0].id = "topxtal";
>> xfi_tphy->clocks[1].id = "xfipll";
>>
>> ret = devm_clk_bulk_get(&pdev->dev, MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
>> if (ret)
>> 	return ret;
>>
>> ...it's that simple :-P
> 
> Ok, thanks :)
> 
>>
>>> +	xfi_tphy->clocks[0].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[0].id);
>>> +	if (IS_ERR(xfi_tphy->clocks[0].clk))
>>> +		return PTR_ERR(xfi_tphy->clocks[0].clk);
>>> +
>>> +	xfi_tphy->clocks[1].id = "xfipll";
>>> +	xfi_tphy->clocks[1].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[1].id);
>>> +	if (IS_ERR(xfi_tphy->clocks[1].clk))
>>> +		return PTR_ERR(xfi_tphy->clocks[1].clk);
>>> +
>>> +	xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
>>> +	if (IS_ERR(xfi_tphy->reset))
>>> +		return PTR_ERR(xfi_tphy->reset);
>>> +
>>> +	xfi_tphy->da_war = of_property_read_bool(np,
>>> +						 "mediatek,usxgmii-performance-errata");
>>> +
>>
>> One line please
>>
>>> +	phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
>>> +	if (IS_ERR(phy))
>>> +		return PTR_ERR(phy);
>>> +
>>> +	phy_set_drvdata(phy, xfi_tphy);
>>> +
>>> +	phy_provider = devm_of_phy_provider_register(&pdev->dev,
>>> +						     of_phy_simple_xlate);
>>
>> ditto
>>
>>> +
>>> +	return PTR_ERR_OR_ZERO(phy_provider);
>>> +}
>>> +
>>> +static const struct of_device_id mtk_xfi_tphy_match[] = {
>>> +	{ .compatible = "mediatek,mt7988-xfi-tphy", },
>>> +	{ }
>>
>> 	{ .compatible = "mediatek,mt7988-xfi-tphy" },
>> 	{ /* sentinel */ }
> 
> Ack.
> 
>>
>>> +};
>>> +MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
>>> +
>>> +static struct platform_driver mtk_xfi_tphy_driver = {
>>> +	.probe = mtk_xfi_tphy_probe,
>>> +	.driver = {
>>> +		.name = "mtk-xfi-tphy",
>>> +		.of_match_table = mtk_xfi_tphy_match,
>>> +	},
>>> +};
>>> +module_platform_driver(mtk_xfi_tphy_driver);
>>> +
>>> +MODULE_DESCRIPTION("MediaTek XFI T-PHY driver");
>>
>> MODULE_DESCRIPTION("MediaTek 10GE SerDes XFI T-PHY driver");
> 
> Ack, will unify the name everywhere.
> 
>>
>> Cheers,
>> Angelo
>>
>>> +MODULE_AUTHOR("Daniel Golle <daniel at makrotopia.org>");
>>> +MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen at mediatek.com>");
>>> +MODULE_LICENSE("GPL");
>>
>>



From peter.griffin at linaro.org  Mon Feb  5 07:26:48 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 5 Feb 2024 15:26:48 +0000
Subject: [PATCH v4 03/16] spi: s3c64xx: avoid possible negative array index
In-Reply-To: <20240205124513.447875-4-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org> <20240205124513.447875-4-tudor.ambarus@linaro.org>
Message-ID: <CADrjBPoBj_TKFJnBDJ8gMgj3PwjBT=g8sy_LhXnJFUTutuMKNA@mail.gmail.com>

On Mon, 5 Feb 2024 at 12:45, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> The platform id is used as an index into the fifo_lvl_mask array.
> Platforms can come with a negative device ID, PLATFORM_DEVID_NONE (-1),
> thus we risked a negative array index. Catch such cases and fail to
> probe.
>
> Fixes: 2b90807549e5 ("spi: s3c64xx: add device tree support")
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>


From peter.griffin at linaro.org  Mon Feb  5 07:28:05 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 5 Feb 2024 15:28:05 +0000
Subject: [PATCH v4 05/16] spi: s3c64xx: sort headers alphabetically
In-Reply-To: <20240205124513.447875-6-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org> <20240205124513.447875-6-tudor.ambarus@linaro.org>
Message-ID: <CADrjBPqv2O+au=MOxCoaLAAuQqOPTL7QDKcmEUUWgfAXbuWmAw@mail.gmail.com>

On Mon, 5 Feb 2024 at 12:45, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> Sorting headers alphabetically helps locating duplicates,
> and makes it easier to figure out where to insert new headers.
>
> Reviewed-by: Andi Shyti <andi.shyti at kernel.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>


From angelogioacchino.delregno at collabora.com  Mon Feb  5 07:29:03 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 5 Feb 2024 16:29:03 +0100
Subject: [PATCH 2/2] phy: add driver for MediaTek XFI T-PHY
In-Reply-To: <a2641a62703bcd33115689544001cdbd26e84bbb.camel@mediatek.com>
References: <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org>
 <dd6b40ea1f7f8459a9a2cfe7fa60c1108332ade6.1706823233.git.daniel@makrotopia.org>
 <a2641a62703bcd33115689544001cdbd26e84bbb.camel@mediatek.com>
Message-ID: <f7b2475a-990e-4972-9c82-0989876fa116@collabora.com>

Il 04/02/24 07:29, Chunfeng Yun (???) ha scritto:
> On Thu, 2024-02-01 at 21:53 +0000, Daniel Golle wrote:
>>   	
>> External email : Please do not click links or open attachments until
>> you have verified the sender or the content.
>>   Add driver for MediaTek's XFI T-PHY, 10 Gigabit/s Ethernet SerDes
>> PHY
>> which can be found in the MT7988 SoC.
>>
>> The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
>> PHY_INTERFACE_MODE_* corresponding to the supported modes:
>>
>>   * USXGMII                 \
>>   * 10GBase-R                }- USXGMII PCS - XGDM  \
>>   * 5GBase-R                /                        \
>>                                                       }- Ethernet MAC
>>   * 2500Base-X              \                        /
>>   * 1000Base-X               }- LynxI PCS - GDM     /
>>   * Cisco SGMII (MAC side)  /
>>
>> In order to work-around a performance issue present on the first of
>> two XFI T-PHYs present in MT7988, special tuning is applied which can
>> be
>> selected by adding the 'mediatek,usxgmii-performance-errata' property
>> to
>> the device tree node.
>>
>> There is no documentation for most registers used for the
>> analog/tuning part, however, most of the registers have been
>> partially
>> reverse-engineered from MediaTek's SDK implementation (an opaque
>> sequence of 32-bit register writes) and descriptions for all relevant
>> digital registers and bits such as resets and muxes have been
>> supplied
>> by MediaTek.
>>
>> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
>> ---
>>   MAINTAINERS                             |   1 +
>>   drivers/phy/mediatek/Kconfig            |  12 +
>>   drivers/phy/mediatek/Makefile           |   1 +
>>   drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 392
>> ++++++++++++++++++++++++
>>   4 files changed, 406 insertions(+)
>>   create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 52769631bdb1a..52e4192470bd9 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -13715,6 +13715,7 @@ L:netdev at vger.kernel.org
>>   S:Maintained
>>   F:drivers/net/phy/mediatek-ge-soc.c
>>   F:drivers/net/phy/mediatek-ge.c
>> +F:drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>>   
>>   MEDIATEK I2C CONTROLLER DRIVER
>>   M:Qii Wang <qii.wang at mediatek.com>
>> diff --git a/drivers/phy/mediatek/Kconfig
>> b/drivers/phy/mediatek/Kconfig
>> index 3125ecb5d119f..5161d130c7f8b 100644
>> --- a/drivers/phy/mediatek/Kconfig
>> +++ b/drivers/phy/mediatek/Kconfig
>> @@ -13,6 +13,18 @@ config PHY_MTK_PCIE
>>     callback for PCIe GEN3 port, it supports software efuse
>>     initialization.
>>   
>> +config PHY_MTK_XFI_TPHY
>> +tristate "MediaTek XFI T-PHY Driver"
>> +depends on ARCH_MEDIATEK || COMPILE_TEST
>> +depends on OF && OF_ADDRESS
>> +depends on HAS_IOMEM
>> +select GENERIC_PHY
>> +help
>> +  Say 'Y' here to add support for MediaTek XFI T-PHY driver.
>> +  The driver provides access to the Ethernet SerDes T-PHY supporting
>> +  1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
>> +  via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
>> +
>>   config PHY_MTK_TPHY
>>   tristate "MediaTek T-PHY Driver"
>>   depends on ARCH_MEDIATEK || COMPILE_TEST
>> diff --git a/drivers/phy/mediatek/Makefile
>> b/drivers/phy/mediatek/Makefile
>> index c9a50395533eb..fa7217178e7f4 100644
>> --- a/drivers/phy/mediatek/Makefile
>> +++ b/drivers/phy/mediatek/Makefile
>> @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)+= phy-mtk-pcie.o
>>   obj-$(CONFIG_PHY_MTK_TPHY)+= phy-mtk-tphy.o
>>   obj-$(CONFIG_PHY_MTK_UFS)+= phy-mtk-ufs.o
>>   obj-$(CONFIG_PHY_MTK_XSPHY)+= phy-mtk-xsphy.o
>> +obj-$(CONFIG_PHY_MTK_XFI_TPHY)+= phy-mtk-xfi-tphy.o
>>   
>>   phy-mtk-hdmi-drv-y:= phy-mtk-hdmi.o
>>   phy-mtk-hdmi-drv-y+= phy-mtk-hdmi-mt2701.o
>> diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>> b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>> new file mode 100644
>> index 0000000000000..d50e6320860e5
>> --- /dev/null
>> +++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
>> @@ -0,0 +1,392 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/* MediaTek 10GE SerDes PHY driver
>> + *
>> + * Copyright (c) 2024 Daniel Golle <daniel at makrotopia.org>
>> + *                    Bc-bocun Chen <bc-bocun.chen at mediatek.com>
>> + * based on mtk_usxgmii.c found in MediaTek's SDK released under
>> GPL-2.0
>> + * Copyright (c) 2022 MediaTek Inc.
>> + * Author: Henry Yen <henry.yen at mediatek.com>
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/of.h>
>> +#include <linux/io.h>
>> +#include <linux/clk.h>
>> +#include <linux/reset.h>
>> +#include <linux/phy.h>
>> +#include <linux/phy/phy.h>
>> +
>> +#define MTK_XFI_TPHY_NUM_CLOCKS2
>> +
>> +#define REG_DIG_GLB_700x0070
>> +#define  XTP_PCS_RX_EQ_IN_PROGRESS(x)FIELD_PREP(GENMASK(25, 24),
>> (x))
>> +#define  XTP_PCS_MODE_MASKGENMASK(17, 16)
>> +#define  XTP_PCS_MODE(x)FIELD_PREP(GENMASK(17, 16), (x))
>> +#define  XTP_PCS_RST_BBIT(15)
>> +#define  XTP_FRC_PCS_RST_BBIT(14)
>> +#define  XTP_PCS_PWD_SYNC_MASKGENMASK(13, 12)
>> +#define  XTP_PCS_PWD_SYNC(x)FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
>> +#define  XTP_PCS_PWD_ASYNC_MASKGENMASK(11, 10)
>> +#define  XTP_PCS_PWD_ASYNC(x)FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
>> +#define  XTP_FRC_PCS_PWD_ASYNCBIT(8)
>> +#define  XTP_PCS_UPDTBIT(4)
>> +#define  XTP_PCS_IN_FR_RGBIT(0)
>> +
>> +#define REG_DIG_GLB_F40x00f4
>> +#define  XFI_DPHY_PCS_SELBIT(0)
>> +#define   XFI_DPHY_PCS_SEL_SGMIIFIELD_PREP(XFI_DPHY_PCS_SEL, 1)
>> +#define   XFI_DPHY_PCS_SEL_USXGMIIFIELD_PREP(XFI_DPHY_PCS_SEL, 0)
>> +#define  XFI_DPHY_AD_SGDT_FRC_ENBIT(5)
>> +
>> +#define REG_DIG_LN_TRX_400x3040
>> +#define  XTP_LN_FRC_TX_DATA_ENBIT(29)
>> +#define  XTP_LN_TX_DATA_ENBIT(28)
>> +
>> +#define REG_DIG_LN_TRX_B00x30b0
>> +#define  XTP_LN_FRC_TX_MACCK_ENBIT(5)
>> +#define  XTP_LN_TX_MACCK_ENBIT(4)
>> +
>> +#define REG_ANA_GLB_D00x90d0
>> +#define  XTP_GLB_USXGMII_SEL_MASKGENMASK(3, 1)
>> +#define  XTP_GLB_USXGMII_SEL(x)FIELD_PREP(GENMASK(3, 1), (x))
>> +#define  XTP_GLB_USXGMII_ENBIT(0)
>> +
>> +struct mtk_xfi_tphy {
>> +void __iomem*base;
>> +struct device*dev;
>> +struct reset_control*reset;
>> +struct clk_bulk_dataclocks[MTK_XFI_TPHY_NUM_CLOCKS];
>> +boolda_war;
>> +};
>> +
>> +static void mtk_xfi_tphy_write(struct mtk_xfi_tphy *xfi_tphy, u16
>> reg,
>> +       u32 value)
>> +{
>> +iowrite32(value, xfi_tphy->base + reg);
>> +}
>> +
>> +static void mtk_xfi_tphy_rmw(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
>> +     u32 clr, u32 set)
>> +{
>> +u32 val;
>> +
>> +val = ioread32(xfi_tphy->base + reg);
>> +val &= ~clr;
>> +val |= set;
>> +iowrite32(val, xfi_tphy->base + reg);
>> +}
>> +
>> +static void mtk_xfi_tphy_set(struct mtk_xfi_tphy *xfi_tphy, u16 reg,
>> +     u32 set)
>> +{
>> +mtk_xfi_tphy_rmw(xfi_tphy, reg, 0, set);
>> +}
>> +
>> +static void mtk_xfi_tphy_clear(struct mtk_xfi_tphy *xfi_tphy, u16
>> reg,
>> +       u32 clr)
>> +{
>> +mtk_xfi_tphy_rmw(xfi_tphy, reg, clr, 0);
>> +}
> 
> Helpers defined in phy-mtk-io.h can be used instead?
> 
>> +
>> +static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
>> +       phy_interface_t interface)
>> +{
>> +bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
>> +bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
>> +      interface == PHY_INTERFACE_MODE_SGMII);
>> +bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
>> +       interface == PHY_INTERFACE_MODE_USXGMII);
>> +bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
>> +bool is_xgmii = (is_10g || is_5g);
>> +
>> +dev_dbg(xfi_tphy->dev, "setting up for mode %s\n",
>> phy_modes(interface));
>> +
>> +/* Setup PLL setting */
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x9024, 0x100000, is_10g ? 0x0 :
>> 0x100000);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x2020, 0x202000, is_5g ? 0x202000 :
>> 0x0);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x2030, 0x500, is_1g ? 0x0 : 0x500);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x2040, 0x340000, is_1g ? 0x200000 :
>> +     0x140000);
>> +
>> +/* Setup RXFE BW setting */
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50f0, 0xc10, is_1g ? 0x410 :
>> +  is_5g ? 0x800 : 0x400);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
>> +
>> +/* Setup RX CDR setting */
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5070, 0x670000, is_5g ? 0x620000 :
>> 0x50000);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5074, 0x180000, is_5g ? 0x180000 :
>> 0x0);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5078, 0xf000400, is_5g ? 0x8000000 :
>> +      0x7000400);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x507c, 0x5000500, is_5g ? 0x4000400 :
>> +      0x1000100);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5080, 0x1410, is_1g ? 0x400 :
>> +   is_5g ? 0x1010 : 0x0);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5084, 0x30300, is_1g ? 0x30300 :
>> +    is_5g ? 0x30100 :
>> +    0x100);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x5088, 0x60200, is_1g ? 0x20200 :
>> + is_5g ? 0x40000 :
>> + 0x20000);
>> +
>> +/* Setting RXFE adaptation range setting */
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x50a8, 0xee0000, is_5g ? 0x800000 :
>> +     0x6e0000);
>> +mtk_xfi_tphy_rmw(xfi_tphy, 0x6004, 0x190000, is_5g ? 0x0 :
>> 0x190000);
>> +if (is_10g)
>> +mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x01423342);
>> +else if (is_5g)
>> +mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00a132a1);
>> +else if (is_2p5g)
>> +mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x009c329c);
>> +else
>> +mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00fa32fa);
> Still have many magic number.
> 

There's lack of documentation, that's why Daniel has all those magic numbers there.

If you can help unrolling some definitions that'd be really appreciated, as that
would result in a cleaner driver.

Cheers,
Angelo



From angelogioacchino.delregno at collabora.com  Mon Feb  5 07:31:51 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 5 Feb 2024 16:31:51 +0100
Subject: [PATCH v2 2/2] arm64: dts: mediatek: Introduce the MT8395 Radxa
 NIO 12L board
In-Reply-To: <202402041754.SHJCpnEP-lkp@intel.com>
References: <20240202114821.79227-3-angelogioacchino.delregno@collabora.com>
 <202402041754.SHJCpnEP-lkp@intel.com>
Message-ID: <1b2538a1-d85d-4a62-8c9a-24ce93613080@collabora.com>

Il 04/02/24 10:31, kernel test robot ha scritto:
> Hi AngeloGioacchino,
> 
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on robh/for-next]
> [also build test ERROR on linus/master v6.8-rc2 next-20240202]

Whoever is reading this... yes that's all expected; this series depends on a commit
that was already picked in the mediatek trees.

https://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux.git/commit/?h=v6.8-next/dts64&id=d464e09e60f024aea0de7adb680a8e8582ab8df8

Regards,
Angelo

> [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#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/AngeloGioacchino-Del-Regno/dt-bindings-arm64-mediatek-Add-MT8395-Radxa-NIO-12L-board-compatible/20240202-195207
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
> patch link:    https://lore.kernel.org/r/20240202114821.79227-3-angelogioacchino.delregno%40collabora.com
> patch subject: [PATCH v2 2/2] arm64: dts: mediatek: Introduce the MT8395 Radxa NIO 12L board
> config: arm64-defconfig (https://download.01.org/0day-ci/archive/20240204/202402041754.SHJCpnEP-lkp at intel.com/config)
> compiler: aarch64-linux-gcc (GCC) 13.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240204/202402041754.SHJCpnEP-lkp at intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp at intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202402041754.SHJCpnEP-lkp at intel.com/
> 
> All errors (new ones prefixed by >>):
> 
>>> Error: arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts:791.1-8 Label or path ssusb0 not found
>>> Error: arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts:804.1-8 Label or path ssusb2 not found
>     FATAL ERROR: Syntax error parsing input tree
> 




From maz at kernel.org  Mon Feb  5 07:34:05 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 05 Feb 2024 15:34:05 +0000
Subject: [PATCH v8 13/38] KVM: arm64: Manage GCS registers for guests
In-Reply-To: <825d2b35-fa10-43ad-b3b3-b29a77f3fed0@sirena.org.uk>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
	<20240203-arm64-gcs-v8-13-c9fec77673ef@kernel.org>
	<868r3z6y6v.wl-maz@kernel.org>
	<825d2b35-fa10-43ad-b3b3-b29a77f3fed0@sirena.org.uk>
Message-ID: <8634u76i36.wl-maz@kernel.org>

On Mon, 05 Feb 2024 12:35:53 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> On Mon, Feb 05, 2024 at 09:46:16AM +0000, Marc Zyngier wrote:
> > On Sat, 03 Feb 2024 12:25:39 +0000,
> > Mark Brown <broonie at kernel.org> wrote:
> 
> > > +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> > > @@ -25,6 +25,8 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt)
> > >  {
> > >  	ctxt_sys_reg(ctxt, TPIDR_EL0)	= read_sysreg(tpidr_el0);
> > >  	ctxt_sys_reg(ctxt, TPIDRRO_EL0)	= read_sysreg(tpidrro_el0);
> > > +	if (has_gcs())
> > > +		ctxt_sys_reg(ctxt, GCSPR_EL0) = read_sysreg_s(SYS_GCSPR_EL0);
> 
> > We have had this discussion in the past. This must be based on the
> > VM's configuration. Guarding the check with the host capability is a
> > valuable optimisation, but that's nowhere near enough. See the series
> > that I have posted on this very subject (you're on Cc), but you are
> > welcome to invent your own mechanism in the meantime.
> 
> Right, which postdates the version you're replying to and isn't merged
> yet - the current code was what you were asking for at the time.

v1 and v2 predate it. And if the above is what I did ask, then I must
have done a very poor job of explaining what was required. For which I
apologise profusely.

> I'm
> expecting to update all these feature series to work with that once it
> gets finalised and merged but it's not there yet, I do see I forgot to
> put a note in v9 about that like I did for dpISA - sorry about that, I
> was too focused on the clone3() rework when rebasing onto the new
> kernel.
> 
> This particular series isn't going to get merged for a while yet anyway
> due to the time it'll take for userspace testing, I'm expecting your
> series to be in by the time it becomes an issue.

Right. Then I'll ignore it for the foreseeable future.

> 
> > > +	if (has_gcs()) {
> > > +		write_sysreg_el1(ctxt_sys_reg(ctxt, GCSPR_EL1),	SYS_GCSPR);
> > > +		write_sysreg_el1(ctxt_sys_reg(ctxt, GCSCR_EL1),	SYS_GCSCR);
> > > +		write_sysreg_s(ctxt_sys_reg(ctxt, GCSCRE0_EL1),
> > > +			       SYS_GCSCRE0_EL1);
> > > +	}
> 
> > For the benefit of the unsuspecting reviewers, and in the absence of a
> > public specification (which the XML drop isn't), it would be good to
> > have the commit message explaining the rationale of what gets saved
> > when.
> 
> What are you looking for in terms of rationale here?  The KVM house
> style is often very reliant on reader context so it would be good to
> know what considerations you'd like to see explicitly addressed.

Nothing to do with style, everything to do with substance: if nothing
in the host kernel makes any use of these registers, why are they
eagerly saved/restored on nVHE/hVHE? I'm sure you have a reason for
it, but it isn't that obvious. Because these two modes need all the
help they can get in terms of overhead reduction.

> These
> registers shouldn't do anything when we aren't running the guest so
> they're not terribly ordering sensitive, the EL2 ones will need a bit
> more consideration in the face of nested virt.

The EL2 registers should follow the exact same pattern, specially once
you fix the VNCR bugs I pointed out.

	M.

-- 
Without deviation from the norm, progress is not possible.


From james.clark at arm.com  Mon Feb  5 07:37:34 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 5 Feb 2024 15:37:34 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event
 state to hypervisor
In-Reply-To: <864jen6k0i.wl-maz@kernel.org>
References: <20240104162714.1062610-1-james.clark@arm.com>
 <20240104162714.1062610-3-james.clark@arm.com> <Zb1mCCi13AJ_YjFZ@linux.dev>
 <8a908ee8-620a-d9c2-734b-5a6402950072@arm.com> <ZcDc8-FQo8wKavA4@linux.dev>
 <867cjj6ohz.wl-maz@kernel.org> <ZcDg1sP3EYZG-i_3@linux.dev>
 <a7cc7791-c476-fd81-b79d-a151293b8302@arm.com> <864jen6k0i.wl-maz@kernel.org>
Message-ID: <c773393c-221e-edd1-00b7-0ce6a2481c15@arm.com>



On 05/02/2024 14:52, Marc Zyngier wrote:
> On Mon, 05 Feb 2024 14:17:10 +0000,
> James Clark <james.clark at arm.com> wrote:
>>
>> On 05/02/2024 13:21, Oliver Upton wrote:
>>> On Mon, Feb 05, 2024 at 01:15:36PM +0000, Marc Zyngier wrote:
>>>> On Mon, 05 Feb 2024 13:04:51 +0000,
>>>> Oliver Upton <oliver.upton at linux.dev> wrote:
>>>>>
>>>>> Unless someone has strong opinions about making this work in protected
>>>>> mode, I am happy to see tracing support limited to the 'normal' nVHE
>>>>> configuration. The protected feature as a whole is just baggage until
>>>>> upstream support is completed.
>>>>
>>>> Limiting tracing to non-protected mode is a must IMO. Allowing tracing
>>>> when pKVM is enabled is a sure way to expose secrets that should
>>>> stay... secret. The only exception I can think of is when
>>>> CONFIG_NVHE_EL2_DEBUG is enabled, at which point all bets are off.
>>>
>>> Zero argument there :) I left off the "and PMU" part of what I was
>>> saying, because that was a feature that semi-worked in protected mode
>>> before VM/VCPU shadowing support landed.
>>>
>>
>> In that case I can hide all this behind CONFIG_NVHE_EL2_DEBUG for pKVM.
>> This will also have the effect of disabling PMU again for pKVM because I
>> moved that into this new shared area.
> 
> I'm not sure what you have in mind, but dropping PMU support for
> non-protected guests when protected-mode is enabled is not an
> acceptable outcome.
> 
> Hiding the trace behind a debug option is fine as this is a global
> setting that has no userspace impact, but impacting guests isn't.
> 
> 	M.
> 

Hmmm in that case if there's currently no way to distinguish between
normal VMs and pVMs in protected-mode then what I was thinking of
probably won't work.

I'll actually just leave PMU as it is and only have tracing disabled in
protected-mode.

My only question now is whether to:

 * Keep this new shared area and use it for both PMU and trace status
   (well, for PMU only in protected mode as trace would always be
   disabled and doesn't actually need any state)

 * Delete patch 2, add a new normal per-cpu struct just for
   trace status that's only used in non-protected mode and revert to
   copying the PMU status into the vCPU on guest switch as it was
   previously.


From sakari.ailus at linux.intel.com  Mon Feb  5 02:53:10 2024
From: sakari.ailus at linux.intel.com (Sakari Ailus)
Date: Mon, 5 Feb 2024 10:53:10 +0000
Subject: [PATCH 17/17] linux: v4l2-vp9.h: Fix kerneldoc
In-Reply-To: <e565f8bd-19d2-4574-8c6d-5573733a8185@xs4all.nl>
References: <20240126-gix-mtk-warnings-v1-0-eed7865fce18@chromium.org>
 <20240126-gix-mtk-warnings-v1-17-eed7865fce18@chromium.org>
 <ZbTTb-SdK-EubGdc@valkosipuli.retiisi.eu>
 <201ae1d1-1e03-40e2-9cc4-49df70abb8da@xs4all.nl>
 <8f3bab1f-8697-40c0-91f2-de934b4b9ddb@infradead.org>
 <e565f8bd-19d2-4574-8c6d-5573733a8185@xs4all.nl>
Message-ID: <ZcC-FjF5pJUKz9Ir@kekkonen.localdomain>

Hi Hans,

On Mon, Feb 05, 2024 at 11:44:13AM +0100, Hans Verkuil wrote:
> On 05/02/2024 11:39, Randy Dunlap wrote:
> > 
> > 
> > On 2/5/24 02:29, Hans Verkuil wrote:
> >> On 27/01/2024 10:57, Sakari Ailus wrote:
> >>> Hi Ricardo,
> >>>
> >>> On Fri, Jan 26, 2024 at 11:16:16PM +0000, Ricardo Ribalda wrote:
> >>>> Kerneldoc cannot understand arrays defined like
> >>>> v4l2_frame_symbol_counts.
> >>>>
> >>>> Adding an asterisk to the name does do the trick.
> >>>>
> >>>> Disable the kerneldoc notation for now, it is already ignored:
> >>>> https://docs.kernel.org/search.html?q=v4l2_vp9_frame_symbol_counts
> >>>
> >>> Wouldn't it be nicer to fix kerneldoc instead? It might not be difficult at
> >>> all.
> >>>
> >>> Feel free to, but I can also give it a try.
> >>>
> >>
> >> It would be nice to have this fixed in kerneldoc itself. I'm holding this
> >> patch back for two weeks to see if someone wants to work on kerneldoc.
> >>
> >> If not, then I'll take this anyway to fix the noise in our build.
> >>
> >> Note that while this header is indeed ignored in the documentation, that
> >> is really more a bug and it would be nice to actually include this header
> >> somewhere in our documentation. So fixing these kerneldoc warnings one way
> >> or another is something that we should do.
> >>
> > 
> > It's just waiting for Jon to apply it: (from Sakari)
> > 
> > https://lore.kernel.org/all/20240131084934.191226-1-sakari.ailus at linux.intel.com/
> 
> Ah, that patch was CCed to me but not to linux-media, and I only searched linux-media
> for it so I missed it. Good news that this is fixed in the right place.

My bad, somehow I missed linux-media from the distribution. :-(

> 
> I marked this 17/17 patch as Obsoleted in patchwork.

Thank you!

-- 
Regards,

Sakari Ailus


From maz at kernel.org  Mon Feb  5 07:50:12 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 05 Feb 2024 15:50:12 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event state to hypervisor
In-Reply-To: <c773393c-221e-edd1-00b7-0ce6a2481c15@arm.com>
References: <20240104162714.1062610-1-james.clark@arm.com>
	<20240104162714.1062610-3-james.clark@arm.com>
	<Zb1mCCi13AJ_YjFZ@linux.dev>
	<8a908ee8-620a-d9c2-734b-5a6402950072@arm.com>
	<ZcDc8-FQo8wKavA4@linux.dev>
	<867cjj6ohz.wl-maz@kernel.org>
	<ZcDg1sP3EYZG-i_3@linux.dev>
	<a7cc7791-c476-fd81-b79d-a151293b8302@arm.com>
	<864jen6k0i.wl-maz@kernel.org>
	<c773393c-221e-edd1-00b7-0ce6a2481c15@arm.com>
Message-ID: <861q9q7vwr.wl-maz@kernel.org>

On Mon, 05 Feb 2024 15:37:34 +0000,
James Clark <james.clark at arm.com> wrote:
> 
> 
> 
> On 05/02/2024 14:52, Marc Zyngier wrote:
> > On Mon, 05 Feb 2024 14:17:10 +0000,
> > James Clark <james.clark at arm.com> wrote:
> >>
> >> On 05/02/2024 13:21, Oliver Upton wrote:
> >>> On Mon, Feb 05, 2024 at 01:15:36PM +0000, Marc Zyngier wrote:
> >>>> On Mon, 05 Feb 2024 13:04:51 +0000,
> >>>> Oliver Upton <oliver.upton at linux.dev> wrote:
> >>>>>
> >>>>> Unless someone has strong opinions about making this work in protected
> >>>>> mode, I am happy to see tracing support limited to the 'normal' nVHE
> >>>>> configuration. The protected feature as a whole is just baggage until
> >>>>> upstream support is completed.
> >>>>
> >>>> Limiting tracing to non-protected mode is a must IMO. Allowing tracing
> >>>> when pKVM is enabled is a sure way to expose secrets that should
> >>>> stay... secret. The only exception I can think of is when
> >>>> CONFIG_NVHE_EL2_DEBUG is enabled, at which point all bets are off.
> >>>
> >>> Zero argument there :) I left off the "and PMU" part of what I was
> >>> saying, because that was a feature that semi-worked in protected mode
> >>> before VM/VCPU shadowing support landed.
> >>>
> >>
> >> In that case I can hide all this behind CONFIG_NVHE_EL2_DEBUG for pKVM.
> >> This will also have the effect of disabling PMU again for pKVM because I
> >> moved that into this new shared area.
> > 
> > I'm not sure what you have in mind, but dropping PMU support for
> > non-protected guests when protected-mode is enabled is not an
> > acceptable outcome.
> > 
> > Hiding the trace behind a debug option is fine as this is a global
> > setting that has no userspace impact, but impacting guests isn't.
> > 
> > 	M.
> > 
> 
> Hmmm in that case if there's currently no way to distinguish between
> normal VMs and pVMs in protected-mode then what I was thinking of
> probably won't work.

Have you looked? kvm_vm_is_protected() has been in for a while, even
if that's not a lot. The upcoming code will flesh this helper out,

	M.

-- 
Without deviation from the norm, progress is not possible.


From luca at lucaweiss.eu  Mon Feb  5 07:44:27 2024
From: luca at lucaweiss.eu (Luca Weiss)
Date: Mon, 05 Feb 2024 16:44:27 +0100
Subject: [PATCH 1/3] dt-bindings: mfd: qcom,spmi-pmic: Add pbs to SPMI device
 types
In-Reply-To: <170714066275.3239944.3114776132620071326.robh@kernel.org>
References: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
 <20240205-pmi632-ppg-v1-1-e236c95a2099@fairphone.com>
 <170714066275.3239944.3114776132620071326.robh@kernel.org>
Message-ID: <5017384.GXAFRqVoOG@z3ntu.xyz>

On Montag, 5. Februar 2024 14:46:45 CET Rob Herring wrote:
> On Mon, 05 Feb 2024 10:51:38 +0100, Luca Weiss wrote:
> > Add the PBS (Programmable Boot Sequencer) to the list of devices.
> > 
> > Signed-off-by: Luca Weiss <luca.weiss at fairphone.com>
> > ---
> > 
> >  Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++
> >  1 file changed, 4 insertions(+)
> 
> 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/dt-review-ci/linux/Documentation/devicetree/bindings/mfd/
> qcom,spmi-pmic.yaml: Error in referenced schema matching $id:
> http://devicetree.org/schemas/soc/qcom/qcom,pbs.yaml

These patches have been merged into linux-next recently, so should get into 
the next release.

> 
> doc reference errors (make refcheckdocs):
> 
> See
> https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240205-pmi
> 632-ppg-v1-1-e236c95a2099 at fairphone.com
> 
> The base for the series is generally the latest rc1. A different dependency
> should be noted in *this* patch.
> 
> 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 after running the above command yourself. Note
> that DT_SCHEMA_FILES can be set to your schema file to speed up checking
> your schema. However, it must be unset to test all examples with your
> schema.






From semen.protsenko at linaro.org  Mon Feb  5 07:53:11 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 5 Feb 2024 09:53:11 -0600
Subject: [PATCH v4 06/16] spi: s3c64xx: remove unneeded (void *) casts in of_match_table
In-Reply-To: <20240205124513.447875-7-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org> <20240205124513.447875-7-tudor.ambarus@linaro.org>
Message-ID: <CAPLW+4=S7+ur0Csd-qQcEBo2_Z3Dy9ZtarYY0=jYhY33kc4WDA@mail.gmail.com>

On Mon, Feb 5, 2024 at 6:45?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> of_device_id::data is an opaque pointer. No explicit cast is needed.
> Remove unneeded (void *) casts in of_match_table.
>
> Reviewed-by: Andi Shyti <andi.shyti at kernel.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

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

>  drivers/spi/spi-s3c64xx.c | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index ccb700312d64..807270ec3c8a 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -1512,31 +1512,31 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
>
>  static const struct of_device_id s3c64xx_spi_dt_match[] = {
>         { .compatible = "samsung,s3c2443-spi",
> -                       .data = (void *)&s3c2443_spi_port_config,
> +                       .data = &s3c2443_spi_port_config,
>         },
>         { .compatible = "samsung,s3c6410-spi",
> -                       .data = (void *)&s3c6410_spi_port_config,
> +                       .data = &s3c6410_spi_port_config,
>         },
>         { .compatible = "samsung,s5pv210-spi",
> -                       .data = (void *)&s5pv210_spi_port_config,
> +                       .data = &s5pv210_spi_port_config,
>         },
>         { .compatible = "samsung,exynos4210-spi",
> -                       .data = (void *)&exynos4_spi_port_config,
> +                       .data = &exynos4_spi_port_config,
>         },
>         { .compatible = "samsung,exynos7-spi",
> -                       .data = (void *)&exynos7_spi_port_config,
> +                       .data = &exynos7_spi_port_config,
>         },
>         { .compatible = "samsung,exynos5433-spi",
> -                       .data = (void *)&exynos5433_spi_port_config,
> +                       .data = &exynos5433_spi_port_config,
>         },
>         { .compatible = "samsung,exynos850-spi",
> -                       .data = (void *)&exynos850_spi_port_config,
> +                       .data = &exynos850_spi_port_config,
>         },
>         { .compatible = "samsung,exynosautov9-spi",
> -                       .data = (void *)&exynosautov9_spi_port_config,
> +                       .data = &exynosautov9_spi_port_config,
>         },
>         { .compatible = "tesla,fsd-spi",
> -                       .data = (void *)&fsd_spi_port_config,
> +                       .data = &fsd_spi_port_config,
>         },
>         { },
>  };
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From megi at xff.cz  Mon Feb  5 07:54:07 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Mon, 5 Feb 2024 16:54:07 +0100
Subject: [PATCH v2 0/6] Pinephone video out fixes (flipping between two
 frames)
In-Reply-To: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
Message-ID: <jzl3mlzk4j7qvgcedvipgale5nhinznefodrnaehwsqfnseiwc@7zzlxd4dpueh>

On Mon, Feb 05, 2024 at 04:22:23PM +0100, Frank Oltmanns wrote:
> On some pinephones the video output sometimes freezes (flips between two
> frames) [1]. It seems to be that the reason for this behaviour is that
> PLL-MIPI, PLL-GPU and GPU are operating outside their limits.
> 
> In this patch series I propose the followin changes:
>   1. sunxi-ng: Adhere to the following constraints given in the
>      Allwinner A64 Manual regarding PLL-MIPI:
>       * M/N <= 3
>       * (PLL_VIDEO0)/M >= 24MHz
>       * 500MHz <= clockrate <= 1400MHz
> 
>   2. Choose a higher clock rate for the ST7703 based XDB599 panel, so
>      that the panel function well with the Allwinner A64 SOC. PLL-MIPI
>      must run between 500 MHz and 1.4 GHz. As PLL-MIPI runs at 6 times
>      the panel's clock rate, we need the panel's clock to be at least
>      83.333 MHz.
> 
>   3. Increase the minimum frequency in the A64 DTS OPPs from 120 MHz to
>      192 MHz. This further reduces the issue.
> 
> Unfortunately, with these patches the issue [1] is not completely gone,
> but becomes less likely.
> 
> Note, that when pinning the GPU to 432 MHz the issue completely
> disappears for me. I've searched the BSP and could not find any
> indication that supports the idea of having the three OPPs. The only
> frequency I found in the BPSs for A64 is 432 MHz, that has also proven
> stable for me. So, while increasing the minimum frequency to 192 MHz
> reduces the issue, should we maybe instead set the GPU to a fixed 432
> MHz instead?

Per A64 User Manual 1.1 page 81:

(9). Clock output of PLL_GPU can be used for GPU;and dynamic frequency scaling is not supported;

Also sunxi-ng clk driver does apply NM factors at once to PLL_GPU clock,
which can cause sudden frequency increase beyond intended output frequency,
because division is applied immediately while multiplication is reflected
slowly.

Eg. if you're changing divider from 7 to 1, you can get a sudden 7x output
frequency spike, before PLL VCO manages to lower the frequency through N clk
divider feedback loop and lock on again. This can mess up whatever's connected
to the output quite badly.

You'd have to put logging on kernel writes to PLL_GPU register to see what
is written in there and if divider is lowered significantly on some GPU
devfreq frequency transitions.

It's also unclear what happens when FRAC_CLK_OUT or PLL_MODE_SEL changes.
Maybe not much because M is supposed to be set to 1, but you still need to
care when enabling fractional mode, and setting M to 1 because that's exactly
the bad scenario if M was previously higher than 1.

It's tricky.

Having GPU module clock gated during PLL config changes may help! You can
do that without locking yourself out, unlike with the CPU PLL.

There's a gate enable bit for it at GPU_CLK_REG.SCLK_GATING. (page 122)

Kind regards,
	o.

> I very much appreciate your feedback!
> 
> [1] https://gitlab.com/postmarketOS/pmaports/-/issues/805
> 
> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> ---
> Changes in v2:
> - dts: Increase minimum GPU frequency to 192 MHz.
> - nkm and a64: Add minimum and maximum rate for PLL-MIPI.
> - nkm: Use the same approach for skipping invalid rates in
>   ccu_nkm_find_best() as in ccu_nkm_find_best_with_parent_adj().
> - nkm: Improve names for ratio struct members and hence get rid of
>   describing comments.
> - nkm and a64: Correct description in the commit messages: M/N <= 3
> - Remove patches for nm as they were not needed.
> - st7703: Rework the commit message to cover more background for the
>   change.
> - Link to v1: https://lore.kernel.org/r/20231218-pinephone-pll-fixes-v1-0-e238b6ed6dc1 at oltmanns.dev
> 
> ---
> Frank Oltmanns (6):
>       clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate
>       clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate
>       clk: sunxi-ng: nkm: Support minimum and maximum rate
>       clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
>       drm/panel: st7703: Drive XBD599 panel at higher clock rate
>       arm64: dts: allwinner: a64: Fix minimum GPU OPP rate
> 
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  4 ++--
>  drivers/clk/sunxi-ng/ccu-sun50i-a64.c         | 14 +++++++----
>  drivers/clk/sunxi-ng/ccu_nkm.c                | 34 +++++++++++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu_nkm.h                |  4 ++++
>  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++++------
>  5 files changed, 56 insertions(+), 14 deletions(-)
> ---
> base-commit: 059c53e877ca6e723e10490c27c1487a63e66efe
> change-id: 20231218-pinephone-pll-fixes-0ccdfde273e4
> 
> Best regards,
> -- 
> Frank Oltmanns <frank at oltmanns.dev>
> 


From avromanov at salutedevices.com  Mon Feb  5 07:55:02 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:02 +0300
Subject: [PATCH v3 01/20] drivers: crypto: meson: don't hardcode IRQ count
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-2-avromanov@salutedevices.com>

IRQ count is no longer hardcoded, and make it part of
struct meson_flow. We need this for extend driver support for
other Amlogic SoC's.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c |  2 +-
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 47 ++++++++++++---------
 drivers/crypto/amlogic/amlogic-gxl.h        |  8 ++--
 3 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 29048da6f50a..b19032f92415 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -19,7 +19,7 @@
 
 static int get_engine_number(struct meson_dev *mc)
 {
-	return atomic_inc_return(&mc->flow) % MAXFLOW;
+	return atomic_inc_return(&mc->flow) % mc->flow_cnt;
 }
 
 static bool meson_cipher_need_fallback(struct skcipher_request *areq)
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f54ab0d0b1e8..35ec64df5b3a 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -28,8 +28,8 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
 	int flow;
 	u32 p;
 
-	for (flow = 0; flow < MAXFLOW; flow++) {
-		if (mc->irqs[flow] == irq) {
+	for (flow = 0; flow < mc->flow_cnt; flow++) {
+		if (mc->chanlist[flow].irq == irq) {
 			p = readl(mc->base + ((0x04 + flow) << 2));
 			if (p) {
 				writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
@@ -110,7 +110,7 @@ static int meson_debugfs_show(struct seq_file *seq, void *v)
 	struct meson_dev *mc __maybe_unused = seq->private;
 	int i;
 
-	for (i = 0; i < MAXFLOW; i++)
+	for (i = 0; i < mc->flow_cnt; i++)
 		seq_printf(seq, "Channel %d: nreq %lu\n", i,
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
 			   mc->chanlist[i].stat_req);
@@ -153,14 +153,32 @@ static void meson_free_chanlist(struct meson_dev *mc, int i)
  */
 static int meson_allocate_chanlist(struct meson_dev *mc)
 {
+	struct platform_device *pdev = to_platform_device(mc->dev);
 	int i, err;
 
-	mc->chanlist = devm_kcalloc(mc->dev, MAXFLOW,
+	mc->flow_cnt = platform_irq_count(pdev);
+	if (mc->flow_cnt <= 0) {
+		dev_err(mc->dev, "No IRQs defined\n");
+		return -ENODEV;
+	}
+
+	mc->chanlist = devm_kcalloc(mc->dev, mc->flow_cnt,
 				    sizeof(struct meson_flow), GFP_KERNEL);
 	if (!mc->chanlist)
 		return -ENOMEM;
 
-	for (i = 0; i < MAXFLOW; i++) {
+	for (i = 0; i < mc->flow_cnt; i++) {
+		mc->chanlist[i].irq = platform_get_irq(pdev, i);
+		if (mc->chanlist[i].irq < 0)
+			return mc->chanlist[i].irq;
+
+		err = devm_request_irq(mc->dev, mc->chanlist[i].irq,
+				       meson_irq_handler, 0, "aml-crypto", mc);
+		if (err < 0) {
+			dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
+			return err;
+		}
+
 		init_completion(&mc->chanlist[i].complete);
 
 		mc->chanlist[i].engine = crypto_engine_alloc_init(mc->dev, true);
@@ -230,7 +248,7 @@ static void meson_unregister_algs(struct meson_dev *mc)
 static int meson_crypto_probe(struct platform_device *pdev)
 {
 	struct meson_dev *mc;
-	int err, i;
+	int err;
 
 	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
 	if (!mc)
@@ -252,19 +270,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	for (i = 0; i < MAXFLOW; i++) {
-		mc->irqs[i] = platform_get_irq(pdev, i);
-		if (mc->irqs[i] < 0)
-			return mc->irqs[i];
-
-		err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0,
-				       "gxl-crypto", mc);
-		if (err < 0) {
-			dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
-			return err;
-		}
-	}
-
 	err = clk_prepare_enable(mc->busclk);
 	if (err != 0) {
 		dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
@@ -294,7 +299,7 @@ static int meson_crypto_probe(struct platform_device *pdev)
 error_alg:
 	meson_unregister_algs(mc);
 error_flow:
-	meson_free_chanlist(mc, MAXFLOW - 1);
+	meson_free_chanlist(mc, mc->flow_cnt - 1);
 	clk_disable_unprepare(mc->busclk);
 	return err;
 }
@@ -309,7 +314,7 @@ static void meson_crypto_remove(struct platform_device *pdev)
 
 	meson_unregister_algs(mc);
 
-	meson_free_chanlist(mc, MAXFLOW - 1);
+	meson_free_chanlist(mc, mc->flow_cnt - 1);
 
 	clk_disable_unprepare(mc->busclk);
 }
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 1013a666c932..79177cfa8b88 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -22,8 +22,6 @@
 #define MESON_OPMODE_ECB 0
 #define MESON_OPMODE_CBC 1
 
-#define MAXFLOW 2
-
 #define MAXDESC 64
 
 #define DESC_LAST BIT(18)
@@ -62,6 +60,7 @@ struct meson_desc {
  * @keylen:	keylen for this flow operation
  * @complete:	completion for the current task on this flow
  * @status:	set to 1 by interrupt if task is done
+ * @irq:	IRQ number for amlogic-crypto
  * @t_phy:	Physical address of task
  * @tl:		pointer to the current ce_task for this flow
  * @stat_req:	number of request done by this flow
@@ -70,6 +69,7 @@ struct meson_flow {
 	struct crypto_engine *engine;
 	struct completion complete;
 	int status;
+	int irq;
 	unsigned int keylen;
 	dma_addr_t t_phy;
 	struct meson_desc *tl;
@@ -85,7 +85,7 @@ struct meson_flow {
  * @dev:	the platform device
  * @chanlist:	array of all flow
  * @flow:	flow to use in next request
- * @irqs:	IRQ numbers for amlogic-crypto
+ * @flow_cnt:	flow count for amlogic-crypto
  * @dbgfs_dir:	Debugfs dentry for statistic directory
  * @dbgfs_stats: Debugfs dentry for statistic counters
  */
@@ -95,7 +95,7 @@ struct meson_dev {
 	struct device *dev;
 	struct meson_flow *chanlist;
 	atomic_t flow;
-	int irqs[MAXFLOW];
+	int flow_cnt;
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
 	struct dentry *dbgfs_dir;
 #endif
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:01 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:01 +0300
Subject: [PATCH v3 00/20] Support more Amlogic SoC families in crypto driver 
Message-ID: <20240205155521.1795552-1-avromanov@salutedevices.com>

Hello!

This patchset expand the funcionality of the Amlogic
crypto driver by adding support for more SoC families:
AXG, G12A, G12B, SM1, A1, S4.

Also specify and enable crypto node in device tree
for reference Amlogic devices.

Tested on AXG, G12A/B, SM1, A1 and S4 devices via
custom tests [1] and tcrypt module.

---

Changes V1 -> V2 [2]:

- Rebased over linux-next.
- Adjusted device tree bindings description.
- A1 and S4 dts use their own compatible, which is a G12 fallback.

Changes V2 -> V3 [3]:

- Fix errors in dt-bindings and device tree.
- Add new field in platform data, which determines
whether clock controller should be used for crypto IP.
- Place back MODULE_DEVICE_TABLE.
- Correct commit messages.

Links:
  - [1] https://gist.github.com/mRrvz/3fb8943a7487ab7b943ec140706995e7
  - [2] https://lore.kernel.org/all/20240110201216.18016-1-avromanov at salutedevices.com/
  - [3] https://lore.kernel.org/all/20240123165831.970023-1-avromanov at salutedevices.com/

Alexey Romanov (20):
  drivers: crypto: meson: don't hardcode IRQ count
  drviers: crypto: meson: add platform data
  drivers: crypto: meson: make CLK controller optional
  drivers: crypto: meson: add MMIO helpers
  drivers: crypto: meson: move get_engine_number()
  drivers: crypto: meson: drop status field from meson_flow
  drivers: crypto: meson: move algs definition and cipher API to
    cipher.c
  drivers: crypto: meson: cleanup defines
  drivers: crypto: meson: process more than MAXDESCS descriptors
  drivers: crypto: meson: avoid kzalloc in engine thread
  drivers: crypto: meson: introduce hasher
  drivers: crypto: meson: add support for AES-CTR
  drivers: crypto: meson: use fallback for 192-bit keys
  drivers: crypto: meson: add support for G12-series
  drivers: crypto: meson: add support for AXG-series
  dt-bindings: crypto: meson: support new SoC's
  arch: arm64: dts: meson: a1: add crypto node
  arch: arm64: dts: meson: s4: add crypto node
  arch: arm64: dts: meson: g12: add crypto node
  arch: arm64: dts: meson: axg: add crypto node

 .../bindings/crypto/amlogic,gxl-crypto.yaml   |  44 +-
 arch/arm64/boot/dts/amlogic/meson-a1.dtsi     |   7 +
 arch/arm64/boot/dts/amlogic/meson-axg.dtsi    |   6 +
 .../boot/dts/amlogic/meson-g12-common.dtsi    |   6 +
 arch/arm64/boot/dts/amlogic/meson-s4.dtsi     |   6 +
 drivers/crypto/amlogic/Makefile               |   2 +-
 drivers/crypto/amlogic/amlogic-gxl-cipher.c   | 602 ++++++++++++------
 drivers/crypto/amlogic/amlogic-gxl-core.c     | 290 +++++----
 drivers/crypto/amlogic/amlogic-gxl-hasher.c   | 452 +++++++++++++
 drivers/crypto/amlogic/amlogic-gxl.h          | 117 +++-
 10 files changed, 1183 insertions(+), 349 deletions(-)
 create mode 100644 drivers/crypto/amlogic/amlogic-gxl-hasher.c

-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:03 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:03 +0300
Subject: [PATCH v3 02/20] drviers: crypto: meson: add platform data
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-3-avromanov@salutedevices.com>

To support other Amlogic SoC's we have to
use platform data: descriptors and status registers
offsets are individual for each SoC series.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c |  2 +-
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 32 +++++++++++++++------
 drivers/crypto/amlogic/amlogic-gxl.h        | 11 +++++++
 3 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index b19032f92415..7eff3ae7356f 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)
 
 	reinit_completion(&mc->chanlist[flow].complete);
 	mc->chanlist[flow].status = 0;
-	writel(mc->chanlist[flow].t_phy | 2, mc->base + (flow << 2));
+	writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
 	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
 						  msecs_to_jiffies(500));
 	if (mc->chanlist[flow].status == 0) {
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 35ec64df5b3a..4d1b1d5b7a54 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
 #include "amlogic-gxl.h"
@@ -30,9 +31,10 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
 
 	for (flow = 0; flow < mc->flow_cnt; flow++) {
 		if (mc->chanlist[flow].irq == irq) {
-			p = readl(mc->base + ((0x04 + flow) << 2));
+			p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
 			if (p) {
-				writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
+				writel_relaxed(0xF, mc->base +
+					      ((mc->pdata->status_reg + flow) << 2));
 				mc->chanlist[flow].status = 1;
 				complete(&mc->chanlist[flow].complete);
 				return IRQ_HANDLED;
@@ -245,15 +247,35 @@ static void meson_unregister_algs(struct meson_dev *mc)
 	}
 }
 
+static const struct meson_pdata meson_gxl_pdata = {
+	.descs_reg = 0x0,
+	.status_reg = 0x4,
+};
+
+static const struct of_device_id meson_crypto_of_match_table[] = {
+	{
+		.compatible = "amlogic,gxl-crypto",
+		.data = &meson_gxl_pdata,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
+
 static int meson_crypto_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *match;
 	struct meson_dev *mc;
 	int err;
 
+	match = of_match_device(meson_crypto_of_match_table, &pdev->dev);
+	if (!match)
+		return -EINVAL;
+
 	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
 	if (!mc)
 		return -ENOMEM;
 
+	mc->pdata = match->data;
 	mc->dev = &pdev->dev;
 	platform_set_drvdata(pdev, mc);
 
@@ -319,12 +341,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
 	clk_disable_unprepare(mc->busclk);
 }
 
-static const struct of_device_id meson_crypto_of_match_table[] = {
-	{ .compatible = "amlogic,gxl-crypto", },
-	{}
-};
-MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
-
 static struct platform_driver meson_crypto_driver = {
 	.probe		 = meson_crypto_probe,
 	.remove_new	 = meson_crypto_remove,
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 79177cfa8b88..9ad75da214ff 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -78,6 +78,16 @@ struct meson_flow {
 #endif
 };
 
+/*
+ * struct meson_pdata - SoC series dependent data.
+ * @reg_descs:	offset to descriptors register
+ * @reg_status:	offset to status register
+ */
+struct meson_pdata {
+	u32 descs_reg;
+	u32 status_reg;
+};
+
 /*
  * struct meson_dev - main container for all this driver information
  * @base:	base address of amlogic-crypto
@@ -93,6 +103,7 @@ struct meson_dev {
 	void __iomem *base;
 	struct clk *busclk;
 	struct device *dev;
+	const struct meson_pdata *pdata;
 	struct meson_flow *chanlist;
 	atomic_t flow;
 	int flow_cnt;
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:04 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:04 +0300
Subject: [PATCH v3 03/20] drivers: crypto: meson: make CLK controller optional
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-4-avromanov@salutedevices.com>

Amlogic crypto IP doesn't take a clock input on some
SoCs: AXG / A1 / S4 / G12. So make it optional.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-core.c | 21 ++++++++-------------
 drivers/crypto/amlogic/amlogic-gxl.h      |  2 ++
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 4d1b1d5b7a54..54113c524ec5 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -250,6 +250,7 @@ static void meson_unregister_algs(struct meson_dev *mc)
 static const struct meson_pdata meson_gxl_pdata = {
 	.descs_reg = 0x0,
 	.status_reg = 0x4,
+	.need_clk = true,
 };
 
 static const struct of_device_id meson_crypto_of_match_table[] = {
@@ -285,17 +286,14 @@ static int meson_crypto_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Cannot request MMIO err=%d\n", err);
 		return err;
 	}
-	mc->busclk = devm_clk_get(&pdev->dev, "blkmv");
-	if (IS_ERR(mc->busclk)) {
-		err = PTR_ERR(mc->busclk);
-		dev_err(&pdev->dev, "Cannot get core clock err=%d\n", err);
-		return err;
-	}
 
-	err = clk_prepare_enable(mc->busclk);
-	if (err != 0) {
-		dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
-		return err;
+	if (mc->pdata->need_clk) {
+		mc->busclk = devm_clk_get_enabled(&pdev->dev, "blkmv");
+		if (IS_ERR(mc->busclk)) {
+			err = PTR_ERR(mc->busclk);
+			dev_err(&pdev->dev, "Cannot get and enable core clock err=%d\n", err);
+			return err;
+		}
 	}
 
 	err = meson_allocate_chanlist(mc);
@@ -322,7 +320,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
 	meson_unregister_algs(mc);
 error_flow:
 	meson_free_chanlist(mc, mc->flow_cnt - 1);
-	clk_disable_unprepare(mc->busclk);
 	return err;
 }
 
@@ -337,8 +334,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
 	meson_unregister_algs(mc);
 
 	meson_free_chanlist(mc, mc->flow_cnt - 1);
-
-	clk_disable_unprepare(mc->busclk);
 }
 
 static struct platform_driver meson_crypto_driver = {
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 9ad75da214ff..a36b9bac63a0 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -82,10 +82,12 @@ struct meson_flow {
  * struct meson_pdata - SoC series dependent data.
  * @reg_descs:	offset to descriptors register
  * @reg_status:	offset to status register
+ * @need_clk:	clock input is needed
  */
 struct meson_pdata {
 	u32 descs_reg;
 	u32 status_reg;
+	bool need_clk;
 };
 
 /*
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:05 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:05 +0300
Subject: [PATCH v3 04/20] drivers: crypto: meson: add MMIO helpers
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-5-avromanov@salutedevices.com>

Add MMIO access helpers: meson_dma_start() and meson_dma_ready().

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c |  2 +-
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 24 ++++++++++++++++-----
 drivers/crypto/amlogic/amlogic-gxl.h        |  2 ++
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 7eff3ae7356f..1fe916b0a138 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)
 
 	reinit_completion(&mc->chanlist[flow].complete);
 	mc->chanlist[flow].status = 0;
-	writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
+	meson_dma_start(mc, flow);
 	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
 						  msecs_to_jiffies(500));
 	if (mc->chanlist[flow].status == 0) {
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 54113c524ec5..372c30f72072 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -23,18 +23,32 @@
 
 #include "amlogic-gxl.h"
 
+void meson_dma_start(struct meson_dev *mc, int flow)
+{
+	u32 offset = (mc->pdata->descs_reg + flow) << 2;
+
+	writel(mc->chanlist[flow].t_phy | 2, mc->base + offset);
+}
+
+static bool meson_dma_ready(struct meson_dev *mc, int flow)
+{
+	u32 offset = (mc->pdata->status_reg + flow) << 2;
+	u32 data = readl(mc->base + offset);
+
+	if (data)
+		writel_relaxed(0xF, mc->base + offset);
+
+	return data;
+}
+
 static irqreturn_t meson_irq_handler(int irq, void *data)
 {
 	struct meson_dev *mc = (struct meson_dev *)data;
 	int flow;
-	u32 p;
 
 	for (flow = 0; flow < mc->flow_cnt; flow++) {
 		if (mc->chanlist[flow].irq == irq) {
-			p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
-			if (p) {
-				writel_relaxed(0xF, mc->base +
-					      ((mc->pdata->status_reg + flow) << 2));
+			if (meson_dma_ready(mc, flow)) {
 				mc->chanlist[flow].status = 1;
 				complete(&mc->chanlist[flow].complete);
 				return IRQ_HANDLED;
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index a36b9bac63a0..59fc6a67e0a9 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -163,6 +163,8 @@ struct meson_alg_template {
 #endif
 };
 
+void meson_dma_start(struct meson_dev *mc, int flow);
+
 int meson_enqueue(struct crypto_async_request *areq, u32 type);
 
 int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:06 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:06 +0300
Subject: [PATCH v3 05/20] drivers: crypto: meson: move get_engine_number()
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-6-avromanov@salutedevices.com>

Move get_engine_number() function from cipher.c to core.c

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 9 ++-------
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 5 +++++
 drivers/crypto/amlogic/amlogic-gxl.h        | 2 ++
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 1fe916b0a138..18e9e2d39b1f 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -17,11 +17,6 @@
 #include <crypto/internal/skcipher.h>
 #include "amlogic-gxl.h"
 
-static int get_engine_number(struct meson_dev *mc)
-{
-	return atomic_inc_return(&mc->flow) % mc->flow_cnt;
-}
-
 static bool meson_cipher_need_fallback(struct skcipher_request *areq)
 {
 	struct scatterlist *src_sg = areq->src;
@@ -282,7 +277,7 @@ int meson_skdecrypt(struct skcipher_request *areq)
 	rctx->op_dir = MESON_DECRYPT;
 	if (meson_cipher_need_fallback(areq))
 		return meson_cipher_do_fallback(areq);
-	e = get_engine_number(op->mc);
+	e = meson_get_engine_number(op->mc);
 	engine = op->mc->chanlist[e].engine;
 	rctx->flow = e;
 
@@ -300,7 +295,7 @@ int meson_skencrypt(struct skcipher_request *areq)
 	rctx->op_dir = MESON_ENCRYPT;
 	if (meson_cipher_need_fallback(areq))
 		return meson_cipher_do_fallback(areq);
-	e = get_engine_number(op->mc);
+	e = meson_get_engine_number(op->mc);
 	engine = op->mc->chanlist[e].engine;
 	rctx->flow = e;
 
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 372c30f72072..51291fdcf8b6 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -23,6 +23,11 @@
 
 #include "amlogic-gxl.h"
 
+int meson_get_engine_number(struct meson_dev *mc)
+{
+	return atomic_inc_return(&mc->flow) % mc->flow_cnt;
+}
+
 void meson_dma_start(struct meson_dev *mc, int flow)
 {
 	u32 offset = (mc->pdata->descs_reg + flow) << 2;
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 59fc6a67e0a9..5f5e3115fcdf 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -163,6 +163,8 @@ struct meson_alg_template {
 #endif
 };
 
+int meson_get_engine_number(struct meson_dev *mc);
+
 void meson_dma_start(struct meson_dev *mc, int flow);
 
 int meson_enqueue(struct crypto_async_request *areq, u32 type);
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:07 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:07 +0300
Subject: [PATCH v3 06/20] drivers: crypto: meson: drop status field from meson_flow
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-7-avromanov@salutedevices.com>

This field is used only to check for timeout. But there is more
convenient way to achive the same goal.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 13 +++++++++----
 drivers/crypto/amlogic/amlogic-gxl-core.c   |  1 -
 drivers/crypto/amlogic/amlogic-gxl.h        |  2 --
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 18e9e2d39b1f..dc0b100c5de2 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -219,13 +219,18 @@ static int meson_cipher(struct skcipher_request *areq)
 	}
 
 	reinit_completion(&mc->chanlist[flow].complete);
-	mc->chanlist[flow].status = 0;
 	meson_dma_start(mc, flow);
-	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
-						  msecs_to_jiffies(500));
-	if (mc->chanlist[flow].status == 0) {
+
+	err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
+							msecs_to_jiffies(500));
+	if (err == 0) {
 		dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
 		err = -EINVAL;
+	} else if (err < 0) {
+		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
+	} else {
+		/* No error */
+		err = 0;
 	}
 
 	dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 51291fdcf8b6..f7c60ebffbc3 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -54,7 +54,6 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
 	for (flow = 0; flow < mc->flow_cnt; flow++) {
 		if (mc->chanlist[flow].irq == irq) {
 			if (meson_dma_ready(mc, flow)) {
-				mc->chanlist[flow].status = 1;
 				complete(&mc->chanlist[flow].complete);
 				return IRQ_HANDLED;
 			}
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 5f5e3115fcdf..e27908992ae3 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -59,7 +59,6 @@ struct meson_desc {
  * @engine:	ptr to the crypto_engine for this flow
  * @keylen:	keylen for this flow operation
  * @complete:	completion for the current task on this flow
- * @status:	set to 1 by interrupt if task is done
  * @irq:	IRQ number for amlogic-crypto
  * @t_phy:	Physical address of task
  * @tl:		pointer to the current ce_task for this flow
@@ -68,7 +67,6 @@ struct meson_desc {
 struct meson_flow {
 	struct crypto_engine *engine;
 	struct completion complete;
-	int status;
 	int irq;
 	unsigned int keylen;
 	dma_addr_t t_phy;
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:08 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:08 +0300
Subject: [PATCH v3 07/20] drivers: crypto: meson: move algs definition and cipher API to cipher.c
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-8-avromanov@salutedevices.com>

Because that is proper place for them. In particular,
it takes less of exported symbol between compiling entities.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c |  98 +++++++++++++++--
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 110 ++++----------------
 drivers/crypto/amlogic/amlogic-gxl.h        |  14 +--
 3 files changed, 119 insertions(+), 103 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index dc0b100c5de2..bc3092a8a2c2 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -271,7 +271,7 @@ int meson_handle_cipher_request(struct crypto_engine *engine, void *areq)
 	return 0;
 }
 
-int meson_skdecrypt(struct skcipher_request *areq)
+static int meson_skdecrypt(struct skcipher_request *areq)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
 	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
@@ -289,7 +289,7 @@ int meson_skdecrypt(struct skcipher_request *areq)
 	return crypto_transfer_skcipher_request_to_engine(engine, areq);
 }
 
-int meson_skencrypt(struct skcipher_request *areq)
+static int meson_skencrypt(struct skcipher_request *areq)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
 	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
@@ -307,7 +307,7 @@ int meson_skencrypt(struct skcipher_request *areq)
 	return crypto_transfer_skcipher_request_to_engine(engine, areq);
 }
 
-int meson_cipher_init(struct crypto_tfm *tfm)
+static int meson_cipher_init(struct crypto_tfm *tfm)
 {
 	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 	struct meson_alg_template *algt;
@@ -333,7 +333,7 @@ int meson_cipher_init(struct crypto_tfm *tfm)
 	return 0;
 }
 
-void meson_cipher_exit(struct crypto_tfm *tfm)
+static void meson_cipher_exit(struct crypto_tfm *tfm)
 {
 	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 
@@ -341,8 +341,8 @@ void meson_cipher_exit(struct crypto_tfm *tfm)
 	crypto_free_skcipher(op->fallback_tfm);
 }
 
-int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
-		     unsigned int keylen)
+static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
+			    unsigned int keylen)
 {
 	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
 	struct meson_dev *mc = op->mc;
@@ -369,3 +369,89 @@ int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 
 	return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
 }
+
+static struct meson_alg_template algs[] = {
+{
+	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+	.blockmode = MESON_OPMODE_CBC,
+	.alg.skcipher.base = {
+		.base = {
+			.cra_name = "cbc(aes)",
+			.cra_driver_name = "cbc-aes-gxl",
+			.cra_priority = 400,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+				CRYPTO_ALG_NEED_FALLBACK,
+			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
+			.cra_module = THIS_MODULE,
+			.cra_alignmask = 0xf,
+			.cra_init = meson_cipher_init,
+			.cra_exit = meson_cipher_exit,
+		},
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.ivsize		= AES_BLOCK_SIZE,
+		.setkey		= meson_aes_setkey,
+		.encrypt	= meson_skencrypt,
+		.decrypt	= meson_skdecrypt,
+	},
+	.alg.skcipher.op = {
+		.do_one_request = meson_handle_cipher_request,
+	},
+},
+{
+	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+	.blockmode = MESON_OPMODE_ECB,
+	.alg.skcipher.base = {
+		.base = {
+			.cra_name = "ecb(aes)",
+			.cra_driver_name = "ecb-aes-gxl",
+			.cra_priority = 400,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+				CRYPTO_ALG_NEED_FALLBACK,
+			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
+			.cra_module = THIS_MODULE,
+			.cra_alignmask = 0xf,
+			.cra_init = meson_cipher_init,
+			.cra_exit = meson_cipher_exit,
+		},
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.setkey		= meson_aes_setkey,
+		.encrypt	= meson_skencrypt,
+		.decrypt	= meson_skdecrypt,
+	},
+	.alg.skcipher.op = {
+		.do_one_request = meson_handle_cipher_request,
+	},
+},
+};
+
+int meson_cipher_register(struct meson_dev *mc)
+{
+	return meson_register_algs(mc, algs, ARRAY_SIZE(algs));
+}
+
+void meson_cipher_unregister(struct meson_dev *mc)
+{
+	meson_unregister_algs(mc, algs, ARRAY_SIZE(algs));
+}
+
+void meson_cipher_debugfs_show(struct seq_file *seq, void *v)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(algs); i++) {
+		seq_printf(seq, "%s %s %lu %lu\n",
+			   algs[i].alg.skcipher.base.base.cra_driver_name,
+			   algs[i].alg.skcipher.base.base.cra_name,
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+			   algs[i].stat_req, algs[i].stat_fb);
+#else
+			   0ul, 0ul);
+#endif
+	}
+}
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f7c60ebffbc3..22ff2768b5e5 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -65,66 +65,6 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static struct meson_alg_template mc_algs[] = {
-{
-	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-	.blockmode = MESON_OPMODE_CBC,
-	.alg.skcipher.base = {
-		.base = {
-			.cra_name = "cbc(aes)",
-			.cra_driver_name = "cbc-aes-gxl",
-			.cra_priority = 400,
-			.cra_blocksize = AES_BLOCK_SIZE,
-			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
-				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
-				CRYPTO_ALG_NEED_FALLBACK,
-			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
-			.cra_module = THIS_MODULE,
-			.cra_alignmask = 0xf,
-			.cra_init = meson_cipher_init,
-			.cra_exit = meson_cipher_exit,
-		},
-		.min_keysize	= AES_MIN_KEY_SIZE,
-		.max_keysize	= AES_MAX_KEY_SIZE,
-		.ivsize		= AES_BLOCK_SIZE,
-		.setkey		= meson_aes_setkey,
-		.encrypt	= meson_skencrypt,
-		.decrypt	= meson_skdecrypt,
-	},
-	.alg.skcipher.op = {
-		.do_one_request = meson_handle_cipher_request,
-	},
-},
-{
-	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-	.blockmode = MESON_OPMODE_ECB,
-	.alg.skcipher.base = {
-		.base = {
-			.cra_name = "ecb(aes)",
-			.cra_driver_name = "ecb-aes-gxl",
-			.cra_priority = 400,
-			.cra_blocksize = AES_BLOCK_SIZE,
-			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
-				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
-				CRYPTO_ALG_NEED_FALLBACK,
-			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
-			.cra_module = THIS_MODULE,
-			.cra_alignmask = 0xf,
-			.cra_init = meson_cipher_init,
-			.cra_exit = meson_cipher_exit,
-		},
-		.min_keysize	= AES_MIN_KEY_SIZE,
-		.max_keysize	= AES_MAX_KEY_SIZE,
-		.setkey		= meson_aes_setkey,
-		.encrypt	= meson_skencrypt,
-		.decrypt	= meson_skdecrypt,
-	},
-	.alg.skcipher.op = {
-		.do_one_request = meson_handle_cipher_request,
-	},
-},
-};
-
 static int meson_debugfs_show(struct seq_file *seq, void *v)
 {
 	struct meson_dev *mc __maybe_unused = seq->private;
@@ -138,20 +78,8 @@ static int meson_debugfs_show(struct seq_file *seq, void *v)
 			   0ul);
 #endif
 
-	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
-		switch (mc_algs[i].type) {
-		case CRYPTO_ALG_TYPE_SKCIPHER:
-			seq_printf(seq, "%s %s %lu %lu\n",
-				   mc_algs[i].alg.skcipher.base.base.cra_driver_name,
-				   mc_algs[i].alg.skcipher.base.base.cra_name,
-#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
-				   mc_algs[i].stat_req, mc_algs[i].stat_fb);
-#else
-				   0ul, 0ul);
-#endif
-			break;
-		}
-	}
+	meson_cipher_debugfs_show(seq, v);
+
 	return 0;
 }
 DEFINE_SHOW_ATTRIBUTE(meson_debugfs);
@@ -228,38 +156,40 @@ static int meson_allocate_chanlist(struct meson_dev *mc)
 	return err;
 }
 
-static int meson_register_algs(struct meson_dev *mc)
+int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+			unsigned int count)
 {
 	int err, i;
 
-	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
-		mc_algs[i].mc = mc;
-		switch (mc_algs[i].type) {
+	for (i = 0; i < count; i++) {
+		switch (algs[i].type) {
 		case CRYPTO_ALG_TYPE_SKCIPHER:
-			err = crypto_engine_register_skcipher(&mc_algs[i].alg.skcipher);
+			err = crypto_engine_register_skcipher(&algs[i].alg.skcipher);
 			if (err) {
 				dev_err(mc->dev, "Fail to register %s\n",
-					mc_algs[i].alg.skcipher.base.base.cra_name);
-				mc_algs[i].mc = NULL;
+					algs[i].alg.skcipher.base.base.cra_name);
+				meson_unregister_algs(mc, algs, count);
 				return err;
 			}
 			break;
 		}
+		algs[i].mc = mc;
 	}
 
 	return 0;
 }
 
-static void meson_unregister_algs(struct meson_dev *mc)
+void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+			   unsigned int count)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
-		if (!mc_algs[i].mc)
+	for (i = 0; i < count; i++) {
+		if (!algs[i].mc)
 			continue;
-		switch (mc_algs[i].type) {
+		switch (algs[i].type) {
 		case CRYPTO_ALG_TYPE_SKCIPHER:
-			crypto_engine_unregister_skcipher(&mc_algs[i].alg.skcipher);
+			crypto_engine_unregister_skcipher(&algs[i].alg.skcipher);
 			break;
 		}
 	}
@@ -318,9 +248,9 @@ static int meson_crypto_probe(struct platform_device *pdev)
 	if (err)
 		goto error_flow;
 
-	err = meson_register_algs(mc);
+	err = meson_cipher_register(mc);
 	if (err)
-		goto error_alg;
+		goto error_flow;
 
 	if (IS_ENABLED(CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG)) {
 		struct dentry *dbgfs_dir;
@@ -334,8 +264,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
 	}
 
 	return 0;
-error_alg:
-	meson_unregister_algs(mc);
 error_flow:
 	meson_free_chanlist(mc, mc->flow_cnt - 1);
 	return err;
@@ -349,7 +277,7 @@ static void meson_crypto_remove(struct platform_device *pdev)
 	debugfs_remove_recursive(mc->dbgfs_dir);
 #endif
 
-	meson_unregister_algs(mc);
+	meson_cipher_unregister(mc);
 
 	meson_free_chanlist(mc, mc->flow_cnt - 1);
 }
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index e27908992ae3..0a03e8144977 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -167,10 +167,12 @@ void meson_dma_start(struct meson_dev *mc, int flow);
 
 int meson_enqueue(struct crypto_async_request *areq, u32 type);
 
-int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
-		     unsigned int keylen);
-int meson_cipher_init(struct crypto_tfm *tfm);
-void meson_cipher_exit(struct crypto_tfm *tfm);
-int meson_skdecrypt(struct skcipher_request *areq);
-int meson_skencrypt(struct skcipher_request *areq);
+int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+			unsigned int count);
+void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+			   unsigned int count);
+
+int meson_cipher_register(struct meson_dev *mc);
+void meson_cipher_unregister(struct meson_dev *mc);
+void meson_cipher_debugfs_show(struct seq_file *seq, void *v);
 int meson_handle_cipher_request(struct crypto_engine *engine, void *areq);
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:12 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:12 +0300
Subject: [PATCH v3 11/20] drivers: crypto: meson: introduce hasher
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-12-avromanov@salutedevices.com>

Introduce support for SHA1/SHA224/SHA256 hash algos.
Tested via tcrypt and custom tests.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/Makefile             |   2 +-
 drivers/crypto/amlogic/amlogic-gxl-core.c   |  24 +-
 drivers/crypto/amlogic/amlogic-gxl-hasher.c | 452 ++++++++++++++++++++
 drivers/crypto/amlogic/amlogic-gxl.h        |  49 +++
 4 files changed, 525 insertions(+), 2 deletions(-)
 create mode 100644 drivers/crypto/amlogic/amlogic-gxl-hasher.c

diff --git a/drivers/crypto/amlogic/Makefile b/drivers/crypto/amlogic/Makefile
index 39057e62c13e..4b6b388b7880 100644
--- a/drivers/crypto/amlogic/Makefile
+++ b/drivers/crypto/amlogic/Makefile
@@ -1,2 +1,2 @@
 obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic-gxl-crypto.o
-amlogic-gxl-crypto-y := amlogic-gxl-core.o amlogic-gxl-cipher.o
+amlogic-gxl-crypto-y := amlogic-gxl-core.o amlogic-gxl-cipher.o amlogic-gxl-hasher.o
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f93e14f5717d..f3b5e004b3a5 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -20,6 +20,9 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/internal/hash.h>
+#include <linux/dma-mapping.h>
 
 #include "amlogic-gxl.h"
 
@@ -172,6 +175,15 @@ int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
 				return err;
 			}
 			break;
+		case CRYPTO_ALG_TYPE_AHASH:
+			err = crypto_engine_register_ahash(&algs[i].alg.ahash);
+			if (err) {
+				dev_err(mc->dev, "Fail to register %s\n",
+					algs[i].alg.ahash.base.halg.base.cra_name);
+				meson_unregister_algs(mc, algs, count);
+				return err;
+			}
+			break;
 		}
 		algs[i].mc = mc;
 	}
@@ -191,6 +203,9 @@ void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs
 		case CRYPTO_ALG_TYPE_SKCIPHER:
 			crypto_engine_unregister_skcipher(&algs[i].alg.skcipher);
 			break;
+		case CRYPTO_ALG_TYPE_AHASH:
+			crypto_engine_unregister_ahash(&algs[i].alg.ahash);
+			break;
 		}
 	}
 }
@@ -258,13 +273,20 @@ static int meson_crypto_probe(struct platform_device *pdev)
 
 		dbgfs_dir = debugfs_create_dir("gxl-crypto", NULL);
 		debugfs_create_file("stats", 0444, dbgfs_dir, mc, &meson_debugfs_fops);
-
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
 		mc->dbgfs_dir = dbgfs_dir;
 #endif
 	}
 
+	err = meson_hasher_register(mc);
+	if (err)
+		goto error_hasher;
+
 	return 0;
+
+error_hasher:
+	meson_cipher_unregister(mc);
+
 error_flow:
 	meson_free_chanlist(mc, mc->flow_cnt - 1);
 	return err;
diff --git a/drivers/crypto/amlogic/amlogic-gxl-hasher.c b/drivers/crypto/amlogic/amlogic-gxl-hasher.c
new file mode 100644
index 000000000000..04f85cd4d97f
--- /dev/null
+++ b/drivers/crypto/amlogic/amlogic-gxl-hasher.c
@@ -0,0 +1,452 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hardware asynchronous hasher for Amlogic SoC's.
+ *
+ * Copyright (c) 2023, SaluteDevices. All Rights Reserved.
+ *
+ * Author: Alexey Romanov <avromanov at salutedevices.com>
+ */
+
+#include <linux/crypto.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <crypto/internal/hash.h>
+#include <crypto/sha1.h>
+#include <crypto/sha2.h>
+
+#include "amlogic-gxl.h"
+
+static int meson_sha_init(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+
+	memset(rctx, 0, sizeof(struct meson_hasher_req_ctx));
+
+	rctx->flow = meson_get_engine_number(tctx->mc);
+	rctx->begin_req = true;
+
+	return 0;
+}
+
+static int meson_sha_update(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct crypto_engine *engine = tctx->mc->chanlist[rctx->flow].engine;
+
+	return crypto_transfer_hash_request_to_engine(engine, req);
+}
+
+static int meson_sha_final(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct crypto_engine *engine = tctx->mc->chanlist[rctx->flow].engine;
+
+	rctx->final_req = true;
+
+	return crypto_transfer_hash_request_to_engine(engine, req);
+}
+
+static int meson_hasher_req_map(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_dev *mc = tctx->mc;
+	int ret;
+
+	if (!req->nbytes)
+		return 0;
+
+	ret = dma_map_sg(mc->dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
+	if (!ret) {
+		dev_err(mc->dev, "Cannot DMA MAP request data\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void meson_hasher_req_unmap(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_dev *mc = tctx->mc;
+
+	if (!req->nbytes)
+		return;
+
+	dma_unmap_sg(mc->dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
+}
+
+struct hasher_ctx {
+	struct crypto_async_request *areq;
+
+	unsigned int tloffset;
+	unsigned int nbytes;
+	unsigned int todo;
+
+	dma_addr_t state_addr;
+	dma_addr_t src_addr;
+	unsigned int src_offset;
+	struct scatterlist *src_sg;
+};
+
+static bool meson_final(struct hasher_ctx *ctx)
+{
+	struct ahash_request *req = ahash_request_cast(ctx->areq);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+
+	return !ctx->nbytes && rctx->final_req;
+}
+
+static int meson_fill_partial_buffer(struct hasher_ctx *ctx, unsigned int len)
+{
+	struct ahash_request *req = ahash_request_cast(ctx->areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct meson_dev *mc = tctx->mc;
+	unsigned int blocksize = crypto_ahash_blocksize(tfm);
+	unsigned int copy;
+
+	if (len) {
+		copy = min(blocksize - rctx->partial_size, len);
+		memcpy(rctx->partial + rctx->partial_size,
+				sg_virt(ctx->src_sg) + ctx->src_offset, copy);
+
+		rctx->partial_size += copy;
+		ctx->nbytes -= copy;
+		ctx->src_offset += copy;
+	}
+
+	if (rctx->partial_size == blocksize || meson_final(ctx)) {
+		rctx->partial_addr = dma_map_single(mc->dev,
+						   rctx->partial,
+						   rctx->partial_size,
+						   DMA_TO_DEVICE);
+		if (dma_mapping_error(mc->dev, rctx->partial_addr)) {
+			dev_err(mc->dev, "Cannot DMA MAP SHA partial buffer\n");
+			return -ENOMEM;
+		}
+
+		rctx->partial_mapped = true;
+		ctx->todo = rctx->partial_size;
+		ctx->src_addr = rctx->partial_addr;
+	}
+
+	return 0;
+}
+
+static unsigned int meson_setup_data_descs(struct hasher_ctx *ctx)
+{
+	struct ahash_request *req = ahash_request_cast(ctx->areq);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_dev *mc = tctx->mc;
+	struct meson_flow *flow = &mc->chanlist[rctx->flow];
+	struct hash_alg_common *alg = crypto_hash_alg_common(tfm);
+	struct meson_alg_template *algt = container_of(alg,
+		struct meson_alg_template, alg.ahash.base.halg);
+	struct meson_desc *desc = &flow->tl[ctx->tloffset];
+	u32 v;
+
+	ctx->tloffset++;
+
+	v = DESC_OWN | DESC_ENCRYPTION | DESC_OPMODE_SHA |
+	    ctx->todo | algt->blockmode;
+	if (rctx->begin_req) {
+		rctx->begin_req = false;
+		v |= DESC_BEGIN;
+	}
+
+	if (!ctx->nbytes && rctx->final_req) {
+		rctx->final_req = false;
+		v |= DESC_END;
+	}
+
+	if (!ctx->nbytes || ctx->tloffset == MAXDESC || rctx->partial_mapped)
+		v |= DESC_LAST;
+
+	desc->t_src = cpu_to_le32(ctx->src_addr);
+	desc->t_dst = cpu_to_le32(ctx->state_addr);
+	desc->t_status = cpu_to_le32(v);
+
+	return v & DESC_LAST;
+}
+
+static int meson_kick_hardware(struct hasher_ctx *ctx)
+{
+	struct ahash_request *req = ahash_request_cast(ctx->areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_dev *mc = tctx->mc;
+	struct meson_flow *flow = &mc->chanlist[rctx->flow];
+	int ret;
+
+	reinit_completion(&flow->complete);
+	meson_dma_start(mc, rctx->flow);
+
+	ret = wait_for_completion_timeout(&flow->complete,
+					  msecs_to_jiffies(500));
+	if (ret == 0) {
+		dev_err(mc->dev, "DMA timeout for flow %d\n", rctx->flow);
+		return -EINVAL;
+	} else if (ret < 0) {
+		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", ret);
+		return ret;
+	}
+
+	if (rctx->partial_mapped) {
+		dma_unmap_single(mc->dev, rctx->partial_addr,
+				 rctx->partial_size,
+				 DMA_TO_DEVICE);
+		rctx->partial_size = 0;
+		rctx->partial_mapped = false;
+	}
+
+	ctx->tloffset = 0;
+
+	return 0;
+}
+
+static void meson_setup_state_descs(struct hasher_ctx *ctx)
+{
+	struct ahash_request *req = ahash_request_cast(ctx->areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_dev *mc = tctx->mc;
+	struct meson_desc *desc;
+	int i;
+
+	if (ctx->tloffset || rctx->begin_req)
+		return;
+
+	for (i = 0; i < mc->pdata->setup_desc_cnt; i++) {
+		int offset = i * 16;
+
+		desc = &mc->chanlist[rctx->flow].tl[ctx->tloffset];
+		desc->t_src = cpu_to_le32(ctx->state_addr + offset);
+		desc->t_dst = cpu_to_le32(offset);
+		desc->t_status = cpu_to_le32(MESON_SHA_BUFFER_SIZE |
+					     DESC_MODE_KEY | DESC_OWN);
+
+		ctx->tloffset++;
+	}
+}
+
+static int meson_hasher_do_one_request(struct crypto_engine *engine, void *areq)
+{
+	struct ahash_request *req = ahash_request_cast(areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct meson_dev *mc = tctx->mc;
+	struct hasher_ctx ctx = {
+		.tloffset = 0,
+		.src_offset = 0,
+		.nbytes = req->nbytes,
+		.src_sg = req->src,
+		.areq = areq,
+	};
+	unsigned int blocksize = crypto_ahash_blocksize(tfm);
+	unsigned int digest_size = crypto_ahash_digestsize(tfm);
+	bool final_req = rctx->final_req;
+	int ret;
+
+	ctx.state_addr = dma_map_single(mc->dev, rctx->state,
+			   sizeof(rctx->state), DMA_BIDIRECTIONAL);
+	ret = dma_mapping_error(mc->dev, ctx.state_addr);
+	if (ret) {
+		dev_err(mc->dev, "Cannot DMA MAP SHA state buffer");
+		goto fail_map_single;
+	}
+
+	ret = meson_hasher_req_map(req);
+	if (ret)
+		goto fail_map_req;
+
+	for (;;) {
+		unsigned int len = ctx.src_sg ?
+			min(sg_dma_len(ctx.src_sg) - ctx.src_offset, ctx.nbytes) : 0;
+
+		ctx.src_addr = 0;
+		ctx.todo = 0;
+
+		if (!rctx->final_req && !ctx.nbytes)
+			break;
+
+		meson_setup_state_descs(&ctx);
+
+		if (rctx->partial_size && rctx->partial_size < blocksize) {
+			ret = meson_fill_partial_buffer(&ctx, len);
+			if (ret)
+				goto fail;
+		} else if (len && len < blocksize) {
+			memcpy(rctx->partial, sg_virt(ctx.src_sg) + ctx.src_offset, len);
+
+			rctx->partial_size = len;
+			ctx.nbytes -= len;
+			ctx.src_offset += len;
+		} else if (len) {
+			ctx.src_addr = sg_dma_address(ctx.src_sg) + ctx.src_offset;
+			ctx.todo = min(rounddown(DESC_MAXLEN, blocksize),
+					rounddown(len, blocksize));
+			ctx.nbytes -= ctx.todo;
+			ctx.src_offset += ctx.todo;
+		}
+
+		if (ctx.src_sg && ctx.src_offset == sg_dma_len(ctx.src_sg)) {
+			ctx.src_offset = 0;
+			ctx.src_sg = sg_next(ctx.src_sg);
+		}
+
+		if (!ctx.todo && ctx.nbytes)
+			continue;
+
+		if (!ctx.todo && !rctx->final_req && !ctx.tloffset)
+			continue;
+
+		if (meson_setup_data_descs(&ctx)) {
+			ret = meson_kick_hardware(&ctx);
+			if (ret)
+				goto fail;
+		}
+	}
+
+fail:
+	meson_hasher_req_unmap(req);
+
+fail_map_req:
+	dma_unmap_single(mc->dev, ctx.state_addr, sizeof(rctx->state),
+			 DMA_BIDIRECTIONAL);
+
+fail_map_single:
+	if (final_req && ret == 0)
+		memcpy(req->result, rctx->state, digest_size);
+
+	local_bh_disable();
+	crypto_finalize_hash_request(engine, req, ret);
+	local_bh_enable();
+
+	return ret;
+}
+
+static int meson_hasher_init(struct crypto_tfm *tfm)
+{
+	struct meson_hasher_tfm_ctx *tctx = crypto_tfm_ctx(tfm);
+	struct crypto_ahash *atfm = __crypto_ahash_cast(tfm);
+	struct hash_alg_common *alg = crypto_hash_alg_common(atfm);
+	struct meson_alg_template *algt = container_of(alg,
+		struct meson_alg_template, alg.ahash.base.halg);
+
+	crypto_ahash_set_reqsize(atfm, crypto_ahash_statesize(atfm));
+
+	memset(tctx, 0, sizeof(struct meson_hasher_tfm_ctx));
+
+	tctx->mc = algt->mc;
+
+	return 0;
+}
+
+static struct meson_alg_template mc_algs[] = {
+{
+	.type = CRYPTO_ALG_TYPE_AHASH,
+	.blockmode = DESC_MODE_SHA1,
+	.alg.ahash.base = {
+		.halg = {
+			.base = {
+				.cra_name = "sha1",
+				.cra_driver_name = "sha1-gxl",
+				.cra_priority = 400,
+				.cra_blocksize = SHA1_BLOCK_SIZE,
+				.cra_flags = CRYPTO_ALG_ASYNC,
+				.cra_ctxsize = sizeof(struct meson_hasher_tfm_ctx),
+				.cra_module = THIS_MODULE,
+				.cra_alignmask = 0,
+				.cra_init = meson_hasher_init,
+			},
+			.digestsize = SHA1_DIGEST_SIZE,
+			.statesize = sizeof(struct meson_hasher_req_ctx),
+		},
+		.init = meson_sha_init,
+		.update = meson_sha_update,
+		.final = meson_sha_final,
+	},
+	.alg.ahash.op = {
+		.do_one_request = meson_hasher_do_one_request,
+	},
+},
+{
+	.type = CRYPTO_ALG_TYPE_AHASH,
+	.blockmode = DESC_MODE_SHA224,
+	.alg.ahash.base = {
+		.halg = {
+			.base = {
+				.cra_name = "sha224",
+				.cra_driver_name = "sha224-gxl",
+				.cra_priority = 400,
+				.cra_blocksize = SHA224_BLOCK_SIZE,
+				.cra_flags = CRYPTO_ALG_ASYNC,
+				.cra_ctxsize = sizeof(struct meson_hasher_tfm_ctx),
+				.cra_module = THIS_MODULE,
+				.cra_alignmask = 0,
+				.cra_init = meson_hasher_init,
+			},
+			.digestsize = SHA224_DIGEST_SIZE,
+			.statesize = sizeof(struct meson_hasher_req_ctx),
+		},
+		.init = meson_sha_init,
+		.update = meson_sha_update,
+		.final = meson_sha_final,
+	},
+	.alg.ahash.op = {
+		.do_one_request = meson_hasher_do_one_request,
+	},
+},
+{
+	.type = CRYPTO_ALG_TYPE_AHASH,
+	.blockmode = DESC_MODE_SHA256,
+	.alg.ahash.base = {
+		.halg = {
+			.base = {
+				.cra_name = "sha256",
+				.cra_driver_name = "sha256-gxl",
+				.cra_priority = 400,
+				.cra_blocksize = SHA256_BLOCK_SIZE,
+				.cra_flags = CRYPTO_ALG_ASYNC,
+				.cra_ctxsize = sizeof(struct meson_hasher_tfm_ctx),
+				.cra_module = THIS_MODULE,
+				.cra_alignmask = 0,
+				.cra_init = meson_hasher_init,
+			},
+			.digestsize = SHA256_DIGEST_SIZE,
+			.statesize = sizeof(struct meson_hasher_req_ctx),
+		},
+		.init = meson_sha_init,
+		.update = meson_sha_update,
+		.final = meson_sha_final,
+	},
+	.alg.ahash.op = {
+		.do_one_request = meson_hasher_do_one_request,
+	},
+},
+};
+
+int meson_hasher_register(struct meson_dev *mc)
+{
+	return meson_register_algs(mc, mc_algs, ARRAY_SIZE(mc_algs));
+}
+
+void meson_hasher_unregister(struct meson_dev *mc)
+{
+	meson_unregister_algs(mc, mc_algs, ARRAY_SIZE(mc_algs));
+}
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index e1453dd2e9f4..a07b4f6b3bcc 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -5,6 +5,7 @@
  * Copyright (C) 2018-2019 Corentin LABBE <clabbe at baylibre.com>
  */
 #include <crypto/aes.h>
+#include <crypto/sha2.h>
 #include <crypto/engine.h>
 #include <crypto/skcipher.h>
 #include <linux/debugfs.h>
@@ -23,13 +24,25 @@
 
 #define DESC_OPMODE_ECB (0 << 26)
 #define DESC_OPMODE_CBC (1 << 26)
+#define DESC_OPMODE_SHA (0 << 26)
 
 #define DESC_MAXLEN ((1 << 17) - 1)
 
+#define DESC_MODE_SHA1   (0x5 << 20)
+#define DESC_MODE_SHA224 (0x7 << 20)
+#define DESC_MODE_SHA256 (0x6 << 20)
+
 #define DESC_LAST BIT(18)
+#define DESC_BEGIN BIT(24)
+#define DESC_END BIT(25)
 #define DESC_ENCRYPTION BIT(28)
 #define DESC_OWN BIT(31)
 
+#define MESON_SHA_BUFFER_SIZE (SHA256_DIGEST_SIZE + 16)
+
+#define MESON_SHA_BEGIN BIT(1)
+#define MESON_SHA_FINAL BIT(2)
+
 /*
  * struct meson_desc - Descriptor for DMA operations
  * Note that without datasheet, some are unknown
@@ -143,6 +156,38 @@ struct meson_cipher_tfm_ctx {
 	struct crypto_skcipher *fallback_tfm;
 };
 
+/*
+ * struct meson_hasher_req_ctx - context for a hasher request
+ * @state:		state data
+ * @partial:		partial buffer data. Contains sent data which
+ *			size < blocksize
+ * @partial_size:	size of the partial buffer
+ * @partial_addr:	physical address of partial buffer
+ * @partial_mapped:	indicates is partial buffer currently mapped or not
+ * @flags:		request flags (for example, is this final req or not)
+ * @flow:		the flow to use for this request
+ */
+struct meson_hasher_req_ctx {
+	u8 state[SHA256_DIGEST_SIZE + 16] ____cacheline_aligned;
+	u8 partial[SHA256_BLOCK_SIZE] ____cacheline_aligned;
+	unsigned int partial_size ____cacheline_aligned;
+	dma_addr_t partial_addr;
+	bool partial_mapped;
+
+	bool begin_req;
+	bool final_req;
+	int flow;
+};
+
+/*
+ * struct meson_hasher_tfm_ctx - context for a hasher TFM
+ * @enginectx:		crypto_engine used by this TFM
+ * @mc:			pointer to the private data of driver handling this TFM
+ */
+struct meson_hasher_tfm_ctx {
+	struct meson_dev *mc;
+};
+
 /*
  * struct meson_alg_template - crypto_alg template
  * @type:		the CRYPTO_ALG_TYPE for this template
@@ -157,6 +202,7 @@ struct meson_alg_template {
 	u32 blockmode;
 	union {
 		struct skcipher_engine_alg skcipher;
+		struct ahash_engine_alg ahash;
 	} alg;
 	struct meson_dev *mc;
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
@@ -180,3 +226,6 @@ int meson_cipher_register(struct meson_dev *mc);
 void meson_cipher_unregister(struct meson_dev *mc);
 void meson_cipher_debugfs_show(struct seq_file *seq, void *v);
 int meson_handle_cipher_request(struct crypto_engine *engine, void *areq);
+
+int meson_hasher_register(struct meson_dev *mc);
+void meson_hasher_unregister(struct meson_dev *mc);
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:13 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:13 +0300
Subject: [PATCH v3 12/20] drivers: crypto: meson: add support for AES-CTR
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-13-avromanov@salutedevices.com>

This patch adds support for AES-CTR algorithm.
Tested via tcrypt and custom tests.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 44 +++++++++++++++++++--
 drivers/crypto/amlogic/amlogic-gxl.h        |  1 +
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 3f42b2cc568d..828109f4a1c3 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -154,7 +154,7 @@ static void meson_setup_keyiv_descs(struct cipher_ctx *ctx)
 	if (ctx->tloffset)
 		return;
 
-	if (blockmode == DESC_OPMODE_CBC) {
+	if (blockmode == DESC_OPMODE_CBC || blockmode == DESC_OPMODE_CTR) {
 		memcpy(op->keyiv + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
 		dma_sync_single_for_device(mc->dev, ctx->keyiv.addr,
 					   ctx->keyiv.len, DMA_TO_DEVICE);
@@ -186,6 +186,7 @@ static bool meson_setup_data_descs(struct cipher_ctx *ctx)
 	struct meson_desc *desc = &mc->chanlist[rctx->flow].tl[ctx->tloffset];
 	unsigned int blocksize = crypto_skcipher_blocksize(tfm);
 	unsigned int blockmode = algt->blockmode;
+	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
 	unsigned int maxlen = rounddown(DESC_MAXLEN, blocksize);
 	unsigned int todo;
 	u32 v;
@@ -204,8 +205,15 @@ static bool meson_setup_data_descs(struct cipher_ctx *ctx)
 	ctx->src_offset += todo;
 	ctx->dst_offset += todo;
 
+	if (blockmode == DESC_OPMODE_CTR) {
+		unsigned int nblocks = todo / blocksize;
+
+		while (nblocks--)
+			crypto_inc(ctx->areq->iv, ivsize);
+	}
+
 	v = DESC_OWN | blockmode | op->keymode | todo;
-	if (rctx->op_dir == MESON_ENCRYPT)
+	if (rctx->op_dir == MESON_ENCRYPT || blockmode == DESC_OPMODE_CTR)
 		v |= DESC_ENCRYPTION;
 
 	if (!ctx->cryptlen || ctx->tloffset == MAXDESC)
@@ -322,7 +330,8 @@ static int meson_cipher(struct skcipher_request *areq)
 	if (ctx.keyiv.len == AES_KEYSIZE_192)
 		ctx.keyiv.len = AES_MAX_KEY_SIZE;
 
-	if (algt->blockmode == DESC_OPMODE_CBC) {
+	if (algt->blockmode == DESC_OPMODE_CBC ||
+		algt->blockmode == DESC_OPMODE_CTR) {
 		memcpy(op->keyiv + AES_MAX_KEY_SIZE, areq->iv, ivsize);
 		ctx.keyiv.len = AES_MAX_KEY_SIZE + ivsize;
 	}
@@ -535,6 +544,35 @@ static struct meson_alg_template algs[] = {
 		.do_one_request = meson_handle_cipher_request,
 	},
 },
+{
+	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+	.blockmode = DESC_OPMODE_CTR,
+	.alg.skcipher.base = {
+		.base = {
+			.cra_name = "ctr(aes)",
+			.cra_driver_name = "ctr-aes-gxl",
+			.cra_priority = 400,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+				CRYPTO_ALG_NEED_FALLBACK,
+			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
+			.cra_module = THIS_MODULE,
+			.cra_alignmask = 0xf,
+			.cra_init = meson_cipher_init,
+			.cra_exit = meson_cipher_exit,
+		},
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.ivsize		= AES_BLOCK_SIZE,
+		.setkey		= meson_aes_setkey,
+		.encrypt	= meson_skencrypt,
+		.decrypt	= meson_skdecrypt,
+	},
+	.alg.skcipher.op = {
+		.do_one_request = meson_handle_cipher_request,
+	},
+},
 };
 
 int meson_cipher_register(struct meson_dev *mc)
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index a07b4f6b3bcc..7f6d91e7b365 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -24,6 +24,7 @@
 
 #define DESC_OPMODE_ECB (0 << 26)
 #define DESC_OPMODE_CBC (1 << 26)
+#define DESC_OPMODE_CTR (2 << 26)
 #define DESC_OPMODE_SHA (0 << 26)
 
 #define DESC_MAXLEN ((1 << 17) - 1)
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:11 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:11 +0300
Subject: [PATCH v3 10/20] drivers: crypto: meson: avoid kzalloc in engine thread
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-11-avromanov@salutedevices.com>

It makes no sense to allocate memory via kzalloc, we
can use static buffer, speedup data processing and
don't think about kfree() calls.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 24 ++++++++-------------
 drivers/crypto/amlogic/amlogic-gxl.h        |  6 +++---
 2 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 9c96e7b65e1e..3f42b2cc568d 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -155,8 +155,7 @@ static void meson_setup_keyiv_descs(struct cipher_ctx *ctx)
 		return;
 
 	if (blockmode == DESC_OPMODE_CBC) {
-		memcpy(op->key + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
-		ctx->keyiv.len = AES_MAX_KEY_SIZE + ivsize;
+		memcpy(op->keyiv + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
 		dma_sync_single_for_device(mc->dev, ctx->keyiv.addr,
 					   ctx->keyiv.len, DMA_TO_DEVICE);
 	}
@@ -319,16 +318,16 @@ static int meson_cipher(struct skcipher_request *areq)
 	mc->chanlist[rctx->flow].stat_req++;
 #endif
 
-	op->key = kzalloc(48, GFP_KERNEL | GFP_DMA);
-	if (!op.key)
-		return -ENOMEM;
-
-	memcpy(op->key, op->key, op->keylen);
 	ctx.keyiv.len = op->keylen;
 	if (ctx.keyiv.len == AES_KEYSIZE_192)
 		ctx.keyiv.len = AES_MAX_KEY_SIZE;
 
-	ctx.keyiv.addr = dma_map_single(mc->dev, op->key, ctx.keyiv.len,
+	if (algt->blockmode == DESC_OPMODE_CBC) {
+		memcpy(op->keyiv + AES_MAX_KEY_SIZE, areq->iv, ivsize);
+		ctx.keyiv.len = AES_MAX_KEY_SIZE + ivsize;
+	}
+
+	ctx.keyiv.addr = dma_map_single(mc->dev, op->keyiv, ctx.keyiv.len,
 				  DMA_TO_DEVICE);
 	err = dma_mapping_error(mc->dev, ctx.keyiv.addr);
 	if (err) {
@@ -366,8 +365,6 @@ static int meson_cipher(struct skcipher_request *areq)
 	meson_unmap_scatterlist(areq, mc);
 
 theend:
-	kfree_sensitive(op->key);
-
 	return err;
 }
 
@@ -450,7 +447,6 @@ static void meson_cipher_exit(struct crypto_tfm *tfm)
 {
 	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 
-	kfree_sensitive(op->key);
 	crypto_free_skcipher(op->fallback_tfm);
 }
 
@@ -474,11 +470,9 @@ static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 		dev_dbg(mc->dev, "ERROR: Invalid keylen %u\n", keylen);
 		return -EINVAL;
 	}
-	kfree_sensitive(op->key);
+
+	memcpy(op->keyiv, key, keylen);
 	op->keylen = keylen;
-	op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
-	if (!op->key)
-		return -ENOMEM;
 
 	return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
 }
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index eb2f8cd72b65..e1453dd2e9f4 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -129,15 +129,15 @@ struct meson_cipher_req_ctx {
 
 /*
  * struct meson_cipher_tfm_ctx - context for a skcipher TFM
- * @key:		pointer to key data
+ * @keyiv:		key data
  * @keylen:		len of the key
  * @keymode:		The keymode(type and size of key) associated with this TFM
  * @mc:			pointer to the private data of driver handling this TFM
  * @fallback_tfm:	pointer to the fallback TFM
  */
 struct meson_cipher_tfm_ctx {
-	u32 *key;
-	u32 keylen;
+	u8 keyiv[AES_MAX_KEY_SIZE + AES_BLOCK_SIZE] ____cacheline_aligned;
+	u32 keylen ____cacheline_aligned;
 	u32 keymode;
 	struct meson_dev *mc;
 	struct crypto_skcipher *fallback_tfm;
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:09 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:09 +0300
Subject: [PATCH v3 08/20] drivers: crypto: meson: cleanup defines
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-9-avromanov@salutedevices.com>

It is bad to use hardcoded values directly in the code.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 24 ++++++++++-----------
 drivers/crypto/amlogic/amlogic-gxl.h        | 16 ++++++++------
 2 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index bc3092a8a2c2..c662c4b86e97 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -141,8 +141,8 @@ static int meson_cipher(struct skcipher_request *areq)
 						 ivsize, 0);
 		}
 	}
-	if (keyivlen == 24)
-		keyivlen = 32;
+	if (keyivlen == AES_KEYSIZE_192)
+		keyivlen = AES_MAX_KEY_SIZE;
 
 	phykeyiv = dma_map_single(mc->dev, bkeyiv, keyivlen,
 				  DMA_TO_DEVICE);
@@ -161,7 +161,7 @@ static int meson_cipher(struct skcipher_request *areq)
 		todo = min(keyivlen - eat, 16u);
 		desc->t_src = cpu_to_le32(phykeyiv + i * 16);
 		desc->t_dst = cpu_to_le32(i * 16);
-		v = (MODE_KEY << 20) | DESC_OWN | 16;
+		v = DESC_MODE_KEY | DESC_OWN | 16;
 		desc->t_status = cpu_to_le32(v);
 
 		eat += todo;
@@ -205,7 +205,7 @@ static int meson_cipher(struct skcipher_request *areq)
 		desc->t_src = cpu_to_le32(sg_dma_address(src_sg));
 		desc->t_dst = cpu_to_le32(sg_dma_address(dst_sg));
 		todo = min(len, sg_dma_len(src_sg));
-		v = (op->keymode << 20) | DESC_OWN | todo | (algt->blockmode << 26);
+		v = op->keymode | DESC_OWN | todo | algt->blockmode;
 		if (rctx->op_dir)
 			v |= DESC_ENCRYPTION;
 		len -= todo;
@@ -348,14 +348,14 @@ static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 	struct meson_dev *mc = op->mc;
 
 	switch (keylen) {
-	case 128 / 8:
-		op->keymode = MODE_AES_128;
+	case AES_KEYSIZE_128:
+		op->keymode = DESC_MODE_AES_128;
 		break;
-	case 192 / 8:
-		op->keymode = MODE_AES_192;
+	case AES_KEYSIZE_192:
+		op->keymode = DESC_MODE_AES_192;
 		break;
-	case 256 / 8:
-		op->keymode = MODE_AES_256;
+	case AES_KEYSIZE_256:
+		op->keymode = DESC_MODE_AES_256;
 		break;
 	default:
 		dev_dbg(mc->dev, "ERROR: Invalid keylen %u\n", keylen);
@@ -373,7 +373,7 @@ static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 static struct meson_alg_template algs[] = {
 {
 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-	.blockmode = MESON_OPMODE_CBC,
+	.blockmode = DESC_OPMODE_CBC,
 	.alg.skcipher.base = {
 		.base = {
 			.cra_name = "cbc(aes)",
@@ -402,7 +402,7 @@ static struct meson_alg_template algs[] = {
 },
 {
 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-	.blockmode = MESON_OPMODE_ECB,
+	.blockmode = DESC_OPMODE_ECB,
 	.alg.skcipher.base = {
 		.base = {
 			.cra_name = "ecb(aes)",
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 0a03e8144977..a0d83c82906d 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -11,19 +11,21 @@
 #include <linux/crypto.h>
 #include <linux/scatterlist.h>
 
-#define MODE_KEY 1
-#define MODE_AES_128 0x8
-#define MODE_AES_192 0x9
-#define MODE_AES_256 0xa
-
 #define MESON_DECRYPT 0
 #define MESON_ENCRYPT 1
 
-#define MESON_OPMODE_ECB 0
-#define MESON_OPMODE_CBC 1
+#define DESC_MODE_KEY (0x1 << 20)
+#define DESC_MODE_AES_128 (0x8 << 20)
+#define DESC_MODE_AES_192 (0x9 << 20)
+#define DESC_MODE_AES_256 (0xa << 20)
 
 #define MAXDESC 64
 
+#define DESC_OPMODE_ECB (0 << 26)
+#define DESC_OPMODE_CBC (1 << 26)
+
+#define DESC_MAXLEN ((1 << 17) - 1)
+
 #define DESC_LAST BIT(18)
 #define DESC_ENCRYPTION BIT(28)
 #define DESC_OWN BIT(31)
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:19 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:19 +0300
Subject: [PATCH v3 18/20] arch: arm64: dts: meson: s4: add crypto node
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-19-avromanov@salutedevices.com>

This patch adds a crypto node declaration for Amlogic S4-series.
With the Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 arch/arm64/boot/dts/amlogic/meson-s4.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
index ce90b35686a2..dc05e2c5da3b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -339,6 +339,12 @@ mux {
 
 			};
 
+			crypto: crypto at 440400 {
+				compatible = "amlogic,s4-crypto", "amlogic,g12a-crypto";
+				reg = <0x0 0x440400 0x0 0x48>;
+				interrupts = <GIC_SPI 24 IRQ_TYPE_EDGE_RISING>;
+			};
+
 			gpio_intc: interrupt-controller at 4080 {
 				compatible = "amlogic,meson-s4-gpio-intc",
 					     "amlogic,meson-gpio-intc";
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:18 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:18 +0300
Subject: [PATCH v3 17/20] arch: arm64: dts: meson: a1: add crypto node
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-18-avromanov@salutedevices.com>

This patch adds a crypto node declaration. With the
Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
index cf150f568335..f0d09fbfd694 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
@@ -653,6 +653,13 @@ sd_emmc: sd at 10000 {
 				power-domains = <&pwrc PWRC_SD_EMMC_ID>;
 				status = "disabled";
 			};
+
+			crypto: crypto at 6000 {
+				compatible = "amlogic,a1-crypto", "amlogic,g12a-crypto";
+				reg = <0x0 0x6000 0x0 0x48>;
+				interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>;
+				power-domains = <&pwrc PWRC_DMA_ID>;
+			};
 		};
 
 		usb: usb at fe004400 {
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:10 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:10 +0300
Subject: [PATCH v3 09/20] drivers: crypto: meson: process more than MAXDESCS descriptors
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-10-avromanov@salutedevices.com>

1. The old alhorithm was not designed to process a large
amount of memory, and therefore gave incorrect results.

2. Not all Amlogic SoC's use 3 KEY/IV descriptors.
Add keyiv descriptors count parameter to platform data.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 443 ++++++++++++--------
 drivers/crypto/amlogic/amlogic-gxl-core.c   |   1 +
 drivers/crypto/amlogic/amlogic-gxl.h        |   2 +
 3 files changed, 281 insertions(+), 165 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index c662c4b86e97..9c96e7b65e1e 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -17,35 +17,41 @@
 #include <crypto/internal/skcipher.h>
 #include "amlogic-gxl.h"
 
-static bool meson_cipher_need_fallback(struct skcipher_request *areq)
+static bool meson_cipher_need_fallback_sg(struct skcipher_request *areq,
+					  struct scatterlist *sg)
 {
-	struct scatterlist *src_sg = areq->src;
-	struct scatterlist *dst_sg = areq->dst;
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+	unsigned int blocksize = crypto_skcipher_blocksize(tfm);
+	unsigned int cryptlen = areq->cryptlen;
+
+	while (cryptlen) {
+		unsigned int len = min(cryptlen, sg->length);
+
+		if (!IS_ALIGNED(sg->offset, sizeof(u32)))
+			return true;
+		if (len % blocksize != 0)
+			return true;
+
+		cryptlen -= len;
+		sg = sg_next(sg);
+	}
+
+	return false;
+}
 
+static bool meson_cipher_need_fallback(struct skcipher_request *areq)
+{
 	if (areq->cryptlen == 0)
 		return true;
 
-	if (sg_nents(src_sg) != sg_nents(dst_sg))
+	if (meson_cipher_need_fallback_sg(areq, areq->src))
 		return true;
 
-	/* KEY/IV descriptors use 3 desc */
-	if (sg_nents(src_sg) > MAXDESC - 3 || sg_nents(dst_sg) > MAXDESC - 3)
-		return true;
+	if (areq->dst == areq->src)
+		return false;
 
-	while (src_sg && dst_sg) {
-		if ((src_sg->length % 16) != 0)
-			return true;
-		if ((dst_sg->length % 16) != 0)
-			return true;
-		if (src_sg->length != dst_sg->length)
-			return true;
-		if (!IS_ALIGNED(src_sg->offset, sizeof(u32)))
-			return true;
-		if (!IS_ALIGNED(dst_sg->offset, sizeof(u32)))
-			return true;
-		src_sg = sg_next(src_sg);
-		dst_sg = sg_next(dst_sg);
-	}
+	if (meson_cipher_need_fallback_sg(areq, areq->dst))
+		return true;
 
 	return false;
 }
@@ -76,6 +82,211 @@ static int meson_cipher_do_fallback(struct skcipher_request *areq)
 	return err;
 }
 
+struct cipher_ctx {
+	struct {
+		dma_addr_t addr;
+		unsigned int len;
+	} keyiv;
+
+	struct skcipher_request *areq;
+	struct scatterlist *src_sg;
+	struct scatterlist *dst_sg;
+
+	unsigned int src_offset;
+	unsigned int dst_offset;
+	unsigned int cryptlen;
+	unsigned int tloffset;
+};
+
+static int meson_map_scatterlist(struct skcipher_request *areq, struct meson_dev *mc)
+{
+	int nr_sgs, nr_sgd;
+
+	if (areq->src == areq->dst) {
+		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
+							DMA_BIDIRECTIONAL);
+		if (!nr_sgs) {
+			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
+			return -EINVAL;
+		}
+	} else {
+		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
+							DMA_TO_DEVICE);
+		if (!nr_sgs) {
+			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
+			return -EINVAL;
+		}
+
+		nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
+							DMA_FROM_DEVICE);
+		if (!nr_sgd) {
+			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void meson_unmap_scatterlist(struct skcipher_request *areq, struct meson_dev *mc)
+{
+	if (areq->src == areq->dst) {
+		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL);
+	} else {
+		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
+		dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE);
+	}
+}
+
+static void meson_setup_keyiv_descs(struct cipher_ctx *ctx)
+{
+	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
+	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+	struct meson_alg_template *algt = container_of(alg,
+		struct meson_alg_template, alg.skcipher.base);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+	struct meson_dev *mc = op->mc;
+	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+	unsigned int blockmode = algt->blockmode;
+	int i;
+
+	if (ctx->tloffset)
+		return;
+
+	if (blockmode == DESC_OPMODE_CBC) {
+		memcpy(op->key + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
+		ctx->keyiv.len = AES_MAX_KEY_SIZE + ivsize;
+		dma_sync_single_for_device(mc->dev, ctx->keyiv.addr,
+					   ctx->keyiv.len, DMA_TO_DEVICE);
+	}
+
+	for (i = 0; i < mc->pdata->setup_desc_cnt; i++) {
+		struct meson_desc *desc =
+			&mc->chanlist[rctx->flow].tl[ctx->tloffset];
+		int offset = i * 16;
+
+		desc->t_src = cpu_to_le32(ctx->keyiv.addr + offset);
+		desc->t_dst = cpu_to_le32(offset);
+		desc->t_status = cpu_to_le32(DESC_OWN | DESC_MODE_KEY | ctx->keyiv.len);
+
+		ctx->tloffset++;
+	}
+}
+
+static bool meson_setup_data_descs(struct cipher_ctx *ctx)
+{
+	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+	struct meson_alg_template *algt = container_of(alg,
+						       struct meson_alg_template,
+						       alg.skcipher.base);
+	struct meson_dev *mc = op->mc;
+	struct meson_desc *desc = &mc->chanlist[rctx->flow].tl[ctx->tloffset];
+	unsigned int blocksize = crypto_skcipher_blocksize(tfm);
+	unsigned int blockmode = algt->blockmode;
+	unsigned int maxlen = rounddown(DESC_MAXLEN, blocksize);
+	unsigned int todo;
+	u32 v;
+
+	ctx->tloffset++;
+
+	todo = min(ctx->cryptlen, maxlen);
+	todo = min(todo, ctx->cryptlen);
+	todo = min(todo, sg_dma_len(ctx->src_sg) - ctx->src_offset);
+	todo = min(todo, sg_dma_len(ctx->dst_sg) - ctx->dst_offset);
+
+	desc->t_src = cpu_to_le32(sg_dma_address(ctx->src_sg) + ctx->src_offset);
+	desc->t_dst = cpu_to_le32(sg_dma_address(ctx->dst_sg) + ctx->dst_offset);
+
+	ctx->cryptlen -= todo;
+	ctx->src_offset += todo;
+	ctx->dst_offset += todo;
+
+	v = DESC_OWN | blockmode | op->keymode | todo;
+	if (rctx->op_dir == MESON_ENCRYPT)
+		v |= DESC_ENCRYPTION;
+
+	if (!ctx->cryptlen || ctx->tloffset == MAXDESC)
+		v |= DESC_LAST;
+
+	desc->t_status = cpu_to_le32(v);
+
+	return v & DESC_LAST;
+}
+
+static int meson_kick_hardware(struct cipher_ctx *ctx)
+{
+	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+	struct meson_alg_template *algt = container_of(alg,
+						       struct meson_alg_template,
+						       alg.skcipher.base);
+	struct meson_dev *mc = op->mc;
+	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+	unsigned int blockmode = algt->blockmode;
+	enum dma_data_direction new_iv_dir;
+	dma_addr_t new_iv_phys;
+	void *new_iv;
+	int err;
+
+	if (blockmode == DESC_OPMODE_CBC) {
+		struct scatterlist *sg;
+		unsigned int offset;
+
+		if (rctx->op_dir == MESON_ENCRYPT) {
+			sg = ctx->dst_sg;
+			offset = ctx->dst_offset;
+			new_iv_dir = DMA_FROM_DEVICE;
+		} else {
+			sg = ctx->src_sg;
+			offset = ctx->src_offset;
+			new_iv_dir = DMA_TO_DEVICE;
+		}
+
+		if (ctx->areq->src == ctx->areq->dst)
+			new_iv_dir = DMA_BIDIRECTIONAL;
+
+		offset -= ivsize;
+		new_iv = sg_virt(sg) + offset;
+		new_iv_phys = sg_dma_address(sg) + offset;
+	}
+
+	if (blockmode == DESC_OPMODE_CBC &&
+		rctx->op_dir == MESON_DECRYPT) {
+		dma_sync_single_for_cpu(mc->dev, new_iv_phys,
+					ivsize, new_iv_dir);
+		memcpy(ctx->areq->iv, new_iv, ivsize);
+	}
+
+	reinit_completion(&mc->chanlist[rctx->flow].complete);
+	meson_dma_start(mc, rctx->flow);
+	err = wait_for_completion_interruptible_timeout(
+			&mc->chanlist[rctx->flow].complete, msecs_to_jiffies(500));
+	if (err == 0) {
+		dev_err(mc->dev, "DMA timeout for flow %d\n", rctx->flow);
+		return -EINVAL;
+	} else if (err < 0) {
+		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
+		return err;
+	}
+
+	if (blockmode == DESC_OPMODE_CBC &&
+		rctx->op_dir == MESON_ENCRYPT) {
+		dma_sync_single_for_cpu(mc->dev, new_iv_phys,
+					ivsize, new_iv_dir);
+		memcpy(ctx->areq->iv, new_iv, ivsize);
+	}
+
+	ctx->tloffset = 0;
+
+	return 0;
+}
+
 static int meson_cipher(struct skcipher_request *areq)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
@@ -84,176 +295,78 @@ static int meson_cipher(struct skcipher_request *areq)
 	struct meson_dev *mc = op->mc;
 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
 	struct meson_alg_template *algt;
-	int flow = rctx->flow;
-	unsigned int todo, eat, len;
-	struct scatterlist *src_sg = areq->src;
-	struct scatterlist *dst_sg = areq->dst;
-	struct meson_desc *desc;
-	int nr_sgs, nr_sgd;
-	int i, err = 0;
-	unsigned int keyivlen, ivsize, offset, tloffset;
-	dma_addr_t phykeyiv;
-	void *backup_iv = NULL, *bkeyiv;
-	u32 v;
-
-	algt = container_of(alg, struct meson_alg_template, alg.skcipher.base);
+	struct cipher_ctx ctx = {
+		.areq = areq,
+		.src_offset = 0,
+		.dst_offset = 0,
+		.src_sg = areq->src,
+		.dst_sg = areq->dst,
+		.cryptlen = areq->cryptlen,
+	};
+	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+	int err;
 
-	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u flow=%d\n", __func__,
+	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u ctx.flow=%d\n", __func__,
 		crypto_tfm_alg_name(areq->base.tfm),
 		areq->cryptlen,
 		rctx->op_dir, crypto_skcipher_ivsize(tfm),
-		op->keylen, flow);
+		op->keylen, rctx->flow);
+
+	algt = container_of(alg, struct meson_alg_template, alg.skcipher.base);
 
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
 	algt->stat_req++;
-	mc->chanlist[flow].stat_req++;
+	mc->chanlist[rctx->flow].stat_req++;
 #endif
 
-	/*
-	 * The hardware expect a list of meson_desc structures.
-	 * The 2 first structures store key
-	 * The third stores IV
-	 */
-	bkeyiv = kzalloc(48, GFP_KERNEL | GFP_DMA);
-	if (!bkeyiv)
+	op->key = kzalloc(48, GFP_KERNEL | GFP_DMA);
+	if (!op.key)
 		return -ENOMEM;
 
-	memcpy(bkeyiv, op->key, op->keylen);
-	keyivlen = op->keylen;
+	memcpy(op->key, op->key, op->keylen);
+	ctx.keyiv.len = op->keylen;
+	if (ctx.keyiv.len == AES_KEYSIZE_192)
+		ctx.keyiv.len = AES_MAX_KEY_SIZE;
 
-	ivsize = crypto_skcipher_ivsize(tfm);
-	if (areq->iv && ivsize > 0) {
-		if (ivsize > areq->cryptlen) {
-			dev_err(mc->dev, "invalid ivsize=%d vs len=%d\n", ivsize, areq->cryptlen);
-			err = -EINVAL;
-			goto theend;
-		}
-		memcpy(bkeyiv + 32, areq->iv, ivsize);
-		keyivlen = 48;
-		if (rctx->op_dir == MESON_DECRYPT) {
-			backup_iv = kzalloc(ivsize, GFP_KERNEL);
-			if (!backup_iv) {
-				err = -ENOMEM;
-				goto theend;
-			}
-			offset = areq->cryptlen - ivsize;
-			scatterwalk_map_and_copy(backup_iv, areq->src, offset,
-						 ivsize, 0);
-		}
-	}
-	if (keyivlen == AES_KEYSIZE_192)
-		keyivlen = AES_MAX_KEY_SIZE;
-
-	phykeyiv = dma_map_single(mc->dev, bkeyiv, keyivlen,
+	ctx.keyiv.addr = dma_map_single(mc->dev, op->key, ctx.keyiv.len,
 				  DMA_TO_DEVICE);
-	err = dma_mapping_error(mc->dev, phykeyiv);
+	err = dma_mapping_error(mc->dev, ctx.keyiv.addr);
 	if (err) {
 		dev_err(mc->dev, "Cannot DMA MAP KEY IV\n");
 		goto theend;
 	}
 
-	tloffset = 0;
-	eat = 0;
-	i = 0;
-	while (keyivlen > eat) {
-		desc = &mc->chanlist[flow].tl[tloffset];
-		memset(desc, 0, sizeof(struct meson_desc));
-		todo = min(keyivlen - eat, 16u);
-		desc->t_src = cpu_to_le32(phykeyiv + i * 16);
-		desc->t_dst = cpu_to_le32(i * 16);
-		v = DESC_MODE_KEY | DESC_OWN | 16;
-		desc->t_status = cpu_to_le32(v);
-
-		eat += todo;
-		i++;
-		tloffset++;
-	}
-
-	if (areq->src == areq->dst) {
-		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
-				    DMA_BIDIRECTIONAL);
-		if (!nr_sgs) {
-			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
-			err = -EINVAL;
-			goto theend;
-		}
-		nr_sgd = nr_sgs;
-	} else {
-		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
-				    DMA_TO_DEVICE);
-		if (!nr_sgs || nr_sgs > MAXDESC - 3) {
-			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
-			err = -EINVAL;
-			goto theend;
-		}
-		nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
-				    DMA_FROM_DEVICE);
-		if (!nr_sgd || nr_sgd > MAXDESC - 3) {
-			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
-			err = -EINVAL;
-			goto theend;
-		}
-	}
-
-	src_sg = areq->src;
-	dst_sg = areq->dst;
-	len = areq->cryptlen;
-	while (src_sg) {
-		desc = &mc->chanlist[flow].tl[tloffset];
-		memset(desc, 0, sizeof(struct meson_desc));
-
-		desc->t_src = cpu_to_le32(sg_dma_address(src_sg));
-		desc->t_dst = cpu_to_le32(sg_dma_address(dst_sg));
-		todo = min(len, sg_dma_len(src_sg));
-		v = op->keymode | DESC_OWN | todo | algt->blockmode;
-		if (rctx->op_dir)
-			v |= DESC_ENCRYPTION;
-		len -= todo;
-
-		if (!sg_next(src_sg))
-			v |= DESC_LAST;
-		desc->t_status = cpu_to_le32(v);
-		tloffset++;
-		src_sg = sg_next(src_sg);
-		dst_sg = sg_next(dst_sg);
-	}
+	err = meson_map_scatterlist(areq, mc);
+	if (err)
+		goto theend;
 
-	reinit_completion(&mc->chanlist[flow].complete);
-	meson_dma_start(mc, flow);
+	ctx.tloffset = 0;
 
-	err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
-							msecs_to_jiffies(500));
-	if (err == 0) {
-		dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
-		err = -EINVAL;
-	} else if (err < 0) {
-		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
-	} else {
-		/* No error */
-		err = 0;
-	}
+	while (ctx.cryptlen) {
+		meson_setup_keyiv_descs(&ctx);
 
-	dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
+		if (meson_setup_data_descs(&ctx)) {
+			err = meson_kick_hardware(&ctx);
+			if (err)
+				break;
+		}
 
-	if (areq->src == areq->dst) {
-		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL);
-	} else {
-		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
-		dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE);
-	}
+		if (ctx.src_offset == sg_dma_len(ctx.src_sg)) {
+			ctx.src_offset = 0;
+			ctx.src_sg = sg_next(ctx.src_sg);
+		}
 
-	if (areq->iv && ivsize > 0) {
-		if (rctx->op_dir == MESON_DECRYPT) {
-			memcpy(areq->iv, backup_iv, ivsize);
-		} else {
-			scatterwalk_map_and_copy(areq->iv, areq->dst,
-						 areq->cryptlen - ivsize,
-						 ivsize, 0);
+		if (ctx.dst_offset == sg_dma_len(ctx.dst_sg)) {
+			ctx.dst_offset = 0;
+			ctx.dst_sg = sg_next(ctx.dst_sg);
 		}
 	}
+
+	dma_unmap_single(mc->dev, ctx.keyiv.addr, ctx.keyiv.len, DMA_TO_DEVICE);
+	meson_unmap_scatterlist(areq, mc);
+
 theend:
-	kfree_sensitive(bkeyiv);
-	kfree_sensitive(backup_iv);
+	kfree_sensitive(op->key);
 
 	return err;
 }
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 22ff2768b5e5..f93e14f5717d 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -199,6 +199,7 @@ static const struct meson_pdata meson_gxl_pdata = {
 	.descs_reg = 0x0,
 	.status_reg = 0x4,
 	.need_clk = true,
+	.setup_desc_cnt = 3,
 };
 
 static const struct of_device_id meson_crypto_of_match_table[] = {
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index a0d83c82906d..eb2f8cd72b65 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -83,11 +83,13 @@ struct meson_flow {
  * @reg_descs:	offset to descriptors register
  * @reg_status:	offset to status register
  * @need_clk:	clock input is needed
+ * @setup_desc_cnt:	number of setup descriptor to configure.
  */
 struct meson_pdata {
 	u32 descs_reg;
 	u32 status_reg;
 	bool need_clk;
+	u32 setup_desc_cnt;
 };
 
 /*
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:14 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:14 +0300
Subject: [PATCH v3 13/20] drivers: crypto: meson: use fallback for 192-bit keys
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-14-avromanov@salutedevices.com>

Unforunately, not all Amlogic SoC's have a 192-bit key
support for AES algo. In this case, use fallback.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 7 +++++++
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 1 +
 drivers/crypto/amlogic/amlogic-gxl.h        | 2 ++
 3 files changed, 10 insertions(+)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 828109f4a1c3..da593130553e 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -41,6 +41,13 @@ static bool meson_cipher_need_fallback_sg(struct skcipher_request *areq,
 
 static bool meson_cipher_need_fallback(struct skcipher_request *areq)
 {
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+	struct meson_dev *mc = op->mc;
+
+	if (op->keymode == DESC_MODE_AES_192 && !mc->pdata->support_192bit_key)
+		return true;
+
 	if (areq->cryptlen == 0)
 		return true;
 
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f3b5e004b3a5..429c3474028b 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -215,6 +215,7 @@ static const struct meson_pdata meson_gxl_pdata = {
 	.status_reg = 0x4,
 	.need_clk = true,
 	.setup_desc_cnt = 3,
+	.support_192bit_key = true,
 };
 
 static const struct of_device_id meson_crypto_of_match_table[] = {
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 7f6d91e7b365..2d2777a25453 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -98,12 +98,14 @@ struct meson_flow {
  * @reg_status:	offset to status register
  * @need_clk:	clock input is needed
  * @setup_desc_cnt:	number of setup descriptor to configure.
+ * @support_192bit_key:	indicates whether platform support AES 192-bit key
  */
 struct meson_pdata {
 	u32 descs_reg;
 	u32 status_reg;
 	bool need_clk;
 	u32 setup_desc_cnt;
+	bool support_192bit_key;
 };
 
 /*
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:15 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:15 +0300
Subject: [PATCH v3 14/20] drivers: crypto: meson: add support for G12-series
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-15-avromanov@salutedevices.com>

This platform data also can be used for A1 and S4 as fallback.
Tested via tcrypt module and with custom tests.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-core.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 429c3474028b..2ffe5994b353 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -218,11 +218,31 @@ static const struct meson_pdata meson_gxl_pdata = {
 	.support_192bit_key = true,
 };
 
+static const struct meson_pdata meson_g12a_pdata = {
+	.descs_reg = 0x0,
+	.status_reg = 0x8,
+	.need_clk = false,
+	.setup_desc_cnt = 1,
+	.support_192bit_key = false,
+};
+
 static const struct of_device_id meson_crypto_of_match_table[] = {
 	{
 		.compatible = "amlogic,gxl-crypto",
 		.data = &meson_gxl_pdata,
 	},
+	{
+		.compatible = "amlogic,g12a-crypto",
+		.data = &meson_g12a_pdata,
+	},
+	{
+		.compatible = "amlogic,a1-crypto",
+		.data = &meson_g12a_pdata,
+	},
+	{
+		.compatible = "amlogic,s4-crypto",
+		.data = &meson_g12a_pdata,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:17 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:17 +0300
Subject: [PATCH v3 16/20] dt-bindings: crypto: meson: support new SoC's
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-17-avromanov@salutedevices.com>

Now crypto module available at G12A/G12B/S4/A1/SM1/AXG.

1. Add new compatibles:
  - amlogic,g12a-crypto
  - amlogic,s4-crypto (uses g12a-crypto as fallback)
  - amlogic,a1-crypto (uses g12a-crypto as fallback)
  - amlogic,axg-crypto

2. All SoC's, exclude GXL, doesn't take a clock input for
Crypto IP. Make it required only for amlogic,gxl-crypto.

3. All SoC's, exclude GXL, uses only one interrupt flow
for Crypto IP.

4. Add power-domains in schema.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 .../bindings/crypto/amlogic,gxl-crypto.yaml   | 44 +++++++++++++++----
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
index 948e11ebe4ee..62f772036b06 100644
--- a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
+++ b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
@@ -11,20 +11,30 @@ maintainers:
 
 properties:
   compatible:
-    items:
-      - const: amlogic,gxl-crypto
+    oneOf:
+      - items:
+          - enum:
+              - amlogic,a1-crypto
+              - amlogic,s4-crypto
+          - const: amlogic,g12a-crypto
+      - items:
+          - const: amlogic,gxl-crypto
+      - items:
+          - const: amlogic,axg-crypto
+      - items:
+          - const: amlogic,g12a-crypto
 
   reg:
     maxItems: 1
 
-  interrupts:
-    items:
-      - description: Interrupt for flow 0
-      - description: Interrupt for flow 1
+  interrupts: true
 
   clocks:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
   clock-names:
     const: blkmv
 
@@ -32,8 +42,26 @@ required:
   - compatible
   - reg
   - interrupts
-  - clocks
-  - clock-names
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: amlogic,gxl-crypto
+    then:
+      required:
+        - clocks
+        - clock-names
+      properties:
+        interrupts:
+          maxItems: 2
+          minItems: 2
+    else:
+      properties:
+        interrupts:
+          maxItems: 1
+          minItems: 1
 
 additionalProperties: false
 
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:16 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:16 +0300
Subject: [PATCH v3 15/20] drivers: crypto: meson: add support for AXG-series
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-16-avromanov@salutedevices.com>

Tested via tcrypt module and with custom tests.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-core.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 2ffe5994b353..536ad438f713 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -226,6 +226,14 @@ static const struct meson_pdata meson_g12a_pdata = {
 	.support_192bit_key = false,
 };
 
+static const struct meson_pdata meson_axg_pdata = {
+	.descs_reg = 0x0,
+	.status_reg = 0x8,
+	.need_clk = false,
+	.setup_desc_cnt = 3,
+	.support_192bit_key = true,
+};
+
 static const struct of_device_id meson_crypto_of_match_table[] = {
 	{
 		.compatible = "amlogic,gxl-crypto",
@@ -243,6 +251,10 @@ static const struct of_device_id meson_crypto_of_match_table[] = {
 		.compatible = "amlogic,s4-crypto",
 		.data = &meson_g12a_pdata,
 	},
+	{
+		.compatible = "amlogic,axg-crypto",
+		.data = &meson_axg_pdata,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:20 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:20 +0300
Subject: [PATCH v3 19/20] arch: arm64: dts: meson: g12: add crypto node
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-20-avromanov@salutedevices.com>

This patch adds a crypto node declaration for Amlogic G12-series.
With the Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.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 ff68b911b729..f6d7047a579c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1709,6 +1709,12 @@ internal_ephy: ethernet-phy at 8 {
 					};
 				};
 			};
+
+			crypto: crypto at 3e000 {
+				compatible = "amlogic,g12a-crypto";
+				reg = <0x0 0x3e000 0x0 0x48>;
+				interrupts = <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>;
+			};
 		};
 
 		aobus: bus at ff800000 {
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb  5 07:55:21 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 5 Feb 2024 18:55:21 +0300
Subject: [PATCH v3 20/20] arch: arm64: dts: meson: axg: add crypto node
In-Reply-To: <20240205155521.1795552-1-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
Message-ID: <20240205155521.1795552-21-avromanov@salutedevices.com>

This patch adds a crypto node declaration. With the
Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 7e5ac9db93f8..39ecb894668e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -286,6 +286,12 @@ ethmac: ethernet at ff3f0000 {
 			status = "disabled";
 		};
 
+		crypto: crypto at ff63e000 {
+			compatible = "amlogic,axg-crypto";
+			reg = <0x0 0xff63e000 0x0 0x48>;
+			interrupts = <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>;
+		};
+
 		pcie_phy: phy at ff644000 {
 			compatible = "amlogic,axg-pcie-phy";
 			reg = <0x0 0xff644000 0x0 0x1c>;
-- 
2.34.1



From megi at xff.cz  Mon Feb  5 08:02:00 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Mon, 5 Feb 2024 17:02:00 +0100
Subject: [PATCH v2 0/6] Pinephone video out fixes (flipping between two
 frames)
In-Reply-To: <jzl3mlzk4j7qvgcedvipgale5nhinznefodrnaehwsqfnseiwc@7zzlxd4dpueh>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <jzl3mlzk4j7qvgcedvipgale5nhinznefodrnaehwsqfnseiwc@7zzlxd4dpueh>
Message-ID: <bgyyemyi4shj3spo6qy4icvk56nrp5sihnzqurnozqdyktwugc@ikurx4ojoxpi>

On Mon, Feb 05, 2024 at 04:54:07PM +0100, Ond?ej Jirman wrote:
> On Mon, Feb 05, 2024 at 04:22:23PM +0100, Frank Oltmanns wrote:
> > On some pinephones the video output sometimes freezes (flips between two
> > frames) [1]. It seems to be that the reason for this behaviour is that
> > PLL-MIPI, PLL-GPU and GPU are operating outside their limits.
> > 
> > In this patch series I propose the followin changes:
> >   1. sunxi-ng: Adhere to the following constraints given in the
> >      Allwinner A64 Manual regarding PLL-MIPI:
> >       * M/N <= 3
> >       * (PLL_VIDEO0)/M >= 24MHz
> >       * 500MHz <= clockrate <= 1400MHz
> > 
> >   2. Choose a higher clock rate for the ST7703 based XDB599 panel, so
> >      that the panel function well with the Allwinner A64 SOC. PLL-MIPI
> >      must run between 500 MHz and 1.4 GHz. As PLL-MIPI runs at 6 times
> >      the panel's clock rate, we need the panel's clock to be at least
> >      83.333 MHz.
> > 
> >   3. Increase the minimum frequency in the A64 DTS OPPs from 120 MHz to
> >      192 MHz. This further reduces the issue.
> > 
> > Unfortunately, with these patches the issue [1] is not completely gone,
> > but becomes less likely.
> > 
> > Note, that when pinning the GPU to 432 MHz the issue completely
> > disappears for me. I've searched the BSP and could not find any
> > indication that supports the idea of having the three OPPs. The only
> > frequency I found in the BPSs for A64 is 432 MHz, that has also proven
> > stable for me. So, while increasing the minimum frequency to 192 MHz
> > reduces the issue, should we maybe instead set the GPU to a fixed 432
> > MHz instead?
> 
> Per A64 User Manual 1.1 page 81:
> 
> (9). Clock output of PLL_GPU can be used for GPU;and dynamic frequency scaling is not supported;

You may be able to elegantly work around this by pinning PLL_GPU to a certain
frequency (assing it in DT and then don't decalre gpu clock as
CLK_SET_RATE_PARENT). Say 432 MHz for PLL and then do the scaling via GPU_CLK_REG
N divider between 432MHz and 216MHz and maybe 108MHz if that brings any gains.

Then you can perhaps sidestep all these potential issues with PLL_GPU and
lack of DVFS support decalred in the manual.

regards,
	o.

> Also sunxi-ng clk driver does apply NM factors at once to PLL_GPU clock,
> which can cause sudden frequency increase beyond intended output frequency,
> because division is applied immediately while multiplication is reflected
> slowly.
> 
> Eg. if you're changing divider from 7 to 1, you can get a sudden 7x output
> frequency spike, before PLL VCO manages to lower the frequency through N clk
> divider feedback loop and lock on again. This can mess up whatever's connected
> to the output quite badly.
> 
> You'd have to put logging on kernel writes to PLL_GPU register to see what
> is written in there and if divider is lowered significantly on some GPU
> devfreq frequency transitions.
> 
> It's also unclear what happens when FRAC_CLK_OUT or PLL_MODE_SEL changes.
> Maybe not much because M is supposed to be set to 1, but you still need to
> care when enabling fractional mode, and setting M to 1 because that's exactly
> the bad scenario if M was previously higher than 1.
> 
> It's tricky.
> 
> Having GPU module clock gated during PLL config changes may help! You can
> do that without locking yourself out, unlike with the CPU PLL.
> 
> There's a gate enable bit for it at GPU_CLK_REG.SCLK_GATING. (page 122)
> 
> Kind regards,
> 	o.
> 
> > I very much appreciate your feedback!
> > 
> > [1] https://gitlab.com/postmarketOS/pmaports/-/issues/805
> > 
> > Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> > ---
> > Changes in v2:
> > - dts: Increase minimum GPU frequency to 192 MHz.
> > - nkm and a64: Add minimum and maximum rate for PLL-MIPI.
> > - nkm: Use the same approach for skipping invalid rates in
> >   ccu_nkm_find_best() as in ccu_nkm_find_best_with_parent_adj().
> > - nkm: Improve names for ratio struct members and hence get rid of
> >   describing comments.
> > - nkm and a64: Correct description in the commit messages: M/N <= 3
> > - Remove patches for nm as they were not needed.
> > - st7703: Rework the commit message to cover more background for the
> >   change.
> > - Link to v1: https://lore.kernel.org/r/20231218-pinephone-pll-fixes-v1-0-e238b6ed6dc1 at oltmanns.dev
> > 
> > ---
> > Frank Oltmanns (6):
> >       clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate
> >       clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate
> >       clk: sunxi-ng: nkm: Support minimum and maximum rate
> >       clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
> >       drm/panel: st7703: Drive XBD599 panel at higher clock rate
> >       arm64: dts: allwinner: a64: Fix minimum GPU OPP rate
> > 
> >  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  4 ++--
> >  drivers/clk/sunxi-ng/ccu-sun50i-a64.c         | 14 +++++++----
> >  drivers/clk/sunxi-ng/ccu_nkm.c                | 34 +++++++++++++++++++++++++++
> >  drivers/clk/sunxi-ng/ccu_nkm.h                |  4 ++++
> >  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++++------
> >  5 files changed, 56 insertions(+), 14 deletions(-)
> > ---
> > base-commit: 059c53e877ca6e723e10490c27c1487a63e66efe
> > change-id: 20231218-pinephone-pll-fixes-0ccdfde273e4
> > 
> > Best regards,
> > -- 
> > Frank Oltmanns <frank at oltmanns.dev>
> > 


From sebastianene at google.com  Mon Feb  5 08:05:21 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Mon, 5 Feb 2024 16:05:21 +0000
Subject: [PATCH v4 02/10] KVM: arm64: Add ptdump registration with
 debugfs for the stage-2 pagetables
In-Reply-To: <ZcDfM2VRiTETM04I@linux.dev>
References: <20231218135859.2513568-2-sebastianene@google.com>
 <20231218135859.2513568-4-sebastianene@google.com>
 <ZYSAfORj2-cXo5t_@linux.dev>
 <Zbt-leieTD64ZefR@google.com>
 <ZcDfM2VRiTETM04I@linux.dev>
Message-ID: <ZcEHQSFx4gNh4yMm@google.com>

On Mon, Feb 05, 2024 at 01:14:27PM +0000, Oliver Upton wrote:
> On Thu, Feb 01, 2024 at 11:20:53AM +0000, Sebastian Ene wrote:
> > On Thu, Dec 21, 2023 at 06:14:20PM +0000, Oliver Upton wrote:
> > 
> > Hi Oliver,
> > 
> > I am planning to split the series based on your suggestion and I
> > wanted to make sure that I understand your feedback.
> > 
> > > On Mon, Dec 18, 2023 at 01:58:52PM +0000, Sebastian Ene wrote:
> > > > +config PTDUMP_STAGE2_DEBUGFS
> > > > +       bool "Present the stage-2 pagetables to debugfs"
> > > > +       depends on PTDUMP_DEBUGFS && KVM
> > > > +       default n
> > > > +       help
> > > > +         Say Y here if you want to show the stage-2 kernel pagetables
> > > > +         layout in a debugfs file. This information is only useful for kernel developers
> > > > +         who are working in architecture specific areas of the kernel.
> > > > +         It is probably not a good idea to enable this feature in a production
> > > > +         kernel.
> > > 
> > > It isn't really a good idea to mount debugfs at all in a production
> > > system. There are already plenty worse interfaces lurking in that
> > > filesystem. The pKVM portions already depend on CONFIG_NVHE_EL2_DEBUG,
> > > so I don't see a need for this Kconfig option.
> > > 
> > 
> > I created a separate option because I wanted to re-use the parsing
> > functionality from the already existing ptdump code for EL1. This option
> > is turned off in production and only enabled for debug.
> > 
> > I was thinking to make use of the `CONFIG_NVHE_EL2_DEBUG` but then I abandoned 
> > this ideea as one can use ptdump for vHE as well.
> 
> Fair enough. I was going to say we could just have KVM follow
> CONFIG_PTDUMP_DEBUGFS, but it doesn't matter either way.
> 
> > > > +void kvm_ptdump_register_host(void)
> > > > +{
> > > > +	if (!is_protected_kvm_enabled())
> > > > +		return;
> > > > +
> > > > +	kvm_ptdump_debugfs_register(&host_reg, "host_page_tables",
> > > > +				    kvm_debugfs_dir);
> > > > +}
> > > > +
> > > > +static int __init kvm_host_ptdump_init(void)
> > > > +{
> > > > +	host_reg.priv = (void *)host_s2_pgtable_pages();
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +device_initcall(kvm_host_ptdump_init);
> > > 
> > > Why can't all of this be called from finalize_pkvm()?
> > > 
> > 
> > I guess it can be called from finalize_pkvm before the is_protected_kvm_enabled
> > check. This should work for nvhe & vhe as well.
> 
> What does nvhe and vhe modes have to do with it? I thought this was for
> hooking up the host's S2, which does not exist outside protected mode.
> 

True I guess there is no other need for the initialization portion in
this function. I will split the series to address the non-protected
support first.

Thanks,
Seb

> -- 
> Thanks,
> Oliver


From vschneid at redhat.com  Mon Feb  5 08:05:14 2024
From: vschneid at redhat.com (Valentin Schneider)
Date: Mon, 05 Feb 2024 17:05:14 +0100
Subject: Question about the ipi_raise filter usage and output
In-Reply-To: <ZcDwoce6Ok25K6Dm@FVFF77S0Q05N>
References: <ZcDwoce6Ok25K6Dm@FVFF77S0Q05N>
Message-ID: <xhsmhmssehp6t.mognet@vschneid-thinkpadt14sgen2i.remote.csb>

On 05/02/24 14:39, Mark Rutland wrote:
> [adding Valentin]
>

Thanks!

> On Mon, Feb 05, 2024 at 08:06:09AM -0500, Steven Rostedt wrote:
>> On Mon, 5 Feb 2024 10:28:57 +0000
>> Mark Rutland <mark.rutland at arm.com> wrote:
>>
>> > > I try to write below:
>> > > echo 'target_cpus == 11 && reason == "Function call interrupts"' >
>> > > events/ipi/ipi_raise/filter
>> >
>> > The '=' checks if the target_cpus bitmap *only* contains CPU 11. If the cpumask
>> > contains other CPUs, the filter will skip the call.
>> >
>> > I believe you can use '&' to check whether a cpumask contains a CPU, e.g.
>> >
>> >    'target_cpus & 11'
>>
>> 11 == 0xb = b1011
>>
>> So the above would only be true for CPUs 0,1 and 3 ;-)
>
> Sorry, I misunderstood the scalar logic and thought that we treated:
>
>       '$mask $OP $scalar', e.g. 'target_cpus & 11'
>
> .. as a special case meaning a cpumask with that scalar bit set, i.e.
>
>       '$mask $OP CPUS{$scalar}', e.g. 'target_cpus & CPUS{11}'
>
> .. but evidently I was wrong.
>
>> I think you meant: 'target_cpus & 0x800'
>>
>> I tried "1 << 11' but it appears to not allow shifts. I wonder if we should add that?
>
> Hmm... shouldn't we make 'CPUS{11}' work for that?
>

It /should/ already be the case, the user input with the curly braces is
parsed as a cpulist. So CPUS{11} really does mean CPU11, not a hex value to
be interpreted as a cpumask.

However...

> From a quick test (below), that doesn't seem to work, though I think it
> probably should?
> Have I completely misunderstood how this is supposed to work, or is that a bug?
>

The CPUS{} thingie only works with an event field that is either declared as a
cpumask (__cpumask) or a scalar. That's not the case for ipi_raise, the
target_cpus event field is saved as a "raw" bitmask.

There /should/ have been a warning about the event filter though, but I
think it's not happening because I'm allowing more than just FILTER_CPUMASK
in parse_pred() to make it work for scalars. I'll go poke around some more.

Generally for this sort of IPI investigation I'd recommend using the newer
trace_ipi_send_cpu() and trace_ipi_send_cpumask() (for which CPUS{}
filtering works).
If it's only the function call interrupts you're interesting in, have a
look at trace_csd_queue_cpu().

> Mark.



From lkp at intel.com  Mon Feb  5 08:17:01 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 6 Feb 2024 00:17:01 +0800
Subject: [PATCH v2 1/3] Subject: [PATCH] drm/mediatek/dp: Add tee client
 application for HDCP feature
In-Reply-To: <20240205055055.25340-2-mac.shen@mediatek.com>
References: <20240205055055.25340-2-mac.shen@mediatek.com>
Message-ID: <202402052342.Y5awT1T2-lkp@intel.com>

Hi mac.shen,

kernel test robot noticed the following build warnings:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on pza/reset/next linus/master v6.8-rc3 next-20240205]
[cannot apply to pza/imx-drm/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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/mac-shen/Subject-PATCH-drm-mediatek-dp-Add-tee-client-application-for-HDCP-feature/20240205-163727
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:    https://lore.kernel.org/r/20240205055055.25340-2-mac.shen%40mediatek.com
patch subject: [PATCH v2 1/3] Subject: [PATCH] drm/mediatek/dp: Add tee client application for HDCP feature
config: arm64-defconfig (https://download.01.org/0day-ci/archive/20240205/202402052342.Y5awT1T2-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240205/202402052342.Y5awT1T2-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402052342.Y5awT1T2-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/mediatek/tlc_dp_hdcp.c:34: warning: Function parameter or struct member 'dp_tee_priv' not described in 'dp_tee_op_send'
>> drivers/gpu/drm/mediatek/tlc_dp_hdcp.c:34: warning: Function parameter or struct member 'cmd_id' not described in 'dp_tee_op_send'


vim +34 drivers/gpu/drm/mediatek/tlc_dp_hdcp.c

    13	
    14	/*
    15	 * TA_FTPM_UUID: 99975014-3c7c-54ea-8487-a80d215ea92c
    16	 *
    17	 * Randomly generated, and must correspond to the GUID on the TA side.
    18	 * Defined here in the reference implementation:
    19	 * https://github.com/microsoft/ms-tpm-20-ref/blob/master/Samples/ARM32-FirmwareTPM/optee_ta/fTPM/include/fTPM.h#L42
    20	 */
    21	static const uuid_t dp_ta_uuid =
    22		UUID_INIT(0x99975014, 0x3c7c, 0x54ea,
    23			  0x84, 0x87, 0xa8, 0x0d, 0x21, 0x5e, 0xa9, 0x2c);
    24	
    25	/**
    26	 * dp_tee_op_send() - send dp commands through the TEE shared memory.
    27	 * @len:	the number of bytes to send.
    28	 *
    29	 * Return:
    30	 *	In case of success, returns 0.
    31	 *	On failure, -errno
    32	 */
    33	static int dp_tee_op_send(struct dp_tee_private *dp_tee_priv, size_t len, u32 cmd_id)
  > 34	{
    35		int rc;
    36		u8 *temp_buf;
    37		struct tee_ioctl_invoke_arg transceive_args;
    38		struct tee_param command_params[4];
    39		struct tee_shm *shm = dp_tee_priv->shm;
    40	
    41		if (len > MAX_COMMAND_SIZE) {
    42			TLCERR("%s: len=%zd exceeds MAX_COMMAND_SIZE supported by dp TA\n", __func__, len);
    43			return -EIO;
    44		}
    45	
    46		memset(&transceive_args, 0, sizeof(transceive_args));
    47		memset(command_params, 0, sizeof(command_params));
    48		dp_tee_priv->resp_len = 0;
    49	
    50		/* Invoke FTPM_OPTEE_TA_SUBMIT_COMMAND function of dp TA */
    51		transceive_args = (struct tee_ioctl_invoke_arg) {
    52			.func = cmd_id,
    53			.session = dp_tee_priv->session,
    54			.num_params = 4,
    55		};
    56	
    57		/* Fill FTPM_OPTEE_TA_SUBMIT_COMMAND parameters */
    58		command_params[0] = (struct tee_param) {
    59			.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
    60			.u.memref = {
    61				.shm = shm,
    62				.size = len,
    63				.shm_offs = 0,
    64			},
    65		};
    66	
    67		command_params[1] = (struct tee_param) {
    68			.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
    69			.u.memref = {
    70				.shm = shm,
    71				.size = MAX_RESPONSE_SIZE,
    72				.shm_offs = MAX_COMMAND_SIZE,
    73			},
    74		};
    75	
    76		rc = tee_client_invoke_func(dp_tee_priv->ctx, &transceive_args, command_params);
    77		if (rc < 0 || transceive_args.ret != 0) {
    78			TLCERR("%s: invoke error: 0x%x\n", __func__, transceive_args.ret);
    79			return (rc < 0) ? rc : transceive_args.ret;
    80		}
    81	
    82		temp_buf = tee_shm_get_va(shm, command_params[1].u.memref.shm_offs);
    83		if (IS_ERR(temp_buf)) {
    84			TLCERR("%s: tee_shm_get_va failed for receive\n", __func__);
    85			return PTR_ERR(temp_buf);
    86		}
    87	
    88		/* Sanity checks look good, cache the response */
    89		memcpy(dp_tee_priv->resp_buf, temp_buf, MAX_RESPONSE_SIZE / 2);
    90		dp_tee_priv->resp_len = MAX_RESPONSE_SIZE / 2;
    91	
    92		return 0;
    93	}
    94	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From maz at kernel.org  Mon Feb  5 08:24:12 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 05 Feb 2024 16:24:12 +0000
Subject: [PATCH v5 00/12] RISCV: Add kvm Sstc timer selftests
In-Reply-To: <CAJve8onDbX44Ph6a-FdO2+p7QOQLah-7OyF+yUc06wud+SvmQQ@mail.gmail.com>
References: <cover.1705916069.git.haibo1.xu@intel.com>
	<CAJve8onDbX44Ph6a-FdO2+p7QOQLah-7OyF+yUc06wud+SvmQQ@mail.gmail.com>
Message-ID: <86zfwe6frn.wl-maz@kernel.org>

On Mon, 05 Feb 2024 13:10:26 +0000,
Haibo Xu <xiaobo55x at gmail.com> wrote:
> 
> Hi Marc,
> 
> Could you help review the first 3 patches in this series?

For these 3 patches:

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

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From alexandru.elisei at arm.com  Mon Feb  5 08:30:17 2024
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Mon, 5 Feb 2024 16:30:17 +0000
Subject: [PATCH RFC v3 22/35] arm64: mte: Enable tag storage if CMA areas
 have been activated
In-Reply-To: <CAFKCwrhNE5PR7cu7tN8qMmSEUhdJ7ensGGrB-oodh-J_fdoRcw@mail.gmail.com>
References: <20240125164256.4147-1-alexandru.elisei@arm.com>
 <20240125164256.4147-23-alexandru.elisei@arm.com>
 <CAFKCwrhNE5PR7cu7tN8qMmSEUhdJ7ensGGrB-oodh-J_fdoRcw@mail.gmail.com>
Message-ID: <ZcEM+DjRX/UB07yM@arm.com>

Hi Evgenii,

On Fri, Feb 02, 2024 at 02:30:00PM -0800, Evgenii Stepanov wrote:
> On Thu, Jan 25, 2024 at 8:44?AM Alexandru Elisei
> <alexandru.elisei at arm.com> wrote:
> >
> > Before enabling MTE tag storage management, make sure that the CMA areas
> > have been successfully activated. If a CMA area fails activation, the pages
> > are kept as reserved. Reserved pages are never used by the page allocator.
> >
> > If this happens, the kernel would have to manage tag storage only for some
> > of the memory, but not for all memory, and that would make the code
> > unreasonably complicated.
> >
> > Choose to disable tag storage management altogether if a CMA area fails to
> > be activated.
> >
> > Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> > ---
> >
> > Changes since v2:
> >
> > * New patch.
> >
> >  arch/arm64/include/asm/mte_tag_storage.h | 12 ++++++
> >  arch/arm64/kernel/mte_tag_storage.c      | 50 ++++++++++++++++++++++++
> >  2 files changed, 62 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/mte_tag_storage.h b/arch/arm64/include/asm/mte_tag_storage.h
> > index 3c2cd29e053e..7b3f6bff8e6f 100644
> > --- a/arch/arm64/include/asm/mte_tag_storage.h
> > +++ b/arch/arm64/include/asm/mte_tag_storage.h
> > @@ -6,8 +6,20 @@
> >  #define __ASM_MTE_TAG_STORAGE_H
> >
> >  #ifdef CONFIG_ARM64_MTE_TAG_STORAGE
> > +
> > +DECLARE_STATIC_KEY_FALSE(tag_storage_enabled_key);
> > +
> > +static inline bool tag_storage_enabled(void)
> > +{
> > +       return static_branch_likely(&tag_storage_enabled_key);
> > +}
> > +
> >  void mte_init_tag_storage(void);
> >  #else
> > +static inline bool tag_storage_enabled(void)
> > +{
> > +       return false;
> > +}
> >  static inline void mte_init_tag_storage(void)
> >  {
> >  }
> > diff --git a/arch/arm64/kernel/mte_tag_storage.c b/arch/arm64/kernel/mte_tag_storage.c
> > index 9a1a8a45171e..d58c68b4a849 100644
> > --- a/arch/arm64/kernel/mte_tag_storage.c
> > +++ b/arch/arm64/kernel/mte_tag_storage.c
> > @@ -19,6 +19,8 @@
> >
> >  #include <asm/mte_tag_storage.h>
> >
> > +__ro_after_init DEFINE_STATIC_KEY_FALSE(tag_storage_enabled_key);
> > +
> >  struct tag_region {
> >         struct range mem_range; /* Memory associated with the tag storage, in PFNs. */
> >         struct range tag_range; /* Tag storage memory, in PFNs. */
> > @@ -314,3 +316,51 @@ void __init mte_init_tag_storage(void)
> >         num_tag_regions = 0;
> >         pr_info("MTE tag storage region management disabled");
> >  }
> > +
> > +static int __init mte_enable_tag_storage(void)
> > +{
> > +       struct range *tag_range;
> > +       struct cma *cma;
> > +       int i, ret;
> > +
> > +       if (num_tag_regions == 0)
> > +               return 0;
> > +
> > +       for (i = 0; i < num_tag_regions; i++) {
> > +               tag_range = &tag_regions[i].tag_range;
> > +               cma = tag_regions[i].cma;
> > +               /*
> > +                * CMA will keep the pages as reserved when the region fails
> > +                * activation.
> > +                */
> > +               if (PageReserved(pfn_to_page(tag_range->start)))
> > +                       goto out_disabled;
> > +       }
> > +
> > +       static_branch_enable(&tag_storage_enabled_key);
> > +       pr_info("MTE tag storage region management enabled");
> > +
> > +       return 0;
> > +
> > +out_disabled:
> > +       for (i = 0; i < num_tag_regions; i++) {
> > +               tag_range = &tag_regions[i].tag_range;
> > +               cma = tag_regions[i].cma;
> > +
> > +               if (PageReserved(pfn_to_page(tag_range->start)))
> > +                       continue;
> > +
> > +               /* Try really hard to reserve the tag storage. */
> > +               ret = cma_alloc(cma, range_len(tag_range), 8, true);
> > +               /*
> > +                * Tag storage is still in use for data, memory and/or tag
> > +                * corruption will ensue.
> > +                */
> > +               WARN_ON_ONCE(ret);
> 
> cma_alloc returns (page *), so this condition needs to be inverted,
> and the type of `ret` changed.
> Not sure how it slipped through, this is a compile error with clang.

Checked just now, it's a warning with gcc, I must have missed it. Will fix.

Thanks,
Alex

> 
> > +       }
> > +       num_tag_regions = 0;
> > +       pr_info("MTE tag storage region management disabled");
> > +
> > +       return -EINVAL;
> > +}
> > +arch_initcall(mte_enable_tag_storage);
> > --
> > 2.43.0
> >


From geert at linux-m68k.org  Mon Feb  5 08:31:26 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 5 Feb 2024 17:31:26 +0100
Subject: [PATCH] pmdomain: mediatek: Use devm_platform_get_and_ioremap_resource()
 in init_scp()
In-Reply-To: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de>
References: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de>
Message-ID: <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>

Hi Markus,

On Mon, Feb 5, 2024 at 3:23?PM Markus Elfring <Markus.Elfring at web.de> wrote:
> From: Markus Elfring <elfring at users.sourceforge.net>
> Date: Mon, 5 Feb 2024 15:08:27 +0100
>
> A wrapper function is available since the commit 890cc39a879906b63912482dfc41944579df2dc6
> ("drivers: provide devm_platform_get_and_ioremap_resource()").
> Thus reuse existing functionality instead of keeping duplicate source code.
>
> This issue was detected by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>

Thanks for your patch!

> --- a/drivers/pmdomain/mediatek/mtk-scpsys.c
> +++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
> @@ -441,8 +441,7 @@ static struct scp *init_scp(struct platform_device *pdev,
>
>         scp->dev = &pdev->dev;
>
> -       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -       scp->base = devm_ioremap_resource(&pdev->dev, res);
> +       scp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);

Given res is further unused, please use devm_platform_ioremap_resource()
instead, and remove the local variable res.

>         if (IS_ERR(scp->base))
>                 return ERR_CAST(scp->base);
>

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 oliver.upton at linux.dev  Mon Feb  5 08:38:55 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 5 Feb 2024 16:38:55 +0000
Subject: [PATCH v4 2/7] arm64: KVM: Use shared area to pass PMU event
 state to hypervisor
In-Reply-To: <861q9q7vwr.wl-maz@kernel.org>
References: <20240104162714.1062610-3-james.clark@arm.com>
 <Zb1mCCi13AJ_YjFZ@linux.dev>
 <8a908ee8-620a-d9c2-734b-5a6402950072@arm.com>
 <ZcDc8-FQo8wKavA4@linux.dev>
 <867cjj6ohz.wl-maz@kernel.org>
 <ZcDg1sP3EYZG-i_3@linux.dev>
 <a7cc7791-c476-fd81-b79d-a151293b8302@arm.com>
 <864jen6k0i.wl-maz@kernel.org>
 <c773393c-221e-edd1-00b7-0ce6a2481c15@arm.com>
 <861q9q7vwr.wl-maz@kernel.org>
Message-ID: <ZcEPHyfQ4n23YOTW@linux.dev>

On Mon, Feb 05, 2024 at 03:50:12PM +0000, Marc Zyngier wrote:
> On Mon, 05 Feb 2024 15:37:34 +0000,
> James Clark <james.clark at arm.com> wrote:
> > 
> > Hmmm in that case if there's currently no way to distinguish between
> > normal VMs and pVMs in protected-mode then what I was thinking of
> > probably won't work.
> 
> Have you looked? kvm_vm_is_protected() has been in for a while, even
> if that's not a lot. The upcoming code will flesh this helper out,

Blame me for the bad intel. What I was mentioning earlier is that (1) we
use the hyp's shadowed vCPUs when running in protected mode and (2) we
don't sync PMU state into the shadow vCPU. So really PMU support for
non-protected guests has been broken since commit be66e67f1750 ("KVM:
arm64: Use the pKVM hyp vCPU structure in handle___kvm_vcpu_run()").

Fixing PMU support for non-protected guests implies the hypervisor will
conditionally trust data coming from the host based on the type of VM
that it is running.

For protected guests the hypervisor will need a private location to
do save/restore of the enable regs since I'm certain we will not trust
whatever the host tells us in these circumstances.

Both of these reasons has me feeling like the PMU context still needs to
be associated with the vCPU, though the tracing stuff can be percpu.

-- 
Thanks,
Oliver


From robin.murphy at arm.com  Mon Feb  5 08:43:27 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon,  5 Feb 2024 16:43:27 +0000
Subject: [PATCH] iommu/ipmmu-vmsa: Minor cleanups
Message-ID: <791877b0d310dc2ab7dc616d2786ab24252b9b8e.1707151207.git.robin.murphy@arm.com>

Remove the of_match_ptr() which was supposed to have gone long ago, but
managed to got lost in a fix-squashing mishap. On a similar theme, we
may as well also modernise the PM ops to get rid of the clunky #ifdefs,
and modernise the resource mapping to keep the checkpatch brigade happy.

Link: https://lore.kernel.org/linux-iommu/Yxni3d6CdI3FZ5D+ at 8bytes.org/
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/ipmmu-vmsa.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index ace1fc4bd34b..90d3f03242db 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -1005,7 +1005,6 @@ static const struct of_device_id ipmmu_of_ids[] = {
 static int ipmmu_probe(struct platform_device *pdev)
 {
 	struct ipmmu_vmsa_device *mmu;
-	struct resource *res;
 	int irq;
 	int ret;
 
@@ -1025,8 +1024,7 @@ static int ipmmu_probe(struct platform_device *pdev)
 		return ret;
 
 	/* Map I/O memory and request IRQ. */
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mmu->base = devm_ioremap_resource(&pdev->dev, res);
+	mmu->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(mmu->base))
 		return PTR_ERR(mmu->base);
 
@@ -1123,7 +1121,6 @@ static void ipmmu_remove(struct platform_device *pdev)
 	ipmmu_device_reset(mmu);
 }
 
-#ifdef CONFIG_PM_SLEEP
 static int ipmmu_resume_noirq(struct device *dev)
 {
 	struct ipmmu_vmsa_device *mmu = dev_get_drvdata(dev);
@@ -1153,18 +1150,14 @@ static int ipmmu_resume_noirq(struct device *dev)
 }
 
 static const struct dev_pm_ops ipmmu_pm  = {
-	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, ipmmu_resume_noirq)
+	NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, ipmmu_resume_noirq)
 };
-#define DEV_PM_OPS	&ipmmu_pm
-#else
-#define DEV_PM_OPS	NULL
-#endif /* CONFIG_PM_SLEEP */
 
 static struct platform_driver ipmmu_driver = {
 	.driver = {
 		.name = "ipmmu-vmsa",
-		.of_match_table = of_match_ptr(ipmmu_of_ids),
-		.pm = DEV_PM_OPS,
+		.of_match_table = ipmmu_of_ids,
+		.pm = pm_sleep_ptr(&ipmmu_pm),
 	},
 	.probe = ipmmu_probe,
 	.remove_new = ipmmu_remove,
-- 
2.39.2.101.g768bb238c484.dirty



From broonie at kernel.org  Mon Feb  5 08:58:20 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 5 Feb 2024 16:58:20 +0000
Subject: [PATCH v8 13/38] KVM: arm64: Manage GCS registers for guests
In-Reply-To: <8634u76i36.wl-maz@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <20240203-arm64-gcs-v8-13-c9fec77673ef@kernel.org>
 <868r3z6y6v.wl-maz@kernel.org>
 <825d2b35-fa10-43ad-b3b3-b29a77f3fed0@sirena.org.uk>
 <8634u76i36.wl-maz@kernel.org>
Message-ID: <ZcETrPAFFfgAy/PT@finisterre.sirena.org.uk>

On Mon, Feb 05, 2024 at 03:34:05PM +0000, Marc Zyngier wrote:
> Mark Brown <broonie at kernel.org> wrote:
> > On Mon, Feb 05, 2024 at 09:46:16AM +0000, Marc Zyngier wrote:

> > > We have had this discussion in the past. This must be based on the
> > > VM's configuration. Guarding the check with the host capability is a
> > > valuable optimisation, but that's nowhere near enough. See the series
> > > that I have posted on this very subject (you're on Cc), but you are
> > > welcome to invent your own mechanism in the meantime.

> > Right, which postdates the version you're replying to and isn't merged
> > yet - the current code was what you were asking for at the time.

> v1 and v2 predate it. And if the above is what I did ask, then I must
> have done a very poor job of explaining what was required. For which I
> apologise profusely.

To be clear it's what was asked for prior to the switch to the
forthcoming switch to the parsing idregs scheme, I haven't pulled in
your idregs work yet since it's being rapidly iterated and this is an
already large series with dependencies.

> > I'm
> > expecting to update all these feature series to work with that once it
> > gets finalised and merged but it's not there yet, I do see I forgot to
> > put a note in v9 about that like I did for dpISA - sorry about that, I
> > was too focused on the clone3() rework when rebasing onto the new
> > kernel.

> > This particular series isn't going to get merged for a while yet anyway
> > due to the time it'll take for userspace testing, I'm expecting your
> > series to be in by the time it becomes an issue.

> Right. Then I'll ignore it for the foreseeable future.

Actually now I think about it would you be open to merging the guest
context switching bit without the rest of the series (pending me fixing
the issues you raise of course)?  If so I'll split that bit out in the
hope that we can reduce the size of the series and CC list for the
userspace support which I imagine would make people a bit happier.

> > > > +		write_sysreg_s(ctxt_sys_reg(ctxt, GCSCRE0_EL1),
> > > > +			       SYS_GCSCRE0_EL1);
> > > > +	}

> > > For the benefit of the unsuspecting reviewers, and in the absence of a
> > > public specification (which the XML drop isn't), it would be good to
> > > have the commit message explaining the rationale of what gets saved
> > > when.

> > What are you looking for in terms of rationale here?  The KVM house
> > style is often very reliant on reader context so it would be good to
> > know what considerations you'd like to see explicitly addressed.

> Nothing to do with style, everything to do with substance: if nothing

The style I'm referring to there is the style for documentation.

> in the host kernel makes any use of these registers, why are they
> eagerly saved/restored on nVHE/hVHE? I'm sure you have a reason for
> it, but it isn't that obvious. Because these two modes need all the
> help they can get in terms of overhead reduction.

Ah, I see - yes, they should probably be moved somewhere else.  Though
I'm not clear why some of the other registers that we're saving and
restoring in the same place are being done eagerly?  The userspace
TPIDRs stand out for example, they're in taken care of in
__sysreg_save_user_state() which is called in the same paths.  IIRC my
thinking there was something along the lines of "this is where we save
and restore everything else that's just a general system register, I
should be consistent".

Am I right in thinking kvm_arch_vcpu_load()/_put() would make sense?
Everything in there currently looked like it was there more due to doing
something more complex than simple register save/restore and we weren't
worrying too much about what was going on with just the sysregs.

> > These
> > registers shouldn't do anything when we aren't running the guest so
> > they're not terribly ordering sensitive, the EL2 ones will need a bit
> > more consideration in the face of nested virt.

> The EL2 registers should follow the exact same pattern, specially once
> you fix the VNCR bugs I pointed out.

Great, that's what I'd thought thanks - I hadn't checked 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/20240205/f32e242b/attachment.sig>

From dianders at chromium.org  Mon Feb  5 09:02:08 2024
From: dianders at chromium.org (Doug Anderson)
Date: Mon, 5 Feb 2024 09:02:08 -0800
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
Message-ID: <CAD=FV=XupbtO3_+P9=XO26vH_5nALSSLZZHZywPSR_hQsWxM0Q@mail.gmail.com>

Hi,

On Sat, Feb 3, 2024 at 4:18?AM Mark Brown <broonie at kernel.org> wrote:
>
> Doug Anderson observed that ChromeOS crashes are being reported which
> include failing allocations of order 7 during core dumps due to ptrace
> allocating storage for regsets:
>
>   chrome: page allocation failure: order:7,
>           mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
>           nodemask=(null),cpuset=urgent,mems_allowed=0
>    ...
>   regset_get_alloc+0x1c/0x28
>   elf_core_dump+0x3d8/0xd8c
>   do_coredump+0xeb8/0x1378
>
> with further investigation showing that this is:
>
>    [   66.957385] DOUG: Allocating 279584 bytes
>
> which is the maximum size of the SVE regset. As Doug observes it is not
> entirely surprising that such a large allocation of contiguous memory might
> fail on a long running system.
>
> The SVE regset is currently sized to hold SVE registers with a VQ of
> SVE_VQ_MAX which is 512, substantially more than the architectural maximum
> of 16 which we might see even in a system emulating the limits of the
> architecture. Since we don't expose the size we tell the regset core
> externally let's define ARCH_SVE_VQ_MAX with the actual architectural
> maximum and use that for the regset, we'll still overallocate most of the
> time but much less so which will be helpful even if the core is fixed to
> not require contiguous allocations.
>
> We could also teach the ptrace core about runtime discoverable regset sizes
> but that would be a more invasive change and this is being observed in
> practical systems.
>
> Reported-by: Doug Anderson <dianders at chromium.org>
> Signed-off-by: Mark Brown <broonie at kernel.org>

Confirmed that when I send a "quit" signal to Chrome now that the
allocation I see for "core_note_type" NT_ARM_SVE goes down from
279,584 bytes (n=17474) to just 8,768 bytes (n=548). I'm not
intimately familiar with this code so I'll skip the Reviewed-by unless
someone thinks it would be valuable for me to analyze more. I think
there are already plenty of people who know this well, so for now,
just:

Tested-by: Douglas Anderson <dianders at chromium.org>


From bvanassche at acm.org  Mon Feb  5 09:08:08 2024
From: bvanassche at acm.org (Bart Van Assche)
Date: Mon, 5 Feb 2024 09:08:08 -0800
Subject: [PATCH v1 1/1] ufs: core: fix shift issue in ufshcd_clear_cmd
In-Reply-To: <20240205104905.24929-1-alice.chao@mediatek.com>
References: <20240205104905.24929-1-alice.chao@mediatek.com>
Message-ID: <55fa1c14-87ef-46ef-8871-f7139f86e8b7@acm.org>

On 2/5/24 02:49, alice.chao at mediatek.com wrote:
> When task_tag > 32 (in mcq mode), 1U << task_tag will out of bound
        ^^^^^^^^^^^^^
        task_tag >= 32 and sizeof(unsigned int) == 4

> for u32 mask. Fix this bug to prevent SHIFT_ISSUE (Bitwise shifts
> that are out of bounds for their data type).

Anyway:

Reviewed-by: Bart Van Assche <bvanassche at acm.org>


From Dave.Martin at arm.com  Mon Feb  5 09:11:59 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Mon, 5 Feb 2024 17:11:59 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
Message-ID: <ZcEW3y0IlEctOYBA@e133380.arm.com>

On Sat, Feb 03, 2024 at 12:16:49PM +0000, Mark Brown wrote:
> Doug Anderson observed that ChromeOS crashes are being reported which
> include failing allocations of order 7 during core dumps due to ptrace
> allocating storage for regsets:
> 
>   chrome: page allocation failure: order:7,
>           mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
>           nodemask=(null),cpuset=urgent,mems_allowed=0
>    ...
>   regset_get_alloc+0x1c/0x28
>   elf_core_dump+0x3d8/0xd8c
>   do_coredump+0xeb8/0x1378
> 
> with further investigation showing that this is:
> 
>    [   66.957385] DOUG: Allocating 279584 bytes
> 
> which is the maximum size of the SVE regset. As Doug observes it is not
> entirely surprising that such a large allocation of contiguous memory might
> fail on a long running system.
> 
> The SVE regset is currently sized to hold SVE registers with a VQ of
> SVE_VQ_MAX which is 512, substantially more than the architectural maximum
> of 16 which we might see even in a system emulating the limits of the
> architecture. Since we don't expose the size we tell the regset core
> externally let's define ARCH_SVE_VQ_MAX with the actual architectural
> maximum and use that for the regset, we'll still overallocate most of the
> time but much less so which will be helpful even if the core is fixed to
> not require contiguous allocations.
> 
> We could also teach the ptrace core about runtime discoverable regset sizes
> but that would be a more invasive change and this is being observed in
> practical systems.

This is not hard at all: see
27e64b4be4b8 ("regset: Add support for dynamically sized regsets") 

But since this is precisely what was ripped out, I guess adding it back
may be controversial (?)

> 
> Reported-by: Doug Anderson <dianders at chromium.org>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> We should probably also use the actual architectural limit for the
> bitmasks we use in the VL enumeration code, though that's both a little
> bit more involved and less immediately a problem.

Since these masks are 64 bytes each and rarely accessed, it seemed
pointless complexity to make them resizeable...

> ---
>  arch/arm64/include/asm/fpsimd.h | 10 +++++-----
>  arch/arm64/kernel/ptrace.c      |  3 ++-
>  2 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index 50e5f25d3024..cf5f31181bc8 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -62,12 +62,12 @@ static inline void cpacr_restore(unsigned long cpacr)
>   * When we defined the maximum SVE vector length we defined the ABI so
>   * that the maximum vector length included all the reserved for future
>   * expansion bits in ZCR rather than those just currently defined by
> - * the architecture. While SME follows a similar pattern the fact that
> - * it includes a square matrix means that any allocations that attempt
> - * to cover the maximum potential vector length (such as happen with
> - * the regset used for ptrace) end up being extremely large. Define
> - * the much lower actual limit for use in such situations.
> + * the architecture.  Using this length to allocate worst size buffers
> + * results in excessively large allocations, and this effect is even
> + * more pronounced for SME due to ZA.  Define more suitable VLs for
> + * these situations.
>   */
> +#define ARCH_SVE_VQ_MAX 16
>  #define SME_VQ_MAX	16

Ack, though part of the reason for not doing this was to discourage
people from allocating statically sized buffers in general.

If the kernel is now juggling two #defines for the maximum vector size,
this feels like it may seed bitrot...

> 
>  struct task_struct;
> diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
> index dc6cf0e37194..e3bef38fc2e2 100644
> --- a/arch/arm64/kernel/ptrace.c
> +++ b/arch/arm64/kernel/ptrace.c
> @@ -1500,7 +1500,8 @@ static const struct user_regset aarch64_regsets[] = {
>  #ifdef CONFIG_ARM64_SVE
>  	[REGSET_SVE] = { /* Scalable Vector Extension */
>  		.core_note_type = NT_ARM_SVE,
> -		.n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE),
> +		.n = DIV_ROUND_UP(SVE_PT_SIZE(ARCH_SVE_VQ_MAX,
> +					      SVE_PT_REGS_SVE),
>  				  SVE_VQ_BYTES),
>  		.size = SVE_VQ_BYTES,
>  		.align = SVE_VQ_BYTES,
> 
> ---
> base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
> change-id: 20240202-arm64-sve-ptrace-regset-size-21b0928969e1
> 
> Best regards,
> -- 
> Mark Brown <broonie at kernel.org>

This looks reasonable, but patching the .n fields doesn't look too bad
either; I'll post a patch separately for comparison.

[...]

Cheers
---Dave


From linux.amoon at gmail.com  Mon Feb  5 09:19:19 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  5 Feb 2024 22:49:19 +0530
Subject: [PATCHv1 1/5] arm64: dts: amlogic: Add cache information to the Amlogic GXBB and GXL SoC
In-Reply-To: <20240205171930.968-1-linux.amoon@gmail.com>
References: <20240205171930.968-1-linux.amoon@gmail.com>
Message-ID: <20240205171930.968-2-linux.amoon@gmail.com>

As per S905 and S905X datasheet add missing cache information to
the Amlogic GXBB and GXL SoC.

- Each Cortex-A53 core has 32KB of L1 instruction cache available and
	32KB of L1 data cache available.
- Along with 512KB Unified L2 cache.

To improve system performance.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
Datasheet
[0] https://dn.odroid.com/S905/DataSheet/S905_Public_Datasheet_V1.1.4.pdf
---
 arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 27 +++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 2673f0dbafe7..e141ade5e49b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -95,6 +95,12 @@ cpu0: cpu at 0 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
 			#cooling-cells = <2>;
@@ -105,6 +111,12 @@ cpu1: cpu at 1 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x1>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
 			#cooling-cells = <2>;
@@ -115,6 +127,12 @@ cpu2: cpu at 2 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x2>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
 			#cooling-cells = <2>;
@@ -125,6 +143,12 @@ cpu3: cpu at 3 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x3>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
 			#cooling-cells = <2>;
@@ -134,6 +158,9 @@ l2: l2-cache0 {
 			compatible = "cache";
 			cache-level = <2>;
 			cache-unified;
+			cache-size = <0x7d000>; /* L2. 512 KB */
+			cache-line-size = <64>;
+			cache-sets = <512>;
 		};
 	};
 
-- 
2.43.0



From linux.amoon at gmail.com  Mon Feb  5 09:19:20 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  5 Feb 2024 22:49:20 +0530
Subject: [PATCHv1 2/5] arm64: dts: amlogic: Add cache information to the Amlogic SM1 SoC
In-Reply-To: <20240205171930.968-1-linux.amoon@gmail.com>
References: <20240205171930.968-1-linux.amoon@gmail.com>
Message-ID: <20240205171930.968-3-linux.amoon@gmail.com>

As per S905X3 datasheet add missing cache information to the Amlogic
SM1 SoC. ARM Cortex-A55 CPU uses unified L3 cache instead of L2 cache.

- Each Cortex-A55 core has 32KB of L1 instruction cache available and
	32KB of L1 data cache available.
- Along with 512KB Unified L3 cache.

To improve system performance.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
Datasheet
[0] https://dn.odroid.com/S905X3/ODROID-C4/Docs/S905X3_Public_Datasheet_Hardkernel.pdf
[1] https://en.wikipedia.org/wiki/ARM_Cortex-A55
---
 arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 39 ++++++++++++++++++----
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
index 643f94d9d08e..403443e782e4 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
@@ -55,7 +55,13 @@ cpu0: cpu at 0 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
-			next-level-cache = <&l2>;
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
+			next-level-cache = <&l3>;
 			#cooling-cells = <2>;
 		};
 
@@ -64,7 +70,13 @@ cpu1: cpu at 1 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0 0x1>;
 			enable-method = "psci";
-			next-level-cache = <&l2>;
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
+			next-level-cache = <&l3>;
 			#cooling-cells = <2>;
 		};
 
@@ -73,7 +85,13 @@ cpu2: cpu at 2 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0 0x2>;
 			enable-method = "psci";
-			next-level-cache = <&l2>;
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
+			next-level-cache = <&l3>;
 			#cooling-cells = <2>;
 		};
 
@@ -82,14 +100,23 @@ cpu3: cpu at 3 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0 0x3>;
 			enable-method = "psci";
-			next-level-cache = <&l2>;
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
+			next-level-cache = <&l3>;
 			#cooling-cells = <2>;
 		};
 
-		l2: l2-cache0 {
+		l3: l3-cache0 {
 			compatible = "cache";
-			cache-level = <2>;
+			cache-level = <3>;
 			cache-unified;
+			cache-size = <0x7d000>; /* L2. 512 KB */
+			cache-line-size = <64>;
+			cache-sets = <512>;
 		};
 	};
 
-- 
2.43.0



From linux.amoon at gmail.com  Mon Feb  5 09:19:21 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  5 Feb 2024 22:49:21 +0530
Subject: [PATCHv1 3/5] arm64: dts: amlogic: Add cache information to the Amlogic G12A SoCS
In-Reply-To: <20240205171930.968-1-linux.amoon@gmail.com>
References: <20240205171930.968-1-linux.amoon@gmail.com>
Message-ID: <20240205171930.968-4-linux.amoon@gmail.com>

As per the S905X2 datasheet add missing cache information to the Amlogic
G12A SoC.

- Each Cortex-A53 core has 32KB of L1 instruction cache available and
	32KB of L1 data cache available.
- Along with 512KB Unified L2 cache.

To improve system performance.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
No public dataheet available, since S905X2 support Arm Cortex-A53 cpu
nence used the same cache size as S905 and S905X.
---
 arch/arm64/boot/dts/amlogic/meson-g12a.dtsi | 27 +++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
index 543e70669df5..6e1e3a3f5f18 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
@@ -17,6 +17,12 @@ cpu0: cpu at 0 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
 			next-level-cache = <&l2>;
 			#cooling-cells = <2>;
 		};
@@ -26,6 +32,12 @@ cpu1: cpu at 1 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x1>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
 			next-level-cache = <&l2>;
 			#cooling-cells = <2>;
 		};
@@ -35,6 +47,12 @@ cpu2: cpu at 2 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x2>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
 			next-level-cache = <&l2>;
 			#cooling-cells = <2>;
 		};
@@ -44,6 +62,12 @@ cpu3: cpu at 3 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x3>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
 			next-level-cache = <&l2>;
 			#cooling-cells = <2>;
 		};
@@ -52,6 +76,9 @@ l2: l2-cache0 {
 			compatible = "cache";
 			cache-level = <2>;
 			cache-unified;
+			cache-size = <0x7d000>; /* L2. 512 KB */
+			cache-line-size = <64>;
+			cache-sets = <512>;
 		};
 	};
 
-- 
2.43.0



From linux.amoon at gmail.com  Mon Feb  5 09:19:22 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  5 Feb 2024 22:49:22 +0530
Subject: [PATCHv1 4/5] arm64: dts: amlogic: Add cache information to the Amlogic S922X SoC
In-Reply-To: <20240205171930.968-1-linux.amoon@gmail.com>
References: <20240205171930.968-1-linux.amoon@gmail.com>
Message-ID: <20240205171930.968-5-linux.amoon@gmail.com>

As per S922X datasheet add missing cache information to the Amlogic
S922X SoC.

- Each Cortex-A53 core has 32 KB of instruction cache and
	32 KB of L1 data cache available.
- Each Cortex-A73 core has 64 KB of L1 instruction cache and
	64 KB of L1 data cache available.
- The little (A53) cluster has 512 KB of unified L2 cache available.
- The big (A73) cluster has 1 MB of unified L2 cache available.

To improve system performance.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
[0] https://dn.odroid.com/S922X/ODROID-N2/Datasheet/S922X_Public_Datasheet_V0.2.pdf
[1] https://en.wikipedia.org/wiki/ARM_Cortex-A73
[2] https://en.wikipedia.org/wiki/ARM_Cortex-A53
---
 arch/arm64/boot/dts/amlogic/meson-g12b.dtsi | 62 ++++++++++++++++++---
 1 file changed, 55 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
index 86e6ceb31d5e..624c6fd763ac 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
@@ -49,7 +49,13 @@ cpu0: cpu at 0 {
 			reg = <0x0 0x0>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <592>;
-			next-level-cache = <&l2>;
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
+			next-level-cache = <&l2_cache_l>;
 			#cooling-cells = <2>;
 		};
 
@@ -59,7 +65,13 @@ cpu1: cpu at 1 {
 			reg = <0x0 0x1>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <592>;
-			next-level-cache = <&l2>;
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
+			next-level-cache = <&l2_cache_l>;
 			#cooling-cells = <2>;
 		};
 
@@ -69,7 +81,13 @@ cpu100: cpu at 100 {
 			reg = <0x0 0x100>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
-			next-level-cache = <&l2>;
+			d-cache-line-size = <64>;
+			d-cache-size = <0x10000>;
+			d-cache-sets = <64>;
+			i-cache-line-size = <64>;
+			i-cache-size = <0x10000>;
+			i-cache-sets = <64>;
+			next-level-cache = <&l2_cache_b>;
 			#cooling-cells = <2>;
 		};
 
@@ -79,7 +97,13 @@ cpu101: cpu at 101 {
 			reg = <0x0 0x101>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
-			next-level-cache = <&l2>;
+			d-cache-line-size = <64>;
+			d-cache-size = <0x10000>;
+			d-cache-sets = <64>;
+			i-cache-line-size = <64>;
+			i-cache-size = <0x10000>;
+			i-cache-sets = <64>;
+			next-level-cache = <&l2_cache_b>;
 			#cooling-cells = <2>;
 		};
 
@@ -89,7 +113,13 @@ cpu102: cpu at 102 {
 			reg = <0x0 0x102>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
-			next-level-cache = <&l2>;
+			d-cache-line-size = <64>;
+			d-cache-size = <0x10000>;
+			d-cache-sets = <64>;
+			i-cache-line-size = <64>;
+			i-cache-size = <0x10000>;
+			i-cache-sets = <64>;
+			next-level-cache = <&l2_cache_b>;
 			#cooling-cells = <2>;
 		};
 
@@ -99,14 +129,32 @@ cpu103: cpu at 103 {
 			reg = <0x0 0x103>;
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
-			next-level-cache = <&l2>;
+			d-cache-line-size = <64>;
+			d-cache-size = <0x10000>;
+			d-cache-sets = <64>;
+			i-cache-line-size = <64>;
+			i-cache-size = <0x10000>;
+			i-cache-sets = <64>;
+			next-level-cache = <&l2_cache_b>;
 			#cooling-cells = <2>;
 		};
 
-		l2: l2-cache0 {
+		l2_cache_l: l2-cache-cluster0 {
 			compatible = "cache";
 			cache-level = <2>;
 			cache-unified;
+			cache-size = <0x80000>;
+			cache-line-size = <64>;
+			cache-sets = <512>;
+		};
+
+		l2_cache_b: l2-cache-cluster1 {
+			compatible = "cache";
+			cache-level = <2>;
+			cache-unified;
+			cache-size = <0x100000>;
+			cache-line-size = <64>;
+			cache-sets = <512>;
 		};
 	};
 };
-- 
2.43.0



From linux.amoon at gmail.com  Mon Feb  5 09:19:23 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon,  5 Feb 2024 22:49:23 +0530
Subject: [PATCHv1 5/5] arm64: dts: amlogic: Add cache information to the Amlogic A7 SoC
In-Reply-To: <20240205171930.968-1-linux.amoon@gmail.com>
References: <20240205171930.968-1-linux.amoon@gmail.com>
Message-ID: <20240205171930.968-6-linux.amoon@gmail.com>

As per A311D datasheet add missing cache information to the Amlogic A7 SoC.

- Each Cortex-A53 core has 32 KB of instruction cache and
	32 KB of L1 data cache available.
- Each Cortex-A73 core has 64 KB of L1 instruction cache and
	64 KB of L1 data cache available.
- The little (A53) cluster has 512 KB of unified L2 cache available.
- The big (A73) cluster has 1 MB of unified L2 cache available.

To improve system performance.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
[0] https://dl.khadas.com/products/vim4/datasheet/a311d2_quick_reference_manual_v0.6.pdf
[1] https://en.wikipedia.org/wiki/ARM_Cortex-A73
[2] https://en.wikipedia.org/wiki/ARM_Cortex-A53
---
 arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 74 +++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index a03c7667d2b6..72dedc40f460 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -52,6 +52,13 @@ cpu100: cpu at 100 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x100>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
+			next-level-cache = <&l2_cache_l>;
 		};
 
 		cpu101: cpu at 101{
@@ -59,6 +66,13 @@ cpu101: cpu at 101{
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x101>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
+			next-level-cache = <&l2_cache_l>;
 		};
 
 		cpu102: cpu at 102 {
@@ -66,6 +80,13 @@ cpu102: cpu at 102 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x102>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
+			next-level-cache = <&l2_cache_l>;
 		};
 
 		cpu103: cpu at 103 {
@@ -73,6 +94,13 @@ cpu103: cpu at 103 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x103>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
+			next-level-cache = <&l2_cache_l>;
 		};
 
 		cpu0: cpu at 0 {
@@ -80,6 +108,13 @@ cpu0: cpu at 0 {
 			compatible = "arm,cortex-a73";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			d-cache-line-size = <64>;
+			d-cache-size = <0x10000>;
+			d-cache-sets = <64>;
+			i-cache-line-size = <64>;
+			i-cache-size = <0x10000>;
+			i-cache-sets = <64>;
+			next-level-cache = <&l2_cache_b>;
 		};
 
 		cpu1: cpu at 1 {
@@ -87,6 +122,13 @@ cpu1: cpu at 1 {
 			compatible = "arm,cortex-a73";
 			reg = <0x0 0x1>;
 			enable-method = "psci";
+			d-cache-line-size = <64>;
+			d-cache-size = <0x10000>;
+			d-cache-sets = <64>;
+			i-cache-line-size = <64>;
+			i-cache-size = <0x10000>;
+			i-cache-sets = <64>;
+			next-level-cache = <&l2_cache_b>;
 		};
 
 		cpu2: cpu at 2 {
@@ -94,6 +136,13 @@ cpu2: cpu at 2 {
 			compatible = "arm,cortex-a73";
 			reg = <0x0 0x2>;
 			enable-method = "psci";
+			d-cache-line-size = <64>;
+			d-cache-size = <0x10000>;
+			d-cache-sets = <64>;
+			i-cache-line-size = <64>;
+			i-cache-size = <0x10000>;
+			i-cache-sets = <64>;
+			next-level-cache = <&l2_cache_b>;
 		};
 
 		cpu3: cpu at 3 {
@@ -101,6 +150,31 @@ cpu3: cpu at 3 {
 			compatible = "arm,cortex-a73";
 			reg = <0x0 0x3>;
 			enable-method = "psci";
+			d-cache-line-size = <64>;
+			d-cache-size = <0x10000>;
+			d-cache-sets = <64>;
+			i-cache-line-size = <64>;
+			i-cache-size = <0x10000>;
+			i-cache-sets = <64>;
+			next-level-cache = <&l2_cache_b>;
+		};
+
+		l2_cache_l: l2-cache-cluster0 {
+			compatible = "cache";
+			cache-level = <2>;
+			cache-unified;
+			cache-size = <0x80000>;
+			cache-line-size = <64>;
+			cache-sets = <512>;
+		};
+
+		l2_cache_b: l2-cache-cluster1 {
+			compatible = "cache";
+			cache-level = <2>;
+			cache-unified;
+			cache-size = <0x100000>;
+			cache-line-size = <64>;
+			cache-sets = <1024>;
 		};
 	};
 
-- 
2.43.0



From robh at kernel.org  Mon Feb  5 09:21:20 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 5 Feb 2024 17:21:20 +0000
Subject: [PATCH 1/4] dt-bindings: hwinfo: samsung,exynos-chipid: add
 gs101-chipid compatible
In-Reply-To: <20240201172224.574238-1-alexey.klimov@linaro.org>
References: <20240201172224.574238-1-alexey.klimov@linaro.org>
Message-ID: <170715368034.3642320.248183501361428491.robh@kernel.org>


On Thu, 01 Feb 2024 17:22:21 +0000, Alexey Klimov wrote:
> Add "google,gs101-chipid" compatible string to binding document.
> 
> Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
> ---
>  .../devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml        | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>



From neil.armstrong at linaro.org  Mon Feb  5 09:27:05 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 5 Feb 2024 18:27:05 +0100
Subject: [PATCH v9 07/12] clk: meson: add vclk driver
In-Reply-To: <1jfs0rywqi.fsf@starbuckisacylon.baylibre.com>
References: <20231124-amlogic-v6-4-upstream-dsi-ccf-vim3-v9-0-95256ed139e6@linaro.org>
 <20231124-amlogic-v6-4-upstream-dsi-ccf-vim3-v9-7-95256ed139e6@linaro.org>
 <1j7cm7dx1b.fsf@starbuckisacylon.baylibre.com>
 <4e5e33c1-45d5-4c83-b647-bfb603347156@linaro.org>
 <1jfs0rywqi.fsf@starbuckisacylon.baylibre.com>
Message-ID: <9d7b3a35-6d21-4b7a-8669-cf3610467cad@linaro.org>

On 27/11/2023 17:24, Jerome Brunet wrote:
> 
> On Mon 27 Nov 2023 at 17:14, Neil Armstrong <neil.armstrong at linaro.org> wrote:
> 
>> On 24/11/2023 15:41, Jerome Brunet wrote:
>>> On Fri 24 Nov 2023 at 09:41, Neil Armstrong <neil.armstrong at linaro.org>
>>> wrote:
>>>
>>>> The VCLK and VCLK_DIV clocks have supplementary bits.
>>>>
>>>> The VCLK has a "SOFT RESET" bit to toggle after the whole
>>>> VCLK sub-tree rate has been set, this is implemented in
>>>> the gate enable callback.
>>>>
>>>> The VCLK_DIV clocks as enable and reset bits used to disable
>>>> and reset the divider, associated with CLK_SET_RATE_GATE it ensures
>>>> the rate is set while the divider is disabled and in reset mode.
>>>>
>>>> The VCLK_DIV enable bit isn't implemented as a gate since it's part
>>>> of the divider logic and vendor does this exact sequence to ensure
>>>> the divider is correctly set.
>>>>
>>>> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
>>>> ---
>>>>    drivers/clk/meson/Kconfig  |   5 ++
>>>>    drivers/clk/meson/Makefile |   1 +
>>>>    drivers/clk/meson/vclk.c   | 141 +++++++++++++++++++++++++++++++++++++++++++++
>>>>    drivers/clk/meson/vclk.h   |  51 ++++++++++++++++
>>>>    4 files changed, 198 insertions(+)
>>>>
>>>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>>>> index 29ffd14d267b..59a40a49f8e1 100644
>>>> --- a/drivers/clk/meson/Kconfig
>>>> +++ b/drivers/clk/meson/Kconfig
>>>> @@ -30,6 +30,10 @@ config COMMON_CLK_MESON_VID_PLL_DIV
>>>>    	tristate
>>>>    	select COMMON_CLK_MESON_REGMAP
>>>>    +config COMMON_CLK_MESON_VCLK
>>>> +	tristate
>>>> +	select COMMON_CLK_MESON_REGMAP
>>>> +
>>>>    config COMMON_CLK_MESON_CLKC_UTILS
>>>>    	tristate
>>>>    @@ -140,6 +144,7 @@ config COMMON_CLK_G12A
>>>>    	select COMMON_CLK_MESON_EE_CLKC
>>>>    	select COMMON_CLK_MESON_CPU_DYNDIV
>>>>    	select COMMON_CLK_MESON_VID_PLL_DIV
>>>> +	select COMMON_CLK_MESON_VCLK
>>> This particular line belong in the next patch
>>>
>>>>    	select MFD_SYSCON
>>>>    	help
>>>>    	  Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
>>>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>>>> index 9ee4b954c896..9ba43fe7a07a 100644
>>>> --- a/drivers/clk/meson/Makefile
>>>> +++ b/drivers/clk/meson/Makefile
>>>> @@ -12,6 +12,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_VCLK) += vclk.o
>>>>      # Amlogic Clock controllers
>>>>    diff --git a/drivers/clk/meson/vclk.c b/drivers/clk/meson/vclk.c
>>>> new file mode 100644
>>>> index 000000000000..47f08a52b49f
>>>> --- /dev/null
>>>> +++ b/drivers/clk/meson/vclk.c
>>>> @@ -0,0 +1,141 @@
>>>> +// SPDX-License-Identifier: GPL-2.0
>>>> +/*
>>>> + * Copyright (c) 2023 Neil Armstrong <neil.armstrong at linaro.org>
>>>> + */
>>>> +
>>>> +#include <linux/module.h>
>>>> +#include "vclk.h"
>>>> +
>>>> +/* The VCLK gate has a supplementary reset bit to pulse after ungating */
>>>> +
>>>> +static inline struct clk_regmap_vclk_data *
>>>> +clk_get_regmap_vclk_data(struct clk_regmap *clk)
>>>> +{
>>>> +	return (struct clk_regmap_vclk_data *)clk->data;
>>>> +}
>>>> +
>>>> +static int clk_regmap_vclk_enable(struct clk_hw *hw)
>>>> +{
>>>> +	struct clk_regmap *clk = to_clk_regmap(hw);
>>>> +	struct clk_regmap_vclk_data *vclk = clk_get_regmap_vclk_data(clk);
>>>> +
>>>> +	meson_parm_write(clk->map, &vclk->enable, 1);
>>>> +
>>>> +	/* Do a reset pulse */
>>>> +	meson_parm_write(clk->map, &vclk->reset, 1);
>>>> +	meson_parm_write(clk->map, &vclk->reset, 0);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static void clk_regmap_vclk_disable(struct clk_hw *hw)
>>>> +{
>>>> +	struct clk_regmap *clk = to_clk_regmap(hw);
>>>> +	struct clk_regmap_vclk_data *vclk = clk_get_regmap_vclk_data(clk);
>>>> +
>>>> +	meson_parm_write(clk->map, &vclk->enable, 0);
>>>> +}
>>>> +
>>>> +static int clk_regmap_vclk_is_enabled(struct clk_hw *hw)
>>>> +{
>>>> +	struct clk_regmap *clk = to_clk_regmap(hw);
>>>> +	struct clk_regmap_vclk_data *vclk = clk_get_regmap_vclk_data(clk);
>>>> +
>>>> +	return meson_parm_read(clk->map, &vclk->enable);
>>>> +}
>>>> +
>>>> +const struct clk_ops clk_regmap_vclk_ops = {
>>>> +	.enable = clk_regmap_vclk_enable,
>>>> +	.disable = clk_regmap_vclk_disable,
>>>> +	.is_enabled = clk_regmap_vclk_is_enabled,
>>>> +};
>>>> +EXPORT_SYMBOL_GPL(clk_regmap_vclk_ops);
>>> s/clk_regmap_vclk/meson_vclk at least for what is exported, ideally most
>>> all the code.
>>> I get clk_regmap_ comes from code copied from clk_regmap.c.
>>> The reason the this part is different (and not using parm) if that when
>>> I converted amlogic to regmap, I hope we could make this generic,
>>> possibly converging between aml and qcom (which was the only other
>>> platform using regmap for clock at the time). This is why clk_regmap.c
>>> is a bit different from the other driver.
>>> For the aml specific drivers, best to look at the mpll or cpu-dyndiv one.
>>>
>>>> +
>>>> +/* The VCLK Divider has supplementary reset & enable bits */
>>>> +
>>>> +static inline struct clk_regmap_vclk_div_data *
>>>> +clk_get_regmap_vclk_div_data(struct clk_regmap *clk)
>>>> +{
>>>> +	return (struct clk_regmap_vclk_div_data *)clk->data;
>>>> +}
>>>> +
>>>> +static unsigned long clk_regmap_vclk_div_recalc_rate(struct clk_hw *hw,
>>>> +						     unsigned long prate)
>>>> +{
>>>> +	struct clk_regmap *clk = to_clk_regmap(hw);
>>>> +	struct clk_regmap_vclk_div_data *vclk = clk_get_regmap_vclk_div_data(clk);
>>>> +
>>>> +	return divider_recalc_rate(hw, prate, meson_parm_read(clk->map, &vclk->div),
>>>> +				   vclk->table, vclk->flags, vclk->div.width);
>>>> +}
>>>> +
>>>> +static int clk_regmap_vclk_div_determine_rate(struct clk_hw *hw,
>>>> +					      struct clk_rate_request *req)
>>>> +{
>>>> +	struct clk_regmap *clk = to_clk_regmap(hw);
>>>> +	struct clk_regmap_vclk_div_data *vclk = clk_get_regmap_vclk_div_data(clk);
>>>> +
>>>> +	return divider_determine_rate(hw, req, vclk->table, vclk->div.width,
>>>> +				      vclk->flags);
>>>> +}
>>>> +
>>>> +static int clk_regmap_vclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
>>>> +					unsigned long parent_rate)
>>>> +{
>>>> +	struct clk_regmap *clk = to_clk_regmap(hw);
>>>> +	struct clk_regmap_vclk_div_data *vclk = clk_get_regmap_vclk_div_data(clk);
>>>> +	int ret;
>>>> +
>>>> +	ret = divider_get_val(rate, parent_rate, vclk->table, vclk->div.width,
>>>> +			      vclk->flags);
>>>> +	if (ret < 0)
>>>> +		return ret;
>>>> +
>>>> +	meson_parm_write(clk->map, &vclk->div, ret);
>>>> +
>>>> +	return 0;
>>>> +};
>>>> +
>>>> +static int clk_regmap_vclk_div_enable(struct clk_hw *hw)
>>>> +{
>>>> +	struct clk_regmap *clk = to_clk_regmap(hw);
>>>> +	struct clk_regmap_vclk_div_data *vclk = clk_get_regmap_vclk_div_data(clk);
>>>> +
>>>> +	/* Unreset the divider when ungating */
>>>> +	meson_parm_write(clk->map, &vclk->reset, 0);
>>>> +	meson_parm_write(clk->map, &vclk->enable, 1);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static void clk_regmap_vclk_div_disable(struct clk_hw *hw)
>>>> +{
>>>> +	struct clk_regmap *clk = to_clk_regmap(hw);
>>>> +	struct clk_regmap_vclk_div_data *vclk = clk_get_regmap_vclk_div_data(clk);
>>>> +
>>>> +	/* Reset the divider when gating */
>>>> +	meson_parm_write(clk->map, &vclk->enable, 0);
>>>> +	meson_parm_write(clk->map, &vclk->reset, 1);
>>>> +}
>>>> +
>>>> +static int clk_regmap_vclk_div_is_enabled(struct clk_hw *hw)
>>>> +{
>>>> +	struct clk_regmap *clk = to_clk_regmap(hw);
>>>> +	struct clk_regmap_vclk_div_data *vclk = clk_get_regmap_vclk_div_data(clk);
>>>> +
>>>> +	return meson_parm_read(clk->map, &vclk->enable);
>>>> +}
>>>> +
>>>> +const struct clk_ops clk_regmap_vclk_div_ops = {
>>>> +	.recalc_rate = clk_regmap_vclk_div_recalc_rate,
>>>> +	.determine_rate = clk_regmap_vclk_div_determine_rate,
>>>> +	.set_rate = clk_regmap_vclk_div_set_rate,
>>>> +	.enable = clk_regmap_vclk_div_enable,
>>>> +	.disable = clk_regmap_vclk_div_disable,
>>>> +	.is_enabled = clk_regmap_vclk_div_is_enabled,
>>>> +};
>>>> +EXPORT_SYMBOL_GPL(clk_regmap_vclk_div_ops);
>>>> +
>>>> +MODULE_DESCRIPTION("Amlogic vclk clock driver");
>>>> +MODULE_AUTHOR("Neil Armstrong <neil.armstrong at linaro.org>");
>>>> +MODULE_LICENSE("GPL v2");
>>>> diff --git a/drivers/clk/meson/vclk.h b/drivers/clk/meson/vclk.h
>>>> new file mode 100644
>>>> index 000000000000..4f25d7ad2717
>>>> --- /dev/null
>>>> +++ b/drivers/clk/meson/vclk.h
>>
>> Is vclk.c/h ok ? clk-vclk doesn't look pretty, but I can switch to it to
>> keep files organized.
> 
> I don't have a strong opinion about it.
> I would have suggested vclk-div.c/h - like sclk ... but you do have gate
> ops in there, so ... :/
> 
> This made me realize that one does not really go without the other.
> It is more a coherent block, isn't it ?
> Would it make more sense to have these 2 merged in a single clk_ops ?

No those a 2 separate blocks, one is for VCLK clock input and the other is for the DIV
block, and the reset isn't used in the same way so I can't merge them.

> 
> It's bit late to point this out, sorry about that.
> 
> I let you decide whether to merge the ops or not and which name to pick.
> 
> If you keep them separated, meson_vclk_gate_ops instead of just
> meson_vclk_ops, to make things clear.

Ack

> 
>>
>> Neil
>>
>>>> @@ -0,0 +1,51 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>> +/*
>>>> + * Copyright (c) 2023 Neil Armstrong <neil.armstrong at linaro.org>
>>>> + */
>>>> +
>>>> +#ifndef __VCLK_H
>>>> +#define __VCLK_H
>>> This is too generic.
>>> Please add the MESON prefix like the other clock driver please.
>>>
>>>> +
>>>> +#include "clk-regmap.h"
>>>> +#include "parm.h"
>>>> +
>>>> +/**
>>>> + * struct clk_regmap_vclk_data - vclk regmap backed specific data
>>>> + *
>>>> + * @enable:	vclk enable field
>>>> + * @reset:	vclk reset field
>>>> + * @flags:	hardware-specific flags
>>>> + *
>>>> + * Flags:
>>>> + * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored
>>>> + */
>>>> +struct clk_regmap_vclk_data {
>>>> +	struct parm enable;
>>>> +	struct parm reset;
>>>> +	u8 flags;
>>>> +};
>>>> +
>>>> +extern const struct clk_ops clk_regmap_vclk_ops;
>>>> +
>>>> +/**
>>>> + * struct clk_regmap_vclk_div_data - vclk_div regmap back specific data
>>>> + *
>>>> + * @div:	divider field
>>>> + * @enable:	vclk divider enable field
>>>> + * @reset:	vclk divider reset field
>>>> + * @table:	array of value/divider pairs, last entry should have div = 0
>>>> + *
>>>> + * Flags:
>>>> + * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored
>>>> + */
>>>> +struct clk_regmap_vclk_div_data {
>>>> +	struct parm div;
>>>> +	struct parm enable;
>>>> +	struct parm reset;
>>>> +	const struct clk_div_table *table;
>>>> +	u8 flags;
>>>> +};
>>>> +
>>>> +extern const struct clk_ops clk_regmap_vclk_div_ops;
>>>> +
>>>> +#endif /* __VCLK_H */
>>>
> 
> 



From Dave.Martin at arm.com  Mon Feb  5 09:27:20 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Mon, 5 Feb 2024 17:27:20 +0000
Subject: [RFC PATCH] arm64/sve,sme: Refine scalable regset sizes at boot
Message-ID: <ZcEaeLeEG8ve+Yp7@e133380.arm.com>

Since [1] and [2], the ptrace core has used the static values in
struct user_regset to preallocate memory when reading a regset.
This results in allocating excessive memory for SVE and related
regsets which are not a fixed size, since the theoretical max size
of those regsets was deliberately made huge in case of future
expansion.

In practice, the regsets can be smaller -- usually _much_ smaller.

Since the max possible size of these regsets depends on how big the
CPUs' registers actually are, clamp the affected regset sizes once
the kernel has probed all boot-time CPUs.

This doesn't make memory allocation failures impossible on the
affected paths, but at least avoids stupidly large allocations.

[1]: commit b4e9c9549f62 ("introduction of regset ->get() wrappers,
switching ELF coredumps to those")

[2]: commit 7717cb9bdd04 ("regset: new method and helpers for it")

Reported-by: Douglas Anderson <dianders at chromium.org>
Link: https://lore.kernel.org/lkml/20240201171159.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924 at changeid/
Signed-off-by: Dave Martin <Dave.Martin at arm.com>
---

Only build-tested for now.

If a short-term fix is needed, Mark Brown's patch [3] looks like the
lower-risk option, but there seems to be outstanding discussion about
whether this change will actually fix the issue reported above or just
make it less likely to fire.  See the Link above.

This patch duplicates logic between the compiled-in regset->n values and
those computed after boot.  It might be better to compile in junk
values, since they should never get used anyway...

[3] https://lore.kernel.org/all/20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e at kernel.org/


 arch/arm64/include/asm/ptrace.h | 12 ++++++++++++
 arch/arm64/kernel/fpsimd.c      |  3 +++
 arch/arm64/kernel/ptrace.c      | 22 +++++++++++++++++++++-
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 47ec58031f11..609b963a05e0 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -389,5 +389,17 @@ static inline void procedure_link_pointer_set(struct pt_regs *regs,
 
 extern unsigned long profile_pc(struct pt_regs *regs);
 
+#ifdef CONFIG_ARM64_SVE
+void __init arch_ptrace_sve_init(unsigned int vq_max);
+#else
+static inline void __init arch_ptrace_sve_init(unsigned int vq_max) { }
+#endif
+
+#ifdef CONFIG_ARM64_SME
+void __init arch_ptrace_sme_init(unsigned int vq_max);
+#else
+static inline void __init arch_ptrace_sme_init(unsigned int vq_max) { }
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a5dc6f764195..5c2f91f84c31 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1189,6 +1189,7 @@ void __init sve_setup(void)
 		pr_warn("%s: unvirtualisable vector lengths present\n",
 			info->name);
 
+	arch_ptrace_sve_init(sve_vq_from_vl(info->max_vl));
 	sve_efi_setup();
 }
 
@@ -1309,6 +1310,8 @@ void __init sme_setup(void)
 		info->max_vl);
 	pr_info("SME: default vector length %u bytes per vector\n",
 		get_sme_default_vl());
+
+	arch_ptrace_sme_init(sve_vq_from_vl(info->max_vl));
 }
 
 #endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index dc6cf0e37194..466a0eb93123 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/audit.h>
+#include <linux/cache.h>
 #include <linux/compat.h>
 #include <linux/kernel.h>
 #include <linux/sched/signal.h>
@@ -1441,7 +1442,7 @@ enum aarch64_regset {
 #endif
 };
 
-static const struct user_regset aarch64_regsets[] = {
+static struct user_regset aarch64_regsets[] __ro_after_init = {
 	[REGSET_GPR] = {
 		.core_note_type = NT_PRSTATUS,
 		.n = sizeof(struct user_pt_regs) / sizeof(u64),
@@ -1596,6 +1597,25 @@ static const struct user_regset_view user_aarch64_view = {
 	.regsets = aarch64_regsets, .n = ARRAY_SIZE(aarch64_regsets)
 };
 
+#ifdef CONFIG_ARM64_SVE
+void __init arch_ptrace_sve_init(unsigned int vq_max)
+{
+	aarch64_regsets[REGSET_SVE].n = DIV_ROUND_UP(
+		SVE_PT_SIZE(vq_max, SVE_PT_REGS_SVE), SVE_VQ_BYTES);
+}
+#endif /* CONFIG_ARM64_SVE */
+
+#ifdef CONFIG_ARM64_SME
+void __init arch_ptrace_sme_init(unsigned int vq_max)
+{
+	aarch64_regsets[REGSET_SSVE].n = DIV_ROUND_UP(
+		SVE_PT_SIZE(vq_max, SVE_PT_REGS_SVE), SVE_VQ_BYTES);
+
+	aarch64_regsets[REGSET_ZA].n = DIV_ROUND_UP(
+		ZA_PT_SIZE(vq_max), SVE_VQ_BYTES);
+}
+#endif /* CONFIG_ARM64_SME */
+
 #ifdef CONFIG_COMPAT
 enum compat_regset {
 	REGSET_COMPAT_GPR,

base-commit: 54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478
-- 
2.34.1



From dianders at chromium.org  Mon Feb  5 09:26:30 2024
From: dianders at chromium.org (Douglas Anderson)
Date: Mon,  5 Feb 2024 09:26:30 -0800
Subject: [PATCH v2] regset: use kvzalloc() for regset_get_alloc()
Message-ID: <20240205092626.v2.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924@changeid>

While browsing through ChromeOS crash reports, I found one with an
allocation failure that looked like this:

  chrome: page allocation failure: order:7,
          mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
	  nodemask=(null),cpuset=urgent,mems_allowed=0
  CPU: 7 PID: 3295 Comm: chrome Not tainted
          5.15.133-20574-g8044615ac35c #1 (HASH:1162 1)
  Hardware name: Google Lazor (rev3 - 8) with KB Backlight (DT)
  Call trace:
  ...
  warn_alloc+0x104/0x174
  __alloc_pages+0x5f0/0x6e4
  kmalloc_order+0x44/0x98
  kmalloc_order_trace+0x34/0x124
  __kmalloc+0x228/0x36c
  __regset_get+0x68/0xcc
  regset_get_alloc+0x1c/0x28
  elf_core_dump+0x3d8/0xd8c
  do_coredump+0xeb8/0x1378
  get_signal+0x14c/0x804
  ...

An order 7 allocation is (1 << 7) contiguous pages, or 512K. It's not
a surprise that this allocation failed on a system that's been running
for a while.

More digging showed that it was fairly easy to see the order 7
allocation by just sending a SIGQUIT to chrome (or other processes) to
generate a core dump. The actual amount being allocated was 279,584
bytes and it was for "core_note_type" NT_ARM_SVE.

There was quite a bit of discussion [1] on the mailing lists in
response to my v1 patch attempting to switch to vmalloc. The overall
conclusion was that we could likely reduce the 279,584 byte allocation
by quite a bit and Mark Brown has sent a patch to that effect [2].
However even with the 279,584 byte allocation gone there are still
65,552 byte allocations. These are just barely more than the 65,536
bytes and thus would require an order 5 allocation.

An order 5 allocation is still something to avoid unless necessary and
nothing needs the memory here to be contiguous. Change the allocation
to kvzalloc() which should still be efficient for small allocations
but doesn't force the memory subsystem to work hard (and maybe fail)
at getting a large contiguous chunk.

[1] https://lore.kernel.org/r/20240201171159.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924 at changeid
[2] https://lore.kernel.org/r/20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e at kernel.org

Signed-off-by: Douglas Anderson <dianders at chromium.org>
---

Changes in v2:
- Use kvzalloc() instead of vmalloc().
- Update description based on v1 discussion.

 fs/binfmt_elf.c | 2 +-
 kernel/regset.c | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 5397b552fbeb..ac178ad38823 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1928,7 +1928,7 @@ static void free_note_info(struct elf_note_info *info)
 		threads = t->next;
 		WARN_ON(t->notes[0].data && t->notes[0].data != &t->prstatus);
 		for (i = 1; i < info->thread_notes; ++i)
-			kfree(t->notes[i].data);
+			kvfree(t->notes[i].data);
 		kfree(t);
 	}
 	kfree(info->psinfo.data);
diff --git a/kernel/regset.c b/kernel/regset.c
index 586823786f39..b2871fa68b2a 100644
--- a/kernel/regset.c
+++ b/kernel/regset.c
@@ -16,14 +16,14 @@ static int __regset_get(struct task_struct *target,
 	if (size > regset->n * regset->size)
 		size = regset->n * regset->size;
 	if (!p) {
-		to_free = p = kzalloc(size, GFP_KERNEL);
+		to_free = p = kvzalloc(size, GFP_KERNEL);
 		if (!p)
 			return -ENOMEM;
 	}
 	res = regset->regset_get(target, regset,
 			   (struct membuf){.p = p, .left = size});
 	if (res < 0) {
-		kfree(to_free);
+		kvfree(to_free);
 		return res;
 	}
 	*data = p;
@@ -71,6 +71,6 @@ int copy_regset_to_user(struct task_struct *target,
 	ret = regset_get_alloc(target, regset, size, &buf);
 	if (ret > 0)
 		ret = copy_to_user(data, buf, ret) ? -EFAULT : 0;
-	kfree(buf);
+	kvfree(buf);
 	return ret;
 }
-- 
2.43.0.594.gd9cf4e227d-goog



From daniel at makrotopia.org  Mon Feb  5 09:28:17 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Mon, 5 Feb 2024 17:28:17 +0000
Subject: [PATCH v2 1/2] dt-bindings: phy: mediatek,mt7988-xfi-tphy: add new
 bindings
Message-ID: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>

Add bindings for the MediaTek XFI Ethernet SerDes T-PHY found in the
MediaTek MT7988 SoC which can operate at various interfaces modes:

via USXGMII PCS:
 * USXGMII
 * 10GBase-R
 * 5GBase-R

via LynxI SGMII PCS:
 * 2500Base-X
 * 1000Base-X
 * Cisco SGMII (MAC side)

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v2: unify filename and compatible as requested

 .../phy/mediatek,mt7988-xfi-tphy.yaml         | 77 +++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml

diff --git a/Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml
new file mode 100644
index 0000000000000..e897118dcf7e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/mediatek,mt7988-xfi-tphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek XFI T-PHY
+
+maintainers:
+  - Daniel Golle <daniel at makrotopia.org>
+
+description:
+  The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes
+  used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in
+  MediaTek's 10G-capabale MT7988 SoC.
+
+properties:
+  compatible:
+    const: mediatek,mt7988-xfi-tphy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: XFI PHY clock
+      - description: XFI register clock
+
+  clock-names:
+    items:
+      - const: xfipll
+      - const: topxtal
+
+  resets:
+    items:
+      - description: PEXTP reset
+
+  mediatek,usxgmii-performance-errata:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      One instance of the T-PHY on MT7988 suffers from a performance
+      problem in 10GBase-R mode which needs a work-around in the driver.
+      The work-around is enabled using this flag.
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      phy at 11f20000 {
+        compatible = "mediatek,mt7988-xfi-tphy";
+        reg = <0 0x11f20000 0 0x10000>;
+        clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>,
+                 <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
+        clock-names = "xfipll", "topxtal";
+        resets = <&watchdog 14>;
+        mediatek,usxgmii-performance-errata;
+        #phy-cells = <0>;
+      };
+    };
+
+...
-- 
2.43.0


From Markus.Elfring at web.de  Mon Feb  5 09:28:31 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Mon, 5 Feb 2024 18:28:31 +0100
Subject: [PATCH] pmdomain: mediatek: Use
 devm_platform_get_and_ioremap_resource() in init_scp()
In-Reply-To: <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
References: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de>
 <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
Message-ID: <8f011126-c95a-4c71-8bc9-a6b0a5823c96@web.de>

>> +++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
>> @@ -441,8 +441,7 @@ static struct scp *init_scp(struct platform_device *pdev,
>>
>>         scp->dev = &pdev->dev;
>>
>> -       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> -       scp->base = devm_ioremap_resource(&pdev->dev, res);
>> +       scp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
>
> Given res is further unused, please use devm_platform_ioremap_resource()
> instead, and remove the local variable res.

I got another idea after looking at the implementation of the function
?devm_platform_get_and_ioremap_resource? once more.
https://elixir.bootlin.com/linux/v6.8-rc3/source/drivers/base/platform.c#L87

It seems that it is supported to pass a null pointer for the last parameter
(while this possibility is not mentioned in the interface description so far).
How do you think about to benefit from such a design option any more
(instead of the determination of a corresponding platform device)?

Regards,
Markus


From ulf.hansson at linaro.org  Mon Feb  5 09:28:47 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 5 Feb 2024 18:28:47 +0100
Subject: [PATCH v2 1/4] dt-bindings: mmc: fsl-imx-esdhc: add iommus property
In-Reply-To: <20240201-8qm_smmu-v2-1-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com> <20240201-8qm_smmu-v2-1-3d12a80201a3@nxp.com>
Message-ID: <CAPDyKFqyQxo+SSYb_+Nf3zcPcmhzCJSp69gJ15qexbuD_mJ=Yg@mail.gmail.com>

On Thu, 1 Feb 2024 at 21:23, Frank Li <Frank.Li at nxp.com> wrote:
>
> iMX95 and iMX8QM have smmu. Add property "iommus".
>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> index 82eb7a24c8578..0d8ed9d055ffe 100644
> --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> @@ -162,6 +162,9 @@ properties:
>        - const: ahb
>        - const: per
>
> +  iommus:
> +    maxItems: 1
> +
>    power-domains:
>      maxItems: 1
>
>
> --
> 2.34.1
>


From daniel at makrotopia.org  Mon Feb  5 09:29:36 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Mon, 5 Feb 2024 17:29:36 +0000
Subject: [PATCH v2 2/2] phy: add driver for MediaTek XFI T-PHY
In-Reply-To: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>
References: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>
Message-ID: <2972dfd0b9ca48174fbf49b9d162bac1a12b2331.1707153425.git.daniel@makrotopia.org>

Add driver for MediaTek's XFI T-PHY which can be found in the MT7988
SoC. The XFI T-PHY is a 10 Gigabit/s Ethernet SerDes PHY with muxes on
the internal side to be used with either USXGMII PCS or LynxI PCS,
depending on the selected PHY interface mode.

The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
PHY_INTERFACE_MODE_* corresponding to the supported modes:

 * USXGMII                 \
 * 10GBase-R                }- USXGMII PCS - XGDM  \
 * 5GBase-R                /                        \
                                                     }- Ethernet MAC
 * 2500Base-X              \                        /
 * 1000Base-X               }- LynxI PCS - GDM     /
 * Cisco SGMII (MAC side)  /

In order to work-around a performance issue present on the first of
two XFI T-PHYs present in MT7988, special tuning is applied which can be
selected by adding the 'mediatek,usxgmii-performance-errata' property to
the device tree node.

There is no documentation for most registers used for the
analog/tuning part, however, most of the registers have been partially
reverse-engineered from MediaTek's SDK implementation (an opaque
sequence of 32-bit register writes) and descriptions for all relevant
digital registers and bits such as resets and muxes have been supplied
by MediaTek.

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v2:
 * use IO helpers from mtk-io.h instead of rolling my own
 * use devm_clk_bulk_get()
 * yse devm_platform_ioremap_resource()
 * unify name and description everywhere
 * invert bool is_xgmii into bool use_lynxi_pcs and add comments
   describing the meaning of each of the stack variables
 * not much we can do about remaining magic values unless MTK provides
   definitions for them

 MAINTAINERS                             |   1 +
 drivers/phy/mediatek/Kconfig            |  12 +
 drivers/phy/mediatek/Makefile           |   1 +
 drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 360 ++++++++++++++++++++++++
 4 files changed, 374 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ff059e870a444..72270296de2bd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13729,6 +13729,7 @@ L:	netdev at vger.kernel.org
 S:	Maintained
 F:	drivers/net/phy/mediatek-ge-soc.c
 F:	drivers/net/phy/mediatek-ge.c
+F:	drivers/phy/mediatek/phy-mtk-xfi-tphy.c
 
 MEDIATEK I2C CONTROLLER DRIVER
 M:	Qii Wang <qii.wang at mediatek.com>
diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index 3125ecb5d119f..be2abf642f2f3 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -13,6 +13,18 @@ config PHY_MTK_PCIE
 	  callback for PCIe GEN3 port, it supports software efuse
 	  initialization.
 
+config PHY_MTK_XFI_TPHY
+	tristate "MediaTek 10GE SerDes XFI T-PHY driver"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on OF && OF_ADDRESS
+	depends on HAS_IOMEM
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for MediaTek XFI T-PHY driver.
+	  The driver provides access to the Ethernet SerDes T-PHY supporting
+	  1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
+	  via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
+
 config PHY_MTK_TPHY
 	tristate "MediaTek T-PHY Driver"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index c9a50395533eb..fa7217178e7f4 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
 obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
 obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
+obj-$(CONFIG_PHY_MTK_XFI_TPHY)		+= phy-mtk-xfi-tphy.o
 
 phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
 phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
new file mode 100644
index 0000000000000..551d6cee33f94
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
@@ -0,0 +1,360 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* MediaTek 10GE SerDes XFI T-PHY driver
+ *
+ * Copyright (c) 2024 Daniel Golle <daniel at makrotopia.org>
+ *                    Bc-bocun Chen <bc-bocun.chen at mediatek.com>
+ * based on mtk_usxgmii.c and mtk_sgmii.c found in MediaTek's SDK (GPL-2.0)
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Henry Yen <henry.yen at mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
+
+#include "phy-mtk-io.h"
+
+#define MTK_XFI_TPHY_NUM_CLOCKS		2
+
+#define REG_DIG_GLB_70			0x0070
+#define  XTP_PCS_RX_EQ_IN_PROGRESS(x)	FIELD_PREP(GENMASK(25, 24), (x))
+#define  XTP_PCS_MODE_MASK		GENMASK(17, 16)
+#define  XTP_PCS_MODE(x)		FIELD_PREP(GENMASK(17, 16), (x))
+#define  XTP_PCS_RST_B			BIT(15)
+#define  XTP_FRC_PCS_RST_B		BIT(14)
+#define  XTP_PCS_PWD_SYNC_MASK		GENMASK(13, 12)
+#define  XTP_PCS_PWD_SYNC(x)		FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
+#define  XTP_PCS_PWD_ASYNC_MASK		GENMASK(11, 10)
+#define  XTP_PCS_PWD_ASYNC(x)		FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
+#define  XTP_FRC_PCS_PWD_ASYNC		BIT(8)
+#define  XTP_PCS_UPDT			BIT(4)
+#define  XTP_PCS_IN_FR_RG		BIT(0)
+
+#define REG_DIG_GLB_F4			0x00f4
+#define  XFI_DPHY_PCS_SEL		BIT(0)
+#define   XFI_DPHY_PCS_SEL_SGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 1)
+#define   XFI_DPHY_PCS_SEL_USXGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 0)
+#define  XFI_DPHY_AD_SGDT_FRC_EN	BIT(5)
+
+#define REG_DIG_LN_TRX_40		0x3040
+#define  XTP_LN_FRC_TX_DATA_EN		BIT(29)
+#define  XTP_LN_TX_DATA_EN		BIT(28)
+
+#define REG_DIG_LN_TRX_B0		0x30b0
+#define  XTP_LN_FRC_TX_MACCK_EN		BIT(5)
+#define  XTP_LN_TX_MACCK_EN		BIT(4)
+
+#define REG_ANA_GLB_D0			0x90d0
+#define  XTP_GLB_USXGMII_SEL_MASK	GENMASK(3, 1)
+#define  XTP_GLB_USXGMII_SEL(x)		FIELD_PREP(GENMASK(3, 1), (x))
+#define  XTP_GLB_USXGMII_EN		BIT(0)
+
+struct mtk_xfi_tphy {
+	void __iomem		*base;
+	struct device		*dev;
+	struct reset_control	*reset;
+	struct clk_bulk_data	clocks[MTK_XFI_TPHY_NUM_CLOCKS];
+	bool			da_war;
+};
+
+static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
+			       phy_interface_t interface)
+{
+	/* Override 10GBase-R tuning value if work-around is selected */
+	bool da_war = (xfi_tphy->da_war && (interface == PHY_INTERFACE_MODE_10GBASER));
+	/* Bools to make setting up values for specific PHY speeds easier */
+	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
+	bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
+		      interface == PHY_INTERFACE_MODE_SGMII);
+	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
+		       interface == PHY_INTERFACE_MODE_USXGMII);
+	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
+	/* Bool to configure input mux to either
+	 *  - USXGMII PCS (64b/66b coding) for 5G/10G
+	 *  - LynxI PCS (8b/10b coding) for 1G/2.5G
+	 */
+	bool use_lynxi_pcs = (is_1g || is_2p5g);
+
+	dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));
+
+	/* Setup PLL setting */
+	mtk_phy_update_bits(xfi_tphy->base + 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
+	mtk_phy_update_bits(xfi_tphy->base + 0x2030, 0x500, is_1g ? 0x0 : 0x500);
+	mtk_phy_update_bits(xfi_tphy->base + 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
+	mtk_phy_update_bits(xfi_tphy->base + 0x2040, 0x340000, is_1g ? 0x200000 : 0x140000);
+
+	/* Setup RXFE BW setting */
+	mtk_phy_update_bits(xfi_tphy->base + 0x50f0, 0xc10, is_1g ? 0x410 : is_5g ? 0x800 : 0x400);
+	mtk_phy_update_bits(xfi_tphy->base + 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
+
+	/* Setup RX CDR setting */
+	mtk_phy_update_bits(xfi_tphy->base + 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5078, 0xf000400, is_5g ? 0x8000000 :
+									0x7000400);
+	mtk_phy_update_bits(xfi_tphy->base + 0x507c, 0x5000500, is_5g ? 0x4000400 :
+									0x1000100);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5080, 0x1410, is_1g ? 0x400 : is_5g ? 0x1010 : 0x0);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5084, 0x30300, is_1g ? 0x30300 :
+							      is_5g ? 0x30100 :
+								      0x100);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5088, 0x60200, is_1g ? 0x20200 :
+							      is_5g ? 0x40000 :
+								      0x20000);
+
+	/* Setting RXFE adaptation range setting */
+	mtk_phy_update_bits(xfi_tphy->base + 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
+	mtk_phy_update_bits(xfi_tphy->base + 0x50a8, 0xee0000, is_5g ? 0x800000 :
+								       0x6e0000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);
+
+	if (is_10g)
+		writel(0x01423342, xfi_tphy->base + 0x00f8);
+	else if (is_5g)
+		writel(0x00a132a1, xfi_tphy->base + 0x00f8);
+	else if (is_2p5g)
+		writel(0x009c329c, xfi_tphy->base + 0x00f8);
+	else
+		writel(0x00fa32fa, xfi_tphy->base + 0x00f8);
+
+	/* Force SGDT_OUT off and select PCS */
+	mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_F4,
+			    XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
+			    XFI_DPHY_AD_SGDT_FRC_EN |
+			    (use_lynxi_pcs ? XFI_DPHY_PCS_SEL_SGMII :
+					     XFI_DPHY_PCS_SEL_USXGMII));
+
+	/* Force GLB_CKDET_OUT */
+	mtk_phy_set_bits(xfi_tphy->base + 0x0030, 0xc00);
+
+	/* Force AEQ on */
+	writel(XTP_PCS_RX_EQ_IN_PROGRESS(2) | XTP_PCS_PWD_SYNC(2) | XTP_PCS_PWD_ASYNC(2),
+	       xfi_tphy->base + REG_DIG_GLB_70);
+
+	usleep_range(1, 5);
+
+	/* Setup TX DA default value */
+	mtk_phy_update_bits(xfi_tphy->base + 0x30b0, 0x30, 0x20);
+	writel(0x00008a01, xfi_tphy->base + 0x3028);
+	writel(0x0000a884, xfi_tphy->base + 0x302c);
+	writel(0x00083002, xfi_tphy->base + 0x3024);
+
+	/* Setup RG default value */
+	if (use_lynxi_pcs) {
+		writel(0x00011110, xfi_tphy->base + 0x3010);
+		writel(0x40704000, xfi_tphy->base + 0x3048);
+	} else {
+		writel(0x00022220, xfi_tphy->base + 0x3010);
+		writel(0x0f020a01, xfi_tphy->base + 0x5064);
+		writel(0x06100600, xfi_tphy->base + 0x50b4);
+		if (interface == PHY_INTERFACE_MODE_USXGMII)
+			writel(0x40704000, xfi_tphy->base + 0x3048);
+		else
+			writel(0x47684100, xfi_tphy->base + 0x3048);
+	}
+
+	if (is_1g)
+		writel(0x0000c000, xfi_tphy->base + 0x3064);
+
+	/* Setup RX EQ initial value */
+	mtk_phy_update_bits(xfi_tphy->base + 0x3050, 0xa8000000,
+			    (interface != PHY_INTERFACE_MODE_10GBASER) ? 0xa8000000 : 0x0);
+	mtk_phy_update_bits(xfi_tphy->base + 0x3054, 0xaa,
+			    (interface != PHY_INTERFACE_MODE_10GBASER) ? 0xaa : 0x0);
+
+	if (!use_lynxi_pcs)
+		writel(0x00000f00, xfi_tphy->base + 0x306c);
+	else if (is_2p5g)
+		writel(0x22000f00, xfi_tphy->base + 0x306c);
+	else
+		writel(0x20200f00, xfi_tphy->base + 0x306c);
+
+	mtk_phy_update_bits(xfi_tphy->base + 0xa008, 0x10000, da_war ? 0x10000 : 0x0);
+
+	mtk_phy_update_bits(xfi_tphy->base + 0xa060, 0x50000, use_lynxi_pcs ? 0x50000 : 0x40000);
+
+	/* Setup PHYA speed */
+	mtk_phy_update_bits(xfi_tphy->base + REG_ANA_GLB_D0,
+			    XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
+			    is_10g ?  XTP_GLB_USXGMII_SEL(0) :
+			    is_5g ?   XTP_GLB_USXGMII_SEL(1) :
+			    is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
+				      XTP_GLB_USXGMII_SEL(3));
+	mtk_phy_set_bits(xfi_tphy->base + REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
+
+	/* Release reset */
+	mtk_phy_set_bits(xfi_tphy->base + REG_DIG_GLB_70,
+			 XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
+	usleep_range(150, 500);
+
+	/* Switch to P0 */
+	mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
+			    XTP_PCS_IN_FR_RG |
+			    XTP_FRC_PCS_PWD_ASYNC |
+			    XTP_PCS_PWD_ASYNC_MASK |
+			    XTP_PCS_PWD_SYNC_MASK |
+			    XTP_PCS_UPDT,
+			    XTP_PCS_IN_FR_RG |
+			    XTP_FRC_PCS_PWD_ASYNC |
+			    XTP_PCS_UPDT);
+	usleep_range(1, 5);
+
+	mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_70, XTP_PCS_UPDT);
+	usleep_range(15, 50);
+
+	if (use_lynxi_pcs) {
+		/* Switch to Gen2 */
+		mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
+				    XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
+				    XTP_PCS_MODE(1) | XTP_PCS_UPDT);
+	} else {
+		/* Switch to Gen3 */
+		mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
+				    XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
+				    XTP_PCS_MODE(2) | XTP_PCS_UPDT);
+	}
+	usleep_range(1, 5);
+
+	mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_70, XTP_PCS_UPDT);
+
+	usleep_range(100, 500);
+
+	/* Enable MAC CK */
+	mtk_phy_set_bits(xfi_tphy->base + REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
+	mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN);
+
+	/* Enable TX data */
+	mtk_phy_set_bits(xfi_tphy->base + REG_DIG_LN_TRX_40,
+			 XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
+	usleep_range(400, 1000);
+}
+
+static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int
+				 submode)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	if (mode != PHY_MODE_ETHERNET)
+		return -EINVAL;
+
+	switch (submode) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		mtk_xfi_tphy_setup(xfi_tphy, submode);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mtk_xfi_tphy_reset(struct phy *phy)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	reset_control_assert(xfi_tphy->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(xfi_tphy->reset);
+	usleep_range(1, 10);
+
+	return 0;
+}
+
+static int mtk_xfi_tphy_power_on(struct phy *phy)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
+}
+
+static int mtk_xfi_tphy_power_off(struct phy *phy)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_xfi_tphy_ops = {
+	.power_on	= mtk_xfi_tphy_power_on,
+	.power_off	= mtk_xfi_tphy_power_off,
+	.set_mode	= mtk_xfi_tphy_set_mode,
+	.reset		= mtk_xfi_tphy_reset,
+	.owner		= THIS_MODULE,
+};
+
+static int mtk_xfi_tphy_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct phy_provider *phy_provider;
+	struct mtk_xfi_tphy *xfi_tphy;
+	struct phy *phy;
+	int ret;
+
+	if (!np)
+		return -ENODEV;
+
+	xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
+	if (!xfi_tphy)
+		return -ENOMEM;
+
+	xfi_tphy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(xfi_tphy->base))
+		return PTR_ERR(xfi_tphy->base);
+
+	xfi_tphy->dev = &pdev->dev;
+	xfi_tphy->clocks[0].id = "topxtal";
+	xfi_tphy->clocks[1].id = "xfipll";
+	ret = devm_clk_bulk_get(&pdev->dev, MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
+	if (ret)
+		return ret;
+
+	xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(xfi_tphy->reset))
+		return PTR_ERR(xfi_tphy->reset);
+
+	xfi_tphy->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata");
+
+	phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	phy_set_drvdata(phy, xfi_tphy);
+	phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id mtk_xfi_tphy_match[] = {
+	{ .compatible = "mediatek,mt7988-xfi-tphy", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
+
+static struct platform_driver mtk_xfi_tphy_driver = {
+	.probe = mtk_xfi_tphy_probe,
+	.driver = {
+		.name = "mtk-xfi-tphy",
+		.of_match_table = mtk_xfi_tphy_match,
+	},
+};
+module_platform_driver(mtk_xfi_tphy_driver);
+
+MODULE_DESCRIPTION("MediaTek 10GE SerDes XFI T-PHY driver");
+MODULE_AUTHOR("Daniel Golle <daniel at makrotopia.org>");
+MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen at mediatek.com>");
+MODULE_LICENSE("GPL");
-- 
2.43.0


From Frank.Li at nxp.com  Mon Feb  5 09:33:21 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:21 -0500
Subject: [PATCH v10 00/14] PCI: imx6: Clean up and add imx95 pci support
Message-ID: <20240205173335.1120469-1-Frank.Li@nxp.com>

first 6 patches use drvdata: flags to simplify some switch-case code.
Improve maintaince and easy to read code.

Then add imx95 basic pci host function.

follow two patch do endpoint code clean up.
Then add imx95 basic endpont function.

Compared with v2, added EP function support and some fixes,  please change
notes at each patches.

Change from v9 to v10
- remove two patches:
>   dt-bindings: imx6q-pcie: Add linux,pci-domain as required for iMX8MQ
>   PCI: imx6: Using "linux,pci-domain" as slot ID
it is not good solution to fixed hardcode check to get controller id.
Will see better solution later.

dt-binding pass pcie node:

pcie0: pcie at 4c300000 {
                        compatible = "fsl,imx95-pcie";
                        reg = <0 0x4c300000 0 0x40000>,
                                <0 0x4c360000 0 0x10000>,
                                <0 0x4c340000 0 0x20000>,
                                <0 0x60100000 0 0xfe00000>;
                        reg-names = "dbi", "atu", "app", "config";
                        #address-cells = <3>;
                        #size-cells = <2>;
                        device_type = "pci";
                        linux,pci-domain = <0>;
                        bus-range = <0x00 0xff>;
                        ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
                                 <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
                        num-lanes = <1>;
                        num-viewport = <8>;
                        interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "msi";
                        #interrupt-cells = <1>;
                        interrupt-map-mask = <0 0 0 0x7>;
                        interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
                                        <0 0 0 2 &gic 0 0 GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
                                        <0 0 0 3 &gic 0 0 GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
                                        <0 0 0 4 &gic 0 0 GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
                        fsl,max-link-speed = <3>;
                        clocks = <&scmi_clk IMX95_CLK_HSIO>,
                                 <&scmi_clk IMX95_CLK_HSIOPLL>,
                                 <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
                                 <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
                        clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
                        assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
                                         <&scmi_clk IMX95_CLK_HSIOPLL>,
                                         <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
                        assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
                        assigned-clock-parents = <0>, <0>,
                                                 <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
                        power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
                        /* 0x30~0x37 stream id for pci0 */
                        /*
                         * iommu-map = <0x000 &apps_smmu 0x30 0x1>,
                         * <0x100 &apps_smmu 0x31 0x1>;
                         */
                        status = "disabled";
                };

pcie1: pcie-ep at 4c380000 {
                        compatible = "fsl,imx95-pcie-ep";
                        reg = <0 0x4c380000 0 0x20000>,
                              <0 0x4c3e0000 0 0x1000>,
                              <0 0x4c3a0000 0 0x1000>,
                              <0 0x4c3c0000 0 0x10000>,
                              <0 0x4c3f0000 0 0x10000>,
                              <0xa 0 1 0>;
                        reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
                        interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "dma";
                        fsl,max-link-speed = <3>;
                        clocks = <&scmi_clk IMX95_CLK_HSIO>,
                                 <&scmi_clk IMX95_CLK_HSIOPLL>,
                                 <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
                                 <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
                        clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
                        assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
                                         <&scmi_clk IMX95_CLK_HSIOPLL>,
                                         <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
                        assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
                        assigned-clock-parents = <0>, <0>,
                                                 <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
                        power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
                        status = "disabled";
                };

Frank Li (13):
  PCI: imx6: Simplify clock handling by using clk_bulk*() function
  PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
  PCI: imx6: Simplify reset handling by using by using
    *_FLAG_HAS_*_RESET
  PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
  PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
  PCI: imx6: Simplify switch-case logic by involve init_phy callback
  dt-bindings: imx6q-pcie: Clean up irrationality clocks check
  dt-bindings: imx6q-pcie: Restruct reg and reg-name
  PCI: imx6: Add iMX95 PCIe Root Complex support
  PCI: imx6: Clean up get addr_space code
  PCI: imx6: Add epc_features in imx6_pcie_drvdata
  dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
  PCI: imx6: Add iMX95 Endpoint (EP) support

Richard Zhu (1):
  dt-bindings: imx6q-pcie: Add imx95 pcie compatible string

 .../bindings/pci/fsl,imx6q-pcie-common.yaml   |  17 +-
 .../bindings/pci/fsl,imx6q-pcie-ep.yaml       |  46 +-
 .../bindings/pci/fsl,imx6q-pcie.yaml          |  49 +-
 drivers/pci/controller/dwc/pci-imx6.c         | 634 ++++++++++--------
 4 files changed, 436 insertions(+), 310 deletions(-)

-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:22 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:22 -0500
Subject: [PATCH v10 01/14] PCI: imx6: Simplify clock handling by using clk_bulk*() function
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-2-Frank.Li@nxp.com>

Refector the clock handling logic. Add 'clk_names' define in drvdata. Use
clk_bulk*() api simplify the code.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v9 to v10
    - fixed missed delete a case, which need failthrough to next one.
    Change from v8 to v9
    - change clks names
    - Add Manivannan's review tag
    
    Change from v7 to v8
    - update comment message
    - using ARRAY_SIZE to count clk_names.
    Change from v6 to v7
    - none
    Change from v4 to v5
    - update commit message
    - direct using clk name list, instead of macro
    - still keep caculate clk list count because sizeof return pre allocated
    array size.
    
    Change from v3 to v4
    - using clk_bulk_*() API
    Change from v1 to v3
    - none
    
    Change from v4 to v5
    - update commit message
    - direct using clk name list, instead of macro
    - still keep caculate clk list count because sizeof return pre allocated
    array size.
    
    Change from v3 to v4
    - using clk_bulk_*() API
    Change from v1 to v3
    - none
    
    Change from v8 to v9
    - change clks names
    - Add Manivannan's review tag
    
    Change from v7 to v8
    - update comment message
    - using ARRAY_SIZE to count clk_names.
    Change from v6 to v7
    - none
    Change from v4 to v5
    - update commit message
    - direct using clk name list, instead of macro
    - still keep caculate clk list count because sizeof return pre allocated
    array size.
    
    Change from v3 to v4
    - using clk_bulk_*() API
    Change from v1 to v3
    - none
    
    Change from v4 to v5
    - update commit message
    - direct using clk name list, instead of macro
    - still keep caculate clk list count because sizeof return pre allocated
    array size.
    
    Change from v3 to v4
    - using clk_bulk_*() API
    Change from v1 to v3
    - none

 drivers/pci/controller/dwc/pci-imx6.c | 138 ++++++++++----------------
 1 file changed, 50 insertions(+), 88 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 74703362aeec7..82854e94c5621 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -61,12 +61,16 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
 #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
 
+#define IMX6_PCIE_MAX_CLKS       6
+
 struct imx6_pcie_drvdata {
 	enum imx6_pcie_variants variant;
 	enum dw_pcie_device_mode mode;
 	u32 flags;
 	int dbi_length;
 	const char *gpr;
+	const char * const *clk_names;
+	const u32 clks_cnt;
 };
 
 struct imx6_pcie {
@@ -74,11 +78,7 @@ struct imx6_pcie {
 	int			reset_gpio;
 	bool			gpio_active_high;
 	bool			link_is_up;
-	struct clk		*pcie_bus;
-	struct clk		*pcie_phy;
-	struct clk		*pcie_inbound_axi;
-	struct clk		*pcie;
-	struct clk		*pcie_aux;
+	struct clk_bulk_data	clks[IMX6_PCIE_MAX_CLKS];
 	struct regmap		*iomuxc_gpr;
 	u16			msi_ctrl;
 	u32			controller_id;
@@ -407,13 +407,18 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
 
 static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
 {
-	unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy);
+	unsigned long phy_rate = 0;
 	int mult, div;
 	u16 val;
+	int i;
 
 	if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY))
 		return 0;
 
+	for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
+		if (strncmp(imx6_pcie->clks[i].id, "pcie_phy", 8) == 0)
+			phy_rate = clk_get_rate(imx6_pcie->clks[i].clk);
+
 	switch (phy_rate) {
 	case 125000000:
 		/*
@@ -550,19 +555,11 @@ static int imx6_pcie_attach_pd(struct device *dev)
 
 static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 {
-	struct dw_pcie *pci = imx6_pcie->pci;
-	struct device *dev = pci->dev;
 	unsigned int offset;
 	int ret = 0;
 
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX6SX:
-		ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
-		if (ret) {
-			dev_err(dev, "unable to enable pcie_axi clock\n");
-			break;
-		}
-
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
 		break;
@@ -589,12 +586,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 	case IMX8MQ_EP:
 	case IMX8MP:
 	case IMX8MP_EP:
-		ret = clk_prepare_enable(imx6_pcie->pcie_aux);
-		if (ret) {
-			dev_err(dev, "unable to enable pcie_aux clock\n");
-			break;
-		}
-
 		offset = imx6_pcie_grp_offset(imx6_pcie);
 		/*
 		 * Set the over ride low and enabled
@@ -615,9 +606,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
 {
 	switch (imx6_pcie->drvdata->variant) {
-	case IMX6SX:
-		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
-		break;
 	case IMX6QP:
 	case IMX6Q:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
@@ -631,14 +619,6 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
 				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
 				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
 		break;
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MQ:
-	case IMX8MQ_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		clk_disable_unprepare(imx6_pcie->pcie_aux);
-		break;
 	default:
 		break;
 	}
@@ -650,23 +630,9 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
 	struct device *dev = pci->dev;
 	int ret;
 
-	ret = clk_prepare_enable(imx6_pcie->pcie_phy);
-	if (ret) {
-		dev_err(dev, "unable to enable pcie_phy clock\n");
+	ret = clk_bulk_prepare_enable(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
+	if (ret)
 		return ret;
-	}
-
-	ret = clk_prepare_enable(imx6_pcie->pcie_bus);
-	if (ret) {
-		dev_err(dev, "unable to enable pcie_bus clock\n");
-		goto err_pcie_bus;
-	}
-
-	ret = clk_prepare_enable(imx6_pcie->pcie);
-	if (ret) {
-		dev_err(dev, "unable to enable pcie clock\n");
-		goto err_pcie;
-	}
 
 	ret = imx6_pcie_enable_ref_clk(imx6_pcie);
 	if (ret) {
@@ -679,11 +645,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
 	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);
+	clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
 
 	return ret;
 }
@@ -691,9 +653,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
 static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
 {
 	imx6_pcie_disable_ref_clk(imx6_pcie);
-	clk_disable_unprepare(imx6_pcie->pcie);
-	clk_disable_unprepare(imx6_pcie->pcie_bus);
-	clk_disable_unprepare(imx6_pcie->pcie_phy);
+	clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
 }
 
 static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
@@ -1252,6 +1212,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	struct device_node *node = dev->of_node;
 	int ret;
 	u16 val;
+	int i;
 
 	imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
 	if (!imx6_pcie)
@@ -1305,32 +1266,20 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 		return imx6_pcie->reset_gpio;
 	}
 
-	/* Fetch clocks */
-	imx6_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus");
-	if (IS_ERR(imx6_pcie->pcie_bus))
-		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_bus),
-				     "pcie_bus clock source missing or invalid\n");
+	if (imx6_pcie->drvdata->clks_cnt >= IMX6_PCIE_MAX_CLKS)
+		return dev_err_probe(dev, -ENOMEM, "clks_cnt is too big\n");
 
-	imx6_pcie->pcie = devm_clk_get(dev, "pcie");
-	if (IS_ERR(imx6_pcie->pcie))
-		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie),
-				     "pcie clock source missing or invalid\n");
+	for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
+		imx6_pcie->clks[i].id = imx6_pcie->drvdata->clk_names[i];
+
+	/* Fetch clocks */
+	ret = devm_clk_bulk_get(dev, imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
+	if (ret)
+		return ret;
 
 	switch (imx6_pcie->drvdata->variant) {
-	case IMX6SX:
-		imx6_pcie->pcie_inbound_axi = devm_clk_get(dev,
-							   "pcie_inbound_axi");
-		if (IS_ERR(imx6_pcie->pcie_inbound_axi))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_inbound_axi),
-					     "pcie_inbound_axi clock missing or invalid\n");
-		break;
 	case IMX8MQ:
 	case IMX8MQ_EP:
-		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
-		if (IS_ERR(imx6_pcie->pcie_aux))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
-					     "pcie_aux clock source missing or invalid\n");
-		fallthrough;
 	case IMX7D:
 		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
 			imx6_pcie->controller_id = 1;
@@ -1353,10 +1302,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	case IMX8MM_EP:
 	case IMX8MP:
 	case IMX8MP_EP:
-		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
-		if (IS_ERR(imx6_pcie->pcie_aux))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
-					     "pcie_aux clock source missing or invalid\n");
 		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
 									 "apps");
 		if (IS_ERR(imx6_pcie->apps_reset))
@@ -1372,14 +1317,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	default:
 		break;
 	}
-	/* Don't fetch the pcie_phy clock, if it has abstract PHY driver */
-	if (imx6_pcie->phy == NULL) {
-		imx6_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy");
-		if (IS_ERR(imx6_pcie->pcie_phy))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_phy),
-					     "pcie_phy clock source missing or invalid\n");
-	}
-
 
 	/* Grab turnoff reset */
 	imx6_pcie->turnoff_reset = devm_reset_control_get_optional_exclusive(dev, "turnoff");
@@ -1470,6 +1407,11 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
 	imx6_pcie_assert_core_reset(imx6_pcie);
 }
 
+static const char * const imx6q_clks[] = {"pcie_bus", "pcie", "pcie_phy"};
+static const char * const imx8mm_clks[] = {"pcie_bus", "pcie", "pcie_aux"};
+static const char * const imx8mq_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_aux"};
+static const char * const imx6sx_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_inbound_axi"};
+
 static const struct imx6_pcie_drvdata drvdata[] = {
 	[IMX6Q] = {
 		.variant = IMX6Q,
@@ -1477,6 +1419,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
 		.dbi_length = 0x200,
 		.gpr = "fsl,imx6q-iomuxc-gpr",
+		.clk_names = imx6q_clks,
+		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 	},
 	[IMX6SX] = {
 		.variant = IMX6SX,
@@ -1484,6 +1428,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE |
 			 IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
 		.gpr = "fsl,imx6q-iomuxc-gpr",
+		.clk_names = imx6sx_clks,
+		.clks_cnt = ARRAY_SIZE(imx6sx_clks),
 	},
 	[IMX6QP] = {
 		.variant = IMX6QP,
@@ -1492,40 +1438,56 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 			 IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
 		.dbi_length = 0x200,
 		.gpr = "fsl,imx6q-iomuxc-gpr",
+		.clk_names = imx6q_clks,
+		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 	},
 	[IMX7D] = {
 		.variant = IMX7D,
 		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
 		.gpr = "fsl,imx7d-iomuxc-gpr",
+		.clk_names = imx6q_clks,
+		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 	},
 	[IMX8MQ] = {
 		.variant = IMX8MQ,
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
+		.clk_names = imx8mq_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
 	},
 	[IMX8MM] = {
 		.variant = IMX8MM,
 		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
+		.clk_names = imx8mm_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 	[IMX8MP] = {
 		.variant = IMX8MP,
 		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
+		.clk_names = imx8mm_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 	[IMX8MQ_EP] = {
 		.variant = IMX8MQ_EP,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
+		.clk_names = imx8mq_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
 	},
 	[IMX8MM_EP] = {
 		.variant = IMX8MM_EP,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
+		.clk_names = imx8mm_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 	[IMX8MP_EP] = {
 		.variant = IMX8MP_EP,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
+		.clk_names = imx8mm_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 };
 
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:23 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:23 -0500
Subject: [PATCH v10 02/14] PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-3-Frank.Li@nxp.com>

Since some i.MX platforms make use of the separate PHY driver, use
IMX6_PCIE_FLAG_HAS_PHYDRV flag to identify them and get the reference to
PHY from DT. This simplifies the code.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v8 to v9:
    - change commit message according Manivannan's suggestion
    - Add Manivannan's review tag
    Change from v7 to v8:
    - renmae IMX6_PCIE_FLAG_HAS_PHY to IMX6_PCIE_FLAG_HAS_PHYDRV
    Change from v6 to v7:
    - none
    Change from v4 to v5:
    - none, Keep IMX6_PCIE_FLAG_HAS_PHY to indicate dts mismatch when platform
    require phy suppport.
    
    Change from v1 to v3:
    - none

 drivers/pci/controller/dwc/pci-imx6.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 82854e94c5621..59f117f855c26 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -60,6 +60,9 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_FLAG_IMX6_PHY			BIT(0)
 #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
 #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
+#define IMX6_PCIE_FLAG_HAS_PHYDRV			BIT(3)
+
+#define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
 
 #define IMX6_PCIE_MAX_CLKS       6
 
@@ -1277,6 +1280,13 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_PHYDRV)) {
+		imx6_pcie->phy = devm_phy_get(dev, "pcie-phy");
+		if (IS_ERR(imx6_pcie->phy))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->phy),
+					     "failed to get pcie phy\n");
+	}
+
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX8MQ:
 	case IMX8MQ_EP:
@@ -1308,11 +1318,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 			return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
 					     "failed to get pcie apps reset control\n");
 
-		imx6_pcie->phy = devm_phy_get(dev, "pcie-phy");
-		if (IS_ERR(imx6_pcie->phy))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->phy),
-					     "failed to get pcie phy\n");
-
 		break;
 	default:
 		break;
@@ -1456,14 +1461,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	},
 	[IMX8MM] = {
 		.variant = IMX8MM,
-		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
+		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
+			 IMX6_PCIE_FLAG_HAS_PHYDRV |
+			 IMX6_PCIE_FLAG_HAS_APP_RESET,
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 	[IMX8MP] = {
 		.variant = IMX8MP,
-		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
+		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
+			 IMX6_PCIE_FLAG_HAS_PHYDRV,
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
@@ -1477,6 +1485,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	},
 	[IMX8MM_EP] = {
 		.variant = IMX8MM_EP,
+		.flags = IMX6_PCIE_FLAG_HAS_PHYDRV,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
@@ -1484,6 +1493,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	},
 	[IMX8MP_EP] = {
 		.variant = IMX8MP_EP,
+		.flags = IMX6_PCIE_FLAG_HAS_PHYDRV,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
-- 
2.34.1



From afd at ti.com  Mon Feb  5 09:34:01 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 11:34:01 -0600
Subject: [PATCH v4 3/3] arm64: dts: ti: k3-am62p: add the USB sub-system
In-Reply-To: <20240205135908.54656-4-rogerq@kernel.org>
References: <20240205135908.54656-1-rogerq@kernel.org>
 <20240205135908.54656-4-rogerq@kernel.org>
Message-ID: <45a0ed98-8dd2-4c5b-8e89-40c70e3fe831@ti.com>

On 2/5/24 7:59 AM, Roger Quadros wrote:
> There are two USB instances available on the am62p5 starter kit. Include
> and enable them for use on the board.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
> 
> Notes:
>      Changelog:
>      
>      v4 - no change
>      
>      v3 - no change
>      https://lore.kernel.org/all/20240201120332.4811-4-rogerq at kernel.org/
>      
>      v2:
>      - added USB PHY CTRL node changes here
>      - changed USB wrapper node names to usb@
>      - changed Type-C chip node name to usb-power-control@
> 
>   arch/arm64/boot/dts/ti/k3-am62p-main.dtsi   | 46 ++++++++++++++
>   arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi | 10 +++
>   arch/arm64/boot/dts/ti/k3-am62p5-sk.dts     | 67 +++++++++++++++++++++
>   3 files changed, 123 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> index 4c51bae06b57..17d28390d587 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> @@ -560,6 +560,52 @@ sdhci2: mmc at fa20000 {
>   		status = "disabled";
>   	};
>   
> +	usbss0: usb at f900000 {
> +		compatible = "ti,am62-usb";
> +		reg = <0x00 0x0f900000 0x00 0x800>;
> +		clocks = <&k3_clks 161 3>;
> +		clock-names = "ref";
> +		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
> +		ranges;
> +		status = "disabled";
> +
> +		usb0: usb at 31000000 {
> +			compatible = "snps,dwc3";
> +			reg = <0x00 0x31000000 0x00 0x50000>;
> +			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
> +			<GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
> +			interrupt-names = "host", "peripheral";
> +			maximum-speed = "high-speed";
> +			dr_mode = "otg";
> +		};
> +	};
> +
> +	usbss1: usb at f910000 {
> +		compatible = "ti,am62-usb";
> +		reg = <0x00 0x0f910000 0x00 0x800>;
> +		clocks = <&k3_clks 162 3>;
> +		clock-names = "ref";
> +		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
> +		ranges;
> +		status = "disabled";
> +
> +		usb1: usb at 31100000 {
> +			compatible = "snps,dwc3";
> +			reg = <0x00 0x31100000 0x00 0x50000>;
> +			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
> +			<GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
> +			interrupt-names = "host", "peripheral";
> +			maximum-speed = "high-speed";
> +			dr_mode = "otg";
> +		};
> +	};
> +
>   	fss: bus at fc00000 {
>   		compatible = "simple-bus";
>   		reg = <0x00 0x0fc00000 0x00 0x70000>;
> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
> index 19f42b39394e..00dd38b02a52 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
> @@ -18,6 +18,16 @@ chipid: chipid at 14 {
>   			reg = <0x14 0x4>;
>   			bootph-all;
>   		};
> +
> +		usb0_phy_ctrl: syscon at 4008 {
> +			compatible = "ti,am62-usb-phy-ctrl", "syscon";
> +			reg = <0x4008 0x4>;
> +		};
> +
> +		usb1_phy_ctrl: syscon at 4018 {
> +			compatible = "ti,am62-usb-phy-ctrl", "syscon";
> +			reg = <0x4018 0x4>;
> +		};
>   	};
>   
>   	wkup_uart0: serial at 2b300000 {
> diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
> index 1773c05f752c..80be56c0a4e0 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
> @@ -27,6 +27,8 @@ aliases {
>   		spi0 = &ospi0;
>   		ethernet0 = &cpsw_port1;
>   		ethernet1 = &cpsw_port2;
> +		usb0 = &usb0;
> +		usb1 = &usb1;
>   	};
>   
>   	chosen {
> @@ -297,6 +299,12 @@ AM62PX_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (G20) MCASP0_ACLKR.UART1_TXD */
>   		bootph-all;
>   	};
>   
> +	main_usb1_pins_default: main-usb1-default-pins {
> +		pinctrl-single,pins = <
> +			AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
> +		>;
> +	};
> +
>   	main_wlirq_pins_default: main-wlirq-default-pins {
>   		pinctrl-single,pins = <
>   			AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
> @@ -340,6 +348,36 @@ AM62PX_IOPAD(0x0124, PIN_INPUT, 7) /* (J25) MMC2_SDCD.GPIO0_71 */
>   	};
>   };
>   
> +&main_i2c0 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&main_i2c0_pins_default>;
> +	clock-frequency = <400000>;
> +
> +	typec_pd0: usb-power-controller at 3f {
> +		compatible = "ti,tps6598x";
> +		reg = <0x3f>;
> +
> +		connector {
> +			compatible = "usb-c-connector";
> +			label = "USB-C";
> +			self-powered;
> +			data-role = "dual";
> +			power-role = "sink";
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +				port at 0 {
> +					reg = <0>;
> +					usb_con_hs: endpoint {
> +						remote-endpoint = <&usb0_hs_ep>;
> +					};
> +				};
> +			};
> +		};
> +	};
> +};
> +
>   &main_i2c1 {
>   	status = "okay";
>   	pinctrl-names = "default";
> @@ -460,6 +498,35 @@ cpsw3g_phy1: ethernet-phy at 1 {
>   	};
>   };
>   
> +&usbss0 {
> +	status = "okay";
> +	ti,vbus-divider;
> +};
> +
> +&usbss1 {
> +	status = "okay";
> +	ti,vbus-divider;
> +};
> +
> +&usb0 {
> +	usb-role-switch;
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	port at 0 {
> +		reg = <0>;
> +		usb0_hs_ep: endpoint {
> +			remote-endpoint = <&usb_con_hs>;
> +		};
> +	};
> +};
> +
> +&usb1 {
> +	dr_mode = "host";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&main_usb1_pins_default>;

I'm not super familiar with USB, but I see this pinmux for the
"DRVVBUS" pin is usually added the the parent USB subsystem node (usbss).
Does this pin belong to the subsystem or the specific USB instance?

Andrew

> +};
> +
>   &mcasp1 {
>   	status = "okay";
>   	#sound-dai-cells = <0>;


From Frank.Li at nxp.com  Mon Feb  5 09:33:24 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:24 -0500
Subject: [PATCH v10 03/14] PCI: imx6: Simplify reset handling by using by using *_FLAG_HAS_*_RESET
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-4-Frank.Li@nxp.com>

Refactors the reset handling logic in the imx6 PCI driver by adding
IMX6_PCIE_FLAG_HAS_*_RESET bitmask define for drvdata::flags.

The drvdata::flags and a bitmask ensures a cleaner and more scalable
switch-case structure for handling reset.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v4 to v5:
    - Add Mani's Reviewed-by tag
    - Fixed MQ_EP's flags
    
    Chagne from v3 to v4:
    - none
    Change from v2 to v3:
    - add Philipp's Reviewed-by tag
    Change from v1 to v2:
    - remove condition check before reset_control_(de)assert() because it is
      none ops if a NULL pointer pass down.
    - still keep condition check at probe to help identify dts file mismatch
      problem.
    
    Change from v1 to v2:
    - remove condition check before reset_control_(de)assert() because it is
      none ops if a NULL pointer pass down.
    - still keep condition check at probe to help identify dts file mismatch
      problem.

 drivers/pci/controller/dwc/pci-imx6.c | 105 ++++++++++----------------
 1 file changed, 39 insertions(+), 66 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 59f117f855c26..a1653b58051b7 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -61,6 +61,8 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
 #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
 #define IMX6_PCIE_FLAG_HAS_PHYDRV			BIT(3)
+#define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
+#define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
 
 #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
 
@@ -661,18 +663,10 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
 
 static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
 {
+	reset_control_assert(imx6_pcie->pciephy_reset);
+	reset_control_assert(imx6_pcie->apps_reset);
+
 	switch (imx6_pcie->drvdata->variant) {
-	case IMX7D:
-	case IMX8MQ:
-	case IMX8MQ_EP:
-		reset_control_assert(imx6_pcie->pciephy_reset);
-		fallthrough;
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		reset_control_assert(imx6_pcie->apps_reset);
-		break;
 	case IMX6SX:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
@@ -693,6 +687,8 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
 				   IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
 		break;
+	default:
+		break;
 	}
 
 	/* Some boards don't have PCIe reset GPIO. */
@@ -706,14 +702,10 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 	struct dw_pcie *pci = imx6_pcie->pci;
 	struct device *dev = pci->dev;
 
+	reset_control_deassert(imx6_pcie->pciephy_reset);
+
 	switch (imx6_pcie->drvdata->variant) {
-	case IMX8MQ:
-	case IMX8MQ_EP:
-		reset_control_deassert(imx6_pcie->pciephy_reset);
-		break;
 	case IMX7D:
-		reset_control_deassert(imx6_pcie->pciephy_reset);
-
 		/* Workaround for ERR010728, failure of PCI-e PLL VCO to
 		 * oscillate, especially when cold.  This turns off "Duty-cycle
 		 * Corrector" and other mysterious undocumented things.
@@ -745,11 +737,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 
 		usleep_range(200, 500);
 		break;
-	case IMX6Q:		/* Nothing to do */
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
+	default:
 		break;
 	}
 
@@ -796,16 +784,11 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
 				   IMX6Q_GPR12_PCIE_CTL_2,
 				   IMX6Q_GPR12_PCIE_CTL_2);
 		break;
-	case IMX7D:
-	case IMX8MQ:
-	case IMX8MQ_EP:
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		reset_control_deassert(imx6_pcie->apps_reset);
+	default:
 		break;
 	}
+
+	reset_control_deassert(imx6_pcie->apps_reset);
 }
 
 static void imx6_pcie_ltssm_disable(struct device *dev)
@@ -819,16 +802,11 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				   IMX6Q_GPR12_PCIE_CTL_2, 0);
 		break;
-	case IMX7D:
-	case IMX8MQ:
-	case IMX8MQ_EP:
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		reset_control_assert(imx6_pcie->apps_reset);
+	default:
 		break;
 	}
+
+	reset_control_assert(imx6_pcie->apps_reset);
 }
 
 static int imx6_pcie_start_link(struct dw_pcie *pci)
@@ -1287,38 +1265,26 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 					     "failed to get pcie phy\n");
 	}
 
+	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_APP_RESET)) {
+		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev, "apps");
+		if (IS_ERR(imx6_pcie->apps_reset))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
+					     "failed to get pcie apps reset control\n");
+	}
+
+	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_PHY_RESET)) {
+		imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, "pciephy");
+		if (IS_ERR(imx6_pcie->pciephy_reset))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pciephy_reset),
+					     "Failed to get PCIEPHY reset control\n");
+	}
+
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX8MQ:
 	case IMX8MQ_EP:
 	case IMX7D:
 		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
 			imx6_pcie->controller_id = 1;
-
-		imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev,
-									    "pciephy");
-		if (IS_ERR(imx6_pcie->pciephy_reset)) {
-			dev_err(dev, "Failed to get PCIEPHY reset control\n");
-			return PTR_ERR(imx6_pcie->pciephy_reset);
-		}
-
-		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
-									 "apps");
-		if (IS_ERR(imx6_pcie->apps_reset)) {
-			dev_err(dev, "Failed to get PCIE APPS reset control\n");
-			return PTR_ERR(imx6_pcie->apps_reset);
-		}
-		break;
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
-									 "apps");
-		if (IS_ERR(imx6_pcie->apps_reset))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
-					     "failed to get pcie apps reset control\n");
-
-		break;
 	default:
 		break;
 	}
@@ -1448,13 +1414,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	},
 	[IMX7D] = {
 		.variant = IMX7D,
-		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
+		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
+			 IMX6_PCIE_FLAG_HAS_APP_RESET |
+			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
 		.gpr = "fsl,imx7d-iomuxc-gpr",
 		.clk_names = imx6q_clks,
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 	},
 	[IMX8MQ] = {
 		.variant = IMX8MQ,
+		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
+			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
 		.clk_names = imx8mq_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
@@ -1471,13 +1441,16 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	[IMX8MP] = {
 		.variant = IMX8MP,
 		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
-			 IMX6_PCIE_FLAG_HAS_PHYDRV,
+			 IMX6_PCIE_FLAG_HAS_PHYDRV |
+			 IMX6_PCIE_FLAG_HAS_APP_RESET,
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 	[IMX8MQ_EP] = {
 		.variant = IMX8MQ_EP,
+		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
+			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
 		.clk_names = imx8mq_clks,
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:25 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:25 -0500
Subject: [PATCH v10 04/14] PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-5-Frank.Li@nxp.com>

Add drvdata::ltssm_off and drvdata::ltssm_mask to simple
imx6_pcie_ltssm_enable(disable)() logic.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8
    - Add Manivannan Sadhasivam's review tag
    Change from v1 to v7
    - none

 drivers/pci/controller/dwc/pci-imx6.c | 37 ++++++++++++---------------
 1 file changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index a1653b58051b7..8c816ff159115 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -76,6 +76,8 @@ struct imx6_pcie_drvdata {
 	const char *gpr;
 	const char * const *clk_names;
 	const u32 clks_cnt;
+	const u32 ltssm_off;
+	const u32 ltssm_mask;
 };
 
 struct imx6_pcie {
@@ -775,18 +777,11 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
 static void imx6_pcie_ltssm_enable(struct device *dev)
 {
 	struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
+	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
 
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX6Q:
-	case IMX6SX:
-	case IMX6QP:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX6Q_GPR12_PCIE_CTL_2,
-				   IMX6Q_GPR12_PCIE_CTL_2);
-		break;
-	default:
-		break;
-	}
+	if (drvdata->ltssm_mask)
+		regmap_update_bits(imx6_pcie->iomuxc_gpr, drvdata->ltssm_off, drvdata->ltssm_mask,
+				   drvdata->ltssm_mask);
 
 	reset_control_deassert(imx6_pcie->apps_reset);
 }
@@ -794,17 +789,11 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
 static void imx6_pcie_ltssm_disable(struct device *dev)
 {
 	struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
+	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
 
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX6Q:
-	case IMX6SX:
-	case IMX6QP:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX6Q_GPR12_PCIE_CTL_2, 0);
-		break;
-	default:
-		break;
-	}
+	if (drvdata->ltssm_mask)
+		regmap_update_bits(imx6_pcie->iomuxc_gpr, drvdata->ltssm_off,
+				   drvdata->ltssm_mask, 0);
 
 	reset_control_assert(imx6_pcie->apps_reset);
 }
@@ -1392,6 +1381,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx6q-iomuxc-gpr",
 		.clk_names = imx6q_clks,
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
+		.ltssm_off = IOMUXC_GPR12,
+		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 	},
 	[IMX6SX] = {
 		.variant = IMX6SX,
@@ -1401,6 +1392,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx6q-iomuxc-gpr",
 		.clk_names = imx6sx_clks,
 		.clks_cnt = ARRAY_SIZE(imx6sx_clks),
+		.ltssm_off = IOMUXC_GPR12,
+		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 	},
 	[IMX6QP] = {
 		.variant = IMX6QP,
@@ -1411,6 +1404,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx6q-iomuxc-gpr",
 		.clk_names = imx6q_clks,
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
+		.ltssm_off = IOMUXC_GPR12,
+		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 	},
 	[IMX7D] = {
 		.variant = IMX7D,
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:26 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:26 -0500
Subject: [PATCH v10 05/14] PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-6-Frank.Li@nxp.com>

Add drvdata::mode_off and drvdata::mode_mask to simplify
imx6_pcie_configure_type() logic.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Chagne from v8 to v9
    - add Manivannan's review tag
    Change from v7 to v8
    - replace simple with simplify
    - remove reduntant comments about FILED_PREP
    Change from v3 to v7
    - none
    Change from v2 to v3
    - none
    Change from v1 to v2
    - use ffs() to fixe build error.
    
    Change from v2 to v3
    - none
    Change from v1 to v2
    - use ffs() to fixe build error.

 drivers/pci/controller/dwc/pci-imx6.c | 59 ++++++++++++++++++---------
 1 file changed, 39 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 8c816ff159115..4eeaf54709afd 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -68,6 +68,7 @@ enum imx6_pcie_variants {
 
 #define IMX6_PCIE_MAX_CLKS       6
 
+#define IMX6_PCIE_MAX_INSTANCES			2
 struct imx6_pcie_drvdata {
 	enum imx6_pcie_variants variant;
 	enum dw_pcie_device_mode mode;
@@ -78,6 +79,8 @@ struct imx6_pcie_drvdata {
 	const u32 clks_cnt;
 	const u32 ltssm_off;
 	const u32 ltssm_mask;
+	const u32 mode_off[IMX6_PCIE_MAX_INSTANCES];
+	const u32 mode_mask[IMX6_PCIE_MAX_INSTANCES];
 };
 
 struct imx6_pcie {
@@ -174,32 +177,24 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
 
 static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
 {
-	unsigned int mask, val, mode;
+	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
+	unsigned int mask, val, mode, id;
 
-	if (imx6_pcie->drvdata->mode == DW_PCIE_EP_TYPE)
+	if (drvdata->mode == DW_PCIE_EP_TYPE)
 		mode = PCI_EXP_TYPE_ENDPOINT;
 	else
 		mode = PCI_EXP_TYPE_ROOT_PORT;
 
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX8MQ:
-	case IMX8MQ_EP:
-		if (imx6_pcie->controller_id == 1) {
-			mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE;
-			val  = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
-					  mode);
-		} else {
-			mask = IMX6Q_GPR12_DEVICE_TYPE;
-			val  = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode);
-		}
-		break;
-	default:
-		mask = IMX6Q_GPR12_DEVICE_TYPE;
-		val  = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode);
-		break;
-	}
+	id = imx6_pcie->controller_id;
+
+	/* If mode_mask[id] is zero, means each controller have its individual gpr */
+	if (!drvdata->mode_mask[id])
+		id = 0;
+
+	mask = drvdata->mode_mask[id];
+	val = mode << (ffs(mask) - 1);
 
-	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, mask, val);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, drvdata->mode_off[id], mask, val);
 }
 
 static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, bool exp_val)
@@ -1383,6 +1378,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 		.ltssm_off = IOMUXC_GPR12,
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX6SX] = {
 		.variant = IMX6SX,
@@ -1394,6 +1391,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx6sx_clks),
 		.ltssm_off = IOMUXC_GPR12,
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX6QP] = {
 		.variant = IMX6QP,
@@ -1406,6 +1405,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 		.ltssm_off = IOMUXC_GPR12,
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX7D] = {
 		.variant = IMX7D,
@@ -1415,6 +1416,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx7d-iomuxc-gpr",
 		.clk_names = imx6q_clks,
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX8MQ] = {
 		.variant = IMX8MQ,
@@ -1423,6 +1426,10 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
 		.clk_names = imx8mq_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.mode_off[1] = IOMUXC_GPR12,
+		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
 	},
 	[IMX8MM] = {
 		.variant = IMX8MM,
@@ -1432,6 +1439,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX8MP] = {
 		.variant = IMX8MP,
@@ -1441,6 +1450,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX8MQ_EP] = {
 		.variant = IMX8MQ_EP,
@@ -1450,6 +1461,10 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
 		.clk_names = imx8mq_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.mode_off[1] = IOMUXC_GPR12,
+		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
 	},
 	[IMX8MM_EP] = {
 		.variant = IMX8MM_EP,
@@ -1458,6 +1473,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX8MP_EP] = {
 		.variant = IMX8MP_EP,
@@ -1466,6 +1483,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 };
 
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:27 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:27 -0500
Subject: [PATCH v10 06/14] PCI: imx6: Simplify switch-case logic by involve init_phy callback
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-7-Frank.Li@nxp.com>

Instead of using the switch case statement to initialize the PHY handled by
this driver itself, let's introduce a new callback init_phy() and define it
for platforms that require it. This simplifies the code.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8:
    - rework commit message
    - wrap comments to 100 chars
    - return 0 at imx7d_pcie_init_phy()
    
    change from v1 to v4:
    - none

 drivers/pci/controller/dwc/pci-imx6.c | 134 +++++++++++++-------------
 1 file changed, 69 insertions(+), 65 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 4eeaf54709afd..c266b9f098a5b 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -69,6 +69,9 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_MAX_CLKS       6
 
 #define IMX6_PCIE_MAX_INSTANCES			2
+
+struct imx6_pcie;
+
 struct imx6_pcie_drvdata {
 	enum imx6_pcie_variants variant;
 	enum dw_pcie_device_mode mode;
@@ -81,6 +84,7 @@ struct imx6_pcie_drvdata {
 	const u32 ltssm_mask;
 	const u32 mode_off[IMX6_PCIE_MAX_INSTANCES];
 	const u32 mode_mask[IMX6_PCIE_MAX_INSTANCES];
+	int (*init_phy)(struct imx6_pcie *pcie);
 };
 
 struct imx6_pcie {
@@ -322,76 +326,66 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data)
 	return 0;
 }
 
-static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+static int imx8mq_pcie_init_phy(struct imx6_pcie *imx6_pcie)
 {
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		/*
-		 * The PHY initialization had been done in the PHY
-		 * driver, break here directly.
-		 */
-		break;
-	case IMX8MQ:
-	case IMX8MQ_EP:
-		/*
-		 * TODO: Currently this code assumes external
-		 * oscillator is being used
-		 */
+	/* TODO: Currently this code assumes external oscillator is being used */
+	regmap_update_bits(imx6_pcie->iomuxc_gpr,
+			   imx6_pcie_grp_offset(imx6_pcie),
+			   IMX8MQ_GPR_PCIE_REF_USE_PAD,
+			   IMX8MQ_GPR_PCIE_REF_USE_PAD);
+	/*
+	 * Regarding the datasheet, the PCIE_VPH is suggested to be 1.8V. If the PCIE_VPH is
+	 * supplied by 3.3V, the VREG_BYPASS should be cleared to zero.
+	 */
+	if (imx6_pcie->vph && regulator_get_voltage(imx6_pcie->vph) > 3000000)
 		regmap_update_bits(imx6_pcie->iomuxc_gpr,
 				   imx6_pcie_grp_offset(imx6_pcie),
-				   IMX8MQ_GPR_PCIE_REF_USE_PAD,
-				   IMX8MQ_GPR_PCIE_REF_USE_PAD);
-		/*
-		 * Regarding the datasheet, the PCIE_VPH is suggested
-		 * to be 1.8V. If the PCIE_VPH is supplied by 3.3V, the
-		 * VREG_BYPASS should be cleared to zero.
-		 */
-		if (imx6_pcie->vph &&
-		    regulator_get_voltage(imx6_pcie->vph) > 3000000)
-			regmap_update_bits(imx6_pcie->iomuxc_gpr,
-					   imx6_pcie_grp_offset(imx6_pcie),
-					   IMX8MQ_GPR_PCIE_VREG_BYPASS,
-					   0);
-		break;
-	case IMX7D:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
-		break;
-	case IMX6SX:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX6SX_GPR12_PCIE_RX_EQ_MASK,
-				   IMX6SX_GPR12_PCIE_RX_EQ_2);
-		fallthrough;
-	default:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+				   IMX8MQ_GPR_PCIE_VREG_BYPASS,
+				   0);
+
+	return 0;
+}
+
+static int imx7d_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+{
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
+
+	return 0;
+}
+
+static int imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+{
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				   IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
 
-		/* configure constant input signal to the pcie ctrl and phy */
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
-
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
-				   IMX6Q_GPR8_TX_DEEMPH_GEN1,
-				   imx6_pcie->tx_deemph_gen1 << 0);
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
-				   IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB,
-				   imx6_pcie->tx_deemph_gen2_3p5db << 6);
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
-				   IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB,
-				   imx6_pcie->tx_deemph_gen2_6db << 12);
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
-				   IMX6Q_GPR8_TX_SWING_FULL,
-				   imx6_pcie->tx_swing_full << 18);
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
-				   IMX6Q_GPR8_TX_SWING_LOW,
-				   imx6_pcie->tx_swing_low << 25);
-		break;
-	}
+	/* configure constant input signal to the pcie ctrl and phy */
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+			   IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
+
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+			   IMX6Q_GPR8_TX_DEEMPH_GEN1,
+			   imx6_pcie->tx_deemph_gen1 << 0);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+			   IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB,
+			   imx6_pcie->tx_deemph_gen2_3p5db << 6);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+			   IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB,
+			   imx6_pcie->tx_deemph_gen2_6db << 12);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+			   IMX6Q_GPR8_TX_SWING_FULL,
+			   imx6_pcie->tx_swing_full << 18);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+			   IMX6Q_GPR8_TX_SWING_LOW,
+			   imx6_pcie->tx_swing_low << 25);
+	return 0;
+}
 
-	imx6_pcie_configure_type(imx6_pcie);
+static int imx6sx_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+{
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+			   IMX6SX_GPR12_PCIE_RX_EQ_MASK, IMX6SX_GPR12_PCIE_RX_EQ_2);
+
+	return imx6_pcie_init_phy(imx6_pcie);
 }
 
 static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
@@ -902,7 +896,11 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
 	}
 
 	imx6_pcie_assert_core_reset(imx6_pcie);
-	imx6_pcie_init_phy(imx6_pcie);
+
+	if (imx6_pcie->drvdata->init_phy)
+		imx6_pcie->drvdata->init_phy(imx6_pcie);
+
+	imx6_pcie_configure_type(imx6_pcie);
 
 	ret = imx6_pcie_clk_enable(imx6_pcie);
 	if (ret) {
@@ -1380,6 +1378,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.init_phy = imx6_pcie_init_phy,
 	},
 	[IMX6SX] = {
 		.variant = IMX6SX,
@@ -1393,6 +1392,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.init_phy = imx6sx_pcie_init_phy,
 	},
 	[IMX6QP] = {
 		.variant = IMX6QP,
@@ -1407,6 +1407,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.init_phy = imx6_pcie_init_phy,
 	},
 	[IMX7D] = {
 		.variant = IMX7D,
@@ -1418,6 +1419,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.init_phy = imx7d_pcie_init_phy,
 	},
 	[IMX8MQ] = {
 		.variant = IMX8MQ,
@@ -1430,6 +1432,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 		.mode_off[1] = IOMUXC_GPR12,
 		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
+		.init_phy = imx8mq_pcie_init_phy,
 	},
 	[IMX8MM] = {
 		.variant = IMX8MM,
@@ -1465,6 +1468,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 		.mode_off[1] = IOMUXC_GPR12,
 		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
+		.init_phy = imx8mq_pcie_init_phy,
 	},
 	[IMX8MM_EP] = {
 		.variant = IMX8MM_EP,
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:28 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:28 -0500
Subject: [PATCH v10 07/14] dt-bindings: imx6q-pcie: Clean up irrationality clocks check
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-8-Frank.Li@nxp.com>

The bindings referencing this file already define these constraints for
each of the variants, so the if not: then: is redundant.

Acked-by: Rob Herring <robh at kernel.org>
Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8
    - add Manivannan Sadhasiva's Ack tag
    Change from v6 to v7
    - rewrite git commit message by using simple words
    Change from v5 to v6
    - rewrite git commit message and explain why remove it safely.
    - Add Rob's Ack
    Change from v1 to v4
    - new patch at v4

 .../bindings/pci/fsl,imx6q-pcie-common.yaml      | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
index d91b639ae7ae7..0c50487a3866d 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
@@ -150,22 +150,6 @@ allOf:
             - {}
             - const: pcie_phy
             - const: pcie_aux
-  - if:
-      properties:
-        compatible:
-          not:
-            contains:
-              enum:
-                - fsl,imx6sx-pcie
-                - fsl,imx8mq-pcie
-                - fsl,imx6sx-pcie-ep
-                - fsl,imx8mq-pcie-ep
-    then:
-      properties:
-        clocks:
-          maxItems: 3
-        clock-names:
-          maxItems: 3
 
   - if:
       properties:
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:31 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:31 -0500
Subject: [PATCH v10 10/14] PCI: imx6: Add iMX95 PCIe Root Complex support
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-11-Frank.Li@nxp.com>

Add iMX95 PCIe Root Complex support.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v8 to v9
    - Add mani's review tag
    
    Change from v7 to v8
    - Update commit subject
    - add const from regmap
    - remove unnessary logic in imx6_pcie_deassert_core_reset()
    
    Change from v4 to v7
    - none
    Change from v1 to v3
    - none

 drivers/pci/controller/dwc/pci-imx6.c | 82 +++++++++++++++++++++++++--
 1 file changed, 77 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index c266b9f098a5b..183bb3b31cf16 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -42,6 +42,25 @@
 #define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE	GENMASK(11, 8)
 #define IMX8MQ_PCIE2_BASE_ADDR			0x33c00000
 
+#define IMX95_PCIE_PHY_GEN_CTRL			0x0
+#define IMX95_PCIE_REF_USE_PAD			BIT(17)
+
+#define IMX95_PCIE_PHY_MPLLA_CTRL		0x10
+#define IMX95_PCIE_PHY_MPLL_STATE		BIT(30)
+
+#define IMX95_PCIE_SS_RW_REG_0			0xf0
+#define IMX95_PCIE_REF_CLKEN			BIT(23)
+#define IMX95_PCIE_PHY_CR_PARA_SEL		BIT(9)
+
+#define IMX95_PE0_GEN_CTRL_1			0x1050
+#define IMX95_PCIE_DEVICE_TYPE			GENMASK(3, 0)
+
+#define IMX95_PE0_GEN_CTRL_3			0x1058
+#define IMX95_PCIE_LTSSM_EN			BIT(0)
+
+#define IMX95_PE0_PM_STS			0x1064
+#define IMX95_PCIE_PM_LINKST_IN_L2		BIT(14)
+
 #define to_imx6_pcie(x)	dev_get_drvdata((x)->dev)
 
 enum imx6_pcie_variants {
@@ -52,6 +71,7 @@ enum imx6_pcie_variants {
 	IMX8MQ,
 	IMX8MM,
 	IMX8MP,
+	IMX95,
 	IMX8MQ_EP,
 	IMX8MM_EP,
 	IMX8MP_EP,
@@ -63,6 +83,7 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_FLAG_HAS_PHYDRV			BIT(3)
 #define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
 #define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
+#define IMX6_PCIE_FLAG_HAS_SERDES		BIT(6)
 
 #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
 
@@ -179,6 +200,24 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
 	return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
 }
 
+static int imx95_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+{
+	regmap_update_bits(imx6_pcie->iomuxc_gpr,
+			IMX95_PCIE_SS_RW_REG_0,
+			IMX95_PCIE_PHY_CR_PARA_SEL,
+			IMX95_PCIE_PHY_CR_PARA_SEL);
+
+	regmap_update_bits(imx6_pcie->iomuxc_gpr,
+			   IMX95_PCIE_PHY_GEN_CTRL,
+			   IMX95_PCIE_REF_USE_PAD, 0);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr,
+			   IMX95_PCIE_SS_RW_REG_0,
+			   IMX95_PCIE_REF_CLKEN,
+			   IMX95_PCIE_REF_CLKEN);
+
+	return 0;
+}
+
 static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
 {
 	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
@@ -575,6 +614,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 				   IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
 		break;
 	case IMX7D:
+	case IMX95:
 		break;
 	case IMX8MM:
 	case IMX8MM_EP:
@@ -1278,12 +1318,32 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 		return PTR_ERR(imx6_pcie->turnoff_reset);
 	}
 
+	if (imx6_pcie->drvdata->gpr) {
 	/* Grab GPR config register range */
-	imx6_pcie->iomuxc_gpr =
-		 syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
-	if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
-		dev_err(dev, "unable to find iomuxc registers\n");
-		return PTR_ERR(imx6_pcie->iomuxc_gpr);
+		imx6_pcie->iomuxc_gpr =
+			 syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
+		if (IS_ERR(imx6_pcie->iomuxc_gpr))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
+					     "unable to find iomuxc registers\n");
+	}
+
+	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_SERDES)) {
+		void __iomem *off = devm_platform_ioremap_resource_byname(pdev, "app");
+
+		if (IS_ERR(off))
+			return dev_err_probe(dev, PTR_ERR(off),
+					     "unable to find serdes registers\n");
+
+		static const struct regmap_config regmap_config = {
+			.reg_bits = 32,
+			.val_bits = 32,
+			.reg_stride = 4,
+		};
+
+		imx6_pcie->iomuxc_gpr = devm_regmap_init_mmio(dev, off, &regmap_config);
+		if (IS_ERR(imx6_pcie->iomuxc_gpr))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
+					     "unable to find iomuxc registers\n");
 	}
 
 	/* Grab PCIe PHY Tx Settings */
@@ -1456,6 +1516,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
+	[IMX95] = {
+		.variant = IMX95,
+		.flags = IMX6_PCIE_FLAG_HAS_SERDES,
+		.clk_names = imx8mq_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
+		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
+		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
+		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
+		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
+		.init_phy = imx95_pcie_init_phy,
+	},
 	[IMX8MQ_EP] = {
 		.variant = IMX8MQ_EP,
 		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
@@ -1500,6 +1571,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
 	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
 	{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
 	{ .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], },
+	{ .compatible = "fsl,imx95-pcie", .data = &drvdata[IMX95], },
 	{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
 	{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
 	{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:30 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:30 -0500
Subject: [PATCH v10 09/14] dt-bindings: imx6q-pcie: Add imx95 pcie compatible string
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-10-Frank.Li@nxp.com>

From: Richard Zhu <hongxing.zhu at nxp.com>

Add i.MX95 PCIe "fsl,imx95-pcie" compatible string.
Add "atu" and "app" to reg-names.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v8 to v9
    - Added rob's review tag
    Change from v7 to v8
    -none
    Change from v6 to v7
    - Added my sign off
    
    Change from v5 to v6
    - move atu and app after config
    
    Change from v2 to v3
    - Remove krzy's ACK tag
    - Add condition check for imx95, which required more reg-names then old
    platform, so need Krzy review again,
    
    Change from v1 to v2
    - add Krzy's ACK tag

 .../bindings/pci/fsl,imx6q-pcie-common.yaml   |  1 +
 .../bindings/pci/fsl,imx6q-pcie.yaml          | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
index 0c50487a3866d..a8b34f58f8f49 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
@@ -207,6 +207,7 @@ allOf:
                 - fsl,imx6sx-pcie
                 - fsl,imx6q-pcie
                 - fsl,imx6qp-pcie
+                - fsl,imx95-pcie
                 - fsl,imx6sx-pcie-ep
                 - fsl,imx6q-pcie-ep
                 - fsl,imx6qp-pcie-ep
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
index eeca6b7b540f9..8b8d77b1154b5 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -29,6 +29,7 @@ properties:
       - fsl,imx8mq-pcie
       - fsl,imx8mm-pcie
       - fsl,imx8mp-pcie
+      - fsl,imx95-pcie
 
   clocks:
     minItems: 3
@@ -100,6 +101,23 @@ allOf:
             - const: dbi
             - const: config
 
+  - if:
+      properties:
+        compatible:
+          enum:
+            - fsl,imx95-pcie
+    then:
+      properties:
+        reg:
+          minItems: 4
+          maxItems: 4
+        reg-names:
+          items:
+            - const: dbi
+            - const: config
+            - const: atu
+            - const: app
+
   - if:
       properties:
         compatible:
@@ -121,6 +139,7 @@ allOf:
         compatible:
           enum:
             - fsl,imx8mq-pcie
+            - fsl,imx95-pcie
     then:
       properties:
         clocks:
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:32 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:32 -0500
Subject: [PATCH v10 11/14] PCI: imx6: Clean up get addr_space code
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-12-Frank.Li@nxp.com>

Since the dw_pcie_ep_init() function is already fetching the 'addr_space'
region, no need to do the same in this driver.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8
    - update commit message
    - Add Manivannan Sadhasivam's review tag
    Change from v4 to v7
    - none
    Change from v1 to v3
    - new patches

 drivers/pci/controller/dwc/pci-imx6.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 183bb3b31cf16..9cc6802e93641 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1067,7 +1067,6 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
 	int ret;
 	unsigned int pcie_dbi2_offset;
 	struct dw_pcie_ep *ep;
-	struct resource *res;
 	struct dw_pcie *pci = imx6_pcie->pci;
 	struct dw_pcie_rp *pp = &pci->pp;
 	struct device *dev = pci->dev;
@@ -1086,14 +1085,8 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
 		pcie_dbi2_offset = SZ_4K;
 		break;
 	}
-	pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset;
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
-	if (!res)
-		return -EINVAL;
 
-	ep->phys_base = res->start;
-	ep->addr_size = resource_size(res);
-	ep->page_size = SZ_64K;
+	pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset;
 
 	ret = dw_pcie_ep_init(ep);
 	if (ret) {
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:29 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:29 -0500
Subject: [PATCH v10 08/14] dt-bindings: imx6q-pcie: Restruct reg and reg-name
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-9-Frank.Li@nxp.com>

snps,dw-pcie.yaml already have reg and reg-name information. Needn't
duplciate here.

Add 'if' check for existed compatible string to restrict reg and reg-names.
This prepare to add new compatible string with difference reg-names sets.

Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8
    - Add Manivannan Sadhasivam's ACK tag
    Change from v6 to v7
    - add Krzysztof's review tag
    Change from v5 to v6
    - Add if check for existed compatible string
    Change from v4 to v5
    - add Rob's Acked
    Change from v1 to v4:
    - new patch at v4

 .../bindings/pci/fsl,imx6q-pcie.yaml          | 30 ++++++++++++-------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
index 81bbb8728f0f9..eeca6b7b540f9 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -30,16 +30,6 @@ properties:
       - fsl,imx8mm-pcie
       - fsl,imx8mp-pcie
 
-  reg:
-    items:
-      - description: Data Bus Interface (DBI) registers.
-      - description: PCIe configuration space region.
-
-  reg-names:
-    items:
-      - const: dbi
-      - const: config
-
   clocks:
     minItems: 3
     items:
@@ -90,6 +80,26 @@ required:
 allOf:
   - $ref: /schemas/pci/snps,dw-pcie.yaml#
   - $ref: /schemas/pci/fsl,imx6q-pcie-common.yaml#
+  - if:
+      properties:
+        compatible:
+          enum:
+            - fsl,imx6q-pcie
+            - fsl,imx6sx-pcie
+            - fsl,imx6qp-pcie
+            - fsl,imx7d-pcie
+            - fsl,imx8mq-pcie
+            - fsl,imx8mm-pcie
+            - fsl,imx8mp-pcie
+    then:
+      properties:
+        reg:
+          maxItems: 2
+        reg-names:
+          items:
+            - const: dbi
+            - const: config
+
   - if:
       properties:
         compatible:
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:33 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:33 -0500
Subject: [PATCH v10 12/14] PCI: imx6: Add epc_features in imx6_pcie_drvdata
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-13-Frank.Li@nxp.com>

The i.MX EP exhibits variations in epc_features among different EP
configurations. This introduces the addition of epc_features in
imx6_pcie_drvdata to accommodate these differences. It's important to note
that there are no functional changes in this commit; instead, it lays the
groundwork for supporting i.MX95 EP functions.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8
    - Added  Manivannan Sadhasivam's review tag
    Change from v6 to v7
    - none
    Change from v5 to v6
    - add missed maxitems.
    - add comments about reuse linux,pci-domain as controller id.
    linux,pci-domain have not defined at PCI endpoint side.
    
    Change from v1 to v3
    - new patch at v3

 drivers/pci/controller/dwc/pci-imx6.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 9cc6802e93641..c2098e59fde1e 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -105,6 +105,7 @@ struct imx6_pcie_drvdata {
 	const u32 ltssm_mask;
 	const u32 mode_off[IMX6_PCIE_MAX_INSTANCES];
 	const u32 mode_mask[IMX6_PCIE_MAX_INSTANCES];
+	const struct pci_epc_features *epc_features;
 	int (*init_phy)(struct imx6_pcie *pcie);
 };
 
@@ -1052,7 +1053,10 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
 static const struct pci_epc_features*
 imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
 {
-	return &imx8m_pcie_epc_features;
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+
+	return imx6_pcie->drvdata->epc_features;
 }
 
 static const struct dw_pcie_ep_ops pcie_ep_ops = {
@@ -1532,6 +1536,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 		.mode_off[1] = IOMUXC_GPR12,
 		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
+		.epc_features = &imx8m_pcie_epc_features,
 		.init_phy = imx8mq_pcie_init_phy,
 	},
 	[IMX8MM_EP] = {
@@ -1543,6 +1548,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.epc_features = &imx8m_pcie_epc_features,
 	},
 	[IMX8MP_EP] = {
 		.variant = IMX8MP_EP,
@@ -1553,6 +1559,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.epc_features = &imx8m_pcie_epc_features,
 	},
 };
 
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:34 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:34 -0500
Subject: [PATCH v10 13/14] dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-14-Frank.Li@nxp.com>

Add i.MX95 PCIe "fsl,imx95-pcie-ep" compatible string.
Add reg-name: "atu", "dbi2", "dma" and "app".

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v9 to v10
    - remove "pci-domain" part
    Change from v8 to v9
    - add rob's review tag
    Change from v3 to v8
    - none
    Change from v1 to v3
    - new patches at v3

 .../bindings/pci/fsl,imx6q-pcie-ep.yaml       | 46 +++++++++++++++----
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
index ee155ed5f1811..a06f75df8458a 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
@@ -22,14 +22,7 @@ properties:
       - fsl,imx8mm-pcie-ep
       - fsl,imx8mq-pcie-ep
       - fsl,imx8mp-pcie-ep
-
-  reg:
-    minItems: 2
-
-  reg-names:
-    items:
-      - const: dbi
-      - const: addr_space
+      - fsl,imx95-pcie-ep
 
   clocks:
     minItems: 3
@@ -62,11 +55,48 @@ required:
 allOf:
   - $ref: /schemas/pci/snps,dw-pcie-ep.yaml#
   - $ref: /schemas/pci/fsl,imx6q-pcie-common.yaml#
+  - if:
+      properties:
+        compatible:
+          enum:
+            - fsl,imx8mm-pcie-ep
+            - fsl,imx8mq-pcie-ep
+            - fsl,imx8mp-pcie-ep
+    then:
+      properties:
+        reg:
+          minItems: 2
+          maxItems: 2
+        reg-names:
+          items:
+            - const: dbi
+            - const: addr_space
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - fsl,imx95-pcie-ep
+    then:
+      properties:
+        reg:
+          minItems: 6
+          maxItems: 6
+        reg-names:
+          items:
+            - const: dbi
+            - const: atu
+            - const: dbi2
+            - const: app
+            - const: dma
+            - const: addr_space
+
   - if:
       properties:
         compatible:
           enum:
             - fsl,imx8mq-pcie-ep
+            - fsl,imx95-pcie-ep
     then:
       properties:
         clocks:
-- 
2.34.1



From Frank.Li at nxp.com  Mon Feb  5 09:33:35 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon,  5 Feb 2024 12:33:35 -0500
Subject: [PATCH v10 14/14] PCI: imx6: Add iMX95 Endpoint (EP) support
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <20240205173335.1120469-15-Frank.Li@nxp.com>

Add iMX95 EP support and add 64bit address support. Internal bus bridge for
PCI support 64bit dma address in iMX95. Hence, call
dma_set_mask_and_coherent() to set 64 bit DMA mask.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v9 to v10
    - using if (device_property_match_string(dev, "reg-names", "dbi2")) instead of
    	if (imx6_pcie->drvdata->variant == IMX95_EP)
    - so other platform can stat use "dbi2" in dts.
    
    @Mani: I change to check device_property_match_string(), so I can update
    other platform dts file, It should be better than
    	imx6_pcie->drvdata->variant == IMX95_EP
    
    Change from v8 to v9
    - update fixme comments
    - update BAR1 comments
    - Add mani's review tag
    Change from v7 to v8
    - Update commit message
    - Using Fixme
    - Update clks_cnts by ARRAY_SIZE
    
    Change from v4 to v7
    - none
    Change from v3 to v4
    - change align to 4k for imx95
    Change from v1 to v3
    - new patches at v3

 drivers/pci/controller/dwc/pci-imx6.c | 47 +++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index c2098e59fde1e..472ff1cc17d2f 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -75,6 +75,7 @@ enum imx6_pcie_variants {
 	IMX8MQ_EP,
 	IMX8MM_EP,
 	IMX8MP_EP,
+	IMX95_EP,
 };
 
 #define IMX6_PCIE_FLAG_IMX6_PHY			BIT(0)
@@ -84,6 +85,7 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
 #define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
 #define IMX6_PCIE_FLAG_HAS_SERDES		BIT(6)
+#define IMX6_PCIE_FLAG_SUPPORT_64BIT		BIT(7)
 
 #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
 
@@ -616,6 +618,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 		break;
 	case IMX7D:
 	case IMX95:
+	case IMX95_EP:
 		break;
 	case IMX8MM:
 	case IMX8MM_EP:
@@ -1050,6 +1053,23 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
 	.align = SZ_64K,
 };
 
+/*
+ * BAR#	| Default BAR enable	| Default BAR Type	| Default BAR Size	| BAR Sizing Scheme
+ * ================================================================================================
+ * BAR0	| Enable		| 64-bit		| 1 MB			| Programmable Size
+ * BAR1	| Disable		| 32-bit		| 64 KB			| Fixed Size
+ *        BAR1 should be disabled if BAR0 is 64bit.
+ * BAR2	| Enable		| 32-bit		| 1 MB			| Programmable Size
+ * BAR3	| Enable		| 32-bit		| 64 KB			| Programmable Size
+ * BAR4	| Enable		| 32-bit		| 1M			| Programmable Size
+ * BAR5	| Enable		| 32-bit		| 64 KB			| Programmable Size
+ */
+static const struct pci_epc_features imx95_pcie_epc_features = {
+	.msi_capable = true,
+	.bar_fixed_size[1] = SZ_64K,
+	.align = SZ_4K,
+};
+
 static const struct pci_epc_features*
 imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
 {
@@ -1092,6 +1112,15 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
 
 	pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset;
 
+	/*
+	 * FIXME: Ideally, dbi2 base address should come from DT. But since only IMX95 is defining
+	 * "dbi2" in DT, "dbi_base2" is set to NULL here for that platform alone so that the DWC
+	 * core code can fetch that from DT. But once all platform DTs were fixed, this and the
+	 * above "dbi_base2" setting should be removed.
+	 */
+	if (device_property_match_string(dev, "reg-names", "dbi2") >= 0)
+		pci->dbi_base2 = NULL;
+
 	ret = dw_pcie_ep_init(ep);
 	if (ret) {
 		dev_err(dev, "failed to initialize endpoint\n");
@@ -1343,6 +1372,9 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 					     "unable to find iomuxc registers\n");
 	}
 
+	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_SUPPORT_64BIT))
+		dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+
 	/* Grab PCIe PHY Tx Settings */
 	if (of_property_read_u32(node, "fsl,tx-deemph-gen1",
 				 &imx6_pcie->tx_deemph_gen1))
@@ -1561,6 +1593,20 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 		.epc_features = &imx8m_pcie_epc_features,
 	},
+	[IMX95_EP] = {
+		.variant = IMX95_EP,
+		.flags = IMX6_PCIE_FLAG_HAS_SERDES |
+			 IMX6_PCIE_FLAG_SUPPORT_64BIT,
+		.clk_names = imx8mq_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
+		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
+		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
+		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
+		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
+		.init_phy = imx95_pcie_init_phy,
+		.epc_features = &imx95_pcie_epc_features,
+		.mode = DW_PCIE_EP_TYPE,
+	},
 };
 
 static const struct of_device_id imx6_pcie_of_match[] = {
@@ -1575,6 +1621,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
 	{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
 	{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
 	{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
+	{ .compatible = "fsl,imx95-pcie-ep", .data = &drvdata[IMX95_EP], },
 	{},
 };
 
-- 
2.34.1



From suzuki.poulose at arm.com  Mon Feb  5 09:38:23 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 5 Feb 2024 17:38:23 +0000
Subject: [PATCH v3 02/26] KVM: arm64: Add feature checking helpers
In-Reply-To: <20240205103431.1104133-3-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
 <20240205103431.1104133-3-maz@kernel.org>
Message-ID: <35b69e13-757a-435c-8dcc-7079a0313f99@arm.com>

On 05/02/2024 10:34, Marc Zyngier wrote:
> In order to make it easier to check whether a particular feature
> is exposed to a guest, add a new set of helpers, with kvm_has_feat()
> being the most useful.
> 
> Let's start making use of them in the PMU code (courtesy of Oliver).
> Follow-up changes will introduce additional use patterns.
> 
> Co-developed--by: Oliver Upton <oliver.upton at linux.dev>
> Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>


> ---
>   arch/arm64/include/asm/kvm_host.h | 44 +++++++++++++++++++++++++++++++
>   arch/arm64/kvm/pmu-emul.c         | 11 ++++----
>   arch/arm64/kvm/sys_regs.c         |  6 ++---
>   include/kvm/arm_pmu.h             | 11 --------
>   4 files changed, 52 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 21c57b812569..527da3d2cedb 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -1233,4 +1233,48 @@ static inline void kvm_hyp_reserve(void) { }
>   void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
>   bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
>   
> +#define __expand_field_sign_unsigned(id, fld, val)			\
> +	((u64)SYS_FIELD_VALUE(id, fld, val))
> +
> +#define __expand_field_sign_signed(id, fld, val)			\
> +	({								\
> +		u64 __val = SYS_FIELD_VALUE(id, fld, val);		\
> +		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
> +	})
> +
> +#define expand_field_sign(id, fld, val)					\
> +	(id##_##fld##_SIGNED ?						\
> +	 __expand_field_sign_signed(id, fld, val) :			\
> +	 __expand_field_sign_unsigned(id, fld, val))
> +
> +#define get_idreg_field_unsigned(kvm, id, fld)				\
> +	({								\
> +		u64 __val = IDREG((kvm), SYS_##id);			\
> +		FIELD_GET(id##_##fld##_MASK, __val);			\
> +	})
> +
> +#define get_idreg_field_signed(kvm, id, fld)				\
> +	({								\
> +		u64 __val = get_idreg_field_unsigned(kvm, id, fld);	\
> +		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
> +	})
> +
> +#define get_idreg_field_enum(kvm, id, fld)				\
> +	get_idreg_field_unsigned(kvm, id, fld)
> +
> +#define get_idreg_field(kvm, id, fld)					\
> +	(id##_##fld##_SIGNED ?						\
> +	 get_idreg_field_signed(kvm, id, fld) :				\
> +	 get_idreg_field_unsigned(kvm, id, fld))
> +
> +#define kvm_has_feat(kvm, id, fld, limit)				\
> +	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit))
> +
> +#define kvm_has_feat_enum(kvm, id, fld, val)				\
> +	(get_idreg_field_unsigned((kvm), id, fld) == __expand_field_sign_unsigned(id, fld, val))
> +
> +#define kvm_has_feat_range(kvm, id, fld, min, max)			\
> +	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
> +	 get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
> +
>   #endif /* __ARM64_KVM_HOST_H__ */
> diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> index 3d9467ff73bc..925522470b2b 100644
> --- a/arch/arm64/kvm/pmu-emul.c
> +++ b/arch/arm64/kvm/pmu-emul.c
> @@ -64,12 +64,11 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm)
>   {
>   	u64 mask = ARMV8_PMU_EXCLUDE_EL1 | ARMV8_PMU_EXCLUDE_EL0 |
>   		   kvm_pmu_event_mask(kvm);
> -	u64 pfr0 = IDREG(kvm, SYS_ID_AA64PFR0_EL1);
>   
> -	if (SYS_FIELD_GET(ID_AA64PFR0_EL1, EL2, pfr0))
> +	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL2, IMP))
>   		mask |= ARMV8_PMU_INCLUDE_EL2;
>   
> -	if (SYS_FIELD_GET(ID_AA64PFR0_EL1, EL3, pfr0))
> +	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL3, IMP))
>   		mask |= ARMV8_PMU_EXCLUDE_NS_EL0 |
>   			ARMV8_PMU_EXCLUDE_NS_EL1 |
>   			ARMV8_PMU_EXCLUDE_EL3;
> @@ -83,8 +82,10 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm)
>    */
>   static bool kvm_pmc_is_64bit(struct kvm_pmc *pmc)
>   {
> +	struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc);
> +
>   	return (pmc->idx == ARMV8_PMU_CYCLE_IDX ||
> -		kvm_pmu_is_3p5(kvm_pmc_to_vcpu(pmc)));
> +		kvm_has_feat(vcpu->kvm, ID_AA64DFR0_EL1, PMUVer, V3P5));
>   }
>   
>   static bool kvm_pmc_has_64bit_overflow(struct kvm_pmc *pmc)
> @@ -556,7 +557,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val)
>   		return;
>   
>   	/* Fixup PMCR_EL0 to reconcile the PMU version and the LP bit */
> -	if (!kvm_pmu_is_3p5(vcpu))
> +	if (!kvm_has_feat(vcpu->kvm, ID_AA64DFR0_EL1, PMUVer, V3P5))
>   		val &= ~ARMV8_PMU_PMCR_LP;
>   
>   	/* The reset bits don't indicate any state, and shouldn't be saved. */
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 041b11825578..3c31f8cb9eef 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -505,10 +505,9 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
>   			  struct sys_reg_params *p,
>   			  const struct sys_reg_desc *r)
>   {
> -	u64 val = IDREG(vcpu->kvm, SYS_ID_AA64MMFR1_EL1);
>   	u32 sr = reg_to_encoding(r);
>   
> -	if (!(val & (0xfUL << ID_AA64MMFR1_EL1_LO_SHIFT))) {
> +	if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR1_EL1, LO, IMP)) {
>   		kvm_inject_undefined(vcpu);
>   		return false;
>   	}
> @@ -2748,8 +2747,7 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
>   		return ignore_write(vcpu, p);
>   	} else {
>   		u64 dfr = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1);
> -		u64 pfr = IDREG(vcpu->kvm, SYS_ID_AA64PFR0_EL1);
> -		u32 el3 = !!SYS_FIELD_GET(ID_AA64PFR0_EL1, EL3, pfr);
> +		u32 el3 = kvm_has_feat(vcpu->kvm, ID_AA64PFR0_EL1, EL3, IMP);
>   
>   		p->regval = ((SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr) << 28) |
>   			     (SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, dfr) << 24) |
> diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
> index 4b9d8fb393a8..eb4c369a79eb 100644
> --- a/include/kvm/arm_pmu.h
> +++ b/include/kvm/arm_pmu.h
> @@ -90,16 +90,6 @@ void kvm_vcpu_pmu_resync_el0(void);
>   			vcpu->arch.pmu.events = *kvm_get_pmu_events();	\
>   	} while (0)
>   
> -/*
> - * Evaluates as true when emulating PMUv3p5, and false otherwise.
> - */
> -#define kvm_pmu_is_3p5(vcpu) ({						\
> -	u64 val = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1);		\
> -	u8 pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer, val);	\
> -									\
> -	pmuver >= ID_AA64DFR0_EL1_PMUVer_V3P5;				\
> -})
> -
>   u8 kvm_arm_pmu_get_pmuver_limit(void);
>   u64 kvm_pmu_evtyper_mask(struct kvm *kvm);
>   int kvm_arm_set_default_pmu(struct kvm *kvm);
> @@ -168,7 +158,6 @@ static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
>   }
>   
>   #define kvm_vcpu_has_pmu(vcpu)		({ false; })
> -#define kvm_pmu_is_3p5(vcpu)		({ false; })
>   static inline void kvm_pmu_update_vcpu_events(struct kvm_vcpu *vcpu) {}
>   static inline void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) {}
>   static inline void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) {}



From Frank.li at nxp.com  Mon Feb  5 09:41:15 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 5 Feb 2024 12:41:15 -0500
Subject: [PATCH v9 05/16] PCI: imx6: Using "linux,pci-domain" as slot ID
In-Reply-To: <Zb06JL5X8EiHEyFD@lpieralisi>
References: <20240119171122.3057511-1-Frank.Li@nxp.com>
 <20240119171122.3057511-6-Frank.Li@nxp.com>
 <ZbzcOarorCS1MPRc@lpieralisi>
 <ZbztZkNQ+wydticD@lizhi-Precision-Tower-5810>
 <Zb06JL5X8EiHEyFD@lpieralisi>
Message-ID: <ZcEdu9Jw1k6Kwuz4@lizhi-Precision-Tower-5810>

On Fri, Feb 02, 2024 at 07:53:24PM +0100, Lorenzo Pieralisi wrote:
> On Fri, Feb 02, 2024 at 08:25:58AM -0500, Frank Li wrote:
> > On Fri, Feb 02, 2024 at 01:12:41PM +0100, Lorenzo Pieralisi wrote:
> > > "PCI: imx6: Use "linux,pci-domain" as slot ID"
> > > 
> > > On Fri, Jan 19, 2024 at 12:11:11PM -0500, Frank Li wrote:
> > > > Avoid use get slot id by compared with register physical address. If there
> > > > are more than 2 slots, compared logic will become complex.
> > > > 
> > > > "linux,pci-domain" already exist at dts since commit:
> > > > 	commit (c0b70f05c87f3b arm64: dts: imx8mq: use_dt_domains for pci node).
> > > > 
> > > > So it is safe to remove compare basic address code:
> > > > 	...
> > > > 	if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> > > > 		imx6_pcie->controller_id = 1;
> > > 
> > > No it is not unless you magically update all firmware out
> > > there in the field.
> > 
> > commit c0b70f05c87f3b09b391027c6f056d0facf331ef
> > Author:     Peng Fan <peng.fan at nxp.com>
> > AuthorDate: Fri Jan 15 11:26:57 2021 +0800
> > Commit:     Shawn Guo <shawnguo at kernel.org>
> > CommitDate: Fri Jan 29 14:46:28 2021 +0800
> > 
> > I am not sure if it is neccesary to compatible with 2 years ago's dts.
> > I think it may not boot at all with using 2 year agao dtb file directly.
> > 
> > Do you have other comments? I can remove it from this big patch series,
> 
> I will have a look at the full series first we can decide whether
> to drop it later.
> 
> I am travelling so I am not sure I can review it before February
> 12th, FYI.

Okay, I send v10 at
https://lore.kernel.org/imx/Zb06JL5X8EiHEyFD at lpieralisi/raw
which removed "linux,pci-domain" patches.

If you have more comments, please comment at v10 version.

Frank


> 
> Lorenzo


From broonie at kernel.org  Mon Feb  5 09:41:47 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 5 Feb 2024 17:41:47 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <ZcEW3y0IlEctOYBA@e133380.arm.com>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
 <ZcEW3y0IlEctOYBA@e133380.arm.com>
Message-ID: <ZcEd2zU/JpeIwn5f@finisterre.sirena.org.uk>

On Mon, Feb 05, 2024 at 05:11:59PM +0000, Dave Martin wrote:
> On Sat, Feb 03, 2024 at 12:16:49PM +0000, Mark Brown wrote:

> > We could also teach the ptrace core about runtime discoverable regset sizes
> > but that would be a more invasive change and this is being observed in
> > practical systems.

> This is not hard at all: see
> 27e64b4be4b8 ("regset: Add support for dynamically sized regsets") 

> But since this is precisely what was ripped out, I guess adding it back
> may be controversial (?)

Also just that people might want to backport and while it's not super
*hard* I tend to prefer to do something as minimal as possible as a fix,
the less we do the less the chances that we mess up.

> > We should probably also use the actual architectural limit for the
> > bitmasks we use in the VL enumeration code, though that's both a little
> > bit more involved and less immediately a problem.

> Since these masks are 64 bytes each and rarely accessed, it seemed
> pointless complexity to make them resizeable...

I was suggesting making them use the architectural maximum rather than
making them dynamic.

> > +#define ARCH_SVE_VQ_MAX 16
> >  #define SME_VQ_MAX	16

> Ack, though part of the reason for not doing this was to discourage
> people from allocating statically sized buffers in general.

I was going to do a patch adding a comment to the header noting that
this is not actually the architectural maximum since at present it's
a bit of a landmine, people who have some idea of the architecture
likely have a rough idea what sort of allocation size is needed for the
maximum SVE state and are likely to not double check the value provided
(I think that's what happened with the refactoring to remove the dynamic
sizing).  A comment in the header is still very missable but it'd be
something.

> If the kernel is now juggling two #defines for the maximum vector size,
> this feels like it may seed bitrot...

Ideally we'd just not have the existing define externally but it's there
and it's been 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/20240205/990f9e07/attachment.sig>

From u-kumar1 at ti.com  Mon Feb  5 09:43:27 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Mon, 5 Feb 2024 23:13:27 +0530
Subject: [PATCH v1] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240205140459.orjvjqqtiugmyosc@obscurity>
References: <20240205044557.3340848-1-u-kumar1@ti.com>
 <20240205140459.orjvjqqtiugmyosc@obscurity>
Message-ID: <5a17f3dd-a27a-49d3-9e54-a0022333abe2@ti.com>


On 2/5/2024 7:34 PM, Nishanth Menon wrote:
> On 10:15-20240205, Udit Kumar wrote:
>> Most of clocks and their parents are defined in contiguous range,
>> But in few cases, there is gap in clock numbers[0].
>>
>> Driver assumes clocks to be in contiguous range, and assigns
>> accordingly.
>>
>> New firmware started returning error in case of
>> non-available clock id.  Therefore drivers throws error while
>> re-calculate and other functions.
> What changed here? started returning error for what API? also please fix
> up 70 char alignment -> there extra spaces in your commit message.


will address in v2

>> In this fix, before assigning and adding clock in list,
>> driver checks if given clock is valid or not.
>>
>> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
>>
>> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
>> Section Clocks for NAVSS0_CPTS_0 Device,
>> clock id 12-15 and 18-19 not present
>>
>> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
>> ---
>> Original logs
>> https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
>> Line 2630 for error
>>
>> Logs with fix
>> https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-with-fix
>> Line 2594
>>
>>   drivers/clk/keystone/sci-clk.c | 20 ++++++++++++++++----
>>   1 file changed, 16 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
>> index 35fe197dd303..d417ec018d82 100644
>> --- a/drivers/clk/keystone/sci-clk.c
>> +++ b/drivers/clk/keystone/sci-clk.c
>> @@ -517,6 +517,8 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>>   	int num_clks = 0;
>>   	int num_parents;
>> [..]
>> -					num_clks++;
>> +						ret = provider->ops->get_freq(provider->sci,
>> +							   sci_clk->dev_id, sci_clk->clk_id, &freq);
>> +					} while (ret != 0 && clk_id < max_clk_id);
> take clock ids 0 1 2 3 -> Say 2 is reserved.
> num_parents = 4
> while(num_parents) Loop 1 ->  clk ID 0 is valid, list_add_tail
> while(num_parents) Loop 2 ->  clk ID 1 is valid, list_add_tail
> while(num_parents) Loop 3 ->  clk ID 2 is invalid.. so we scan forward
> 	to clk ID 3 -> list_add_tail
> while(num_parents) Loop 4 ->  clk ID 4 is invalid.. but 5 is out of
> 	range, so we break off loop. sci_clk is still devm_kzalloced ->
> 	but since clk_id > max_clk_id, we jump off loop, and we dont add
> 	it to tail. so one extra allocation?

Thanks for catching this.


> If we have multiple reserved intermediate ones, then we'd have as many
> allocations that aren't linked? Could we not improve the logic a bit to
> allocate just what is necessary?

Sure, will change in v2.

to check clock validity first and then allocate, add


>> +
>> +					sci_clk->provider = provider;
>> +					if (ret == 0) {
>> +						list_add_tail(&sci_clk->node, &clks);
>> +						num_clks++;
>> +					}
>>   				}
>>   			}
>>   
>> -- 
>> 2.34.1
>>


From afd at ti.com  Mon Feb  5 09:44:13 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 11:44:13 -0600
Subject: [PATCH 1/2] dt-bindings: mfd: syscon: Add ti,am654-serdes-ctrl
 compatible
In-Reply-To: <a50c5731-b328-4bf1-9449-ad15eb0f9ea6@ti.com>
References: <20240130195128.58748-1-afd@ti.com>
 <a50c5731-b328-4bf1-9449-ad15eb0f9ea6@ti.com>
Message-ID: <cacd8a60-3006-4e16-b0ad-1d194ef0d70b@ti.com>

On 2/5/24 8:05 AM, Vignesh Raghavendra wrote:
> 
> 
> On 31/01/24 01:21, Andrew Davis wrote:
>> Add TI SERDES control registers compatible. This is a region found in the
>> TI AM65 CTRL_MMR0 register space[0]. Each instance is used to control a
>> SERDES clock and lane select mux.
>>
>> [0] https://www.ti.com/lit/pdf/spruid7
>>
>> Signed-off-by: Andrew Davis <afd at ti.com>
>> ---
>>   Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
>> index 084b5c2a2a3c2..d8679a2ad4b10 100644
>> --- a/Documentation/devicetree/bindings/mfd/syscon.yaml
>> +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
>> @@ -73,6 +73,7 @@ properties:
>>                 - rockchip,rv1126-qos
>>                 - starfive,jh7100-sysmain
>>                 - ti,am654-dss-oldi-io-ctrl
>> +              - ti,am654-serdes-ctrl
>>   
>>             - const: syscon
>>   
> 
> This needs to go via mfd tree (or at least need an ACK). Please cc
> appropriate maintainer  (Lee Jones <lee at kernel.org>). So, I recommended
> to split 2/2 out into separate series and post once this patch is merged.
> 

Sure, will send this patch standalone, then post the dts changes later.

Andrew


From jernej.skrabec at gmail.com  Mon Feb  5 09:45:27 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 18:45:27 +0100
Subject: [PATCH v2 1/6] clk: sunxi-ng: nkm: Support constraints on m/n ratio and
 parent rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-1-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-1-96a46a2d8c9b@oltmanns.dev>
Message-ID: <2717565.mvXUDI8C0e@jernej-laptop>

Dne ponedeljek, 05. februar 2024 ob 16:22:24 CET je Frank Oltmanns napisal(a):
> The Allwinner A64 manual lists the following constraints for the
> PLL-MIPI clock:
>  - M/N <= 3
>  - (PLL_VIDEO0)/M >= 24MHz
> 
> The PLL-MIPI clock is implemented as ccu_nkm. Therefore, add support for
> these constraints.
> 
> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>

Haven't we discussed that this patch is unnecessary because same effect can
be reached by limiting minimum frequency?

Best regards,
Jernej

> ---
>  drivers/clk/sunxi-ng/ccu_nkm.c | 21 +++++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index 853f84398e2b..1168d894d636 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -16,6 +16,20 @@ struct _ccu_nkm {
>  	unsigned long	m, min_m, max_m;
>  };
>  
> +static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned long parent,
> +				  unsigned long n, unsigned long m)
> +{
> +	struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common);
> +
> +	if (nkm->max_m_n_ratio && (m > nkm->max_m_n_ratio * n))
> +		return false;
> +
> +	if (nkm->min_parent_m_ratio && (parent < nkm->min_parent_m_ratio * m))
> +		return false;
> +
> +	return true;
> +}
> +
>  static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common,
>  						       struct clk_hw *parent_hw,
>  						       unsigned long *parent, unsigned long rate,
> @@ -31,6 +45,10 @@ static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common
>  				unsigned long tmp_rate, tmp_parent;
>  
>  				tmp_parent = clk_hw_round_rate(parent_hw, rate * _m / (_n * _k));
> +
> +				if (!ccu_nkm_is_valid_rate(common, tmp_parent, _n, _m))
> +					continue;
> +
>  				tmp_rate = tmp_parent * _n * _k / _m;
>  
>  				if (ccu_is_better_rate(common, rate, tmp_rate, best_rate) ||
> @@ -64,6 +82,9 @@ static unsigned long ccu_nkm_find_best(unsigned long parent, unsigned long rate,
>  	for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
>  		for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
>  			for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
> +				if (!ccu_nkm_is_valid_rate(common, parent, _n, _m))
> +					continue;
> +
>  				unsigned long tmp_rate;
>  
>  				tmp_rate = parent * _n * _k / _m;
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
> index 6601defb3f38..c409212ee40e 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> @@ -27,6 +27,8 @@ struct ccu_nkm {
>  	struct ccu_mux_internal	mux;
>  
>  	unsigned int		fixed_post_div;
> +	unsigned long		max_m_n_ratio;
> +	unsigned long		min_parent_m_ratio;
>  
>  	struct ccu_common	common;
>  };
> 
> 






From tj at kernel.org  Mon Feb  5 09:45:54 2024
From: tj at kernel.org (Tejun Heo)
Date: Mon, 5 Feb 2024 07:45:54 -1000
Subject: [Bisected] [commit dd6c3c544126] [linux-next] [6.8.0-rc2] Task
 hungs for infinite time call traces
In-Reply-To: <a95f5bcd-3c49-4ebd-b1b3-a688c5b6727c@linux.vnet.ibm.com>
References: <a95f5bcd-3c49-4ebd-b1b3-a688c5b6727c@linux.vnet.ibm.com>
Message-ID: <ZcEe0q8Bg5zca1nA@slm.duckdns.org>

Hello,

On Mon, Feb 05, 2024 at 03:24:17PM +0530, Tasmiya Nalatwad wrote:
> Greetings,
> 
> [Linux-next] [6.8.0-rc2-next-20240130] [FC / XFS] Task hangs for infinite
> time while running bonnie test XFS filesystem
> 
> Bisected the issue. Git bisect points to the below commit
> commit dd6c3c5441263723305a9c52c5ccc899a4653000
> ????????? workqueue: Move pwq_dec_nr_in_flight() to the end of work item
> handling

This should be fixed by c70e1779b73a ("Fix pwq->nr_in_flight corruption in
try_to_grab_pending()").

Thanks.

-- 
tejun


From broonie at kernel.org  Mon Feb  5 09:47:03 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 05 Feb 2024 17:47:03 +0000
Subject: [PATCH v5] spi: imx: fix the burst length at DMA mode and CPU
 mode
In-Reply-To: <20240204091912.36488-1-carlos.song@nxp.com>
References: <20240204091912.36488-1-carlos.song@nxp.com>
Message-ID: <170715522367.847267.14071106009498726230.b4-ty@kernel.org>

On Sun, 04 Feb 2024 17:19:12 +0800, carlos.song at nxp.com wrote:
> For DMA mode, the bus width of the DMA is equal to the size of data
> word, so burst length should be configured as bits per word.
> 
> For CPU mode, because of the spi transfer len is in byte, so calculate
> the total number of words according to spi transfer len and bits per
> word, burst length should be configured as total data bits.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: imx: fix the burst length at DMA mode and CPU mode
      commit: c712c05e46c8ce550842951e9e2606e24dbf0475

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 ulf.hansson at linaro.org  Mon Feb  5 09:49:30 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 5 Feb 2024 18:49:30 +0100
Subject: [PATCH v2 1/2] dt-bindings: net: bluetooth: Add MediaTek MT7921S
 SDIO Bluetooth
In-Reply-To: <CAGXv+5FwaNe7oesGwZ=yR0Pg82tEzEF3B0zjoex4qw+6zsSYbQ@mail.gmail.com>
References: <20240126063500.2684087-1-wenst@chromium.org> <20240126063500.2684087-2-wenst@chromium.org>
 <74b9f249-fcb4-4338-bf7b-8477de6c935c@linaro.org> <CAGXv+5Hu+KsTBd1JtnKcaE3qUzPhHbunoVaH2++yfNopHtFf4g@mail.gmail.com>
 <21568334-b21f-429e-81cd-5ce77accaf3c@linaro.org> <CAGXv+5HxXzjigN3Bp96vkv71WfTJ1S2b7Wgafc4GxLmhu6+jMg@mail.gmail.com>
 <a4324473-e0c6-4d53-8de0-03b69480e40b@linaro.org> <CAGXv+5HAqmUizXztMH_nY6e+6oQh01hCtxEJXKtCn3_74-sOsQ@mail.gmail.com>
 <78241d63-3b9d-4c04-9ea5-11b45eac6f00@linaro.org> <20240130223856.GA2538998-robh@kernel.org>
 <CAGXv+5FwaNe7oesGwZ=yR0Pg82tEzEF3B0zjoex4qw+6zsSYbQ@mail.gmail.com>
Message-ID: <CAPDyKFofy24N7ymzTF7wiADc17Tw9FiNTYMnbxgoioMBwDKVhA@mail.gmail.com>

On Wed, 31 Jan 2024 at 04:39, Chen-Yu Tsai <wenst at chromium.org> wrote:
>
> (+CC Ulf Hansson)
>
> On Wed, Jan 31, 2024 at 6:38?AM Rob Herring <robh at kernel.org> wrote:
> >
> > On Tue, Jan 30, 2024 at 05:25:38PM +0100, Krzysztof Kozlowski wrote:
> > > On 30/01/2024 08:47, Chen-Yu Tsai wrote:
> > > > On Tue, Jan 30, 2024 at 3:37?PM Krzysztof Kozlowski
> > > > <krzysztof.kozlowski at linaro.org> wrote:
> > > >>
> > > >> On 30/01/2024 04:32, Chen-Yu Tsai wrote:
> > > >>> On Mon, Jan 29, 2024 at 3:34?PM Krzysztof Kozlowski
> > > >>> <krzysztof.kozlowski at linaro.org> wrote:
> > > >>>>
> > > >>>> On 29/01/2024 04:38, Chen-Yu Tsai wrote:
> > > >>>>
> > > >>>>>>> +allOf:
> > > >>>>>>> +  - $ref: bluetooth-controller.yaml#
> > > >>>>>>> +
> > > >>>>>>> +properties:
> > > >>>>>>> +  compatible:
> > > >>>>>>> +    enum:
> > > >>>>>>> +      - mediatek,mt7921s-bluetooth
> > > >>>>>>
> > > >>>>>> Can it be also WiFi on separate bus? How many device nodes do you need
> > > >>>>>> for this device?
> > > >>>>>
> > > >>>>> For the "S" variant, WiFi is also on SDIO. For the other two variants,
> > > >>>>> "U" and "E", WiFi goes over USB and PCIe respectively. On both those
> > > >>>>> variants, Bluetooth can either go over USB or UART. That is what I
> > > >>>>> gathered from the pinouts. There are a dozen GPIO pins which don't
> > > >>>>> have detailed descriptions though. If you want a comprehensive
> > > >>>>> binding of the whole chip and all its variants, I suggest we ask
> > > >>>>> MediaTek to provide it instead. My goal with the binding is to document
> > > >>>>> existing usage and allow me to upstream new device trees.
> > > >>>>>
> > > >>>>> For now we only need the Bluetooth node. The WiFi part is perfectly
> > > >>>>> detectable, and the driver doesn't seem to need the WiFi reset pin.
> > > >>>>> The Bluetooth driver only uses its reset pin to reset a hung controller.
> > > >>>>
> > > >>>> Then suffix "bluetooth" seems redundant.
> > > >>>
> > > >>> I think keeping the suffix makes more sense though. The chip is a two
> > > >>> function piece, and this only targets one of the functions. Also, the
> > > >>
> > > >> That's why I asked and you said there is only one interface: SDIO.
> > > >
> > > > There's only one interface, SDIO, but two SDIO functions. The two
> > > > functions, if both were to be described in the device tree, would
> > > > be two separate nodes. We just don't have any use for the WiFi one
> > > > right now. Does that make sense to keep the suffix?
> > >
> > > Number of functions does not really matter. Number of interfaces on the
> > > bus would matter. Why would you have two separate nodes for the same
> > > SDIO interface? Or do you want to say there are two interfaces?
>
> There is only one external interface. I don't know how the functions
> are stitched together internally.
>
> It could be that the separate functions have nothing in common other
> than sharing a standard external SDIO interface. Each function can be
> individually controlled, and operations for different functions are
> directed internally to the corresponding core.
>
> > Right, one device at 2 addresses on a bus should be a node with 2 "reg"
> > entries, not 2 nodes with 1 "reg" address each.
>
> AFAICU that's not what the MMC controller binding, which I quote below,
> says. It implies that each SDIO function shall be a separate node under
> the MMC controller node.

Yes, that's what we decided to go with, a long time ago. At least in
this particular case, I think it makes sense, as each function
(child-node) may also describe additional resources routed to each
function.

A typical description could be for a WiFi-Bluetooth combo-chip, where
each function may have its own clocks, irqs and regulators being
routed.

>
>
> patternProperties:
>   "^.*@[0-9]+$":
>     type: object
>     description: |
>       On embedded systems the cards connected to a host may need
>       additional properties. These can be specified in subnodes to the
>       host controller node. The subnodes are identified by the
>       standard \'reg\' property. Which information exactly can be
>       specified depends on the bindings for the SDIO function driver
>       for the subnode, as specified by the compatible string.
>
>     properties:
>       compatible:
>         description: |
>           Name of SDIO function following generic names recommended
>           practice
>
>       reg:
>         items:
>           - minimum: 0
>             maximum: 7
>             description:
>               Must contain the SDIO function number of the function this
>               subnode describes. A value of 0 denotes the memory SD
>               function, values from 1 to 7 denote the SDIO functions.
>
>
> ChenYu

Kind regards
Uffe


From frank at oltmanns.dev  Mon Feb  5 09:50:27 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 05 Feb 2024 18:50:27 +0100
Subject: [PATCH v2 1/6] clk: sunxi-ng: nkm: Support constraints on m/n
 ratio and parent rate
In-Reply-To: <2717565.mvXUDI8C0e@jernej-laptop>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-1-96a46a2d8c9b@oltmanns.dev>
 <2717565.mvXUDI8C0e@jernej-laptop>
Message-ID: <87il32ztp8.fsf@oltmanns.dev>

Hi Jernej,

On 2024-02-05 at 18:45:27 +0100, Jernej ?krabec <jernej.skrabec at gmail.com> wrote:
> Dne ponedeljek, 05. februar 2024 ob 16:22:24 CET je Frank Oltmanns napisal(a):
>> The Allwinner A64 manual lists the following constraints for the
>> PLL-MIPI clock:
>>  - M/N <= 3
>>  - (PLL_VIDEO0)/M >= 24MHz
>>
>> The PLL-MIPI clock is implemented as ccu_nkm. Therefore, add support for
>> these constraints.
>>
>> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
>
> Haven't we discussed that this patch is unnecessary because same effect can
> be reached by limiting minimum frequency?

The patch for ccu_nm was unnecessary:
https://lore.kernel.org/all/87jzoug2jz.fsf at oltmanns.dev/

Unfortunately, we still need this one.

Best regards,
  Frank

>
> Best regards,
> Jernej
>
>> ---
>>  drivers/clk/sunxi-ng/ccu_nkm.c | 21 +++++++++++++++++++++
>>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>>  2 files changed, 23 insertions(+)
>>
>> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
>> index 853f84398e2b..1168d894d636 100644
>> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
>> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
>> @@ -16,6 +16,20 @@ struct _ccu_nkm {
>>  	unsigned long	m, min_m, max_m;
>>  };
>>
>> +static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned long parent,
>> +				  unsigned long n, unsigned long m)
>> +{
>> +	struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common);
>> +
>> +	if (nkm->max_m_n_ratio && (m > nkm->max_m_n_ratio * n))
>> +		return false;
>> +
>> +	if (nkm->min_parent_m_ratio && (parent < nkm->min_parent_m_ratio * m))
>> +		return false;
>> +
>> +	return true;
>> +}
>> +
>>  static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common,
>>  						       struct clk_hw *parent_hw,
>>  						       unsigned long *parent, unsigned long rate,
>> @@ -31,6 +45,10 @@ static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common
>>  				unsigned long tmp_rate, tmp_parent;
>>
>>  				tmp_parent = clk_hw_round_rate(parent_hw, rate * _m / (_n * _k));
>> +
>> +				if (!ccu_nkm_is_valid_rate(common, tmp_parent, _n, _m))
>> +					continue;
>> +
>>  				tmp_rate = tmp_parent * _n * _k / _m;
>>
>>  				if (ccu_is_better_rate(common, rate, tmp_rate, best_rate) ||
>> @@ -64,6 +82,9 @@ static unsigned long ccu_nkm_find_best(unsigned long parent, unsigned long rate,
>>  	for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
>>  		for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
>>  			for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
>> +				if (!ccu_nkm_is_valid_rate(common, parent, _n, _m))
>> +					continue;
>> +
>>  				unsigned long tmp_rate;
>>
>>  				tmp_rate = parent * _n * _k / _m;
>> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
>> index 6601defb3f38..c409212ee40e 100644
>> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
>> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
>> @@ -27,6 +27,8 @@ struct ccu_nkm {
>>  	struct ccu_mux_internal	mux;
>>
>>  	unsigned int		fixed_post_div;
>> +	unsigned long		max_m_n_ratio;
>> +	unsigned long		min_parent_m_ratio;
>>
>>  	struct ccu_common	common;
>>  };
>>
>>


From robin.murphy at arm.com  Mon Feb  5 09:55:03 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 5 Feb 2024 17:55:03 +0000
Subject: [PATCH 04/12] bcm2835-dma: Advertise the full DMA range
In-Reply-To: <a56a6d24066a64598efe4343090e51e2223475b8.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
 <a56a6d24066a64598efe4343090e51e2223475b8.1706948717.git.andrea.porta@suse.com>
Message-ID: <1e71c153-e482-409c-b229-9b9c0662b67e@arm.com>

On 2024-02-04 6:59 am, Andrea della Porta wrote:
> From: Phil Elwell <phil at raspberrypi.com>
> 
> Unless the DMA mask is set wider than 32 bits, DMA mapping will use a
> bounce buffer.
> 
> Signed-off-by: Phil Elwell <phil at raspberrypi.com>
> ---
>   drivers/dma/bcm2835-dma.c | 18 +++++++++++++++---
>   1 file changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> index 36bad198b655..237dcdb8d726 100644
> --- a/drivers/dma/bcm2835-dma.c
> +++ b/drivers/dma/bcm2835-dma.c
> @@ -39,6 +39,7 @@
>   #define BCM2711_DMA_MEMCPY_CHAN 14
>   
>   struct bcm2835_dma_cfg_data {
> +	u64	dma_mask;
>   	u32	chan_40bit_mask;
>   };
>   
> @@ -308,10 +309,12 @@ DEFINE_SPINLOCK(memcpy_lock);
>   
>   static const struct bcm2835_dma_cfg_data bcm2835_dma_cfg = {
>   	.chan_40bit_mask = 0,
> +	.dma_mask = DMA_BIT_MASK(32),
>   };
>   
>   static const struct bcm2835_dma_cfg_data bcm2711_dma_cfg = {
>   	.chan_40bit_mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
> +	.dma_mask = DMA_BIT_MASK(36),
>   };
>   
>   static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c)
> @@ -1263,6 +1266,8 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
>   
>   static int bcm2835_dma_probe(struct platform_device *pdev)
>   {
> +	const struct bcm2835_dma_cfg_data *cfg_data;
> +	const struct of_device_id *of_id;
>   	struct bcm2835_dmadev *od;
>   	struct resource *res;
>   	void __iomem *base;
> @@ -1272,13 +1277,20 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
>   	int irq_flags;
>   	uint32_t chans_available;
>   	char chan_name[BCM2835_DMA_CHAN_NAME_SIZE];
> -	const struct of_device_id *of_id;
>   	int chan_count, chan_start, chan_end;
>   
> +	of_id = of_match_node(bcm2835_dma_of_match, pdev->dev.of_node);
> +	if (!of_id) {
> +		dev_err(&pdev->dev, "Failed to match compatible string\n");
> +		return -EINVAL;
> +	}
> +
> +	cfg_data = of_id->data;

We've had of_device_get_match_data() for nearly 9 years now, and even a 
generic device_get_match_data() for 6 ;)

> +
>   	if (!pdev->dev.dma_mask)
>   		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;

[ Passing nit: that also really shouldn't be there, especially since 
cdfee5623290 ]

>   
> -	rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
> +	rc = dma_set_mask_and_coherent(&pdev->dev, cfg_data->dma_mask);

Wait, does chan_40bit_mask mean that you still have some channels which 
*can't* address this full mask? If so this can't work properly. You may 
well need to redesign a bit further to have a separate DMA device for 
each channel such they can each have different masks.

Thanks,
Robin.

>   	if (rc) {
>   		dev_err(&pdev->dev, "Unable to set DMA mask\n");
>   		return rc;
> @@ -1342,7 +1354,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
>   		return -EINVAL;
>   	}
>   
> -	od->cfg_data = of_id->data;
> +	od->cfg_data = cfg_data;
>   
>   	/* Request DMA channel mask from device tree */
>   	if (of_property_read_u32(pdev->dev.of_node,


From neil.armstrong at linaro.org  Mon Feb  5 09:55:27 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 05 Feb 2024 18:55:27 +0100
Subject: [PATCH v10 0/7] drm/meson: add support for MIPI DSI Display
Message-ID: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>

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 is a follow-up of v5  now the DRM patches are applied, the clk & DT changes
remains for a full DSI support on G12A & SM1 platforms.

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.

The clock setup has been redesigned to use CCF, a common PLL (GP0) and the VCLK2 clock
path for DSI in preparation of full CCF support and possibly dual display with HDMI.

The change from v5 is that now we use a "VCLK" driver instead of notifier and rely
on CLK_SET_RATE_GATE to ensure the VCLK gate operation are called.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
Changes in v10:
- Rename regmap_vclk to meson_clk and add _gate for the gate
- Move COMMON_CLK_MESON_VCLK to following patch
- Remove CLK_SET_RATE_PARENT from g12a_vclk2_sel, keep it only on mipi_dsi_pxclk_sel
- Add more info on commit message to specify how clock setup is designed
- Remove forgotten CLK_IGNORE_UNUSED on g12a_vclk2_input
- Remove useless CLK_SET_RATE_PARENT on g12a_vclk2_div to stop propagatting rate _after_ vclk2_div
- Remove invalid CLK_SET_RATE_GATE on g12a_vclk2 since it's not a divider...
- Drop already applied patches
- move Khadas TS050 changes as an overlay
- Link to v9: https://lore.kernel.org/r/20231124-amlogic-v6-4-upstream-dsi-ccf-vim3-v9-0-95256ed139e6 at linaro.org

Changes in v9:
- Colledte reviewed-bys
- Fixed patches 2 & 4, commit messages and bindings format
- Link to v8: https://lore.kernel.org/r/20231109-amlogic-v6-4-upstream-dsi-ccf-vim3-v8-0-81e4aeeda193 at linaro.org

Changes in v8:
- Switch vclk clk driver to parm as requested by Jerome
- Added bindings fixes to amlogic,meson-axg-mipi-pcie-analog & amlogic,g12a-mipi-dphy-analog
- Fixed DT errors in vim3 example and MNT Reform DT
- Rebased on next-20231107, successfully tested on VIM3L
- Link to v7: https://lore.kernel.org/r/20230803-amlogic-v6-4-upstream-dsi-ccf-vim3-v7-0-762219fc5b28 at linaro.org

Changes in v7:
- Added review tags
- Fixed patch 5 thanks to George
- Link to v6: https://lore.kernel.org/r/20230512-amlogic-v6-4-upstream-dsi-ccf-vim3-v6-0-fd2ac9845472 at linaro.org

Changes in v6:
- dropped applied DRM patches
- dropped clk private prefix patches
- rebased on top of 20230607-topic-amlogic-upstream-clkid-public-migration-v2-0-38172d17c27a at linaro.org
- re-ordered/cleaned ENCL patches to match clkid public migration
- Added new "vclk" driver
- uses vclk driver instead of notifier
- cleaned VCLK2 clk flags
- add px_clk gating from DSI driver
- Link to v5: https://lore.kernel.org/r/20230512-amlogic-v6-4-upstream-dsi-ccf-vim3-v5-0-56eb7a4d5b8e at linaro.org

Changes in v5:
- Aded PRIV all the G12 internal clk IDS to simplify public exposing
- Fixed the DSI bindings
- Fixed the DSI HSYNC/VSYNC polarity handling
- Fixed the DSI clock setup
- Fixed the DSI phy timings
- Dropped components for DSI, only keeping it for HDMI
- Added MNT Reform 2 CM4 DT
- Dropped already applied PHY fix
- Link to v4: https://lore.kernel.org/r/20230512-amlogic-v6-4-upstream-dsi-ccf-vim3-v4-0-2592c29ea263 at linaro.org

Changes from v3 at [3]:
- switched all clk setup via CCF
- using single PLL for DSI controller & ENCL encoder
- added ENCL clocks to CCF
- make the VCLK2 clocks configuration by CCF
- fixed probe/bind of DSI controller to work with panels & bridges
- added bit_clk to controller to it can setup the BIT clock aswell
- added fix for components unbind
- added fix for analog phy setup value
- added TS050 timings fix
- dropped previous clk control patch

Changes from v2 at [2]:
- Fixed patch 3
- Added reviews from Jagan
- Rebased on v5.19-rc1

Changes from v1 at [1]:
- 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/20220120083357.1541262-1-narmstrong at baylibre.com
[3] https://lore.kernel.org/r/20220617072723.1742668-1-narmstrong at baylibre.com

---
Neil Armstrong (7):
      dt-bindings: arm: amlogic: Document the MNT Reform 2 CM4 adapter with a BPI-CM4 Module
      clk: meson: add vclk driver
      clk: meson: g12a: make VCLK2 and ENCL clock path configurable by CCF
      drm/meson: gate px_clk when setting rate
      arm64: meson: g12-common: add the MIPI DSI nodes
      arm64: meson: khadas-vim3l: add TS050 DSI panel overlay
      arm64: dts: amlogic: meson-g12b-bananapi-cm4: add support for MNT Reform2 with CM4 adaper

 Documentation/devicetree/bindings/arm/amlogic.yaml |   1 +
 arch/arm64/boot/dts/amlogic/Makefile               |   4 +
 arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi  |  70 ++++
 .../meson-g12b-bananapi-cm4-mnt-reform2.dts        | 384 +++++++++++++++++++++
 .../boot/dts/amlogic/meson-khadas-vim3-ts050.dtso  | 108 ++++++
 drivers/clk/meson/Kconfig                          |   5 +
 drivers/clk/meson/Makefile                         |   1 +
 drivers/clk/meson/g12a.c                           |  72 ++--
 drivers/clk/meson/vclk.c                           | 141 ++++++++
 drivers/clk/meson/vclk.h                           |  51 +++
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c          |   7 +
 11 files changed, 824 insertions(+), 20 deletions(-)
---
base-commit: 23e11d0318521e8693459b0e4d23aec614b3b68b
change-id: 20230512-amlogic-v6-4-upstream-dsi-ccf-vim3-b8e5217e1f4a

Best regards,
-- 
Neil Armstrong <neil.armstrong at linaro.org>



From neil.armstrong at linaro.org  Mon Feb  5 09:55:28 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 05 Feb 2024 18:55:28 +0100
Subject: [PATCH v10 1/7] dt-bindings: arm: amlogic: Document the MNT Reform
 2 CM4 adapter with a BPI-CM4 Module
In-Reply-To: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
References: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
Message-ID: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-1-dc06073d5330@linaro.org>

The MNT Reform 2 CM4 adapter can be populated with any Raspberry Pi CM4
compatible module such as a BPI-CM4 Module, document that.

Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Neil Armstrong <neil.armstrong at linaro.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 caab7ceeda45..2154a4614fda 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -164,6 +164,7 @@ properties:
         items:
           - enum:
               - bananapi,bpi-cm4io
+              - mntre,reform2-cm4
           - const: bananapi,bpi-cm4
           - const: amlogic,a311d
           - const: amlogic,g12b

-- 
2.34.1



From neil.armstrong at linaro.org  Mon Feb  5 09:55:29 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 05 Feb 2024 18:55:29 +0100
Subject: [PATCH v10 2/7] clk: meson: add vclk driver
In-Reply-To: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
References: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
Message-ID: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-2-dc06073d5330@linaro.org>

The VCLK and VCLK_DIV clocks have supplementary bits.

The VCLK gate has a "SOFT RESET" bit to toggle after the whole
VCLK sub-tree rate has been set, this is implemented in
the gate enable callback.

The VCLK_DIV clocks as enable and reset bits used to disable
and reset the divider, associated with CLK_SET_RATE_GATE it ensures
the rate is set while the divider is disabled and in reset mode.

The VCLK_DIV enable bit isn't implemented as a gate since it's part
of the divider logic and vendor does this exact sequence to ensure
the divider is correctly set.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/clk/meson/Kconfig  |   4 ++
 drivers/clk/meson/Makefile |   1 +
 drivers/clk/meson/vclk.c   | 141 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/vclk.h   |  51 ++++++++++++++++
 4 files changed, 197 insertions(+)

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 29ffd14d267b..8a9823789fa3 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -30,6 +30,10 @@ config COMMON_CLK_MESON_VID_PLL_DIV
 	tristate
 	select COMMON_CLK_MESON_REGMAP
 
+config COMMON_CLK_MESON_VCLK
+	tristate
+	select COMMON_CLK_MESON_REGMAP
+
 config COMMON_CLK_MESON_CLKC_UTILS
 	tristate
 
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 9ee4b954c896..9ba43fe7a07a 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -12,6 +12,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_VCLK) += vclk.o
 
 # Amlogic Clock controllers
 
diff --git a/drivers/clk/meson/vclk.c b/drivers/clk/meson/vclk.c
new file mode 100644
index 000000000000..3ea813a0a995
--- /dev/null
+++ b/drivers/clk/meson/vclk.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Neil Armstrong <neil.armstrong at linaro.org>
+ */
+
+#include <linux/module.h>
+#include "vclk.h"
+
+/* The VCLK gate has a supplementary reset bit to pulse after ungating */
+
+static inline struct meson_vclk_gate_data *
+clk_get_meson_vclk_gate_data(struct clk_regmap *clk)
+{
+	return (struct meson_vclk_gate_data *)clk->data;
+}
+
+static int meson_vclk_gate_enable(struct clk_hw *hw)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_vclk_gate_data *vclk = clk_get_meson_vclk_gate_data(clk);
+
+	meson_parm_write(clk->map, &vclk->enable, 1);
+
+	/* Do a reset pulse */
+	meson_parm_write(clk->map, &vclk->reset, 1);
+	meson_parm_write(clk->map, &vclk->reset, 0);
+
+	return 0;
+}
+
+static void meson_vclk_gate_disable(struct clk_hw *hw)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_vclk_gate_data *vclk = clk_get_meson_vclk_gate_data(clk);
+
+	meson_parm_write(clk->map, &vclk->enable, 0);
+}
+
+static int meson_vclk_gate_is_enabled(struct clk_hw *hw)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_vclk_gate_data *vclk = clk_get_meson_vclk_gate_data(clk);
+
+	return meson_parm_read(clk->map, &vclk->enable);
+}
+
+const struct clk_ops meson_vclk_gate_ops = {
+	.enable = meson_vclk_gate_enable,
+	.disable = meson_vclk_gate_disable,
+	.is_enabled = meson_vclk_gate_is_enabled,
+};
+EXPORT_SYMBOL_GPL(meson_vclk_gate_ops);
+
+/* The VCLK Divider has supplementary reset & enable bits */
+
+static inline struct meson_vclk_div_data *
+clk_get_meson_vclk_div_data(struct clk_regmap *clk)
+{
+	return (struct meson_vclk_div_data *)clk->data;
+}
+
+static unsigned long meson_vclk_div_recalc_rate(struct clk_hw *hw,
+						     unsigned long prate)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);
+
+	return divider_recalc_rate(hw, prate, meson_parm_read(clk->map, &vclk->div),
+				   vclk->table, vclk->flags, vclk->div.width);
+}
+
+static int meson_vclk_div_determine_rate(struct clk_hw *hw,
+					      struct clk_rate_request *req)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);
+
+	return divider_determine_rate(hw, req, vclk->table, vclk->div.width,
+				      vclk->flags);
+}
+
+static int meson_vclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long parent_rate)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);
+	int ret;
+
+	ret = divider_get_val(rate, parent_rate, vclk->table, vclk->div.width,
+			      vclk->flags);
+	if (ret < 0)
+		return ret;
+
+	meson_parm_write(clk->map, &vclk->div, ret);
+
+	return 0;
+};
+
+static int meson_vclk_div_enable(struct clk_hw *hw)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);
+
+	/* Unreset the divider when ungating */
+	meson_parm_write(clk->map, &vclk->reset, 0);
+	meson_parm_write(clk->map, &vclk->enable, 1);
+
+	return 0;
+}
+
+static void meson_vclk_div_disable(struct clk_hw *hw)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);
+
+	/* Reset the divider when gating */
+	meson_parm_write(clk->map, &vclk->enable, 0);
+	meson_parm_write(clk->map, &vclk->reset, 1);
+}
+
+static int meson_vclk_div_is_enabled(struct clk_hw *hw)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_vclk_div_data *vclk = clk_get_meson_vclk_div_data(clk);
+
+	return meson_parm_read(clk->map, &vclk->enable);
+}
+
+const struct clk_ops meson_vclk_div_ops = {
+	.recalc_rate = meson_vclk_div_recalc_rate,
+	.determine_rate = meson_vclk_div_determine_rate,
+	.set_rate = meson_vclk_div_set_rate,
+	.enable = meson_vclk_div_enable,
+	.disable = meson_vclk_div_disable,
+	.is_enabled = meson_vclk_div_is_enabled,
+};
+EXPORT_SYMBOL_GPL(meson_vclk_div_ops);
+
+MODULE_DESCRIPTION("Amlogic vclk clock driver");
+MODULE_AUTHOR("Neil Armstrong <neil.armstrong at linaro.org>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/vclk.h b/drivers/clk/meson/vclk.h
new file mode 100644
index 000000000000..20b0b181db09
--- /dev/null
+++ b/drivers/clk/meson/vclk.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2024 Neil Armstrong <neil.armstrong at linaro.org>
+ */
+
+#ifndef __VCLK_H
+#define __VCLK_H
+
+#include "clk-regmap.h"
+#include "parm.h"
+
+/**
+ * struct meson_vclk_gate_data - vclk_gate regmap backed specific data
+ *
+ * @enable:	vclk enable field
+ * @reset:	vclk reset field
+ * @flags:	hardware-specific flags
+ *
+ * Flags:
+ * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored
+ */
+struct meson_vclk_gate_data {
+	struct parm enable;
+	struct parm reset;
+	u8 flags;
+};
+
+extern const struct clk_ops meson_vclk_gate_ops;
+
+/**
+ * struct meson_vclk_div_data - vclk_div regmap back specific data
+ *
+ * @div:	divider field
+ * @enable:	vclk divider enable field
+ * @reset:	vclk divider reset field
+ * @table:	array of value/divider pairs, last entry should have div = 0
+ *
+ * Flags:
+ * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored
+ */
+struct meson_vclk_div_data {
+	struct parm div;
+	struct parm enable;
+	struct parm reset;
+	const struct clk_div_table *table;
+	u8 flags;
+};
+
+extern const struct clk_ops meson_vclk_div_ops;
+
+#endif /* __VCLK_H */

-- 
2.34.1



From neil.armstrong at linaro.org  Mon Feb  5 09:55:30 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 05 Feb 2024 18:55:30 +0100
Subject: [PATCH v10 3/7] clk: meson: g12a: make VCLK2 and ENCL clock path
 configurable by CCF
In-Reply-To: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
References: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
Message-ID: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-3-dc06073d5330@linaro.org>

In order to setup the DSI clock, let's make the unused VCLK2 clock path
configuration via CCF.

The nocache option is removed from following clocks:
- vclk2_sel
- vclk2_input
- vclk2_div
- vclk2
- vclk_div1
- vclk2_div2_en
- vclk2_div4_en
- vclk2_div6_en
- vclk2_div12_en
- vclk2_div2
- vclk2_div4
- vclk2_div6
- vclk2_div12
- cts_encl_sel

vclk2 and vclk2_div uses the newly introduced vclk regmap driver
to handle the enable and reset bits.

In order to set a rate on cts_encl via the vclk2 clock path,
the NO_REPARENT flag is set on cts_encl_sel & vclk2_sel in order
to keep CCF from selection a parent.
The parents of cts_encl_sel & vclk2_sel are expected to be defined
in DT or manually set by the display driver at some point.

The following clock scheme is to be used for DSI:

xtal
\_ gp0_pll_dco
   \_ gp0_pll
      |- vclk2_sel
      |  \_ vclk2_input
      |     \_ vclk2_div
      |        \_ vclk2
      |           \_ vclk2_div1
      |              \_ cts_encl_sel
      |                 \_ cts_encl	-> to VPU LCD Encoder
      |- mipi_dsi_pxclk_sel
      \_ mipi_dsi_pxclk_div
         \_ mipi_dsi_pxclk		-> to DSI controller

The mipi_dsi_pxclk_div is set as bypass with a single /1 entry in div_table
in order to use the same GP0 for mipi_dsi_pxclk and vclk2_input.

The SET_RATE_PARENT is only set on the mipi_dsi_pxclk_sel clock so the
DSI bitclock is the reference base clock to calculate the vclk2_div value
when pixel clock is set on the cts_encl endpoint.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/clk/meson/Kconfig |  1 +
 drivers/clk/meson/g12a.c  | 72 ++++++++++++++++++++++++++++++++++-------------
 2 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 8a9823789fa3..59a40a49f8e1 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -144,6 +144,7 @@ config COMMON_CLK_G12A
 	select COMMON_CLK_MESON_EE_CLKC
 	select COMMON_CLK_MESON_CPU_DYNDIV
 	select COMMON_CLK_MESON_VID_PLL_DIV
+	select COMMON_CLK_MESON_VCLK
 	select MFD_SYSCON
 	help
 	  Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index 90f4c6103014..083882e53b65 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -22,6 +22,7 @@
 #include "clk-regmap.h"
 #include "clk-cpu-dyndiv.h"
 #include "vid-pll-div.h"
+#include "vclk.h"
 #include "meson-eeclk.h"
 #include "g12a.h"
 
@@ -3165,7 +3166,7 @@ static struct clk_regmap g12a_vclk2_sel = {
 		.ops = &clk_regmap_mux_ops,
 		.parent_hws = g12a_vclk_parent_hws,
 		.num_parents = ARRAY_SIZE(g12a_vclk_parent_hws),
-		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+		.flags = CLK_SET_RATE_NO_REPARENT,
 	},
 };
 
@@ -3193,7 +3194,6 @@ static struct clk_regmap g12a_vclk2_input = {
 		.ops = &clk_regmap_gate_ops,
 		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_sel.hw },
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
 	},
 };
 
@@ -3215,19 +3215,32 @@ static struct clk_regmap g12a_vclk_div = {
 };
 
 static struct clk_regmap g12a_vclk2_div = {
-	.data = &(struct clk_regmap_div_data){
-		.offset = HHI_VIID_CLK_DIV,
-		.shift = 0,
-		.width = 8,
+	.data = &(struct meson_vclk_div_data){
+		.div = {
+			.reg_off = HHI_VIID_CLK_DIV,
+			.shift   = 0,
+			.width   = 8,
+		},
+		.enable = {
+			.reg_off = HHI_VIID_CLK_DIV,
+			.shift   = 16,
+			.width   = 1,
+		},
+		.reset = {
+			.reg_off = HHI_VIID_CLK_DIV,
+			.shift   = 17,
+			.width   = 1,
+		},
+		.flags = CLK_DIVIDER_ROUND_CLOSEST,
 	},
 	.hw.init = &(struct clk_init_data){
 		.name = "vclk2_div",
-		.ops = &clk_regmap_divider_ops,
+		.ops = &meson_vclk_div_ops,
 		.parent_hws = (const struct clk_hw *[]) {
 			&g12a_vclk2_input.hw
 		},
 		.num_parents = 1,
-		.flags = CLK_GET_RATE_NOCACHE,
+		.flags = CLK_SET_RATE_GATE,
 	},
 };
 
@@ -3246,16 +3259,24 @@ static struct clk_regmap g12a_vclk = {
 };
 
 static struct clk_regmap g12a_vclk2 = {
-	.data = &(struct clk_regmap_gate_data){
-		.offset = HHI_VIID_CLK_CNTL,
-		.bit_idx = 19,
+	.data = &(struct meson_vclk_gate_data){
+		.enable = {
+			.reg_off = HHI_VIID_CLK_CNTL,
+			.shift   = 19,
+			.width   = 1,
+		},
+		.reset = {
+			.reg_off = HHI_VIID_CLK_CNTL,
+			.shift   = 15,
+			.width   = 1,
+		},
 	},
 	.hw.init = &(struct clk_init_data) {
 		.name = "vclk2",
-		.ops = &clk_regmap_gate_ops,
+		.ops = &meson_vclk_gate_ops,
 		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_div.hw },
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -3339,7 +3360,7 @@ static struct clk_regmap g12a_vclk2_div1 = {
 		.ops = &clk_regmap_gate_ops,
 		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -3353,7 +3374,7 @@ static struct clk_regmap g12a_vclk2_div2_en = {
 		.ops = &clk_regmap_gate_ops,
 		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -3367,7 +3388,7 @@ static struct clk_regmap g12a_vclk2_div4_en = {
 		.ops = &clk_regmap_gate_ops,
 		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -3381,7 +3402,7 @@ static struct clk_regmap g12a_vclk2_div6_en = {
 		.ops = &clk_regmap_gate_ops,
 		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -3395,7 +3416,7 @@ static struct clk_regmap g12a_vclk2_div12_en = {
 		.ops = &clk_regmap_gate_ops,
 		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -3461,6 +3482,7 @@ static struct clk_fixed_factor g12a_vclk2_div2 = {
 			&g12a_vclk2_div2_en.hw
 		},
 		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -3474,6 +3496,7 @@ static struct clk_fixed_factor g12a_vclk2_div4 = {
 			&g12a_vclk2_div4_en.hw
 		},
 		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -3487,6 +3510,7 @@ static struct clk_fixed_factor g12a_vclk2_div6 = {
 			&g12a_vclk2_div6_en.hw
 		},
 		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -3500,6 +3524,7 @@ static struct clk_fixed_factor g12a_vclk2_div12 = {
 			&g12a_vclk2_div12_en.hw
 		},
 		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
 	},
 };
 
@@ -3561,7 +3586,7 @@ static struct clk_regmap g12a_cts_encl_sel = {
 		.ops = &clk_regmap_mux_ops,
 		.parent_hws = g12a_cts_parent_hws,
 		.num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
-		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+		.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
 	},
 };
 
@@ -3717,15 +3742,22 @@ static struct clk_regmap g12a_mipi_dsi_pxclk_sel = {
 		.ops = &clk_regmap_mux_ops,
 		.parent_hws = g12a_mipi_dsi_pxclk_parent_hws,
 		.num_parents = ARRAY_SIZE(g12a_mipi_dsi_pxclk_parent_hws),
-		.flags = CLK_SET_RATE_NO_REPARENT,
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
 	},
 };
 
+/* Force as bypass by forcing a single /1 table entry, and not rely of boot value */
+static const struct clk_div_table g12a_mipi_dsi_pxclk_div_table[] = {
+	{ .val = 0, .div = 1 },
+	{ /* sentinel */ },
+};
+
 static struct clk_regmap g12a_mipi_dsi_pxclk_div = {
 	.data = &(struct clk_regmap_div_data){
 		.offset = HHI_MIPIDSI_PHY_CLK_CNTL,
 		.shift = 0,
 		.width = 7,
+		.table = g12a_mipi_dsi_pxclk_div_table,
 	},
 	.hw.init = &(struct clk_init_data){
 		.name = "mipi_dsi_pxclk_div",

-- 
2.34.1



From neil.armstrong at linaro.org  Mon Feb  5 09:55:31 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 05 Feb 2024 18:55:31 +0100
Subject: [PATCH v10 4/7] drm/meson: gate px_clk when setting rate
In-Reply-To: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
References: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
Message-ID: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-4-dc06073d5330@linaro.org>

Disable the px_clk when setting the rate to recover a fully
configured and correctly reset VCLK clock tree after the rate
is set.

Fixes: 77d9e1e6b846 ("drm/meson: add support for MIPI-DSI transceiver")
Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
index a6bc1bdb3d0d..a10cff3ca1fe 100644
--- a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
+++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
@@ -95,6 +95,7 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
 		return ret;
 	}
 
+	clk_disable_unprepare(mipi_dsi->px_clk);
 	ret = clk_set_rate(mipi_dsi->px_clk, mipi_dsi->mode->clock * 1000);
 
 	if (ret) {
@@ -103,6 +104,12 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
 		return ret;
 	}
 
+	ret = clk_prepare_enable(mipi_dsi->px_clk);
+	if (ret) {
+		dev_err(mipi_dsi->dev, "Failed to enable DSI Pixel clock (ret %d)\n", ret);
+		return ret;
+	}
+
 	switch (mipi_dsi->dsi_device->format) {
 	case MIPI_DSI_FMT_RGB888:
 		dpi_data_format = DPI_COLOR_24BIT;

-- 
2.34.1



From neil.armstrong at linaro.org  Mon Feb  5 09:55:33 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 05 Feb 2024 18:55:33 +0100
Subject: [PATCH v10 6/7] arm64: meson: khadas-vim3l: add TS050 DSI panel
 overlay
In-Reply-To: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
References: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
Message-ID: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-6-dc06073d5330@linaro.org>

This add dtbo overlay to support the Khadas TS050 panel on the
Khadas VIM3 & VIM3L boards.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/boot/dts/amlogic/Makefile               |   3 +
 .../boot/dts/amlogic/meson-khadas-vim3-ts050.dtso  | 108 +++++++++++++++++++++
 2 files changed, 111 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index cc8b34bd583d..5e5ea0f14fe2 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -80,3 +80,6 @@ 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-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air.dtb
+
+# Overlays
+dtb-$(CONFIG_ARCH_MESON) += meson-khadas-vim3-ts050.dtbo
diff --git a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3-ts050.dtso b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3-ts050.dtso
new file mode 100644
index 000000000000..a41b4e619580
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3-ts050.dtso
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/g12a-clkc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/amlogic,meson-g12a-gpio-intc.h>
+
+/dts-v1/;
+/plugin/;
+
+/*
+ * Enable Khadas TS050 DSI Panel + Touch Controller
+ * on Khadas VIM3 (A311D) and VIM3L (S905D3)
+ */
+
+&{/} {
+	panel_backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm_AO_cd 0 25000 0>;
+		brightness-levels = <0 255>;
+		num-interpolated-steps = <255>;
+		default-brightness-level = <200>;
+	};
+};
+
+&i2c3 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	touch-controller at 38 {
+		compatible = "edt,edt-ft5206";
+		reg = <0x38>;
+		interrupt-parent = <&gpio_intc>;
+		interrupts = <IRQID_GPIOA_5 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&gpio_expander 6 GPIO_ACTIVE_LOW>;
+		touchscreen-size-x = <1080>;
+		touchscreen-size-y = <1920>;
+		status = "okay";
+	};
+};
+
+&mipi_dsi {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	assigned-clocks = <&clkc CLKID_GP0_PLL>,
+			  <&clkc CLKID_MIPI_DSI_PXCLK_SEL>,
+			  <&clkc CLKID_MIPI_DSI_PXCLK>,
+			  <&clkc CLKID_CTS_ENCL_SEL>,
+			  <&clkc CLKID_VCLK2_SEL>;
+	assigned-clock-parents = <0>,
+				 <&clkc CLKID_GP0_PLL>,
+				 <0>,
+				 <&clkc CLKID_VCLK2_DIV1>,
+				 <&clkc CLKID_GP0_PLL>;
+	assigned-clock-rates = <960000000>,
+			       <0>,
+			       <960000000>,
+			       <0>,
+			       <0>;
+
+	panel at 0 {
+		compatible = "khadas,ts050";
+		reset-gpios = <&gpio_expander 0 GPIO_ACTIVE_LOW>;
+		enable-gpios = <&gpio_expander 1 GPIO_ACTIVE_HIGH>;
+		power-supply = <&vcc_3v3>;
+		backlight = <&panel_backlight>;
+		reg = <0>;
+
+		port {
+			mipi_in_panel: endpoint {
+				remote-endpoint = <&mipi_out_panel>;
+			};
+		};
+	};
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 1 {
+			mipi_out_panel: endpoint {
+				remote-endpoint = <&mipi_in_panel>;
+			};
+		};
+	};
+};
+
+&mipi_analog_dphy {
+	status = "okay";
+};
+
+&mipi_dphy {
+	status = "okay";
+};
+
+&pwm_AO_cd {
+	pinctrl-0 = <&pwm_ao_c_6_pins>, <&pwm_ao_d_e_pins>;
+};

-- 
2.34.1



From neil.armstrong at linaro.org  Mon Feb  5 09:55:32 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 05 Feb 2024 18:55:32 +0100
Subject: [PATCH v10 5/7] arm64: meson: g12-common: add the MIPI DSI nodes
In-Reply-To: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
References: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
Message-ID: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-5-dc06073d5330@linaro.org>

Add the MIPI DSI Analog & Digital PHY nodes and the DSI control
nodes with proper port endpoint to the VPU.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 70 +++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index ff68b911b729..7300408262d5 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1663,9 +1663,28 @@ pwrc: power-controller {
 								       <250000000>,
 								       <0>; /* Do Nothing */
 					};
+
+					mipi_analog_dphy: phy {
+						compatible = "amlogic,g12a-mipi-dphy-analog";
+						#phy-cells = <0>;
+						status = "disabled";
+					};
 				};
 			};
 
+			mipi_dphy: phy at 44000 {
+				compatible = "amlogic,axg-mipi-dphy";
+				reg = <0x0 0x44000 0x0 0x2000>;
+				clocks = <&clkc CLKID_MIPI_DSI_PHY>;
+				clock-names = "pclk";
+				resets = <&reset RESET_MIPI_DSI_PHY>;
+				reset-names = "phy";
+				phys = <&mipi_analog_dphy>;
+				phy-names = "analog";
+				#phy-cells = <0>;
+				status = "disabled";
+			};
+
 			usb3_pcie_phy: phy at 46000 {
 				compatible = "amlogic,g12a-usb3-pcie-phy";
 				reg = <0x0 0x46000 0x0 0x2000>;
@@ -2152,6 +2171,15 @@ hdmi_tx_out: endpoint {
 					remote-endpoint = <&hdmi_tx_in>;
 				};
 			};
+
+			/* DPI output port */
+			dpi_port: port at 2 {
+				reg = <2>;
+
+				dpi_out: endpoint {
+					remote-endpoint = <&mipi_dsi_in>;
+				};
+			};
 		};
 
 		gic: interrupt-controller at ffc01000 {
@@ -2189,6 +2217,48 @@ gpio_intc: interrupt-controller at f080 {
 				amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>;
 			};
 
+			mipi_dsi: dsi at 7000 {
+				compatible = "amlogic,meson-g12a-dw-mipi-dsi";
+				reg = <0x0 0x7000 0x0 0x1000>;
+				resets = <&reset RESET_MIPI_DSI_HOST>;
+				reset-names = "top";
+				clocks = <&clkc CLKID_MIPI_DSI_HOST>,
+					 <&clkc CLKID_MIPI_DSI_PXCLK>,
+					 <&clkc CLKID_CTS_ENCL>;
+				clock-names = "pclk", "bit", "px";
+				phys = <&mipi_dphy>;
+				phy-names = "dphy";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+
+				assigned-clocks = <&clkc CLKID_MIPI_DSI_PXCLK_SEL>,
+					 <&clkc CLKID_CTS_ENCL_SEL>,
+					 <&clkc CLKID_VCLK2_SEL>;
+				assigned-clock-parents = <&clkc CLKID_GP0_PLL>,
+					 <&clkc CLKID_VCLK2_DIV1>,
+					 <&clkc CLKID_GP0_PLL>;
+
+				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>;
+					};
+				};
+			};
+
 			watchdog: watchdog at f0d0 {
 				compatible = "amlogic,meson-gxbb-wdt";
 				reg = <0x0 0xf0d0 0x0 0x10>;

-- 
2.34.1



From neil.armstrong at linaro.org  Mon Feb  5 09:55:34 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 05 Feb 2024 18:55:34 +0100
Subject: [PATCH v10 7/7] arm64: dts: amlogic: meson-g12b-bananapi-cm4: add
 support for MNT Reform2 with CM4 adaper
In-Reply-To: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
References: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org>
Message-ID: <20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-7-dc06073d5330@linaro.org>

This adds a basic devicetree for the MNT Reform2 DIY laptop when using a
CM4 adapter and a BPI-CM4 module.

Co-developed-by: Lukas F. Hartmann <lukas at mntre.com>
Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/boot/dts/amlogic/Makefile               |   1 +
 .../meson-g12b-bananapi-cm4-mnt-reform2.dts        | 384 +++++++++++++++++++++
 2 files changed, 385 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 5e5ea0f14fe2..0d819a63b15e 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -15,6 +15,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-bananapi-m2s.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12b-bananapi-cm4-cm4io.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-bananapi-cm4-mnt-reform2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gsking-x.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking-pro.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dts
new file mode 100644
index 000000000000..003efed529ba
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dts
@@ -0,0 +1,384 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Neil Armstrong <neil.armstrong at linaro.org>
+ * Copyright 2023 MNT Research GmbH
+ */
+
+/dts-v1/;
+
+#include "meson-g12b-bananapi-cm4.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	model = "MNT Reform 2 with BPI-CM4 Module";
+	compatible = "mntre,reform2-cm4", "bananapi,bpi-cm4", "amlogic,a311d", "amlogic,g12b";
+	chassis-type = "laptop";
+
+	aliases {
+		ethernet0 = &ethmac;
+		i2c0 = &i2c1;
+		i2c1 = &i2c3;
+	};
+
+	hdmi_connector: hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-blue {
+			color = <LED_COLOR_ID_BLUE>;
+			function = LED_FUNCTION_STATUS;
+			gpios = <&gpio_ao GPIOAO_7 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		led-green {
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_STATUS;
+			gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "MNT-REFORM2-BPI-CM4";
+		audio-widgets = "Headphone", "Headphone Jack",
+				"Speaker", "External Speaker",
+				"Microphone", "Mic Jack";
+		audio-aux-devs = <&tdmout_a>, <&tdmout_b>, <&tdmin_b>;
+		audio-routing =	"TDMOUT_A IN 0", "FRDDR_A OUT 0",
+				"TDMOUT_A IN 1", "FRDDR_B OUT 0",
+				"TDMOUT_A IN 2", "FRDDR_C OUT 0",
+				"TDM_A Playback", "TDMOUT_A OUT",
+				"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",
+				"TDMIN_B IN 1", "TDM_B Capture",
+				"TDMIN_B IN 4", "TDM_B Loopback",
+				"TODDR_A IN 1", "TDMIN_B OUT",
+				"TODDR_B IN 1", "TDMIN_B OUT",
+				"TODDR_C IN 1", "TDMIN_B OUT",
+				"Headphone Jack", "HP_L",
+				"Headphone Jack", "HP_R",
+				"External Speaker", "SPK_LP",
+				"External Speaker", "SPK_LN",
+				"External Speaker", "SPK_RP",
+				"External Speaker", "SPK_RN",
+				"LINPUT1", "Mic Jack",
+				"Mic Jack", "MICB";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+					<&clkc CLKID_MPLL0>,
+					<&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		dai-link-3 {
+			sound-dai = <&toddr_a>;
+		};
+
+		dai-link-4 {
+			sound-dai = <&toddr_b>;
+		};
+
+		dai-link-5 {
+			sound-dai = <&toddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-6 {
+			sound-dai = <&tdmif_a>;
+			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_A>;
+			};
+		};
+
+		/* Analog Audio */
+		dai-link-7 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&wm8960>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-8 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+
+	reg_main_1v8: regulator-main-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&reg_main_3v3>;
+	};
+
+	reg_main_1v2: regulator-main-1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "1V2";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		vin-supply = <&reg_main_5v>;
+	};
+
+	reg_main_3v3: regulator-main-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_main_5v: regulator-main-5v {
+		compatible = "regulator-fixed";
+		regulator-name = "5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	reg_main_usb: regulator-main-usb {
+		compatible = "regulator-fixed";
+		regulator-name = "USB_PWR";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&reg_main_5v>;
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm_AO_ab 0 10000 0>;
+		power-supply = <&reg_main_usb>;
+		enable-gpios = <&gpio 58 GPIO_ACTIVE_HIGH>;
+		brightness-levels = <0 32 64 128 160 200 255>;
+		default-brightness-level = <6>;
+	};
+
+	panel {
+		compatible = "innolux,n125hce-gn1";
+		power-supply = <&reg_main_3v3>;
+		backlight = <&backlight>;
+		no-hpd;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&edp_bridge_out>;
+			};
+		};
+	};
+
+	clock_12288: clock_12288 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12288000>;
+	};
+};
+
+&mipi_analog_dphy {
+	status = "okay";
+};
+
+&mipi_dphy {
+	status = "okay";
+};
+
+&mipi_dsi {
+	status = "okay";
+
+	assigned-clocks = <&clkc CLKID_GP0_PLL>,
+			  <&clkc CLKID_MIPI_DSI_PXCLK_SEL>,
+			  <&clkc CLKID_MIPI_DSI_PXCLK>,
+			  <&clkc CLKID_CTS_ENCL_SEL>,
+			  <&clkc CLKID_VCLK2_SEL>;
+	assigned-clock-parents = <0>,
+				 <&clkc CLKID_GP0_PLL>,
+				 <0>,
+				 <&clkc CLKID_VCLK2_DIV1>,
+				 <&clkc CLKID_GP0_PLL>;
+	assigned-clock-rates = <936000000>,
+			       <0>,
+			       <936000000>,
+			       <0>,
+			       <0>;
+};
+
+&mipi_dsi_panel_port {
+	mipi_dsi_out: endpoint {
+		remote-endpoint = <&edp_bridge_in>;
+	};
+};
+
+&cecb_AO {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+};
+
+&hdmi_tx {
+	status = "okay";
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
+&pwm_AO_ab {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm_ao_a_pins>;
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+};
+
+&i2c3 {
+	status = "okay";
+
+	edp_bridge: bridge at 2c {
+		compatible = "ti,sn65dsi86";
+		reg = <0x2c>;
+		enable-gpios = <&gpio GPIOX_10 GPIO_ACTIVE_HIGH>; // PIN_24 / GPIO8
+		vccio-supply = <&reg_main_1v8>;
+		vpll-supply = <&reg_main_1v8>;
+		vcca-supply = <&reg_main_1v2>;
+		vcc-supply = <&reg_main_1v2>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				edp_bridge_in: endpoint {
+					remote-endpoint = <&mipi_dsi_out>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				edp_bridge_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
+			};
+		};
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	wm8960: codec at 1a {
+		compatible = "wlf,wm8960";
+		reg = <0x1a>;
+		clocks = <&clock_12288>;
+		clock-names = "mclk";
+		#sound-dai-cells = <0>;
+		wlf,shared-lrclk;
+	};
+
+	rtc at 68 {
+		compatible = "nxp,pcf8523";
+		reg = <0x68>;
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&sd_emmc_b {
+	status = "okay";
+};
+
+&tdmif_a {
+	status = "okay";
+};
+
+&tdmout_a {
+	status = "okay";
+};
+
+&tdmif_b {
+	pinctrl-0 = <&tdm_b_dout0_pins>, <&tdm_b_fs_pins>, <&tdm_b_sclk_pins>, <&tdm_b_din1_pins>;
+	pinctrl-names = "default";
+
+	assigned-clocks = <&clkc_audio AUD_CLKID_TDM_SCLK_PAD1>,
+			  <&clkc_audio AUD_CLKID_TDM_LRCLK_PAD1>;
+	assigned-clock-parents = <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+				 <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
+	assigned-clock-rates = <0>, <0>;
+};
+
+&tdmin_b {
+	status = "okay";
+};
+
+&toddr_a {
+	status = "okay";
+};
+
+&toddr_b {
+	status = "okay";
+};
+
+&toddr_c {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
+
+&usb {
+	dr_mode = "host";
+
+	status = "okay";
+};

-- 
2.34.1



From jernej.skrabec at gmail.com  Mon Feb  5 09:56:09 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 18:56:09 +0100
Subject: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>
Message-ID: <4543794.LvFx2qVVIh@jernej-laptop>

Dne ponedeljek, 05. februar 2024 ob 16:22:26 CET je Frank Oltmanns napisal(a):
> According to the Allwinner User Manual, the Allwinner A64 requires
> PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.
> 
> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> ---
>  drivers/clk/sunxi-ng/ccu_nkm.c | 13 +++++++++++++
>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index 1168d894d636..7d135908d6e0 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -181,6 +181,12 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
>  	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
>  		rate *= nkm->fixed_post_div;
>  
> +	if (nkm->min_rate && rate < nkm->min_rate)
> +		rate = nkm->min_rate;
> +
> +	if (nkm->max_rate && rate > nkm->max_rate)
> +		rate = nkm->max_rate;

Please take a look at ccu_nm_round_rate() code. You need to consider postdiv
and you can return immediately.

> +
>  	if (!clk_hw_can_set_rate_parent(&nkm->common.hw))
>  		rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm->common);
>  	else
> @@ -220,6 +226,13 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
>  	_nkm.min_m = 1;
>  	_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
>  
> +
> +	if (nkm->min_rate && rate < nkm->min_rate)
> +		rate = nkm->min_rate;
> +
> +	if (nkm->max_rate && rate > nkm->max_rate)
> +		rate = nkm->max_rate;
> +

No need for this, clk subsystem calls round rate before setting actual clock
rate.

Best regards,
Jernej

>  	ccu_nkm_find_best(parent_rate, rate, &_nkm, &nkm->common);
>  
>  	spin_lock_irqsave(nkm->common.lock, flags);
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
> index c409212ee40e..358a9df6b6a0 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> @@ -27,6 +27,8 @@ struct ccu_nkm {
>  	struct ccu_mux_internal	mux;
>  
>  	unsigned int		fixed_post_div;
> +	unsigned long		min_rate;
> +	unsigned long		max_rate;
>  	unsigned long		max_m_n_ratio;
>  	unsigned long		min_parent_m_ratio;
>  
> 
> 






From jernej.skrabec at gmail.com  Mon Feb  5 09:57:55 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 18:57:55 +0100
Subject: [PATCH v2 4/6] clk: sunxi-ng: a64: Set minimum and maximum rate for
 PLL-MIPI
In-Reply-To: <20240205-pinephone-pll-fixes-v2-4-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-4-96a46a2d8c9b@oltmanns.dev>
Message-ID: <1877423.tdWV9SEqCh@jernej-laptop>

Dne ponedeljek, 05. februar 2024 ob 16:22:27 CET je Frank Oltmanns napisal(a):
> Set the minimum and maximum rate of Allwinner A64's PLL-MIPI according
> to the Allwinner User Manual.
> 
> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej





From jernej.skrabec at gmail.com  Mon Feb  5 09:59:11 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 18:59:11 +0100
Subject: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher clock rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-5-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-5-96a46a2d8c9b@oltmanns.dev>
Message-ID: <13445659.uLZWGnKmhe@jernej-laptop>

Dne ponedeljek, 05. februar 2024 ob 16:22:28 CET je Frank Oltmanns napisal(a):
> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
> The SOC requires pll-mipi to run at more than 500 MHz.
> 
> This is the relevant clock tree:
>  pll-mipi
>     tcon0
>        tcon-data-clock
> 
> tcon-data-clock has to run at 1/4 the DSI per-lane bit rate. The XBD599
> has 24 bpp and 4 lanes. Therefore, the resulting requested
> tcon-data-clock rate is:
>     crtc_clock * 1000 * (24 / 4) / 4
> 
> tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it requests a
> parent rate of
>     4 * (crtc_clock * 1000 * (24 / 4) / 4)
> 
> Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate of pll-mipi.
> 
> pll-mipi's constraint to run at 500MHz or higher forces us to have a
> crtc_clock >= 83333 kHz if we want a 60 Hz vertical refresh rate.
> 
> Change [hv]sync_(start|end) so that we reach a clock rate of 83502 kHz
> so that it is high enough to align with pll-pipi limits.

Typo: pll-pipi -> pll-mipi

Best regards,
Jernej

> 
> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> ---
>  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> index b55bafd1a8be..6886fd7f765e 100644
> --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
> @@ -320,14 +320,14 @@ static int xbd599_init_sequence(struct st7703 *ctx)
>  
>  static const struct drm_display_mode xbd599_mode = {
>  	.hdisplay    = 720,
> -	.hsync_start = 720 + 40,
> -	.hsync_end   = 720 + 40 + 40,
> -	.htotal	     = 720 + 40 + 40 + 40,
> +	.hsync_start = 720 + 65,
> +	.hsync_end   = 720 + 65 + 65,
> +	.htotal      = 720 + 65 + 65 + 65,
>  	.vdisplay    = 1440,
> -	.vsync_start = 1440 + 18,
> -	.vsync_end   = 1440 + 18 + 10,
> -	.vtotal	     = 1440 + 18 + 10 + 17,
> -	.clock	     = 69000,
> +	.vsync_start = 1440 + 30,
> +	.vsync_end   = 1440 + 30 + 22,
> +	.vtotal	     = 1440 + 30 + 22 + 29,
> +	.clock	     = (720 + 65 + 65 + 65) * (1440 + 30 + 22 + 29) * 60 / 1000,
>  	.flags	     = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
>  	.width_mm    = 68,
>  	.height_mm   = 136,
> 
> 






From eballetb at redhat.com  Mon Feb  5 09:58:26 2024
From: eballetb at redhat.com (Enric Balletbo i Serra)
Date: Mon, 5 Feb 2024 18:58:26 +0100
Subject: [RESEND PATCH v2] arm64: dts: ti: k3-am69-sk: remove
 assigned-clock-parents for unused VP
In-Reply-To: <92d7de31-2c14-469d-8da8-11bb70ea2707@ti.com>
References: <20240201142308.4954-1-j-choudhary@ti.com> <92d7de31-2c14-469d-8da8-11bb70ea2707@ti.com>
Message-ID: <CALE0LRuTL8wOAG465-63JsUrXT6e=aBfGt48LNco+tKWTY5FHA@mail.gmail.com>

Hi Jayesh,

Many thanks for the patch.

On Fri, Feb 2, 2024 at 6:17?AM Aradhya Bhatia <a-bhatia1 at ti.com> wrote:
>
>
>
> On 01-Feb-24 19:53, Jayesh Choudhary wrote:
> > VP2 and VP3 are unused video ports and VP3 share the same parent
> > clock as VP1 causing issue with pixel clock setting for HDMI (VP1).
> > The current DM firmware does not support changing parent clock if it
> > is shared by another component. It returns 0 for the determine_rate
> > query before causing set_rate to set the clock at default maximum of
> > 1.8GHz which is a lot more than the maximum frequency videoports can
> > support (600MHz) causing SYNC LOST issues.
> > So remove the parent clocks for unused VPs to avoid conflict.
> >
> > Fixes: 6f8605fd7d11 ("arm64: dts: ti: k3-am69-sk: Add DP and HDMI support")
> > Reported-by: Nishanth Menon <nm at ti.com>
> > Signed-off-by: Jayesh Choudhary <j-choudhary at ti.com>
> > Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>
> Reviewed-by: Aradhya Bhatia <a-bhatia1 at ti.com>
>

This patch fixes the issue I see on my AM69-SK board and after
applying it  the HDMI of the board works again so

Tested-by: Enric Balletbo i Serra <eballetbo at redhat.com>

> Regards
> Aradhya
>
> > ---
> >
> > v1: <https://lore.kernel.org/all/20231221113042.48492-1-j-choudhary at ti.com/>
> >
> > Changelog v1->v2:
> > - Updated commit message
> > - Picked up Tomi's R-by from v1
> > - Removed "Closes:" link since its invalid now
> >
> > (NOTE: Sending again as forgot to put mailing list in cc earlier)
> >
> >  arch/arm64/boot/dts/ti/k3-am69-sk.dts | 8 ++------
> >  1 file changed, 2 insertions(+), 6 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> > index 8da591579868..370980eb59b0 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> > +++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> > @@ -918,13 +918,9 @@ &dss {
> >       pinctrl-names = "default";
> >       pinctrl-0 = <&dss_vout0_pins_default>;
> >       assigned-clocks = <&k3_clks 218 2>,
> > -                       <&k3_clks 218 5>,
> > -                       <&k3_clks 218 14>,
> > -                       <&k3_clks 218 18>;
> > +                       <&k3_clks 218 5>;
> >       assigned-clock-parents = <&k3_clks 218 3>,
> > -                              <&k3_clks 218 7>,
> > -                              <&k3_clks 218 16>,
> > -                              <&k3_clks 218 22>;
> > +                              <&k3_clks 218 7>;
> >  };
> >
> >  &serdes_wiz4 {
>



From robin.murphy at arm.com  Mon Feb  5 10:03:53 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 5 Feb 2024 18:03:53 +0000
Subject: [PATCH 05/12] bcm2835-dma: Derive slave DMA addresses correctly
In-Reply-To: <30da53ebdf43b712da790fd2ae0f0040f71762b8.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
 <30da53ebdf43b712da790fd2ae0f0040f71762b8.1706948717.git.andrea.porta@suse.com>
Message-ID: <ee19a95d-fe1e-4f3f-bc81-bdef38475469@arm.com>

On 2024-02-04 6:59 am, Andrea della Porta wrote:
> From: Phil Elwell <phil at raspberrypi.com>
> 
> Slave addresses for DMA are meant to be supplied as physical addresses
> (contrary to what struct snd_dmaengine_dai_dma_data does). It is up to
> the DMA controller driver to perform the translation based on its own
> view of the world, as described in Device Tree.
> 
> Now that the Pi Device Trees have the correct peripheral mappings,
> replace the hacky address munging with phys_to_dma().
> 
> Signed-off-by: Phil Elwell <phil at raspberrypi.com>
> ---
>   drivers/dma/bcm2835-dma.c | 23 +++++------------------
>   1 file changed, 5 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> index 237dcdb8d726..077812eda609 100644
> --- a/drivers/dma/bcm2835-dma.c
> +++ b/drivers/dma/bcm2835-dma.c
> @@ -18,6 +18,7 @@
>    *	Copyright 2012 Marvell International Ltd.
>    */
>   #include <linux/dmaengine.h>
> +#include <linux/dma-direct.h>

Please read the comment at the top of that file; this driver is 
definitely not a DMA API implementation, and should not be including it.

>   #include <linux/dma-mapping.h>
>   #include <linux/dmapool.h>
>   #include <linux/err.h>
> @@ -980,22 +981,12 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
>   	if (direction == DMA_DEV_TO_MEM) {
>   		if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
>   			return NULL;
> -		src = c->cfg.src_addr;
> -		/*
> -		 * One would think it ought to be possible to get the physical
> -		 * to dma address mapping information from the dma-ranges DT
> -		 * property, but I've not found a way yet that doesn't involve
> -		 * open-coding the whole thing.
> -		 */
> -		if (c->is_40bit_channel)
> -			src |= 0x400000000ull;
> +		src = phys_to_dma(chan->device->dev, c->cfg.src_addr);

FWIW I'd argue that abusing DMA API internals like this is even more 
hacky than bypassing it entirely. The appropriate public API for setting 
up the device end of a transfer is dma_map_resource(). Now, it *is* the 
case currently that the dma-direct implementation of that does not take 
dma_range_map into account, but that's already an open question:

https://lore.kernel.org/linux-iommu/20220610080802.11147-1-Sergey.Semin at baikalelectronics.ru/

Thanks,
Robin.

>   		info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC;
>   	} else {
>   		if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
>   			return NULL;
> -		dst = c->cfg.dst_addr;
> -		if (c->is_40bit_channel)
> -			dst |= 0x400000000ull;
> +		dst = phys_to_dma(chan->device->dev, c->cfg.dst_addr);
>   		info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
>   	}
>   
> @@ -1064,17 +1055,13 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
>   	if (direction == DMA_DEV_TO_MEM) {
>   		if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
>   			return NULL;
> -		src = c->cfg.src_addr;
> -		if (c->is_40bit_channel)
> -			src |= 0x400000000ull;
> +		src = phys_to_dma(chan->device->dev, c->cfg.src_addr);
>   		dst = buf_addr;
>   		info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC;
>   	} else {
>   		if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
>   			return NULL;
> -		dst = c->cfg.dst_addr;
> -		if (c->is_40bit_channel)
> -			dst |= 0x400000000ull;
> +		dst = phys_to_dma(chan->device->dev, c->cfg.dst_addr);
>   		src = buf_addr;
>   		info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
>   


From william.zhang at broadcom.com  Mon Feb  5 10:05:14 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Mon, 5 Feb 2024 10:05:14 -0800
Subject: [PATCH v4 03/12] dt-bindings: mtd: brcmnand: Add ecc strap
 property
In-Reply-To: <20240205142639.5d7c70f0@xps-13>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
 <20240203002834.171462-4-william.zhang@broadcom.com>
 <20240203-expenses-tarmac-c564bc7ae34f@spud> <20240205142639.5d7c70f0@xps-13>
Message-ID: <ce15922e-4292-41d6-8c5f-2b4fbfa83d5c@broadcom.com>

Hi Miquel,

On 2/5/24 05:26, Miquel Raynal wrote:
> Hi,
> 
> conor at kernel.org wrote on Sat, 3 Feb 2024 14:49:50 +0000:
> 
>> On Fri, Feb 02, 2024 at 04:28:24PM -0800, William Zhang wrote:
>>> Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
>>> board boot strap for broadband board designs because they do not specify
>>> ecc setting in dts but rather using the strap setting.
>>>
>>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>>>
>>> ---
>>>
>>> Changes in v4:
>>> - Move ecc strap property to this separate patch and remove some
>>> non-binding related text from the description
>>>
>>> Changes in v3: None
>>> Changes in v2: None
>>>
>>>   Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 8 ++++++++
>>>   1 file changed, 8 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>>> index d0168d55c73e..2599d902ec3a 100644
>>> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>>> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>>> @@ -147,6 +147,14 @@ patternProperties:
>>>             layout.
>>>           $ref: /schemas/types.yaml#/definitions/uint32
>>>   
>>> +      brcm,nand-ecc-use-strap:
>>> +        description:
>>> +          This flag indicates the ecc strength and spare area size should
>>> +          be retrieved from the SoC NAND boot strap setting instead of
>>> +          nand-ecc-strength and brcm,nand-oob-sector-size or auto detection.
>>
>> I'm still on the fence about this being overly prescriptive about the
>> operating systems behaviour. I think it would be good to say why the
>> strap values are better than those explicitly provided in DT rather than
>> just saying "these strap values should be used".
> 
> I don't know if there is a point is saying why they would be better, as
> they are not. It is a -questionable- design choice. However I would
> just get rid of any mention to other properties. Just say one should
> expect the strap value to be read and applied by the system when this
> property is present.
> 
Agree we don't need to say which is better as it is just a design 
choice. And it is used by all BCMBCA internal ref boards and customer 
designs. But if we just say strap value is read and applied, it is vague 
and nobody would know what is applied.  I replied this email yesterday 
and suggest the followings:

This property provides a choice for retrieving ecc strength and spare 
area size from the SoC NAND boot strap setting. It is commonly used by 
the BCMBCA SoC board design.

Hope this make everyone happy and we can move forward.


>>> +          This is commonly used by the BCMBCA SoC board design.
>>> +        $ref: /schemas/types.yaml#/definitions/flag
>>> +
>>>       unevaluatedProperties: false
>>>   
>>>   allOf:
>>> -- 
>>> 2.37.3
>>>    
> 
> 
> Thanks,
> Miqu?l
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240205/63ed6dea/attachment-0001.p7s>

From william.zhang at broadcom.com  Mon Feb  5 10:06:23 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Mon, 5 Feb 2024 10:06:23 -0800
Subject: [PATCH v4 02/12] dt-bindings: mtd: brcmnand: Add WP pin
 connection property
In-Reply-To: <20240205143246.52ee97ec@xps-13>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
 <20240203002834.171462-3-william.zhang@broadcom.com>
 <20240205143246.52ee97ec@xps-13>
Message-ID: <ee201484-78b4-4c7a-97ad-e5dea0748b04@broadcom.com>



On 2/5/24 05:32, Miquel Raynal wrote:
> Hi William,
> 
> william.zhang at broadcom.com wrote on Fri,  2 Feb 2024 16:28:23 -0800:
> 
>> Add brcm,wp-not-connected property to have an option for disabling this
>> feature on broadband board design that does not connect WP pin.
>>
>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>>
>> ---
>>
>> Changes in v4:
>> - Move the WP pin property to this separate patch and change it to
>> boolean type.
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>>   Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 8 ++++++++
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>> index e54ca08a798a..d0168d55c73e 100644
>> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>> @@ -113,6 +113,14 @@ properties:
>>         earlier versions of this core that include WP
>>       type: boolean
>>   
>> +  brcm,wp-not-connected:
>> +    description:
>> +      Use this property when board design does not connect controller's
>> +      NAND_WPb pin to NAND chip's WP_L pin and disable the write
>> +      protection feature. By default, controller assumes the pin is
>> +      connected and feature is used.
> 
> I would rephrase slightly. What about:
> 
> 	 WP pin is not physically wired to the NAND chip. Write
> 	 protection feature cannot be used.
>   
That's fine with me.  Will update.

>> +    $ref: /schemas/types.yaml#/definitions/flag
>> +
>>   patternProperties:
>>     "^nand@[a-f0-9]$":
>>       type: object
> 
> 
> Thanks,
> Miqu?l
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240205/aba9f52f/attachment.p7s>

From jernej.skrabec at gmail.com  Mon Feb  5 10:12:45 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 19:12:45 +0100
Subject: [PATCH 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC support
In-Reply-To: <20240204094404.149776-4-andre.przywara@arm.com>
References: <20240204094404.149776-1-andre.przywara@arm.com>
 <20240204094404.149776-4-andre.przywara@arm.com>
Message-ID: <3280179.44csPzL39Z@jernej-laptop>

Hi Andre!

Dne nedelja, 04. februar 2024 ob 10:44:04 CET je Andre Przywara napisal(a):
> The Remix Mini PC is a "mini computer" using the Allwinner H64 SoC,
> which appears to be just a relabelled A64. It was launched in 2015 by
> the now defunct company Jide, and shipped with a desktop optimised
> version of Android. It features
> 	- Allwinner H64 Soc (4 * Arm Cortex-A53 cores)
> 	- 1 or 2 GB DRAM
> 	- 8 or 16 GB eMMC flash
> 	- 100 MBit Ethernet port (using an X-Powers AC200 PHY)
> 	- RTL8723BS WiFi & Bluetooth chip
> 	- HDMI port
> 	- two USB 2.0 ports
> 	- 3.5mm AV port
> 	- microSD card slot
> 
> The devicetree covers most peripherals, though there is no agreed
> binding for the PHY chip yet, so this is left out.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
>  .../allwinner/sun50i-h64-remix-mini-pc.dts    | 357 ++++++++++++++++++
>  2 files changed, 358 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> 
> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> index 91d505b385de..2db3b15ad09f 100644
> --- a/arch/arm64/boot/dts/allwinner/Makefile
> +++ b/arch/arm64/boot/dts/allwinner/Makefile
> @@ -16,6 +16,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab-early-adopter.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> new file mode 100644
> index 000000000000..537923a541a8
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> @@ -0,0 +1,357 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +// Copyright (c) 2018 ARM Ltd.

Shouldn't be 2024?

> +
> +/dts-v1/;
> +
> +#include "sun50i-a64.dtsi"
> +#include "sun50i-a64-cpu-opp.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +
> +/ {
> +	model = "Remix Mini PC";
> +	compatible = "jide,remix-mini-pc", "allwinner,sun50i-h64",
> +		     "allwinner,sun50i-a64";
> +
> +	aliases {
> +		ethernet1 = &rtl8723bs;
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	hdmi-connector {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_con_in: endpoint {
> +				remote-endpoint = <&hdmi_out_con>;
> +			};
> +		};
> +	};
> +
> +	reg_vcc5v: regulator-5v {
> +		/* board wide 5V supply directly from the DC input */
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc-5v";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-always-on;
> +	};
> +
> +	wifi_pwrseq: wifi_pwrseq {
> +		compatible = "mmc-pwrseq-simple";
> +		pinctrl-names = "default";
> +		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
> +		post-power-on-delay-ms = <200>;
> +	};
> +};
> +
> +&codec {
> +	status = "okay";
> +};
> +
> +&codec_analog {
> +	cpvdd-supply = <&reg_eldo1>;
> +	status = "okay";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
> +&cpu1 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
> +&cpu2 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
> +&cpu3 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
> +&dai {
> +	status = "okay";
> +};
> +
> +&de {
> +	status = "okay";
> +};
> +
> +&ehci0 {
> +	status = "okay";
> +};
> +
> +&ehci1 {
> +	status = "okay";
> +};
> +
> +&hdmi {
> +	hvcc-supply = <&reg_dldo1>;
> +	status = "okay";
> +};
> +
> +&hdmi_out {
> +	hdmi_out_con: endpoint {
> +		remote-endpoint = <&hdmi_con_in>;
> +	};
> +};
> +
> +/* Connects to the AC200 chip */
> +&i2c0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c0_pins>;
> +	status = "okay";
> +};
> +
> +&i2c0_pins {
> +	bias-pull-up;
> +};
> +
> +&mmc0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc0_pins>;
> +	vmmc-supply = <&reg_dcdc1>;
> +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
> +	disable-wp;
> +	bus-width = <4>;
> +	status = "okay";
> +};
> +
> +&mmc1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc1_pins>;
> +	vmmc-supply = <&reg_aldo1>;
> +	vqmmc-supply = <&reg_dldo4>;
> +	mmc-pwrseq = <&wifi_pwrseq>;
> +	bus-width = <4>;
> +	non-removable;
> +	status = "okay";
> +
> +	rtl8723bs: wifi at 1 {
> +		reg = <1>;
> +		interrupt-parent = <&r_pio>;
> +		interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
> +		interrupt-names = "host-wake";
> +	};

Node without compatible doesn't help. Please remove it.

> +};
> +
> +&mmc2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
> +	vmmc-supply = <&reg_dcdc1>;
> +	vqmmc-supply = <&reg_eldo1>;
> +	bus-width = <8>;
> +	non-removable;
> +	mmc-ddr-1_8v;
> +	mmc-hs200-1_8v;

Aren't these speed modes enabled by default?


Best regards,
Jernej

> +	cap-mmc-hw-reset;
> +	status = "okay";
> +};
> +
> +&ohci0 {
> +	status = "okay";
> +};
> +
> +&ohci1 {
> +	status = "okay";
> +};
> +
> +&pio {
> +	vcc-pb-supply = <&reg_dcdc1>;
> +	vcc-pc-supply = <&reg_dcdc1>;
> +	vcc-pd-supply = <&reg_dcdc1>;
> +	vcc-pe-supply = <&reg_dcdc1>;
> +	vcc-pf-supply = <&reg_dcdc1>;
> +	vcc-pg-supply = <&reg_dldo4>;
> +	vcc-ph-supply = <&reg_dcdc1>;
> +};
> +
> +&r_ir {
> +	status = "okay";
> +};
> +
> +&r_pio {
> +	/*
> +	 * We cannot add that supply for now since it would create a circular
> +	 * dependency between pinctrl, the regulator and the RSB Bus.
> +	 *
> +	 * vcc-pl-supply = <&reg_aldo2>;
> +	 */
> +};
> +
> +&r_rsb {
> +	status = "okay";
> +
> +	axp803: pmic at 3a3 {
> +		compatible = "x-powers,axp803";
> +		reg = <0x3a3>;
> +		interrupt-parent = <&r_intc>;
> +		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
> +		x-powers,drive-vbus-en;
> +
> +		vin1-supply = <&reg_vcc5v>;
> +		vin2-supply = <&reg_vcc5v>;
> +		vin3-supply = <&reg_vcc5v>;
> +		vin5-supply = <&reg_vcc5v>;
> +		vin6-supply = <&reg_vcc5v>;
> +		aldoin-supply = <&reg_vcc5v>;
> +		dldoin-supply = <&reg_vcc5v>;
> +		eldoin-supply = <&reg_vcc5v>;
> +		fldoin-supply = <&reg_vcc5v>;
> +		drivevbus-supply = <&reg_vcc5v>;
> +		ips-supply = <&reg_vcc5v>;
> +
> +		status = "okay";
> +	};
> +};
> +
> +#include "axp803.dtsi"
> +
> +&ac_power_supply {
> +	status = "okay";
> +};
> +
> +&reg_dcdc1 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3300000>;
> +	regulator-max-microvolt = <3300000>;
> +	regulator-name = "vcc-3v3";
> +};
> +
> +&reg_dcdc2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1040000>;
> +	regulator-max-microvolt = <1300000>;
> +	regulator-name = "vdd-cpux";
> +};
> +
> +/* DCDC3 is polyphased with DCDC2 */
> +
> +&reg_dcdc5 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1500000>;
> +	regulator-max-microvolt = <1500000>;
> +	regulator-name = "vcc-dram";
> +};
> +
> +/* Deviates from the reset default of 1.1V. */
> +&reg_dcdc6 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1200000>;
> +	regulator-max-microvolt = <1200000>;
> +	regulator-name = "vdd-sys";
> +};
> +
> +&reg_aldo1 {
> +	regulator-min-microvolt = <3300000>;
> +	regulator-max-microvolt = <3300000>;
> +	regulator-name = "vcc-wifi";
> +};
> +
> +&reg_aldo2 {
> +	/* Specifying R_PIO consumer would create circular dependency. */
> +	regulator-always-on;
> +	regulator-min-microvolt = <3300000>;
> +	regulator-max-microvolt = <3300000>;
> +	regulator-name = "vcc-pl";
> +};
> +
> +&reg_aldo3 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3000000>;
> +	regulator-max-microvolt = <3000000>;
> +	regulator-name = "vcc-pll-avcc";
> +};
> +
> +/* AC200 power supply */
> +&reg_dldo1 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3300000>;
> +	regulator-max-microvolt = <3300000>;
> +	regulator-name = "vcc-ave-33";
> +};
> +
> +&reg_dldo4 {
> +	regulator-min-microvolt = <3300000>;
> +	regulator-max-microvolt = <3300000>;
> +	regulator-name = "vcc-wifi-io";
> +};
> +
> +&reg_drivevbus {
> +	regulator-name = "usb0-vbus";
> +	status = "okay";
> +};
> +
> +&reg_eldo1 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1800000>;
> +	regulator-max-microvolt = <1800000>;
> +	regulator-name = "vcc-cpvdd-dram-emmc";
> +};
> +
> +/* Supplies the arisc management core, needed by TF-A to power off cores. */
> +&reg_fldo2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1100000>;
> +	regulator-max-microvolt = <1100000>;
> +	regulator-name = "vdd-cpus";
> +};
> +
> +&reg_rtc_ldo {
> +	regulator-name = "vcc-rtc";
> +};
> +
> +&simplefb_hdmi {
> +	vcc-hdmi-supply = <&reg_dcdc1>;
> +};
> +
> +&sound {
> +	simple-audio-card,aux-devs = <&codec_analog>;
> +	simple-audio-card,widgets = "Microphone", "Microphone Jack",
> +				    "Headphone", "Headphone Jack";
> +	simple-audio-card,routing =
> +			"Left DAC", "DACL",
> +			"Right DAC", "DACR",
> +			"Headphone Jack", "HP",
> +			"ADCL", "Left ADC",
> +			"ADCR", "Right ADC",
> +			"MIC2", "Microphone Jack";
> +	status = "okay";
> +};
> +
> +/* On the (unpopulated) UART pads. */
> +&uart0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart0_pb_pins>;
> +	status = "okay";
> +};
> +
> +&uart1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
> +	uart-has-rtscts;
> +	status = "okay";
> +
> +	bluetooth {
> +		compatible = "realtek,rtl8723bs-bt";
> +		enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
> +		max-speed = <1500000>;
> +	};
> +};
> +
> +&usb_otg {
> +	dr_mode = "host";
> +	status = "okay";
> +};
> +
> +&usbphy {
> +	usb0_vbus-supply = <&reg_drivevbus>;
> +	usb1_vbus-supply = <&reg_drivevbus>;
> +	status = "okay";
> +};
> 






From jernej.skrabec at gmail.com  Mon Feb  5 10:14:09 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 19:14:09 +0100
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <10412979.nUPlyArG6x@jernej-laptop>

Dne nedelja, 04. februar 2024 ob 16:56:44 CET je Ricardo B. Marliere napisal(a):
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Acked-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  drivers/bus/sunxi-rsb.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
> index fd3e9d82340a..1e29ba76615d 100644
> --- a/drivers/bus/sunxi-rsb.c
> +++ b/drivers/bus/sunxi-rsb.c
> @@ -128,7 +128,7 @@ struct sunxi_rsb {
>  };
>  
>  /* bus / slave device related functions */
> -static struct bus_type sunxi_rsb_bus;
> +static const struct bus_type sunxi_rsb_bus;
>  
>  static int sunxi_rsb_device_match(struct device *dev, struct device_driver *drv)
>  {
> @@ -177,7 +177,7 @@ static int sunxi_rsb_device_modalias(const struct device *dev, struct kobj_ueven
>  	return of_device_uevent_modalias(dev, env);
>  }
>  
> -static struct bus_type sunxi_rsb_bus = {
> +static const struct bus_type sunxi_rsb_bus = {
>  	.name		= RSB_CTRL_NAME,
>  	.match		= sunxi_rsb_device_match,
>  	.probe		= sunxi_rsb_device_probe,
> 
> ---
> base-commit: 38ed19495066966979ba821b9e0f549ad5ea620d
> change-id: 20240204-bus_cleanup-bus-de90b25d7ce6
> 
> Best regards,
> 






From jernej.skrabec at gmail.com  Mon Feb  5 10:19:26 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 19:19:26 +0100
Subject: [PATCH v2 2/2] arm64: dts: allwinner: h618: add BananaPi M4 Berry board
In-Reply-To: <20240204101054.152012-3-andre.przywara@arm.com>
References: <20240204101054.152012-1-andre.przywara@arm.com>
 <20240204101054.152012-3-andre.przywara@arm.com>
Message-ID: <22174359.EfDdHjke4D@jernej-laptop>

Dne nedelja, 04. februar 2024 ob 11:10:54 CET je Andre Przywara napisal(a):
> The BananaPi M4 Berry is a development board using the Allwinner H618
> SoC. It comes with the following specs:
> 	- Allwinner H618 SoC (4 * Arm Cortex-A53 cores, 1MB L2 cache)
> 	- 2 GiB LPDDR4 DRAM
> 	- 8 GiB eMMC flash
> 	- AXP313a PMIC
> 	- Gigabit Ethernet, using RTL8211 PHY
> 	- RTL8821CU USB WiFi chip
> 	- HDMI port
> 	- 4 * USB 2.0 ports, via an on-board hub chip
> 	- microSD card slot
> 	- 3.5mm A/V port
> 	- power supply and USB-OTG via USB-C connector
> 
> Add a devicetree file describing the components that we already have
> bindings for, that excludes audio and video at the moment.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
>  .../sun50i-h618-bananapi-m4-berry.dts         | 223 ++++++++++++++++++
>  2 files changed, 224 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
> 
> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> index 2db3b15ad09f..1c5c204a109b 100644
> --- a/arch/arm64/boot/dts/allwinner/Makefile
> +++ b/arch/arm64/boot/dts/allwinner/Makefile
> @@ -43,5 +43,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-bananapi-m4-berry.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
> new file mode 100644
> index 000000000000..a3f8ff75db42
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
> @@ -0,0 +1,223 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (C) 2023 Arm Ltd.
> + */
> +
> +/dts-v1/;
> +
> +#include "sun50i-h616.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/linux-event-codes.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/leds/common.h>
> +
> +/ {
> +	model = "BananaPi M4 Berry";
> +	compatible = "sinovoip,bananapi-m4-berry", "allwinner,sun50i-h618";
> +
> +	aliases {
> +		ethernet0 = &emac0;
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		led-0 {
> +			function = LED_FUNCTION_STATUS;
> +			color = <LED_COLOR_ID_GREEN>;
> +			gpios = <&pio 2 12 GPIO_ACTIVE_LOW>; /* PC12 */
> +		};
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +
> +		key-sw3 {
> +			label = "sw3";
> +			linux,code = <BTN_0>;
> +			gpios = <&pio 2 7 GPIO_ACTIVE_LOW>;	/* PC7 */
> +		};
> +	};
> +
> +	reg_vcc5v: regulator-5v {
> +		/* board wide 5V supply directly from the USB-C socket */
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc-5v";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-always-on;
> +	};
> +
> +	reg_usb_vbus: regulator-usb-vbus {
> +		/* separate discrete regulator for the USB ports */
> +		compatible = "regulator-fixed";
> +		regulator-name = "usb-vbus";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&reg_vcc5v>;
> +	};
> +
> +	reg_3v3: regulator-3v3 {
> +		/* separate discrete regulator for WiFi and Ethernet PHY */
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc-3v3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&reg_vcc5v>;
> +	};
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
> +/* Connected to an on-board RTL8821CU USB WiFi chip. */
> +&ehci1 {
> +	status = "okay";
> +};
> +
> +/* EHCI2 is on unpopulated pins */
> +
> +/* Connected to an on-board FE1.1s USB hub chip, supplying 4 USB-A ports. */
> +&ehci3 {
> +	status = "okay";
> +};
> +
> +&emac0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&ext_rgmii_pins>;
> +	phy-mode = "rgmii";
> +	phy-handle = <&ext_rgmii_phy>;
> +	phy-supply = <&reg_3v3>;
> +	allwinner,rx-delay-ps = <3100>;
> +	allwinner,tx-delay-ps = <700>;
> +	status = "okay";
> +};
> +
> +&ir {
> +	status = "okay";
> +};
> +
> +&mdio0 {
> +	ext_rgmii_phy: ethernet-phy at 1 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <1>;
> +		reset-gpios = <&pio 8 16 GPIO_ACTIVE_LOW>;	/* PI16 */
> +	};
> +};
> +
> +&mmc0 {
> +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;	/* PF6 */
> +	vmmc-supply = <&reg_dldo1>;
> +	bus-width = <4>;
> +	status = "okay";
> +};
> +
> +&mmc2 {
> +	vmmc-supply = <&reg_dldo1>;
> +	vqmmc-supply = <&reg_aldo1>;
> +	bus-width = <8>;
> +	non-removable;
> +	cap-mmc-hw-reset;
> +	mmc-ddr-1_8v;

This one should be dropped.

Best regards,
Jernej

> +	mmc-hs200-1_8v;
> +	status = "okay";
> +};
> +
> +/* USB ports 1 and 3 connect to onboard devices that are high-speed only. */
> +
> +/* OHCI2 is on unpopulated pins */
> +
> +&pio {
> +	vcc-pc-supply = <&reg_aldo1>;
> +	vcc-pf-supply = <&reg_dldo1>;
> +	vcc-pg-supply = <&reg_dldo1>;
> +	vcc-ph-supply = <&reg_dldo1>;
> +	vcc-pi-supply = <&reg_dldo1>;
> +};
> +
> +&r_i2c {
> +	status = "okay";
> +
> +	axp313: pmic at 36 {
> +		compatible = "x-powers,axp313a";
> +		reg = <0x36>;
> +		#interrupt-cells = <1>;
> +		interrupt-controller;
> +		interrupt-parent = <&pio>;
> +
> +		vin1-supply = <&reg_vcc5v>;
> +		vin2-supply = <&reg_vcc5v>;
> +		vin3-supply = <&reg_vcc5v>;
> +
> +		regulators {
> +			reg_aldo1: aldo1 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-name = "vcc-1v8-pll";
> +			};
> +
> +			reg_dldo1: dldo1 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-name = "vcc-3v3-io";
> +			};
> +
> +			reg_dcdc1: dcdc1 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <810000>;
> +				regulator-max-microvolt = <990000>;
> +				regulator-name = "vdd-gpu-sys";
> +			};
> +
> +			reg_dcdc2: dcdc2 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <810000>;
> +				regulator-max-microvolt = <1100000>;
> +				regulator-name = "vdd-cpu";
> +			};
> +
> +			reg_dcdc3: dcdc3 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <1100000>;
> +				regulator-max-microvolt = <1100000>;
> +				regulator-name = "vdd-dram";
> +			};
> +		};
> +	};
> +};
> +
> +&uart0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart0_ph_pins>;
> +	status = "okay";
> +};
> +
> +&usbotg {
> +	/*
> +	 * PHY0 pins are connected to a USB-C socket, but a role switch is not
> +	 * implemented: both CC pins are pulled to GND via a 5.1K resistor.
> +	 * The VBUS pins power the device, so a fixed peripheral mode
> +	 * is the best choice.
> +	 * The board can be powered via GPIOs, in this case port0 *can*
> +	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
> +	 * then provided by the GPIOs. Any user of this setup would
> +	 * need to adjust the DT accordingly: dr_mode set to "host",
> +	 * enabling OHCI0 and EHCI0.
> +	 */
> +	dr_mode = "peripheral";
> +	status = "okay";
> +};
> +
> +&usbphy {
> +	usb3_vbus-supply = <&reg_usb_vbus>;
> +	status = "okay";
> +};
> 






From william.zhang at broadcom.com  Mon Feb  5 10:20:20 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Mon, 5 Feb 2024 10:20:20 -0800
Subject: [PATCH v4 12/12] mtd: rawnand: brcmnand: update log level
 messages
In-Reply-To: <20240205143745.5a1036c6@xps-13>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
 <20240203002834.171462-13-william.zhang@broadcom.com>
 <20240205143745.5a1036c6@xps-13>
Message-ID: <2b299550-4cd8-4f32-93e4-71e529d7c266@broadcom.com>



On 2/5/24 05:37, Miquel Raynal wrote:
> Hi William,
> 
> william.zhang at broadcom.com wrote on Fri,  2 Feb 2024 16:28:33 -0800:
> 
>> From: David Regan <dregan at broadcom.com>
>>
>> Update log level messages so that more critical messages
>> can be seen.
> 
> This commit log does not convince me. Warning messages are visible,
> they are in dmesg. If you want them on your console, lower your default
> console level by 1 and they will appear. I'm fine increasing the log
> level on error messages, but the justification cannot be specific to
> your own setup.
> 
It is mainly for troubleshooting our customer devices. Understand we can 
get the log through dmesg but when we deal with system hang issue, 
console log is very important. And also sometimes customer has rebooted 
the device due to error condition and we lost the dmesg.

How about we update the commit message to:
Update log level messages so that more critical messages
can be logged to console and help the troubleshooting with customer 
devices.

>>
>> Signed-off-by: David Regan <dregan at broadcom.com>
>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>> Reviewed-by: William Zhang <william.zhang at broadcom.com>
>>
>> ---
>>
>> Changes in v4:
>> - Revert the log level change for correctable ecc error
>>
>> Changes in v3: None
>> Changes in v2:
>> - Added to patch series
>>
>>   drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
>> index 7ce2b267676f..e50582b45182 100644
>> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
>> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
>> @@ -1143,7 +1143,7 @@ static int bcmnand_ctrl_poll_status(struct brcmnand_host *host,
>>   	if ((val & mask) == expected_val)
>>   		return 0;
>>   
>> -	dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
>> +	dev_err(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
>>   		 expected_val, val & mask);
>>   
>>   	return -ETIMEDOUT;
>> @@ -2196,7 +2196,7 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
>>   				return err;
>>   		}
>>   
>> -		dev_dbg(ctrl->dev, "uncorrectable error at 0x%llx\n",
>> +		dev_err(ctrl->dev, "uncorrectable error at 0x%llx\n",
>>   			(unsigned long long)err_addr);
>>   		mtd->ecc_stats.failed++;
>>   		/* NAND layer expects zero on ECC errors */
> 
> 
> Thanks,
> Miqu?l
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240205/16fe7bf0/attachment-0001.p7s>

From jernej.skrabec at gmail.com  Mon Feb  5 10:20:24 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 19:20:24 +0100
Subject: [PATCH 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC support
In-Reply-To: <3280179.44csPzL39Z@jernej-laptop>
References: <20240204094404.149776-1-andre.przywara@arm.com>
 <20240204094404.149776-4-andre.przywara@arm.com>
 <3280179.44csPzL39Z@jernej-laptop>
Message-ID: <3788758.kQq0lBPeGt@jernej-laptop>

Dne ponedeljek, 05. februar 2024 ob 19:12:45 CET je Jernej ?krabec napisal(a):
> Hi Andre!
> 
> Dne nedelja, 04. februar 2024 ob 10:44:04 CET je Andre Przywara napisal(a):
> > The Remix Mini PC is a "mini computer" using the Allwinner H64 SoC,
> > which appears to be just a relabelled A64. It was launched in 2015 by
> > the now defunct company Jide, and shipped with a desktop optimised
> > version of Android. It features
> > 	- Allwinner H64 Soc (4 * Arm Cortex-A53 cores)
> > 	- 1 or 2 GB DRAM
> > 	- 8 or 16 GB eMMC flash
> > 	- 100 MBit Ethernet port (using an X-Powers AC200 PHY)
> > 	- RTL8723BS WiFi & Bluetooth chip
> > 	- HDMI port
> > 	- two USB 2.0 ports
> > 	- 3.5mm AV port
> > 	- microSD card slot
> > 
> > The devicetree covers most peripherals, though there is no agreed
> > binding for the PHY chip yet, so this is left out.
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
> >  .../allwinner/sun50i-h64-remix-mini-pc.dts    | 357 ++++++++++++++++++
> >  2 files changed, 358 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> > index 91d505b385de..2db3b15ad09f 100644
> > --- a/arch/arm64/boot/dts/allwinner/Makefile
> > +++ b/arch/arm64/boot/dts/allwinner/Makefile
> > @@ -16,6 +16,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab-early-adopter.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
> > +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> > new file mode 100644
> > index 000000000000..537923a541a8
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> > @@ -0,0 +1,357 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +// Copyright (c) 2018 ARM Ltd.
> 
> Shouldn't be 2024?
> 
> > +
> > +/dts-v1/;
> > +
> > +#include "sun50i-a64.dtsi"
> > +#include "sun50i-a64-cpu-opp.dtsi"
> > +
> > +#include <dt-bindings/gpio/gpio.h>
> > +
> > +/ {
> > +	model = "Remix Mini PC";
> > +	compatible = "jide,remix-mini-pc", "allwinner,sun50i-h64",
> > +		     "allwinner,sun50i-a64";
> > +
> > +	aliases {
> > +		ethernet1 = &rtl8723bs;
> > +		serial0 = &uart0;
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +
> > +	hdmi-connector {
> > +		compatible = "hdmi-connector";
> > +		type = "a";
> > +
> > +		port {
> > +			hdmi_con_in: endpoint {
> > +				remote-endpoint = <&hdmi_out_con>;
> > +			};
> > +		};
> > +	};
> > +
> > +	reg_vcc5v: regulator-5v {
> > +		/* board wide 5V supply directly from the DC input */
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "vcc-5v";
> > +		regulator-min-microvolt = <5000000>;
> > +		regulator-max-microvolt = <5000000>;
> > +		regulator-always-on;
> > +	};
> > +
> > +	wifi_pwrseq: wifi_pwrseq {
> > +		compatible = "mmc-pwrseq-simple";
> > +		pinctrl-names = "default";
> > +		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
> > +		post-power-on-delay-ms = <200>;
> > +	};
> > +};
> > +
> > +&codec {
> > +	status = "okay";
> > +};
> > +
> > +&codec_analog {
> > +	cpvdd-supply = <&reg_eldo1>;
> > +	status = "okay";
> > +};
> > +
> > +&cpu0 {
> > +	cpu-supply = <&reg_dcdc2>;
> > +};
> > +
> > +&cpu1 {
> > +	cpu-supply = <&reg_dcdc2>;
> > +};
> > +
> > +&cpu2 {
> > +	cpu-supply = <&reg_dcdc2>;
> > +};
> > +
> > +&cpu3 {
> > +	cpu-supply = <&reg_dcdc2>;
> > +};
> > +
> > +&dai {
> > +	status = "okay";
> > +};
> > +
> > +&de {
> > +	status = "okay";
> > +};
> > +
> > +&ehci0 {
> > +	status = "okay";
> > +};
> > +
> > +&ehci1 {
> > +	status = "okay";
> > +};
> > +
> > +&hdmi {
> > +	hvcc-supply = <&reg_dldo1>;
> > +	status = "okay";
> > +};
> > +
> > +&hdmi_out {
> > +	hdmi_out_con: endpoint {
> > +		remote-endpoint = <&hdmi_con_in>;
> > +	};
> > +};
> > +
> > +/* Connects to the AC200 chip */
> > +&i2c0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&i2c0_pins>;
> > +	status = "okay";
> > +};
> > +
> > +&i2c0_pins {
> > +	bias-pull-up;
> > +};
> > +
> > +&mmc0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&mmc0_pins>;
> > +	vmmc-supply = <&reg_dcdc1>;
> > +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
> > +	disable-wp;
> > +	bus-width = <4>;
> > +	status = "okay";
> > +};
> > +
> > +&mmc1 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&mmc1_pins>;
> > +	vmmc-supply = <&reg_aldo1>;
> > +	vqmmc-supply = <&reg_dldo4>;
> > +	mmc-pwrseq = <&wifi_pwrseq>;
> > +	bus-width = <4>;
> > +	non-removable;
> > +	status = "okay";
> > +
> > +	rtl8723bs: wifi at 1 {
> > +		reg = <1>;
> > +		interrupt-parent = <&r_pio>;
> > +		interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
> > +		interrupt-names = "host-wake";
> > +	};
> 
> Node without compatible doesn't help. Please remove it.
> 
> > +};
> > +
> > +&mmc2 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
> > +	vmmc-supply = <&reg_dcdc1>;
> > +	vqmmc-supply = <&reg_eldo1>;
> > +	bus-width = <8>;
> > +	non-removable;
> > +	mmc-ddr-1_8v;
> > +	mmc-hs200-1_8v;
> 
> Aren't these speed modes enabled by default?

Sorry, mmc-hs200-1_8v is ok, but mmc-ddr-1_8v should be
removed.

Best regards,
Jernej

> > +	cap-mmc-hw-reset;
> > +	status = "okay";
> > +};
> > +
> > +&ohci0 {
> > +	status = "okay";
> > +};
> > +
> > +&ohci1 {
> > +	status = "okay";
> > +};
> > +
> > +&pio {
> > +	vcc-pb-supply = <&reg_dcdc1>;
> > +	vcc-pc-supply = <&reg_dcdc1>;
> > +	vcc-pd-supply = <&reg_dcdc1>;
> > +	vcc-pe-supply = <&reg_dcdc1>;
> > +	vcc-pf-supply = <&reg_dcdc1>;
> > +	vcc-pg-supply = <&reg_dldo4>;
> > +	vcc-ph-supply = <&reg_dcdc1>;
> > +};
> > +
> > +&r_ir {
> > +	status = "okay";
> > +};
> > +
> > +&r_pio {
> > +	/*
> > +	 * We cannot add that supply for now since it would create a circular
> > +	 * dependency between pinctrl, the regulator and the RSB Bus.
> > +	 *
> > +	 * vcc-pl-supply = <&reg_aldo2>;
> > +	 */
> > +};
> > +
> > +&r_rsb {
> > +	status = "okay";
> > +
> > +	axp803: pmic at 3a3 {
> > +		compatible = "x-powers,axp803";
> > +		reg = <0x3a3>;
> > +		interrupt-parent = <&r_intc>;
> > +		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
> > +		x-powers,drive-vbus-en;
> > +
> > +		vin1-supply = <&reg_vcc5v>;
> > +		vin2-supply = <&reg_vcc5v>;
> > +		vin3-supply = <&reg_vcc5v>;
> > +		vin5-supply = <&reg_vcc5v>;
> > +		vin6-supply = <&reg_vcc5v>;
> > +		aldoin-supply = <&reg_vcc5v>;
> > +		dldoin-supply = <&reg_vcc5v>;
> > +		eldoin-supply = <&reg_vcc5v>;
> > +		fldoin-supply = <&reg_vcc5v>;
> > +		drivevbus-supply = <&reg_vcc5v>;
> > +		ips-supply = <&reg_vcc5v>;
> > +
> > +		status = "okay";
> > +	};
> > +};
> > +
> > +#include "axp803.dtsi"
> > +
> > +&ac_power_supply {
> > +	status = "okay";
> > +};
> > +
> > +&reg_dcdc1 {
> > +	regulator-always-on;
> > +	regulator-min-microvolt = <3300000>;
> > +	regulator-max-microvolt = <3300000>;
> > +	regulator-name = "vcc-3v3";
> > +};
> > +
> > +&reg_dcdc2 {
> > +	regulator-always-on;
> > +	regulator-min-microvolt = <1040000>;
> > +	regulator-max-microvolt = <1300000>;
> > +	regulator-name = "vdd-cpux";
> > +};
> > +
> > +/* DCDC3 is polyphased with DCDC2 */
> > +
> > +&reg_dcdc5 {
> > +	regulator-always-on;
> > +	regulator-min-microvolt = <1500000>;
> > +	regulator-max-microvolt = <1500000>;
> > +	regulator-name = "vcc-dram";
> > +};
> > +
> > +/* Deviates from the reset default of 1.1V. */
> > +&reg_dcdc6 {
> > +	regulator-always-on;
> > +	regulator-min-microvolt = <1200000>;
> > +	regulator-max-microvolt = <1200000>;
> > +	regulator-name = "vdd-sys";
> > +};
> > +
> > +&reg_aldo1 {
> > +	regulator-min-microvolt = <3300000>;
> > +	regulator-max-microvolt = <3300000>;
> > +	regulator-name = "vcc-wifi";
> > +};
> > +
> > +&reg_aldo2 {
> > +	/* Specifying R_PIO consumer would create circular dependency. */
> > +	regulator-always-on;
> > +	regulator-min-microvolt = <3300000>;
> > +	regulator-max-microvolt = <3300000>;
> > +	regulator-name = "vcc-pl";
> > +};
> > +
> > +&reg_aldo3 {
> > +	regulator-always-on;
> > +	regulator-min-microvolt = <3000000>;
> > +	regulator-max-microvolt = <3000000>;
> > +	regulator-name = "vcc-pll-avcc";
> > +};
> > +
> > +/* AC200 power supply */
> > +&reg_dldo1 {
> > +	regulator-always-on;
> > +	regulator-min-microvolt = <3300000>;
> > +	regulator-max-microvolt = <3300000>;
> > +	regulator-name = "vcc-ave-33";
> > +};
> > +
> > +&reg_dldo4 {
> > +	regulator-min-microvolt = <3300000>;
> > +	regulator-max-microvolt = <3300000>;
> > +	regulator-name = "vcc-wifi-io";
> > +};
> > +
> > +&reg_drivevbus {
> > +	regulator-name = "usb0-vbus";
> > +	status = "okay";
> > +};
> > +
> > +&reg_eldo1 {
> > +	regulator-always-on;
> > +	regulator-min-microvolt = <1800000>;
> > +	regulator-max-microvolt = <1800000>;
> > +	regulator-name = "vcc-cpvdd-dram-emmc";
> > +};
> > +
> > +/* Supplies the arisc management core, needed by TF-A to power off cores. */
> > +&reg_fldo2 {
> > +	regulator-always-on;
> > +	regulator-min-microvolt = <1100000>;
> > +	regulator-max-microvolt = <1100000>;
> > +	regulator-name = "vdd-cpus";
> > +};
> > +
> > +&reg_rtc_ldo {
> > +	regulator-name = "vcc-rtc";
> > +};
> > +
> > +&simplefb_hdmi {
> > +	vcc-hdmi-supply = <&reg_dcdc1>;
> > +};
> > +
> > +&sound {
> > +	simple-audio-card,aux-devs = <&codec_analog>;
> > +	simple-audio-card,widgets = "Microphone", "Microphone Jack",
> > +				    "Headphone", "Headphone Jack";
> > +	simple-audio-card,routing =
> > +			"Left DAC", "DACL",
> > +			"Right DAC", "DACR",
> > +			"Headphone Jack", "HP",
> > +			"ADCL", "Left ADC",
> > +			"ADCR", "Right ADC",
> > +			"MIC2", "Microphone Jack";
> > +	status = "okay";
> > +};
> > +
> > +/* On the (unpopulated) UART pads. */
> > +&uart0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&uart0_pb_pins>;
> > +	status = "okay";
> > +};
> > +
> > +&uart1 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
> > +	uart-has-rtscts;
> > +	status = "okay";
> > +
> > +	bluetooth {
> > +		compatible = "realtek,rtl8723bs-bt";
> > +		enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
> > +		max-speed = <1500000>;
> > +	};
> > +};
> > +
> > +&usb_otg {
> > +	dr_mode = "host";
> > +	status = "okay";
> > +};
> > +
> > +&usbphy {
> > +	usb0_vbus-supply = <&reg_drivevbus>;
> > +	usb1_vbus-supply = <&reg_drivevbus>;
> > +	status = "okay";
> > +};
> > 
> 
> 
> 
> 
> 






From jernej.skrabec at gmail.com  Mon Feb  5 10:23:31 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 19:23:31 +0100
Subject: [PATCH 1/2] arm64: dts: allwinner: h616: Add 32K fanout pin
In-Reply-To: <20240204093255.148972-2-andre.przywara@arm.com>
References: <20240204093255.148972-1-andre.przywara@arm.com>
 <20240204093255.148972-2-andre.przywara@arm.com>
Message-ID: <3206408.5fSG56mABF@jernej-laptop>

Dne nedelja, 04. februar 2024 ob 10:32:54 CET je Andre Przywara napisal(a):
> On some boards the designers saved on a 32KHz crystal for some external
> chips, so the SoC has to help out, with providing a 32 KHz clock signal.
> 
> Add a pinctrl group node to allow DT nodes to reference this fanout signal.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> index d549d277d972..107256eeedc3 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> @@ -256,6 +256,11 @@ uart1_rts_cts_pins: uart1-rts-cts-pins {
>  				pins = "PG8", "PG9";
>  				function = "uart1";
>  			};
> +
> +			x32clk_fanout_pin: x32clk-fanout-pin {
> +				pins = "PG10";
> +				function = "clock";
> +			};

Please add /omit-if-no-ref/

Best regards,
Jernej

>  		};
>  
>  		gic: interrupt-controller at 3021000 {
> 






From wahrenst at gmx.net  Mon Feb  5 10:25:25 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon, 5 Feb 2024 19:25:25 +0100
Subject: [PATCH 04/12] bcm2835-dma: Advertise the full DMA range
In-Reply-To: <a56a6d24066a64598efe4343090e51e2223475b8.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
 <a56a6d24066a64598efe4343090e51e2223475b8.1706948717.git.andrea.porta@suse.com>
Message-ID: <419984b7-1b19-4daa-ae88-f574267b6c00@gmx.net>

Hi Andrea,

Am 04.02.24 um 07:59 schrieb Andrea della Porta:
> From: Phil Elwell <phil at raspberrypi.com>
>
> Unless the DMA mask is set wider than 32 bits, DMA mapping will use a
> bounce buffer.
>
> Signed-off-by: Phil Elwell <phil at raspberrypi.com>
this lacks your Signed-off-by

Regards


From jernej.skrabec at gmail.com  Mon Feb  5 10:26:44 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 19:26:44 +0100
Subject: [PATCH 2/2] arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes
In-Reply-To: <20240204093255.148972-3-andre.przywara@arm.com>
References: <20240204093255.148972-1-andre.przywara@arm.com>
 <20240204093255.148972-3-andre.przywara@arm.com>
Message-ID: <8371906.NyiUUSuA9g@jernej-laptop>

Dne nedelja, 04. februar 2024 ob 10:32:55 CET je Andre Przywara napisal(a):
> In contrast to other devices using Allwinner SoCs, the Transpeed 8K618-T
> TV box uses a mainline supported WiFi chip: it's a Broadcom 4335
> compatible, packaged by a company called Murata.
> It works nicely with the Linux driver, when providing the respective
> firmware files.
> 
> Add the required DT nodes to let the kernel find the SDIO device.

Can you reword message in a way to omit Linux?

> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  .../sun50i-h618-transpeed-8k618-t.dts         | 23 +++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> index 8ea1fd41aeba..7ec4098e707b 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> @@ -16,6 +16,7 @@ / {
>  
>  	aliases {
>  		serial0 = &uart0;
> +		ethernet1 = &sdio_wifi;
>  	};
>  
>  	chosen {
> @@ -39,6 +40,15 @@ reg_vcc3v3: vcc3v3 {
>  		regulator-max-microvolt = <3300000>;
>  		regulator-always-on;
>  	};
> +
> +	wifi_pwrseq: wifi_pwrseq {
> +		compatible = "mmc-pwrseq-simple";
> +		clocks = <&rtc CLK_OSC32K_FANOUT>;
> +		clock-names = "ext_clock";
> +		pinctrl-0 = <&x32clk_fanout_pin>;
> +		pinctrl-names = "default";
> +		reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
> +	};
>  };
>  
>  &ehci0 {
> @@ -60,6 +70,19 @@ &mmc0 {
>  	status = "okay";
>  };
>  
> +&mmc1 {
> +	vmmc-supply = <&reg_dldo1>;
> +	vqmmc-supply = <&reg_aldo1>;
> +	mmc-pwrseq = <&wifi_pwrseq>;
> +	bus-width = <4>;
> +	non-removable;
> +	status = "okay";
> +
> +	sdio_wifi: wifi at 1 {
> +		reg = <1>;
> +	};

I don't think this node and alias are useful in any way. SDIO scan will find
device regardless and potential mac property set up by bootloader will be
ignored anyway.

Best regards,
Jernej

> +};
> +
>  &mmc2 {
>  	vmmc-supply = <&reg_dldo1>;
>  	vqmmc-supply = <&reg_aldo1>;
> 






From brgl at bgdev.pl  Mon Feb  5 10:27:58 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:27:58 +0100
Subject: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
Message-ID: <20240205182810.58382-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

We've established the need for using separate secured memory pools for
SCM and QSEECOM as well as the upcoming scminvoke driver.

It's also become clear that in order to be future-proof, the new
allocator must be an abstraction layer of a higher level as the SHM
Bridge will not be the only memory protection mechanism that we'll see
upstream. Hence the rename to TrustZone Memory rather than SCM Memory
allocator.

Also to that end: the new allocator is its own module now and provides a
Kconfig choice menu for selecting the mode of operation (currently
default and SHM Bridge).

Tested on sm8550 and sa8775p with the Inline Crypto Engine and
remoteproc.

v6 -> v7:
- fix a Kconfig issue: TZMEM must select GENERIC_ALLOCATOR

v5 -> v6:
Fixed two issues reported by autobuilders:
- add a fix for memory leaks in the qseecom driver as the first patch for
  easier backporting to the v6.6.y branch
- explicitly cast the bus address stored in a variable of type dma_addr_t
  to phys_addr_t expected by the genpool API

v4 -> v5:
- fix the return value from qcom_tzmem_init() if SHM Bridge is not supported
- remove a comment that's no longer useful
- collect tags

v3 -> v4:
- include linux/sizes.h for SZ_X macros
- use dedicated RCU APIs to dereference radix tree slots
- fix kerneldocs
- fix the comment in patch 14/15: it's the hypervisor, not the TrustZone
  that creates the SHM bridge

v2 -> v3:
- restore pool management and use separate pools for different users
- don't use the new allocator in qcom_scm_pas_init_image() as the
  TrustZone will create an SHM bridge for us here
- rewrite the entire series again for most part

v1 -> v2:
- too many changes to list, it's a complete rewrite as explained above

Bartosz Golaszewski (12):
  firmware: qcom: add a dedicated TrustZone buffer allocator
  firmware: qcom: scm: enable the TZ mem allocator
  firmware: qcom: scm: smc: switch to using the SCM allocator
  firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
  firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
  firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
  firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ
    allocator
  firmware: qcom: qseecom: convert to using the TZ allocator
  firmware: qcom: scm: add support for SHM bridge operations
  firmware: qcom: tzmem: enable SHM Bridge support
  firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
  arm64: defconfig: enable SHM Bridge support for the TZ memory
    allocator

 MAINTAINERS                                   |   8 +
 arch/arm64/configs/defconfig                  |   1 +
 drivers/firmware/qcom/Kconfig                 |  31 ++
 drivers/firmware/qcom/Makefile                |   1 +
 .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++---------
 drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
 drivers/firmware/qcom/qcom_scm.c              | 179 +++++----
 drivers/firmware/qcom/qcom_scm.h              |   6 +
 drivers/firmware/qcom/qcom_tzmem.c            | 365 ++++++++++++++++++
 drivers/firmware/qcom/qcom_tzmem.h            |  13 +
 include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
 include/linux/firmware/qcom/qcom_scm.h        |   6 +
 include/linux/firmware/qcom/qcom_tzmem.h      |  28 ++
 13 files changed, 685 insertions(+), 268 deletions(-)
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
 create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h

-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:27:59 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:27:59 +0100
Subject: [PATCH v7 01/12] firmware: qcom: add a dedicated TrustZone buffer allocator
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-2-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

We have several SCM calls that require passing buffers to the TrustZone
on top of the SMC core which allocates memory for calls that require
more than 4 arguments.

Currently every user does their own thing which leads to code
duplication. Many users call dma_alloc_coherent() for every call which
is terribly unperformant (speed- and size-wise).

Provide a set of library functions for creating and managing pool of
memory which is suitable for sharing with the TrustZone, that is:
page-aligned, contiguous and non-cachable as well as provides a way of
mapping of kernel virtual addresses to physical space.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 MAINTAINERS                              |   8 +
 drivers/firmware/qcom/Kconfig            |  20 ++
 drivers/firmware/qcom/Makefile           |   1 +
 drivers/firmware/qcom/qcom_tzmem.c       | 302 +++++++++++++++++++++++
 drivers/firmware/qcom/qcom_tzmem.h       |  13 +
 include/linux/firmware/qcom/qcom_tzmem.h |  28 +++
 6 files changed, 372 insertions(+)
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
 create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ff059e870a44..0c82625de50d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18231,6 +18231,14 @@ L:	linux-arm-msm at vger.kernel.org
 S:	Maintained
 F:	drivers/firmware/qcom/qcom_qseecom.c
 
+QUALCOMM TRUST ZONE MEMORY ALLOCATOR
+M:	Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
+L:	linux-arm-msm at vger.kernel.org
+S:	Maintained
+F:	drivers/firmware/qcom/qcom_tzmem.c
+F:	drivers/firmware/qcom/qcom_tzmem.h
+F:	include/linux/firmware/qcom/qcom_tzmem.h
+
 QUALCOMM QSEECOM UEFISECAPP DRIVER
 M:	Maximilian Luz <luzmaximilian at gmail.com>
 L:	linux-arm-msm at vger.kernel.org
diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index 3f05d9854ddf..f18686edf415 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -9,6 +9,26 @@ menu "Qualcomm firmware drivers"
 config QCOM_SCM
 	tristate
 
+config QCOM_TZMEM
+	tristate
+	select GENERIC_ALLOCATOR
+
+choice
+	prompt "TrustZone interface memory allocator mode"
+	default QCOM_TZMEM_MODE_DEFAULT
+	help
+	  Selects the mode of the memory allocator providing memory buffers of
+	  suitable format for sharing with the TrustZone. If in doubt, select
+	  'Default'.
+
+config QCOM_TZMEM_MODE_DEFAULT
+	bool "Default"
+	help
+	  Use the default allocator mode. The memory is page-aligned, non-cachable
+	  and contiguous.
+
+endchoice
+
 config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
 	bool "Qualcomm download mode enabled by default"
 	depends on QCOM_SCM
diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
index c9f12ee8224a..0be40a1abc13 100644
--- a/drivers/firmware/qcom/Makefile
+++ b/drivers/firmware/qcom/Makefile
@@ -5,5 +5,6 @@
 
 obj-$(CONFIG_QCOM_SCM)		+= qcom-scm.o
 qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
+obj-$(CONFIG_QCOM_TZMEM)	+= qcom_tzmem.o
 obj-$(CONFIG_QCOM_QSEECOM)	+= qcom_qseecom.o
 obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
new file mode 100644
index 000000000000..44a062f2abd4
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Memory allocator for buffers shared with the TrustZone.
+ *
+ * Copyright (C) 2023 Linaro Ltd.
+ */
+
+#include <linux/bug.h>
+#include <linux/cleanup.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
+#include <linux/genalloc.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+#include <linux/radix-tree.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include "qcom_tzmem.h"
+
+struct qcom_tzmem_pool {
+	void *vbase;
+	dma_addr_t pbase;
+	size_t size;
+	struct gen_pool *pool;
+	void *priv;
+};
+
+struct qcom_tzmem_chunk {
+	phys_addr_t paddr;
+	size_t size;
+	struct qcom_tzmem_pool *owner;
+};
+
+static struct device *qcom_tzmem_dev;
+static RADIX_TREE(qcom_tzmem_chunks, GFP_ATOMIC);
+static DEFINE_SPINLOCK(qcom_tzmem_chunks_lock);
+
+#if IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_DEFAULT)
+
+static int qcom_tzmem_init(void)
+{
+	return 0;
+}
+
+static int qcom_tzmem_init_pool(struct qcom_tzmem_pool *pool)
+{
+	return 0;
+}
+
+static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
+{
+
+}
+
+#endif /* CONFIG_QCOM_TZMEM_MODE_DEFAULT */
+
+/**
+ * qcom_tzmem_pool_new() - Create a new TZ memory pool.
+ * @size: Size of the new pool in bytes.
+ *
+ * Create a new pool of memory suitable for sharing with the TrustZone.
+ *
+ * Must not be used in atomic context.
+ *
+ * Returns:
+ * New memory pool address or ERR_PTR() on error.
+ */
+struct qcom_tzmem_pool *qcom_tzmem_pool_new(size_t size)
+{
+	struct qcom_tzmem_pool *pool;
+	int ret = -ENOMEM;
+
+	if (!size)
+		return ERR_PTR(-EINVAL);
+
+	size = PAGE_ALIGN(size);
+
+	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+	if (!pool)
+		return ERR_PTR(-ENOMEM);
+
+	pool->size = size;
+
+	pool->vbase = dma_alloc_coherent(qcom_tzmem_dev, size, &pool->pbase,
+					 GFP_KERNEL);
+	if (!pool->vbase)
+		goto err_kfree_pool;
+
+	pool->pool = gen_pool_create(PAGE_SHIFT, -1);
+	if (!pool)
+		goto err_dma_free;
+
+	gen_pool_set_algo(pool->pool, gen_pool_best_fit, NULL);
+
+	ret = gen_pool_add_virt(pool->pool, (unsigned long)pool->vbase,
+				(phys_addr_t)pool->pbase, size, -1);
+	if (ret)
+		goto err_destroy_genpool;
+
+	ret = qcom_tzmem_init_pool(pool);
+	if (ret)
+		goto err_destroy_genpool;
+
+	return pool;
+
+err_destroy_genpool:
+	gen_pool_destroy(pool->pool);
+err_dma_free:
+	dma_free_coherent(qcom_tzmem_dev, size, pool->vbase, pool->pbase);
+err_kfree_pool:
+	kfree(pool);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_pool_new);
+
+/**
+ * qcom_tzmem_pool_free() - Destroy a TZ memory pool and free all resources.
+ * @pool: Memory pool to free.
+ *
+ * Must not be called if any of the allocated chunks has not been freed.
+ * Must not be used in atomic context.
+ */
+void qcom_tzmem_pool_free(struct qcom_tzmem_pool *pool)
+{
+	struct qcom_tzmem_chunk *chunk;
+	struct radix_tree_iter iter;
+	bool non_empty = false;
+	void __rcu **slot;
+
+	if (!pool)
+		return;
+
+	qcom_tzmem_cleanup_pool(pool);
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock) {
+		radix_tree_for_each_slot(slot, &qcom_tzmem_chunks, &iter, 0) {
+			chunk = radix_tree_deref_slot_protected(slot,
+						&qcom_tzmem_chunks_lock);
+
+			if (chunk->owner == pool)
+				non_empty = true;
+		}
+	}
+
+	WARN(non_empty, "Freeing TZ memory pool with memory still allocated");
+
+	gen_pool_destroy(pool->pool);
+	dma_free_coherent(qcom_tzmem_dev, pool->size, pool->vbase, pool->pbase);
+	kfree(pool);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_pool_free);
+
+static void devm_qcom_tzmem_pool_free(void *data)
+{
+	struct qcom_tzmem_pool *pool = data;
+
+	qcom_tzmem_pool_free(pool);
+}
+
+/**
+ * devm_qcom_tzmem_pool_new() - Managed variant of qcom_tzmem_pool_new().
+ * @dev: Device managing this resource.
+ * @size: Size of the pool in bytes.
+ *
+ * Must not be used in atomic context.
+ *
+ * Returns:
+ * Address of the managed pool or ERR_PTR() on failure.
+ */
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev, size_t size)
+{
+	struct qcom_tzmem_pool *pool;
+	int ret;
+
+	pool = qcom_tzmem_pool_new(size);
+	if (IS_ERR(pool))
+		return pool;
+
+	ret = devm_add_action_or_reset(dev, devm_qcom_tzmem_pool_free, pool);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return pool;
+}
+
+/**
+ * qcom_tzmem_alloc() - Allocate a memory chunk suitable for sharing with TZ.
+ * @pool: TZ memory pool from which to allocate memory.
+ * @size: Number of bytes to allocate.
+ * @gfp: GFP flags.
+ *
+ * Can be used in any context.
+ *
+ * Returns:
+ * Address of the allocated buffer or NULL if no more memory can be allocated.
+ * The buffer must be released using qcom_tzmem_free().
+ */
+void *qcom_tzmem_alloc(struct qcom_tzmem_pool *pool, size_t size, gfp_t gfp)
+{
+	struct qcom_tzmem_chunk *chunk;
+	unsigned long vaddr;
+	int ret;
+
+	if (!size)
+		return NULL;
+
+	size = PAGE_ALIGN(size);
+
+	chunk = kzalloc(sizeof(*chunk), gfp);
+	if (!chunk)
+		return NULL;
+
+	vaddr = gen_pool_alloc(pool->pool, size);
+	if (!vaddr) {
+		kfree(chunk);
+		return NULL;
+	}
+
+	chunk->paddr = gen_pool_virt_to_phys(pool->pool, vaddr);
+	chunk->size = size;
+	chunk->owner = pool;
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock) {
+		ret = radix_tree_insert(&qcom_tzmem_chunks, vaddr, chunk);
+		if (ret) {
+			gen_pool_free(pool->pool, vaddr, size);
+			kfree(chunk);
+			return NULL;
+		}
+	}
+
+	return (void *)vaddr;
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_alloc);
+
+/**
+ * qcom_tzmem_free() - Release a buffer allocated from a TZ memory pool.
+ * @vaddr: Virtual address of the buffer.
+ *
+ * Can be used in any context.
+ */
+void qcom_tzmem_free(void *vaddr)
+{
+	struct qcom_tzmem_chunk *chunk;
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock)
+		chunk = radix_tree_delete_item(&qcom_tzmem_chunks,
+					       (unsigned long)vaddr, NULL);
+
+	if (!chunk) {
+		WARN(1, "Virtual address %p not owned by TZ memory allocator",
+		     vaddr);
+		return;
+	}
+
+	gen_pool_free(chunk->owner->pool, (unsigned long)vaddr, chunk->size);
+	kfree(chunk);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_free);
+
+/**
+ * qcom_tzmem_to_phys() - Map the virtual address of a TZ buffer to physical.
+ * @vaddr: Virtual address of the buffer allocated from a TZ memory pool.
+ *
+ * Can be used in any context. The address must have been returned by a call
+ * to qcom_tzmem_alloc().
+ *
+ * Returns:
+ * Physical address of the buffer.
+ */
+phys_addr_t qcom_tzmem_to_phys(void *vaddr)
+{
+	struct qcom_tzmem_chunk *chunk;
+
+	guard(spinlock_irqsave)(&qcom_tzmem_chunks_lock);
+
+	chunk = radix_tree_lookup(&qcom_tzmem_chunks, (unsigned long)vaddr);
+	if (!chunk)
+		return 0;
+
+	return chunk->paddr;
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_to_phys);
+
+int qcom_tzmem_enable(struct device *dev)
+{
+	if (qcom_tzmem_dev)
+		return -EBUSY;
+
+	qcom_tzmem_dev = dev;
+
+	return qcom_tzmem_init();
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_enable);
+
+MODULE_DESCRIPTION("TrustZone memory allocator for Qualcomm firmware drivers");
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski at linaro.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/qcom/qcom_tzmem.h b/drivers/firmware/qcom/qcom_tzmem.h
new file mode 100644
index 000000000000..f82f5dc5b7b1
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 Linaro Ltd.
+ */
+
+#ifndef __QCOM_TZMEM_PRIV_H
+#define __QCOM_TZMEM_PRIV_H
+
+struct device;
+
+int qcom_tzmem_enable(struct device *dev);
+
+#endif /* __QCOM_TZMEM_PRIV_H */
diff --git a/include/linux/firmware/qcom/qcom_tzmem.h b/include/linux/firmware/qcom/qcom_tzmem.h
new file mode 100644
index 000000000000..8e7fddab8cb4
--- /dev/null
+++ b/include/linux/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 Linaro Ltd.
+ */
+
+#ifndef __QCOM_TZMEM_H
+#define __QCOM_TZMEM_H
+
+#include <linux/cleanup.h>
+#include <linux/gfp.h>
+#include <linux/types.h>
+
+struct device;
+struct qcom_tzmem_pool;
+
+struct qcom_tzmem_pool *qcom_tzmem_pool_new(size_t size);
+void qcom_tzmem_pool_free(struct qcom_tzmem_pool *pool);
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev, size_t size);
+
+void *qcom_tzmem_alloc(struct qcom_tzmem_pool *pool, size_t size, gfp_t gfp);
+void qcom_tzmem_free(void *ptr);
+
+DEFINE_FREE(qcom_tzmem, void *, if (_T) qcom_tzmem_free(_T));
+
+phys_addr_t qcom_tzmem_to_phys(void *ptr);
+
+#endif /* __QCOM_TZMEM */
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:00 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:00 +0100
Subject: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-3-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Select the TrustZone memory allocator in Kconfig and create a pool of
memory shareable with the TrustZone when probing the SCM driver.

This will allow a gradual conversion of all relevant SCM calls to using
the dedicated allocator.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/firmware/qcom/Kconfig    |  1 +
 drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index f18686edf415..d24d83223867 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -7,6 +7,7 @@
 menu "Qualcomm firmware drivers"
 
 config QCOM_SCM
+	select QCOM_TZMEM
 	tristate
 
 config QCOM_TZMEM
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 520de9b5633a..0d4c028be0c1 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -8,8 +8,10 @@
 #include <linux/completion.h>
 #include <linux/cpumask.h>
 #include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/export.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 #include <linux/init.h>
 #include <linux/interconnect.h>
 #include <linux/interrupt.h>
@@ -20,9 +22,11 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/reset-controller.h>
+#include <linux/sizes.h>
 #include <linux/types.h>
 
 #include "qcom_scm.h"
+#include "qcom_tzmem.h"
 
 static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
 module_param(download_mode, bool, 0);
@@ -41,6 +45,8 @@ struct qcom_scm {
 	int scm_vote_count;
 
 	u64 dload_mode_addr;
+
+	struct qcom_tzmem_pool *mempool;
 };
 
 struct qcom_scm_current_perm_info {
@@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
 	if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
 		qcom_scm_disable_sdi();
 
+	ret = qcom_tzmem_enable(__scm->dev);
+	if (ret)
+		return dev_err_probe(__scm->dev, ret,
+				     "Failed to enable the TrustZone memory allocator\n");
+
+	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);
+	if (IS_ERR(__scm->mempool))
+		return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
+				     "Failed to create the SCM memory pool\n");
+
 	/*
 	 * Initialize the QSEECOM interface.
 	 *
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:01 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:01 +0100
Subject: [PATCH v7 03/12] firmware: qcom: scm: smc: switch to using the SCM allocator
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-4-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

We need to allocate, map and pass a buffer to the trustzone if we have
more than 4 arguments for a given SCM calls. Let's use the new TrustZone
allocator for that memory and shrink the code in process.

As this code lives in a different compilation unit than the rest of the
SCM code, we need to provide a helper in the form of
qcom_scm_get_tzmem_pool() that allows the SMC low-level routines to
access the SCM memory pool.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/firmware/qcom/qcom_scm-smc.c | 30 ++++++++--------------------
 drivers/firmware/qcom/qcom_scm.c     |  5 +++++
 drivers/firmware/qcom/qcom_scm.h     |  3 +++
 3 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm-smc.c b/drivers/firmware/qcom/qcom_scm-smc.c
index 16cf88acfa8e..dca5f3f1883b 100644
--- a/drivers/firmware/qcom/qcom_scm-smc.c
+++ b/drivers/firmware/qcom/qcom_scm-smc.c
@@ -2,6 +2,7 @@
 /* Copyright (c) 2015,2019 The Linux Foundation. All rights reserved.
  */
 
+#include <linux/cleanup.h>
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
@@ -9,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 #include <linux/arm-smccc.h>
 #include <linux/dma-mapping.h>
 
@@ -150,11 +152,10 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
 		   enum qcom_scm_convention qcom_convention,
 		   struct qcom_scm_res *res, bool atomic)
 {
+	struct qcom_tzmem_pool *mempool = qcom_scm_get_tzmem_pool();
 	int arglen = desc->arginfo & 0xf;
 	int i, ret;
-	dma_addr_t args_phys = 0;
-	void *args_virt = NULL;
-	size_t alloc_len;
+	void *args_virt __free(qcom_tzmem) = NULL;
 	gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
 	u32 smccc_call_type = atomic ? ARM_SMCCC_FAST_CALL : ARM_SMCCC_STD_CALL;
 	u32 qcom_smccc_convention = (qcom_convention == SMC_CONVENTION_ARM_32) ?
@@ -172,9 +173,9 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
 		smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i];
 
 	if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) {
-		alloc_len = SCM_SMC_N_EXT_ARGS * sizeof(u64);
-		args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
-
+		args_virt = qcom_tzmem_alloc(mempool,
+					     SCM_SMC_N_EXT_ARGS * sizeof(u64),
+					     flag);
 		if (!args_virt)
 			return -ENOMEM;
 
@@ -192,25 +193,10 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
 						      SCM_SMC_FIRST_EXT_IDX]);
 		}
 
-		args_phys = dma_map_single(dev, args_virt, alloc_len,
-					   DMA_TO_DEVICE);
-
-		if (dma_mapping_error(dev, args_phys)) {
-			kfree(args_virt);
-			return -ENOMEM;
-		}
-
-		smc.args[SCM_SMC_LAST_REG_IDX] = args_phys;
+		smc.args[SCM_SMC_LAST_REG_IDX] = qcom_tzmem_to_phys(args_virt);
 	}
 
-	/* ret error check follows after args_virt cleanup*/
 	ret = __scm_smc_do(dev, &smc, &smc_res, atomic);
-
-	if (args_virt) {
-		dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
-		kfree(args_virt);
-	}
-
 	if (ret)
 		return ret;
 
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 0d4c028be0c1..71e98b666391 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -201,6 +201,11 @@ static void qcom_scm_bw_disable(void)
 enum qcom_scm_convention qcom_scm_convention = SMC_CONVENTION_UNKNOWN;
 static DEFINE_SPINLOCK(scm_query_lock);
 
+struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void)
+{
+	return __scm->mempool;
+}
+
 static enum qcom_scm_convention __get_convention(void)
 {
 	unsigned long flags;
diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
index 4532907e8489..aa7d06939f8e 100644
--- a/drivers/firmware/qcom/qcom_scm.h
+++ b/drivers/firmware/qcom/qcom_scm.h
@@ -5,6 +5,7 @@
 #define __QCOM_SCM_INT_H
 
 struct device;
+struct qcom_tzmem_pool;
 
 enum qcom_scm_convention {
 	SMC_CONVENTION_UNKNOWN,
@@ -78,6 +79,8 @@ int scm_legacy_call_atomic(struct device *dev, const struct qcom_scm_desc *desc,
 int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
 		    struct qcom_scm_res *res);
 
+struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
+
 #define QCOM_SCM_SVC_BOOT		0x01
 #define QCOM_SCM_BOOT_SET_ADDR		0x01
 #define QCOM_SCM_BOOT_TERMINATE_PC	0x02
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:02 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:02 +0100
Subject: [PATCH v7 04/12] firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-5-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of using dma_alloc_coherent().

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 71e98b666391..754f6056b99f 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/arm-smccc.h>
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/cpumask.h>
@@ -998,14 +999,13 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 	struct qcom_scm_mem_map_info *mem_to_map;
 	phys_addr_t mem_to_map_phys;
 	phys_addr_t dest_phys;
-	dma_addr_t ptr_phys;
+	phys_addr_t ptr_phys;
 	size_t mem_to_map_sz;
 	size_t dest_sz;
 	size_t src_sz;
 	size_t ptr_sz;
 	int next_vm;
 	__le32 *src;
-	void *ptr;
 	int ret, i, b;
 	u64 srcvm_bits = *srcvm;
 
@@ -1015,10 +1015,13 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 	ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) +
 			ALIGN(dest_sz, SZ_64);
 
-	ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL);
+	void *ptr __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							ptr_sz, GFP_KERNEL);
 	if (!ptr)
 		return -ENOMEM;
 
+	ptr_phys = qcom_tzmem_to_phys(ptr);
+
 	/* Fill source vmid detail */
 	src = ptr;
 	i = 0;
@@ -1047,7 +1050,6 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 
 	ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz,
 				    ptr_phys, src_sz, dest_phys, dest_sz);
-	dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_phys);
 	if (ret) {
 		dev_err(__scm->dev,
 			"Assign memory protection call failed %d\n", ret);
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:03 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:03 +0100
Subject: [PATCH v7 05/12] firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-6-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of using dma_alloc_coherent().

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 754f6056b99f..31071a714cf1 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1197,32 +1197,21 @@ int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,
 		.args[4] = data_unit_size,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
-	void *keybuf;
-	dma_addr_t key_phys;
+
 	int ret;
 
-	/*
-	 * 'key' may point to vmalloc()'ed memory, but we need to pass a
-	 * physical address that's been properly flushed.  The sanctioned way to
-	 * do this is by using the DMA API.  But as is best practice for crypto
-	 * keys, we also must wipe the key after use.  This makes kmemdup() +
-	 * dma_map_single() not clearly correct, since the DMA API can use
-	 * bounce buffers.  Instead, just use dma_alloc_coherent().  Programming
-	 * keys is normally rare and thus not performance-critical.
-	 */
-
-	keybuf = dma_alloc_coherent(__scm->dev, key_size, &key_phys,
-				    GFP_KERNEL);
+	void *keybuf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							   key_size,
+							   GFP_KERNEL);
 	if (!keybuf)
 		return -ENOMEM;
 	memcpy(keybuf, key, key_size);
-	desc.args[1] = key_phys;
+	desc.args[1] = qcom_tzmem_to_phys(keybuf);
 
 	ret = qcom_scm_call(__scm->dev, &desc, NULL);
 
 	memzero_explicit(keybuf, key_size);
 
-	dma_free_coherent(__scm->dev, key_size, keybuf, key_phys);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_scm_ice_set_key);
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:04 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:04 +0100
Subject: [PATCH v7 06/12] firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-7-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of using dma_alloc_coherent().

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 31071a714cf1..11638daa2fe5 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1340,8 +1340,6 @@ EXPORT_SYMBOL_GPL(qcom_scm_lmh_profile_change);
 int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 		       u64 limit_node, u32 node_id, u64 version)
 {
-	dma_addr_t payload_phys;
-	u32 *payload_buf;
 	int ret, payload_size = 5 * sizeof(u32);
 
 	struct qcom_scm_desc desc = {
@@ -1356,7 +1354,9 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
 
-	payload_buf = dma_alloc_coherent(__scm->dev, payload_size, &payload_phys, GFP_KERNEL);
+	u32 *payload_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							       payload_size,
+							       GFP_KERNEL);
 	if (!payload_buf)
 		return -ENOMEM;
 
@@ -1366,11 +1366,10 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 	payload_buf[3] = 1;
 	payload_buf[4] = payload_val;
 
-	desc.args[0] = payload_phys;
+	desc.args[0] = qcom_tzmem_to_phys(payload_buf);
 
 	ret = qcom_scm_call(__scm->dev, &desc, NULL);
 
-	dma_free_coherent(__scm->dev, payload_size, payload_buf, payload_phys);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh);
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:05 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:05 +0100
Subject: [PATCH v7 07/12] firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ allocator
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-8-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of manually kmalloc()ing it and then mapping to physical space.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
Tested-by: Maximilian Luz <luzmaximilian at gmail.com>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 11638daa2fe5..3a6cefb4eb2e 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1525,37 +1525,27 @@ int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id)
 	unsigned long app_name_len = strlen(app_name);
 	struct qcom_scm_desc desc = {};
 	struct qcom_scm_qseecom_resp res = {};
-	dma_addr_t name_buf_phys;
-	char *name_buf;
 	int status;
 
 	if (app_name_len >= name_buf_size)
 		return -EINVAL;
 
-	name_buf = kzalloc(name_buf_size, GFP_KERNEL);
+	char *name_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							     name_buf_size,
+							     GFP_KERNEL);
 	if (!name_buf)
 		return -ENOMEM;
 
 	memcpy(name_buf, app_name, app_name_len);
 
-	name_buf_phys = dma_map_single(__scm->dev, name_buf, name_buf_size, DMA_TO_DEVICE);
-	status = dma_mapping_error(__scm->dev, name_buf_phys);
-	if (status) {
-		kfree(name_buf);
-		dev_err(__scm->dev, "qseecom: failed to map dma address\n");
-		return status;
-	}
-
 	desc.owner = QSEECOM_TZ_OWNER_QSEE_OS;
 	desc.svc = QSEECOM_TZ_SVC_APP_MGR;
 	desc.cmd = QSEECOM_TZ_CMD_APP_LOOKUP;
 	desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL);
-	desc.args[0] = name_buf_phys;
+	desc.args[0] = qcom_tzmem_to_phys(name_buf);
 	desc.args[1] = app_name_len;
 
 	status = qcom_scm_qseecom_call(&desc, &res);
-	dma_unmap_single(__scm->dev, name_buf_phys, name_buf_size, DMA_TO_DEVICE);
-	kfree(name_buf);
 
 	if (status)
 		return status;
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:07 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:07 +0100
Subject: [PATCH v7 09/12] firmware: qcom: scm: add support for SHM bridge operations
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-10-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Add low-level primitives for enabling SHM bridge support as well as
creating and destroying SHM bridge pools to qcom-scm.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Acked-by: Andrew Halaney <ahalaney at redhat.com>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c       | 60 ++++++++++++++++++++++++++
 drivers/firmware/qcom/qcom_scm.h       |  3 ++
 include/linux/firmware/qcom/qcom_scm.h |  6 +++
 3 files changed, 69 insertions(+)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 318d7d398e5f..839773270a21 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1323,6 +1323,66 @@ bool qcom_scm_lmh_dcvsh_available(void)
 }
 EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available);
 
+int qcom_scm_shm_bridge_enable(void)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_ENABLE,
+		.owner = ARM_SMCCC_OWNER_SIP
+	};
+
+	struct qcom_scm_res res;
+
+	if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
+					  QCOM_SCM_MP_SHM_BRIDGE_ENABLE))
+		return -EOPNOTSUPP;
+
+	return qcom_scm_call(__scm->dev, &desc, &res) ?: res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_enable);
+
+int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
+			       u64 ipfn_and_s_perm_flags, u64 size_and_flags,
+			       u64 ns_vmids, u64 *handle)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_CREATE,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = pfn_and_ns_perm_flags,
+		.args[1] = ipfn_and_s_perm_flags,
+		.args[2] = size_and_flags,
+		.args[3] = ns_vmids,
+		.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL,
+					 QCOM_SCM_VAL, QCOM_SCM_VAL),
+	};
+
+	struct qcom_scm_res res;
+	int ret;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	if (handle && !ret)
+		*handle = res.result[1];
+
+	return ret ?: res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_create);
+
+int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_DELETE,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = handle,
+		.arginfo = QCOM_SCM_ARGS(1, QCOM_SCM_VAL),
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_delete);
+
 int qcom_scm_lmh_profile_change(u32 profile_id)
 {
 	struct qcom_scm_desc desc = {
diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
index aa7d06939f8e..cb7273aa0a5e 100644
--- a/drivers/firmware/qcom/qcom_scm.h
+++ b/drivers/firmware/qcom/qcom_scm.h
@@ -116,6 +116,9 @@ struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
 #define QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE	0x05
 #define QCOM_SCM_MP_VIDEO_VAR			0x08
 #define QCOM_SCM_MP_ASSIGN			0x16
+#define QCOM_SCM_MP_SHM_BRIDGE_ENABLE		0x1c
+#define QCOM_SCM_MP_SHM_BRIDGE_DELETE		0x1d
+#define QCOM_SCM_MP_SHM_BRIDGE_CREATE		0x1e
 
 #define QCOM_SCM_SVC_OCMEM		0x0f
 #define QCOM_SCM_OCMEM_LOCK_CMD		0x01
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index ccaf28846054..9b6054813f59 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -115,6 +115,12 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 int qcom_scm_lmh_profile_change(u32 profile_id);
 bool qcom_scm_lmh_dcvsh_available(void);
 
+int qcom_scm_shm_bridge_enable(void);
+int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
+			       u64 ipfn_and_s_perm_flags, u64 size_and_flags,
+			       u64 ns_vmids, u64 *handle);
+int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle);
+
 #ifdef CONFIG_QCOM_QSEECOM
 
 int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id);
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:06 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:06 +0100
Subject: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-9-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
convert all users of it in the qseecom module to using the TZ allocator
for creating SCM call buffers. Together with using the cleanup macros,
it has the added benefit of a significant code shrink. As this is
largely a module separate from the SCM driver, let's use a separate
memory pool.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
Tested-by: Maximilian Luz <luzmaximilian at gmail.com>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++++-----------
 drivers/firmware/qcom/qcom_scm.c              |  30 +-
 include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
 3 files changed, 111 insertions(+), 204 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
index 32188f098ef3..3a068f8b6990 100644
--- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
+++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
@@ -7,17 +7,21 @@
  * Copyright (C) 2023 Maximilian Luz <luzmaximilian at gmail.com>
  */
 
+#include <linux/cleanup.h>
 #include <linux/efi.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/sizes.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/ucs2_string.h>
 
 #include <linux/firmware/qcom/qcom_qseecom.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 
 /* -- Qualcomm "uefisecapp" interface definitions. -------------------------- */
 
@@ -253,6 +257,7 @@ struct qsee_rsp_uefi_query_variable_info {
 struct qcuefi_client {
 	struct qseecom_client *client;
 	struct efivars efivars;
+	struct qcom_tzmem_pool *mempool;
 };
 
 static struct device *qcuefi_dev(struct qcuefi_client *qcuefi)
@@ -272,11 +277,11 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 					   const efi_guid_t *guid, u32 *attributes,
 					   unsigned long *data_size, void *data)
 {
-	struct qsee_req_uefi_get_variable *req_data;
-	struct qsee_rsp_uefi_get_variable *rsp_data;
+	struct qsee_req_uefi_get_variable *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_get_variable *rsp_data __free(qcom_tzmem) = NULL;
 	unsigned long buffer_size = *data_size;
-	efi_status_t efi_status = EFI_SUCCESS;
 	unsigned long name_length;
+	efi_status_t efi_status;
 	size_t guid_offs;
 	size_t name_offs;
 	size_t req_size;
@@ -304,17 +309,13 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 		__array(u8, buffer_size)
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE;
 	req_data->data_size = buffer_size;
@@ -325,28 +326,20 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 	req_data->length = req_size;
 
 	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
-	if (status < 0) {
-		efi_status = EFI_INVALID_PARAMETER;
-		goto out_free;
-	}
+	if (status < 0)
+		return EFI_INVALID_PARAMETER;
 
 	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length < sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length < sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
@@ -360,18 +353,14 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 				*attributes = rsp_data->attributes;
 		}
 
-		goto out_free;
+		return efi_status;
 	}
 
-	if (rsp_data->length > rsp_size) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length > rsp_size)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length)
+		return EFI_DEVICE_ERROR;
 
 	/*
 	 * Note: We need to set attributes and data size even if the buffer is
@@ -394,33 +383,23 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 	if (attributes)
 		*attributes = rsp_data->attributes;
 
-	if (buffer_size == 0 && !data) {
-		efi_status = EFI_SUCCESS;
-		goto out_free;
-	}
+	if (buffer_size == 0 && !data)
+		return EFI_SUCCESS;
 
-	if (buffer_size < rsp_data->data_size) {
-		efi_status = EFI_BUFFER_TOO_SMALL;
-		goto out_free;
-	}
+	if (buffer_size < rsp_data->data_size)
+		return EFI_BUFFER_TOO_SMALL;
 
 	memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size);
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const efi_char16_t *name,
 					   const efi_guid_t *guid, u32 attributes,
 					   unsigned long data_size, const void *data)
 {
-	struct qsee_req_uefi_set_variable *req_data;
-	struct qsee_rsp_uefi_set_variable *rsp_data;
-	efi_status_t efi_status = EFI_SUCCESS;
+	struct qsee_req_uefi_set_variable *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_set_variable *rsp_data __free(qcom_tzmem) = NULL;
 	unsigned long name_length;
 	size_t name_offs;
 	size_t guid_offs;
@@ -450,17 +429,14 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 		__array_offs(u8, data_size, &data_offs)
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
+				    GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
 	req_data->attributes = attributes;
@@ -473,10 +449,8 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 	req_data->length = req_size;
 
 	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
-	if (status < 0) {
-		efi_status = EFI_INVALID_PARAMETER;
-		goto out_free;
-	}
+	if (status < 0)
+		return EFI_INVALID_PARAMETER;
 
 	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
 
@@ -485,42 +459,31 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data,
 				       sizeof(*rsp_data));
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length != sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length != sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
 			__func__, rsp_data->status);
-		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
+		return qsee_uefi_status_to_efi(rsp_data->status);
 	}
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 						unsigned long *name_size, efi_char16_t *name,
 						efi_guid_t *guid)
 {
-	struct qsee_req_uefi_get_next_variable *req_data;
-	struct qsee_rsp_uefi_get_next_variable *rsp_data;
-	efi_status_t efi_status = EFI_SUCCESS;
+	struct qsee_req_uefi_get_next_variable *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_get_next_variable *rsp_data __free(qcom_tzmem) = NULL;
+	efi_status_t efi_status;
 	size_t guid_offs;
 	size_t name_offs;
 	size_t req_size;
@@ -545,17 +508,13 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 		__array(*name, *name_size / sizeof(*name))
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE;
 	req_data->guid_offset = guid_offs;
@@ -567,26 +526,18 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
 	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name,
 			      *name_size / sizeof(*name));
-	if (status < 0) {
-		efi_status = EFI_INVALID_PARAMETER;
-		goto out_free;
-	}
+	if (status < 0)
+		return EFI_INVALID_PARAMETER;
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length < sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length < sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
@@ -601,77 +552,59 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 		if (efi_status == EFI_BUFFER_TOO_SMALL)
 			*name_size = rsp_data->name_size;
 
-		goto out_free;
+		return efi_status;
 	}
 
-	if (rsp_data->length > rsp_size) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length > rsp_size)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length)
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->name_size > *name_size) {
 		*name_size = rsp_data->name_size;
-		efi_status = EFI_BUFFER_TOO_SMALL;
-		goto out_free;
+		return EFI_BUFFER_TOO_SMALL;
 	}
 
-	if (rsp_data->guid_size != sizeof(*guid)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->guid_size != sizeof(*guid))
+		return EFI_DEVICE_ERROR;
 
 	memcpy(guid, ((void *)rsp_data) + rsp_data->guid_offset, rsp_data->guid_size);
 	status = ucs2_strscpy(name, ((void *)rsp_data) + rsp_data->name_offset,
 			      rsp_data->name_size / sizeof(*name));
 	*name_size = rsp_data->name_size;
 
-	if (status < 0) {
+	if (status < 0)
 		/*
 		 * Return EFI_DEVICE_ERROR here because the buffer size should
 		 * have already been validated above, causing this function to
 		 * bail with EFI_BUFFER_TOO_SMALL.
 		 */
-		efi_status = EFI_DEVICE_ERROR;
-	}
+		return EFI_DEVICE_ERROR;
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, u32 attr,
 						  u64 *storage_space, u64 *remaining_space,
 						  u64 *max_variable_size)
 {
-	struct qsee_req_uefi_query_variable_info *req_data;
-	struct qsee_rsp_uefi_query_variable_info *rsp_data;
-	efi_status_t efi_status = EFI_SUCCESS;
+	struct qsee_req_uefi_query_variable_info *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_query_variable_info *rsp_data __free(qcom_tzmem) = NULL;
 	int status;
 
-	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*req_data),
+				    GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
+				    GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
 	req_data->attributes = attr;
@@ -679,26 +612,19 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data,
 				       sizeof(*rsp_data));
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length != sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length != sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
 			__func__, rsp_data->status);
-		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
-		goto out_free;
+		return qsee_uefi_status_to_efi(rsp_data->status);
 	}
 
 	if (storage_space)
@@ -710,12 +636,7 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
 	if (max_variable_size)
 		*max_variable_size = rsp_data->max_variable_size;
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 /* -- Global efivar interface. ---------------------------------------------- */
@@ -844,6 +765,10 @@ static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
 	if (status)
 		qcuefi_set_reference(NULL);
 
+	qcuefi->mempool = devm_qcom_tzmem_pool_new(&aux_dev->dev, SZ_256K);
+	if (IS_ERR(qcuefi->mempool))
+		return PTR_ERR(qcuefi->mempool);
+
 	return status;
 }
 
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 3a6cefb4eb2e..318d7d398e5f 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1567,9 +1567,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id);
 /**
  * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app.
  * @app_id:   The ID of the target app.
- * @req:      Request buffer sent to the app (must be DMA-mappable).
+ * @req:      Request buffer sent to the app (must be TZ memory)
  * @req_size: Size of the request buffer.
- * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
+ * @rsp:      Response buffer, written to by the app (must be TZ memory)
  * @rsp_size: Size of the response buffer.
  *
  * Sends a request to the QSEE app associated with the given ID and read back
@@ -1585,26 +1585,12 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
 {
 	struct qcom_scm_qseecom_resp res = {};
 	struct qcom_scm_desc desc = {};
-	dma_addr_t req_phys;
-	dma_addr_t rsp_phys;
+	phys_addr_t req_phys;
+	phys_addr_t rsp_phys;
 	int status;
 
-	/* Map request buffer */
-	req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE);
-	status = dma_mapping_error(__scm->dev, req_phys);
-	if (status) {
-		dev_err(__scm->dev, "qseecom: failed to map request buffer\n");
-		return status;
-	}
-
-	/* Map response buffer */
-	rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE);
-	status = dma_mapping_error(__scm->dev, rsp_phys);
-	if (status) {
-		dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
-		dev_err(__scm->dev, "qseecom: failed to map response buffer\n");
-		return status;
-	}
+	req_phys = qcom_tzmem_to_phys(req);
+	rsp_phys = qcom_tzmem_to_phys(rsp);
 
 	/* Set up SCM call data */
 	desc.owner = QSEECOM_TZ_OWNER_TZ_APPS;
@@ -1622,10 +1608,6 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
 	/* Perform call */
 	status = qcom_scm_qseecom_call(&desc, &res);
 
-	/* Unmap buffers */
-	dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE);
-	dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
-
 	if (status)
 		return status;
 
diff --git a/include/linux/firmware/qcom/qcom_qseecom.h b/include/linux/firmware/qcom/qcom_qseecom.h
index 5c28298a98be..e868fac55675 100644
--- a/include/linux/firmware/qcom/qcom_qseecom.h
+++ b/include/linux/firmware/qcom/qcom_qseecom.h
@@ -27,9 +27,9 @@ struct qseecom_client {
 /**
  * qcom_qseecom_app_send() - Send to and receive data from a given QSEE app.
  * @client:   The QSEECOM client associated with the target app.
- * @req:      Request buffer sent to the app (must be DMA-mappable).
+ * @req:      Request buffer sent to the app (must be TZ memory).
  * @req_size: Size of the request buffer.
- * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
+ * @rsp:      Response buffer, written to by the app (must be TZ memory).
  * @rsp_size: Size of the response buffer.
  *
  * Sends a request to the QSEE app associated with the given client and read
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:08 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:08 +0100
Subject: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-11-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Add a new Kconfig option for selecting the SHM Bridge mode of operation
for the TrustZone memory allocator.

If enabled at build-time, it will still be checked for availability at
run-time. If the architecture doesn't support SHM Bridge, the allocator
will work just like in the default mode.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/firmware/qcom/Kconfig      | 10 +++++
 drivers/firmware/qcom/qcom_tzmem.c | 65 +++++++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index d24d83223867..af6f895c5adf 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -28,6 +28,16 @@ config QCOM_TZMEM_MODE_DEFAULT
 	  Use the default allocator mode. The memory is page-aligned, non-cachable
 	  and contiguous.
 
+config QCOM_TZMEM_MODE_SHMBRIDGE
+	bool "SHM Bridge"
+	help
+	  Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
+	  in the 'Default' allocator but is also explicitly marked as an SHM Bridge
+	  buffer.
+
+	  With this selected, all buffers passed to the TrustZone must be allocated
+	  using the TZMem allocator or else the TrustZone will refuse to use them.
+
 endchoice
 
 config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
index 44a062f2abd4..1ca3773263e5 100644
--- a/drivers/firmware/qcom/qcom_tzmem.c
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -55,7 +55,70 @@ static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
 
 }
 
-#endif /* CONFIG_QCOM_TZMEM_MODE_DEFAULT */
+#elif IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE)
+
+#include <linux/firmware/qcom/qcom_scm.h>
+
+#define QCOM_SHM_BRIDGE_NUM_VM_SHIFT 9
+
+static bool qcom_tzmem_using_shm_bridge;
+
+static int qcom_tzmem_init(void)
+{
+	int ret;
+
+	ret = qcom_scm_shm_bridge_enable();
+	if (ret == -EOPNOTSUPP) {
+		dev_info(qcom_tzmem_dev, "SHM Bridge not supported\n");
+		return 0;
+	}
+
+	if (!ret)
+		qcom_tzmem_using_shm_bridge = true;
+
+	return ret;
+}
+
+static int qcom_tzmem_init_pool(struct qcom_tzmem_pool *pool)
+{
+	u64 pfn_and_ns_perm, ipfn_and_s_perm, size_and_flags, ns_perms;
+	int ret;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return 0;
+
+	ns_perms = (QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_READ);
+	pfn_and_ns_perm = (u64)pool->pbase | ns_perms;
+	ipfn_and_s_perm = (u64)pool->pbase | ns_perms;
+	size_and_flags = pool->size | (1 << QCOM_SHM_BRIDGE_NUM_VM_SHIFT);
+
+	u64 *handle __free(kfree) = kzalloc(sizeof(*handle), GFP_KERNEL);
+	if (!handle)
+		return -ENOMEM;
+
+	ret = qcom_scm_shm_bridge_create(qcom_tzmem_dev, pfn_and_ns_perm,
+					 ipfn_and_s_perm, size_and_flags,
+					 QCOM_SCM_VMID_HLOS, handle);
+	if (ret)
+		return ret;
+
+	pool->priv = no_free_ptr(handle);
+
+	return 0;
+}
+
+static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
+{
+	u64 *handle = pool->priv;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return;
+
+	qcom_scm_shm_bridge_delete(qcom_tzmem_dev, *handle);
+	kfree(handle);
+}
+
+#endif /* CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE */
 
 /**
  * qcom_tzmem_pool_new() - Create a new TZ memory pool.
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:09 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:09 +0100
Subject: [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-12-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

The "memory protection" mechanism mentioned in the comment is the SHM
Bridge. This is also the reason why we do not convert this call to using
the TZ memory allocator.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 839773270a21..7ba5cff6e4e7 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -563,9 +563,13 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
 	struct qcom_scm_res res;
 
 	/*
-	 * During the scm call memory protection will be enabled for the meta
-	 * data blob, so make sure it's physically contiguous, 4K aligned and
-	 * non-cachable to avoid XPU violations.
+	 * During the SCM call the hypervisor will make the buffer containing
+	 * the program data into an SHM Bridge. This is why we exceptionally
+	 * must not use the TrustZone memory allocator here as - depending on
+	 * Kconfig - it may already use the SHM Bridge mechanism internally.
+	 *
+	 * If we pass a buffer that is already part of an SHM Bridge to this
+	 * call, it will fail.
 	 */
 	mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
 				       GFP_KERNEL);
-- 
2.40.1



From brgl at bgdev.pl  Mon Feb  5 10:28:10 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon,  5 Feb 2024 19:28:10 +0100
Subject: [PATCH v7 12/12] arm64: defconfig: enable SHM Bridge support for the TZ memory allocator
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <20240205182810.58382-13-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Enable SHM Bridge support in the Qualcomm TrustZone allocator by default
as even on architectures that don't support it, we automatically fall
back to the default behavior.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index cfa3e00def09..f17bd3ea4a7f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -253,6 +253,7 @@ CONFIG_INTEL_STRATIX10_RSU=m
 CONFIG_MTK_ADSP_IPC=m
 CONFIG_EFI_CAPSULE_LOADER=y
 CONFIG_IMX_SCU=y
+CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y
 CONFIG_QCOM_QSEECOM=y
 CONFIG_QCOM_QSEECOM_UEFISECAPP=y
 CONFIG_GNSS=m
-- 
2.40.1



From jernej.skrabec at gmail.com  Mon Feb  5 10:29:08 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 05 Feb 2024 19:29:08 +0100
Subject: [PATCH 2/2] arm64: dts: allwinner: h616: Add Sipeed Longan SoM 3H and Pi
 3H board support
In-Reply-To: <Zb4zWsfzgJkZa2KQ@xhacker>
References: <20231228145647.1470-1-jszhang@kernel.org> <2589997.Lt9SDvczpP@jernej-laptop>
 <Zb4zWsfzgJkZa2KQ@xhacker>
Message-ID: <3466281.QJadu78ljV@jernej-laptop>

Dne sobota, 03. februar 2024 ob 13:36:42 CET je Jisheng Zhang napisal(a):
> On Tue, Jan 09, 2024 at 09:37:03PM +0100, Jernej ?krabec wrote:
> > Hi Jisheng,
> 
> Hi Jernej,
> 
> > 
> > Andre gave you thorough review already, so just one additional comment
> > below.
> > 
> > Dne ?etrtek, 28. december 2023 ob 15:56:47 CET je Jisheng Zhang napisal(a):
> > > The Sipeed Longan SoM 3H is a system on module based on the Allwinner
> > > H618 SoC. The SoM features:
> > > 
> > > - Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
> > > - 2/4 GiB LPDDR4 DRAM SoMs
> > > - AXP313a PMIC
> > > - eMMC
> > > 
> > > The Sipeed Longan PI 3H is a development board based on the above SoM.
> > > The board features:
> > > - Longan SoM 3H
> > > - Raspberry-Pi-1 compatible GPIO header
> > > - 2 USB 2.0 host port
> > > - 1 USB 2.0 type C port (power supply + OTG)
> > > - MicroSD slot
> > > - 1Gbps Ethernet port (via RTL8211 PHY)
> > > - HDMI port
> > > - WiFi/BT chip
> > > 
> > > Add the devicetree file describing the currently supported features,
> > > namely PMIC, LEDs, UART, SD card, eMMC, USB and Ethernet.
> > > 
> > > Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> > > ---
> > >  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
> > >  .../sun50i-h618-longan-module-3h.dtsi         |  82 +++++++++++
> > >  .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 133 ++++++++++++++++++
> > >  3 files changed, 216 insertions(+)
> > >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> > >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> > > 
> > > diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> > > index 3aca6787a167..00db504a9b8c 100644
> > > --- a/arch/arm64/boot/dts/allwinner/Makefile
> > > +++ b/arch/arm64/boot/dts/allwinner/Makefile
> > > @@ -42,4 +42,5 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
> > >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
> > >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
> > >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
> > > +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
> > >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
> > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> > > new file mode 100644
> > > index 000000000000..88a7d287b73c
> > > --- /dev/null
> > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> > > @@ -0,0 +1,82 @@
> > > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > > +/*
> > > + * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
> > > + */
> > > +
> > > +/dts-v1/;
> > > +
> > > +#include "sun50i-h616.dtsi"
> > > +
> > > +/ {
> > > +	model = "Sipeed Longan Module 3H";
> > > +	compatible = "sipeed,longan-module-3h", "allwinner,sun50i-h618";
> > > +};
> > > +
> > > +&mmc2 {
> > > +	pinctrl-names = "default";
> > > +	pinctrl-0 = <&mmc2_pins>;
> > > +	vmmc-supply = <&reg_dldo1>;
> > > +	vqmmc-supply = <&reg_aldo1>;
> > > +	bus-width = <8>;
> > > +	non-removable;
> > > +	cap-mmc-hw-reset;
> > > +	mmc-ddr-1_8v;
> > 
> > I think above is superfluous if hs200 is also defined.
> 
> I read the mmc code again, IMHO, mmc-ddr-1_8v and mmc-hs200-1_8v
> are for different caps, the former is for MMC_CAP_1_8V_DDR and
> the later is for MMC_CAP2_HS200_1_8V_SDR, I must admit that
> mmc-hs200-1_8v does imply mmc-ddr-1_8v in normal host controllers
> but they are different, and I found other dts files also contain
> both, so I kept this as is in v2.

Yeah, this was oversight. Most DTs have only second one defined.

Best regards,
Jernej

> 
> Thanks
> 
> > 
> > > +	mmc-hs200-1_8v;
> > > +	status = "okay";
> > > +};
> > > +
>  
> 






From sauravsc at amazon.com  Mon Feb  5 10:43:26 2024
From: sauravsc at amazon.com (Saurav Sachidanand)
Date: Mon, 5 Feb 2024 18:43:26 +0000
Subject: [PATCH] [RFC] KVM: arm64/vgic: Populate GICR_TYPER with Aff3
Message-ID: <20240205184326.78814-1-sauravsc@amazon.com>

According to spec, bits [63:56] of the GICR_TYPER register are supposed
to contain Affinity level 3 (Aff3) bits of the Processing Element (PE)
associated with its GIC redistributor. Linux guests on boot match PEs
with their redistributor using all four Affinity level bits from this
register.

Currently, vGIC populates GICR_TYPER with just the first three Affinity
levels of a vCPU's MPIDR. This works fine for a Linux guest that boots
with KVM's default vCPU MPIDR assignment, which also only populates till
the first three Affinity levels.

However, a hypervisor can override KVM's default MPIDR assignment by
writing directly to a vCPU's MPIDR_EL1 register. If such a hypervisor
were to populate Aff3 bits for a VM, a Linux guest booting there would
fail to match vCPUs with their vGIC redistributors, since their virtual
GICR_TYPER registers would be missing the respective Aff3 bits.

To change that, let's populate GICR_TYPER using Aff3 bits [39:32] from
the vCPU's MPIDR.

Signed-off-by: Saurav Sachidanand <sauravsc at amazon.com>
---
 arch/arm64/kvm/vgic/vgic-mmio-v3.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
index c15ee1df036a..26bc838ce14c 100644
--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
@@ -324,6 +324,7 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu,
 	u64 value;
 
 	value = (u64)(mpidr & GENMASK(23, 0)) << 32;
+	value |= (u64)((mpidr >> 32) & GENMASK(7, 0)) << 56;
 	value |= ((target_vcpu_id & 0xffff) << 8);
 
 	if (vgic_has_its(vcpu->kvm))
-- 
2.40.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879





From vmalik at redhat.com  Mon Feb  5 10:43:02 2024
From: vmalik at redhat.com (Viktor Malik)
Date: Mon, 5 Feb 2024 19:43:02 +0100
Subject: [PATCH bpf-next v4 0/3] Annotate kfuncs in .BTF_ids section
In-Reply-To: <Zb6Jt30bNcNhM6zR@surya>
References: <cover.1706491398.git.dxu@dxuuu.xyz> <Zb12EZt0BAKOPBk/@surya>
 <Zb5QWCw3Tg26_MDa@krava> <Zb6Jt30bNcNhM6zR@surya>
Message-ID: <afb2fc66-abb4-4010-8120-ada7a6881f89@redhat.com>

On 2/3/24 19:45, Manu Bretelle wrote:
> On Sat, Feb 03, 2024 at 03:40:24PM +0100, Jiri Olsa wrote:
>> On Fri, Feb 02, 2024 at 03:09:05PM -0800, Manu Bretelle wrote:
>>> On Sun, Jan 28, 2024 at 06:24:05PM -0700, Daniel Xu wrote:
>>>> === Description ===
>>>>
>>>> This is a bpf-treewide change that annotates all kfuncs as such inside
>>>> .BTF_ids. This annotation eventually allows us to automatically generate
>>>> kfunc prototypes from bpftool.
>>>>
>>>> We store this metadata inside a yet-unused flags field inside struct
>>>> btf_id_set8 (thanks Kumar!). pahole will be taught where to look.
>>>>
>>>> More details about the full chain of events are available in commit 3's
>>>> description.
>>>>
>>>> The accompanying pahole and bpftool changes can be viewed
>>>> here on these "frozen" branches [0][1].
>>>>
>>>> [0]: https://github.com/danobi/pahole/tree/kfunc_btf-v3-mailed
>>>> [1]: https://github.com/danobi/linux/tree/kfunc_bpftool-mailed
>>>
>>>
>>> I hit a similar issue to [0] on master
>>> 943b043aeecc ("selftests/bpf: Fix bench runner SIGSEGV")
>>>  when cross-compiling on x86_64 (LE) to s390x (BE).
>>> I do have CONFIG_DEBUG_INFO_BTF enable and the issue would not trigger if
>>> I disabled CONFIG_DEBUG_INFO_BTF (and with the fix mentioned in [0]).
>>>
>>> What seems to happen is that `tools/resolve_btfids` is ran in the context of the
>>> host endianess and if I printk before the WARN_ON:
>>> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
>>> index ef380e546952..a9ed7a1a4936 100644
>>>   --- a/kernel/bpf/btf.c
>>>   +++ b/kernel/bpf/btf.c
>>>   @@ -8128,6 +8128,7 @@ int register_btf_kfunc_id_set(enum bpf_prog_type prog_type,
>>>            * WARN() for initcall registrations that do not check errors.
>>>            */
>>>           if (!(kset->set->flags & BTF_SET8_KFUNCS)) {
>>>   +        printk("Flag 0x%08X, expected 0x%08X\n", kset->set->flags, BTF_SET8_KFUNCS);
>>>                   WARN_ON(!kset->owner);
>>>                   return -EINVAL;
>>>           }
>>>
>>> the boot logs would show:
>>>   Flag 0x01000000, expected 0x00000001
>>>
>>> The issue did not happen prior to
>>> 6f3189f38a3e ("bpf: treewide: Annotate BPF kfuncs in BTF")
>>> has only 0 was written before.
>>>
>>> It seems [1] will be addressing cross-compilation, but it did not fix it as is
>>> by just applying on top of master, so probably some of the changes will also need
>>> to be ported to `tools/include/linux/btf_ids.h`?
>>
>> the fix in [1] is fixing flags in set8's pairs, but not the global flags
>>
>> it looks like Viktor's fix should now also swap that as well? like in the
>> change below on top of Viktor's changes (untested)
>>
>> jirka
>>
>>
>> ---
>> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
>> index d01603ef6283..c44d57fec390 100644
>> --- a/tools/bpf/resolve_btfids/main.c
>> +++ b/tools/bpf/resolve_btfids/main.c
>> @@ -706,6 +706,8 @@ static int sets_patch(struct object *obj)
>>  			 * correctly translate everything.
>>  			 */
>>  			if (need_bswap) {
>> +				set8->flags = bswap_32(set8->flags);
>> +
>>  				for (i = 0; i < cnt; i++) {
>>  					set8->pairs[i].flags =
>>  						bswap_32(set8->pairs[i].flags);
>>
> 
> That should work. Here are a few tests I ran:
> 
> $ md5sum /tmp/kbuild-s390x/vmlinux.*
> eb658e51e089f3c5b2c8909a29dc9997  /tmp/kbuild-s390x/vmlinux.a
> # plain vmlinux before running resolv_btfids (all 0s)
> ea907cd46a1a73b8276b5f2a82af00ca  /tmp/kbuild-s390x/vmlinux.before_resolv
> # x86_64 resolv_btfids on master without Viktor's patch
> 980a40c3a3ff563d1c2d1ebdd5071a23  /tmp/kbuild-s390x/vmlinux.resolv_native
> # x86_64 resolv_btfids on master with Viktor's patch
> b986d19e242719ebea41c578235da662  /tmp/kbuild-s390x/vmlinux.resolv_native_patch_viktor
> # x86_64 resolv_btfids on master with Viktor's patch and your suggested patch
> 4edd8752ff01129945bd442689b1927b  /tmp/kbuild-s390x/vmlinux.resolv_native_patch_viktor_patched
> # s390x resolv_btfids run with qemu-s390x-static
> 4edd8752ff01129945bd442689b1927b  /tmp/kbuild-s390x/vmlinux.resolv_s390x
> 
> 
> and some hexdiff of those binaries:
> 
> 
> # difference between master's native build and s390x build.... has byte swapping for set8 and others
> diff -ruN <(xxd /tmp/kbuild-s390x/vmlinux.resolv_s390x) <(xxd /tmp/kbuild-s390x/vmlinux.resolv_native) > diff_s390x_native.diff
> https://gist.github.com/chantra/c3d58637a08a6f7340953dc155bb18cc
> 
> # difference betwee Viktor's version and  s390x build.... squinting my eyes I only see the global set8 is missing
> diff -ruN <(xxd /tmp/kbuild-s390x/vmlinux.resolv_s390x) <(xxd /tmp/kbuild-s390x/vmlinux.resolv_native_patch_viktor) > diff_s390x_native_viktor.diff
> https://gist.github.com/chantra/61cfff02b456ae72d3c0161ce1897097

Thanks for the testing Manu!

Jiri's suggested fix is now a part of [1].

Viktor

[1] https://lore.kernel.org/bpf/cover.1707157553.git.vmalik at redhat.com/

> 
> Have a good weekend all!
> 
> Manu
> 



From wahrenst at gmx.net  Mon Feb  5 10:50:44 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon, 5 Feb 2024 19:50:44 +0100
Subject: [PATCH 02/12] bcm2835-dma: Add proper 40-bit DMA support
In-Reply-To: <eeb94204c30c2182f5ffd3ec083c04399ecdee32.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
 <eeb94204c30c2182f5ffd3ec083c04399ecdee32.1706948717.git.andrea.porta@suse.com>
Message-ID: <8736c115-e11c-41ca-85eb-7cd19a205068@gmx.net>

Hi Andrea,

[add Dave]

Am 04.02.24 um 07:59 schrieb Andrea della Porta:
> From: Phil Elwell <phil at raspberrypi.org>
>
> BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
> to access the full 4GB of memory on a Pi 4.
>
> Cc: Phil Elwell <phil at raspberrypi.org>
> Cc: Maxime Ripard <maxime at cerno.tech>
> Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
mainlining isn't that simple by sending just the downstream patches to
the mailing list. In many cases there reasons why this hasn't been
upstreamed yet.

In my opinion just this feature is worth a separate patch series. In
2021 i already send an initial version, which tried to implement it in a
cleaner & maintainabler way [1]. In the meantime Dave Stevenson from
Raspberry Pi wrote that he also wanted to work on this. Maybe you want
to work on this together?

[1] -
https://lore.kernel.org/linux-arm-kernel/13ec386b-2305-27da-9765-8fa3ad71146c at i2se.com/T/


From robh at kernel.org  Mon Feb  5 10:53:49 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 5 Feb 2024 18:53:49 +0000
Subject: [PATCH v4 01/12] dt-bindings: mtd: brcmnand: Updates for bcmbca
 SoCs
In-Reply-To: <20240203002834.171462-2-william.zhang@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
 <20240203002834.171462-2-william.zhang@broadcom.com>
Message-ID: <20240205185349.GA4084919-robh@kernel.org>

On Fri, Feb 02, 2024 at 04:28:22PM -0800, William Zhang wrote:
> Update the descriptions to reflect different families of broadband SoC and
> use the general name bcmbca for ARM based SoC.
> 
> Remove the requirement of interrupts property to reflect the driver
> code and only require interrupt-names when interrupts property present.
> 
> Also add myself to the list of maintainers.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>
> 
> ---
> 
> Changes in v4:
> - Split the yaml changes into three patches. This is the first one.
> 
> Changes in v3:
> - Update brcm,nand-use-wp description
> - Revert the description change to BCM63168 SoC-specific NAND controller
> 
> Changes in v2:
> - Revert the new compatible string nand-bcmbca
> - Drop the BCM63168 compatible fix to avoid any potential ABI
> incompatibility issue
> - Simplify the explanation for brcm,nand-use-wp
> - Keep the interrupt name requirement when interrupt number is specified
> 
>  .../devicetree/bindings/mtd/brcm,brcmnand.yaml      | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)

Reviewed-by: Rob Herring <robh at kernel.org>


From geert at linux-m68k.org  Mon Feb  5 11:01:17 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 5 Feb 2024 20:01:17 +0100
Subject: [PATCH] pmdomain: mediatek: Use devm_platform_get_and_ioremap_resource()
 in init_scp()
In-Reply-To: <8f011126-c95a-4c71-8bc9-a6b0a5823c96@web.de>
References: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de> <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
 <8f011126-c95a-4c71-8bc9-a6b0a5823c96@web.de>
Message-ID: <CAMuHMdUQLWBQemtgnCHj64wCYAET8J2-MgbisyMChSbh0k0L7w@mail.gmail.com>

Hi Markus,

On Mon, Feb 5, 2024 at 6:28?PM Markus Elfring <Markus.Elfring at web.de> wrote:
> >> +++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
> >> @@ -441,8 +441,7 @@ static struct scp *init_scp(struct platform_device *pdev,
> >>
> >>         scp->dev = &pdev->dev;
> >>
> >> -       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >> -       scp->base = devm_ioremap_resource(&pdev->dev, res);
> >> +       scp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> >
> > Given res is further unused, please use devm_platform_ioremap_resource()
> > instead, and remove the local variable res.
>
> I got another idea after looking at the implementation of the function
> ?devm_platform_get_and_ioremap_resource? once more.
> https://elixir.bootlin.com/linux/v6.8-rc3/source/drivers/base/platform.c#L87
>
> It seems that it is supported to pass a null pointer for the last parameter
> (while this possibility is not mentioned in the interface description so far).
> How do you think about to benefit from such a design option any more
> (instead of the determination of a corresponding platform device)?

Yes, you can pass a NULL pointer as the last parameter.
And as this is very common, the wrapper devm_platform_ioremap_resource()
exists.

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 gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb  5 04:50:59 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 5 Feb 2024 04:50:59 -0800
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <2024020550-stipulate-washbasin-42a4@gregkh>

On Sun, Feb 04, 2024 at 12:56:44PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From wahrenst at gmx.net  Mon Feb  5 11:06:25 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon, 5 Feb 2024 20:06:25 +0100
Subject: [PATCH 00/12] Add support for BCM2712 DMA engine
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <a12a0bf1-c59d-4b87-87ac-546f0f5e8d72@gmx.net>

Hi Andrea,

Am 04.02.24 um 07:59 schrieb Andrea della Porta:
> This patchset aims to update the dma engine for BCM* chipset with respect
> to current advancements in downstream vendor tree. In particular:
>
> * Added support for BCM2712 DMA.
> * Extended DMA addressing to 40 bit. Since BCM2711 also supports 40 bit addressing,
> it will also benefit from the update.
> * Handled the devicetree node from vendor dts (e.g. "dma40").
>
> The only difference between the application of this patch and the relative code
> in vendor tree is the dropping of channel reservation for BCM2708 DMA legacy
> driver, that seems to have not made its way to upstream anyway, and it's
> probably used only from deprecated subsystems.
>
> Compile tested and runtime tested on RPi4B only.
sorry but this is not sufficient. AFAIK only the Raspberry Pi 5 has a
BCM2712. I suggest to start with BCM2711 40 bit support, which is enough
work.

This whole series does neither contain a change to the dt-bindings nor
to the DTS files. This is not how it works.

Best regards
>
> Dom Cobley (4):
>    bcm2835-dma: Support dma flags for multi-beat burst
>    bcm2835-dma: Need to keep PROT bits set in CS on 40bit controller
>    dmaengine: bcm2835: Rename to_bcm2711_cbaddr to to_40bit_cbaddr
>    bcm2835-dma: Fixes for dma_abort
>
> Maxime Ripard (2):
>    dmaengine: bcm2835: Use to_bcm2711_cbaddr where relevant
>    dmaengine: bcm2835: Support DMA-Lite channels
>
> Phil Elwell (6):
>    bcm2835-dma: Add support for per-channel flags
>    bcm2835-dma: Add proper 40-bit DMA support
>    bcm2835-dma: Add NO_WAIT_RESP, DMA_WIDE_SOURCE and DMA_WIDE_DEST flag
>    bcm2835-dma: Advertise the full DMA range
>    bcm2835-dma: Derive slave DMA addresses correctly
>    dmaengine: bcm2835: Add BCM2712 support
>
>   drivers/dma/bcm2835-dma.c | 701 ++++++++++++++++++++++++++++++++------
>   1 file changed, 588 insertions(+), 113 deletions(-)
>



From sboyd at kernel.org  Mon Feb  5 11:19:01 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 05 Feb 2024 11:19:01 -0800
Subject: [PATCH v3 7/7] of: Add KUnit test to confirm DTB is loaded
In-Reply-To: <CABVgOS=A8BQ6HHpBKFqg-N10ckk2XYavaS-MPXvZ0wenrVm=1g@mail.gmail.com>
References: <20240202195909.3458162-1-sboyd@kernel.org> <20240202195909.3458162-8-sboyd@kernel.org> <CABVgOS=A8BQ6HHpBKFqg-N10ckk2XYavaS-MPXvZ0wenrVm=1g@mail.gmail.com>
Message-ID: <89892ecd6b1b043db58258705c32b02b.sboyd@kernel.org>

Quoting David Gow (2024-02-02 20:10:17)
> On Sat, 3 Feb 2024 at 03:59, Stephen Boyd <sboyd at kernel.org> wrote:
> >
> > Add a KUnit test that confirms a DTB has been loaded, i.e. there is a
> > root node, and that the of_have_populated_dt() API works properly.
> >
> > Cc: Rob Herring <robh+dt at kernel.org>
> > Cc: Frank Rowand <frowand.list at gmail.com>
> > Cc: David Gow <davidgow at google.com>
> > Cc: Brendan Higgins <brendan.higgins at linux.dev>
> > Signed-off-by: Stephen Boyd <sboyd at kernel.org>
> > ---
> 
> This looks pretty good to me test-wise, though it still fails on m68k.
> (Everything else I tried it on works, though I've definitely not tried
> _every_ architecture.)
> 
> aarch64: PASSED
> i386: PASSED
> x86_64: PASSED
> x86_64 KASAN: PASSED
> powerpc64: PASSED
> UML: PASSED
> UML LLVM: PASSED
> m68k: FAILED
> > $ qemu-system-m68k -nodefaults -m 1024 -kernel .kunit-all-m68k/vmlinux -append 'kunit.enable=1 console=hvc0 kunit_shutdown=reboot' -no-reboot -nographic -serial stdio -machine virt
> > [11:55:05] ===================== dtb (2 subtests) =====================
> > [11:55:05] # dtb_root_node_found_by_path: EXPECTATION FAILED at drivers/of/of_test.c:18
> > [11:55:05] Expected np is not null, but is
> > [11:55:05] [FAILED] dtb_root_node_found_by_path
> > [11:55:05] # dtb_root_node_populates_of_root: EXPECTATION FAILED at drivers/of/of_test.c:28
> > [11:55:05] Expected of_root is not null, but is
> > [11:55:05] [FAILED] dtb_root_node_populates_of_root
> > [11:55:05]     # module: of_test
> > [11:55:05] # dtb: pass:0 fail:2 skip:0 total:2
> > [11:55:05] # Totals: pass:0 fail:2 skip:0 total:2
> > [11:55:05] ======================= [FAILED] dtb =======================

Ah yeah I forgot to mention that. m68k fails because it doesn't call the
unflatten_(and_copy)?_device_tree() function, so we don't populate a
root node on that architecture. One solution would be to make CONFIG_OF
unavailable on m68k. Or we have to make sure DT works on any
architecture. Rob, what do you prefer here?

> 
> 
> My only other question is about the test names: the mix of 'of' and
> 'dtb' can be a bit confusing. As is, we have:
> kconfig name: OF_KUNIT_TEST
> module name: of_test
> suite name: dtb
> test names: all start with dtb_
> 
> Given KUnit only really deals with the suite/test names directly, it's
> not trivial to see that 'dtb.dtb_*' is controlled by OF_KUNIT_TEST and
> in of_test if built as a module. (This is getting a bit easier now
> that we have the 'module' attribute in the output, but still.)
> 
> Would 'of_dtb' work as a suite name if it's important to keep both
> 'of' and 'dtb'?

Sure, I can add of_ prefix to the tests.

> 
> In general, though, this test looks good to me. Particularly if m68k
> can be fixed.
> 
> Reviewed-by: David Gow <davidgow at google.com>
> 

Thanks!


From robh at kernel.org  Mon Feb  5 11:19:15 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 5 Feb 2024 19:19:15 +0000
Subject: [PATCH V8 03/12] dt-bindings: soc: imx: add missing clock and
 power-domains to imx8mp-hdmi-blk-ctrl
In-Reply-To: <20240203165307.7806-4-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-4-aford173@gmail.com>
Message-ID: <170716075503.138486.15196612878281167365.robh@kernel.org>


On Sat, 03 Feb 2024 10:52:43 -0600, Adam Ford wrote:
> Per guidance from the NXP downstream kernel, if the clock is
> disabled before HDMI/LCDIF probe, LCDIF will not get pixel
> clock from HDMI PHY and throw an error:
> 
> [CRTC:39:crtc-2] vblank wait timed out
>     WARNING: CPU: 2 PID: 9 at drivers/gpu/drm/drm_atomic_helper.c:
>         1634 drm_atomic_helper_wait_for_vblanks.part.0+0x23c/0x260
> 
> Fix this by adding the fdcc clock to the hdmi_blk_ctrl.  This
> should be safe, since neither this power domain nor the dependent
> HDMI and LCDIF drivers been enabled or added to the SoC device
> tree yet.
> 
> According to Sandor Yu from NXP, "the FDCC clock is not for HDMITX
> in desgin, but it is part of HDMI domain that needed by HDMITX.
> So I think it is reasonable added it to the power domain driver."
> 
> The driver also supports two power domains which are missing from the binding
> that also fix an issue with resuming from suspend.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> ---
> V2:  Update commit message to both show error and give a bit more
>      background.
>      Add missing power domains hdcp and hdrv as pointed out by Marek Vasut
> ---
>  .../soc/imx/fsl,imx8mp-hdmi-blk-ctrl.yaml     | 22 ++++++++++++-------
>  1 file changed, 14 insertions(+), 8 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From robh at kernel.org  Mon Feb  5 11:23:01 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 5 Feb 2024 19:23:01 +0000
Subject: [PATCH V8 09/12] dt-bindings: display: imx: add binding for
 i.MX8MP HDMI TX
In-Reply-To: <20240203165307.7806-10-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-10-aford173@gmail.com>
Message-ID: <170716098090.168745.4661359468123158581.robh@kernel.org>


On Sat, 03 Feb 2024 10:52:49 -0600, Adam Ford wrote:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> The HDMI TX controller on the i.MX8MP SoC is a Synopsys designware IP
> core with a little bit of SoC integration around it.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 
> ---
> V3:  Change name and location to better idenfity as a bridge and
>      HDMI 2.0a transmitter
> 
>      Fix typos and feedback from Rob and added ports.
> ---
>  .../display/bridge/fsl,imx8mp-hdmi-tx.yaml    | 102 ++++++++++++++++++
>  1 file changed, 102 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From ankur.a.arora at oracle.com  Mon Feb  5 11:33:23 2024
From: ankur.a.arora at oracle.com (Ankur Arora)
Date: Mon, 05 Feb 2024 11:33:23 -0800
Subject: [PATCH 7/7] cpuidle/poll_state: replace cpu_relax with
 smp_cond_load_relaxed
In-Reply-To: <1b25b492-b9e7-4411-90d1-463d44084043@oracle.com>
References: <1700488898-12431-1-git-send-email-mihai.carabas@oracle.com>
 <1700488898-12431-8-git-send-email-mihai.carabas@oracle.com>
 <20231211114642.GB24899@willie-the-truck>
 <1b3650c5-822e-4789-81d2-0304573cabd9@oracle.com>
 <20240129181547.GA12305@willie-the-truck>
 <1b25b492-b9e7-4411-90d1-463d44084043@oracle.com>
Message-ID: <87ttmmu2nw.fsf@oracle.com>


Mihai Carabas <mihai.carabas at oracle.com> writes:

>>>>> cpu_relax on ARM64 does a simple "yield". Thus we replace it with
>>>>> smp_cond_load_relaxed which basically does a "wfe".
>>>>>
>>>>> Suggested-by: Peter Zijlstra <peterz at infradead.org>
>>>>> Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
>>>>> ---
>>>>>    drivers/cpuidle/poll_state.c | 14 +++++++++-----
>>>>>    1 file changed, 9 insertions(+), 5 deletions(-)
>>>>>
>>>>> diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c
>>>>> index 9b6d90a72601..440cd713e39a 100644
>>>>> --- a/drivers/cpuidle/poll_state.c
>>>>> +++ b/drivers/cpuidle/poll_state.c
>>>>> @@ -26,12 +26,16 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev,
>>>>>    		limit = cpuidle_poll_time(drv, dev);
>>>>> -		while (!need_resched()) {
>>>>> -			cpu_relax();
>>>>> -			if (loop_count++ < POLL_IDLE_RELAX_COUNT)
>>>>> -				continue;
>>>>> -
>>>>> +		for (;;) {
>>>>>    			loop_count = 0;
>>>>> +
>>>>> +			smp_cond_load_relaxed(&current_thread_info()->flags,
>>>>> +					      (VAL & _TIF_NEED_RESCHED) ||
>>>>> +					      (loop_count++ >= POLL_IDLE_RELAX_COUNT));
>>>>> +
>>>>> +			if (loop_count < POLL_IDLE_RELAX_COUNT)
>>>>> +				break;
>>>>> +
>>>>>    			if (local_clock_noinstr() - time_start > limit) {
>>>>>    				dev->poll_time_limit = true;
>>>>>    				break;
>>>> Doesn't this make ARCH_HAS_CPU_RELAX a complete misnomer?
>>> This controls the build of poll_state.c and the generic definition of
>>> smp_cond_load_relaxed (used by x86) is using cpu_relax(). Do you propose
>>> other approach here?
>> Give it a better name? Having ARCH_HAS_CPU_RELAX control a piece of code
>> that doesn't use cpu_relax() doesn't make sense to me.
>
> The generic code for smp_cond_load_relaxed is using cpu_relax and this one is
> used on x86 - so ARCH_HAS_CPU_RELAX is a prerequisite on x86 when using
> haltpoll. Only on ARM64 this is overwritten. Moreover ARCH_HAS_CPU_RELAX is
> controlling the function definition for cpuidle_poll_state_init (this is how it
> was originally designed).

I suspect Will's point is that the term ARCH_HAS_CPU_RELAX doesn't make
a whole lot of sense when we are only indirectly using cpu_relax() in
the series.

Also, all archs define cpu_relax() (though some as just a barrier()) so
ARCH_HAS_CPU_RELAX .

Maybe an arch can instead just opt into polling in idle?

Perhaps something like this trivial patch:

--
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5edec175b9bf..d80c98c64fd4 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -367,7 +367,7 @@ config ARCH_MAY_HAVE_PC_FDC
 config GENERIC_CALIBRATE_DELAY
 	def_bool y

-config ARCH_HAS_CPU_RELAX
+config ARCH_WANTS_IDLE_POLL
 	def_bool y

 config ARCH_HIBERNATION_POSSIBLE
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 55437f5e0c3a..6a0a1f16a5c3 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -36,7 +36,7 @@
 #include <asm/cpu.h>
 #endif

-#define ACPI_IDLE_STATE_START	(IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX) ? 1 : 0)
+#define ACPI_IDLE_STATE_START	(IS_ENABLED(CONFIG_ARCH_WANTS_IDLE_POLL) ? 1 : 0)

 static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
 module_param(max_cstate, uint, 0400);
@@ -787,7 +787,7 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr)
 	if (max_cstate == 0)
 		max_cstate = 1;

-	if (IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX)) {
+	if (IS_ENABLED(CONFIG_ARCH_WANTS_IDLE_POLL)) {
 		cpuidle_poll_state_init(drv);
 		count = 1;
 	} else {
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index d103342b7cfc..23f48d99f0f2 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -7,7 +7,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_ARCH_WANTS_IDLE_POLL)	  += poll_state.o
 obj-$(CONFIG_HALTPOLL_CPUIDLE)		  += cpuidle-haltpoll.o

 ##################################################################################
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 3183aeb7f5b4..53e55a91d55d 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -275,7 +275,7 @@ static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev,
 }
 #endif

-#if defined(CONFIG_CPU_IDLE) && defined(CONFIG_ARCH_HAS_CPU_RELAX)
+#if defined(CONFIG_CPU_IDLE) && defined(CONFIG_ARCH_WANTS_IDLE_POLL)
 void cpuidle_poll_state_init(struct cpuidle_driver *drv);
 #else
 static inline void cpuidle_poll_state_init(struct cpuidle_driver *drv) {}


From afd at ti.com  Mon Feb  5 11:44:18 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:18 -0600
Subject: [PATCH v2 00/19] Remove pm_power_off use in drivers/power/reset
Message-ID: <20240205194437.180802-1-afd@ti.com>

Hello all,

Use of pm_power_off is considered legacy and should be replaced with
register_sys_off*(). Same for register_restart_handler(). Do this
for the drivers/power/reset subsystem for all trivial cases.

Thanks,
Andrew

Changes for v2:
 - Fix sparse warning in 7/19 and 10/19
 - Add new patch fixing an already existing sparse warning (3/19)
 - Rebase on v6.8-rc3

Andrew Davis (19):
  power: reset: atc260x-poweroff: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: atc260x-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: xgene-reboot: Use devm_platform_ioremap_resource()
    helper
  power: reset: xgene-reboot: Use devm_register_sys_off_handler(RESTART)
  power: reset: tps65086-restart: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: tps65086-restart: Remove unneeded device data struct
  power: reset: brcm-kona-reset: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: axxia-reset: Use devm_register_sys_off_handler(RESTART)
  power: reset: rmobile-reset: Use devm_platform_ioremap_resource()
    helper
  power: reset: rmobile-reset: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: mt6323-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: msm-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: msm-poweroff: Use devm_register_sys_off_handler(RESTART)
  power: reset: regulator-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: as3722-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: gemini-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: restart-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: syscon-poweroff: Move device data into a struct
  power: reset: syscon-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)

 drivers/power/reset/as3722-poweroff.c    | 30 ++++-------
 drivers/power/reset/atc260x-poweroff.c   | 55 ++++++++------------
 drivers/power/reset/axxia-reset.c        | 16 +++---
 drivers/power/reset/brcm-kona-reset.c    | 11 ++--
 drivers/power/reset/gemini-poweroff.c    | 16 +++---
 drivers/power/reset/msm-poweroff.c       | 25 ++++-----
 drivers/power/reset/mt6323-poweroff.c    | 28 +++++-----
 drivers/power/reset/regulator-poweroff.c | 36 +++++--------
 drivers/power/reset/restart-poweroff.c   | 25 +++------
 drivers/power/reset/rmobile-reset.c      | 35 ++++---------
 drivers/power/reset/syscon-poweroff.c    | 66 ++++++++++++------------
 drivers/power/reset/tps65086-restart.c   | 58 ++++-----------------
 drivers/power/reset/xgene-reboot.c       | 21 +++-----
 13 files changed, 154 insertions(+), 268 deletions(-)

-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:28 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:28 -0600
Subject: [PATCH v2 10/19] power: reset: rmobile-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-11-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/rmobile-reset.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c
index 29c17ed2d4de9..80265608c18e0 100644
--- a/drivers/power/reset/rmobile-reset.c
+++ b/drivers/power/reset/rmobile-reset.c
@@ -21,22 +21,14 @@
 
 static void __iomem *sysc_base2;
 
-static int rmobile_reset_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int rmobile_reset_handler(struct sys_off_data *data)
 {
-	pr_debug("%s %lu\n", __func__, mode);
-
 	/* Let's assume we have acquired the HPB semaphore */
 	writel(RESCNT2_PRES, sysc_base2 + RESCNT2);
 
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block rmobile_reset_nb = {
-	.notifier_call = rmobile_reset_handler,
-	.priority = 192,
-};
-
 static int rmobile_reset_probe(struct platform_device *pdev)
 {
 	int error;
@@ -45,7 +37,11 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 	if (IS_ERR(sysc_base2))
 		return PTR_ERR(sysc_base2);
 
-	error = register_restart_handler(&rmobile_reset_nb);
+	error = devm_register_sys_off_handler(&pdev->dev,
+					      SYS_OFF_MODE_RESTART,
+					      SYS_OFF_PRIO_HIGH,
+					      rmobile_reset_handler,
+					      NULL);
 	if (error) {
 		dev_err(&pdev->dev,
 			"cannot register restart handler (err=%d)\n", error);
@@ -55,11 +51,6 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static void rmobile_reset_remove(struct platform_device *pdev)
-{
-	unregister_restart_handler(&rmobile_reset_nb);
-}
-
 static const struct of_device_id rmobile_reset_of_match[] = {
 	{ .compatible = "renesas,sysc-rmobile", },
 	{ /* sentinel */ }
@@ -68,7 +59,6 @@ MODULE_DEVICE_TABLE(of, rmobile_reset_of_match);
 
 static struct platform_driver rmobile_reset_driver = {
 	.probe = rmobile_reset_probe,
-	.remove_new = rmobile_reset_remove,
 	.driver = {
 		.name = "rmobile_reset",
 		.of_match_table = rmobile_reset_of_match,
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:22 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:22 -0600
Subject: [PATCH v2 04/19] power: reset: xgene-reboot: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-5-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/xgene-reboot.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
index 6b545a83d8889..867162dfe7eae 100644
--- a/drivers/power/reset/xgene-reboot.c
+++ b/drivers/power/reset/xgene-reboot.c
@@ -24,15 +24,11 @@ struct xgene_reboot_context {
 	struct device *dev;
 	void __iomem *csr;
 	u32 mask;
-	struct notifier_block restart_handler;
 };
 
-static int xgene_restart_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int xgene_restart_handler(struct sys_off_data *data)
 {
-	struct xgene_reboot_context *ctx =
-		container_of(this, struct xgene_reboot_context,
-			     restart_handler);
+	struct xgene_reboot_context *ctx = data->cb_data;
 
 	/* Issue the reboot */
 	writel(ctx->mask, ctx->csr);
@@ -64,9 +60,8 @@ static int xgene_reboot_probe(struct platform_device *pdev)
 		ctx->mask = 0xFFFFFFFF;
 
 	ctx->dev = dev;
-	ctx->restart_handler.notifier_call = xgene_restart_handler;
-	ctx->restart_handler.priority = 128;
-	err = register_restart_handler(&ctx->restart_handler);
+	err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, 128,
+					    xgene_restart_handler, ctx);
 	if (err)
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
 
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:29 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:29 -0600
Subject: [PATCH v2 11/19] power: reset: mt6323-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-12-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/mt6323-poweroff.c | 28 ++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c
index 57a63c0ab7fb7..ca5d11b17ff03 100644
--- a/drivers/power/reset/mt6323-poweroff.c
+++ b/drivers/power/reset/mt6323-poweroff.c
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/mfd/mt6397/core.h>
 #include <linux/mfd/mt6397/rtc.h>
+#include <linux/reboot.h>
 
 struct mt6323_pwrc {
 	struct device *dev;
@@ -21,11 +22,9 @@ struct mt6323_pwrc {
 	u32 base;
 };
 
-static struct mt6323_pwrc *mt_pwrc;
-
-static void mt6323_do_pwroff(void)
+static int mt6323_do_pwroff(struct sys_off_data *data)
 {
-	struct mt6323_pwrc *pwrc = mt_pwrc;
+	struct mt6323_pwrc *pwrc = data->cb_data;
 	unsigned int val;
 	int ret;
 
@@ -44,6 +43,8 @@ static void mt6323_do_pwroff(void)
 	mdelay(1000);
 
 	WARN_ONCE(1, "Unable to power off system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int mt6323_pwrc_probe(struct platform_device *pdev)
@@ -51,6 +52,7 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
 	struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
 	struct mt6323_pwrc *pwrc;
 	struct resource *res;
+	int ret;
 
 	pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
 	if (!pwrc)
@@ -63,19 +65,20 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
 	pwrc->base = res->start;
 	pwrc->regmap = mt6397_chip->regmap;
 	pwrc->dev = &pdev->dev;
-	mt_pwrc = pwrc;
 
-	pm_power_off = &mt6323_do_pwroff;
+	ret = devm_register_sys_off_handler(pwrc->dev,
+					    SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    mt6323_do_pwroff,
+					    pwrc);
+	if (ret) {
+		dev_err(pwrc->dev, "failed to register power-off handler: %d\n", ret);
+		return ret;
+	}
 
 	return 0;
 }
 
-static void mt6323_pwrc_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &mt6323_do_pwroff)
-		pm_power_off = NULL;
-}
-
 static const struct of_device_id mt6323_pwrc_dt_match[] = {
 	{ .compatible = "mediatek,mt6323-pwrc" },
 	{},
@@ -84,7 +87,6 @@ MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match);
 
 static struct platform_driver mt6323_pwrc_driver = {
 	.probe          = mt6323_pwrc_probe,
-	.remove_new     = mt6323_pwrc_remove,
 	.driver         = {
 		.name   = "mt6323-pwrc",
 		.of_match_table = mt6323_pwrc_dt_match,
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:27 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:27 -0600
Subject: [PATCH v2 09/19] power: reset: rmobile-reset: Use devm_platform_ioremap_resource() helper
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-10-afd@ti.com>

Use device life-cycle managed ioremap function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/rmobile-reset.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c
index 5df9b41c68c79..29c17ed2d4de9 100644
--- a/drivers/power/reset/rmobile-reset.c
+++ b/drivers/power/reset/rmobile-reset.c
@@ -41,28 +41,23 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 {
 	int error;
 
-	sysc_base2 = of_iomap(pdev->dev.of_node, 1);
-	if (!sysc_base2)
-		return -ENODEV;
+	sysc_base2 = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(sysc_base2))
+		return PTR_ERR(sysc_base2);
 
 	error = register_restart_handler(&rmobile_reset_nb);
 	if (error) {
 		dev_err(&pdev->dev,
 			"cannot register restart handler (err=%d)\n", error);
-		goto fail_unmap;
+		return error;
 	}
 
 	return 0;
-
-fail_unmap:
-	iounmap(sysc_base2);
-	return error;
 }
 
 static void rmobile_reset_remove(struct platform_device *pdev)
 {
 	unregister_restart_handler(&rmobile_reset_nb);
-	iounmap(sysc_base2);
 }
 
 static const struct of_device_id rmobile_reset_of_match[] = {
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:30 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:30 -0600
Subject: [PATCH v2 12/19] power: reset: msm-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-13-afd@ti.com>

Use this helper to register sys_off handler. Drivers should move away from
setting pm_power_off directly as it only allows for one handler. The new
way allows for trying multiple if the first one doesn't work.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/msm-poweroff.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index d96d248a6e25b..bcf04491e7022 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -28,9 +28,11 @@ static struct notifier_block restart_nb = {
 	.priority = 128,
 };
 
-static void do_msm_poweroff(void)
+static int do_msm_poweroff(struct sys_off_data *data)
 {
 	deassert_pshold(&restart_nb, 0, NULL);
+
+	return NOTIFY_DONE;
 }
 
 static int msm_restart_probe(struct platform_device *pdev)
@@ -41,7 +43,9 @@ static int msm_restart_probe(struct platform_device *pdev)
 
 	register_restart_handler(&restart_nb);
 
-	pm_power_off = do_msm_poweroff;
+	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
+				      SYS_OFF_PRIO_DEFAULT, do_msm_poweroff,
+				      msm_ps_hold);
 
 	return 0;
 }
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:33 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:33 -0600
Subject: [PATCH v2 15/19] power: reset: as3722-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-16-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/as3722-poweroff.c | 30 ++++++++++-----------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/power/reset/as3722-poweroff.c b/drivers/power/reset/as3722-poweroff.c
index ab3350ce2d621..bb26fa6fa67ca 100644
--- a/drivers/power/reset/as3722-poweroff.c
+++ b/drivers/power/reset/as3722-poweroff.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/slab.h>
 
 struct as3722_poweroff {
@@ -18,22 +19,18 @@ struct as3722_poweroff {
 	struct as3722 *as3722;
 };
 
-static struct as3722_poweroff *as3722_pm_poweroff;
-
-static void as3722_pm_power_off(void)
+static int as3722_pm_power_off(struct sys_off_data *data)
 {
+	struct as3722_poweroff *as3722_pm_poweroff = data->cb_data;
 	int ret;
 
-	if (!as3722_pm_poweroff) {
-		pr_err("AS3722 poweroff is not initialised\n");
-		return;
-	}
-
 	ret = as3722_update_bits(as3722_pm_poweroff->as3722,
 		AS3722_RESET_CONTROL_REG, AS3722_POWER_OFF, AS3722_POWER_OFF);
 	if (ret < 0)
 		dev_err(as3722_pm_poweroff->dev,
 			"RESET_CONTROL_REG update failed, %d\n", ret);
+
+	return NOTIFY_DONE;
 }
 
 static int as3722_poweroff_probe(struct platform_device *pdev)
@@ -54,18 +51,14 @@ static int as3722_poweroff_probe(struct platform_device *pdev)
 
 	as3722_poweroff->as3722 = dev_get_drvdata(pdev->dev.parent);
 	as3722_poweroff->dev = &pdev->dev;
-	as3722_pm_poweroff = as3722_poweroff;
-	if (!pm_power_off)
-		pm_power_off = as3722_pm_power_off;
 
-	return 0;
-}
+	return devm_register_sys_off_handler(as3722_poweroff->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_DEFAULT,
+					     as3722_pm_power_off,
+					     as3722_poweroff);
 
-static void as3722_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == as3722_pm_power_off)
-		pm_power_off = NULL;
-	as3722_pm_poweroff = NULL;
+	return 0;
 }
 
 static struct platform_driver as3722_poweroff_driver = {
@@ -73,7 +66,6 @@ static struct platform_driver as3722_poweroff_driver = {
 		.name = "as3722-power-off",
 	},
 	.probe = as3722_poweroff_probe,
-	.remove_new = as3722_poweroff_remove,
 };
 
 module_platform_driver(as3722_poweroff_driver);
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:23 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:23 -0600
Subject: [PATCH v2 05/19] power: reset: tps65086-restart: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-6-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/tps65086-restart.c | 35 ++++++--------------------
 1 file changed, 7 insertions(+), 28 deletions(-)

diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c
index ee8e9f4b837ea..82d7a761a0385 100644
--- a/drivers/power/reset/tps65086-restart.c
+++ b/drivers/power/reset/tps65086-restart.c
@@ -10,15 +10,12 @@
 #include <linux/reboot.h>
 
 struct tps65086_restart {
-	struct notifier_block handler;
 	struct device *dev;
 };
 
-static int tps65086_restart_notify(struct notifier_block *this,
-				   unsigned long mode, void *cmd)
+static int tps65086_restart_notify(struct sys_off_data *data)
 {
-	struct tps65086_restart *tps65086_restart =
-		container_of(this, struct tps65086_restart, handler);
+	struct tps65086_restart *tps65086_restart = data->cb_data;
 	struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent);
 	int ret;
 
@@ -46,13 +43,13 @@ static int tps65086_restart_probe(struct platform_device *pdev)
 	if (!tps65086_restart)
 		return -ENOMEM;
 
-	platform_set_drvdata(pdev, tps65086_restart);
-
-	tps65086_restart->handler.notifier_call = tps65086_restart_notify;
-	tps65086_restart->handler.priority = 192;
 	tps65086_restart->dev = &pdev->dev;
 
-	ret = register_restart_handler(&tps65086_restart->handler);
+	ret = devm_register_sys_off_handler(&pdev->dev,
+					    SYS_OFF_MODE_RESTART,
+					    SYS_OFF_PRIO_HIGH,
+					    tps65086_restart_notify,
+					    tps65086_restart);
 	if (ret) {
 		dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
 			__func__, ret);
@@ -62,23 +59,6 @@ static int tps65086_restart_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static void tps65086_restart_remove(struct platform_device *pdev)
-{
-	struct tps65086_restart *tps65086_restart = platform_get_drvdata(pdev);
-	int ret;
-
-	ret = unregister_restart_handler(&tps65086_restart->handler);
-	if (ret) {
-		/*
-		 * tps65086_restart_probe() registered the restart handler. So
-		 * unregistering should work fine. Checking the error code
-		 * shouldn't be needed, still doing it for completeness.
-		 */
-		dev_err(&pdev->dev, "%s: cannot unregister restart handler: %d\n",
-			__func__, ret);
-	}
-}
-
 static const struct platform_device_id tps65086_restart_id_table[] = {
 	{ "tps65086-reset", },
 	{ /* sentinel */ }
@@ -90,7 +70,6 @@ static struct platform_driver tps65086_restart_driver = {
 		.name = "tps65086-restart",
 	},
 	.probe = tps65086_restart_probe,
-	.remove_new = tps65086_restart_remove,
 	.id_table = tps65086_restart_id_table,
 };
 module_platform_driver(tps65086_restart_driver);
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:24 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:24 -0600
Subject: [PATCH v2 06/19] power: reset: tps65086-restart: Remove unneeded device data struct
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-7-afd@ti.com>

We only need one member of the struct tps65086_restart, pass that
tps65086_restart_notify() directly. Remove that struct and its
allocation.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/tps65086-restart.c | 35 ++++++--------------------
 1 file changed, 8 insertions(+), 27 deletions(-)

diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c
index 82d7a761a0385..6976dbcac74fa 100644
--- a/drivers/power/reset/tps65086-restart.c
+++ b/drivers/power/reset/tps65086-restart.c
@@ -9,19 +9,14 @@
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
 
-struct tps65086_restart {
-	struct device *dev;
-};
-
 static int tps65086_restart_notify(struct sys_off_data *data)
 {
-	struct tps65086_restart *tps65086_restart = data->cb_data;
-	struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent);
+	struct tps65086 *tps65086 = data->cb_data;
 	int ret;
 
 	ret = regmap_write(tps65086->regmap, TPS65086_FORCESHUTDN, 1);
 	if (ret) {
-		dev_err(tps65086_restart->dev, "%s: error writing to tps65086 pmic: %d\n",
+		dev_err(tps65086->dev, "%s: error writing to tps65086 pmic: %d\n",
 			__func__, ret);
 		return NOTIFY_DONE;
 	}
@@ -36,27 +31,13 @@ static int tps65086_restart_notify(struct sys_off_data *data)
 
 static int tps65086_restart_probe(struct platform_device *pdev)
 {
-	struct tps65086_restart *tps65086_restart;
-	int ret;
-
-	tps65086_restart = devm_kzalloc(&pdev->dev, sizeof(*tps65086_restart), GFP_KERNEL);
-	if (!tps65086_restart)
-		return -ENOMEM;
-
-	tps65086_restart->dev = &pdev->dev;
-
-	ret = devm_register_sys_off_handler(&pdev->dev,
-					    SYS_OFF_MODE_RESTART,
-					    SYS_OFF_PRIO_HIGH,
-					    tps65086_restart_notify,
-					    tps65086_restart);
-	if (ret) {
-		dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
-			__func__, ret);
-		return -ENODEV;
-	}
+	struct tps65086 *tps65086 = dev_get_drvdata(pdev->dev.parent);
 
-	return 0;
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_RESTART,
+					     SYS_OFF_PRIO_HIGH,
+					     tps65086_restart_notify,
+					     tps65086);
 }
 
 static const struct platform_device_id tps65086_restart_id_table[] = {
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:19 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:19 -0600
Subject: [PATCH v2 01/19] power: reset: atc260x-poweroff: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-2-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/atc260x-poweroff.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/power/reset/atc260x-poweroff.c b/drivers/power/reset/atc260x-poweroff.c
index b4aa50e9685e1..ce2748d3282c3 100644
--- a/drivers/power/reset/atc260x-poweroff.c
+++ b/drivers/power/reset/atc260x-poweroff.c
@@ -16,7 +16,6 @@
 struct atc260x_pwrc {
 	struct device *dev;
 	struct regmap *regmap;
-	struct notifier_block restart_nb;
 	int (*do_poweroff)(const struct atc260x_pwrc *pwrc, bool restart);
 };
 
@@ -172,11 +171,9 @@ static void atc260x_pwrc_pm_handler(void)
 	WARN_ONCE(1, "Unable to power off system\n");
 }
 
-static int atc260x_pwrc_restart_handler(struct notifier_block *nb,
-					unsigned long mode, void *cmd)
+static int atc260x_pwrc_restart_handler(struct sys_off_data *data)
 {
-	struct atc260x_pwrc *pwrc = container_of(nb, struct atc260x_pwrc,
-						 restart_nb);
+	struct atc260x_pwrc *pwrc = data->cb_data;
 	pwrc->do_poweroff(pwrc, true);
 
 	return NOTIFY_DONE;
@@ -194,8 +191,6 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 
 	priv->dev = &pdev->dev;
 	priv->regmap = atc260x->regmap;
-	priv->restart_nb.notifier_call = atc260x_pwrc_restart_handler;
-	priv->restart_nb.priority = 192;
 
 	switch (atc260x->ic_type) {
 	case ATC2603C:
@@ -225,7 +220,11 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 		dev_warn(priv->dev, "Poweroff callback already assigned\n");
 	}
 
-	ret = register_restart_handler(&priv->restart_nb);
+	ret = devm_register_sys_off_handler(priv->dev,
+					    SYS_OFF_MODE_RESTART,
+					    SYS_OFF_PRIO_HIGH,
+					    atc260x_pwrc_restart_handler,
+					    priv);
 	if (ret)
 		dev_err(priv->dev, "failed to register restart handler: %d\n",
 			ret);
@@ -241,8 +240,6 @@ static void atc260x_pwrc_remove(struct platform_device *pdev)
 		pm_power_off = NULL;
 		atc260x_pwrc_data = NULL;
 	}
-
-	unregister_restart_handler(&priv->restart_nb);
 }
 
 static struct platform_driver atc260x_pwrc_driver = {
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:35 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:35 -0600
Subject: [PATCH v2 17/19] power: reset: restart-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-18-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/restart-poweroff.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
index f4d6004793d3a..fcd588f9ae9d3 100644
--- a/drivers/power/reset/restart-poweroff.c
+++ b/drivers/power/reset/restart-poweroff.c
@@ -14,29 +14,21 @@
 #include <linux/module.h>
 #include <linux/reboot.h>
 
-static void restart_poweroff_do_poweroff(void)
+static int restart_poweroff_do_poweroff(struct sys_off_data *data)
 {
 	reboot_mode = REBOOT_HARD;
 	machine_restart(NULL);
+	return NOTIFY_DONE;
 }
 
 static int restart_poweroff_probe(struct platform_device *pdev)
 {
-	/* If a pm_power_off function has already been added, leave it alone */
-	if (pm_power_off != NULL) {
-		dev_err(&pdev->dev,
-			"pm_power_off function already registered");
-		return -EBUSY;
-	}
-
-	pm_power_off = &restart_poweroff_do_poweroff;
-	return 0;
-}
-
-static void restart_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &restart_poweroff_do_poweroff)
-		pm_power_off = NULL;
+	/* Set this handler to low priority to not override an existing handler */
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_LOW,
+					     restart_poweroff_do_poweroff,
+					     NULL);
 }
 
 static const struct of_device_id of_restart_poweroff_match[] = {
@@ -47,7 +39,6 @@ MODULE_DEVICE_TABLE(of, of_restart_poweroff_match);
 
 static struct platform_driver restart_poweroff_driver = {
 	.probe = restart_poweroff_probe,
-	.remove_new = restart_poweroff_remove,
 	.driver = {
 		.name = "poweroff-restart",
 		.of_match_table = of_restart_poweroff_match,
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:26 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:26 -0600
Subject: [PATCH v2 08/19] power: reset: axxia-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-9-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/axxia-reset.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/power/reset/axxia-reset.c b/drivers/power/reset/axxia-reset.c
index 24946766760c3..797bf6773860e 100644
--- a/drivers/power/reset/axxia-reset.c
+++ b/drivers/power/reset/axxia-reset.c
@@ -26,11 +26,10 @@
 #define SC_EFUSE_INT_STATUS	0x180c
 #define   EFUSE_READ_DONE	(1<<31)
 
-static struct regmap *syscon;
-
-static int axxia_restart_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int axxia_restart_handler(struct sys_off_data *data)
 {
+	struct regmap *syscon = data->cb_data;
+
 	/* Access Key (0xab) */
 	regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab);
 	/* Select internal boot from 0xffff0000 */
@@ -44,14 +43,10 @@ static int axxia_restart_handler(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block axxia_restart_nb = {
-	.notifier_call = axxia_restart_handler,
-	.priority = 128,
-};
-
 static int axxia_reset_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct regmap *syscon;
 	int err;
 
 	syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
@@ -60,7 +55,8 @@ static int axxia_reset_probe(struct platform_device *pdev)
 		return PTR_ERR(syscon);
 	}
 
-	err = register_restart_handler(&axxia_restart_nb);
+	err = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+					    128, axxia_restart_handler, syscon);
 	if (err)
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
 
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:37 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:37 -0600
Subject: [PATCH v2 19/19] power: reset: syscon-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-20-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/syscon-poweroff.c | 34 ++++++++++++---------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
index 4899a019256e8..203936f4c544f 100644
--- a/drivers/power/reset/syscon-poweroff.c
+++ b/drivers/power/reset/syscon-poweroff.c
@@ -13,6 +13,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+#include <linux/reboot.h>
 #include <linux/regmap.h>
 
 struct syscon_poweroff_data {
@@ -22,23 +23,30 @@ struct syscon_poweroff_data {
 	u32 mask;
 };
 
-static struct syscon_poweroff_data *data;
-
-static void syscon_poweroff(void)
+static int syscon_poweroff(struct sys_off_data *off_data)
 {
+	struct syscon_poweroff_data *data = off_data->cb_data;
+
 	/* Issue the poweroff */
 	regmap_update_bits(data->map, data->offset, data->mask, data->value);
 
 	mdelay(1000);
 
 	pr_emerg("Unable to poweroff system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int syscon_poweroff_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct syscon_poweroff_data *data;
 	int mask_err, value_err;
 
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
 	data->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
 	if (IS_ERR(data->map)) {
 		data->map = syscon_node_to_regmap(dev->parent->of_node);
@@ -69,21 +77,10 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 		data->mask = 0xFFFFFFFF;
 	}
 
-	if (pm_power_off) {
-		dev_err(dev, "pm_power_off already claimed for %ps",
-			pm_power_off);
-		return -EBUSY;
-	}
-
-	pm_power_off = syscon_poweroff;
-
-	return 0;
-}
-
-static void syscon_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == syscon_poweroff)
-		pm_power_off = NULL;
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_DEFAULT,
+					     syscon_poweroff, data);
 }
 
 static const struct of_device_id syscon_poweroff_of_match[] = {
@@ -93,7 +90,6 @@ static const struct of_device_id syscon_poweroff_of_match[] = {
 
 static struct platform_driver syscon_poweroff_driver = {
 	.probe = syscon_poweroff_probe,
-	.remove_new = syscon_poweroff_remove,
 	.driver = {
 		.name = "syscon-poweroff",
 		.of_match_table = syscon_poweroff_of_match,
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:31 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:31 -0600
Subject: [PATCH v2 13/19] power: reset: msm-poweroff: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-14-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/msm-poweroff.c | 23 ++++++-----------------
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index bcf04491e7022..c5831c46f69e2 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -13,35 +13,24 @@
 #include <linux/reboot.h>
 #include <linux/pm.h>
 
-static void __iomem *msm_ps_hold;
-static int deassert_pshold(struct notifier_block *nb, unsigned long action,
-			   void *data)
+static int do_msm_poweroff(struct sys_off_data *data)
 {
+	void __iomem *msm_ps_hold = data->cb_data;
+
 	writel(0, msm_ps_hold);
 	mdelay(10000);
 
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block restart_nb = {
-	.notifier_call = deassert_pshold,
-	.priority = 128,
-};
-
-static int do_msm_poweroff(struct sys_off_data *data)
-{
-	deassert_pshold(&restart_nb, 0, NULL);
-
-	return NOTIFY_DONE;
-}
-
 static int msm_restart_probe(struct platform_device *pdev)
 {
-	msm_ps_hold = devm_platform_ioremap_resource(pdev, 0);
+	void __iomem *msm_ps_hold = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(msm_ps_hold))
 		return PTR_ERR(msm_ps_hold);
 
-	register_restart_handler(&restart_nb);
+	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+				      128, do_msm_poweroff, msm_ps_hold);
 
 	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
 				      SYS_OFF_PRIO_DEFAULT, do_msm_poweroff,
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:32 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:32 -0600
Subject: [PATCH v2 14/19] power: reset: regulator-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-15-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/regulator-poweroff.c | 36 +++++++++---------------
 1 file changed, 13 insertions(+), 23 deletions(-)

diff --git a/drivers/power/reset/regulator-poweroff.c b/drivers/power/reset/regulator-poweroff.c
index 15160809c423a..fed4978e38580 100644
--- a/drivers/power/reset/regulator-poweroff.c
+++ b/drivers/power/reset/regulator-poweroff.c
@@ -13,18 +13,15 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+#include <linux/reboot.h>
 #include <linux/regulator/consumer.h>
 
 #define TIMEOUT_MS 3000
 
-/*
- * Hold configuration here, cannot be more than one instance of the driver
- * since pm_power_off itself is global.
- */
-static struct regulator *cpu_regulator;
-
-static void regulator_poweroff_do_poweroff(void)
+static int regulator_poweroff_do_poweroff(struct sys_off_data *data)
 {
+	struct regulator *cpu_regulator = data->cb_data;
+
 	if (cpu_regulator && regulator_is_enabled(cpu_regulator))
 		regulator_force_disable(cpu_regulator);
 
@@ -32,30 +29,24 @@ static void regulator_poweroff_do_poweroff(void)
 	mdelay(TIMEOUT_MS);
 
 	WARN_ON(1);
+
+	return NOTIFY_DONE;
 }
 
 static int regulator_poweroff_probe(struct platform_device *pdev)
 {
-	/* If a pm_power_off function has already been added, leave it alone */
-	if (pm_power_off != NULL) {
-		dev_err(&pdev->dev,
-			"%s: pm_power_off function already registered\n",
-			__func__);
-		return -EBUSY;
-	}
+	struct regulator *cpu_regulator;
 
 	cpu_regulator = devm_regulator_get(&pdev->dev, "cpu");
 	if (IS_ERR(cpu_regulator))
 		return PTR_ERR(cpu_regulator);
 
-	pm_power_off = &regulator_poweroff_do_poweroff;
-	return 0;
-}
-
-static void regulator_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &regulator_poweroff_do_poweroff)
-		pm_power_off = NULL;
+	/* Set this handler to low priority to not override an existing handler */
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_LOW,
+					     regulator_poweroff_do_poweroff,
+					     cpu_regulator);
 }
 
 static const struct of_device_id of_regulator_poweroff_match[] = {
@@ -66,7 +57,6 @@ MODULE_DEVICE_TABLE(of, of_regulator_poweroff_match);
 
 static struct platform_driver regulator_poweroff_driver = {
 	.probe = regulator_poweroff_probe,
-	.remove_new = regulator_poweroff_remove,
 	.driver = {
 		.name = "poweroff-regulator",
 		.of_match_table = of_regulator_poweroff_match,
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:21 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:21 -0600
Subject: [PATCH v2 03/19] power: reset: xgene-reboot: Use devm_platform_ioremap_resource() helper
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-4-afd@ti.com>

Use device life-cycle managed ioremap function to simplify probe and
exit paths.

While here add __iomem to the returned pointer to fix a sparse warning.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/xgene-reboot.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
index c2e5a99940d37..6b545a83d8889 100644
--- a/drivers/power/reset/xgene-reboot.c
+++ b/drivers/power/reset/xgene-reboot.c
@@ -22,7 +22,7 @@
 
 struct xgene_reboot_context {
 	struct device *dev;
-	void *csr;
+	void __iomem *csr;
 	u32 mask;
 	struct notifier_block restart_handler;
 };
@@ -54,7 +54,7 @@ static int xgene_reboot_probe(struct platform_device *pdev)
 	if (!ctx)
 		return -ENOMEM;
 
-	ctx->csr = of_iomap(dev->of_node, 0);
+	ctx->csr = devm_platform_ioremap_resource(pdev, 0);
 	if (!ctx->csr) {
 		dev_err(dev, "can not map resource\n");
 		return -ENODEV;
@@ -67,10 +67,8 @@ static int xgene_reboot_probe(struct platform_device *pdev)
 	ctx->restart_handler.notifier_call = xgene_restart_handler;
 	ctx->restart_handler.priority = 128;
 	err = register_restart_handler(&ctx->restart_handler);
-	if (err) {
-		iounmap(ctx->csr);
+	if (err)
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
-	}
 
 	return err;
 }
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:25 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:25 -0600
Subject: [PATCH v2 07/19] power: reset: brcm-kona-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-8-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/brcm-kona-reset.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/power/reset/brcm-kona-reset.c b/drivers/power/reset/brcm-kona-reset.c
index d05728b1db097..ee3f1bb976530 100644
--- a/drivers/power/reset/brcm-kona-reset.c
+++ b/drivers/power/reset/brcm-kona-reset.c
@@ -15,8 +15,7 @@
 
 static void __iomem *kona_reset_base;
 
-static int kona_reset_handler(struct notifier_block *this,
-				unsigned long mode, void *cmd)
+static int kona_reset_handler(struct sys_off_data *data)
 {
 	/*
 	 * A soft reset is triggered by writing a 0 to bit 0 of the soft reset
@@ -31,18 +30,14 @@ static int kona_reset_handler(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block kona_reset_nb = {
-	.notifier_call = kona_reset_handler,
-	.priority = 128,
-};
-
 static int kona_reset_probe(struct platform_device *pdev)
 {
 	kona_reset_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(kona_reset_base))
 		return PTR_ERR(kona_reset_base);
 
-	return register_restart_handler(&kona_reset_nb);
+	return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+					     128, kona_reset_handler, NULL);
 }
 
 static const struct of_device_id of_match[] = {
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:34 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:34 -0600
Subject: [PATCH v2 16/19] power: reset: gemini-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-17-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/gemini-poweroff.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/power/reset/gemini-poweroff.c b/drivers/power/reset/gemini-poweroff.c
index d309b610142ce..06d6992dec892 100644
--- a/drivers/power/reset/gemini-poweroff.c
+++ b/drivers/power/reset/gemini-poweroff.c
@@ -70,12 +70,9 @@ static irqreturn_t gemini_powerbutton_interrupt(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-/* This callback needs this static local as it has void as argument */
-static struct gemini_powercon *gpw_poweroff;
-
-static void gemini_poweroff(void)
+static int gemini_poweroff(struct sys_off_data *data)
 {
-	struct gemini_powercon *gpw = gpw_poweroff;
+	struct gemini_powercon *gpw = data->cb_data;
 	u32 val;
 
 	dev_crit(gpw->dev, "Gemini power off\n");
@@ -86,6 +83,8 @@ static void gemini_poweroff(void)
 	val &= ~GEMINI_CTRL_ENABLE;
 	val |= GEMINI_CTRL_SHUTDOWN;
 	writel(val, gpw->base + GEMINI_PWC_CTRLREG);
+
+	return NOTIFY_DONE;
 }
 
 static int gemini_poweroff_probe(struct platform_device *pdev)
@@ -148,8 +147,11 @@ static int gemini_poweroff_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	pm_power_off = gemini_poweroff;
-	gpw_poweroff = gpw;
+	ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    gemini_poweroff, gpw);
+	if (ret)
+		return ret;
 
 	dev_info(dev, "Gemini poweroff driver registered\n");
 
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:20 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:20 -0600
Subject: [PATCH v2 02/19] power: reset: atc260x-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-3-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/atc260x-poweroff.c | 38 ++++++++++----------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/drivers/power/reset/atc260x-poweroff.c b/drivers/power/reset/atc260x-poweroff.c
index ce2748d3282c3..e3e4621ccb1dd 100644
--- a/drivers/power/reset/atc260x-poweroff.c
+++ b/drivers/power/reset/atc260x-poweroff.c
@@ -19,9 +19,6 @@ struct atc260x_pwrc {
 	int (*do_poweroff)(const struct atc260x_pwrc *pwrc, bool restart);
 };
 
-/* Global variable needed only for pm_power_off */
-static struct atc260x_pwrc *atc260x_pwrc_data;
-
 static int atc2603c_do_poweroff(const struct atc260x_pwrc *pwrc, bool restart)
 {
 	int ret, deep_sleep = 0;
@@ -164,11 +161,15 @@ static int atc2609a_init(const struct atc260x_pwrc *pwrc)
 	return ret;
 }
 
-static void atc260x_pwrc_pm_handler(void)
+static int atc260x_pwrc_pm_handler(struct sys_off_data *data)
 {
-	atc260x_pwrc_data->do_poweroff(atc260x_pwrc_data, false);
+	struct atc260x_pwrc *pwrc = data->cb_data;
+
+	pwrc->do_poweroff(pwrc, false);
 
 	WARN_ONCE(1, "Unable to power off system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int atc260x_pwrc_restart_handler(struct sys_off_data *data)
@@ -211,14 +212,14 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	platform_set_drvdata(pdev, priv);
-
-	if (!pm_power_off) {
-		atc260x_pwrc_data = priv;
-		pm_power_off = atc260x_pwrc_pm_handler;
-	} else {
-		dev_warn(priv->dev, "Poweroff callback already assigned\n");
-	}
+	ret = devm_register_sys_off_handler(priv->dev,
+					    SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    atc260x_pwrc_pm_handler,
+					    priv);
+	if (ret)
+		dev_err(priv->dev, "failed to register power-off handler: %d\n",
+			ret);
 
 	ret = devm_register_sys_off_handler(priv->dev,
 					    SYS_OFF_MODE_RESTART,
@@ -232,19 +233,8 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static void atc260x_pwrc_remove(struct platform_device *pdev)
-{
-	struct atc260x_pwrc *priv = platform_get_drvdata(pdev);
-
-	if (atc260x_pwrc_data == priv) {
-		pm_power_off = NULL;
-		atc260x_pwrc_data = NULL;
-	}
-}
-
 static struct platform_driver atc260x_pwrc_driver = {
 	.probe = atc260x_pwrc_probe,
-	.remove_new = atc260x_pwrc_remove,
 	.driver = {
 		.name = "atc260x-pwrc",
 	},
-- 
2.39.2



From afd at ti.com  Mon Feb  5 11:44:36 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 13:44:36 -0600
Subject: [PATCH v2 18/19] power: reset: syscon-poweroff: Move device data into a struct
In-Reply-To: <20240205194437.180802-1-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
Message-ID: <20240205194437.180802-19-afd@ti.com>

Currently all these device data elements are top level global variables.
Move these into a struct. This will be used in the next patch when
the global variable usage is removed. Doing this in two steps makes
the patches easier to read.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/syscon-poweroff.c | 36 +++++++++++++++------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
index 1b2ce7734260c..4899a019256e8 100644
--- a/drivers/power/reset/syscon-poweroff.c
+++ b/drivers/power/reset/syscon-poweroff.c
@@ -15,15 +15,19 @@
 #include <linux/pm.h>
 #include <linux/regmap.h>
 
-static struct regmap *map;
-static u32 offset;
-static u32 value;
-static u32 mask;
+struct syscon_poweroff_data {
+	struct regmap *map;
+	u32 offset;
+	u32 value;
+	u32 mask;
+};
+
+static struct syscon_poweroff_data *data;
 
 static void syscon_poweroff(void)
 {
 	/* Issue the poweroff */
-	regmap_update_bits(map, offset, mask, value);
+	regmap_update_bits(data->map, data->offset, data->mask, data->value);
 
 	mdelay(1000);
 
@@ -35,22 +39,22 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	int mask_err, value_err;
 
-	map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
-	if (IS_ERR(map)) {
-		map = syscon_node_to_regmap(dev->parent->of_node);
-		if (IS_ERR(map)) {
+	data->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
+	if (IS_ERR(data->map)) {
+		data->map = syscon_node_to_regmap(dev->parent->of_node);
+		if (IS_ERR(data->map)) {
 			dev_err(dev, "unable to get syscon");
-			return PTR_ERR(map);
+			return PTR_ERR(data->map);
 		}
 	}
 
-	if (of_property_read_u32(dev->of_node, "offset", &offset)) {
+	if (of_property_read_u32(dev->of_node, "offset", &data->offset)) {
 		dev_err(dev, "unable to read 'offset'");
 		return -EINVAL;
 	}
 
-	value_err = of_property_read_u32(dev->of_node, "value", &value);
-	mask_err = of_property_read_u32(dev->of_node, "mask", &mask);
+	value_err = of_property_read_u32(dev->of_node, "value", &data->value);
+	mask_err = of_property_read_u32(dev->of_node, "mask", &data->mask);
 	if (value_err && mask_err) {
 		dev_err(dev, "unable to read 'value' and 'mask'");
 		return -EINVAL;
@@ -58,11 +62,11 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 
 	if (value_err) {
 		/* support old binding */
-		value = mask;
-		mask = 0xFFFFFFFF;
+		data->value = data->mask;
+		data->mask = 0xFFFFFFFF;
 	} else if (mask_err) {
 		/* support value without mask*/
-		mask = 0xFFFFFFFF;
+		data->mask = 0xFFFFFFFF;
 	}
 
 	if (pm_power_off) {
-- 
2.39.2



From b-brnich at ti.com  Mon Feb  5 11:47:02 2024
From: b-brnich at ti.com (Brandon Brnich)
Date: Mon, 5 Feb 2024 13:47:02 -0600
Subject: [PATCH v4 0/4] Add Support for Wave5 on TI Devices
Message-ID: <20240205194706.3605309-1-b-brnich@ti.com>

This series is responsible for adding support for Wave5 driver[0]
across numerous TI K3 platforms.

[0]: https://lore.kernel.org/all/ae6d2ad3-0b2a-462a-a9eb-9ce01e7a7f5e at xs4all.nl/

Changes since v3:
=================

* Address Andrew's comments
  - remove disabled by default on all platforms
  - reorder addresses in 84s4 to be correctly sorted

Changes since v2:
=================

* Remove reference to k3 as requested
* Rebase on v6.8-rc2 where new bindings are present
* Remove am62a dts entry until hrtimer[1] patch gets merged

[1]: https://patchwork.kernel.org/project/linux-media/patch/20240125130833.1953617-1-devarsht at ti.com/

Changes since v1:
=================

* Remove sram parameters
  - sram-size property not included in bindings. Without this, size
  will default to 0 so no point in specifying until binding is added.
* Remove global CMA pools for each platform
  - This is something that has been added in TI backport of driver
  and does not yet have reliable support in upstream version.
  - Removing for now with intention to add back once 48-bit
  addressing is supported in upstream Wave5 driver.

Brandon Brnich (3):
  arm64: dts: ti: k3-j784s4: Add Wave5 Video Encoder/Decoder Node
  arm64: dts: ti: k3-am62p: Add Wave5 Video Encoder/Decoder Node
  arm64: defconfig: Enable Wave5 Video Encoder/Decoder

Darren Etheridge (1):
  arm64: dts: ti: k3-j721s2-main: Add Wave5 Video Encoder/Decoder Node

 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi  |  9 +++++++++
 arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi |  9 +++++++++
 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 18 ++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-j784s4.dtsi      |  2 ++
 arch/arm64/configs/defconfig               |  1 +
 5 files changed, 39 insertions(+)

-- 
2.34.1



From b-brnich at ti.com  Mon Feb  5 11:47:05 2024
From: b-brnich at ti.com (Brandon Brnich)
Date: Mon, 5 Feb 2024 13:47:05 -0600
Subject: [PATCH v4 3/4] arm64: dts: ti: k3-am62p: Add Wave5 Video Encoder/Decoder Node
In-Reply-To: <20240205194706.3605309-1-b-brnich@ti.com>
References: <20240205194706.3605309-1-b-brnich@ti.com>
Message-ID: <20240205194706.3605309-4-b-brnich@ti.com>

This patch adds support for the Wave521cl on the AM62P.

Signed-off-by: Brandon Brnich <b-brnich at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 4c51bae06b57..d550660ca4c7 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -891,4 +891,13 @@ mcasp2: audio-controller at 2b20000 {
 		power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 	};
+
+	vpu: video-codec at 30210000 {
+		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+		reg = <0x00 0x30210000 0x00 0x10000>;
+		interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&k3_clks 204 2>;
+		clock-names = "vcodec";
+		power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
+	};
 };
-- 
2.34.1



From b-brnich at ti.com  Mon Feb  5 11:47:03 2024
From: b-brnich at ti.com (Brandon Brnich)
Date: Mon, 5 Feb 2024 13:47:03 -0600
Subject: [PATCH v4 1/4] arm64: dts: ti: k3-j784s4: Add Wave5 Video Encoder/Decoder Node
In-Reply-To: <20240205194706.3605309-1-b-brnich@ti.com>
References: <20240205194706.3605309-1-b-brnich@ti.com>
Message-ID: <20240205194706.3605309-2-b-brnich@ti.com>

This patch adds support for the Wave521cl on the J784S4-evm.

Signed-off-by: Brandon Brnich <b-brnich at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 18 ++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-j784s4.dtsi      |  2 ++
 2 files changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
index f2b720ed1e4f..e628e748f215 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -662,6 +662,24 @@ main_i2c6: i2c at 2060000 {
 		status = "disabled";
 	};
 
+	vpu0: video-codec at 4210000 {
+		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+		reg = <0x00 0x4210000 0x00 0x10000>;
+		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&k3_clks 241 2>;
+		clock-names = "vcodec";
+		power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>;
+	};
+
+	vpu1: video-codec at 4220000 {
+		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+		reg = <0x00 0x4220000 0x00 0x10000>;
+		interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&k3_clks 242 2>;
+		clock-names = "vcodec";
+		power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
+	};
+
 	main_sdhci0: mmc at 4f80000 {
 		compatible = "ti,j721e-sdhci-8bit";
 		reg = <0x00 0x04f80000 0x00 0x1000>,
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
index 4398c3a463e1..2f633721a0c6 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
@@ -235,6 +235,8 @@ cbass_main: bus at 100000 {
 		ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
 			 <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
 			 <0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */
+			 <0x00 0x04210000 0x00 0x04210000 0x00 0x00010000>, /* VPU0 */
+			 <0x00 0x04220000 0x00 0x04220000 0x00 0x00010000>, /* VPU1 */
 			 <0x00 0x0d000000 0x00 0x0d000000 0x00 0x01000000>, /* PCIe Core*/
 			 <0x00 0x10000000 0x00 0x10000000 0x00 0x08000000>, /* PCIe0 DAT0 */
 			 <0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */
-- 
2.34.1



From b-brnich at ti.com  Mon Feb  5 11:47:06 2024
From: b-brnich at ti.com (Brandon Brnich)
Date: Mon, 5 Feb 2024 13:47:06 -0600
Subject: [PATCH v4 4/4] arm64: defconfig: Enable Wave5 Video Encoder/Decoder
In-Reply-To: <20240205194706.3605309-1-b-brnich@ti.com>
References: <20240205194706.3605309-1-b-brnich@ti.com>
Message-ID: <20240205194706.3605309-5-b-brnich@ti.com>

Enable Wave521c video decoder/encoder driver on all TI
K3 platforms that contain the IP.

Signed-off-by: Brandon Brnich <b-brnich at ti.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e6cf3e5d63c3..6fe4f2da4aca 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -795,6 +795,7 @@ CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_CADENCE_CSI2RX=m
 CONFIG_VIDEO_MEDIATEK_JPEG=m
 CONFIG_VIDEO_MEDIATEK_VCODEC=m
+CONFIG_VIDEO_WAVE_VPU=m
 CONFIG_VIDEO_IMX7_CSI=m
 CONFIG_VIDEO_IMX_MIPI_CSIS=m
 CONFIG_VIDEO_IMX8_ISI=m
-- 
2.34.1



From b-brnich at ti.com  Mon Feb  5 11:47:04 2024
From: b-brnich at ti.com (Brandon Brnich)
Date: Mon, 5 Feb 2024 13:47:04 -0600
Subject: [PATCH v4 2/4] arm64: dts: ti: k3-j721s2-main: Add Wave5 Video Encoder/Decoder Node
In-Reply-To: <20240205194706.3605309-1-b-brnich@ti.com>
References: <20240205194706.3605309-1-b-brnich@ti.com>
Message-ID: <20240205194706.3605309-3-b-brnich@ti.com>

From: Darren Etheridge <detheridge at ti.com>

Add the Chips and Media wave521cl video decoder/encoder node on J721S2.

Signed-off-by: Darren Etheridge <detheridge at ti.com>
Signed-off-by: Brandon Brnich <b-brnich at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
index ea7f2b2ab165..df4cdbf94539 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -716,6 +716,15 @@ main_i2c6: i2c at 2060000 {
 		status = "disabled";
 	};
 
+	vpu: video-codec at 4210000 {
+		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+		reg = <0x00 0x4210000 0x00 0x10000>;
+		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&k3_clks 179 2>;
+		clock-names = "vcodec";
+		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
+	};
+
 	main_sdhci0: mmc at 4f80000 {
 		compatible = "ti,j721e-sdhci-8bit";
 		reg = <0x00 0x04f80000 0x00 0x1000>,
-- 
2.34.1



From ilkka at os.amperecomputing.com  Mon Feb  5 11:46:55 2024
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Mon,  5 Feb 2024 11:46:55 -0800
Subject: [PATCH] perf/arm-cmn: Workaround AmpereOneX errata AC04_MESH_1 (incorrect child count)
Message-ID: <20240205194655.1567434-1-ilkka@os.amperecomputing.com>

AmpereOneX mesh implementation has a bug in HN-P nodes that makes them
report incorrect child count. The failing crosspoints report 8 children
while they only have two.

When the driver tries to access the inexistent child nodes, it believes it
has reached an invalid node type and probing fails. The workaround is to
ignore those incorrect child nodes and continue normally.

Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
---
 drivers/perf/arm-cmn.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index c584165b13ba..97fed8ec3693 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -2168,6 +2168,23 @@ static enum cmn_node_type arm_cmn_subtype(enum cmn_node_type type)
 	}
 }
 
+static inline bool arm_cmn_is_ampereonex_bug(const struct arm_cmn *cmn,
+					     struct arm_cmn_node *dn,
+					     u16 child_count, int child)
+{
+	/*
+	 * The bug occurs only when a crosspoint reports 8 children
+	 * while it only has two HN-P child nodes.
+	 */
+	dn -= 2;
+
+	if (arm_cmn_model(cmn) == CMN650 && child_count == 8 &&
+	    child == 2 && dn->type == CMN_TYPE_HNP)
+		return true;
+
+	return false;
+}
+
 static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 {
 	void __iomem *cfg_region;
@@ -2292,6 +2309,14 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 
 		for (j = 0; j < child_count; j++) {
 			reg = readq_relaxed(xp_region + child_poff + j * 8);
+			if (reg == 0)
+				if (arm_cmn_is_ampereonex_bug(cmn, dn, child_count, j))
+					/*
+					 * We know there are only two real children and the rest 6
+					 * are inexistent. Thus, we can skip the rest of the loop
+					 */
+					break;
+
 			/*
 			 * Don't even try to touch anything external, since in general
 			 * we haven't a clue how to power up arbitrary CHI requesters.
-- 
2.40.1



From robh at kernel.org  Mon Feb  5 11:53:40 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 5 Feb 2024 19:53:40 +0000
Subject: [PATCH] dt-bindings: ata: atmel: remove at91 compact flash
 documentation
In-Reply-To: <20240205105201.81060-1-Hari.PrasathGE@microchip.com>
References: <20240205105201.81060-1-Hari.PrasathGE@microchip.com>
Message-ID: <170716281814.270322.2449852122042883860.robh@kernel.org>


On Mon, 05 Feb 2024 16:22:01 +0530, Hari Prasath Gujulan Elango wrote:
> The compatible "at91rm9200-cf" is not used by any driver,hence remove the
> corresponding documentation.
> 
> Signed-off-by: Hari Prasath Gujulan Elango <Hari.PrasathGE at microchip.com>
> ---
>  .../devicetree/bindings/ata/atmel-at91_cf.txt | 19 -------------------
>  1 file changed, 19 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/ata/atmel-at91_cf.txt
> 

Acked-by: Rob Herring <robh at kernel.org>



From geert at linux-m68k.org  Mon Feb  5 11:55:29 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 5 Feb 2024 20:55:29 +0100
Subject: [PATCH v3 7/7] of: Add KUnit test to confirm DTB is loaded
In-Reply-To: <89892ecd6b1b043db58258705c32b02b.sboyd@kernel.org>
References: <20240202195909.3458162-1-sboyd@kernel.org> <20240202195909.3458162-8-sboyd@kernel.org>
 <CABVgOS=A8BQ6HHpBKFqg-N10ckk2XYavaS-MPXvZ0wenrVm=1g@mail.gmail.com> <89892ecd6b1b043db58258705c32b02b.sboyd@kernel.org>
Message-ID: <CAMuHMdUuP5Ya2gU3V_ET=Ji_+yx+jr7eCch5uDJSqvQN9jJM3g@mail.gmail.com>

Hi Stephen,

On Mon, Feb 5, 2024 at 8:19?PM Stephen Boyd <sboyd at kernel.org> wrote:
> Quoting David Gow (2024-02-02 20:10:17)
> > On Sat, 3 Feb 2024 at 03:59, Stephen Boyd <sboyd at kernel.org> wrote:
> > > Add a KUnit test that confirms a DTB has been loaded, i.e. there is a
> > > root node, and that the of_have_populated_dt() API works properly.
> > >
> > > Cc: Rob Herring <robh+dt at kernel.org>
> > > Cc: Frank Rowand <frowand.list at gmail.com>
> > > Cc: David Gow <davidgow at google.com>
> > > Cc: Brendan Higgins <brendan.higgins at linux.dev>
> > > Signed-off-by: Stephen Boyd <sboyd at kernel.org>
> > > ---
> >
> > This looks pretty good to me test-wise, though it still fails on m68k.
> > (Everything else I tried it on works, though I've definitely not tried
> > _every_ architecture.)
> >
> > aarch64: PASSED
> > i386: PASSED
> > x86_64: PASSED
> > x86_64 KASAN: PASSED
> > powerpc64: PASSED
> > UML: PASSED
> > UML LLVM: PASSED
> > m68k: FAILED
> > > $ qemu-system-m68k -nodefaults -m 1024 -kernel .kunit-all-m68k/vmlinux -append 'kunit.enable=1 console=hvc0 kunit_shutdown=reboot' -no-reboot -nographic -serial stdio -machine virt
> > > [11:55:05] ===================== dtb (2 subtests) =====================
> > > [11:55:05] # dtb_root_node_found_by_path: EXPECTATION FAILED at drivers/of/of_test.c:18
> > > [11:55:05] Expected np is not null, but is
> > > [11:55:05] [FAILED] dtb_root_node_found_by_path
> > > [11:55:05] # dtb_root_node_populates_of_root: EXPECTATION FAILED at drivers/of/of_test.c:28
> > > [11:55:05] Expected of_root is not null, but is
> > > [11:55:05] [FAILED] dtb_root_node_populates_of_root
> > > [11:55:05]     # module: of_test
> > > [11:55:05] # dtb: pass:0 fail:2 skip:0 total:2
> > > [11:55:05] # Totals: pass:0 fail:2 skip:0 total:2
> > > [11:55:05] ======================= [FAILED] dtb =======================
>
> Ah yeah I forgot to mention that. m68k fails because it doesn't call the
> unflatten_(and_copy)?_device_tree() function, so we don't populate a
> root node on that architecture. One solution would be to make CONFIG_OF
> unavailable on m68k. Or we have to make sure DT works on any
> architecture. Rob, what do you prefer here?

I guess the latter?
Alpha, hexagon, parisc, s390, and sparc are also lacking calls
to unflatten.*device_tree().

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 Frank.li at nxp.com  Mon Feb  5 11:55:37 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 5 Feb 2024 14:55:37 -0500
Subject: [PATCH v2 0/4] Add 8qm SMMU information
In-Reply-To: <65097032-74d4-4617-8ef6-e1f76b41cce6@linaro.org>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240202110511.135d26b7@kernel.org>
 <Zb1sijexWGLG5gcH@lizhi-Precision-Tower-5810>
 <65097032-74d4-4617-8ef6-e1f76b41cce6@linaro.org>
Message-ID: <ZcE9OQ5Vu3nPP0Vc@lizhi-Precision-Tower-5810>

On Mon, Feb 05, 2024 at 10:25:46AM +0100, Krzysztof Kozlowski wrote:
> On 02/02/2024 23:28, Frank Li wrote:
> > On Fri, Feb 02, 2024 at 11:05:11AM -0800, Jakub Kicinski wrote:
> >> On Thu, 01 Feb 2024 15:22:40 -0500 Frank Li wrote:
> >>>       dt-bindings: mmc: fsl-imx-esdhc: add iommus property
> >>>       dt-bindings: net: fec: add iommus property
> >>>       arm64: dts: imx8qm: add smmu node
> >>>       arm64: dts: imx8qm: add smmu stream id information
> >>>
> >>>  .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml     |  3 ++
> >>>  Documentation/devicetree/bindings/net/fsl,fec.yaml |  3 ++
> >>>  arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi  |  6 ++++
> >>>  arch/arm64/boot/dts/freescale/imx8qm.dtsi          | 41 ++++++++++++++++++++++
> >>
> >> Any preference on whether all these go via a platform tree,
> >> or should we pick up the net patch to netdev? I guess taking
> >> the DTB via netdev would be the usual way to handle this?
> > 
> > Supposed dt-bindings go through netdev tree.
> > 
> > without dt-bindings, just DTB_CHECK warning. No strict dependence
> > relationship between dt-bindings doc and dts file. 
> 
> Please make it easier for maintainers and sent entirely independent
> patches for different subsystems in SEPARATE patchsets.
> 
> There is no dependency here between anything. Combining it, OTOH, brings
> the questions about such dependency and makes it a bit more difficult to
> apply for each maintainer.

Understand, but without dts change, it is not easy to understand why need
change dt-binding files.

Frank

> 
> Best regards,
> Krzysztof
> 


From jkardatzke at google.com  Mon Feb  5 12:21:38 2024
From: jkardatzke at google.com (Jeffrey Kardatzke)
Date: Mon, 5 Feb 2024 12:21:38 -0800
Subject: [PATCH v3 03/11] drm/mediatek: Add secure buffer control flow to mtk_drm_gem
In-Reply-To: <ZaE6_I95IcxIUB4x@phenom.ffwll.local>
References: <20231223182932.27683-1-jason-jh.lin@mediatek.com>
 <20231223182932.27683-4-jason-jh.lin@mediatek.com> <ZaE6_I95IcxIUB4x@phenom.ffwll.local>
Message-ID: <CA+ddPcOw5tP+rz7f6ty3HXyRUg1ReC_BwyhVpzuVVViZSwx_zg@mail.gmail.com>

On Fri, Jan 12, 2024 at 5:13?AM Daniel Vetter <daniel at ffwll.ch> wrote:
>
> On Sun, Dec 24, 2023 at 02:29:24AM +0800, Jason-JH.Lin wrote:
> > Add secure buffer control flow to mtk_drm_gem.
> >
> > When user space takes DRM_MTK_GEM_CREATE_ENCRYPTED flag and size
> > to create a mtk_drm_gem object, mtk_drm_gem will find a matched size
> > dma buffer from secure dma-heap and bind it to mtk_drm_gem object.
> >
> > Signed-off-by: Jason-JH.Lin <jason-jh.lin at mediatek.com>
>
> Apologies for jumping rather late, but last year was a mess here.
>
> There's the fundamental issue that this is new uapi, and it needs open
> userspace, and I haven't seen that.

The open userspace for it is currently in minigbm for ChromeOS here:
https://chromium.googlesource.com/chromiumos/platform/minigbm/+/main/mediatek.c#322

Does that satisfy that particular requirement?
>
> What's more, this is a pure kms api so there's no precedent at all for
> adding special ioctl to those - all the existing support for
> protected/restricted content buffers in upstream has used render nodes and
> EGL_EXT_protected_content in mesa3d to enable this feature on the drm/kms
> side. So I'm not exactly sure what your plan here is, but you need one,
> and it needs to be more than a testcase/demo.

I'm probably not understanding something here, but for the Intel
protected content allocation there was a specific structure
(drm_i915_gem_create_ext_protected_content) added to the
DRM_IOCTL_I915_GEM_CREATE_EXT ioctl in order to enable allocation of
protected buffers.  So wouldn't that be precedent for using an ioctl
like this to allocate a GEM object?

>
> The other issue, and the reason I've looked into the mtk code, is that the
> dma-buf implementation breaks the dma-buf api. So that needs to be
> changed.
Yeah, agreed here...I do see now that attaching dma_bufs for content
that is completely inaccessible by the kernel will be a no-go.
>
> Finally I think the primary way to display a protected content buffer on a
> pure kms driver should be by using prime fd2handle buffer importing.
> Because you're adding a dma-buf heap it's already possible for userspace
> to use this path (or at least try), and so we have to make this path work
> anyway.

Is what you're getting at here having MTK implement their own
gem_prime_import in order to work around having to do the dma_buf
attach operation? (from looking at the code, this appears to be the
only place in non-vendor specific code that dma_buf_attach is called)
>
> Once we have the prime import path working correctly for protected content
> buffers (which should shake out all the dma-api issues I've explained in
> the dma-buf heaps thread), it should be possible to implement the direct
> allocation function in a generic helper:
>
> struct drm_gem_object * drm_gem_create_object_from_heap(struct drm_device *dev,
>                                                         struct drm_file *file,
>                                                         struct drm_buf_heap *heap);
>
> Which does roughly:
>
> - allocate a dma-buf from the desired heap
> - import that dma-buf into the device using prime for the drm_file
> - using the already implemented driver import code for special cases like
>   protected content buffers
>
> There should be no need to hand-roll all this code here, and especially
> not have any special-casing for the heap string name or things like that.
> That all must be handled in the dma-buf prime import code.
>
> Cheers, Sima
>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_gem.c | 85 +++++++++++++++++++++++++-
> >  drivers/gpu/drm/mediatek/mtk_drm_gem.h |  4 ++
> >  2 files changed, 88 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
> > index 30e347adcbe9..858f34a735f8 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
> > @@ -4,6 +4,8 @@
> >   */
> >
> >  #include <linux/dma-buf.h>
> > +#include <linux/dma-heap.h>
> > +#include <uapi/linux/dma-heap.h>
> >  #include <drm/mediatek_drm.h>
> >
> >  #include <drm/drm.h>
> > @@ -55,6 +57,81 @@ static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct drm_device *dev,
> >       return mtk_gem_obj;
> >  }
> >
> > +struct mtk_drm_gem_obj *mtk_drm_gem_create_from_heap(struct drm_device *dev,
> > +                                                  const char *heap, size_t size)
> > +{
> > +     struct mtk_drm_private *priv = dev->dev_private;
> > +     struct mtk_drm_gem_obj *mtk_gem;
> > +     struct drm_gem_object *obj;
> > +     struct dma_heap *dma_heap;
> > +     struct dma_buf *dma_buf;
> > +     struct dma_buf_attachment *attach;
> > +     struct sg_table *sgt;
> > +     struct iosys_map map = {};
> > +     int ret;
> > +
> > +     mtk_gem = mtk_drm_gem_init(dev, size);
> > +     if (IS_ERR(mtk_gem))
> > +             return ERR_CAST(mtk_gem);
> > +
> > +     obj = &mtk_gem->base;
> > +
> > +     dma_heap = dma_heap_find(heap);
> > +     if (!dma_heap) {
> > +             DRM_ERROR("heap find fail\n");
> > +             goto err_gem_free;
> > +     }
> > +     dma_buf = dma_heap_buffer_alloc(dma_heap, size,
> > +                                     O_RDWR | O_CLOEXEC, DMA_HEAP_VALID_HEAP_FLAGS);
> > +     if (IS_ERR(dma_buf)) {
> > +             DRM_ERROR("buffer alloc fail\n");
> > +             dma_heap_put(dma_heap);
> > +             goto err_gem_free;
> > +     }
> > +     dma_heap_put(dma_heap);
> > +
> > +     attach = dma_buf_attach(dma_buf, priv->dma_dev);
> > +     if (IS_ERR(attach)) {
> > +             DRM_ERROR("attach fail, return\n");
> > +             dma_buf_put(dma_buf);
> > +             goto err_gem_free;
> > +     }
> > +
> > +     sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
> > +     if (IS_ERR(sgt)) {
> > +             DRM_ERROR("map failed, detach and return\n");
> > +             dma_buf_detach(dma_buf, attach);
> > +             dma_buf_put(dma_buf);
> > +             goto err_gem_free;
> > +     }
> > +     obj->import_attach = attach;
> > +     mtk_gem->dma_addr = sg_dma_address(sgt->sgl);
> > +     mtk_gem->sg = sgt;
> > +     mtk_gem->size = dma_buf->size;
> > +
> > +     if (!strcmp(heap, "mtk_svp") || !strcmp(heap, "mtk_svp_cma")) {
> > +             /* secure buffer can not be mapped */
> > +             mtk_gem->secure = true;
> > +     } else {
> > +             ret = dma_buf_vmap(dma_buf, &map);
> > +             mtk_gem->kvaddr = map.vaddr;
> > +             if (ret) {
> > +                     DRM_ERROR("map failed, ret=%d\n", ret);
> > +                     dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
> > +                     dma_buf_detach(dma_buf, attach);
> > +                     dma_buf_put(dma_buf);
> > +                     mtk_gem->kvaddr = NULL;
> > +             }
> > +     }
> > +
> > +     return mtk_gem;
> > +
> > +err_gem_free:
> > +     drm_gem_object_release(obj);
> > +     kfree(mtk_gem);
> > +     return ERR_PTR(-ENOMEM);
> > +}
> > +
> >  struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev,
> >                                          size_t size, bool alloc_kmap)
> >  {
> > @@ -225,7 +302,9 @@ struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
> >       if (IS_ERR(mtk_gem))
> >               return ERR_CAST(mtk_gem);
> >
> > +     mtk_gem->secure = !sg_page(sg->sgl);
> >       mtk_gem->dma_addr = sg_dma_address(sg->sgl);
> > +     mtk_gem->size = attach->dmabuf->size;
> >       mtk_gem->sg = sg;
> >
> >       return &mtk_gem->base;
> > @@ -301,7 +380,11 @@ int mtk_gem_create_ioctl(struct drm_device *dev, void *data,
> >       struct drm_mtk_gem_create *args = data;
> >       int ret;
> >
> > -     mtk_gem = mtk_drm_gem_create(dev, args->size, false);
> > +     if (args->flags & DRM_MTK_GEM_CREATE_ENCRYPTED)
> > +             mtk_gem = mtk_drm_gem_create_from_heap(dev, "mtk_svp_cma", args->size);
> > +     else
> > +             mtk_gem = mtk_drm_gem_create(dev, args->size, false);
> > +
> >       if (IS_ERR(mtk_gem))
> >               return PTR_ERR(mtk_gem);
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.h b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
> > index 90f3d2916ec5..8fd5ce827d4f 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
> > @@ -27,9 +27,11 @@ struct mtk_drm_gem_obj {
> >       void                    *cookie;
> >       void                    *kvaddr;
> >       dma_addr_t              dma_addr;
> > +     size_t                  size;
> >       unsigned long           dma_attrs;
> >       struct sg_table         *sg;
> >       struct page             **pages;
> > +     bool                    secure;
> >  };
> >
> >  #define to_mtk_gem_obj(x)    container_of(x, struct mtk_drm_gem_obj, base)
> > @@ -37,6 +39,8 @@ struct mtk_drm_gem_obj {
> >  void mtk_drm_gem_free_object(struct drm_gem_object *gem);
> >  struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev, size_t size,
> >                                          bool alloc_kmap);
> > +struct mtk_drm_gem_obj *mtk_drm_gem_create_from_heap(struct drm_device *dev,
> > +                                                  const char *heap, size_t size);
> >  int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
> >                           struct drm_mode_create_dumb *args);
> >  struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj);
> > --
> > 2.18.0
> >
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch


From konstantin at linuxfoundation.org  Mon Feb  5 12:24:19 2024
From: konstantin at linuxfoundation.org (Konstantin Ryabitsev)
Date: Mon, 5 Feb 2024 15:24:19 -0500
Subject: [PATCH net RFC] net: dsa: mt7530: fix link-local frames that
 ingress vlan filtering ports
In-Reply-To: <1f0e67ba-edd7-4998-bc20-1de86bd53a68@arinc9.com>
References: <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
 <20240201225943.abphuuavp7bkbrt6@skbuf>
 <1f0e67ba-edd7-4998-bc20-1de86bd53a68@arinc9.com>
Message-ID: <20240205-silky-sensible-puffin-8e23ee@lemur>

On Fri, Feb 02, 2024 at 12:11:37PM +0300, Ar?n? ?NAL wrote:
> There're no brackets enclosing the Message-Id. That must be why Gmail
> modified it with the SMTPIN_ADDED_BROKEN disclaimer added for you. I can't
> come up with a theory as to why you've received it thrice though.
> 
> Konstantin, could you take a look at what happened here?

Oh, yay, another python email module bug. *sigh* It's not supposed to break
items enclosed in brackets.

I'll see if I can work around it on the submission side of things, but for now
the silly workaround is not to create branch names that are too long (which
results in message-ids that are very long).

-K


From olteanv at gmail.com  Mon Feb  5 12:29:35 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Mon, 5 Feb 2024 22:29:35 +0200
Subject: [PATCH net-next v3 1/7] net: dsa: mt7530: empty default case on
 mt7530_setup_port5()
In-Reply-To: <Zb0u8NY0q6ay17j5@shell.armlinux.org.uk>
References: <20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca@arinc9.com>
 <20240202-for-netnext-mt7530-improvements-2-v3-1-63d5adae99ca@arinc9.com>
 <ZbzUotyQm/FyKK7G@shell.armlinux.org.uk>
 <e3b4add6-425c-46ca-9da5-8713055fc422@arinc9.com>
 <Zb0u8NY0q6ay17j5@shell.armlinux.org.uk>
Message-ID: <20240205202935.tolbbwbtrig32jlj@skbuf>

On Fri, Feb 02, 2024 at 06:05:36PM +0000, Russell King (Oracle) wrote:
> > > Given everything I've said above, the only way to configure RGMII
> > > delays is via the rx-internal-delay-ps and tx-internal-delay-ps
> > > properties. So, DSA drivers should _not_ be configuring their ports
> > > with RGMII delays based on the RGMII phy interface mode.
> > > 
> > > The above is my purely logically reasoned point of view on this
> > > subject. Others may have other (to me completely illogical)
> > > interpretations that can only lead to interoperability issues.
> > 
> > I will address this with the next patch series. Thank you for explaining it
> > in detail.
> 
> This is a good time to point out not to rush with the next patch
> series, as my email will _likely_ provoke some additional discussion
> from Andrew and/or Vladimir. So please give it a few days (maybe
> around the middle of next week) to give them time to consider my
> email and respond.

I agree with everything you've said. The only problem is that
Documentation/devicetree/bindings/net/ethernet-controller.yaml is
ambiguous on this topic (to put it mildly).

@Ar?n?, there are ways to handle the "tx-internal-delay-ps" in
mt7530_setup_port5() in a way that is backwards compatible. I don't know
about RX delays - the function doesn't handle them, and I don't have the
time to open datasheets now. You can take inspiration from
ksz_parse_rgmii_delay() and sja1105_parse_rgmii_delays() on how to only
fall back to the current logic to set the tx_delay if the more specific
OF properties are not present.


From frank at oltmanns.dev  Mon Feb  5 12:34:04 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 05 Feb 2024 21:34:04 +0100
Subject: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum
 rate
In-Reply-To: <4543794.LvFx2qVVIh@jernej-laptop>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>
 <4543794.LvFx2qVVIh@jernej-laptop>
Message-ID: <87eddqzm4j.fsf@oltmanns.dev>


On 2024-02-05 at 18:56:09 +0100, Jernej ?krabec <jernej.skrabec at gmail.com> wrote:
> Dne ponedeljek, 05. februar 2024 ob 16:22:26 CET je Frank Oltmanns napisal(a):
>> According to the Allwinner User Manual, the Allwinner A64 requires
>> PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.
>>
>> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
>> ---
>>  drivers/clk/sunxi-ng/ccu_nkm.c | 13 +++++++++++++
>>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>>  2 files changed, 15 insertions(+)
>>
>> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
>> index 1168d894d636..7d135908d6e0 100644
>> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
>> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
>> @@ -181,6 +181,12 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
>>  	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
>>  		rate *= nkm->fixed_post_div;
>>
>> +	if (nkm->min_rate && rate < nkm->min_rate)
>> +		rate = nkm->min_rate;
>> +
>> +	if (nkm->max_rate && rate > nkm->max_rate)
>> +		rate = nkm->max_rate;
>
> Please take a look at ccu_nm_round_rate() code. You need to consider postdiv
> and you can return immediately.

There is a difference here insofar that ccu_nm is always connected to a
fixed rate parent (at least that's my understanding). Therefore, in
ccu_nm_round_rate() we can be sure that the min or max rate can really
be set. In ccu_nkm we don't have that luxury, we actually have to find a
rate that is approximately equal to the min and max rate, based on the
parent rate. Therefore, we can't return immediately.

Also, I'm not sure what you mean about me needing to consider postdiv.
That's what I did. The check is after multiplying with the postdiv. It's
the same as in ccu_nm_round_rate() (just minus the immediate return).

>
>> +
>>  	if (!clk_hw_can_set_rate_parent(&nkm->common.hw))
>>  		rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm->common);
>>  	else
>> @@ -220,6 +226,13 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
>>  	_nkm.min_m = 1;
>>  	_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
>>
>> +
>> +	if (nkm->min_rate && rate < nkm->min_rate)
>> +		rate = nkm->min_rate;
>> +
>> +	if (nkm->max_rate && rate > nkm->max_rate)
>> +		rate = nkm->max_rate;
>> +
>
> No need for this, clk subsystem calls round rate before setting actual clock
> rate.

I'll remove the checks in V3.

Best regards,
  Frank

>
> Best regards,
> Jernej
>
>>  	ccu_nkm_find_best(parent_rate, rate, &_nkm, &nkm->common);
>>
>>  	spin_lock_irqsave(nkm->common.lock, flags);
>> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
>> index c409212ee40e..358a9df6b6a0 100644
>> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
>> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
>> @@ -27,6 +27,8 @@ struct ccu_nkm {
>>  	struct ccu_mux_internal	mux;
>>
>>  	unsigned int		fixed_post_div;
>> +	unsigned long		min_rate;
>> +	unsigned long		max_rate;
>>  	unsigned long		max_m_n_ratio;
>>  	unsigned long		min_parent_m_ratio;
>>
>>
>>


From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb  5 14:08:03 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Tue, 06 Feb 2024 01:08:03 +0300
Subject: [PATCH net-next v5 2/7] net: dsa: mt7530: move XTAL check to
 mt7530_setup()
In-Reply-To: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
References: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
Message-ID: <20240206-for-netnext-mt7530-improvements-2-v5-2-d7d92a185cb1@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

The crystal frequency concerns the switch core. The frequency should be
checked when the switch is being set up so the driver can reject the
unsupported hardware earlier and without requiring port 6 to be used.

Move it to mt7530_setup(). Drop the unnecessary function printing.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 330e22abc076..8b8469eba863 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -422,13 +422,6 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 
 	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
 
-	if (xtal == HWTRAP_XTAL_20MHZ) {
-		dev_err(priv->dev,
-			"%s: MT7530 with a 20MHz XTAL is not supported!\n",
-			__func__);
-		return -EINVAL;
-	}
-
 	switch (interface) {
 	case PHY_INTERFACE_MODE_RGMII:
 		trgint = 0;
@@ -2259,6 +2252,12 @@ mt7530_setup(struct dsa_switch *ds)
 		return -ENODEV;
 	}
 
+	if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_20MHZ) {
+		dev_err(priv->dev,
+			"MT7530 with a 20MHz XTAL is not supported!\n");
+		return -EINVAL;
+	}
+
 	/* Reset the switch through internal reset */
 	mt7530_write(priv, MT7530_SYS_CTRL,
 		     SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb  5 14:08:02 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Tue, 06 Feb 2024 01:08:02 +0300
Subject: [PATCH net-next v5 1/7] net: dsa: mt7530: empty default case on
 mt7530_setup_port5()
In-Reply-To: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
References: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
Message-ID: <20240206-for-netnext-mt7530-improvements-2-v5-1-d7d92a185cb1@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

There're two code paths for setting up port 5:

mt7530_setup()
-> mt7530_setup_port5()

mt753x_phylink_mac_config()
-> mt753x_mac_config()
   -> mt7530_mac_config()
      -> mt7530_setup_port5()

On the first code path, priv->p5_intf_sel is either set to
P5_INTF_SEL_PHY_P0 or P5_INTF_SEL_PHY_P4 when mt7530_setup_port5() is run.

On the second code path, priv->p5_intf_sel is set to P5_INTF_SEL_GMAC5 when
mt7530_setup_port5() is run.

Empty the default case which will never run but is needed nonetheless to
handle all the remaining enumeration values.

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 68be38ae66e0..330e22abc076 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -943,9 +943,7 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
 		val &= ~MHWTRAP_P5_DIS;
 		break;
 	default:
-		dev_err(ds->dev, "Unsupported p5_intf_sel %d\n",
-			priv->p5_intf_sel);
-		goto unlock_exit;
+		break;
 	}
 
 	/* Setup RGMII settings */
@@ -975,7 +973,6 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
 	dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n",
 		val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface));
 
-unlock_exit:
 	mutex_unlock(&priv->reg_mutex);
 }
 

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb  5 14:08:05 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Tue, 06 Feb 2024 01:08:05 +0300
Subject: [PATCH net-next v5 4/7] net: dsa: mt7530: call port 6 setup from
 mt7530_mac_config()
In-Reply-To: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
References: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
Message-ID: <20240206-for-netnext-mt7530-improvements-2-v5-4-d7d92a185cb1@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

mt7530_pad_clk_setup() is called if port 6 is enabled. It used to do more
things than setting up port 6. That part was moved to more appropriate
locations, mt7530_setup() and mt7530_pll_setup().

Now that all it does is set up port 6, rename it to mt7530_setup_port6(),
and move it to a more appropriate location, under mt7530_mac_config().

Change mt7530_setup_port6() to void as there're no error cases.

Leave an empty mt7530_pad_clk_setup() to satisfy the pad_setup function
pointer.

This is the code path for setting up the ports before:

dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
-> mt753x_mac_config()
   -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
      -> mt7530_setup_port5()
-> mt753x_pad_setup()
   -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup()

This is after:

dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config()
-> mt753x_mac_config()
   -> mt753x_info :: mac_port_config() -> mt7530_mac_config()
      -> mt7530_setup_port5()
      -> mt7530_setup_port6()

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index e13b9c9cb19f..65c2f5f275a3 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -414,8 +414,8 @@ mt753x_preferred_default_local_cpu_port(struct dsa_switch *ds)
 }
 
 /* Setup port 6 interface mode and TRGMII TX circuit */
-static int
-mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
+static void
+mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
 {
 	struct mt7530_priv *priv = ds->priv;
 	u32 ncpo1, ssc_delta, xtal;
@@ -426,7 +426,7 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 	if (interface == PHY_INTERFACE_MODE_RGMII) {
 		mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
 			   P6_INTF_MODE(0));
-		return 0;
+		return;
 	}
 
 	mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
@@ -465,7 +465,11 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 
 	/* Enable the MT7530 TRGMII clocks */
 	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
+}
 
+static int
+mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
+{
 	return 0;
 }
 
@@ -2613,11 +2617,10 @@ mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 {
 	struct mt7530_priv *priv = ds->priv;
 
-	/* Only need to setup port5. */
-	if (port != 5)
-		return 0;
-
-	mt7530_setup_port5(priv->ds, interface);
+	if (port == 5)
+		mt7530_setup_port5(priv->ds, interface);
+	else if (port == 6)
+		mt7530_setup_port6(priv->ds, interface);
 
 	return 0;
 }

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb  5 14:08:06 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Tue, 06 Feb 2024 01:08:06 +0300
Subject: [PATCH net-next v5 5/7] net: dsa: mt7530: remove pad_setup
 function pointer
In-Reply-To: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
References: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
Message-ID: <20240206-for-netnext-mt7530-improvements-2-v5-5-d7d92a185cb1@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

The pad_setup function pointer was introduced with 88bdef8be9f6 ("net: dsa:
mt7530: Extend device data ready for adding a new hardware"). It was being
used to set up the core clock and port 6 of the MT7530 switch, and pll of
the MT7531 switch.

All of these were moved to more appropriate locations, and it was never
used for the switch on the MT7988 SoC. Therefore, this function pointer
hasn't got a use anymore. Remove it.

Acked-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 36 ++----------------------------------
 drivers/net/dsa/mt7530.h |  3 ---
 2 files changed, 2 insertions(+), 37 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 65c2f5f275a3..e1fdef5766fb 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -467,18 +467,6 @@ mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
 	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 }
 
-static int
-mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
-{
-	return 0;
-}
-
-static int
-mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
-{
-	return 0;
-}
-
 static void
 mt7531_pll_setup(struct mt7530_priv *priv)
 {
@@ -2603,14 +2591,6 @@ static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 	}
 }
 
-static int
-mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
-{
-	struct mt7530_priv *priv = ds->priv;
-
-	return priv->info->pad_setup(ds, state->interface);
-}
-
 static int
 mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
@@ -2776,8 +2756,6 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		if (priv->p6_interface == state->interface)
 			break;
 
-		mt753x_pad_setup(ds, state);
-
 		if (mt753x_mac_config(ds, port, mode, state) < 0)
 			goto unsupported;
 
@@ -3095,11 +3073,6 @@ mt753x_conduit_state_change(struct dsa_switch *ds,
 	mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val);
 }
 
-static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
-{
-	return 0;
-}
-
 static int mt7988_setup(struct dsa_switch *ds)
 {
 	struct mt7530_priv *priv = ds->priv;
@@ -3163,7 +3136,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7530_phy_write_c22,
 		.phy_read_c45 = mt7530_phy_read_c45,
 		.phy_write_c45 = mt7530_phy_write_c45,
-		.pad_setup = mt7530_pad_clk_setup,
 		.mac_port_get_caps = mt7530_mac_port_get_caps,
 		.mac_port_config = mt7530_mac_config,
 	},
@@ -3175,7 +3147,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7530_phy_write_c22,
 		.phy_read_c45 = mt7530_phy_read_c45,
 		.phy_write_c45 = mt7530_phy_write_c45,
-		.pad_setup = mt7530_pad_clk_setup,
 		.mac_port_get_caps = mt7530_mac_port_get_caps,
 		.mac_port_config = mt7530_mac_config,
 	},
@@ -3187,7 +3158,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7531_ind_c22_phy_write,
 		.phy_read_c45 = mt7531_ind_c45_phy_read,
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
-		.pad_setup = mt7531_pad_setup,
 		.cpu_port_config = mt7531_cpu_port_config,
 		.mac_port_get_caps = mt7531_mac_port_get_caps,
 		.mac_port_config = mt7531_mac_config,
@@ -3200,7 +3170,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7531_ind_c22_phy_write,
 		.phy_read_c45 = mt7531_ind_c45_phy_read,
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
-		.pad_setup = mt7988_pad_setup,
 		.cpu_port_config = mt7988_cpu_port_config,
 		.mac_port_get_caps = mt7988_mac_port_get_caps,
 		.mac_port_config = mt7988_mac_config,
@@ -3230,9 +3199,8 @@ mt7530_probe_common(struct mt7530_priv *priv)
 	/* Sanity check if these required device operations are filled
 	 * properly.
 	 */
-	if (!priv->info->sw_setup || !priv->info->pad_setup ||
-	    !priv->info->phy_read_c22 || !priv->info->phy_write_c22 ||
-	    !priv->info->mac_port_get_caps ||
+	if (!priv->info->sw_setup || !priv->info->phy_read_c22 ||
+	    !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps ||
 	    !priv->info->mac_port_config)
 		return -EINVAL;
 
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 80060cc740d2..26a6d2160c08 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -704,8 +704,6 @@ struct mt753x_pcs {
  * @phy_write_c22:	Holding the way writing PHY port using C22
  * @phy_read_c45:	Holding the way reading PHY port using C45
  * @phy_write_c45:	Holding the way writing PHY port using C45
- * @pad_setup:		Holding the way setting up the bus pad for a certain
- *			MAC port
  * @phy_mode_supported:	Check if the PHY type is being supported on a certain
  *			port
  * @mac_port_validate:	Holding the way to set addition validate type for a
@@ -726,7 +724,6 @@ struct mt753x_info {
 			    int regnum);
 	int (*phy_write_c45)(struct mt7530_priv *priv, int port, int devad,
 			     int regnum, u16 val);
-	int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
 	int (*cpu_port_config)(struct dsa_switch *ds, int port);
 	void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
 				  struct phylink_config *config);

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb  5 14:08:07 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Tue, 06 Feb 2024 01:08:07 +0300
Subject: [PATCH net-next v5 6/7] net: dsa: mt7530: correct port
 capabilities of MT7988
In-Reply-To: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
References: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
Message-ID: <20240206-for-netnext-mt7530-improvements-2-v5-6-d7d92a185cb1@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

On the switch on the MT7988 SoC, as shown in Block Diagram 8.1.1.3 on page
125 of "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open
Version) v0.1", there are only 4 PHYs. That's port 0 to 3. Set the case for
ports which connect to switch PHYs to '0 ... 3'.

Port 4 and 5 are not used at all in this design.

Link: https://wiki.banana-pi.org/Banana_Pi_BPI-R4#Documents [1]
Acked-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index e1fdef5766fb..4ca7ba94788e 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2577,7 +2577,7 @@ static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 
 	switch (port) {
 	/* Ports which are connected to switch PHYs. There is no MII pinout. */
-	case 0 ... 4:
+	case 0 ... 3:
 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 			  config->supported_interfaces);
 		break;

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb  5 14:08:08 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Tue, 06 Feb 2024 01:08:08 +0300
Subject: [PATCH net-next v5 7/7] net: dsa: mt7530: do not clear
 config->supported_interfaces
In-Reply-To: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
References: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
Message-ID: <20240206-for-netnext-mt7530-improvements-2-v5-7-d7d92a185cb1@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

There's no need to clear the config->supported_interfaces bitmap before
reporting the supported interfaces as all bits in the bitmap will already
be initialized to zero when the phylink_config structure is allocated. The
"config" pointer points to &dp->phylink_config, and "dp" is allocated by
dsa_port_touch() with kzalloc(), so all its fields are filled with zeroes.

There's no code that would change the bitmap beforehand. Remove it.

Acked-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 4ca7ba94788e..aed1ea6815ee 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2573,8 +2573,6 @@ static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
 static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 				     struct phylink_config *config)
 {
-	phy_interface_zero(config->supported_interfaces);
-
 	switch (port) {
 	/* Ports which are connected to switch PHYs. There is no MII pinout. */
 	case 0 ... 3:

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb  5 14:08:04 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Tue, 06 Feb 2024 01:08:04 +0300
Subject: [PATCH net-next v5 3/7] net: dsa: mt7530: simplify
 mt7530_pad_clk_setup()
In-Reply-To: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
References: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
Message-ID: <20240206-for-netnext-mt7530-improvements-2-v5-3-d7d92a185cb1@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

This code is from before this driver was converted to phylink API. Phylink
deals with the unsupported interface cases before mt7530_pad_clk_setup() is
run. Therefore, the default case would never run. However, it must be
defined nonetheless to handle all the remaining enumeration values, the
phy-modes.

Switch to if statement for RGMII and return which simplifies the code and
saves an indent.

Set P6_INTF_MODE, which is the three least significant bits of the
MT7530_P6ECR register, to 0 for RGMII even though it will already be 0
after reset. This is to keep supporting dynamic reconfiguration of the port
in the case the interface changes from TRGMII to RGMII.

Disable the TRGMII clocks for all cases. They will be enabled if TRGMII is
being used.

Read XTAL after checking for RGMII as it's only needed for the TRGMII
interface mode.

Reviewed-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 91 +++++++++++++++++++++---------------------------
 1 file changed, 40 insertions(+), 51 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 8b8469eba863..e13b9c9cb19f 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -418,64 +418,53 @@ static int
 mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
 {
 	struct mt7530_priv *priv = ds->priv;
-	u32 ncpo1, ssc_delta, trgint, xtal;
+	u32 ncpo1, ssc_delta, xtal;
 
-	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
+	/* Disable the MT7530 TRGMII clocks */
+	core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 
-	switch (interface) {
-	case PHY_INTERFACE_MODE_RGMII:
-		trgint = 0;
-		break;
-	case PHY_INTERFACE_MODE_TRGMII:
-		trgint = 1;
-		if (xtal == HWTRAP_XTAL_25MHZ)
-			ssc_delta = 0x57;
-		else
-			ssc_delta = 0x87;
-		if (priv->id == ID_MT7621) {
-			/* PLL frequency: 125MHz: 1.0GBit */
-			if (xtal == HWTRAP_XTAL_40MHZ)
-				ncpo1 = 0x0640;
-			if (xtal == HWTRAP_XTAL_25MHZ)
-				ncpo1 = 0x0a00;
-		} else { /* PLL frequency: 250MHz: 2.0Gbit */
-			if (xtal == HWTRAP_XTAL_40MHZ)
-				ncpo1 = 0x0c80;
-			if (xtal == HWTRAP_XTAL_25MHZ)
-				ncpo1 = 0x1400;
-		}
-		break;
-	default:
-		dev_err(priv->dev, "xMII interface %d not supported\n",
-			interface);
-		return -EINVAL;
+	if (interface == PHY_INTERFACE_MODE_RGMII) {
+		mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
+			   P6_INTF_MODE(0));
+		return 0;
 	}
 
-	mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK,
-		   P6_INTF_MODE(trgint));
+	mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
 
-	if (trgint) {
-		/* Disable the MT7530 TRGMII clocks */
-		core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
+	xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
 
-		/* Setup the MT7530 TRGMII Tx Clock */
-		core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
-		core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
-		core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
-		core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
-		core_write(priv, CORE_PLL_GROUP4,
-			   RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN |
-			   RG_SYSPLL_BIAS_LPF_EN);
-		core_write(priv, CORE_PLL_GROUP2,
-			   RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
-			   RG_SYSPLL_POSDIV(1));
-		core_write(priv, CORE_PLL_GROUP7,
-			   RG_LCDDS_PCW_NCPO_CHG | RG_LCCDS_C(3) |
-			   RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
+	if (xtal == HWTRAP_XTAL_25MHZ)
+		ssc_delta = 0x57;
+	else
+		ssc_delta = 0x87;
 
-		/* Enable the MT7530 TRGMII clocks */
-		core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
-	}
+	if (priv->id == ID_MT7621) {
+		/* PLL frequency: 125MHz: 1.0GBit */
+		if (xtal == HWTRAP_XTAL_40MHZ)
+			ncpo1 = 0x0640;
+		if (xtal == HWTRAP_XTAL_25MHZ)
+			ncpo1 = 0x0a00;
+	} else { /* PLL frequency: 250MHz: 2.0Gbit */
+		if (xtal == HWTRAP_XTAL_40MHZ)
+			ncpo1 = 0x0c80;
+		if (xtal == HWTRAP_XTAL_25MHZ)
+			ncpo1 = 0x1400;
+	}
+
+	/* Setup the MT7530 TRGMII Tx Clock */
+	core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1));
+	core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0));
+	core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta));
+	core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta));
+	core_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN |
+		   RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
+	core_write(priv, CORE_PLL_GROUP2, RG_SYSPLL_EN_NORMAL |
+		   RG_SYSPLL_VODEN | RG_SYSPLL_POSDIV(1));
+	core_write(priv, CORE_PLL_GROUP7, RG_LCDDS_PCW_NCPO_CHG |
+		   RG_LCCDS_C(3) | RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
+
+	/* Enable the MT7530 TRGMII clocks */
+	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
 
 	return 0;
 }

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb  5 14:08:01 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Tue, 06 Feb 2024 01:08:01 +0300
Subject: [PATCH net-next v5 0/7] MT7530 DSA Subdriver Improvements Act II
Message-ID: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>

Hello!

This is the second patch series with the goal of simplifying the MT7530 DSA
subdriver and improving support for MT7530, MT7531, and the switch on the
MT7988 SoC.

I have done a simple ping test to confirm basic communication on all switch
ports on MCM and standalone MT7530, and MT7531 switch with this patch
series applied.

MT7621 Unielec, MCM MT7530:

rgmii-only-gmac0-mt7621-unielec-u7621-06-16m.dtb
gmac0-and-gmac1-mt7621-unielec-u7621-06-16m.dtb

tftpboot 0x80008000 mips-uzImage.bin; tftpboot 0x83000000 mips-rootfs.cpio.uboot; tftpboot 0x83f00000 $dtb; bootm 0x80008000 0x83000000 0x83f00000

MT7622 Bananapi, MT7531:

gmac0-and-gmac1-mt7622-bananapi-bpi-r64.dtb

tftpboot 0x40000000 arm64-Image; tftpboot 0x45000000 arm64-rootfs.cpio.uboot; tftpboot 0x4a000000 $dtb; booti 0x40000000 0x45000000 0x4a000000

MT7623 Bananapi, standalone MT7530:

rgmii-only-gmac0-mt7623n-bananapi-bpi-r2.dtb
gmac0-and-gmac1-mt7623n-bananapi-bpi-r2.dtb

tftpboot 0x80008000 arm-zImage; tftpboot 0x83000000 arm-rootfs.cpio.uboot; tftpboot 0x83f00000 $dtb; bootz 0x80008000 0x83000000 0x83f00000

This patch series is the continuation of the patch series linked below.

https://lore.kernel.org/r/20230522121532.86610-1-arinc.unal at arinc9.com

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
Changes in v5:
- Update the patches with the latest received trailers.
- Patch 3
  - Replace "return;" with "return 0;".
- Patch 4
  - Remove the stray brace.
- Link to v4: https://lore.kernel.org/r/20240204-for-netnext-mt7530-improvements-2-v4-0-02bf0abaadb8 at arinc9.com

Changes in v4:
- Update the patches with the latest received trailers.
- Leave no error returns on mt7530_pad_clk_setup() before renaming it to
  mt7530_setup_port6() and moving it to under mt7530_mac_config().
- Link to v3: https://lore.kernel.org/r/20240202-for-netnext-mt7530-improvements-2-v3-0-63d5adae99ca at arinc9.com

Changes in v3:
- Update the patches with the latest received trailers.
- Patch 5
  - Disable TRGMII clocks for all cases.
- Link to v2: https://lore.kernel.org/r/20240130-for-netnext-mt7530-improvements-2-v2-0-ba06f5dd9eb0 at arinc9.com

Changes in v2:
- Update the patches with the latest received trailers.
- Remove 'net: dsa: mt7530: move enabling port 6 to mt7530_setup_port6()'
  which was patch 5. I will bring a more appropriate change with a later
  patch series.
- Patch 5
  - Set P6_INTF_MODE(0) and explain why on the patch log.
- Patch 6
  - Mention the MT7988 document and explain more on the patch log.
- Patch 7
  - Explain more on the patch log.
- Link to v1: https://lore.kernel.org/r/20240113102529.80371-1-arinc.unal at arinc9.com

---
Ar?n? ?NAL (7):
      net: dsa: mt7530: empty default case on mt7530_setup_port5()
      net: dsa: mt7530: move XTAL check to mt7530_setup()
      net: dsa: mt7530: simplify mt7530_pad_clk_setup()
      net: dsa: mt7530: call port 6 setup from mt7530_mac_config()
      net: dsa: mt7530: remove pad_setup function pointer
      net: dsa: mt7530: correct port capabilities of MT7988
      net: dsa: mt7530: do not clear config->supported_interfaces

 drivers/net/dsa/mt7530.c | 152 +++++++++++++++++------------------------------
 drivers/net/dsa/mt7530.h |   3 -
 2 files changed, 53 insertions(+), 102 deletions(-)
---
base-commit: 4acf4e62cd572b0c806035046b3698f5585ab821
change-id: 20240121-for-netnext-mt7530-improvements-2-b4f43661b485

Best regards,
-- 
Ar?n? ?NAL <arinc.unal at arinc9.com>



From Anatoliy.Klymenko at amd.com  Mon Feb  5 14:22:38 2024
From: Anatoliy.Klymenko at amd.com (Klymenko, Anatoliy)
Date: Mon, 5 Feb 2024 22:22:38 +0000
Subject: [PATCH v3 2/5] drm: xlnx: zynqmp_dpsub: Fix timing for live mode
In-Reply-To: <20240205080824.GH6804@pendragon.ideasonboard.com>
References: <20240124025402.373620-1-anatoliy.klymenko@amd.com>
 <20240124025402.373620-3-anatoliy.klymenko@amd.com>
 <20240205080824.GH6804@pendragon.ideasonboard.com>
Message-ID: <MW4PR12MB7165B4A0AD707686C04162DCE6472@MW4PR12MB7165.namprd12.prod.outlook.com>

Hi Laurent,

Thanks a lot for the review.

> -----Original Message-----
> From: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Sent: Monday, February 5, 2024 12:08 AM
> To: Klymenko, Anatoliy <Anatoliy.Klymenko at amd.com>
> Cc: maarten.lankhorst at linux.intel.com; mripard at kernel.org;
> tzimmermann at suse.de; airlied at gmail.com; daniel at ffwll.ch; Simek, Michal
> <michal.simek at amd.com>; dri-devel at lists.freedesktop.org; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
> Subject: Re: [PATCH v3 2/5] drm: xlnx: zynqmp_dpsub: Fix timing for live mode
> 
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
> 
> 
> Hi Anatoliy,
> 
> Thank you for the patch.
> 
> On Tue, Jan 23, 2024 at 06:53:59PM -0800, Anatoliy Klymenko wrote:
> > Expect external video timing in live video input mode, program DPSUB
> > acordingly.
> 
> Are there no designs where the DPSUB operates in non-live mode, but uses a
> video clock from the PL, for instance to use a different clock frequency ?
> 
> I don't think that use case is very common, so I'm fine with this patch in order to
> properly support the more common use case of live input, and leave the PL clock
> without live input use case for later.
> 
Theoretically, we can create such a design, but it wouldn't make too much sense since the PS clock is the best choice here. Probably, in some complicated scenarios like hybrid live-in/DMA or live-out, we would consider using the PL video clock, but the DPSUB driver is not supporting them yet.
> >
> > Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> >
> 
> No need for a blank line here.
> 
Sure, I'll fix this in the new version. Thank you.
> > Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko at amd.com>
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> 
> > ---
> >  drivers/gpu/drm/xlnx/zynqmp_disp.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > index 407bc07cec69..8a39b3accce5 100644
> > --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > @@ -1166,7 +1166,7 @@ void zynqmp_disp_enable(struct zynqmp_disp *disp)
> >       /* Choose clock source based on the DT clock handle. */
> >       zynqmp_disp_avbuf_set_clocks_sources(disp, disp->dpsub-
> >vid_clk_from_ps,
> >                                            disp->dpsub->aud_clk_from_ps,
> > -                                          true);
> > +
> > + disp->dpsub->vid_clk_from_ps);
> >       zynqmp_disp_avbuf_enable_channels(disp);
> >       zynqmp_disp_avbuf_enable_audio(disp);
> >
> 
> --
> Regards,
> 
> Laurent Pinchart

From afd at ti.com  Mon Feb  5 14:36:25 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 16:36:25 -0600
Subject: [PATCH v7 2/5] remoteproc: k3: Move out data structures common
 with M4 driver
In-Reply-To: <20240202175538.1705-3-hnagalla@ti.com>
References: <20240202175538.1705-1-hnagalla@ti.com>
 <20240202175538.1705-3-hnagalla@ti.com>
Message-ID: <e0f604e0-f7e1-4ef3-8370-fc9f9213170d@ti.com>

On 2/2/24 11:55 AM, Hari Nagalla wrote:
> From: Martyn Welch <martyn.welch at collabora.com>
> 
> We will be adding the M4F driver which shares a lot of commonality
> with the DSP driver. Common data structures are introduced here.
> 
> Signed-off-by: Martyn Welch <martyn.welch at collabora.com>
> Signed-off-by: Hari Nagalla <hnagalla at ti.com>
> ---
> Changes since v5:
>   - Created a separate patch for data structures to ease review
> 
> Changes since v6:
>   - Reworded 'split' to 'move' as the common data structures between
>     DSP and M4 remote rpoc drivers are moved into common driver.
> 

Is this a joke? In v6 Krzysztof commented the following:

> Where is the split? I see only addition here.
> 
> Where is the usage of this header? This is basically dead code. Don't
> add dead code, but instead actually move the structures here! Move is
> cut and paste, not just paste.

Instead of changing the patch in any way to address this comment you
just replaced the word 'split' to 'move' in the commit subject.. Maybe
no one will notice this is all still dead code since you didn't say the
word 'split' anymore..

Andrew

> link to v6:
> https://lore.kernel.org/all/20230913111644.29889-3-hnagalla at ti.com/
> 
>   drivers/remoteproc/ti_k3_common.h | 107 ++++++++++++++++++++++++++++++
>   1 file changed, 107 insertions(+)
>   create mode 100644 drivers/remoteproc/ti_k3_common.h
> 
> diff --git a/drivers/remoteproc/ti_k3_common.h b/drivers/remoteproc/ti_k3_common.h
> new file mode 100644
> index 000000000000..f1bab83dd0fc
> --- /dev/null
> +++ b/drivers/remoteproc/ti_k3_common.h
> @@ -0,0 +1,107 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * TI K3 Remote Processor(s) driver common code
> + *
> + * Refactored from ti_k3_dsp_remoteproc.c.
> + *
> + * ti_k3_dsp_remoteproc.c:
> + * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
> + *	Suman Anna <s-anna at ti.com>
> + */
> +
> +#ifndef REMOTEPROC_TI_K3_COMMON_H
> +#define REMOTEPROC_TI_K3_COMMON_H
> +
> +#define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK	(SZ_16M - 1)
> +
> +/**
> + * struct k3_rproc_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 remote processor view
> + * @size: Size of the memory region
> + */
> +struct k3_rproc_mem {
> +	void __iomem *cpu_addr;
> +	phys_addr_t bus_addr;
> +	u32 dev_addr;
> +	size_t size;
> +};
> +
> +/**
> + * struct k3_rproc_mem_data - memory definitions for a remote processor
> + * @name: name for this memory entry
> + * @dev_addr: device address for the memory entry
> + */
> +struct k3_rproc_mem_data {
> +	const char *name;
> +	const u32 dev_addr;
> +};
> +
> +/**
> + * struct k3_rproc_dev_data - device data structure for a remote processor
> + * @mems: pointer to memory definitions for a remote processor
> + * @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_rproc_dev_data {
> +	const struct k3_rproc_mem_data *mems;
> +	u32 num_mems;
> +	u32 boot_align_addr;
> +	bool uses_lreset;
> +};
> +
> +/**
> + * struct k3_rproc - k3 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 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
> + */
> +struct k3_rproc {
> +	struct device *dev;
> +	struct rproc *rproc;
> +	struct k3_rproc_mem *mem;
> +	int num_mems;
> +	struct k3_rproc_mem *sram;
> +	int num_sram;
> +	struct k3_rproc_mem *rmem;
> +	int num_rmems;
> +	struct reset_control *reset;
> +	const struct k3_rproc_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;
> +};
> +
> +void k3_rproc_kick(struct rproc *rproc, int vqid);
> +int k3_rproc_reset(struct k3_rproc *kproc);
> +int k3_rproc_release(struct k3_rproc *kproc);
> +int k3_rproc_request_mbox(struct rproc *rproc);
> +int k3_rproc_prepare(struct rproc *rproc);
> +int k3_rproc_unprepare(struct rproc *rproc);
> +struct resource_table *k3_get_loaded_rsc_table(struct rproc *rproc,
> +					       size_t *rsc_table_sz);
> +void *k3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len,
> +			bool *is_iomem);
> +int k3_rproc_of_get_memories(struct platform_device *pdev,
> +			     struct k3_rproc *kproc);
> +int k3_rproc_of_get_sram_memories(struct platform_device *pdev,
> +			     struct k3_rproc *kproc);
> +int k3_reserved_mem_init(struct k3_rproc *kproc);
> +void k3_reserved_mem_exit(struct k3_rproc *kproc);
> +struct ti_sci_proc *k3_rproc_of_get_tsp(struct device *dev,
> +					const struct ti_sci_handle *sci);
> +#endif /* REMOTEPROC_TI_K3_COMMON_H */


From afd at ti.com  Mon Feb  5 14:46:34 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 5 Feb 2024 16:46:34 -0600
Subject: [PATCH v7 3/5] remoteproc: k3: Move out functions common with M4
 driver
In-Reply-To: <20240202175538.1705-4-hnagalla@ti.com>
References: <20240202175538.1705-1-hnagalla@ti.com>
 <20240202175538.1705-4-hnagalla@ti.com>
Message-ID: <5cc16585-d0fc-4746-a833-3041a70c1588@ti.com>

On 2/2/24 11:55 AM, Hari Nagalla wrote:
> From: Martyn Welch <martyn.welch at collabora.com>
> 
> In the next commit we will be adding the M4F driver which shares a lot of
> commonality with the DSP driver. Move this shared functionality out so
> that it can be used by both drivers.
> 
> Signed-off-by: Martyn Welch <martyn.welch at collabora.com>
> Signed-off-by: Hari Nagalla <hnagalla at ti.com>
> ---
> Changes since v2:
>   - New patch (reordered refactored from v2)
> 
> Changes since v3:
>   - Removed "ipc_only" element from k3_rproc structure
>   - Refactored to bring 3 more common functions
> 
> Changes since v4:
>   - None
> 
> Changes since v5:
>   - Rearranged the functions order to match with the functions in
>     ti_k3_dsp_remoteproc.c to ease review.
> 
> Changes since v6:
>   - Generated patch with -M/-B/-C options
> 

You where asked to generate this patch "correctly" with these options,
not just use them all and hope for the best.. Now it looks like you
re-wrote all of ti_k3_dsp_remoteproc.c when you only factored out
a couple functions to a different file.

Build up the new ti_k3_common.c one function per patch if it helps.
And factor the functions out of ti_k3_r5 also as it seems many
of these are common to that driver too.

Andrew

> link to v6:
> https://lore.kernel.org/all/20230913111644.29889-4-hnagalla at ti.com/
> 
>   drivers/remoteproc/Makefile               |    2 +-
>   drivers/remoteproc/ti_k3_common.c         |  583 ++++++++++
>   drivers/remoteproc/ti_k3_dsp_remoteproc.c | 1277 ++++++---------------
>   3 files changed, 952 insertions(+), 910 deletions(-)
>   create mode 100644 drivers/remoteproc/ti_k3_common.c
>   rewrite drivers/remoteproc/ti_k3_dsp_remoteproc.c (67%)
> 
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 91314a9b43ce..55c552e27a45 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -36,6 +36,6 @@ obj-$(CONFIG_RCAR_REMOTEPROC)		+= rcar_rproc.o
>   obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
>   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_DSP_REMOTEPROC)	+= ti_k3_dsp_remoteproc.o ti_k3_common.o
>   obj-$(CONFIG_TI_K3_R5_REMOTEPROC)	+= ti_k3_r5_remoteproc.o
>   obj-$(CONFIG_XLNX_R5_REMOTEPROC)	+= xlnx_r5_remoteproc.o
> diff --git a/drivers/remoteproc/ti_k3_common.c b/drivers/remoteproc/ti_k3_common.c
> new file mode 100644
> index 000000000000..62c7c5dba78a
> --- /dev/null
> +++ b/drivers/remoteproc/ti_k3_common.c
> @@ -0,0 +1,583 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * TI K3 Remote Processor(s) driver common code
> + *
> + * Refactored from ti_k3_dsp_remoteproc.c.
> + *
> + * ti_k3_dsp_remoteproc.c:
> + * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
> + *	Suman Anna <s-anna at ti.com>
> + */
> +
> +#include <linux/io.h>
> +#include <linux/mailbox_client.h>
> +#include <linux/module.h>
> +#include <linux/of_address.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"
> +#include "ti_k3_common.h"
> +
> +/**
> + * k3_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 K3 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_rproc_mbox_callback(struct mbox_client *client, void *data)
> +{
> +	struct k3_rproc *kproc = container_of(client, struct k3_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 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.
> + */
> +void k3_rproc_kick(struct rproc *rproc, int vqid)
> +{
> +	struct k3_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);
> +}
> +EXPORT_SYMBOL_GPL(k3_rproc_kick);
> +
> +/* Put the remote processor into reset */
> +int k3_rproc_reset(struct k3_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;
> +}
> +EXPORT_SYMBOL_GPL(k3_rproc_reset);
> +
> +/* Release the remote processor from reset */
> +int k3_rproc_release(struct k3_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;
> +	}
> +
> +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;
> +}
> +EXPORT_SYMBOL_GPL(k3_rproc_release);
> +
> +int k3_rproc_request_mbox(struct rproc *rproc)
> +{
> +	struct k3_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_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;
> +}
> +EXPORT_SYMBOL_GPL(k3_rproc_request_mbox);
> +
> +/*
> + * The DSP and MCU cores have a local reset that affects only the CPU, and a
> + * generic module reset that powers on the device and allows the internal
> + * memories to be accessed while the local reset is asserted. This function is
> + * used to release the global reset on remote cores to allow loading into the
> + * 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 remote cores to run. This callback is invoked only in
> + * remoteproc mode.
> + */
> +int k3_rproc_prepare(struct rproc *rproc)
> +{
> +	struct k3_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +	int ret;
> +
> +	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;
> +}
> +EXPORT_SYMBOL_GPL(k3_rproc_prepare);
> +
> +/*
> + * 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 DSP, MCU cores. This completes the second portion of
> + * powering down the remote core. 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. This callback is invoked only in remoteproc mode.
> + */
> +int k3_rproc_unprepare(struct rproc *rproc)
> +{
> +	struct k3_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +	int 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);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(k3_rproc_unprepare);
> +
> +/*
> + * This function implements the .get_loaded_rsc_table() callback and is used
> + * to provide the resource table for a booted remote processor in IPC-only
> + * mode. The remote processor 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.
> + */
> +struct resource_table *k3_get_loaded_rsc_table(struct rproc *rproc,
> +					       size_t *rsc_table_sz)
> +{
> +	struct k3_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;
> +}
> +EXPORT_SYMBOL_GPL(k3_get_loaded_rsc_table);
> +
> +/*
> + * Custom function to translate a remote processor device address (internal
> + * RAMs only) to a kernel virtual address.  The remote processors can access
> + * their RAMs at either an internal address visible only from a remote
> + * processor, 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.
> + */
> +void *k3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
> +{
> +	struct k3_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 remote-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 any SRAM regions using SoC-view addresses */
> +	for (i = 0; i < kproc->num_sram; i++) {
> +		dev_addr = kproc->sram[i].dev_addr;
> +		size = kproc->sram[i].size;
> +
> +		if (da >= dev_addr && ((da + len) <= (dev_addr + size))) {
> +			offset = da - dev_addr;
> +			va = kproc->sram[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;
> +}
> +EXPORT_SYMBOL_GPL(k3_rproc_da_to_va);
> +
> +int k3_rproc_of_get_memories(struct platform_device *pdev,
> +			     struct k3_rproc *kproc)
> +{
> +	const struct k3_rproc_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;
> +}
> +EXPORT_SYMBOL_GPL(k3_rproc_of_get_memories);
> +
> +int k3_rproc_of_get_sram_memories(struct platform_device *pdev,
> +					   struct k3_rproc *kproc)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *sram_np;
> +	struct resource res;
> +	int num_sram;
> +	int i, ret;
> +
> +	num_sram = of_property_count_elems_of_size(np, "sram", sizeof(phandle));
> +	if (num_sram <= 0) {
> +		dev_dbg(dev, "device does not use reserved on-chip memories, num_sram = %d\n",
> +			num_sram);
> +		return 0;
> +	}
> +
> +	kproc->sram = devm_kcalloc(dev, num_sram, sizeof(*kproc->sram), GFP_KERNEL);
> +	if (!kproc->sram)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < num_sram; i++) {
> +		sram_np = of_parse_phandle(np, "sram", i);
> +		if (!sram_np)
> +			return -EINVAL;
> +
> +		if (!of_device_is_available(sram_np)) {
> +			of_node_put(sram_np);
> +			return -EINVAL;
> +		}
> +
> +		ret = of_address_to_resource(sram_np, 0, &res);
> +		of_node_put(sram_np);
> +		if (ret)
> +			return -EINVAL;
> +
> +		kproc->sram[i].bus_addr = res.start;
> +		kproc->sram[i].dev_addr = res.start;
> +		kproc->sram[i].size = resource_size(&res);
> +		kproc->sram[i].cpu_addr = devm_ioremap_wc(dev, res.start,
> +							 resource_size(&res));
> +		if (!kproc->sram[i].cpu_addr) {
> +			dev_err(dev, "failed to parse and map sram%d memory at %pad\n",
> +				i, &res.start);
> +			return -ENOMEM;
> +		}
> +
> +		dev_dbg(dev, "memory sram%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
> +			i, &kproc->sram[i].bus_addr,
> +			kproc->sram[i].size, kproc->sram[i].cpu_addr,
> +			kproc->sram[i].dev_addr);
> +	}
> +	kproc->num_sram = num_sram;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(k3_rproc_of_get_sram_memories);
> +int k3_reserved_mem_init(struct k3_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;
> +}
> +EXPORT_SYMBOL_GPL(k3_reserved_mem_init);
> +
> +void k3_reserved_mem_exit(struct k3_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);
> +}
> +EXPORT_SYMBOL_GPL(k3_reserved_mem_exit);
> +
> +struct ti_sci_proc *k3_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;
> +}
> +EXPORT_SYMBOL_GPL(k3_rproc_of_get_tsp);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("TI K3 common Remoteproc support");
> diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
> dissimilarity index 67%
> index ab882e3b7130..ebe23fc5ca44 100644
> --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
> +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
> @@ -1,909 +1,368 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * TI K3 DSP Remote Processor(s) driver
> - *
> - * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
> - *	Suman Anna <s-anna at ti.com>
> - */
> -
> -#include <linux/io.h>
> -#include <linux/mailbox_client.h>
> -#include <linux/module.h>
> -#include <linux/of.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_dsp_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_dsp_mem {
> -	void __iomem *cpu_addr;
> -	phys_addr_t bus_addr;
> -	u32 dev_addr;
> -	size_t size;
> -};
> -
> -/**
> - * struct k3_dsp_mem_data - memory definitions for a DSP
> - * @name: name for this memory entry
> - * @dev_addr: device address for the memory entry
> - */
> -struct k3_dsp_mem_data {
> -	const char *name;
> -	const u32 dev_addr;
> -};
> -
> -/**
> - * struct k3_dsp_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_dsp_dev_data {
> -	const struct k3_dsp_mem_data *mems;
> -	u32 num_mems;
> -	u32 boot_align_addr;
> -	bool uses_lreset;
> -};
> -
> -/**
> - * struct k3_dsp_rproc - k3 DSP 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 DSP-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
> - */
> -struct k3_dsp_rproc {
> -	struct device *dev;
> -	struct rproc *rproc;
> -	struct k3_dsp_mem *mem;
> -	int num_mems;
> -	struct k3_dsp_mem *rmem;
> -	int num_rmems;
> -	struct reset_control *reset;
> -	const struct k3_dsp_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;
> -};
> -
> -/**
> - * k3_dsp_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_dsp_rproc_mbox_callback(struct mbox_client *client, void *data)
> -{
> -	struct k3_dsp_rproc *kproc = container_of(client, struct k3_dsp_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 DSP 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_dsp_rproc_kick(struct rproc *rproc, int vqid)
> -{
> -	struct k3_dsp_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 (%pe)\n",
> -			ERR_PTR(ret));
> -}
> -
> -/* Put the DSP processor into reset */
> -static int k3_dsp_rproc_reset(struct k3_dsp_rproc *kproc)
> -{
> -	struct device *dev = kproc->dev;
> -	int ret;
> -
> -	ret = reset_control_assert(kproc->reset);
> -	if (ret) {
> -		dev_err(dev, "local-reset assert failed (%pe)\n", ERR_PTR(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 (%pe)\n", ERR_PTR(ret));
> -		if (reset_control_deassert(kproc->reset))
> -			dev_warn(dev, "local-reset deassert back failed\n");
> -	}
> -
> -	return ret;
> -}
> -
> -/* Release the DSP processor from reset */
> -static int k3_dsp_rproc_release(struct k3_dsp_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 (%pe)\n", ERR_PTR(ret));
> -		return ret;
> -	}
> -
> -lreset:
> -	ret = reset_control_deassert(kproc->reset);
> -	if (ret) {
> -		dev_err(dev, "local-reset deassert failed, (%pe)\n", ERR_PTR(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_dsp_rproc_request_mbox(struct rproc *rproc)
> -{
> -	struct k3_dsp_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_dsp_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 (%pe)\n", ERR_PTR(ret));
> -		mbox_free_channel(kproc->mbox);
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -/*
> - * The C66x DSP cores have a local reset that affects only the CPU, and a
> - * generic module reset that powers on the device and allows the DSP internal
> - * memories to be accessed while the local reset is asserted. This function is
> - * used to release the global reset on C66x DSPs to allow loading into the DSP
> - * 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 C66x DSP cores run. This callback is invoked only in
> - * remoteproc mode.
> - */
> -static int k3_dsp_rproc_prepare(struct rproc *rproc)
> -{
> -	struct k3_dsp_rproc *kproc = rproc->priv;
> -	struct device *dev = kproc->dev;
> -	int ret;
> -
> -	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 (%pe)\n",
> -			ERR_PTR(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 C66x cores. This completes the second portion of
> - * powering down the C66x DSP 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. This callback is invoked only in remoteproc mode.
> - */
> -static int k3_dsp_rproc_unprepare(struct rproc *rproc)
> -{
> -	struct k3_dsp_rproc *kproc = rproc->priv;
> -	struct device *dev = kproc->dev;
> -	int 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 (%pe)\n", ERR_PTR(ret));
> -
> -	return ret;
> -}
> -
> -/*
> - * Power up the DSP 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. This callback is invoked only in remoteproc mode.
> - */
> -static int k3_dsp_rproc_start(struct rproc *rproc)
> -{
> -	struct k3_dsp_rproc *kproc = rproc->priv;
> -	struct device *dev = kproc->dev;
> -	u32 boot_addr;
> -	int ret;
> -
> -	ret = k3_dsp_rproc_request_mbox(rproc);
> -	if (ret)
> -		return ret;
> -
> -	boot_addr = rproc->bootaddr;
> -	if (boot_addr & (kproc->data->boot_align_addr - 1)) {
> -		dev_err(dev, "invalid boot address 0x%x, must be aligned on a 0x%x boundary\n",
> -			boot_addr, kproc->data->boot_align_addr);
> -		ret = -EINVAL;
> -		goto put_mbox;
> -	}
> -
> -	dev_err(dev, "booting DSP core using boot addr = 0x%x\n", boot_addr);
> -	ret = ti_sci_proc_set_config(kproc->tsp, boot_addr, 0, 0);
> -	if (ret)
> -		goto put_mbox;
> -
> -	ret = k3_dsp_rproc_release(kproc);
> -	if (ret)
> -		goto put_mbox;
> -
> -	return 0;
> -
> -put_mbox:
> -	mbox_free_channel(kproc->mbox);
> -	return ret;
> -}
> -
> -/*
> - * Stop the DSP remote processor.
> - *
> - * This function puts the DSP processor into reset, and finishes processing
> - * of any pending messages. This callback is invoked only in remoteproc mode.
> - */
> -static int k3_dsp_rproc_stop(struct rproc *rproc)
> -{
> -	struct k3_dsp_rproc *kproc = rproc->priv;
> -
> -	mbox_free_channel(kproc->mbox);
> -
> -	k3_dsp_rproc_reset(kproc);
> -
> -	return 0;
> -}
> -
> -/*
> - * Attach to a running DSP 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 DSP core. This callback is invoked only in IPC-only
> - * mode.
> - */
> -static int k3_dsp_rproc_attach(struct rproc *rproc)
> -{
> -	struct k3_dsp_rproc *kproc = rproc->priv;
> -	struct device *dev = kproc->dev;
> -	int ret;
> -
> -	ret = k3_dsp_rproc_request_mbox(rproc);
> -	if (ret)
> -		return ret;
> -
> -	dev_info(dev, "DSP initialized in IPC-only mode\n");
> -	return 0;
> -}
> -
> -/*
> - * Detach from a running DSP remote processor (IPC-only mode)
> - *
> - * This rproc detach callback performs the opposite operation to attach callback
> - * and only needs to release the mailbox, the DSP core is not stopped and will
> - * be left to continue to run its booted firmware. This callback is invoked only
> - * in IPC-only mode.
> - */
> -static int k3_dsp_rproc_detach(struct rproc *rproc)
> -{
> -	struct k3_dsp_rproc *kproc = rproc->priv;
> -	struct device *dev = kproc->dev;
> -
> -	mbox_free_channel(kproc->mbox);
> -	dev_info(dev, "DSP 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 DSP in IPC-only mode. The K3 DSP
> - * 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. This callback is invoked only in
> - * IPC-only mode.
> - */
> -static struct resource_table *k3_dsp_get_loaded_rsc_table(struct rproc *rproc,
> -							  size_t *rsc_table_sz)
> -{
> -	struct k3_dsp_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 DSP device address (internal RAMs only) to a
> - * kernel virtual address.  The DSPs can access their RAMs at either an internal
> - * address visible only from a DSP, 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_dsp_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
> -{
> -	struct k3_dsp_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 DSP-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_dsp_rproc_ops = {
> -	.start		= k3_dsp_rproc_start,
> -	.stop		= k3_dsp_rproc_stop,
> -	.kick		= k3_dsp_rproc_kick,
> -	.da_to_va	= k3_dsp_rproc_da_to_va,
> -};
> -
> -static int k3_dsp_rproc_of_get_memories(struct platform_device *pdev,
> -					struct k3_dsp_rproc *kproc)
> -{
> -	const struct k3_dsp_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_dsp_reserved_mem_init(struct k3_dsp_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 (%pe)\n",
> -			ERR_PTR(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 (%pe)\n",
> -			ERR_PTR(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_dsp_reserved_mem_exit(struct k3_dsp_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_dsp_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_dsp_rproc_probe(struct platform_device *pdev)
> -{
> -	struct device *dev = &pdev->dev;
> -	struct device_node *np = dev->of_node;
> -	const struct k3_dsp_dev_data *data;
> -	struct k3_dsp_rproc *kproc;
> -	struct rproc *rproc;
> -	const char *fw_name;
> -	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)
> -		return dev_err_probe(dev, ret, "failed to parse firmware-name property\n");
> -
> -	rproc = rproc_alloc(dev, dev_name(dev), &k3_dsp_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_dsp_rproc_prepare;
> -		rproc->ops->unprepare = k3_dsp_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 = dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
> -				    "failed to get ti-sci handle\n");
> -		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_probe(dev, ret, "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 = dev_err_probe(dev, PTR_ERR(kproc->reset),
> -				    "failed to get reset\n");
> -		goto put_sci;
> -	}
> -
> -	kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci);
> -	if (IS_ERR(kproc->tsp)) {
> -		ret = dev_err_probe(dev, PTR_ERR(kproc->tsp),
> -				    "failed to construct ti-sci proc control\n");
> -		goto put_sci;
> -	}
> -
> -	ret = ti_sci_proc_request(kproc->tsp);
> -	if (ret < 0) {
> -		dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
> -		goto free_tsp;
> -	}
> -
> -	ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
> -	if (ret)
> -		goto release_tsp;
> -
> -	ret = k3_dsp_reserved_mem_init(kproc);
> -	if (ret) {
> -		dev_err_probe(dev, ret, "reserved memory init failed\n");
> -		goto release_tsp;
> -	}
> -
> -	ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
> -					       NULL, &p_state);
> -	if (ret) {
> -		dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
> -		goto release_mem;
> -	}
> -
> -	/* configure J721E devices for either remoteproc or IPC-only mode */
> -	if (p_state) {
> -		dev_info(dev, "configured DSP for IPC-only mode\n");
> -		rproc->state = RPROC_DETACHED;
> -		/* override rproc ops with only required IPC-only mode ops */
> -		rproc->ops->prepare = NULL;
> -		rproc->ops->unprepare = NULL;
> -		rproc->ops->start = NULL;
> -		rproc->ops->stop = NULL;
> -		rproc->ops->attach = k3_dsp_rproc_attach;
> -		rproc->ops->detach = k3_dsp_rproc_detach;
> -		rproc->ops->get_loaded_rsc_table = k3_dsp_get_loaded_rsc_table;
> -	} else {
> -		dev_info(dev, "configured DSP for remoteproc mode\n");
> -		/*
> -		 * ensure the DSP local reset is asserted to ensure the DSP
> -		 * 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_probe(dev, ret, "failed to get reset status\n");
> -				goto release_mem;
> -			} else if (ret == 0) {
> -				dev_warn(dev, "local reset is deasserted for device\n");
> -				k3_dsp_rproc_reset(kproc);
> -			}
> -		}
> -	}
> -
> -	ret = rproc_add(rproc);
> -	if (ret) {
> -		dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
> -		goto release_mem;
> -	}
> -
> -	platform_set_drvdata(pdev, kproc);
> -
> -	return 0;
> -
> -release_mem:
> -	k3_dsp_reserved_mem_exit(kproc);
> -release_tsp:
> -	ret1 = ti_sci_proc_release(kproc->tsp);
> -	if (ret1)
> -		dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(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 (%pe)\n", ERR_PTR(ret1));
> -free_rproc:
> -	rproc_free(rproc);
> -	return ret;
> -}
> -
> -static void k3_dsp_rproc_remove(struct platform_device *pdev)
> -{
> -	struct k3_dsp_rproc *kproc = platform_get_drvdata(pdev);
> -	struct rproc *rproc = kproc->rproc;
> -	struct device *dev = &pdev->dev;
> -	int ret;
> -
> -	if (rproc->state == RPROC_ATTACHED) {
> -		ret = rproc_detach(rproc);
> -		if (ret) {
> -			/* Note this error path leaks resources */
> -			dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(ret));
> -			return;
> -		}
> -	}
> -
> -	rproc_del(kproc->rproc);
> -
> -	ret = ti_sci_proc_release(kproc->tsp);
> -	if (ret)
> -		dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret));
> -
> -	kfree(kproc->tsp);
> -
> -	ret = ti_sci_put_handle(kproc->ti_sci);
> -	if (ret)
> -		dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret));
> -
> -	k3_dsp_reserved_mem_exit(kproc);
> -	rproc_free(kproc->rproc);
> -}
> -
> -static const struct k3_dsp_mem_data c66_mems[] = {
> -	{ .name = "l2sram", .dev_addr = 0x800000 },
> -	{ .name = "l1pram", .dev_addr = 0xe00000 },
> -	{ .name = "l1dram", .dev_addr = 0xf00000 },
> -};
> -
> -/* C71x cores only have a L1P Cache, there are no L1P SRAMs */
> -static const struct k3_dsp_mem_data c71_mems[] = {
> -	{ .name = "l2sram", .dev_addr = 0x800000 },
> -	{ .name = "l1dram", .dev_addr = 0xe00000 },
> -};
> -
> -static const struct k3_dsp_mem_data c7xv_mems[] = {
> -	{ .name = "l2sram", .dev_addr = 0x800000 },
> -};
> -
> -static const struct k3_dsp_dev_data c66_data = {
> -	.mems = c66_mems,
> -	.num_mems = ARRAY_SIZE(c66_mems),
> -	.boot_align_addr = SZ_1K,
> -	.uses_lreset = true,
> -};
> -
> -static const struct k3_dsp_dev_data c71_data = {
> -	.mems = c71_mems,
> -	.num_mems = ARRAY_SIZE(c71_mems),
> -	.boot_align_addr = SZ_2M,
> -	.uses_lreset = false,
> -};
> -
> -static const struct k3_dsp_dev_data c7xv_data = {
> -	.mems = c7xv_mems,
> -	.num_mems = ARRAY_SIZE(c7xv_mems),
> -	.boot_align_addr = SZ_2M,
> -	.uses_lreset = false,
> -};
> -
> -static const struct of_device_id k3_dsp_of_match[] = {
> -	{ .compatible = "ti,j721e-c66-dsp", .data = &c66_data, },
> -	{ .compatible = "ti,j721e-c71-dsp", .data = &c71_data, },
> -	{ .compatible = "ti,j721s2-c71-dsp", .data = &c71_data, },
> -	{ .compatible = "ti,am62a-c7xv-dsp", .data = &c7xv_data, },
> -	{ /* sentinel */ },
> -};
> -MODULE_DEVICE_TABLE(of, k3_dsp_of_match);
> -
> -static struct platform_driver k3_dsp_rproc_driver = {
> -	.probe	= k3_dsp_rproc_probe,
> -	.remove_new = k3_dsp_rproc_remove,
> -	.driver	= {
> -		.name = "k3-dsp-rproc",
> -		.of_match_table = k3_dsp_of_match,
> -	},
> -};
> -
> -module_platform_driver(k3_dsp_rproc_driver);
> -
> -MODULE_AUTHOR("Suman Anna <s-anna at ti.com>");
> -MODULE_LICENSE("GPL v2");
> -MODULE_DESCRIPTION("TI K3 DSP Remoteproc driver");
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * TI K3 DSP Remote Processor(s) driver
> + *
> + * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
> + *	Suman Anna <s-anna at ti.com>
> + */
> +
> +#include <linux/io.h>
> +#include <linux/mailbox_client.h>
> +#include <linux/module.h>
> +#include <linux/of.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"
> +#include "ti_k3_common.h"
> +
> +/*
> + * Power up the DSP 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. This callback is invoked only in remoteproc mode.
> + */
> +static int k3_dsp_rproc_start(struct rproc *rproc)
> +{
> +	struct k3_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +	u32 boot_addr;
> +	int ret;
> +
> +	ret = k3_rproc_request_mbox(rproc);
> +	if (ret)
> +		return ret;
> +
> +	boot_addr = rproc->bootaddr;
> +	if (boot_addr & (kproc->data->boot_align_addr - 1)) {
> +		dev_err(dev, "invalid boot address 0x%x, must be aligned on a 0x%x boundary\n",
> +			boot_addr, kproc->data->boot_align_addr);
> +		ret = -EINVAL;
> +		goto put_mbox;
> +	}
> +
> +	dev_err(dev, "booting DSP core using boot addr = 0x%x\n", boot_addr);
> +	ret = ti_sci_proc_set_config(kproc->tsp, boot_addr, 0, 0);
> +	if (ret)
> +		goto put_mbox;
> +
> +	ret = k3_rproc_release(kproc);
> +	if (ret)
> +		goto put_mbox;
> +
> +	return 0;
> +
> +put_mbox:
> +	mbox_free_channel(kproc->mbox);
> +	return ret;
> +}
> +
> +/*
> + * Stop the DSP remote processor.
> + *
> + * This function puts the DSP processor into reset, and finishes processing
> + * of any pending messages. This callback is invoked only in remoteproc mode.
> + */
> +static int k3_dsp_rproc_stop(struct rproc *rproc)
> +{
> +	struct k3_rproc *kproc = rproc->priv;
> +
> +	mbox_free_channel(kproc->mbox);
> +
> +	k3_rproc_reset(kproc);
> +
> +	return 0;
> +}
> +
> +/*
> + * Attach to a running DSP 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 DSP core. This callback is invoked only in IPC-only
> + * mode.
> + */
> +static int k3_dsp_rproc_attach(struct rproc *rproc)
> +{
> +	struct k3_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +	int ret;
> +
> +	ret = k3_rproc_request_mbox(rproc);
> +	if (ret)
> +		return ret;
> +
> +	dev_info(dev, "DSP initialized in IPC-only mode\n");
> +	return 0;
> +}
> +
> +/*
> + * Detach from a running DSP remote processor (IPC-only mode)
> + *
> + * This rproc detach callback performs the opposite operation to attach callback
> + * and only needs to release the mailbox, the DSP core is not stopped and will
> + * be left to continue to run its booted firmware. This callback is invoked only
> + * in IPC-only mode.
> + */
> +static int k3_dsp_rproc_detach(struct rproc *rproc)
> +{
> +	struct k3_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +
> +	mbox_free_channel(kproc->mbox);
> +	dev_info(dev, "DSP deinitialized in IPC-only mode\n");
> +	return 0;
> +}
> +
> +
> +static const struct rproc_ops k3_dsp_rproc_ops = {
> +	.start		= k3_dsp_rproc_start,
> +	.stop		= k3_dsp_rproc_stop,
> +	.kick		= k3_rproc_kick,
> +	.da_to_va	= k3_rproc_da_to_va,
> +};
> +
> +static int k3_dsp_rproc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	const struct k3_rproc_dev_data *data;
> +	struct k3_rproc *kproc;
> +	struct rproc *rproc;
> +	const char *fw_name;
> +	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)
> +		return dev_err_probe(dev, ret, "failed to parse firmware-name property\n");
> +
> +	rproc = rproc_alloc(dev, dev_name(dev), &k3_dsp_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_rproc_prepare;
> +		rproc->ops->unprepare = k3_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 = dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
> +				    "failed to get ti-sci handle\n");
> +		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_probe(dev, ret, "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 = dev_err_probe(dev, PTR_ERR(kproc->reset),
> +				    "failed to get reset\n");
> +		goto put_sci;
> +	}
> +
> +	kproc->tsp = k3_rproc_of_get_tsp(dev, kproc->ti_sci);
> +	if (IS_ERR(kproc->tsp)) {
> +		ret = dev_err_probe(dev, PTR_ERR(kproc->tsp),
> +				    "failed to construct ti-sci proc control\n");
> +		goto put_sci;
> +	}
> +
> +	ret = ti_sci_proc_request(kproc->tsp);
> +	if (ret < 0) {
> +		dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
> +		goto free_tsp;
> +	}
> +
> +	ret = k3_rproc_of_get_memories(pdev, kproc);
> +	if (ret)
> +		goto release_tsp;
> +
> +	ret = k3_reserved_mem_init(kproc);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "reserved memory init failed\n");
> +		goto release_tsp;
> +	}
> +
> +	ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
> +					       NULL, &p_state);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
> +		goto release_mem;
> +	}
> +
> +	/* configure J721E devices for either remoteproc or IPC-only mode */
> +	if (p_state) {
> +		dev_info(dev, "configured DSP for IPC-only mode\n");
> +		rproc->state = RPROC_DETACHED;
> +		/* override rproc ops with only required IPC-only mode ops */
> +		rproc->ops->prepare = NULL;
> +		rproc->ops->unprepare = NULL;
> +		rproc->ops->start = NULL;
> +		rproc->ops->stop = NULL;
> +		rproc->ops->attach = k3_dsp_rproc_attach;
> +		rproc->ops->detach = k3_dsp_rproc_detach;
> +		rproc->ops->get_loaded_rsc_table = k3_get_loaded_rsc_table;
> +	} else {
> +		dev_info(dev, "configured DSP for remoteproc mode\n");
> +		/*
> +		 * ensure the DSP local reset is asserted to ensure the DSP
> +		 * 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_probe(dev, ret, "failed to get reset status\n");
> +				goto release_mem;
> +			} else if (ret == 0) {
> +				dev_warn(dev, "local reset is deasserted for device\n");
> +				k3_rproc_reset(kproc);
> +			}
> +		}
> +	}
> +
> +	ret = rproc_add(rproc);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
> +		goto release_mem;
> +	}
> +
> +	platform_set_drvdata(pdev, kproc);
> +
> +	return 0;
> +
> +release_mem:
> +	k3_reserved_mem_exit(kproc);
> +release_tsp:
> +	ret1 = ti_sci_proc_release(kproc->tsp);
> +	if (ret1)
> +		dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(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 (%pe)\n", ERR_PTR(ret1));
> +free_rproc:
> +	rproc_free(rproc);
> +	return ret;
> +}
> +
> +static void k3_dsp_rproc_remove(struct platform_device *pdev)
> +{
> +	struct k3_rproc *kproc = platform_get_drvdata(pdev);
> +	struct rproc *rproc = kproc->rproc;
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +
> +	if (rproc->state == RPROC_ATTACHED) {
> +		ret = rproc_detach(rproc);
> +		if (ret) {
> +			/* Note this error path leaks resources */
> +			dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(ret));
> +			return;
> +		}
> +	}
> +
> +	rproc_del(kproc->rproc);
> +
> +	ret = ti_sci_proc_release(kproc->tsp);
> +	if (ret)
> +		dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret));
> +
> +	kfree(kproc->tsp);
> +
> +	ret = ti_sci_put_handle(kproc->ti_sci);
> +	if (ret)
> +		dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret));
> +
> +	k3_reserved_mem_exit(kproc);
> +	rproc_free(kproc->rproc);
> +}
> +
> +static const struct k3_rproc_mem_data c66_mems[] = {
> +	{ .name = "l2sram", .dev_addr = 0x800000 },
> +	{ .name = "l1pram", .dev_addr = 0xe00000 },
> +	{ .name = "l1dram", .dev_addr = 0xf00000 },
> +};
> +
> +/* C71x cores only have a L1P Cache, there are no L1P SRAMs */
> +static const struct k3_rproc_mem_data c71_mems[] = {
> +	{ .name = "l2sram", .dev_addr = 0x800000 },
> +	{ .name = "l1dram", .dev_addr = 0xe00000 },
> +};
> +
> +static const struct k3_rproc_mem_data c7xv_mems[] = {
> +	{ .name = "l2sram", .dev_addr = 0x800000 },
> +};
> +
> +static const struct k3_rproc_dev_data c66_data = {
> +	.mems = c66_mems,
> +	.num_mems = ARRAY_SIZE(c66_mems),
> +	.boot_align_addr = SZ_1K,
> +	.uses_lreset = true,
> +};
> +
> +static const struct k3_rproc_dev_data c71_data = {
> +	.mems = c71_mems,
> +	.num_mems = ARRAY_SIZE(c71_mems),
> +	.boot_align_addr = SZ_2M,
> +	.uses_lreset = false,
> +};
> +
> +static const struct k3_rproc_dev_data c7xv_data = {
> +	.mems = c7xv_mems,
> +	.num_mems = ARRAY_SIZE(c7xv_mems),
> +	.boot_align_addr = SZ_2M,
> +	.uses_lreset = false,
> +};
> +
> +static const struct of_device_id k3_dsp_of_match[] = {
> +	{ .compatible = "ti,j721e-c66-dsp", .data = &c66_data, },
> +	{ .compatible = "ti,j721e-c71-dsp", .data = &c71_data, },
> +	{ .compatible = "ti,j721s2-c71-dsp", .data = &c71_data, },
> +	{ .compatible = "ti,am62a-c7xv-dsp", .data = &c7xv_data, },
> +	{ /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, k3_dsp_of_match);
> +
> +static struct platform_driver k3_dsp_rproc_driver = {
> +	.probe	= k3_dsp_rproc_probe,
> +	.remove_new = k3_dsp_rproc_remove,
> +	.driver	= {
> +		.name = "k3-dsp-rproc",
> +		.of_match_table = k3_dsp_of_match,
> +	},
> +};
> +
> +module_platform_driver(k3_dsp_rproc_driver);
> +
> +MODULE_AUTHOR("Suman Anna <s-anna at ti.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("TI K3 DSP Remoteproc driver");


From seanjc at google.com  Mon Feb  5 15:32:09 2024
From: seanjc at google.com (Sean Christopherson)
Date: Mon, 5 Feb 2024 15:32:09 -0800
Subject: [PATCH] KVM: selftests: Fix GUEST_PRINTF() format warnings in ARM code
In-Reply-To: <Zb69ryhz_mDw9UK4@linux.dev>
References: <20240202234603.366925-1-seanjc@google.com> <Zb69ryhz_mDw9UK4@linux.dev>
Message-ID: <ZcFv-cYtQghiz2JK@google.com>

On Sat, Feb 03, 2024, Oliver Upton wrote:
> On Fri, Feb 02, 2024 at 03:46:03PM -0800, Sean Christopherson wrote:
> > Fix a pile of -Wformat warnings in the KVM ARM selftests code, almost all
> > of which are benign "long" versus "long long" issues (selftests are 64-bit
> > only, and the guest printf code treats "ll" the same as "l").  The code
> > itself isn't problematic, but the warnings make it impossible to build ARM
> > selftests with -Werror, which does detect real issues from time to time.
> > 
> > Opportunistically have GUEST_ASSERT_BITMAP_REG() interpret set_expected,
> > which is a bool, as an unsigned decimal value, i.e. have it print '0' or
> > '1' instead of '0x0' or '0x1'.
> > 
> > Signed-off-by: Sean Christopherson <seanjc at google.com>
> 
> This all looks good to me. Just want to confirm before applying: you're
> not planning any other patches that'll go through your tree that depend
> on this right?

Correct.  There's one patch in kvm-x86/selftests (see below) that touches some
of the same files, but unless I had a bad -ENOCOFFEE on Friday, there are no conflicts.

[2/5] KVM: selftests: aarch64: Remove redundant newlines
      https://github.com/kvm-x86/linux/commit/95be17e4008b


From namhyung at kernel.org  Mon Feb  5 16:19:40 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Mon,  5 Feb 2024 16:19:40 -0800
Subject: [PATCH 0/1] tools: perf: Expose sample ID / stream ID to python scripts
In-Reply-To: <20240123103137.1890779-1-ben.gainey@arm.com>
References: <20240123103137.1890779-1-ben.gainey@arm.com>
Message-ID: <170717858575.1700937.1642994669335608980.b4-ty@kernel.org>

On Tue, 23 Jan 2024 10:31:36 +0000, Ben Gainey wrote:
> This patch modifies the perf python scripting engine so that the ID and
> STREAM_ID are exposed as part of the sample so that they may be
> correlated to the corresponding throttle/unthrottle event (for example).
> 
> NB: For scripts where perf_db_export_mode = True, this may be a breaking
> change depending on how the script is constructed. Each field is passed
> to `sample_table` as an argument so any script that is written as:
> 
> [...]

Applied to perf-tools-next, thanks!

Best regards,
-- 
Namhyung Kim <namhyung at kernel.org>


From andre.przywara at arm.com  Mon Feb  5 16:47:05 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 6 Feb 2024 00:47:05 +0000
Subject: [PATCH 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC support
In-Reply-To: <3788758.kQq0lBPeGt@jernej-laptop>
References: <20240204094404.149776-1-andre.przywara@arm.com>
 <20240204094404.149776-4-andre.przywara@arm.com>
 <3280179.44csPzL39Z@jernej-laptop> <3788758.kQq0lBPeGt@jernej-laptop>
Message-ID: <205b3828-6ec2-4670-ac68-a61e5cc0597d@arm.com>

Hi Jernej,

thanks for having a look!

On 05/02/2024 19:20, Jernej ?krabec wrote:
> Dne ponedeljek, 05. februar 2024 ob 19:12:45 CET je Jernej ?krabec napisal(a):
>> Hi Andre!
>>
>> Dne nedelja, 04. februar 2024 ob 10:44:04 CET je Andre Przywara napisal(a):
>>> The Remix Mini PC is a "mini computer" using the Allwinner H64 SoC,
>>> which appears to be just a relabelled A64. It was launched in 2015 by
>>> the now defunct company Jide, and shipped with a desktop optimised
>>> version of Android. It features
>>> 	- Allwinner H64 Soc (4 * Arm Cortex-A53 cores)
>>> 	- 1 or 2 GB DRAM
>>> 	- 8 or 16 GB eMMC flash
>>> 	- 100 MBit Ethernet port (using an X-Powers AC200 PHY)
>>> 	- RTL8723BS WiFi & Bluetooth chip
>>> 	- HDMI port
>>> 	- two USB 2.0 ports
>>> 	- 3.5mm AV port
>>> 	- microSD card slot
>>>
>>> The devicetree covers most peripherals, though there is no agreed
>>> binding for the PHY chip yet, so this is left out.
>>>
>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>> ---
>>>   arch/arm64/boot/dts/allwinner/Makefile        |   1 +
>>>   .../allwinner/sun50i-h64-remix-mini-pc.dts    | 357 ++++++++++++++++++
>>>   2 files changed, 358 insertions(+)
>>>   create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
>>>
>>> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
>>> index 91d505b385de..2db3b15ad09f 100644
>>> --- a/arch/arm64/boot/dts/allwinner/Makefile
>>> +++ b/arch/arm64/boot/dts/allwinner/Makefile
>>> @@ -16,6 +16,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb
>>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab-early-adopter.dtb
>>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
>>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
>>> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
>>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
>>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
>>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
>>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
>>> new file mode 100644
>>> index 000000000000..537923a541a8
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
>>> @@ -0,0 +1,357 @@
>>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>>> +// Copyright (c) 2018 ARM Ltd.
>>
>> Shouldn't be 2024?

Well, that just documents that sad fact that I indeed created this file 
6 years ago, but just managed now to actually send this. Is there a 
requirement for this being "recent"?

>>
>>> +
>>> +/dts-v1/;
>>> +
>>> +#include "sun50i-a64.dtsi"
>>> +#include "sun50i-a64-cpu-opp.dtsi"
>>> +
>>> +#include <dt-bindings/gpio/gpio.h>
>>> +
>>> +/ {
>>> +	model = "Remix Mini PC";
>>> +	compatible = "jide,remix-mini-pc", "allwinner,sun50i-h64",
>>> +		     "allwinner,sun50i-a64";
>>> +
>>> +	aliases {
>>> +		ethernet1 = &rtl8723bs;
>>> +		serial0 = &uart0;
>>> +	};
>>> +
>>> +	chosen {
>>> +		stdout-path = "serial0:115200n8";
>>> +	};
>>> +
>>> +	hdmi-connector {
>>> +		compatible = "hdmi-connector";
>>> +		type = "a";
>>> +
>>> +		port {
>>> +			hdmi_con_in: endpoint {
>>> +				remote-endpoint = <&hdmi_out_con>;
>>> +			};
>>> +		};
>>> +	};
>>> +
>>> +	reg_vcc5v: regulator-5v {
>>> +		/* board wide 5V supply directly from the DC input */
>>> +		compatible = "regulator-fixed";
>>> +		regulator-name = "vcc-5v";
>>> +		regulator-min-microvolt = <5000000>;
>>> +		regulator-max-microvolt = <5000000>;
>>> +		regulator-always-on;
>>> +	};
>>> +
>>> +	wifi_pwrseq: wifi_pwrseq {
>>> +		compatible = "mmc-pwrseq-simple";
>>> +		pinctrl-names = "default";
>>> +		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
>>> +		post-power-on-delay-ms = <200>;
>>> +	};
>>> +};
>>> +
>>> +&codec {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&codec_analog {
>>> +	cpvdd-supply = <&reg_eldo1>;
>>> +	status = "okay";
>>> +};
>>> +
>>> +&cpu0 {
>>> +	cpu-supply = <&reg_dcdc2>;
>>> +};
>>> +
>>> +&cpu1 {
>>> +	cpu-supply = <&reg_dcdc2>;
>>> +};
>>> +
>>> +&cpu2 {
>>> +	cpu-supply = <&reg_dcdc2>;
>>> +};
>>> +
>>> +&cpu3 {
>>> +	cpu-supply = <&reg_dcdc2>;
>>> +};
>>> +
>>> +&dai {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&de {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&ehci0 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&ehci1 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&hdmi {
>>> +	hvcc-supply = <&reg_dldo1>;
>>> +	status = "okay";
>>> +};
>>> +
>>> +&hdmi_out {
>>> +	hdmi_out_con: endpoint {
>>> +		remote-endpoint = <&hdmi_con_in>;
>>> +	};
>>> +};
>>> +
>>> +/* Connects to the AC200 chip */
>>> +&i2c0 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&i2c0_pins>;
>>> +	status = "okay";
>>> +};
>>> +
>>> +&i2c0_pins {
>>> +	bias-pull-up;
>>> +};
>>> +
>>> +&mmc0 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&mmc0_pins>;
>>> +	vmmc-supply = <&reg_dcdc1>;
>>> +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
>>> +	disable-wp;
>>> +	bus-width = <4>;
>>> +	status = "okay";
>>> +};
>>> +
>>> +&mmc1 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&mmc1_pins>;
>>> +	vmmc-supply = <&reg_aldo1>;
>>> +	vqmmc-supply = <&reg_dldo4>;
>>> +	mmc-pwrseq = <&wifi_pwrseq>;
>>> +	bus-width = <4>;
>>> +	non-removable;
>>> +	status = "okay";
>>> +
>>> +	rtl8723bs: wifi at 1 {
>>> +		reg = <1>;
>>> +		interrupt-parent = <&r_pio>;
>>> +		interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
>>> +		interrupt-names = "host-wake";
>>> +	};
>>
>> Node without compatible doesn't help. Please remove it.

Huh, but where do I put the the IRQ line then? And every other RTL8723BS 
user seems to do the same?

>>
>>> +};
>>> +
>>> +&mmc2 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
>>> +	vmmc-supply = <&reg_dcdc1>;
>>> +	vqmmc-supply = <&reg_eldo1>;
>>> +	bus-width = <8>;
>>> +	non-removable;
>>> +	mmc-ddr-1_8v;
>>> +	mmc-hs200-1_8v;
>>
>> Aren't these speed modes enabled by default?

Enabled by who? Our current sunxi-mmc driver? I cannot find anything in 
the binding that suggests that there would be some default settings.

> Sorry, mmc-hs200-1_8v is ok, but mmc-ddr-1_8v should be
> removed.

Mmh, I am confused: I thought after the H5 eMMC mishap we figured that 
all speed modes supported by the eMMC chip should be listed in the DT?
So any driver wouldn't need to make assumptions, and if a particular 
mode shows problems on a board, we just remove that mode from the DT.
Actually, thinking about that, I guess I should list HS-400 as well? The 
BSP kernel uses that mode.
Or do you mean to say that in particular DDR (@1.8V) is problematic? I 
cannot test at the moment, but could try later to force that mode.

Cheers,
Andre


>>> +	cap-mmc-hw-reset;
>>> +	status = "okay";
>>> +};
>>> +
>>> +&ohci0 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&ohci1 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&pio {
>>> +	vcc-pb-supply = <&reg_dcdc1>;
>>> +	vcc-pc-supply = <&reg_dcdc1>;
>>> +	vcc-pd-supply = <&reg_dcdc1>;
>>> +	vcc-pe-supply = <&reg_dcdc1>;
>>> +	vcc-pf-supply = <&reg_dcdc1>;
>>> +	vcc-pg-supply = <&reg_dldo4>;
>>> +	vcc-ph-supply = <&reg_dcdc1>;
>>> +};
>>> +
>>> +&r_ir {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&r_pio {
>>> +	/*
>>> +	 * We cannot add that supply for now since it would create a circular
>>> +	 * dependency between pinctrl, the regulator and the RSB Bus.
>>> +	 *
>>> +	 * vcc-pl-supply = <&reg_aldo2>;
>>> +	 */
>>> +};
>>> +
>>> +&r_rsb {
>>> +	status = "okay";
>>> +
>>> +	axp803: pmic at 3a3 {
>>> +		compatible = "x-powers,axp803";
>>> +		reg = <0x3a3>;
>>> +		interrupt-parent = <&r_intc>;
>>> +		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
>>> +		x-powers,drive-vbus-en;
>>> +
>>> +		vin1-supply = <&reg_vcc5v>;
>>> +		vin2-supply = <&reg_vcc5v>;
>>> +		vin3-supply = <&reg_vcc5v>;
>>> +		vin5-supply = <&reg_vcc5v>;
>>> +		vin6-supply = <&reg_vcc5v>;
>>> +		aldoin-supply = <&reg_vcc5v>;
>>> +		dldoin-supply = <&reg_vcc5v>;
>>> +		eldoin-supply = <&reg_vcc5v>;
>>> +		fldoin-supply = <&reg_vcc5v>;
>>> +		drivevbus-supply = <&reg_vcc5v>;
>>> +		ips-supply = <&reg_vcc5v>;
>>> +
>>> +		status = "okay";
>>> +	};
>>> +};
>>> +
>>> +#include "axp803.dtsi"
>>> +
>>> +&ac_power_supply {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&reg_dcdc1 {
>>> +	regulator-always-on;
>>> +	regulator-min-microvolt = <3300000>;
>>> +	regulator-max-microvolt = <3300000>;
>>> +	regulator-name = "vcc-3v3";
>>> +};
>>> +
>>> +&reg_dcdc2 {
>>> +	regulator-always-on;
>>> +	regulator-min-microvolt = <1040000>;
>>> +	regulator-max-microvolt = <1300000>;
>>> +	regulator-name = "vdd-cpux";
>>> +};
>>> +
>>> +/* DCDC3 is polyphased with DCDC2 */
>>> +
>>> +&reg_dcdc5 {
>>> +	regulator-always-on;
>>> +	regulator-min-microvolt = <1500000>;
>>> +	regulator-max-microvolt = <1500000>;
>>> +	regulator-name = "vcc-dram";
>>> +};
>>> +
>>> +/* Deviates from the reset default of 1.1V. */
>>> +&reg_dcdc6 {
>>> +	regulator-always-on;
>>> +	regulator-min-microvolt = <1200000>;
>>> +	regulator-max-microvolt = <1200000>;
>>> +	regulator-name = "vdd-sys";
>>> +};
>>> +
>>> +&reg_aldo1 {
>>> +	regulator-min-microvolt = <3300000>;
>>> +	regulator-max-microvolt = <3300000>;
>>> +	regulator-name = "vcc-wifi";
>>> +};
>>> +
>>> +&reg_aldo2 {
>>> +	/* Specifying R_PIO consumer would create circular dependency. */
>>> +	regulator-always-on;
>>> +	regulator-min-microvolt = <3300000>;
>>> +	regulator-max-microvolt = <3300000>;
>>> +	regulator-name = "vcc-pl";
>>> +};
>>> +
>>> +&reg_aldo3 {
>>> +	regulator-always-on;
>>> +	regulator-min-microvolt = <3000000>;
>>> +	regulator-max-microvolt = <3000000>;
>>> +	regulator-name = "vcc-pll-avcc";
>>> +};
>>> +
>>> +/* AC200 power supply */
>>> +&reg_dldo1 {
>>> +	regulator-always-on;
>>> +	regulator-min-microvolt = <3300000>;
>>> +	regulator-max-microvolt = <3300000>;
>>> +	regulator-name = "vcc-ave-33";
>>> +};
>>> +
>>> +&reg_dldo4 {
>>> +	regulator-min-microvolt = <3300000>;
>>> +	regulator-max-microvolt = <3300000>;
>>> +	regulator-name = "vcc-wifi-io";
>>> +};
>>> +
>>> +&reg_drivevbus {
>>> +	regulator-name = "usb0-vbus";
>>> +	status = "okay";
>>> +};
>>> +
>>> +&reg_eldo1 {
>>> +	regulator-always-on;
>>> +	regulator-min-microvolt = <1800000>;
>>> +	regulator-max-microvolt = <1800000>;
>>> +	regulator-name = "vcc-cpvdd-dram-emmc";
>>> +};
>>> +
>>> +/* Supplies the arisc management core, needed by TF-A to power off cores. */
>>> +&reg_fldo2 {
>>> +	regulator-always-on;
>>> +	regulator-min-microvolt = <1100000>;
>>> +	regulator-max-microvolt = <1100000>;
>>> +	regulator-name = "vdd-cpus";
>>> +};
>>> +
>>> +&reg_rtc_ldo {
>>> +	regulator-name = "vcc-rtc";
>>> +};
>>> +
>>> +&simplefb_hdmi {
>>> +	vcc-hdmi-supply = <&reg_dcdc1>;
>>> +};
>>> +
>>> +&sound {
>>> +	simple-audio-card,aux-devs = <&codec_analog>;
>>> +	simple-audio-card,widgets = "Microphone", "Microphone Jack",
>>> +				    "Headphone", "Headphone Jack";
>>> +	simple-audio-card,routing =
>>> +			"Left DAC", "DACL",
>>> +			"Right DAC", "DACR",
>>> +			"Headphone Jack", "HP",
>>> +			"ADCL", "Left ADC",
>>> +			"ADCR", "Right ADC",
>>> +			"MIC2", "Microphone Jack";
>>> +	status = "okay";
>>> +};
>>> +
>>> +/* On the (unpopulated) UART pads. */
>>> +&uart0 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&uart0_pb_pins>;
>>> +	status = "okay";
>>> +};
>>> +
>>> +&uart1 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
>>> +	uart-has-rtscts;
>>> +	status = "okay";
>>> +
>>> +	bluetooth {
>>> +		compatible = "realtek,rtl8723bs-bt";
>>> +		enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
>>> +		max-speed = <1500000>;
>>> +	};
>>> +};
>>> +
>>> +&usb_otg {
>>> +	dr_mode = "host";
>>> +	status = "okay";
>>> +};
>>> +
>>> +&usbphy {
>>> +	usb0_vbus-supply = <&reg_drivevbus>;
>>> +	usb1_vbus-supply = <&reg_drivevbus>;
>>> +	status = "okay";
>>> +};
>>>
>>
>>
>>
>>
>>
> 
> 
> 
> 


From wens at csie.org  Mon Feb  5 17:03:21 2024
From: wens at csie.org (Chen-Yu Tsai)
Date: Tue, 6 Feb 2024 09:03:21 +0800
Subject: [PATCH 2/2] arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes
In-Reply-To: <8371906.NyiUUSuA9g@jernej-laptop>
References: <20240204093255.148972-1-andre.przywara@arm.com>
 <20240204093255.148972-3-andre.przywara@arm.com> <8371906.NyiUUSuA9g@jernej-laptop>
Message-ID: <CAGb2v66=s-k5xNtL9N_Tyzzk92u_32Hk_+V+rFVYne3=fnMjdA@mail.gmail.com>

On Tue, Feb 6, 2024 at 2:26?AM Jernej ?krabec <jernej.skrabec at gmail.com> wrote:
>
> Dne nedelja, 04. februar 2024 ob 10:32:55 CET je Andre Przywara napisal(a):
> > In contrast to other devices using Allwinner SoCs, the Transpeed 8K618-T
> > TV box uses a mainline supported WiFi chip: it's a Broadcom 4335
> > compatible, packaged by a company called Murata.
> > It works nicely with the Linux driver, when providing the respective
> > firmware files.
> >
> > Add the required DT nodes to let the kernel find the SDIO device.
>
> Can you reword message in a way to omit Linux?

Probably reword it to say "add nodes so that custom MAC addresses can be
associated with it"?

> >
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  .../sun50i-h618-transpeed-8k618-t.dts         | 23 +++++++++++++++++++
> >  1 file changed, 23 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> > index 8ea1fd41aeba..7ec4098e707b 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> > @@ -16,6 +16,7 @@ / {
> >
> >       aliases {
> >               serial0 = &uart0;
> > +             ethernet1 = &sdio_wifi;
> >       };
> >
> >       chosen {
> > @@ -39,6 +40,15 @@ reg_vcc3v3: vcc3v3 {
> >               regulator-max-microvolt = <3300000>;
> >               regulator-always-on;
> >       };
> > +
> > +     wifi_pwrseq: wifi_pwrseq {
> > +             compatible = "mmc-pwrseq-simple";
> > +             clocks = <&rtc CLK_OSC32K_FANOUT>;
> > +             clock-names = "ext_clock";
> > +             pinctrl-0 = <&x32clk_fanout_pin>;
> > +             pinctrl-names = "default";
> > +             reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
> > +     };
> >  };
> >
> >  &ehci0 {
> > @@ -60,6 +70,19 @@ &mmc0 {
> >       status = "okay";
> >  };
> >
> > +&mmc1 {
> > +     vmmc-supply = <&reg_dldo1>;
> > +     vqmmc-supply = <&reg_aldo1>;
> > +     mmc-pwrseq = <&wifi_pwrseq>;
> > +     bus-width = <4>;
> > +     non-removable;
> > +     status = "okay";
> > +
> > +     sdio_wifi: wifi at 1 {
> > +             reg = <1>;
> > +     };
>
> I don't think this node and alias are useful in any way. SDIO scan will find
> device regardless and potential mac property set up by bootloader will be
> ignored anyway.

If a node with the matching function number is found, the MMC core will
associate the node with the SDIO function device before calling the probe
function. It has worked correctly for quite some time.

If the driver isn't taking the MAC address given in the DT, then that's
a driver issue.

ChenYu

> Best regards,
> Jernej
>
> > +};
> > +
> >  &mmc2 {
> >       vmmc-supply = <&reg_dldo1>;
> >       vqmmc-supply = <&reg_aldo1>;
> >
>
>
>
>


From yoshihiro.shimoda.uh at renesas.com  Mon Feb  5 17:26:07 2024
From: yoshihiro.shimoda.uh at renesas.com (Yoshihiro Shimoda)
Date: Tue, 6 Feb 2024 01:26:07 +0000
Subject: [PATCH] iommu/ipmmu-vmsa: Minor cleanups
In-Reply-To: <791877b0d310dc2ab7dc616d2786ab24252b9b8e.1707151207.git.robin.murphy@arm.com>
References: <791877b0d310dc2ab7dc616d2786ab24252b9b8e.1707151207.git.robin.murphy@arm.com>
Message-ID: <OSZPR01MB8611DFF66D172D3A8C480012D8462@OSZPR01MB8611.jpnprd01.prod.outlook.com>

> From: Robin Murphy, Sent: Tuesday, February 6, 2024 1:43 AM
> 
> Remove the of_match_ptr() which was supposed to have gone long ago, but
> managed to got lost in a fix-squashing mishap. On a similar theme, we
> may as well also modernise the PM ops to get rid of the clunky #ifdefs,
> and modernise the resource mapping to keep the checkpatch brigade happy.
> 
> Link: https://lore.kernel.org/linux-iommu/Yxni3d6CdI3FZ5D+ at 8bytes.org/
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>

Best regards,
Yoshihiro Shimoda

> ---
>  drivers/iommu/ipmmu-vmsa.c | 15 ++++-----------
>  1 file changed, 4 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index ace1fc4bd34b..90d3f03242db 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -1005,7 +1005,6 @@ static const struct of_device_id ipmmu_of_ids[] = {
>  static int ipmmu_probe(struct platform_device *pdev)
>  {
>  	struct ipmmu_vmsa_device *mmu;
> -	struct resource *res;
>  	int irq;
>  	int ret;
> 
> @@ -1025,8 +1024,7 @@ static int ipmmu_probe(struct platform_device *pdev)
>  		return ret;
> 
>  	/* Map I/O memory and request IRQ. */
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	mmu->base = devm_ioremap_resource(&pdev->dev, res);
> +	mmu->base = devm_platform_ioremap_resource(pdev, 0);
>  	if (IS_ERR(mmu->base))
>  		return PTR_ERR(mmu->base);
> 
> @@ -1123,7 +1121,6 @@ static void ipmmu_remove(struct platform_device *pdev)
>  	ipmmu_device_reset(mmu);
>  }
> 
> -#ifdef CONFIG_PM_SLEEP
>  static int ipmmu_resume_noirq(struct device *dev)
>  {
>  	struct ipmmu_vmsa_device *mmu = dev_get_drvdata(dev);
> @@ -1153,18 +1150,14 @@ static int ipmmu_resume_noirq(struct device *dev)
>  }
> 
>  static const struct dev_pm_ops ipmmu_pm  = {
> -	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, ipmmu_resume_noirq)
> +	NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, ipmmu_resume_noirq)
>  };
> -#define DEV_PM_OPS	&ipmmu_pm
> -#else
> -#define DEV_PM_OPS	NULL
> -#endif /* CONFIG_PM_SLEEP */
> 
>  static struct platform_driver ipmmu_driver = {
>  	.driver = {
>  		.name = "ipmmu-vmsa",
> -		.of_match_table = of_match_ptr(ipmmu_of_ids),
> -		.pm = DEV_PM_OPS,
> +		.of_match_table = ipmmu_of_ids,
> +		.pm = pm_sleep_ptr(&ipmmu_pm),
>  	},
>  	.probe = ipmmu_probe,
>  	.remove_new = ipmmu_remove,
> --
> 2.39.2.101.g768bb238c484.dirty



From xiaobo55x at gmail.com  Mon Feb  5 17:32:17 2024
From: xiaobo55x at gmail.com (Haibo Xu)
Date: Tue, 6 Feb 2024 09:32:17 +0800
Subject: [PATCH v5 00/12] RISCV: Add kvm Sstc timer selftests
In-Reply-To: <86zfwe6frn.wl-maz@kernel.org>
References: <cover.1705916069.git.haibo1.xu@intel.com> <CAJve8onDbX44Ph6a-FdO2+p7QOQLah-7OyF+yUc06wud+SvmQQ@mail.gmail.com>
 <86zfwe6frn.wl-maz@kernel.org>
Message-ID: <CAJve8okvg=UTWgmE=TpJT=nQJB3i6R_Tn_0AS1MtsD0mP8i3JQ@mail.gmail.com>

On Tue, Feb 6, 2024 at 12:24?AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Mon, 05 Feb 2024 13:10:26 +0000,
> Haibo Xu <xiaobo55x at gmail.com> wrote:
> >
> > Hi Marc,
> >
> > Could you help review the first 3 patches in this series?
>
> For these 3 patches:
>
> Reviewed-by: Marc Zyngier <maz at kernel.org>
>

Thanks for the review!

> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


From dawei.li at shingroup.cn  Mon Feb  5 17:39:30 2024
From: dawei.li at shingroup.cn (Dawei Li)
Date: Tue, 6 Feb 2024 09:39:30 +0800
Subject: [PATCH] arm64: remove unneeded BUILD_BUG_ON assertion
In-Reply-To: <ZcDPOgoQE8IncTHY@FVFF77S0Q05N>
References: <20240202040211.3118918-1-dawei.li@shingroup.cn>
 <ZcDPOgoQE8IncTHY@FVFF77S0Q05N>
Message-ID: <DB04BC31DF5E38DB+ZcGN0lyKk+olujm8@centos8>

Hi Mark,

Thanks for reviewing.

On Mon, Feb 05, 2024 at 12:06:18PM +0000, Mark Rutland wrote:
> On Fri, Feb 02, 2024 at 12:02:11PM +0800, Dawei Li wrote:
> > Since commit c02433dd6de3 ("arm64: split thread_info from task stack"),
> > CONFIG_THREAD_INFO_IN_TASK is enabled unconditionally for arm64. So
> > remove this always-true assertion from arch_dup_task_struct.
> > 
> > Signed-off-by: Dawei Li <dawei.li at shingroup.cn>
> > ---
> >  arch/arm64/kernel/process.c | 3 ---
> >  1 file changed, 3 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> > index 7387b68c745b..4ae31b7af6c3 100644
> > --- a/arch/arm64/kernel/process.c
> > +++ b/arch/arm64/kernel/process.c
> > @@ -290,9 +290,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
> >  		fpsimd_preserve_current_state();
> >  	*dst = *src;
> >  
> > -	/* We rely on the above assignment to initialize dst's thread_flags: */
> > -	BUILD_BUG_ON(!IS_ENABLED(CONFIG_THREAD_INFO_IN_TASK));
> > -
> 
> Does the above cause any problem today, or is this patch just a cleanup?

It's just a cleanup patch.

> 
> For the benefit of other reviewers, the assertion and comment were added in
> commit:
> 
>   4585fc59c0e8 ("arm64/sve: Fix wrong free for task->thread.sve_state")
> 
> .. back in 2019, 3 years after commit:
> 
>   c02433dd6de3 ("arm64: split thread_info from task stack")
> 
> The comment and assertion were a safety-net for backports, since commit
> 4585fc59c0e8 was a fix which dependend upon the thread_info being contained
> within task_struct, and couldn't be backported to kernels without
> CONFIG_THREAD_INFO_IN_TASK.

Thanks for the update! It helps.

> 
> I'm sure that we currently have plenty of other code with a similar (but
> undocumented) dependency. Given we've unconditionally selected

Totally agreed.

> CONFIG_THREAD_INFO_IN_TASK since v4.10, and the oldest longterm stable kernel
> is v4.19 (with v4.14 having EOL'd last month), I think it makes sense to delete
> the assertion and comment.
> 
> So FWIW:
> 
> Acked-by: Mark Rutland <mark.rutland at arm.com>
> 
> Mark.
> 

Thanks,

    Dawei


From martin.petersen at oracle.com  Mon Feb  5 18:08:55 2024
From: martin.petersen at oracle.com (Martin K. Petersen)
Date: Mon,  5 Feb 2024 21:08:55 -0500
Subject: [PATCH v1 1/1] ufs: core: fix shift issue in ufshcd_clear_cmd
In-Reply-To: <20240205104905.24929-1-alice.chao@mediatek.com>
References: <20240205104905.24929-1-alice.chao@mediatek.com>
Message-ID: <170718504180.1101069.12960133692209922791.b4-ty@oracle.com>

On Mon, 05 Feb 2024 18:49:04 +0800, alice.chao at mediatek.com wrote:

> When task_tag > 32 (in mcq mode), 1U << task_tag will out of bound
> for u32 mask. Fix this bug to prevent SHIFT_ISSUE (Bitwise shifts
> that are out of bounds for their data type).
> 
> [name:debug_monitors&]Unexpected kernel BRK exception at EL1
> [name:traps&]Internal error: BRK handler: 00000000f2005514 [#1] PREEMPT SMP
> [name:mediatek_cpufreq_hw&]cpufreq stop DVFS log done
> [name:mrdump&]Kernel Offset: 0x1ba5800000 from 0xffffffc008000000
> [name:mrdump&]PHYS_OFFSET: 0x80000000
> [name:mrdump&]pstate: 22400005 (nzCv daif +PAN -UAO)
> [name:mrdump&]pc : [0xffffffdbaf52bb2c] ufshcd_clear_cmd+0x280/0x288
> [name:mrdump&]lr : [0xffffffdbaf52a774] ufshcd_wait_for_dev_cmd+0x3e4/0x82c
> [name:mrdump&]sp : ffffffc0081471b0
> <snip>
> Workqueue: ufs_eh_wq_0 ufshcd_err_handler
> Call trace:
>  dump_backtrace+0xf8/0x144
>  show_stack+0x18/0x24
>  dump_stack_lvl+0x78/0x9c
>  dump_stack+0x18/0x44
>  mrdump_common_die+0x254/0x480 [mrdump]
>  ipanic_die+0x20/0x30 [mrdump]
>  notify_die+0x15c/0x204
>  die+0x10c/0x5f8
>  arm64_notify_die+0x74/0x13c
>  do_debug_exception+0x164/0x26c
>  el1_dbg+0x64/0x80
>  el1h_64_sync_handler+0x3c/0x90
>  el1h_64_sync+0x68/0x6c
>  ufshcd_clear_cmd+0x280/0x288
>  ufshcd_wait_for_dev_cmd+0x3e4/0x82c
>  ufshcd_exec_dev_cmd+0x5bc/0x9ac
>  ufshcd_verify_dev_init+0x84/0x1c8
>  ufshcd_probe_hba+0x724/0x1ce0
>  ufshcd_host_reset_and_restore+0x260/0x574
>  ufshcd_reset_and_restore+0x138/0xbd0
>  ufshcd_err_handler+0x1218/0x2f28
>  process_one_work+0x5fc/0x1140
>  worker_thread+0x7d8/0xe20
>  kthread+0x25c/0x468
>  ret_from_fork+0x10/0x20
> 
> [...]

Applied to 6.8/scsi-fixes, thanks!

[1/1] ufs: core: fix shift issue in ufshcd_clear_cmd
      https://git.kernel.org/mkp/scsi/c/b513d30d59bb

-- 
Martin K. Petersen	Oracle Linux Engineering


From aford173 at gmail.com  Mon Feb  5 18:25:08 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon, 5 Feb 2024 20:25:08 -0600
Subject: [PATCH V8 05/12] arm64: dts: imx8mp: add HDMI power-domains
In-Reply-To: <1880028.tdWV9SEqCh@steina-w>
References: <20240203165307.7806-1-aford173@gmail.com> <20240203165307.7806-6-aford173@gmail.com>
 <1880028.tdWV9SEqCh@steina-w>
Message-ID: <CAHCN7xJZ5m1kZwx_9whx7Bv3B4N8mhB1feZUO4PpcosBXe5R2g@mail.gmail.com>

On Mon, Feb 5, 2024 at 1:26?AM Alexander Stein
<alexander.stein at ew.tq-group.com> wrote:
>
> Hi Adam,
>
> thanks for working on this.
>
> Am Samstag, 3. Februar 2024, 17:52:45 CET schrieb Adam Ford:
> > From: Lucas Stach <l.stach at pengutronix.de>
> >
> > This adds the PGC and HDMI blk-ctrl nodes providing power control for
> > HDMI subsystem peripherals.
> >
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > ---
> > V2:  Add missing power-domains hdcp and hrv
> > ---
> >  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 38 +++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index
> > 76c73daf546b..5c54073de615 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > @@ -836,6 +836,23 @@ pgc_mediamix: power-domain at 10 {
> >                                                        <&clk
> IMX8MP_CLK_MEDIA_APB_ROOT>;
> >                                       };
> >
> > +                                     pgc_hdmimix: power-
> domains at 14 {
>

Alexander,

Thanks for the feedback.

> As per Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml the node
> should be called power-domain at .
>
> > +                                             #power-domain-
> cells = <0>;
> > +                                             reg =
> <IMX8MP_POWER_DOMAIN_HDMIMIX>;
> > +                                             clocks = <&clk
> IMX8MP_CLK_HDMI_ROOT>,
> > +                                                      <&clk
> IMX8MP_CLK_HDMI_APB>;
> > +                                             assigned-clocks =
> <&clk IMX8MP_CLK_HDMI_AXI>,
> > +
>   <&clk IMX8MP_CLK_HDMI_APB>;
> > +                                             assigned-clock-
> parents = <&clk IMX8MP_SYS_PLL2_500M>,
> > +
>          <&clk IMX8MP_SYS_PLL1_133M>;
> > +                                             assigned-clock-
> rates = <500000000>, <133000000>;
> > +                                     };
> > +
> > +                                     pgc_hdmi_phy: power-
> domains at 15 {
>
> As per Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml the node
> should be called power-domain at .

Whoops.  I totally missed these when I applied them.  I'll have them
fixed on the next spin.
>
> > +                                             #power-domain-
> cells = <0>;
> > +                                             reg =
> <IMX8MP_POWER_DOMAIN_HDMI_PHY>;
> > +                                     };
> > +
> >                                       pgc_mipi_phy2: power-
> domain at 16 {
> >                                               #power-domain-
> cells = <0>;
> >                                               reg =
> <IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
> > @@ -1361,6 +1378,27 @@ eqos: ethernet at 30bf0000 {
> >                               intf_mode = <&gpr 0x4>;
> >                               status = "disabled";
> >                       };
> > +
> > +                     hdmi_blk_ctrl: blk-ctrl at 32fc0000 {
> > +                             compatible = "fsl,imx8mp-hdmi-blk-
> ctrl", "syscon";
> > +                             reg = <0x32fc0000 0x23c>;
> > +                             clocks = <&clk IMX8MP_CLK_HDMI_APB>,
> > +                                      <&clk
> IMX8MP_CLK_HDMI_ROOT>,
> > +                                      <&clk
> IMX8MP_CLK_HDMI_REF_266M>,
> > +                                      <&clk IMX8MP_CLK_HDMI_24M>,
> > +                                      <&clk
> IMX8MP_CLK_HDMI_FDCC_TST>;
> > +                             clock-names = "apb", "axi",
> "ref_266m", "ref_24m", "fdcc";
> > +                             power-domains = <&pgc_hdmimix>,
> <&pgc_hdmimix>,
> > +                                             <&pgc_hdmimix>,
> <&pgc_hdmimix>,
> > +                                             <&pgc_hdmimix>,
> <&pgc_hdmimix>,
> > +                                             <&pgc_hdmimix>,
> <&pgc_hdmi_phy>,
> > +                                             <&pgc_hdmimix>,
> <&pgc_hdmimix>;
> > +                             power-domain-names = "bus",
> "irqsteer", "lcdif",
> > +                                                  "pai", "pvi",
> "trng",
> > +                                                  "hdmi-tx",
> "hdmi-tx-phy",
> > +                                                  "hdcp",
> "hrv";
> > +                             #power-domain-cells = <1>;
> > +                     };
> >               };
> >
>
> According to RM this block is part of AIPS4, so it should be below
> hsio_blk_ctrl.

This is how it was when I got it, but I should have caught it.  Thanks
for that.  It looks like the subsequent HDMI, IRQ_steerting, LCDIF and
PHY ones are also out of place.

adam
>
> Best regards,
> Alexander
>
> >               aips5: bus at 30c00000 {
>
>
> --
> TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht M?nchen, HRB 105018
> Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> http://www.tq-group.com/
>
>


From richard.xnu.clark at gmail.com  Mon Feb  5 18:47:55 2024
From: richard.xnu.clark at gmail.com (richard clark)
Date: Tue, 6 Feb 2024 10:47:55 +0800
Subject: Question about the ipi_raise filter usage and output
In-Reply-To: <20240205053819.3cf848f0@rorschach.local.home>
References: <CAJNi4rMpt88Gz+149wR9crzApmfUEfpS05sbOgAvOhzh2+Brbg@mail.gmail.com>
 <20240205053819.3cf848f0@rorschach.local.home>
Message-ID: <CAJNi4rN+hRg0UxhNus727t7f_D5XPMOyCdpJM2WoZH4yfw8kmQ@mail.gmail.com>

Hi Steve,

On Mon, Feb 5, 2024 at 6:38?PM Steven Rostedt <rostedt at goodmis.org> wrote:
>
> On Mon, 5 Feb 2024 17:57:29 +0800
> richard clark <richard.xnu.clark at gmail.com> wrote:
>
> > I try to write below:
> > echo 'target_cpus == 11 && reason == "Function call interrupts"' >
> > events/ipi/ipi_raise/filter
>
> You mean when it is sent only to CPU 11? Not when the event is
> happening on CPU 11. Like the above example, the event was triggered on
> CPU 10, but the mask was for all the other CPUs.
>
> If you are looking for just CPU 11, you can do:
>
>   echo 'target_cpus == 0x800 && reason == "Function call interrupts"'
>

Seems both 'target_cpus == 0x800 && reason == "Function call
interrupts"' and 'target_cpus & 0x800 && reason == "Function call
interrupts"' don't work:

# cat events/ipi/ipi_raise/enable
1
# cat events/ipi/ipi_raise/filter
target_cpus == 0x800 && reason == "Function call interrupts"

The kernel module code snippet:

void ipi_func_run_cpu(void *info)
{
        pr_info("remote function runs on cpu[%d].\n", smp_processor_id());
}
static int __init ipi_send_init(void)
{
        int target = (smp_processor_id() + 1) % nr_cpu_ids;
        int ret = smp_call_function_single(target, ipi_func_run_cpu,
NULL, true);
        pr_info("ipi cpu[%d --> %d] ret = %d\n", smp_processor_id(),
target, ret);
        return 0;
}
...
module_init(ipi_send_init);
module_exit(ipi_send_exit);

$ sudo taskset -c 10 insmod ipi_send.ko
$ dmesg
...
[84931.864273] remote function runs on cpu[11].
[84931.864282] ipi cpu[10 --> 11] ret = 0

The 'cat trace' will output the below message with 'reason ==
"Function call interrupts"' filter:
...
            sudo-5726    [007] dn.h1.. 84302.833545: ipi_raise:
target_mask=00000000,00000001 (Function call interrupts)
            sudo-5726    [007] dn.h2.. 84302.837544: ipi_raise:
target_mask=00000000,00000001 (Function call interrupts)
          insmod-5727    [011] dn.h1.. 84302.841545: ipi_raise:
target_mask=00000000,00000001 (Function call interrupts)
          insmod-5727    [010] ....1.. 84302.843966: ipi_raise:
target_mask=00000000,00000bff (Function call interrupts)
          insmod-5727    [010] ....1.. 84302.843975: ipi_raise:
target_mask=00000000,00000bff (Function call interrupts)
          insmod-5727    [010] ....1.. 84302.844184: ipi_raise:
target_mask=00000000,00000800 (Function call interrupts)
...

I find that 'target_cpus == 0xfff && reason == "Function call
interrupts"' doesn't have output in the buffer, but 'target_cpus &
0xfff && reason == "Function call interrupts"' does. I also tried to
use 'target_cpus & 0xf00 && reason == "Function call interrupts"' in
my case, the trace buffer has nothing after the kmod inserted.

Any comments?

>
>
> -- Steve


From ychuang570808 at gmail.com  Mon Feb  5 18:52:19 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Tue,  6 Feb 2024 02:52:19 +0000
Subject: [PATCH v4 0/4] Add support for nuvoton ma35d1 pin control
Message-ID: <20240206025223.35147-1-ychuang570808@gmail.com>

From: Jacky Huang <ychuang3 at nuvoton.com>

This patch series adds the pin control and GPIO driver for the nuvoton ma35d1
ARMv8 SoC. It includes DT binding documentation, the ma35d1 pin control driver,
and device tree updates.

This pin control driver has been tested on the ma35d1 som board with Linux 6.8-rc1.

v4:
  - Update the pinctrl driver Kconfig
    - Add depends to CONFIG_PINCTRL_MA35D1 to prevent compilation errors.
  - Update the pinctrl driver
    - Utilize devm_kcalloc() instead of devm_kzalloc().
    - Employ ARRAY_SIZE() instead of sizeof()/sizeof().

v3:
  - Update DTS and YAML files
    - Corrected the unit address of nodes gpioa ~ gpion.
    - Removed the invalid "pin-default" node.
    - Removed the phandle entry from "nuvoton,pins".
  - Update pinctrl driver
    - Fixed the Kconfig by using "depend on" instead of "if".
    - Removed unused #include of header files.
    - Utilized immutable irq_chip instead of dynamic irq_chip.
    - Replaced ma35_dt_free_map() with pinconf_generic_dt_free_map().
    - Implemented other minor fixes as suggested by the reviewer.

v2:
  - Update nuvoton,ma35d1-pinctrl.yaml
    - Update the 'nuvoton,pins' to follow the style of rockchip pinctrl approch.
    - Use power-source to indicate the pin voltage selection which follow the
      realtek pinctrl approch.
    - Instead of integer, use drive-strength-microamp to specify the real driving
      strength capability of IO pins.
  - Update ma35d1 pinctrl driver
    - Add I/O drive strength lookup table for translating device tree setting
      into control register.
  - Remove ma35d1-pinfunc.h which is unused after update definition of 'nuvoton,pins'.


Jacky Huang (4):
  dt-bindings: reset: Add syscon to nuvoton ma35d1 system-management
    node
  dt-bindings: pinctrl: Document nuvoton ma35d1 pin control
  arm64: dts: nuvoton: Add pinctrl support for ma35d1
  pinctrl: nuvoton: Add ma35d1 pinctrl and GPIO driver

 .../pinctrl/nuvoton,ma35d1-pinctrl.yaml       |  163 ++
 .../bindings/reset/nuvoton,ma35d1-reset.yaml  |    3 +-
 .../boot/dts/nuvoton/ma35d1-iot-512m.dts      |   80 +-
 .../boot/dts/nuvoton/ma35d1-som-256m.dts      |   83 +-
 arch/arm64/boot/dts/nuvoton/ma35d1.dtsi       |  150 +-
 drivers/pinctrl/nuvoton/Kconfig               |   19 +
 drivers/pinctrl/nuvoton/Makefile              |    2 +
 drivers/pinctrl/nuvoton/pinctrl-ma35.c        | 1211 +++++++++++
 drivers/pinctrl/nuvoton/pinctrl-ma35.h        |   50 +
 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c      | 1797 +++++++++++++++++
 10 files changed, 3548 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/nuvoton,ma35d1-pinctrl.yaml
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.c
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.h
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c

-- 
2.34.1



From ychuang570808 at gmail.com  Mon Feb  5 18:52:20 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Tue,  6 Feb 2024 02:52:20 +0000
Subject: [PATCH v4 1/4] dt-bindings: reset: Add syscon to nuvoton ma35d1 system-management node
In-Reply-To: <20240206025223.35147-1-ychuang570808@gmail.com>
References: <20240206025223.35147-1-ychuang570808@gmail.com>
Message-ID: <20240206025223.35147-2-ychuang570808@gmail.com>

From: Jacky Huang <ychuang3 at nuvoton.com>

Add a compatible 'syscon' to the system management node since the system
control registers are mapped by this driver. The other driver must access
the system control registers through 'regmap' using a phandle that
references this node.

Signed-off-by: Jacky Huang <ychuang3 at nuvoton.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Philipp Zabel <p.zabel at pengutronix.de>
---
 .../devicetree/bindings/reset/nuvoton,ma35d1-reset.yaml        | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/reset/nuvoton,ma35d1-reset.yaml b/Documentation/devicetree/bindings/reset/nuvoton,ma35d1-reset.yaml
index 34c5c1c08ec1..3ce7dcecd87a 100644
--- a/Documentation/devicetree/bindings/reset/nuvoton,ma35d1-reset.yaml
+++ b/Documentation/devicetree/bindings/reset/nuvoton,ma35d1-reset.yaml
@@ -18,6 +18,7 @@ properties:
   compatible:
     items:
       - const: nuvoton,ma35d1-reset
+      - const: syscon
 
   reg:
     maxItems: 1
@@ -37,7 +38,7 @@ examples:
   - |
 
     system-management at 40460000 {
-        compatible = "nuvoton,ma35d1-reset";
+        compatible = "nuvoton,ma35d1-reset", "syscon";
         reg = <0x40460000 0x200>;
         #reset-cells = <1>;
     };
-- 
2.34.1



From ychuang570808 at gmail.com  Mon Feb  5 18:52:21 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Tue,  6 Feb 2024 02:52:21 +0000
Subject: [PATCH v4 2/4] dt-bindings: pinctrl: Document nuvoton ma35d1 pin control
In-Reply-To: <20240206025223.35147-1-ychuang570808@gmail.com>
References: <20240206025223.35147-1-ychuang570808@gmail.com>
Message-ID: <20240206025223.35147-3-ychuang570808@gmail.com>

From: Jacky Huang <ychuang3 at nuvoton.com>

Add documentation to describe nuvoton ma35d1 pin control and GPIO.

Signed-off-by: Jacky Huang <ychuang3 at nuvoton.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../pinctrl/nuvoton,ma35d1-pinctrl.yaml       | 163 ++++++++++++++++++
 1 file changed, 163 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/nuvoton,ma35d1-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/nuvoton,ma35d1-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/nuvoton,ma35d1-pinctrl.yaml
new file mode 100644
index 000000000000..8b9ec263213f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/nuvoton,ma35d1-pinctrl.yaml
@@ -0,0 +1,163 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/nuvoton,ma35d1-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton MA35D1 pin control and GPIO
+
+maintainers:
+  - Shan-Chun Hung <schung at nuvoton.com>
+  - Jacky Huang <ychuang3 at nuvoton.com>
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+properties:
+  compatible:
+    enum:
+      - nuvoton,ma35d1-pinctrl
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 1
+
+  nuvoton,sys:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      phandle of the system-management node.
+
+  ranges: true
+
+patternProperties:
+  "^gpio@[0-9a-f]+$":
+    type: object
+    additionalProperties: false
+    properties:
+      gpio-controller: true
+
+      '#gpio-cells':
+        const: 2
+
+      reg:
+        maxItems: 1
+
+      clocks:
+        maxItems: 1
+
+      interrupt-controller: true
+
+      '#interrupt-cells':
+        const: 2
+
+      interrupts:
+        description:
+          The interrupt outputs to sysirq.
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - '#gpio-cells'
+      - reg
+      - clocks
+      - interrupt-controller
+      - '#interrupt-cells'
+      - interrupts
+
+  "^pin-[a-z0-9]+$":
+    type: object
+    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.
+
+    $ref: pincfg-node.yaml#
+
+    properties:
+      power-source:
+        description: |
+          Valid arguments are described as below:
+          0: power supply of 1.8V
+          1: power supply of 3.3V
+        enum: [0, 1]
+
+      drive-strength-microamp:
+        oneOf:
+          - enum: [ 2900, 4400, 5800, 7300, 8600, 10100, 11500, 13000 ]
+            description: 1.8V I/O driving strength
+          - enum: [ 17100, 25600, 34100, 42800, 48000, 56000, 77000, 82000 ]
+            description: 3.3V I/O driving strength
+
+    unevaluatedProperties: false
+
+  "-grp$":
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+    properties:
+      nuvoton,pins:
+        description:
+          Each entry consists of 4 parameters and represents the mux and config
+          setting for one pin.
+        $ref: /schemas/types.yaml#/definitions/uint32-matrix
+        minItems: 1
+        items:
+          items:
+            - minimum: 0
+              maximum: 13
+              description:
+                Pin bank.
+            - minimum: 0
+              maximum: 15
+              description:
+                Pin bank index.
+            - minimum: 0
+              maximum: 15
+              description:
+                Mux 0 means GPIO and mux 1 to 15 means the specific device function.
+
+required:
+  - compatible
+  - nuvoton,sys
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+
+    pinctrl at 40040000 {
+        compatible = "nuvoton,ma35d1-pinctrl";
+        #address-cells = <1>;
+        #size-cells = <1>;
+        nuvoton,sys = <&sys>;
+        ranges = <0 0x40040000 0xc00>;
+
+        gpio at 0 {
+            reg = <0x0 0x40>;
+            interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&clk GPA_GATE>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+        };
+
+        uart-grp {
+            uart11-pins {
+                nuvoton,pins = <11 0 2>,
+                               <11 1 2>,
+                               <11 2 2>,
+                               <11 3 2>;
+                bias-disable;
+                power-source = <1>;
+            };
+        };
+    };
-- 
2.34.1



From ychuang570808 at gmail.com  Mon Feb  5 18:52:22 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Tue,  6 Feb 2024 02:52:22 +0000
Subject: [PATCH v4 3/4] arm64: dts: nuvoton: Add pinctrl support for ma35d1
In-Reply-To: <20240206025223.35147-1-ychuang570808@gmail.com>
References: <20240206025223.35147-1-ychuang570808@gmail.com>
Message-ID: <20240206025223.35147-4-ychuang570808@gmail.com>

From: Jacky Huang <ychuang3 at nuvoton.com>

Add 'pinctrl' node and 'gpioa' ~ 'gpion' nodes to the dtsi of ma35d1
SoC and describe default pin configurations.

Enable all UART nodes presented on som and iot boards, and add pinctrl
function settings to these nodes.

Signed-off-by: Jacky Huang <ychuang3 at nuvoton.com>
---
 .../boot/dts/nuvoton/ma35d1-iot-512m.dts      |  80 +++++++++-
 .../boot/dts/nuvoton/ma35d1-som-256m.dts      |  83 +++++++++-
 arch/arm64/boot/dts/nuvoton/ma35d1.dtsi       | 150 +++++++++++++++++-
 3 files changed, 304 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts b/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
index b89e2be6abae..9482bec1aa57 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
@@ -14,6 +14,10 @@ / {
 
 	aliases {
 		serial0 = &uart0;
+		serial10 = &uart10;
+		serial12 = &uart12;
+		serial13 = &uart13;
+		serial14 = &uart14;
 	};
 
 	chosen {
@@ -33,10 +37,6 @@ clk_hxt: clock-hxt {
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &clk {
 	assigned-clocks = <&clk CAPLL>,
 			  <&clk DDRPLL>,
@@ -54,3 +54,75 @@ &clk {
 			   "integer",
 			   "integer";
 };
+
+&pinctrl {
+	uart-grp {
+		pinctrl_uart0: uart0-pins {
+			nuvoton,pins = <4 14 1>,
+				       <4 15 1>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart10: uart10-pins {
+			nuvoton,pins = <7 4 2>,
+				       <7 5 2>,
+				       <7 6 2>,
+				       <7 7 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart12: uart12-pins {
+			nuvoton,pins = <2 13 2>,
+				       <2 14 2>,
+				       <2 15 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart13: uart13-pins {
+			nuvoton,pins = <7 12 3>,
+				       <7 13 3>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart14: uart14-pins {
+			nuvoton,pins = <7 14 2>,
+				       <7 15 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart0>;
+	status = "okay";
+};
+
+&uart10 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart10>;
+	status = "okay";
+};
+
+&uart12 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart12>;
+	status = "okay";
+};
+
+&uart13 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart13>;
+	status = "okay";
+};
+
+&uart14 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart14>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts b/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
index a1ebddecb7f8..f6f20a17e501 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
@@ -14,6 +14,10 @@ / {
 
 	aliases {
 		serial0 = &uart0;
+		serial11 = &uart11;
+		serial12 = &uart12;
+		serial14 = &uart14;
+		serial16 = &uart16;
 	};
 
 	chosen {
@@ -33,10 +37,6 @@ clk_hxt: clock-hxt {
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &clk {
 	assigned-clocks = <&clk CAPLL>,
 			  <&clk DDRPLL>,
@@ -54,3 +54,78 @@ &clk {
 			   "integer",
 			   "integer";
 };
+
+&pinctrl {
+	uart-grp {
+		pinctrl_uart0: uart0-pins {
+			nuvoton,pins = <4 14 1>,
+				       <4 15 1>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart11: uart11-pins {
+			nuvoton,pins = <11 0 2>,
+				       <11 1 2>,
+				       <11 2 2>,
+				       <11 3 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart12: uart12-pins {
+			nuvoton,pins = <8 1 2>,
+				       <8 2 2>,
+				       <8 3 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart14: uart14-pins {
+			nuvoton,pins = <8 5 2>,
+				       <8 6 2>,
+				       <8 7 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart16: uart16-pins {
+			nuvoton,pins = <10 0 2>,
+				       <10 1 2>,
+				       <10 2 2>,
+				       <10 3 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart0>;
+	status = "okay";
+};
+
+&uart11 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart11>;
+	status = "okay";
+};
+
+&uart12 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart12>;
+	status = "okay";
+};
+
+&uart14 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart14>;
+	status = "okay";
+};
+
+&uart16 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart16>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi b/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
index 781cdae566a0..5f366f4c7fde 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
@@ -83,7 +83,7 @@ soc {
 		ranges;
 
 		sys: system-management at 40460000 {
-			compatible = "nuvoton,ma35d1-reset";
+			compatible = "nuvoton,ma35d1-reset", "syscon";
 			reg = <0x0 0x40460000 0x0 0x200>;
 			#reset-cells = <1>;
 		};
@@ -95,6 +95,154 @@ clk: clock-controller at 40460200 {
 			clocks = <&clk_hxt>;
 		};
 
+		pinctrl: pinctrl at 40040000 {
+			compatible = "nuvoton,ma35d1-pinctrl";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			nuvoton,sys = <&sys>;
+			ranges = <0x0 0x0 0x40040000 0xc00>;
+
+			gpioa: gpio at 0 {
+				reg = <0x0 0x40>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPA_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiob: gpio at 40 {
+				reg = <0x40 0x40>;
+				interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPB_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpioc: gpio at 80 {
+				reg = <0x80 0x40>;
+				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPC_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiod: gpio at c0 {
+				reg = <0xc0 0x40>;
+				interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPD_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpioe: gpio at 100 {
+				reg = <0x100 0x40>;
+				interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPE_GATE>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiof: gpio at 140 {
+				reg = <0x140 0x40>;
+				interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPF_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiog: gpio at 180 {
+				reg = <0x180 0x40>;
+				interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPG_GATE>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpioh: gpio at 1c0 {
+				reg = <0x1c0 0x40>;
+				interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPH_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpioi: gpio at 200 {
+				reg = <0x200 0x40>;
+				interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPI_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpioj: gpio at 240 {
+				reg = <0x240 0x40>;
+				interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPJ_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiok: gpio at 280 {
+				reg = <0x280 0x40>;
+				interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPK_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiol: gpio at 2c0 {
+				reg = <0x2c0 0x40>;
+				interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPL_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiom: gpio at 300 {
+				reg = <0x300 0x40>;
+				interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPM_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpion: gpio at 340 {
+				reg = <0x340 0x40>;
+				interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPN_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+		};
+
 		uart0: serial at 40700000 {
 			compatible = "nuvoton,ma35d1-uart";
 			reg = <0x0 0x40700000 0x0 0x100>;
-- 
2.34.1



From ychuang570808 at gmail.com  Mon Feb  5 18:52:23 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Tue,  6 Feb 2024 02:52:23 +0000
Subject: [PATCH v4 4/4] pinctrl: nuvoton: Add ma35d1 pinctrl and GPIO driver
In-Reply-To: <20240206025223.35147-1-ychuang570808@gmail.com>
References: <20240206025223.35147-1-ychuang570808@gmail.com>
Message-ID: <20240206025223.35147-5-ychuang570808@gmail.com>

From: Jacky Huang <ychuang3 at nuvoton.com>

Add common pinctrl and GPIO driver for Nuvoton MA35 series SoC, and
add support for ma35d1 pinctrl.

Signed-off-by: Jacky Huang <ychuang3 at nuvoton.com>
---
 drivers/pinctrl/nuvoton/Kconfig          |   19 +
 drivers/pinctrl/nuvoton/Makefile         |    2 +
 drivers/pinctrl/nuvoton/pinctrl-ma35.c   | 1211 +++++++++++++++
 drivers/pinctrl/nuvoton/pinctrl-ma35.h   |   50 +
 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c | 1797 ++++++++++++++++++++++
 5 files changed, 3079 insertions(+)
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.c
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.h
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c

diff --git a/drivers/pinctrl/nuvoton/Kconfig b/drivers/pinctrl/nuvoton/Kconfig
index 2abbfcec1fae..7eadaaf48d6e 100644
--- a/drivers/pinctrl/nuvoton/Kconfig
+++ b/drivers/pinctrl/nuvoton/Kconfig
@@ -45,3 +45,22 @@ config PINCTRL_NPCM8XX
 	  Say Y or M here to enable pin controller and GPIO support for
 	  the Nuvoton NPCM8XX SoC. This is strongly recommended when
 	  building a kernel that will run on this chip.
+
+config PINCTRL_MA35
+	bool
+	depends on (ARCH_MA35 || COMPILE_TEST) && OF
+	select GENERIC_PINCTRL_GROUPS
+	select GENERIC_PINMUX_FUNCTIONS
+	select GENERIC_PINCONF
+	select GPIOLIB
+	select GPIO_GENERIC
+	select GPIOLIB_IRQCHIP
+	select MFD_SYSCON
+
+config PINCTRL_MA35D1
+	bool "Pinctrl and GPIO driver for Nuvoton MA35D1"
+	depends on (ARCH_MA35 || COMPILE_TEST) && OF
+	select PINCTRL_MA35
+	help
+	  Say Y here to enable pin controller and GPIO support
+	  for Nuvoton MA35D1 SoC.
diff --git a/drivers/pinctrl/nuvoton/Makefile b/drivers/pinctrl/nuvoton/Makefile
index 08031eab0af6..346c5082bc60 100644
--- a/drivers/pinctrl/nuvoton/Makefile
+++ b/drivers/pinctrl/nuvoton/Makefile
@@ -4,3 +4,5 @@
 obj-$(CONFIG_PINCTRL_WPCM450)	+= pinctrl-wpcm450.o
 obj-$(CONFIG_PINCTRL_NPCM7XX)	+= pinctrl-npcm7xx.o
 obj-$(CONFIG_PINCTRL_NPCM8XX)	+= pinctrl-npcm8xx.o
+obj-$(CONFIG_PINCTRL_MA35)	+= pinctrl-ma35.o
+obj-$(CONFIG_PINCTRL_MA35D1)	+= pinctrl-ma35d1.o
diff --git a/drivers/pinctrl/nuvoton/pinctrl-ma35.c b/drivers/pinctrl/nuvoton/pinctrl-ma35.c
new file mode 100644
index 000000000000..8efbe559be1e
--- /dev/null
+++ b/drivers/pinctrl/nuvoton/pinctrl-ma35.c
@@ -0,0 +1,1211 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Nuvoton Technology Corp.
+ *
+ * Author: Shan-Chun Hung <schung at nuvoton.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio/driver.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../core.h"
+#include "../pinconf.h"
+#include "pinctrl-ma35.h"
+
+#define MA35_MFP_REG_BASE		0x80
+#define MA35_MFP_REG_SZ_PER_BANK	8
+#define MA35_MFP_BITS_PER_PORT		4
+
+#define MA35_GPIO_BANK_MAX		14
+#define MA35_GPIO_PORT_MAX		16
+
+/* GPIO control registers */
+#define MA35_GP_REG_MODE		0x00
+#define MA35_GP_REG_DINOFF		0x04
+#define MA35_GP_REG_DOUT		0x08
+#define MA35_GP_REG_DATMSK		0x0c
+#define MA35_GP_REG_PIN			0x10
+#define MA35_GP_REG_DBEN		0x14
+#define MA35_GP_REG_INTTYPE		0x18
+#define MA35_GP_REG_INTEN		0x1c
+#define MA35_GP_REG_INTSRC		0x20
+#define MA35_GP_REG_SMTEN		0x24
+#define MA35_GP_REG_SLEWCTL		0x28
+#define MA35_GP_REG_SPW			0x2c
+#define MA35_GP_REG_PUSEL		0x30
+#define MA35_GP_REG_DSL			0x38
+#define MA35_GP_REG_DSH			0x3c
+
+/* GPIO mode control */
+#define MA35_GP_MODE_INPUT		0x0
+#define MA35_GP_MODE_OUTPUT		0x1
+#define MA35_GP_MODE_OPEN_DRAIN		0x2
+#define MA35_GP_MODE_QUASI		0x3
+
+/* GPIO pull-up and pull-down selection control */
+#define MA35_GP_PUSEL_DISABLE		0x0
+#define MA35_GP_PUSEL_PULL_UP		0x1
+#define MA35_GP_PUSEL_PULL_DOWN		0x2
+
+/* Each pin data input/output is mapped by address mapping */
+#define MA35_PIN_MAP_BASE		0x800
+#define MA35_GP_DSH_BASE_PORT		8
+
+#define MVOLT_1800			0
+#define MVOLT_3300			1
+
+static const char * const gpio_group_name[] = {
+	"gpioa", "gpiob", "gpioc", "gpiod", "gpioe", "gpiof", "gpiog",
+	"gpioh", "gpioi", "gpioj", "gpiok", "gpiol", "gpiom", "gpion",
+};
+
+static const u32 ds_1800mv_tbl[] = {
+	2900, 4400, 5800, 7300, 8600, 10100, 11500, 13000,
+};
+
+static const u32 ds_3300mv_tbl[] = {
+	17100, 25600, 34100, 42800, 48000, 56000, 77000, 82000,
+};
+
+struct ma35_pin_func {
+	const char		*name;
+	const char		**groups;
+	u32			ngroups;
+};
+
+struct ma35_pin_setting {
+	u32			offset;
+	u32			shift;
+	u32			muxval;
+	unsigned long		*configs;
+	unsigned int		nconfigs;
+};
+
+struct ma35_pin_group {
+	const char		*name;
+	unsigned int		npins;
+	unsigned int		*pins;
+	struct ma35_pin_setting	*settings;
+};
+
+struct ma35_pin_bank {
+	void __iomem		*reg_base;
+	struct clk		*clk;
+	int			irq;
+	u8			nr_pins;
+	const char		*name;
+	u8			bank_num;
+	bool			valid;
+	struct device_node	*np;
+	struct gpio_chip	chip;
+	u32			irqtype;
+	u32			irqinten;
+	struct regmap		*regmap;
+	struct device		*dev;
+	spinlock_t		lock;
+};
+
+struct ma35_pin_ctrl {
+	struct ma35_pin_bank	*pin_banks;
+	u32			nr_banks;
+	u32			nr_pins;
+};
+
+struct ma35_pinctrl {
+	struct device		*dev;
+	struct ma35_pin_ctrl	*ctrl;
+	struct pinctrl_dev	*pctl;
+	const struct ma35_pinctrl_soc_info *info;
+	struct regmap		*regmap;
+	struct ma35_pin_group	*groups;
+	unsigned int		ngroups;
+	struct ma35_pin_func	*functions;
+	unsigned int		nfunctions;
+};
+
+static int ma35_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return npctl->ngroups;
+}
+
+static const char *ma35_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return npctl->groups[selector].name;
+}
+
+static int ma35_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
+			       const unsigned int **pins, unsigned int *npins)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	if (selector >= npctl->ngroups)
+		return -EINVAL;
+
+	*pins = npctl->groups[selector].pins;
+	*npins = npctl->groups[selector].npins;
+
+	return 0;
+}
+
+static struct ma35_pin_group *ma35_pinctrl_find_group_by_name(
+			      const struct ma35_pinctrl *npctl, const char *name)
+{
+	int i;
+
+	for (i = 0; i < npctl->ngroups; i++) {
+		if (!strcmp(npctl->groups[i].name, name))
+			return &npctl->groups[i];
+	}
+	return NULL;
+}
+
+static int ma35_pinctrl_dt_node_to_map_func(struct pinctrl_dev *pctldev,
+					    struct device_node *np,
+					    struct pinctrl_map **map,
+					    unsigned int *num_maps)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+	struct ma35_pin_group *grp;
+	struct pinctrl_map *new_map;
+	struct device_node *parent;
+	int map_num = 1;
+	int i;
+
+	/*
+	 * first find the group of this node and check if we need create
+	 * config maps for pins
+	 */
+	grp = ma35_pinctrl_find_group_by_name(npctl, np->name);
+	if (!grp) {
+		dev_err(npctl->dev, "unable to find group for node %s\n", np->name);
+		return -EINVAL;
+	}
+
+	map_num += grp->npins;
+	new_map = devm_kcalloc(pctldev->dev, map_num, sizeof(*new_map), GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	*map = new_map;
+	*num_maps = map_num;
+	/* create mux map */
+	parent = of_get_parent(np);
+	if (!parent) {
+		devm_kfree(pctldev->dev, new_map);
+		return -EINVAL;
+	}
+
+	new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+	new_map[0].data.mux.function = parent->name;
+	new_map[0].data.mux.group = np->name;
+	of_node_put(parent);
+
+	new_map++;
+	for (i = 0; i < grp->npins; i++) {
+		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+		new_map[i].data.configs.group_or_pin = pin_get_name(pctldev, grp->pins[i]);
+		new_map[i].data.configs.configs = grp->settings[i].configs;
+		new_map[i].data.configs.num_configs = grp->settings[i].nconfigs;
+	}
+	dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n",
+		(*map)->data.mux.function, (*map)->data.mux.group, map_num);
+
+	return 0;
+}
+
+static const struct pinctrl_ops ma35_pctrl_ops = {
+	.get_groups_count = ma35_get_groups_count,
+	.get_group_name = ma35_get_group_name,
+	.get_group_pins = ma35_get_group_pins,
+	.dt_node_to_map = ma35_pinctrl_dt_node_to_map_func,
+	.dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int ma35_pinmux_get_func_count(struct pinctrl_dev *pctldev)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return npctl->nfunctions;
+}
+
+static const char *ma35_pinmux_get_func_name(struct pinctrl_dev *pctldev,
+					     unsigned int selector)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return npctl->functions[selector].name;
+}
+
+static int ma35_pinmux_get_func_groups(struct pinctrl_dev *pctldev,
+				       unsigned int function,
+				       const char *const **groups,
+				       unsigned int *const num_groups)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = npctl->functions[function].groups;
+	*num_groups = npctl->functions[function].ngroups;
+
+	return 0;
+}
+
+static int ma35_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
+			       unsigned int group)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+	struct ma35_pin_group *grp = &npctl->groups[group];
+	struct ma35_pin_setting *setting = grp->settings;
+	u32 i, regval;
+
+	dev_dbg(npctl->dev, "enable function %s group %s\n",
+		npctl->functions[selector].name, npctl->groups[group].name);
+
+	for (i = 0; i < grp->npins; i++) {
+		regmap_read(npctl->regmap, setting->offset, &regval);
+		regval &= ~GENMASK(setting->shift + 3, setting->shift);
+		regval |= setting->muxval << setting->shift;
+		regmap_write(npctl->regmap, setting->offset, regval);
+		setting++;
+	}
+	return 0;
+}
+
+static const struct pinmux_ops ma35_pmx_ops = {
+	.get_functions_count = ma35_pinmux_get_func_count,
+	.get_function_name = ma35_pinmux_get_func_name,
+	.get_function_groups = ma35_pinmux_get_func_groups,
+	.set_mux = ma35_pinmux_set_mux,
+	.strict = true,
+};
+
+static int ma35_gpio_core_direction_in(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
+	void __iomem *reg_mode = bank->reg_base + MA35_GP_REG_MODE;
+	unsigned long flags;
+	unsigned int regval;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	regval = readl(reg_mode);
+	regval &= ~GENMASK(gpio * 2 + 1, gpio * 2);
+	regval |= MA35_GP_MODE_INPUT << gpio * 2;
+	writel(regval, reg_mode);
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+static int ma35_gpio_core_get(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
+
+	return readl(bank->reg_base + MA35_PIN_MAP_BASE + gpio * 4);
+}
+
+static void ma35_gpio_core_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
+
+	writel(val, bank->reg_base + MA35_PIN_MAP_BASE + gpio * 4);
+}
+
+static int ma35_gpio_core_direction_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
+	void __iomem *reg_dout = bank->reg_base + MA35_GP_REG_DOUT;
+	void __iomem *reg_mode = bank->reg_base + MA35_GP_REG_MODE;
+	unsigned long flags;
+	unsigned int regval;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	regval = readl(reg_dout);
+	if (val)
+		writel(regval | BIT(gpio), reg_dout);
+	else
+		writel(regval & ~BIT(gpio), reg_dout);
+
+	regval = readl(reg_mode);
+	regval &= ~GENMASK(gpio * 2 + 1, gpio * 2);
+	regval |= MA35_GP_MODE_OUTPUT << gpio * 2;
+	writel(regval, reg_mode);
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+static int ma35_gpio_core_to_request(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
+	u32 reg_offs, bit_offs, regval;
+
+	if (gpio < 8) {
+		/* The MFP low register controls port 0 ~ 7 */
+		reg_offs = bank->bank_num * MA35_MFP_REG_SZ_PER_BANK;
+		bit_offs = gpio * MA35_MFP_BITS_PER_PORT;
+	} else {
+		/* The MFP high register controls port 8 ~ 15 */
+		reg_offs = bank->bank_num * MA35_MFP_REG_SZ_PER_BANK + 4;
+		bit_offs = (gpio - 8) * MA35_MFP_BITS_PER_PORT;
+	}
+
+	regmap_read(bank->regmap, MA35_MFP_REG_BASE + reg_offs, &regval);
+	regval &= ~GENMASK(bit_offs + MA35_MFP_BITS_PER_PORT - 1, bit_offs);
+	regmap_write(bank->regmap, MA35_MFP_REG_BASE + reg_offs, regval);
+
+	return 0;
+}
+
+static void ma35_irq_gpio_mask(struct irq_data *d)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+	void __iomem *reg_ien = bank->reg_base + MA35_GP_REG_INTEN;
+	unsigned int num = (d->hwirq);
+	u32 regval;
+
+	regval = readl(reg_ien);
+
+	/*
+	 * The MA35_GP_REG_INTEN bits 0 ~ 15 control low-level or falling edge trigger,
+	 * while bits 16 ~ 31 control high-level or rising edge trigger.
+	 * We disable both type of interrupt.
+	 */
+	regval &= ~(BIT(num + 16) | BIT(num));
+
+	writel(regval, reg_ien);
+}
+
+static void ma35_irq_gpio_unmask(struct irq_data *d)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+	void __iomem *reg_itype = bank->reg_base + MA35_GP_REG_INTTYPE;
+	void __iomem *reg_ien = bank->reg_base + MA35_GP_REG_INTEN;
+	unsigned int num = (d->hwirq);
+	u32 bval, regval;
+
+	bval = bank->irqtype & BIT(num);
+
+	regval = readl(reg_itype);
+	regval &= ~BIT(num);
+	writel(regval | bval, reg_itype);
+
+	bval = bank->irqinten & (BIT(num + 16) | BIT(num));
+
+	regval = readl(reg_ien);
+	regval &= ~(BIT(num + 16) | BIT(num));
+	writel(regval | bval, reg_ien);
+}
+
+static int ma35_irq_irqtype(struct irq_data *d, unsigned int type)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+	void __iomem *reg_itype = bank->reg_base + MA35_GP_REG_INTTYPE;
+	void __iomem *reg_ien = bank->reg_base + MA35_GP_REG_INTEN;
+	unsigned int num = (d->hwirq);
+
+	if (type == IRQ_TYPE_PROBE) {
+		writel(readl(reg_itype) & ~BIT(num), reg_itype);
+		writel(readl(reg_ien) | BIT(num) | BIT(num + 16), reg_ien);
+		bank->irqtype &= ~BIT(num);
+		bank->irqinten |= BIT(num) | BIT(num + 16);
+		return 0;
+	}
+
+	if (type & IRQ_TYPE_LEVEL_MASK) {
+		writel(readl(reg_itype) | BIT(num), reg_itype);
+		writel(readl(reg_ien) & ~(BIT(num) | BIT(num + 16)), reg_ien);
+		bank->irqtype |= BIT(num);
+		bank->irqinten &= ~(BIT(num) | BIT(num + 16));
+		if (type == IRQ_TYPE_LEVEL_HIGH) {
+			writel(readl(reg_ien) | BIT(num + 16), reg_ien);
+			bank->irqinten |= BIT(num + 16);
+			return 0;
+		}
+
+		if (type == IRQ_TYPE_LEVEL_LOW) {
+			writel(readl(reg_ien) | BIT(num), reg_ien);
+			bank->irqinten |= BIT(num);
+			return 0;
+		}
+
+	} else {
+		writel(readl(reg_itype) & ~BIT(num), reg_itype);
+		bank->irqtype &= ~BIT(num);
+
+		if (type & IRQ_TYPE_EDGE_RISING) {
+			writel(readl(reg_ien) | BIT(num + 16), reg_ien);
+			bank->irqinten |= BIT(num + 16);
+
+		} else {
+			writel(readl(reg_ien) & ~BIT(num + 16), reg_ien);
+			bank->irqinten &= ~BIT(num + 16);
+		}
+
+		if (type & IRQ_TYPE_EDGE_FALLING) {
+			writel(readl(reg_ien) | BIT(num), reg_ien);
+			bank->irqinten |= BIT(num);
+
+		} else {
+			writel(readl(reg_ien) & ~BIT(num), reg_ien);
+			bank->irqinten &= ~BIT(num);
+		}
+	}
+	return 0;
+}
+
+static struct irq_chip ma35_gpio_irqchip = {
+	.name = "MA35-GPIO-IRQ",
+	.irq_disable = ma35_irq_gpio_mask,
+	.irq_enable = ma35_irq_gpio_unmask,
+	.irq_mask = ma35_irq_gpio_mask,
+	.irq_unmask = ma35_irq_gpio_unmask,
+	.irq_set_type = ma35_irq_irqtype,
+	.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE,
+};
+
+static void ma35_irq_demux_intgroup(struct irq_desc *desc)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(irq_desc_get_handler_data(desc));
+	struct irq_domain *irqdomain = bank->chip.irq.domain;
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	unsigned int j, isr;
+
+	chained_irq_enter(irqchip, desc);
+
+	isr = readl(bank->reg_base + MA35_GP_REG_INTSRC);
+
+	if (isr != 0) {
+		writel(isr, bank->reg_base + MA35_GP_REG_INTSRC);
+
+		for (j = 0; j < 16; j++) {
+			if (isr & 0x1)
+				generic_handle_irq(irq_find_mapping(irqdomain, j));
+			isr = isr >> 1;
+		}
+	}
+
+	chained_irq_exit(irqchip, desc);
+}
+
+static int ma35_gpiolib_register(struct platform_device *pdev, struct ma35_pinctrl *npctl)
+{
+	struct ma35_pin_ctrl *ctrl = npctl->ctrl;
+	struct ma35_pin_bank *bank = ctrl->pin_banks;
+	int ret;
+	int i;
+
+	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		if (!bank->valid) {
+			dev_warn(&pdev->dev, "bank %s is not valid\n",
+				 bank->np->name);
+			continue;
+		}
+		bank->irqtype = 0;
+		bank->irqinten = 0;
+		bank->chip.label = bank->name;
+		bank->chip.of_gpio_n_cells = 2;
+		bank->chip.parent = &pdev->dev;
+		bank->chip.request = ma35_gpio_core_to_request;
+		bank->chip.direction_input = ma35_gpio_core_direction_in;
+		bank->chip.direction_output = ma35_gpio_core_direction_out;
+		bank->chip.get = ma35_gpio_core_get;
+		bank->chip.set = ma35_gpio_core_set;
+		bank->chip.base = -1;
+		bank->chip.ngpio = bank->nr_pins;
+		bank->chip.can_sleep = false;
+		spin_lock_init(&bank->lock);
+
+		if (bank->irq > 0) {
+			struct gpio_irq_chip *girq;
+
+			girq = &bank->chip.irq;
+			gpio_irq_chip_set_chip(girq, &ma35_gpio_irqchip);
+			girq->parent_handler = ma35_irq_demux_intgroup;
+			girq->num_parents = 1;
+
+			girq->parents = devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents),
+						     GFP_KERNEL);
+			if (!girq->parents)
+				return -ENOMEM;
+
+			girq->parents[0] = bank->irq;
+			girq->default_type = IRQ_TYPE_NONE;
+			girq->handler = handle_level_irq;
+		}
+
+		ret = gpiochip_add_data(&bank->chip, bank);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
+				bank->chip.label, ret);
+			goto fail;
+		}
+	}
+	return 0;
+
+fail:
+	for (--i, --bank; i >= 0; --i, --bank) {
+		if (!bank->valid)
+			continue;
+		gpiochip_remove(&bank->chip);
+	}
+	return ret;
+}
+
+static int ma35_get_bank_data(struct ma35_pin_bank *bank, struct ma35_pinctrl *npctl)
+{
+	struct resource res;
+
+	if (of_address_to_resource(bank->np, 0, &res)) {
+		dev_err(npctl->dev, "cannot find IO resource for bank\n");
+		return -ENOENT;
+	}
+
+	bank->reg_base = devm_ioremap_resource(npctl->dev, &res);
+	if (IS_ERR(bank->reg_base)) {
+		dev_err(npctl->dev, "cannot ioremap resource for bank\n");
+		return PTR_ERR(bank->reg_base);
+	}
+
+	bank->irq = irq_of_parse_and_map(bank->np, 0);
+	bank->nr_pins = MA35_GPIO_PORT_MAX;
+
+	bank->clk = of_clk_get(bank->np, 0);
+	if (IS_ERR(bank->clk))
+		return PTR_ERR(bank->clk);
+
+	return clk_prepare_enable(bank->clk);
+}
+
+static int ma35_pinctrl_get_soc_data(struct ma35_pinctrl *pctl, struct platform_device *pdev)
+{
+	struct fwnode_handle *child;
+	struct ma35_pin_ctrl *ctrl;
+	struct ma35_pin_bank *bank;
+	int i, id = 0;
+
+	ctrl = pctl->ctrl;
+	ctrl->nr_banks = MA35_GPIO_BANK_MAX;
+
+	ctrl->pin_banks = devm_kcalloc(&pdev->dev, ctrl->nr_banks,
+				       sizeof(*ctrl->pin_banks), GFP_KERNEL);
+	if (!ctrl->pin_banks)
+		return -ENOMEM;
+
+	for (i = 0; i < ctrl->nr_banks; i++) {
+		ctrl->pin_banks[i].bank_num = i;
+		ctrl->pin_banks[i].name = gpio_group_name[i];
+	}
+
+	for_each_gpiochip_node(&pdev->dev, child) {
+		struct device_node *np = to_of_node(child);
+
+		bank = &ctrl->pin_banks[id];
+		bank->np = np;
+		bank->regmap = pctl->regmap;
+		bank->dev = &pdev->dev;
+		if (!ma35_get_bank_data(bank, pctl))
+			bank->valid = true;
+		id++;
+	}
+	return 0;
+}
+
+static void ma35_gpio_cla_port(unsigned int gpio_num, unsigned int *group,
+			       unsigned int *num)
+{
+	*group = gpio_num / MA35_GPIO_PORT_MAX;
+	*num = gpio_num % MA35_GPIO_PORT_MAX;
+}
+
+static int ma35_pinconf_set_pull(struct ma35_pinctrl *npctl, unsigned int pin,
+				 int pull_up)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_PUSEL);
+	regval &= ~GENMASK(port * 2 + 1, port * 2);
+
+	switch (pull_up) {
+	case PIN_CONFIG_BIAS_PULL_UP:
+		regval |= MA35_GP_PUSEL_PULL_UP << port * 2;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		regval |= MA35_GP_PUSEL_PULL_DOWN << port * 2;
+		break;
+
+	case MA35_GP_PUSEL_DISABLE:
+		regval |= MA35_GP_PUSEL_DISABLE << port * 2;
+		break;
+
+	default:
+		regval |= MA35_GP_PUSEL_DISABLE << port * 2;
+		break;
+	}
+	writel(regval, base + MA35_GP_REG_PUSEL);
+
+	return 0;
+}
+
+static int ma35_pinconf_get_output(struct ma35_pinctrl *npctl, unsigned int pin)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval, mode;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_MODE);
+	mode = (regval & GENMASK(port * 2 + 1, port * 2)) >> port * 2;
+
+	if (mode == MA35_GP_MODE_OUTPUT)
+		return 1;
+
+	return 0;
+}
+
+static int ma35_pinconf_get_pull(struct ma35_pinctrl *npctl, unsigned int pin)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval, mode;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_PUSEL);
+	mode = (regval & GENMASK(port * 2 + 1, port * 2)) >> port * 2;
+
+	switch (mode) {
+	case MA35_GP_PUSEL_PULL_UP:
+		return PIN_CONFIG_BIAS_PULL_UP;
+
+	case MA35_GP_PUSEL_PULL_DOWN:
+		return PIN_CONFIG_BIAS_PULL_DOWN;
+
+	case MA35_GP_PUSEL_DISABLE:
+		return PIN_CONFIG_BIAS_DISABLE;
+	}
+
+	return PIN_CONFIG_BIAS_DISABLE;
+}
+
+static int ma35_pinconf_set_output(struct ma35_pinctrl *npctl, unsigned int pin, bool out)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_MODE);
+	regval &= ~GENMASK(port * 2 + 1, port * 2);
+	regval |= MA35_GP_MODE_OUTPUT << port * 2;
+	writel(regval, base + MA35_GP_REG_MODE);
+
+	return 0;
+}
+
+static int ma35_pinconf_get_power_source(struct ma35_pinctrl *npctl, unsigned int pin)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SPW);
+
+	if (regval & BIT(port))
+		return MVOLT_3300;
+	else
+		return MVOLT_1800;
+}
+
+static int ma35_pinconf_set_power_source(struct ma35_pinctrl *npctl,
+					 unsigned int pin, int arg)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	if ((arg != MVOLT_1800) && (arg != MVOLT_3300))
+		return -EINVAL;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SPW);
+
+	if (arg == MVOLT_1800)
+		regval &= ~BIT(port);
+	else
+		regval |= BIT(port);
+
+	writel(regval, base + MA35_GP_REG_SPW);
+
+	return 0;
+}
+
+static int ma35_pinconf_get_drive_strength(struct ma35_pinctrl *npctl, unsigned int pin,
+					   u32 *strength)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval, ds_val;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	if (port < MA35_GP_DSH_BASE_PORT) {
+		regval = readl(base + MA35_GP_REG_DSL);
+		ds_val = (regval & GENMASK(port * 4 + 2, port * 4)) >> port * 4;
+	} else {
+		port -= MA35_GP_DSH_BASE_PORT;
+		regval = readl(base + MA35_GP_REG_DSH);
+		ds_val = (regval & GENMASK(port * 4 + 2, port * 4)) >> port * 4;
+	}
+
+	if (ma35_pinconf_get_power_source(npctl, pin) == MVOLT_1800)
+		*strength = ds_1800mv_tbl[ds_val];
+	else
+		*strength = ds_3300mv_tbl[ds_val];
+
+	return 0;
+}
+
+static int ma35_pinconf_set_drive_strength(struct ma35_pinctrl *npctl, unsigned int pin,
+					   int strength)
+{
+	int port, group_num;
+	void __iomem *base;
+	int i, ds_val = -1;
+	u32 regval;
+
+	if (ma35_pinconf_get_power_source(npctl, pin) == MVOLT_1800) {
+		for (i = 0; i < ARRAY_SIZE(ds_1800mv_tbl); i++) {
+			if (ds_1800mv_tbl[i] == strength)
+				ds_val = i;
+		}
+	} else {
+		for (i = 0; i < ARRAY_SIZE(ds_3300mv_tbl); i++) {
+			if (ds_3300mv_tbl[i] == strength)
+				ds_val = i;
+		}
+	}
+	if (ds_val == -1)
+		return -EINVAL;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	if (port < MA35_GP_DSH_BASE_PORT) {
+		regval = readl(base + MA35_GP_REG_DSL);
+		regval &= ~GENMASK(port * 4 + 2, port * 4);
+		regval |= ds_val << port * 4;
+		writel(regval, base + MA35_GP_REG_DSL);
+	} else {
+		port -= MA35_GP_DSH_BASE_PORT;
+		regval = readl(base + MA35_GP_REG_DSH);
+		regval &= ~GENMASK(port * 4 + 2, port * 4);
+		regval |= ds_val << port * 4;
+		writel(regval, base + MA35_GP_REG_DSH);
+	}
+	return 0;
+}
+
+static int ma35_pinconf_get_schmitt_enable(struct ma35_pinctrl *npctl, unsigned int pin)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SMTEN);
+
+	return !!(regval & BIT(port));
+}
+
+static int ma35_pinconf_set_schmitt(struct ma35_pinctrl *npctl, unsigned int pin, int enable)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SMTEN);
+
+	if (enable)
+		regval |= BIT(port);
+	else
+		regval &= ~BIT(port);
+
+	writel(regval, base + MA35_GP_REG_SMTEN);
+
+	return 0;
+}
+
+static int ma35_pinconf_get_slew_rate(struct ma35_pinctrl *npctl, unsigned int pin)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SLEWCTL);
+
+	return (regval & GENMASK(port * 2 + 1, port * 2)) >> port * 2;
+}
+
+static int ma35_pinconf_set_slew_rate(struct ma35_pinctrl *npctl, unsigned int pin, int rate)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SLEWCTL);
+	regval &= ~GENMASK(port * 2 + 1, port * 2);
+	regval |= rate << port * 2;
+	writel(regval, base + MA35_GP_REG_SLEWCTL);
+
+	return 0;
+}
+
+static int ma35_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *config)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	u32 arg;
+	int ret;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (ma35_pinconf_get_pull(npctl, pin) == param)
+			arg = 1;
+		else
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		ret = ma35_pinconf_get_drive_strength(npctl, pin, &arg);
+		if (ret)
+			return ret;
+		break;
+
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		arg = ma35_pinconf_get_schmitt_enable(npctl, pin);
+		break;
+
+	case PIN_CONFIG_SLEW_RATE:
+		arg = ma35_pinconf_get_slew_rate(npctl, pin);
+		break;
+
+	case PIN_CONFIG_OUTPUT_ENABLE:
+		arg = ma35_pinconf_get_output(npctl, pin);
+		break;
+
+	case PIN_CONFIG_POWER_SOURCE:
+		arg = ma35_pinconf_get_power_source(npctl, pin);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int ma35_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+			    unsigned long *configs, unsigned int num_configs)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param;
+	unsigned int arg = 0;
+	int i, ret = 0;
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_DISABLE:
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			ret = ma35_pinconf_set_pull(npctl, pin, param);
+			break;
+
+		case PIN_CONFIG_DRIVE_STRENGTH:
+			ret = ma35_pinconf_set_drive_strength(npctl, pin, arg);
+			break;
+
+		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+			ret = ma35_pinconf_set_schmitt(npctl, pin, 1);
+			break;
+
+		case PIN_CONFIG_INPUT_SCHMITT:
+			ret = ma35_pinconf_set_schmitt(npctl, pin, arg);
+			break;
+
+		case PIN_CONFIG_SLEW_RATE:
+			ret = ma35_pinconf_set_slew_rate(npctl, pin, arg);
+			break;
+
+		case PIN_CONFIG_OUTPUT_ENABLE:
+			ret = ma35_pinconf_set_output(npctl, pin, arg);
+			break;
+
+		case PIN_CONFIG_POWER_SOURCE:
+			ret = ma35_pinconf_set_power_source(npctl, pin, arg);
+			break;
+
+		default:
+			return -EINVAL;
+		}
+	}
+	return ret;
+}
+
+static const struct pinconf_ops ma35_pinconf_ops = {
+	.pin_config_get = ma35_pinconf_get,
+	.pin_config_set = ma35_pinconf_set,
+	.is_generic = true,
+};
+
+static int ma35_pinctrl_parse_groups(struct device_node *np, struct ma35_pin_group *grp,
+				     struct ma35_pinctrl *npctl, u32 index)
+{
+	unsigned long *configs;
+	unsigned int nconfigs;
+	struct ma35_pin_setting *pin;
+	const __be32 *list;
+	int i, j, size, ret;
+
+	dev_dbg(npctl->dev, "group(%d): %s\n", index, np->name);
+
+	grp->name = np->name;
+
+	ret = pinconf_generic_parse_dt_config(np, NULL, &configs, &nconfigs);
+	if (ret)
+		return ret;
+
+	/*
+	 * the binding format is nuvoton,pins = <bank pin-mfp pin-function>,
+	 * do sanity check and calculate pins number
+	 */
+	list = of_get_property(np, "nuvoton,pins", &size);
+	size /= sizeof(*list);
+	if (!size || size % 3) {
+		dev_err(npctl->dev, "wrong setting!\n");
+		return -EINVAL;
+	}
+	grp->npins = size / 3;
+
+	grp->pins = devm_kcalloc(npctl->dev, grp->npins, sizeof(*grp->pins), GFP_KERNEL);
+	if (!grp->pins)
+		return -ENOMEM;
+
+	grp->settings = devm_kcalloc(npctl->dev, grp->npins, sizeof(*grp->settings), GFP_KERNEL);
+	if (!grp->settings)
+		return -ENOMEM;
+
+	pin = grp->settings;
+
+	for (i = 0, j = 0; i < size; i += 3, j++) {
+		pin->offset = be32_to_cpu(*list++) * MA35_MFP_REG_SZ_PER_BANK + MA35_MFP_REG_BASE;
+		pin->shift = (be32_to_cpu(*list++) * MA35_MFP_BITS_PER_PORT) % 32;
+		pin->muxval = be32_to_cpu(*list++);
+		pin->configs = configs;
+		pin->nconfigs = nconfigs;
+		grp->pins[j] = npctl->info->get_pin_num(pin->offset, pin->shift);
+		pin++;
+	}
+	return 0;
+}
+
+static int ma35_pinctrl_parse_functions(struct device_node *np, struct ma35_pinctrl *npctl,
+					u32 index)
+{
+	struct device_node *child;
+	struct ma35_pin_func *func;
+	struct ma35_pin_group *grp;
+	static u32 grp_index;
+	u32 ret, i = 0;
+
+	dev_dbg(npctl->dev, "parse function(%d): %s\n", index, np->name);
+
+	func = &npctl->functions[index];
+	func->name = np->name;
+	func->ngroups = of_get_child_count(np);
+
+	if (func->ngroups <= 0)
+		return 0;
+
+	func->groups = devm_kcalloc(npctl->dev, func->ngroups, sizeof(char *), GFP_KERNEL);
+	if (!func->groups)
+		return -ENOMEM;
+
+	for_each_child_of_node(np, child) {
+		func->groups[i] = child->name;
+		grp = &npctl->groups[grp_index++];
+		ret = ma35_pinctrl_parse_groups(child, grp, npctl, i++);
+		if (ret) {
+			of_node_put(child);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static int ma35_pinctrl_probe_dt(struct platform_device *pdev, struct ma35_pinctrl *npctl)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *child;
+	u32 idx = 0;
+	int ret;
+
+	if (!np)
+		return -ENODEV;
+
+	for_each_child_of_node(np, child) {
+		if (of_property_read_bool(child, "gpio-controller"))
+			continue;
+		npctl->nfunctions++;
+		npctl->ngroups += of_get_child_count(child);
+	}
+
+	npctl->functions = devm_kcalloc(&pdev->dev, npctl->nfunctions,
+					sizeof(*npctl->functions), GFP_KERNEL);
+	if (!npctl->functions)
+		return -ENOMEM;
+
+	npctl->groups = devm_kcalloc(&pdev->dev, npctl->ngroups,
+				     sizeof(*npctl->groups), GFP_KERNEL);
+	if (!npctl->groups)
+		return -ENOMEM;
+
+	dev_dbg(&pdev->dev, "nfunctions = %d\n", npctl->nfunctions);
+	dev_dbg(&pdev->dev, "ngroups = %d\n", npctl->ngroups);
+
+	for_each_child_of_node(np, child) {
+		if (of_property_read_bool(child, "gpio-controller"))
+			continue;
+
+		ret = ma35_pinctrl_parse_functions(child, npctl, idx++);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to parse function\n");
+			of_node_put(child);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+int ma35_pinctrl_probe(struct platform_device *pdev, const struct ma35_pinctrl_soc_info *info)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct pinctrl_desc *ma35_pinctrl_desc;
+	struct ma35_pinctrl *npctl;
+	int ret;
+
+	if (!info || !info->pins || !info->npins) {
+		dev_err(&pdev->dev, "wrong pinctrl info\n");
+		return -EINVAL;
+	}
+
+	npctl = devm_kzalloc(&pdev->dev, sizeof(*npctl), GFP_KERNEL);
+	if (!npctl)
+		return -ENOMEM;
+
+	ma35_pinctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*ma35_pinctrl_desc), GFP_KERNEL);
+	if (!ma35_pinctrl_desc)
+		return -ENOMEM;
+
+	npctl->ctrl = devm_kzalloc(&pdev->dev, sizeof(*npctl->ctrl), GFP_KERNEL);
+	if (!npctl->ctrl)
+		return -ENOMEM;
+
+	ma35_pinctrl_desc->name = dev_name(&pdev->dev);
+	ma35_pinctrl_desc->pins = info->pins;
+	ma35_pinctrl_desc->npins = info->npins;
+	ma35_pinctrl_desc->pctlops = &ma35_pctrl_ops;
+	ma35_pinctrl_desc->pmxops = &ma35_pmx_ops;
+	ma35_pinctrl_desc->confops = &ma35_pinconf_ops;
+	ma35_pinctrl_desc->owner = THIS_MODULE;
+
+	npctl->info = info;
+	npctl->dev = &pdev->dev;
+
+	npctl->regmap = syscon_regmap_lookup_by_phandle(np, "nuvoton,sys");
+	if (IS_ERR(npctl->regmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(npctl->regmap),
+				     "No syscfg phandle specified\n");
+
+	ma35_pinctrl_get_soc_data(npctl, pdev);
+
+	platform_set_drvdata(pdev, npctl);
+
+	ret = ma35_pinctrl_probe_dt(pdev, npctl);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "fail to probe MA35 pinctrl dt\n");
+
+	ret = devm_pinctrl_register_and_init(&pdev->dev, ma35_pinctrl_desc,
+					     npctl, &npctl->pctl);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "fail to register MA35 pinctrl\n");
+
+	ret = pinctrl_enable(npctl->pctl);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "fail to enable MA35 pinctrl\n");
+
+	return ma35_gpiolib_register(pdev, npctl);
+}
+
+int __maybe_unused ma35_pinctrl_suspend(struct device *dev)
+{
+	struct ma35_pinctrl *npctl = dev_get_drvdata(dev);
+
+	return pinctrl_force_sleep(npctl->pctl);
+}
+
+int __maybe_unused ma35_pinctrl_resume(struct device *dev)
+{
+	struct ma35_pinctrl *npctl = dev_get_drvdata(dev);
+
+	return pinctrl_force_default(npctl->pctl);
+}
diff --git a/drivers/pinctrl/nuvoton/pinctrl-ma35.h b/drivers/pinctrl/nuvoton/pinctrl-ma35.h
new file mode 100644
index 000000000000..83ddf0e83ef7
--- /dev/null
+++ b/drivers/pinctrl/nuvoton/pinctrl-ma35.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Nuvoton Technology Corp.
+ *
+ * Author: Shan-Chun Hung <schung at nuvoton.com>
+ */
+#ifndef __PINCTRL_MA35_H
+#define __PINCTRL_MA35_H
+
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+
+struct ma35_mux_desc {
+	const char *name;
+	u32 muxval;
+};
+
+struct ma35_pin_data {
+	u32 offset;
+	u32 shift;
+	struct ma35_mux_desc *muxes;
+};
+
+struct ma35_pinctrl_soc_info {
+	const struct pinctrl_pin_desc *pins;
+	unsigned int npins;
+	int (*get_pin_num)(int offset, int shift);
+};
+
+#define MA35_PIN(num, n, o, s, ...) {			\
+	.number = num,					\
+	.name = #n,					\
+	.drv_data = &(struct ma35_pin_data) {		\
+		.offset = o,				\
+		.shift = s,				\
+		.muxes = (struct ma35_mux_desc[]) {	\
+			 __VA_ARGS__, { } },		\
+	},						\
+}
+
+#define MA35_MUX(_val, _name) {				\
+	.name = _name,					\
+	.muxval = _val,					\
+}
+
+int ma35_pinctrl_probe(struct platform_device *pdev, const struct ma35_pinctrl_soc_info *info);
+int ma35_pinctrl_suspend(struct device *dev);
+int ma35_pinctrl_resume(struct device *dev);
+
+#endif /* __PINCTRL_MA35_H */
diff --git a/drivers/pinctrl/nuvoton/pinctrl-ma35d1.c b/drivers/pinctrl/nuvoton/pinctrl-ma35d1.c
new file mode 100644
index 000000000000..36510c0b0690
--- /dev/null
+++ b/drivers/pinctrl/nuvoton/pinctrl-ma35d1.c
@@ -0,0 +1,1797 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Nuvoton Technology Corp.
+ *
+ * Author: Shan-Chun Hung <schung at nuvoton.com>
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-ma35.h"
+
+static const struct pinctrl_pin_desc ma35d1_pins[] = {
+	MA35_PIN(0, PA0, 0x80, 0x0,
+		MA35_MUX(0x0, "GPA0"),
+		MA35_MUX(0x2, "UART1_nCTS"),
+		MA35_MUX(0x3, "UART16_RXD"),
+		MA35_MUX(0x6, "NAND_DATA0"),
+		MA35_MUX(0x7, "EBI_AD0"),
+		MA35_MUX(0x9, "EBI_ADR0")),
+	MA35_PIN(1, PA1, 0x80, 0x4,
+		MA35_MUX(0x0, "GPA1"),
+		MA35_MUX(0x2, "UART1_nRTS"),
+		MA35_MUX(0x3, "UART16_TXD"),
+		MA35_MUX(0x6, "NAND_DATA1"),
+		MA35_MUX(0x7, "EBI_AD1"),
+		MA35_MUX(0x9, "EBI_ADR1")),
+	MA35_PIN(2, PA2, 0x80, 0x8,
+		MA35_MUX(0x0, "GPA2"),
+		MA35_MUX(0x2, "UART1_RXD"),
+		MA35_MUX(0x6, "NAND_DATA2"),
+		MA35_MUX(0x7, "EBI_AD2"),
+		MA35_MUX(0x9, "EBI_ADR2")),
+	MA35_PIN(3, PA3, 0x80, 0xc,
+		MA35_MUX(0x0, "GPA3"),
+		MA35_MUX(0x2, "UART1_TXD"),
+		MA35_MUX(0x6, "NAND_DATA3"),
+		MA35_MUX(0x7, "EBI_AD3"),
+		MA35_MUX(0x9, "EBI_ADR3")),
+	MA35_PIN(4, PA4, 0x80, 0x10,
+		MA35_MUX(0x0, "GPA4"),
+		MA35_MUX(0x2, "UART3_nCTS"),
+		MA35_MUX(0x3, "UART2_RXD"),
+		MA35_MUX(0x6, "NAND_DATA4"),
+		MA35_MUX(0x7, "EBI_AD4"),
+		MA35_MUX(0x9, "EBI_ADR4")),
+	MA35_PIN(5, PA5, 0x80, 0x14,
+		MA35_MUX(0x0, "GPA5"),
+		MA35_MUX(0x2, "UART3_nRTS"),
+		MA35_MUX(0x3, "UART2_TXD"),
+		MA35_MUX(0x6, "NAND_DATA5"),
+		MA35_MUX(0x7, "EBI_AD5"),
+		MA35_MUX(0x9, "EBI_ADR5")),
+	MA35_PIN(6, PA6, 0x80, 0x18,
+		MA35_MUX(0x0, "GPA6"),
+		MA35_MUX(0x2, "UART3_RXD"),
+		MA35_MUX(0x6, "NAND_DATA6"),
+		MA35_MUX(0x7, "EBI_AD6"),
+		MA35_MUX(0x9, "EBI_ADR6")),
+	MA35_PIN(7, PA7, 0x80, 0x1c,
+		MA35_MUX(0x0, "GPA7"),
+		MA35_MUX(0x2, "UART3_TXD"),
+		MA35_MUX(0x6, "NAND_DATA7"),
+		MA35_MUX(0x7, "EBI_AD7"),
+		MA35_MUX(0x9, "EBI_ADR7")),
+	MA35_PIN(8, PA8, 0x84, 0x0,
+		MA35_MUX(0x0, "GPA8"),
+		MA35_MUX(0x2, "UART5_nCTS"),
+		MA35_MUX(0x3, "UART4_RXD"),
+		MA35_MUX(0x6, "NAND_RDY0"),
+		MA35_MUX(0x7, "EBI_AD8"),
+		MA35_MUX(0x9, "EBI_ADR8")),
+	MA35_PIN(9, PA9, 0x84, 0x4,
+		MA35_MUX(0x0, "GPA9"),
+		MA35_MUX(0x2, "UART5_nRTS"),
+		MA35_MUX(0x3, "UART4_TXD"),
+		MA35_MUX(0x6, "NAND_nRE"),
+		MA35_MUX(0x7, "EBI_AD9"),
+		MA35_MUX(0x9, "EBI_ADR9")),
+	MA35_PIN(10, PA10, 0x84, 0x8,
+		MA35_MUX(0x0, "GPA10"),
+		MA35_MUX(0x2, "UART5_RXD"),
+		MA35_MUX(0x6, "NAND_nWE"),
+		MA35_MUX(0x7, "EBI_AD10"),
+		MA35_MUX(0x9, "EBI_ADR10")),
+	MA35_PIN(11, PA11, 0x84, 0xc,
+		MA35_MUX(0x0, "GPA11"),
+		MA35_MUX(0x2, "UART5_TXD"),
+		MA35_MUX(0x6, "NAND_CLE"),
+		MA35_MUX(0x7, "EBI_AD11"),
+		MA35_MUX(0x9, "EBI_ADR11")),
+	MA35_PIN(12, PA12, 0x84, 0x10,
+		MA35_MUX(0x0, "GPA12"),
+		MA35_MUX(0x2, "UART7_nCTS"),
+		MA35_MUX(0x3, "UART8_RXD"),
+		MA35_MUX(0x6, "NAND_ALE"),
+		MA35_MUX(0x7, "EBI_AD12"),
+		MA35_MUX(0x9, "EBI_ADR12")),
+	MA35_PIN(13, PA13, 0x84, 0x14,
+		MA35_MUX(0x0, "GPA13"),
+		MA35_MUX(0x2, "UART7_nRTS"),
+		MA35_MUX(0x3, "UART8_TXD"),
+		MA35_MUX(0x6, "NAND_nCS0"),
+		MA35_MUX(0x7, "EBI_AD13"),
+		MA35_MUX(0x9, "EBI_ADR13")),
+	MA35_PIN(14, PA14, 0x84, 0x18,
+		MA35_MUX(0x0, "GPA14"),
+		MA35_MUX(0x2, "UART7_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x6, "NAND_nWP"),
+		MA35_MUX(0x7, "EBI_AD14"),
+		MA35_MUX(0x9, "EBI_ADR14")),
+	MA35_PIN(15, PA15, 0x84, 0x1c,
+		MA35_MUX(0x0, "GPA15"),
+		MA35_MUX(0x1, "EPWM0_CH2"),
+		MA35_MUX(0x2, "UART9_nCTS"),
+		MA35_MUX(0x3, "UART6_RXD"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x5, "CAN2_RXD"),
+		MA35_MUX(0x7, "EBI_ALE"),
+		MA35_MUX(0x9, "QEI0_A"),
+		MA35_MUX(0xb, "TM1"),
+		MA35_MUX(0xe, "RGMII0_PPS"),
+		MA35_MUX(0xf, "RMII0_PPS")),
+	MA35_PIN(16, PB0, 0x88, 0x0,
+		MA35_MUX(0x0, "GPB0"),
+		MA35_MUX(0x8, "EADC0_CH0")),
+	MA35_PIN(17, PB1, 0x88, 0x4,
+		MA35_MUX(0x0, "GPB1"),
+		MA35_MUX(0x8, "EADC0_CH1")),
+	MA35_PIN(18, PB2, 0x88, 0x8,
+		MA35_MUX(0x0, "GPB2"),
+		MA35_MUX(0x8, "EADC0_CH2")),
+	MA35_PIN(19, PB3, 0x88, 0xc,
+		MA35_MUX(0x0, "GPB3"),
+		MA35_MUX(0x8, "EADC0_CH3")),
+	MA35_PIN(20, PB4, 0x88, 0x10,
+		MA35_MUX(0x0, "GPB4"),
+		MA35_MUX(0x8, "EADC0_CH4")),
+	MA35_PIN(21, PB5, 0x88, 0x14,
+		MA35_MUX(0x0, "GPB5"),
+		MA35_MUX(0x8, "EADC0_CH5")),
+	MA35_PIN(22, PB6, 0x88, 0x18,
+		MA35_MUX(0x0, "GPB6"),
+		MA35_MUX(0x8, "EADC0_CH6")),
+	MA35_PIN(23, PB7, 0x88, 0x1c,
+		MA35_MUX(0x0, "GPB7"),
+		MA35_MUX(0x8, "EADC0_CH7")),
+	MA35_PIN(24, PB8, 0x8c, 0x0,
+		MA35_MUX(0x0, "GPB8"),
+		MA35_MUX(0x1, "EPWM2_BRAKE0"),
+		MA35_MUX(0x2, "UART2_nCTS"),
+		MA35_MUX(0x3, "UART1_RXD"),
+		MA35_MUX(0x4, "I2C2_SDA"),
+		MA35_MUX(0x5, "SPI0_SS1"),
+		MA35_MUX(0x6, "SPI0_I2SMCLK"),
+		MA35_MUX(0x8, "ADC0_CH0"),
+		MA35_MUX(0x9, "EBI_nCS0"),
+		MA35_MUX(0xb, "TM4"),
+		MA35_MUX(0xe, "QEI2_INDEX"),
+		MA35_MUX(0xf, "KPI_ROW6")),
+	MA35_PIN(25, PB9, 0x8c, 0x4,
+		MA35_MUX(0x0, "GPB9"),
+		MA35_MUX(0x1, "EPWM2_CH4"),
+		MA35_MUX(0x2, "UART2_nRTS"),
+		MA35_MUX(0x3, "UART1_TXD"),
+		MA35_MUX(0x4, "I2C2_SCL"),
+		MA35_MUX(0x5, "SPI0_CLK"),
+		MA35_MUX(0x6, "I2S0_MCLK"),
+		MA35_MUX(0x7, "CCAP1_HSYNC"),
+		MA35_MUX(0x8, "ADC0_CH1"),
+		MA35_MUX(0x9, "EBI_ALE"),
+		MA35_MUX(0xa, "EBI_AD13"),
+		MA35_MUX(0xb, "TM0_EXT"),
+		MA35_MUX(0xc, "I2S1_MCLK"),
+		MA35_MUX(0xd, "SC0_nCD"),
+		MA35_MUX(0xe, "QEI2_A"),
+		MA35_MUX(0xf, "KPI_ROW7")),
+	MA35_PIN(26, PB10, 0x8c, 0x8,
+		MA35_MUX(0x0, "GPB10"),
+		MA35_MUX(0x1, "EPWM2_CH5"),
+		MA35_MUX(0x2, "UART2_RXD"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x5, "SPI0_MOSI"),
+		MA35_MUX(0x6, "EBI_MCLK"),
+		MA35_MUX(0x7, "CCAP1_VSYNC"),
+		MA35_MUX(0x8, "ADC0_CH2"),
+		MA35_MUX(0x9, "EBI_ADR15"),
+		MA35_MUX(0xa, "EBI_AD14"),
+		MA35_MUX(0xb, "TM5"),
+		MA35_MUX(0xc, "I2C1_SDA"),
+		MA35_MUX(0xd, "INT1"),
+		MA35_MUX(0xe, "QEI2_B")),
+	MA35_PIN(27, PB11, 0x8c, 0xc,
+		MA35_MUX(0x0, "GPB11"),
+		MA35_MUX(0x1, "EPWM2_BRAKE1"),
+		MA35_MUX(0x2, "UART2_TXD"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x5, "SPI0_MISO"),
+		MA35_MUX(0x6, "I2S1_MCLK"),
+		MA35_MUX(0x7, "CCAP1_SFIELD"),
+		MA35_MUX(0x8, "ADC0_CH3"),
+		MA35_MUX(0x9, "EBI_nCS2"),
+		MA35_MUX(0xa, "EBI_ALE"),
+		MA35_MUX(0xb, "TM5_EXT"),
+		MA35_MUX(0xc, "I2C1_SCL"),
+		MA35_MUX(0xd, "INT2"),
+		MA35_MUX(0xe, "QEI2_INDEX")),
+	MA35_PIN(28, PB12, 0x8c, 0x10,
+		MA35_MUX(0x0, "GPB12"),
+		MA35_MUX(0x1, "EPWM2_CH0"),
+		MA35_MUX(0x2, "UART4_nCTS"),
+		MA35_MUX(0x3, "UART3_RXD"),
+		MA35_MUX(0x4, "I2C3_SDA"),
+		MA35_MUX(0x5, "CAN2_RXD"),
+		MA35_MUX(0x6, "I2S1_LRCK"),
+		MA35_MUX(0x8, "ADC0_CH4"),
+		MA35_MUX(0x9, "EBI_ADR16"),
+		MA35_MUX(0xe, "ECAP2_IC0")),
+	MA35_PIN(29, PB13, 0x8c, 0x14,
+		MA35_MUX(0x0, "GPB13"),
+		MA35_MUX(0x1, "EPWM2_CH1"),
+		MA35_MUX(0x2, "UART4_nRTS"),
+		MA35_MUX(0x3, "UART3_TXD"),
+		MA35_MUX(0x4, "I2C3_SCL"),
+		MA35_MUX(0x5, "CAN2_TXD"),
+		MA35_MUX(0x6, "I2S1_BCLK"),
+		MA35_MUX(0x8, "ADC0_CH5"),
+		MA35_MUX(0x9, "EBI_ADR17"),
+		MA35_MUX(0xe, "ECAP2_IC1")),
+	MA35_PIN(30, PB14, 0x8c, 0x18,
+		MA35_MUX(0x0, "GPB14"),
+		MA35_MUX(0x1, "EPWM2_CH2"),
+		MA35_MUX(0x2, "UART4_RXD"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x5, "I2C4_SDA"),
+		MA35_MUX(0x6, "I2S1_DI"),
+		MA35_MUX(0x8, "ADC0_CH6"),
+		MA35_MUX(0x9, "EBI_ADR18"),
+		MA35_MUX(0xe, "ECAP2_IC2")),
+	MA35_PIN(31, PB15, 0x8c, 0x1c,
+		MA35_MUX(0x0, "GPB15"),
+		MA35_MUX(0x1, "EPWM2_CH3"),
+		MA35_MUX(0x2, "UART4_TXD"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x5, "I2C4_SCL"),
+		MA35_MUX(0x6, "I2S1_DO"),
+		MA35_MUX(0x8, "ADC0_CH7"),
+		MA35_MUX(0x9, "EBI_ADR19")),
+	MA35_PIN(32, PC0, 0x90, 0x0,
+		MA35_MUX(0x0, "GPC0"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x6, "SD0_CMD/eMMC0_CMD")),
+	MA35_PIN(33, PC1, 0x90, 0x4,
+		MA35_MUX(0x0, "GPC1"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x6, "SD0_CLK/eMMC0_CLK")),
+	MA35_PIN(34, PC2, 0x90, 0x8,
+		MA35_MUX(0x0, "GPC2"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x6, "SD0_DAT0/eMMC0_DAT0")),
+	MA35_PIN(35, PC3, 0x90, 0xc,
+		MA35_MUX(0x0, "GPC3"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x6, "SD0_DAT1/eMMC0_DAT1")),
+	MA35_PIN(36, PC4, 0x90, 0x10,
+		MA35_MUX(0x0, "GPC4"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x6, "SD0_DAT2/eMMC0_DAT2")),
+	MA35_PIN(37, PC5, 0x90, 0x14,
+		MA35_MUX(0x0, "GPC5"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x6, "SD0_DAT3/eMMC0_DAT3")),
+	MA35_PIN(38, PC6, 0x90, 0x18,
+		MA35_MUX(0x0, "GPC6"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x6, "SD0_nCD")),
+	MA35_PIN(39, PC7, 0x90, 0x1c,
+		MA35_MUX(0x0, "GPC7"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x6, "SD0_WP")),
+	MA35_PIN(40, PC12, 0x94, 0x10,
+		MA35_MUX(0x0, "GPC12"),
+		MA35_MUX(0x2, "UART12_nCTS"),
+		MA35_MUX(0x3, "UART11_RXD"),
+		MA35_MUX(0x6, "LCM_DATA16")),
+	MA35_PIN(41, PC13, 0x94, 0x14,
+		MA35_MUX(0x0, "GPC13"),
+		MA35_MUX(0x2, "UART12_nRTS"),
+		MA35_MUX(0x3, "UART11_TXD"),
+		MA35_MUX(0x6, "LCM_DATA17")),
+	MA35_PIN(42, PC14, 0x94, 0x18,
+		MA35_MUX(0x0, "GPC14"),
+		MA35_MUX(0x2, "UART12_RXD"),
+		MA35_MUX(0x6, "LCM_DATA18")),
+	MA35_PIN(43, PC15, 0x94, 0x1c,
+		MA35_MUX(0x0, "GPC15"),
+		MA35_MUX(0x2, "UART12_TXD"),
+		MA35_MUX(0x6, "LCM_DATA19"),
+		MA35_MUX(0x7, "LCM_MPU_TE"),
+		MA35_MUX(0x8, "LCM_MPU_VSYNC")),
+	MA35_PIN(44, PD0, 0x98, 0x0,
+		MA35_MUX(0x0, "GPD0"),
+		MA35_MUX(0x2, "UART3_nCTS"),
+		MA35_MUX(0x3, "UART4_RXD"),
+		MA35_MUX(0x5, "QSPI0_SS0")),
+	MA35_PIN(45, PD1, 0x98, 0x4,
+		MA35_MUX(0x0, "GPD1"),
+		MA35_MUX(0x2, "UART3_nRTS"),
+		MA35_MUX(0x3, "UART4_TXD"),
+		MA35_MUX(0x5, "QSPI0_CLK")),
+	MA35_PIN(46, PD2, 0x98, 0x8,
+		MA35_MUX(0x0, "GPD2"),
+		MA35_MUX(0x2, "UART3_RXD"),
+		MA35_MUX(0x5, "QSPI0_MOSI0")),
+	MA35_PIN(47, PD3, 0x98, 0xc,
+		MA35_MUX(0x0, "GPD3"),
+		MA35_MUX(0x2, "UART3_TXD"),
+		MA35_MUX(0x5, "QSPI0_MISO0")),
+	MA35_PIN(48, PD4, 0x98, 0x10,
+		MA35_MUX(0x0, "GPD4"),
+		MA35_MUX(0x2, "UART1_nCTS"),
+		MA35_MUX(0x3, "UART2_RXD"),
+		MA35_MUX(0x4, "I2C2_SDA"),
+		MA35_MUX(0x5, "QSPI0_MOSI1")),
+	MA35_PIN(49, PD5, 0x98, 0x14,
+		MA35_MUX(0x0, "GPD5"),
+		MA35_MUX(0x2, "UART1_nRTS"),
+		MA35_MUX(0x3, "UART2_TXD"),
+		MA35_MUX(0x4, "I2C2_SCL"),
+		MA35_MUX(0x5, "QSPI0_MISO1")),
+	MA35_PIN(50, PD6, 0x98, 0x18,
+		MA35_MUX(0x0, "GPD6"),
+		MA35_MUX(0x1, "EPWM0_SYNC_IN"),
+		MA35_MUX(0x2, "UART1_RXD"),
+		MA35_MUX(0x5, "QSPI1_MOSI1"),
+		MA35_MUX(0x6, "I2C0_SDA"),
+		MA35_MUX(0x7, "I2S0_MCLK"),
+		MA35_MUX(0x8, "EPWM0_CH0"),
+		MA35_MUX(0x9, "EBI_AD5"),
+		MA35_MUX(0xa, "SPI3_SS1"),
+		MA35_MUX(0xb, "TRACE_CLK")),
+	MA35_PIN(51, PD7, 0x98, 0x1c,
+		MA35_MUX(0x0, "GPD7"),
+		MA35_MUX(0x1, "EPWM0_SYNC_OUT"),
+		MA35_MUX(0x2, "UART1_TXD"),
+		MA35_MUX(0x5, "QSPI1_MISO1"),
+		MA35_MUX(0x6, "I2C0_SCL"),
+		MA35_MUX(0x7, "I2S1_MCLK"),
+		MA35_MUX(0x8, "EPWM0_CH1"),
+		MA35_MUX(0x9, "EBI_AD6"),
+		MA35_MUX(0xa, "SC1_nCD"),
+		MA35_MUX(0xb, "EADC0_ST")),
+	MA35_PIN(52, PD8, 0x9c, 0x0,
+		MA35_MUX(0x0, "GPD8"),
+		MA35_MUX(0x1, "EPWM0_BRAKE0"),
+		MA35_MUX(0x2, "UART16_nCTS"),
+		MA35_MUX(0x3, "UART15_RXD"),
+		MA35_MUX(0x5, "QSPI1_SS0"),
+		MA35_MUX(0x7, "I2S1_LRCK"),
+		MA35_MUX(0x8, "EPWM0_CH2"),
+		MA35_MUX(0x9, "EBI_AD7"),
+		MA35_MUX(0xa, "SC1_CLK"),
+		MA35_MUX(0xb, "TM0")),
+	MA35_PIN(53, PD9, 0x9c, 0x4,
+		MA35_MUX(0x0, "GPD9"),
+		MA35_MUX(0x1, "EPWM0_BRAKE1"),
+		MA35_MUX(0x2, "UART16_nRTS"),
+		MA35_MUX(0x3, "UART15_TXD"),
+		MA35_MUX(0x5, "QSPI1_CLK"),
+		MA35_MUX(0x7, "I2S1_BCLK"),
+		MA35_MUX(0x8, "EPWM0_CH3"),
+		MA35_MUX(0x9, "EBI_AD8"),
+		MA35_MUX(0xa, "SC1_DAT"),
+		MA35_MUX(0xb, "TM0_EXT")),
+	MA35_PIN(54, PD10, 0x9c, 0x8,
+		MA35_MUX(0x0, "GPD10"),
+		MA35_MUX(0x1, "EPWM1_BRAKE0"),
+		MA35_MUX(0x2, "UART16_RXD"),
+		MA35_MUX(0x5, "QSPI1_MOSI0"),
+		MA35_MUX(0x7, "I2S1_DI"),
+		MA35_MUX(0x8, "EPWM0_CH4"),
+		MA35_MUX(0x9, "EBI_AD9"),
+		MA35_MUX(0xa, "SC1_RST"),
+		MA35_MUX(0xb, "TM2")),
+	MA35_PIN(55, PD11, 0x9c, 0xc,
+		MA35_MUX(0x0, "GPD11"),
+		MA35_MUX(0x1, "EPWM1_BRAKE1"),
+		MA35_MUX(0x2, "UART16_TXD"),
+		MA35_MUX(0x5, "QSPI1_MISO0"),
+		MA35_MUX(0x7, "I2S1_DO"),
+		MA35_MUX(0x8, "EPWM0_CH5"),
+		MA35_MUX(0x9, "EBI_AD10"),
+		MA35_MUX(0xa, "SC1_PWR"),
+		MA35_MUX(0xb, "TM2_EXT")),
+	MA35_PIN(56, PD12, 0x9c, 0x10,
+		MA35_MUX(0x0, "GPD12"),
+		MA35_MUX(0x1, "EPWM0_BRAKE0"),
+		MA35_MUX(0x2, "UART11_TXD"),
+		MA35_MUX(0x3, "UART10_RXD"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x6, "TRACE_DATA0"),
+		MA35_MUX(0x7, "EBI_nCS1"),
+		MA35_MUX(0x8, "EBI_AD4"),
+		MA35_MUX(0x9, "QEI0_INDEX"),
+		MA35_MUX(0xb, "TM5"),
+		MA35_MUX(0xc, "I2S1_LRCK"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(57, PD13, 0x9c, 0x14,
+		MA35_MUX(0x0, "GPD13"),
+		MA35_MUX(0x1, "EPWM0_BRAKE1"),
+		MA35_MUX(0x2, "UART11_RXD"),
+		MA35_MUX(0x3, "UART10_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x6, "TRACE_DATA1"),
+		MA35_MUX(0x7, "EBI_nCS2"),
+		MA35_MUX(0x8, "EBI_AD5"),
+		MA35_MUX(0x9, "ECAP0_IC0"),
+		MA35_MUX(0xb, "TM5_EXT"),
+		MA35_MUX(0xc, "I2S1_BCLK")),
+	MA35_PIN(58, PD14, 0x9c, 0x18,
+		MA35_MUX(0x0, "GPD14"),
+		MA35_MUX(0x1, "EPWM0_SYNC_IN"),
+		MA35_MUX(0x2, "UART11_nCTS"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x6, "TRACE_DATA2"),
+		MA35_MUX(0x7, "EBI_MCLK"),
+		MA35_MUX(0x8, "EBI_AD6"),
+		MA35_MUX(0x9, "ECAP0_IC1"),
+		MA35_MUX(0xb, "TM6"),
+		MA35_MUX(0xc, "I2S1_DI"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(59, PD15, 0x9c, 0x1c,
+		MA35_MUX(0x0, "GPD15"),
+		MA35_MUX(0x1, "EPWM0_SYNC_OUT"),
+		MA35_MUX(0x2, "UART11_nRTS"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x6, "TRACE_DATA3"),
+		MA35_MUX(0x7, "EBI_ALE"),
+		MA35_MUX(0x8, "EBI_AD7"),
+		MA35_MUX(0x9, "ECAP0_IC2"),
+		MA35_MUX(0xb, "TM6_EXT"),
+		MA35_MUX(0xc, "I2S1_DO")),
+	MA35_PIN(60, PE0, 0xa0, 0x0,
+		MA35_MUX(0x0, "GPE0"),
+		MA35_MUX(0x2, "UART9_nCTS"),
+		MA35_MUX(0x3, "UART8_RXD"),
+		MA35_MUX(0x7, "CCAP1_DATA0"),
+		MA35_MUX(0x8, "RGMII0_MDC"),
+		MA35_MUX(0x9, "RMII0_MDC")),
+	MA35_PIN(61, PE1, 0xa0, 0x4,
+		MA35_MUX(0x0, "GPE1"),
+		MA35_MUX(0x2, "UART9_nRTS"),
+		MA35_MUX(0x3, "UART8_TXD"),
+		MA35_MUX(0x7, "CCAP1_DATA1"),
+		MA35_MUX(0x8, "RGMII0_MDIO"),
+		MA35_MUX(0x9, "RMII0_MDIO")),
+	MA35_PIN(62, PE2, 0xa0, 0x8,
+		MA35_MUX(0x0, "GPE2"),
+		MA35_MUX(0x2, "UART9_RXD"),
+		MA35_MUX(0x7, "CCAP1_DATA2"),
+		MA35_MUX(0x8, "RGMII0_TXCTL"),
+		MA35_MUX(0x9, "RMII0_TXEN")),
+	MA35_PIN(63, PE3, 0xa0, 0xc,
+		MA35_MUX(0x0, "GPE3"),
+		MA35_MUX(0x2, "UART9_TXD"),
+		MA35_MUX(0x7, "CCAP1_DATA3"),
+		MA35_MUX(0x8, "RGMII0_TXD0"),
+		MA35_MUX(0x9, "RMII0_TXD0")),
+	MA35_PIN(64, PE4, 0xa0, 0x10,
+		MA35_MUX(0x0, "GPE4"),
+		MA35_MUX(0x2, "UART4_nCTS"),
+		MA35_MUX(0x3, "UART3_RXD"),
+		MA35_MUX(0x7, "CCAP1_DATA4"),
+		MA35_MUX(0x8, "RGMII0_TXD1"),
+		MA35_MUX(0x9, "RMII0_TXD1")),
+	MA35_PIN(65, PE5, 0xa0, 0x14,
+		MA35_MUX(0x0, "GPE5"),
+		MA35_MUX(0x2, "UART4_nRTS"),
+		MA35_MUX(0x3, "UART3_TXD"),
+		MA35_MUX(0x7, "CCAP1_DATA5"),
+		MA35_MUX(0x8, "RGMII0_RXCLK"),
+		MA35_MUX(0x9, "RMII0_REFCLK")),
+	MA35_PIN(66, PE6, 0xa0, 0x18,
+		MA35_MUX(0x0, "GPE6"),
+		MA35_MUX(0x2, "UART4_RXD"),
+		MA35_MUX(0x7, "CCAP1_DATA6"),
+		MA35_MUX(0x8, "RGMII0_RXCTL"),
+		MA35_MUX(0x9, "RMII0_CRSDV")),
+	MA35_PIN(67, PE7, 0xa0, 0x1c,
+		MA35_MUX(0x0, "GPE7"),
+		MA35_MUX(0x2, "UART4_TXD"),
+		MA35_MUX(0x7, "CCAP1_DATA7"),
+		MA35_MUX(0x8, "RGMII0_RXD0"),
+		MA35_MUX(0x9, "RMII0_RXD0")),
+	MA35_PIN(68, PE8, 0xa4, 0x0,
+		MA35_MUX(0x0, "GPE8"),
+		MA35_MUX(0x2, "UART13_nCTS"),
+		MA35_MUX(0x3, "UART12_RXD"),
+		MA35_MUX(0x7, "CCAP1_SCLK"),
+		MA35_MUX(0x8, "RGMII0_RXD1"),
+		MA35_MUX(0x9, "RMII0_RXD1")),
+	MA35_PIN(69, PE9, 0xa4, 0x4,
+		MA35_MUX(0x0, "GPE9"),
+		MA35_MUX(0x2, "UART13_nRTS"),
+		MA35_MUX(0x3, "UART12_TXD"),
+		MA35_MUX(0x7, "CCAP1_PIXCLK"),
+		MA35_MUX(0x8, "RGMII0_RXD2"),
+		MA35_MUX(0x9, "RMII0_RXERR")),
+	MA35_PIN(70, PE10, 0xa4, 0x8,
+		MA35_MUX(0x0, "GPE10"),
+		MA35_MUX(0x2, "UART15_nCTS"),
+		MA35_MUX(0x3, "UART14_RXD"),
+		MA35_MUX(0x5, "SPI1_SS0"),
+		MA35_MUX(0x7, "CCAP1_HSYNC"),
+		MA35_MUX(0x8, "RGMII0_RXD3")),
+	MA35_PIN(71, PE11, 0xa4, 0xc,
+		MA35_MUX(0x0, "GPE11"),
+		MA35_MUX(0x2, "UART15_nRTS"),
+		MA35_MUX(0x3, "UART14_TXD"),
+		MA35_MUX(0x5, "SPI1_CLK"),
+		MA35_MUX(0x7, "CCAP1_VSYNC"),
+		MA35_MUX(0x8, "RGMII0_TXCLK")),
+	MA35_PIN(72, PE12, 0xa4, 0x10,
+		MA35_MUX(0x0, "GPE12"),
+		MA35_MUX(0x2, "UART15_RXD"),
+		MA35_MUX(0x5, "SPI1_MOSI"),
+		MA35_MUX(0x7, "CCAP1_DATA8"),
+		MA35_MUX(0x8, "RGMII0_TXD2")),
+	MA35_PIN(73, PE13, 0xa4, 0x14,
+		MA35_MUX(0x0, "GPE13"),
+		MA35_MUX(0x2, "UART15_TXD"),
+		MA35_MUX(0x5, "SPI1_MISO"),
+		MA35_MUX(0x7, "CCAP1_DATA9"),
+		MA35_MUX(0x8, "RGMII0_TXD3")),
+	MA35_PIN(74, PE14, 0xa4, 0x18,
+		MA35_MUX(0x0, "GPE14"),
+		MA35_MUX(0x1, "UART0_TXD")),
+	MA35_PIN(75, PE15, 0xa4, 0x1c,
+		MA35_MUX(0x0, "GPE15"),
+		MA35_MUX(0x1, "UART0_RXD")),
+	MA35_PIN(76, PF0, 0xa8, 0x0,
+		MA35_MUX(0x0, "GPF0"),
+		MA35_MUX(0x2, "UART2_nCTS"),
+		MA35_MUX(0x3, "UART1_RXD"),
+		MA35_MUX(0x6, "RGMII0_RXD3"),
+		MA35_MUX(0x8, "RGMII1_MDC"),
+		MA35_MUX(0x9, "RMII1_MDC"),
+		MA35_MUX(0xe, "KPI_COL0")),
+	MA35_PIN(77, PF1, 0xa8, 0x4,
+		MA35_MUX(0x0, "GPF1"),
+		MA35_MUX(0x2, "UART2_nRTS"),
+		MA35_MUX(0x3, "UART1_TXD"),
+		MA35_MUX(0x6, "RGMII0_TXCLK"),
+		MA35_MUX(0x8, "RGMII1_MDIO"),
+		MA35_MUX(0x9, "RMII1_MDIO"),
+		MA35_MUX(0xe, "KPI_COL1")),
+	MA35_PIN(78, PF2, 0xa8, 0x8,
+		MA35_MUX(0x0, "GPF2"),
+		MA35_MUX(0x2, "UART2_RXD"),
+		MA35_MUX(0x6, "RGMII0_TXD2"),
+		MA35_MUX(0x8, "RGMII1_TXCTL"),
+		MA35_MUX(0x9, "RMII1_TXEN"),
+		MA35_MUX(0xe, "KPI_COL2")),
+	MA35_PIN(79, PF3, 0xa8, 0xc,
+		MA35_MUX(0x0, "GPF3"),
+		MA35_MUX(0x2, "UART2_TXD"),
+		MA35_MUX(0x6, "RGMII0_TXD3"),
+		MA35_MUX(0x8, "RGMII1_TXD0"),
+		MA35_MUX(0x9, "RMII1_TXD0"),
+		MA35_MUX(0xe, "KPI_COL3")),
+	MA35_PIN(80, PF4, 0xa8, 0x10,
+		MA35_MUX(0x0, "GPF4"),
+		MA35_MUX(0x2, "UART11_nCTS"),
+		MA35_MUX(0x3, "UART10_RXD"),
+		MA35_MUX(0x4, "I2S0_LRCK"),
+		MA35_MUX(0x5, "SPI1_SS0"),
+		MA35_MUX(0x8, "RGMII1_TXD1"),
+		MA35_MUX(0x9, "RMII1_TXD1"),
+		MA35_MUX(0xd, "CAN2_RXD"),
+		MA35_MUX(0xe, "KPI_ROW0")),
+	MA35_PIN(81, PF5, 0xa8, 0x14,
+		MA35_MUX(0x0, "GPF5"),
+		MA35_MUX(0x2, "UART11_nRTS"),
+		MA35_MUX(0x3, "UART10_TXD"),
+		MA35_MUX(0x4, "I2S0_BCLK"),
+		MA35_MUX(0x5, "SPI1_CLK"),
+		MA35_MUX(0x8, "RGMII1_RXCLK"),
+		MA35_MUX(0x9, "RMII1_REFCLK"),
+		MA35_MUX(0xd, "CAN2_TXD"),
+		MA35_MUX(0xe, "KPI_ROW1")),
+	MA35_PIN(82, PF6, 0xa8, 0x18,
+		MA35_MUX(0x0, "GPF6"),
+		MA35_MUX(0x2, "UART11_RXD"),
+		MA35_MUX(0x4, "I2S0_DI"),
+		MA35_MUX(0x5, "SPI1_MOSI"),
+		MA35_MUX(0x8, "RGMII1_RXCTL"),
+		MA35_MUX(0x9, "RMII1_CRSDV"),
+		MA35_MUX(0xa, "I2C4_SDA"),
+		MA35_MUX(0xd, "SC0_CLK"),
+		MA35_MUX(0xe, "KPI_ROW2")),
+	MA35_PIN(83, PF7, 0xa8, 0x1c,
+		MA35_MUX(0x0, "GPF7"),
+		MA35_MUX(0x2, "UART11_TXD"),
+		MA35_MUX(0x4, "I2S0_DO"),
+		MA35_MUX(0x5, "SPI1_MISO"),
+		MA35_MUX(0x8, "RGMII1_RXD0"),
+		MA35_MUX(0x9, "RMII1_RXD0"),
+		MA35_MUX(0xa, "I2C4_SCL"),
+		MA35_MUX(0xd, "SC0_DAT"),
+		MA35_MUX(0xe, "KPI_ROW3")),
+	MA35_PIN(84, PF8, 0xac, 0x0,
+		MA35_MUX(0x0, "GPF8"),
+		MA35_MUX(0x2, "UART13_RXD"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x5, "SPI0_SS0"),
+		MA35_MUX(0x8, "RGMII1_RXD1"),
+		MA35_MUX(0x9, "RMII1_RXD1"),
+		MA35_MUX(0xd, "SC0_RST"),
+		MA35_MUX(0xe, "KPI_COL4")),
+	MA35_PIN(85, PF9, 0xac, 0x4,
+		MA35_MUX(0x0, "GPF9"),
+		MA35_MUX(0x2, "UART13_TXD"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x5, "SPI0_SS1"),
+		MA35_MUX(0x8, "RGMII1_RXD2"),
+		MA35_MUX(0x9, "RMII1_RXERR"),
+		MA35_MUX(0xd, "SC0_PWR"),
+		MA35_MUX(0xe, "KPI_COL5")),
+	MA35_PIN(86, PF10, 0xac, 0x8,
+		MA35_MUX(0x0, "GPF10"),
+		MA35_MUX(0x2, "UART13_nCTS"),
+		MA35_MUX(0x5, "I2S0_LRCK"),
+		MA35_MUX(0x6, "SPI1_SS0"),
+		MA35_MUX(0x8, "RGMII1_RXD3"),
+		MA35_MUX(0x9, "SC0_CLK"),
+		MA35_MUX(0xe, "KPI_COL6")),
+	MA35_PIN(87, PF11, 0xac, 0xc,
+		MA35_MUX(0x0, "GPF11"),
+		MA35_MUX(0x2, "UART13_nRTS"),
+		MA35_MUX(0x5, "I2S0_BCLK"),
+		MA35_MUX(0x6, "SPI1_CLK"),
+		MA35_MUX(0x8, "RGMII1_TXCLK"),
+		MA35_MUX(0x9, "SC0_DAT"),
+		MA35_MUX(0xe, "KPI_COL7")),
+	MA35_PIN(88, PF12, 0xac, 0x10,
+		MA35_MUX(0x0, "GPF12"),
+		MA35_MUX(0x5, "I2S0_DI"),
+		MA35_MUX(0x6, "SPI1_MOSI"),
+		MA35_MUX(0x8, "RGMII1_TXD2"),
+		MA35_MUX(0x9, "SC0_RST"),
+		MA35_MUX(0xe, "KPI_ROW4")),
+	MA35_PIN(89, PF13, 0xac, 0x14,
+		MA35_MUX(0x0, "GPF13"),
+		MA35_MUX(0x5, "I2S0_DO"),
+		MA35_MUX(0x6, "SPI1_MISO"),
+		MA35_MUX(0x8, "RGMII1_TXD3"),
+		MA35_MUX(0x9, "SC0_PWR"),
+		MA35_MUX(0xe, "KPI_ROW5")),
+	MA35_PIN(90, PF14, 0xac, 0x18,
+		MA35_MUX(0x0, "GPF14"),
+		MA35_MUX(0x1, "EPWM2_BRAKE0"),
+		MA35_MUX(0x2, "EADC0_ST"),
+		MA35_MUX(0x3, "RGMII1_PPS"),
+		MA35_MUX(0x4, "RMII1_PPS"),
+		MA35_MUX(0x5, "SPI0_I2SMCLK"),
+		MA35_MUX(0x6, "SPI1_I2SMCLK"),
+		MA35_MUX(0x7, "CCAP1_SFIELD"),
+		MA35_MUX(0x8, "RGMII0_PPS"),
+		MA35_MUX(0x9, "RMII0_PPS"),
+		MA35_MUX(0xb, "TM0"),
+		MA35_MUX(0xc, "INT0"),
+		MA35_MUX(0xd, "SPI1_SS1"),
+		MA35_MUX(0xe, "QEI2_INDEX"),
+		MA35_MUX(0xf, "I2S0_MCLK")),
+	MA35_PIN(91, PF15, 0xac, 0x1c,
+		MA35_MUX(0x0, "GPF15"),
+		MA35_MUX(0x1, "HSUSB0_VBUSVLD")),
+	MA35_PIN(92, PG0, 0xb0, 0x0,
+		MA35_MUX(0x0, "GPG0"),
+		MA35_MUX(0x1, "EPWM0_CH0"),
+		MA35_MUX(0x2, "UART7_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "SPI0_SS0"),
+		MA35_MUX(0x6, "EADC0_ST"),
+		MA35_MUX(0x7, "EBI_AD15"),
+		MA35_MUX(0x9, "I2S1_MCLK"),
+		MA35_MUX(0xa, "QEI0_INDEX"),
+		MA35_MUX(0xb, "TM1"),
+		MA35_MUX(0xc, "CLKO"),
+		MA35_MUX(0xd, "INT0"),
+		MA35_MUX(0xf, "EBI_ADR15")),
+	MA35_PIN(93, PG1, 0xb0, 0x4,
+		MA35_MUX(0x0, "GPG1"),
+		MA35_MUX(0x1, "EPWM0_CH3"),
+		MA35_MUX(0x2, "UART9_nRTS"),
+		MA35_MUX(0x3, "UART6_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x5, "CAN2_TXD"),
+		MA35_MUX(0x7, "EBI_nCS0"),
+		MA35_MUX(0x9, "QEI0_B"),
+		MA35_MUX(0xb, "TM1_EXT"),
+		MA35_MUX(0xe, "RGMII1_PPS"),
+		MA35_MUX(0xf, "RMII1_PPS")),
+	MA35_PIN(94, PG2, 0xb0, 0x8,
+		MA35_MUX(0x0, "GPG2"),
+		MA35_MUX(0x1, "EPWM0_CH4"),
+		MA35_MUX(0x2, "UART9_RXD"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x5, "SPI0_SS1"),
+		MA35_MUX(0x7, "EBI_ADR16"),
+		MA35_MUX(0x8, "EBI_nCS2"),
+		MA35_MUX(0xa, "QEI0_A"),
+		MA35_MUX(0xb, "TM3"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(95, PG3, 0xb0, 0xc,
+		MA35_MUX(0x0, "GPG3"),
+		MA35_MUX(0x1, "EPWM0_CH5"),
+		MA35_MUX(0x2, "UART9_TXD"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x5, "SPI0_I2SMCLK"),
+		MA35_MUX(0x7, "EBI_ADR17"),
+		MA35_MUX(0x8, "EBI_nCS1"),
+		MA35_MUX(0x9, "EBI_MCLK"),
+		MA35_MUX(0xa, "QEI0_B"),
+		MA35_MUX(0xb, "TM3_EXT"),
+		MA35_MUX(0xc, "I2S1_MCLK")),
+	MA35_PIN(96, PG4, 0xb0, 0x10,
+		MA35_MUX(0x0, "GPG4"),
+		MA35_MUX(0x1, "EPWM1_CH0"),
+		MA35_MUX(0x2, "UART5_nCTS"),
+		MA35_MUX(0x3, "UART6_RXD"),
+		MA35_MUX(0x5, "SPI3_SS0"),
+		MA35_MUX(0x6, "QEI1_INDEX"),
+		MA35_MUX(0x7, "EBI_ADR18"),
+		MA35_MUX(0x8, "EBI_nCS0"),
+		MA35_MUX(0x9, "I2S1_DO"),
+		MA35_MUX(0xa, "SC1_CLK"),
+		MA35_MUX(0xb, "TM4"),
+		MA35_MUX(0xd, "INT2"),
+		MA35_MUX(0xe, "ECAP1_IC2")),
+	MA35_PIN(97, PG5, 0xb0, 0x14,
+		MA35_MUX(0x0, "GPG5"),
+		MA35_MUX(0x1, "EPWM1_CH1"),
+		MA35_MUX(0x2, "UART5_nRTS"),
+		MA35_MUX(0x3, "UART6_TXD"),
+		MA35_MUX(0x5, "SPI3_CLK"),
+		MA35_MUX(0x6, "ECAP0_IC0"),
+		MA35_MUX(0x7, "EBI_ADR19"),
+		MA35_MUX(0x8, "EBI_ALE"),
+		MA35_MUX(0x9, "I2S1_DI"),
+		MA35_MUX(0xa, "SC1_DAT"),
+		MA35_MUX(0xb, "TM4_EXT")),
+	MA35_PIN(98, PG6, 0xb0, 0x18,
+		MA35_MUX(0x0, "GPG6"),
+		MA35_MUX(0x1, "EPWM1_CH2"),
+		MA35_MUX(0x2, "UART5_RXD"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x5, "SPI3_MOSI"),
+		MA35_MUX(0x6, "ECAP0_IC1"),
+		MA35_MUX(0x7, "EBI_nRD"),
+		MA35_MUX(0x9, "I2S1_BCLK"),
+		MA35_MUX(0xa, "SC1_RST"),
+		MA35_MUX(0xb, "TM7"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(99, PG7, 0xb0, 0x1c,
+		MA35_MUX(0x0, "GPG7"),
+		MA35_MUX(0x1, "EPWM1_CH3"),
+		MA35_MUX(0x2, "UART5_TXD"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x5, "SPI3_MISO"),
+		MA35_MUX(0x6, "ECAP0_IC2"),
+		MA35_MUX(0x7, "EBI_nWR"),
+		MA35_MUX(0x9, "I2S1_LRCK"),
+		MA35_MUX(0xa, "SC1_PWR"),
+		MA35_MUX(0xb, "TM7_EXT")),
+	MA35_PIN(100, PG8, 0xb4, 0x0,
+		MA35_MUX(0x0, "GPG8"),
+		MA35_MUX(0x1, "EPWM1_CH4"),
+		MA35_MUX(0x2, "UART12_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "SPI2_SS0"),
+		MA35_MUX(0x6, "LCM_VSYNC"),
+		MA35_MUX(0x7, "I2C3_SDA"),
+		MA35_MUX(0xc, "EBI_AD7"),
+		MA35_MUX(0xd, "EBI_nCS0")),
+	MA35_PIN(101, PG9, 0xb4, 0x4,
+		MA35_MUX(0x0, "GPG9"),
+		MA35_MUX(0x1, "EPWM1_CH5"),
+		MA35_MUX(0x2, "UART12_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "SPI2_CLK"),
+		MA35_MUX(0x6, "LCM_HSYNC"),
+		MA35_MUX(0x7, "I2C3_SCL"),
+		MA35_MUX(0xc, "EBI_AD8"),
+		MA35_MUX(0xd, "EBI_nCS1")),
+	MA35_PIN(102, PG10, 0xb4, 0x8,
+		MA35_MUX(0x0, "GPG10"),
+		MA35_MUX(0x2, "UART12_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x5, "SPI2_MOSI"),
+		MA35_MUX(0x6, "LCM_CLK"),
+		MA35_MUX(0xc, "EBI_AD9"),
+		MA35_MUX(0xd, "EBI_nWRH")),
+	MA35_PIN(103, PG11, 0xb4, 0xc,
+		MA35_MUX(0x0, "GPG11"),
+		MA35_MUX(0x3, "JTAG_TDO"),
+		MA35_MUX(0x5, "I2S0_MCLK"),
+		MA35_MUX(0x6, "NAND_RDY1"),
+		MA35_MUX(0x7, "EBI_nWRH"),
+		MA35_MUX(0x8, "EBI_nCS1"),
+		MA35_MUX(0xa, "EBI_AD0")),
+	MA35_PIN(104, PG12, 0xb4, 0x10,
+		MA35_MUX(0x0, "GPG12"),
+		MA35_MUX(0x3, "JTAG_TCK/SW_CLK"),
+		MA35_MUX(0x5, "I2S0_LRCK"),
+		MA35_MUX(0x7, "EBI_nWRL"),
+		MA35_MUX(0xa, "EBI_AD1")),
+	MA35_PIN(105, PG13, 0xb4, 0x14,
+		MA35_MUX(0x0, "GPG13"),
+		MA35_MUX(0x3, "JTAG_TMS/SW_DIO"),
+		MA35_MUX(0x5, "I2S0_BCLK"),
+		MA35_MUX(0x7, "EBI_MCLK"),
+		MA35_MUX(0xa, "EBI_AD2")),
+	MA35_PIN(106, PG14, 0xb4, 0x18,
+		MA35_MUX(0x0, "GPG14"),
+		MA35_MUX(0x3, "JTAG_TDI"),
+		MA35_MUX(0x5, "I2S0_DI"),
+		MA35_MUX(0x6, "NAND_nCS1"),
+		MA35_MUX(0x7, "EBI_ALE"),
+		MA35_MUX(0xa, "EBI_AD3")),
+	MA35_PIN(107, PG15, 0xb4, 0x1c,
+		MA35_MUX(0x0, "GPG15"),
+		MA35_MUX(0x3, "JTAG_nTRST"),
+		MA35_MUX(0x5, "I2S0_DO"),
+		MA35_MUX(0x7, "EBI_nCS0"),
+		MA35_MUX(0xa, "EBI_AD4")),
+	MA35_PIN(108, PH0, 0xb8, 0x0,
+		MA35_MUX(0x0, "GPH0"),
+		MA35_MUX(0x2, "UART8_nCTS"),
+		MA35_MUX(0x3, "UART7_RXD"),
+		MA35_MUX(0x6, "LCM_DATA8")),
+	MA35_PIN(109, PH1, 0xb8, 0x4,
+		MA35_MUX(0x0, "GPH1"),
+		MA35_MUX(0x2, "UART8_nRTS"),
+		MA35_MUX(0x3, "UART7_TXD"),
+		MA35_MUX(0x6, "LCM_DATA9")),
+	MA35_PIN(110, PH2, 0xb8, 0x8,
+		MA35_MUX(0x0, "GPH2"),
+		MA35_MUX(0x2, "UART8_RXD"),
+		MA35_MUX(0x6, "LCM_DATA10")),
+	MA35_PIN(111, PH3, 0xb8, 0xc,
+		MA35_MUX(0x0, "GPH3"),
+		MA35_MUX(0x2, "UART8_TXD"),
+		MA35_MUX(0x6, "LCM_DATA11")),
+	MA35_PIN(112, PH4, 0xb8, 0x10,
+		MA35_MUX(0x0, "GPH4"),
+		MA35_MUX(0x2, "UART10_nCTS"),
+		MA35_MUX(0x3, "UART9_RXD"),
+		MA35_MUX(0x6, "LCM_DATA12")),
+	MA35_PIN(113, PH5, 0xb8, 0x14,
+		MA35_MUX(0x0, "GPH5"),
+		MA35_MUX(0x2, "UART10_nRTS"),
+		MA35_MUX(0x3, "UART9_TXD"),
+		MA35_MUX(0x6, "LCM_DATA13")),
+	MA35_PIN(114, PH6, 0xb8, 0x18,
+		MA35_MUX(0x0, "GPH6"),
+		MA35_MUX(0x2, "UART10_RXD"),
+		MA35_MUX(0x6, "LCM_DATA14")),
+	MA35_PIN(115, PH7, 0xb8, 0x1c,
+		MA35_MUX(0x0, "GPH7"),
+		MA35_MUX(0x2, "UART10_TXD"),
+		MA35_MUX(0x6, "LCM_DATA15")),
+	MA35_PIN(116, PH8, 0xbc, 0x0,
+		MA35_MUX(0x0, "GPH8"),
+		MA35_MUX(0x6, "TAMPER0")),
+	MA35_PIN(117, PH9, 0xbc, 0x4,
+		MA35_MUX(0x0, "GPH9"),
+		MA35_MUX(0x4, "CLK_32KOUT"),
+		MA35_MUX(0x6, "TAMPER1")),
+	MA35_PIN(118, PH12, 0xbc, 0x10,
+		MA35_MUX(0x0, "GPH12"),
+		MA35_MUX(0x2, "UART14_nCTS"),
+		MA35_MUX(0x3, "UART13_RXD"),
+		MA35_MUX(0x6, "LCM_DATA20")),
+	MA35_PIN(119, PH13, 0xbc, 0x14,
+		MA35_MUX(0x0, "GPH13"),
+		MA35_MUX(0x2, "UART14_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x6, "LCM_DATA21")),
+	MA35_PIN(120, PH14, 0xbc, 0x18,
+		MA35_MUX(0x0, "GPH14"),
+		MA35_MUX(0x2, "UART14_RXD"),
+		MA35_MUX(0x6, "LCM_DATA22")),
+	MA35_PIN(121, PH15, 0xbc, 0x1c,
+		MA35_MUX(0x0, "GPH15"),
+		MA35_MUX(0x2, "UART14_TXD"),
+		MA35_MUX(0x6, "LCM_DATA23")),
+	MA35_PIN(122, PI0, 0xc0, 0x0,
+		MA35_MUX(0x0, "GPI0"),
+		MA35_MUX(0x1, "EPWM0_CH0"),
+		MA35_MUX(0x2, "UART12_nCTS"),
+		MA35_MUX(0x3, "UART11_RXD"),
+		MA35_MUX(0x4, "I2C2_SDA"),
+		MA35_MUX(0x5, "SPI3_SS0"),
+		MA35_MUX(0x7, "SC0_nCD"),
+		MA35_MUX(0x8, "EBI_ADR0"),
+		MA35_MUX(0xb, "TM0"),
+		MA35_MUX(0xc, "ECAP1_IC0")),
+	MA35_PIN(123, PI1, 0xc0, 0x4,
+		MA35_MUX(0x0, "GPI1"),
+		MA35_MUX(0x1, "EPWM0_CH1"),
+		MA35_MUX(0x2, "UART12_nRTS"),
+		MA35_MUX(0x3, "UART11_TXD"),
+		MA35_MUX(0x4, "I2C2_SCL"),
+		MA35_MUX(0x5, "SPI3_CLK"),
+		MA35_MUX(0x7, "SC0_CLK"),
+		MA35_MUX(0x8, "EBI_ADR1"),
+		MA35_MUX(0xb, "TM0_EXT"),
+		MA35_MUX(0xc, "ECAP1_IC1")),
+	MA35_PIN(124, PI2, 0xc0, 0x8,
+		MA35_MUX(0x0, "GPI2"),
+		MA35_MUX(0x1, "EPWM0_CH2"),
+		MA35_MUX(0x2, "UART12_RXD"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x5, "SPI3_MOSI"),
+		MA35_MUX(0x7, "SC0_DAT"),
+		MA35_MUX(0x8, "EBI_ADR2"),
+		MA35_MUX(0xb, "TM1"),
+		MA35_MUX(0xc, "ECAP1_IC2")),
+	MA35_PIN(125, PI3, 0xc0, 0xc,
+		MA35_MUX(0x0, "GPI3"),
+		MA35_MUX(0x1, "EPWM0_CH3"),
+		MA35_MUX(0x2, "UART12_TXD"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x5, "SPI3_MISO"),
+		MA35_MUX(0x7, "SC0_RST"),
+		MA35_MUX(0x8, "EBI_ADR3"),
+		MA35_MUX(0xb, "TM1_EXT")),
+	MA35_PIN(126, PI4, 0xc0, 0x10,
+		MA35_MUX(0x0, "GPI4"),
+		MA35_MUX(0x1, "EPWM0_CH4"),
+		MA35_MUX(0x2, "UART14_nCTS"),
+		MA35_MUX(0x3, "UART13_RXD"),
+		MA35_MUX(0x4, "I2C3_SDA"),
+		MA35_MUX(0x5, "SPI2_SS1"),
+		MA35_MUX(0x6, "I2S1_LRCK"),
+		MA35_MUX(0x8, "EBI_ADR4"),
+		MA35_MUX(0xd, "INT0")),
+	MA35_PIN(127, PI5, 0xc0, 0x14,
+		MA35_MUX(0x0, "GPI5"),
+		MA35_MUX(0x1, "EPWM0_CH5"),
+		MA35_MUX(0x2, "UART14_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x4, "I2C3_SCL"),
+		MA35_MUX(0x6, "I2S1_BCLK"),
+		MA35_MUX(0x8, "EBI_ADR5"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(128, PI6, 0xc0, 0x18,
+		MA35_MUX(0x0, "GPI6"),
+		MA35_MUX(0x1, "EPWM0_BRAKE0"),
+		MA35_MUX(0x2, "UART14_RXD"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x6, "I2S1_DI"),
+		MA35_MUX(0x8, "EBI_ADR6"),
+		MA35_MUX(0xc, "QEI1_INDEX"),
+		MA35_MUX(0xd, "INT2")),
+	MA35_PIN(129, PI7, 0xc0, 0x1c,
+		MA35_MUX(0x0, "GPI7"),
+		MA35_MUX(0x1, "EPWM0_BRAKE1"),
+		MA35_MUX(0x2, "UART14_TXD"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x6, "I2S1_DO"),
+		MA35_MUX(0x8, "EBI_ADR7"),
+		MA35_MUX(0xc, "ECAP0_IC0"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(130, PI8, 0xc4, 0x0,
+		MA35_MUX(0x0, "GPI8"),
+		MA35_MUX(0x2, "UART4_nCTS"),
+		MA35_MUX(0x3, "UART3_RXD"),
+		MA35_MUX(0x6, "LCM_DATA0"),
+		MA35_MUX(0xc, "EBI_AD11")),
+	MA35_PIN(131, PI9, 0xc4, 0x4,
+		MA35_MUX(0x0, "GPI9"),
+		MA35_MUX(0x2, "UART4_nRTS"),
+		MA35_MUX(0x3, "UART3_TXD"),
+		MA35_MUX(0x6, "LCM_DATA1"),
+		MA35_MUX(0xc, "EBI_AD12")),
+	MA35_PIN(132, PI10, 0xc4, 0x8,
+		MA35_MUX(0x0, "GPI10"),
+		MA35_MUX(0x2, "UART4_RXD"),
+		MA35_MUX(0x6, "LCM_DATA2"),
+		MA35_MUX(0xc, "EBI_AD13")),
+	MA35_PIN(133, PI11, 0xC4, 0xc,
+		MA35_MUX(0x0, "GPI11"),
+		MA35_MUX(0x2, "UART4_TXD"),
+		MA35_MUX(0x6, "LCM_DATA3"),
+		MA35_MUX(0xc, "EBI_AD14")),
+	MA35_PIN(134, PI12, 0xc4, 0x10,
+		MA35_MUX(0x0, "GPI12"),
+		MA35_MUX(0x2, "UART6_nCTS"),
+		MA35_MUX(0x3, "UART5_RXD"),
+		MA35_MUX(0x6, "LCM_DATA4")),
+	MA35_PIN(135, PI13, 0xc4, 0x14,
+		MA35_MUX(0x0, "GPI13"),
+		MA35_MUX(0x2, "UART6_nRTS"),
+		MA35_MUX(0x3, "UART5_TXD"),
+		MA35_MUX(0x6, "LCM_DATA5")),
+	MA35_PIN(136, PI14, 0xc4, 0x18,
+		MA35_MUX(0x0, "GPI14"),
+		MA35_MUX(0x2, "UART6_RXD"),
+		MA35_MUX(0x6, "LCM_DATA6")),
+	MA35_PIN(137, PI15, 0xc4, 0x1c,
+		MA35_MUX(0x0, "GPI15"),
+		MA35_MUX(0x2, "UART6_TXD"),
+		MA35_MUX(0x6, "LCM_DATA7")),
+	MA35_PIN(138, PJ0, 0xc8, 0x0,
+		MA35_MUX(0x0, "GPJ0"),
+		MA35_MUX(0x1, "EPWM1_BRAKE0"),
+		MA35_MUX(0x2, "UART8_nCTS"),
+		MA35_MUX(0x3, "UART7_RXD"),
+		MA35_MUX(0x4, "I2C2_SDA"),
+		MA35_MUX(0x5, "SPI2_SS0"),
+		MA35_MUX(0x6, "eMMC1_DAT4"),
+		MA35_MUX(0x7, "I2S0_LRCK"),
+		MA35_MUX(0x8, "SC0_CLK"),
+		MA35_MUX(0x9, "EBI_AD11"),
+		MA35_MUX(0xa, "EBI_ADR16"),
+		MA35_MUX(0xb, "EBI_nCS0"),
+		MA35_MUX(0xc, "EBI_AD7")),
+	MA35_PIN(139, PJ1, 0xc8, 0x4,
+		MA35_MUX(0x0, "GPJ1"),
+		MA35_MUX(0x1, "EPWM1_BRAKE1"),
+		MA35_MUX(0x2, "UART8_nRTS"),
+		MA35_MUX(0x3, "UART7_TXD"),
+		MA35_MUX(0x4, "I2C2_SCL"),
+		MA35_MUX(0x5, "SPI2_CLK"),
+		MA35_MUX(0x6, "eMMC1_DAT5"),
+		MA35_MUX(0x7, "I2S0_BCLK"),
+		MA35_MUX(0x8, "SC0_DAT"),
+		MA35_MUX(0x9, "EBI_AD12"),
+		MA35_MUX(0xa, "EBI_ADR17"),
+		MA35_MUX(0xb, "EBI_nCS1"),
+		MA35_MUX(0xc, "EBI_AD8")),
+	MA35_PIN(140, PJ2, 0xc8, 0x8,
+		MA35_MUX(0x0, "GPJ2"),
+		MA35_MUX(0x1, "EPWM1_CH4"),
+		MA35_MUX(0x2, "UART8_RXD"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x5, "SPI2_MOSI"),
+		MA35_MUX(0x6, "eMMC1_DAT6"),
+		MA35_MUX(0x7, "I2S0_DI"),
+		MA35_MUX(0x8, "SC0_RST"),
+		MA35_MUX(0x9, "EBI_AD13"),
+		MA35_MUX(0xa, "EBI_ADR18"),
+		MA35_MUX(0xb, "EBI_nWRH"),
+		MA35_MUX(0xc, "EBI_AD9")),
+	MA35_PIN(141, PJ3, 0xc8, 0xc,
+		MA35_MUX(0x0, "GPJ3"),
+		MA35_MUX(0x1, "EPWM1_CH5"),
+		MA35_MUX(0x2, "UART8_TXD"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x5, "SPI2_MISO"),
+		MA35_MUX(0x6, "eMMC1_DAT7"),
+		MA35_MUX(0x7, "I2S0_DO"),
+		MA35_MUX(0x8, "SC0_PWR"),
+		MA35_MUX(0x9, "EBI_AD14"),
+		MA35_MUX(0xa, "EBI_ADR19"),
+		MA35_MUX(0xb, "EBI_nWRL"),
+		MA35_MUX(0xc, "EBI_AD10")),
+	MA35_PIN(142, PJ4, 0xc8, 0x10,
+		MA35_MUX(0x0, "GPJ4"),
+		MA35_MUX(0x4, "I2C3_SDA"),
+		MA35_MUX(0x6, "SD1_WP")),
+	MA35_PIN(143, PJ5, 0xc8, 0x14,
+		MA35_MUX(0x0, "GPJ5"),
+		MA35_MUX(0x4, "I2C3_SCL"),
+		MA35_MUX(0x6, "SD1_nCD")),
+	MA35_PIN(144, PJ6, 0xc8, 0x18,
+		MA35_MUX(0x0, "GPJ6"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x6, "SD1_CMD/eMMC1_CMD")),
+	MA35_PIN(145, PJ7, 0xc8, 0x1c,
+		MA35_MUX(0x0, "GPJ7"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x6, "SD1_CLK/eMMC1_CLK")),
+	MA35_PIN(146, PJ8, 0xcc, 0x0,
+		MA35_MUX(0x0, "GPJ8"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x6, "SD1_DAT0/eMMC1_DAT0")),
+	MA35_PIN(147, PJ9, 0xcc, 0x4,
+		MA35_MUX(0x0, "GPJ9"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x6, "SD1_DAT1/eMMC1_DAT1")),
+	MA35_PIN(148, PJ10, 0xcc, 0x8,
+		MA35_MUX(0x0, "GPJ10"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x6, "SD1_DAT2/eMMC1_DAT2")),
+	MA35_PIN(149, PJ11, 0xcc, 0xc,
+		MA35_MUX(0x0, "GPJ11"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x6, "SD1_DAT3/eMMC1_DAT3")),
+	MA35_PIN(150, PJ12, 0xcc, 0x10,
+		MA35_MUX(0x0, "GPJ12"),
+		MA35_MUX(0x1, "EPWM1_CH2"),
+		MA35_MUX(0x2, "UART2_nCTS"),
+		MA35_MUX(0x3, "UART1_RXD"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x5, "SPI3_SS0"),
+		MA35_MUX(0x7, "SC1_CLK"),
+		MA35_MUX(0x8, "EBI_ADR12"),
+		MA35_MUX(0xb, "TM2"),
+		MA35_MUX(0xc, "QEI0_INDEX")),
+	MA35_PIN(151, PJ13, 0xcc, 0x14,
+		MA35_MUX(0x0, "GPJ13"),
+		MA35_MUX(0x1, "EPWM1_CH3"),
+		MA35_MUX(0x2, "UART2_nRTS"),
+		MA35_MUX(0x3, "UART1_TXD"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x5, "SPI3_MOSI"),
+		MA35_MUX(0x7, "SC1_DAT"),
+		MA35_MUX(0x8, "EBI_ADR13"),
+		MA35_MUX(0xb, "TM2_EXT")),
+	MA35_PIN(152, PJ14, 0xcc, 0x18,
+		MA35_MUX(0x0, "GPJ14"),
+		MA35_MUX(0x1, "EPWM1_CH4"),
+		MA35_MUX(0x2, "UART2_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "SPI3_MISO"),
+		MA35_MUX(0x7, "SC1_RST"),
+		MA35_MUX(0x8, "EBI_ADR14"),
+		MA35_MUX(0xb, "TM3")),
+	MA35_PIN(153, PJ15, 0xcc, 0x1c,
+		MA35_MUX(0x0, "GPJ15"),
+		MA35_MUX(0x1, "EPWM1_CH5"),
+		MA35_MUX(0x2, "UART2_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "SPI3_CLK"),
+		MA35_MUX(0x6, "EADC0_ST"),
+		MA35_MUX(0x7, "SC1_PWR"),
+		MA35_MUX(0x8, "EBI_ADR15"),
+		MA35_MUX(0xb, "TM3_EXT"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(154, PK0, 0xd0, 0x0,
+		MA35_MUX(0x0, "GPK0"),
+		MA35_MUX(0x1, "EPWM0_SYNC_IN"),
+		MA35_MUX(0x2, "UART16_nCTS"),
+		MA35_MUX(0x3, "UART15_RXD"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x6, "I2S1_MCLK"),
+		MA35_MUX(0x8, "EBI_ADR8"),
+		MA35_MUX(0xb, "TM7"),
+		MA35_MUX(0xc, "ECAP0_IC1")),
+	MA35_PIN(155, PK1, 0xd0, 0x4,
+		MA35_MUX(0x0, "GPK1"),
+		MA35_MUX(0x1, "EPWM0_SYNC_OUT"),
+		MA35_MUX(0x2, "UART16_nRTS"),
+		MA35_MUX(0x3, "UART15_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x6, "EADC0_ST"),
+		MA35_MUX(0x8, "EBI_ADR9"),
+		MA35_MUX(0xb, "TM7_EXT"),
+		MA35_MUX(0xc, "ECAP0_IC2")),
+	MA35_PIN(156, PK2, 0xd0, 0x8,
+		MA35_MUX(0x0, "GPK2"),
+		MA35_MUX(0x1, "EPWM1_CH0"),
+		MA35_MUX(0x2, "UART16_RXD"),
+		MA35_MUX(0x3, "CAN2_RXD"),
+		MA35_MUX(0x5, "SPI3_I2SMCLK"),
+		MA35_MUX(0x7, "SC0_PWR"),
+		MA35_MUX(0x8, "EBI_ADR10"),
+		MA35_MUX(0xc, "QEI0_A")),
+	MA35_PIN(157, PK3, 0xd0, 0xc,
+		MA35_MUX(0x0, "GPK3"),
+		MA35_MUX(0x1, "EPWM1_CH1"),
+		MA35_MUX(0x2, "UART16_TXD"),
+		MA35_MUX(0x3, "CAN2_TXD"),
+		MA35_MUX(0x5, "SPI3_SS1"),
+		MA35_MUX(0x7, "SC1_nCD"),
+		MA35_MUX(0x8, "EBI_ADR11"),
+		MA35_MUX(0xc, "QEI0_B")),
+	MA35_PIN(158, PK4, 0xd0, 0x10,
+		MA35_MUX(0x0, "GPK4"),
+		MA35_MUX(0x2, "UART12_nCTS"),
+		MA35_MUX(0x3, "UART13_RXD"),
+		MA35_MUX(0x5, "SPI2_MISO"),
+		MA35_MUX(0x6, "LCM_DEN"),
+		MA35_MUX(0xc, "EBI_AD10"),
+		MA35_MUX(0xd, "EBI_nWRL")),
+	MA35_PIN(159, PK5, 0xd0, 0x14,
+		MA35_MUX(0x0, "GPK5"),
+		MA35_MUX(0x1, "EPWM1_CH1"),
+		MA35_MUX(0x2, "UART12_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x5, "SPI2_CLK"),
+		MA35_MUX(0x7, "I2S1_DI"),
+		MA35_MUX(0x8, "SC0_DAT"),
+		MA35_MUX(0x9, "EADC0_ST"),
+		MA35_MUX(0xb, "TM8_EXT"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(160, PK6, 0xd0, 0x18,
+		MA35_MUX(0x0, "GPK6"),
+		MA35_MUX(0x1, "EPWM1_CH2"),
+		MA35_MUX(0x2, "UART12_RXD"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x5, "SPI2_MOSI"),
+		MA35_MUX(0x7, "I2S1_BCLK"),
+		MA35_MUX(0x8, "SC0_RST"),
+		MA35_MUX(0xb, "TM6"),
+		MA35_MUX(0xd, "INT2")),
+	MA35_PIN(161, PK7, 0xd0, 0x1c,
+		MA35_MUX(0x0, "GPK7"),
+		MA35_MUX(0x1, "EPWM1_CH3"),
+		MA35_MUX(0x2, "UART12_TXD"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x5, "SPI2_MISO"),
+		MA35_MUX(0x7, "I2S1_LRCK"),
+		MA35_MUX(0x8, "SC0_PWR"),
+		MA35_MUX(0x9, "CLKO"),
+		MA35_MUX(0xb, "TM6_EXT"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(162, PK8, 0xd4, 0x0,
+		MA35_MUX(0x0, "GPK8"),
+		MA35_MUX(0x1, "EPWM1_CH0"),
+		MA35_MUX(0x4, "I2C3_SDA"),
+		MA35_MUX(0x5, "SPI3_CLK"),
+		MA35_MUX(0x7, "EADC0_ST"),
+		MA35_MUX(0x8, "EBI_AD15"),
+		MA35_MUX(0x9, "EBI_MCLK"),
+		MA35_MUX(0xa, "EBI_ADR15"),
+		MA35_MUX(0xb, "TM8"),
+		MA35_MUX(0xc, "QEI1_INDEX")),
+	MA35_PIN(163, PK9, 0xd4, 0x4,
+		MA35_MUX(0x0, "GPK9"),
+		MA35_MUX(0x4, "I2C3_SCL"),
+		MA35_MUX(0x6, "CCAP0_SCLK"),
+		MA35_MUX(0x8, "EBI_AD0"),
+		MA35_MUX(0xa, "EBI_ADR0")),
+	MA35_PIN(164, PK10, 0xd4, 0x8,
+		MA35_MUX(0x0, "GPK10"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x6, "CCAP0_PIXCLK"),
+		MA35_MUX(0x8, "EBI_AD1"),
+		MA35_MUX(0xa, "EBI_ADR1")),
+	MA35_PIN(165, PK11, 0xd4, 0xc,
+		MA35_MUX(0x0, "GPK11"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x6, "CCAP0_HSYNC"),
+		MA35_MUX(0x8, "EBI_AD2"),
+		MA35_MUX(0xa, "EBI_ADR2")),
+	MA35_PIN(166, PK12, 0xd4, 0x10,
+		MA35_MUX(0x0, "GPK12"),
+		MA35_MUX(0x1, "EPWM2_CH0"),
+		MA35_MUX(0x2, "UART1_nCTS"),
+		MA35_MUX(0x3, "UART13_RXD"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x5, "I2S0_LRCK"),
+		MA35_MUX(0x6, "SPI1_SS0"),
+		MA35_MUX(0x8, "SC0_CLK"),
+		MA35_MUX(0xb, "TM10"),
+		MA35_MUX(0xd, "INT2")),
+	MA35_PIN(167, PK13, 0xd4, 0x14,
+		MA35_MUX(0x0, "GPK13"),
+		MA35_MUX(0x1, "EPWM2_CH1"),
+		MA35_MUX(0x2, "UART1_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x5, "I2S0_BCLK"),
+		MA35_MUX(0x6, "SPI1_CLK"),
+		MA35_MUX(0x8, "SC0_DAT"),
+		MA35_MUX(0xb, "TM10_EXT")),
+	MA35_PIN(168, PK14, 0xd4, 0x18,
+		MA35_MUX(0x0, "GPK14"),
+		MA35_MUX(0x1, "EPWM2_CH2"),
+		MA35_MUX(0x2, "UART1_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "I2S0_DI"),
+		MA35_MUX(0x6, "SPI1_MOSI"),
+		MA35_MUX(0x8, "SC0_RST"),
+		MA35_MUX(0xa, "I2C5_SDA"),
+		MA35_MUX(0xb, "TM11"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(169, PK15, 0xd4, 0x1c,
+		MA35_MUX(0x0, "GPK15"),
+		MA35_MUX(0x1, "EPWM2_CH3"),
+		MA35_MUX(0x2, "UART1_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "I2S0_DO"),
+		MA35_MUX(0x6, "SPI1_MISO"),
+		MA35_MUX(0x8, "SC0_PWR"),
+		MA35_MUX(0xa, "I2C5_SCL"),
+		MA35_MUX(0xb, "TM11_EXT")),
+	MA35_PIN(170, PL0, 0xd8, 0x0,
+		MA35_MUX(0x0, "GPL0"),
+		MA35_MUX(0x1, "EPWM1_CH0"),
+		MA35_MUX(0x2, "UART11_nCTS"),
+		MA35_MUX(0x3, "UART10_RXD"),
+		MA35_MUX(0x4, "I2C3_SDA"),
+		MA35_MUX(0x5, "SPI2_MOSI"),
+		MA35_MUX(0x6, "QSPI1_MOSI1"),
+		MA35_MUX(0x7, "I2S0_LRCK"),
+		MA35_MUX(0x8, "EBI_AD11"),
+		MA35_MUX(0x9, "SC1_CLK"),
+		MA35_MUX(0xb, "TM5"),
+		MA35_MUX(0xc, "QEI1_A")),
+	MA35_PIN(171, PL1, 0xd8, 0x4,
+		MA35_MUX(0x0, "GPL1"),
+		MA35_MUX(0x1, "EPWM1_CH1"),
+		MA35_MUX(0x2, "UART11_nRTS"),
+		MA35_MUX(0x3, "UART10_TXD"),
+		MA35_MUX(0x4, "I2C3_SCL"),
+		MA35_MUX(0x5, "SPI2_MISO"),
+		MA35_MUX(0x6, "QSPI1_MISO1"),
+		MA35_MUX(0x7, "I2S0_BCLK"),
+		MA35_MUX(0x8, "EBI_AD12"),
+		MA35_MUX(0x9, "SC1_DAT"),
+		MA35_MUX(0xb, "TM5_EXT"),
+		MA35_MUX(0xc, "QEI1_B")),
+	MA35_PIN(172, PL2, 0xd8, 0x8,
+		MA35_MUX(0x0, "GPL2"),
+		MA35_MUX(0x1, "EPWM1_CH2"),
+		MA35_MUX(0x2, "UART11_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "SPI2_SS0"),
+		MA35_MUX(0x6, "QSPI1_SS1"),
+		MA35_MUX(0x7, "I2S0_DI"),
+		MA35_MUX(0x8, "EBI_AD13"),
+		MA35_MUX(0x9, "SC1_RST"),
+		MA35_MUX(0xb, "TM7"),
+		MA35_MUX(0xc, "QEI1_INDEX")),
+	MA35_PIN(173, PL3, 0xd8, 0xc,
+		MA35_MUX(0x0, "GPL3"),
+		MA35_MUX(0x1, "EPWM1_CH3"),
+		MA35_MUX(0x2, "UART11_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "SPI2_CLK"),
+		MA35_MUX(0x6, "QSPI1_CLK"),
+		MA35_MUX(0x7, "I2S0_DO"),
+		MA35_MUX(0x8, "EBI_AD14"),
+		MA35_MUX(0x9, "SC1_PWR"),
+		MA35_MUX(0xb, "TM7_EXT"),
+		MA35_MUX(0xc, "ECAP0_IC0")),
+	MA35_PIN(174, PL4, 0xd8, 0x10,
+		MA35_MUX(0x0, "GPL4"),
+		MA35_MUX(0x1, "EPWM1_CH4"),
+		MA35_MUX(0x2, "UART2_nCTS"),
+		MA35_MUX(0x3, "UART1_RXD"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x5, "SPI3_MOSI"),
+		MA35_MUX(0x6, "QSPI1_MOSI0"),
+		MA35_MUX(0x7, "I2S0_MCLK"),
+		MA35_MUX(0x8, "EBI_nRD"),
+		MA35_MUX(0x9, "SC1_nCD"),
+		MA35_MUX(0xb, "TM9"),
+		MA35_MUX(0xc, "ECAP0_IC1")),
+	MA35_PIN(175, PL5, 0xd8, 0x14,
+		MA35_MUX(0x0, "GPL5"),
+		MA35_MUX(0x1, "EPWM1_CH5"),
+		MA35_MUX(0x2, "UART2_nRTS"),
+		MA35_MUX(0x3, "UART1_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x5, "SPI3_MISO"),
+		MA35_MUX(0x6, "QSPI1_MISO0"),
+		MA35_MUX(0x7, "I2S1_MCLK"),
+		MA35_MUX(0x8, "EBI_nWR"),
+		MA35_MUX(0x9, "SC0_nCD"),
+		MA35_MUX(0xb, "TM9_EXT"),
+		MA35_MUX(0xc, "ECAP0_IC2")),
+	MA35_PIN(176, PL6, 0xd8, 0x18,
+		MA35_MUX(0x0, "GPL6"),
+		MA35_MUX(0x1, "EPWM0_CH0"),
+		MA35_MUX(0x2, "UART2_RXD"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x6, "QSPI1_MOSI1"),
+		MA35_MUX(0x7, "TRACE_CLK"),
+		MA35_MUX(0x8, "EBI_AD5"),
+		MA35_MUX(0xb, "TM3"),
+		MA35_MUX(0xc, "ECAP1_IC0"),
+		MA35_MUX(0xd, "INT0")),
+	MA35_PIN(177, PL7, 0xd8, 0x1c,
+		MA35_MUX(0x0, "GPL7"),
+		MA35_MUX(0x1, "EPWM0_CH1"),
+		MA35_MUX(0x2, "UART2_TXD"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x6, "QSPI1_MISO1"),
+		MA35_MUX(0x8, "EBI_AD6"),
+		MA35_MUX(0xb, "TM3_EXT"),
+		MA35_MUX(0xc, "ECAP1_IC1"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(178, PL8, 0xdc, 0x0,
+		MA35_MUX(0x0, "GPL8"),
+		MA35_MUX(0x1, "EPWM0_CH2"),
+		MA35_MUX(0x2, "UART14_nCTS"),
+		MA35_MUX(0x3, "UART13_RXD"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x5, "SPI3_SS0"),
+		MA35_MUX(0x6, "EPWM0_CH4"),
+		MA35_MUX(0x7, "I2S1_LRCK"),
+		MA35_MUX(0x8, "EBI_AD7"),
+		MA35_MUX(0x9, "SC0_CLK"),
+		MA35_MUX(0xb, "TM4"),
+		MA35_MUX(0xc, "ECAP1_IC2"),
+		MA35_MUX(0xd, "INT2")),
+	MA35_PIN(179, PL9, 0xdc, 0x4,
+		MA35_MUX(0x0, "GPL9"),
+		MA35_MUX(0x1, "EPWM0_CH3"),
+		MA35_MUX(0x2, "UART14_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x5, "SPI3_CLK"),
+		MA35_MUX(0x6, "EPWM1_CH4"),
+		MA35_MUX(0x7, "I2S1_BCLK"),
+		MA35_MUX(0x8, "EBI_AD8"),
+		MA35_MUX(0x9, "SC0_DAT"),
+		MA35_MUX(0xb, "TM4_EXT"),
+		MA35_MUX(0xc, "QEI0_A"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(180, PL10, 0xdc, 0x8,
+		MA35_MUX(0x0, "GPL10"),
+		MA35_MUX(0x1, "EPWM0_CH4"),
+		MA35_MUX(0x2, "UART14_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "SPI3_MOSI"),
+		MA35_MUX(0x6, "EPWM0_CH5"),
+		MA35_MUX(0x7, "I2S1_DI"),
+		MA35_MUX(0x8, "EBI_AD9"),
+		MA35_MUX(0x9, "SC0_RST"),
+		MA35_MUX(0xb, "EBI_nWRH"),
+		MA35_MUX(0xc, "QEI0_B")),
+	MA35_PIN(181, PL11, 0xdc, 0xc,
+		MA35_MUX(0x0, "GPL11"),
+		MA35_MUX(0x1, "EPWM0_CH5"),
+		MA35_MUX(0x2, "UART14_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "SPI3_MISO"),
+		MA35_MUX(0x6, "EPWM1_CH5"),
+		MA35_MUX(0x7, "I2S1_DO"),
+		MA35_MUX(0x8, "EBI_AD10"),
+		MA35_MUX(0x9, "SC0_PWR"),
+		MA35_MUX(0xb, "EBI_nWRL"),
+		MA35_MUX(0xc, "QEI0_INDEX")),
+	MA35_PIN(182, PL12, 0xdc, 0x10,
+		MA35_MUX(0x0, "GPL12"),
+		MA35_MUX(0x1, "EPWM0_SYNC_IN"),
+		MA35_MUX(0x2, "UART7_nCTS"),
+		MA35_MUX(0x3, "ECAP1_IC0"),
+		MA35_MUX(0x4, "UART14_RXD"),
+		MA35_MUX(0x5, "SPI0_SS0"),
+		MA35_MUX(0x6, "I2S1_LRCK"),
+		MA35_MUX(0x7, "SC1_CLK"),
+		MA35_MUX(0x8, "EBI_AD0"),
+		MA35_MUX(0x9, "HSUSBH_PWREN"),
+		MA35_MUX(0xa, "I2C2_SDA"),
+		MA35_MUX(0xb, "TM0"),
+		MA35_MUX(0xc, "EPWM0_CH2"),
+		MA35_MUX(0xd, "EBI_AD11"),
+		MA35_MUX(0xe, "RGMII0_PPS"),
+		MA35_MUX(0xf, "RMII0_PPS")),
+	MA35_PIN(183, PL13, 0xdc, 0x14,
+		MA35_MUX(0x0, "GPL13"),
+		MA35_MUX(0x1, "EPWM0_SYNC_OUT"),
+		MA35_MUX(0x2, "UART7_nRTS"),
+		MA35_MUX(0x3, "ECAP1_IC1"),
+		MA35_MUX(0x4, "UART14_TXD"),
+		MA35_MUX(0x5, "SPI0_CLK"),
+		MA35_MUX(0x6, "I2S1_BCLK"),
+		MA35_MUX(0x7, "SC1_DAT"),
+		MA35_MUX(0x8, "EBI_AD1"),
+		MA35_MUX(0x9, "HSUSBH_OVC"),
+		MA35_MUX(0xa, "I2C2_SCL"),
+		MA35_MUX(0xb, "TM0_EXT"),
+		MA35_MUX(0xc, "EPWM0_CH3"),
+		MA35_MUX(0xd, "EBI_AD12"),
+		MA35_MUX(0xe, "RGMII1_PPS"),
+		MA35_MUX(0xf, "RMII1_PPS")),
+	MA35_PIN(184, PL14, 0xdc, 0x18,
+		MA35_MUX(0x0, "GPL14"),
+		MA35_MUX(0x1, "EPWM0_CH2"),
+		MA35_MUX(0x2, "UART7_RXD"),
+		MA35_MUX(0x4, "CAN1_RXD"),
+		MA35_MUX(0x5, "SPI0_MOSI"),
+		MA35_MUX(0x6, "I2S1_DI"),
+		MA35_MUX(0x7, "SC1_RST"),
+		MA35_MUX(0x8, "EBI_AD2"),
+		MA35_MUX(0xb, "TM2"),
+		MA35_MUX(0xc, "INT0"),
+		MA35_MUX(0xd, "EBI_AD13")),
+	MA35_PIN(185, PL15, 0xdc, 0x1c,
+		MA35_MUX(0x0, "GPL15"),
+		MA35_MUX(0x1, "EPWM0_CH1"),
+		MA35_MUX(0x2, "UART7_TXD"),
+		MA35_MUX(0x3, "TRACE_CLK"),
+		MA35_MUX(0x4, "CAN1_TXD"),
+		MA35_MUX(0x5, "SPI0_MISO"),
+		MA35_MUX(0x6, "I2S1_DO"),
+		MA35_MUX(0x7, "SC1_PWR"),
+		MA35_MUX(0x8, "EBI_AD3"),
+		MA35_MUX(0xb, "TM2_EXT"),
+		MA35_MUX(0xc, "INT2"),
+		MA35_MUX(0xd, "EBI_AD14")),
+	MA35_PIN(186, PM0, 0xe0, 0x0,
+		MA35_MUX(0x0, "GPM0"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x6, "CCAP0_VSYNC"),
+		MA35_MUX(0x8, "EBI_AD3"),
+		MA35_MUX(0xa, "EBI_ADR3")),
+	MA35_PIN(187, PM1, 0xe0, 0x4,
+		MA35_MUX(0x0, "GPM1"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x5, "SPI3_I2SMCLK"),
+		MA35_MUX(0x6, "CCAP0_SFIELD"),
+		MA35_MUX(0x8, "EBI_AD4"),
+		MA35_MUX(0xa, "EBI_ADR4")),
+	MA35_PIN(188, PM2, 0xe0, 0x8,
+		MA35_MUX(0x0, "GPM2"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x6, "CCAP0_DATA0"),
+		MA35_MUX(0x8, "EBI_AD5"),
+		MA35_MUX(0xa, "EBI_ADR5")),
+	MA35_PIN(189, PM3, 0xe0, 0xc,
+		MA35_MUX(0x0, "GPM3"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x6, "CCAP0_DATA1"),
+		MA35_MUX(0x8, "EBI_AD6"),
+		MA35_MUX(0xa, "EBI_ADR6")),
+	MA35_PIN(190, PM4, 0xe0, 0x10,
+		MA35_MUX(0x0, "GPM4"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x6, "CCAP0_DATA2"),
+		MA35_MUX(0x8, "EBI_AD7"),
+		MA35_MUX(0xa, "EBI_ADR7")),
+	MA35_PIN(191, PM5, 0xe0, 0x14,
+		MA35_MUX(0x0, "GPM5"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x6, "CCAP0_DATA3"),
+		MA35_MUX(0x8, "EBI_AD8"),
+		MA35_MUX(0xa, "EBI_ADR8")),
+	MA35_PIN(192, PM6, 0xe0, 0x18,
+		MA35_MUX(0x0, "GPM6"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x6, "CCAP0_DATA4"),
+		MA35_MUX(0x8, "EBI_AD9"),
+		MA35_MUX(0xa, "EBI_ADR9")),
+	MA35_PIN(193, PM7, 0xe0, 0x1c,
+		MA35_MUX(0x0, "GPM7"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x6, "CCAP0_DATA5"),
+		MA35_MUX(0x8, "EBI_AD10"),
+		MA35_MUX(0xa, "EBI_ADR10")),
+	MA35_PIN(194, PM8, 0xe4, 0x0,
+		MA35_MUX(0x0, "GPM8"),
+		MA35_MUX(0x4, "I2C0_SDA"),
+		MA35_MUX(0x6, "CCAP0_DATA6"),
+		MA35_MUX(0x8, "EBI_AD11"),
+		MA35_MUX(0xa, "EBI_ADR11")),
+	MA35_PIN(195, PM9, 0xe4, 0x4,
+		MA35_MUX(0x0, "GPM9"),
+		MA35_MUX(0x4, "I2C0_SCL"),
+		MA35_MUX(0x6, "CCAP0_DATA7"),
+		MA35_MUX(0x8, "EBI_AD12"),
+		MA35_MUX(0xa, "EBI_ADR12")),
+	MA35_PIN(196, PM10, 0xe4, 0x8,
+		MA35_MUX(0x0, "GPM10"),
+		MA35_MUX(0x1, "EPWM1_CH2"),
+		MA35_MUX(0x3, "CAN2_RXD"),
+		MA35_MUX(0x5, "SPI3_SS0"),
+		MA35_MUX(0x6, "CCAP0_DATA8"),
+		MA35_MUX(0x7, "SPI2_I2SMCLK"),
+		MA35_MUX(0x8, "EBI_AD13"),
+		MA35_MUX(0xa, "EBI_ADR13")),
+	MA35_PIN(197, PM11, 0xe4, 0xc,
+		MA35_MUX(0x0, "GPM11"),
+		MA35_MUX(0x1, "EPWM1_CH3"),
+		MA35_MUX(0x3, "CAN2_TXD"),
+		MA35_MUX(0x5, "SPI3_SS1"),
+		MA35_MUX(0x6, "CCAP0_DATA9"),
+		MA35_MUX(0x7, "SPI2_SS1"),
+		MA35_MUX(0x8, "EBI_AD14"),
+		MA35_MUX(0xa, "EBI_ADR14")),
+	MA35_PIN(198, PM12, 0xe4, 0x10,
+		MA35_MUX(0x0, "GPM12"),
+		MA35_MUX(0x1, "EPWM1_CH4"),
+		MA35_MUX(0x2, "UART10_nCTS"),
+		MA35_MUX(0x3, "TRACE_DATA0"),
+		MA35_MUX(0x4, "UART11_RXD"),
+		MA35_MUX(0x5, "I2C2_SDA"),
+		MA35_MUX(0x7, "SC1_nCD"),
+		MA35_MUX(0x8, "EBI_AD8"),
+		MA35_MUX(0x9, "I2S1_MCLK"),
+		MA35_MUX(0xb, "TM8")),
+	MA35_PIN(199, PM13, 0xe4, 0x14,
+		MA35_MUX(0x0, "GPM13"),
+		MA35_MUX(0x1, "EPWM1_CH5"),
+		MA35_MUX(0x2, "UART10_nRTS"),
+		MA35_MUX(0x3, "TRACE_DATA1"),
+		MA35_MUX(0x4, "UART11_TXD"),
+		MA35_MUX(0x5, "I2C2_SCL"),
+		MA35_MUX(0x8, "EBI_AD9"),
+		MA35_MUX(0x9, "ECAP1_IC0"),
+		MA35_MUX(0xb, "TM8_EXT")),
+	MA35_PIN(200, PM14, 0xe4, 0x18,
+		MA35_MUX(0x0, "GPM14"),
+		MA35_MUX(0x1, "EPWM1_BRAKE0"),
+		MA35_MUX(0x2, "UART10_RXD"),
+		MA35_MUX(0x3, "TRACE_DATA2"),
+		MA35_MUX(0x4, "CAN2_RXD"),
+		MA35_MUX(0x6, "I2C3_SDA"),
+		MA35_MUX(0x8, "EBI_AD10"),
+		MA35_MUX(0x9, "ECAP1_IC1"),
+		MA35_MUX(0xb, "TM10"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(201, PM15, 0xe4, 0x1c,
+		MA35_MUX(0x0, "GPM15"),
+		MA35_MUX(0x1, "EPWM1_BRAKE1"),
+		MA35_MUX(0x2, "UART10_TXD"),
+		MA35_MUX(0x3, "TRACE_DATA3"),
+		MA35_MUX(0x4, "CAN2_TXD"),
+		MA35_MUX(0x6, "I2C3_SCL"),
+		MA35_MUX(0x8, "EBI_AD11"),
+		MA35_MUX(0x9, "ECAP1_IC2"),
+		MA35_MUX(0xb, "TM10_EXT"),
+		MA35_MUX(0xd, "INT2")),
+	MA35_PIN(202, PN0, 0xe8, 0x0,
+		MA35_MUX(0x0, "GPN0"),
+		MA35_MUX(0x4, "I2C2_SDA"),
+		MA35_MUX(0x6, "CCAP1_DATA0")),
+	MA35_PIN(203, PN1, 0xe8, 0x4,
+		MA35_MUX(0x0, "GPN1"),
+		MA35_MUX(0x4, "I2C2_SCL"),
+		MA35_MUX(0x6, "CCAP1_DATA1")),
+	MA35_PIN(204, PN2, 0xe8, 0x8,
+		MA35_MUX(0x0, "GPN2"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x6, "CCAP1_DATA2")),
+	MA35_PIN(205, PN3, 0xe8, 0xc,
+		MA35_MUX(0x0, "GPN3"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x6, "CCAP1_DATA3")),
+	MA35_PIN(206, PN4, 0xe8, 0x10,
+		MA35_MUX(0x0, "GPN4"),
+		MA35_MUX(0x4, "I2C1_SDA"),
+		MA35_MUX(0x6, "CCAP1_DATA4")),
+	MA35_PIN(207, PN5, 0xe8, 0x14,
+		MA35_MUX(0x0, "GPN5"),
+		MA35_MUX(0x4, "I2C1_SCL"),
+		MA35_MUX(0x6, "CCAP1_DATA5")),
+	MA35_PIN(208, PN6, 0xe8, 0x18,
+		MA35_MUX(0x0, "GPN6"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x6, "CCAP1_DATA6")),
+	MA35_PIN(209, PN7, 0xe8, 0x1c,
+		MA35_MUX(0x0, "GPN7"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x6, "CCAP1_DATA7")),
+	MA35_PIN(210, PN10, 0xec, 0x8,
+		MA35_MUX(0x0, "GPN10"),
+		MA35_MUX(0x3, "CAN2_RXD"),
+		MA35_MUX(0x6, "CCAP1_SCLK")),
+	MA35_PIN(211, PN11, 0xec, 0xc,
+		MA35_MUX(0x0, "GPN11"),
+		MA35_MUX(0x3, "CAN2_TXD"),
+		MA35_MUX(0x6, "CCAP1_PIXCLK")),
+	MA35_PIN(212, PN12, 0xec, 0x10,
+		MA35_MUX(0x0, "GPN12"),
+		MA35_MUX(0x2, "UART6_nCTS"),
+		MA35_MUX(0x3, "UART12_RXD"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x6, "CCAP1_HSYNC")),
+	MA35_PIN(213, PN13, 0xec, 0x14,
+		MA35_MUX(0x0, "GPN13"),
+		MA35_MUX(0x2, "UART6_nRTS"),
+		MA35_MUX(0x3, "UART12_TXD"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x6, "CCAP1_VSYNC")),
+	MA35_PIN(214, PN14, 0xec, 0x18,
+		MA35_MUX(0x0, "GPN14"),
+		MA35_MUX(0x2, "UART6_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "SPI1_SS1"),
+		MA35_MUX(0x6, "CCAP1_SFIELD"),
+		MA35_MUX(0x7, "SPI1_I2SMCLK")),
+	MA35_PIN(215, PN15, 0xec, 0x1c,
+		MA35_MUX(0x0, "GPN15"),
+		MA35_MUX(0x1, "EPWM2_CH4"),
+		MA35_MUX(0x2, "UART6_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "I2S0_MCLK"),
+		MA35_MUX(0x6, "SPI1_SS1"),
+		MA35_MUX(0x7, "SPI1_I2SMCLK"),
+		MA35_MUX(0x8, "SC0_nCD"),
+		MA35_MUX(0x9, "EADC0_ST"),
+		MA35_MUX(0xa, "CLKO"),
+		MA35_MUX(0xb, "TM6")),
+	MA35_PIN(216, PN8, 0xec, 0x0,
+		MA35_MUX(0x0, "GPN8"),
+		MA35_MUX(0x1, "EPWM2_CH4"),
+		MA35_MUX(0x4, "I2C0_SDA"),
+		MA35_MUX(0x5, "SPI2_I2SMCLK"),
+		MA35_MUX(0x6, "CCAP1_DATA8")),
+	MA35_PIN(217, PN9, 0xec, 0x4,
+		MA35_MUX(0x0, "GPN9"),
+		MA35_MUX(0x1, "EPWM2_CH5"),
+		MA35_MUX(0x4, "I2C0_SCL"),
+		MA35_MUX(0x5, "SPI1_I2SMCLK"),
+		MA35_MUX(0x6, "CCAP1_DATA9")),
+	MA35_PIN(218, PN10, 0xec, 0x8,
+		MA35_MUX(0x0, "GPN10"),
+		MA35_MUX(0x3, "CAN2_RXD"),
+		MA35_MUX(0x4, "USBHL2_DM"),
+		MA35_MUX(0x6, "CCAP1_SCLK")),
+	MA35_PIN(219, PN11, 0xec, 0xc,
+		MA35_MUX(0x0, "GPN11"),
+		MA35_MUX(0x3, "CAN2_TXD"),
+		MA35_MUX(0x4, "USBHL2_DP"),
+		MA35_MUX(0x6, "CCAP1_PIXCLK")),
+	MA35_PIN(220, PN12, 0xec, 0x10,
+		MA35_MUX(0x0, "GPN12"),
+		MA35_MUX(0x2, "UART6_nCTS"),
+		MA35_MUX(0x3, "UART12_RXD"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x6, "CCAP1_HSYNC")),
+	MA35_PIN(221, PN13, 0xec, 0x14,
+		MA35_MUX(0x0, "GPN13"),
+		MA35_MUX(0x2, "UART6_nRTS"),
+		MA35_MUX(0x3, "UART12_TXD"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x6, "CCAP1_VSYNC")),
+	MA35_PIN(222, PN14, 0xec, 0x18,
+		MA35_MUX(0x0, "GPN14"),
+		MA35_MUX(0x2, "UART6_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x4, "USBHL3_DM"),
+		MA35_MUX(0x5, "SPI1_SS1"),
+		MA35_MUX(0x6, "CCAP1_SFIELD"),
+		MA35_MUX(0x7, "SPI1_I2SMCLK")),
+	MA35_PIN(223, PN15, 0xec, 0x1c,
+		MA35_MUX(0x0, "GPN15"),
+		MA35_MUX(0x1, "EPWM2_CH4"),
+		MA35_MUX(0x2, "UART6_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x4, "USBHL3_DP"),
+		MA35_MUX(0x5, "I2S0_MCLK"),
+		MA35_MUX(0x6, "SPI1_SS1"),
+		MA35_MUX(0x7, "SPI1_I2SMCLK"),
+		MA35_MUX(0x8, "SC0_nCD"),
+		MA35_MUX(0x9, "EADC0_ST"),
+		MA35_MUX(0xa, "CLKO"),
+		MA35_MUX(0xb, "TM6")),
+};
+
+static int ma35d1_get_pin_num(int offset, int shift)
+{
+	return (offset - 0x80) * 2 + shift / 4;
+}
+
+static struct ma35_pinctrl_soc_info ma35d1_pinctrl_info = {
+	.pins = ma35d1_pins,
+	.npins = ARRAY_SIZE(ma35d1_pins),
+	.get_pin_num = ma35d1_get_pin_num,
+};
+
+static const struct dev_pm_ops ma35d1_pinctrl_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(ma35_pinctrl_suspend, ma35_pinctrl_resume)
+};
+
+static int ma35d1_pinctrl_probe(struct platform_device *pdev)
+{
+	return ma35_pinctrl_probe(pdev, &ma35d1_pinctrl_info);
+}
+
+static const struct of_device_id ma35d1_pinctrl_of_match[] = {
+	{ .compatible = "nuvoton,ma35d1-pinctrl", },
+	{ },
+};
+
+static struct platform_driver ma35d1_pinctrl_driver = {
+	.probe = ma35d1_pinctrl_probe,
+	.driver = {
+		.name = "ma35d1-pinctrl",
+		.pm = &ma35d1_pinctrl_pm_ops,
+		.of_match_table = ma35d1_pinctrl_of_match,
+	},
+};
+
+static int __init ma35d1_pinctrl_init(void)
+{
+	return platform_driver_register(&ma35d1_pinctrl_driver);
+}
+arch_initcall(ma35d1_pinctrl_init);
+
+MODULE_AUTHOR("schung at nuvoton.com");
+MODULE_DESCRIPTION("Nuvoton MA35D1 pinctrl driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From kuninori.morimoto.gx at renesas.com  Mon Feb  5 18:55:01 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Tue, 6 Feb 2024 02:55:01 +0000
Subject: [PATCH 1/4] gpu: drm: replace of_graph_get_next_endpoint()
In-Reply-To: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87sf26nvy2.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 drivers/gpu/drm/drm_of.c                              | 2 +-
 drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c | 2 +-
 drivers/gpu/drm/tiny/arcpgu.c                         | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 177b600895d3..c2eae9296012 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -516,7 +516,7 @@ struct mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev)
 	/*
 	 * Get first endpoint child from device.
 	 */
-	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!endpoint)
 		return ERR_PTR(-ENODEV);
 
diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
index 4618c892cdd6..e10e469aa7a6 100644
--- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
+++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
@@ -400,7 +400,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c)
 	rpi_touchscreen_i2c_write(ts, REG_POWERON, 0);
 
 	/* Look up the DSI host.  It needs to probe before we do. */
-	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!endpoint)
 		return -ENODEV;
 
diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c
index e5b10e41554a..04d0053b9315 100644
--- a/drivers/gpu/drm/tiny/arcpgu.c
+++ b/drivers/gpu/drm/tiny/arcpgu.c
@@ -288,7 +288,7 @@ static int arcpgu_load(struct arcpgu_drm_private *arcpgu)
 	 * There is only one output port inside each device. It is linked with
 	 * encoder endpoint.
 	 */
-	endpoint_node = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
+	endpoint_node = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 0, -1);
 	if (endpoint_node) {
 		encoder_node = of_graph_get_remote_port_parent(endpoint_node);
 		of_node_put(endpoint_node);
-- 
2.25.1



From kuninori.morimoto.gx at renesas.com  Mon Feb  5 18:55:27 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Tue, 6 Feb 2024 02:55:27 +0000
Subject: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87r0hqnvxc.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 drivers/media/i2c/adv7343.c              | 2 +-
 drivers/media/i2c/adv7604.c              | 2 +-
 drivers/media/i2c/mt9p031.c              | 2 +-
 drivers/media/i2c/mt9v032.c              | 2 +-
 drivers/media/i2c/ov2659.c               | 2 +-
 drivers/media/i2c/ov5645.c               | 2 +-
 drivers/media/i2c/ov5647.c               | 2 +-
 drivers/media/i2c/s5c73m3/s5c73m3-core.c | 2 +-
 drivers/media/i2c/s5k5baf.c              | 2 +-
 drivers/media/i2c/tc358743.c             | 2 +-
 drivers/media/i2c/tda1997x.c             | 2 +-
 drivers/media/i2c/tvp514x.c              | 2 +-
 drivers/media/i2c/tvp7002.c              | 2 +-
 13 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index ff21cd4744d3..4fbe4e18570e 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -403,7 +403,7 @@ adv7343_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index b202a85fbeaa..dcfdbb975473 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -3205,7 +3205,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
 	np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
 
 	/* Parse the endpoint. */
-	endpoint = of_graph_get_next_endpoint(np, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!endpoint)
 		return -EINVAL;
 
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 348f1e1098fb..c57a0d436421 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -1080,7 +1080,7 @@ mt9p031_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 1c6f6cea1204..14d277680fa2 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -1008,7 +1008,7 @@ mt9v032_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 2c3dbe164eb6..edea62a02320 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1388,7 +1388,7 @@ ov2659_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!endpoint)
 		return NULL;
 
diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
index a70db7e601a4..31d214bd4a83 100644
--- a/drivers/media/i2c/ov5645.c
+++ b/drivers/media/i2c/ov5645.c
@@ -1053,7 +1053,7 @@ static int ov5645_probe(struct i2c_client *client)
 	ov5645->i2c_client = client;
 	ov5645->dev = dev;
 
-	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!endpoint) {
 		dev_err(dev, "endpoint node not found\n");
 		return -EINVAL;
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index dcfe3129c63a..beab2813c672 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -1363,7 +1363,7 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
 	struct device_node *ep;
 	int ret;
 
-	ep = of_graph_get_next_endpoint(np, NULL);
+	ep = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!ep)
 		return -EINVAL;
 
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index ed5b10731a14..aaec5f64f31a 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1555,7 +1555,7 @@ static int s5c73m3_get_dt_data(struct s5c73m3 *state)
 				     "failed to request gpio S5C73M3_RST\n");
 	gpiod_set_consumer_name(state->reset, "S5C73M3_RST");
 
-	node_ep = of_graph_get_next_endpoint(node, NULL);
+	node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!node_ep) {
 		dev_warn(dev, "no endpoint defined for node: %pOF\n", node);
 		return 0;
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 67da2045f543..af7e49e6cc5b 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1836,7 +1836,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
 			 state->mclk_frequency);
 	}
 
-	node_ep = of_graph_get_next_endpoint(node, NULL);
+	node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!node_ep) {
 		dev_err(dev, "no endpoint defined at node %pOF\n", node);
 		return -EINVAL;
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 2785935da497..872e802cdfbe 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1895,7 +1895,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
 		return dev_err_probe(dev, PTR_ERR(refclk),
 				     "failed to get refclk\n");
 
-	ep = of_graph_get_next_endpoint(dev->of_node, NULL);
+	ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!ep) {
 		dev_err(dev, "missing endpoint node\n");
 		return -EINVAL;
diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
index 325e99125941..662efd5e69b9 100644
--- a/drivers/media/i2c/tda1997x.c
+++ b/drivers/media/i2c/tda1997x.c
@@ -2307,7 +2307,7 @@ static int tda1997x_parse_dt(struct tda1997x_state *state)
 	pdata->vidout_sel_de = DE_FREF_SEL_DE_VHREF;
 
 	np = state->client->dev.of_node;
-	ep = of_graph_get_next_endpoint(np, NULL);
+	ep = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!ep)
 		return -EINVAL;
 
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index c37f605cb75f..b1630a6c396b 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -988,7 +988,7 @@ tvp514x_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!endpoint)
 		return NULL;
 
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index a2d7bc799849..8e58ce400df2 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -893,7 +893,7 @@ tvp7002_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!endpoint)
 		return NULL;
 
-- 
2.25.1



From kuninori.morimoto.gx at renesas.com  Mon Feb  5 18:55:38 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Tue, 6 Feb 2024 02:55:38 +0000
Subject: [PATCH 3/4] media: platform: replace of_graph_get_next_endpoint()
In-Reply-To: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87plxanvx1.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 drivers/media/platform/atmel/atmel-isi.c              | 4 ++--
 drivers/media/platform/intel/pxa_camera.c             | 2 +-
 drivers/media/platform/samsung/exynos4-is/fimc-is.c   | 2 +-
 drivers/media/platform/samsung/exynos4-is/mipi-csis.c | 2 +-
 drivers/media/platform/st/stm32/stm32-dcmi.c          | 4 ++--
 drivers/media/platform/ti/davinci/vpif.c              | 3 +--
 6 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index 4046212d48b4..f615aee85968 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -831,7 +831,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
 	isi->pdata.full_mode = 1;
 	isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
 
-	np = of_graph_get_next_endpoint(np, NULL);
+	np = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!np) {
 		dev_err(&pdev->dev, "Could not find the endpoint\n");
 		return -EINVAL;
@@ -1155,7 +1155,7 @@ static int isi_graph_init(struct atmel_isi *isi)
 	struct device_node *ep;
 	int ret;
 
-	ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
+	ep = of_graph_get_endpoint_by_regs(isi->dev->of_node, 0, -1);
 	if (!ep)
 		return -EINVAL;
 
diff --git a/drivers/media/platform/intel/pxa_camera.c b/drivers/media/platform/intel/pxa_camera.c
index 59b89e421dc2..d904952bf00e 100644
--- a/drivers/media/platform/intel/pxa_camera.c
+++ b/drivers/media/platform/intel/pxa_camera.c
@@ -2207,7 +2207,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
 		pcdev->mclk = mclk_rate;
 	}
 
-	np = of_graph_get_next_endpoint(np, NULL);
+	np = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!np) {
 		dev_err(dev, "could not find endpoint\n");
 		return -EINVAL;
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
index a08c87ef6e2d..39aab667910d 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
@@ -175,7 +175,7 @@ static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,
 		return -EINVAL;
 	}
 
-	ep = of_graph_get_next_endpoint(node, NULL);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return -ENXIO;
 
diff --git a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
index 686ca8753ba2..3f8bea2e3934 100644
--- a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
@@ -728,7 +728,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
 				 &state->max_num_lanes))
 		return -EINVAL;
 
-	node = of_graph_get_next_endpoint(node, NULL);
+	node = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!node) {
 		dev_err(&pdev->dev, "No port node at %pOF\n",
 				pdev->dev.of_node);
diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c
index 8cb4fdcae137..4c00aae013af 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmi.c
@@ -1856,7 +1856,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi)
 	struct device_node *ep;
 	int ret;
 
-	ep = of_graph_get_next_endpoint(dcmi->dev->of_node, NULL);
+	ep = of_graph_get_endpoint_by_regs(dcmi->dev->of_node, 0, -1);
 	if (!ep) {
 		dev_err(dcmi->dev, "Failed to get next endpoint\n");
 		return -EINVAL;
@@ -1915,7 +1915,7 @@ static int dcmi_probe(struct platform_device *pdev)
 				     "Could not get reset control\n");
 
 	/* Get bus characteristics from devicetree */
-	np = of_graph_get_next_endpoint(np, NULL);
+	np = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!np) {
 		dev_err(&pdev->dev, "Could not find the endpoint\n");
 		return -ENODEV;
diff --git a/drivers/media/platform/ti/davinci/vpif.c b/drivers/media/platform/ti/davinci/vpif.c
index 63cdfed37bc9..f4e1fa76bf37 100644
--- a/drivers/media/platform/ti/davinci/vpif.c
+++ b/drivers/media/platform/ti/davinci/vpif.c
@@ -465,8 +465,7 @@ static int vpif_probe(struct platform_device *pdev)
 	 * so their devices need to be registered manually here
 	 * for their legacy platform_drivers to work.
 	 */
-	endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
-					      endpoint);
+	endpoint = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 0, -1);
 	if (!endpoint)
 		return 0;
 	of_node_put(endpoint);
-- 
2.25.1



From kuninori.morimoto.gx at renesas.com  Mon Feb  5 18:55:45 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Tue, 6 Feb 2024 02:55:45 +0000
Subject: [PATCH 4/4] video: fbdev: replace of_graph_get_next_endpoint()
In-Reply-To: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87o7cunvwv.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 drivers/video/fbdev/amba-clcd.c               |  2 +-
 drivers/video/fbdev/omap2/omapfb/dss/dsi.c    |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/dss-of.c | 20 +------------------
 drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c  |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c  |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/venc.c   |  3 ++-
 drivers/video/fbdev/pxafb.c                   |  2 +-
 include/video/omapfb_dss.h                    |  3 ---
 8 files changed, 11 insertions(+), 28 deletions(-)

diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
index 0399db369e70..2371b204cfd2 100644
--- a/drivers/video/fbdev/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
@@ -691,7 +691,7 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
 	/*
 	 * Fetch the panel endpoint.
 	 */
-	endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(fb->dev->dev.of_node, 0, -1);
 	if (!endpoint)
 		return -ENODEV;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
index b7eb17a16ec4..1f13bcf73da5 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
@@ -28,6 +28,7 @@
 #include <linux/debugfs.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/of_platform.h>
 #include <linux/component.h>
 
@@ -5079,7 +5080,7 @@ static int dsi_probe_of(struct platform_device *pdev)
 	struct device_node *ep;
 	struct omap_dsi_pin_config pin_cfg;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
index 0282d4eef139..14965a3fd05b 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
@@ -130,24 +130,6 @@ static struct device_node *omapdss_of_get_remote_port(const struct device_node *
 	return np;
 }
 
-struct device_node *
-omapdss_of_get_first_endpoint(const struct device_node *parent)
-{
-	struct device_node *port, *ep;
-
-	port = omapdss_of_get_next_port(parent, NULL);
-
-	if (!port)
-		return NULL;
-
-	ep = omapdss_of_get_next_endpoint(port, NULL);
-
-	of_node_put(port);
-
-	return ep;
-}
-EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint);
-
 struct omap_dss_device *
 omapdss_of_find_source_for_first_ep(struct device_node *node)
 {
@@ -155,7 +137,7 @@ omapdss_of_find_source_for_first_ep(struct device_node *node)
 	struct device_node *src_port;
 	struct omap_dss_device *src;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return ERR_PTR(-EINVAL);
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
index f05b4e35a842..8f407ec134dc 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
@@ -20,6 +20,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/regulator/consumer.h>
 #include <linux/component.h>
 #include <video/omapfb_dss.h>
@@ -529,7 +530,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
 	struct device_node *ep;
 	int r;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
index 03292945b1d4..4ad219f522b9 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
@@ -25,6 +25,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/regulator/consumer.h>
 #include <linux/component.h>
 #include <video/omapfb_dss.h>
@@ -561,7 +562,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
 	struct device_node *ep;
 	int r;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/venc.c b/drivers/video/fbdev/omap2/omapfb/dss/venc.c
index c9d40e28a06f..0bd80d3b8f1b 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/venc.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/venc.c
@@ -24,6 +24,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/component.h>
 
 #include <video/omapfb_dss.h>
@@ -764,7 +765,7 @@ static int venc_probe_of(struct platform_device *pdev)
 	u32 channels;
 	int r;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
index fa943612c4e2..2ef56fa28aff 100644
--- a/drivers/video/fbdev/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
@@ -2171,7 +2171,7 @@ static int of_get_pxafb_mode_info(struct device *dev,
 	u32 bus_width;
 	int ret, i;
 
-	np = of_graph_get_next_endpoint(dev->of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!np) {
 		dev_err(dev, "could not find endpoint\n");
 		return -EINVAL;
diff --git a/include/video/omapfb_dss.h b/include/video/omapfb_dss.h
index e8eaac2cb7b8..a8c0c3eeeb5b 100644
--- a/include/video/omapfb_dss.h
+++ b/include/video/omapfb_dss.h
@@ -819,9 +819,6 @@ struct device_node *
 omapdss_of_get_next_endpoint(const struct device_node *parent,
 			     struct device_node *prev);
 
-struct device_node *
-omapdss_of_get_first_endpoint(const struct device_node *parent);
-
 struct omap_dss_device *
 omapdss_of_find_source_for_first_ep(struct device_node *node);
 #else
-- 
2.25.1



From dinguyen at kernel.org  Mon Feb  5 19:11:03 2024
From: dinguyen at kernel.org (Dinh Nguyen)
Date: Mon, 5 Feb 2024 21:11:03 -0600
Subject: [PATCH 3/3] arm64: dts: intel: agilex5: drop "master" I3C node
 name suffix
In-Reply-To: <20240117075618.81932-3-krzysztof.kozlowski@linaro.org>
References: <20240117075618.81932-1-krzysztof.kozlowski@linaro.org>
 <20240117075618.81932-3-krzysztof.kozlowski@linaro.org>
Message-ID: <f3ae2e5a-1850-461f-aa9c-2c7bceac8318@kernel.org>

On 1/17/24 01:56, Krzysztof Kozlowski wrote:
> Following change in the I3C bindings, the "master" suffix in I3C
> controller node name is discouraged (it is "controller" now) and not
> accurate (if device supports also target mode).
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> ---
> 
> The change can be applied through independent trees, if the I3C bindings
> change is applied.  Therefore please take it once I3C bindings is
> applied.
> ---
>   arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 

Applied.

Thanks,
Dinh



From aford173 at gmail.com  Mon Feb  5 19:39:04 2024
From: aford173 at gmail.com (Adam Ford)
Date: Mon, 5 Feb 2024 21:39:04 -0600
Subject: [PATCH V8 02/12] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240205081719.z2uqa4dwn5ucsymv@pengutronix.de>
References: <20240203165307.7806-1-aford173@gmail.com> <20240203165307.7806-3-aford173@gmail.com>
 <CAA8EJpo4omXogg48urEMzxQ+CA7DNTSf66pA6hoO8wpmtn_-MQ@mail.gmail.com> <20240205081719.z2uqa4dwn5ucsymv@pengutronix.de>
Message-ID: <CAHCN7x+9pLZZhypgVh8Q3jAxeM6UKJrPCOdjVoszK3XLTh=gBQ@mail.gmail.com>

On Mon, Feb 5, 2024 at 2:17?AM Marco Felsch <m.felsch at pengutronix.de> wrote:
>
> On 24-02-04, Dmitry Baryshkov wrote:
> > On Sat, 3 Feb 2024 at 17:53, Adam Ford <aford173 at gmail.com> wrote:
> > >
> > > From: Lucas Stach <l.stach at pengutronix.de>
> > >
> > > This adds the driver for the Samsung HDMI PHY found on the
> > > i.MX8MP SoC.
> > >
> > > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > > Signed-off-by: Adam Ford <aford173 at gmail.com>
> > > Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > > ---
> > > V4:  Make lookup table hex values lower case.
> > >
> > > V3:  Re-order the Makefile to keep it alphabetical
> > >      Remove unused defines
> > >
> > > V2:  Fixed some whitespace found from checkpatch
> > >      Change error handling when enabling apbclk to use dev_err_probe
> > >      Rebase on Linux-Next
> > >
> > >      I (Adam) tried to help move this along, so I took Lucas' patch and
> > >      attempted to apply fixes based on feedback.  I don't have
> > >      all the history, so apologies for that.
> > > ---
> > >  drivers/phy/freescale/Kconfig                |    6 +
> > >  drivers/phy/freescale/Makefile               |    1 +
> > >  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 1075 ++++++++++++++++++
> > >  3 files changed, 1082 insertions(+)
> > >  create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > >
> > > diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> > > index 853958fb2c06..5c2b73042dfc 100644
> > > --- a/drivers/phy/freescale/Kconfig
> > > +++ b/drivers/phy/freescale/Kconfig
> > > @@ -35,6 +35,12 @@ config PHY_FSL_IMX8M_PCIE
> > >           Enable this to add support for the PCIE PHY as found on
> > >           i.MX8M family of SOCs.
> > >
> > > +config PHY_FSL_SAMSUNG_HDMI_PHY
> > > +       tristate "Samsung HDMI PHY support"
> > > +       depends on OF && HAS_IOMEM
> > > +       help
> > > +         Enable this to add support for the Samsung HDMI PHY in i.MX8MP.
> > > +
> > >  endif
> > >
> > >  config PHY_FSL_LYNX_28G
> > > diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
> > > index cedb328bc4d2..79e5f16d3ce8 100644
> > > --- a/drivers/phy/freescale/Makefile
> > > +++ b/drivers/phy/freescale/Makefile
> > > @@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)        += phy-fsl-imx8qm-lvds-phy.o
> > >  obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)      += phy-fsl-imx8-mipi-dphy.o
> > >  obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)       += phy-fsl-imx8m-pcie.o
> > >  obj-$(CONFIG_PHY_FSL_LYNX_28G)         += phy-fsl-lynx-28g.o
> > > +obj-$(CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY)  += phy-fsl-samsung-hdmi.o
> > > diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > > new file mode 100644
> > > index 000000000000..bf0e2299d00f
> > > --- /dev/null
> > > +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> > > @@ -0,0 +1,1075 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/*
> > > + * Copyright 2020 NXP
> > > + * Copyright 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
> > > + */
> > > +
> > > +#include <linux/clk-provider.h>
> > > +#include <linux/clk.h>
> > > +#include <linux/delay.h>
> > > +#include <linux/io.h>
> > > +#include <linux/iopoll.h>
> > > +#include <linux/module.h>
> > > +#include <linux/of_device.h>
> > > +#include <linux/of.h>
> > > +#include <linux/platform_device.h>
> > > +#include <linux/pm_runtime.h>
> > > +
> > > +#define PHY_REG_33             0x84
> > > +#define  REG33_MODE_SET_DONE   BIT(7)
> > > +#define  REG33_FIX_DA          BIT(1)
> > > +
> > > +#define PHY_REG_34             0x88
> > > +#define  REG34_PHY_READY       BIT(7)
> > > +#define  REG34_PLL_LOCK                BIT(6)
> > > +#define  REG34_PHY_CLK_READY   BIT(5)
> > > +
> > > +
> > > +#define PHY_PLL_REGS_NUM 48
> > > +
> > > +struct phy_config {
> > > +       u32     clk_rate;
> > > +       u8 regs[PHY_PLL_REGS_NUM];
> > > +};
> > > +
> > > +const struct phy_config phy_pll_cfg[] = {
> > > +       {       22250000, {
> > > +                       0x00, 0xd1, 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40,
> > > +                       0x4f, 0x30, 0x33, 0x65, 0x00, 0x15, 0x25, 0x80,
> > > +                       0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
> > > +                       0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
> > > +                       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +                       0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
> > > +               },
> > > +       }, {
> > > +               23750000, {
> > > +                       0x00, 0xd1, 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40,
> > > +                       0x4f, 0x30, 0x33, 0x65, 0x00, 0x03, 0x25, 0x80,
> > > +                       0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
> > > +                       0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
> > > +                       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +                       0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
> > > +               },
> >
> > Generally I see that these entries contain a high level of duplication.
> > Could you please extract the common part and a rate-dependent part.
> > Next, it would be best if instead of writing the register values via
> > the rate LUT, the driver could calculate those values.
> > This allows us to support other HDMI modes if the need arises at some point.
>
> Hi Adam,
>
> can you please have a look at: https://lore.kernel.org/all/4830698.GXAFRqVoOG at steina-w/
>
> there we have fixed this already. Not sure which version you picked for
> your work.

It must have been an earlier version.  I got the list from Fabio, but
I might have also gotten it mixed up.  I'll look at this version and
base my series on it and try to address comments others made.  It'll
likely take me a few days to catch up.

thanks for the pointer.

adam
>
> Regards,
>   Marco
>
> >
> > > +       }, {
> > > +               24000000, {
> > > +                       0x00, 0xd1, 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00,
> > > +                       0x4f, 0x30, 0x33, 0x65, 0x00, 0x01, 0x25, 0x80,
> > > +                       0x6c, 0xf2, 0x67, 0x00, 0x10, 0x8f, 0x30, 0x32,
> > > +                       0x60, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
> > > +                       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +                       0x00, 0xe0, 0x83, 0x0f, 0x3e, 0xf8, 0x00, 0x00,
> > > +               },
> >
> >
> > --
> > With best wishes
> > Dmitry
> >
> >


From tzungbi at kernel.org  Mon Feb  5 19:54:12 2024
From: tzungbi at kernel.org (Tzung-Bi Shih)
Date: Tue, 6 Feb 2024 11:54:12 +0800
Subject: [PATCH v3 1/4] firmware: coreboot: Generate modalias uevent for
 devices
In-Reply-To: <2a2736e5-8788-4643-8d19-a79b9a9ec776@notapiano>
References: <20240117-coreboot-mod-defconfig-v3-0-049565a27bba@collabora.com>
 <20240117-coreboot-mod-defconfig-v3-1-049565a27bba@collabora.com>
 <ZcA72dyYd9ZR8k_J@google.com>
 <2a2736e5-8788-4643-8d19-a79b9a9ec776@notapiano>
Message-ID: <ZcGtZHV9EB8UsNXc@google.com>

On Mon, Feb 05, 2024 at 09:13:51AM -0500, N?colas F. R. A. Prado wrote:
> On Mon, Feb 05, 2024 at 09:37:29AM +0800, Tzung-Bi Shih wrote:
> > On Wed, Jan 17, 2024 at 04:03:22PM -0300, N?colas F. R. A. Prado wrote:
> > > Generate a modalias uevent for devices in the coreboot bus to allow
> > > userspace to automatically load the corresponding modules.
> > >
> > > [...]
> > 
> > Applied, thanks!
> > 
> > [1/4] firmware: coreboot: Generate modalias uevent for devices
> >       commit: c6b0a4ceb7c9d8bb014d2967c97c8c7cbf60b006
> 
> Hi Tzung-Bi,
> 
> I was going to send a v4 with tag changed into 64 bit long as suggested by Greg:
> https://lore.kernel.org/all/2024020105-dash-antiquity-a56b at gregkh
> 
> And that includes this commit, as the modalias field would need to be 16 hex
> long.
> 
> But since you already merged this, would you prefer a change on top of this
> making it 64 bit long, or do you want to keep it 32 bits?

Oops, I overlooked `u32` in the patch thus I thought the patch is indepedent.
Please go ahead to send v4 with 64 bit long tag.  I will drop
c6b0a4ceb7c9d8bb014d2967c97c8c7cbf60b006 from the queue.


From vigneshr at ti.com  Mon Feb  5 20:29:10 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 09:59:10 +0530
Subject: [PATCH 0/2] Set boot tags for the usb0 port of AM62x SK and Beagleplay
In-Reply-To: <20240112091745.1896922-1-sjoerd@collabora.com>
References: <20240112091745.1896922-1-sjoerd@collabora.com>
Message-ID: <170719349980.2245010.13978940073133357464.b4-ty@ti.com>

Hi Sjoerd Simons,

On Fri, 12 Jan 2024 10:17:06 +0100, Sjoerd Simons wrote:
> The AM62x SoC can be booted from the first USB port using DFU. Set the
> relevant boot tags for both
> 
> 
> Sjoerd Simons (2):
>   arm64: dts: ti: k3-am625-sk: Add boot phase tags for USB0
>   arm64: dts: ti: k3-am625-beagleplay: Add boot phase tags for USB0
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/2] arm64: dts: ti: k3-am625-sk: Add boot phase tags for USB0
      commit: 524c8086a453b8df1002c1ccfa9f99589761fc80
[2/2] arm64: dts: ti: k3-am625-beagleplay: Add boot phase tags for USB0
      commit: f7d2844d848f8836e6a7923e3ea426f7be4f38d1

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb  5 20:29:59 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 09:59:59 +0530
Subject: [PATCH] arm64: dts: ti: k3-am625-beagleplay: Use the builtin mdio bus
In-Reply-To: <20240112124505.2054212-1-sjoerd@collabora.com>
References: <20240112124505.2054212-1-sjoerd@collabora.com>
Message-ID: <170719349980.2245010.17097111330669476352.b4-ty@ti.com>

Hi Sjoerd Simons,

On Fri, 12 Jan 2024 13:44:55 +0100, Sjoerd Simons wrote:
> The beagleplay dts was using a bit-bang gpio mdio bus as a work-around
> for errata i2329. However since commit d04807b80691 ("net: ethernet: ti:
> davinci_mdio: Add workaround for errata i2329") the mdio driver itself
> already takes care of this errata for effected silicon, which landed
> well before the beagleplay dts. So i suspect the reason for the
> workaround in upstream was simply due to copying the vendor dts.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: k3-am625-beagleplay: Use the builtin mdio bus
      commit: 3c3f2d13d3c8e748ebdebfc6d8a72024240227e9

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb  5 20:32:02 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 10:02:02 +0530
Subject: [PATCH] arm64: dts: ti: Disable clock output of the ethernet PHY
In-Reply-To: <20240119225257.403222-1-nmorrisson@phytec.com>
References: <20240119225257.403222-1-nmorrisson@phytec.com>
Message-ID: <170719349981.2245010.3205058653973869263.b4-ty@ti.com>

Hi Nathan Morrisson,

On Fri, 19 Jan 2024 14:52:57 -0800, Nathan Morrisson wrote:
> The clock on the ethernet1 PHY is turned on by default. This turns
> the clock off as we do not use it.
> 
> 

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: Disable clock output of the ethernet PHY
      commit: f4ee6882ef25959f14c61aa76515fe301fa45a99

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb  5 20:32:03 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 10:02:03 +0530
Subject: [PATCH] arm64: dts: ti: phycore-am64: Add ADC
In-Reply-To: <20240201001439.3259450-1-nmorrisson@phytec.com>
References: <20240201001439.3259450-1-nmorrisson@phytec.com>
Message-ID: <170719349984.2245010.9672098246589016677.b4-ty@ti.com>

Hi Nathan Morrisson,

On Wed, 31 Jan 2024 16:14:39 -0800, Nathan Morrisson wrote:
> Add the ADC node to the phyCORE AM64x and enable the ADC.
> 
> 

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: phycore-am64: Add ADC
      commit: 61fc6b43f0e321e265164701d3bf65a2e5157720

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb  5 20:33:33 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 10:03:33 +0530
Subject: [PATCH 01/11] arm64: dts: ti: k3-am642-evm: Do not split single items
In-Reply-To: <20240123222536.875797-1-afd@ti.com>
References: <20240123222536.875797-1-afd@ti.com>
Message-ID: <170719349982.2245010.4501898536246619202.b4-ty@ti.com>

Hi Andrew Davis,

On Tue, 23 Jan 2024 16:25:26 -0600, Andrew Davis wrote:
> Each "mboxes" item is composed of two cells. It seems these got split
> as they appeared to be two items in an array, but are actually a single
> two-cell item. Rejoin these cells.
> 
> 

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[01/11] arm64: dts: ti: k3-am642-evm: Do not split single items
        commit: ba076778dd70f0011aeb2c9847abce937b52c3f6
[02/11] arm64: dts: ti: k3-am642-sk: Do not split single items
        commit: 3c25149bb61e483b4cf04473768a3a24f57c04fc
[03/11] arm64: dts: ti: iot2050: Do not split single items
        commit: 966459a6994bf7b16a330635b2c2ff9f00437b31
[04/11] arm64: dts: ti: k3-am654-base-board: Do not split single items
        commit: 6d1ffc18d68f82f82899f2f2d9aca65657828a96
[05/11] arm64: dts: ti: k3-am68-sk-som: Do not split single items
        commit: 48159cb78e3c540b592031e1db5a6c9eed853621
[06/11] arm64: dts: ti: k3-am69-sk: Do not split single items
        commit: 2b8e6fac6bb254f70dfcefce01deada89251ae99
[07/11] arm64: dts: ti: k3-j7200-som-p0: Do not split single items
        commit: ff61b8cbafdcc9a0be0a45758769a54b3d9f2042
[08/11] arm64: dts: ti: k3-j721e-beagleboneai64: Do not split single items
        commit: 3ff119bb1cb1e3a81bf620125a3bd74821464804
[09/11] arm64: dts: ti: k3-j721e-sk: Do not split single items
        commit: 90ca6810778865ae7b3ac33229f72f542dc7830d
[10/11] arm64: dts: ti: k3-j721e-som-p0: Do not split single items
        commit: 9fedf76ac33b2a169eaa64d235f5b433c575ebb3
[11/11] arm64: dts: ti: k3-j721s2-som-p0: Do not split single items
        commit: b1898456a4307097c47a340f4a9327a125f75a43

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb  5 20:41:25 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 10:11:25 +0530
Subject: [PATCH 1/4] arm64: dts: ti: k3-j7200: Enable PCIe nodes at the board level
In-Reply-To: <20240124183659.149119-1-afd@ti.com>
References: <20240124183659.149119-1-afd@ti.com>
Message-ID: <170719349982.2245010.16848121374381229501.b4-ty@ti.com>

Hi Andrew Davis,

On Wed, 24 Jan 2024 12:36:56 -0600, Andrew Davis wrote:
> PCIe node defined in the top-level J7200 SoC dtsi file is incomplete
> and will not be functional unless it is extended with a SerDes PHY.
> 
> As the PHY and mode is only known at the board integration level, this
> node should only be enabled when provided with this information.
> 
> Disable the PCIe node in the dtsi files and only enable when it is
> actually pinned out on a given board.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/4] arm64: dts: ti: k3-j7200: Enable PCIe nodes at the board level
      commit: 1b63a1b480c27764d30a0924a4982d31e15df6fd
[2/4] arm64: dts: ti: k3-j7200: Remove PCIe endpoint node
      commit: 0b16abe711bd5136f2319c4f548fb20588540266
[3/4] arm64: dts: ti: k3-am65: Remove PCIe endpoint nodes
      commit: e074d9d9a52eec11cd8b3f98e2576b0c762686f1
[4/4] arm64: dts: ti: k3-am64: Remove PCIe endpoint node
      commit: 6cce60550763564360beadf57ecf2e4d45b585e1

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From s-vadapalli at ti.com  Mon Feb  5 20:42:12 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Tue, 6 Feb 2024 10:12:12 +0530
Subject: [PATCH 0/3] Add PCIe DT support for TI's J784S4 SoC
In-Reply-To: <ffeb1902-332c-445b-a16a-7fc293cad2eb@ti.com>
References: <20240129114749.1197579-1-s-vadapalli@ti.com>
 <ffeb1902-332c-445b-a16a-7fc293cad2eb@ti.com>
Message-ID: <a1957347-7c23-42bb-9c62-e1276dd23c53@ti.com>



On 05/02/24 20:05, Vignesh Raghavendra wrote:
> 
> 
> On 29/01/24 17:17, Siddharth Vadapalli wrote:
>> Hello,
>>
>> TI's J784S4 SoC has two Gen3 x4 Lane PCIe Controllers. This series adds
>> the necessary device-tree support to enable both PCIe instances in Root
>> Complex mode of operation by default. The device-tree overlay to enable
>> both instances in Endpoint mode of operation is also present in this
>> series.
>>
>> **NOTE**
>> This series depends on:
>> 1. https://patchwork.kernel.org/project/linux-arm-kernel/patch/20240124122936.816142-1-s-vadapalli at ti.com/
>>    for adding the Device ID in the bindings for J784S4 SoC.
>>
>> 2. https://patchwork.kernel.org/project/linux-arm-kernel/patch/20240129104958.1139787-1-s-vadapalli at ti.com/
>>    for enabling support for configuring the PCIe mode of operation,
>>    number of lanes and link speed when the System Controller node
>>    in the device-tree is modelled as a "simple-bus" which happens to
>>    be the case for J784S4 SoC:
>>    https://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi#L45
>>
>> 3. https://patchwork.kernel.org/project/linux-arm-kernel/patch/20240125100501.4137977-2-c-vankar at ti.com/
>>    for fixing the "serdes_ln_ctrl" node in order to ensure that the PCIe
>>    lanes are mapped correctly to the corresponding Serdes Lanes.
> 
> Sorry, too many dependencies for me to keep track of. I am ignoring  the
>  series, please resubmit once dependencies are resolved.

Sure Vignesh. I will post the v2 series once the dependencies are met.

-- 
Regards,
Siddharth.


From vigneshr at ti.com  Mon Feb  5 20:42:05 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 10:12:05 +0530
Subject: [PATCH v1] arm64: dts: ti: verdin-am62: mallow: add TPM device
In-Reply-To: <20240126165136.28543-1-francesco@dolcini.it>
References: <20240126165136.28543-1-francesco@dolcini.it>
Message-ID: <170719349982.2245010.4000049121495842797.b4-ty@ti.com>

Hi Francesco Dolcini,

On Fri, 26 Jan 2024 17:51:36 +0100, Francesco Dolcini wrote:
> Add TPM device to Mallow device tree file, the device is connected to
> the SoC with SPI1/CS1, the same SPI interface is also available on an
> extension header together with an additional CS0 signal.
> 
> 

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: verdin-am62: mallow: add TPM device
      commit: e55b0bf4c2b31cc0b202b375796f96b2b9af2e6a

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb  5 20:42:28 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 10:12:28 +0530
Subject: [PATCH] arm64: dts: ti: k3-am642-phyboard-electra: Add TPM support
In-Reply-To: <20240123102921.1348777-1-w.egorov@phytec.de>
References: <20240123102921.1348777-1-w.egorov@phytec.de>
Message-ID: <170719349981.2245010.3337630647469226018.b4-ty@ti.com>

Hi Wadim Egorov,

On Tue, 23 Jan 2024 11:29:21 +0100, Wadim Egorov wrote:
> The phyBOARD-Electra populates a TPM module on SPI0 bus.
> Add support for the Infineon SLB9670 TPM module.
> 
> 

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: k3-am642-phyboard-electra: Add TPM support
      commit: 742b9732e88a0b0d24a4cffd8aaa343a2aee6683

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb  5 20:43:03 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 10:13:03 +0530
Subject: (subset)[PATCH 0/3] pinctrl: pinctrl-single: fix suspend/resume on j7200
In-Reply-To: <20231128-j7200-pinctrl-s2r-v1-0-704e7dc24460@bootlin.com>
References: <20231128-j7200-pinctrl-s2r-v1-0-704e7dc24460@bootlin.com>
Message-ID: <170719349987.2245010.13900750309896394285.b4-ty@ti.com>

Hi Thomas Richard,

On Tue, 28 Nov 2023 16:34:58 +0100, Thomas Richard wrote:
> On j7200, during suspend to ram the SoC is powered-off. So the pinctrl
> contexts are lost.
> The flag PCS_CONTEXT_LOSS_OFF shall be set to restore the pinctrl
> contexts.
> 
> A new compatible (ti,j7200-padconf) was created to enable this flag only
> for j7200.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[3/3] arm64: dts: ti: k3-j7200: use ti,j7200-padconf compatible
      commit: 4eb42afed5d488c4707be5362e8e0f0771f5218e

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb  5 20:55:56 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 10:25:56 +0530
Subject: [RESEND PATCH v2] arm64: dts: ti: k3-am69-sk: remove assigned-clock-parents for unused VP
In-Reply-To: <20240201142308.4954-1-j-choudhary@ti.com>
References: <20240201142308.4954-1-j-choudhary@ti.com>
Message-ID: <170719349985.2245010.17205587189304843387.b4-ty@ti.com>

Hi Jayesh Choudhary,

On Thu, 01 Feb 2024 19:53:08 +0530, Jayesh Choudhary wrote:
> VP2 and VP3 are unused video ports and VP3 share the same parent
> clock as VP1 causing issue with pixel clock setting for HDMI (VP1).
> The current DM firmware does not support changing parent clock if it
> is shared by another component. It returns 0 for the determine_rate
> query before causing set_rate to set the clock at default maximum of
> 1.8GHz which is a lot more than the maximum frequency videoports can
> support (600MHz) causing SYNC LOST issues.
> So remove the parent clocks for unused VPs to avoid conflict.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: k3-am69-sk: remove assigned-clock-parents for unused VP
      commit: cfdb4f7ffdb855c1a3d274dc7757e780dcbf2d55

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb  5 20:56:25 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 10:26:25 +0530
Subject: [PATCH] arm64: dts: ti: k3-am62p5-sk: Enable CPSW MDIO node
In-Reply-To: <20240201-am62p_cpsw_mdio-v1-1-05f758300f6e@ti.com>
References: <20240201-am62p_cpsw_mdio-v1-1-05f758300f6e@ti.com>
Message-ID: <170719349983.2245010.18430004394937215893.b4-ty@ti.com>

Hi Jai Luthra,

On Thu, 01 Feb 2024 18:13:53 +0530, Jai Luthra wrote:
> Enable the CPSW MDIO node, and link the pinctrl information to enable
> ethernet on SK-AM62P.
> 
> Ethernet was unintentally broken on this board, even though these nodes
> were already present, as enabling them was missed in the original
> patch.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: k3-am62p5-sk: Enable CPSW MDIO node
      commit: 8839a9af397e803e0447a6b3e69fad54ed22d26d

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From danishanwar at ti.com  Mon Feb  5 21:15:59 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Tue, 6 Feb 2024 10:45:59 +0530
Subject: [PATCH v3 3/3] arm64: dts: ti: k3-am642-evm: add overlay for
 icssg1 2nd port
In-Reply-To: <6c5e2ca5-9b47-4a08-817c-e4bb1d10032f@kernel.org>
References: <20240122113045.1711818-1-danishanwar@ti.com>
 <20240122113045.1711818-4-danishanwar@ti.com>
 <33e62844-a148-4374-aba8-481dc7799e15@kernel.org>
 <17d1cfd0-2962-4857-af1d-7f2126b37abf@ti.com>
 <6c5e2ca5-9b47-4a08-817c-e4bb1d10032f@kernel.org>
Message-ID: <704316db-cb3f-4069-bf34-8d470b0ab444@ti.com>



On 05/02/24 6:27 pm, Roger Quadros wrote:
> 
> 
> On 02/02/2024 18:50, Anwar, Md Danish wrote:
>> On 2/2/2024 5:56 PM, Roger Quadros wrote:
>>>
>>>
>>> On 22/01/2024 13:30, MD Danish Anwar wrote:
>>>> The am642-evm doesn't allow to enable 2 x CPSW3g ports and 2 x ICSSG1 ports
>>>> all together, so base k3-am642-evm.dts enables by default 2 x CPSW3g ports
>>>> and 1 x ICSSG1 ports, but it also possible to support 1 x CPSW3g ports and
>>>> 2 x ICSSG1 ports configuration.
>>>
>>> "it is also possible"
>>>
>>> OK so there can only be 3 ethernet ports on this board. There is no "ethernet3" alias.
>>>
>>
>> Yes maximum there can be 3 ports only. By default 2 are cpsw and 1 icssg
>> but this parch introduces overlay to change the muxed port into icssg.
>>
>> By default,
>> 	ethernet0 = &cpsw_port1;
>> 	ethernet1 = &cpsw_port2;
>> 	ethernet2 = &icssg1_emac0;
>>
>> When this overlay is applied, it should be something like this,
>> 	ethernet0 = &cpsw_port1;
>> 	ethernet1 = &icssg1_emac0;
>> 	ethernet2 = &icssg1_emac1;
>>
>> Let me know if this looks ok to you. I will modify the alias accordingly.
> 
> ethernet0 is ok
> 
> As per schematics: icssg1_emac0 is fixed to J21A port. so I'd call this ethernet1
> 
> J21B port can be switched between cpsw_port2 and icssg1_emac1. so I'd call this ethernet2
> 
> This way ethernet1 definition is fixed regardless and you are only switching ethernet2
> definition.
> 

So ethernet0 and ethernet1 will be fixed and only ethernet2 will change
from cpsw_port2 to icssg1_emac1 when this overlay is applied.

I have posted v4 [1] before your this reply. In v4 I have kept ethernet0
and ethernet2 fixed to cpsw_port1 and icssg1_emac0 respectively and only
ethernet1 changes from cpsw_port2 to icssg1_emac1 when this overlay is
applied. Overlay only changes ethernet1. I think this is also a valid
approach. eth0 will be fixed to cpsw and eth2 will be fixed to icssg.
eth1 will toggle between cpsw and icssg. You can have a look at v4.

Pls let me know if you are okay with this.

[1] https://lore.kernel.org/all/20240205090546.4000446-1-danishanwar at ti.com/

>>
>>>>
>>>> This patch adds overlay to support 1 x CPSW3g ports and 2 x ICSSG1 ports
>>>> configuration:
>>>> - Add label name 'mdio_mux_1' for 'mdio-mux-1' node so that the node
>>>>   'mdio-mux-1' can be disabled in the overlay using the label name.
>>>> - disable 2nd CPSW3g port
>>>> - update CPSW3g pinmuxes to not use RGMII2
>>>> - disable mdio-mux-1 and define mdio-mux-2 to route ICSSG1 MDIO to the
>>>>   shared DP83869 PHY
>>>> - add and enable ICSSG1 RGMII2 pinmuxes
>>>> - enable ICSSG1 MII1 port
>>>>
>>>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>>>> ---
>>>>  arch/arm64/boot/dts/ti/Makefile               |  5 ++
>>>>  .../dts/ti/k3-am642-evm-icssg1-dualemac.dtso  | 75 +++++++++++++++++++
>>>>  arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  2 +-
>>>>  3 files changed, 81 insertions(+), 1 deletion(-)
>>>>  create mode 100644 arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>>>>
>>>> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
>>>> index 52c1dc910308..320b2fae5730 100644
>>>> --- a/arch/arm64/boot/dts/ti/Makefile
>>>> +++ b/arch/arm64/boot/dts/ti/Makefile
>>>> @@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
>>>>  dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
>>>>  dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>>>>  dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
>>>> +dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac.dtbo
>>>>  
>>>>  # Boards with AM65x SoC
>>>>  k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
>>>> @@ -105,6 +106,8 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
>>>>  	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>>>>  k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
>>>>  	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
>>>> +k3-am642-evm-icssg1-dualemac-dtbs := \
>>>> +	k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
>>>>  k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
>>>>  	k3-j721e-evm-pcie0-ep.dtbo
>>>>  k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
>>>> @@ -120,6 +123,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
>>>>  	k3-am62a7-sk-csi2-ov5640.dtb \
>>>>  	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
>>>>  	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
>>>> +	k3-am642-evm-icssg1-dualemac.dtb \
>>>>  	k3-j721e-evm-pcie0-ep.dtb \
>>>>  	k3-j721s2-evm-pcie1-ep.dtb
>>>>  
>>>> @@ -129,6 +133,7 @@ DTC_FLAGS_k3-am625-sk += -@
>>>>  DTC_FLAGS_k3-am62-lp-sk += -@
>>>>  DTC_FLAGS_k3-am62a7-sk += -@
>>>>  DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
>>>> +DTC_FLAGS_k3-am642-evm += -@
>>>>  DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
>>>>  DTC_FLAGS_k3-j721e-common-proc-board += -@
>>>>  DTC_FLAGS_k3-j721s2-common-proc-board += -@
>>>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>>>> new file mode 100644
>>>> index 000000000000..b2b1a6252e73
>>>> --- /dev/null
>>>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>>>> @@ -0,0 +1,75 @@
>>>> +// SPDX-License-Identifier: GPL-2.0
>>>
>>> Don't you need to use updated licensing header like in the series [1]
>>>
>>> [1] https://lore.kernel.org/all/20240110140903.4090946-1-nm at ti.com/
>>>
>>
>> Sure. I will update the header.
>>
>>>> +/**
>>>> + * DT overlay for enabling 2nd ICSSG1 port on AM642 EVM
>>>> + *
>>>> + * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
>>>> + */
>>>> +
>>>> +/dts-v1/;
>>>> +/plugin/;
>>>> +
>>>> +#include <dt-bindings/gpio/gpio.h>
>>>> +#include "k3-pinctrl.h"
>>>> +
>>>> +&{/} {
>>>
>>> You need to fixup alias for ethernet1 to icssg1_emac1?
>>>
>>
>> Yes I will update the aliases accordingly.
>>
>>>> +	mdio-mux-2 {
>>>
>>> this should be mdio-mux at 0 ?
>>>
>>
>> The main mux in evm dts is defined as mdio-mux-1 so I was following the
>> same. I will change this to mdio-mux at 0
>>
>>>> +		compatible = "mdio-mux-multiplexer";
>>>> +		mux-controls = <&mdio_mux>;
>>>> +		mdio-parent-bus = <&icssg1_mdio>;
>>>> +		#address-cells = <1>;
>>>> +		#size-cells = <0>;
>>>> +
>>>> +		mdio at 0 {
>>>> +			reg = <0x0>;
>>>> +			#address-cells = <1>;
>>>> +			#size-cells = <0>;
>>>> +
>>>> +			icssg1_phy2: ethernet-phy at 3 {
>>>> +				reg = <3>;
>>>> +				tx-internal-delay-ps = <250>;
>>>> +				rx-internal-delay-ps = <2000>;
>>>> +			};
>>>> +		};
>>>> +	};
>>>> +};
>>>> +
>>>> +&main_pmx0 {
>>>> +	icssg1_rgmii2_pins_default: icssg1-rgmii2-default-pins {
>>>> +		pinctrl-single,pins = <
>>>> +			AM64X_IOPAD(0x0108, PIN_INPUT, 2) /* (W11) PRG1_PRU1_GPO0.RGMII2_RD0 */
>>>> +			AM64X_IOPAD(0x010c, PIN_INPUT, 2) /* (V11) PRG1_PRU1_GPO1.RGMII2_RD1 */
>>>> +			AM64X_IOPAD(0x0110, PIN_INPUT, 2) /* (AA12) PRG1_PRU1_GPO2.RGMII2_RD2 */
>>>> +			AM64X_IOPAD(0x0114, PIN_INPUT, 2) /* (Y12) PRG1_PRU1_GPO3.RGMII2_RD3 */
>>>> +			AM64X_IOPAD(0x0120, PIN_INPUT, 2) /* (U11) PRG1_PRU1_GPO6.RGMII2_RXC */
>>>> +			AM64X_IOPAD(0x0118, PIN_INPUT, 2) /* (W12) PRG1_PRU1_GPO4.RGMII2_RX_CTL */
>>>> +			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2) /* (AA10) PRG1_PRU1_GPO11.RGMII2_TD0 */
>>>> +			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2) /* (V10) PRG1_PRU1_GPO12.RGMII2_TD1 */
>>>> +			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2) /* (U10) PRG1_PRU1_GPO13.RGMII2_TD2 */
>>>> +			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2) /* (AA11) PRG1_PRU1_GPO14.RGMII2_TD3 */
>>>> +			AM64X_IOPAD(0x0148, PIN_OUTPUT, 2) /* (Y10) PRG1_PRU1_GPO16.RGMII2_TXC */
>>>> +			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2) /* (Y11) PRG1_PRU1_GPO15.RGMII2_TX_CTL */
>>>> +		>;
>>>> +	};
>>>> +};
>>>> +
>>>> +&cpsw3g {
>>>> +	pinctrl-0 = <&rgmii1_pins_default>;
>>>> +};
>>>> +
>>>> +&cpsw_port2 {
>>>> +	status = "disabled";
>>>> +};
>>>> +
>>>> +&mdio_mux_1 {
>>>> +	status = "disabled";
>>>> +};
>>>> +
>>>> +&icssg1_eth {
>>>> +	pinctrl-0 = <&icssg1_rgmii1_pins_default>, <&icssg1_rgmii2_pins_default>;
>>>> +};
>>>> +
>>>> +&icssg1_emac1 {
>>>> +	status = "okay";
>>>> +	phy-handle = <&icssg1_phy2>;
>>>> +	phy-mode = "rgmii-id";
>>>> +};
>>>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>>>> index c08b0223be52..6ae43c12419f 100644
>>>> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>>>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>>>> @@ -200,7 +200,7 @@ mdio_mux: mux-controller {
>>>>  		mux-gpios = <&exp1 12 GPIO_ACTIVE_HIGH>;
>>>>  	};
>>>>  
>>>> -	mdio-mux-1 {
>>>> +	mdio_mux_1: mdio-mux-1 {
>>>
>>> mdio_mux_1: mdio-mux at 1
>>>
>>
>> Sure. I will update this.
>>
>>>>  		compatible = "mdio-mux-multiplexer";
>>>>  		mux-controls = <&mdio_mux>;
>>>>  		mdio-parent-bus = <&cpsw3g_mdio>;
>>>
>>
> 

-- 
Thanks and Regards,
Danish


From umang.jain at ideasonboard.com  Mon Feb  5 21:21:46 2024
From: umang.jain at ideasonboard.com (Umang Jain)
Date: Tue,  6 Feb 2024 10:51:46 +0530
Subject: [PATCH] drm/imx: Replace of_device.h with explicit includes
Message-ID: <20240206052146.69779-1-umang.jain@ideasonboard.com>

The DT of_device.h and of_platform.h date back to the separate
of_platform_bus_type before it as merged into the regular platform bus.
As part of that merge prepping Arm DT support 13 years ago, they
"temporarily" include each other. They also include platform_device.h
and of.h.

of_device.h isn't needed, but of.h is for of_node_put().

This fixes the following build errors:
error: implicit declaration of function ?platform_set_drvdata? [-Werror=implicit-function-declaration]
error: implicit declaration of function ?of_node_put? [-Werror=implicit-function-declaration]

Fixes: 3075f087680b ("drm/imx: add driver for HDMI TX Parallel Video Interface")
Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
---
 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
index 962779dc539e..8a51a2ac8df1 100644
--- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
+++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
@@ -8,9 +8,10 @@
 #include <drm/drm_bridge.h>
 #include <drm/drm_crtc.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
 #include <linux/of_graph.h>
 #include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
 
 #define HTX_PVI_CTL	0x0
 #define  PVI_CTL_OP_VSYNC_POL	BIT(18)
-- 
2.41.0



From claudiu.beznea at tuxon.dev  Mon Feb  5 21:54:48 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 6 Feb 2024 07:54:48 +0200
Subject: [PATCH v2 2/8] ARM: dts: microchip: sam9x60ek: Add power-supply
 properties for sdmmc nodes
In-Reply-To: <20240205080027.4565-3-mihai.sain@microchip.com>
References: <20240205080027.4565-1-mihai.sain@microchip.com>
 <20240205080027.4565-3-mihai.sain@microchip.com>
Message-ID: <35eca42a-5bb0-4d24-972b-6fe2fb4d87ab@tuxon.dev>

Hi, Mihai,

On 05.02.2024 10:00, Mihai Sain wrote:
> The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.
> Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
> The sdmmc controller from SAM9X60 MPU doesn't support the IO voltage signaling/switching required by the UHS sd-card.

Please wrap the line at 75 chars (see [1]).

Thank you,
Claudiu Beznea

[1]
https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html#the-canonical-patch-format.

> In order to use the sd high-speed mode, keep vqmmc at 3V3.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/at91-sam9x60ek.dts | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts b/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
> index f3cbb675cea4..b19a0956dc97 100644
> --- a/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
> +++ b/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
> @@ -560,6 +560,8 @@ &sdmmc0 {
>  	status = "okay";
>  	cd-gpios = <&pioA 23 GPIO_ACTIVE_LOW>;
>  	disable-wp;
> +	vmmc-supply = <&vdd1_3v3>;
> +	vqmmc-supply = <&vdd1_3v3>;
>  };
>  
>  &sdmmc1 {
> @@ -568,6 +570,8 @@ &sdmmc1 {
>  	pinctrl-0 = <&pinctrl_sdmmc1_default>;
>  	no-1-8-v;
>  	non-removable;
> +	vmmc-supply = <&vdd1_3v3>;
> +	vqmmc-supply = <&vdd1_3v3>;
>  	status = "disabled"; /* Conflict with flx4. */
>  };
>  


From shawn.gsc at gmail.com  Mon Feb  5 22:11:20 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Tue, 6 Feb 2024 14:11:20 +0800
Subject: [PATCH] bus: imx-weim: fix valid range check
In-Reply-To: <20240119185026.1192333-1-l.stach@pengutronix.de>
References: <20240119185026.1192333-1-l.stach@pengutronix.de>
Message-ID: <ZcHNiJJzpRaVni+6@dragon>

On Fri, Jan 19, 2024 at 07:50:26PM +0100, Lucas Stach wrote:
> When the range parsing was open-coded the number of u32 entries to
> parse had to be a multiple of 4 and the driver checks this. With
> the range parsing converted to the range parser the counting changes
> from individual u32 entries to a complete range, so the check must
> not reject counts not divisible by 4.
> 
> Fixes: 2a88e4792c6d ("bus: imx-weim: Remove open coded "ranges" parsing")
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

Applied, thanks!


From shawn.gsc at gmail.com  Mon Feb  5 22:16:26 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Tue, 6 Feb 2024 14:16:26 +0800
Subject: [PATCH 1/4] arm64: dts: ls1012a: correct the size of dcfg block
In-Reply-To: <20240119201035.3124007-1-Frank.Li@nxp.com>
References: <20240119201035.3124007-1-Frank.Li@nxp.com>
Message-ID: <ZcHOuo7iTQBlHC/2@dragon>

On Fri, Jan 19, 2024 at 03:10:32PM -0500, Frank Li wrote:
> From: Li Yang <leoyang.li at nxp.com>
> 
> Correct the size of dcfg block to 4k.
> 
> Signed-off-by: Zhang Ying-22455 <ying.zhang22455 at nxp.com>
> Signed-off-by: Li Yang <leoyang.li at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied all, thanks!


From claudiu.beznea at tuxon.dev  Mon Feb  5 22:33:27 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Tue, 6 Feb 2024 08:33:27 +0200
Subject: [PATCH v1 0/2] ARM: dts: at91: gardena-smart-gateway: Use DMA for
 serial ports
In-Reply-To: <20240102161839.702625-1-ezra.buehler@husqvarna.com>
References: <20240102161839.702625-1-ezra.buehler@husqvarna.com>
Message-ID: <c2427050-9d96-4f2b-b6b3-1f3605df77d5@tuxon.dev>



On 02.01.2024 18:18, ezra at easyb.ch wrote:
> From: Ezra Buehler <ezra.buehler at husqvarnagroup.com>
> 
> On our AT91SAM9G25-based GARDENA smart Gateway we have been experiencing
> various problems which we were able to trace back to unreliable UART
> communication. Enabling DMA for the serial ports resolved these issues.
> 
> Ezra Buehler (2):
>   ARM: dts: at91: at91sam9x5ek: Use DMA for DBGU serial port
>   ARM: dts: at91: gardena-smart-gateway: Use DMA for USART3

Applied to at91-dt, thank you!


From dharma.b at microchip.com  Mon Feb  5 22:44:18 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Tue, 6 Feb 2024 12:14:18 +0530
Subject: [linux][PATCH] ASoC: dt-bindings: atmel,sam9x5-wm8731: Convert to json-schema
Message-ID: <20240206064418.237377-1-dharma.b@microchip.com>

Convert atmel sam9x5-wm8731-audio devicetree binding to json-schema.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
 .../sound/atmel,sam9x5-wm8731-audio.yaml      | 76 +++++++++++++++++++
 .../sound/atmel-sam9x5-wm8731-audio.txt       | 35 ---------
 2 files changed, 76 insertions(+), 35 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/atmel,sam9x5-wm8731-audio.yaml
 delete mode 100644 Documentation/devicetree/bindings/sound/atmel-sam9x5-wm8731-audio.txt

diff --git a/Documentation/devicetree/bindings/sound/atmel,sam9x5-wm8731-audio.yaml b/Documentation/devicetree/bindings/sound/atmel,sam9x5-wm8731-audio.yaml
new file mode 100644
index 000000000000..33717b728f63
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel,sam9x5-wm8731-audio.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/atmel,sam9x5-wm8731-audio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel at91sam9x5ek wm8731 audio complex
+
+maintainers:
+  - Dharma Balasubiramani <dharma.b at microchip.com>
+
+description:
+  The audio complex configuration for Atmel at91sam9x5ek with WM8731 audio codec.
+
+properties:
+  compatible:
+    const: atmel,sam9x5-wm8731-audio
+
+  atmel,model:
+    $ref: /schemas/types.yaml#/definitions/string
+    description: The user-visible name of this sound complex.
+
+  atmel,ssc-controller:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of the SSC controller.
+
+  atmel,audio-codec:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of the WM8731 audio codec.
+
+  atmel,audio-routing:
+    description:
+      A list of the connections between audio components. Each entry is a pair
+      of strings, the first being the connection's sink, the second being the
+      connection's source.
+    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+    items:
+      enum:
+        # Board Connectors
+        - Headphone Jack
+        - Line In Jack
+
+        # CODEC Pins
+        - LOUT
+        - ROUT
+        - LHPOUT
+        - RHPOUT
+        - LLINEIN
+        - RLINEIN
+        - MICIN
+
+required:
+  - compatible
+  - atmel,model
+  - atmel,ssc-controller
+  - atmel,audio-codec
+  - atmel,audio-routing
+
+additionalProperties: false
+
+examples:
+  - |
+    sound {
+        compatible = "atmel,sam9x5-wm8731-audio";
+
+        atmel,model = "wm8731 @ AT91SAM9X5EK";
+
+        atmel,audio-routing =
+                "Headphone Jack", "RHPOUT",
+                "Headphone Jack", "LHPOUT",
+                "LLINEIN", "Line In Jack",
+                "RLINEIN", "Line In Jack";
+
+        atmel,ssc-controller = <&ssc0>;
+        atmel,audio-codec = <&wm8731>;
+    };
diff --git a/Documentation/devicetree/bindings/sound/atmel-sam9x5-wm8731-audio.txt b/Documentation/devicetree/bindings/sound/atmel-sam9x5-wm8731-audio.txt
deleted file mode 100644
index 8facbce53db8..000000000000
--- a/Documentation/devicetree/bindings/sound/atmel-sam9x5-wm8731-audio.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-* Atmel at91sam9x5ek wm8731 audio complex
-
-Required properties:
-  - compatible: "atmel,sam9x5-wm8731-audio"
-  - atmel,model: The user-visible name of this sound complex.
-  - atmel,ssc-controller: The phandle of the SSC controller
-  - atmel,audio-codec: The phandle of the WM8731 audio codec
-  - atmel,audio-routing: A list of the connections between audio components.
-    Each entry is a pair of strings, the first being the connection's sink,
-    the second being the connection's source.
-
-Available audio endpoints for the audio-routing table:
-
-Board connectors:
- * Headphone Jack
- * Line In Jack
-
-wm8731 pins:
-cf Documentation/devicetree/bindings/sound/wlf,wm8731.yaml
-
-Example:
-sound {
-	compatible = "atmel,sam9x5-wm8731-audio";
-
-	atmel,model = "wm8731 @ AT91SAM9X5EK";
-
-	atmel,audio-routing =
-		"Headphone Jack", "RHPOUT",
-		"Headphone Jack", "LHPOUT",
-		"LLINEIN", "Line In Jack",
-		"RLINEIN", "Line In Jack";
-
-	atmel,ssc-controller = <&ssc0>;
-	atmel,audio-codec = <&wm8731>;
-};
-- 
2.25.1



From Markus.Elfring at web.de  Mon Feb  5 22:48:07 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Tue, 6 Feb 2024 07:48:07 +0100
Subject: [PATCH] pmdomain: mediatek: Use
 devm_platform_get_and_ioremap_resource() in init_scp()
In-Reply-To: <CAMuHMdUQLWBQemtgnCHj64wCYAET8J2-MgbisyMChSbh0k0L7w@mail.gmail.com>
References: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de>
 <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
 <8f011126-c95a-4c71-8bc9-a6b0a5823c96@web.de>
 <CAMuHMdUQLWBQemtgnCHj64wCYAET8J2-MgbisyMChSbh0k0L7w@mail.gmail.com>
Message-ID: <8ffda85d-8fc4-4329-ac7c-1afa6c1eaa2e@web.de>

?
>> I got another idea after looking at the implementation of the function
>> ?devm_platform_get_and_ioremap_resource? once more.
>> https://elixir.bootlin.com/linux/v6.8-rc3/source/drivers/base/platform.c#L87
?
> Yes, you can pass a NULL pointer as the last parameter.

Would you like to support any approaches which can make interface descriptions clearer
for such an implementation detail?


> And as this is very common, the wrapper devm_platform_ioremap_resource() exists.

I find further collateral evolution interesting for the involved parameter reduction.

Regards,
Markus


From shawn.gsc at gmail.com  Mon Feb  5 23:02:35 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Tue, 6 Feb 2024 15:02:35 +0800
Subject: [PATCH] arm64: dts: imx8mp: Enable SAI audio on Data Modul
 i.MX8M Plus eDM SBC
In-Reply-To: <20240122144359.169899-1-marex@denx.de>
References: <20240122144359.169899-1-marex@denx.de>
Message-ID: <ZcHZizwC3KdNUytg@dragon>

On Mon, Jan 22, 2024 at 03:43:51PM +0100, Marek Vasut wrote:
> Add SAI I2S and audio bindings to Data Modul i.MX8M Plus eDM SBC.
> 
> The SGTL5000 is attached to SAI3, however the SGTL5000 codec MCLK
> must be supplied even if the SAI3 is not in use and is controlled
> separately by the codec. The MCLK is also used to drive the codec
> I2C block, so without MCLK, I2C access to the codec would not be
> possible.
> 
> To provide such flexible MCLK control, use PWM4 with period 1 and
> duty cycle 50% as 12 MHz clock source, as there is no direct way
> to route MX8MP CCM clock to the MCLK pin. Use codec as bitclock
> and frame clock master, so that the SGTL5000 PLL can be used to
> generate derived clock.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: devicetree at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> ---
>  .../freescale/imx8mp-data-modul-edm-sbc.dts   | 64 ++++++++++++++++++-
>  1 file changed, 63 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
> index 5828c9d7821de..433b2c9468f89 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
> @@ -45,6 +45,19 @@ clk_xtal25: clock-xtal25 {
>  		clock-frequency = <25000000>;
>  	};
>  
> +	clk_pwm4: clock-pwm4 {
> +		compatible = "pwm-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <12000000>;
> +		clock-output-names = "codec-pwm4";
> +		/*
> +		 * 1 / 83 ns ~= 12 MHz , but since the PWM input clock is 24 MHz
> +		 * and the calculated PWM period is 1 and duty cycle is 50%, the
> +		 * result is exactly 12 MHz, which is fine for SGTL5000 MCLK.
> +		 */
> +		pwms = <&pwm4 0 83 0>;
> +	};
> +
>  	panel: panel {
>  		/* Compatible string is filled in by panel board DT Overlay. */
>  		backlight = <&backlight>;
> @@ -82,6 +95,24 @@ reg_usdhc2_vmmc: regulator-usdhc2-vmmc {
>  		vin-supply = <&buck4>;
>  	};
>  
> +	sound {
> +		compatible = "simple-audio-card";
> +		simple-audio-card,name = "SGTL5000-Card";
> +		simple-audio-card,format = "i2s";
> +		simple-audio-card,bitclock-master = <&codec_dai>;
> +		simple-audio-card,frame-master = <&codec_dai>;
> +		simple-audio-card,widgets = "Headphone", "Headphone Jack";
> +		simple-audio-card,routing = "Headphone Jack", "HP_OUT";
> +
> +		cpu_dai: simple-audio-card,cpu {
> +			sound-dai = <&sai3>;
> +		};
> +
> +		codec_dai: simple-audio-card,codec {
> +			sound-dai = <&sgtl5000>;
> +		};
> +	};
> +
>  	watchdog { /* TPS3813 */
>  		compatible = "linux,wdt-gpio";
>  		pinctrl-names = "default";
> @@ -288,6 +319,15 @@ &i2c1 {
>  	sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
>  	status = "okay";
>  
> +	sgtl5000: codec at a {

audio-codec

> +		#sound-dai-cells = <0>;
> +		clocks = <&clk_pwm4>;
> +		compatible = "fsl,sgtl5000";
> +		reg = <0x0a>;

Could you follow the "Order of Properties in Device Node" recommendation
from Documentation/devicetree/bindings/dts-coding-style.rst?

Shawn

> +		VDDA-supply = <&buck4>;
> +		VDDIO-supply = <&buck4>;
> +	};
> +
>  	usb-hub at 2c {
>  		compatible = "microchip,usb2514bi";
>  		reg = <0x2c>;
> @@ -436,6 +476,23 @@ &pwm1 {
>  	status = "disabled";
>  };
>  
> +&pwm4 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_pwm4>;
> +	status = "okay";
> +};
> +
> +&sai3 {
> +	#clock-cells = <0>;
> +	#sound-dai-cells = <0>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sai3>;
> +	assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
> +	assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
> +	assigned-clock-rates = <12288000>;
> +	status = "okay";
> +};
> +
>  /* SD slot */
>  &usdhc2 {
>  	pinctrl-names = "default", "state_100mhz", "state_200mhz";
> @@ -785,6 +842,12 @@ MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x40000090
>  		>;
>  	};
>  
> +	pinctrl_pwm4: pwm4-grp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SAI3_MCLK__PWM4_OUT		0xd6
> +		>;
> +	};
> +
>  	pinctrl_rtc: rtc-grp {
>  		fsl,pins = <
>  			/* RTC_IRQ# */
> @@ -816,7 +879,6 @@ pinctrl_sai3: sai3-grp {
>  			MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC	0xd6
>  			MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00	0xd6
>  			MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK	0xd6
> -			MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI3_MCLK	0xd6
>  			MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00	0xd6
>  		>;
>  	};
> -- 
> 2.43.0
> 


From shawn.gsc at gmail.com  Mon Feb  5 23:03:38 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Tue, 6 Feb 2024 15:03:38 +0800
Subject: [PATCH] arm64: dts: imx8mp: Enable PCIe to Data Modul i.MX8M
 Plus eDM SBC
In-Reply-To: <20240122144501.169941-1-marex@denx.de>
References: <20240122144501.169941-1-marex@denx.de>
Message-ID: <ZcHZyih/a1xZAXEy@dragon>

On Mon, Jan 22, 2024 at 03:44:44PM +0100, Marek Vasut wrote:
> Enable PCIe support on Data Modul i.MX8M Plus eDM SBC.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>

Applied, thanks!


From michal.simek at amd.com  Mon Feb  5 23:04:18 2024
From: michal.simek at amd.com (Michal Simek)
Date: Tue, 6 Feb 2024 08:04:18 +0100
Subject: [PATCH v2] dt-bindings: firmware: xilinx: Describe soc-nvmem
 subnode
In-Reply-To: <24fe6adbf2424360618e8f5ca541ebfd8bb0723e.1706692641.git.michal.simek@amd.com>
References: <24fe6adbf2424360618e8f5ca541ebfd8bb0723e.1706692641.git.michal.simek@amd.com>
Message-ID: <7d2a1c77-16db-4ab6-9dcc-146a600ac8d4@amd.com>



On 1/31/24 10:17, Michal Simek wrote:
> Describe soc-nvmem subnode as the part of firmware node. The name can't be
> pure nvmem because dt-schema already defines it as array property that's
> why different name should be used.
> 
> Signed-off-by: Michal Simek <michal.simek at amd.com>
> ---
> 
> Changes in v2:
> - Fix typo in subject
> - Make example bigger requested by Conor
> 
> Dt binding for nvmem node has been already merged and it is the part of
> linux-next tree.
> Here is the reference to it just in case:
> https://lore.kernel.org/r/170635581622.41421.8980881999042944764.b4-ty at linaro.org
> 
> v1 available here:
> https://lore.kernel.org/r/3869498c995cbb123127122f429e90de0a3f4014.1706531104.git.michal.simek at amd.com
> 
> ---
>   .../firmware/xilinx/xlnx,zynqmp-firmware.yaml  | 18 ++++++++++++++++++
>   1 file changed, 18 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.yaml b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.yaml
> index 870b94813a43..741f17c830f4 100644
> --- a/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.yaml
> +++ b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.yaml
> @@ -62,6 +62,12 @@ properties:
>         interface.
>       type: object
>   
> +  soc-nvmem:
> +    $ref: /schemas/nvmem/xlnx,zynqmp-nvmem.yaml#
> +    description: The ZynqMP MPSoC provides access to the hardware related data
> +      like SOC revision, IDCODE and specific purpose efuses.
> +    type: object
> +
>     pcap:
>       $ref: /schemas/fpga/xlnx,zynqmp-pcap-fpga.yaml#
>       description: The ZynqMP SoC uses the PCAP (Processor Configuration Port) to
> @@ -110,6 +116,18 @@ examples:
>       firmware {
>         zynqmp_firmware: zynqmp-firmware {
>           #power-domain-cells = <1>;
> +        soc-nvmem {
> +          compatible = "xlnx,zynqmp-nvmem-fw";
> +          nvmem-layout {
> +            compatible = "fixed-layout";
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +
> +            soc_revision: soc-revision at 0 {
> +                reg = <0x0 0x4>;
> +            };
> +          };
> +        };
>           gpio {
>             compatible = "xlnx,zynqmp-gpio-modepin";
>             gpio-controller;

Applied.
M


From shawn.gsc at gmail.com  Mon Feb  5 23:07:21 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Tue, 6 Feb 2024 15:07:21 +0800
Subject: [PATCH] bus: imx-weim: fix imx_weim_gpr_setup()
In-Reply-To: <20240122205738.2432552-1-charles.perry@savoirfairelinux.com>
References: <20240122205738.2432552-1-charles.perry@savoirfairelinux.com>
Message-ID: <ZcHaqasXS60LtbVn@dragon>

On Mon, Jan 22, 2024 at 03:57:29PM -0500, Charles Perry wrote:
> Commit 2a88e4792c6d ("bus: imx-weim: Remove open coded "ranges"
> parsing") changes the parsing of the "ranges" field by using
> for_each_of_range instead of of_property_for_each_u32. The number of
> iteration of the loop is now equal to the number of range within
> ranges. It is therefore no longer needed to check that i is divisible
> by 4, otherwise, valid configurations will fail imx_weim_gpr_setup().
> 
> Fixes: 2a88e4792c6d ("bus: imx-weim: Remove open coded "ranges" parsing")
> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>

Thanks for the patch!  But I have picked up the one [1] from Lucas.

Shawn

[1] https://lore.kernel.org/all/20240119185026.1192333-1-l.stach at pengutronix.de/

> ---
>  drivers/bus/imx-weim.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c
> index 6b5da73c85417..837bf9d51c6ec 100644
> --- a/drivers/bus/imx-weim.c
> +++ b/drivers/bus/imx-weim.c
> @@ -120,7 +120,7 @@ static int imx_weim_gpr_setup(struct platform_device *pdev)
>  		i++;
>  	}
>  
> -	if (i == 0 || i % 4)
> +	if (i == 0)
>  		goto err;
>  
>  	for (i = 0; i < ARRAY_SIZE(gprvals); i++) {
> -- 
> 2.43.0
> 


From liubo03 at inspur.com  Mon Feb  5 23:12:56 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:12:56 -0500
Subject: [PATCH 00/18] mfd: convert to use maple tree register cache
Message-ID: <20240206071314.8721-1-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Bo Liu (18):
  mfd: ac100: convert to use maple tree register cache
  mfd: as3711: convert to use maple tree register cache
  mfd: as3722: convert to use maple tree register cache
  mfd: axp20x: convert to use maple tree register cache
  mfd: bcm590xx: convert to use maple tree register cache
  mfd: bd9571mwv: convert to use maple tree register cache
  mfd: dialog: convert to use maple tree register cache
  mfd: khadas-mcu: convert to use maple tree register cache
  mfd: lochnagar-i2c: convert to use maple tree register cache
  mfd: wolfson: convert to use maple tree register cache
  mfd: rohm: convert to use maple tree register cache
  mfd: rk8xx: convert to use maple tree register cache
  mfd: rn5t618: convert to use maple tree register cache
  mfd: rsmu_i2c: convert to use maple tree register cache
  mfd: si476x: convert to use maple tree register cache
  mfd: stmfx: convert to use maple tree register cache
  mfd: stpmic1: convert to use maple tree register cache
  mfd: rc5t583: convert to use maple tree register cache

 drivers/mfd/ac100.c         | 2 +-
 drivers/mfd/as3711.c        | 2 +-
 drivers/mfd/as3722.c        | 2 +-
 drivers/mfd/axp20x.c        | 4 ++--
 drivers/mfd/bcm590xx.c      | 4 ++--
 drivers/mfd/bd9571mwv.c     | 4 ++--
 drivers/mfd/da9052-core.c   | 2 +-
 drivers/mfd/da9055-core.c   | 2 +-
 drivers/mfd/da9062-core.c   | 4 ++--
 drivers/mfd/da9063-i2c.c    | 2 +-
 drivers/mfd/da9150-core.c   | 2 +-
 drivers/mfd/khadas-mcu.c    | 2 +-
 drivers/mfd/lochnagar-i2c.c | 4 ++--
 drivers/mfd/rc5t583.c       | 2 +-
 drivers/mfd/rk8xx-spi.c     | 2 +-
 drivers/mfd/rn5t618.c       | 2 +-
 drivers/mfd/rohm-bd71828.c  | 4 ++--
 drivers/mfd/rohm-bd718x7.c  | 2 +-
 drivers/mfd/rohm-bd9576.c   | 2 +-
 drivers/mfd/rsmu_i2c.c      | 2 +-
 drivers/mfd/si476x-prop.c   | 2 +-
 drivers/mfd/stmfx.c         | 2 +-
 drivers/mfd/stpmic1.c       | 2 +-
 drivers/mfd/wm5102-tables.c | 2 +-
 drivers/mfd/wm5110-tables.c | 2 +-
 drivers/mfd/wm8350-regmap.c | 2 +-
 drivers/mfd/wm8400-core.c   | 2 +-
 drivers/mfd/wm97xx-core.c   | 6 +++---
 28 files changed, 36 insertions(+), 36 deletions(-)

-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:08 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:08 -0500
Subject: [PATCH 12/18] mfd: rk8xx: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-13-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/rk8xx-spi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c
index fd137f38c2c4..3405fb82ff9f 100644
--- a/drivers/mfd/rk8xx-spi.c
+++ b/drivers/mfd/rk8xx-spi.c
@@ -34,7 +34,7 @@ static const struct regmap_config rk806_regmap_config_spi = {
 	.reg_bits = 16,
 	.val_bits = 8,
 	.max_register = RK806_BUCK_RSERVE_REG5,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 	.volatile_table = &rk806_volatile_table,
 };
 
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:07 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:07 -0500
Subject: [PATCH 11/18] mfd: rohm: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-12-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/rohm-bd71828.c | 4 ++--
 drivers/mfd/rohm-bd718x7.c | 2 +-
 drivers/mfd/rohm-bd9576.c  | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
index 594718f7e8e1..2f3826c7eef4 100644
--- a/drivers/mfd/rohm-bd71828.c
+++ b/drivers/mfd/rohm-bd71828.c
@@ -197,7 +197,7 @@ static const struct regmap_config bd71815_regmap = {
 	.val_bits = 8,
 	.volatile_table = &bd71815_volatile_regs,
 	.max_register = BD71815_MAX_REGISTER - 1,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 static const struct regmap_config bd71828_regmap = {
@@ -205,7 +205,7 @@ static const struct regmap_config bd71828_regmap = {
 	.val_bits = 8,
 	.volatile_table = &bd71828_volatile_regs,
 	.max_register = BD71828_MAX_REGISTER,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 /*
diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
index 4798bdf27afb..7755a4c073bf 100644
--- a/drivers/mfd/rohm-bd718x7.c
+++ b/drivers/mfd/rohm-bd718x7.c
@@ -87,7 +87,7 @@ static const struct regmap_config bd718xx_regmap_config = {
 	.val_bits = 8,
 	.volatile_table = &volatile_regs,
 	.max_register = BD718XX_MAX_REGISTER - 1,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 static int bd718xx_init_press_duration(struct regmap *regmap,
diff --git a/drivers/mfd/rohm-bd9576.c b/drivers/mfd/rohm-bd9576.c
index bceac7016740..3a9f61961721 100644
--- a/drivers/mfd/rohm-bd9576.c
+++ b/drivers/mfd/rohm-bd9576.c
@@ -62,7 +62,7 @@ static struct regmap_config bd957x_regmap = {
 	.val_bits = 8,
 	.volatile_table = &volatile_regs,
 	.max_register = BD957X_MAX_REGISTER,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 static struct regmap_irq bd9576_irqs[] = {
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:12:57 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:12:57 -0500
Subject: [PATCH 01/18] mfd: ac100: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-2-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/ac100.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/ac100.c b/drivers/mfd/ac100.c
index 6d49d7fb5f14..8f47c392cbd1 100644
--- a/drivers/mfd/ac100.c
+++ b/drivers/mfd/ac100.c
@@ -72,7 +72,7 @@ static const struct regmap_config ac100_regmap_config = {
 	.wr_table	= &ac100_writeable_table,
 	.volatile_table	= &ac100_volatile_table,
 	.max_register	= AC100_RTC_GP(15),
-	.cache_type	= REGCACHE_RBTREE,
+	.cache_type	= REGCACHE_MAPLE,
 };
 
 static struct mfd_cell ac100_cells[] = {
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:00 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:00 -0500
Subject: [PATCH 04/18] mfd: axp20x: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-5-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/axp20x.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index deaa969bab4e..d8daa593ebd5 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -352,7 +352,7 @@ static const struct regmap_config axp192_regmap_config = {
 	.wr_table	= &axp192_writeable_table,
 	.volatile_table	= &axp192_volatile_table,
 	.max_register	= AXP20X_CC_CTRL,
-	.cache_type	= REGCACHE_RBTREE,
+	.cache_type	= REGCACHE_MAPLE,
 };
 
 static const struct regmap_config axp20x_regmap_config = {
@@ -388,7 +388,7 @@ static const struct regmap_config axp313a_regmap_config = {
 	.wr_table = &axp313a_writeable_table,
 	.volatile_table = &axp313a_volatile_table,
 	.max_register = AXP313A_IRQ_STATE,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 static const struct regmap_config axp806_regmap_config = {
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:10 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:10 -0500
Subject: [PATCH 14/18] mfd: rsmu_i2c: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-15-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/rsmu_i2c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/rsmu_i2c.c b/drivers/mfd/rsmu_i2c.c
index 06d78a1cf1cc..5711e512b6a2 100644
--- a/drivers/mfd/rsmu_i2c.c
+++ b/drivers/mfd/rsmu_i2c.c
@@ -188,7 +188,7 @@ static const struct regmap_config rsmu_sabre_regmap_config = {
 	.ranges = rsmu_sabre_range_cfg,
 	.num_ranges = ARRAY_SIZE(rsmu_sabre_range_cfg),
 	.volatile_reg = rsmu_sabre_volatile_reg,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 	.can_multi_write = true,
 };
 
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:09 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:09 -0500
Subject: [PATCH 13/18] mfd: rn5t618: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-14-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/rn5t618.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c
index 7336e6d8a001..23ca00d2c624 100644
--- a/drivers/mfd/rn5t618.c
+++ b/drivers/mfd/rn5t618.c
@@ -62,7 +62,7 @@ static const struct regmap_config rn5t618_regmap_config = {
 	.val_bits	= 8,
 	.volatile_reg	= rn5t618_volatile_reg,
 	.max_register	= RN5T618_MAX_REG,
-	.cache_type	= REGCACHE_RBTREE,
+	.cache_type	= REGCACHE_MAPLE,
 };
 
 static const struct regmap_irq rc5t619_irqs[] = {
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:01 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:01 -0500
Subject: [PATCH 05/18] mfd: bcm590xx: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-6-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/bcm590xx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c
index 92eede9a5e61..8b56786d85d0 100644
--- a/drivers/mfd/bcm590xx.c
+++ b/drivers/mfd/bcm590xx.c
@@ -27,14 +27,14 @@ static const struct regmap_config bcm590xx_regmap_config_pri = {
 	.reg_bits	= 8,
 	.val_bits	= 8,
 	.max_register	= BCM590XX_MAX_REGISTER_PRI,
-	.cache_type	= REGCACHE_RBTREE,
+	.cache_type	= REGCACHE_MAPLE,
 };
 
 static const struct regmap_config bcm590xx_regmap_config_sec = {
 	.reg_bits	= 8,
 	.val_bits	= 8,
 	.max_register	= BCM590XX_MAX_REGISTER_SEC,
-	.cache_type	= REGCACHE_RBTREE,
+	.cache_type	= REGCACHE_MAPLE,
 };
 
 static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri)
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:12:58 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:12:58 -0500
Subject: [PATCH 02/18] mfd: as3711: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-3-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/as3711.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/as3711.c b/drivers/mfd/as3711.c
index c7e85ff38013..9741977031df 100644
--- a/drivers/mfd/as3711.c
+++ b/drivers/mfd/as3711.c
@@ -106,7 +106,7 @@ static const struct regmap_config as3711_regmap_config = {
 	.precious_reg = as3711_precious_reg,
 	.max_register = AS3711_MAX_REG,
 	.num_reg_defaults_raw = AS3711_NUM_REGS,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 #ifdef CONFIG_OF
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:12:59 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:12:59 -0500
Subject: [PATCH 03/18] mfd: as3722: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-4-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/as3722.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/as3722.c b/drivers/mfd/as3722.c
index a2bf68afc131..bec047bdd088 100644
--- a/drivers/mfd/as3722.c
+++ b/drivers/mfd/as3722.c
@@ -299,7 +299,7 @@ static const struct regmap_config as3722_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
 	.max_register = AS3722_MAX_REGISTER,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 	.rd_table = &as3722_readable_table,
 	.wr_table = &as3722_writable_table,
 	.volatile_table = &as3722_volatile_table,
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:04 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:04 -0500
Subject: [PATCH 08/18] mfd: khadas-mcu: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-9-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/khadas-mcu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c
index 61396d824f16..ba981a788692 100644
--- a/drivers/mfd/khadas-mcu.c
+++ b/drivers/mfd/khadas-mcu.c
@@ -72,7 +72,7 @@ static const struct regmap_config khadas_mcu_regmap_config = {
 	.max_register	= KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
 	.volatile_reg	= khadas_mcu_reg_volatile,
 	.writeable_reg	= khadas_mcu_reg_writeable,
-	.cache_type	= REGCACHE_RBTREE,
+	.cache_type	= REGCACHE_MAPLE,
 };
 
 static struct mfd_cell khadas_mcu_fan_cells[] = {
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:12 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:12 -0500
Subject: [PATCH 16/18] mfd: stmfx: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-17-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/stmfx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c
index c02cbd9c2f5d..f391c2ccaa72 100644
--- a/drivers/mfd/stmfx.c
+++ b/drivers/mfd/stmfx.c
@@ -53,7 +53,7 @@ static const struct regmap_config stmfx_regmap_config = {
 	.max_register	= STMFX_REG_MAX,
 	.volatile_reg	= stmfx_reg_volatile,
 	.writeable_reg	= stmfx_reg_writeable,
-	.cache_type	= REGCACHE_RBTREE,
+	.cache_type	= REGCACHE_MAPLE,
 };
 
 static const struct resource stmfx_pinctrl_resources[] = {
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:11 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:11 -0500
Subject: [PATCH 15/18] mfd: si476x: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-16-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/si476x-prop.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/si476x-prop.c b/drivers/mfd/si476x-prop.c
index f0608d138f02..3d5c118888b2 100644
--- a/drivers/mfd/si476x-prop.c
+++ b/drivers/mfd/si476x-prop.c
@@ -222,7 +222,7 @@ static const struct regmap_config si476x_regmap_config = {
 	.reg_read = si476x_core_regmap_read,
 	.reg_write = si476x_core_regmap_write,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 struct regmap *devm_regmap_init_si476x(struct si476x_core *core)
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:03 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:03 -0500
Subject: [PATCH 07/18] mfd: dialog: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-8-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/da9052-core.c | 2 +-
 drivers/mfd/da9055-core.c | 2 +-
 drivers/mfd/da9062-core.c | 4 ++--
 drivers/mfd/da9063-i2c.c  | 2 +-
 drivers/mfd/da9150-core.c | 2 +-
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c
index 150448cd2eb0..dc85801b9fa0 100644
--- a/drivers/mfd/da9052-core.c
+++ b/drivers/mfd/da9052-core.c
@@ -533,7 +533,7 @@ const struct regmap_config da9052_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 
 	.max_register = DA9052_PAGE1_CON_REG,
 	.readable_reg = da9052_reg_readable,
diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c
index 768302e05baa..1f727ef60d63 100644
--- a/drivers/mfd/da9055-core.c
+++ b/drivers/mfd/da9055-core.c
@@ -245,7 +245,7 @@ const struct regmap_config da9055_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 
 	.max_register = DA9055_MAX_REGISTER_CNT,
 	.readable_reg = da9055_register_readable,
diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c
index 73a22107900c..dbbc4779170a 100644
--- a/drivers/mfd/da9062-core.c
+++ b/drivers/mfd/da9062-core.c
@@ -476,7 +476,7 @@ static struct regmap_config da9061_regmap_config = {
 	.ranges = da9061_range_cfg,
 	.num_ranges = ARRAY_SIZE(da9061_range_cfg),
 	.max_register = DA9062AA_CONFIG_ID,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 	.rd_table = &da9061_aa_readable_table,
 	.wr_table = &da9061_aa_writeable_table,
 	.volatile_table = &da9061_aa_volatile_table,
@@ -582,7 +582,7 @@ static struct regmap_config da9062_regmap_config = {
 	.ranges = da9062_range_cfg,
 	.num_ranges = ARRAY_SIZE(da9062_range_cfg),
 	.max_register = DA9062AA_CONFIG_ID,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 	.rd_table = &da9062_aa_readable_table,
 	.wr_table = &da9062_aa_writeable_table,
 	.volatile_table = &da9062_aa_volatile_table,
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
index d715cf9a9e68..c6235cd0dbdc 100644
--- a/drivers/mfd/da9063-i2c.c
+++ b/drivers/mfd/da9063-i2c.c
@@ -342,7 +342,7 @@ static struct regmap_config da9063_regmap_config = {
 	.num_ranges = ARRAY_SIZE(da9063_range_cfg),
 	.max_register = DA9063_REG_CONFIG_ID,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 static const struct of_device_id da9063_dt_ids[] = {
diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c
index 94d621e20635..5c59cc869fb3 100644
--- a/drivers/mfd/da9150-core.c
+++ b/drivers/mfd/da9150-core.c
@@ -169,7 +169,7 @@ static const struct regmap_config da9150_regmap_config = {
 	.num_ranges = ARRAY_SIZE(da9150_range_cfg),
 	.max_register = DA9150_TBAT_RES_B,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 
 	.volatile_reg = da9150_volatile_reg,
 };
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:02 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:02 -0500
Subject: [PATCH 06/18] mfd: bd9571mwv: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-7-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/bd9571mwv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/bd9571mwv.c b/drivers/mfd/bd9571mwv.c
index 819d09e4d100..0a955178d469 100644
--- a/drivers/mfd/bd9571mwv.c
+++ b/drivers/mfd/bd9571mwv.c
@@ -67,7 +67,7 @@ static const struct regmap_access_table bd9571mwv_volatile_table = {
 static const struct regmap_config bd9571mwv_regmap_config = {
 	.reg_bits	= 8,
 	.val_bits	= 8,
-	.cache_type	= REGCACHE_RBTREE,
+	.cache_type	= REGCACHE_MAPLE,
 	.rd_table	= &bd9571mwv_readable_table,
 	.wr_table	= &bd9571mwv_writable_table,
 	.volatile_table	= &bd9571mwv_volatile_table,
@@ -152,7 +152,7 @@ static const struct regmap_access_table bd9574mwf_volatile_table = {
 static const struct regmap_config bd9574mwf_regmap_config = {
 	.reg_bits	= 8,
 	.val_bits	= 8,
-	.cache_type	= REGCACHE_RBTREE,
+	.cache_type	= REGCACHE_MAPLE,
 	.rd_table	= &bd9574mwf_readable_table,
 	.wr_table	= &bd9574mwf_writable_table,
 	.volatile_table	= &bd9574mwf_volatile_table,
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:05 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:05 -0500
Subject: [PATCH 09/18] mfd: lochnagar-i2c: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-10-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/lochnagar-i2c.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/lochnagar-i2c.c b/drivers/mfd/lochnagar-i2c.c
index 0b76fcccd0bd..6c930c57f2e2 100644
--- a/drivers/mfd/lochnagar-i2c.c
+++ b/drivers/mfd/lochnagar-i2c.c
@@ -70,7 +70,7 @@ static const struct regmap_config lochnagar1_i2c_regmap = {
 	.use_single_read = true,
 	.use_single_write = true,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 static const struct reg_sequence lochnagar1_patch[] = {
@@ -163,7 +163,7 @@ static const struct regmap_config lochnagar2_i2c_regmap = {
 	.readable_reg = lochnagar2_readable_register,
 	.volatile_reg = lochnagar2_volatile_register,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 static const struct reg_sequence lochnagar2_patch[] = {
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:06 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:06 -0500
Subject: [PATCH 10/18] mfd: wolfson: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-11-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/wm5102-tables.c | 2 +-
 drivers/mfd/wm5110-tables.c | 2 +-
 drivers/mfd/wm8350-regmap.c | 2 +-
 drivers/mfd/wm8400-core.c   | 2 +-
 drivers/mfd/wm97xx-core.c   | 6 +++---
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index f77ecc635b6f..6a8602c1c4ee 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -1922,7 +1922,7 @@ const struct regmap_config wm5102_spi_regmap = {
 	.readable_reg = wm5102_readable_register,
 	.volatile_reg = wm5102_volatile_register,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 	.reg_defaults = wm5102_reg_default,
 	.num_reg_defaults = ARRAY_SIZE(wm5102_reg_default),
 };
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c
index eba324875afd..6ff33a54a068 100644
--- a/drivers/mfd/wm5110-tables.c
+++ b/drivers/mfd/wm5110-tables.c
@@ -3202,7 +3202,7 @@ const struct regmap_config wm5110_spi_regmap = {
 	.readable_reg = wm5110_readable_register,
 	.volatile_reg = wm5110_volatile_register,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 	.reg_defaults = wm5110_reg_default,
 	.num_reg_defaults = ARRAY_SIZE(wm5110_reg_default),
 };
diff --git a/drivers/mfd/wm8350-regmap.c b/drivers/mfd/wm8350-regmap.c
index 5663b8b0b3ad..3d0ebb004dbf 100644
--- a/drivers/mfd/wm8350-regmap.c
+++ b/drivers/mfd/wm8350-regmap.c
@@ -325,7 +325,7 @@ const struct regmap_config wm8350_regmap = {
 	.reg_bits = 8,
 	.val_bits = 16,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 
 	.max_register = WM8350_MAX_REGISTER,
 	.readable_reg = wm8350_readable,
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
index 75483c9be0c4..ddfb234849dd 100644
--- a/drivers/mfd/wm8400-core.c
+++ b/drivers/mfd/wm8400-core.c
@@ -100,7 +100,7 @@ static const struct regmap_config wm8400_regmap_config = {
 
 	.volatile_reg = wm8400_volatile,
 
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 /**
diff --git a/drivers/mfd/wm97xx-core.c b/drivers/mfd/wm97xx-core.c
index 663acbb1854c..1566a9b04b6a 100644
--- a/drivers/mfd/wm97xx-core.c
+++ b/drivers/mfd/wm97xx-core.c
@@ -95,7 +95,7 @@ static const struct regmap_config wm9705_regmap_config = {
 	.reg_stride = 2,
 	.val_bits = 16,
 	.max_register = 0x7e,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 
 	.reg_defaults = wm9705_reg_defaults,
 	.num_reg_defaults = ARRAY_SIZE(wm9705_reg_defaults),
@@ -163,7 +163,7 @@ static const struct regmap_config wm9712_regmap_config = {
 	.reg_stride = 2,
 	.val_bits = 16,
 	.max_register = 0x7e,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 
 	.reg_defaults = wm9712_reg_defaults,
 	.num_reg_defaults = ARRAY_SIZE(wm9712_reg_defaults),
@@ -234,7 +234,7 @@ static const struct regmap_config wm9713_regmap_config = {
 	.reg_stride = 2,
 	.val_bits = 16,
 	.max_register = 0x7e,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 
 	.reg_defaults = wm9713_reg_defaults,
 	.num_reg_defaults = ARRAY_SIZE(wm9713_reg_defaults),
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:14 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:14 -0500
Subject: [PATCH 18/18] mfd: rc5t583: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-19-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/rc5t583.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
index 5e81f011363f..2c0e8e9630f7 100644
--- a/drivers/mfd/rc5t583.c
+++ b/drivers/mfd/rc5t583.c
@@ -230,7 +230,7 @@ static const struct regmap_config rc5t583_regmap_config = {
 	.volatile_reg = volatile_reg,
 	.max_register = RC5T583_MAX_REG,
 	.num_reg_defaults_raw = RC5T583_NUM_REGS,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 };
 
 static int rc5t583_i2c_probe(struct i2c_client *i2c)
-- 
2.18.2



From liubo03 at inspur.com  Mon Feb  5 23:13:13 2024
From: liubo03 at inspur.com (Bo Liu)
Date: Tue, 6 Feb 2024 02:13:13 -0500
Subject: [PATCH 17/18] mfd: stpmic1: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <20240206071314.8721-18-liubo03@inspur.com>

The maple tree register cache is based on a much more modern data structure
than the rbtree cache and makes optimisation choices which are probably
more appropriate for modern systems than those made by the rbtree cache.

Signed-off-by: Bo Liu <liubo03 at inspur.com>
---
 drivers/mfd/stpmic1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/stpmic1.c b/drivers/mfd/stpmic1.c
index c5128fe96cc7..d8a603d95aa6 100644
--- a/drivers/mfd/stpmic1.c
+++ b/drivers/mfd/stpmic1.c
@@ -63,7 +63,7 @@ static const struct regmap_access_table stpmic1_volatile_table = {
 static const struct regmap_config stpmic1_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
-	.cache_type = REGCACHE_RBTREE,
+	.cache_type = REGCACHE_MAPLE,
 	.max_register = PMIC_MAX_REGISTER_ADDRESS,
 	.rd_table = &stpmic1_readable_table,
 	.wr_table = &stpmic1_writeable_table,
-- 
2.18.2



From shawn.gsc at gmail.com  Mon Feb  5 23:31:25 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Tue, 6 Feb 2024 15:31:25 +0800
Subject: [PATCH v5 1/3] dt-bindings: arm: fsl: Add phyBOARD-Segin-i.MX93
In-Reply-To: <20240124074930.26101-2-othacehe@gnu.org>
References: <20240124074930.26101-1-othacehe@gnu.org>
 <20240124074930.26101-2-othacehe@gnu.org>
Message-ID: <ZcHdc73ys6TCaUom@dragon>

On Wed, Jan 24, 2024 at 08:49:28AM +0100, Mathieu Othacehe wrote:
> Add support for phyBOARD-Segin-i.MX93 board.
> 
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> Signed-off-by: Mathieu Othacehe <othacehe at gnu.org>

Applied, thanks!


From shawn.gsc at gmail.com  Mon Feb  5 23:31:59 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Tue, 6 Feb 2024 15:31:59 +0800
Subject: [PATCH v5 3/3] arm64: dts: imx93: Add phyBOARD-Segin-i.MX93
 support
In-Reply-To: <20240124074930.26101-4-othacehe@gnu.org>
References: <20240124074930.26101-1-othacehe@gnu.org>
 <20240124074930.26101-4-othacehe@gnu.org>
Message-ID: <ZcHgb4egPKh+Yqnf@dragon>

On Wed, Jan 24, 2024 at 08:49:30AM +0100, Mathieu Othacehe wrote:
> Add basic support for phyBOARD-Segin-i.MX93.
> Main features are:
> * eMMC
> * Ethernet
> * SD-Card
> * UART
> 
> Tested-by: Primoz Fiser <primoz.fiser at norik.com>
> Signed-off-by: Mathieu Othacehe <othacehe at gnu.org>

Applied, thanks!


From shawn.gsc at gmail.com  Mon Feb  5 23:35:58 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Tue, 6 Feb 2024 15:35:58 +0800
Subject: [PATCH v1 1/1] ARM: dts: imx6: skov: add aliases for all
 ethernet nodes
In-Reply-To: <20240124124455.738187-1-o.rempel@pengutronix.de>
References: <20240124124455.738187-1-o.rempel@pengutronix.de>
Message-ID: <ZcHhXosBK4obwNYW@dragon>

On Wed, Jan 24, 2024 at 01:44:55PM +0100, Oleksij Rempel wrote:
> Add aliases for all ethernet nodes including the switch. It makes it
> easier to find this nodes by the boot loader.
> 
> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>

Applied, thanks! 


From shawn.gsc at gmail.com  Mon Feb  5 23:40:26 2024
From: shawn.gsc at gmail.com (Shawn Guo)
Date: Tue, 6 Feb 2024 15:40:26 +0800
Subject: [PATCH v2 0/2] nxp: imx: Add support for Apalis Evaluation Board
 v1.2
In-Reply-To: <20240124141849.26254-1-hiagofranco@gmail.com>
References: <20240124141849.26254-1-hiagofranco@gmail.com>
Message-ID: <ZcHiamfoDeZ1rueS@dragon>

On Wed, Jan 24, 2024 at 11:13:18AM -0300, Hiago De Franco wrote:
> Hiago De Franco (2):
>   dt-bindings: arm: fsl: Add toradex,apalis_imx6q-eval-v1.2 board
>   arm: dts: nxp: imx: Add support for Apalis Evaluation Board v1.2

Changed the subject prefix of the second one to 'ARM: dts: imx: ...'

Applied both, thanks!

Shawn


From maskray at google.com  Mon Feb  5 23:45:52 2024
From: maskray at google.com (Fangrui Song)
Date: Mon,  5 Feb 2024 23:45:52 -0800
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
Message-ID: <20240206074552.541154-1-maskray@google.com>

The generic constraint "i" seems to be copied from x86 or arm (and with
a redundant generic operand modifier "c"). It works with -fno-PIE but
not with -fPIE/-fPIC in GCC's aarch64 port.

The machine constraint "S", which denotes a symbol or label reference
with a constant offset, supports PIC and has been available in GCC since
2012 and in Clang since 7.0. However, Clang before 19 does not support
"S" on a symbol with a constant offset [1] (e.g.
`static_key_false(&nf_hooks_needed[pf][hook])` in
include/linux/netfilter.h), so we use "i" as a fallback.

Suggested-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Fangrui Song <maskray at google.com>
Link: https://github.com/llvm/llvm-project/pull/80255 [1]

---
Changes from
arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)

* Use "Si" as Ard suggested to support Clang<19
* Make branch a separate operand

Changes from v1:

* Use asmSymbolicName for readability
---
 arch/arm64/include/asm/jump_label.h | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
index 48ddc0f45d22..b7716b215f91 100644
--- a/arch/arm64/include/asm/jump_label.h
+++ b/arch/arm64/include/asm/jump_label.h
@@ -15,6 +15,10 @@
 
 #define JUMP_LABEL_NOP_SIZE		AARCH64_INSN_SIZE
 
+/*
+ * Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
+ * support "S" on a symbol with a constant offset, so we use "i" as a fallback.
+ */
 static __always_inline bool arch_static_branch(struct static_key * const key,
 					       const bool branch)
 {
@@ -23,9 +27,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
 		 "	.pushsection	__jump_table, \"aw\"	\n\t"
 		 "	.align		3			\n\t"
 		 "	.long		1b - ., %l[l_yes] - .	\n\t"
-		 "	.quad		%c0 - .			\n\t"
+		 "	.quad		(%[key] - .) + %[bit0]  \n\t"
 		 "	.popsection				\n\t"
-		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
+		 :  :  [key]"Si"(key), [bit0]"i"(branch) :  : l_yes);
 
 	return false;
 l_yes:
@@ -40,9 +44,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
 		 "	.pushsection	__jump_table, \"aw\"	\n\t"
 		 "	.align		3			\n\t"
 		 "	.long		1b - ., %l[l_yes] - .	\n\t"
-		 "	.quad		%c0 - .			\n\t"
+		 "	.quad		(%[key] - .) + %[bit0]  \n\t"
 		 "	.popsection				\n\t"
-		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
+		 :  :  [key]"Si"(key), [bit0]"i"(branch) :  : l_yes);
 
 	return false;
 l_yes:
-- 
2.43.0.594.gd9cf4e227d-goog



From adeep at lexina.in  Mon Feb  5 23:48:09 2024
From: adeep at lexina.in (Viacheslav)
Date: Tue, 6 Feb 2024 10:48:09 +0300
Subject: [PATCHv1 3/5] arm64: dts: amlogic: Add cache information to the
 Amlogic G12A SoCS
In-Reply-To: <20240205171930.968-4-linux.amoon@gmail.com>
References: <20240205171930.968-1-linux.amoon@gmail.com>
 <20240205171930.968-4-linux.amoon@gmail.com>
Message-ID: <4248e19e-5f2f-4e4f-a869-a0fec81b16bd@lexina.in>

Hi!

You missed the AXG family with the Cortex-A53 CPU. The datasheet does 
not provide information on cache sizes. Given that the A113X/A113D are 
equipped with the Arm Cortex-A53 processor, it is assumed they use the 
same cache size as the S905/S905X/S905X2 models.

05/02/2024 20.19, Anand Moon wrote:
> As per the S905X2 datasheet add missing cache information to the Amlogic
> G12A SoC.
> 
> - Each Cortex-A53 core has 32KB of L1 instruction cache available and
> 	32KB of L1 data cache available.
> - Along with 512KB Unified L2 cache.
> 
> To improve system performance.
> 
> Signed-off-by: Anand Moon <linux.amoon at gmail.com>
> ---
> No public dataheet available, since S905X2 support Arm Cortex-A53 cpu
> nence used the same cache size as S905 and S905X.
> ---
>   arch/arm64/boot/dts/amlogic/meson-g12a.dtsi | 27 +++++++++++++++++++++
>   1 file changed, 27 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
> index 543e70669df5..6e1e3a3f5f18 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
> @@ -17,6 +17,12 @@ cpu0: cpu at 0 {
>   			compatible = "arm,cortex-a53";
>   			reg = <0x0 0x0>;
>   			enable-method = "psci";
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
>   			next-level-cache = <&l2>;
>   			#cooling-cells = <2>;
>   		};
> @@ -26,6 +32,12 @@ cpu1: cpu at 1 {
>   			compatible = "arm,cortex-a53";
>   			reg = <0x0 0x1>;
>   			enable-method = "psci";
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
>   			next-level-cache = <&l2>;
>   			#cooling-cells = <2>;
>   		};
> @@ -35,6 +47,12 @@ cpu2: cpu at 2 {
>   			compatible = "arm,cortex-a53";
>   			reg = <0x0 0x2>;
>   			enable-method = "psci";
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
>   			next-level-cache = <&l2>;
>   			#cooling-cells = <2>;
>   		};
> @@ -44,6 +62,12 @@ cpu3: cpu at 3 {
>   			compatible = "arm,cortex-a53";
>   			reg = <0x0 0x3>;
>   			enable-method = "psci";
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
>   			next-level-cache = <&l2>;
>   			#cooling-cells = <2>;
>   		};
> @@ -52,6 +76,9 @@ l2: l2-cache0 {
>   			compatible = "cache";
>   			cache-level = <2>;
>   			cache-unified;
> +			cache-size = <0x7d000>; /* L2. 512 KB */
> +			cache-line-size = <64>;
> +			cache-sets = <512>;
>   		};
>   	};
>   


Best regards,
--
Viacheslav Bocharov <adeep at lexina.in>


From alexander.stein at ew.tq-group.com  Mon Feb  5 23:50:22 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 06 Feb 2024 08:50:22 +0100
Subject: [PATCH 2/2] arm64: dts: imx8: Fix lpuart DMA channel order
In-Reply-To: <ZbfdsY8MkQrIzOqG@lizhi-Precision-Tower-5810>
References: <20231219123439.3359318-1-alexander.stein@ew.tq-group.com> <20231219123439.3359318-2-alexander.stein@ew.tq-group.com> <ZbfdsY8MkQrIzOqG@lizhi-Precision-Tower-5810>
Message-ID: <3282920.44csPzL39Z@steina-w>

Hi,

Am Montag, 29. Januar 2024, 18:17:37 CET schrieb Frank Li:
> On Tue, Dec 19, 2023 at 01:34:39PM +0100, Alexander Stein wrote:
> > Bindings say DMA channels are in order Rx, Tx. Adjust the DT nodes
> > accordingly.
> > 
> > Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> > 
> >  arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi | 16 ++++++++--------
> >  1 file changed, 8 insertions(+), 8 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi index
> > a180893ac81e..0f48796e32b2 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
> > @@ -93,8 +93,8 @@ lpuart0: serial at 5a060000 {
> > 
> >  		assigned-clocks = <&clk IMX_SC_R_UART_0 
IMX_SC_PM_CLK_PER>;
> >  		assigned-clock-rates = <80000000>;
> >  		power-domains = <&pd IMX_SC_R_UART_0>;
> > 
> > -		dma-names = "tx","rx";
> > -		dmas = <&edma2 9 0 0>, <&edma2 8 0 1>;
> > +		dma-names = "rx", "tx";
> > +		dmas = <&edma2 8 0 0>, <&edma2 9 0 1>;
> 
> edma device bind header file already merged.
> Please include <dt-binding/dma/fsl-edma.h>
> 
> Change "1" to "FSL_EDMA_RX".

Thanks, I was not aware of that change. Meanwhile I noticed in my patch the 
flags were not switched as well.

Best regards,
Alexander

> Frank
> 
> >  		status = "disabled";
> >  	
> >  	};
> > 
> > @@ -107,8 +107,8 @@ lpuart1: serial at 5a070000 {
> > 
> >  		assigned-clocks = <&clk IMX_SC_R_UART_1 
IMX_SC_PM_CLK_PER>;
> >  		assigned-clock-rates = <80000000>;
> >  		power-domains = <&pd IMX_SC_R_UART_1>;
> > 
> > -		dma-names = "tx","rx";
> > -		dmas = <&edma2 11 0 0>, <&edma2 10 0 1>;
> > +		dma-names = "rx", "tx";
> > +		dmas = <&edma2 10 0 0>, <&edma2 11 0 1>;
> > 
> >  		status = "disabled";
> >  	
> >  	};
> > 
> > @@ -121,8 +121,8 @@ lpuart2: serial at 5a080000 {
> > 
> >  		assigned-clocks = <&clk IMX_SC_R_UART_2 
IMX_SC_PM_CLK_PER>;
> >  		assigned-clock-rates = <80000000>;
> >  		power-domains = <&pd IMX_SC_R_UART_2>;
> > 
> > -		dma-names = "tx","rx";
> > -		dmas = <&edma2 13 0 0>, <&edma2 12 0 1>;
> > +		dma-names = "rx", "tx";
> > +		dmas = <&edma2 12 0 0>, <&edma2 13 0 1>;
> > 
> >  		status = "disabled";
> >  	
> >  	};
> > 
> > @@ -135,8 +135,8 @@ lpuart3: serial at 5a090000 {
> > 
> >  		assigned-clocks = <&clk IMX_SC_R_UART_3 
IMX_SC_PM_CLK_PER>;
> >  		assigned-clock-rates = <80000000>;
> >  		power-domains = <&pd IMX_SC_R_UART_3>;
> > 
> > -		dma-names = "tx","rx";
> > -		dmas = <&edma2 15 0 0>, <&edma2 14 0 1>;
> > +		dma-names = "rx", "tx";
> > +		dmas = <&edma2 14 0 0>, <&edma2 15 0 1>;
> > 
> >  		status = "disabled";
> >  	
> >  	};


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From christianshewitt at gmail.com  Mon Feb  5 23:53:22 2024
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Tue, 6 Feb 2024 11:53:22 +0400
Subject: [PATCHv1 3/5] arm64: dts: amlogic: Add cache information to the
 Amlogic G12A SoCS
In-Reply-To: <4248e19e-5f2f-4e4f-a869-a0fec81b16bd@lexina.in>
References: <20240205171930.968-1-linux.amoon@gmail.com>
 <20240205171930.968-4-linux.amoon@gmail.com>
 <4248e19e-5f2f-4e4f-a869-a0fec81b16bd@lexina.in>
Message-ID: <E850AF1E-BF7E-45F7-8AF0-68B548166094@gmail.com>

> On 6 Feb 2024, at 11:48?am, Viacheslav <adeep at lexina.in> wrote:
> 
> You missed the AXG family with the Cortex-A53 CPU. The datasheet does not provide information on cache sizes. Given that the A113X/A113D are equipped with the Arm Cortex-A53 processor, it is assumed they use the same cache size as the S905/S905X/S905X2 models.

GXM is also missing, and also using A53 cores.

Christian

> 05/02/2024 20.19, Anand Moon wrote:
>> As per the S905X2 datasheet add missing cache information to the Amlogic
>> G12A SoC.
>> - Each Cortex-A53 core has 32KB of L1 instruction cache available and
>> 32KB of L1 data cache available.
>> - Along with 512KB Unified L2 cache.
>> To improve system performance.
>> Signed-off-by: Anand Moon <linux.amoon at gmail.com>
>> ---
>> No public dataheet available, since S905X2 support Arm Cortex-A53 cpu
>> nence used the same cache size as S905 and S905X.
>> ---
>>  arch/arm64/boot/dts/amlogic/meson-g12a.dtsi | 27 +++++++++++++++++++++
>>  1 file changed, 27 insertions(+)
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
>> index 543e70669df5..6e1e3a3f5f18 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
>> @@ -17,6 +17,12 @@ cpu0: cpu at 0 {
>>   compatible = "arm,cortex-a53";
>>   reg = <0x0 0x0>;
>>   enable-method = "psci";
>> + d-cache-line-size = <32>;
>> + d-cache-size = <0x8000>;
>> + d-cache-sets = <32>;
>> + i-cache-line-size = <32>;
>> + i-cache-size = <0x8000>;
>> + i-cache-sets = <32>;
>>   next-level-cache = <&l2>;
>>   #cooling-cells = <2>;
>>   };
>> @@ -26,6 +32,12 @@ cpu1: cpu at 1 {
>>   compatible = "arm,cortex-a53";
>>   reg = <0x0 0x1>;
>>   enable-method = "psci";
>> + d-cache-line-size = <32>;
>> + d-cache-size = <0x8000>;
>> + d-cache-sets = <32>;
>> + i-cache-line-size = <32>;
>> + i-cache-size = <0x8000>;
>> + i-cache-sets = <32>;
>>   next-level-cache = <&l2>;
>>   #cooling-cells = <2>;
>>   };
>> @@ -35,6 +47,12 @@ cpu2: cpu at 2 {
>>   compatible = "arm,cortex-a53";
>>   reg = <0x0 0x2>;
>>   enable-method = "psci";
>> + d-cache-line-size = <32>;
>> + d-cache-size = <0x8000>;
>> + d-cache-sets = <32>;
>> + i-cache-line-size = <32>;
>> + i-cache-size = <0x8000>;
>> + i-cache-sets = <32>;
>>   next-level-cache = <&l2>;
>>   #cooling-cells = <2>;
>>   };
>> @@ -44,6 +62,12 @@ cpu3: cpu at 3 {
>>   compatible = "arm,cortex-a53";
>>   reg = <0x0 0x3>;
>>   enable-method = "psci";
>> + d-cache-line-size = <32>;
>> + d-cache-size = <0x8000>;
>> + d-cache-sets = <32>;
>> + i-cache-line-size = <32>;
>> + i-cache-size = <0x8000>;
>> + i-cache-sets = <32>;
>>   next-level-cache = <&l2>;
>>   #cooling-cells = <2>;
>>   };
>> @@ -52,6 +76,9 @@ l2: l2-cache0 {
>>   compatible = "cache";
>>   cache-level = <2>;
>>   cache-unified;
>> + cache-size = <0x7d000>; /* L2. 512 KB */
>> + cache-line-size = <64>;
>> + cache-sets = <512>;
>>   };
>>   };
>>  
> 
> 
> Best regards,
> --
> Viacheslav Bocharov <adeep at lexina.in>
> 
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic




From alexander.stein at ew.tq-group.com  Tue Feb  6 00:02:05 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 06 Feb 2024 09:02:05 +0100
Subject: [PATCH v2 1/1] phy: freescale: phy-fsl-imx8-mipi-dphy: Fix alias name to use dashes
In-Reply-To: <20240110093343.468810-1-alexander.stein@ew.tq-group.com>
References: <20240110093343.468810-1-alexander.stein@ew.tq-group.com>
Message-ID: <10415929.nUPlyArG6x@steina-w>

Hi everyone,

Am Mittwoch, 10. Januar 2024, 10:33:43 CET schrieb Alexander Stein:
> Devicetree spec lists only dashes as valid characters for alias names.
> Table 3.2: Valid characters for alias names, Devicee Specification,
> Release v0.4
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Fixes: 3fbae284887de ("phy: freescale: phy-fsl-imx8-mipi-dphy: Add i.MX8qxp
> LVDS PHY mode support")
> ---
> Changes in v2:
> * Added Fixes tag as suggested by Liu Ying

Any feedback on this?

Thanks and best regards,
Alexander

>  drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c
> b/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c index
> e625b32889bfc..0928a526e2ab3 100644
> --- a/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c
> +++ b/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c
> @@ -706,7 +706,7 @@ static int mixel_dphy_probe(struct platform_device
> *pdev) return ret;
>  		}
> 
> -		priv->id = of_alias_get_id(np, "mipi_dphy");
> +		priv->id = of_alias_get_id(np, "mipi-dphy");
>  		if (priv->id < 0) {
>  			dev_err(dev, "Failed to get phy node alias id: 
%d\n",
>  				priv->id);


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From lihuisong at huawei.com  Tue Feb  6 00:02:15 2024
From: lihuisong at huawei.com (lihuisong (C))
Date: Tue, 6 Feb 2024 16:02:15 +0800
Subject: [PATCH] cpufreq: CPPC: Resolve the large frequency discrepancy
 from cpuinfo_cur_freq
In-Reply-To: <Zbyi40XtqbqXm0CL@e129154.nice.arm.com>
References: <20231212072617.14756-1-lihuisong@huawei.com>
 <ZZWfJOsDlEXWYHA5@arm.com> <9428a1ed-ba4d-1fe6-63e8-11e152bf1f09@huawei.com>
 <lnocwcitdbmgcyhd2dlczgdlhtfw4pfot2br2i3hqscnvr3xgq@nuxlauxum3nr>
 <d0f47e9d-6a58-8b46-89be-b3182abb69f0@huawei.com> <ZZwAmqp6hcmMF8aN@arm.com>
 <6505bdcb-5a5f-cba6-483b-75c51414a9c6@huawei.com>
 <ZaaOQzCpBjmW71xf@e129154.nice.arm.com>
 <a84a9749-97a5-a207-dfd3-8322a5a992d9@huawei.com>
 <Zbyi40XtqbqXm0CL@e129154.nice.arm.com>
Message-ID: <4f66c62e-b089-a125-5a8d-4a98d4181618@huawei.com>


? 2024/2/2 16:08, Beata Michalska ??:
> On Wed, Jan 17, 2024 at 05:18:40PM +0800, lihuisong (C) wrote:
>
> Hi ,
>
> Again, apologies for delay,
>
>> Hi,
>>
>> ? 2024/1/16 22:10, Beata Michalska ??:
>>> Hi,
>>>
>>> Apologies for jumping in so late....
>>>
>>> On Wed, Jan 10, 2024 at 03:09:48PM +0800, lihuisong (C) wrote:
>>>> Hi Ionela,
>>>>
>>>> ? 2024/1/8 22:03, Ionela Voinescu ??:
>>>>> Hi,
>>>>>
>>>>> On Friday 05 Jan 2024 at 15:04:47 (+0800), lihuisong (C) wrote:
>>>>>> Hi Vanshi,
>>>>>>
>>>>>> ? 2024/1/5 8:48, Vanshidhar Konda ??:
>>>>>>> On Thu, Jan 04, 2024 at 05:36:51PM +0800, lihuisong (C) wrote:
>>>>>>>> ? 2024/1/4 1:53, Ionela Voinescu ??:
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> On Tuesday 12 Dec 2023 at 15:26:17 (+0800), Huisong Li wrote:
>>>>>>>>>> Many developers found that the cpu current frequency is greater than
>>>>>>>>>> the maximum frequency of the platform, please see [1], [2] and [3].
>>>>>>>>>>
>>>>>>>>>> In the scenarios with high memory access pressure, the patch [1] has
>>>>>>>>>> proved the significant latency of cpc_read() which is used to obtain
>>>>>>>>>> delivered and reference performance counter cause an absurd frequency.
>>>>>>>>>> The sampling interval for this counters is very critical and
>>>>>>>>>> is expected
>>>>>>>>>> to be equal. However, the different latency of cpc_read() has a direct
>>>>>>>>>> impact on their sampling interval.
>>>>>>>>>>
>>>>>>>>> Would this [1] alternative solution work for you?
>>>>>>>> It would work for me AFAICS.
>>>>>>>> Because the "arch_freq_scale" is also from AMU core and constant
>>>>>>>> counter, and read together.
>>>>>>>> But, from their discuss line, it seems that there are some tricky
>>>>>>>> points to clarify or consider.
>>>>>>> I think the changes in [1] would work better when CPUs may be idle. With
>>>>>>> this
>>>>>>> patch we would have to wake any core that is in idle state to read the
>>>>>>> AMU
>>>>>>> counters. Worst case, if core 0 is trying to read the CPU frequency of
>>>>>>> all
>>>>>>> cores, it may need to wake up all the other cores to read the AMU
>>>>>>> counters.
>>>>>>    From the approach in [1], if all CPUs (one or more cores) under one policy
>>>>>> are idle, they still cannot be obtained the CPU frequency, right?
>>>>>> In this case, the [1] API will return 0 and have to back to call
>>>>>> cpufreq_driver->get() for cpuinfo_cur_freq.
>>>>>> Then we still need to face the issue this patch mentioned.
>>>>> With the implementation at [1], arch_freq_get_on_cpu() will not return 0
>>>>> for idle CPUs and the get() callback will not be called to wake up the
>>>>> CPUs.
>>>> Right, arch_freq_get_on_cpu() will not return 0 for idle CPUs.
>>>> However, for no-housekeeping CPUs, it will return 0 and have to call get()
>>>> callback, right?
>>>>> Worst case, arch_freq_get_on_cpu() will return a frequency based on the
>>>>> AMU counter values obtained on the last tick on that CPU. But if that CPU
>>>>> is not a housekeeping CPU, a housekeeping CPU in the same policy will be
>>>>> selected, as it would have had a more recent tick, and therefore a more
>>>>> recent frequency value for the domain.
>>>> But this frequency is from the last tick,
>>>> this last tick is probably a long time ago and it doesn't update
>>>> 'arch_freq_scale' for some reasons like CPU dile.
>>>> In addition, I'm not sure if there is possible that amu_scale_freq_tick() is
>>>> executed delayed under high stress case.
>>>> It also have an impact on the accuracy of the cpu frequency we query.
>>>>> I understand that the frequency returned here will not be up to date,
>>>>> but there's no proper frequency feedback for an idle CPU. If one only
>>>>> wakes up a CPU to sample counters, before the CPU goes back to sleep,
>>>>> the obtained frequency feedback is meaningless.
>>>>>
>>>>>>> For systems with 128 cores or more, this could be very expensive and
>>>>>>> happen
>>>>>>> very frequently.
>>>>>>>
>>>>>>> AFAICS, the approach in [1] would avoid this cost.
>>>>>> But the CPU frequency is just an average value for the last tick period
>>>>>> instead of the current one the CPU actually runs at.
>>>>>> In addition, there are some conditions to use 'arch_freq_scale' in this
>>>>>> approach.
>>>>> What are the conditions you are referring to?
>>>> It depends on the housekeeping CPUs.
>>>>>> So I'm not sure if this approach can entirely cover the frequency
>>>>>> discrepancy issue.
>>>>> Unfortunately there is no perfect frequency feedback. By the time you
>>>>> observe/use the value of scaling_cur_freq/cpuinfo_cur_freq, the frequency
>>>>> of the CPU might have already changed. Therefore, an average value might
>>>>> be a better indication of the recent performance level of a CPU.
>>>> An average value for CPU frequency is ok. It may be better if it has not any
>>>> delaying.
>>>>
>>>> The original implementation for cpuinfo_cur_freq can more reflect their
>>>> meaning in the user-guide [1]. The user-guide said:
>>>> "cpuinfo_cur_freq : Current frequency of the CPU as obtained from the
>>>> hardware, in KHz.
>>>> This is the frequency the CPU actually runs at."
>>>>
>>>>
>>>> [1]https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt
>>>>
>>>>> Would you be able to test [1] on your platform and usecase?
>>>> I has tested it on my platform (CPU number: 64, SMT: off and CPU base
>>>> frequency: 2.7GHz).
>>>> Accoding to the testing result,
>>>> 1> I found that patch [1] and [2] cannot cover the no housekeeping CPUs.
>>>> They still have to face the large frequency discrepancy issue my patch
>>>> mentioned.
>>>> 2> Additionally, the frequency value of all CPUs are almost the same by
>>>> using the 'arch_freq_scale' factor way. I'm not sure if it is ok.
>>>>
>>>> The patch [1] has been modified silightly as below:
>>>> -->
>>>> @@ -1756,7 +1756,10 @@ static unsigned int
>>>> cpufreq_verify_current_freq(struct cpufreq_policy *policy, b
>>>>   ?{
>>>>   ??????? unsigned int new_freq;
>>>>
>>>> -?????? new_freq = cpufreq_driver->get(policy->cpu);
>>>> +?????? new_freq = arch_freq_get_on_cpu(policy->cpu);
>>>> +?????? if (!new_freq)
>>>> +?????????????? new_freq = cpufreq_driver->get(policy->cpu);
>>>> +
>>> As pointed out this change will not make it to the next version of the patch.
>>> So I'd say you can safely ignore it and assume that arch_freq_get_on_cpu will
>>> only be wired for sysfs nodes for scaling_cur_freq/cpuinfo_cur_freq
>>>>   ??????? if (!new_freq)
>>>>   ??????????????? return 0;
>>>>
>>>> And the result is as follows:
>>>> *case 1:**No setting the nohz_full and cpufreq use performance governor*
>>>> *--> Step1: *read 'cpuinfo_cur_freq' in no pressure
>>>>   ? 0: 2699264???? 2: 2699264???? 4: 2699264???? 6: 2699264
>>>>   ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2699264
>>>>   ?16: 2699264??? 18: 2696628??? 20: 2699264??? 22: 2696628
>>>>   ?24: 2699264??? 26: 2696628??? 28: 2699264??? 30: 2696628
>>>>   ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
>>>>   ?40: 2699264??? 42: 2699264??? 44: 2696628??? 46: 2696628
>>>>   ?48: 2696628??? 50: 2699264??? 52: 2699264??? 54: 2696628
>>>>   ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
>>>>   ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2696628
>>>>   ?72: 2699264??? 74: 2696628??? 76: 2696628??? 78: 2699264
>>>>   ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
>>>>   ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2699264
>>>>   ?96: 2696628??? 98: 2699264?? 100: 2699264?? 102: 2696628
>>>> 104: 2699264?? 106: 2699264?? 108: 2699264?? 110: 2696628
>>>> 112: 2699264?? 114: 2699264?? 116: 2699264?? 118: 2699264
>>>> 120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2699264
>>>> Note: the frequency of all CPUs are almost the same.
>>> Were you expecting smth else ?
>> The frequency of each CPU might have a different value.
>> All value of all CPUs is the same under high pressure.
>> I don't know what the phenomenon is on other platform.
>> Do you know who else tested it?
> So I might have rushed a bit with my previous comment/question: apologies for
> that.
> The numbers above: those are on a fairly idle/lightly loaded system right?
Yes.
> Would you mind having another go with just the arch_freq_get_on_cpu
> implementation beign added and dropping the changes in the cpufreq and
All my tests are done when cpufreq policy is "performance" and OS isn't 
on a high load.
Reading "scaling_cur_freq" or "scaling_cur_freq" for each physical core 
on platform

The testing result for "cpuinfo_cur_freq" with your changes on a fairly 
idle and high loaded system can also be found in this thread.
*A: the result with your changes*
--> Reading "scaling_cur_freq"
 ? 0: 2688720???? 2: 2696628???? 4: 2699264???? 6: 2696628
 ? 8: 2699264??? 10: 2696628??? 12: 2699264??? 14: 2699264
 ?16: 2699264??? 18: 2696628??? 20: 2696628??? 22: 2696628
 ?24: 2699264??? 26: 2696628??? 28: 2696628??? 30: 2696628
 ?32: 2699264??? 34: 2691356??? 36: 2696628??? 38: 2699264
 ?40: 2699264??? 42: 2696628??? 44: 2696628??? 46: 2699264
 ?48: 2699264??? 50: 2696628??? 52: 2696628??? 54: 2696628
 ?56: 2696628??? 58: 2699264??? 60: 2691356??? 62: 2696628
 ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
 ?72: 2696628??? 74: 2696628??? 76: 2699264??? 78: 2696628
 ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
 ?88: 2625456??? 90: 2696628??? 92: 2699264??? 94: 2696628
 ?96: 2696628??? 98: 2696628?? 100: 2699264?? 102: 2699264
104: 2699264?? 106: 2696628?? 108: 2699264?? 110: 2696628
112: 2699264?? 114: 2699264?? 116: 2696628?? 118: 2696628
120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2696628
-->Reading? "cpuinfo_cur_freq"
 ? 0: 2696628???? 2: 2696628???? 4: 2699264???? 6: 2688720
 ? 8: 2699264??? 10: 2700000??? 12: 2696628??? 14: 2698322
 ?16: 2699264??? 18: 2699264??? 20: 2696628??? 22: 2699264
 ?24: 2699264??? 26: 2699264??? 28: 2699264??? 30: 2699264
 ?32: 2699264??? 34: 2693992??? 36: 2696628??? 38: 2696628
 ?40: 2699264??? 42: 2699264??? 44: 2699264??? 46: 2696628
 ?48: 2696628??? 50: 2699264??? 52: 2696628??? 54: 2696628
 ?56: 2699264??? 58: 2699264??? 60: 2696628??? 62: 2699264
 ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2699264
 ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2693992
 ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
 ?88: 2696628??? 90: 2699264??? 92: 2696628??? 94: 2699264
 ?96: 2699264??? 98: 2696628?? 100: 2699264?? 102: 2699264
104: 2691356?? 106: 2699264?? 108: 2699264?? 110: 2699264
112: 2699264?? 114: 2696628?? 116: 2699264?? 118: 2699264
120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628

*B: the result without your changes*
-->Reading "scaling_cur_freq"
 ? 0: 2698245???? 2: 2706690???? 4: 2699649???? 6: 2702105
 ? 8: 2704362??? 10: 2697993??? 12: 2701672??? 14: 2704362
 ?16: 2701052??? 18: 2701052??? 20: 2694385??? 22: 2699650
 ?24: 2706802??? 26: 2702389??? 28: 2698299??? 30: 2698299
 ?32: 2697333??? 34: 2697993??? 36: 2701337??? 38: 2699328
 ?40: 2700330??? 42: 2700330??? 44: 2698019??? 46: 2697697
 ?48: 2699659??? 50: 2701700??? 52: 2703401??? 54: 2701700
 ?56: 2704013??? 58: 2697658??? 60: 2695000??? 62: 2697666
 ?64: 2697902??? 66: 2701052??? 68: 2698245??? 70: 2695789
 ?72: 2701315??? 74: 2696655??? 76: 2693666??? 78: 2695317
 ?80: 2704912??? 82: 2699649??? 84: 2698245??? 86: 2695454
 ?88: 2697966??? 90: 2697959??? 92: 2699319??? 94: 2700680
 ?96: 2695317??? 98: 2698996?? 100: 2700000?? 102: 2700334
104: 2701320?? 106: 2695065?? 108: 2700986?? 110: 2703960
112: 2697635?? 114: 2704421?? 116: 2700680?? 118: 2702040
120: 2700334?? 122: 2697993?? 124: 2700334?? 126: 2705351
-->Reading "cpuinfo_cur_freq"
 ? 0: 2696853???? 2: 2695454???? 4: 2699649???? 6: 2706993
 ? 8: 2706060??? 10: 2704362??? 12: 2704362??? 14: 2697658
 ?16: 2707719??? 18: 2697192??? 20: 2702456??? 22: 2699650
 ?24: 2705782??? 26: 2698299??? 28: 2703061??? 30: 2705802
 ?32: 2700000??? 34: 2700671??? 36: 2701337??? 38: 2697658
 ?40: 2700330??? 42: 2700330??? 44: 2699672??? 46: 2697697
 ?48: 2703061??? 50: 2696610??? 52: 2692542??? 54: 2704406
 ?56: 2695317??? 58: 2699331??? 60: 2698996??? 62: 2702675
 ?64: 2704912??? 66: 2703859??? 68: 2699649??? 70: 2698596
 ?72: 2703908??? 74: 2703355??? 76: 2697658??? 78: 2695317
 ?80: 2702105??? 82: 2707719??? 84: 2702105??? 86: 2699649
 ?88: 2697966??? 90: 2691525??? 92: 2701700??? 94: 2700680
 ?96: 2695317??? 98: 2698996?? 100: 2698666?? 102: 2700334
104: 2690429?? 106: 2707590?? 108: 2700986?? 110: 2701320
112: 2696283?? 114: 2692881?? 116: 2697627?? 118: 2704421
120: 2698996?? 122: 2696321?? 124: 2696655?? 126: 2695000

> then read 'scaling_cur_freq', doing several reads in some intervals ?
It seems that above phenomenon has not a lot to do with reading intervals.
> The change has been tested on RD-N2 model (Neoverse N2 ref platform),
> it has also been discussed here [1]
I doesn't get the testing result on this platform in its thread.
>>>> *--> Step 2: *read 'cpuinfo_cur_freq' in the high memory access pressure.
>>>>   ? 0: 2696628???? 2: 2696628???? 4: 2696628???? 6: 2696628
>>>>   ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2696628
>>>>   ?16: 2696628??? 18: 2696628??? 20: 2696628??? 22: 2696628
>>>>   ?24: 2696628??? 26: 2696628??? 28: 2696628??? 30: 2696628
>>>>   ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
>>>>   ?40: 2696628??? 42: 2696628??? 44: 2696628??? 46: 2696628
>>>>   ?48: 2696628??? 50: 2696628??? 52: 2696628??? 54: 2696628
>>>>   ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
>>>>   ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
>>>>   ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2696628
>>>>   ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
>>>>   ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2696628
>>>>   ?96: 2696628??? 98: 2696628?? 100: 2696628?? 102: 2696628
>>>> 104: 2696628?? 106: 2696628?? 108: 2696628?? 110: 2696628
>>>> 112: 2696628?? 114: 2696628?? 116: 2696628?? 118: 2696628
>>>> 120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628
>>>>
>>>> *Case 2: setting nohz_full and cpufreq use ondemand governor*
>>>> There is "isolcpus=1-10,41-50 nohz_full=1-10,41-50 rcu_nocbs=1-10,41-50" in
>>>> /proc/cmdline.
>>> Right, so if I remember correctly nohz_full implies rcu_nocbs, so no need to
>>> set that one.
>>> Now, afair, isolcpus will make the selected CPUs to disappear from the
>>> schedulers view (no balancing, no migrating), so unless you affine smth
>>> explicitly to those CPUs, you will not see much of an activity there.
>> Correct.
>>> Need to double check though as it has been a while ...
>>>> *--> Step 1: *setting ondemand governor to all policy and query
>>>> 'cpuinfo_cur_freq' in no pressure case.
>>>> And the frequency of CPUs all are about 400MHz.
>>>> *--> Step 2:* read 'cpuinfo_cur_freq' in the high memory access pressure.
>>>> The high memory access pressure is from the command: "stress-ng -c 64
>>>> --cpu-load 100% --taskset 0-63"
>>> I'm not entirely convinced that this will affine to isolated cpus, especially
>>> that the affinity mask spans all available cpus. If that is the case, no wonder
>>> your isolated cpus are getting wasted being idle. But I would have to double
>>> check how this is being handled.
>>>> The result:
>>>>   ?0: 2696628???? 1:? 400000???? 2:? 400000???? 3:? 400909
>>>>   ?4:? 400000???? 5:? 400000???? 6:? 400000???? 7:? 400000
>>>>   ?8:? 400000???? 9:? 400000??? 10:? 400600??? 11: 2696628
>>>> 12: 2696628??? 13: 2696628??? 14: 2696628??? 15: 2696628
>>>> 16: 2696628??? 17: 2696628??? 18: 2696628??? 19: 2696628
>>>> 20: 2696628??? 21: 2696628??? 22: 2696628??? 23: 2696628
>>>> 24: 2696628??? 25: 2696628??? 26: 2696628??? 27: 2696628
>>>> 28: 2696628??? 29: 2696628??? 30: 2696628??? 31: 2696628
>>>> 32: 2696628??? 33: 2696628??? 34: 2696628??? 35: 2696628
>>>> 36: 2696628??? 37: 2696628??? 38: 2696628??? 39: 2696628
>>>> 40: 2696628??? 41:? 400000??? 42:? 400000??? 43:? 400000
>>>> 44:? 400000??? 45:? 398847??? 46:? 400000??? 47:? 400000
>>>> 48:? 400000??? 49:? 400000??? 50:? 400000??? 51: 2696628
>>>> 52: 2696628??? 53: 2696628??? 54: 2696628??? 55: 2696628
>>>> 56: 2696628??? 57: 2696628??? 58: 2696628??? 59: 2696628
>>>> 60: 2696628??? 61: 2696628??? 62: 2696628??? 63: 2699264
>>>>
>>>> Note:
>>>> (1) The frequency of 1-10 and 41-50 CPUs work on the lowest frequency.
>>>>   ???? It turned out that nohz full was already work.
>>>>   ???? I guess that stress-ng cannot use the CPU in the range of nohz full.
>>>>   ???? Because the CPU frequency will be increased to 2.7G by binding CPU to
>>>> other application.
>>>> (2) The frequency of the nohz full core is calculated by get() callback
>>>> according to ftrace.
>>> It is as there is no sched tick on those, and apparently there is nothing
>>> running on them either.
>> Yes.
>> If we select your approach and the above phenomenon is normal,
>> the large frequency discrepancy issue can be resolved for CPUs with sched
>> tick by the way.
>> But the nohz full cores still have to face this issue. So this patch is also
>> needed.
>>
> Yes, nohz cores full have to be handled by the cpufreq driver.
Correct. So we still have to face the issue in this patch and push this 
patch.
Beata, would you please review this patch?


/Huisong
>
> ---
> [1] https://lore.kernel.org/lkml/ZIHpd6unkOtYVEqP at e120325.cambridge.arm.com/T/#m4e74cb5a0aaa353c60fedc6cfb95ab7a6e381e3c
> ---
> BR
> Beata
>> BR
>> /huisong
>>> Unless I am missing smth.
>>>
>>> ---
>>> BR
>>> Beata
>>>
>>>> [1] https://lore.kernel.org/lkml/20230418113459.12860-7-sumitg at nvidia.com/
>>>> [2] https://lore.kernel.org/lkml/20231127160838.1403404-3-beata.michalska at arm.com/
>>>>> Many thanks,
>>>>> Ionela.
>>>>>
>>>>>> /Huisong
>>>>>>
>>>>>>>>> [1] https://lore.kernel.org/lkml/20231127160838.1403404-1-beata.michalska at arm.com/
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Ionela.
>>>>>>>>>
>>>>>>>>>> This patch adds a interface, cpc_read_arch_counters_on_cpu, to read
>>>>>>>>>> delivered and reference performance counter together. According to my
>>>>>>>>>> test[4], the discrepancy of cpu current frequency in the
>>>>>>>>>> scenarios with
>>>>>>>>>> high memory access pressure is lower than 0.2% by stress-ng
>>>>>>>>>> application.
>>>>>>>>>>
>>>>>>>>>> [1] https://lore.kernel.org/all/20231025093847.3740104-4-zengheng4 at huawei.com/
>>>>>>>>>> [2] https://lore.kernel.org/all/20230328193846.8757-1-yang at os.amperecomputing.com/
>>>>>>>>>> [3]
>>>>>>>>>> https://lore.kernel.org/all/20230418113459.12860-7-sumitg at nvidia.com/
>>>>>>>>>>
>>>>>>>>>> [4] My local test:
>>>>>>>>>> The testing platform enable SMT and include 128 logical CPU in total,
>>>>>>>>>> and CPU base frequency is 2.7GHz. Reading "cpuinfo_cur_freq" for each
>>>>>>>>>> physical core on platform during the high memory access pressure from
>>>>>>>>>> stress-ng, and the output is as follows:
>>>>>>>>>>    ? 0: 2699133???? 2: 2699942???? 4: 2698189???? 6: 2704347
>>>>>>>>>>    ? 8: 2704009??? 10: 2696277??? 12: 2702016??? 14: 2701388
>>>>>>>>>>    ?16: 2700358??? 18: 2696741??? 20: 2700091??? 22: 2700122
>>>>>>>>>>    ?24: 2701713??? 26: 2702025??? 28: 2699816??? 30: 2700121
>>>>>>>>>>    ?32: 2700000??? 34: 2699788??? 36: 2698884??? 38: 2699109
>>>>>>>>>>    ?40: 2704494??? 42: 2698350??? 44: 2699997??? 46: 2701023
>>>>>>>>>>    ?48: 2703448??? 50: 2699501??? 52: 2700000??? 54: 2699999
>>>>>>>>>>    ?56: 2702645??? 58: 2696923??? 60: 2697718??? 62: 2700547
>>>>>>>>>>    ?64: 2700313??? 66: 2700000??? 68: 2699904??? 70: 2699259
>>>>>>>>>>    ?72: 2699511??? 74: 2700644??? 76: 2702201??? 78: 2700000
>>>>>>>>>>    ?80: 2700776??? 82: 2700364??? 84: 2702674??? 86: 2700255
>>>>>>>>>>    ?88: 2699886??? 90: 2700359??? 92: 2699662??? 94: 2696188
>>>>>>>>>>    ?96: 2705454??? 98: 2699260?? 100: 2701097?? 102: 2699630
>>>>>>>>>> 104: 2700463?? 106: 2698408?? 108: 2697766?? 110: 2701181
>>>>>>>>>> 112: 2699166?? 114: 2701804?? 116: 2701907?? 118: 2701973
>>>>>>>>>> 120: 2699584?? 122: 2700474?? 124: 2700768?? 126: 2701963
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Huisong Li <lihuisong at huawei.com>
>>>>>>>>>> ---
>>>> [snip]
>>>>> .
>>> .
> .


From krzysztof.kozlowski at linaro.org  Tue Feb  6 00:02:48 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 6 Feb 2024 09:02:48 +0100
Subject: [PATCH] MAINTAINERS: Remove Tomasz from Samsung clock and pinctrl
 entries
In-Reply-To: <20240201140134.4345-1-tomasz.figa@gmail.com>
References: <20240201140134.4345-1-tomasz.figa@gmail.com>
Message-ID: <12615b4d-5296-4fd7-9395-6a7b6df27764@linaro.org>

On 01/02/2024 15:01, Tomasz Figa wrote:
> I have been no longer at Samsung for a long time, the platforms
> that I am knowledgable about (S3C24xx, S3C64xx, Exynos 4) are no longer
> relevant and we have people with better capabilities as maintainers
> already, so let me remove myself. Thanks for the nice collaboration
> everyone!
> 
> Signed-off-by: Tomasz Figa <tomasz.figa at gmail.com>

Thanks Tomasz for the work!

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb  6 00:03:22 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 06 Feb 2024 09:03:22 +0100
Subject: [PATCH] MAINTAINERS: Remove Tomasz from Samsung clock and
 pinctrl entries
In-Reply-To: <20240201140134.4345-1-tomasz.figa@gmail.com>
References: <20240201140134.4345-1-tomasz.figa@gmail.com>
Message-ID: <170720660257.7713.7995799928562429624.b4-ty@linaro.org>


On Thu, 01 Feb 2024 23:01:34 +0900, Tomasz Figa wrote:
> I have been no longer at Samsung for a long time, the platforms
> that I am knowledgable about (S3C24xx, S3C64xx, Exynos 4) are no longer
> relevant and we have people with better capabilities as maintainers
> already, so let me remove myself. Thanks for the nice collaboration
> everyone!
> 
> 
> [...]

Applied, thanks!

[1/1] MAINTAINERS: Remove Tomasz from Samsung clock and pinctrl entries
      https://git.kernel.org/krzk/linux/c/dde76e324c65969fda35165694b5e982d0033bf7

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From alexander.stein at ew.tq-group.com  Tue Feb  6 00:04:58 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue,  6 Feb 2024 09:04:58 +0100
Subject: [PATCH v2 1/2] arm64: dts: freescale: imx8-ss-dma: Fix edma3's location
Message-ID: <20240206080459.1741172-1-alexander.stein@ew.tq-group.com>

Sort nodes by base address. edma3 comes later in the memory map.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 .../arm64/boot/dts/freescale/imx8-ss-dma.dtsi | 46 +++++++++----------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
index b0bb77150adcc..a180893ac81e0 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
@@ -192,29 +192,6 @@ edma2: dma-controller at 5a1f0000 {
 				<&pd IMX_SC_R_DMA_2_CH15>;
 	};
 
-	edma3: dma-controller at 5a9f0000 {
-		compatible = "fsl,imx8qm-edma";
-		reg = <0x5a9f0000 0x90000>;
-		#dma-cells = <3>;
-		dma-channels = <8>;
-		interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>;
-		power-domains = <&pd IMX_SC_R_DMA_3_CH0>,
-				<&pd IMX_SC_R_DMA_3_CH1>,
-				<&pd IMX_SC_R_DMA_3_CH2>,
-				<&pd IMX_SC_R_DMA_3_CH3>,
-				<&pd IMX_SC_R_DMA_3_CH4>,
-				<&pd IMX_SC_R_DMA_3_CH5>,
-				<&pd IMX_SC_R_DMA_3_CH6>,
-				<&pd IMX_SC_R_DMA_3_CH7>;
-	};
-
 	spi0_lpcg: clock-controller at 5a400000 {
 		compatible = "fsl,imx8qxp-lpcg";
 		reg = <0x5a400000 0x10000>;
@@ -460,6 +437,29 @@ flexcan3: can at 5a8f0000 {
 		status = "disabled";
 	};
 
+	edma3: dma-controller at 5a9f0000 {
+		compatible = "fsl,imx8qm-edma";
+		reg = <0x5a9f0000 0x90000>;
+		#dma-cells = <3>;
+		dma-channels = <8>;
+		interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&pd IMX_SC_R_DMA_3_CH0>,
+				<&pd IMX_SC_R_DMA_3_CH1>,
+				<&pd IMX_SC_R_DMA_3_CH2>,
+				<&pd IMX_SC_R_DMA_3_CH3>,
+				<&pd IMX_SC_R_DMA_3_CH4>,
+				<&pd IMX_SC_R_DMA_3_CH5>,
+				<&pd IMX_SC_R_DMA_3_CH6>,
+				<&pd IMX_SC_R_DMA_3_CH7>;
+	};
+
 	i2c0_lpcg: clock-controller at 5ac00000 {
 		compatible = "fsl,imx8qxp-lpcg";
 		reg = <0x5ac00000 0x10000>;
-- 
2.34.1



From alexander.stein at ew.tq-group.com  Tue Feb  6 00:04:59 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue,  6 Feb 2024 09:04:59 +0100
Subject: [PATCH v2 2/2] arm64: dts: imx8: Fix lpuart DMA channel order
In-Reply-To: <20240206080459.1741172-1-alexander.stein@ew.tq-group.com>
References: <20240206080459.1741172-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240206080459.1741172-2-alexander.stein@ew.tq-group.com>

Bindings say DMA channels are in order Rx, Tx. Adjust the DT nodes
accordingly. While at it, use defines for the flags.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
Changes in v2:
* Use defines from dt-bindings/dma/fsl-edma.h
* Switch DMA channel flags as well

 arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
index a180893ac81e0..cab3468b1875e 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
@@ -5,6 +5,7 @@
  */
 
 #include <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/dma/fsl-edma.h>
 #include <dt-bindings/firmware/imx/rsrc.h>
 
 dma_ipg_clk: clock-dma-ipg {
@@ -93,8 +94,8 @@ lpuart0: serial at 5a060000 {
 		assigned-clocks = <&clk IMX_SC_R_UART_0 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <80000000>;
 		power-domains = <&pd IMX_SC_R_UART_0>;
-		dma-names = "tx","rx";
-		dmas = <&edma2 9 0 0>, <&edma2 8 0 1>;
+		dma-names = "rx", "tx";
+		dmas = <&edma2 8 0 FSL_EDMA_RX>, <&edma2 9 0 0>;
 		status = "disabled";
 	};
 
@@ -107,8 +108,8 @@ lpuart1: serial at 5a070000 {
 		assigned-clocks = <&clk IMX_SC_R_UART_1 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <80000000>;
 		power-domains = <&pd IMX_SC_R_UART_1>;
-		dma-names = "tx","rx";
-		dmas = <&edma2 11 0 0>, <&edma2 10 0 1>;
+		dma-names = "rx", "tx";
+		dmas = <&edma2 10 0 FSL_EDMA_RX>, <&edma2 11 0 0>;
 		status = "disabled";
 	};
 
@@ -121,8 +122,8 @@ lpuart2: serial at 5a080000 {
 		assigned-clocks = <&clk IMX_SC_R_UART_2 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <80000000>;
 		power-domains = <&pd IMX_SC_R_UART_2>;
-		dma-names = "tx","rx";
-		dmas = <&edma2 13 0 0>, <&edma2 12 0 1>;
+		dma-names = "rx", "tx";
+		dmas = <&edma2 12 0 FSL_EDMA_RX>, <&edma2 13 0 0>;
 		status = "disabled";
 	};
 
@@ -135,8 +136,8 @@ lpuart3: serial at 5a090000 {
 		assigned-clocks = <&clk IMX_SC_R_UART_3 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <80000000>;
 		power-domains = <&pd IMX_SC_R_UART_3>;
-		dma-names = "tx","rx";
-		dmas = <&edma2 15 0 0>, <&edma2 14 0 1>;
+		dma-names = "rx", "tx";
+		dmas = <&edma2 14 0 FSL_EDMA_RX>, <&edma2 15 0 0>;
 		status = "disabled";
 	};
 
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Tue Feb  6 00:05:19 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 06 Feb 2024 09:05:19 +0100
Subject: [PATCH v3] arm64: dts: exynos: Add SPI nodes for Exynos850
In-Reply-To: <20240201183025.14566-1-semen.protsenko@linaro.org>
References: <20240201183025.14566-1-semen.protsenko@linaro.org>
Message-ID: <170720671934.8244.1763443195474086978.b4-ty@linaro.org>


On Thu, 01 Feb 2024 12:30:25 -0600, Sam Protsenko wrote:
> Some USI blocks can be configured as SPI controllers. Add corresponding
> SPI nodes to Exynos850 SoC device tree.
> 
> 

Applied, thanks!

[1/1] arm64: dts: exynos: Add SPI nodes for Exynos850
      https://git.kernel.org/krzk/linux/c/2ef4cddd31950f563b5642e34d8fa38ad2352ef0

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From shawnguo2 at yeah.net  Tue Feb  6 00:11:32 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 16:11:32 +0800
Subject: [PATCH v4 3/4] ARM: imx_v6_v7_defconfig: enable the vf610 gpio
 driver
In-Reply-To: <20240124205900.14791-4-martin@kaiser.cx>
References: <20240124205900.14791-1-martin@kaiser.cx>
 <20240124205900.14791-4-martin@kaiser.cx>
Message-ID: <ZcHptCbteajfAWL7@dragon>

On Wed, Jan 24, 2024 at 09:58:59PM +0100, Martin Kaiser wrote:
> The vf610 gpio driver is used in i.MX7ULP chips (Cortex A7, ARMv7-A
> architecture). Enable it in imx_v6_v7_defconfig.
> 
> (vf610 gpio used to be enabled by default for all i.MX chips. This was
> changed recently as most i.MX chips don't need this driver.)
> 
> Signed-off-by: Martin Kaiser <martin at kaiser.cx>

Applied, thanks!



From shawnguo2 at yeah.net  Tue Feb  6 00:11:58 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 16:11:58 +0800
Subject: [PATCH v4 4/4] arm64: defconfig: enable the vf610 gpio driver
In-Reply-To: <20240124205900.14791-5-martin@kaiser.cx>
References: <20240124205900.14791-1-martin@kaiser.cx>
 <20240124205900.14791-5-martin@kaiser.cx>
Message-ID: <ZcHpzuagGIhz/mmM@dragon>

On Wed, Jan 24, 2024 at 09:59:00PM +0100, Martin Kaiser wrote:
> The vf610 gpio driver is used in i.MX8QM, DXL, ULP and i.MX93 chips.
> Enable it in arm64 defconfig.
> 
> (vf610 gpio used to be enabled by default for all i.MX chips. This was
> changed recently as most i.MX chips don't need this driver.)
> 
> Signed-off-by: Martin Kaiser <martin at kaiser.cx>

Applied, thanks!



From neil.armstrong at linaro.org  Tue Feb  6 00:15:07 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 06 Feb 2024 09:15:07 +0100
Subject: (subset) [PATCH V8 00/12] soc: imx8mp: Add support for HDMI
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <170720730748.2682504.5723443718654255772.b4-ty@linaro.org>

Hi,

On Sat, 03 Feb 2024 10:52:40 -0600, Adam Ford wrote:
> The i.MX8M Plus has an HDMI controller, but it depends on two
> other systems, the Parallel Video Interface (PVI) and the
> HDMI PHY from Samsung. The LCDIF controller generates the display
> and routes it to the PVI which converts passes the parallel video
> to the HDMI bridge.  The HDMI system has a corresponding power
> domain controller whose driver was partially written, but the
> device tree for it was never applied, so some changes to the
> power domain should be harmless because they've not really been
> used yet.
> 
> [...]

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git (drm-misc-next)

[09/12] dt-bindings: display: imx: add binding for i.MX8MP HDMI TX
        https://cgit.freedesktop.org/drm/drm-misc/commit/?id=8933d29e7703f6f905bc84186b915b0ab4fe03bb
[10/12] drm/bridge: imx: add bridge wrapper driver for i.MX8MP DWC HDMI
        https://cgit.freedesktop.org/drm/drm-misc/commit/?id=1f36d634670d8001a45fe2f2dcae546819f9c7d8

-- 
Neil



From o.rempel at pengutronix.de  Tue Feb  6 00:17:36 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Tue, 6 Feb 2024 09:17:36 +0100
Subject: [PATCH v3 00/17] kexec: Allow preservation of ftrace buffers
In-Reply-To: <20240117144704.602-1-graf@amazon.com>
References: <20240117144704.602-1-graf@amazon.com>
Message-ID: <ZcHrIJ7lxpbkm5sc@pengutronix.de>

Hi Alexander,

Nice work!

On Wed, Jan 17, 2024 at 02:46:47PM +0000, Alexander Graf wrote:
> Kexec today considers itself purely a boot loader: When we enter the new
> kernel, any state the previous kernel left behind is irrelevant and the
> new kernel reinitializes the system.
> 
> However, there are use cases where this mode of operation is not what we
> actually want. In virtualization hosts for example, we want to use kexec
> to update the host kernel while virtual machine memory stays untouched.
> When we add device assignment to the mix, we also need to ensure that
> IOMMU and VFIO states are untouched. If we add PCIe peer to peer DMA, we
> need to do the same for the PCI subsystem. If we want to kexec while an
> SEV-SNP enabled virtual machine is running, we need to preserve the VM
> context pages and physical memory. See James' and my Linux Plumbers
> Conference 2023 presentation for details:
> 
>   https://lpc.events/event/17/contributions/1485/
> 
> To start us on the journey to support all the use cases above, this
> patch implements basic infrastructure to allow hand over of kernel state
> across kexec (Kexec HandOver, aka KHO). As example target, we use ftrace:
> With this patch set applied, you can read ftrace records from the
> pre-kexec environment in your post-kexec one. This creates a very powerful
> debugging and performance analysis tool for kexec. It's also slightly
> easier to reason about than full blown VFIO state preservation.
> 
> == Alternatives ==
> 
> There are alternative approaches to (parts of) the problems above:
> 
>   * Memory Pools [1] - preallocated persistent memory region + allocator
>   * PRMEM [2] - resizable persistent memory regions with fixed metadata
>                 pointer on the kernel command line + allocator
>   * Pkernfs [3] - preallocated file system for in-kernel data with fixed
>                   address location on the kernel command line
>   * PKRAM [4] - handover of user space pages using a fixed metadata page
>                 specified via command line
> 
> All of the approaches above fundamentally have the same problem: They
> require the administrator to explicitly carve out a physical memory
> location because they have no mechanism outside of the kernel command
> line to pass data (including memory reservations) between kexec'ing
> kernels.
> 
> KHO provides that base foundation. We will determine later whether we
> still need any of the approaches above for fast bulk memory handover of for
> example IOMMU page tables. But IMHO they would all be users of KHO, with
> KHO providing the foundational primitive to pass metadata and bulk memory
> reservations as well as provide easy versioning for data.
> 
> == Overview ==
> 
> We introduce a metadata file that the kernels pass between each other. How
> they pass it is architecture specific. The file's format is a Flattened
> Device Tree (fdt) which has a generator and parser already included in
> Linux. When the root user enables KHO through /sys/kernel/kho/active, the
> kernel invokes callbacks to every driver that supports KHO to serialize
> its state. When the actual kexec happens, the fdt is part of the image
> set that we boot into. In addition, we keep a "scratch region" available
> for kexec: A physically contiguous memory region that is guaranteed to
> not have any memory that KHO would preserve.  The new kernel bootstraps
> itself using the scratch region and sets all handed over memory as in use.
> When drivers initialize that support KHO, they introspect the fdt and
> recover their state from it. This includes memory reservations, where the
> driver can either discard or claim reservations.
> 
> == Limitations ==
> 
> I currently only implemented file based kexec. The kernel interfaces
> in the patch set are already in place to support user space kexec as well,
> but I have not implemented it yet inside kexec tools.
> 
> == How to Use ==
> 
> To use the code, please boot the kernel with the "kho_scratch=" command
> line parameter set: "kho_scratch=512M". KHO requires a scratch region.
> 
> Make sure to fill ftrace with contents that you want to observe after
> kexec.  Then, before you invoke file based "kexec -l", activate KHO:
> 
>   # echo 1 > /sys/kernel/kho/active
>   # kexec -l Image --initrd=initrd -s
>   # kexec -e
> 
> The new kernel will boot up and contain the previous kernel's trace
> buffers in /sys/kernel/debug/tracing/trace.

Assuming:
- we wont to start tracing as early as possible, before rootfs
  or initrd would be able to configure it.
- traces are stored on a different device, not RAM. For example NVMEM.
- Location of NVMEM is different for different board types, but
  bootloader is able to give the right configuration to the kernel.

What would be the best, acceptable for mainline, way to provide this
kind of configuration? At least part of this information do not
describes devices or device states, this would not fit in to devicetree
universe. Amount of possible information would not fit in to bootconfig
too.

Other more or less overlapping use case I have in mind is a netbootable
embedded system with a requirement to boot as fast as possible. Since
bootloader already established a link and got all needed ip
configuration, it would be able to hand over etherent controller and ip
configuration states. Wille be the KHO the way to go for this use case?

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 neil.armstrong at linaro.org  Tue Feb  6 00:17:47 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 6 Feb 2024 09:17:47 +0100
Subject: [PATCH 5/5] drm/panel: simple: push blanking limit on RK32FN48H
In-Reply-To: <20240205-ltdc_mp13-v1-5-116d43ebba75@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-116d43ebba75@foss.st.com>
 <20240205-ltdc_mp13-v1-5-116d43ebba75@foss.st.com>
Message-ID: <30648f19-f25b-49cc-94f1-213bc96c67f4@linaro.org>

On 05/02/2024 10:26, Raphael Gallais-Pou wrote:
> Push horizontal front porch and vertical back porch blanking limit.
> This allows to get a 60 fps sharp.
> 
> Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
> ---
>   drivers/gpu/drm/panel/panel-simple.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index 7b286382ffb4..10b361d603be 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -3516,10 +3516,10 @@ static const struct display_timing rocktech_rk043fn48h_timing = {
>   	.pixelclock = { 6000000, 9000000, 12000000 },
>   	.hactive = { 480, 480, 480 },
>   	.hback_porch = { 8, 43, 43 },
> -	.hfront_porch = { 2, 8, 8 },
> +	.hfront_porch = { 2, 8, 10 },
>   	.hsync_len = { 1, 1, 1 },
>   	.vactive = { 272, 272, 272 },
> -	.vback_porch = { 2, 12, 12 },
> +	.vback_porch = { 2, 12, 26 },
>   	.vfront_porch = { 1, 4, 4 },
>   	.vsync_len = { 1, 10, 10 },
>   	.flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW |
> 

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Tue Feb  6 00:17:59 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 6 Feb 2024 09:17:59 +0100
Subject: [PATCH 4/5] drm/panel: simple: fix flags on RK043FN48H
In-Reply-To: <20240205-ltdc_mp13-v1-4-072d24bf1b36@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
 <20240205-ltdc_mp13-v1-4-072d24bf1b36@foss.st.com>
Message-ID: <b78d2ca4-9516-4d7e-9ec0-3fe93894523b@linaro.org>

On 05/02/2024 10:06, Raphael Gallais-Pou wrote:
> DISPLAY_FLAGS_SYNC_POSEDGE is missing in the flags on the default
> timings. When overriding the default mode with one described in the
> device tree, the mode does not get acked because of this missing flag.
> Moreover since the panel is driven by the positive edge it makes sense
> to add it here.
> 
> Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
> ---
>   drivers/gpu/drm/panel/panel-simple.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index 2214cb09678c..7b286382ffb4 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -3523,7 +3523,8 @@ static const struct display_timing rocktech_rk043fn48h_timing = {
>   	.vfront_porch = { 1, 4, 4 },
>   	.vsync_len = { 1, 10, 10 },
>   	.flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW |
> -		 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE,
> +		 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
> +		 DISPLAY_FLAGS_SYNC_POSEDGE,
>   };
>   
>   static const struct panel_desc rocktech_rk043fn48h = {
> 

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From shawnguo2 at yeah.net  Tue Feb  6 00:23:29 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 16:23:29 +0800
Subject: [PATCH v1 0/2] arm64: dts: freescale: imx8qm: add apalis eval
 v1.2 carrier board
In-Reply-To: <20240125101457.9873-1-francesco@dolcini.it>
References: <20240125101457.9873-1-francesco@dolcini.it>
Message-ID: <ZcHsgUoiB0JCp6U0@dragon>

On Thu, Jan 25, 2024 at 11:14:55AM +0100, Francesco Dolcini wrote:
> From: Francesco Dolcini <francesco.dolcini at toradex.com>
> 
> This series introduces support for the new Apalis Evaluation Board v1.2
> for imx8qm-based Toradex SoM. With the introduction of board v1.2, a common
> board configurations dtsi file and two version-specific dtsi board files were
> added. Consequently, four possible dts files are generated to support the
> range of different SoM versions. Additionally, updates have been made to dts
> freescale/Makefile and arm/fsl.yaml to accommodate the changes.
> 
> 
> Joao Paulo Goncalves (2):
>   dt-bindings: arm: fsl: add imx8qm apalis eval v1.2 carrier board
>   arm64: dts: freescale: imx8qm: add apalis eval v1.2 carrier board

Applied both, thanks!



From yangyicong at huawei.com  Tue Feb  6 00:20:16 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 6 Feb 2024 16:20:16 +0800
Subject: [RESEND v4] perf stat: Support per-cluster aggregation
Message-ID: <20240206082016.22292-1-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Some platforms have 'cluster' topology and CPUs in the cluster will
share resources like L3 Cache Tag (for HiSilicon Kunpeng SoC) or L2
cache (for Intel Jacobsville). Currently parsing and building cluster
topology have been supported since [1].

perf stat has already supported aggregation for other topologies like
die or socket, etc. It'll be useful to aggregate per-cluster to find
problems like L3T bandwidth contention.

This patch add support for "--per-cluster" option for per-cluster
aggregation. Also update the docs and related test. The output will
be like:

[root at localhost tmp]# perf stat -a -e LLC-load --per-cluster -- sleep 5

 Performance counter stats for 'system wide':

S56-D0-CLS158    4      1,321,521,570      LLC-load
S56-D0-CLS594    4        794,211,453      LLC-load
S56-D0-CLS1030    4             41,623      LLC-load
S56-D0-CLS1466    4             41,646      LLC-load
S56-D0-CLS1902    4             16,863      LLC-load
S56-D0-CLS2338    4             15,721      LLC-load
S56-D0-CLS2774    4             22,671      LLC-load
[...]

On a legacy system without cluster or cluster support, the output will
be look like:
[root at localhost perf]# perf stat -a -e cycles --per-cluster -- sleep 1

 Performance counter stats for 'system wide':

S56-D0-CLS0   64         18,011,485      cycles
S7182-D0-CLS0   64         16,548,835      cycles

Note that this patch doesn't mix the cluster information in the outputs
of --per-core to avoid breaking any tools/scripts using it.

Note that perf recently supports "--per-cache" aggregation, but it's not
the same with the cluster although cluster CPUs may share some cache
resources. For example on my machine all clusters within a die share the
same L3 cache:
$ cat /sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list
0-31
$ cat /sys/devices/system/cpu/cpu0/topology/cluster_cpus_list
0-3

[1] commit c5e22feffdd7 ("topology: Represent clusters of CPUs within a die")
Tested-by: Jie Zhan <zhanjie9 at hisilicon.com>
Reviewed-by: Tim Chen <tim.c.chen at linux.intel.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
Change since v3:
- Rebase on v6.7-rc4 and resolve the conflicts
Link: https://lore.kernel.org/all/20230404104951.27537-1-yangyicong at huawei.com/

Change since v2:
- Use 0 as cluster ID on legacy system without cluster support, keep consistenct
  with what --per-die does.
Link: https://lore.kernel.org/all/20230328112717.19573-1-yangyicong at huawei.com/

Change since v1:
- Provides the information about how to map the cluster to the CPUs in the manual
- Thanks the review from Tim and test from Jie.
Link: https://lore.kernel.org/all/20230313085911.61359-1-yangyicong at huawei.com/

 tools/perf/Documentation/perf-stat.txt        | 11 ++++
 tools/perf/builtin-stat.c                     | 52 +++++++++++++++++--
 .../tests/shell/lib/perf_json_output_lint.py  |  4 +-
 tools/perf/tests/shell/lib/stat_output.sh     | 12 +++++
 tools/perf/tests/shell/stat+csv_output.sh     |  2 +
 tools/perf/tests/shell/stat+json_output.sh    | 13 +++++
 tools/perf/tests/shell/stat+std_output.sh     |  2 +
 tools/perf/util/cpumap.c                      | 32 +++++++++++-
 tools/perf/util/cpumap.h                      | 19 +++++--
 tools/perf/util/env.h                         |  1 +
 tools/perf/util/stat-display.c                | 13 +++++
 tools/perf/util/stat.h                        |  1 +
 12 files changed, 153 insertions(+), 9 deletions(-)

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 5af2e432b54f..29756a87ab6f 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -308,6 +308,14 @@ use --per-die in addition to -a. (system-wide).  The output includes the
 die number and the number of online processors on that die. This is
 useful to gauge the amount of aggregation.
 
+--per-cluster::
+Aggregate counts per processor cluster for system-wide mode measurement.  This
+is a useful mode to detect imbalance between clusters.  To enable this mode,
+use --per-cluster in addition to -a. (system-wide).  The output includes the
+cluster number and the number of online processors on that cluster. This is
+useful to gauge the amount of aggregation. The information of cluster ID and
+related CPUs can be gotten from /sys/devices/system/cpu/cpuX/topology/cluster_{id, cpus}.
+
 --per-cache::
 Aggregate counts per cache instance for system-wide mode measurements.  By
 default, the aggregation happens for the cache level at the highest index
@@ -396,6 +404,9 @@ Aggregate counts per processor socket for system-wide mode measurements.
 --per-die::
 Aggregate counts per processor die for system-wide mode measurements.
 
+--per-cluster::
+Aggregate counts perf processor cluster for system-wide mode measurements.
+
 --per-cache::
 Aggregate counts per cache instance for system-wide mode measurements.  By
 default, the aggregation happens for the cache level at the highest index
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 5fe9abc6a524..6bba1a89d030 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1238,6 +1238,8 @@ static struct option stat_options[] = {
 		     "aggregate counts per processor socket", AGGR_SOCKET),
 	OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
 		     "aggregate counts per processor die", AGGR_DIE),
+	OPT_SET_UINT(0, "per-cluster", &stat_config.aggr_mode,
+		     "aggregate counts per processor cluster", AGGR_CLUSTER),
 	OPT_CALLBACK_OPTARG(0, "per-cache", &stat_config.aggr_mode, &stat_config.aggr_level,
 			    "cache level", "aggregate count at this cache level (Default: LLC)",
 			    parse_cache_level),
@@ -1428,6 +1430,7 @@ static struct aggr_cpu_id aggr_cpu_id__cache(struct perf_cpu cpu, void *data)
 static const char *const aggr_mode__string[] = {
 	[AGGR_CORE] = "core",
 	[AGGR_CACHE] = "cache",
+	[AGGR_CLUSTER] = "cluster",
 	[AGGR_DIE] = "die",
 	[AGGR_GLOBAL] = "global",
 	[AGGR_NODE] = "node",
@@ -1455,6 +1458,12 @@ static struct aggr_cpu_id perf_stat__get_cache_id(struct perf_stat_config *confi
 	return aggr_cpu_id__cache(cpu, /*data=*/NULL);
 }
 
+static struct aggr_cpu_id perf_stat__get_cluster(struct perf_stat_config *config __maybe_unused,
+						 struct perf_cpu cpu)
+{
+	return aggr_cpu_id__cluster(cpu, /*data=*/NULL);
+}
+
 static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
 					      struct perf_cpu cpu)
 {
@@ -1507,6 +1516,12 @@ static struct aggr_cpu_id perf_stat__get_die_cached(struct perf_stat_config *con
 	return perf_stat__get_aggr(config, perf_stat__get_die, cpu);
 }
 
+static struct aggr_cpu_id perf_stat__get_cluster_cached(struct perf_stat_config *config,
+							struct perf_cpu cpu)
+{
+	return perf_stat__get_aggr(config, perf_stat__get_cluster, cpu);
+}
+
 static struct aggr_cpu_id perf_stat__get_cache_id_cached(struct perf_stat_config *config,
 							 struct perf_cpu cpu)
 {
@@ -1544,6 +1559,8 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode)
 		return aggr_cpu_id__socket;
 	case AGGR_DIE:
 		return aggr_cpu_id__die;
+	case AGGR_CLUSTER:
+		return aggr_cpu_id__cluster;
 	case AGGR_CACHE:
 		return aggr_cpu_id__cache;
 	case AGGR_CORE:
@@ -1569,6 +1586,8 @@ static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode)
 		return perf_stat__get_socket_cached;
 	case AGGR_DIE:
 		return perf_stat__get_die_cached;
+	case AGGR_CLUSTER:
+		return perf_stat__get_cluster_cached;
 	case AGGR_CACHE:
 		return perf_stat__get_cache_id_cached;
 	case AGGR_CORE:
@@ -1737,6 +1756,21 @@ static struct aggr_cpu_id perf_env__get_cache_aggr_by_cpu(struct perf_cpu cpu,
 	return id;
 }
 
+static struct aggr_cpu_id perf_env__get_cluster_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.cpu != -1) {
+		id.socket = env->cpu[cpu.cpu].socket_id;
+		id.die = env->cpu[cpu.cpu].die_id;
+		id.cluster = env->cpu[cpu.cpu].cluster_id;
+	}
+
+	return id;
+}
+
 static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, void *data)
 {
 	struct perf_env *env = data;
@@ -1744,12 +1778,12 @@ static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, vo
 
 	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
+		 * core_id is relative to socket, die and cluster, we need a
+		 * global id. So we set socket, die id, cluster id and core id.
 		 */
 		id.socket = env->cpu[cpu.cpu].socket_id;
 		id.die = env->cpu[cpu.cpu].die_id;
+		id.cluster = env->cpu[cpu.cpu].cluster_id;
 		id.core = env->cpu[cpu.cpu].core_id;
 	}
 
@@ -1805,6 +1839,12 @@ static struct aggr_cpu_id perf_stat__get_die_file(struct perf_stat_config *confi
 	return perf_env__get_die_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
 
+static struct aggr_cpu_id perf_stat__get_cluster_file(struct perf_stat_config *config __maybe_unused,
+						      struct perf_cpu cpu)
+{
+	return perf_env__get_cluster_aggr_by_cpu(cpu, &perf_stat.session->header.env);
+}
+
 static struct aggr_cpu_id perf_stat__get_cache_file(struct perf_stat_config *config __maybe_unused,
 						    struct perf_cpu cpu)
 {
@@ -1842,6 +1882,8 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode)
 		return perf_env__get_socket_aggr_by_cpu;
 	case AGGR_DIE:
 		return perf_env__get_die_aggr_by_cpu;
+	case AGGR_CLUSTER:
+		return perf_env__get_cluster_aggr_by_cpu;
 	case AGGR_CACHE:
 		return perf_env__get_cache_aggr_by_cpu;
 	case AGGR_CORE:
@@ -1867,6 +1909,8 @@ static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode)
 		return perf_stat__get_socket_file;
 	case AGGR_DIE:
 		return perf_stat__get_die_file;
+	case AGGR_CLUSTER:
+		return perf_stat__get_cluster_file;
 	case AGGR_CACHE:
 		return perf_stat__get_cache_file;
 	case AGGR_CORE:
@@ -2398,6 +2442,8 @@ static int __cmd_report(int argc, const char **argv)
 		     "aggregate counts per processor socket", AGGR_SOCKET),
 	OPT_SET_UINT(0, "per-die", &perf_stat.aggr_mode,
 		     "aggregate counts per processor die", AGGR_DIE),
+	OPT_SET_UINT(0, "per-cluster", &perf_stat.aggr_mode,
+		     "aggregate counts perf processor cluster", AGGR_CLUSTER),
 	OPT_CALLBACK_OPTARG(0, "per-cache", &perf_stat.aggr_mode, &perf_stat.aggr_level,
 			    "cache level",
 			    "aggregate count at this cache level (Default: LLC)",
diff --git a/tools/perf/tests/shell/lib/perf_json_output_lint.py b/tools/perf/tests/shell/lib/perf_json_output_lint.py
index ea55d5ea1ced..abc1fd737782 100644
--- a/tools/perf/tests/shell/lib/perf_json_output_lint.py
+++ b/tools/perf/tests/shell/lib/perf_json_output_lint.py
@@ -15,6 +15,7 @@ ap.add_argument('--event', action='store_true')
 ap.add_argument('--per-core', action='store_true')
 ap.add_argument('--per-thread', action='store_true')
 ap.add_argument('--per-cache', action='store_true')
+ap.add_argument('--per-cluster', action='store_true')
 ap.add_argument('--per-die', action='store_true')
 ap.add_argument('--per-node', action='store_true')
 ap.add_argument('--per-socket', action='store_true')
@@ -49,6 +50,7 @@ def check_json_output(expected_items):
       'cgroup': lambda x: True,
       'cpu': lambda x: isint(x),
       'cache': lambda x: True,
+      'cluster': lambda x: True,
       'die': lambda x: True,
       'event': lambda x: True,
       'event-runtime': lambda x: isfloat(x),
@@ -88,7 +90,7 @@ try:
     expected_items = 7
   elif args.interval or args.per_thread or args.system_wide_no_aggr:
     expected_items = 8
-  elif args.per_core or args.per_socket or args.per_node or args.per_die or args.per_cache:
+  elif args.per_core or args.per_socket or args.per_node or args.per_die or args.per_cluster or args.per_cache:
     expected_items = 9
   else:
     # If no option is specified, don't check the number of items.
diff --git a/tools/perf/tests/shell/lib/stat_output.sh b/tools/perf/tests/shell/lib/stat_output.sh
index 3cc158a64326..c81d6a9f7983 100644
--- a/tools/perf/tests/shell/lib/stat_output.sh
+++ b/tools/perf/tests/shell/lib/stat_output.sh
@@ -97,6 +97,18 @@ check_per_cache_instance()
 	echo "[Success]"
 }
 
+check_per_cluster()
+{
+	echo -n "Checking $1 output: per cluster "
+	if ParanoidAndNotRoot 0
+	then
+		echo "[Skip] paranoid and not root"
+		return
+	fi
+	perf stat --per-cluster -a $2 true
+	echo "[Success]"
+}
+
 check_per_die()
 {
 	echo -n "Checking $1 output: per die "
diff --git a/tools/perf/tests/shell/stat+csv_output.sh b/tools/perf/tests/shell/stat+csv_output.sh
index f1818fa6d9ce..fc2d8cc6e5e0 100755
--- a/tools/perf/tests/shell/stat+csv_output.sh
+++ b/tools/perf/tests/shell/stat+csv_output.sh
@@ -42,6 +42,7 @@ function commachecker()
 	;; "--per-socket")	exp=8
 	;; "--per-node")	exp=8
 	;; "--per-die")		exp=8
+	;; "--per-cluster")	exp=8
 	;; "--per-cache")	exp=8
 	esac
 
@@ -79,6 +80,7 @@ then
 	check_system_wide_no_aggr "CSV" "$perf_cmd"
 	check_per_core "CSV" "$perf_cmd"
 	check_per_cache_instance "CSV" "$perf_cmd"
+	check_per_cluster "CSV" "$perf_cmd"
 	check_per_die "CSV" "$perf_cmd"
 	check_per_socket "CSV" "$perf_cmd"
 else
diff --git a/tools/perf/tests/shell/stat+json_output.sh b/tools/perf/tests/shell/stat+json_output.sh
index 3bc900533a5d..2b9c6212dffc 100755
--- a/tools/perf/tests/shell/stat+json_output.sh
+++ b/tools/perf/tests/shell/stat+json_output.sh
@@ -122,6 +122,18 @@ check_per_cache_instance()
 	echo "[Success]"
 }
 
+check_per_cluster()
+{
+	echo -n "Checking json output: per cluster "
+	if ParanoidAndNotRoot 0
+	then
+		echo "[Skip] paranoia and not root"
+		return
+	fi
+	perf stat -j --per-cluster -a true 2>&1 | $PYTHON $pythonchecker --per-cluster
+	echo "[Success]"
+}
+
 check_per_die()
 {
 	echo -n "Checking json output: per die "
@@ -200,6 +212,7 @@ then
 	check_system_wide_no_aggr
 	check_per_core
 	check_per_cache_instance
+	check_per_cluster
 	check_per_die
 	check_per_socket
 else
diff --git a/tools/perf/tests/shell/stat+std_output.sh b/tools/perf/tests/shell/stat+std_output.sh
index 4fcdd1a9142c..16f61e86afc5 100755
--- a/tools/perf/tests/shell/stat+std_output.sh
+++ b/tools/perf/tests/shell/stat+std_output.sh
@@ -40,6 +40,7 @@ function commachecker()
 	;; "--per-node")	prefix=3
 	;; "--per-die")		prefix=3
 	;; "--per-cache")	prefix=3
+	;; "--per-cluster")	prefix=3
 	esac
 
 	while read line
@@ -99,6 +100,7 @@ then
 	check_system_wide_no_aggr "STD" "$perf_cmd"
 	check_per_core "STD" "$perf_cmd"
 	check_per_cache_instance "STD" "$perf_cmd"
+	check_per_cluster "STD" "$perf_cmd"
 	check_per_die "STD" "$perf_cmd"
 	check_per_socket "STD" "$perf_cmd"
 else
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 0581ee0fa5f2..5907456d42a2 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -222,6 +222,8 @@ static int aggr_cpu_id__cmp(const void *a_pointer, const void *b_pointer)
 		return a->socket - b->socket;
 	else if (a->die != b->die)
 		return a->die - b->die;
+	else if (a->cluster != b->cluster)
+		return a->cluster - b->cluster;
 	else if (a->cache_lvl != b->cache_lvl)
 		return a->cache_lvl - b->cache_lvl;
 	else if (a->cache != b->cache)
@@ -309,6 +311,29 @@ struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data)
 	return id;
 }
 
+int cpu__get_cluster_id(struct perf_cpu cpu)
+{
+	int value, ret = cpu__get_topology_int(cpu.cpu, "cluster_id", &value);
+	return ret ?: value;
+}
+
+struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data)
+{
+	int cluster = cpu__get_cluster_id(cpu);
+	struct aggr_cpu_id id;
+
+	/* There is no cluster_id on legacy system. */
+	if (cluster == -1)
+		cluster = 0;
+
+	id = aggr_cpu_id__die(cpu, data);
+	if (aggr_cpu_id__is_empty(&id))
+		return id;
+
+	id.cluster = cluster;
+	return id;
+}
+
 int cpu__get_core_id(struct perf_cpu cpu)
 {
 	int value, ret = cpu__get_topology_int(cpu.cpu, "core_id", &value);
@@ -320,8 +345,8 @@ 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);
 
-	/* aggr_cpu_id__die returns a struct with socket and die set. */
-	id = aggr_cpu_id__die(cpu, data);
+	/* aggr_cpu_id__die returns a struct with socket die, and cluster set. */
+	id = aggr_cpu_id__cluster(cpu, data);
 	if (aggr_cpu_id__is_empty(&id))
 		return id;
 
@@ -683,6 +708,7 @@ 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->cluster == b->cluster &&
 		a->cache_lvl == b->cache_lvl &&
 		a->cache == b->cache &&
 		a->core == b->core &&
@@ -695,6 +721,7 @@ bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a)
 		a->node == -1 &&
 		a->socket == -1 &&
 		a->die == -1 &&
+		a->cluster == -1 &&
 		a->cache_lvl == -1 &&
 		a->cache == -1 &&
 		a->core == -1 &&
@@ -708,6 +735,7 @@ struct aggr_cpu_id aggr_cpu_id__empty(void)
 		.node = -1,
 		.socket = -1,
 		.die = -1,
+		.cluster = -1,
 		.cache_lvl = -1,
 		.cache = -1,
 		.core = -1,
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 9df2aeb34d3d..26cf76c693f5 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -20,6 +20,8 @@ struct aggr_cpu_id {
 	int socket;
 	/** The die id as read from /sys/devices/system/cpu/cpuX/topology/die_id. */
 	int die;
+	/** The cluster id as read from /sys/devices/system/cpu/cpuX/topology/cluster_id */
+	int cluster;
 	/** The cache level as read from /sys/devices/system/cpu/cpuX/cache/indexY/level */
 	int cache_lvl;
 	/**
@@ -86,6 +88,11 @@ int cpu__get_socket_id(struct perf_cpu cpu);
  * /sys/devices/system/cpu/cpuX/topology/die_id for the given CPU.
  */
 int cpu__get_die_id(struct perf_cpu cpu);
+/**
+ * cpu__get_cluster_id - Returns the cluster id as read from
+ * /sys/devices/system/cpu/cpuX/topology/cluster_id for the given CPU
+ */
+int cpu__get_cluster_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.
@@ -127,9 +134,15 @@ struct aggr_cpu_id aggr_cpu_id__socket(struct perf_cpu 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.
+ * aggr_cpu_id__cluster - Create an aggr_cpu_id with cluster, die and socket
+ * populated with the cluster, die and socket for cpu. The function signature
+ * is compatible with aggr_cpu_id_get_t.
+ */
+struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data);
+/**
+ * aggr_cpu_id__core - Create an aggr_cpu_id with the core, cluster, 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(struct perf_cpu cpu, void *data);
 /**
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 7c527e65c186..2a2c37cc40b7 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -12,6 +12,7 @@ struct perf_cpu_map;
 struct cpu_topology_map {
 	int	socket_id;
 	int	die_id;
+	int	cluster_id;
 	int	core_id;
 };
 
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 8c61f8627ebc..4dfe7d9517a9 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -201,6 +201,9 @@ static void print_aggr_id_std(struct perf_stat_config *config,
 		snprintf(buf, sizeof(buf), "S%d-D%d-L%d-ID%d",
 			 id.socket, id.die, id.cache_lvl, id.cache);
 		break;
+	case AGGR_CLUSTER:
+		snprintf(buf, sizeof(buf), "S%d-D%d-CLS%d", id.socket, id.die, id.cluster);
+		break;
 	case AGGR_DIE:
 		snprintf(buf, sizeof(buf), "S%d-D%d", id.socket, id.die);
 		break;
@@ -251,6 +254,10 @@ static void print_aggr_id_csv(struct perf_stat_config *config,
 		fprintf(config->output, "S%d-D%d-L%d-ID%d%s%d%s",
 			id.socket, id.die, id.cache_lvl, id.cache, sep, aggr_nr, sep);
 		break;
+	case AGGR_CLUSTER:
+		fprintf(config->output, "S%d-D%d-CLS%d%s%d%s",
+			id.socket, id.die, id.cluster, sep, aggr_nr, sep);
+		break;
 	case AGGR_DIE:
 		fprintf(output, "S%d-D%d%s%d%s",
 			id.socket, id.die, sep, aggr_nr, sep);
@@ -300,6 +307,10 @@ static void print_aggr_id_json(struct perf_stat_config *config,
 		fprintf(output, "\"cache\" : \"S%d-D%d-L%d-ID%d\", \"aggregate-number\" : %d, ",
 			id.socket, id.die, id.cache_lvl, id.cache, aggr_nr);
 		break;
+	case AGGR_CLUSTER:
+		fprintf(output, "\"cluster\" : \"S%d-D%d-CLS%d\", \"aggregate-number\" : %d, ",
+			id.socket, id.die, id.cluster, aggr_nr);
+		break;
 	case AGGR_DIE:
 		fprintf(output, "\"die\" : \"S%d-D%d\", \"aggregate-number\" : %d, ",
 			id.socket, id.die, aggr_nr);
@@ -1248,6 +1259,7 @@ static void print_header_interval_std(struct perf_stat_config *config,
 	case AGGR_NODE:
 	case AGGR_SOCKET:
 	case AGGR_DIE:
+	case AGGR_CLUSTER:
 	case AGGR_CACHE:
 	case AGGR_CORE:
 		fprintf(output, "#%*s %-*s cpus",
@@ -1550,6 +1562,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
 	switch (config->aggr_mode) {
 	case AGGR_CORE:
 	case AGGR_CACHE:
+	case AGGR_CLUSTER:
 	case AGGR_DIE:
 	case AGGR_SOCKET:
 	case AGGR_NODE:
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 4357ba114822..d6e5c8787ba2 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -48,6 +48,7 @@ enum aggr_mode {
 	AGGR_GLOBAL,
 	AGGR_SOCKET,
 	AGGR_DIE,
+	AGGR_CLUSTER,
 	AGGR_CACHE,
 	AGGR_CORE,
 	AGGR_THREAD,
-- 
2.24.0



From shawnguo2 at yeah.net  Tue Feb  6 00:25:03 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 16:25:03 +0800
Subject: [PATCH] ARM: dts: imx6ull-dhcom: Remove /omit-if-no-ref/ from
 node usdhc1-pwrseq
In-Reply-To: <20240125124621.16011-1-cniedermaier@dh-electronics.com>
References: <20240125124621.16011-1-cniedermaier@dh-electronics.com>
Message-ID: <ZcHs36/WVSlBQxcQ@dragon>

On Thu, Jan 25, 2024 at 01:46:21PM +0100, Christoph Niedermaier wrote:
> Remove /omit-if-no-ref/ from node usdhc1-pwrseq, because if the compile
> flag -@ (include symbols) is used the node will always be there. In this
> case, GPIO H is not released and therefore cannot be used. Therefore,
> remove this node manually from the corresponding devicetree file and
> don't rely on /omit-if-no-ref/.
> 
> Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>

Applied, thanks!



From vigneshr at ti.com  Tue Feb  6 00:40:02 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 14:10:02 +0530
Subject: [PATCH] arm64: dts: ti: Add phase tags for memory node on J784S4 EVM and AM69 SK
In-Reply-To: <20240119171619.3759205-1-a-nandan@ti.com>
References: <20240119171619.3759205-1-a-nandan@ti.com>
Message-ID: <170719349981.2245010.15227162718815432967.b4-ty@ti.com>

Hi Apurva Nandan,

On Fri, 19 Jan 2024 22:46:19 +0530, Apurva Nandan wrote:
> memory node are required for bootloader operation on TI K3 J784S4 EVM
> and AM69-SK boards for finding the memory size during early boot stage.
> 
> So, align Linux device tree by adding phase tag marking 'bootph-all',
> which is to enable for all bootloader stages.
> 
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: Add phase tags for memory node on J784S4 EVM and AM69 SK
      commit: 28e4e3232777b6a00e483857fe9863f5adbcc10d

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Tue Feb  6 00:40:03 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 14:10:03 +0530
Subject: [PATCH 0/3] arm64: dts: ti: k3-j7200: Add support for multiple CAN nodes in J7200
In-Reply-To: <20240130102044.120483-1-b-kapoor@ti.com>
References: <20240130102044.120483-1-b-kapoor@ti.com>
Message-ID: <170719349983.2245010.1711894811388300123.b4-ty@ti.com>

Hi Bhavya Kapoor,

On Tue, 30 Jan 2024 15:50:41 +0530, Bhavya Kapoor wrote:
> Add CAN Nodes for 18 CAN instances present in main domain and 2 CAN
> instances present in the mcu domain. CAN instance 0 in main domain is
> enabled on transceiver 0 in J7200 SoM. CAN instance 0 and 1 in mcu
> domain and CAN instance 3 in main domain is enabled on transceivers
> 1, 2 and 3 respectively on common processor board.
> 
> Rebased to next-20240130
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/3] arm64: dts: ti: k3-j7200: Add support for CAN nodes
      commit: 03b94719ec31ba0e6580f512cba9100bb560e17b
[2/3] arm64: dts: ti: k3-j7200-som-p0: Add support for CAN instance 0 in main domain
      commit: da23e8d1124b93e468a24247021ace34902a9895
[3/3] arm64: dts: ti: k3-j7200: Add support for multiple CAN instances
      commit: 6b80695f93b2253dbf669323154eb06b162f55ef

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Tue Feb  6 00:40:04 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 14:10:04 +0530
Subject: [PATCH v2 0/2] TI: K3: Fix the device IDs for VTM node.
In-Reply-To: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-0-85fd568b77e3@ti.com>
References: <20240201-b4-upstream-j721s2-fix-vtm-devid-v2-0-85fd568b77e3@ti.com>
Message-ID: <170719349984.2245010.11811390979313823199.b4-ty@ti.com>

Hi Manorit Chawdhry,

On Thu, 01 Feb 2024 13:37:25 +0530, Manorit Chawdhry wrote:
> 


I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/2] arm64: dts: ti: k3-j721s2: Fix power domain for VTM node
      commit: 5ef196ed912e80a1e64936119ced8d7eb5635f0f
[2/2] arm64: dts: ti: k3-j784s4: Fix power domain for VTM node
      commit: e4d252e6d29208aea56d4c04270523e306b1e3c2

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Tue Feb  6 00:40:05 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 14:10:05 +0530
Subject: [PATCH] arm64: dts: ti: k3-am62p-mcu/wakeup: Disable MCU and wakeup R5FSS nodes
In-Reply-To: <20240121134017.374992-1-vaishnav.a@ti.com>
References: <20240121134017.374992-1-vaishnav.a@ti.com>
Message-ID: <170719349986.2245010.7290601708313622270.b4-ty@ti.com>

Hi Vaishnav Achath,

On Sun, 21 Jan 2024 19:10:17 +0530, Vaishnav Achath wrote:
> K3 Remoteproc R5 driver requires reserved memory carveouts and
> mailbox configuration to instantiate the cores successfully.
> Since this is a board level dependency, keep the R5 subsytem
> disabled at SoC dtsi, otherwise it results in probe errors like
> below during AM62P SK boot:
> 
> r5fss at 79000000: reserved memory init failed, ret = -22
> r5fss at 79000000: k3_r5_cluster_rproc_init failed, ret = -22
> r5fss at 78000000: reserved memory init failed, ret = -22
> r5fss at 78000000: k3_r5_cluster_rproc_init failed, ret = -22
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: k3-am62p-mcu/wakeup: Disable MCU and wakeup R5FSS nodes
      commit: dfc90e5f1a0fe0f8124521bc1911e38aa6cd9118

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From richard.xnu.clark at gmail.com  Tue Feb  6 00:42:25 2024
From: richard.xnu.clark at gmail.com (richard clark)
Date: Tue, 6 Feb 2024 16:42:25 +0800
Subject: Question about the ipi_raise filter usage and output
In-Reply-To: <xhsmhmssehp6t.mognet@vschneid-thinkpadt14sgen2i.remote.csb>
References: <ZcDwoce6Ok25K6Dm@FVFF77S0Q05N> <xhsmhmssehp6t.mognet@vschneid-thinkpadt14sgen2i.remote.csb>
Message-ID: <CAJNi4rMiGcP4wdA=1dSOXwYXOKSCWnN8FYxBaFdaAXBqAU_ePQ@mail.gmail.com>

On Tue, Feb 6, 2024 at 12:05?AM Valentin Schneider <vschneid at redhat.com> wrote:
>
> On 05/02/24 14:39, Mark Rutland wrote:
> > [adding Valentin]
> >
>
> Thanks!
>
> > On Mon, Feb 05, 2024 at 08:06:09AM -0500, Steven Rostedt wrote:
> >> On Mon, 5 Feb 2024 10:28:57 +0000
> >> Mark Rutland <mark.rutland at arm.com> wrote:
> >>
> >> > > I try to write below:
> >> > > echo 'target_cpus == 11 && reason == "Function call interrupts"' >
> >> > > events/ipi/ipi_raise/filter
> >> >
> >> > The '=' checks if the target_cpus bitmap *only* contains CPU 11. If the cpumask
> >> > contains other CPUs, the filter will skip the call.
> >> >
> >> > I believe you can use '&' to check whether a cpumask contains a CPU, e.g.
> >> >
> >> >    'target_cpus & 11'
> >>
> >> 11 == 0xb = b1011
> >>
> >> So the above would only be true for CPUs 0,1 and 3 ;-)
> >
> > Sorry, I misunderstood the scalar logic and thought that we treated:
> >
> >       '$mask $OP $scalar', e.g. 'target_cpus & 11'
> >
> > .. as a special case meaning a cpumask with that scalar bit set, i.e.
> >
> >       '$mask $OP CPUS{$scalar}', e.g. 'target_cpus & CPUS{11}'
> >
> > .. but evidently I was wrong.
> >
> >> I think you meant: 'target_cpus & 0x800'
> >>
> >> I tried "1 << 11' but it appears to not allow shifts. I wonder if we should add that?
> >
> > Hmm... shouldn't we make 'CPUS{11}' work for that?
> >
>
> It /should/ already be the case, the user input with the curly braces is
> parsed as a cpulist. So CPUS{11} really does mean CPU11, not a hex value to
> be interpreted as a cpumask.
>
> However...
>
> > From a quick test (below), that doesn't seem to work, though I think it
> > probably should?
> > Have I completely misunderstood how this is supposed to work, or is that a bug?
> >
>
> The CPUS{} thingie only works with an event field that is either declared as a
> cpumask (__cpumask) or a scalar. That's not the case for ipi_raise, the
> target_cpus event field is saved as a "raw" bitmask.
>
> There /should/ have been a warning about the event filter though, but I
> think it's not happening because I'm allowing more than just FILTER_CPUMASK
> in parse_pred() to make it work for scalars. I'll go poke around some more.
>
> Generally for this sort of IPI investigation I'd recommend using the newer
> trace_ipi_send_cpu() and trace_ipi_send_cpumask() (for which CPUS{}
> filtering works).
> If it's only the function call interrupts you're interesting in, have a
> look at trace_csd_queue_cpu().

This should be supported by newer version kernels like v6.5, but I am
using v6.1 and this trace event has not been supported yet... so ipi
is more suitable for me. ipi_entry and ipi_exit is ok, but seems the
filter doesn't support a specific cpu, maybe we need to add this?
>
> > Mark.
>


From neil.armstrong at linaro.org  Tue Feb  6 00:47:49 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Tue, 6 Feb 2024 09:47:49 +0100
Subject: [PATCH 08/18] mfd: khadas-mcu: convert to use maple tree register
 cache
In-Reply-To: <20240206071314.8721-9-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
 <20240206071314.8721-9-liubo03@inspur.com>
Message-ID: <0e47aa27-b28d-4672-a2eb-f906e0e6a5ac@linaro.org>

On 06/02/2024 08:13, Bo Liu wrote:
> The maple tree register cache is based on a much more modern data structure
> than the rbtree cache and makes optimisation choices which are probably
> more appropriate for modern systems than those made by the rbtree cache.
> 
> Signed-off-by: Bo Liu <liubo03 at inspur.com>
> ---
>   drivers/mfd/khadas-mcu.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c
> index 61396d824f16..ba981a788692 100644
> --- a/drivers/mfd/khadas-mcu.c
> +++ b/drivers/mfd/khadas-mcu.c
> @@ -72,7 +72,7 @@ static const struct regmap_config khadas_mcu_regmap_config = {
>   	.max_register	= KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
>   	.volatile_reg	= khadas_mcu_reg_volatile,
>   	.writeable_reg	= khadas_mcu_reg_writeable,
> -	.cache_type	= REGCACHE_RBTREE,
> +	.cache_type	= REGCACHE_MAPLE,
>   };
>   
>   static struct mfd_cell khadas_mcu_fan_cells[] = {

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From tudor.ambarus at linaro.org  Tue Feb  6 00:52:34 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue,  6 Feb 2024 08:52:34 +0000
Subject: [PATCH 0/4] spi: s3c64xx: add support for google,gs101-spi
Message-ID: <20240206085238.1208256-1-tudor.ambarus@linaro.org>

Depends on the simple cleanup patches from:
https://lore.kernel.org/linux-spi/20240205124513.447875-1-tudor.ambarus at linaro.org/

A slightly different version of the google,gs101-spi support was sent at:
https://lore.kernel.org/linux-spi/20240125145007.748295-1-tudor.ambarus at linaro.org/

Let's add support for gs101-spi so that I have a testing base for the
driver rework patches that will follow.

Tudor Ambarus (4):
  spi: s3c64xx: explicitly include <linux/types.h>
  spi: dt-bindings: samsung: add google,gs101-spi compatible
  spi: s3c64xx: add s3c64xx_iowrite{8,16}_32_rep accessors
  spi: s3c64xx: add support for google,gs101-spi

 .../devicetree/bindings/spi/samsung,spi.yaml  |  1 +
 drivers/spi/spi-s3c64xx.c                     | 89 +++++++++++++++----
 2 files changed, 75 insertions(+), 15 deletions(-)

-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Tue Feb  6 00:52:35 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue,  6 Feb 2024 08:52:35 +0000
Subject: [PATCH 1/4] spi: s3c64xx: explicitly include <linux/types.h>
In-Reply-To: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
Message-ID: <20240206085238.1208256-2-tudor.ambarus@linaro.org>

The driver uses u32 and relies on an implicit inclusion of
<linux/types.h>.

It is good practice to directly include all headers used, it avoids
implicit dependencies and spurious breakage if someone rearranges
headers and causes the implicit include to vanish.

Include the missing header.

Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver")
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 72c35dbe53b2..c15ca6a910dc 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/spi/spi.h>
+#include <linux/types.h>
 
 #define MAX_SPI_PORTS		12
 #define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1)
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Tue Feb  6 00:52:36 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue,  6 Feb 2024 08:52:36 +0000
Subject: [PATCH 2/4] spi: dt-bindings: samsung: add google,gs101-spi compatible
In-Reply-To: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
Message-ID: <20240206085238.1208256-3-tudor.ambarus@linaro.org>

Add "google,gs101-spi" dedicated compatible for representing SPI of
Google GS101 SoC.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Andi Shyti <andi.shyti at kernel.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.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 f71099852653..2f0a0835ecfb 100644
--- a/Documentation/devicetree/bindings/spi/samsung,spi.yaml
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     oneOf:
       - enum:
+          - google,gs101-spi
           - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
           - samsung,s3c6410-spi
           - samsung,s5pv210-spi # for S5PV210 and S5PC110
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Tue Feb  6 00:52:37 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue,  6 Feb 2024 08:52:37 +0000
Subject: [PATCH 3/4] spi: s3c64xx: add s3c64xx_iowrite{8,16}_32_rep accessors
In-Reply-To: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
Message-ID: <20240206085238.1208256-4-tudor.ambarus@linaro.org>

Allow SoCs that require 32 bits register accesses to write data in
chunks of 8 or 16 bits. One SoC that requires 32 bit register accesses
is the google gs101. The operation is rare, thus open code it in the
driver rather than making it generic (through asm-generic/io.h)

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 70 +++++++++++++++++++++++++++++++--------
 1 file changed, 56 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index c15ca6a910dc..cb45ad615f3d 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -142,6 +142,7 @@ struct s3c64xx_spi_dma_data {
  *	prescaler unit.
  * @clk_ioclk: True if clock is present on this device
  * @has_loopback: True if loopback mode can be supported
+ * @use_32bit_io: True if the SoC allows just 32-bit register accesses.
  *
  * The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
  * differ in some aspects such as the size of the fifo and spi bus clock
@@ -158,6 +159,7 @@ struct s3c64xx_spi_port_config {
 	bool	clk_from_cmu;
 	bool	clk_ioclk;
 	bool	has_loopback;
+	bool	use_32bit_io;
 };
 
 /**
@@ -412,6 +414,59 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
 	return false;
 }
 
+static void s3c64xx_iowrite8_32_rep(volatile void __iomem *addr,
+				    const void *buffer, unsigned int count)
+{
+	if (count) {
+		const u8 *buf = buffer;
+
+		do {
+			__raw_writel(*buf++, addr);
+		} while (--count);
+	}
+}
+
+static void s3c64xx_iowrite16_32_rep(volatile void __iomem *addr,
+				     const void *buffer, unsigned int count)
+{
+	if (count) {
+		const u16 *buf = buffer;
+
+		do {
+			__raw_writel(*buf++, addr);
+		} while (--count);
+	}
+}
+
+static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd,
+				struct spi_transfer *xfer)
+{
+	void __iomem *regs = sdd->regs;
+
+	switch (sdd->cur_bpw) {
+	case 32:
+		iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
+			      xfer->tx_buf, xfer->len / 4);
+		break;
+	case 16:
+		if (sdd->port_conf->use_32bit_io)
+			s3c64xx_iowrite16_32_rep(regs + S3C64XX_SPI_TX_DATA,
+						 xfer->tx_buf, xfer->len / 2);
+		else
+			iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
+				      xfer->tx_buf, xfer->len / 2);
+		break;
+	default:
+		if (sdd->port_conf->use_32bit_io)
+			s3c64xx_iowrite8_32_rep(regs + S3C64XX_SPI_TX_DATA,
+						xfer->tx_buf, xfer->len);
+		else
+			iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
+				     xfer->tx_buf, xfer->len);
+		break;
+	}
+}
+
 static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 				    struct spi_transfer *xfer, int dma_mode)
 {
@@ -445,20 +500,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
 			ret = s3c64xx_prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
 		} else {
-			switch (sdd->cur_bpw) {
-			case 32:
-				iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
-					xfer->tx_buf, xfer->len / 4);
-				break;
-			case 16:
-				iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
-					xfer->tx_buf, xfer->len / 2);
-				break;
-			default:
-				iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
-					xfer->tx_buf, xfer->len);
-				break;
-			}
+			s3c64xx_iowrite_rep(sdd, xfer);
 		}
 	}
 
-- 
2.43.0.594.gd9cf4e227d-goog



From tudor.ambarus at linaro.org  Tue Feb  6 00:52:38 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue,  6 Feb 2024 08:52:38 +0000
Subject: [PATCH 4/4] spi: s3c64xx: add support for google,gs101-spi
In-Reply-To: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
Message-ID: <20240206085238.1208256-5-tudor.ambarus@linaro.org>

Add support for GS101 SPI. GS101 integrates 16 SPI nodes, all with 64
bytes FIFOs. GS101 allows just 32 bit register accesses, otherwise a
Serror Interrupt is raised. Do the write reg accesses in 32 bits.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index cb45ad615f3d..9ad0d513fb30 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -19,7 +19,7 @@
 #include <linux/spi/spi.h>
 #include <linux/types.h>
 
-#define MAX_SPI_PORTS		12
+#define MAX_SPI_PORTS		16
 #define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1)
 #define AUTOSUSPEND_TIMEOUT	2000
 
@@ -1538,6 +1538,19 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
 	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
 };
 
+static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
+	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+			    0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
+	.clk_div	= 4,
+	.high_speed	= true,
+	.clk_from_cmu	= true,
+	.has_loopback	= true,
+	.use_32bit_io	= true,
+	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
+};
+
 static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
 	{
 		.name		= "s3c2443-spi",
@@ -1550,6 +1563,9 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
 };
 
 static const struct of_device_id s3c64xx_spi_dt_match[] = {
+	{ .compatible = "google,gs101-spi",
+			.data = &gs101_spi_port_config,
+	},
 	{ .compatible = "samsung,s3c2443-spi",
 			.data = &s3c2443_spi_port_config,
 	},
-- 
2.43.0.594.gd9cf4e227d-goog



From neil.armstrong at linaro.org  Tue Feb  6 00:54:23 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 6 Feb 2024 09:54:23 +0100
Subject: [PATCHv1 2/5] arm64: dts: amlogic: Add cache information to the
 Amlogic SM1 SoC
In-Reply-To: <20240205171930.968-3-linux.amoon@gmail.com>
References: <20240205171930.968-1-linux.amoon@gmail.com>
 <20240205171930.968-3-linux.amoon@gmail.com>
Message-ID: <26732d5a-9fe1-4662-9362-ed397d266e01@linaro.org>

On 05/02/2024 18:19, Anand Moon wrote:
> As per S905X3 datasheet add missing cache information to the Amlogic
> SM1 SoC. ARM Cortex-A55 CPU uses unified L3 cache instead of L2 cache.
> 
> - Each Cortex-A55 core has 32KB of L1 instruction cache available and
> 	32KB of L1 data cache available.
> - Along with 512KB Unified L3 cache.

This 512K number is for the NPU, AFAIK the CPU L3 Cache size isn't specified in the datasheet

> 
> To improve system performance.
> 
> Signed-off-by: Anand Moon <linux.amoon at gmail.com>
> ---
> Datasheet
> [0] https://dn.odroid.com/S905X3/ODROID-C4/Docs/S905X3_Public_Datasheet_Hardkernel.pdf
> [1] https://en.wikipedia.org/wiki/ARM_Cortex-A55
> ---
>   arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 39 ++++++++++++++++++----
>   1 file changed, 33 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> index 643f94d9d08e..403443e782e4 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> @@ -55,7 +55,13 @@ cpu0: cpu at 0 {
>   			compatible = "arm,cortex-a55";
>   			reg = <0x0 0x0>;
>   			enable-method = "psci";
> -			next-level-cache = <&l2>;
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
> +			next-level-cache = <&l3>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -64,7 +70,13 @@ cpu1: cpu at 1 {
>   			compatible = "arm,cortex-a55";
>   			reg = <0x0 0x1>;
>   			enable-method = "psci";
> -			next-level-cache = <&l2>;
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
> +			next-level-cache = <&l3>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -73,7 +85,13 @@ cpu2: cpu at 2 {
>   			compatible = "arm,cortex-a55";
>   			reg = <0x0 0x2>;
>   			enable-method = "psci";
> -			next-level-cache = <&l2>;
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
> +			next-level-cache = <&l3>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -82,14 +100,23 @@ cpu3: cpu at 3 {
>   			compatible = "arm,cortex-a55";
>   			reg = <0x0 0x3>;
>   			enable-method = "psci";
> -			next-level-cache = <&l2>;
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
> +			next-level-cache = <&l3>;
>   			#cooling-cells = <2>;
>   		};
>   
> -		l2: l2-cache0 {
> +		l3: l3-cache0 {
>   			compatible = "cache";
> -			cache-level = <2>;
> +			cache-level = <3>;
>   			cache-unified;
> +			cache-size = <0x7d000>; /* L2. 512 KB */

Comment should be L3 here

> +			cache-line-size = <64>;
> +			cache-sets = <512>;
>   		};
>   	};
>   

Thanks,
Neil



From neil.armstrong at linaro.org  Tue Feb  6 01:00:05 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 6 Feb 2024 10:00:05 +0100
Subject: [PATCHv1 4/5] arm64: dts: amlogic: Add cache information to the
 Amlogic S922X SoC
In-Reply-To: <20240205171930.968-5-linux.amoon@gmail.com>
References: <20240205171930.968-1-linux.amoon@gmail.com>
 <20240205171930.968-5-linux.amoon@gmail.com>
Message-ID: <cf47b82c-6307-475b-af3a-eab7f09715f0@linaro.org>

On 05/02/2024 18:19, Anand Moon wrote:
> As per S922X datasheet add missing cache information to the Amlogic
> S922X SoC.
> 
> - Each Cortex-A53 core has 32 KB of instruction cache and
> 	32 KB of L1 data cache available.
> - Each Cortex-A73 core has 64 KB of L1 instruction cache and
> 	64 KB of L1 data cache available.
> - The little (A53) cluster has 512 KB of unified L2 cache available.
> - The big (A73) cluster has 1 MB of unified L2 cache available.

Datasheet says:
The quad core Cortex?-A73 processor is paired with A53 processor in a big.Little configuration, with each
core has L1 instruction and data chaches, together with a single shared L2 unified cache with A53

And there's no indication of the L1 or L2 cache sizes.

Neil

> 
> To improve system performance.
> 
> Signed-off-by: Anand Moon <linux.amoon at gmail.com>
> ---
> [0] https://dn.odroid.com/S922X/ODROID-N2/Datasheet/S922X_Public_Datasheet_V0.2.pdf
> [1] https://en.wikipedia.org/wiki/ARM_Cortex-A73
> [2] https://en.wikipedia.org/wiki/ARM_Cortex-A53
> ---
>   arch/arm64/boot/dts/amlogic/meson-g12b.dtsi | 62 ++++++++++++++++++---
>   1 file changed, 55 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
> index 86e6ceb31d5e..624c6fd763ac 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
> @@ -49,7 +49,13 @@ cpu0: cpu at 0 {
>   			reg = <0x0 0x0>;
>   			enable-method = "psci";
>   			capacity-dmips-mhz = <592>;
> -			next-level-cache = <&l2>;
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
> +			next-level-cache = <&l2_cache_l>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -59,7 +65,13 @@ cpu1: cpu at 1 {
>   			reg = <0x0 0x1>;
>   			enable-method = "psci";
>   			capacity-dmips-mhz = <592>;
> -			next-level-cache = <&l2>;
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
> +			next-level-cache = <&l2_cache_l>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -69,7 +81,13 @@ cpu100: cpu at 100 {
>   			reg = <0x0 0x100>;
>   			enable-method = "psci";
>   			capacity-dmips-mhz = <1024>;
> -			next-level-cache = <&l2>;
> +			d-cache-line-size = <64>;
> +			d-cache-size = <0x10000>;
> +			d-cache-sets = <64>;
> +			i-cache-line-size = <64>;
> +			i-cache-size = <0x10000>;
> +			i-cache-sets = <64>;
> +			next-level-cache = <&l2_cache_b>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -79,7 +97,13 @@ cpu101: cpu at 101 {
>   			reg = <0x0 0x101>;
>   			enable-method = "psci";
>   			capacity-dmips-mhz = <1024>;
> -			next-level-cache = <&l2>;
> +			d-cache-line-size = <64>;
> +			d-cache-size = <0x10000>;
> +			d-cache-sets = <64>;
> +			i-cache-line-size = <64>;
> +			i-cache-size = <0x10000>;
> +			i-cache-sets = <64>;
> +			next-level-cache = <&l2_cache_b>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -89,7 +113,13 @@ cpu102: cpu at 102 {
>   			reg = <0x0 0x102>;
>   			enable-method = "psci";
>   			capacity-dmips-mhz = <1024>;
> -			next-level-cache = <&l2>;
> +			d-cache-line-size = <64>;
> +			d-cache-size = <0x10000>;
> +			d-cache-sets = <64>;
> +			i-cache-line-size = <64>;
> +			i-cache-size = <0x10000>;
> +			i-cache-sets = <64>;
> +			next-level-cache = <&l2_cache_b>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -99,14 +129,32 @@ cpu103: cpu at 103 {
>   			reg = <0x0 0x103>;
>   			enable-method = "psci";
>   			capacity-dmips-mhz = <1024>;
> -			next-level-cache = <&l2>;
> +			d-cache-line-size = <64>;
> +			d-cache-size = <0x10000>;
> +			d-cache-sets = <64>;
> +			i-cache-line-size = <64>;
> +			i-cache-size = <0x10000>;
> +			i-cache-sets = <64>;
> +			next-level-cache = <&l2_cache_b>;
>   			#cooling-cells = <2>;
>   		};
>   
> -		l2: l2-cache0 {
> +		l2_cache_l: l2-cache-cluster0 {
>   			compatible = "cache";
>   			cache-level = <2>;
>   			cache-unified;
> +			cache-size = <0x80000>;
> +			cache-line-size = <64>;
> +			cache-sets = <512>;
> +		};
> +
> +		l2_cache_b: l2-cache-cluster1 {
> +			compatible = "cache";
> +			cache-level = <2>;
> +			cache-unified;
> +			cache-size = <0x100000>;
> +			cache-line-size = <64>;
> +			cache-sets = <512>;
>   		};
>   	};
>   };



From neil.armstrong at linaro.org  Tue Feb  6 01:01:04 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 6 Feb 2024 10:01:04 +0100
Subject: [PATCHv1 5/5] arm64: dts: amlogic: Add cache information to the
 Amlogic A7 SoC
In-Reply-To: <20240205171930.968-6-linux.amoon@gmail.com>
References: <20240205171930.968-1-linux.amoon@gmail.com>
 <20240205171930.968-6-linux.amoon@gmail.com>
Message-ID: <451adbff-c2b7-4141-990d-73cf869b752f@linaro.org>

On 05/02/2024 18:19, Anand Moon wrote:
> As per A311D datasheet add missing cache information to the Amlogic A7 SoC.
> 
> - Each Cortex-A53 core has 32 KB of instruction cache and
> 	32 KB of L1 data cache available.
> - Each Cortex-A73 core has 64 KB of L1 instruction cache and
> 	64 KB of L1 data cache available.
> - The little (A53) cluster has 512 KB of unified L2 cache available.
> - The big (A73) cluster has 1 MB of unified L2 cache available.

Where did you get those numbers ? I can't find them.

Neil

> 
> To improve system performance.
> 
> Signed-off-by: Anand Moon <linux.amoon at gmail.com>
> ---
> [0] https://dl.khadas.com/products/vim4/datasheet/a311d2_quick_reference_manual_v0.6.pdf
> [1] https://en.wikipedia.org/wiki/ARM_Cortex-A73
> [2] https://en.wikipedia.org/wiki/ARM_Cortex-A53
> ---
>   arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 74 +++++++++++++++++++++
>   1 file changed, 74 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index a03c7667d2b6..72dedc40f460 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -52,6 +52,13 @@ cpu100: cpu at 100 {
>   			compatible = "arm,cortex-a53";
>   			reg = <0x0 0x100>;
>   			enable-method = "psci";
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
> +			next-level-cache = <&l2_cache_l>;
>   		};
>   
>   		cpu101: cpu at 101{
> @@ -59,6 +66,13 @@ cpu101: cpu at 101{
>   			compatible = "arm,cortex-a53";
>   			reg = <0x0 0x101>;
>   			enable-method = "psci";
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
> +			next-level-cache = <&l2_cache_l>;
>   		};
>   
>   		cpu102: cpu at 102 {
> @@ -66,6 +80,13 @@ cpu102: cpu at 102 {
>   			compatible = "arm,cortex-a53";
>   			reg = <0x0 0x102>;
>   			enable-method = "psci";
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
> +			next-level-cache = <&l2_cache_l>;
>   		};
>   
>   		cpu103: cpu at 103 {
> @@ -73,6 +94,13 @@ cpu103: cpu at 103 {
>   			compatible = "arm,cortex-a53";
>   			reg = <0x0 0x103>;
>   			enable-method = "psci";
> +			d-cache-line-size = <32>;
> +			d-cache-size = <0x8000>;
> +			d-cache-sets = <32>;
> +			i-cache-line-size = <32>;
> +			i-cache-size = <0x8000>;
> +			i-cache-sets = <32>;
> +			next-level-cache = <&l2_cache_l>;
>   		};
>   
>   		cpu0: cpu at 0 {
> @@ -80,6 +108,13 @@ cpu0: cpu at 0 {
>   			compatible = "arm,cortex-a73";
>   			reg = <0x0 0x0>;
>   			enable-method = "psci";
> +			d-cache-line-size = <64>;
> +			d-cache-size = <0x10000>;
> +			d-cache-sets = <64>;
> +			i-cache-line-size = <64>;
> +			i-cache-size = <0x10000>;
> +			i-cache-sets = <64>;
> +			next-level-cache = <&l2_cache_b>;
>   		};
>   
>   		cpu1: cpu at 1 {
> @@ -87,6 +122,13 @@ cpu1: cpu at 1 {
>   			compatible = "arm,cortex-a73";
>   			reg = <0x0 0x1>;
>   			enable-method = "psci";
> +			d-cache-line-size = <64>;
> +			d-cache-size = <0x10000>;
> +			d-cache-sets = <64>;
> +			i-cache-line-size = <64>;
> +			i-cache-size = <0x10000>;
> +			i-cache-sets = <64>;
> +			next-level-cache = <&l2_cache_b>;
>   		};
>   
>   		cpu2: cpu at 2 {
> @@ -94,6 +136,13 @@ cpu2: cpu at 2 {
>   			compatible = "arm,cortex-a73";
>   			reg = <0x0 0x2>;
>   			enable-method = "psci";
> +			d-cache-line-size = <64>;
> +			d-cache-size = <0x10000>;
> +			d-cache-sets = <64>;
> +			i-cache-line-size = <64>;
> +			i-cache-size = <0x10000>;
> +			i-cache-sets = <64>;
> +			next-level-cache = <&l2_cache_b>;
>   		};
>   
>   		cpu3: cpu at 3 {
> @@ -101,6 +150,31 @@ cpu3: cpu at 3 {
>   			compatible = "arm,cortex-a73";
>   			reg = <0x0 0x3>;
>   			enable-method = "psci";
> +			d-cache-line-size = <64>;
> +			d-cache-size = <0x10000>;
> +			d-cache-sets = <64>;
> +			i-cache-line-size = <64>;
> +			i-cache-size = <0x10000>;
> +			i-cache-sets = <64>;
> +			next-level-cache = <&l2_cache_b>;
> +		};
> +
> +		l2_cache_l: l2-cache-cluster0 {
> +			compatible = "cache";
> +			cache-level = <2>;
> +			cache-unified;
> +			cache-size = <0x80000>;
> +			cache-line-size = <64>;
> +			cache-sets = <512>;
> +		};
> +
> +		l2_cache_b: l2-cache-cluster1 {
> +			compatible = "cache";
> +			cache-level = <2>;
> +			cache-unified;
> +			cache-size = <0x100000>;
> +			cache-line-size = <64>;
> +			cache-sets = <1024>;
>   		};
>   	};
>   



From msp at baylibre.com  Tue Feb  6 01:12:56 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue, 6 Feb 2024 10:12:56 +0100
Subject: [PATCH v4 1/1] arm64: dts: ti: k3-am62-wakeup: Configure ti-sysc
 for wkup_uart0
In-Reply-To: <20240126082006.GT5185@atomide.com>
References: <20231219072503.12427-1-tony@atomide.com>
 <q54c4f3l2ddvnnwzigz2hebru27nhevf4oij6g2nqv6yyijigr@nuvwukfwpsjh>
 <20240126082006.GT5185@atomide.com>
Message-ID: <wl7atq35kwgd3lgscp2sygjulrheukjfjcia3nl6f5326ot35i@jey76kt25sz7>

Hi Tony,

On Fri, Jan 26, 2024 at 10:20:06AM +0200, Tony Lindgren wrote:
> * Markus Schneider-Pargmann <msp at baylibre.com> [240124 13:55]:
> > I tested this patch on am62-lp-sk and required this additional property:
> > 
> >   ti,no-reset-on-init;
> > 
> > I am not sure at the moment why a reset doesn't work. But with the given
> > property (so without reset) the wakeup on wkup_uart0 works as expected.
> 
> OK. This might be some firmware related difference. Care to describe what
> goes wrong so that can be added to the patch description?

I tested this patch on sk-am62-lp on the upstream kernel and on the
latest ti-sdk 6.1 kernel. With the ti-sdk 6.1 kernel I get mbox timeouts
if the driver resets the ti-sysc. If it doesn't reset it, everything
works on ti-sdk 6.1 as expected as well including wakeup from the
wkup_uart0.

Best,
Markus


From Jonathan.Cameron at Huawei.com  Tue Feb  6 01:16:51 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Tue, 6 Feb 2024 09:16:51 +0000
Subject: [RESEND v4] perf stat: Support per-cluster aggregation
In-Reply-To: <20240206082016.22292-1-yangyicong@huawei.com>
References: <20240206082016.22292-1-yangyicong@huawei.com>
Message-ID: <20240206091651.00007c1b@Huawei.com>

On Tue, 6 Feb 2024 16:20:16 +0800
Yicong Yang <yangyicong at huawei.com> wrote:

> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> Some platforms have 'cluster' topology and CPUs in the cluster will
> share resources like L3 Cache Tag (for HiSilicon Kunpeng SoC) or L2
> cache (for Intel Jacobsville). Currently parsing and building cluster
> topology have been supported since [1].
> 
> perf stat has already supported aggregation for other topologies like
> die or socket, etc. It'll be useful to aggregate per-cluster to find
> problems like L3T bandwidth contention.
> 
> This patch add support for "--per-cluster" option for per-cluster
> aggregation. Also update the docs and related test. The output will
> be like:
> 
> [root at localhost tmp]# perf stat -a -e LLC-load --per-cluster -- sleep 5
> 
>  Performance counter stats for 'system wide':
> 
> S56-D0-CLS158    4      1,321,521,570      LLC-load
> S56-D0-CLS594    4        794,211,453      LLC-load
> S56-D0-CLS1030    4             41,623      LLC-load
> S56-D0-CLS1466    4             41,646      LLC-load
> S56-D0-CLS1902    4             16,863      LLC-load
> S56-D0-CLS2338    4             15,721      LLC-load
> S56-D0-CLS2774    4             22,671      LLC-load
> [...]
> 
> On a legacy system without cluster or cluster support, the output will
> be look like:
> [root at localhost perf]# perf stat -a -e cycles --per-cluster -- sleep 1
> 
>  Performance counter stats for 'system wide':
> 
> S56-D0-CLS0   64         18,011,485      cycles
> S7182-D0-CLS0   64         16,548,835      cycles
> 
> Note that this patch doesn't mix the cluster information in the outputs
> of --per-core to avoid breaking any tools/scripts using it.
> 
> Note that perf recently supports "--per-cache" aggregation, but it's not
> the same with the cluster although cluster CPUs may share some cache
> resources. For example on my machine all clusters within a die share the
> same L3 cache:
> $ cat /sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list
> 0-31
> $ cat /sys/devices/system/cpu/cpu0/topology/cluster_cpus_list
> 0-3
> 
> [1] commit c5e22feffdd7 ("topology: Represent clusters of CPUs within a die")
> Tested-by: Jie Zhan <zhanjie9 at hisilicon.com>
> Reviewed-by: Tim Chen <tim.c.chen at linux.intel.com>
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
> Change since v3:
> - Rebase on v6.7-rc4 and resolve the conflicts
> Link: https://lore.kernel.org/all/20230404104951.27537-1-yangyicong at huawei.com/
> 
> Change since v2:
> - Use 0 as cluster ID on legacy system without cluster support, keep consistenct
>   with what --per-die does.
> Link: https://lore.kernel.org/all/20230328112717.19573-1-yangyicong at huawei.com/
> 
> Change since v1:
> - Provides the information about how to map the cluster to the CPUs in the manual
Given this change incorporates both the case in the example above where PPTT doesn't
have the IDs set for the Processor Hierarchy nodes and the one where it does 
(which would be the UIDs of the Processor Containers in DSDT) I think this is sufficient.

Not an expert on perftool but in general this looks both useful and correct to me.

Jonathan

> - Thanks the review from Tim and test from Jie.
> Link: https://lore.kernel.org/all/20230313085911.61359-1-yangyicong at huawei.com/
> 
>  tools/perf/Documentation/perf-stat.txt        | 11 ++++
>  tools/perf/builtin-stat.c                     | 52 +++++++++++++++++--
>  .../tests/shell/lib/perf_json_output_lint.py  |  4 +-
>  tools/perf/tests/shell/lib/stat_output.sh     | 12 +++++
>  tools/perf/tests/shell/stat+csv_output.sh     |  2 +
>  tools/perf/tests/shell/stat+json_output.sh    | 13 +++++
>  tools/perf/tests/shell/stat+std_output.sh     |  2 +
>  tools/perf/util/cpumap.c                      | 32 +++++++++++-
>  tools/perf/util/cpumap.h                      | 19 +++++--
>  tools/perf/util/env.h                         |  1 +
>  tools/perf/util/stat-display.c                | 13 +++++
>  tools/perf/util/stat.h                        |  1 +
>  12 files changed, 153 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
> index 5af2e432b54f..29756a87ab6f 100644
> --- a/tools/perf/Documentation/perf-stat.txt
> +++ b/tools/perf/Documentation/perf-stat.txt
> @@ -308,6 +308,14 @@ use --per-die in addition to -a. (system-wide).  The output includes the
>  die number and the number of online processors on that die. This is
>  useful to gauge the amount of aggregation.
>  
> +--per-cluster::
> +Aggregate counts per processor cluster for system-wide mode measurement.  This
> +is a useful mode to detect imbalance between clusters.  To enable this mode,
> +use --per-cluster in addition to -a. (system-wide).  The output includes the
> +cluster number and the number of online processors on that cluster. This is
> +useful to gauge the amount of aggregation. The information of cluster ID and
> +related CPUs can be gotten from /sys/devices/system/cpu/cpuX/topology/cluster_{id, cpus}.
> +
>  --per-cache::
>  Aggregate counts per cache instance for system-wide mode measurements.  By
>  default, the aggregation happens for the cache level at the highest index
> @@ -396,6 +404,9 @@ Aggregate counts per processor socket for system-wide mode measurements.
>  --per-die::
>  Aggregate counts per processor die for system-wide mode measurements.
>  
> +--per-cluster::
> +Aggregate counts perf processor cluster for system-wide mode measurements.
> +
>  --per-cache::
>  Aggregate counts per cache instance for system-wide mode measurements.  By
>  default, the aggregation happens for the cache level at the highest index
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index 5fe9abc6a524..6bba1a89d030 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -1238,6 +1238,8 @@ static struct option stat_options[] = {
>  		     "aggregate counts per processor socket", AGGR_SOCKET),
>  	OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
>  		     "aggregate counts per processor die", AGGR_DIE),
> +	OPT_SET_UINT(0, "per-cluster", &stat_config.aggr_mode,
> +		     "aggregate counts per processor cluster", AGGR_CLUSTER),
>  	OPT_CALLBACK_OPTARG(0, "per-cache", &stat_config.aggr_mode, &stat_config.aggr_level,
>  			    "cache level", "aggregate count at this cache level (Default: LLC)",
>  			    parse_cache_level),
> @@ -1428,6 +1430,7 @@ static struct aggr_cpu_id aggr_cpu_id__cache(struct perf_cpu cpu, void *data)
>  static const char *const aggr_mode__string[] = {
>  	[AGGR_CORE] = "core",
>  	[AGGR_CACHE] = "cache",
> +	[AGGR_CLUSTER] = "cluster",
>  	[AGGR_DIE] = "die",
>  	[AGGR_GLOBAL] = "global",
>  	[AGGR_NODE] = "node",
> @@ -1455,6 +1458,12 @@ static struct aggr_cpu_id perf_stat__get_cache_id(struct perf_stat_config *confi
>  	return aggr_cpu_id__cache(cpu, /*data=*/NULL);
>  }
>  
> +static struct aggr_cpu_id perf_stat__get_cluster(struct perf_stat_config *config __maybe_unused,
> +						 struct perf_cpu cpu)
> +{
> +	return aggr_cpu_id__cluster(cpu, /*data=*/NULL);
> +}
> +
>  static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
>  					      struct perf_cpu cpu)
>  {
> @@ -1507,6 +1516,12 @@ static struct aggr_cpu_id perf_stat__get_die_cached(struct perf_stat_config *con
>  	return perf_stat__get_aggr(config, perf_stat__get_die, cpu);
>  }
>  
> +static struct aggr_cpu_id perf_stat__get_cluster_cached(struct perf_stat_config *config,
> +							struct perf_cpu cpu)
> +{
> +	return perf_stat__get_aggr(config, perf_stat__get_cluster, cpu);
> +}
> +
>  static struct aggr_cpu_id perf_stat__get_cache_id_cached(struct perf_stat_config *config,
>  							 struct perf_cpu cpu)
>  {
> @@ -1544,6 +1559,8 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode)
>  		return aggr_cpu_id__socket;
>  	case AGGR_DIE:
>  		return aggr_cpu_id__die;
> +	case AGGR_CLUSTER:
> +		return aggr_cpu_id__cluster;
>  	case AGGR_CACHE:
>  		return aggr_cpu_id__cache;
>  	case AGGR_CORE:
> @@ -1569,6 +1586,8 @@ static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode)
>  		return perf_stat__get_socket_cached;
>  	case AGGR_DIE:
>  		return perf_stat__get_die_cached;
> +	case AGGR_CLUSTER:
> +		return perf_stat__get_cluster_cached;
>  	case AGGR_CACHE:
>  		return perf_stat__get_cache_id_cached;
>  	case AGGR_CORE:
> @@ -1737,6 +1756,21 @@ static struct aggr_cpu_id perf_env__get_cache_aggr_by_cpu(struct perf_cpu cpu,
>  	return id;
>  }
>  
> +static struct aggr_cpu_id perf_env__get_cluster_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.cpu != -1) {
> +		id.socket = env->cpu[cpu.cpu].socket_id;
> +		id.die = env->cpu[cpu.cpu].die_id;
> +		id.cluster = env->cpu[cpu.cpu].cluster_id;
> +	}
> +
> +	return id;
> +}
> +
>  static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, void *data)
>  {
>  	struct perf_env *env = data;
> @@ -1744,12 +1778,12 @@ static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, vo
>  
>  	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
> +		 * core_id is relative to socket, die and cluster, we need a
> +		 * global id. So we set socket, die id, cluster id and core id.
>  		 */
>  		id.socket = env->cpu[cpu.cpu].socket_id;
>  		id.die = env->cpu[cpu.cpu].die_id;
> +		id.cluster = env->cpu[cpu.cpu].cluster_id;
>  		id.core = env->cpu[cpu.cpu].core_id;
>  	}
>  
> @@ -1805,6 +1839,12 @@ static struct aggr_cpu_id perf_stat__get_die_file(struct perf_stat_config *confi
>  	return perf_env__get_die_aggr_by_cpu(cpu, &perf_stat.session->header.env);
>  }
>  
> +static struct aggr_cpu_id perf_stat__get_cluster_file(struct perf_stat_config *config __maybe_unused,
> +						      struct perf_cpu cpu)
> +{
> +	return perf_env__get_cluster_aggr_by_cpu(cpu, &perf_stat.session->header.env);
> +}
> +
>  static struct aggr_cpu_id perf_stat__get_cache_file(struct perf_stat_config *config __maybe_unused,
>  						    struct perf_cpu cpu)
>  {
> @@ -1842,6 +1882,8 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode)
>  		return perf_env__get_socket_aggr_by_cpu;
>  	case AGGR_DIE:
>  		return perf_env__get_die_aggr_by_cpu;
> +	case AGGR_CLUSTER:
> +		return perf_env__get_cluster_aggr_by_cpu;
>  	case AGGR_CACHE:
>  		return perf_env__get_cache_aggr_by_cpu;
>  	case AGGR_CORE:
> @@ -1867,6 +1909,8 @@ static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode)
>  		return perf_stat__get_socket_file;
>  	case AGGR_DIE:
>  		return perf_stat__get_die_file;
> +	case AGGR_CLUSTER:
> +		return perf_stat__get_cluster_file;
>  	case AGGR_CACHE:
>  		return perf_stat__get_cache_file;
>  	case AGGR_CORE:
> @@ -2398,6 +2442,8 @@ static int __cmd_report(int argc, const char **argv)
>  		     "aggregate counts per processor socket", AGGR_SOCKET),
>  	OPT_SET_UINT(0, "per-die", &perf_stat.aggr_mode,
>  		     "aggregate counts per processor die", AGGR_DIE),
> +	OPT_SET_UINT(0, "per-cluster", &perf_stat.aggr_mode,
> +		     "aggregate counts perf processor cluster", AGGR_CLUSTER),
>  	OPT_CALLBACK_OPTARG(0, "per-cache", &perf_stat.aggr_mode, &perf_stat.aggr_level,
>  			    "cache level",
>  			    "aggregate count at this cache level (Default: LLC)",
> diff --git a/tools/perf/tests/shell/lib/perf_json_output_lint.py b/tools/perf/tests/shell/lib/perf_json_output_lint.py
> index ea55d5ea1ced..abc1fd737782 100644
> --- a/tools/perf/tests/shell/lib/perf_json_output_lint.py
> +++ b/tools/perf/tests/shell/lib/perf_json_output_lint.py
> @@ -15,6 +15,7 @@ ap.add_argument('--event', action='store_true')
>  ap.add_argument('--per-core', action='store_true')
>  ap.add_argument('--per-thread', action='store_true')
>  ap.add_argument('--per-cache', action='store_true')
> +ap.add_argument('--per-cluster', action='store_true')
>  ap.add_argument('--per-die', action='store_true')
>  ap.add_argument('--per-node', action='store_true')
>  ap.add_argument('--per-socket', action='store_true')
> @@ -49,6 +50,7 @@ def check_json_output(expected_items):
>        'cgroup': lambda x: True,
>        'cpu': lambda x: isint(x),
>        'cache': lambda x: True,
> +      'cluster': lambda x: True,
>        'die': lambda x: True,
>        'event': lambda x: True,
>        'event-runtime': lambda x: isfloat(x),
> @@ -88,7 +90,7 @@ try:
>      expected_items = 7
>    elif args.interval or args.per_thread or args.system_wide_no_aggr:
>      expected_items = 8
> -  elif args.per_core or args.per_socket or args.per_node or args.per_die or args.per_cache:
> +  elif args.per_core or args.per_socket or args.per_node or args.per_die or args.per_cluster or args.per_cache:
>      expected_items = 9
>    else:
>      # If no option is specified, don't check the number of items.
> diff --git a/tools/perf/tests/shell/lib/stat_output.sh b/tools/perf/tests/shell/lib/stat_output.sh
> index 3cc158a64326..c81d6a9f7983 100644
> --- a/tools/perf/tests/shell/lib/stat_output.sh
> +++ b/tools/perf/tests/shell/lib/stat_output.sh
> @@ -97,6 +97,18 @@ check_per_cache_instance()
>  	echo "[Success]"
>  }
>  
> +check_per_cluster()
> +{
> +	echo -n "Checking $1 output: per cluster "
> +	if ParanoidAndNotRoot 0
> +	then
> +		echo "[Skip] paranoid and not root"
> +		return
> +	fi
> +	perf stat --per-cluster -a $2 true
> +	echo "[Success]"
> +}
> +
>  check_per_die()
>  {
>  	echo -n "Checking $1 output: per die "
> diff --git a/tools/perf/tests/shell/stat+csv_output.sh b/tools/perf/tests/shell/stat+csv_output.sh
> index f1818fa6d9ce..fc2d8cc6e5e0 100755
> --- a/tools/perf/tests/shell/stat+csv_output.sh
> +++ b/tools/perf/tests/shell/stat+csv_output.sh
> @@ -42,6 +42,7 @@ function commachecker()
>  	;; "--per-socket")	exp=8
>  	;; "--per-node")	exp=8
>  	;; "--per-die")		exp=8
> +	;; "--per-cluster")	exp=8
>  	;; "--per-cache")	exp=8
>  	esac
>  
> @@ -79,6 +80,7 @@ then
>  	check_system_wide_no_aggr "CSV" "$perf_cmd"
>  	check_per_core "CSV" "$perf_cmd"
>  	check_per_cache_instance "CSV" "$perf_cmd"
> +	check_per_cluster "CSV" "$perf_cmd"
>  	check_per_die "CSV" "$perf_cmd"
>  	check_per_socket "CSV" "$perf_cmd"
>  else
> diff --git a/tools/perf/tests/shell/stat+json_output.sh b/tools/perf/tests/shell/stat+json_output.sh
> index 3bc900533a5d..2b9c6212dffc 100755
> --- a/tools/perf/tests/shell/stat+json_output.sh
> +++ b/tools/perf/tests/shell/stat+json_output.sh
> @@ -122,6 +122,18 @@ check_per_cache_instance()
>  	echo "[Success]"
>  }
>  
> +check_per_cluster()
> +{
> +	echo -n "Checking json output: per cluster "
> +	if ParanoidAndNotRoot 0
> +	then
> +		echo "[Skip] paranoia and not root"
> +		return
> +	fi
> +	perf stat -j --per-cluster -a true 2>&1 | $PYTHON $pythonchecker --per-cluster
> +	echo "[Success]"
> +}
> +
>  check_per_die()
>  {
>  	echo -n "Checking json output: per die "
> @@ -200,6 +212,7 @@ then
>  	check_system_wide_no_aggr
>  	check_per_core
>  	check_per_cache_instance
> +	check_per_cluster
>  	check_per_die
>  	check_per_socket
>  else
> diff --git a/tools/perf/tests/shell/stat+std_output.sh b/tools/perf/tests/shell/stat+std_output.sh
> index 4fcdd1a9142c..16f61e86afc5 100755
> --- a/tools/perf/tests/shell/stat+std_output.sh
> +++ b/tools/perf/tests/shell/stat+std_output.sh
> @@ -40,6 +40,7 @@ function commachecker()
>  	;; "--per-node")	prefix=3
>  	;; "--per-die")		prefix=3
>  	;; "--per-cache")	prefix=3
> +	;; "--per-cluster")	prefix=3
>  	esac
>  
>  	while read line
> @@ -99,6 +100,7 @@ then
>  	check_system_wide_no_aggr "STD" "$perf_cmd"
>  	check_per_core "STD" "$perf_cmd"
>  	check_per_cache_instance "STD" "$perf_cmd"
> +	check_per_cluster "STD" "$perf_cmd"
>  	check_per_die "STD" "$perf_cmd"
>  	check_per_socket "STD" "$perf_cmd"
>  else
> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> index 0581ee0fa5f2..5907456d42a2 100644
> --- a/tools/perf/util/cpumap.c
> +++ b/tools/perf/util/cpumap.c
> @@ -222,6 +222,8 @@ static int aggr_cpu_id__cmp(const void *a_pointer, const void *b_pointer)
>  		return a->socket - b->socket;
>  	else if (a->die != b->die)
>  		return a->die - b->die;
> +	else if (a->cluster != b->cluster)
> +		return a->cluster - b->cluster;
>  	else if (a->cache_lvl != b->cache_lvl)
>  		return a->cache_lvl - b->cache_lvl;
>  	else if (a->cache != b->cache)
> @@ -309,6 +311,29 @@ struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data)
>  	return id;
>  }
>  
> +int cpu__get_cluster_id(struct perf_cpu cpu)
> +{
> +	int value, ret = cpu__get_topology_int(cpu.cpu, "cluster_id", &value);
> +	return ret ?: value;
> +}
> +
> +struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data)
> +{
> +	int cluster = cpu__get_cluster_id(cpu);
> +	struct aggr_cpu_id id;
> +
> +	/* There is no cluster_id on legacy system. */
> +	if (cluster == -1)
> +		cluster = 0;
> +
> +	id = aggr_cpu_id__die(cpu, data);
> +	if (aggr_cpu_id__is_empty(&id))
> +		return id;
> +
> +	id.cluster = cluster;
> +	return id;
> +}
> +
>  int cpu__get_core_id(struct perf_cpu cpu)
>  {
>  	int value, ret = cpu__get_topology_int(cpu.cpu, "core_id", &value);
> @@ -320,8 +345,8 @@ 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);
>  
> -	/* aggr_cpu_id__die returns a struct with socket and die set. */
> -	id = aggr_cpu_id__die(cpu, data);
> +	/* aggr_cpu_id__die returns a struct with socket die, and cluster set. */
> +	id = aggr_cpu_id__cluster(cpu, data);
>  	if (aggr_cpu_id__is_empty(&id))
>  		return id;
>  
> @@ -683,6 +708,7 @@ 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->cluster == b->cluster &&
>  		a->cache_lvl == b->cache_lvl &&
>  		a->cache == b->cache &&
>  		a->core == b->core &&
> @@ -695,6 +721,7 @@ bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a)
>  		a->node == -1 &&
>  		a->socket == -1 &&
>  		a->die == -1 &&
> +		a->cluster == -1 &&
>  		a->cache_lvl == -1 &&
>  		a->cache == -1 &&
>  		a->core == -1 &&
> @@ -708,6 +735,7 @@ struct aggr_cpu_id aggr_cpu_id__empty(void)
>  		.node = -1,
>  		.socket = -1,
>  		.die = -1,
> +		.cluster = -1,
>  		.cache_lvl = -1,
>  		.cache = -1,
>  		.core = -1,
> diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> index 9df2aeb34d3d..26cf76c693f5 100644
> --- a/tools/perf/util/cpumap.h
> +++ b/tools/perf/util/cpumap.h
> @@ -20,6 +20,8 @@ struct aggr_cpu_id {
>  	int socket;
>  	/** The die id as read from /sys/devices/system/cpu/cpuX/topology/die_id. */
>  	int die;
> +	/** The cluster id as read from /sys/devices/system/cpu/cpuX/topology/cluster_id */
> +	int cluster;
>  	/** The cache level as read from /sys/devices/system/cpu/cpuX/cache/indexY/level */
>  	int cache_lvl;
>  	/**
> @@ -86,6 +88,11 @@ int cpu__get_socket_id(struct perf_cpu cpu);
>   * /sys/devices/system/cpu/cpuX/topology/die_id for the given CPU.
>   */
>  int cpu__get_die_id(struct perf_cpu cpu);
> +/**
> + * cpu__get_cluster_id - Returns the cluster id as read from
> + * /sys/devices/system/cpu/cpuX/topology/cluster_id for the given CPU
> + */
> +int cpu__get_cluster_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.
> @@ -127,9 +134,15 @@ struct aggr_cpu_id aggr_cpu_id__socket(struct perf_cpu 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.
> + * aggr_cpu_id__cluster - Create an aggr_cpu_id with cluster, die and socket
> + * populated with the cluster, die and socket for cpu. The function signature
> + * is compatible with aggr_cpu_id_get_t.
> + */
> +struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data);
> +/**
> + * aggr_cpu_id__core - Create an aggr_cpu_id with the core, cluster, 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(struct perf_cpu cpu, void *data);
>  /**
> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
> index 7c527e65c186..2a2c37cc40b7 100644
> --- a/tools/perf/util/env.h
> +++ b/tools/perf/util/env.h
> @@ -12,6 +12,7 @@ struct perf_cpu_map;
>  struct cpu_topology_map {
>  	int	socket_id;
>  	int	die_id;
> +	int	cluster_id;
>  	int	core_id;
>  };
>  
> diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
> index 8c61f8627ebc..4dfe7d9517a9 100644
> --- a/tools/perf/util/stat-display.c
> +++ b/tools/perf/util/stat-display.c
> @@ -201,6 +201,9 @@ static void print_aggr_id_std(struct perf_stat_config *config,
>  		snprintf(buf, sizeof(buf), "S%d-D%d-L%d-ID%d",
>  			 id.socket, id.die, id.cache_lvl, id.cache);
>  		break;
> +	case AGGR_CLUSTER:
> +		snprintf(buf, sizeof(buf), "S%d-D%d-CLS%d", id.socket, id.die, id.cluster);
> +		break;
>  	case AGGR_DIE:
>  		snprintf(buf, sizeof(buf), "S%d-D%d", id.socket, id.die);
>  		break;
> @@ -251,6 +254,10 @@ static void print_aggr_id_csv(struct perf_stat_config *config,
>  		fprintf(config->output, "S%d-D%d-L%d-ID%d%s%d%s",
>  			id.socket, id.die, id.cache_lvl, id.cache, sep, aggr_nr, sep);
>  		break;
> +	case AGGR_CLUSTER:
> +		fprintf(config->output, "S%d-D%d-CLS%d%s%d%s",
> +			id.socket, id.die, id.cluster, sep, aggr_nr, sep);
> +		break;
>  	case AGGR_DIE:
>  		fprintf(output, "S%d-D%d%s%d%s",
>  			id.socket, id.die, sep, aggr_nr, sep);
> @@ -300,6 +307,10 @@ static void print_aggr_id_json(struct perf_stat_config *config,
>  		fprintf(output, "\"cache\" : \"S%d-D%d-L%d-ID%d\", \"aggregate-number\" : %d, ",
>  			id.socket, id.die, id.cache_lvl, id.cache, aggr_nr);
>  		break;
> +	case AGGR_CLUSTER:
> +		fprintf(output, "\"cluster\" : \"S%d-D%d-CLS%d\", \"aggregate-number\" : %d, ",
> +			id.socket, id.die, id.cluster, aggr_nr);
> +		break;
>  	case AGGR_DIE:
>  		fprintf(output, "\"die\" : \"S%d-D%d\", \"aggregate-number\" : %d, ",
>  			id.socket, id.die, aggr_nr);
> @@ -1248,6 +1259,7 @@ static void print_header_interval_std(struct perf_stat_config *config,
>  	case AGGR_NODE:
>  	case AGGR_SOCKET:
>  	case AGGR_DIE:
> +	case AGGR_CLUSTER:
>  	case AGGR_CACHE:
>  	case AGGR_CORE:
>  		fprintf(output, "#%*s %-*s cpus",
> @@ -1550,6 +1562,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
>  	switch (config->aggr_mode) {
>  	case AGGR_CORE:
>  	case AGGR_CACHE:
> +	case AGGR_CLUSTER:
>  	case AGGR_DIE:
>  	case AGGR_SOCKET:
>  	case AGGR_NODE:
> diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
> index 4357ba114822..d6e5c8787ba2 100644
> --- a/tools/perf/util/stat.h
> +++ b/tools/perf/util/stat.h
> @@ -48,6 +48,7 @@ enum aggr_mode {
>  	AGGR_GLOBAL,
>  	AGGR_SOCKET,
>  	AGGR_DIE,
> +	AGGR_CLUSTER,
>  	AGGR_CACHE,
>  	AGGR_CORE,
>  	AGGR_THREAD,



From ck.hu at mediatek.com  Tue Feb  6 00:57:08 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 6 Feb 2024 08:57:08 +0000
Subject: [PATCH v3 1/7] drm/mediatek: dsi: Use GENMASK() for register mask
 definitions
In-Reply-To: <20240131113434.241929-2-angelogioacchino.delregno@collabora.com>
References: <20240131113434.241929-1-angelogioacchino.delregno@collabora.com>
	 <20240131113434.241929-2-angelogioacchino.delregno@collabora.com>
Message-ID: <082bc4d9efd0746d7ec25eab0b3bf96018e997e5.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-01-31 at 12:34 +0100, AngeloGioacchino Del Regno wrote:
> Change magic numerical masks with usage of the GENMASK() macro
> to improve readability.
> 
> While at it, also fix the DSI_PS_SEL mask to include all bits instead
> of just a subset of them.
> 
> This commit brings no functional changes.
> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 45 +++++++++++++++-------------
> --
>  1 file changed, 23 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index a2fdfc8ddb15..3b7392c03b4d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -58,18 +58,18 @@
>  
>  #define DSI_TXRX_CTRL		0x18
>  #define VC_NUM				BIT(1)
> -#define LANE_NUM			(0xf << 2)
> +#define LANE_NUM			GENMASK(5, 2)
>  #define DIS_EOT				BIT(6)
>  #define NULL_EN				BIT(7)
>  #define TE_FREERUN			BIT(8)
>  #define EXT_TE_EN			BIT(9)
>  #define EXT_TE_EDGE			BIT(10)
> -#define MAX_RTN_SIZE			(0xf << 12)
> +#define MAX_RTN_SIZE			GENMASK(15, 12)
>  #define HSTX_CKLP_EN			BIT(16)
>  
>  #define DSI_PSCTRL		0x1c
> -#define DSI_PS_WC			0x3fff
> -#define DSI_PS_SEL			(3 << 16)
> +#define DSI_PS_WC			GENMASK(14, 0)
> +#define DSI_PS_SEL			GENMASK(19, 16)

The original definition of DSI_PS_WC/DSI_PS_SEL is correct in MT8173.
So both need two definition and let each SoC select its own definition.

Regards,
CK

>  #define PACKED_PS_16BIT_RGB565		(0 << 16)
>  #define LOOSELY_PS_18BIT_RGB666		(1 << 16)
>  #define PACKED_PS_18BIT_RGB666		(2 << 16)
> @@ -109,26 +109,26 @@
>  #define LD0_WAKEUP_EN			BIT(2)
>  
>  #define DSI_PHY_TIMECON0	0x110
> -#define LPX				(0xff << 0)
> -#define HS_PREP				(0xff << 8)
> -#define HS_ZERO				(0xff << 16)
> -#define HS_TRAIL			(0xff << 24)
> +#define LPX				GENMASK(7, 0)
> +#define HS_PREP				GENMASK(15, 8)
> +#define HS_ZERO				GENMASK(23, 16)
> +#define HS_TRAIL			GENMASK(31, 24)
>  
>  #define DSI_PHY_TIMECON1	0x114
> -#define TA_GO				(0xff << 0)
> -#define TA_SURE				(0xff << 8)
> -#define TA_GET				(0xff << 16)
> -#define DA_HS_EXIT			(0xff << 24)
> +#define TA_GO				GENMASK(7, 0)
> +#define TA_SURE				GENMASK(15, 8)
> +#define TA_GET				GENMASK(23, 16)
> +#define DA_HS_EXIT			GENMASK(31, 24)
>  
>  #define DSI_PHY_TIMECON2	0x118
> -#define CONT_DET			(0xff << 0)
> -#define CLK_ZERO			(0xff << 16)
> -#define CLK_TRAIL			(0xff << 24)
> +#define CONT_DET			GENMASK(7, 0)
> +#define CLK_ZERO			GENMASK(23, 16)
> +#define CLK_TRAIL			GENMASK(31, 24)
>  
>  #define DSI_PHY_TIMECON3	0x11c
> -#define CLK_HS_PREP			(0xff << 0)
> -#define CLK_HS_POST			(0xff << 8)
> -#define CLK_HS_EXIT			(0xff << 16)
> +#define CLK_HS_PREP			GENMASK(7, 0)
> +#define CLK_HS_POST			GENMASK(15, 8)
> +#define CLK_HS_EXIT			GENMASK(23, 16)
>  
>  #define DSI_VM_CMD_CON		0x130
>  #define VM_CMD_EN			BIT(0)
> @@ -138,13 +138,14 @@
>  #define FORCE_COMMIT			BIT(0)
>  #define BYPASS_SHADOW			BIT(1)
>  
> -#define CONFIG				(0xff << 0)
> +/* CMDQ related bits */
> +#define CONFIG				GENMASK(7, 0)
>  #define SHORT_PACKET			0
>  #define LONG_PACKET			2
>  #define BTA				BIT(2)
> -#define DATA_ID				(0xff << 8)
> -#define DATA_0				(0xff << 16)
> -#define DATA_1				(0xff << 24)
> +#define DATA_ID				GENMASK(15, 8)
> +#define DATA_0				GENMASK(23, 16)
> +#define DATA_1				GENMASK(31, 24)
>  
>  #define NS_TO_CYCLE(n, c)    ((n) / (c) + (((n) % (c)) ? 1 : 0))
>  

From Markus.Elfring at web.de  Tue Feb  6 01:21:26 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Tue, 6 Feb 2024 10:21:26 +0100
Subject: [PATCH v2] pmdomain: mediatek: Use devm_platform_ioremap_resource()
 in init_scp()
In-Reply-To: <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
References: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de>
 <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
Message-ID: <6e397bf2-1d45-434f-8619-58a737a138e3@web.de>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Tue, 6 Feb 2024 10:05:34 +0100
Subject: [PATCH v2] pmdomain: mediatek: Use devm_platform_ioremap_resource() in init_scp()

A wrapper function is available since the commit 7945f929f1a77a1c8887a97ca07f87626858ff42
("drivers: provide devm_platform_ioremap_resource()").

* Thus reuse existing functionality instead of keeping duplicate source code.

* Delete a local variable which became unnecessary with this refactoring.


This issue was transformed by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---

v2:
The transformation pattern was adjusted based on advices by known contributors.

Examples:
* Doug Anderson
* Geert Uytterhoeven
* Robin Murphy


 drivers/pmdomain/mediatek/mtk-scpsys.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index b374d01fdac7..59a7a8c261ed 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -425,7 +425,6 @@ static struct scp *init_scp(struct platform_device *pdev,
 			bool bus_prot_reg_update)
 {
 	struct genpd_onecell_data *pd_data;
-	struct resource *res;
 	int i, j;
 	struct scp *scp;
 	struct clk *clk[CLK_MAX];
@@ -441,8 +440,7 @@ static struct scp *init_scp(struct platform_device *pdev,

 	scp->dev = &pdev->dev;

-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	scp->base = devm_ioremap_resource(&pdev->dev, res);
+	scp->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(scp->base))
 		return ERR_CAST(scp->base);

--
2.43.0



From sinthu.raja at mistralsolutions.com  Tue Feb  6 01:23:34 2024
From: sinthu.raja at mistralsolutions.com (Sinthu Raja)
Date: Tue,  6 Feb 2024 14:53:34 +0530
Subject: [PATCH] arm64: dts: ti: k3-am68-sk-som: Add support for OSPI flash
Message-ID: <20240206092334.30307-1-sinthu.raja@ti.com>

From: Sinthu Raja <sinthu.raja at ti.com>

AM68 SK has an OSPI NOR flash on its SOM connected to OSPI0 instance.
Enable support for the same. Also, describe the OSPI flash partition
information through the device tree, according to the offsets in the
bootloader.

Signed-off-by: Sinthu Raja <sinthu.raja at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi | 79 ++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
index 20861a0a46b0..84011d5e1b3b 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
@@ -130,6 +130,25 @@ rtos_ipc_memory_region: ipc-memories at a8000000 {
 	};
 };
 
+&wkup_pmx0 {
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default {
+		pinctrl-single,pins = <
+			J721S2_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (D19) MCU_OSPI0_CLK */
+			J721S2_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F15) MCU_OSPI0_CSn0 */
+			J721S2_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (C19) MCU_OSPI0_D0 */
+			J721S2_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (F16) MCU_OSPI0_D1 */
+			J721S2_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (G15) MCU_OSPI0_D2 */
+			J721S2_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (F18) MCU_OSPI0_D3 */
+			J721S2_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (E19) MCU_OSPI0_D4 */
+			J721S2_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (G19) MCU_OSPI0_D5 */
+			J721S2_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (F19) MCU_OSPI0_D6 */
+			J721S2_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (F20) MCU_OSPI0_D7 */
+			J721S2_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (E18) MCU_OSPI0_DQS */
+			J721S2_WKUP_IOPAD(0x004, PIN_INPUT, 0) /* (E20) MCU_OSPI0_LBCLKO */
+		>;
+	};
+};
+
 &wkup_pmx2 {
 	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
 		pinctrl-single,pins = <
@@ -152,6 +171,66 @@ eeprom at 51 {
 	};
 };
 
+&ospi0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <4>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "ospi.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition at 80000 {
+				label = "ospi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition at 280000 {
+				label = "ospi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition at 680000 {
+				label = "ospi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition at 6c0000 {
+				label = "ospi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition at 800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition at 3fc0000 {
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+};
+
 &mailbox0_cluster0 {
 	status = "okay";
 	interrupts = <436>;
-- 
2.36.1



From angelogioacchino.delregno at collabora.com  Tue Feb  6 01:24:01 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 10:24:01 +0100
Subject: [PATCH] pmdomain: mediatek: Use
 devm_platform_get_and_ioremap_resource() in init_scp()
In-Reply-To: <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
References: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de>
 <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
Message-ID: <cb85caec-d2e3-460b-a9ab-90ef9aacc2ce@collabora.com>

Il 05/02/24 17:31, Geert Uytterhoeven ha scritto:
> Hi Markus,
> 
> On Mon, Feb 5, 2024 at 3:23?PM Markus Elfring <Markus.Elfring at web.de> wrote:
>> From: Markus Elfring <elfring at users.sourceforge.net>
>> Date: Mon, 5 Feb 2024 15:08:27 +0100
>>
>> A wrapper function is available since the commit 890cc39a879906b63912482dfc41944579df2dc6
>> ("drivers: provide devm_platform_get_and_ioremap_resource()").
>> Thus reuse existing functionality instead of keeping duplicate source code.
>>
>> This issue was detected by using the Coccinelle software.
>>
>> Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
> 
> Thanks for your patch!
> 
>> --- a/drivers/pmdomain/mediatek/mtk-scpsys.c
>> +++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
>> @@ -441,8 +441,7 @@ static struct scp *init_scp(struct platform_device *pdev,
>>
>>          scp->dev = &pdev->dev;
>>
>> -       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> -       scp->base = devm_ioremap_resource(&pdev->dev, res);
>> +       scp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> 
> Given res is further unused, please use devm_platform_ioremap_resource()
> instead, and remove the local variable res.
> 

Agreed: res will never be used.

Cheers,
Angelo




From geert at linux-m68k.org  Tue Feb  6 01:26:03 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 6 Feb 2024 10:26:03 +0100
Subject: [PATCH v2] pmdomain: mediatek: Use devm_platform_ioremap_resource()
 in init_scp()
In-Reply-To: <6e397bf2-1d45-434f-8619-58a737a138e3@web.de>
References: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de> <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
 <6e397bf2-1d45-434f-8619-58a737a138e3@web.de>
Message-ID: <CAMuHMdVWbG6vG4PkbBZ2V+GYbFdnxOgogHUrdBNj4bFYaDafKA@mail.gmail.com>

On Tue, Feb 6, 2024 at 10:21?AM Markus Elfring <Markus.Elfring at web.de> wrote:
> From: Markus Elfring <elfring at users.sourceforge.net>
> Date: Tue, 6 Feb 2024 10:05:34 +0100
> Subject: [PATCH v2] pmdomain: mediatek: Use devm_platform_ioremap_resource() in init_scp()
>
> A wrapper function is available since the commit 7945f929f1a77a1c8887a97ca07f87626858ff42
> ("drivers: provide devm_platform_ioremap_resource()").
>
> * Thus reuse existing functionality instead of keeping duplicate source code.
>
> * Delete a local variable which became unnecessary with this refactoring.
>
>
> This issue was transformed by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
> ---
>
> v2:
> The transformation pattern was adjusted based on advices by known contributors.
>
> Examples:
> * Doug Anderson
> * Geert Uytterhoeven
> * Robin Murphy

Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>

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 Feb  6 01:28:07 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 10:28:07 +0100
Subject: [PATCH v2 2/2] phy: add driver for MediaTek XFI T-PHY
In-Reply-To: <2972dfd0b9ca48174fbf49b9d162bac1a12b2331.1707153425.git.daniel@makrotopia.org>
References: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>
 <2972dfd0b9ca48174fbf49b9d162bac1a12b2331.1707153425.git.daniel@makrotopia.org>
Message-ID: <02f4d6ee-e9f6-4184-a125-091f45bae54a@collabora.com>

Il 05/02/24 18:29, Daniel Golle ha scritto:
> Add driver for MediaTek's XFI T-PHY which can be found in the MT7988
> SoC. The XFI T-PHY is a 10 Gigabit/s Ethernet SerDes PHY with muxes on
> the internal side to be used with either USXGMII PCS or LynxI PCS,
> depending on the selected PHY interface mode.
> 
> The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
> PHY_INTERFACE_MODE_* corresponding to the supported modes:
> 
>   * USXGMII                 \
>   * 10GBase-R                }- USXGMII PCS - XGDM  \
>   * 5GBase-R                /                        \
>                                                       }- Ethernet MAC
>   * 2500Base-X              \                        /
>   * 1000Base-X               }- LynxI PCS - GDM     /
>   * Cisco SGMII (MAC side)  /
> 
> In order to work-around a performance issue present on the first of
> two XFI T-PHYs present in MT7988, special tuning is applied which can be
> selected by adding the 'mediatek,usxgmii-performance-errata' property to
> the device tree node.
> 
> There is no documentation for most registers used for the
> analog/tuning part, however, most of the registers have been partially
> reverse-engineered from MediaTek's SDK implementation (an opaque
> sequence of 32-bit register writes) and descriptions for all relevant
> digital registers and bits such as resets and muxes have been supplied
> by MediaTek.
> 
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Feb  6 01:28:38 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 10:28:38 +0100
Subject: [PATCH v2 1/2] dt-bindings: phy: mediatek,mt7988-xfi-tphy: add
 new bindings
In-Reply-To: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>
References: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>
Message-ID: <98c6c8ae-f7cf-4e5d-895a-18cb2dcc5d35@collabora.com>

Il 05/02/24 18:28, Daniel Golle ha scritto:
> Add bindings for the MediaTek XFI Ethernet SerDes T-PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
> via USXGMII PCS:
>   * USXGMII
>   * 10GBase-R
>   * 5GBase-R
> 
> via LynxI SGMII PCS:
>   * 2500Base-X
>   * 1000Base-X
>   * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From geert at linux-m68k.org  Tue Feb  6 01:33:22 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 6 Feb 2024 10:33:22 +0100
Subject: [PATCH 00/18] mfd: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <CAMuHMdU7fYCsNT9ditqJ-saUsRm9J2zLh=-q-zmExhBRJeE8NQ@mail.gmail.com>

Hi Bo,

CC broonie

Thanks for your series!

On Tue, Feb 6, 2024 at 8:16?AM Bo Liu <liubo03 at inspur.com> wrote:
> The maple tree register cache is based on a much more modern data structure
> than the rbtree cache and makes optimisation choices which are probably

probably?

> more appropriate for modern systems than those made by the rbtree cache.
>
> Bo Liu (18):
>   mfd: ac100: convert to use maple tree register cache
>   mfd: as3711: convert to use maple tree register cache
>   mfd: as3722: convert to use maple tree register cache
>   mfd: axp20x: convert to use maple tree register cache
>   mfd: bcm590xx: convert to use maple tree register cache
>   mfd: bd9571mwv: convert to use maple tree register cache
>   mfd: dialog: convert to use maple tree register cache
>   mfd: khadas-mcu: convert to use maple tree register cache
>   mfd: lochnagar-i2c: convert to use maple tree register cache
>   mfd: wolfson: convert to use maple tree register cache
>   mfd: rohm: convert to use maple tree register cache
>   mfd: rk8xx: convert to use maple tree register cache
>   mfd: rn5t618: convert to use maple tree register cache
>   mfd: rsmu_i2c: convert to use maple tree register cache
>   mfd: si476x: convert to use maple tree register cache
>   mfd: stmfx: convert to use maple tree register cache
>   mfd: stpmic1: convert to use maple tree register cache
>   mfd: rc5t583: convert to use maple tree register cache

If all of this is true, is there any reason to keep REGCACHE_RBTREE
around?  If not, perhaps REGCACHE_RBTREE should be treated as
REGCACHE_MAPLE in the regmap core code first, followed by a single
tree-wide patch to replace REGCACHE_RBTREE?

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 Feb  6 01:33:47 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 10:33:47 +0100
Subject: [PATCH v2 11/19] power: reset: mt6323-poweroff: Use
 devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240205194437.180802-12-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
 <20240205194437.180802-12-afd@ti.com>
Message-ID: <f5044987-2514-44cf-83d4-0976b37dc683@collabora.com>

Il 05/02/24 20:44, Andrew Davis ha scritto:
> Use device life-cycle managed register function to simplify probe and
> exit paths.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> ---
>   drivers/power/reset/mt6323-poweroff.c | 28 ++++++++++++++-------------
>   1 file changed, 15 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c
> index 57a63c0ab7fb7..ca5d11b17ff03 100644
> --- a/drivers/power/reset/mt6323-poweroff.c
> +++ b/drivers/power/reset/mt6323-poweroff.c
> @@ -14,6 +14,7 @@
>   #include <linux/platform_device.h>
>   #include <linux/mfd/mt6397/core.h>
>   #include <linux/mfd/mt6397/rtc.h>
> +#include <linux/reboot.h>
>   
>   struct mt6323_pwrc {
>   	struct device *dev;
> @@ -21,11 +22,9 @@ struct mt6323_pwrc {
>   	u32 base;
>   };
>   
> -static struct mt6323_pwrc *mt_pwrc;
> -
> -static void mt6323_do_pwroff(void)
> +static int mt6323_do_pwroff(struct sys_off_data *data)
>   {
> -	struct mt6323_pwrc *pwrc = mt_pwrc;
> +	struct mt6323_pwrc *pwrc = data->cb_data;
>   	unsigned int val;
>   	int ret;
>   
> @@ -44,6 +43,8 @@ static void mt6323_do_pwroff(void)
>   	mdelay(1000);
>   
>   	WARN_ONCE(1, "Unable to power off system\n");
> +
> +	return NOTIFY_DONE;
>   }
>   
>   static int mt6323_pwrc_probe(struct platform_device *pdev)
> @@ -51,6 +52,7 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
>   	struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
>   	struct mt6323_pwrc *pwrc;
>   	struct resource *res;
> +	int ret;
>   
>   	pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
>   	if (!pwrc)
> @@ -63,19 +65,20 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
>   	pwrc->base = res->start;
>   	pwrc->regmap = mt6397_chip->regmap;
>   	pwrc->dev = &pdev->dev;
> -	mt_pwrc = pwrc;
>   
> -	pm_power_off = &mt6323_do_pwroff;
> +	ret = devm_register_sys_off_handler(pwrc->dev,
> +					    SYS_OFF_MODE_POWER_OFF,
> +					    SYS_OFF_PRIO_DEFAULT,
> +					    mt6323_do_pwroff,
> +					    pwrc);

	if (ret)
		return dev_err_probe(....);

Regards,
Angelo

> +	if (ret) {
> +		dev_err(pwrc->dev, "failed to register power-off handler: %d\n", ret);
> +		return ret;
> +	}
>   



From miquel.raynal at bootlin.com  Tue Feb  6 01:34:53 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 6 Feb 2024 10:34:53 +0100
Subject: [PATCH v4 03/12] dt-bindings: mtd: brcmnand: Add ecc strap
 property
In-Reply-To: <ce15922e-4292-41d6-8c5f-2b4fbfa83d5c@broadcom.com>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
	<20240203002834.171462-4-william.zhang@broadcom.com>
	<20240203-expenses-tarmac-c564bc7ae34f@spud>
	<20240205142639.5d7c70f0@xps-13>
	<ce15922e-4292-41d6-8c5f-2b4fbfa83d5c@broadcom.com>
Message-ID: <20240206103453.7ac23384@xps-13>

Hi William,

william.zhang at broadcom.com wrote on Mon, 5 Feb 2024 10:05:14 -0800:

> Hi Miquel,
> 
> On 2/5/24 05:26, Miquel Raynal wrote:
> > Hi,
> > 
> > conor at kernel.org wrote on Sat, 3 Feb 2024 14:49:50 +0000:
> >   
> >> On Fri, Feb 02, 2024 at 04:28:24PM -0800, William Zhang wrote:  
> >>> Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
> >>> board boot strap for broadband board designs because they do not specify
> >>> ecc setting in dts but rather using the strap setting.
> >>>
> >>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> >>>
> >>> ---
> >>>
> >>> Changes in v4:
> >>> - Move ecc strap property to this separate patch and remove some
> >>> non-binding related text from the description
> >>>
> >>> Changes in v3: None
> >>> Changes in v2: None
> >>>
> >>>   Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 8 ++++++++
> >>>   1 file changed, 8 insertions(+)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> >>> index d0168d55c73e..2599d902ec3a 100644
> >>> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> >>> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> >>> @@ -147,6 +147,14 @@ patternProperties:
> >>>             layout.
> >>>           $ref: /schemas/types.yaml#/definitions/uint32  
> >>>   >>> +      brcm,nand-ecc-use-strap:  
> >>> +        description:
> >>> +          This flag indicates the ecc strength and spare area size should
> >>> +          be retrieved from the SoC NAND boot strap setting instead of
> >>> +          nand-ecc-strength and brcm,nand-oob-sector-size or auto detection.  
> >>
> >> I'm still on the fence about this being overly prescriptive about the
> >> operating systems behaviour. I think it would be good to say why the
> >> strap values are better than those explicitly provided in DT rather than
> >> just saying "these strap values should be used".  
> > 
> > I don't know if there is a point is saying why they would be better, as
> > they are not. It is a -questionable- design choice. However I would
> > just get rid of any mention to other properties. Just say one should
> > expect the strap value to be read and applied by the system when this
> > property is present.
> >   
> Agree we don't need to say which is better as it is just a design choice. And it is used by all BCMBCA internal ref boards and customer designs. But if we just say strap value is read and applied, it is vague and nobody would know what is applied.  I replied this email yesterday and suggest the followings:
> 
> This property provides a choice for retrieving ecc strength and spare area size from
 the SoC NAND boot strap setting. It is commonly used by the BCMBCA SoC board design.

What about:

This property requires the host system to get the ECC strength and step
size from the SoC NAND boot strap setting. This is a common hardware
design on BCMBCA based boards.

I would also like to constrain this more by adding an exclusive use wrt
the nand-ecc-* properties. So either you put this property, or you put
the generic nand-ecc-* properties, or you put nothing (which, again, is
by far the best solution), but in no case you can have a mix.

> 
> Hope this make everyone happy and we can move forward.

I was advising to avoid mentioning too specific DT properties, but
mentioning the kind of impact it has (on the choice for the ECC
strength and size) is fine.

> 
> 
> >>> +          This is commonly used by the BCMBCA SoC board design.
> >>> +        $ref: /schemas/types.yaml#/definitions/flag
> >>> +
> >>>       unevaluatedProperties: false  
> >>>   >>>   allOf:
> >>> -- >>> 2.37.3  
> >>>    > >   
> > Thanks,
> > Miqu?l  


Thanks,
Miqu?l


From angelogioacchino.delregno at collabora.com  Tue Feb  6 01:36:09 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 10:36:09 +0100
Subject: [PATCH v2 19/19] power: reset: syscon-poweroff: Use
 devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240205194437.180802-20-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
 <20240205194437.180802-20-afd@ti.com>
Message-ID: <736ee63e-a066-49e8-b1fd-62f0fc665389@collabora.com>

Il 05/02/24 20:44, Andrew Davis ha scritto:
> Use device life-cycle managed register function to simplify probe and
> exit paths.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Feb  6 01:36:10 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 10:36:10 +0100
Subject: [PATCH v2 18/19] power: reset: syscon-poweroff: Move device data
 into a struct
In-Reply-To: <20240205194437.180802-19-afd@ti.com>
References: <20240205194437.180802-1-afd@ti.com>
 <20240205194437.180802-19-afd@ti.com>
Message-ID: <bf4b8c00-cb21-4eae-9bf2-7941dcfae437@collabora.com>

Il 05/02/24 20:44, Andrew Davis ha scritto:
> Currently all these device data elements are top level global variables.
> Move these into a struct. This will be used in the next patch when
> the global variable usage is removed. Doing this in two steps makes
> the patches easier to read.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From broonie at kernel.org  Tue Feb  6 01:37:41 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 06 Feb 2024 09:37:41 +0000
Subject: [PATCH v2] ASoC: pxa: remove duplicated CONFIG_SND_PXA2XX_AC97
 entry
In-Reply-To: <20240204091424.38306-1-masahiroy@kernel.org>
References: <20240204091424.38306-1-masahiroy@kernel.org>
Message-ID: <170721226176.850647.15506347741778971521.b4-ty@kernel.org>

On Sun, 04 Feb 2024 18:14:24 +0900, Masahiro Yamada wrote:
> 'config SND_PXA2XX_AC97' is already present in sound/arm/Kconfig with
> a prompt.
> 
> Commit 734c2d4bb7cf ("[ALSA] ASoC pxa2xx build support") redundantly
> added the second one to sound/soc/pxa/Kconfig.
> 
> Remove it.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: pxa: remove duplicated CONFIG_SND_PXA2XX_AC97 entry
      commit: 8f501d29c7a6a03303c1a085fd27948e1edb0c90

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 yangyicong at huawei.com  Tue Feb  6 01:38:59 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Tue, 6 Feb 2024 17:38:59 +0800
Subject: [RESEND v4] perf stat: Support per-cluster aggregation
In-Reply-To: <20240206091651.00007c1b@Huawei.com>
References: <20240206082016.22292-1-yangyicong@huawei.com>
 <20240206091651.00007c1b@Huawei.com>
Message-ID: <8af31d10-4779-77e7-1774-baf4d9280fbb@huawei.com>

On 2024/2/6 17:16, Jonathan Cameron wrote:
> On Tue, 6 Feb 2024 16:20:16 +0800
> Yicong Yang <yangyicong at huawei.com> wrote:
> 
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> Some platforms have 'cluster' topology and CPUs in the cluster will
>> share resources like L3 Cache Tag (for HiSilicon Kunpeng SoC) or L2
>> cache (for Intel Jacobsville). Currently parsing and building cluster
>> topology have been supported since [1].
>>
>> perf stat has already supported aggregation for other topologies like
>> die or socket, etc. It'll be useful to aggregate per-cluster to find
>> problems like L3T bandwidth contention.
>>
>> This patch add support for "--per-cluster" option for per-cluster
>> aggregation. Also update the docs and related test. The output will
>> be like:
>>
>> [root at localhost tmp]# perf stat -a -e LLC-load --per-cluster -- sleep 5
>>
>>  Performance counter stats for 'system wide':
>>
>> S56-D0-CLS158    4      1,321,521,570      LLC-load
>> S56-D0-CLS594    4        794,211,453      LLC-load
>> S56-D0-CLS1030    4             41,623      LLC-load
>> S56-D0-CLS1466    4             41,646      LLC-load
>> S56-D0-CLS1902    4             16,863      LLC-load
>> S56-D0-CLS2338    4             15,721      LLC-load
>> S56-D0-CLS2774    4             22,671      LLC-load
>> [...]
>>
>> On a legacy system without cluster or cluster support, the output will
>> be look like:
>> [root at localhost perf]# perf stat -a -e cycles --per-cluster -- sleep 1
>>
>>  Performance counter stats for 'system wide':
>>
>> S56-D0-CLS0   64         18,011,485      cycles
>> S7182-D0-CLS0   64         16,548,835      cycles
>>
>> Note that this patch doesn't mix the cluster information in the outputs
>> of --per-core to avoid breaking any tools/scripts using it.
>>
>> Note that perf recently supports "--per-cache" aggregation, but it's not
>> the same with the cluster although cluster CPUs may share some cache
>> resources. For example on my machine all clusters within a die share the
>> same L3 cache:
>> $ cat /sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list
>> 0-31
>> $ cat /sys/devices/system/cpu/cpu0/topology/cluster_cpus_list
>> 0-3
>>
>> [1] commit c5e22feffdd7 ("topology: Represent clusters of CPUs within a die")
>> Tested-by: Jie Zhan <zhanjie9 at hisilicon.com>
>> Reviewed-by: Tim Chen <tim.c.chen at linux.intel.com>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> ---
>> Change since v3:
>> - Rebase on v6.7-rc4 and resolve the conflicts
>> Link: https://lore.kernel.org/all/20230404104951.27537-1-yangyicong at huawei.com/
>>
>> Change since v2:
>> - Use 0 as cluster ID on legacy system without cluster support, keep consistenct
>>   with what --per-die does.
>> Link: https://lore.kernel.org/all/20230328112717.19573-1-yangyicong at huawei.com/
>>
>> Change since v1:
>> - Provides the information about how to map the cluster to the CPUs in the manual
> Given this change incorporates both the case in the example above where PPTT doesn't
> have the IDs set for the Processor Hierarchy nodes and the one where it does 
> (which would be the UIDs of the Processor Containers in DSDT) I think this is sufficient.
> 

Yes the perf only read the IDs from sysfs and if the firmware fill the ID more meaningfully
we should get a more readable output like:
[root at localhost yang]# ./perf stat -e ll_cache_miss --per-cluster --timeout 1000

 Performance counter stats for 'system wide':

S0-D0-CLS0    4             944838      ll_cache_miss
S0-D0-CLS1    4            4067300      ll_cache_miss
S0-D0-CLS2    4           14804515      ll_cache_miss
S0-D0-CLS3    4           11664175      ll_cache_miss
S0-D0-CLS4    4           11301486      ll_cache_miss
S0-D0-CLS5    4           11300000      ll_cache_miss
S0-D0-CLS6    4            1996552      ll_cache_miss
[...]

> Not an expert on perftool but in general this looks both useful and correct to me.
> 

Thanks.

> Jonathan
> 
>> - Thanks the review from Tim and test from Jie.
>> Link: https://lore.kernel.org/all/20230313085911.61359-1-yangyicong at huawei.com/
>>
>>  tools/perf/Documentation/perf-stat.txt        | 11 ++++
>>  tools/perf/builtin-stat.c                     | 52 +++++++++++++++++--
>>  .../tests/shell/lib/perf_json_output_lint.py  |  4 +-
>>  tools/perf/tests/shell/lib/stat_output.sh     | 12 +++++
>>  tools/perf/tests/shell/stat+csv_output.sh     |  2 +
>>  tools/perf/tests/shell/stat+json_output.sh    | 13 +++++
>>  tools/perf/tests/shell/stat+std_output.sh     |  2 +
>>  tools/perf/util/cpumap.c                      | 32 +++++++++++-
>>  tools/perf/util/cpumap.h                      | 19 +++++--
>>  tools/perf/util/env.h                         |  1 +
>>  tools/perf/util/stat-display.c                | 13 +++++
>>  tools/perf/util/stat.h                        |  1 +
>>  12 files changed, 153 insertions(+), 9 deletions(-)
>>
>> diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
>> index 5af2e432b54f..29756a87ab6f 100644
>> --- a/tools/perf/Documentation/perf-stat.txt
>> +++ b/tools/perf/Documentation/perf-stat.txt
>> @@ -308,6 +308,14 @@ use --per-die in addition to -a. (system-wide).  The output includes the
>>  die number and the number of online processors on that die. This is
>>  useful to gauge the amount of aggregation.
>>  
>> +--per-cluster::
>> +Aggregate counts per processor cluster for system-wide mode measurement.  This
>> +is a useful mode to detect imbalance between clusters.  To enable this mode,
>> +use --per-cluster in addition to -a. (system-wide).  The output includes the
>> +cluster number and the number of online processors on that cluster. This is
>> +useful to gauge the amount of aggregation. The information of cluster ID and
>> +related CPUs can be gotten from /sys/devices/system/cpu/cpuX/topology/cluster_{id, cpus}.
>> +
>>  --per-cache::
>>  Aggregate counts per cache instance for system-wide mode measurements.  By
>>  default, the aggregation happens for the cache level at the highest index
>> @@ -396,6 +404,9 @@ Aggregate counts per processor socket for system-wide mode measurements.
>>  --per-die::
>>  Aggregate counts per processor die for system-wide mode measurements.
>>  
>> +--per-cluster::
>> +Aggregate counts perf processor cluster for system-wide mode measurements.
>> +
>>  --per-cache::
>>  Aggregate counts per cache instance for system-wide mode measurements.  By
>>  default, the aggregation happens for the cache level at the highest index
>> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
>> index 5fe9abc6a524..6bba1a89d030 100644
>> --- a/tools/perf/builtin-stat.c
>> +++ b/tools/perf/builtin-stat.c
>> @@ -1238,6 +1238,8 @@ static struct option stat_options[] = {
>>  		     "aggregate counts per processor socket", AGGR_SOCKET),
>>  	OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
>>  		     "aggregate counts per processor die", AGGR_DIE),
>> +	OPT_SET_UINT(0, "per-cluster", &stat_config.aggr_mode,
>> +		     "aggregate counts per processor cluster", AGGR_CLUSTER),
>>  	OPT_CALLBACK_OPTARG(0, "per-cache", &stat_config.aggr_mode, &stat_config.aggr_level,
>>  			    "cache level", "aggregate count at this cache level (Default: LLC)",
>>  			    parse_cache_level),
>> @@ -1428,6 +1430,7 @@ static struct aggr_cpu_id aggr_cpu_id__cache(struct perf_cpu cpu, void *data)
>>  static const char *const aggr_mode__string[] = {
>>  	[AGGR_CORE] = "core",
>>  	[AGGR_CACHE] = "cache",
>> +	[AGGR_CLUSTER] = "cluster",
>>  	[AGGR_DIE] = "die",
>>  	[AGGR_GLOBAL] = "global",
>>  	[AGGR_NODE] = "node",
>> @@ -1455,6 +1458,12 @@ static struct aggr_cpu_id perf_stat__get_cache_id(struct perf_stat_config *confi
>>  	return aggr_cpu_id__cache(cpu, /*data=*/NULL);
>>  }
>>  
>> +static struct aggr_cpu_id perf_stat__get_cluster(struct perf_stat_config *config __maybe_unused,
>> +						 struct perf_cpu cpu)
>> +{
>> +	return aggr_cpu_id__cluster(cpu, /*data=*/NULL);
>> +}
>> +
>>  static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
>>  					      struct perf_cpu cpu)
>>  {
>> @@ -1507,6 +1516,12 @@ static struct aggr_cpu_id perf_stat__get_die_cached(struct perf_stat_config *con
>>  	return perf_stat__get_aggr(config, perf_stat__get_die, cpu);
>>  }
>>  
>> +static struct aggr_cpu_id perf_stat__get_cluster_cached(struct perf_stat_config *config,
>> +							struct perf_cpu cpu)
>> +{
>> +	return perf_stat__get_aggr(config, perf_stat__get_cluster, cpu);
>> +}
>> +
>>  static struct aggr_cpu_id perf_stat__get_cache_id_cached(struct perf_stat_config *config,
>>  							 struct perf_cpu cpu)
>>  {
>> @@ -1544,6 +1559,8 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode)
>>  		return aggr_cpu_id__socket;
>>  	case AGGR_DIE:
>>  		return aggr_cpu_id__die;
>> +	case AGGR_CLUSTER:
>> +		return aggr_cpu_id__cluster;
>>  	case AGGR_CACHE:
>>  		return aggr_cpu_id__cache;
>>  	case AGGR_CORE:
>> @@ -1569,6 +1586,8 @@ static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode)
>>  		return perf_stat__get_socket_cached;
>>  	case AGGR_DIE:
>>  		return perf_stat__get_die_cached;
>> +	case AGGR_CLUSTER:
>> +		return perf_stat__get_cluster_cached;
>>  	case AGGR_CACHE:
>>  		return perf_stat__get_cache_id_cached;
>>  	case AGGR_CORE:
>> @@ -1737,6 +1756,21 @@ static struct aggr_cpu_id perf_env__get_cache_aggr_by_cpu(struct perf_cpu cpu,
>>  	return id;
>>  }
>>  
>> +static struct aggr_cpu_id perf_env__get_cluster_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.cpu != -1) {
>> +		id.socket = env->cpu[cpu.cpu].socket_id;
>> +		id.die = env->cpu[cpu.cpu].die_id;
>> +		id.cluster = env->cpu[cpu.cpu].cluster_id;
>> +	}
>> +
>> +	return id;
>> +}
>> +
>>  static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, void *data)
>>  {
>>  	struct perf_env *env = data;
>> @@ -1744,12 +1778,12 @@ static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, vo
>>  
>>  	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
>> +		 * core_id is relative to socket, die and cluster, we need a
>> +		 * global id. So we set socket, die id, cluster id and core id.
>>  		 */
>>  		id.socket = env->cpu[cpu.cpu].socket_id;
>>  		id.die = env->cpu[cpu.cpu].die_id;
>> +		id.cluster = env->cpu[cpu.cpu].cluster_id;
>>  		id.core = env->cpu[cpu.cpu].core_id;
>>  	}
>>  
>> @@ -1805,6 +1839,12 @@ static struct aggr_cpu_id perf_stat__get_die_file(struct perf_stat_config *confi
>>  	return perf_env__get_die_aggr_by_cpu(cpu, &perf_stat.session->header.env);
>>  }
>>  
>> +static struct aggr_cpu_id perf_stat__get_cluster_file(struct perf_stat_config *config __maybe_unused,
>> +						      struct perf_cpu cpu)
>> +{
>> +	return perf_env__get_cluster_aggr_by_cpu(cpu, &perf_stat.session->header.env);
>> +}
>> +
>>  static struct aggr_cpu_id perf_stat__get_cache_file(struct perf_stat_config *config __maybe_unused,
>>  						    struct perf_cpu cpu)
>>  {
>> @@ -1842,6 +1882,8 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode)
>>  		return perf_env__get_socket_aggr_by_cpu;
>>  	case AGGR_DIE:
>>  		return perf_env__get_die_aggr_by_cpu;
>> +	case AGGR_CLUSTER:
>> +		return perf_env__get_cluster_aggr_by_cpu;
>>  	case AGGR_CACHE:
>>  		return perf_env__get_cache_aggr_by_cpu;
>>  	case AGGR_CORE:
>> @@ -1867,6 +1909,8 @@ static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode)
>>  		return perf_stat__get_socket_file;
>>  	case AGGR_DIE:
>>  		return perf_stat__get_die_file;
>> +	case AGGR_CLUSTER:
>> +		return perf_stat__get_cluster_file;
>>  	case AGGR_CACHE:
>>  		return perf_stat__get_cache_file;
>>  	case AGGR_CORE:
>> @@ -2398,6 +2442,8 @@ static int __cmd_report(int argc, const char **argv)
>>  		     "aggregate counts per processor socket", AGGR_SOCKET),
>>  	OPT_SET_UINT(0, "per-die", &perf_stat.aggr_mode,
>>  		     "aggregate counts per processor die", AGGR_DIE),
>> +	OPT_SET_UINT(0, "per-cluster", &perf_stat.aggr_mode,
>> +		     "aggregate counts perf processor cluster", AGGR_CLUSTER),
>>  	OPT_CALLBACK_OPTARG(0, "per-cache", &perf_stat.aggr_mode, &perf_stat.aggr_level,
>>  			    "cache level",
>>  			    "aggregate count at this cache level (Default: LLC)",
>> diff --git a/tools/perf/tests/shell/lib/perf_json_output_lint.py b/tools/perf/tests/shell/lib/perf_json_output_lint.py
>> index ea55d5ea1ced..abc1fd737782 100644
>> --- a/tools/perf/tests/shell/lib/perf_json_output_lint.py
>> +++ b/tools/perf/tests/shell/lib/perf_json_output_lint.py
>> @@ -15,6 +15,7 @@ ap.add_argument('--event', action='store_true')
>>  ap.add_argument('--per-core', action='store_true')
>>  ap.add_argument('--per-thread', action='store_true')
>>  ap.add_argument('--per-cache', action='store_true')
>> +ap.add_argument('--per-cluster', action='store_true')
>>  ap.add_argument('--per-die', action='store_true')
>>  ap.add_argument('--per-node', action='store_true')
>>  ap.add_argument('--per-socket', action='store_true')
>> @@ -49,6 +50,7 @@ def check_json_output(expected_items):
>>        'cgroup': lambda x: True,
>>        'cpu': lambda x: isint(x),
>>        'cache': lambda x: True,
>> +      'cluster': lambda x: True,
>>        'die': lambda x: True,
>>        'event': lambda x: True,
>>        'event-runtime': lambda x: isfloat(x),
>> @@ -88,7 +90,7 @@ try:
>>      expected_items = 7
>>    elif args.interval or args.per_thread or args.system_wide_no_aggr:
>>      expected_items = 8
>> -  elif args.per_core or args.per_socket or args.per_node or args.per_die or args.per_cache:
>> +  elif args.per_core or args.per_socket or args.per_node or args.per_die or args.per_cluster or args.per_cache:
>>      expected_items = 9
>>    else:
>>      # If no option is specified, don't check the number of items.
>> diff --git a/tools/perf/tests/shell/lib/stat_output.sh b/tools/perf/tests/shell/lib/stat_output.sh
>> index 3cc158a64326..c81d6a9f7983 100644
>> --- a/tools/perf/tests/shell/lib/stat_output.sh
>> +++ b/tools/perf/tests/shell/lib/stat_output.sh
>> @@ -97,6 +97,18 @@ check_per_cache_instance()
>>  	echo "[Success]"
>>  }
>>  
>> +check_per_cluster()
>> +{
>> +	echo -n "Checking $1 output: per cluster "
>> +	if ParanoidAndNotRoot 0
>> +	then
>> +		echo "[Skip] paranoid and not root"
>> +		return
>> +	fi
>> +	perf stat --per-cluster -a $2 true
>> +	echo "[Success]"
>> +}
>> +
>>  check_per_die()
>>  {
>>  	echo -n "Checking $1 output: per die "
>> diff --git a/tools/perf/tests/shell/stat+csv_output.sh b/tools/perf/tests/shell/stat+csv_output.sh
>> index f1818fa6d9ce..fc2d8cc6e5e0 100755
>> --- a/tools/perf/tests/shell/stat+csv_output.sh
>> +++ b/tools/perf/tests/shell/stat+csv_output.sh
>> @@ -42,6 +42,7 @@ function commachecker()
>>  	;; "--per-socket")	exp=8
>>  	;; "--per-node")	exp=8
>>  	;; "--per-die")		exp=8
>> +	;; "--per-cluster")	exp=8
>>  	;; "--per-cache")	exp=8
>>  	esac
>>  
>> @@ -79,6 +80,7 @@ then
>>  	check_system_wide_no_aggr "CSV" "$perf_cmd"
>>  	check_per_core "CSV" "$perf_cmd"
>>  	check_per_cache_instance "CSV" "$perf_cmd"
>> +	check_per_cluster "CSV" "$perf_cmd"
>>  	check_per_die "CSV" "$perf_cmd"
>>  	check_per_socket "CSV" "$perf_cmd"
>>  else
>> diff --git a/tools/perf/tests/shell/stat+json_output.sh b/tools/perf/tests/shell/stat+json_output.sh
>> index 3bc900533a5d..2b9c6212dffc 100755
>> --- a/tools/perf/tests/shell/stat+json_output.sh
>> +++ b/tools/perf/tests/shell/stat+json_output.sh
>> @@ -122,6 +122,18 @@ check_per_cache_instance()
>>  	echo "[Success]"
>>  }
>>  
>> +check_per_cluster()
>> +{
>> +	echo -n "Checking json output: per cluster "
>> +	if ParanoidAndNotRoot 0
>> +	then
>> +		echo "[Skip] paranoia and not root"
>> +		return
>> +	fi
>> +	perf stat -j --per-cluster -a true 2>&1 | $PYTHON $pythonchecker --per-cluster
>> +	echo "[Success]"
>> +}
>> +
>>  check_per_die()
>>  {
>>  	echo -n "Checking json output: per die "
>> @@ -200,6 +212,7 @@ then
>>  	check_system_wide_no_aggr
>>  	check_per_core
>>  	check_per_cache_instance
>> +	check_per_cluster
>>  	check_per_die
>>  	check_per_socket
>>  else
>> diff --git a/tools/perf/tests/shell/stat+std_output.sh b/tools/perf/tests/shell/stat+std_output.sh
>> index 4fcdd1a9142c..16f61e86afc5 100755
>> --- a/tools/perf/tests/shell/stat+std_output.sh
>> +++ b/tools/perf/tests/shell/stat+std_output.sh
>> @@ -40,6 +40,7 @@ function commachecker()
>>  	;; "--per-node")	prefix=3
>>  	;; "--per-die")		prefix=3
>>  	;; "--per-cache")	prefix=3
>> +	;; "--per-cluster")	prefix=3
>>  	esac
>>  
>>  	while read line
>> @@ -99,6 +100,7 @@ then
>>  	check_system_wide_no_aggr "STD" "$perf_cmd"
>>  	check_per_core "STD" "$perf_cmd"
>>  	check_per_cache_instance "STD" "$perf_cmd"
>> +	check_per_cluster "STD" "$perf_cmd"
>>  	check_per_die "STD" "$perf_cmd"
>>  	check_per_socket "STD" "$perf_cmd"
>>  else
>> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
>> index 0581ee0fa5f2..5907456d42a2 100644
>> --- a/tools/perf/util/cpumap.c
>> +++ b/tools/perf/util/cpumap.c
>> @@ -222,6 +222,8 @@ static int aggr_cpu_id__cmp(const void *a_pointer, const void *b_pointer)
>>  		return a->socket - b->socket;
>>  	else if (a->die != b->die)
>>  		return a->die - b->die;
>> +	else if (a->cluster != b->cluster)
>> +		return a->cluster - b->cluster;
>>  	else if (a->cache_lvl != b->cache_lvl)
>>  		return a->cache_lvl - b->cache_lvl;
>>  	else if (a->cache != b->cache)
>> @@ -309,6 +311,29 @@ struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data)
>>  	return id;
>>  }
>>  
>> +int cpu__get_cluster_id(struct perf_cpu cpu)
>> +{
>> +	int value, ret = cpu__get_topology_int(cpu.cpu, "cluster_id", &value);
>> +	return ret ?: value;
>> +}
>> +
>> +struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data)
>> +{
>> +	int cluster = cpu__get_cluster_id(cpu);
>> +	struct aggr_cpu_id id;
>> +
>> +	/* There is no cluster_id on legacy system. */
>> +	if (cluster == -1)
>> +		cluster = 0;
>> +
>> +	id = aggr_cpu_id__die(cpu, data);
>> +	if (aggr_cpu_id__is_empty(&id))
>> +		return id;
>> +
>> +	id.cluster = cluster;
>> +	return id;
>> +}
>> +
>>  int cpu__get_core_id(struct perf_cpu cpu)
>>  {
>>  	int value, ret = cpu__get_topology_int(cpu.cpu, "core_id", &value);
>> @@ -320,8 +345,8 @@ 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);
>>  
>> -	/* aggr_cpu_id__die returns a struct with socket and die set. */
>> -	id = aggr_cpu_id__die(cpu, data);
>> +	/* aggr_cpu_id__die returns a struct with socket die, and cluster set. */
>> +	id = aggr_cpu_id__cluster(cpu, data);
>>  	if (aggr_cpu_id__is_empty(&id))
>>  		return id;
>>  
>> @@ -683,6 +708,7 @@ 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->cluster == b->cluster &&
>>  		a->cache_lvl == b->cache_lvl &&
>>  		a->cache == b->cache &&
>>  		a->core == b->core &&
>> @@ -695,6 +721,7 @@ bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a)
>>  		a->node == -1 &&
>>  		a->socket == -1 &&
>>  		a->die == -1 &&
>> +		a->cluster == -1 &&
>>  		a->cache_lvl == -1 &&
>>  		a->cache == -1 &&
>>  		a->core == -1 &&
>> @@ -708,6 +735,7 @@ struct aggr_cpu_id aggr_cpu_id__empty(void)
>>  		.node = -1,
>>  		.socket = -1,
>>  		.die = -1,
>> +		.cluster = -1,
>>  		.cache_lvl = -1,
>>  		.cache = -1,
>>  		.core = -1,
>> diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
>> index 9df2aeb34d3d..26cf76c693f5 100644
>> --- a/tools/perf/util/cpumap.h
>> +++ b/tools/perf/util/cpumap.h
>> @@ -20,6 +20,8 @@ struct aggr_cpu_id {
>>  	int socket;
>>  	/** The die id as read from /sys/devices/system/cpu/cpuX/topology/die_id. */
>>  	int die;
>> +	/** The cluster id as read from /sys/devices/system/cpu/cpuX/topology/cluster_id */
>> +	int cluster;
>>  	/** The cache level as read from /sys/devices/system/cpu/cpuX/cache/indexY/level */
>>  	int cache_lvl;
>>  	/**
>> @@ -86,6 +88,11 @@ int cpu__get_socket_id(struct perf_cpu cpu);
>>   * /sys/devices/system/cpu/cpuX/topology/die_id for the given CPU.
>>   */
>>  int cpu__get_die_id(struct perf_cpu cpu);
>> +/**
>> + * cpu__get_cluster_id - Returns the cluster id as read from
>> + * /sys/devices/system/cpu/cpuX/topology/cluster_id for the given CPU
>> + */
>> +int cpu__get_cluster_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.
>> @@ -127,9 +134,15 @@ struct aggr_cpu_id aggr_cpu_id__socket(struct perf_cpu 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.
>> + * aggr_cpu_id__cluster - Create an aggr_cpu_id with cluster, die and socket
>> + * populated with the cluster, die and socket for cpu. The function signature
>> + * is compatible with aggr_cpu_id_get_t.
>> + */
>> +struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data);
>> +/**
>> + * aggr_cpu_id__core - Create an aggr_cpu_id with the core, cluster, 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(struct perf_cpu cpu, void *data);
>>  /**
>> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
>> index 7c527e65c186..2a2c37cc40b7 100644
>> --- a/tools/perf/util/env.h
>> +++ b/tools/perf/util/env.h
>> @@ -12,6 +12,7 @@ struct perf_cpu_map;
>>  struct cpu_topology_map {
>>  	int	socket_id;
>>  	int	die_id;
>> +	int	cluster_id;
>>  	int	core_id;
>>  };
>>  
>> diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
>> index 8c61f8627ebc..4dfe7d9517a9 100644
>> --- a/tools/perf/util/stat-display.c
>> +++ b/tools/perf/util/stat-display.c
>> @@ -201,6 +201,9 @@ static void print_aggr_id_std(struct perf_stat_config *config,
>>  		snprintf(buf, sizeof(buf), "S%d-D%d-L%d-ID%d",
>>  			 id.socket, id.die, id.cache_lvl, id.cache);
>>  		break;
>> +	case AGGR_CLUSTER:
>> +		snprintf(buf, sizeof(buf), "S%d-D%d-CLS%d", id.socket, id.die, id.cluster);
>> +		break;
>>  	case AGGR_DIE:
>>  		snprintf(buf, sizeof(buf), "S%d-D%d", id.socket, id.die);
>>  		break;
>> @@ -251,6 +254,10 @@ static void print_aggr_id_csv(struct perf_stat_config *config,
>>  		fprintf(config->output, "S%d-D%d-L%d-ID%d%s%d%s",
>>  			id.socket, id.die, id.cache_lvl, id.cache, sep, aggr_nr, sep);
>>  		break;
>> +	case AGGR_CLUSTER:
>> +		fprintf(config->output, "S%d-D%d-CLS%d%s%d%s",
>> +			id.socket, id.die, id.cluster, sep, aggr_nr, sep);
>> +		break;
>>  	case AGGR_DIE:
>>  		fprintf(output, "S%d-D%d%s%d%s",
>>  			id.socket, id.die, sep, aggr_nr, sep);
>> @@ -300,6 +307,10 @@ static void print_aggr_id_json(struct perf_stat_config *config,
>>  		fprintf(output, "\"cache\" : \"S%d-D%d-L%d-ID%d\", \"aggregate-number\" : %d, ",
>>  			id.socket, id.die, id.cache_lvl, id.cache, aggr_nr);
>>  		break;
>> +	case AGGR_CLUSTER:
>> +		fprintf(output, "\"cluster\" : \"S%d-D%d-CLS%d\", \"aggregate-number\" : %d, ",
>> +			id.socket, id.die, id.cluster, aggr_nr);
>> +		break;
>>  	case AGGR_DIE:
>>  		fprintf(output, "\"die\" : \"S%d-D%d\", \"aggregate-number\" : %d, ",
>>  			id.socket, id.die, aggr_nr);
>> @@ -1248,6 +1259,7 @@ static void print_header_interval_std(struct perf_stat_config *config,
>>  	case AGGR_NODE:
>>  	case AGGR_SOCKET:
>>  	case AGGR_DIE:
>> +	case AGGR_CLUSTER:
>>  	case AGGR_CACHE:
>>  	case AGGR_CORE:
>>  		fprintf(output, "#%*s %-*s cpus",
>> @@ -1550,6 +1562,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
>>  	switch (config->aggr_mode) {
>>  	case AGGR_CORE:
>>  	case AGGR_CACHE:
>> +	case AGGR_CLUSTER:
>>  	case AGGR_DIE:
>>  	case AGGR_SOCKET:
>>  	case AGGR_NODE:
>> diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
>> index 4357ba114822..d6e5c8787ba2 100644
>> --- a/tools/perf/util/stat.h
>> +++ b/tools/perf/util/stat.h
>> @@ -48,6 +48,7 @@ enum aggr_mode {
>>  	AGGR_GLOBAL,
>>  	AGGR_SOCKET,
>>  	AGGR_DIE,
>> +	AGGR_CLUSTER,
>>  	AGGR_CACHE,
>>  	AGGR_CORE,
>>  	AGGR_THREAD,
> 
> .
> 


From vschneid at redhat.com  Tue Feb  6 01:39:28 2024
From: vschneid at redhat.com (Valentin Schneider)
Date: Tue, 06 Feb 2024 10:39:28 +0100
Subject: Question about the ipi_raise filter usage and output
In-Reply-To: <CAJNi4rMiGcP4wdA=1dSOXwYXOKSCWnN8FYxBaFdaAXBqAU_ePQ@mail.gmail.com>
References: <ZcDwoce6Ok25K6Dm@FVFF77S0Q05N>
 <xhsmhmssehp6t.mognet@vschneid-thinkpadt14sgen2i.remote.csb>
 <CAJNi4rMiGcP4wdA=1dSOXwYXOKSCWnN8FYxBaFdaAXBqAU_ePQ@mail.gmail.com>
Message-ID: <xhsmhjznigcdr.mognet@vschneid-thinkpadt14sgen2i.remote.csb>

On 06/02/24 16:42, richard clark wrote:
> On Tue, Feb 6, 2024 at 12:05?AM Valentin Schneider <vschneid at redhat.com> wrote:
>>
>> The CPUS{} thingie only works with an event field that is either declared as a
>> cpumask (__cpumask) or a scalar. That's not the case for ipi_raise, the
>> target_cpus event field is saved as a "raw" bitmask.
>>
>> There /should/ have been a warning about the event filter though, but I
>> think it's not happening because I'm allowing more than just FILTER_CPUMASK
>> in parse_pred() to make it work for scalars. I'll go poke around some more.
>>
>> Generally for this sort of IPI investigation I'd recommend using the newer
>> trace_ipi_send_cpu() and trace_ipi_send_cpumask() (for which CPUS{}
>> filtering works).
>> If it's only the function call interrupts you're interesting in, have a
>> look at trace_csd_queue_cpu().
>
> This should be supported by newer version kernels like v6.5, but I am
> using v6.1 and this trace event has not been supported yet... so ipi
> is more suitable for me. ipi_entry and ipi_exit is ok, but seems the
> filter doesn't support a specific cpu, maybe we need to add this?
>>

You should have access to the generic fields which include the CPU from
which the event happens. Any of "CPU", "cpu" or "common_cpu" would match
this.

So if you're on a recent enough kernel (v6.6 or above AFAICT), you should
be able to do something like so:

  trace-cmd record -e 'ipi_raise' -f 'CPU & CPUS{7-42}' ./foo.sh

If you just want to match a single CPU, or are on an older kernel, this
should work as well:

  trace-cmd record -e 'ipi_raise' -f 'CPU == 42' ./foo.sh

For example on a QEMU x86 environment:

  # trace-cmd record -e 'call_function*' -f 'CPU & CPUS{3}' hackbench
  Running in process mode with 10 groups using 40 file descriptors each (== 400 tasks)
  Each sender will pass 100 messages of 100 bytes
  Time: 0.396
  CPU0 data recorded at offset=0x738000
      0 bytes in size
  CPU1 data recorded at offset=0x738000
      0 bytes in size
  CPU2 data recorded at offset=0x738000
      0 bytes in size
  CPU3 data recorded at offset=0x738000
      4096 bytes in size

  # trace-cmd report
  CPU 0 is empty
  CPU 1 is empty
  CPU 2 is empty
  cpus=4
            <idle>-0     [003]    29.704387: call_function_single_entry: vector=251
            <idle>-0     [003]    29.704388: call_function_single_exit: vector=251
            <idle>-0     [003]    29.705950: call_function_single_entry: vector=251
            <idle>-0     [003]    29.705951: call_function_single_exit: vector=251
            <idle>-0     [003]    29.706462: call_function_single_entry: vector=251
            <idle>-0     [003]    29.706463: call_function_single_exit: vector=251
         hackbench-962   [003]    29.706501: call_function_single_entry: vector=251
         hackbench-962   [003]    29.706502: call_function_single_exit: vector=251
         hackbench-955   [003]    29.706521: call_function_single_entry: vector=251
         hackbench-955   [003]    29.706522: call_function_single_exit: vector=251
            <idle>-0     [003]    30.101812: call_function_single_entry: vector=251
            <idle>-0     [003]    30.101814: call_function_single_exit: vector=251
            <idle>-0     [003]    30.101897: call_function_single_entry: vector=251
            <idle>-0     [003]    30.101898: call_function_single_exit: vector=251
            <idle>-0     [003]    30.101985: call_function_single_entry: vector=251
            <idle>-0     [003]    30.101986: call_function_single_exit: vector=251
            <idle>-0     [003]    30.102072: call_function_single_entry: vector=251
            <idle>-0     [003]    30.102072: call_function_single_exit: vector=251
            <idle>-0     [003]    30.102161: call_function_single_entry: vector=251
            <idle>-0     [003]    30.102161: call_function_single_exit: vector=251
            <idle>-0     [003]    30.102250: call_function_single_entry: vector=251
            <idle>-0     [003]    30.102251: call_function_single_exit: vector=251
            <idle>-0     [003]    30.102372: call_function_single_entry: vector=251
            <idle>-0     [003]    30.102372: call_function_single_exit: vector=251


  CPU 0 is empty
  CPU 1 is empty
  CPU 2 is empty
  cpus=4
          <idle>-0     [003]  1067.718304: call_function_single_entry: vector=251
          <idle>-0     [003]  1067.718309: call_function_single_exit: vector=251

and that behaves the same as

  trace-cmd record -e 'call_function*' -f 'CPU == 3' hackbench



From hj96.nam at samsung.com  Tue Feb  6 01:41:51 2024
From: hj96.nam at samsung.com (Hojin Nam)
Date: Tue, 06 Feb 2024 18:41:51 +0900
Subject: [PATCH] perf: CXL: fix mismatched cpmu event opcode
References: <CGME20240206094151epcms2p373ed7f50efa332765e14bff2b5a2abe2@epcms2p3>
Message-ID: <20240206094151epcms2p373ed7f50efa332765e14bff2b5a2abe2@epcms2p3>

S2M NDR BI-ConflictAck opcode is described as 4 in the CXL
3.0 specification. However, it is defined as 3 in macro definition.

Signed-off-by: Hojin Nam <hj96.nam at samsung.com>
---
 drivers/perf/cxl_pmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index 365d964b0f6a..bc0d414a6aff 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -419,7 +419,7 @@ static struct attribute *cxl_pmu_event_attrs[] = {
        CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmp,                     CXL_PMU_GID_S2M_NDR, BIT(0)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmps,                    CXL_PMU_GID_S2M_NDR, BIT(1)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmpe,                    CXL_PMU_GID_S2M_NDR, BIT(2)),
-       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(3)),
+       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(4)),
        /* CXL rev 3.0 Table 3-46 S2M DRS opcodes */
        CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdata,                 CXL_PMU_GID_S2M_DRS, BIT(0)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdatanxm,              CXL_PMU_GID_S2M_DRS, BIT(1)),
--
2.34.1


From ck.hu at mediatek.com  Tue Feb  6 01:50:41 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 6 Feb 2024 09:50:41 +0000
Subject: [PATCH v3 2/7] drm/mediatek: dsi: Cleanup functions
 mtk_dsi_ps_control{_vact}()
In-Reply-To: <20240131113434.241929-3-angelogioacchino.delregno@collabora.com>
References: <20240131113434.241929-1-angelogioacchino.delregno@collabora.com>
	 <20240131113434.241929-3-angelogioacchino.delregno@collabora.com>
Message-ID: <14e124f02d82ff151974f99d042c4197e4dd5dd7.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-01-31 at 12:34 +0100, AngeloGioacchino Del Regno wrote:
> Function mtk_dsi_ps_control() is a subset of
> mtk_dsi_ps_control_vact():
> merge the two in one mtk_dsi_ps_control() function by adding one
> function parameter `config_vact` which, when true, writes the VACT
> related registers.
> 
> Reviewed-by: Fei Shao <fshao at chromium.org>
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 76 +++++++++-------------------
> --
>  1 file changed, 23 insertions(+), 53 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 3b7392c03b4d..8414ce73ce9f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -351,40 +351,6 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi
> *dsi)
>  	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
>  }
>  
> -static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
> -{
> -	struct videomode *vm = &dsi->vm;
> -	u32 dsi_buf_bpp, ps_wc;
> -	u32 ps_bpp_mode;
> -
> -	if (dsi->format == MIPI_DSI_FMT_RGB565)
> -		dsi_buf_bpp = 2;
> -	else
> -		dsi_buf_bpp = 3;
> -
> -	ps_wc = vm->hactive * dsi_buf_bpp;
> -	ps_bpp_mode = ps_wc;
> -
> -	switch (dsi->format) {
> -	case MIPI_DSI_FMT_RGB888:
> -		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
> -		break;
> -	case MIPI_DSI_FMT_RGB666:
> -		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
> -		break;
> -	case MIPI_DSI_FMT_RGB666_PACKED:
> -		ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;
> -		break;
> -	case MIPI_DSI_FMT_RGB565:
> -		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
> -		break;
> -	}
> -
> -	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
> -	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
> -	writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
> -}
> -
>  static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
>  {
>  	u32 tmp_reg;
> @@ -416,36 +382,40 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi
> *dsi)
>  	writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
>  }
>  
> -static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
> +static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool
> config_vact)
>  {
> -	u32 dsi_tmp_buf_bpp;
> -	u32 tmp_reg;
> +	struct videomode *vm = &dsi->vm;
> +	u32 dsi_buf_bpp, ps_wc;
> +	u32 ps_bpp_mode;
> +
> +	if (dsi->format == MIPI_DSI_FMT_RGB565)
> +		dsi_buf_bpp = 2;
> +	else
> +		dsi_buf_bpp = 3;
> +
> +	ps_wc = vm->hactive * dsi_buf_bpp;
> +	ps_bpp_mode = ps_wc;
>  
>  	switch (dsi->format) {
>  	case MIPI_DSI_FMT_RGB888:
> -		tmp_reg = PACKED_PS_24BIT_RGB888;
> -		dsi_tmp_buf_bpp = 3;
> +		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
>  		break;
>  	case MIPI_DSI_FMT_RGB666:
> -		tmp_reg = LOOSELY_PS_18BIT_RGB666;
> -		dsi_tmp_buf_bpp = 3;
> +		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
>  		break;
>  	case MIPI_DSI_FMT_RGB666_PACKED:
> -		tmp_reg = PACKED_PS_18BIT_RGB666;
> -		dsi_tmp_buf_bpp = 3;
> +		ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;

You change the original logic here. If it is a fixup, separate to a
independent patch not hiding in a clean up patch. So we could backport
the fixup patch.

Regards,
CK

>  		break;
>  	case MIPI_DSI_FMT_RGB565:
> -		tmp_reg = PACKED_PS_16BIT_RGB565;
> -		dsi_tmp_buf_bpp = 2;
> -		break;
> -	default:
> -		tmp_reg = PACKED_PS_24BIT_RGB888;
> -		dsi_tmp_buf_bpp = 3;
> +		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
>  		break;
>  	}
>  
> -	tmp_reg += dsi->vm.hactive * dsi_tmp_buf_bpp & DSI_PS_WC;
> -	writel(tmp_reg, dsi->regs + DSI_PSCTRL);
> +	if (config_vact) {
> +		writel(vm->vactive, dsi->regs + DSI_VACT_NL);
> +		writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
> +	}
> +	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
>  }
>  
>  static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
> @@ -521,7 +491,7 @@ static void mtk_dsi_config_vdo_timing(struct
> mtk_dsi *dsi)
>  	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
>  	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
>  
> -	mtk_dsi_ps_control(dsi);
> +	mtk_dsi_ps_control(dsi, false);
>  }
>  
>  static void mtk_dsi_start(struct mtk_dsi *dsi)
> @@ -666,7 +636,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>  	mtk_dsi_reset_engine(dsi);
>  	mtk_dsi_phy_timconfig(dsi);
>  
> -	mtk_dsi_ps_control_vact(dsi);
> +	mtk_dsi_ps_control(dsi, true);
>  	mtk_dsi_set_vm_cmd(dsi);
>  	mtk_dsi_config_vdo_timing(dsi);
>  	mtk_dsi_set_interrupt_enable(dsi);

From peter.griffin at linaro.org  Tue Feb  6 01:56:04 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 6 Feb 2024 09:56:04 +0000
Subject: [PATCH 1/4] spi: s3c64xx: explicitly include <linux/types.h>
In-Reply-To: <20240206085238.1208256-2-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org> <20240206085238.1208256-2-tudor.ambarus@linaro.org>
Message-ID: <CADrjBPr7AjCOi_sgzpJWRmKdyYkgB8Vcw0HW-e4VKUVh_yT6wA@mail.gmail.com>

On Tue, 6 Feb 2024 at 08:52, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> The driver uses u32 and relies on an implicit inclusion of
> <linux/types.h>.
>
> It is good practice to directly include all headers used, it avoids
> implicit dependencies and spurious breakage if someone rearranges
> headers and causes the implicit include to vanish.
>
> Include the missing header.
>
> Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver")
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>

>  drivers/spi/spi-s3c64xx.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index 72c35dbe53b2..c15ca6a910dc 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -17,6 +17,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/spi/spi.h>
> +#include <linux/types.h>
>
>  #define MAX_SPI_PORTS          12
>  #define S3C64XX_SPI_QUIRK_CS_AUTO      (1 << 1)
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From peter.griffin at linaro.org  Tue Feb  6 01:57:19 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 6 Feb 2024 09:57:19 +0000
Subject: [PATCH 2/4] spi: dt-bindings: samsung: add google,gs101-spi compatible
In-Reply-To: <20240206085238.1208256-3-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org> <20240206085238.1208256-3-tudor.ambarus@linaro.org>
Message-ID: <CADrjBPpLB0RJO6xH=0+jvc=EnaNX6eCg2JV2DNkDdFAoS1mJQw@mail.gmail.com>

On Tue, 6 Feb 2024 at 08:52, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> Add "google,gs101-spi" dedicated compatible for representing SPI of
> Google GS101 SoC.
>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Acked-by: Andi Shyti <andi.shyti at kernel.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.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 f71099852653..2f0a0835ecfb 100644
> --- a/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> +++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> @@ -17,6 +17,7 @@ properties:
>    compatible:
>      oneOf:
>        - enum:
> +          - google,gs101-spi
>            - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
>            - samsung,s3c6410-spi
>            - samsung,s5pv210-spi # for S5PV210 and S5PC110
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From ckeepax at opensource.cirrus.com  Tue Feb  6 01:58:49 2024
From: ckeepax at opensource.cirrus.com (Charles Keepax)
Date: Tue, 6 Feb 2024 09:58:49 +0000
Subject: [PATCH 09/18] mfd: lochnagar-i2c: convert to use maple tree
 register cache
In-Reply-To: <20240206071314.8721-10-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
 <20240206071314.8721-10-liubo03@inspur.com>
Message-ID: <ZcIC2V/hM8nnekJr@ediswmail9.ad.cirrus.com>

On Tue, Feb 06, 2024 at 02:13:05AM -0500, Bo Liu wrote:
> The maple tree register cache is based on a much more modern data structure
> than the rbtree cache and makes optimisation choices which are probably
> more appropriate for modern systems than those made by the rbtree cache.
> 
> Signed-off-by: Bo Liu <liubo03 at inspur.com>
> ---

Tested-by: Charles Keepax <ckeepax at opensource.cirrus.com>
Reviewed-by: Charles Keepax <ckeepax at opensource.cirrus.com>

Thanks,
Charles


From cassel at kernel.org  Tue Feb  6 01:59:26 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 6 Feb 2024 10:59:26 +0100
Subject: [PATCH] dt-bindings: ata: atmel: remove at91 compact flash
 documentation
In-Reply-To: <20240205105201.81060-1-Hari.PrasathGE@microchip.com>
References: <20240205105201.81060-1-Hari.PrasathGE@microchip.com>
Message-ID: <ZcIC/gP0WeI4BYU3@x1-carbon>

On Mon, Feb 05, 2024 at 04:22:01PM +0530, Hari Prasath Gujulan Elango wrote:
> The compatible "at91rm9200-cf" is not used by any driver,hence remove the
> corresponding documentation.
> 
> Signed-off-by: Hari Prasath Gujulan Elango <Hari.PrasathGE at microchip.com>
> ---
>  .../devicetree/bindings/ata/atmel-at91_cf.txt | 19 -------------------
>  1 file changed, 19 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/ata/atmel-at91_cf.txt
> 
> diff --git a/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt b/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt
> deleted file mode 100644
> index c1d22b3ae134..000000000000
> --- a/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -Atmel AT91RM9200 CompactFlash
> -
> -Required properties:
> -- compatible : "atmel,at91rm9200-cf".
> -- reg : should specify localbus address and size used.
> -- gpios : specifies the gpio pins to control the CF device. Detect
> -  and reset gpio's are mandatory while irq and vcc gpio's are
> -  optional and may be set to 0 if not present.
> -
> -Example:
> -compact-flash at 50000000 {
> -	compatible = "atmel,at91rm9200-cf";
> -	reg = <0x50000000 0x30000000>;
> -	gpios = <&pioC 13 0	/* irq */
> -		 &pioC 15 0 	/* detect */
> -		 0		/* vcc */
> -		 &pioC  5 0	/* reset */
> -		>;
> -};
> -- 
> 2.34.1
> 

Applied:
https://git.kernel.org/pub/scm/linux/kernel/git/libata/linux.git/log/?h=for-6.9


From robin.murphy at arm.com  Tue Feb  6 02:00:19 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 6 Feb 2024 10:00:19 +0000
Subject: [PATCH] perf/arm-cmn: Workaround AmpereOneX errata AC04_MESH_1
 (incorrect child count)
In-Reply-To: <20240205194655.1567434-1-ilkka@os.amperecomputing.com>
References: <20240205194655.1567434-1-ilkka@os.amperecomputing.com>
Message-ID: <dd862d7a-11bd-482a-b248-60d4616fb6ef@arm.com>

On 2024-02-05 7:46 pm, Ilkka Koskinen wrote:
> AmpereOneX mesh implementation has a bug in HN-P nodes that makes them
> report incorrect child count. The failing crosspoints report 8 children
> while they only have two.

Ooh, fun :)

> When the driver tries to access the inexistent child nodes, it believes it
> has reached an invalid node type and probing fails. The workaround is to
> ignore those incorrect child nodes and continue normally.
> 
> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
> ---
>   drivers/perf/arm-cmn.c | 25 +++++++++++++++++++++++++
>   1 file changed, 25 insertions(+)
> 
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index c584165b13ba..97fed8ec3693 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -2168,6 +2168,23 @@ static enum cmn_node_type arm_cmn_subtype(enum cmn_node_type type)
>   	}
>   }
>   
> +static inline bool arm_cmn_is_ampereonex_bug(const struct arm_cmn *cmn,
> +					     struct arm_cmn_node *dn,
> +					     u16 child_count, int child)
> +{
> +	/*
> +	 * The bug occurs only when a crosspoint reports 8 children
> +	 * while it only has two HN-P child nodes.
> +	 */
> +	dn -= 2;
> +
> +	if (arm_cmn_model(cmn) == CMN650 && child_count == 8 &&
> +	    child == 2 && dn->type == CMN_TYPE_HNP)
> +		return true;
> +
> +	return false;
> +}
> +
>   static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
>   {
>   	void __iomem *cfg_region;
> @@ -2292,6 +2309,14 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
>   
>   		for (j = 0; j < child_count; j++) {
>   			reg = readq_relaxed(xp_region + child_poff + j * 8);
> +			if (reg == 0)
> +				if (arm_cmn_is_ampereonex_bug(cmn, dn, child_count, j))
> +					/*
> +					 * We know there are only two real children and the rest 6
> +					 * are inexistent. Thus, we can skip the rest of the loop
> +					 */
> +					break;
> +

TBH I don't see much harm in taking an even simpler approach, so I'd be
inclined to not bother being all that specific beyond documenting it,
something like the below:

Cheers,
Robin.

----->8-----

diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index c584165b13ba..7e3aa7e2345f 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -2305,6 +2305,17 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
  				dev_dbg(cmn->dev, "ignoring external node %llx\n", reg);
  				continue;
  			}
+			/*
+			 * AmpereOneX erratum AC04_MESH_1 makes some XPs report a bogus
+			 * child count larger than the number of valid child pointers.
+			 * A child offset of 0 can only occur on CMN-600; otherwise it
+			 * would imply the root node being its own grandchild, which
+			 * we can safely dismiss in general.
+			 */
+			if (reg == 0 && cmn->part != PART_CMN600) {
+				dev_dbg(cmn->dev, "bogus child pointer?\n");
+				continue;
+			}
  
  			arm_cmn_init_node_info(cmn, reg & CMN_CHILD_NODE_ADDR, dn);
  


From ckeepax at opensource.cirrus.com  Tue Feb  6 02:04:07 2024
From: ckeepax at opensource.cirrus.com (Charles Keepax)
Date: Tue, 6 Feb 2024 10:04:07 +0000
Subject: [PATCH 10/18] mfd: wolfson: convert to use maple tree register
 cache
In-Reply-To: <20240206071314.8721-11-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
 <20240206071314.8721-11-liubo03@inspur.com>
Message-ID: <ZcIEFxh76TTXBTiT@ediswmail9.ad.cirrus.com>

On Tue, Feb 06, 2024 at 02:13:06AM -0500, Bo Liu wrote:
> The maple tree register cache is based on a much more modern data structure
> than the rbtree cache and makes optimisation choices which are probably
> more appropriate for modern systems than those made by the rbtree cache.
> 
> Signed-off-by: Bo Liu <liubo03 at inspur.com>
> ---
>  drivers/mfd/wm5102-tables.c | 2 +-
>  drivers/mfd/wm5110-tables.c | 2 +-
>  drivers/mfd/wm8350-regmap.c | 2 +-
>  drivers/mfd/wm8400-core.c   | 2 +-
>  drivers/mfd/wm97xx-core.c   | 6 +++---
>  5 files changed, 7 insertions(+), 7 deletions(-)

The change looks good, but whilst it won't cause any problems, it
seems a bit weird not to convert wm8997, wm8998 and cs47l24.
These are part of the same driver as wm5102 and wm5110.

Reviewed-by: Charles Keepax <ckeepax at opensource.cirrus.com>

Thanks,
Charles


From vaishnav.a at ti.com  Tue Feb  6 02:06:05 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Tue, 6 Feb 2024 15:36:05 +0530
Subject: [PATCH v2 0/3] arm64: dts: ti: Introduce J722S SoC and EVM
Message-ID: <20240206100608.127702-1-vaishnav.a@ti.com>

This series adds basic support for J722S family of SoCs. Also add
J722S EVM support with basic peripheral like MMC and UART.

TRM: https://www.ti.com/lit/zip/sprujb3
EVM Schematics: https://www.ti.com/lit/zip/sprr495

Bootlog (6.8.0-rc3-next-20240206):
https://gist.github.com/vaishnavachath/23d859925277df9ccd628190e7c23371

Changelog:
V1->V2:
  * Address feedback from Nishanth to reuse from AM62P5 dtsi.
  * Remove bootph-all from root nodes.
  * Change License to GPL-2.0-only OR MIT as followed for other
    K3 files.

Vaishnav Achath (3):
  dt-bindings: arm: ti: Add bindings for J722S SoCs
  arm64: dts: ti: Introduce J722S family of SoCs
  arm64: dts: ti: Add support for TI J722S Evaluation Module

 .../devicetree/bindings/arm/ti/k3.yaml        |   6 +
 arch/arm64/boot/dts/ti/Makefile               |   3 +
 arch/arm64/boot/dts/ti/k3-j722s-evm.dts       | 251 ++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-j722s.dtsi          |  89 +++++++
 arch/arm64/boot/dts/ti/k3-pinctrl.h           |   3 +
 5 files changed, 352 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-j722s-evm.dts
 create mode 100644 arch/arm64/boot/dts/ti/k3-j722s.dtsi

-- 
2.34.1



From vaishnav.a at ti.com  Tue Feb  6 02:06:08 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Tue, 6 Feb 2024 15:36:08 +0530
Subject: [PATCH v2 3/3] arm64: dts: ti: Add support for TI J722S Evaluation Module
In-Reply-To: <20240206100608.127702-1-vaishnav.a@ti.com>
References: <20240206100608.127702-1-vaishnav.a@ti.com>
Message-ID: <20240206100608.127702-4-vaishnav.a@ti.com>

Add basic support for the J722S EVM with UART console and
MMC SD as rootfs.

Schematics are available at:
	https://www.ti.com/lit/zip/sprr495

Co-developed-by: Jayesh Choudhary <j-choudhary at ti.com>
Signed-off-by: Jayesh Choudhary <j-choudhary at ti.com>
Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2:
  * Address feedback from Nishanth to reuse from AM62P5 dtsi.
  * Remove bootph-all from root nodes.
  * Change License to GPL-2.0-only OR MIT as followed for other
    K3 files.
  * Add label for reserved_memory node.

 arch/arm64/boot/dts/ti/Makefile         |   3 +
 arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 251 ++++++++++++++++++++++++
 2 files changed, 254 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-j722s-evm.dts

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..ecd11f444e81 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -78,6 +78,9 @@ k3-j721s2-evm-dtbs := k3-j721s2-common-proc-board.dtb k3-j721s2-evm-gesi-exp-boa
 dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-pcie1-ep.dtbo
 
+# Boards with J722s SoC
+dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb
+
 # Boards with J784s4 SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am69-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
new file mode 100644
index 000000000000..b4f2fee53a97
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
@@ -0,0 +1,251 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Device Tree file for the J722S EVM
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Schematics: https://www.ti.com/lit/zip/sprr495
+ */
+
+/dts-v1/;
+
+#include "k3-j722s.dtsi"
+
+/ {
+	compatible = "ti,j722s-evm", "ti,j722s";
+	model = "Texas Instruments J722S EVM";
+
+	aliases {
+		serial0 = &wkup_uart0;
+		serial2 = &main_uart0;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+	};
+
+	chosen {
+		stdout-path = &main_uart0;
+	};
+
+	memory at 80000000 {
+		/* 8G RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+		      <0x00000008 0x80000000 0x00000001 0x80000000>;
+		device_type = "memory";
+		bootph-pre-ram;
+	};
+
+	reserved_memory: reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		secure_tfa_ddr: tfa at 9e780000 {
+			reg = <0x00 0x9e780000 0x00 0x80000>;
+			no-map;
+		};
+
+		secure_ddr: optee at 9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>;
+			no-map;
+		};
+
+		wkup_r5fss0_core0_memory_region: r5f-memory at a0100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0100000 0x00 0xf00000>;
+			no-map;
+		};
+
+	};
+
+	vmain_pd: regulator-0 {
+		/* TPS65988 PD CONTROLLER OUTPUT */
+		compatible = "regulator-fixed";
+		regulator-name = "vmain_pd";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+		bootph-all;
+	};
+
+	vsys_5v0: regulator-vsys5v0 {
+		/* Output of LM5140 */
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vmain_pd>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vdd_mmc1: regulator-mmc1 {
+		/* TPS22918DBVR */
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_mmc1";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		gpio = <&exp1 15 GPIO_ACTIVE_HIGH>;
+		bootph-all;
+	};
+
+	vdd_sd_dv: regulator-TLV71033 {
+		compatible = "regulator-gpio";
+		regulator-name = "tlv71033";
+		pinctrl-names = "default";
+		pinctrl-0 = <&vdd_sd_dv_pins_default>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		vin-supply = <&vsys_5v0>;
+		gpios = <&main_gpio0 70 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x0>,
+			 <3300000 0x1>;
+	};
+
+	vsys_io_1v8: regulator-vsys-io-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_io_1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vsys_io_1v2: regulator-vsys-io-1v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys_io_1v2";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&main_pmx0 {
+
+	main_i2c0_pins_default: main-i2c0-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (D23) I2C0_SCL */
+			J722S_IOPAD(0x01e4, PIN_INPUT_PULLUP, 0) /* (B22) I2C0_SDA */
+		>;
+		bootph-all;
+	};
+
+	main_uart0_pins_default: main-uart0-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x01c8, PIN_INPUT, 0)	/* (A22) UART0_RXD */
+			J722S_IOPAD(0x01cc, PIN_OUTPUT, 0)	/* (B22) UART0_TXD */
+		>;
+		bootph-all;
+	};
+
+	vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0120, PIN_INPUT, 7) /* (F27) MMC2_CMD.GPIO0_70 */
+		>;
+		bootph-all;
+	};
+
+	main_mmc1_pins_default: main-mmc1-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x023c, PIN_INPUT, 0) /* (H22) MMC1_CMD */
+			J722S_IOPAD(0x0234, PIN_OUTPUT, 0) /* (H24) MMC1_CLK */
+			J722S_IOPAD(0x0230, PIN_INPUT, 0) /* (H23) MMC1_DAT0 */
+			J722S_IOPAD(0x022c, PIN_INPUT_PULLUP, 0) /* (H20) MMC1_DAT1 */
+			J722S_IOPAD(0x0228, PIN_INPUT_PULLUP, 0) /* (J23) MMC1_DAT2 */
+			J722S_IOPAD(0x0224, PIN_INPUT_PULLUP, 0) /* (H25) MMC1_DAT3 */
+			J722S_IOPAD(0x0240, PIN_INPUT, 0) /* (B24) MMC1_SDCD */
+		>;
+		bootph-all;
+	};
+};
+
+&main_gpio1 {
+	status = "okay";
+};
+
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_pins_default>;
+	status = "okay";
+	bootph-all;
+};
+
+&mcu_pmx0 {
+
+	wkup_uart0_pins_default: wkup-uart0-default-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x02c, PIN_INPUT, 0)	/* (C7) WKUP_UART0_CTSn */
+			J722S_MCU_IOPAD(0x030, PIN_OUTPUT, 0)	/* (C6) WKUP_UART0_RTSn */
+			J722S_MCU_IOPAD(0x024, PIN_INPUT, 0)	/* (D8) WKUP_UART0_RXD */
+			J722S_MCU_IOPAD(0x028, PIN_OUTPUT, 0)	/* (D7) WKUP_UART0_TXD */
+		>;
+		bootph-all;
+	};
+
+	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+		pinctrl-single,pins = <
+			J722S_MCU_IOPAD(0x04c, PIN_INPUT_PULLUP, 0)	/* (C7) WKUP_I2C0_SCL */
+			J722S_MCU_IOPAD(0x050, PIN_INPUT_PULLUP, 0)	/* (C6) WKUP_I2C1_SDA */
+		>;
+		bootph-all;
+	};
+};
+
+&wkup_uart0 {
+	/* WKUP UART0 is used by Device Manager firmware */
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_uart0_pins_default>;
+	status = "reserved";
+	bootph-all;
+};
+
+&wkup_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_i2c0_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+	bootph-all;
+};
+
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+	bootph-all;
+
+	exp1: gpio at 23 {
+		compatible = "ti,tca6424";
+		reg = <0x23>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "TRC_MUX_SEL", "OSPI/ONAND_MUX_SEL",
+				  "MCASP1_FET_SEL", "CTRL_PM_I2C_OE#",
+				  "CSI_VIO_SEL", "USB2.0_MUX_SEL",
+				  "CSI01_MUX_SEL_2", "CSI23_MUX_SEL_2",
+				  "LMK1_OE1", "LMK1_OE0",
+				  "LMK2_OE0", "LMK2_OE1",
+				  "GPIO_RGMII1_RST#", "GPIO_AUD_RSTn",
+				  "GPIO_eMMC_RSTn", "GPIO_uSD_PWR_EN",
+				  "USER_LED2", "MCAN0_STB",
+				  "PCIe0_1L_RC_RSTz", "PCIe0_1L_PRSNT#",
+				  "ENET1_EXP_SPARE2", "ENET1_EXP_PWRDN",
+				  "PD_I2ENET1_I2CMUX_SELC_IRQ", "ENET1_EXP_RESETZ";
+	};
+};
+
+&sdhci1 {
+	/* SD/MMC */
+	vmmc-supply = <&vdd_mmc1>;
+	vqmmc-supply = <&vdd_sd_dv>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_pins_default>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+	no-1-8-v;
+	status = "okay";
+	bootph-all;
+};
-- 
2.34.1



From vaishnav.a at ti.com  Tue Feb  6 02:06:06 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Tue, 6 Feb 2024 15:36:06 +0530
Subject: [PATCH v2 1/3] dt-bindings: arm: ti: Add bindings for J722S SoCs
In-Reply-To: <20240206100608.127702-1-vaishnav.a@ti.com>
References: <20240206100608.127702-1-vaishnav.a@ti.com>
Message-ID: <20240206100608.127702-2-vaishnav.a@ti.com>

Add bindings for TI J722S family of devices.

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/ti/k3.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
index c6506bccfe88..d52672348424 100644
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -123,6 +123,12 @@ properties:
               - ti,j721s2-evm
           - const: ti,j721s2
 
+      - description: K3 J722S SoC and Boards
+        items:
+          - enum:
+              - ti,j722s-evm
+          - const: ti,j722s
+
       - description: K3 J784s4 SoC
         items:
           - enum:
-- 
2.34.1



From vaishnav.a at ti.com  Tue Feb  6 02:06:07 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Tue, 6 Feb 2024 15:36:07 +0530
Subject: [PATCH v2 2/3] arm64: dts: ti: Introduce J722S family of SoCs
In-Reply-To: <20240206100608.127702-1-vaishnav.a@ti.com>
References: <20240206100608.127702-1-vaishnav.a@ti.com>
Message-ID: <20240206100608.127702-3-vaishnav.a@ti.com>

The J722S is a family of  application processors built for Automotive and
Linux Application development. J722S family of SoCs is a superset of the
AM62P SoC family and shares similar memory map, thus the nodes are being
reused from AM62P includes instead of duplicating the definitions.

Some highlights of J722S SoC (in addition to AM62P SoC features) are:
    * Two Cortex-R5F for Functional Safety or general-purpose usage and
      two C7x floating point vector DSP with Matrix Multiply Accelerator
      for deep learning.
    * Vision Processing Accelerator (VPAC) with image signal processor
      and Depth and Motion Processing Accelerator (DMPAC).
    * 7xUARTs, 3xSPI, 5xI2C, 2xUSB2, 2xCAN-FD, 3xMMC and SD, GPMC for
      NAND/FPGA connection, OSPI memory controller, 5xMcASP for audio,
      4xCSI-RX for Camera, 1 PCIe Gen3 controller, USB3.0 eCAP/eQEP,
      ePWM, among other peripherals.

For those interested, more details about this SoC can be found in the
Technical Reference Manual here:
	https://www.ti.com/lit/zip/sprujb3

Co-developed-by: Jayesh Choudhary <j-choudhary at ti.com>
Signed-off-by: Jayesh Choudhary <j-choudhary at ti.com>
Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

checkpatch error is ignored for arch/arm64/boot/dts/ti/k3-pinctrl.h:
ERROR: Macros with complex values should be enclosed in parentheses

However, we do not need parentheses enclosing the values for this
macro as we do intend it to generate two separate values as has been
done for other similar platforms.

V1->V2:
  * Address feedback from Nishanth to reuse by including AM62P5 dtsi.
  * Remove bootph-all from root nodes.
  * Change License to GPL-2.0-only OR MIT as followed for other
    K3 files.

 arch/arm64/boot/dts/ti/k3-j722s.dtsi | 89 ++++++++++++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-pinctrl.h  |  3 +
 2 files changed, 92 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-j722s.dtsi

diff --git a/arch/arm64/boot/dts/ti/k3-j722s.dtsi b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
new file mode 100644
index 000000000000..c75744edb143
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Device Tree Source for J722S SoC Family
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-am62p5.dtsi"
+
+/ {
+	model = "Texas Instruments K3 J722S SoC";
+	compatible = "ti,j722s";
+
+	cbass_main: bus at f0000 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x00 0x000f0000 0x00 0x000f0000 0x00 0x00030000>, /* Main MMRs */
+			 <0x00 0x00420000 0x00 0x00420000 0x00 0x00001000>, /* ESM0 */
+			 <0x00 0x00600000 0x00 0x00600000 0x00 0x00001100>, /* GPIO */
+			 <0x00 0x00703000 0x00 0x00703000 0x00 0x00000200>, /* USB0 debug trace */
+			 <0x00 0x0070c000 0x00 0x0070c000 0x00 0x00000200>, /* USB1 debug trace */
+			 <0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* Timesync router */
+			 <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First peripheral window */
+			 <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */
+			 <0x00 0x0d000000 0x00 0x0d000000 0x00 0x00800000>, /* PCIE_0 */
+			 <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */
+			 <0x00 0x0fd80000 0x00 0x0fd80000 0x00 0x00080000>, /* GPU */
+			 <0x00 0x0fd20000 0x00 0x0fd20000 0x00 0x00000100>, /* JPEGENC0_CORE */
+			 <0x00 0x0fd20200 0x00 0x0fd20200 0x00 0x00000200>, /* JPEGENC0_CORE_MMU */
+			 <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */
+			 <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */
+			 <0x00 0x301C0000 0x00 0x301C0000 0x00 0x00001000>, /* DPHY-TX */
+			 <0x00 0x30101000 0x00 0x30101000 0x00 0x00080100>, /* CSI window */
+			 <0x00 0x30200000 0x00 0x30200000 0x00 0x00010000>, /* DSS */
+			 <0x00 0x30210000 0x00 0x30210000 0x00 0x00010000>, /* VPU */
+			 <0x00 0x30220000 0x00 0x30220000 0x00 0x00010000>, /* DSS1 */
+			 <0x00 0x30270000 0x00 0x30270000 0x00 0x00010000>, /* DSI-base1 */
+			 <0x00 0x30500000 0x00 0x30500000 0x00 0x00100000>, /* DSI-base2 */
+			 <0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core window */
+			 <0x00 0x31200000 0x00 0x31200000 0x00 0x00040000>, /* USB1 DWC3 Core window */
+			 <0x00 0x40900000 0x00 0x40900000 0x00 0x00030000>, /* SA3UL */
+			 <0x00 0x43600000 0x00 0x43600000 0x00 0x00010000>, /* SA3 sproxy data */
+			 <0x00 0x44043000 0x00 0x44043000 0x00 0x00000fe0>, /* TI SCI DEBUG */
+			 <0x00 0x44860000 0x00 0x44860000 0x00 0x00040000>, /* SA3 sproxy config */
+			 <0x00 0x48000000 0x00 0x48000000 0x00 0x06408000>, /* DMSS */
+			 <0x00 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS0 DAT1 */
+			 <0x00 0x68000000 0x00 0x68000000 0x00 0x08000000>, /* PCIe0 DAT0 */
+			 <0x00 0x70000000 0x00 0x70000000 0x00 0x00040000>, /* OCSRAM */
+			 <0x00 0x78400000 0x00 0x78400000 0x00 0x00008000>, /* MAIN R5FSS0 ATCM */
+			 <0x00 0x78500000 0x00 0x78500000 0x00 0x00008000>, /* MAIN R5FSS0 BTCM */
+			 <0x00 0x7e000000 0x00 0x7e000000 0x00 0x00200000>, /* C7X_0 L2SRAM */
+			 <0x00 0x7e200000 0x00 0x7e200000 0x00 0x00200000>, /* C7X_1 L2SRAM */
+			 <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */
+			 <0x05 0x00000000 0x05 0x00000000 0x01 0x00000000>, /* FSS0 DAT3 */
+			 <0x06 0x00000000 0x06 0x00000000 0x01 0x00000000>, /* PCIe0 DAT1 */
+
+			 /* MCU Domain Range */
+			 <0x00 0x04000000 0x00 0x04000000 0x00 0x01ff1400>,
+			 <0x00 0x79000000 0x00 0x79000000 0x00 0x00008000>,
+			 <0x00 0x79020000 0x00 0x79020000 0x00 0x00008000>,
+			 <0x00 0x79100000 0x00 0x79100000 0x00 0x00040000>,
+			 <0x00 0x79140000 0x00 0x79140000 0x00 0x00040000>,
+
+			 /* Wakeup Domain Range */
+			 <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00002400>,
+			 <0x00 0x2b000000 0x00 0x2b000000 0x00 0x00300400>,
+			 <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>,
+			 <0x00 0x78000000 0x00 0x78000000 0x00 0x00008000>,
+			 <0x00 0x78100000 0x00 0x78100000 0x00 0x00008000>;
+	};
+};
+
+/* Main domain overrides */
+
+&inta_main_dmss {
+	ti,interrupt-ranges = <7 71 21>;
+};
+
+&oc_sram {
+	reg = <0x00 0x70000000 0x00 0x40000>;
+	ranges = <0x00 0x00 0x70000000 0x40000>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-pinctrl.h b/arch/arm64/boot/dts/ti/k3-pinctrl.h
index 2a4e0e084d69..591be4489f37 100644
--- a/arch/arm64/boot/dts/ti/k3-pinctrl.h
+++ b/arch/arm64/boot/dts/ti/k3-pinctrl.h
@@ -59,6 +59,9 @@
 #define J721S2_IOPAD(pa, val, muxmode)		(((pa) & 0x1fff)) ((val) | (muxmode))
 #define J721S2_WKUP_IOPAD(pa, val, muxmode)	(((pa) & 0x1fff)) ((val) | (muxmode))
 
+#define J722S_IOPAD(pa, val, muxmode)		(((pa) & 0x1fff)) ((val) | (muxmode))
+#define J722S_MCU_IOPAD(pa, val, muxmode)	(((pa) & 0x1fff)) ((val) | (muxmode))
+
 #define J784S4_IOPAD(pa, val, muxmode)		(((pa) & 0x1fff)) ((val) | (muxmode))
 #define J784S4_WKUP_IOPAD(pa, val, muxmode)	(((pa) & 0x1fff)) ((val) | (muxmode))
 
-- 
2.34.1



From broonie at kernel.org  Tue Feb  6 02:07:57 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 6 Feb 2024 10:07:57 +0000
Subject: [PATCH 00/18] mfd: convert to use maple tree register cache
In-Reply-To: <CAMuHMdU7fYCsNT9ditqJ-saUsRm9J2zLh=-q-zmExhBRJeE8NQ@mail.gmail.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
 <CAMuHMdU7fYCsNT9ditqJ-saUsRm9J2zLh=-q-zmExhBRJeE8NQ@mail.gmail.com>
Message-ID: <ZcIE/RMTq34TgpQt@finisterre.sirena.org.uk>

On Tue, Feb 06, 2024 at 10:33:22AM +0100, Geert Uytterhoeven wrote:

> If all of this is true, is there any reason to keep REGCACHE_RBTREE
> around?  If not, perhaps REGCACHE_RBTREE should be treated as
> REGCACHE_MAPLE in the regmap core code first, followed by a single
> tree-wide patch to replace REGCACHE_RBTREE?

There is a very small niche for devices where cache syncs are a
particularly important part of the workload where rbtree's choices might
give better performance, especially on systems with low end CPUs.
-------------- 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/20240206/ec3b8597/attachment.sig>

From Jonathan.Cameron at Huawei.com  Tue Feb  6 02:09:29 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Tue, 6 Feb 2024 10:09:29 +0000
Subject: [PATCH] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <20240123071201.30914-1-yangyicong@huawei.com>
References: <20240123071201.30914-1-yangyicong@huawei.com>
Message-ID: <20240206100929.00007128@Huawei.com>

On Tue, 23 Jan 2024 15:12:01 +0800
Yicong Yang <yangyicong at huawei.com> wrote:

> From: Yicong Yang <yangyicong at hisilicon.com>

If you end up doing a v2, a few typos and grammar tweaks.
A few other trivial comments inline on things that might improve readability
a tiny bit.


> 
> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
> throughout and latency of PCIe traffic. With the support of PCIe PMU
> we can enable the perf iostat mode.
> 
> The HiSilicon PCIe PMU can support measuring the throughout of certain
> TLP types and of certian root port. Totally 6 metrics are provided in

certain

> the unit of MB:
> 
> - Inbound MWR: The memory write TLPs from the devices downstream the root port
> - Inbound MRD: The memory read TLPs from the devices downstream the root port
> - Inbound CPL: The completion TLPs from the devices downstream the root port
> - Outbound MWR: The memory write TLPs from the CPU to the downstream devices
> - Outbound MRD: The memory read TLPs from the CPU to the downstream devices
> - Outbound CPL: The completions TLPs from the CPU to the downstream devices
> 
> Since the PMU measures the throughout with unit of DWords. So we need to
throughput in DWords

> calculate the throughout in MB like:
>   Count * 4B / 1024 / 1024
> 
> Some of the display of the `perf iostat` will be like:
> [root at localhost tmp]# ./perf iostat list
> hisi_pcie0_core2<0000:40:00.0>
> hisi_pcie2_core2<0000:5f:00.0>
> hisi_pcie0_core1<0000:16:00.0>
> hisi_pcie0_core1<0000:16:04.0>
> [root at localhost tmp]# ./perf iostat --timeout 10000
> 
>  Performance counter stats for 'system wide':
> 
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
> 
>       10.008227512 seconds time elapsed
> 
> [root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
> -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
> -norandommap -group_reporting -runtime=10 -time_based -bs=64k
> 
>  Performance counter stats for 'system wide':
> 
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
> 
>       10.168561767 seconds time elapsed
> 
>        0.465373000 seconds user
>        1.952948000 seconds sys
> 
> More information of the HiSilicon PCIe PMU can be found at
> Documentation/admin-guide/perf/hisi-pcie-pmu.rst.
> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
>  tools/perf/arch/arm64/util/Build         |   1 +
>  tools/perf/arch/arm64/util/hisi-iostat.c | 433 +++++++++++++++++++++++
>  2 files changed, 434 insertions(+)
>  create mode 100644 tools/perf/arch/arm64/util/hisi-iostat.c
> 
> diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
> index 78ef7115be3d..4e8dabf98b29 100644
> --- a/tools/perf/arch/arm64/util/Build
> +++ b/tools/perf/arch/arm64/util/Build
> @@ -3,6 +3,7 @@ perf-y += machine.o
>  perf-y += perf_regs.o
>  perf-y += tsc.o
>  perf-y += pmu.o
> +perf-y += hisi-iostat.o
>  perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
>  perf-$(CONFIG_DWARF)     += dwarf-regs.o
>  perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
> diff --git a/tools/perf/arch/arm64/util/hisi-iostat.c b/tools/perf/arch/arm64/util/hisi-iostat.c
> new file mode 100644
> index 000000000000..418eebece184
> --- /dev/null
> +++ b/tools/perf/arch/arm64/util/hisi-iostat.c
> @@ -0,0 +1,433 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * perf iostat support for HiSilicon PCIe PMU.
> + * Partly derived from tools/perf/arch/x86/util/iostat.c.
> + *
> + * Copyright (c) 2024 HiSilicon Technologies Co., Ltd.
> + * Author: Yicong Yang <yangyicong at hisilicon.com>
> + */
> +
> +#include <api/fs/fs.h>
> +#include <linux/err.h>
> +#include <linux/zalloc.h>
> +#include <linux/limits.h>
> +#include <dirent.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +
> +#include "util/counts.h"
> +#include "util/cpumap.h"
> +#include "util/debug.h"
> +#include "util/iostat.h"
> +#include "util/pmu.h"
> +
> +#define PCI_DEFAULT_DOMAIN		0
> +#define PCI_DEVICE_NAME_PATTERN		"%04x:%02hhx:%02hhx.%hhu"
> +#define PCI_ROOT_BUS_DEVICES_PATH	"bus/pci/devices"
> +
> +static const char * const hisi_iostat_metrics[] = {
> +	"Inbound MWR(MB)",
> +	"Inbound MRD(MB)",
> +	"Inbound CPL(MB)",
> +	"Outbound MWR(MB)",
> +	"Outbound MRD(MB)",
> +	"Outbound CPL(MB)",
> +};
> +
> +static const char * const hisi_iostat_cmd_template[] = {

Given this array and the one above have to remain in same order, perhaps
an enum?  Would also remove need to have the comments via
[in_bound_wr] = "....
etc


> +	/* Inbound Memory Write */
> +	"hisi_pcie%hu_core%hu/event=0x0104,port=0x%hx/",
> +	/* Inbound Memory Read */
> +	"hisi_pcie%hu_core%hu/event=0x0804,port=0x%hx/",
> +	/* Inbound Memory Completion */
> +	"hisi_pcie%hu_core%hu/event=0x2004,port=0x%hx/",
> +	/* Outbound Memory Write */
> +	"hisi_pcie%hu_core%hu/event=0x0105,port=0x%hx/",
> +	/* Outbound Memory Read */
> +	"hisi_pcie%hu_core%hu/event=0x0405,port=0x%hx/",
> +	/* Outbound Memory Completion */
> +	"hisi_pcie%hu_core%hu/event=0x1005,port=0x%hx/",
> +};
>

...




> +
> +void iostat_print_metric(struct perf_stat_config *config, struct evsel *evsel,
> +			 struct perf_stat_output_ctx *out)
> +{
> +	struct perf_counts_values *count;
> +	const char *iostat_metric;
> +	double iostat_value;
> +
> +	iostat_metric = hisi_iostat_metrics[evsel->core.idx % ARRAY_SIZE(hisi_iostat_metrics)];
> +
> +	/* We're using AGGR_GLOBAL so there's only one aggr counts aggr[0]. */
> +	count = &evsel->stats->aggr[0].counts;
> +
> +	/* The counts has been scaled, we can use it directly. */
> +	iostat_value = (double)count->val;
> +
> +	/*
> +	 * Display two digits after decimal point for better accuracy if the
> +	 * value is non-zero.
> +	 */
> +	out->print_metric(config, out->ctx, NULL,
> +			  iostat_value > 0 ? "%8.2f" : "%8.0f",
> +			  iostat_metric, iostat_value / (256 * 1024));

I assume that 256 * 1024 is MiB/sizeof(dword)?  Perhaps express it as
that to make the reasoning clearer?






From krzysztof.kozlowski at linaro.org  Tue Feb  6 02:10:07 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 6 Feb 2024 11:10:07 +0100
Subject: [PATCH 2/4] arm64: dts: exynos: gs101: add chipid node
In-Reply-To: <CADrjBPpqHx1uoVZCYDX51kW+JdOr_-+4oryOjXcUMFkmLGTBLw@mail.gmail.com>
References: <20240201172224.574238-1-alexey.klimov@linaro.org>
 <20240201172224.574238-2-alexey.klimov@linaro.org>
 <CADrjBPpqHx1uoVZCYDX51kW+JdOr_-+4oryOjXcUMFkmLGTBLw@mail.gmail.com>
Message-ID: <b199ba24-403b-44fa-b807-9b98f9e98913@linaro.org>

On 05/02/2024 15:36, Peter Griffin wrote:
> Hi Alexey & Krysztof,
> 
> On Thu, 1 Feb 2024 at 17:22, Alexey Klimov <alexey.klimov at linaro.org> wrote:
>>
>> Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
>> ---
>>  arch/arm64/boot/dts/exynos/google/gs101.dtsi | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>> index d838e3a7af6e..156fec2575bc 100644
>> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>> @@ -283,6 +283,11 @@ soc: soc at 0 {
>>                 #size-cells = <1>;
>>                 ranges = <0x0 0x0 0x0 0x40000000>;
>>
>> +               chipid at 10000000 {
>> +                       compatible = "google,gs101-chipid";
>> +                       reg = <0x10000000 0xd000>;
>> +               };
>> +
> 
> I was wondering about the 0xd000 size here, as most upstream platforms
> use a chipid size of 0x100 or 0x24. I see the downstream gs101 kernel
> also uses 0xd000. Looking a bit more, that is because gs-chipid.c also
> has support for dumping other areas of the OTP SFR bank like asv table
> (offset 0x9000) hpm_asv (offset 0xa000) and hw_tune (0xc000).
> 
> I checked Exynos850 and that also has ASV tables at those same offsets
> above, but it currently uses a chipid size of 0x100 upstream.
> Exynos-asv.c driver is part of exynos-chipid.c upstream so it seems
> reasonable to have the increased size including those SFR registers.
> Currently exynos-asv.c driver only supports Exynos5422 upstream.
> 
> @Krzysztof - From a process PoV what is the best/correct thing to do
> here? Have the increased size in DT that includes ASV parts of the OTP
> bank from the get-go?

ChipID so far had only size of 0x30 or something like that. What you
refer to does not look like old ChipID but full blown OTP, which also
includes ChipID. Although I am not entirely sure about that, either.
Depends whether they share clocks, for example.

I don't have any GS101 information so I don't know what's there. It
seems you ask me to give you decision based on guessing... If you have
one block, so if there is OTP, which contains ChipID, then define OTP.
Not ChipID+OTP.

I think Exynos850 DTSI is wrong here. That's OTP block, not ChipID.

Best regards,
Krzysztof



From angelogioacchino.delregno at collabora.com  Tue Feb  6 02:10:27 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 11:10:27 +0100
Subject: [PATCH v2] pmdomain: mediatek: Use
 devm_platform_ioremap_resource() in init_scp()
In-Reply-To: <6e397bf2-1d45-434f-8619-58a737a138e3@web.de>
References: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de>
 <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
 <6e397bf2-1d45-434f-8619-58a737a138e3@web.de>
Message-ID: <d5998dd4-d582-488e-b3ef-98ea9737dcfb@collabora.com>

Il 06/02/24 10:21, Markus Elfring ha scritto:
> From: Markus Elfring <elfring at users.sourceforge.net>
> Date: Tue, 6 Feb 2024 10:05:34 +0100
> Subject: [PATCH v2] pmdomain: mediatek: Use devm_platform_ioremap_resource() in init_scp()
> 
> A wrapper function is available since the commit 7945f929f1a77a1c8887a97ca07f87626858ff42
> ("drivers: provide devm_platform_ioremap_resource()").
> 
> * Thus reuse existing functionality instead of keeping duplicate source code.
> 
> * Delete a local variable which became unnecessary with this refactoring.
> 
> 
> This issue was transformed by using the Coccinelle software.
> 
> Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From krzysztof.kozlowski at linaro.org  Tue Feb  6 02:12:22 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 6 Feb 2024 11:12:22 +0100
Subject: [PATCH v2] serial: samsung: honor fifosize from dts at first
In-Reply-To: <20240205082434.36531-1-m.shams@samsung.com>
References: <CGME20240205082441epcas5p1e904f4f95852de3fd8663742ed5131df@epcas5p1.samsung.com>
 <20240205082434.36531-1-m.shams@samsung.com>
Message-ID: <0a2604e7-8b30-4cf9-9099-ba3681bc5538@linaro.org>

On 05/02/2024 09:24, Tamseel Shams wrote:
> Currently for platforms which passes UART fifosize from DT gets
> override by local driver structure "s3c24xx_serial_drv_data",
> which is not intended. Change the code to honor fifosize from
> device tree at first.
> 
> Signed-off-by: Tamseel Shams <m.shams at samsung.com>
> ---
> Change Log:
> v1 -> v2:
> Acknowledged Krzysztof's comments
> Initialized "ret" variable
> 
>  drivers/tty/serial/samsung_tty.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
> index 71d17d804fda..e5dc2c32b1bd 100644
> --- a/drivers/tty/serial/samsung_tty.c
> +++ b/drivers/tty/serial/samsung_tty.c
> @@ -1952,7 +1952,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
>  	struct device_node *np = pdev->dev.of_node;
>  	struct s3c24xx_uart_port *ourport;
>  	int index = probe_index;
> -	int ret, prop = 0;
> +	int ret = 1, prop = 0;

I am sorry, but return of probe function cannot be positive.

>  
>  	if (np) {
>  		ret = of_alias_get_id(np, "serial");
> @@ -1990,8 +1990,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
>  	}
>  
>  	if (np) {
> -		of_property_read_u32(np,
> -			"samsung,uart-fifosize", &ourport->port.fifosize);
> +		ret = of_property_read_u32(np, "samsung,uart-fifosize", &ourport->port.fifosize);
>  
>  		if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
>  			switch (prop) {
> @@ -2009,10 +2008,13 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (ourport->drv_data->fifosize[index])
> -		ourport->port.fifosize = ourport->drv_data->fifosize[index];
> -	else if (ourport->info->fifosize)
> -		ourport->port.fifosize = ourport->info->fifosize;
> +	if (ret) {

Are you sure that you are checking correct ret?

Best regards,
Krzysztof



From peter.griffin at linaro.org  Tue Feb  6 02:12:30 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 6 Feb 2024 10:12:30 +0000
Subject: [PATCH 4/4] spi: s3c64xx: add support for google,gs101-spi
In-Reply-To: <20240206085238.1208256-5-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org> <20240206085238.1208256-5-tudor.ambarus@linaro.org>
Message-ID: <CADrjBPqaE9Mmbr+zkHOAadr3aLSu3GMjS4nPPd4VZY4s2DTznA@mail.gmail.com>

Hi Tudor,

On Tue, 6 Feb 2024 at 08:52, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> Add support for GS101 SPI. GS101 integrates 16 SPI nodes, all with 64
> bytes FIFOs. GS101 allows just 32 bit register accesses, otherwise a
> Serror Interrupt is raised. Do the write reg accesses in 32 bits.
>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

The patch ordering seems a bit off with this series..I believe it should be
1) dt-bindings patch (docs first)
2) Add the use_32bit_io flag / functionality
3) gs101 support (this patch) that uses the use_32bit_io functionality

Peter.

>  drivers/spi/spi-s3c64xx.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index cb45ad615f3d..9ad0d513fb30 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -19,7 +19,7 @@
>  #include <linux/spi/spi.h>
>  #include <linux/types.h>
>
> -#define MAX_SPI_PORTS          12
> +#define MAX_SPI_PORTS          16
>  #define S3C64XX_SPI_QUIRK_CS_AUTO      (1 << 1)
>  #define AUTOSUSPEND_TIMEOUT    2000
>
> @@ -1538,6 +1538,19 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
>         .quirks         = S3C64XX_SPI_QUIRK_CS_AUTO,
>  };
>
> +static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
> +       .fifo_lvl_mask  = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
> +                           0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
> +       .rx_lvl_offset  = 15,
> +       .tx_st_done     = 25,
> +       .clk_div        = 4,
> +       .high_speed     = true,
> +       .clk_from_cmu   = true,
> +       .has_loopback   = true,
> +       .use_32bit_io   = true,
> +       .quirks         = S3C64XX_SPI_QUIRK_CS_AUTO,
> +};
> +
>  static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
>         {
>                 .name           = "s3c2443-spi",
> @@ -1550,6 +1563,9 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
>  };
>
>  static const struct of_device_id s3c64xx_spi_dt_match[] = {
> +       { .compatible = "google,gs101-spi",
> +                       .data = &gs101_spi_port_config,
> +       },
>         { .compatible = "samsung,s3c2443-spi",
>                         .data = &s3c2443_spi_port_config,
>         },
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From krzysztof.kozlowski at linaro.org  Tue Feb  6 02:13:32 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 6 Feb 2024 11:13:32 +0100
Subject: [PATCH 2/4] arm64: dts: exynos: gs101: add chipid node
In-Reply-To: <20240201172224.574238-2-alexey.klimov@linaro.org>
References: <20240201172224.574238-1-alexey.klimov@linaro.org>
 <20240201172224.574238-2-alexey.klimov@linaro.org>
Message-ID: <4c648128-8f87-46b0-a38d-31700d0f0e8d@linaro.org>

On 01/02/2024 18:22, Alexey Klimov wrote:
> Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
> ---
>  arch/arm64/boot/dts/exynos/google/gs101.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> index d838e3a7af6e..156fec2575bc 100644
> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> @@ -283,6 +283,11 @@ soc: soc at 0 {
>  		#size-cells = <1>;
>  		ranges = <0x0 0x0 0x0 0x40000000>;
>  
> +		chipid at 10000000 {
> +			compatible = "google,gs101-chipid";
> +			reg = <0x10000000 0xd000>;

ChipID has size around 0x20 or 0x30, not 0xd000. Maybe you are defining
some other device like OTP?

Best regards,
Krzysztof



From geert at linux-m68k.org  Tue Feb  6 02:14:11 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 6 Feb 2024 11:14:11 +0100
Subject: [PATCH 00/18] mfd: convert to use maple tree register cache
In-Reply-To: <ZcIE/RMTq34TgpQt@finisterre.sirena.org.uk>
References: <20240206071314.8721-1-liubo03@inspur.com> <CAMuHMdU7fYCsNT9ditqJ-saUsRm9J2zLh=-q-zmExhBRJeE8NQ@mail.gmail.com>
 <ZcIE/RMTq34TgpQt@finisterre.sirena.org.uk>
Message-ID: <CAMuHMdVj1bS9s69ASrd5xULc8oELoBbnb8HEX9MEmA43853_EQ@mail.gmail.com>

Hi Mark,

On Tue, Feb 6, 2024 at 11:09?AM Mark Brown <broonie at kernel.org> wrote:
> On Tue, Feb 06, 2024 at 10:33:22AM +0100, Geert Uytterhoeven wrote:
> > If all of this is true, is there any reason to keep REGCACHE_RBTREE
> > around?  If not, perhaps REGCACHE_RBTREE should be treated as
> > REGCACHE_MAPLE in the regmap core code first, followed by a single
> > tree-wide patch to replace REGCACHE_RBTREE?
>
> There is a very small niche for devices where cache syncs are a
> particularly important part of the workload where rbtree's choices might
> give better performance, especially on systems with low end CPUs.

The REGCACHE_* value is specified by the device, not by the CPU?
While some of these MFD devices are on-SoC, and thus there is some
relation between device and CPU, several others (e.g. PMICs) are
external, and thus might be present on systems with a variety of CPU
performance.

Perhaps the value should depend on some CPU heuristic instead?

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 linux.amoon at gmail.com  Tue Feb  6 02:15:16 2024
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 6 Feb 2024 15:45:16 +0530
Subject: [PATCHv1 4/5] arm64: dts: amlogic: Add cache information to the
 Amlogic S922X SoC
In-Reply-To: <cf47b82c-6307-475b-af3a-eab7f09715f0@linaro.org>
References: <20240205171930.968-1-linux.amoon@gmail.com> <20240205171930.968-5-linux.amoon@gmail.com>
 <cf47b82c-6307-475b-af3a-eab7f09715f0@linaro.org>
Message-ID: <CANAwSgTOpDmZGR33veBWrzr75=xEZ-28iu=GeCzqa0ZPXxDchw@mail.gmail.com>

Hi Neil,

On Tue, 6 Feb 2024 at 14:30, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>
> On 05/02/2024 18:19, Anand Moon wrote:
> > As per S922X datasheet add missing cache information to the Amlogic
> > S922X SoC.
> >
> > - Each Cortex-A53 core has 32 KB of instruction cache and
> >       32 KB of L1 data cache available.
> > - Each Cortex-A73 core has 64 KB of L1 instruction cache and
> >       64 KB of L1 data cache available.
> > - The little (A53) cluster has 512 KB of unified L2 cache available.
> > - The big (A73) cluster has 1 MB of unified L2 cache available.
>
> Datasheet says:
> The quad core Cortex?-A73 processor is paired with A53 processor in a big.Little configuration, with each
> core has L1 instruction and data chaches, together with a single shared L2 unified cache with A53
>
Ok,

Since all the Cortex?-A73 and Cortex?-A53 share some improvements in
the architecture with some improvements in cache features
hence I update the changes accordingly.
Also, I checked this in the ARM documentation earlier on this.

> And there's no indication of the L1 or L2 cache sizes.

What I feel is in general all the Cortex?-A73 and Cortex?-A53 supports
L1 and L2 cache size since it is part of the core features.
but I opted for these size values from a Wikipedia article.

On my Odroid N2+, I observe the following.

I have also done some testing on the stress-ng to verify this.

alarm at archl-on2:~$ lscpu
Architecture:           aarch64
  CPU op-mode(s):       32-bit, 64-bit
  Byte Order:           Little Endian
CPU(s):                 6
  On-line CPU(s) list:  0-5
Vendor ID:              ARM
  Model name:           Cortex-A53
    Model:              4
    Thread(s) per core: 1
    Core(s) per socket: 2
    Socket(s):          1
    Stepping:           r0p4
    CPU(s) scaling MHz: 100%
    CPU max MHz:        1800.0000
    CPU min MHz:        1000.0000
    BogoMIPS:           48.00
    Flags:              fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
  Model name:           Cortex-A73
    Model:              2
    Thread(s) per core: 1
    Core(s) per socket: 4
    Socket(s):          1
    Stepping:           r0p2
    CPU(s) scaling MHz: 63%
    CPU max MHz:        2208.0000
    CPU min MHz:        1000.0000
    BogoMIPS:           48.00
    Flags:              fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
Caches (sum of all):
  L1d:                  320 KiB (6 instances)
  L1i:                  320 KiB (6 instances)
  L2:                   1.5 MiB (2 instances)
NUMA:
  NUMA node(s):         1
  NUMA node0 CPU(s):    0-5
Vulnerabilities:
  Gather data sampling: Not affected
  Itlb multihit:        Not affected
  L1tf:                 Not affected
  Mds:                  Not affected
  Meltdown:             Not affected
  Mmio stale data:      Not affected
  Retbleed:             Not affected
  Spec rstack overflow: Not affected
  Spec store bypass:    Vulnerable
  Spectre v1:           Mitigation; __user pointer sanitization
  Spectre v2:           Vulnerable
  Srbds:                Not affected
  Tsx async abort:      Not affected
alarm at archl-on2:~$

alarm at archl-on2:~$ lstopo-no-graphics
Machine (3659MB total)
  Package L#0
    NUMANode L#0 (P#0 3659MB)
    L2 L#0 (512KB)
      L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0 + PU L#0 (P#0)
      L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1 + PU L#1 (P#1)
    L2 L#1 (1024KB)
      L1d L#2 (64KB) + L1i L#2 (64KB) + Core L#2 + PU L#2 (P#2)
      L1d L#3 (64KB) + L1i L#3 (64KB) + Core L#3 + PU L#3 (P#3)
      L1d L#4 (64KB) + L1i L#4 (64KB) + Core L#4 + PU L#4 (P#4)
      L1d L#5 (64KB) + L1i L#5 (64KB) + Core L#5 + PU L#5 (P#5)
  Block "mmcblk1boot0"
  Block "mmcblk1boot1"
  Block "mmcblk1"
  Net "eth0"

 >
> Neil
>

Thanks
-Anand


From krzysztof.kozlowski at linaro.org  Tue Feb  6 02:16:29 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 6 Feb 2024 11:16:29 +0100
Subject: [PATCH 2/3] ARM: dts: samsung: exynos5420-galaxy-tab-common: add
 wifi node
In-Reply-To: <20240130-galaxy-tab-s-cleanup-v1-2-d4e17857241d@grimler.se>
References: <20240130-galaxy-tab-s-cleanup-v1-0-d4e17857241d@grimler.se>
 <20240130-galaxy-tab-s-cleanup-v1-2-d4e17857241d@grimler.se>
Message-ID: <0f207210-07c9-41d1-ad80-11429cbc7cfe@linaro.org>

On 30/01/2024 21:40, Henrik Grimler wrote:
> By using brcm/brcmfmac4354-sdio.bin from linux-firmware together with
> nvram.txt from vendor firmware wifi works well on the chagall-wifi and
> klimt-lte.
> 
> Signed-off-by: Henrik Grimler <henrik at grimler.se>
> ---
>  .../dts/samsung/exynos5420-galaxy-tab-common.dtsi  | 32 ++++++++++++++++++++++
>  1 file changed, 32 insertions(+)

This does not apply, maybe because I skipped patch #1. Please resend.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb  6 02:17:21 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 06 Feb 2024 11:17:21 +0100
Subject: (subset) [PATCH 3/3] ARM: dts: samsung:
 exynos5420-galaxy-tab-common: decrease available memory
In-Reply-To: <20240130-galaxy-tab-s-cleanup-v1-3-d4e17857241d@grimler.se>
References: <20240130-galaxy-tab-s-cleanup-v1-0-d4e17857241d@grimler.se>
 <20240130-galaxy-tab-s-cleanup-v1-3-d4e17857241d@grimler.se>
Message-ID: <170721464155.19396.4129646315750177250.b4-ty@linaro.org>


On Tue, 30 Jan 2024 21:40:41 +0100, Henrik Grimler wrote:
> The last 6 MiB are used by trustzone firmware, and cannot be used by
> Linux.  Currently we are saved by that the proprietary bootloader
> (sboot) passes available memory to kernel through ATAG_MEM.  Change
> memory range in any case so that we do not have to rely on ATAG_MEM.
> 
> 

Applied, thanks!

[3/3] ARM: dts: samsung: exynos5420-galaxy-tab-common: decrease available memory
      https://git.kernel.org/krzk/linux/c/9a5dbb835fd396c78da34b26ee91db6d529d096d

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From heiko at sntech.de  Tue Feb  6 02:21:14 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 06 Feb 2024 11:21:14 +0100
Subject: [PATCH v2 1/2] dt-bindings: phy: Add Rockchip HDMI/eDP Combo PHY schema
In-Reply-To: <20240205-phy-hdptx-v2-1-a7150814c047@collabora.com>
References: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
 <20240205-phy-hdptx-v2-1-a7150814c047@collabora.com>
Message-ID: <8371238.NyiUUSuA9g@diego>

Am Montag, 5. Februar 2024, 12:24:24 CET schrieb Cristian Ciocaltea:
> Add dt-binding schema for the HDMI/eDP Transmitter Combo PHY found on
> Rockchip RK3588 SoC.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>





From Jonathan.Cameron at Huawei.com  Tue Feb  6 02:21:32 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Tue, 6 Feb 2024 10:21:32 +0000
Subject: [PATCH] perf: CXL: fix mismatched cpmu event opcode
In-Reply-To: <20240206094151epcms2p373ed7f50efa332765e14bff2b5a2abe2@epcms2p3>
References: <CGME20240206094151epcms2p373ed7f50efa332765e14bff2b5a2abe2@epcms2p3>
	<20240206094151epcms2p373ed7f50efa332765e14bff2b5a2abe2@epcms2p3>
Message-ID: <20240206102132.00000797@Huawei.com>

On Tue, 06 Feb 2024 18:41:51 +0900
Hojin Nam <hj96.nam at samsung.com> wrote:

> S2M NDR BI-ConflictAck opcode is described as 4 in the CXL
> 3.0 specification. However, it is defined as 3 in macro definition.
> 
Please provide a reference to a specific spec section.
Ideally from r3.1 as that's the easily available version today.
I think this is Table 3-50 S2M NDR Opcodes in r3.1

Looks like s2m_ndr_cmpm should be there for bit 3 so we should probably
add that as part of the fix.


> Signed-off-by: Hojin Nam <hj96.nam at samsung.com>
> ---
>  drivers/perf/cxl_pmu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
> index 365d964b0f6a..bc0d414a6aff 100644
> --- a/drivers/perf/cxl_pmu.c
> +++ b/drivers/perf/cxl_pmu.c
> @@ -419,7 +419,7 @@ static struct attribute *cxl_pmu_event_attrs[] = {
>         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmp,                     CXL_PMU_GID_S2M_NDR, BIT(0)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmps,                    CXL_PMU_GID_S2M_NDR, BIT(1)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmpe,                    CXL_PMU_GID_S2M_NDR, BIT(2)),
> -       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(3)),
> +       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(4)),
>         /* CXL rev 3.0 Table 3-46 S2M DRS opcodes */
>         CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdata,                 CXL_PMU_GID_S2M_DRS, BIT(0)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdatanxm,              CXL_PMU_GID_S2M_DRS, BIT(1)),
> --
> 2.34.1



From ckeepax at opensource.cirrus.com  Tue Feb  6 02:23:27 2024
From: ckeepax at opensource.cirrus.com (Charles Keepax)
Date: Tue, 6 Feb 2024 10:23:27 +0000
Subject: [PATCH 10/18] mfd: wolfson: convert to use maple tree register
 cache
In-Reply-To: <ZcIEFxh76TTXBTiT@ediswmail9.ad.cirrus.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
 <20240206071314.8721-11-liubo03@inspur.com>
 <ZcIEFxh76TTXBTiT@ediswmail9.ad.cirrus.com>
Message-ID: <ZcIIn6b+BFR/FRIS@ediswmail9.ad.cirrus.com>

On Tue, Feb 06, 2024 at 10:04:07AM +0000, Charles Keepax wrote:
> On Tue, Feb 06, 2024 at 02:13:06AM -0500, Bo Liu wrote:
> >  drivers/mfd/wm5102-tables.c | 2 +-
> >  drivers/mfd/wm5110-tables.c | 2 +-
> >  drivers/mfd/wm8350-regmap.c | 2 +-
> >  drivers/mfd/wm8400-core.c   | 2 +-
> >  drivers/mfd/wm97xx-core.c   | 6 +++---
>
> seems a bit weird not to convert wm8997, wm8998 and cs47l24.
> These are part of the same driver as wm5102 and wm5110.

Nevermind, it seems those parts were already converted.

Thanks,
Charles


From robin.murphy at arm.com  Tue Feb  6 02:27:53 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue,  6 Feb 2024 10:27:53 +0000
Subject: [PATCH v3 0/5] perf/arm_cspmu: Add devicetree support
Message-ID: <cover.1706718007.git.robin.murphy@arm.com>

v2: https://lore.kernel.org/linux-arm-kernel/cover.1702571292.git.robin.murphy at arm.com/

Hi all,

Third time lucky... here's a hopefully-final spin to address the
functional issues Besar pointed out, and give a little final polish to
the binding (although I stand firm on teh point of a trivial example
not being valuable :))

Cheers,
Robin.


Robin Murphy (5):
  perf/arm_cspmu: Simplify initialisation
  perf/arm_cspmu: Simplify attribute groups
  perf/arm_cspmu: Simplify counter reset
  dt-bindings/perf: Add Arm CoreSight PMU
  perf/arm_cspmu: Add devicetree support

 .../bindings/perf/arm,coresight-pmu.yaml      |  39 +++++
 drivers/perf/arm_cspmu/arm_cspmu.c            | 153 ++++++++++--------
 drivers/perf/arm_cspmu/arm_cspmu.h            |   1 +
 drivers/perf/arm_cspmu/nvidia_cspmu.c         |   6 -
 4 files changed, 126 insertions(+), 73 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/perf/arm,coresight-pmu.yaml

-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Tue Feb  6 02:27:55 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue,  6 Feb 2024 10:27:55 +0000
Subject: [PATCH v3 2/5] perf/arm_cspmu: Simplify attribute groups
In-Reply-To: <cover.1706718007.git.robin.murphy@arm.com>
References: <cover.1706718007.git.robin.murphy@arm.com>
Message-ID: <cf12b803114b0815438833fcb2495f20f2007761.1706718007.git.robin.murphy@arm.com>

The attribute group array itself is always the same, so there's no
need to allocate it separately. Storing it directly in our instance
data saves memory and gives us one less point of failure.

Reviewed-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/perf/arm_cspmu/arm_cspmu.c | 26 +++++++++-----------------
 drivers/perf/arm_cspmu/arm_cspmu.h |  1 +
 2 files changed, 10 insertions(+), 17 deletions(-)

diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index 7c8a6bd940f4..b888473ec71f 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -501,23 +501,16 @@ arm_cspmu_alloc_format_attr_group(struct arm_cspmu *cspmu)
 	return format_group;
 }
 
-static struct attribute_group **
-arm_cspmu_alloc_attr_group(struct arm_cspmu *cspmu)
+static int arm_cspmu_alloc_attr_groups(struct arm_cspmu *cspmu)
 {
-	struct attribute_group **attr_groups = NULL;
-	struct device *dev = cspmu->dev;
+	const struct attribute_group **attr_groups = cspmu->attr_groups;
 	const struct arm_cspmu_impl_ops *impl_ops = &cspmu->impl.ops;
 
 	cspmu->identifier = impl_ops->get_identifier(cspmu);
 	cspmu->name = impl_ops->get_name(cspmu);
 
 	if (!cspmu->identifier || !cspmu->name)
-		return NULL;
-
-	attr_groups = devm_kcalloc(dev, 5, sizeof(struct attribute_group *),
-				   GFP_KERNEL);
-	if (!attr_groups)
-		return NULL;
+		return -ENOMEM;
 
 	attr_groups[0] = arm_cspmu_alloc_event_attr_group(cspmu);
 	attr_groups[1] = arm_cspmu_alloc_format_attr_group(cspmu);
@@ -525,9 +518,9 @@ arm_cspmu_alloc_attr_group(struct arm_cspmu *cspmu)
 	attr_groups[3] = &arm_cspmu_cpumask_attr_group;
 
 	if (!attr_groups[0] || !attr_groups[1])
-		return NULL;
+		return -ENOMEM;
 
-	return attr_groups;
+	return 0;
 }
 
 static inline void arm_cspmu_reset_counters(struct arm_cspmu *cspmu)
@@ -1164,11 +1157,10 @@ static int arm_cspmu_get_cpus(struct arm_cspmu *cspmu)
 static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
 {
 	int ret, capabilities;
-	struct attribute_group **attr_groups;
 
-	attr_groups = arm_cspmu_alloc_attr_group(cspmu);
-	if (!attr_groups)
-		return -ENOMEM;
+	ret = arm_cspmu_alloc_attr_groups(cspmu);
+	if (ret)
+		return ret;
 
 	ret = cpuhp_state_add_instance(arm_cspmu_cpuhp_state,
 				       &cspmu->cpuhp_node);
@@ -1190,7 +1182,7 @@ static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
 		.start		= arm_cspmu_start,
 		.stop		= arm_cspmu_stop,
 		.read		= arm_cspmu_read,
-		.attr_groups	= (const struct attribute_group **)attr_groups,
+		.attr_groups	= cspmu->attr_groups,
 		.capabilities	= capabilities,
 	};
 
diff --git a/drivers/perf/arm_cspmu/arm_cspmu.h b/drivers/perf/arm_cspmu/arm_cspmu.h
index 2fe723555a6b..c9163acfe810 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.h
+++ b/drivers/perf/arm_cspmu/arm_cspmu.h
@@ -157,6 +157,7 @@ struct arm_cspmu {
 	int cycle_counter_logical_idx;
 
 	struct arm_cspmu_hw_events hw_events;
+	const struct attribute_group *attr_groups[5];
 
 	struct arm_cspmu_impl impl;
 };
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Tue Feb  6 02:27:57 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue,  6 Feb 2024 10:27:57 +0000
Subject: [PATCH v3 4/5] dt-bindings/perf: Add Arm CoreSight PMU
In-Reply-To: <cover.1706718007.git.robin.murphy@arm.com>
References: <cover.1706718007.git.robin.murphy@arm.com>
Message-ID: <c62a86ef177bec5c6d12176c605de900e9e40c87.1706718007.git.robin.murphy@arm.com>

Add a binding for implementations of the Arm CoreSight Performance
Monitoring Unit Architecture. Not to be confused with CoreSight debug
and trace, the PMU architecture defines a standard MMIO interface for
event counters following a similar design to the CPU PMU architecture,
where the implementation and most of its features are discoverable
through ID registers.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
v2: Use reg-io-width instead of a new property; tweak descriptions
v3: Tweak formatting
---
 .../bindings/perf/arm,coresight-pmu.yaml      | 39 +++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/perf/arm,coresight-pmu.yaml

diff --git a/Documentation/devicetree/bindings/perf/arm,coresight-pmu.yaml b/Documentation/devicetree/bindings/perf/arm,coresight-pmu.yaml
new file mode 100644
index 000000000000..985b62990f80
--- /dev/null
+++ b/Documentation/devicetree/bindings/perf/arm,coresight-pmu.yaml
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/perf/arm,coresight-pmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Arm Coresight Performance Monitoring Unit Architecture
+
+maintainers:
+  - Robin Murphy <robin.murphy at arm.com>
+
+properties:
+  compatible:
+    const: arm,coresight-pmu
+
+  reg:
+    items:
+      - description: Register page 0
+      - description: Register page 1, if the PMU implements the dual-page extension
+    minItems: 1
+
+  interrupts:
+    items:
+      - description: Overflow interrupt
+
+  cpus:
+    description: If the PMU is associated with a particular CPU or subset of CPUs,
+      array of phandles to the appropriate CPU node(s)
+
+  reg-io-width:
+    description: Granularity at which PMU register accesses are single-copy atomic
+    default: 4
+    enum: [4, 8]
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Tue Feb  6 02:27:54 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue,  6 Feb 2024 10:27:54 +0000
Subject: [PATCH v3 1/5] perf/arm_cspmu: Simplify initialisation
In-Reply-To: <cover.1706718007.git.robin.murphy@arm.com>
References: <cover.1706718007.git.robin.murphy@arm.com>
Message-ID: <dd39718ee4890fd46a8e443c25303e87ae23f422.1706718007.git.robin.murphy@arm.com>

It's far simpler for implementations to literally override whichever
default ops they want to, by initialising to the default ops first. This
saves all the bother of checking what the impl_init_ops call has or
hasn't touched. Make the same clear distinction for the PMIIDR override
as well, in case we gain more sources for overriding that in future.

Reviewed-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/perf/arm_cspmu/arm_cspmu.c    | 55 +++++++++++----------------
 drivers/perf/arm_cspmu/nvidia_cspmu.c |  6 ---
 2 files changed, 22 insertions(+), 39 deletions(-)

diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index 50b89b989ce7..7c8a6bd940f4 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -100,13 +100,6 @@
 #define ARM_CSPMU_ACTIVE_CPU_MASK		0x0
 #define ARM_CSPMU_ASSOCIATED_CPU_MASK		0x1
 
-/* Check and use default if implementer doesn't provide attribute callback */
-#define CHECK_DEFAULT_IMPL_OPS(ops, callback)			\
-	do {							\
-		if (!ops->callback)				\
-			ops->callback = arm_cspmu_ ## callback;	\
-	} while (0)
-
 /*
  * Maximum poll count for reading counter value using high-low-high sequence.
  */
@@ -408,21 +401,32 @@ static struct arm_cspmu_impl_match *arm_cspmu_impl_match_get(u32 pmiidr)
 	return NULL;
 }
 
+#define DEFAULT_IMPL_OP(name)	.name = arm_cspmu_##name
+
 static int arm_cspmu_init_impl_ops(struct arm_cspmu *cspmu)
 {
 	int ret = 0;
-	struct arm_cspmu_impl_ops *impl_ops = &cspmu->impl.ops;
 	struct acpi_apmt_node *apmt_node = arm_cspmu_apmt_node(cspmu->dev);
 	struct arm_cspmu_impl_match *match;
 
-	/*
-	 * Get PMU implementer and product id from APMT node.
-	 * If APMT node doesn't have implementer/product id, try get it
-	 * from PMIIDR.
-	 */
-	cspmu->impl.pmiidr =
-		(apmt_node->impl_id) ? apmt_node->impl_id :
-				       readl(cspmu->base0 + PMIIDR);
+	/* Start with a default PMU implementation */
+	cspmu->impl.module = THIS_MODULE;
+	cspmu->impl.pmiidr = readl(cspmu->base0 + PMIIDR);
+	cspmu->impl.ops = (struct arm_cspmu_impl_ops) {
+		DEFAULT_IMPL_OP(get_event_attrs),
+		DEFAULT_IMPL_OP(get_format_attrs),
+		DEFAULT_IMPL_OP(get_identifier),
+		DEFAULT_IMPL_OP(get_name),
+		DEFAULT_IMPL_OP(is_cycle_counter_event),
+		DEFAULT_IMPL_OP(event_type),
+		DEFAULT_IMPL_OP(event_filter),
+		DEFAULT_IMPL_OP(set_ev_filter),
+		DEFAULT_IMPL_OP(event_attr_is_visible),
+	};
+
+	/* Firmware may override implementer/product ID from PMIIDR */
+	if (apmt_node->impl_id)
+		cspmu->impl.pmiidr = apmt_node->impl_id;
 
 	/* Find implementer specific attribute ops. */
 	match = arm_cspmu_impl_match_get(cspmu->impl.pmiidr);
@@ -450,24 +454,9 @@ static int arm_cspmu_init_impl_ops(struct arm_cspmu *cspmu)
 		}
 
 		mutex_unlock(&arm_cspmu_lock);
+	}
 
-		if (ret)
-			return ret;
-	} else
-		cspmu->impl.module = THIS_MODULE;
-
-	/* Use default callbacks if implementer doesn't provide one. */
-	CHECK_DEFAULT_IMPL_OPS(impl_ops, get_event_attrs);
-	CHECK_DEFAULT_IMPL_OPS(impl_ops, get_format_attrs);
-	CHECK_DEFAULT_IMPL_OPS(impl_ops, get_identifier);
-	CHECK_DEFAULT_IMPL_OPS(impl_ops, get_name);
-	CHECK_DEFAULT_IMPL_OPS(impl_ops, is_cycle_counter_event);
-	CHECK_DEFAULT_IMPL_OPS(impl_ops, event_type);
-	CHECK_DEFAULT_IMPL_OPS(impl_ops, event_filter);
-	CHECK_DEFAULT_IMPL_OPS(impl_ops, event_attr_is_visible);
-	CHECK_DEFAULT_IMPL_OPS(impl_ops, set_ev_filter);
-
-	return 0;
+	return ret;
 }
 
 static struct attribute_group *
diff --git a/drivers/perf/arm_cspmu/nvidia_cspmu.c b/drivers/perf/arm_cspmu/nvidia_cspmu.c
index 0382b702f092..5b84b701ad62 100644
--- a/drivers/perf/arm_cspmu/nvidia_cspmu.c
+++ b/drivers/perf/arm_cspmu/nvidia_cspmu.c
@@ -388,12 +388,6 @@ static int nv_cspmu_init_ops(struct arm_cspmu *cspmu)
 	impl_ops->get_format_attrs		= nv_cspmu_get_format_attrs;
 	impl_ops->get_name			= nv_cspmu_get_name;
 
-	/* Set others to NULL to use default callback. */
-	impl_ops->event_type			= NULL;
-	impl_ops->event_attr_is_visible		= NULL;
-	impl_ops->get_identifier		= NULL;
-	impl_ops->is_cycle_counter_event	= NULL;
-
 	return 0;
 }
 
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Tue Feb  6 02:27:56 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue,  6 Feb 2024 10:27:56 +0000
Subject: [PATCH v3 3/5] perf/arm_cspmu: Simplify counter reset
In-Reply-To: <cover.1706718007.git.robin.murphy@arm.com>
References: <cover.1706718007.git.robin.murphy@arm.com>
Message-ID: <3105815327989f6bb7bb068994d0eb4096b4ef64.1706718007.git.robin.murphy@arm.com>

arm_cspmu_reset_counters() inherently also stops them since it is
writing 0 to PMCR.E, so there should be no need to do that twice.
Also tidy up the reset routine itself for consistency with the start
and stop routines, and to be clear at first glance that it is simply
writing a constant value.

Reviewed-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/perf/arm_cspmu/arm_cspmu.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index b888473ec71f..b54dc7fd6ca5 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -525,11 +525,7 @@ static int arm_cspmu_alloc_attr_groups(struct arm_cspmu *cspmu)
 
 static inline void arm_cspmu_reset_counters(struct arm_cspmu *cspmu)
 {
-	u32 pmcr = 0;
-
-	pmcr |= PMCR_P;
-	pmcr |= PMCR_C;
-	writel(pmcr, cspmu->base0 + PMCR);
+	writel(PMCR_C | PMCR_P, cspmu->base0 + PMCR);
 }
 
 static inline void arm_cspmu_start_counters(struct arm_cspmu *cspmu)
@@ -1187,7 +1183,6 @@ static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
 	};
 
 	/* Hardware counter init */
-	arm_cspmu_stop_counters(cspmu);
 	arm_cspmu_reset_counters(cspmu);
 
 	ret = perf_pmu_register(&cspmu->pmu, cspmu->name, -1);
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Tue Feb  6 02:27:58 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue,  6 Feb 2024 10:27:58 +0000
Subject: [PATCH v3 5/5] perf/arm_cspmu: Add devicetree support
In-Reply-To: <cover.1706718007.git.robin.murphy@arm.com>
References: <cover.1706718007.git.robin.murphy@arm.com>
Message-ID: <836722034302ff62f2df56aaeb0036e71945a5d1.1706718007.git.robin.murphy@arm.com>

Hook up devicetree probing support. For now let's hope that people
implement PMIIDR properly and we don't need an override property or
match data mechanism.

Reviewed-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
v2: Use APMT node to distinguish ACPI; adjust for binding change
v3: Handle NULL APMT node properly, fix phandle iteration.
---
 drivers/perf/arm_cspmu/arm_cspmu.c | 67 ++++++++++++++++++++++++------
 1 file changed, 55 insertions(+), 12 deletions(-)

diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c b/drivers/perf/arm_cspmu/arm_cspmu.c
index b54dc7fd6ca5..6bc21ef96250 100644
--- a/drivers/perf/arm_cspmu/arm_cspmu.c
+++ b/drivers/perf/arm_cspmu/arm_cspmu.c
@@ -27,6 +27,7 @@
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/of.h>
 #include <linux/perf_event.h>
 #include <linux/platform_device.h>
 
@@ -114,7 +115,9 @@ static void arm_cspmu_set_ev_filter(struct arm_cspmu *cspmu,
 
 static struct acpi_apmt_node *arm_cspmu_apmt_node(struct device *dev)
 {
-	return *(struct acpi_apmt_node **)dev_get_platdata(dev);
+	struct acpi_apmt_node **ptr = dev_get_platdata(dev);
+
+	return ptr ? *ptr : NULL;
 }
 
 /*
@@ -310,6 +313,10 @@ static const char *arm_cspmu_get_name(const struct arm_cspmu *cspmu)
 
 	dev = cspmu->dev;
 	apmt_node = arm_cspmu_apmt_node(dev);
+	if (!apmt_node)
+		return devm_kasprintf(dev, GFP_KERNEL, PMUNAME "_%u",
+				      atomic_fetch_inc(&pmu_idx[0]));
+
 	pmu_type = apmt_node->type;
 
 	if (pmu_type >= ACPI_APMT_NODE_TYPE_COUNT) {
@@ -425,7 +432,7 @@ static int arm_cspmu_init_impl_ops(struct arm_cspmu *cspmu)
 	};
 
 	/* Firmware may override implementer/product ID from PMIIDR */
-	if (apmt_node->impl_id)
+	if (apmt_node && apmt_node->impl_id)
 		cspmu->impl.pmiidr = apmt_node->impl_id;
 
 	/* Find implementer specific attribute ops. */
@@ -940,7 +947,14 @@ static struct arm_cspmu *arm_cspmu_alloc(struct platform_device *pdev)
 	platform_set_drvdata(pdev, cspmu);
 
 	apmt_node = arm_cspmu_apmt_node(dev);
-	cspmu->has_atomic_dword = apmt_node->flags & ACPI_APMT_FLAGS_ATOMIC;
+	if (apmt_node) {
+		cspmu->has_atomic_dword = apmt_node->flags & ACPI_APMT_FLAGS_ATOMIC;
+	} else {
+		u32 width = 0;
+
+		device_property_read_u32(dev, "reg-io-width", &width);
+		cspmu->has_atomic_dword = (width == 8);
+	}
 
 	return cspmu;
 }
@@ -1131,11 +1145,6 @@ static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu)
 		}
 	}
 
-	if (cpumask_empty(&cspmu->associated_cpus)) {
-		dev_dbg(cspmu->dev, "No cpu associated with the PMU\n");
-		return -ENODEV;
-	}
-
 	return 0;
 }
 #else
@@ -1145,9 +1154,36 @@ static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu)
 }
 #endif
 
+static int arm_cspmu_of_get_cpus(struct arm_cspmu *cspmu)
+{
+	struct of_phandle_iterator it;
+	int ret, cpu;
+
+	of_for_each_phandle(&it, ret, dev_of_node(cspmu->dev), "cpus", NULL, 0) {
+		cpu = of_cpu_node_to_id(it.node);
+		if (cpu < 0)
+			continue;
+		cpumask_set_cpu(cpu, &cspmu->associated_cpus);
+	}
+	return ret == -ENOENT ? 0 : ret;
+}
+
 static int arm_cspmu_get_cpus(struct arm_cspmu *cspmu)
 {
-	return arm_cspmu_acpi_get_cpus(cspmu);
+	int ret = 0;
+
+	if (arm_cspmu_apmt_node(cspmu->dev))
+		ret = arm_cspmu_acpi_get_cpus(cspmu);
+	else if (device_property_present(cspmu->dev, "cpus"))
+		ret = arm_cspmu_of_get_cpus(cspmu);
+	else
+		cpumask_copy(&cspmu->associated_cpus, cpu_possible_mask);
+
+	if (!ret && cpumask_empty(&cspmu->associated_cpus)) {
+		dev_dbg(cspmu->dev, "No cpu associated with the PMU\n");
+		ret = -ENODEV;
+	}
+	return ret;
 }
 
 static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
@@ -1244,11 +1280,18 @@ static const struct platform_device_id arm_cspmu_id[] = {
 };
 MODULE_DEVICE_TABLE(platform, arm_cspmu_id);
 
+static const struct of_device_id arm_cspmu_of_match[] = {
+	{ .compatible = "arm,coresight-pmu" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, arm_cspmu_of_match);
+
 static struct platform_driver arm_cspmu_driver = {
 	.driver = {
-			.name = DRVNAME,
-			.suppress_bind_attrs = true,
-		},
+		.name = DRVNAME,
+		.of_match_table = arm_cspmu_of_match,
+		.suppress_bind_attrs = true,
+	},
 	.probe = arm_cspmu_device_probe,
 	.remove = arm_cspmu_device_remove,
 	.id_table = arm_cspmu_id,
-- 
2.39.2.101.g768bb238c484.dirty



From oliver.upton at linux.dev  Tue Feb  6 02:28:30 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 6 Feb 2024 10:28:30 +0000
Subject: [PATCH] [RFC] KVM: arm64/vgic: Populate GICR_TYPER with Aff3
In-Reply-To: <20240205184326.78814-1-sauravsc@amazon.com>
References: <20240205184326.78814-1-sauravsc@amazon.com>
Message-ID: <ZcIJzn9KLR_bWdwc@linux.dev>

Hi Saurav,

On Mon, Feb 05, 2024 at 06:43:26PM +0000, Saurav Sachidanand wrote:

[...]

> diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> index c15ee1df036a..26bc838ce14c 100644
> --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> @@ -324,6 +324,7 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu,
>  	u64 value;
>  
>  	value = (u64)(mpidr & GENMASK(23, 0)) << 32;
> +	value |= (u64)((mpidr >> 32) & GENMASK(7, 0)) << 56;

This looks suspiciously similar to what MPIDR_AFFINITY_LEVEL()
accomplishes. I think we can tolerate a few extra lines of code to make
the entire thing more self-documenting, like:

	value = ((u64)MPIDR_AFFINITY_LEVEL(mpidr, 3) << 56 |
		MPIDR_AFFINITY_LEVEL(mpidr, 2) << 48 |
		MPIDR_AFFINITY_LEVEL(mpidr, 1) << 40 |
		MPIDR_AFFINITY_LEVEL(mpidr, 0) << 32);

-- 
Thanks,
Oliver


From maz at kernel.org  Tue Feb  6 02:29:22 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 06 Feb 2024 10:29:22 +0000
Subject: [PATCH] [RFC] KVM: arm64/vgic: Populate GICR_TYPER with Aff3
In-Reply-To: <20240205184326.78814-1-sauravsc@amazon.com>
References: <20240205184326.78814-1-sauravsc@amazon.com>
Message-ID: <86y1bx6g3h.wl-maz@kernel.org>

Hi Saurav,

On Mon, 05 Feb 2024 18:43:26 +0000,
Saurav Sachidanand <sauravsc at amazon.com> wrote:
> 
> According to spec, bits [63:56] of the GICR_TYPER register are supposed
> to contain Affinity level 3 (Aff3) bits of the Processing Element (PE)
> associated with its GIC redistributor. Linux guests on boot match PEs
> with their redistributor using all four Affinity level bits from this
> register.

If you read the spec carefully, you will notice that Aff3 support is
*optional*, and that it is on purpose that we don't support Aff3: this
cannot work for 32bit guests.

The other thing is that there is no guarantee that the HW actually
supports that either: ICH_VTR_EL2.A3V tells you whether the CPU
interface actually supports it.

> 
> Currently, vGIC populates GICR_TYPER with just the first three Affinity
> levels of a vCPU's MPIDR. This works fine for a Linux guest that boots
> with KVM's default vCPU MPIDR assignment, which also only populates till
> the first three Affinity levels.
> 
> However, a hypervisor can override KVM's default MPIDR assignment by
> writing directly to a vCPU's MPIDR_EL1 register. If such a hypervisor
> were to populate Aff3 bits for a VM, a Linux guest booting there would
> fail to match vCPUs with their vGIC redistributors, since their virtual
> GICR_TYPER registers would be missing the respective Aff3 bits.
> 
> To change that, let's populate GICR_TYPER using Aff3 bits [39:32] from
> the vCPU's MPIDR.
> 
> Signed-off-by: Saurav Sachidanand <sauravsc at amazon.com>
> ---
>  arch/arm64/kvm/vgic/vgic-mmio-v3.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> index c15ee1df036a..26bc838ce14c 100644
> --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> @@ -324,6 +324,7 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu,
>  	u64 value;
>  
>  	value = (u64)(mpidr & GENMASK(23, 0)) << 32;
> +	value |= (u64)((mpidr >> 32) & GENMASK(7, 0)) << 56;
>  	value |= ((target_vcpu_id & 0xffff) << 8);
>  
>  	if (vgic_has_its(vcpu->kvm))

So if you consider the above remarks, this is neither sufficient nor
guaranteed to work. I'm not opposed to having full Aff3 support (most
of it is already there), but this needs to be done in a consistent
way, and consider both the case of 32bit guests (which are not going
away) and the capabilities of the HW (the current code being rather
inconsistent in this regard).

If you are willing to work on this, I'll happily review a more
complete series of patches.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From shawnguo2 at yeah.net  Tue Feb  6 02:32:40 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 18:32:40 +0800
Subject: [PATCH v3 0/2] board: imx8mn-rve-gateway: fix compatible
 description
In-Reply-To: <20240125165935.886992-1-hugo@hugovil.com>
References: <20240125165935.886992-1-hugo@hugovil.com>
Message-ID: <ZcIKyL7l2bIN3KeK@dragon>

On Thu, Jan 25, 2024 at 11:59:33AM -0500, Hugo Villeneuve wrote:
> Hugo Villeneuve (2):
>   dt-bindings: arm: fsl: remove redundant company name
>   arm64: dts: imx8mn-rve-gateway: remove redundant company name

Applied both, thanks!



From shawnguo2 at yeah.net  Tue Feb  6 02:35:17 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 18:35:17 +0800
Subject: [PATCH RFC for upstream 3/4] arm64: dts:
 imx8mp-phyboard-pollux-rdk: add etml panel support
In-Reply-To: <20240126-wip-y-moog-phytec-de-upstream-pollux-lvds-v1-3-8ec5b48eec05@phytec.de>
References: <20240126-wip-y-moog-phytec-de-upstream-pollux-lvds-v1-0-8ec5b48eec05@phytec.de>
 <20240126-wip-y-moog-phytec-de-upstream-pollux-lvds-v1-3-8ec5b48eec05@phytec.de>
Message-ID: <ZcILZSg7ERGza+1p@dragon>

On Fri, Jan 26, 2024 at 09:57:25AM +0100, Yannic Moog wrote:
> The imx8mp-phyboard-pollux has on-board lvds interface connections. An
> edt,etml1010g3dra panel is supported for this interface. Add device tree
> nodes for backlight and panel.
> 
> Signed-off-by: Yannic Moog <y.moog at phytec.de>

Applied, thanks!



From shawnguo2 at yeah.net  Tue Feb  6 02:35:31 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 18:35:31 +0800
Subject: [PATCH RFC for upstream 4/4] arm64: defconfig: enable i.MX8MP
 ldb bridge
In-Reply-To: <20240126-wip-y-moog-phytec-de-upstream-pollux-lvds-v1-4-8ec5b48eec05@phytec.de>
References: <20240126-wip-y-moog-phytec-de-upstream-pollux-lvds-v1-0-8ec5b48eec05@phytec.de>
 <20240126-wip-y-moog-phytec-de-upstream-pollux-lvds-v1-4-8ec5b48eec05@phytec.de>
Message-ID: <ZcILc05xove6D92V@dragon>

On Fri, Jan 26, 2024 at 09:57:26AM +0100, Yannic Moog wrote:
> Enable the i.MX8MP LDB driver used for display support of the i.MX8MP
> LVDS interface.
> 
> Signed-off-by: Yannic Moog <y.moog at phytec.de>

Applied, thanks!



From shawnguo2 at yeah.net  Tue Feb  6 02:38:29 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 18:38:29 +0800
Subject: [PATCH 2/2] arm64: dts: imx8dxl update edma0 information
In-Reply-To: <20240129201633.234255-2-Frank.Li@nxp.com>
References: <20240129201633.234255-1-Frank.Li@nxp.com>
 <20240129201633.234255-2-Frank.Li@nxp.com>
Message-ID: <ZcIMJWKBrPW4Y5R8@dragon>

On Mon, Jan 29, 2024 at 03:16:32PM -0500, Frank Li wrote:
> edma0 of iMX8DXL is difference with other imx8 chips. Update register's
> size, channel number and power-domain.
> Update i2c[0-3] channel number information.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
>  .../boot/dts/freescale/imx8dxl-ss-adma.dtsi   | 65 +++++++++++++++++++
>  1 file changed, 65 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
> index 0a477f6318f15..f8fca86babda7 100644
> --- a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
> @@ -15,6 +15,63 @@ &adc0 {
>  	interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
>  };
>  
> +&edma0 {
> +	reg = <0x591f0000 0x1a0000>;
> +	#dma-cells = <3>;
> +	dma-channels = <25>;
> +	dma-channel-mask = <0x1c0cc0>;
> +	interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>, /* asrc 0 */
> +		<GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* spdif0 */
> +		<GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
> +		<GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>, /* sai1 */
> +		<GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* sai2 */
> +		<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>, /* sai3 */
> +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> +		<GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, /* gpt0 */
> +		<GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>, /* gpt1 */
> +		<GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>, /* gpt2 */
> +		<GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>; /* gpt3 */
> +	power-domains = <&pd IMX_SC_R_DMA_0_CH0>,
> +			<&pd IMX_SC_R_DMA_0_CH1>,
> +			<&pd IMX_SC_R_DMA_0_CH2>,
> +			<&pd IMX_SC_R_DMA_0_CH3>,
> +			<&pd IMX_SC_R_DMA_0_CH4>,
> +			<&pd IMX_SC_R_DMA_0_CH5>,
> +			<&pd IMX_SC_R_DMA_0_CH6>,
> +			<&pd IMX_SC_R_DMA_0_CH7>,
> +			<&pd IMX_SC_R_DMA_0_CH8>,
> +			<&pd IMX_SC_R_DMA_0_CH9>,
> +			<&pd IMX_SC_R_DMA_0_CH10>,
> +			<&pd IMX_SC_R_DMA_0_CH11>,
> +			<&pd IMX_SC_R_DMA_0_CH12>,
> +			<&pd IMX_SC_R_DMA_0_CH13>,
> +			<&pd IMX_SC_R_DMA_0_CH14>,
> +			<&pd IMX_SC_R_DMA_0_CH15>,
> +			<&pd IMX_SC_R_DMA_0_CH16>,
> +			<&pd IMX_SC_R_DMA_0_CH17>,
> +			<&pd IMX_SC_R_DMA_0_CH18>,
> +			<&pd IMX_SC_R_DMA_0_CH19>,
> +			<&pd IMX_SC_R_DMA_0_CH20>,
> +			<&pd IMX_SC_R_DMA_0_CH21>,
> +			<&pd IMX_SC_R_DMA_0_CH22>,
> +			<&pd IMX_SC_R_DMA_0_CH23>,
> +			<&pd IMX_SC_R_DMA_0_CH24>;
> +};
> +
>  &edma2 {
>  	interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>,
>  		     <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>,
> @@ -48,21 +105,29 @@ &edma3 {
>  &i2c0 {
>  	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
>  	interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
> +	dma-names = "tx","rx";
> +	dmas = <&edma3 1 0 0>, <&edma3 0 0 FSL_EDMA_RX>;
>  };
>  
>  &i2c1 {
>  	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
>  	interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
> +	dma-names = "tx","rx";
> +	dmas = <&edma3 3 0 0>, <&edma3 2 0 FSL_EDMA_RX>;

No FSL_EDMA_TX for "tx"?

Shawn

>  };
>  
>  &i2c2 {
>  	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
>  	interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
> +	dma-names = "tx","rx";
> +	dmas = <&edma3 5 0 0>, <&edma3 4 0 FSL_EDMA_RX>;
>  };
>  
>  &i2c3 {
>  	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
>  	interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
> +	dma-names = "tx","rx";
> +	dmas = <&edma3 7 0 0>, <&edma3 6 0 FSL_EDMA_RX>;
>  };
>  
>  &lpuart0 {
> -- 
> 2.34.1
> 



From u-kumar1 at ti.com  Tue Feb  6 02:43:57 2024
From: u-kumar1 at ti.com (Udit Kumar)
Date: Tue, 6 Feb 2024 16:13:57 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non contiguous clocks
Message-ID: <20240206104357.3803517-1-u-kumar1@ti.com>

Most of clocks and their parents are defined in contiguous range,
But in few cases, there is gap in clock numbers[0].
Driver assumes clocks to be in contiguous range, and add their clock
ids incrementally.

New firmware started returning error while calling get_freq and is_on
API for non-available clock ids.

In this fix, driver checks and adds only valid clock ids.

Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")

[0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
Section Clocks for NAVSS0_CPTS_0 Device,
clock id 12-15 not present.

Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
---
Changelog

Changes in v2
- Updated commit message
- Simplified logic for valid clock id
link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/


P.S
Firmawre returns total num_parents count including non available ids.
For above device id NAVSS0_CPTS_0, number of parents clocks are 16
i.e from id 2 to 17. But out of these ids few are not valid.
So driver adds only valid clock ids out ot total.

Original logs
https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
Line 2630 for error

Logs with fix v2
https://gist.github.com/uditkumarti/94e3e28d62282fd708dbfe37435ce1d9
Line 2591


 drivers/clk/keystone/sci-clk.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 35fe197dd303..ff249cbd54a1 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -517,6 +517,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
 	int num_clks = 0;
 	int num_parents;
 	int clk_id;
+	u64 freq;
 	const char * const clk_names[] = {
 		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
 	};
@@ -586,16 +587,23 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
 				clk_id = args.args[1] + 1;
 
 				while (num_parents--) {
+					/* Check if this clock id is valid */
+					ret = provider->ops->get_freq(provider->sci,
+						sci_clk->dev_id, clk_id, &freq);
+
+					clk_id++;
+					if (ret)
+						continue;
+
 					sci_clk = devm_kzalloc(dev,
 							       sizeof(*sci_clk),
 							       GFP_KERNEL);
 					if (!sci_clk)
 						return -ENOMEM;
 					sci_clk->dev_id = args.args[0];
-					sci_clk->clk_id = clk_id++;
+					sci_clk->clk_id = clk_id - 1;
 					sci_clk->provider = provider;
 					list_add_tail(&sci_clk->node, &clks);
-
 					num_clks++;
 				}
 			}
-- 
2.34.1



From shawnguo2 at yeah.net  Tue Feb  6 02:45:52 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 18:45:52 +0800
Subject: [PATCH v2 1/3] arm64: dts: imx8dxl: update flexcan[1-3]
 interrupt number
In-Reply-To: <20240130152547.272125-1-Frank.Li@nxp.com>
References: <20240130152547.272125-1-Frank.Li@nxp.com>
Message-ID: <ZcIN4EWS+t3hR9Xq@dragon>

On Tue, Jan 30, 2024 at 10:25:45AM -0500, Frank Li wrote:
> Update interrupt number of flexcan[1-3].
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied all, thanks!



From olteanv at gmail.com  Tue Feb  6 02:50:49 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 6 Feb 2024 12:50:49 +0200
Subject: [PATCH net-next v5 3/7] net: dsa: mt7530: simplify
 mt7530_pad_clk_setup()
In-Reply-To: <20240206-for-netnext-mt7530-improvements-2-v5-3-d7d92a185cb1@arinc9.com>
References: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
 <20240206-for-netnext-mt7530-improvements-2-v5-3-d7d92a185cb1@arinc9.com>
Message-ID: <20240206105049.rldesxnyjs4dungi@skbuf>

On Tue, Feb 06, 2024 at 01:08:04AM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> This code is from before this driver was converted to phylink API. Phylink
> deals with the unsupported interface cases before mt7530_pad_clk_setup() is
> run. Therefore, the default case would never run. However, it must be
> defined nonetheless to handle all the remaining enumeration values, the
> phy-modes.
> 
> Switch to if statement for RGMII and return which simplifies the code and
> saves an indent.
> 
> Set P6_INTF_MODE, which is the three least significant bits of the
> MT7530_P6ECR register, to 0 for RGMII even though it will already be 0
> after reset. This is to keep supporting dynamic reconfiguration of the port
> in the case the interface changes from TRGMII to RGMII.
> 
> Disable the TRGMII clocks for all cases. They will be enabled if TRGMII is
> being used.
> 
> Read XTAL after checking for RGMII as it's only needed for the TRGMII
> interface mode.
> 
> Reviewed-by: Daniel Golle <daniel at makrotopia.org>
> Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> ---

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From shawnguo2 at yeah.net  Tue Feb  6 02:50:51 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 18:50:51 +0800
Subject: [PATCH v2 0/4] Add 8qm SMMU information
In-Reply-To: <20240202110511.135d26b7@kernel.org>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240202110511.135d26b7@kernel.org>
Message-ID: <ZcIPCxgO3Gxc/aXh@dragon>

On Fri, Feb 02, 2024 at 11:05:11AM -0800, Jakub Kicinski wrote:
> On Thu, 01 Feb 2024 15:22:40 -0500 Frank Li wrote:
> >       dt-bindings: mmc: fsl-imx-esdhc: add iommus property
> >       dt-bindings: net: fec: add iommus property
> >       arm64: dts: imx8qm: add smmu node
> >       arm64: dts: imx8qm: add smmu stream id information
> > 
> >  .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml     |  3 ++
> >  Documentation/devicetree/bindings/net/fsl,fec.yaml |  3 ++
> >  arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi  |  6 ++++
> >  arch/arm64/boot/dts/freescale/imx8qm.dtsi          | 41 ++++++++++++++++++++++
> 
> Any preference on whether all these go via a platform tree,
> or should we pick up the net patch to netdev? I guess taking
> the DTB via netdev would be the usual way to handle this?

No, it's not.  Taking DTS changes through arch/platform tree is the
usual way.

Shawn



From shawnguo2 at yeah.net  Tue Feb  6 02:52:14 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 18:52:14 +0800
Subject: [PATCH v2 3/4] arm64: dts: imx8qm: add smmu node
In-Reply-To: <20240201-8qm_smmu-v2-3-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240201-8qm_smmu-v2-3-3d12a80201a3@nxp.com>
Message-ID: <ZcIPXiiyM6080TgD@dragon>

On Thu, Feb 01, 2024 at 03:22:43PM -0500, Frank Li wrote:
> Add smmu node for imx8qm.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied, thanks!



From shawnguo2 at yeah.net  Tue Feb  6 02:53:10 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 18:53:10 +0800
Subject: [PATCH v2 4/4] arm64: dts: imx8qm: add smmu stream id information
In-Reply-To: <20240201-8qm_smmu-v2-4-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240201-8qm_smmu-v2-4-3d12a80201a3@nxp.com>
Message-ID: <ZcIPlp7BUxuo/ZeM@dragon>

On Thu, Feb 01, 2024 at 03:22:44PM -0500, Frank Li wrote:
> Add smmu stream id information for fec and esdhc.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
> index ec1639174e2e5..3cbc861400b43 100644
> --- a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
> @@ -6,20 +6,26 @@
>  
>  &fec1 {
>  	compatible = "fsl,imx8qm-fec", "fsl,imx6sx-fec";
> +	iommus = <&smmu 0x12 0x7f80>;
>  };
>  
>  &fec2 {
>  	compatible = "fsl,imx8qm-fec", "fsl,imx6sx-fec";
> +	iommus = <&smmu 0x12 0x7f80>;
>  };
>  
>  &usdhc1 {
>  	compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
> +	iommus = <&smmu 0x11 0x7f80>;
>  };
>  
>  &usdhc2 {
>  	compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
> +	iommus = <&smmu 0x11 0x7f80>;
>  };
>  
>  &usdhc3 {
>  	compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
> +	iommus = <&smmu 0x11 0x7f80>;
>  };
> +

Dropped this whitespace and applied.

Shawn

> 
> -- 
> 2.34.1
> 



From krzysztof.kozlowski at linaro.org  Tue Feb  6 02:53:55 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 6 Feb 2024 11:53:55 +0100
Subject: [PATCH v2 1/2] dt-bindings: phy: mediatek,mt7988-xfi-tphy: add
 new bindings
In-Reply-To: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>
References: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>
Message-ID: <31d2c56a-5108-4265-a267-6733e1ba328e@linaro.org>

On 05/02/2024 18:28, Daniel Golle wrote:
> Add bindings for the MediaTek XFI Ethernet SerDes T-PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
> via USXGMII PCS:
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
> 
> via LynxI SGMII PCS:
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---
> v2: unify filename and compatible as requested

Several comments, from me and Rob, were ignored. Please respond to them.

Best regards,
Krzysztof



From shawnguo2 at yeah.net  Tue Feb  6 02:57:03 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue, 6 Feb 2024 18:57:03 +0800
Subject: [PATCH v2 1/2] arm64: dts: imx8mm-evk: Add PDM micphone sound
 card support
In-Reply-To: <1707098664-23265-1-git-send-email-shengjiu.wang@nxp.com>
References: <1707098664-23265-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <ZcIQf6qvoDIYj+6v@dragon>

On Mon, Feb 05, 2024 at 10:04:23AM +0800, Shengjiu Wang wrote:
> Add PDM micphone sound card support, configure the pinmux.
> 
> This sound card supports recording sound from PDM micphone
> and convert the PDM format data to PCM data.
> 
> Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>

Applied both, thanks!



From broonie at kernel.org  Tue Feb  6 02:59:05 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 6 Feb 2024 10:59:05 +0000
Subject: [PATCH 00/18] mfd: convert to use maple tree register cache
In-Reply-To: <CAMuHMdVj1bS9s69ASrd5xULc8oELoBbnb8HEX9MEmA43853_EQ@mail.gmail.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
 <CAMuHMdU7fYCsNT9ditqJ-saUsRm9J2zLh=-q-zmExhBRJeE8NQ@mail.gmail.com>
 <ZcIE/RMTq34TgpQt@finisterre.sirena.org.uk>
 <CAMuHMdVj1bS9s69ASrd5xULc8oELoBbnb8HEX9MEmA43853_EQ@mail.gmail.com>
Message-ID: <ZcIQ+f3F/hSU1Jcx@finisterre.sirena.org.uk>

On Tue, Feb 06, 2024 at 11:14:11AM +0100, Geert Uytterhoeven wrote:
> On Tue, Feb 6, 2024 at 11:09?AM Mark Brown <broonie at kernel.org> wrote:

> > There is a very small niche for devices where cache syncs are a
> > particularly important part of the workload where rbtree's choices might
> > give better performance, especially on systems with low end CPUs.

> The REGCACHE_* value is specified by the device, not by the CPU?

The device is going to dominate here, the main thing is how much of the
workload consists of syncs.

> While some of these MFD devices are on-SoC, and thus there is some
> relation between device and CPU, several others (e.g. PMICs) are
> external, and thus might be present on systems with a variety of CPU
> performance.

> Perhaps the value should depend on some CPU heuristic instead?

No.
-------------- 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/20240206/0bfd0f55/attachment.sig>

From broonie at kernel.org  Tue Feb  6 03:04:16 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 6 Feb 2024 11:04:16 +0000
Subject: [PATCH 4/4] spi: s3c64xx: add support for google,gs101-spi
In-Reply-To: <CADrjBPqaE9Mmbr+zkHOAadr3aLSu3GMjS4nPPd4VZY4s2DTznA@mail.gmail.com>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
 <20240206085238.1208256-5-tudor.ambarus@linaro.org>
 <CADrjBPqaE9Mmbr+zkHOAadr3aLSu3GMjS4nPPd4VZY4s2DTznA@mail.gmail.com>
Message-ID: <ZcISMLoB2ytoQs/0@finisterre.sirena.org.uk>

On Tue, Feb 06, 2024 at 10:12:30AM +0000, Peter Griffin wrote:

> The patch ordering seems a bit off with this series..I believe it should be
> 1) dt-bindings patch (docs first)
> 2) Add the use_32bit_io flag / functionality
> 3) gs101 support (this patch) that uses the use_32bit_io functionality

That's the ordering the series has?  There's a random cleanup patch
tacked on the front but that really ought to be separate anyway.
-------------- 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/20240206/70e58e1d/attachment-0001.sig>

From broonie at kernel.org  Tue Feb  6 03:07:23 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 6 Feb 2024 11:07:23 +0000
Subject: [RFC PATCH] arm64/sve,sme: Refine scalable regset sizes at boot
In-Reply-To: <ZcEaeLeEG8ve+Yp7@e133380.arm.com>
References: <ZcEaeLeEG8ve+Yp7@e133380.arm.com>
Message-ID: <ZcIS6ySfoGzwv31M@finisterre.sirena.org.uk>

On Mon, Feb 05, 2024 at 05:27:20PM +0000, Dave Martin wrote:

> --- a/arch/arm64/kernel/ptrace.c
> +++ b/arch/arm64/kernel/ptrace.c
> @@ -9,6 +9,7 @@
>   */
>  
>  #include <linux/audit.h>
> +#include <linux/cache.h>
>  #include <linux/compat.h>
>  #include <linux/kernel.h>
>  #include <linux/sched/signal.h>

Why?
-------------- 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/20240206/cb0f57cd/attachment.sig>

From bp at alien8.de  Tue Feb  6 03:07:23 2024
From: bp at alien8.de (Borislav Petkov)
Date: Tue, 6 Feb 2024 12:07:23 +0100
Subject: [PATCH] x86/sev: Fix position dependent variable references in
 startup code
In-Reply-To: <20240203125306.1887331-2-ardb+git@google.com>
References: <20240203125306.1887331-2-ardb+git@google.com>
Message-ID: <20240206110723.GBZcIS60p3LIvfPfgM@fat_crate.local>

On Sat, Feb 03, 2024 at 01:53:06PM +0100, Ard Biesheuvel wrote:
>  arch/x86/coco/core.c               |  7 +----
>  arch/x86/include/asm/asm.h         | 13 ++++++++++
>  arch/x86/include/asm/coco.h        |  8 +++++-
>  arch/x86/include/asm/mem_encrypt.h | 13 ++++++----
>  arch/x86/kernel/sev-shared.c       | 12 ++++-----
>  arch/x86/kernel/sev.c              |  4 +--
>  arch/x86/mm/mem_encrypt_identity.c | 27 +++++++++-----------
>  7 files changed, 49 insertions(+), 35 deletions(-)

Not bad - some touchups ontop like calling it "rip_rel_ref" everywhere
like other code shortens "rIP-relative reference" and making the asm
wrapper __always_inline.

Thx.

---

diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 41b408b3dfb6..ca8eed1d496a 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -115,14 +115,15 @@
 
 #ifndef __ASSEMBLY__
 #ifndef __pic__
-static inline __pure void *rip_relative_ptr(void *p)
+static __always_inline __pure void *rip_rel_ptr(void *p)
 {
 	asm("leaq %c1(%%rip), %0" : "=r"(p) : "i"(p));
+
 	return p;
 }
-#define RIP_RELATIVE_REF(var)	(*(typeof(&(var)))rip_relative_ptr(&(var)))
+#define RIP_REL_REF(var)	(*(typeof(&(var)))rip_rel_ptr(&(var)))
 #else
-#define RIP_RELATIVE_REF(var)	(var)
+#define RIP_REL_REF(var)	(var)
 #endif
 #endif
 
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
index d6865e0f7587..21940ef8d290 100644
--- a/arch/x86/include/asm/coco.h
+++ b/arch/x86/include/asm/coco.h
@@ -17,7 +17,7 @@ extern u64 cc_mask;
 #ifdef CONFIG_ARCH_HAS_CC_PLATFORM
 static inline void cc_set_mask(u64 mask)
 {
-	RIP_RELATIVE_REF(cc_mask) = mask;
+	RIP_REL_REF(cc_mask) = mask;
 }
 
 u64 cc_mkenc(u64 val);
diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h
index 6fa2ba58ed3f..b31eb9fd5954 100644
--- a/arch/x86/include/asm/mem_encrypt.h
+++ b/arch/x86/include/asm/mem_encrypt.h
@@ -61,7 +61,7 @@ void __init sev_es_init_vc_handling(void);
 
 static inline u64 sme_get_me_mask(void)
 {
-	return RIP_RELATIVE_REF(sme_me_mask);
+	return RIP_REL_REF(sme_me_mask);
 }
 
 #define __bss_decrypted __section(".bss..decrypted")
diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
index a54711300d0b..a200bd72fadc 100644
--- a/arch/x86/kernel/sev-shared.c
+++ b/arch/x86/kernel/sev-shared.c
@@ -562,9 +562,9 @@ static int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_le
 		leaf->eax = leaf->ebx = leaf->ecx = leaf->edx = 0;
 
 		/* Skip post-processing for out-of-range zero leafs. */
-		if (!(leaf->fn <= RIP_RELATIVE_REF(cpuid_std_range_max) ||
-		      (leaf->fn >= 0x40000000 && leaf->fn <= RIP_RELATIVE_REF(cpuid_hyp_range_max)) ||
-		      (leaf->fn >= 0x80000000 && leaf->fn <= RIP_RELATIVE_REF(cpuid_ext_range_max))))
+		if (!(leaf->fn <= RIP_REL_REF(cpuid_std_range_max) ||
+		      (leaf->fn >= 0x40000000 && leaf->fn <= RIP_REL_REF(cpuid_hyp_range_max)) ||
+		      (leaf->fn >= 0x80000000 && leaf->fn <= RIP_REL_REF(cpuid_ext_range_max))))
 			return 0;
 	}
 
@@ -1074,11 +1074,11 @@ static void __init setup_cpuid_table(const struct cc_blob_sev_info *cc_info)
 		const struct snp_cpuid_fn *fn = &cpuid_table->fn[i];
 
 		if (fn->eax_in == 0x0)
-			RIP_RELATIVE_REF(cpuid_std_range_max) = fn->eax;
+			RIP_REL_REF(cpuid_std_range_max) = fn->eax;
 		else if (fn->eax_in == 0x40000000)
-			RIP_RELATIVE_REF(cpuid_hyp_range_max) = fn->eax;
+			RIP_REL_REF(cpuid_hyp_range_max) = fn->eax;
 		else if (fn->eax_in == 0x80000000)
-			RIP_RELATIVE_REF(cpuid_ext_range_max) = fn->eax;
+			RIP_REL_REF(cpuid_ext_range_max) = fn->eax;
 	}
 }
 
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index 1cf348e19556..1ef7ae806a01 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -748,7 +748,7 @@ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long padd
 	 * This eliminates worries about jump tables or checking boot_cpu_data
 	 * in the cc_platform_has() function.
 	 */
-	if (!(RIP_RELATIVE_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED))
+	if (!(RIP_REL_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED))
 		return;
 
 	 /*
@@ -767,7 +767,7 @@ void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr
 	 * This eliminates worries about jump tables or checking boot_cpu_data
 	 * in the cc_platform_has() function.
 	 */
-	if (!(RIP_RELATIVE_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED))
+	if (!(RIP_REL_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED))
 		return;
 
 	 /* Ask hypervisor to mark the memory pages shared in the RMP table. */
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index d8d14133b654..0166ab1780cc 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -305,7 +305,7 @@ void __init sme_encrypt_kernel(struct boot_params *bp)
 	 * function.
 	 */
 	if (!sme_get_me_mask() ||
-	    RIP_RELATIVE_REF(sev_status) & MSR_AMD64_SEV_ENABLED)
+	    RIP_REL_REF(sev_status) & MSR_AMD64_SEV_ENABLED)
 		return;
 
 	/*
@@ -542,7 +542,7 @@ void __init sme_enable(struct boot_params *bp)
 	me_mask = 1UL << (ebx & 0x3f);
 
 	/* Check the SEV MSR whether SEV or SME is enabled */
-	RIP_RELATIVE_REF(sev_status) = msr = __rdmsr(MSR_AMD64_SEV);
+	RIP_REL_REF(sev_status) = msr = __rdmsr(MSR_AMD64_SEV);
 	feature_mask = (msr & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
 
 	/* The SEV-SNP CC blob should never be present unless SEV-SNP is enabled. */
@@ -595,7 +595,7 @@ void __init sme_enable(struct boot_params *bp)
 		return;
 
 out:
-	RIP_RELATIVE_REF(sme_me_mask) = me_mask;
+	RIP_REL_REF(sme_me_mask) = me_mask;
 	physical_mask &= ~me_mask;
 	cc_vendor = CC_VENDOR_AMD;
 	cc_set_mask(me_mask);

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette


From suzuki.poulose at arm.com  Tue Feb  6 03:12:27 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 6 Feb 2024 11:12:27 +0000
Subject: [PATCH v3 0/5] perf/arm_cspmu: Add devicetree support
In-Reply-To: <cover.1706718007.git.robin.murphy@arm.com>
References: <cover.1706718007.git.robin.murphy@arm.com>
Message-ID: <04d94b55-0991-40c1-b3a6-96a7e2a4020e@arm.com>

On 06/02/2024 10:27, Robin Murphy wrote:
> v2: https://lore.kernel.org/linux-arm-kernel/cover.1702571292.git.robin.murphy at arm.com/
> 
> Hi all,
> 
> Third time lucky... here's a hopefully-final spin to address the
> functional issues Besar pointed out, and give a little final polish to
> the binding (although I stand firm on teh point of a trivial example
> not being valuable :))
> 
> Cheers,
> Robin.
> 
> 
> Robin Murphy (5):
>    perf/arm_cspmu: Simplify initialisation
>    perf/arm_cspmu: Simplify attribute groups
>    perf/arm_cspmu: Simplify counter reset
>    dt-bindings/perf: Add Arm CoreSight PMU
>    perf/arm_cspmu: Add devicetree support
> 
>   .../bindings/perf/arm,coresight-pmu.yaml      |  39 +++++
>   drivers/perf/arm_cspmu/arm_cspmu.c            | 153 ++++++++++--------
>   drivers/perf/arm_cspmu/arm_cspmu.h            |   1 +
>   drivers/perf/arm_cspmu/nvidia_cspmu.c         |   6 -
>   4 files changed, 126 insertions(+), 73 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/perf/arm,coresight-pmu.yaml
> 

For the series:

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>


From ardb at kernel.org  Tue Feb  6 03:19:06 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 6 Feb 2024 11:19:06 +0000
Subject: [PATCH] x86/sev: Fix position dependent variable references in
 startup code
In-Reply-To: <20240206110723.GBZcIS60p3LIvfPfgM@fat_crate.local>
References: <20240203125306.1887331-2-ardb+git@google.com> <20240206110723.GBZcIS60p3LIvfPfgM@fat_crate.local>
Message-ID: <CAMj1kXFGpTxPhNu8H090OVJ_izbgHyYy2VKwrpv43mdZuiHadA@mail.gmail.com>

On Tue, 6 Feb 2024 at 11:07, Borislav Petkov <bp at alien8.de> wrote:
>
> On Sat, Feb 03, 2024 at 01:53:06PM +0100, Ard Biesheuvel wrote:
> >  arch/x86/coco/core.c               |  7 +----
> >  arch/x86/include/asm/asm.h         | 13 ++++++++++
> >  arch/x86/include/asm/coco.h        |  8 +++++-
> >  arch/x86/include/asm/mem_encrypt.h | 13 ++++++----
> >  arch/x86/kernel/sev-shared.c       | 12 ++++-----
> >  arch/x86/kernel/sev.c              |  4 +--
> >  arch/x86/mm/mem_encrypt_identity.c | 27 +++++++++-----------
> >  7 files changed, 49 insertions(+), 35 deletions(-)
>
> Not bad - some touchups ontop like calling it "rip_rel_ref" everywhere
> like other code shortens "rIP-relative reference" and making the asm
> wrapper __always_inline.
>

Looks good to me - thanks.


From tudor.ambarus at linaro.org  Tue Feb  6 03:19:33 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue, 6 Feb 2024 11:19:33 +0000
Subject: [PATCH 4/4] spi: s3c64xx: add support for google,gs101-spi
In-Reply-To: <ZcISMLoB2ytoQs/0@finisterre.sirena.org.uk>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
 <20240206085238.1208256-5-tudor.ambarus@linaro.org>
 <CADrjBPqaE9Mmbr+zkHOAadr3aLSu3GMjS4nPPd4VZY4s2DTznA@mail.gmail.com>
 <ZcISMLoB2ytoQs/0@finisterre.sirena.org.uk>
Message-ID: <833b96e5-348f-4c5c-b157-c57c9a67e0f2@linaro.org>



On 2/6/24 11:04, Mark Brown wrote:
> On Tue, Feb 06, 2024 at 10:12:30AM +0000, Peter Griffin wrote:
> 
>> The patch ordering seems a bit off with this series..I believe it should be
>> 1) dt-bindings patch (docs first)
>> 2) Add the use_32bit_io flag / functionality
>> 3) gs101 support (this patch) that uses the use_32bit_io functionality
> 
> That's the ordering the series has?  There's a random cleanup patch
> tacked on the front but that really ought to be separate anyway.

I put the include <linux/types.h> patch first because I considered it a
fix (driver is using u32) and because I need types.h in patch 3/4. Fixes
first, then bindings, then driver.

Was I wrong?


From olteanv at gmail.com  Tue Feb  6 03:20:24 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 6 Feb 2024 13:20:24 +0200
Subject: [PATCH net-next v2 6/6] net: dsa: b53: remove
 eee_enabled/eee_active in b53_get_mac_eee()
In-Reply-To: <E1rWbNI-002cCz-4x@rmk-PC.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
 <E1rWbNI-002cCz-4x@rmk-PC.armlinux.org.uk>
Message-ID: <20240206112024.3jxtcru3dupeirnj@skbuf>

On Sun, Feb 04, 2024 at 12:13:28PM +0000, Russell King (Oracle) wrote:
> b53_get_mac_eee() sets both eee_enabled and eee_active, and then
> returns zero.
> 
> dsa_slave_get_eee(), which calls this function, will then continue to
> call phylink_ethtool_get_eee(), which will return -EOPNOTSUPP if there
> is no PHY present, otherwise calling phy_ethtool_get_eee() which in
> turn will call genphy_c45_ethtool_get_eee().

Nitpick: If you need to resend, the function name changed to
dsa_user_get_eee().

> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Thus, when there is no PHY, dsa_slave_get_eee() will fail with

Here too.

> -EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
> userspace. When there is a PHY, eee_enabled and eee_active will be
> overwritten by phylib, making the setting of these members in
> b53_get_mac_eee() entirely unnecessary.
> 
> Remove this code, thus simplifying b53_get_mac_eee().
> 
> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
>  drivers/net/dsa/b53/b53_common.c | 6 ------
>  1 file changed, 6 deletions(-)
> 
> diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
> index adc93abf4551..9e4c9bd6abcc 100644
> --- a/drivers/net/dsa/b53/b53_common.c
> +++ b/drivers/net/dsa/b53/b53_common.c
> @@ -2227,16 +2227,10 @@ EXPORT_SYMBOL(b53_eee_init);
>  int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e)
>  {
>  	struct b53_device *dev = ds->priv;
> -	struct ethtool_keee *p = &dev->ports[port].eee;
> -	u16 reg;
>  
>  	if (is5325(dev) || is5365(dev))
>  		return -EOPNOTSUPP;
>  
> -	b53_read16(dev, B53_EEE_PAGE, B53_EEE_LPI_INDICATE, &reg);
> -	e->eee_enabled = p->eee_enabled;
> -	e->eee_active = !!(reg & BIT(port));
> -

I know next to nothing about EEE and especially the implementation on
Broadcom switches. But is the information brought by B53_EEE_LPI_INDICATE
completely redundant? Is it actually in the system's best interest to
ignore it?

>  	return 0;
>  }
>  EXPORT_SYMBOL(b53_get_mac_eee);
> -- 
> 2.30.2
> 


From angelogioacchino.delregno at collabora.com  Tue Feb  6 03:24:50 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 12:24:50 +0100
Subject: [PATCH v3 2/7] drm/mediatek: dsi: Cleanup functions
 mtk_dsi_ps_control{_vact}()
In-Reply-To: <14e124f02d82ff151974f99d042c4197e4dd5dd7.camel@mediatek.com>
References: <20240131113434.241929-1-angelogioacchino.delregno@collabora.com>
 <20240131113434.241929-3-angelogioacchino.delregno@collabora.com>
 <14e124f02d82ff151974f99d042c4197e4dd5dd7.camel@mediatek.com>
Message-ID: <1d6b4a7d-4107-4880-858a-ecd565eee124@collabora.com>

Il 06/02/24 10:50, CK Hu (???) ha scritto:
> Hi, Angelo:
> 
> On Wed, 2024-01-31 at 12:34 +0100, AngeloGioacchino Del Regno wrote:
>> Function mtk_dsi_ps_control() is a subset of
>> mtk_dsi_ps_control_vact():
>> merge the two in one mtk_dsi_ps_control() function by adding one
>> function parameter `config_vact` which, when true, writes the VACT
>> related registers.
>>
>> Reviewed-by: Fei Shao <fshao at chromium.org>
>> Signed-off-by: AngeloGioacchino Del Regno <
>> angelogioacchino.delregno at collabora.com>
>> ---
>>   drivers/gpu/drm/mediatek/mtk_dsi.c | 76 +++++++++-------------------
>> --
>>   1 file changed, 23 insertions(+), 53 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> index 3b7392c03b4d..8414ce73ce9f 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> @@ -351,40 +351,6 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi
>> *dsi)
>>   	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
>>   }
>>   
>> -static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
>> -{
>> -	struct videomode *vm = &dsi->vm;
>> -	u32 dsi_buf_bpp, ps_wc;
>> -	u32 ps_bpp_mode;
>> -
>> -	if (dsi->format == MIPI_DSI_FMT_RGB565)
>> -		dsi_buf_bpp = 2;
>> -	else
>> -		dsi_buf_bpp = 3;
>> -
>> -	ps_wc = vm->hactive * dsi_buf_bpp;
>> -	ps_bpp_mode = ps_wc;
>> -
>> -	switch (dsi->format) {
>> -	case MIPI_DSI_FMT_RGB888:
>> -		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
>> -		break;
>> -	case MIPI_DSI_FMT_RGB666:
>> -		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
>> -		break;
>> -	case MIPI_DSI_FMT_RGB666_PACKED:
>> -		ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;
>> -		break;
>> -	case MIPI_DSI_FMT_RGB565:
>> -		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
>> -		break;
>> -	}
>> -
>> -	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
>> -	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
>> -	writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
>> -}
>> -
>>   static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
>>   {
>>   	u32 tmp_reg;
>> @@ -416,36 +382,40 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi
>> *dsi)
>>   	writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
>>   }
>>   
>> -static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
>> +static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool
>> config_vact)
>>   {
>> -	u32 dsi_tmp_buf_bpp;
>> -	u32 tmp_reg;
>> +	struct videomode *vm = &dsi->vm;
>> +	u32 dsi_buf_bpp, ps_wc;
>> +	u32 ps_bpp_mode;
>> +
>> +	if (dsi->format == MIPI_DSI_FMT_RGB565)
>> +		dsi_buf_bpp = 2;
>> +	else
>> +		dsi_buf_bpp = 3;
>> +
>> +	ps_wc = vm->hactive * dsi_buf_bpp;
>> +	ps_bpp_mode = ps_wc;
>>   
>>   	switch (dsi->format) {
>>   	case MIPI_DSI_FMT_RGB888:
>> -		tmp_reg = PACKED_PS_24BIT_RGB888;
>> -		dsi_tmp_buf_bpp = 3;
>> +		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
>>   		break;
>>   	case MIPI_DSI_FMT_RGB666:
>> -		tmp_reg = LOOSELY_PS_18BIT_RGB666;
>> -		dsi_tmp_buf_bpp = 3;
>> +		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
>>   		break;
>>   	case MIPI_DSI_FMT_RGB666_PACKED:
>> -		tmp_reg = PACKED_PS_18BIT_RGB666;
>> -		dsi_tmp_buf_bpp = 3;
>> +		ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;
> 
> You change the original logic here. If it is a fixup, separate to a
> independent patch not hiding in a clean up patch. So we could backport
> the fixup patch.
> 

Thank you CK! Thanks to you noticing that, I've discovered that actually
besides the two functions not agreeing on the bit to set, the definitions
of those bits are actually wrong (as you can verify on datasheets for
multiple SoCs, including MT8195, MT8188, MT8186, MT8183).

v4 will fix that by adding a fixup commit to rectify the whole thing.

Cheers,
Angelo

> Regards,
> CK
> 
>>   		break;
>>   	case MIPI_DSI_FMT_RGB565:
>> -		tmp_reg = PACKED_PS_16BIT_RGB565;
>> -		dsi_tmp_buf_bpp = 2;
>> -		break;
>> -	default:
>> -		tmp_reg = PACKED_PS_24BIT_RGB888;
>> -		dsi_tmp_buf_bpp = 3;
>> +		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
>>   		break;
>>   	}
>>   
>> -	tmp_reg += dsi->vm.hactive * dsi_tmp_buf_bpp & DSI_PS_WC;
>> -	writel(tmp_reg, dsi->regs + DSI_PSCTRL);
>> +	if (config_vact) {
>> +		writel(vm->vactive, dsi->regs + DSI_VACT_NL);
>> +		writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
>> +	}
>> +	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
>>   }
>>   
>>   static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
>> @@ -521,7 +491,7 @@ static void mtk_dsi_config_vdo_timing(struct
>> mtk_dsi *dsi)
>>   	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
>>   	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
>>   
>> -	mtk_dsi_ps_control(dsi);
>> +	mtk_dsi_ps_control(dsi, false);
>>   }
>>   
>>   static void mtk_dsi_start(struct mtk_dsi *dsi)
>> @@ -666,7 +636,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>>   	mtk_dsi_reset_engine(dsi);
>>   	mtk_dsi_phy_timconfig(dsi);
>>   
>> -	mtk_dsi_ps_control_vact(dsi);
>> +	mtk_dsi_ps_control(dsi, true);
>>   	mtk_dsi_set_vm_cmd(dsi);
>>   	mtk_dsi_config_vdo_timing(dsi);
>>   	mtk_dsi_set_interrupt_enable(dsi);




From Jonathan.Cameron at Huawei.com  Tue Feb  6 03:29:31 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Tue, 6 Feb 2024 11:29:31 +0000
Subject: [PATCH] perf: CXL: fix mismatched cpmu event opcode
In-Reply-To: <20240206102132.00000797@Huawei.com>
References: <CGME20240206094151epcms2p373ed7f50efa332765e14bff2b5a2abe2@epcms2p3>
	<20240206094151epcms2p373ed7f50efa332765e14bff2b5a2abe2@epcms2p3>
	<20240206102132.00000797@Huawei.com>
Message-ID: <20240206112931.00004224@Huawei.com>

On Tue, 6 Feb 2024 10:21:32 +0000
Jonathan Cameron <Jonathan.Cameron at Huawei.com> wrote:

> On Tue, 06 Feb 2024 18:41:51 +0900
> Hojin Nam <hj96.nam at samsung.com> wrote:
> 
> > S2M NDR BI-ConflictAck opcode is described as 4 in the CXL
> > 3.0 specification. However, it is defined as 3 in macro definition.
> >   
> Please provide a reference to a specific spec section.
> Ideally from r3.1 as that's the easily available version today.
> I think this is Table 3-50 S2M NDR Opcodes in r3.1
> 
> Looks like s2m_ndr_cmpm should be there for bit 3 so we should probably
> add that as part of the fix.
> 
Also, please add a Fixes tag.
> 
> > Signed-off-by: Hojin Nam <hj96.nam at samsung.com>
> > ---
> >  drivers/perf/cxl_pmu.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
> > index 365d964b0f6a..bc0d414a6aff 100644
> > --- a/drivers/perf/cxl_pmu.c
> > +++ b/drivers/perf/cxl_pmu.c
> > @@ -419,7 +419,7 @@ static struct attribute *cxl_pmu_event_attrs[] = {
> >         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmp,                     CXL_PMU_GID_S2M_NDR, BIT(0)),
> >         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmps,                    CXL_PMU_GID_S2M_NDR, BIT(1)),
> >         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmpe,                    CXL_PMU_GID_S2M_NDR, BIT(2)),
> > -       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(3)),
> > +       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(4)),
> >         /* CXL rev 3.0 Table 3-46 S2M DRS opcodes */
> >         CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdata,                 CXL_PMU_GID_S2M_DRS, BIT(0)),
> >         CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdatanxm,              CXL_PMU_GID_S2M_DRS, BIT(1)),
> > --
> > 2.34.1  
> 
> 



From raphael.gallais-pou at foss.st.com  Tue Feb  6 03:33:18 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Tue, 6 Feb 2024 12:33:18 +0100
Subject: [PATCH v4 3/3] drm/stm: ltdc: add lvds pixel clock
In-Reply-To: <20240206-lvds-v4-0-98d5f9af399d@foss.st.com>
References: <20240206-lvds-v4-0-98d5f9af399d@foss.st.com>
Message-ID: <20240206-lvds-v4-3-98d5f9af399d@foss.st.com>

The STM32MP25x display subsystem presents a mux which feeds the loopback
pixel clock of the current bridge in use into the LTDC. This mux is only
accessible through sysconfig registers which is not yet available in the
STM32MP25x common clock framework.

While waiting for a complete update of the clock framework, this would
allow to use the LVDS.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
---
Changes in v2:
	- Fixed my address
	- Fixed smatch warning
---
 drivers/gpu/drm/stm/ltdc.c | 19 +++++++++++++++++++
 drivers/gpu/drm/stm/ltdc.h |  1 +
 2 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 5576fdae4962..23011a8913bd 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -838,6 +838,12 @@ ltdc_crtc_mode_valid(struct drm_crtc *crtc,
 	int target_max = target + CLK_TOLERANCE_HZ;
 	int result;
 
+	if (ldev->lvds_clk) {
+		result = clk_round_rate(ldev->lvds_clk, target);
+		DRM_DEBUG_DRIVER("lvds pixclk rate target %d, available %d\n",
+				 target, result);
+	}
+
 	result = clk_round_rate(ldev->pixel_clk, target);
 
 	DRM_DEBUG_DRIVER("clk rate target %d, available %d\n", target, result);
@@ -1896,6 +1902,8 @@ void ltdc_suspend(struct drm_device *ddev)
 
 	DRM_DEBUG_DRIVER("\n");
 	clk_disable_unprepare(ldev->pixel_clk);
+	if (ldev->lvds_clk)
+		clk_disable_unprepare(ldev->lvds_clk);
 }
 
 int ltdc_resume(struct drm_device *ddev)
@@ -1910,6 +1918,13 @@ int ltdc_resume(struct drm_device *ddev)
 		DRM_ERROR("failed to enable pixel clock (%d)\n", ret);
 		return ret;
 	}
+	if (ldev->lvds_clk) {
+		if (clk_prepare_enable(ldev->lvds_clk)) {
+			clk_disable_unprepare(ldev->pixel_clk);
+			DRM_ERROR("Unable to prepare lvds clock\n");
+			return -ENODEV;
+		}
+	}
 
 	return 0;
 }
@@ -1981,6 +1996,10 @@ int ltdc_load(struct drm_device *ddev)
 		}
 	}
 
+	ldev->lvds_clk = devm_clk_get(dev, "lvds");
+	if (IS_ERR(ldev->lvds_clk))
+		ldev->lvds_clk = NULL;
+
 	rstc = devm_reset_control_get_exclusive(dev, NULL);
 
 	mutex_init(&ldev->err_lock);
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index 9d488043ffdb..4a60ce5b610c 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -44,6 +44,7 @@ struct ltdc_device {
 	void __iomem *regs;
 	struct regmap *regmap;
 	struct clk *pixel_clk;	/* lcd pixel clock */
+	struct clk *lvds_clk;	/* lvds pixel clock */
 	struct mutex err_lock;	/* protecting error_status */
 	struct ltdc_caps caps;
 	u32 irq_status;

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Tue Feb  6 03:33:15 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Tue, 6 Feb 2024 12:33:15 +0100
Subject: [PATCH v4 0/3] Introduce STM32 LVDS driver
Message-ID: <20240206-lvds-v4-0-98d5f9af399d@foss.st.com>

This serie introduces a new DRM bridge driver for STM32MP257 platforms
based on Arm Cortex-35. It also adds an instance in the device-tree and
handle the inclusion of the driver within the DRM framework. First patch
adds a new panel compatible in the panel-lvds driver, which is used by
default on the STM32MP257.

Changes in v4:
	- Align dt-bindings filename and compatible
	- Remove redundant word in [1/6] subject
	- Fix example on typo
	- Some minor fixes on YAML syntax
	- Explicitly include linux/platform_device.h
	- Drop device-tree related patch after internal discussions
	- Rebase on latest drm-misc-next

Changes in v3:
	- Changed the compatible to show SoC specificity
	- Fixed includes in dt-binding example
	- Added "#clock-cells" description in dt-binding example
	- Some minor fixes on typo

Changes in v2:
	- Dropped [1/8] because already merged
	- Dropped [4/8] since not mandatory for this serie
	- [1/6]: Switch compatible and clock-cells related areas
	- [1/6]: Remove faulty #include in the example.
	- [1/6]: Add missing entry in MAINTAINERS
	- [2/6]: Removed CamelCase macros
	- [2/6]: Removed hard to read debug log
	- [3/6]: Fixed my address
	- [3/6]: Fixed smatch warning
	- [5/6]: Move changes to stm32mp255.dtsi

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Raphael Gallais-Pou (3):
      dt-bindings: display: add STM32 LVDS device
      drm/stm: lvds: add new STM32 LVDS Display Interface Transmitter driver
      drm/stm: ltdc: add lvds pixel clock

 .../bindings/display/st,stm32mp25-lvds.yaml        |  119 ++
 MAINTAINERS                                        |    1 +
 drivers/gpu/drm/stm/Kconfig                        |   11 +
 drivers/gpu/drm/stm/Makefile                       |    2 +
 drivers/gpu/drm/stm/ltdc.c                         |   19 +
 drivers/gpu/drm/stm/ltdc.h                         |    1 +
 drivers/gpu/drm/stm/lvds.c                         | 1226 ++++++++++++++++++++
 7 files changed, 1379 insertions(+)
---
base-commit: bb3bc3eac316b7c388733e625cc2343131b69dee
change-id: 20240205-lvds-e084ec50e878

Best regards,
-- 
Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>



From raphael.gallais-pou at foss.st.com  Tue Feb  6 03:33:17 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Tue, 6 Feb 2024 12:33:17 +0100
Subject: [PATCH v4 2/3] drm/stm: lvds: add new STM32 LVDS Display Interface
 Transmitter driver
In-Reply-To: <20240206-lvds-v4-0-98d5f9af399d@foss.st.com>
References: <20240206-lvds-v4-0-98d5f9af399d@foss.st.com>
Message-ID: <20240206-lvds-v4-2-98d5f9af399d@foss.st.com>

The Low-Voltage Differential Signaling (LVDS) Display Interface
Transmitter handles the LVDS protocol: it maps the pixels received from
the upstream Pixel-DMA LCD-TFT Display Controller (LTDC) onto the LVDS
PHY.

It is composed of three sub blocks:
	* LVDS host: handles the LVDS protocol (FPD / OpenLDI) and maps
	  its input pixels onto the data lanes of the PHY
	* LVDS PHY: parallelize the data and drives the LVDS data lanes
	* LVDS wrapper: handles top-level settings

The LVDS controller driver supports the following high-level features:
	* FDP-Link-I and OpenLDI (v0.95) protocols
	* Single-Link or Dual-Link operation
	* Single-Display or Double-Display (with the same content
	  duplicated on both)
	* Flexible Bit-Mapping, including JEIDA and VESA
	* RGB888 or RGB666 output
	* Synchronous design, with one input pixel per clock cycle

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Changes in v4:
	- Explicitly include linux/platform_device.h, dependency introduced by
	ef175b29a242 of: Stop circularly including of_device.h and of_platform.h

Changes in v3:
	- s/regroups/is composed of/ in commit log
	- Change the compatible to show SoC specificity

Changes in v2:
	- Fixed Camel Case macros
	- Removed debug log
---
 drivers/gpu/drm/stm/Kconfig  |   11 +
 drivers/gpu/drm/stm/Makefile |    2 +
 drivers/gpu/drm/stm/lvds.c   | 1226 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1239 insertions(+)

diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig
index fa49cde43bb2..9627814d027c 100644
--- a/drivers/gpu/drm/stm/Kconfig
+++ b/drivers/gpu/drm/stm/Kconfig
@@ -20,3 +20,14 @@ config DRM_STM_DSI
 	select DRM_DW_MIPI_DSI
 	help
 	  Choose this option for MIPI DSI support on STMicroelectronics SoC.
+
+config DRM_STM_LVDS
+	tristate "STMicroelectronics LVDS Display Interface Transmitter DRM driver"
+	depends on DRM_STM
+	help
+	  Enable support for LVDS encoders on STMicroelectronics SoC.
+	  The STM LVDS is a bridge which serialize pixel stream onto
+	  a LVDS protocol.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called lvds.
diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile
index 4df5caf01f35..ad740d6175a6 100644
--- a/drivers/gpu/drm/stm/Makefile
+++ b/drivers/gpu/drm/stm/Makefile
@@ -5,4 +5,6 @@ stm-drm-y := \
 
 obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o
 
+obj-$(CONFIG_DRM_STM_LVDS) += lvds.o
+
 obj-$(CONFIG_DRM_STM) += stm-drm.o
diff --git a/drivers/gpu/drm/stm/lvds.c b/drivers/gpu/drm/stm/lvds.c
new file mode 100644
index 000000000000..ff872788943d
--- /dev/null
+++ b/drivers/gpu/drm/stm/lvds.c
@@ -0,0 +1,1226 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Author(s): Rapha?l GALLAIS-POU <raphael.gallais-pou at foss.st.com> for STMicroelectronics.
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_device.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/media-bus-format.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+/* LVDS Host registers */
+#define LVDS_CR		0x0000  /* configuration register */
+#define LVDS_DMLCR0	0x0004  /* data mapping lsb configuration register 0 */
+#define LVDS_DMMCR0	0x0008  /* data mapping msb configuration register 0 */
+#define LVDS_DMLCR1	0x000C  /* data mapping lsb configuration register 1 */
+#define LVDS_DMMCR1	0x0010  /* data mapping msb configuration register 1 */
+#define LVDS_DMLCR2	0x0014  /* data mapping lsb configuration register 2 */
+#define LVDS_DMMCR2	0x0018  /* data mapping msb configuration register 2 */
+#define LVDS_DMLCR3	0x001C  /* data mapping lsb configuration register 3 */
+#define LVDS_DMMCR3	0x0020  /* data mapping msb configuration register 3 */
+#define LVDS_DMLCR4	0x0024  /* data mapping lsb configuration register 4 */
+#define LVDS_DMMCR4	0x0028  /* data mapping msb configuration register 4 */
+#define LVDS_CDL1CR	0x002C  /* channel distrib link 1 configuration register */
+#define LVDS_CDL2CR	0x0030  /* channel distrib link 2 configuration register */
+
+#define CDL1CR_DEFAULT	0x04321 /* Default value for CDL1CR */
+#define CDL2CR_DEFAULT	0x59876 /* Default value for CDL2CR */
+
+#define LVDS_DMLCR(bit)	(LVDS_DMLCR0 + 0x8 * (bit))
+#define LVDS_DMMCR(bit)	(LVDS_DMMCR0 + 0x8 * (bit))
+
+/* LVDS Wrapper registers */
+#define LVDS_WCLKCR	0x11B0  /* Wrapper clock control register */
+
+#define LVDS_HWCFGR	0x1FF0  /* HW configuration register	*/
+#define LVDS_VERR	0x1FF4  /* Version register	*/
+#define LVDS_IPIDR	0x1FF8  /* Identification register	*/
+#define LVDS_SIDR	0x1FFC  /* Size Identification register	*/
+
+/* Bitfield description */
+#define CR_LVDSEN	BIT(0)  /* LVDS PHY Enable */
+#define CR_HSPOL	BIT(1)  /* Horizontal Synchronization Polarity */
+#define CR_VSPOL	BIT(2)  /* Vertical Synchronization Polarity */
+#define CR_DEPOL	BIT(3)  /* Data Enable Polarity */
+#define CR_CI		BIT(4)  /* Control Internal (software controlled bit) */
+#define CR_LKMOD	BIT(5)  /* Link Mode, for both Links */
+#define CR_LKPHA	BIT(6)  /* Link Phase, for both Links */
+#define CR_LK1POL	GENMASK(20, 16)  /* Link-1 output Polarity */
+#define CR_LK2POL	GENMASK(25, 21)  /* Link-2 output Polarity */
+
+#define DMMCR_MAP0	GENMASK(4, 0) /* Mapping for bit 0 of datalane x */
+#define DMMCR_MAP1	GENMASK(9, 5) /* Mapping for bit 1 of datalane x */
+#define DMMCR_MAP2	GENMASK(14, 10) /* Mapping for bit 2 of datalane x */
+#define DMMCR_MAP3	GENMASK(19, 15) /* Mapping for bit 3 of datalane x */
+#define DMLCR_MAP4	GENMASK(4, 0) /* Mapping for bit 4 of datalane x */
+#define DMLCR_MAP5	GENMASK(9, 5) /* Mapping for bit 5 of datalane x */
+#define DMLCR_MAP6	GENMASK(14, 10) /* Mapping for bit 6 of datalane x */
+
+#define CDLCR_DISTR0	GENMASK(3, 0) /* Channel distribution for lane 0 */
+#define CDLCR_DISTR1	GENMASK(7, 4) /* Channel distribution for lane 1 */
+#define CDLCR_DISTR2	GENMASK(11, 8) /* Channel distribution for lane 2 */
+#define CDLCR_DISTR3	GENMASK(15, 12) /* Channel distribution for lane 3 */
+#define CDLCR_DISTR4	GENMASK(19, 16) /* Channel distribution for lane 4 */
+
+#define PHY_GCR_BIT_CLK_OUT	BIT(0)  /* BIT clock enable */
+#define PHY_GCR_LS_CLK_OUT	BIT(4)  /* LS clock enable */
+#define PHY_GCR_DP_CLK_OUT	BIT(8)  /* DP clock enable */
+#define PHY_GCR_RSTZ		BIT(24) /* LVDS PHY digital reset */
+#define PHY_GCR_DIV_RSTN	BIT(25) /* Output divider reset */
+#define PHY_SCR_TX_EN		BIT(16) /* Transmission mode enable */
+/* Current mode driver enable */
+#define PHY_CMCR_CM_EN_DL	(BIT(28) | BIT(20) | BIT(12) | BIT(4))
+#define PHY_CMCR_CM_EN_DL4	BIT(4)
+/* Bias enable */
+#define PHY_BCR1_EN_BIAS_DL	(BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0))
+#define PHY_BCR2_BIAS_EN	BIT(28)
+/* Voltage mode driver enable */
+#define PHY_BCR3_VM_EN_DL	(BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0))
+#define PHY_DCR_POWER_OK	BIT(12)
+#define PHY_CFGCR_EN_DIG_DL	GENMASK(4, 0) /* LVDS PHY digital lane enable */
+#define PHY_PLLCR1_PLL_EN	BIT(0) /* LVDS PHY PLL enable */
+#define PHY_PLLCR1_EN_SD	BIT(1) /* LVDS PHY PLL sigma-delta signal enable */
+#define PHY_PLLCR1_EN_TWG	BIT(2) /* LVDS PHY PLL triangular wave generator enable */
+#define PHY_PLLCR1_DIV_EN	BIT(8) /* LVDS PHY PLL dividers enable */
+#define PHY_PLLCR2_NDIV		GENMASK(25, 16) /* NDIV mask value */
+#define PHY_PLLCR2_BDIV		GENMASK(9, 0)   /* BDIV mask value */
+#define PHY_PLLSR_PLL_LOCK	BIT(0) /* LVDS PHY PLL lock status */
+#define PHY_PLLSDCR1_MDIV	GENMASK(9, 0)   /* MDIV mask value */
+#define PHY_PLLTESTCR_TDIV	GENMASK(25, 16) /* TDIV mask value */
+#define PHY_PLLTESTCR_CLK_EN	BIT(0) /* Test clock enable */
+#define PHY_PLLTESTCR_EN	BIT(8) /* Test divider output enable */
+
+#define WCLKCR_SECND_CLKPIX_SEL	BIT(0) /* Pixel clock selection */
+#define WCLKCR_SRCSEL		BIT(8) /* Source selection for the pixel clock */
+
+/* Sleep & timeout for pll lock/unlock */
+#define SLEEP_US	1000
+#define TIMEOUT_US	200000
+
+/*
+ * The link phase defines whether an ODD pixel is carried over together with
+ * the next EVEN pixel or together with the previous EVEN pixel.
+ *
+ * LVDS_DUAL_LINK_EVEN_ODD_PIXELS (LKPHA = 0)
+ *
+ * ,--------.  ,--------.  ,--------.  ,--------.  ,---------.
+ * | ODD  LK \/ PIXEL  3 \/ PIXEL  1 \/ PIXEL' 1 \/ PIXEL' 3 |
+ * | EVEN LK /\ PIXEL  2 /\ PIXEL' 0 /\ PIXEL' 2 /\ PIXEL' 4 |
+ * `--------'  `--------'  `--------'  `--------'  `---------'
+ *
+ * LVDS_DUAL_LINK_ODD_EVEN_PIXELS (LKPHA = 1)
+ *
+ * ,--------.  ,--------.  ,--------.  ,--------.  ,---------.
+ * | ODD  LK \/ PIXEL  3 \/ PIXEL  1 \/ PIXEL' 1 \/ PIXEL' 3 |
+ * | EVEN LK /\ PIXEL  4 /\ PIXEL  2 /\ PIXEL' 0 /\ PIXEL' 2 |
+ * `--------'  `--------'  `--------'  `--------'  `---------'
+ *
+ */
+enum lvds_link_type {
+	LVDS_SINGLE_LINK_PRIMARY = 0,
+	LVDS_SINGLE_LINK_SECONDARY,
+	LVDS_DUAL_LINK_EVEN_ODD_PIXELS,
+	LVDS_DUAL_LINK_ODD_EVEN_PIXELS,
+};
+
+enum lvds_pixel {
+	PIX_R_0 = 0,
+	PIX_R_1,
+	PIX_R_2,
+	PIX_R_3,
+	PIX_R_4,
+	PIX_R_5,
+	PIX_R_6,
+	PIX_R_7,
+	PIX_G_0,
+	PIX_G_1,
+	PIX_G_2,
+	PIX_G_3,
+	PIX_G_4,
+	PIX_G_5,
+	PIX_G_6,
+	PIX_G_7,
+	PIX_B_0,
+	PIX_B_1,
+	PIX_B_2,
+	PIX_B_3,
+	PIX_B_4,
+	PIX_B_5,
+	PIX_B_6,
+	PIX_B_7,
+	PIX_H_S,
+	PIX_V_S,
+	PIX_D_E,
+	PIX_C_E,
+	PIX_C_I,
+	PIX_TOG,
+	PIX_ONE,
+	PIX_ZER,
+};
+
+struct phy_reg_offsets {
+	u32 GCR;	/* Global Control Register	*/
+	u32 CMCR1;    /* Current Mode Control Register 1 */
+	u32 CMCR2;    /* Current Mode Control Register 2 */
+	u32 SCR;      /* Serial Control Register	*/
+	u32 BCR1;     /* Bias Control Register 1	*/
+	u32 BCR2;     /* Bias Control Register 2	*/
+	u32 BCR3;     /* Bias Control Register 3	*/
+	u32 MPLCR;    /* Monitor PLL Lock Control Register */
+	u32 DCR;      /* Debug Control Register	*/
+	u32 SSR1;     /* Spare Status Register 1	*/
+	u32 CFGCR;    /* Configuration Control Register */
+	u32 PLLCR1;   /* PLL_MODE 1 Control Register	*/
+	u32 PLLCR2;   /* PLL_MODE 2 Control Register	*/
+	u32 PLLSR;    /* PLL Status Register	*/
+	u32 PLLSDCR1; /* PLL_SD_1 Control Register	*/
+	u32 PLLSDCR2; /* PLL_SD_2 Control Register	*/
+	u32 PLLTWGCR1;/* PLL_TWG_1 Control Register	*/
+	u32 PLLTWGCR2;/* PLL_TWG_2 Control Register	*/
+	u32 PLLCPCR;  /* PLL_CP Control Register	*/
+	u32 PLLTESTCR;/* PLL_TEST Control Register	*/
+};
+
+struct lvds_phy_info {
+	u32 base;
+	struct phy_reg_offsets ofs;
+};
+
+static struct lvds_phy_info lvds_phy_16ff_primary = {
+	.base = 0x1000,
+	.ofs = {
+		.GCR = 0x0,
+		.CMCR1 = 0xC,
+		.CMCR2 = 0x10,
+		.SCR = 0x20,
+		.BCR1 = 0x2C,
+		.BCR2 = 0x30,
+		.BCR3 = 0x34,
+		.MPLCR = 0x64,
+		.DCR = 0x84,
+		.SSR1 = 0x88,
+		.CFGCR = 0xA0,
+		.PLLCR1 = 0xC0,
+		.PLLCR2 = 0xC4,
+		.PLLSR = 0xC8,
+		.PLLSDCR1 = 0xCC,
+		.PLLSDCR2 = 0xD0,
+		.PLLTWGCR1 = 0xD4,
+		.PLLTWGCR2 = 0xD8,
+		.PLLCPCR = 0xE0,
+		.PLLTESTCR = 0xE8,
+	}
+};
+
+static struct lvds_phy_info lvds_phy_16ff_secondary = {
+	.base = 0x1100,
+	.ofs = {
+		.GCR = 0x0,
+		.CMCR1 = 0xC,
+		.CMCR2 = 0x10,
+		.SCR = 0x20,
+		.BCR1 = 0x2C,
+		.BCR2 = 0x30,
+		.BCR3 = 0x34,
+		.MPLCR = 0x64,
+		.DCR = 0x84,
+		.SSR1 = 0x88,
+		.CFGCR = 0xA0,
+		.PLLCR1 = 0xC0,
+		.PLLCR2 = 0xC4,
+		.PLLSR = 0xC8,
+		.PLLSDCR1 = 0xCC,
+		.PLLSDCR2 = 0xD0,
+		.PLLTWGCR1 = 0xD4,
+		.PLLTWGCR2 = 0xD8,
+		.PLLCPCR = 0xE0,
+		.PLLTESTCR = 0xE8,
+	}
+};
+
+struct stm_lvds {
+	void __iomem *base;
+	struct device *dev;
+	struct clk *pclk;		/* APB peripheral clock */
+	struct clk *pllref_clk;		/* Reference clock for the internal PLL */
+	struct clk_hw lvds_ck_px;	/* Pixel clock */
+	u32 pixel_clock_rate;		/* Pixel clock rate */
+
+	struct lvds_phy_info *primary;
+	struct lvds_phy_info *secondary;
+
+	struct drm_bridge lvds_bridge;
+	struct drm_bridge *next_bridge;
+	struct drm_connector connector;
+	struct drm_encoder *encoder;
+	struct drm_panel *panel;
+
+	u32 hw_version;
+	u32 link_type;
+};
+
+#define bridge_to_stm_lvds(b) \
+	container_of(b, struct stm_lvds, lvds_bridge)
+
+#define connector_to_stm_lvds(c) \
+	container_of(c, struct stm_lvds, connector)
+
+#define lvds_is_dual_link(lvds) \
+	({	\
+	typeof(lvds) __lvds = (lvds);	\
+	__lvds == LVDS_DUAL_LINK_EVEN_ODD_PIXELS ||	\
+	__lvds == LVDS_DUAL_LINK_ODD_EVEN_PIXELS;	\
+	})
+
+static inline void lvds_write(struct stm_lvds *lvds, u32 reg, u32 val)
+{
+	writel(val, lvds->base + reg);
+}
+
+static inline u32 lvds_read(struct stm_lvds *lvds, u32 reg)
+{
+	return readl(lvds->base + reg);
+}
+
+static inline void lvds_set(struct stm_lvds *lvds, u32 reg, u32 mask)
+{
+	lvds_write(lvds, reg, lvds_read(lvds, reg) | mask);
+}
+
+static inline void lvds_clear(struct stm_lvds *lvds, u32 reg, u32 mask)
+{
+	lvds_write(lvds, reg, lvds_read(lvds, reg) & ~mask);
+}
+
+/*
+ * Expected JEIDA-RGB888 data to be sent in LSB format
+ *	    bit6 ............................bit0
+ * CHAN0   {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE}
+ * CHAN1   {G2,  R7,  R6,   R5,   R4,   R3,  R2}
+ * CHAN2   {B3,  B2,  G7,   G6,   G5,   G4,  G3}
+ * CHAN3   {DE,  VS,  HS,   B7,   B6,   B5,  B4}
+ * CHAN4   {CE,  B1,  B0,   G1,   G0,   R1,  R0}
+ */
+enum lvds_pixel lvds_bitmap_jeida_rgb888[5][7] = {
+	{ PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE },
+	{ PIX_G_2, PIX_R_7, PIX_R_6, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2 },
+	{ PIX_B_3, PIX_B_2, PIX_G_7, PIX_G_6, PIX_G_5, PIX_G_4, PIX_G_3 },
+	{ PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_7, PIX_B_6, PIX_B_5, PIX_B_4 },
+	{ PIX_C_E, PIX_B_1, PIX_B_0, PIX_G_1, PIX_G_0, PIX_R_1, PIX_R_0 }
+};
+
+/*
+ * Expected VESA-RGB888 data to be sent in LSB format
+ *	    bit6 ............................bit0
+ * CHAN0   {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE}
+ * CHAN1   {G0,  R5,  R4,   R3,   R2,   R1,  R0}
+ * CHAN2   {B1,  B0,  G5,   G4,   G3,   G2,  G1}
+ * CHAN3   {DE,  VS,  HS,   B5,   B4,   B3,  B2}
+ * CHAN4   {CE,  B7,  B6,   G7,   G6,   R7,  R6}
+ */
+enum lvds_pixel lvds_bitmap_vesa_rgb888[5][7] = {
+	{ PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE },
+	{ PIX_G_0, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2, PIX_R_1, PIX_R_0 },
+	{ PIX_B_1, PIX_B_0, PIX_G_5, PIX_G_4, PIX_G_3, PIX_G_2, PIX_G_1 },
+	{ PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_5, PIX_B_4, PIX_B_3, PIX_B_2 },
+	{ PIX_C_E, PIX_B_7, PIX_B_6, PIX_G_7, PIX_G_6, PIX_R_7, PIX_R_6 }
+};
+
+/*
+ * Clocks and PHY related functions
+ */
+static int lvds_pll_enable(struct stm_lvds *lvds, struct lvds_phy_info *phy)
+{
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	u32 lvds_gcr;
+	int val, ret;
+
+	/*
+	 * PLL lock timing control for the monitor unmask after startup (pll_en)
+	 * Adjusted value so that the masking window is opened at start-up
+	 */
+	lvds_write(lvds, phy->base + phy->ofs.MPLCR, (0x200 - 0x160) << 16);
+
+	/* Enable bias */
+	lvds_write(lvds, phy->base + phy->ofs.BCR2, PHY_BCR2_BIAS_EN);
+
+	/* Enable DP, LS, BIT clock output */
+	lvds_gcr = PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT;
+	lvds_set(lvds, phy->base + phy->ofs.GCR, lvds_gcr);
+
+	/* Power up all output dividers */
+	lvds_set(lvds, phy->base + phy->ofs.PLLTESTCR, PHY_PLLTESTCR_EN);
+	lvds_set(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_DIV_EN);
+
+	/* Set PHY in serial transmission mode */
+	lvds_set(lvds, phy->base + phy->ofs.SCR, PHY_SCR_TX_EN);
+
+	/* Enable the LVDS PLL & wait for its lock */
+	lvds_set(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_PLL_EN);
+	ret = readl_poll_timeout_atomic(lvds->base + phy->base + phy->ofs.PLLSR,
+					val, val & PHY_PLLSR_PLL_LOCK,
+					SLEEP_US, TIMEOUT_US);
+	if (ret)
+		drm_err(drm, "!TIMEOUT! waiting PLL, let's continue\n");
+
+	/* WCLKCR_SECND_CLKPIX_SEL is for dual link */
+	lvds_write(lvds, LVDS_WCLKCR, WCLKCR_SECND_CLKPIX_SEL);
+
+	lvds_set(lvds, phy->ofs.PLLTESTCR, PHY_PLLTESTCR_CLK_EN);
+
+	return ret;
+}
+
+static int pll_get_clkout_khz(int clkin_khz, int bdiv, int mdiv, int ndiv)
+{
+	int divisor = ndiv * bdiv;
+
+	/* Prevents from division by 0 */
+	if (!divisor)
+		return 0;
+
+	return clkin_khz * mdiv / divisor;
+}
+
+#define TDIV	70
+#define NDIV_MIN	2
+#define NDIV_MAX	6
+#define BDIV_MIN	2
+#define BDIV_MAX	6
+#define MDIV_MIN	1
+#define MDIV_MAX	1023
+
+static int lvds_pll_get_params(struct stm_lvds *lvds,
+			       unsigned int clkin_khz, unsigned int clkout_khz,
+			       unsigned int *bdiv, unsigned int *mdiv, unsigned int *ndiv)
+{
+	int delta, best_delta; /* all in khz */
+	int i, o, n;
+
+	/* Early checks preventing division by 0 & odd results */
+	if (clkin_khz <= 0 || clkout_khz <= 0)
+		return -EINVAL;
+
+	best_delta = 1000000; /* big started value (1000000khz) */
+
+	for (i = NDIV_MIN; i <= NDIV_MAX; i++) {
+		for (o = BDIV_MIN; o <= BDIV_MAX; o++) {
+			n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz);
+			/* Check ndiv according to vco range */
+			if (n < MDIV_MIN || n > MDIV_MAX)
+				continue;
+			/* Check if new delta is better & saves parameters */
+			delta = pll_get_clkout_khz(clkin_khz, i, n, o) - clkout_khz;
+			if (delta < 0)
+				delta = -delta;
+			if (delta < best_delta) {
+				*ndiv = i;
+				*mdiv = n;
+				*bdiv = o;
+				best_delta = delta;
+			}
+			/* fast return in case of "perfect result" */
+			if (!delta)
+				return 0;
+		}
+	}
+
+	return 0;
+}
+
+static void lvds_pll_config(struct stm_lvds *lvds, struct lvds_phy_info *phy)
+{
+	unsigned int pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0;
+	struct clk_hw *hwclk;
+	int multiplier;
+
+	/*
+	 * The LVDS PHY includes a low power low jitter high performance and
+	 * highly configuration Phase Locked Loop supporting integer and
+	 * fractional multiplication ratios and Spread Spectrum Clocking.  In
+	 * integer mode, the only software supported feature for now, the PLL is
+	 * made of a pre-divider NDIV, a feedback multiplier MDIV, followed by
+	 * several post-dividers, each one with a specific application.
+	 *
+	 *          ,------.         ,-----.     ,-----.
+	 * Fref --> | NDIV | -Fpdf-> | PFD | --> | VCO | --------> Fvco
+	 *          `------'     ,-> |     |     `-----'  |
+	 *                       |   `-----'              |
+	 *                       |         ,------.       |
+	 *                       `-------- | MDIV | <-----'
+	 *                                 `------'
+	 *
+	 * From the output of the VCO, the clock can be optionally extracted on
+	 * the RCC clock observer, with a divider TDIV, for testing purpose, or
+	 * is passed through a programmable post-divider BDIV.  Finally, the
+	 * frequency can be divided further with two fixed dividers.
+	 *
+	 *                            ,--------.
+	 *                    ,-----> | DP div | ----------------> Fdp
+	 *          ,------.  |       `--------'
+	 * Fvco --> | BDIV | ------------------------------------> Fbit
+	 *      |   `------'    ,------.   |
+	 *      `-------------> | TDIV | --.---------------------> ClkObs
+	 *                      '------'   |    ,--------.
+	 *                                 `--> | LS div | ------> Fls
+	 *                                      '--------'
+	 *
+	 * The LS and DP clock dividers operate at a fixed ratio of 7 and 3.5
+	 * respectively with regards to fbit. LS divider converts the bit clock
+	 * to a pixel clock per lane per clock sample (Fls).  This is useful
+	 * when used to generate a dot clock for the display unit RGB output,
+	 * and DP divider is.
+	 */
+
+	hwclk = __clk_get_hw(lvds->pllref_clk);
+	if (!hwclk)
+		return;
+
+	pll_in_khz = clk_hw_get_rate(hwclk) / 1000;
+
+	if (lvds_is_dual_link(lvds->link_type))
+		multiplier = 2;
+	else
+		multiplier = 1;
+
+	lvds_pll_get_params(lvds, pll_in_khz,
+			    lvds->pixel_clock_rate * 7 / 1000 / multiplier,
+			    &bdiv, &mdiv, &ndiv);
+
+	/* Set BDIV, MDIV and NDIV */
+	lvds_write(lvds, phy->base + phy->ofs.PLLCR2, ndiv << 16);
+	lvds_set(lvds, phy->base + phy->ofs.PLLCR2, bdiv);
+	lvds_write(lvds, phy->base + phy->ofs.PLLSDCR1, mdiv);
+
+	/* Hardcode TDIV as dynamic values are not yet implemented */
+	lvds_write(lvds, phy->base + phy->ofs.PLLTESTCR, TDIV << 16);
+
+	/*
+	 * For now, PLL just needs to be in integer mode
+	 * Fractional and spread spectrum clocking are not yet implemented
+	 *
+	 * PLL integer mode:
+	 *	- PMRY_PLL_TWG_STEP = PMRY_PLL_SD_INT_RATIO
+	 *	- EN_TWG = 0
+	 *	- EN_SD = 0
+	 *	- DOWN_SPREAD = 0
+	 *
+	 * PLL fractional mode:
+	 *	- EN_TWG = 0
+	 *	- EN_SD = 1
+	 *	- DOWN_SPREAD = 0
+	 *
+	 * Spread Spectrum Clocking
+	 *	- EN_TWG = 1
+	 *	- EN_SD = 1
+	 */
+
+	/* Disable TWG and SD */
+	lvds_clear(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_EN_TWG | PHY_PLLCR1_EN_SD);
+
+	/* Power up bias and PLL dividers */
+	lvds_set(lvds, phy->base + phy->ofs.DCR, PHY_DCR_POWER_OK);
+	lvds_set(lvds, phy->base + phy->ofs.CMCR1, PHY_CMCR_CM_EN_DL);
+	lvds_set(lvds, phy->base + phy->ofs.CMCR2, PHY_CMCR_CM_EN_DL4);
+
+	/* Set up voltage mode */
+	lvds_set(lvds, phy->base + phy->ofs.PLLCPCR, 0x1);
+	lvds_set(lvds, phy->base + phy->ofs.BCR3, PHY_BCR3_VM_EN_DL);
+	lvds_set(lvds, phy->base + phy->ofs.BCR1, PHY_BCR1_EN_BIAS_DL);
+	/* Enable digital datalanes */
+	lvds_set(lvds, phy->base + phy->ofs.CFGCR, PHY_CFGCR_EN_DIG_DL);
+}
+
+static int lvds_pixel_clk_enable(struct clk_hw *hw)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	struct lvds_phy_info *phy;
+	int ret;
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		drm_err(drm, "Failed to enable lvds peripheral clk\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(lvds->pllref_clk);
+	if (ret) {
+		drm_err(drm, "Failed to enable lvds reference clk\n");
+		clk_disable_unprepare(lvds->pclk);
+		return ret;
+	}
+
+	/* In case we are operating in dual link the second PHY is set before the primary PHY. */
+	if (lvds->secondary) {
+		phy = lvds->secondary;
+
+		/* Release LVDS PHY from reset mode */
+		lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+		lvds_pll_config(lvds, phy);
+
+		ret = lvds_pll_enable(lvds, phy);
+		if (ret) {
+			drm_err(drm, "Failed to enable secondary PHY PLL: %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (lvds->primary) {
+		phy = lvds->primary;
+
+		/* Release LVDS PHY from reset mode */
+		lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+		lvds_pll_config(lvds, phy);
+
+		ret = lvds_pll_enable(lvds, phy);
+		if (ret) {
+			drm_err(drm, "Failed to enable primary PHY PLL: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static void lvds_pixel_clk_disable(struct clk_hw *hw)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+
+	/*
+	 * For each PHY:
+	 * Disable DP, LS, BIT clock outputs
+	 * Shutdown the PLL
+	 * Assert LVDS PHY in reset mode
+	 */
+
+	if (lvds->primary) {
+		lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR,
+			   (PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT));
+		lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR1,
+			   PHY_PLLCR1_PLL_EN);
+		lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR,
+			   PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+	}
+
+	if (lvds->secondary) {
+		lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR,
+			   (PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT));
+		lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.PLLCR1,
+			   PHY_PLLCR1_PLL_EN);
+		lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR,
+			   PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+	}
+
+	clk_disable_unprepare(lvds->pllref_clk);
+	clk_disable_unprepare(lvds->pclk);
+}
+
+static unsigned long lvds_pixel_clk_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	unsigned int pll_in_khz, bdiv, mdiv, ndiv;
+	int ret, multiplier, pll_out_khz;
+	u32 val;
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		drm_err(drm, "Failed to enable lvds peripheral clk\n");
+		return 0;
+	}
+
+	if (lvds_is_dual_link(lvds->link_type))
+		multiplier = 2;
+	else
+		multiplier = 1;
+
+	val = lvds_read(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR2);
+
+	ndiv = (val & PHY_PLLCR2_NDIV) >> 16;
+	bdiv = (val & PHY_PLLCR2_BDIV) >> 0;
+
+	mdiv = (unsigned int)lvds_read(lvds,
+				       lvds->primary->base + lvds->primary->ofs.PLLSDCR1);
+
+	pll_in_khz = (unsigned int)(parent_rate / 1000);
+
+	/* Compute values if not yet accessible */
+	if (val == 0 || mdiv == 0) {
+		lvds_pll_get_params(lvds, pll_in_khz,
+				    lvds->pixel_clock_rate * 7 / 1000 / multiplier,
+				    &bdiv, &mdiv, &ndiv);
+	}
+
+	pll_out_khz = pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv);
+	drm_dbg(drm, "ndiv %d , bdiv %d, mdiv %d, pll_out_khz %d\n",
+		ndiv, bdiv, mdiv, pll_out_khz);
+
+	/*
+	 * 1/7 because for each pixel in 1 lane there is 7 bits
+	 * We want pixclk, not bitclk
+	 */
+	lvds->pixel_clock_rate = pll_out_khz * 1000 * multiplier / 7;
+
+	clk_disable_unprepare(lvds->pclk);
+
+	return (unsigned long)lvds->pixel_clock_rate;
+}
+
+static long lvds_pixel_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *parent_rate)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+	unsigned int pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0;
+	const struct drm_connector *connector;
+	const struct drm_display_mode *mode;
+	int multiplier;
+
+	connector = &lvds->connector;
+	if (!connector)
+		return -EINVAL;
+
+	if (list_empty(&connector->modes)) {
+		drm_dbg(connector->dev, "connector: empty modes list\n");
+		return -EINVAL;
+	}
+
+	mode = list_first_entry(&connector->modes,
+				struct drm_display_mode, head);
+
+	pll_in_khz = (unsigned int)(*parent_rate / 1000);
+
+	if (lvds_is_dual_link(lvds->link_type))
+		multiplier = 2;
+	else
+		multiplier = 1;
+
+	lvds_pll_get_params(lvds, pll_in_khz, mode->clock * 7 / multiplier, &bdiv, &mdiv, &ndiv);
+
+	/*
+	 * 1/7 because for each pixel in 1 lane there is 7 bits
+	 * We want pixclk, not bitclk
+	 */
+	lvds->pixel_clock_rate = (unsigned long)pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv)
+					 * 1000 * multiplier / 7;
+
+	return lvds->pixel_clock_rate;
+}
+
+static const struct clk_ops lvds_pixel_clk_ops = {
+	.enable = lvds_pixel_clk_enable,
+	.disable = lvds_pixel_clk_disable,
+	.recalc_rate = lvds_pixel_clk_recalc_rate,
+	.round_rate = lvds_pixel_clk_round_rate,
+};
+
+static const struct clk_init_data clk_data = {
+	.name = "clk_pix_lvds",
+	.ops = &lvds_pixel_clk_ops,
+	.parent_names = (const char * []) {"ck_ker_lvdsphy"},
+	.num_parents = 1,
+	.flags = CLK_IGNORE_UNUSED,
+};
+
+static void lvds_pixel_clk_unregister(void *data)
+{
+	struct stm_lvds *lvds = data;
+
+	of_clk_del_provider(lvds->dev->of_node);
+	clk_hw_unregister(&lvds->lvds_ck_px);
+}
+
+static int lvds_pixel_clk_register(struct stm_lvds *lvds)
+{
+	struct device_node *node = lvds->dev->of_node;
+	int ret;
+
+	lvds->lvds_ck_px.init = &clk_data;
+
+	/* set the rate by default at 148500000 */
+	lvds->pixel_clock_rate = 148500000;
+
+	ret = clk_hw_register(lvds->dev, &lvds->lvds_ck_px);
+	if (ret)
+		return ret;
+
+	ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get,
+				     &lvds->lvds_ck_px);
+	if (ret)
+		clk_hw_unregister(&lvds->lvds_ck_px);
+
+	return ret;
+}
+
+/*
+ * Host configuration related
+ */
+static void lvds_config_data_mapping(struct stm_lvds *lvds)
+{
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	const struct drm_display_info *info;
+	enum lvds_pixel (*bitmap)[7];
+	u32 lvds_dmlcr, lvds_dmmcr;
+	int i;
+
+	info = &(&lvds->connector)->display_info;
+	if (!info->num_bus_formats || !info->bus_formats) {
+		drm_warn(drm, "No LVDS bus format reported\n");
+		return;
+	}
+
+	switch (info->bus_formats[0]) {
+	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* VESA-RGB666 */
+		drm_warn(drm, "Pixel format with data mapping not yet supported.\n");
+		return;
+	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* VESA-RGB888 */
+		bitmap = lvds_bitmap_vesa_rgb888;
+		break;
+	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* JEIDA-RGB888 */
+		bitmap = lvds_bitmap_jeida_rgb888;
+		break;
+	default:
+		drm_warn(drm, "Unsupported LVDS bus format 0x%04x\n", info->bus_formats[0]);
+		return;
+	}
+
+	/* Set bitmap for each lane */
+	for (i = 0; i < 5; i++) {
+		lvds_dmlcr = ((bitmap[i][0])
+			      + (bitmap[i][1] << 5)
+			      + (bitmap[i][2] << 10)
+			      + (bitmap[i][3] << 15));
+		lvds_dmmcr = ((bitmap[i][4])
+			      + (bitmap[i][5] << 5)
+			      + (bitmap[i][6] << 10));
+
+		lvds_write(lvds, LVDS_DMLCR(i), lvds_dmlcr);
+		lvds_write(lvds, LVDS_DMMCR(i), lvds_dmmcr);
+	}
+}
+
+static void lvds_config_mode(struct stm_lvds *lvds)
+{
+	u32 bus_flags, lvds_cr = 0, lvds_cdl1cr = 0, lvds_cdl2cr = 0;
+	const struct drm_display_mode *mode;
+	const struct drm_connector *connector;
+
+	connector = &lvds->connector;
+	if (!connector)
+		return;
+
+	if (list_empty(&connector->modes)) {
+		drm_dbg(connector->dev, "connector: empty modes list\n");
+		return;
+	}
+
+	bus_flags = connector->display_info.bus_flags;
+	mode = list_first_entry(&connector->modes,
+				struct drm_display_mode, head);
+
+	lvds_clear(lvds, LVDS_CR, CR_LKMOD);
+	lvds_clear(lvds, LVDS_CDL1CR, CDLCR_DISTR0 | CDLCR_DISTR1 | CDLCR_DISTR2 |
+				      CDLCR_DISTR3 | CDLCR_DISTR4);
+	lvds_clear(lvds, LVDS_CDL2CR, CDLCR_DISTR0 | CDLCR_DISTR1 | CDLCR_DISTR2 |
+				      CDLCR_DISTR3 | CDLCR_DISTR4);
+
+	/* Set channel distribution */
+	if (lvds->primary)
+		lvds_cdl1cr = CDL1CR_DEFAULT;
+
+	if (lvds->secondary) {
+		lvds_cr |= CR_LKMOD;
+		lvds_cdl2cr = CDL2CR_DEFAULT;
+	}
+
+	/* Set signal polarity */
+	if (bus_flags & DRM_BUS_FLAG_DE_LOW)
+		lvds_cr |= CR_DEPOL;
+
+	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+		lvds_cr |= CR_HSPOL;
+
+	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+		lvds_cr |= CR_VSPOL;
+
+	switch (lvds->link_type) {
+	case LVDS_DUAL_LINK_EVEN_ODD_PIXELS: /* LKPHA = 0 */
+		lvds_cr &= ~CR_LKPHA;
+		break;
+	case LVDS_DUAL_LINK_ODD_EVEN_PIXELS: /* LKPHA = 1 */
+		lvds_cr |= CR_LKPHA;
+		break;
+	default:
+		drm_notice(lvds->lvds_bridge.dev, "No phase precised, setting default\n");
+		lvds_cr &= ~CR_LKPHA;
+		break;
+	}
+
+	/* Write config to registers */
+	lvds_set(lvds, LVDS_CR, lvds_cr);
+	lvds_write(lvds, LVDS_CDL1CR, lvds_cdl1cr);
+	lvds_write(lvds, LVDS_CDL2CR, lvds_cdl2cr);
+}
+
+static int lvds_connector_get_modes(struct drm_connector *connector)
+{
+	struct stm_lvds *lvds = connector_to_stm_lvds(connector);
+
+	return drm_panel_get_modes(lvds->panel, connector);
+}
+
+static int lvds_connector_atomic_check(struct drm_connector *connector,
+				       struct drm_atomic_state *state)
+{
+	const struct drm_display_mode *panel_mode;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc_state *crtc_state;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (!conn_state)
+		return -EINVAL;
+
+	if (list_empty(&connector->modes)) {
+		drm_dbg(connector->dev, "connector: empty modes list\n");
+		return -EINVAL;
+	}
+
+	if (!conn_state->crtc)
+		return -EINVAL;
+
+	panel_mode = list_first_entry(&connector->modes,
+				      struct drm_display_mode, head);
+
+	/* We're not allowed to modify the resolution. */
+	crtc_state = drm_atomic_get_crtc_state(state, conn_state->crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
+	if (crtc_state->mode.hdisplay != panel_mode->hdisplay ||
+	    crtc_state->mode.vdisplay != panel_mode->vdisplay)
+		return -EINVAL;
+
+	/* The flat panel mode is fixed, just copy it to the adjusted mode. */
+	drm_mode_copy(&crtc_state->adjusted_mode, panel_mode);
+
+	return 0;
+}
+
+static const struct drm_connector_helper_funcs lvds_conn_helper_funcs = {
+	.get_modes = lvds_connector_get_modes,
+	.atomic_check = lvds_connector_atomic_check,
+};
+
+static const struct drm_connector_funcs lvds_conn_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 int lvds_attach(struct drm_bridge *bridge,
+		       enum drm_bridge_attach_flags flags)
+{
+	struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);
+	struct drm_connector *connector = &lvds->connector;
+	struct drm_encoder *encoder = bridge->encoder;
+	int ret;
+
+	if (!bridge->encoder) {
+		drm_err(bridge->dev, "Parent encoder object not found\n");
+		return -ENODEV;
+	}
+
+	/* Set the encoder type as caller does not know it */
+	bridge->encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
+
+	/* No cloning support */
+	bridge->encoder->possible_clones = 0;
+
+	/* If we have a next bridge just attach it. */
+	if (lvds->next_bridge)
+		return drm_bridge_attach(bridge->encoder, lvds->next_bridge,
+					 bridge, flags);
+
+	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
+		drm_err(bridge->dev, "Fix bridge driver to make connector optional!");
+		return -EINVAL;
+	}
+
+	/* Otherwise if we have a panel, create a connector. */
+	if (!lvds->panel)
+		return 0;
+
+	ret = drm_connector_init(bridge->dev, connector,
+				 &lvds_conn_funcs, DRM_MODE_CONNECTOR_LVDS);
+	if (ret < 0)
+		return ret;
+
+	drm_connector_helper_add(connector, &lvds_conn_helper_funcs);
+
+	ret = drm_connector_attach_encoder(connector, encoder);
+
+	return ret;
+}
+
+static void lvds_atomic_enable(struct drm_bridge *bridge,
+			       struct drm_bridge_state *old_bridge_state)
+{
+	struct drm_atomic_state *state = old_bridge_state->base.state;
+	struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);
+	struct drm_connector_state *conn_state;
+	struct drm_connector *connector;
+	int ret;
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		drm_err(bridge->dev, "Failed to enable lvds peripheral clk\n");
+		return;
+	}
+
+	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
+	if (!connector)
+		return;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (!conn_state)
+		return;
+
+	lvds_config_mode(lvds);
+
+	/* Set Data Mapping */
+	lvds_config_data_mapping(lvds);
+
+	/* Turn the output on. */
+	lvds_set(lvds, LVDS_CR, CR_LVDSEN);
+
+	if (lvds->panel) {
+		drm_panel_prepare(lvds->panel);
+		drm_panel_enable(lvds->panel);
+	}
+}
+
+static void lvds_atomic_disable(struct drm_bridge *bridge,
+				struct drm_bridge_state *old_bridge_state)
+{
+	struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);
+
+	if (lvds->panel) {
+		drm_panel_disable(lvds->panel);
+		drm_panel_unprepare(lvds->panel);
+	}
+
+	/* Disable LVDS module */
+	lvds_clear(lvds, LVDS_CR, CR_LVDSEN);
+
+	clk_disable_unprepare(lvds->pclk);
+}
+
+static const struct drm_bridge_funcs lvds_bridge_funcs = {
+	.attach = lvds_attach,
+	.atomic_enable = lvds_atomic_enable,
+	.atomic_disable = lvds_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,
+};
+
+static int lvds_probe(struct platform_device *pdev)
+{
+	struct device_node *port1, *port2, *remote;
+	struct device *dev = &pdev->dev;
+	struct reset_control *rstc;
+	struct stm_lvds *lvds;
+	int ret, dual_link;
+
+	dev_dbg(dev, "Probing LVDS driver...\n");
+
+	lvds = devm_kzalloc(dev, sizeof(*lvds), GFP_KERNEL);
+	if (!lvds)
+		return -ENOMEM;
+
+	lvds->dev = dev;
+
+	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0,
+					  &lvds->panel, &lvds->next_bridge);
+	if (ret) {
+		dev_err_probe(dev, ret, "Panel not found\n");
+		return ret;
+	}
+
+	lvds->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(lvds->base)) {
+		ret = PTR_ERR(lvds->base);
+		dev_err(dev, "Unable to get regs %d\n", ret);
+		return ret;
+	}
+
+	lvds->pclk = devm_clk_get(dev, "pclk");
+	if (IS_ERR(lvds->pclk)) {
+		ret = PTR_ERR(lvds->pclk);
+		dev_err(dev, "Unable to get peripheral clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		dev_err(dev, "%s: Failed to enable peripheral clk\n", __func__);
+		return ret;
+	}
+
+	rstc = devm_reset_control_get_exclusive(dev, NULL);
+
+	if (IS_ERR(rstc)) {
+		ret = PTR_ERR(rstc);
+		goto err_lvds_probe;
+	}
+
+	reset_control_assert(rstc);
+	usleep_range(10, 20);
+	reset_control_deassert(rstc);
+
+	port1 = of_graph_get_port_by_id(dev->of_node, 1);
+	port2 = of_graph_get_port_by_id(dev->of_node, 2);
+	dual_link = drm_of_lvds_get_dual_link_pixel_order(port1, port2);
+
+	switch (dual_link) {
+	case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
+		lvds->link_type = LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
+		lvds->primary = &lvds_phy_16ff_primary;
+		lvds->secondary = &lvds_phy_16ff_secondary;
+		break;
+	case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
+		lvds->link_type = LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
+		lvds->primary = &lvds_phy_16ff_primary;
+		lvds->secondary = &lvds_phy_16ff_secondary;
+		break;
+	case -EINVAL:
+		/*
+		 * drm_of_lvds_get_dual_pixel_order returns 4 possible values.
+		 * In the case where the returned value is an error, it can be
+		 * either ENODEV or EINVAL. Seeing the structure of this
+		 * function, EINVAL means that either port1 or port2 is not
+		 * present in the device tree.
+		 * In that case, the lvds panel can be a single link panel, or
+		 * there is a semantical error in the device tree code.
+		 */
+		remote = of_get_next_available_child(port1, NULL);
+		if (remote) {
+			if (of_graph_get_remote_endpoint(remote)) {
+				lvds->link_type = LVDS_SINGLE_LINK_PRIMARY;
+				lvds->primary = &lvds_phy_16ff_primary;
+				lvds->secondary = NULL;
+			} else {
+				ret = -EINVAL;
+			}
+
+			of_node_put(remote);
+		}
+
+		remote = of_get_next_available_child(port2, NULL);
+		if (remote) {
+			if (of_graph_get_remote_endpoint(remote)) {
+				lvds->link_type = LVDS_SINGLE_LINK_SECONDARY;
+				lvds->primary = NULL;
+				lvds->secondary = &lvds_phy_16ff_secondary;
+			} else {
+				ret = (ret == -EINVAL) ? -EINVAL : 0;
+			}
+
+			of_node_put(remote);
+		}
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_lvds_probe;
+	}
+	of_node_put(port1);
+	of_node_put(port2);
+
+	lvds->pllref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(lvds->pllref_clk)) {
+		ret = PTR_ERR(lvds->pllref_clk);
+		dev_err(dev, "Unable to get reference clock: %d\n", ret);
+		goto err_lvds_probe;
+	}
+
+	ret = lvds_pixel_clk_register(lvds);
+	if (ret) {
+		dev_err(dev, "Failed to register LVDS pixel clock: %d\n", ret);
+		goto err_lvds_probe;
+	}
+
+	lvds->lvds_bridge.funcs = &lvds_bridge_funcs;
+	lvds->lvds_bridge.of_node = dev->of_node;
+	lvds->hw_version = lvds_read(lvds, LVDS_VERR);
+
+	dev_info(dev, "version 0x%02x initialized\n", lvds->hw_version);
+
+	drm_bridge_add(&lvds->lvds_bridge);
+
+	platform_set_drvdata(pdev, lvds);
+
+	clk_disable_unprepare(lvds->pclk);
+
+	return 0;
+
+err_lvds_probe:
+	clk_disable_unprepare(lvds->pclk);
+
+	return ret;
+}
+
+static int lvds_remove(struct platform_device *pdev)
+{
+	struct stm_lvds *lvds = platform_get_drvdata(pdev);
+
+	lvds_pixel_clk_unregister(lvds);
+
+	drm_bridge_remove(&lvds->lvds_bridge);
+
+	return 0;
+}
+
+static const struct of_device_id lvds_dt_ids[] = {
+	{
+		.compatible = "st,stm32-lvds",
+		.data = NULL
+	},
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, lvds_dt_ids);
+
+static struct platform_driver lvds_platform_driver = {
+	.probe = lvds_probe,
+	.remove = lvds_remove,
+	.driver = {
+		.name = "stm32-display-lvds",
+		.owner = THIS_MODULE,
+		.of_match_table = lvds_dt_ids,
+	},
+};
+
+module_platform_driver(lvds_platform_driver);
+
+MODULE_AUTHOR("Rapha?l Gallais-Pou <raphael.gallais-pou at foss.st.com>");
+MODULE_AUTHOR("Philippe Cornu <philippe.cornu at foss.st.com>");
+MODULE_AUTHOR("Yannick Fertre <yannick.fertre at foss.st.com>");
+MODULE_DESCRIPTION("STMicroelectronics LVDS Display Interface Transmitter DRM driver");
+MODULE_LICENSE("GPL");

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Tue Feb  6 03:33:16 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Tue, 6 Feb 2024 12:33:16 +0100
Subject: [PATCH v4 1/3] dt-bindings: display: add STM32 LVDS device
In-Reply-To: <20240206-lvds-v4-0-98d5f9af399d@foss.st.com>
References: <20240206-lvds-v4-0-98d5f9af399d@foss.st.com>
Message-ID: <20240206-lvds-v4-1-98d5f9af399d@foss.st.com>

Add "st,stm32mp25-lvds" compatible.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Depends on: "dt-bindings: stm32: add clocks and reset binding for
	    stm32mp25 platform" by Gabriel Fernandez

Changes in v4:
	- Align filename to compatible
	- Fix compatible in the example
	- Remove redundant word in the subject

Changes in v3:
	- Clarify commit dependency
	- Fix includes in the example
	- Fix YAML
	- Add "clock-cells" description
	- s/regroups/is composed of/
	- Changed compatible to show SoC specificity

Changes in v2:
	- Switch compatible and clock-cells related areas
	- Remove faulty #include in the example.
	- Add entry in MAINTAINERS
---
 .../bindings/display/st,stm32mp25-lvds.yaml        | 119 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 2 files changed, 120 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml b/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
new file mode 100644
index 000000000000..6736f93256b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/st,stm32mp25-lvds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32 LVDS Display Interface Transmitter
+
+maintainers:
+  - Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
+  - Yannick Fertre <yannick.fertre at foss.st.com>
+
+description: |
+  The STMicroelectronics STM32 LVDS Display Interface Transmitter handles the
+  LVDS protocol: it maps the pixels received from the upstream Pixel-DMA (LTDC)
+  onto the LVDS PHY.
+
+  It is composed of three sub blocks:
+    - LVDS host: handles the LVDS protocol (FPD / OpenLDI) and maps its input
+      pixels onto the data lanes of the PHY
+    - LVDS PHY: parallelize the data and drives the LVDS data lanes
+    - LVDS wrapper: handles top-level settings
+
+  The LVDS controller driver supports the following high-level features:
+    - FDP-Link-I and OpenLDI (v0.95) protocols
+    - Single-Link or Dual-Link operation
+    - Single-Display or Double-Display (with the same content duplicated on both)
+    - Flexible Bit-Mapping, including JEIDA and VESA
+    - RGB888 or RGB666 output
+    - Synchronous design, with one input pixel per clock cycle
+
+properties:
+  compatible:
+    const: st,stm32mp25-lvds
+
+  "#clock-cells":
+    const: 0
+    description:
+      Provides the internal LVDS PHY clock to the framework.
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: APB peripheral clock
+      - description: Reference clock for the internal PLL
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: ref
+
+  resets:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          LVDS input port node, connected to the LTDC RGB output port.
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          LVDS output port node, connected to a panel or bridge input port.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+    lvds: lvds at 48060000 {
+        compatible = "st,stm32mp25-lvds";
+        reg = <0x48060000 0x2000>;
+        #clock-cells = <0>;
+        clocks = <&rcc CK_BUS_LVDS>, <&rcc CK_KER_LVDSPHY>;
+        clock-names = "pclk", "ref";
+        resets = <&rcc LVDS_R>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+                lvds_in: endpoint {
+                   remote-endpoint = <&ltdc_ep1_out>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+                lvds_out0: endpoint {
+                   remote-endpoint = <&lvds_panel_in>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 59b3da17debc..1736b243d7d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7231,6 +7231,7 @@ L:	dri-devel at lists.freedesktop.org
 S:	Maintained
 T:	git git://anongit.freedesktop.org/drm/drm-misc
 F:	Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml
+F:	Documentation/devicetree/bindings/display/st,stm32-lvds.yaml
 F:	drivers/gpu/drm/stm
 
 DRM DRIVERS FOR TI KEYSTONE

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Tue Feb  6 03:45:33 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Tue, 6 Feb 2024 12:45:33 +0100
Subject: [PATCH v5 0/3] Introduce STM32 LVDS driver
Message-ID: <20240206-lvds-v5-0-bd16797b0f09@foss.st.com>

This serie introduces a new DRM bridge driver for STM32MP257 platforms
based on Arm Cortex-35. It also adds an instance in the device-tree and
handle the inclusion of the driver within the DRM framework. First patch
adds a new panel compatible in the panel-lvds driver, which is used by
default on the STM32MP257.

Changes in v5:
	- Fixed path in MAINTAINERS
	- Fixed compatible in driver

Changes in v4:
	- Align dt-bindings filename and compatible
	- Remove redundant word in [1/6] subject
	- Fix example on typo
	- Some minor fixes on YAML syntax
	- Explicitly include linux/platform_device.h
	- Drop device-tree related patch after internal discussions
	- Rebase on latest drm-misc-next

Changes in v3:
	- Changed the compatible to show SoC specificity
	- Fixed includes in dt-binding example
	- Added "#clock-cells" description in dt-binding example
	- Some minor fixes on typo

Changes in v2:
	- Dropped [1/8] because already merged
	- Dropped [4/8] since not mandatory for this serie
	- [1/6]: Switch compatible and clock-cells related areas
	- [1/6]: Remove faulty #include in the example.
	- [1/6]: Add missing entry in MAINTAINERS
	- [2/6]: Removed CamelCase macros
	- [2/6]: Removed hard to read debug log
	- [3/6]: Fixed my address
	- [3/6]: Fixed smatch warning
	- [5/6]: Move changes to stm32mp255.dtsi

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Raphael Gallais-Pou (3):
      dt-bindings: display: add STM32 LVDS device
      drm/stm: lvds: add new STM32 LVDS Display Interface Transmitter driver
      drm/stm: ltdc: add lvds pixel clock

 .../bindings/display/st,stm32mp25-lvds.yaml        |  119 ++
 MAINTAINERS                                        |    1 +
 drivers/gpu/drm/stm/Kconfig                        |   11 +
 drivers/gpu/drm/stm/Makefile                       |    2 +
 drivers/gpu/drm/stm/ltdc.c                         |   19 +
 drivers/gpu/drm/stm/ltdc.h                         |    1 +
 drivers/gpu/drm/stm/lvds.c                         | 1226 ++++++++++++++++++++
 7 files changed, 1379 insertions(+)
---
base-commit: bb3bc3eac316b7c388733e625cc2343131b69dee
change-id: 20240205-lvds-e084ec50e878

Best regards,
-- 
Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>



From raphael.gallais-pou at foss.st.com  Tue Feb  6 03:45:36 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Tue, 6 Feb 2024 12:45:36 +0100
Subject: [PATCH v5 3/3] drm/stm: ltdc: add lvds pixel clock
In-Reply-To: <20240206-lvds-v5-0-bd16797b0f09@foss.st.com>
References: <20240206-lvds-v5-0-bd16797b0f09@foss.st.com>
Message-ID: <20240206-lvds-v5-3-bd16797b0f09@foss.st.com>

The STM32MP25x display subsystem presents a mux which feeds the loopback
pixel clock of the current bridge in use into the LTDC. This mux is only
accessible through sysconfig registers which is not yet available in the
STM32MP25x common clock framework.

While waiting for a complete update of the clock framework, this would
allow to use the LVDS.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
---
Changes in v2:
	- Fixed my address
	- Fixed smatch warning
---
 drivers/gpu/drm/stm/ltdc.c | 19 +++++++++++++++++++
 drivers/gpu/drm/stm/ltdc.h |  1 +
 2 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 5576fdae4962..23011a8913bd 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -838,6 +838,12 @@ ltdc_crtc_mode_valid(struct drm_crtc *crtc,
 	int target_max = target + CLK_TOLERANCE_HZ;
 	int result;
 
+	if (ldev->lvds_clk) {
+		result = clk_round_rate(ldev->lvds_clk, target);
+		DRM_DEBUG_DRIVER("lvds pixclk rate target %d, available %d\n",
+				 target, result);
+	}
+
 	result = clk_round_rate(ldev->pixel_clk, target);
 
 	DRM_DEBUG_DRIVER("clk rate target %d, available %d\n", target, result);
@@ -1896,6 +1902,8 @@ void ltdc_suspend(struct drm_device *ddev)
 
 	DRM_DEBUG_DRIVER("\n");
 	clk_disable_unprepare(ldev->pixel_clk);
+	if (ldev->lvds_clk)
+		clk_disable_unprepare(ldev->lvds_clk);
 }
 
 int ltdc_resume(struct drm_device *ddev)
@@ -1910,6 +1918,13 @@ int ltdc_resume(struct drm_device *ddev)
 		DRM_ERROR("failed to enable pixel clock (%d)\n", ret);
 		return ret;
 	}
+	if (ldev->lvds_clk) {
+		if (clk_prepare_enable(ldev->lvds_clk)) {
+			clk_disable_unprepare(ldev->pixel_clk);
+			DRM_ERROR("Unable to prepare lvds clock\n");
+			return -ENODEV;
+		}
+	}
 
 	return 0;
 }
@@ -1981,6 +1996,10 @@ int ltdc_load(struct drm_device *ddev)
 		}
 	}
 
+	ldev->lvds_clk = devm_clk_get(dev, "lvds");
+	if (IS_ERR(ldev->lvds_clk))
+		ldev->lvds_clk = NULL;
+
 	rstc = devm_reset_control_get_exclusive(dev, NULL);
 
 	mutex_init(&ldev->err_lock);
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index 9d488043ffdb..4a60ce5b610c 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -44,6 +44,7 @@ struct ltdc_device {
 	void __iomem *regs;
 	struct regmap *regmap;
 	struct clk *pixel_clk;	/* lcd pixel clock */
+	struct clk *lvds_clk;	/* lvds pixel clock */
 	struct mutex err_lock;	/* protecting error_status */
 	struct ltdc_caps caps;
 	u32 irq_status;

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Tue Feb  6 03:45:34 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Tue, 6 Feb 2024 12:45:34 +0100
Subject: [PATCH v5 1/3] dt-bindings: display: add STM32 LVDS device
In-Reply-To: <20240206-lvds-v5-0-bd16797b0f09@foss.st.com>
References: <20240206-lvds-v5-0-bd16797b0f09@foss.st.com>
Message-ID: <20240206-lvds-v5-1-bd16797b0f09@foss.st.com>

Add "st,stm32mp25-lvds" compatible.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Depends on: "dt-bindings: stm32: add clocks and reset binding for
	    stm32mp25 platform" by Gabriel Fernandez

Changes in v5:
	- Fixed path in MAINTAINERS

Changes in v4:
	- Align filename to compatible
	- Fix compatible in the example
	- Remove redundant word in the subject

Changes in v3:
	- Clarify commit dependency
	- Fix includes in the example
	- Fix YAML
	- Add "clock-cells" description
	- s/regroups/is composed of/
	- Changed compatible to show SoC specificity

Changes in v2:
	- Switch compatible and clock-cells related areas
	- Remove faulty #include in the example.
	- Add entry in MAINTAINERS
---
 .../bindings/display/st,stm32mp25-lvds.yaml        | 119 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 2 files changed, 120 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml b/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
new file mode 100644
index 000000000000..6736f93256b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/st,stm32mp25-lvds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32 LVDS Display Interface Transmitter
+
+maintainers:
+  - Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
+  - Yannick Fertre <yannick.fertre at foss.st.com>
+
+description: |
+  The STMicroelectronics STM32 LVDS Display Interface Transmitter handles the
+  LVDS protocol: it maps the pixels received from the upstream Pixel-DMA (LTDC)
+  onto the LVDS PHY.
+
+  It is composed of three sub blocks:
+    - LVDS host: handles the LVDS protocol (FPD / OpenLDI) and maps its input
+      pixels onto the data lanes of the PHY
+    - LVDS PHY: parallelize the data and drives the LVDS data lanes
+    - LVDS wrapper: handles top-level settings
+
+  The LVDS controller driver supports the following high-level features:
+    - FDP-Link-I and OpenLDI (v0.95) protocols
+    - Single-Link or Dual-Link operation
+    - Single-Display or Double-Display (with the same content duplicated on both)
+    - Flexible Bit-Mapping, including JEIDA and VESA
+    - RGB888 or RGB666 output
+    - Synchronous design, with one input pixel per clock cycle
+
+properties:
+  compatible:
+    const: st,stm32mp25-lvds
+
+  "#clock-cells":
+    const: 0
+    description:
+      Provides the internal LVDS PHY clock to the framework.
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: APB peripheral clock
+      - description: Reference clock for the internal PLL
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: ref
+
+  resets:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          LVDS input port node, connected to the LTDC RGB output port.
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          LVDS output port node, connected to a panel or bridge input port.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+    lvds: lvds at 48060000 {
+        compatible = "st,stm32mp25-lvds";
+        reg = <0x48060000 0x2000>;
+        #clock-cells = <0>;
+        clocks = <&rcc CK_BUS_LVDS>, <&rcc CK_KER_LVDSPHY>;
+        clock-names = "pclk", "ref";
+        resets = <&rcc LVDS_R>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+                lvds_in: endpoint {
+                   remote-endpoint = <&ltdc_ep1_out>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+                lvds_out0: endpoint {
+                   remote-endpoint = <&lvds_panel_in>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 59b3da17debc..225e8ae75eee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7231,6 +7231,7 @@ L:	dri-devel at lists.freedesktop.org
 S:	Maintained
 T:	git git://anongit.freedesktop.org/drm/drm-misc
 F:	Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml
+F:	Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
 F:	drivers/gpu/drm/stm
 
 DRM DRIVERS FOR TI KEYSTONE

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Tue Feb  6 03:45:35 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Tue, 6 Feb 2024 12:45:35 +0100
Subject: [PATCH v5 2/3] drm/stm: lvds: add new STM32 LVDS Display Interface
 Transmitter driver
In-Reply-To: <20240206-lvds-v5-0-bd16797b0f09@foss.st.com>
References: <20240206-lvds-v5-0-bd16797b0f09@foss.st.com>
Message-ID: <20240206-lvds-v5-2-bd16797b0f09@foss.st.com>

The Low-Voltage Differential Signaling (LVDS) Display Interface
Transmitter handles the LVDS protocol: it maps the pixels received from
the upstream Pixel-DMA LCD-TFT Display Controller (LTDC) onto the LVDS
PHY.

It is composed of three sub blocks:
	* LVDS host: handles the LVDS protocol (FPD / OpenLDI) and maps
	  its input pixels onto the data lanes of the PHY
	* LVDS PHY: parallelize the data and drives the LVDS data lanes
	* LVDS wrapper: handles top-level settings

The LVDS controller driver supports the following high-level features:
	* FDP-Link-I and OpenLDI (v0.95) protocols
	* Single-Link or Dual-Link operation
	* Single-Display or Double-Display (with the same content
	  duplicated on both)
	* Flexible Bit-Mapping, including JEIDA and VESA
	* RGB888 or RGB666 output
	* Synchronous design, with one input pixel per clock cycle

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Changes in v5:
	- Align compatible

Changes in v4:
	- Explicitly include linux/platform_device.h, dependency introduced by
	ef175b29a242 of: Stop circularly including of_device.h and of_platform.h

Changes in v3:
	- s/regroups/is composed of/ in commit log
	- Change the compatible to show SoC specificity

Changes in v2:
	- Fixed Camel Case macros
	- Removed debug log
---
 drivers/gpu/drm/stm/Kconfig  |   11 +
 drivers/gpu/drm/stm/Makefile |    2 +
 drivers/gpu/drm/stm/lvds.c   | 1226 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1239 insertions(+)

diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig
index fa49cde43bb2..9627814d027c 100644
--- a/drivers/gpu/drm/stm/Kconfig
+++ b/drivers/gpu/drm/stm/Kconfig
@@ -20,3 +20,14 @@ config DRM_STM_DSI
 	select DRM_DW_MIPI_DSI
 	help
 	  Choose this option for MIPI DSI support on STMicroelectronics SoC.
+
+config DRM_STM_LVDS
+	tristate "STMicroelectronics LVDS Display Interface Transmitter DRM driver"
+	depends on DRM_STM
+	help
+	  Enable support for LVDS encoders on STMicroelectronics SoC.
+	  The STM LVDS is a bridge which serialize pixel stream onto
+	  a LVDS protocol.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called lvds.
diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile
index 4df5caf01f35..ad740d6175a6 100644
--- a/drivers/gpu/drm/stm/Makefile
+++ b/drivers/gpu/drm/stm/Makefile
@@ -5,4 +5,6 @@ stm-drm-y := \
 
 obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o
 
+obj-$(CONFIG_DRM_STM_LVDS) += lvds.o
+
 obj-$(CONFIG_DRM_STM) += stm-drm.o
diff --git a/drivers/gpu/drm/stm/lvds.c b/drivers/gpu/drm/stm/lvds.c
new file mode 100644
index 000000000000..4616544cb886
--- /dev/null
+++ b/drivers/gpu/drm/stm/lvds.c
@@ -0,0 +1,1226 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Author(s): Rapha?l GALLAIS-POU <raphael.gallais-pou at foss.st.com> for STMicroelectronics.
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_device.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/media-bus-format.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+/* LVDS Host registers */
+#define LVDS_CR		0x0000  /* configuration register */
+#define LVDS_DMLCR0	0x0004  /* data mapping lsb configuration register 0 */
+#define LVDS_DMMCR0	0x0008  /* data mapping msb configuration register 0 */
+#define LVDS_DMLCR1	0x000C  /* data mapping lsb configuration register 1 */
+#define LVDS_DMMCR1	0x0010  /* data mapping msb configuration register 1 */
+#define LVDS_DMLCR2	0x0014  /* data mapping lsb configuration register 2 */
+#define LVDS_DMMCR2	0x0018  /* data mapping msb configuration register 2 */
+#define LVDS_DMLCR3	0x001C  /* data mapping lsb configuration register 3 */
+#define LVDS_DMMCR3	0x0020  /* data mapping msb configuration register 3 */
+#define LVDS_DMLCR4	0x0024  /* data mapping lsb configuration register 4 */
+#define LVDS_DMMCR4	0x0028  /* data mapping msb configuration register 4 */
+#define LVDS_CDL1CR	0x002C  /* channel distrib link 1 configuration register */
+#define LVDS_CDL2CR	0x0030  /* channel distrib link 2 configuration register */
+
+#define CDL1CR_DEFAULT	0x04321 /* Default value for CDL1CR */
+#define CDL2CR_DEFAULT	0x59876 /* Default value for CDL2CR */
+
+#define LVDS_DMLCR(bit)	(LVDS_DMLCR0 + 0x8 * (bit))
+#define LVDS_DMMCR(bit)	(LVDS_DMMCR0 + 0x8 * (bit))
+
+/* LVDS Wrapper registers */
+#define LVDS_WCLKCR	0x11B0  /* Wrapper clock control register */
+
+#define LVDS_HWCFGR	0x1FF0  /* HW configuration register	*/
+#define LVDS_VERR	0x1FF4  /* Version register	*/
+#define LVDS_IPIDR	0x1FF8  /* Identification register	*/
+#define LVDS_SIDR	0x1FFC  /* Size Identification register	*/
+
+/* Bitfield description */
+#define CR_LVDSEN	BIT(0)  /* LVDS PHY Enable */
+#define CR_HSPOL	BIT(1)  /* Horizontal Synchronization Polarity */
+#define CR_VSPOL	BIT(2)  /* Vertical Synchronization Polarity */
+#define CR_DEPOL	BIT(3)  /* Data Enable Polarity */
+#define CR_CI		BIT(4)  /* Control Internal (software controlled bit) */
+#define CR_LKMOD	BIT(5)  /* Link Mode, for both Links */
+#define CR_LKPHA	BIT(6)  /* Link Phase, for both Links */
+#define CR_LK1POL	GENMASK(20, 16)  /* Link-1 output Polarity */
+#define CR_LK2POL	GENMASK(25, 21)  /* Link-2 output Polarity */
+
+#define DMMCR_MAP0	GENMASK(4, 0) /* Mapping for bit 0 of datalane x */
+#define DMMCR_MAP1	GENMASK(9, 5) /* Mapping for bit 1 of datalane x */
+#define DMMCR_MAP2	GENMASK(14, 10) /* Mapping for bit 2 of datalane x */
+#define DMMCR_MAP3	GENMASK(19, 15) /* Mapping for bit 3 of datalane x */
+#define DMLCR_MAP4	GENMASK(4, 0) /* Mapping for bit 4 of datalane x */
+#define DMLCR_MAP5	GENMASK(9, 5) /* Mapping for bit 5 of datalane x */
+#define DMLCR_MAP6	GENMASK(14, 10) /* Mapping for bit 6 of datalane x */
+
+#define CDLCR_DISTR0	GENMASK(3, 0) /* Channel distribution for lane 0 */
+#define CDLCR_DISTR1	GENMASK(7, 4) /* Channel distribution for lane 1 */
+#define CDLCR_DISTR2	GENMASK(11, 8) /* Channel distribution for lane 2 */
+#define CDLCR_DISTR3	GENMASK(15, 12) /* Channel distribution for lane 3 */
+#define CDLCR_DISTR4	GENMASK(19, 16) /* Channel distribution for lane 4 */
+
+#define PHY_GCR_BIT_CLK_OUT	BIT(0)  /* BIT clock enable */
+#define PHY_GCR_LS_CLK_OUT	BIT(4)  /* LS clock enable */
+#define PHY_GCR_DP_CLK_OUT	BIT(8)  /* DP clock enable */
+#define PHY_GCR_RSTZ		BIT(24) /* LVDS PHY digital reset */
+#define PHY_GCR_DIV_RSTN	BIT(25) /* Output divider reset */
+#define PHY_SCR_TX_EN		BIT(16) /* Transmission mode enable */
+/* Current mode driver enable */
+#define PHY_CMCR_CM_EN_DL	(BIT(28) | BIT(20) | BIT(12) | BIT(4))
+#define PHY_CMCR_CM_EN_DL4	BIT(4)
+/* Bias enable */
+#define PHY_BCR1_EN_BIAS_DL	(BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0))
+#define PHY_BCR2_BIAS_EN	BIT(28)
+/* Voltage mode driver enable */
+#define PHY_BCR3_VM_EN_DL	(BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0))
+#define PHY_DCR_POWER_OK	BIT(12)
+#define PHY_CFGCR_EN_DIG_DL	GENMASK(4, 0) /* LVDS PHY digital lane enable */
+#define PHY_PLLCR1_PLL_EN	BIT(0) /* LVDS PHY PLL enable */
+#define PHY_PLLCR1_EN_SD	BIT(1) /* LVDS PHY PLL sigma-delta signal enable */
+#define PHY_PLLCR1_EN_TWG	BIT(2) /* LVDS PHY PLL triangular wave generator enable */
+#define PHY_PLLCR1_DIV_EN	BIT(8) /* LVDS PHY PLL dividers enable */
+#define PHY_PLLCR2_NDIV		GENMASK(25, 16) /* NDIV mask value */
+#define PHY_PLLCR2_BDIV		GENMASK(9, 0)   /* BDIV mask value */
+#define PHY_PLLSR_PLL_LOCK	BIT(0) /* LVDS PHY PLL lock status */
+#define PHY_PLLSDCR1_MDIV	GENMASK(9, 0)   /* MDIV mask value */
+#define PHY_PLLTESTCR_TDIV	GENMASK(25, 16) /* TDIV mask value */
+#define PHY_PLLTESTCR_CLK_EN	BIT(0) /* Test clock enable */
+#define PHY_PLLTESTCR_EN	BIT(8) /* Test divider output enable */
+
+#define WCLKCR_SECND_CLKPIX_SEL	BIT(0) /* Pixel clock selection */
+#define WCLKCR_SRCSEL		BIT(8) /* Source selection for the pixel clock */
+
+/* Sleep & timeout for pll lock/unlock */
+#define SLEEP_US	1000
+#define TIMEOUT_US	200000
+
+/*
+ * The link phase defines whether an ODD pixel is carried over together with
+ * the next EVEN pixel or together with the previous EVEN pixel.
+ *
+ * LVDS_DUAL_LINK_EVEN_ODD_PIXELS (LKPHA = 0)
+ *
+ * ,--------.  ,--------.  ,--------.  ,--------.  ,---------.
+ * | ODD  LK \/ PIXEL  3 \/ PIXEL  1 \/ PIXEL' 1 \/ PIXEL' 3 |
+ * | EVEN LK /\ PIXEL  2 /\ PIXEL' 0 /\ PIXEL' 2 /\ PIXEL' 4 |
+ * `--------'  `--------'  `--------'  `--------'  `---------'
+ *
+ * LVDS_DUAL_LINK_ODD_EVEN_PIXELS (LKPHA = 1)
+ *
+ * ,--------.  ,--------.  ,--------.  ,--------.  ,---------.
+ * | ODD  LK \/ PIXEL  3 \/ PIXEL  1 \/ PIXEL' 1 \/ PIXEL' 3 |
+ * | EVEN LK /\ PIXEL  4 /\ PIXEL  2 /\ PIXEL' 0 /\ PIXEL' 2 |
+ * `--------'  `--------'  `--------'  `--------'  `---------'
+ *
+ */
+enum lvds_link_type {
+	LVDS_SINGLE_LINK_PRIMARY = 0,
+	LVDS_SINGLE_LINK_SECONDARY,
+	LVDS_DUAL_LINK_EVEN_ODD_PIXELS,
+	LVDS_DUAL_LINK_ODD_EVEN_PIXELS,
+};
+
+enum lvds_pixel {
+	PIX_R_0 = 0,
+	PIX_R_1,
+	PIX_R_2,
+	PIX_R_3,
+	PIX_R_4,
+	PIX_R_5,
+	PIX_R_6,
+	PIX_R_7,
+	PIX_G_0,
+	PIX_G_1,
+	PIX_G_2,
+	PIX_G_3,
+	PIX_G_4,
+	PIX_G_5,
+	PIX_G_6,
+	PIX_G_7,
+	PIX_B_0,
+	PIX_B_1,
+	PIX_B_2,
+	PIX_B_3,
+	PIX_B_4,
+	PIX_B_5,
+	PIX_B_6,
+	PIX_B_7,
+	PIX_H_S,
+	PIX_V_S,
+	PIX_D_E,
+	PIX_C_E,
+	PIX_C_I,
+	PIX_TOG,
+	PIX_ONE,
+	PIX_ZER,
+};
+
+struct phy_reg_offsets {
+	u32 GCR;	/* Global Control Register	*/
+	u32 CMCR1;    /* Current Mode Control Register 1 */
+	u32 CMCR2;    /* Current Mode Control Register 2 */
+	u32 SCR;      /* Serial Control Register	*/
+	u32 BCR1;     /* Bias Control Register 1	*/
+	u32 BCR2;     /* Bias Control Register 2	*/
+	u32 BCR3;     /* Bias Control Register 3	*/
+	u32 MPLCR;    /* Monitor PLL Lock Control Register */
+	u32 DCR;      /* Debug Control Register	*/
+	u32 SSR1;     /* Spare Status Register 1	*/
+	u32 CFGCR;    /* Configuration Control Register */
+	u32 PLLCR1;   /* PLL_MODE 1 Control Register	*/
+	u32 PLLCR2;   /* PLL_MODE 2 Control Register	*/
+	u32 PLLSR;    /* PLL Status Register	*/
+	u32 PLLSDCR1; /* PLL_SD_1 Control Register	*/
+	u32 PLLSDCR2; /* PLL_SD_2 Control Register	*/
+	u32 PLLTWGCR1;/* PLL_TWG_1 Control Register	*/
+	u32 PLLTWGCR2;/* PLL_TWG_2 Control Register	*/
+	u32 PLLCPCR;  /* PLL_CP Control Register	*/
+	u32 PLLTESTCR;/* PLL_TEST Control Register	*/
+};
+
+struct lvds_phy_info {
+	u32 base;
+	struct phy_reg_offsets ofs;
+};
+
+static struct lvds_phy_info lvds_phy_16ff_primary = {
+	.base = 0x1000,
+	.ofs = {
+		.GCR = 0x0,
+		.CMCR1 = 0xC,
+		.CMCR2 = 0x10,
+		.SCR = 0x20,
+		.BCR1 = 0x2C,
+		.BCR2 = 0x30,
+		.BCR3 = 0x34,
+		.MPLCR = 0x64,
+		.DCR = 0x84,
+		.SSR1 = 0x88,
+		.CFGCR = 0xA0,
+		.PLLCR1 = 0xC0,
+		.PLLCR2 = 0xC4,
+		.PLLSR = 0xC8,
+		.PLLSDCR1 = 0xCC,
+		.PLLSDCR2 = 0xD0,
+		.PLLTWGCR1 = 0xD4,
+		.PLLTWGCR2 = 0xD8,
+		.PLLCPCR = 0xE0,
+		.PLLTESTCR = 0xE8,
+	}
+};
+
+static struct lvds_phy_info lvds_phy_16ff_secondary = {
+	.base = 0x1100,
+	.ofs = {
+		.GCR = 0x0,
+		.CMCR1 = 0xC,
+		.CMCR2 = 0x10,
+		.SCR = 0x20,
+		.BCR1 = 0x2C,
+		.BCR2 = 0x30,
+		.BCR3 = 0x34,
+		.MPLCR = 0x64,
+		.DCR = 0x84,
+		.SSR1 = 0x88,
+		.CFGCR = 0xA0,
+		.PLLCR1 = 0xC0,
+		.PLLCR2 = 0xC4,
+		.PLLSR = 0xC8,
+		.PLLSDCR1 = 0xCC,
+		.PLLSDCR2 = 0xD0,
+		.PLLTWGCR1 = 0xD4,
+		.PLLTWGCR2 = 0xD8,
+		.PLLCPCR = 0xE0,
+		.PLLTESTCR = 0xE8,
+	}
+};
+
+struct stm_lvds {
+	void __iomem *base;
+	struct device *dev;
+	struct clk *pclk;		/* APB peripheral clock */
+	struct clk *pllref_clk;		/* Reference clock for the internal PLL */
+	struct clk_hw lvds_ck_px;	/* Pixel clock */
+	u32 pixel_clock_rate;		/* Pixel clock rate */
+
+	struct lvds_phy_info *primary;
+	struct lvds_phy_info *secondary;
+
+	struct drm_bridge lvds_bridge;
+	struct drm_bridge *next_bridge;
+	struct drm_connector connector;
+	struct drm_encoder *encoder;
+	struct drm_panel *panel;
+
+	u32 hw_version;
+	u32 link_type;
+};
+
+#define bridge_to_stm_lvds(b) \
+	container_of(b, struct stm_lvds, lvds_bridge)
+
+#define connector_to_stm_lvds(c) \
+	container_of(c, struct stm_lvds, connector)
+
+#define lvds_is_dual_link(lvds) \
+	({	\
+	typeof(lvds) __lvds = (lvds);	\
+	__lvds == LVDS_DUAL_LINK_EVEN_ODD_PIXELS ||	\
+	__lvds == LVDS_DUAL_LINK_ODD_EVEN_PIXELS;	\
+	})
+
+static inline void lvds_write(struct stm_lvds *lvds, u32 reg, u32 val)
+{
+	writel(val, lvds->base + reg);
+}
+
+static inline u32 lvds_read(struct stm_lvds *lvds, u32 reg)
+{
+	return readl(lvds->base + reg);
+}
+
+static inline void lvds_set(struct stm_lvds *lvds, u32 reg, u32 mask)
+{
+	lvds_write(lvds, reg, lvds_read(lvds, reg) | mask);
+}
+
+static inline void lvds_clear(struct stm_lvds *lvds, u32 reg, u32 mask)
+{
+	lvds_write(lvds, reg, lvds_read(lvds, reg) & ~mask);
+}
+
+/*
+ * Expected JEIDA-RGB888 data to be sent in LSB format
+ *	    bit6 ............................bit0
+ * CHAN0   {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE}
+ * CHAN1   {G2,  R7,  R6,   R5,   R4,   R3,  R2}
+ * CHAN2   {B3,  B2,  G7,   G6,   G5,   G4,  G3}
+ * CHAN3   {DE,  VS,  HS,   B7,   B6,   B5,  B4}
+ * CHAN4   {CE,  B1,  B0,   G1,   G0,   R1,  R0}
+ */
+enum lvds_pixel lvds_bitmap_jeida_rgb888[5][7] = {
+	{ PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE },
+	{ PIX_G_2, PIX_R_7, PIX_R_6, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2 },
+	{ PIX_B_3, PIX_B_2, PIX_G_7, PIX_G_6, PIX_G_5, PIX_G_4, PIX_G_3 },
+	{ PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_7, PIX_B_6, PIX_B_5, PIX_B_4 },
+	{ PIX_C_E, PIX_B_1, PIX_B_0, PIX_G_1, PIX_G_0, PIX_R_1, PIX_R_0 }
+};
+
+/*
+ * Expected VESA-RGB888 data to be sent in LSB format
+ *	    bit6 ............................bit0
+ * CHAN0   {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE}
+ * CHAN1   {G0,  R5,  R4,   R3,   R2,   R1,  R0}
+ * CHAN2   {B1,  B0,  G5,   G4,   G3,   G2,  G1}
+ * CHAN3   {DE,  VS,  HS,   B5,   B4,   B3,  B2}
+ * CHAN4   {CE,  B7,  B6,   G7,   G6,   R7,  R6}
+ */
+enum lvds_pixel lvds_bitmap_vesa_rgb888[5][7] = {
+	{ PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE },
+	{ PIX_G_0, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2, PIX_R_1, PIX_R_0 },
+	{ PIX_B_1, PIX_B_0, PIX_G_5, PIX_G_4, PIX_G_3, PIX_G_2, PIX_G_1 },
+	{ PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_5, PIX_B_4, PIX_B_3, PIX_B_2 },
+	{ PIX_C_E, PIX_B_7, PIX_B_6, PIX_G_7, PIX_G_6, PIX_R_7, PIX_R_6 }
+};
+
+/*
+ * Clocks and PHY related functions
+ */
+static int lvds_pll_enable(struct stm_lvds *lvds, struct lvds_phy_info *phy)
+{
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	u32 lvds_gcr;
+	int val, ret;
+
+	/*
+	 * PLL lock timing control for the monitor unmask after startup (pll_en)
+	 * Adjusted value so that the masking window is opened at start-up
+	 */
+	lvds_write(lvds, phy->base + phy->ofs.MPLCR, (0x200 - 0x160) << 16);
+
+	/* Enable bias */
+	lvds_write(lvds, phy->base + phy->ofs.BCR2, PHY_BCR2_BIAS_EN);
+
+	/* Enable DP, LS, BIT clock output */
+	lvds_gcr = PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT;
+	lvds_set(lvds, phy->base + phy->ofs.GCR, lvds_gcr);
+
+	/* Power up all output dividers */
+	lvds_set(lvds, phy->base + phy->ofs.PLLTESTCR, PHY_PLLTESTCR_EN);
+	lvds_set(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_DIV_EN);
+
+	/* Set PHY in serial transmission mode */
+	lvds_set(lvds, phy->base + phy->ofs.SCR, PHY_SCR_TX_EN);
+
+	/* Enable the LVDS PLL & wait for its lock */
+	lvds_set(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_PLL_EN);
+	ret = readl_poll_timeout_atomic(lvds->base + phy->base + phy->ofs.PLLSR,
+					val, val & PHY_PLLSR_PLL_LOCK,
+					SLEEP_US, TIMEOUT_US);
+	if (ret)
+		drm_err(drm, "!TIMEOUT! waiting PLL, let's continue\n");
+
+	/* WCLKCR_SECND_CLKPIX_SEL is for dual link */
+	lvds_write(lvds, LVDS_WCLKCR, WCLKCR_SECND_CLKPIX_SEL);
+
+	lvds_set(lvds, phy->ofs.PLLTESTCR, PHY_PLLTESTCR_CLK_EN);
+
+	return ret;
+}
+
+static int pll_get_clkout_khz(int clkin_khz, int bdiv, int mdiv, int ndiv)
+{
+	int divisor = ndiv * bdiv;
+
+	/* Prevents from division by 0 */
+	if (!divisor)
+		return 0;
+
+	return clkin_khz * mdiv / divisor;
+}
+
+#define TDIV	70
+#define NDIV_MIN	2
+#define NDIV_MAX	6
+#define BDIV_MIN	2
+#define BDIV_MAX	6
+#define MDIV_MIN	1
+#define MDIV_MAX	1023
+
+static int lvds_pll_get_params(struct stm_lvds *lvds,
+			       unsigned int clkin_khz, unsigned int clkout_khz,
+			       unsigned int *bdiv, unsigned int *mdiv, unsigned int *ndiv)
+{
+	int delta, best_delta; /* all in khz */
+	int i, o, n;
+
+	/* Early checks preventing division by 0 & odd results */
+	if (clkin_khz <= 0 || clkout_khz <= 0)
+		return -EINVAL;
+
+	best_delta = 1000000; /* big started value (1000000khz) */
+
+	for (i = NDIV_MIN; i <= NDIV_MAX; i++) {
+		for (o = BDIV_MIN; o <= BDIV_MAX; o++) {
+			n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz);
+			/* Check ndiv according to vco range */
+			if (n < MDIV_MIN || n > MDIV_MAX)
+				continue;
+			/* Check if new delta is better & saves parameters */
+			delta = pll_get_clkout_khz(clkin_khz, i, n, o) - clkout_khz;
+			if (delta < 0)
+				delta = -delta;
+			if (delta < best_delta) {
+				*ndiv = i;
+				*mdiv = n;
+				*bdiv = o;
+				best_delta = delta;
+			}
+			/* fast return in case of "perfect result" */
+			if (!delta)
+				return 0;
+		}
+	}
+
+	return 0;
+}
+
+static void lvds_pll_config(struct stm_lvds *lvds, struct lvds_phy_info *phy)
+{
+	unsigned int pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0;
+	struct clk_hw *hwclk;
+	int multiplier;
+
+	/*
+	 * The LVDS PHY includes a low power low jitter high performance and
+	 * highly configuration Phase Locked Loop supporting integer and
+	 * fractional multiplication ratios and Spread Spectrum Clocking.  In
+	 * integer mode, the only software supported feature for now, the PLL is
+	 * made of a pre-divider NDIV, a feedback multiplier MDIV, followed by
+	 * several post-dividers, each one with a specific application.
+	 *
+	 *          ,------.         ,-----.     ,-----.
+	 * Fref --> | NDIV | -Fpdf-> | PFD | --> | VCO | --------> Fvco
+	 *          `------'     ,-> |     |     `-----'  |
+	 *                       |   `-----'              |
+	 *                       |         ,------.       |
+	 *                       `-------- | MDIV | <-----'
+	 *                                 `------'
+	 *
+	 * From the output of the VCO, the clock can be optionally extracted on
+	 * the RCC clock observer, with a divider TDIV, for testing purpose, or
+	 * is passed through a programmable post-divider BDIV.  Finally, the
+	 * frequency can be divided further with two fixed dividers.
+	 *
+	 *                            ,--------.
+	 *                    ,-----> | DP div | ----------------> Fdp
+	 *          ,------.  |       `--------'
+	 * Fvco --> | BDIV | ------------------------------------> Fbit
+	 *      |   `------'    ,------.   |
+	 *      `-------------> | TDIV | --.---------------------> ClkObs
+	 *                      '------'   |    ,--------.
+	 *                                 `--> | LS div | ------> Fls
+	 *                                      '--------'
+	 *
+	 * The LS and DP clock dividers operate at a fixed ratio of 7 and 3.5
+	 * respectively with regards to fbit. LS divider converts the bit clock
+	 * to a pixel clock per lane per clock sample (Fls).  This is useful
+	 * when used to generate a dot clock for the display unit RGB output,
+	 * and DP divider is.
+	 */
+
+	hwclk = __clk_get_hw(lvds->pllref_clk);
+	if (!hwclk)
+		return;
+
+	pll_in_khz = clk_hw_get_rate(hwclk) / 1000;
+
+	if (lvds_is_dual_link(lvds->link_type))
+		multiplier = 2;
+	else
+		multiplier = 1;
+
+	lvds_pll_get_params(lvds, pll_in_khz,
+			    lvds->pixel_clock_rate * 7 / 1000 / multiplier,
+			    &bdiv, &mdiv, &ndiv);
+
+	/* Set BDIV, MDIV and NDIV */
+	lvds_write(lvds, phy->base + phy->ofs.PLLCR2, ndiv << 16);
+	lvds_set(lvds, phy->base + phy->ofs.PLLCR2, bdiv);
+	lvds_write(lvds, phy->base + phy->ofs.PLLSDCR1, mdiv);
+
+	/* Hardcode TDIV as dynamic values are not yet implemented */
+	lvds_write(lvds, phy->base + phy->ofs.PLLTESTCR, TDIV << 16);
+
+	/*
+	 * For now, PLL just needs to be in integer mode
+	 * Fractional and spread spectrum clocking are not yet implemented
+	 *
+	 * PLL integer mode:
+	 *	- PMRY_PLL_TWG_STEP = PMRY_PLL_SD_INT_RATIO
+	 *	- EN_TWG = 0
+	 *	- EN_SD = 0
+	 *	- DOWN_SPREAD = 0
+	 *
+	 * PLL fractional mode:
+	 *	- EN_TWG = 0
+	 *	- EN_SD = 1
+	 *	- DOWN_SPREAD = 0
+	 *
+	 * Spread Spectrum Clocking
+	 *	- EN_TWG = 1
+	 *	- EN_SD = 1
+	 */
+
+	/* Disable TWG and SD */
+	lvds_clear(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_EN_TWG | PHY_PLLCR1_EN_SD);
+
+	/* Power up bias and PLL dividers */
+	lvds_set(lvds, phy->base + phy->ofs.DCR, PHY_DCR_POWER_OK);
+	lvds_set(lvds, phy->base + phy->ofs.CMCR1, PHY_CMCR_CM_EN_DL);
+	lvds_set(lvds, phy->base + phy->ofs.CMCR2, PHY_CMCR_CM_EN_DL4);
+
+	/* Set up voltage mode */
+	lvds_set(lvds, phy->base + phy->ofs.PLLCPCR, 0x1);
+	lvds_set(lvds, phy->base + phy->ofs.BCR3, PHY_BCR3_VM_EN_DL);
+	lvds_set(lvds, phy->base + phy->ofs.BCR1, PHY_BCR1_EN_BIAS_DL);
+	/* Enable digital datalanes */
+	lvds_set(lvds, phy->base + phy->ofs.CFGCR, PHY_CFGCR_EN_DIG_DL);
+}
+
+static int lvds_pixel_clk_enable(struct clk_hw *hw)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	struct lvds_phy_info *phy;
+	int ret;
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		drm_err(drm, "Failed to enable lvds peripheral clk\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(lvds->pllref_clk);
+	if (ret) {
+		drm_err(drm, "Failed to enable lvds reference clk\n");
+		clk_disable_unprepare(lvds->pclk);
+		return ret;
+	}
+
+	/* In case we are operating in dual link the second PHY is set before the primary PHY. */
+	if (lvds->secondary) {
+		phy = lvds->secondary;
+
+		/* Release LVDS PHY from reset mode */
+		lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+		lvds_pll_config(lvds, phy);
+
+		ret = lvds_pll_enable(lvds, phy);
+		if (ret) {
+			drm_err(drm, "Failed to enable secondary PHY PLL: %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (lvds->primary) {
+		phy = lvds->primary;
+
+		/* Release LVDS PHY from reset mode */
+		lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+		lvds_pll_config(lvds, phy);
+
+		ret = lvds_pll_enable(lvds, phy);
+		if (ret) {
+			drm_err(drm, "Failed to enable primary PHY PLL: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static void lvds_pixel_clk_disable(struct clk_hw *hw)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+
+	/*
+	 * For each PHY:
+	 * Disable DP, LS, BIT clock outputs
+	 * Shutdown the PLL
+	 * Assert LVDS PHY in reset mode
+	 */
+
+	if (lvds->primary) {
+		lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR,
+			   (PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT));
+		lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR1,
+			   PHY_PLLCR1_PLL_EN);
+		lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR,
+			   PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+	}
+
+	if (lvds->secondary) {
+		lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR,
+			   (PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT));
+		lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.PLLCR1,
+			   PHY_PLLCR1_PLL_EN);
+		lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR,
+			   PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+	}
+
+	clk_disable_unprepare(lvds->pllref_clk);
+	clk_disable_unprepare(lvds->pclk);
+}
+
+static unsigned long lvds_pixel_clk_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	unsigned int pll_in_khz, bdiv, mdiv, ndiv;
+	int ret, multiplier, pll_out_khz;
+	u32 val;
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		drm_err(drm, "Failed to enable lvds peripheral clk\n");
+		return 0;
+	}
+
+	if (lvds_is_dual_link(lvds->link_type))
+		multiplier = 2;
+	else
+		multiplier = 1;
+
+	val = lvds_read(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR2);
+
+	ndiv = (val & PHY_PLLCR2_NDIV) >> 16;
+	bdiv = (val & PHY_PLLCR2_BDIV) >> 0;
+
+	mdiv = (unsigned int)lvds_read(lvds,
+				       lvds->primary->base + lvds->primary->ofs.PLLSDCR1);
+
+	pll_in_khz = (unsigned int)(parent_rate / 1000);
+
+	/* Compute values if not yet accessible */
+	if (val == 0 || mdiv == 0) {
+		lvds_pll_get_params(lvds, pll_in_khz,
+				    lvds->pixel_clock_rate * 7 / 1000 / multiplier,
+				    &bdiv, &mdiv, &ndiv);
+	}
+
+	pll_out_khz = pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv);
+	drm_dbg(drm, "ndiv %d , bdiv %d, mdiv %d, pll_out_khz %d\n",
+		ndiv, bdiv, mdiv, pll_out_khz);
+
+	/*
+	 * 1/7 because for each pixel in 1 lane there is 7 bits
+	 * We want pixclk, not bitclk
+	 */
+	lvds->pixel_clock_rate = pll_out_khz * 1000 * multiplier / 7;
+
+	clk_disable_unprepare(lvds->pclk);
+
+	return (unsigned long)lvds->pixel_clock_rate;
+}
+
+static long lvds_pixel_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *parent_rate)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+	unsigned int pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0;
+	const struct drm_connector *connector;
+	const struct drm_display_mode *mode;
+	int multiplier;
+
+	connector = &lvds->connector;
+	if (!connector)
+		return -EINVAL;
+
+	if (list_empty(&connector->modes)) {
+		drm_dbg(connector->dev, "connector: empty modes list\n");
+		return -EINVAL;
+	}
+
+	mode = list_first_entry(&connector->modes,
+				struct drm_display_mode, head);
+
+	pll_in_khz = (unsigned int)(*parent_rate / 1000);
+
+	if (lvds_is_dual_link(lvds->link_type))
+		multiplier = 2;
+	else
+		multiplier = 1;
+
+	lvds_pll_get_params(lvds, pll_in_khz, mode->clock * 7 / multiplier, &bdiv, &mdiv, &ndiv);
+
+	/*
+	 * 1/7 because for each pixel in 1 lane there is 7 bits
+	 * We want pixclk, not bitclk
+	 */
+	lvds->pixel_clock_rate = (unsigned long)pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv)
+					 * 1000 * multiplier / 7;
+
+	return lvds->pixel_clock_rate;
+}
+
+static const struct clk_ops lvds_pixel_clk_ops = {
+	.enable = lvds_pixel_clk_enable,
+	.disable = lvds_pixel_clk_disable,
+	.recalc_rate = lvds_pixel_clk_recalc_rate,
+	.round_rate = lvds_pixel_clk_round_rate,
+};
+
+static const struct clk_init_data clk_data = {
+	.name = "clk_pix_lvds",
+	.ops = &lvds_pixel_clk_ops,
+	.parent_names = (const char * []) {"ck_ker_lvdsphy"},
+	.num_parents = 1,
+	.flags = CLK_IGNORE_UNUSED,
+};
+
+static void lvds_pixel_clk_unregister(void *data)
+{
+	struct stm_lvds *lvds = data;
+
+	of_clk_del_provider(lvds->dev->of_node);
+	clk_hw_unregister(&lvds->lvds_ck_px);
+}
+
+static int lvds_pixel_clk_register(struct stm_lvds *lvds)
+{
+	struct device_node *node = lvds->dev->of_node;
+	int ret;
+
+	lvds->lvds_ck_px.init = &clk_data;
+
+	/* set the rate by default at 148500000 */
+	lvds->pixel_clock_rate = 148500000;
+
+	ret = clk_hw_register(lvds->dev, &lvds->lvds_ck_px);
+	if (ret)
+		return ret;
+
+	ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get,
+				     &lvds->lvds_ck_px);
+	if (ret)
+		clk_hw_unregister(&lvds->lvds_ck_px);
+
+	return ret;
+}
+
+/*
+ * Host configuration related
+ */
+static void lvds_config_data_mapping(struct stm_lvds *lvds)
+{
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	const struct drm_display_info *info;
+	enum lvds_pixel (*bitmap)[7];
+	u32 lvds_dmlcr, lvds_dmmcr;
+	int i;
+
+	info = &(&lvds->connector)->display_info;
+	if (!info->num_bus_formats || !info->bus_formats) {
+		drm_warn(drm, "No LVDS bus format reported\n");
+		return;
+	}
+
+	switch (info->bus_formats[0]) {
+	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* VESA-RGB666 */
+		drm_warn(drm, "Pixel format with data mapping not yet supported.\n");
+		return;
+	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* VESA-RGB888 */
+		bitmap = lvds_bitmap_vesa_rgb888;
+		break;
+	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* JEIDA-RGB888 */
+		bitmap = lvds_bitmap_jeida_rgb888;
+		break;
+	default:
+		drm_warn(drm, "Unsupported LVDS bus format 0x%04x\n", info->bus_formats[0]);
+		return;
+	}
+
+	/* Set bitmap for each lane */
+	for (i = 0; i < 5; i++) {
+		lvds_dmlcr = ((bitmap[i][0])
+			      + (bitmap[i][1] << 5)
+			      + (bitmap[i][2] << 10)
+			      + (bitmap[i][3] << 15));
+		lvds_dmmcr = ((bitmap[i][4])
+			      + (bitmap[i][5] << 5)
+			      + (bitmap[i][6] << 10));
+
+		lvds_write(lvds, LVDS_DMLCR(i), lvds_dmlcr);
+		lvds_write(lvds, LVDS_DMMCR(i), lvds_dmmcr);
+	}
+}
+
+static void lvds_config_mode(struct stm_lvds *lvds)
+{
+	u32 bus_flags, lvds_cr = 0, lvds_cdl1cr = 0, lvds_cdl2cr = 0;
+	const struct drm_display_mode *mode;
+	const struct drm_connector *connector;
+
+	connector = &lvds->connector;
+	if (!connector)
+		return;
+
+	if (list_empty(&connector->modes)) {
+		drm_dbg(connector->dev, "connector: empty modes list\n");
+		return;
+	}
+
+	bus_flags = connector->display_info.bus_flags;
+	mode = list_first_entry(&connector->modes,
+				struct drm_display_mode, head);
+
+	lvds_clear(lvds, LVDS_CR, CR_LKMOD);
+	lvds_clear(lvds, LVDS_CDL1CR, CDLCR_DISTR0 | CDLCR_DISTR1 | CDLCR_DISTR2 |
+				      CDLCR_DISTR3 | CDLCR_DISTR4);
+	lvds_clear(lvds, LVDS_CDL2CR, CDLCR_DISTR0 | CDLCR_DISTR1 | CDLCR_DISTR2 |
+				      CDLCR_DISTR3 | CDLCR_DISTR4);
+
+	/* Set channel distribution */
+	if (lvds->primary)
+		lvds_cdl1cr = CDL1CR_DEFAULT;
+
+	if (lvds->secondary) {
+		lvds_cr |= CR_LKMOD;
+		lvds_cdl2cr = CDL2CR_DEFAULT;
+	}
+
+	/* Set signal polarity */
+	if (bus_flags & DRM_BUS_FLAG_DE_LOW)
+		lvds_cr |= CR_DEPOL;
+
+	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+		lvds_cr |= CR_HSPOL;
+
+	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+		lvds_cr |= CR_VSPOL;
+
+	switch (lvds->link_type) {
+	case LVDS_DUAL_LINK_EVEN_ODD_PIXELS: /* LKPHA = 0 */
+		lvds_cr &= ~CR_LKPHA;
+		break;
+	case LVDS_DUAL_LINK_ODD_EVEN_PIXELS: /* LKPHA = 1 */
+		lvds_cr |= CR_LKPHA;
+		break;
+	default:
+		drm_notice(lvds->lvds_bridge.dev, "No phase precised, setting default\n");
+		lvds_cr &= ~CR_LKPHA;
+		break;
+	}
+
+	/* Write config to registers */
+	lvds_set(lvds, LVDS_CR, lvds_cr);
+	lvds_write(lvds, LVDS_CDL1CR, lvds_cdl1cr);
+	lvds_write(lvds, LVDS_CDL2CR, lvds_cdl2cr);
+}
+
+static int lvds_connector_get_modes(struct drm_connector *connector)
+{
+	struct stm_lvds *lvds = connector_to_stm_lvds(connector);
+
+	return drm_panel_get_modes(lvds->panel, connector);
+}
+
+static int lvds_connector_atomic_check(struct drm_connector *connector,
+				       struct drm_atomic_state *state)
+{
+	const struct drm_display_mode *panel_mode;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc_state *crtc_state;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (!conn_state)
+		return -EINVAL;
+
+	if (list_empty(&connector->modes)) {
+		drm_dbg(connector->dev, "connector: empty modes list\n");
+		return -EINVAL;
+	}
+
+	if (!conn_state->crtc)
+		return -EINVAL;
+
+	panel_mode = list_first_entry(&connector->modes,
+				      struct drm_display_mode, head);
+
+	/* We're not allowed to modify the resolution. */
+	crtc_state = drm_atomic_get_crtc_state(state, conn_state->crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
+	if (crtc_state->mode.hdisplay != panel_mode->hdisplay ||
+	    crtc_state->mode.vdisplay != panel_mode->vdisplay)
+		return -EINVAL;
+
+	/* The flat panel mode is fixed, just copy it to the adjusted mode. */
+	drm_mode_copy(&crtc_state->adjusted_mode, panel_mode);
+
+	return 0;
+}
+
+static const struct drm_connector_helper_funcs lvds_conn_helper_funcs = {
+	.get_modes = lvds_connector_get_modes,
+	.atomic_check = lvds_connector_atomic_check,
+};
+
+static const struct drm_connector_funcs lvds_conn_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 int lvds_attach(struct drm_bridge *bridge,
+		       enum drm_bridge_attach_flags flags)
+{
+	struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);
+	struct drm_connector *connector = &lvds->connector;
+	struct drm_encoder *encoder = bridge->encoder;
+	int ret;
+
+	if (!bridge->encoder) {
+		drm_err(bridge->dev, "Parent encoder object not found\n");
+		return -ENODEV;
+	}
+
+	/* Set the encoder type as caller does not know it */
+	bridge->encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
+
+	/* No cloning support */
+	bridge->encoder->possible_clones = 0;
+
+	/* If we have a next bridge just attach it. */
+	if (lvds->next_bridge)
+		return drm_bridge_attach(bridge->encoder, lvds->next_bridge,
+					 bridge, flags);
+
+	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
+		drm_err(bridge->dev, "Fix bridge driver to make connector optional!");
+		return -EINVAL;
+	}
+
+	/* Otherwise if we have a panel, create a connector. */
+	if (!lvds->panel)
+		return 0;
+
+	ret = drm_connector_init(bridge->dev, connector,
+				 &lvds_conn_funcs, DRM_MODE_CONNECTOR_LVDS);
+	if (ret < 0)
+		return ret;
+
+	drm_connector_helper_add(connector, &lvds_conn_helper_funcs);
+
+	ret = drm_connector_attach_encoder(connector, encoder);
+
+	return ret;
+}
+
+static void lvds_atomic_enable(struct drm_bridge *bridge,
+			       struct drm_bridge_state *old_bridge_state)
+{
+	struct drm_atomic_state *state = old_bridge_state->base.state;
+	struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);
+	struct drm_connector_state *conn_state;
+	struct drm_connector *connector;
+	int ret;
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		drm_err(bridge->dev, "Failed to enable lvds peripheral clk\n");
+		return;
+	}
+
+	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
+	if (!connector)
+		return;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (!conn_state)
+		return;
+
+	lvds_config_mode(lvds);
+
+	/* Set Data Mapping */
+	lvds_config_data_mapping(lvds);
+
+	/* Turn the output on. */
+	lvds_set(lvds, LVDS_CR, CR_LVDSEN);
+
+	if (lvds->panel) {
+		drm_panel_prepare(lvds->panel);
+		drm_panel_enable(lvds->panel);
+	}
+}
+
+static void lvds_atomic_disable(struct drm_bridge *bridge,
+				struct drm_bridge_state *old_bridge_state)
+{
+	struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);
+
+	if (lvds->panel) {
+		drm_panel_disable(lvds->panel);
+		drm_panel_unprepare(lvds->panel);
+	}
+
+	/* Disable LVDS module */
+	lvds_clear(lvds, LVDS_CR, CR_LVDSEN);
+
+	clk_disable_unprepare(lvds->pclk);
+}
+
+static const struct drm_bridge_funcs lvds_bridge_funcs = {
+	.attach = lvds_attach,
+	.atomic_enable = lvds_atomic_enable,
+	.atomic_disable = lvds_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,
+};
+
+static int lvds_probe(struct platform_device *pdev)
+{
+	struct device_node *port1, *port2, *remote;
+	struct device *dev = &pdev->dev;
+	struct reset_control *rstc;
+	struct stm_lvds *lvds;
+	int ret, dual_link;
+
+	dev_dbg(dev, "Probing LVDS driver...\n");
+
+	lvds = devm_kzalloc(dev, sizeof(*lvds), GFP_KERNEL);
+	if (!lvds)
+		return -ENOMEM;
+
+	lvds->dev = dev;
+
+	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0,
+					  &lvds->panel, &lvds->next_bridge);
+	if (ret) {
+		dev_err_probe(dev, ret, "Panel not found\n");
+		return ret;
+	}
+
+	lvds->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(lvds->base)) {
+		ret = PTR_ERR(lvds->base);
+		dev_err(dev, "Unable to get regs %d\n", ret);
+		return ret;
+	}
+
+	lvds->pclk = devm_clk_get(dev, "pclk");
+	if (IS_ERR(lvds->pclk)) {
+		ret = PTR_ERR(lvds->pclk);
+		dev_err(dev, "Unable to get peripheral clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		dev_err(dev, "%s: Failed to enable peripheral clk\n", __func__);
+		return ret;
+	}
+
+	rstc = devm_reset_control_get_exclusive(dev, NULL);
+
+	if (IS_ERR(rstc)) {
+		ret = PTR_ERR(rstc);
+		goto err_lvds_probe;
+	}
+
+	reset_control_assert(rstc);
+	usleep_range(10, 20);
+	reset_control_deassert(rstc);
+
+	port1 = of_graph_get_port_by_id(dev->of_node, 1);
+	port2 = of_graph_get_port_by_id(dev->of_node, 2);
+	dual_link = drm_of_lvds_get_dual_link_pixel_order(port1, port2);
+
+	switch (dual_link) {
+	case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
+		lvds->link_type = LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
+		lvds->primary = &lvds_phy_16ff_primary;
+		lvds->secondary = &lvds_phy_16ff_secondary;
+		break;
+	case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
+		lvds->link_type = LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
+		lvds->primary = &lvds_phy_16ff_primary;
+		lvds->secondary = &lvds_phy_16ff_secondary;
+		break;
+	case -EINVAL:
+		/*
+		 * drm_of_lvds_get_dual_pixel_order returns 4 possible values.
+		 * In the case where the returned value is an error, it can be
+		 * either ENODEV or EINVAL. Seeing the structure of this
+		 * function, EINVAL means that either port1 or port2 is not
+		 * present in the device tree.
+		 * In that case, the lvds panel can be a single link panel, or
+		 * there is a semantical error in the device tree code.
+		 */
+		remote = of_get_next_available_child(port1, NULL);
+		if (remote) {
+			if (of_graph_get_remote_endpoint(remote)) {
+				lvds->link_type = LVDS_SINGLE_LINK_PRIMARY;
+				lvds->primary = &lvds_phy_16ff_primary;
+				lvds->secondary = NULL;
+			} else {
+				ret = -EINVAL;
+			}
+
+			of_node_put(remote);
+		}
+
+		remote = of_get_next_available_child(port2, NULL);
+		if (remote) {
+			if (of_graph_get_remote_endpoint(remote)) {
+				lvds->link_type = LVDS_SINGLE_LINK_SECONDARY;
+				lvds->primary = NULL;
+				lvds->secondary = &lvds_phy_16ff_secondary;
+			} else {
+				ret = (ret == -EINVAL) ? -EINVAL : 0;
+			}
+
+			of_node_put(remote);
+		}
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_lvds_probe;
+	}
+	of_node_put(port1);
+	of_node_put(port2);
+
+	lvds->pllref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(lvds->pllref_clk)) {
+		ret = PTR_ERR(lvds->pllref_clk);
+		dev_err(dev, "Unable to get reference clock: %d\n", ret);
+		goto err_lvds_probe;
+	}
+
+	ret = lvds_pixel_clk_register(lvds);
+	if (ret) {
+		dev_err(dev, "Failed to register LVDS pixel clock: %d\n", ret);
+		goto err_lvds_probe;
+	}
+
+	lvds->lvds_bridge.funcs = &lvds_bridge_funcs;
+	lvds->lvds_bridge.of_node = dev->of_node;
+	lvds->hw_version = lvds_read(lvds, LVDS_VERR);
+
+	dev_info(dev, "version 0x%02x initialized\n", lvds->hw_version);
+
+	drm_bridge_add(&lvds->lvds_bridge);
+
+	platform_set_drvdata(pdev, lvds);
+
+	clk_disable_unprepare(lvds->pclk);
+
+	return 0;
+
+err_lvds_probe:
+	clk_disable_unprepare(lvds->pclk);
+
+	return ret;
+}
+
+static int lvds_remove(struct platform_device *pdev)
+{
+	struct stm_lvds *lvds = platform_get_drvdata(pdev);
+
+	lvds_pixel_clk_unregister(lvds);
+
+	drm_bridge_remove(&lvds->lvds_bridge);
+
+	return 0;
+}
+
+static const struct of_device_id lvds_dt_ids[] = {
+	{
+		.compatible = "st,stm32mp25-lvds",
+		.data = NULL
+	},
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, lvds_dt_ids);
+
+static struct platform_driver lvds_platform_driver = {
+	.probe = lvds_probe,
+	.remove = lvds_remove,
+	.driver = {
+		.name = "stm32-display-lvds",
+		.owner = THIS_MODULE,
+		.of_match_table = lvds_dt_ids,
+	},
+};
+
+module_platform_driver(lvds_platform_driver);
+
+MODULE_AUTHOR("Rapha?l Gallais-Pou <raphael.gallais-pou at foss.st.com>");
+MODULE_AUTHOR("Philippe Cornu <philippe.cornu at foss.st.com>");
+MODULE_AUTHOR("Yannick Fertre <yannick.fertre at foss.st.com>");
+MODULE_DESCRIPTION("STMicroelectronics LVDS Display Interface Transmitter DRM driver");
+MODULE_LICENSE("GPL");

-- 
2.25.1



From peter.griffin at linaro.org  Tue Feb  6 04:00:16 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 6 Feb 2024 12:00:16 +0000
Subject: [PATCH 4/4] spi: s3c64xx: add support for google,gs101-spi
In-Reply-To: <833b96e5-348f-4c5c-b157-c57c9a67e0f2@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
 <20240206085238.1208256-5-tudor.ambarus@linaro.org> <CADrjBPqaE9Mmbr+zkHOAadr3aLSu3GMjS4nPPd4VZY4s2DTznA@mail.gmail.com>
 <ZcISMLoB2ytoQs/0@finisterre.sirena.org.uk> <833b96e5-348f-4c5c-b157-c57c9a67e0f2@linaro.org>
Message-ID: <CADrjBPpF_RdB5fe9udOgxLKmdb7D0Gux+n0XxUtneuAawSjoaA@mail.gmail.com>

On Tue, 6 Feb 2024 at 11:19, Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
>
>
> On 2/6/24 11:04, Mark Brown wrote:
> > On Tue, Feb 06, 2024 at 10:12:30AM +0000, Peter Griffin wrote:
> >
> >> The patch ordering seems a bit off with this series..I believe it should be
> >> 1) dt-bindings patch (docs first)
> >> 2) Add the use_32bit_io flag / functionality
> >> 3) gs101 support (this patch) that uses the use_32bit_io functionality
> >
> > That's the ordering the series has?  There's a random cleanup patch
> > tacked on the front but that really ought to be separate anyway.
>
> I put the include <linux/types.h> patch first because I considered it a
> fix (driver is using u32) and because I need types.h in patch 3/4. Fixes
> first, then bindings, then driver.
>
> Was I wrong?

No my mistake, sorry for the noise. Gmail showed this driver change as
the first patch after the cover letter but the subject was hidden so
it wasn't obvious it was [4/4]


From krzysztof.kozlowski at linaro.org  Tue Feb  6 04:01:51 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 6 Feb 2024 13:01:51 +0100
Subject: [PATCH v5 0/3] Introduce STM32 LVDS driver
In-Reply-To: <20240206-lvds-v5-0-bd16797b0f09@foss.st.com>
References: <20240206-lvds-v5-0-bd16797b0f09@foss.st.com>
Message-ID: <f4bc2484-0e1f-4e5c-be36-c267539f3efc@linaro.org>

On 06/02/2024 12:45, Raphael Gallais-Pou wrote:
> This serie introduces a new DRM bridge driver for STM32MP257 platforms
> based on Arm Cortex-35. It also adds an instance in the device-tree and
> handle the inclusion of the driver within the DRM framework. First patch
> adds a new panel compatible in the panel-lvds driver, which is used by
> default on the STM32MP257.
> 
> Changes in v5:
> 	- Fixed path in MAINTAINERS
> 	- Fixed compatible in driver

One patchset per day. Allow people to actually review your code...

Best regards,
Krzysztof



From mihai.sain at microchip.com  Tue Feb  6 04:03:14 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 6 Feb 2024 14:03:14 +0200
Subject: [PATCH v3 0/8] Add power-supply properties for sdmmc nodes on Microchip boards
Message-ID: <20240206120322.88907-1-mihai.sain@microchip.com>

This patch series adds power-supply properties for sdmmc nodes on Microchip boards.

Changes in v3:
--------------

* Update the commit description for each board in order to wrap the line at max 75 columns.

Changes in v2:
--------------

* Update the commit description for each board.
* The goal is to keep the vqmmc at 3V3 in order to use the sd high-speed mode.

Mihai Sain (8):
  ARM: dts: microchip: sam9x60_curiosity: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sam9x60ek: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sama5d27_som1_ek: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sama5d27_wlsom1: Add power-supply property for sdmmc1 node
  ARM: dts: microchip: sama5d27_wlsom1_ek: Add power-supply property for sdmmc0 node
  ARM: dts: microchip: sama5d29_curiosity: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sama5d2_icp: Add power-supply property for sdmmc0 node
  ARM: dts: microchip: sama5d2_xplained: Add power-supply property for sdmmc0 node

-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb  6 04:03:15 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 6 Feb 2024 14:03:15 +0200
Subject: [PATCH v3 1/8] ARM: dts: microchip: sam9x60_curiosity: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240206120322.88907-1-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
Message-ID: <20240206120322.88907-2-mihai.sain@microchip.com>

The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
The sdmmc controller from SAM9X60 MPU doesn't support the
IO voltage signaling/switching required by the UHS sd-card.
In order to use the sd high-speed mode, keep vqmmc at 3V3.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
index c6fbdd29019f..457c54dde0b7 100644
--- a/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
+++ b/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
@@ -452,6 +452,8 @@ &sdmmc0 {
 	pinctrl-0 = <&pinctrl_sdmmc0_default &pinctrl_sdmmc0_cd>;
 	cd-gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
 	disable-wp;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 	status = "okay";
 };
 
@@ -460,6 +462,8 @@ &sdmmc1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc1_default>;
 	disable-wp;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 	status = "okay";
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb  6 04:03:17 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 6 Feb 2024 14:03:17 +0200
Subject: [PATCH v3 3/8] ARM: dts: microchip: sama5d27_som1_ek: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240206120322.88907-1-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
Message-ID: <20240206120322.88907-4-mihai.sain@microchip.com>

The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
The sdmmc controller from SAMA5D2 MPU has support for
IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts b/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
index f3ffb8f01d8a..255ee0640133 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
@@ -56,6 +56,8 @@ sdmmc0: sdio-host at a0000000 {
 			bus-width = <8>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_sdmmc0_default>;
+			vmmc-supply = <&vddin_3v3>;
+			vqmmc-supply = <&vddin_3v3>;
 			status = "okay";
 		};
 
@@ -63,6 +65,8 @@ sdmmc1: sdio-host at b0000000 {
 			bus-width = <4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_sdmmc1_default>;
+			vmmc-supply = <&vddin_3v3>;
+			vqmmc-supply = <&vddin_3v3>;
 			status = "okay";
 		};
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb  6 04:03:16 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 6 Feb 2024 14:03:16 +0200
Subject: [PATCH v3 2/8] ARM: dts: microchip: sam9x60ek: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240206120322.88907-1-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
Message-ID: <20240206120322.88907-3-mihai.sain@microchip.com>

The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
The sdmmc controller from SAM9X60 MPU doesn't support the
IO voltage signaling/switching required by the UHS sd-card.
In order to use the sd high-speed mode, keep vqmmc at 3V3.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sam9x60ek.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts b/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
index f3cbb675cea4..b19a0956dc97 100644
--- a/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
+++ b/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
@@ -560,6 +560,8 @@ &sdmmc0 {
 	status = "okay";
 	cd-gpios = <&pioA 23 GPIO_ACTIVE_LOW>;
 	disable-wp;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 };
 
 &sdmmc1 {
@@ -568,6 +570,8 @@ &sdmmc1 {
 	pinctrl-0 = <&pinctrl_sdmmc1_default>;
 	no-1-8-v;
 	non-removable;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 	status = "disabled"; /* Conflict with flx4. */
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb  6 04:03:18 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 6 Feb 2024 14:03:18 +0200
Subject: [PATCH v3 4/8] ARM: dts: microchip: sama5d27_wlsom1: Add power-supply property for sdmmc1 node
In-Reply-To: <20240206120322.88907-1-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
Message-ID: <20240206120322.88907-5-mihai.sain@microchip.com>

The sdmmc1 controller is powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
The sdmmc controller from SAMA5D2 MPU has support for
IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi
index 4617805c7748..96819ea24cbd 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi
+++ b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi
@@ -368,6 +368,8 @@ &sdmmc1 {
 	no-1-8-v;
 	non-removable;
 	bus-width = <4>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 
 	wilc: wifi at 0 {
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb  6 04:03:19 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 6 Feb 2024 14:03:19 +0200
Subject: [PATCH v3 5/8] ARM: dts: microchip: sama5d27_wlsom1_ek: Add power-supply property for sdmmc0 node
In-Reply-To: <20240206120322.88907-1-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
Message-ID: <20240206120322.88907-6-mihai.sain@microchip.com>

The sdmmc0 controller is powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.
The sdmmc controller from SAMA5D2 MPU has support for
IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
index 15239834d886..7b36e1970bb7 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
@@ -199,6 +199,8 @@ &sdmmc0 {
 	bus-width = <4>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb  6 04:03:21 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 6 Feb 2024 14:03:21 +0200
Subject: [PATCH v3 7/8] ARM: dts: microchip: sama5d2_icp: Add power-supply property for sdmmc0 node
In-Reply-To: <20240206120322.88907-1-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
Message-ID: <20240206120322.88907-8-mihai.sain@microchip.com>

The sdmmc0 controller is powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.
The sdmmc controller from SAMA5D2 MPU has support for
IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts b/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts
index 999adeca6f33..adcb3240e5f5 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts
@@ -712,6 +712,8 @@ &sdmmc0 {
 	bus-width = <4>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
+	vmmc-supply = <&vdd_io_reg>;	// 3.3V
+	vqmmc-supply = <&vdd_io_reg>;	// 3.3V
 	status = "okay";
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb  6 04:03:20 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 6 Feb 2024 14:03:20 +0200
Subject: [PATCH v3 6/8] ARM: dts: microchip: sama5d29_curiosity: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240206120322.88907-1-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
Message-ID: <20240206120322.88907-7-mihai.sain@microchip.com>

The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
The sdmmc controller from SAMA5D2 MPU has support for
IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
index 6b02b7bcfd49..4a86597d089a 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
@@ -504,6 +504,8 @@ &sdmmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
 	disable-wp;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 };
 
@@ -512,6 +514,8 @@ &sdmmc1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc1_default>;
 	disable-wp;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb  6 04:03:22 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 6 Feb 2024 14:03:22 +0200
Subject: [PATCH v3 8/8] ARM: dts: microchip: sama5d2_xplained: Add power-supply property for sdmmc0 node
In-Reply-To: <20240206120322.88907-1-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
Message-ID: <20240206120322.88907-9-mihai.sain@microchip.com>

The sdmmc0 controller is powered from 3.3V regulator.
Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.
The sdmmc controller from SAMA5D2 MPU has support for
IO voltage signaling/switching required by the UHS sd-card.
In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
index 6680031387e8..9b7e56790a5a 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
@@ -67,6 +67,8 @@ sdmmc0: sdio-host at a0000000 {
 			pinctrl-0 = <&pinctrl_sdmmc0_default>;
 			non-removable;
 			mmc-ddr-3_3v;
+			vmmc-supply = <&vdd_3v3_reg>;
+			vqmmc-supply = <&vdd_3v3_reg>;
 			status = "okay";
 		};
 
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Tue Feb  6 04:07:39 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  6 Feb 2024 13:07:39 +0100
Subject: [PATCH v4 0/9] MediaTek DRM - DSI driver cleanups
Message-ID: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>

Changes in v4:
 - Added a fix for RGB666 formats setting and for wrong register
   definitions for packed vs loosely packed formats
 - Added a commit to make use of mipi_dsi_pixel_format_to_bpp() helper
   instead of open coding the same

Changes in v3:
 - Rebased over next-20240131
 - Added bitfield.h inclusion in patch 3
 - Added three more cleanup commits to the mix to simplify
   the probe function and remove gotos.

Changes in v2:
 - Rebased over next-20231213

This series performs some cleanups for mtk_dsi, enhancing human
readability, using kernel provided macros where possible and
also reducing code size.

Tested on MT8173 and MT8192 Chromebooks (using a DSI<->DP bridge)
and on MT6795 Sony Xperia M5 (DSI video mode panel).

AngeloGioacchino Del Regno (9):
  drm/mediatek: dsi: Use GENMASK() for register mask definitions
  drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
  drm/mediatek: dsi: Cleanup functions mtk_dsi_ps_control{_vact}()
  drm/mediatek: dsi: Use bitfield macros where useful
  drm/mediatek: dsi: Replace open-coded instance of HZ_PER_MHZ
  drm/mediatek: dsi: Register DSI host after acquiring clocks and PHY
  drm/mediatek: dsi: Simplify with dev_err_probe and remove gotos
  drm/mediatek: dsi: Compress of_device_id entries and add sentinel
  drm/mediatek: dsi: Use mipi_dsi_pixel_format_to_bpp() helper function

 drivers/gpu/drm/mediatek/mtk_dsi.c | 310 ++++++++++++-----------------
 1 file changed, 126 insertions(+), 184 deletions(-)

-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Tue Feb  6 04:07:40 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  6 Feb 2024 13:07:40 +0100
Subject: [PATCH v4 1/9] drm/mediatek: dsi: Use GENMASK() for register mask definitions
In-Reply-To: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240206120748.136610-2-angelogioacchino.delregno@collabora.com>

Change magic numerical masks with usage of the GENMASK() macro
to improve readability.

While at it, also fix the DSI_PS_SEL mask to include all bits instead
of just a subset of them.

This commit brings no functional changes.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 45 +++++++++++++++---------------
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index a2fdfc8ddb15..3b7392c03b4d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -58,18 +58,18 @@
 
 #define DSI_TXRX_CTRL		0x18
 #define VC_NUM				BIT(1)
-#define LANE_NUM			(0xf << 2)
+#define LANE_NUM			GENMASK(5, 2)
 #define DIS_EOT				BIT(6)
 #define NULL_EN				BIT(7)
 #define TE_FREERUN			BIT(8)
 #define EXT_TE_EN			BIT(9)
 #define EXT_TE_EDGE			BIT(10)
-#define MAX_RTN_SIZE			(0xf << 12)
+#define MAX_RTN_SIZE			GENMASK(15, 12)
 #define HSTX_CKLP_EN			BIT(16)
 
 #define DSI_PSCTRL		0x1c
-#define DSI_PS_WC			0x3fff
-#define DSI_PS_SEL			(3 << 16)
+#define DSI_PS_WC			GENMASK(14, 0)
+#define DSI_PS_SEL			GENMASK(19, 16)
 #define PACKED_PS_16BIT_RGB565		(0 << 16)
 #define LOOSELY_PS_18BIT_RGB666		(1 << 16)
 #define PACKED_PS_18BIT_RGB666		(2 << 16)
@@ -109,26 +109,26 @@
 #define LD0_WAKEUP_EN			BIT(2)
 
 #define DSI_PHY_TIMECON0	0x110
-#define LPX				(0xff << 0)
-#define HS_PREP				(0xff << 8)
-#define HS_ZERO				(0xff << 16)
-#define HS_TRAIL			(0xff << 24)
+#define LPX				GENMASK(7, 0)
+#define HS_PREP				GENMASK(15, 8)
+#define HS_ZERO				GENMASK(23, 16)
+#define HS_TRAIL			GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON1	0x114
-#define TA_GO				(0xff << 0)
-#define TA_SURE				(0xff << 8)
-#define TA_GET				(0xff << 16)
-#define DA_HS_EXIT			(0xff << 24)
+#define TA_GO				GENMASK(7, 0)
+#define TA_SURE				GENMASK(15, 8)
+#define TA_GET				GENMASK(23, 16)
+#define DA_HS_EXIT			GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON2	0x118
-#define CONT_DET			(0xff << 0)
-#define CLK_ZERO			(0xff << 16)
-#define CLK_TRAIL			(0xff << 24)
+#define CONT_DET			GENMASK(7, 0)
+#define CLK_ZERO			GENMASK(23, 16)
+#define CLK_TRAIL			GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON3	0x11c
-#define CLK_HS_PREP			(0xff << 0)
-#define CLK_HS_POST			(0xff << 8)
-#define CLK_HS_EXIT			(0xff << 16)
+#define CLK_HS_PREP			GENMASK(7, 0)
+#define CLK_HS_POST			GENMASK(15, 8)
+#define CLK_HS_EXIT			GENMASK(23, 16)
 
 #define DSI_VM_CMD_CON		0x130
 #define VM_CMD_EN			BIT(0)
@@ -138,13 +138,14 @@
 #define FORCE_COMMIT			BIT(0)
 #define BYPASS_SHADOW			BIT(1)
 
-#define CONFIG				(0xff << 0)
+/* CMDQ related bits */
+#define CONFIG				GENMASK(7, 0)
 #define SHORT_PACKET			0
 #define LONG_PACKET			2
 #define BTA				BIT(2)
-#define DATA_ID				(0xff << 8)
-#define DATA_0				(0xff << 16)
-#define DATA_1				(0xff << 24)
+#define DATA_ID				GENMASK(15, 8)
+#define DATA_0				GENMASK(23, 16)
+#define DATA_1				GENMASK(31, 24)
 
 #define NS_TO_CYCLE(n, c)    ((n) / (c) + (((n) % (c)) ? 1 : 0))
 
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Tue Feb  6 04:07:41 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  6 Feb 2024 13:07:41 +0100
Subject: [PATCH v4 2/9] drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
In-Reply-To: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240206120748.136610-3-angelogioacchino.delregno@collabora.com>

The register bits definitions for RGB666 formats are wrong in multiple
ways: first, in the DSI_PS_SEL bits region, the Packed 18-bits RGB666
format is selected with bit 1, while the Loosely Packed one is bit 2,
and second - the definition name "LOOSELY_PS_18BIT_RGB666" is wrong
because the loosely packed format is 24 bits instead!

Either way, functions mtk_dsi_ps_control_vact() and mtk_dsi_ps_control()
do not even agree on the DSI_PS_SEL bit to set in DSI_PSCTRL: one sets
loosely packed (24) on RGB666, the other sets packed (18), and the other
way around for RGB666_PACKED.

Fixing this entire stack of issues is done in one go:
 - Use the correct bit for the Loosely Packed RGB666 definition
 - Rename LOOSELY_PS_18BIT_RGB666 to LOOSELY_PS_24BIT_RGB666
 - Change ps_bpp_mode in mtk_dsi_ps_control_vact() to set:
    - Loosely Packed, 24-bits for MIPI_DSI_FMT_RGB666
    - Packed, 18-bits for MIPI_DSI_FMT_RGB666_PACKED

Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 3b7392c03b4d..9fbf293db1c8 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -71,8 +71,8 @@
 #define DSI_PS_WC			GENMASK(14, 0)
 #define DSI_PS_SEL			GENMASK(19, 16)
 #define PACKED_PS_16BIT_RGB565		(0 << 16)
-#define LOOSELY_PS_18BIT_RGB666		(1 << 16)
-#define PACKED_PS_18BIT_RGB666		(2 << 16)
+#define PACKED_PS_18BIT_RGB666		(1 << 16)
+#define LOOSELY_PS_24BIT_RGB666		(2 << 16)
 #define PACKED_PS_24BIT_RGB888		(3 << 16)
 
 #define DSI_VSA_NL		0x20
@@ -370,10 +370,10 @@ static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
 		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
+		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-		ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;
+		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB565:
 		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
@@ -427,7 +427,7 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
 		dsi_tmp_buf_bpp = 3;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		tmp_reg = LOOSELY_PS_18BIT_RGB666;
+		tmp_reg = LOOSELY_PS_24BIT_RGB666;
 		dsi_tmp_buf_bpp = 3;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Tue Feb  6 04:07:43 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  6 Feb 2024 13:07:43 +0100
Subject: [PATCH v4 4/9] drm/mediatek: dsi: Use bitfield macros where useful
In-Reply-To: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240206120748.136610-5-angelogioacchino.delregno@collabora.com>

Instead of open coding bitshifting for various register fields,
use the bitfield macro FIELD_PREP(): this allows to enhance the
human readability, decrease likeliness of mistakes (and register
field overflowing) and also to simplify the code.
The latter is especially seen in mtk_dsi_rxtx_control(), where
it was possible to change a switch to a short for loop and to
also remove the need to check for maximum DSI lanes == 4 thanks
to the FIELD_PREP macro masking the value.

While at it, also add the missing DA_HS_SYNC bitmask, used in
mtk_dsi_phy_timconfig().

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 97 ++++++++++++++++--------------
 1 file changed, 52 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index b025886be680..26c221737387 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2015 MediaTek Inc.
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/iopoll.h>
@@ -70,16 +71,19 @@
 #define DSI_PSCTRL		0x1c
 #define DSI_PS_WC			GENMASK(14, 0)
 #define DSI_PS_SEL			GENMASK(19, 16)
-#define PACKED_PS_16BIT_RGB565		(0 << 16)
-#define PACKED_PS_18BIT_RGB666		(1 << 16)
-#define LOOSELY_PS_24BIT_RGB666		(2 << 16)
-#define PACKED_PS_24BIT_RGB888		(3 << 16)
+#define PACKED_PS_16BIT_RGB565		0
+#define PACKED_PS_18BIT_RGB666		1
+#define LOOSELY_PS_24BIT_RGB666		2
+#define PACKED_PS_24BIT_RGB888		3
 
 #define DSI_VSA_NL		0x20
 #define DSI_VBP_NL		0x24
 #define DSI_VFP_NL		0x28
 #define DSI_VACT_NL		0x2C
+#define VACT_NL				GENMASK(14, 0)
 #define DSI_SIZE_CON		0x38
+#define DSI_HEIGHT				GENMASK(30, 16)
+#define DSI_WIDTH				GENMASK(14, 0)
 #define DSI_HSA_WC		0x50
 #define DSI_HBP_WC		0x54
 #define DSI_HFP_WC		0x58
@@ -122,6 +126,7 @@
 
 #define DSI_PHY_TIMECON2	0x118
 #define CONT_DET			GENMASK(7, 0)
+#define DA_HS_SYNC			GENMASK(15, 8)
 #define CLK_ZERO			GENMASK(23, 16)
 #define CLK_TRAIL			GENMASK(31, 24)
 
@@ -253,14 +258,23 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
 	timing->clk_hs_zero = timing->clk_hs_trail * 4;
 	timing->clk_hs_exit = 2 * timing->clk_hs_trail;
 
-	timcon0 = timing->lpx | timing->da_hs_prepare << 8 |
-		  timing->da_hs_zero << 16 | timing->da_hs_trail << 24;
-	timcon1 = timing->ta_go | timing->ta_sure << 8 |
-		  timing->ta_get << 16 | timing->da_hs_exit << 24;
-	timcon2 = 1 << 8 | timing->clk_hs_zero << 16 |
-		  timing->clk_hs_trail << 24;
-	timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 |
-		  timing->clk_hs_exit << 16;
+	timcon0 = FIELD_PREP(LPX, timing->lpx) |
+		  FIELD_PREP(HS_PREP, timing->da_hs_prepare) |
+		  FIELD_PREP(HS_ZERO, timing->da_hs_zero) |
+		  FIELD_PREP(HS_TRAIL, timing->da_hs_trail);
+
+	timcon1 = FIELD_PREP(TA_GO, timing->ta_go) |
+		  FIELD_PREP(TA_SURE, timing->ta_sure) |
+		  FIELD_PREP(TA_GET, timing->ta_get) |
+		  FIELD_PREP(DA_HS_EXIT, timing->da_hs_exit);
+
+	timcon2 = FIELD_PREP(DA_HS_SYNC, 1) |
+		  FIELD_PREP(CLK_ZERO, timing->clk_hs_zero) |
+		  FIELD_PREP(CLK_TRAIL, timing->clk_hs_trail);
+
+	timcon3 = FIELD_PREP(CLK_HS_PREP, timing->clk_hs_prepare) |
+		  FIELD_PREP(CLK_HS_POST, timing->clk_hs_post) |
+		  FIELD_PREP(CLK_HS_EXIT, timing->clk_hs_exit);
 
 	writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
 	writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
@@ -353,69 +367,61 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
 
 static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 {
-	u32 tmp_reg;
+	u32 regval, tmp_reg = 0;
+	u8 i;
 
-	switch (dsi->lanes) {
-	case 1:
-		tmp_reg = 1 << 2;
-		break;
-	case 2:
-		tmp_reg = 3 << 2;
-		break;
-	case 3:
-		tmp_reg = 7 << 2;
-		break;
-	case 4:
-		tmp_reg = 0xf << 2;
-		break;
-	default:
-		tmp_reg = 0xf << 2;
-		break;
-	}
+	/* Number of DSI lanes (max 4 lanes), each bit enables one DSI lane. */
+	for (i = 0; i < dsi->lanes; i++)
+		tmp_reg |= BIT(i);
+
+	regval = FIELD_PREP(LANE_NUM, tmp_reg);
 
 	if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
-		tmp_reg |= HSTX_CKLP_EN;
+		regval |= HSTX_CKLP_EN;
 
 	if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
-		tmp_reg |= DIS_EOT;
+		regval |= DIS_EOT;
 
-	writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
+	writel(regval, dsi->regs + DSI_TXRX_CTRL);
 }
 
 static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
 {
-	struct videomode *vm = &dsi->vm;
-	u32 dsi_buf_bpp, ps_wc;
-	u32 ps_bpp_mode;
+	u32 dsi_buf_bpp, ps_val, ps_wc, vact_nl;
 
 	if (dsi->format == MIPI_DSI_FMT_RGB565)
 		dsi_buf_bpp = 2;
 	else
 		dsi_buf_bpp = 3;
 
-	ps_wc = vm->hactive * dsi_buf_bpp;
-	ps_bpp_mode = ps_wc;
+	/* Word count */
+	ps_wc = FIELD_PREP(DSI_PS_WC, dsi->vm.hactive * dsi_buf_bpp);
+	ps_val = ps_wc;
 
+	/* Pixel Stream type */
 	switch (dsi->format) {
+	default:
+		fallthrough;
 	case MIPI_DSI_FMT_RGB888:
-		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_24BIT_RGB888);
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, LOOSELY_PS_24BIT_RGB666);
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_18BIT_RGB666);
 		break;
 	case MIPI_DSI_FMT_RGB565:
-		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_16BIT_RGB565);
 		break;
 	}
 
 	if (config_vact) {
-		writel(vm->vactive, dsi->regs + DSI_VACT_NL);
+		vact_nl = FIELD_PREP(VACT_NL, dsi->vm.vactive);
+		writel(vact_nl, dsi->regs + DSI_VACT_NL);
 		writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
 	}
-	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
+	writel(ps_val, dsi->regs + DSI_PSCTRL);
 }
 
 static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
@@ -442,7 +448,8 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
 
 	if (dsi->driver_data->has_size_ctl)
-		writel(vm->vactive << 16 | vm->hactive,
+		writel(FIELD_PREP(DSI_HEIGHT, vm->vactive) |
+		       FIELD_PREP(DSI_WIDTH, vm->hactive),
 		       dsi->regs + DSI_SIZE_CON);
 
 	horizontal_sync_active_byte = (vm->hsync_len * dsi_tmp_buf_bpp - 10);
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Tue Feb  6 04:07:42 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  6 Feb 2024 13:07:42 +0100
Subject: [PATCH v4 3/9] drm/mediatek: dsi: Cleanup functions mtk_dsi_ps_control{_vact}()
In-Reply-To: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240206120748.136610-4-angelogioacchino.delregno@collabora.com>

Function mtk_dsi_ps_control() is a subset of mtk_dsi_ps_control_vact():
merge the two in one mtk_dsi_ps_control() function by adding one
function parameter `config_vact` which, when true, writes the VACT
related registers.

Reviewed-by: Fei Shao <fshao at chromium.org>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 76 +++++++++---------------------
 1 file changed, 23 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 9fbf293db1c8..b025886be680 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -351,40 +351,6 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
 	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
 }
 
-static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
-{
-	struct videomode *vm = &dsi->vm;
-	u32 dsi_buf_bpp, ps_wc;
-	u32 ps_bpp_mode;
-
-	if (dsi->format == MIPI_DSI_FMT_RGB565)
-		dsi_buf_bpp = 2;
-	else
-		dsi_buf_bpp = 3;
-
-	ps_wc = vm->hactive * dsi_buf_bpp;
-	ps_bpp_mode = ps_wc;
-
-	switch (dsi->format) {
-	case MIPI_DSI_FMT_RGB888:
-		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
-		break;
-	case MIPI_DSI_FMT_RGB666:
-		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
-		break;
-	case MIPI_DSI_FMT_RGB666_PACKED:
-		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
-		break;
-	case MIPI_DSI_FMT_RGB565:
-		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
-		break;
-	}
-
-	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
-	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
-	writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
-}
-
 static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 {
 	u32 tmp_reg;
@@ -416,36 +382,40 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 	writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
 }
 
-static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
+static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
 {
-	u32 dsi_tmp_buf_bpp;
-	u32 tmp_reg;
+	struct videomode *vm = &dsi->vm;
+	u32 dsi_buf_bpp, ps_wc;
+	u32 ps_bpp_mode;
+
+	if (dsi->format == MIPI_DSI_FMT_RGB565)
+		dsi_buf_bpp = 2;
+	else
+		dsi_buf_bpp = 3;
+
+	ps_wc = vm->hactive * dsi_buf_bpp;
+	ps_bpp_mode = ps_wc;
 
 	switch (dsi->format) {
 	case MIPI_DSI_FMT_RGB888:
-		tmp_reg = PACKED_PS_24BIT_RGB888;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		tmp_reg = LOOSELY_PS_24BIT_RGB666;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-		tmp_reg = PACKED_PS_18BIT_RGB666;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB565:
-		tmp_reg = PACKED_PS_16BIT_RGB565;
-		dsi_tmp_buf_bpp = 2;
-		break;
-	default:
-		tmp_reg = PACKED_PS_24BIT_RGB888;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
 		break;
 	}
 
-	tmp_reg += dsi->vm.hactive * dsi_tmp_buf_bpp & DSI_PS_WC;
-	writel(tmp_reg, dsi->regs + DSI_PSCTRL);
+	if (config_vact) {
+		writel(vm->vactive, dsi->regs + DSI_VACT_NL);
+		writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
+	}
+	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
 }
 
 static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
@@ -521,7 +491,7 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
 	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
 
-	mtk_dsi_ps_control(dsi);
+	mtk_dsi_ps_control(dsi, false);
 }
 
 static void mtk_dsi_start(struct mtk_dsi *dsi)
@@ -666,7 +636,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	mtk_dsi_reset_engine(dsi);
 	mtk_dsi_phy_timconfig(dsi);
 
-	mtk_dsi_ps_control_vact(dsi);
+	mtk_dsi_ps_control(dsi, true);
 	mtk_dsi_set_vm_cmd(dsi);
 	mtk_dsi_config_vdo_timing(dsi);
 	mtk_dsi_set_interrupt_enable(dsi);
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Tue Feb  6 04:07:44 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  6 Feb 2024 13:07:44 +0100
Subject: [PATCH v4 5/9] drm/mediatek: dsi: Replace open-coded instance of HZ_PER_MHZ
In-Reply-To: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240206120748.136610-6-angelogioacchino.delregno@collabora.com>

In mtk_dsi_phy_timconfig(), we're dividing the `data_rate` variable,
expressed in Hz to retrieve a value in MHz: instead of open-coding,
use the HZ_PER_MHZ definition, available in linux/units.h.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 26c221737387..5e383ca00ba8 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -13,6 +13,7 @@
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
+#include <linux/units.h>
 
 #include <video/mipi_display.h>
 #include <video/videomode.h>
@@ -238,7 +239,7 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, u32 mask, u32 data)
 static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
 {
 	u32 timcon0, timcon1, timcon2, timcon3;
-	u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, 1000000);
+	u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, HZ_PER_MHZ);
 	struct mtk_phy_timing *timing = &dsi->phy_timing;
 
 	timing->lpx = (60 * data_rate_mhz / (8 * 1000)) + 1;
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Tue Feb  6 04:07:46 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  6 Feb 2024 13:07:46 +0100
Subject: [PATCH v4 7/9] drm/mediatek: dsi: Simplify with dev_err_probe and remove gotos
In-Reply-To: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240206120748.136610-8-angelogioacchino.delregno@collabora.com>

Most of the functions that are called in the probe callback are
devm managed, or all but mipi_dsi_host_register(): simplify the probe
function's error paths with dev_err_probe() and remove the lonely
instance of `goto err_unregister_host` by just directly calling the
mipi_dsi_host_unregister() function in the devm_request_irq() error
path, allowing to also remove the same label.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 60 +++++++++---------------------
 1 file changed, 18 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 6ee01626d55c..8d407d71e9db 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1117,64 +1117,44 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
-	if (IS_ERR(dsi->engine_clk)) {
-		ret = PTR_ERR(dsi->engine_clk);
+	if (IS_ERR(dsi->engine_clk))
+		return dev_err_probe(dev, PTR_ERR(dsi->engine_clk),
+				     "Failed to get engine clock\n");
 
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get engine clock: %d\n", ret);
-		return ret;
-	}
 
 	dsi->digital_clk = devm_clk_get(dev, "digital");
-	if (IS_ERR(dsi->digital_clk)) {
-		ret = PTR_ERR(dsi->digital_clk);
-
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get digital clock: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->digital_clk))
+		return dev_err_probe(dev, PTR_ERR(dsi->digital_clk),
+				     "Failed to get digital clock\n");
 
 	dsi->hs_clk = devm_clk_get(dev, "hs");
-	if (IS_ERR(dsi->hs_clk)) {
-		ret = PTR_ERR(dsi->hs_clk);
-		dev_err(dev, "Failed to get hs clock: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->hs_clk))
+		return dev_err_probe(dev, PTR_ERR(dsi->hs_clk), "Failed to get hs clock\n");
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dsi->regs = devm_ioremap_resource(dev, regs);
-	if (IS_ERR(dsi->regs)) {
-		ret = PTR_ERR(dsi->regs);
-		dev_err(dev, "Failed to ioremap memory: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->regs))
+		return dev_err_probe(dev, PTR_ERR(dsi->regs), "Failed to ioremap memory\n");
 
 	dsi->phy = devm_phy_get(dev, "dphy");
-	if (IS_ERR(dsi->phy)) {
-		ret = PTR_ERR(dsi->phy);
-		dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->phy))
+		return dev_err_probe(dev, PTR_ERR(dsi->phy), "Failed to get MIPI-DPHY\n");
 
 	irq_num = platform_get_irq(pdev, 0);
-	if (irq_num < 0) {
-		ret = irq_num;
-		return ret;
-	}
+	if (irq_num < 0)
+		return irq_num;
 
 	dsi->host.ops = &mtk_dsi_ops;
 	dsi->host.dev = dev;
 	ret = mipi_dsi_host_register(&dsi->host);
-	if (ret < 0) {
-		dev_err(dev, "failed to register DSI host: %d\n", ret);
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to register DSI host\n");
 
 	ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq,
 			       IRQF_TRIGGER_NONE, dev_name(&pdev->dev), dsi);
 	if (ret) {
-		dev_err(&pdev->dev, "failed to request mediatek dsi irq\n");
-		goto err_unregister_host;
+		mipi_dsi_host_unregister(&dsi->host);
+		return dev_err_probe(&pdev->dev, ret, "Failed to request DSI irq\n");
 	}
 
 	init_waitqueue_head(&dsi->irq_wait_queue);
@@ -1186,10 +1166,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
 	return 0;
-
-err_unregister_host:
-	mipi_dsi_host_unregister(&dsi->host);
-	return ret;
 }
 
 static void mtk_dsi_remove(struct platform_device *pdev)
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Tue Feb  6 04:07:45 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  6 Feb 2024 13:07:45 +0100
Subject: [PATCH v4 6/9] drm/mediatek: dsi: Register DSI host after acquiring clocks and PHY
In-Reply-To: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240206120748.136610-7-angelogioacchino.delregno@collabora.com>

Registering the dsi host with its ops before getting dsi->regs is
simply wrong: even though there's nothing (for now) asynchronously
calling those ops before the end of the probe function, installing
ops that are using iospace(s) and clocks before even initializing
those is too fragile.

Register the DSI host after getting clocks, iospace and PHY.
This wil also allow to simplify the error paths in a later commit.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5e383ca00ba8..6ee01626d55c 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1114,14 +1114,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	if (!dsi)
 		return -ENOMEM;
 
-	dsi->host.ops = &mtk_dsi_ops;
-	dsi->host.dev = dev;
-	ret = mipi_dsi_host_register(&dsi->host);
-	if (ret < 0) {
-		dev_err(dev, "failed to register DSI host: %d\n", ret);
-		return ret;
-	}
-
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
@@ -1130,7 +1122,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 
 		if (ret != -EPROBE_DEFER)
 			dev_err(dev, "Failed to get engine clock: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	dsi->digital_clk = devm_clk_get(dev, "digital");
@@ -1139,14 +1131,14 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 
 		if (ret != -EPROBE_DEFER)
 			dev_err(dev, "Failed to get digital clock: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	dsi->hs_clk = devm_clk_get(dev, "hs");
 	if (IS_ERR(dsi->hs_clk)) {
 		ret = PTR_ERR(dsi->hs_clk);
 		dev_err(dev, "Failed to get hs clock: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1154,20 +1146,28 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	if (IS_ERR(dsi->regs)) {
 		ret = PTR_ERR(dsi->regs);
 		dev_err(dev, "Failed to ioremap memory: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	dsi->phy = devm_phy_get(dev, "dphy");
 	if (IS_ERR(dsi->phy)) {
 		ret = PTR_ERR(dsi->phy);
 		dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	irq_num = platform_get_irq(pdev, 0);
 	if (irq_num < 0) {
 		ret = irq_num;
-		goto err_unregister_host;
+		return ret;
+	}
+
+	dsi->host.ops = &mtk_dsi_ops;
+	dsi->host.dev = dev;
+	ret = mipi_dsi_host_register(&dsi->host);
+	if (ret < 0) {
+		dev_err(dev, "failed to register DSI host: %d\n", ret);
+		return ret;
 	}
 
 	ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq,
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Tue Feb  6 04:07:47 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  6 Feb 2024 13:07:47 +0100
Subject: [PATCH v4 8/9] drm/mediatek: dsi: Compress of_device_id entries and add sentinel
In-Reply-To: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240206120748.136610-9-angelogioacchino.delregno@collabora.com>

All entries fit in 82 columns, which is acceptable: compress all of
the mtk_dsi_of_match[] entries to a single line for each.

While at it, also add the usual sentinel comment to the last entry.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 8d407d71e9db..545c5cc071d9 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1204,17 +1204,12 @@ static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = {
 };
 
 static const struct of_device_id mtk_dsi_of_match[] = {
-	{ .compatible = "mediatek,mt2701-dsi",
-	  .data = &mt2701_dsi_driver_data },
-	{ .compatible = "mediatek,mt8173-dsi",
-	  .data = &mt8173_dsi_driver_data },
-	{ .compatible = "mediatek,mt8183-dsi",
-	  .data = &mt8183_dsi_driver_data },
-	{ .compatible = "mediatek,mt8186-dsi",
-	  .data = &mt8186_dsi_driver_data },
-	{ .compatible = "mediatek,mt8188-dsi",
-	  .data = &mt8188_dsi_driver_data },
-	{ },
+	{ .compatible = "mediatek,mt2701-dsi", .data = &mt2701_dsi_driver_data },
+	{ .compatible = "mediatek,mt8173-dsi", .data = &mt8173_dsi_driver_data },
+	{ .compatible = "mediatek,mt8183-dsi", .data = &mt8183_dsi_driver_data },
+	{ .compatible = "mediatek,mt8186-dsi", .data = &mt8186_dsi_driver_data },
+	{ .compatible = "mediatek,mt8188-dsi", .data = &mt8188_dsi_driver_data },
+	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mtk_dsi_of_match);
 
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Tue Feb  6 04:07:48 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  6 Feb 2024 13:07:48 +0100
Subject: [PATCH v4 9/9] drm/mediatek: dsi: Use mipi_dsi_pixel_format_to_bpp() helper function
In-Reply-To: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240206120748.136610-10-angelogioacchino.delregno@collabora.com>

Instead of open coding, use the mipi_dsi_pixel_format_to_bpp() helper
function from drm_mipi_dsi.h in mtk_dsi_poweron() and for validation
in mtk_dsi_bridge_mode_valid().

Note that this function changes the behavior of this driver: previously,
in case of unknown formats, it would (wrongly) assume that it should
account for a 24-bits format - now it will return an error and refuse
to set clocks and/or enable the DSI.

This is done because setting the wrong data rate will only produce a
garbage output that the display will misinterpret both because this
driver doesn't actually provide any extra-spec format support and/or
because the data rate (hence, the HS clock) will be wrong.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 545c5cc071d9..d844a0500e2b 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -598,19 +598,12 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	if (++dsi->refcount != 1)
 		return 0;
 
-	switch (dsi->format) {
-	case MIPI_DSI_FMT_RGB565:
-		bit_per_pixel = 16;
-		break;
-	case MIPI_DSI_FMT_RGB666_PACKED:
-		bit_per_pixel = 18;
-		break;
-	case MIPI_DSI_FMT_RGB666:
-	case MIPI_DSI_FMT_RGB888:
-	default:
-		bit_per_pixel = 24;
-		break;
+	ret = mipi_dsi_pixel_format_to_bpp(dsi->format);
+	if (ret < 0) {
+		dev_err(dev, "Unknown MIPI DSI format %d\n", dsi->format);
+		return ret;
 	}
+	bit_per_pixel = ret;
 
 	dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock * bit_per_pixel,
 					  dsi->lanes);
@@ -793,12 +786,11 @@ mtk_dsi_bridge_mode_valid(struct drm_bridge *bridge,
 			  const struct drm_display_mode *mode)
 {
 	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
-	u32 bpp;
+	int bpp;
 
-	if (dsi->format == MIPI_DSI_FMT_RGB565)
-		bpp = 16;
-	else
-		bpp = 24;
+	bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+	if (bpp < 0)
+		return MODE_ERROR;
 
 	if (mode->clock * bpp / dsi->lanes > 1500000)
 		return MODE_CLOCK_HIGH;
-- 
2.43.0



From broonie at kernel.org  Tue Feb  6 04:09:14 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 06 Feb 2024 12:09:14 +0000
Subject: [PATCH] spi: bcm2835: implement ctlr->max_transfer_size
In-Reply-To: <20240126220024.3926403-2-dlechner@baylibre.com>
References: <20240126220024.3926403-2-dlechner@baylibre.com>
Message-ID: <170722135486.992289.5399586153021617257.b4-ty@kernel.org>

On Fri, 26 Jan 2024 16:00:23 -0600, David Lechner wrote:
> The core SPI code will handle splitting transfers if needed as long
> as ctlr->max_transfer_size is implemented. It does this in
> __spi_pump_transfer_message() immediately before calling
> ctlr->prepare_message. So effectively, this change does not
> alter the behavior of the driver.
> 
> Also, several peripheral drivers make use of spi_max_transfer_size(),
> so this should improve compatibility with those drivers.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: bcm2835: implement ctlr->max_transfer_size
      commit: 2733092baa3e8a1f05fd16088808be17c98990b4

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  Tue Feb  6 04:09:17 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 06 Feb 2024 12:09:17 +0000
Subject: [PATCH 1/3] spi: spi-rockchip: Fix out of bounds array access
In-Reply-To: <d0a0c4b94f933f7f43973c34765214303ee82b77.camel@gmail.com>
References: <d0a0c4b94f933f7f43973c34765214303ee82b77.camel@gmail.com>
Message-ID: <170722135749.992289.15697794972690614056.b4-ty@kernel.org>

On Fri, 26 Jan 2024 20:46:22 +0100, Luis de Arquer wrote:
> Since spi-rockchip enables use_gpio_descriptors and the
> SPI_CONTROLLER_GPIO_SS flag, the spi subsytem may call set_cs()
> for spi devices with indexes above ROCKCHIP_SPI_MAX_CS_NUM
> 
> Remove array cs_asserted[] which held a shadow copy of the state
> of the chip select lines with the only purpose of optimizing out
> rewriting a chip select line to the current state (no-op)
> This case is already handled by spi.c
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/3] spi: spi-rockchip: Fix out of bounds array access
      commit: 5c018e378f916b56503bba65cbdec66ad16f20b7

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  Tue Feb  6 04:09:19 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 06 Feb 2024 12:09:19 +0000
Subject: [PATCH 2/3] spi: spi-rockchip: Fix max_native_cs
In-Reply-To: <4d18808e85b85077761c5655083f20ebfd7d3770.camel@gmail.com>
References: <4d18808e85b85077761c5655083f20ebfd7d3770.camel@gmail.com>
Message-ID: <170722135988.992289.16551970004382399267.b4-ty@kernel.org>

On Fri, 26 Jan 2024 20:46:44 +0100, Luis de Arquer wrote:
> 


Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[2/3] spi: spi-rockchip: Fix max_native_cs
      commit: 07d6749317bf8cc416fb7eb8f997a884bd610f8d

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 patchwork-bot+netdevbpf at kernel.org  Tue Feb  6 04:10:28 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Tue, 06 Feb 2024 12:10:28 +0000
Subject: [PATCH net-next] net: phy: constify phydev->drv
In-Reply-To: <E1rVxXt-002YqY-9G@rmk-PC.armlinux.org.uk>
References: <E1rVxXt-002YqY-9G@rmk-PC.armlinux.org.uk>
Message-ID: <170722142863.5713.2764946066155223415.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni at redhat.com>:

On Fri, 02 Feb 2024 17:41:45 +0000 you wrote:
> Device driver structures are shared between all devices that they
> match, and thus nothing should never write to the device driver
> structure through the phydev->drv pointer. Let's make this pointer
> const to catch code that attempts to do so.
> 
> Suggested-by: Christian Marangi <ansuelsmth at gmail.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> 
> [...]

Here is the summary with links:
  - [net-next] net: phy: constify phydev->drv
    https://git.kernel.org/netdev/net-next/c/0bd199fd9c19

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From rogerq at kernel.org  Tue Feb  6 04:30:33 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 6 Feb 2024 14:30:33 +0200
Subject: [PATCH v4 3/3] arm64: dts: ti: k3-am62p: add the USB sub-system
In-Reply-To: <45a0ed98-8dd2-4c5b-8e89-40c70e3fe831@ti.com>
References: <20240205135908.54656-1-rogerq@kernel.org>
 <20240205135908.54656-4-rogerq@kernel.org>
 <45a0ed98-8dd2-4c5b-8e89-40c70e3fe831@ti.com>
Message-ID: <77f7b127-e609-45e3-90aa-67aa7838ce6b@kernel.org>



On 05/02/2024 19:34, Andrew Davis wrote:
> On 2/5/24 7:59 AM, Roger Quadros wrote:
>> There are two USB instances available on the am62p5 starter kit. Include
>> and enable them for use on the board.
>>
>> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>> ---
>>
>> Notes:
>> ???? Changelog:
>> ???? ???? v4 - no change
>> ???? ???? v3 - no change
>> ???? https://lore.kernel.org/all/20240201120332.4811-4-rogerq at kernel.org/
>> ???? ???? v2:
>> ???? - added USB PHY CTRL node changes here
>> ???? - changed USB wrapper node names to usb@
>> ???? - changed Type-C chip node name to usb-power-control@
>>
>> ? arch/arm64/boot/dts/ti/k3-am62p-main.dtsi?? | 46 ++++++++++++++
>> ? arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi | 10 +++
>> ? arch/arm64/boot/dts/ti/k3-am62p5-sk.dts???? | 67 +++++++++++++++++++++
>> ? 3 files changed, 123 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
>> index 4c51bae06b57..17d28390d587 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
>> @@ -560,6 +560,52 @@ sdhci2: mmc at fa20000 {
>> ????????? status = "disabled";
>> ????? };
>> ? +??? usbss0: usb at f900000 {
>> +??????? compatible = "ti,am62-usb";
>> +??????? reg = <0x00 0x0f900000 0x00 0x800>;
>> +??????? clocks = <&k3_clks 161 3>;
>> +??????? clock-names = "ref";
>> +??????? ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
>> +??????? #address-cells = <2>;
>> +??????? #size-cells = <2>;
>> +??????? power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
>> +??????? ranges;
>> +??????? status = "disabled";
>> +
>> +??????? usb0: usb at 31000000 {
>> +??????????? compatible = "snps,dwc3";
>> +??????????? reg = <0x00 0x31000000 0x00 0x50000>;
>> +??????????? interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
>> +??????????? <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
>> +??????????? interrupt-names = "host", "peripheral";
>> +??????????? maximum-speed = "high-speed";
>> +??????????? dr_mode = "otg";
>> +??????? };
>> +??? };
>> +
>> +??? usbss1: usb at f910000 {
>> +??????? compatible = "ti,am62-usb";
>> +??????? reg = <0x00 0x0f910000 0x00 0x800>;
>> +??????? clocks = <&k3_clks 162 3>;
>> +??????? clock-names = "ref";
>> +??????? ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
>> +??????? #address-cells = <2>;
>> +??????? #size-cells = <2>;
>> +??????? power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
>> +??????? ranges;
>> +??????? status = "disabled";
>> +
>> +??????? usb1: usb at 31100000 {
>> +??????????? compatible = "snps,dwc3";
>> +??????????? reg = <0x00 0x31100000 0x00 0x50000>;
>> +??????????? interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
>> +??????????? <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
>> +??????????? interrupt-names = "host", "peripheral";
>> +??????????? maximum-speed = "high-speed";
>> +??????????? dr_mode = "otg";
>> +??????? };
>> +??? };
>> +
>> ????? fss: bus at fc00000 {
>> ????????? compatible = "simple-bus";
>> ????????? reg = <0x00 0x0fc00000 0x00 0x70000>;
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
>> index 19f42b39394e..00dd38b02a52 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
>> @@ -18,6 +18,16 @@ chipid: chipid at 14 {
>> ????????????? reg = <0x14 0x4>;
>> ????????????? bootph-all;
>> ????????? };
>> +
>> +??????? usb0_phy_ctrl: syscon at 4008 {
>> +??????????? compatible = "ti,am62-usb-phy-ctrl", "syscon";
>> +??????????? reg = <0x4008 0x4>;
>> +??????? };
>> +
>> +??????? usb1_phy_ctrl: syscon at 4018 {
>> +??????????? compatible = "ti,am62-usb-phy-ctrl", "syscon";
>> +??????????? reg = <0x4018 0x4>;
>> +??????? };
>> ????? };
>> ? ????? wkup_uart0: serial at 2b300000 {
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>> index 1773c05f752c..80be56c0a4e0 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>> @@ -27,6 +27,8 @@ aliases {
>> ????????? spi0 = &ospi0;
>> ????????? ethernet0 = &cpsw_port1;
>> ????????? ethernet1 = &cpsw_port2;
>> +??????? usb0 = &usb0;
>> +??????? usb1 = &usb1;
>> ????? };
>> ? ????? chosen {
>> @@ -297,6 +299,12 @@ AM62PX_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (G20) MCASP0_ACLKR.UART1_TXD */
>> ????????? bootph-all;
>> ????? };
>> ? +??? main_usb1_pins_default: main-usb1-default-pins {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
>> +??????? >;
>> +??? };
>> +
>> ????? main_wlirq_pins_default: main-wlirq-default-pins {
>> ????????? pinctrl-single,pins = <
>> ????????????? AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
>> @@ -340,6 +348,36 @@ AM62PX_IOPAD(0x0124, PIN_INPUT, 7) /* (J25) MMC2_SDCD.GPIO0_71 */
>> ????? };
>> ? };
>> ? +&main_i2c0 {
>> +??? status = "okay";
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&main_i2c0_pins_default>;
>> +??? clock-frequency = <400000>;
>> +
>> +??? typec_pd0: usb-power-controller at 3f {
>> +??????? compatible = "ti,tps6598x";
>> +??????? reg = <0x3f>;
>> +
>> +??????? connector {
>> +??????????? compatible = "usb-c-connector";
>> +??????????? label = "USB-C";
>> +??????????? self-powered;
>> +??????????? data-role = "dual";
>> +??????????? power-role = "sink";
>> +??????????? ports {
>> +??????????????? #address-cells = <1>;
>> +??????????????? #size-cells = <0>;
>> +??????????????? port at 0 {
>> +??????????????????? reg = <0>;
>> +??????????????????? usb_con_hs: endpoint {
>> +??????????????????????? remote-endpoint = <&usb0_hs_ep>;
>> +??????????????????? };
>> +??????????????? };
>> +??????????? };
>> +??????? };
>> +??? };
>> +};
>> +
>> ? &main_i2c1 {
>> ????? status = "okay";
>> ????? pinctrl-names = "default";
>> @@ -460,6 +498,35 @@ cpsw3g_phy1: ethernet-phy at 1 {
>> ????? };
>> ? };
>> ? +&usbss0 {
>> +??? status = "okay";
>> +??? ti,vbus-divider;
>> +};
>> +
>> +&usbss1 {
>> +??? status = "okay";
>> +??? ti,vbus-divider;
>> +};
>> +
>> +&usb0 {
>> +??? usb-role-switch;
>> +??? #address-cells = <1>;
>> +??? #size-cells = <0>;
>> +
>> +??? port at 0 {
>> +??????? reg = <0>;
>> +??????? usb0_hs_ep: endpoint {
>> +??????????? remote-endpoint = <&usb_con_hs>;
>> +??????? };
>> +??? };
>> +};
>> +
>> +&usb1 {
>> +??? dr_mode = "host";
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&main_usb1_pins_default>;
> 
> I'm not super familiar with USB, but I see this pinmux for the
> "DRVVBUS" pin is usually added the the parent USB subsystem node (usbss).
> Does this pin belong to the subsystem or the specific USB instance?
> 
There is only 1 USB instance per USB sub-system.
The "DRVVBUS" pin is a control signal to enable the VBUS regulator
while in host mode.

Just probing the usbss1 driver has no use of "DRVVBUS".
I think usb1 is the right place as it is used there.

> Andrew
> 
>> +};
>> +
>> ? &mcasp1 {
>> ????? status = "okay";
>> ????? #sound-dai-cells = <0>;

-- 
cheers,
-roger


From mark.rutland at arm.com  Tue Feb  6 04:38:45 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue,  6 Feb 2024 12:38:45 +0000
Subject: [PATCH 0/3] arm64: cleanup DAIF handling for EL0 returns
Message-ID: <20240206123848.1696480-1-mark.rutland@arm.com>

Hi,

These patches rework DAIF handling when returning to EL0, simplifiying
the logic in do_notify_resume() and allowing Debug + SError to be
unmasked for a little longer during exception return.

My primary motivation for these changes is to centralize entry/exit DAIF
management within entry-common.c, as this will allow entry/exit
sequences to be specialised, and make it much easier to add support for
FEAT_NMI. With specialized entry DAIF management, it will also be
possible to simplify local_daif_{save,restore}() and
local_irq_{save,restore}().

I'm sending this out on its own as (IMO) it's a nice cleanup on its own,
and I don't believe that I'll have the remainder of the DAIF rework
ready for this cycle.

The series is based on v6.8-rc3.

Mark.

Mark Rutland (3):
  arm64: Simplify do_notify_resume() DAIF masking
  arm64: Move do_notify_resume() to entry-common.c
  arm64: Unmask Debug + SError in do_notify_resume()

 arch/arm64/include/asm/exception.h |  2 +-
 arch/arm64/kernel/entry-common.c   | 36 ++++++++++++++++++++++++++-
 arch/arm64/kernel/signal.c         | 39 ++----------------------------
 3 files changed, 38 insertions(+), 39 deletions(-)

-- 
2.30.2



From mark.rutland at arm.com  Tue Feb  6 04:38:46 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue,  6 Feb 2024 12:38:46 +0000
Subject: [PATCH 1/3] arm64: Simplify do_notify_resume() DAIF masking
In-Reply-To: <20240206123848.1696480-1-mark.rutland@arm.com>
References: <20240206123848.1696480-1-mark.rutland@arm.com>
Message-ID: <20240206123848.1696480-2-mark.rutland@arm.com>

In do_notify_resume, we handle _TIF_NEED_RESCHED differently from all
other flags, leaving IRQ+FIQ masked when calling into schedule(). This
masking is a historical artifact, and it is not currently necessary
to mask IRQ+FIQ when calling into schedule (as evidenced by the generic
exit_to_user_mode_loop(), which unmasks IRQs before checking
_TIF_NEED_RESCHED and calling schedule()).

This patch removes the special case for _TIF_NEED_RESCHED, moving this
check into the main loop such that schedule() will be called from a
regular process context with IRQ+FIQ unmasked. This is a minor
simplification to do_notify_resume() and brings it into line with the
generic exit_to_user_mode_loop() logic. This will also aid subsequent
rework of DAIF management.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: James Morse <james.morse at arm.com>
Cc: Mark Brown <broonie at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/signal.c | 34 +++++++++++++++-------------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 0e8beb3349ea2..50e108741599d 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -1281,32 +1281,28 @@ static void do_signal(struct pt_regs *regs)
 void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
 {
 	do {
-		if (thread_flags & _TIF_NEED_RESCHED) {
-			/* Unmask Debug and SError for the next task */
-			local_daif_restore(DAIF_PROCCTX_NOIRQ);
+		local_daif_restore(DAIF_PROCCTX);
 
+		if (thread_flags & _TIF_NEED_RESCHED)
 			schedule();
-		} else {
-			local_daif_restore(DAIF_PROCCTX);
 
-			if (thread_flags & _TIF_UPROBE)
-				uprobe_notify_resume(regs);
+		if (thread_flags & _TIF_UPROBE)
+			uprobe_notify_resume(regs);
 
-			if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
-				clear_thread_flag(TIF_MTE_ASYNC_FAULT);
-				send_sig_fault(SIGSEGV, SEGV_MTEAERR,
-					       (void __user *)NULL, current);
-			}
+		if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
+			clear_thread_flag(TIF_MTE_ASYNC_FAULT);
+			send_sig_fault(SIGSEGV, SEGV_MTEAERR,
+				       (void __user *)NULL, current);
+		}
 
-			if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
-				do_signal(regs);
+		if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
+			do_signal(regs);
 
-			if (thread_flags & _TIF_NOTIFY_RESUME)
-				resume_user_mode_work(regs);
+		if (thread_flags & _TIF_NOTIFY_RESUME)
+			resume_user_mode_work(regs);
 
-			if (thread_flags & _TIF_FOREIGN_FPSTATE)
-				fpsimd_restore_current_state();
-		}
+		if (thread_flags & _TIF_FOREIGN_FPSTATE)
+			fpsimd_restore_current_state();
 
 		local_daif_mask();
 		thread_flags = read_thread_flags();
-- 
2.30.2



From mark.rutland at arm.com  Tue Feb  6 04:38:47 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue,  6 Feb 2024 12:38:47 +0000
Subject: [PATCH 2/3] arm64: Move do_notify_resume() to entry-common.c
In-Reply-To: <20240206123848.1696480-1-mark.rutland@arm.com>
References: <20240206123848.1696480-1-mark.rutland@arm.com>
Message-ID: <20240206123848.1696480-3-mark.rutland@arm.com>

Currently do_notify_resume() lives in arch/arm64/kernel/signal.c, but it would
make more sense for it to live in entry-common.c as it handles more than
signals, and is coupled with the rest of the return-to-userspace sequence (e.g.
with unusual DAIF masking that matches the exception return requirements).

Move do_notify_resume() to entry-common.c.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: James Morse <james.morse at arm.com>
Cc: Mark Brown <broonie at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/exception.h |  2 +-
 arch/arm64/kernel/entry-common.c   | 32 +++++++++++++++++++++++++++
 arch/arm64/kernel/signal.c         | 35 ++----------------------------
 3 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index ad688e157c9be..f296662590c7f 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -74,7 +74,7 @@ void do_el0_fpac(struct pt_regs *regs, unsigned long esr);
 void do_el1_fpac(struct pt_regs *regs, unsigned long esr);
 void do_el0_mops(struct pt_regs *regs, unsigned long esr);
 void do_serror(struct pt_regs *regs, unsigned long esr);
-void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags);
+void do_signal(struct pt_regs *regs);
 
 void __noreturn panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far);
 #endif	/* __ASM_EXCEPTION_H */
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 0fc94207e69a8..3c849ad03bf83 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -10,6 +10,7 @@
 #include <linux/linkage.h>
 #include <linux/lockdep.h>
 #include <linux/ptrace.h>
+#include <linux/resume_user_mode.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
 #include <linux/thread_info.h>
@@ -126,6 +127,37 @@ static __always_inline void __exit_to_user_mode(void)
 	lockdep_hardirqs_on(CALLER_ADDR0);
 }
 
+static void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
+{
+	do {
+		local_daif_restore(DAIF_PROCCTX);
+
+		if (thread_flags & _TIF_NEED_RESCHED)
+			schedule();
+
+		if (thread_flags & _TIF_UPROBE)
+			uprobe_notify_resume(regs);
+
+		if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
+			clear_thread_flag(TIF_MTE_ASYNC_FAULT);
+			send_sig_fault(SIGSEGV, SEGV_MTEAERR,
+				       (void __user *)NULL, current);
+		}
+
+		if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
+			do_signal(regs);
+
+		if (thread_flags & _TIF_NOTIFY_RESUME)
+			resume_user_mode_work(regs);
+
+		if (thread_flags & _TIF_FOREIGN_FPSTATE)
+			fpsimd_restore_current_state();
+
+		local_daif_mask();
+		thread_flags = read_thread_flags();
+	} while (thread_flags & _TIF_WORK_MASK);
+}
+
 static __always_inline void exit_to_user_mode_prepare(struct pt_regs *regs)
 {
 	unsigned long flags;
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 50e108741599d..c08e6465e0f49 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -16,8 +16,8 @@
 #include <linux/uaccess.h>
 #include <linux/sizes.h>
 #include <linux/string.h>
-#include <linux/resume_user_mode.h>
 #include <linux/ratelimit.h>
+#include <linux/rseq.h>
 #include <linux/syscalls.h>
 
 #include <asm/daifflags.h>
@@ -1207,7 +1207,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
  * the kernel can handle, and then we build all the user-level signal handling
  * stack-frames in one go after that.
  */
-static void do_signal(struct pt_regs *regs)
+void do_signal(struct pt_regs *regs)
 {
 	unsigned long continue_addr = 0, restart_addr = 0;
 	int retval = 0;
@@ -1278,37 +1278,6 @@ static void do_signal(struct pt_regs *regs)
 	restore_saved_sigmask();
 }
 
-void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
-{
-	do {
-		local_daif_restore(DAIF_PROCCTX);
-
-		if (thread_flags & _TIF_NEED_RESCHED)
-			schedule();
-
-		if (thread_flags & _TIF_UPROBE)
-			uprobe_notify_resume(regs);
-
-		if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
-			clear_thread_flag(TIF_MTE_ASYNC_FAULT);
-			send_sig_fault(SIGSEGV, SEGV_MTEAERR,
-				       (void __user *)NULL, current);
-		}
-
-		if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
-			do_signal(regs);
-
-		if (thread_flags & _TIF_NOTIFY_RESUME)
-			resume_user_mode_work(regs);
-
-		if (thread_flags & _TIF_FOREIGN_FPSTATE)
-			fpsimd_restore_current_state();
-
-		local_daif_mask();
-		thread_flags = read_thread_flags();
-	} while (thread_flags & _TIF_WORK_MASK);
-}
-
 unsigned long __ro_after_init signal_minsigstksz;
 
 /*
-- 
2.30.2



From mark.rutland at arm.com  Tue Feb  6 04:38:48 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue,  6 Feb 2024 12:38:48 +0000
Subject: [PATCH 3/3] arm64: Unmask Debug + SError in do_notify_resume()
In-Reply-To: <20240206123848.1696480-1-mark.rutland@arm.com>
References: <20240206123848.1696480-1-mark.rutland@arm.com>
Message-ID: <20240206123848.1696480-4-mark.rutland@arm.com>

When returning to a user context, the arm64 entry code masks all DAIF
exceptions before handling pending work in exit_to_user_mode_prepare()
and do_notify_resume(), where it will transiently unmask all DAIF
exceptions. This is a holdover from the old entry assembly, which
conservatively masked all DAIF exceptions, and it's only necessary to
mask interrupts at this point during the exception return path, so long
as we subsequently mask all DAIF exceptions before the actual exception
return.

While most DAIF manipulation follows a save...restore sequence, the
manipulation in do_notify_resume() is the other way around, unmasking
all DAIF exceptions before masking them again. This is unfortunate as we
unnecessarily mask Debug and SError exceptions, and it would be nice to
remove this special case to make DAIF manipulation simpler and most
consistent.

This patch changes exit_to_user_mode_prepare() and do_notify_resume() to
only mask interrupts while handling pending work, masking other DAIF
exceptions after this has completed. This removes the unusual DAIF
manipulation and allows Debug and SError exceptions to be taken for a
slightly longer window during the exception return path.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: James Morse <james.morse at arm.com>
Cc: Mark Brown <broonie at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/entry-common.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 3c849ad03bf83..b77a15955f28b 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -130,7 +130,7 @@ static __always_inline void __exit_to_user_mode(void)
 static void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
 {
 	do {
-		local_daif_restore(DAIF_PROCCTX);
+		local_irq_enable();
 
 		if (thread_flags & _TIF_NEED_RESCHED)
 			schedule();
@@ -153,7 +153,7 @@ static void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
 		if (thread_flags & _TIF_FOREIGN_FPSTATE)
 			fpsimd_restore_current_state();
 
-		local_daif_mask();
+		local_irq_disable();
 		thread_flags = read_thread_flags();
 	} while (thread_flags & _TIF_WORK_MASK);
 }
@@ -162,12 +162,14 @@ static __always_inline void exit_to_user_mode_prepare(struct pt_regs *regs)
 {
 	unsigned long flags;
 
-	local_daif_mask();
+	local_irq_disable();
 
 	flags = read_thread_flags();
 	if (unlikely(flags & _TIF_WORK_MASK))
 		do_notify_resume(regs, flags);
 
+	local_daif_mask();
+
 	lockdep_sys_exit();
 }
 
-- 
2.30.2



From broonie at kernel.org  Tue Feb  6 04:52:21 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 6 Feb 2024 12:52:21 +0000
Subject: [PATCH 2/3] arm64: Move do_notify_resume() to entry-common.c
In-Reply-To: <20240206123848.1696480-3-mark.rutland@arm.com>
References: <20240206123848.1696480-1-mark.rutland@arm.com>
 <20240206123848.1696480-3-mark.rutland@arm.com>
Message-ID: <ZcIrhVjTnms+Nec3@finisterre.sirena.org.uk>

On Tue, Feb 06, 2024 at 12:38:47PM +0000, Mark Rutland wrote:
> Currently do_notify_resume() lives in arch/arm64/kernel/signal.c, but it would
> make more sense for it to live in entry-common.c as it handles more than
> signals, and is coupled with the rest of the return-to-userspace sequence (e.g.
> with unusual DAIF masking that matches the exception return requirements).
> 
> Move do_notify_resume() to entry-common.c.

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/20240206/3347cc0c/attachment.sig>

From marex at denx.de  Tue Feb  6 04:55:17 2024
From: marex at denx.de (Marek Vasut)
Date: Tue,  6 Feb 2024 13:55:17 +0100
Subject: [PATCH v2] arm64: dts: imx8mp: Enable SAI audio on Data Modul i.MX8M Plus eDM SBC
Message-ID: <20240206125541.37959-1-marex@denx.de>

Add SAI I2S and audio bindings to Data Modul i.MX8M Plus eDM SBC.

The SGTL5000 is attached to SAI3, however the SGTL5000 codec MCLK
must be supplied even if the SAI3 is not in use and is controlled
separately by the codec. The MCLK is also used to drive the codec
I2C block, so without MCLK, I2C access to the codec would not be
possible.

To provide such flexible MCLK control, use PWM4 with period 1 and
duty cycle 50% as 12 MHz clock source, as there is no direct way
to route MX8MP CCM clock to the MCLK pin. Use codec as bitclock
and frame clock master, so that the SGTL5000 PLL can be used to
generate derived clock.

Signed-off-by: Marek Vasut <marex at denx.de>
---
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: Fabio Estevam <festevam at gmail.com>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Sascha Hauer <s.hauer at pengutronix.de>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
---
V2: Reorder DT properties
---
 .../freescale/imx8mp-data-modul-edm-sbc.dts   | 64 ++++++++++++++++++-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
index 5828c9d7821de..ef36b7ec65ee1 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
@@ -45,6 +45,19 @@ clk_xtal25: clock-xtal25 {
 		clock-frequency = <25000000>;
 	};
 
+	clk_pwm4: clock-pwm4 {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12000000>;
+		clock-output-names = "codec-pwm4";
+		/*
+		 * 1 / 83 ns ~= 12 MHz , but since the PWM input clock is 24 MHz
+		 * and the calculated PWM period is 1 and duty cycle is 50%, the
+		 * result is exactly 12 MHz, which is fine for SGTL5000 MCLK.
+		 */
+		pwms = <&pwm4 0 83 0>;
+	};
+
 	panel: panel {
 		/* Compatible string is filled in by panel board DT Overlay. */
 		backlight = <&backlight>;
@@ -82,6 +95,24 @@ reg_usdhc2_vmmc: regulator-usdhc2-vmmc {
 		vin-supply = <&buck4>;
 	};
 
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "SGTL5000-Card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&codec_dai>;
+		simple-audio-card,frame-master = <&codec_dai>;
+		simple-audio-card,widgets = "Headphone", "Headphone Jack";
+		simple-audio-card,routing = "Headphone Jack", "HP_OUT";
+
+		cpu_dai: simple-audio-card,cpu {
+			sound-dai = <&sai3>;
+		};
+
+		codec_dai: simple-audio-card,codec {
+			sound-dai = <&sgtl5000>;
+		};
+	};
+
 	watchdog { /* TPS3813 */
 		compatible = "linux,wdt-gpio";
 		pinctrl-names = "default";
@@ -288,6 +319,15 @@ &i2c1 {
 	sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 	status = "okay";
 
+	sgtl5000: audio-codec at a {
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		#sound-dai-cells = <0>;
+		clocks = <&clk_pwm4>;
+		VDDA-supply = <&buck4>;
+		VDDIO-supply = <&buck4>;
+	};
+
 	usb-hub at 2c {
 		compatible = "microchip,usb2514bi";
 		reg = <0x2c>;
@@ -436,6 +476,23 @@ &pwm1 {
 	status = "disabled";
 };
 
+&pwm4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm4>;
+	status = "okay";
+};
+
+&sai3 {
+	#clock-cells = <0>;
+	#sound-dai-cells = <0>;
+	assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
+	assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+	assigned-clock-rates = <12288000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sai3>;
+	status = "okay";
+};
+
 /* SD slot */
 &usdhc2 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz";
@@ -785,6 +842,12 @@ MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x40000090
 		>;
 	};
 
+	pinctrl_pwm4: pwm4-grp {
+		fsl,pins = <
+			MX8MP_IOMUXC_SAI3_MCLK__PWM4_OUT		0xd6
+		>;
+	};
+
 	pinctrl_rtc: rtc-grp {
 		fsl,pins = <
 			/* RTC_IRQ# */
@@ -816,7 +879,6 @@ pinctrl_sai3: sai3-grp {
 			MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC	0xd6
 			MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00	0xd6
 			MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK	0xd6
-			MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI3_MCLK	0xd6
 			MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00	0xd6
 		>;
 	};
-- 
2.43.0



From pabeni at redhat.com  Tue Feb  6 04:57:05 2024
From: pabeni at redhat.com (Paolo Abeni)
Date: Tue, 06 Feb 2024 13:57:05 +0100
Subject: [PATCH net] net: stmmac: xgmac: fix a typo of register name in
 DPP safety handling
In-Reply-To: <Zb49M9fKRR2HeGhR@nanopsycho>
References: <20240203053133.1129236-1-0x1207@gmail.com>
	 <Zb49M9fKRR2HeGhR@nanopsycho>
Message-ID: <1f5fd28c7acaf22e09a8ae41b829ea9ac0a317b5.camel@redhat.com>

On Sat, 2024-02-03 at 14:18 +0100, Jiri Pirko wrote:
> Sat, Feb 03, 2024 at 06:31:33AM CET, 0x1207 at gmail.com wrote:
> > DDPP is copied from Synopsys Data book:
> > 
> > DDPP: Disable Data path Parity Protection.
> >    When it is 0x0, Data path Parity Protection is enabled.
> >    When it is 0x1, Data path Parity Protection is disabled.
> > 
> > The macro name should be XGMAC_DPP_DISABLE.
> > 
> > Fixes: 46eba193d04f ("net: stmmac: xgmac: fix handling of DPP safety error for DMA channels")
> > Signed-off-by: Furong Xu <0x1207 at gmail.com>
> 
> Looks okay, but this is net-next material.

The blamed commit has been applied to net before Serge spotted the typo
during patch review. I think it deserves the net target, so the typo
will never land into vanilla.

Cheers,

Paolo



From dmitry.baryshkov at linaro.org  Tue Feb  6 05:04:10 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 06 Feb 2024 15:04:10 +0200
Subject: [PATCH] ARM: dts: imx53: add support for the HDMI expander
Message-ID: <20240206-imx53-qsb-hdmi-v1-1-e798eb1181c5@linaro.org>

Add support for the MCIMXHDMICARD epansion card attached to the iMX53
QSB / QSRB platforms. This enables HDMI output on those devices.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 arch/arm/boot/dts/nxp/imx/Makefile            |  4 ++
 arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso | 87 +++++++++++++++++++++++++++
 2 files changed, 91 insertions(+)

diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile
index a724d1a7a9a0..24654deba303 100644
--- a/arch/arm/boot/dts/nxp/imx/Makefile
+++ b/arch/arm/boot/dts/nxp/imx/Makefile
@@ -45,7 +45,9 @@ dtb-$(CONFIG_SOC_IMX53) += \
 	imx53-mba53.dtb \
 	imx53-ppd.dtb \
 	imx53-qsb.dtb \
+	imx53-qsb-hdmi.dtb \
 	imx53-qsrb.dtb \
+	imx53-qsrb-hdmi.dtb \
 	imx53-sk-imx53.dtb \
 	imx53-sk-imx53-atm0700d4-lvds.dtb \
 	imx53-sk-imx53-atm0700d4-rgb.dtb \
@@ -54,6 +56,8 @@ dtb-$(CONFIG_SOC_IMX53) += \
 	imx53-tx53-x13x.dtb \
 	imx53-usbarmory.dtb \
 	imx53-voipac-bsb.dtb
+imx53-qsb-hdmi-dtbs := imx53-qsb.dtb imx53-qsb-hdmi.dtbo
+imx53-qsrb-hdmi-dtbs := imx53-qsrb.dtb imx53-qsb-hdmi.dtbo
 dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6dl-alti6p.dtb \
 	imx6dl-apf6dev.dtb \
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso b/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso
new file mode 100644
index 000000000000..c84e9b052527
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * DT overlay for MCIMXHDMICARD as used with the iMX53 QSB or QSRB boards
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	/delete-node/ panel;
+
+	hdmi: connector-hdmi {
+		compatible = "hdmi-connector";
+		label = "hdmi";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&sii9022_out>;
+			};
+		};
+	};
+
+	reg_1p2v: regulator-1p2v {
+		compatible = "regulator-fixed";
+		regulator-name = "1P2V";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-always-on;
+		vin-supply = <&reg_3p2v>;
+	};
+};
+
+&display0 {
+	status = "okay";
+};
+
+&display0 {
+	port at 1 {
+		display0_out: endpoint {
+			remote-endpoint = <&sii9022_in>;
+		};
+	};
+};
+
+&i2c2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	sii9022: bridge-hdmi at 39 {
+		compatible = "sil,sii9022";
+		reg = <0x39>;
+		reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+		interrupts-extended = <&gpio3 31 IRQ_TYPE_LEVEL_LOW>;
+		iovcc-supply = <&reg_3p2v>;
+		#sound-dai-cells = <0>;
+		sil,i2s-data-lanes = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				sii9022_in: endpoint {
+					remote-endpoint = <&display0_out>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				sii9022_out: endpoint {
+					remote-endpoint = <&hdmi_connector_in>;
+				};
+			};
+		};
+	};
+};
+
+&tve {
+	status = "disabled";
+};

---
base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
change-id: 20240206-imx53-qsb-hdmi-a4b6032e061e

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



From patchwork-bot+netdevbpf at kernel.org  Tue Feb  6 05:10:27 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Tue, 06 Feb 2024 13:10:27 +0000
Subject: [PATCH net] net: stmmac: xgmac: fix a typo of register name in DPP
 safety handling
In-Reply-To: <20240203053133.1129236-1-0x1207@gmail.com>
References: <20240203053133.1129236-1-0x1207@gmail.com>
Message-ID: <170722502700.6009.7954883492875206061.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni at redhat.com>:

On Sat,  3 Feb 2024 13:31:33 +0800 you wrote:
> DDPP is copied from Synopsys Data book:
> 
> DDPP: Disable Data path Parity Protection.
>     When it is 0x0, Data path Parity Protection is enabled.
>     When it is 0x1, Data path Parity Protection is disabled.
> 
> The macro name should be XGMAC_DPP_DISABLE.
> 
> [...]

Here is the summary with links:
  - [net] net: stmmac: xgmac: fix a typo of register name in DPP safety handling
    https://git.kernel.org/netdev/net/c/1ce2654d87e2

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From linux at armlinux.org.uk  Tue Feb  6 05:12:33 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 6 Feb 2024 13:12:33 +0000
Subject: [PATCH net-next v2 6/6] net: dsa: b53: remove
 eee_enabled/eee_active in b53_get_mac_eee()
In-Reply-To: <20240206112024.3jxtcru3dupeirnj@skbuf>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
 <E1rWbNI-002cCz-4x@rmk-PC.armlinux.org.uk>
 <20240206112024.3jxtcru3dupeirnj@skbuf>
Message-ID: <ZcIwQcn3qlk0UjS4@shell.armlinux.org.uk>

On Tue, Feb 06, 2024 at 01:20:24PM +0200, Vladimir Oltean wrote:
> On Sun, Feb 04, 2024 at 12:13:28PM +0000, Russell King (Oracle) wrote:
> > b53_get_mac_eee() sets both eee_enabled and eee_active, and then
> > returns zero.
> > 
> > dsa_slave_get_eee(), which calls this function, will then continue to
> > call phylink_ethtool_get_eee(), which will return -EOPNOTSUPP if there
> > is no PHY present, otherwise calling phy_ethtool_get_eee() which in
> > turn will call genphy_c45_ethtool_get_eee().
> 
> Nitpick: If you need to resend, the function name changed to
> dsa_user_get_eee().

Thanks.

> > @@ -2227,16 +2227,10 @@ EXPORT_SYMBOL(b53_eee_init);
> >  int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e)
> >  {
> >  	struct b53_device *dev = ds->priv;
> > -	struct ethtool_keee *p = &dev->ports[port].eee;
> > -	u16 reg;
> >  
> >  	if (is5325(dev) || is5365(dev))
> >  		return -EOPNOTSUPP;
> >  
> > -	b53_read16(dev, B53_EEE_PAGE, B53_EEE_LPI_INDICATE, &reg);
> > -	e->eee_enabled = p->eee_enabled;
> > -	e->eee_active = !!(reg & BIT(port));
> > -
> 
> I know next to nothing about EEE and especially the implementation on
> Broadcom switches. But is the information brought by B53_EEE_LPI_INDICATE
> completely redundant? Is it actually in the system's best interest to
> ignore it?

That's a review comment that should have been made when the original
change to phylib was done, because it's already ignored in kernels
today since the commit changing phylib that I've referenced in this
series - since e->eee_enabled and e->eee_active will be overwritten by
phylib.

If we need B53_EEE_LPI_INDICATE to do something, then we need to have
a discussion about it, and decide how that fits in with the EEE
interface, and how to work around phylib's implementation.

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


From neil.armstrong at linaro.org  Tue Feb  6 05:13:52 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Tue, 6 Feb 2024 14:13:52 +0100
Subject: [PATCH v3 09/20] drivers: crypto: meson: process more than
 MAXDESCS descriptors
In-Reply-To: <20240205155521.1795552-10-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
 <20240205155521.1795552-10-avromanov@salutedevices.com>
Message-ID: <99a9dd91-9e83-4ca2-93c6-a4de8616e64d@linaro.org>

Hi,

On 05/02/2024 16:55, Alexey Romanov wrote:
> 1. The old alhorithm was not designed to process a large
> amount of memory, and therefore gave incorrect results.
> 
> 2. Not all Amlogic SoC's use 3 KEY/IV descriptors.
> Add keyiv descriptors count parameter to platform data.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   drivers/crypto/amlogic/amlogic-gxl-cipher.c | 443 ++++++++++++--------
>   drivers/crypto/amlogic/amlogic-gxl-core.c   |   1 +
>   drivers/crypto/amlogic/amlogic-gxl.h        |   2 +
>   3 files changed, 281 insertions(+), 165 deletions(-)
> 
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index c662c4b86e97..9c96e7b65e1e 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -17,35 +17,41 @@
>   #include <crypto/internal/skcipher.h>
>   #include "amlogic-gxl.h"
>   
> -static bool meson_cipher_need_fallback(struct skcipher_request *areq)
> +static bool meson_cipher_need_fallback_sg(struct skcipher_request *areq,
> +					  struct scatterlist *sg)
>   {
> -	struct scatterlist *src_sg = areq->src;
> -	struct scatterlist *dst_sg = areq->dst;
> +	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
> +	unsigned int blocksize = crypto_skcipher_blocksize(tfm);
> +	unsigned int cryptlen = areq->cryptlen;
> +
> +	while (cryptlen) {
> +		unsigned int len = min(cryptlen, sg->length);
> +
> +		if (!IS_ALIGNED(sg->offset, sizeof(u32)))
> +			return true;
> +		if (len % blocksize != 0)
> +			return true;
> +
> +		cryptlen -= len;
> +		sg = sg_next(sg);
> +	}
> +
> +	return false;
> +}
>   
> +static bool meson_cipher_need_fallback(struct skcipher_request *areq)
> +{
>   	if (areq->cryptlen == 0)
>   		return true;
>   
> -	if (sg_nents(src_sg) != sg_nents(dst_sg))
> +	if (meson_cipher_need_fallback_sg(areq, areq->src))
>   		return true;
>   
> -	/* KEY/IV descriptors use 3 desc */
> -	if (sg_nents(src_sg) > MAXDESC - 3 || sg_nents(dst_sg) > MAXDESC - 3)
> -		return true;
> +	if (areq->dst == areq->src)
> +		return false;
>   
> -	while (src_sg && dst_sg) {
> -		if ((src_sg->length % 16) != 0)
> -			return true;
> -		if ((dst_sg->length % 16) != 0)
> -			return true;
> -		if (src_sg->length != dst_sg->length)
> -			return true;
> -		if (!IS_ALIGNED(src_sg->offset, sizeof(u32)))
> -			return true;
> -		if (!IS_ALIGNED(dst_sg->offset, sizeof(u32)))
> -			return true;
> -		src_sg = sg_next(src_sg);
> -		dst_sg = sg_next(dst_sg);
> -	}
> +	if (meson_cipher_need_fallback_sg(areq, areq->dst))
> +		return true;
>   
>   	return false;
>   }
> @@ -76,6 +82,211 @@ static int meson_cipher_do_fallback(struct skcipher_request *areq)
>   	return err;
>   }
>   
> +struct cipher_ctx {
> +	struct {
> +		dma_addr_t addr;
> +		unsigned int len;
> +	} keyiv;
> +
> +	struct skcipher_request *areq;
> +	struct scatterlist *src_sg;
> +	struct scatterlist *dst_sg;
> +
> +	unsigned int src_offset;
> +	unsigned int dst_offset;
> +	unsigned int cryptlen;
> +	unsigned int tloffset;
> +};
> +
> +static int meson_map_scatterlist(struct skcipher_request *areq, struct meson_dev *mc)
> +{
> +	int nr_sgs, nr_sgd;
> +
> +	if (areq->src == areq->dst) {
> +		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
> +							DMA_BIDIRECTIONAL);
> +		if (!nr_sgs) {
> +			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
> +			return -EINVAL;
> +		}
> +	} else {
> +		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
> +							DMA_TO_DEVICE);
> +		if (!nr_sgs) {
> +			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
> +			return -EINVAL;
> +		}
> +
> +		nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
> +							DMA_FROM_DEVICE);
> +		if (!nr_sgd) {
> +			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static void meson_unmap_scatterlist(struct skcipher_request *areq, struct meson_dev *mc)
> +{
> +	if (areq->src == areq->dst) {
> +		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL);
> +	} else {
> +		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
> +		dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE);
> +	}
> +}
> +
> +static void meson_setup_keyiv_descs(struct cipher_ctx *ctx)
> +{
> +	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
> +	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
> +	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
> +	struct meson_alg_template *algt = container_of(alg,
> +		struct meson_alg_template, alg.skcipher.base);
> +	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
> +	struct meson_dev *mc = op->mc;
> +	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
> +	unsigned int blockmode = algt->blockmode;
> +	int i;
> +
> +	if (ctx->tloffset)
> +		return;
> +
> +	if (blockmode == DESC_OPMODE_CBC) {
> +		memcpy(op->key + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
> +		ctx->keyiv.len = AES_MAX_KEY_SIZE + ivsize;
> +		dma_sync_single_for_device(mc->dev, ctx->keyiv.addr,
> +					   ctx->keyiv.len, DMA_TO_DEVICE);
> +	}
> +
> +	for (i = 0; i < mc->pdata->setup_desc_cnt; i++) {
> +		struct meson_desc *desc =
> +			&mc->chanlist[rctx->flow].tl[ctx->tloffset];
> +		int offset = i * 16;
> +
> +		desc->t_src = cpu_to_le32(ctx->keyiv.addr + offset);
> +		desc->t_dst = cpu_to_le32(offset);
> +		desc->t_status = cpu_to_le32(DESC_OWN | DESC_MODE_KEY | ctx->keyiv.len);
> +
> +		ctx->tloffset++;
> +	}
> +}
> +
> +static bool meson_setup_data_descs(struct cipher_ctx *ctx)
> +{
> +	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
> +	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
> +	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
> +	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
> +	struct meson_alg_template *algt = container_of(alg,
> +						       struct meson_alg_template,
> +						       alg.skcipher.base);
> +	struct meson_dev *mc = op->mc;
> +	struct meson_desc *desc = &mc->chanlist[rctx->flow].tl[ctx->tloffset];
> +	unsigned int blocksize = crypto_skcipher_blocksize(tfm);
> +	unsigned int blockmode = algt->blockmode;
> +	unsigned int maxlen = rounddown(DESC_MAXLEN, blocksize);
> +	unsigned int todo;
> +	u32 v;
> +
> +	ctx->tloffset++;
> +
> +	todo = min(ctx->cryptlen, maxlen);
> +	todo = min(todo, ctx->cryptlen);
> +	todo = min(todo, sg_dma_len(ctx->src_sg) - ctx->src_offset);
> +	todo = min(todo, sg_dma_len(ctx->dst_sg) - ctx->dst_offset);
> +
> +	desc->t_src = cpu_to_le32(sg_dma_address(ctx->src_sg) + ctx->src_offset);
> +	desc->t_dst = cpu_to_le32(sg_dma_address(ctx->dst_sg) + ctx->dst_offset);
> +
> +	ctx->cryptlen -= todo;
> +	ctx->src_offset += todo;
> +	ctx->dst_offset += todo;
> +
> +	v = DESC_OWN | blockmode | op->keymode | todo;
> +	if (rctx->op_dir == MESON_ENCRYPT)
> +		v |= DESC_ENCRYPTION;
> +
> +	if (!ctx->cryptlen || ctx->tloffset == MAXDESC)
> +		v |= DESC_LAST;
> +
> +	desc->t_status = cpu_to_le32(v);
> +
> +	return v & DESC_LAST;
> +}
> +
> +static int meson_kick_hardware(struct cipher_ctx *ctx)
> +{
> +	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
> +	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
> +	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
> +	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
> +	struct meson_alg_template *algt = container_of(alg,
> +						       struct meson_alg_template,
> +						       alg.skcipher.base);
> +	struct meson_dev *mc = op->mc;
> +	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
> +	unsigned int blockmode = algt->blockmode;
> +	enum dma_data_direction new_iv_dir;
> +	dma_addr_t new_iv_phys;
> +	void *new_iv;
> +	int err;
> +
> +	if (blockmode == DESC_OPMODE_CBC) {
> +		struct scatterlist *sg;
> +		unsigned int offset;
> +
> +		if (rctx->op_dir == MESON_ENCRYPT) {
> +			sg = ctx->dst_sg;
> +			offset = ctx->dst_offset;
> +			new_iv_dir = DMA_FROM_DEVICE;
> +		} else {
> +			sg = ctx->src_sg;
> +			offset = ctx->src_offset;
> +			new_iv_dir = DMA_TO_DEVICE;
> +		}
> +
> +		if (ctx->areq->src == ctx->areq->dst)
> +			new_iv_dir = DMA_BIDIRECTIONAL;
> +
> +		offset -= ivsize;
> +		new_iv = sg_virt(sg) + offset;
> +		new_iv_phys = sg_dma_address(sg) + offset;
> +	}
> +
> +	if (blockmode == DESC_OPMODE_CBC &&
> +		rctx->op_dir == MESON_DECRYPT) {
> +		dma_sync_single_for_cpu(mc->dev, new_iv_phys,
> +					ivsize, new_iv_dir);
> +		memcpy(ctx->areq->iv, new_iv, ivsize);
> +	}
> +
> +	reinit_completion(&mc->chanlist[rctx->flow].complete);
> +	meson_dma_start(mc, rctx->flow);
> +	err = wait_for_completion_interruptible_timeout(
> +			&mc->chanlist[rctx->flow].complete, msecs_to_jiffies(500));
> +	if (err == 0) {
> +		dev_err(mc->dev, "DMA timeout for flow %d\n", rctx->flow);
> +		return -EINVAL;
> +	} else if (err < 0) {
> +		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
> +		return err;
> +	}
> +
> +	if (blockmode == DESC_OPMODE_CBC &&
> +		rctx->op_dir == MESON_ENCRYPT) {
> +		dma_sync_single_for_cpu(mc->dev, new_iv_phys,
> +					ivsize, new_iv_dir);
> +		memcpy(ctx->areq->iv, new_iv, ivsize);
> +	}
> +
> +	ctx->tloffset = 0;
> +
> +	return 0;
> +}
> +
>   static int meson_cipher(struct skcipher_request *areq)
>   {
>   	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
> @@ -84,176 +295,78 @@ static int meson_cipher(struct skcipher_request *areq)
>   	struct meson_dev *mc = op->mc;
>   	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
>   	struct meson_alg_template *algt;
> -	int flow = rctx->flow;
> -	unsigned int todo, eat, len;
> -	struct scatterlist *src_sg = areq->src;
> -	struct scatterlist *dst_sg = areq->dst;
> -	struct meson_desc *desc;
> -	int nr_sgs, nr_sgd;
> -	int i, err = 0;
> -	unsigned int keyivlen, ivsize, offset, tloffset;
> -	dma_addr_t phykeyiv;
> -	void *backup_iv = NULL, *bkeyiv;
> -	u32 v;
> -
> -	algt = container_of(alg, struct meson_alg_template, alg.skcipher.base);
> +	struct cipher_ctx ctx = {
> +		.areq = areq,
> +		.src_offset = 0,
> +		.dst_offset = 0,
> +		.src_sg = areq->src,
> +		.dst_sg = areq->dst,
> +		.cryptlen = areq->cryptlen,
> +	};
> +	unsigned int ivsize = crypto_skcipher_ivsize(tfm);

I'm getting build errors with W=1 build:

drivers/crypto/amlogic/amlogic-gxl-cipher.c:306:22: error: unused variable ?ivsize? [-Werror=unused-variable]
   306 |         unsigned int ivsize = crypto_skcipher_ivsize(tfm);
       |                      ^~~~~~

> +	int err;
>   
> -	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u flow=%d\n", __func__,
> +	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u ctx.flow=%d\n", __func__,
>   		crypto_tfm_alg_name(areq->base.tfm),
>   		areq->cryptlen,
>   		rctx->op_dir, crypto_skcipher_ivsize(tfm),
> -		op->keylen, flow);
> +		op->keylen, rctx->flow);
> +
> +	algt = container_of(alg, struct meson_alg_template, alg.skcipher.base);
>   
>   #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
>   	algt->stat_req++;
> -	mc->chanlist[flow].stat_req++;
> +	mc->chanlist[rctx->flow].stat_req++;
>   #endif
>   
> -	/*
> -	 * The hardware expect a list of meson_desc structures.
> -	 * The 2 first structures store key
> -	 * The third stores IV
> -	 */
> -	bkeyiv = kzalloc(48, GFP_KERNEL | GFP_DMA);
> -	if (!bkeyiv)
> +	op->key = kzalloc(48, GFP_KERNEL | GFP_DMA);
> +	if (!op.key)
>   		return -ENOMEM;

drivers/crypto/amlogic/amlogic-gxl-cipher.c: In function ?meson_cipher?:
drivers/crypto/amlogic/amlogic-gxl-cipher.c:323:16: error: ?op? is a pointer; did you mean to use ?->??
   323 |         if (!op.key)
       |                ^

>   
> -	memcpy(bkeyiv, op->key, op->keylen);
> -	keyivlen = op->keylen;
> +	memcpy(op->key, op->key, op->keylen);
> +	ctx.keyiv.len = op->keylen;
> +	if (ctx.keyiv.len == AES_KEYSIZE_192)
> +		ctx.keyiv.len = AES_MAX_KEY_SIZE;
>   
> -	ivsize = crypto_skcipher_ivsize(tfm);
> -	if (areq->iv && ivsize > 0) {
> -		if (ivsize > areq->cryptlen) {
> -			dev_err(mc->dev, "invalid ivsize=%d vs len=%d\n", ivsize, areq->cryptlen);
> -			err = -EINVAL;
> -			goto theend;
> -		}
> -		memcpy(bkeyiv + 32, areq->iv, ivsize);
> -		keyivlen = 48;
> -		if (rctx->op_dir == MESON_DECRYPT) {
> -			backup_iv = kzalloc(ivsize, GFP_KERNEL);
> -			if (!backup_iv) {
> -				err = -ENOMEM;
> -				goto theend;
> -			}
> -			offset = areq->cryptlen - ivsize;
> -			scatterwalk_map_and_copy(backup_iv, areq->src, offset,
> -						 ivsize, 0);
> -		}
> -	}
> -	if (keyivlen == AES_KEYSIZE_192)
> -		keyivlen = AES_MAX_KEY_SIZE;
> -
> -	phykeyiv = dma_map_single(mc->dev, bkeyiv, keyivlen,
> +	ctx.keyiv.addr = dma_map_single(mc->dev, op->key, ctx.keyiv.len,
>   				  DMA_TO_DEVICE);
> -	err = dma_mapping_error(mc->dev, phykeyiv);
> +	err = dma_mapping_error(mc->dev, ctx.keyiv.addr);
>   	if (err) {
>   		dev_err(mc->dev, "Cannot DMA MAP KEY IV\n");
>   		goto theend;
>   	}
>   
> -	tloffset = 0;
> -	eat = 0;
> -	i = 0;
> -	while (keyivlen > eat) {
> -		desc = &mc->chanlist[flow].tl[tloffset];
> -		memset(desc, 0, sizeof(struct meson_desc));
> -		todo = min(keyivlen - eat, 16u);
> -		desc->t_src = cpu_to_le32(phykeyiv + i * 16);
> -		desc->t_dst = cpu_to_le32(i * 16);
> -		v = DESC_MODE_KEY | DESC_OWN | 16;
> -		desc->t_status = cpu_to_le32(v);
> -
> -		eat += todo;
> -		i++;
> -		tloffset++;
> -	}
> -
> -	if (areq->src == areq->dst) {
> -		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
> -				    DMA_BIDIRECTIONAL);
> -		if (!nr_sgs) {
> -			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
> -			err = -EINVAL;
> -			goto theend;
> -		}
> -		nr_sgd = nr_sgs;
> -	} else {
> -		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
> -				    DMA_TO_DEVICE);
> -		if (!nr_sgs || nr_sgs > MAXDESC - 3) {
> -			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
> -			err = -EINVAL;
> -			goto theend;
> -		}
> -		nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
> -				    DMA_FROM_DEVICE);
> -		if (!nr_sgd || nr_sgd > MAXDESC - 3) {
> -			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
> -			err = -EINVAL;
> -			goto theend;
> -		}
> -	}
> -
> -	src_sg = areq->src;
> -	dst_sg = areq->dst;
> -	len = areq->cryptlen;
> -	while (src_sg) {
> -		desc = &mc->chanlist[flow].tl[tloffset];
> -		memset(desc, 0, sizeof(struct meson_desc));
> -
> -		desc->t_src = cpu_to_le32(sg_dma_address(src_sg));
> -		desc->t_dst = cpu_to_le32(sg_dma_address(dst_sg));
> -		todo = min(len, sg_dma_len(src_sg));
> -		v = op->keymode | DESC_OWN | todo | algt->blockmode;
> -		if (rctx->op_dir)
> -			v |= DESC_ENCRYPTION;
> -		len -= todo;
> -
> -		if (!sg_next(src_sg))
> -			v |= DESC_LAST;
> -		desc->t_status = cpu_to_le32(v);
> -		tloffset++;
> -		src_sg = sg_next(src_sg);
> -		dst_sg = sg_next(dst_sg);
> -	}
> +	err = meson_map_scatterlist(areq, mc);
> +	if (err)
> +		goto theend;
>   
> -	reinit_completion(&mc->chanlist[flow].complete);
> -	meson_dma_start(mc, flow);
> +	ctx.tloffset = 0;
>   
> -	err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
> -							msecs_to_jiffies(500));
> -	if (err == 0) {
> -		dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
> -		err = -EINVAL;
> -	} else if (err < 0) {
> -		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
> -	} else {
> -		/* No error */
> -		err = 0;
> -	}
> +	while (ctx.cryptlen) {
> +		meson_setup_keyiv_descs(&ctx);
>   
> -	dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
> +		if (meson_setup_data_descs(&ctx)) {
> +			err = meson_kick_hardware(&ctx);
> +			if (err)
> +				break;
> +		}
>   
> -	if (areq->src == areq->dst) {
> -		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL);
> -	} else {
> -		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
> -		dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE);
> -	}
> +		if (ctx.src_offset == sg_dma_len(ctx.src_sg)) {
> +			ctx.src_offset = 0;
> +			ctx.src_sg = sg_next(ctx.src_sg);
> +		}
>   
> -	if (areq->iv && ivsize > 0) {
> -		if (rctx->op_dir == MESON_DECRYPT) {
> -			memcpy(areq->iv, backup_iv, ivsize);
> -		} else {
> -			scatterwalk_map_and_copy(areq->iv, areq->dst,
> -						 areq->cryptlen - ivsize,
> -						 ivsize, 0);
> +		if (ctx.dst_offset == sg_dma_len(ctx.dst_sg)) {
> +			ctx.dst_offset = 0;
> +			ctx.dst_sg = sg_next(ctx.dst_sg);
>   		}
>   	}
> +
> +	dma_unmap_single(mc->dev, ctx.keyiv.addr, ctx.keyiv.len, DMA_TO_DEVICE);
> +	meson_unmap_scatterlist(areq, mc);
> +
>   theend:
> -	kfree_sensitive(bkeyiv);
> -	kfree_sensitive(backup_iv);
> +	kfree_sensitive(op->key);
>   
>   	return err;
>   }
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 22ff2768b5e5..f93e14f5717d 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -199,6 +199,7 @@ static const struct meson_pdata meson_gxl_pdata = {
>   	.descs_reg = 0x0,
>   	.status_reg = 0x4,
>   	.need_clk = true,
> +	.setup_desc_cnt = 3,
>   };
>   
>   static const struct of_device_id meson_crypto_of_match_table[] = {
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index a0d83c82906d..eb2f8cd72b65 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -83,11 +83,13 @@ struct meson_flow {
>    * @reg_descs:	offset to descriptors register
>    * @reg_status:	offset to status register
>    * @need_clk:	clock input is needed
> + * @setup_desc_cnt:	number of setup descriptor to configure.
>    */
>   struct meson_pdata {
>   	u32 descs_reg;
>   	u32 status_reg;
>   	bool need_clk;
> +	u32 setup_desc_cnt;
>   };
>   
>   /*

Thanks,
Neil



From nm at ti.com  Tue Feb  6 05:14:20 2024
From: nm at ti.com (Nishanth Menon)
Date: Tue, 6 Feb 2024 07:14:20 -0600
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240206104357.3803517-1-u-kumar1@ti.com>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
Message-ID: <20240206131420.wtitflgav23jto2q@verbally>

On 16:13-20240206, Udit Kumar wrote:
> Most of clocks and their parents are defined in contiguous range,
> But in few cases, there is gap in clock numbers[0].
> Driver assumes clocks to be in contiguous range, and add their clock
> ids incrementally.
> 
> New firmware started returning error while calling get_freq and is_on
> API for non-available clock ids.
> 
> In this fix, driver checks and adds only valid clock ids.
> 
> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
> 
> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> Section Clocks for NAVSS0_CPTS_0 Device,
> clock id 12-15 not present.
> 
> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
> ---
> Changelog
> 
> Changes in v2
> - Updated commit message
> - Simplified logic for valid clock id
> link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/
> 
> 
> P.S
> Firmawre returns total num_parents count including non available ids.
> For above device id NAVSS0_CPTS_0, number of parents clocks are 16
> i.e from id 2 to 17. But out of these ids few are not valid.
> So driver adds only valid clock ids out ot total.
> 
> Original logs
> https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
> Line 2630 for error
> 
> Logs with fix v2
> https://gist.github.com/uditkumarti/94e3e28d62282fd708dbfe37435ce1d9
> Line 2591
> 
> 
>  drivers/clk/keystone/sci-clk.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> index 35fe197dd303..ff249cbd54a1 100644
> --- a/drivers/clk/keystone/sci-clk.c
> +++ b/drivers/clk/keystone/sci-clk.c
> @@ -517,6 +517,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  	int num_clks = 0;
>  	int num_parents;
>  	int clk_id;
> +	u64 freq;
>  	const char * const clk_names[] = {
>  		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
>  	};
> @@ -586,16 +587,23 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  				clk_id = args.args[1] + 1;
>  
>  				while (num_parents--) {
> +					/* Check if this clock id is valid */
> +					ret = provider->ops->get_freq(provider->sci,
> +						sci_clk->dev_id, clk_id, &freq);

get_freq is a bit expensive as it has to walk the clock tree to find
the clock frequency (at least the first time?). just wondering if
there is lighter alternative here?

> +
> +					clk_id++;
> +					if (ret)
> +						continue;
> +
>  					sci_clk = devm_kzalloc(dev,
>  							       sizeof(*sci_clk),
>  							       GFP_KERNEL);
>  					if (!sci_clk)
>  						return -ENOMEM;
>  					sci_clk->dev_id = args.args[0];
> -					sci_clk->clk_id = clk_id++;
> +					sci_clk->clk_id = clk_id - 1;
>  					sci_clk->provider = provider;
>  					list_add_tail(&sci_clk->node, &clks);
> -
	Spurious change.
>  					num_clks++;
>  				}
>  			}
> -- 
> 2.34.1
> 

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From angelogioacchino.delregno at collabora.com  Tue Feb  6 05:27:11 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 14:27:11 +0100
Subject: [PATCH v3 1/7] drm/mediatek: dsi: Use GENMASK() for register mask
 definitions
In-Reply-To: <082bc4d9efd0746d7ec25eab0b3bf96018e997e5.camel@mediatek.com>
References: <20240131113434.241929-1-angelogioacchino.delregno@collabora.com>
 <20240131113434.241929-2-angelogioacchino.delregno@collabora.com>
 <082bc4d9efd0746d7ec25eab0b3bf96018e997e5.camel@mediatek.com>
Message-ID: <4fe9947f-b190-4dcc-8d1e-f532e6dcb827@collabora.com>

Il 06/02/24 09:57, CK Hu (???) ha scritto:
> Hi, Angelo:
> 
> On Wed, 2024-01-31 at 12:34 +0100, AngeloGioacchino Del Regno wrote:
>> Change magic numerical masks with usage of the GENMASK() macro
>> to improve readability.
>>
>> While at it, also fix the DSI_PS_SEL mask to include all bits instead
>> of just a subset of them.
>>
>> This commit brings no functional changes.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <
>> angelogioacchino.delregno at collabora.com>
>> ---
>>   drivers/gpu/drm/mediatek/mtk_dsi.c | 45 +++++++++++++++-------------
>> --
>>   1 file changed, 23 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> index a2fdfc8ddb15..3b7392c03b4d 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> @@ -58,18 +58,18 @@
>>   
>>   #define DSI_TXRX_CTRL		0x18
>>   #define VC_NUM				BIT(1)
>> -#define LANE_NUM			(0xf << 2)
>> +#define LANE_NUM			GENMASK(5, 2)
>>   #define DIS_EOT				BIT(6)
>>   #define NULL_EN				BIT(7)
>>   #define TE_FREERUN			BIT(8)
>>   #define EXT_TE_EN			BIT(9)
>>   #define EXT_TE_EDGE			BIT(10)
>> -#define MAX_RTN_SIZE			(0xf << 12)
>> +#define MAX_RTN_SIZE			GENMASK(15, 12)
>>   #define HSTX_CKLP_EN			BIT(16)
>>   
>>   #define DSI_PSCTRL		0x1c
>> -#define DSI_PS_WC			0x3fff
>> -#define DSI_PS_SEL			(3 << 16)
>> +#define DSI_PS_WC			GENMASK(14, 0)
>> +#define DSI_PS_SEL			GENMASK(19, 16)
> 
> The original definition of DSI_PS_WC/DSI_PS_SEL is correct in MT8173.
> So both need two definition and let each SoC select its own definition.
> 

The additional bits are unused on older SoCs and, if set, will be simply ignored;
if we want to prevent setting bits that don't exist on the old ones, that should
be done as a later commit introducing SoC capabilities for those and when the new
capabilities for the new SoCs are introduced anyway.

As of now, this doesn't break anything.

Regards,
Angelo




From olteanv at gmail.com  Tue Feb  6 05:29:23 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 6 Feb 2024 15:29:23 +0200
Subject: [PATCH net-next v2 6/6] net: dsa: b53: remove
 eee_enabled/eee_active in b53_get_mac_eee()
In-Reply-To: <ZcIwQcn3qlk0UjS4@shell.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
 <E1rWbNI-002cCz-4x@rmk-PC.armlinux.org.uk>
 <20240206112024.3jxtcru3dupeirnj@skbuf>
 <ZcIwQcn3qlk0UjS4@shell.armlinux.org.uk>
Message-ID: <20240206132923.eypnqvqwe3cga5tp@skbuf>

On Tue, Feb 06, 2024 at 01:12:33PM +0000, Russell King (Oracle) wrote:
> > I know next to nothing about EEE and especially the implementation on
> > Broadcom switches. But is the information brought by B53_EEE_LPI_INDICATE
> > completely redundant? Is it actually in the system's best interest to
> > ignore it?
> 
> That's a review comment that should have been made when the original
> change to phylib was done, because it's already ignored in kernels
> today since the commit changing phylib that I've referenced in this
> series - since e->eee_enabled and e->eee_active will be overwritten by
> phylib.

That's fair, but commit d1420bb99515 ("net: phy: improve generic EEE
ethtool functions") is dated November 2018, and my involvement with the
kernel started in March 2019. So it would have been a bit difficult for
me to make this observation back then.

> If we need B53_EEE_LPI_INDICATE to do something, then we need to have
> a discussion about it, and decide how that fits in with the EEE
> interface, and how to work around phylib's implementation.

Hopefully Florian or Doug can quickly clarify whether this is the case
or not.


From laurent.pinchart at ideasonboard.com  Tue Feb  6 05:31:22 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 6 Feb 2024 15:31:22 +0200
Subject: [PATCH 1/4] gpu: drm: replace of_graph_get_next_endpoint()
In-Reply-To: <87sf26nvy2.wl-kuninori.morimoto.gx@renesas.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
 <87sf26nvy2.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <20240206133122.GA2827@pendragon.ideasonboard.com>

Hello Morimoto-san,

Thank you for the patch.

On Tue, Feb 06, 2024 at 02:55:01AM +0000, Kuninori Morimoto wrote:
> From DT point of view, in general, drivers should be asking for a
> specific port number because their function is fixed in the binding.
> 
> of_graph_get_next_endpoint() doesn't match to this concept.
> 
> Simply replace
> 
> 	- of_graph_get_next_endpoint(xxx, NULL);
> 	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);
> 
> Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
> ---
>  drivers/gpu/drm/drm_of.c                              | 2 +-
>  drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c | 2 +-
>  drivers/gpu/drm/tiny/arcpgu.c                         | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> index 177b600895d3..c2eae9296012 100644
> --- a/drivers/gpu/drm/drm_of.c
> +++ b/drivers/gpu/drm/drm_of.c
> @@ -516,7 +516,7 @@ struct mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev)
>  	/*
>  	 * Get first endpoint child from device.
>  	 */
> -	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);

This assumes that the DSI device's port at 0 will also be the input. That's
fine for current users of this function, but we should at least document
it.

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 177b600895d3..012c4d04cf51 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -504,6 +504,8 @@ EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep);
  * Gets parent DSI bus for a DSI device controlled through a bus other
  * than MIPI-DCS (SPI, I2C, etc.) using the Device Tree.
  *
+ * This function assumes that the device's port at 0 is the DSI input.
+ *
  * Returns pointer to mipi_dsi_host if successful, -EINVAL if the
  * request is unsupported, -EPROBE_DEFER if the DSI host is found but
  * not available, or -ENODEV otherwise.

With this,

Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>

>  	if (!endpoint)
>  		return ERR_PTR(-ENODEV);
>  
> diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> index 4618c892cdd6..e10e469aa7a6 100644
> --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
> @@ -400,7 +400,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c)
>  	rpi_touchscreen_i2c_write(ts, REG_POWERON, 0);
>  
>  	/* Look up the DSI host.  It needs to probe before we do. */
> -	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
>  	if (!endpoint)
>  		return -ENODEV;
>  
> diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c
> index e5b10e41554a..04d0053b9315 100644
> --- a/drivers/gpu/drm/tiny/arcpgu.c
> +++ b/drivers/gpu/drm/tiny/arcpgu.c
> @@ -288,7 +288,7 @@ static int arcpgu_load(struct arcpgu_drm_private *arcpgu)
>  	 * There is only one output port inside each device. It is linked with
>  	 * encoder endpoint.
>  	 */
> -	endpoint_node = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
> +	endpoint_node = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 0, -1);
>  	if (endpoint_node) {
>  		encoder_node = of_graph_get_remote_port_parent(endpoint_node);
>  		of_node_put(endpoint_node);

-- 
Regards,

Laurent Pinchart


From angelogioacchino.delregno at collabora.com  Tue Feb  6 05:33:10 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 14:33:10 +0100
Subject: [PATCH 1/3] drm/mediatek: Dynamically allocate CMDQ and use
 helper functions
In-Reply-To: <7175ec117988657c2fb7bf6d50b67d60038e3a54.camel@mediatek.com>
References: <20230623094931.117918-1-angelogioacchino.delregno@collabora.com>
 <20230623094931.117918-2-angelogioacchino.delregno@collabora.com>
 <bd19faf644fa80f8fa77ed0841a724aa3ca871f5.camel@mediatek.com>
 <0acd286d-d4f4-97b2-c296-b2860a00def6@collabora.com>
 <e8e60556e53ccf319358cbef203bc84c418a352b.camel@mediatek.com>
 <d29d342b-37f4-8d7b-ed7d-c441cc928393@collabora.com>
 <7175ec117988657c2fb7bf6d50b67d60038e3a54.camel@mediatek.com>
Message-ID: <072f049a-021f-4f39-81ff-d3cba1e6c47c@collabora.com>

Il 03/08/23 10:37, CK Hu (???) ha scritto:
> Hi, Angelo:
> 
> On Thu, 2023-08-03 at 10:25 +0200, AngeloGioacchino Del Regno wrote:
>> Il 03/08/23 08:28, CK Hu (???) ha scritto:
>>> Hi, Angelo:
>>>
>>> On Wed, 2023-08-02 at 12:41 +0200, AngeloGioacchino Del Regno
>>> wrote:
>>>> Il 02/08/23 08:24, CK Hu (???) ha scritto:
>>>>> Hi, Angelo:
>>>>>
>>>>> On Fri, 2023-06-23 at 11:49 +0200, AngeloGioacchino Del Regno
>>>>> wrote:
>>>>>>     	
>>>>>> External email : Please do not click links or open
>>>>>> attachments
>>>>>> until
>>>>>> you have verified the sender or the content.
>>>>>>     Instead of stack allocating the cmdq_client and
>>>>>> cmdq_handle
>>>>>> structures
>>>>>> switch them to pointers, allowing us to migrate this driver
>>>>>> to
>>>>>> use
>>>>>> the
>>>>>> common functions provided by mtk-cmdq-helper.
>>>>>> In order to do this, it was also necessary to add a `priv`
>>>>>> pointer to
>>>>>> struct cmdq_client, as that's used to pass (in this case) a
>>>>>> mtk_crtc
>>>>>> handle to the ddp_cmdq_cb() mailbox RX callback function.
>>>>>>
>>>>>> Signed-off-by: AngeloGioacchino Del Regno <
>>>>>> angelogioacchino.delregno at collabora.com>
>>>>>> ---
>>>>>>     drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 107 +++++++-----
>>>>>> ---
>>>>>> -------
>>>>>> --
>>>>>>     include/linux/soc/mediatek/mtk-cmdq.h   |   1 +
>>>>>>     2 files changed, 32 insertions(+), 76 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
>>>>>> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
>>>>>> index 0df62b076f49..b63289ab6787 100644
>>>>>> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
>>>>>> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
>>>>>> @@ -50,8 +50,8 @@ struct mtk_drm_crtc {
>>>>>>     	bool				pending_async_planes;
>>>>>>     
>>>>>>     #if IS_REACHABLE(CONFIG_MTK_CMDQ)
>>>>>> -	struct cmdq_client		cmdq_client;
>>>>>> -	struct cmdq_pkt			cmdq_handle;
>>>>>> +	struct cmdq_client		*cmdq_client;
>>>>>> +	struct cmdq_pkt			*cmdq_handle;
>>>>>>     	u32				cmdq_event;
>>>>>>     	u32				cmdq_vblank_cnt;
>>>>>>     	wait_queue_head_t		cb_blocking_queue;
>>>>>> @@ -108,47 +108,6 @@ static void
>>>>>> mtk_drm_finish_page_flip(struct
>>>>>> mtk_drm_crtc *mtk_crtc)
>>>>>>     	}
>>>>>>     }
>>>>>>     
>>>>>> -#if IS_REACHABLE(CONFIG_MTK_CMDQ)
>>>>>> -static int mtk_drm_cmdq_pkt_create(struct cmdq_client
>>>>>> *client,
>>>>>> struct cmdq_pkt *pkt,
>>>>>> -				   size_t size)
>>>>>> -{
>>>>>> -	struct device *dev;
>>>>>> -	dma_addr_t dma_addr;
>>>>>> -
>>>>>> -	pkt->va_base = kzalloc(size, GFP_KERNEL);
>>>>>> -	if (!pkt->va_base) {
>>>>>> -		kfree(pkt);
>>>>>> -		return -ENOMEM;
>>>>>> -	}
>>>>>> -	pkt->buf_size = size;
>>>>>> -	pkt->cl = (void *)client;
>>>>>
>>>>> I have a plan to remove cl in struct cmdq_pkt. But this
>>>>> modification
>>>>> would make this plan more difficult. So I would pending this
>>>>> patch
>>>>> until cl is removed from struct cmdq_pkt.
>>>>>
>>>>
>>>> I think that this ifdef cleanup is more urgent than the removal
>>>> of
>>>> `cl` from
>>>> struct cmdq_pkt, as those ifdefs shouldn't have reached upstream
>>>> in
>>>> the first
>>>> place, don't you agree?
>>>
>>> I think removing ifdefs and using helper function are different
>>> things.
>>> You could remove ifdefs and keep mtk_drm_cmdq_pkt_create().
>>>
>>
>> I chose to do it like that because this function would otherwise be a
>> 100% duplicate of the related cmdq helper :-)
> 
> Removing cl would change the interface of cmdq_pkt_create(). And this
> is related to different maintainer's tree. So it would be a long time
> to process. For you, only removing ifdes is urgent, so use
> cmdq_pkt_create() is not urgent. So let's keep
> mtk_drm_cmdq_pkt_create() and you could remove ifdefs.
> 

Hello CK,

my CMDQ cleanup has been stuck on your intention to remove `cl` from the CMDQ
helpers for ** six months ** now.

Are you performing that removal, or can we just get this cleanup finally done?

Regards,
Angelo




From rogerq at kernel.org  Tue Feb  6 05:36:16 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 6 Feb 2024 15:36:16 +0200
Subject: [PATCH 3/3] arm64: dts: ti: Add DT overlay for PCIe + USB3.0
 SERDES personality card
In-Reply-To: <547d7069-3457-4ee3-ad1c-fedc9db5da62@ti.com>
References: <20240126114530.40913-1-rogerq@kernel.org>
 <20240126114530.40913-4-rogerq@kernel.org>
 <547d7069-3457-4ee3-ad1c-fedc9db5da62@ti.com>
Message-ID: <a576961e-b737-49a8-80a5-65c87fff845d@kernel.org>



On 05/02/2024 16:46, Vignesh Raghavendra wrote:
> 
> 
> On 26/01/24 17:15, Roger Quadros wrote:
>> From: Kishon Vijay Abraham I <kishon at ti.com>
>>
> 
> [...]
> 
>>  # Boards with J7200 SoC
>>  k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo
>> diff --git a/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso
>> new file mode 100644
>> index 000000000000..c63b7241c005
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso
>> @@ -0,0 +1,67 @@
>> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
>> +/**
>> + * DT overlay for SERDES personality card: 1lane PCIe + USB3.0 DRD on AM654 EVM
>> + *
>> + * Copyright (C) 2018-2024 Texas Instruments Incorporated - http://www.ti.com/
>> + */
>> +
>> +/dts-v1/;
>> +/plugin/;
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include <dt-bindings/phy/phy.h>
>> +#include <dt-bindings/phy/phy-am654-serdes.h>
>> +
>> +#include "k3-pinctrl.h"
>> +
>> +&serdes1 {
>> +	status = "okay";
>> +};
>> +
>> +&pcie1_rc {
>> +	num-lanes = <1>;
>> +	phys = <&serdes1 PHY_TYPE_PCIE 0>;
>> +	phy-names = "pcie-phy0";
>> +	reset-gpios = <&pca9555 5 GPIO_ACTIVE_HIGH>;
>> +	status = "okay";
>> +};
>> +
>> +&pcie1_ep {
>> +	num-lanes = <1>;
>> +	phys = <&serdes1 PHY_TYPE_PCIE 0>;
>> +	phy-names = "pcie-phy0";
>> +};
>> +
>> +&main_pmx0 {
>> +	usb0_pins_default: usb0_pins_default {
> 
> No underscores in node-name and also should end with -pins
> 
>> +		pinctrl-single,pins = <
>> +			AM65X_IOPAD(0x02bc, PIN_OUTPUT, 0) /* (AD9) USB0_DRVVBUS */
>> +		>;
>> +	};
>> +};
>> +
>> +&serdes0 {
>> +	status = "okay";
>> +	assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
>> +	assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
>> +};
>> +
>> +&dwc3_0 {
>> +	status = "okay";
>> +	assigned-clock-parents = <&k3_clks 151 4>,      /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
>> +	<&k3_clks 151 8>;      /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */
>> +	phys = <&serdes0 PHY_TYPE_USB3 0>;
>> +	phy-names = "usb3-phy";
>> +};
>> +
>> +&usb0 {
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&usb0_pins_default>;
>> +	dr_mode = "host";
>> +	maximum-speed = "super-speed";
>> +	snps,dis-u1-entry-quirk;
>> +	snps,dis-u2-entry-quirk;
>> +};
>> +
>> +&usb0_phy {
>> +	status = "okay";
>> +};
> 
> 
> BTW, this breaks build on 6.8-rc1
> 
> 
>   DTOVL   arch/arm64/boot/dts/ti/k3-am654-gp-evm.dtb
> 
> Failed to apply 'arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtbo': FDT_ERR_NOTFOUND
> 
> 

It builds fine for me. Did the 3rd patch apply cleanly for you?

-- 
cheers,
-roger


From laurent.pinchart at ideasonboard.com  Tue Feb  6 05:41:55 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 6 Feb 2024 15:41:55 +0200
Subject: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <87r0hqnvxc.wl-kuninori.morimoto.gx@renesas.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
 <87r0hqnvxc.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <20240206134155.GB2827@pendragon.ideasonboard.com>

Hi Morimoto-san,

(Adding Krzysztof Ha?asa)

Thank you for the patch.

On Tue, Feb 06, 2024 at 02:55:27AM +0000, Kuninori Morimoto wrote:
> From DT point of view, in general, drivers should be asking for a
> specific port number because their function is fixed in the binding.
> 
> of_graph_get_next_endpoint() doesn't match to this concept.
> 
> Simply replace
> 
> 	- of_graph_get_next_endpoint(xxx, NULL);
> 	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);
> 
> Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
> ---
>  drivers/media/i2c/adv7343.c              | 2 +-
>  drivers/media/i2c/adv7604.c              | 2 +-
>  drivers/media/i2c/mt9p031.c              | 2 +-
>  drivers/media/i2c/mt9v032.c              | 2 +-
>  drivers/media/i2c/ov2659.c               | 2 +-
>  drivers/media/i2c/ov5645.c               | 2 +-
>  drivers/media/i2c/ov5647.c               | 2 +-
>  drivers/media/i2c/s5c73m3/s5c73m3-core.c | 2 +-
>  drivers/media/i2c/s5k5baf.c              | 2 +-
>  drivers/media/i2c/tc358743.c             | 2 +-
>  drivers/media/i2c/tda1997x.c             | 2 +-
>  drivers/media/i2c/tvp514x.c              | 2 +-
>  drivers/media/i2c/tvp7002.c              | 2 +-
>  13 files changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
> index ff21cd4744d3..4fbe4e18570e 100644
> --- a/drivers/media/i2c/adv7343.c
> +++ b/drivers/media/i2c/adv7343.c
> @@ -403,7 +403,7 @@ adv7343_get_pdata(struct i2c_client *client)
>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>  		return client->dev.platform_data;
>  
> -	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
> +	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>  	if (!np)
>  		return NULL;
>  
> diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
> index b202a85fbeaa..dcfdbb975473 100644
> --- a/drivers/media/i2c/adv7604.c
> +++ b/drivers/media/i2c/adv7604.c
> @@ -3205,7 +3205,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
>  	np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
>  
>  	/* Parse the endpoint. */
> -	endpoint = of_graph_get_next_endpoint(np, NULL);
> +	endpoint = of_graph_get_endpoint_by_regs(np, 0, -1);

I think this should be port 1 for the adv7611 and port2 for the adv7612.
The adv7610 may need to use port 1 too, but the bindings likely need to
be updated.

Hans, Krzysztof, any opinion ?

>  	if (!endpoint)
>  		return -EINVAL;
>  
> diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
> index 348f1e1098fb..c57a0d436421 100644
> --- a/drivers/media/i2c/mt9p031.c
> +++ b/drivers/media/i2c/mt9p031.c
> @@ -1080,7 +1080,7 @@ mt9p031_get_pdata(struct i2c_client *client)
>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>  		return client->dev.platform_data;
>  
> -	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
> +	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>  	if (!np)
>  		return NULL;
>  
> diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
> index 1c6f6cea1204..14d277680fa2 100644
> --- a/drivers/media/i2c/mt9v032.c
> +++ b/drivers/media/i2c/mt9v032.c
> @@ -1008,7 +1008,7 @@ mt9v032_get_pdata(struct i2c_client *client)
>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>  		return client->dev.platform_data;
>  
> -	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
> +	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>  	if (!np)
>  		return NULL;
>  
> diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
> index 2c3dbe164eb6..edea62a02320 100644
> --- a/drivers/media/i2c/ov2659.c
> +++ b/drivers/media/i2c/ov2659.c
> @@ -1388,7 +1388,7 @@ ov2659_get_pdata(struct i2c_client *client)
>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>  		return client->dev.platform_data;
>  
> -	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
> +	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>  	if (!endpoint)
>  		return NULL;
>  
> diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
> index a70db7e601a4..31d214bd4a83 100644
> --- a/drivers/media/i2c/ov5645.c
> +++ b/drivers/media/i2c/ov5645.c
> @@ -1053,7 +1053,7 @@ static int ov5645_probe(struct i2c_client *client)
>  	ov5645->i2c_client = client;
>  	ov5645->dev = dev;
>  
> -	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
>  	if (!endpoint) {
>  		dev_err(dev, "endpoint node not found\n");
>  		return -EINVAL;
> diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
> index dcfe3129c63a..beab2813c672 100644
> --- a/drivers/media/i2c/ov5647.c
> +++ b/drivers/media/i2c/ov5647.c
> @@ -1363,7 +1363,7 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
>  	struct device_node *ep;
>  	int ret;
>  
> -	ep = of_graph_get_next_endpoint(np, NULL);
> +	ep = of_graph_get_endpoint_by_regs(np, 0, -1);
>  	if (!ep)
>  		return -EINVAL;
>  
> diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
> index ed5b10731a14..aaec5f64f31a 100644
> --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
> +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
> @@ -1555,7 +1555,7 @@ static int s5c73m3_get_dt_data(struct s5c73m3 *state)
>  				     "failed to request gpio S5C73M3_RST\n");
>  	gpiod_set_consumer_name(state->reset, "S5C73M3_RST");
>  
> -	node_ep = of_graph_get_next_endpoint(node, NULL);
> +	node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
>  	if (!node_ep) {
>  		dev_warn(dev, "no endpoint defined for node: %pOF\n", node);
>  		return 0;
> diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
> index 67da2045f543..af7e49e6cc5b 100644
> --- a/drivers/media/i2c/s5k5baf.c
> +++ b/drivers/media/i2c/s5k5baf.c
> @@ -1836,7 +1836,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
>  			 state->mclk_frequency);
>  	}
>  
> -	node_ep = of_graph_get_next_endpoint(node, NULL);
> +	node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
>  	if (!node_ep) {
>  		dev_err(dev, "no endpoint defined at node %pOF\n", node);
>  		return -EINVAL;
> diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
> index 2785935da497..872e802cdfbe 100644
> --- a/drivers/media/i2c/tc358743.c
> +++ b/drivers/media/i2c/tc358743.c
> @@ -1895,7 +1895,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
>  		return dev_err_probe(dev, PTR_ERR(refclk),
>  				     "failed to get refclk\n");
>  
> -	ep = of_graph_get_next_endpoint(dev->of_node, NULL);
> +	ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
>  	if (!ep) {
>  		dev_err(dev, "missing endpoint node\n");
>  		return -EINVAL;
> diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
> index 325e99125941..662efd5e69b9 100644
> --- a/drivers/media/i2c/tda1997x.c
> +++ b/drivers/media/i2c/tda1997x.c
> @@ -2307,7 +2307,7 @@ static int tda1997x_parse_dt(struct tda1997x_state *state)
>  	pdata->vidout_sel_de = DE_FREF_SEL_DE_VHREF;
>  
>  	np = state->client->dev.of_node;
> -	ep = of_graph_get_next_endpoint(np, NULL);
> +	ep = of_graph_get_endpoint_by_regs(np, 0, -1);
>  	if (!ep)
>  		return -EINVAL;
>  
> diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
> index c37f605cb75f..b1630a6c396b 100644
> --- a/drivers/media/i2c/tvp514x.c
> +++ b/drivers/media/i2c/tvp514x.c
> @@ -988,7 +988,7 @@ tvp514x_get_pdata(struct i2c_client *client)
>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>  		return client->dev.platform_data;
>  
> -	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
> +	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>  	if (!endpoint)
>  		return NULL;
>  
> diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
> index a2d7bc799849..8e58ce400df2 100644
> --- a/drivers/media/i2c/tvp7002.c
> +++ b/drivers/media/i2c/tvp7002.c
> @@ -893,7 +893,7 @@ tvp7002_get_pdata(struct i2c_client *client)
>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>  		return client->dev.platform_data;
>  
> -	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
> +	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>  	if (!endpoint)
>  		return NULL;
>  

-- 
Regards,

Laurent Pinchart


From graf at amazon.com  Tue Feb  6 05:43:15 2024
From: graf at amazon.com (Alexander Graf)
Date: Tue, 6 Feb 2024 14:43:15 +0100
Subject: [PATCH v3 00/17] kexec: Allow preservation of ftrace buffers
In-Reply-To: <ZcHrIJ7lxpbkm5sc@pengutronix.de>
References: <20240117144704.602-1-graf@amazon.com>
 <ZcHrIJ7lxpbkm5sc@pengutronix.de>
Message-ID: <c7157097-4727-4360-80a0-20e7d8015e13@amazon.com>

Hey Oleksij!

On 06.02.24 09:17, Oleksij Rempel wrote:
> Hi Alexander,
>
> Nice work!
>
> On Wed, Jan 17, 2024 at 02:46:47PM +0000, Alexander Graf wrote:
>> Kexec today considers itself purely a boot loader: When we enter the new
>> kernel, any state the previous kernel left behind is irrelevant and the
>> new kernel reinitializes the system.
>>
>> However, there are use cases where this mode of operation is not what we
>> actually want. In virtualization hosts for example, we want to use kexec
>> to update the host kernel while virtual machine memory stays untouched.
>> When we add device assignment to the mix, we also need to ensure that
>> IOMMU and VFIO states are untouched. If we add PCIe peer to peer DMA, we
>> need to do the same for the PCI subsystem. If we want to kexec while an
>> SEV-SNP enabled virtual machine is running, we need to preserve the VM
>> context pages and physical memory. See James' and my Linux Plumbers
>> Conference 2023 presentation for details:
>>
>>    https://lpc.events/event/17/contributions/1485/
>>
>> To start us on the journey to support all the use cases above, this
>> patch implements basic infrastructure to allow hand over of kernel state
>> across kexec (Kexec HandOver, aka KHO). As example target, we use ftrace:
>> With this patch set applied, you can read ftrace records from the
>> pre-kexec environment in your post-kexec one. This creates a very powerful
>> debugging and performance analysis tool for kexec. It's also slightly
>> easier to reason about than full blown VFIO state preservation.
>>
>> == Alternatives ==
>>
>> There are alternative approaches to (parts of) the problems above:
>>
>>    * Memory Pools [1] - preallocated persistent memory region + allocator
>>    * PRMEM [2] - resizable persistent memory regions with fixed metadata
>>                  pointer on the kernel command line + allocator
>>    * Pkernfs [3] - preallocated file system for in-kernel data with fixed
>>                    address location on the kernel command line
>>    * PKRAM [4] - handover of user space pages using a fixed metadata page
>>                  specified via command line
>>
>> All of the approaches above fundamentally have the same problem: They
>> require the administrator to explicitly carve out a physical memory
>> location because they have no mechanism outside of the kernel command
>> line to pass data (including memory reservations) between kexec'ing
>> kernels.
>>
>> KHO provides that base foundation. We will determine later whether we
>> still need any of the approaches above for fast bulk memory handover of for
>> example IOMMU page tables. But IMHO they would all be users of KHO, with
>> KHO providing the foundational primitive to pass metadata and bulk memory
>> reservations as well as provide easy versioning for data.
>>
>> == Overview ==
>>
>> We introduce a metadata file that the kernels pass between each other. How
>> they pass it is architecture specific. The file's format is a Flattened
>> Device Tree (fdt) which has a generator and parser already included in
>> Linux. When the root user enables KHO through /sys/kernel/kho/active, the
>> kernel invokes callbacks to every driver that supports KHO to serialize
>> its state. When the actual kexec happens, the fdt is part of the image
>> set that we boot into. In addition, we keep a "scratch region" available
>> for kexec: A physically contiguous memory region that is guaranteed to
>> not have any memory that KHO would preserve.  The new kernel bootstraps
>> itself using the scratch region and sets all handed over memory as in use.
>> When drivers initialize that support KHO, they introspect the fdt and
>> recover their state from it. This includes memory reservations, where the
>> driver can either discard or claim reservations.
>>
>> == Limitations ==
>>
>> I currently only implemented file based kexec. The kernel interfaces
>> in the patch set are already in place to support user space kexec as well,
>> but I have not implemented it yet inside kexec tools.
>>
>> == How to Use ==
>>
>> To use the code, please boot the kernel with the "kho_scratch=" command
>> line parameter set: "kho_scratch=512M". KHO requires a scratch region.
>>
>> Make sure to fill ftrace with contents that you want to observe after
>> kexec.  Then, before you invoke file based "kexec -l", activate KHO:
>>
>>    # echo 1 > /sys/kernel/kho/active
>>    # kexec -l Image --initrd=initrd -s
>>    # kexec -e
>>
>> The new kernel will boot up and contain the previous kernel's trace
>> buffers in /sys/kernel/debug/tracing/trace.
> Assuming:
> - we wont to start tracing as early as possible, before rootfs
>    or initrd would be able to configure it.
> - traces are stored on a different device, not RAM. For example NVMEM.
> - Location of NVMEM is different for different board types, but
>    bootloader is able to give the right configuration to the kernel.


Let me try to really understand what you're tracing here. Are we talking 
about exposing boot loader traces into Linux [1]? In that case, I think 
a mechanism like [2] is what you're looking for.

Or do you want to transfer genuine Linux ftrace traces? In that case, 
why would you want to store them outside of RAM?


>
> What would be the best, acceptable for mainline, way to provide this
> kind of configuration? At least part of this information do not
> describes devices or device states, this would not fit in to devicetree
> universe. Amount of possible information would not fit in to bootconfig
> too.


We have precedence for configuration in device tree: You can use device 
tree to describe partitions on a NAND device, you can use it to specify 
MAC address overrides of devices attached to USB, etc etc. At the end of 
the day when people say they don't want configuration in device tree, 
what they mean is that device tree should be a hand over data structure 
from firmware to kernel, not from OS integrator to kernel :). If your 
firmware is the place that knows about offsets and you need to pass 
those offsets, IMHO DT is a good fit.


> Other more or less overlapping use case I have in mind is a netbootable
> embedded system with a requirement to boot as fast as possible. Since
> bootloader already established a link and got all needed ip
> configuration, it would be able to hand over etherent controller and ip
> configuration states. Wille be the KHO the way to go for this use case?


That's an interesting one too. I would lean towards "try with normal 
device tree first" here as well. It's again a very clear case of 
"firmware wants to tell OS about things it knows, but the OS doesn't 
know" to me. That means device tree should be fine to describe it.


Alex

[1] https://www.youtube.com/watch?v=RaFm5FfzFaM / 
https://edk2.groups.io/g/devel/topic/91368904
[2] 
https://github.com/agraf/linux/commit/b1fe0c296ec923e9b1f544862b0eb9365a8da7cb

>
> 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 |



Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



From kamlesh at ti.com  Tue Feb  6 05:54:37 2024
From: kamlesh at ti.com (Kamlesh Gurudasani)
Date: Tue, 6 Feb 2024 19:24:37 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240206131420.wtitflgav23jto2q@verbally>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
 <20240206131420.wtitflgav23jto2q@verbally>
Message-ID: <871q9pzoiq.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>

Nishanth Menon <nm at ti.com> writes:

> On 16:13-20240206, Udit Kumar wrote:
>> Most of clocks and their parents are defined in contiguous range,
>> But in few cases, there is gap in clock numbers[0].
>> Driver assumes clocks to be in contiguous range, and add their clock
>> ids incrementally.
>> 
>> New firmware started returning error while calling get_freq and is_on
>> API for non-available clock ids.
>> 
>> In this fix, driver checks and adds only valid clock ids.
>> 
>> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
>> 
>> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
>> Section Clocks for NAVSS0_CPTS_0 Device,
>> clock id 12-15 not present.
>> 
>> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
>>  				while (num_parents--) {
>> +					/* Check if this clock id is valid */
>> +					ret = provider->ops->get_freq(provider->sci,
>> +						sci_clk->dev_id, clk_id, &freq);
>
> get_freq is a bit expensive as it has to walk the clock tree to find
> the clock frequency (at least the first time?). just wondering if
> there is lighter alternative here?
>
How about get_clock? Doesn't read the registers at least.

Regards,
Kamlesh


From bp at alien8.de  Tue Feb  6 06:00:38 2024
From: bp at alien8.de (Borislav Petkov)
Date: Tue, 6 Feb 2024 15:00:38 +0100
Subject: [PATCH] x86/sev: Fix position dependent variable references in
 startup code
In-Reply-To: <CAMj1kXFGpTxPhNu8H090OVJ_izbgHyYy2VKwrpv43mdZuiHadA@mail.gmail.com>
References: <20240203125306.1887331-2-ardb+git@google.com>
 <20240206110723.GBZcIS60p3LIvfPfgM@fat_crate.local>
 <CAMj1kXFGpTxPhNu8H090OVJ_izbgHyYy2VKwrpv43mdZuiHadA@mail.gmail.com>
Message-ID: <20240206140038.GDZcI7hr8qMy0ACKgY@fat_crate.local>

On Tue, Feb 06, 2024 at 11:19:06AM +0000, Ard Biesheuvel wrote:
> Looks good to me - thanks.

Thanks.

Now, next question: I'm presuming we want this in stable?

If so, which one?

And if there are conflicts during backporting over there, would you guys
address them and test the backports?

I'm presuming there's only a subset of stable kernels which you care
about. If so, we probably don't want to backport it all the way back to
5.19... but mark it for a later kernel only...

Thoughts?

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette


From martin at kaiser.cx  Tue Feb  6 06:05:23 2024
From: martin at kaiser.cx (Martin Kaiser)
Date: Tue, 6 Feb 2024 15:05:23 +0100
Subject: [PATCH v4 1/4] gpio: vf610: allow disabling the vf610 driver
In-Reply-To: <ZbibA9QbOn19AXcn@gaggiata.pivistrello.it>
References: <20240124205900.14791-1-martin@kaiser.cx>
 <20240124205900.14791-2-martin@kaiser.cx>
 <20240126122719.GA13659@francesco-nb>
 <ZbgX-HGjM5fdftCG@v2202401214221251712.nicesrv.de>
 <ZbibA9QbOn19AXcn@gaggiata.pivistrello.it>
Message-ID: <ZcI8oyHzaktJcfNV@v2202401214221251712.nicesrv.de>

Thus wrote Francesco Dolcini (francesco at dolcini.it):

> On Mon, Jan 29, 2024 at 10:26:16PM +0100, Martin Kaiser wrote:
> > Thus wrote Francesco Dolcini (francesco at dolcini.it):

> > > On Wed, Jan 24, 2024 at 09:58:57PM +0100, Martin Kaiser wrote:
> > > > The vf610 gpio driver is enabled by default for all i.MX machines,
> > > > without any option to disable it in a board-specific config file.

> > > > Most i.MX chipsets have no hardware for this driver. Change the default
> > > > to enable GPIO_VF610 for SOC_VF610 and disable it otherwise.

> > > > Add a text description after the bool type, this makes the driver
> > > > selectable by make config etc.

> > > > Fixes: 30a35c07d9e9 ("gpio: vf610: drop the SOC_VF610 dependency for GPIO_VF610")
> > > > Signed-off-by: Martin Kaiser <martin at kaiser.cx>
> > > > ---

> > > >  config GPIO_VF610
> > > > -	def_bool y
> > > > +	bool "VF610 GPIO support"
> > > > +	default y if SOC_VF610

> > > any reason for having this default y for SOC_VF610, but not for the
> > > other SOC that uses the same variant (i.MX7ULP, ... ?).

> > Ok, it's probably not as consistent as it could be.

> ...

> > Does this make sense?
> sounds fair to me.

Sorry for the delay, other tasks got in the way.

The maintainers have meanwhile merged v4.

Basically, the conclusion of my last mail was that imx7ulp and soc_vf610 could
be configured in the same way to make things a bit clearer. This wouldn't be
much of an improvement compared to the v4 set, I'd suggest keeping the current
state.

Thanks,
Martin


From vadim.fedorenko at linux.dev  Tue Feb  6 06:07:32 2024
From: vadim.fedorenko at linux.dev (Vadim Fedorenko)
Date: Tue, 6 Feb 2024 14:07:32 +0000
Subject: [PATCH v3 09/20] drivers: crypto: meson: process more than
 MAXDESCS descriptors
In-Reply-To: <20240205155521.1795552-10-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
 <20240205155521.1795552-10-avromanov@salutedevices.com>
Message-ID: <f4ff9d98-a1ae-4214-9740-c6f921d1bc48@linux.dev>

On 05/02/2024 15:55, Alexey Romanov wrote:
> 1. The old alhorithm was not designed to process a large
> amount of memory, and therefore gave incorrect results.
> 
> 2. Not all Amlogic SoC's use 3 KEY/IV descriptors.
> Add keyiv descriptors count parameter to platform data.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   drivers/crypto/amlogic/amlogic-gxl-cipher.c | 443 ++++++++++++--------
>   drivers/crypto/amlogic/amlogic-gxl-core.c   |   1 +
>   drivers/crypto/amlogic/amlogic-gxl.h        |   2 +
>   3 files changed, 281 insertions(+), 165 deletions(-)
> 
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index c662c4b86e97..9c96e7b65e1e 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -17,35 +17,41 @@
>   #include <crypto/internal/skcipher.h>
>   #include "amlogic-gxl.h"
>   

[.. skip ..]

> @@ -84,176 +295,78 @@ static int meson_cipher(struct skcipher_request *areq)
>   	struct meson_dev *mc = op->mc;
>   	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
>   	struct meson_alg_template *algt;
> -	int flow = rctx->flow;
> -	unsigned int todo, eat, len;
> -	struct scatterlist *src_sg = areq->src;
> -	struct scatterlist *dst_sg = areq->dst;
> -	struct meson_desc *desc;
> -	int nr_sgs, nr_sgd;
> -	int i, err = 0;
> -	unsigned int keyivlen, ivsize, offset, tloffset;
> -	dma_addr_t phykeyiv;
> -	void *backup_iv = NULL, *bkeyiv;
> -	u32 v;
> -
> -	algt = container_of(alg, struct meson_alg_template, alg.skcipher.base);
> +	struct cipher_ctx ctx = {
> +		.areq = areq,
> +		.src_offset = 0,
> +		.dst_offset = 0,
> +		.src_sg = areq->src,
> +		.dst_sg = areq->dst,
> +		.cryptlen = areq->cryptlen,
> +	};
> +	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
> +	int err;
>   
> -	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u flow=%d\n", __func__,
> +	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u ctx.flow=%d\n", __func__,
>   		crypto_tfm_alg_name(areq->base.tfm),
>   		areq->cryptlen,
>   		rctx->op_dir, crypto_skcipher_ivsize(tfm),
> -		op->keylen, flow);
> +		op->keylen, rctx->flow);
> +
> +	algt = container_of(alg, struct meson_alg_template, alg.skcipher.base);
>   
>   #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
>   	algt->stat_req++;
> -	mc->chanlist[flow].stat_req++;
> +	mc->chanlist[rctx->flow].stat_req++;
>   #endif
>   
> -	/*
> -	 * The hardware expect a list of meson_desc structures.
> -	 * The 2 first structures store key
> -	 * The third stores IV
> -	 */
> -	bkeyiv = kzalloc(48, GFP_KERNEL | GFP_DMA);
> -	if (!bkeyiv)
> +	op->key = kzalloc(48, GFP_KERNEL | GFP_DMA);
> +	if (!op.key)
>   		return -ENOMEM;
>   
> -	memcpy(bkeyiv, op->key, op->keylen);
> -	keyivlen = op->keylen;
> +	memcpy(op->key, op->key, op->keylen);

Apart form invalid if() you try to copy op->key to itself.
I believe it should be removed, because you initialize ctx.key.addr
later

> +	ctx.keyiv.len = op->keylen;
> +	if (ctx.keyiv.len == AES_KEYSIZE_192)
> +		ctx.keyiv.len = AES_MAX_KEY_SIZE;
>   
> -	ivsize = crypto_skcipher_ivsize(tfm);
> -	if (areq->iv && ivsize > 0) {
> -		if (ivsize > areq->cryptlen) {
> -			dev_err(mc->dev, "invalid ivsize=%d vs len=%d\n", ivsize, areq->cryptlen);
> -			err = -EINVAL;
> -			goto theend;
> -		}
> -		memcpy(bkeyiv + 32, areq->iv, ivsize);
> -		keyivlen = 48;
> -		if (rctx->op_dir == MESON_DECRYPT) {
> -			backup_iv = kzalloc(ivsize, GFP_KERNEL);
> -			if (!backup_iv) {
> -				err = -ENOMEM;
> -				goto theend;
> -			}
> -			offset = areq->cryptlen - ivsize;
> -			scatterwalk_map_and_copy(backup_iv, areq->src, offset,
> -						 ivsize, 0);
> -		}
> -	}
> -	if (keyivlen == AES_KEYSIZE_192)
> -		keyivlen = AES_MAX_KEY_SIZE;
> -
> -	phykeyiv = dma_map_single(mc->dev, bkeyiv, keyivlen,
> +	ctx.keyiv.addr = dma_map_single(mc->dev, op->key, ctx.keyiv.len,
>   				  DMA_TO_DEVICE);
> -	err = dma_mapping_error(mc->dev, phykeyiv);
> +	err = dma_mapping_error(mc->dev, ctx.keyiv.addr);
>   	if (err) {
>   		dev_err(mc->dev, "Cannot DMA MAP KEY IV\n");
>   		goto theend;
>   	}
>   
> -	tloffset = 0;
> -	eat = 0;
> -	i = 0;
> -	while (keyivlen > eat) {
> -		desc = &mc->chanlist[flow].tl[tloffset];
> -		memset(desc, 0, sizeof(struct meson_desc));
> -		todo = min(keyivlen - eat, 16u);
> -		desc->t_src = cpu_to_le32(phykeyiv + i * 16);
> -		desc->t_dst = cpu_to_le32(i * 16);
> -		v = DESC_MODE_KEY | DESC_OWN | 16;
> -		desc->t_status = cpu_to_le32(v);
> -
> -		eat += todo;
> -		i++;
> -		tloffset++;
> -	}
> -
> -	if (areq->src == areq->dst) {
> -		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
> -				    DMA_BIDIRECTIONAL);
> -		if (!nr_sgs) {
> -			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
> -			err = -EINVAL;
> -			goto theend;
> -		}
> -		nr_sgd = nr_sgs;
> -	} else {
> -		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
> -				    DMA_TO_DEVICE);
> -		if (!nr_sgs || nr_sgs > MAXDESC - 3) {
> -			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
> -			err = -EINVAL;
> -			goto theend;
> -		}
> -		nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
> -				    DMA_FROM_DEVICE);
> -		if (!nr_sgd || nr_sgd > MAXDESC - 3) {
> -			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
> -			err = -EINVAL;
> -			goto theend;
> -		}
> -	}
> -
> -	src_sg = areq->src;
> -	dst_sg = areq->dst;
> -	len = areq->cryptlen;
> -	while (src_sg) {
> -		desc = &mc->chanlist[flow].tl[tloffset];
> -		memset(desc, 0, sizeof(struct meson_desc));
> -
> -		desc->t_src = cpu_to_le32(sg_dma_address(src_sg));
> -		desc->t_dst = cpu_to_le32(sg_dma_address(dst_sg));
> -		todo = min(len, sg_dma_len(src_sg));
> -		v = op->keymode | DESC_OWN | todo | algt->blockmode;
> -		if (rctx->op_dir)
> -			v |= DESC_ENCRYPTION;
> -		len -= todo;
> -
> -		if (!sg_next(src_sg))
> -			v |= DESC_LAST;
> -		desc->t_status = cpu_to_le32(v);
> -		tloffset++;
> -		src_sg = sg_next(src_sg);
> -		dst_sg = sg_next(dst_sg);
> -	}
> +	err = meson_map_scatterlist(areq, mc);
> +	if (err)
> +		goto theend;
>   
> -	reinit_completion(&mc->chanlist[flow].complete);
> -	meson_dma_start(mc, flow);
> +	ctx.tloffset = 0;
>   
> -	err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
> -							msecs_to_jiffies(500));
> -	if (err == 0) {
> -		dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
> -		err = -EINVAL;
> -	} else if (err < 0) {
> -		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
> -	} else {
> -		/* No error */
> -		err = 0;
> -	}
> +	while (ctx.cryptlen) {
> +		meson_setup_keyiv_descs(&ctx);
>   
> -	dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
> +		if (meson_setup_data_descs(&ctx)) {
> +			err = meson_kick_hardware(&ctx);
> +			if (err)
> +				break;
> +		}
>   
> -	if (areq->src == areq->dst) {
> -		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL);
> -	} else {
> -		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
> -		dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE);
> -	}
> +		if (ctx.src_offset == sg_dma_len(ctx.src_sg)) {
> +			ctx.src_offset = 0;
> +			ctx.src_sg = sg_next(ctx.src_sg);
> +		}
>   
> -	if (areq->iv && ivsize > 0) {
> -		if (rctx->op_dir == MESON_DECRYPT) {
> -			memcpy(areq->iv, backup_iv, ivsize);
> -		} else {
> -			scatterwalk_map_and_copy(areq->iv, areq->dst,
> -						 areq->cryptlen - ivsize,
> -						 ivsize, 0);
> +		if (ctx.dst_offset == sg_dma_len(ctx.dst_sg)) {
> +			ctx.dst_offset = 0;
> +			ctx.dst_sg = sg_next(ctx.dst_sg);
>   		}
>   	}
> +
> +	dma_unmap_single(mc->dev, ctx.keyiv.addr, ctx.keyiv.len, DMA_TO_DEVICE);
> +	meson_unmap_scatterlist(areq, mc);
> +
>   theend:
> -	kfree_sensitive(bkeyiv);
> -	kfree_sensitive(backup_iv);
> +	kfree_sensitive(op->key);
>   
>   	return err;
>   }
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 22ff2768b5e5..f93e14f5717d 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -199,6 +199,7 @@ static const struct meson_pdata meson_gxl_pdata = {
>   	.descs_reg = 0x0,
>   	.status_reg = 0x4,
>   	.need_clk = true,
> +	.setup_desc_cnt = 3,
>   };
>   
>   static const struct of_device_id meson_crypto_of_match_table[] = {
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index a0d83c82906d..eb2f8cd72b65 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -83,11 +83,13 @@ struct meson_flow {
>    * @reg_descs:	offset to descriptors register
>    * @reg_status:	offset to status register
>    * @need_clk:	clock input is needed
> + * @setup_desc_cnt:	number of setup descriptor to configure.
>    */
>   struct meson_pdata {
>   	u32 descs_reg;
>   	u32 status_reg;
>   	bool need_clk;
> +	u32 setup_desc_cnt;
>   };
>   
>   /*



From krzysztof.kozlowski at linaro.org  Tue Feb  6 06:12:50 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 6 Feb 2024 15:12:50 +0100
Subject: [linux][PATCH] ASoC: dt-bindings: atmel,sam9x5-wm8731: Convert to
 json-schema
In-Reply-To: <20240206064418.237377-1-dharma.b@microchip.com>
References: <20240206064418.237377-1-dharma.b@microchip.com>
Message-ID: <47bbd3e5-d94a-4b7e-afc2-68297f5a79c1@linaro.org>

On 06/02/2024 07:44, Dharma Balasubiramani wrote:
> Convert atmel sam9x5-wm8731-audio devicetree binding to json-schema.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>

There is no need to prefix patches with "linux".

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From u-kumar1 at ti.com  Tue Feb  6 06:14:51 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Tue, 6 Feb 2024 19:44:51 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240206131420.wtitflgav23jto2q@verbally>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
 <20240206131420.wtitflgav23jto2q@verbally>
Message-ID: <a0249265-255b-40d7-b609-c1ab6a789d46@ti.com>


On 2/6/2024 6:44 PM, Nishanth Menon wrote:
> On 16:13-20240206, Udit Kumar wrote:
>> Most of clocks and their parents are defined in contiguous range,
>> But in few cases, there is gap in clock numbers[0].
>> Driver assumes clocks to be in contiguous range, and add their clock
>> ids incrementally.
>>
>> New firmware started returning error while calling get_freq and is_on
>> API for non-available clock ids.
>>
>> In this fix, driver checks and adds only valid clock ids.
>>
>> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
>>
>> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
>> Section Clocks for NAVSS0_CPTS_0 Device,
>> clock id 12-15 not present.
>>
>> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
>> ---
>> Changelog
>>
>> Changes in v2
>> - Updated commit message
>> - Simplified logic for valid clock id
>> link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/
>>
>>
>> P.S
>> Firmawre returns total num_parents count including non available ids.
>> For above device id NAVSS0_CPTS_0, number of parents clocks are 16
>> i.e from id 2 to 17. But out of these ids few are not valid.
>> So driver adds only valid clock ids out ot total.
>>
>> Original logs
>> https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
>> Line 2630 for error
>>
>> Logs with fix v2
>> https://gist.github.com/uditkumarti/94e3e28d62282fd708dbfe37435ce1d9
>> Line 2591
>>
>>
>>   drivers/clk/keystone/sci-clk.c | 12 ++++++++++--
>>   1 file changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
>> index 35fe197dd303..ff249cbd54a1 100644
>> --- a/drivers/clk/keystone/sci-clk.c
>> +++ b/drivers/clk/keystone/sci-clk.c
>> @@ -517,6 +517,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>>   	int num_clks = 0;
>>   	int num_parents;
>>   	int clk_id;
>> +	u64 freq;
>>   	const char * const clk_names[] = {
>>   		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
>>   	};
>> @@ -586,16 +587,23 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>>   				clk_id = args.args[1] + 1;
>>   
>>   				while (num_parents--) {
>> +					/* Check if this clock id is valid */
>> +					ret = provider->ops->get_freq(provider->sci,
>> +						sci_clk->dev_id, clk_id, &freq);
> get_freq is a bit expensive as it has to walk the clock tree to find
> the clock frequency (at least the first time?). just wondering if
> there is lighter alternative here?


Let me check , if we have some other alternative here

>> +
>> +					clk_id++;
>> +					if (ret)
>> +						continue;
>> +
>>   					sci_clk = devm_kzalloc(dev,
>>   							       sizeof(*sci_clk),
>>   							       GFP_KERNEL);
>>   					if (!sci_clk)
>>   						return -ENOMEM;
>>   					sci_clk->dev_id = args.args[0];
>> -					sci_clk->clk_id = clk_id++;
>> +					sci_clk->clk_id = clk_id - 1;
>>   					sci_clk->provider = provider;
>>   					list_add_tail(&sci_clk->node, &clks);
>> -
> 	Spurious change.

I think, you meant by deleting the line ?

If yes then will address in next version


>>   					num_clks++;
>>   				}
>>   			}
>> -- 
>> 2.34.1
>>


From u-kumar1 at ti.com  Tue Feb  6 06:15:47 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Tue, 6 Feb 2024 19:45:47 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <871q9pzoiq.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
 <20240206131420.wtitflgav23jto2q@verbally>
 <871q9pzoiq.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
Message-ID: <c5b6bd1d-dbb4-4bfb-8b3e-9b0733e2ba5d@ti.com>


On 2/6/2024 7:24 PM, Kamlesh Gurudasani wrote:
> Nishanth Menon <nm at ti.com> writes:
>
>> On 16:13-20240206, Udit Kumar wrote:
>>> Most of clocks and their parents are defined in contiguous range,
>>> But in few cases, there is gap in clock numbers[0].
>>> Driver assumes clocks to be in contiguous range, and add their clock
>>> ids incrementally.
>>>
>>> New firmware started returning error while calling get_freq and is_on
>>> API for non-available clock ids.
>>>
>>> In this fix, driver checks and adds only valid clock ids.
>>>
>>> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
>>>
>>> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
>>> Section Clocks for NAVSS0_CPTS_0 Device,
>>> clock id 12-15 not present.
>>>
>>> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
>>>   				while (num_parents--) {
>>> +					/* Check if this clock id is valid */
>>> +					ret = provider->ops->get_freq(provider->sci,
>>> +						sci_clk->dev_id, clk_id, &freq);
>> get_freq is a bit expensive as it has to walk the clock tree to find
>> the clock frequency (at least the first time?). just wondering if
>> there is lighter alternative here?
>>
> How about get_clock? Doesn't read the registers at least.

Said API needs, some flags to be passed,

Can those flag be set to zero, Chandru ?


> Regards,
> Kamlesh


From kamlesh at ti.com  Tue Feb  6 06:21:00 2024
From: kamlesh at ti.com (Kamlesh Gurudasani)
Date: Tue, 6 Feb 2024 19:51:00 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240206104357.3803517-1-u-kumar1@ti.com>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
Message-ID: <87wmrhy8qb.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>

Udit Kumar <u-kumar1 at ti.com> writes:

> Most of clocks and their parents are defined in contiguous range,
> But in few cases, there is gap in clock numbers[0].
> Driver assumes clocks to be in contiguous range, and add their clock
> ids incrementally.
>
> New firmware started returning error while calling get_freq and is_on
> API for non-available clock ids.
>
> In this fix, driver checks and adds only valid clock ids.
>
> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
>
> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> Section Clocks for NAVSS0_CPTS_0 Device,
> clock id 12-15 not present.
>
> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
...
> @@ -586,16 +587,23 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  				clk_id = args.args[1] + 1;
>  
>  				while (num_parents--) {
> +					/* Check if this clock id is valid */
> +					ret = provider->ops->get_freq(provider->sci,
> +						sci_clk->dev_id, clk_id, &freq);


> +
> +					clk_id++;
Why increment it here and subtract if get_freq succeeds (sci_clk->clk_id = clk_id - 1;), rather
if(ret) {
        clk_id++;
        continue;
}
> +					if (ret)
> +						continue;

> +
>  					sci_clk = devm_kzalloc(dev,
>  							       sizeof(*sci_clk),
>  							       GFP_KERNEL);
>  					if (!sci_clk)
>  						return -ENOMEM;
>  					sci_clk->dev_id = args.args[0];
> -					sci_clk->clk_id = clk_id++;
> +					sci_clk->clk_id = clk_id - 1;
and keep sci_clk->clk_id = clk_id++; intact

saves one subtraction

or even better

 - 				clk_id = args.args[1] + 1;
 + 				clk_id = args.args[1];
  				while (num_parents--) {
 +					/* Check if this clock id is valid */
 +					ret = provider->ops->get_freq(provider->sci,
 +						sci_clk->dev_id, ++clk_id, &freq);

and then no increments after, for clk_id

Regards,
Kamlesh


From ardb at kernel.org  Tue Feb  6 06:22:25 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 6 Feb 2024 14:22:25 +0000
Subject: [PATCH] x86/sev: Fix position dependent variable references in
 startup code
In-Reply-To: <20240206140038.GDZcI7hr8qMy0ACKgY@fat_crate.local>
References: <20240203125306.1887331-2-ardb+git@google.com> <20240206110723.GBZcIS60p3LIvfPfgM@fat_crate.local>
 <CAMj1kXFGpTxPhNu8H090OVJ_izbgHyYy2VKwrpv43mdZuiHadA@mail.gmail.com> <20240206140038.GDZcI7hr8qMy0ACKgY@fat_crate.local>
Message-ID: <CAMj1kXFn4qN9-C5AUAReeE67Kow730yk9d9U7JtRdrhEHuO=qQ@mail.gmail.com>

On Tue, 6 Feb 2024 at 14:00, Borislav Petkov <bp at alien8.de> wrote:
>
> On Tue, Feb 06, 2024 at 11:19:06AM +0000, Ard Biesheuvel wrote:
> > Looks good to me - thanks.
>
> Thanks.
>
> Now, next question: I'm presuming we want this in stable?
>

Yes.

> If so, which one?
>

Ideally, any kernel that could reasonably be expected to work
correctly in a SEV guest should get this. And IMHO, the state of SEV
host support for any of its flavors is irrelevant there. But let's see
how painful it gets working our way back. I think Kevin mentioned
v5.10 but I haven't had a look yet how feasible that is.

> And if there are conflicts during backporting over there, would you guys
> address them and test the backports?
>

Yes - I cannot speak for Kevin outright but I'm sure that between him
and me, we will be able to allocate the time and effort to make sure
that those conflicts are resolved and the resolutions tested
sufficiently. (With Kevin's help, I have been able to test these
changes myself on our internal SEV infrastructure)

> I'm presuming there's only a subset of stable kernels which you care
> about. If so, we probably don't want to backport it all the way back to
> 5.19... but mark it for a later kernel only...
>
> Thoughts?
>

One slight complication is that the change currently relies on your
patch to remove CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT, so if we
don't want to backport that, I will have to tweak the it. Personally,
I think it would be fine but others may feel differently.


From chandru at ti.com  Tue Feb  6 06:26:30 2024
From: chandru at ti.com (CHANDRU DHAVAMANI)
Date: Tue, 6 Feb 2024 19:56:30 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <c5b6bd1d-dbb4-4bfb-8b3e-9b0733e2ba5d@ti.com>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
 <20240206131420.wtitflgav23jto2q@verbally>
 <871q9pzoiq.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <c5b6bd1d-dbb4-4bfb-8b3e-9b0733e2ba5d@ti.com>
Message-ID: <c2b7f22d-f07d-4cac-8a01-af7b014e7ff4@ti.com>


On 06/02/24 19:45, Kumar, Udit wrote:
>
> On 2/6/2024 7:24 PM, Kamlesh Gurudasani wrote:
>> Nishanth Menon <nm at ti.com> writes:
>>
>>> On 16:13-20240206, Udit Kumar wrote:
>>>> Most of clocks and their parents are defined in contiguous range,
>>>> But in few cases, there is gap in clock numbers[0].
>>>> Driver assumes clocks to be in contiguous range, and add their clock
>>>> ids incrementally.
>>>>
>>>> New firmware started returning error while calling get_freq and is_on
>>>> API for non-available clock ids.
>>>>
>>>> In this fix, driver checks and adds only valid clock ids.
>>>>
>>>> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for 
>>>> dynamically probing clocks")
>>>>
>>>> [0] 
>>>> https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html 
>>>>
>>>> Section Clocks for NAVSS0_CPTS_0 Device,
>>>> clock id 12-15 not present.
>>>>
>>>> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
>>>> ????????????????? while (num_parents--) {
>>>> +??????????????????? /* Check if this clock id is valid */
>>>> +??????????????????? ret = provider->ops->get_freq(provider->sci,
>>>> +??????????????????????? sci_clk->dev_id, clk_id, &freq);
>>> get_freq is a bit expensive as it has to walk the clock tree to find
>>> the clock frequency (at least the first time?). just wondering if
>>> there is lighter alternative here?
>>>
>> How about get_clock? Doesn't read the registers at least.
>
> Said API needs, some flags to be passed,
>
> Can those flag be set to zero, Chandru ?


get_clock doesn't require any flags to be passed.


>
>
>> Regards,
>> Kamlesh


From gregkh at linuxfoundation.org  Tue Feb  6 06:29:39 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 6 Feb 2024 14:29:39 +0000
Subject: [PATCH] tty: serial: samsung: Remove superfluous braces in macro
In-Reply-To: <20240202010507.22638-1-semen.protsenko@linaro.org>
References: <20240202010507.22638-1-semen.protsenko@linaro.org>
Message-ID: <2024020609-left-trimester-13c8@gregkh>

On Thu, Feb 01, 2024 at 07:05:07PM -0600, Sam Protsenko wrote:
> Commit 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")
> removes parameters from EXYNOS_COMMON_SERIAL_DRV_DATA() macro, but
> leaves unnecessary empty braces. Remove those to fix the style. No
> functional change.
> 
> Fixes: 59f37b7370ef ("tty: serial: samsung: Remove USI initialization")

"no functional change" don't really deserve a "Fixes:" tag.  I'll go
delete this when applying, thanks.

greg k-h


From bp at alien8.de  Tue Feb  6 06:37:13 2024
From: bp at alien8.de (Borislav Petkov)
Date: Tue, 6 Feb 2024 15:37:13 +0100
Subject: [PATCH] x86/sev: Fix position dependent variable references in
 startup code
In-Reply-To: <CAMj1kXFn4qN9-C5AUAReeE67Kow730yk9d9U7JtRdrhEHuO=qQ@mail.gmail.com>
References: <20240203125306.1887331-2-ardb+git@google.com>
 <20240206110723.GBZcIS60p3LIvfPfgM@fat_crate.local>
 <CAMj1kXFGpTxPhNu8H090OVJ_izbgHyYy2VKwrpv43mdZuiHadA@mail.gmail.com>
 <20240206140038.GDZcI7hr8qMy0ACKgY@fat_crate.local>
 <CAMj1kXFn4qN9-C5AUAReeE67Kow730yk9d9U7JtRdrhEHuO=qQ@mail.gmail.com>
Message-ID: <20240206143713.GFZcJEGUxaZRIVSlrg@fat_crate.local>

On Tue, Feb 06, 2024 at 02:22:25PM +0000, Ard Biesheuvel wrote:
> Ideally, any kernel that could reasonably be expected to work
> correctly in a SEV guest should get this. And IMHO, the state of SEV
> host support for any of its flavors is irrelevant there. But let's see
> how painful it gets working our way back. I think Kevin mentioned
> v5.10 but I haven't had a look yet how feasible that is.

Ok, I'll add Cc:stable and then you guys can sort it out when the stable
failed-to-apply messages come in.

> Yes - I cannot speak for Kevin outright but I'm sure that between him
> and me, we will be able to allocate the time and effort to make sure
> that those conflicts are resolved and the resolutions tested
> sufficiently. (With Kevin's help, I have been able to test these
> changes myself on our internal SEV infrastructure)

Sounds good.

> One slight complication is that the change currently relies on your
> patch to remove CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT, so if we
> don't want to backport that, I will have to tweak the it. Personally,
> I think it would be fine but others may feel differently.

Well, tip:x86/sev is cast in stone because the KVM folks will use it
eventually to base the KVM SNP host changes ontop so I cannot rebase.

If there's trouble backporting just holler.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette


From msp at baylibre.com  Tue Feb  6 06:37:07 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue,  6 Feb 2024 15:37:07 +0100
Subject: [PATCH 0/4] soc: ti: k3-socinfo: Add support for nvmem cells
Message-ID: <20240206143711.2410135-1-msp@baylibre.com>

Hi,

am62 has a number of efuse fields that are situated in the device range
of the current chipid device node. As other devices require these
information as well, I am trying to establish a new nvmem layout for the
information available in this register range.

In this series the conflicting chipid driver is updated to support
nvmem-cells and the chipid node gets the register range removed and
replaced with nvmem cells on am62.

In a follow-up series the opp table will be updated.

Best,
Markus

Markus Schneider-Pargmann (4):
  nvmem: core: Read into buffers larger than data
  dt-bindings: hwinfo: ti,k3-socinfo: Add nvmem-cells
  soc: ti: k3-socinfo: Add support for nvmem cells
  arm64: dts: ti: k3-am62-wakeup: Add chip efuse nodes

 .../bindings/hwinfo/ti,k3-socinfo.yaml        | 23 ++++++-
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi    | 36 +++++++++-
 drivers/nvmem/core.c                          |  6 +-
 drivers/soc/ti/k3-socinfo.c                   | 67 +++++++++++++------
 4 files changed, 107 insertions(+), 25 deletions(-)

-- 
2.43.0



From msp at baylibre.com  Tue Feb  6 06:37:08 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue,  6 Feb 2024 15:37:08 +0100
Subject: [PATCH 1/4] nvmem: core: Read into buffers larger than data
In-Reply-To: <20240206143711.2410135-1-msp@baylibre.com>
References: <20240206143711.2410135-1-msp@baylibre.com>
Message-ID: <20240206143711.2410135-2-msp@baylibre.com>

The actual size that nvmem is using internally on a specific platform
with a specific devicetree may not be known in the consumer code. The
maximum size may be available at the same time.

Allow the use of larger buffers in nvmem_cell_read_common() by setting
buffers that are too large to zero before copying into them.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 drivers/nvmem/core.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 980123fb4dde..6fa061ede605 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1806,12 +1806,14 @@ static int nvmem_cell_read_common(struct device *dev, const char *cell_id,
 		nvmem_cell_put(cell);
 		return PTR_ERR(buf);
 	}
-	if (len != count) {
+	if (len > count) {
 		kfree(buf);
 		nvmem_cell_put(cell);
 		return -EINVAL;
+	} else if (len < count) {
+		memset(val + len, 0, count - len);
 	}
-	memcpy(val, buf, count);
+	memcpy(val, buf, len);
 	kfree(buf);
 	nvmem_cell_put(cell);
 
-- 
2.43.0



From msp at baylibre.com  Tue Feb  6 06:37:09 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue,  6 Feb 2024 15:37:09 +0100
Subject: [PATCH 2/4] dt-bindings: hwinfo: ti,k3-socinfo: Add nvmem-cells
In-Reply-To: <20240206143711.2410135-1-msp@baylibre.com>
References: <20240206143711.2410135-1-msp@baylibre.com>
Message-ID: <20240206143711.2410135-3-msp@baylibre.com>

The information k3-socinfo requires is stored in an efuse area. This
area is required by other devices/drivers as well, so using nvmem-cells
can be a cleaner way to describe which information are used.

If nvmem-cells are supplied, the address range is not required.
Cells chipvariant, chippartno and chipmanufacturer are introduced to
cover all required information.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
Reviewed-by: Andrew Davis <afd at ti.com>
---
 .../bindings/hwinfo/ti,k3-socinfo.yaml        | 23 ++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
index dada28b47ea0..f085b7275b7d 100644
--- a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
+++ b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
@@ -26,9 +26,24 @@ properties:
   reg:
     maxItems: 1
 
+  nvmem-cells:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+  nvmem-cell-names:
+    items:
+      - const: chipvariant
+      - const: chippartno
+      - const: chipmanufacturer
+
 required:
   - compatible
-  - reg
+
+oneOf:
+  - required:
+      - reg
+  - required:
+      - nvmem-cells
+      - nvmem-cell-names
 
 additionalProperties: false
 
@@ -38,3 +53,9 @@ examples:
         compatible = "ti,am654-chipid";
         reg = <0x43000014 0x4>;
     };
+  - |
+    chipid: chipid at 14 {
+        compatible = "ti,am654-chipid";
+        nvmem-cells = <&chip_variant>, <&chip_partno>, <&chip_manufacturer>;
+        nvmem-cell-names = "chipvariant", "chippartno", "chipmanufacturer";
+    };
-- 
2.43.0



From msp at baylibre.com  Tue Feb  6 06:37:10 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue,  6 Feb 2024 15:37:10 +0100
Subject: [PATCH 3/4] soc: ti: k3-socinfo: Add support for nvmem cells
In-Reply-To: <20240206143711.2410135-1-msp@baylibre.com>
References: <20240206143711.2410135-1-msp@baylibre.com>
Message-ID: <20240206143711.2410135-4-msp@baylibre.com>

Support nvmem cells to retrieve chip variant, part number and
manufacturer. As multiple different devices depend on these information
it is cleaner to abstract efuse fields with nvmem cells.

If chipvariant nvmem cell is found, the driver assumes nvmem cells are
being used and tries to find the other fields as well. If it can't find
'chipvariant' it will try to create a regmap.

Some prints had to be updated as I don't read the full jtagid anymore.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
Acked-by: Andrew Davis <afd at ti.com>
---
 drivers/soc/ti/k3-socinfo.c | 67 +++++++++++++++++++++++++------------
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/drivers/soc/ti/k3-socinfo.c b/drivers/soc/ti/k3-socinfo.c
index 59101bf7cf23..99794aeb6206 100644
--- a/drivers/soc/ti/k3-socinfo.c
+++ b/drivers/soc/ti/k3-socinfo.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/mfd/syscon.h>
+#include <linux/nvmem-consumer.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/regmap.h>
@@ -114,45 +115,68 @@ static int k3_chipinfo_probe(struct platform_device *pdev)
 	struct regmap *regmap;
 	u32 partno_id;
 	u32 variant;
-	u32 jtag_id;
 	u32 mfg;
 	int ret;
 
-	regmap = device_node_to_regmap(node);
-	if (IS_ERR(regmap))
-		return PTR_ERR(regmap);
-
-	ret = regmap_read(regmap, CTRLMMR_WKUP_JTAGID_REG, &jtag_id);
-	if (ret < 0)
-		return ret;
-
-	mfg = (jtag_id & CTRLMMR_WKUP_JTAGID_MFG_MASK) >>
-	       CTRLMMR_WKUP_JTAGID_MFG_SHIFT;
+	ret = nvmem_cell_read_u32(dev, "chipvariant", &variant);
+	if (ret && ret != -ENOENT)
+		return dev_err_probe(dev, ret,
+				     "Failed to read nvmem cell 'chipvariant': %pe",
+				     ERR_PTR(ret));
+
+	if (ret != -ENOENT) {
+		ret = nvmem_cell_read_u32(dev, "chippartno", &partno_id);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "Failed to read nvmem cell 'chippartno': %pe",
+					     ERR_PTR(ret));
+
+		ret = nvmem_cell_read_u32(dev, "chipmanufacturer", &mfg);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "Failed to read nvmem cell 'chipmanufacturer': %pe",
+					     ERR_PTR(ret));
+	} else {
+		u32 jtag_id;
+
+		regmap = device_node_to_regmap(node);
+		if (IS_ERR(regmap))
+			return PTR_ERR(regmap);
+
+		ret = regmap_read(regmap, CTRLMMR_WKUP_JTAGID_REG, &jtag_id);
+		if (ret < 0)
+			return ret;
+
+		mfg = (jtag_id & CTRLMMR_WKUP_JTAGID_MFG_MASK) >>
+		       CTRLMMR_WKUP_JTAGID_MFG_SHIFT;
+
+		variant = (jtag_id & CTRLMMR_WKUP_JTAGID_VARIANT_MASK) >>
+			  CTRLMMR_WKUP_JTAGID_VARIANT_SHIFT;
+
+		partno_id = (jtag_id & CTRLMMR_WKUP_JTAGID_PARTNO_MASK) >>
+			 CTRLMMR_WKUP_JTAGID_PARTNO_SHIFT;
+	}
 
 	if (mfg != CTRLMMR_WKUP_JTAGID_MFG_TI) {
 		dev_err(dev, "Invalid MFG SoC\n");
 		return -ENODEV;
 	}
 
-	variant = (jtag_id & CTRLMMR_WKUP_JTAGID_VARIANT_MASK) >>
-		  CTRLMMR_WKUP_JTAGID_VARIANT_SHIFT;
-
-	partno_id = (jtag_id & CTRLMMR_WKUP_JTAGID_PARTNO_MASK) >>
-		 CTRLMMR_WKUP_JTAGID_PARTNO_SHIFT;
-
 	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
 	if (!soc_dev_attr)
 		return -ENOMEM;
 
 	ret = k3_chipinfo_partno_to_names(partno_id, soc_dev_attr);
 	if (ret) {
-		dev_err(dev, "Unknown SoC JTAGID[0x%08X]: %d\n", jtag_id, ret);
+		dev_err(dev, "Unknown SoC JTAGID[variant=0x%X, partno=0x%X]: %d\n",
+			variant, partno_id, ret);
 		goto err;
 	}
 
 	ret = k3_chipinfo_variant_to_sr(partno_id, variant, soc_dev_attr);
 	if (ret) {
-		dev_err(dev, "Unknown SoC SR[0x%08X]: %d\n", jtag_id, ret);
+		dev_err(dev, "Unknown SoC SR[variant=0x%X, partno=0x%X]: %d\n",
+			variant, partno_id, ret);
 		goto err;
 	}
 
@@ -166,9 +190,10 @@ static int k3_chipinfo_probe(struct platform_device *pdev)
 		goto err_free_rev;
 	}
 
-	dev_info(dev, "Family:%s rev:%s JTAGID[0x%08x] Detected\n",
+	dev_info(dev, "Family:%s rev:%s JTAGID[variant=0x%X, partno=0x%X] Detected\n",
 		 soc_dev_attr->family,
-		 soc_dev_attr->revision, jtag_id);
+		 soc_dev_attr->revision,
+		 variant, partno_id);
 
 	return 0;
 
-- 
2.43.0



From msp at baylibre.com  Tue Feb  6 06:37:11 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue,  6 Feb 2024 15:37:11 +0100
Subject: [PATCH 4/4] arm64: dts: ti: k3-am62-wakeup: Add chip efuse nodes
In-Reply-To: <20240206143711.2410135-1-msp@baylibre.com>
References: <20240206143711.2410135-1-msp@baylibre.com>
Message-ID: <20240206143711.2410135-5-msp@baylibre.com>

Add efuse nodes describing chip variant and speed grade.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi | 36 +++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
index fef76f52a52e..14419df43624 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -14,10 +14,44 @@ wkup_conf: syscon at 43000000 {
 		#size-cells = <1>;
 		ranges = <0x0 0x00 0x43000000 0x20000>;
 
+		wkup_efuse: efuse at 0 {
+			compatible = "socionext,uniphier-efuse";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x0 0x200>;
+
+			nvmem-layout {
+				compatible = "fixed-layout";
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				chip_manufacturer: jtagidmfg at 14 {
+					reg = <0x14 0x2>;
+					bits = <1 11>;
+				};
+
+				chip_partno: jtagidpartno at 15 {
+					reg = <0x15 0x3>;
+					bits = <4 16>;
+				};
+
+				chip_variant: jtagidvariant at 17 {
+					reg = <0x17 0x1>;
+					bits = <4 4>;
+				};
+
+				chip_speed: jtaguseridspeed at 18 {
+					reg = <0x18 0x4>;
+					bits = <6 5>;
+				};
+			};
+		};
+
 		chipid: chipid at 14 {
 			bootph-all;
 			compatible = "ti,am654-chipid";
-			reg = <0x14 0x4>;
+			nvmem-cells = <&chip_variant>, <&chip_partno>, <&chip_manufacturer>;
+			nvmem-cell-names = "chipvariant", "chippartno", "chipmanufacturer";
 		};
 	};
 
-- 
2.43.0



From u-kumar1 at ti.com  Tue Feb  6 06:39:05 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Tue, 6 Feb 2024 20:09:05 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <c2b7f22d-f07d-4cac-8a01-af7b014e7ff4@ti.com>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
 <20240206131420.wtitflgav23jto2q@verbally>
 <871q9pzoiq.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <c5b6bd1d-dbb4-4bfb-8b3e-9b0733e2ba5d@ti.com>
 <c2b7f22d-f07d-4cac-8a01-af7b014e7ff4@ti.com>
Message-ID: <a4fdbcfe-e0e0-4280-8638-e39b6b46778e@ti.com>


On 2/6/2024 7:56 PM, CHANDRU DHAVAMANI wrote:
>
> On 06/02/24 19:45, Kumar, Udit wrote:
>>
>> On 2/6/2024 7:24 PM, Kamlesh Gurudasani wrote:
>>> Nishanth Menon <nm at ti.com> writes:
>>>
>>>> On 16:13-20240206, Udit Kumar wrote:
>>>>> Most of clocks and their parents are defined in contiguous range,
>>>>> But in few cases, there is gap in clock numbers[0].
>>>>> Driver assumes clocks to be in contiguous range, and add their clock
>>>>> ids incrementally.
>>>>>
>>>>> New firmware started returning error while calling get_freq and is_on
>>>>> API for non-available clock ids.
>>>>>
>>>>> In this fix, driver checks and adds only valid clock ids.
>>>>>
>>>>> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for 
>>>>> dynamically probing clocks")
>>>>>
>>>>> [0] 
>>>>> https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html 
>>>>>
>>>>> Section Clocks for NAVSS0_CPTS_0 Device,
>>>>> clock id 12-15 not present.
>>>>>
>>>>> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
>>>>> ????????????????? while (num_parents--) {
>>>>> +??????????????????? /* Check if this clock id is valid */
>>>>> +??????????????????? ret = provider->ops->get_freq(provider->sci,
>>>>> +??????????????????????? sci_clk->dev_id, clk_id, &freq);
>>>> get_freq is a bit expensive as it has to walk the clock tree to find
>>>> the clock frequency (at least the first time?). just wondering if
>>>> there is lighter alternative here?
>>>>
>>> How about get_clock? Doesn't read the registers at least.
>>
>> Said API needs, some flags to be passed,
>>
>> Can those flag be set to zero, Chandru ?
>
>
> get_clock doesn't require any flags to be passed.


May be firmware does not need it but? I was referring to

https://elixir.bootlin.com/linux/latest/source/drivers/clk/keystone/sci-clk.c#L78



>
>
>>
>>
>>> Regards,
>>> Kamlesh


From o.rempel at pengutronix.de  Tue Feb  6 06:40:22 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Tue, 6 Feb 2024 15:40:22 +0100
Subject: [PATCH v3 00/17] kexec: Allow preservation of ftrace buffers
In-Reply-To: <c7157097-4727-4360-80a0-20e7d8015e13@amazon.com>
References: <20240117144704.602-1-graf@amazon.com>
 <ZcHrIJ7lxpbkm5sc@pengutronix.de>
 <c7157097-4727-4360-80a0-20e7d8015e13@amazon.com>
Message-ID: <ZcJE1qQy29lR42-G@pengutronix.de>

On Tue, Feb 06, 2024 at 02:43:15PM +0100, Alexander Graf wrote:
> Hey Oleksij!
> 
> On 06.02.24 09:17, Oleksij Rempel wrote:
> > Hi Alexander,
> > 
> > Nice work!
> > 
> > On Wed, Jan 17, 2024 at 02:46:47PM +0000, Alexander Graf wrote:
> > > Make sure to fill ftrace with contents that you want to observe after
> > > kexec.  Then, before you invoke file based "kexec -l", activate KHO:
> > > 
> > >    # echo 1 > /sys/kernel/kho/active
> > >    # kexec -l Image --initrd=initrd -s
> > >    # kexec -e
> > > 
> > > The new kernel will boot up and contain the previous kernel's trace
> > > buffers in /sys/kernel/debug/tracing/trace.
> > Assuming:
> > - we wont to start tracing as early as possible, before rootfs
> >    or initrd would be able to configure it.
> > - traces are stored on a different device, not RAM. For example NVMEM.
> > - Location of NVMEM is different for different board types, but
> >    bootloader is able to give the right configuration to the kernel.
> 
> 
> Let me try to really understand what you're tracing here. Are we talking
> about exposing boot loader traces into Linux [1]? In that case, I think a
> mechanism like [2] is what you're looking for.
> 
> Or do you want to transfer genuine Linux ftrace traces? In that case, why
> would you want to store them outside of RAM?

The high level object of what i need is to find how embedded systems in
fields do break. Since this devices should be always on, there are
different situations where system may reboot. For example, voltage
related issues, temperature, scheduled system updates, HW or SW errors.

To get better understand on what is going on, information should be
collected. But there are some limitations:
- voltage drops can be recorder only with prepared HW:
  https://www.spinics.net/lists/devicetree/msg644030.html

- In case of voltage drops RAM or block devices can't be used. Instead,
  some variant of NVMEM should be used. In my case, NVMEM has 8 bits of
  storage :) So, only one entry of the "trace" is compressed to this storage.
  https://lore.kernel.org/all/20240124122204.730370-1-o.rempel at pengutronix.de
  The reset reason information is provide by kernel and used by firmware
  and kernel on next reboot

The implementation is not a big deal. The problematic part is the way
how the system should get information about existence of recorder and
where the recorder should stored things, for example NVMEM cell.

In my initial implementation I used devicetree to configure the software
based recorder and linked it with NVMEM cell. But it is against the DT
purpose to describe only HW and it makes this recorder unusable for
not DT basd systems.

Krzysztof is suggesting to configure it from initrd. This has own
limitations as well:
 - record can't be used before initrd.
 - we have multiple configuration point of board specific information - 
   firmware (bootloader) and initrd.
 - initrd take place and reduce boot time for device which do not needed
   it before.

Other variants like kernel command-line and/or module parameters seems
to be not acceptable depending maintainer. So, I'm still seeking
proper, acceptable, portable way to hand over not HW specific
information to the kernel.

> > What would be the best, acceptable for mainline, way to provide this
> > kind of configuration? At least part of this information do not
> > describes devices or device states, this would not fit in to devicetree
> > universe. Amount of possible information would not fit in to bootconfig
> > too.
> 
> 
> We have precedence for configuration in device tree: You can use device tree
> to describe partitions on a NAND device, you can use it to specify MAC
> address overrides of devices attached to USB, etc etc. At the end of the day
> when people say they don't want configuration in device tree, what they mean
> is that device tree should be a hand over data structure from firmware to
> kernel, not from OS integrator to kernel :). If your firmware is the place
> that knows about offsets and you need to pass those offsets, IMHO DT is a
> good fit.

Yes, the layout of the NVMEM can be described in the DT. How can I tell
the system that this NVMEM cell should be used by some recorder or
tracer? Before sysfs is available any how. @Krzysztof ?

> > Other more or less overlapping use case I have in mind is a netbootable
> > embedded system with a requirement to boot as fast as possible. Since
> > bootloader already established a link and got all needed ip
> > configuration, it would be able to hand over etherent controller and ip
> > configuration states. Wille be the KHO the way to go for this use case?
> 
> 
> That's an interesting one too. I would lean towards "try with normal device
> tree first" here as well. It's again a very clear case of "firmware wants to
> tell OS about things it knows, but the OS doesn't know" to me. That means
> device tree should be fine to describe it.

I can imagine description of PHY and MAC state. But IP configuration
state of the firmware seems to be out of DT scope?

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 josua at solid-run.com  Tue Feb  6 06:41:05 2024
From: josua at solid-run.com (Josua Mayer)
Date: Tue, 6 Feb 2024 14:41:05 +0000
Subject: [PATCH v4 4/5] arm64: dts: add description for solidrun am642 som
 and evaluation board
In-Reply-To: <6b457759-9a2d-44a7-a1a4-7c7ac42aedae@ti.com>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
 <20240202-add-am64-som-v4-4-5f8b12af5e71@solid-run.com>
 <6b457759-9a2d-44a7-a1a4-7c7ac42aedae@ti.com>
Message-ID: <a2cd8285-106c-480b-9fa3-4c58f60e9a55@solid-run.com>

Am 02.02.24 um 18:09 schrieb Andrew Davis:
> On 2/2/24 10:10 AM, Josua Mayer wrote:
>> Add description for the SolidRun AM642 SoM, and HummingBoard-T
>> evaluation board.
>>
>> The SoM features:
>> - 1x cpsw ethernet with phy
>> - 2x pru ethernet with phy
>> - eMMC
>> - spi flash (assembly option)
>>
>> Additionally microSD and usb-2.0 otg are included in the SoM
>> description as they are supported boot sources for the SOC boot-rom.
>>
>> The Carrier provides:
>> - 3x RJ45 connector
>> - 2x M.2 connector
>> - USB-2.0 Hub
>> - USB-A Connector
>> - LEDs
>> - 2x CAN transceiver
>> - 1x RS485 transceiver
>> - sensors
>>
>> The M.2 connectors support either USB-3.1 or PCI-E depending on status
>> of a mux. By default the mux is switched off.
>>
>> Signed-off-by: Josua Mayer <josua at solid-run.com>
>> ---
>> ? arch/arm64/boot/dts/ti/Makefile??????????????????? |?? 1 +
>> ? arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
>> ? arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi??????? | 592 +++++++++++++++++++++
>> ? 3 files changed, 885 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
>> index 77a347f9f47d..041c3b71155e 100644
>> --- a/arch/arm64/boot/dts/ti/Makefile
>> +++ b/arch/arm64/boot/dts/ti/Makefile
>> @@ -32,6 +32,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb
>> ? ? # Boards with AM64x SoC
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
>> +dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
>> new file mode 100644
>> index 000000000000..ebaf281e1e1e
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
>> @@ -0,0 +1,292 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
>> + *
>> + * DTS for SolidRun AM642 HummingBoard-T,
>> + * running on Cortex A53.
>> + *
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include <dt-bindings/leds/common.h>
>> +#include <dt-bindings/phy/phy.h>
>> +
>> +#include "k3-am642.dtsi"
>> +#include "k3-am642-sr-som.dtsi"
>> +
>> +/ {
>> +??? model = "SolidRun AM642 HummingBoard-T";
>> +??? compatible = "solidrun,am642-hummingboard-t", "solidrun,am642-sr-som", "ti,am642";
>> +
>> +??? aliases {
>> +??????? serial5 = &main_uart3;
>> +??? };
>> +
>> +??? leds {
>> +??????? compatible = "gpio-leds";
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&leds_pins_default>;
>> +
>> +??????? /* D24 */
>> +??????? led1: led-1 {
>> +??????????? label = "led1";
>> +??????????? gpios = <&main_gpio0 29 GPIO_ACTIVE_HIGH>;
>> +??????????? color = <LED_COLOR_ID_GREEN>;
>> +??????? };
>> +
>> +??????? /* D25 */
>> +??????? led2: led-2 {
>> +??????????? label = "led2";
>> +??????????? gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
>> +??????????? color = <LED_COLOR_ID_GREEN>;
>> +??????? };
>> +
>> +??????? /* D26 */
>> +??????? led3: led-3 {
>> +??????????? label = "led3";
>> +??????????? gpios = <&main_gpio0 33 GPIO_ACTIVE_HIGH>;
>> +??????????? color = <LED_COLOR_ID_GREEN>;
>> +??????? };
>> +??? };
>> +
>> +??? regulator-m2-3v3 {
>> +??????? compatible = "regulator-fixed";
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&regulator_pcie_3v3_pins_default>;
>> +??????? regulator-name = "m2-3v3";
>> +??????? regulator-min-microvolt = <3300000>;
>> +??????? regulator-max-microvolt = <3300000>;
>> +??????? gpio = <&main_gpio1 17 GPIO_ACTIVE_HIGH>;
>> +??????? enable-active-high;
>> +??????? regulator-always-on;
>> +??? };
>> +
>> +??? regulator-vpp-1v8 {
>> +??????? compatible = "regulator-fixed";
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&regulator_vpp_1v8_pins_default>;
>> +??????? regulator-name = "vpp-1v8";
>> +??????? regulator-min-microvolt = <1800000>;
>> +??????? regulator-max-microvolt = <1800000>;
>> +??????? gpio = <&main_gpio1 78 GPIO_ACTIVE_HIGH>;
>> +??????? enable-active-high;
>> +??? };
>> +
>> +??? serdes_mux: mux-controller {
>> +??????? compatible = "gpio-mux";
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&serdes_mux_pins_default>;
>> +??????? #mux-control-cells = <0>;
>> +??????? /*
>> +???????? * Mux has 2 IOs:
>> +???????? * - select: 0 = USB-3 (M2); 1 = PCIE (M1)
>> +???????? * - shutdown: 0 = active; 1 = disabled (high impedance)
>> +???????? */
>> +??????? mux-gpios = <&main_gpio1 40 GPIO_ACTIVE_HIGH>, <&main_gpio1 41 GPIO_ACTIVE_HIGH>;
>> +??????? /* default disabled */
>> +??????? idle-state = <2>;
>> +??? };
>> +};
>> +
>> +&main_gpio0 {
>> +??? m2-reset-hog {
>> +??????? gpio-hog;
>> +??????? gpios = <12 GPIO_ACTIVE_LOW>;
>> +??????? output-low; /* deasserted */
>> +??????? line-name = "m2-reset";
>> +??? };
>> +
>> +??? m1-m2-w-disable1-hog {
>> +??????? gpio-hog;
>> +??????? gpios = <32 GPIO_ACTIVE_LOW>;
>> +??????? output-low; /* deasserted */
>> +??????? line-name = "m1-m2-pcie-w-disable1";
>> +??? };
>> +
>> +??? m1-m2-w-disable2-hog {
>> +??????? gpio-hog;
>> +??????? gpios = <34 GPIO_ACTIVE_LOW>;
>> +??????? output-low; /* deasserted */
>> +??????? line-name = "m1-m2-pcie-w-disable2";
>> +??? };
>> +};
>> +
>> +&main_gpio1 {
>> +??? m1-pcie-clkreq0-hog {
>> +??????? gpio-hog;
>> +??????? gpios = <11 GPIO_ACTIVE_LOW>;
>> +??????? input;
>> +??????? line-name = "m1-pcie-clkreq0";
>> +??? };
>> +
>> +??? m2-pcie-clkreq-hog {
>> +??????? gpio-hog;
>> +??????? gpios = <35 GPIO_ACTIVE_LOW>;
>> +??????? input;
>> +??????? line-name = "m2-pcie-clkreq";
>> +??? };
>> +};
>> +
>> +&main_i2c0 {
>> +??? pinctrl-0 = <&main_i2c0_pins_default>, <&main_i2c0_int_pins_default>;
>> +
>> +??? humidity-sensor at 41 {
>> +??????? compatible = "ti,hdc2010";
>> +??????? reg = <0x41>;
>> +??????? interrupt-parent = <&main_gpio0>;
>> +??????? interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
>> +??? };
>> +
>> +??? light-sensor at 44 {
>> +??????? compatible = "ti,opt3001";
>> +??????? reg = <0x44>;
>> +??????? interrupt-parent = <&main_gpio0>;
>> +??????? interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
>> +??? };
>> +
>> +??? /* charger at 6a */
>> +};
>> +
>> +&main_i2c1 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&main_i2c1_pins_default>;
>> +??? status = "okay";
>> +
>> +??? rtc at 69 {
>> +??????? compatible = "abracon,abx80x";
>> +??????? reg = <0x69>;
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&rtc_int_pins_default>;
>> +??????? abracon,tc-diode = "schottky";
>> +??????? abracon,tc-resistor = <3>;
>> +??????? interrupt-parent = <&main_gpio0>;
>> +??????? interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
>> +??? };
>> +};
>> +
>> +&main_mcan0 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&main_mcan0_pins_default>;
>> +??? status = "okay";
>> +
>> +??? can-transceiver {
>> +??????? max-bitrate = <8000000>;
>> +??? };
>> +};
>> +
>> +&main_mcan1 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&main_mcan1_pins_default>;
>> +??? status = "okay";
>> +
>> +??? can-transceiver {
>> +??????? max-bitrate = <8000000>;
>> +??? };
>> +};
>> +
>> +&main_pmx0 {
>> +??? leds_pins_default: leds-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x0074, PIN_OUTPUT, 7)??? /* GPMC0_AD14.GPIO0_29 */
>> +??????????? AM64X_IOPAD(0x0078, PIN_OUTPUT, 7)??? /* GPMC0_AD15.GPIO0_30 */
>> +??????????? AM64X_IOPAD(0x0088, PIN_OUTPUT, 7)??? /* GPMC0_OEn_REn.GPIO0_33 */
>> +??????? >;
>> +??? };
>> +
>> +??? main_i2c0_int_pins_default: main-i2c0-pins-int-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* external pull-up on Carrier */
>> +??????????? AM64X_IOPAD(0x0098, PIN_INPUT, 7)??? /* GPMC0_WAIT0.GPIO0_37 */
>> +??????? >;
>> +??? };
>> +
>> +??? main_i2c1_pins_default: main-i2c1-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* external pull-up on SoM */
>> +??????????? AM64X_IOPAD(0x0268, PIN_INPUT, 0)??? /* I2C1_SCL.I2C1_SCL */
>> +??????????? AM64X_IOPAD(0x026c, PIN_INPUT, 0)??? /* I2C1_SDA.I2C1_SDA */
>> +??????? >;
>> +??? };
>> +
>> +??? main_mcan0_pins_default: main-mcan0-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x0254, PIN_INPUT, 0)??? /* MCAN0_RX.MCAN0_RX */
>> +??????????? AM64X_IOPAD(0x0250, PIN_OUTPUT, 0)??? /* MCAN0_TX.MCAN0_TX */
>> +??????? >;
>> +??? };
>> +
>> +??? main_mcan1_pins_default: main-mcan1-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x025c, PIN_INPUT, 0)??? /* MCAN1_RX.MCAN1_RX */
>> +??????????? AM64X_IOPAD(0x0258, PIN_OUTPUT, 0)??? /* MCAN1_TX.MCAN1_TX */
>> +??????? >;
>> +??? };
>> +
>> +??? main_uart3_pins_default: main-uart3-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x016c, PIN_INPUT, 10)??? /* PRG0_PRU0_GPO3.UART3_CTSn */
>> +??????????? AM64X_IOPAD(0x0170, PIN_OUTPUT, 10)??? /* PRG0_PRU0_GPO4.UART3_TXD */
>> +??????????? AM64X_IOPAD(0x0174, PIN_OUTPUT, 10)??? /* PRG0_PRU0_GPO5.UART3_RTSn */
>> +??????????? AM64X_IOPAD(0x01ac, PIN_INPUT, 10)??? /* PRG0_PRU0_GPO19.UART3_RXD */
>> +??????? >;
>> +??? };
>> +
>> +??? pcie0_pins_default: pcie0-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* connector M2 RESET */
>> +??????????? AM64X_IOPAD(0x0030, PIN_OUTPUT, 7)??? /* OSPI0_CSn1.GPIO0_12 */
>> +??????????? /* connectors M1 & M2 W_DISABLE1 */
>> +??????????? AM64X_IOPAD(0x0084, PIN_OUTPUT, 7)??? /* GPMC0_ADVN_ALE.GPIO0_32 */
>> +??????????? /* connectors M1 & M2 W_DISABLE2 */
>> +??????????? AM64X_IOPAD(0x008c, PIN_OUTPUT, 7)??? /* GPMC0_WEN.GPIO0_34 */
>> +??????????? /* connectors M1 & M2 PERST0 (PCI Reset) */
>> +??????????? AM64X_IOPAD(0x019c, PIN_OUTPUT, 7)??? /* PRG0_PRU0_GPO15.GPIO1_15 */
>> +??????????? /* connector M1 CLKREQ0 */
>> +??????????? AM64X_IOPAD(0x018c, PIN_INPUT, 7)??? /* PRG0_PRU0_GPO11.GPIO1_11 */
>> +??????????? /* connector M2 CLKREQ0 */
>> +??????????? AM64X_IOPAD(0x01ec, PIN_INPUT, 7)??? /* PRG0_PRU1_GPO15.GPIO1_35 */
>> +??????? >;
>> +??? };
>> +
>> +??? regulator_pcie_3v3_pins_default: regulator-pcie-3v3-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x01a4, PIN_OUTPUT, 7)??? /* PRG0_PRU0_GPO17.GPIO1_17 */
>> +??????? >;
>> +??? };
>> +
>> +??? regulator_vpp_1v8_pins_default: regulator-vpp-1v8-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x029c, PIN_OUTPUT, 7)??? /* MMC1_SDWP.GPIO1_78 */
>> +??????? >;
>> +??? };
>> +
>> +??? rtc_int_pins_default: rtc-int-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* external pull-up on Carrier */
>> +??????????? AM64X_IOPAD(0x00b4, PIN_INPUT, 7)??? /* GPMC0_CSn3.GPIO0_44 */
>> +??????? >;
>> +??? };
>> +
>> +??? serdes_mux_pins_default: serdes-mux-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* SEL, 10k pull-down on carrier, 2.2k pullup on SoM */
>> +??????????? AM64X_IOPAD(0x0200, PIN_OUTPUT, 7)??? /* PRG0_MDIO0_MDIO.GPIO1_40 */
>> +??????????? /* EN */
>> +??????????? AM64X_IOPAD(0x0204, PIN_OUTPUT, 7)??? /* PRG0_MDIO0_MDC.GPIO1_41 */
>> +??????? >;
>> +??? };
>> +};
>> +
>> +&main_uart3 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&main_uart3_pins_default>;
>> +??? uart-has-rtscts;
>> +??? rs485-rts-active-low;
>> +??? linux,rs485-enabled-at-boot-time;
>> +??? status = "okay";
>> +};
>> +
>> +&usb0 {
>> +??? dr_mode = "host";
>> +};
>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
>> new file mode 100644
>> index 000000000000..83b73d433508
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
>> @@ -0,0 +1,592 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
>> + *
>> + */
>> +
>> +#include <dt-bindings/net/ti-dp83869.h>
>> +
>> +/ {
>> +??? model = "SolidRun AM642 SoM";
>> +??? compatible = "solidrun,am642-sr-som", "ti,am642";
>> +
>> +??? aliases {
>> +??????? ethernet0 = &cpsw_port1;
>> +??????? ethernet1 = &icssg1_emac0;
>> +??????? ethernet2 = &icssg1_emac1;
>> +??????? mmc0 = &sdhci0;
>> +??????? mmc1 = &sdhci1;
>> +??????? serial2 = &main_uart0;
>> +??? };
>> +
>> +??? chosen {
>> +??????? /* SoC default UART console */
>> +??????? stdout-path = "serial2:115200n8";
>> +??? };
>> +
>> +??? /* PRU Ethernet Controller */
>> +??? ethernet {
>> +??????? compatible = "ti,am642-icssg-prueth";
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&pru_rgmii1_pins_default>, <&pru_rgmii2_pins_default>;
>> +
>> +??????? sram = <&oc_sram>;
>> +??????? ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
>> +??????? firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
>> +??????????????? "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
>> +??????????????? "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
>> +??????????????? "ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
>> +??????????????? "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
>> +??????????????? "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
>> +
>> +??????? /* configure internal pinmux for mii mode */
>> +??????? ti,pruss-gp-mux-sel = <2>, <2>, <2>, <2>, <2>, <2>;
>> +
>> +??????? ti,mii-g-rt = <&icssg1_mii_g_rt>;
>> +??????? ti,mii-rt = <&icssg1_mii_rt>;
>> +??????? ti,iep = <&icssg1_iep0>, <&icssg1_iep1>;
>> +
>> +??????? /*
>> +???????? * Configure icssg interrupt controller to map pru-internal
>> +???????? * interrupts 8/9 via channels 0/1 to host interrupts 0/1.
>> +???????? *
>> +???????? * For details see interrupt controller documentation:
>> +???????? * Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
>> +???????? */
>> +??????? interrupt-parent = <&icssg1_intc>;
>> +??????? interrupts = <24 0 2>, <25 1 3>;
>> +??????? interrupt-names = "tx_ts0", "tx_ts1";
>> +
>> +??????? dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
>> +?????????????? <&main_pktdma 0xc201 15>, /* egress slice 0 */
>> +?????????????? <&main_pktdma 0xc202 15>, /* egress slice 0 */
>> +?????????????? <&main_pktdma 0xc203 15>, /* egress slice 0 */
>> +?????????????? <&main_pktdma 0xc204 15>, /* egress slice 1 */
>> +?????????????? <&main_pktdma 0xc205 15>, /* egress slice 1 */
>> +?????????????? <&main_pktdma 0xc206 15>, /* egress slice 1 */
>> +?????????????? <&main_pktdma 0xc207 15>, /* egress slice 1 */
>> +?????????????? <&main_pktdma 0x4200 15>, /* ingress slice 0 */
>> +?????????????? <&main_pktdma 0x4201 15>; /* ingress slice 1 */
>> +??????? dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
>> +??????????????? "tx1-0", "tx1-1", "tx1-2", "tx1-3",
>> +??????????????? "rx0", "rx1";
>> +
>> +??????? ethernet-ports {
>> +??????????? #address-cells = <1>;
>> +??????????? #size-cells = <0>;
>> +
>> +??????????? icssg1_emac0: port at 0 {
>> +??????????????? reg = <0>;
>> +??????????????? ti,syscon-rgmii-delay = <&main_conf 0x4110>;
>> +??????????????? /* Filled in by bootloader */
>> +??????????????? local-mac-address = [00 00 00 00 00 00];
>> +??????????????? phy-handle = <&ethernet_phy2>;
>> +??????????????? phy-mode = "rgmii-id";
>> +??????????? };
>> +
>> +??????????? icssg1_emac1: port at 1 {
>> +??????????????? reg = <1>;
>> +??????????????? ti,syscon-rgmii-delay = <&main_conf 0x4114>;
>> +??????????????? /* Filled in by bootloader */
>> +??????????????? local-mac-address = [00 00 00 00 00 00];
>> +??????????????? phy-handle = <&ethernet_phy1>;
>> +??????????????? phy-mode = "rgmii-id";
>> +??????????? };
>> +??????? };
>> +??? };
>> +
>> +??? /* DDR16SS0:
>> +???? * - Bank 1 @ 0x080000000-0x0FFFFFFFF: max. 2GB in 32-bit address space
>> +???? * - Bank 2 @ 0x880000000-0x9FFFFFFFF: max. 6GB in 64-bit address space
>> +???? */
>> +??? memory at 80000000 {
>> +??????? reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
>> +????????????? <0x00000008 0x80000000 0x00000001 0x80000000>;
>> +??????? device_type = "memory";
>> +??? };
>> +
>> +??? reserved-memory {
>> +??????? #address-cells = <2>;
>> +??????? #size-cells = <2>;
>> +??????? ranges;
>> +
>> +??????? secure_ddr: optee at 9e800000 {
>> +??????????? reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
>> +??????????? no-map;
>> +??????? };
>> +
>> +??????? main_r5fss0_core0_dma_memory_region: r5f-dma-memory at a0000000 {
>> +??????????? compatible = "shared-dma-pool";
>> +??????????? reg = <0x00 0xa0000000 0x00 0x100000>;
>> +??????????? no-map;
>> +??????? };
>> +
>> +??????? main_r5fss0_core0_memory_region: r5f-memory at a0100000 {
>> +??????????? compatible = "shared-dma-pool";
>> +??????????? reg = <0x00 0xa0100000 0x00 0xf00000>;
>> +??????????? no-map;
>> +??????? };
>> +
>> +??????? main_r5fss0_core1_dma_memory_region: r5f-dma-memory at a1000000 {
>> +??????????? compatible = "shared-dma-pool";
>> +??????????? reg = <0x00 0xa1000000 0x00 0x100000>;
>> +??????????? no-map;
>> +??????? };
>> +
>> +??????? main_r5fss0_core1_memory_region: r5f-memory at a1100000 {
>> +??????????? compatible = "shared-dma-pool";
>> +??????????? reg = <0x00 0xa1100000 0x00 0xf00000>;
>> +??????????? no-map;
>> +??????? };
>> +
>> +??????? main_r5fss1_core0_dma_memory_region: r5f-dma-memory at a2000000 {
>> +??????????? compatible = "shared-dma-pool";
>> +??????????? reg = <0x00 0xa2000000 0x00 0x100000>;
>> +??????????? no-map;
>> +??????? };
>> +
>> +??????? main_r5fss1_core0_memory_region: r5f-memory at a2100000 {
>> +??????????? compatible = "shared-dma-pool";
>> +??????????? reg = <0x00 0xa2100000 0x00 0xf00000>;
>> +??????????? no-map;
>> +??????? };
>> +
>> +??????? main_r5fss1_core1_dma_memory_region: r5f-dma-memory at a3000000 {
>> +??????????? compatible = "shared-dma-pool";
>> +??????????? reg = <0x00 0xa3000000 0x00 0x100000>;
>> +??????????? no-map;
>> +??????? };
>> +
>> +??????? main_r5fss1_core1_memory_region: r5f-memory at a3100000 {
>> +??????????? compatible = "shared-dma-pool";
>> +??????????? reg = <0x00 0xa3100000 0x00 0xf00000>;
>> +??????????? no-map;
>> +??????? };
>> +??? };
>> +
>> +??? vdd_mmc0: regulator-vdd-mmc0 {
>> +??????? compatible = "regulator-fixed";
>> +??????? regulator-name = "vdd-mmc0";
>> +??????? regulator-min-microvolt = <1800000>;
>> +??????? regulator-max-microvolt = <1800000>;
>> +??????? regulator-always-on;
>> +??????? regulator-boot-on;
>> +??? };
>> +};
>> +
>> +&cpsw3g {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&rgmii1_pins_default>;
>> +};
>> +
>> +&cpsw3g_mdio {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&mdio0_pins_default>;
>> +??? status = "okay";
>> +
>> +??? ethernet_phy0: ethernet-phy at 0 {
>> +??????? compatible = "ethernet-phy-id2000.a0f1";
>> +??????? reg = <0>;
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&ethernet_phy0_pins_default>;
>> +??????? ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
>> +??????? ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
>> +??????? /*
>> +???????? * Disable interrupts because ISR never clears 0x0040
>> +???????? *
>> +???????? * interrupt-parent = <&main_gpio1>;
>> +???????? * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
>> +???????? */
>> +??????? /*
>> +???????? * Disable HW Reset because clock signal is daisy-chained
>> +???????? *
>> +???????? * reset-gpios = <&main_gpio0 84 GPIO_ACTIVE_LOW>;
>> +???????? * reset-assert-us = <1>;
>> +???????? * reset-deassert-us = <30>;
>> +???????? */
>> +??? };
>> +};
>> +
>> +&cpsw_port1 {
>> +??? phy-mode = "rgmii-id";
>> +??? phy-handle = <&ethernet_phy0>;
>> +};
>> +
>> +&cpsw_port2 {
>> +??? status = "disabled";
>> +};
>> +
>> +&icssg1_mdio {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&pru1_mdio0_pins_default>;
>> +??? status = "okay";
>> +
>> +??? ethernet_phy1: ethernet-phy at 3 {
>> +??????? compatible = "ethernet-phy-id2000.a0f1";
>> +??????? reg = <3>;
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&ethernet_phy1_pins_default>;
>> +??????? ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
>> +??????? ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
>> +??????? /*
>> +???????? * Disable interrupts because ISR never clears 0x0040
>> +???????? *
>> +???????? * interrupt-parent = <&main_gpio1>;
>> +???????? * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
>> +???????? */
>> +??????? /*
>> +???????? * Disable HW Reset because clock signal is daisy-chained
>> +???????? *
>> +???????? * reset-gpios = <&main_gpio0 20 GPIO_ACTIVE_LOW>;
>> +???????? * reset-assert-us = <1>;
>> +???????? * reset-deassert-us = <30>;
>> +???????? */
>> +??? };
>> +
>> +??? ethernet_phy2: ethernet-phy at f {
>> +??????? compatible = "ethernet-phy-id2000.a0f1";
>> +??????? reg = <0xf>;
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&ethernet_phy2_pins_default>;
>> +??????? ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
>> +??????? /*
>> +???????? * Disable interrupts because ISR never clears 0x0040
>> +???????? *
>> +???????? * interrupt-parent = <&main_gpio1>;
>> +???????? * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
>> +???????? */
>> +??????? /*
>> +???????? * Disable HW Reset because clock signal is daisy-chained
>> +???????? *
>> +???????? * reset-gpios = <&main_gpio0 52 GPIO_ACTIVE_LOW>;
>> +???????? * reset-assert-us = <1>;
>> +???????? * reset-deassert-us = <30>;
>> +???????? */
>> +??? };
>> +};
>> +
>> +&mailbox0_cluster2 {
>> +??? status = "okay";
>> +
>> +??? mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
>> +??????? ti,mbox-rx = <0 0 2>;
>> +??????? ti,mbox-tx = <1 0 2>;
>> +??? };
>> +
>> +??? mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
>> +??????? ti,mbox-rx = <2 0 2>;
>> +??????? ti,mbox-tx = <3 0 2>;
>> +??? };
>> +};
>> +
>> +&mailbox0_cluster4 {
>> +??? status = "okay";
>> +
>> +??? mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
>> +??????? ti,mbox-rx = <0 0 2>;
>> +??????? ti,mbox-tx = <1 0 2>;
>> +??? };
>> +
>> +??? mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
>> +??????? ti,mbox-rx = <2 0 2>;
>> +??????? ti,mbox-tx = <3 0 2>;
>> +??? };
>> +};
>> +
>> +&main_i2c0 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&main_i2c0_pins_default>;
>> +??? status = "okay";
>> +
>> +??? som_eeprom: eeprom at 50 {
>> +??????? compatible = "atmel,24c01";
>> +??????? reg = <0x50>;
>> +??????? pagesize = <8>;
>> +??? };
>> +};
>> +
>> +&main_pmx0 {
>> +??? /* hog global functions */
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&ethernet_phy_pins_default>;
>> +
>> +??? ethernet_phy_pins_default: ethernet-phy-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* interrupt / power-down, external pull-up on SoM */
>> +??????????? AM64X_IOPAD(0x0278, PIN_INPUT, 7)??? /* EXTINTn.GPIO1_70 */
>> +??????? >;
>> +??? };
>> +
>> +??? ethernet_phy0_pins_default: ethernet-phy0-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* reset */
>> +??????????? AM64X_IOPAD(0x0154, PIN_OUTPUT, 7)??? /* PRG1_PRU1_GPO19.GPIO0_84 */
>> +??????????? /* reference clock */
>> +??????????? AM64X_IOPAD(0x0274, PIN_OUTPUT, 5)??? /* EXT_REFCLK1.CLKOUT0 */
>> +??????? >;
>> +??? };
>> +
>> +??? ethernet_phy1_pins_default: ethernet-phy1-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* reset */
>> +??????????? AM64X_IOPAD(0x0150, PIN_OUTPUT, 7)??? /* PRG1_PRU1_GPO18.GPIO0_20 */
>> +??????????? /* led0, external pull-down on SoM */
>> +??????????? AM64X_IOPAD(0x0128, PIN_INPUT, 7)??? /* PRG1_PRU1_GPO8.GPIO0_73 */
>> +??????????? /* led1/rxer */
>> +??????????? AM64X_IOPAD(0x011c, PIN_INPUT, 7)??? /* PRG1_PRU1_GPO5.GPIO0_70 */
>> +??????? >;
>> +??? };
>> +
>> +??? ethernet_phy2_pins_default: ethernet-phy2-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* reset */
>> +??????????? AM64X_IOPAD(0x00d4, PIN_OUTPUT, 7)??? /* PRG1_PRU0_GPO7.GPIO0_52 */
>> +??????????? /* led0, external pull-down on SoM */
>> +??????????? AM64X_IOPAD(0x00d8, PIN_INPUT, 7)??? /* PRG1_PRU0_GPO8.GPIO0_53 */
>> +??????????? /* led1/rxer */
>> +??????????? AM64X_IOPAD(0x00cc, PIN_INPUT, 7)??? /* PRG1_PRU0_GPO5.GPIO0_50 */
>> +??????? >;
>> +??? };
>> +
>> +??? main_i2c0_pins_default: main-i2c0-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* external pull-up on SoM */
>> +??????????? AM64X_IOPAD(0x0260, PIN_INPUT, 0)??? /* I2C0_SCL.I2C0_SCL */
>> +??????????? AM64X_IOPAD(0x0264, PIN_INPUT, 0)??? /* I2C0_SDA.I2C0_SDA */
>> +??????? >;
>> +??? };
>> +
>> +??? /*
>> +???? * main_mmc0_pins_default: main-mmc0-pins-default
>> +???? *
>> +???? * MMC0_CMD: no padconfig
>> +???? * MMC0_CLK: no padconfig, external pull-up on SoM
>> +???? * MMC0_DAT0: no padconfig
>> +???? * MMC0_DAT1: no padconfig
>> +???? * MMC0_DAT2: no padconfig
>> +???? * MMC0_DAT3: no padconfig
>> +???? * MMC0_DAT4: no padconfig
>> +???? * MMC0_DAT5: no padconfig
>> +???? * MMC0_DAT6: no padconfig
>> +???? * MMC0_DAT7: no padconfig
>> +???? * MMC0_DS: no padconfig, external pull-down on SoM
>> +???? */
>> +
>> +??? main_mmc1_pins_default: main-mmc1-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x0294, PIN_INPUT_PULLUP, 0)??? /* (J19) MMC1_CMD */
>> +??????????? AM64X_IOPAD(0x028c, PIN_INPUT, 0)??????? /* MMC1_CLK.MMC1_CLK */
>> +??????????? AM64X_IOPAD(0x0288, PIN_INPUT_PULLUP, 0)??? /* MMC1_DAT0.MMC1_DAT0 */
>> +??????????? AM64X_IOPAD(0x0284, PIN_INPUT_PULLUP, 0)??? /* MMC1_DAT1.MMC1_DAT1 */
>> +??????????? AM64X_IOPAD(0x0280, PIN_INPUT_PULLUP, 0)??? /* MMC1_DAT2.MMC1_DAT2 */
>> +??????????? AM64X_IOPAD(0x027c, PIN_INPUT_PULLUP, 0)??? /* MMC1_DAT3.MMC1_DAT3 */
>> +??????????? /* external pull-down on SoM & Carrier */
>> +??????????? AM64X_IOPAD(0x0298, PIN_INPUT_PULLUP, 0)??? /* MMC1_SDCD.MMC1_SDCD */
>> +??????????? AM64X_IOPAD(0x0290, PIN_INPUT, 0)??????? /* MMC1_CLKLB: clock loopback */
>> +??????? >;
>> +??? };
>> +
>> +??? main_uart0_pins_default: main-uart0-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x0230, PIN_INPUT, 0)??????? /* UART0_RXD.UART0_RXD */
>> +??????????? AM64X_IOPAD(0x0234, PIN_OUTPUT, 0)??????? /* UART0_TXD.UART0_TXD */
>> +??????? >;
>> +??? };
>> +
>> +??? mdio0_pins_default: mdio0-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x01fc, PIN_OUTPUT, 4)??????? /* PRG0_PRU1_GPO19.MDIO0_MDC */
>> +??????????? AM64X_IOPAD(0x01f8, PIN_INPUT, 4)??????? /* PRG0_PRU1_GPO18.MDIO0_MDIO */
>> +??????? >;
>> +??? };
>> +
>> +??? ospi0_pins_default: ospi0-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? /* external pull-down on SoM */
>> +??????????? AM64X_IOPAD(0x0000, PIN_OUTPUT, 0)??????? /* OSPI0_CLK.OSPI0_CLK */
>> +??????????? AM64X_IOPAD(0x0008, PIN_OUTPUT, 0)??????? /* OSPI0_DQS.OSPI0_DQS */
>> +??????????? /* external pull-up on SoM */
>> +??????????? AM64X_IOPAD(0x002c, PIN_OUTPUT, 0)??????? /* OSPI0_CSn0.OSPI0_CSn0 */
>> +??????????? AM64X_IOPAD(0x000c, PIN_INPUT, 0)??????? /* OSPI0_D0.OSPI0_D0 */
>> +??????????? AM64X_IOPAD(0x0010, PIN_INPUT, 0)??????? /* OSPI0_D1.OSPI0_D1 */
>> +??????????? AM64X_IOPAD(0x0014, PIN_INPUT, 0)??????? /* OSPI0_D2.OSPI0_D2 */
>> +??????????? AM64X_IOPAD(0x0018, PIN_INPUT, 0)??????? /* OSPI0_D3.OSPI0_D3 */
>> +??????????? AM64X_IOPAD(0x001c, PIN_INPUT, 0)??????? /* OSPI0_D4.OSPI0_D4 */
>> +??????????? AM64X_IOPAD(0x0020, PIN_INPUT, 0)??????? /* OSPI0_D5.OSPI0_D5 */
>> +??????????? AM64X_IOPAD(0x0024, PIN_INPUT, 0)??????? /* OSPI0_D6.OSPI0_D6 */
>> +??????????? AM64X_IOPAD(0x0028, PIN_INPUT, 0)??????? /* OSPI0_D7.OSPI0_D7 */
>> +??????? >;
>> +??? };
>> +
>> +??? ospi0_flash0_pins_default: ospi0-flash0-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x0034, PIN_OUTPUT, 7)??????? /* OSPI0_CSn2.GPIO0_13 */
>> +??????????? AM64X_IOPAD(0x0038, PIN_INPUT, 7)??????? /* OSPI0_CSn3.GPIO0_14 */
>> +??????? >;
>> +??? };
>> +
>> +??? pru1_mdio0_pins_default: pru1-mdio0-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x015c, PIN_OUTPUT, 0)??????? /* PRG1_MDIO0_MDC.PRG1_MDIO0_MDC */
>> +??????????? AM64X_IOPAD(0x0158, PIN_INPUT, 0)??????? /* PRG1_MDIO0_MDIO.PRG1_MDIO0_MDIO */
>> +??????? >;
>> +??? };
>> +
>> +??? pru_rgmii1_pins_default: pru-rgmii1-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x00b8, PIN_INPUT, 2)??????? /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
>> +??????????? AM64X_IOPAD(0x00bc, PIN_INPUT, 2)??????? /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
>> +??????????? AM64X_IOPAD(0x00c0, PIN_INPUT, 2)??????? /* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
>> +??????????? AM64X_IOPAD(0x00c4, PIN_INPUT, 2)??????? /* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
>> +??????????? AM64X_IOPAD(0x00d0, PIN_INPUT, 2)??????? /* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
>> +??????????? AM64X_IOPAD(0x00c8, PIN_INPUT, 2)??????? /* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
>> +??????????? AM64X_IOPAD(0x00e4, PIN_OUTPUT, 2)??????? /* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
>> +??????????? AM64X_IOPAD(0x00e8, PIN_OUTPUT, 2)??????? /* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
>> +??????????? AM64X_IOPAD(0x00ec, PIN_OUTPUT, 2)??????? /* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
>> +??????????? AM64X_IOPAD(0x00f0, PIN_OUTPUT, 2)??????? /* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
>> +??????????? AM64X_IOPAD(0x00f8, PIN_INPUT, 2)??????? /* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
>> +??????????? AM64X_IOPAD(0x00f4, PIN_OUTPUT, 2)??????? /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
>> +??????? >;
>> +??? };
>> +
>> +??? pru_rgmii2_pins_default: pru-rgmii2-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x0108, PIN_INPUT, 2)??????? /* PRG1_PRU1_GPO0.RGMII2_RD0 */
>> +??????????? AM64X_IOPAD(0x010c, PIN_INPUT, 2)??????? /* PRG1_PRU1_GPO1.RGMII2_RD1 */
>> +??????????? AM64X_IOPAD(0x0110, PIN_INPUT, 2)??????? /* PRG1_PRU1_GPO2.RGMII2_RD2 */
>> +??????????? AM64X_IOPAD(0x0114, PIN_INPUT, 2)??????? /* PRG1_PRU1_GPO3.RGMII2_RD3 */
>> +??????????? AM64X_IOPAD(0x0120, PIN_INPUT, 2)??????? /* PRG1_PRU1_GPO6.RGMII2_RXC */
>> +??????????? AM64X_IOPAD(0x0118, PIN_INPUT, 2)??????? /* PRG1_PRU1_GPO4.RGMII2_RX_CTL */
>> +??????????? AM64X_IOPAD(0x0134, PIN_OUTPUT, 2)??????? /* PRG1_PRU1_GPO11.RGMII2_TD0 */
>> +??????????? AM64X_IOPAD(0x0138, PIN_OUTPUT, 2)??????? /* PRG1_PRU1_GPO12.RGMII2_TD1 */
>> +??????????? AM64X_IOPAD(0x013c, PIN_OUTPUT, 2)??????? /* PRG1_PRU1_GPO13.RGMII2_TD2 */
>> +??????????? AM64X_IOPAD(0x0140, PIN_OUTPUT, 2)??????? /* PRG1_PRU1_GPO14.RGMII2_TD3 */
>> +??????????? AM64X_IOPAD(0x0148, PIN_INPUT, 2)??????? /* PRG1_PRU1_GPO16.RGMII2_TXC */
>> +??????????? AM64X_IOPAD(0x0144, PIN_OUTPUT, 2)??????? /* PRG1_PRU1_GPO15.RGMII2_TX_CTL */
>> +??????? >;
>> +??? };
>> +
>> +??? rgmii1_pins_default: rgmii1-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x01cc, PIN_INPUT, 4)??????? /* PRG0_PRU1_GPO7.RGMII1_RD0 */
>> +??????????? AM64X_IOPAD(0x01d4, PIN_INPUT, 4)??????? /* PRG0_PRU1_GPO9.RGMII1_RD1 */
>> +??????????? AM64X_IOPAD(0x01d8, PIN_INPUT, 4)??????? /* PRG0_PRU1_GPO10.RGMII1_RD2 */
>> +??????????? AM64X_IOPAD(0x01f4, PIN_INPUT, 4)??????? /* PRG0_PRU1_GPO17.RGMII1_RD3 */
>> +??????????? AM64X_IOPAD(0x0188, PIN_INPUT, 4)??????? /* PRG0_PRU0_GPO10.RGMII1_RXC */
>> +??????????? AM64X_IOPAD(0x0184, PIN_INPUT, 4)??????? /* PRG0_PRU0_GPO9.RGMII1_RX_CTL */
>> +??????????? AM64X_IOPAD(0x0124, PIN_OUTPUT, 4)??????? /* PRG1_PRU1_GPO7.RGMII1_TD0 */
>> +??????????? AM64X_IOPAD(0x012c, PIN_OUTPUT, 4)??????? /* PRG1_PRU1_GPO9.RGMII1_TD1 */
>> +??????????? AM64X_IOPAD(0x0130, PIN_OUTPUT, 4)??????? /* PRG1_PRU1_GPO10.RGMII1_TD2 */
>> +??????????? AM64X_IOPAD(0x014c, PIN_OUTPUT, 4)??????? /* PRG1_PRU1_GPO17.RGMII1_TD3 */
>> +??????????? AM64X_IOPAD(0x00e0, PIN_INPUT, 4)??????? /* PRG1_PRU0_GPO10.RGMII1_TXC */
>> +??????????? AM64X_IOPAD(0x00dc, PIN_OUTPUT, 4)??????? /* PRG1_PRU0_GPO9.RGMII1_TX_CTL */
>> +??????? >;
>> +??? };
>> +
>> +??? usb0_pins_default: usb0-pins-default {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0)??????? /* USB0_DRVVBUS.USB0_DRVVBUS */
>> +??????? >;
>> +??? };
>> +};
>> +
>> +&main_r5fss0_core0 {
>> +??? mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core0>;
>> +??? memory-region = <&main_r5fss0_core0_dma_memory_region>,
>> +??????????? <&main_r5fss0_core0_memory_region>;
>> +};
>> +
>> +&main_r5fss0_core1 {
>> +??? mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core1>;
>> +??? memory-region = <&main_r5fss0_core1_dma_memory_region>,
>> +??????????? <&main_r5fss0_core1_memory_region>;
>> +};
>> +
>> +&main_r5fss1_core0 {
>> +??? mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core0>;
>> +??? memory-region = <&main_r5fss1_core0_dma_memory_region>,
>> +??????????? <&main_r5fss1_core0_memory_region>;
>> +};
>> +
>> +&main_r5fss1_core1 {
>> +??? mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core1>;
>> +??? memory-region = <&main_r5fss1_core1_dma_memory_region>,
>> +??????????? <&main_r5fss1_core1_memory_region>;
>> +};
>> +
>> +/* SoC default UART console */
>> +&main_uart0 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&main_uart0_pins_default>;
>> +??? status = "okay";
>> +};
>> +
>> +&ospi0 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&ospi0_pins_default>;
>> +??? num-cs = <1>;
>> +??? status = "okay";
>> +
>> +??? flash at 0 {
>> +??????? compatible = "jedec,spi-nor";
>> +??????? reg = <0>;
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&ospi0_flash0_pins_default>;
>> +??????? spi-tx-bus-width = <8>;
>> +??????? spi-rx-bus-width = <8>;
>> +??????? spi-max-frequency = <200000000>;
>> +??????? cdns,tshsl-ns = <50>;
>> +??????? cdns,tsd2d-ns = <50>;
>> +??????? cdns,tchsh-ns = <4>;
>> +??????? cdns,tslch-ns = <4>;
>> +??????? cdns,read-delay = <0>;
>> +??????? interrupt-parent = <&main_gpio0>;
>> +??????? interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
>> +??????? reset-gpios = <&main_gpio0 13 GPIO_ACTIVE_LOW>;
>> +??? };
>> +};
>> +
>> +&sdhci0 {
>
> These sdhci* nodes are disabled by default
My full expectation in v0 was that (most) everything in
soc dtsi would have been disabled by default.

As per 6.7-rc7 k3-am64-main.dtsi did not disable sdhci nodes,
so this was fine, I had even removed my unnecessary
status = okay since v1 :(
(Now I can see how you spotted it, thanks!)

> , you might
> want to status = "okay" here.
Will re-add them just for sdhci nodes in v5.
> Rule of thumb is if you
> needed to add info to the node here in the board file
> it probably needs to be enabled here too.
>
> Otherwise LGTM,
>
> Reviewed-by: Andrew Davis <afd at ti.com>
>
>> +??? /* mmc0 pins have no padconfig */
>> +??? bus-width = <8>;
>> +??? ti,driver-strength-ohm = <50>;
>> +??? disable-wp;
>> +??? non-removable;
>> +??? cap-mmc-hw-reset;
>> +??? no-sd;
>> +??? /*
>> +???? * MMC controller supports switching between 1.8V and 3.3V signalling.
>> +???? * However MMC0 (unlike MMC1) does not integrate an LDO.
>> +???? * Explicitly link a regulator node for indicating to the driver which
>> +???? * voltages are actually usable.
>> +???? */
>> +??? vqmmc-supply = <&vdd_mmc0>;
>> +};
>> +
>> +/*
>> + * microSD is on carrier - however since SoC can boot from it,
>> + * configure it just in case.
>> + */
>> +&sdhci1 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&main_mmc1_pins_default>;
>> +??? bus-width = <4>;
>> +??? ti,driver-strength-ohm = <50>;
>> +??? disable-wp;
>> +};
>> +
>> +/*
>> + * USB settings are a carrier choice - however since SoC can boot from it,
>> + * configure as USB-2.0 OTG here, keeping USB-3 serdes disabled.
>> + */
>> +&usb0 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&usb0_pins_default>;
>> +??? dr_mode = "otg";
>> +??? maximum-speed = "high-speed";
>> +};
>> +
>> +&usbss0 {
>> +??? ti,vbus-divider;
>> +??? ti,usb2-only;
>> +};
>>

From josua at solid-run.com  Tue Feb  6 06:44:24 2024
From: josua at solid-run.com (Josua Mayer)
Date: Tue, 6 Feb 2024 14:44:24 +0000
Subject: [PATCH v4 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240203-tummy-egomaniac-5aba55889a83@spud>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
 <20240202-add-am64-som-v4-2-5f8b12af5e71@solid-run.com>
 <20240203-prolonged-backfield-c659e0016d70@spud>
 <20240203-tummy-egomaniac-5aba55889a83@spud>
Message-ID: <0c784113-9288-46bd-a34e-49bf0f1651bb@solid-run.com>

Am 03.02.24 um 16:10 schrieb Conor Dooley:
> On Sat, Feb 03, 2024 at 03:08:59PM +0000, Conor Dooley wrote:
>> Hey,
>>
>> On Fri, Feb 02, 2024 at 05:10:49PM +0100, Josua Mayer wrote:
>>> Convert the abracon abx80x rtc text bindings to dt-schema format.
>>>
>>> In addition to the text description reference generic interrupts
>>> properties and add an example.
>>>
>>> Signed-off-by: Josua Mayer <josua at solid-run.com>
>>> ---
>>>  .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ---------
>>>  .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 74 ++++++++++++++++++++++
>>>  2 files changed, 74 insertions(+), 31 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
>>> deleted file mode 100644
>>> index 2405e35a1bc0..000000000000
>>> --- a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
>>> +++ /dev/null
>>> @@ -1,31 +0,0 @@
>>> -Abracon ABX80X I2C ultra low power RTC/Alarm chip
>>> -
>>> -The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
>>> -ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
>>> -is the superset of ab180x.
>>> -
>>> -Required properties:
>>> -
>>> - - "compatible": should one of:
>>> -        "abracon,abx80x"
>>> -        "abracon,ab0801"
>>> -        "abracon,ab0803"
>>> -        "abracon,ab0804"
>>> -        "abracon,ab0805"
>>> -        "abracon,ab1801"
>>> -        "abracon,ab1803"
>>> -        "abracon,ab1804"
>>> -        "abracon,ab1805"
>>> -        "microcrystal,rv1805"
>>> -	Using "abracon,abx80x" will enable chip autodetection.
>>> - - "reg": I2C bus address of the device
>>> -
>>> -Optional properties:
>>> -
>>> -The abx804 and abx805 have a trickle charger that is able to charge the
>>> -connected battery or supercap. Both the following properties have to be defined
>>> -and valid to enable charging:
>>> -
>>> - - "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
>>> - - "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
>>> -                          resistor, the other values are in kOhm.
>>> diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
>>> new file mode 100644
>>> index 000000000000..405b386a54b0
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
>>> @@ -0,0 +1,74 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Abracon ABX80X I2C ultra low power RTC/Alarm chip
>>> +
>>> +maintainers:
>>> +  - devicetree at vger.kernel.org
>> Ideally you put someone here, not the DT list. Usually the original
>> author is a good choice, which I think happens to be the subsystem
>> maintainer... Failing that, the rtc subsystem list is likely a better
>> choice than the DT one.
>>
>>> +
>>> +allOf:
>>> +  - $ref: rtc.yaml#
>>> +  - $ref: /schemas/interrupts.yaml#
I was intentionally looking for some feedback on this idea,
for solving dtbs_check complaints for both interrupts and
interrupt-parent properties:

arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb: rtc at 69:
Unevaluated properties are not allowed ('interrupt-parent', 'interrupts' were unexpected)
???????from schema $id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#

> Ahh I now realise what your intent was here. All you need to do is add
> | interrupts:
> |   maxItems: 1
> to your binding and it should do what you're looking for.

Yes, that is in line with everything else.

What bugs me is what to do about interrupt-parent,
and whether to include it in example.


From hverkuil-cisco at xs4all.nl  Tue Feb  6 06:44:45 2024
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Tue, 6 Feb 2024 15:44:45 +0100
Subject: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <20240206134155.GB2827@pendragon.ideasonboard.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
 <87r0hqnvxc.wl-kuninori.morimoto.gx@renesas.com>
 <20240206134155.GB2827@pendragon.ideasonboard.com>
Message-ID: <9d1e99b0-892d-4a72-a9b3-886b8ed094b0@xs4all.nl>

On 2/6/24 14:41, Laurent Pinchart wrote:
> Hi Morimoto-san,
> 
> (Adding Krzysztof Ha?asa)
> 
> Thank you for the patch.
> 
> On Tue, Feb 06, 2024 at 02:55:27AM +0000, Kuninori Morimoto wrote:
>> From DT point of view, in general, drivers should be asking for a
>> specific port number because their function is fixed in the binding.
>>
>> of_graph_get_next_endpoint() doesn't match to this concept.
>>
>> Simply replace
>>
>> 	- of_graph_get_next_endpoint(xxx, NULL);
>> 	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);
>>
>> Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
>> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
>> ---
>>  drivers/media/i2c/adv7343.c              | 2 +-
>>  drivers/media/i2c/adv7604.c              | 2 +-
>>  drivers/media/i2c/mt9p031.c              | 2 +-
>>  drivers/media/i2c/mt9v032.c              | 2 +-
>>  drivers/media/i2c/ov2659.c               | 2 +-
>>  drivers/media/i2c/ov5645.c               | 2 +-
>>  drivers/media/i2c/ov5647.c               | 2 +-
>>  drivers/media/i2c/s5c73m3/s5c73m3-core.c | 2 +-
>>  drivers/media/i2c/s5k5baf.c              | 2 +-
>>  drivers/media/i2c/tc358743.c             | 2 +-
>>  drivers/media/i2c/tda1997x.c             | 2 +-
>>  drivers/media/i2c/tvp514x.c              | 2 +-
>>  drivers/media/i2c/tvp7002.c              | 2 +-
>>  13 files changed, 13 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
>> index ff21cd4744d3..4fbe4e18570e 100644
>> --- a/drivers/media/i2c/adv7343.c
>> +++ b/drivers/media/i2c/adv7343.c
>> @@ -403,7 +403,7 @@ adv7343_get_pdata(struct i2c_client *client)
>>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>>  		return client->dev.platform_data;
>>  
>> -	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
>> +	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>>  	if (!np)
>>  		return NULL;
>>  
>> diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
>> index b202a85fbeaa..dcfdbb975473 100644
>> --- a/drivers/media/i2c/adv7604.c
>> +++ b/drivers/media/i2c/adv7604.c
>> @@ -3205,7 +3205,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
>>  	np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
>>  
>>  	/* Parse the endpoint. */
>> -	endpoint = of_graph_get_next_endpoint(np, NULL);
>> +	endpoint = of_graph_get_endpoint_by_regs(np, 0, -1);
> 
> I think this should be port 1 for the adv7611 and port2 for the adv7612.
> The adv7610 may need to use port 1 too, but the bindings likely need to
> be updated.
> 
> Hans, Krzysztof, any opinion ?

It looks like it. But I suspect the code never worked. The endpoint parsing
is only needed if a specific mbus type is used (i.e., not 'UNKNOWN'), and
I don't think that is used in the device trees in the kernel. So everything
silently falls back to UNKNOWN and some default bus config that 'just works' (tm).

I'm pretty sure this code is wrong, but nobody ever noticed. Changing it
to the new code just makes it bug-compatible :-)

Ideally someone would have to actually test this, perhaps with one of those
Renesas boards. While I do have one, it got bricked after I attempted a
u-boot update :-(

Regards,

	Hans

> 
>>  	if (!endpoint)
>>  		return -EINVAL;
>>  
>> diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
>> index 348f1e1098fb..c57a0d436421 100644
>> --- a/drivers/media/i2c/mt9p031.c
>> +++ b/drivers/media/i2c/mt9p031.c
>> @@ -1080,7 +1080,7 @@ mt9p031_get_pdata(struct i2c_client *client)
>>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>>  		return client->dev.platform_data;
>>  
>> -	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
>> +	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>>  	if (!np)
>>  		return NULL;
>>  
>> diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
>> index 1c6f6cea1204..14d277680fa2 100644
>> --- a/drivers/media/i2c/mt9v032.c
>> +++ b/drivers/media/i2c/mt9v032.c
>> @@ -1008,7 +1008,7 @@ mt9v032_get_pdata(struct i2c_client *client)
>>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>>  		return client->dev.platform_data;
>>  
>> -	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
>> +	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>>  	if (!np)
>>  		return NULL;
>>  
>> diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
>> index 2c3dbe164eb6..edea62a02320 100644
>> --- a/drivers/media/i2c/ov2659.c
>> +++ b/drivers/media/i2c/ov2659.c
>> @@ -1388,7 +1388,7 @@ ov2659_get_pdata(struct i2c_client *client)
>>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>>  		return client->dev.platform_data;
>>  
>> -	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
>> +	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>>  	if (!endpoint)
>>  		return NULL;
>>  
>> diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
>> index a70db7e601a4..31d214bd4a83 100644
>> --- a/drivers/media/i2c/ov5645.c
>> +++ b/drivers/media/i2c/ov5645.c
>> @@ -1053,7 +1053,7 @@ static int ov5645_probe(struct i2c_client *client)
>>  	ov5645->i2c_client = client;
>>  	ov5645->dev = dev;
>>  
>> -	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
>> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
>>  	if (!endpoint) {
>>  		dev_err(dev, "endpoint node not found\n");
>>  		return -EINVAL;
>> diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
>> index dcfe3129c63a..beab2813c672 100644
>> --- a/drivers/media/i2c/ov5647.c
>> +++ b/drivers/media/i2c/ov5647.c
>> @@ -1363,7 +1363,7 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
>>  	struct device_node *ep;
>>  	int ret;
>>  
>> -	ep = of_graph_get_next_endpoint(np, NULL);
>> +	ep = of_graph_get_endpoint_by_regs(np, 0, -1);
>>  	if (!ep)
>>  		return -EINVAL;
>>  
>> diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
>> index ed5b10731a14..aaec5f64f31a 100644
>> --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
>> +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
>> @@ -1555,7 +1555,7 @@ static int s5c73m3_get_dt_data(struct s5c73m3 *state)
>>  				     "failed to request gpio S5C73M3_RST\n");
>>  	gpiod_set_consumer_name(state->reset, "S5C73M3_RST");
>>  
>> -	node_ep = of_graph_get_next_endpoint(node, NULL);
>> +	node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
>>  	if (!node_ep) {
>>  		dev_warn(dev, "no endpoint defined for node: %pOF\n", node);
>>  		return 0;
>> diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
>> index 67da2045f543..af7e49e6cc5b 100644
>> --- a/drivers/media/i2c/s5k5baf.c
>> +++ b/drivers/media/i2c/s5k5baf.c
>> @@ -1836,7 +1836,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
>>  			 state->mclk_frequency);
>>  	}
>>  
>> -	node_ep = of_graph_get_next_endpoint(node, NULL);
>> +	node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
>>  	if (!node_ep) {
>>  		dev_err(dev, "no endpoint defined at node %pOF\n", node);
>>  		return -EINVAL;
>> diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
>> index 2785935da497..872e802cdfbe 100644
>> --- a/drivers/media/i2c/tc358743.c
>> +++ b/drivers/media/i2c/tc358743.c
>> @@ -1895,7 +1895,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
>>  		return dev_err_probe(dev, PTR_ERR(refclk),
>>  				     "failed to get refclk\n");
>>  
>> -	ep = of_graph_get_next_endpoint(dev->of_node, NULL);
>> +	ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
>>  	if (!ep) {
>>  		dev_err(dev, "missing endpoint node\n");
>>  		return -EINVAL;
>> diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
>> index 325e99125941..662efd5e69b9 100644
>> --- a/drivers/media/i2c/tda1997x.c
>> +++ b/drivers/media/i2c/tda1997x.c
>> @@ -2307,7 +2307,7 @@ static int tda1997x_parse_dt(struct tda1997x_state *state)
>>  	pdata->vidout_sel_de = DE_FREF_SEL_DE_VHREF;
>>  
>>  	np = state->client->dev.of_node;
>> -	ep = of_graph_get_next_endpoint(np, NULL);
>> +	ep = of_graph_get_endpoint_by_regs(np, 0, -1);
>>  	if (!ep)
>>  		return -EINVAL;
>>  
>> diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
>> index c37f605cb75f..b1630a6c396b 100644
>> --- a/drivers/media/i2c/tvp514x.c
>> +++ b/drivers/media/i2c/tvp514x.c
>> @@ -988,7 +988,7 @@ tvp514x_get_pdata(struct i2c_client *client)
>>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>>  		return client->dev.platform_data;
>>  
>> -	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
>> +	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>>  	if (!endpoint)
>>  		return NULL;
>>  
>> diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
>> index a2d7bc799849..8e58ce400df2 100644
>> --- a/drivers/media/i2c/tvp7002.c
>> +++ b/drivers/media/i2c/tvp7002.c
>> @@ -893,7 +893,7 @@ tvp7002_get_pdata(struct i2c_client *client)
>>  	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>>  		return client->dev.platform_data;
>>  
>> -	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
>> +	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>>  	if (!endpoint)
>>  		return NULL;
>>  
> 



From amergnat at baylibre.com  Tue Feb  6 06:47:17 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Tue, 6 Feb 2024 15:47:17 +0100
Subject: [PATCH v4 1/9] drm/mediatek: dsi: Use GENMASK() for register mask
 definitions
In-Reply-To: <20240206120748.136610-2-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-2-angelogioacchino.delregno@collabora.com>
Message-ID: <f91db779-ad94-4c18-9a06-1029da4edaab@baylibre.com>



On 06/02/2024 13:07, AngeloGioacchino Del Regno wrote:
> Change magic numerical masks with usage of the GENMASK() macro
> to improve readability.
> 
> While at it, also fix the DSI_PS_SEL mask to include all bits instead
> of just a subset of them.
> 
> This commit brings no functional changes.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dsi.c | 45 +++++++++++++++---------------
>   1 file changed, 23 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index a2fdfc8ddb15..3b7392c03b4d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -58,18 +58,18 @@
>   

...snip...

>   #define DSI_PSCTRL		0x1c
> -#define DSI_PS_WC			0x3fff
> -#define DSI_PS_SEL			(3 << 16)
> +#define DSI_PS_WC			GENMASK(14, 0)
> +#define DSI_PS_SEL			GENMASK(19, 16)

0011 0000 0000 0000 0000 => GENMASK(17, 16)

>   #define PACKED_PS_16BIT_RGB565		(0 << 16)
>   #define LOOSELY_PS_18BIT_RGB666		(1 << 16)
>   #define PACKED_PS_18BIT_RGB666		(2 << 16)
> @@ -109,26 +109,26 @@
>   #define LD0_WAKEUP_EN			BIT(2)

-- 
Regards,
Alexandre


From amergnat at baylibre.com  Tue Feb  6 06:51:38 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Tue, 6 Feb 2024 15:51:38 +0100
Subject: [PATCH v4 2/9] drm/mediatek: dsi: Fix DSI RGB666 formats and
 definitions
In-Reply-To: <20240206120748.136610-3-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-3-angelogioacchino.delregno@collabora.com>
Message-ID: <06d0f56f-c27f-4d6a-9a88-e2932de29bf3@baylibre.com>

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>

On 06/02/2024 13:07, AngeloGioacchino Del Regno wrote:
> The register bits definitions for RGB666 formats are wrong in multiple
> ways: first, in the DSI_PS_SEL bits region, the Packed 18-bits RGB666
> format is selected with bit 1, while the Loosely Packed one is bit 2,
> and second - the definition name "LOOSELY_PS_18BIT_RGB666" is wrong
> because the loosely packed format is 24 bits instead!
> 
> Either way, functions mtk_dsi_ps_control_vact() and mtk_dsi_ps_control()
> do not even agree on the DSI_PS_SEL bit to set in DSI_PSCTRL: one sets
> loosely packed (24) on RGB666, the other sets packed (18), and the other
> way around for RGB666_PACKED.
> 
> Fixing this entire stack of issues is done in one go:
>   - Use the correct bit for the Loosely Packed RGB666 definition
>   - Rename LOOSELY_PS_18BIT_RGB666 to LOOSELY_PS_24BIT_RGB666
>   - Change ps_bpp_mode in mtk_dsi_ps_control_vact() to set:
>      - Loosely Packed, 24-bits for MIPI_DSI_FMT_RGB666
>      - Packed, 18-bits for MIPI_DSI_FMT_RGB666_PACKED

-- 
Regards,
Alexandre


From vigneshr at ti.com  Tue Feb  6 06:54:40 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 6 Feb 2024 20:24:40 +0530
Subject: [PATCH V2 00/16] arm64: dts: ti: Additional licensing and clarification
In-Reply-To: <20240122145539.194512-1-nm@ti.com>
References: <20240122145539.194512-1-nm@ti.com>
Message-ID: <170723117278.3216299.12458152939034721597.b4-ty@ti.com>

Hi Nishanth Menon,

On Mon, 22 Jan 2024 08:55:23 -0600, Nishanth Menon wrote:
> Thank you all for the detailed acks on various patches on V1,
> consolidated all of these with V2 and noted some missing acks below.
> Since it has been 12 days since I posted v1 and v6.8-rc1 is now
> tagged, looks like a good time to refresh the series.
> 
> As part of my 2023 LPC talk[1] about the difficulty in ensuring
> device tree is same across multiple s/w ecosystems, I mentioned about
> Licensing, and Rob had indicated that other SoC vendors have MIT
> license option that allows co-existance with Apache.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[01/16] arm64: dts: ti: Use https for urls
        commit: 01e886c4dfdacc2956d9857a3b5c985ea74e9ddd
[02/16] arm64: dts: ti: k3-am62a7: Add MIT license along with GPL-2.0
        commit: 89bd4c373649b81d4255d9c5a3e49d3fd10df708
[03/16] arm64: dts: ti: k3-am625: Add MIT license along with GPL-2.0
        commit: 7e614b5394f06c7ff5e9ef570bb1d40af08c6449
[04/16] arm64: dts: ti: k3-am62p: Add MIT license along with GPL-2.0
        commit: 20f8173afaac90dd9dca11be4aa602a47776077f
[05/16] arm64: dts: ti: k3-am64: Add MIT license along with GPL-2.0
        commit: 6248b20e3203c5f255efe6c330b5c871ca4e8033
[06/16] arm64: dts: ti: k3-am65: Add MIT license along with GPL-2.0
        commit: 2822c791af4d98ca469485dacde9ea4f13c905af
[07/16] arm64: dts: ti: k3-j7200: Add MIT license along with GPL-2.0
        commit: b87c44dd974e13aab1d0a9a01a5f94f1fe5fd1fb
[08/16] arm64: dts: ti: k3-j721e: Add MIT license along with GPL-2.0
        commit: 111f6dac6c08471888da49389f63174f3717bfbd
[09/16] arm64: dts: ti: k3-j721s2: Add MIT license along with GPL-2.0
        commit: 25aec8a64a2413f6b16e33ecbc0334bd7075ba49
[10/16] arm64: dts: ti: k3-j784s4: Add MIT license along with GPL-2.0
        commit: 33e089bd1e136f1e2c58e6b44455de55f4fe4bae
[11/16] arm64: dts: ti: k3-pinctrl: Add MIT license along with GPL-2.0
        commit: 67fdcf08cd76a7d81e64343b2f0730f554245840
[12/16] arm64: dts: ti: k3-serdes: Add MIT license along with GPL-2.0
        commit: 3feda6a0cf7d9a82d820032033ae7e600e9dca66
[13/16] arm64: dts: ti: beagle*: Add MIT license along with GPL-2.0
        commit: 380f1ffd281b6f33a6e03220921be2750c6fd8ce
[14/16] arm64: dts: ti: phycore*: Add MIT license along with GPL-2.0
        commit: 049010c9604f87568ae59ee5ea1b885ece19e6c6
[15/16] arm64: dts: ti: iot2050*: Clarify GPL-2.0 as GPL-2.0-only
        commit: c32953cf00a5ab9059483d825f866a528ad80460
[16/16] arm64: dts: ti: Makefile: Clarify GPL-2.0 as GPL-2.0-only
        commit: 1e6bbc5185bcd113c8d2f7aa0a02f588a6bdbe5d

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From conor at kernel.org  Tue Feb  6 06:55:12 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 6 Feb 2024 14:55:12 +0000
Subject: [PATCH v4 1/3] dt-bindings: display: add STM32 LVDS device
In-Reply-To: <20240206-lvds-v4-1-98d5f9af399d@foss.st.com>
References: <20240206-lvds-v4-0-98d5f9af399d@foss.st.com>
 <20240206-lvds-v4-1-98d5f9af399d@foss.st.com>
Message-ID: <20240206-retail-thicket-75e6e0b1fe45@spud>

On Tue, Feb 06, 2024 at 12:33:16PM +0100, Raphael Gallais-Pou wrote:
> Add "st,stm32mp25-lvds" compatible.
> 
> Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Thanks,
Conor.
-------------- 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/20240206/af824ceb/attachment.sig>

From ulf.hansson at linaro.org  Tue Feb  6 06:54:58 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 6 Feb 2024 15:54:58 +0100
Subject: [PATCH V8 00/12] soc: imx8mp: Add support for HDMI
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <CAPDyKFpe-+ttcciPsQiSYUh4ptZ+5RGc3S=K3xVwpaTuCA_FeA@mail.gmail.com>

- trimmed cc-list

On Sat, 3 Feb 2024 at 17:53, Adam Ford <aford173 at gmail.com> wrote:
>
> The i.MX8M Plus has an HDMI controller, but it depends on two
> other systems, the Parallel Video Interface (PVI) and the
> HDMI PHY from Samsung. The LCDIF controller generates the display
> and routes it to the PVI which converts passes the parallel video
> to the HDMI bridge.  The HDMI system has a corresponding power
> domain controller whose driver was partially written, but the
> device tree for it was never applied, so some changes to the
> power domain should be harmless because they've not really been
> used yet.
>
> This series is adapted from multiple series from Lucas Stach with
> edits and suggestions from feedback from various series, but it
> since it's difficult to use and test them independently,
> I merged them into on unified series.  The version history is a
> bit ambiguous since different components were submitted at different
> times and had different amount of retries.  In an effort to merge them
> I used the highest version attempt.
>
> Adam Ford (3):
>   dt-bindings: soc: imx: add missing clock and power-domains to
>     imx8mp-hdmi-blk-ctrl
>   pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix
>     domain
>   arm64: defconfig: Enable DRM_IMX8MP_DW_HDMI_BRIDGE as module
>
> Lucas Stach (9):
>   dt-bindings: phy: add binding for the i.MX8MP HDMI PHY
>   phy: freescale: add Samsung HDMI PHY
>   arm64: dts: imx8mp: add HDMI power-domains
>   arm64: dts: imx8mp: add HDMI irqsteer
>   dt-bindings: display: imx: add binding for i.MX8MP HDMI PVI
>   drm/bridge: imx: add driver for HDMI TX Parallel Video Interface
>   dt-bindings: display: imx: add binding for i.MX8MP HDMI TX
>   drm/bridge: imx: add bridge wrapper driver for i.MX8MP DWC HDMI
>   arm64: dts: imx8mp: add HDMI display pipeline
>
>  .../display/bridge/fsl,imx8mp-hdmi-tx.yaml    |  102 ++
>  .../display/imx/fsl,imx8mp-hdmi-pvi.yaml      |   84 ++
>  .../bindings/phy/fsl,imx8mp-hdmi-phy.yaml     |   62 +
>  .../soc/imx/fsl,imx8mp-hdmi-blk-ctrl.yaml     |   22 +-
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi     |  145 +++
>  arch/arm64/configs/defconfig                  |    1 +
>  drivers/gpu/drm/bridge/imx/Kconfig            |   18 +
>  drivers/gpu/drm/bridge/imx/Makefile           |    2 +
>  drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c  |  207 ++++
>  drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c   |  154 +++
>  drivers/phy/freescale/Kconfig                 |    6 +
>  drivers/phy/freescale/Makefile                |    1 +
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c  | 1075 +++++++++++++++++
>  drivers/pmdomain/imx/imx8mp-blk-ctrl.c        |   10 +-
>  14 files changed, 1876 insertions(+), 13 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml
>  create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml
>  create mode 100644 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
>  create mode 100644 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c
>  create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c
>

Patch 3 and patch 4, applied for next to my pmdomain tree. Patch 3 (DT
doc) is also available at the immutable "dt" branch, allowing it to be
pulled into the soc maintainer's tree too.

Kind regards
Uffe


From ulf.hansson at linaro.org  Tue Feb  6 06:55:24 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 6 Feb 2024 15:55:24 +0100
Subject: [PATCH v2] pmdomain: mediatek: Use devm_platform_ioremap_resource()
 in init_scp()
In-Reply-To: <6e397bf2-1d45-434f-8619-58a737a138e3@web.de>
References: <da6af483-5ee9-45cd-922e-d9d5364674dc@web.de> <CAMuHMdUxn4Ne7kmEfONz8Uk3Why3m9r83GdM5RzTxm_4Gj_a6g@mail.gmail.com>
 <6e397bf2-1d45-434f-8619-58a737a138e3@web.de>
Message-ID: <CAPDyKFrVgHKXrps5wB3yhOK6JFdBeW8zzYHcQJC1RVs8PXJgOw@mail.gmail.com>

On Tue, 6 Feb 2024 at 10:21, Markus Elfring <Markus.Elfring at web.de> wrote:
>
> From: Markus Elfring <elfring at users.sourceforge.net>
> Date: Tue, 6 Feb 2024 10:05:34 +0100
> Subject: [PATCH v2] pmdomain: mediatek: Use devm_platform_ioremap_resource() in init_scp()
>
> A wrapper function is available since the commit 7945f929f1a77a1c8887a97ca07f87626858ff42
> ("drivers: provide devm_platform_ioremap_resource()").
>
> * Thus reuse existing functionality instead of keeping duplicate source code.
>
> * Delete a local variable which became unnecessary with this refactoring.
>
>
> This issue was transformed by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>

Applied for next, thanks!

Kind regards
Uffe


> ---
>
> v2:
> The transformation pattern was adjusted based on advices by known contributors.
>
> Examples:
> * Doug Anderson
> * Geert Uytterhoeven
> * Robin Murphy
>
>
>  drivers/pmdomain/mediatek/mtk-scpsys.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
> index b374d01fdac7..59a7a8c261ed 100644
> --- a/drivers/pmdomain/mediatek/mtk-scpsys.c
> +++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
> @@ -425,7 +425,6 @@ static struct scp *init_scp(struct platform_device *pdev,
>                         bool bus_prot_reg_update)
>  {
>         struct genpd_onecell_data *pd_data;
> -       struct resource *res;
>         int i, j;
>         struct scp *scp;
>         struct clk *clk[CLK_MAX];
> @@ -441,8 +440,7 @@ static struct scp *init_scp(struct platform_device *pdev,
>
>         scp->dev = &pdev->dev;
>
> -       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -       scp->base = devm_ioremap_resource(&pdev->dev, res);
> +       scp->base = devm_platform_ioremap_resource(pdev, 0);
>         if (IS_ERR(scp->base))
>                 return ERR_CAST(scp->base);
>
> --
> 2.43.0
>


From msp at baylibre.com  Tue Feb  6 06:57:18 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue,  6 Feb 2024 15:57:18 +0100
Subject: [PATCH 0/3] arm64: am62: Use nvmem for chip information in opp table
Message-ID: <20240206145721.2418893-1-msp@baylibre.com>

Hi everyone,

the OPP table on am625 currently uses a syscon node to get required
information from efuse registers. As efuse registers contain many
different information, this series adds nvmem support for the TI OPP
table and cpufreq driver. This way just the specific information can be
referenced in the devicetree without the need to use a syscon reference.

The nvmem layout is added in my previous series, links are below.

This series is based on
  https://lore.kernel.org/linux-arm-kernel/20240206143711.2410135-1-msp at baylibre.com/
Which is also available on my public git:
  https://gitlab.baylibre.com/msp8/linux/-/tree/topic/ti-chipid-nvmem/v6.8?ref_type=heads

This series is available on git as well:
  https://gitlab.baylibre.com/msp8/linux/-/tree/topic/ti-cpufreq-nvmem/v6.8?ref_type=heads

Best,
Markus

Markus Schneider-Pargmann (3):
  dt-bindings: cpufreq: Add nvmem-cells for chip information
  cpufreq: ti-cpufreq: Support nvmem for chip version
  arm64: dts: ti: k3-am625: Use nvmem-cells for opp

 .../opp/operating-points-v2-ti-cpu.yaml       |  16 ++-
 arch/arm64/boot/dts/ti/k3-am625.dtsi          |   2 +
 drivers/cpufreq/ti-cpufreq.c                  | 105 +++++++++++-------
 3 files changed, 83 insertions(+), 40 deletions(-)

-- 
2.43.0



From msp at baylibre.com  Tue Feb  6 06:57:19 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue,  6 Feb 2024 15:57:19 +0100
Subject: [PATCH 1/3] dt-bindings: cpufreq: Add nvmem-cells for chip information
In-Reply-To: <20240206145721.2418893-1-msp@baylibre.com>
References: <20240206145721.2418893-1-msp@baylibre.com>
Message-ID: <20240206145721.2418893-2-msp@baylibre.com>

Add nvmem-cells to describe chip information like chipvariant and
chipspeed. If nvmem-cells are used, the syscon property is not necessary
anymore.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
Acked-by: Andrew Davis <afd at ti.com>
---
 .../bindings/opp/operating-points-v2-ti-cpu.yaml | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml b/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml
index 02d1d2c17129..b1881a0834fe 100644
--- a/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml
+++ b/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml
@@ -34,6 +34,14 @@ properties:
       points to syscon node representing the control module
       register space of the SoC.
 
+  nvmem-cells:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+  nvmem-cell-names:
+    items:
+      - const: chipvariant
+      - const: chipspeed
+
   opp-shared: true
 
 patternProperties:
@@ -55,7 +63,13 @@ patternProperties:
 
 required:
   - compatible
-  - syscon
+
+oneOf:
+  - required:
+      - syscon
+  - required:
+      - nvmem-cells
+      - nvmem-cell-names
 
 additionalProperties: false
 
-- 
2.43.0



From msp at baylibre.com  Tue Feb  6 06:57:20 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue,  6 Feb 2024 15:57:20 +0100
Subject: [PATCH 2/3] cpufreq: ti-cpufreq: Support nvmem for chip version
In-Reply-To: <20240206145721.2418893-1-msp@baylibre.com>
References: <20240206145721.2418893-1-msp@baylibre.com>
Message-ID: <20240206145721.2418893-3-msp@baylibre.com>

Support using nvmem-cells 'chipvariant' and 'chipspeed' instead of
syscon. This makes it more flexible and moves more configuration into
the devicetree.

If nvmem-cells are present, probing will fail if the configuration of
these cells is broken. If nvmem-cells is not present syscon will be
used.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 drivers/cpufreq/ti-cpufreq.c | 105 ++++++++++++++++++++++-------------
 1 file changed, 66 insertions(+), 39 deletions(-)

diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
index 46c41e2ca727..3ee72b1309f0 100644
--- a/drivers/cpufreq/ti-cpufreq.c
+++ b/drivers/cpufreq/ti-cpufreq.c
@@ -10,6 +10,7 @@
 #include <linux/io.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
+#include <linux/nvmem-consumer.h>
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -65,6 +66,7 @@ struct ti_cpufreq_soc_data {
 
 struct ti_cpufreq_data {
 	struct device *cpu_dev;
+	struct device *dev;
 	struct device_node *opp_node;
 	struct regmap *syscon;
 	const struct ti_cpufreq_soc_data *soc_data;
@@ -244,31 +246,40 @@ static struct ti_cpufreq_soc_data am625_soc_data = {
 static int ti_cpufreq_get_efuse(struct ti_cpufreq_data *opp_data,
 				u32 *efuse_value)
 {
+	struct device_node *np = opp_data->opp_node;
 	struct device *dev = opp_data->cpu_dev;
 	u32 efuse;
 	int ret;
 
-	ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset,
-			  &efuse);
-	if (ret == -EIO) {
-		/* not a syscon register! */
-		void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
-				opp_data->soc_data->efuse_offset, 4);
-
-		if (!regs)
-			return -ENOMEM;
-		efuse = readl(regs);
-		iounmap(regs);
+	ret = nvmem_cell_read_u32(opp_data->dev, "chipspeed", &efuse);
+	if (ret && (ret != -ENOENT || !opp_data->syscon))
+		return dev_err_probe(dev, ret,
+				     "Failed to read nvmem cell 'chipspeed': %pe",
+				     ERR_PTR(ret));
+
+	if (ret) {
+		ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset,
+				  &efuse);
+		if (ret == -EIO) {
+			/* not a syscon register! */
+			void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
+					opp_data->soc_data->efuse_offset, 4);
+
+			if (!regs)
+				return -ENOMEM;
+			efuse = readl(regs);
+			iounmap(regs);
+			}
+		else if (ret) {
+			dev_err(dev,
+				"Failed to read the efuse value from syscon: %d\n",
+				ret);
+			return ret;
 		}
-	else if (ret) {
-		dev_err(dev,
-			"Failed to read the efuse value from syscon: %d\n",
-			ret);
-		return ret;
-	}
 
-	efuse = (efuse & opp_data->soc_data->efuse_mask);
-	efuse >>= opp_data->soc_data->efuse_shift;
+		efuse = (efuse & opp_data->soc_data->efuse_mask);
+		efuse >>= opp_data->soc_data->efuse_shift;
+	}
 
 	*efuse_value = opp_data->soc_data->efuse_xlate(opp_data, efuse);
 
@@ -285,30 +296,41 @@ static int ti_cpufreq_get_efuse(struct ti_cpufreq_data *opp_data,
 static int ti_cpufreq_get_rev(struct ti_cpufreq_data *opp_data,
 			      u32 *revision_value)
 {
+	struct device_node *np = opp_data->opp_node;
 	struct device *dev = opp_data->cpu_dev;
 	u32 revision;
 	int ret;
 
-	ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset,
-			  &revision);
-	if (ret == -EIO) {
-		/* not a syscon register! */
-		void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
-				opp_data->soc_data->rev_offset, 4);
-
-		if (!regs)
-			return -ENOMEM;
-		revision = readl(regs);
-		iounmap(regs);
+	ret = nvmem_cell_read_u32(opp_data->dev, "chipvariant", &revision);
+	if (ret && (ret != -ENOENT || !opp_data->syscon))
+		return dev_err_probe(dev, ret,
+				     "Failed to read nvmem cell 'chipvariant': %pe",
+				     ERR_PTR(ret));
+
+	if (ret) {
+		ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset,
+				  &revision);
+		if (ret == -EIO) {
+			/* not a syscon register! */
+			void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
+					opp_data->soc_data->rev_offset, 4);
+
+			if (!regs)
+				return -ENOMEM;
+			revision = readl(regs);
+			iounmap(regs);
+			}
+		else if (ret) {
+			dev_err(dev,
+				"Failed to read the revision number from syscon: %d\n",
+				ret);
+			return ret;
 		}
-	else if (ret) {
-		dev_err(dev,
-			"Failed to read the revision number from syscon: %d\n",
-			ret);
-		return ret;
+
+		revision = (revision >> REVISION_SHIFT) & REVISION_MASK;
 	}
 
-	*revision_value = BIT((revision >> REVISION_SHIFT) & REVISION_MASK);
+	*revision_value = BIT(revision);
 
 	return 0;
 }
@@ -392,9 +414,14 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
 		goto register_cpufreq_dt;
 	}
 
-	ret = ti_cpufreq_setup_syscon_register(opp_data);
-	if (ret)
-		goto fail_put_node;
+	opp_data->dev = &pdev->dev;
+	opp_data->dev->of_node = opp_data->opp_node;
+
+	if (!of_property_read_bool(opp_data->opp_node, "nvmem-cells")) {
+		ret = ti_cpufreq_setup_syscon_register(opp_data);
+		if (ret)
+			goto fail_put_node;
+	}
 
 	/*
 	 * OPPs determine whether or not they are supported based on
-- 
2.43.0



From msp at baylibre.com  Tue Feb  6 06:57:21 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue,  6 Feb 2024 15:57:21 +0100
Subject: [PATCH 3/3] arm64: dts: ti: k3-am625: Use nvmem-cells for opp
In-Reply-To: <20240206145721.2418893-1-msp@baylibre.com>
References: <20240206145721.2418893-1-msp@baylibre.com>
Message-ID: <20240206145721.2418893-4-msp@baylibre.com>

Use nvmem cells referring to chip variant and speed grade for the
operating points.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 arch/arm64/boot/dts/ti/k3-am625.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am625.dtsi b/arch/arm64/boot/dts/ti/k3-am625.dtsi
index 4193c2b3eed6..d60e1be9eb89 100644
--- a/arch/arm64/boot/dts/ti/k3-am625.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am625.dtsi
@@ -105,6 +105,8 @@ a53_opp_table: opp-table {
 		compatible = "operating-points-v2-ti-cpu";
 		opp-shared;
 		syscon = <&wkup_conf>;
+		nvmem-cells = <&chip_variant>, <&chip_speed>;
+		nvmem-cell-names = "chipvariant", "chipspeed";
 
 		opp-200000000 {
 			opp-hz = /bits/ 64 <200000000>;
-- 
2.43.0



From amergnat at baylibre.com  Tue Feb  6 06:57:58 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Tue, 6 Feb 2024 15:57:58 +0100
Subject: [PATCH v4 3/9] drm/mediatek: dsi: Cleanup functions
 mtk_dsi_ps_control{_vact}()
In-Reply-To: <20240206120748.136610-4-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-4-angelogioacchino.delregno@collabora.com>
Message-ID: <74778dc1-1c36-4db8-9d5e-abdff9f8d8a5@baylibre.com>

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>

On 06/02/2024 13:07, AngeloGioacchino Del Regno wrote:
> Function mtk_dsi_ps_control() is a subset of mtk_dsi_ps_control_vact():
> merge the two in one mtk_dsi_ps_control() function by adding one
> function parameter `config_vact` which, when true, writes the VACT
> related registers.

-- 
Regards,
Alexandre


From neil.armstrong at linaro.org  Tue Feb  6 07:01:45 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Tue, 6 Feb 2024 16:01:45 +0100
Subject: [PATCHv1 4/5] arm64: dts: amlogic: Add cache information to the
 Amlogic S922X SoC
In-Reply-To: <CANAwSgTOpDmZGR33veBWrzr75=xEZ-28iu=GeCzqa0ZPXxDchw@mail.gmail.com>
References: <20240205171930.968-1-linux.amoon@gmail.com>
 <20240205171930.968-5-linux.amoon@gmail.com>
 <cf47b82c-6307-475b-af3a-eab7f09715f0@linaro.org>
 <CANAwSgTOpDmZGR33veBWrzr75=xEZ-28iu=GeCzqa0ZPXxDchw@mail.gmail.com>
Message-ID: <f87069a4-042c-467a-94fb-0b65bfa4758d@linaro.org>

On 06/02/2024 11:15, Anand Moon wrote:
> Hi Neil,
> 
> On Tue, 6 Feb 2024 at 14:30, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>>
>> On 05/02/2024 18:19, Anand Moon wrote:
>>> As per S922X datasheet add missing cache information to the Amlogic
>>> S922X SoC.
>>>
>>> - Each Cortex-A53 core has 32 KB of instruction cache and
>>>        32 KB of L1 data cache available.
>>> - Each Cortex-A73 core has 64 KB of L1 instruction cache and
>>>        64 KB of L1 data cache available.
>>> - The little (A53) cluster has 512 KB of unified L2 cache available.
>>> - The big (A73) cluster has 1 MB of unified L2 cache available.
>>
>> Datasheet says:
>> The quad core Cortex?-A73 processor is paired with A53 processor in a big.Little configuration, with each
>> core has L1 instruction and data chaches, together with a single shared L2 unified cache with A53
>>
> Ok,
> 
> Since all the Cortex?-A73 and Cortex?-A53 share some improvements in
> the architecture with some improvements in cache features
> hence I update the changes accordingly.
> Also, I checked this in the ARM documentation earlier on this.

I don't understand, Amlogic states it's a shared L2 cache, but you trust
the ARM documentation instead ???

> 
>> And there's no indication of the L1 or L2 cache sizes.
> 
> What I feel is in general all the Cortex?-A73 and Cortex?-A53 supports
> L1 and L2 cache size since it is part of the core features.
> but I opted for these size values from a Wikipedia article.
> 
> On my Odroid N2+, I observe the following.
> 
> I have also done some testing on the stress-ng to verify this.


Ok I don't feel confident adding numbers that comes out of thin air,
and even more since they are only shared to userspace.

I think we should only add the numbers which are 100% sure

> 
> alarm at archl-on2:~$ lscpu
> Architecture:           aarch64
>    CPU op-mode(s):       32-bit, 64-bit
>    Byte Order:           Little Endian
> CPU(s):                 6
>    On-line CPU(s) list:  0-5
> Vendor ID:              ARM
>    Model name:           Cortex-A53
>      Model:              4
>      Thread(s) per core: 1
>      Core(s) per socket: 2
>      Socket(s):          1
>      Stepping:           r0p4
>      CPU(s) scaling MHz: 100%
>      CPU max MHz:        1800.0000
>      CPU min MHz:        1000.0000
>      BogoMIPS:           48.00
>      Flags:              fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
>    Model name:           Cortex-A73
>      Model:              2
>      Thread(s) per core: 1
>      Core(s) per socket: 4
>      Socket(s):          1
>      Stepping:           r0p2
>      CPU(s) scaling MHz: 63%
>      CPU max MHz:        2208.0000
>      CPU min MHz:        1000.0000
>      BogoMIPS:           48.00
>      Flags:              fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
> Caches (sum of all):
>    L1d:                  320 KiB (6 instances)
>    L1i:                  320 KiB (6 instances)
>    L2:                   1.5 MiB (2 instances)
> NUMA:
>    NUMA node(s):         1
>    NUMA node0 CPU(s):    0-5
> Vulnerabilities:
>    Gather data sampling: Not affected
>    Itlb multihit:        Not affected
>    L1tf:                 Not affected
>    Mds:                  Not affected
>    Meltdown:             Not affected
>    Mmio stale data:      Not affected
>    Retbleed:             Not affected
>    Spec rstack overflow: Not affected
>    Spec store bypass:    Vulnerable
>    Spectre v1:           Mitigation; __user pointer sanitization
>    Spectre v2:           Vulnerable
>    Srbds:                Not affected
>    Tsx async abort:      Not affected
> alarm at archl-on2:~$
> 
> alarm at archl-on2:~$ lstopo-no-graphics
> Machine (3659MB total)
>    Package L#0
>      NUMANode L#0 (P#0 3659MB)
>      L2 L#0 (512KB)
>        L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0 + PU L#0 (P#0)
>        L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1 + PU L#1 (P#1)
>      L2 L#1 (1024KB)
>        L1d L#2 (64KB) + L1i L#2 (64KB) + Core L#2 + PU L#2 (P#2)
>        L1d L#3 (64KB) + L1i L#3 (64KB) + Core L#3 + PU L#3 (P#3)
>        L1d L#4 (64KB) + L1i L#4 (64KB) + Core L#4 + PU L#4 (P#4)
>        L1d L#5 (64KB) + L1i L#5 (64KB) + Core L#5 + PU L#5 (P#5)
>    Block "mmcblk1boot0"
>    Block "mmcblk1boot1"
>    Block "mmcblk1"
>    Net "eth0"

This looks pretty, but let's keep exporting verified data.

> 
>   >
>> Neil
>>
> 
> Thanks
> -Anand



From festevam at gmail.com  Tue Feb  6 07:03:23 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 6 Feb 2024 12:03:23 -0300
Subject: [PATCH] ARM: dts: imx53: add support for the HDMI expander
In-Reply-To: <20240206-imx53-qsb-hdmi-v1-1-e798eb1181c5@linaro.org>
References: <20240206-imx53-qsb-hdmi-v1-1-e798eb1181c5@linaro.org>
Message-ID: <CAOMZO5DLYV8Eo=9-W1=tiAE6fva_vgheErFVcBJpmF=FHvSOfg@mail.gmail.com>

Hi Dmitry,

On the Subject line: s/imx53/imx53-qsb

On Tue, Feb 6, 2024 at 10:04?AM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> Add support for the MCIMXHDMICARD epansion card attached to the iMX53

s/epansion/expansion

> QSB / QSRB platforms. This enables HDMI output on those devices.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From horms at kernel.org  Tue Feb  6 07:07:04 2024
From: horms at kernel.org (Simon Horman)
Date: Tue, 6 Feb 2024 15:07:04 +0000
Subject: [PATCH] stmmac: Fix incorrect dereference in stmmac_*_interrupt()
In-Reply-To: <20240203150323.1041736-1-p.sakharov@ispras.ru>
References: <20240203150323.1041736-1-p.sakharov@ispras.ru>
Message-ID: <20240206150704.GD1104779@kernel.org>

On Sat, Feb 03, 2024 at 06:03:21PM +0300, Pavel Sakharov wrote:
> If 'dev' is NULL, the 'priv' variable has an incorrect address when
> dereferencing calling netdev_err().
> 
> Pass 'dev' instead of 'priv->dev" to the function.
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Signed-off-by: Pavel Sakharov <p.sakharov at ispras.ru>

Thanks Pavel,

I agree with your analysis that this can result in a NULL dereference.
And that your proposed fix is good: netdev_err() can handle a NULL
dev argument.

As this seems to be a fix I suggest it should be for net.
And that it should be based on that tree and designated as such
in the subject:

Subject: [PATCH net] ...

Also if it is a fix, it should have a fixes tag.
Perhaps this one:

Fixes: 8532f613bc78 ("net: stmmac: introduce MSI Interrupt routines for mac, safety, RX & TX")


I don't think there is a need to respin for the above, though please
keep this in mind when posting Networking patches in future.


Looking at the patch above, and stmmac_main.c, it seems that the following
functions also suffer from a similar problem:

static irqreturn_t stmmac_msi_intr_tx(int irq, void *data)
{
	struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)data;
	...
	dma_conf = container_of(tx_q, struct stmmac_dma_conf, tx_queue[chan]);
	priv = container_of(dma_conf, struct stmmac_priv, dma_conf);

	if (unlikely(!data)) {
		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
		...

And stmmac_msi_intr_rx(), which follows a similar pattern
to stmmac_msi_intr_tx().

I also note that in those functions "invalid dev pointer" seems misleading,
perhaps it ought to be "invalid queue" pointer.

As these problems seem to all have been introduced at the same time,
perhaps it is appropriate to fix them all in one patch?

> ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 4727f7be4f86..5ab5148013cd 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -5848,7 +5848,7 @@ static irqreturn_t stmmac_mac_interrupt(int irq, void *dev_id)
>  	struct stmmac_priv *priv = netdev_priv(dev);
> 
>  	if (unlikely(!dev)) {
> -		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
> +		netdev_err(dev, "%s: invalid dev pointer\n", __func__);
>  		return IRQ_NONE;
>  	}
> 
> @@ -5868,7 +5868,7 @@ static irqreturn_t stmmac_safety_interrupt(int irq, void *dev_id)
>  	struct stmmac_priv *priv = netdev_priv(dev);
> 
>  	if (unlikely(!dev)) {
> -		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
> +		netdev_err(dev, "%s: invalid dev pointer\n", __func__);
>  		return IRQ_NONE;
>  	}
> 
> 


From amergnat at baylibre.com  Tue Feb  6 07:09:37 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Tue, 6 Feb 2024 16:09:37 +0100
Subject: [PATCH v4 4/9] drm/mediatek: dsi: Use bitfield macros where
 useful
In-Reply-To: <20240206120748.136610-5-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-5-angelogioacchino.delregno@collabora.com>
Message-ID: <f5942f06-c4c5-4b5f-bcfb-10b7976d38be@baylibre.com>

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>

On 06/02/2024 13:07, AngeloGioacchino Del Regno wrote:
> Instead of open coding bitshifting for various register fields,
> use the bitfield macro FIELD_PREP(): this allows to enhance the
> human readability, decrease likeliness of mistakes (and register
> field overflowing) and also to simplify the code.
> The latter is especially seen in mtk_dsi_rxtx_control(), where
> it was possible to change a switch to a short for loop and to
> also remove the need to check for maximum DSI lanes == 4 thanks
> to the FIELD_PREP macro masking the value.
> 
> While at it, also add the missing DA_HS_SYNC bitmask, used in
> mtk_dsi_phy_timconfig().

-- 
Regards,
Alexandre


From amergnat at baylibre.com  Tue Feb  6 07:11:06 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Tue, 6 Feb 2024 16:11:06 +0100
Subject: [PATCH v4 5/9] drm/mediatek: dsi: Replace open-coded instance of
 HZ_PER_MHZ
In-Reply-To: <20240206120748.136610-6-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-6-angelogioacchino.delregno@collabora.com>
Message-ID: <594a9b63-0e3d-4ab9-a1c4-bd25ee40d9c7@baylibre.com>

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>

On 06/02/2024 13:07, AngeloGioacchino Del Regno wrote:
> In mtk_dsi_phy_timconfig(), we're dividing the `data_rate` variable,
> expressed in Hz to retrieve a value in MHz: instead of open-coding,
> use the HZ_PER_MHZ definition, available in linux/units.h.

-- 
Regards,
Alexandre


From jgg at nvidia.com  Tue Feb  6 07:12:47 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:47 -0400
Subject: [PATCH v5 10/17] iommu/arm-smmu-v3: Pass smmu_domain to arm_enable/disable_ats()
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <10-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

The caller already has the domain, just pass it in. A following patch will
remove master->domain.

Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

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 2a6ac0af932c54..133f13f33df124 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2474,12 +2474,12 @@ static bool arm_smmu_ats_supported(struct arm_smmu_master *master)
 	return dev_is_pci(dev) && pci_ats_supported(to_pci_dev(dev));
 }
 
-static void arm_smmu_enable_ats(struct arm_smmu_master *master)
+static void arm_smmu_enable_ats(struct arm_smmu_master *master,
+				struct arm_smmu_domain *smmu_domain)
 {
 	size_t stu;
 	struct pci_dev *pdev;
 	struct arm_smmu_device *smmu = master->smmu;
-	struct arm_smmu_domain *smmu_domain = master->domain;
 
 	/* Don't enable ATS at the endpoint if it's not enabled in the STE */
 	if (!master->ats_enabled)
@@ -2495,10 +2495,9 @@ static void arm_smmu_enable_ats(struct arm_smmu_master *master)
 		dev_err(master->dev, "Failed to enable ATS (STU %zu)\n", stu);
 }
 
-static void arm_smmu_disable_ats(struct arm_smmu_master *master)
+static void arm_smmu_disable_ats(struct arm_smmu_master *master,
+				 struct arm_smmu_domain *smmu_domain)
 {
-	struct arm_smmu_domain *smmu_domain = master->domain;
-
 	if (!master->ats_enabled)
 		return;
 
@@ -2567,7 +2566,7 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
 	if (!smmu_domain)
 		return;
 
-	arm_smmu_disable_ats(master);
+	arm_smmu_disable_ats(master, smmu_domain);
 
 	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
 	list_del(&master->domain_head);
@@ -2689,7 +2688,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		break;
 	}
 
-	arm_smmu_enable_ats(master);
+	arm_smmu_enable_ats(master, smmu_domain);
 	goto out_unlock;
 
 out_list_del:
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:38 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:38 -0400
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming independent of the callers
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

As the comment in arm_smmu_write_strtab_ent() explains, this routine has
been limited to only work correctly in certain scenarios that the caller
must ensure. Generally the caller must put the STE into ABORT or BYPASS
before attempting to program it to something else.

The iommu core APIs would ideally expect the driver to do a hitless change
of iommu_domain in a number of cases:

 - RESV_DIRECT support wants IDENTITY -> DMA -> IDENTITY to be hitless
   for the RESV ranges

 - PASID upgrade has IDENTIY on the RID with no PASID then a PASID paging
   domain installed. The RID should not be impacted

 - PASID downgrade has IDENTIY on the RID and all PASID's removed.
   The RID should not be impacted

 - RID does PAGING -> BLOCKING with active PASID, PASID's should not be
   impacted

 - NESTING -> NESTING for carrying all the above hitless cases in a VM
   into the hypervisor. To comprehensively emulate the HW in a VM we should
   assume the VM OS is running logic like this and expecting hitless updates
   to be relayed to real HW.

For CD updates arm_smmu_write_ctx_desc() has a similar comment explaining
how limited it is, and the driver does have a need for hitless CD updates:

 - SMMUv3 BTM S1 ASID re-label

 - SVA mm release should change the CD to answert not-present to all
   requests without allowing logging (EPD0)

The next patches/series are going to start removing some of this logic
from the callers, and add more complex state combinations than currently.
At the end everything that can be hitless will be hitless, including all
of the above.

Introduce arm_smmu_write_entry() which will run through the multi-qword
programming sequence to avoid creating an incoherent 'torn' STE in the HW
caches. It automatically detects which of two algorithms to use:

1) The disruptive V=0 update described in the spec which disrupts the
   entry and does three syncs to make the change:
       - Write V=0 to QWORD 0
       - Write the entire STE except QWORD 0
       - Write QWORD 0

2) A hitless update algorithm that follows the same rational that the driver
   already uses. It is safe to change IGNORED bits that HW doesn't use:
       - Write the target value into all currently unused bits
       - Write a single QWORD, this makes the new STE live atomically
       - Ensure now unused bits are 0

The detection of which path to use and the implementation of the hitless
update rely on a "used bitmask" describing what bits the HW is actually
using based on the V/CFG/etc bits. This flows from the spec language,
typically indicated as IGNORED.

Knowing which bits the HW is using we can update the bits it does not use
and then compute how many QWORDS need to be changed. If only one qword
needs to be updated the hitless algorithm is possible.

Later patches will include CD updates in this mechanism so make the
implementation generic using a struct arm_smmu_entry_writer and struct
arm_smmu_entry_writer_ops to abstract the differences between STE and CD
to be plugged in.

At this point it generates the same sequence of updates as the current
code, except that zeroing the VMID on entry to BYPASS/ABORT will do an
extra sync (this seems to be an existing bug).

Going forward this will use a V=0 transition instead of cycling through
ABORT if a hitfull change is required. This seems more appropriate as ABORT
will fail DMAs without any logging, but dropping a DMA due to transient
V=0 is probably signaling a bug, so the C_BAD_STE is valuable.

Signed-off-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 330 ++++++++++++++++----
 1 file changed, 263 insertions(+), 67 deletions(-)

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 0ffb1cf17e0b2e..f0b915567cbcdc 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -48,6 +48,21 @@ enum arm_smmu_msi_index {
 	ARM_SMMU_MAX_MSIS,
 };
 
+struct arm_smmu_entry_writer_ops;
+struct arm_smmu_entry_writer {
+	const struct arm_smmu_entry_writer_ops *ops;
+	struct arm_smmu_master *master;
+};
+
+struct arm_smmu_entry_writer_ops {
+	unsigned int num_entry_qwords;
+	__le64 v_bit;
+	void (*get_used)(const __le64 *entry, __le64 *used);
+	void (*sync)(struct arm_smmu_entry_writer *writer);
+};
+
+#define NUM_ENTRY_QWORDS (sizeof(struct arm_smmu_ste) / sizeof(u64))
+
 static phys_addr_t arm_smmu_msi_cfg[ARM_SMMU_MAX_MSIS][3] = {
 	[EVTQ_MSI_INDEX] = {
 		ARM_SMMU_EVTQ_IRQ_CFG0,
@@ -971,6 +986,140 @@ void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid)
 	arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 }
 
+/*
+ * Figure out if we can do a hitless update of entry to become target. Returns a
+ * bit mask where 1 indicates that qword needs to be set disruptively.
+ * unused_update is an intermediate value of entry that has unused bits set to
+ * their new values.
+ */
+static u8 arm_smmu_entry_qword_diff(struct arm_smmu_entry_writer *writer,
+				    const __le64 *entry, const __le64 *target,
+				    __le64 *unused_update)
+{
+	__le64 target_used[NUM_ENTRY_QWORDS] = {};
+	__le64 cur_used[NUM_ENTRY_QWORDS] = {};
+	u8 used_qword_diff = 0;
+	unsigned int i;
+
+	writer->ops->get_used(entry, cur_used);
+	writer->ops->get_used(target, target_used);
+
+	for (i = 0; i != writer->ops->num_entry_qwords; i++) {
+		/*
+		 * Check that masks are up to date, the make functions are not
+		 * allowed to set a bit to 1 if the used function doesn't say it
+		 * is used.
+		 */
+		WARN_ON_ONCE(target[i] & ~target_used[i]);
+
+		/* Bits can change because they are not currently being used */
+		unused_update[i] = (entry[i] & cur_used[i]) |
+				   (target[i] & ~cur_used[i]);
+		/*
+		 * Each bit indicates that a used bit in a qword needs to be
+		 * changed after unused_update is applied.
+		 */
+		if ((unused_update[i] & target_used[i]) != target[i])
+			used_qword_diff |= 1 << i;
+	}
+	return used_qword_diff;
+}
+
+static bool entry_set(struct arm_smmu_entry_writer *writer, __le64 *entry,
+		      const __le64 *target, unsigned int start,
+		      unsigned int len)
+{
+	bool changed = false;
+	unsigned int i;
+
+	for (i = start; len != 0; len--, i++) {
+		if (entry[i] != target[i]) {
+			WRITE_ONCE(entry[i], target[i]);
+			changed = true;
+		}
+	}
+
+	if (changed)
+		writer->ops->sync(writer);
+	return changed;
+}
+
+/*
+ * Update the STE/CD to the target configuration. The transition from the
+ * current entry to the target entry takes place over multiple steps that
+ * attempts to make the transition hitless if possible. This function takes care
+ * not to create a situation where the HW can perceive a corrupted entry. HW is
+ * only required to have a 64 bit atomicity with stores from the CPU, while
+ * entries are many 64 bit values big.
+ *
+ * The difference between the current value and the target value is analyzed to
+ * determine which of three updates are required - disruptive, hitless or no
+ * change.
+ *
+ * In the most general disruptive case we can make any update in three steps:
+ *  - Disrupting the entry (V=0)
+ *  - Fill now unused qwords, execpt qword 0 which contains V
+ *  - Make qword 0 have the final value and valid (V=1) with a single 64
+ *    bit store
+ *
+ * However this disrupts the HW while it is happening. There are several
+ * interesting cases where a STE/CD can be updated without disturbing the HW
+ * because only a small number of bits are changing (S1DSS, CONFIG, etc) or
+ * because the used bits don't intersect. We can detect this by calculating how
+ * many 64 bit values need update after adjusting the unused bits and skip the
+ * V=0 process. This relies on the IGNORED behavior described in the
+ * specification.
+ */
+static void arm_smmu_write_entry(struct arm_smmu_entry_writer *writer,
+				 __le64 *entry, const __le64 *target)
+{
+	unsigned int num_entry_qwords = writer->ops->num_entry_qwords;
+	__le64 unused_update[NUM_ENTRY_QWORDS];
+	u8 used_qword_diff;
+
+	used_qword_diff =
+		arm_smmu_entry_qword_diff(writer, entry, target, unused_update);
+	if (hweight8(used_qword_diff) == 1) {
+		/*
+		 * Only one qword needs its used bits to be changed. This is a
+		 * hitless update, update all bits the current STE is ignoring
+		 * to their new values, then update a single "critical qword" to
+		 * change the STE and finally 0 out any bits that are now unused
+		 * in the target configuration.
+		 */
+		unsigned int critical_qword_index = ffs(used_qword_diff) - 1;
+
+		/*
+		 * Skip writing unused bits in the critical qword since we'll be
+		 * writing it in the next step anyways. This can save a sync
+		 * when the only change is in that qword.
+		 */
+		unused_update[critical_qword_index] =
+			entry[critical_qword_index];
+		entry_set(writer, entry, unused_update, 0, num_entry_qwords);
+		entry_set(writer, entry, target, critical_qword_index, 1);
+		entry_set(writer, entry, target, 0, num_entry_qwords);
+	} else if (used_qword_diff) {
+		/*
+		 * At least two qwords need their inuse bits to be changed. This
+		 * requires a breaking update, zero the V bit, write all qwords
+		 * but 0, then set qword 0
+		 */
+		unused_update[0] = entry[0] & (~writer->ops->v_bit);
+		entry_set(writer, entry, unused_update, 0, 1);
+		entry_set(writer, entry, target, 1, num_entry_qwords - 1);
+		entry_set(writer, entry, target, 0, 1);
+	} else {
+		/*
+		 * No inuse bit changed. Sanity check that all unused bits are 0
+		 * in the entry. The target was already sanity checked by
+		 * compute_qword_diff().
+		 */
+		WARN_ON_ONCE(
+			entry_set(writer, entry, target, 0, num_entry_qwords));
+	}
+}
+
 static void arm_smmu_sync_cd(struct arm_smmu_master *master,
 			     int ssid, bool leaf)
 {
@@ -1238,50 +1387,126 @@ arm_smmu_write_strtab_l1_desc(__le64 *dst, struct arm_smmu_strtab_l1_desc *desc)
 	WRITE_ONCE(*dst, cpu_to_le64(val));
 }
 
-static void arm_smmu_sync_ste_for_sid(struct arm_smmu_device *smmu, u32 sid)
+struct arm_smmu_ste_writer {
+	struct arm_smmu_entry_writer writer;
+	u32 sid;
+};
+
+/*
+ * Based on the value of ent report which bits of the STE the HW will access. It
+ * would be nice if this was complete according to the spec, but minimally it
+ * has to capture the bits this driver uses.
+ */
+static void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
 {
+	unsigned int cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ent[0]));
+
+	used_bits[0] = cpu_to_le64(STRTAB_STE_0_V);
+	if (!(ent[0] & cpu_to_le64(STRTAB_STE_0_V)))
+		return;
+
+	/*
+	 * See 13.5 Summary of attribute/permission configuration fields for the
+	 * SHCFG behavior. It is only used for BYPASS, including S1DSS BYPASS,
+	 * and S2 only.
+	 */
+	if (cfg == STRTAB_STE_0_CFG_BYPASS ||
+	    cfg == STRTAB_STE_0_CFG_S2_TRANS ||
+	    (cfg == STRTAB_STE_0_CFG_S1_TRANS &&
+	     FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
+		     STRTAB_STE_1_S1DSS_BYPASS))
+		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_SHCFG);
+
+	used_bits[0] |= cpu_to_le64(STRTAB_STE_0_CFG);
+	switch (cfg) {
+	case STRTAB_STE_0_CFG_ABORT:
+	case STRTAB_STE_0_CFG_BYPASS:
+		break;
+	case STRTAB_STE_0_CFG_S1_TRANS:
+		used_bits[0] |= cpu_to_le64(STRTAB_STE_0_S1FMT |
+					    STRTAB_STE_0_S1CTXPTR_MASK |
+					    STRTAB_STE_0_S1CDMAX);
+		used_bits[1] |=
+			cpu_to_le64(STRTAB_STE_1_S1DSS | STRTAB_STE_1_S1CIR |
+				    STRTAB_STE_1_S1COR | STRTAB_STE_1_S1CSH |
+				    STRTAB_STE_1_S1STALLD | STRTAB_STE_1_STRW);
+		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_EATS);
+		used_bits[2] |= cpu_to_le64(STRTAB_STE_2_S2VMID);
+		break;
+	case STRTAB_STE_0_CFG_S2_TRANS:
+		used_bits[1] |=
+			cpu_to_le64(STRTAB_STE_1_EATS);
+		used_bits[2] |=
+			cpu_to_le64(STRTAB_STE_2_S2VMID | STRTAB_STE_2_VTCR |
+				    STRTAB_STE_2_S2AA64 | STRTAB_STE_2_S2ENDI |
+				    STRTAB_STE_2_S2PTW | STRTAB_STE_2_S2R);
+		used_bits[3] |= cpu_to_le64(STRTAB_STE_3_S2TTB_MASK);
+		break;
+
+	default:
+		memset(used_bits, 0xFF, sizeof(struct arm_smmu_ste));
+		WARN_ON(true);
+	}
+}
+
+static void arm_smmu_ste_writer_sync_entry(struct arm_smmu_entry_writer *writer)
+{
+	struct arm_smmu_ste_writer *ste_writer =
+		container_of(writer, struct arm_smmu_ste_writer, writer);
 	struct arm_smmu_cmdq_ent cmd = {
 		.opcode	= CMDQ_OP_CFGI_STE,
 		.cfgi	= {
-			.sid	= sid,
+			.sid	= ste_writer->sid,
 			.leaf	= true,
 		},
 	};
 
-	arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
+	arm_smmu_cmdq_issue_cmd_with_sync(writer->master->smmu, &cmd);
+}
+
+static const struct arm_smmu_entry_writer_ops arm_smmu_ste_writer_ops = {
+	.sync = arm_smmu_ste_writer_sync_entry,
+	.get_used = arm_smmu_get_ste_used,
+	.v_bit = cpu_to_le64(STRTAB_STE_0_V),
+	.num_entry_qwords = sizeof(struct arm_smmu_ste) / sizeof(u64),
+};
+
+static void arm_smmu_write_ste(struct arm_smmu_master *master, u32 sid,
+			       struct arm_smmu_ste *ste,
+			       const struct arm_smmu_ste *target)
+{
+	struct arm_smmu_device *smmu = master->smmu;
+	struct arm_smmu_ste_writer ste_writer = {
+		.writer = {
+			.ops = &arm_smmu_ste_writer_ops,
+			.master = master,
+		},
+		.sid = sid,
+	};
+
+	arm_smmu_write_entry(&ste_writer.writer, ste->data, target->data);
+
+	/* It's likely that we'll want to use the new STE soon */
+	if (!(smmu->options & ARM_SMMU_OPT_SKIP_PREFETCH)) {
+		struct arm_smmu_cmdq_ent
+			prefetch_cmd = { .opcode = CMDQ_OP_PREFETCH_CFG,
+					 .prefetch = {
+						 .sid = sid,
+					 } };
+
+		arm_smmu_cmdq_issue_cmd(smmu, &prefetch_cmd);
+	}
 }
 
 static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 				      struct arm_smmu_ste *dst)
 {
-	/*
-	 * This is hideously complicated, but we only really care about
-	 * three cases at the moment:
-	 *
-	 * 1. Invalid (all zero) -> bypass/fault (init)
-	 * 2. Bypass/fault -> translation/bypass (attach)
-	 * 3. Translation/bypass -> bypass/fault (detach)
-	 *
-	 * Given that we can't update the STE atomically and the SMMU
-	 * doesn't read the thing in a defined order, that leaves us
-	 * with the following maintenance requirements:
-	 *
-	 * 1. Update Config, return (init time STEs aren't live)
-	 * 2. Write everything apart from dword 0, sync, write dword 0, sync
-	 * 3. Update Config, sync
-	 */
-	u64 val = le64_to_cpu(dst->data[0]);
-	bool ste_live = false;
+	u64 val;
 	struct arm_smmu_device *smmu = master->smmu;
 	struct arm_smmu_ctx_desc_cfg *cd_table = NULL;
 	struct arm_smmu_s2_cfg *s2_cfg = NULL;
 	struct arm_smmu_domain *smmu_domain = master->domain;
-	struct arm_smmu_cmdq_ent prefetch_cmd = {
-		.opcode		= CMDQ_OP_PREFETCH_CFG,
-		.prefetch	= {
-			.sid	= sid,
-		},
-	};
+	struct arm_smmu_ste target = {};
 
 	if (smmu_domain) {
 		switch (smmu_domain->stage) {
@@ -1296,22 +1521,6 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 		}
 	}
 
-	if (val & STRTAB_STE_0_V) {
-		switch (FIELD_GET(STRTAB_STE_0_CFG, val)) {
-		case STRTAB_STE_0_CFG_BYPASS:
-			break;
-		case STRTAB_STE_0_CFG_S1_TRANS:
-		case STRTAB_STE_0_CFG_S2_TRANS:
-			ste_live = true;
-			break;
-		case STRTAB_STE_0_CFG_ABORT:
-			BUG_ON(!disable_bypass);
-			break;
-		default:
-			BUG(); /* STE corruption */
-		}
-	}
-
 	/* Nuke the existing STE_0 value, as we're going to rewrite it */
 	val = STRTAB_STE_0_V;
 
@@ -1322,16 +1531,11 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 		else
 			val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
 
-		dst->data[0] = cpu_to_le64(val);
-		dst->data[1] = cpu_to_le64(FIELD_PREP(STRTAB_STE_1_SHCFG,
+		target.data[0] = cpu_to_le64(val);
+		target.data[1] = cpu_to_le64(FIELD_PREP(STRTAB_STE_1_SHCFG,
 						STRTAB_STE_1_SHCFG_INCOMING));
-		dst->data[2] = 0; /* Nuke the VMID */
-		/*
-		 * The SMMU can perform negative caching, so we must sync
-		 * the STE regardless of whether the old value was live.
-		 */
-		if (smmu)
-			arm_smmu_sync_ste_for_sid(smmu, sid);
+		target.data[2] = 0; /* Nuke the VMID */
+		arm_smmu_write_ste(master, sid, dst, &target);
 		return;
 	}
 
@@ -1339,8 +1543,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 		u64 strw = smmu->features & ARM_SMMU_FEAT_E2H ?
 			STRTAB_STE_1_STRW_EL2 : STRTAB_STE_1_STRW_NSEL1;
 
-		BUG_ON(ste_live);
-		dst->data[1] = cpu_to_le64(
+		target.data[1] = cpu_to_le64(
 			 FIELD_PREP(STRTAB_STE_1_S1DSS, STRTAB_STE_1_S1DSS_SSID0) |
 			 FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) |
 			 FIELD_PREP(STRTAB_STE_1_S1COR, STRTAB_STE_1_S1C_CACHE_WBRA) |
@@ -1349,7 +1552,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 
 		if (smmu->features & ARM_SMMU_FEAT_STALLS &&
 		    !master->stall_enabled)
-			dst->data[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
+			target.data[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
 
 		val |= (cd_table->cdtab_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
 			FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS) |
@@ -1358,8 +1561,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 	}
 
 	if (s2_cfg) {
-		BUG_ON(ste_live);
-		dst->data[2] = cpu_to_le64(
+		target.data[2] = cpu_to_le64(
 			 FIELD_PREP(STRTAB_STE_2_S2VMID, s2_cfg->vmid) |
 			 FIELD_PREP(STRTAB_STE_2_VTCR, s2_cfg->vtcr) |
 #ifdef __BIG_ENDIAN
@@ -1368,23 +1570,17 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 			 STRTAB_STE_2_S2PTW | STRTAB_STE_2_S2AA64 |
 			 STRTAB_STE_2_S2R);
 
-		dst->data[3] = cpu_to_le64(s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK);
+		target.data[3] = cpu_to_le64(s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK);
 
 		val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS);
 	}
 
 	if (master->ats_enabled)
-		dst->data[1] |= cpu_to_le64(FIELD_PREP(STRTAB_STE_1_EATS,
+		target.data[1] |= cpu_to_le64(FIELD_PREP(STRTAB_STE_1_EATS,
 						 STRTAB_STE_1_EATS_TRANS));
 
-	arm_smmu_sync_ste_for_sid(smmu, sid);
-	/* See comment in arm_smmu_write_ctx_desc() */
-	WRITE_ONCE(dst->data[0], cpu_to_le64(val));
-	arm_smmu_sync_ste_for_sid(smmu, sid);
-
-	/* It's likely that we'll want to use the new STE soon */
-	if (!(smmu->options & ARM_SMMU_OPT_SKIP_PREFETCH))
-		arm_smmu_cmdq_issue_cmd(smmu, &prefetch_cmd);
+	target.data[0] = cpu_to_le64(val);
+	arm_smmu_write_ste(master, sid, dst, &target);
 }
 
 static void arm_smmu_init_bypass_stes(struct arm_smmu_ste *strtab,
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:42 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:42 -0400
Subject: [PATCH v5 05/17] iommu/arm-smmu-v3: Build the whole STE in arm_smmu_make_s2_domain_ste()
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <5-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

Half the code was living in arm_smmu_domain_finalise_s2(), just move it
here and take the values directly from the pgtbl_ops instead of storing
copies.

Reviewed-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Reviewed-by: Mostafa Saleh <smostafa at google.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 27 ++++++++++++---------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  2 --
 2 files changed, 15 insertions(+), 14 deletions(-)

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 893df3e76400ec..417b2c877ff311 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1573,6 +1573,11 @@ static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
 					struct arm_smmu_domain *smmu_domain)
 {
 	struct arm_smmu_s2_cfg *s2_cfg = &smmu_domain->s2_cfg;
+	const struct io_pgtable_cfg *pgtbl_cfg =
+		&io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops)->cfg;
+	typeof(&pgtbl_cfg->arm_lpae_s2_cfg.vtcr) vtcr =
+		&pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
+	u64 vtcr_val;
 
 	memset(target, 0, sizeof(*target));
 	target->data[0] = cpu_to_le64(
@@ -1585,9 +1590,16 @@ static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
 		FIELD_PREP(STRTAB_STE_1_SHCFG,
 			   STRTAB_STE_1_SHCFG_NON_SHARABLE));
 
+	vtcr_val = FIELD_PREP(STRTAB_STE_2_VTCR_S2T0SZ, vtcr->tsz) |
+		   FIELD_PREP(STRTAB_STE_2_VTCR_S2SL0, vtcr->sl) |
+		   FIELD_PREP(STRTAB_STE_2_VTCR_S2IR0, vtcr->irgn) |
+		   FIELD_PREP(STRTAB_STE_2_VTCR_S2OR0, vtcr->orgn) |
+		   FIELD_PREP(STRTAB_STE_2_VTCR_S2SH0, vtcr->sh) |
+		   FIELD_PREP(STRTAB_STE_2_VTCR_S2TG, vtcr->tg) |
+		   FIELD_PREP(STRTAB_STE_2_VTCR_S2PS, vtcr->ps);
 	target->data[2] = cpu_to_le64(
 		FIELD_PREP(STRTAB_STE_2_S2VMID, s2_cfg->vmid) |
-		FIELD_PREP(STRTAB_STE_2_VTCR, s2_cfg->vtcr) |
+		FIELD_PREP(STRTAB_STE_2_VTCR, vtcr_val) |
 		STRTAB_STE_2_S2AA64 |
 #ifdef __BIG_ENDIAN
 		STRTAB_STE_2_S2ENDI |
@@ -1595,7 +1607,8 @@ static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
 		STRTAB_STE_2_S2PTW |
 		STRTAB_STE_2_S2R);
 
-	target->data[3] = cpu_to_le64(s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK);
+	target->data[3] = cpu_to_le64(pgtbl_cfg->arm_lpae_s2_cfg.vttbr &
+				      STRTAB_STE_3_S2TTB_MASK);
 }
 
 static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
@@ -2355,7 +2368,6 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
 	int vmid;
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
 	struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
-	typeof(&pgtbl_cfg->arm_lpae_s2_cfg.vtcr) vtcr;
 
 	/* Reserve VMID 0 for stage-2 bypass STEs */
 	vmid = ida_alloc_range(&smmu->vmid_map, 1, (1 << smmu->vmid_bits) - 1,
@@ -2363,16 +2375,7 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
 	if (vmid < 0)
 		return vmid;
 
-	vtcr = &pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
 	cfg->vmid	= (u16)vmid;
-	cfg->vttbr	= pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
-	cfg->vtcr	= FIELD_PREP(STRTAB_STE_2_VTCR_S2T0SZ, vtcr->tsz) |
-			  FIELD_PREP(STRTAB_STE_2_VTCR_S2SL0, vtcr->sl) |
-			  FIELD_PREP(STRTAB_STE_2_VTCR_S2IR0, vtcr->irgn) |
-			  FIELD_PREP(STRTAB_STE_2_VTCR_S2OR0, vtcr->orgn) |
-			  FIELD_PREP(STRTAB_STE_2_VTCR_S2SH0, vtcr->sh) |
-			  FIELD_PREP(STRTAB_STE_2_VTCR_S2TG, vtcr->tg) |
-			  FIELD_PREP(STRTAB_STE_2_VTCR_S2PS, vtcr->ps);
 	return 0;
 }
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 53695dbc9b33f3..cbf4b57719b7b9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -610,8 +610,6 @@ struct arm_smmu_ctx_desc_cfg {
 
 struct arm_smmu_s2_cfg {
 	u16				vmid;
-	u64				vttbr;
-	u64				vtcr;
 };
 
 struct arm_smmu_strtab_cfg {
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:39 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:39 -0400
Subject: [PATCH v5 02/17] iommu/arm-smmu-v3: Consolidate the STE generation for abort/bypass
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <2-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

This allows writing the flow of arm_smmu_write_strtab_ent() around abort
and bypass domains more naturally.

Note that the core code no longer supplies NULL domains, though there is
still a flow in the driver that end up in arm_smmu_write_strtab_ent() with
NULL. A later patch will remove it.

Remove the duplicate calculation of the STE in arm_smmu_init_bypass_stes()
and remove the force parameter. arm_smmu_rmr_install_bypass_ste() can now
simply invoke arm_smmu_make_bypass_ste() directly.

Reviewed-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Reviewed-by: Mostafa Saleh <smostafa at google.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 97 ++++++++++++---------
 1 file changed, 55 insertions(+), 42 deletions(-)

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 f0b915567cbcdc..6123e5ad95822c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1498,6 +1498,24 @@ static void arm_smmu_write_ste(struct arm_smmu_master *master, u32 sid,
 	}
 }
 
+static void arm_smmu_make_abort_ste(struct arm_smmu_ste *target)
+{
+	memset(target, 0, sizeof(*target));
+	target->data[0] = cpu_to_le64(
+		STRTAB_STE_0_V |
+		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT));
+}
+
+static void arm_smmu_make_bypass_ste(struct arm_smmu_ste *target)
+{
+	memset(target, 0, sizeof(*target));
+	target->data[0] = cpu_to_le64(
+		STRTAB_STE_0_V |
+		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS));
+	target->data[1] = cpu_to_le64(
+		FIELD_PREP(STRTAB_STE_1_SHCFG, STRTAB_STE_1_SHCFG_INCOMING));
+}
+
 static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 				      struct arm_smmu_ste *dst)
 {
@@ -1508,37 +1526,31 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 	struct arm_smmu_domain *smmu_domain = master->domain;
 	struct arm_smmu_ste target = {};
 
-	if (smmu_domain) {
-		switch (smmu_domain->stage) {
-		case ARM_SMMU_DOMAIN_S1:
-			cd_table = &master->cd_table;
-			break;
-		case ARM_SMMU_DOMAIN_S2:
-			s2_cfg = &smmu_domain->s2_cfg;
-			break;
-		default:
-			break;
-		}
+	if (!smmu_domain) {
+		if (disable_bypass)
+			arm_smmu_make_abort_ste(&target);
+		else
+			arm_smmu_make_bypass_ste(&target);
+		arm_smmu_write_ste(master, sid, dst, &target);
+		return;
+	}
+
+	switch (smmu_domain->stage) {
+	case ARM_SMMU_DOMAIN_S1:
+		cd_table = &master->cd_table;
+		break;
+	case ARM_SMMU_DOMAIN_S2:
+		s2_cfg = &smmu_domain->s2_cfg;
+		break;
+	case ARM_SMMU_DOMAIN_BYPASS:
+		arm_smmu_make_bypass_ste(&target);
+		arm_smmu_write_ste(master, sid, dst, &target);
+		return;
 	}
 
 	/* Nuke the existing STE_0 value, as we're going to rewrite it */
 	val = STRTAB_STE_0_V;
 
-	/* Bypass/fault */
-	if (!smmu_domain || !(cd_table || s2_cfg)) {
-		if (!smmu_domain && disable_bypass)
-			val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT);
-		else
-			val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
-
-		target.data[0] = cpu_to_le64(val);
-		target.data[1] = cpu_to_le64(FIELD_PREP(STRTAB_STE_1_SHCFG,
-						STRTAB_STE_1_SHCFG_INCOMING));
-		target.data[2] = 0; /* Nuke the VMID */
-		arm_smmu_write_ste(master, sid, dst, &target);
-		return;
-	}
-
 	if (cd_table) {
 		u64 strw = smmu->features & ARM_SMMU_FEAT_E2H ?
 			STRTAB_STE_1_STRW_EL2 : STRTAB_STE_1_STRW_NSEL1;
@@ -1583,22 +1595,20 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 	arm_smmu_write_ste(master, sid, dst, &target);
 }
 
+/*
+ * This can safely directly manipulate the STE memory without a sync sequence
+ * because the STE table has not been installed in the SMMU yet.
+ */
 static void arm_smmu_init_bypass_stes(struct arm_smmu_ste *strtab,
-				      unsigned int nent, bool force)
+				      unsigned int nent)
 {
 	unsigned int i;
-	u64 val = STRTAB_STE_0_V;
-
-	if (disable_bypass && !force)
-		val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT);
-	else
-		val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
 
 	for (i = 0; i < nent; ++i) {
-		strtab->data[0] = cpu_to_le64(val);
-		strtab->data[1] = cpu_to_le64(FIELD_PREP(
-			STRTAB_STE_1_SHCFG, STRTAB_STE_1_SHCFG_INCOMING));
-		strtab->data[2] = 0;
+		if (disable_bypass)
+			arm_smmu_make_abort_ste(strtab);
+		else
+			arm_smmu_make_bypass_ste(strtab);
 		strtab++;
 	}
 }
@@ -1626,7 +1636,7 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
 		return -ENOMEM;
 	}
 
-	arm_smmu_init_bypass_stes(desc->l2ptr, 1 << STRTAB_SPLIT, false);
+	arm_smmu_init_bypass_stes(desc->l2ptr, 1 << STRTAB_SPLIT);
 	arm_smmu_write_strtab_l1_desc(strtab, desc);
 	return 0;
 }
@@ -3245,7 +3255,7 @@ static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
 	reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits);
 	cfg->strtab_base_cfg = reg;
 
-	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents, false);
+	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents);
 	return 0;
 }
 
@@ -3956,7 +3966,6 @@ static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
 	iort_get_rmr_sids(dev_fwnode(smmu->dev), &rmr_list);
 
 	list_for_each_entry(e, &rmr_list, list) {
-		struct arm_smmu_ste *step;
 		struct iommu_iort_rmr_data *rmr;
 		int ret, i;
 
@@ -3969,8 +3978,12 @@ static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
 				continue;
 			}
 
-			step = arm_smmu_get_step_for_sid(smmu, rmr->sids[i]);
-			arm_smmu_init_bypass_stes(step, 1, true);
+			/*
+			 * STE table is not programmed to HW, see
+			 * arm_smmu_init_bypass_stes()
+			 */
+			arm_smmu_make_bypass_ste(
+				arm_smmu_get_step_for_sid(smmu, rmr->sids[i]));
 		}
 	}
 
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:49 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:49 -0400
Subject: [PATCH v5 12/17] iommu/arm-smmu-v3: Check that the RID domain is S1 in SVA
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <12-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

The SVA code only works if the RID domain is a S1 domain and has already
installed the cdtable.

Originally the check for this was in arm_smmu_sva_bind() but when the op
was removed the test didn't get copied over to the new
arm_smmu_sva_set_dev_pasid().

Without the test wrong usage usually will hit a WARN_ON() in
arm_smmu_write_ctx_desc() due to a missing ctx table.

However, the next patches wil change things so that an IDENTITY domain is
not a struct arm_smmu_domain and this will get into memory corruption if
the struct is wrongly casted.

Fail in arm_smmu_sva_set_dev_pasid() if the STE does not have a S1, which
is a proxy for the STE having a pointer to the CD table. Write it in a way
that will be compatible with the next patches.

Fixes: 386fa64fd52b ("arm-smmu-v3/sva: Add SVA domain support")
Reported-by: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
Closes: https://lore.kernel.org/linux-iommu/2a828e481416405fb3a4cceb9e075a59 at huawei.com/
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index 05722121f00e70..540f524ecf018b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -387,7 +387,13 @@ static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
 	struct arm_smmu_bond *bond;
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
 	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
-	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+	struct arm_smmu_domain *smmu_domain;
+
+	if (!(domain->type & __IOMMU_DOMAIN_PAGING))
+		return -ENODEV;
+	smmu_domain = to_smmu_domain(domain);
+	if (smmu_domain->stage != ARM_SMMU_DOMAIN_S1)
+		return -ENODEV;
 
 	if (!master || !master->sva_enabled)
 		return -ENODEV;
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:51 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:51 -0400
Subject: [PATCH v5 14/17] iommu/arm-smmu-v3: Add a global static BLOCKED domain
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <14-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

Using the same design as the IDENTITY domain install an
STRTAB_STE_0_CFG_ABORT STE.

Reviewed-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 19 +++++++++++++++++++
 1 file changed, 19 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 a940b5ff96843c..9271f3a035b5b8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2727,6 +2727,24 @@ static struct iommu_domain arm_smmu_identity_domain = {
 	.ops = &arm_smmu_identity_ops,
 };
 
+static int arm_smmu_attach_dev_blocked(struct iommu_domain *domain,
+					struct device *dev)
+{
+	struct arm_smmu_ste ste;
+
+	arm_smmu_make_abort_ste(&ste);
+	return arm_smmu_attach_dev_ste(dev, &ste);
+}
+
+static const struct iommu_domain_ops arm_smmu_blocked_ops = {
+	.attach_dev = arm_smmu_attach_dev_blocked,
+};
+
+static struct iommu_domain arm_smmu_blocked_domain = {
+	.type = IOMMU_DOMAIN_BLOCKED,
+	.ops = &arm_smmu_blocked_ops,
+};
+
 static int arm_smmu_map_pages(struct iommu_domain *domain, unsigned long iova,
 			      phys_addr_t paddr, size_t pgsize, size_t pgcount,
 			      int prot, gfp_t gfp, size_t *mapped)
@@ -3117,6 +3135,7 @@ static void arm_smmu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
 
 static struct iommu_ops arm_smmu_ops = {
 	.identity_domain	= &arm_smmu_identity_domain,
+	.blocked_domain		= &arm_smmu_blocked_domain,
 	.capable		= arm_smmu_capable,
 	.domain_alloc		= arm_smmu_domain_alloc,
 	.probe_device		= arm_smmu_probe_device,
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:45 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:45 -0400
Subject: [PATCH v5 08/17] iommu/arm-smmu-v3: Do not change the STE twice during arm_smmu_attach_dev()
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <8-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

This was needed because the STE code required the STE to be in
ABORT/BYPASS inorder to program a cdtable or S2 STE. Now that the STE code
can automatically handle all transitions we can remove this step
from the attach_dev flow.

A few small bugs exist because of this:

1) If the core code does BLOCKED -> UNMANAGED with disable_bypass=false
   then there will be a moment where the STE points at BYPASS. Since
   this can be done by VFIO/IOMMUFD it is a small security race.

2) If the core code does IDENTITY -> DMA then any IOMMU_RESV_DIRECT
   regions will temporarily become BLOCKED. We'd like drivers to
   work in a way that allows IOMMU_RESV_DIRECT to be continuously
   functional during these transitions.

Make arm_smmu_release_device() put the STE back to the correct
ABORT/BYPASS setting. Fix a bug where a IOMMU_RESV_DIRECT was ignored on
this path.

As noted before the reordering of the linked list/STE/CD changes is OK
against concurrent arm_smmu_share_asid() because of the
arm_smmu_asid_lock.

Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

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 1138e868c4d73e..340f3dc82c9ce0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2562,7 +2562,6 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
 static void arm_smmu_detach_dev(struct arm_smmu_master *master)
 {
 	unsigned long flags;
-	struct arm_smmu_ste target;
 	struct arm_smmu_domain *smmu_domain = master->domain;
 
 	if (!smmu_domain)
@@ -2576,11 +2575,6 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
 
 	master->domain = NULL;
 	master->ats_enabled = false;
-	if (disable_bypass)
-		arm_smmu_make_abort_ste(&target);
-	else
-		arm_smmu_make_bypass_ste(&target);
-	arm_smmu_install_ste_for_dev(master, &target);
 	/*
 	 * Clearing the CD entry isn't strictly required to detach the domain
 	 * since the table is uninstalled anyway, but it helps avoid confusion
@@ -2928,9 +2922,18 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 static void arm_smmu_release_device(struct device *dev)
 {
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+	struct arm_smmu_ste target;
 
 	if (WARN_ON(arm_smmu_master_sva_enabled(master)))
 		iopf_queue_remove_device(master->smmu->evtq.iopf, dev);
+
+	/* Put the STE back to what arm_smmu_init_strtab() sets */
+	if (disable_bypass && !dev->iommu->require_direct)
+		arm_smmu_make_abort_ste(&target);
+	else
+		arm_smmu_make_bypass_ste(&target);
+	arm_smmu_install_ste_for_dev(master, &target);
+
 	arm_smmu_detach_dev(master);
 	arm_smmu_disable_pasid(master);
 	arm_smmu_remove_master(master);
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:46 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:46 -0400
Subject: [PATCH v5 09/17] iommu/arm-smmu-v3: Put writing the context descriptor in the right order
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <9-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

Get closer to the IOMMU API ideal that changes between domains can be
hitless. The ordering for the CD table entry is not entirely clean from
this perspective.

When switching away from a STE with a CD table programmed in it we should
write the new STE first, then clear any old data in the CD entry.

If we are programming a CD table for the first time to a STE then the CD
entry should be programmed before the STE is loaded.

If we are replacing a CD table entry when the STE already points at the CD
entry then we just need to do the make/break sequence.

Lift this code out of arm_smmu_detach_dev() so it can all be sequenced
properly. The only other caller is arm_smmu_release_device() and it is
going to free the cdtable anyhow, so it doesn't matter what is in it.

Reviewed-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29 ++++++++++++++-------
 1 file changed, 20 insertions(+), 9 deletions(-)

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 340f3dc82c9ce0..2a6ac0af932c54 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2575,14 +2575,6 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
 
 	master->domain = NULL;
 	master->ats_enabled = false;
-	/*
-	 * Clearing the CD entry isn't strictly required to detach the domain
-	 * since the table is uninstalled anyway, but it helps avoid confusion
-	 * in the call to arm_smmu_write_ctx_desc on the next attach (which
-	 * expects the entry to be empty).
-	 */
-	if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 && master->cd_table.cdtab)
-		arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, NULL);
 }
 
 static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
@@ -2659,6 +2651,17 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 				master->domain = NULL;
 				goto out_list_del;
 			}
+		} else {
+			/*
+			 * arm_smmu_write_ctx_desc() relies on the entry being
+			 * invalid to work, clear any existing entry.
+			 */
+			ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
+						      NULL);
+			if (ret) {
+				master->domain = NULL;
+				goto out_list_del;
+			}
 		}
 
 		ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, &smmu_domain->cd);
@@ -2668,15 +2671,23 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		}
 
 		arm_smmu_make_cdtable_ste(&target, master);
+		arm_smmu_install_ste_for_dev(master, &target);
 		break;
 	case ARM_SMMU_DOMAIN_S2:
 		arm_smmu_make_s2_domain_ste(&target, master, smmu_domain);
+		arm_smmu_install_ste_for_dev(master, &target);
+		if (master->cd_table.cdtab)
+			arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
+						      NULL);
 		break;
 	case ARM_SMMU_DOMAIN_BYPASS:
 		arm_smmu_make_bypass_ste(&target);
+		arm_smmu_install_ste_for_dev(master, &target);
+		if (master->cd_table.cdtab)
+			arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
+						      NULL);
 		break;
 	}
-	arm_smmu_install_ste_for_dev(master, &target);
 
 	arm_smmu_enable_ats(master);
 	goto out_unlock;
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:48 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:48 -0400
Subject: [PATCH v5 11/17] iommu/arm-smmu-v3: Remove arm_smmu_master->domain
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <11-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

Introducing global statics which are of type struct iommu_domain, not
struct arm_smmu_domain makes it difficult to retain
arm_smmu_master->domain, as it can no longer point to an IDENTITY or
BLOCKED domain.

The only place that uses the value is arm_smmu_detach_dev(). Change things
to work like other drivers and call iommu_get_domain_for_dev() to obtain
the current domain.

The master->domain is subtly protecting the domain_head against being
unused, change the domain_head to be INIT'd when the master is not
attached to a domain instead of garbage/zero.

Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 ++++++++-------------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  1 -
 2 files changed, 10 insertions(+), 17 deletions(-)

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 133f13f33df124..a98707cd1efccb 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2560,19 +2560,20 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
 
 static void arm_smmu_detach_dev(struct arm_smmu_master *master)
 {
+	struct iommu_domain *domain = iommu_get_domain_for_dev(master->dev);
+	struct arm_smmu_domain *smmu_domain;
 	unsigned long flags;
-	struct arm_smmu_domain *smmu_domain = master->domain;
 
-	if (!smmu_domain)
+	if (!domain)
 		return;
 
+	smmu_domain = to_smmu_domain(domain);
 	arm_smmu_disable_ats(master, smmu_domain);
 
 	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
-	list_del(&master->domain_head);
+	list_del_init(&master->domain_head);
 	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
 
-	master->domain = NULL;
 	master->ats_enabled = false;
 }
 
@@ -2626,8 +2627,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 
 	arm_smmu_detach_dev(master);
 
-	master->domain = smmu_domain;
-
 	/*
 	 * The SMMU does not support enabling ATS with bypass. When the STE is
 	 * in bypass (STE.Config[2:0] == 0b100), ATS Translation Requests and
@@ -2646,10 +2645,8 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	case ARM_SMMU_DOMAIN_S1:
 		if (!master->cd_table.cdtab) {
 			ret = arm_smmu_alloc_cd_tables(master);
-			if (ret) {
-				master->domain = NULL;
+			if (ret)
 				goto out_list_del;
-			}
 		} else {
 			/*
 			 * arm_smmu_write_ctx_desc() relies on the entry being
@@ -2657,17 +2654,13 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			 */
 			ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
 						      NULL);
-			if (ret) {
-				master->domain = NULL;
+			if (ret)
 				goto out_list_del;
-			}
 		}
 
 		ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, &smmu_domain->cd);
-		if (ret) {
-			master->domain = NULL;
+		if (ret)
 			goto out_list_del;
-		}
 
 		arm_smmu_make_cdtable_ste(&target, master);
 		arm_smmu_install_ste_for_dev(master, &target);
@@ -2693,7 +2686,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 
 out_list_del:
 	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
-	list_del(&master->domain_head);
+	list_del_init(&master->domain_head);
 	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
 
 out_unlock:
@@ -2894,6 +2887,7 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 	master->dev = dev;
 	master->smmu = smmu;
 	INIT_LIST_HEAD(&master->bonds);
+	INIT_LIST_HEAD(&master->domain_head);
 	dev_iommu_priv_set(dev, master);
 
 	ret = arm_smmu_insert_master(smmu, master);
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index cbf4b57719b7b9..587f99701ad30f 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -696,7 +696,6 @@ struct arm_smmu_stream {
 struct arm_smmu_master {
 	struct arm_smmu_device		*smmu;
 	struct device			*dev;
-	struct arm_smmu_domain		*domain;
 	struct list_head		domain_head;
 	struct arm_smmu_stream		*streams;
 	/* Locked by the iommu core using the group mutex */
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:44 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:44 -0400
Subject: [PATCH v5 07/17] iommu/arm-smmu-v3: Compute the STE only once for each master
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <7-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

Currently arm_smmu_install_ste_for_dev() iterates over every SID and
computes from scratch an identical STE. Every SID should have the same STE
contents. Turn this inside out so that the STE is supplied by the caller
and arm_smmu_install_ste_for_dev() simply installs it to every SID.

This is possible now that the STE generation does not inform what sequence
should be used to program it.

This allows splitting the STE calculation up according to the call site,
which following patches will make use of, and removes the confusing NULL
domain special case that only supported arm_smmu_detach_dev().

Reviewed-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Reviewed-by: Mostafa Saleh <smostafa at google.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 57 ++++++++-------------
 1 file changed, 22 insertions(+), 35 deletions(-)

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 1229545ae6db4e..1138e868c4d73e 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1611,35 +1611,6 @@ static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
 				      STRTAB_STE_3_S2TTB_MASK);
 }
 
-static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
-				      struct arm_smmu_ste *dst)
-{
-	struct arm_smmu_domain *smmu_domain = master->domain;
-	struct arm_smmu_ste target = {};
-
-	if (!smmu_domain) {
-		if (disable_bypass)
-			arm_smmu_make_abort_ste(&target);
-		else
-			arm_smmu_make_bypass_ste(&target);
-		arm_smmu_write_ste(master, sid, dst, &target);
-		return;
-	}
-
-	switch (smmu_domain->stage) {
-	case ARM_SMMU_DOMAIN_S1:
-		arm_smmu_make_cdtable_ste(&target, master);
-		break;
-	case ARM_SMMU_DOMAIN_S2:
-		arm_smmu_make_s2_domain_ste(&target, master, smmu_domain);
-		break;
-	case ARM_SMMU_DOMAIN_BYPASS:
-		arm_smmu_make_bypass_ste(&target);
-		break;
-	}
-	arm_smmu_write_ste(master, sid, dst, &target);
-}
-
 /*
  * This can safely directly manipulate the STE memory without a sync sequence
  * because the STE table has not been installed in the SMMU yet.
@@ -2466,7 +2437,8 @@ arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
 	}
 }
 
-static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
+static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
+					 const struct arm_smmu_ste *target)
 {
 	int i, j;
 	struct arm_smmu_device *smmu = master->smmu;
@@ -2483,7 +2455,7 @@ static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
 		if (j < i)
 			continue;
 
-		arm_smmu_write_strtab_ent(master, sid, step);
+		arm_smmu_write_ste(master, sid, step, target);
 	}
 }
 
@@ -2590,6 +2562,7 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
 static void arm_smmu_detach_dev(struct arm_smmu_master *master)
 {
 	unsigned long flags;
+	struct arm_smmu_ste target;
 	struct arm_smmu_domain *smmu_domain = master->domain;
 
 	if (!smmu_domain)
@@ -2603,7 +2576,11 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
 
 	master->domain = NULL;
 	master->ats_enabled = false;
-	arm_smmu_install_ste_for_dev(master);
+	if (disable_bypass)
+		arm_smmu_make_abort_ste(&target);
+	else
+		arm_smmu_make_bypass_ste(&target);
+	arm_smmu_install_ste_for_dev(master, &target);
 	/*
 	 * Clearing the CD entry isn't strictly required to detach the domain
 	 * since the table is uninstalled anyway, but it helps avoid confusion
@@ -2618,6 +2595,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 {
 	int ret = 0;
 	unsigned long flags;
+	struct arm_smmu_ste target;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	struct arm_smmu_device *smmu;
 	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
@@ -2679,7 +2657,8 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	list_add(&master->domain_head, &smmu_domain->devices);
 	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
 
-	if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
+	switch (smmu_domain->stage) {
+	case ARM_SMMU_DOMAIN_S1:
 		if (!master->cd_table.cdtab) {
 			ret = arm_smmu_alloc_cd_tables(master);
 			if (ret) {
@@ -2693,9 +2672,17 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			master->domain = NULL;
 			goto out_list_del;
 		}
-	}
 
-	arm_smmu_install_ste_for_dev(master);
+		arm_smmu_make_cdtable_ste(&target, master);
+		break;
+	case ARM_SMMU_DOMAIN_S2:
+		arm_smmu_make_s2_domain_ste(&target, master, smmu_domain);
+		break;
+	case ARM_SMMU_DOMAIN_BYPASS:
+		arm_smmu_make_bypass_ste(&target);
+		break;
+	}
+	arm_smmu_install_ste_for_dev(master, &target);
 
 	arm_smmu_enable_ats(master);
 	goto out_unlock;
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:53 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:53 -0400
Subject: [PATCH v5 16/17] iommu/arm-smmu-v3: Pass arm_smmu_domain and arm_smmu_device to finalize
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <16-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

Instead of putting container_of() casts in the internals, use the proper
type in this call chain. This makes it easier to check that the two global
static domains are not leaking into call chains they should not.

Passing the smmu avoids the only caller from having to set it and unset it
in the error path.

Reviewed-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 34 ++++++++++-----------
 1 file changed, 17 insertions(+), 17 deletions(-)

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 27a2792a6acd76..7116874c332ffd 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -102,6 +102,8 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
 };
 
 static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu);
+static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
+				    struct arm_smmu_device *smmu);
 
 static void parse_driver_options(struct arm_smmu_device *smmu)
 {
@@ -2295,12 +2297,12 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 	kfree(smmu_domain);
 }
 
-static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
+static int arm_smmu_domain_finalise_s1(struct arm_smmu_device *smmu,
+				       struct arm_smmu_domain *smmu_domain,
 				       struct io_pgtable_cfg *pgtbl_cfg)
 {
 	int ret;
 	u32 asid;
-	struct arm_smmu_device *smmu = smmu_domain->smmu;
 	struct arm_smmu_ctx_desc *cd = &smmu_domain->cd;
 	typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr) tcr = &pgtbl_cfg->arm_lpae_s1_cfg.tcr;
 
@@ -2332,11 +2334,11 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
 	return ret;
 }
 
-static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
+static int arm_smmu_domain_finalise_s2(struct arm_smmu_device *smmu,
+				       struct arm_smmu_domain *smmu_domain,
 				       struct io_pgtable_cfg *pgtbl_cfg)
 {
 	int vmid;
-	struct arm_smmu_device *smmu = smmu_domain->smmu;
 	struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
 
 	/* Reserve VMID 0 for stage-2 bypass STEs */
@@ -2349,17 +2351,17 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
 	return 0;
 }
 
-static int arm_smmu_domain_finalise(struct iommu_domain *domain)
+static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
+				    struct arm_smmu_device *smmu)
 {
 	int ret;
 	unsigned long ias, oas;
 	enum io_pgtable_fmt fmt;
 	struct io_pgtable_cfg pgtbl_cfg;
 	struct io_pgtable_ops *pgtbl_ops;
-	int (*finalise_stage_fn)(struct arm_smmu_domain *,
-				 struct io_pgtable_cfg *);
-	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
-	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	int (*finalise_stage_fn)(struct arm_smmu_device *smmu,
+				 struct arm_smmu_domain *smmu_domain,
+				 struct io_pgtable_cfg *pgtbl_cfg);
 
 	/* Restrict the stage to what we can actually support */
 	if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1))
@@ -2398,17 +2400,18 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
 	if (!pgtbl_ops)
 		return -ENOMEM;
 
-	domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
-	domain->geometry.aperture_end = (1UL << pgtbl_cfg.ias) - 1;
-	domain->geometry.force_aperture = true;
+	smmu_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
+	smmu_domain->domain.geometry.aperture_end = (1UL << pgtbl_cfg.ias) - 1;
+	smmu_domain->domain.geometry.force_aperture = true;
 
-	ret = finalise_stage_fn(smmu_domain, &pgtbl_cfg);
+	ret = finalise_stage_fn(smmu, smmu_domain, &pgtbl_cfg);
 	if (ret < 0) {
 		free_io_pgtable_ops(pgtbl_ops);
 		return ret;
 	}
 
 	smmu_domain->pgtbl_ops = pgtbl_ops;
+	smmu_domain->smmu = smmu;
 	return 0;
 }
 
@@ -2600,10 +2603,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	mutex_lock(&smmu_domain->init_mutex);
 
 	if (!smmu_domain->smmu) {
-		smmu_domain->smmu = smmu;
-		ret = arm_smmu_domain_finalise(domain);
-		if (ret)
-			smmu_domain->smmu = NULL;
+		ret = arm_smmu_domain_finalise(smmu_domain, smmu);
 	} else if (smmu_domain->smmu != smmu)
 		ret = -EINVAL;
 
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:52 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:52 -0400
Subject: [PATCH v5 15/17] iommu/arm-smmu-v3: Use the identity/blocked domain during release
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <15-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

Consolidate some more code by having release call
arm_smmu_attach_dev_identity/blocked() instead of open coding this.

Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

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 9271f3a035b5b8..27a2792a6acd76 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2977,19 +2977,16 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 static void arm_smmu_release_device(struct device *dev)
 {
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
-	struct arm_smmu_ste target;
 
 	if (WARN_ON(arm_smmu_master_sva_enabled(master)))
 		iopf_queue_remove_device(master->smmu->evtq.iopf, dev);
 
 	/* Put the STE back to what arm_smmu_init_strtab() sets */
 	if (disable_bypass && !dev->iommu->require_direct)
-		arm_smmu_make_abort_ste(&target);
+		arm_smmu_attach_dev_blocked(&arm_smmu_blocked_domain, dev);
 	else
-		arm_smmu_make_bypass_ste(&target);
-	arm_smmu_install_ste_for_dev(master, &target);
+		arm_smmu_attach_dev_identity(&arm_smmu_identity_domain, dev);
 
-	arm_smmu_detach_dev(master);
 	arm_smmu_disable_pasid(master);
 	arm_smmu_remove_master(master);
 	if (master->cd_table.cdtab)
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:37 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:37 -0400
Subject: [PATCH v5 00/17] Update SMMUv3 to the modern iommu API (part 1/3)
Message-ID: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

The SMMUv3 driver was originally written in 2015 when the iommu driver
facing API looked quite different. The API has evolved, especially lately,
and the driver has fallen behind.

This work aims to bring make the SMMUv3 driver the best IOMMU driver with
the most comprehensive implementation of the API. After all parts it
addresses:

 - Global static BLOCKED and IDENTITY domains with 'never fail' attach
   semantics. BLOCKED is desired for efficient VFIO.

 - Support map before attach for PAGING iommu_domains.

 - attach_dev failure does not change the HW configuration.

 - Fully hitless transitions between IDENTITY -> DMA -> IDENTITY.
   The API has IOMMU_RESV_DIRECT which is expected to be
   continuously translating.

 - Safe transitions between PAGING -> BLOCKED, do not ever temporarily
   do IDENTITY. This is required for iommufd security.

 - Full PASID API support including:
    - S1/SVA domains attached to PASIDs
    - IDENTITY/BLOCKED/S1 attached to RID
    - Change of the RID domain while PASIDs are attached

 - Streamlined SVA support using the core infrastructure

 - Hitless, whenever possible, change between two domains

 - iommufd IOMMU_GET_HW_INFO, IOMMU_HWPT_ALLOC_NEST_PARENT, and
   IOMMU_DOMAIN_NESTED support

Over all these things are going to become more accessible to iommufd, and
exposed to VMs, so it is important for the driver to have a robust
implementation of the API.

The work is split into three parts, with this part largely focusing on the
STE and building up to the BLOCKED & IDENTITY global static domains.

The second part largely focuses on the CD and builds up to having a common
PASID infrastructure that SVA and S1 domains equally use.

The third part has some random cleanups and the iommufd related parts.

Overall this takes the approach of turning the STE/CD programming upside
down where the CD/STE value is computed right at a driver callback
function and then pushed down into programming logic. The programming
logic hides the details of the required CD/STE tear-less update. This
makes the CD/STE functions independent of the arm_smmu_domain which makes
it fairly straightforward to untangle all the different call chains, and
add news ones.

Further, this frees the arm_smmu_domain related logic from keeping track
of what state the STE/CD is currently in so it can carefully sequence the
correct update. There are many new update pairs that are subtly introduced
as the work progresses.

The locking to support BTM via arm_smmu_asid_lock is a bit subtle right
now and patches throughout this work adjust and tighten this so that it is
clearer and doesn't get broken.

Once the lower STE layers no longer need to touch arm_smmu_domain we can
isolate struct arm_smmu_domain to be only used for PAGING domains, audit
all the to_smmu_domain() calls to be only in PAGING domain ops, and
introduce the normal global static BLOCKED/IDENTITY domains using the new
STE infrastructure. Part 2 will ultimately migrate SVA over to use
arm_smmu_domain as well.

All parts are on github:

 https://github.com/jgunthorpe/linux/commits/smmuv3_newapi

v5:
 - Rebase on v6.8-rc3
 - Remove the writer argument to arm_smmu_entry_writer_ops get_used()
 - Swap order of hweight tests so one call to hweight8() can be removed
 - Add STRTAB_STE_2_S2VMID used for STRTAB_STE_0_CFG_S1_TRANS, for
   S2 bypass the VMID is used but 0
 - Be more exact when generating STEs and store 0's to document the HW
   is using that value and 0 is actually a deliberate choice for VMID and
   SHCFG.
 - Remove cd_table argument to arm_smmu_make_cdtable_ste()
 - Put arm_smmu_rmr_install_bypass_ste() after setting up a 2 level table
 - Pull patch "Check that the RID domain is S1 in SVA" from part 2 to
   guard against memory corruption on failure paths
 - Tighten the used logic for SHCFG to accommodate nesting patches in
   part 3
 - Additional comments and commit message adjustments
v4: https://lore.kernel.org/r/0-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg at nvidia.com
 - Rebase on v6.8-rc1. Patches 1-3 merged
 - Replace patch "Make STE programming independent of the callers" with
   Michael's version
    * Describe the core API desire for hitless updates
    * Replace the iterator with STE/CD specific function pointers.
      This lets the logic be written top down instead of rolled into an
      iterator
    * Optimize away a sync when the critical qword is the only qword
      to update
 - Pass master not smmu to arm_smmu_write_ste() throughout
 - arm_smmu_make_s2_domain_ste() should use data[1] = not |= since
   it is known to be zero
 - Return errno's from domain_alloc() paths
v3: https://lore.kernel.org/r/0-v3-d794f8d934da+411a-smmuv3_newapi_p1_jgg at nvidia.com
 - Use some local variables in arm_smmu_get_step_for_sid() for clarity
 - White space and spelling changes
 - Commit message updates
 - Keep master->domain_head initialized to avoid a list_del corruption
v2: https://lore.kernel.org/r/0-v2-de8b10590bf5+400-smmuv3_newapi_p1_jgg at nvidia.com
 - Rebased on v6.7-rc1
 - Improve the comment for arm_smmu_write_entry_step()
 - Fix the botched memcmp
 - Document the spec justification for the SHCFG exclusion in used
 - Include STRTAB_STE_1_SHCFG for STRTAB_STE_0_CFG_S2_TRANS in used
 - WARN_ON for unknown STEs in used
 - Fix error unwind in arm_smmu_attach_dev()
 - Whitespace, spelling, and checkpatch related items
v1: https://lore.kernel.org/r/0-v1-e289ca9121be+2be-smmuv3_newapi_p1_jgg at nvidia.com

Jason Gunthorpe (17):
  iommu/arm-smmu-v3: Make STE programming independent of the callers
  iommu/arm-smmu-v3: Consolidate the STE generation for abort/bypass
  iommu/arm-smmu-v3: Move arm_smmu_rmr_install_bypass_ste()
  iommu/arm-smmu-v3: Move the STE generation for S1 and S2 domains into
    functions
  iommu/arm-smmu-v3: Build the whole STE in
    arm_smmu_make_s2_domain_ste()
  iommu/arm-smmu-v3: Hold arm_smmu_asid_lock during all of attach_dev
  iommu/arm-smmu-v3: Compute the STE only once for each master
  iommu/arm-smmu-v3: Do not change the STE twice during
    arm_smmu_attach_dev()
  iommu/arm-smmu-v3: Put writing the context descriptor in the right
    order
  iommu/arm-smmu-v3: Pass smmu_domain to arm_enable/disable_ats()
  iommu/arm-smmu-v3: Remove arm_smmu_master->domain
  iommu/arm-smmu-v3: Check that the RID domain is S1 in SVA
  iommu/arm-smmu-v3: Add a global static IDENTITY domain
  iommu/arm-smmu-v3: Add a global static BLOCKED domain
  iommu/arm-smmu-v3: Use the identity/blocked domain during release
  iommu/arm-smmu-v3: Pass arm_smmu_domain and arm_smmu_device to
    finalize
  iommu/arm-smmu-v3: Convert to domain_alloc_paging()

 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c   |   8 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 778 ++++++++++++------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |   5 +-
 3 files changed, 549 insertions(+), 242 deletions(-)

The diff against v4 is small:

--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -57,8 +57,7 @@ struct arm_smmu_entry_writer {
 struct arm_smmu_entry_writer_ops {
 	unsigned int num_entry_qwords;
 	__le64 v_bit;
-	void (*get_used)(struct arm_smmu_entry_writer *writer, const __le64 *entry,
-			 __le64 *used);
+	void (*get_used)(const __le64 *entry, __le64 *used);
 	void (*sync)(struct arm_smmu_entry_writer *writer);
 };
 
@@ -1006,8 +1005,8 @@ static u8 arm_smmu_entry_qword_diff(struct arm_smmu_entry_writer *writer,
 	u8 used_qword_diff = 0;
 	unsigned int i;
 
-	writer->ops->get_used(writer, entry, cur_used);
-	writer->ops->get_used(writer, target, target_used);
+	writer->ops->get_used(entry, cur_used);
+	writer->ops->get_used(target, target_used);
 
 	for (i = 0; i != writer->ops->num_entry_qwords; i++) {
 		/*
@@ -1084,17 +1083,7 @@ static void arm_smmu_write_entry(struct arm_smmu_entry_writer *writer,
 
 	used_qword_diff =
 		arm_smmu_entry_qword_diff(writer, entry, target, unused_update);
-	if (hweight8(used_qword_diff) > 1) {
-		/*
-		 * At least two qwords need their inuse bits to be changed. This
-		 * requires a breaking update, zero the V bit, write all qwords
-		 * but 0, then set qword 0
-		 */
-		unused_update[0] = entry[0] & (~writer->ops->v_bit);
-		entry_set(writer, entry, unused_update, 0, 1);
-		entry_set(writer, entry, target, 1, num_entry_qwords - 1);
-		entry_set(writer, entry, target, 0, 1);
-	} else if (hweight8(used_qword_diff) == 1) {
+	if (hweight8(used_qword_diff) == 1) {
 		/*
 		 * Only one qword needs its used bits to be changed. This is a
 		 * hitless update, update all bits the current STE is ignoring
@@ -1114,6 +1103,16 @@ static void arm_smmu_write_entry(struct arm_smmu_entry_writer *writer,
 		entry_set(writer, entry, unused_update, 0, num_entry_qwords);
 		entry_set(writer, entry, target, critical_qword_index, 1);
 		entry_set(writer, entry, target, 0, num_entry_qwords);
+	} else if (used_qword_diff) {
+		/*
+		 * At least two qwords need their inuse bits to be changed. This
+		 * requires a breaking update, zero the V bit, write all qwords
+		 * but 0, then set qword 0
+		 */
+		unused_update[0] = entry[0] & (~writer->ops->v_bit);
+		entry_set(writer, entry, unused_update, 0, 1);
+		entry_set(writer, entry, target, 1, num_entry_qwords - 1);
+		entry_set(writer, entry, target, 0, 1);
 	} else {
 		/*
 		 * No inuse bit changed. Sanity check that all unused bits are 0
@@ -1402,28 +1401,30 @@ struct arm_smmu_ste_writer {
  * would be nice if this was complete according to the spec, but minimally it
  * has to capture the bits this driver uses.
  */
-static void arm_smmu_get_ste_used(struct arm_smmu_entry_writer *writer,
-				  const __le64 *ent, __le64 *used_bits)
+static void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
 {
+	unsigned int cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ent[0]));
+
 	used_bits[0] = cpu_to_le64(STRTAB_STE_0_V);
 	if (!(ent[0] & cpu_to_le64(STRTAB_STE_0_V)))
 		return;
 
 	/*
-	 * If S1 is enabled S1DSS is valid, see 13.5 Summary of
-	 * attribute/permission configuration fields for the SHCFG behavior.
+	 * See 13.5 Summary of attribute/permission configuration fields for the
+	 * SHCFG behavior. It is only used for BYPASS, including S1DSS BYPASS,
+	 * and S2 only.
 	 */
-	if (FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ent[0])) & 1 &&
-	    FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
-		    STRTAB_STE_1_S1DSS_BYPASS)
+	if (cfg == STRTAB_STE_0_CFG_BYPASS ||
+	    cfg == STRTAB_STE_0_CFG_S2_TRANS ||
+	    (cfg == STRTAB_STE_0_CFG_S1_TRANS &&
+	     FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
+		     STRTAB_STE_1_S1DSS_BYPASS))
 		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_SHCFG);
 
 	used_bits[0] |= cpu_to_le64(STRTAB_STE_0_CFG);
-	switch (FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ent[0]))) {
+	switch (cfg) {
 	case STRTAB_STE_0_CFG_ABORT:
-		break;
 	case STRTAB_STE_0_CFG_BYPASS:
-		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_SHCFG);
 		break;
 	case STRTAB_STE_0_CFG_S1_TRANS:
 		used_bits[0] |= cpu_to_le64(STRTAB_STE_0_S1FMT |
@@ -1434,10 +1435,11 @@ static void arm_smmu_get_ste_used(struct arm_smmu_entry_writer *writer,
 				    STRTAB_STE_1_S1COR | STRTAB_STE_1_S1CSH |
 				    STRTAB_STE_1_S1STALLD | STRTAB_STE_1_STRW);
 		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_EATS);
+		used_bits[2] |= cpu_to_le64(STRTAB_STE_2_S2VMID);
 		break;
 	case STRTAB_STE_0_CFG_S2_TRANS:
 		used_bits[1] |=
-			cpu_to_le64(STRTAB_STE_1_EATS | STRTAB_STE_1_SHCFG);
+			cpu_to_le64(STRTAB_STE_1_EATS);
 		used_bits[2] |=
 			cpu_to_le64(STRTAB_STE_2_S2VMID | STRTAB_STE_2_VTCR |
 				    STRTAB_STE_2_S2AA64 | STRTAB_STE_2_S2ENDI |
@@ -1519,9 +1521,9 @@ static void arm_smmu_make_bypass_ste(struct arm_smmu_ste *target)
 }
 
 static void arm_smmu_make_cdtable_ste(struct arm_smmu_ste *target,
-				      struct arm_smmu_master *master,
-				      struct arm_smmu_ctx_desc_cfg *cd_table)
+				      struct arm_smmu_master *master)
 {
+	struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
 	struct arm_smmu_device *smmu = master->smmu;
 
 	memset(target, 0, sizeof(*target));
@@ -1542,11 +1544,30 @@ static void arm_smmu_make_cdtable_ste(struct arm_smmu_ste *target,
 			 STRTAB_STE_1_S1STALLD :
 			 0) |
 		FIELD_PREP(STRTAB_STE_1_EATS,
-			   master->ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0) |
-		FIELD_PREP(STRTAB_STE_1_STRW,
-			   (smmu->features & ARM_SMMU_FEAT_E2H) ?
-				   STRTAB_STE_1_STRW_EL2 :
-				   STRTAB_STE_1_STRW_NSEL1));
+			   master->ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0));
+
+	if (smmu->features & ARM_SMMU_FEAT_E2H) {
+		/*
+		 * To support BTM the streamworld needs to match the
+		 * configuration of the CPU so that the ASID broadcasts are
+		 * properly matched. This means either S/NS-EL2-E2H (hypervisor)
+		 * or NS-EL1 (guest). Since an SVA domain can be installed in a
+		 * PASID this should always use a BTM compatible configuration
+		 * if the HW supports it.
+		 */
+		target->data[1] |= cpu_to_le64(
+			FIELD_PREP(STRTAB_STE_1_STRW, STRTAB_STE_1_STRW_EL2));
+	} else {
+		target->data[1] |= cpu_to_le64(
+			FIELD_PREP(STRTAB_STE_1_STRW, STRTAB_STE_1_STRW_NSEL1));
+
+		/*
+		 * VMID 0 is reserved for stage-2 bypass EL1 STEs, see
+		 * arm_smmu_domain_alloc_id()
+		 */
+		target->data[2] =
+			cpu_to_le64(FIELD_PREP(STRTAB_STE_2_S2VMID, 0));
+	}
 }
 
 static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
@@ -1567,7 +1588,9 @@ static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
 
 	target->data[1] = cpu_to_le64(
 		FIELD_PREP(STRTAB_STE_1_EATS,
-			   master->ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0));
+			   master->ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0) |
+		FIELD_PREP(STRTAB_STE_1_SHCFG,
+			   STRTAB_STE_1_SHCFG_NON_SHARABLE));
 
 	vtcr_val = FIELD_PREP(STRTAB_STE_2_VTCR_S2T0SZ, vtcr->tsz) |
 		   FIELD_PREP(STRTAB_STE_2_VTCR_S2SL0, vtcr->sl) |
@@ -1590,6 +1613,10 @@ static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
 				      STRTAB_STE_3_S2TTB_MASK);
 }
 
+/*
+ * This can safely directly manipulate the STE memory without a sync sequence
+ * because the STE table has not been installed in the SMMU yet.
+ */
 static void arm_smmu_init_bypass_stes(struct arm_smmu_ste *strtab,
 				      unsigned int nent)
 {
@@ -2632,7 +2659,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		if (ret)
 			goto out_list_del;
 
-		arm_smmu_make_cdtable_ste(&target, master, &master->cd_table);
+		arm_smmu_make_cdtable_ste(&target, master);
 		arm_smmu_install_ste_for_dev(master, &target);
 		break;
 	case ARM_SMMU_DOMAIN_S2:
@@ -3325,8 +3352,6 @@ static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
 
 	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents);
 
-	/* Check for RMRs and install bypass STEs if any */
-	arm_smmu_rmr_install_bypass_ste(smmu);
 	return 0;
 }
 
@@ -3350,6 +3375,8 @@ static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
 
 	ida_init(&smmu->vmid_map);
 
+	/* Check for RMRs and install bypass STEs if any */
+	arm_smmu_rmr_install_bypass_ste(smmu);
 	return 0;
 }
 
@@ -4049,6 +4076,10 @@ static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
 				continue;
 			}
 
+			/*
+			 * STE table is not programmed to HW, see
+			 * arm_smmu_init_bypass_stes()
+			 */
 			arm_smmu_make_bypass_ste(
 				arm_smmu_get_step_for_sid(smmu, rmr->sids[i]));
 		}
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 23baf117e7e4b5..23d8ab9a937aa6 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -249,6 +249,7 @@ struct arm_smmu_ste {
 #define STRTAB_STE_1_STRW_EL2		2UL
 
 #define STRTAB_STE_1_SHCFG		GENMASK_ULL(45, 44)
+#define STRTAB_STE_1_SHCFG_NON_SHARABLE	0UL
 #define STRTAB_STE_1_SHCFG_INCOMING	1UL
 
 #define STRTAB_STE_2_S2VMID		GENMASK_ULL(15, 0)


base-commit: 54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:43 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:43 -0400
Subject: [PATCH v5 06/17] iommu/arm-smmu-v3: Hold arm_smmu_asid_lock during all of attach_dev
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <6-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

The BTM support wants to be able to change the ASID of any smmu_domain.
When it goes to do this it holds the arm_smmu_asid_lock and iterates over
the target domain's devices list.

During attach of a S1 domain we must ensure that the devices list and
CD are in sync, otherwise we could miss CD updates or a parallel CD update
could push an out of date CD.

This is pretty complicated, and almost works today because
arm_smmu_detach_dev() removes the master from the linked list before
working on the CD entries, preventing parallel update of the CD.

However, it does have an issue where the CD can remain programed while the
domain appears to be unattached. arm_smmu_share_asid() will then not clear
any CD entriess and install its own CD entry with the same ASID
concurrently. This creates a small race window where the IOMMU can see two
ASIDs pointing to different translations.

Solve this by wrapping most of the attach flow in the
arm_smmu_asid_lock. This locks more than strictly needed to prepare for
the next patch which will reorganize the order of the linked list, STE and
CD changes.

Move arm_smmu_detach_dev() till after we have initialized the domain so
the lock can be held for less time.

Reviewed-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 22 ++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

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 417b2c877ff311..1229545ae6db4e 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2639,8 +2639,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		return -EBUSY;
 	}
 
-	arm_smmu_detach_dev(master);
-
 	mutex_lock(&smmu_domain->init_mutex);
 
 	if (!smmu_domain->smmu) {
@@ -2655,6 +2653,16 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	if (ret)
 		return ret;
 
+	/*
+	 * Prevent arm_smmu_share_asid() from trying to change the ASID
+	 * of either the old or new domain while we are working on it.
+	 * This allows the STE and the smmu_domain->devices list to
+	 * be inconsistent during this routine.
+	 */
+	mutex_lock(&arm_smmu_asid_lock);
+
+	arm_smmu_detach_dev(master);
+
 	master->domain = smmu_domain;
 
 	/*
@@ -2680,13 +2688,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			}
 		}
 
-		/*
-		 * Prevent SVA from concurrently modifying the CD or writing to
-		 * the CD entry
-		 */
-		mutex_lock(&arm_smmu_asid_lock);
 		ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, &smmu_domain->cd);
-		mutex_unlock(&arm_smmu_asid_lock);
 		if (ret) {
 			master->domain = NULL;
 			goto out_list_del;
@@ -2696,13 +2698,15 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	arm_smmu_install_ste_for_dev(master);
 
 	arm_smmu_enable_ats(master);
-	return 0;
+	goto out_unlock;
 
 out_list_del:
 	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
 	list_del(&master->domain_head);
 	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
 
+out_unlock:
+	mutex_unlock(&arm_smmu_asid_lock);
 	return ret;
 }
 
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:50 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:50 -0400
Subject: [PATCH v5 13/17] iommu/arm-smmu-v3: Add a global static IDENTITY domain
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <13-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

Move to the new static global for identity domains. Move all the logic out
of arm_smmu_attach_dev into an identity only function.

Reviewed-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 82 +++++++++++++++------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  1 -
 2 files changed, 58 insertions(+), 25 deletions(-)

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 a98707cd1efccb..a940b5ff96843c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2253,8 +2253,7 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 		return arm_smmu_sva_domain_alloc();
 
 	if (type != IOMMU_DOMAIN_UNMANAGED &&
-	    type != IOMMU_DOMAIN_DMA &&
-	    type != IOMMU_DOMAIN_IDENTITY)
+	    type != IOMMU_DOMAIN_DMA)
 		return NULL;
 
 	/*
@@ -2362,11 +2361,6 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
 	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
 
-	if (domain->type == IOMMU_DOMAIN_IDENTITY) {
-		smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
-		return 0;
-	}
-
 	/* Restrict the stage to what we can actually support */
 	if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1))
 		smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
@@ -2564,7 +2558,7 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
 	struct arm_smmu_domain *smmu_domain;
 	unsigned long flags;
 
-	if (!domain)
+	if (!domain || !(domain->type & __IOMMU_DOMAIN_PAGING))
 		return;
 
 	smmu_domain = to_smmu_domain(domain);
@@ -2627,15 +2621,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 
 	arm_smmu_detach_dev(master);
 
-	/*
-	 * The SMMU does not support enabling ATS with bypass. When the STE is
-	 * in bypass (STE.Config[2:0] == 0b100), ATS Translation Requests and
-	 * Translated transactions are denied as though ATS is disabled for the
-	 * stream (STE.EATS == 0b00), causing F_BAD_ATS_TREQ and
-	 * F_TRANSL_FORBIDDEN events (IHI0070Ea 5.2 Stream Table Entry).
-	 */
-	if (smmu_domain->stage != ARM_SMMU_DOMAIN_BYPASS)
-		master->ats_enabled = arm_smmu_ats_supported(master);
+	master->ats_enabled = arm_smmu_ats_supported(master);
 
 	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
 	list_add(&master->domain_head, &smmu_domain->devices);
@@ -2672,13 +2658,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 			arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
 						      NULL);
 		break;
-	case ARM_SMMU_DOMAIN_BYPASS:
-		arm_smmu_make_bypass_ste(&target);
-		arm_smmu_install_ste_for_dev(master, &target);
-		if (master->cd_table.cdtab)
-			arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
-						      NULL);
-		break;
 	}
 
 	arm_smmu_enable_ats(master, smmu_domain);
@@ -2694,6 +2673,60 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	return ret;
 }
 
+static int arm_smmu_attach_dev_ste(struct device *dev,
+				   struct arm_smmu_ste *ste)
+{
+	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+
+	if (arm_smmu_master_sva_enabled(master))
+		return -EBUSY;
+
+	/*
+	 * Do not allow any ASID to be changed while are working on the STE,
+	 * otherwise we could miss invalidations.
+	 */
+	mutex_lock(&arm_smmu_asid_lock);
+
+	/*
+	 * The SMMU does not support enabling ATS with bypass/abort. When the
+	 * STE is in bypass (STE.Config[2:0] == 0b100), ATS Translation Requests
+	 * and Translated transactions are denied as though ATS is disabled for
+	 * the stream (STE.EATS == 0b00), causing F_BAD_ATS_TREQ and
+	 * F_TRANSL_FORBIDDEN events (IHI0070Ea 5.2 Stream Table Entry).
+	 */
+	arm_smmu_detach_dev(master);
+
+	arm_smmu_install_ste_for_dev(master, ste);
+	mutex_unlock(&arm_smmu_asid_lock);
+
+	/*
+	 * This has to be done after removing the master from the
+	 * arm_smmu_domain->devices to avoid races updating the same context
+	 * descriptor from arm_smmu_share_asid().
+	 */
+	if (master->cd_table.cdtab)
+		arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, NULL);
+	return 0;
+}
+
+static int arm_smmu_attach_dev_identity(struct iommu_domain *domain,
+					struct device *dev)
+{
+	struct arm_smmu_ste ste;
+
+	arm_smmu_make_bypass_ste(&ste);
+	return arm_smmu_attach_dev_ste(dev, &ste);
+}
+
+static const struct iommu_domain_ops arm_smmu_identity_ops = {
+	.attach_dev = arm_smmu_attach_dev_identity,
+};
+
+static struct iommu_domain arm_smmu_identity_domain = {
+	.type = IOMMU_DOMAIN_IDENTITY,
+	.ops = &arm_smmu_identity_ops,
+};
+
 static int arm_smmu_map_pages(struct iommu_domain *domain, unsigned long iova,
 			      phys_addr_t paddr, size_t pgsize, size_t pgcount,
 			      int prot, gfp_t gfp, size_t *mapped)
@@ -3083,6 +3116,7 @@ static void arm_smmu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
 }
 
 static struct iommu_ops arm_smmu_ops = {
+	.identity_domain	= &arm_smmu_identity_domain,
 	.capable		= arm_smmu_capable,
 	.domain_alloc		= arm_smmu_domain_alloc,
 	.probe_device		= arm_smmu_probe_device,
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 587f99701ad30f..23d8ab9a937aa6 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -713,7 +713,6 @@ struct arm_smmu_master {
 enum arm_smmu_domain_stage {
 	ARM_SMMU_DOMAIN_S1 = 0,
 	ARM_SMMU_DOMAIN_S2,
-	ARM_SMMU_DOMAIN_BYPASS,
 };
 
 struct arm_smmu_domain {
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:54 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:54 -0400
Subject: [PATCH v5 17/17] iommu/arm-smmu-v3: Convert to domain_alloc_paging()
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <17-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

Now that the BLOCKED and IDENTITY behaviors are managed with their own
domains change to the domain_alloc_paging() op.

For now SVA remains using the old interface, eventually it will get its
own op that can pass in the device and mm_struct which will let us have a
sane lifetime for the mmu_notifier.

Call arm_smmu_domain_finalise() early if dev is available.

Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 22 ++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

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 7116874c332ffd..ab2f5ac4020d71 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2249,14 +2249,15 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 {
-	struct arm_smmu_domain *smmu_domain;
 
 	if (type == IOMMU_DOMAIN_SVA)
 		return arm_smmu_sva_domain_alloc();
+	return ERR_PTR(-EOPNOTSUPP);
+}
 
-	if (type != IOMMU_DOMAIN_UNMANAGED &&
-	    type != IOMMU_DOMAIN_DMA)
-		return NULL;
+static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
+{
+	struct arm_smmu_domain *smmu_domain;
 
 	/*
 	 * Allocate the domain and initialise some of its data structures.
@@ -2265,13 +2266,23 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 	 */
 	smmu_domain = kzalloc(sizeof(*smmu_domain), GFP_KERNEL);
 	if (!smmu_domain)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	mutex_init(&smmu_domain->init_mutex);
 	INIT_LIST_HEAD(&smmu_domain->devices);
 	spin_lock_init(&smmu_domain->devices_lock);
 	INIT_LIST_HEAD(&smmu_domain->mmu_notifiers);
 
+	if (dev) {
+		struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+		int ret;
+
+		ret = arm_smmu_domain_finalise(smmu_domain, master->smmu);
+		if (ret) {
+			kfree(smmu_domain);
+			return ERR_PTR(ret);
+		}
+	}
 	return &smmu_domain->domain;
 }
 
@@ -3135,6 +3146,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.blocked_domain		= &arm_smmu_blocked_domain,
 	.capable		= arm_smmu_capable,
 	.domain_alloc		= arm_smmu_domain_alloc,
+	.domain_alloc_paging    = arm_smmu_domain_alloc_paging,
 	.probe_device		= arm_smmu_probe_device,
 	.release_device		= arm_smmu_release_device,
 	.device_group		= arm_smmu_device_group,
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:41 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:41 -0400
Subject: [PATCH v5 04/17] iommu/arm-smmu-v3: Move the STE generation for S1 and S2 domains into functions
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <4-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

This is preparation to move the STE calculation higher up in to the call
chain and remove arm_smmu_write_strtab_ent(). These new functions will be
called directly from attach_dev.

Reviewed-by: Moritz Fischer <mdf at kernel.org>
Reviewed-by: Michael Shavit <mshavit at google.com>
Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
Reviewed-by: Mostafa Saleh <smostafa at google.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 136 ++++++++++++--------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |   1 +
 2 files changed, 84 insertions(+), 53 deletions(-)

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 2ab36dcf7c61f5..893df3e76400ec 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1518,13 +1518,89 @@ static void arm_smmu_make_bypass_ste(struct arm_smmu_ste *target)
 		FIELD_PREP(STRTAB_STE_1_SHCFG, STRTAB_STE_1_SHCFG_INCOMING));
 }
 
+static void arm_smmu_make_cdtable_ste(struct arm_smmu_ste *target,
+				      struct arm_smmu_master *master)
+{
+	struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
+	struct arm_smmu_device *smmu = master->smmu;
+
+	memset(target, 0, sizeof(*target));
+	target->data[0] = cpu_to_le64(
+		STRTAB_STE_0_V |
+		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS) |
+		FIELD_PREP(STRTAB_STE_0_S1FMT, cd_table->s1fmt) |
+		(cd_table->cdtab_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
+		FIELD_PREP(STRTAB_STE_0_S1CDMAX, cd_table->s1cdmax));
+
+	target->data[1] = cpu_to_le64(
+		FIELD_PREP(STRTAB_STE_1_S1DSS, STRTAB_STE_1_S1DSS_SSID0) |
+		FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) |
+		FIELD_PREP(STRTAB_STE_1_S1COR, STRTAB_STE_1_S1C_CACHE_WBRA) |
+		FIELD_PREP(STRTAB_STE_1_S1CSH, ARM_SMMU_SH_ISH) |
+		((smmu->features & ARM_SMMU_FEAT_STALLS &&
+		  !master->stall_enabled) ?
+			 STRTAB_STE_1_S1STALLD :
+			 0) |
+		FIELD_PREP(STRTAB_STE_1_EATS,
+			   master->ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0));
+
+	if (smmu->features & ARM_SMMU_FEAT_E2H) {
+		/*
+		 * To support BTM the streamworld needs to match the
+		 * configuration of the CPU so that the ASID broadcasts are
+		 * properly matched. This means either S/NS-EL2-E2H (hypervisor)
+		 * or NS-EL1 (guest). Since an SVA domain can be installed in a
+		 * PASID this should always use a BTM compatible configuration
+		 * if the HW supports it.
+		 */
+		target->data[1] |= cpu_to_le64(
+			FIELD_PREP(STRTAB_STE_1_STRW, STRTAB_STE_1_STRW_EL2));
+	} else {
+		target->data[1] |= cpu_to_le64(
+			FIELD_PREP(STRTAB_STE_1_STRW, STRTAB_STE_1_STRW_NSEL1));
+
+		/*
+		 * VMID 0 is reserved for stage-2 bypass EL1 STEs, see
+		 * arm_smmu_domain_alloc_id()
+		 */
+		target->data[2] =
+			cpu_to_le64(FIELD_PREP(STRTAB_STE_2_S2VMID, 0));
+	}
+}
+
+static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
+					struct arm_smmu_master *master,
+					struct arm_smmu_domain *smmu_domain)
+{
+	struct arm_smmu_s2_cfg *s2_cfg = &smmu_domain->s2_cfg;
+
+	memset(target, 0, sizeof(*target));
+	target->data[0] = cpu_to_le64(
+		STRTAB_STE_0_V |
+		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS));
+
+	target->data[1] = cpu_to_le64(
+		FIELD_PREP(STRTAB_STE_1_EATS,
+			   master->ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0) |
+		FIELD_PREP(STRTAB_STE_1_SHCFG,
+			   STRTAB_STE_1_SHCFG_NON_SHARABLE));
+
+	target->data[2] = cpu_to_le64(
+		FIELD_PREP(STRTAB_STE_2_S2VMID, s2_cfg->vmid) |
+		FIELD_PREP(STRTAB_STE_2_VTCR, s2_cfg->vtcr) |
+		STRTAB_STE_2_S2AA64 |
+#ifdef __BIG_ENDIAN
+		STRTAB_STE_2_S2ENDI |
+#endif
+		STRTAB_STE_2_S2PTW |
+		STRTAB_STE_2_S2R);
+
+	target->data[3] = cpu_to_le64(s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK);
+}
+
 static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 				      struct arm_smmu_ste *dst)
 {
-	u64 val;
-	struct arm_smmu_device *smmu = master->smmu;
-	struct arm_smmu_ctx_desc_cfg *cd_table = NULL;
-	struct arm_smmu_s2_cfg *s2_cfg = NULL;
 	struct arm_smmu_domain *smmu_domain = master->domain;
 	struct arm_smmu_ste target = {};
 
@@ -1539,61 +1615,15 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 
 	switch (smmu_domain->stage) {
 	case ARM_SMMU_DOMAIN_S1:
-		cd_table = &master->cd_table;
+		arm_smmu_make_cdtable_ste(&target, master);
 		break;
 	case ARM_SMMU_DOMAIN_S2:
-		s2_cfg = &smmu_domain->s2_cfg;
+		arm_smmu_make_s2_domain_ste(&target, master, smmu_domain);
 		break;
 	case ARM_SMMU_DOMAIN_BYPASS:
 		arm_smmu_make_bypass_ste(&target);
-		arm_smmu_write_ste(master, sid, dst, &target);
-		return;
+		break;
 	}
-
-	/* Nuke the existing STE_0 value, as we're going to rewrite it */
-	val = STRTAB_STE_0_V;
-
-	if (cd_table) {
-		u64 strw = smmu->features & ARM_SMMU_FEAT_E2H ?
-			STRTAB_STE_1_STRW_EL2 : STRTAB_STE_1_STRW_NSEL1;
-
-		target.data[1] = cpu_to_le64(
-			 FIELD_PREP(STRTAB_STE_1_S1DSS, STRTAB_STE_1_S1DSS_SSID0) |
-			 FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) |
-			 FIELD_PREP(STRTAB_STE_1_S1COR, STRTAB_STE_1_S1C_CACHE_WBRA) |
-			 FIELD_PREP(STRTAB_STE_1_S1CSH, ARM_SMMU_SH_ISH) |
-			 FIELD_PREP(STRTAB_STE_1_STRW, strw));
-
-		if (smmu->features & ARM_SMMU_FEAT_STALLS &&
-		    !master->stall_enabled)
-			target.data[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
-
-		val |= (cd_table->cdtab_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
-			FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS) |
-			FIELD_PREP(STRTAB_STE_0_S1CDMAX, cd_table->s1cdmax) |
-			FIELD_PREP(STRTAB_STE_0_S1FMT, cd_table->s1fmt);
-	}
-
-	if (s2_cfg) {
-		target.data[2] = cpu_to_le64(
-			 FIELD_PREP(STRTAB_STE_2_S2VMID, s2_cfg->vmid) |
-			 FIELD_PREP(STRTAB_STE_2_VTCR, s2_cfg->vtcr) |
-#ifdef __BIG_ENDIAN
-			 STRTAB_STE_2_S2ENDI |
-#endif
-			 STRTAB_STE_2_S2PTW | STRTAB_STE_2_S2AA64 |
-			 STRTAB_STE_2_S2R);
-
-		target.data[3] = cpu_to_le64(s2_cfg->vttbr & STRTAB_STE_3_S2TTB_MASK);
-
-		val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS);
-	}
-
-	if (master->ats_enabled)
-		target.data[1] |= cpu_to_le64(FIELD_PREP(STRTAB_STE_1_EATS,
-						 STRTAB_STE_1_EATS_TRANS));
-
-	target.data[0] = cpu_to_le64(val);
 	arm_smmu_write_ste(master, sid, dst, &target);
 }
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 65fb388d51734d..53695dbc9b33f3 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -249,6 +249,7 @@ struct arm_smmu_ste {
 #define STRTAB_STE_1_STRW_EL2		2UL
 
 #define STRTAB_STE_1_SHCFG		GENMASK_ULL(45, 44)
+#define STRTAB_STE_1_SHCFG_NON_SHARABLE	0UL
 #define STRTAB_STE_1_SHCFG_INCOMING	1UL
 
 #define STRTAB_STE_2_S2VMID		GENMASK_ULL(15, 0)
-- 
2.43.0



From jgg at nvidia.com  Tue Feb  6 07:12:40 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue,  6 Feb 2024 11:12:40 -0400
Subject: [PATCH v5 03/17] iommu/arm-smmu-v3: Move arm_smmu_rmr_install_bypass_ste()
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <3-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>

Logically arm_smmu_init_strtab() is the function that allocates and
populates the stream table with the initial value of the STEs. After this
function returns the stream table should be fully ready.

arm_smmu_rmr_install_bypass_ste() adjusts the initial stream table to force
any SIDs that the FW says have IOMMU_RESV_DIRECT to use bypass. This
ensures there is no disruption to the identity mapping during boot.

Put arm_smmu_rmr_install_bypass_ste() into arm_smmu_init_strtab(), it
already executes immediately after arm_smmu_init_strtab().

No functional change intended.

Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Tested-by: Nicolin Chen <nicolinc at nvidia.com>
Tested-by: Moritz Fischer <moritzf at google.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

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 6123e5ad95822c..2ab36dcf7c61f5 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -101,6 +101,8 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
 	{ 0, NULL},
 };
 
+static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu);
+
 static void parse_driver_options(struct arm_smmu_device *smmu)
 {
 	int i = 0;
@@ -3256,6 +3258,7 @@ static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
 	cfg->strtab_base_cfg = reg;
 
 	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents);
+
 	return 0;
 }
 
@@ -3279,6 +3282,8 @@ static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
 
 	ida_init(&smmu->vmid_map);
 
+	/* Check for RMRs and install bypass STEs if any */
+	arm_smmu_rmr_install_bypass_ste(smmu);
 	return 0;
 }
 
@@ -4073,9 +4078,6 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	/* Record our private device structure */
 	platform_set_drvdata(pdev, smmu);
 
-	/* Check for RMRs and install bypass STEs if any */
-	arm_smmu_rmr_install_bypass_ste(smmu);
-
 	/* Reset the device */
 	ret = arm_smmu_device_reset(smmu, bypass);
 	if (ret)
-- 
2.43.0



From amergnat at baylibre.com  Tue Feb  6 07:13:39 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Tue, 6 Feb 2024 16:13:39 +0100
Subject: [PATCH v4 6/9] drm/mediatek: dsi: Register DSI host after
 acquiring clocks and PHY
In-Reply-To: <20240206120748.136610-7-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-7-angelogioacchino.delregno@collabora.com>
Message-ID: <2d97df42-1d23-456e-9f0f-36b8aef08670@baylibre.com>


On 06/02/2024 13:07, AngeloGioacchino Del Regno wrote:
> Registering the dsi host with its ops before getting dsi->regs is
> simply wrong: even though there's nothing (for now) asynchronously
> calling those ops before the end of the probe function, installing
> ops that are using iospace(s) and clocks before even initializing
> those is too fragile.
> 
> Register the DSI host after getting clocks, iospace and PHY.
> This wil also allow to simplify the error paths in a later commit.
wil => will

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>

-- 
Regards,
Alexandre


From shawnguo2 at yeah.net  Tue Feb  6 07:17:44 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Tue,  6 Feb 2024 23:17:44 +0800
Subject: [GIT PULL] i.MX fixes for 6.8
Message-ID: <20240206151744.2459-1-shawnguo2@yeah.net>

From: Shawn Guo <shawnguo at kernel.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-fixes-6.8

for you to fetch changes up to 7bca405c986075c99b9f729d3587b5c45db39d01:

  bus: imx-weim: fix valid range check (2024-02-06 14:10:47 +0800)

----------------------------------------------------------------
i.MX fixes for 6.8:

- A tqma8mpql device tree fix to correct audio codec iov-supply.
- A couple of USB-C connector DT description revert to fix regression
  on imx8mp-dhcom-pdk3 and imx8mn-var-som-symphony board.
- Fix valid range check for imx-weim bus driver.
- Disable UART4 on Data Modul i.MX8M Plus eDM SBC to avoid boot hang
  in case that RDC protection is in place.

----------------------------------------------------------------
Alexander Stein (1):
      arm64: dts: tqma8mpql: fix audio codec iov-supply

Fabio Estevam (2):
      Revert "arm64: dts: imx8mp-dhcom-pdk3: Describe the USB-C connector"
      Revert "arm64: dts: imx8mn-var-som-symphony: Describe the USB-C connector"

Lucas Stach (1):
      bus: imx-weim: fix valid range check

Marek Vasut (1):
      arm64: dts: imx8mp: Disable UART4 by default on Data Modul i.MX8M Plus eDM SBC

 arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts   | 11 +++--------
 arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts |  2 +-
 arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts         | 12 ++++--------
 arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts |  9 ++++++++-
 drivers/bus/imx-weim.c                                      |  2 +-
 5 files changed, 17 insertions(+), 19 deletions(-)



From amergnat at baylibre.com  Tue Feb  6 07:20:10 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Tue, 6 Feb 2024 16:20:10 +0100
Subject: [PATCH v4 7/9] drm/mediatek: dsi: Simplify with dev_err_probe and
 remove gotos
In-Reply-To: <20240206120748.136610-8-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-8-angelogioacchino.delregno@collabora.com>
Message-ID: <16bc6402-c60a-4857-a7e9-a60c3507c979@baylibre.com>

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>

On 06/02/2024 13:07, AngeloGioacchino Del Regno wrote:
> Most of the functions that are called in the probe callback are
> devm managed, or all but mipi_dsi_host_register(): simplify the probe
> function's error paths with dev_err_probe() and remove the lonely
> instance of `goto err_unregister_host` by just directly calling the
> mipi_dsi_host_unregister() function in the devm_request_irq() error
> path, allowing to also remove the same label.

-- 
Regards,
Alexandre


From amergnat at baylibre.com  Tue Feb  6 07:21:03 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Tue, 6 Feb 2024 16:21:03 +0100
Subject: [PATCH v4 8/9] drm/mediatek: dsi: Compress of_device_id entries
 and add sentinel
In-Reply-To: <20240206120748.136610-9-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-9-angelogioacchino.delregno@collabora.com>
Message-ID: <07c825c7-5036-4b9a-946d-eaaaeb4c050b@baylibre.com>

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>

On 06/02/2024 13:07, AngeloGioacchino Del Regno wrote:
> All entries fit in 82 columns, which is acceptable: compress all of
> the mtk_dsi_of_match[] entries to a single line for each.
> 
> While at it, also add the usual sentinel comment to the last entry.

-- 
Regards,
Alexandre


From diogo.ivo at siemens.com  Tue Feb  6 07:20:51 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Tue,  6 Feb 2024 15:20:51 +0000
Subject: [PATCH net] net: ti: icssg-prueth: Remove duplicate cleanup calls in emac_ndo_stop()
Message-ID: <20240206152052.98217-1-diogo.ivo@siemens.com>

Remove the duplicate calls to prueth_emac_stop() and
prueth_cleanup_tx_chns() in emac_ndo_stop().

Fixes: 128d5874c082 ("net: ti: icssg-prueth: Add ICSSG ethernet driver")
Fixes: 186734c15886 ("net: ti: icssg-prueth: add packet timestamping and ptp support")
Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index 411898a4f38c..cf7b73f8f450 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -1489,9 +1489,6 @@ static int emac_ndo_stop(struct net_device *ndev)
 	/* Destroying the queued work in ndo_stop() */
 	cancel_delayed_work_sync(&emac->stats_work);
 
-	/* stop PRUs */
-	prueth_emac_stop(emac);
-
 	if (prueth->emacs_initialized == 1)
 		icss_iep_exit(emac->iep);
 
@@ -1502,7 +1499,6 @@ static int emac_ndo_stop(struct net_device *ndev)
 
 	free_irq(emac->rx_chns.irq[rx_flow], emac);
 	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
-	prueth_cleanup_tx_chns(emac);
 
 	prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows);
 	prueth_cleanup_tx_chns(emac);
-- 
2.43.0



From amergnat at baylibre.com  Tue Feb  6 07:24:11 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Tue, 6 Feb 2024 16:24:11 +0100
Subject: [PATCH v4 9/9] drm/mediatek: dsi: Use
 mipi_dsi_pixel_format_to_bpp() helper function
In-Reply-To: <20240206120748.136610-10-angelogioacchino.delregno@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-10-angelogioacchino.delregno@collabora.com>
Message-ID: <282d07cf-97b4-423f-b148-42a5d5ff9d10@baylibre.com>

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>

On 06/02/2024 13:07, AngeloGioacchino Del Regno wrote:
> Instead of open coding, use the mipi_dsi_pixel_format_to_bpp() helper
> function from drm_mipi_dsi.h in mtk_dsi_poweron() and for validation
> in mtk_dsi_bridge_mode_valid().
> 
> Note that this function changes the behavior of this driver: previously,
> in case of unknown formats, it would (wrongly) assume that it should
> account for a 24-bits format - now it will return an error and refuse
> to set clocks and/or enable the DSI.
> 
> This is done because setting the wrong data rate will only produce a
> garbage output that the display will misinterpret both because this
> driver doesn't actually provide any extra-spec format support and/or
> because the data rate (hence, the HS clock) will be wrong.

-- 
Regards,
Alexandre


From dmitry.baryshkov at linaro.org  Tue Feb  6 07:26:29 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 06 Feb 2024 17:26:29 +0200
Subject: [PATCH v2] ARM: dts: imx53-qsb: add support for the HDMI expander
Message-ID: <20240206-imx53-qsb-hdmi-v2-1-a025fe0c4362@linaro.org>

Add support for the MCIMXHDMICARD expansion card attached to the iMX53
QSB / QSRB platforms. This enables HDMI output on those devices.

Reviewed-by: Fabio Estevam <festevam at gmail.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
Changes in v2:
- Fixed commit subject to mention imx53-qsb (Fabio)
- Fixed epansion -> expansion typo (Fabio)
- Link to v1: https://lore.kernel.org/r/20240206-imx53-qsb-hdmi-v1-1-e798eb1181c5 at linaro.org
---
 arch/arm/boot/dts/nxp/imx/Makefile            |  4 ++
 arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso | 87 +++++++++++++++++++++++++++
 2 files changed, 91 insertions(+)

diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile
index a724d1a7a9a0..24654deba303 100644
--- a/arch/arm/boot/dts/nxp/imx/Makefile
+++ b/arch/arm/boot/dts/nxp/imx/Makefile
@@ -45,7 +45,9 @@ dtb-$(CONFIG_SOC_IMX53) += \
 	imx53-mba53.dtb \
 	imx53-ppd.dtb \
 	imx53-qsb.dtb \
+	imx53-qsb-hdmi.dtb \
 	imx53-qsrb.dtb \
+	imx53-qsrb-hdmi.dtb \
 	imx53-sk-imx53.dtb \
 	imx53-sk-imx53-atm0700d4-lvds.dtb \
 	imx53-sk-imx53-atm0700d4-rgb.dtb \
@@ -54,6 +56,8 @@ dtb-$(CONFIG_SOC_IMX53) += \
 	imx53-tx53-x13x.dtb \
 	imx53-usbarmory.dtb \
 	imx53-voipac-bsb.dtb
+imx53-qsb-hdmi-dtbs := imx53-qsb.dtb imx53-qsb-hdmi.dtbo
+imx53-qsrb-hdmi-dtbs := imx53-qsrb.dtb imx53-qsb-hdmi.dtbo
 dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6dl-alti6p.dtb \
 	imx6dl-apf6dev.dtb \
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso b/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso
new file mode 100644
index 000000000000..c84e9b052527
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * DT overlay for MCIMXHDMICARD as used with the iMX53 QSB or QSRB boards
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	/delete-node/ panel;
+
+	hdmi: connector-hdmi {
+		compatible = "hdmi-connector";
+		label = "hdmi";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&sii9022_out>;
+			};
+		};
+	};
+
+	reg_1p2v: regulator-1p2v {
+		compatible = "regulator-fixed";
+		regulator-name = "1P2V";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-always-on;
+		vin-supply = <&reg_3p2v>;
+	};
+};
+
+&display0 {
+	status = "okay";
+};
+
+&display0 {
+	port at 1 {
+		display0_out: endpoint {
+			remote-endpoint = <&sii9022_in>;
+		};
+	};
+};
+
+&i2c2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	sii9022: bridge-hdmi at 39 {
+		compatible = "sil,sii9022";
+		reg = <0x39>;
+		reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+		interrupts-extended = <&gpio3 31 IRQ_TYPE_LEVEL_LOW>;
+		iovcc-supply = <&reg_3p2v>;
+		#sound-dai-cells = <0>;
+		sil,i2s-data-lanes = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				sii9022_in: endpoint {
+					remote-endpoint = <&display0_out>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				sii9022_out: endpoint {
+					remote-endpoint = <&hdmi_connector_in>;
+				};
+			};
+		};
+	};
+};
+
+&tve {
+	status = "disabled";
+};

---
base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
change-id: 20240206-imx53-qsb-hdmi-a4b6032e061e

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



From daniel at makrotopia.org  Tue Feb  6 07:31:21 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Tue, 6 Feb 2024 15:31:21 +0000
Subject: [PATCH v2 1/2] dt-bindings: phy: mediatek,mt7988-xfi-tphy: add
 new bindings
In-Reply-To: <31d2c56a-5108-4265-a267-6733e1ba328e@linaro.org>
References: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>
 <31d2c56a-5108-4265-a267-6733e1ba328e@linaro.org>
Message-ID: <ZcJQyaTotW_bCWGU@makrotopia.org>

Hi Krzysztof,

On Tue, Feb 06, 2024 at 11:53:55AM +0100, Krzysztof Kozlowski wrote:
> On 05/02/2024 18:28, Daniel Golle wrote:
> > Add bindings for the MediaTek XFI Ethernet SerDes T-PHY found in the
> > MediaTek MT7988 SoC which can operate at various interfaces modes:
> > 
> > via USXGMII PCS:
> >  * USXGMII
> >  * 10GBase-R
> >  * 5GBase-R
> > 
> > via LynxI SGMII PCS:
> >  * 2500Base-X
> >  * 1000Base-X
> >  * Cisco SGMII (MAC side)
> > 
> > Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> > ---
> > v2: unify filename and compatible as requested
> 
> Several comments, from me and Rob, were ignored. Please respond to them.

I'm sorry if I have missed something. I just checked again on
patchwork, just in case I would have missed an email reply to this or
any of the preceding posts of this patch as part of the old series
going to netdev.

Comments you have made which I have addressed:
 - removed $nodename
 - use compatible as filename

And the only thing I found that I didn't either fix or reply to is this:
> Can you explain what is this issue and errata about (except performance)?

Not overwriting that (undocumented) value in that (undocumented)
register results in 10GBase-R having performance issues according to a
commit in MediaTek's SDK, see here:

https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/a500d94cd%5E%21/#F0

Maybe Bc or SkyLake of MediaTek (added to Cc) can explain this in more
detail?


What I did miss was Rob's comment at the very bottom of this reply:
> What is PEXTP?

I can again only answer by referencing to MediaTek's SDK sources:

https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c#96

Here this reset is called XFI_PEXTP0_GRST.

I personally find that name confusing (as this PHY has nothing to do with
_P_ci _EX_press) and have tried to get rid of it where it isn't either part
of official documentation or already merged drivers (like Sam's clock driver).

If there have been any other issues with this patch which I'm not aware
of, please point them out to me.


Thank you


Best regards


Daniel


From angelogioacchino.delregno at collabora.com  Tue Feb  6 07:34:23 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 16:34:23 +0100
Subject: [PATCH v2 2/3] Subject: [PATCH] drm/mediatek/dp: Add HDCP2.x
 feature for DisplayPort
In-Reply-To: <20240205055055.25340-3-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
 <20240205055055.25340-3-mac.shen@mediatek.com>
Message-ID: <bd1b6561-d862-4482-aa1b-365429dd4e1c@collabora.com>

Il 05/02/24 06:50, mac.shen ha scritto:
> Add HDCP2.x feature for DisplayPort.
> When userspace request the kernel protect future content communicated
> over the link with Content_Protection property, the feature will do
> HDCP2.x authentication if the sink support HDCP2.X.
> 
> Changes in v2:
> - remove switch case, and refine code to make more clear
> - remove some definitions, and use the definitions in
>    include/drm/drm_hdcp.h
> - use the struct which defined in include/drm/drm_hdcp.h
> - do HDCP2.x authentication when userspace request the
>    kernel protect future content communicated
> per suggestion from the previous thread:
> https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
> 9218a545c46.camel at mediatek.com/
> 
> Signed-off-by: mac.shen <mac.shen at mediatek.com>
> ---
>   drivers/gpu/drm/mediatek/Makefile       |    1 +
>   drivers/gpu/drm/mediatek/mtk_dp.c       |  297 +++++--
>   drivers/gpu/drm/mediatek/mtk_dp.h       |   99 +++
>   drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c | 1021 +++++++++++++++++++++++
>   drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h |   52 ++
>   drivers/gpu/drm/mediatek/mtk_dp_reg.h   |    4 +-
>   drivers/gpu/drm/mediatek/mtk_dpi.c      |    3 +
>   7 files changed, 1392 insertions(+), 85 deletions(-)
>   create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.h
>   create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c
>   create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h
> 
> diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
> index c80e6c2f9336..50ea069b047e 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -27,6 +27,7 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
>   obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
>   
>   mtk-dp-objs := tlc_dp_hdcp.o \
> +		  mtk_dp_hdcp2.o \
>   		  mtk_dp.o
>   
>   obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk-dp.o
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
> index e4c16ba9902d..7ff72f15528b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dp.c
> @@ -1,6 +1,6 @@
>   // SPDX-License-Identifier: GPL-2.0
>   /*
> - * Copyright (c) 2019-2022 MediaTek Inc.
> + * Copyright (c) 2019-2024 MediaTek Inc.
>    * Copyright (c) 2022 BayLibre
>    */
>   
> @@ -8,13 +8,13 @@
>   #include <drm/display/drm_dp.h>
>   #include <drm/display/drm_dp_helper.h>
>   #include <drm/drm_atomic_helper.h>
> -#include <drm/drm_bridge.h>
>   #include <drm/drm_crtc.h>
>   #include <drm/drm_edid.h>
>   #include <drm/drm_of.h>
>   #include <drm/drm_panel.h>
>   #include <drm/drm_print.h>
>   #include <drm/drm_probe_helper.h>
> +#include <drm/display/drm_hdcp_helper.h>
>   #include <linux/arm-smccc.h>
>   #include <linux/clk.h>
>   #include <linux/delay.h>
> @@ -30,10 +30,10 @@
>   #include <linux/pm_runtime.h>
>   #include <linux/regmap.h>
>   #include <linux/soc/mediatek/mtk_sip_svc.h>
> -#include <sound/hdmi-codec.h>
> -#include <video/videomode.h>
>   
> +#include "mtk_dp.h"
>   #include "mtk_dp_reg.h"
> +#include "mtk_dp_hdcp2.h"
>   
>   #define MTK_DP_SIP_CONTROL_AARCH32	MTK_SIP_SMC_CMD(0x523)
>   #define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE	(BIT(0) | BIT(5))
> @@ -52,43 +52,6 @@
>   #define MTK_DP_VERSION 0x11
>   #define MTK_DP_SDP_AUI 0x4
>   
> -enum {
> -	MTK_DP_CAL_GLB_BIAS_TRIM = 0,
> -	MTK_DP_CAL_CLKTX_IMPSE,
> -	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_0,
> -	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_1,
> -	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_2,
> -	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_3,
> -	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_0,
> -	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_1,
> -	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_2,
> -	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_3,
> -	MTK_DP_CAL_MAX,
> -};
> -
> -struct mtk_dp_train_info {
> -	bool sink_ssc;
> -	bool cable_plugged_in;
> -	/* link_rate is in multiple of 0.27Gbps */
> -	int link_rate;
> -	int lane_count;
> -	unsigned int channel_eq_pattern;
> -};
> -
> -struct mtk_dp_audio_cfg {
> -	bool detect_monitor;
> -	int sad_count;
> -	int sample_rate;
> -	int word_length_bits;
> -	int channels;
> -};
> -
> -struct mtk_dp_info {
> -	enum dp_pixelformat format;
> -	struct videomode vm;
> -	struct mtk_dp_audio_cfg audio_cur_cfg;
> -};
> -
>   struct mtk_dp_efuse_fmt {
>   	unsigned short idx;
>   	unsigned short shift;
> @@ -98,44 +61,6 @@ struct mtk_dp_efuse_fmt {
>   	unsigned short default_val;
>   };
>   
> -struct mtk_dp {
> -	bool enabled;
> -	bool need_debounce;
> -	int irq;
> -	u8 max_lanes;
> -	u8 max_linkrate;
> -	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
> -	u32 cal_data[MTK_DP_CAL_MAX];
> -	u32 irq_thread_handle;
> -	/* irq_thread_lock is used to protect irq_thread_handle */
> -	spinlock_t irq_thread_lock;
> -
> -	struct device *dev;
> -	struct drm_bridge bridge;
> -	struct drm_bridge *next_bridge;
> -	struct drm_connector *conn;
> -	struct drm_device *drm_dev;
> -	struct drm_dp_aux aux;
> -
> -	const struct mtk_dp_data *data;
> -	struct mtk_dp_info info;
> -	struct mtk_dp_train_info train_info;
> -
> -	struct platform_device *phy_dev;
> -	struct phy *phy;
> -	struct regmap *regs;
> -	struct timer_list debounce_timer;
> -
> -	/* For audio */
> -	bool audio_enable;
> -	hdmi_codec_plugged_cb plugged_cb;
> -	struct platform_device *audio_pdev;
> -
> -	struct device *codec_dev;
> -	/* protect the plugged_cb as it's used in both bridge ops and audio */
> -	struct mutex update_plugged_status_lock;
> -};
> -
>   struct mtk_dp_data {
>   	int bridge_type;
>   	unsigned int smc_cmd;
> @@ -319,12 +244,28 @@ static struct regmap_config mtk_dp_regmap_config = {
>   	.name = "mtk-dp-registers",
>   };
>   
> +u32 mtk_dp_get_system_time(void)
> +{
> +	u32 tms = (u32)((sched_clock() / 1000000) % 1000000);

You want to use ktime_get_coarse_ns() or ktime_get_mono_fast_ns() and not
sched_clock(), besides, I don't get the sense of the MOD 1000000.....

Whatever, I'd write this one like:

u32 mtk_dp_get_system_time_ms(void)
{
	return (u32)(ktime_get_coarse_ns() / 1000000ULL);
}

...but then I don't get why you're not simply using the time in nanoseconds
and converting it to milliseconds all the time: okay, ns would be 64-bits but
I don't see the problem about that?!

If it is about not changing the wait time constants that are expressed in
milliseconds, you can simply redefine something like

#define SOME_MAX_WAIT_MS	20

to

#define MS_TO_NS(x)		((x) * NSEC_PER_MSEC)

#define SOME_MAX_WAIT_MS	MS_TO_NS(20)

...so that your functions won't perform any division, won't care about casting
between u32 and u64, won't ever be affected by possible overflows, so way less
possible issues to care about.

I say that wins over a total of 1-4 bytes of memory saving :-)

> +	return tms;
> +}
> +
> +u32 mtk_dp_get_time_diff(u32 pre_time)
> +{
> +	u32 post_time = mtk_dp_get_system_time();
> +
> +	if (pre_time > post_time)
> +		return ((1000000 - pre_time) + post_time);
> +	else
> +		return (post_time - pre_time);
> +}
> +
>   static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
>   {
>   	return container_of(b, struct mtk_dp, bridge);
>   }
>   
> -static u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
> +u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset)
>   {
>   	u32 read_val;
>   	int ret;
> @@ -350,8 +291,8 @@ static int mtk_dp_write(struct mtk_dp *mtk_dp, u32 offset, u32 val)
>   	return ret;
>   }
>   
> -static int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset,
> -			      u32 val, u32 mask)
> +int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset,
> +		       u32 val, u32 mask)
>   {
>   	int ret = regmap_update_bits(mtk_dp->regs, offset, mask, val);
>   
> @@ -1865,6 +1806,160 @@ static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
>   	mtk_dp_digital_sw_reset(mtk_dp);
>   }
>   
> +void mtk_dp_check_hdcp_version(struct mtk_dp *mtk_dp, bool only_hdcp1x)
> +{
> +	if (!only_hdcp1x && dp_tx_hdcp2_support(&mtk_dp->hdcp_info))
> +		return;
> +
> +	if (tee_add_device(&mtk_dp->hdcp_info, HDCP_NONE) != RET_SUCCESS)
> +		mtk_dp->hdcp_info.auth_status = AUTH_FAIL;
> +}
> +
> +static void mtk_dp_check_sink_esi(struct mtk_dp *mtk_dp)
> +{
> +	u8 clear_cp_irq = BIT(2);
> +
> +	if (mtk_dp->hdcp_info.hdcp2_info.enable) {
> +		dp_tx_hdcp2_irq(&mtk_dp->hdcp_info);
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> +				  DP_DEVICE_SERVICE_IRQ_VECTOR, &clear_cp_irq, 0x1);
> +	}
> +	/*hdcp 1.x do not need irq*/
> +}
> +
> +static void mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)

static int mtk_dp_hpd_sink_event(...)

> +{
> +	ssize_t ret;
> +	u8 sink_count;
> +	u8 sink_count_200;
> +
> +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT_ESI, &sink_count);
> +	if (ret < 0) {
> +		drm_info(mtk_dp->drm_dev, "Read sink count failed: %ld\n", ret);
> +		return;

return ret

> +	}
> +
> +	ret = drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count_200);
> +	if (ret < 0) {
> +		drm_info(mtk_dp->drm_dev,
> +			 "Read DP_SINK_COUNT_ESI failed: %ld\n", ret);
> +		return;

return ret

> +	}
> +
> +	mtk_dp_check_sink_esi(mtk_dp);

return 0;

> +}
> +
> +static void mtk_dp_hdcp_handle(struct work_struct *data)
> +{
> +	struct mtk_dp *mtk_dp = container_of(data, struct mtk_dp, hdcp_work);
> +
> +	if (!mtk_dp->train_info.cable_plugged_in)
> +		return;
> +
> +	if (mtk_dp->hdcp_info.auth_status == AUTH_PREPARE) {
> +		mtk_dp_check_hdcp_version(mtk_dp, false);
> +		if (mtk_dp->hdcp_info.hdcp2_info.enable)
> +			dp_tx_hdcp2_set_start_auth(&mtk_dp->hdcp_info, true);
> +		else
> +			mtk_dp->hdcp_info.auth_status = AUTH_ZERO;
> +	}
> +
> +	while (mtk_dp->hdcp_info.hdcp2_info.enable &&
> +	       mtk_dp->hdcp_info.auth_status != AUTH_FAIL &&
> +			mtk_dp->hdcp_info.auth_status != AUTH_PASS) {

Set an iteration limit to this, or it can potentially spin forever.

while (x && y && z && some_number > 0 {
	if (...) do_something()

	some_number--;
}

if (it_never_ran)
	return -ESOMETHING

return 0;

> +		if (mtk_dp->hdcp_info.hdcp2_info.enable)
> +			dp_tx_hdcp2_fsm(&mtk_dp->hdcp_info);
> +	}
> +}
> +
> +static void mtk_dp_hdcp_prop_work(struct work_struct *work)
> +{
> +	struct mtk_dp *mtk_dp;
> +	struct delayed_work *dework;
> +	struct drm_device *drm_dev;
> +
> +	dework = to_delayed_work(work);
> +	mtk_dp = container_of(dework, struct mtk_dp, prop_work);
> +
> +	if (!mtk_dp->conn) {
> +		dev_err(mtk_dp->dev, "connector is null!");
> +		return;
> +	}
> +
> +	drm_dev = mtk_dp->conn->dev;
> +
> +	drm_modeset_lock(&drm_dev->mode_config.connection_mutex, NULL);
> +

if (mtk_dp->hdcp_info.auth_status == AUTH_PASS)
	mtk_dp->hdcp_info.content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
else if (mtk_dp->hdcp_info.content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
	mtk_dp->hdcp_info.content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
else
	mtk_dp->hdcp_info.content_protection = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;

That's more readable :-)

> +	if (mtk_dp->hdcp_info.content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
> +		mtk_dp->hdcp_info.content_protection =
> +		(mtk_dp->hdcp_info.auth_status == AUTH_PASS) ? DRM_MODE_CONTENT_PROTECTION_ENABLED :
> +		DRM_MODE_CONTENT_PROTECTION_DESIRED;
> +	else
> +		mtk_dp->hdcp_info.content_protection =
> +		(mtk_dp->hdcp_info.auth_status == AUTH_PASS) ? DRM_MODE_CONTENT_PROTECTION_ENABLED :
> +		DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
> +
> +	dev_info(mtk_dp->dev, "update CP, content protection: %d, auth status:%d\n",
> +		 mtk_dp->hdcp_info.content_protection, mtk_dp->hdcp_info.auth_status);
> +	drm_hdcp_update_content_protection(mtk_dp->conn, mtk_dp->hdcp_info.content_protection);
> +
> +	drm_modeset_unlock(&drm_dev->mode_config.connection_mutex);
> +}
> +
> +static void mtk_dp_hdcp_atomic_check(struct mtk_dp *mtk_dp, struct drm_connector_state *state)
> +{

I propose:

static void mtk_dp_hdcp_atomic_check(struct mtk_dp *mtk_dp, struct 
drm_connector_state *state)
{
	unsigned int old_content_protection = mtk_dp->hdcp_info.content_protection;
	unsigned int new_content_protection = state->content_protection;
	unsigned int hdcp_content_type = state->hdcp_content_type;

	dev_dbg(mtk_dp->dev, "CP type and protection, atomic: %d, %d, driver:%d, %d\n",
		hdcp_content_type, content_protection,
		mtk_dp->hdcp_info.hdcp_content_type, mtk_dp->hdcp_info.content_protection);

	if (new_content_protection != DRM_MODE_CONTENT_PROTECTION_DESIRED &&
	    (hdcp_content_type == mtk_dp->hdcp_info.hdcp_content_type ||
	     new_content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
		return;

	mtk_dp->hdcp_info.content_protection = new_content_protection;

	if (old_content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
		dev_dbg(mtk_dp->dev, "disable HDCP\n");
		if (mtk_dp->hdcp_info.hdcp2_info.enable)
			dp_tx_hdcp2_set_start_auth(&mtk_dp->hdcp_info, false);

		drm_hdcp_update_content_protection(mtk_dp->conn,
						   mtk_dp->hdcp_info.content_protection);
	} else {
		mtk_dp->hdcp_info.hdcp_content_type = hdcp_content_type;
		mtk_dp->hdcp_info.hdcp2_info.stream_id_type = hdcp_content_type;

		if (mtk_dp->hdcp_info.auth_status == AUTH_FAIL ||
		    mtk_dp->hdcp_info.auth_status == AUTH_ZERO) {
			dev_dbg(mtk_dp->dev, "enable HDCP\n");
			mtk_dp_authentication(&mtk_dp->hdcp_info);

			queue_delayed_work(mtk_dp->hdcp_workqueue,
					   &mtk_dp->prop_work, msecs_to_jiffies(2000));
	}
}




> +	unsigned int hdcp_content_type = state->hdcp_content_type;
> +	unsigned int content_protection = state->content_protection;
> +
> +	dev_dbg(mtk_dp->dev, "CP type and protection, atomic: %d, %d, driver:%d, %d\n",
> +		hdcp_content_type, content_protection,
> +		mtk_dp->hdcp_info.hdcp_content_type, mtk_dp->hdcp_info.content_protection);
> +
> +	if ((content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
> +	     mtk_dp->hdcp_info.content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
> +		(hdcp_content_type != mtk_dp->hdcp_info.hdcp_content_type &&
> +		 content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
> +		mtk_dp->hdcp_info.content_protection = content_protection;
> +
> +		dev_dbg(mtk_dp->dev, "disable HDCP\n");
> +		if (mtk_dp->hdcp_info.hdcp2_info.enable)
> +			dp_tx_hdcp2_set_start_auth(&mtk_dp->hdcp_info, false);
> +
> +		drm_hdcp_update_content_protection(mtk_dp->conn,
> +						   mtk_dp->hdcp_info.content_protection);
> +	}
> +
> +	if (content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED ||
> +	    (hdcp_content_type != mtk_dp->hdcp_info.hdcp_content_type &&
> +		 content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
> +		mtk_dp->hdcp_info.content_protection = content_protection;
> +		mtk_dp->hdcp_info.hdcp_content_type = hdcp_content_type;
> +		mtk_dp->hdcp_info.hdcp2_info.stream_id_type = hdcp_content_type;
> +
> +		if (mtk_dp->hdcp_info.auth_status == AUTH_FAIL ||
> +		    mtk_dp->hdcp_info.auth_status == AUTH_ZERO) {
> +			dev_dbg(mtk_dp->dev, "enable HDCP\n");
> +			mtk_dp_authentication(&mtk_dp->hdcp_info);
> +
> +			queue_delayed_work(mtk_dp->hdcp_workqueue,
> +					   &mtk_dp->prop_work, msecs_to_jiffies(2000));
> +		}
> +	}
> +}
> +
> +void mtk_dp_authentication(struct mtk_hdcp_info *hdcp_info)
> +{
> +	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
> +
> +	if (!mtk_dp->train_info.cable_plugged_in)
> +		return;
> +
> +	hdcp_info->auth_status = AUTH_PREPARE;
> +
> +	dev_info(mtk_dp->dev, "dp start HDCP work");
> +	queue_work(mtk_dp->hdcp_workqueue, &mtk_dp->hdcp_work);
> +}
> +
>   static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
>   {
>   	struct mtk_dp *mtk_dp = dev;
> @@ -1894,9 +1989,11 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
>   		}
>   	}
>   
> -	if (status & MTK_DP_THREAD_HPD_EVENT)
> +	if (status & MTK_DP_THREAD_HPD_EVENT) {
>   		dev_dbg(mtk_dp->dev, "Receive IRQ from sink devices\n");
> -
> +		/*check if need clear hpd irq*/
> +		mtk_dp_hpd_sink_event(mtk_dp);

		ret = mtk_dp_hpd_sink_event(mtk_dp);
		if (ret)
			do_something;

> +	}
>   	return IRQ_HANDLED;
>   }
>   
> @@ -2233,6 +2330,7 @@ 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 *connector_state;
>   	int ret;
>   
>   	mtk_dp->conn = drm_atomic_get_new_connector_for_encoder(old_state->base.state,
> @@ -2243,6 +2341,8 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
>   		return;
>   	}
>   
> +	connector_state = drm_atomic_get_connector_state(old_state->base.state, mtk_dp->conn);
> +
>   	mtk_dp_aux_panel_poweron(mtk_dp, true);
>   
>   	/* Training */
> @@ -2272,6 +2372,14 @@ static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
>   	mtk_dp->enabled = true;
>   	mtk_dp_update_plugged_status(mtk_dp);
>   
> +	/* Enable hdcp if it's desired */
> +	dev_info(mtk_dp->dev, "hdcp_content_type:%d, content protection: %d",
> +		 connector_state->hdcp_content_type, connector_state->content_protection);

I'm not sure if this message is really informative for the user. I'd say no.
In that case, dev_dbg()

> +	if (connector_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
> +		mtk_dp->hdcp_info.hdcp_content_type = connector_state->hdcp_content_type;
> +		mtk_dp_authentication(&mtk_dp->hdcp_info);
> +	}
> +
>   	return;
>   power_off_aux:
>   	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
> @@ -2284,6 +2392,17 @@ static void mtk_dp_bridge_atomic_disable(struct drm_bridge *bridge,
>   {
>   	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
>   
> +	if (mtk_dp->hdcp_info.hdcp2_info.enable)
> +		dp_tx_hdcp2_set_start_auth(&mtk_dp->hdcp_info, false);
> +
> +	if (mtk_dp->hdcp_info.content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
> +		mtk_dp->hdcp_info.content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
> +		dev_info(mtk_dp->dev, "update CP, content protection: %d\n",
> +			 mtk_dp->hdcp_info.content_protection);

dev_dbg()

> +		drm_hdcp_update_content_protection(mtk_dp->conn,
> +						   mtk_dp->hdcp_info.content_protection);
> +	}
> +
>   	mtk_dp->enabled = false;
>   	mtk_dp_update_plugged_status(mtk_dp);
>   	mtk_dp_video_enable(mtk_dp, false);
> @@ -2418,6 +2537,8 @@ static int mtk_dp_bridge_atomic_check(struct drm_bridge *bridge,
>   
>   	drm_display_mode_to_videomode(&crtc_state->adjusted_mode, &mtk_dp->info.vm);
>   
> +	mtk_dp_hdcp_atomic_check(mtk_dp, conn_state);
> +
>   	return 0;
>   }
>   
> @@ -2657,6 +2778,14 @@ static int mtk_dp_probe(struct platform_device *pdev)
>   	if (ret)
>   		return ret;
>   
> +	INIT_WORK(&mtk_dp->hdcp_work, mtk_dp_hdcp_handle);
> +	INIT_DELAYED_WORK(&mtk_dp->prop_work, mtk_dp_hdcp_prop_work);
> +	mtk_dp->hdcp_workqueue = create_workqueue("mtk_dp_hdcp_work");
> +	if (!mtk_dp->hdcp_workqueue) {
> +		dev_err(mtk_dp->dev, "failed to create hdcp work queue");
> +		return -ENOMEM;
> +	}
> +
>   	mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs;
>   	mtk_dp->bridge.of_node = dev->of_node;
>   	mtk_dp->bridge.type = mtk_dp->data->bridge_type;
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp.h b/drivers/gpu/drm/mediatek/mtk_dp.h
> new file mode 100644
> index 000000000000..85c0cf0005c0
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_dp.h
> @@ -0,0 +1,99 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019-2024 MediaTek Inc.
> + */
> +
> +#ifndef _MTK_DP_H_
> +#define _MTK_DP_H_
> +
> +#include "tlc_dp_hdcp.h"
> +#include <drm/drm_bridge.h>
> +#include <sound/hdmi-codec.h>
> +#include <video/videomode.h>
> +
> +enum {
> +	MTK_DP_CAL_GLB_BIAS_TRIM = 0,
> +	MTK_DP_CAL_CLKTX_IMPSE,
> +	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_0,
> +	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_1,
> +	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_2,
> +	MTK_DP_CAL_LN_TX_IMPSEL_PMOS_3,
> +	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_0,
> +	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_1,
> +	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_2,
> +	MTK_DP_CAL_LN_TX_IMPSEL_NMOS_3,
> +	MTK_DP_CAL_MAX,
> +};
> +
> +struct mtk_dp_audio_cfg {
> +	bool detect_monitor;
> +	int sad_count;
> +	int sample_rate;
> +	int word_length_bits;
> +	int channels;
> +};
> +
> +struct mtk_dp_info {
> +	enum dp_pixelformat format;
> +	struct videomode vm;
> +	struct mtk_dp_audio_cfg audio_cur_cfg;
> +};
> +
> +struct mtk_dp_train_info {
> +	bool sink_ssc;
> +	bool cable_plugged_in;
> +	/* link_rate is in multiple of 0.27Gbps */
> +	int link_rate;
> +	int lane_count;
> +	unsigned int channel_eq_pattern;
> +};
> +
> +struct mtk_dp {
> +	bool enabled;
> +	bool need_debounce;
> +	int irq;
> +	u8 max_lanes;
> +	u8 max_linkrate;
> +	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
> +	u32 cal_data[MTK_DP_CAL_MAX];
> +	u32 irq_thread_handle;
> +	/* irq_thread_lock is used to protect irq_thread_handle */
> +	spinlock_t irq_thread_lock;
> +
> +	struct device *dev;
> +	struct drm_bridge bridge;
> +	struct drm_bridge *next_bridge;
> +	struct drm_connector *conn;
> +	struct drm_device *drm_dev;
> +	struct drm_dp_aux aux;
> +
> +	const struct mtk_dp_data *data;
> +	struct mtk_dp_info info;
> +	struct mtk_dp_train_info train_info;
> +	struct mtk_hdcp_info hdcp_info;
> +	struct work_struct hdcp_work;
> +	struct delayed_work prop_work;
> +	struct workqueue_struct *hdcp_workqueue;
> +
> +	struct platform_device *phy_dev;
> +	struct phy *phy;
> +	struct regmap *regs;
> +	struct timer_list debounce_timer;
> +
> +	/* For audio */
> +	bool audio_enable;
> +	hdmi_codec_plugged_cb plugged_cb;
> +	struct platform_device *audio_pdev;
> +
> +	struct device *codec_dev;
> +	/* protect the plugged_cb as it's used in both bridge ops and audio */
> +	struct mutex update_plugged_status_lock;
> +};
> +
> +u32 mtk_dp_get_system_time(void);
> +u32 mtk_dp_get_time_diff(u32 pre_time);
> +u32 mtk_dp_read(struct mtk_dp *mtk_dp, u32 offset);
> +int mtk_dp_update_bits(struct mtk_dp *mtk_dp, u32 offset, u32 val, u32 mask);
> +void mtk_dp_authentication(struct mtk_hdcp_info *hdcp_info);
> +
> +#endif /* _MTK_DP_H_ */
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c b/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c
> new file mode 100644
> index 000000000000..8528e33f3f49
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.c
> @@ -0,0 +1,1021 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019-2024 MediaTek Inc.
> + */
> +
> +#include "mtk_dp_hdcp2.h"
> +#include "mtk_dp_reg.h"
> +#include "mtk_dp.h"
> +
> +u8 t_rtx[HDCP_2_2_RTX_LEN] = {
> +	0x18, 0xfa, 0xe4, 0x20, 0x6a, 0xfb, 0x51, 0x49
> +};
> +
> +u8 t_tx_caps[HDCP_2_2_TXCAPS_LEN] = {
> +	0x02, 0x00, 0x00
> +};
> +
> +u8 t_rn[HDCP_2_2_RN_LEN] = {
> +	0x32, 0x75, 0x3e, 0xa8, 0x78, 0xa6, 0x38, 0x1c
> +};
> +
> +u8 t_riv[HDCP_2_2_RIV_LEN] = {
> +	0x40, 0x2b, 0x6b, 0x43, 0xc5, 0xe8, 0x86, 0xd8
> +};
> +
> +static void dp_tx_hdcp2_fill_stream_type(struct mtk_hdcp_info *hdcp_info, u8 uc_type)
> +{
> +	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
> +
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34D0, uc_type, 0xff);
> +}
> +
> +static void dp_tx_hdcp2_set_state(struct mtk_hdcp_info *hdcp_info, u8 main_state, u8 sub_state)
> +{
> +	hdcp_info->hdcp2_info.hdcp_handler.main_state = main_state;
> +	hdcp_info->hdcp2_info.hdcp_handler.sub_state = sub_state;
> +}
> +
> +static void dp_tx_hdcp2_set_auth_pass(struct mtk_hdcp_info *hdcp_info, bool enable)
> +{
> +	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
> +
> +	if (enable) {
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3400, BIT(11), BIT(11));

#define SOMETHING BIT(11) please - and same for BIT(4). No magic numbers.

> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4, BIT(4), BIT(4));
> +	} else {
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3400, 0, BIT(11));
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_34A4, 0, BIT(4));
> +	}
> +}
> +
> +static void dp_tx_hdcp2_enable_auth(struct mtk_hdcp_info *hdcp_info, bool enable)
> +{
> +	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
> +
> +	DPTXHDCPFUNC();

What would that be?! That's not upstream quality.

> +	dp_tx_hdcp2_set_auth_pass(hdcp_info, enable);

Also...

u32 version;

if (!enable) {
	tee_hdcp_enable_encrypt(hdcp_info, enable, HDCP_NONE);
	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, 0, BIT(5) <--- define it!);

	return;
}

if ...
	version = HDCP_V1;
else if ...
	version = HDCP_V2;
else
	version = HDCP_V2_3;

enable encrypt, update_bits

> +	if (enable) {
> +		u32 version = HDCP_V2_3;
> +
> +		if (hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info[1] & BIT(0))
> +			version = HDCP_V1;
> +		else if (hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info[1] & BIT(1))
> +			version = HDCP_V2;
> +
> +		tee_hdcp_enable_encrypt(hdcp_info, enable, version);
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, BIT(5), BIT(5));
> +	} else {
> +		tee_hdcp_enable_encrypt(hdcp_info, enable, HDCP_NONE);
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000, 0, BIT(5));
> +	}
> +}
> +
> +static int dp_tx_hdcp2_init(struct mtk_hdcp_info *hdcp_info)
> +{
> +	int err_code = HDCP_ERR_NONE;
> +
> +	DPTXHDCPFUNC();

Seriously, a call to "DPTXHDCPFUNC()" is nothing we should ever see upstream.

> +
> +	memset(&hdcp_info->hdcp2_info.hdcp_tx, 0, sizeof(struct hdcp2_info_tx));
> +	memset(&hdcp_info->hdcp2_info.hdcp_rx, 0, sizeof(struct hdcp2_info_rx));

All memset zero first, all memcpy last.
Makes that more readable.

> +	memcpy(hdcp_info->hdcp2_info.hdcp_tx.ake_init.r_tx, t_rtx, HDCP_2_2_RTX_LEN);
> +	memcpy(&hdcp_info->hdcp2_info.hdcp_tx.tx_caps, t_tx_caps, HDCP_2_2_TXCAPS_LEN);
> +	memcpy(hdcp_info->hdcp2_info.hdcp_tx.lc_init.r_n, t_rn, HDCP_2_2_RN_LEN);
> +	memcpy(hdcp_info->hdcp2_info.hdcp_tx.send_eks.riv, t_riv, HDCP_2_2_RIV_LEN);
> +
> +	memset(&hdcp_info->hdcp2_info.hdcp_handler, 0, sizeof(struct hdcp2_handler));
> +	memset(&hdcp_info->hdcp2_info.ake_stored_km, 0, sizeof(struct hdcp2_ake_stored_km));
> +
> +	dp_tx_hdcp2_enable_auth(hdcp_info, false);
> +

	return HDCP_ERR_NONE;

> +	return err_code;
> +}
> +
> +static bool dp_tx_hdcp2_inc_seq_num_m(struct mtk_hdcp_info *hdcp_info)
> +{
> +	u32 tmp = 0;

u32 tmp = drm_hdcp_be24_to_cpu(...)

> +
> +	tmp = drm_hdcp_be24_to_cpu(hdcp_info->hdcp2_info.hdcp_tx.stream_manage.seq_num_m);
> +
> +	if (tmp == 0xFFFFFF)

#define SOMETHING 0xFFFFFF

	if (tmp == SOMETHING)
		return false;

> +		return false;
> +
> +	tmp++;
> +
> +	drm_hdcp_cpu_to_be24(hdcp_info->hdcp2_info.hdcp_tx.stream_manage.seq_num_m, tmp);
> +	return true;
> +}
> +
> +static bool dp_tx_hdcp2_process_rep_auth_stream_manage(struct mtk_hdcp_info *hdcp_info)
> +{
> +	bool ret = false;

You don't need bool ret.

> +
> +	hdcp_info->hdcp2_info.hdcp_tx.k[0] = 0x00;
> +	hdcp_info->hdcp2_info.hdcp_tx.k[1] = 0x01;
> +
> +	hdcp_info->hdcp2_info.hdcp_tx.stream_id_type[0] = 0x00; //Payload ID
> +	hdcp_info->hdcp2_info.hdcp_tx.stream_id_type[1] = hdcp_info->hdcp2_info.stream_id_type;
> +
> +	ret = dp_tx_hdcp2_inc_seq_num_m(hdcp_info);

	return dp_tx_hdcp2_inc_seq_num_m(hdcp_info);

> +
> +	return ret;
> +}
> +
> +static bool dp_tx_hdcp2_recv_rep_auth_send_recv_id_list(struct mtk_hdcp_info *hdcp_info)
> +{
> +	bool ret = false;
> +	u8 *buffer = NULL;
> +	u32 len = 0, len_recv_id_list = 0;
> +	int rc = 0;
> +
> +	len_recv_id_list = hdcp_info->hdcp2_info.device_count * HDCP_2_2_RECEIVER_ID_LEN;
> +	len = len_recv_id_list + HDCP_2_2_RXINFO_LEN + HDCP_2_2_SEQ_NUM_LEN;
> +	buffer = kmalloc(len, GFP_KERNEL);
> +	if (!buffer) {
> +		pr_err("2.x: Out of Memory\n");

can we use dev_err instead?

> +		return ret;
> +	}
> +
> +	memcpy(buffer, hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.receiver_ids,
> +	       len_recv_id_list);
> +	memcpy(buffer + len_recv_id_list,
> +	       hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info, HDCP_2_2_RXINFO_LEN);
> +	memcpy(buffer + len_recv_id_list + HDCP_2_2_RXINFO_LEN,
> +	       hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v, HDCP_2_2_SEQ_NUM_LEN);
> +
> +	rc = tee_hdcp2_compute_compare_v(hdcp_info, buffer, len,
> +					 hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.v_prime,
> +		hdcp_info->hdcp2_info.hdcp_tx.send_ack.v);
> +
> +	if (rc == RET_COMPARE_PASS) {
> +		ret = true;
> +		DPTXHDCPMSG("2.x: V' is PASS!!\n");
> +	} else {
> +		DPTXHDCPMSG("2.x: V' is FAIL!!\n");
> +	}

This if branch is probably useless.

> +
> +	kfree(buffer);

	return !!(rc == RET_COMPARE_PASS)

> +	return ret;
> +}
> +
> +static bool dp_tx_hdcp2_recv_rep_auth_stream_ready(struct mtk_hdcp_info *hdcp_info)
> +{
> +	bool ret = false;
> +	u8 *buffer = NULL;
> +	u32 len = 0;
> +	int tmp = 0;
> +
> +	len = HDCP2_STREAMID_TYPE_LEN + HDCP_2_2_SEQ_NUM_LEN;
> +	buffer = kmalloc(len, GFP_KERNEL);
> +	if (!buffer) {
> +		pr_err("2.x: Out of Memory\n");
> +		return ret;
> +	}
> +
> +	memcpy(buffer, hdcp_info->hdcp2_info.hdcp_tx.stream_id_type, HDCP2_STREAMID_TYPE_LEN);
> +	memcpy(buffer + HDCP2_STREAMID_TYPE_LEN,
> +	       hdcp_info->hdcp2_info.hdcp_tx.stream_manage.seq_num_m,
> +	       HDCP_2_2_SEQ_NUM_LEN);
> +	tmp = tee_hdcp2_compute_compare_m(hdcp_info, buffer, len,
> +					  hdcp_info->hdcp2_info.hdcp_rx.stream_ready.m_prime);
> +
> +	if (tmp == RET_COMPARE_PASS) {
> +		ret = true;
> +		DPTXHDCPMSG("2.x: M' is PASS!!\n");
> +	} else {
> +		DPTXHDCPMSG("2.x: M' is FAIL!!\n");
> +	}

same here, if branch useless.

> +
> +	kfree(buffer);
> +	return ret;
> +}
> +
> +static bool dp_tx_hdcp2_check_seq_num_v(struct mtk_hdcp_info *hdcp_info)
> +{
> +	if ((hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[0] == 0x00 &&
> +	     hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[1] == 0x00 &&
> +			hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[2] == 0x00) &&

fix indentation please

> +		hdcp_info->hdcp2_info.hdcp_handler.seq_num_v_cnt > 0xFFFFFF) {
> +		DPTXHDCPMSG("2.x: SeqNumV Rollover!\n");
> +		return false;
> +	}
> +
> +	if ((hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[0]
> +		!= (u8)((hdcp_info->hdcp2_info.hdcp_handler.seq_num_v_cnt & 0xFF0000) >> 16)) ||

See bitfield.h and use those macros, or this is totally unreadable.

> +			(hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[1]
> +		!= (u8)((hdcp_info->hdcp2_info.hdcp_handler.seq_num_v_cnt & 0x00FF00) >> 8)) ||
> +			(hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v[2]
> +		!= (u8)((hdcp_info->hdcp2_info.hdcp_handler.seq_num_v_cnt & 0x0000FF)))) {
> +		DPTXHDCPMSG("2.x: Invalid Seq_num_V!\n");
> +		return false;
> +	}
> +
> +	hdcp_info->hdcp2_info.hdcp_handler.seq_num_v_cnt++;
> +	return true;
> +}
> +
> +static void dp_tx_hdcp2_err_handle(struct mtk_hdcp_info *hdcp_info, int err_msg, int line)
> +{
> +	pr_err("2.x: MainState:%d; SubState:%d;\n", hdcp_info->hdcp2_info.hdcp_handler.main_state,
> +	       hdcp_info->hdcp2_info.hdcp_handler.sub_state);
> +
> +	switch (err_msg) {
> +	case HDCP_ERR_UNKNOWN_STATE:
> +		pr_err("2.x: Unknown State, line:%d\n", line);
> +		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_H1P1, HDCP_2_2_AUTH_FAIL);
> +		break;
> +
> +	case HDCP_ERR_SEND_MSG_FAIL:
> +		pr_err("2.x: Send Msg Fail, line:%d\n", line);
> +		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0, HDCP_2_2_NULL_MSG);
> +		break;
> +	case HDCP_ERR_RESPONSE_TIMEROUT:
> +		pr_err("2.x: Response Timeout, line:%d!\n", line);
> +		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0, HDCP_2_2_NULL_MSG);
> +		break;
> +
> +	case HDCP_ERR_PROCESS_FAIL:
> +		pr_err("2.x: Process Fail, line:%d!\n", line);
> +		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0, HDCP_2_2_NULL_MSG);
> +		break;
> +
> +	default:
> +		pr_err("2.x: NO ERROR!");

pr_err("no error\n"); ?!?!?

Unless having no error is an error, this doesn't make any sense, at all.

> +		break;
> +	}
> +}
> +
> +static bool dp_tx_hdcp2_read_msg(struct mtk_hdcp_info *hdcp_info, u8 cmd_ID)
> +{
> +	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
> +	bool ret = false;

You don't need bool ret.

> +	u8 size = 0;
> +
> +	switch (cmd_ID) {
> +	case HDCP_2_2_AKE_SEND_CERT:
> +		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_CERT_RX_OFFSET,
> +				 (void *)&hdcp_info->hdcp2_info.hdcp_rx.cert_rx, HDCP2_CERTRX_LEN);
> +		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RRX_OFFSET,
> +				 hdcp_info->hdcp2_info.hdcp_rx.send_cert.r_rx, HDCP_2_2_RRX_LEN);
> +		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
> +				 hdcp_info->hdcp2_info.hdcp_rx.send_cert.rx_caps,
> +				 HDCP_2_2_RXCAPS_LEN);
> +
> +		hdcp_info->hdcp2_info.read_certrx = false;
> +		hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
> +		ret = true;

return true;

> +		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_SEND_CERT\n");
> +		break;
> +
> +	case HDCP_2_2_AKE_SEND_HPRIME:
> +		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_HPRIME_OFFSET,
> +				 hdcp_info->hdcp2_info.hdcp_rx.send_hprime.h_prime,
> +				 HDCP_2_2_H_PRIME_LEN);
> +
> +		hdcp_info->hdcp2_info.read_h_prime = false;
> +		hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
> +		ret = true;
> +

return true;

> +		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_SEND_HPRIME\n");
> +		break;
> +
> +	case HDCP_2_2_AKE_SEND_PAIRING_INFO:
> +		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_EKH_KM_RD_OFFSET,
> +				 hdcp_info->hdcp2_info.hdcp_rx.pairing_info.e_kh_km,
> +				 HDCP_2_2_E_KH_KM_LEN);
> +		hdcp_info->hdcp2_info.read_pairing = false;
> +		hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
> +		ret = true;

return true;

> +		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_SEND_PAIRING_INFO\n");
> +		break;
> +
> +	case HDCP_2_2_LC_SEND_LPRIME:
> +		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_LPRIME_OFFSET,
> +				 hdcp_info->hdcp2_info.hdcp_rx.send_lprime.l_prime,
> +				 HDCP_2_2_L_PRIME_LEN);
> +
> +		hdcp_info->hdcp2_info.read_l_prime = false;
> +		hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
> +		ret = true;

return true;

> +		DPTXHDCPMSG("2.x: HDCP_2_2_LC_SEND_LPRIME\n");
> +		break;
> +
> +	case HDCP_2_2_REP_SEND_RECVID_LIST:
> +		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RXINFO_OFFSET,
> +				 hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info,
> +				 HDCP_2_2_RXINFO_LEN);
> +		hdcp_info->hdcp2_info.device_count =
> +			((hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info[1] & 0xf0) >> 4)
> +				| ((hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info[0]
> +				& BIT(0)) << 4);
> +
> +		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_SEQ_NUM_V_OFFSET,
> +				 hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.seq_num_v,
> +				 HDCP_2_2_SEQ_NUM_LEN);
> +		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_VPRIME_OFFSET,
> +				 hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.v_prime,
> +				 HDCP_2_2_V_PRIME_HALF_LEN);
> +		drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RECV_ID_LIST_OFFSET,
> +				 hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.receiver_ids,
> +			hdcp_info->hdcp2_info.device_count * HDCP_2_2_RECEIVER_ID_LEN);
> +
> +		hdcp_info->hdcp2_info.read_v_prime = false;
> +		hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
> +		ret = true;

return true;

> +		DPTXHDCPMSG("2.x: HDCP_2_2_REP_SEND_RECVID_LIST\n");
> +		break;
> +
> +	case HDCP_2_2_REP_STREAM_READY:
> +		size = drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_MPRIME_OFFSET,
> +					hdcp_info->hdcp2_info.hdcp_rx.stream_ready.m_prime,
> +					HDCP_2_2_MPRIME_LEN);
> +
> +		if (size == HDCP_2_2_MPRIME_LEN)
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = true;
> +		ret = true;

return true;

> +		DPTXHDCPMSG("2.x: HDCP_2_2_REP_STREAM_READY\n");
> +		break;
> +
> +	default:
> +		DPTXHDCPMSG("2.x: Invalid DPTX_HDCP2_OffSETADDR_ReadMessage !\n");
> +		break;
> +	}
> +
> +	return ret;

return false;

> +}
> +
> +static bool dp_tx_hdcp2_write_msg(struct mtk_hdcp_info *hdcp_info, u8 cmd_ID)
> +{
> +	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
> +	bool ret = false;

same story here.

> +
> +	switch (cmd_ID) {
> +	case HDCP_2_2_AKE_INIT:
> +		tee_hdcp2_soft_rst(hdcp_info);
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_RTX_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.ake_init.r_tx, HDCP_2_2_RTX_LEN);
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_TXCAPS_OFFSET,
> +				  (void *)&hdcp_info->hdcp2_info.hdcp_tx.tx_caps,
> +				  HDCP_2_2_TXCAPS_LEN);
> +
> +		ret = true;
> +		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_Init !\n");
> +		break;
> +
> +	case HDCP_2_2_AKE_NO_STORED_KM:
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_EKPUB_KM_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.no_stored_km.e_kpub_km,
> +				  HDCP_2_2_E_KPUB_KM_LEN);
> +
> +		ret = true;
> +
> +		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_NO_STORED_KM !\n");
> +		break;
> +
> +	case HDCP_2_2_AKE_STORED_KM:
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_EKH_KM_WR_OFFSET,
> +				  hdcp_info->hdcp2_info.ake_stored_km.e_kh_km_m,
> +				  HDCP_2_2_E_KH_KM_LEN);
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_M_OFFSET,
> +				  hdcp_info->hdcp2_info.ake_stored_km.e_kh_km_m +
> +				  HDCP_2_2_E_KH_KM_LEN,
> +				  HDCP_2_2_E_KH_KM_M_LEN - HDCP_2_2_E_KH_KM_LEN);
> +
> +		ret = true;
> +
> +		DPTXHDCPMSG("2.x: DPTX_HDCP_2_2_AKE_STORED_KM !\n");
> +		break;
> +
> +	case HDCP_2_2_LC_INIT:
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_RN_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.lc_init.r_n, HDCP_2_2_RN_LEN);
> +
> +		hdcp_info->hdcp2_info.read_l_prime = true;
> +		ret = true;
> +
> +		DPTXHDCPMSG("2.x: HDCP_2_2_LC_INIT !\n");
> +		break;
> +
> +	case HDCP_2_2_SKE_SEND_EKS:
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_EDKEY_KS_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.send_eks.e_dkey_ks,
> +				  HDCP_2_2_E_DKEY_KS_LEN);
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_RIV_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.send_eks.riv, HDCP_2_2_RIV_LEN);
> +
> +		hdcp_info->hdcp2_info.ks_exchange_done = true;
> +
> +		ret = true;
> +		DPTXHDCPMSG("2.x: HDCP_2_2_SKE_SEND_EKS !\n");
> +		break;
> +
> +	case HDCP_2_2_STREAM_TYPE:
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.stream_id_type, 1);
> +
> +		ret = true;
> +		DPTXHDCPMSG("HDCP2_MSG_DP_STREAM_TYPE !\n");
> +		break;
> +
> +	case HDCP_2_2_REP_SEND_ACK:
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_V_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.send_ack.v,
> +				  HDCP_2_2_V_PRIME_HALF_LEN);
> +
> +		ret = true;
> +		DPTXHDCPMSG("2.x: HDCP_2_2_SEND_ACK !\n");
> +		break;
> +
> +	case HDCP_2_2_REP_STREAM_MANAGE:
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_SEQ_NUM_M_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.stream_manage.seq_num_m,
> +				  HDCP_2_2_SEQ_NUM_LEN);
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_K_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.k, HDCP2_K_LEN);
> +		drm_dp_dpcd_write(&mtk_dp->aux, DP_HDCP_2_2_REG_STREAM_ID_TYPE_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.stream_id_type,
> +				  HDCP2_STREAMID_TYPE_LEN);
> +
> +		dp_tx_hdcp2_fill_stream_type(hdcp_info, hdcp_info->hdcp2_info.stream_id_type);
> +
> +		ret = true;
> +		DPTXHDCPMSG("2.x: HDCP_2_2_STREAM_MANAGE !\n");
> +		break;
> +
> +	default:
> +		DPTXHDCPMSG("2.x: Invalid HDCP2_OffSETADDR_WriteMessage !\n");
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static void dp_tx_hdcp2_rest_variable(struct mtk_hdcp_info *hdcp_info)
> +{
> +	hdcp_info->hdcp2_info.read_certrx = false;
> +	hdcp_info->hdcp2_info.read_h_prime = false;
> +	hdcp_info->hdcp2_info.read_pairing = false;
> +	hdcp_info->hdcp2_info.read_l_prime = false;
> +	hdcp_info->hdcp2_info.ks_exchange_done = false;
> +	hdcp_info->hdcp2_info.read_v_prime = false;
> +}
> +
> +int dp_tx_hdcp2_fsm(struct mtk_hdcp_info *hdcp_info)
> +{
> +	static u32 timeout_value;
> +	static u8 pre_main;
> +	static u8 pre_sub;
> +	static u32 pre_time;
> +	int err_code = HDCP_ERR_NONE;
> +	bool stored = false;
> +	u32 time;
> +	int ret = 0;

Avoid double assignments, don't initialize ret to 0 here.

> +	bool tmp = false;
> +
> +	if (pre_main != hdcp_info->hdcp2_info.hdcp_handler.main_state ||
> +	    hdcp_info->hdcp2_info.hdcp_handler.sub_state != pre_sub) {
> +		DPTXHDCPMSG("2.x: Port(M : S)= (%d, %d)",
> +			    hdcp_info->hdcp2_info.hdcp_handler.main_state,
> +			    hdcp_info->hdcp2_info.hdcp_handler.sub_state);
> +		pre_main = hdcp_info->hdcp2_info.hdcp_handler.main_state;
> +		pre_sub = hdcp_info->hdcp2_info.hdcp_handler.sub_state;
> +	}
> +
> +	switch (hdcp_info->hdcp2_info.hdcp_handler.main_state) {
> +	case HDCP2_MS_H1P1:
> +		/* HDCP2_MS_H1P1 */
> +		/* HDCP_2_2_AUTH_FAIL */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AUTH_FAIL) {
> +			pr_err("2.x: Authentication Fail!\n");
> +			dp_tx_hdcp2_enable_auth(hdcp_info, false);
> +			hdcp_info->auth_status = AUTH_FAIL;
> +		}
> +		break;
> +
> +	case HDCP2_MS_A0F0:
> +		/* HDCP2_MS_A0F0 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_NULL_MSG) {
> +			if (!hdcp_info->hdcp2_info.enable) {
> +				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_H1P1, HDCP_2_2_AUTH_FAIL);
> +				DPTXHDCPMSG("2.x: Sink Doesn't Support Hdcp2x!\n");
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_init(hdcp_info);
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1, HDCP_2_2_NULL_MSG);
> +			DPTXHDCPMSG("2.x: Sink Support Hdcp2x!\n");
> +		}
> +		break;
> +
> +	case HDCP2_MS_A1F1:
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_NULL_MSG) {
> +			if (hdcp_info->hdcp2_info.retry_count >= HDCP2_TX_RETRY_CNT) {
> +				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_H1P1, HDCP_2_2_AUTH_FAIL);
> +				pr_err("2.x: Try Max Count\n");
> +				break;
> +			}
> +
> +			hdcp_info->hdcp2_info.retry_count++;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1, HDCP_2_2_AKE_INIT);
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_INIT */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AKE_INIT) {
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_AKE_INIT);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +			dp_tx_hdcp2_rest_variable(hdcp_info);
> +			hdcp_info->hdcp2_info.read_certrx = true;
> +
> +			hdcp_info->hdcp2_info.hdcp_handler.send_ake_init = true;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1, HDCP_2_2_AKE_SEND_CERT);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_SEND_CERT */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AKE_SEND_CERT) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time < HDCP_2_2_CERT_TIMEOUT_MS) {
> +				msleep(20);
> +				break;
> +			}
> +			if (hdcp_info->hdcp2_info.read_certrx)
> +				dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_AKE_SEND_CERT);
> +
> +			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			ret = tee_ake_certificate(hdcp_info,
> +						  (u8 *)&hdcp_info->hdcp2_info.hdcp_rx.cert_rx,
> +						  &stored,
> +				hdcp_info->hdcp2_info.ake_stored_km.e_kh_km_m +
> +				HDCP_2_2_E_KH_KM_LEN,
> +				hdcp_info->hdcp2_info.ake_stored_km.e_kh_km_m);
> +
> +			if (ret != RET_COMPARE_PASS) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			hdcp_info->hdcp2_info.hdcp_handler.stored_km = stored;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> +					      hdcp_info->hdcp2_info.hdcp_handler.stored_km ?
> +					HDCP_2_2_AKE_STORED_KM :
> +					HDCP_2_2_AKE_NO_STORED_KM);
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_NO_STORED_KM */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AKE_NO_STORED_KM) {
> +			DPTXHDCPMSG("2.x: Get Km, derive Ekpub(km)\n");
> +
> +			tee_enc_rsaes_oaep(hdcp_info,
> +					   hdcp_info->hdcp2_info.hdcp_tx.no_stored_km.e_kpub_km);
> +			/* Prepare e_kpub_km to send */
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_AKE_NO_STORED_KM);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1, HDCP_2_2_AKE_SEND_HPRIME);
> +			timeout_value = HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_STORED_KM */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AKE_STORED_KM) {
> +			/* Prepare ekh_km & M to send */
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_AKE_STORED_KM);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			err_code = HDCP_ERR_NONE;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1, HDCP_2_2_AKE_SEND_HPRIME);
> +			timeout_value = HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_SEND_HPRIME */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AKE_SEND_HPRIME) {
> +			if (hdcp_info->hdcp2_info.read_h_prime)
> +				dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_AKE_SEND_HPRIME);
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > timeout_value) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			ret = tee_ake_h_prime(hdcp_info,
> +					      hdcp_info->hdcp2_info.hdcp_tx.ake_init.r_tx,
> +					      hdcp_info->hdcp2_info.hdcp_rx.send_cert.r_rx,
> +				hdcp_info->hdcp2_info.hdcp_rx.send_cert.rx_caps,
> +				(u8 *)&hdcp_info->hdcp2_info.hdcp_tx.tx_caps,
> +				hdcp_info->hdcp2_info.hdcp_rx.send_hprime.h_prime,
> +				HDCP_2_2_H_PRIME_LEN);
> +			if (ret != RET_COMPARE_PASS) {
> +				if (hdcp_info->hdcp2_info.hdcp_handler.stored_km)
> +					tee_clear_paring(hdcp_info);
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (hdcp_info->hdcp2_info.hdcp_handler.stored_km)
> +				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A2F2, HDCP_2_2_LC_INIT);
> +			else
> +				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> +						      HDCP_2_2_AKE_SEND_PAIRING_INFO);
> +
> +			pre_time = mtk_dp_get_system_time();
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_SEND_PAIRING_INFO */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> +			HDCP_2_2_AKE_SEND_PAIRING_INFO) {
> +			if (hdcp_info->hdcp2_info.read_pairing)
> +				dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_AKE_SEND_PAIRING_INFO);
> +
> +			/* Ekh_Km must be available less than 200ms, Give mode time for some Rx */
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time >	HDCP_2_2_PAIRING_TIMEOUT_MS * 2) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			/* Store m, km, Ekh(km) */
> +			tee_ake_paring(hdcp_info,
> +				       hdcp_info->hdcp2_info.hdcp_rx.pairing_info.e_kh_km);
> +
> +			hdcp_info->hdcp2_info.hdcp_handler.send_pair = true;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A2F2, HDCP_2_2_LC_INIT);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +		break;
> +
> +	case HDCP2_MS_A2F2:
> +		/* HDCP2_MS_A2F2 */
> +		/* HDCP_2_2_LC_INIT */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_LC_INIT) {
> +			/* prepare Rn to send */
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_LC_INIT);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +			hdcp_info->hdcp2_info.hdcp_handler.send_lc_init = true;
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A2F2, HDCP_2_2_LC_SEND_LPRIME);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A2F2 */
> +		/* HDCP_2_2_LC_SEND_LPRIME */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_LC_SEND_LPRIME) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time < HDCP_2_2_DP_HPRIME_READ_TIMEOUT_MS)
> +				break;
> +
> +			if (hdcp_info->hdcp2_info.read_l_prime)
> +				dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_LC_SEND_LPRIME);
> +
> +			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			ret = tee_lc_l_prime(hdcp_info, hdcp_info->hdcp2_info.hdcp_tx.lc_init.r_n,
> +					     hdcp_info->hdcp2_info.hdcp_rx.send_lprime.l_prime,
> +					     HDCP_2_2_L_PRIME_LEN);
> +			if (ret != RET_COMPARE_PASS) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			DPTXHDCPMSG("2.x: L' is PASS!!\n");
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A3F3, HDCP_2_2_NULL_MSG);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +		break;
> +
> +	case HDCP2_MS_A3F3:
> +		/* HDCP2_MS_A3F3 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_NULL_MSG) {
> +			tee_ske_enc_ks(hdcp_info, hdcp_info->hdcp2_info.hdcp_tx.send_eks.riv,
> +				       hdcp_info->hdcp2_info.hdcp_tx.send_eks.e_dkey_ks);
> +
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_SKE_SEND_EKS);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info->hdcp2_info.repeater)
> +				dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_STREAM_TYPE);
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A3F3, HDCP_2_2_SKE_SEND_EKS);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A3F3 */
> +		/* HDCP_2_2_SKE_SEND_EKS */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_SKE_SEND_EKS) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time >= HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN)
> +				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A4F4, HDCP_2_2_NULL_MSG);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A4F4:
> +		/* HDCP2_MS_A4F4 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_NULL_MSG) {
> +			if (!hdcp_info->hdcp2_info.repeater) {
> +				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A5F5, HDCP_2_2_AUTH_DONE);
> +				break;
> +			}
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A6F6,
> +					      HDCP_2_2_REP_SEND_RECVID_LIST);
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +		break;
> +
> +	case HDCP2_MS_A5F5:
> +		/* HDCP2_MS_A5F5 */
> +		/* HDCP_2_2_AUTH_DONE */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_AUTH_DONE) {
> +			DPTXHDCPMSG("2.x: Authentication done!\n");
> +			hdcp_info->auth_status = AUTH_PASS;
> +			hdcp_info->hdcp2_info.retry_count = 0;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A5F5, HDCP_2_2_NULL_MSG);
> +			dp_tx_hdcp2_enable_auth(hdcp_info, true);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A6F6:
> +		/* HDCP2_MS_A6F6 */
> +		/* HDCP_2_2_REP_SEND_RECVID_LIST */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> +			HDCP_2_2_REP_SEND_RECVID_LIST) {
> +			if (hdcp_info->hdcp2_info.read_v_prime)
> +				dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_REP_SEND_RECVID_LIST);
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > HDCP_2_2_RECVID_LIST_TIMEOUT_MS) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			pre_time = mtk_dp_get_system_time();
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A7F7,
> +					      HDCP_2_2_REP_VERIFY_RECVID_LIST);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A7F7:
> +		/* HDCP2_MS_A7F7 */
> +		/* HDCP_2_2_REP_VERIFY_RECVID_LIST */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> +			HDCP_2_2_REP_VERIFY_RECVID_LIST) {
> +			if ((hdcp_info->hdcp2_info.hdcp_rx.receiverid_list.rx_info[1]
> +				& (BIT(2) | BIT(3))) != 0) {
> +				pr_err("2.x: DEVS_EXCEEDED or CASCADE_EXCEDDED!\n");
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			/* check seqNumV here */
> +			tmp = dp_tx_hdcp2_check_seq_num_v(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			tmp = dp_tx_hdcp2_recv_rep_auth_send_recv_id_list(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A8F8, HDCP_2_2_REP_SEND_ACK);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A8F8:
> +		/* HDCP2_MS_A8F8 */
> +		/* HDCP_2_2_REP_SEND_ACK */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_REP_SEND_ACK) {
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_REP_SEND_ACK);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > HDCP2_REP_SEND_ACK) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A9F9, HDCP_2_2_REP_STREAM_MANAGE);
> +			hdcp_info->hdcp2_info.hdcp_handler.retry_cnt = 0;
> +		}
> +		break;
> +
> +	case HDCP2_MS_A9F9:
> +		/* HDCP2_MS_A9F9 */
> +		/* HDCP_2_2_REP_STREAM_MANAGE */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_REP_STREAM_MANAGE) {
> +			tmp = dp_tx_hdcp2_process_rep_auth_stream_manage(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info, HDCP_2_2_REP_STREAM_MANAGE);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			pre_time = mtk_dp_get_system_time();
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg = false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A9F9,
> +					      HDCP_2_2_REP_STREAM_READY);
> +		}
> +
> +		/* HDCP2_MS_A9F9 */
> +		/* HDCP_2_2_REP_STREAM_READY */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state == HDCP_2_2_REP_STREAM_READY) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time <= HDCP_2_2_STREAM_READY_TIMEOUT_MS / 2)
> +				break;
> +
> +			dp_tx_hdcp2_read_msg(hdcp_info, HDCP_2_2_REP_STREAM_READY);
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > HDCP_2_2_STREAM_READY_TIMEOUT_MS) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info->hdcp2_info.hdcp_handler.recv_msg) {
> +				if (hdcp_info->hdcp2_info.hdcp_handler.retry_cnt
> +					>= HDCP2_STREAM_MANAGE_RETRY_CNT) {
> +					err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +					dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +					break;
> +				}
> +
> +				hdcp_info->hdcp2_info.hdcp_handler.retry_cnt++;
> +
> +				dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A9F9,
> +						      HDCP_2_2_REP_STREAM_READY);
> +				break;
> +			}
> +
> +			tmp = dp_tx_hdcp2_recv_rep_auth_stream_ready(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A5F5, HDCP_2_2_AUTH_DONE);
> +		}
> +		break;
> +
> +	default:
> +		err_code = HDCP_ERR_UNKNOWN_STATE;
> +		dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +		break;
> +	}
> +
> +	return err_code;
> +}
> +
> +void dp_tx_hdcp2_set_start_auth(struct mtk_hdcp_info *hdcp_info, bool enable)
> +{
> +	hdcp_info->hdcp2_info.enable = enable;
> +
> +	if (enable) {
> +		hdcp_info->auth_status = AUTH_INIT;
> +		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0, HDCP_2_2_NULL_MSG);
> +	} else {
> +		hdcp_info->auth_status = AUTH_ZERO;
> +		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_H1P1, HDCP_2_2_NULL_MSG);
> +		dp_tx_hdcp2_enable_auth(hdcp_info, false);
> +	}
> +
> +	hdcp_info->hdcp2_info.retry_count = 0;
> +}
> +
> +bool dp_tx_hdcp2_support(struct mtk_hdcp_info *hdcp_info)
> +{
> +	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
> +	u8 tmp[3];
> +	int ret;
> +
> +	drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RX_CAPS_OFFSET, tmp, HDCP_2_2_RXCAPS_LEN);
> +
> +	if (HDCP_2_2_DP_HDCP_CAPABLE(tmp[2]) && tmp[0] == HDCP_2_2_RX_CAPS_VERSION_VAL) {
> +		hdcp_info->hdcp2_info.enable = true;
> +		hdcp_info->hdcp2_info.repeater = tmp[2] & BIT(0);
> +	} else {
> +		hdcp_info->hdcp2_info.enable = false;

if (!HDCP_2_2_DP_HDCP_CAPABLE(tmp[2]) || tmp[0] != HDCP_2_2_RX_CAPS_VERSION_VAL) {
	hdcp_info->hdcp2_info.enable = false;
	return false;
}

hdcp_info->hdcp2_info.enable = true;
hdcp_info->hdcp2_info.repeater = tmp[2] & BIT(0);

> +	}
> +
> +	DPTXHDCPMSG("2.x: CAPABLE: %d, Reapeater: %d\n", hdcp_info->hdcp2_info.enable,
> +		    hdcp_info->hdcp2_info.repeater);
> +
> +	if (!hdcp_info->hdcp2_info.enable)
> +		return false;
> +
> +	ret = tee_add_device(hdcp_info, HDCP_VERSION_2X);
> +	if (ret != RET_SUCCESS) {
> +		pr_err("2.x: HDCP TA has some error\n");
> +		hdcp_info->hdcp2_info.enable = false;

		return false;

> +	}
> +

	return true;

> +	return hdcp_info->hdcp2_info.enable;
> +}
> +
> +bool dp_tx_hdcp2_irq(struct mtk_hdcp_info *hdcp_info)
> +{
> +	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp, hdcp_info);
> +	u8 rx_status = 0;
> +
> +	drm_dp_dpcd_read(&mtk_dp->aux, DP_HDCP_2_2_REG_RXSTATUS_OFFSET, &rx_status,
> +			 HDCP_2_2_DP_RXSTATUS_LEN);
> +
> +	if (rx_status & BIT(0)) {

#define SOMETHING BIT(0) please

> +		DPTXHDCPMSG("2.x: READY_BIT0 Ready!\n");
> +		hdcp_info->hdcp2_info.read_v_prime = true;
> +	}
> +
> +	if (rx_status & BIT(1)) {
> +		DPTXHDCPMSG("2.x: H'_AVAILABLE Ready!\n");
> +		hdcp_info->hdcp2_info.read_h_prime = true;
> +	}
> +
> +	if (rx_status & BIT(2)) {
> +		DPTXHDCPMSG("2.x: PAIRING_AVAILABLE Ready!\n");
> +		hdcp_info->hdcp2_info.read_pairing = true;
> +	}
> +
> +	if (rx_status & BIT(4) || rx_status & BIT(3)) {
> +		DPTXHDCPMSG("2.x: Re-Auth HDCP2X!\n");
> +		dp_tx_hdcp2_set_start_auth(hdcp_info, true);
> +		mtk_dp_authentication(hdcp_info);
> +	}
> +
> +	return true;
> +}
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h b/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h
> new file mode 100644
> index 000000000000..df309d3dcc6e
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_dp_hdcp2.h
> @@ -0,0 +1,52 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019-2024 MediaTek Inc.
> + */
> +
> +#ifndef _MTK_dp_HDCP2_H_
> +#define _MTK_dp_HDCP2_H_
> +
> +#include "tlc_dp_hdcp.h"
> +
> +/* Timeout relative */
> +#define HDCP2_REP_SEND_ACK 2000
> +
> +/* Patch for QD980 LLCTS */
> +#define HDCP2_TX_RETRY_CNT 3
> +#define HDCP2_TX_LC_RETRY_CNT 1023
> +#define HDCP2_STREAM_MANAGE_RETRY_CNT 8
> +
> +/* HDCP2.2 Msg IDs */
> +#define HDCP_2_2_STREAM_TYPE 20
> +#define HDCP_2_2_REP_VERIFY_RECVID_LIST 21
> +#define HDCP_2_2_AUTH_FAIL 22
> +#define HDCP_2_2_AUTH_DONE 23
> +
> +enum ENUM_HDCP2TX_MAIN_STATE {

lower case names for enums please.

> +	HDCP2_MS_H1P1 = 0,
> +	HDCP2_MS_A0F0 = 1,
> +	HDCP2_MS_A1F1 = 2,
> +	HDCP2_MS_A2F2 = 3,
> +	HDCP2_MS_A3F3 = 4,
> +	HDCP2_MS_A4F4 = 5,
> +	HDCP2_MS_A5F5 = 6,
> +	HDCP2_MS_A6F6 = 7,
> +	HDCP2_MS_A7F7 = 8,
> +	HDCP2_MS_A8F8 = 9,
> +	HDCP2_MS_A9F9 = 10
> +};
> +
> +enum ENUM_HDCP_ERR_CODE {
> +	HDCP_ERR_NONE = 0,
> +	HDCP_ERR_UNKNOWN_STATE,
> +	HDCP_ERR_SEND_MSG_FAIL,
> +	HDCP_ERR_RESPONSE_TIMEROUT,
> +	HDCP_ERR_PROCESS_FAIL
> +};
> +
> +int dp_tx_hdcp2_fsm(struct mtk_hdcp_info *hdcp_info);
> +void dp_tx_hdcp2_set_start_auth(struct mtk_hdcp_info *hdcp_info, bool enable);
> +bool dp_tx_hdcp2_support(struct mtk_hdcp_info *hdcp_info);
> +bool dp_tx_hdcp2_irq(struct mtk_hdcp_info *hdcp_info);
> +
> +#endif /* _MTK_dp_HDCP2_H_ */
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp_reg.h b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> index 709b79480693..5cf5059762ed 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> @@ -1,8 +1,9 @@
>   /* SPDX-License-Identifier: GPL-2.0 */
>   /*
> - * Copyright (c) 2019-2022 MediaTek Inc.
> + * Copyright (c) 2019-2024 MediaTek Inc.
>    * Copyright (c) 2022 BayLibre
>    */
> +
>   #ifndef _MTK_DP_REG_H_
>   #define _MTK_DP_REG_H_
>   
> @@ -277,6 +278,7 @@
>   #define HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT		BIT(1)
>   #define MTK_DP_TRANS_P0_34A4				0x34a4
>   #define LANE_NUM_DP_TRANS_P0_MASK				GENMASK(3, 2)
> +#define MTK_DP_TRANS_P0_34D0                0x34D0
>   #define MTK_DP_TRANS_P0_3540				0x3540
>   #define FEC_EN_DP_TRANS_P0_MASK					BIT(0)
>   #define FEC_CLOCK_EN_MODE_DP_TRANS_P0				BIT(3)
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 4e3d9f7b4d8c..7f4a8f7dfce2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -25,6 +25,7 @@
>   #include <drm/drm_edid.h>
>   #include <drm/drm_of.h>
>   #include <drm/drm_simple_kms_helper.h>
> +#include <drm/display/drm_hdcp_helper.h>
>   
>   #include "mtk_disp_drv.h"
>   #include "mtk_dpi_regs.h"
> @@ -820,6 +821,8 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
>   	}
>   	drm_connector_attach_encoder(dpi->connector, &dpi->encoder);
>   
> +	drm_connector_attach_content_protection_property(dpi->connector, true);
> +
>   	return 0;
>   
>   err_cleanup:

This driver needs lots of cleanups to reach upstream quality.

Regards,
Angelo



From angelogioacchino.delregno at collabora.com  Tue Feb  6 07:34:29 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 16:34:29 +0100
Subject: [PATCH v2 1/3] Subject: [PATCH] drm/mediatek/dp: Add tee client
 application for HDCP feature
In-Reply-To: <20240205055055.25340-2-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
 <20240205055055.25340-2-mac.shen@mediatek.com>
Message-ID: <65e5e4fa-3c09-4fa1-922c-0cc9f891e174@collabora.com>

Il 05/02/24 06:50, mac.shen ha scritto:
> Add tee client application which will be used for
> HDCP 1.x and 2.x authentication in DisplayPort.
> 
> Changes in v2:
> - remove ca folder, and change file name with lower case
> - refine the tci_t structure to make the data to tee can
>    through this structure
> - remove aux and regs from mtk_hdcp_info structure
> - remove some definitions, and use the definitions in
>    include/drm/drm_hdcp.h
> - remove useless code
> per suggestion from the previous thread:
> https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
> 9218a545c46.camel at mediatek.com/
> 
> Signed-off-by: mac.shen <mac.shen at mediatek.com>
> ---
>   drivers/gpu/drm/mediatek/Makefile      |   5 +-
>   drivers/gpu/drm/mediatek/tci.h         | 156 +++++++
>   drivers/gpu/drm/mediatek/tlc_dp_hdcp.c | 598 +++++++++++++++++++++++++
>   drivers/gpu/drm/mediatek/tlc_dp_hdcp.h | 414 +++++++++++++++++
>   4 files changed, 1172 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/gpu/drm/mediatek/tci.h
>   create mode 100644 drivers/gpu/drm/mediatek/tlc_dp_hdcp.c
>   create mode 100644 drivers/gpu/drm/mediatek/tlc_dp_hdcp.h
> 
> diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
> index d4d193f60271..c80e6c2f9336 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -26,4 +26,7 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
>   
>   obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
>   
> -obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o
> +mtk-dp-objs := tlc_dp_hdcp.o \
> +		  mtk_dp.o
> +
> +obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk-dp.o
> diff --git a/drivers/gpu/drm/mediatek/tci.h b/drivers/gpu/drm/mediatek/tci.h
> new file mode 100644
> index 000000000000..f2239ea3ffbf
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/tci.h
> @@ -0,0 +1,156 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019-2024 MediaTek Inc.
> + */
> +
> +#ifndef _TCI_H_
> +#define _TCI_H_
> +
> +#include <drm/display/drm_hdcp.h>
> +
> +#define CMD_DEVICE_ADDED        1
> +#define CMD_DEVICE_REMOVE       2
> +#define CMD_WRITE_VAL           3
> +#define CMD_DEVICE_CLEAN        4
> +#define CMD_ENABLE_ENCRYPT      5
> +
> +/* V1.3 */
> +#define CMD_CALCULATE_LM        11
> +#define CMD_COMPARE_R0          12
> +#define CMD_COMPARE_V1          13
> +#define CMD_GET_AKSV            14
> +
> +/* V2.2 */
> +#define CMD_AKE_CERTIFICATE     20
> +#define CMD_ENC_KM              21
> +#define CMD_AKE_H_PRIME         22
> +#define CMD_AKE_PARING          23
> +#define CMD_LC_L_PRIME          24
> +#define CMD_COMPARE_L           25
> +#define CMD_SKE_CAL_EKS         26
> +
> +#define CMD_COMPARE_V2          27
> +#define CMD_COMPARE_M           28
> +
> +/* Need remove in furture */
> +#define CMD_LOAD_KEY            50
> +
> +#define RET_COMPARE_PASS 0
> +#define RET_COMPARE_FAIL 1
> +#define RET_NEW_DEVICE 2
> +#define RET_STORED_DEVICE 3
> +
> +#define TYPE_HDCP_PARAM_AN 10
> +#define TYPE_HDCP_PARAM_RST_1 11
> +#define TYPE_HDCP_PARAM_RST_2 12
> +#define TYPE_HDCP_ENABLE_ENCRYPT 13
> +#define TYPE_HDCP_DISABLE_ENCRYPT 14
> +
> +#define TYPE_HDCP13_KEY 20
> +#define TYPE_HDCP22_KEY 21
> +
> +// reserved:2

Please, C-style comments only.

> +#define HDCP2_CERTRX_LEN (HDCP_2_2_RECEIVER_ID_LEN + HDCP_2_2_K_PUB_RX_LEN + \
> +	2 + HDCP_2_2_DCP_LLC_SIG_LEN)
> +// version:1
> +#define HDCP_2_2_TXCAPS_LEN (HDCP_2_2_TXCAP_MASK_LEN + 1)
> +#define PARAM_LEN 1024
> +
> +#define TCI_LENGTH sizeof(struct tci_t)
> +
> +struct cmd_hdcp_init_for_verion_t {
> +	u32 version;
> +	bool need_load_key;
> +};
> +
> +struct cmd_hdcp_write_val_t {
> +	u8 type;
> +	u8 len;
> +	u8 val[DRM_HDCP_AN_LEN];
> +};
> +
> +struct cmd_hdcp_calculate_lm_t {
> +	u8 bksv[DRM_HDCP_KSV_LEN];
> +};
> +
> +struct cmd_hdcp_get_aksv_t {
> +	u8 aksv[DRM_HDCP_KSV_LEN];
> +};
> +
> +struct cmd_hdcp_ake_certificate_t {
> +	u8 certification[HDCP2_CERTRX_LEN];
> +	bool stored;
> +	u8 m[HDCP_2_2_E_KH_KM_M_LEN - HDCP_2_2_E_KH_KM_LEN];
> +	u8 ekm[HDCP_2_2_E_KH_KM_LEN];
> +};
> +
> +struct cmd_hdcp_ake_paring_t {
> +	u8 ekm[HDCP_2_2_E_KH_KM_LEN];
> +};
> +
> +struct cmd_hdcp_enc_km_t {
> +	u8 enc_km[HDCP_2_2_E_KPUB_KM_LEN];
> +};
> +
> +struct cmd_hdcp_ake_h_prime_t {
> +	u8 rtx[HDCP_2_2_RTX_LEN];
> +	u8 rrx[HDCP_2_2_RRX_LEN];
> +	u8 rx_caps[HDCP_2_2_RXCAPS_LEN];
> +	u8 tx_caps[HDCP_2_2_TXCAPS_LEN];
> +	u32 rx_h_len;
> +	u8 rx_h[HDCP_2_2_H_PRIME_LEN];
> +};
> +
> +struct cmd_hdcp_lc_l_prime_t {
> +	u8 rn[HDCP_2_2_RN_LEN];
> +	u32 rx_l_len;
> +	u8 rx_l[HDCP_2_2_L_PRIME_LEN];
> +};
> +
> +struct cmd_hdcp_ske_eks_t {
> +	u8 riv[HDCP_2_2_RIV_LEN];
> +	u32 eks_len;
> +	u32 eks;
> +};
> +
> +struct cmd_hdcp_compare_t {
> +	u32 rx_val_len;
> +	u8 rx_val[HDCP_2_2_MPRIME_LEN];
> +	u32 param_len;
> +	u8 param[PARAM_LEN];
> +	u32 out_len;
> +	u32 out;
> +};
> +
> +union tci_cmd_body_t {
> +	/* Init with special HDCP version */
> +	struct cmd_hdcp_init_for_verion_t cmd_hdcp_init_for_verion;
> +	/* Write uint32 data to hw */
> +	struct cmd_hdcp_write_val_t cmd_hdcp_write_val;
> +	/* Get aksv */
> +	struct cmd_hdcp_get_aksv_t cmd_hdcp_get_aksv;
> +	/* Calculate r0 */
> +	struct cmd_hdcp_calculate_lm_t cmd_hdcp_calculate_lm;
> +	/* Generate signature for certificate */
> +	struct cmd_hdcp_ake_certificate_t cmd_hdcp_ake_certificate;
> +	/* To store ekm */
> +	struct cmd_hdcp_ake_paring_t cmd_hdcp_ake_paring;
> +	/* Encrypt km for V2.2 */
> +	struct cmd_hdcp_enc_km_t cmd_hdcp_enc_km;
> +	/* Compute H prime */
> +	struct cmd_hdcp_ake_h_prime_t cmd_hdcp_ake_h_prime;
> +	/* Compute L prime */
> +	struct cmd_hdcp_lc_l_prime_t cmd_hdcp_lc_l_prime;
> +	/* Compute eks */
> +	struct cmd_hdcp_ske_eks_t cmd_hdcp_ske_eks;
> +	/* Compare */
> +	struct cmd_hdcp_compare_t cmd_hdcp_compare;
> +} __packed;
> +
> +struct tci_t {
> +	u32 command_id;
> +	u32 return_code;
> +	union tci_cmd_body_t cmd_body;
> +};
> +
> +#endif /* _TCI_H_ */
> diff --git a/drivers/gpu/drm/mediatek/tlc_dp_hdcp.c b/drivers/gpu/drm/mediatek/tlc_dp_hdcp.c
> new file mode 100644
> index 000000000000..147329324648
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/tlc_dp_hdcp.c
> @@ -0,0 +1,598 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019-2024 MediaTek Inc.
> + */
> +
> +#include <linux/types.h>
> +#include <linux/string.h>
> +#include <linux/slab.h>
> +#include "tlc_dp_hdcp.h"
> +
> +#define DEFAULT_WRITE_VAL_LEN 1
> +#define DEFAULT_WRITE_VAL 0
> +
> +/*
> + * TA_FTPM_UUID: 99975014-3c7c-54ea-8487-a80d215ea92c
> + *
> + * Randomly generated, and must correspond to the GUID on the TA side.
> + * Defined here in the reference implementation:
> + * https://github.com/microsoft/ms-tpm-20-ref/blob/master/Samples/ARM32-FirmwareTPM/optee_ta/fTPM/include/fTPM.h#L42
> + */
> +static const uuid_t dp_ta_uuid =
> +	UUID_INIT(0x99975014, 0x3c7c, 0x54ea,
> +		  0x84, 0x87, 0xa8, 0x0d, 0x21, 0x5e, 0xa9, 0x2c);
> +
> +/**
> + * dp_tee_op_send() - send dp commands through the TEE shared memory.
> + * @len:	the number of bytes to send.
> + *
> + * Return:
> + *	In case of success, returns 0.
> + *	On failure, -errno

I think that's not what you want as final format, please check the documentation.

https://docs.kernel.org/doc-guide/kernel-doc.html#return-values

> + */
> +static int dp_tee_op_send(struct dp_tee_private *dp_tee_priv, size_t len, u32 cmd_id)
> +{
> +	int rc;
> +	u8 *temp_buf;
> +	struct tee_ioctl_invoke_arg transceive_args;
> +	struct tee_param command_params[4];
> +	struct tee_shm *shm = dp_tee_priv->shm;

Please reorder:

	struct tee_ioctl_invoke_arg transceive_args;
	struct tee_shm *shm = dp_tee_priv->shm;
	struct tee_param command_params[4];
	u8 *temp_buf;
	int rc;

> +
> +	if (len > MAX_COMMAND_SIZE) {
> +		TLCERR("%s: len=%zd exceeds MAX_COMMAND_SIZE supported by dp TA\n", __func__, len);
> +		return -EIO;
> +	}
> +
> +	memset(&transceive_args, 0, sizeof(transceive_args));
> +	memset(command_params, 0, sizeof(command_params));
> +	dp_tee_priv->resp_len = 0;
> +
> +	/* Invoke FTPM_OPTEE_TA_SUBMIT_COMMAND function of dp TA */
> +	transceive_args = (struct tee_ioctl_invoke_arg) {
> +		.func = cmd_id,
> +		.session = dp_tee_priv->session,
> +		.num_params = 4,
> +	};
> +
> +	/* Fill FTPM_OPTEE_TA_SUBMIT_COMMAND parameters */
> +	command_params[0] = (struct tee_param) {
> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
> +		.u.memref = {
> +			.shm = shm,
> +			.size = len,
> +			.shm_offs = 0,
> +		},
> +	};
> +
> +	command_params[1] = (struct tee_param) {
> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
> +		.u.memref = {
> +			.shm = shm,
> +			.size = MAX_RESPONSE_SIZE,
> +			.shm_offs = MAX_COMMAND_SIZE,
> +		},
> +	};
> +
> +	rc = tee_client_invoke_func(dp_tee_priv->ctx, &transceive_args, command_params);
> +	if (rc < 0 || transceive_args.ret != 0) {
> +		TLCERR("%s: invoke error: 0x%x\n", __func__, transceive_args.ret);
> +		return (rc < 0) ? rc : transceive_args.ret;
> +	}
> +
> +	temp_buf = tee_shm_get_va(shm, command_params[1].u.memref.shm_offs);
> +	if (IS_ERR(temp_buf)) {
> +		TLCERR("%s: tee_shm_get_va failed for receive\n", __func__);
> +		return PTR_ERR(temp_buf);
> +	}
> +
> +	/* Sanity checks look good, cache the response */
> +	memcpy(dp_tee_priv->resp_buf, temp_buf, MAX_RESPONSE_SIZE / 2);
> +	dp_tee_priv->resp_len = MAX_RESPONSE_SIZE / 2;
> +
> +	return 0;
> +}
> +
> +/*
> + * Check whether this driver supports the dp TA in the TEE instance
> + * represented by the params (ver/data) to this function.
> + */
> +static int dp_tee_match(struct tee_ioctl_version_data *ver, const void *data)
> +{
> +	/*
> +	 * Currently this driver only support GP Complaint OPTEE based dp TA
> +	 */
> +	if (ver->impl_id == TEE_IMPL_ID_OPTEE && ver->gen_caps & TEE_GEN_CAP_GP)
> +		return 1;
> +	else
> +		return 0;

/*
  * Check whether this driver supports the dp TA in the TEE instance
  * represented by the params (ver/data) to this function.
  *
  * Note that currently this driver only supports GP Compliant OPTEE
  * based dp TA.
  */
static int dp_tee_match(struct tee_ioctl_version_data *ver, const void *data)
{
	return ver->impl_id == TEE_IMPL_ID_OPTEE &&
	       ver->gen_caps & TEE_GEN_CAP_GP
}

That's shorter :-)

> +}
> +
> +int tee_add_device(struct mtk_hdcp_info *hdcp_info, u32 version)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = NULL;

You don't need this NULL assignment...

> +	struct tee_ioctl_open_session_arg sess_arg;
> +	struct tci_t *tci;

	struct tee_ioctl_open_session_arg sess_arg;
	struct dp_tee_private *dp_tee_priv;
	struct tci_t *tci;
	int rc;


> +
> +	if (hdcp_info->g_init)
> +		tee_remove_device(hdcp_info);
> +
> +	dp_tee_priv = kzalloc(sizeof(*dp_tee_priv), GFP_KERNEL);
> +	if (!dp_tee_priv) {
> +		kfree(dp_tee_priv);

There's no need to kfree something that couldn't be allocated.

> +		TLCERR("%s: tee_alloc_memory failed\n", __func__);
> +		return -ENOMEM;
> +	}
> +	hdcp_info->g_dp_tee_priv = dp_tee_priv;
> +
> +	/* Open context with TEE driver */
> +	dp_tee_priv->ctx = tee_client_open_context(NULL, dp_tee_match, NULL, NULL);
> +	if (IS_ERR(dp_tee_priv->ctx)) {

		/* We return -EPROBE_DEFER because ... why?!
		 * does it even make any sense to override this
		 * return value? I don't think so.
		 */
		if (PTR_ERR(dp_tee_priv->ctx) == -ENOENT)
			rc = -EPROBE_DEFER;
		else
			rc = PTR_ERR(dp_tee_priv->ctx);

		goto free_priv;
	}

> +		if (PTR_ERR(dp_tee_priv->ctx) == -ENOENT) {
> +			kfree(dp_tee_priv);
> +			return -EPROBE_DEFER;
> +		}
> +		kfree(dp_tee_priv);
> +		TLCERR("%s: tee_client_open_context failed\n", __func__);
> +		return PTR_ERR(dp_tee_priv->ctx);
> +	}
> +
> +	/* Open a session with dp TA */
> +	memset(&sess_arg, 0, sizeof(sess_arg));
> +	export_uuid(sess_arg.uuid, &dp_ta_uuid);
> +	sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
> +	sess_arg.num_params = 0;
> +
> +	rc = tee_client_open_session(dp_tee_priv->ctx, &sess_arg, NULL);
> +	if (rc < 0 || sess_arg.ret != 0) {
> +		kfree(dp_tee_priv);

We don't kfree here because the goto will take care of that already...
P.S.: same for the other instances

> +		TLCERR("tee_client_open_session failed, err=%x\n", sess_arg.ret);
> +		rc = -EINVAL;
> +		goto out_tee_session;
> +	}
> +	dp_tee_priv->session = sess_arg.session;
> +
> +	/* Allocate dynamic shared memory with dp TA */
> +	dp_tee_priv->shm = tee_shm_alloc_kernel_buf(dp_tee_priv->ctx, MAX_COMMAND_SIZE
> +	 + MAX_RESPONSE_SIZE);
> +	if (IS_ERR(dp_tee_priv->shm)) {
> +		kfree(dp_tee_priv);
> +		TLCERR("%s: tee_shm_alloc_kernel_buf failed\n", __func__);
> +		rc = -ENOMEM;
> +		goto out_shm_alloc;
> +	}
> +	TLCINFO("Register 8k share memory successfully, (%p)",
> +		dp_tee_priv->shm->kaddr);

Don't print pointer addresses, it won't mean anything for most people as there will
be randomization and - if not - could be used for a vulnerability.

Please, just don't.

> +
> +	/* Copy parameter for add new device */
> +	tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +	memset(tci, 0, TCI_LENGTH);
> +	tci->command_id = CMD_DEVICE_ADDED;
> +	tci->cmd_body.cmd_hdcp_init_for_verion.version = version;
> +	tci->cmd_body.cmd_hdcp_init_for_verion.need_load_key = true;
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_DEVICE_ADDED);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		tee_remove_device(hdcp_info);
> +		return rc;
> +	}
> +
> +	hdcp_info->g_init = true;
> +
> +	return rc;

If you intend to pass on a result of dp_tee_op_send, then pass that to a pointer
in the function param.

Here, you shall return 0.

> +
> +out_shm_alloc:
> +	tee_client_close_session(dp_tee_priv->ctx, dp_tee_priv->session);
> +out_tee_session:
> +	tee_client_close_context(dp_tee_priv->ctx);

free_priv:
	kfree(dp_tee_priv);

> +
> +	return rc;
> +}
> +
> +void tee_remove_device(struct mtk_hdcp_info *hdcp_info)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;

int rc goes here

> +
> +	if (!hdcp_info->g_init)
> +		return;
> +
> +	hdcp_info->g_init = false;
> +	memset(tci, 0, TCI_LENGTH);
> +	tci->command_id = CMD_DEVICE_REMOVE;
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_DEVICE_REMOVE);
> +	if (rc != 0)
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +
> +	/* Free the shared memory pool */
> +	tee_shm_free(dp_tee_priv->shm);
> +
> +	/* Close the existing session with fTPM TA */
> +	tee_client_close_session(dp_tee_priv->ctx, dp_tee_priv->session);
> +
> +	/* Close the context with TEE driver */
> +	tee_client_close_context(dp_tee_priv->ctx);
> +
> +	/* Free the memory */
> +	kfree(dp_tee_priv);
> +}
> +
> +int tee_clear_paring(struct mtk_hdcp_info *hdcp_info)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;

int rc goes here

> +
> +	/* Copy parameters */
> +	memset(tci, 0, TCI_LENGTH);
> +	tci->command_id = CMD_DEVICE_CLEAN;
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_DEVICE_CLEAN);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	return rc;

return 0;

> +}
> +
> +int tee_hdcp1x_set_tx_an(struct mtk_hdcp_info *hdcp_info, u8 *an_code)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_WRITE_VAL;
> +	tci->cmd_body.cmd_hdcp_write_val.len = DRM_HDCP_AN_LEN;
> +	tci->cmd_body.cmd_hdcp_write_val.type = TYPE_HDCP_PARAM_AN;
> +	memcpy(tci->cmd_body.cmd_hdcp_write_val.val, an_code, DRM_HDCP_AN_LEN);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_WRITE_VAL);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	return rc;
> +}
> +
> +int tee_hdcp_enable_encrypt(struct mtk_hdcp_info *hdcp_info, bool enable, u8 version)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_ENABLE_ENCRYPT;

	tci->cmd_body.cmd_hdcp_write_val.type = enable ? TYPE_HDCP_ENABLE_ENCRYPT : 
TYPE_HDCP_DISABLE_ENCRYPT;

> +	if (enable)
> +		tci->cmd_body.cmd_hdcp_write_val.type = TYPE_HDCP_ENABLE_ENCRYPT;
> +	else
> +		tci->cmd_body.cmd_hdcp_write_val.type = TYPE_HDCP_DISABLE_ENCRYPT;
> +
> +	/* Set HDCP version supportted by device */
> +	tci->cmd_body.cmd_hdcp_write_val.len = 1;
> +	tci->cmd_body.cmd_hdcp_write_val.val[0] = version;
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_ENABLE_ENCRYPT);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +

return 0.... here and everywhere else.

> +	return rc;
> +}
> +
> +int tee_hdcp1x_soft_rst(struct mtk_hdcp_info *hdcp_info)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_WRITE_VAL;
> +	tci->cmd_body.cmd_hdcp_write_val.type = TYPE_HDCP_PARAM_RST_1;
> +	/* No need input. Set default value 0 for check */
> +	tci->cmd_body.cmd_hdcp_write_val.len = DEFAULT_WRITE_VAL_LEN;
> +	memset(tci->cmd_body.cmd_hdcp_write_val.val, DEFAULT_WRITE_VAL, DEFAULT_WRITE_VAL_LEN);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_WRITE_VAL);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	return rc;
> +}
> +
> +int tee_hdcp2_soft_rst(struct mtk_hdcp_info *hdcp_info)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	tci->command_id = CMD_WRITE_VAL;
> +	tci->cmd_body.cmd_hdcp_write_val.type = TYPE_HDCP_PARAM_RST_2;
> +	/* No need input. Set default value 0 for check */

> +	tci->cmd_body.cmd_hdcp_write_val.len =
> +		DEFAULT_WRITE_VAL_LEN;

Fits in one line.

> +	memset(tci->cmd_body.cmd_hdcp_write_val.val, DEFAULT_WRITE_VAL, DEFAULT_WRITE_VAL_LEN);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_WRITE_VAL);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	return rc;
> +}
> +
> +/** V1.X **/
> +int tee_get_aksv(struct mtk_hdcp_info *hdcp_info, u8 *aksv)
> +{

Reorder the variables, here and everywhere else.

> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_GET_AKSV;
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_GET_AKSV);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	tci = (struct tci_t *)dp_tee_priv->resp_buf;

Use a different variable, otherwise this adds up confusion.

> +	memcpy(aksv, tci->cmd_body.cmd_hdcp_get_aksv.aksv, DRM_HDCP_KSV_LEN);
> +
> +	return rc;
> +}
> +
> +int tee_calculate_lm(struct mtk_hdcp_info *hdcp_info, u8 *bksv)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_CALCULATE_LM;
> +	memcpy(tci->cmd_body.cmd_hdcp_calculate_lm.bksv, bksv, DRM_HDCP_KSV_LEN);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_CALCULATE_LM);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	return rc;
> +}
> +
> +int tee_compare_r0(struct mtk_hdcp_info *hdcp_info, u8 *r0, u32 len)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_COMPARE_R0;
> +	tci->cmd_body.cmd_hdcp_compare.rx_val_len = len;
> +	memcpy(tci->cmd_body.cmd_hdcp_compare.rx_val, r0, len);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_COMPARE_R0);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	return rc;
> +}
> +
> +int tee_hdcp1x_compute_compare_v(struct mtk_hdcp_info *hdcp_info,
> +				 u8 *crypto_param, u32 param_len, u8 *rx_v)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_COMPARE_V1;
> +	tci->cmd_body.cmd_hdcp_compare.rx_val_len = 20;
> +	tci->cmd_body.cmd_hdcp_compare.param_len = param_len;
> +	memcpy(tci->cmd_body.cmd_hdcp_compare.rx_val, rx_v, 20);
> +	memcpy(tci->cmd_body.cmd_hdcp_compare.param, crypto_param, param_len);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_COMPARE_V1);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	return rc;
> +}
> +
> +/** V2.X **/
> +int tee_ake_certificate(struct mtk_hdcp_info *hdcp_info,
> +			u8 *certificate, bool *stored, u8 *out_m, u8 *out_ekm)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_AKE_CERTIFICATE;
> +	memcpy(tci->cmd_body.cmd_hdcp_ake_certificate.certification,
> +	       certificate, HDCP2_CERTRX_LEN);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_AKE_CERTIFICATE);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	TLCINFO("verify signature: result %d", rc);
> +	tci = (struct tci_t *)dp_tee_priv->resp_buf;
> +	*stored = tci->cmd_body.cmd_hdcp_ake_certificate.stored;
> +	memcpy(out_m, tci->cmd_body.cmd_hdcp_ake_certificate.m,
> +	       HDCP_2_2_E_KH_KM_M_LEN - HDCP_2_2_E_KH_KM_LEN);
> +	memcpy(out_ekm, tci->cmd_body.cmd_hdcp_ake_certificate.ekm, HDCP_2_2_E_KH_KM_LEN);
> +
> +	return rc;
> +}
> +
> +int tee_enc_rsaes_oaep(struct mtk_hdcp_info *hdcp_info, u8 *ekm)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_ENC_KM;
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_ENC_KM);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	tci = (struct tci_t *)dp_tee_priv->resp_buf;
> +	memcpy(ekm, tci->cmd_body.cmd_hdcp_enc_km.enc_km, HDCP_2_2_E_KPUB_KM_LEN);
> +
> +	return rc;
> +}
> +
> +int tee_ake_h_prime(struct mtk_hdcp_info *hdcp_info,
> +		    u8 *rtx, u8 *rrx, u8 *rx_caps, u8 *tx_caps, u8 *rx_h, u32 rx_h_len)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_AKE_H_PRIME;
> +	tci->cmd_body.cmd_hdcp_ake_h_prime.rx_h_len = rx_h_len;
> +
> +	memcpy(tci->cmd_body.cmd_hdcp_ake_h_prime.rtx, rtx, HDCP_2_2_RTX_LEN);
> +	memcpy(tci->cmd_body.cmd_hdcp_ake_h_prime.rrx, rrx, HDCP_2_2_RRX_LEN);
> +	memcpy(tci->cmd_body.cmd_hdcp_ake_h_prime.rx_caps, rx_caps, HDCP_2_2_RXCAPS_LEN);
> +	memcpy(tci->cmd_body.cmd_hdcp_ake_h_prime.tx_caps, tx_caps, HDCP_2_2_TXCAPS_LEN);
> +	memcpy(tci->cmd_body.cmd_hdcp_ake_h_prime.rx_h, rx_h, rx_h_len);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_AKE_H_PRIME);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	tci = (struct tci_t *)dp_tee_priv->resp_buf;
> +	return tci->return_code;
> +}
> +
> +int tee_ake_paring(struct mtk_hdcp_info *hdcp_info, u8 *rx_ekm)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_AKE_PARING;
> +	memcpy(tci->cmd_body.cmd_hdcp_ake_paring.ekm, rx_ekm, HDCP_2_2_E_KH_KM_LEN);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_AKE_PARING);
> +	if (rc != 0)
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +
> +	return rc;
> +}
> +
> +int tee_lc_l_prime(struct mtk_hdcp_info *hdcp_info, u8 *rn, u8 *rx_l, u32 len)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_LC_L_PRIME;
> +	memcpy(tci->cmd_body.cmd_hdcp_lc_l_prime.rn, rn, HDCP_2_2_RN_LEN);
> +	tci->cmd_body.cmd_hdcp_lc_l_prime.rx_l_len = len;
> +	memcpy(tci->cmd_body.cmd_hdcp_lc_l_prime.rx_l, rx_l, len);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_LC_L_PRIME);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	tci = (struct tci_t *)dp_tee_priv->resp_buf;
> +	return tci->return_code;
> +}
> +
> +int tee_ske_enc_ks(struct mtk_hdcp_info *hdcp_info, u8 *riv, u8 *eks)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +	u8 *share_buffer = NULL;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_SKE_CAL_EKS;
> +	memcpy(tci->cmd_body.cmd_hdcp_ske_eks.riv, riv, HDCP_2_2_RIV_LEN);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH + 16, CMD_SKE_CAL_EKS);
> +	if (rc != 0)
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +
> +	share_buffer = (u8 *)dp_tee_priv->resp_buf;
> +	memcpy(eks, share_buffer + TCI_LENGTH, 16);
> +
> +	return rc;
> +}
> +
> +int tee_hdcp2_compute_compare_v(struct mtk_hdcp_info *hdcp_info,
> +				u8 *crypto_param, u32 param_len, u8 *rx_v, u8 *tx_v)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +	u8 *share_buffer = NULL;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_COMPARE_V2;
> +	tci->cmd_body.cmd_hdcp_compare.rx_val_len = 16;
> +	tci->cmd_body.cmd_hdcp_compare.param_len = param_len;
> +	memcpy(tci->cmd_body.cmd_hdcp_compare.rx_val, rx_v, 16);
> +	memcpy(tci->cmd_body.cmd_hdcp_compare.param, crypto_param, param_len);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_COMPARE_V2);
> +	if (rc != 0) {
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +		return rc;
> +	}
> +
> +	share_buffer = (u8 *)dp_tee_priv->resp_buf;
> +	memcpy(tx_v, share_buffer + TCI_LENGTH, 16);
> +
> +	return rc;
> +}
> +
> +int tee_hdcp2_compute_compare_m(struct mtk_hdcp_info *hdcp_info,
> +				u8 *crypto_param, u32 param_len, u8 *rx_m)
> +{
> +	int rc;
> +	struct dp_tee_private *dp_tee_priv = hdcp_info->g_dp_tee_priv;
> +	struct tci_t *tci = (struct tci_t *)dp_tee_priv->shm->kaddr;
> +
> +	/* Copy parameters */
> +	tci->command_id = CMD_COMPARE_M;
> +	tci->cmd_body.cmd_hdcp_compare.rx_val_len = HDCP_2_2_MPRIME_LEN;
> +	tci->cmd_body.cmd_hdcp_compare.param_len = param_len;
> +	memcpy(tci->cmd_body.cmd_hdcp_compare.rx_val, rx_m, HDCP_2_2_MPRIME_LEN);
> +	memcpy(tci->cmd_body.cmd_hdcp_compare.param, crypto_param, param_len);
> +
> +	rc = dp_tee_op_send(dp_tee_priv, TCI_LENGTH, CMD_COMPARE_M);
> +	if (rc != 0)
> +		TLCERR("tee_op_send failed, error=%x\n", rc);
> +
> +	return rc;
> +}
> diff --git a/drivers/gpu/drm/mediatek/tlc_dp_hdcp.h b/drivers/gpu/drm/mediatek/tlc_dp_hdcp.h
> new file mode 100644
> index 000000000000..493d3c51a7a0
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/tlc_dp_hdcp.h
> @@ -0,0 +1,414 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019-2024 MediaTek Inc.
> + */
> +
> +#ifndef _TLC_DP_HDCP_H_
> +#define _TLC_DP_HDCP_H_
> +
> +#include <linux/printk.h>
> +#include <linux/tee_drv.h>
> +#include <linux/uuid.h>
> +#include <linux/types.h>
> +#include <linux/sched/clock.h>
> +#include <drm/display/drm_dp_helper.h>
> +#include "tci.h"
> +
> +#define TLCINFO(string, args...) pr_info("[TLC_HDCP]info: "string, ##args)
> +#define TLCERR(string, args...) pr_info("[TLC_HDCP]line:%d,err:%s:"string,\
> +	__LINE__, __func__, ##args)
> +
> +#define DPTXHDCPFUNC(fmt, arg...)		\
> +	pr_info("[DPTXHDCP][%s line:%d]"pr_fmt(fmt), __func__, __LINE__, ##arg)
> +#define DPTXHDCPMSG(fmt, arg...)                                  \
> +		pr_info("[DPTXHDCP]"pr_fmt(fmt), ##arg)
> +#define DPTXHDCPERR(fmt, arg...)                                  \
> +		pr_err("[DPTXHDCP]"pr_fmt(fmt), ##arg)

You don't need those print wrappers and you can just use pr_{info,err} where
needed in the code.
Also, dev_info/dev_err would be preferred.

> +
> +#define RET_SUCCESS 0

Unused (and anyway unneeded) definition: please remove.

> +
> +/**
> + * hdcp version definitions
> + */
> +#define HDCP_NONE                0x0 // No HDCP supported, no secure data path
> +#define HDCP_V1                  0x1 // HDCP version 1.0
> +#define HDCP_V2                  0x2 // HDCP version 2.0 Type 1
> +#define HDCP_V2_1                0x3 // HDCP version 2.1 Type 1
> +#define HDCP_V2_2                0x4 // HDCP version 2.2 Type 1
> +#define HDCP_V2_3                0x5 // HDCP version 2.3 Type 1

Please introduce definitions in the same commits where you use them.
Also, C-style comments please.

> +
> +/* Local display only(content required version use only) */
> +#define HDCP_LOCAL_DISPLAY_ONLY  0xf
> +#define HDCP_NO_DIGITAL_OUTPUT   0xff // No digital output
> +#define HDCP_DEFAULT             HDCP_NO_DIGITAL_OUTPUT // Default value
> +
> +#define HDCP_VERSION_1X 1
> +#define HDCP_VERSION_2X 2
> +
> +/* max. buffer size supported by dp  */
> +#define MAX_COMMAND_SIZE       4096
> +#define MAX_RESPONSE_SIZE      4096
> +
> +#define HDCP1X_REP_MAXDEVS 128
> +#define HDCP1X_V_LEN 20
> +#define HDCP1X_B_INFO_LEN 2
> +
> +#define HDCP2_K_LEN 2
> +#define HDCP2_STREAMID_TYPE_LEN 2
> +
> +enum HDCP_RESULT {
> +	AUTH_ZERO = 0,
> +	AUTH_PREPARE = 1,
> +	AUTH_INIT = 2,
> +	AUTH_PASS = 3,
> +	AUTH_FAIL = 4,
> +};
> +
> +struct dp_header {
> +	__be16 tag;
> +	__be32 length;
> +	union {
> +		__be32 ordinal;
> +		__be32 return_code;
> +	};
> +} __packed;
> +
> +/**
> + * struct dp_tee_private - fTPM's private data
> + * @session:  dp TA session identifier.
> + * @resp_len: cached response buffer length.
> + * @resp_buf: cached response buffer.
> + * @ctx:      TEE context handler.
> + * @shm:      Memory pool shared with fTPM TA in TEE.
> + */
> +struct dp_tee_private {
> +	u32 session;
> +	size_t resp_len;
> +	u8 resp_buf[MAX_RESPONSE_SIZE];
> +	struct tee_context *ctx;
> +	struct tee_shm *shm;
> +};
> +
> +struct hdcp2_info_tx {
> +	struct hdcp2_ake_init ake_init;
> +	struct hdcp2_ake_no_stored_km no_stored_km;
> +	struct hdcp2_ske_send_eks send_eks;
> +	struct hdcp2_lc_init lc_init;
> +	struct hdcp2_rep_stream_manage stream_manage;
> +	struct hdcp2_rep_send_ack send_ack;
> +	struct hdcp2_tx_caps tx_caps;
> +	u8 k[HDCP2_K_LEN];
> +	u8 stream_id_type[HDCP2_STREAMID_TYPE_LEN];
> +};
> +
> +struct hdcp2_info_rx {
> +	struct hdcp2_cert_rx cert_rx;
> +	struct hdcp2_ake_send_cert send_cert;
> +	struct hdcp2_rep_send_receiverid_list receiverid_list;
> +	struct hdcp2_ake_send_pairing_info pairing_info;
> +	struct hdcp2_rep_stream_ready stream_ready;
> +	struct hdcp2_ake_send_hprime send_hprime;
> +	struct hdcp2_lc_send_lprime send_lprime;
> +};
> +
> +struct hdcp2_handler {
> +	u8 main_state;
> +	u8 sub_state;
> +	u8 down_stream_dev_cnt;
> +	u8 hdcp_rx_ver;
> +	bool send_ake_init:1;
> +	bool get_recv_id_list:1;
> +	bool stored_km:1;
> +	bool send_lc_init:1;
> +	bool send_ack:1;
> +	bool sink_is_repeater:1;
> +	bool recv_msg:1;
> +	bool send_pair:1;
> +	u32 seq_num_v_cnt;
> +	u32 retry_cnt;
> +};
> +
> +struct hdcp1x_info {
> +	bool enable;
> +	bool repeater;
> +	bool r0_read;
> +	bool ksv_ready;
> +	bool max_cascade;
> +	bool max_devs;
> +	u8 b_status;
> +	u8 b_ksv[DRM_HDCP_KSV_LEN];
> +	u8 a_ksv[DRM_HDCP_KSV_LEN];
> +	u8 v[HDCP1X_V_LEN];
> +	u8 b_info[HDCP1X_B_INFO_LEN];
> +	u8 ksvfifo[DRM_HDCP_KSV_LEN * (HDCP1X_REP_MAXDEVS - 1)];
> +	u8 device_count;
> +	u8 retry_count;
> +	int main_states;
> +	int sub_states;
> +};
> +
> +struct hdcp2_info {
> +	struct hdcp2_info_tx hdcp_tx;
> +	struct hdcp2_info_rx hdcp_rx;
> +	struct hdcp2_ake_stored_km ake_stored_km;
> +	struct hdcp2_handler hdcp_handler;
> +	bool enable;
> +	bool repeater;
> +	bool read_certrx;
> +	bool read_h_prime;
> +	bool read_pairing;
> +	bool read_l_prime;
> +	bool ks_exchange_done;
> +	bool read_v_prime;
> +	u8 retry_count;
> +	u8 device_count;
> +	u8 stream_id_type;
> +};
> +
> +struct mtk_hdcp_info {
> +	u8 auth_status;
> +	bool g_init;
> +	u32 hdcp_content_type;
> +	u32 content_protection;
> +	struct dp_tee_private *g_dp_tee_priv;
> +	struct hdcp1x_info hdcp1x_info;
> +	struct hdcp2_info hdcp2_info;
> +};
> +
> +#ifdef __cplusplus
> +extern "C"

cplusplus?! This is the kernel, this is not a UAPI header and will never be, and
you don't need this ifdef at all.

> +{
> +#endif
> +
> +/*

Please use valid kerneldoc; here and everywhere else.

> + *Description:
> + *  A device connect and do some initializations.
> + *
> + *Input:
> + *  version: HDCP version
> + *
> + *Returns:
> + *  TEEC_SUCCESS success*
> + */
> +int tee_add_device(struct mtk_hdcp_info *hdcp_info, u32 version);
> +

Regards,
Angelo



From bjorn at kernel.org  Tue Feb  6 07:36:36 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Tue, 06 Feb 2024 16:36:36 +0100
Subject: [PATCH v12 19/25] irqchip/riscv-imsic: Add device MSI domain
 support for platform devices
In-Reply-To: <20240127161753.114685-20-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-20-apatel@ventanamicro.com>
Message-ID: <87le7xy58b.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

> The Linux platform MSI support allows per-device MSI domains so let
> us add a platform irqchip driver for RISC-V IMSIC which provides a
> base IRQ domain with MSI parent support for platform device domains.
>
> This driver assumes that the IMSIC state is already initialized by
> the IMSIC early driver.
>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>

[...]

> diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
> new file mode 100644
> index 000000000000..65791a6b0727
> --- /dev/null
> +++ b/drivers/irqchip/irq-riscv-imsic-platform.c
> @@ -0,0 +1,371 @@

[...]

> +static int imsic_irq_retrigger(struct irq_data *d)
> +{
> +	struct imsic_vector *vec = irq_data_get_irq_chip_data(d);
> +	struct imsic_local_config *local;
> +
> +	if (WARN_ON(vec == NULL))
> +		return -ENOENT;
> +
> +	local = per_cpu_ptr(imsic->global.local, vec->cpu);
> +	writel(vec->local_id, local->msi_va);

Change to writel_relaxed().



From bjorn at kernel.org  Tue Feb  6 07:39:27 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Tue, 06 Feb 2024 16:39:27 +0100
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <20240127161753.114685-1-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
Message-ID: <87h6ily53k.fsf@all.your.base.are.belong.to.us>

Hi Anup,

Anup Patel <apatel at ventanamicro.com> writes:

> The RISC-V AIA specification is ratified as-per the RISC-V international
> process. The latest ratified AIA specifcation can be found at:
> https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf
>
> At a high-level, the AIA specification adds three things:
> 1) AIA CSRs
>    - Improved local interrupt support
> 2) Incoming Message Signaled Interrupt Controller (IMSIC)
>    - Per-HART MSI controller
>    - Support MSI virtualization
>    - Support IPI along with virtualization
> 3) Advanced Platform-Level Interrupt Controller (APLIC)
>    - Wired interrupt controller
>    - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
>    - In Direct-mode, injects external interrupts directly into HARTs
>
> For an overview of the AIA specification, refer the AIA virtualization
> talk at KVM Forum 2022:
> https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
> https://www.youtube.com/watch?v=r071dL8Z0yo

Thank you for continuing to work on this series! I like this
direction of the series!

TL;DR: I think we can get rid of most of the id/householding data
structures, except for the irq matrix.

Most of my comments are more of a design/overview nature, so I'll
comment here in the cover letter.

I took the series for a spin with and it with Alex' ftrace fix it,
passes all my tests nicely!

Now some thoughts/comments (I'm coming from the x86 side of things!):

id/enable-tracking: There are a lot of different id/enabled tracking
with corresponding locks, where there's IMO overlap with what the
matrix provides.

Let's start with struct imsic_priv:

   | /* Dummy HW interrupt numbers */
   | unsigned int nr_hwirqs;
   | raw_spinlock_t hwirqs_lock;
   | unsigned long *hwirqs_used_bitmap;

These are used to for the domain routing (hwirq -> desc/virq), and not
needed. Just use the same id as virq (at allocation time), and get rid
of these data structures/corresponding functions. The lookup in the
interrupt handler via imsic_local_priv.vectors doesn't care about
hwirq. This is what x86 does... The imsic_vector roughly corresponds
to apic_chip_data (nit: imsic_vector could have the chip_data suffix
as well, at least it would have helped me!)

Moving/affinity changes. The moving of a vector to another CPU
currently involves:

1. Allocate a new vector from the matrix
2. Disable/enable the corresponding per-cpu ids_enabled_bitmap (nested
   spinlocks)
3. Trigger two IPIs to apply the bitmap
4. On each CPU target (imsic_local_sync()) loop the bitmap and flip
   all bits, and potentially rearm

This seems a bit heavy-weight: Why are you explicitly setting/clearing
all the bits in a loop at the local sync?

x86 does it a bit differently (more lazily): The chip_data has
prev_{cpu,vector}/move_in_progress fields, and keep both vectors
enabled until there's an interrupt on the new vector, and then the old
one is cleaned (irq_complete_move()).

Further; When it's time to remove the old vector, x86 doesn't trigger
an IPI on the disabling side, but queues a cleanup job on a per-cpu
list and triggers a timeout. So, the per-cpu chip_data (per-cpu
"vectors" in your series) can reside in two places during the transit.

I wonder if this clean up is less intrusive, and you just need to
perform what's in the per-list instead of dealing with the
ids_enabled_bitmap? Maybe we can even remove that bitmap as well. The
chip_data/desc has that information. This would mean that
imsic_local_priv() would only have the local vectors (chip_data), and
a cleanup list/timer.

My general comment is that instead of having these global id-tracking
structures, use the matrix together with some desc/chip_data local
data, which should be sufficient.

Random thought: Do we need to explicitly disable (csr) the vector,
when we're changing the affinity? What if we just leave it enabled,
and only when mask/unmask is performed it's actually explicitly masked
(writes to the csr)?

Missing features (which can be added later):
* Reservation mode/activate support (allocate many MSI, but only
  request/activate a subset)
* Handle managed interrupts
* There might be some irqd flags are missing, which mostly cpuhp care
  about (e.g. irqd_*_single_target())...

Finally; Given that the APLIC requires a lot more patches, depending
on how the review process moves on -- maybe the IMSIC side could go as
a separate series?


Cheers,
Bj?rn



From charles.perry at savoirfairelinux.com  Tue Feb  6 07:39:58 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Tue, 6 Feb 2024 10:39:58 -0500 (EST)
Subject: [PATCH 1/3] fpga: xilinx-spi: extract a common driver core
In-Reply-To: <Zb9JUMcGkbbPXPcE@yilunxu-OptiPlex-7050>
References: <20240129225602.3832449-1-charles.perry@savoirfairelinux.com> <20240131230542.3993409-1-charles.perry@savoirfairelinux.com> <20240131230542.3993409-2-charles.perry@savoirfairelinux.com> <Zb9JUMcGkbbPXPcE@yilunxu-OptiPlex-7050>
Message-ID: <1580556877.524419.1707233998229.JavaMail.zimbra@savoirfairelinux.com>

On Feb 4, 2024, at 3:22 AM, Xu Yilun yilun.xu at linux.intel.com wrote:
> On Wed, Jan 31, 2024 at 06:05:31PM -0500, Charles Perry wrote:
>> Factor out the gpio handshaking (using PROGRAM_B, INIT_B and DONE)
>> protocol in xilinx-core so that it can be reused for another driver.
>> This commit does not change anything functionally to xilinx-spi.
>> 
>> xilinx-core expects drivers to provide two operations:
>> 
>>  * ->write(const char* buf, size_t count): write to the device
>>  * ->write_one_dummy_byte(): write 0xFF to the device
>> 
>> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
>> ---
>>  drivers/fpga/Kconfig       |   4 +
>>  drivers/fpga/Makefile      |   1 +
>>  drivers/fpga/xilinx-core.c | 210 +++++++++++++++++++++++++++++++++++++
>>  drivers/fpga/xilinx-core.h |  27 +++++
>>  drivers/fpga/xilinx-spi.c  | 204 +++--------------------------------
>>  5 files changed, 257 insertions(+), 189 deletions(-)
>>  create mode 100644 drivers/fpga/xilinx-core.c
>>  create mode 100644 drivers/fpga/xilinx-core.h
>> 
>> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
>> index 2f689ac4ba3a3..d27a1ebf40838 100644
>> --- a/drivers/fpga/Kconfig
>> +++ b/drivers/fpga/Kconfig
>> @@ -64,9 +64,13 @@ config FPGA_MGR_STRATIX10_SOC
>>  	help
>>  	  FPGA manager driver support for the Intel Stratix10 SoC.
>>  
>> +config FPGA_MGR_XILINX_CORE
>> +	tristate
>> +
>>  config FPGA_MGR_XILINX_SPI
>>  	tristate "Xilinx Configuration over Slave Serial (SPI)"
>>  	depends on SPI
>> +	select FPGA_MGR_XILINX_CORE
>>  	help
>>  	  FPGA manager driver support for Xilinx FPGA configuration
>>  	  over slave serial interface.
>> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
>> index 352a2612623e0..7ec795b6a5a70 100644
>> --- a/drivers/fpga/Makefile
>> +++ b/drivers/fpga/Makefile
>> @@ -15,6 +15,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
>>  obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
>>  obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC)	+= stratix10-soc.o
>>  obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
>> +obj-$(CONFIG_FPGA_MGR_XILINX_CORE)	+= xilinx-core.o
>>  obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
>>  obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
>>  obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA)	+= zynqmp-fpga.o
>> diff --git a/drivers/fpga/xilinx-core.c b/drivers/fpga/xilinx-core.c
>> new file mode 100644
>> index 0000000000000..aff40e9394085
>> --- /dev/null
>> +++ b/drivers/fpga/xilinx-core.c
>> @@ -0,0 +1,210 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Common parts of the Xilinx Spartan6 and 7 Series FPGA manager drivers.
>> + *
>> + * Copyright (C) 2017 DENX Software Engineering
>> + *
>> + * Anatolij Gustschin <agust at denx.de>
>> + */
>> +
>> +#include "xilinx-core.h"
>> +
>> +#include <linux/delay.h>
>> +#include <linux/fpga/fpga-mgr.h>
>> +#include <linux/gpio/consumer.h>
>> +#include <linux/of.h>
>> +
>> +static int get_done_gpio(struct fpga_manager *mgr)
>> +{
>> +	struct xilinx_fpga_core *core = mgr->priv;
>> +	int ret;
>> +
>> +	ret = gpiod_get_value(core->done);
>> +
> 
> remove the line.
> 

Ok

>> +	if (ret < 0)
>> +		dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret);
>> +
>> +	return ret;
>> +}
>> +
>> +static enum fpga_mgr_states xilinx_core_state(struct fpga_manager *mgr)
>> +{
>> +	if (!get_done_gpio(mgr))
>> +		return FPGA_MGR_STATE_RESET;
>> +
>> +	return FPGA_MGR_STATE_UNKNOWN;
>> +}
>> +
>> +/**
>> + * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
>> + * a given delay if the pin is unavailable
>> + *
>> + * @mgr:        The FPGA manager object
>> + * @value:      Value INIT_B to wait for (1 = asserted = low)
>> + * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
>> + *
>> + * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
>> + * too much time passed waiting for that. If no INIT_B GPIO is available
>> + * then always return 0.
>> + */
>> +static int wait_for_init_b(struct fpga_manager *mgr, int value,
>> +			   unsigned long alt_udelay)
>> +{
>> +	struct xilinx_fpga_core *core = mgr->priv;
>> +	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
>> +
>> +	if (core->init_b) {
>> +		while (time_before(jiffies, timeout)) {
>> +			int ret = gpiod_get_value(core->init_b);
>> +
>> +			if (ret == value)
>> +				return 0;
>> +
>> +			if (ret < 0) {
>> +				dev_err(&mgr->dev,
>> +					"Error reading INIT_B (%d)\n", ret);
>> +				return ret;
>> +			}
>> +
>> +			usleep_range(100, 400);
>> +		}
>> +
>> +		dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n",
>> +			value ? "assert" : "deassert");
>> +		return -ETIMEDOUT;
>> +	}
>> +
>> +	udelay(alt_udelay);
>> +
>> +	return 0;
>> +}
>> +
>> +static int xilinx_core_write_init(struct fpga_manager *mgr,
>> +				  struct fpga_image_info *info, const char *buf,
>> +				  size_t count)
>> +{
>> +	struct xilinx_fpga_core *core = mgr->priv;
>> +	int err;
>> +
>> +	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
>> +		dev_err(&mgr->dev, "Partial reconfiguration not supported\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	gpiod_set_value(core->prog_b, 1);
>> +
>> +	err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */
>> +	if (err) {
>> +		gpiod_set_value(core->prog_b, 0);
>> +		return err;
>> +	}
>> +
>> +	gpiod_set_value(core->prog_b, 0);
>> +
>> +	err = wait_for_init_b(mgr, 0, 0);
>> +	if (err)
>> +		return err;
>> +
>> +	if (get_done_gpio(mgr)) {
>> +		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
>> +		return -EIO;
>> +	}
>> +
>> +	/* program latency */
>> +	usleep_range(7500, 7600);
>> +	return 0;
>> +}
>> +
>> +static int xilinx_core_write(struct fpga_manager *mgr, const char *buf,
>> +			     size_t count)
>> +{
>> +	struct xilinx_fpga_core *core = mgr->priv;
>> +
>> +	return core->write(core, buf, count);
>> +}
>> +
>> +static int xilinx_core_write_complete(struct fpga_manager *mgr,
>> +				      struct fpga_image_info *info)
>> +{
>> +	struct xilinx_fpga_core *core = mgr->priv;
>> +	unsigned long timeout =
>> +		jiffies + usecs_to_jiffies(info->config_complete_timeout_us);
>> +	bool expired = false;
>> +	int done;
>> +	int ret;
>> +
>> +	/*
>> +	 * This loop is carefully written such that if the driver is
>> +	 * scheduled out for more than 'timeout', we still check for DONE
>> +	 * before giving up and we apply 8 extra CCLK cycles in all cases.
>> +	 */
>> +	while (!expired) {
>> +		expired = time_after(jiffies, timeout);
>> +
>> +		done = get_done_gpio(mgr);
>> +		if (done < 0)
>> +			return done;
>> +
>> +		ret = core->write_one_dummy_byte(core);
>> +		if (ret)
>> +			return ret;
>> +
>> +		if (done)
>> +			return 0;
>> +	}
>> +
>> +	if (core->init_b) {
>> +		ret = gpiod_get_value(core->init_b);
>> +
>> +		if (ret < 0) {
>> +			dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
>> +			return ret;
>> +		}
>> +
>> +		dev_err(&mgr->dev,
>> +			ret ? "CRC error or invalid device\n" :
>> +			      "Missing sync word or incomplete bitstream\n");
>> +	} else {
>> +		dev_err(&mgr->dev, "Timeout after config data transfer\n");
>> +	}
>> +
>> +	return -ETIMEDOUT;
>> +}
>> +
>> +static const struct fpga_manager_ops xilinx_core_ops = {
>> +	.state = xilinx_core_state,
>> +	.write_init = xilinx_core_write_init,
>> +	.write = xilinx_core_write,
>> +	.write_complete = xilinx_core_write_complete,
>> +};
>> +
>> +int xilinx_core_probe(struct xilinx_fpga_core *core, struct device *dev,
>> +		      xilinx_write_func write,
>> +		      xilinx_write_one_dummy_byte_func write_one_dummy_byte)
> 
> I prefer to move these parameters in xilinx_fpga_core structure. I don't
> want the param list becomes longer and longer when we have more inputs.
> 

Ok

>> +{
>> +	struct fpga_manager *mgr;
>> +
>> +	core->dev = dev;
>> +	core->write = write;
>> +	core->write_one_dummy_byte = write_one_dummy_byte;
> 
> Could the write() writes one dummy byte? Maybe one write callback is enough.
> 

Yes, good idea.

>> +
>> +	/* PROGRAM_B is active low */
>> +	core->prog_b = devm_gpiod_get(dev, "prog_b", GPIOD_OUT_LOW);
>> +	if (IS_ERR(core->prog_b))
>> +		return dev_err_probe(dev, PTR_ERR(core->prog_b),
>> +				     "Failed to get PROGRAM_B gpio\n");
>> +
>> +	core->init_b = devm_gpiod_get_optional(dev, "init-b", GPIOD_IN);
>> +	if (IS_ERR(core->init_b))
>> +		return dev_err_probe(dev, PTR_ERR(core->init_b),
>> +				     "Failed to get INIT_B gpio\n");
>> +
>> +	core->done = devm_gpiod_get(dev, "done", GPIOD_IN);
>> +	if (IS_ERR(core->done))
>> +		return dev_err_probe(dev, PTR_ERR(core->done),
>> +				     "Failed to get DONE gpio\n");
>> +
>> +	mgr = devm_fpga_mgr_register(dev, "Xilinx Slave Serial FPGA Manager",
>> +				     &xilinx_core_ops, core);
>> +	return PTR_ERR_OR_ZERO(mgr);
>> +}
>> diff --git a/drivers/fpga/xilinx-core.h b/drivers/fpga/xilinx-core.h
>> new file mode 100644
>> index 0000000000000..40e120945ba70
>> --- /dev/null
>> +++ b/drivers/fpga/xilinx-core.h
>> @@ -0,0 +1,27 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +
>> +#ifndef __XILINX_CORE_H
>> +#define __XILINX_CORE_H
>> +
>> +#include <linux/device.h>
>> +
>> +struct xilinx_fpga_core;
>> +
>> +typedef int (*xilinx_write_func)(struct xilinx_fpga_core *core, const char
>> *buf,
>> +				 size_t count);
>> +typedef int (*xilinx_write_one_dummy_byte_func)(struct xilinx_fpga_core *core);
> 
> No need to typedef.
> 
> Thanks,
> Yilun
> 

Ok

Thank you for the review,
Charles

>> +
>> +struct xilinx_fpga_core {
>> +	struct device *dev;
>> +	xilinx_write_func write;
>> +	xilinx_write_one_dummy_byte_func write_one_dummy_byte;
>> +	struct gpio_desc *prog_b;
>> +	struct gpio_desc *init_b;
>> +	struct gpio_desc *done;
>> +};
>> +
>> +int xilinx_core_probe(struct xilinx_fpga_core *core, struct device *dev,
>> +		      xilinx_write_func write,
>> +		      xilinx_write_one_dummy_byte_func write_one_dummy_byte);
>> +
>> +#endif /* __XILINX_CORE_H */
>> diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c
>> index e1a227e7ff2ae..ec128dee97312 100644
>> --- a/drivers/fpga/xilinx-spi.c
>> +++ b/drivers/fpga/xilinx-spi.c
>> @@ -10,127 +10,24 @@
>>   * the slave serial configuration interface.
>>   */
>>  
>> -#include <linux/delay.h>
>> -#include <linux/device.h>
>> -#include <linux/fpga/fpga-mgr.h>
>> -#include <linux/gpio/consumer.h>
>> +#include "xilinx-core.h"
>> +
>>  #include <linux/module.h>
>>  #include <linux/mod_devicetable.h>
>>  #include <linux/of.h>
>>  #include <linux/spi/spi.h>
>> -#include <linux/sizes.h>
>>  
>>  struct xilinx_spi_conf {
>> +	struct xilinx_fpga_core core;
>>  	struct spi_device *spi;
>> -	struct gpio_desc *prog_b;
>> -	struct gpio_desc *init_b;
>> -	struct gpio_desc *done;
>>  };
>>  
>> -static int get_done_gpio(struct fpga_manager *mgr)
>> -{
>> -	struct xilinx_spi_conf *conf = mgr->priv;
>> -	int ret;
>> -
>> -	ret = gpiod_get_value(conf->done);
>> -
>> -	if (ret < 0)
>> -		dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret);
>> -
>> -	return ret;
>> -}
>> -
>> -static enum fpga_mgr_states xilinx_spi_state(struct fpga_manager *mgr)
>> -{
>> -	if (!get_done_gpio(mgr))
>> -		return FPGA_MGR_STATE_RESET;
>> -
>> -	return FPGA_MGR_STATE_UNKNOWN;
>> -}
>> -
>> -/**
>> - * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
>> - * a given delay if the pin is unavailable
>> - *
>> - * @mgr:        The FPGA manager object
>> - * @value:      Value INIT_B to wait for (1 = asserted = low)
>> - * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
>> - *
>> - * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
>> - * too much time passed waiting for that. If no INIT_B GPIO is available
>> - * then always return 0.
>> - */
>> -static int wait_for_init_b(struct fpga_manager *mgr, int value,
>> -			   unsigned long alt_udelay)
>> -{
>> -	struct xilinx_spi_conf *conf = mgr->priv;
>> -	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
>> -
>> -	if (conf->init_b) {
>> -		while (time_before(jiffies, timeout)) {
>> -			int ret = gpiod_get_value(conf->init_b);
>> -
>> -			if (ret == value)
>> -				return 0;
>> -
>> -			if (ret < 0) {
>> -				dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
>> -				return ret;
>> -			}
>> -
>> -			usleep_range(100, 400);
>> -		}
>> -
>> -		dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n",
>> -			value ? "assert" : "deassert");
>> -		return -ETIMEDOUT;
>> -	}
>> -
>> -	udelay(alt_udelay);
>> -
>> -	return 0;
>> -}
>> -
>> -static int xilinx_spi_write_init(struct fpga_manager *mgr,
>> -				 struct fpga_image_info *info,
>> -				 const char *buf, size_t count)
>> -{
>> -	struct xilinx_spi_conf *conf = mgr->priv;
>> -	int err;
>> -
>> -	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
>> -		dev_err(&mgr->dev, "Partial reconfiguration not supported\n");
>> -		return -EINVAL;
>> -	}
>> -
>> -	gpiod_set_value(conf->prog_b, 1);
>> +#define to_xilinx_spi_conf(obj) container_of(obj, struct xilinx_spi_conf, core)
>>  
>> -	err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */
>> -	if (err) {
>> -		gpiod_set_value(conf->prog_b, 0);
>> -		return err;
>> -	}
>> -
>> -	gpiod_set_value(conf->prog_b, 0);
>> -
>> -	err = wait_for_init_b(mgr, 0, 0);
>> -	if (err)
>> -		return err;
>> -
>> -	if (get_done_gpio(mgr)) {
>> -		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
>> -		return -EIO;
>> -	}
>> -
>> -	/* program latency */
>> -	usleep_range(7500, 7600);
>> -	return 0;
>> -}
>> -
>> -static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
>> +static int xilinx_spi_write(struct xilinx_fpga_core *core, const char *buf,
>>  			    size_t count)
>>  {
>> -	struct xilinx_spi_conf *conf = mgr->priv;
>> +	struct xilinx_spi_conf *conf = to_xilinx_spi_conf(core);
>>  	const char *fw_data = buf;
>>  	const char *fw_data_end = fw_data + count;
>>  
>> @@ -143,7 +40,7 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const
>> char *buf,
>>  
>>  		ret = spi_write(conf->spi, fw_data, stride);
>>  		if (ret) {
>> -			dev_err(&mgr->dev, "SPI error in firmware write: %d\n",
>> +			dev_err(core->dev, "SPI error in firmware write: %d\n",
>>  				ret);
>>  			return ret;
>>  		}
>> @@ -153,77 +50,22 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const
>> char *buf,
>>  	return 0;
>>  }
>>  
>> -static int xilinx_spi_apply_cclk_cycles(struct xilinx_spi_conf *conf)
>> +static int xilinx_spi_apply_cclk_cycles(struct xilinx_fpga_core *core)
>>  {
>> -	struct spi_device *spi = conf->spi;
>> +	struct xilinx_spi_conf *conf = to_xilinx_spi_conf(core);
>>  	const u8 din_data[1] = { 0xff };
>>  	int ret;
>>  
>>  	ret = spi_write(conf->spi, din_data, sizeof(din_data));
>>  	if (ret)
>> -		dev_err(&spi->dev, "applying CCLK cycles failed: %d\n", ret);
>> +		dev_err(core->dev, "applying CCLK cycles failed: %d\n", ret);
>>  
>>  	return ret;
>>  }
>>  
>> -static int xilinx_spi_write_complete(struct fpga_manager *mgr,
>> -				     struct fpga_image_info *info)
>> -{
>> -	struct xilinx_spi_conf *conf = mgr->priv;
>> -	unsigned long timeout = jiffies +
>> usecs_to_jiffies(info->config_complete_timeout_us);
>> -	bool expired = false;
>> -	int done;
>> -	int ret;
>> -
>> -	/*
>> -	 * This loop is carefully written such that if the driver is
>> -	 * scheduled out for more than 'timeout', we still check for DONE
>> -	 * before giving up and we apply 8 extra CCLK cycles in all cases.
>> -	 */
>> -	while (!expired) {
>> -		expired = time_after(jiffies, timeout);
>> -
>> -		done = get_done_gpio(mgr);
>> -		if (done < 0)
>> -			return done;
>> -
>> -		ret = xilinx_spi_apply_cclk_cycles(conf);
>> -		if (ret)
>> -			return ret;
>> -
>> -		if (done)
>> -			return 0;
>> -	}
>> -
>> -	if (conf->init_b) {
>> -		ret = gpiod_get_value(conf->init_b);
>> -
>> -		if (ret < 0) {
>> -			dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
>> -			return ret;
>> -		}
>> -
>> -		dev_err(&mgr->dev,
>> -			ret ? "CRC error or invalid device\n"
>> -			: "Missing sync word or incomplete bitstream\n");
>> -	} else {
>> -		dev_err(&mgr->dev, "Timeout after config data transfer\n");
>> -	}
>> -
>> -	return -ETIMEDOUT;
>> -}
>> -
>> -static const struct fpga_manager_ops xilinx_spi_ops = {
>> -	.state = xilinx_spi_state,
>> -	.write_init = xilinx_spi_write_init,
>> -	.write = xilinx_spi_write,
>> -	.write_complete = xilinx_spi_write_complete,
>> -};
>> -
>>  static int xilinx_spi_probe(struct spi_device *spi)
>>  {
>>  	struct xilinx_spi_conf *conf;
>> -	struct fpga_manager *mgr;
>>  
>>  	conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL);
>>  	if (!conf)
>> @@ -231,31 +73,15 @@ static int xilinx_spi_probe(struct spi_device *spi)
>>  
>>  	conf->spi = spi;
>>  
>> -	/* PROGRAM_B is active low */
>> -	conf->prog_b = devm_gpiod_get(&spi->dev, "prog_b", GPIOD_OUT_LOW);
>> -	if (IS_ERR(conf->prog_b))
>> -		return dev_err_probe(&spi->dev, PTR_ERR(conf->prog_b),
>> -				     "Failed to get PROGRAM_B gpio\n");
>> -
>> -	conf->init_b = devm_gpiod_get_optional(&spi->dev, "init-b", GPIOD_IN);
>> -	if (IS_ERR(conf->init_b))
>> -		return dev_err_probe(&spi->dev, PTR_ERR(conf->init_b),
>> -				     "Failed to get INIT_B gpio\n");
>> -
>> -	conf->done = devm_gpiod_get(&spi->dev, "done", GPIOD_IN);
>> -	if (IS_ERR(conf->done))
>> -		return dev_err_probe(&spi->dev, PTR_ERR(conf->done),
>> -				     "Failed to get DONE gpio\n");
>> -
>> -	mgr = devm_fpga_mgr_register(&spi->dev,
>> -				     "Xilinx Slave Serial FPGA Manager",
>> -				     &xilinx_spi_ops, conf);
>> -	return PTR_ERR_OR_ZERO(mgr);
>> +	return xilinx_core_probe(&conf->core, &spi->dev, xilinx_spi_write,
>> +				 xilinx_spi_apply_cclk_cycles);
>>  }
>>  
>>  #ifdef CONFIG_OF
>>  static const struct of_device_id xlnx_spi_of_match[] = {
>> -	{ .compatible = "xlnx,fpga-slave-serial", },
>> +	{
>> +		.compatible = "xlnx,fpga-slave-serial",
>> +	},
>>  	{}
>>  };
>>  MODULE_DEVICE_TABLE(of, xlnx_spi_of_match);
>> --
>> 2.43.0
>> 


From Frank.li at nxp.com  Tue Feb  6 07:24:42 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 6 Feb 2024 10:24:42 -0500
Subject: [PATCH 2/2] arm64: dts: imx8dxl update edma0 information
In-Reply-To: <ZcIMJWKBrPW4Y5R8@dragon>
References: <20240129201633.234255-1-Frank.Li@nxp.com>
 <20240129201633.234255-2-Frank.Li@nxp.com>
 <ZcIMJWKBrPW4Y5R8@dragon>
Message-ID: <ZcJPOldJBIo3E7RK@lizhi-Precision-Tower-5810>

On Tue, Feb 06, 2024 at 06:38:29PM +0800, Shawn Guo wrote:
> On Mon, Jan 29, 2024 at 03:16:32PM -0500, Frank Li wrote:
> > edma0 of iMX8DXL is difference with other imx8 chips. Update register's
> > size, channel number and power-domain.
> > Update i2c[0-3] channel number information.
> > 
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> >  .../boot/dts/freescale/imx8dxl-ss-adma.dtsi   | 65 +++++++++++++++++++
> >  1 file changed, 65 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
> > index 0a477f6318f15..f8fca86babda7 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
> > @@ -15,6 +15,63 @@ &adc0 {
> >  	interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
> >  };
> >  
> > +&edma0 {
> > +	reg = <0x591f0000 0x1a0000>;
> > +	#dma-cells = <3>;
> > +	dma-channels = <25>;
> > +	dma-channel-mask = <0x1c0cc0>;
> > +	interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>, /* asrc 0 */
> > +		<GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* spdif0 */
> > +		<GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
> > +		<GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>, /* sai1 */
> > +		<GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* sai2 */
> > +		<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>, /* sai3 */
> > +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
> > +		<GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, /* gpt0 */
> > +		<GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>, /* gpt1 */
> > +		<GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>, /* gpt2 */
> > +		<GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>; /* gpt3 */
> > +	power-domains = <&pd IMX_SC_R_DMA_0_CH0>,
> > +			<&pd IMX_SC_R_DMA_0_CH1>,
> > +			<&pd IMX_SC_R_DMA_0_CH2>,
> > +			<&pd IMX_SC_R_DMA_0_CH3>,
> > +			<&pd IMX_SC_R_DMA_0_CH4>,
> > +			<&pd IMX_SC_R_DMA_0_CH5>,
> > +			<&pd IMX_SC_R_DMA_0_CH6>,
> > +			<&pd IMX_SC_R_DMA_0_CH7>,
> > +			<&pd IMX_SC_R_DMA_0_CH8>,
> > +			<&pd IMX_SC_R_DMA_0_CH9>,
> > +			<&pd IMX_SC_R_DMA_0_CH10>,
> > +			<&pd IMX_SC_R_DMA_0_CH11>,
> > +			<&pd IMX_SC_R_DMA_0_CH12>,
> > +			<&pd IMX_SC_R_DMA_0_CH13>,
> > +			<&pd IMX_SC_R_DMA_0_CH14>,
> > +			<&pd IMX_SC_R_DMA_0_CH15>,
> > +			<&pd IMX_SC_R_DMA_0_CH16>,
> > +			<&pd IMX_SC_R_DMA_0_CH17>,
> > +			<&pd IMX_SC_R_DMA_0_CH18>,
> > +			<&pd IMX_SC_R_DMA_0_CH19>,
> > +			<&pd IMX_SC_R_DMA_0_CH20>,
> > +			<&pd IMX_SC_R_DMA_0_CH21>,
> > +			<&pd IMX_SC_R_DMA_0_CH22>,
> > +			<&pd IMX_SC_R_DMA_0_CH23>,
> > +			<&pd IMX_SC_R_DMA_0_CH24>;
> > +};
> > +
> >  &edma2 {
> >  	interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>,
> >  		     <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>,
> > @@ -48,21 +105,29 @@ &edma3 {
> >  &i2c0 {
> >  	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
> >  	interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
> > +	dma-names = "tx","rx";
> > +	dmas = <&edma3 1 0 0>, <&edma3 0 0 FSL_EDMA_RX>;
> >  };
> >  
> >  &i2c1 {
> >  	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
> >  	interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
> > +	dma-names = "tx","rx";
> > +	dmas = <&edma3 3 0 0>, <&edma3 2 0 FSL_EDMA_RX>;
> 
> No FSL_EDMA_TX for "tx"?

Yes, only defined FSL_EDMA_RX. It is bitmask. If no FSL_EDMA_RX, means
TX channel.

Frank

> 
> Shawn
> 
> >  };
> >  
> >  &i2c2 {
> >  	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
> >  	interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
> > +	dma-names = "tx","rx";
> > +	dmas = <&edma3 5 0 0>, <&edma3 4 0 FSL_EDMA_RX>;
> >  };
> >  
> >  &i2c3 {
> >  	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
> >  	interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
> > +	dma-names = "tx","rx";
> > +	dmas = <&edma3 7 0 0>, <&edma3 6 0 FSL_EDMA_RX>;
> >  };
> >  
> >  &lpuart0 {
> > -- 
> > 2.34.1
> > 
> 


From kuba at kernel.org  Tue Feb  6 07:41:51 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 6 Feb 2024 07:41:51 -0800
Subject: [PATCH v2 0/4] Add 8qm SMMU information
In-Reply-To: <ZcIPCxgO3Gxc/aXh@dragon>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
	<20240202110511.135d26b7@kernel.org>
	<ZcIPCxgO3Gxc/aXh@dragon>
Message-ID: <20240206074151.577d33f1@kernel.org>

On Tue, 6 Feb 2024 18:50:51 +0800 Shawn Guo wrote:
> > Any preference on whether all these go via a platform tree,
> > or should we pick up the net patch to netdev? I guess taking
> > the DTB via netdev would be the usual way to handle this?  
> 
> No, it's not.  Taking DTS changes through arch/platform tree is the
> usual way.

I said DTB.


From charles.perry at savoirfairelinux.com  Tue Feb  6 07:48:25 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Tue, 6 Feb 2024 10:48:25 -0500 (EST)
Subject: [PATCH 3/3] fpga: xilinx-selectmap: add new driver
In-Reply-To: <Zb9GkY6cMtR+4xOX@yilunxu-OptiPlex-7050>
References: <20240129225602.3832449-1-charles.perry@savoirfairelinux.com> <20240131230542.3993409-1-charles.perry@savoirfairelinux.com> <20240131230542.3993409-4-charles.perry@savoirfairelinux.com> <Zb9GkY6cMtR+4xOX@yilunxu-OptiPlex-7050>
Message-ID: <1245786788.524590.1707234505127.JavaMail.zimbra@savoirfairelinux.com>

On Feb 4, 2024, at 3:10 AM, Xu Yilun yilun.xu at linux.intel.com wrote:
> On Wed, Jan 31, 2024 at 06:05:33PM -0500, Charles Perry wrote:
>> Xilinx 7 series FPGA can be programmed using a slave parallel port named
>> the SelectMAP interface in the datasheet. This slave interface is
>> compatible with the i.MX6 EIM bus controller but other types of external
>> memory mapped parallel bus might work.
>> 
>> xilinx-selectmap currently only supports the x8 mode where data is loaded
>> at one byte per rising edge of the clock, with the MSb of each byte
>> presented to the D0 pin.
>> 
>> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
>> ---
>>  drivers/fpga/Kconfig            |   8 +++
>>  drivers/fpga/Makefile           |   1 +
>>  drivers/fpga/xilinx-core.c      |  11 +++-
>>  drivers/fpga/xilinx-core.h      |   3 +-
>>  drivers/fpga/xilinx-selectmap.c | 106 ++++++++++++++++++++++++++++++++
>>  drivers/fpga/xilinx-spi.c       |   3 +-
>>  6 files changed, 127 insertions(+), 5 deletions(-)
>>  create mode 100644 drivers/fpga/xilinx-selectmap.c
>> 
>> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
>> index d27a1ebf40838..37b35f58f0dfb 100644
>> --- a/drivers/fpga/Kconfig
>> +++ b/drivers/fpga/Kconfig
>> @@ -67,6 +67,14 @@ config FPGA_MGR_STRATIX10_SOC
>>  config FPGA_MGR_XILINX_CORE
>>  	tristate
>>  
>> +config FPGA_MGR_XILINX_SELECTMAP
>> +	tristate "Xilinx Configuration over SelectMAP"
>> +	depends on HAS_IOMEM
>> +	select FPGA_MGR_XILINX_CORE
>> +	help
>> +	  FPGA manager driver support for Xilinx FPGA configuration
>> +	  over SelectMAP interface.
>> +
>>  config FPGA_MGR_XILINX_SPI
>>  	tristate "Xilinx Configuration over Slave Serial (SPI)"
>>  	depends on SPI
>> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
>> index 7ec795b6a5a70..aeb89bb13517e 100644
>> --- a/drivers/fpga/Makefile
>> +++ b/drivers/fpga/Makefile
>> @@ -16,6 +16,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
>>  obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC)	+= stratix10-soc.o
>>  obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
>>  obj-$(CONFIG_FPGA_MGR_XILINX_CORE)	+= xilinx-core.o
>> +obj-$(CONFIG_FPGA_MGR_XILINX_SELECTMAP)	+= xilinx-selectmap.o
>>  obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
>>  obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
>>  obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA)	+= zynqmp-fpga.o
>> diff --git a/drivers/fpga/xilinx-core.c b/drivers/fpga/xilinx-core.c
>> index aff40e9394085..64117759be100 100644
>> --- a/drivers/fpga/xilinx-core.c
>> +++ b/drivers/fpga/xilinx-core.c
>> @@ -180,21 +180,26 @@ static const struct fpga_manager_ops xilinx_core_ops = {
>>  
>>  int xilinx_core_probe(struct xilinx_fpga_core *core, struct device *dev,
>>  		      xilinx_write_func write,
>> -		      xilinx_write_one_dummy_byte_func write_one_dummy_byte)
>> +		      xilinx_write_one_dummy_byte_func write_one_dummy_byte,
>> +		      const char *prog_con_id, const char *init_con_id)
> 
> These gpio name inputs are not necessary except for DTS format concern.
> Is it possible we don't change the names?
> 

Krzysztof won't accept the old names as they are non standard (contain a 
prohibited char "_" and use a "-b" prefix for active low). I agree that it
is cumbersome to have different gpio names injected in the core by the top 
level driver.

Can I change the GPIO names of xlnx,fpga-slave-serial? i.e.:

 * "prog_b" -> "prog"
 * "init-b" -> "init"

and keep a fallback in the driver so that current users of this driver keep
working without adaptation in the DT.

>>  {
>>  	struct fpga_manager *mgr;
>>  
>> +	if (!core || !dev || !write || !write_one_dummy_byte || !prog_con_id ||
>> +	    !init_con_id)
>> +		return -EINVAL;
> 
> These checks belong to Patch #1.
> 

Ok

>> +
>>  	core->dev = dev;
>>  	core->write = write;
>>  	core->write_one_dummy_byte = write_one_dummy_byte;
>>  
>>  	/* PROGRAM_B is active low */
>> -	core->prog_b = devm_gpiod_get(dev, "prog_b", GPIOD_OUT_LOW);
>> +	core->prog_b = devm_gpiod_get(dev, prog_con_id, GPIOD_OUT_LOW);
>>  	if (IS_ERR(core->prog_b))
>>  		return dev_err_probe(dev, PTR_ERR(core->prog_b),
>>  				     "Failed to get PROGRAM_B gpio\n");
>>  
>> -	core->init_b = devm_gpiod_get_optional(dev, "init-b", GPIOD_IN);
>> +	core->init_b = devm_gpiod_get_optional(dev, init_con_id, GPIOD_IN);
>>  	if (IS_ERR(core->init_b))
>>  		return dev_err_probe(dev, PTR_ERR(core->init_b),
>>  				     "Failed to get INIT_B gpio\n");
>> diff --git a/drivers/fpga/xilinx-core.h b/drivers/fpga/xilinx-core.h
>> index 40e120945ba70..817f0e551d093 100644
>> --- a/drivers/fpga/xilinx-core.h
>> +++ b/drivers/fpga/xilinx-core.h
>> @@ -22,6 +22,7 @@ struct xilinx_fpga_core {
>>  
>>  int xilinx_core_probe(struct xilinx_fpga_core *core, struct device *dev,
>>  		      xilinx_write_func write,
>> -		      xilinx_write_one_dummy_byte_func write_one_dummy_byte);
>> +		      xilinx_write_one_dummy_byte_func write_one_dummy_byte,
>> +		      const char *prog_con_id, const char *init_con_id);
>>  
>>  #endif /* __XILINX_CORE_H */
>> diff --git a/drivers/fpga/xilinx-selectmap.c b/drivers/fpga/xilinx-selectmap.c
>> new file mode 100644
>> index 0000000000000..08054e19bb498
>> --- /dev/null
>> +++ b/drivers/fpga/xilinx-selectmap.c
>> @@ -0,0 +1,106 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Xilinx Spartan6 and 7 Series SelectMAP interface driver
>> + *
>> + * (C) 2024 Charles Perry <charles.perry at savoirfairelinux.com>
>> + *
>> + * Manage Xilinx FPGA firmware loaded over the SelectMAP configuration
>> + * interface.
>> + */
>> +
>> +#include "xilinx-core.h"
>> +
>> +#include <linux/platform_device.h>
>> +#include <linux/gpio/consumer.h>
>> +#include <linux/module.h>
>> +#include <linux/mod_devicetable.h>
>> +#include <linux/of.h>
>> +#include <linux/io.h>
>> +
>> +struct xilinx_selectmap_conf {
>> +	struct xilinx_fpga_core core;
>> +	void __iomem *base;
>> +	struct gpio_desc *csi_b;
>> +	struct gpio_desc *rdwr_b;
> 
> These 2 gpio_desc are not used globally, maybe remove them here.
> 

Ok

>> +};
>> +
>> +#define to_xilinx_selectmap_conf(obj) \
>> +	container_of(obj, struct xilinx_selectmap_conf, core)
>> +
>> +static int xilinx_selectmap_write(struct xilinx_fpga_core *core,
>> +				  const char *buf, size_t count)
>> +{
>> +	struct xilinx_selectmap_conf *conf = to_xilinx_selectmap_conf(core);
>> +	u32 i;
>> +
>> +	for (i = 0; i < count; ++i)
>> +		writeb(buf[i], conf->base);
>> +
>> +	return 0;
>> +}
>> +
>> +static int xilinx_selectmap_apply_padding(struct xilinx_fpga_core *core)
>> +{
>> +	struct xilinx_selectmap_conf *conf = to_xilinx_selectmap_conf(core);
>> +
>> +	writeb(0xFF, conf->base);
> 
> Seems only one callback needed. Just use write() to xfer 1 byte?
> 
> Thanks,
> Yilun
> 

Yes, will be changed.

Thank you,
Charles

>> +	return 0;
>> +}
>> +
>> +static int xilinx_selectmap_probe(struct platform_device *pdev)
>> +{
>> +	struct xilinx_selectmap_conf *conf;
>> +	struct resource *r;
>> +	void __iomem *base;
>> +
>> +	conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL);
>> +	if (!conf)
>> +		return -ENOMEM;
>> +
>> +	base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
>> +	if (IS_ERR(base))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(base),
>> +				     "ioremap error\n");
>> +	conf->base = base;
>> +
>> +	/* CSI_B is active low */
>> +	conf->csi_b =
>> +		devm_gpiod_get_optional(&pdev->dev, "csi", GPIOD_OUT_HIGH);
>> +	if (IS_ERR(conf->csi_b))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(conf->csi_b),
>> +				     "Failed to get CSI_B gpio\n");
>> +
>> +	/* RDWR_B is active low */
>> +	conf->rdwr_b =
>> +		devm_gpiod_get_optional(&pdev->dev, "rdwr", GPIOD_OUT_HIGH);
>> +	if (IS_ERR(conf->rdwr_b))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(conf->rdwr_b),
>> +				     "Failed to get RDWR_B gpio\n");
>> +
>> +	return xilinx_core_probe(&conf->core, &pdev->dev,
>> +				 xilinx_selectmap_write,
>> +				 xilinx_selectmap_apply_padding, "prog",
>> +				 "init");
>> +}
>> +
>> +static const struct of_device_id xlnx_selectmap_of_match[] = {
>> +	{
>> +		.compatible = "xlnx,fpga-selectmap",
>> +	},
>> +	{}
>> +};
>> +MODULE_DEVICE_TABLE(of, xlnx_selectmap_of_match);
>> +
>> +static struct platform_driver xilinx_selectmap_driver = {
>> +	.driver = {
>> +		.name = "xilinx-selectmap",
>> +		.of_match_table = xlnx_selectmap_of_match,
>> +	},
>> +	.probe  = xilinx_selectmap_probe,
>> +};
>> +
>> +module_platform_driver(xilinx_selectmap_driver);
>> +
>> +MODULE_LICENSE("GPL");
>> +MODULE_AUTHOR("Charles Perry <charles.perry at savoirfairelinux.com>");
>> +MODULE_DESCRIPTION("Load Xilinx FPGA firmware over SelectMap");
>> diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c
>> index ec128dee97312..b9ab3d5da004c 100644
>> --- a/drivers/fpga/xilinx-spi.c
>> +++ b/drivers/fpga/xilinx-spi.c
>> @@ -74,7 +74,8 @@ static int xilinx_spi_probe(struct spi_device *spi)
>>  	conf->spi = spi;
>>  
>>  	return xilinx_core_probe(&conf->core, &spi->dev, xilinx_spi_write,
>> -				 xilinx_spi_apply_cclk_cycles);
>> +				 xilinx_spi_apply_cclk_cycles, "prog_b",
>> +				 "init-b");
>>  }
>>  
>>  #ifdef CONFIG_OF
>> --
>> 2.43.0
>> 


From angelogioacchino.delregno at collabora.com  Tue Feb  6 07:53:56 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 6 Feb 2024 16:53:56 +0100
Subject: [PATCH v4 1/9] drm/mediatek: dsi: Use GENMASK() for register mask
 definitions
In-Reply-To: <f91db779-ad94-4c18-9a06-1029da4edaab@baylibre.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-2-angelogioacchino.delregno@collabora.com>
 <f91db779-ad94-4c18-9a06-1029da4edaab@baylibre.com>
Message-ID: <c1e2c380-21b5-47c1-b83b-f7f2b481df21@collabora.com>

Il 06/02/24 15:47, Alexandre Mergnat ha scritto:
> 
> 
> On 06/02/2024 13:07, AngeloGioacchino Del Regno wrote:
>> Change magic numerical masks with usage of the GENMASK() macro
>> to improve readability.
>>
>> While at it, also fix the DSI_PS_SEL mask to include all bits instead
>> of just a subset of them.
>>
>> This commit brings no functional changes.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
>> ? drivers/gpu/drm/mediatek/mtk_dsi.c | 45 +++++++++++++++---------------
>> ? 1 file changed, 23 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> index a2fdfc8ddb15..3b7392c03b4d 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> @@ -58,18 +58,18 @@
> 
> ...snip...
> 
>> ? #define DSI_PSCTRL??????? 0x1c
>> -#define DSI_PS_WC??????????? 0x3fff
>> -#define DSI_PS_SEL??????????? (3 << 16)
>> +#define DSI_PS_WC??????????? GENMASK(14, 0)
>> +#define DSI_PS_SEL??????????? GENMASK(19, 16)
> 
> 0011 0000 0000 0000 0000 => GENMASK(17, 16)

Alexandre, the reason for that is in the commit description :-P

"While at it, also fix the DSI_PS_SEL mask to include all bits instead
of just a subset of them."

Thanks for the reviews, btw!

Cheers!
Angelo

> 
>> ? #define PACKED_PS_16BIT_RGB565??????? (0 << 16)
>> ? #define LOOSELY_PS_18BIT_RGB666??????? (1 << 16)
>> ? #define PACKED_PS_18BIT_RGB666??????? (2 << 16)
>> @@ -109,26 +109,26 @@
>> ? #define LD0_WAKEUP_EN??????????? BIT(2)
> 



From kamlesh at ti.com  Tue Feb  6 07:54:01 2024
From: kamlesh at ti.com (Kamlesh Gurudasani)
Date: Tue, 6 Feb 2024 21:24:01 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <a4fdbcfe-e0e0-4280-8638-e39b6b46778e@ti.com>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
 <20240206131420.wtitflgav23jto2q@verbally>
 <871q9pzoiq.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <c5b6bd1d-dbb4-4bfb-8b3e-9b0733e2ba5d@ti.com>
 <c2b7f22d-f07d-4cac-8a01-af7b014e7ff4@ti.com>
 <a4fdbcfe-e0e0-4280-8638-e39b6b46778e@ti.com>
Message-ID: <87ttmly4fa.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>

"Kumar, Udit" <u-kumar1 at ti.com> writes:

>>>>> get_freq is a bit expensive as it has to walk the clock tree to find
>>>>> the clock frequency (at least the first time?). just wondering if
>>>>> there is lighter alternative here?
>>>>>
>>>> How about get_clock? Doesn't read the registers at least.
>>>
>>> Said API needs, some flags to be passed,
>>>
>>> Can those flag be set to zero, Chandru ?
>>
>>
>> get_clock doesn't require any flags to be passed.
>
>
> May be firmware does not need it but? I was referring to
>
> https://elixir.bootlin.com/linux/latest/source/drivers/clk/keystone/sci-clk.c#L78
Just took a look,

I now understand the reason for confusion,

#define TI_SCI_MSG_SET_CLOCK_STATE	0x0100
#define TI_SCI_MSG_GET_CLOCK_STATE	0x0101

cops->get_clock = ti_sci_cmd_get_clock;  --> refers to
TI_SCI_MSG_SET_CLOCK_STATE
That's why we are passing the flag from linux for get_clock

Linux is using terminology of get/put.

As Chandru pointed, we don't have to pass flags, cause he is refering
to TI_SCI_MSG_GET_CLOCK_STATE

Below functions passes TI_SCI_MSG_GET_CLOCK_STATE to DM, which is what
we actually want.
cops->is_auto = ti_sci_cmd_clk_is_auto;
cops->is_on = ti_sci_cmd_clk_is_on;
cops->is_off = ti_sci_cmd_clk_is_off;

Which should be safe to call, Chandru can confirm.

Regards,
Kamlesh
>
>
>
>>
>>
>>>
>>>
>>>> Regards,
>>>> Kamlesh


From peter.griffin at linaro.org  Tue Feb  6 07:56:39 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 6 Feb 2024 15:56:39 +0000
Subject: [PATCH v3 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <CAPLW+4=Cm36Q311Y7mCGgm+3fe5NNNc5XhNSMkbigTG2BVCTpA@mail.gmail.com>
References: <20240202145731.4082033-1-peter.griffin@linaro.org>
 <20240202145731.4082033-2-peter.griffin@linaro.org> <CAPLW+4=Cm36Q311Y7mCGgm+3fe5NNNc5XhNSMkbigTG2BVCTpA@mail.gmail.com>
Message-ID: <CADrjBPqT=F+MALssnWsMa1E1RcPN7Sz8s+HfEZRU3pSgPO+z6w@mail.gmail.com>

Hi Sam,

Thanks for the great review feedback.

On Fri, 2 Feb 2024 at 17:35, Sam Protsenko <semen.protsenko at linaro.org> wrote:
>
> On Fri, Feb 2, 2024 at 8:57?AM Peter Griffin <peter.griffin at linaro.org> wrote:
> >
> > Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> > security hardening reasons so that they are only write accessible in el3
> > via an SMC call.
> >
> > As most Exynos drivers that need to write PMU registers currently obtain a
> > regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> > is implemented in this driver using a custom regmap similar to syscon to
> > handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> > regmap like before. As regmaps abstract out the underlying register access
> > changes to the leaf drivers are minimal.
> >
> > A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> > that currently use syscon_regmap_lookup_by_phandle(). This also handles
> > deferred probing.
> >
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > ---
> > Changes since v2
> >  - Add select REGMAP to Kconfig
> >  - Add constant for SET/CLEAR bits
> >  - Replace kerneldoc with one line comment
> >  - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
> >  - remove superflous extern keyword
> >  - dev_err_probe() on probe error
> >  - shorten regmcfg name
> >  - no compatibles inside probe, use match data
> >  - don't mix declarations with/without initializations
> >  - tensor_sec_reg_read() use mmio to avoid access restrictions
> >  - Collect up Reviewed-by
> >  - const for regmap_config structs
> > ---
> >  drivers/soc/samsung/Kconfig            |   1 +
> >  drivers/soc/samsung/exynos-pmu.c       | 233 ++++++++++++++++++++++++-
> >  drivers/soc/samsung/exynos-pmu.h       |   1 +
> >  include/linux/soc/samsung/exynos-pmu.h |  11 +-
> >  4 files changed, 241 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> > index 27ec99af77e3..1a5dfdc978dc 100644
> > --- a/drivers/soc/samsung/Kconfig
> > +++ b/drivers/soc/samsung/Kconfig
> > @@ -42,6 +42,7 @@ config EXYNOS_PMU
> >         depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
> >         select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
> >         select MFD_CORE
> > +       select REGMAP_MMIO
> >
> >  # There is no need to enable these drivers for ARMv8
> >  config EXYNOS_PMU_ARM_DRIVERS
> > diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> > index 250537d7cfd6..adf3549370d6 100644
> > --- a/drivers/soc/samsung/exynos-pmu.c
> > +++ b/drivers/soc/samsung/exynos-pmu.c
> > @@ -5,6 +5,7 @@
> >  //
> >  // Exynos - CPU PMU(Power Management Unit) support
> >
> > +#include <linux/arm-smccc.h>
> >  #include <linux/of.h>
> >  #include <linux/of_address.h>
> >  #include <linux/mfd/core.h>
> > @@ -12,19 +13,130 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/delay.h>
> > +#include <linux/regmap.h>
> >
> >  #include <linux/soc/samsung/exynos-regs-pmu.h>
> >  #include <linux/soc/samsung/exynos-pmu.h>
> >
> >  #include "exynos-pmu.h"
> >
> > +#define PMUALIVE_MASK GENMASK(14, 0)
>
> Are you sure it's not GENMASK(13, 0)?

Yes, you're right, mask should be 0x3fff.

> Because SET_BITS has bit #14
> set, which overlaps with bit #14 from PMUALIVE_MASK, when being added
> in tensor_set_bit_atomic().
>
> This also can be aligned with below definitions.

Will update alignment
>
> > +#define SET_BITS       0xc000
> > +#define CLEAR_BITS     0x8000
>
> All 3 above values seem to be gs101 specific. At least I can't find
> any similar atomic registers in Exynos850 TRM, in PMU block. So I'd
> suggest also adding TENSOR_ prefix to those to make it clear and to
> prevent possible naming conflicts in future.

Sure, I can add a Tensor prefix. Unfortunately these atomic registers
aren't mentioned anywhere in gs101 TRM's either, so it is a bit of a
nature study :( It was implemented and used in the downstream drivers
though (and doesn't look to be implemented downstream for exynos850,
so you're likely correct it doesn't have it.). I tried to check some
other downstream product tree's, I found the hardware looks to exist
on Exynos 9820 [1]. But I think we can update the name if somebody
tries to upstream that platform in the future.

[1] https://github.com/PixelOS-Devices/kernel_samsung_exynos9820/blob/thirteen/drivers/soc/samsung/exynos-pmu.c#L32

>
> Also, not sure if it makes things better, but FWIW:
>
>     #define CLEAR_BITS     BIT(15)
>     #define SET_BITS       (BIT(15) | BIT(14))

I agree that would make it clearer.

>
> Just to show that those two bits don't overlap with PMUALIVE_MASK (if
> it can be fixed to 13:0), and show their relation. If I understand
> correctly what's going on anyway.

I think you've understood what's happening here perfectly

>
> > +
> > +#define TENSOR_SMC_PMU_SEC_REG         0x82000504
> > +#define TENSOR_PMUREG_READ             0
> > +#define TENSOR_PMUREG_WRITE            1
> > +#define TENSOR_PMUREG_RMW              2
> > +
> >  struct exynos_pmu_context {
> >         struct device *dev;
> >         const struct exynos_pmu_data *pmu_data;
> > +       struct regmap *pmureg;
> >  };
> >
> >  void __iomem *pmu_base_addr;
> >  static struct exynos_pmu_context *pmu_context;
> > +static struct platform_driver exynos_pmu_driver;
>
> Just an idea: maybe add a comment saying it's a forward declaration,
> and the variable is assigned below, as it might be confusing. Not sure
> if it's worth it though.
>
> > +
> > +/*
> > + * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
> > + * from EL3, but are still read accessible. As Linux needs to write some of
> > + * these registers, the following functions are provided and exposed via
> > + * regmap.
> > + *
> > + * Note: This SMC interface is known to be implemented on gs101 and derivative
> > + * SoCs.
> > + */
> > +
> > +/* Write to a protected PMU register. */
> > +static int tensor_sec_reg_write(void *base, unsigned int reg, unsigned int val)
> > +{
> > +       struct arm_smccc_res res;
> > +       unsigned long pmu_base = (unsigned long)base;
> > +
> > +       arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> > +                     TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
> > +
> > +       /* returns -EINVAL if access isn't allowed or 0 */
> > +       if (res.a0)
> > +               pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> > +
> > +       return (int)res.a0;
> > +}
> > +
> > +/* Read/Modify/Write a protected PMU register. */
> > +static int tensor_sec_reg_rmw(void *base, unsigned int reg,
> > +                             unsigned int mask, unsigned int val)
> > +{
> > +       struct arm_smccc_res res;
> > +       unsigned long pmu_base = (unsigned long)base;
> > +
> > +       arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> > +                     TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
> > +
> > +       /* returns -EINVAL if access isn't allowed or 0*/
> > +       if (res.a0)
> > +               pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> > +
> > +       return (int)res.a0;
> > +}
> > +
> > +/*
> > + * Read a protected PMU register. All PMU registers can be read by Linux.
> > + * Note: The SMC read register is not used, as only registers that can be
> > + * written are readable via SMC.
> > + */
> > +static int tensor_sec_reg_read(void *base, unsigned int reg, unsigned int *val)
> > +{
> > +       *val = pmu_raw_readl(reg);
> > +       return 0;
> > +}
> > +
> > +/*
> > + * For SoCs that have set/clear bit hardware this function can be used when
> > + * the PMU register will be accessed by multiple masters.
> > + *
> > + * For example, to set bits 13:8 in PMU reg offset 0x3e80
> > + * tensor_set_bit_atomic(0x3e80, 0x3f00, 0x3f00);
> > + *
> > + * To clear bits 13:8 in PMU offset 0x3e80
> > + * tensor_set_bit_atomic(0x3e80, 0x0, 0x3f00);
> > + */
> > +static inline int tensor_set_bit_atomic(void *ctx, unsigned int offset,
>
> set_bit -> set_bits?

Will change

>
> > +                                       u32 val, u32 mask)
> > +{
> > +       int ret;
> > +       unsigned int i;
> > +
> > +       for (i = 0; i < 32; i++) {
> > +               if (mask & BIT(i)) {
>
> Maybe replace it with:
>
>     if (!(mask & BIT(i)))
>         continue;
>
> to reduce the indentation level?

Will do

>
> > +                       if (val & BIT(i))
> > +                               offset |= SET_BITS;
> > +                       else
> > +                               offset |= CLEAR_BITS;
>
> What if someone calls this functions like this:
>
>     tensor_set_bit_atomic(0x3e80, 0x100, 0x3f00);
>
> which means "set bit #8, and clear bits 13:9). But because the offset
> variable will hold SET_BITS set during bit #8 handling, bits 13:9 are
> also going to be set, effectively making that call act like
> tensor_set_bit_atomic(0x3e80, 0x3f00, 0x3f00) instead. So I'd add
> something like:
>
>     offset &= ~SET_BITS;
>
> before doing |= operations.

Good catch! Will fix in v4

>
> > +
> > +                       ret = tensor_sec_reg_write(ctx, offset, i);
> > +                       if (ret)
> > +                               goto out;
>
> Maybe remove "out" and just do return ret here?

Will update

>
> > +               }
> > +       }
> > +out:
> > +       return ret;
> > +}
> > +
> > +static int tensor_sec_update_bits(void *ctx, unsigned int reg,
> > +                                 unsigned int mask, unsigned int val)
> > +{
> > +       /*
> > +        * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
> > +        * as the target registers can be accessed by multiple masters.
> > +        */
> > +       if (reg > PMUALIVE_MASK)
> > +               return tensor_sec_reg_rmw(ctx, reg, mask, val);
> > +
> > +       return tensor_set_bit_atomic(ctx, reg, val, mask);
> > +}
> >
> >  void pmu_raw_writel(u32 val, u32 offset)
> >  {
> > @@ -75,11 +187,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
> >  #define exynos_pmu_data_arm_ptr(data)  NULL
> >  #endif
> >
> > +static const struct regmap_config regmap_smccfg = {
> > +       .name = "pmu_regs",
> > +       .reg_bits = 32,
> > +       .reg_stride = 4,
> > +       .val_bits = 32,
> > +       .fast_io = true,
> > +       .use_single_read = true,
> > +       .use_single_write = true,
> > +       .reg_read = tensor_sec_reg_read,
> > +       .reg_write = tensor_sec_reg_write,
> > +       .reg_update_bits = tensor_sec_update_bits,
> > +};
> > +
> > +static const struct regmap_config regmap_mmiocfg = {
> > +       .name = "pmu_regs",
> > +       .reg_bits = 32,
> > +       .reg_stride = 4,
> > +       .val_bits = 32,
> > +       .fast_io = true,
> > +       .use_single_read = true,
> > +       .use_single_write = true,
> > +};
> > +
> > +static const struct exynos_pmu_data gs101_pmu_data = {
> > +       .pmu_secure = true
> > +};
> > +
> >  /*
> >   * PMU platform driver and devicetree bindings.
> >   */
> >  static const struct of_device_id exynos_pmu_of_device_ids[] = {
> >         {
> > +               .compatible = "google,gs101-pmu",
> > +               .data = &gs101_pmu_data,
> > +       }, {
> >                 .compatible = "samsung,exynos3250-pmu",
> >                 .data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
> >         }, {
> > @@ -113,19 +255,73 @@ static const struct mfd_cell exynos_pmu_devs[] = {
> >         { .name = "exynos-clkout", },
> >  };
> >
> > +/**
> > + * exynos_get_pmu_regmap() - Obtain pmureg regmap
> > + *
> > + * Find the pmureg regmap previously configured in probe() and return regmap
> > + * pointer.
> > + *
> > + * Return: A pointer to regmap if found or ERR_PTR error value.
> > + */
> >  struct regmap *exynos_get_pmu_regmap(void)
> >  {
> >         struct device_node *np = of_find_matching_node(NULL,
> >                                                       exynos_pmu_of_device_ids);
> >         if (np)
> > -               return syscon_node_to_regmap(np);
> > +               return exynos_get_pmu_regmap_by_phandle(np, NULL);
> >         return ERR_PTR(-ENODEV);
> >  }
> >  EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
> >
> > +/**
> > + * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
> > + * @np: Pointer to device's Device Tree node
> > + * @property: Device Tree property name which references the pmu
> > + *
> > + * Find the pmureg regmap previously configured in probe() and return regmap
> > + * pointer.
> > + *
> > + * Return: A pointer to regmap if found or ERR_PTR error value.
> > + */
> > +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> > +                                               const char *property)
> > +{
> > +       struct device *dev;
> > +       struct exynos_pmu_context *ctx;
> > +       struct device_node *pmu_np;
> > +
> > +       if (property)
> > +               pmu_np = of_parse_phandle(np, property, 0);
> > +       else
> > +               pmu_np = np;
> > +
> > +       if (!pmu_np)
> > +               return ERR_PTR(-ENODEV);
> > +
> > +       /*
> > +        * Determine if exynos-pmu device has probed and therefore regmap
> > +        * has been created and can be returned to the caller. Otherwise we
> > +        * return -EPROBE_DEFER.
> > +        */
> > +       dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
> > +                                           (void *)pmu_np);
> > +
> > +       of_node_put(pmu_np);
> > +       if (!dev)
> > +               return ERR_PTR(-EPROBE_DEFER);
> > +
> > +       ctx = dev_get_drvdata(dev);
> > +
> > +       return ctx->pmureg;
> > +}
> > +EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
> > +
> >  static int exynos_pmu_probe(struct platform_device *pdev)
> >  {
> >         struct device *dev = &pdev->dev;
> > +       struct regmap_config pmu_regmcfg;
> > +       struct regmap *regmap;
> > +       struct resource *res;
> >         int ret;
> >
> >         pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
> > @@ -133,13 +329,42 @@ static int exynos_pmu_probe(struct platform_device *pdev)
> >                 return PTR_ERR(pmu_base_addr);
> >
> >         pmu_context = devm_kzalloc(&pdev->dev,
> > -                       sizeof(struct exynos_pmu_context),
> > -                       GFP_KERNEL);
> > +                                  sizeof(struct exynos_pmu_context),
> > +                                  GFP_KERNEL);
> >         if (!pmu_context)
> >                 return -ENOMEM;
> > -       pmu_context->dev = dev;
> > +
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       if (!res)
> > +               return -ENODEV;
> > +
> >         pmu_context->pmu_data = of_device_get_match_data(dev);
> >
> > +       /* For SoCs that secure PMU register writes use custom regmap */
> > +       if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_secure) {
> > +               pmu_regmcfg = regmap_smccfg;
> > +               pmu_regmcfg.max_register = resource_size(res) -
> > +                                          pmu_regmcfg.reg_stride;
> > +               /* Need physical address for SMC call */
> > +               regmap = devm_regmap_init(dev, NULL,
> > +                                         (void *)(uintptr_t)res->start,
> > +                                         &pmu_regmcfg);
> > +       } else {
> > +               /* all other SoCs use a MMIO regmap */
>
> Suggest starting with a capital letter, for consistency with previous comments.

Will update

>
> > +               pmu_regmcfg = regmap_mmiocfg;
> > +               pmu_regmcfg.max_register = resource_size(res) -
> > +                                          pmu_regmcfg.reg_stride;
> > +               regmap = devm_regmap_init_mmio(dev, pmu_base_addr,
> > +                                              &pmu_regmcfg);
> > +       }
> > +
> > +       if (IS_ERR(regmap))
> > +               dev_err_probe(&pdev->dev, PTR_ERR(regmap),
> > +                             "regmap init failed\n");
>
> Why not "return dev_err_probe()"? Is it ok to continue with no regmap created?

That should have been return dev_err_probe. Will fix

Peter



>
> > +
> > +       pmu_context->pmureg = regmap;
> > +       pmu_context->dev = dev;
> > +
> >         if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init)
> >                 pmu_context->pmu_data->pmu_init();
> >
> > diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
> > index 1c652ffd79b4..0a49a2c9a08e 100644
> > --- a/drivers/soc/samsung/exynos-pmu.h
> > +++ b/drivers/soc/samsung/exynos-pmu.h
> > @@ -21,6 +21,7 @@ struct exynos_pmu_conf {
> >  struct exynos_pmu_data {
> >         const struct exynos_pmu_conf *pmu_config;
> >         const struct exynos_pmu_conf *pmu_config_extra;
> > +       bool pmu_secure;
> >
> >         void (*pmu_init)(void);
> >         void (*powerdown_conf)(enum sys_powerdown);
> > diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
> > index a4f5516cc956..406ed73614fd 100644
> > --- a/include/linux/soc/samsung/exynos-pmu.h
> > +++ b/include/linux/soc/samsung/exynos-pmu.h
> > @@ -20,12 +20,21 @@ enum sys_powerdown {
> >
> >  extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
> >  #ifdef CONFIG_EXYNOS_PMU
> > -extern struct regmap *exynos_get_pmu_regmap(void);
> > +struct regmap *exynos_get_pmu_regmap(void);
> > +
>
> Usually empty line delimeter is not needed in cases like that.
>
> > +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> > +                                               const char *property);
> >  #else
> >  static inline struct regmap *exynos_get_pmu_regmap(void)
> >  {
> >         return ERR_PTR(-ENODEV);
> >  }
> > +
> > +static inline struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> > +                                                             const char *property)
> > +{
> > +       return ERR_PTR(-ENODEV);
> > +}
> >  #endif
> >
> >  #endif /* __LINUX_SOC_EXYNOS_PMU_H */
> > --
> > 2.43.0.594.gd9cf4e227d-goog
> >


From barrettkovacskovacs at gmail.com  Tue Feb  6 07:57:29 2024
From: barrettkovacskovacs at gmail.com (Ruth Lennon)
Date: Tue, 06 Feb 2024 16:57:29 +0100
Subject: Giving Out Yamaha Baby Grand.
Message-ID: <09f142e8570b1568cf4e1f99c5ace96296f037e6af79dad7aa92326f02749540@mx.google.com>

I am giving away my late husband's Yamaha Grand Baby GC1 to a passionate instrument lover. If you know of a fellow teacher, school, student, family or church that might be interested, please forward this email to them.God bless you.Ruth.
 


From henrik at grimler.se  Tue Feb  6 08:02:27 2024
From: henrik at grimler.se (Henrik Grimler)
Date: Tue, 06 Feb 2024 17:02:27 +0100
Subject: [PATCH v2] ARM: dts: samsung: exynos5420-galaxy-tab-common: add
 wifi node
Message-ID: <20240206-galaxy-tab-s-cleanup-v2-1-89025c6c66c5@grimler.se>

By using brcm/brcmfmac4354-sdio.bin from linux-firmware together with
nvram.txt from vendor firmware wifi works well on the chagall-wifi and
klimt-lte.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
Describe wifi node for exynos5420-chagall-wifi and
exynos5420-klimt-wifi, and decrease available memory.
---
Changes in v2:
- Drop patch 1 and 3 (the latter was applied)
- Fixup patch 2 so it applies cleanly after dropping patch 1
- Link to v1: https://lore.kernel.org/r/20240130-galaxy-tab-s-cleanup-v1-0-d4e17857241d at grimler.se
---

Changes since v1:
- Fix conflicts after dropping patch 1
---
 .../dts/samsung/exynos5420-galaxy-tab-common.dtsi  | 32 ++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm/boot/dts/samsung/exynos5420-galaxy-tab-common.dtsi b/arch/arm/boot/dts/samsung/exynos5420-galaxy-tab-common.dtsi
index 3532f1e8e902..246040967082 100644
--- a/arch/arm/boot/dts/samsung/exynos5420-galaxy-tab-common.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos5420-galaxy-tab-common.dtsi
@@ -30,6 +30,7 @@ / {
 
 	aliases {
 		mmc0 = &mmc_0;
+		mmc1 = &mmc_1;
 		mmc2 = &mmc_2;
 	};
 
@@ -87,6 +88,13 @@ key-volume-down {
 			linux,code = <KEY_VOLUMEDOWN>;
 		};
 	};
+
+	mmc1_pwrseq: pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpy7 7 GPIO_ACTIVE_LOW>;
+		clocks = <&s2mps11_osc S2MPS11_CLK_BT>;
+		clock-names = "ext_clock";
+	};
 };
 
 &cci {
@@ -620,6 +628,25 @@ &mmc_0 {
 	vqmmc-supply = <&ldo3_reg>;
 };
 
+/* WiFi */
+&mmc_1 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	card-detect-delay = <200>;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&mmc1_pwrseq>;
+	non-removable;
+	pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_int>, <&sd1_bus1>,
+		    <&sd1_bus4>, <&wifi_en>;
+	pinctrl-names = "default";
+	vqmmc-supply = <&ldo2_reg>;
+	samsung,dw-mshc-ciu-div = <1>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	samsung,dw-mshc-sdr-timing = <0 1>;
+	status = "okay";
+};
+
 /* External sdcard */
 &mmc_2 {
 	status = "okay";
@@ -649,6 +676,11 @@ s2mps11_irq: s2mps11-irq-pins {
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
+
+	wifi_en: wifi-en-pins {
+		samsung,pins = "gpy7-7";
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
 };
 
 &rtc {

---
base-commit: 9a5dbb835fd396c78da34b26ee91db6d529d096d
change-id: 20231210-galaxy-tab-s-cleanup-14da98b23606

Best regards,
-- 
Henrik Grimler <henrik at grimler.se>



From broonie at kernel.org  Tue Feb  6 08:10:50 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 06 Feb 2024 16:10:50 +0000
Subject: [linux][PATCH] ASoC: dt-bindings: atmel,sam9x5-wm8731: Convert
 to json-schema
In-Reply-To: <20240206064418.237377-1-dharma.b@microchip.com>
References: <20240206064418.237377-1-dharma.b@microchip.com>
Message-ID: <170723585073.1032228.17039996472357795011.b4-ty@kernel.org>

On Tue, 06 Feb 2024 12:14:18 +0530, Dharma Balasubiramani wrote:
> Convert atmel sam9x5-wm8731-audio devicetree binding to json-schema.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: dt-bindings: atmel,sam9x5-wm8731: Convert to json-schema
      commit: a15f859ca312feb4730c93320bbe46929d0f9d26

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 nfraprado at collabora.com  Tue Feb  6 08:10:56 2024
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Tue, 6 Feb 2024 11:10:56 -0500
Subject: Probe regression of efuse@11f10000 on
 mt8183-kukui-jacuzzi-juniper-sku16 running next-20240202
Message-ID: <47cdeac1-121d-4b1a-a3ac-e2affc7a2fc3@notapiano>

Hi,

KernelCI has identified a regression [1] on the
mt8183-kukui-jacuzzi-juniper-sku16 machine running on next-20240202 compared to
next-20240118:

<4>[    0.627077] sysfs: cannot create duplicate filename '/bus/nvmem/devices/mtk-efuse0'
<4>[    0.634945] CPU: 7 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc2-next-20240202 #1
<4>[    0.642542] Hardware name: Google juniper sku16 board (DT)
<4>[    0.648237] Call trace:
<4>[    0.650917]  dump_backtrace+0x94/0xec
<4>[    0.654815]  show_stack+0x18/0x24
<4>[    0.658359]  dump_stack_lvl+0x48/0x60
<4>[    0.662252]  dump_stack+0x18/0x24
<4>[    0.665796]  sysfs_warn_dup+0x64/0x80
<4>[    0.669688]  sysfs_do_create_link_sd+0xf0/0xf8
<4>[    0.674353]  sysfs_create_link+0x20/0x40
<4>[    0.678500]  bus_add_device+0x64/0x104
<4>[    0.682475]  device_add+0x33c/0x778
<4>[    0.686193]  nvmem_register+0x514/0x714
<4>[    0.690256]  devm_nvmem_register+0x1c/0x6c
<4>[    0.694577]  mtk_efuse_probe+0xe8/0x170
<4>[    0.698637]  platform_probe+0x68/0xd8
<4>[    0.702525]  really_probe+0x148/0x2b4
<4>[    0.706413]  __driver_probe_device+0x78/0x12c
<4>[    0.710990]  driver_probe_device+0xdc/0x160
<4>[    0.715394]  __driver_attach+0x94/0x19c
<4>[    0.719453]  bus_for_each_dev+0x74/0xd4
<4>[    0.723512]  driver_attach+0x24/0x30
<4>[    0.727312]  bus_add_driver+0xe4/0x1e8
<4>[    0.731284]  driver_register+0x60/0x128
<4>[    0.735343]  __platform_driver_register+0x28/0x34
<4>[    0.740265]  mtk_efuse_init+0x20/0x5c
<4>[    0.744155]  do_one_initcall+0x6c/0x1b0
<4>[    0.748214]  kernel_init_freeable+0x1c8/0x290
<4>[    0.752795]  kernel_init+0x20/0x1dc
<4>[    0.756512]  ret_from_fork+0x10/0x20
<4>[    0.760353] mediatek,efuse: probe of 11f10000.efuse failed with error -17

This efuse probe failure causes the probe failure of other components that
depend on it, including the display pipeline:

/soc/dsi-phy at 11e50000
/soc/dsi at 14014000
/soc/efuse at 11f10000
/soc/i2c at 11008000/anx7625 at 58
/soc/i2c at 11008000/anx7625 at 58/aux-bus/panel
/soc/thermal at 1100b000

There is a series already addressing the issue [2]. The first two patches have
been merged into the mediatek tree, but that tree isn't currently being
integrated into linux-next. Besides that, patch 3 hasn't been merged into the
nvmem tree yet, and it is required in order to solve the issue.

I'm sending this regression report so we can properly track the regression while
the fixes don't land on linux-next.

Thanks,
N?colas

[1] https://linux.kernelci.org/test/plan/id/65bd63c3f12d8a95e200a225/
[2] https://lore.kernel.org/linux-mediatek/20240130095656.3712469-1-wenst at chromium.org/

#regzbot introduced next-20240118..next-20240202


From nfraprado at collabora.com  Tue Feb  6 08:14:01 2024
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Tue, 6 Feb 2024 11:14:01 -0500
Subject: [PATCH 3/3] nvmem: mtk-efuse: Drop NVMEM device name
In-Reply-To: <20240130095656.3712469-4-wenst@chromium.org>
References: <20240130095656.3712469-1-wenst@chromium.org>
 <20240130095656.3712469-4-wenst@chromium.org>
Message-ID: <915f1ec3-a70a-4b56-9e93-5b597fc770cd@notapiano>

On Tue, Jan 30, 2024 at 05:56:53PM +0800, Chen-Yu Tsai wrote:
> The MT8183 has not one but two efuse devices. The static name and ID
> causes the second efuse device to fail to probe, due to duplicate sysfs
> entries.
> 
> With the rework of the mtk-socinfo driver, lookup by name is no longer
> necessary. The custom name can simply be dropped.
> 
> Fixes: 4e6102d60d88 ("nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Tested-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

This does fix the efuse (and display) probe issue on MT8183. FYI I've sent a
regression report for it at
https://lore.kernel.org/all/47cdeac1-121d-4b1a-a3ac-e2affc7a2fc3 at notapiano

Thanks,
N?colas


From laurent.pinchart at ideasonboard.com  Tue Feb  6 08:25:06 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 6 Feb 2024 18:25:06 +0200
Subject: [PATCH 3/4] media: platform: replace of_graph_get_next_endpoint()
In-Reply-To: <87plxanvx1.wl-kuninori.morimoto.gx@renesas.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
 <87plxanvx1.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <20240206162506.GC2827@pendragon.ideasonboard.com>

Hi Morimoto-san,

Thank you for the patch.

On Tue, Feb 06, 2024 at 02:55:38AM +0000, Kuninori Morimoto wrote:
> From DT point of view, in general, drivers should be asking for a
> specific port number because their function is fixed in the binding.
> 
> of_graph_get_next_endpoint() doesn't match to this concept.
> 
> Simply replace
> 
> 	- of_graph_get_next_endpoint(xxx, NULL);
> 	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);
> 
> Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
> ---
>  drivers/media/platform/atmel/atmel-isi.c              | 4 ++--
>  drivers/media/platform/intel/pxa_camera.c             | 2 +-
>  drivers/media/platform/samsung/exynos4-is/fimc-is.c   | 2 +-
>  drivers/media/platform/samsung/exynos4-is/mipi-csis.c | 2 +-
>  drivers/media/platform/st/stm32/stm32-dcmi.c          | 4 ++--
>  drivers/media/platform/ti/davinci/vpif.c              | 3 +--
>  6 files changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
> index 4046212d48b4..f615aee85968 100644
> --- a/drivers/media/platform/atmel/atmel-isi.c
> +++ b/drivers/media/platform/atmel/atmel-isi.c
> @@ -831,7 +831,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
>  	isi->pdata.full_mode = 1;
>  	isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
>  
> -	np = of_graph_get_next_endpoint(np, NULL);
> +	np = of_graph_get_endpoint_by_regs(np, 0, -1);
>  	if (!np) {
>  		dev_err(&pdev->dev, "Could not find the endpoint\n");
>  		return -EINVAL;
> @@ -1155,7 +1155,7 @@ static int isi_graph_init(struct atmel_isi *isi)
>  	struct device_node *ep;
>  	int ret;
>  
> -	ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
> +	ep = of_graph_get_endpoint_by_regs(isi->dev->of_node, 0, -1);
>  	if (!ep)
>  		return -EINVAL;
>  
> diff --git a/drivers/media/platform/intel/pxa_camera.c b/drivers/media/platform/intel/pxa_camera.c
> index 59b89e421dc2..d904952bf00e 100644
> --- a/drivers/media/platform/intel/pxa_camera.c
> +++ b/drivers/media/platform/intel/pxa_camera.c
> @@ -2207,7 +2207,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
>  		pcdev->mclk = mclk_rate;
>  	}
>  
> -	np = of_graph_get_next_endpoint(np, NULL);
> +	np = of_graph_get_endpoint_by_regs(np, 0, -1);
>  	if (!np) {
>  		dev_err(dev, "could not find endpoint\n");
>  		return -EINVAL;
> diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
> index a08c87ef6e2d..39aab667910d 100644
> --- a/drivers/media/platform/samsung/exynos4-is/fimc-is.c
> +++ b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
> @@ -175,7 +175,7 @@ static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,
>  		return -EINVAL;
>  	}
>  
> -	ep = of_graph_get_next_endpoint(node, NULL);
> +	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
>  	if (!ep)
>  		return -ENXIO;
>  
> diff --git a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> index 686ca8753ba2..3f8bea2e3934 100644
> --- a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> +++ b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> @@ -728,7 +728,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
>  				 &state->max_num_lanes))
>  		return -EINVAL;
>  
> -	node = of_graph_get_next_endpoint(node, NULL);
> +	node = of_graph_get_endpoint_by_regs(node, 0, -1);

This is not correct, see
Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml.

>  	if (!node) {
>  		dev_err(&pdev->dev, "No port node at %pOF\n",
>  				pdev->dev.of_node);
> diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c
> index 8cb4fdcae137..4c00aae013af 100644
> --- a/drivers/media/platform/st/stm32/stm32-dcmi.c
> +++ b/drivers/media/platform/st/stm32/stm32-dcmi.c
> @@ -1856,7 +1856,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi)
>  	struct device_node *ep;
>  	int ret;
>  
> -	ep = of_graph_get_next_endpoint(dcmi->dev->of_node, NULL);
> +	ep = of_graph_get_endpoint_by_regs(dcmi->dev->of_node, 0, -1);
>  	if (!ep) {
>  		dev_err(dcmi->dev, "Failed to get next endpoint\n");
>  		return -EINVAL;
> @@ -1915,7 +1915,7 @@ static int dcmi_probe(struct platform_device *pdev)
>  				     "Could not get reset control\n");
>  
>  	/* Get bus characteristics from devicetree */
> -	np = of_graph_get_next_endpoint(np, NULL);
> +	np = of_graph_get_endpoint_by_regs(np, 0, -1);
>  	if (!np) {
>  		dev_err(&pdev->dev, "Could not find the endpoint\n");
>  		return -ENODEV;
> diff --git a/drivers/media/platform/ti/davinci/vpif.c b/drivers/media/platform/ti/davinci/vpif.c
> index 63cdfed37bc9..f4e1fa76bf37 100644
> --- a/drivers/media/platform/ti/davinci/vpif.c
> +++ b/drivers/media/platform/ti/davinci/vpif.c
> @@ -465,8 +465,7 @@ static int vpif_probe(struct platform_device *pdev)
>  	 * so their devices need to be registered manually here
>  	 * for their legacy platform_drivers to work.
>  	 */
> -	endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
> -					      endpoint);
> +	endpoint = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 0, -1);
>  	if (!endpoint)
>  		return 0;
>  	of_node_put(endpoint);

-- 
Regards,

Laurent Pinchart


From broonie at kernel.org  Tue Feb  6 08:27:01 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 06 Feb 2024 16:27:01 +0000
Subject: [PATCH] arm64/sve: Document that __SVE_VQ_MAX is much larger than
 needed
Message-ID: <20240206-arm64-sve-vl-max-comment-v1-1-dddf16414412@kernel.org>

__SVE_VQ_MAX is defined without comment as 512 but the actual
architectural maximum is 16, a substantial difference which might not
be obvious to readers especially given the several different units used
for specifying vector sizes in various contexts and the fact that it's
often used via macros.  In an effort to minimise surprises for users who
might assume the value is the architectural maximum and use it to do
things like size allocations add a comment noting the difference.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/sve_context.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/sve_context.h b/arch/arm64/include/uapi/asm/sve_context.h
index 754ab751b523..59f283f373a6 100644
--- a/arch/arm64/include/uapi/asm/sve_context.h
+++ b/arch/arm64/include/uapi/asm/sve_context.h
@@ -13,6 +13,10 @@
 
 #define __SVE_VQ_BYTES		16	/* number of bytes per quadword */
 
+/*
+ * Note that for future proofing __SVE_VQ_MAX is defined much larger
+ * than the actual architecture maximum of 16.
+ */
 #define __SVE_VQ_MIN		1
 #define __SVE_VQ_MAX		512
 

---
base-commit: 54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478
change-id: 20240206-arm64-sve-vl-max-comment-64efa3f03625

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From dave.stevenson at raspberrypi.com  Tue Feb  6 08:31:06 2024
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Tue, 6 Feb 2024 16:31:06 +0000
Subject: [PATCH 02/12] bcm2835-dma: Add proper 40-bit DMA support
In-Reply-To: <8736c115-e11c-41ca-85eb-7cd19a205068@gmx.net>
References: <cover.1706948717.git.andrea.porta@suse.com> <eeb94204c30c2182f5ffd3ec083c04399ecdee32.1706948717.git.andrea.porta@suse.com>
 <8736c115-e11c-41ca-85eb-7cd19a205068@gmx.net>
Message-ID: <CAPY8ntCEvsTJwoEBYc7JsTaYfdMURhmytvvVMcLVNBkmdTNcZQ@mail.gmail.com>

Hi Stefan and Andrea

On Mon, 5 Feb 2024 at 18:50, Stefan Wahren <wahrenst at gmx.net> wrote:
>
> Hi Andrea,
>
> [add Dave]
>
> Am 04.02.24 um 07:59 schrieb Andrea della Porta:
> > From: Phil Elwell <phil at raspberrypi.org>
> >
> > BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
> > to access the full 4GB of memory on a Pi 4.
> >
> > Cc: Phil Elwell <phil at raspberrypi.org>
> > Cc: Maxime Ripard <maxime at cerno.tech>
> > Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
> mainlining isn't that simple by sending just the downstream patches to
> the mailing list. In many cases there reasons why this hasn't been
> upstreamed yet.
>
> In my opinion just this feature is worth a separate patch series. In
> 2021 i already send an initial version, which tried to implement it in a
> cleaner & maintainabler way [1]. In the meantime Dave Stevenson from
> Raspberry Pi wrote that he also wanted to work on this. Maybe you want
> to work on this together?

Yes, I'm looking at reworking Stefan's series to work on Pi4 & Pi5 as
it's needed for HDMI audio (and other things) on those platforms which
I'm working to upstream.

I was getting weirdness from the sdhci block when I was last looking
at it, so it was just proving a little trickier than first thought.
Hopefully I'll get some time on it in the next couple of weeks.

  Dave

> [1] -
> https://lore.kernel.org/linux-arm-kernel/13ec386b-2305-27da-9765-8fa3ad71146c at i2se.com/T/


From laurent.pinchart at ideasonboard.com  Tue Feb  6 08:44:29 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 6 Feb 2024 18:44:29 +0200
Subject: [PATCH 4/4] video: fbdev: replace of_graph_get_next_endpoint()
In-Reply-To: <87o7cunvwv.wl-kuninori.morimoto.gx@renesas.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
 <87o7cunvwv.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <20240206164429.GD2827@pendragon.ideasonboard.com>

Hi Morimoto-san,

Thank you for the patch.

On Tue, Feb 06, 2024 at 02:55:45AM +0000, Kuninori Morimoto wrote:
> From DT point of view, in general, drivers should be asking for a
> specific port number because their function is fixed in the binding.
> 
> of_graph_get_next_endpoint() doesn't match to this concept.
> 
> Simply replace
> 
> 	- of_graph_get_next_endpoint(xxx, NULL);
> 	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);
> 
> Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
> ---
>  drivers/video/fbdev/amba-clcd.c               |  2 +-
>  drivers/video/fbdev/omap2/omapfb/dss/dsi.c    |  3 ++-
>  drivers/video/fbdev/omap2/omapfb/dss/dss-of.c | 20 +------------------
>  drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c  |  3 ++-
>  drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c  |  3 ++-
>  drivers/video/fbdev/omap2/omapfb/dss/venc.c   |  3 ++-
>  drivers/video/fbdev/pxafb.c                   |  2 +-
>  include/video/omapfb_dss.h                    |  3 ---
>  8 files changed, 11 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
> index 0399db369e70..2371b204cfd2 100644
> --- a/drivers/video/fbdev/amba-clcd.c
> +++ b/drivers/video/fbdev/amba-clcd.c

This driver has been deleted in v6.8-rc1.

> @@ -691,7 +691,7 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
>  	/*
>  	 * Fetch the panel endpoint.
>  	 */
> -	endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL);
> +	endpoint = of_graph_get_endpoint_by_regs(fb->dev->dev.of_node, 0, -1);
>  	if (!endpoint)
>  		return -ENODEV;
>  
> diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
> index b7eb17a16ec4..1f13bcf73da5 100644
> --- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
> +++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
> @@ -28,6 +28,7 @@
>  #include <linux/debugfs.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/of.h>
> +#include <linux/of_graph.h>
>  #include <linux/of_platform.h>
>  #include <linux/component.h>
>  
> @@ -5079,7 +5080,7 @@ static int dsi_probe_of(struct platform_device *pdev)
>  	struct device_node *ep;
>  	struct omap_dsi_pin_config pin_cfg;
>  
> -	ep = omapdss_of_get_first_endpoint(node);
> +	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
>  	if (!ep)
>  		return 0;
>  
> diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
> index 0282d4eef139..14965a3fd05b 100644
> --- a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
> +++ b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
> @@ -130,24 +130,6 @@ static struct device_node *omapdss_of_get_remote_port(const struct device_node *
>  	return np;
>  }
>  
> -struct device_node *
> -omapdss_of_get_first_endpoint(const struct device_node *parent)
> -{
> -	struct device_node *port, *ep;
> -
> -	port = omapdss_of_get_next_port(parent, NULL);
> -
> -	if (!port)
> -		return NULL;
> -
> -	ep = omapdss_of_get_next_endpoint(port, NULL);
> -
> -	of_node_put(port);
> -
> -	return ep;
> -}
> -EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint);
> -

I *think* replacing omapdss_of_get_first_endpoint() with
of_graph_get_endpoint_by_regs(0, -1) is functionally equivalent in all
cases, but a confirmation from Tomi would be nice. I wonder if it
wouldn't be time to drop the fbdev driver though...

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

>  struct omap_dss_device *
>  omapdss_of_find_source_for_first_ep(struct device_node *node)
>  {
> @@ -155,7 +137,7 @@ omapdss_of_find_source_for_first_ep(struct device_node *node)
>  	struct device_node *src_port;
>  	struct omap_dss_device *src;
>  
> -	ep = omapdss_of_get_first_endpoint(node);
> +	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
>  	if (!ep)
>  		return ERR_PTR(-EINVAL);
>  
> diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
> index f05b4e35a842..8f407ec134dc 100644
> --- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
> +++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
> @@ -20,6 +20,7 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/clk.h>
>  #include <linux/of.h>
> +#include <linux/of_graph.h>
>  #include <linux/regulator/consumer.h>
>  #include <linux/component.h>
>  #include <video/omapfb_dss.h>
> @@ -529,7 +530,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
>  	struct device_node *ep;
>  	int r;
>  
> -	ep = omapdss_of_get_first_endpoint(node);
> +	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
>  	if (!ep)
>  		return 0;
>  
> diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
> index 03292945b1d4..4ad219f522b9 100644
> --- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
> +++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
> @@ -25,6 +25,7 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/clk.h>
>  #include <linux/of.h>
> +#include <linux/of_graph.h>
>  #include <linux/regulator/consumer.h>
>  #include <linux/component.h>
>  #include <video/omapfb_dss.h>
> @@ -561,7 +562,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
>  	struct device_node *ep;
>  	int r;
>  
> -	ep = omapdss_of_get_first_endpoint(node);
> +	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
>  	if (!ep)
>  		return 0;
>  
> diff --git a/drivers/video/fbdev/omap2/omapfb/dss/venc.c b/drivers/video/fbdev/omap2/omapfb/dss/venc.c
> index c9d40e28a06f..0bd80d3b8f1b 100644
> --- a/drivers/video/fbdev/omap2/omapfb/dss/venc.c
> +++ b/drivers/video/fbdev/omap2/omapfb/dss/venc.c
> @@ -24,6 +24,7 @@
>  #include <linux/regulator/consumer.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/of.h>
> +#include <linux/of_graph.h>
>  #include <linux/component.h>
>  
>  #include <video/omapfb_dss.h>
> @@ -764,7 +765,7 @@ static int venc_probe_of(struct platform_device *pdev)
>  	u32 channels;
>  	int r;
>  
> -	ep = omapdss_of_get_first_endpoint(node);
> +	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
>  	if (!ep)
>  		return 0;
>  
> diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
> index fa943612c4e2..2ef56fa28aff 100644
> --- a/drivers/video/fbdev/pxafb.c
> +++ b/drivers/video/fbdev/pxafb.c
> @@ -2171,7 +2171,7 @@ static int of_get_pxafb_mode_info(struct device *dev,
>  	u32 bus_width;
>  	int ret, i;
>  
> -	np = of_graph_get_next_endpoint(dev->of_node, NULL);
> +	np = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
>  	if (!np) {
>  		dev_err(dev, "could not find endpoint\n");
>  		return -EINVAL;
> diff --git a/include/video/omapfb_dss.h b/include/video/omapfb_dss.h
> index e8eaac2cb7b8..a8c0c3eeeb5b 100644
> --- a/include/video/omapfb_dss.h
> +++ b/include/video/omapfb_dss.h
> @@ -819,9 +819,6 @@ struct device_node *
>  omapdss_of_get_next_endpoint(const struct device_node *parent,
>  			     struct device_node *prev);
>  
> -struct device_node *
> -omapdss_of_get_first_endpoint(const struct device_node *parent);
> -
>  struct omap_dss_device *
>  omapdss_of_find_source_for_first_ep(struct device_node *node);
>  #else

-- 
Regards,

Laurent Pinchart


From nathan at kernel.org  Tue Feb  6 09:06:32 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Tue, 6 Feb 2024 10:06:32 -0700
Subject: [PATCH V8 08/12] drm/bridge: imx: add driver for HDMI TX
 Parallel Video Interface
In-Reply-To: <20240203165307.7806-9-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-9-aford173@gmail.com>
Message-ID: <20240206170632.GA2183819@dev-arch.thelio-3990X>

Hi all,

On Sat, Feb 03, 2024 at 10:52:48AM -0600, Adam Ford wrote:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This IP block is found in the HDMI subsystem of the i.MX8MP SoC. It has a
> full timing generator and can switch between different video sources. On
> the i.MX8MP however the only supported source is the LCDIF. The block
> just needs to be powered up and told about the polarity of the video
> sync signals to act in bypass mode.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v7)
> Tested-by: Marek Vasut <marex at denx.de> (v1)
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v7)
> Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> (v2)
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com> (v3)
> Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> Tested-by: Fabio Estevam <festevam at gmail.com>
> Signed-off-by: Adam Ford <aford173 at gmail.com>

<snip>

> diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> new file mode 100644
> index 000000000000..a76b7669fe8a
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
...
> +static void imx8mp_hdmi_pvi_bridge_enable(struct drm_bridge *bridge,
> +					  struct drm_bridge_state *bridge_state)
> +{
> +	struct drm_atomic_state *state = bridge_state->base.state;
> +	struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);
> +	struct drm_connector_state *conn_state;
> +	const struct drm_display_mode *mode;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_connector *connector;
> +	u32 bus_flags, val;
> +
> +	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
> +	conn_state = drm_atomic_get_new_connector_state(state, connector);
> +	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
> +
> +	if (WARN_ON(pm_runtime_resume_and_get(pvi->dev)))
> +		return;
> +
> +	mode = &crtc_state->adjusted_mode;
> +
> +	val = FIELD_PREP(PVI_CTRL_MODE_MASK, PVI_CTRL_MODE_LCDIF) | PVI_CTRL_EN;
> +
> +	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
> +		val |= PVI_CTRL_OP_VSYNC_POL | PVI_CTRL_INP_VSYNC_POL;
> +
> +	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
> +		val |= PVI_CTRL_OP_HSYNC_POL | PVI_CTRL_INP_HSYNC_POL;
> +
> +	if (pvi->next_bridge->timings)
> +		bus_flags = pvi->next_bridge->timings->input_bus_flags;
> +	else if (bridge_state)
> +		bus_flags = bridge_state->input_bus_cfg.flags;
> +
> +	if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
> +		val |= PVI_CTRL_OP_DE_POL | PVI_CTRL_INP_DE_POL;
> +
> +	writel(val, pvi->regs + HTX_PVI_CTRL);
> +}

Apologies if this has already been reported or fixed, I searched lore
and did not find anything. Clang warns (or errors with CONFIG_WERROR=y)
for this function:

  drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:81:11: error: variable 'bus_flags' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
     81 |         else if (bridge_state)
        |                  ^~~~~~~~~~~~
  drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:84:6: note: uninitialized use occurs here
     84 |         if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
        |             ^~~~~~~~~
  drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:81:7: note: remove the 'if' if its condition is always true
     81 |         else if (bridge_state)
        |              ^~~~~~~~~~~~~~~~~
     82 |                 bus_flags = bridge_state->input_bus_cfg.flags;
  drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:60:15: note: initialize the variable 'bus_flags' to silence this warning
     60 |         u32 bus_flags, val;
        |                      ^
        |                       = 0
  1 error generated.

This seems legitimate. If bridge_state can be NULL, should bus_flags be
initialized to zero like it suggests or should that 'else if' be turned
into a plain 'else'? I am happy to send a patch with that guidance.

Cheers,
Nathan


From jernej.skrabec at gmail.com  Tue Feb  6 09:20:02 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 06 Feb 2024 18:20:02 +0100
Subject: [PATCH 2/2] arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes
In-Reply-To: <CAGb2v66=s-k5xNtL9N_Tyzzk92u_32Hk_+V+rFVYne3=fnMjdA@mail.gmail.com>
References: <20240204093255.148972-1-andre.przywara@arm.com>
 <8371906.NyiUUSuA9g@jernej-laptop>
 <CAGb2v66=s-k5xNtL9N_Tyzzk92u_32Hk_+V+rFVYne3=fnMjdA@mail.gmail.com>
Message-ID: <2717857.mvXUDI8C0e@jernej-laptop>

Dne torek, 06. februar 2024 ob 02:03:21 CET je Chen-Yu Tsai napisal(a):
> On Tue, Feb 6, 2024 at 2:26?AM Jernej ?krabec <jernej.skrabec at gmail.com> wrote:
> >
> > Dne nedelja, 04. februar 2024 ob 10:32:55 CET je Andre Przywara napisal(a):
> > > In contrast to other devices using Allwinner SoCs, the Transpeed 8K618-T
> > > TV box uses a mainline supported WiFi chip: it's a Broadcom 4335
> > > compatible, packaged by a company called Murata.
> > > It works nicely with the Linux driver, when providing the respective
> > > firmware files.
> > >
> > > Add the required DT nodes to let the kernel find the SDIO device.
> >
> > Can you reword message in a way to omit Linux?
> 
> Probably reword it to say "add nodes so that custom MAC addresses can be
> associated with it"?
> 
> > >
> > > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > > ---
> > >  .../sun50i-h618-transpeed-8k618-t.dts         | 23 +++++++++++++++++++
> > >  1 file changed, 23 insertions(+)
> > >
> > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> > > index 8ea1fd41aeba..7ec4098e707b 100644
> > > --- a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> > > @@ -16,6 +16,7 @@ / {
> > >
> > >       aliases {
> > >               serial0 = &uart0;
> > > +             ethernet1 = &sdio_wifi;
> > >       };
> > >
> > >       chosen {
> > > @@ -39,6 +40,15 @@ reg_vcc3v3: vcc3v3 {
> > >               regulator-max-microvolt = <3300000>;
> > >               regulator-always-on;
> > >       };
> > > +
> > > +     wifi_pwrseq: wifi_pwrseq {
> > > +             compatible = "mmc-pwrseq-simple";
> > > +             clocks = <&rtc CLK_OSC32K_FANOUT>;
> > > +             clock-names = "ext_clock";
> > > +             pinctrl-0 = <&x32clk_fanout_pin>;
> > > +             pinctrl-names = "default";
> > > +             reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
> > > +     };
> > >  };
> > >
> > >  &ehci0 {
> > > @@ -60,6 +70,19 @@ &mmc0 {
> > >       status = "okay";
> > >  };
> > >
> > > +&mmc1 {
> > > +     vmmc-supply = <&reg_dldo1>;
> > > +     vqmmc-supply = <&reg_aldo1>;
> > > +     mmc-pwrseq = <&wifi_pwrseq>;
> > > +     bus-width = <4>;
> > > +     non-removable;
> > > +     status = "okay";
> > > +
> > > +     sdio_wifi: wifi at 1 {
> > > +             reg = <1>;
> > > +     };
> >
> > I don't think this node and alias are useful in any way. SDIO scan will find
> > device regardless and potential mac property set up by bootloader will be
> > ignored anyway.
> 
> If a node with the matching function number is found, the MMC core will
> associate the node with the SDIO function device before calling the probe
> function. It has worked correctly for quite some time.

Ah, I didn't know. Ok then, Andre, just update commit message and it's good
to go.

Best regards,
Jernej

> 
> If the driver isn't taking the MAC address given in the DT, then that's
> a driver issue.
> 
> ChenYu
> 
> > Best regards,
> > Jernej
> >
> > > +};
> > > +
> > >  &mmc2 {
> > >       vmmc-supply = <&reg_dldo1>;
> > >       vqmmc-supply = <&reg_aldo1>;
> > >
> >
> >
> >
> >
> 






From quic_jesszhan at quicinc.com  Tue Feb  6 09:24:27 2024
From: quic_jesszhan at quicinc.com (Jessica Zhang)
Date: Tue, 6 Feb 2024 09:24:27 -0800
Subject: [PATCH 4/5] drm/panel: simple: fix flags on RK043FN48H
In-Reply-To: <20240205-ltdc_mp13-v1-4-072d24bf1b36@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
 <20240205-ltdc_mp13-v1-4-072d24bf1b36@foss.st.com>
Message-ID: <80c8f6cf-5419-4c45-8e0f-f5eab7419df3@quicinc.com>



On 2/5/2024 1:06 AM, Raphael Gallais-Pou wrote:
> DISPLAY_FLAGS_SYNC_POSEDGE is missing in the flags on the default
> timings. When overriding the default mode with one described in the
> device tree, the mode does not get acked because of this missing flag.
> Moreover since the panel is driven by the positive edge it makes sense
> to add it here.
> 
> Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>

Hi Raphael,

Reviewed-by: Jessica Zhang <quic_jesszhan at quicinc.com>

Thanks,

Jessica Zhang

> ---
>   drivers/gpu/drm/panel/panel-simple.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index 2214cb09678c..7b286382ffb4 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -3523,7 +3523,8 @@ static const struct display_timing rocktech_rk043fn48h_timing = {
>   	.vfront_porch = { 1, 4, 4 },
>   	.vsync_len = { 1, 10, 10 },
>   	.flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW |
> -		 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE,
> +		 DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
> +		 DISPLAY_FLAGS_SYNC_POSEDGE,
>   };
>   
>   static const struct panel_desc rocktech_rk043fn48h = {
> 
> -- 
> 2.25.1
> 


From jernej.skrabec at gmail.com  Tue Feb  6 09:32:53 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 06 Feb 2024 18:32:53 +0100
Subject: [PATCH 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC support
In-Reply-To: <205b3828-6ec2-4670-ac68-a61e5cc0597d@arm.com>
References: <20240204094404.149776-1-andre.przywara@arm.com>
 <3788758.kQq0lBPeGt@jernej-laptop>
 <205b3828-6ec2-4670-ac68-a61e5cc0597d@arm.com>
Message-ID: <4867577.GXAFRqVoOG@jernej-laptop>

Dne torek, 06. februar 2024 ob 01:47:05 CET je Andre Przywara napisal(a):
> Hi Jernej,
> 
> thanks for having a look!
> 
> On 05/02/2024 19:20, Jernej ?krabec wrote:
> > Dne ponedeljek, 05. februar 2024 ob 19:12:45 CET je Jernej ?krabec napisal(a):
> >> Hi Andre!
> >>
> >> Dne nedelja, 04. februar 2024 ob 10:44:04 CET je Andre Przywara napisal(a):
> >>> The Remix Mini PC is a "mini computer" using the Allwinner H64 SoC,
> >>> which appears to be just a relabelled A64. It was launched in 2015 by
> >>> the now defunct company Jide, and shipped with a desktop optimised
> >>> version of Android. It features
> >>> 	- Allwinner H64 Soc (4 * Arm Cortex-A53 cores)
> >>> 	- 1 or 2 GB DRAM
> >>> 	- 8 or 16 GB eMMC flash
> >>> 	- 100 MBit Ethernet port (using an X-Powers AC200 PHY)
> >>> 	- RTL8723BS WiFi & Bluetooth chip
> >>> 	- HDMI port
> >>> 	- two USB 2.0 ports
> >>> 	- 3.5mm AV port
> >>> 	- microSD card slot
> >>>
> >>> The devicetree covers most peripherals, though there is no agreed
> >>> binding for the PHY chip yet, so this is left out.
> >>>
> >>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> >>> ---
> >>>   arch/arm64/boot/dts/allwinner/Makefile        |   1 +
> >>>   .../allwinner/sun50i-h64-remix-mini-pc.dts    | 357 ++++++++++++++++++
> >>>   2 files changed, 358 insertions(+)
> >>>   create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> >>>
> >>> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> >>> index 91d505b385de..2db3b15ad09f 100644
> >>> --- a/arch/arm64/boot/dts/allwinner/Makefile
> >>> +++ b/arch/arm64/boot/dts/allwinner/Makefile
> >>> @@ -16,6 +16,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb
> >>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab-early-adopter.dtb
> >>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
> >>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
> >>> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
> >>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
> >>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
> >>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
> >>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> >>> new file mode 100644
> >>> index 000000000000..537923a541a8
> >>> --- /dev/null
> >>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> >>> @@ -0,0 +1,357 @@
> >>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> >>> +// Copyright (c) 2018 ARM Ltd.
> >>
> >> Shouldn't be 2024?
> 
> Well, that just documents that sad fact that I indeed created this file 
> 6 years ago, but just managed now to actually send this. Is there a 
> requirement for this being "recent"?

Not really, but it's strange looking. Some might incorrectly assume that it's
present in the kernel longer than it really is.

> 
> >>
> >>> +
> >>> +/dts-v1/;
> >>> +
> >>> +#include "sun50i-a64.dtsi"
> >>> +#include "sun50i-a64-cpu-opp.dtsi"
> >>> +
> >>> +#include <dt-bindings/gpio/gpio.h>
> >>> +
> >>> +/ {
> >>> +	model = "Remix Mini PC";
> >>> +	compatible = "jide,remix-mini-pc", "allwinner,sun50i-h64",
> >>> +		     "allwinner,sun50i-a64";
> >>> +
> >>> +	aliases {
> >>> +		ethernet1 = &rtl8723bs;
> >>> +		serial0 = &uart0;
> >>> +	};
> >>> +
> >>> +	chosen {
> >>> +		stdout-path = "serial0:115200n8";
> >>> +	};
> >>> +
> >>> +	hdmi-connector {
> >>> +		compatible = "hdmi-connector";
> >>> +		type = "a";
> >>> +
> >>> +		port {
> >>> +			hdmi_con_in: endpoint {
> >>> +				remote-endpoint = <&hdmi_out_con>;
> >>> +			};
> >>> +		};
> >>> +	};
> >>> +
> >>> +	reg_vcc5v: regulator-5v {
> >>> +		/* board wide 5V supply directly from the DC input */
> >>> +		compatible = "regulator-fixed";
> >>> +		regulator-name = "vcc-5v";
> >>> +		regulator-min-microvolt = <5000000>;
> >>> +		regulator-max-microvolt = <5000000>;
> >>> +		regulator-always-on;
> >>> +	};
> >>> +
> >>> +	wifi_pwrseq: wifi_pwrseq {
> >>> +		compatible = "mmc-pwrseq-simple";
> >>> +		pinctrl-names = "default";
> >>> +		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
> >>> +		post-power-on-delay-ms = <200>;
> >>> +	};
> >>> +};
> >>> +
> >>> +&codec {
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&codec_analog {
> >>> +	cpvdd-supply = <&reg_eldo1>;
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&cpu0 {
> >>> +	cpu-supply = <&reg_dcdc2>;
> >>> +};
> >>> +
> >>> +&cpu1 {
> >>> +	cpu-supply = <&reg_dcdc2>;
> >>> +};
> >>> +
> >>> +&cpu2 {
> >>> +	cpu-supply = <&reg_dcdc2>;
> >>> +};
> >>> +
> >>> +&cpu3 {
> >>> +	cpu-supply = <&reg_dcdc2>;
> >>> +};
> >>> +
> >>> +&dai {
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&de {
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&ehci0 {
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&ehci1 {
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&hdmi {
> >>> +	hvcc-supply = <&reg_dldo1>;
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&hdmi_out {
> >>> +	hdmi_out_con: endpoint {
> >>> +		remote-endpoint = <&hdmi_con_in>;
> >>> +	};
> >>> +};
> >>> +
> >>> +/* Connects to the AC200 chip */
> >>> +&i2c0 {
> >>> +	pinctrl-names = "default";
> >>> +	pinctrl-0 = <&i2c0_pins>;
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&i2c0_pins {
> >>> +	bias-pull-up;
> >>> +};
> >>> +
> >>> +&mmc0 {
> >>> +	pinctrl-names = "default";
> >>> +	pinctrl-0 = <&mmc0_pins>;
> >>> +	vmmc-supply = <&reg_dcdc1>;
> >>> +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
> >>> +	disable-wp;
> >>> +	bus-width = <4>;
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&mmc1 {
> >>> +	pinctrl-names = "default";
> >>> +	pinctrl-0 = <&mmc1_pins>;
> >>> +	vmmc-supply = <&reg_aldo1>;
> >>> +	vqmmc-supply = <&reg_dldo4>;
> >>> +	mmc-pwrseq = <&wifi_pwrseq>;
> >>> +	bus-width = <4>;
> >>> +	non-removable;
> >>> +	status = "okay";
> >>> +
> >>> +	rtl8723bs: wifi at 1 {
> >>> +		reg = <1>;
> >>> +		interrupt-parent = <&r_pio>;
> >>> +		interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
> >>> +		interrupt-names = "host-wake";
> >>> +	};
> >>
> >> Node without compatible doesn't help. Please remove it.
> 
> Huh, but where do I put the the IRQ line then? And every other RTL8723BS 
> user seems to do the same?

It's good, sorry for the noise.

> 
> >>
> >>> +};
> >>> +
> >>> +&mmc2 {
> >>> +	pinctrl-names = "default";
> >>> +	pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
> >>> +	vmmc-supply = <&reg_dcdc1>;
> >>> +	vqmmc-supply = <&reg_eldo1>;
> >>> +	bus-width = <8>;
> >>> +	non-removable;
> >>> +	mmc-ddr-1_8v;
> >>> +	mmc-hs200-1_8v;
> >>
> >> Aren't these speed modes enabled by default?
> 
> Enabled by who? Our current sunxi-mmc driver? I cannot find anything in 
> the binding that suggests that there would be some default settings.

Looking at Linux sunxi mmc driver, mmc-ddr-1_8v is enabled by default for
"new timings" variants except for H5. Anyway...

> 
> > Sorry, mmc-hs200-1_8v is ok, but mmc-ddr-1_8v should be
> > removed.
> 
> Mmh, I am confused: I thought after the H5 eMMC mishap we figured that 
> all speed modes supported by the eMMC chip should be listed in the DT?

I think H5 just has (had?) driver issue. From what I can see, only highest
supported mode by kernel and chip is specified in all Allwinner DTs.
mmc-ddr-1_8v is only specified by two recent board addition, where I missed
it while reviewing.

> So any driver wouldn't need to make assumptions, and if a particular 
> mode shows problems on a board, we just remove that mode from the DT.
> Actually, thinking about that, I guess I should list HS-400 as well? The 
> BSP kernel uses that mode.

Sure, but it also calibrates timing for it. If you'll specify HS400, kernel
will try to use it, but it won't work.

> Or do you mean to say that in particular DDR (@1.8V) is problematic? I 
> cannot test at the moment, but could try later to force that mode.

No, no need.

Best regards,
Jernej

> 
> Cheers,
> Andre
> 
> 
> >>> +	cap-mmc-hw-reset;
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&ohci0 {
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&ohci1 {
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&pio {
> >>> +	vcc-pb-supply = <&reg_dcdc1>;
> >>> +	vcc-pc-supply = <&reg_dcdc1>;
> >>> +	vcc-pd-supply = <&reg_dcdc1>;
> >>> +	vcc-pe-supply = <&reg_dcdc1>;
> >>> +	vcc-pf-supply = <&reg_dcdc1>;
> >>> +	vcc-pg-supply = <&reg_dldo4>;
> >>> +	vcc-ph-supply = <&reg_dcdc1>;
> >>> +};
> >>> +
> >>> +&r_ir {
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&r_pio {
> >>> +	/*
> >>> +	 * We cannot add that supply for now since it would create a circular
> >>> +	 * dependency between pinctrl, the regulator and the RSB Bus.
> >>> +	 *
> >>> +	 * vcc-pl-supply = <&reg_aldo2>;
> >>> +	 */
> >>> +};
> >>> +
> >>> +&r_rsb {
> >>> +	status = "okay";
> >>> +
> >>> +	axp803: pmic at 3a3 {
> >>> +		compatible = "x-powers,axp803";
> >>> +		reg = <0x3a3>;
> >>> +		interrupt-parent = <&r_intc>;
> >>> +		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
> >>> +		x-powers,drive-vbus-en;
> >>> +
> >>> +		vin1-supply = <&reg_vcc5v>;
> >>> +		vin2-supply = <&reg_vcc5v>;
> >>> +		vin3-supply = <&reg_vcc5v>;
> >>> +		vin5-supply = <&reg_vcc5v>;
> >>> +		vin6-supply = <&reg_vcc5v>;
> >>> +		aldoin-supply = <&reg_vcc5v>;
> >>> +		dldoin-supply = <&reg_vcc5v>;
> >>> +		eldoin-supply = <&reg_vcc5v>;
> >>> +		fldoin-supply = <&reg_vcc5v>;
> >>> +		drivevbus-supply = <&reg_vcc5v>;
> >>> +		ips-supply = <&reg_vcc5v>;
> >>> +
> >>> +		status = "okay";
> >>> +	};
> >>> +};
> >>> +
> >>> +#include "axp803.dtsi"
> >>> +
> >>> +&ac_power_supply {
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&reg_dcdc1 {
> >>> +	regulator-always-on;
> >>> +	regulator-min-microvolt = <3300000>;
> >>> +	regulator-max-microvolt = <3300000>;
> >>> +	regulator-name = "vcc-3v3";
> >>> +};
> >>> +
> >>> +&reg_dcdc2 {
> >>> +	regulator-always-on;
> >>> +	regulator-min-microvolt = <1040000>;
> >>> +	regulator-max-microvolt = <1300000>;
> >>> +	regulator-name = "vdd-cpux";
> >>> +};
> >>> +
> >>> +/* DCDC3 is polyphased with DCDC2 */
> >>> +
> >>> +&reg_dcdc5 {
> >>> +	regulator-always-on;
> >>> +	regulator-min-microvolt = <1500000>;
> >>> +	regulator-max-microvolt = <1500000>;
> >>> +	regulator-name = "vcc-dram";
> >>> +};
> >>> +
> >>> +/* Deviates from the reset default of 1.1V. */
> >>> +&reg_dcdc6 {
> >>> +	regulator-always-on;
> >>> +	regulator-min-microvolt = <1200000>;
> >>> +	regulator-max-microvolt = <1200000>;
> >>> +	regulator-name = "vdd-sys";
> >>> +};
> >>> +
> >>> +&reg_aldo1 {
> >>> +	regulator-min-microvolt = <3300000>;
> >>> +	regulator-max-microvolt = <3300000>;
> >>> +	regulator-name = "vcc-wifi";
> >>> +};
> >>> +
> >>> +&reg_aldo2 {
> >>> +	/* Specifying R_PIO consumer would create circular dependency. */
> >>> +	regulator-always-on;
> >>> +	regulator-min-microvolt = <3300000>;
> >>> +	regulator-max-microvolt = <3300000>;
> >>> +	regulator-name = "vcc-pl";
> >>> +};
> >>> +
> >>> +&reg_aldo3 {
> >>> +	regulator-always-on;
> >>> +	regulator-min-microvolt = <3000000>;
> >>> +	regulator-max-microvolt = <3000000>;
> >>> +	regulator-name = "vcc-pll-avcc";
> >>> +};
> >>> +
> >>> +/* AC200 power supply */
> >>> +&reg_dldo1 {
> >>> +	regulator-always-on;
> >>> +	regulator-min-microvolt = <3300000>;
> >>> +	regulator-max-microvolt = <3300000>;
> >>> +	regulator-name = "vcc-ave-33";
> >>> +};
> >>> +
> >>> +&reg_dldo4 {
> >>> +	regulator-min-microvolt = <3300000>;
> >>> +	regulator-max-microvolt = <3300000>;
> >>> +	regulator-name = "vcc-wifi-io";
> >>> +};
> >>> +
> >>> +&reg_drivevbus {
> >>> +	regulator-name = "usb0-vbus";
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&reg_eldo1 {
> >>> +	regulator-always-on;
> >>> +	regulator-min-microvolt = <1800000>;
> >>> +	regulator-max-microvolt = <1800000>;
> >>> +	regulator-name = "vcc-cpvdd-dram-emmc";
> >>> +};
> >>> +
> >>> +/* Supplies the arisc management core, needed by TF-A to power off cores. */
> >>> +&reg_fldo2 {
> >>> +	regulator-always-on;
> >>> +	regulator-min-microvolt = <1100000>;
> >>> +	regulator-max-microvolt = <1100000>;
> >>> +	regulator-name = "vdd-cpus";
> >>> +};
> >>> +
> >>> +&reg_rtc_ldo {
> >>> +	regulator-name = "vcc-rtc";
> >>> +};
> >>> +
> >>> +&simplefb_hdmi {
> >>> +	vcc-hdmi-supply = <&reg_dcdc1>;
> >>> +};
> >>> +
> >>> +&sound {
> >>> +	simple-audio-card,aux-devs = <&codec_analog>;
> >>> +	simple-audio-card,widgets = "Microphone", "Microphone Jack",
> >>> +				    "Headphone", "Headphone Jack";
> >>> +	simple-audio-card,routing =
> >>> +			"Left DAC", "DACL",
> >>> +			"Right DAC", "DACR",
> >>> +			"Headphone Jack", "HP",
> >>> +			"ADCL", "Left ADC",
> >>> +			"ADCR", "Right ADC",
> >>> +			"MIC2", "Microphone Jack";
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +/* On the (unpopulated) UART pads. */
> >>> +&uart0 {
> >>> +	pinctrl-names = "default";
> >>> +	pinctrl-0 = <&uart0_pb_pins>;
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&uart1 {
> >>> +	pinctrl-names = "default";
> >>> +	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
> >>> +	uart-has-rtscts;
> >>> +	status = "okay";
> >>> +
> >>> +	bluetooth {
> >>> +		compatible = "realtek,rtl8723bs-bt";
> >>> +		enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
> >>> +		max-speed = <1500000>;
> >>> +	};
> >>> +};
> >>> +
> >>> +&usb_otg {
> >>> +	dr_mode = "host";
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&usbphy {
> >>> +	usb0_vbus-supply = <&reg_drivevbus>;
> >>> +	usb1_vbus-supply = <&reg_drivevbus>;
> >>> +	status = "okay";
> >>> +};
> >>>
> >>
> >>
> >>
> >>
> >>
> > 
> > 
> > 
> > 
> 






From luca.ceresoli at bootlin.com  Tue Feb  6 09:34:43 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Tue, 6 Feb 2024 18:34:43 +0100
Subject: [PATCH V8 01/12] dt-bindings: phy: add binding for the i.MX8MP
 HDMI PHY
In-Reply-To: <20240203165307.7806-2-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-2-aford173@gmail.com>
Message-ID: <20240206183443.000dca1b@booty>

On Sat,  3 Feb 2024 10:52:41 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> Add a DT binding for the HDMI PHY found on the i.MX8MP SoC.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From afd at ti.com  Tue Feb  6 09:34:48 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 6 Feb 2024 11:34:48 -0600
Subject: [PATCH v4 3/3] arm64: dts: ti: k3-am62p: add the USB sub-system
In-Reply-To: <77f7b127-e609-45e3-90aa-67aa7838ce6b@kernel.org>
References: <20240205135908.54656-1-rogerq@kernel.org>
 <20240205135908.54656-4-rogerq@kernel.org>
 <45a0ed98-8dd2-4c5b-8e89-40c70e3fe831@ti.com>
 <77f7b127-e609-45e3-90aa-67aa7838ce6b@kernel.org>
Message-ID: <8f9e8ec5-fc78-4b51-b36f-3ba06768ce62@ti.com>

On 2/6/24 6:30 AM, Roger Quadros wrote:
> 
> 
> On 05/02/2024 19:34, Andrew Davis wrote:
>> On 2/5/24 7:59 AM, Roger Quadros wrote:
>>> There are two USB instances available on the am62p5 starter kit. Include
>>> and enable them for use on the board.
>>>
>>> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
>>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>>> ---
>>>
>>> Notes:
>>>  ???? Changelog:
>>>  ???? ???? v4 - no change
>>>  ???? ???? v3 - no change
>>>  ???? https://lore.kernel.org/all/20240201120332.4811-4-rogerq at kernel.org/
>>>  ???? ???? v2:
>>>  ???? - added USB PHY CTRL node changes here
>>>  ???? - changed USB wrapper node names to usb@
>>>  ???? - changed Type-C chip node name to usb-power-control@
>>>
>>>  ? arch/arm64/boot/dts/ti/k3-am62p-main.dtsi?? | 46 ++++++++++++++
>>>  ? arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi | 10 +++
>>>  ? arch/arm64/boot/dts/ti/k3-am62p5-sk.dts???? | 67 +++++++++++++++++++++
>>>  ? 3 files changed, 123 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
>>> index 4c51bae06b57..17d28390d587 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
>>> @@ -560,6 +560,52 @@ sdhci2: mmc at fa20000 {
>>>  ????????? status = "disabled";
>>>  ????? };
>>>  ? +??? usbss0: usb at f900000 {
>>> +??????? compatible = "ti,am62-usb";
>>> +??????? reg = <0x00 0x0f900000 0x00 0x800>;
>>> +??????? clocks = <&k3_clks 161 3>;
>>> +??????? clock-names = "ref";
>>> +??????? ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
>>> +??????? #address-cells = <2>;
>>> +??????? #size-cells = <2>;
>>> +??????? power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
>>> +??????? ranges;
>>> +??????? status = "disabled";
>>> +
>>> +??????? usb0: usb at 31000000 {
>>> +??????????? compatible = "snps,dwc3";
>>> +??????????? reg = <0x00 0x31000000 0x00 0x50000>;
>>> +??????????? interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
>>> +??????????? <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
>>> +??????????? interrupt-names = "host", "peripheral";
>>> +??????????? maximum-speed = "high-speed";
>>> +??????????? dr_mode = "otg";
>>> +??????? };
>>> +??? };
>>> +
>>> +??? usbss1: usb at f910000 {
>>> +??????? compatible = "ti,am62-usb";
>>> +??????? reg = <0x00 0x0f910000 0x00 0x800>;
>>> +??????? clocks = <&k3_clks 162 3>;
>>> +??????? clock-names = "ref";
>>> +??????? ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
>>> +??????? #address-cells = <2>;
>>> +??????? #size-cells = <2>;
>>> +??????? power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
>>> +??????? ranges;
>>> +??????? status = "disabled";
>>> +
>>> +??????? usb1: usb at 31100000 {
>>> +??????????? compatible = "snps,dwc3";
>>> +??????????? reg = <0x00 0x31100000 0x00 0x50000>;
>>> +??????????? interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
>>> +??????????? <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
>>> +??????????? interrupt-names = "host", "peripheral";
>>> +??????????? maximum-speed = "high-speed";
>>> +??????????? dr_mode = "otg";
>>> +??????? };
>>> +??? };
>>> +
>>>  ????? fss: bus at fc00000 {
>>>  ????????? compatible = "simple-bus";
>>>  ????????? reg = <0x00 0x0fc00000 0x00 0x70000>;
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
>>> index 19f42b39394e..00dd38b02a52 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
>>> @@ -18,6 +18,16 @@ chipid: chipid at 14 {
>>>  ????????????? reg = <0x14 0x4>;
>>>  ????????????? bootph-all;
>>>  ????????? };
>>> +
>>> +??????? usb0_phy_ctrl: syscon at 4008 {
>>> +??????????? compatible = "ti,am62-usb-phy-ctrl", "syscon";
>>> +??????????? reg = <0x4008 0x4>;
>>> +??????? };
>>> +
>>> +??????? usb1_phy_ctrl: syscon at 4018 {
>>> +??????????? compatible = "ti,am62-usb-phy-ctrl", "syscon";
>>> +??????????? reg = <0x4018 0x4>;
>>> +??????? };
>>>  ????? };
>>>  ? ????? wkup_uart0: serial at 2b300000 {
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>>> index 1773c05f752c..80be56c0a4e0 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>>> @@ -27,6 +27,8 @@ aliases {
>>>  ????????? spi0 = &ospi0;
>>>  ????????? ethernet0 = &cpsw_port1;
>>>  ????????? ethernet1 = &cpsw_port2;
>>> +??????? usb0 = &usb0;
>>> +??????? usb1 = &usb1;
>>>  ????? };
>>>  ? ????? chosen {
>>> @@ -297,6 +299,12 @@ AM62PX_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (G20) MCASP0_ACLKR.UART1_TXD */
>>>  ????????? bootph-all;
>>>  ????? };
>>>  ? +??? main_usb1_pins_default: main-usb1-default-pins {
>>> +??????? pinctrl-single,pins = <
>>> +??????????? AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
>>> +??????? >;
>>> +??? };
>>> +
>>>  ????? main_wlirq_pins_default: main-wlirq-default-pins {
>>>  ????????? pinctrl-single,pins = <
>>>  ????????????? AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
>>> @@ -340,6 +348,36 @@ AM62PX_IOPAD(0x0124, PIN_INPUT, 7) /* (J25) MMC2_SDCD.GPIO0_71 */
>>>  ????? };
>>>  ? };
>>>  ? +&main_i2c0 {
>>> +??? status = "okay";
>>> +??? pinctrl-names = "default";
>>> +??? pinctrl-0 = <&main_i2c0_pins_default>;
>>> +??? clock-frequency = <400000>;
>>> +
>>> +??? typec_pd0: usb-power-controller at 3f {
>>> +??????? compatible = "ti,tps6598x";
>>> +??????? reg = <0x3f>;
>>> +
>>> +??????? connector {
>>> +??????????? compatible = "usb-c-connector";
>>> +??????????? label = "USB-C";
>>> +??????????? self-powered;
>>> +??????????? data-role = "dual";
>>> +??????????? power-role = "sink";
>>> +??????????? ports {
>>> +??????????????? #address-cells = <1>;
>>> +??????????????? #size-cells = <0>;
>>> +??????????????? port at 0 {
>>> +??????????????????? reg = <0>;
>>> +??????????????????? usb_con_hs: endpoint {
>>> +??????????????????????? remote-endpoint = <&usb0_hs_ep>;
>>> +??????????????????? };
>>> +??????????????? };
>>> +??????????? };
>>> +??????? };
>>> +??? };
>>> +};
>>> +
>>>  ? &main_i2c1 {
>>>  ????? status = "okay";
>>>  ????? pinctrl-names = "default";
>>> @@ -460,6 +498,35 @@ cpsw3g_phy1: ethernet-phy at 1 {
>>>  ????? };
>>>  ? };
>>>  ? +&usbss0 {
>>> +??? status = "okay";
>>> +??? ti,vbus-divider;
>>> +};
>>> +
>>> +&usbss1 {
>>> +??? status = "okay";
>>> +??? ti,vbus-divider;
>>> +};
>>> +
>>> +&usb0 {
>>> +??? usb-role-switch;
>>> +??? #address-cells = <1>;
>>> +??? #size-cells = <0>;
>>> +
>>> +??? port at 0 {
>>> +??????? reg = <0>;
>>> +??????? usb0_hs_ep: endpoint {
>>> +??????????? remote-endpoint = <&usb_con_hs>;
>>> +??????? };
>>> +??? };
>>> +};
>>> +
>>> +&usb1 {
>>> +??? dr_mode = "host";
>>> +??? pinctrl-names = "default";
>>> +??? pinctrl-0 = <&main_usb1_pins_default>;
>>
>> I'm not super familiar with USB, but I see this pinmux for the
>> "DRVVBUS" pin is usually added the the parent USB subsystem node (usbss).
>> Does this pin belong to the subsystem or the specific USB instance?
>>
> There is only 1 USB instance per USB sub-system.
> The "DRVVBUS" pin is a control signal to enable the VBUS regulator
> while in host mode.
> 
> Just probing the usbss1 driver has no use of "DRVVBUS".
> I think usb1 is the right place as it is used there.
> 

Seems reasonable, so if there ever was more than 1 instance
per sub-system, each instance would need its own pin?

We should move these pinctrl to the instance node in the other
dts files at some point then.

Reviewed-by: Andrew Davis <afd at ti.com>

>> Andrew
>>
>>> +};
>>> +
>>>  ? &mcasp1 {
>>>  ????? status = "okay";
>>>  ????? #sound-dai-cells = <0>;
> 


From luca.ceresoli at bootlin.com  Tue Feb  6 09:35:17 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Tue, 6 Feb 2024 18:35:17 +0100
Subject: [PATCH V8 02/12] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240203165307.7806-3-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-3-aford173@gmail.com>
Message-ID: <20240206183517.2b9dfb07@booty>

On Sat,  3 Feb 2024 10:52:42 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the driver for the Samsung HDMI PHY found on the
> i.MX8MP SoC.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>

[...]

> +#define PHY_REG_33		0x84
> +#define  REG33_MODE_SET_DONE	BIT(7)
> +#define  REG33_FIX_DA		BIT(1)
> +
> +#define PHY_REG_34		0x88
> +#define  REG34_PHY_READY	BIT(7)
> +#define  REG34_PLL_LOCK		BIT(6)
> +#define  REG34_PHY_CLK_READY	BIT(5)
> +
> +

Nitpick: only one empty line here.

> +#define PHY_PLL_REGS_NUM 48

[...]

> +static int phy_clk_register(struct fsl_samsung_hdmi_phy *phy)
> +{
> +	struct device *dev = phy->dev;
> +	struct device_node *np = dev->of_node;
> +	struct clk_init_data init;
> +	const char *parent_name;
> +	struct clk *phyclk;
> +	int ret;
> +
> +	parent_name = __clk_get_name(phy->refclk);
> +
> +	init.parent_names = &parent_name;
> +	init.num_parents = 1;
> +	init.flags = 0;
> +	init.name = "hdmi_pclk";
> +	init.ops = &phy_clk_ops;
> +
> +	phy->hw.init = &init;
> +
> +	phyclk = devm_clk_register(dev, &phy->hw);
> +	if (IS_ERR(phyclk))
> +		return dev_err_probe(dev, PTR_ERR(phyclk),
> +				     "failed to register clock\n");
> +
> +	ret = of_clk_add_provider(np, of_clk_src_simple_get, phyclk);

Ouch:

> This function is *deprecated*. Use of_clk_add_hw_provider() instead.

Appears as an easy replacement though.

Otherwise looks good.

Luca

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From luca.ceresoli at bootlin.com  Tue Feb  6 09:35:28 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Tue, 6 Feb 2024 18:35:28 +0100
Subject: [PATCH V8 07/12] dt-bindings: display: imx: add binding for
 i.MX8MP HDMI PVI
In-Reply-To: <20240203165307.7806-8-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-8-aford173@gmail.com>
Message-ID: <20240206183528.5b2e587f@booty>

Hi Adam,

On Sat,  3 Feb 2024 10:52:47 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> Add binding for the i.MX8MP HDMI parallel video interface block.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From luca.ceresoli at bootlin.com  Tue Feb  6 09:35:37 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Tue, 6 Feb 2024 18:35:37 +0100
Subject: [PATCH V8 09/12] dt-bindings: display: imx: add binding for
 i.MX8MP HDMI TX
In-Reply-To: <20240203165307.7806-10-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-10-aford173@gmail.com>
Message-ID: <20240206183537.38360f1d@booty>

On Sat,  3 Feb 2024 10:52:49 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> The HDMI TX controller on the i.MX8MP SoC is a Synopsys designware IP
> core with a little bit of SoC integration around it.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>

[...]

> +examples:
> +  - |
> +    #include <dt-bindings/clock/imx8mp-clock.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/power/imx8mp-power.h>
> +
> +    hdmi at 32fd8000 {
> +        compatible = "fsl,imx8mp-hdmi-tx";
> +        reg = <0x32fd8000 0x7eff>;
> +        interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
> +        clocks = <&clk IMX8MP_CLK_HDMI_APB>,
> +                 <&clk IMX8MP_CLK_HDMI_REF_266M>,
> +                 <&clk IMX8MP_CLK_32K>,
> +                 <&hdmi_tx_phy>;
> +        clock-names = "iahb", "isfr", "cec", "pix";
> +        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
> +        reg-io-width = <1>;
> +        ports {
> +           #address-cells = <1>;
> +           #size-cells = <0>;
> +           port at 0 {
> +             reg = <0>;
> +
> +             hdmi_tx_from_pvi: endpoint {
> +               remote-endpoint = <&pvi_to_hdmi_tx>;
> +             };
> +          };
> +
> +          port at 1 {
> +            reg = <1>;
> +              hdmi_tx_out: endpoint {

Two excess indenting spaces on this line (port at 0 is correct).
Also, I think there should an empty line between properties and nodes.

With these fixed:
Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

Luca

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From luca.ceresoli at bootlin.com  Tue Feb  6 09:35:57 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Tue, 6 Feb 2024 18:35:57 +0100
Subject: [PATCH V8 10/12] drm/bridge: imx: add bridge wrapper driver for
 i.MX8MP DWC HDMI
In-Reply-To: <20240203165307.7806-11-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-11-aford173@gmail.com>
Message-ID: <20240206183557.408399f0@booty>

On Sat,  3 Feb 2024 10:52:50 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> Add a simple wrapper driver for the DWC HDMI bridge driver that
> implements the few bits that are necessary to abstract the i.MX8MP
> SoC integration.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Tested-by: Marek Vasut <marex at denx.de>
> Tested-by: Adam Ford <aford173 at gmail.com> #imx8mp-beacon
> Tested-by: Richard Leitner <richard.leitner at skidata.com>
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> Signed-off-by:  Adam Ford <aford173 at gmail.com>

Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From quic_jesszhan at quicinc.com  Tue Feb  6 09:37:11 2024
From: quic_jesszhan at quicinc.com (Jessica Zhang)
Date: Tue, 6 Feb 2024 09:37:11 -0800
Subject: [PATCH 5/5] drm/panel: simple: push blanking limit on RK32FN48H
In-Reply-To: <20240205-ltdc_mp13-v1-5-116d43ebba75@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-116d43ebba75@foss.st.com>
 <20240205-ltdc_mp13-v1-5-116d43ebba75@foss.st.com>
Message-ID: <6436b9c7-de53-4248-9c06-48c39c54e014@quicinc.com>



On 2/5/2024 1:26 AM, Raphael Gallais-Pou wrote:
> Push horizontal front porch and vertical back porch blanking limit.
> This allows to get a 60 fps sharp.
> 
> Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>

Hi Raphael,

Reviewed-by: Jessica Zhang <quic_jesszhan at quicinc.com>

Thanks,

Jessica Zhang

> ---
>   drivers/gpu/drm/panel/panel-simple.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index 7b286382ffb4..10b361d603be 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -3516,10 +3516,10 @@ static const struct display_timing rocktech_rk043fn48h_timing = {
>   	.pixelclock = { 6000000, 9000000, 12000000 },
>   	.hactive = { 480, 480, 480 },
>   	.hback_porch = { 8, 43, 43 },
> -	.hfront_porch = { 2, 8, 8 },
> +	.hfront_porch = { 2, 8, 10 },
>   	.hsync_len = { 1, 1, 1 },
>   	.vactive = { 272, 272, 272 },
> -	.vback_porch = { 2, 12, 12 },
> +	.vback_porch = { 2, 12, 26 },
>   	.vfront_porch = { 1, 4, 4 },
>   	.vsync_len = { 1, 10, 10 },
>   	.flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW |
> 
> -- 
> 2.25.1
> 


From anup at brainfault.org  Tue Feb  6 09:39:44 2024
From: anup at brainfault.org (Anup Patel)
Date: Tue, 6 Feb 2024 23:09:44 +0530
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <87h6ily53k.fsf@all.your.base.are.belong.to.us>
References: <20240127161753.114685-1-apatel@ventanamicro.com> <87h6ily53k.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAAhSdy2PPjS6++Edh8NkgiBmcovTUjS5oXE2eR5ZwPfAfVA0ng@mail.gmail.com>

On Tue, Feb 6, 2024 at 9:09?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Hi Anup,
>
> Anup Patel <apatel at ventanamicro.com> writes:
>
> > The RISC-V AIA specification is ratified as-per the RISC-V international
> > process. The latest ratified AIA specifcation can be found at:
> > https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf
> >
> > At a high-level, the AIA specification adds three things:
> > 1) AIA CSRs
> >    - Improved local interrupt support
> > 2) Incoming Message Signaled Interrupt Controller (IMSIC)
> >    - Per-HART MSI controller
> >    - Support MSI virtualization
> >    - Support IPI along with virtualization
> > 3) Advanced Platform-Level Interrupt Controller (APLIC)
> >    - Wired interrupt controller
> >    - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
> >    - In Direct-mode, injects external interrupts directly into HARTs
> >
> > For an overview of the AIA specification, refer the AIA virtualization
> > talk at KVM Forum 2022:
> > https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
> > https://www.youtube.com/watch?v=r071dL8Z0yo
>
> Thank you for continuing to work on this series! I like this
> direction of the series!
>
> TL;DR: I think we can get rid of most of the id/householding data
> structures, except for the irq matrix.
>
> Most of my comments are more of a design/overview nature, so I'll
> comment here in the cover letter.
>
> I took the series for a spin with and it with Alex' ftrace fix it,
> passes all my tests nicely!
>
> Now some thoughts/comments (I'm coming from the x86 side of things!):
>
> id/enable-tracking: There are a lot of different id/enabled tracking
> with corresponding locks, where there's IMO overlap with what the
> matrix provides.

The matrix allocator does not track the enabled/disabled state of
the per-CPU IDs. This is why we have a separate per-CPU
ids_enabled_bitmap which is also used for remote synchronization
across CPUs.

>
> Let's start with struct imsic_priv:
>
>    | /* Dummy HW interrupt numbers */
>    | unsigned int nr_hwirqs;
>    | raw_spinlock_t hwirqs_lock;
>    | unsigned long *hwirqs_used_bitmap;

The matrix allocator manages actual IDs for each CPU whereas
the Linux irq_data expects a fixed hwirq which does not change.

Due to this, we have a dummy hwirq space which is always
fixed. The only thing that is changed under-the-hood by the
IMSIC driver is the dummy hwirq to actual HW vector (cpu, id)
mapping.

>
> These are used to for the domain routing (hwirq -> desc/virq), and not
> needed. Just use the same id as virq (at allocation time), and get rid
> of these data structures/corresponding functions. The lookup in the
> interrupt handler via imsic_local_priv.vectors doesn't care about
> hwirq. This is what x86 does... The imsic_vector roughly corresponds
> to apic_chip_data (nit: imsic_vector could have the chip_data suffix
> as well, at least it would have helped me!)

Yes, imsic_vector corresponds to apic_chip_data in the x86 world.

>
> Moving/affinity changes. The moving of a vector to another CPU
> currently involves:
>
> 1. Allocate a new vector from the matrix
> 2. Disable/enable the corresponding per-cpu ids_enabled_bitmap (nested
>    spinlocks)
> 3. Trigger two IPIs to apply the bitmap
> 4. On each CPU target (imsic_local_sync()) loop the bitmap and flip
>    all bits, and potentially rearm
>
> This seems a bit heavy-weight: Why are you explicitly setting/clearing
> all the bits in a loop at the local sync?

This can be certainly optimized by introducing another
ids_dirty_bitmap. I will add this in the next revision.

>
> x86 does it a bit differently (more lazily): The chip_data has
> prev_{cpu,vector}/move_in_progress fields, and keep both vectors
> enabled until there's an interrupt on the new vector, and then the old
> one is cleaned (irq_complete_move()).
>
> Further; When it's time to remove the old vector, x86 doesn't trigger
> an IPI on the disabling side, but queues a cleanup job on a per-cpu
> list and triggers a timeout. So, the per-cpu chip_data (per-cpu
> "vectors" in your series) can reside in two places during the transit.

We can't avoid IPIs when moving vectors from one CPU to another
CPU because IMSIC id enable/disable is only possible through
CSRs. Also, keep in-mind that irq affinity change might be initiated
on CPU X for some interrupt targeting CPU Y which is then changed
to target CPU Z.

In the case of x86, they have memory mapped registers which
allows one CPU to enable/disable the ID of another CPU.

>
> I wonder if this clean up is less intrusive, and you just need to
> perform what's in the per-list instead of dealing with the
> ids_enabled_bitmap? Maybe we can even remove that bitmap as well. The
> chip_data/desc has that information. This would mean that
> imsic_local_priv() would only have the local vectors (chip_data), and
> a cleanup list/timer.
>
> My general comment is that instead of having these global id-tracking
> structures, use the matrix together with some desc/chip_data local
> data, which should be sufficient.

The "ids_enabled_bitmap", "dummy hwirqs" and private imsic_vectors
are required since the matrix allocator only manages allocation of
per-CPU IDs.

>
> Random thought: Do we need to explicitly disable (csr) the vector,
> when we're changing the affinity? What if we just leave it enabled,
> and only when mask/unmask is performed it's actually explicitly masked
> (writes to the csr)?

We should not leave it enabled because some rough/buggy device
can inject spurious interrupts using MSI writes to unused enabled
interrupts.

>
> Missing features (which can be added later):
> * Reservation mode/activate support (allocate many MSI, but only
>   request/activate a subset)

I did not see any PCIe or platform device requiring this kind of
reservation. Any examples ?

> * Handle managed interrupts

Any examples of managed interrupts in the RISC-V world ?

> * There might be some irqd flags are missing, which mostly cpuhp care
>   about (e.g. irqd_*_single_target())...

Okay, let me check and update.

>
> Finally; Given that the APLIC requires a lot more patches, depending
> on how the review process moves on -- maybe the IMSIC side could go as
> a separate series?
>

The most popular implementation choice across RISC-V platforms
will be IMSIC + APLIC so both drivers should go together. In fact,
we need both drivers for the QEMU virt machine as well because
UART interrupt (and other wired interrupts) on the QEMU virt
machine goes through APLIC.

Regards,
Anup


From jernej.skrabec at gmail.com  Tue Feb  6 09:44:33 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 06 Feb 2024 18:44:33 +0100
Subject: [PATCH v2 1/6] clk: sunxi-ng: nkm: Support constraints on m/n ratio and
 parent rate
In-Reply-To: <87il32ztp8.fsf@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <2717565.mvXUDI8C0e@jernej-laptop> <87il32ztp8.fsf@oltmanns.dev>
Message-ID: <2172947.irdbgypaU6@jernej-laptop>

Dne ponedeljek, 05. februar 2024 ob 18:50:27 CET je Frank Oltmanns napisal(a):
> Hi Jernej,
> 
> On 2024-02-05 at 18:45:27 +0100, Jernej ?krabec <jernej.skrabec at gmail.com> wrote:
> > Dne ponedeljek, 05. februar 2024 ob 16:22:24 CET je Frank Oltmanns napisal(a):
> >> The Allwinner A64 manual lists the following constraints for the
> >> PLL-MIPI clock:
> >>  - M/N <= 3
> >>  - (PLL_VIDEO0)/M >= 24MHz
> >>
> >> The PLL-MIPI clock is implemented as ccu_nkm. Therefore, add support for
> >> these constraints.
> >>
> >> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> >
> > Haven't we discussed that this patch is unnecessary because same effect can
> > be reached by limiting minimum frequency?
> 
> The patch for ccu_nm was unnecessary:
> https://lore.kernel.org/all/87jzoug2jz.fsf at oltmanns.dev/
> 
> Unfortunately, we still need this one.

Ok, then:
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> 
> Best regards,
>   Frank
> 
> >
> > Best regards,
> > Jernej
> >
> >> ---
> >>  drivers/clk/sunxi-ng/ccu_nkm.c | 21 +++++++++++++++++++++
> >>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
> >>  2 files changed, 23 insertions(+)
> >>
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> index 853f84398e2b..1168d894d636 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> @@ -16,6 +16,20 @@ struct _ccu_nkm {
> >>  	unsigned long	m, min_m, max_m;
> >>  };
> >>
> >> +static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned long parent,
> >> +				  unsigned long n, unsigned long m)
> >> +{
> >> +	struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common);
> >> +
> >> +	if (nkm->max_m_n_ratio && (m > nkm->max_m_n_ratio * n))
> >> +		return false;
> >> +
> >> +	if (nkm->min_parent_m_ratio && (parent < nkm->min_parent_m_ratio * m))
> >> +		return false;
> >> +
> >> +	return true;
> >> +}
> >> +
> >>  static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common,
> >>  						       struct clk_hw *parent_hw,
> >>  						       unsigned long *parent, unsigned long rate,
> >> @@ -31,6 +45,10 @@ static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common
> >>  				unsigned long tmp_rate, tmp_parent;
> >>
> >>  				tmp_parent = clk_hw_round_rate(parent_hw, rate * _m / (_n * _k));
> >> +
> >> +				if (!ccu_nkm_is_valid_rate(common, tmp_parent, _n, _m))
> >> +					continue;
> >> +
> >>  				tmp_rate = tmp_parent * _n * _k / _m;
> >>
> >>  				if (ccu_is_better_rate(common, rate, tmp_rate, best_rate) ||
> >> @@ -64,6 +82,9 @@ static unsigned long ccu_nkm_find_best(unsigned long parent, unsigned long rate,
> >>  	for (_k = nkm->min_k; _k <= nkm->max_k; _k++) {
> >>  		for (_n = nkm->min_n; _n <= nkm->max_n; _n++) {
> >>  			for (_m = nkm->min_m; _m <= nkm->max_m; _m++) {
> >> +				if (!ccu_nkm_is_valid_rate(common, parent, _n, _m))
> >> +					continue;
> >> +
> >>  				unsigned long tmp_rate;
> >>
> >>  				tmp_rate = parent * _n * _k / _m;
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
> >> index 6601defb3f38..c409212ee40e 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> >> @@ -27,6 +27,8 @@ struct ccu_nkm {
> >>  	struct ccu_mux_internal	mux;
> >>
> >>  	unsigned int		fixed_post_div;
> >> +	unsigned long		max_m_n_ratio;
> >> +	unsigned long		min_parent_m_ratio;
> >>
> >>  	struct ccu_common	common;
> >>  };
> >>
> >>
> 






From afd at ti.com  Tue Feb  6 09:48:05 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 6 Feb 2024 11:48:05 -0600
Subject: [PATCH 4/4] arm64: dts: ti: k3-am62-wakeup: Add chip efuse nodes
In-Reply-To: <20240206143711.2410135-5-msp@baylibre.com>
References: <20240206143711.2410135-1-msp@baylibre.com>
 <20240206143711.2410135-5-msp@baylibre.com>
Message-ID: <0b758df7-8583-48d1-b289-a297890344f4@ti.com>

On 2/6/24 8:37 AM, Markus Schneider-Pargmann wrote:
> Add efuse nodes describing chip variant and speed grade.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> ---
>   arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi | 36 +++++++++++++++++++++-
>   1 file changed, 35 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
> index fef76f52a52e..14419df43624 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
> @@ -14,10 +14,44 @@ wkup_conf: syscon at 43000000 {
>   		#size-cells = <1>;
>   		ranges = <0x0 0x00 0x43000000 0x20000>;
>   
> +		wkup_efuse: efuse at 0 {
> +			compatible = "socionext,uniphier-efuse";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			reg = <0x0 0x200>;
> +
> +			nvmem-layout {
> +				compatible = "fixed-layout";
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +
> +				chip_manufacturer: jtagidmfg at 14 {
> +					reg = <0x14 0x2>;
> +					bits = <1 11>;
> +				};
> +
> +				chip_partno: jtagidpartno at 15 {
> +					reg = <0x15 0x3>;
> +					bits = <4 16>;
> +				};
> +
> +				chip_variant: jtagidvariant at 17 {
> +					reg = <0x17 0x1>;
> +					bits = <4 4>;
> +				};
> +
> +				chip_speed: jtaguseridspeed at 18 {
> +					reg = <0x18 0x4>;
> +					bits = <6 5>;
> +				};
> +			};
> +		};
> +
>   		chipid: chipid at 14 {

If you remove the reg property you will want to drop the @14
also or you will get a DT check warning. That needs fixed
in the binding example too (and the binding nodename pattern).

Andrew

>   			bootph-all;
>   			compatible = "ti,am654-chipid";
> -			reg = <0x14 0x4>;
> +			nvmem-cells = <&chip_variant>, <&chip_partno>, <&chip_manufacturer>;
> +			nvmem-cell-names = "chipvariant", "chippartno", "chipmanufacturer";
>   		};
>   	};
>   


From jernej.skrabec at gmail.com  Tue Feb  6 09:48:34 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 06 Feb 2024 18:48:34 +0100
Subject: [PATCH v2 2/6] clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m
 ratio and parent rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-2-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-2-96a46a2d8c9b@oltmanns.dev>
Message-ID: <2922005.e9J7NaK4W3@jernej-laptop>

Dne ponedeljek, 05. februar 2024 ob 16:22:25 CET je Frank Oltmanns napisal(a):
> The Allwinner A64 manual lists the following constraints for the
> PLL-MIPI clock:
>  - M/N <= 3
>  - (PLL_VIDEO0)/M >= 24MHz
> 
> Use these constraints.
> 
> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From irogers at google.com  Tue Feb  6 09:49:53 2024
From: irogers at google.com (Ian Rogers)
Date: Tue, 6 Feb 2024 09:49:53 -0800
Subject: [RESEND v4] perf stat: Support per-cluster aggregation
In-Reply-To: <20240206082016.22292-1-yangyicong@huawei.com>
References: <20240206082016.22292-1-yangyicong@huawei.com>
Message-ID: <CAP-5=fUaJSF1R_yDTeNwiNbm0isGTEpZSbp2m0q7BJox+TdRwg@mail.gmail.com>

On Tue, Feb 6, 2024 at 12:24?AM Yicong Yang <yangyicong at huawei.com> wrote:
>
> From: Yicong Yang <yangyicong at hisilicon.com>
>
> Some platforms have 'cluster' topology and CPUs in the cluster will
> share resources like L3 Cache Tag (for HiSilicon Kunpeng SoC) or L2
> cache (for Intel Jacobsville). Currently parsing and building cluster
> topology have been supported since [1].
>
> perf stat has already supported aggregation for other topologies like
> die or socket, etc. It'll be useful to aggregate per-cluster to find
> problems like L3T bandwidth contention.
>
> This patch add support for "--per-cluster" option for per-cluster
> aggregation. Also update the docs and related test. The output will
> be like:
>
> [root at localhost tmp]# perf stat -a -e LLC-load --per-cluster -- sleep 5
>
>  Performance counter stats for 'system wide':
>
> S56-D0-CLS158    4      1,321,521,570      LLC-load
> S56-D0-CLS594    4        794,211,453      LLC-load
> S56-D0-CLS1030    4             41,623      LLC-load
> S56-D0-CLS1466    4             41,646      LLC-load
> S56-D0-CLS1902    4             16,863      LLC-load
> S56-D0-CLS2338    4             15,721      LLC-load
> S56-D0-CLS2774    4             22,671      LLC-load
> [...]
>
> On a legacy system without cluster or cluster support, the output will
> be look like:
> [root at localhost perf]# perf stat -a -e cycles --per-cluster -- sleep 1
>
>  Performance counter stats for 'system wide':
>
> S56-D0-CLS0   64         18,011,485      cycles
> S7182-D0-CLS0   64         16,548,835      cycles
>
> Note that this patch doesn't mix the cluster information in the outputs
> of --per-core to avoid breaking any tools/scripts using it.
>
> Note that perf recently supports "--per-cache" aggregation, but it's not
> the same with the cluster although cluster CPUs may share some cache
> resources. For example on my machine all clusters within a die share the
> same L3 cache:
> $ cat /sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list
> 0-31
> $ cat /sys/devices/system/cpu/cpu0/topology/cluster_cpus_list
> 0-3
>
> [1] commit c5e22feffdd7 ("topology: Represent clusters of CPUs within a die")
> Tested-by: Jie Zhan <zhanjie9 at hisilicon.com>
> Reviewed-by: Tim Chen <tim.c.chen at linux.intel.com>
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>

Reviewed-by: Ian Rogers <irogers at google.com>

> ---
> Change since v3:
> - Rebase on v6.7-rc4 and resolve the conflicts
> Link: https://lore.kernel.org/all/20230404104951.27537-1-yangyicong at huawei.com/
>
> Change since v2:
> - Use 0 as cluster ID on legacy system without cluster support, keep consistenct
>   with what --per-die does.
> Link: https://lore.kernel.org/all/20230328112717.19573-1-yangyicong at huawei.com/
>
> Change since v1:
> - Provides the information about how to map the cluster to the CPUs in the manual
> - Thanks the review from Tim and test from Jie.
> Link: https://lore.kernel.org/all/20230313085911.61359-1-yangyicong at huawei.com/
>
>  tools/perf/Documentation/perf-stat.txt        | 11 ++++
>  tools/perf/builtin-stat.c                     | 52 +++++++++++++++++--
>  .../tests/shell/lib/perf_json_output_lint.py  |  4 +-
>  tools/perf/tests/shell/lib/stat_output.sh     | 12 +++++
>  tools/perf/tests/shell/stat+csv_output.sh     |  2 +
>  tools/perf/tests/shell/stat+json_output.sh    | 13 +++++
>  tools/perf/tests/shell/stat+std_output.sh     |  2 +
>  tools/perf/util/cpumap.c                      | 32 +++++++++++-
>  tools/perf/util/cpumap.h                      | 19 +++++--
>  tools/perf/util/env.h                         |  1 +
>  tools/perf/util/stat-display.c                | 13 +++++
>  tools/perf/util/stat.h                        |  1 +
>  12 files changed, 153 insertions(+), 9 deletions(-)
>
> diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
> index 5af2e432b54f..29756a87ab6f 100644
> --- a/tools/perf/Documentation/perf-stat.txt
> +++ b/tools/perf/Documentation/perf-stat.txt
> @@ -308,6 +308,14 @@ use --per-die in addition to -a. (system-wide).  The output includes the
>  die number and the number of online processors on that die. This is
>  useful to gauge the amount of aggregation.
>
> +--per-cluster::
> +Aggregate counts per processor cluster for system-wide mode measurement.  This
> +is a useful mode to detect imbalance between clusters.  To enable this mode,
> +use --per-cluster in addition to -a. (system-wide).  The output includes the
> +cluster number and the number of online processors on that cluster. This is
> +useful to gauge the amount of aggregation. The information of cluster ID and
> +related CPUs can be gotten from /sys/devices/system/cpu/cpuX/topology/cluster_{id, cpus}.
> +
>  --per-cache::
>  Aggregate counts per cache instance for system-wide mode measurements.  By
>  default, the aggregation happens for the cache level at the highest index
> @@ -396,6 +404,9 @@ Aggregate counts per processor socket for system-wide mode measurements.
>  --per-die::
>  Aggregate counts per processor die for system-wide mode measurements.
>
> +--per-cluster::
> +Aggregate counts perf processor cluster for system-wide mode measurements.
> +
>  --per-cache::
>  Aggregate counts per cache instance for system-wide mode measurements.  By
>  default, the aggregation happens for the cache level at the highest index
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index 5fe9abc6a524..6bba1a89d030 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -1238,6 +1238,8 @@ static struct option stat_options[] = {
>                      "aggregate counts per processor socket", AGGR_SOCKET),
>         OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
>                      "aggregate counts per processor die", AGGR_DIE),
> +       OPT_SET_UINT(0, "per-cluster", &stat_config.aggr_mode,
> +                    "aggregate counts per processor cluster", AGGR_CLUSTER),
>         OPT_CALLBACK_OPTARG(0, "per-cache", &stat_config.aggr_mode, &stat_config.aggr_level,
>                             "cache level", "aggregate count at this cache level (Default: LLC)",
>                             parse_cache_level),
> @@ -1428,6 +1430,7 @@ static struct aggr_cpu_id aggr_cpu_id__cache(struct perf_cpu cpu, void *data)
>  static const char *const aggr_mode__string[] = {
>         [AGGR_CORE] = "core",
>         [AGGR_CACHE] = "cache",
> +       [AGGR_CLUSTER] = "cluster",
>         [AGGR_DIE] = "die",
>         [AGGR_GLOBAL] = "global",
>         [AGGR_NODE] = "node",
> @@ -1455,6 +1458,12 @@ static struct aggr_cpu_id perf_stat__get_cache_id(struct perf_stat_config *confi
>         return aggr_cpu_id__cache(cpu, /*data=*/NULL);
>  }
>
> +static struct aggr_cpu_id perf_stat__get_cluster(struct perf_stat_config *config __maybe_unused,
> +                                                struct perf_cpu cpu)
> +{
> +       return aggr_cpu_id__cluster(cpu, /*data=*/NULL);
> +}
> +
>  static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
>                                               struct perf_cpu cpu)
>  {
> @@ -1507,6 +1516,12 @@ static struct aggr_cpu_id perf_stat__get_die_cached(struct perf_stat_config *con
>         return perf_stat__get_aggr(config, perf_stat__get_die, cpu);
>  }
>
> +static struct aggr_cpu_id perf_stat__get_cluster_cached(struct perf_stat_config *config,
> +                                                       struct perf_cpu cpu)
> +{
> +       return perf_stat__get_aggr(config, perf_stat__get_cluster, cpu);
> +}
> +
>  static struct aggr_cpu_id perf_stat__get_cache_id_cached(struct perf_stat_config *config,
>                                                          struct perf_cpu cpu)
>  {
> @@ -1544,6 +1559,8 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode)
>                 return aggr_cpu_id__socket;
>         case AGGR_DIE:
>                 return aggr_cpu_id__die;
> +       case AGGR_CLUSTER:
> +               return aggr_cpu_id__cluster;
>         case AGGR_CACHE:
>                 return aggr_cpu_id__cache;
>         case AGGR_CORE:
> @@ -1569,6 +1586,8 @@ static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode)
>                 return perf_stat__get_socket_cached;
>         case AGGR_DIE:
>                 return perf_stat__get_die_cached;
> +       case AGGR_CLUSTER:
> +               return perf_stat__get_cluster_cached;
>         case AGGR_CACHE:
>                 return perf_stat__get_cache_id_cached;
>         case AGGR_CORE:
> @@ -1737,6 +1756,21 @@ static struct aggr_cpu_id perf_env__get_cache_aggr_by_cpu(struct perf_cpu cpu,
>         return id;
>  }
>
> +static struct aggr_cpu_id perf_env__get_cluster_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.cpu != -1) {
> +               id.socket = env->cpu[cpu.cpu].socket_id;
> +               id.die = env->cpu[cpu.cpu].die_id;
> +               id.cluster = env->cpu[cpu.cpu].cluster_id;
> +       }
> +
> +       return id;
> +}
> +
>  static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, void *data)
>  {
>         struct perf_env *env = data;
> @@ -1744,12 +1778,12 @@ static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, vo
>
>         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
> +                * core_id is relative to socket, die and cluster, we need a
> +                * global id. So we set socket, die id, cluster id and core id.
>                  */
>                 id.socket = env->cpu[cpu.cpu].socket_id;
>                 id.die = env->cpu[cpu.cpu].die_id;
> +               id.cluster = env->cpu[cpu.cpu].cluster_id;
>                 id.core = env->cpu[cpu.cpu].core_id;
>         }
>
> @@ -1805,6 +1839,12 @@ static struct aggr_cpu_id perf_stat__get_die_file(struct perf_stat_config *confi
>         return perf_env__get_die_aggr_by_cpu(cpu, &perf_stat.session->header.env);
>  }
>
> +static struct aggr_cpu_id perf_stat__get_cluster_file(struct perf_stat_config *config __maybe_unused,
> +                                                     struct perf_cpu cpu)
> +{
> +       return perf_env__get_cluster_aggr_by_cpu(cpu, &perf_stat.session->header.env);
> +}
> +
>  static struct aggr_cpu_id perf_stat__get_cache_file(struct perf_stat_config *config __maybe_unused,
>                                                     struct perf_cpu cpu)
>  {
> @@ -1842,6 +1882,8 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode)
>                 return perf_env__get_socket_aggr_by_cpu;
>         case AGGR_DIE:
>                 return perf_env__get_die_aggr_by_cpu;
> +       case AGGR_CLUSTER:
> +               return perf_env__get_cluster_aggr_by_cpu;
>         case AGGR_CACHE:
>                 return perf_env__get_cache_aggr_by_cpu;
>         case AGGR_CORE:
> @@ -1867,6 +1909,8 @@ static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode)
>                 return perf_stat__get_socket_file;
>         case AGGR_DIE:
>                 return perf_stat__get_die_file;
> +       case AGGR_CLUSTER:
> +               return perf_stat__get_cluster_file;
>         case AGGR_CACHE:
>                 return perf_stat__get_cache_file;
>         case AGGR_CORE:
> @@ -2398,6 +2442,8 @@ static int __cmd_report(int argc, const char **argv)
>                      "aggregate counts per processor socket", AGGR_SOCKET),
>         OPT_SET_UINT(0, "per-die", &perf_stat.aggr_mode,
>                      "aggregate counts per processor die", AGGR_DIE),
> +       OPT_SET_UINT(0, "per-cluster", &perf_stat.aggr_mode,
> +                    "aggregate counts perf processor cluster", AGGR_CLUSTER),
>         OPT_CALLBACK_OPTARG(0, "per-cache", &perf_stat.aggr_mode, &perf_stat.aggr_level,
>                             "cache level",
>                             "aggregate count at this cache level (Default: LLC)",
> diff --git a/tools/perf/tests/shell/lib/perf_json_output_lint.py b/tools/perf/tests/shell/lib/perf_json_output_lint.py
> index ea55d5ea1ced..abc1fd737782 100644
> --- a/tools/perf/tests/shell/lib/perf_json_output_lint.py
> +++ b/tools/perf/tests/shell/lib/perf_json_output_lint.py
> @@ -15,6 +15,7 @@ ap.add_argument('--event', action='store_true')
>  ap.add_argument('--per-core', action='store_true')
>  ap.add_argument('--per-thread', action='store_true')
>  ap.add_argument('--per-cache', action='store_true')
> +ap.add_argument('--per-cluster', action='store_true')
>  ap.add_argument('--per-die', action='store_true')
>  ap.add_argument('--per-node', action='store_true')
>  ap.add_argument('--per-socket', action='store_true')
> @@ -49,6 +50,7 @@ def check_json_output(expected_items):
>        'cgroup': lambda x: True,
>        'cpu': lambda x: isint(x),
>        'cache': lambda x: True,
> +      'cluster': lambda x: True,
>        'die': lambda x: True,
>        'event': lambda x: True,
>        'event-runtime': lambda x: isfloat(x),
> @@ -88,7 +90,7 @@ try:
>      expected_items = 7
>    elif args.interval or args.per_thread or args.system_wide_no_aggr:
>      expected_items = 8
> -  elif args.per_core or args.per_socket or args.per_node or args.per_die or args.per_cache:
> +  elif args.per_core or args.per_socket or args.per_node or args.per_die or args.per_cluster or args.per_cache:
>      expected_items = 9
>    else:
>      # If no option is specified, don't check the number of items.
> diff --git a/tools/perf/tests/shell/lib/stat_output.sh b/tools/perf/tests/shell/lib/stat_output.sh
> index 3cc158a64326..c81d6a9f7983 100644
> --- a/tools/perf/tests/shell/lib/stat_output.sh
> +++ b/tools/perf/tests/shell/lib/stat_output.sh
> @@ -97,6 +97,18 @@ check_per_cache_instance()
>         echo "[Success]"
>  }
>
> +check_per_cluster()
> +{
> +       echo -n "Checking $1 output: per cluster "
> +       if ParanoidAndNotRoot 0
> +       then
> +               echo "[Skip] paranoid and not root"
> +               return
> +       fi
> +       perf stat --per-cluster -a $2 true
> +       echo "[Success]"
> +}
> +
>  check_per_die()
>  {
>         echo -n "Checking $1 output: per die "
> diff --git a/tools/perf/tests/shell/stat+csv_output.sh b/tools/perf/tests/shell/stat+csv_output.sh
> index f1818fa6d9ce..fc2d8cc6e5e0 100755
> --- a/tools/perf/tests/shell/stat+csv_output.sh
> +++ b/tools/perf/tests/shell/stat+csv_output.sh
> @@ -42,6 +42,7 @@ function commachecker()
>         ;; "--per-socket")      exp=8
>         ;; "--per-node")        exp=8
>         ;; "--per-die")         exp=8
> +       ;; "--per-cluster")     exp=8
>         ;; "--per-cache")       exp=8
>         esac
>
> @@ -79,6 +80,7 @@ then
>         check_system_wide_no_aggr "CSV" "$perf_cmd"
>         check_per_core "CSV" "$perf_cmd"
>         check_per_cache_instance "CSV" "$perf_cmd"
> +       check_per_cluster "CSV" "$perf_cmd"
>         check_per_die "CSV" "$perf_cmd"
>         check_per_socket "CSV" "$perf_cmd"
>  else
> diff --git a/tools/perf/tests/shell/stat+json_output.sh b/tools/perf/tests/shell/stat+json_output.sh
> index 3bc900533a5d..2b9c6212dffc 100755
> --- a/tools/perf/tests/shell/stat+json_output.sh
> +++ b/tools/perf/tests/shell/stat+json_output.sh
> @@ -122,6 +122,18 @@ check_per_cache_instance()
>         echo "[Success]"
>  }
>
> +check_per_cluster()
> +{
> +       echo -n "Checking json output: per cluster "
> +       if ParanoidAndNotRoot 0
> +       then
> +               echo "[Skip] paranoia and not root"
> +               return
> +       fi
> +       perf stat -j --per-cluster -a true 2>&1 | $PYTHON $pythonchecker --per-cluster
> +       echo "[Success]"
> +}
> +
>  check_per_die()
>  {
>         echo -n "Checking json output: per die "
> @@ -200,6 +212,7 @@ then
>         check_system_wide_no_aggr
>         check_per_core
>         check_per_cache_instance
> +       check_per_cluster
>         check_per_die
>         check_per_socket
>  else
> diff --git a/tools/perf/tests/shell/stat+std_output.sh b/tools/perf/tests/shell/stat+std_output.sh
> index 4fcdd1a9142c..16f61e86afc5 100755
> --- a/tools/perf/tests/shell/stat+std_output.sh
> +++ b/tools/perf/tests/shell/stat+std_output.sh
> @@ -40,6 +40,7 @@ function commachecker()
>         ;; "--per-node")        prefix=3
>         ;; "--per-die")         prefix=3
>         ;; "--per-cache")       prefix=3
> +       ;; "--per-cluster")     prefix=3
>         esac
>
>         while read line
> @@ -99,6 +100,7 @@ then
>         check_system_wide_no_aggr "STD" "$perf_cmd"
>         check_per_core "STD" "$perf_cmd"
>         check_per_cache_instance "STD" "$perf_cmd"
> +       check_per_cluster "STD" "$perf_cmd"
>         check_per_die "STD" "$perf_cmd"
>         check_per_socket "STD" "$perf_cmd"
>  else
> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> index 0581ee0fa5f2..5907456d42a2 100644
> --- a/tools/perf/util/cpumap.c
> +++ b/tools/perf/util/cpumap.c
> @@ -222,6 +222,8 @@ static int aggr_cpu_id__cmp(const void *a_pointer, const void *b_pointer)
>                 return a->socket - b->socket;
>         else if (a->die != b->die)
>                 return a->die - b->die;
> +       else if (a->cluster != b->cluster)
> +               return a->cluster - b->cluster;
>         else if (a->cache_lvl != b->cache_lvl)
>                 return a->cache_lvl - b->cache_lvl;
>         else if (a->cache != b->cache)
> @@ -309,6 +311,29 @@ struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data)
>         return id;
>  }
>
> +int cpu__get_cluster_id(struct perf_cpu cpu)
> +{
> +       int value, ret = cpu__get_topology_int(cpu.cpu, "cluster_id", &value);

nit: normal coding style is for a whitespace newline here.

Thanks,
Ian

> +       return ret ?: value;
> +}
> +
> +struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data)
> +{
> +       int cluster = cpu__get_cluster_id(cpu);
> +       struct aggr_cpu_id id;
> +
> +       /* There is no cluster_id on legacy system. */
> +       if (cluster == -1)
> +               cluster = 0;
> +
> +       id = aggr_cpu_id__die(cpu, data);
> +       if (aggr_cpu_id__is_empty(&id))
> +               return id;
> +
> +       id.cluster = cluster;
> +       return id;
> +}
> +
>  int cpu__get_core_id(struct perf_cpu cpu)
>  {
>         int value, ret = cpu__get_topology_int(cpu.cpu, "core_id", &value);
> @@ -320,8 +345,8 @@ 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);
>
> -       /* aggr_cpu_id__die returns a struct with socket and die set. */
> -       id = aggr_cpu_id__die(cpu, data);
> +       /* aggr_cpu_id__die returns a struct with socket die, and cluster set. */
> +       id = aggr_cpu_id__cluster(cpu, data);
>         if (aggr_cpu_id__is_empty(&id))
>                 return id;
>
> @@ -683,6 +708,7 @@ 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->cluster == b->cluster &&
>                 a->cache_lvl == b->cache_lvl &&
>                 a->cache == b->cache &&
>                 a->core == b->core &&
> @@ -695,6 +721,7 @@ bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a)
>                 a->node == -1 &&
>                 a->socket == -1 &&
>                 a->die == -1 &&
> +               a->cluster == -1 &&
>                 a->cache_lvl == -1 &&
>                 a->cache == -1 &&
>                 a->core == -1 &&
> @@ -708,6 +735,7 @@ struct aggr_cpu_id aggr_cpu_id__empty(void)
>                 .node = -1,
>                 .socket = -1,
>                 .die = -1,
> +               .cluster = -1,
>                 .cache_lvl = -1,
>                 .cache = -1,
>                 .core = -1,
> diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> index 9df2aeb34d3d..26cf76c693f5 100644
> --- a/tools/perf/util/cpumap.h
> +++ b/tools/perf/util/cpumap.h
> @@ -20,6 +20,8 @@ struct aggr_cpu_id {
>         int socket;
>         /** The die id as read from /sys/devices/system/cpu/cpuX/topology/die_id. */
>         int die;
> +       /** The cluster id as read from /sys/devices/system/cpu/cpuX/topology/cluster_id */
> +       int cluster;
>         /** The cache level as read from /sys/devices/system/cpu/cpuX/cache/indexY/level */
>         int cache_lvl;
>         /**
> @@ -86,6 +88,11 @@ int cpu__get_socket_id(struct perf_cpu cpu);
>   * /sys/devices/system/cpu/cpuX/topology/die_id for the given CPU.
>   */
>  int cpu__get_die_id(struct perf_cpu cpu);
> +/**
> + * cpu__get_cluster_id - Returns the cluster id as read from
> + * /sys/devices/system/cpu/cpuX/topology/cluster_id for the given CPU
> + */
> +int cpu__get_cluster_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.
> @@ -127,9 +134,15 @@ struct aggr_cpu_id aggr_cpu_id__socket(struct perf_cpu 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.
> + * aggr_cpu_id__cluster - Create an aggr_cpu_id with cluster, die and socket
> + * populated with the cluster, die and socket for cpu. The function signature
> + * is compatible with aggr_cpu_id_get_t.
> + */
> +struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data);
> +/**
> + * aggr_cpu_id__core - Create an aggr_cpu_id with the core, cluster, 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(struct perf_cpu cpu, void *data);
>  /**
> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
> index 7c527e65c186..2a2c37cc40b7 100644
> --- a/tools/perf/util/env.h
> +++ b/tools/perf/util/env.h
> @@ -12,6 +12,7 @@ struct perf_cpu_map;
>  struct cpu_topology_map {
>         int     socket_id;
>         int     die_id;
> +       int     cluster_id;
>         int     core_id;
>  };
>
> diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
> index 8c61f8627ebc..4dfe7d9517a9 100644
> --- a/tools/perf/util/stat-display.c
> +++ b/tools/perf/util/stat-display.c
> @@ -201,6 +201,9 @@ static void print_aggr_id_std(struct perf_stat_config *config,
>                 snprintf(buf, sizeof(buf), "S%d-D%d-L%d-ID%d",
>                          id.socket, id.die, id.cache_lvl, id.cache);
>                 break;
> +       case AGGR_CLUSTER:
> +               snprintf(buf, sizeof(buf), "S%d-D%d-CLS%d", id.socket, id.die, id.cluster);
> +               break;
>         case AGGR_DIE:
>                 snprintf(buf, sizeof(buf), "S%d-D%d", id.socket, id.die);
>                 break;
> @@ -251,6 +254,10 @@ static void print_aggr_id_csv(struct perf_stat_config *config,
>                 fprintf(config->output, "S%d-D%d-L%d-ID%d%s%d%s",
>                         id.socket, id.die, id.cache_lvl, id.cache, sep, aggr_nr, sep);
>                 break;
> +       case AGGR_CLUSTER:
> +               fprintf(config->output, "S%d-D%d-CLS%d%s%d%s",
> +                       id.socket, id.die, id.cluster, sep, aggr_nr, sep);
> +               break;
>         case AGGR_DIE:
>                 fprintf(output, "S%d-D%d%s%d%s",
>                         id.socket, id.die, sep, aggr_nr, sep);
> @@ -300,6 +307,10 @@ static void print_aggr_id_json(struct perf_stat_config *config,
>                 fprintf(output, "\"cache\" : \"S%d-D%d-L%d-ID%d\", \"aggregate-number\" : %d, ",
>                         id.socket, id.die, id.cache_lvl, id.cache, aggr_nr);
>                 break;
> +       case AGGR_CLUSTER:
> +               fprintf(output, "\"cluster\" : \"S%d-D%d-CLS%d\", \"aggregate-number\" : %d, ",
> +                       id.socket, id.die, id.cluster, aggr_nr);
> +               break;
>         case AGGR_DIE:
>                 fprintf(output, "\"die\" : \"S%d-D%d\", \"aggregate-number\" : %d, ",
>                         id.socket, id.die, aggr_nr);
> @@ -1248,6 +1259,7 @@ static void print_header_interval_std(struct perf_stat_config *config,
>         case AGGR_NODE:
>         case AGGR_SOCKET:
>         case AGGR_DIE:
> +       case AGGR_CLUSTER:
>         case AGGR_CACHE:
>         case AGGR_CORE:
>                 fprintf(output, "#%*s %-*s cpus",
> @@ -1550,6 +1562,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
>         switch (config->aggr_mode) {
>         case AGGR_CORE:
>         case AGGR_CACHE:
> +       case AGGR_CLUSTER:
>         case AGGR_DIE:
>         case AGGR_SOCKET:
>         case AGGR_NODE:
> diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
> index 4357ba114822..d6e5c8787ba2 100644
> --- a/tools/perf/util/stat.h
> +++ b/tools/perf/util/stat.h
> @@ -48,6 +48,7 @@ enum aggr_mode {
>         AGGR_GLOBAL,
>         AGGR_SOCKET,
>         AGGR_DIE,
> +       AGGR_CLUSTER,
>         AGGR_CACHE,
>         AGGR_CORE,
>         AGGR_THREAD,
> --
> 2.24.0
>


From jernej.skrabec at gmail.com  Tue Feb  6 09:51:02 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 06 Feb 2024 18:51:02 +0100
Subject: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum rate
In-Reply-To: <87eddqzm4j.fsf@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <4543794.LvFx2qVVIh@jernej-laptop> <87eddqzm4j.fsf@oltmanns.dev>
Message-ID: <3280499.44csPzL39Z@jernej-laptop>

Dne ponedeljek, 05. februar 2024 ob 21:34:04 CET je Frank Oltmanns napisal(a):
> 
> On 2024-02-05 at 18:56:09 +0100, Jernej ?krabec <jernej.skrabec at gmail.com> wrote:
> > Dne ponedeljek, 05. februar 2024 ob 16:22:26 CET je Frank Oltmanns napisal(a):
> >> According to the Allwinner User Manual, the Allwinner A64 requires
> >> PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.
> >>
> >> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> >> ---
> >>  drivers/clk/sunxi-ng/ccu_nkm.c | 13 +++++++++++++
> >>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
> >>  2 files changed, 15 insertions(+)
> >>
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> index 1168d894d636..7d135908d6e0 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> @@ -181,6 +181,12 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
> >>  	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
> >>  		rate *= nkm->fixed_post_div;
> >>
> >> +	if (nkm->min_rate && rate < nkm->min_rate)
> >> +		rate = nkm->min_rate;
> >> +
> >> +	if (nkm->max_rate && rate > nkm->max_rate)
> >> +		rate = nkm->max_rate;
> >
> > Please take a look at ccu_nm_round_rate() code. You need to consider postdiv
> > and you can return immediately.
> 
> There is a difference here insofar that ccu_nm is always connected to a
> fixed rate parent (at least that's my understanding). Therefore, in
> ccu_nm_round_rate() we can be sure that the min or max rate can really
> be set. In ccu_nkm we don't have that luxury, we actually have to find a
> rate that is approximately equal to the min and max rate, based on the
> parent rate. Therefore, we can't return immediately.

Good point.

> 
> Also, I'm not sure what you mean about me needing to consider postdiv.
> That's what I did. The check is after multiplying with the postdiv. It's
> the same as in ccu_nm_round_rate() (just minus the immediate return).

Nevermind, this applies only for immediate return.

Best regards,
Jernej

> 
> >
> >> +
> >>  	if (!clk_hw_can_set_rate_parent(&nkm->common.hw))
> >>  		rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm->common);
> >>  	else
> >> @@ -220,6 +226,13 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
> >>  	_nkm.min_m = 1;
> >>  	_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
> >>
> >> +
> >> +	if (nkm->min_rate && rate < nkm->min_rate)
> >> +		rate = nkm->min_rate;
> >> +
> >> +	if (nkm->max_rate && rate > nkm->max_rate)
> >> +		rate = nkm->max_rate;
> >> +
> >
> > No need for this, clk subsystem calls round rate before setting actual clock
> > rate.
> 
> I'll remove the checks in V3.
> 
> Best regards,
>   Frank
> 
> >
> > Best regards,
> > Jernej
> >
> >>  	ccu_nkm_find_best(parent_rate, rate, &_nkm, &nkm->common);
> >>
> >>  	spin_lock_irqsave(nkm->common.lock, flags);
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
> >> index c409212ee40e..358a9df6b6a0 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> >> @@ -27,6 +27,8 @@ struct ccu_nkm {
> >>  	struct ccu_mux_internal	mux;
> >>
> >>  	unsigned int		fixed_post_div;
> >> +	unsigned long		min_rate;
> >> +	unsigned long		max_rate;
> >>  	unsigned long		max_m_n_ratio;
> >>  	unsigned long		min_parent_m_ratio;
> >>
> >>
> >>
> 






From semen.protsenko at linaro.org  Tue Feb  6 10:02:48 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 6 Feb 2024 12:02:48 -0600
Subject: [PATCH 1/4] spi: s3c64xx: explicitly include <linux/types.h>
In-Reply-To: <20240206085238.1208256-2-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org> <20240206085238.1208256-2-tudor.ambarus@linaro.org>
Message-ID: <CAPLW+4=Xd+B=ZncqPgU4qaJ8zY8JJvJZApdUW_v0w6yr2cy9Sg@mail.gmail.com>

On Tue, Feb 6, 2024 at 2:52?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> The driver uses u32 and relies on an implicit inclusion of
> <linux/types.h>.
>
> It is good practice to directly include all headers used, it avoids
> implicit dependencies and spurious breakage if someone rearranges
> headers and causes the implicit include to vanish.
>
> Include the missing header.
>
> Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver")

Not sure if Fixes tag is needed here.

> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  drivers/spi/spi-s3c64xx.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index 72c35dbe53b2..c15ca6a910dc 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -17,6 +17,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/spi/spi.h>
> +#include <linux/types.h>

Is this really needed for the further patches in this series?

>
>  #define MAX_SPI_PORTS          12
>  #define S3C64XX_SPI_QUIRK_CS_AUTO      (1 << 1)
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From wahrenst at gmx.net  Tue Feb  6 10:08:40 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Tue, 6 Feb 2024 19:08:40 +0100
Subject: [PATCH 02/12] bcm2835-dma: Add proper 40-bit DMA support
In-Reply-To: <CAPY8ntCEvsTJwoEBYc7JsTaYfdMURhmytvvVMcLVNBkmdTNcZQ@mail.gmail.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
 <eeb94204c30c2182f5ffd3ec083c04399ecdee32.1706948717.git.andrea.porta@suse.com>
 <8736c115-e11c-41ca-85eb-7cd19a205068@gmx.net>
 <CAPY8ntCEvsTJwoEBYc7JsTaYfdMURhmytvvVMcLVNBkmdTNcZQ@mail.gmail.com>
Message-ID: <42e760f9-8304-4237-bb68-54c98eb7fcb9@gmx.net>

Hi Dave and Andrea,

Am 06.02.24 um 17:31 schrieb Dave Stevenson:
> Hi Stefan and Andrea
>
> On Mon, 5 Feb 2024 at 18:50, Stefan Wahren <wahrenst at gmx.net> wrote:
>> Hi Andrea,
>>
>> [add Dave]
>>
>> Am 04.02.24 um 07:59 schrieb Andrea della Porta:
>>> From: Phil Elwell <phil at raspberrypi.org>
>>>
>>> BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
>>> to access the full 4GB of memory on a Pi 4.
>>>
>>> Cc: Phil Elwell <phil at raspberrypi.org>
>>> Cc: Maxime Ripard <maxime at cerno.tech>
>>> Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
>> mainlining isn't that simple by sending just the downstream patches to
>> the mailing list. In many cases there reasons why this hasn't been
>> upstreamed yet.
>>
>> In my opinion just this feature is worth a separate patch series. In
>> 2021 i already send an initial version, which tried to implement it in a
>> cleaner & maintainabler way [1]. In the meantime Dave Stevenson from
>> Raspberry Pi wrote that he also wanted to work on this. Maybe you want
>> to work on this together?
> Yes, I'm looking at reworking Stefan's series to work on Pi4 & Pi5 as
> it's needed for HDMI audio (and other things) on those platforms which
> I'm working to upstream.
>
> I was getting weirdness from the sdhci block when I was last looking
> at it, so it was just proving a little trickier than first thought.
> Hopefully I'll get some time on it in the next couple of weeks.
i must confess that my series was just a draft to see that the general
approach would be accepted. Yes, it's possible that there are issues :-(

Maybe i can help you a little bit by taking care of first two patches
(node name fix & YAML conversion)?

Regards
>    Dave
>
>> [1] -
>> https://lore.kernel.org/linux-arm-kernel/13ec386b-2305-27da-9765-8fa3ad71146c at i2se.com/T/



From cl at gentwo.org  Tue Feb  6 10:09:59 2024
From: cl at gentwo.org (Christoph Lameter (Ampere))
Date: Tue, 6 Feb 2024 10:09:59 -0800 (PST)
Subject: [PATCH REPOST v2] ARM64: Dynamically allocate cpumasks and increase
 supported CPUs to 512
Message-ID: <e0d41efb-a74e-6bb5-f325-63d42358c802@gentwo.org>

Can we get this merged for 6.9? The patch has been around for awhile now.



Ampere Computing develops high end ARM processor that support an ever
increasing number of processors. The default 256 processors are
not enough for our newer products. The default is used by
distros and therefore our customers cannot use distro kernels because
the number of processors is not supported.

One of the objections against earlier patches to increase the limit
was that the memory use becomes too high. There is a feature called
CPUMASK_OFFSTACK that configures the cpumasks in the kernel to be
dynamically allocated. This was used in the X86 architecture in the
past to enable support for larger CPU configurations up to 8k cpus.

With that is becomes possible to dynamically size the allocation of
the cpu bitmaps depending on the quantity of processors detected on
bootup.

This patch enables that logic if more than 256 processors
are configured and increases the default to 512 processors.

Further increases may be needed if ARM processor vendors start
supporting more processors. Given the current inflationary trends
in core counts from multiple processor manufacturers this may occur.

Tested-by: Eric Mackay <eric.mackay at oracle.com>
Signed-off-by: Christoph Lameter (Ampere) <cl at linux.com>

---

Original post: https://www.spinics.net/lists/linux-mm/msg369701.html

V1->V2

- Keep quotation marks
- Remove whiltespace damage
- Add tested by


Index: linux/arch/arm64/Kconfig
===================================================================
--- linux.orig/arch/arm64/Kconfig
+++ linux/arch/arm64/Kconfig
@@ -1407,7 +1407,21 @@ config SCHED_SMT
   config NR_CPUS
   	int "Maximum number of CPUs (2-4096)"
   	range 2 4096
-	default "256"
+	default "512"
+
+#
+# Determines the placement of cpumasks.
+#
+# With CPUMASK_OFFSTACK the cpumasks are dynamically allocated.
+# Useful for machines with lots of core because it avoids increasing
+# the size of many of the data structures in the kernel.
+#
+# If this is off then the cpumasks have a static sizes and are
+# embedded within data structures.
+#
+config CPUMASK_OFFSTACK
+	def_bool y
+	depends on NR_CPUS > 256

   config HOTPLUG_CPU
   	bool "Support for hot-pluggable CPUs"

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From wahrenst at gmx.net  Tue Feb  6 10:11:37 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Tue, 6 Feb 2024 19:11:37 +0100
Subject: [PATCH 02/12] bcm2835-dma: Add proper 40-bit DMA support
In-Reply-To: <42e760f9-8304-4237-bb68-54c98eb7fcb9@gmx.net>
References: <cover.1706948717.git.andrea.porta@suse.com>
 <eeb94204c30c2182f5ffd3ec083c04399ecdee32.1706948717.git.andrea.porta@suse.com>
 <8736c115-e11c-41ca-85eb-7cd19a205068@gmx.net>
 <CAPY8ntCEvsTJwoEBYc7JsTaYfdMURhmytvvVMcLVNBkmdTNcZQ@mail.gmail.com>
 <42e760f9-8304-4237-bb68-54c98eb7fcb9@gmx.net>
Message-ID: <956e0b7c-b1b2-4eaa-bb6d-da6f9dc2335d@gmx.net>

Am 06.02.24 um 19:08 schrieb Stefan Wahren:
> Hi Dave and Andrea,
>
> Am 06.02.24 um 17:31 schrieb Dave Stevenson:
>> Hi Stefan and Andrea
>>
>> On Mon, 5 Feb 2024 at 18:50, Stefan Wahren <wahrenst at gmx.net> wrote:
>>> Hi Andrea,
>>>
>>> [add Dave]
>>>
>>> Am 04.02.24 um 07:59 schrieb Andrea della Porta:
>>>> From: Phil Elwell <phil at raspberrypi.org>
>>>>
>>>> BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
>>>> to access the full 4GB of memory on a Pi 4.
>>>>
>>>> Cc: Phil Elwell <phil at raspberrypi.org>
>>>> Cc: Maxime Ripard <maxime at cerno.tech>
>>>> Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
>>> mainlining isn't that simple by sending just the downstream patches to
>>> the mailing list. In many cases there reasons why this hasn't been
>>> upstreamed yet.
>>>
>>> In my opinion just this feature is worth a separate patch series. In
>>> 2021 i already send an initial version, which tried to implement it
>>> in a
>>> cleaner & maintainabler way [1]. In the meantime Dave Stevenson from
>>> Raspberry Pi wrote that he also wanted to work on this. Maybe you want
>>> to work on this together?
>> Yes, I'm looking at reworking Stefan's series to work on Pi4 & Pi5 as
>> it's needed for HDMI audio (and other things) on those platforms which
>> I'm working to upstream.
>>
>> I was getting weirdness from the sdhci block when I was last looking
>> at it, so it was just proving a little trickier than first thought.
>> Hopefully I'll get some time on it in the next couple of weeks.
> i must confess that my series was just a draft to see that the general
> approach would be accepted. Yes, it's possible that there are issues :-(
>
> Maybe i can help you a little bit by taking care of first two patches
> (node name fix & YAML conversion)?
Forget about this, it's already done
>
> Regards
>> ?? Dave
>>
>>> [1] -
>>> https://lore.kernel.org/linux-arm-kernel/13ec386b-2305-27da-9765-8fa3ad71146c at i2se.com/T/
>>>
>



From andre.przywara at arm.com  Tue Feb  6 10:13:46 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 6 Feb 2024 18:13:46 +0000
Subject: [PATCH 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC support
In-Reply-To: <4867577.GXAFRqVoOG@jernej-laptop>
References: <20240204094404.149776-1-andre.przywara@arm.com>
 <3788758.kQq0lBPeGt@jernej-laptop>
 <205b3828-6ec2-4670-ac68-a61e5cc0597d@arm.com>
 <4867577.GXAFRqVoOG@jernej-laptop>
Message-ID: <8d9d1d7c-8066-4400-8fe4-68aa0e28023d@arm.com>

Hi Jernej,

On 06/02/2024 18:32, Jernej ?krabec wrote:
> Dne torek, 06. februar 2024 ob 01:47:05 CET je Andre Przywara napisal(a):
>> Hi Jernej,
>>
>> thanks for having a look!
>>
>> On 05/02/2024 19:20, Jernej ?krabec wrote:
>>> Dne ponedeljek, 05. februar 2024 ob 19:12:45 CET je Jernej ?krabec napisal(a):
>>>> Hi Andre!
>>>>
>>>> Dne nedelja, 04. februar 2024 ob 10:44:04 CET je Andre Przywara napisal(a):
>>>>> The Remix Mini PC is a "mini computer" using the Allwinner H64 SoC,
>>>>> which appears to be just a relabelled A64. It was launched in 2015 by
>>>>> the now defunct company Jide, and shipped with a desktop optimised
>>>>> version of Android. It features
>>>>> 	- Allwinner H64 Soc (4 * Arm Cortex-A53 cores)
>>>>> 	- 1 or 2 GB DRAM
>>>>> 	- 8 or 16 GB eMMC flash
>>>>> 	- 100 MBit Ethernet port (using an X-Powers AC200 PHY)
>>>>> 	- RTL8723BS WiFi & Bluetooth chip
>>>>> 	- HDMI port
>>>>> 	- two USB 2.0 ports
>>>>> 	- 3.5mm AV port
>>>>> 	- microSD card slot
>>>>>
>>>>> The devicetree covers most peripherals, though there is no agreed
>>>>> binding for the PHY chip yet, so this is left out.
>>>>>
>>>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>>>> ---
>>>>>    arch/arm64/boot/dts/allwinner/Makefile        |   1 +
>>>>>    .../allwinner/sun50i-h64-remix-mini-pc.dts    | 357 ++++++++++++++++++
>>>>>    2 files changed, 358 insertions(+)
>>>>>    create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
>>>>>
>>>>> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
>>>>> index 91d505b385de..2db3b15ad09f 100644
>>>>> --- a/arch/arm64/boot/dts/allwinner/Makefile
>>>>> +++ b/arch/arm64/boot/dts/allwinner/Makefile
>>>>> @@ -16,6 +16,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb
>>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab-early-adopter.dtb
>>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
>>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
>>>>> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
>>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
>>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
>>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
>>>>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
>>>>> new file mode 100644
>>>>> index 000000000000..537923a541a8
>>>>> --- /dev/null
>>>>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
>>>>> @@ -0,0 +1,357 @@
>>>>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>>>>> +// Copyright (c) 2018 ARM Ltd.
>>>>
>>>> Shouldn't be 2024?
>>
>> Well, that just documents that sad fact that I indeed created this file
>> 6 years ago, but just managed now to actually send this. Is there a
>> requirement for this being "recent"?
> 
> Not really, but it's strange looking. Some might incorrectly assume that it's
> present in the kernel longer than it really is.

OK, I will put in 2023, as this is when I touched this again.

>>>>
>>>>> +
>>>>> +/dts-v1/;
>>>>> +
>>>>> +#include "sun50i-a64.dtsi"
>>>>> +#include "sun50i-a64-cpu-opp.dtsi"
>>>>> +
>>>>> +#include <dt-bindings/gpio/gpio.h>
>>>>> +
>>>>> +/ {
>>>>> +	model = "Remix Mini PC";
>>>>> +	compatible = "jide,remix-mini-pc", "allwinner,sun50i-h64",
>>>>> +		     "allwinner,sun50i-a64";
>>>>> +
>>>>> +	aliases {
>>>>> +		ethernet1 = &rtl8723bs;
>>>>> +		serial0 = &uart0;
>>>>> +	};
>>>>> +
>>>>> +	chosen {
>>>>> +		stdout-path = "serial0:115200n8";
>>>>> +	};
>>>>> +
>>>>> +	hdmi-connector {
>>>>> +		compatible = "hdmi-connector";
>>>>> +		type = "a";
>>>>> +
>>>>> +		port {
>>>>> +			hdmi_con_in: endpoint {
>>>>> +				remote-endpoint = <&hdmi_out_con>;
>>>>> +			};
>>>>> +		};
>>>>> +	};
>>>>> +
>>>>> +	reg_vcc5v: regulator-5v {
>>>>> +		/* board wide 5V supply directly from the DC input */
>>>>> +		compatible = "regulator-fixed";
>>>>> +		regulator-name = "vcc-5v";
>>>>> +		regulator-min-microvolt = <5000000>;
>>>>> +		regulator-max-microvolt = <5000000>;
>>>>> +		regulator-always-on;
>>>>> +	};
>>>>> +
>>>>> +	wifi_pwrseq: wifi_pwrseq {
>>>>> +		compatible = "mmc-pwrseq-simple";
>>>>> +		pinctrl-names = "default";
>>>>> +		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
>>>>> +		post-power-on-delay-ms = <200>;
>>>>> +	};
>>>>> +};
>>>>> +
>>>>> +&codec {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&codec_analog {
>>>>> +	cpvdd-supply = <&reg_eldo1>;
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&cpu0 {
>>>>> +	cpu-supply = <&reg_dcdc2>;
>>>>> +};
>>>>> +
>>>>> +&cpu1 {
>>>>> +	cpu-supply = <&reg_dcdc2>;
>>>>> +};
>>>>> +
>>>>> +&cpu2 {
>>>>> +	cpu-supply = <&reg_dcdc2>;
>>>>> +};
>>>>> +
>>>>> +&cpu3 {
>>>>> +	cpu-supply = <&reg_dcdc2>;
>>>>> +};
>>>>> +
>>>>> +&dai {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&de {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&ehci0 {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&ehci1 {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&hdmi {
>>>>> +	hvcc-supply = <&reg_dldo1>;
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&hdmi_out {
>>>>> +	hdmi_out_con: endpoint {
>>>>> +		remote-endpoint = <&hdmi_con_in>;
>>>>> +	};
>>>>> +};
>>>>> +
>>>>> +/* Connects to the AC200 chip */
>>>>> +&i2c0 {
>>>>> +	pinctrl-names = "default";
>>>>> +	pinctrl-0 = <&i2c0_pins>;
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&i2c0_pins {
>>>>> +	bias-pull-up;
>>>>> +};
>>>>> +
>>>>> +&mmc0 {
>>>>> +	pinctrl-names = "default";
>>>>> +	pinctrl-0 = <&mmc0_pins>;
>>>>> +	vmmc-supply = <&reg_dcdc1>;
>>>>> +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
>>>>> +	disable-wp;
>>>>> +	bus-width = <4>;
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&mmc1 {
>>>>> +	pinctrl-names = "default";
>>>>> +	pinctrl-0 = <&mmc1_pins>;
>>>>> +	vmmc-supply = <&reg_aldo1>;
>>>>> +	vqmmc-supply = <&reg_dldo4>;
>>>>> +	mmc-pwrseq = <&wifi_pwrseq>;
>>>>> +	bus-width = <4>;
>>>>> +	non-removable;
>>>>> +	status = "okay";
>>>>> +
>>>>> +	rtl8723bs: wifi at 1 {
>>>>> +		reg = <1>;
>>>>> +		interrupt-parent = <&r_pio>;
>>>>> +		interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
>>>>> +		interrupt-names = "host-wake";
>>>>> +	};
>>>>
>>>> Node without compatible doesn't help. Please remove it.
>>
>> Huh, but where do I put the the IRQ line then? And every other RTL8723BS
>> user seems to do the same?
> 
> It's good, sorry for the noise.

Just for the records, and for my own reference:
Since there is no "ranges" property in the MMC node, the Linux platform 
bus driver is not automatically traversing any child nodes. So we don't 
need a compatible string. Instead it's a new addressing scheme (this 
obsolete MMC "bus" address, like SPI or I2C), so it's up to the driver 
to do the child iteration. And it will match device #1 to reg <1>, and 
use that node, as Chen-Yu mentioned.

>>>>
>>>>> +};
>>>>> +
>>>>> +&mmc2 {
>>>>> +	pinctrl-names = "default";
>>>>> +	pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
>>>>> +	vmmc-supply = <&reg_dcdc1>;
>>>>> +	vqmmc-supply = <&reg_eldo1>;
>>>>> +	bus-width = <8>;
>>>>> +	non-removable;
>>>>> +	mmc-ddr-1_8v;
>>>>> +	mmc-hs200-1_8v;
>>>>
>>>> Aren't these speed modes enabled by default?
>>
>> Enabled by who? Our current sunxi-mmc driver? I cannot find anything in
>> the binding that suggests that there would be some default settings.
> 
> Looking at Linux sunxi mmc driver, mmc-ddr-1_8v is enabled by default for
> "new timings" variants except for H5. Anyway...

But this is a Linux implementation detail, which we should not rely on 
in a DT? And if I remember Maxime correctly back then, the plan was to 
avoid those driver hacks and just say what we support in the DT, going 
forward. This might be needed for other OSes, which might not support 
HS-200?
>>> Sorry, mmc-hs200-1_8v is ok, but mmc-ddr-1_8v should be
>>> removed.
>>
>> Mmh, I am confused: I thought after the H5 eMMC mishap we figured that
>> all speed modes supported by the eMMC chip should be listed in the DT?
> 
> I think H5 just has (had?) driver issue. From what I can see, only highest
> supported mode by kernel and chip is specified in all Allwinner DTs.
> mmc-ddr-1_8v is only specified by two recent board addition, where I missed
> it while reviewing.
> 
>> So any driver wouldn't need to make assumptions, and if a particular
>> mode shows problems on a board, we just remove that mode from the DT.
>> Actually, thinking about that, I guess I should list HS-400 as well? The
>> BSP kernel uses that mode.
> 
> Sure, but it also calibrates timing for it. If you'll specify HS400, kernel
> will try to use it, but it won't work.

But this is also a limitation of the current Linux kernel driver. And 
since we indeed don't support HS-400, we explicitly remove it from the 
capability list, *after* the call to mmc_of_parse():

drivers/mmc/host/sunxi-mmc.c:1460
         /* TODO: This driver doesn't support HS400 mode yet */
         mmc->caps2 &= ~MMC_CAP2_HS400;

So I think this should be safe?

Cheers,
Andre

> 
>> Or do you mean to say that in particular DDR (@1.8V) is problematic? I
>> cannot test at the moment, but could try later to force that mode.
> 
> No, no need.
> 
> Best regards,
> Jernej
> 
>>
>> Cheers,
>> Andre
>>
>>
>>>>> +	cap-mmc-hw-reset;
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&ohci0 {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&ohci1 {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&pio {
>>>>> +	vcc-pb-supply = <&reg_dcdc1>;
>>>>> +	vcc-pc-supply = <&reg_dcdc1>;
>>>>> +	vcc-pd-supply = <&reg_dcdc1>;
>>>>> +	vcc-pe-supply = <&reg_dcdc1>;
>>>>> +	vcc-pf-supply = <&reg_dcdc1>;
>>>>> +	vcc-pg-supply = <&reg_dldo4>;
>>>>> +	vcc-ph-supply = <&reg_dcdc1>;
>>>>> +};
>>>>> +
>>>>> +&r_ir {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&r_pio {
>>>>> +	/*
>>>>> +	 * We cannot add that supply for now since it would create a circular
>>>>> +	 * dependency between pinctrl, the regulator and the RSB Bus.
>>>>> +	 *
>>>>> +	 * vcc-pl-supply = <&reg_aldo2>;
>>>>> +	 */
>>>>> +};
>>>>> +
>>>>> +&r_rsb {
>>>>> +	status = "okay";
>>>>> +
>>>>> +	axp803: pmic at 3a3 {
>>>>> +		compatible = "x-powers,axp803";
>>>>> +		reg = <0x3a3>;
>>>>> +		interrupt-parent = <&r_intc>;
>>>>> +		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
>>>>> +		x-powers,drive-vbus-en;
>>>>> +
>>>>> +		vin1-supply = <&reg_vcc5v>;
>>>>> +		vin2-supply = <&reg_vcc5v>;
>>>>> +		vin3-supply = <&reg_vcc5v>;
>>>>> +		vin5-supply = <&reg_vcc5v>;
>>>>> +		vin6-supply = <&reg_vcc5v>;
>>>>> +		aldoin-supply = <&reg_vcc5v>;
>>>>> +		dldoin-supply = <&reg_vcc5v>;
>>>>> +		eldoin-supply = <&reg_vcc5v>;
>>>>> +		fldoin-supply = <&reg_vcc5v>;
>>>>> +		drivevbus-supply = <&reg_vcc5v>;
>>>>> +		ips-supply = <&reg_vcc5v>;
>>>>> +
>>>>> +		status = "okay";
>>>>> +	};
>>>>> +};
>>>>> +
>>>>> +#include "axp803.dtsi"
>>>>> +
>>>>> +&ac_power_supply {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&reg_dcdc1 {
>>>>> +	regulator-always-on;
>>>>> +	regulator-min-microvolt = <3300000>;
>>>>> +	regulator-max-microvolt = <3300000>;
>>>>> +	regulator-name = "vcc-3v3";
>>>>> +};
>>>>> +
>>>>> +&reg_dcdc2 {
>>>>> +	regulator-always-on;
>>>>> +	regulator-min-microvolt = <1040000>;
>>>>> +	regulator-max-microvolt = <1300000>;
>>>>> +	regulator-name = "vdd-cpux";
>>>>> +};
>>>>> +
>>>>> +/* DCDC3 is polyphased with DCDC2 */
>>>>> +
>>>>> +&reg_dcdc5 {
>>>>> +	regulator-always-on;
>>>>> +	regulator-min-microvolt = <1500000>;
>>>>> +	regulator-max-microvolt = <1500000>;
>>>>> +	regulator-name = "vcc-dram";
>>>>> +};
>>>>> +
>>>>> +/* Deviates from the reset default of 1.1V. */
>>>>> +&reg_dcdc6 {
>>>>> +	regulator-always-on;
>>>>> +	regulator-min-microvolt = <1200000>;
>>>>> +	regulator-max-microvolt = <1200000>;
>>>>> +	regulator-name = "vdd-sys";
>>>>> +};
>>>>> +
>>>>> +&reg_aldo1 {
>>>>> +	regulator-min-microvolt = <3300000>;
>>>>> +	regulator-max-microvolt = <3300000>;
>>>>> +	regulator-name = "vcc-wifi";
>>>>> +};
>>>>> +
>>>>> +&reg_aldo2 {
>>>>> +	/* Specifying R_PIO consumer would create circular dependency. */
>>>>> +	regulator-always-on;
>>>>> +	regulator-min-microvolt = <3300000>;
>>>>> +	regulator-max-microvolt = <3300000>;
>>>>> +	regulator-name = "vcc-pl";
>>>>> +};
>>>>> +
>>>>> +&reg_aldo3 {
>>>>> +	regulator-always-on;
>>>>> +	regulator-min-microvolt = <3000000>;
>>>>> +	regulator-max-microvolt = <3000000>;
>>>>> +	regulator-name = "vcc-pll-avcc";
>>>>> +};
>>>>> +
>>>>> +/* AC200 power supply */
>>>>> +&reg_dldo1 {
>>>>> +	regulator-always-on;
>>>>> +	regulator-min-microvolt = <3300000>;
>>>>> +	regulator-max-microvolt = <3300000>;
>>>>> +	regulator-name = "vcc-ave-33";
>>>>> +};
>>>>> +
>>>>> +&reg_dldo4 {
>>>>> +	regulator-min-microvolt = <3300000>;
>>>>> +	regulator-max-microvolt = <3300000>;
>>>>> +	regulator-name = "vcc-wifi-io";
>>>>> +};
>>>>> +
>>>>> +&reg_drivevbus {
>>>>> +	regulator-name = "usb0-vbus";
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&reg_eldo1 {
>>>>> +	regulator-always-on;
>>>>> +	regulator-min-microvolt = <1800000>;
>>>>> +	regulator-max-microvolt = <1800000>;
>>>>> +	regulator-name = "vcc-cpvdd-dram-emmc";
>>>>> +};
>>>>> +
>>>>> +/* Supplies the arisc management core, needed by TF-A to power off cores. */
>>>>> +&reg_fldo2 {
>>>>> +	regulator-always-on;
>>>>> +	regulator-min-microvolt = <1100000>;
>>>>> +	regulator-max-microvolt = <1100000>;
>>>>> +	regulator-name = "vdd-cpus";
>>>>> +};
>>>>> +
>>>>> +&reg_rtc_ldo {
>>>>> +	regulator-name = "vcc-rtc";
>>>>> +};
>>>>> +
>>>>> +&simplefb_hdmi {
>>>>> +	vcc-hdmi-supply = <&reg_dcdc1>;
>>>>> +};
>>>>> +
>>>>> +&sound {
>>>>> +	simple-audio-card,aux-devs = <&codec_analog>;
>>>>> +	simple-audio-card,widgets = "Microphone", "Microphone Jack",
>>>>> +				    "Headphone", "Headphone Jack";
>>>>> +	simple-audio-card,routing =
>>>>> +			"Left DAC", "DACL",
>>>>> +			"Right DAC", "DACR",
>>>>> +			"Headphone Jack", "HP",
>>>>> +			"ADCL", "Left ADC",
>>>>> +			"ADCR", "Right ADC",
>>>>> +			"MIC2", "Microphone Jack";
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +/* On the (unpopulated) UART pads. */
>>>>> +&uart0 {
>>>>> +	pinctrl-names = "default";
>>>>> +	pinctrl-0 = <&uart0_pb_pins>;
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&uart1 {
>>>>> +	pinctrl-names = "default";
>>>>> +	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
>>>>> +	uart-has-rtscts;
>>>>> +	status = "okay";
>>>>> +
>>>>> +	bluetooth {
>>>>> +		compatible = "realtek,rtl8723bs-bt";
>>>>> +		enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
>>>>> +		max-speed = <1500000>;
>>>>> +	};
>>>>> +};
>>>>> +
>>>>> +&usb_otg {
>>>>> +	dr_mode = "host";
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&usbphy {
>>>>> +	usb0_vbus-supply = <&reg_drivevbus>;
>>>>> +	usb1_vbus-supply = <&reg_drivevbus>;
>>>>> +	status = "okay";
>>>>> +};
>>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>>
>>
> 
> 
> 
> 


From jernej.skrabec at gmail.com  Tue Feb  6 10:23:35 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 06 Feb 2024 19:23:35 +0100
Subject: [PATCH 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC support
In-Reply-To: <8d9d1d7c-8066-4400-8fe4-68aa0e28023d@arm.com>
References: <20240204094404.149776-1-andre.przywara@arm.com>
 <4867577.GXAFRqVoOG@jernej-laptop>
 <8d9d1d7c-8066-4400-8fe4-68aa0e28023d@arm.com>
Message-ID: <10413667.nUPlyArG6x@jernej-laptop>

Dne torek, 06. februar 2024 ob 19:13:46 CET je Andre Przywara napisal(a):
> Hi Jernej,
> 
> On 06/02/2024 18:32, Jernej ?krabec wrote:
> > Dne torek, 06. februar 2024 ob 01:47:05 CET je Andre Przywara napisal(a):
> >> Hi Jernej,
> >>
> >> thanks for having a look!
> >>
> >> On 05/02/2024 19:20, Jernej ?krabec wrote:
> >>> Dne ponedeljek, 05. februar 2024 ob 19:12:45 CET je Jernej ?krabec napisal(a):
> >>>> Hi Andre!
> >>>>
> >>>> Dne nedelja, 04. februar 2024 ob 10:44:04 CET je Andre Przywara napisal(a):
> >>>>> The Remix Mini PC is a "mini computer" using the Allwinner H64 SoC,
> >>>>> which appears to be just a relabelled A64. It was launched in 2015 by
> >>>>> the now defunct company Jide, and shipped with a desktop optimised
> >>>>> version of Android. It features
> >>>>> 	- Allwinner H64 Soc (4 * Arm Cortex-A53 cores)
> >>>>> 	- 1 or 2 GB DRAM
> >>>>> 	- 8 or 16 GB eMMC flash
> >>>>> 	- 100 MBit Ethernet port (using an X-Powers AC200 PHY)
> >>>>> 	- RTL8723BS WiFi & Bluetooth chip
> >>>>> 	- HDMI port
> >>>>> 	- two USB 2.0 ports
> >>>>> 	- 3.5mm AV port
> >>>>> 	- microSD card slot
> >>>>>
> >>>>> The devicetree covers most peripherals, though there is no agreed
> >>>>> binding for the PHY chip yet, so this is left out.
> >>>>>
> >>>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> >>>>> ---
> >>>>>    arch/arm64/boot/dts/allwinner/Makefile        |   1 +
> >>>>>    .../allwinner/sun50i-h64-remix-mini-pc.dts    | 357 ++++++++++++++++++
> >>>>>    2 files changed, 358 insertions(+)
> >>>>>    create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> >>>>>
> >>>>> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> >>>>> index 91d505b385de..2db3b15ad09f 100644
> >>>>> --- a/arch/arm64/boot/dts/allwinner/Makefile
> >>>>> +++ b/arch/arm64/boot/dts/allwinner/Makefile
> >>>>> @@ -16,6 +16,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb
> >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab-early-adopter.dtb
> >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
> >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
> >>>>> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
> >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
> >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
> >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
> >>>>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> >>>>> new file mode 100644
> >>>>> index 000000000000..537923a541a8
> >>>>> --- /dev/null
> >>>>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> >>>>> @@ -0,0 +1,357 @@
> >>>>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> >>>>> +// Copyright (c) 2018 ARM Ltd.
> >>>>
> >>>> Shouldn't be 2024?
> >>
> >> Well, that just documents that sad fact that I indeed created this file
> >> 6 years ago, but just managed now to actually send this. Is there a
> >> requirement for this being "recent"?
> > 
> > Not really, but it's strange looking. Some might incorrectly assume that it's
> > present in the kernel longer than it really is.
> 
> OK, I will put in 2023, as this is when I touched this again.
> 
> >>>>
> >>>>> +
> >>>>> +/dts-v1/;
> >>>>> +
> >>>>> +#include "sun50i-a64.dtsi"
> >>>>> +#include "sun50i-a64-cpu-opp.dtsi"
> >>>>> +
> >>>>> +#include <dt-bindings/gpio/gpio.h>
> >>>>> +
> >>>>> +/ {
> >>>>> +	model = "Remix Mini PC";
> >>>>> +	compatible = "jide,remix-mini-pc", "allwinner,sun50i-h64",
> >>>>> +		     "allwinner,sun50i-a64";
> >>>>> +
> >>>>> +	aliases {
> >>>>> +		ethernet1 = &rtl8723bs;
> >>>>> +		serial0 = &uart0;
> >>>>> +	};
> >>>>> +
> >>>>> +	chosen {
> >>>>> +		stdout-path = "serial0:115200n8";
> >>>>> +	};
> >>>>> +
> >>>>> +	hdmi-connector {
> >>>>> +		compatible = "hdmi-connector";
> >>>>> +		type = "a";
> >>>>> +
> >>>>> +		port {
> >>>>> +			hdmi_con_in: endpoint {
> >>>>> +				remote-endpoint = <&hdmi_out_con>;
> >>>>> +			};
> >>>>> +		};
> >>>>> +	};
> >>>>> +
> >>>>> +	reg_vcc5v: regulator-5v {
> >>>>> +		/* board wide 5V supply directly from the DC input */
> >>>>> +		compatible = "regulator-fixed";
> >>>>> +		regulator-name = "vcc-5v";
> >>>>> +		regulator-min-microvolt = <5000000>;
> >>>>> +		regulator-max-microvolt = <5000000>;
> >>>>> +		regulator-always-on;
> >>>>> +	};
> >>>>> +
> >>>>> +	wifi_pwrseq: wifi_pwrseq {
> >>>>> +		compatible = "mmc-pwrseq-simple";
> >>>>> +		pinctrl-names = "default";
> >>>>> +		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
> >>>>> +		post-power-on-delay-ms = <200>;
> >>>>> +	};
> >>>>> +};
> >>>>> +
> >>>>> +&codec {
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&codec_analog {
> >>>>> +	cpvdd-supply = <&reg_eldo1>;
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&cpu0 {
> >>>>> +	cpu-supply = <&reg_dcdc2>;
> >>>>> +};
> >>>>> +
> >>>>> +&cpu1 {
> >>>>> +	cpu-supply = <&reg_dcdc2>;
> >>>>> +};
> >>>>> +
> >>>>> +&cpu2 {
> >>>>> +	cpu-supply = <&reg_dcdc2>;
> >>>>> +};
> >>>>> +
> >>>>> +&cpu3 {
> >>>>> +	cpu-supply = <&reg_dcdc2>;
> >>>>> +};
> >>>>> +
> >>>>> +&dai {
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&de {
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&ehci0 {
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&ehci1 {
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&hdmi {
> >>>>> +	hvcc-supply = <&reg_dldo1>;
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&hdmi_out {
> >>>>> +	hdmi_out_con: endpoint {
> >>>>> +		remote-endpoint = <&hdmi_con_in>;
> >>>>> +	};
> >>>>> +};
> >>>>> +
> >>>>> +/* Connects to the AC200 chip */
> >>>>> +&i2c0 {
> >>>>> +	pinctrl-names = "default";
> >>>>> +	pinctrl-0 = <&i2c0_pins>;
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&i2c0_pins {
> >>>>> +	bias-pull-up;
> >>>>> +};
> >>>>> +
> >>>>> +&mmc0 {
> >>>>> +	pinctrl-names = "default";
> >>>>> +	pinctrl-0 = <&mmc0_pins>;
> >>>>> +	vmmc-supply = <&reg_dcdc1>;
> >>>>> +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
> >>>>> +	disable-wp;
> >>>>> +	bus-width = <4>;
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&mmc1 {
> >>>>> +	pinctrl-names = "default";
> >>>>> +	pinctrl-0 = <&mmc1_pins>;
> >>>>> +	vmmc-supply = <&reg_aldo1>;
> >>>>> +	vqmmc-supply = <&reg_dldo4>;
> >>>>> +	mmc-pwrseq = <&wifi_pwrseq>;
> >>>>> +	bus-width = <4>;
> >>>>> +	non-removable;
> >>>>> +	status = "okay";
> >>>>> +
> >>>>> +	rtl8723bs: wifi at 1 {
> >>>>> +		reg = <1>;
> >>>>> +		interrupt-parent = <&r_pio>;
> >>>>> +		interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
> >>>>> +		interrupt-names = "host-wake";
> >>>>> +	};
> >>>>
> >>>> Node without compatible doesn't help. Please remove it.
> >>
> >> Huh, but where do I put the the IRQ line then? And every other RTL8723BS
> >> user seems to do the same?
> > 
> > It's good, sorry for the noise.
> 
> Just for the records, and for my own reference:
> Since there is no "ranges" property in the MMC node, the Linux platform 
> bus driver is not automatically traversing any child nodes. So we don't 
> need a compatible string. Instead it's a new addressing scheme (this 
> obsolete MMC "bus" address, like SPI or I2C), so it's up to the driver 
> to do the child iteration. And it will match device #1 to reg <1>, and 
> use that node, as Chen-Yu mentioned.
> 
> >>>>
> >>>>> +};
> >>>>> +
> >>>>> +&mmc2 {
> >>>>> +	pinctrl-names = "default";
> >>>>> +	pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
> >>>>> +	vmmc-supply = <&reg_dcdc1>;
> >>>>> +	vqmmc-supply = <&reg_eldo1>;
> >>>>> +	bus-width = <8>;
> >>>>> +	non-removable;
> >>>>> +	mmc-ddr-1_8v;
> >>>>> +	mmc-hs200-1_8v;
> >>>>
> >>>> Aren't these speed modes enabled by default?
> >>
> >> Enabled by who? Our current sunxi-mmc driver? I cannot find anything in
> >> the binding that suggests that there would be some default settings.
> > 
> > Looking at Linux sunxi mmc driver, mmc-ddr-1_8v is enabled by default for
> > "new timings" variants except for H5. Anyway...
> 
> But this is a Linux implementation detail, which we should not rely on 
> in a DT? And if I remember Maxime correctly back then, the plan was to 
> avoid those driver hacks and just say what we support in the DT, going 
> forward. This might be needed for other OSes, which might not support 
> HS-200?
> >>> Sorry, mmc-hs200-1_8v is ok, but mmc-ddr-1_8v should be
> >>> removed.
> >>
> >> Mmh, I am confused: I thought after the H5 eMMC mishap we figured that
> >> all speed modes supported by the eMMC chip should be listed in the DT?
> > 
> > I think H5 just has (had?) driver issue. From what I can see, only highest
> > supported mode by kernel and chip is specified in all Allwinner DTs.
> > mmc-ddr-1_8v is only specified by two recent board addition, where I missed
> > it while reviewing.
> > 
> >> So any driver wouldn't need to make assumptions, and if a particular
> >> mode shows problems on a board, we just remove that mode from the DT.
> >> Actually, thinking about that, I guess I should list HS-400 as well? The
> >> BSP kernel uses that mode.
> > 
> > Sure, but it also calibrates timing for it. If you'll specify HS400, kernel
> > will try to use it, but it won't work.
> 
> But this is also a limitation of the current Linux kernel driver. And 
> since we indeed don't support HS-400, we explicitly remove it from the 
> capability list, *after* the call to mmc_of_parse():
> 
> drivers/mmc/host/sunxi-mmc.c:1460
>          /* TODO: This driver doesn't support HS400 mode yet */
>          mmc->caps2 &= ~MMC_CAP2_HS400;
> 
> So I think this should be safe?

Right. Can you test it?

Best regards,
Jernej

> 
> Cheers,
> Andre
> 
> > 
> >> Or do you mean to say that in particular DDR (@1.8V) is problematic? I
> >> cannot test at the moment, but could try later to force that mode.
> > 
> > No, no need.
> > 
> > Best regards,
> > Jernej
> > 
> >>
> >> Cheers,
> >> Andre
> >>
> >>
> >>>>> +	cap-mmc-hw-reset;
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&ohci0 {
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&ohci1 {
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&pio {
> >>>>> +	vcc-pb-supply = <&reg_dcdc1>;
> >>>>> +	vcc-pc-supply = <&reg_dcdc1>;
> >>>>> +	vcc-pd-supply = <&reg_dcdc1>;
> >>>>> +	vcc-pe-supply = <&reg_dcdc1>;
> >>>>> +	vcc-pf-supply = <&reg_dcdc1>;
> >>>>> +	vcc-pg-supply = <&reg_dldo4>;
> >>>>> +	vcc-ph-supply = <&reg_dcdc1>;
> >>>>> +};
> >>>>> +
> >>>>> +&r_ir {
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&r_pio {
> >>>>> +	/*
> >>>>> +	 * We cannot add that supply for now since it would create a circular
> >>>>> +	 * dependency between pinctrl, the regulator and the RSB Bus.
> >>>>> +	 *
> >>>>> +	 * vcc-pl-supply = <&reg_aldo2>;
> >>>>> +	 */
> >>>>> +};
> >>>>> +
> >>>>> +&r_rsb {
> >>>>> +	status = "okay";
> >>>>> +
> >>>>> +	axp803: pmic at 3a3 {
> >>>>> +		compatible = "x-powers,axp803";
> >>>>> +		reg = <0x3a3>;
> >>>>> +		interrupt-parent = <&r_intc>;
> >>>>> +		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
> >>>>> +		x-powers,drive-vbus-en;
> >>>>> +
> >>>>> +		vin1-supply = <&reg_vcc5v>;
> >>>>> +		vin2-supply = <&reg_vcc5v>;
> >>>>> +		vin3-supply = <&reg_vcc5v>;
> >>>>> +		vin5-supply = <&reg_vcc5v>;
> >>>>> +		vin6-supply = <&reg_vcc5v>;
> >>>>> +		aldoin-supply = <&reg_vcc5v>;
> >>>>> +		dldoin-supply = <&reg_vcc5v>;
> >>>>> +		eldoin-supply = <&reg_vcc5v>;
> >>>>> +		fldoin-supply = <&reg_vcc5v>;
> >>>>> +		drivevbus-supply = <&reg_vcc5v>;
> >>>>> +		ips-supply = <&reg_vcc5v>;
> >>>>> +
> >>>>> +		status = "okay";
> >>>>> +	};
> >>>>> +};
> >>>>> +
> >>>>> +#include "axp803.dtsi"
> >>>>> +
> >>>>> +&ac_power_supply {
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&reg_dcdc1 {
> >>>>> +	regulator-always-on;
> >>>>> +	regulator-min-microvolt = <3300000>;
> >>>>> +	regulator-max-microvolt = <3300000>;
> >>>>> +	regulator-name = "vcc-3v3";
> >>>>> +};
> >>>>> +
> >>>>> +&reg_dcdc2 {
> >>>>> +	regulator-always-on;
> >>>>> +	regulator-min-microvolt = <1040000>;
> >>>>> +	regulator-max-microvolt = <1300000>;
> >>>>> +	regulator-name = "vdd-cpux";
> >>>>> +};
> >>>>> +
> >>>>> +/* DCDC3 is polyphased with DCDC2 */
> >>>>> +
> >>>>> +&reg_dcdc5 {
> >>>>> +	regulator-always-on;
> >>>>> +	regulator-min-microvolt = <1500000>;
> >>>>> +	regulator-max-microvolt = <1500000>;
> >>>>> +	regulator-name = "vcc-dram";
> >>>>> +};
> >>>>> +
> >>>>> +/* Deviates from the reset default of 1.1V. */
> >>>>> +&reg_dcdc6 {
> >>>>> +	regulator-always-on;
> >>>>> +	regulator-min-microvolt = <1200000>;
> >>>>> +	regulator-max-microvolt = <1200000>;
> >>>>> +	regulator-name = "vdd-sys";
> >>>>> +};
> >>>>> +
> >>>>> +&reg_aldo1 {
> >>>>> +	regulator-min-microvolt = <3300000>;
> >>>>> +	regulator-max-microvolt = <3300000>;
> >>>>> +	regulator-name = "vcc-wifi";
> >>>>> +};
> >>>>> +
> >>>>> +&reg_aldo2 {
> >>>>> +	/* Specifying R_PIO consumer would create circular dependency. */
> >>>>> +	regulator-always-on;
> >>>>> +	regulator-min-microvolt = <3300000>;
> >>>>> +	regulator-max-microvolt = <3300000>;
> >>>>> +	regulator-name = "vcc-pl";
> >>>>> +};
> >>>>> +
> >>>>> +&reg_aldo3 {
> >>>>> +	regulator-always-on;
> >>>>> +	regulator-min-microvolt = <3000000>;
> >>>>> +	regulator-max-microvolt = <3000000>;
> >>>>> +	regulator-name = "vcc-pll-avcc";
> >>>>> +};
> >>>>> +
> >>>>> +/* AC200 power supply */
> >>>>> +&reg_dldo1 {
> >>>>> +	regulator-always-on;
> >>>>> +	regulator-min-microvolt = <3300000>;
> >>>>> +	regulator-max-microvolt = <3300000>;
> >>>>> +	regulator-name = "vcc-ave-33";
> >>>>> +};
> >>>>> +
> >>>>> +&reg_dldo4 {
> >>>>> +	regulator-min-microvolt = <3300000>;
> >>>>> +	regulator-max-microvolt = <3300000>;
> >>>>> +	regulator-name = "vcc-wifi-io";
> >>>>> +};
> >>>>> +
> >>>>> +&reg_drivevbus {
> >>>>> +	regulator-name = "usb0-vbus";
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&reg_eldo1 {
> >>>>> +	regulator-always-on;
> >>>>> +	regulator-min-microvolt = <1800000>;
> >>>>> +	regulator-max-microvolt = <1800000>;
> >>>>> +	regulator-name = "vcc-cpvdd-dram-emmc";
> >>>>> +};
> >>>>> +
> >>>>> +/* Supplies the arisc management core, needed by TF-A to power off cores. */
> >>>>> +&reg_fldo2 {
> >>>>> +	regulator-always-on;
> >>>>> +	regulator-min-microvolt = <1100000>;
> >>>>> +	regulator-max-microvolt = <1100000>;
> >>>>> +	regulator-name = "vdd-cpus";
> >>>>> +};
> >>>>> +
> >>>>> +&reg_rtc_ldo {
> >>>>> +	regulator-name = "vcc-rtc";
> >>>>> +};
> >>>>> +
> >>>>> +&simplefb_hdmi {
> >>>>> +	vcc-hdmi-supply = <&reg_dcdc1>;
> >>>>> +};
> >>>>> +
> >>>>> +&sound {
> >>>>> +	simple-audio-card,aux-devs = <&codec_analog>;
> >>>>> +	simple-audio-card,widgets = "Microphone", "Microphone Jack",
> >>>>> +				    "Headphone", "Headphone Jack";
> >>>>> +	simple-audio-card,routing =
> >>>>> +			"Left DAC", "DACL",
> >>>>> +			"Right DAC", "DACR",
> >>>>> +			"Headphone Jack", "HP",
> >>>>> +			"ADCL", "Left ADC",
> >>>>> +			"ADCR", "Right ADC",
> >>>>> +			"MIC2", "Microphone Jack";
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +/* On the (unpopulated) UART pads. */
> >>>>> +&uart0 {
> >>>>> +	pinctrl-names = "default";
> >>>>> +	pinctrl-0 = <&uart0_pb_pins>;
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&uart1 {
> >>>>> +	pinctrl-names = "default";
> >>>>> +	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
> >>>>> +	uart-has-rtscts;
> >>>>> +	status = "okay";
> >>>>> +
> >>>>> +	bluetooth {
> >>>>> +		compatible = "realtek,rtl8723bs-bt";
> >>>>> +		enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
> >>>>> +		max-speed = <1500000>;
> >>>>> +	};
> >>>>> +};
> >>>>> +
> >>>>> +&usb_otg {
> >>>>> +	dr_mode = "host";
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>> +
> >>>>> +&usbphy {
> >>>>> +	usb0_vbus-supply = <&reg_drivevbus>;
> >>>>> +	usb1_vbus-supply = <&reg_drivevbus>;
> >>>>> +	status = "okay";
> >>>>> +};
> >>>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>
> >>>
> >>>
> >>>
> >>
> > 
> > 
> > 
> > 
> 






From robh at kernel.org  Tue Feb  6 10:23:43 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 06 Feb 2024 18:23:43 +0000
Subject: [PATCH 2/4] dt-bindings: hwinfo: ti,k3-socinfo: Add
 nvmem-cells
In-Reply-To: <20240206143711.2410135-3-msp@baylibre.com>
References: <20240206143711.2410135-1-msp@baylibre.com>
 <20240206143711.2410135-3-msp@baylibre.com>
Message-ID: <170724381132.1723363.3827684466667274405.robh@kernel.org>


On Tue, 06 Feb 2024 15:37:09 +0100, Markus Schneider-Pargmann wrote:
> The information k3-socinfo requires is stored in an efuse area. This
> area is required by other devices/drivers as well, so using nvmem-cells
> can be a cleaner way to describe which information are used.
> 
> If nvmem-cells are supplied, the address range is not required.
> Cells chipvariant, chippartno and chipmanufacturer are introduced to
> cover all required information.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> Reviewed-by: Andrew Davis <afd at ti.com>
> ---
>  .../bindings/hwinfo/ti,k3-socinfo.yaml        | 23 ++++++++++++++++++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
> 

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/hwinfo/ti,k3-socinfo.example.dts:39.27-43.11: Warning (unit_address_vs_reg): /example-1/chipid at 14: node has a unit name, but no reg or ranges property

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240206143711.2410135-3-msp at baylibre.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From jernej.skrabec at gmail.com  Tue Feb  6 10:27:22 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 06 Feb 2024 19:27:22 +0100
Subject: [PATCH 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC support
In-Reply-To: <10413667.nUPlyArG6x@jernej-laptop>
References: <20240204094404.149776-1-andre.przywara@arm.com>
 <8d9d1d7c-8066-4400-8fe4-68aa0e28023d@arm.com>
 <10413667.nUPlyArG6x@jernej-laptop>
Message-ID: <1957012.PYKUYFuaPT@jernej-laptop>

Dne torek, 06. februar 2024 ob 19:23:35 CET je Jernej ?krabec napisal(a):
> Dne torek, 06. februar 2024 ob 19:13:46 CET je Andre Przywara napisal(a):
> > Hi Jernej,
> > 
> > On 06/02/2024 18:32, Jernej ?krabec wrote:
> > > Dne torek, 06. februar 2024 ob 01:47:05 CET je Andre Przywara napisal(a):
> > >> Hi Jernej,
> > >>
> > >> thanks for having a look!
> > >>
> > >> On 05/02/2024 19:20, Jernej ?krabec wrote:
> > >>> Dne ponedeljek, 05. februar 2024 ob 19:12:45 CET je Jernej ?krabec napisal(a):
> > >>>> Hi Andre!
> > >>>>
> > >>>> Dne nedelja, 04. februar 2024 ob 10:44:04 CET je Andre Przywara napisal(a):
> > >>>>> The Remix Mini PC is a "mini computer" using the Allwinner H64 SoC,
> > >>>>> which appears to be just a relabelled A64. It was launched in 2015 by
> > >>>>> the now defunct company Jide, and shipped with a desktop optimised
> > >>>>> version of Android. It features
> > >>>>> 	- Allwinner H64 Soc (4 * Arm Cortex-A53 cores)
> > >>>>> 	- 1 or 2 GB DRAM
> > >>>>> 	- 8 or 16 GB eMMC flash
> > >>>>> 	- 100 MBit Ethernet port (using an X-Powers AC200 PHY)
> > >>>>> 	- RTL8723BS WiFi & Bluetooth chip
> > >>>>> 	- HDMI port
> > >>>>> 	- two USB 2.0 ports
> > >>>>> 	- 3.5mm AV port
> > >>>>> 	- microSD card slot
> > >>>>>
> > >>>>> The devicetree covers most peripherals, though there is no agreed
> > >>>>> binding for the PHY chip yet, so this is left out.
> > >>>>>
> > >>>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > >>>>> ---
> > >>>>>    arch/arm64/boot/dts/allwinner/Makefile        |   1 +
> > >>>>>    .../allwinner/sun50i-h64-remix-mini-pc.dts    | 357 ++++++++++++++++++
> > >>>>>    2 files changed, 358 insertions(+)
> > >>>>>    create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> > >>>>>
> > >>>>> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> > >>>>> index 91d505b385de..2db3b15ad09f 100644
> > >>>>> --- a/arch/arm64/boot/dts/allwinner/Makefile
> > >>>>> +++ b/arch/arm64/boot/dts/allwinner/Makefile
> > >>>>> @@ -16,6 +16,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb
> > >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab-early-adopter.dtb
> > >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
> > >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
> > >>>>> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
> > >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
> > >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
> > >>>>>    dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
> > >>>>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> > >>>>> new file mode 100644
> > >>>>> index 000000000000..537923a541a8
> > >>>>> --- /dev/null
> > >>>>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> > >>>>> @@ -0,0 +1,357 @@
> > >>>>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > >>>>> +// Copyright (c) 2018 ARM Ltd.
> > >>>>
> > >>>> Shouldn't be 2024?
> > >>
> > >> Well, that just documents that sad fact that I indeed created this file
> > >> 6 years ago, but just managed now to actually send this. Is there a
> > >> requirement for this being "recent"?
> > > 
> > > Not really, but it's strange looking. Some might incorrectly assume that it's
> > > present in the kernel longer than it really is.
> > 
> > OK, I will put in 2023, as this is when I touched this again.
> > 
> > >>>>
> > >>>>> +
> > >>>>> +/dts-v1/;
> > >>>>> +
> > >>>>> +#include "sun50i-a64.dtsi"
> > >>>>> +#include "sun50i-a64-cpu-opp.dtsi"
> > >>>>> +
> > >>>>> +#include <dt-bindings/gpio/gpio.h>
> > >>>>> +
> > >>>>> +/ {
> > >>>>> +	model = "Remix Mini PC";
> > >>>>> +	compatible = "jide,remix-mini-pc", "allwinner,sun50i-h64",
> > >>>>> +		     "allwinner,sun50i-a64";
> > >>>>> +
> > >>>>> +	aliases {
> > >>>>> +		ethernet1 = &rtl8723bs;
> > >>>>> +		serial0 = &uart0;
> > >>>>> +	};
> > >>>>> +
> > >>>>> +	chosen {
> > >>>>> +		stdout-path = "serial0:115200n8";
> > >>>>> +	};
> > >>>>> +
> > >>>>> +	hdmi-connector {
> > >>>>> +		compatible = "hdmi-connector";
> > >>>>> +		type = "a";
> > >>>>> +
> > >>>>> +		port {
> > >>>>> +			hdmi_con_in: endpoint {
> > >>>>> +				remote-endpoint = <&hdmi_out_con>;
> > >>>>> +			};
> > >>>>> +		};
> > >>>>> +	};
> > >>>>> +
> > >>>>> +	reg_vcc5v: regulator-5v {
> > >>>>> +		/* board wide 5V supply directly from the DC input */
> > >>>>> +		compatible = "regulator-fixed";
> > >>>>> +		regulator-name = "vcc-5v";
> > >>>>> +		regulator-min-microvolt = <5000000>;
> > >>>>> +		regulator-max-microvolt = <5000000>;
> > >>>>> +		regulator-always-on;
> > >>>>> +	};
> > >>>>> +
> > >>>>> +	wifi_pwrseq: wifi_pwrseq {
> > >>>>> +		compatible = "mmc-pwrseq-simple";
> > >>>>> +		pinctrl-names = "default";
> > >>>>> +		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
> > >>>>> +		post-power-on-delay-ms = <200>;
> > >>>>> +	};
> > >>>>> +};
> > >>>>> +
> > >>>>> +&codec {
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&codec_analog {
> > >>>>> +	cpvdd-supply = <&reg_eldo1>;
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&cpu0 {
> > >>>>> +	cpu-supply = <&reg_dcdc2>;
> > >>>>> +};
> > >>>>> +
> > >>>>> +&cpu1 {
> > >>>>> +	cpu-supply = <&reg_dcdc2>;
> > >>>>> +};
> > >>>>> +
> > >>>>> +&cpu2 {
> > >>>>> +	cpu-supply = <&reg_dcdc2>;
> > >>>>> +};
> > >>>>> +
> > >>>>> +&cpu3 {
> > >>>>> +	cpu-supply = <&reg_dcdc2>;
> > >>>>> +};
> > >>>>> +
> > >>>>> +&dai {
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&de {
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&ehci0 {
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&ehci1 {
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&hdmi {
> > >>>>> +	hvcc-supply = <&reg_dldo1>;
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&hdmi_out {
> > >>>>> +	hdmi_out_con: endpoint {
> > >>>>> +		remote-endpoint = <&hdmi_con_in>;
> > >>>>> +	};
> > >>>>> +};
> > >>>>> +
> > >>>>> +/* Connects to the AC200 chip */
> > >>>>> +&i2c0 {
> > >>>>> +	pinctrl-names = "default";
> > >>>>> +	pinctrl-0 = <&i2c0_pins>;
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&i2c0_pins {
> > >>>>> +	bias-pull-up;
> > >>>>> +};
> > >>>>> +
> > >>>>> +&mmc0 {
> > >>>>> +	pinctrl-names = "default";
> > >>>>> +	pinctrl-0 = <&mmc0_pins>;
> > >>>>> +	vmmc-supply = <&reg_dcdc1>;
> > >>>>> +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
> > >>>>> +	disable-wp;
> > >>>>> +	bus-width = <4>;
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&mmc1 {
> > >>>>> +	pinctrl-names = "default";
> > >>>>> +	pinctrl-0 = <&mmc1_pins>;
> > >>>>> +	vmmc-supply = <&reg_aldo1>;
> > >>>>> +	vqmmc-supply = <&reg_dldo4>;
> > >>>>> +	mmc-pwrseq = <&wifi_pwrseq>;
> > >>>>> +	bus-width = <4>;
> > >>>>> +	non-removable;
> > >>>>> +	status = "okay";
> > >>>>> +
> > >>>>> +	rtl8723bs: wifi at 1 {
> > >>>>> +		reg = <1>;
> > >>>>> +		interrupt-parent = <&r_pio>;
> > >>>>> +		interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
> > >>>>> +		interrupt-names = "host-wake";
> > >>>>> +	};
> > >>>>
> > >>>> Node without compatible doesn't help. Please remove it.
> > >>
> > >> Huh, but where do I put the the IRQ line then? And every other RTL8723BS
> > >> user seems to do the same?
> > > 
> > > It's good, sorry for the noise.
> > 
> > Just for the records, and for my own reference:
> > Since there is no "ranges" property in the MMC node, the Linux platform 
> > bus driver is not automatically traversing any child nodes. So we don't 
> > need a compatible string. Instead it's a new addressing scheme (this 
> > obsolete MMC "bus" address, like SPI or I2C), so it's up to the driver 
> > to do the child iteration. And it will match device #1 to reg <1>, and 
> > use that node, as Chen-Yu mentioned.
> > 
> > >>>>
> > >>>>> +};
> > >>>>> +
> > >>>>> +&mmc2 {
> > >>>>> +	pinctrl-names = "default";
> > >>>>> +	pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
> > >>>>> +	vmmc-supply = <&reg_dcdc1>;
> > >>>>> +	vqmmc-supply = <&reg_eldo1>;
> > >>>>> +	bus-width = <8>;
> > >>>>> +	non-removable;
> > >>>>> +	mmc-ddr-1_8v;
> > >>>>> +	mmc-hs200-1_8v;
> > >>>>
> > >>>> Aren't these speed modes enabled by default?
> > >>
> > >> Enabled by who? Our current sunxi-mmc driver? I cannot find anything in
> > >> the binding that suggests that there would be some default settings.
> > > 
> > > Looking at Linux sunxi mmc driver, mmc-ddr-1_8v is enabled by default for
> > > "new timings" variants except for H5. Anyway...
> > 
> > But this is a Linux implementation detail, which we should not rely on 
> > in a DT? And if I remember Maxime correctly back then, the plan was to 
> > avoid those driver hacks and just say what we support in the DT, going 
> > forward. This might be needed for other OSes, which might not support 
> > HS-200?
> > >>> Sorry, mmc-hs200-1_8v is ok, but mmc-ddr-1_8v should be
> > >>> removed.
> > >>
> > >> Mmh, I am confused: I thought after the H5 eMMC mishap we figured that
> > >> all speed modes supported by the eMMC chip should be listed in the DT?
> > > 
> > > I think H5 just has (had?) driver issue. From what I can see, only highest
> > > supported mode by kernel and chip is specified in all Allwinner DTs.
> > > mmc-ddr-1_8v is only specified by two recent board addition, where I missed
> > > it while reviewing.
> > > 
> > >> So any driver wouldn't need to make assumptions, and if a particular
> > >> mode shows problems on a board, we just remove that mode from the DT.
> > >> Actually, thinking about that, I guess I should list HS-400 as well? The
> > >> BSP kernel uses that mode.
> > > 
> > > Sure, but it also calibrates timing for it. If you'll specify HS400, kernel
> > > will try to use it, but it won't work.
> > 
> > But this is also a limitation of the current Linux kernel driver. And 
> > since we indeed don't support HS-400, we explicitly remove it from the 
> > capability list, *after* the call to mmc_of_parse():
> > 
> > drivers/mmc/host/sunxi-mmc.c:1460
> >          /* TODO: This driver doesn't support HS400 mode yet */
> >          mmc->caps2 &= ~MMC_CAP2_HS400;
> > 
> > So I think this should be safe?
> 
> Right. Can you test it?
> 
> Best regards,
> Jernej
> 
> > 
> > Cheers,
> > Andre
> > 
> > > 
> > >> Or do you mean to say that in particular DDR (@1.8V) is problematic? I
> > >> cannot test at the moment, but could try later to force that mode.
> > > 
> > > No, no need.

If we go in new direction, then it would be good to test it.

Best regards,
Jernej

> > > 
> > > Best regards,
> > > Jernej
> > > 
> > >>
> > >> Cheers,
> > >> Andre
> > >>
> > >>
> > >>>>> +	cap-mmc-hw-reset;
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&ohci0 {
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&ohci1 {
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&pio {
> > >>>>> +	vcc-pb-supply = <&reg_dcdc1>;
> > >>>>> +	vcc-pc-supply = <&reg_dcdc1>;
> > >>>>> +	vcc-pd-supply = <&reg_dcdc1>;
> > >>>>> +	vcc-pe-supply = <&reg_dcdc1>;
> > >>>>> +	vcc-pf-supply = <&reg_dcdc1>;
> > >>>>> +	vcc-pg-supply = <&reg_dldo4>;
> > >>>>> +	vcc-ph-supply = <&reg_dcdc1>;
> > >>>>> +};
> > >>>>> +
> > >>>>> +&r_ir {
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&r_pio {
> > >>>>> +	/*
> > >>>>> +	 * We cannot add that supply for now since it would create a circular
> > >>>>> +	 * dependency between pinctrl, the regulator and the RSB Bus.
> > >>>>> +	 *
> > >>>>> +	 * vcc-pl-supply = <&reg_aldo2>;
> > >>>>> +	 */
> > >>>>> +};
> > >>>>> +
> > >>>>> +&r_rsb {
> > >>>>> +	status = "okay";
> > >>>>> +
> > >>>>> +	axp803: pmic at 3a3 {
> > >>>>> +		compatible = "x-powers,axp803";
> > >>>>> +		reg = <0x3a3>;
> > >>>>> +		interrupt-parent = <&r_intc>;
> > >>>>> +		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
> > >>>>> +		x-powers,drive-vbus-en;
> > >>>>> +
> > >>>>> +		vin1-supply = <&reg_vcc5v>;
> > >>>>> +		vin2-supply = <&reg_vcc5v>;
> > >>>>> +		vin3-supply = <&reg_vcc5v>;
> > >>>>> +		vin5-supply = <&reg_vcc5v>;
> > >>>>> +		vin6-supply = <&reg_vcc5v>;
> > >>>>> +		aldoin-supply = <&reg_vcc5v>;
> > >>>>> +		dldoin-supply = <&reg_vcc5v>;
> > >>>>> +		eldoin-supply = <&reg_vcc5v>;
> > >>>>> +		fldoin-supply = <&reg_vcc5v>;
> > >>>>> +		drivevbus-supply = <&reg_vcc5v>;
> > >>>>> +		ips-supply = <&reg_vcc5v>;
> > >>>>> +
> > >>>>> +		status = "okay";
> > >>>>> +	};
> > >>>>> +};
> > >>>>> +
> > >>>>> +#include "axp803.dtsi"
> > >>>>> +
> > >>>>> +&ac_power_supply {
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&reg_dcdc1 {
> > >>>>> +	regulator-always-on;
> > >>>>> +	regulator-min-microvolt = <3300000>;
> > >>>>> +	regulator-max-microvolt = <3300000>;
> > >>>>> +	regulator-name = "vcc-3v3";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&reg_dcdc2 {
> > >>>>> +	regulator-always-on;
> > >>>>> +	regulator-min-microvolt = <1040000>;
> > >>>>> +	regulator-max-microvolt = <1300000>;
> > >>>>> +	regulator-name = "vdd-cpux";
> > >>>>> +};
> > >>>>> +
> > >>>>> +/* DCDC3 is polyphased with DCDC2 */
> > >>>>> +
> > >>>>> +&reg_dcdc5 {
> > >>>>> +	regulator-always-on;
> > >>>>> +	regulator-min-microvolt = <1500000>;
> > >>>>> +	regulator-max-microvolt = <1500000>;
> > >>>>> +	regulator-name = "vcc-dram";
> > >>>>> +};
> > >>>>> +
> > >>>>> +/* Deviates from the reset default of 1.1V. */
> > >>>>> +&reg_dcdc6 {
> > >>>>> +	regulator-always-on;
> > >>>>> +	regulator-min-microvolt = <1200000>;
> > >>>>> +	regulator-max-microvolt = <1200000>;
> > >>>>> +	regulator-name = "vdd-sys";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&reg_aldo1 {
> > >>>>> +	regulator-min-microvolt = <3300000>;
> > >>>>> +	regulator-max-microvolt = <3300000>;
> > >>>>> +	regulator-name = "vcc-wifi";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&reg_aldo2 {
> > >>>>> +	/* Specifying R_PIO consumer would create circular dependency. */
> > >>>>> +	regulator-always-on;
> > >>>>> +	regulator-min-microvolt = <3300000>;
> > >>>>> +	regulator-max-microvolt = <3300000>;
> > >>>>> +	regulator-name = "vcc-pl";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&reg_aldo3 {
> > >>>>> +	regulator-always-on;
> > >>>>> +	regulator-min-microvolt = <3000000>;
> > >>>>> +	regulator-max-microvolt = <3000000>;
> > >>>>> +	regulator-name = "vcc-pll-avcc";
> > >>>>> +};
> > >>>>> +
> > >>>>> +/* AC200 power supply */
> > >>>>> +&reg_dldo1 {
> > >>>>> +	regulator-always-on;
> > >>>>> +	regulator-min-microvolt = <3300000>;
> > >>>>> +	regulator-max-microvolt = <3300000>;
> > >>>>> +	regulator-name = "vcc-ave-33";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&reg_dldo4 {
> > >>>>> +	regulator-min-microvolt = <3300000>;
> > >>>>> +	regulator-max-microvolt = <3300000>;
> > >>>>> +	regulator-name = "vcc-wifi-io";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&reg_drivevbus {
> > >>>>> +	regulator-name = "usb0-vbus";
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&reg_eldo1 {
> > >>>>> +	regulator-always-on;
> > >>>>> +	regulator-min-microvolt = <1800000>;
> > >>>>> +	regulator-max-microvolt = <1800000>;
> > >>>>> +	regulator-name = "vcc-cpvdd-dram-emmc";
> > >>>>> +};
> > >>>>> +
> > >>>>> +/* Supplies the arisc management core, needed by TF-A to power off cores. */
> > >>>>> +&reg_fldo2 {
> > >>>>> +	regulator-always-on;
> > >>>>> +	regulator-min-microvolt = <1100000>;
> > >>>>> +	regulator-max-microvolt = <1100000>;
> > >>>>> +	regulator-name = "vdd-cpus";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&reg_rtc_ldo {
> > >>>>> +	regulator-name = "vcc-rtc";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&simplefb_hdmi {
> > >>>>> +	vcc-hdmi-supply = <&reg_dcdc1>;
> > >>>>> +};
> > >>>>> +
> > >>>>> +&sound {
> > >>>>> +	simple-audio-card,aux-devs = <&codec_analog>;
> > >>>>> +	simple-audio-card,widgets = "Microphone", "Microphone Jack",
> > >>>>> +				    "Headphone", "Headphone Jack";
> > >>>>> +	simple-audio-card,routing =
> > >>>>> +			"Left DAC", "DACL",
> > >>>>> +			"Right DAC", "DACR",
> > >>>>> +			"Headphone Jack", "HP",
> > >>>>> +			"ADCL", "Left ADC",
> > >>>>> +			"ADCR", "Right ADC",
> > >>>>> +			"MIC2", "Microphone Jack";
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +/* On the (unpopulated) UART pads. */
> > >>>>> +&uart0 {
> > >>>>> +	pinctrl-names = "default";
> > >>>>> +	pinctrl-0 = <&uart0_pb_pins>;
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&uart1 {
> > >>>>> +	pinctrl-names = "default";
> > >>>>> +	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
> > >>>>> +	uart-has-rtscts;
> > >>>>> +	status = "okay";
> > >>>>> +
> > >>>>> +	bluetooth {
> > >>>>> +		compatible = "realtek,rtl8723bs-bt";
> > >>>>> +		enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
> > >>>>> +		max-speed = <1500000>;
> > >>>>> +	};
> > >>>>> +};
> > >>>>> +
> > >>>>> +&usb_otg {
> > >>>>> +	dr_mode = "host";
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>> +
> > >>>>> +&usbphy {
> > >>>>> +	usb0_vbus-supply = <&reg_drivevbus>;
> > >>>>> +	usb1_vbus-supply = <&reg_drivevbus>;
> > >>>>> +	status = "okay";
> > >>>>> +};
> > >>>>>
> > >>>>
> > >>>>
> > >>>>
> > >>>>
> > >>>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>
> > > 
> > > 
> > > 
> > > 
> > 
> 
> 
> 
> 
> 






From afd at ti.com  Tue Feb  6 10:29:13 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 6 Feb 2024 12:29:13 -0600
Subject: [PATCH v1] arm64: dts: ti: verdin-am62: mallow: add TPM device
In-Reply-To: <20240126165136.28543-1-francesco@dolcini.it>
References: <20240126165136.28543-1-francesco@dolcini.it>
Message-ID: <65a24f21-4cc6-4843-b838-b1c7020ca45d@ti.com>

On 1/26/24 10:51 AM, Francesco Dolcini wrote:
> From: Francesco Dolcini <francesco.dolcini at toradex.com>
> 
> Add TPM device to Mallow device tree file, the device is connected to
> the SoC with SPI1/CS1, the same SPI interface is also available on an
> extension header together with an additional CS0 signal.
> 
> Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
> ---
>   arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
> index 17b93534f658..77b1beb638ad 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
> @@ -127,6 +127,16 @@ &main_spi1 {
>   		    <&pinctrl_qspi1_cs2_gpio>;
>   	cs-gpios = <0>, <&main_gpio0 12 GPIO_ACTIVE_LOW>;
>   	status = "okay";
> +
> +	tpm at 1 {
> +		compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
> +		reg = <1>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_qspi1_dqs_gpio>;
> +		interrupt-parent = <&main_gpio1>;
> +		interrupts = <18 IRQ_TYPE_EDGE_FALLING>;

Just a heads-up, the SLB9670 datasheet says this device uses
an active low interrupt (IRQ_TYPE_LEVEL_LOW). Using TYPE_EDGE
here can cause missed interrupts if the line stays low for
multiple interrupts.

Andrew

> +		spi-max-frequency = <18500000>;
> +	};
>   };
>   
>   /* Verdin UART_3 */


From francesco at dolcini.it  Tue Feb  6 10:36:53 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Tue, 06 Feb 2024 19:36:53 +0100
Subject: [PATCH v1] arm64: dts: ti: verdin-am62: mallow: add TPM device
In-Reply-To: <65a24f21-4cc6-4843-b838-b1c7020ca45d@ti.com>
References: <20240126165136.28543-1-francesco@dolcini.it> <65a24f21-4cc6-4843-b838-b1c7020ca45d@ti.com>
Message-ID: <26F9C286-606C-40C6-994E-EABDFFCDFDC4@dolcini.it>



Il 6 febbraio 2024 19:29:13 CET, Andrew Davis <afd at ti.com> ha scritto:
>On 1/26/24 10:51 AM, Francesco Dolcini wrote:
>> From: Francesco Dolcini <francesco.dolcini at toradex.com>
>> 
>> Add TPM device to Mallow device tree file, the device is connected to
>> the SoC with SPI1/CS1, the same SPI interface is also available on an
>> extension header together with an additional CS0 signal.
>> 
>> Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
>> ---
>>   arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi | 10 ++++++++++
>>   1 file changed, 10 insertions(+)
>> 
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
>> index 17b93534f658..77b1beb638ad 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
>> @@ -127,6 +127,16 @@ &main_spi1 {
>>   		    <&pinctrl_qspi1_cs2_gpio>;
>>   	cs-gpios = <0>, <&main_gpio0 12 GPIO_ACTIVE_LOW>;
>>   	status = "okay";
>> +
>> +	tpm at 1 {
>> +		compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
>> +		reg = <1>;
>> +		pinctrl-names = "default";
>> +		pinctrl-0 = <&pinctrl_qspi1_dqs_gpio>;
>> +		interrupt-parent = <&main_gpio1>;
>> +		interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
>
>Just a heads-up, the SLB9670 datasheet says this device uses
>an active low interrupt (IRQ_TYPE_LEVEL_LOW). Using TYPE_EDGE
>here can cause missed interrupts if the line stays low for
>multiple interrupts.


The driver interrupt handler would need to take care of it, if needed.

The SOC does not support level interrupt, so there is no other solution, am I wrong?
 
Francesco



From robh at kernel.org  Tue Feb  6 10:43:05 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 6 Feb 2024 18:43:05 +0000
Subject: [PATCH 2/4] dt-bindings: hwinfo: ti,k3-socinfo: Add nvmem-cells
In-Reply-To: <20240206143711.2410135-3-msp@baylibre.com>
References: <20240206143711.2410135-1-msp@baylibre.com>
 <20240206143711.2410135-3-msp@baylibre.com>
Message-ID: <20240206184305.GA1875492-robh@kernel.org>

On Tue, Feb 06, 2024 at 03:37:09PM +0100, Markus Schneider-Pargmann wrote:
> The information k3-socinfo requires is stored in an efuse area. This
> area is required by other devices/drivers as well, so using nvmem-cells
> can be a cleaner way to describe which information are used.
> 
> If nvmem-cells are supplied, the address range is not required.
> Cells chipvariant, chippartno and chipmanufacturer are introduced to
> cover all required information.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> Reviewed-by: Andrew Davis <afd at ti.com>
> ---
>  .../bindings/hwinfo/ti,k3-socinfo.yaml        | 23 ++++++++++++++++++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
> index dada28b47ea0..f085b7275b7d 100644
> --- a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
> +++ b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
> @@ -26,9 +26,24 @@ properties:
>    reg:
>      maxItems: 1
>  
> +  nvmem-cells:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +
> +  nvmem-cell-names:
> +    items:
> +      - const: chipvariant
> +      - const: chippartno
> +      - const: chipmanufacturer
> +
>  required:
>    - compatible
> -  - reg
> +
> +oneOf:
> +  - required:
> +      - reg
> +  - required:
> +      - nvmem-cells
> +      - nvmem-cell-names
>  
>  additionalProperties: false
>  
> @@ -38,3 +53,9 @@ examples:
>          compatible = "ti,am654-chipid";
>          reg = <0x43000014 0x4>;
>      };
> +  - |
> +    chipid: chipid at 14 {
> +        compatible = "ti,am654-chipid";

This isn't compatible if you have a completely different way to access 
it. 


> +        nvmem-cells = <&chip_variant>, <&chip_partno>, <&chip_manufacturer>;
> +        nvmem-cell-names = "chipvariant", "chippartno", "chipmanufacturer";
> +    };
> -- 
> 2.43.0
> 


From semen.protsenko at linaro.org  Tue Feb  6 10:44:13 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 6 Feb 2024 12:44:13 -0600
Subject: [PATCH 3/4] spi: s3c64xx: add s3c64xx_iowrite{8,16}_32_rep accessors
In-Reply-To: <20240206085238.1208256-4-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org> <20240206085238.1208256-4-tudor.ambarus@linaro.org>
Message-ID: <CAPLW+4k+FkuNwsyvWH54gcLz0YFmh8OmvOWt_LdQvELRXMvOTQ@mail.gmail.com>

On Tue, Feb 6, 2024 at 2:52?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> Allow SoCs that require 32 bits register accesses to write data in
> chunks of 8 or 16 bits. One SoC that requires 32 bit register accesses
> is the google gs101. The operation is rare, thus open code it in the
> driver rather than making it generic (through asm-generic/io.h)
>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  drivers/spi/spi-s3c64xx.c | 70 +++++++++++++++++++++++++++++++--------
>  1 file changed, 56 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index c15ca6a910dc..cb45ad615f3d 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -142,6 +142,7 @@ struct s3c64xx_spi_dma_data {
>   *     prescaler unit.
>   * @clk_ioclk: True if clock is present on this device
>   * @has_loopback: True if loopback mode can be supported
> + * @use_32bit_io: True if the SoC allows just 32-bit register accesses.

A matter of taste, but: just -> only.

>   *
>   * The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
>   * differ in some aspects such as the size of the fifo and spi bus clock
> @@ -158,6 +159,7 @@ struct s3c64xx_spi_port_config {
>         bool    clk_from_cmu;
>         bool    clk_ioclk;
>         bool    has_loopback;
> +       bool    use_32bit_io;
>  };
>
>  /**
> @@ -412,6 +414,59 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
>         return false;
>  }
>
> +static void s3c64xx_iowrite8_32_rep(volatile void __iomem *addr,
> +                                   const void *buffer, unsigned int count)
> +{
> +       if (count) {
> +               const u8 *buf = buffer;
> +
> +               do {
> +                       __raw_writel(*buf++, addr);
> +               } while (--count);
> +       }

How about:

    while (count--)
        __raw_writel(*buf++, addr);

This way "if" condition is not needed. The same goes for the function below.

> +}
> +
> +static void s3c64xx_iowrite16_32_rep(volatile void __iomem *addr,
> +                                    const void *buffer, unsigned int count)
> +{
> +       if (count) {
> +               const u16 *buf = buffer;
> +
> +               do {
> +                       __raw_writel(*buf++, addr);
> +               } while (--count);
> +       }
> +}
> +
> +static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd,
> +                               struct spi_transfer *xfer)
> +{
> +       void __iomem *regs = sdd->regs;

Suggest declaring aliases here, like this:

    void __iomem *addr = sdd->regs + S3C64XX_SPI_TX_DATA;
    const void *buf = xfer->tx_buf;
    unsigned int len = xfer->len;

Using those in the code below makes it more compact and easier to read.

> +
> +       switch (sdd->cur_bpw) {
> +       case 32:
> +               iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
> +                             xfer->tx_buf, xfer->len / 4);
> +               break;
> +       case 16:
> +               if (sdd->port_conf->use_32bit_io)
> +                       s3c64xx_iowrite16_32_rep(regs + S3C64XX_SPI_TX_DATA,
> +                                                xfer->tx_buf, xfer->len / 2);
> +               else
> +                       iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
> +                                     xfer->tx_buf, xfer->len / 2);
> +               break;
> +       default:
> +               if (sdd->port_conf->use_32bit_io)
> +                       s3c64xx_iowrite8_32_rep(regs + S3C64XX_SPI_TX_DATA,
> +                                               xfer->tx_buf, xfer->len);
> +               else
> +                       iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
> +                                    xfer->tx_buf, xfer->len);
> +               break;
> +       }
> +}
> +
>  static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>                                     struct spi_transfer *xfer, int dma_mode)
>  {
> @@ -445,20 +500,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>                         modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
>                         ret = s3c64xx_prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
>                 } else {
> -                       switch (sdd->cur_bpw) {
> -                       case 32:
> -                               iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
> -                                       xfer->tx_buf, xfer->len / 4);
> -                               break;
> -                       case 16:
> -                               iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
> -                                       xfer->tx_buf, xfer->len / 2);
> -                               break;
> -                       default:
> -                               iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
> -                                       xfer->tx_buf, xfer->len);
> -                               break;
> -                       }
> +                       s3c64xx_iowrite_rep(sdd, xfer);

This extraction (with no functional change yet) could've been a
preceding separate patch, preparing things for this rework.

>                 }
>         }
>
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From konrad.dybcio at linaro.org  Tue Feb  6 10:45:16 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Tue, 6 Feb 2024 19:45:16 +0100
Subject: [PATCH] arm64: deconfig: enable Goodix Berlin SPI touchscreen
 driver as module
In-Reply-To: <20240203-topic-sm8x50-upstream-goodix-spi-defconfig-v1-1-b69ed85ddd05@linaro.org>
References: <20240203-topic-sm8x50-upstream-goodix-spi-defconfig-v1-1-b69ed85ddd05@linaro.org>
Message-ID: <002d1f81-34f6-4d86-97e9-170c6a66d495@linaro.org>

On 3.02.2024 21:20, Neil Armstrong wrote:
> enable Goodix Berlin SPI driver as module since used on the
> Qualcomm SM8550 QRD and SM8650 QRD platforms.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---

Acked-by: Konrad Dybcio <konrad.dybcio at linaro.org>

Konrad


From laurent.pinchart at ideasonboard.com  Tue Feb  6 10:45:42 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 6 Feb 2024 20:45:42 +0200
Subject: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <20240204061538.2105-3-zhi.mao@mediatek.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
 <20240204061538.2105-3-zhi.mao@mediatek.com>
Message-ID: <20240206184542.GE2827@pendragon.ideasonboard.com>

Hi Zhi,

Thank you for the patch.

On Sun, Feb 04, 2024 at 02:15:38PM +0800, Zhi Mao wrote:
> Add a V4L2 sub-device driver for Galaxycore GC08A3 image sensor.
> 
> Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> ---
>  drivers/media/i2c/Kconfig  |   10 +
>  drivers/media/i2c/Makefile |    1 +
>  drivers/media/i2c/gc08a3.c | 1448 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 1459 insertions(+)
>  create mode 100644 drivers/media/i2c/gc08a3.c
> 
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 56f276b920ab..e4da68835683 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -70,6 +70,16 @@ config VIDEO_GC0308
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called gc0308.
>  
> +config VIDEO_GC08A3
> +	tristate "GalaxyCore gc08a3 sensor support"
> +	select V4L2_CCI_I2C
> +	help
> +	  This is a Video4Linux2 sensor driver for the GalaxyCore gc08a3
> +	  camera.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called gc08a3.
> +
>  config VIDEO_GC2145
>  	select V4L2_CCI_I2C
>  	tristate "GalaxyCore GC2145 sensor support"
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index dfbe6448b549..b82e99ca7578 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
>  obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
>  obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
>  obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
> +obj-$(CONFIG_VIDEO_GC08A3) += gc08a3.o
>  obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
>  obj-$(CONFIG_VIDEO_HI556) += hi556.o
>  obj-$(CONFIG_VIDEO_HI846) += hi846.o
> diff --git a/drivers/media/i2c/gc08a3.c b/drivers/media/i2c/gc08a3.c
> new file mode 100644
> index 000000000000..3fc7fffb815c
> --- /dev/null
> +++ b/drivers/media/i2c/gc08a3.c
> @@ -0,0 +1,1448 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * gc08a3.c - gc08a3 sensor driver
> + *
> + * Copyright 2023 MediaTek
> + *
> + * Zhi Mao <zhi.mao at mediatek.com>
> + */
> +
> +#include <asm/unaligned.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +#include <media/media-entity.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +#include <media/v4l2-cci.h>
> +#include <media/v4l2-event.h>

Please sort the headers alphabetically.

> +
> +#define GC08A3_REG_CHIP_ID CCI_REG16(0x03f0)
> +#define GC08A3_CHIP_ID 0x08a3
> +
> +#define GC08A3_NATIVE_WIDTH 3264
> +#define GC08A3_NATIVE_HEIGHT 2448
> +
> +#define GC08A3_REG_TEST_PATTERN_EN CCI_REG8(0x008c)
> +#define GC08A3_REG_TEST_PATTERN_IDX CCI_REG8(0x008d)
> +#define GC08A3_TEST_PATTERN_EN 0x01
> +
> +#define GC08A3_STRAEMING_REG CCI_REG8(0x0100)

s/STRAEMING/STREAMING/

> +
> +#define GC08A3_DEFAULT_CLK_FREQ 24000000
> +#define GC08A3_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
> +#define GC08A3_DATA_LANES 4

Let's not mix registers and other macros. Please define the register and
register field macros first (sorted by register address in numerical
order), and then all other macros.

> +
> +/* for 1920*1080 */
> +#define GC08A3_LINK_FREQ_207MHZ 207000000ULL
> +/* for 3264*2448 */
> +#define GC08A3_LINK_FREQ_336MHZ 336000000ULL

Use the values directly in the single location where the macros are used
below, and drop the macros.

> +
> +#define GC08A3_RGB_DEPTH 10
> +
> +#define GC08A3_FRAME_LENGTH_REG CCI_REG16(0x0340)
> +#define GC08A3_VTS_30FPS 2548
> +#define GC08A3_VTS_30FPS_MIN 2548
> +#define GC08A3_VTS_60FPS 1276
> +#define GC08A3_VTS_60FPS_MIN 1276

These four macros don't improve readability, you can use the values
directly in the single location where they are used.

> +#define GC08A3_VTS_MAX 0xfff0
> +
> +#define GC08A3_HTS_30FPS 3640
> +#define GC08A3_HTS_60FPS 3640

Same for these two macros.

> +
> +#define GC08A3_EXP_REG CCI_REG16(0x0202)
> +#define GC08A3_EXP_MARGIN 16
> +#define GC08A3_EXP_MIN 4
> +#define GC08A3_EXP_STEP 1
> +
> +#define GC08A3_FLIP_REG CCI_REG8(0x0101)
> +#define GC08A3_FLIP_H_MASK 0x1

BIT(0)

> +#define GC08A3_FLIP_V_MASK 0x2

BIT(1)

> +
> +#define GC08A3_AGAIN_REG CCI_REG16(0x0204)
> +#define GC08A3_AGAIN_MIN 1024
> +#define GC08A3_AGAIN_MAX (1024 * 16)
> +#define GC08A3_AGAIN_STEP 1
> +
> +#define GC08A3_MIN_SLEEP_US  2000
> +#define GC08A3_MAX_SLEEP_US  3000
> +
> +static const char *const gc08a3_test_pattern_menu[] = {
> +	"No Pattern", "Solid Black", "Colour Bar", "Solid White",
> +	"Solid Red", "Solid Green", "Solid Blue", "Solid Yellow",
> +};
> +
> +enum {
> +	GC08A3_LINK_FREQ_336MHZ_INDEX,
> +	GC08A3_LINK_FREQ_207MHZ_INDEX,

The second value is never used, and the first one is used in
gc08a3_init_controls() only. I would drop both, and pass
link_freq_menu_items[0] to the to_pixel_rate() function instead of
passing an index.

> +};
> +
> +static const s64 link_freq_menu_items[] = {

s/link_freq_menu_items/gc08a3_link_freq_menu_items/

> +	GC08A3_LINK_FREQ_336MHZ,
> +	GC08A3_LINK_FREQ_207MHZ,
> +};
> +
> +static const char *const gc08a3_supply_name[] = {
> +	"avdd",
> +	"dvdd",
> +	"dovdd",
> +};
> +
> +struct gc08a3 {
> +	struct device *dev;
> +	struct v4l2_subdev sd;
> +	struct media_pad pad;
> +	struct i2c_client *client;

Not used, you can drop this field.

> +
> +	struct clk *xclk;
> +	struct regulator_bulk_data supplies[ARRAY_SIZE(gc08a3_supply_name)];
> +	struct gpio_desc *reset_gpio;
> +
> +	struct v4l2_ctrl_handler ctrls;
> +	struct v4l2_ctrl *pixel_rate;
> +	struct v4l2_ctrl *link_freq;
> +	struct v4l2_ctrl *exposure;
> +	struct v4l2_ctrl *vblank;
> +	struct v4l2_ctrl *hblank;
> +
> +	struct regmap *regmap;
> +
> +	bool streaming;

Set but never used, you can drop this field.

> +	unsigned long link_freq_bitmap;
> +
> +	/* Current mode */
> +	const struct gc08a3_mode *cur_mode;
> +};
> +
> +struct gc08a3_reg_list {
> +	u32 num_of_regs;
> +	const struct cci_reg_sequence *regs;
> +};
> +
> +struct gc08a3_link_freq_config {
> +	const struct gc08a3_reg_list reg_list;
> +};
> +
> +static const struct cci_reg_sequence mode_3264x2448[] = {
> +	/* system */
> +	{ CCI_REG8(0x0336), 0x70 },
> +	{ CCI_REG8(0x0383), 0xbb },
> +	{ CCI_REG8(0x0344), 0x00 },
> +	{ CCI_REG8(0x0345), 0x06 },
> +	{ CCI_REG8(0x0346), 0x00 },
> +	{ CCI_REG8(0x0347), 0x04 },
> +	{ CCI_REG8(0x0348), 0x0c },
> +	{ CCI_REG8(0x0349), 0xd0 },
> +	{ CCI_REG8(0x034a), 0x09 },
> +	{ CCI_REG8(0x034b), 0x9c },
> +	{ CCI_REG8(0x0202), 0x09 },
> +	{ CCI_REG8(0x0203), 0x04 },
> +	{ CCI_REG8(0x0340), 0x09 },
> +	{ CCI_REG8(0x0341), 0xf4 },
> +	{ CCI_REG8(0x0342), 0x07 },
> +	{ CCI_REG8(0x0343), 0x1c },
> +
> +	{ CCI_REG8(0x0226), 0x00 },
> +	{ CCI_REG8(0x0227), 0x28 },
> +	{ CCI_REG8(0x0e38), 0x49 },
> +	{ CCI_REG8(0x0210), 0x13 },
> +	{ CCI_REG8(0x0218), 0x00 },
> +	{ CCI_REG8(0x0241), 0x88 },
> +	{ CCI_REG8(0x0392), 0x60 },
> +
> +	/* ISP */
> +	{ CCI_REG8(0x00a2), 0x00 },
> +	{ CCI_REG8(0x00a3), 0x00 },
> +	{ CCI_REG8(0x00ab), 0x00 },
> +	{ CCI_REG8(0x00ac), 0x00 },
> +
> +	/* GAIN */
> +	{ CCI_REG8(0x0204), 0x04 },
> +	{ CCI_REG8(0x0205), 0x00 },
> +	{ CCI_REG8(0x0050), 0x5c },
> +	{ CCI_REG8(0x0051), 0x44 },
> +
> +	/* out window */
> +	{ CCI_REG8(0x009a), 0x66 },
> +	{ CCI_REG8(0x0351), 0x00 },
> +	{ CCI_REG8(0x0352), 0x06 },
> +	{ CCI_REG8(0x0353), 0x00 },
> +	{ CCI_REG8(0x0354), 0x08 },
> +	{ CCI_REG8(0x034c), 0x0c },
> +	{ CCI_REG8(0x034d), 0xc0 },
> +	{ CCI_REG8(0x034e), 0x09 },
> +	{ CCI_REG8(0x034f), 0x90 },
> +
> +	/* MIPI */
> +	{ CCI_REG8(0x0114), 0x03 },
> +	{ CCI_REG8(0x0180), 0x65 },
> +	{ CCI_REG8(0x0181), 0xf0 },
> +	{ CCI_REG8(0x0185), 0x01 },
> +	{ CCI_REG8(0x0115), 0x30 },
> +	{ CCI_REG8(0x011b), 0x12 },
> +	{ CCI_REG8(0x011c), 0x12 },
> +	{ CCI_REG8(0x0121), 0x06 },
> +	{ CCI_REG8(0x0122), 0x06 },
> +	{ CCI_REG8(0x0123), 0x15 },
> +	{ CCI_REG8(0x0124), 0x01 },
> +	{ CCI_REG8(0x0125), 0x0b },
> +	{ CCI_REG8(0x0126), 0x08 },
> +	{ CCI_REG8(0x0129), 0x06 },
> +	{ CCI_REG8(0x012a), 0x08 },
> +	{ CCI_REG8(0x012b), 0x08 },
> +
> +	{ CCI_REG8(0x0a73), 0x60 },
> +	{ CCI_REG8(0x0a70), 0x11 },
> +	{ CCI_REG8(0x0313), 0x80 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },

Does this register really need to be written 8 times ? Same below.

> +	{ CCI_REG8(0x0a70), 0x00 },
> +	{ CCI_REG8(0x00a4), 0x80 },
> +	{ CCI_REG8(0x0316), 0x01 },
> +	{ CCI_REG8(0x0a67), 0x00 },
> +	{ CCI_REG8(0x0084), 0x10 },
> +	{ CCI_REG8(0x0102), 0x09 },
> +};
> +
> +static const struct cci_reg_sequence mode_1920x1080[] = {
> +	/* system */
> +	{ CCI_REG8(0x0336), 0x45 },
> +	{ CCI_REG8(0x0383), 0x8b },
> +	{ CCI_REG8(0x0344), 0x02 },
> +	{ CCI_REG8(0x0345), 0xa6 },
> +	{ CCI_REG8(0x0346), 0x02 },
> +	{ CCI_REG8(0x0347), 0xb0 },
> +	{ CCI_REG8(0x0348), 0x07 },
> +	{ CCI_REG8(0x0349), 0x90 },
> +	{ CCI_REG8(0x034a), 0x04 },
> +	{ CCI_REG8(0x034b), 0x44 },
> +	{ CCI_REG8(0x0202), 0x03 },
> +	{ CCI_REG8(0x0203), 0x00 },
> +	{ CCI_REG8(0x0340), 0x04 },
> +	{ CCI_REG8(0x0341), 0xfc },
> +	{ CCI_REG8(0x0342), 0x07 },
> +	{ CCI_REG8(0x0343), 0x1c },
> +	{ CCI_REG8(0x0226), 0x00 },
> +	{ CCI_REG8(0x0227), 0x88 },
> +	{ CCI_REG8(0x0e38), 0x49 },
> +	{ CCI_REG8(0x0210), 0x13 },
> +	{ CCI_REG8(0x0218), 0x00 },
> +	{ CCI_REG8(0x0241), 0x88 },
> +	{ CCI_REG8(0x0392), 0x60 },
> +
> +	/* ISP */
> +	{ CCI_REG8(0x00a2), 0xac },
> +	{ CCI_REG8(0x00a3), 0x02 },
> +	{ CCI_REG8(0x00ab), 0xa0 },
> +	{ CCI_REG8(0x00ac), 0x02 },
> +
> +	/* GAIN */
> +	{ CCI_REG8(0x0204), 0x04 },
> +	{ CCI_REG8(0x0205), 0x00 },
> +	{ CCI_REG8(0x0050), 0x38 },
> +	{ CCI_REG8(0x0051), 0x20 },
> +
> +	/* out window */
> +	{ CCI_REG8(0x009a), 0x66 },
> +	{ CCI_REG8(0x0351), 0x00 },
> +	{ CCI_REG8(0x0352), 0x06 },
> +	{ CCI_REG8(0x0353), 0x00 },
> +	{ CCI_REG8(0x0354), 0x08 },
> +	{ CCI_REG8(0x034c), 0x07 },
> +	{ CCI_REG8(0x034d), 0x80 },
> +	{ CCI_REG8(0x034e), 0x04 },
> +	{ CCI_REG8(0x034f), 0x38 },
> +
> +	/* MIPI */
> +	{ CCI_REG8(0x0114), 0x03 },
> +	{ CCI_REG8(0x0180), 0x65 },
> +	{ CCI_REG8(0x0181), 0xf0 },
> +	{ CCI_REG8(0x0185), 0x01 },
> +	{ CCI_REG8(0x0115), 0x30 },
> +	{ CCI_REG8(0x011b), 0x12 },
> +	{ CCI_REG8(0x011c), 0x12 },
> +	{ CCI_REG8(0x0121), 0x02 },
> +	{ CCI_REG8(0x0122), 0x03 },
> +	{ CCI_REG8(0x0123), 0x0c },
> +	{ CCI_REG8(0x0124), 0x00 },
> +	{ CCI_REG8(0x0125), 0x09 },
> +	{ CCI_REG8(0x0126), 0x06 },
> +	{ CCI_REG8(0x0129), 0x04 },
> +	{ CCI_REG8(0x012a), 0x03 },
> +	{ CCI_REG8(0x012b), 0x06 },
> +
> +	{ CCI_REG8(0x0a73), 0x60 },
> +	{ CCI_REG8(0x0a70), 0x11 },
> +	{ CCI_REG8(0x0313), 0x80 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0aff), 0x00 },
> +	{ CCI_REG8(0x0a70), 0x00 },
> +	{ CCI_REG8(0x00a4), 0x80 },
> +	{ CCI_REG8(0x0316), 0x01 },
> +	{ CCI_REG8(0x0a67), 0x00 },
> +	{ CCI_REG8(0x0084), 0x10 },
> +	{ CCI_REG8(0x0102), 0x09 },
> +};
> +
> +static const struct cci_reg_sequence mode_table_common[] = {
> +	{ GC08A3_STRAEMING_REG, 0x00 },
> +	/* system */
> +	{ CCI_REG8(0x031c), 0x60 },
> +	{ CCI_REG8(0x0337), 0x04 },
> +	{ CCI_REG8(0x0335), 0x51 },
> +	{ CCI_REG8(0x0336), 0x70 },
> +	{ CCI_REG8(0x0383), 0xbb },
> +	{ CCI_REG8(0x031a), 0x00 },
> +	{ CCI_REG8(0x0321), 0x10 },
> +	{ CCI_REG8(0x0327), 0x03 },
> +	{ CCI_REG8(0x0325), 0x40 },
> +	{ CCI_REG8(0x0326), 0x23 },
> +	{ CCI_REG8(0x0314), 0x11 },
> +	{ CCI_REG8(0x0315), 0xd6 },
> +	{ CCI_REG8(0x0316), 0x01 },
> +	{ CCI_REG8(0x0334), 0x40 },
> +	{ CCI_REG8(0x0324), 0x42 },
> +	{ CCI_REG8(0x031c), 0x00 },
> +	{ CCI_REG8(0x031c), 0x9f },
> +	{ CCI_REG8(0x039a), 0x13 },
> +	{ CCI_REG8(0x0084), 0x30 },
> +	{ CCI_REG8(0x02b3), 0x08 },
> +	{ CCI_REG8(0x0057), 0x0c },
> +	{ CCI_REG8(0x05c3), 0x50 },
> +	{ CCI_REG8(0x0311), 0x90 },
> +	{ CCI_REG8(0x05a0), 0x02 },
> +	{ CCI_REG8(0x0074), 0x0a },
> +	{ CCI_REG8(0x0059), 0x11 },
> +	{ CCI_REG8(0x0070), 0x05 },
> +	{ CCI_REG8(0x0101), 0x00 },
> +
> +	/* analog */
> +	{ CCI_REG8(0x0344), 0x00 },
> +	{ CCI_REG8(0x0345), 0x06 },
> +	{ CCI_REG8(0x0346), 0x00 },
> +	{ CCI_REG8(0x0347), 0x04 },
> +	{ CCI_REG8(0x0348), 0x0c },
> +	{ CCI_REG8(0x0349), 0xd0 },
> +	{ CCI_REG8(0x034a), 0x09 },
> +	{ CCI_REG8(0x034b), 0x9c },
> +	{ CCI_REG8(0x0202), 0x09 },
> +	{ CCI_REG8(0x0203), 0x04 },
> +
> +	{ CCI_REG8(0x0219), 0x05 },
> +	{ CCI_REG8(0x0226), 0x00 },
> +	{ CCI_REG8(0x0227), 0x28 },
> +	{ CCI_REG8(0x0e0a), 0x00 },
> +	{ CCI_REG8(0x0e0b), 0x00 },
> +	{ CCI_REG8(0x0e24), 0x04 },
> +	{ CCI_REG8(0x0e25), 0x04 },
> +	{ CCI_REG8(0x0e26), 0x00 },
> +	{ CCI_REG8(0x0e27), 0x10 },
> +	{ CCI_REG8(0x0e01), 0x74 },
> +	{ CCI_REG8(0x0e03), 0x47 },
> +	{ CCI_REG8(0x0e04), 0x33 },
> +	{ CCI_REG8(0x0e05), 0x44 },
> +	{ CCI_REG8(0x0e06), 0x44 },
> +	{ CCI_REG8(0x0e0c), 0x1e },
> +	{ CCI_REG8(0x0e17), 0x3a },
> +	{ CCI_REG8(0x0e18), 0x3c },
> +	{ CCI_REG8(0x0e19), 0x40 },
> +	{ CCI_REG8(0x0e1a), 0x42 },
> +	{ CCI_REG8(0x0e28), 0x21 },
> +	{ CCI_REG8(0x0e2b), 0x68 },
> +	{ CCI_REG8(0x0e2c), 0x0d },
> +	{ CCI_REG8(0x0e2d), 0x08 },
> +	{ CCI_REG8(0x0e34), 0xf4 },
> +	{ CCI_REG8(0x0e35), 0x44 },
> +	{ CCI_REG8(0x0e36), 0x07 },
> +	{ CCI_REG8(0x0e38), 0x49 },
> +	{ CCI_REG8(0x0210), 0x13 },
> +	{ CCI_REG8(0x0218), 0x00 },
> +	{ CCI_REG8(0x0241), 0x88 },
> +	{ CCI_REG8(0x0e32), 0x00 },
> +	{ CCI_REG8(0x0e33), 0x18 },
> +	{ CCI_REG8(0x0e42), 0x03 },
> +	{ CCI_REG8(0x0e43), 0x80 },
> +	{ CCI_REG8(0x0e44), 0x04 },
> +	{ CCI_REG8(0x0e45), 0x00 },
> +	{ CCI_REG8(0x0e4f), 0x04 },
> +	{ CCI_REG8(0x057a), 0x20 },
> +	{ CCI_REG8(0x0381), 0x7c },
> +	{ CCI_REG8(0x0382), 0x9b },
> +	{ CCI_REG8(0x0384), 0xfb },
> +	{ CCI_REG8(0x0389), 0x38 },
> +	{ CCI_REG8(0x038a), 0x03 },
> +	{ CCI_REG8(0x0390), 0x6a },
> +	{ CCI_REG8(0x0391), 0x0b },
> +	{ CCI_REG8(0x0392), 0x60 },
> +	{ CCI_REG8(0x0393), 0xc1 },
> +	{ CCI_REG8(0x0396), 0xff },
> +	{ CCI_REG8(0x0398), 0x62 },
> +
> +	/* cisctl reset */
> +	{ CCI_REG8(0x031c), 0x80 },
> +	{ CCI_REG8(0x03fe), 0x10 },
> +	{ CCI_REG8(0x03fe), 0x00 },
> +	{ CCI_REG8(0x031c), 0x9f },
> +	{ CCI_REG8(0x03fe), 0x00 },
> +	{ CCI_REG8(0x03fe), 0x00 },
> +	{ CCI_REG8(0x03fe), 0x00 },
> +	{ CCI_REG8(0x03fe), 0x00 },
> +	{ CCI_REG8(0x031c), 0x80 },
> +	{ CCI_REG8(0x03fe), 0x10 },
> +	{ CCI_REG8(0x03fe), 0x00 },
> +	{ CCI_REG8(0x031c), 0x9f },
> +	{ CCI_REG8(0x0360), 0x01 },
> +	{ CCI_REG8(0x0360), 0x00 },
> +	{ CCI_REG8(0x0316), 0x09 },
> +	{ CCI_REG8(0x0a67), 0x80 },
> +	{ CCI_REG8(0x0313), 0x00 },
> +	{ CCI_REG8(0x0a53), 0x0e },
> +	{ CCI_REG8(0x0a65), 0x17 },
> +	{ CCI_REG8(0x0a68), 0xa1 },
> +	{ CCI_REG8(0x0a58), 0x00 },
> +	{ CCI_REG8(0x0ace), 0x0c },
> +	{ CCI_REG8(0x00a4), 0x00 },
> +	{ CCI_REG8(0x00a5), 0x01 },
> +	{ CCI_REG8(0x00a7), 0x09 },
> +	{ CCI_REG8(0x00a8), 0x9c },
> +	{ CCI_REG8(0x00a9), 0x0c },
> +	{ CCI_REG8(0x00aa), 0xd0 },
> +	{ CCI_REG8(0x0a8a), 0x00 },
> +	{ CCI_REG8(0x0a8b), 0xe0 },
> +	{ CCI_REG8(0x0a8c), 0x13 },
> +	{ CCI_REG8(0x0a8d), 0xe8 },
> +	{ CCI_REG8(0x0a90), 0x0a },
> +	{ CCI_REG8(0x0a91), 0x10 },
> +	{ CCI_REG8(0x0a92), 0xf8 },
> +	{ CCI_REG8(0x0a71), 0xf2 },
> +	{ CCI_REG8(0x0a72), 0x12 },
> +	{ CCI_REG8(0x0a73), 0x64 },
> +	{ CCI_REG8(0x0a75), 0x41 },
> +	{ CCI_REG8(0x0a70), 0x07 },
> +	{ CCI_REG8(0x0313), 0x80 },
> +
> +	/* ISP */
> +	{ CCI_REG8(0x00a0), 0x01 },
> +	{ CCI_REG8(0x0080), 0xd2 },
> +	{ CCI_REG8(0x0081), 0x3f },
> +	{ CCI_REG8(0x0087), 0x51 },
> +	{ CCI_REG8(0x0089), 0x03 },
> +	{ CCI_REG8(0x009b), 0x40 },
> +	{ CCI_REG8(0x05a0), 0x82 },
> +	{ CCI_REG8(0x05ac), 0x00 },
> +	{ CCI_REG8(0x05ad), 0x01 },
> +	{ CCI_REG8(0x05ae), 0x00 },
> +	{ CCI_REG8(0x0800), 0x0a },
> +	{ CCI_REG8(0x0801), 0x14 },
> +	{ CCI_REG8(0x0802), 0x28 },
> +	{ CCI_REG8(0x0803), 0x34 },
> +	{ CCI_REG8(0x0804), 0x0e },
> +	{ CCI_REG8(0x0805), 0x33 },
> +	{ CCI_REG8(0x0806), 0x03 },
> +	{ CCI_REG8(0x0807), 0x8a },
> +	{ CCI_REG8(0x0808), 0x50 },
> +	{ CCI_REG8(0x0809), 0x00 },
> +	{ CCI_REG8(0x080a), 0x34 },
> +	{ CCI_REG8(0x080b), 0x03 },
> +	{ CCI_REG8(0x080c), 0x26 },
> +	{ CCI_REG8(0x080d), 0x03 },
> +	{ CCI_REG8(0x080e), 0x18 },
> +	{ CCI_REG8(0x080f), 0x03 },
> +	{ CCI_REG8(0x0810), 0x10 },
> +	{ CCI_REG8(0x0811), 0x03 },
> +	{ CCI_REG8(0x0812), 0x00 },
> +	{ CCI_REG8(0x0813), 0x00 },
> +	{ CCI_REG8(0x0814), 0x01 },
> +	{ CCI_REG8(0x0815), 0x00 },
> +	{ CCI_REG8(0x0816), 0x01 },
> +	{ CCI_REG8(0x0817), 0x00 },
> +	{ CCI_REG8(0x0818), 0x00 },
> +	{ CCI_REG8(0x0819), 0x0a },
> +	{ CCI_REG8(0x081a), 0x01 },
> +	{ CCI_REG8(0x081b), 0x6c },
> +	{ CCI_REG8(0x081c), 0x00 },
> +	{ CCI_REG8(0x081d), 0x0b },
> +	{ CCI_REG8(0x081e), 0x02 },
> +	{ CCI_REG8(0x081f), 0x00 },
> +	{ CCI_REG8(0x0820), 0x00 },
> +	{ CCI_REG8(0x0821), 0x0c },
> +	{ CCI_REG8(0x0822), 0x02 },
> +	{ CCI_REG8(0x0823), 0xd9 },
> +	{ CCI_REG8(0x0824), 0x00 },
> +	{ CCI_REG8(0x0825), 0x0d },
> +	{ CCI_REG8(0x0826), 0x03 },
> +	{ CCI_REG8(0x0827), 0xf0 },
> +	{ CCI_REG8(0x0828), 0x00 },
> +	{ CCI_REG8(0x0829), 0x0e },
> +	{ CCI_REG8(0x082a), 0x05 },
> +	{ CCI_REG8(0x082b), 0x94 },
> +	{ CCI_REG8(0x082c), 0x09 },
> +	{ CCI_REG8(0x082d), 0x6e },
> +	{ CCI_REG8(0x082e), 0x07 },
> +	{ CCI_REG8(0x082f), 0xe6 },
> +	{ CCI_REG8(0x0830), 0x10 },
> +	{ CCI_REG8(0x0831), 0x0e },
> +	{ CCI_REG8(0x0832), 0x0b },
> +	{ CCI_REG8(0x0833), 0x2c },
> +	{ CCI_REG8(0x0834), 0x14 },
> +	{ CCI_REG8(0x0835), 0xae },
> +	{ CCI_REG8(0x0836), 0x0f },
> +	{ CCI_REG8(0x0837), 0xc4 },
> +	{ CCI_REG8(0x0838), 0x18 },
> +	{ CCI_REG8(0x0839), 0x0e },
> +	{ CCI_REG8(0x05ac), 0x01 },
> +	{ CCI_REG8(0x059a), 0x00 },
> +	{ CCI_REG8(0x059b), 0x00 },
> +	{ CCI_REG8(0x059c), 0x01 },
> +	{ CCI_REG8(0x0598), 0x00 },
> +	{ CCI_REG8(0x0597), 0x14 },
> +	{ CCI_REG8(0x05ab), 0x09 },
> +	{ CCI_REG8(0x05a4), 0x02 },
> +	{ CCI_REG8(0x05a3), 0x05 },
> +	{ CCI_REG8(0x05a0), 0xc2 },
> +	{ CCI_REG8(0x0207), 0xc4 },
> +
> +	/* GAIN */
> +	{ CCI_REG8(0x0208), 0x01 },
> +	{ CCI_REG8(0x0209), 0x72 },
> +	{ CCI_REG8(0x0204), 0x04 },
> +	{ CCI_REG8(0x0205), 0x00 },
> +
> +	{ CCI_REG8(0x0040), 0x22 },
> +	{ CCI_REG8(0x0041), 0x20 },
> +	{ CCI_REG8(0x0043), 0x10 },
> +	{ CCI_REG8(0x0044), 0x00 },
> +	{ CCI_REG8(0x0046), 0x08 },
> +	{ CCI_REG8(0x0047), 0xf0 },
> +	{ CCI_REG8(0x0048), 0x0f },
> +	{ CCI_REG8(0x004b), 0x0f },
> +	{ CCI_REG8(0x004c), 0x00 },
> +	{ CCI_REG8(0x0050), 0x5c },
> +	{ CCI_REG8(0x0051), 0x44 },
> +	{ CCI_REG8(0x005b), 0x03 },
> +	{ CCI_REG8(0x00c0), 0x00 },
> +	{ CCI_REG8(0x00c1), 0x80 },
> +	{ CCI_REG8(0x00c2), 0x31 },
> +	{ CCI_REG8(0x00c3), 0x00 },
> +	{ CCI_REG8(0x0460), 0x04 },
> +	{ CCI_REG8(0x0462), 0x08 },
> +	{ CCI_REG8(0x0464), 0x0e },
> +	{ CCI_REG8(0x0466), 0x0a },
> +	{ CCI_REG8(0x0468), 0x12 },
> +	{ CCI_REG8(0x046a), 0x12 },
> +	{ CCI_REG8(0x046c), 0x10 },
> +	{ CCI_REG8(0x046e), 0x0c },
> +	{ CCI_REG8(0x0461), 0x03 },
> +	{ CCI_REG8(0x0463), 0x03 },
> +	{ CCI_REG8(0x0465), 0x03 },
> +	{ CCI_REG8(0x0467), 0x03 },
> +	{ CCI_REG8(0x0469), 0x04 },
> +	{ CCI_REG8(0x046b), 0x04 },
> +	{ CCI_REG8(0x046d), 0x04 },
> +	{ CCI_REG8(0x046f), 0x04 },
> +	{ CCI_REG8(0x0470), 0x04 },
> +	{ CCI_REG8(0x0472), 0x10 },
> +	{ CCI_REG8(0x0474), 0x26 },
> +	{ CCI_REG8(0x0476), 0x38 },
> +	{ CCI_REG8(0x0478), 0x20 },
> +	{ CCI_REG8(0x047a), 0x30 },
> +	{ CCI_REG8(0x047c), 0x38 },
> +	{ CCI_REG8(0x047e), 0x60 },
> +	{ CCI_REG8(0x0471), 0x05 },
> +	{ CCI_REG8(0x0473), 0x05 },
> +	{ CCI_REG8(0x0475), 0x05 },
> +	{ CCI_REG8(0x0477), 0x05 },
> +	{ CCI_REG8(0x0479), 0x04 },
> +	{ CCI_REG8(0x047b), 0x04 },
> +	{ CCI_REG8(0x047d), 0x04 },
> +	{ CCI_REG8(0x047f), 0x04 },
> +};
> +
> +static const struct gc08a3_link_freq_config gc08a3_link_freq_336m_configs = {
> +	.reg_list = {
> +		.num_of_regs = ARRAY_SIZE(mode_table_common),
> +		.regs = mode_table_common,
> +	}
> +};
> +
> +static const struct gc08a3_link_freq_config gc08a3_link_freq_207m_configs = {
> +	.reg_list = {
> +		.num_of_regs = ARRAY_SIZE(mode_table_common),
> +		.regs = mode_table_common,
> +	}
> +};

The registers are the same for both, so I think you can simplify this
and drop the gc08a3_link_freq_config structure.

> +
> +struct gc08a3_mode {
> +	u32 width;
> +	u32 height;
> +	const struct gc08a3_reg_list reg_list;
> +
> +	u32 hts; /* Horizontal timining size */
> +	u32 vts_def; /* Default vertical timining size */
> +	u32 vts_min; /* Min vertical timining size */
> +	u32 max_framerate;
> +	const struct gc08a3_link_freq_config *link_freq_configs;
> +};
> +
> +/*
> + * Declare modes in order, from biggest
> + * to smallest height.
> + */
> +static const struct gc08a3_mode gc08a3_modes[] = {
> +	{
> +		.width = GC08A3_NATIVE_WIDTH,
> +		.height = GC08A3_NATIVE_HEIGHT,
> +		.reg_list = {
> +			.num_of_regs = ARRAY_SIZE(mode_3264x2448),
> +			.regs = mode_3264x2448,
> +		},
> +		.link_freq_configs = &gc08a3_link_freq_336m_configs,
> +
> +		.hts = GC08A3_HTS_30FPS,
> +		.vts_def = GC08A3_VTS_30FPS,
> +		.vts_min = GC08A3_VTS_30FPS_MIN,
> +		.max_framerate = 300,
> +	},
> +	{
> +		.width = 1920,
> +		.height = 1080,
> +		.reg_list = {
> +			.num_of_regs = ARRAY_SIZE(mode_1920x1080),
> +			.regs = mode_1920x1080,
> +		},
> +		.link_freq_configs = &gc08a3_link_freq_207m_configs,
> +
> +		.hts = GC08A3_HTS_60FPS,
> +		.vts_def = GC08A3_VTS_60FPS,
> +		.vts_min = GC08A3_VTS_60FPS_MIN,
> +		.max_framerate = 600,
> +	},
> +};
> +
> +static u64 to_pixel_rate(u32 f_index)

Move this function just before gc08a3_init_controls() where it is used,
and rename it with a gc08a3_ prefix.

> +{
> +	u64 pixel_rate = link_freq_menu_items[f_index] * 2 * GC08A3_DATA_LANES;
> +
> +	do_div(pixel_rate, GC08A3_RGB_DEPTH);
> +
> +	return pixel_rate;
> +}
> +
> +static int gc08a3_identify_module(struct gc08a3 *gc08a3)

I would also move this down, before the probe function.

> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
> +	u64 val = 0;

No need to initialize val to 0.

> +	int ret;
> +
> +	ret = cci_read(gc08a3->regmap, GC08A3_REG_CHIP_ID, &val, NULL);
> +	if (ret) {
> +		dev_err(&client->dev,

Use gc08a3->dev and drop the local client variable.

> +			"failed to read chip id: 0x%x", GC08A3_CHIP_ID);

			"failed to read chip id\n");

Printing GC08A3_CHIP_ID isn't useful.

> +		return ret;
> +	}
> +
> +	if (val != GC08A3_CHIP_ID) {
> +		dev_err(&client->dev, "chip id mismatch: 0x%x!=0x%llx",
> +			GC08A3_CHIP_ID, val);
> +		return -ENXIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static inline struct gc08a3 *to_gc08a3(struct v4l2_subdev *sd)
> +{
> +	return container_of(sd, struct gc08a3, sd);
> +}
> +
> +static int gc08a3_power_on(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);

You can use

	struct v4l2_subdev *sd = dev_get_drvdata(dev);

Same below.

> +	struct gc08a3 *gc08a3 = to_gc08a3(sd);
> +	int ret;
> +
> +	ret = regulator_bulk_enable(ARRAY_SIZE(gc08a3_supply_name),
> +				    gc08a3->supplies);
> +	if (ret < 0) {
> +		dev_err(gc08a3->dev, "failed to enable regulators: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(gc08a3->xclk);
> +	if (ret < 0) {
> +		regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
> +				       gc08a3->supplies);
> +		dev_err(gc08a3->dev, "clk prepare enable failed\n");
> +		return ret;
> +	}
> +
> +	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);

fsleep() is a good candidate to replace the usleep_range() calls.

> +
> +	gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);

Are you asserting reset when powering on ? That sounds wrong, you should
de-assert reset here (and acquire the reset gpio in probe() with
GPIOD_OUT_HIGH). Drivers should use logical levels for GPIOs, setting a
GPIO named "reset" to 1 should assert the reset signal, even if the
physical signal is active low. You may have the wrong polarity in the
device tree.

> +	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> +
> +	return 0;
> +}
> +
> +static int gc08a3_power_off(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct gc08a3 *gc08a3 = to_gc08a3(sd);
> +
> +	clk_disable_unprepare(gc08a3->xclk);
> +
> +	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> +
> +	gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);
> +	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> +
> +	regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
> +			       gc08a3->supplies);
> +	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);

Do you need all those sleeps, especially the last one ?

> +
> +	return 0;
> +}
> +
> +static int gc08a3_enum_mbus_code(struct v4l2_subdev *sd,
> +				 struct v4l2_subdev_state *sd_state,
> +				 struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	if (code->index > 0)
> +		return -EINVAL;
> +
> +	code->code = GC08A3_MBUS_CODE;
> +
> +	return 0;
> +}
> +
> +static int gc08a3_enum_frame_size(struct v4l2_subdev *subdev,
> +				  struct v4l2_subdev_state *sd_state,
> +				  struct v4l2_subdev_frame_size_enum *fse)
> +{
> +	if (fse->code != GC08A3_MBUS_CODE)
> +		return -EINVAL;
> +
> +	if (fse->index >= ARRAY_SIZE(gc08a3_modes))
> +		return -EINVAL;
> +
> +	fse->min_width = gc08a3_modes[fse->index].width;
> +	fse->max_width = gc08a3_modes[fse->index].width;
> +	fse->min_height = gc08a3_modes[fse->index].height;
> +	fse->max_height = gc08a3_modes[fse->index].height;
> +
> +	return 0;
> +}
> +
> +static int gc08a3_update_cur_mode_controls(struct gc08a3 *gc08a3,
> +					   const struct gc08a3_mode *mode)
> +{
> +	s64 exposure_max, h_blank;
> +	int ret = 0;
> +
> +	ret = __v4l2_ctrl_modify_range(gc08a3->vblank,
> +				       mode->vts_min - mode->height,
> +				       GC08A3_VTS_MAX - mode->height, 1,
> +				       mode->vts_def - mode->height);
> +	if (ret)
> +		dev_err(gc08a3->dev, "VB ctrl range update failed\n");

		return ret;
	}

Same below.

> +
> +	h_blank = mode->hts - mode->width;
> +	ret = __v4l2_ctrl_modify_range(gc08a3->hblank, h_blank, h_blank, 1,
> +				       h_blank);
> +	if (ret)
> +		dev_err(gc08a3->dev, "HB ctrl range update failed\n");
> +
> +	exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
> +	ret = __v4l2_ctrl_modify_range(gc08a3->exposure, GC08A3_EXP_MIN,
> +				       exposure_max, GC08A3_EXP_STEP,
> +				       exposure_max);
> +	if (ret)
> +		dev_err(gc08a3->dev, "exposure ctrl range update failed\n");
> +
> +	return ret;
> +}
> +
> +static void gc08a3_update_pad_format(struct gc08a3 *gc08a3,
> +				     const struct gc08a3_mode *mode,
> +				     struct v4l2_mbus_framefmt *fmt)
> +{
> +	fmt->width = mode->width;
> +	fmt->height = mode->height;
> +	fmt->code = GC08A3_MBUS_CODE;
> +	fmt->field = V4L2_FIELD_NONE;
> +	fmt->colorspace = V4L2_COLORSPACE_SRGB;

It's a raw sensor, isn't V4L2_COLORSPACE_RAW more appropriate, or does
the sensor really use the sRGB primaries ?

> +	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
> +	fmt->quantization =
> +		V4L2_MAP_QUANTIZATION_DEFAULT(true,
> +					      fmt->colorspace,
> +					      fmt->ycbcr_enc);

I think you can write

	fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;

here, it's more explicit.

> +	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);

Sensors usually produce linear output, V4L2_XFER_FUNC_NONE is likely
what you need here.

> +}
> +
> +static int gc08a3_set_format(struct v4l2_subdev *sd,
> +			     struct v4l2_subdev_state *state,
> +			     struct v4l2_subdev_format *fmt)
> +{
> +	struct gc08a3 *gc08a3 = to_gc08a3(sd);
> +	struct v4l2_mbus_framefmt *mbus_fmt;
> +	struct v4l2_rect *crop;
> +	const struct gc08a3_mode *mode;
> +
> +	mode = v4l2_find_nearest_size(gc08a3_modes, ARRAY_SIZE(gc08a3_modes),
> +				      width, height, fmt->format.width,
> +				      fmt->format.height);
> +
> +	/*update crop info to subdev state*/

Missing spaces after /* and before */. Same below.

> +	crop = v4l2_subdev_state_get_crop(state, 0);
> +	crop->width = mode->width;
> +	crop->height = mode->height;
> +
> +	/*update fmt info to subdev state*/
> +	gc08a3_update_pad_format(gc08a3, mode, &fmt->format);
> +	mbus_fmt = v4l2_subdev_state_get_format(state, 0);
> +	*mbus_fmt = fmt->format;
> +
> +	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
> +		return 0;
> +
> +	gc08a3->cur_mode = mode;
> +	gc08a3_update_cur_mode_controls(gc08a3, mode);
> +
> +	return 0;
> +}
> +
> +static int gc08a3_get_selection(struct v4l2_subdev *sd,
> +				struct v4l2_subdev_state *state,
> +				struct v4l2_subdev_selection *sel)
> +{
> +	struct gc08a3 *gc08a3 = to_gc08a3(sd);
> +
> +	switch (sel->target) {
> +	case V4L2_SEL_TGT_CROP:
> +		sel->r = *v4l2_subdev_state_get_crop(state, 0);
> +		break;
> +	case V4L2_SEL_TGT_CROP_BOUNDS:
> +		sel->r.top = 0;
> +		sel->r.left = 0;
> +		sel->r.width = GC08A3_NATIVE_WIDTH;
> +		sel->r.height = GC08A3_NATIVE_HEIGHT;
> +		break;
> +	case V4L2_SEL_TGT_CROP_DEFAULT:
> +		if (gc08a3->cur_mode->width == GC08A3_NATIVE_WIDTH) {
> +			sel->r.top = 0;
> +			sel->r.left = 0;
> +			sel->r.width = gc08a3_modes[0].width;
> +			sel->r.height = gc08a3_modes[0].height;
> +		} else {
> +			sel->r.top = 0;
> +			sel->r.left = 0;
> +			sel->r.width = gc08a3_modes[1].width;
> +			sel->r.height = gc08a3_modes[1].height;
> +		}

You store the crop rectangle in the gc08a3_set_format() function, you
can simplify this with

		sel->r = *v4l2_subdev_state_get_crop(state, 0);

> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int gc08a3_init_state(struct v4l2_subdev *sd,
> +			     struct v4l2_subdev_state *state)
> +{
> +	struct v4l2_subdev_format fmt = {
> +		.which = V4L2_SUBDEV_FORMAT_TRY,
> +		.pad = 0,
> +		.format = {
> +			.code = GC08A3_MBUS_CODE,
> +			.width = gc08a3_modes[0].width,
> +			.height = gc08a3_modes[0].height,
> +		},
> +	};
> +
> +	gc08a3_set_format(sd, state, &fmt);
> +
> +	return 0;
> +}
> +
> +static int gc08a3_set_ctrl_hflip(struct gc08a3 *gc08a3, u32 ctrl_val)
> +{
> +	int ret;
> +	u64 val;
> +
> +	ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
> +	if (ret) {
> +		dev_err(gc08a3->dev, "read hflip register failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	val = ctrl_val ? (val | GC08A3_FLIP_H_MASK) :
> +			   (val & ~GC08A3_FLIP_H_MASK);
> +	ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
> +	if (ret < 0)
> +		dev_err(gc08a3->dev, "Error %d\n", ret);

You can use cci_update_bits()

	return cci_update_bits(gc08a3->regmap, GC08A3_FLIP_REG,
			       GC08A3_FLIP_H_MASK,
			       ctrl_val ? GC08A3_FLIP_H_MASK : 0, NULL);

Same below.

> +
> +	return ret;
> +}
> +
> +static int gc08a3_set_ctrl_vflip(struct gc08a3 *gc08a3, u32 ctrl_val)
> +{
> +	int ret;
> +	u64 val;
> +
> +	ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
> +	if (ret) {
> +		dev_err(gc08a3->dev, "read vflip register failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	val = ctrl_val ? (val | GC08A3_FLIP_V_MASK) :
> +			   (val & ~GC08A3_FLIP_V_MASK);
> +	ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
> +	if (ret < 0)
> +		dev_err(gc08a3->dev, "Error %d\n", ret);
> +
> +	return ret;
> +}
> +
> +static int gc08a3_test_pattern(struct gc08a3 *gc08a3, u32 pattern_menu)
> +{
> +	u32 pattern = 0;
> +	int ret;

	int ret = 0;

> +
> +	if (pattern_menu) {
> +		switch (pattern_menu) {
> +		case 1:
> +			pattern = 0x00;
> +			break;
> +		case 2:
> +			pattern = 0x10;
> +			break;
> +		case 3:
> +		case 4:
> +		case 5:
> +		case 6:
> +		case 7:
> +			pattern = pattern_menu + 1;
> +			break;
> +		}
> +
> +		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
> +				GC08A3_TEST_PATTERN_EN, NULL);
> +		if (ret)
> +			return ret;
> +
> +		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_IDX,
> +				pattern, NULL);
> +

		cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
			  GC08A3_TEST_PATTERN_EN, &ret);
		cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_IDX,
			  pattern, &ret);

And unless the sensor requires writing the GC08A3_REG_TEST_PATTERN_EN
register first, I would write the test pattern index first, to avoid
generating one frame with the wrong pattern.

> +	} else {
> +		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
> +				0x00, NULL);
> +	}
> +
> +	return ret;
> +}
> +
> +static int gc08a3_set_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	struct gc08a3 *gc08a3 =
> +		container_of(ctrl->handler, struct gc08a3, ctrls);
> +	int ret = 0;
> +	s64 exposure_max;
> +
> +	if (ctrl->id == V4L2_CID_VBLANK) {
> +		/* Update max exposure while meeting expected vblanking */
> +		exposure_max = gc08a3->cur_mode->height + ctrl->val -
> +			       GC08A3_EXP_MARGIN;

Let's not use cur_mode here, but retrieve the height from the state.
This makes the driver implementation less dependent on the modes, paving
the way to make the sensor fully configurable. You can look at the
imx219 driver for an example.

> +		__v4l2_ctrl_modify_range(gc08a3->exposure,
> +					 gc08a3->exposure->minimum,
> +					 exposure_max, gc08a3->exposure->step,
> +					 exposure_max);
> +	}
> +
> +	/*
> +	 * Applying V4L2 control value only happens
> +	 * when power is on for streaming
> +	 */
> +	if (!pm_runtime_get_if_in_use(gc08a3->dev))
> +		return 0;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_EXPOSURE:
> +		ret = cci_write(gc08a3->regmap, GC08A3_EXP_REG,
> +				ctrl->val, NULL);
> +		break;
> +
> +	case V4L2_CID_ANALOGUE_GAIN:
> +		ret = cci_write(gc08a3->regmap, GC08A3_AGAIN_REG,
> +				ctrl->val, NULL);
> +		break;
> +
> +	case V4L2_CID_VBLANK:
> +		ret = cci_write(gc08a3->regmap, GC08A3_FRAME_LENGTH_REG,
> +				gc08a3->cur_mode->height + ctrl->val, NULL);
> +		break;
> +
> +	case V4L2_CID_HFLIP:
> +		ret = gc08a3_set_ctrl_hflip(gc08a3, ctrl->val);
> +		break;
> +
> +	case V4L2_CID_VFLIP:
> +		ret = gc08a3_set_ctrl_vflip(gc08a3, ctrl->val);
> +		break;
> +
> +	case V4L2_CID_TEST_PATTERN:
> +		ret = gc08a3_test_pattern(gc08a3, ctrl->val);
> +		break;
> +
> +	default:
> +		break;
> +	}
> +
> +	pm_runtime_put(gc08a3->dev);
> +
> +	return ret;
> +}
> +
> +static const struct v4l2_ctrl_ops gc08a3_ctrl_ops = {
> +	.s_ctrl = gc08a3_set_ctrl,
> +};
> +
> +static int gc08a3_start_streaming(struct gc08a3 *gc08a3)
> +{
> +	const struct gc08a3_mode *mode;
> +	const struct gc08a3_reg_list *reg_list;
> +	const struct gc08a3_link_freq_config *link_freq_cfg;
> +	int ret;
> +
> +	ret = pm_runtime_resume_and_get(gc08a3->dev);
> +	if (ret < 0)
> +		return ret;
> +
> +	link_freq_cfg = gc08a3->cur_mode->link_freq_configs;
> +
> +	reg_list = &link_freq_cfg->reg_list;
> +	ret = cci_multi_reg_write(gc08a3->regmap,
> +				  reg_list->regs, reg_list->num_of_regs, NULL);
> +	if (ret) {
> +		dev_err(gc08a3->dev, "could not sent common table %d\n", ret);

The cci helpers already write error messages, I think you can drop this
one, as well as similar messages below.

> +		goto err_rpm_put;
> +	}
> +
> +	mode = gc08a3->cur_mode;
> +	reg_list = &mode->reg_list;
> +	ret = cci_multi_reg_write(gc08a3->regmap,
> +				  reg_list->regs, reg_list->num_of_regs, NULL);
> +	if (ret < 0) {
> +		dev_err(gc08a3->dev, "could not sent mode table %d\n", ret);
> +		goto err_rpm_put;
> +	}
> +
> +	ret = __v4l2_ctrl_handler_setup(&gc08a3->ctrls);
> +	if (ret < 0) {
> +		dev_err(gc08a3->dev, "could not sync v4l2 controls\n");
> +		goto err_rpm_put;
> +	}
> +
> +	ret = cci_write(gc08a3->regmap, GC08A3_STRAEMING_REG, 1, NULL);
> +	if (ret < 0) {
> +		dev_err(gc08a3->dev, "write STRAEMING_REG failed: %d\n", ret);
> +		goto err_rpm_put;
> +	}
> +
> +	return 0;
> +
> +err_rpm_put:
> +	pm_runtime_put(gc08a3->dev);
> +	return ret;
> +}
> +
> +static int gc08a3_stop_streaming(struct gc08a3 *gc08a3)
> +{
> +	int ret;
> +
> +	ret = cci_write(gc08a3->regmap, GC08A3_STRAEMING_REG, 0, NULL);
> +	if (ret < 0)
> +		dev_err(gc08a3->dev, "could not sent stop streaming %d\n", ret);
> +
> +	pm_runtime_put(gc08a3->dev);
> +	return ret;
> +}
> +
> +static int gc08a3_s_stream(struct v4l2_subdev *subdev, int enable)
> +{
> +	struct gc08a3 *gc08a3 = to_gc08a3(subdev);
> +	struct v4l2_subdev_state *state;
> +	int ret;
> +
> +	state = v4l2_subdev_lock_and_get_active_state(subdev);
> +
> +	if (enable)
> +		ret = gc08a3_start_streaming(gc08a3);
> +	else
> +		ret = gc08a3_stop_streaming(gc08a3);
> +
> +	gc08a3->streaming = enable;
> +	v4l2_subdev_unlock_state(state);
> +
> +	return ret;
> +}
> +
> +static int
> +gc08a3_enum_frame_interval(struct v4l2_subdev *subdev,
> +			   struct v4l2_subdev_state *sd_state,
> +			   struct v4l2_subdev_frame_interval_enum *fie)

Frame intervals on sensors should be controlled through the pixel rate
and blanking. You can drop this function, as well as the
gc08a3_mode.max_framerate field.

> +{
> +	unsigned int index = fie->index;
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(gc08a3_modes); i++) {
> +		if (fie->width != gc08a3_modes[i].width ||
> +		    fie->height != gc08a3_modes[i].height)
> +			continue;
> +
> +		if (index-- == 0) {
> +			fie->interval.numerator = 1;
> +			fie->interval.denominator =
> +				gc08a3_modes[i].max_framerate / 10;
> +			return 0;
> +		}
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct v4l2_subdev_video_ops gc08a3_video_ops = {
> +	.s_stream = gc08a3_s_stream,
> +};
> +
> +static const struct v4l2_subdev_pad_ops gc08a3_subdev_pad_ops = {
> +	.enum_mbus_code = gc08a3_enum_mbus_code,
> +	.enum_frame_size = gc08a3_enum_frame_size,
> +	.enum_frame_interval = gc08a3_enum_frame_interval,
> +	.get_fmt = v4l2_subdev_get_fmt,
> +	.set_fmt = gc08a3_set_format,
> +	.get_selection = gc08a3_get_selection,
> +};
> +
> +static const struct v4l2_subdev_core_ops gc08a3_core_ops = {
> +	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> +	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
> +};
> +
> +static const struct v4l2_subdev_ops gc08a3_subdev_ops = {
> +	.core = &gc08a3_core_ops,
> +	.video = &gc08a3_video_ops,
> +	.pad = &gc08a3_subdev_pad_ops,
> +};
> +
> +static const struct v4l2_subdev_internal_ops gc08a3_internal_ops = {
> +	.init_state = gc08a3_init_state,
> +};
> +
> +static int gc08a3_get_regulators(struct device *dev, struct gc08a3 *gc08a3)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(gc08a3_supply_name); i++)
> +		gc08a3->supplies[i].supply = gc08a3_supply_name[i];
> +
> +	return devm_regulator_bulk_get(dev, ARRAY_SIZE(gc08a3_supply_name),
> +				       gc08a3->supplies);
> +}
> +
> +static int gc08a3_parse_fwnode(struct device *dev, struct gc08a3 *gc08a3)

You can drop the first argument and use gc08a3->dev instead.

> +{
> +	struct fwnode_handle *endpoint;
> +	struct v4l2_fwnode_endpoint bus_cfg = {
> +		.bus_type = V4L2_MBUS_CSI2_DPHY,
> +	};
> +	int ret;
> +
> +	endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);

Please use

	endpoint = fwnode_graph_get_endpoint_by_id(dev_fwnode(gc08a3->dev),
						   0, 0,
						   FWNODE_GRAPH_ENDPOINT_NEXT);

> +	if (!endpoint) {
> +		dev_err(dev, "endpoint node not found\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
> +	if (ret) {
> +		dev_err(dev, "parsing endpoint node failed\n");
> +		goto done;
> +	}
> +
> +	ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
> +				       bus_cfg.nr_of_link_frequencies,
> +				       link_freq_menu_items,
> +				       ARRAY_SIZE(link_freq_menu_items),
> +				       &gc08a3->link_freq_bitmap);
> +	if (ret)
> +		goto done;
> +
> +done:
> +	v4l2_fwnode_endpoint_free(&bus_cfg);
> +	fwnode_handle_put(endpoint);
> +	return ret;
> +}
> +
> +static int gc08a3_init_controls(struct gc08a3 *gc08a3)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
> +	const struct gc08a3_mode *mode = &gc08a3_modes[0];
> +	const struct v4l2_ctrl_ops *ops = &gc08a3_ctrl_ops;
> +	struct v4l2_fwnode_device_properties props;
> +	struct v4l2_ctrl_handler *ctrl_hdlr;
> +	s64 exposure_max, h_blank;
> +	int ret;
> +
> +	ctrl_hdlr = &gc08a3->ctrls;
> +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
> +	if (ret)
> +		return ret;
> +
> +	gc08a3->link_freq =
> +		v4l2_ctrl_new_int_menu(ctrl_hdlr,
> +				       &gc08a3_ctrl_ops,
> +				       V4L2_CID_LINK_FREQ,
> +				       ARRAY_SIZE(link_freq_menu_items) - 1,
> +				       0, link_freq_menu_items);
> +	if (gc08a3->link_freq)
> +		gc08a3->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> +	gc08a3->pixel_rate =
> +		v4l2_ctrl_new_std(ctrl_hdlr,
> +				  &gc08a3_ctrl_ops,
> +				  V4L2_CID_PIXEL_RATE, 0,
> +				  to_pixel_rate(GC08A3_LINK_FREQ_336MHZ_INDEX),
> +				  1,
> +				  to_pixel_rate(GC08A3_LINK_FREQ_336MHZ_INDEX));
> +
> +	gc08a3->vblank =
> +		v4l2_ctrl_new_std(ctrl_hdlr,
> +				  &gc08a3_ctrl_ops, V4L2_CID_VBLANK,
> +				  mode->vts_min - mode->height,
> +				  GC08A3_VTS_MAX - mode->height, 1,
> +				  mode->vts_def - mode->height);
> +
> +	h_blank = mode->hts - mode->width;
> +	gc08a3->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
> +					   V4L2_CID_HBLANK, h_blank, h_blank, 1,
> +					   h_blank);
> +	if (gc08a3->hblank)
> +		gc08a3->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> +	v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
> +			  V4L2_CID_ANALOGUE_GAIN, GC08A3_AGAIN_MIN,
> +			  GC08A3_AGAIN_MAX, GC08A3_AGAIN_STEP,
> +			  GC08A3_AGAIN_MIN);
> +
> +	exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
> +	gc08a3->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
> +					     V4L2_CID_EXPOSURE, GC08A3_EXP_MIN,
> +					     exposure_max, GC08A3_EXP_STEP,
> +					     exposure_max);
> +
> +	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &gc08a3_ctrl_ops,
> +				     V4L2_CID_TEST_PATTERN,
> +				     ARRAY_SIZE(gc08a3_test_pattern_menu) - 1,
> +				     0, 0, gc08a3_test_pattern_menu);
> +
> +	v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops, V4L2_CID_HFLIP, 0,
> +			  1, 1, 0);
> +
> +	v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops, V4L2_CID_VFLIP, 0,
> +			  1, 1, 0);

Let's put the HFLIP and VFLIP controls in a cluster to make it possible
to efficiently set them in an atomic operation. See the imx219 driver
for an example.

> +
> +	/* register properties to fwnode (e.g. rotation, orientation) */
> +	ret = v4l2_fwnode_device_parse(&client->dev, &props);
> +	if (ret)
> +		goto error_ctrls;
> +
> +	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, ops, &props);
> +	if (ret)
> +		goto error_ctrls;
> +
> +	if (ctrl_hdlr->error) {
> +		ret = ctrl_hdlr->error;
> +		goto error_ctrls;
> +	}
> +
> +	gc08a3->sd.ctrl_handler = ctrl_hdlr;
> +
> +	return 0;
> +
> +error_ctrls:
> +	v4l2_ctrl_handler_free(ctrl_hdlr);
> +
> +	return ret;
> +}
> +
> +static int gc08a3_probe(struct i2c_client *client)
> +{
> +	struct device *dev = &client->dev;
> +	struct gc08a3 *gc08a3;
> +	int ret;
> +
> +	gc08a3 = devm_kzalloc(dev, sizeof(*gc08a3), GFP_KERNEL);
> +	if (!gc08a3)
> +		return -ENOMEM;
> +
> +	gc08a3->dev = dev;
> +
> +	ret = gc08a3_parse_fwnode(dev, gc08a3);
> +	if (ret)
> +		return ret;
> +
> +	gc08a3->regmap = devm_cci_regmap_init_i2c(client, 16);
> +	if (IS_ERR(gc08a3->regmap))
> +		return dev_err_probe(dev, PTR_ERR(gc08a3->regmap),
> +				     "failed to init CCI\n");
> +
> +	gc08a3->xclk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(gc08a3->xclk))
> +		return dev_err_probe(dev, PTR_ERR(gc08a3->xclk),
> +				     "failed to get xclk\n");
> +
> +	ret = clk_set_rate(gc08a3->xclk, GC08A3_DEFAULT_CLK_FREQ);
> +	if (ret)
> +		return dev_err_probe(dev, ret,
> +				     "failed to set xclk frequency\n");
> +
> +	ret = gc08a3_get_regulators(dev, gc08a3);
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret,
> +				     "failed to get regulators\n");
> +
> +	gc08a3->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> +	if (IS_ERR(gc08a3->reset_gpio))
> +		return dev_err_probe(dev, PTR_ERR(gc08a3->reset_gpio),
> +				     "failed to get gpio\n");
> +
> +	v4l2_i2c_subdev_init(&gc08a3->sd, client, &gc08a3_subdev_ops);
> +	gc08a3->sd.internal_ops = &gc08a3_internal_ops;
> +	gc08a3->cur_mode = &gc08a3_modes[0];
> +
> +	ret = gc08a3_power_on(gc08a3->dev);
> +	if (ret)
> +		return dev_err_probe(dev, ret,
> +				     "failed to sensor power on\n");
> +
> +	ret = gc08a3_identify_module(gc08a3);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to find sensor: %d\n", ret);
> +		goto err_power_off;
> +	}
> +
> +	ret = gc08a3_init_controls(gc08a3);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to init controls: %d", ret);
> +		goto err_power_off;
> +	}
> +
> +	gc08a3->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> +			    V4L2_SUBDEV_FL_HAS_EVENTS;
> +	gc08a3->pad.flags = MEDIA_PAD_FL_SOURCE;
> +	gc08a3->sd.dev = &client->dev;
> +	gc08a3->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +
> +	ret = media_entity_pads_init(&gc08a3->sd.entity, 1, &gc08a3->pad);
> +	if (ret < 0) {
> +		dev_err(dev, "could not register media entity\n");
> +		goto err_v4l2_ctrl_handler_free;
> +	}
> +
> +	gc08a3->sd.state_lock = gc08a3->ctrls.lock;
> +	ret = v4l2_subdev_init_finalize(&gc08a3->sd);
> +	if (ret < 0) {
> +		dev_err(dev, "v4l2 subdev init error: %d\n", ret);
> +		goto err_media_entity_cleanup;
> +	}
> +
> +	pm_runtime_set_active(gc08a3->dev);
> +	pm_runtime_enable(gc08a3->dev);
> +	pm_runtime_idle(gc08a3->dev);

Could you enable autosuspend ?

> +
> +	ret = v4l2_async_register_subdev_sensor(&gc08a3->sd);
> +	if (ret < 0) {
> +		dev_err(dev, "could not register v4l2 device\n");
> +		goto err_rpm;
> +	}
> +
> +	return 0;
> +
> +err_rpm:
> +	pm_runtime_disable(gc08a3->dev);
> +	v4l2_subdev_cleanup(&gc08a3->sd);
> +
> +err_media_entity_cleanup:
> +	media_entity_cleanup(&gc08a3->sd.entity);
> +
> +err_v4l2_ctrl_handler_free:
> +	v4l2_ctrl_handler_free(gc08a3->sd.ctrl_handler);
> +
> +err_power_off:
> +	gc08a3_power_off(gc08a3->dev);
> +
> +	return ret;
> +}
> +
> +static void gc08a3_remove(struct i2c_client *client)
> +{
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct gc08a3 *gc08a3 = to_gc08a3(sd);
> +
> +	v4l2_async_unregister_subdev(&gc08a3->sd);
> +	v4l2_subdev_cleanup(sd);
> +	media_entity_cleanup(&gc08a3->sd.entity);
> +	v4l2_ctrl_handler_free(&gc08a3->ctrls);
> +
> +	pm_runtime_disable(&client->dev);
> +	if (!pm_runtime_status_suspended(&client->dev))
> +		gc08a3_power_off(gc08a3->dev);
> +	pm_runtime_set_suspended(&client->dev);
> +}
> +
> +static const struct of_device_id gc08a3_of_match[] = {
> +	{ .compatible = "galaxycore,gc08a3" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, gc08a3_of_match);
> +
> +static const struct dev_pm_ops gc08a3_pm_ops = {
> +	SET_RUNTIME_PM_OPS(gc08a3_power_off, gc08a3_power_on, NULL)
> +};
> +
> +static struct i2c_driver gc08a3_i2c_driver = {
> +	.driver = {
> +		.of_match_table = gc08a3_of_match,
> +		.pm = &gc08a3_pm_ops,
> +		.name  = "gc08a3",
> +	},
> +	.probe  = gc08a3_probe,
> +	.remove = gc08a3_remove,
> +};
> +
> +module_i2c_driver(gc08a3_i2c_driver);
> +
> +MODULE_DESCRIPTION("GalaxyCore gc08a3 Camera driver");
> +MODULE_AUTHOR("Zhi Mao <zhi.mao at mediatek.com>");
> +MODULE_LICENSE("GPL");

-- 
Regards,

Laurent Pinchart


From aford173 at gmail.com  Tue Feb  6 10:50:16 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 6 Feb 2024 12:50:16 -0600
Subject: [PATCH V8 08/12] drm/bridge: imx: add driver for HDMI TX Parallel
 Video Interface
In-Reply-To: <20240206170632.GA2183819@dev-arch.thelio-3990X>
References: <20240203165307.7806-1-aford173@gmail.com> <20240203165307.7806-9-aford173@gmail.com>
 <20240206170632.GA2183819@dev-arch.thelio-3990X>
Message-ID: <CAHCN7x+Jt8Qfyjxg=TasUgezA3ZDk=6mFZkMyFEwk2Evt-6c5Q@mail.gmail.com>

On Tue, Feb 6, 2024 at 11:06?AM Nathan Chancellor <nathan at kernel.org> wrote:
>
> Hi all,
>
> On Sat, Feb 03, 2024 at 10:52:48AM -0600, Adam Ford wrote:
> > From: Lucas Stach <l.stach at pengutronix.de>
> >
> > This IP block is found in the HDMI subsystem of the i.MX8MP SoC. It has a
> > full timing generator and can switch between different video sources. On
> > the i.MX8MP however the only supported source is the LCDIF. The block
> > just needs to be powered up and told about the polarity of the video
> > sync signals to act in bypass mode.
> >
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v7)
> > Tested-by: Marek Vasut <marex at denx.de> (v1)
> > Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v7)
> > Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
> > Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> (v2)
> > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com> (v3)
> > Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> > Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> > Tested-by: Fabio Estevam <festevam at gmail.com>
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
>
> <snip>
>
> > diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> > new file mode 100644
> > index 000000000000..a76b7669fe8a
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> ...
> > +static void imx8mp_hdmi_pvi_bridge_enable(struct drm_bridge *bridge,
> > +                                       struct drm_bridge_state *bridge_state)
> > +{
> > +     struct drm_atomic_state *state = bridge_state->base.state;
> > +     struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);
> > +     struct drm_connector_state *conn_state;
> > +     const struct drm_display_mode *mode;
> > +     struct drm_crtc_state *crtc_state;
> > +     struct drm_connector *connector;
> > +     u32 bus_flags, val;
> > +
> > +     connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
> > +     conn_state = drm_atomic_get_new_connector_state(state, connector);
> > +     crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
> > +
> > +     if (WARN_ON(pm_runtime_resume_and_get(pvi->dev)))
> > +             return;
> > +
> > +     mode = &crtc_state->adjusted_mode;
> > +
> > +     val = FIELD_PREP(PVI_CTRL_MODE_MASK, PVI_CTRL_MODE_LCDIF) | PVI_CTRL_EN;
> > +
> > +     if (mode->flags & DRM_MODE_FLAG_PVSYNC)
> > +             val |= PVI_CTRL_OP_VSYNC_POL | PVI_CTRL_INP_VSYNC_POL;
> > +
> > +     if (mode->flags & DRM_MODE_FLAG_PHSYNC)
> > +             val |= PVI_CTRL_OP_HSYNC_POL | PVI_CTRL_INP_HSYNC_POL;
> > +
> > +     if (pvi->next_bridge->timings)
> > +             bus_flags = pvi->next_bridge->timings->input_bus_flags;
> > +     else if (bridge_state)
> > +             bus_flags = bridge_state->input_bus_cfg.flags;
> > +
> > +     if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
> > +             val |= PVI_CTRL_OP_DE_POL | PVI_CTRL_INP_DE_POL;
> > +
> > +     writel(val, pvi->regs + HTX_PVI_CTRL);
> > +}
>
> Apologies if this has already been reported or fixed, I searched lore
> and did not find anything. Clang warns (or errors with CONFIG_WERROR=y)
> for this function:
>
>   drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:81:11: error: variable 'bus_flags' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
>      81 |         else if (bridge_state)
>         |                  ^~~~~~~~~~~~
>   drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:84:6: note: uninitialized use occurs here
>      84 |         if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
>         |             ^~~~~~~~~
>   drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:81:7: note: remove the 'if' if its condition is always true
>      81 |         else if (bridge_state)
>         |              ^~~~~~~~~~~~~~~~~
>      82 |                 bus_flags = bridge_state->input_bus_cfg.flags;
>   drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:60:15: note: initialize the variable 'bus_flags' to silence this warning
>      60 |         u32 bus_flags, val;
>         |                      ^
>         |                       = 0
>   1 error generated.
>
> This seems legitimate. If bridge_state can be NULL, should bus_flags be
> initialized to zero like it suggests or should that 'else if' be turned
> into a plain 'else'? I am happy to send a patch with that guidance.

I don't think we can turn the else-if into a blind else, because in
order to make bus_flags point to bridge_state->input_bus_cfg.flags,
bridge_state must not be NULL, but we could add an additional else to
set bus_flags to 0, but I think the simplest thing to do would be to
set bus_flags = 0 at the initialization on line 60 as it suggests.

If you agree, I can submit a patch later tonight.  I need to fix
another issue found by the build-bot [1]  to make line 113 return NULL
instead of 0 anyway.  I figured I could just fix them both at the same
time.

adam

[1] - https://lore.kernel.org/oe-kbuild-all/202402062134.a6CqAt3s-lkp at intel.com/

>
> Cheers,
> Nathan


From afd at ti.com  Tue Feb  6 10:50:38 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 6 Feb 2024 12:50:38 -0600
Subject: [PATCH v1] arm64: dts: ti: verdin-am62: mallow: add TPM device
In-Reply-To: <26F9C286-606C-40C6-994E-EABDFFCDFDC4@dolcini.it>
References: <20240126165136.28543-1-francesco@dolcini.it>
 <65a24f21-4cc6-4843-b838-b1c7020ca45d@ti.com>
 <26F9C286-606C-40C6-994E-EABDFFCDFDC4@dolcini.it>
Message-ID: <b5b70049-81f6-455e-b2bf-d03431e5b27b@ti.com>

On 2/6/24 12:36 PM, Francesco Dolcini wrote:
> 
> 
> Il 6 febbraio 2024 19:29:13 CET, Andrew Davis <afd at ti.com> ha scritto:
>> On 1/26/24 10:51 AM, Francesco Dolcini wrote:
>>> From: Francesco Dolcini <francesco.dolcini at toradex.com>
>>>
>>> Add TPM device to Mallow device tree file, the device is connected to
>>> the SoC with SPI1/CS1, the same SPI interface is also available on an
>>> extension header together with an additional CS0 signal.
>>>
>>> Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
>>> ---
>>>    arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi | 10 ++++++++++
>>>    1 file changed, 10 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
>>> index 17b93534f658..77b1beb638ad 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
>>> @@ -127,6 +127,16 @@ &main_spi1 {
>>>    		    <&pinctrl_qspi1_cs2_gpio>;
>>>    	cs-gpios = <0>, <&main_gpio0 12 GPIO_ACTIVE_LOW>;
>>>    	status = "okay";
>>> +
>>> +	tpm at 1 {
>>> +		compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
>>> +		reg = <1>;
>>> +		pinctrl-names = "default";
>>> +		pinctrl-0 = <&pinctrl_qspi1_dqs_gpio>;
>>> +		interrupt-parent = <&main_gpio1>;
>>> +		interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
>>
>> Just a heads-up, the SLB9670 datasheet says this device uses
>> an active low interrupt (IRQ_TYPE_LEVEL_LOW). Using TYPE_EDGE
>> here can cause missed interrupts if the line stays low for
>> multiple interrupts.
> 
> 
> The driver interrupt handler would need to take care of it, if needed.
> 
> The SOC does not support level interrupt, so there is no other solution, am I wrong?

Correct, our K3 SoCs do not support level interrupts and so are not compatible
with most hardware that uses interrupts (unless you are okay with missing
some interrupts every now and then..).

As you say, our interrupt driver needs to be modified to handle that. Possibly
by re-checking the line level after the interrupt handlers have all run to see
if it is still high/low, then manually re-triggering the interrupt if so.

The heads-up is just that you should be aware of this in case you have issues.
When(if) our interrupt driver is ever fixed you will need to update the DT here
to take advantage of the level handler.

Andrew

>   
> Francesco
> 


From semen.protsenko at linaro.org  Tue Feb  6 10:51:41 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 6 Feb 2024 12:51:41 -0600
Subject: [PATCH 4/4] spi: s3c64xx: add support for google,gs101-spi
In-Reply-To: <20240206085238.1208256-5-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org> <20240206085238.1208256-5-tudor.ambarus@linaro.org>
Message-ID: <CAPLW+4m2qhayzzWBSc-Qq2zuYZCp6N30UfkBM9Cf7sip36KrYQ@mail.gmail.com>

On Tue, Feb 6, 2024 at 2:52?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> Add support for GS101 SPI. GS101 integrates 16 SPI nodes, all with 64
> bytes FIFOs. GS101 allows just 32 bit register accesses, otherwise a
> Serror Interrupt is raised. Do the write reg accesses in 32 bits.
>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

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

>  drivers/spi/spi-s3c64xx.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index cb45ad615f3d..9ad0d513fb30 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -19,7 +19,7 @@
>  #include <linux/spi/spi.h>
>  #include <linux/types.h>
>
> -#define MAX_SPI_PORTS          12
> +#define MAX_SPI_PORTS          16
>  #define S3C64XX_SPI_QUIRK_CS_AUTO      (1 << 1)
>  #define AUTOSUSPEND_TIMEOUT    2000
>
> @@ -1538,6 +1538,19 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
>         .quirks         = S3C64XX_SPI_QUIRK_CS_AUTO,
>  };
>
> +static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
> +       .fifo_lvl_mask  = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
> +                           0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
> +       .rx_lvl_offset  = 15,
> +       .tx_st_done     = 25,
> +       .clk_div        = 4,
> +       .high_speed     = true,
> +       .clk_from_cmu   = true,
> +       .has_loopback   = true,
> +       .use_32bit_io   = true,
> +       .quirks         = S3C64XX_SPI_QUIRK_CS_AUTO,
> +};
> +
>  static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
>         {
>                 .name           = "s3c2443-spi",
> @@ -1550,6 +1563,9 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
>  };
>
>  static const struct of_device_id s3c64xx_spi_dt_match[] = {
> +       { .compatible = "google,gs101-spi",
> +                       .data = &gs101_spi_port_config,
> +       },
>         { .compatible = "samsung,s3c2443-spi",
>                         .data = &s3c2443_spi_port_config,
>         },
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From nathan at kernel.org  Tue Feb  6 10:52:59 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Tue, 6 Feb 2024 11:52:59 -0700
Subject: [PATCH V8 08/12] drm/bridge: imx: add driver for HDMI TX
 Parallel Video Interface
In-Reply-To: <CAHCN7x+Jt8Qfyjxg=TasUgezA3ZDk=6mFZkMyFEwk2Evt-6c5Q@mail.gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-9-aford173@gmail.com>
 <20240206170632.GA2183819@dev-arch.thelio-3990X>
 <CAHCN7x+Jt8Qfyjxg=TasUgezA3ZDk=6mFZkMyFEwk2Evt-6c5Q@mail.gmail.com>
Message-ID: <20240206185259.GA2649447@dev-arch.thelio-3990X>

On Tue, Feb 06, 2024 at 12:50:16PM -0600, Adam Ford wrote:
> On Tue, Feb 6, 2024 at 11:06?AM Nathan Chancellor <nathan at kernel.org> wrote:
> >
> > Hi all,
> >
> > On Sat, Feb 03, 2024 at 10:52:48AM -0600, Adam Ford wrote:
> > > From: Lucas Stach <l.stach at pengutronix.de>
> > >
> > > This IP block is found in the HDMI subsystem of the i.MX8MP SoC. It has a
> > > full timing generator and can switch between different video sources. On
> > > the i.MX8MP however the only supported source is the LCDIF. The block
> > > just needs to be powered up and told about the polarity of the video
> > > sync signals to act in bypass mode.
> > >
> > > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > > Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v7)
> > > Tested-by: Marek Vasut <marex at denx.de> (v1)
> > > Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v7)
> > > Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
> > > Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> (v2)
> > > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com> (v3)
> > > Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> > > Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> > > Tested-by: Fabio Estevam <festevam at gmail.com>
> > > Signed-off-by: Adam Ford <aford173 at gmail.com>
> >
> > <snip>
> >
> > > diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> > > new file mode 100644
> > > index 000000000000..a76b7669fe8a
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> > ...
> > > +static void imx8mp_hdmi_pvi_bridge_enable(struct drm_bridge *bridge,
> > > +                                       struct drm_bridge_state *bridge_state)
> > > +{
> > > +     struct drm_atomic_state *state = bridge_state->base.state;
> > > +     struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);
> > > +     struct drm_connector_state *conn_state;
> > > +     const struct drm_display_mode *mode;
> > > +     struct drm_crtc_state *crtc_state;
> > > +     struct drm_connector *connector;
> > > +     u32 bus_flags, val;
> > > +
> > > +     connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
> > > +     conn_state = drm_atomic_get_new_connector_state(state, connector);
> > > +     crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
> > > +
> > > +     if (WARN_ON(pm_runtime_resume_and_get(pvi->dev)))
> > > +             return;
> > > +
> > > +     mode = &crtc_state->adjusted_mode;
> > > +
> > > +     val = FIELD_PREP(PVI_CTRL_MODE_MASK, PVI_CTRL_MODE_LCDIF) | PVI_CTRL_EN;
> > > +
> > > +     if (mode->flags & DRM_MODE_FLAG_PVSYNC)
> > > +             val |= PVI_CTRL_OP_VSYNC_POL | PVI_CTRL_INP_VSYNC_POL;
> > > +
> > > +     if (mode->flags & DRM_MODE_FLAG_PHSYNC)
> > > +             val |= PVI_CTRL_OP_HSYNC_POL | PVI_CTRL_INP_HSYNC_POL;
> > > +
> > > +     if (pvi->next_bridge->timings)
> > > +             bus_flags = pvi->next_bridge->timings->input_bus_flags;
> > > +     else if (bridge_state)
> > > +             bus_flags = bridge_state->input_bus_cfg.flags;
> > > +
> > > +     if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
> > > +             val |= PVI_CTRL_OP_DE_POL | PVI_CTRL_INP_DE_POL;
> > > +
> > > +     writel(val, pvi->regs + HTX_PVI_CTRL);
> > > +}
> >
> > Apologies if this has already been reported or fixed, I searched lore
> > and did not find anything. Clang warns (or errors with CONFIG_WERROR=y)
> > for this function:
> >
> >   drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:81:11: error: variable 'bus_flags' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
> >      81 |         else if (bridge_state)
> >         |                  ^~~~~~~~~~~~
> >   drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:84:6: note: uninitialized use occurs here
> >      84 |         if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
> >         |             ^~~~~~~~~
> >   drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:81:7: note: remove the 'if' if its condition is always true
> >      81 |         else if (bridge_state)
> >         |              ^~~~~~~~~~~~~~~~~
> >      82 |                 bus_flags = bridge_state->input_bus_cfg.flags;
> >   drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c:60:15: note: initialize the variable 'bus_flags' to silence this warning
> >      60 |         u32 bus_flags, val;
> >         |                      ^
> >         |                       = 0
> >   1 error generated.
> >
> > This seems legitimate. If bridge_state can be NULL, should bus_flags be
> > initialized to zero like it suggests or should that 'else if' be turned
> > into a plain 'else'? I am happy to send a patch with that guidance.
> 
> I don't think we can turn the else-if into a blind else, because in
> order to make bus_flags point to bridge_state->input_bus_cfg.flags,
> bridge_state must not be NULL, but we could add an additional else to
> set bus_flags to 0, but I think the simplest thing to do would be to
> set bus_flags = 0 at the initialization on line 60 as it suggests.
> 
> If you agree, I can submit a patch later tonight.  I need to fix
> another issue found by the build-bot [1]  to make line 113 return NULL
> instead of 0 anyway.  I figured I could just fix them both at the same
> time.
> 
> [1] - https://lore.kernel.org/oe-kbuild-all/202402062134.a6CqAt3s-lkp at intel.com/

Seems reasonable to me, thanks!

Nathan


From andrea.porta at suse.com  Tue Feb  6 10:54:59 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Tue,  6 Feb 2024 19:54:59 +0100
Subject: [PATCH] arm64: Add the arm64.no32bit_el0 command line option
Message-ID: <20240206185459.32465-1-andrea.porta@suse.com>

Introducing the field 'el0' to the idreg-override for register
ID_AA64PFR0_EL1. This field is also aliased to the new kernel
command line option 'arm64.no32bit_el0' as a more recognizable
and mnemonic name to disable the execution of 32 bit userspace
applications (i.e. avoid Aarch32 execution state in EL0) from
kernel command line.

Link: https://lore.kernel.org/r/ZVTleETzfFUchs77 at apocalypse
Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 Documentation/admin-guide/kernel-parameters.txt | 3 +++
 arch/arm64/kernel/idreg-override.c              | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 65731b060e3f..9f962deeef5a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -433,6 +433,9 @@
 	arm64.nosve	[ARM64] Unconditionally disable Scalable Vector
 			Extension support
 
+	arm64.no32bit_el0 [ARM64] Unconditionally disable the execution of
+			32 bit applications
+
 	ataflop=	[HW,M68k]
 
 	atarimouse=	[HW,MOUSE] Atari Mouse
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index e30fd9e32ef3..642cda19e42d 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -86,6 +86,7 @@ static const struct ftr_set_desc pfr0 __prel64_initconst = {
 	.override	= &id_aa64pfr0_override,
 	.fields		= {
 	        FIELD("sve", ID_AA64PFR0_EL1_SVE_SHIFT, pfr0_sve_filter),
+		FIELD("el0", ID_AA64PFR0_EL1_EL0_SHIFT, NULL),
 		{}
 	},
 };
@@ -197,6 +198,7 @@ static const struct {
 	{ "arm64.nomops",		"id_aa64isar2.mops=0" },
 	{ "arm64.nomte",		"id_aa64pfr1.mte=0" },
 	{ "nokaslr",			"arm64_sw.nokaslr=1" },
+	{ "arm64.no32bit_el0",		"id_aa64pfr0.el0=1" },
 };
 
 static int __init parse_hexdigit(const char *p, u64 *v)
-- 
2.41.0



From semen.protsenko at linaro.org  Tue Feb  6 10:59:33 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 6 Feb 2024 12:59:33 -0600
Subject: [PATCH 0/4] spi: s3c64xx: add support for google,gs101-spi
In-Reply-To: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
Message-ID: <CAPLW+4kPib_3MJeGL3bHT__rLoJOS=GS+gNZUbZ0dpyey9E-Hg@mail.gmail.com>

On Tue, Feb 6, 2024 at 2:52?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> Depends on the simple cleanup patches from:
> https://lore.kernel.org/linux-spi/20240205124513.447875-1-tudor.ambarus at linaro.org/
>
> A slightly different version of the google,gs101-spi support was sent at:
> https://lore.kernel.org/linux-spi/20240125145007.748295-1-tudor.ambarus at linaro.org/
>
> Let's add support for gs101-spi so that I have a testing base for the
> driver rework patches that will follow.
>
> Tudor Ambarus (4):
>   spi: s3c64xx: explicitly include <linux/types.h>
>   spi: dt-bindings: samsung: add google,gs101-spi compatible
>   spi: s3c64xx: add s3c64xx_iowrite{8,16}_32_rep accessors
>   spi: s3c64xx: add support for google,gs101-spi
>

Just a grumpy note: I wish this series (except for the [PATCH 1/4],
which I'd argue doesn't belong here) was submitted before the rest of
SPI cleanups and reworkings. Would've made reviewing much easier,
because this series doesn't apply without SPI cleanup series that has
to be applied prior to that. There are other benefits to that approach
too, as was discussed earlier.

>  .../devicetree/bindings/spi/samsung,spi.yaml  |  1 +
>  drivers/spi/spi-s3c64xx.c                     | 89 +++++++++++++++----
>  2 files changed, 75 insertions(+), 15 deletions(-)
>
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From aren at peacevolution.org  Tue Feb  6 10:13:17 2024
From: aren at peacevolution.org (Aren Moynihan)
Date: Tue,  6 Feb 2024 13:13:17 -0500
Subject: [PATCH v2 1/4] leds: rgb: leds-group-multicolor: allow leds to stay on in suspend
Message-ID: <20240206185400.596979-1-aren@peacevolution.org>

If none of the managed leds enable LED_CORE_SUSPENDRESUME, then we
shouldn't need to set it here. This makes it possible to use multicolor
groups with gpio leds that enable retain-state-suspended in the device
tree.

Signed-off-by: Aren Moynihan <aren at peacevolution.org>
---

Changes in v2:
 - make sure count gets initialized
 - send the patch to (hopefully) all the correct people this time

 drivers/leds/rgb/leds-group-multicolor.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/leds/rgb/leds-group-multicolor.c b/drivers/leds/rgb/leds-group-multicolor.c
index 39f58be32af5..b6c7679015fd 100644
--- a/drivers/leds/rgb/leds-group-multicolor.c
+++ b/drivers/leds/rgb/leds-group-multicolor.c
@@ -69,7 +69,7 @@ static int leds_gmc_probe(struct platform_device *pdev)
 	struct mc_subled *subled;
 	struct leds_multicolor *priv;
 	unsigned int max_brightness = 0;
-	int i, ret, count = 0;
+	int i, ret, count = 0, common_flags = 0;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -91,6 +91,7 @@ static int leds_gmc_probe(struct platform_device *pdev)
 		if (!priv->monochromatics)
 			return -ENOMEM;
 
+		common_flags |= led_cdev->flags;
 		priv->monochromatics[count] = led_cdev;
 
 		max_brightness = max(max_brightness, led_cdev->max_brightness);
@@ -114,12 +115,15 @@ static int leds_gmc_probe(struct platform_device *pdev)
 
 	/* Initialise the multicolor's LED class device */
 	cdev = &priv->mc_cdev.led_cdev;
-	cdev->flags = LED_CORE_SUSPENDRESUME;
 	cdev->brightness_set_blocking = leds_gmc_set;
 	cdev->max_brightness = max_brightness;
 	cdev->color = LED_COLOR_ID_MULTI;
 	priv->mc_cdev.num_colors = count;
 
+	/* we only need suspend/resume if a sub-led requests it */
+	if (common_flags & LED_CORE_SUSPENDRESUME)
+		cdev->flags = LED_CORE_SUSPENDRESUME;
+
 	init_data.fwnode = dev_fwnode(dev);
 	ret = devm_led_classdev_multicolor_register_ext(dev, &priv->mc_cdev, &init_data);
 	if (ret)
-- 
2.43.0



From aren at peacevolution.org  Tue Feb  6 10:13:18 2024
From: aren at peacevolution.org (Aren Moynihan)
Date: Tue,  6 Feb 2024 13:13:18 -0500
Subject: [PATCH v2 2/4] arm64: dts: sun50i-a64-pinephone: Retain leds state in suspend
In-Reply-To: <20240206185400.596979-1-aren@peacevolution.org>
References: <20240206185400.596979-1-aren@peacevolution.org>
Message-ID: <20240206185400.596979-2-aren@peacevolution.org>

From: Miles Alan <m at milesalan.com>

Allows user to set a led before entering suspend to know that
the phone is still on (or could be used for notifications etc.)

Signed-off-by: Miles Alan <m at milesalan.com>
Signed-off-by: Ondrej Jirman <megi at xff.cz>
Signed-off-by: Aren Moynihan <aren at peacevolution.org>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---

(no changes since v1)

 arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
index 87847116ab6d..ad2476ee01e4 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -43,18 +43,21 @@ led-0 {
 			function = LED_FUNCTION_INDICATOR;
 			color = <LED_COLOR_ID_BLUE>;
 			gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */
+			retain-state-suspended;
 		};
 
 		led-1 {
 			function = LED_FUNCTION_INDICATOR;
 			color = <LED_COLOR_ID_GREEN>;
 			gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */
+			retain-state-suspended;
 		};
 
 		led-2 {
 			function = LED_FUNCTION_INDICATOR;
 			color = <LED_COLOR_ID_RED>;
 			gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */
+			retain-state-suspended;
 		};
 	};
 
-- 
2.43.0



From aren at peacevolution.org  Tue Feb  6 10:13:19 2024
From: aren at peacevolution.org (Aren Moynihan)
Date: Tue,  6 Feb 2024 13:13:19 -0500
Subject: [PATCH v2 3/4] arm64: dts: sun50i-a64-pinephone: add multicolor led node
In-Reply-To: <20240206185400.596979-1-aren@peacevolution.org>
References: <20240206185400.596979-1-aren@peacevolution.org>
Message-ID: <20240206185400.596979-3-aren@peacevolution.org>

The red, green, and blue leds currently in the device tree represent a
single rgb led on the front of the PinePhone.

Signed-off-by: Aren Moynihan <aren at peacevolution.org>
---

Changes in v2:
 - remove function property from individual led nodes

 .../boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
index ad2476ee01e4..e53e0d4579a7 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -39,28 +39,32 @@ chosen {
 	leds {
 		compatible = "gpio-leds";
 
-		led-0 {
-			function = LED_FUNCTION_INDICATOR;
+		led0: led-0 {
 			color = <LED_COLOR_ID_BLUE>;
 			gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */
 			retain-state-suspended;
 		};
 
-		led-1 {
-			function = LED_FUNCTION_INDICATOR;
+		led1: led-1 {
 			color = <LED_COLOR_ID_GREEN>;
 			gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */
 			retain-state-suspended;
 		};
 
-		led-2 {
-			function = LED_FUNCTION_INDICATOR;
+		led2: led-2 {
 			color = <LED_COLOR_ID_RED>;
 			gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */
 			retain-state-suspended;
 		};
 	};
 
+	multi-led {
+		compatible = "leds-group-multicolor";
+		color = <LED_COLOR_ID_RGB>;
+		function = LED_FUNCTION_INDICATOR;
+		leds = <&led0>, <&led1>, <&led2>;
+	};
+
 	reg_ps: ps-regulator {
 		compatible = "regulator-fixed";
 		regulator-name = "ps";
-- 
2.43.0



From aren at peacevolution.org  Tue Feb  6 10:13:20 2024
From: aren at peacevolution.org (Aren Moynihan)
Date: Tue,  6 Feb 2024 13:13:20 -0500
Subject: [PATCH v2 4/4] arm64: dts: sun50i-a64-pinephone: change led type to status
In-Reply-To: <20240206185400.596979-1-aren@peacevolution.org>
References: <20240206185400.596979-1-aren@peacevolution.org>
Message-ID: <20240206185400.596979-4-aren@peacevolution.org>

The status function is described in the documentation as being a rgb led
used for system notifications on phones[1][2]. This is exactly what this
led is used for on the PinePhone, so using status is probably more
accurate than indicator.

1: Documentation/leds/well-known-leds.txt
2: include/dt-bindings/leds/common.h

Signed-off-by: Aren Moynihan <aren at peacevolution.org>
---
I can't find any documentation describing the indicator function, so
it's definitely less specific than status, but besides that I'm not sure
how it compares. Please ignore this patch if it's not useful.

(no changes since v1)

 arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
index e53e0d4579a7..6d327266e6cc 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -61,7 +61,7 @@ led2: led-2 {
 	multi-led {
 		compatible = "leds-group-multicolor";
 		color = <LED_COLOR_ID_RGB>;
-		function = LED_FUNCTION_INDICATOR;
+		function = LED_FUNCTION_STATUS;
 		leds = <&led0>, <&led1>, <&led2>;
 	};
 
-- 
2.43.0



From konrad.dybcio at linaro.org  Tue Feb  6 11:04:20 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Tue, 6 Feb 2024 20:04:20 +0100
Subject: [PATCH 3/3] arm64: defconfig: enable audio drivers for SM8650 QRD
 board
In-Reply-To: <20240125-topic-sm8650-upstream-audio-dt-v1-3-c24d23ae5763@linaro.org>
References: <20240125-topic-sm8650-upstream-audio-dt-v1-0-c24d23ae5763@linaro.org>
 <20240125-topic-sm8650-upstream-audio-dt-v1-3-c24d23ae5763@linaro.org>
Message-ID: <4c2939ea-0666-41b0-9885-3eea4130c623@linaro.org>

On 25.01.2024 17:42, Neil Armstrong wrote:
> Enable the SM8650 LPASS driver and the WCD939x codec driver
> as module which are used to support Audio on the SM8650 QRD board.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>

Konrad


From chrysh at christina-quast.de  Tue Feb  6 11:19:50 2024
From: chrysh at christina-quast.de (Christina Quast)
Date: Tue, 6 Feb 2024 20:19:50 +0100
Subject: [PATCH v2 3/3] net: phy: add Rust Rockchip PHY driver
In-Reply-To: <CALNs47tnwCgyvM2jBo=bTt1=2AJFt3b6W+JsTHM3Np2tbNJYCA@mail.gmail.com>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
 <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>
 <CALNs47tnwCgyvM2jBo=bTt1=2AJFt3b6W+JsTHM3Np2tbNJYCA@mail.gmail.com>
Message-ID: <eb229460-0efc-448a-863f-ac0634a72f2c@christina-quast.de>

Hi Trevor!

Thanks a lot for your review, I learned a lot! I felt, from the feedback 
in the Zulip forum that rewriting more phy drivers might be interesting, 
but I think I misunderstood something.

There is no specific goal behind the rewrite, I just thought it would be 
useful to bring more Rust into the Kernel.

Cheers,

Christina

On 2/1/24 22:06, Trevor Gross wrote:
> On Thu, Feb 1, 2024 at 12:07?PM Christina Quast
> <contact at christina-quast.de> wrote:
>> +++ b/drivers/net/phy/rockchip_rust.rs
>> @@ -0,0 +1,131 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (C) 2024 Christina Quast <contact at christina-quast.de>
>> +
>> +//! Rust Rockchip PHY driver
>> +//!
>> +//! C version of this driver: [`drivers/net/phy/rockchip.c`](./rockchip.c)
>> +use kernel::{
>> +    c_str,
>> +    net::phy::{self, DeviceId, Driver},
>> +    prelude::*,
>> +    uapi,
>> +};
>> +
>> +kernel::module_phy_driver! {
>> +    drivers: [PhyRockchip],
>> +    device_table: [
>> +        DeviceId::new_with_driver::<PhyRockchip>(),
>> +    ],
>> +    name: "rust_asix_phy",
>> +    author: "FUJITA Tomonori <fujita.tomonori at gmail.com>",
> Tomo wrote this? :)
>
>> +    description: "Rust Asix PHYs driver",
>> +    license: "GPL",
>> +}
>> +
>> +
>> +const MII_INTERNAL_CTRL_STATUS: u16 = 17;
>> +const SMI_ADDR_TSTCNTL: u16 = 20;
>> +const SMI_ADDR_TSTWRITE: u16 = 23;
>> +
>> +const MII_AUTO_MDIX_EN: u16 = bit(7);
>> +const MII_MDIX_EN: u16 = bit(6);
>> +
>> +const TSTCNTL_WR: u16 = bit(14) | bit(10);
>> +
>> +const TSTMODE_ENABLE: u16 = 0x400;
>> +const TSTMODE_DISABLE: u16 = 0x0;
>> +
>> +const WR_ADDR_A7CFG: u16 = 0x18;
> Most of these are clear enough, but could you add comments about what
> the more ambiguous constants are for? (e.g. A7CFG).
>
>> +struct PhyRockchip;
>> +
>> +impl PhyRockchip {
> Remove the `helper_` prefix for these functions, and change the docs.
> Their use as helpers is obvious enough based on where they are called,
> better to say what they actually accomplish.
>
> Since they don't take `self`, these could also just be standalone
> functions rather than in an `impl PhyRockchip` block. This makes
> calling them a bit cleaner since you don't need the `PhyRockchip::`
> prefix.
>
>> +   /// Helper function for helper_integrated_phy_analog_init
>> +    fn helper_init_tstmode(dev: &mut phy::Device) -> Result {
>> +        // Enable access to Analog and DSP register banks
>> +        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_ENABLE)?;
>> +        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_DISABLE)?;
>> +        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_ENABLE)
>> +    }
> For consistency, just make the last write also end with `?;` and add a
> `Ok(())` line.
>
>> +
>> +    /// Helper function for helper_integrated_phy_analog_init
>> +    fn helper_close_tstmode(dev: &mut phy::Device) -> Result {
>> +        dev.write(SMI_ADDR_TSTCNTL, TSTMODE_DISABLE)
>> +    }
>> +
>> +    /// Helper function for rockchip_config_init
>> +    fn helper_integrated_phy_analog_init(dev: &mut phy::Device) -> Result {
>> +        Self::helper_init_tstmode(dev)?;
>> +        dev.write(SMI_ADDR_TSTWRITE, 0xB)?;
>> +        dev.write(SMI_ADDR_TSTCNTL, TSTCNTL_WR | WR_ADDR_A7CFG)?;
>> +        Self::helper_close_tstmode(dev)
>> +    }
>> +
>> +    /// Helper function for config_init
>> +    fn helper_config_init(dev: &mut phy::Device) -> Result {
>> +        let val = !MII_AUTO_MDIX_EN & dev.read(MII_INTERNAL_CTRL_STATUS)?;
>> +        dev.write(MII_INTERNAL_CTRL_STATUS, val)?;
>> +        Self::helper_integrated_phy_analog_init(dev)
>> +    }
>> +
>> +    fn helper_set_polarity(dev: &mut phy::Device, polarity: u8) -> Result {
>> +        let reg = !MII_AUTO_MDIX_EN & dev.read(MII_INTERNAL_CTRL_STATUS)?;
>> +        let val = match polarity as u32 {
>> +            // status: MDI; control: force MDI
>> +            uapi::ETH_TP_MDI => Some(reg & !MII_MDIX_EN),
>> +            // status: MDI-X; control: force MDI-X
>> +            uapi::ETH_TP_MDI_X => Some(reg | MII_MDIX_EN),
>> +            // uapi::ETH_TP_MDI_AUTO => control: auto-select
>> +            // uapi::ETH_TP_MDI_INVALID => status: unknown; control: unsupported
>> +            _ => None,
> Is receiving an invalid value not an error? I.e.
>
>      uapi::ETH_TP_MDI_AUTO | uapi::ETH_TP_MDI_INVALID => None,
>      _ => return Err(...)
>
> I know the current implementation came from the C version, just
> wondering about correctness here.
>
>> +        };
>> +        if let Some(v) = val {
>> +            if v != reg {
>> +                return dev.write(MII_INTERNAL_CTRL_STATUS, v);
>> +            }
>> +        }
> In the match statement above - I think you can replace `=> None` with
> `=> return Ok(())` and drop the `Some(...)` wrappers. Then you don't
> need to destructure val here.
>
>> +        Ok(())
>> +
>> +    }
>> +}
>> +
>> +#[vtable]
>> +impl Driver for PhyRockchip {
>> +    const FLAGS: u32 = 0;
>> +    const NAME: &'static CStr = c_str!("Rockchip integrated EPHY");
>> +    const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_custom_mask(0x1234d400, 0xfffffff0);
>> +
>> +    fn link_change_notify(dev: &mut phy::Device) {
>> +    // If mode switch happens from 10BT to 100BT, all DSP/AFE
>> +    // registers are set to default values. So any AFE/DSP
>> +    // registers have to be re-initialized in this case.
> Comment indent
>
>> +        if dev.state() == phy::DeviceState::Running && dev.speed() == uapi::SPEED_100 {
>> +            if let Err(e) = Self::helper_integrated_phy_analog_init(dev) {
>> +                pr_err!("rockchip: integrated_phy_analog_init err: {:?}", e);
>> +            }
>> +        }
>> +    }
>> +
>> +    fn soft_reset(dev: &mut phy::Device) -> Result {
>> +        dev.genphy_soft_reset()
>> +    }
>> +
>> +    fn config_init(dev: &mut phy::Device) -> Result {
>> +        PhyRockchip::helper_config_init(dev)
>> +    }
>> +
>> +    fn config_aneg(dev: &mut phy::Device) -> Result {
>> +        PhyRockchip::helper_set_polarity(dev, dev.mdix())?;
>> +        dev.genphy_config_aneg()
>> +    }
>> +
>> +    fn suspend(dev: &mut phy::Device) -> Result {
>> +        dev.genphy_suspend()
>> +    }
>> +
>> +    fn resume(dev: &mut phy::Device) -> Result {
>> +        let _ = dev.genphy_resume();
> Why not `?` the possible error?
>
>> +
>> +        PhyRockchip::helper_config_init(dev)
>> +    }
>> +}
>>
>> --
>> 2.43.0
>>
> As Greg and Dragan mentioned, duplicate drivers are generally not
> accepted in-tree to avoid double maintenance and confusing config. Is
> there a specific goal?
>
> It is quite alright to request feedback on Rust drivers (and I have
> provided some) or even ask if anyone is willing to help test it out,
> but please use RFC PATCH and make it clear that this is for
> experimentation rather than upstreaming.
>
> Netdev has seemed relatively open to adding Rust drivers for new phys
> that don't have a C implementation, but these phys are of course
> tougher to find.
>
> Also for future reference, changes intended for the net tree should be
> labeled [PATCH v? net-next].
>
> Best regards,
> Trevor


From eahariha at linux.microsoft.com  Tue Feb  6 11:58:16 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Tue,  6 Feb 2024 19:58:16 +0000
Subject: [RFC PATCH] KVM: arm64: Override Microsoft Azure Cobalt 100 MIDR value with ARM Neoverse N2
Message-ID: <20240206195819.1146693-1-eahariha@linux.microsoft.com>

Several workload optimizations and errata depend on validating that the
optimization or errata are applicable to the particular CPU by checking
the MIDR_EL1 system register value. With the Microsoft implementer ID
for Azure Cobalt 100, the value doesn't match and ~20-25% performance
regression is seen in these workloads. Override the Azure Cobalt 100
value and replace it with the default ARM Neoverse N2 value that Azure
Cobalt 100 is based on.

Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>
---
 arch/arm64/include/asm/cputype.h   | 3 ++-
 arch/arm64/include/asm/el2_setup.h | 5 +++++
 arch/arm64/kvm/sys_regs.c          | 9 ++++++++-
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 7c7493cb571f..0450c6c32377 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -262,7 +262,8 @@ is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
  */
 static inline u32 __attribute_const__ read_cpuid_id(void)
 {
-	return read_cpuid(MIDR_EL1);
+	return (read_cpuid(MIDR_EL1) == 0x6D0FD490 ? 0x410FD490 :
+			read_cpuid(MIDR_EL1));
 }
 
 static inline u64 __attribute_const__ read_cpuid_mpidr(void)
diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index b7afaa026842..502a14e54a31 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -138,6 +138,11 @@
 .macro __init_el2_nvhe_idregs
 	mrs	x0, midr_el1
 	mrs	x1, mpidr_el1
+	ldr	x2, =0x6D0FD490
+	cmp	x0, x2
+	bne	.Loverride_cobalt100_\@
+	ldr	x0, =0x410FD490
+.Loverride_cobalt100_\@:
 	msr	vpidr_el2, x0
 	msr	vmpidr_el2, x1
 .endm
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 30253bd19917..8ea9c7fdabdb 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3574,7 +3574,14 @@ id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id,
 		return ((struct sys_reg_desc *)r)->val;			\
 	}
 
-FUNCTION_INVARIANT(midr_el1)
+static u64 get_midr_el1(struct kvm_vcpu *v, const struct sys_reg_desc *r)
+{
+	((struct sys_reg_desc *)r)->val = read_sysreg(midr_el1);
+	if (((struct sys_reg_desc *)r)->val == 0x6D0FD490)
+		((struct sys_reg_desc *)r)->val == 0x410FD490;
+	return ((struct sys_reg_desc *)r)->val;
+}
+
 FUNCTION_INVARIANT(revidr_el1)
 FUNCTION_INVARIANT(aidr_el1)
 
-- 
2.34.1



From dlechner at baylibre.com  Tue Feb  6 12:06:46 2024
From: dlechner at baylibre.com (David Lechner)
Date: Tue,  6 Feb 2024 14:06:46 -0600
Subject: [PATCH] spi: drop gpf arg from __spi_split_transfer_maxsize()
Message-ID: <20240206200648.1782234-1-dlechner@baylibre.com>

The __spi_split_transfer_maxsize() function has a gpf argument to allow
callers to specify the type of memory allocation that needs to be used.
However, this function only allocates struct spi_transfer and is not
intended to be used from atomic contexts so this type should always be
GFP_KERNEL, so we can just drop the argument.

Some callers of these functions also passed GFP_DMA, but since only
struct spi_transfer is allocated and not any tx/rx buffers, this is
not actually necessary and is removed in this commit.

Signed-off-by: David Lechner <dlechner at baylibre.com>
---
 drivers/spi/spi-stm32.c |  4 +---
 drivers/spi/spi.c       | 22 ++++++++--------------
 include/linux/spi/spi.h |  6 ++----
 3 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index e61302ef3c21..c32e57bb38bd 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -1170,9 +1170,7 @@ static int stm32_spi_prepare_msg(struct spi_controller *ctrl,
 	if (spi->cfg->set_number_of_data) {
 		int ret;
 
-		ret = spi_split_transfers_maxwords(ctrl, msg,
-						   spi->t_size_max,
-						   GFP_KERNEL | GFP_DMA);
+		ret = spi_split_transfers_maxwords(ctrl, msg, spi->t_size_max);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index a8b8474abc74..99ffc179f77d 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1756,7 +1756,7 @@ static int __spi_pump_transfer_message(struct spi_controller *ctlr,
 	 */
 	if ((msg->spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
 					       spi_is_csgpiod(msg->spi))) {
-		ret = spi_split_transfers_maxwords(ctlr, msg, 1, GFP_KERNEL);
+		ret = spi_split_transfers_maxwords(ctlr, msg, 1);
 		if (ret) {
 			msg->status = ret;
 			spi_finalize_current_message(ctlr);
@@ -1771,8 +1771,7 @@ static int __spi_pump_transfer_message(struct spi_controller *ctlr,
 		}
 	} else {
 		ret = spi_split_transfers_maxsize(ctlr, msg,
-						  spi_max_transfer_size(msg->spi),
-						  GFP_KERNEL | GFP_DMA);
+						  spi_max_transfer_size(msg->spi));
 		if (ret) {
 			msg->status = ret;
 			spi_finalize_current_message(ctlr);
@@ -3711,8 +3710,7 @@ static struct spi_replaced_transfers *spi_replace_transfers(
 static int __spi_split_transfer_maxsize(struct spi_controller *ctlr,
 					struct spi_message *msg,
 					struct spi_transfer **xferp,
-					size_t maxsize,
-					gfp_t gfp)
+					size_t maxsize)
 {
 	struct spi_transfer *xfer = *xferp, *xfers;
 	struct spi_replaced_transfers *srt;
@@ -3723,7 +3721,7 @@ static int __spi_split_transfer_maxsize(struct spi_controller *ctlr,
 	count = DIV_ROUND_UP(xfer->len, maxsize);
 
 	/* Create replacement */
-	srt = spi_replace_transfers(msg, xfer, 1, count, NULL, 0, gfp);
+	srt = spi_replace_transfers(msg, xfer, 1, count, NULL, 0, GFP_KERNEL);
 	if (IS_ERR(srt))
 		return PTR_ERR(srt);
 	xfers = srt->inserted_transfers;
@@ -3783,14 +3781,12 @@ static int __spi_split_transfer_maxsize(struct spi_controller *ctlr,
  * @ctlr:    the @spi_controller for this transfer
  * @msg:   the @spi_message to transform
  * @maxsize:  the maximum when to apply this
- * @gfp: GFP allocation flags
  *
  * Return: status of transformation
  */
 int spi_split_transfers_maxsize(struct spi_controller *ctlr,
 				struct spi_message *msg,
-				size_t maxsize,
-				gfp_t gfp)
+				size_t maxsize)
 {
 	struct spi_transfer *xfer;
 	int ret;
@@ -3805,7 +3801,7 @@ int spi_split_transfers_maxsize(struct spi_controller *ctlr,
 	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
 		if (xfer->len > maxsize) {
 			ret = __spi_split_transfer_maxsize(ctlr, msg, &xfer,
-							   maxsize, gfp);
+							   maxsize);
 			if (ret)
 				return ret;
 		}
@@ -3823,14 +3819,12 @@ EXPORT_SYMBOL_GPL(spi_split_transfers_maxsize);
  * @ctlr:     the @spi_controller for this transfer
  * @msg:      the @spi_message to transform
  * @maxwords: the number of words to limit each transfer to
- * @gfp:      GFP allocation flags
  *
  * Return: status of transformation
  */
 int spi_split_transfers_maxwords(struct spi_controller *ctlr,
 				 struct spi_message *msg,
-				 size_t maxwords,
-				 gfp_t gfp)
+				 size_t maxwords)
 {
 	struct spi_transfer *xfer;
 
@@ -3848,7 +3842,7 @@ int spi_split_transfers_maxwords(struct spi_controller *ctlr,
 		maxsize = maxwords * roundup_pow_of_two(BITS_TO_BYTES(xfer->bits_per_word));
 		if (xfer->len > maxsize) {
 			ret = __spi_split_transfer_maxsize(ctlr, msg, &xfer,
-							   maxsize, gfp);
+							   maxsize);
 			if (ret)
 				return ret;
 		}
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 9e3866809a0e..1ec2c07eb711 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -1365,12 +1365,10 @@ struct spi_replaced_transfers {
 
 extern int spi_split_transfers_maxsize(struct spi_controller *ctlr,
 				       struct spi_message *msg,
-				       size_t maxsize,
-				       gfp_t gfp);
+				       size_t maxsize);
 extern int spi_split_transfers_maxwords(struct spi_controller *ctlr,
 					struct spi_message *msg,
-					size_t maxwords,
-					gfp_t gfp);
+					size_t maxwords);
 
 /*---------------------------------------------------------------------------*/
 
-- 
2.43.0



From rdunlap at infradead.org  Tue Feb  6 12:23:21 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Tue, 6 Feb 2024 12:23:21 -0800
Subject: [PATCH] arm64: Add the arm64.no32bit_el0 command line option
In-Reply-To: <20240206185459.32465-1-andrea.porta@suse.com>
References: <20240206185459.32465-1-andrea.porta@suse.com>
Message-ID: <7c0dd2f1-0b43-425e-8b0e-004760bed317@infradead.org>

Hi--

On 2/6/24 10:54, Andrea della Porta wrote:
> Introducing the field 'el0' to the idreg-override for register
> ID_AA64PFR0_EL1. This field is also aliased to the new kernel
> command line option 'arm64.no32bit_el0' as a more recognizable
> and mnemonic name to disable the execution of 32 bit userspace
> applications (i.e. avoid Aarch32 execution state in EL0) from
> kernel command line.
> 
> Link: https://lore.kernel.org/r/ZVTleETzfFUchs77 at apocalypse
> Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
> ---
>  Documentation/admin-guide/kernel-parameters.txt | 3 +++
>  arch/arm64/kernel/idreg-override.c              | 2 ++
>  2 files changed, 5 insertions(+)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 65731b060e3f..9f962deeef5a 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -433,6 +433,9 @@
>  	arm64.nosve	[ARM64] Unconditionally disable Scalable Vector
>  			Extension support
>  
> +	arm64.no32bit_el0 [ARM64] Unconditionally disable the execution of
> +			32 bit applications
> +

That new entry is not in alphabetical order like it should be.

>  	ataflop=	[HW,M68k]
>  
>  	atarimouse=	[HW,MOUSE] Atari Mouse


-- 
#Randy


From seanjc at google.com  Tue Feb  6 12:36:22 2024
From: seanjc at google.com (Sean Christopherson)
Date: Tue, 6 Feb 2024 12:36:22 -0800
Subject: [PATCH v8 10/10] KVM: selftests: Add a basic SEV smoke test
In-Reply-To: <20240203000917.376631-11-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com> <20240203000917.376631-11-seanjc@google.com>
Message-ID: <ZcKYRsNUAngWGy2a@google.com>

On Fri, Feb 02, 2024, Sean Christopherson wrote:
> +int main(int argc, char *argv[])
> +{
> +	TEST_REQUIRE(is_kvm_sev_supported());

This also needs

	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV));

to handle the case where the platform supports SEV, i.e. /dev/sev exists, but
KVM doesn't support SEV, e.g. if TDP is disabled, if SEV was explicitly disabled
via module param, etc.


From ilkka at os.amperecomputing.com  Tue Feb  6 13:04:27 2024
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Tue, 6 Feb 2024 13:04:27 -0800 (PST)
Subject: [PATCH] perf/arm-cmn: Workaround AmpereOneX errata AC04_MESH_1
 (incorrect child count)
In-Reply-To: <dd862d7a-11bd-482a-b248-60d4616fb6ef@arm.com>
References: <20240205194655.1567434-1-ilkka@os.amperecomputing.com> <dd862d7a-11bd-482a-b248-60d4616fb6ef@arm.com>
Message-ID: <8bf2275a-dea7-1817-731a-7d47d3b01d13@os.amperecomputing.com>



On Tue, 6 Feb 2024, Robin Murphy wrote:
> On 2024-02-05 7:46 pm, Ilkka Koskinen wrote:
>> AmpereOneX mesh implementation has a bug in HN-P nodes that makes them
>> report incorrect child count. The failing crosspoints report 8 children
>> while they only have two.
>
> Ooh, fun :)
>
>> When the driver tries to access the inexistent child nodes, it believes it
>> has reached an invalid node type and probing fails. The workaround is to
>> ignore those incorrect child nodes and continue normally.
>> 
>> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
>> ---
>>   drivers/perf/arm-cmn.c | 25 +++++++++++++++++++++++++
>>   1 file changed, 25 insertions(+)
>> 
>> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
>> index c584165b13ba..97fed8ec3693 100644
>> --- a/drivers/perf/arm-cmn.c
>> +++ b/drivers/perf/arm-cmn.c
>> @@ -2168,6 +2168,23 @@ static enum cmn_node_type arm_cmn_subtype(enum 
>> cmn_node_type type)
>>   	}
>>   }
>>   +static inline bool arm_cmn_is_ampereonex_bug(const struct arm_cmn *cmn,
>> +					     struct arm_cmn_node *dn,
>> +					     u16 child_count, int child)
>> +{
>> +	/*
>> +	 * The bug occurs only when a crosspoint reports 8 children
>> +	 * while it only has two HN-P child nodes.
>> +	 */
>> +	dn -= 2;
>> +
>> +	if (arm_cmn_model(cmn) == CMN650 && child_count == 8 &&
>> +	    child == 2 && dn->type == CMN_TYPE_HNP)
>> +		return true;
>> +
>> +	return false;
>> +}
>> +
>>   static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
>>   {
>>   	void __iomem *cfg_region;
>> @@ -2292,6 +2309,14 @@ static int arm_cmn_discover(struct arm_cmn *cmn, 
>> unsigned int rgn_offset)
>>     		for (j = 0; j < child_count; j++) {
>>   			reg = readq_relaxed(xp_region + child_poff + j * 8);
>> +			if (reg == 0)
>> +				if (arm_cmn_is_ampereonex_bug(cmn, dn, 
>> child_count, j))
>> +					/*
>> +					 * We know there are only two real 
>> children and the rest 6
>> +					 * are inexistent. Thus, we can skip 
>> the rest of the loop
>> +					 */
>> +					break;
>> +
>
> TBH I don't see much harm in taking an even simpler approach, so I'd be
> inclined to not bother being all that specific beyond documenting it,
> something like the below:

Sounds good to me.

>
> Cheers,
> Robin.
>
> ----->8-----
>
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index c584165b13ba..7e3aa7e2345f 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -2305,6 +2305,17 @@ static int arm_cmn_discover(struct arm_cmn *cmn, 
> unsigned int rgn_offset)
> 				dev_dbg(cmn->dev, "ignoring external node 
> %llx\n", reg);
> 				continue;
> 			}
> +			/*
> +			 * AmpereOneX erratum AC04_MESH_1 makes some XPs 
> report a bogus
> +			 * child count larger than the number of valid child 
> pointers.
> +			 * A child offset of 0 can only occur on CMN-600; 
> otherwise it
> +			 * would imply the root node being its own 
> grandchild, which
> +			 * we can safely dismiss in general.
> +			 */
> +			if (reg == 0 && cmn->part != PART_CMN600) {
> +				dev_dbg(cmn->dev, "bogus child pointer?\n");
> +				continue;
> +			}
>  			arm_cmn_init_node_info(cmn, reg & 
> CMN_CHILD_NODE_ADDR, dn);
>

Tested-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>

Cheers, Ilkka


From tmgross at umich.edu  Tue Feb  6 13:30:56 2024
From: tmgross at umich.edu (Trevor Gross)
Date: Tue, 6 Feb 2024 16:30:56 -0500
Subject: [PATCH v2 3/3] net: phy: add Rust Rockchip PHY driver
In-Reply-To: <eb229460-0efc-448a-863f-ac0634a72f2c@christina-quast.de>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
 <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>
 <CALNs47tnwCgyvM2jBo=bTt1=2AJFt3b6W+JsTHM3Np2tbNJYCA@mail.gmail.com> <eb229460-0efc-448a-863f-ac0634a72f2c@christina-quast.de>
Message-ID: <CALNs47tfmcayLdbLbArPS=AHwETiaQKZ09h69_Q4HmfrMPk4-A@mail.gmail.com>

On Tue, Feb 6, 2024 at 2:20?PM Christina Quast
<chrysh at christina-quast.de> wrote:
>
> Hi Trevor!
>
> Thanks a lot for your review, I learned a lot! I felt, from the feedback
> in the Zulip forum that rewriting more phy drivers might be interesting,
> but I think I misunderstood something.
>
> There is no specific goal behind the rewrite, I just thought it would be
> useful to bring more Rust into the Kernel.
>
> Cheers,
>
> Christina

Happy to help :)

There is definitely no harm in experimenting, but the general
(reasonable) rule is that there shouldn't be duplicate drivers
in-tree, even across languages.

What you probably saw on Zulip is that we were trying to locate newer
phys that don't already have a C driver. Shashwat reached out to a few
companies and mentioned that Microchip was interested in drivers for
some of their VSC84xx/82xx families. They are a bit more complicated
(MACSec, XFI/SFP+) and apparently somewhat difficult to get hardware
for, but that might be an option if you are interested in working on
something like this.

Andrew might have some ideas too. There are a lot of new phys coming
out since MACsec is getting more popular, also some newer specs like
10GBase-T1 and 10Base-T1S.

- Trevor


From srinivas.kandagatla at linaro.org  Tue Feb  6 14:07:59 2024
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 6 Feb 2024 22:07:59 +0000
Subject: [PATCH 1/4] nvmem: core: Read into buffers larger than data
In-Reply-To: <20240206143711.2410135-2-msp@baylibre.com>
References: <20240206143711.2410135-1-msp@baylibre.com>
 <20240206143711.2410135-2-msp@baylibre.com>
Message-ID: <bffe2a23-d3fc-499d-825a-e2fd3c7a9d7f@linaro.org>



On 06/02/2024 14:37, Markus Schneider-Pargmann wrote:
> The actual size that nvmem is using internally on a specific platform
> with a specific devicetree may not be known in the consumer code. The
> maximum size may be available at the same time.
> 
> Allow the use of larger buffers in nvmem_cell_read_common() by setting
> buffers that are too large to zero before copying into them.
> 
Can you explain why can we not use nvmem_cell_read() ?



there is an other thread to add get_size
https://www.spinics.net/lists/kernel/msg5075254.html

> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> ---
>   drivers/nvmem/core.c | 6 ++++--
>   1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
> index 980123fb4dde..6fa061ede605 100644
> --- a/drivers/nvmem/core.c
> +++ b/drivers/nvmem/core.c
> @@ -1806,12 +1806,14 @@ static int nvmem_cell_read_common(struct device *dev, const char *cell_id,
>   		nvmem_cell_put(cell);
>   		return PTR_ERR(buf);
>   	}
> -	if (len != count) {
> +	if (len > count) {
>   		kfree(buf);
>   		nvmem_cell_put(cell);
>   		return -EINVAL;
> +	} else if (len < count) {
> +		memset(val + len, 0, count - len);
no please.. this really does not belong here.

--srini
>   	}
> -	memcpy(val, buf, count);
> +	memcpy(val, buf, len);
>   	kfree(buf);
>   	nvmem_cell_put(cell);
>   


From Frank.Li at nxp.com  Tue Feb  6 14:59:03 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue,  6 Feb 2024 17:59:03 -0500
Subject: [PATCH 1/2] arm64: dts: imx8qm: add i2c4 and i2c4_lpcg node
Message-ID: <20240206225904.3565362-1-Frank.Li@nxp.com>

Add i2c4 and i2c4_lpcg node for imx8qm.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 .../boot/dts/freescale/imx8qm-ss-dma.dtsi     | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
index cafc1383115ab..11626fae5f97f 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
@@ -17,6 +17,32 @@ uart4_lpcg: clock-controller at 5a4a0000 {
 		power-domains = <&pd IMX_SC_R_UART_4>;
 	};
 
+	i2c4: i2c at 5a840000 {
+		compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x5a840000 0x4000>;
+		interrupts = <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		clocks = <&i2c4_lpcg 0>,
+			 <&i2c4_lpcg 1>;
+		clock-names = "per", "ipg";
+		assigned-clocks = <&clk IMX_SC_R_I2C_4 IMX_SC_PM_CLK_PER>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd IMX_SC_R_I2C_4>;
+		status = "disabled";
+	};
+
+	i2c4_lpcg: clock-controller at 5ac40000 {
+		compatible = "fsl,imx8qxp-lpcg";
+		reg = <0x5ac40000 0x10000>;
+		#clock-cells = <1>;
+		clocks = <&clk IMX_SC_R_I2C_4 IMX_SC_PM_CLK_PER>,
+			 <&dma_ipg_clk>;
+		clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+		clock-output-names = "i2c4_lpcg_clk",
+				     "i2c4_lpcg_ipg_clk";
+		power-domains = <&pd IMX_SC_R_I2C_4>;
+	};
+
 	can1_lpcg: clock-controller at 5ace0000 {
 		compatible = "fsl,imx8qxp-lpcg";
 		reg = <0x5ace0000 0x10000>;
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb  6 14:59:04 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue,  6 Feb 2024 17:59:04 -0500
Subject: [PATCH 2/2] arm64: dts: imx8qm: add i2c1 for imx8qm-mek board
In-Reply-To: <20240206225904.3565362-1-Frank.Li@nxp.com>
References: <20240206225904.3565362-1-Frank.Li@nxp.com>
Message-ID: <20240206225904.3565362-2-Frank.Li@nxp.com>

Add i2c1 for imx8qm-mek board.

Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qm-mek.dts | 26 ++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
index 6d50838ad17de..77ac0efdfaada 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
@@ -41,6 +41,18 @@ reg_usdhc2_vmmc: usdhc2-vmmc {
 	};
 };
 
+&i2c1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	clock-frequency = <100000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	pinctrl-1 = <&pinctrl_i2c1_gpio>;
+	scl-gpios = <&lsio_gpio0 14 GPIO_ACTIVE_HIGH>;
+	sda-gpios = <&lsio_gpio0 15 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
 &lpuart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_lpuart0>;
@@ -104,6 +116,20 @@ &usdhc2 {
 };
 
 &iomuxc {
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			IMX8QM_GPT0_CLK_DMA_I2C1_SCL 0x0600004c
+			IMX8QM_GPT0_CAPTURE_DMA_I2C1_SDA 0x0600004c
+		>;
+	};
+
+	pinctrl_i2c1_gpio: i2c1gpio-grp {
+		fsl,pins = <
+			IMX8QM_GPT0_CLK_LSIO_GPIO0_IO14		0xc600004c
+			IMX8QM_GPT0_CAPTURE_LSIO_GPIO0_IO15	0xc600004c
+		>;
+	};
+
 	pinctrl_fec1: fec1grp {
 		fsl,pins = <
 			IMX8QM_ENET0_MDC_CONN_ENET0_MDC				0x06000020
-- 
2.34.1



From andrew at lunn.ch  Tue Feb  6 15:00:41 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 7 Feb 2024 00:00:41 +0100
Subject: [PATCH v2 3/3] net: phy: add Rust Rockchip PHY driver
In-Reply-To: <CALNs47tfmcayLdbLbArPS=AHwETiaQKZ09h69_Q4HmfrMPk4-A@mail.gmail.com>
References: <20240201-rockchip-rust-phy_depend-v2-0-c5fa4faab924@christina-quast.de>
 <20240201-rockchip-rust-phy_depend-v2-3-c5fa4faab924@christina-quast.de>
 <CALNs47tnwCgyvM2jBo=bTt1=2AJFt3b6W+JsTHM3Np2tbNJYCA@mail.gmail.com>
 <eb229460-0efc-448a-863f-ac0634a72f2c@christina-quast.de>
 <CALNs47tfmcayLdbLbArPS=AHwETiaQKZ09h69_Q4HmfrMPk4-A@mail.gmail.com>
Message-ID: <8a95a80f-55da-4606-a55c-59b63a249178@lunn.ch>

> Andrew might have some ideas too. There are a lot of new phys coming
> out since MACsec is getting more popular, also some newer specs like
> 10GBase-T1 and 10Base-T1S.

Those can also be hard to get hold of, unless a vendor is interested.

Another source to look at might be OpenWRT and DD-WRT. These projects
are not always good at upstreaming. They sometimes just use the vendor
crap drivers. See if they have any PHY drivers for devices not in
mainline. Any they do have should be for COTS hardware you probably
can buy off the shelf.

    Andrew


From Frank.Li at nxp.com  Tue Feb  6 15:05:25 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue,  6 Feb 2024 18:05:25 -0500
Subject: [PATCH 1/1] arm64: dts: ls1088a: Add the PME interrupt for PCIe EP node
Message-ID: <20240206230525.3578868-1-Frank.Li@nxp.com>

From: Xiaowei Bao <xiaowei.bao at nxp.com>

Add the PME interrupt porperty in PCIe EP node.

Signed-off-by: Xiaowei Bao <xiaowei.bao at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index 8616d5e0c3884..604bf88d70b3a 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -591,6 +591,8 @@ pcie_ep1: pcie-ep at 3400000 {
 			reg = <0x00 0x03400000 0x0 0x00100000>,
 			      <0x20 0x00000000 0x8 0x00000000>;
 			reg-names = "regs", "addr_space";
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; /* PME interrupt */
+			interrupt-names = "pme";
 			num-ib-windows = <24>;
 			num-ob-windows = <256>;
 			max-functions = /bits/ 8 <2>;
@@ -628,6 +630,8 @@ pcie_ep2: pcie-ep at 3500000 {
 			reg = <0x00 0x03500000 0x0 0x00100000>,
 			      <0x28 0x00000000 0x8 0x00000000>;
 			reg-names = "regs", "addr_space";
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; /* PME interrupt */
+			interrupt-names = "pme";
 			num-ib-windows = <6>;
 			num-ob-windows = <6>;
 			status = "disabled";
@@ -664,6 +668,8 @@ pcie_ep3: pcie-ep at 3600000 {
 			reg = <0x00 0x03600000 0x0 0x00100000>,
 			      <0x30 0x00000000 0x8 0x00000000>;
 			reg-names = "regs", "addr_space";
+			interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; /* PME interrupt */
+			interrupt-names = "pme";
 			num-ib-windows = <6>;
 			num-ob-windows = <6>;
 			status = "disabled";
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb  6 15:15:21 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue,  6 Feb 2024 18:15:21 -0500
Subject: [PATCH 1/1] arm64: dts: lx2160a: Fix DTS for full PL011 UART
Message-ID: <20240206231521.3600089-1-Frank.Li@nxp.com>

From: Heinz Wrobel <Heinz.Wrobel at nxp.com>

The prior configuration was an SBSA UART that can't be configured or
modified, or even enabled if it isn't the boot console. With properly
defined clocks, the PL011 configuration can be used.

Signed-off-by: Heinz Wrobel <Heinz.Wrobel at nxp.com>
Signed-off-by: Li Yang <leoyang.li at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 32 ++++++++++++++-----
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index 6640b49670ae5..e665c629e1a1f 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -949,34 +949,50 @@ QORIQ_CLK_PLL_DIV(8)>,
 		};
 
 		uart0: serial at 21c0000 {
-			compatible = "arm,sbsa-uart","arm,pl011";
+			compatible = "arm,pl011", "arm,primecell";
+			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
+					    QORIQ_CLK_PLL_DIV(8)>,
+				 <&clockgen QORIQ_CLK_PLATFORM_PLL
+					    QORIQ_CLK_PLL_DIV(8)>;
+			clock-names = "uartclk", "apb_pclk";
 			reg = <0x0 0x21c0000 0x0 0x1000>;
 			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-			current-speed = <115200>;
 			status = "disabled";
 		};
 
 		uart1: serial at 21d0000 {
-			compatible = "arm,sbsa-uart","arm,pl011";
+			compatible = "arm,pl011", "arm,primecell";
+			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
+					    QORIQ_CLK_PLL_DIV(8)>,
+				 <&clockgen QORIQ_CLK_PLATFORM_PLL
+					    QORIQ_CLK_PLL_DIV(8)>;
+			clock-names = "uartclk", "apb_pclk";
 			reg = <0x0 0x21d0000 0x0 0x1000>;
 			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
-			current-speed = <115200>;
 			status = "disabled";
 		};
 
 		uart2: serial at 21e0000 {
-			compatible = "arm,sbsa-uart","arm,pl011";
+			compatible = "arm,pl011", "arm,primecell";
+			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
+					    QORIQ_CLK_PLL_DIV(8)>,
+				 <&clockgen QORIQ_CLK_PLATFORM_PLL
+					    QORIQ_CLK_PLL_DIV(8)>;
+			clock-names = "uartclk", "apb_pclk";
 			reg = <0x0 0x21e0000 0x0 0x1000>;
 			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
-			current-speed = <115200>;
 			status = "disabled";
 		};
 
 		uart3: serial at 21f0000 {
-			compatible = "arm,sbsa-uart","arm,pl011";
+			compatible = "arm,pl011", "arm,primecell";
+			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
+					    QORIQ_CLK_PLL_DIV(8)>,
+				 <&clockgen QORIQ_CLK_PLATFORM_PLL
+					    QORIQ_CLK_PLL_DIV(8)>;
+			clock-names = "uartclk", "apb_pclk";
 			reg = <0x0 0x21f0000 0x0 0x1000>;
 			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
-			current-speed = <115200>;
 			status = "disabled";
 		};
 
-- 
2.34.1



From linux at armlinux.org.uk  Tue Feb  6 15:17:58 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 6 Feb 2024 23:17:58 +0000
Subject: [PATCH REPOST v2] ARM64: Dynamically allocate cpumasks and
 increase supported CPUs to 512
In-Reply-To: <e0d41efb-a74e-6bb5-f325-63d42358c802@gentwo.org>
References: <e0d41efb-a74e-6bb5-f325-63d42358c802@gentwo.org>
Message-ID: <ZcK+JmY2KRfkdQj4@shell.armlinux.org.uk>

On Tue, Feb 06, 2024 at 10:09:59AM -0800, Christoph Lameter (Ampere) wrote:
> Can we get this merged for 6.9? The patch has been around for awhile now.
> 
> 
> 
> Ampere Computing develops high end ARM processor that support an ever
> increasing number of processors. The default 256 processors are
> not enough for our newer products. The default is used by
> distros and therefore our customers cannot use distro kernels because
> the number of processors is not supported.
> 
> One of the objections against earlier patches to increase the limit
> was that the memory use becomes too high. There is a feature called
> CPUMASK_OFFSTACK that configures the cpumasks in the kernel to be
> dynamically allocated. This was used in the X86 architecture in the
> past to enable support for larger CPU configurations up to 8k cpus.
> 
> With that is becomes possible to dynamically size the allocation of
> the cpu bitmaps depending on the quantity of processors detected on
> bootup.
> 
> This patch enables that logic if more than 256 processors
> are configured and increases the default to 512 processors.
> 
> Further increases may be needed if ARM processor vendors start
> supporting more processors. Given the current inflationary trends
> in core counts from multiple processor manufacturers this may occur.
> 
> Tested-by: Eric Mackay <eric.mackay at oracle.com>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Thanks!

> Signed-off-by: Christoph Lameter (Ampere) <cl at linux.com>

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


From abel.vesa at linaro.org  Tue Feb  6 15:33:41 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 07 Feb 2024 01:33:41 +0200
Subject: [PATCH RFC 0/2] spmi: Add multi master support
Message-ID: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>

Newer SPMI controller (v7) found on Qualcomm platforms
provide support for multiple bus master. So add support
for multiple masters in both the generic framework and
the Qualcomm SPMI PMIC Arbiter driver.

Currently, the DT child nodes of the spmi controller node
are the slave devices connected to the bus. This patchset
proposes another layer of nodes in between. They would be
the master bus nodes. They will not be populated as separate
devices as they need to share register regions with the controller.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
Abel Vesa (2):
      spmi: Add support for multi-master
      spmi: pmic-arb: Add support for multi-master

 drivers/spmi/spmi-mtk-pmif.c |   6 +-
 drivers/spmi/spmi-pmic-arb.c | 711 +++++++++++++++++++++++++++----------------
 drivers/spmi/spmi.c          |  76 +++--
 include/linux/spmi.h         |  10 +-
 4 files changed, 506 insertions(+), 297 deletions(-)
---
base-commit: ac139fc7db67968e5061715508b5fc4aa7c40c56
change-id: 20240207-spmi-multi-master-support-832a704b779b

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>



From abel.vesa at linaro.org  Tue Feb  6 15:33:42 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 07 Feb 2024 01:33:42 +0200
Subject: [PATCH RFC 1/2] spmi: Add support for multi-master
In-Reply-To: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
Message-ID: <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>

Some newer SPMI controllers support multiple bus masters.
Such a master can control multiple slave devices. The generic
framework needs to be able to pass on the master id to the
controller-specific driver. So do that. The framework will
check if the devicetree child nodes are actually bus masters
and will register the devices for each master. The legacy
approach will still be supported for backwards compatibility.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-mtk-pmif.c |  6 ++--
 drivers/spmi/spmi-pmic-arb.c | 10 +++---
 drivers/spmi/spmi.c          | 76 ++++++++++++++++++++++++++++++--------------
 include/linux/spmi.h         | 10 +++---
 4 files changed, 67 insertions(+), 35 deletions(-)

diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
index 5079442f8ea1..b19bb0351ff1 100644
--- a/drivers/spmi/spmi-mtk-pmif.c
+++ b/drivers/spmi/spmi-mtk-pmif.c
@@ -286,7 +286,7 @@ static bool pmif_is_fsm_vldclr(struct pmif *arb)
 	return GET_SWINF(reg_rdata) == SWINF_WFVLDCLR;
 }
 
-static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
+static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id, u8 sid)
 {
 	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
 	u32 rdata, cmd;
@@ -308,7 +308,7 @@ static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
 	return ret;
 }
 
-static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id, u8 sid,
 			      u16 addr, u8 *buf, size_t len)
 {
 	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
@@ -375,7 +375,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 	return 0;
 }
 
-static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id, u8 sid,
 			       u16 addr, const u8 *buf, size_t len)
 {
 	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 9ed1180fe31f..597207720146 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -341,7 +341,7 @@ pmic_arb_non_data_cmd_v2(struct spmi_controller *ctrl, u8 opc, u8 sid)
 }
 
 /* Non-data command */
-static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
+static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id, u8 sid)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
 
@@ -410,7 +410,7 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 	return 0;
 }
 
-static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id, u8 sid,
 			     u16 addr, u8 *buf, size_t len)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
@@ -486,7 +486,7 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      PMIC_ARB_CHANNEL_RW);
 }
 
-static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id, u8 sid,
 			      u16 addr, const u8 *buf, size_t len)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
@@ -568,7 +568,7 @@ static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
+	if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, 0, sid,
 			       (per << 8) + reg, buf, len))
 		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
@@ -580,7 +580,7 @@ static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, sid,
+	if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, 0, sid,
 			      (per << 8) + reg, buf, len))
 		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 3a60fd2e09e1..7dc778db7242 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -64,7 +64,7 @@ int spmi_device_add(struct spmi_device *sdev)
 	struct spmi_controller *ctrl = sdev->ctrl;
 	int err;
 
-	dev_set_name(&sdev->dev, "%d-%02x", ctrl->nr, sdev->usid);
+	dev_set_name(&sdev->dev, "%d-%02x-%02x", ctrl->nr, sdev->mid, sdev->usid);
 
 	err = device_add(&sdev->dev);
 	if (err < 0) {
@@ -91,19 +91,19 @@ void spmi_device_remove(struct spmi_device *sdev)
 EXPORT_SYMBOL_GPL(spmi_device_remove);
 
 static inline int
-spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid)
+spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 mid, u8 sid)
 {
 	int ret;
 
 	if (!ctrl || !ctrl->cmd || ctrl->dev.type != &spmi_ctrl_type)
 		return -EINVAL;
 
-	ret = ctrl->cmd(ctrl, opcode, sid);
+	ret = ctrl->cmd(ctrl, opcode, mid, sid);
 	trace_spmi_cmd(opcode, sid, ret);
 	return ret;
 }
 
-static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode,
+static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode, u8 mid,
 				u8 sid, u16 addr, u8 *buf, size_t len)
 {
 	int ret;
@@ -112,12 +112,12 @@ static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode,
 		return -EINVAL;
 
 	trace_spmi_read_begin(opcode, sid, addr);
-	ret = ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len);
+	ret = ctrl->read_cmd(ctrl, opcode, mid, sid, addr, buf, len);
 	trace_spmi_read_end(opcode, sid, addr, ret, len, buf);
 	return ret;
 }
 
-static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode,
+static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode, u8 mid,
 				 u8 sid, u16 addr, const u8 *buf, size_t len)
 {
 	int ret;
@@ -126,7 +126,7 @@ static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode,
 		return -EINVAL;
 
 	trace_spmi_write_begin(opcode, sid, addr, len, buf);
-	ret = ctrl->write_cmd(ctrl, opcode, sid, addr, buf, len);
+	ret = ctrl->write_cmd(ctrl, opcode, mid, sid, addr, buf, len);
 	trace_spmi_write_end(opcode, sid, addr, ret);
 	return ret;
 }
@@ -145,7 +145,7 @@ int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf)
 	if (addr > 0x1F)
 		return -EINVAL;
 
-	return spmi_read_cmd(sdev->ctrl, SPMI_CMD_READ, sdev->usid, addr,
+	return spmi_read_cmd(sdev->ctrl, SPMI_CMD_READ, sdev->mid, sdev->usid, addr,
 			     buf, 1);
 }
 EXPORT_SYMBOL_GPL(spmi_register_read);
@@ -167,7 +167,7 @@ int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
 	if (len == 0 || len > 16)
 		return -EINVAL;
 
-	return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READ, sdev->usid, addr,
+	return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READ, sdev->mid, sdev->usid, addr,
 			     buf, len);
 }
 EXPORT_SYMBOL_GPL(spmi_ext_register_read);
@@ -189,7 +189,7 @@ int spmi_ext_register_readl(struct spmi_device *sdev, u16 addr, u8 *buf,
 	if (len == 0 || len > 8)
 		return -EINVAL;
 
-	return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READL, sdev->usid, addr,
+	return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READL, sdev->mid, sdev->usid, addr,
 			     buf, len);
 }
 EXPORT_SYMBOL_GPL(spmi_ext_register_readl);
@@ -208,7 +208,7 @@ int spmi_register_write(struct spmi_device *sdev, u8 addr, u8 data)
 	if (addr > 0x1F)
 		return -EINVAL;
 
-	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_WRITE, sdev->usid, addr,
+	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_WRITE, sdev->mid, sdev->usid, addr,
 			      &data, 1);
 }
 EXPORT_SYMBOL_GPL(spmi_register_write);
@@ -222,7 +222,7 @@ EXPORT_SYMBOL_GPL(spmi_register_write);
  */
 int spmi_register_zero_write(struct spmi_device *sdev, u8 data)
 {
-	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_ZERO_WRITE, sdev->usid, 0,
+	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_ZERO_WRITE, sdev->mid, sdev->usid, 0,
 			      &data, 1);
 }
 EXPORT_SYMBOL_GPL(spmi_register_zero_write);
@@ -244,7 +244,7 @@ int spmi_ext_register_write(struct spmi_device *sdev, u8 addr, const u8 *buf,
 	if (len == 0 || len > 16)
 		return -EINVAL;
 
-	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_EXT_WRITE, sdev->usid, addr,
+	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_EXT_WRITE, sdev->mid, sdev->usid, addr,
 			      buf, len);
 }
 EXPORT_SYMBOL_GPL(spmi_ext_register_write);
@@ -266,7 +266,7 @@ int spmi_ext_register_writel(struct spmi_device *sdev, u16 addr, const u8 *buf,
 	if (len == 0 || len > 8)
 		return -EINVAL;
 
-	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_EXT_WRITEL, sdev->usid,
+	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_EXT_WRITEL, sdev->mid, sdev->usid,
 			      addr, buf, len);
 }
 EXPORT_SYMBOL_GPL(spmi_ext_register_writel);
@@ -281,7 +281,7 @@ EXPORT_SYMBOL_GPL(spmi_ext_register_writel);
  */
 int spmi_command_reset(struct spmi_device *sdev)
 {
-	return spmi_cmd(sdev->ctrl, SPMI_CMD_RESET, sdev->usid);
+	return spmi_cmd(sdev->ctrl, SPMI_CMD_RESET, sdev->mid, sdev->usid);
 }
 EXPORT_SYMBOL_GPL(spmi_command_reset);
 
@@ -293,7 +293,7 @@ EXPORT_SYMBOL_GPL(spmi_command_reset);
  */
 int spmi_command_sleep(struct spmi_device *sdev)
 {
-	return spmi_cmd(sdev->ctrl, SPMI_CMD_SLEEP, sdev->usid);
+	return spmi_cmd(sdev->ctrl, SPMI_CMD_SLEEP, sdev->mid, sdev->usid);
 }
 EXPORT_SYMBOL_GPL(spmi_command_sleep);
 
@@ -306,7 +306,7 @@ EXPORT_SYMBOL_GPL(spmi_command_sleep);
  */
 int spmi_command_wakeup(struct spmi_device *sdev)
 {
-	return spmi_cmd(sdev->ctrl, SPMI_CMD_WAKEUP, sdev->usid);
+	return spmi_cmd(sdev->ctrl, SPMI_CMD_WAKEUP, sdev->mid, sdev->usid);
 }
 EXPORT_SYMBOL_GPL(spmi_command_wakeup);
 
@@ -318,7 +318,7 @@ EXPORT_SYMBOL_GPL(spmi_command_wakeup);
  */
 int spmi_command_shutdown(struct spmi_device *sdev)
 {
-	return spmi_cmd(sdev->ctrl, SPMI_CMD_SHUTDOWN, sdev->usid);
+	return spmi_cmd(sdev->ctrl, SPMI_CMD_SHUTDOWN, sdev->mid, sdev->usid);
 }
 EXPORT_SYMBOL_GPL(spmi_command_shutdown);
 
@@ -477,15 +477,16 @@ struct spmi_controller *spmi_controller_alloc(struct device *parent,
 }
 EXPORT_SYMBOL_GPL(spmi_controller_alloc);
 
-static void of_spmi_register_devices(struct spmi_controller *ctrl)
+static void of_spmi_register_devices(struct spmi_controller *ctrl,
+				     struct device_node *parent, u8 mid)
 {
 	struct device_node *node;
 	int err;
 
-	if (!ctrl->dev.of_node)
+	if (!parent)
 		return;
 
-	for_each_available_child_of_node(ctrl->dev.of_node, node) {
+	for_each_available_child_of_node(parent, node) {
 		struct spmi_device *sdev;
 		u32 reg[2];
 
@@ -519,6 +520,7 @@ static void of_spmi_register_devices(struct spmi_controller *ctrl)
 
 		sdev->dev.of_node = node;
 		sdev->usid = (u8)reg[0];
+		sdev->mid = mid;
 
 		err = spmi_device_add(sdev);
 		if (err) {
@@ -529,6 +531,30 @@ static void of_spmi_register_devices(struct spmi_controller *ctrl)
 	}
 }
 
+static int of_spmi_register_bus_masters(struct spmi_controller *ctrl)
+{
+	struct device_node *node = ctrl->dev.of_node, *child;
+	int mid = 0;
+
+	for_each_available_child_of_node(node, child) {
+		if (of_node_name_eq(child, "spmi-bus-master"))
+			of_spmi_register_devices(ctrl, child, mid++);
+	}
+
+	return 0;
+}
+
+static bool of_spmi_has_bus_multi_master(struct spmi_controller *ctrl)
+{
+	struct device_node *node = ctrl->dev.of_node, *child;
+
+	for_each_available_child_of_node(node, child)
+		if (of_node_name_eq(child, "spmi-bus-master"))
+			return true;
+
+	return false;
+}
+
 /**
  * spmi_controller_add() - Add an SPMI controller
  * @ctrl:	controller to be registered.
@@ -548,8 +574,12 @@ int spmi_controller_add(struct spmi_controller *ctrl)
 	if (ret)
 		return ret;
 
-	if (IS_ENABLED(CONFIG_OF))
-		of_spmi_register_devices(ctrl);
+	if (IS_ENABLED(CONFIG_OF)) {
+		if (of_spmi_has_bus_multi_master(ctrl))
+			of_spmi_register_bus_masters(ctrl);
+		else
+			of_spmi_register_devices(ctrl, ctrl->dev.of_node, 0);
+	}
 
 	dev_dbg(&ctrl->dev, "spmi-%d registered: dev:%p\n",
 		ctrl->nr, &ctrl->dev);
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index 28e8c8bd3944..6e9031df47f0 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -34,12 +34,14 @@
  * struct spmi_device - Basic representation of an SPMI device
  * @dev:	Driver model representation of the device.
  * @ctrl:	SPMI controller managing the bus hosting this device.
- * @usid:	This devices' Unique Slave IDentifier.
+ * @usid:	This device's Unique Slave IDentifier.
+ * @mid:	This device's Bus Master IDentifier.
  */
 struct spmi_device {
 	struct device		dev;
 	struct spmi_controller	*ctrl;
 	u8			usid;
+	u8			mid;
 };
 
 static inline struct spmi_device *to_spmi_device(struct device *d)
@@ -80,10 +82,10 @@ void spmi_device_remove(struct spmi_device *sdev);
 struct spmi_controller {
 	struct device		dev;
 	unsigned int		nr;
-	int	(*cmd)(struct spmi_controller *ctrl, u8 opcode, u8 sid);
-	int	(*read_cmd)(struct spmi_controller *ctrl, u8 opcode,
+	int	(*cmd)(struct spmi_controller *ctrl, u8 opcode, u8 mid, u8 sid);
+	int	(*read_cmd)(struct spmi_controller *ctrl, u8 opcode, u8 mid,
 			    u8 sid, u16 addr, u8 *buf, size_t len);
-	int	(*write_cmd)(struct spmi_controller *ctrl, u8 opcode,
+	int	(*write_cmd)(struct spmi_controller *ctrl, u8 opcode, u8 mid,
 			     u8 sid, u16 addr, const u8 *buf, size_t len);
 };
 

-- 
2.34.1



From abel.vesa at linaro.org  Tue Feb  6 15:33:43 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 07 Feb 2024 01:33:43 +0200
Subject: [PATCH RFC 2/2] spmi: pmic-arb: Add support for multi-master
In-Reply-To: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
Message-ID: <20240207-spmi-multi-master-support-v1-2-ce57f301c7fd@linaro.org>

The v7 HW supports currently 2 masters. So register
each master and adapt all ops to pass on the master id.
Legacy mode is still supported as long as there is no
child node that represents a bus master, but rather all
devicetree child nodes are actual slave decices.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 711 +++++++++++++++++++++++++++----------------
 1 file changed, 444 insertions(+), 267 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 597207720146..4a281da3310c 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -13,6 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spmi.h>
@@ -125,6 +127,25 @@ struct apid_data {
 	u8		irq_ee;
 };
 
+struct spmi_pmic_arb;
+
+struct spmi_pmic_master {
+	struct spmi_pmic_arb	*pmic_arb;
+	struct irq_domain	*domain;
+	void __iomem		*intr;
+	void __iomem		*cnfg;
+	u32			bus_instance;
+	u16			base_apid;
+	int			apid_count;
+	u16			*ppid_to_apid;
+	u16			last_apid;
+	struct apid_data	*apid_data;
+	u16			min_apid;
+	u16			max_apid;
+	int			irq;
+	u8			id;
+};
+
 /**
  * struct spmi_pmic_arb - SPMI PMIC Arbiter object
  *
@@ -155,34 +176,26 @@ struct apid_data {
 struct spmi_pmic_arb {
 	void __iomem		*rd_base;
 	void __iomem		*wr_base;
-	void __iomem		*intr;
-	void __iomem		*cnfg;
 	void __iomem		*core;
 	resource_size_t		core_size;
 	raw_spinlock_t		lock;
 	u8			channel;
-	int			irq;
 	u8			ee;
 	u32			bus_instance;
-	u16			min_apid;
-	u16			max_apid;
-	u16			base_apid;
-	int			apid_count;
 	u32			*mapping_table;
 	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
-	struct irq_domain	*domain;
 	struct spmi_controller	*spmic;
 	const struct pmic_arb_ver_ops *ver_ops;
-	u16			*ppid_to_apid;
-	u16			last_apid;
-	struct apid_data	*apid_data;
 	int			max_periphs;
+	struct spmi_pmic_master *masters;
+	int			masters_count;
 };
 
 /**
  * struct pmic_arb_ver_ops - version dependent functionality.
  *
  * @ver_str:		version string.
+ * @init_apid:		finds the apid base and count
  * @ppid_to_apid:	finds the apid for a given ppid.
  * @non_data_cmd:	on v1 issues an spmi non-data command.
  *			on v2 no HW support, returns -EOPNOTSUPP.
@@ -202,20 +215,21 @@ struct spmi_pmic_arb {
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
-	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
+	int (*init_apid)(struct spmi_pmic_master *master);
+	int (*ppid_to_apid)(struct spmi_pmic_master *master, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
-	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type);
+	int (*offset)(struct spmi_pmic_master *master, u8 sid, u16 addr,
+		      enum pmic_arb_channel ch_type);
 	u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
 	int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
 	/* Interrupts controller functionality (offset of PIC registers) */
-	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb *pmic_arb, u8 m,
+	void __iomem *(*owner_acc_status)(struct spmi_pmic_master *master, u8 m,
 					  u16 n);
-	void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*acc_enable)(struct spmi_pmic_master *master, u16 n);
+	void __iomem *(*irq_status)(struct spmi_pmic_master *master, u16 n);
+	void __iomem *(*irq_clear)(struct spmi_pmic_master *master, u16 n);
 	u32 (*apid_map_offset)(u16 n);
-	void __iomem *(*apid_owner)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*apid_owner)(struct spmi_pmic_master *master, u16 n);
 };
 
 static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -260,16 +274,17 @@ static void pmic_arb_write_data(struct spmi_pmic_arb *pmic_arb, const u8 *buf,
 }
 
 static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
-				  void __iomem *base, u8 sid, u16 addr,
+				  void __iomem *base, u8 mid, u8 sid, u16 addr,
 				  enum pmic_arb_channel ch_type)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_master *master = &pmic_arb->masters[mid];
 	u32 status = 0;
 	u32 timeout = PMIC_ARB_TIMEOUT_US;
 	u32 offset;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type);
+	rc = pmic_arb->ver_ops->offset(master, sid, addr, ch_type);
 	if (rc < 0)
 		return rc;
 
@@ -287,8 +302,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 			}
 
 			if (status & PMIC_ARB_STATUS_FAILURE) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction failed (%#x) reg: 0x%x\n",
+					__func__, sid, mid, addr, status, offset);
 				WARN_ON(1);
 				return -EIO;
 			}
@@ -313,12 +328,13 @@ static int
 pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_master *master = &pmic_arb->masters[0];
 	unsigned long flags;
 	u32 cmd;
 	int rc;
 	u32 offset;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW);
+	rc = pmic_arb->ver_ops->offset(master, sid, 0, PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
@@ -327,7 +343,7 @@ pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid)
 
 	raw_spin_lock_irqsave(&pmic_arb->lock, flags);
 	pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
-	rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0,
+	rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, 0, sid, 0,
 				    PMIC_ARB_CHANNEL_RW);
 	raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
 
@@ -341,7 +357,7 @@ pmic_arb_non_data_cmd_v2(struct spmi_controller *ctrl, u8 opc, u8 sid)
 }
 
 /* Non-data command */
-static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id, u8 sid)
+static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 mid, u8 sid)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
 
@@ -354,13 +370,14 @@ static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id, u8 s
 	return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid);
 }
 
-static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 sid,
+static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 mid, u8 sid,
 				 u16 addr, size_t len, u32 *cmd, u32 *offset)
 {
+	struct spmi_pmic_master *master = &pmic_arb->masters[mid];
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(master, sid, addr,
 				       PMIC_ARB_CHANNEL_OBS);
 	if (rc < 0)
 		return rc;
@@ -388,7 +405,7 @@ static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 sid,
 }
 
 static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
-				      u32 offset, u8 sid, u16 addr, u8 *buf,
+				      u32 offset, u8 mid, u8 sid, u16 addr, u8 *buf,
 				      size_t len)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
@@ -396,7 +413,7 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 	int rc;
 
 	pmic_arb_set_rd_cmd(pmic_arb, offset + PMIC_ARB_CMD, cmd);
-	rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, sid, addr,
+	rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, mid, sid, addr,
 				    PMIC_ARB_CHANNEL_OBS);
 	if (rc)
 		return rc;
@@ -410,7 +427,7 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 	return 0;
 }
 
-static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id, u8 sid,
+static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 mid, u8 sid,
 			     u16 addr, u8 *buf, size_t len)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
@@ -418,26 +435,27 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id,
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_read_cmd(pmic_arb, opc, mid, sid, addr, len, &cmd,
 				   &offset);
 	if (rc)
 		return rc;
 
 	raw_spin_lock_irqsave(&pmic_arb->lock, flags);
-	rc = pmic_arb_read_cmd_unlocked(ctrl, cmd, offset, sid, addr, buf, len);
+	rc = pmic_arb_read_cmd_unlocked(ctrl, cmd, offset, mid, sid, addr, buf, len);
 	raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
 
 	return rc;
 }
 
-static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc,
+static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 mid,
 				  u8 sid, u16 addr, size_t len, u32 *cmd,
 				  u32 *offset)
 {
+	struct spmi_pmic_master *master = &pmic_arb->masters[mid];
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(master, sid, addr,
 					PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
@@ -467,7 +485,7 @@ static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc,
 }
 
 static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
-				      u32 offset, u8 sid, u16 addr,
+				      u32 offset, u8 mid, u8 sid, u16 addr,
 				      const u8 *buf, size_t len)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
@@ -482,11 +500,11 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 
 	/* Start the transaction */
 	pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
-	return pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, addr,
+	return pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, mid, sid, addr,
 				      PMIC_ARB_CHANNEL_RW);
 }
 
-static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id, u8 sid,
+static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 mid, u8 sid,
 			      u16 addr, const u8 *buf, size_t len)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
@@ -494,20 +512,20 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 master_id
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_write_cmd(pmic_arb, opc, mid, sid, addr, len, &cmd,
 				    &offset);
 	if (rc)
 		return rc;
 
 	raw_spin_lock_irqsave(&pmic_arb->lock, flags);
-	rc = pmic_arb_write_cmd_unlocked(ctrl, cmd, offset, sid, addr, buf,
+	rc = pmic_arb_write_cmd_unlocked(ctrl, cmd, offset, mid, sid, addr, buf,
 					 len);
 	raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
 
 	return rc;
 }
 
-static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr,
+static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 mid, u8 sid, u16 addr,
 				 const u8 *buf, const u8 *mask, size_t len)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
@@ -516,18 +534,18 @@ static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr,
 	unsigned long flags;
 	int rc, i;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, SPMI_CMD_EXT_READL, sid, addr, len,
+	rc = pmic_arb_fmt_read_cmd(pmic_arb, SPMI_CMD_EXT_READL, mid, sid, addr, len,
 				   &read_cmd, &read_offset);
 	if (rc)
 		return rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, SPMI_CMD_EXT_WRITEL, sid, addr,
+	rc = pmic_arb_fmt_write_cmd(pmic_arb, SPMI_CMD_EXT_WRITEL, mid, sid, addr,
 				    len, &write_cmd, &write_offset);
 	if (rc)
 		return rc;
 
 	raw_spin_lock_irqsave(&pmic_arb->lock, flags);
-	rc = pmic_arb_read_cmd_unlocked(ctrl, read_cmd, read_offset, sid, addr,
+	rc = pmic_arb_read_cmd_unlocked(ctrl, read_cmd, read_offset, mid, sid, addr,
 					temp, len);
 	if (rc)
 		goto done;
@@ -535,7 +553,7 @@ static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr,
 	for (i = 0; i < len; i++)
 		temp[i] = (temp[i] & ~mask[i]) | (buf[i] & mask[i]);
 
-	rc = pmic_arb_write_cmd_unlocked(ctrl, write_cmd, write_offset, sid,
+	rc = pmic_arb_write_cmd_unlocked(ctrl, write_cmd, write_offset, mid, sid,
 					 addr, temp, len);
 done:
 	raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
@@ -564,11 +582,12 @@ struct spmi_pmic_arb_qpnpint_type {
 static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
 			       size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_master *master = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, 0, sid,
+	if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, master->id, sid,
 			       (per << 8) + reg, buf, len))
 		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
@@ -576,11 +595,12 @@ static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
 
 static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_master *master = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, 0, sid,
+	if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, master->id, sid,
 			      (per << 8) + reg, buf, len))
 		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
@@ -590,12 +610,13 @@ static int qpnpint_spmi_masked_write(struct irq_data *d, u8 reg,
 				     const void *buf, const void *mask,
 				     size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_master *master = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 	int rc;
 
-	rc = pmic_arb_masked_write(pmic_arb->spmic, sid, (per << 8) + reg, buf,
+	rc = pmic_arb_masked_write(pmic_arb->spmic, master->id, sid, (per << 8) + reg, buf,
 				   mask, len);
 	if (rc)
 		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
@@ -603,34 +624,36 @@ static int qpnpint_spmi_masked_write(struct irq_data *d, u8 reg,
 	return rc;
 }
 
-static void cleanup_irq(struct spmi_pmic_arb *pmic_arb, u16 apid, int id)
+static void cleanup_irq(struct spmi_pmic_master *master, u16 apid, int id)
 {
-	u16 ppid = pmic_arb->apid_data[apid].ppid;
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
+	u16 ppid = master->apid_data[apid].ppid;
 	u8 sid = ppid >> 8;
 	u8 per = ppid & 0xFF;
 	u8 irq_mask = BIT(id);
 
 	dev_err_ratelimited(&pmic_arb->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
 			__func__, apid, sid, per, id);
-	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(master, apid));
 }
 
-static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
+static int periph_interrupt(struct spmi_pmic_master *master, u16 apid)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	unsigned int irq;
 	u32 status, id;
 	int handled = 0;
-	u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF;
-	u8 per = pmic_arb->apid_data[apid].ppid & 0xFF;
+	u8 sid = (master->apid_data[apid].ppid >> 8) & 0xF;
+	u8 per = master->apid_data[apid].ppid & 0xFF;
 
-	status = readl_relaxed(pmic_arb->ver_ops->irq_status(pmic_arb, apid));
+	status = readl_relaxed(pmic_arb->ver_ops->irq_status(master, apid));
 	while (status) {
 		id = ffs(status) - 1;
 		status &= ~BIT(id);
-		irq = irq_find_mapping(pmic_arb->domain,
-					spec_to_hwirq(sid, per, id, apid));
+		irq = irq_find_mapping(master->domain,
+				       spec_to_hwirq(sid, per, id, apid));
 		if (irq == 0) {
-			cleanup_irq(pmic_arb, apid, id);
+			cleanup_irq(master, apid, id);
 			continue;
 		}
 		generic_handle_irq(irq);
@@ -642,16 +665,17 @@ static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
 
 static void pmic_arb_chained_irq(struct irq_desc *desc)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_master *master = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int first = pmic_arb->min_apid;
-	int last = pmic_arb->max_apid;
+	int first = master->min_apid;
+	int last = master->max_apid;
 	/*
 	 * acc_offset will be non-zero for the secondary SPMI bus instance on
 	 * v7 controllers.
 	 */
-	int acc_offset = pmic_arb->base_apid >> 5;
+	int acc_offset = master->base_apid >> 5;
 	u8 ee = pmic_arb->ee;
 	u32 status, enable, handled = 0;
 	int i, id, apid;
@@ -662,7 +686,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	chained_irq_enter(chip, desc);
 
 	for (i = first >> 5; i <= last >> 5; ++i) {
-		status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i - acc_offset));
+		status = readl_relaxed(ver_ops->owner_acc_status(master, ee, i - acc_offset));
 		if (status)
 			acc_valid = true;
 
@@ -676,9 +700,9 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 				continue;
 			}
 			enable = readl_relaxed(
-					ver_ops->acc_enable(pmic_arb, apid));
+					ver_ops->acc_enable(master, apid));
 			if (enable & SPMI_PIC_ACC_ENABLE_BIT)
-				if (periph_interrupt(pmic_arb, apid) != 0)
+				if (periph_interrupt(master, apid) != 0)
 					handled++;
 		}
 	}
@@ -687,19 +711,19 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	if (!acc_valid) {
 		for (i = first; i <= last; i++) {
 			/* skip if APPS is not irq owner */
-			if (pmic_arb->apid_data[i].irq_ee != pmic_arb->ee)
+			if (master->apid_data[i].irq_ee != pmic_arb->ee)
 				continue;
 
 			irq_status = readl_relaxed(
-					     ver_ops->irq_status(pmic_arb, i));
+					     ver_ops->irq_status(master, i));
 			if (irq_status) {
 				enable = readl_relaxed(
-					     ver_ops->acc_enable(pmic_arb, i));
+					     ver_ops->acc_enable(master, i));
 				if (enable & SPMI_PIC_ACC_ENABLE_BIT) {
 					dev_dbg(&pmic_arb->spmic->dev,
 						"Dispatching IRQ for apid=%d status=%x\n",
 						i, irq_status);
-					if (periph_interrupt(pmic_arb, i) != 0)
+					if (periph_interrupt(master, i) != 0)
 						handled++;
 				}
 			}
@@ -714,12 +738,13 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 
 static void qpnpint_irq_ack(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_master *master = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 data;
 
-	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(master, apid));
 
 	data = BIT(irq);
 	qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
@@ -735,14 +760,15 @@ static void qpnpint_irq_mask(struct irq_data *d)
 
 static void qpnpint_irq_unmask(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_master *master = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 buf[2];
 
 	writel_relaxed(SPMI_PIC_ACC_ENABLE_BIT,
-			ver_ops->acc_enable(pmic_arb, apid));
+			ver_ops->acc_enable(master, apid));
 
 	qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1);
 	if (!(buf[0] & BIT(irq))) {
@@ -799,9 +825,9 @@ static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
 
 static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_master *master = irq_data_get_irq_chip_data(d);
 
-	return irq_set_irq_wake(pmic_arb->irq, on);
+	return irq_set_irq_wake(master->irq, on);
 }
 
 static int qpnpint_get_irqchip_state(struct irq_data *d,
@@ -823,17 +849,18 @@ static int qpnpint_get_irqchip_state(struct irq_data *d,
 static int qpnpint_irq_domain_activate(struct irq_domain *domain,
 				       struct irq_data *d, bool reserve)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_master *master = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	u16 periph = hwirq_to_per(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u16 sid = hwirq_to_sid(d->hwirq);
 	u16 irq = hwirq_to_irq(d->hwirq);
 	u8 buf;
 
-	if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) {
+	if (master->apid_data[apid].irq_ee != pmic_arb->ee) {
 		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
 			sid, periph, irq, pmic_arb->ee,
-			pmic_arb->apid_data[apid].irq_ee);
+			master->apid_data[apid].irq_ee);
 		return -ENODEV;
 	}
 
@@ -860,7 +887,8 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 					unsigned long *out_hwirq,
 					unsigned int *out_type)
 {
-	struct spmi_pmic_arb *pmic_arb = d->host_data;
+	struct spmi_pmic_master *master = d->host_data;
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	u32 *intspec = fwspec->param;
 	u16 apid, ppid;
 	int rc;
@@ -876,7 +904,7 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 		return -EINVAL;
 
 	ppid = intspec[0] << 8 | intspec[1];
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(master, ppid);
 	if (rc < 0) {
 		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
 		intspec[0], intspec[1], intspec[2], rc);
@@ -885,10 +913,10 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 
 	apid = rc;
 	/* Keep track of {max,min}_apid for bounding search during interrupt */
-	if (apid > pmic_arb->max_apid)
-		pmic_arb->max_apid = apid;
-	if (apid < pmic_arb->min_apid)
-		pmic_arb->min_apid = apid;
+	if (apid > master->max_apid)
+		master->max_apid = apid;
+	if (apid < master->min_apid)
+		master->min_apid = apid;
 
 	*out_hwirq = spec_to_hwirq(intspec[0], intspec[1], intspec[2], apid);
 	*out_type  = intspec[3] & IRQ_TYPE_SENSE_MASK;
@@ -942,15 +970,33 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 	return 0;
 }
 
-static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+/*
+ * For non-v5 and non-v7, just set up the max and min apid.
+ */
+static int pmic_arb_init_apid_v1(struct spmi_pmic_master *master)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
+
+	/*
+	 * Initialize max_apid/min_apid to the opposite bounds, during
+	 * the irq domain translation, we are sure to update these
+	 */
+	master->max_apid = 0;
+	master->min_apid = pmic_arb->max_periphs - 1;
+
+	return 0;
+}
+
+static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_master *master, u16 ppid)
+{
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	u32 *mapping_table = pmic_arb->mapping_table;
 	int index = 0, i;
 	u16 apid_valid;
 	u16 apid;
 	u32 data;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = master->ppid_to_apid[ppid];
 	if (apid_valid & PMIC_ARB_APID_VALID) {
 		apid = apid_valid & ~PMIC_ARB_APID_VALID;
 		return apid;
@@ -958,7 +1004,7 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 
 	for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
 		if (!test_and_set_bit(index, pmic_arb->mapping_table_valid))
-			mapping_table[index] = readl_relaxed(pmic_arb->cnfg +
+			mapping_table[index] = readl_relaxed(master->cnfg +
 						SPMI_MAPPING_TABLE_REG(index));
 
 		data = mapping_table[index];
@@ -968,9 +1014,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				master->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				master->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		} else {
@@ -978,9 +1024,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				master->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				master->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		}
@@ -990,24 +1036,26 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 }
 
 /* v1 offset per ee */
-static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v1(struct spmi_pmic_master *master, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	return 0x800 + 0x80 * pmic_arb->channel;
 }
 
-static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static u16 pmic_arb_find_apid(struct spmi_pmic_master *master, u16 ppid)
 {
-	struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid];
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
+	struct apid_data *apidd = &master->apid_data[master->last_apid];
 	u32 regval, offset;
 	u16 id, apid;
 
-	for (apid = pmic_arb->last_apid; ; apid++, apidd++) {
+	for (apid = master->last_apid; ; apid++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(apid);
 		if (offset >= pmic_arb->core_size)
 			break;
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(master,
 								     apid));
 		apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 		apidd->write_ee = apidd->irq_ee;
@@ -1017,33 +1065,34 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 			continue;
 
 		id = (regval >> 8) & PMIC_ARB_PPID_MASK;
-		pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
+		master->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
 		apidd->ppid = id;
 		if (id == ppid) {
 			apid |= PMIC_ARB_APID_VALID;
 			break;
 		}
 	}
-	pmic_arb->last_apid = apid & ~PMIC_ARB_APID_VALID;
+	master->last_apid = apid & ~PMIC_ARB_APID_VALID;
 
 	return apid;
 }
 
-static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_master *master, u16 ppid)
 {
 	u16 apid_valid;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = master->ppid_to_apid[ppid];
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
-		apid_valid = pmic_arb_find_apid(pmic_arb, ppid);
+		apid_valid = pmic_arb_find_apid(master, ppid);
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
 	return apid_valid & ~PMIC_ARB_APID_VALID;
 }
 
-static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_read_apid_map_v5(struct spmi_pmic_master *master)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	struct apid_data *apidd;
 	struct apid_data *prev_apidd;
 	u16 i, apid, ppid, apid_max;
@@ -1065,9 +1114,9 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 	 * where N = number of APIDs supported by the primary bus and
 	 *       M = number of APIDs supported by the secondary bus
 	 */
-	apidd = &pmic_arb->apid_data[pmic_arb->base_apid];
-	apid_max = pmic_arb->base_apid + pmic_arb->apid_count;
-	for (i = pmic_arb->base_apid; i < apid_max; i++, apidd++) {
+	apidd = &master->apid_data[master->base_apid];
+	apid_max = master->base_apid + master->apid_count;
+	for (i = master->base_apid; i < apid_max; i++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(i);
 		if (offset >= pmic_arb->core_size)
 			break;
@@ -1078,19 +1127,18 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		ppid = (regval >> 8) & PMIC_ARB_PPID_MASK;
 		is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval);
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
-								     i));
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(master, i));
 		apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 
 		apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE;
 
-		valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
-		apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
-		prev_apidd = &pmic_arb->apid_data[apid];
+		valid = master->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
+		apid = master->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+		prev_apidd = &master->apid_data[apid];
 
 		if (!valid || apidd->write_ee == pmic_arb->ee) {
 			/* First PPID mapping or one for this EE */
-			pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+			master->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
 		} else if (valid && is_irq_ee &&
 			   prev_apidd->write_ee == pmic_arb->ee) {
 			/*
@@ -1101,16 +1149,16 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		}
 
 		apidd->ppid = ppid;
-		pmic_arb->last_apid = i;
+		master->last_apid = i;
 	}
 
 	/* Dump the mapping table for debug purposes. */
 	dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
 	for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) {
-		apid = pmic_arb->ppid_to_apid[ppid];
+		apid = master->ppid_to_apid[ppid];
 		if (apid & PMIC_ARB_APID_VALID) {
 			apid &= ~PMIC_ARB_APID_VALID;
-			apidd = &pmic_arb->apid_data[apid];
+			apidd = &master->apid_data[apid];
 			dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n",
 			      ppid, apid, apidd->write_ee, apidd->irq_ee);
 		}
@@ -1119,24 +1167,25 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 	return 0;
 }
 
-static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_master *master, u16 ppid)
 {
-	if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
+	if (!(master->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
-	return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+	return master->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
 }
 
 /* v2 offset per ppid and per ee */
-static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v2(struct spmi_pmic_master *master, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	u16 apid;
 	u16 ppid;
 	int rc;
 
 	ppid = sid << 8 | ((addr >> 8) & 0xFF);
-	rc = pmic_arb_ppid_to_apid_v2(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v2(master, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1144,19 +1193,58 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0x1000 * pmic_arb->ee + 0x8000 * apid;
 }
 
+/*
+ * v5 only supports one master. Compute apid accordingly.
+ */
+static int pmic_arb_init_apid_v5(struct spmi_pmic_master *master)
+{
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
+	int ret;
+
+	if (master->id != 0) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported masters count %d detected\n",
+			master->id);
+		return -EINVAL;
+	}
+
+	master->base_apid = 0;
+	master->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+					   PMIC_ARB_FEATURES_PERIPH_MASK;
+
+	if (master->base_apid + master->apid_count > pmic_arb->max_periphs) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+			master->base_apid + master->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_v1(master);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(master);
+	if (ret) {
+		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v5 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v5(struct spmi_pmic_master *master, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v5(master, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1166,7 +1254,7 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
+		if (master->apid_data[apid].write_ee != pmic_arb->ee) {
 			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
@@ -1178,19 +1266,64 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return offset;
 }
 
+/*
+ * Only v7 supports 2 bus masters. Each master will get a different apid count,
+ * read from different registers.
+ */
+static int pmic_arb_init_apid_v7(struct spmi_pmic_master *master)
+{
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
+	int ret;
+
+	if (master->id == 0) {
+		master->base_apid = 0;
+		master->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else if (master->id == 1) {
+		master->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						  PMIC_ARB_FEATURES_PERIPH_MASK;
+		master->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported masters count %d detected\n",
+			master->id);
+		return -EINVAL;
+	}
+
+	if (master->base_apid + master->apid_count > pmic_arb->max_periphs) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+			master->base_apid + master->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_v1(master);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(master);
+	if (ret) {
+		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v7 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v7(struct spmi_pmic_master *master, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(master, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1200,7 +1333,7 @@ static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x8000 * pmic_arb->ee + 0x20 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
+		if (master->apid_data[apid].write_ee != pmic_arb->ee) {
 			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
@@ -1223,104 +1356,110 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v1(struct spmi_pmic_master *master, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x20 * m + 0x4 * n;
+	return master->intr + 0x20 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v2(struct spmi_pmic_master *master, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n;
+	return master->intr + 0x100000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v3(struct spmi_pmic_master *master, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n;
+	return master->intr + 0x200000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v5(struct spmi_pmic_master *master, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x10000 * m + 0x4 * n;
+	return master->intr + 0x10000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v7(struct spmi_pmic_master *master, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * m + 0x4 * n;
+	return master->intr + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v1(struct spmi_pmic_master *master, u16 n)
 {
-	return pmic_arb->intr + 0x200 + 0x4 * n;
+	return master->intr + 0x200 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v2(struct spmi_pmic_master *master, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * n;
+	return master->intr + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v5(struct spmi_pmic_master *master, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v7(struct spmi_pmic_master *master, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v1(struct spmi_pmic_master *master, u16 n)
 {
-	return pmic_arb->intr + 0x600 + 0x4 * n;
+	return master->intr + 0x600 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v2(struct spmi_pmic_master *master, u16 n)
 {
-	return pmic_arb->intr + 0x4 + 0x1000 * n;
+	return master->intr + 0x4 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v5(struct spmi_pmic_master *master, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v7(struct spmi_pmic_master *master, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v1(struct spmi_pmic_master *master, u16 n)
 {
-	return pmic_arb->intr + 0xA00 + 0x4 * n;
+	return master->intr + 0xA00 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v2(struct spmi_pmic_master *master, u16 n)
 {
-	return pmic_arb->intr + 0x8 + 0x1000 * n;
+	return master->intr + 0x8 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v5(struct spmi_pmic_master *master, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v7(struct spmi_pmic_master *master, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = master->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x1000 * n;
 }
 
@@ -1340,9 +1479,9 @@ static u32 pmic_arb_apid_map_offset_v7(u16 n)
 }
 
 static void __iomem *
-pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v2(struct spmi_pmic_master *master, u16 n)
 {
-	return pmic_arb->cnfg + 0x700 + 0x4 * n;
+	return master->cnfg + 0x700 + 0x4 * n;
 }
 
 /*
@@ -1351,13 +1490,14 @@ pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
  * 0.
  */
 static void __iomem *
-pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v7(struct spmi_pmic_master *master, u16 n)
 {
-	return pmic_arb->cnfg + 0x4 * (n - pmic_arb->base_apid);
+	return  master->cnfg + 0x4 * (n - master->base_apid);
 }
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v1,
 	.offset			= pmic_arb_offset_v1,
@@ -1372,6 +1512,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.ver_str		= "v2",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1386,6 +1527,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.ver_str		= "v3",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1400,6 +1542,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.ver_str		= "v5",
+	.init_apid		= pmic_arb_init_apid_v5,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v5,
@@ -1414,6 +1557,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.ver_str		= "v7",
+	.init_apid		= pmic_arb_init_apid_v7,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v7,
@@ -1433,6 +1577,128 @@ static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
 	.translate = qpnpint_irq_domain_translate,
 };
 
+static int spmi_pmic_master_init(struct platform_device *pdev,
+				 struct device_node *node,
+				 struct spmi_pmic_arb *pmic_arb, u8 id)
+{
+	struct spmi_pmic_master *master = &pmic_arb->masters[id];
+	struct device *dev = &pdev->dev;
+	void __iomem *intr;
+	void __iomem *cnfg;
+	int bus_instance = id;
+	int index, ret;
+	u32 irq;
+
+	master->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID,
+					    sizeof(*master->ppid_to_apid),
+					    GFP_KERNEL);
+	if (!master->ppid_to_apid)
+		return -ENOMEM;
+
+	master->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs,
+					 sizeof(*master->apid_data),
+					 GFP_KERNEL);
+	if (!master->apid_data)
+		return -ENOMEM;
+
+	/* Optional property for v7: */
+	of_property_read_u32(node, "qcom,bus-id", &bus_instance);
+	if (bus_instance != id) {
+		dev_err(dev, "wrong bus-id value");
+		return -EINVAL;
+	}
+
+	index = of_property_match_string(node, "reg-names", "cnfg");
+	if (index < 0) {
+		dev_err(dev, "cnfg reg region missing");
+		return -EINVAL;
+	}
+
+	cnfg = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(cnfg))
+		return PTR_ERR(cnfg);
+
+	index = of_property_match_string(node, "reg-names", "intr");
+	if (index < 0) {
+		dev_err(dev, "intr reg region missing");
+		return -EINVAL;
+	}
+
+	intr = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(intr))
+		return PTR_ERR(intr);
+
+	irq = of_irq_get_byname(node, "periph_irq");
+	if (irq < 0)
+		return irq;
+
+	master->pmic_arb = pmic_arb;
+	master->intr = intr;
+	master->cnfg = cnfg;
+	master->irq = irq;
+	master->id = id;
+
+	ret = pmic_arb->ver_ops->init_apid(master);
+	if (ret)
+		return ret;
+
+	dev_dbg(&pdev->dev, "adding irq domain for master %d\n", id);
+
+	master->domain = irq_domain_add_tree(pdev->dev.of_node,
+					     &pmic_arb_irq_domain_ops, master);
+	if (!master->domain) {
+		dev_err(&pdev->dev, "unable to create irq_domain\n");
+		return -ENOMEM;
+	}
+
+	irq_set_chained_handler_and_data(master->irq,
+					 pmic_arb_chained_irq, master);
+
+	return 0;
+}
+
+static int spmi_pmic_arb_register_masters(struct spmi_pmic_arb *pmic_arb,
+					  struct platform_device *pdev)
+{
+	struct spmi_controller *ctrl = pmic_arb->spmic;
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *child;
+	int child_count = of_get_available_child_count(node);
+	int ret, i = 0;
+
+	/* Even without child nodes, there is at least one master */
+	pmic_arb->masters_count = child_count ? child_count : 1;
+
+	pmic_arb->masters = devm_kcalloc(&ctrl->dev, pmic_arb->masters_count,
+					 sizeof(*pmic_arb->masters),
+					 GFP_KERNEL);
+	if (!pmic_arb->masters)
+		return -ENOMEM;
+
+	if (child_count) {
+		for_each_available_child_of_node(node, child) {
+			ret = spmi_pmic_master_init(pdev, child, pmic_arb, i++);
+			if (ret)
+				return ret;
+		}
+	} else {
+		ret = spmi_pmic_master_init(pdev, node, pmic_arb, 0);
+	}
+
+	return ret;
+}
+
+static void spmi_pmic_arb_deregister_masters(struct spmi_pmic_arb *pmic_arb)
+{
+	int i;
+
+	for (i = 0; i < pmic_arb->masters_count; i++) {
+		irq_set_chained_handler_and_data(pmic_arb->masters[i].irq,
+						 NULL, NULL);
+		irq_domain_remove(pmic_arb->masters[i].domain);
+	}
+}
+
 static int spmi_pmic_arb_probe(struct platform_device *pdev)
 {
 	struct spmi_pmic_arb *pmic_arb;
@@ -1461,18 +1727,12 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	 * which does not result in a devm_request_mem_region() call.
 	 */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
-	core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
+	core = devm_ioremap(&pdev->dev, res->start, resource_size(res));
 	if (IS_ERR(core))
 		return PTR_ERR(core);
 
 	pmic_arb->core_size = resource_size(res);
 
-	pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
-					      sizeof(*pmic_arb->ppid_to_apid),
-					      GFP_KERNEL);
-	if (!pmic_arb->ppid_to_apid)
-		return -ENOMEM;
-
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
 	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
@@ -1493,86 +1753,27 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 						   "obsrvr");
-		pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start,
+		pmic_arb->rd_base = devm_ioremap(&pdev->dev, res->start,
 						 resource_size(res));
 		if (IS_ERR(pmic_arb->rd_base))
 			return PTR_ERR(pmic_arb->rd_base);
 
 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 						   "chnls");
-		pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start,
+		pmic_arb->wr_base = devm_ioremap(&pdev->dev, res->start,
 						 resource_size(res));
 		if (IS_ERR(pmic_arb->wr_base))
 			return PTR_ERR(pmic_arb->wr_base);
 	}
 
-	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
-
-	if (hw_ver >= PMIC_ARB_VERSION_V7_MIN) {
+	if (hw_ver == PMIC_ARB_VERSION_V7_MIN)
 		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
-		/* Optional property for v7: */
-		of_property_read_u32(pdev->dev.of_node, "qcom,bus-id",
-					&pmic_arb->bus_instance);
-		if (pmic_arb->bus_instance > 1) {
-			dev_err(&pdev->dev, "invalid bus instance (%u) specified\n",
-				pmic_arb->bus_instance);
-			return -EINVAL;
-		}
-
-		if (pmic_arb->bus_instance == 0) {
-			pmic_arb->base_apid = 0;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		} else {
-			pmic_arb->base_apid =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES1) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		}
-
-		if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->base_apid + pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	} else if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		pmic_arb->base_apid = 0;
-		pmic_arb->apid_count = readl_relaxed(core + PMIC_ARB_FEATURES) &
-					PMIC_ARB_FEATURES_PERIPH_MASK;
-
-		if (pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	}
-
-	pmic_arb->apid_data = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					   sizeof(*pmic_arb->apid_data),
-					   GFP_KERNEL);
-	if (!pmic_arb->apid_data)
-		return -ENOMEM;
+	else
+		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
 
-	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
+	dev_info(&pdev->dev, "PMIC arbiter version %s (0x%x)\n",
 		 pmic_arb->ver_ops->ver_str, hw_ver);
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
-	pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->intr))
-		return PTR_ERR(pmic_arb->intr);
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
-	pmic_arb->cnfg = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->cnfg))
-		return PTR_ERR(pmic_arb->cnfg);
-
-	pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq");
-	if (pmic_arb->irq < 0)
-		return pmic_arb->irq;
-
 	err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
 	if (err) {
 		dev_err(&pdev->dev, "channel unspecified.\n");
@@ -1599,16 +1800,12 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	}
 
 	pmic_arb->ee = ee;
-	mapping_table = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					sizeof(*mapping_table), GFP_KERNEL);
+	mapping_table = devm_kcalloc(&pdev->dev, pmic_arb->max_periphs,
+				     sizeof(*mapping_table), GFP_KERNEL);
 	if (!mapping_table)
 		return -ENOMEM;
 
 	pmic_arb->mapping_table = mapping_table;
-	/* Initialize max_apid/min_apid to the opposite bounds, during
-	 * the irq domain translation, we are sure to update these */
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
 
 	platform_set_drvdata(pdev, ctrl);
 	raw_spin_lock_init(&pmic_arb->lock);
@@ -1617,34 +1814,14 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	ctrl->read_cmd = pmic_arb_read_cmd;
 	ctrl->write_cmd = pmic_arb_write_cmd;
 
-	if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		err = pmic_arb_read_apid_map_v5(pmic_arb);
-		if (err) {
-			dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n",
-				err);
-			return err;
-		}
-	}
-
-	dev_dbg(&pdev->dev, "adding irq domain\n");
-	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
-					 &pmic_arb_irq_domain_ops, pmic_arb);
-	if (!pmic_arb->domain) {
-		dev_err(&pdev->dev, "unable to create irq_domain\n");
+	err = spmi_pmic_arb_register_masters(pmic_arb, pdev);
+	if (err)
 		return -ENOMEM;
-	}
 
-	irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq,
-					pmic_arb);
 	err = spmi_controller_add(ctrl);
 	if (err)
-		goto err_domain_remove;
-
-	return 0;
+		spmi_pmic_arb_deregister_masters(pmic_arb);
 
-err_domain_remove:
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
 	return err;
 }
 
@@ -1652,9 +1829,9 @@ static void spmi_pmic_arb_remove(struct platform_device *pdev)
 {
 	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+
 	spmi_controller_remove(ctrl);
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
+	spmi_pmic_arb_deregister_masters(pmic_arb);
 }
 
 static const struct of_device_id spmi_pmic_arb_match_table[] = {

-- 
2.34.1



From kuninori.morimoto.gx at renesas.com  Tue Feb  6 15:45:58 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Tue, 6 Feb 2024 23:45:58 +0000
Subject: [PATCH 3/4] media: platform: replace of_graph_get_next_endpoint()
In-Reply-To: <20240206162506.GC2827@pendragon.ideasonboard.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
	<87plxanvx1.wl-kuninori.morimoto.gx@renesas.com>
	<20240206162506.GC2827@pendragon.ideasonboard.com>
Message-ID: <875xz1tave.wl-kuninori.morimoto.gx@renesas.com>


Hi Laurent

Thank you for your review

> > diff --git a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> > index 686ca8753ba2..3f8bea2e3934 100644
> > --- a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> > +++ b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> > @@ -728,7 +728,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
> >  				 &state->max_num_lanes))
> >  		return -EINVAL;
> >  
> > -	node = of_graph_get_next_endpoint(node, NULL);
> > +	node = of_graph_get_endpoint_by_regs(node, 0, -1);
> 
> This is not correct, see
> Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml.

Hmm... Then, It can be like this ?

	+ node = of_graph_get_endpoint_by_regs(node, -1, -1);




Thank you for your help !!

Best regards
---
Renesas Electronics
Ph.D. Kuninori Morimoto


From dmitry.baryshkov at linaro.org  Tue Feb  6 15:55:39 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 7 Feb 2024 01:55:39 +0200
Subject: [PATCH RFC 1/2] spmi: Add support for multi-master
In-Reply-To: <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org> <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>
Message-ID: <CAA8EJpqsJmv36=o1aTjVH6eMHXMg8BHNpiDvs+Q8YB23ezVGtQ@mail.gmail.com>

On Wed, 7 Feb 2024 at 01:34, Abel Vesa <abel.vesa at linaro.org> wrote:
>
> Some newer SPMI controllers support multiple bus masters.
> Such a master can control multiple slave devices. The generic
> framework needs to be able to pass on the master id to the
> controller-specific driver. So do that. The framework will
> check if the devicetree child nodes are actually bus masters
> and will register the devices for each master. The legacy
> approach will still be supported for backwards compatibility.

Please remind me, are those two actual bus musters driving a single
bus in parallel or two SPMI buses being handled by a single device? In
the latter case this implementation is incorrect. There should be
multiple spmi_controller instances, one for each bus. Allocate them in
a loop and set ctrl->dev.of_node after allocating.

>
> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> ---
>  drivers/spmi/spmi-mtk-pmif.c |  6 ++--
>  drivers/spmi/spmi-pmic-arb.c | 10 +++---
>  drivers/spmi/spmi.c          | 76 ++++++++++++++++++++++++++++++--------------
>  include/linux/spmi.h         | 10 +++---
>  4 files changed, 67 insertions(+), 35 deletions(-)

-- 
With best wishes
Dmitry


From kuninori.morimoto.gx at renesas.com  Tue Feb  6 16:05:42 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Wed, 07 Feb 2024 09:05:42 +0900
Subject: [PATCH 4/4] video: fbdev: replace of_graph_get_next_endpoint()
In-Reply-To: <20240206164429.GD2827@pendragon.ideasonboard.com>
References: <20240206164429.GD2827@pendragon.ideasonboard.com>
Message-ID: <8734u5t9yh.wl-kuninori.morimoto.gx@renesas.com>


Hi Laurent

Thank you for the review

> > From DT point of view, in general, drivers should be asking for a
> > specific port number because their function is fixed in the binding.
> > 
> > of_graph_get_next_endpoint() doesn't match to this concept.
> > 
> > Simply replace
> > 
> > 	- of_graph_get_next_endpoint(xxx, NULL);
> > 	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);
(snip)
> > --- a/drivers/video/fbdev/amba-clcd.c
> > +++ b/drivers/video/fbdev/amba-clcd.c
> 
> This driver has been deleted in v6.8-rc1.

Thank you for pointing it.
I will rebase to latest of branch in v2


Thank you for your help !!

Best regards
---
Renesas Electronics
Ph.D. Kuninori Morimoto


From aford173 at gmail.com  Tue Feb  6 16:23:04 2024
From: aford173 at gmail.com (Adam Ford)
Date: Tue,  6 Feb 2024 18:23:04 -0600
Subject: [PATCH] drm/bridge: imx8mp-hdmi-pvi:  Fix build warnings
Message-ID: <20240207002305.618499-1-aford173@gmail.com>

Two separate build warnings were reported.  One from an
uninitialized variable, and the other from returning 0
instead of NULL from a pointer.

Fixes: 059c53e877ca ("drm/bridge: imx: add driver for HDMI TX Parallel Video Interface")
Reported-by: nathan at kernel.org
Reported-by: kernel test robot <lkp at intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202402062134.a6CqAt3s-lkp at intel.com/
Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
index a76b7669fe8a..f2a09c879e3d 100644
--- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
+++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
@@ -57,7 +57,7 @@ static void imx8mp_hdmi_pvi_bridge_enable(struct drm_bridge *bridge,
 	const struct drm_display_mode *mode;
 	struct drm_crtc_state *crtc_state;
 	struct drm_connector *connector;
-	u32 bus_flags, val;
+	u32 bus_flags = 0, val;
 
 	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
 	conn_state = drm_atomic_get_new_connector_state(state, connector);
@@ -110,7 +110,7 @@ imx8mp_hdmi_pvi_bridge_get_input_bus_fmts(struct drm_bridge *bridge,
 	struct drm_bridge_state *next_state;
 
 	if (!next_bridge->funcs->atomic_get_input_bus_fmts)
-		return 0;
+		return NULL;
 
 	next_state = drm_atomic_get_new_bridge_state(crtc_state->state,
 						     next_bridge);
-- 
2.43.0



From andre.przywara at arm.com  Tue Feb  6 16:27:33 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 7 Feb 2024 00:27:33 +0000
Subject: [PATCH 2/2] arm64: dts: allwinner: h616: Add Sipeed Longan SoM 3H
 and Pi 3H board support
In-Reply-To: <Zb4xui9QtKvilSZh@xhacker>
References: <20231228145647.1470-1-jszhang@kernel.org>
 <20231228145647.1470-3-jszhang@kernel.org>
 <20231229235543.7548cafa@minigeek.lan> <Zb4xui9QtKvilSZh@xhacker>
Message-ID: <66071a2d-e773-4b92-9470-457086895871@arm.com>

Hi Jisheng,

On 03/02/2024 13:29, Jisheng Zhang wrote:
> On Fri, Dec 29, 2023 at 11:55:43PM +0000, Andre Przywara wrote:
>> On Thu, 28 Dec 2023 22:56:47 +0800
>> Jisheng Zhang <jszhang at kernel.org> wrote:
>>
>> Hi,
>>
>>> The Sipeed Longan SoM 3H is a system on module based on the Allwinner
>>> H618 SoC. The SoM features:
>>>
>>> - Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
>>> - 2/4 GiB LPDDR4 DRAM SoMs
>>> - AXP313a PMIC
>>> - eMMC
>>>
>>> The Sipeed Longan PI 3H is a development board based on the above SoM.
>>> The board features:
>>> - Longan SoM 3H
>>> - Raspberry-Pi-1 compatible GPIO header
>>> - 2 USB 2.0 host port
>>> - 1 USB 2.0 type C port (power supply + OTG)
>>> - MicroSD slot
>>> - 1Gbps Ethernet port (via RTL8211 PHY)
>>> - HDMI port
>>> - WiFi/BT chip
>>>
>>> Add the devicetree file describing the currently supported features,
>>> namely PMIC, LEDs, UART, SD card, eMMC, USB and Ethernet.
>>>
>>> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
>>> ---
>>>   arch/arm64/boot/dts/allwinner/Makefile        |   1 +
>>>   .../sun50i-h618-longan-module-3h.dtsi         |  82 +++++++++++
>>>   .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 133 ++++++++++++++++++
>>>   3 files changed, 216 insertions(+)
>>>   create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
>>>   create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
>>>
>>> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
>>> index 3aca6787a167..00db504a9b8c 100644
>>> --- a/arch/arm64/boot/dts/allwinner/Makefile
>>> +++ b/arch/arm64/boot/dts/allwinner/Makefile
>>> @@ -42,4 +42,5 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
>>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
>>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
>>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
>>> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
>>>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
>>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
>>> new file mode 100644
>>> index 000000000000..88a7d287b73c
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
>>> @@ -0,0 +1,82 @@
>>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>>> +/*
>>> + * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
>>> + */
>>> +
>>> +/dts-v1/;
>>
>> I don't see how the SoM could be used on its own, without a hosting
>> board. So we don't need the dts version tag in the .dtsi, that would
>> just be double when we are going to compile any actual .dtb.
>>
>>> +
>>> +#include "sun50i-h616.dtsi"
>>> +
>>> +/ {
>>> +	model = "Sipeed Longan Module 3H";
>>> +	compatible = "sipeed,longan-module-3h", "allwinner,sun50i-h618";
>>
>> Same here, any model or compatible string would only be overwritten by
>> the board versions, so you don't need those two in the SoM .dtsi.
>> Compare the SoPine and BTT CB1 .dtsi files.
>>
>>> +};
>>> +
>>> +&mmc2 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&mmc2_pins>;
>>
>> Can you please add the DS pin here? At the moment the sunxi Linux
>> driver doesn't support HS-400, but that can a) change and b) doesn't
>> affect the DT anyway, since that describes the hardware. The connection
>> is definitely there, according to the schematics.
> 
> Hi Andre,
> 
> Thank you so much for the review and comments, could you please review?
> Except DS pin, other comments are adopted and updated in v2.
> DS pin is already there, IIUC, PC0 is emmc DS pin

Ah, you are absolutely right, PC0 is part of the mmc2 pin group already! 
Arguably we should move it out, since it conflicts with SPI0, but only 
if HS-400 is needed. But we can surely push this off until a board 
appears that requires both SPI0 and MMC2.

Sorry for the noise!

Cheers,
Andre

> Thanks
> 
>>
>>> +	vmmc-supply = <&reg_dldo1>;
>>> +	vqmmc-supply = <&reg_aldo1>;
>>> +	bus-width = <8>;
>>> +	non-removable;
>>> +	cap-mmc-hw-reset;
>>> +	mmc-ddr-1_8v;
>>> +	mmc-hs200-1_8v;
>>> +	status = "okay";
>>> +};
>>> +
>>> +&r_i2c {
>>> +	status = "okay";
>>> +
>>> +	axp313: pmic at 36 {
>>> +		compatible = "x-powers,axp313a";
>>
>> According to the bindings you need:
>>
>> 	interrupt-controller;
>> 	#interrupt-cells = <1>;
>>
>> Even without the IRQ line connected. dt-validate complains about that.
>>
>> Actually, do you know of any reason why it is not connected? I see it on
>> the SoM pins, is the idea that any *board* could dedicate a GPIO pin for
>> it, if needed?
>>
>>> +		reg = <0x36>;
>>> +
>>> +		regulators {
>>> +			/* Supplies VCC-PLL, so needs to be always on. */
>>> +			reg_aldo1: aldo1 {
>>> +				regulator-always-on;
>>> +				regulator-min-microvolt = <1800000>;
>>> +				regulator-max-microvolt = <1800000>;
>>> +				regulator-name = "vcc1v8";
>>
>> Can you please use "vcc-1v8-pll" instead? Then you don't need the
>> comment.
>>
>>> +			};
>>> +
>>> +			/* Supplies VCC-IO, so needs to be always on. */
>>> +			reg_dldo1: dldo1 {
>>> +				regulator-always-on;
>>> +				regulator-min-microvolt = <3300000>;
>>> +				regulator-max-microvolt = <3300000>;
>>> +				regulator-name = "vcc3v3";
>>
>> Same here, "vcc-3v3-io" is the name we used lately, to avoid the
>> comment.
>>
>>> +			};
>>> +
>>> +			reg_dcdc1: dcdc1 {
>>> +				regulator-always-on;
>>> +				regulator-min-microvolt = <810000>;
>>> +				regulator-max-microvolt = <990000>;
>>> +				regulator-name = "vdd-gpu-sys";
>>> +			};
>>> +
>>> +			reg_dcdc2: dcdc2 {
>>> +				regulator-always-on;
>>> +				regulator-min-microvolt = <810000>;
>>> +				regulator-max-microvolt = <1100000>;
>>> +				regulator-name = "vdd-cpu";
>>> +			};
>>> +
>>> +			reg_dcdc3: dcdc3 {
>>> +				regulator-always-on;
>>> +				regulator-min-microvolt = <1100000>;
>>> +				regulator-max-microvolt = <1100000>;
>>> +				regulator-name = "vdd-dram";
>>> +			};
>>> +		};
>>> +	};
>>> +};
>>> +
>>> +&pio {
>>> +	vcc-pc-supply = <&reg_dldo1>;
>>> +	vcc-pf-supply = <&reg_dldo1>;
>>> +	vcc-pg-supply = <&reg_aldo1>;
>>> +	vcc-ph-supply = <&reg_dldo1>;
>>> +	vcc-pi-supply = <&reg_dldo1>;
>>> +};
>>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
>>> new file mode 100644
>>> index 000000000000..245583881549
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
>>> @@ -0,0 +1,133 @@
>>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>>> +/*
>>> + * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
>>> + */
>>> +
>>> +/dts-v1/;
>>> +
>>> +#include "sun50i-h618-longan-module-3h.dtsi"
>>> +
>>> +#include <dt-bindings/gpio/gpio.h>
>>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>>> +#include <dt-bindings/leds/common.h>
>>> +
>>> +/ {
>>> +	model = "Sipeed Longan Pi 3H";
>>> +	compatible = "sipeed,longan-pi-3h", "sipeed,longan-module-3h", "allwinner,sun50i-h618";
>>> +
>>> +	aliases {
>>> +		ethernet0 = &emac0;
>>> +		serial0 = &uart0;
>>> +	};
>>> +
>>> +	chosen {
>>> +		stdout-path = "serial0:115200n8";
>>> +	};
>>> +
>>> +	leds {
>>> +		compatible = "gpio-leds";
>>> +
>>> +		led-0 {
>>> +			color = <LED_COLOR_ID_ORANGE>;
>>> +			function = LED_FUNCTION_INDICATOR;
>>> +			function-enumerator = <0>;
>>> +			gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */
>>> +		};
>>> +
>>> +		led-1 {
>>> +			color = <LED_COLOR_ID_ORANGE>;
>>> +			function = LED_FUNCTION_INDICATOR;
>>> +			function-enumerator = <1>;
>>> +			gpios = <&pio 6 4 GPIO_ACTIVE_LOW>; /* PG4 */
>>> +		};
>>> +	};
>>> +
>>> +	reg_vcc5v: vcc5v {
>>> +		/* board wide 5V supply directly from the USB-C socket */
>>> +		compatible = "regulator-fixed";
>>> +		regulator-name = "vcc-5v";
>>> +		regulator-min-microvolt = <5000000>;
>>> +		regulator-max-microvolt = <5000000>;
>>> +		regulator-always-on;
>>> +	};
>>
>> According to the schematic, there is a discrete 5V->3.3V regulator, can
>> you please describe this here as well?
>>
>>> +};
>>> +
>>> +&axp313 {
>>> +	vin1-supply = <&reg_vcc5v>;
>>> +	vin2-supply = <&reg_vcc5v>;
>>> +	vin3-supply = <&reg_vcc5v>;
>>> +};
>>> +
>>> +&ehci1 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&ohci1 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&ehci2 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&ohci2 {
>>> +	status = "okay";
>>> +};
>>> +
>>
>> Maybe worth adding a comment here that there is a USB WiFi chip
>> connected to those pins.
>>
>>> +&ehci3 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&ohci3 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&emac0 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&ext_rgmii_pins>;
>>> +	phy-mode = "rgmii";
>>> +	phy-handle = <&ext_rgmii_phy>;
>>> +	allwinner,rx-delay-ps = <3100>;
>>> +	allwinner,tx-delay-ps = <700>;
>>> +	phy-supply = <&reg_dldo1>;
>>
>> If I get the schematic correctly, the PHY is powered from the discrete
>> 3.3V regulator? In fact, the 3V3-DLDO-OUT/1V8-ALDO-OUT pins on the SoM
>> do not seem to be connected, so anything using 3.3V or 1.8V on the
>> board needs to be fed from this regulator, and everything on the SoM is
>> supplied by the AXP?
>>
>>> +	status = "okay";
>>> +};
>>> +
>>> +&mdio0 {
>>> +	ext_rgmii_phy: ethernet-phy at 1 {
>>> +		compatible = "ethernet-phy-ieee802.3-c22";
>>> +		reg = <1>;
>>> +	};
>>> +};
>>> +
>>> +&mmc0 {
>>> +	bus-width = <4>;
>>> +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;	/* PF6 */
>>> +	vmmc-supply = <&reg_dldo1>;
>>
>> According to the schematic, the SD card is supplied by the discrete
>> 3.3V regulator on the board.
>>
>>> +	status = "okay";
>>> +};
>>> +
>>> +&uart0 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&usbotg {
>>> +	/*
>>> +	 * PHY0 pins are connected to a USB-C socket, but a role switch
>>> +	 * is not implemented: both CC pins are pulled to GND.
>>> +	 * The VBUS pins power the device, so a fixed peripheral mode
>>> +	 * is the best choice.
>>> +	 * The board can be powered via GPIOs, in this case port0 *can*
>>> +	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
>>> +	 * then provided by the GPIOs. Any user of this setup would
>>> +	 * need to adjust the DT accordingly: dr_mode set to "host",
>>> +	 * enabling OHCI0 and EHCI0.
>>> +	 */
>>> +	dr_mode = "peripheral";
>>> +	status = "okay";
>>> +};
>>> +
>>> +&usbphy {
>>> +	usb1_vbus-supply = <&reg_vcc5v>;
>>
>> The same seems to be true for USB2 as well, and the WiFi chip on USB3 is
>> powered by the discrete 3.3V regulator. But I think we don't need these
>> properties at all if it's directly connected to the input and so always
>> powered. Or maybe we should do this anyway, and be it to make it clear
>> where the bus power is coming from?
>>
>> Cheers,
>> Andre
>>
>> P.S. I saw some U-Boot patches on some github. Most of them are
>> merged, but feel free to post the DT (same ones as here) and the
>> defconfig to the U-Boot list as well. You can use "make savedefconfig"
>> when you have configured the board, this will create a file "defconfig"
>> in the build directory that contains the minimal items, this can be
>> directly used as a defconfig.
>>
>>> +	status = "okay";
>>> +};
>>


From andre.przywara at arm.com  Tue Feb  6 16:28:54 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 7 Feb 2024 00:28:54 +0000
Subject: [PATCH v2 1/2] dt-bindings: arm: sunxi: Add Sipeed Longan Module
 3H and Longan Pi 3H
In-Reply-To: <20240203122502.1259-2-jszhang@kernel.org>
References: <20240203122502.1259-1-jszhang@kernel.org>
 <20240203122502.1259-2-jszhang@kernel.org>
Message-ID: <69512f5f-65b0-4b4f-8135-0265edd7ed5f@arm.com>

Hi,

On 03/02/2024 13:25, Jisheng Zhang wrote:
> Add name & compatible for the Sipeed Longan Module 3H and Longan PI 3H
> board.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>   Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
> index a9d8e85565b8..a97d44ba10ac 100644
> --- a/Documentation/devicetree/bindings/arm/sunxi.yaml
> +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
> @@ -835,6 +835,12 @@ properties:
>             - const: sinlinx,sina33
>             - const: allwinner,sun8i-a33
>   
> +      - description: Sipeed Longan Pi 3H board for the Sipeed Longan Module 3H
> +        items:
> +          - const: sipeed,longan-pi-3h
> +          - const: sipeed,longan-module-3h
> +          - const: allwinner,sun50i-h618
> +
>         - description: SourceParts PopStick v1.1
>           items:
>             - const: sourceparts,popstick-v1.1


From andre.przywara at arm.com  Tue Feb  6 16:36:09 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 7 Feb 2024 00:36:09 +0000
Subject: [PATCH v2 2/2] arm64: dts: allwinner: h616: Add Sipeed Longan SoM
 3H and Pi 3H board support
In-Reply-To: <20240203122502.1259-3-jszhang@kernel.org>
References: <20240203122502.1259-1-jszhang@kernel.org>
 <20240203122502.1259-3-jszhang@kernel.org>
Message-ID: <2108caa3-1725-4df5-ad0e-bded3288ca88@arm.com>

Hi,

On 03/02/2024 13:25, Jisheng Zhang wrote:
> The Sipeed Longan SoM 3H is a system on module based on the Allwinner
> H618 SoC. The SoM features:
> 
> - Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
> - 2/4 GiB LPDDR4 DRAM SoMs
> - AXP313a PMIC
> - eMMC
> 
> The Sipeed Longan PI 3H is a development board based on the above SoM.
> The board features:
> - Longan SoM 3H
> - Raspberry-Pi-1 compatible GPIO header
> - 2 USB 2.0 host port
> - 1 USB 2.0 type C port (power supply + OTG)
> - MicroSD slot
> - 1Gbps Ethernet port (via RTL8211 PHY)
> - HDMI port
> - WiFi/BT chip
> 
> Add the devicetree file describing the currently supported features,
> namely PMIC, LEDs, UART, SD card, eMMC, USB and Ethernet.

many thanks for the changes, that looks almost perfect now. Two small 
questions below:

> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> ---
>   arch/arm64/boot/dts/allwinner/Makefile        |   1 +
>   .../sun50i-h618-longan-module-3h.dtsi         |  77 ++++++++++
>   .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 143 ++++++++++++++++++
>   3 files changed, 221 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
>   create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> 
> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> index 91d505b385de..4b9173a16efe 100644
> --- a/arch/arm64/boot/dts/allwinner/Makefile
> +++ b/arch/arm64/boot/dts/allwinner/Makefile
> @@ -42,5 +42,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
>   dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> new file mode 100644
> index 000000000000..5f0f48cf4f01
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> @@ -0,0 +1,77 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
> + */
> +
> +#include "sun50i-h616.dtsi"
> +
> +&mmc2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc2_pins>;
> +	vmmc-supply = <&reg_dldo1>;
> +	vqmmc-supply = <&reg_aldo1>;
> +	bus-width = <8>;
> +	non-removable;
> +	cap-mmc-hw-reset;
> +	mmc-ddr-1_8v;
> +	mmc-hs200-1_8v;
> +	status = "okay";
> +};
> +
> +&r_i2c {
> +	status = "okay";
> +
> +	axp313: pmic at 36 {
> +		compatible = "x-powers,axp313a";
> +		reg = <0x36>;
> +		#interrupt-cells = <1>;
> +		interrupt-controller;
> +		interrupt-parent = <&pio>;
> +		interrupts = <3 11 IRQ_TYPE_LEVEL_LOW>;	/* PD11 */

So looking at the SoM schematic I found, the AXP IRQ pin is only 
connected to the SoM connector, but nowhere else. And I don't see PD11 
listed on the SoM schematic at all? So can you please double check that?
To make sure: it's fine to not list the interrupt (and 
interrupt-parent), we support this for the AXP313a, and other boards 
omit it as well already.

> +
> +		regulators {
> +			reg_aldo1: aldo1 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-name = "vcc-1v8-pll";
> +			};
> +
> +			reg_dldo1: dldo1 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-name = "vcc-3v3-io";
> +			};
> +
> +			reg_dcdc1: dcdc1 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <810000>;
> +				regulator-max-microvolt = <990000>;
> +				regulator-name = "vdd-gpu-sys";
> +			};
> +
> +			reg_dcdc2: dcdc2 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <810000>;
> +				regulator-max-microvolt = <1100000>;
> +				regulator-name = "vdd-cpu";
> +			};
> +
> +			reg_dcdc3: dcdc3 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <1100000>;
> +				regulator-max-microvolt = <1100000>;
> +				regulator-name = "vdd-dram";
> +			};
> +		};
> +	};
> +};
> +
> +&pio {
> +	vcc-pc-supply = <&reg_dldo1>;
> +	vcc-pf-supply = <&reg_dldo1>;
> +	vcc-pg-supply = <&reg_aldo1>;
> +	vcc-ph-supply = <&reg_dldo1>;
> +	vcc-pi-supply = <&reg_dldo1>;
> +};
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> new file mode 100644
> index 000000000000..08d3ad7114fb
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> @@ -0,0 +1,143 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
> + */
> +
> +/dts-v1/;
> +
> +#include "sun50i-h618-longan-module-3h.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/leds/common.h>
> +
> +/ {
> +	model = "Sipeed Longan Pi 3H";
> +	compatible = "sipeed,longan-pi-3h", "sipeed,longan-module-3h", "allwinner,sun50i-h618";
> +
> +	aliases {
> +		ethernet0 = &emac0;
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		led-0 {
> +			color = <LED_COLOR_ID_ORANGE>;
> +			function = LED_FUNCTION_INDICATOR;
> +			function-enumerator = <0>;
> +			gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */
> +		};
> +
> +		led-1 {
> +			color = <LED_COLOR_ID_ORANGE>;
> +			function = LED_FUNCTION_INDICATOR;
> +			function-enumerator = <1>;
> +			gpios = <&pio 6 4 GPIO_ACTIVE_LOW>; /* PG4 */
> +		};
> +	};
> +
> +	reg_vcc5v: regulator-vcc5v {
> +		/* board wide 5V supply directly from the USB-C socket */
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc-5v";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-always-on;
> +	};
> +
> +	reg_vcc3v3: regulator-vcc3v3 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc-3v3";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-always-on;

Only if you respin: can you please add "vin-supply = <&reg_vcc5v>;" 
here? That would avoid one dummy regulator message, I think.

Otherwise looks good, all the things I listed on v1 were fixed.

Thanks!
Andre


> +	};
> +};
> +
> +&axp313 {
> +	vin1-supply = <&reg_vcc5v>;
> +	vin2-supply = <&reg_vcc5v>;
> +	vin3-supply = <&reg_vcc5v>;
> +};
> +
> +&ehci1 {
> +	status = "okay";
> +};
> +
> +&ohci1 {
> +	status = "okay";
> +};
> +
> +&ehci2 {
> +	status = "okay";
> +};
> +
> +&ohci2 {
> +	status = "okay";
> +};
> +
> +/* WiFi & BT combo module is connected to this Host */
> +&ehci3 {
> +	status = "okay";
> +};
> +
> +&ohci3 {
> +	status = "okay";
> +};
> +
> +&emac0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&ext_rgmii_pins>;
> +	phy-mode = "rgmii";
> +	phy-handle = <&ext_rgmii_phy>;
> +	allwinner,rx-delay-ps = <3100>;
> +	allwinner,tx-delay-ps = <700>;
> +	phy-supply = <&reg_vcc3v3>;
> +	status = "okay";
> +};
> +
> +&mdio0 {
> +	ext_rgmii_phy: ethernet-phy at 1 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <1>;
> +	};
> +};
> +
> +&mmc0 {
> +	bus-width = <4>;
> +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;	/* PF6 */
> +	vmmc-supply = <&reg_vcc3v3>;
> +	status = "okay";
> +};
> +
> +&uart0 {
> +	status = "okay";
> +};
> +
> +&usbotg {
> +	/*
> +	 * PHY0 pins are connected to a USB-C socket, but a role switch
> +	 * is not implemented: both CC pins are pulled to GND.
> +	 * The VBUS pins power the device, so a fixed peripheral mode
> +	 * is the best choice.
> +	 * The board can be powered via GPIOs, in this case port0 *can*
> +	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
> +	 * then provided by the GPIOs. Any user of this setup would
> +	 * need to adjust the DT accordingly: dr_mode set to "host",
> +	 * enabling OHCI0 and EHCI0.
> +	 */
> +	dr_mode = "peripheral";
> +	status = "okay";
> +};
> +
> +&usbphy {
> +	usb1_vbus-supply = <&reg_vcc5v>;
> +	usb2_vbus-supply = <&reg_vcc5v>;
> +	status = "okay";
> +};


From kuninori.morimoto.gx at renesas.com  Tue Feb  6 17:06:03 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Wed, 7 Feb 2024 01:06:03 +0000
Subject: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <9d1e99b0-892d-4a72-a9b3-886b8ed094b0@xs4all.nl>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
	<87r0hqnvxc.wl-kuninori.morimoto.gx@renesas.com>
	<20240206134155.GB2827@pendragon.ideasonboard.com>
	<9d1e99b0-892d-4a72-a9b3-886b8ed094b0@xs4all.nl>
Message-ID: <87zfwdrslh.wl-kuninori.morimoto.gx@renesas.com>


Hi Laurent, Hans

> >> From DT point of view, in general, drivers should be asking for a
> >> specific port number because their function is fixed in the binding.
> >>
> >> of_graph_get_next_endpoint() doesn't match to this concept.
> >>
> >> Simply replace
> >>
> >> 	- of_graph_get_next_endpoint(xxx, NULL);
> >> 	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);
(snip)
> >>  	/* Parse the endpoint. */
> >> -	endpoint = of_graph_get_next_endpoint(np, NULL);
> >> +	endpoint = of_graph_get_endpoint_by_regs(np, 0, -1);
> > 
> > I think this should be port 1 for the adv7611 and port2 for the adv7612.
> > The adv7610 may need to use port 1 too, but the bindings likely need to
> > be updated.
> > 
> > Hans, Krzysztof, any opinion ?
> 
> It looks like it. But I suspect the code never worked. The endpoint parsing
> is only needed if a specific mbus type is used (i.e., not 'UNKNOWN'), and
> I don't think that is used in the device trees in the kernel. So everything
> silently falls back to UNKNOWN and some default bus config that 'just works' (tm).
> 
> I'm pretty sure this code is wrong, but nobody ever noticed. Changing it
> to the new code just makes it bug-compatible :-)

Nice ;)
So, let's add /* FIXME */ here in v2

Thank you for your help !!

Best regards
---
Renesas Electronics
Ph.D. Kuninori Morimoto


From daniel at makrotopia.org  Tue Feb  6 17:29:18 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Wed, 7 Feb 2024 01:29:18 +0000
Subject: [RFC PATCH net-next v3 3/8] net: pcs: pcs-mtk-lynxi: add
 platform driver for MT7988
In-Reply-To: <ZXnV/Pk1PYxAm/jS@shell.armlinux.org.uk>
References: <cover.1702352117.git.daniel@makrotopia.org>
 <8aa905080bdb6760875d62cb3b2b41258837f80e.1702352117.git.daniel@makrotopia.org>
 <ZXnV/Pk1PYxAm/jS@shell.armlinux.org.uk>
Message-ID: <ZcLc7vJ4fPmRyuxn@makrotopia.org>

Hi Russell,

sorry for the extended time it took me to get back to this patch and
the comments you made for it. Understanding the complete scope of the
problem took a while (plus there were holidays and other fun things),
and also brought up further questions which I hope you can help me
find good answers for, see below:

On Wed, Dec 13, 2023 at 04:04:12PM +0000, Russell King (Oracle) wrote:
> On Tue, Dec 12, 2023 at 03:47:18AM +0000, Daniel Golle wrote:
> > Introduce a proper platform MFD driver for the LynxI (H)SGMII PCS which
> > is going to initially be used for the MT7988 SoC.
> > 
> > Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> 
> I made some specific suggestions about what I wanted to see for
> "getting" PCS in the previous review, and I'm disappointed that this
> patch set is still inventing its own solution.
> 
> > +struct phylink_pcs *mtk_pcs_lynxi_get(struct device *dev, struct device_node *np)
> > +{
> > +	struct platform_device *pdev;
> > +	struct mtk_pcs_lynxi *mpcs;
> > +
> > +	if (!np)
> > +		return NULL;
> > +
> > +	if (!of_device_is_available(np))
> > +		return ERR_PTR(-ENODEV);
> > +
> > +	if (!of_match_node(mtk_pcs_lynxi_of_match, np))
> > +		return ERR_PTR(-EINVAL);
> > +
> > +	pdev = of_find_device_by_node(np);
> > +	if (!pdev || !platform_get_drvdata(pdev)) {
> 
> This is racy - as I thought I described before, userspace can unbind
> the device in one thread, while another thread is calling this
> function. With just the right timing, this check succeeds, but...
> 
> > +		if (pdev)
> > +			put_device(&pdev->dev);
> > +		return ERR_PTR(-EPROBE_DEFER);
> > +	}
> > +
> > +	mpcs = platform_get_drvdata(pdev);
> 
> mpcs ends up being read as NULL here. Even if you did manage to get a
> valid pointer, "mpcs" being devm-alloced could be freed from under
> you at this point...
> 
> > +	device_link_add(dev, mpcs->dev, DL_FLAG_AUTOREMOVE_CONSUMER);
> 
> resulting in this accessing memory which has been freed.
> 
> The solution would be either to suppress the bind/unbind attributes
> (provided the underlying struct device can't go away, which probably
> also means ensuring the same of the MDIO bus. Aternatively, adding
> a lock around the remove path and around the checking of
> platform_get_drvdata() down to adding the device link would probably
> solve it.
> 
> However, I come back to my general point - this kind of stuff is
> hairy. Do we want N different implementations of it in various drivers
> with subtle bugs, or do we want _one_ implemenatation.
> 
> If we go with the one implemenation approach, then we need to think
> about whether we should be using device links or not. The problem
> could be for network interfaces where one struct device is
> associated with multiple network interfaces. Using device links has
> the unfortunate side effect that if the PCS for one of those network
> interfaces is removed, _all_ network interfaces disappear.

I agree, esp. on this MT7988 removal of a PCS which may then not
even be in use also impairs connectivity on the built-in gigE DSA
switch. It would be nice to try to avoid this.

> 
> My original suggestion was to hook into phylink to cause that to
> take the link down when an in-use PCS gets removed.

I took a deep dive into how this could be done correctly and how
similar things are done for other drivers. Apart from the PCS there
often also is a muxing-PHY involved, eg. MediaTek's XFI T-PHY in this
case (previously often called "pextp" for no apparent reason) or
Marvell's comphy (mvebu-comphy).

So let's try something simple on an already well-supported platform,
I thought and grabbed Marvell Armada CN9131-DB running vanilla Linux,
and it didn't even take some something racy, but plain:

ip link set eth6 up
cd /sys/bus/platform/drivers/mvebu-comphy
echo f2120000.phy > unbind
echo f4120000.phy > unbind
echo f6120000.phy > unbind
ip link set eth6 down


That was enough. The result is a kernel crash, and the same should
apply on popular platforms like the SolidRun MACCHIATOBin and other
similar boards.

So this gets me to think that there is a wider problem around
non-phylink-managed resources which may disappear while in use by
network drivers, and I guess that the same applies in many other
places. I don't have a SATA drive connected to that Marvell board, but
I can imagine what happens when suddenly removing the comphy instance
in charge of the SATA link and then a subsequent SATA hotplug event
happens or stuff like that...

Anyway, back to network subsystem and phylink:

Do you agree that we need a way to register (and unregister) PCS
providers with phylink, so we don't need *_get_by_of_node implementations
in each driver? If so, can you sketch out what the basic requirements
for an acceptable solution would be?

Also, do you agree that lack of handling of disappearing resources,
such as PHYs (*not* network PHYs, but PHYs as in drivers/phy/*) or
syscons, is already a problem right now which should be addressed?

If you imagine phylink to take care of the life-cycle of all link-
resources, what is vision about those things other than classic MDIO-
connected PHYs?

And well, of course, the easy fix for the example above would be:
diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
index b0dd133665986..9517c96319595 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
@@ -1099,6 +1099,7 @@ static const struct of_device_id mvebu_comphy_of_match_table[] = {
 MODULE_DEVICE_TABLE(of, mvebu_comphy_of_match_table);
 
 static struct platform_driver mvebu_comphy_driver = {
+	.suppress_bind_attrs = true,
 	.probe	= mvebu_comphy_probe,
 	.driver	= {
 		.name = "mvebu-comphy",

But that should then apply to every single driver in drivers/phy/...


> 
> > +
> > +	return &mpcs->pcs;
> > +}
> > +EXPORT_SYMBOL(mtk_pcs_lynxi_get);
> > +
> > +void mtk_pcs_lynxi_put(struct phylink_pcs *pcs)
> > +{
> > +	struct mtk_pcs_lynxi *cur, *mpcs = NULL;
> > +
> > +	if (!pcs)
> > +		return;
> > +
> > +	mutex_lock(&instance_mutex);
> > +	list_for_each_entry(cur, &mtk_pcs_lynxi_instances, node)
> > +		if (pcs == &cur->pcs) {
> > +			mpcs = cur;
> > +			break;
> > +		}
> > +	mutex_unlock(&instance_mutex);
> 
> I don't see what this loop gains us, other than checking that the "pcs"
> is still on the list and hasn't already been removed. If that is all
> that this is about, then I would suggest:
> 
> 	bool found = false;
> 
> 	if (!pcs)
> 		return;
> 
> 	mpcs = pcs_to_mtk_pcs_lynxi(pcs);
> 	mutex_lock(&instance_mutex);
> 	list_for_each_entry(cur, &mtk_pcs_lynxi_instances, node)
> 		if (cur == mpcs) {
> 			found = true;
> 			break;
> 		}
> 	mutex_unlock(&instance_mutex);
> 
> 	if (WARN_ON(!found))
> 		return;
> 
> which makes it more obvious why this exists.

The idea was not only to make sure it hasn't been removed, but also
to be sure that what ever the private data pointer points to has
actually been created by that very driver.

But yes, doing it in the way you suggest will work in the same way,
just when having my idea in mind it looks more fishy to use
pcs_to_mtk_pcs_lynxi() before we are 100% sure that what we dealing
with has previously been created by this driver.


Cheers


Daniel


From shawn.sung at mediatek.com  Tue Feb  6 18:15:09 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Wed, 7 Feb 2024 10:15:09 +0800
Subject: [PATCH v2 0/1] Filter modes according to hardware capability
Message-ID: <20240207021510.24035-1-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

This series is based on mediatek-drm-next branch of
kernel/git/chunkuang.hu/linux.git.

Changes in v2:
- Refined the filtering formula
- Add the .mode_valid hook to the hardware that causes the limitation

Hsiao Chien Sung (1):
  drm/mediatek: Filter modes according to hardware capability

 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 56 +++++++++++++++++++
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 17 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 17 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   | 12 ++++
 6 files changed, 107 insertions(+)

--
2.18.0



From shawn.sung at mediatek.com  Tue Feb  6 18:15:10 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Wed, 7 Feb 2024 10:15:10 +0800
Subject: [PATCH v2 1/1] drm/mediatek: Filter modes according to hardware capability
In-Reply-To: <20240207021510.24035-1-shawn.sung@mediatek.com>
References: <20240207021510.24035-1-shawn.sung@mediatek.com>
Message-ID: <20240207021510.24035-2-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

We found a stability issue on MT8188 when connecting an external monitor
in 2560x1440 at 144Hz mode. Checked with the designer, there is a function
called "prefetch" which is working during VBP (triggered by VSYNC).
If the duration of VBP is too short, the throughput requirement could
increase more than 3 times and lead to stability issues.

The mode settings that VDOSYS supports are mainly affected by clock
rate and throughput, display driver should filter these settings
according to the SoC's limitation to avoid unstable conditions.

Since currently the mode filter is only available on MT8195 and MT8188
and they share the same compatible name, the reference number (8250)
is hard coded instead of in the driver data.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 56 +++++++++++++++++++
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 17 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 17 ++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   | 12 ++++
 6 files changed, 107 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index eb738f14f09e3..4a5661334fb1a 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -72,6 +72,8 @@ void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned int
 			      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);
+enum drm_mode_status mtk_merge_mode_valid(struct device *dev,
+					  const struct drm_display_mode *mode);
 
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
@@ -130,6 +132,8 @@ unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
 struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev);
 const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
 size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
+enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
+						const struct drm_display_mode *mode);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index c19fb1836034d..6b065ee254455 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -223,6 +223,62 @@ void mtk_merge_clk_disable(struct device *dev)
 	clk_disable_unprepare(priv->clk);
 }
 
+enum drm_mode_status mtk_merge_mode_valid(struct device *dev,
+					  const struct drm_display_mode *mode)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+	unsigned long rate = 0;
+
+	rate = clk_get_rate(priv->clk);
+
+	/* Convert to KHz and round the number */
+	rate = (rate + 500) / 1000;
+
+	if (rate && mode->clock > rate) {
+		dev_dbg(dev, "invalid clock: %d (>%lu)\n", mode->clock, rate);
+		return MODE_CLOCK_HIGH;
+	}
+
+	/*
+	 * Measure the bandwidth requirement of hardware prefetch (per frame)
+	 *
+	 * let N = prefetch buffer size in lines
+	 *         (ex. N=3, then prefetch buffer size = 3 lines)
+	 *
+	 * prefetch size = htotal * N (pixels)
+	 * time per line = 1 / fps / vtotal (seconds)
+	 * duration      = vbp * time per line
+	 *               = vbp / fps / vtotal
+	 *
+	 * data rate = prefetch size / duration
+	 *           = htotal * N / (vbp / fps / vtotal)
+	 *           = htotal * vtotal * fps * N / vbp
+	 *           = clk * N / vbp (pixels per second)
+	 *
+	 * Say 4K60 (CAE-861) is the maximum mode supported by the SoC
+	 * data rate = 594000K * N / 72 = 8250 (standard)
+	 * (remove K*N because of the same unit)
+	 *
+	 * For 2560x1440 at 144 (clk=583600K, vbp=17):
+	 * rate = 583600 / 17 ~= 34329 > 8250 (NG)
+	 *
+	 * For 2560x1440 at 120 (clk=497760K, vbp=77):
+	 * rate = 497760 / 77 ~= 6464 < 8250 (OK)
+	 *
+	 * Bandwidth requirement of hardware prefetch increases significantly
+	 * when the VBP decreases (more than 4x in this example).
+	 */
+	rate = mode->clock / (mode->vtotal - mode->vsync_end);
+
+	if (rate > 8250) {
+		dev_dbg(dev, "invalid rate: %lu (>8250): " DRM_MODE_FMT "\n",
+			rate, DRM_MODE_ARG(mode));
+		return MODE_BAD;
+	}
+
+	return MODE_OK;
+}
+
 static int mtk_disp_merge_bind(struct device *dev, struct device *master,
 			       void *data)
 {
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index 10d23e76acaa9..6d4334955e3d3 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -88,6 +88,7 @@ static const struct mtk_ddp_comp_funcs ethdr = {
 static const struct mtk_ddp_comp_funcs merge = {
 	.clk_enable = mtk_merge_clk_enable,
 	.clk_disable = mtk_merge_clk_disable,
+	.mode_valid = mtk_merge_mode_valid,
 };
 
 static const struct mtk_ddp_comp_funcs padding = {
@@ -341,6 +342,22 @@ void mtk_ovl_adaptor_clk_disable(struct device *dev)
 	}
 }
 
+enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
+						const struct drm_display_mode *mode)
+
+{
+	int i;
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
+		dev = ovl_adaptor->ovl_adaptor_comp[i];
+		if (!dev || !comp_matches[i].funcs->mode_valid)
+			continue;
+		return comp_matches[i].funcs->mode_valid(dev, mode);
+	}
+	return MODE_OK;
+}
+
 unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev)
 {
 	return MTK_OVL_ADAPTOR_LAYER_NUM;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 1dac8d0fbc669..14cf75fa217f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -212,6 +212,22 @@ static void mtk_drm_crtc_destroy_state(struct drm_crtc *crtc,
 	kfree(to_mtk_crtc_state(state));
 }
 
+static enum drm_mode_status
+mtk_drm_crtc_mode_valid(struct drm_crtc *crtc,
+			const struct drm_display_mode *mode)
+{
+	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	enum drm_mode_status status = MODE_OK;
+	int i;
+
+	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
+		status = mtk_ddp_comp_mode_valid(mtk_crtc->ddp_comp[i], mode);
+		if (status != MODE_OK)
+			break;
+	}
+	return status;
+}
+
 static bool mtk_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 				    const struct drm_display_mode *mode,
 				    struct drm_display_mode *adjusted_mode)
@@ -830,6 +846,7 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
 static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
 	.mode_fixup	= mtk_drm_crtc_mode_fixup,
 	.mode_set_nofb	= mtk_drm_crtc_mode_set_nofb,
+	.mode_valid	= mtk_drm_crtc_mode_valid,
 	.atomic_begin	= mtk_drm_crtc_atomic_begin,
 	.atomic_flush	= mtk_drm_crtc_atomic_flush,
 	.atomic_enable	= mtk_drm_crtc_atomic_enable,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 9633e860cc3ce..94590227c56a9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -416,6 +416,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
 	.remove = mtk_ovl_adaptor_remove_comp,
 	.get_formats = mtk_ovl_adaptor_get_formats,
 	.get_num_formats = mtk_ovl_adaptor_get_num_formats,
+	.mode_valid = mtk_ovl_adaptor_mode_valid,
 };
 
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index f8c7e8d8ddc12..215b7234ff13c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -12,6 +12,8 @@
 #include <linux/soc/mediatek/mtk-mmsys.h>
 #include <linux/soc/mediatek/mtk-mutex.h>
 
+#include <drm/drm_modes.h>
+
 struct device;
 struct device_node;
 struct drm_crtc;
@@ -84,6 +86,7 @@ struct mtk_ddp_comp_funcs {
 	void (*add)(struct device *dev, struct mtk_mutex *mutex);
 	void (*remove)(struct device *dev, struct mtk_mutex *mutex);
 	unsigned int (*encoder_index)(struct device *dev);
+	enum drm_mode_status (*mode_valid)(struct device *dev, const struct drm_display_mode *mode);
 };
 
 struct mtk_ddp_comp {
@@ -125,6 +128,15 @@ static inline void mtk_ddp_comp_clk_disable(struct mtk_ddp_comp *comp)
 		comp->funcs->clk_disable(comp->dev);
 }
 
+static inline
+enum drm_mode_status mtk_ddp_comp_mode_valid(struct mtk_ddp_comp *comp,
+					     const struct drm_display_mode *mode)
+{
+	if (comp && comp->funcs && comp->funcs->mode_valid)
+		return comp->funcs->mode_valid(comp->dev, mode);
+	return MODE_OK;
+}
+
 static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
 				       unsigned int w, unsigned int h,
 				       unsigned int vrefresh, unsigned int bpc,
-- 
2.18.0



From william.zhang at broadcom.com  Tue Feb  6 18:21:52 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Tue, 6 Feb 2024 18:21:52 -0800
Subject: [PATCH v4 03/12] dt-bindings: mtd: brcmnand: Add ecc strap
 property
In-Reply-To: <20240206103453.7ac23384@xps-13>
References: <20240203002834.171462-1-william.zhang@broadcom.com>
 <20240203002834.171462-4-william.zhang@broadcom.com>
 <20240203-expenses-tarmac-c564bc7ae34f@spud> <20240205142639.5d7c70f0@xps-13>
 <ce15922e-4292-41d6-8c5f-2b4fbfa83d5c@broadcom.com>
 <20240206103453.7ac23384@xps-13>
Message-ID: <376d63f1-fd01-4fc2-a8fa-d59361910f3d@broadcom.com>



On 2/6/24 01:34, Miquel Raynal wrote:
> Hi William,
> 
> william.zhang at broadcom.com wrote on Mon, 5 Feb 2024 10:05:14 -0800:
> 
>> Hi Miquel,
>>
>> On 2/5/24 05:26, Miquel Raynal wrote:
>>> Hi,
>>>
>>> conor at kernel.org wrote on Sat, 3 Feb 2024 14:49:50 +0000:
>>>    
>>>> On Fri, Feb 02, 2024 at 04:28:24PM -0800, William Zhang wrote:
>>>>> Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
>>>>> board boot strap for broadband board designs because they do not specify
>>>>> ecc setting in dts but rather using the strap setting.
>>>>>
>>>>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>>>>>
>>>>> ---
>>>>>
>>>>> Changes in v4:
>>>>> - Move ecc strap property to this separate patch and remove some
>>>>> non-binding related text from the description
>>>>>
>>>>> Changes in v3: None
>>>>> Changes in v2: None
>>>>>
>>>>>    Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 8 ++++++++
>>>>>    1 file changed, 8 insertions(+)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>>>>> index d0168d55c73e..2599d902ec3a 100644
>>>>> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>>>>> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
>>>>> @@ -147,6 +147,14 @@ patternProperties:
>>>>>              layout.
>>>>>            $ref: /schemas/types.yaml#/definitions/uint32
>>>>>    >>> +      brcm,nand-ecc-use-strap:
>>>>> +        description:
>>>>> +          This flag indicates the ecc strength and spare area size should
>>>>> +          be retrieved from the SoC NAND boot strap setting instead of
>>>>> +          nand-ecc-strength and brcm,nand-oob-sector-size or auto detection.
>>>>
>>>> I'm still on the fence about this being overly prescriptive about the
>>>> operating systems behaviour. I think it would be good to say why the
>>>> strap values are better than those explicitly provided in DT rather than
>>>> just saying "these strap values should be used".
>>>
>>> I don't know if there is a point is saying why they would be better, as
>>> they are not. It is a -questionable- design choice. However I would
>>> just get rid of any mention to other properties. Just say one should
>>> expect the strap value to be read and applied by the system when this
>>> property is present.
>>>    
>> Agree we don't need to say which is better as it is just a design choice. And it is used by all BCMBCA internal ref boards and customer designs. But if we just say strap value is read and applied, it is vague and nobody would know what is applied.  I replied this email yesterday and suggest the followings:
>>
>> This property provides a choice for retrieving ecc strength and spare area size from
>   the SoC NAND boot strap setting. It is commonly used by the BCMBCA SoC board design.
> 
> What about:
> 
> This property requires the host system to get the ECC strength and step
> size from the SoC NAND boot strap setting. This is a common hardware
> design on BCMBCA based boards.
> 
Sounds good.  Will update.

> I would also like to constrain this more by adding an exclusive use wrt
> the nand-ecc-* properties. So either you put this property, or you put
> the generic nand-ecc-* properties, or you put nothing (which, again, is
> by far the best solution), but in no case you can have a mix.
> 
Right, nobody should have a mix but in case it happens, the driver code 
handles that well by taking nand-ecc-* property. So not sure if the 
exclusion check is really important. Anyway I will add a condition check 
in the yaml on them as you requested.

>>
>> Hope this make everyone happy and we can move forward.
> 
> I was advising to avoid mentioning too specific DT properties, but
> mentioning the kind of impact it has (on the choice for the ECC
> strength and size) is fine.
> 
>>
>>
>>>>> +          This is commonly used by the BCMBCA SoC board design.
>>>>> +        $ref: /schemas/types.yaml#/definitions/flag
>>>>> +
>>>>>        unevaluatedProperties: false
>>>>>    >>>   allOf:
>>>>> -- >>> 2.37.3
>>>>>     > >
>>> Thanks,
>>> Miqu?l
> 
> 
> Thanks,
> Miqu?l
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240206/b5279e2c/attachment-0001.p7s>

From richard.xnu.clark at gmail.com  Tue Feb  6 18:28:33 2024
From: richard.xnu.clark at gmail.com (richard clark)
Date: Wed, 7 Feb 2024 10:28:33 +0800
Subject: Question about the ipi_raise filter usage and output
In-Reply-To: <xhsmhjznigcdr.mognet@vschneid-thinkpadt14sgen2i.remote.csb>
References: <ZcDwoce6Ok25K6Dm@FVFF77S0Q05N> <xhsmhmssehp6t.mognet@vschneid-thinkpadt14sgen2i.remote.csb>
 <CAJNi4rMiGcP4wdA=1dSOXwYXOKSCWnN8FYxBaFdaAXBqAU_ePQ@mail.gmail.com> <xhsmhjznigcdr.mognet@vschneid-thinkpadt14sgen2i.remote.csb>
Message-ID: <CAJNi4rPHhEMGbv9ndKxFLdTvdN9a3HBiRkT4jtTp0bOTYvWq0Q@mail.gmail.com>

On Tue, Feb 6, 2024 at 5:39?PM Valentin Schneider <vschneid at redhat.com> wrote:
>
> You should have access to the generic fields which include the CPU from
> which the event happens. Any of "CPU", "cpu" or "common_cpu" would match
> this.
>
> So if you're on a recent enough kernel (v6.6 or above AFAICT), you should
> be able to do something like so:
>
>   trace-cmd record -e 'ipi_raise' -f 'CPU & CPUS{7-42}' ./foo.sh
>
> If you just want to match a single CPU, or are on an older kernel, this
> should work as well:
>
>   trace-cmd record -e 'ipi_raise' -f 'CPU == 42' ./foo.sh
>
> For example on a QEMU x86 environment:
>
>   # trace-cmd record -e 'call_function*' -f 'CPU & CPUS{3}' hackbench
>   Running in process mode with 10 groups using 40 file descriptors each (== 400 tasks)
>   Each sender will pass 100 messages of 100 bytes
>   Time: 0.396
>   CPU0 data recorded at offset=0x738000
>       0 bytes in size
>   CPU1 data recorded at offset=0x738000
>       0 bytes in size
>   CPU2 data recorded at offset=0x738000
>       0 bytes in size
>   CPU3 data recorded at offset=0x738000
>       4096 bytes in size
>
>   # trace-cmd report
>   CPU 0 is empty
>   CPU 1 is empty
>   CPU 2 is empty
>   cpus=4
>             <idle>-0     [003]    29.704387: call_function_single_entry: vector=251
>             <idle>-0     [003]    29.704388: call_function_single_exit: vector=251
>             <idle>-0     [003]    29.705950: call_function_single_entry: vector=251
>             <idle>-0     [003]    29.705951: call_function_single_exit: vector=251
>             <idle>-0     [003]    29.706462: call_function_single_entry: vector=251
>             <idle>-0     [003]    29.706463: call_function_single_exit: vector=251
>          hackbench-962   [003]    29.706501: call_function_single_entry: vector=251
>          hackbench-962   [003]    29.706502: call_function_single_exit: vector=251
>          hackbench-955   [003]    29.706521: call_function_single_entry: vector=251
>          hackbench-955   [003]    29.706522: call_function_single_exit: vector=251
>             <idle>-0     [003]    30.101812: call_function_single_entry: vector=251
>             <idle>-0     [003]    30.101814: call_function_single_exit: vector=251
>             <idle>-0     [003]    30.101897: call_function_single_entry: vector=251
>             <idle>-0     [003]    30.101898: call_function_single_exit: vector=251
>             <idle>-0     [003]    30.101985: call_function_single_entry: vector=251
>             <idle>-0     [003]    30.101986: call_function_single_exit: vector=251
>             <idle>-0     [003]    30.102072: call_function_single_entry: vector=251
>             <idle>-0     [003]    30.102072: call_function_single_exit: vector=251
>             <idle>-0     [003]    30.102161: call_function_single_entry: vector=251
>             <idle>-0     [003]    30.102161: call_function_single_exit: vector=251
>             <idle>-0     [003]    30.102250: call_function_single_entry: vector=251
>             <idle>-0     [003]    30.102251: call_function_single_exit: vector=251
>             <idle>-0     [003]    30.102372: call_function_single_entry: vector=251
>             <idle>-0     [003]    30.102372: call_function_single_exit: vector=251
>
>
>   CPU 0 is empty
>   CPU 1 is empty
>   CPU 2 is empty
>   cpus=4
>           <idle>-0     [003]  1067.718304: call_function_single_entry: vector=251
>           <idle>-0     [003]  1067.718309: call_function_single_exit: vector=251
>
> and that behaves the same as
>
>   trace-cmd record -e 'call_function*' -f 'CPU == 3' hackbench
>
Thanks, # trace-cmd record -e 'ipi' -f 'CPU==10 || CPU==11' -f
'reason=="Function call interrupts"' works:
CPU0 data recorded at offset=0x336000
    0 bytes in size
CPU1 data recorded at offset=0x336000
    0 bytes in size
CPU2 data recorded at offset=0x336000
    0 bytes in size
CPU3 data recorded at offset=0x336000
    0 bytes in size
CPU4 data recorded at offset=0x336000
    0 bytes in size
CPU5 data recorded at offset=0x336000
    0 bytes in size
CPU6 data recorded at offset=0x336000
    0 bytes in size
CPU7 data recorded at offset=0x336000
    0 bytes in size
CPU8 data recorded at offset=0x336000
    0 bytes in size
CPU9 data recorded at offset=0x336000
    0 bytes in size
CPU10 data recorded at offset=0x336000
    4096 bytes in size
CPU11 data recorded at offset=0x337000
    4096 bytes in size

# trace-cmd report
CPU 0 is empty
CPU 1 is empty
CPU 2 is empty
CPU 3 is empty
CPU 4 is empty
CPU 5 is empty
CPU 6 is empty
CPU 7 is empty
CPU 8 is empty
CPU 9 is empty
cpus=12
          insmod-8519  [010] 170847.580062: ipi_raise:
target_mask=00000000,00000bff (Function call interrupts)
          <idle>-0     [011] 170847.580070: ipi_entry:
(Function call interrupts)
          <idle>-0     [011] 170847.580071: ipi_exit:
(Function call interrupts)
          insmod-8519  [010] 170847.580078: ipi_raise:
target_mask=00000000,00000bff (Function call interrupts)
          <idle>-0     [011] 170847.580080: ipi_entry:
(Function call interrupts)
          <idle>-0     [011] 170847.580080: ipi_exit:
(Function call interrupts)
          insmod-8519  [010] 170847.580282: ipi_raise:
target_mask=00000000,00000002 (Function call interrupts)
          insmod-8519  [010] 170847.580329: ipi_raise:
target_mask=00000000,00000800 (Function call interrupts)
          <idle>-0     [011] 170847.580331: ipi_entry:
(Function call interrupts)
          <idle>-0     [011] 170847.580343: ipi_exit:
(Function call interrupts)

BTW: where does 12 come from in 'cpus=12' :-)


From m.shams at samsung.com  Tue Feb  6 03:33:56 2024
From: m.shams at samsung.com (Tamseel Shams)
Date: Tue, 6 Feb 2024 17:03:56 +0530
Subject: [PATCH v2] serial: samsung: honor fifosize from dts at first
In-Reply-To: <0a2604e7-8b30-4cf9-9099-ba3681bc5538@linaro.org>
References: <CGME20240205082441epcas5p1e904f4f95852de3fd8663742ed5131df@epcas5p1.samsung.com>
	<20240205082434.36531-1-m.shams@samsung.com>
	<0a2604e7-8b30-4cf9-9099-ba3681bc5538@linaro.org>
Message-ID: <006b01da58f0$601316b0$20394410$@samsung.com>

Hi Krzysztof,

> -----Original Message-----
> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at linaro.org]
> Sent: 06 February 2024 15:42
> To: Tamseel Shams <m.shams at samsung.com>; alim.akhtar at samsung.com;
> krzysztof.kozlowski+dt at linaro.org; gregkh at linuxfoundation.org;
> jirislaby at kernel.org
> Cc: 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: Re: [PATCH v2] serial: samsung: honor fifosize from dts at first
> 
> On 05/02/2024 09:24, Tamseel Shams wrote:
> > Currently for platforms which passes UART fifosize from DT gets
> > override by local driver structure "s3c24xx_serial_drv_data", which is
> > not intended. Change the code to honor fifosize from device tree at
> > first.
> >
> > Signed-off-by: Tamseel Shams <m.shams at samsung.com>
> > ---
> > Change Log:
> > v1 -> v2:
> > Acknowledged Krzysztof's comments
> > Initialized "ret" variable
> >
> >  drivers/tty/serial/samsung_tty.c | 16 +++++++++-------
> >  1 file changed, 9 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/tty/serial/samsung_tty.c
> > b/drivers/tty/serial/samsung_tty.c
> > index 71d17d804fda..e5dc2c32b1bd 100644
> > --- a/drivers/tty/serial/samsung_tty.c
> > +++ b/drivers/tty/serial/samsung_tty.c
> > @@ -1952,7 +1952,7 @@ static int s3c24xx_serial_probe(struct
> platform_device *pdev)
> >  	struct device_node *np = pdev->dev.of_node;
> >  	struct s3c24xx_uart_port *ourport;
> >  	int index = probe_index;
> > -	int ret, prop = 0;
> > +	int ret = 1, prop = 0;
> 
> I am sorry, but return of probe function cannot be positive.
> 

Thanks for the review.

I am reusing the "ret" variable to check whether fifosize property
is present in DT or not. It will be overwritten at later stage in probe
function before returning. Also, "ret" variable is used to return from
probe function only in case of failure i.e. "ret" is negative.
Currently, probe function always returns 0 in case of success.

For better readability, I am thinking of introducing a new variable for
checking the return value from function "of_property_read_u32" while
getting "samsung,uart-fifosize" property.

What are your thoughts on that?

> >
> >  	if (np) {
> >  		ret = of_alias_get_id(np, "serial"); @@ -1990,8 +1990,7 @@
> static
> > int s3c24xx_serial_probe(struct platform_device *pdev)
> >  	}
> >
> >  	if (np) {
> > -		of_property_read_u32(np,
> > -			"samsung,uart-fifosize", &ourport->port.fifosize);
> > +		ret = of_property_read_u32(np, "samsung,uart-fifosize",
> > +&ourport->port.fifosize);
> >
> >  		if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
> >  			switch (prop) {
> > @@ -2009,10 +2008,13 @@ static int s3c24xx_serial_probe(struct
> platform_device *pdev)
> >  		}
> >  	}
> >
> > -	if (ourport->drv_data->fifosize[index])
> > -		ourport->port.fifosize = ourport->drv_data->fifosize[index];
> > -	else if (ourport->info->fifosize)
> > -		ourport->port.fifosize = ourport->info->fifosize;
> > +	if (ret) {
> 
> Are you sure that you are checking correct ret?

Explanation same as above. 


Thanks & Regards,
Tamseel Shams




From richard.xnu.clark at gmail.com  Tue Feb  6 18:33:38 2024
From: richard.xnu.clark at gmail.com (richard clark)
Date: Wed, 7 Feb 2024 10:33:38 +0800
Subject: Question about the ipi_raise filter usage and output
In-Reply-To: <CAJNi4rPHhEMGbv9ndKxFLdTvdN9a3HBiRkT4jtTp0bOTYvWq0Q@mail.gmail.com>
References: <ZcDwoce6Ok25K6Dm@FVFF77S0Q05N> <xhsmhmssehp6t.mognet@vschneid-thinkpadt14sgen2i.remote.csb>
 <CAJNi4rMiGcP4wdA=1dSOXwYXOKSCWnN8FYxBaFdaAXBqAU_ePQ@mail.gmail.com>
 <xhsmhjznigcdr.mognet@vschneid-thinkpadt14sgen2i.remote.csb> <CAJNi4rPHhEMGbv9ndKxFLdTvdN9a3HBiRkT4jtTp0bOTYvWq0Q@mail.gmail.com>
Message-ID: <CAJNi4rNC3zNi8RywzxXiVLfxVVuCfV_x1GbAXhT+h4DJ5ZrF7A@mail.gmail.com>

On Wed, Feb 7, 2024 at 10:28?AM richard clark
<richard.xnu.clark at gmail.com> wrote:
>
> On Tue, Feb 6, 2024 at 5:39?PM Valentin Schneider <vschneid at redhat.com> wrote:
> >
> > You should have access to the generic fields which include the CPU from
> > which the event happens. Any of "CPU", "cpu" or "common_cpu" would match
> > this.
> >
> > So if you're on a recent enough kernel (v6.6 or above AFAICT), you should
> > be able to do something like so:
> >
> >   trace-cmd record -e 'ipi_raise' -f 'CPU & CPUS{7-42}' ./foo.sh
> >
> > If you just want to match a single CPU, or are on an older kernel, this
> > should work as well:
> >
> >   trace-cmd record -e 'ipi_raise' -f 'CPU == 42' ./foo.sh
> >
> > For example on a QEMU x86 environment:
> >
> >   # trace-cmd record -e 'call_function*' -f 'CPU & CPUS{3}' hackbench
> >   Running in process mode with 10 groups using 40 file descriptors each (== 400 tasks)
> >   Each sender will pass 100 messages of 100 bytes
> >   Time: 0.396
> >   CPU0 data recorded at offset=0x738000
> >       0 bytes in size
> >   CPU1 data recorded at offset=0x738000
> >       0 bytes in size
> >   CPU2 data recorded at offset=0x738000
> >       0 bytes in size
> >   CPU3 data recorded at offset=0x738000
> >       4096 bytes in size
> >
> >   # trace-cmd report
> >   CPU 0 is empty
> >   CPU 1 is empty
> >   CPU 2 is empty
> >   cpus=4
> >             <idle>-0     [003]    29.704387: call_function_single_entry: vector=251
> >             <idle>-0     [003]    29.704388: call_function_single_exit: vector=251
> >             <idle>-0     [003]    29.705950: call_function_single_entry: vector=251
> >             <idle>-0     [003]    29.705951: call_function_single_exit: vector=251
> >             <idle>-0     [003]    29.706462: call_function_single_entry: vector=251
> >             <idle>-0     [003]    29.706463: call_function_single_exit: vector=251
> >          hackbench-962   [003]    29.706501: call_function_single_entry: vector=251
> >          hackbench-962   [003]    29.706502: call_function_single_exit: vector=251
> >          hackbench-955   [003]    29.706521: call_function_single_entry: vector=251
> >          hackbench-955   [003]    29.706522: call_function_single_exit: vector=251
> >             <idle>-0     [003]    30.101812: call_function_single_entry: vector=251
> >             <idle>-0     [003]    30.101814: call_function_single_exit: vector=251
> >             <idle>-0     [003]    30.101897: call_function_single_entry: vector=251
> >             <idle>-0     [003]    30.101898: call_function_single_exit: vector=251
> >             <idle>-0     [003]    30.101985: call_function_single_entry: vector=251
> >             <idle>-0     [003]    30.101986: call_function_single_exit: vector=251
> >             <idle>-0     [003]    30.102072: call_function_single_entry: vector=251
> >             <idle>-0     [003]    30.102072: call_function_single_exit: vector=251
> >             <idle>-0     [003]    30.102161: call_function_single_entry: vector=251
> >             <idle>-0     [003]    30.102161: call_function_single_exit: vector=251
> >             <idle>-0     [003]    30.102250: call_function_single_entry: vector=251
> >             <idle>-0     [003]    30.102251: call_function_single_exit: vector=251
> >             <idle>-0     [003]    30.102372: call_function_single_entry: vector=251
> >             <idle>-0     [003]    30.102372: call_function_single_exit: vector=251
> >
> >
> >   CPU 0 is empty
> >   CPU 1 is empty
> >   CPU 2 is empty
> >   cpus=4
> >           <idle>-0     [003]  1067.718304: call_function_single_entry: vector=251
> >           <idle>-0     [003]  1067.718309: call_function_single_exit: vector=251
> >
> > and that behaves the same as
> >
> >   trace-cmd record -e 'call_function*' -f 'CPU == 3' hackbench
> >
> Thanks, # trace-cmd record -e 'ipi' -f 'CPU==10 || CPU==11' -f
> 'reason=="Function call interrupts"' works:
> CPU0 data recorded at offset=0x336000
>     0 bytes in size
> CPU1 data recorded at offset=0x336000
>     0 bytes in size
> CPU2 data recorded at offset=0x336000
>     0 bytes in size
> CPU3 data recorded at offset=0x336000
>     0 bytes in size
> CPU4 data recorded at offset=0x336000
>     0 bytes in size
> CPU5 data recorded at offset=0x336000
>     0 bytes in size
> CPU6 data recorded at offset=0x336000
>     0 bytes in size
> CPU7 data recorded at offset=0x336000
>     0 bytes in size
> CPU8 data recorded at offset=0x336000
>     0 bytes in size
> CPU9 data recorded at offset=0x336000
>     0 bytes in size
> CPU10 data recorded at offset=0x336000
>     4096 bytes in size
> CPU11 data recorded at offset=0x337000
>     4096 bytes in size
>
> # trace-cmd report
> CPU 0 is empty
> CPU 1 is empty
> CPU 2 is empty
> CPU 3 is empty
> CPU 4 is empty
> CPU 5 is empty
> CPU 6 is empty
> CPU 7 is empty
> CPU 8 is empty
> CPU 9 is empty
> cpus=12
>           insmod-8519  [010] 170847.580062: ipi_raise:
> target_mask=00000000,00000bff (Function call interrupts)
>           <idle>-0     [011] 170847.580070: ipi_entry:
> (Function call interrupts)
>           <idle>-0     [011] 170847.580071: ipi_exit:
> (Function call interrupts)
>           insmod-8519  [010] 170847.580078: ipi_raise:
> target_mask=00000000,00000bff (Function call interrupts)
>           <idle>-0     [011] 170847.580080: ipi_entry:
> (Function call interrupts)
>           <idle>-0     [011] 170847.580080: ipi_exit:
> (Function call interrupts)
>           insmod-8519  [010] 170847.580282: ipi_raise:
> target_mask=00000000,00000002 (Function call interrupts)
>           insmod-8519  [010] 170847.580329: ipi_raise:
> target_mask=00000000,00000800 (Function call interrupts)
>           <idle>-0     [011] 170847.580331: ipi_entry:
> (Function call interrupts)
>           <idle>-0     [011] 170847.580343: ipi_exit:
> (Function call interrupts)
>
> BTW: where does 12 come from in 'cpus=12' :-)

Hmmm, please ignore the BTW, it should be the cpu total number in the system...


From ck.hu at mediatek.com  Tue Feb  6 19:49:19 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Wed, 7 Feb 2024 03:49:19 +0000
Subject: [PATCH 1/3] drm/mediatek: Dynamically allocate CMDQ and use
 helper functions
In-Reply-To: <072f049a-021f-4f39-81ff-d3cba1e6c47c@collabora.com>
References: <20230623094931.117918-1-angelogioacchino.delregno@collabora.com>
	 <20230623094931.117918-2-angelogioacchino.delregno@collabora.com>
	 <bd19faf644fa80f8fa77ed0841a724aa3ca871f5.camel@mediatek.com>
	 <0acd286d-d4f4-97b2-c296-b2860a00def6@collabora.com>
	 <e8e60556e53ccf319358cbef203bc84c418a352b.camel@mediatek.com>
	 <d29d342b-37f4-8d7b-ed7d-c441cc928393@collabora.com>
	 <7175ec117988657c2fb7bf6d50b67d60038e3a54.camel@mediatek.com>
	 <072f049a-021f-4f39-81ff-d3cba1e6c47c@collabora.com>
Message-ID: <8811a5e04514954cf379ac561023a7e1884a2da1.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-02-06 at 14:33 +0100, AngeloGioacchino Del Regno wrote:
> Il 03/08/23 10:37, CK Hu (???) ha scritto:
> > Hi, Angelo:
> > 
> > On Thu, 2023-08-03 at 10:25 +0200, AngeloGioacchino Del Regno
> > wrote:
> > > Il 03/08/23 08:28, CK Hu (???) ha scritto:
> > > > Hi, Angelo:
> > > > 
> > > > On Wed, 2023-08-02 at 12:41 +0200, AngeloGioacchino Del Regno
> > > > wrote:
> > > > > Il 02/08/23 08:24, CK Hu (???) ha scritto:
> > > > > > Hi, Angelo:
> > > > > > 
> > > > > > On Fri, 2023-06-23 at 11:49 +0200, AngeloGioacchino Del
> > > > > > Regno
> > > > > > wrote:
> > > > > > >     	
> > > > > > > External email : Please do not click links or open
> > > > > > > attachments
> > > > > > > until
> > > > > > > you have verified the sender or the content.
> > > > > > >     Instead of stack allocating the cmdq_client and
> > > > > > > cmdq_handle
> > > > > > > structures
> > > > > > > switch them to pointers, allowing us to migrate this
> > > > > > > driver
> > > > > > > to
> > > > > > > use
> > > > > > > the
> > > > > > > common functions provided by mtk-cmdq-helper.
> > > > > > > In order to do this, it was also necessary to add a
> > > > > > > `priv`
> > > > > > > pointer to
> > > > > > > struct cmdq_client, as that's used to pass (in this case)
> > > > > > > a
> > > > > > > mtk_crtc
> > > > > > > handle to the ddp_cmdq_cb() mailbox RX callback function.
> > > > > > > 
> > > > > > > Signed-off-by: AngeloGioacchino Del Regno <
> > > > > > > angelogioacchino.delregno at collabora.com>
> > > > > > > ---
> > > > > > >     drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 107
> > > > > > > +++++++-----
> > > > > > > ---
> > > > > > > -------
> > > > > > > --
> > > > > > >     include/linux/soc/mediatek/mtk-cmdq.h   |   1 +
> > > > > > >     2 files changed, 32 insertions(+), 76 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > > > > > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > > > > > index 0df62b076f49..b63289ab6787 100644
> > > > > > > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > > > > > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > > > > > @@ -50,8 +50,8 @@ struct mtk_drm_crtc {
> > > > > > >     	bool				pending_async_pla
> > > > > > > nes;
> > > > > > >     
> > > > > > >     #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > > > > > > -	struct cmdq_client		cmdq_client;
> > > > > > > -	struct cmdq_pkt			cmdq_handle;
> > > > > > > +	struct cmdq_client		*cmdq_client;
> > > > > > > +	struct cmdq_pkt			*cmdq_handle;
> > > > > > >     	u32				cmdq_event;
> > > > > > >     	u32				cmdq_vblank_cnt;
> > > > > > >     	wait_queue_head_t		cb_blocking_queue
> > > > > > > ;
> > > > > > > @@ -108,47 +108,6 @@ static void
> > > > > > > mtk_drm_finish_page_flip(struct
> > > > > > > mtk_drm_crtc *mtk_crtc)
> > > > > > >     	}
> > > > > > >     }
> > > > > > >     
> > > > > > > -#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > > > > > > -static int mtk_drm_cmdq_pkt_create(struct cmdq_client
> > > > > > > *client,
> > > > > > > struct cmdq_pkt *pkt,
> > > > > > > -				   size_t size)
> > > > > > > -{
> > > > > > > -	struct device *dev;
> > > > > > > -	dma_addr_t dma_addr;
> > > > > > > -
> > > > > > > -	pkt->va_base = kzalloc(size, GFP_KERNEL);
> > > > > > > -	if (!pkt->va_base) {
> > > > > > > -		kfree(pkt);
> > > > > > > -		return -ENOMEM;
> > > > > > > -	}
> > > > > > > -	pkt->buf_size = size;
> > > > > > > -	pkt->cl = (void *)client;
> > > > > > 
> > > > > > I have a plan to remove cl in struct cmdq_pkt. But this
> > > > > > modification
> > > > > > would make this plan more difficult. So I would pending
> > > > > > this
> > > > > > patch
> > > > > > until cl is removed from struct cmdq_pkt.
> > > > > > 
> > > > > 
> > > > > I think that this ifdef cleanup is more urgent than the
> > > > > removal
> > > > > of
> > > > > `cl` from
> > > > > struct cmdq_pkt, as those ifdefs shouldn't have reached
> > > > > upstream
> > > > > in
> > > > > the first
> > > > > place, don't you agree?
> > > > 
> > > > I think removing ifdefs and using helper function are different
> > > > things.
> > > > You could remove ifdefs and keep mtk_drm_cmdq_pkt_create().
> > > > 
> > > 
> > > I chose to do it like that because this function would otherwise
> > > be a
> > > 100% duplicate of the related cmdq helper :-)
> > 
> > Removing cl would change the interface of cmdq_pkt_create(). And
> > this
> > is related to different maintainer's tree. So it would be a long
> > time
> > to process. For you, only removing ifdes is urgent, so use
> > cmdq_pkt_create() is not urgent. So let's keep
> > mtk_drm_cmdq_pkt_create() and you could remove ifdefs.
> > 
> 
> Hello CK,
> 
> my CMDQ cleanup has been stuck on your intention to remove `cl` from
> the CMDQ
> helpers for ** six months ** now.
> 
> Are you performing that removal, or can we just get this cleanup
> finally done?

It's busy last year and I almost forget this. Thank you to notice me. I
would send patch after Chinese new year (Feb 8th ~ Feb 14th).

Regards,
CK


> 
> Regards,
> Angelo
> 
> 
> 

From hj96.nam at samsung.com  Tue Feb  6 20:22:35 2024
From: hj96.nam at samsung.com (Hojin Nam)
Date: Wed, 07 Feb 2024 13:22:35 +0900
Subject: [PATCH v2] perf: CXL: fix mismatched cpmu event opcode
References: <CGME20240207042235epcms2p358e40f0409e25bd9e875ad1ae0dd0764@epcms2p3>
Message-ID: <20240207042235epcms2p358e40f0409e25bd9e875ad1ae0dd0764@epcms2p3>

S2M NDR BI-ConflictAck opcode is described as 4 in the CXL
r3.1 3.3.9 Table 3.50. However, it is defined as 3 in macro definition. Also
adds s2m_ndr_cmpm for bit 3 that was added in CXL r3.1.

Fixes: 5d7107c72796 ("perf: CXL Performance Monitoring Unit driver")
Signed-off-by: Hojin Nam <hj96.nam at samsung.com>
---

Hi Jonathan,
I've modified the commit messsge and code to reflect you mentioned. Thank you!

Changes since v1:
- Add s2m_ndr_cmpm event attribute (Jonathan)


 drivers/perf/cxl_pmu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index 365d964b0f6a..d85d53d907a6 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -415,11 +415,12 @@ static struct attribute *cxl_pmu_event_attrs[] = {
        CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_curblk,                CXL_PMU_GID_S2M_BISNP, BIT(4)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_datblk,                CXL_PMU_GID_S2M_BISNP, BIT(5)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_invblk,                CXL_PMU_GID_S2M_BISNP, BIT(6)),
-       /* CXL rev 3.0 Table 3-43 S2M NDR Opcopdes */
+       /* CXL rev 3.1 Table 3-50 S2M NDR Opcopdes */
        CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmp,                     CXL_PMU_GID_S2M_NDR, BIT(0)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmps,                    CXL_PMU_GID_S2M_NDR, BIT(1)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmpe,                    CXL_PMU_GID_S2M_NDR, BIT(2)),
-       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(3)),
+       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmpm,                    CXL_PMU_GID_S2M_NDR, BIT(3)),
+       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(4)),
        /* CXL rev 3.0 Table 3-46 S2M DRS opcodes */
        CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdata,                 CXL_PMU_GID_S2M_DRS, BIT(0)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdatanxm,              CXL_PMU_GID_S2M_DRS, BIT(1)),
--
2.34.1


From f.fainelli at gmail.com  Tue Feb  6 20:25:17 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 6 Feb 2024 20:25:17 -0800
Subject: [PATCH net-next v2 6/6] net: dsa: b53: remove
 eee_enabled/eee_active in b53_get_mac_eee()
In-Reply-To: <20240206132923.eypnqvqwe3cga5tp@skbuf>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
 <E1rWbNI-002cCz-4x@rmk-PC.armlinux.org.uk>
 <20240206112024.3jxtcru3dupeirnj@skbuf>
 <ZcIwQcn3qlk0UjS4@shell.armlinux.org.uk>
 <20240206132923.eypnqvqwe3cga5tp@skbuf>
Message-ID: <57406055-ff3c-4788-bbf7-8476f63f90db@gmail.com>



On 2/6/2024 5:29 AM, Vladimir Oltean wrote:
> On Tue, Feb 06, 2024 at 01:12:33PM +0000, Russell King (Oracle) wrote:
>>> I know next to nothing about EEE and especially the implementation on
>>> Broadcom switches. But is the information brought by B53_EEE_LPI_INDICATE
>>> completely redundant? Is it actually in the system's best interest to
>>> ignore it?
>>
>> That's a review comment that should have been made when the original
>> change to phylib was done, because it's already ignored in kernels
>> today since the commit changing phylib that I've referenced in this
>> series - since e->eee_enabled and e->eee_active will be overwritten by
>> phylib.
> 
> That's fair, but commit d1420bb99515 ("net: phy: improve generic EEE
> ethtool functions") is dated November 2018, and my involvement with the
> kernel started in March 2019. So it would have been a bit difficult for
> me to make this observation back then.
> 
>> If we need B53_EEE_LPI_INDICATE to do something, then we need to have
>> a discussion about it, and decide how that fits in with the EEE
>> interface, and how to work around phylib's implementation.
> 
> Hopefully Florian or Doug can quickly clarify whether this is the case
> or not.

Russell's replacement is actually a better one because it will return a 
stable state. B53_EEE_LPI_INDICATE would indicate when the switch port's 
built-in PHY asserts the LPI signal to its MAC, which could be transient 
AFAICT.
-- 
Florian


From kuninori.morimoto.gx at renesas.com  Tue Feb  6 20:38:50 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Wed, 7 Feb 2024 04:38:50 +0000
Subject: [PATCH v2 1/4] gpu: drm: replace of_graph_get_next_endpoint()
In-Reply-To: <87r0hosxc3.wl-kuninori.morimoto.gx@renesas.com>
References: <87r0hosxc3.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87plx8sxb9.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
---
 drivers/gpu/drm/drm_of.c                              | 4 +++-
 drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c | 2 +-
 drivers/gpu/drm/tiny/arcpgu.c                         | 2 +-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 177b600895d3..b6b2cade69ae 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -504,6 +504,8 @@ EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep);
  * Gets parent DSI bus for a DSI device controlled through a bus other
  * than MIPI-DCS (SPI, I2C, etc.) using the Device Tree.
  *
+ * This function assumes that the device's port at 0 is the DSI input.
+ *
  * Returns pointer to mipi_dsi_host if successful, -EINVAL if the
  * request is unsupported, -EPROBE_DEFER if the DSI host is found but
  * not available, or -ENODEV otherwise.
@@ -516,7 +518,7 @@ struct mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev)
 	/*
 	 * Get first endpoint child from device.
 	 */
-	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!endpoint)
 		return ERR_PTR(-ENODEV);
 
diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
index 4618c892cdd6..e10e469aa7a6 100644
--- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
+++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
@@ -400,7 +400,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c)
 	rpi_touchscreen_i2c_write(ts, REG_POWERON, 0);
 
 	/* Look up the DSI host.  It needs to probe before we do. */
-	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!endpoint)
 		return -ENODEV;
 
diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c
index 4f8f3172379e..8c29b719ea62 100644
--- a/drivers/gpu/drm/tiny/arcpgu.c
+++ b/drivers/gpu/drm/tiny/arcpgu.c
@@ -288,7 +288,7 @@ static int arcpgu_load(struct arcpgu_drm_private *arcpgu)
 	 * There is only one output port inside each device. It is linked with
 	 * encoder endpoint.
 	 */
-	endpoint_node = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
+	endpoint_node = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 0, -1);
 	if (endpoint_node) {
 		encoder_node = of_graph_get_remote_port_parent(endpoint_node);
 		of_node_put(endpoint_node);
-- 
2.25.1



From kuninori.morimoto.gx at renesas.com  Tue Feb  6 20:39:01 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Wed, 7 Feb 2024 04:39:01 +0000
Subject: [PATCH v2 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <87r0hosxc3.wl-kuninori.morimoto.gx@renesas.com>
References: <87r0hosxc3.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87o7cssxay.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Link: https://lore.kernel.org/r/9d1e99b0-892d-4a72-a9b3-886b8ed094b0 at xs4all.nl
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 drivers/media/i2c/adv7343.c              | 2 +-
 drivers/media/i2c/adv7604.c              | 4 ++--
 drivers/media/i2c/mt9p031.c              | 2 +-
 drivers/media/i2c/mt9v032.c              | 2 +-
 drivers/media/i2c/ov2659.c               | 2 +-
 drivers/media/i2c/ov5645.c               | 2 +-
 drivers/media/i2c/ov5647.c               | 2 +-
 drivers/media/i2c/s5c73m3/s5c73m3-core.c | 2 +-
 drivers/media/i2c/s5k5baf.c              | 2 +-
 drivers/media/i2c/tc358743.c             | 2 +-
 drivers/media/i2c/tda1997x.c             | 2 +-
 drivers/media/i2c/tvp514x.c              | 2 +-
 drivers/media/i2c/tvp7002.c              | 2 +-
 13 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index ff21cd4744d3..4fbe4e18570e 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -403,7 +403,7 @@ adv7343_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 810fa8826f30..319db3e847c4 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -3204,8 +3204,8 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
 
 	np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
 
-	/* Parse the endpoint. */
-	endpoint = of_graph_get_next_endpoint(np, NULL);
+	/* FIXME: Parse the endpoint. */
+	endpoint = of_graph_get_endpoint_by_regs(np, -1, -1);
 	if (!endpoint)
 		return -EINVAL;
 
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 596200d0248c..f4b481212356 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -1078,7 +1078,7 @@ mt9p031_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 3ca76eeae7ff..e9f5c6647f97 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -1006,7 +1006,7 @@ mt9v032_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 1d0ef72a6403..d1653d7431d0 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1388,7 +1388,7 @@ ov2659_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!endpoint)
 		return NULL;
 
diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
index a26ac11c989d..9daf06ffedf4 100644
--- a/drivers/media/i2c/ov5645.c
+++ b/drivers/media/i2c/ov5645.c
@@ -1056,7 +1056,7 @@ static int ov5645_probe(struct i2c_client *client)
 	ov5645->i2c_client = client;
 	ov5645->dev = dev;
 
-	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!endpoint) {
 		dev_err(dev, "endpoint node not found\n");
 		return -EINVAL;
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 96c0fd4ff5ab..7e1ecdf2485f 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -1363,7 +1363,7 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
 	struct device_node *ep;
 	int ret;
 
-	ep = of_graph_get_next_endpoint(np, NULL);
+	ep = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!ep)
 		return -EINVAL;
 
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index af8d01f78c32..cf6be509af33 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1568,7 +1568,7 @@ static int s5c73m3_get_dt_data(struct s5c73m3 *state)
 				     "failed to request gpio S5C73M3_RST\n");
 	gpiod_set_consumer_name(state->reset, "S5C73M3_RST");
 
-	node_ep = of_graph_get_next_endpoint(node, NULL);
+	node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!node_ep) {
 		dev_warn(dev, "no endpoint defined for node: %pOF\n", node);
 		return 0;
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index de079d2c9282..6b11039c3579 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1849,7 +1849,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
 			 state->mclk_frequency);
 	}
 
-	node_ep = of_graph_get_next_endpoint(node, NULL);
+	node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!node_ep) {
 		dev_err(dev, "no endpoint defined at node %pOF\n", node);
 		return -EINVAL;
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 2785935da497..872e802cdfbe 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1895,7 +1895,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
 		return dev_err_probe(dev, PTR_ERR(refclk),
 				     "failed to get refclk\n");
 
-	ep = of_graph_get_next_endpoint(dev->of_node, NULL);
+	ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!ep) {
 		dev_err(dev, "missing endpoint node\n");
 		return -EINVAL;
diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
index 1ea703a9909f..8e4a0718c4b6 100644
--- a/drivers/media/i2c/tda1997x.c
+++ b/drivers/media/i2c/tda1997x.c
@@ -2310,7 +2310,7 @@ static int tda1997x_parse_dt(struct tda1997x_state *state)
 	pdata->vidout_sel_de = DE_FREF_SEL_DE_VHREF;
 
 	np = state->client->dev.of_node;
-	ep = of_graph_get_next_endpoint(np, NULL);
+	ep = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!ep)
 		return -EINVAL;
 
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index 5a561e5bf659..f9c9c80c33ac 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -987,7 +987,7 @@ tvp514x_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!endpoint)
 		return NULL;
 
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 30831b4b56d6..6a04ffae5343 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -893,7 +893,7 @@ tvp7002_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!endpoint)
 		return NULL;
 
-- 
2.25.1



From kuninori.morimoto.gx at renesas.com  Tue Feb  6 20:39:08 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Wed, 7 Feb 2024 04:39:08 +0000
Subject: [PATCH v2 3/4] media: platform: replace of_graph_get_next_endpoint()
In-Reply-To: <87r0hosxc3.wl-kuninori.morimoto.gx@renesas.com>
References: <87r0hosxc3.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87msscsxar.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 drivers/media/platform/atmel/atmel-isi.c              | 4 ++--
 drivers/media/platform/intel/pxa_camera.c             | 2 +-
 drivers/media/platform/samsung/exynos4-is/fimc-is.c   | 2 +-
 drivers/media/platform/samsung/exynos4-is/mipi-csis.c | 3 ++-
 drivers/media/platform/st/stm32/stm32-dcmi.c          | 4 ++--
 drivers/media/platform/ti/davinci/vpif.c              | 3 +--
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index f8450a8ccda6..c1108df72dd5 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -834,7 +834,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
 	isi->pdata.full_mode = 1;
 	isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
 
-	np = of_graph_get_next_endpoint(np, NULL);
+	np = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!np) {
 		dev_err(&pdev->dev, "Could not find the endpoint\n");
 		return -EINVAL;
@@ -1158,7 +1158,7 @@ static int isi_graph_init(struct atmel_isi *isi)
 	struct device_node *ep;
 	int ret;
 
-	ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
+	ep = of_graph_get_endpoint_by_regs(isi->dev->of_node, 0, -1);
 	if (!ep)
 		return -EINVAL;
 
diff --git a/drivers/media/platform/intel/pxa_camera.c b/drivers/media/platform/intel/pxa_camera.c
index 59b89e421dc2..d904952bf00e 100644
--- a/drivers/media/platform/intel/pxa_camera.c
+++ b/drivers/media/platform/intel/pxa_camera.c
@@ -2207,7 +2207,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
 		pcdev->mclk = mclk_rate;
 	}
 
-	np = of_graph_get_next_endpoint(np, NULL);
+	np = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!np) {
 		dev_err(dev, "could not find endpoint\n");
 		return -EINVAL;
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
index a08c87ef6e2d..39aab667910d 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
@@ -175,7 +175,7 @@ static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,
 		return -EINVAL;
 	}
 
-	ep = of_graph_get_next_endpoint(node, NULL);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return -ENXIO;
 
diff --git a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
index aae8a8b2c0f4..4b9b20ba3504 100644
--- a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
@@ -727,7 +727,8 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
 				 &state->max_num_lanes))
 		return -EINVAL;
 
-	node = of_graph_get_next_endpoint(node, NULL);
+	/* from port at 3 or port at 4 */
+	node = of_graph_get_endpoint_by_regs(node, -1, -1);
 	if (!node) {
 		dev_err(&pdev->dev, "No port node at %pOF\n",
 				pdev->dev.of_node);
diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c
index c4610e305546..ff3331af9406 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmi.c
@@ -1855,7 +1855,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi)
 	struct device_node *ep;
 	int ret;
 
-	ep = of_graph_get_next_endpoint(dcmi->dev->of_node, NULL);
+	ep = of_graph_get_endpoint_by_regs(dcmi->dev->of_node, 0, -1);
 	if (!ep) {
 		dev_err(dcmi->dev, "Failed to get next endpoint\n");
 		return -EINVAL;
@@ -1907,7 +1907,7 @@ static int dcmi_probe(struct platform_device *pdev)
 				     "Could not get reset control\n");
 
 	/* Get bus characteristics from devicetree */
-	np = of_graph_get_next_endpoint(np, NULL);
+	np = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!np) {
 		dev_err(&pdev->dev, "Could not find the endpoint\n");
 		return -ENODEV;
diff --git a/drivers/media/platform/ti/davinci/vpif.c b/drivers/media/platform/ti/davinci/vpif.c
index 63cdfed37bc9..f4e1fa76bf37 100644
--- a/drivers/media/platform/ti/davinci/vpif.c
+++ b/drivers/media/platform/ti/davinci/vpif.c
@@ -465,8 +465,7 @@ static int vpif_probe(struct platform_device *pdev)
 	 * so their devices need to be registered manually here
 	 * for their legacy platform_drivers to work.
 	 */
-	endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
-					      endpoint);
+	endpoint = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 0, -1);
 	if (!endpoint)
 		return 0;
 	of_node_put(endpoint);
-- 
2.25.1



From kuninori.morimoto.gx at renesas.com  Tue Feb  6 20:39:17 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Wed, 7 Feb 2024 04:39:17 +0000
Subject: [PATCH v2 4/4] video: fbdev: replace of_graph_get_next_endpoint()
In-Reply-To: <87r0hosxc3.wl-kuninori.morimoto.gx@renesas.com>
References: <87r0hosxc3.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87le7wsxai.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 drivers/video/fbdev/omap2/omapfb/dss/dsi.c    |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/dss-of.c | 20 +------------------
 drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c  |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c  |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/venc.c   |  3 ++-
 drivers/video/fbdev/pxafb.c                   |  2 +-
 include/video/omapfb_dss.h                    |  3 ---
 7 files changed, 10 insertions(+), 27 deletions(-)

diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
index b7eb17a16ec4..1f13bcf73da5 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
@@ -28,6 +28,7 @@
 #include <linux/debugfs.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/of_platform.h>
 #include <linux/component.h>
 
@@ -5079,7 +5080,7 @@ static int dsi_probe_of(struct platform_device *pdev)
 	struct device_node *ep;
 	struct omap_dsi_pin_config pin_cfg;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
index 0282d4eef139..14965a3fd05b 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
@@ -130,24 +130,6 @@ static struct device_node *omapdss_of_get_remote_port(const struct device_node *
 	return np;
 }
 
-struct device_node *
-omapdss_of_get_first_endpoint(const struct device_node *parent)
-{
-	struct device_node *port, *ep;
-
-	port = omapdss_of_get_next_port(parent, NULL);
-
-	if (!port)
-		return NULL;
-
-	ep = omapdss_of_get_next_endpoint(port, NULL);
-
-	of_node_put(port);
-
-	return ep;
-}
-EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint);
-
 struct omap_dss_device *
 omapdss_of_find_source_for_first_ep(struct device_node *node)
 {
@@ -155,7 +137,7 @@ omapdss_of_find_source_for_first_ep(struct device_node *node)
 	struct device_node *src_port;
 	struct omap_dss_device *src;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return ERR_PTR(-EINVAL);
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
index f05b4e35a842..8f407ec134dc 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
@@ -20,6 +20,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/regulator/consumer.h>
 #include <linux/component.h>
 #include <video/omapfb_dss.h>
@@ -529,7 +530,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
 	struct device_node *ep;
 	int r;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
index 03292945b1d4..4ad219f522b9 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
@@ -25,6 +25,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/regulator/consumer.h>
 #include <linux/component.h>
 #include <video/omapfb_dss.h>
@@ -561,7 +562,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
 	struct device_node *ep;
 	int r;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/venc.c b/drivers/video/fbdev/omap2/omapfb/dss/venc.c
index c9d40e28a06f..0bd80d3b8f1b 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/venc.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/venc.c
@@ -24,6 +24,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/component.h>
 
 #include <video/omapfb_dss.h>
@@ -764,7 +765,7 @@ static int venc_probe_of(struct platform_device *pdev)
 	u32 channels;
 	int r;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
index fa943612c4e2..2ef56fa28aff 100644
--- a/drivers/video/fbdev/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
@@ -2171,7 +2171,7 @@ static int of_get_pxafb_mode_info(struct device *dev,
 	u32 bus_width;
 	int ret, i;
 
-	np = of_graph_get_next_endpoint(dev->of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!np) {
 		dev_err(dev, "could not find endpoint\n");
 		return -EINVAL;
diff --git a/include/video/omapfb_dss.h b/include/video/omapfb_dss.h
index e8eaac2cb7b8..a8c0c3eeeb5b 100644
--- a/include/video/omapfb_dss.h
+++ b/include/video/omapfb_dss.h
@@ -819,9 +819,6 @@ struct device_node *
 omapdss_of_get_next_endpoint(const struct device_node *parent,
 			     struct device_node *prev);
 
-struct device_node *
-omapdss_of_get_first_endpoint(const struct device_node *parent);
-
 struct omap_dss_device *
 omapdss_of_find_source_for_first_ep(struct device_node *node);
 #else
-- 
2.25.1



From andersson at kernel.org  Tue Feb  6 20:46:17 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Tue,  6 Feb 2024 22:46:17 -0600
Subject: [PATCH v2 0/3] ARM: qcom: drop 32-bit machine Kconfig entries
In-Reply-To: <20231216162700.863456-1-dmitry.baryshkov@linaro.org>
References: <20231216162700.863456-1-dmitry.baryshkov@linaro.org>
Message-ID: <170728117673.479358.10461724344516754087.b4-ty@kernel.org>


On Sat, 16 Dec 2023 18:26:57 +0200, Dmitry Baryshkov wrote:
> The Kconfig for 32-bit Qualcomm arch predates DT and multi-machine
> support. It still defines ARCH_MSM* types for some (but not all) 32-bit
> Qualcomm machines. The MSM_IOMMU driver has a strict dependency on one
> of such kinds.
> 
> With the DT support in place, this has become obsolete quite a while
> ago. Replace all 32-bit Qualcomm ARCH kinds with the single Kconfig
> entry for the workaround required to be enabled for some of those 32-bit
> platforms.
> 
> [...]

Applied, thanks!

[1/3] iommu/msm-iommu: don't limit the driver too much
      commit: 18368ee25d881981971fde430c7f33cbc27359d1
[2/3] ARM: qcom: drop most of 32-bit ARCH_QCOM subtypes
      commit: 85148df36835d6bbdb2e4d06a3322629e4bb12c6
[3/3] ARM: qcom: merge remaining subplatforms into sensible Kconfig entry
      commit: 99497df59427a11222571034afebf2f0f7f9a3e2

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From andersson at kernel.org  Tue Feb  6 20:46:31 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Tue,  6 Feb 2024 22:46:31 -0600
Subject: (subset) [PATCH 0/3] arm64: qcom: sm8650: enable Audio on MTP and QRD
In-Reply-To: <20240125-topic-sm8650-upstream-audio-dt-v1-0-c24d23ae5763@linaro.org>
References: <20240125-topic-sm8650-upstream-audio-dt-v1-0-c24d23ae5763@linaro.org>
Message-ID: <170728117685.479358.1744444074409243114.b4-ty@kernel.org>


On Thu, 25 Jan 2024 17:42:40 +0100, Neil Armstrong wrote:
> Add the remaining Audio nodes on the SM8650-QRD & MTP boards including:
> - Qualcomm Aqstic WCD9395 audio codec on the RX & TX Soundwire interfaces
> - WSA8845 Left & Right Speakers
> - Link the WCD9395 Codec node to the WCD9395 USB SubSystem node to handle
>   the USB-C Audio Accessory Mode events & lane swapping
> - Sound card with routing for Speakers and Microphones
> 
> [...]

Applied, thanks!

[1/3] arm64: dts: qcom: sm8650-qrd: add Audio nodes
      commit: ce745475acacfe159a358897e122e38b045f8008
[2/3] arm64: dts: qcom: sm8650-mtp: add Audio sound card node
      commit: 6e9d86933cab198d6d86ee19f4b81fd1732787b3

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From kuninori.morimoto.gx at renesas.com  Tue Feb  6 20:38:20 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Wed, 7 Feb 2024 04:38:20 +0000
Subject: [PATCH v2 0/4] of: replace of_graph_get_next_endpoint()
Message-ID: <87r0hosxc3.wl-kuninori.morimoto.gx@renesas.com>


Hi Rob

This is v2 of replace of_graph_get_next_endpoint()

We should get rid of or minimize of_graph_get_next_endpoint() in
its current form. In general, drivers should be asking for a specific 
port number because their function is fixed in the binding.

	https://lore.kernel.org/r/20240131184347.GA1906672-robh at kernel.org

This patch-set replace of_graph_get_next_endpoint() by
of_graph_get_endpoint_by_regs(). There are still next_endpoint()
after this patch-set, but it will be replaced by
for_each_endpoint_of_node() in next patch-set (A)

[*] this patch-set
[o] done

	[o] tidyup of_graph_get_endpoint_count()
	[*] replace endpoint func - use endpoint_by_regs()
(A)	[ ] replace endpoint func - use for_each()
	[ ] rename endpoint func to device_endpoint
	[ ] add new port function
	[ ] add new endpont function
	[ ] remove of_graph_get_next_device_endpoint()

v1 -> v2
	- add Reviewed-by from Launrent
	- use by_regs(xx, -1, -1) for some devices
	- add extra explain for drm_of_get_dsi_bus()
	- add FIXME and Link on adv7604.c
	- based on latest of branch

Kuninori Morimoto (4):
  gpu: drm: replace of_graph_get_next_endpoint()
  media: i2c: replace of_graph_get_next_endpoint()
  media: platform: replace of_graph_get_next_endpoint()
  video: fbdev: replace of_graph_get_next_endpoint()

 drivers/gpu/drm/drm_of.c                      |  4 +++-
 .../drm/panel/panel-raspberrypi-touchscreen.c |  2 +-
 drivers/gpu/drm/tiny/arcpgu.c                 |  2 +-
 drivers/media/i2c/adv7343.c                   |  2 +-
 drivers/media/i2c/adv7604.c                   |  4 ++--
 drivers/media/i2c/mt9p031.c                   |  2 +-
 drivers/media/i2c/mt9v032.c                   |  2 +-
 drivers/media/i2c/ov2659.c                    |  2 +-
 drivers/media/i2c/ov5645.c                    |  2 +-
 drivers/media/i2c/ov5647.c                    |  2 +-
 drivers/media/i2c/s5c73m3/s5c73m3-core.c      |  2 +-
 drivers/media/i2c/s5k5baf.c                   |  2 +-
 drivers/media/i2c/tc358743.c                  |  2 +-
 drivers/media/i2c/tda1997x.c                  |  2 +-
 drivers/media/i2c/tvp514x.c                   |  2 +-
 drivers/media/i2c/tvp7002.c                   |  2 +-
 drivers/media/platform/atmel/atmel-isi.c      |  4 ++--
 drivers/media/platform/intel/pxa_camera.c     |  2 +-
 .../platform/samsung/exynos4-is/fimc-is.c     |  2 +-
 .../platform/samsung/exynos4-is/mipi-csis.c   |  3 ++-
 drivers/media/platform/st/stm32/stm32-dcmi.c  |  4 ++--
 drivers/media/platform/ti/davinci/vpif.c      |  3 +--
 drivers/video/fbdev/omap2/omapfb/dss/dsi.c    |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/dss-of.c | 20 +------------------
 drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c  |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c  |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/venc.c   |  3 ++-
 drivers/video/fbdev/pxafb.c                   |  2 +-
 include/video/omapfb_dss.h                    |  3 ---
 29 files changed, 38 insertions(+), 53 deletions(-)

-- 
2.25.1



From nicolinc at nvidia.com  Tue Feb  6 21:27:22 2024
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Tue, 6 Feb 2024 21:27:22 -0800
Subject: [PATCH v5 00/17] Update SMMUv3 to the modern iommu API (part 1/3)
In-Reply-To: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <ZcMUujkhNkhEpOSP@Asurada-Nvidia>

On Tue, Feb 06, 2024 at 11:12:37AM -0400, Jason Gunthorpe wrote:
> The SMMUv3 driver was originally written in 2015 when the iommu driver
> facing API looked quite different. The API has evolved, especially lately,
> and the driver has fallen behind.
> 
> This work aims to bring make the SMMUv3 driver the best IOMMU driver with
> the most comprehensive implementation of the API. After all parts it
> addresses:
> 
>  - Global static BLOCKED and IDENTITY domains with 'never fail' attach
>    semantics. BLOCKED is desired for efficient VFIO.
> 
>  - Support map before attach for PAGING iommu_domains.
> 
>  - attach_dev failure does not change the HW configuration.
> 
>  - Fully hitless transitions between IDENTITY -> DMA -> IDENTITY.
>    The API has IOMMU_RESV_DIRECT which is expected to be
>    continuously translating.
> 
>  - Safe transitions between PAGING -> BLOCKED, do not ever temporarily
>    do IDENTITY. This is required for iommufd security.
> 
>  - Full PASID API support including:
>     - S1/SVA domains attached to PASIDs
>     - IDENTITY/BLOCKED/S1 attached to RID
>     - Change of the RID domain while PASIDs are attached
> 
>  - Streamlined SVA support using the core infrastructure
> 
>  - Hitless, whenever possible, change between two domains
> 
>  - iommufd IOMMU_GET_HW_INFO, IOMMU_HWPT_ALLOC_NEST_PARENT, and
>    IOMMU_DOMAIN_NESTED support
> 
> Over all these things are going to become more accessible to iommufd, and
> exposed to VMs, so it is important for the driver to have a robust
> implementation of the API.
> 
> The work is split into three parts, with this part largely focusing on the
> STE and building up to the BLOCKED & IDENTITY global static domains.
> 
> The second part largely focuses on the CD and builds up to having a common
> PASID infrastructure that SVA and S1 domains equally use.
> 
> The third part has some random cleanups and the iommufd related parts.
> 
> Overall this takes the approach of turning the STE/CD programming upside
> down where the CD/STE value is computed right at a driver callback
> function and then pushed down into programming logic. The programming
> logic hides the details of the required CD/STE tear-less update. This
> makes the CD/STE functions independent of the arm_smmu_domain which makes
> it fairly straightforward to untangle all the different call chains, and
> add news ones.
> 
> Further, this frees the arm_smmu_domain related logic from keeping track
> of what state the STE/CD is currently in so it can carefully sequence the
> correct update. There are many new update pairs that are subtly introduced
> as the work progresses.
> 
> The locking to support BTM via arm_smmu_asid_lock is a bit subtle right
> now and patches throughout this work adjust and tighten this so that it is
> clearer and doesn't get broken.
> 
> Once the lower STE layers no longer need to touch arm_smmu_domain we can
> isolate struct arm_smmu_domain to be only used for PAGING domains, audit
> all the to_smmu_domain() calls to be only in PAGING domain ops, and
> introduce the normal global static BLOCKED/IDENTITY domains using the new
> STE infrastructure. Part 2 will ultimately migrate SVA over to use
> arm_smmu_domain as well.
> 
> All parts are on github:
> 
>  https://github.com/jgunthorpe/linux/commits/smmuv3_newapi
> 
> v5:
>  - Rebase on v6.8-rc3
>  - Remove the writer argument to arm_smmu_entry_writer_ops get_used()
>  - Swap order of hweight tests so one call to hweight8() can be removed
>  - Add STRTAB_STE_2_S2VMID used for STRTAB_STE_0_CFG_S1_TRANS, for
>    S2 bypass the VMID is used but 0
>  - Be more exact when generating STEs and store 0's to document the HW
>    is using that value and 0 is actually a deliberate choice for VMID and
>    SHCFG.
>  - Remove cd_table argument to arm_smmu_make_cdtable_ste()
>  - Put arm_smmu_rmr_install_bypass_ste() after setting up a 2 level table
>  - Pull patch "Check that the RID domain is S1 in SVA" from part 2 to
>    guard against memory corruption on failure paths
>  - Tighten the used logic for SHCFG to accommodate nesting patches in
>    part 3
>  - Additional comments and commit message adjustments

I have retested this v5 alone with SVA cases and system sanity.

I also did similar tests with part-2 in the "smmuv3_newapi" branch,
plus adding "iommu.passthrough=y" string to cover the S1DSS.BYPASS
use case.

After that, I retested the entire branch including part-3 with a
nested-smmu VM, to cover different STE configurations.

All results look good.

Tested-by: Nicolin Chen <nicolinc at nvidia.com>


From u-kumar1 at ti.com  Tue Feb  6 21:33:52 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Wed, 7 Feb 2024 11:03:52 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <87ttmly4fa.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
 <20240206131420.wtitflgav23jto2q@verbally>
 <871q9pzoiq.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <c5b6bd1d-dbb4-4bfb-8b3e-9b0733e2ba5d@ti.com>
 <c2b7f22d-f07d-4cac-8a01-af7b014e7ff4@ti.com>
 <a4fdbcfe-e0e0-4280-8638-e39b6b46778e@ti.com>
 <87ttmly4fa.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
Message-ID: <e2ea03ce-0367-413b-aca9-7c1fabda173a@ti.com>


On 2/6/2024 9:24 PM, Kamlesh Gurudasani wrote:
> "Kumar, Udit" <u-kumar1 at ti.com> writes:
>
>>>>>> get_freq is a bit expensive as it has to walk the clock tree to find
>>>>>> the clock frequency (at least the first time?). just wondering if
>>>>>> there is lighter alternative here?
>>>>>>
>>>>> How about get_clock? Doesn't read the registers at least.
>>>> Said API needs, some flags to be passed,
>>>>
>>>> Can those flag be set to zero, Chandru ?
>>>
>>> get_clock doesn't require any flags to be passed.
>>
>> May be firmware does not need it but? I was referring to
>>
>> https://elixir.bootlin.com/linux/latest/source/drivers/clk/keystone/sci-clk.c#L78
> Just took a look,
>
> I now understand the reason for confusion,
>
> #define TI_SCI_MSG_SET_CLOCK_STATE	0x0100
> #define TI_SCI_MSG_GET_CLOCK_STATE	0x0101
>
> cops->get_clock = ti_sci_cmd_get_clock;  --> refers to
> TI_SCI_MSG_SET_CLOCK_STATE
> That's why we are passing the flag from linux for get_clock
>
> Linux is using terminology of get/put.
>
> As Chandru pointed, we don't have to pass flags, cause he is refering
> to TI_SCI_MSG_GET_CLOCK_STATE
>
> Below functions passes TI_SCI_MSG_GET_CLOCK_STATE to DM, which is what
> we actually want.
> cops->is_auto = ti_sci_cmd_clk_is_auto;
> cops->is_on = ti_sci_cmd_clk_is_on;
> cops->is_off = ti_sci_cmd_clk_is_off;


I think calling ti_sci_cmd_clk_is_auto should be good . other functions 
needs current state and requested state.

Chandru ?

>
> Which should be safe to call, Chandru can confirm.
>
> Regards,
> Kamlesh
>>
>>
>>>
>>>>
>>>>> Regards,
>>>>> Kamlesh


From zajec5 at gmail.com  Tue Feb  6 21:40:29 2024
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Wed, 7 Feb 2024 06:40:29 +0100
Subject: [PATCH V3 1/3] dt-bindings: vendor-prefixes: add acelink
In-Reply-To: <20231207080512.3688-1-zajec5@gmail.com>
References: <20231207080512.3688-1-zajec5@gmail.com>
Message-ID: <b75897ce-a6e7-4e7d-a41c-c6466d9d746e@gmail.com>

On 7.12.2023 09:05, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Acelink is a Taiwan company providing network products (routers, access
> points, switches, cameras and more).
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

It's 2 months now that I'm waiting for this patchset to be applied.

Can you handle it now, please?


While at it please also look at two more pending patches:
[PATCH 1/2] arm64: dts: mediatek: mt7986: reorder properties
[PATCH 2/2] arm64: dts: mediatek: mt7986: reorder nodes


From tudor.ambarus at linaro.org  Tue Feb  6 22:20:56 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed, 7 Feb 2024 06:20:56 +0000
Subject: [PATCH 1/4] spi: s3c64xx: explicitly include <linux/types.h>
In-Reply-To: <CAPLW+4=Xd+B=ZncqPgU4qaJ8zY8JJvJZApdUW_v0w6yr2cy9Sg@mail.gmail.com>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
 <20240206085238.1208256-2-tudor.ambarus@linaro.org>
 <CAPLW+4=Xd+B=ZncqPgU4qaJ8zY8JJvJZApdUW_v0w6yr2cy9Sg@mail.gmail.com>
Message-ID: <16a5e423-1111-49ff-ad6c-b0bb89a4879a@linaro.org>



On 2/6/24 18:02, Sam Protsenko wrote:
> On Tue, Feb 6, 2024 at 2:52?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>>
>> The driver uses u32 and relies on an implicit inclusion of
>> <linux/types.h>.
>>
>> It is good practice to directly include all headers used, it avoids
>> implicit dependencies and spurious breakage if someone rearranges
>> headers and causes the implicit include to vanish.
>>
>> Include the missing header.
>>
>> Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver")
> 
> Not sure if Fixes tag is needed here.

We have already talked about this. If a patch that causes the implicit
include to vanish is backported to stable, it will reveal the missing
header here and will result in backporting this patch as well. So, as a
good practice let's allow this patch to be queued to stable, it will
avoid possible compilation errors.

I guess Mark has to break the tie again. Or Greg if he cares, I added
him in To:.

> 
>> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
>> ---
>>  drivers/spi/spi-s3c64xx.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
>> index 72c35dbe53b2..c15ca6a910dc 100644
>> --- a/drivers/spi/spi-s3c64xx.c
>> +++ b/drivers/spi/spi-s3c64xx.c
>> @@ -17,6 +17,7 @@
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>>  #include <linux/spi/spi.h>
>> +#include <linux/types.h>
> 
> Is this really needed for the further patches in this series?
> 

Yes, because in patch 3/4 I use u8 and u16 and I don't want to use those
without having the header included. Do you find this wrong?

>>
>>  #define MAX_SPI_PORTS          12
>>  #define S3C64XX_SPI_QUIRK_CS_AUTO      (1 << 1)
>> --
>> 2.43.0.594.gd9cf4e227d-goog
>>


From lkp at intel.com  Tue Feb  6 22:37:46 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 07 Feb 2024 14:37:46 +0800
Subject: [linux-next:master] BUILD REGRESSION
 ac139fc7db67968e5061715508b5fc4aa7c40c56
Message-ID: <202402071439.AER2foE3-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: ac139fc7db67968e5061715508b5fc4aa7c40c56  Add linux-next specific files for 20240206

Error/Warning reports:

https://lore.kernel.org/oe-kbuild-all/202402061900.rTuYDlo6-lkp at intel.com
https://lore.kernel.org/oe-kbuild-all/202402062106.cfArbjsv-lkp at intel.com
https://lore.kernel.org/oe-kbuild-all/202402062134.a6CqAt3s-lkp at intel.com
https://lore.kernel.org/oe-kbuild-all/202402062139.MKznS4Qf-lkp at intel.com
https://lore.kernel.org/oe-kbuild-all/202402062151.Kq60k2LK-lkp at intel.com
https://lore.kernel.org/oe-kbuild-all/202402062210.3YyBVGF1-lkp at intel.com

Error/Warning: (recently discovered and may have been fixed)

arch/sh/boot/compressed/../../../../lib/xz/xz_dec_lzma2.c:648:(.text+0xaf0): undefined reference to `__ubsan_handle_shift_out_of_bounds'
arch/sh/boot/compressed/../../../../lib/zlib_inflate/inffast.c:132:(.text+0x738): undefined reference to `__ubsan_handle_shift_out_of_bounds'
arch/sh/boot/compressed/../../../../lib/zlib_inflate/inflate.c:57:(.text+0xbd0): undefined reference to `__ubsan_handle_shift_out_of_bounds'
arch/sh/boot/compressed/../../../../lib/zlib_inflate/inftrees.c:270:(.text+0x3dc): undefined reference to `__ubsan_handle_shift_out_of_bounds'
arch/xtensa/boot/lib/inflate.c:91:(.text+0x1a4): undefined reference to `__ubsan_handle_out_of_bounds'
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c:1955: warning: Function parameter or struct member 'gsp' not described in 'nvkm_gsp_radix3_sg'
fs/ceph/locks.c:379:27: warning: unused variable 'lock' [-Wunused-variable]
make[2]: *** kselftest/livepatch/test_modules: No such file or directory.  Stop.
powerpc-linux-ld: warning: orphan section `.bss..Lubsan_data202' from `fs/overlayfs/copy_up.o' being placed in section `.bss..Lubsan_data202'
powerpc-linux-ld: warning: orphan section `.bss..Lubsan_data219' from `kernel/ptrace.o' being placed in section `.bss..Lubsan_data219'
powerpc-linux-ld: warning: orphan section `.bss..Lubsan_data327' from `kernel/sched/core.o' being placed in section `.bss..Lubsan_data327'
sh4-linux-ld: arch/sh/boot/compressed/../../../../lib/zlib_inflate/inffast.c:305:(.text+0xac4): undefined reference to `__ubsan_handle_shift_out_of_bounds'
sh4-linux-ld: arch/sh/boot/compressed/../../../../lib/zlib_inflate/inftrees.c:315:(.text+0x60c): undefined reference to `__ubsan_handle_shift_out_of_bounds'
sh4-linux-ld: arch/sh/boot/compressed/misc.o:(.debug_addr+0x388): undefined reference to `__ubsan_handle_shift_out_of_bounds'
sh4-linux-ld: misc.c:(.text+0x23d4): undefined reference to `__ubsan_handle_shift_out_of_bounds'
xtensa-linux-ld: arch/xtensa/boot/lib/inflate.c:487:(.text+0x546): undefined reference to `__ubsan_handle_out_of_bounds'

Error/Warning ids grouped by kconfigs:

gcc_recent_errors
|-- arc-randconfig-r113-20240206
|   `-- drivers-gpu-drm-bridge-imx-imx8mp-hdmi-pvi.c:sparse:sparse:Using-plain-integer-as-NULL-pointer
|-- arm-randconfig-r071-20240206
|   `-- fs-ceph-locks.c:warning:unused-variable-lock
|-- i386-buildonly-randconfig-003-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-014-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-016-20240206
|   `-- include-kunit-test.h:warning:s-directive-argument-is-null
|-- i386-randconfig-052-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- mips-allyesconfig
|   |-- (.ref.text):relocation-truncated-to-fit:R_MIPS_26-against-start_secondary
|   `-- (.text):relocation-truncated-to-fit:R_MIPS_26-against-kernel_entry
|-- nios2-randconfig-001-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- parisc-defconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- parisc-randconfig-001-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- powerpc-randconfig-r022-20230201
|   |-- powerpc-linux-ld:warning:orphan-section-bss..Lubsan_data202-from-fs-overlayfs-copy_up.o-being-placed-in-section-.bss..Lubsan_data202
|   |-- powerpc-linux-ld:warning:orphan-section-bss..Lubsan_data219-from-kernel-ptrace.o-being-placed-in-section-.bss..Lubsan_data219
|   `-- powerpc-linux-ld:warning:orphan-section-bss..Lubsan_data327-from-kernel-sched-core.o-being-placed-in-section-.bss..Lubsan_data327
|-- powerpc64-randconfig-003-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- sh-randconfig-r003-20220501
|   |-- arch-sh-boot-compressed-..-..-..-..-lib-zlib_inflate-inffast.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|   |-- arch-sh-boot-compressed-..-..-..-..-lib-zlib_inflate-inflate.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|   |-- arch-sh-boot-compressed-..-..-..-..-lib-zlib_inflate-inftrees.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|   |-- sh4-linux-ld:arch-sh-boot-compressed-..-..-..-..-lib-zlib_inflate-inffast.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|   `-- sh4-linux-ld:arch-sh-boot-compressed-..-..-..-..-lib-zlib_inflate-inftrees.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|-- sh-randconfig-r015-20220607
|   `-- sh4-linux-ld:misc.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|-- sh-randconfig-r023-20230502
|   |-- arch-sh-boot-compressed-..-..-..-..-lib-xz-xz_dec_lzma2.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|   `-- sh4-linux-ld:arch-sh-boot-compressed-misc.o:(.debug_addr):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|-- sparc64-randconfig-001-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- sparc64-randconfig-002-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-003-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-004-20240206
|   `-- include-kunit-test.h:warning:s-directive-argument-is-null
|-- x86_64-randconfig-161-20240206
|   |-- fs-bcachefs-btree_locking.c-bch2_trans_relock()-warn:passing-zero-to-PTR_ERR
|   |-- fs-bcachefs-buckets.c-bch2_trans_account_disk_usage_change()-error:we-previously-assumed-trans-disk_res-could-be-null-(see-line-)
|   `-- mm-huge_memory.c-thpsize_create()-warn:Calling-kobject_put-get-with-state-initialized-unset-from-line:
|-- x86_64-rhel-8.3-bpf
|   `-- make:kselftest-livepatch-test_modules:No-such-file-or-directory.-Stop.
`-- xtensa-randconfig-r022-20220710
    |-- arch-xtensa-boot-lib-inflate.c:(.text):undefined-reference-to-__ubsan_handle_out_of_bounds
    `-- xtensa-linux-ld:arch-xtensa-boot-lib-inflate.c:(.text):undefined-reference-to-__ubsan_handle_out_of_bounds
clang_recent_errors
|-- arm64-randconfig-002-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-buildonly-randconfig-002-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-buildonly-randconfig-004-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-003-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-004-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-013-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-054-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- powerpc-randconfig-003-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-006-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-012-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-014-20240206
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
`-- x86_64-randconfig-122-20240206
    |-- fs-quota-dquot.c:sparse:sparse:incompatible-types-in-comparison-expression-(different-address-spaces):
    `-- fs-smb-client-file.c:sparse:sparse:symbol-cifs_req_ops-was-not-declared.-Should-it-be-static

elapsed time: 1479m

configs tested: 179
configs skipped: 3

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                   randconfig-001-20240206   gcc  
arc                   randconfig-002-20240206   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm                        mvebu_v7_defconfig   clang
arm                        neponset_defconfig   gcc  
arm                   randconfig-001-20240206   clang
arm                   randconfig-002-20240206   gcc  
arm                   randconfig-003-20240206   gcc  
arm                   randconfig-004-20240206   clang
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240206   gcc  
arm64                 randconfig-002-20240206   clang
arm64                 randconfig-003-20240206   gcc  
arm64                 randconfig-004-20240206   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240206   gcc  
csky                  randconfig-002-20240206   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
hexagon               randconfig-001-20240206   clang
hexagon               randconfig-002-20240206   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-001-20240206   clang
i386         buildonly-randconfig-002-20240206   clang
i386         buildonly-randconfig-003-20240206   gcc  
i386         buildonly-randconfig-004-20240206   clang
i386         buildonly-randconfig-005-20240206   gcc  
i386         buildonly-randconfig-006-20240206   gcc  
i386                                defconfig   clang
i386                  randconfig-001-20240206   clang
i386                  randconfig-002-20240206   clang
i386                  randconfig-003-20240206   clang
i386                  randconfig-004-20240206   clang
i386                  randconfig-005-20240206   clang
i386                  randconfig-006-20240206   clang
i386                  randconfig-011-20240206   clang
i386                  randconfig-012-20240206   gcc  
i386                  randconfig-013-20240206   clang
i386                  randconfig-014-20240206   gcc  
i386                  randconfig-015-20240206   gcc  
i386                  randconfig-016-20240206   gcc  
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240206   gcc  
loongarch             randconfig-002-20240206   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
m68k                       m5249evb_defconfig   gcc  
m68k                        mvme147_defconfig   gcc  
m68k                            q40_defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                          malta_defconfig   gcc  
mips                      maltasmvp_defconfig   gcc  
mips                           mtx1_defconfig   clang
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240206   gcc  
nios2                 randconfig-002-20240206   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                randconfig-001-20240206   gcc  
parisc                randconfig-002-20240206   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc                   currituck_defconfig   clang
powerpc                  iss476-smp_defconfig   gcc  
powerpc                   microwatt_defconfig   gcc  
powerpc                      ppc64e_defconfig   gcc  
powerpc               randconfig-001-20240206   clang
powerpc               randconfig-002-20240206   gcc  
powerpc               randconfig-003-20240206   clang
powerpc                  storcenter_defconfig   gcc  
powerpc64             randconfig-001-20240206   gcc  
powerpc64             randconfig-002-20240206   clang
powerpc64             randconfig-003-20240206   gcc  
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                 randconfig-001-20240206   gcc  
riscv                 randconfig-002-20240206   clang
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240206   clang
s390                  randconfig-002-20240206   clang
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                    randconfig-001-20240206   gcc  
sh                    randconfig-002-20240206   gcc  
sh                          sdk7780_defconfig   gcc  
sh                           se7722_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240206   gcc  
sparc64               randconfig-002-20240206   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                    randconfig-001-20240206   clang
um                    randconfig-002-20240206   gcc  
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240206   gcc  
x86_64       buildonly-randconfig-002-20240206   clang
x86_64       buildonly-randconfig-003-20240206   gcc  
x86_64       buildonly-randconfig-004-20240206   gcc  
x86_64       buildonly-randconfig-005-20240206   gcc  
x86_64       buildonly-randconfig-006-20240206   gcc  
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240206   clang
x86_64                randconfig-002-20240206   clang
x86_64                randconfig-003-20240206   gcc  
x86_64                randconfig-004-20240206   gcc  
x86_64                randconfig-005-20240206   gcc  
x86_64                randconfig-006-20240206   clang
x86_64                randconfig-011-20240206   gcc  
x86_64                randconfig-012-20240206   clang
x86_64                randconfig-013-20240206   gcc  
x86_64                randconfig-014-20240206   clang
x86_64                randconfig-015-20240206   gcc  
x86_64                randconfig-016-20240206   clang
x86_64                randconfig-071-20240206   gcc  
x86_64                randconfig-072-20240206   gcc  
x86_64                randconfig-073-20240206   gcc  
x86_64                randconfig-074-20240206   gcc  
x86_64                randconfig-075-20240206   clang
x86_64                randconfig-076-20240206   gcc  
x86_64                          rhel-8.3-rust   clang
xtensa                           alldefconfig   gcc  
xtensa                            allnoconfig   gcc  
xtensa                randconfig-001-20240206   gcc  
xtensa                randconfig-002-20240206   gcc  
xtensa                         virt_defconfig   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From yangyicong at huawei.com  Tue Feb  6 23:02:23 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Wed, 7 Feb 2024 15:02:23 +0800
Subject: [PATCH] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <20240206100929.00007128@Huawei.com>
References: <20240123071201.30914-1-yangyicong@huawei.com>
 <20240206100929.00007128@Huawei.com>
Message-ID: <693e27ed-48e6-5463-a827-a020f0ed5fc2@huawei.com>

On 2024/2/6 18:09, Jonathan Cameron wrote:
> On Tue, 23 Jan 2024 15:12:01 +0800
> Yicong Yang <yangyicong at huawei.com> wrote:
> 
>> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> If you end up doing a v2, a few typos and grammar tweaks.
> A few other trivial comments inline on things that might improve readability
> a tiny bit.
> 

Thanks for the comments.

> 
>>
>> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
>> throughout and latency of PCIe traffic. With the support of PCIe PMU
>> we can enable the perf iostat mode.
>>
>> The HiSilicon PCIe PMU can support measuring the throughout of certain
>> TLP types and of certian root port. Totally 6 metrics are provided in
> 
> certain
> 

ok.

>> the unit of MB:
>>
>> - Inbound MWR: The memory write TLPs from the devices downstream the root port
>> - Inbound MRD: The memory read TLPs from the devices downstream the root port
>> - Inbound CPL: The completion TLPs from the devices downstream the root port
>> - Outbound MWR: The memory write TLPs from the CPU to the downstream devices
>> - Outbound MRD: The memory read TLPs from the CPU to the downstream devices
>> - Outbound CPL: The completions TLPs from the CPU to the downstream devices
>>
>> Since the PMU measures the throughout with unit of DWords. So we need to
> throughput in DWords
> 

ok.

>> calculate the throughout in MB like:
>>   Count * 4B / 1024 / 1024
>>
>> Some of the display of the `perf iostat` will be like:
>> [root at localhost tmp]# ./perf iostat list
>> hisi_pcie0_core2<0000:40:00.0>
>> hisi_pcie2_core2<0000:5f:00.0>
>> hisi_pcie0_core1<0000:16:00.0>
>> hisi_pcie0_core1<0000:16:04.0>
>> [root at localhost tmp]# ./perf iostat --timeout 10000
>>
>>  Performance counter stats for 'system wide':
>>
>>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
>> 0000:40:00.0                    0                    0                    0                    0                    0                    0
>> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
>> 0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
>> 0000:16:04.0                    0                    0                    0                    0                    0                    0
>>
>>       10.008227512 seconds time elapsed
>>
>> [root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
>> -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
>> -norandommap -group_reporting -runtime=10 -time_based -bs=64k
>>
>>  Performance counter stats for 'system wide':
>>
>>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
>> 0000:40:00.0                    0                    0                    0                    0                    0                    0
>> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
>> 0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
>> 0000:16:04.0                    0                    0                    0                    0                    0                    0
>>
>>       10.168561767 seconds time elapsed
>>
>>        0.465373000 seconds user
>>        1.952948000 seconds sys
>>
>> More information of the HiSilicon PCIe PMU can be found at
>> Documentation/admin-guide/perf/hisi-pcie-pmu.rst.
>>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> ---
>>  tools/perf/arch/arm64/util/Build         |   1 +
>>  tools/perf/arch/arm64/util/hisi-iostat.c | 433 +++++++++++++++++++++++
>>  2 files changed, 434 insertions(+)
>>  create mode 100644 tools/perf/arch/arm64/util/hisi-iostat.c
>>
>> diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
>> index 78ef7115be3d..4e8dabf98b29 100644
>> --- a/tools/perf/arch/arm64/util/Build
>> +++ b/tools/perf/arch/arm64/util/Build
>> @@ -3,6 +3,7 @@ perf-y += machine.o
>>  perf-y += perf_regs.o
>>  perf-y += tsc.o
>>  perf-y += pmu.o
>> +perf-y += hisi-iostat.o
>>  perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
>>  perf-$(CONFIG_DWARF)     += dwarf-regs.o
>>  perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
>> diff --git a/tools/perf/arch/arm64/util/hisi-iostat.c b/tools/perf/arch/arm64/util/hisi-iostat.c
>> new file mode 100644
>> index 000000000000..418eebece184
>> --- /dev/null
>> +++ b/tools/perf/arch/arm64/util/hisi-iostat.c
>> @@ -0,0 +1,433 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * perf iostat support for HiSilicon PCIe PMU.
>> + * Partly derived from tools/perf/arch/x86/util/iostat.c.
>> + *
>> + * Copyright (c) 2024 HiSilicon Technologies Co., Ltd.
>> + * Author: Yicong Yang <yangyicong at hisilicon.com>
>> + */
>> +
>> +#include <api/fs/fs.h>
>> +#include <linux/err.h>
>> +#include <linux/zalloc.h>
>> +#include <linux/limits.h>
>> +#include <dirent.h>
>> +#include <stdio.h>
>> +#include <errno.h>
>> +#include <stdlib.h>
>> +
>> +#include "util/counts.h"
>> +#include "util/cpumap.h"
>> +#include "util/debug.h"
>> +#include "util/iostat.h"
>> +#include "util/pmu.h"
>> +
>> +#define PCI_DEFAULT_DOMAIN		0
>> +#define PCI_DEVICE_NAME_PATTERN		"%04x:%02hhx:%02hhx.%hhu"
>> +#define PCI_ROOT_BUS_DEVICES_PATH	"bus/pci/devices"
>> +
>> +static const char * const hisi_iostat_metrics[] = {
>> +	"Inbound MWR(MB)",
>> +	"Inbound MRD(MB)",
>> +	"Inbound CPL(MB)",
>> +	"Outbound MWR(MB)",
>> +	"Outbound MRD(MB)",
>> +	"Outbound CPL(MB)",
>> +};
>> +
>> +static const char * const hisi_iostat_cmd_template[] = {
> 
> Given this array and the one above have to remain in same order, perhaps
> an enum?  Would also remove need to have the comments via
> [in_bound_wr] = "....
> etc
> 

sure. Will use an enum to define both the metric event string and here
for cmd template.

> 
>> +	/* Inbound Memory Write */
>> +	"hisi_pcie%hu_core%hu/event=0x0104,port=0x%hx/",
>> +	/* Inbound Memory Read */
>> +	"hisi_pcie%hu_core%hu/event=0x0804,port=0x%hx/",
>> +	/* Inbound Memory Completion */
>> +	"hisi_pcie%hu_core%hu/event=0x2004,port=0x%hx/",
>> +	/* Outbound Memory Write */
>> +	"hisi_pcie%hu_core%hu/event=0x0105,port=0x%hx/",
>> +	/* Outbound Memory Read */
>> +	"hisi_pcie%hu_core%hu/event=0x0405,port=0x%hx/",
>> +	/* Outbound Memory Completion */
>> +	"hisi_pcie%hu_core%hu/event=0x1005,port=0x%hx/",
>> +};
>>
> 
> ...
> 
> 
> 
> 
>> +
>> +void iostat_print_metric(struct perf_stat_config *config, struct evsel *evsel,
>> +			 struct perf_stat_output_ctx *out)
>> +{
>> +	struct perf_counts_values *count;
>> +	const char *iostat_metric;
>> +	double iostat_value;
>> +
>> +	iostat_metric = hisi_iostat_metrics[evsel->core.idx % ARRAY_SIZE(hisi_iostat_metrics)];
>> +
>> +	/* We're using AGGR_GLOBAL so there's only one aggr counts aggr[0]. */
>> +	count = &evsel->stats->aggr[0].counts;
>> +
>> +	/* The counts has been scaled, we can use it directly. */
>> +	iostat_value = (double)count->val;
>> +
>> +	/*
>> +	 * Display two digits after decimal point for better accuracy if the
>> +	 * value is non-zero.
>> +	 */
>> +	out->print_metric(config, out->ctx, NULL,
>> +			  iostat_value > 0 ? "%8.2f" : "%8.0f",
>> +			  iostat_metric, iostat_value / (256 * 1024));
> 
> I assume that 256 * 1024 is MiB/sizeof(dword)?  Perhaps express it as
> that to make the reasoning clearer?
> 
> 

Yes you're right. I mentioned it in the commit. Will add some comment it to
make it clearer here.

Thanks,
Yicong




From tudor.ambarus at linaro.org  Tue Feb  6 23:04:24 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed, 7 Feb 2024 07:04:24 +0000
Subject: [PATCH 3/4] spi: s3c64xx: add s3c64xx_iowrite{8,16}_32_rep
 accessors
In-Reply-To: <CAPLW+4k+FkuNwsyvWH54gcLz0YFmh8OmvOWt_LdQvELRXMvOTQ@mail.gmail.com>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
 <20240206085238.1208256-4-tudor.ambarus@linaro.org>
 <CAPLW+4k+FkuNwsyvWH54gcLz0YFmh8OmvOWt_LdQvELRXMvOTQ@mail.gmail.com>
Message-ID: <82358d4c-f100-472a-a4ed-88f28c460698@linaro.org>



On 2/6/24 18:44, Sam Protsenko wrote:
> On Tue, Feb 6, 2024 at 2:52?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>>
>> Allow SoCs that require 32 bits register accesses to write data in
>> chunks of 8 or 16 bits. One SoC that requires 32 bit register accesses
>> is the google gs101. The operation is rare, thus open code it in the
>> driver rather than making it generic (through asm-generic/io.h)
>>
>> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
>> ---
>>  drivers/spi/spi-s3c64xx.c | 70 +++++++++++++++++++++++++++++++--------
>>  1 file changed, 56 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
>> index c15ca6a910dc..cb45ad615f3d 100644
>> --- a/drivers/spi/spi-s3c64xx.c
>> +++ b/drivers/spi/spi-s3c64xx.c
>> @@ -142,6 +142,7 @@ struct s3c64xx_spi_dma_data {
>>   *     prescaler unit.
>>   * @clk_ioclk: True if clock is present on this device
>>   * @has_loopback: True if loopback mode can be supported
>> + * @use_32bit_io: True if the SoC allows just 32-bit register accesses.
> 
> A matter of taste, but: just -> only.

ok, will change if I send a new version.
> 
>>   *
>>   * The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
>>   * differ in some aspects such as the size of the fifo and spi bus clock
>> @@ -158,6 +159,7 @@ struct s3c64xx_spi_port_config {
>>         bool    clk_from_cmu;
>>         bool    clk_ioclk;
>>         bool    has_loopback;
>> +       bool    use_32bit_io;
>>  };
>>
>>  /**
>> @@ -412,6 +414,59 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
>>         return false;
>>  }
>>
>> +static void s3c64xx_iowrite8_32_rep(volatile void __iomem *addr,
>> +                                   const void *buffer, unsigned int count)
>> +{
>> +       if (count) {
>> +               const u8 *buf = buffer;
>> +
>> +               do {
>> +                       __raw_writel(*buf++, addr);
>> +               } while (--count);
>> +       }
> 
> How about:
> 
>     while (count--)
>         __raw_writel(*buf++, addr);
> 
> This way "if" condition is not needed. The same goes for the function below.

count will overflow, but shouldn't matter as it's not used afterwards.
But I would keep the style as it is, if you don't mind, it follows other
similar implementations from include/asm-generic/io.h. I'd like to be
consistent with the coding style of the generic implementations.

> 
>> +}
>> +
>> +static void s3c64xx_iowrite16_32_rep(volatile void __iomem *addr,
>> +                                    const void *buffer, unsigned int count)
>> +{
>> +       if (count) {
>> +               const u16 *buf = buffer;
>> +
>> +               do {
>> +                       __raw_writel(*buf++, addr);
>> +               } while (--count);
>> +       }
>> +}
>> +
>> +static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd,
>> +                               struct spi_transfer *xfer)
>> +{
>> +       void __iomem *regs = sdd->regs;
> 
> Suggest declaring aliases here, like this:
> 
>     void __iomem *addr = sdd->regs + S3C64XX_SPI_TX_DATA;
>     const void *buf = xfer->tx_buf;
>     unsigned int len = xfer->len;
> 
> Using those in the code below makes it more compact and easier to read.

Ok, will add the local variables if I send again. I hope you're fine
with adding the local variables when introducing the method.
> 
>> +
>> +       switch (sdd->cur_bpw) {
>> +       case 32:
>> +               iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
>> +                             xfer->tx_buf, xfer->len / 4);
>> +               break;
>> +       case 16:
>> +               if (sdd->port_conf->use_32bit_io)
>> +                       s3c64xx_iowrite16_32_rep(regs + S3C64XX_SPI_TX_DATA,
>> +                                                xfer->tx_buf, xfer->len / 2);
>> +               else
>> +                       iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
>> +                                     xfer->tx_buf, xfer->len / 2);
>> +               break;
>> +       default:
>> +               if (sdd->port_conf->use_32bit_io)
>> +                       s3c64xx_iowrite8_32_rep(regs + S3C64XX_SPI_TX_DATA,
>> +                                               xfer->tx_buf, xfer->len);
>> +               else
>> +                       iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
>> +                                    xfer->tx_buf, xfer->len);
>> +               break;
>> +       }
>> +}
>> +
>>  static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>>                                     struct spi_transfer *xfer, int dma_mode)
>>  {
>> @@ -445,20 +500,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>>                         modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
>>                         ret = s3c64xx_prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
>>                 } else {
>> -                       switch (sdd->cur_bpw) {
>> -                       case 32:
>> -                               iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
>> -                                       xfer->tx_buf, xfer->len / 4);
>> -                               break;
>> -                       case 16:
>> -                               iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
>> -                                       xfer->tx_buf, xfer->len / 2);
>> -                               break;
>> -                       default:
>> -                               iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
>> -                                       xfer->tx_buf, xfer->len);
>> -                               break;
>> -                       }
>> +                       s3c64xx_iowrite_rep(sdd, xfer);
> 
> This extraction (with no functional change yet) could've been a
> preceding separate patch, preparing things for this rework.
> 

I'm not a fan of having preparation patches for small changes like this,
it hides the scope. As the patch is now one can see that the logic
extends and would have made the indentation horrible if not introducing
a dedicated method. No preparation patch, please.


From bc-bocun.chen at mediatek.com  Tue Feb  6 23:14:51 2024
From: bc-bocun.chen at mediatek.com (=?utf-8?B?QmMtYm9jdW4gQ2hlbiAo6Zmz5p+P5p2RKQ==?=)
Date: Wed, 7 Feb 2024 07:14:51 +0000
Subject: [PATCH v2 1/2] dt-bindings: phy: mediatek,mt7988-xfi-tphy: add
 new bindings
In-Reply-To: <ZcJQyaTotW_bCWGU@makrotopia.org>
References: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>
	 <31d2c56a-5108-4265-a267-6733e1ba328e@linaro.org>
	 <ZcJQyaTotW_bCWGU@makrotopia.org>
Message-ID: <6058aea8a315201f686957e520f5784725b6b95e.camel@mediatek.com>

Hi Daniel,
Hi Krzysztof,

On Tue, 2024-02-06 at 15:31 +0000, Daniel Golle wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  Hi Krzysztof,
> 
> On Tue, Feb 06, 2024 at 11:53:55AM +0100, Krzysztof Kozlowski wrote:
> > On 05/02/2024 18:28, Daniel Golle wrote:
> > > Add bindings for the MediaTek XFI Ethernet SerDes T-PHY found in
> the
> > > MediaTek MT7988 SoC which can operate at various interfaces
> modes:
> > > 
> > > via USXGMII PCS:
> > >  * USXGMII
> > >  * 10GBase-R
> > >  * 5GBase-R
> > > 
> > > via LynxI SGMII PCS:
> > >  * 2500Base-X
> > >  * 1000Base-X
> > >  * Cisco SGMII (MAC side)
> > > 
> > > Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> > > ---
> > > v2: unify filename and compatible as requested
> > 
> > Several comments, from me and Rob, were ignored. Please respond to
> them.
> 
> I'm sorry if I have missed something. I just checked again on
> patchwork, just in case I would have missed an email reply to this or
> any of the preceding posts of this patch as part of the old series
> going to netdev.
> 
> Comments you have made which I have addressed:
>  - removed $nodename
>  - use compatible as filename
> 
> And the only thing I found that I didn't either fix or reply to is
> this:
> > Can you explain what is this issue and errata about (except
> performance)?
> 
> Not overwriting that (undocumented) value in that (undocumented)
> register results in 10GBase-R having performance issues according to
> a
> commit in MediaTek's SDK, see here:
> 
> 
https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/a500d94cd%5E%21/#F0
> 
> Maybe Bc or SkyLake of MediaTek (added to Cc) can explain this in
> more
> detail?

Our QA team has identified a potential performance issue when
connecting XFI Port0 with an SFP optical fiber, which may violate the
SFP specification.
Therefore, we have adjusted the PHYA setting for this port.

> 
> What I did miss was Rob's comment at the very bottom of this reply:
> > What is PEXTP?
> 
> I can again only answer by referencing to MediaTek's SDK sources:
> 
> 
https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c#96
> 
> Here this reset is called XFI_PEXTP0_GRST.
> 
> I personally find that name confusing (as this PHY has nothing to do
> with
> _P_ci _EX_press) and have tried to get rid of it where it isn't
> either part
> of official documentation or already merged drivers (like Sam's clock
> driver).
> 
> If there have been any other issues with this patch which I'm not
> aware
> of, please point them out to me.
> 
> 
> Thank you
> 
> 
> Best regards
> 
> 
> Daniel

Thanks
BC

From abel.vesa at linaro.org  Tue Feb  6 23:19:50 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 7 Feb 2024 09:19:50 +0200
Subject: [PATCH RFC 1/2] spmi: Add support for multi-master
In-Reply-To: <CAA8EJpqsJmv36=o1aTjVH6eMHXMg8BHNpiDvs+Q8YB23ezVGtQ@mail.gmail.com>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
 <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>
 <CAA8EJpqsJmv36=o1aTjVH6eMHXMg8BHNpiDvs+Q8YB23ezVGtQ@mail.gmail.com>
Message-ID: <ZcMvFtAwQQjAZhk6@linaro.org>

On 24-02-07 01:55:39, Dmitry Baryshkov wrote:
> On Wed, 7 Feb 2024 at 01:34, Abel Vesa <abel.vesa at linaro.org> wrote:
> >
> > Some newer SPMI controllers support multiple bus masters.
> > Such a master can control multiple slave devices. The generic
> > framework needs to be able to pass on the master id to the
> > controller-specific driver. So do that. The framework will
> > check if the devicetree child nodes are actually bus masters
> > and will register the devices for each master. The legacy
> > approach will still be supported for backwards compatibility.
> 
> Please remind me, are those two actual bus musters driving a single
> bus in parallel or two SPMI buses being handled by a single device? In
> the latter case this implementation is incorrect. There should be
> multiple spmi_controller instances, one for each bus. Allocate them in
> a loop and set ctrl->dev.of_node after allocating.

It's two SPMI buses (two sets of wires) handled by the same controller,
HW-wise.

If we register two spmi controllers with the kernel framework, it will
be HW inaccurate, because there is just one controller which has
multiple masters.

I'm not saying it might not work. But, to me, it looks more like a hack.

Basically, we would be mapping HW bus masters to kernel controllers.

> 
> >
> > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > ---
> >  drivers/spmi/spmi-mtk-pmif.c |  6 ++--
> >  drivers/spmi/spmi-pmic-arb.c | 10 +++---
> >  drivers/spmi/spmi.c          | 76 ++++++++++++++++++++++++++++++--------------
> >  include/linux/spmi.h         | 10 +++---
> >  4 files changed, 67 insertions(+), 35 deletions(-)
> 
> -- 
> With best wishes
> Dmitry


From dmitry.baryshkov at linaro.org  Tue Feb  6 23:23:09 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 7 Feb 2024 09:23:09 +0200
Subject: [PATCH RFC 1/2] spmi: Add support for multi-master
In-Reply-To: <ZcMvFtAwQQjAZhk6@linaro.org>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
 <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>
 <CAA8EJpqsJmv36=o1aTjVH6eMHXMg8BHNpiDvs+Q8YB23ezVGtQ@mail.gmail.com> <ZcMvFtAwQQjAZhk6@linaro.org>
Message-ID: <CAA8EJprqWLX7_yWZzKp3FAKFGkSkk041f9hj1uXuRBrbH5APyQ@mail.gmail.com>

On Wed, 7 Feb 2024 at 09:19, Abel Vesa <abel.vesa at linaro.org> wrote:
>
> On 24-02-07 01:55:39, Dmitry Baryshkov wrote:
> > On Wed, 7 Feb 2024 at 01:34, Abel Vesa <abel.vesa at linaro.org> wrote:
> > >
> > > Some newer SPMI controllers support multiple bus masters.
> > > Such a master can control multiple slave devices. The generic
> > > framework needs to be able to pass on the master id to the
> > > controller-specific driver. So do that. The framework will
> > > check if the devicetree child nodes are actually bus masters
> > > and will register the devices for each master. The legacy
> > > approach will still be supported for backwards compatibility.
> >
> > Please remind me, are those two actual bus musters driving a single
> > bus in parallel or two SPMI buses being handled by a single device? In
> > the latter case this implementation is incorrect. There should be
> > multiple spmi_controller instances, one for each bus. Allocate them in
> > a loop and set ctrl->dev.of_node after allocating.
>
> It's two SPMI buses (two sets of wires) handled by the same controller,
> HW-wise.
>
> If we register two spmi controllers with the kernel framework, it will
> be HW inaccurate, because there is just one controller which has
> multiple masters.

struct spmi_controller is a controller for a single bus. Inside your
device you have two SPMI buses, each can be controlled by its own
struct spmi_controller. Just like devices that control multiple I2C,
SPI or USB busses register a separate instance of the bus controller.

>
> I'm not saying it might not work. But, to me, it looks more like a hack.
>
> Basically, we would be mapping HW bus masters to kernel controllers.

Buses, not just masters.

>
> >
> > >
> > > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > > ---
> > >  drivers/spmi/spmi-mtk-pmif.c |  6 ++--
> > >  drivers/spmi/spmi-pmic-arb.c | 10 +++---
> > >  drivers/spmi/spmi.c          | 76 ++++++++++++++++++++++++++++++--------------
> > >  include/linux/spmi.h         | 10 +++---
> > >  4 files changed, 67 insertions(+), 35 deletions(-)
> >
> > --
> > With best wishes
> > Dmitry



-- 
With best wishes
Dmitry


From chandru at ti.com  Tue Feb  6 23:23:47 2024
From: chandru at ti.com (CHANDRU DHAVAMANI)
Date: Wed, 7 Feb 2024 12:53:47 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <e2ea03ce-0367-413b-aca9-7c1fabda173a@ti.com>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
 <20240206131420.wtitflgav23jto2q@verbally>
 <871q9pzoiq.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <c5b6bd1d-dbb4-4bfb-8b3e-9b0733e2ba5d@ti.com>
 <c2b7f22d-f07d-4cac-8a01-af7b014e7ff4@ti.com>
 <a4fdbcfe-e0e0-4280-8638-e39b6b46778e@ti.com>
 <87ttmly4fa.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <e2ea03ce-0367-413b-aca9-7c1fabda173a@ti.com>
Message-ID: <4398af20-3396-4a5c-8fcb-a7b3d0d6f15b@ti.com>


On 07/02/24 11:03, Kumar, Udit wrote:
>
> On 2/6/2024 9:24 PM, Kamlesh Gurudasani wrote:
>> "Kumar, Udit" <u-kumar1 at ti.com> writes:
>>
>>>>>>> get_freq is a bit expensive as it has to walk the clock tree to 
>>>>>>> find
>>>>>>> the clock frequency (at least the first time?). just wondering if
>>>>>>> there is lighter alternative here?
>>>>>>>
>>>>>> How about get_clock? Doesn't read the registers at least.
>>>>> Said API needs, some flags to be passed,
>>>>>
>>>>> Can those flag be set to zero, Chandru ?
>>>>
>>>> get_clock doesn't require any flags to be passed.
>>>
>>> May be firmware does not need it but? I was referring to
>>>
>>> https://elixir.bootlin.com/linux/latest/source/drivers/clk/keystone/sci-clk.c#L78 
>>>
>> Just took a look,
>>
>> I now understand the reason for confusion,
>>
>> #define TI_SCI_MSG_SET_CLOCK_STATE??? 0x0100
>> #define TI_SCI_MSG_GET_CLOCK_STATE??? 0x0101
>>
>> cops->get_clock = ti_sci_cmd_get_clock;? --> refers to
>> TI_SCI_MSG_SET_CLOCK_STATE
>> That's why we are passing the flag from linux for get_clock
>>
>> Linux is using terminology of get/put.
>>
>> As Chandru pointed, we don't have to pass flags, cause he is refering
>> to TI_SCI_MSG_GET_CLOCK_STATE
>>
>> Below functions passes TI_SCI_MSG_GET_CLOCK_STATE to DM, which is what
>> we actually want.
>> cops->is_auto = ti_sci_cmd_clk_is_auto;
>> cops->is_on = ti_sci_cmd_clk_is_on;
>> cops->is_off = ti_sci_cmd_clk_is_off;
>
>
> I think calling ti_sci_cmd_clk_is_auto should be good . other 
> functions needs current state and requested state.
>
> Chandru ?
>

ti_sci_cmd_clk_is_auto is internal function to linux.
For TI_SCI_MSG_GET_CLOCK_STATE, linux only needs to pass pointers to the 
variables where result will be stored.


>>
>> Which should be safe to call, Chandru can confirm.
>>
>> Regards,
>> Kamlesh
>>>
>>>
>>>>
>>>>>
>>>>>> Regards,
>>>>>> Kamlesh


From yangyicong at huawei.com  Tue Feb  6 23:25:44 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Wed, 7 Feb 2024 15:25:44 +0800
Subject: [RESEND v4] perf stat: Support per-cluster aggregation
In-Reply-To: <CAP-5=fUaJSF1R_yDTeNwiNbm0isGTEpZSbp2m0q7BJox+TdRwg@mail.gmail.com>
References: <20240206082016.22292-1-yangyicong@huawei.com>
 <CAP-5=fUaJSF1R_yDTeNwiNbm0isGTEpZSbp2m0q7BJox+TdRwg@mail.gmail.com>
Message-ID: <d8382fd2-1c0c-5041-3c0e-cd15244ef9f6@huawei.com>

On 2024/2/7 1:49, Ian Rogers wrote:
> On Tue, Feb 6, 2024 at 12:24?AM Yicong Yang <yangyicong at huawei.com> wrote:
>>
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> Some platforms have 'cluster' topology and CPUs in the cluster will
>> share resources like L3 Cache Tag (for HiSilicon Kunpeng SoC) or L2
>> cache (for Intel Jacobsville). Currently parsing and building cluster
>> topology have been supported since [1].
>>
>> perf stat has already supported aggregation for other topologies like
>> die or socket, etc. It'll be useful to aggregate per-cluster to find
>> problems like L3T bandwidth contention.
>>
>> This patch add support for "--per-cluster" option for per-cluster
>> aggregation. Also update the docs and related test. The output will
>> be like:
>>
>> [root at localhost tmp]# perf stat -a -e LLC-load --per-cluster -- sleep 5
>>
>>  Performance counter stats for 'system wide':
>>
>> S56-D0-CLS158    4      1,321,521,570      LLC-load
>> S56-D0-CLS594    4        794,211,453      LLC-load
>> S56-D0-CLS1030    4             41,623      LLC-load
>> S56-D0-CLS1466    4             41,646      LLC-load
>> S56-D0-CLS1902    4             16,863      LLC-load
>> S56-D0-CLS2338    4             15,721      LLC-load
>> S56-D0-CLS2774    4             22,671      LLC-load
>> [...]
>>
>> On a legacy system without cluster or cluster support, the output will
>> be look like:
>> [root at localhost perf]# perf stat -a -e cycles --per-cluster -- sleep 1
>>
>>  Performance counter stats for 'system wide':
>>
>> S56-D0-CLS0   64         18,011,485      cycles
>> S7182-D0-CLS0   64         16,548,835      cycles
>>
>> Note that this patch doesn't mix the cluster information in the outputs
>> of --per-core to avoid breaking any tools/scripts using it.
>>
>> Note that perf recently supports "--per-cache" aggregation, but it's not
>> the same with the cluster although cluster CPUs may share some cache
>> resources. For example on my machine all clusters within a die share the
>> same L3 cache:
>> $ cat /sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list
>> 0-31
>> $ cat /sys/devices/system/cpu/cpu0/topology/cluster_cpus_list
>> 0-3
>>
>> [1] commit c5e22feffdd7 ("topology: Represent clusters of CPUs within a die")
>> Tested-by: Jie Zhan <zhanjie9 at hisilicon.com>
>> Reviewed-by: Tim Chen <tim.c.chen at linux.intel.com>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> 
> Reviewed-by: Ian Rogers <irogers at google.com>
> 

Thanks!

>> ---
>> Change since v3:
>> - Rebase on v6.7-rc4 and resolve the conflicts
>> Link: https://lore.kernel.org/all/20230404104951.27537-1-yangyicong at huawei.com/
>>
>> Change since v2:
>> - Use 0 as cluster ID on legacy system without cluster support, keep consistenct
>>   with what --per-die does.
>> Link: https://lore.kernel.org/all/20230328112717.19573-1-yangyicong at huawei.com/
>>
>> Change since v1:
>> - Provides the information about how to map the cluster to the CPUs in the manual
>> - Thanks the review from Tim and test from Jie.
>> Link: https://lore.kernel.org/all/20230313085911.61359-1-yangyicong at huawei.com/
>>
>>  tools/perf/Documentation/perf-stat.txt        | 11 ++++
>>  tools/perf/builtin-stat.c                     | 52 +++++++++++++++++--
>>  .../tests/shell/lib/perf_json_output_lint.py  |  4 +-
>>  tools/perf/tests/shell/lib/stat_output.sh     | 12 +++++
>>  tools/perf/tests/shell/stat+csv_output.sh     |  2 +
>>  tools/perf/tests/shell/stat+json_output.sh    | 13 +++++
>>  tools/perf/tests/shell/stat+std_output.sh     |  2 +
>>  tools/perf/util/cpumap.c                      | 32 +++++++++++-
>>  tools/perf/util/cpumap.h                      | 19 +++++--
>>  tools/perf/util/env.h                         |  1 +
>>  tools/perf/util/stat-display.c                | 13 +++++
>>  tools/perf/util/stat.h                        |  1 +
>>  12 files changed, 153 insertions(+), 9 deletions(-)
>>
[...]
>> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
>> index 0581ee0fa5f2..5907456d42a2 100644
>> --- a/tools/perf/util/cpumap.c
>> +++ b/tools/perf/util/cpumap.c
>> @@ -222,6 +222,8 @@ static int aggr_cpu_id__cmp(const void *a_pointer, const void *b_pointer)
>>                 return a->socket - b->socket;
>>         else if (a->die != b->die)
>>                 return a->die - b->die;
>> +       else if (a->cluster != b->cluster)
>> +               return a->cluster - b->cluster;
>>         else if (a->cache_lvl != b->cache_lvl)
>>                 return a->cache_lvl - b->cache_lvl;
>>         else if (a->cache != b->cache)
>> @@ -309,6 +311,29 @@ struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data)
>>         return id;
>>  }
>>
>> +int cpu__get_cluster_id(struct perf_cpu cpu)
>> +{
>> +       int value, ret = cpu__get_topology_int(cpu.cpu, "cluster_id", &value);
> 
> nit: normal coding style is for a whitespace newline here.
> 

Will fix. I may referred to cpu__get_core_id() below which is an exception.

Thanks,
Yicong


From bjorn at kernel.org  Tue Feb  6 23:27:47 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Wed, 07 Feb 2024 08:27:47 +0100
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <CAAhSdy2PPjS6++Edh8NkgiBmcovTUjS5oXE2eR5ZwPfAfVA0ng@mail.gmail.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <87h6ily53k.fsf@all.your.base.are.belong.to.us>
 <CAAhSdy2PPjS6++Edh8NkgiBmcovTUjS5oXE2eR5ZwPfAfVA0ng@mail.gmail.com>
Message-ID: <874jekag3w.fsf@all.your.base.are.belong.to.us>

Hi!

Anup Patel <anup at brainfault.org> writes:

> On Tue, Feb 6, 2024 at 9:09?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>>
>> Hi Anup,
>>
>> Anup Patel <apatel at ventanamicro.com> writes:
>>
>> > The RISC-V AIA specification is ratified as-per the RISC-V international
>> > process. The latest ratified AIA specifcation can be found at:
>> > https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf
>> >
>> > At a high-level, the AIA specification adds three things:
>> > 1) AIA CSRs
>> >    - Improved local interrupt support
>> > 2) Incoming Message Signaled Interrupt Controller (IMSIC)
>> >    - Per-HART MSI controller
>> >    - Support MSI virtualization
>> >    - Support IPI along with virtualization
>> > 3) Advanced Platform-Level Interrupt Controller (APLIC)
>> >    - Wired interrupt controller
>> >    - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
>> >    - In Direct-mode, injects external interrupts directly into HARTs
>> >
>> > For an overview of the AIA specification, refer the AIA virtualization
>> > talk at KVM Forum 2022:
>> > https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
>> > https://www.youtube.com/watch?v=r071dL8Z0yo
>>
>> Thank you for continuing to work on this series! I like this
>> direction of the series!
>>
>> TL;DR: I think we can get rid of most of the id/householding data
>> structures, except for the irq matrix.
>>
>> Most of my comments are more of a design/overview nature, so I'll
>> comment here in the cover letter.
>>
>> I took the series for a spin with and it with Alex' ftrace fix it,
>> passes all my tests nicely!
>>
>> Now some thoughts/comments (I'm coming from the x86 side of things!):
>>
>> id/enable-tracking: There are a lot of different id/enabled tracking
>> with corresponding locks, where there's IMO overlap with what the
>> matrix provides.
>
> The matrix allocator does not track the enabled/disabled state of
> the per-CPU IDs. This is why we have a separate per-CPU
> ids_enabled_bitmap which is also used for remote synchronization
> across CPUs.

Exactly, but what I'm asking is if that structure is really needed. More
below.

>> Let's start with struct imsic_priv:
>>
>>    | /* Dummy HW interrupt numbers */
>>    | unsigned int nr_hwirqs;
>>    | raw_spinlock_t hwirqs_lock;
>>    | unsigned long *hwirqs_used_bitmap;
>
> The matrix allocator manages actual IDs for each CPU whereas
> the Linux irq_data expects a fixed hwirq which does not change.
>
> Due to this, we have a dummy hwirq space which is always
> fixed. The only thing that is changed under-the-hood by the
> IMSIC driver is the dummy hwirq to actual HW vector (cpu, id)
> mapping.

Read below. I'm not talking about local_id from the irq_matrix, I'm
saying use virq, which has the properties you're asking for, and doesn't
require an additional structure. When an irq/desc is allocated, you have
a nice unique number with the virq for the lifetime of the interrupt.

>> These are used to for the domain routing (hwirq -> desc/virq), and not
>> needed. Just use the same id as virq (at allocation time), and get rid
>> of these data structures/corresponding functions. The lookup in the
>> interrupt handler via imsic_local_priv.vectors doesn't care about
>> hwirq. This is what x86 does... The imsic_vector roughly corresponds
>> to apic_chip_data (nit: imsic_vector could have the chip_data suffix
>> as well, at least it would have helped me!)
>
> Yes, imsic_vector corresponds to apic_chip_data in the x86 world.

...and I'm trying to ask the following; Given the IMSIC is pretty much
x86 vector (arch/x86/kernel/apic/vector.c), I'm trying to figure out the
rational why IMSIC has all the extra householding data, not needed by
x86. The x86 has been battle proven, and having to deal with all kind of
quirks (e.g. lost interrupts on affinity changes).

>> Moving/affinity changes. The moving of a vector to another CPU
>> currently involves:
>>
>> 1. Allocate a new vector from the matrix
>> 2. Disable/enable the corresponding per-cpu ids_enabled_bitmap (nested
>>    spinlocks)
>> 3. Trigger two IPIs to apply the bitmap
>> 4. On each CPU target (imsic_local_sync()) loop the bitmap and flip
>>    all bits, and potentially rearm
>>
>> This seems a bit heavy-weight: Why are you explicitly setting/clearing
>> all the bits in a loop at the local sync?
>
> This can be certainly optimized by introducing another
> ids_dirty_bitmap. I will add this in the next revision.

I rather have fewer maps, and less locks! ;-)

>> x86 does it a bit differently (more lazily): The chip_data has
>> prev_{cpu,vector}/move_in_progress fields, and keep both vectors
>> enabled until there's an interrupt on the new vector, and then the old
>> one is cleaned (irq_complete_move()).
>>
>> Further; When it's time to remove the old vector, x86 doesn't trigger
>> an IPI on the disabling side, but queues a cleanup job on a per-cpu
>> list and triggers a timeout. So, the per-cpu chip_data (per-cpu
>> "vectors" in your series) can reside in two places during the transit.
>
> We can't avoid IPIs when moving vectors from one CPU to another
> CPU because IMSIC id enable/disable is only possible through
> CSRs. Also, keep in-mind that irq affinity change might be initiated
> on CPU X for some interrupt targeting CPU Y which is then changed
> to target CPU Z.
>
> In the case of x86, they have memory mapped registers which
> allows one CPU to enable/disable the ID of another CPU.

Nope. Same mechanics on x86 -- the cleanup has to be done one the
originating core. What I asked was "what about using a timer instead of
an IPI". I think this was up in the last rev as well?

Check out commit bdc1dad299bb ("x86/vector: Replace
IRQ_MOVE_CLEANUP_VECTOR with a timer callback") Specifically, the
comment about lost interrupts, and the rational for keeping the original
target active until there's a new interrupt on the new cpu.

>> I wonder if this clean up is less intrusive, and you just need to
>> perform what's in the per-list instead of dealing with the
>> ids_enabled_bitmap? Maybe we can even remove that bitmap as well. The
>> chip_data/desc has that information. This would mean that
>> imsic_local_priv() would only have the local vectors (chip_data), and
>> a cleanup list/timer.
>>
>> My general comment is that instead of having these global id-tracking
>> structures, use the matrix together with some desc/chip_data local
>> data, which should be sufficient.
>
> The "ids_enabled_bitmap", "dummy hwirqs" and private imsic_vectors
> are required since the matrix allocator only manages allocation of
> per-CPU IDs.

The information in ids_enabled_bitmap is/could be inherent in
imsic_local_priv.vectors (guess what x86 does... ;-)).

Dummy hwirqs could be replaced with the virq.

Hmm, seems like we're talking past each other, or at least I get the
feeling I can't get my opinions out right. I'll try to do a quick PoC,
to show you what I mean. That's probably easier than just talking about
it. ...and maybe I'll come realizing I'm all wrong!

My reaction is -- you're doing a lot of householding with a lot of
locks, and my worry is that we'll just end up with same issues/bloat
that x86 once had (has? ;-)).

>> Random thought: Do we need to explicitly disable (csr) the vector,
>> when we're changing the affinity? What if we just leave it enabled,
>> and only when mask/unmask is performed it's actually explicitly masked
>> (writes to the csr)?
>
> We should not leave it enabled because some rough/buggy device
> can inject spurious interrupts using MSI writes to unused enabled
> interrupts.

OK!

>>
>> Missing features (which can be added later):
>> * Reservation mode/activate support (allocate many MSI, but only
>>   request/activate a subset)
>
> I did not see any PCIe or platform device requiring this kind of
> reservation. Any examples ?

It's not a requirement. Some devices allocate a gazillion interrupts
(NICs with many QoS queues, e.g.), but only activate a subset (via
request_irq()). A system using these kind of devices might run out of
interrupts.

Problems you run into once you leave the embedded world, pretty much.

>> * Handle managed interrupts
>
> Any examples of managed interrupts in the RISC-V world ?

E.g. all nvme drives: nvme_setup_irqs(), and I'd assume contemporary
netdev drivers would use it. Typically devices with per-cpu queues.

>> * There might be some irqd flags are missing, which mostly cpuhp care
>>   about (e.g. irqd_*_single_target())...
>
> Okay, let me check and update.

I haven't dug much into cpuhp, so I'm out on a limb here...

>> Finally; Given that the APLIC requires a lot more patches, depending
>> on how the review process moves on -- maybe the IMSIC side could go as
>> a separate series?
>>
>
> The most popular implementation choice across RISC-V platforms
> will be IMSIC + APLIC so both drivers should go together. In fact,
> we need both drivers for the QEMU virt machine as well because
> UART interrupt (and other wired interrupts) on the QEMU virt
> machine goes through APLIC.

Thanks for clearing that out! Hmm, an IMSIC only QEMU would be awesome.


Cheers,
Bj?rn


From u-kumar1 at ti.com  Tue Feb  6 23:33:37 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Wed, 7 Feb 2024 13:03:37 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <4398af20-3396-4a5c-8fcb-a7b3d0d6f15b@ti.com>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
 <20240206131420.wtitflgav23jto2q@verbally>
 <871q9pzoiq.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <c5b6bd1d-dbb4-4bfb-8b3e-9b0733e2ba5d@ti.com>
 <c2b7f22d-f07d-4cac-8a01-af7b014e7ff4@ti.com>
 <a4fdbcfe-e0e0-4280-8638-e39b6b46778e@ti.com>
 <87ttmly4fa.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <e2ea03ce-0367-413b-aca9-7c1fabda173a@ti.com>
 <4398af20-3396-4a5c-8fcb-a7b3d0d6f15b@ti.com>
Message-ID: <978c8110-3083-4fc2-a348-d7f97fd7839c@ti.com>


On 2/7/2024 12:53 PM, CHANDRU DHAVAMANI wrote:
>
> On 07/02/24 11:03, Kumar, Udit wrote:
>>
>> On 2/6/2024 9:24 PM, Kamlesh Gurudasani wrote:
>>> "Kumar, Udit" <u-kumar1 at ti.com> writes:
>>>
>>>>>>>> get_freq is a bit expensive as it has to walk the clock tree to 
>>>>>>>> find
>>>>>>>> the clock frequency (at least the first time?). just wondering if
>>>>>>>> there is lighter alternative here?
>>>>>>>>
>>>>>>> How about get_clock? Doesn't read the registers at least.
>>>>>> Said API needs, some flags to be passed,
>>>>>>
>>>>>> Can those flag be set to zero, Chandru ?
>>>>>
>>>>> get_clock doesn't require any flags to be passed.
>>>>
>>>> May be firmware does not need it but? I was referring to
>>>>
>>>> https://elixir.bootlin.com/linux/latest/source/drivers/clk/keystone/sci-clk.c#L78 
>>>>
>>> Just took a look,
>>>
>>> I now understand the reason for confusion,
>>>
>>> #define TI_SCI_MSG_SET_CLOCK_STATE??? 0x0100
>>> #define TI_SCI_MSG_GET_CLOCK_STATE??? 0x0101
>>>
>>> cops->get_clock = ti_sci_cmd_get_clock;? --> refers to
>>> TI_SCI_MSG_SET_CLOCK_STATE
>>> That's why we are passing the flag from linux for get_clock
>>>
>>> Linux is using terminology of get/put.
>>>
>>> As Chandru pointed, we don't have to pass flags, cause he is refering
>>> to TI_SCI_MSG_GET_CLOCK_STATE
>>>
>>> Below functions passes TI_SCI_MSG_GET_CLOCK_STATE to DM, which is what
>>> we actually want.
>>> cops->is_auto = ti_sci_cmd_clk_is_auto;
>>> cops->is_on = ti_sci_cmd_clk_is_on;
>>> cops->is_off = ti_sci_cmd_clk_is_off;
>>
>>
>> I think calling ti_sci_cmd_clk_is_auto should be good . other 
>> functions needs current state and requested state.
>>
>> Chandru ?
>>
>
> ti_sci_cmd_clk_is_auto is internal function to linux.
> For TI_SCI_MSG_GET_CLOCK_STATE, linux only needs to pass pointers to 
> the variables where result will be stored.


Yes this internal function calls TI_SCI_MSG_GET_CLOCK_STATE


>
>
>>>
>>> Which should be safe to call, Chandru can confirm.
>>>
>>> Regards,
>>> Kamlesh
>>>>
>>>>
>>>>>
>>>>>>
>>>>>>> Regards,
>>>>>>> Kamlesh


From tudor.ambarus at linaro.org  Tue Feb  6 23:50:43 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed, 7 Feb 2024 07:50:43 +0000
Subject: [PATCH 0/4] spi: s3c64xx: add support for google,gs101-spi
In-Reply-To: <CAPLW+4kPib_3MJeGL3bHT__rLoJOS=GS+gNZUbZ0dpyey9E-Hg@mail.gmail.com>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
 <CAPLW+4kPib_3MJeGL3bHT__rLoJOS=GS+gNZUbZ0dpyey9E-Hg@mail.gmail.com>
Message-ID: <1249bfa8-2a40-449a-897c-a862d3a8e65a@linaro.org>



On 2/6/24 18:59, Sam Protsenko wrote:
> On Tue, Feb 6, 2024 at 2:52?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>>
>> Depends on the simple cleanup patches from:
>> https://lore.kernel.org/linux-spi/20240205124513.447875-1-tudor.ambarus at linaro.org/
>>
>> A slightly different version of the google,gs101-spi support was sent at:
>> https://lore.kernel.org/linux-spi/20240125145007.748295-1-tudor.ambarus at linaro.org/
>>
>> Let's add support for gs101-spi so that I have a testing base for the
>> driver rework patches that will follow.
>>
>> Tudor Ambarus (4):
>>   spi: s3c64xx: explicitly include <linux/types.h>
>>   spi: dt-bindings: samsung: add google,gs101-spi compatible
>>   spi: s3c64xx: add s3c64xx_iowrite{8,16}_32_rep accessors
>>   spi: s3c64xx: add support for google,gs101-spi
>>
> 
> Just a grumpy note: I wish this series (except for the [PATCH 1/4],
> which I'd argue doesn't belong here) was submitted before the rest of
> SPI cleanups and reworkings. Would've made reviewing much easier,
> because this series doesn't apply without SPI cleanup series that has
> to be applied prior to that. There are other benefits to that approach
> too, as was discussed earlier.
> 

I feel we're bike-shedding, it drains my energy. Your reasons were:
1/ easier review
2/ easier backporting of gs101 if that's ever wanted
3/ driver rework takes more review time and I risk not having gs101
integrated for next release

2/ is not true right now, I could cherry-pick the iowrite and gs101
patches on top of v6.7. With 1/ I don't agree as the gs101 patches are
the same with or without the simple cleanup.
3/ is my responsibility and I'm ok with it, I feel there's enough time
for all

What matters, as I specified in the cover letter, is to have the gs101
patches before the functional driver rework which will follow, so that I
can test each functional patch with gs101.

I give up however, I'll do as you want. Will respin all.


From tudor.ambarus at linaro.org  Tue Feb  6 23:52:45 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed, 7 Feb 2024 07:52:45 +0000
Subject: [PATCH v4 00/16] spi: s3c64xx: straightforward cleanup
In-Reply-To: <20240205124513.447875-1-tudor.ambarus@linaro.org>
References: <20240205124513.447875-1-tudor.ambarus@linaro.org>
Message-ID: <555a3600-8669-4733-b89c-ec0b5c6a2c6e@linaro.org>

Hi, Mark,

Please don't queue this yet, I'll come up with the gs101 patches first,
as Sam suggests. I'll then add this patch set on top of gs101.

ta


From anshuman.khandual at arm.com  Tue Feb  6 23:54:48 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 7 Feb 2024 13:24:48 +0530
Subject: [RFC PATCH] KVM: arm64: Override Microsoft Azure Cobalt 100 MIDR
 value with ARM Neoverse N2
In-Reply-To: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
References: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
Message-ID: <df731836-04ab-41b9-b317-434a1060ad61@arm.com>


On 2/7/24 01:28, Easwar Hariharan wrote:
> Several workload optimizations and errata depend on validating that the
> optimization or errata are applicable to the particular CPU by checking
> the MIDR_EL1 system register value. With the Microsoft implementer ID

Which is how it should be done.

> for Azure Cobalt 100, the value doesn't match and ~20-25% performance
> regression is seen in these workloads. Override the Azure Cobalt 100
> value and replace it with the default ARM Neoverse N2 value that Azure
> Cobalt 100 is based on.

Why cannot these MIDR values be classified as required and subscribed to
the existing erratas that is affecting such implementations. Hence these
work arounds will be triggered as and when applicable. Why then override
MIDR value instead ?

> 
> Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>
> ---
>  arch/arm64/include/asm/cputype.h   | 3 ++-
>  arch/arm64/include/asm/el2_setup.h | 5 +++++
>  arch/arm64/kvm/sys_regs.c          | 9 ++++++++-
>  3 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 7c7493cb571f..0450c6c32377 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -262,7 +262,8 @@ is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
>   */
>  static inline u32 __attribute_const__ read_cpuid_id(void)
>  {
> -	return read_cpuid(MIDR_EL1);
> +	return (read_cpuid(MIDR_EL1) == 0x6D0FD490 ? 0x410FD490 :
> +			read_cpuid(MIDR_EL1));
>  }
>  
>  static inline u64 __attribute_const__ read_cpuid_mpidr(void)
> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> index b7afaa026842..502a14e54a31 100644
> --- a/arch/arm64/include/asm/el2_setup.h
> +++ b/arch/arm64/include/asm/el2_setup.h
> @@ -138,6 +138,11 @@
>  .macro __init_el2_nvhe_idregs
>  	mrs	x0, midr_el1
>  	mrs	x1, mpidr_el1
> +	ldr	x2, =0x6D0FD490
> +	cmp	x0, x2
> +	bne	.Loverride_cobalt100_\@
> +	ldr	x0, =0x410FD490
> +.Loverride_cobalt100_\@:
>  	msr	vpidr_el2, x0
>  	msr	vmpidr_el2, x1
>  .endm
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 30253bd19917..8ea9c7fdabdb 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -3574,7 +3574,14 @@ id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id,
>  		return ((struct sys_reg_desc *)r)->val;			\
>  	}
>  
> -FUNCTION_INVARIANT(midr_el1)
> +static u64 get_midr_el1(struct kvm_vcpu *v, const struct sys_reg_desc *r)
> +{
> +	((struct sys_reg_desc *)r)->val = read_sysreg(midr_el1);
> +	if (((struct sys_reg_desc *)r)->val == 0x6D0FD490)
> +		((struct sys_reg_desc *)r)->val == 0x410FD490;
> +	return ((struct sys_reg_desc *)r)->val;
> +}
> +
>  FUNCTION_INVARIANT(revidr_el1)
>  FUNCTION_INVARIANT(aidr_el1)
>  


From mazziesaccount at gmail.com  Tue Feb  6 23:57:54 2024
From: mazziesaccount at gmail.com (Matti Vaittinen)
Date: Wed, 7 Feb 2024 09:57:54 +0200
Subject: [PATCH 11/18] mfd: rohm: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-12-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
 <20240206071314.8721-12-liubo03@inspur.com>
Message-ID: <ab8d9d0a-aad4-42b7-9e24-9ae6acf7c939@gmail.com>

On 2/6/24 09:13, Bo Liu wrote:
> The maple tree register cache is based on a much more modern data structure
> than the rbtree cache and makes optimisation choices which are probably
> more appropriate for modern systems than those made by the rbtree cache.
> 
> Signed-off-by: Bo Liu <liubo03 at inspur.com>

Acked-by: Matti Vaittinen <mazziesaccount at gmail.com>

> ---
>   drivers/mfd/rohm-bd71828.c | 4 ++--
>   drivers/mfd/rohm-bd718x7.c | 2 +-
>   drivers/mfd/rohm-bd9576.c  | 2 +-
>   3 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
> index 594718f7e8e1..2f3826c7eef4 100644
> --- a/drivers/mfd/rohm-bd71828.c
> +++ b/drivers/mfd/rohm-bd71828.c
> @@ -197,7 +197,7 @@ static const struct regmap_config bd71815_regmap = {
>   	.val_bits = 8,
>   	.volatile_table = &bd71815_volatile_regs,
>   	.max_register = BD71815_MAX_REGISTER - 1,
> -	.cache_type = REGCACHE_RBTREE,
> +	.cache_type = REGCACHE_MAPLE,
>   };
>   
>   static const struct regmap_config bd71828_regmap = {
> @@ -205,7 +205,7 @@ static const struct regmap_config bd71828_regmap = {
>   	.val_bits = 8,
>   	.volatile_table = &bd71828_volatile_regs,
>   	.max_register = BD71828_MAX_REGISTER,
> -	.cache_type = REGCACHE_RBTREE,
> +	.cache_type = REGCACHE_MAPLE,
>   };
>   
>   /*
> diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
> index 4798bdf27afb..7755a4c073bf 100644
> --- a/drivers/mfd/rohm-bd718x7.c
> +++ b/drivers/mfd/rohm-bd718x7.c
> @@ -87,7 +87,7 @@ static const struct regmap_config bd718xx_regmap_config = {
>   	.val_bits = 8,
>   	.volatile_table = &volatile_regs,
>   	.max_register = BD718XX_MAX_REGISTER - 1,
> -	.cache_type = REGCACHE_RBTREE,
> +	.cache_type = REGCACHE_MAPLE,
>   };
>   
>   static int bd718xx_init_press_duration(struct regmap *regmap,
> diff --git a/drivers/mfd/rohm-bd9576.c b/drivers/mfd/rohm-bd9576.c
> index bceac7016740..3a9f61961721 100644
> --- a/drivers/mfd/rohm-bd9576.c
> +++ b/drivers/mfd/rohm-bd9576.c
> @@ -62,7 +62,7 @@ static struct regmap_config bd957x_regmap = {
>   	.val_bits = 8,
>   	.volatile_table = &volatile_regs,
>   	.max_register = BD957X_MAX_REGISTER,
> -	.cache_type = REGCACHE_RBTREE,
> +	.cache_type = REGCACHE_MAPLE,
>   };
>   
>   static struct regmap_irq bd9576_irqs[] = {

-- 
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~



From krzysztof.kozlowski at linaro.org  Tue Feb  6 23:58:03 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 7 Feb 2024 08:58:03 +0100
Subject: [PATCH 2/4] dt-bindings: hwinfo: ti,k3-socinfo: Add nvmem-cells
In-Reply-To: <20240206143711.2410135-3-msp@baylibre.com>
References: <20240206143711.2410135-1-msp@baylibre.com>
 <20240206143711.2410135-3-msp@baylibre.com>
Message-ID: <ef617fb5-8086-4f86-b855-e27fd69751fd@linaro.org>

On 06/02/2024 15:37, Markus Schneider-Pargmann wrote:
> The information k3-socinfo requires is stored in an efuse area. This
> area is required by other devices/drivers as well, so using nvmem-cells
> can be a cleaner way to describe which information are used.
> 
> If nvmem-cells are supplied, the address range is not required.
> Cells chipvariant, chippartno and chipmanufacturer are introduced to
> cover all required information.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> Reviewed-by: Andrew Davis <afd at ti.com>
> ---
>  .../bindings/hwinfo/ti,k3-socinfo.yaml        | 23 ++++++++++++++++++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
> index dada28b47ea0..f085b7275b7d 100644
> --- a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
> +++ b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
> @@ -26,9 +26,24 @@ properties:
>    reg:
>      maxItems: 1
>  
> +  nvmem-cells:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array

You do not need to redefine the type. You need constraints, so maxItems.

> +
> +  nvmem-cell-names:
> +    items:
> +      - const: chipvariant
> +      - const: chippartno
> +      - const: chipmanufacturer


Best regards,
Krzysztof



From chandru at ti.com  Wed Feb  7 00:06:05 2024
From: chandru at ti.com (CHANDRU DHAVAMANI)
Date: Wed, 7 Feb 2024 13:36:05 +0530
Subject: [PATCH v2] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <978c8110-3083-4fc2-a348-d7f97fd7839c@ti.com>
References: <20240206104357.3803517-1-u-kumar1@ti.com>
 <20240206131420.wtitflgav23jto2q@verbally>
 <871q9pzoiq.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <c5b6bd1d-dbb4-4bfb-8b3e-9b0733e2ba5d@ti.com>
 <c2b7f22d-f07d-4cac-8a01-af7b014e7ff4@ti.com>
 <a4fdbcfe-e0e0-4280-8638-e39b6b46778e@ti.com>
 <87ttmly4fa.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <e2ea03ce-0367-413b-aca9-7c1fabda173a@ti.com>
 <4398af20-3396-4a5c-8fcb-a7b3d0d6f15b@ti.com>
 <978c8110-3083-4fc2-a348-d7f97fd7839c@ti.com>
Message-ID: <5f54ee18-b3df-4918-9d5e-b765a6714ea2@ti.com>


On 07/02/24 13:03, Kumar, Udit wrote:
>
> On 2/7/2024 12:53 PM, CHANDRU DHAVAMANI wrote:
>>
>> On 07/02/24 11:03, Kumar, Udit wrote:
>>>
>>> On 2/6/2024 9:24 PM, Kamlesh Gurudasani wrote:
>>>> "Kumar, Udit" <u-kumar1 at ti.com> writes:
>>>>
>>>>>>>>> get_freq is a bit expensive as it has to walk the clock tree 
>>>>>>>>> to find
>>>>>>>>> the clock frequency (at least the first time?). just wondering if
>>>>>>>>> there is lighter alternative here?
>>>>>>>>>
>>>>>>>> How about get_clock? Doesn't read the registers at least.
>>>>>>> Said API needs, some flags to be passed,
>>>>>>>
>>>>>>> Can those flag be set to zero, Chandru ?
>>>>>>
>>>>>> get_clock doesn't require any flags to be passed.
>>>>>
>>>>> May be firmware does not need it but? I was referring to
>>>>>
>>>>> https://elixir.bootlin.com/linux/latest/source/drivers/clk/keystone/sci-clk.c#L78 
>>>>>
>>>> Just took a look,
>>>>
>>>> I now understand the reason for confusion,
>>>>
>>>> #define TI_SCI_MSG_SET_CLOCK_STATE??? 0x0100
>>>> #define TI_SCI_MSG_GET_CLOCK_STATE??? 0x0101
>>>>
>>>> cops->get_clock = ti_sci_cmd_get_clock;? --> refers to
>>>> TI_SCI_MSG_SET_CLOCK_STATE
>>>> That's why we are passing the flag from linux for get_clock
>>>>
>>>> Linux is using terminology of get/put.
>>>>
>>>> As Chandru pointed, we don't have to pass flags, cause he is refering
>>>> to TI_SCI_MSG_GET_CLOCK_STATE
>>>>
>>>> Below functions passes TI_SCI_MSG_GET_CLOCK_STATE to DM, which is what
>>>> we actually want.
>>>> cops->is_auto = ti_sci_cmd_clk_is_auto;
>>>> cops->is_on = ti_sci_cmd_clk_is_on;
>>>> cops->is_off = ti_sci_cmd_clk_is_off;
>>>
>>>
>>> I think calling ti_sci_cmd_clk_is_auto should be good . other 
>>> functions needs current state and requested state.
>>>
>>> Chandru ?
>>>
>>
>> ti_sci_cmd_clk_is_auto is internal function to linux.
>> For TI_SCI_MSG_GET_CLOCK_STATE, linux only needs to pass pointers to 
>> the variables where result will be stored.
>
>
> Yes this internal function calls TI_SCI_MSG_GET_CLOCK_STATE
>

Okay. We can use TI_SCI_MSG_GET_CLOCK_STATE to check to if clock is 
valid or not.


>
>>
>>
>>>>
>>>> Which should be safe to call, Chandru can confirm.
>>>>
>>>> Regards,
>>>> Kamlesh
>>>>>
>>>>>
>>>>>>
>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Kamlesh


From vkoul at kernel.org  Wed Feb  7 00:19:47 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 7 Feb 2024 09:19:47 +0100
Subject: [PATCH 00/12] Add support for BCM2712 DMA engine
In-Reply-To: <cover.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
Message-ID: <ZcM9I-U3w7xRcWVt@matsya>

On 04-02-24, 07:59, Andrea della Porta wrote:
> This patchset aims to update the dma engine for BCM* chipset with respect
> to current advancements in downstream vendor tree. In particular:
> 
> * Added support for BCM2712 DMA.
> * Extended DMA addressing to 40 bit. Since BCM2711 also supports 40 bit addressing,
> it will also benefit from the update.
> * Handled the devicetree node from vendor dts (e.g. "dma40").
> 
> The only difference between the application of this patch and the relative code
> in vendor tree is the dropping of channel reservation for BCM2708 DMA legacy
> driver, that seems to have not made its way to upstream anyway, and it's
> probably used only from deprecated subsystems.
> 
> Compile tested and runtime tested on RPi4B only.
> 
> Dom Cobley (4):
>   bcm2835-dma: Support dma flags for multi-beat burst
>   bcm2835-dma: Need to keep PROT bits set in CS on 40bit controller
>   dmaengine: bcm2835: Rename to_bcm2711_cbaddr to to_40bit_cbaddr
>   bcm2835-dma: Fixes for dma_abort
> 
> Maxime Ripard (2):
>   dmaengine: bcm2835: Use to_bcm2711_cbaddr where relevant
>   dmaengine: bcm2835: Support DMA-Lite channels
> 
> Phil Elwell (6):
>   bcm2835-dma: Add support for per-channel flags
>   bcm2835-dma: Add proper 40-bit DMA support
>   bcm2835-dma: Add NO_WAIT_RESP, DMA_WIDE_SOURCE and DMA_WIDE_DEST flag
>   bcm2835-dma: Advertise the full DMA range
>   bcm2835-dma: Derive slave DMA addresses correctly
>   dmaengine: bcm2835: Add BCM2712 support
> 
>  drivers/dma/bcm2835-dma.c | 701 ++++++++++++++++++++++++++++++++------
>  1 file changed, 588 insertions(+), 113 deletions(-)

Everything is modifying one file and still you have 2 different tags for patches, why?

Consistency is a good thing, right...

-- 
~Vinod


From ck.hu at mediatek.com  Wed Feb  7 00:21:26 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Wed, 7 Feb 2024 08:21:26 +0000
Subject: [PATCH v3 1/7] drm/mediatek: dsi: Use GENMASK() for register mask
 definitions
In-Reply-To: <4fe9947f-b190-4dcc-8d1e-f532e6dcb827@collabora.com>
References: <20240131113434.241929-1-angelogioacchino.delregno@collabora.com>
	 <20240131113434.241929-2-angelogioacchino.delregno@collabora.com>
	 <082bc4d9efd0746d7ec25eab0b3bf96018e997e5.camel@mediatek.com>
	 <4fe9947f-b190-4dcc-8d1e-f532e6dcb827@collabora.com>
Message-ID: <c10b8511f7d539cda9bcd941d5d48b253e8407e6.camel@mediatek.com>

Hi, Angelo:

On Tue, 2024-02-06 at 14:27 +0100, AngeloGioacchino Del Regno wrote:
> Il 06/02/24 09:57, CK Hu (???) ha scritto:
> > Hi, Angelo:
> > 
> > On Wed, 2024-01-31 at 12:34 +0100, AngeloGioacchino Del Regno
> > wrote:
> > > Change magic numerical masks with usage of the GENMASK() macro
> > > to improve readability.
> > > 
> > > While at it, also fix the DSI_PS_SEL mask to include all bits
> > > instead
> > > of just a subset of them.
> > > 
> > > This commit brings no functional changes.
> > > 
> > > Signed-off-by: AngeloGioacchino Del Regno <
> > > angelogioacchino.delregno at collabora.com>
> > > ---
> > >   drivers/gpu/drm/mediatek/mtk_dsi.c | 45 +++++++++++++++------
> > > -------
> > > --
> > >   1 file changed, 23 insertions(+), 22 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > index a2fdfc8ddb15..3b7392c03b4d 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > @@ -58,18 +58,18 @@
> > >   
> > >   #define DSI_TXRX_CTRL		0x18
> > >   #define VC_NUM				BIT(1)
> > > -#define LANE_NUM			(0xf << 2)
> > > +#define LANE_NUM			GENMASK(5, 2)
> > >   #define DIS_EOT				BIT(6)
> > >   #define NULL_EN				BIT(7)
> > >   #define TE_FREERUN			BIT(8)
> > >   #define EXT_TE_EN			BIT(9)
> > >   #define EXT_TE_EDGE			BIT(10)
> > > -#define MAX_RTN_SIZE			(0xf << 12)
> > > +#define MAX_RTN_SIZE			GENMASK(15, 12)
> > >   #define HSTX_CKLP_EN			BIT(16)
> > >   
> > >   #define DSI_PSCTRL		0x1c
> > > -#define DSI_PS_WC			0x3fff
> > > -#define DSI_PS_SEL			(3 << 16)
> > > +#define DSI_PS_WC			GENMASK(14, 0)
> > > +#define DSI_PS_SEL			GENMASK(19, 16)
> > 
> > The original definition of DSI_PS_WC/DSI_PS_SEL is correct in
> > MT8173.
> > So both need two definition and let each SoC select its own
> > definition.
> > 
> 
> The additional bits are unused on older SoCs and, if set, will be
> simply ignored;
> if we want to prevent setting bits that don't exist on the old ones,
> that should
> be done as a later commit introducing SoC capabilities for those and
> when the new
> capabilities for the new SoCs are introduced anyway.
> 
> As of now, this doesn't break anything.

The title of this patch is only to use GENMASK(), but here does more
things. I agree this does not break anything, but I would like to
separate this to an independent patch just for new bits. In your later
patch, DSI_PS_WC is not used any more. So maybe after that patch, you
could define as:

#define DSI_PS_WC_MT8173 GENMASK(13, 0)
#define DSI_PS_WC_MT8xxx GENMASK(14, 0)

DSI_PS_SEL is not used now, so it could also define as:

#define DSI_PS_SEL_MT8137 GENMASK(17, 16)
#define DSI_PS_SEL_MT8xxx GENMASK(19, 16)

And add definition of value 4 ~ 15.

Regards,
CK

> 
> Regards,
> Angelo
> 
> 

From vkoul at kernel.org  Wed Feb  7 00:22:10 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 7 Feb 2024 09:22:10 +0100
Subject: [PATCH 07/12] bcm2835-dma: Support dma flags for multi-beat burst
In-Reply-To: <570953f9532e2dc46568674d3c1348cdf26488b6.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
 <570953f9532e2dc46568674d3c1348cdf26488b6.1706948717.git.andrea.porta@suse.com>
Message-ID: <ZcM9slv_x-CltW6y@matsya>

On 04-02-24, 07:59, Andrea della Porta wrote:
> From: Dom Cobley <popcornmix at gmail.com>
> 
> Add a control bit to enable a multi-beat burst on a DMA.
> This improves DMA performance and is required for HDMI audio.
> 
> Signed-off-by: Dom Cobley <popcornmix at gmail.com>
> Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
> ---
>  drivers/dma/bcm2835-dma.c | 28 ++++++++++++++++++++--------
>  1 file changed, 20 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> index d8d1f9ba2572..a20700a400a2 100644
> --- a/drivers/dma/bcm2835-dma.c
> +++ b/drivers/dma/bcm2835-dma.c
> @@ -156,7 +156,8 @@ struct bcm2835_desc {
>  #define BCM2835_DMA_S_WIDTH	BIT(9) /* 128bit writes if set */
>  #define BCM2835_DMA_S_DREQ	BIT(10) /* enable SREQ for source */
>  #define BCM2835_DMA_S_IGNORE	BIT(11) /* ignore source reads - read 0 */
> -#define BCM2835_DMA_BURST_LENGTH(x) ((x & 15) << 12)
> +#define BCM2835_DMA_BURST_LENGTH(x) (((x) & 15) << 12)

why this changes, sounds like it does not belong here.. 


> +#define BCM2835_DMA_GET_BURST_LENGTH(x) (((x) >> 12) & 15)
>  #define BCM2835_DMA_CS_FLAGS(x) ((x) & (BCM2835_DMA_PRIORITY(15) | \
>  				      BCM2835_DMA_PANIC_PRIORITY(15) | \
>  				      BCM2835_DMA_WAIT_FOR_WRITES | \
> @@ -180,6 +181,11 @@ struct bcm2835_desc {
>  #define WIDE_DEST(x) (((x) & BCM2835_DMA_WIDE_DEST) ? \
>  		      BCM2835_DMA_D_WIDTH : 0)
>  
> +/* A fake bit to request that the driver requires multi-beat burst */
> +#define BCM2835_DMA_BURST BIT(30)
> +#define BURST_LENGTH(x) (((x) & BCM2835_DMA_BURST) ? \
> +			 BCM2835_DMA_BURST_LENGTH(3) : 0)
> +
>  /* debug register bits */
>  #define BCM2835_DMA_DEBUG_LAST_NOT_SET_ERR	BIT(0)
>  #define BCM2835_DMA_DEBUG_FIFO_ERR		BIT(1)
> @@ -282,7 +288,7 @@ struct bcm2835_desc {
>  /* the max dma length for different channels */
>  #define MAX_DMA40_LEN SZ_1G
>  
> -#define BCM2711_DMA40_BURST_LEN(x)	((min(x, 16) - 1) << 8)
> +#define BCM2711_DMA40_BURST_LEN(x)	(((x) & 15) << 8)
>  #define BCM2711_DMA40_INC		BIT(12)
>  #define BCM2711_DMA40_SIZE_32		(0 << 13)
>  #define BCM2711_DMA40_SIZE_64		(1 << 13)
> @@ -359,12 +365,16 @@ static inline uint32_t to_bcm2711_ti(uint32_t info)
>  
>  static inline uint32_t to_bcm2711_srci(uint32_t info)
>  {
> -	return ((info & BCM2835_DMA_S_INC) ? BCM2711_DMA40_INC : 0);
> +	return ((info & BCM2835_DMA_S_INC) ? BCM2711_DMA40_INC : 0) |
> +	       ((info & BCM2835_DMA_S_WIDTH) ? BCM2711_DMA40_SIZE_128 : 0) |
> +	       BCM2711_DMA40_BURST_LEN(BCM2835_DMA_GET_BURST_LENGTH(info));
>  }
>  
>  static inline uint32_t to_bcm2711_dsti(uint32_t info)
>  {
> -	return ((info & BCM2835_DMA_D_INC) ? BCM2711_DMA40_INC : 0);
> +	return ((info & BCM2835_DMA_D_INC) ? BCM2711_DMA40_INC : 0) |
> +	       ((info & BCM2835_DMA_D_WIDTH) ? BCM2711_DMA40_SIZE_128 : 0) |
> +	       BCM2711_DMA40_BURST_LEN(BCM2835_DMA_GET_BURST_LENGTH(info));
>  }
>  
>  static inline uint32_t to_bcm2711_cbaddr(dma_addr_t addr)
> @@ -933,7 +943,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_memcpy(
>  	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
>  	struct bcm2835_desc *d;
>  	u32 info = BCM2835_DMA_D_INC | BCM2835_DMA_S_INC |
> -		   WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) | WIDE_DEST(c->dreq);
> +		   WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) |
> +		   WIDE_DEST(c->dreq) | BURST_LENGTH(c->dreq);
>  	u32 extra = BCM2835_DMA_INT_EN;
>  	size_t max_len = bcm2835_dma_max_frame_length(c);
>  	size_t frames;
> @@ -964,8 +975,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg(
>  	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
>  	struct bcm2835_desc *d;
>  	dma_addr_t src = 0, dst = 0;
> -	u32 info = WAIT_RESP(c->dreq) |
> -		   WIDE_SOURCE(c->dreq) | WIDE_DEST(c->dreq);
> +	u32 info = WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) |
> +		   WIDE_DEST(c->dreq) | BURST_LENGTH(c->dreq);
>  	u32 extra = BCM2835_DMA_INT_EN;
>  	size_t frames;
>  
> @@ -1017,7 +1028,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
>  	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
>  	struct bcm2835_desc *d;
>  	dma_addr_t src, dst;
> -	u32 info = WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) | WIDE_DEST(c->dreq);
> +	u32 info = WAIT_RESP(c->dreq) | WIDE_SOURCE(c->dreq) |
> +		   WIDE_DEST(c->dreq) | BURST_LENGTH(c->dreq);
>  	u32 extra = 0;
>  	size_t max_len = bcm2835_dma_max_frame_length(c);
>  	size_t frames;
> -- 
> 2.41.0

-- 
~Vinod


From vkoul at kernel.org  Wed Feb  7 00:26:08 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 7 Feb 2024 09:26:08 +0100
Subject: [PATCH 10/12] dmaengine: bcm2835: Support DMA-Lite channels
In-Reply-To: <ca956587595954525fca0b635a66ca78b7000bf4.1706948717.git.andrea.porta@suse.com>
References: <cover.1706948717.git.andrea.porta@suse.com>
 <ca956587595954525fca0b635a66ca78b7000bf4.1706948717.git.andrea.porta@suse.com>
Message-ID: <ZcM-oM2hySPlOcyp@matsya>

On 04-02-24, 07:59, Andrea della Porta wrote:
> From: Maxime Ripard <maxime at cerno.tech>
> 
> The BCM2712 has a DMA-Lite controller that is basically a BCM2835-style
> DMA controller that supports 40 bits DMA addresses.
> 
> We need it for HDMI audio to work.
> 
> Cc: Maxime Ripard <maxime at cerno.tech>
> Cc: Dom Cobley <popcornmix at gmail.com>
> Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
> ---
>  drivers/dma/bcm2835-dma.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
> index 548cf7343d83..055c558caa0e 100644
> --- a/drivers/dma/bcm2835-dma.c
> +++ b/drivers/dma/bcm2835-dma.c
> @@ -100,6 +100,7 @@ struct bcm2835_chan {
>  
>  	bool is_lite_channel;
>  	bool is_40bit_channel;
> +	bool is_2712;

why not use is_40bit_channel..? also this can be applicable for more
soc, make it generic flag if you cant reuse this one

>  };
>  
>  struct bcm2835_desc {
> @@ -545,7 +546,11 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
>  			control_block->info = info;
>  			control_block->src = src;
>  			control_block->dst = dst;
> -			control_block->stride = 0;
> +			if (c->is_2712)
> +				control_block->stride = (upper_32_bits(dst) << 8) |
> +							upper_32_bits(src);
> +			else
> +				control_block->stride = 0;
>  			control_block->next = 0;
>  		}
>  
> @@ -570,7 +575,8 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain(
>  			 d->cb_list[frame - 1].cb)->next_cb =
>  				to_bcm2711_cbaddr(cb_entry->paddr);
>  		if (frame && !c->is_40bit_channel)
> -			d->cb_list[frame - 1].cb->next = cb_entry->paddr;
> +			d->cb_list[frame - 1].cb->next = c->is_2712 ?
> +			to_bcm2711_cbaddr(cb_entry->paddr) : cb_entry->paddr;
>  
>  		/* update src and dst and length */
>  		if (src && (info & BCM2835_DMA_S_INC)) {
> @@ -750,7 +756,10 @@ static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
>  		writel(BCM2711_DMA40_ACTIVE | BCM2711_DMA40_PROT | BCM2711_DMA40_CS_FLAGS(c->dreq),
>  		       c->chan_base + BCM2711_DMA40_CS);
>  	} else {
> -		writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR);
> +		writel(BIT(31), c->chan_base + BCM2835_DMA_CS);
> +
> +		writel(c->is_2712 ? to_bcm2711_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr,
> +		       c->chan_base + BCM2835_DMA_ADDR);
>  		writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq),
>  		       c->chan_base + BCM2835_DMA_CS);
>  	}
> @@ -1119,7 +1128,8 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
>  		 d->cb_list[frames - 1].cb)->next_cb =
>  			to_bcm2711_cbaddr(d->cb_list[0].paddr);
>  	else
> -		d->cb_list[d->frames - 1].cb->next = d->cb_list[0].paddr;
> +		d->cb_list[d->frames - 1].cb->next = c->is_2712 ?
> +		to_bcm2711_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr;
>  
>  	return vchan_tx_prep(&c->vc, &d->vd, flags);
>  }
> @@ -1186,6 +1196,8 @@ static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id,
>  	else if (readl(c->chan_base + BCM2835_DMA_DEBUG) &
>  		 BCM2835_DMA_DEBUG_LITE)
>  		c->is_lite_channel = true;
> +	if (d->cfg_data->dma_mask == DMA_BIT_MASK(40))
> +		c->is_2712 = true;
>  
>  	return 0;
>  }
> -- 
> 2.41.0

-- 
~Vinod


From vkoul at kernel.org  Wed Feb  7 00:49:31 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 07 Feb 2024 09:49:31 +0100
Subject: (subset) [PATCH v2 0/2] dt-bindings: mmp-dma: YAML conversion
In-Reply-To: <20240131-pxa-dma-yaml-v2-0-9611d0af0edc@skole.hr>
References: <20240131-pxa-dma-yaml-v2-0-9611d0af0edc@skole.hr>
Message-ID: <170729577170.88801.16549328232366263331.b4-ty@kernel.org>


On Wed, 31 Jan 2024 22:26:01 +0100, Duje Mihanovi? wrote:
> Convert the mmp-dma binding to YAML and drop a useless property in
> MMP2's ADMA node.
> 
> 

Applied, thanks!

[2/2] dt-bindings: mmp-dma: convert to YAML
      commit: d2363272ef9f96709ec1a146bb66378256c92e1d

Best regards,
-- 
~Vinod




From piotr.firek at financialflows.pl  Wed Feb  7 00:55:43 2024
From: piotr.firek at financialflows.pl (Piotr Firek)
Date: Wed,  7 Feb 2024 08:55:43 GMT
Subject: =?UTF-8?Q?Prosz=C4=99_o_kontakt?=
Message-ID: <20240207074500-0.1.2j.8i4i.0.s6md252gy8@financialflows.pl>

Dzie? dobry,

Czy jest mo?liwo?? nawi?zania wsp??pracy z Pa?stwem?

Z ch?ci? porozmawiam z osob? zajmuj?c? si? dzia?aniami zwi?zanymi ze sprzeda??.

Pomagamy skutecznie pozyskiwa? nowych klient?w.

Zapraszam do kontaktu.


Pozdrawiam
Piotr Firek


From gankulkarni at os.amperecomputing.com  Wed Feb  7 01:04:58 2024
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Wed,  7 Feb 2024 01:04:58 -0800
Subject: [PATCH] arm64: errata: Minimize tlb flush due to vttbr writes on AmpereOne
Message-ID: <20240207090458.463021-1-gankulkarni@os.amperecomputing.com>

AmpereOne implementation is doing tlb flush when ever there is
a write to vttbr_el2. As per KVM implementation, vttbr_el2 is updated
with VM's S2-MMU while return to VM. This is not necessary when there
is no VM context switch and a just return to same Guest.

Adding a check to avoid the vttbr_el2 write if the same value
already exist to prevent needless tlb flush.

Signed-off-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
---
 Documentation/arch/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                          | 13 +++++++++++++
 arch/arm64/include/asm/kvm_mmu.h            |  8 +++++++-
 arch/arm64/kernel/cpu_errata.c              |  7 +++++++
 arch/arm64/tools/cpucaps                    |  1 +
 5 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index e8c2ce1f9df6..8924e84358c9 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -54,6 +54,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | Ampere         | AmpereOne       | AC03_CPU_38     | AMPERE_ERRATUM_AC03_CPU_38  |
 +----------------+-----------------+-----------------+-----------------------------+
+| Ampere         | AmpereOne       | N/A             | AMPERE_AC03_REDUCE_TLB_FLUSH|
++----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2457168        | ARM64_ERRATUM_2457168       |
 +----------------+-----------------+-----------------+-----------------------------+
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aa7c1d435139..77485d0322e4 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -436,6 +436,19 @@ config AMPERE_ERRATUM_AC03_CPU_38
 
 	  If unsure, say Y.
 
+config AMPERE_AC03_REDUCE_TLB_FLUSH
+	bool "AmpereOne: Minimize the writes to vttbr_el2 register"
+	default y
+	help
+	  On AmpereOne, any writes to vttbr_el2 results in TLB flush.
+	  It can be avoided to improve the performance when there is no VM
+	  context switches and a just return to same VM from the hypervisor.
+
+	  This option adds a check to avoid rewrite of the same value
+	  to vttbr_el2.
+
+	  If unsure, say Y.
+
 config ARM64_WORKAROUND_CLEAN_CACHE
 	bool
 
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index e3e793d0ec30..da39e4749434 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -317,8 +317,14 @@ static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
 static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu,
 					  struct kvm_arch *arch)
 {
+	u64 vttbr;
+
+	vttbr = kvm_get_vttbr(mmu);
 	write_sysreg(mmu->vtcr, vtcr_el2);
-	write_sysreg(kvm_get_vttbr(mmu), vttbr_el2);
+
+	if (!cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_TLB_FLUSH) ||
+	    read_sysreg(vttbr_el2) != vttbr)
+		write_sysreg(vttbr, vttbr_el2);
 
 	/*
 	 * ARM errata 1165522 and 1530923 require the actual execution of the
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 967c7c7a4e7d..f612975e0cb5 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -740,6 +740,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		.capability = ARM64_WORKAROUND_AMPERE_AC03_CPU_38,
 		ERRATA_MIDR_ALL_VERSIONS(MIDR_AMPERE1),
 	},
+#endif
+#ifdef CONFIG_AMPERE_AC03_REDUCE_TLB_FLUSH
+	{
+		.desc = "AmpereOne, minimize tlb flush due to vttbr write",
+		.capability = ARM64_WORKAROUND_AMPERE_AC03_TLB_FLUSH,
+		ERRATA_MIDR_ALL_VERSIONS(MIDR_AMPERE1),
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index b912b1409fc0..b4bee37d0527 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -85,6 +85,7 @@ WORKAROUND_2457168
 WORKAROUND_2645198
 WORKAROUND_2658417
 WORKAROUND_AMPERE_AC03_CPU_38
+WORKAROUND_AMPERE_AC03_TLB_FLUSH
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.41.0



From abel.vesa at linaro.org  Wed Feb  7 01:08:05 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 7 Feb 2024 11:08:05 +0200
Subject: [PATCH RFC 1/2] spmi: Add support for multi-master
In-Reply-To: <CAA8EJprqWLX7_yWZzKp3FAKFGkSkk041f9hj1uXuRBrbH5APyQ@mail.gmail.com>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
 <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>
 <CAA8EJpqsJmv36=o1aTjVH6eMHXMg8BHNpiDvs+Q8YB23ezVGtQ@mail.gmail.com>
 <ZcMvFtAwQQjAZhk6@linaro.org>
 <CAA8EJprqWLX7_yWZzKp3FAKFGkSkk041f9hj1uXuRBrbH5APyQ@mail.gmail.com>
Message-ID: <ZcNIddeG6VHxBEOQ@linaro.org>

On 24-02-07 09:23:09, Dmitry Baryshkov wrote:
> On Wed, 7 Feb 2024 at 09:19, Abel Vesa <abel.vesa at linaro.org> wrote:
> >
> > On 24-02-07 01:55:39, Dmitry Baryshkov wrote:
> > > On Wed, 7 Feb 2024 at 01:34, Abel Vesa <abel.vesa at linaro.org> wrote:
> > > >
> > > > Some newer SPMI controllers support multiple bus masters.
> > > > Such a master can control multiple slave devices. The generic
> > > > framework needs to be able to pass on the master id to the
> > > > controller-specific driver. So do that. The framework will
> > > > check if the devicetree child nodes are actually bus masters
> > > > and will register the devices for each master. The legacy
> > > > approach will still be supported for backwards compatibility.
> > >
> > > Please remind me, are those two actual bus musters driving a single
> > > bus in parallel or two SPMI buses being handled by a single device? In
> > > the latter case this implementation is incorrect. There should be
> > > multiple spmi_controller instances, one for each bus. Allocate them in
> > > a loop and set ctrl->dev.of_node after allocating.
> >
> > It's two SPMI buses (two sets of wires) handled by the same controller,
> > HW-wise.
> >
> > If we register two spmi controllers with the kernel framework, it will
> > be HW inaccurate, because there is just one controller which has
> > multiple masters.
> 
> struct spmi_controller is a controller for a single bus. Inside your
> device you have two SPMI buses, each can be controlled by its own
> struct spmi_controller. Just like devices that control multiple I2C,
> SPI or USB busses register a separate instance of the bus controller.

Well, this is what this patchset is trying to do in the generic part.
The SPMI controller supports multiple buses (HW-wise) and therefore SW
implementation shouldn't be tied to single bus requirement.

> 
> >
> > I'm not saying it might not work. But, to me, it looks more like a hack.
> >
> > Basically, we would be mapping HW bus masters to kernel controllers.
> 
> Buses, not just masters.
> 
> >
> > >
> > > >
> > > > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > > > ---
> > > >  drivers/spmi/spmi-mtk-pmif.c |  6 ++--
> > > >  drivers/spmi/spmi-pmic-arb.c | 10 +++---
> > > >  drivers/spmi/spmi.c          | 76 ++++++++++++++++++++++++++++++--------------
> > > >  include/linux/spmi.h         | 10 +++---
> > > >  4 files changed, 67 insertions(+), 35 deletions(-)
> > >
> > > --
> > > With best wishes
> > > Dmitry
> 
> 
> 
> -- 
> With best wishes
> Dmitry


From dharma.b at microchip.com  Wed Feb  7 01:08:53 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Wed, 7 Feb 2024 14:38:53 +0530
Subject: [PATCH] dt-bindings: input: atmel,captouch: convert bindings to YAML
Message-ID: <20240207090853.188400-1-dharma.b@microchip.com>

Convert the Atmel capacitive touchscreen bindings to YAML format.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
 .../bindings/input/atmel,captouch.txt         | 36 -----------
 .../bindings/input/atmel,captouch.yaml        | 62 +++++++++++++++++++
 2 files changed, 62 insertions(+), 36 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/input/atmel,captouch.txt
 create mode 100644 Documentation/devicetree/bindings/input/atmel,captouch.yaml

diff --git a/Documentation/devicetree/bindings/input/atmel,captouch.txt b/Documentation/devicetree/bindings/input/atmel,captouch.txt
deleted file mode 100644
index fe9ee5c53bcc..000000000000
--- a/Documentation/devicetree/bindings/input/atmel,captouch.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-Device tree bindings for Atmel capacitive touch device, typically
-an Atmel touch sensor connected to AtmegaXX MCU running firmware
-based on Qtouch library.
-
-The node for this device must be a child of a I2C controller node, as the
-device communicates via I2C.
-
-Required properties:
-
-	compatible:	Must be "atmel,captouch".
-	reg:		The I2C slave address of the device.
-	interrupts:	Property describing the interrupt line the device
-			is connected to. The device only has one interrupt
-			source.
-	linux,keycodes:	Specifies an array of numeric keycode values to
-			be used for reporting button presses. The array can
-			contain up to 8 entries.
-
-Optional properties:
-
-	autorepeat:	Enables the Linux input system's autorepeat
-			feature on the input device.
-
-Example:
-
-	atmel-captouch at 51 {
-		compatible = "atmel,captouch";
-		reg = <0x51>;
-		interrupt-parent = <&tlmm>;
-		interrupts = <67 IRQ_TYPE_EDGE_FALLING>;
-		linux,keycodes = <BTN_0>, <BTN_1>,
-			<BTN_2>, <BTN_3>,
-			<BTN_4>, <BTN_5>,
-			<BTN_6>, <BTN_7>;
-		autorepeat;
-	};
diff --git a/Documentation/devicetree/bindings/input/atmel,captouch.yaml b/Documentation/devicetree/bindings/input/atmel,captouch.yaml
new file mode 100644
index 000000000000..5d5679896bc9
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/atmel,captouch.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/atmel,captouch.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel capacitive touch device
+
+maintainers:
+  - Dharma balasubiramani <dharma.b at microchip.com>
+
+description:
+  Atmel capacitive touch device, typically an Atmel touch sensor connected to
+  AtmegaXX MCU running firmware based on Qtouch library.
+
+allOf:
+  - $ref: input.yaml#
+
+properties:
+  compatible:
+    const: atmel,captouch
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  linux,keycodes:
+    minItems: 1
+    maxItems: 8
+
+  autorepeat:
+    type: boolean
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - linux,keycodes
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/input/linux-event-codes.h>
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      atmel-captouch at 51 {
+        compatible = "atmel,captouch";
+        reg = <0x51>;
+        interrupt-parent = <&tlmm>;
+        interrupts = <67 IRQ_TYPE_EDGE_FALLING>;
+        linux,keycodes = <BTN_0>, <BTN_1>,
+                         <BTN_2>, <BTN_3>,
+                         <BTN_4>, <BTN_5>,
+                         <BTN_6>, <BTN_7>;
+        autorepeat;
+      };
+    };
-- 
2.25.1



From Kuan-Ying.Lee at mediatek.com  Wed Feb  7 00:58:51 2024
From: Kuan-Ying.Lee at mediatek.com (Kuan-Ying Lee)
Date: Wed, 7 Feb 2024 16:58:51 +0800
Subject: [PATCH] scripts/gdb/vmalloc: fix vmallocinfo error
Message-ID: <20240207085856.11190-1-Kuan-Ying.Lee@mediatek.com>

We met the gdb vmallocinfo issue as following.

(gdb) lx-vmallocinfo
Python Exception <class 'gdb.error'>: No symbol "vmap_area_list" in current context.
Error occurred in Python: No symbol "vmap_area_list" in current context.

Since Mitigate a vmap lock contention patchset [1], we
remove the vmap_area_list.

We need to use vmap_nodes to iterate all vmallocinfo.

[1] https://lore.kernel.org/linux-mm/20240102184633.748113-1-urezki at gmail.com/

Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
Cc: Casper Li <casper.li at mediatek.com>
---
 scripts/gdb/linux/vmalloc.py | 56 +++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 27 deletions(-)

diff --git a/scripts/gdb/linux/vmalloc.py b/scripts/gdb/linux/vmalloc.py
index d3c8a0274d1e..803f17371052 100644
--- a/scripts/gdb/linux/vmalloc.py
+++ b/scripts/gdb/linux/vmalloc.py
@@ -29,32 +29,34 @@ class LxVmallocInfo(gdb.Command):
         if not constants.LX_CONFIG_MMU:
             raise gdb.GdbError("Requires MMU support")
 
-        vmap_area_list = gdb.parse_and_eval('vmap_area_list')
-        for vmap_area in lists.list_for_each_entry(vmap_area_list, vmap_area_ptr_type, "list"):
-            if not vmap_area['vm']:
-                gdb.write("0x%x-0x%x %10d vm_map_ram\n" % (vmap_area['va_start'], vmap_area['va_end'],
-                    vmap_area['va_end'] - vmap_area['va_start']))
-                continue
-            v = vmap_area['vm']
-            gdb.write("0x%x-0x%x %10d" % (v['addr'], v['addr'] + v['size'], v['size']))
-            if v['caller']:
-                gdb.write(" %s" % str(v['caller']).split(' ')[-1])
-            if v['nr_pages']:
-                gdb.write(" pages=%d" % v['nr_pages'])
-            if v['phys_addr']:
-                gdb.write(" phys=0x%x" % v['phys_addr'])
-            if v['flags'] & constants.LX_VM_IOREMAP:
-                gdb.write(" ioremap")
-            if v['flags'] & constants.LX_VM_ALLOC:
-                gdb.write(" vmalloc")
-            if v['flags'] & constants.LX_VM_MAP:
-                gdb.write(" vmap")
-            if v['flags'] & constants.LX_VM_USERMAP:
-                gdb.write(" user")
-            if v['flags'] & constants.LX_VM_DMA_COHERENT:
-                gdb.write(" dma-coherent")
-            if is_vmalloc_addr(v['pages']):
-                gdb.write(" vpages")
-            gdb.write("\n")
+        nr_vmap_nodes = gdb.parse_and_eval('nr_vmap_nodes')
+        for i in range(0, nr_vmap_nodes):
+            vn = gdb.parse_and_eval('&vmap_nodes[%d]' % i)
+            for vmap_area in lists.list_for_each_entry(vn['busy']['head'], vmap_area_ptr_type, "list"):
+                if not vmap_area['vm']:
+                    gdb.write("0x%x-0x%x %10d vm_map_ram\n" % (vmap_area['va_start'], vmap_area['va_end'],
+                        vmap_area['va_end'] - vmap_area['va_start']))
+                    continue
+                v = vmap_area['vm']
+                gdb.write("0x%x-0x%x %10d" % (v['addr'], v['addr'] + v['size'], v['size']))
+                if v['caller']:
+                    gdb.write(" %s" % str(v['caller']).split(' ')[-1])
+                if v['nr_pages']:
+                    gdb.write(" pages=%d" % v['nr_pages'])
+                if v['phys_addr']:
+                    gdb.write(" phys=0x%x" % v['phys_addr'])
+                if v['flags'] & constants.LX_VM_IOREMAP:
+                    gdb.write(" ioremap")
+                if v['flags'] & constants.LX_VM_ALLOC:
+                    gdb.write(" vmalloc")
+                if v['flags'] & constants.LX_VM_MAP:
+                    gdb.write(" vmap")
+                if v['flags'] & constants.LX_VM_USERMAP:
+                    gdb.write(" user")
+                if v['flags'] & constants.LX_VM_DMA_COHERENT:
+                    gdb.write(" dma-coherent")
+                if is_vmalloc_addr(v['pages']):
+                    gdb.write(" vpages")
+                gdb.write("\n")
 
 LxVmallocInfo()
-- 
2.18.0



From patchwork-bot+netdevbpf at kernel.org  Wed Feb  7 01:10:25 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 07 Feb 2024 09:10:25 +0000
Subject: [PATCH net v3] net: stmmac: protect updates of 64-bit statistics
 counters
In-Reply-To: <20240203190927.19669-1-petr@tesarici.cz>
References: <20240203190927.19669-1-petr@tesarici.cz>
Message-ID: <170729702541.31522.8754905006786635767.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (main)
by David S. Miller <davem at davemloft.net>:

On Sat,  3 Feb 2024 20:09:27 +0100 you wrote:
> As explained by a comment in <linux/u64_stats_sync.h>, write side of struct
> u64_stats_sync must ensure mutual exclusion, or one seqcount update could
> be lost on 32-bit platforms, thus blocking readers forever. Such lockups
> have been observed in real world after stmmac_xmit() on one CPU raced with
> stmmac_napi_poll_tx() on another CPU.
> 
> To fix the issue without introducing a new lock, split the statics into
> three parts:
> 
> [...]

Here is the summary with links:
  - [net,v3] net: stmmac: protect updates of 64-bit statistics counters
    https://git.kernel.org/netdev/net/c/38cc3c6dcc09

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From u-kumar1 at ti.com  Wed Feb  7 01:11:00 2024
From: u-kumar1 at ti.com (Udit Kumar)
Date: Wed, 7 Feb 2024 14:41:00 +0530
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non contiguous clocks
Message-ID: <20240207091100.4001428-1-u-kumar1@ti.com>

Most of clocks and their parents are defined in contiguous range,
But in few cases, there is gap in clock numbers[0].
Driver assumes clocks to be in contiguous range, and add their clock
ids incrementally.

New firmware started returning error while calling get_freq and is_on
API for non-available clock ids.

In this fix, driver checks and adds only valid clock ids.

Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")

[0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
Section Clocks for NAVSS0_CPTS_0 Device,
clock id 12-15 not present.

Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
---
Changelog
Changes in v3
- instead of get_freq, is_auto API is used to check validilty of clock
- Address comments of v2, to have preindex increment
Link to v2 https://lore.kernel.org/all/20240206104357.3803517-1-u-kumar1 at ti.com/

Changes in v2
- Updated commit message
- Simplified logic for valid clock id
link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/


P.S
Firmawre returns total num_parents count including non available ids.
For above device id NAVSS0_CPTS_0, number of parents clocks are 16
i.e from id 2 to 17. But out of these ids few are not valid.
So driver adds only valid clock ids out ot total.

Original logs
https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
Line 2630 for error

Logs with fix v3
https://gist.github.com/uditkumarti/94e3e28d62282fd708dbfe37435ce1d9#file-v3
Line 2586


 drivers/clk/keystone/sci-clk.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 35fe197dd303..31b7df05d7bb 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -516,6 +516,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
 	struct sci_clk *sci_clk, *prev;
 	int num_clks = 0;
 	int num_parents;
+	bool state;
 	int clk_id;
 	const char * const clk_names[] = {
 		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
@@ -583,16 +584,23 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
 					num_parents = 255;
 				}
 
-				clk_id = args.args[1] + 1;
+				clk_id = args.args[1];
 
 				while (num_parents--) {
+					/* Check if this clock id is valid */
+					ret = provider->ops->is_auto(provider->sci,
+						sci_clk->dev_id, ++clk_id, &state);
+
+					if (ret)
+						continue;
+
 					sci_clk = devm_kzalloc(dev,
 							       sizeof(*sci_clk),
 							       GFP_KERNEL);
 					if (!sci_clk)
 						return -ENOMEM;
 					sci_clk->dev_id = args.args[0];
-					sci_clk->clk_id = clk_id++;
+					sci_clk->clk_id = clk_id;
 					sci_clk->provider = provider;
 					list_add_tail(&sci_clk->node, &clks);
 
-- 
2.34.1



From neil.armstrong at linaro.org  Wed Feb  7 01:13:29 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 7 Feb 2024 10:13:29 +0100
Subject: [PATCH] drm/bridge: imx8mp-hdmi-pvi: Fix build warnings
In-Reply-To: <20240207002305.618499-1-aford173@gmail.com>
References: <20240207002305.618499-1-aford173@gmail.com>
Message-ID: <b56d11ce-869f-4183-bb26-f0261af356a6@linaro.org>

On 07/02/2024 01:23, Adam Ford wrote:
> Two separate build warnings were reported.  One from an
> uninitialized variable, and the other from returning 0
> instead of NULL from a pointer.
> 
> Fixes: 059c53e877ca ("drm/bridge: imx: add driver for HDMI TX Parallel Video Interface")
> Reported-by: nathan at kernel.org
> Reported-by: kernel test robot <lkp at intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202402062134.a6CqAt3s-lkp at intel.com/
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 
> diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> index a76b7669fe8a..f2a09c879e3d 100644
> --- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> @@ -57,7 +57,7 @@ static void imx8mp_hdmi_pvi_bridge_enable(struct drm_bridge *bridge,
>   	const struct drm_display_mode *mode;
>   	struct drm_crtc_state *crtc_state;
>   	struct drm_connector *connector;
> -	u32 bus_flags, val;
> +	u32 bus_flags = 0, val;
>   
>   	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
>   	conn_state = drm_atomic_get_new_connector_state(state, connector);
> @@ -110,7 +110,7 @@ imx8mp_hdmi_pvi_bridge_get_input_bus_fmts(struct drm_bridge *bridge,
>   	struct drm_bridge_state *next_state;
>   
>   	if (!next_bridge->funcs->atomic_get_input_bus_fmts)
> -		return 0;
> +		return NULL;
>   
>   	next_state = drm_atomic_get_new_bridge_state(crtc_state->state,
>   						     next_bridge);

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From apatel at ventanamicro.com  Wed Feb  7 01:18:38 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 7 Feb 2024 14:48:38 +0530
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <874jekag3w.fsf@all.your.base.are.belong.to.us>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <87h6ily53k.fsf@all.your.base.are.belong.to.us> <CAAhSdy2PPjS6++Edh8NkgiBmcovTUjS5oXE2eR5ZwPfAfVA0ng@mail.gmail.com>
 <874jekag3w.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAK9=C2XJYTfY4nXWtjK9OP1iXLDXBVF-=mN1SmJDmJ_dO5CohA@mail.gmail.com>

On Wed, Feb 7, 2024 at 12:57?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Hi!
>
> Anup Patel <anup at brainfault.org> writes:
>
> > On Tue, Feb 6, 2024 at 9:09?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
> >>
> >> Hi Anup,
> >>
> >> Anup Patel <apatel at ventanamicro.com> writes:
> >>
> >> > The RISC-V AIA specification is ratified as-per the RISC-V international
> >> > process. The latest ratified AIA specifcation can be found at:
> >> > https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf
> >> >
> >> > At a high-level, the AIA specification adds three things:
> >> > 1) AIA CSRs
> >> >    - Improved local interrupt support
> >> > 2) Incoming Message Signaled Interrupt Controller (IMSIC)
> >> >    - Per-HART MSI controller
> >> >    - Support MSI virtualization
> >> >    - Support IPI along with virtualization
> >> > 3) Advanced Platform-Level Interrupt Controller (APLIC)
> >> >    - Wired interrupt controller
> >> >    - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
> >> >    - In Direct-mode, injects external interrupts directly into HARTs
> >> >
> >> > For an overview of the AIA specification, refer the AIA virtualization
> >> > talk at KVM Forum 2022:
> >> > https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
> >> > https://www.youtube.com/watch?v=r071dL8Z0yo
> >>
> >> Thank you for continuing to work on this series! I like this
> >> direction of the series!
> >>
> >> TL;DR: I think we can get rid of most of the id/householding data
> >> structures, except for the irq matrix.
> >>
> >> Most of my comments are more of a design/overview nature, so I'll
> >> comment here in the cover letter.
> >>
> >> I took the series for a spin with and it with Alex' ftrace fix it,
> >> passes all my tests nicely!
> >>
> >> Now some thoughts/comments (I'm coming from the x86 side of things!):
> >>
> >> id/enable-tracking: There are a lot of different id/enabled tracking
> >> with corresponding locks, where there's IMO overlap with what the
> >> matrix provides.
> >
> > The matrix allocator does not track the enabled/disabled state of
> > the per-CPU IDs. This is why we have a separate per-CPU
> > ids_enabled_bitmap which is also used for remote synchronization
> > across CPUs.
>
> Exactly, but what I'm asking is if that structure is really needed. More
> below.
>
> >> Let's start with struct imsic_priv:
> >>
> >>    | /* Dummy HW interrupt numbers */
> >>    | unsigned int nr_hwirqs;
> >>    | raw_spinlock_t hwirqs_lock;
> >>    | unsigned long *hwirqs_used_bitmap;
> >
> > The matrix allocator manages actual IDs for each CPU whereas
> > the Linux irq_data expects a fixed hwirq which does not change.
> >
> > Due to this, we have a dummy hwirq space which is always
> > fixed. The only thing that is changed under-the-hood by the
> > IMSIC driver is the dummy hwirq to actual HW vector (cpu, id)
> > mapping.
>
> Read below. I'm not talking about local_id from the irq_matrix, I'm
> saying use virq, which has the properties you're asking for, and doesn't
> require an additional structure. When an irq/desc is allocated, you have
> a nice unique number with the virq for the lifetime of the interrupt.

Sure, let me explore using virq in-place of hwirq.

>
> >> These are used to for the domain routing (hwirq -> desc/virq), and not
> >> needed. Just use the same id as virq (at allocation time), and get rid
> >> of these data structures/corresponding functions. The lookup in the
> >> interrupt handler via imsic_local_priv.vectors doesn't care about
> >> hwirq. This is what x86 does... The imsic_vector roughly corresponds
> >> to apic_chip_data (nit: imsic_vector could have the chip_data suffix
> >> as well, at least it would have helped me!)
> >
> > Yes, imsic_vector corresponds to apic_chip_data in the x86 world.
>
> ...and I'm trying to ask the following; Given the IMSIC is pretty much
> x86 vector (arch/x86/kernel/apic/vector.c), I'm trying to figure out the
> rational why IMSIC has all the extra householding data, not needed by
> x86. The x86 has been battle proven, and having to deal with all kind of
> quirks (e.g. lost interrupts on affinity changes).

Understood.

>
> >> Moving/affinity changes. The moving of a vector to another CPU
> >> currently involves:
> >>
> >> 1. Allocate a new vector from the matrix
> >> 2. Disable/enable the corresponding per-cpu ids_enabled_bitmap (nested
> >>    spinlocks)
> >> 3. Trigger two IPIs to apply the bitmap
> >> 4. On each CPU target (imsic_local_sync()) loop the bitmap and flip
> >>    all bits, and potentially rearm
> >>
> >> This seems a bit heavy-weight: Why are you explicitly setting/clearing
> >> all the bits in a loop at the local sync?
> >
> > This can be certainly optimized by introducing another
> > ids_dirty_bitmap. I will add this in the next revision.
>
> I rather have fewer maps, and less locks! ;-)
>
> >> x86 does it a bit differently (more lazily): The chip_data has
> >> prev_{cpu,vector}/move_in_progress fields, and keep both vectors
> >> enabled until there's an interrupt on the new vector, and then the old
> >> one is cleaned (irq_complete_move()).
> >>
> >> Further; When it's time to remove the old vector, x86 doesn't trigger
> >> an IPI on the disabling side, but queues a cleanup job on a per-cpu
> >> list and triggers a timeout. So, the per-cpu chip_data (per-cpu
> >> "vectors" in your series) can reside in two places during the transit.
> >
> > We can't avoid IPIs when moving vectors from one CPU to another
> > CPU because IMSIC id enable/disable is only possible through
> > CSRs. Also, keep in-mind that irq affinity change might be initiated
> > on CPU X for some interrupt targeting CPU Y which is then changed
> > to target CPU Z.
> >
> > In the case of x86, they have memory mapped registers which
> > allows one CPU to enable/disable the ID of another CPU.
>
> Nope. Same mechanics on x86 -- the cleanup has to be done one the
> originating core. What I asked was "what about using a timer instead of
> an IPI". I think this was up in the last rev as well?
>
> Check out commit bdc1dad299bb ("x86/vector: Replace
> IRQ_MOVE_CLEANUP_VECTOR with a timer callback") Specifically, the
> comment about lost interrupts, and the rational for keeping the original
> target active until there's a new interrupt on the new cpu.

Trying timer interrupt is still TBD on my side because with v12
my goal was to implement per-device MSI domains. Let me
explore timer interrupts for v13.

>
> >> I wonder if this clean up is less intrusive, and you just need to
> >> perform what's in the per-list instead of dealing with the
> >> ids_enabled_bitmap? Maybe we can even remove that bitmap as well. The
> >> chip_data/desc has that information. This would mean that
> >> imsic_local_priv() would only have the local vectors (chip_data), and
> >> a cleanup list/timer.
> >>
> >> My general comment is that instead of having these global id-tracking
> >> structures, use the matrix together with some desc/chip_data local
> >> data, which should be sufficient.
> >
> > The "ids_enabled_bitmap", "dummy hwirqs" and private imsic_vectors
> > are required since the matrix allocator only manages allocation of
> > per-CPU IDs.
>
> The information in ids_enabled_bitmap is/could be inherent in
> imsic_local_priv.vectors (guess what x86 does... ;-)).
>
> Dummy hwirqs could be replaced with the virq.
>
> Hmm, seems like we're talking past each other, or at least I get the
> feeling I can't get my opinions out right. I'll try to do a quick PoC,
> to show you what I mean. That's probably easier than just talking about
> it. ...and maybe I'll come realizing I'm all wrong!

I suggest to wait for my v13 and try something on top of that
otherwise we might duplicate efforts.

>
> My reaction is -- you're doing a lot of householding with a lot of
> locks, and my worry is that we'll just end up with same issues/bloat
> that x86 once had (has? ;-)).
>
> >> Random thought: Do we need to explicitly disable (csr) the vector,
> >> when we're changing the affinity? What if we just leave it enabled,
> >> and only when mask/unmask is performed it's actually explicitly masked
> >> (writes to the csr)?
> >
> > We should not leave it enabled because some rough/buggy device
> > can inject spurious interrupts using MSI writes to unused enabled
> > interrupts.
>
> OK!
>
> >>
> >> Missing features (which can be added later):
> >> * Reservation mode/activate support (allocate many MSI, but only
> >>   request/activate a subset)
> >
> > I did not see any PCIe or platform device requiring this kind of
> > reservation. Any examples ?
>
> It's not a requirement. Some devices allocate a gazillion interrupts
> (NICs with many QoS queues, e.g.), but only activate a subset (via
> request_irq()). A system using these kind of devices might run out of
> interrupts.

I don't see how this is not possible currently.

>
> Problems you run into once you leave the embedded world, pretty much.
>
> >> * Handle managed interrupts
> >
> > Any examples of managed interrupts in the RISC-V world ?
>
> E.g. all nvme drives: nvme_setup_irqs(), and I'd assume contemporary
> netdev drivers would use it. Typically devices with per-cpu queues.

We have tested with NVMe devices, e1000e, VirtIO-net, etc and I did
not see any issue.

We can always add new features as separate incremental series as long
as there is clear use-cause backed by real-world devices.

>
> >> * There might be some irqd flags are missing, which mostly cpuhp care
> >>   about (e.g. irqd_*_single_target())...
> >
> > Okay, let me check and update.
>
> I haven't dug much into cpuhp, so I'm out on a limb here...
>
> >> Finally; Given that the APLIC requires a lot more patches, depending
> >> on how the review process moves on -- maybe the IMSIC side could go as
> >> a separate series?
> >>
> >
> > The most popular implementation choice across RISC-V platforms
> > will be IMSIC + APLIC so both drivers should go together. In fact,
> > we need both drivers for the QEMU virt machine as well because
> > UART interrupt (and other wired interrupts) on the QEMU virt
> > machine goes through APLIC.
>
> Thanks for clearing that out! Hmm, an IMSIC only QEMU would be awesome.
>
>
> Cheers,
> Bj?rn

Regards,
Anup


From neil.armstrong at linaro.org  Wed Feb  7 01:19:15 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 07 Feb 2024 10:19:15 +0100
Subject: (subset) [PATCH 0/5] Add display support for stm32mp135f-dk
 board
In-Reply-To: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
Message-ID: <170729755552.1647630.4818786052103823648.b4-ty@linaro.org>

Hi,

On Mon, 05 Feb 2024 10:06:50 +0100, Raphael Gallais-Pou wrote:
> This serie aims to enable display support for the stm32mp135f-dk board
> 
> Those are only patches of the device-tree since the driver support has
> already been added [1].
> 
> It respectivelly:
> 	- adds support for the display controller on stm32mp135
> 	- adds pinctrl for the display controller
> 	- enables panel, backlight and display controller on
> 	  stm32mp135f-dk
> 
> [...]

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git (drm-misc-next)

[4/5] drm/panel: simple: fix flags on RK043FN48H
      https://cgit.freedesktop.org/drm/drm-misc/commit/?id=536090b695c429e9d672f72341a5b6fb147d389d

-- 
Neil



From neil.armstrong at linaro.org  Wed Feb  7 01:19:16 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 07 Feb 2024 10:19:16 +0100
Subject: [PATCH 5/5] drm/panel: simple: push blanking limit on
 RK32FN48H
In-Reply-To: <20240205-ltdc_mp13-v1-5-116d43ebba75@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-116d43ebba75@foss.st.com>
 <20240205-ltdc_mp13-v1-5-116d43ebba75@foss.st.com>
Message-ID: <170729755662.1647630.425379349649657352.b4-ty@linaro.org>

Hi,

On Mon, 05 Feb 2024 10:26:50 +0100, Raphael Gallais-Pou wrote:
> Push horizontal front porch and vertical back porch blanking limit.
> This allows to get a 60 fps sharp.
> 
> 

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git (drm-misc-next)

[5/5] drm/panel: simple: push blanking limit on RK32FN48H
      https://cgit.freedesktop.org/drm/drm-misc/commit/?id=c9424076d7642bf6e214eccf34904848c8b53515

-- 
Neil



From festevam at gmail.com  Wed Feb  7 01:22:19 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 7 Feb 2024 06:22:19 -0300
Subject: [PATCH] drm/bridge: imx8mp-hdmi-pvi: Fix build warnings
In-Reply-To: <20240207002305.618499-1-aford173@gmail.com>
References: <20240207002305.618499-1-aford173@gmail.com>
Message-ID: <CAOMZO5A1yiXiLOtR=H_4vJYAMGwjpqrErCzvSkmLoB_f6_rN_w@mail.gmail.com>

Hi Adam,

On Tue, Feb 6, 2024 at 9:23?PM Adam Ford <aford173 at gmail.com> wrote:
>
> Two separate build warnings were reported.  One from an
> uninitialized variable, and the other from returning 0
> instead of NULL from a pointer.
>
> Fixes: 059c53e877ca ("drm/bridge: imx: add driver for HDMI TX Parallel Video Interface")
> Reported-by: nathan at kernel.org

The Reported-by line format can be improved:

Reported-by: Nathan Chancellor <nathan at kernel.org>

Thanks


From neil.armstrong at linaro.org  Wed Feb  7 01:24:08 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 7 Feb 2024 10:24:08 +0100
Subject: [PATCH] drm/bridge: imx8mp-hdmi-pvi: Fix build warnings
In-Reply-To: <CAOMZO5A1yiXiLOtR=H_4vJYAMGwjpqrErCzvSkmLoB_f6_rN_w@mail.gmail.com>
References: <20240207002305.618499-1-aford173@gmail.com>
 <CAOMZO5A1yiXiLOtR=H_4vJYAMGwjpqrErCzvSkmLoB_f6_rN_w@mail.gmail.com>
Message-ID: <7b71ab7f-7ea5-4144-a7c5-d0b66ab13476@linaro.org>

On 07/02/2024 10:22, Fabio Estevam wrote:
> Hi Adam,
> 
> On Tue, Feb 6, 2024 at 9:23?PM Adam Ford <aford173 at gmail.com> wrote:
>>
>> Two separate build warnings were reported.  One from an
>> uninitialized variable, and the other from returning 0
>> instead of NULL from a pointer.
>>
>> Fixes: 059c53e877ca ("drm/bridge: imx: add driver for HDMI TX Parallel Video Interface")
>> Reported-by: nathan at kernel.org
> 
> The Reported-by line format can be improved:
> 
> Reported-by: Nathan Chancellor <nathan at kernel.org>
> 
> Thanks

Fixed while applying,

Thanks,
Neil


From neil.armstrong at linaro.org  Wed Feb  7 01:26:07 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 07 Feb 2024 10:26:07 +0100
Subject: [PATCH] drm/bridge: imx8mp-hdmi-pvi: Fix build warnings
In-Reply-To: <20240207002305.618499-1-aford173@gmail.com>
References: <20240207002305.618499-1-aford173@gmail.com>
Message-ID: <170729796773.1668186.17562131345712345176.b4-ty@linaro.org>

Hi,

On Tue, 06 Feb 2024 18:23:04 -0600, Adam Ford wrote:
> Two separate build warnings were reported.  One from an
> uninitialized variable, and the other from returning 0
> instead of NULL from a pointer.
> 
> 

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git (drm-misc-next)

[1/1] drm/bridge: imx8mp-hdmi-pvi: Fix build warnings
      https://cgit.freedesktop.org/drm/drm-misc/commit/?id=c4ae9fd0de44832cb01d36af14bfc7783472e631

-- 
Neil



From bjorn at kernel.org  Wed Feb  7 01:37:00 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Wed, 07 Feb 2024 10:37:00 +0100
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <CAK9=C2XJYTfY4nXWtjK9OP1iXLDXBVF-=mN1SmJDmJ_dO5CohA@mail.gmail.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <87h6ily53k.fsf@all.your.base.are.belong.to.us>
 <CAAhSdy2PPjS6++Edh8NkgiBmcovTUjS5oXE2eR5ZwPfAfVA0ng@mail.gmail.com>
 <874jekag3w.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2XJYTfY4nXWtjK9OP1iXLDXBVF-=mN1SmJDmJ_dO5CohA@mail.gmail.com>
Message-ID: <87plx8y5s3.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

>> Nope. Same mechanics on x86 -- the cleanup has to be done one the
>> originating core. What I asked was "what about using a timer instead of
>> an IPI". I think this was up in the last rev as well?
>>
>> Check out commit bdc1dad299bb ("x86/vector: Replace
>> IRQ_MOVE_CLEANUP_VECTOR with a timer callback") Specifically, the
>> comment about lost interrupts, and the rational for keeping the original
>> target active until there's a new interrupt on the new cpu.
>
> Trying timer interrupt is still TBD on my side because with v12
> my goal was to implement per-device MSI domains. Let me
> explore timer interrupts for v13.

OK!

>> >> I wonder if this clean up is less intrusive, and you just need to
>> >> perform what's in the per-list instead of dealing with the
>> >> ids_enabled_bitmap? Maybe we can even remove that bitmap as well. The
>> >> chip_data/desc has that information. This would mean that
>> >> imsic_local_priv() would only have the local vectors (chip_data), and
>> >> a cleanup list/timer.
>> >>
>> >> My general comment is that instead of having these global id-tracking
>> >> structures, use the matrix together with some desc/chip_data local
>> >> data, which should be sufficient.
>> >
>> > The "ids_enabled_bitmap", "dummy hwirqs" and private imsic_vectors
>> > are required since the matrix allocator only manages allocation of
>> > per-CPU IDs.
>>
>> The information in ids_enabled_bitmap is/could be inherent in
>> imsic_local_priv.vectors (guess what x86 does... ;-)).
>>
>> Dummy hwirqs could be replaced with the virq.
>>
>> Hmm, seems like we're talking past each other, or at least I get the
>> feeling I can't get my opinions out right. I'll try to do a quick PoC,
>> to show you what I mean. That's probably easier than just talking about
>> it. ...and maybe I'll come realizing I'm all wrong!
>
> I suggest to wait for my v13 and try something on top of that
> otherwise we might duplicate efforts.

OK!

>> > I did not see any PCIe or platform device requiring this kind of
>> > reservation. Any examples ?
>>
>> It's not a requirement. Some devices allocate a gazillion interrupts
>> (NICs with many QoS queues, e.g.), but only activate a subset (via
>> request_irq()). A system using these kind of devices might run out of
>> interrupts.
>
> I don't see how this is not possible currently.

Again, this is something we can improve on later. But, this
implementation activates the interrupt at allocation time, no?

>> Problems you run into once you leave the embedded world, pretty much.
>>
>> >> * Handle managed interrupts
>> >
>> > Any examples of managed interrupts in the RISC-V world ?
>>
>> E.g. all nvme drives: nvme_setup_irqs(), and I'd assume contemporary
>> netdev drivers would use it. Typically devices with per-cpu queues.
>
> We have tested with NVMe devices, e1000e, VirtIO-net, etc and I did
> not see any issue.
>
> We can always add new features as separate incremental series as long
> as there is clear use-cause backed by real-world devices.

Agreed. Let's not feature creep.


Bj?rn


From u-kumar1 at ti.com  Wed Feb  7 01:37:55 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Wed, 7 Feb 2024 15:07:55 +0530
Subject: [PATCH] arm64: dts: ti: k3-am68-sk-som: Add support for OSPI
 flash
In-Reply-To: <20240206092334.30307-1-sinthu.raja@ti.com>
References: <20240206092334.30307-1-sinthu.raja@ti.com>
Message-ID: <8edafc4f-c4b9-4cf6-9a11-178492404170@ti.com>


On 2/6/2024 2:53 PM, Sinthu Raja wrote:
> From: Sinthu Raja <sinthu.raja at ti.com>
>
> AM68 SK has an OSPI NOR flash on its SOM connected to OSPI0 instance.
> Enable support for the same. Also, describe the OSPI flash partition
> information through the device tree, according to the offsets in the
> bootloader.
>
> Signed-off-by: Sinthu Raja <sinthu.raja at ti.com>
> ---
>   arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi | 79 ++++++++++++++++++++++
>   1 file changed, 79 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
> index 20861a0a46b0..84011d5e1b3b 100644
> --- a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
> @@ -130,6 +130,25 @@ rtos_ipc_memory_region: ipc-memories at a8000000 {
>   	};
>   };
>   
> +&wkup_pmx0 {
> +	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default {
> +		pinctrl-single,pins = <
> +			J721S2_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (D19) MCU_OSPI0_CLK */
> +			J721S2_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F15) MCU_OSPI0_CSn0 */
> +			J721S2_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (C19) MCU_OSPI0_D0 */
> +			J721S2_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (F16) MCU_OSPI0_D1 */
> +			J721S2_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (G15) MCU_OSPI0_D2 */
> +			J721S2_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (F18) MCU_OSPI0_D3 */
> +			J721S2_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (E19) MCU_OSPI0_D4 */
> +			J721S2_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (G19) MCU_OSPI0_D5 */
> +			J721S2_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (F19) MCU_OSPI0_D6 */
> +			J721S2_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (F20) MCU_OSPI0_D7 */
> +			J721S2_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (E18) MCU_OSPI0_DQS */
> +			J721S2_WKUP_IOPAD(0x004, PIN_INPUT, 0) /* (E20) MCU_OSPI0_LBCLKO */


E20 is seems to be not connected? . Refer page-11 of SOM schematic 
(PROC131 001 AM68 SK, rev E2)

Can we think of to remove pin, which is not connected .


> +		>;
> +	};
> +};
> +
>   &wkup_pmx2 {
>   	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
>   		pinctrl-single,pins = <
> @@ -152,6 +171,66 @@ eeprom at 51 {
>   	};
>   };
>   
> +&ospi0 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
> +
> +	flash at 0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0x0>;
> +		spi-tx-bus-width = <8>;
> +		spi-rx-bus-width = <8>;
> +		spi-max-frequency = <25000000>;
> +		cdns,tshsl-ns = <60>;
> +		cdns,tsd2d-ns = <60>;
> +		cdns,tchsh-ns = <60>;
> +		cdns,tslch-ns = <60>;
> +		cdns,read-delay = <4>;
> +
> +		partitions {
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			partition at 0 {
> +				label = "ospi.tiboot3";
> +				reg = <0x0 0x80000>;
> +			};
> +
> +			partition at 80000 {
> +				label = "ospi.tispl";
> +				reg = <0x80000 0x200000>;
> +			};
> +
> +			partition at 280000 {
> +				label = "ospi.u-boot";
> +				reg = <0x280000 0x400000>;
> +			};
> +
> +			partition at 680000 {
> +				label = "ospi.env";
> +				reg = <0x680000 0x40000>;
> +			};
> +
> +			partition at 6c0000 {
> +				label = "ospi.env.backup";
> +				reg = <0x6c0000 0x40000>;
> +			};
> +
> +			partition at 800000 {
> +				label = "ospi.rootfs";
> +				reg = <0x800000 0x37c0000>;
> +			};
> +
> +			partition at 3fc0000 {
> +				label = "ospi.phypattern";
> +				reg = <0x3fc0000 0x40000>;
> +			};
> +		};
> +	};
> +};
> +
>   &mailbox0_cluster0 {
>   	status = "okay";
>   	interrupts = <436>;


From dharma.b at microchip.com  Wed Feb  7 01:41:44 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Wed, 7 Feb 2024 15:11:44 +0530
Subject: [PATCH] ASoC: dt-bindings: atmel,asoc-wm8904: Convert to json-schema
Message-ID: <20240207094144.195397-1-dharma.b@microchip.com>

Convert atmel,asoc-wm8904 devicetree binding to json-schema.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
 .../bindings/sound/atmel,asoc-wm8904.yaml     | 84 +++++++++++++++++++
 .../bindings/sound/atmel-wm8904.txt           | 55 ------------
 2 files changed, 84 insertions(+), 55 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/atmel,asoc-wm8904.yaml
 delete mode 100644 Documentation/devicetree/bindings/sound/atmel-wm8904.txt

diff --git a/Documentation/devicetree/bindings/sound/atmel,asoc-wm8904.yaml b/Documentation/devicetree/bindings/sound/atmel,asoc-wm8904.yaml
new file mode 100644
index 000000000000..89a67f8e33b6
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel,asoc-wm8904.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/atmel,asoc-wm8904.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel wm8904 audio codec complex
+
+maintainers:
+  - Dharma Balasubiramani <dharma.b at microchip.com>
+
+description:
+  The ASoC audio complex configuration for Atmel with WM8904 audio codec.
+
+properties:
+  compatible:
+    const: atmel,asoc-wm8904
+
+  atmel,model:
+    $ref: /schemas/types.yaml#/definitions/string
+    description: The user-visible name of this sound complex.
+
+  atmel,ssc-controller:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of the SSC controller.
+
+  atmel,audio-codec:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of the WM8731 audio codec.
+
+  atmel,audio-routing:
+    description:
+      A list of the connections between audio components. Each entry is a pair
+      of strings, the first being the connection's sink, the second being the
+      connection's source.
+    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+    items:
+      enum:
+        # Board Connectors
+        - Headphone Jack
+        - Line In Jack
+        - Mic
+        # WM8904 CODEC Pins
+        - IN1L
+        - IN1R
+        - IN2L
+        - IN2R
+        - IN3L
+        - IN3R
+        - HPOUTL
+        - HPOUTR
+        - LINEOUTL
+        - LINEOUTR
+        - MICBIAS
+
+required:
+  - compatible
+  - atmel,model
+  - atmel,audio-routing
+  - atmel,ssc-controller
+  - atmel,audio-codec
+
+additionalProperties: false
+
+examples:
+  - |
+    sound {
+        compatible = "atmel,asoc-wm8904";
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_pck0_as_mck>;
+
+        atmel,model = "wm8904 @ AT91SAM9N12EK";
+
+        atmel,audio-routing =
+                "Headphone Jack", "HPOUTL",
+                "Headphone Jack", "HPOUTR",
+                "IN2L", "Line In Jack",
+                "IN2R", "Line In Jack",
+                "Mic", "MICBIAS",
+                "IN1L", "Mic";
+
+        atmel,ssc-controller = <&ssc0>;
+        atmel,audio-codec = <&wm8904>;
+    };
diff --git a/Documentation/devicetree/bindings/sound/atmel-wm8904.txt b/Documentation/devicetree/bindings/sound/atmel-wm8904.txt
deleted file mode 100644
index 8bbe50c884b6..000000000000
--- a/Documentation/devicetree/bindings/sound/atmel-wm8904.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-Atmel ASoC driver with wm8904 audio codec complex
-
-Required properties:
-  - compatible: "atmel,asoc-wm8904"
-  - atmel,model: The user-visible name of this sound complex.
-  - atmel,audio-routing: A list of the connections between audio components.
-    Each entry is a pair of strings, the first being the connection's sink,
-    the second being the connection's source. Valid names for sources and
-    sinks are the WM8904's pins, and the jacks on the board:
-
-    WM8904 pins:
-
-    * IN1L
-    * IN1R
-    * IN2L
-    * IN2R
-    * IN3L
-    * IN3R
-    * HPOUTL
-    * HPOUTR
-    * LINEOUTL
-    * LINEOUTR
-    * MICBIAS
-
-    Board connectors:
-
-    * Headphone Jack
-    * Line In Jack
-    * Mic
-
-  - atmel,ssc-controller: The phandle of the SSC controller
-  - atmel,audio-codec: The phandle of the WM8904 audio codec
-
-Optional properties:
-  - pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt
-
-Example:
-sound {
-	compatible = "atmel,asoc-wm8904";
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_pck0_as_mck>;
-
-	atmel,model = "wm8904 @ AT91SAM9N12EK";
-
-	atmel,audio-routing =
-		"Headphone Jack", "HPOUTL",
-		"Headphone Jack", "HPOUTR",
-		"IN2L", "Line In Jack",
-		"IN2R", "Line In Jack",
-		"Mic", "MICBIAS",
-		"IN1L", "Mic";
-
-	atmel,ssc-controller = <&ssc0>;
-	atmel,audio-codec = <&wm8904>;
-};
-- 
2.25.1



From bjorn at kernel.org  Wed Feb  7 01:43:08 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Wed, 07 Feb 2024 10:43:08 +0100
Subject: [PATCH v12 18/25] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <20240127161753.114685-19-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-19-apatel@ventanamicro.com>
Message-ID: <87il30y5hv.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

> The RISC-V advanced interrupt architecture (AIA) specification
> defines a new MSI controller called incoming message signalled
> interrupt controller (IMSIC) which manages MSI on per-HART (or
> per-CPU) basis. It also supports IPIs as software injected MSIs.
> (For more details refer https://github.com/riscv/riscv-aia)
>
> Let us add an early irqchip driver for RISC-V IMSIC which sets
> up the IMSIC state and provide IPIs.
>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> ---
>  drivers/irqchip/Kconfig                 |   7 +
>  drivers/irqchip/Makefile                |   1 +
>  drivers/irqchip/irq-riscv-imsic-early.c | 241 +++++++
>  drivers/irqchip/irq-riscv-imsic-state.c | 887 ++++++++++++++++++++++++
>  drivers/irqchip/irq-riscv-imsic-state.h | 105 +++
>  include/linux/irqchip/riscv-imsic.h     |  87 +++
>  6 files changed, 1328 insertions(+)
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-early.c
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-state.c
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-state.h
>  create mode 100644 include/linux/irqchip/riscv-imsic.h
>
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index f7149d0f3d45..85f86e31c996 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -546,6 +546,13 @@ config SIFIVE_PLIC
>  	select IRQ_DOMAIN_HIERARCHY
>  	select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
>  
> +config RISCV_IMSIC
> +	bool
> +	depends on RISCV
> +	select IRQ_DOMAIN_HIERARCHY
> +	select GENERIC_IRQ_MATRIX_ALLOCATOR
> +	select GENERIC_MSI_IRQ
> +
>  config EXYNOS_IRQ_COMBINER
>  	bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
>  	depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index ffd945fe71aa..d714724387ce 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
>  obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
>  obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
>  obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
> +obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o
>  obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
>  obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
>  obj-$(CONFIG_IMX_INTMUX)		+= irq-imx-intmux.o
> diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
> new file mode 100644
> index 000000000000..3557e32a713c
> --- /dev/null
> +++ b/drivers/irqchip/irq-riscv-imsic-early.c
> @@ -0,0 +1,241 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> + * Copyright (C) 2022 Ventana Micro Systems Inc.
> + */
> +
> +#define pr_fmt(fmt) "riscv-imsic: " fmt
> +#include <linux/cpu.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/module.h>
> +#include <linux/spinlock.h>
> +#include <linux/smp.h>
> +
> +#include "irq-riscv-imsic-state.h"
> +
> +static int imsic_parent_irq;
> +
> +#ifdef CONFIG_SMP
> +static irqreturn_t imsic_local_sync_handler(int irq, void *data)
> +{
> +	imsic_local_sync();
> +	return IRQ_HANDLED;
> +}
> +
> +static void imsic_ipi_send(unsigned int cpu)
> +{
> +	struct imsic_local_config *local =
> +				per_cpu_ptr(imsic->global.local, cpu);
> +
> +	writel_relaxed(IMSIC_IPI_ID, local->msi_va);
> +}
> +
> +static void imsic_ipi_starting_cpu(void)
> +{
> +	/* Enable IPIs for current CPU. */
> +	__imsic_id_set_enable(IMSIC_IPI_ID);
> +
> +	/* Enable virtual IPI used for IMSIC ID synchronization */
> +	enable_percpu_irq(imsic->ipi_virq, 0);
> +}
> +
> +static void imsic_ipi_dying_cpu(void)
> +{
> +	/*
> +	 * Disable virtual IPI used for IMSIC ID synchronization so
> +	 * that we don't receive ID synchronization requests.
> +	 */
> +	disable_percpu_irq(imsic->ipi_virq);
> +}
> +
> +static int __init imsic_ipi_domain_init(void)
> +{
> +	int virq;
> +
> +	/* Create IMSIC IPI multiplexing */
> +	virq = ipi_mux_create(IMSIC_NR_IPI, imsic_ipi_send);
> +	if (virq <= 0)
> +		return (virq < 0) ? virq : -ENOMEM;
> +	imsic->ipi_virq = virq;
> +
> +	/* First vIRQ is used for IMSIC ID synchronization */
> +	virq = request_percpu_irq(imsic->ipi_virq, imsic_local_sync_handler,
> +				  "riscv-imsic-lsync", imsic->global.local);

There's a lot of boilerplate for the local-sync IPI. Any reason not to
use what the kernel provides out-of-the-box:

  int smp_call_function_single(int cpuid, smp_call_func_t func, void *info,
			     int wait);

e.g.

  smp_call_function_single(target_cpu, imsic_local_sync_with_new_signature, NULL, 0);


Bj?rn


From hejunhao3 at huawei.com  Wed Feb  7 01:42:45 2024
From: hejunhao3 at huawei.com (Junhao He)
Date: Wed, 7 Feb 2024 17:42:45 +0800
Subject: [PATCH] drivers/perf: hisi: Enable HiSilicon Erratum 162700402 quirk for UC PMU
Message-ID: <20240207094245.34195-1-hejunhao3@huawei.com>

HiSilicon UC PMU v2 suffers the erratum 162700402 that the PMU counter
cannot be set due to the lack of clock under power saving mode. This will
lead to error or inaccurate counts. The clock can be enabled by the PMU
global enabling control.

This patch tries to fix this by set the UC PMU enable before set event
period to turn on the clock, and then restore the UC PMU configuration.
The counter register can hold its value without a clock.

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
---
 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c | 40 ++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
index 636fb79647c8..8e7a9e1f419a 100644
--- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
@@ -287,10 +287,48 @@ static u64 hisi_uc_pmu_read_counter(struct hisi_pmu *uc_pmu,
 	return readq(uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
 }
 
-static void hisi_uc_pmu_write_counter(struct hisi_pmu *uc_pmu,
+static bool hisi_uc_pmu_get_glb_en_state(struct hisi_pmu *uc_pmu)
+{
+	u32 val;
+
+	val = readl(uc_pmu->base + HISI_UC_EVENT_CTRL_REG);
+	return !!FIELD_GET(HISI_UC_EVENT_GLB_EN, val);
+}
+
+static void hisi_uc_pmu_write_counter_quirk_hip09(struct hisi_pmu *uc_pmu,
 				      struct hw_perf_event *hwc, u64 val)
 {
+	bool enable = hisi_uc_pmu_get_glb_en_state(uc_pmu);
+
+	/* Set the UC PMU enable to turn on the clock. */
+	if (!enable)
+		hisi_uc_pmu_start_counters(uc_pmu);
+
 	writeq(val, uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
+
+	/*
+	 * The counter register can hold its value without a clock. We need
+	 * restore the UC PMU configuration. The irq handler will also call
+	 * the function to set period. At this time, PMU is still enabled and
+	 * we cannot directly disable the PMU.
+	 */
+	if (!enable)
+		hisi_uc_pmu_stop_counters(uc_pmu);
+}
+
+static void hisi_uc_pmu_write_counter(struct hisi_pmu *uc_pmu,
+				      struct hw_perf_event *hwc, u64 val)
+{
+	/*
+	 * HiSilicon UC PMU v2 suffers the erratum 162700402 that the PMU
+	 * counter cannot be set due to the lack of clock under power saving
+	 * mode. This will lead to error or inaccurate counts. The clock can
+	 * be enabled by the PMU global enabling control.
+	 */
+	if (uc_pmu->identifier == HISI_PMU_V2)
+		hisi_uc_pmu_write_counter_quirk_hip09(uc_pmu, hwc, val);
+	else
+		writeq(val, uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
 }
 
 static void hisi_uc_pmu_enable_counter_int(struct hisi_pmu *uc_pmu,
-- 
2.33.0



From dmitry.baryshkov at linaro.org  Wed Feb  7 01:44:19 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 7 Feb 2024 11:44:19 +0200
Subject: [PATCH RFC 1/2] spmi: Add support for multi-master
In-Reply-To: <ZcNIddeG6VHxBEOQ@linaro.org>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
 <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>
 <CAA8EJpqsJmv36=o1aTjVH6eMHXMg8BHNpiDvs+Q8YB23ezVGtQ@mail.gmail.com>
 <ZcMvFtAwQQjAZhk6@linaro.org> <CAA8EJprqWLX7_yWZzKp3FAKFGkSkk041f9hj1uXuRBrbH5APyQ@mail.gmail.com>
 <ZcNIddeG6VHxBEOQ@linaro.org>
Message-ID: <CAA8EJprgkM9fO967Swrzjf4PYuVoSpmXLU-zadN4eKhjez30Gg@mail.gmail.com>

On Wed, 7 Feb 2024 at 11:08, Abel Vesa <abel.vesa at linaro.org> wrote:
>
> On 24-02-07 09:23:09, Dmitry Baryshkov wrote:
> > On Wed, 7 Feb 2024 at 09:19, Abel Vesa <abel.vesa at linaro.org> wrote:
> > >
> > > On 24-02-07 01:55:39, Dmitry Baryshkov wrote:
> > > > On Wed, 7 Feb 2024 at 01:34, Abel Vesa <abel.vesa at linaro.org> wrote:
> > > > >
> > > > > Some newer SPMI controllers support multiple bus masters.
> > > > > Such a master can control multiple slave devices. The generic
> > > > > framework needs to be able to pass on the master id to the
> > > > > controller-specific driver. So do that. The framework will
> > > > > check if the devicetree child nodes are actually bus masters
> > > > > and will register the devices for each master. The legacy
> > > > > approach will still be supported for backwards compatibility.
> > > >
> > > > Please remind me, are those two actual bus musters driving a single
> > > > bus in parallel or two SPMI buses being handled by a single device? In
> > > > the latter case this implementation is incorrect. There should be
> > > > multiple spmi_controller instances, one for each bus. Allocate them in
> > > > a loop and set ctrl->dev.of_node after allocating.
> > >
> > > It's two SPMI buses (two sets of wires) handled by the same controller,
> > > HW-wise.
> > >
> > > If we register two spmi controllers with the kernel framework, it will
> > > be HW inaccurate, because there is just one controller which has
> > > multiple masters.
> >
> > struct spmi_controller is a controller for a single bus. Inside your
> > device you have two SPMI buses, each can be controlled by its own
> > struct spmi_controller. Just like devices that control multiple I2C,
> > SPI or USB busses register a separate instance of the bus controller.
>
> Well, this is what this patchset is trying to do in the generic part.
> The SPMI controller supports multiple buses (HW-wise) and therefore SW
> implementation shouldn't be tied to single bus requirement.

SPMI controller doesn't support multiple buses. You have a device
which has two SPMI controllers inside. Just like all multi-bus
controllers.

>
> >
> > >
> > > I'm not saying it might not work. But, to me, it looks more like a hack.
> > >
> > > Basically, we would be mapping HW bus masters to kernel controllers.
> >
> > Buses, not just masters.
> >
> > >
> > > >
> > > > >
> > > > > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > > > > ---
> > > > >  drivers/spmi/spmi-mtk-pmif.c |  6 ++--
> > > > >  drivers/spmi/spmi-pmic-arb.c | 10 +++---
> > > > >  drivers/spmi/spmi.c          | 76 ++++++++++++++++++++++++++++++--------------
> > > > >  include/linux/spmi.h         | 10 +++---
> > > > >  4 files changed, 67 insertions(+), 35 deletions(-)
> > > >
> > > > --
> > > > With best wishes
> > > > Dmitry
> >
> >
> >
> > --
> > With best wishes
> > Dmitry



-- 
With best wishes
Dmitry


From oliver.upton at linux.dev  Wed Feb  7 01:45:59 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 7 Feb 2024 09:45:59 +0000
Subject: [PATCH] arm64: errata: Minimize tlb flush due to vttbr writes on
 AmpereOne
In-Reply-To: <20240207090458.463021-1-gankulkarni@os.amperecomputing.com>
References: <20240207090458.463021-1-gankulkarni@os.amperecomputing.com>
Message-ID: <ZcNRV-lMiNgE0_jv@linux.dev>

On Wed, Feb 07, 2024 at 01:04:58AM -0800, Ganapatrao Kulkarni wrote:
> AmpereOne implementation is doing tlb flush when ever there is
> a write to vttbr_el2. As per KVM implementation, vttbr_el2 is updated
> with VM's S2-MMU while return to VM. This is not necessary when there
> is no VM context switch and a just return to same Guest.
> 
> Adding a check to avoid the vttbr_el2 write if the same value
> already exist to prevent needless tlb flush.

Sorry, zero interest in taking what is really a uarch optimization.
The errata framework exists to allow the kernel achieve *correctness*
on a variety of hardware and is not a collection of party tricks for
optimizing any given implementation.

Think of the precedent this would establish. What would stop
implementers from, say, changing out our memcpy implementation into a
a hundred different uarch-specific routines. That isn't maintainable,
nor is it even testable as most folks don't have access to your
hardware.

Ignoring all of that -- I question the necessity of these patches
altogether. KVM writes to VTTBR at the time of vcpu load as of commit
934bf871f011 ("KVM: arm64: Load the stage-2 MMU context in
kvm_vcpu_load_vhe()"), which should drastically reduce the overhead of
this hardware fix.

--
Thanks,
Oliver


From mark.rutland at arm.com  Wed Feb  7 01:49:23 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 7 Feb 2024 09:49:23 +0000
Subject: [RFC PATCH] KVM: arm64: Override Microsoft Azure Cobalt 100 MIDR
 value with ARM Neoverse N2
In-Reply-To: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
References: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
Message-ID: <ZcNSI089xqia6lho@FVFF77S0Q05N.cambridge.arm.com>

On Tue, Feb 06, 2024 at 07:58:16PM +0000, Easwar Hariharan wrote:
> Several workload optimizations and errata depend on validating that the
> optimization or errata are applicable to the particular CPU by checking
> the MIDR_EL1 system register value. With the Microsoft implementer ID
> for Azure Cobalt 100, the value doesn't match and ~20-25% performance
> regression is seen in these workloads. Override the Azure Cobalt 100
> value and replace it with the default ARM Neoverse N2 value that Azure
> Cobalt 100 is based on.

NAK to rewriting the MIDR in the kernel; we do not lie to userspace about the
MIDR, and this is not a can of worms we're going to open.

If you desire some microarchitectural performance optimizations in particular
projects, please submit patches to those projects to understand your MIDR
value.

Further, if Azure Cobalt 100 is based on ARM Neoverse N2, you presumably suffer
from the same errata; can you comment on that at all? e.g. are there any
changes in this part that *might* lead to differences in errata and/or
workarounds? How do the MIDR_EL1.{Variant,Revision} values compare to that of
Neoverse N2?

Mark.

> Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>
> ---
>  arch/arm64/include/asm/cputype.h   | 3 ++-
>  arch/arm64/include/asm/el2_setup.h | 5 +++++
>  arch/arm64/kvm/sys_regs.c          | 9 ++++++++-
>  3 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 7c7493cb571f..0450c6c32377 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -262,7 +262,8 @@ is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
>   */
>  static inline u32 __attribute_const__ read_cpuid_id(void)
>  {
> -	return read_cpuid(MIDR_EL1);
> +	return (read_cpuid(MIDR_EL1) == 0x6D0FD490 ? 0x410FD490 :
> +			read_cpuid(MIDR_EL1));
>  }
>  
>  static inline u64 __attribute_const__ read_cpuid_mpidr(void)
> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> index b7afaa026842..502a14e54a31 100644
> --- a/arch/arm64/include/asm/el2_setup.h
> +++ b/arch/arm64/include/asm/el2_setup.h
> @@ -138,6 +138,11 @@
>  .macro __init_el2_nvhe_idregs
>  	mrs	x0, midr_el1
>  	mrs	x1, mpidr_el1
> +	ldr	x2, =0x6D0FD490
> +	cmp	x0, x2
> +	bne	.Loverride_cobalt100_\@
> +	ldr	x0, =0x410FD490
> +.Loverride_cobalt100_\@:
>  	msr	vpidr_el2, x0
>  	msr	vmpidr_el2, x1
>  .endm
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 30253bd19917..8ea9c7fdabdb 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -3574,7 +3574,14 @@ id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id,
>  		return ((struct sys_reg_desc *)r)->val;			\
>  	}
>  
> -FUNCTION_INVARIANT(midr_el1)
> +static u64 get_midr_el1(struct kvm_vcpu *v, const struct sys_reg_desc *r)
> +{
> +	((struct sys_reg_desc *)r)->val = read_sysreg(midr_el1);
> +	if (((struct sys_reg_desc *)r)->val == 0x6D0FD490)
> +		((struct sys_reg_desc *)r)->val == 0x410FD490;
> +	return ((struct sys_reg_desc *)r)->val;
> +}
> +
>  FUNCTION_INVARIANT(revidr_el1)
>  FUNCTION_INVARIANT(aidr_el1)
>  
> -- 
> 2.34.1
> 
> 


From maz at kernel.org  Wed Feb  7 01:50:09 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 07 Feb 2024 09:50:09 +0000
Subject: [RFC PATCH] KVM: arm64: Override Microsoft Azure Cobalt 100 MIDR value with ARM Neoverse N2
In-Reply-To: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
References: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
Message-ID: <86r0ho61ta.wl-maz@kernel.org>

On Tue, 06 Feb 2024 19:58:16 +0000,
Easwar Hariharan <eahariha at linux.microsoft.com> wrote:
> 
> Several workload optimizations and errata depend on validating that the
> optimization or errata are applicable to the particular CPU by checking
> the MIDR_EL1 system register value. With the Microsoft implementer ID
> for Azure Cobalt 100, the value doesn't match and ~20-25% performance
> regression is seen in these workloads. Override the Azure Cobalt 100
> value and replace it with the default ARM Neoverse N2 value that Azure
> Cobalt 100 is based on.

Since you don't disclose *why* this particular value should have any
impact on the behaviour of the kernel, the answer should be "Thanks,
but no, thanks".

Whatever the reason is for doing so, you should make it plain what you
are working around. Blindly overriding ID registers is not an option,
and you should simply add your MIDR value to whatever errata list that
actually matches your implementation.

> 
> Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>
> ---
>  arch/arm64/include/asm/cputype.h   | 3 ++-
>  arch/arm64/include/asm/el2_setup.h | 5 +++++
>  arch/arm64/kvm/sys_regs.c          | 9 ++++++++-
>  3 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 7c7493cb571f..0450c6c32377 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -262,7 +262,8 @@ is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
>   */
>  static inline u32 __attribute_const__ read_cpuid_id(void)
>  {
> -	return read_cpuid(MIDR_EL1);
> +	return (read_cpuid(MIDR_EL1) == 0x6D0FD490 ? 0x410FD490 :
> +			read_cpuid(MIDR_EL1));
>  }
>  
>  static inline u64 __attribute_const__ read_cpuid_mpidr(void)
> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> index b7afaa026842..502a14e54a31 100644
> --- a/arch/arm64/include/asm/el2_setup.h
> +++ b/arch/arm64/include/asm/el2_setup.h
> @@ -138,6 +138,11 @@
>  .macro __init_el2_nvhe_idregs
>  	mrs	x0, midr_el1
>  	mrs	x1, mpidr_el1
> +	ldr	x2, =0x6D0FD490
> +	cmp	x0, x2
> +	bne	.Loverride_cobalt100_\@
> +	ldr	x0, =0x410FD490
> +.Loverride_cobalt100_\@:
>  	msr	vpidr_el2, x0
>  	msr	vmpidr_el2, x1
>  .endm
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 30253bd19917..8ea9c7fdabdb 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -3574,7 +3574,14 @@ id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id,
>  		return ((struct sys_reg_desc *)r)->val;			\
>  	}
>  
> -FUNCTION_INVARIANT(midr_el1)
> +static u64 get_midr_el1(struct kvm_vcpu *v, const struct sys_reg_desc *r)
> +{
> +	((struct sys_reg_desc *)r)->val = read_sysreg(midr_el1);
> +	if (((struct sys_reg_desc *)r)->val == 0x6D0FD490)
> +		((struct sys_reg_desc *)r)->val == 0x410FD490;

As pointed out to me by Joey, this line is really interesting, and
shows that you didn't really test this patch.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From kamlesh at ti.com  Wed Feb  7 01:53:36 2024
From: kamlesh at ti.com (Kamlesh Gurudasani)
Date: Wed, 7 Feb 2024 15:23:36 +0530
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240207091100.4001428-1-u-kumar1@ti.com>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
Message-ID: <87le7wy50f.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>

Udit Kumar <u-kumar1 at ti.com> writes:

> Most of clocks and their parents are defined in contiguous range,
> But in few cases, there is gap in clock numbers[0].
> Driver assumes clocks to be in contiguous range, and add their clock
> ids incrementally.
>
> New firmware started returning error while calling get_freq and is_on
> API for non-available clock ids.
>
> In this fix, driver checks and adds only valid clock ids.
>
> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
>
> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> Section Clocks for NAVSS0_CPTS_0 Device,
> clock id 12-15 not present.
>
> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
> ---
> Changelog
> Changes in v3
> - instead of get_freq, is_auto API is used to check validilty of clock
> - Address comments of v2, to have preindex increment
> Link to v2 https://lore.kernel.org/all/20240206104357.3803517-1-u-kumar1 at ti.com/
>
> Changes in v2
> - Updated commit message
> - Simplified logic for valid clock id
> link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/
>
>
> P.S
> Firmawre returns total num_parents count including non available ids.
> For above device id NAVSS0_CPTS_0, number of parents clocks are 16
> i.e from id 2 to 17. But out of these ids few are not valid.
> So driver adds only valid clock ids out ot total.
>
> Original logs
> https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
> Line 2630 for error
>
> Logs with fix v3
> https://gist.github.com/uditkumarti/94e3e28d62282fd708dbfe37435ce1d9#file-v3
> Line 2586
>
>
>  drivers/clk/keystone/sci-clk.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> index 35fe197dd303..31b7df05d7bb 100644
> --- a/drivers/clk/keystone/sci-clk.c
> +++ b/drivers/clk/keystone/sci-clk.c
> @@ -516,6 +516,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  	struct sci_clk *sci_clk, *prev;
>  	int num_clks = 0;
>  	int num_parents;
> +	bool state;
>  	int clk_id;
>  	const char * const clk_names[] = {
>  		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
> @@ -583,16 +584,23 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  					num_parents = 255;
>  				}
>  
> -				clk_id = args.args[1] + 1;
> +				clk_id = args.args[1];
>  
>  				while (num_parents--) {
> +					/* Check if this clock id is valid */
> +					ret = provider->ops->is_auto(provider->sci,
> +						sci_clk->dev_id, ++clk_id, &state);
> +
> +					if (ret)
> +						continue;
> +
>  					sci_clk = devm_kzalloc(dev,
>  							       sizeof(*sci_clk),
>  							       GFP_KERNEL);
>  					if (!sci_clk)
>  						return -ENOMEM;
>  					sci_clk->dev_id = args.args[0];
> -					sci_clk->clk_id = clk_id++;
> +					sci_clk->clk_id = clk_id;
>  					sci_clk->provider = provider;
>  					list_add_tail(&sci_clk->node, &clks);
>
Looks good to me.

Reviewed-by: Kamlesh Gurudasani <kamlesh at ti.com>

> -- 
> 2.34.1


From amergnat at baylibre.com  Wed Feb  7 01:55:07 2024
From: amergnat at baylibre.com (Alexandre Mergnat)
Date: Wed, 7 Feb 2024 10:55:07 +0100
Subject: [PATCH v4 1/9] drm/mediatek: dsi: Use GENMASK() for register mask
 definitions
In-Reply-To: <c1e2c380-21b5-47c1-b83b-f7f2b481df21@collabora.com>
References: <20240206120748.136610-1-angelogioacchino.delregno@collabora.com>
 <20240206120748.136610-2-angelogioacchino.delregno@collabora.com>
 <f91db779-ad94-4c18-9a06-1029da4edaab@baylibre.com>
 <c1e2c380-21b5-47c1-b83b-f7f2b481df21@collabora.com>
Message-ID: <843e34a5-f175-4bda-a2f1-2ea3b56b68f5@baylibre.com>



On 06/02/2024 16:53, AngeloGioacchino Del Regno wrote:
>>> ? #define DSI_PSCTRL??????? 0x1c
>>> -#define DSI_PS_WC??????????? 0x3fff
>>> -#define DSI_PS_SEL??????????? (3 << 16)
>>> +#define DSI_PS_WC??????????? GENMASK(14, 0)
>>> +#define DSI_PS_SEL??????????? GENMASK(19, 16)
>>
>> 0011 0000 0000 0000 0000 => GENMASK(17, 16)
> 
> Alexandre, the reason for that is in the commit description :-P
> 
> "While at it, also fix the DSI_PS_SEL mask to include all bits instead
> of just a subset of them."

Oh sorry...

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>

-- 
Regards,
Alexandre


From gregkh at linuxfoundation.org  Wed Feb  7 01:58:03 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 7 Feb 2024 09:58:03 +0000
Subject: [PATCH 1/4] spi: s3c64xx: explicitly include <linux/types.h>
In-Reply-To: <16a5e423-1111-49ff-ad6c-b0bb89a4879a@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
 <20240206085238.1208256-2-tudor.ambarus@linaro.org>
 <CAPLW+4=Xd+B=ZncqPgU4qaJ8zY8JJvJZApdUW_v0w6yr2cy9Sg@mail.gmail.com>
 <16a5e423-1111-49ff-ad6c-b0bb89a4879a@linaro.org>
Message-ID: <2024020741-repaint-nastiness-9f8d@gregkh>

On Wed, Feb 07, 2024 at 06:20:56AM +0000, Tudor Ambarus wrote:
> 
> 
> On 2/6/24 18:02, Sam Protsenko wrote:
> > On Tue, Feb 6, 2024 at 2:52?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
> >>
> >> The driver uses u32 and relies on an implicit inclusion of
> >> <linux/types.h>.
> >>
> >> It is good practice to directly include all headers used, it avoids
> >> implicit dependencies and spurious breakage if someone rearranges
> >> headers and causes the implicit include to vanish.
> >>
> >> Include the missing header.
> >>
> >> Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver")
> > 
> > Not sure if Fixes tag is needed here.
> 
> We have already talked about this. If a patch that causes the implicit
> include to vanish is backported to stable, it will reveal the missing
> header here and will result in backporting this patch as well.

So worry about this then, not now.

> So, as a
> good practice let's allow this patch to be queued to stable, it will
> avoid possible compilation errors.

"possible" does not mean "needed".

Please only tag stuff that you know is needed, if the stable developers
break things, they can fix it up when it happens.

Adding .h includes is not a fixes: thing unless it actually fixes
something in Linus's tree, otherwise it's an abuse of the tag.  Please
don't do that.

thanks,

greg k-h


From broonie at kernel.org  Wed Feb  7 02:04:56 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 7 Feb 2024 10:04:56 +0000
Subject: [RFC PATCH] arm64/sve,sme: Refine scalable regset sizes at boot
In-Reply-To: <ZcEaeLeEG8ve+Yp7@e133380.arm.com>
References: <ZcEaeLeEG8ve+Yp7@e133380.arm.com>
Message-ID: <ZcNVyMyiFB3Nndth@finisterre.sirena.org.uk>

On Mon, Feb 05, 2024 at 05:27:20PM +0000, Dave Martin wrote:

> index a5dc6f764195..5c2f91f84c31 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -1189,6 +1189,7 @@ void __init sve_setup(void)
>  		pr_warn("%s: unvirtualisable vector lengths present\n",
>  			info->name);
>  
> +	arch_ptrace_sve_init(sve_vq_from_vl(info->max_vl));
>  	sve_efi_setup();
>  }

This will only get run if the system actually supports SVE since the
first thing that sve_setup() does is to exit if the system does not
support SVE.  That means that the size limiting will only be done on
systems that have SVE, but since we unconditionally register all our
regsets if the system doesn't have SVE it will end up with a maximally
sized SVE regset registered which doesn't seem ideal.  As I mentioned in
the other thread we should probably just not be registering unsupported
regsets with the core, that would avoid the issue without a change to
this patch.

A similar issue applies for SME.
-------------- 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/20240207/2343667e/attachment-0001.sig>

From tudor.ambarus at linaro.org  Wed Feb  7 02:14:49 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed, 7 Feb 2024 10:14:49 +0000
Subject: [PATCH 1/4] spi: s3c64xx: explicitly include <linux/types.h>
In-Reply-To: <2024020741-repaint-nastiness-9f8d@gregkh>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
 <20240206085238.1208256-2-tudor.ambarus@linaro.org>
 <CAPLW+4=Xd+B=ZncqPgU4qaJ8zY8JJvJZApdUW_v0w6yr2cy9Sg@mail.gmail.com>
 <16a5e423-1111-49ff-ad6c-b0bb89a4879a@linaro.org>
 <2024020741-repaint-nastiness-9f8d@gregkh>
Message-ID: <894561a9-51b5-4e7d-a65d-5e8e6c32a3ff@linaro.org>



On 2/7/24 09:58, Greg Kroah-Hartman wrote:
> On Wed, Feb 07, 2024 at 06:20:56AM +0000, Tudor Ambarus wrote:
>>
>>
>> On 2/6/24 18:02, Sam Protsenko wrote:
>>> On Tue, Feb 6, 2024 at 2:52?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>>>>
>>>> The driver uses u32 and relies on an implicit inclusion of
>>>> <linux/types.h>.
>>>>
>>>> It is good practice to directly include all headers used, it avoids
>>>> implicit dependencies and spurious breakage if someone rearranges
>>>> headers and causes the implicit include to vanish.
>>>>
>>>> Include the missing header.
>>>>
>>>> Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver")
>>>
>>> Not sure if Fixes tag is needed here.
>>
>> We have already talked about this. If a patch that causes the implicit
>> include to vanish is backported to stable, it will reveal the missing
>> header here and will result in backporting this patch as well.
> 
> So worry about this then, not now.
> 
>> So, as a
>> good practice let's allow this patch to be queued to stable, it will
>> avoid possible compilation errors.
> 
> "possible" does not mean "needed".
> 
> Please only tag stuff that you know is needed, if the stable developers
> break things, they can fix it up when it happens.
> 
> Adding .h includes is not a fixes: thing unless it actually fixes
> something in Linus's tree, otherwise it's an abuse of the tag.  Please
> don't do that.
> 

Okay, thanks for the clarification.

Cheers,
ta


From vkoul at kernel.org  Wed Feb  7 02:16:52 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 7 Feb 2024 11:16:52 +0100
Subject: [PATCH v2 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>
References: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
 <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>
Message-ID: <ZcNYlFgT0rXiCGbo@matsya>

On 05-02-24, 13:24, Cristian Ciocaltea wrote:
> Add driver for the HDMI/eDP TX Combo PHY found on Rockchip RK3588 SoC.
> 
> The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
> and eDP links.  The maximum data rate is 12Gbps (FRL), while the minimum
> is 250Mbps (TMDS).
> 
> Only the TMDS link is currently supported.
> 
> Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
> Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---
>  drivers/phy/rockchip/Kconfig                      |    8 +
>  drivers/phy/rockchip/Makefile                     |    1 +
>  drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 1040 +++++++++++++++++++++
>  3 files changed, 1049 insertions(+)
> 
> diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
> index 94360fc96a6f..a34f67bb7e61 100644
> --- a/drivers/phy/rockchip/Kconfig
> +++ b/drivers/phy/rockchip/Kconfig
> @@ -83,6 +83,14 @@ config PHY_ROCKCHIP_PCIE
>  	help
>  	  Enable this to support the Rockchip PCIe PHY.
>  
> +config PHY_ROCKCHIP_SAMSUNG_HDPTX
> +	tristate "Rockchip Samsung HDMI/eDP Combo PHY driver"
> +	depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
> +	select GENERIC_PHY
> +	help
> +	  Enable this to support the Rockchip HDMI/eDP Combo PHY
> +	  with Samsung IP block.
> +
>  config PHY_ROCKCHIP_SNPS_PCIE3
>  	tristate "Rockchip Snps PCIe3 PHY Driver"
>  	depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
> diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
> index 7eab129230d1..3d911304e654 100644
> --- a/drivers/phy/rockchip/Makefile
> +++ b/drivers/phy/rockchip/Makefile
> @@ -8,6 +8,7 @@ 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_SAMSUNG_HDPTX)	+= phy-rockchip-samsung-hdptx.o
>  obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3)	+= phy-rockchip-snps-pcie3.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-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> new file mode 100644
> index 000000000000..744bbe8280a8
> --- /dev/null
> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
> @@ -0,0 +1,1040 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
> + * Copyright (c) 2024 Collabora Ltd.
> + *
> + * Author: Algea Cao <algea.cao at rock-chips.com>
> + * Author: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> + */
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/rational.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#define GRF_HDPTX_CON0			0x00
> +#define HDPTX_I_PLL_EN			BIT(7)
> +#define HDPTX_I_BIAS_EN			BIT(6)
> +#define HDPTX_I_BGR_EN			BIT(5)
> +#define GRF_HDPTX_STATUS		0x80
> +#define HDPTX_O_PLL_LOCK_DONE		BIT(3)
> +#define HDPTX_O_PHY_CLK_RDY		BIT(2)
> +#define HDPTX_O_PHY_RDY			BIT(1)
> +#define HDPTX_O_SB_RDY			BIT(0)
> +
> +#define HDTPX_REG(_n, _min, _max)				\
> +	(							\
> +		BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) +	\
> +		BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) +	\
> +		((0x##_n) * 4)					\
> +	)
> +
> +#define CMN_REG(n)			HDTPX_REG(n, 0000, 00A7)
> +#define SB_REG(n)			HDTPX_REG(n, 0100, 0129)
> +#define LNTOP_REG(n)			HDTPX_REG(n, 0200, 0229)
> +#define LANE_REG(n)			HDTPX_REG(n, 0300, 062D)
> +
> +/* CMN_REG(0008) */
> +#define LCPLL_EN_MASK			BIT(6)
> +#define LCPLL_LCVCO_MODE_EN_MASK	BIT(4)
> +/* CMN_REG(001E) */
> +#define LCPLL_PI_EN_MASK		BIT(5)
> +#define LCPLL_100M_CLK_EN_MASK		BIT(0)
> +/* CMN_REG(0025) */
> +#define LCPLL_PMS_IQDIV_RSTN		BIT(4)
> +/* CMN_REG(0028) */
> +#define LCPLL_SDC_FRAC_EN		BIT(2)
> +#define LCPLL_SDC_FRAC_RSTN		BIT(0)
> +/* CMN_REG(002D) */
> +#define LCPLL_SDC_N_MASK		GENMASK(3, 1)
> +/* CMN_REG(002E) */
> +#define LCPLL_SDC_NUMBERATOR_MASK	GENMASK(5, 0)
> +/* CMN_REG(002F) */
> +#define LCPLL_SDC_DENOMINATOR_MASK	GENMASK(7, 2)
> +#define LCPLL_SDC_NDIV_RSTN		BIT(0)
> +/* CMN_REG(003D) */
> +#define ROPLL_LCVCO_EN			BIT(4)
> +/* CMN_REG(004E) */
> +#define ROPLL_PI_EN			BIT(5)
> +/* CMN_REG(005C) */
> +#define ROPLL_PMS_IQDIV_RSTN		BIT(5)
> +/* CMN_REG(005E) */
> +#define ROPLL_SDM_EN_MASK		BIT(6)
> +#define ROPLL_SDM_FRAC_EN_RBR		BIT(3)
> +#define ROPLL_SDM_FRAC_EN_HBR		BIT(2)
> +#define ROPLL_SDM_FRAC_EN_HBR2		BIT(1)
> +#define ROPLL_SDM_FRAC_EN_HBR3		BIT(0)
> +/* CMN_REG(0064) */
> +#define ROPLL_SDM_NUM_SIGN_RBR_MASK	BIT(3)
> +/* CMN_REG(0069) */
> +#define ROPLL_SDC_N_RBR_MASK		GENMASK(2, 0)
> +/* CMN_REG(0074) */
> +#define ROPLL_SDC_NDIV_RSTN		BIT(2)
> +#define ROPLL_SSC_EN			BIT(0)
> +/* CMN_REG(0081) */
> +#define OVRD_PLL_CD_CLK_EN		BIT(8)
> +#define PLL_CD_HSCLK_EAST_EN		BIT(0)
> +/* CMN_REG(0086) */
> +#define PLL_PCG_POSTDIV_SEL_MASK	GENMASK(7, 4)
> +#define PLL_PCG_CLK_SEL_MASK		GENMASK(3, 1)
> +#define PLL_PCG_CLK_EN			BIT(0)
> +/* CMN_REG(0087) */
> +#define PLL_FRL_MODE_EN			BIT(3)
> +#define PLL_TX_HS_CLK_EN		BIT(2)
> +/* CMN_REG(0089) */
> +#define LCPLL_ALONE_MODE		BIT(1)
> +/* CMN_REG(0097) */
> +#define DIG_CLK_SEL			BIT(1)
> +#define ROPLL_REF			BIT(1)
> +#define LCPLL_REF			0
> +/* CMN_REG(0099) */
> +#define CMN_ROPLL_ALONE_MODE		BIT(2)
> +#define ROPLL_ALONE_MODE		BIT(2)
> +/* CMN_REG(009A) */
> +#define HS_SPEED_SEL			BIT(0)
> +#define DIV_10_CLOCK			BIT(0)
> +/* CMN_REG(009B) */
> +#define IS_SPEED_SEL			BIT(4)
> +#define LINK_SYMBOL_CLOCK		BIT(4)
> +#define LINK_SYMBOL_CLOCK1_2		0
> +
> +/* SB_REG(0102) */
> +#define OVRD_SB_RXTERM_EN_MASK		BIT(5)
> +#define SB_RXTERM_EN_MASK		BIT(4)
> +#define ANA_SB_RXTERM_OFFSP_MASK	GENMASK(3, 0)
> +/* SB_REG(0103) */
> +#define ANA_SB_RXTERM_OFFSN_MASK	GENMASK(6, 3)
> +#define OVRD_SB_RX_RESCAL_DONE_MASK	BIT(1)
> +#define SB_RX_RESCAL_DONE_MASK		BIT(0)
> +/* SB_REG(0104) */
> +#define OVRD_SB_EN_MASK			BIT(5)
> +#define SB_EN_MASK			BIT(4)
> +/* SB_REG(0105) */
> +#define OVRD_SB_EARC_CMDC_EN_MASK	BIT(6)
> +#define SB_EARC_CMDC_EN_MASK		BIT(5)
> +#define ANA_SB_TX_HLVL_PROG_MASK	GENMASK(2, 0)
> +/* SB_REG(0106) */
> +#define ANA_SB_TX_LLVL_PROG_MASK	GENMASK(6, 4)
> +/* SB_REG(0109) */
> +#define ANA_SB_DMRX_AFC_DIV_RATIO_MASK	GENMASK(2, 0)
> +/* SB_REG(010F) */
> +#define OVRD_SB_VREG_EN_MASK		BIT(7)
> +#define SB_VREG_EN_MASK			BIT(6)
> +#define OVRD_SB_VREG_LPF_BYPASS_MASK	BIT(5)
> +#define SB_VREG_LPF_BYPASS_MASK		BIT(4)
> +#define ANA_SB_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
> +/* SB_REG(0110) */
> +#define ANA_SB_VREG_REF_SEL_MASK	BIT(0)
> +/* SB_REG(0113) */
> +#define SB_RX_RCAL_OPT_CODE_MASK	GENMASK(5, 4)
> +#define SB_RX_RTERM_CTRL_MASK		GENMASK(3, 0)
> +/* SB_REG(0114) */
> +#define SB_TG_SB_EN_DELAY_TIME_MASK	GENMASK(5, 3)
> +#define SB_TG_RXTERM_EN_DELAY_TIME_MASK	GENMASK(2, 0)
> +/* SB_REG(0115) */
> +#define SB_READY_DELAY_TIME_MASK	GENMASK(5, 3)
> +#define SB_TG_OSC_EN_DELAY_TIME_MASK	GENMASK(2, 0)
> +/* SB_REG(0116) */
> +#define AFC_RSTN_DELAY_TIME_MASK	GENMASK(6, 4)
> +/* SB_REG(0117) */
> +#define FAST_PULSE_TIME_MASK		GENMASK(3, 0)
> +/* SB_REG(011B) */
> +#define SB_EARC_SIG_DET_BYPASS_MASK	BIT(4)
> +#define SB_AFC_TOL_MASK			GENMASK(3, 0)
> +/* SB_REG(011F) */
> +#define SB_PWM_AFC_CTRL_MASK		GENMASK(7, 2)
> +#define SB_RCAL_RSTN_MASK		BIT(1)
> +/* SB_REG(0120) */
> +#define SB_EARC_EN_MASK			BIT(1)
> +#define SB_EARC_AFC_EN_MASK		BIT(2)
> +/* SB_REG(0123) */
> +#define OVRD_SB_READY_MASK		BIT(5)
> +#define SB_READY_MASK			BIT(4)
> +
> +/* LNTOP_REG(0200) */
> +#define PROTOCOL_SEL			BIT(2)
> +#define HDMI_MODE			BIT(2)
> +#define HDMI_TMDS_FRL_SEL		BIT(1)
> +/* LNTOP_REG(0206) */
> +#define DATA_BUS_SEL			BIT(0)
> +#define DATA_BUS_36_40			BIT(0)
> +/* LNTOP_REG(0207) */
> +#define LANE_EN				0xf
> +#define ALL_LANE_EN			0xf
> +
> +/* LANE_REG(0312) */
> +#define LN0_TX_SER_RATE_SEL_RBR		BIT(5)
> +#define LN0_TX_SER_RATE_SEL_HBR		BIT(4)
> +#define LN0_TX_SER_RATE_SEL_HBR2	BIT(3)
> +#define LN0_TX_SER_RATE_SEL_HBR3	BIT(2)
> +/* LANE_REG(0412) */
> +#define LN1_TX_SER_RATE_SEL_RBR		BIT(5)
> +#define LN1_TX_SER_RATE_SEL_HBR		BIT(4)
> +#define LN1_TX_SER_RATE_SEL_HBR2	BIT(3)
> +#define LN1_TX_SER_RATE_SEL_HBR3	BIT(2)
> +/* LANE_REG(0512) */
> +#define LN2_TX_SER_RATE_SEL_RBR		BIT(5)
> +#define LN2_TX_SER_RATE_SEL_HBR		BIT(4)
> +#define LN2_TX_SER_RATE_SEL_HBR2	BIT(3)
> +#define LN2_TX_SER_RATE_SEL_HBR3	BIT(2)
> +/* LANE_REG(0612) */
> +#define LN3_TX_SER_RATE_SEL_RBR		BIT(5)
> +#define LN3_TX_SER_RATE_SEL_HBR		BIT(4)
> +#define LN3_TX_SER_RATE_SEL_HBR2	BIT(3)
> +#define LN3_TX_SER_RATE_SEL_HBR3	BIT(2)
> +
> +struct lcpll_config {
> +	u32 bit_rate;
> +	u8 lcvco_mode_en;
> +	u8 pi_en;
> +	u8 clk_en_100m;
> +	u8 pms_mdiv;
> +	u8 pms_mdiv_afc;
> +	u8 pms_pdiv;
> +	u8 pms_refdiv;
> +	u8 pms_sdiv;
> +	u8 pi_cdiv_rstn;
> +	u8 pi_cdiv_sel;
> +	u8 sdm_en;
> +	u8 sdm_rstn;
> +	u8 sdc_frac_en;
> +	u8 sdc_rstn;
> +	u8 sdm_deno;
> +	u8 sdm_num_sign;
> +	u8 sdm_num;
> +	u8 sdc_n;
> +	u8 sdc_n2;
> +	u8 sdc_num;
> +	u8 sdc_deno;
> +	u8 sdc_ndiv_rstn;
> +	u8 ssc_en;
> +	u8 ssc_fm_dev;
> +	u8 ssc_fm_freq;
> +	u8 ssc_clk_div_sel;
> +	u8 cd_tx_ser_rate_sel;
> +};
> +
> +struct ropll_config {
> +	u32 bit_rate;
> +	u8 pms_mdiv;
> +	u8 pms_mdiv_afc;
> +	u8 pms_pdiv;
> +	u8 pms_refdiv;
> +	u8 pms_sdiv;
> +	u8 pms_iqdiv_rstn;
> +	u8 ref_clk_sel;
> +	u8 sdm_en;
> +	u8 sdm_rstn;
> +	u8 sdc_frac_en;
> +	u8 sdc_rstn;
> +	u8 sdm_clk_div;
> +	u8 sdm_deno;
> +	u8 sdm_num_sign;
> +	u8 sdm_num;
> +	u8 sdc_n;
> +	u8 sdc_num;
> +	u8 sdc_deno;
> +	u8 sdc_ndiv_rstn;
> +	u8 ssc_en;
> +	u8 ssc_fm_dev;
> +	u8 ssc_fm_freq;
> +	u8 ssc_clk_div_sel;
> +	u8 ana_cpp_ctrl;
> +	u8 ana_lpf_c_sel;
> +	u8 cd_tx_ser_rate_sel;
> +};
> +
> +enum rockchip_hdptx_reset {
> +	RST_PHY = 0,
> +	RST_APB,
> +	RST_INIT,
> +	RST_CMN,
> +	RST_LANE,
> +	RST_ROPLL,
> +	RST_LCPLL,
> +	RST_MAX
> +};
> +
> +struct rockchip_hdptx_phy {
> +	struct device *dev;
> +	struct regmap *regmap;
> +	struct regmap *grf;
> +
> +	struct phy *phy;
> +	struct phy_config *phy_cfg;
> +	struct clk_bulk_data *clks;
> +	int nr_clks;
> +	struct reset_control_bulk_data rsts[RST_MAX];
> +};
> +
> +static const struct ropll_config ropll_tmds_cfg[] = {
> +	{ 5940000, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
> +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 3712500, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
> +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 2970000, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
> +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 1620000, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10,
> +	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 1856250, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
> +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 1540000, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1,
> +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 1485000, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5,
> +	  0x10, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 1462500, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1,
> +	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 1190000, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1,
> +	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 1065000, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1,
> +	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 1080000, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
> +	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 855000, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1,
> +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 835000, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0,
> +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 928125, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
> +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 742500, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
> +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 650000, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1,
> +	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 337500, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5,
> +	  1, 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 400000, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
> +	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 270000, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
> +	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +	{ 251750, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1,
> +	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
> +};
> +
> +static const struct reg_sequence hdtpx_common_cmn_init_seq[] = {
> +	REG_SEQ0(CMN_REG(0009), 0x0c),
> +	REG_SEQ0(CMN_REG(000A), 0x83),
> +	REG_SEQ0(CMN_REG(000B), 0x06),
> +	REG_SEQ0(CMN_REG(000C), 0x20),
> +	REG_SEQ0(CMN_REG(000D), 0xb8),
> +	REG_SEQ0(CMN_REG(000E), 0x0f),
> +	REG_SEQ0(CMN_REG(000F), 0x0f),

Any reason for these to be mixed case, lets have lower case pls
everywhere

> +	REG_SEQ0(CMN_REG(0010), 0x04),
> +	REG_SEQ0(CMN_REG(0011), 0x00),
> +	REG_SEQ0(CMN_REG(0012), 0x26),
> +	REG_SEQ0(CMN_REG(0013), 0x22),
> +	REG_SEQ0(CMN_REG(0014), 0x24),
> +	REG_SEQ0(CMN_REG(0015), 0x77),
> +	REG_SEQ0(CMN_REG(0016), 0x08),
> +	REG_SEQ0(CMN_REG(0017), 0x00),
> +	REG_SEQ0(CMN_REG(0018), 0x04),
> +	REG_SEQ0(CMN_REG(0019), 0x48),
> +	REG_SEQ0(CMN_REG(001A), 0x01),
> +	REG_SEQ0(CMN_REG(001B), 0x00),
> +	REG_SEQ0(CMN_REG(001C), 0x01),
> +	REG_SEQ0(CMN_REG(001D), 0x64),
> +	REG_SEQ0(CMN_REG(001F), 0x00),
> +	REG_SEQ0(CMN_REG(0026), 0x53),
> +	REG_SEQ0(CMN_REG(0029), 0x01),
> +	REG_SEQ0(CMN_REG(0030), 0x00),
> +	REG_SEQ0(CMN_REG(0031), 0x20),
> +	REG_SEQ0(CMN_REG(0032), 0x30),
> +	REG_SEQ0(CMN_REG(0033), 0x0b),
> +	REG_SEQ0(CMN_REG(0034), 0x23),
> +	REG_SEQ0(CMN_REG(0035), 0x00),
> +	REG_SEQ0(CMN_REG(0038), 0x00),
> +	REG_SEQ0(CMN_REG(0039), 0x00),
> +	REG_SEQ0(CMN_REG(003A), 0x00),
> +	REG_SEQ0(CMN_REG(003B), 0x00),
> +	REG_SEQ0(CMN_REG(003C), 0x80),
> +	REG_SEQ0(CMN_REG(003E), 0x0c),
> +	REG_SEQ0(CMN_REG(003F), 0x83),
> +	REG_SEQ0(CMN_REG(0040), 0x06),
> +	REG_SEQ0(CMN_REG(0041), 0x20),
> +	REG_SEQ0(CMN_REG(0042), 0xb8),
> +	REG_SEQ0(CMN_REG(0043), 0x00),
> +	REG_SEQ0(CMN_REG(0044), 0x46),
> +	REG_SEQ0(CMN_REG(0045), 0x24),
> +	REG_SEQ0(CMN_REG(0046), 0xff),
> +	REG_SEQ0(CMN_REG(0047), 0x00),
> +	REG_SEQ0(CMN_REG(0048), 0x44),
> +	REG_SEQ0(CMN_REG(0049), 0xfa),
> +	REG_SEQ0(CMN_REG(004A), 0x08),
> +	REG_SEQ0(CMN_REG(004B), 0x00),
> +	REG_SEQ0(CMN_REG(004C), 0x01),
> +	REG_SEQ0(CMN_REG(004D), 0x64),
> +	REG_SEQ0(CMN_REG(004E), 0x14),
> +	REG_SEQ0(CMN_REG(004F), 0x00),
> +	REG_SEQ0(CMN_REG(0050), 0x00),
> +	REG_SEQ0(CMN_REG(005D), 0x0c),
> +	REG_SEQ0(CMN_REG(005F), 0x01),
> +	REG_SEQ0(CMN_REG(006B), 0x04),
> +	REG_SEQ0(CMN_REG(0073), 0x30),
> +	REG_SEQ0(CMN_REG(0074), 0x00),
> +	REG_SEQ0(CMN_REG(0075), 0x20),
> +	REG_SEQ0(CMN_REG(0076), 0x30),
> +	REG_SEQ0(CMN_REG(0077), 0x08),
> +	REG_SEQ0(CMN_REG(0078), 0x0c),
> +	REG_SEQ0(CMN_REG(0079), 0x00),
> +	REG_SEQ0(CMN_REG(007B), 0x00),
> +	REG_SEQ0(CMN_REG(007C), 0x00),
> +	REG_SEQ0(CMN_REG(007D), 0x00),
> +	REG_SEQ0(CMN_REG(007E), 0x00),
> +	REG_SEQ0(CMN_REG(007F), 0x00),
> +	REG_SEQ0(CMN_REG(0080), 0x00),
> +	REG_SEQ0(CMN_REG(0081), 0x09),
> +	REG_SEQ0(CMN_REG(0082), 0x04),
> +	REG_SEQ0(CMN_REG(0083), 0x24),
> +	REG_SEQ0(CMN_REG(0084), 0x20),
> +	REG_SEQ0(CMN_REG(0085), 0x03),
> +	REG_SEQ0(CMN_REG(0086), 0x01),
> +	REG_SEQ0(CMN_REG(0087), 0x0c),
> +	REG_SEQ0(CMN_REG(008A), 0x55),
> +	REG_SEQ0(CMN_REG(008B), 0x25),
> +	REG_SEQ0(CMN_REG(008C), 0x2c),
> +	REG_SEQ0(CMN_REG(008D), 0x22),
> +	REG_SEQ0(CMN_REG(008E), 0x14),
> +	REG_SEQ0(CMN_REG(008F), 0x20),
> +	REG_SEQ0(CMN_REG(0090), 0x00),
> +	REG_SEQ0(CMN_REG(0091), 0x00),
> +	REG_SEQ0(CMN_REG(0092), 0x00),
> +	REG_SEQ0(CMN_REG(0093), 0x00),
> +	REG_SEQ0(CMN_REG(009A), 0x11),
> +	REG_SEQ0(CMN_REG(009B), 0x10),
> +};
> +
> +static const struct reg_sequence hdtpx_tmds_cmn_init_seq[] = {
> +	REG_SEQ0(CMN_REG(0008), 0x00),
> +	REG_SEQ0(CMN_REG(0011), 0x01),
> +	REG_SEQ0(CMN_REG(0017), 0x20),
> +	REG_SEQ0(CMN_REG(001E), 0x14),
> +	REG_SEQ0(CMN_REG(0020), 0x00),
> +	REG_SEQ0(CMN_REG(0021), 0x00),
> +	REG_SEQ0(CMN_REG(0022), 0x11),
> +	REG_SEQ0(CMN_REG(0023), 0x00),
> +	REG_SEQ0(CMN_REG(0024), 0x00),
> +	REG_SEQ0(CMN_REG(0025), 0x53),
> +	REG_SEQ0(CMN_REG(0026), 0x00),
> +	REG_SEQ0(CMN_REG(0027), 0x00),
> +	REG_SEQ0(CMN_REG(0028), 0x01),
> +	REG_SEQ0(CMN_REG(002A), 0x00),
> +	REG_SEQ0(CMN_REG(002B), 0x00),
> +	REG_SEQ0(CMN_REG(002C), 0x00),
> +	REG_SEQ0(CMN_REG(002D), 0x00),
> +	REG_SEQ0(CMN_REG(002E), 0x04),
> +	REG_SEQ0(CMN_REG(002F), 0x00),
> +	REG_SEQ0(CMN_REG(0030), 0x20),
> +	REG_SEQ0(CMN_REG(0031), 0x30),
> +	REG_SEQ0(CMN_REG(0032), 0x0b),
> +	REG_SEQ0(CMN_REG(0033), 0x23),
> +	REG_SEQ0(CMN_REG(0034), 0x00),
> +	REG_SEQ0(CMN_REG(003D), 0x40),
> +	REG_SEQ0(CMN_REG(0042), 0x78),
> +	REG_SEQ0(CMN_REG(004E), 0x34),
> +	REG_SEQ0(CMN_REG(005C), 0x25),
> +	REG_SEQ0(CMN_REG(005E), 0x4f),
> +	REG_SEQ0(CMN_REG(0074), 0x04),
> +	REG_SEQ0(CMN_REG(0081), 0x01),
> +	REG_SEQ0(CMN_REG(0087), 0x04),
> +	REG_SEQ0(CMN_REG(0089), 0x00),
> +	REG_SEQ0(CMN_REG(0095), 0x00),
> +	REG_SEQ0(CMN_REG(0097), 0x02),
> +	REG_SEQ0(CMN_REG(0099), 0x04),
> +	REG_SEQ0(CMN_REG(009B), 0x00),
> +};
> +
> +static const struct reg_sequence hdtpx_common_sb_init_seq[] = {
> +	REG_SEQ0(SB_REG(0114), 0x00),
> +	REG_SEQ0(SB_REG(0115), 0x00),
> +	REG_SEQ0(SB_REG(0116), 0x00),
> +	REG_SEQ0(SB_REG(0117), 0x00),
> +};
> +
> +static const struct reg_sequence hdtpx_tmds_lntop_highbr_seq[] = {
> +	REG_SEQ0(LNTOP_REG(0201), 0x00),
> +	REG_SEQ0(LNTOP_REG(0202), 0x00),
> +	REG_SEQ0(LNTOP_REG(0203), 0x0f),
> +	REG_SEQ0(LNTOP_REG(0204), 0xff),
> +	REG_SEQ0(LNTOP_REG(0205), 0xff),
> +};
> +
> +static const struct reg_sequence hdtpx_tmds_lntop_lowbr_seq[] = {
> +	REG_SEQ0(LNTOP_REG(0201), 0x07),
> +	REG_SEQ0(LNTOP_REG(0202), 0xc1),
> +	REG_SEQ0(LNTOP_REG(0203), 0xf0),
> +	REG_SEQ0(LNTOP_REG(0204), 0x7c),
> +	REG_SEQ0(LNTOP_REG(0205), 0x1f),
> +};
> +
> +static const struct reg_sequence hdtpx_common_lane_init_seq[] = {
> +	REG_SEQ0(LANE_REG(0303), 0x0c),
> +	REG_SEQ0(LANE_REG(0307), 0x20),
> +	REG_SEQ0(LANE_REG(030A), 0x17),
> +	REG_SEQ0(LANE_REG(030B), 0x77),
> +	REG_SEQ0(LANE_REG(030C), 0x77),
> +	REG_SEQ0(LANE_REG(030D), 0x77),
> +	REG_SEQ0(LANE_REG(030E), 0x38),
> +	REG_SEQ0(LANE_REG(0310), 0x03),
> +	REG_SEQ0(LANE_REG(0311), 0x0f),
> +	REG_SEQ0(LANE_REG(0316), 0x02),
> +	REG_SEQ0(LANE_REG(031B), 0x01),
> +	REG_SEQ0(LANE_REG(031F), 0x15),
> +	REG_SEQ0(LANE_REG(0320), 0xa0),
> +	REG_SEQ0(LANE_REG(0403), 0x0c),
> +	REG_SEQ0(LANE_REG(0407), 0x20),
> +	REG_SEQ0(LANE_REG(040A), 0x17),
> +	REG_SEQ0(LANE_REG(040B), 0x77),
> +	REG_SEQ0(LANE_REG(040C), 0x77),
> +	REG_SEQ0(LANE_REG(040D), 0x77),
> +	REG_SEQ0(LANE_REG(040E), 0x38),
> +	REG_SEQ0(LANE_REG(0410), 0x03),
> +	REG_SEQ0(LANE_REG(0411), 0x0f),
> +	REG_SEQ0(LANE_REG(0416), 0x02),
> +	REG_SEQ0(LANE_REG(041B), 0x01),
> +	REG_SEQ0(LANE_REG(041F), 0x15),
> +	REG_SEQ0(LANE_REG(0420), 0xa0),
> +	REG_SEQ0(LANE_REG(0503), 0x0c),
> +	REG_SEQ0(LANE_REG(0507), 0x20),
> +	REG_SEQ0(LANE_REG(050A), 0x17),
> +	REG_SEQ0(LANE_REG(050B), 0x77),
> +	REG_SEQ0(LANE_REG(050C), 0x77),
> +	REG_SEQ0(LANE_REG(050D), 0x77),
> +	REG_SEQ0(LANE_REG(050E), 0x38),
> +	REG_SEQ0(LANE_REG(0510), 0x03),
> +	REG_SEQ0(LANE_REG(0511), 0x0f),
> +	REG_SEQ0(LANE_REG(0516), 0x02),
> +	REG_SEQ0(LANE_REG(051B), 0x01),
> +	REG_SEQ0(LANE_REG(051F), 0x15),
> +	REG_SEQ0(LANE_REG(0520), 0xa0),
> +	REG_SEQ0(LANE_REG(0603), 0x0c),
> +	REG_SEQ0(LANE_REG(0607), 0x20),
> +	REG_SEQ0(LANE_REG(060A), 0x17),
> +	REG_SEQ0(LANE_REG(060B), 0x77),
> +	REG_SEQ0(LANE_REG(060C), 0x77),
> +	REG_SEQ0(LANE_REG(060D), 0x77),
> +	REG_SEQ0(LANE_REG(060E), 0x38),
> +	REG_SEQ0(LANE_REG(0610), 0x03),
> +	REG_SEQ0(LANE_REG(0611), 0x0f),
> +	REG_SEQ0(LANE_REG(0616), 0x02),
> +	REG_SEQ0(LANE_REG(061B), 0x01),
> +	REG_SEQ0(LANE_REG(061F), 0x15),
> +	REG_SEQ0(LANE_REG(0620), 0xa0),
> +};
> +
> +static const struct reg_sequence hdtpx_tmds_lane_init_seq[] = {
> +	REG_SEQ0(LANE_REG(0312), 0x00),
> +	REG_SEQ0(LANE_REG(031E), 0x00),
> +	REG_SEQ0(LANE_REG(0412), 0x00),
> +	REG_SEQ0(LANE_REG(041E), 0x00),
> +	REG_SEQ0(LANE_REG(0512), 0x00),
> +	REG_SEQ0(LANE_REG(051E), 0x00),
> +	REG_SEQ0(LANE_REG(0612), 0x00),
> +	REG_SEQ0(LANE_REG(061E), 0x08),
> +	REG_SEQ0(LANE_REG(0303), 0x2f),
> +	REG_SEQ0(LANE_REG(0403), 0x2f),
> +	REG_SEQ0(LANE_REG(0503), 0x2f),
> +	REG_SEQ0(LANE_REG(0603), 0x2f),
> +	REG_SEQ0(LANE_REG(0305), 0x03),
> +	REG_SEQ0(LANE_REG(0405), 0x03),
> +	REG_SEQ0(LANE_REG(0505), 0x03),
> +	REG_SEQ0(LANE_REG(0605), 0x03),
> +	REG_SEQ0(LANE_REG(0306), 0x1c),
> +	REG_SEQ0(LANE_REG(0406), 0x1c),
> +	REG_SEQ0(LANE_REG(0506), 0x1c),
> +	REG_SEQ0(LANE_REG(0606), 0x1c),
> +};
> +
> +static bool rockchip_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case 0x0000 ... 0x029c:
> +	case 0x0400 ... 0x04a4:
> +	case 0x0800 ... 0x08a4:
> +	case 0x0c00 ... 0x0cb4:
> +	case 0x1000 ... 0x10b4:
> +	case 0x1400 ... 0x14b4:
> +	case 0x1800 ... 0x18b4:
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +static const struct regmap_config rockchip_hdptx_phy_regmap_config = {
> +	.reg_bits = 32,
> +	.reg_stride = 4,
> +	.val_bits = 32,
> +	.writeable_reg = rockchip_hdptx_phy_is_rw_reg,
> +	.readable_reg = rockchip_hdptx_phy_is_rw_reg,
> +	.fast_io = true,
> +	.max_register = 0x18b4,
> +};
> +
> +static int hdptx_write(struct rockchip_hdptx_phy *hdptx, u32 reg, u8 val)
> +{
> +	return regmap_write(hdptx->regmap, reg, val);
> +}
> +
> +#define hdptx_multi_reg_write(hdptx, seq) \
> +	regmap_multi_reg_write((hdptx)->regmap, seq, ARRAY_SIZE(seq))
> +
> +static int hdptx_update_bits(struct rockchip_hdptx_phy *hdptx, u32 reg,
> +			     u8 mask, u8 val)
> +{
> +	return regmap_update_bits(hdptx->regmap, reg, mask, val);
> +}
> +
> +static int hdptx_grf_write(struct rockchip_hdptx_phy *hdptx, u32 reg, u32 val)
> +{
> +	return regmap_write(hdptx->grf, reg, val);
> +}
> +
> +static u8 hdptx_grf_read(struct rockchip_hdptx_phy *hdptx, u32 reg)
> +{
> +	u32 val;
> +
> +	regmap_read(hdptx->grf, reg, &val);
> +
> +	return val;
> +}

why use wrappers, why not call regmap_ apis directly

> +
> +static void hdptx_pre_power_up(struct rockchip_hdptx_phy *hdptx)
> +{
> +	u32 val;
> +
> +	reset_control_assert(hdptx->rsts[RST_APB].rstc);
> +	usleep_range(20, 25);
> +	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
> +
> +	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
> +	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
> +	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
> +
> +	val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
> +	hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val);
> +}
> +
> +static int hdptx_post_enable_lane(struct rockchip_hdptx_phy *hdptx)
> +{
> +	u32 val;
> +	int ret;
> +
> +	reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
> +
> +	val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
> +	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
> +	hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val);
> +
> +	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
> +				       (val & HDPTX_O_PHY_RDY) &&
> +				       (val & HDPTX_O_PLL_LOCK_DONE),
> +				       100, 5000);
> +	if (ret) {
> +		dev_err(hdptx->dev, "Failed to get PHY lane lock: %d\n", ret);
> +		return ret;
> +	}
> +
> +	dev_dbg(hdptx->dev, "PHY lane locked\n");
> +
> +	return 0;
> +}
> +
> +static int hdptx_post_enable_pll(struct rockchip_hdptx_phy *hdptx)
> +{
> +	u32 val;
> +	int ret;
> +
> +	val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
> +	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
> +	hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val);
> +
> +	usleep_range(10, 15);
> +	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
> +
> +	usleep_range(10, 15);
> +	val = HDPTX_I_PLL_EN << 16 | HDPTX_I_PLL_EN;
> +	hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val);
> +
> +	usleep_range(10, 15);
> +	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
> +
> +	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
> +				       val & HDPTX_O_PHY_CLK_RDY, 20, 400);
> +	if (ret) {
> +		dev_err(hdptx->dev, "Failed to get PHY clk ready: %d\n", ret);
> +		return ret;
> +	}
> +
> +	dev_dbg(hdptx->dev, "PHY clk ready\n");
> +
> +	return 0;
> +}
> +
> +static void hdptx_phy_disable(struct rockchip_hdptx_phy *hdptx)
> +{
> +	u32 val;
> +
> +	/* reset phy and apb, or phy locked flag may keep 1 */
> +	reset_control_assert(hdptx->rsts[RST_PHY].rstc);
> +	usleep_range(20, 30);
> +	reset_control_deassert(hdptx->rsts[RST_PHY].rstc);
> +
> +	reset_control_assert(hdptx->rsts[RST_APB].rstc);
> +	usleep_range(20, 30);
> +	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
> +
> +	hdptx_write(hdptx, LANE_REG(0300), 0x82);
> +	hdptx_write(hdptx, SB_REG(010F), 0xc1);
> +	hdptx_write(hdptx, SB_REG(0110), 0x1);
> +	hdptx_write(hdptx, LANE_REG(0301), 0x80);
> +	hdptx_write(hdptx, LANE_REG(0401), 0x80);
> +	hdptx_write(hdptx, LANE_REG(0501), 0x80);
> +	hdptx_write(hdptx, LANE_REG(0601), 0x80);
> +
> +	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
> +	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
> +	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
> +
> +	val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
> +	hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val);
> +}
> +
> +static bool hdptx_phy_clk_pll_calc(unsigned int data_rate,
> +				   struct ropll_config *cfg)
> +{
> +	const unsigned int fout = data_rate / 2, fref = 24000;
> +	unsigned long k = 0, lc, k_sub, lc_sub;
> +	unsigned int fvco, sdc;
> +	u32 mdiv, sdiv, n = 8;
> +
> +	for (sdiv = 16; sdiv >= 1; sdiv--) {
> +		if (sdiv % 2 && sdiv != 1)
> +			continue;
> +
> +		fvco = fout * sdiv;
> +
> +		if (fvco < 2000000 || fvco > 4000000)
> +			continue;
> +
> +		mdiv = DIV_ROUND_UP(fvco, fref);
> +		if (mdiv < 20 || mdiv > 255)
> +			continue;
> +
> +		if (fref * mdiv - fvco) {
> +			for (sdc = 264000; sdc <= 750000; sdc += fref)
> +				if (sdc * n > fref * mdiv)
> +					break;
> +
> +			if (sdc > 750000)
> +				continue;
> +
> +			rational_best_approximation(fref * mdiv - fvco,
> +						    sdc / 16,
> +						    GENMASK(6, 0),
> +						    GENMASK(7, 0),
> +						    &k, &lc);
> +
> +			rational_best_approximation(sdc * n - fref * mdiv,
> +						    sdc,
> +						    GENMASK(6, 0),
> +						    GENMASK(7, 0),
> +						    &k_sub, &lc_sub);
> +		}
> +
> +		break;
> +	}
> +
> +	if (sdiv < 1)
> +		return false;
> +
> +	if (cfg) {
> +		cfg->pms_mdiv = mdiv;
> +		cfg->pms_mdiv_afc = mdiv;
> +		cfg->pms_pdiv = 1;
> +		cfg->pms_refdiv = 1;
> +		cfg->pms_sdiv = sdiv - 1;
> +
> +		cfg->sdm_en = k > 0 ? 1 : 0;
> +		if (cfg->sdm_en) {
> +			cfg->sdm_deno = lc;
> +			cfg->sdm_num_sign = 1;
> +			cfg->sdm_num = k;
> +			cfg->sdc_n = n - 3;
> +			cfg->sdc_num = k_sub;
> +			cfg->sdc_deno = lc_sub;
> +		}
> +	}
> +
> +	return true;
> +}
> +
> +static int hdptx_ropll_tmds_cmn_config(struct rockchip_hdptx_phy *hdptx,
> +				       unsigned int rate)
> +{
> +	const struct ropll_config *cfg = NULL;
> +	struct ropll_config rc = {0};
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
> +		if (rate == ropll_tmds_cfg[i].bit_rate) {
> +			cfg = &ropll_tmds_cfg[i];
> +			break;
> +		}
> +
> +	if (!cfg) {
> +		if (hdptx_phy_clk_pll_calc(rate, &rc)) {
> +			cfg = &rc;
> +		} else {
> +			dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	dev_dbg(hdptx->dev, "mdiv=%u, sdiv=%u, sdm_en=%u, k_sign=%u, k=%u, lc=%u\n",
> +		cfg->pms_mdiv, cfg->pms_sdiv + 1, cfg->sdm_en,
> +		cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno);
> +
> +	hdptx_pre_power_up(hdptx);
> +
> +	reset_control_assert(hdptx->rsts[RST_ROPLL].rstc);
> +	usleep_range(20, 30);
> +	reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc);
> +
> +	hdptx_multi_reg_write(hdptx, hdtpx_common_cmn_init_seq);
> +	hdptx_multi_reg_write(hdptx, hdtpx_tmds_cmn_init_seq);
> +
> +	hdptx_write(hdptx, CMN_REG(0051), cfg->pms_mdiv);
> +	hdptx_write(hdptx, CMN_REG(0055), cfg->pms_mdiv_afc);
> +	hdptx_write(hdptx, CMN_REG(0059), (cfg->pms_pdiv << 4) | cfg->pms_refdiv);
> +	hdptx_write(hdptx, CMN_REG(005A), cfg->pms_sdiv << 4);

small case here as well pls

> +
> +	hdptx_update_bits(hdptx, CMN_REG(005E), ROPLL_SDM_EN_MASK,
> +			  FIELD_PREP(ROPLL_SDM_EN_MASK, cfg->sdm_en));
> +	if (!cfg->sdm_en)
> +		hdptx_update_bits(hdptx, CMN_REG(005E), 0xf, 0);
> +
> +	hdptx_update_bits(hdptx, CMN_REG(0064), ROPLL_SDM_NUM_SIGN_RBR_MASK,
> +			  FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, cfg->sdm_num_sign));
> +
> +	hdptx_write(hdptx, CMN_REG(0060), cfg->sdm_deno);
> +	hdptx_write(hdptx, CMN_REG(0065), cfg->sdm_num);
> +
> +	hdptx_update_bits(hdptx, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,
> +			  FIELD_PREP(ROPLL_SDC_N_RBR_MASK, cfg->sdc_n));
> +
> +	hdptx_write(hdptx, CMN_REG(006C), cfg->sdc_num);
> +	hdptx_write(hdptx, CMN_REG(0070), cfg->sdc_deno);
> +
> +	hdptx_update_bits(hdptx, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,
> +			  FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));
> +
> +	hdptx_update_bits(hdptx, CMN_REG(0086), PLL_PCG_CLK_EN, PLL_PCG_CLK_EN);
> +
> +	return hdptx_post_enable_pll(hdptx);
> +}
> +
> +static int hdptx_ropll_tmds_mode_config(struct rockchip_hdptx_phy *hdptx,
> +					unsigned int rate)
> +{
> +	int ret;
> +
> +	if (!(hdptx_grf_read(hdptx, GRF_HDPTX_STATUS) & HDPTX_O_PLL_LOCK_DONE)) {
> +		ret = hdptx_ropll_tmds_cmn_config(hdptx, rate);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	hdptx_multi_reg_write(hdptx, hdtpx_common_sb_init_seq);
> +
> +	hdptx_write(hdptx, LNTOP_REG(0200), 0x06);
> +
> +	if (rate >= 3400000) {
> +		/* For 1/40 bitrate clk */
> +		hdptx_multi_reg_write(hdptx, hdtpx_tmds_lntop_highbr_seq);
> +	} else {
> +		/* For 1/10 bitrate clk */
> +		hdptx_multi_reg_write(hdptx, hdtpx_tmds_lntop_lowbr_seq);
> +	}
> +
> +	hdptx_write(hdptx, LNTOP_REG(0206), 0x07);
> +	hdptx_write(hdptx, LNTOP_REG(0207), 0x0f);
> +
> +	hdptx_multi_reg_write(hdptx, hdtpx_common_lane_init_seq);
> +	hdptx_multi_reg_write(hdptx, hdtpx_tmds_lane_init_seq);
> +
> +	return hdptx_post_enable_lane(hdptx);
> +}
> +
> +static int rockchip_hdptx_phy_power_on(struct phy *phy)
> +{
> +	struct rockchip_hdptx_phy *hdptx = phy_get_drvdata(phy);
> +	int ret, bus_width = phy_get_bus_width(hdptx->phy);
> +	/*
> +	 * FIXME: Temporary workaround to pass pixel_clk_rate
> +	 * from the HDMI bridge driver until phy_configure_opts_hdmi
> +	 * becomes available in the PHY API.
> +	 */
> +	unsigned int rate = bus_width & 0xFFFFFFF;
> +
> +	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
> +		__func__, bus_width, rate);
> +
> +	ret = pm_runtime_resume_and_get(hdptx->dev);
> +	if (ret) {
> +		dev_err(hdptx->dev, "Failed to resume phy: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = hdptx_ropll_tmds_mode_config(hdptx, rate);
> +	if (ret)
> +		pm_runtime_put(hdptx->dev);
> +
> +	return ret;
> +}
> +
> +static int rockchip_hdptx_phy_power_off(struct phy *phy)
> +{
> +	struct rockchip_hdptx_phy *hdptx = phy_get_drvdata(phy);
> +
> +	if (hdptx_grf_read(hdptx, GRF_HDPTX_STATUS) & HDPTX_O_PLL_LOCK_DONE)
> +		hdptx_phy_disable(hdptx);
> +
> +	pm_runtime_put(hdptx->dev);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops rockchip_hdptx_phy_ops = {
> +	.power_on  = rockchip_hdptx_phy_power_on,
> +	.power_off = rockchip_hdptx_phy_power_off,
> +	.owner	   = THIS_MODULE,
> +};
> +
> +static int rockchip_hdptx_phy_runtime_suspend(struct device *dev)
> +{
> +	struct rockchip_hdptx_phy *hdptx = dev_get_drvdata(dev);
> +
> +	clk_bulk_disable_unprepare(hdptx->nr_clks, hdptx->clks);
> +
> +	return 0;
> +}
> +
> +static int rockchip_hdptx_phy_runtime_resume(struct device *dev)
> +{
> +	struct rockchip_hdptx_phy *hdptx = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = clk_bulk_prepare_enable(hdptx->nr_clks, hdptx->clks);
> +	if (ret)
> +		dev_err(hdptx->dev, "Failed to enable clocks: %d\n", ret);
> +
> +	return ret;
> +}
> +
> +static int rockchip_hdptx_phy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct rockchip_hdptx_phy *hdptx;
> +	struct phy_provider *phy_provider;
> +	void __iomem *regs;
> +	int ret;
> +
> +	hdptx = devm_kzalloc(dev, sizeof(*hdptx), GFP_KERNEL);
> +	if (!hdptx)
> +		return -ENOMEM;
> +
> +	hdptx->dev = dev;
> +
> +	regs = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(regs))
> +		return dev_err_probe(dev, PTR_ERR(regs),
> +				     "Failed to ioremap resource\n");
> +
> +	ret = devm_clk_bulk_get_all(dev, &hdptx->clks);
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "Failed to get clocks\n");
> +	if (ret == 0)
> +		return dev_err_probe(dev, -EINVAL, "Missing clocks\n");
> +
> +	hdptx->nr_clks = ret;
> +
> +	hdptx->regmap = devm_regmap_init_mmio(dev, regs,
> +					      &rockchip_hdptx_phy_regmap_config);
> +	if (IS_ERR(hdptx->regmap))
> +		return dev_err_probe(dev, PTR_ERR(hdptx->regmap),
> +				     "Failed to init regmap\n");
> +
> +	hdptx->rsts[RST_PHY].id = "phy";
> +	hdptx->rsts[RST_APB].id = "apb";
> +	hdptx->rsts[RST_INIT].id = "init";
> +	hdptx->rsts[RST_CMN].id = "cmn";
> +	hdptx->rsts[RST_LANE].id = "lane";
> +	hdptx->rsts[RST_ROPLL].id = "ropll";
> +	hdptx->rsts[RST_LCPLL].id = "lcpll";
> +
> +	ret = devm_reset_control_bulk_get_exclusive(dev, RST_MAX, hdptx->rsts);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to get resets\n");
> +
> +	hdptx->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
> +						     "rockchip,grf");
> +	if (IS_ERR(hdptx->grf))
> +		return dev_err_probe(dev, PTR_ERR(hdptx->grf),
> +				     "Could not get GRF syscon\n");
> +
> +	hdptx->phy = devm_phy_create(dev, NULL, &rockchip_hdptx_phy_ops);
> +	if (IS_ERR(hdptx->phy))
> +		return dev_err_probe(dev, PTR_ERR(hdptx->phy),
> +				     "Failed to create HDMI PHY\n");
> +
> +	platform_set_drvdata(pdev, hdptx);
> +	phy_set_drvdata(hdptx->phy, hdptx);
> +	phy_set_bus_width(hdptx->phy, 8);
> +
> +	ret = devm_pm_runtime_enable(dev);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
> +
> +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +	if (IS_ERR(phy_provider))
> +		return dev_err_probe(dev, PTR_ERR(phy_provider),
> +				     "Failed to register PHY provider\n");
> +
> +	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
> +	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
> +	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops rockchip_hdptx_phy_pm_ops = {
> +	RUNTIME_PM_OPS(rockchip_hdptx_phy_runtime_suspend,
> +		       rockchip_hdptx_phy_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id rockchip_hdptx_phy_of_match[] = {
> +	{ .compatible = "rockchip,rk3588-hdptx-phy", },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, rockchip_hdptx_phy_of_match);
> +
> +static struct platform_driver rockchip_hdptx_phy_driver = {
> +	.probe  = rockchip_hdptx_phy_probe,
> +	.driver = {
> +		.name = "rockchip-hdptx-phy",
> +		.pm = &rockchip_hdptx_phy_pm_ops,
> +		.of_match_table = rockchip_hdptx_phy_of_match,
> +	},
> +};
> +module_platform_driver(rockchip_hdptx_phy_driver);
> +
> +MODULE_AUTHOR("Algea Cao <algea.cao at rock-chips.com>");
> +MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea at collabora.com>");
> +MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver");
> +MODULE_LICENSE("GPL");
> 
> -- 
> 2.43.0

-- 
~Vinod


From mark.rutland at arm.com  Wed Feb  7 02:18:24 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 7 Feb 2024 10:18:24 +0000
Subject: [PATCH REPOST v2] ARM64: Dynamically allocate cpumasks and
 increase supported CPUs to 512
In-Reply-To: <e0d41efb-a74e-6bb5-f325-63d42358c802@gentwo.org>
References: <e0d41efb-a74e-6bb5-f325-63d42358c802@gentwo.org>
Message-ID: <ZcNY8HuKHMguvdf9@FVFF77S0Q05N.cambridge.arm.com>

Hi CHristoph,

On Tue, Feb 06, 2024 at 10:09:59AM -0800, Christoph Lameter (Ampere) wrote:
> Can we get this merged for 6.9? The patch has been around for awhile now.
>
> Ampere Computing develops high end ARM processor that support an ever
> increasing number of processors. The default 256 processors are
> not enough for our newer products. The default is used by
> distros and therefore our customers cannot use distro kernels because
> the number of processors is not supported.
> 
> One of the objections against earlier patches to increase the limit
> was that the memory use becomes too high. There is a feature called
> CPUMASK_OFFSTACK that configures the cpumasks in the kernel to be
> dynamically allocated. This was used in the X86 architecture in the
> past to enable support for larger CPU configurations up to 8k cpus.
> 
> With that is becomes possible to dynamically size the allocation of
> the cpu bitmaps depending on the quantity of processors detected on
> bootup.
> 
> This patch enables that logic if more than 256 processors
> are configured and increases the default to 512 processors.
> 
> Further increases may be needed if ARM processor vendors start
> supporting more processors. Given the current inflationary trends
> in core counts from multiple processor manufacturers this may occur.

Can we please make this simpler, and clearer e.g.

  Currently defconfig selects NR_CPUS=256, but some vendors (e.g. Ampere
  Computing) are planning to ship systems with 512 CPUs. So that all CPUs on
  these systems can be used with defconfig, we'd like to bump NR_CPUS to 512.
  Therefore this patch increases the default NR_CPUS from 256 to 512.

  As increasing NR_CPUS will increase the size of cpumasks, there's a fear that
  this might have a significant impact on stack usage due to code which places
  cpumasks on the stack. To mitigate that concern, we can select
  CPUMASK_OFFSTACK. As that doesn't seem to be a problem today with
  NR_CPUS=256, we only select this when NR_CPUS > 256.

There's no need for all the other gunk.

However, can you please comment on the impact of this? e.g. 

* Does it make the kernel Image or vmlinux any bigger? 
 
  If you can build the kernel before/after this patch and dump the output of
  'ls -l arch/arm64/boot/Image' and 'size vmlinux', that would be great.

* Does this have any obvious impact on the memory usage of the kernel?

* Does this have any obvious performance impact? e.g. is a kernel build any
  slower/faster before/after this patch on a system with 256-or-fewer CPUs?

> Tested-by: Eric Mackay <eric.mackay at oracle.com>
> Signed-off-by: Christoph Lameter (Ampere) <cl at linux.com>
> 
> ---
> 
> Original post: https://www.spinics.net/lists/linux-mm/msg369701.html
> 
> V1->V2
> 
> - Keep quotation marks
> - Remove whiltespace damage
> - Add tested by
> 
> 
> Index: linux/arch/arm64/Kconfig
> ===================================================================

Can you please use git format-patch? This is more painful than necessary to
apply with usual tools like b4 and git am, and the arm64 maintainers are much
more likely to pick up a patch when they don't have to go outside of their
usual workflow to do so...

> --- linux.orig/arch/arm64/Kconfig
> +++ linux/arch/arm64/Kconfig
> @@ -1407,7 +1407,21 @@ config SCHED_SMT
>   config NR_CPUS
>   	int "Maximum number of CPUs (2-4096)"
>   	range 2 4096
> -	default "256"
> +	default "512"
> +
> +#
> +# Determines the placement of cpumasks.
> +#
> +# With CPUMASK_OFFSTACK the cpumasks are dynamically allocated.
> +# Useful for machines with lots of core because it avoids increasing
> +# the size of many of the data structures in the kernel.
> +#
> +# If this is off then the cpumasks have a static sizes and are
> +# embedded within data structures.
> +#

This described the semantic of CPUMASK_OFFSTACK, which is not specific to
arm64. If we need a comment, it should explain *why* we select this for more
than 256 CPUs specifically.

I think we can just delete this comment and rely on having that rationale in
the commit message. We can find that with git-log and git-blame.

With this comment gone, the patch itself looks fine to me, but as above the
commit message needs to be cleaned up and it'd be *really* helpful if you could
send this a git formatted patch.

Mark.

> +config CPUMASK_OFFSTACK
> +	def_bool y
> +	depends on NR_CPUS > 256
> 
>   config HOTPLUG_CPU
>   	bool "Support for hot-pluggable CPUs"
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From andrea.porta at suse.com  Wed Feb  7 02:24:06 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Wed,  7 Feb 2024 11:24:06 +0100
Subject: [PATCH 00/12] Add support for BCM2712 DMA engine
In-Reply-To: <ZcM9I-U3w7xRcWVt@matsya>
References: <ZcM9I-U3w7xRcWVt@matsya>
Message-ID: <20240207102406.6672-1-andrea.porta@suse.com>

I was utterly inclined to unify all tags, then I realized that
could be simpler for anyone working on it to be able to grep
the patch subjects as they are for an easier mapping to the commit
from the vendor tree. But I see the point and I agree with you, so 
the next series version will have 'dmaengine: bcm2835:'.

Thanks


From dharma.b at microchip.com  Wed Feb  7 02:27:58 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Wed, 7 Feb 2024 15:57:58 +0530
Subject: [PATCH v3 0/4] LVDS Controller Support for SAM9X75 SoC
Message-ID: <20240207102802.200220-1-dharma.b@microchip.com>

This patch series introduces LVDS controller support for the SAM9X75 SoC. The
LVDS controller is designed to work with Microchip's sam9x7 series
System-on-Chip (SoC) devices, providing Low Voltage Differential Signaling
capabilities.

Patch series Changelog:
- Include configs: at91: Enable LVDS serializer

The Individual Changelogs are available on the respective patches.

Dharma Balasubiramani (4):
  dt-bindings: display: bridge: add sam9x75-lvds compatible
  drm/bridge: add lvds controller support for sam9x7
  MAINTAINERS: add SAM9X7 SoC's LVDS controller
  ARM: configs: at91: Enable LVDS serializer support

 .../bridge/microchip,sam9x75-lvds.yaml        |  55 +++++
 MAINTAINERS                                   |   8 +
 arch/arm/configs/at91_dt_defconfig            |   1 +
 drivers/gpu/drm/bridge/Kconfig                |   7 +
 drivers/gpu/drm/bridge/Makefile               |   1 +
 drivers/gpu/drm/bridge/microchip-lvds.c       | 228 ++++++++++++++++++
 6 files changed, 300 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/microchip,sam9x75-lvds.yaml
 create mode 100644 drivers/gpu/drm/bridge/microchip-lvds.c


base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
-- 
2.25.1



From dharma.b at microchip.com  Wed Feb  7 02:27:59 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Wed, 7 Feb 2024 15:57:59 +0530
Subject: [PATCH v3 1/4] dt-bindings: display: bridge: add sam9x75-lvds compatible
In-Reply-To: <20240207102802.200220-1-dharma.b@microchip.com>
References: <20240207102802.200220-1-dharma.b@microchip.com>
Message-ID: <20240207102802.200220-2-dharma.b@microchip.com>

Add the 'sam9x75-lvds' compatible binding, which describes the Low Voltage
Differential Signaling (LVDS) Controller found on some Microchip's sam9x7
series System-on-Chip (SoC) devices. This binding will be used to define
the properties and configuration for the LVDS Controller in DT.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
Changelog
v2 -> v3
- No changes.
v1 -> v2
- Remove '|' in description, as there is no formatting to preserve.
- Remove 'gclk' from clock-names as there is only one clock(pclk).
- Remove the unused headers and include only used ones.
- Change the compatible name specific to SoC (sam9x75) instead of entire series.
- Change file name to match the compatible name.
---
 .../bridge/microchip,sam9x75-lvds.yaml        | 55 +++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/microchip,sam9x75-lvds.yaml

diff --git a/Documentation/devicetree/bindings/display/bridge/microchip,sam9x75-lvds.yaml b/Documentation/devicetree/bindings/display/bridge/microchip,sam9x75-lvds.yaml
new file mode 100644
index 000000000000..862ef441ac9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/microchip,sam9x75-lvds.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/microchip,sam9x75-lvds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip SAM9X75 LVDS Controller
+
+maintainers:
+  - Dharma Balasubiramani <dharma.b at microchip.com>
+
+description:
+  The Low Voltage Differential Signaling Controller (LVDSC) manages data
+  format conversion from the LCD Controller internal DPI bus to OpenLDI
+  LVDS output signals. LVDSC functions include bit mapping, balanced mode
+  management, and serializer.
+
+properties:
+  compatible:
+    const: microchip,sam9x75-lvds
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Peripheral Bus Clock
+
+  clock-names:
+    items:
+      - const: pclk
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/at91.h>
+    lvds-controller at f8060000 {
+      compatible = "microchip,sam9x75-lvds";
+      reg = <0xf8060000 0x100>;
+      interrupts = <56 IRQ_TYPE_LEVEL_HIGH 0>;
+      clocks = <&pmc PMC_TYPE_PERIPHERAL 56>;
+      clock-names = "pclk";
+    };
-- 
2.25.1



From dharma.b at microchip.com  Wed Feb  7 02:28:00 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Wed, 7 Feb 2024 15:58:00 +0530
Subject: [PATCH v3 2/4] drm/bridge: add lvds controller support for sam9x7
In-Reply-To: <20240207102802.200220-1-dharma.b@microchip.com>
References: <20240207102802.200220-1-dharma.b@microchip.com>
Message-ID: <20240207102802.200220-3-dharma.b@microchip.com>

Add a new LVDS controller driver for sam9x7 which does the following:
- Prepares and enables the LVDS Peripheral clock
- Defines its connector type as DRM_MODE_CONNECTOR_LVDS and adds itself
to the global bridge list.
- Identifies its output endpoint as panel and adds it to the encoder
display pipeline
- Enables the LVDS serializer

Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
Changelog
v2 ->v3
- Correct Typo error "serializer".
- Consolidate get() and prepare() functions and use devm_clk_get_prepared().
- Remove unused variable 'ret' in probe().
- Use devm_pm_runtime_enable() and drop the mchp_lvds_remove().

v1 -> v2
- Drop 'res' variable and combine two lines into one.
- Handle deferred probe properly, use dev_err_probe().
- Don't print anything on deferred probe. Dropped print.
- Remove the MODULE_ALIAS and add MODULE_DEVICE_TABLE().
- symbol 'mchp_lvds_driver' was not declared. It should be static.
---
 drivers/gpu/drm/bridge/Kconfig          |   7 +
 drivers/gpu/drm/bridge/Makefile         |   1 +
 drivers/gpu/drm/bridge/microchip-lvds.c | 228 ++++++++++++++++++++++++
 3 files changed, 236 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/microchip-lvds.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 3e6a4e2044c0..74ca0edb4e0d 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -173,6 +173,13 @@ config DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW
 	  to DP++. This is used with the i.MX6 imx-ldb
 	  driver. You are likely to say N here.
 
+config DRM_MICROCHIP_LVDS_SERIALIZER
+	tristate "Microchip LVDS serializer support"
+	depends on OF
+	depends on DRM_ATMEL_HLCDC
+	help
+	  Support for Microchip's LVDS serializer.
+
 config DRM_NWL_MIPI_DSI
 	tristate "Northwest Logic MIPI DSI Host controller"
 	depends on DRM
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 2b892b7ed59e..e3804e93d324 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
 obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o
 obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o
 obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
+obj-$(CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER) += microchip-lvds.o
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
 obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
diff --git a/drivers/gpu/drm/bridge/microchip-lvds.c b/drivers/gpu/drm/bridge/microchip-lvds.c
new file mode 100644
index 000000000000..d3fd9d722e36
--- /dev/null
+++ b/drivers/gpu/drm/bridge/microchip-lvds.c
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Manikandan Muralidharan <manikandan.m at microchip.com>
+ * Author: Dharma Balasubiramani <dharma.b at microchip.com>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_graph.h>
+#include <linux/pinctrl/devinfo.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+
+#define LVDS_POLL_TIMEOUT_MS 1000
+
+/* LVDSC register offsets */
+#define LVDSC_CR	0x00
+#define LVDSC_CFGR	0x04
+#define LVDSC_SR	0x0C
+#define LVDSC_WPMR	0xE4
+
+/* Bitfields in LVDSC_CR (Control Register) */
+#define LVDSC_CR_SER_EN	BIT(0)
+
+/* Bitfields in LVDSC_CFGR (Configuration Register) */
+#define LVDSC_CFGR_PIXSIZE_24BITS	0
+#define LVDSC_CFGR_DEN_POL_HIGH		0
+#define LVDSC_CFGR_DC_UNBALANCED	0
+#define LVDSC_CFGR_MAPPING_JEIDA	BIT(6)
+
+/*Bitfields in LVDSC_SR */
+#define LVDSC_SR_CS	BIT(0)
+
+/* Bitfields in LVDSC_WPMR (Write Protection Mode Register) */
+#define LVDSC_WPMR_WPKEY_MASK	GENMASK(31, 8)
+#define LVDSC_WPMR_WPKEY_PSSWD	0x4C5644
+
+struct mchp_lvds {
+	struct device *dev;
+	void __iomem *regs;
+	struct clk *pclk;
+	int format; /* vesa or jeida format */
+	struct drm_panel *panel;
+	struct drm_bridge bridge;
+	struct drm_bridge *panel_bridge;
+};
+
+static inline struct mchp_lvds *bridge_to_lvds(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct mchp_lvds, bridge);
+}
+
+static inline u32 lvds_readl(struct mchp_lvds *lvds, u32 offset)
+{
+	return readl_relaxed(lvds->regs + offset);
+}
+
+static inline void lvds_writel(struct mchp_lvds *lvds, u32 offset, u32 val)
+{
+	writel_relaxed(val, lvds->regs + offset);
+}
+
+static void lvds_serialiser_on(struct mchp_lvds *lvds)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(LVDS_POLL_TIMEOUT_MS);
+
+	/* The LVDSC registers can only be written if WPEN is cleared */
+	lvds_writel(lvds, LVDSC_WPMR, (LVDSC_WPMR_WPKEY_PSSWD &
+				LVDSC_WPMR_WPKEY_MASK));
+
+	/* Wait for the status of configuration registers to be changed */
+	while (lvds_readl(lvds, LVDSC_SR) & LVDSC_SR_CS) {
+		if (time_after(jiffies, timeout)) {
+			dev_err(lvds->dev, "%s: timeout error\n", __func__);
+			return;
+		}
+		usleep_range(1000, 2000);
+	}
+
+	/* Configure the LVDSC */
+	lvds_writel(lvds, LVDSC_CFGR, (LVDSC_CFGR_MAPPING_JEIDA |
+				LVDSC_CFGR_DC_UNBALANCED |
+				LVDSC_CFGR_DEN_POL_HIGH |
+				LVDSC_CFGR_PIXSIZE_24BITS));
+
+	/* Enable the LVDS serializer */
+	lvds_writel(lvds, LVDSC_CR, LVDSC_CR_SER_EN);
+}
+
+static int mchp_lvds_attach(struct drm_bridge *bridge,
+			    enum drm_bridge_attach_flags flags)
+{
+	struct mchp_lvds *lvds = bridge_to_lvds(bridge);
+
+	bridge->encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
+
+	return drm_bridge_attach(bridge->encoder, lvds->panel_bridge,
+				 bridge, flags);
+}
+
+static void mchp_lvds_enable(struct drm_bridge *bridge)
+{
+	struct mchp_lvds *lvds = bridge_to_lvds(bridge);
+	int ret;
+
+	ret = clk_enable(lvds->pclk);
+	if (ret < 0) {
+		DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
+		return;
+	}
+
+	ret = pm_runtime_get_sync(lvds->dev);
+	if (ret < 0) {
+		DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
+		clk_disable(lvds->pclk);
+		return;
+	}
+
+	lvds_serialiser_on(lvds);
+}
+
+static void mchp_lvds_disable(struct drm_bridge *bridge)
+{
+	struct mchp_lvds *lvds = bridge_to_lvds(bridge);
+
+	pm_runtime_put(lvds->dev);
+	clk_disable(lvds->pclk);
+}
+
+static const struct drm_bridge_funcs mchp_lvds_bridge_funcs = {
+	.attach = mchp_lvds_attach,
+	.enable = mchp_lvds_enable,
+	.disable = mchp_lvds_disable,
+};
+
+static int mchp_lvds_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mchp_lvds *lvds;
+	struct device_node *port;
+
+	if (!dev->of_node)
+		return -ENODEV;
+
+	lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL);
+	if (!lvds)
+		return -ENOMEM;
+
+	lvds->dev = dev;
+
+	lvds->regs = devm_ioremap_resource(lvds->dev,
+			platform_get_resource(pdev, IORESOURCE_MEM, 0));
+	if (IS_ERR(lvds->regs))
+		return PTR_ERR(lvds->regs);
+
+	lvds->pclk = devm_clk_get_prepared(lvds->dev, "pclk");
+	if (IS_ERR(lvds->pclk))
+		return dev_err_probe(lvds->dev, PTR_ERR(lvds->pclk),
+				"could not get pclk_lvds prepared\n");
+
+	port = of_graph_get_remote_node(dev->of_node, 1, 0);
+	if (!port) {
+		DRM_DEV_ERROR(dev,
+			      "can't find port point, please init lvds panel port!\n");
+		return -EINVAL;
+	}
+
+	lvds->panel = of_drm_find_panel(port);
+	of_node_put(port);
+
+	if (IS_ERR(lvds->panel))
+		return -EPROBE_DEFER;
+
+	lvds->panel_bridge = devm_drm_panel_bridge_add(dev, lvds->panel);
+
+	if (IS_ERR(lvds->panel_bridge))
+		return PTR_ERR(lvds->panel_bridge);
+
+	lvds->bridge.of_node = dev->of_node;
+	lvds->bridge.type = DRM_MODE_CONNECTOR_LVDS;
+	lvds->bridge.funcs = &mchp_lvds_bridge_funcs;
+
+	dev_set_drvdata(dev, lvds);
+	devm_pm_runtime_enable(dev);
+
+	drm_bridge_add(&lvds->bridge);
+
+	return 0;
+}
+
+static const struct of_device_id mchp_lvds_dt_ids[] = {
+	{
+		.compatible = "microchip,sam9x75-lvds",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mchp_lvds_dt_ids);
+
+static struct platform_driver mchp_lvds_driver = {
+	.probe = mchp_lvds_probe,
+	.driver = {
+		   .name = "microchip-lvds",
+		   .of_match_table = mchp_lvds_dt_ids,
+	},
+};
+module_platform_driver(mchp_lvds_driver);
+
+MODULE_AUTHOR("Manikandan Muralidharan <manikandan.m at microchip.com>");
+MODULE_AUTHOR("Dharma Balasubiramani <dharma.b at microchip.com>");
+MODULE_DESCRIPTION("Low Voltage Differential Signaling Controller Driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From dharma.b at microchip.com  Wed Feb  7 02:28:01 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Wed, 7 Feb 2024 15:58:01 +0530
Subject: [PATCH v3 3/4] MAINTAINERS: add SAM9X7 SoC's LVDS controller
In-Reply-To: <20240207102802.200220-1-dharma.b@microchip.com>
References: <20240207102802.200220-1-dharma.b@microchip.com>
Message-ID: <20240207102802.200220-4-dharma.b@microchip.com>

Add the newly added LVDS controller for the SAM9X7 SoC to the existing
MAINTAINERS entry.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
Changelog
v2 -> v3
- Move the entry before "MICROCHIP SAMA5D2-COMPATIBLE ADC DRIVER".

v1 -> v2
- No Changes.
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a7c4cf8201e0..ce592b6cf375 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14216,6 +14216,14 @@ S:	Supported
 F:	Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml
 F:	drivers/pwm/pwm-atmel.c
 
+MICROCHIP SAM9x7-COMPATIBLE LVDS CONTROLLER
+M:	Manikandan Muralidharan <manikandan.m at microchip.com>
+M:	Dharma Balasubiramani <dharma.b at microchip.com>
+L:	dri-devel at lists.freedesktop.org
+S:	Supported
+F:	Documentation/devicetree/bindings/display/bridge/microchip,sam9x7-lvds.yaml
+F:	drivers/gpu/drm/bridge/microchip-lvds.c
+
 MICROCHIP SAMA5D2-COMPATIBLE ADC DRIVER
 M:	Eugen Hristev <eugen.hristev at microchip.com>
 L:	linux-iio at vger.kernel.org
-- 
2.25.1



From dharma.b at microchip.com  Wed Feb  7 02:28:02 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Wed, 7 Feb 2024 15:58:02 +0530
Subject: [PATCH v3 4/4] ARM: configs: at91: Enable LVDS serializer support
In-Reply-To: <20240207102802.200220-1-dharma.b@microchip.com>
References: <20240207102802.200220-1-dharma.b@microchip.com>
Message-ID: <20240207102802.200220-5-dharma.b@microchip.com>

Enable LVDS serializer support for display pipeline.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Acked-by: Hari Prasath Gujulan Elango <hari.prasathge at microchip.com>
Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
Changelog
v2 -> v3
- No Changes.
---
 arch/arm/configs/at91_dt_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index 71b5acc78187..6a7714beb099 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -143,6 +143,7 @@ CONFIG_VIDEO_OV2640=m
 CONFIG_VIDEO_OV7740=m
 CONFIG_DRM=y
 CONFIG_DRM_ATMEL_HLCDC=y
+CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER=y
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_PANEL_EDP=y
 CONFIG_FB_ATMEL=y
-- 
2.25.1



From oliver.upton at linux.dev  Wed Feb  7 02:40:08 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 7 Feb 2024 10:40:08 +0000
Subject: [PATCH v3 04/26] KVM: arm64: nv: Add sanitising to EL2
 configuration registers
In-Reply-To: <20240205103431.1104133-5-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
 <20240205103431.1104133-5-maz@kernel.org>
Message-ID: <ZcNeCACYeozbM_Dr@linux.dev>

On Mon, Feb 05, 2024 at 10:34:09AM +0000, Marc Zyngier wrote:
> +	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
> +	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS)))
> +		res0 |= (HCR_API | HCR_APK);

I think what you probably meant here is _ADDRESS and _GENERIC, right? Of
course, this has no actual effect on the code, since we don't allow one
without the other.

Maybe we can just change KVM's representation to a single flag to avoid
this pointless exercise.

> +	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TME, IMP))
> +		res0 |= BIT(39);
> +	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP))
> +		res0 |= (HCR_TEA | HCR_TERR);
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
> +		res0 |= HCR_TLOR;
> +	if (!kvm_has_feat(kvm, ID_AA64MMFR4_EL1, E2H0, IMP))
> +		res1 |= HCR_E2H;
> +	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
> +
>  out:
>  	mutex_unlock(&kvm->arch.config_lock);
>  
> -- 
> 2.39.2

-- 
Thanks,
Oliver


From antonio.borneo at foss.st.com  Wed Feb  7 02:46:04 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Wed, 7 Feb 2024 11:46:04 +0100
Subject: [PATCH] pinctrl: stm32: fix PM support for stm32mp257
Message-ID: <20240207104604.174843-1-antonio.borneo@foss.st.com>

The driver for stm32mp257 is missing the suspend callback in
struct dev_pm_ops.

Add the callback, using the common stm32_pinctrl_suspend()
function.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
Fixes: 619f8ca4a73d ("pinctrl: stm32: add stm32mp257 pinctrl support")
---
 drivers/pinctrl/stm32/pinctrl-stm32mp257.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/stm32/pinctrl-stm32mp257.c b/drivers/pinctrl/stm32/pinctrl-stm32mp257.c
index 73f091cd827e..23aebd4695e9 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32mp257.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32mp257.c
@@ -2562,7 +2562,7 @@ static const struct of_device_id stm32mp257_pctrl_match[] = {
 };
 
 static const struct dev_pm_ops stm32_pinctrl_dev_pm_ops = {
-	 SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, stm32_pinctrl_resume)
+	 SET_LATE_SYSTEM_SLEEP_PM_OPS(stm32_pinctrl_suspend, stm32_pinctrl_resume)
 };
 
 static struct platform_driver stm32mp257_pinctrl_driver = {

base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
-- 
2.34.1



From linus.walleij at linaro.org  Wed Feb  7 02:48:47 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 7 Feb 2024 11:48:47 +0100
Subject: [PATCH 1/2] pinctrl: mediatek: Drop bogus slew rate register
 range for MT8186
In-Reply-To: <20240131071910.3950450-1-wenst@chromium.org>
References: <20240131071910.3950450-1-wenst@chromium.org>
Message-ID: <CACRpkdbRY70+Er-=Xv338j68NgjEKZeD5FYW9GqFY-68sCBvgA@mail.gmail.com>

On Wed, Jan 31, 2024 at 8:19?AM Chen-Yu Tsai <wenst at chromium.org> wrote:

> The MT8186 does not support configuring pin slew rate. This is evident
> from both the datasheet, and the fact that the driver points the slew
> rate register range at the GPIO direction register range.
>
> Drop the bogus setting.
>
> Fixes: 8b483bda1e46 ("pinctrl: add pinctrl driver on mt8186")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Patches applied!

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Feb  7 02:56:44 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 7 Feb 2024 11:56:44 +0100
Subject: [PATCH RFC 0/2] pinctrl: bcm2835: Implement pin_conf_get
In-Reply-To: <20240204165852.166157-1-wahrenst@gmx.net>
References: <20240204165852.166157-1-wahrenst@gmx.net>
Message-ID: <CACRpkda=VsgiH0-iJVLry4hy6kLeJ_20mzMs8OrqR6Fr8eAp-g@mail.gmail.com>

On Sun, Feb 4, 2024 at 5:59?PM Stefan Wahren <wahrenst at gmx.net> wrote:

> For years, the Raspberry Pi users relied on userspace programs to read
> the pin configuration. In the meantime, it has become apparent that this
> approach has reached its limits for various reasons.
>
> This patch series now attempts to improve the debugging possibilities on
> the kernel side in order to reduce the dependency on these userspace
> programs.
>
> Stefan Wahren (2):
>   pinctrl: bcm2835: Implement bcm2835_pinconf_get
>   pinctrl: bcm2835: Implement bcm2711_pinconf_get

I don't see any problems with this, can I just apply the patches or do you
want to first resend them as non-RFC?

Yours,
Linus Walleij


From maz at kernel.org  Wed Feb  7 02:57:26 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 07 Feb 2024 10:57:26 +0000
Subject: [PATCH v3 04/26] KVM: arm64: nv: Add sanitising to EL2 configuration registers
In-Reply-To: <ZcNeCACYeozbM_Dr@linux.dev>
References: <20240205103431.1104133-1-maz@kernel.org>
	<20240205103431.1104133-5-maz@kernel.org>
	<ZcNeCACYeozbM_Dr@linux.dev>
Message-ID: <86plx85yp5.wl-maz@kernel.org>

On Wed, 07 Feb 2024 10:40:08 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Mon, Feb 05, 2024 at 10:34:09AM +0000, Marc Zyngier wrote:
> > +	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
> > +	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS)))
> > +		res0 |= (HCR_API | HCR_APK);
> 
> I think what you probably meant here is _ADDRESS and _GENERIC, right? Of
> course, this has no actual effect on the code, since we don't allow one
> without the other.

Gah. Embarrassing. But yes, harmless as we set both bits all the time.

> Maybe we can just change KVM's representation to a single flag to avoid
> this pointless exercise.

Yeah, it's been on my list of things to cleanup for a while. I'll look
into it for a separate patch.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From oliver.upton at linux.dev  Wed Feb  7 02:57:49 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 7 Feb 2024 10:57:49 +0000
Subject: [PATCH v3 05/26] KVM: arm64: nv: Add sanitising to VNCR-backed
 FGT sysregs
In-Reply-To: <20240205103431.1104133-6-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
 <20240205103431.1104133-6-maz@kernel.org>
Message-ID: <ZcNiLYCbacgnRuaw@linux.dev>

On Mon, Feb 05, 2024 at 10:34:10AM +0000, Marc Zyngier wrote:
> Fine Grained Traps are controlled by a whole bunch of features.
> Each one of them must be checked and the corresponding masks
> computed so that we don't let the guest apply traps it shouldn't
> be using.
> 
> This takes care of HFG[IRW]TR_EL2, HDFG[RW]TR_EL2, and HAFGRTR_EL2.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Reviewed-by: Joey Gouly <joey.gouly at arm.com>
> ---
>  arch/arm64/kvm/nested.c | 128 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 128 insertions(+)
> 
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index a8fe0f970e04..31c4ce0439d6 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -265,6 +265,134 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
>  		res1 |= HCR_E2H;
>  	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
>  
> +	/* HFG[RW]TR_EL2 */
> +	res0 = res1 = 0;
> +	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
> +	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS)))

Same thing here w/ the different flags.

> +	/* HDFG[RW]TR_EL2 */
> +	res0 = res1 = 0;
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
> +		res0 |= HDFGRTR_EL2_OSDLR_EL1;
> +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
> +		res0 |= (HDFGRTR_EL2_PMEVCNTRn_EL0 | HDFGRTR_EL2_PMEVTYPERn_EL0 |
> +			 HDFGRTR_EL2_PMCCFILTR_EL0 | HDFGRTR_EL2_PMCCNTR_EL0 |
> +			 HDFGRTR_EL2_PMCNTEN | HDFGRTR_EL2_PMINTEN |
> +			 HDFGRTR_EL2_PMOVS | HDFGRTR_EL2_PMSELR_EL0 |
> +			 HDFGRTR_EL2_PMMIR_EL1 | HDFGRTR_EL2_PMUSERENR_EL0 |
> +			 HDFGRTR_EL2_PMCEIDn_EL0);

I think you're missing HDFGWTR_EL2_PMSWINC_EL0 and HDFGWTR_EL2_PMCR_EL0
here. Silly write-only and read-only registers...

-- 
Thanks,
Oliver


From andrea.porta at suse.com  Wed Feb  7 02:58:47 2024
From: andrea.porta at suse.com (Andrea della Porta)
Date: Wed,  7 Feb 2024 11:58:47 +0100
Subject: [PATCH v2] arm64: Add the arm64.no32bit_el0 command line option
Message-ID: <20240207105847.7739-1-andrea.porta@suse.com>

Introducing the field 'el0' to the idreg-override for register
ID_AA64PFR0_EL1. This field is also aliased to the new kernel
command line option 'arm64.no32bit_el0' as a more recognizable
and mnemonic name to disable the execution of 32 bit userspace
applications (i.e. avoid Aarch32 execution state in EL0) from
kernel command line.

Changes in V2:
- fixed the order of appearance of arm64.no32bit_el0 entry in
  kernel-parameters.txt documentation.

Link: https://lore.kernel.org/r/ZVTleETzfFUchs77 at apocalypse
Signed-off-by: Andrea della Porta <andrea.porta at suse.com>
---
 Documentation/admin-guide/kernel-parameters.txt | 3 +++
 arch/arm64/kernel/idreg-override.c              | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 65731b060e3f..fa7cdf2f4f3a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -415,6 +415,9 @@
 	arcrimi=	[HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards
 			Format: <io>,<irq>,<nodeID>
 
+	arm64.no32bit_el0 [ARM64] Unconditionally disable the execution of
+			32 bit applications
+
 	arm64.nobti	[ARM64] Unconditionally disable Branch Target
 			Identification support
 
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index e30fd9e32ef3..642cda19e42d 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -86,6 +86,7 @@ static const struct ftr_set_desc pfr0 __prel64_initconst = {
 	.override	= &id_aa64pfr0_override,
 	.fields		= {
 	        FIELD("sve", ID_AA64PFR0_EL1_SVE_SHIFT, pfr0_sve_filter),
+		FIELD("el0", ID_AA64PFR0_EL1_EL0_SHIFT, NULL),
 		{}
 	},
 };
@@ -197,6 +198,7 @@ static const struct {
 	{ "arm64.nomops",		"id_aa64isar2.mops=0" },
 	{ "arm64.nomte",		"id_aa64pfr1.mte=0" },
 	{ "nokaslr",			"arm64_sw.nokaslr=1" },
+	{ "arm64.no32bit_el0",		"id_aa64pfr0.el0=1" },
 };
 
 static int __init parse_hexdigit(const char *p, u64 *v)
-- 
2.41.0



From vkoul at kernel.org  Wed Feb  7 03:09:05 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 7 Feb 2024 12:09:05 +0100
Subject: [PATCH v5 0/2] phy: mtk-mipi-csi: add driver for CSI phy
In-Reply-To: <20240111101504.468169-1-jstephan@baylibre.com>
References: <20240111101504.468169-1-jstephan@baylibre.com>
Message-ID: <ZcNk0VylU2mBsewy@matsya>

On 11-01-24, 11:14, Julien Stephan wrote:
> Adding a new driver for the MIPI CSI CD-PHY module v 0.5 embedded in
> some Mediatek soc, such as the MT8365

You would want to fix the way you send patches, the series is disjoint.
I had to apply them manually, but please fix your process

-- 
~Vinod


From oliver.upton at linux.dev  Wed Feb  7 03:09:08 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 7 Feb 2024 11:09:08 +0000
Subject: [PATCH v3 05/26] KVM: arm64: nv: Add sanitising to VNCR-backed
 FGT sysregs
In-Reply-To: <ZcNiLYCbacgnRuaw@linux.dev>
References: <20240205103431.1104133-1-maz@kernel.org>
 <20240205103431.1104133-6-maz@kernel.org>
 <ZcNiLYCbacgnRuaw@linux.dev>
Message-ID: <ZcNk1OC-qGcdF1fl@linux.dev>

On Wed, Feb 07, 2024 at 10:57:49AM +0000, Oliver Upton wrote:
> On Mon, Feb 05, 2024 at 10:34:10AM +0000, Marc Zyngier wrote:
> > Fine Grained Traps are controlled by a whole bunch of features.
> > Each one of them must be checked and the corresponding masks
> > computed so that we don't let the guest apply traps it shouldn't
> > be using.
> > 
> > This takes care of HFG[IRW]TR_EL2, HDFG[RW]TR_EL2, and HAFGRTR_EL2.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > Reviewed-by: Joey Gouly <joey.gouly at arm.com>
> > ---
> >  arch/arm64/kvm/nested.c | 128 ++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 128 insertions(+)
> > 
> > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> > index a8fe0f970e04..31c4ce0439d6 100644
> > --- a/arch/arm64/kvm/nested.c
> > +++ b/arch/arm64/kvm/nested.c
> > @@ -265,6 +265,134 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
> >  		res1 |= HCR_E2H;
> >  	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
> >  
> > +	/* HFG[RW]TR_EL2 */
> > +	res0 = res1 = 0;
> > +	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
> > +	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS)))
> 
> Same thing here w/ the different flags.
> 
> > +	/* HDFG[RW]TR_EL2 */
> > +	res0 = res1 = 0;
> > +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
> > +		res0 |= HDFGRTR_EL2_OSDLR_EL1;
> > +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
> > +		res0 |= (HDFGRTR_EL2_PMEVCNTRn_EL0 | HDFGRTR_EL2_PMEVTYPERn_EL0 |
> > +			 HDFGRTR_EL2_PMCCFILTR_EL0 | HDFGRTR_EL2_PMCCNTR_EL0 |
> > +			 HDFGRTR_EL2_PMCNTEN | HDFGRTR_EL2_PMINTEN |
> > +			 HDFGRTR_EL2_PMOVS | HDFGRTR_EL2_PMSELR_EL0 |
> > +			 HDFGRTR_EL2_PMMIR_EL1 | HDFGRTR_EL2_PMUSERENR_EL0 |
> > +			 HDFGRTR_EL2_PMCEIDn_EL0);
> 
> I think you're missing HDFGWTR_EL2_PMSWINC_EL0 and HDFGWTR_EL2_PMCR_EL0
> here. Silly write-only and read-only registers...

I can't read. Looks like you're doing this a few lines down.

-- 
Thanks,
Oliver


From will at kernel.org  Wed Feb  7 03:12:52 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 7 Feb 2024 11:12:52 +0000
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com>
 <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
Message-ID: <20240207111252.GA22167@willie-the-truck>

On Sat, Jan 27, 2024 at 01:04:15PM +0800, Nanyong Sun wrote:
> 
> On 2024/1/26 2:06, Catalin Marinas wrote:
> > On Sat, Jan 13, 2024 at 05:44:33PM +0800, Nanyong Sun wrote:
> > > HVO was previously disabled on arm64 [1] due to the lack of necessary
> > > BBM(break-before-make) logic when changing page tables.
> > > This set of patches fix this by adding necessary BBM sequence when
> > > changing page table, and supporting vmemmap page fault handling to
> > > fixup kernel address translation fault if vmemmap is concurrently accessed.
> > I'm not keen on this approach. I'm not even sure it's safe. In the
> > second patch, you take the init_mm.page_table_lock on the fault path but
> > are we sure this is unlocked when the fault was taken?
> I think this situation is impossible. In the implementation of the second
> patch, when the page table is being corrupted
> (the time window when a page fault may occur), vmemmap_update_pte() already
> holds the init_mm.page_table_lock,
> and unlock it until page table update is done.Another thread could not hold
> the init_mm.page_table_lock and
> also trigger a page fault at the same time.
> If I have missed any points in my thinking, please correct me. Thank you.

It still strikes me as incredibly fragile to handle the fault and trying
to reason about all the users of 'struct page' is impossible. For example,
can the fault happen from irq context?

If we want to optimise the vmemmap mapping for arm64, I think we need to
consider approaches which avoid the possibility of the fault altogether.
It's more complicated to implement, but I think it would be a lot more
robust.

Andrew -- please can you drop these from -next?

Thanks,

Will


From maz at kernel.org  Wed Feb  7 03:13:10 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 07 Feb 2024 11:13:10 +0000
Subject: [PATCH v3 05/26] KVM: arm64: nv: Add sanitising to VNCR-backed FGT sysregs
In-Reply-To: <ZcNk1OC-qGcdF1fl@linux.dev>
References: <20240205103431.1104133-1-maz@kernel.org>
	<20240205103431.1104133-6-maz@kernel.org>
	<ZcNiLYCbacgnRuaw@linux.dev>
	<ZcNk1OC-qGcdF1fl@linux.dev>
Message-ID: <86o7cs5xyx.wl-maz@kernel.org>

On Wed, 07 Feb 2024 11:09:08 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Wed, Feb 07, 2024 at 10:57:49AM +0000, Oliver Upton wrote:
> > On Mon, Feb 05, 2024 at 10:34:10AM +0000, Marc Zyngier wrote:
> > > Fine Grained Traps are controlled by a whole bunch of features.
> > > Each one of them must be checked and the corresponding masks
> > > computed so that we don't let the guest apply traps it shouldn't
> > > be using.
> > > 
> > > This takes care of HFG[IRW]TR_EL2, HDFG[RW]TR_EL2, and HAFGRTR_EL2.
> > > 
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > Reviewed-by: Joey Gouly <joey.gouly at arm.com>
> > > ---
> > >  arch/arm64/kvm/nested.c | 128 ++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 128 insertions(+)
> > > 
> > > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> > > index a8fe0f970e04..31c4ce0439d6 100644
> > > --- a/arch/arm64/kvm/nested.c
> > > +++ b/arch/arm64/kvm/nested.c
> > > @@ -265,6 +265,134 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
> > >  		res1 |= HCR_E2H;
> > >  	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
> > >  
> > > +	/* HFG[RW]TR_EL2 */
> > > +	res0 = res1 = 0;
> > > +	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
> > > +	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS)))
> > 
> > Same thing here w/ the different flags.

Yup, fixed both occurrences already.

> > 
> > > +	/* HDFG[RW]TR_EL2 */
> > > +	res0 = res1 = 0;
> > > +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
> > > +		res0 |= HDFGRTR_EL2_OSDLR_EL1;
> > > +	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
> > > +		res0 |= (HDFGRTR_EL2_PMEVCNTRn_EL0 | HDFGRTR_EL2_PMEVTYPERn_EL0 |
> > > +			 HDFGRTR_EL2_PMCCFILTR_EL0 | HDFGRTR_EL2_PMCCNTR_EL0 |
> > > +			 HDFGRTR_EL2_PMCNTEN | HDFGRTR_EL2_PMINTEN |
> > > +			 HDFGRTR_EL2_PMOVS | HDFGRTR_EL2_PMSELR_EL0 |
> > > +			 HDFGRTR_EL2_PMMIR_EL1 | HDFGRTR_EL2_PMUSERENR_EL0 |
> > > +			 HDFGRTR_EL2_PMCEIDn_EL0);
> > 
> > I think you're missing HDFGWTR_EL2_PMSWINC_EL0 and HDFGWTR_EL2_PMCR_EL0
> > here. Silly write-only and read-only registers...
> 
> I can't read. Looks like you're doing this a few lines down.

Yeah, it's a bit tucked away to reuse the previously constructed
masks.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From tudor.ambarus at linaro.org  Wed Feb  7 03:15:13 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 11:15:13 +0000
Subject: [PATCH v2 1/4] spi: dt-bindings: samsung: add google,gs101-spi compatible
In-Reply-To: <20240207111516.2563218-1-tudor.ambarus@linaro.org>
References: <20240207111516.2563218-1-tudor.ambarus@linaro.org>
Message-ID: <20240207111516.2563218-2-tudor.ambarus@linaro.org>

Add "google,gs101-spi" dedicated compatible for representing SPI of
Google GS101 SoC.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Acked-by: Andi Shyti <andi.shyti at kernel.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.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 f71099852653..2f0a0835ecfb 100644
--- a/Documentation/devicetree/bindings/spi/samsung,spi.yaml
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     oneOf:
       - enum:
+          - google,gs101-spi
           - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
           - samsung,s3c6410-spi
           - samsung,s5pv210-spi # for S5PV210 and S5PC110
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 03:15:14 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 11:15:14 +0000
Subject: [PATCH v2 2/4] spi: s3c64xx: prepare for a different flavor of iowrite rep
In-Reply-To: <20240207111516.2563218-1-tudor.ambarus@linaro.org>
References: <20240207111516.2563218-1-tudor.ambarus@linaro.org>
Message-ID: <20240207111516.2563218-3-tudor.ambarus@linaro.org>

There are SoCs (gs101) that allow only 32 bit register accesses. As the
requirement is rare enough, for those SoCs we'll open code in the driver
some s3c64xx_iowrite{8,16}_32_rep() accessors. Prepare for such addition.

Suggested-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 35 +++++++++++++++++++++--------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 7f7eb8f742e4..eb79c6e4f509 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -414,6 +414,26 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
 
 }
 
+static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd,
+				struct spi_transfer *xfer)
+{
+	void __iomem *addr = sdd->regs + S3C64XX_SPI_TX_DATA;
+	const void *buf = xfer->tx_buf;
+	unsigned int len = xfer->len;
+
+	switch (sdd->cur_bpw) {
+	case 32:
+		iowrite32_rep(addr, buf, len / 4);
+		break;
+	case 16:
+		iowrite16_rep(addr, buf, len / 2);
+		break;
+	default:
+		iowrite8_rep(addr, buf, len);
+		break;
+	}
+}
+
 static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 				    struct spi_transfer *xfer, int dma_mode)
 {
@@ -447,20 +467,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
 			ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
 		} else {
-			switch (sdd->cur_bpw) {
-			case 32:
-				iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
-					xfer->tx_buf, xfer->len / 4);
-				break;
-			case 16:
-				iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
-					xfer->tx_buf, xfer->len / 2);
-				break;
-			default:
-				iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
-					xfer->tx_buf, xfer->len);
-				break;
-			}
+			s3c64xx_iowrite_rep(sdd, xfer);
 		}
 	}
 
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 03:15:12 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 11:15:12 +0000
Subject: [PATCH v2 0/4] spi: s3c64xx: add support for google,gs101-spi
Message-ID: <20240207111516.2563218-1-tudor.ambarus@linaro.org>

This applies on Mark's for-next branch. It can be queued before the
simple cleanup patches.

v2:
- drop the include linux/types.h patch
- patch 2 is a preparation step as per Sam's suggestion
- contrary to Sam's suggestion, I kept the style for the
  s3c64xx_iowrite{8,16}_32_rep() methods, to be consistent with the
  generic implementations from asm-generic/io.h.
- s/just/only
- collect R-b tags.

v1:
https://lore.kernel.org/linux-spi/20240206085238.1208256-1-tudor.ambarus at linaro.org/

v1 was derived from:
https://lore.kernel.org/linux-spi/20240125145007.748295-1-tudor.ambarus at linaro.org/

Tudor Ambarus (4):
  spi: dt-bindings: samsung: add google,gs101-spi compatible
  spi: s3c64xx: prepare for a different flavor of iowrite rep
  spi: s3c64xx: add s3c64xx_iowrite{8,16}_32_rep accessors
  spi: s3c64xx: add support for google,gs101-spi

 .../devicetree/bindings/spi/samsung,spi.yaml  |  1 +
 drivers/spi/spi-s3c64xx.c                     | 85 +++++++++++++++----
 2 files changed, 71 insertions(+), 15 deletions(-)

-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 03:15:15 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 11:15:15 +0000
Subject: [PATCH v2 3/4] spi: s3c64xx: add s3c64xx_iowrite{8,16}_32_rep accessors
In-Reply-To: <20240207111516.2563218-1-tudor.ambarus@linaro.org>
References: <20240207111516.2563218-1-tudor.ambarus@linaro.org>
Message-ID: <20240207111516.2563218-4-tudor.ambarus@linaro.org>

Allow SoCs that require 32 bits register accesses to write data in
chunks of 8 or 16 bits. One SoC that requires 32 bit register accesses
is the google gs101. The operation is rare, thus open code it in the
driver rather than making it generic (through asm-generic/io.h).

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index eb79c6e4f509..014fcc933c90 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -142,6 +142,7 @@ struct s3c64xx_spi_dma_data {
  *	prescaler unit.
  * @clk_ioclk: True if clock is present on this device
  * @has_loopback: True if loopback mode can be supported
+ * @use_32bit_io: True if the SoC allows only 32-bit register accesses.
  *
  * The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
  * differ in some aspects such as the size of the fifo and spi bus clock
@@ -158,6 +159,7 @@ struct s3c64xx_spi_port_config {
 	bool	clk_from_cmu;
 	bool	clk_ioclk;
 	bool	has_loopback;
+	bool	use_32bit_io;
 };
 
 /**
@@ -414,6 +416,30 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
 
 }
 
+static void s3c64xx_iowrite8_32_rep(volatile void __iomem *addr,
+				    const void *buffer, unsigned int count)
+{
+	if (count) {
+		const u8 *buf = buffer;
+
+		do {
+			__raw_writel(*buf++, addr);
+		} while (--count);
+	}
+}
+
+static void s3c64xx_iowrite16_32_rep(volatile void __iomem *addr,
+				     const void *buffer, unsigned int count)
+{
+	if (count) {
+		const u16 *buf = buffer;
+
+		do {
+			__raw_writel(*buf++, addr);
+		} while (--count);
+	}
+}
+
 static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd,
 				struct spi_transfer *xfer)
 {
@@ -426,10 +452,16 @@ static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd,
 		iowrite32_rep(addr, buf, len / 4);
 		break;
 	case 16:
-		iowrite16_rep(addr, buf, len / 2);
+		if (sdd->port_conf->use_32bit_io)
+			s3c64xx_iowrite16_32_rep(addr, buf, len / 2);
+		else
+			iowrite16_rep(addr, buf, len / 2);
 		break;
 	default:
-		iowrite8_rep(addr, buf, len);
+		if (sdd->port_conf->use_32bit_io)
+			s3c64xx_iowrite8_32_rep(addr, buf, len);
+		else
+			iowrite8_rep(addr, buf, len);
 		break;
 	}
 }
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 03:15:16 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 11:15:16 +0000
Subject: [PATCH v2 4/4] spi: s3c64xx: add support for google,gs101-spi
In-Reply-To: <20240207111516.2563218-1-tudor.ambarus@linaro.org>
References: <20240207111516.2563218-1-tudor.ambarus@linaro.org>
Message-ID: <20240207111516.2563218-5-tudor.ambarus@linaro.org>

Add support for GS101 SPI. GS101 integrates 16 SPI nodes, all with 64
bytes FIFOs. GS101 allows just 32 bit register accesses, otherwise a
Serror Interrupt is raised. Do the write reg accesses in 32 bits.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 014fcc933c90..7ab3f3c2e9aa 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -17,7 +17,7 @@
 
 #include <linux/platform_data/spi-s3c64xx.h>
 
-#define MAX_SPI_PORTS		12
+#define MAX_SPI_PORTS		16
 #define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1)
 #define AUTOSUSPEND_TIMEOUT	2000
 
@@ -1534,6 +1534,19 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
 	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
 };
 
+static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
+	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+			    0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
+	.clk_div	= 4,
+	.high_speed	= true,
+	.clk_from_cmu	= true,
+	.has_loopback	= true,
+	.use_32bit_io	= true,
+	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
+};
+
 static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
 	{
 		.name		= "s3c2443-spi",
@@ -1546,6 +1559,9 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
 };
 
 static const struct of_device_id s3c64xx_spi_dt_match[] = {
+	{ .compatible = "google,gs101-spi",
+			.data = &gs101_spi_port_config,
+	},
 	{ .compatible = "samsung,s3c2443-spi",
 			.data = (void *)&s3c2443_spi_port_config,
 	},
-- 
2.43.0.687.g38aa6559b0-goog



From willy at infradead.org  Wed Feb  7 03:21:17 2024
From: willy at infradead.org (Matthew Wilcox)
Date: Wed, 7 Feb 2024 11:21:17 +0000
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <20240207111252.GA22167@willie-the-truck>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com>
 <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
Message-ID: <ZcNnrdlb3fe0kGHK@casper.infradead.org>

On Wed, Feb 07, 2024 at 11:12:52AM +0000, Will Deacon wrote:
> On Sat, Jan 27, 2024 at 01:04:15PM +0800, Nanyong Sun wrote:
> > 
> > On 2024/1/26 2:06, Catalin Marinas wrote:
> > > On Sat, Jan 13, 2024 at 05:44:33PM +0800, Nanyong Sun wrote:
> > > > HVO was previously disabled on arm64 [1] due to the lack of necessary
> > > > BBM(break-before-make) logic when changing page tables.
> > > > This set of patches fix this by adding necessary BBM sequence when
> > > > changing page table, and supporting vmemmap page fault handling to
> > > > fixup kernel address translation fault if vmemmap is concurrently accessed.
> > > I'm not keen on this approach. I'm not even sure it's safe. In the
> > > second patch, you take the init_mm.page_table_lock on the fault path but
> > > are we sure this is unlocked when the fault was taken?
> > I think this situation is impossible. In the implementation of the second
> > patch, when the page table is being corrupted
> > (the time window when a page fault may occur), vmemmap_update_pte() already
> > holds the init_mm.page_table_lock,
> > and unlock it until page table update is done.Another thread could not hold
> > the init_mm.page_table_lock and
> > also trigger a page fault at the same time.
> > If I have missed any points in my thinking, please correct me. Thank you.
> 
> It still strikes me as incredibly fragile to handle the fault and trying
> to reason about all the users of 'struct page' is impossible. For example,
> can the fault happen from irq context?

The pte lock cannot be taken in irq context (which I think is what
you're asking?)  While it is not possible to reason about all users of
struct page, we are somewhat relieved of that work by noting that this is
only for hugetlbfs, so we don't need to reason about slab, page tables,
netmem or zsmalloc.

> If we want to optimise the vmemmap mapping for arm64, I think we need to
> consider approaches which avoid the possibility of the fault altogether.
> It's more complicated to implement, but I think it would be a lot more
> robust.
> 
> Andrew -- please can you drop these from -next?
> 
> Thanks,
> 
> Will


From wahrenst at gmx.net  Wed Feb  7 03:33:55 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Wed, 7 Feb 2024 12:33:55 +0100
Subject: [PATCH RFC 0/2] pinctrl: bcm2835: Implement pin_conf_get
In-Reply-To: <CACRpkda=VsgiH0-iJVLry4hy6kLeJ_20mzMs8OrqR6Fr8eAp-g@mail.gmail.com>
References: <20240204165852.166157-1-wahrenst@gmx.net>
 <CACRpkda=VsgiH0-iJVLry4hy6kLeJ_20mzMs8OrqR6Fr8eAp-g@mail.gmail.com>
Message-ID: <1709f26f-0486-4856-8b2d-ba5e6fd492e2@gmx.net>

Hi Linus,

Am 07.02.24 um 11:56 schrieb Linus Walleij:
> On Sun, Feb 4, 2024 at 5:59?PM Stefan Wahren <wahrenst at gmx.net> wrote:
>
>> For years, the Raspberry Pi users relied on userspace programs to read
>> the pin configuration. In the meantime, it has become apparent that this
>> approach has reached its limits for various reasons.
>>
>> This patch series now attempts to improve the debugging possibilities on
>> the kernel side in order to reduce the dependency on these userspace
>> programs.
>>
>> Stefan Wahren (2):
>>    pinctrl: bcm2835: Implement bcm2835_pinconf_get
>>    pinctrl: bcm2835: Implement bcm2711_pinconf_get
> I don't see any problems with this, can I just apply the patches or do you
> want to first resend them as non-RFC?
since the second patch hasn't been tested with BCM7211, it would be nice
to get a feedback from Florian or someone else with this hardware?

Best regards
>
> Yours,
> Linus Walleij
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From fancer.lancer at gmail.com  Wed Feb  7 03:34:33 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Wed, 7 Feb 2024 14:34:33 +0300
Subject: [PATCH] stmmac: Fix incorrect dereference in stmmac_*_interrupt()
In-Reply-To: <20240206150704.GD1104779@kernel.org>
References: <20240203150323.1041736-1-p.sakharov@ispras.ru>
 <20240206150704.GD1104779@kernel.org>
Message-ID: <tg2au3a524douxq6k37aa73zuotlx5sl6hbcokm7xwy3bumqxc@lothlyjh6ksg>

On Tue, Feb 06, 2024 at 03:07:04PM +0000, Simon Horman wrote:
> On Sat, Feb 03, 2024 at 06:03:21PM +0300, Pavel Sakharov wrote:
> > If 'dev' is NULL, the 'priv' variable has an incorrect address when
> > dereferencing calling netdev_err().
> > 
> > Pass 'dev' instead of 'priv->dev" to the function.
> > 
> > Found by Linux Verification Center (linuxtesting.org) with SVACE.
> > 
> > Signed-off-by: Pavel Sakharov <p.sakharov at ispras.ru>
> 
> Thanks Pavel,
> 
> I agree with your analysis that this can result in a NULL dereference.
> And that your proposed fix is good: netdev_err() can handle a NULL
> dev argument.
> 
> As this seems to be a fix I suggest it should be for net.
> And that it should be based on that tree and designated as such
> in the subject:
> 
> Subject: [PATCH net] ...
> 
> Also if it is a fix, it should have a fixes tag.
> Perhaps this one:
> 
> Fixes: 8532f613bc78 ("net: stmmac: introduce MSI Interrupt routines for mac, safety, RX & TX")
> 
> 
> I don't think there is a need to respin for the above, though please
> keep this in mind when posting Networking patches in future.
> 
> 
> Looking at the patch above, and stmmac_main.c, it seems that the following
> functions also suffer from a similar problem:
> 
> static irqreturn_t stmmac_msi_intr_tx(int irq, void *data)
> {
> 	struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)data;
> 	...
> 	dma_conf = container_of(tx_q, struct stmmac_dma_conf, tx_queue[chan]);
> 	priv = container_of(dma_conf, struct stmmac_priv, dma_conf);
> 
> 	if (unlikely(!data)) {
> 		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
> 		...
> 
> And stmmac_msi_intr_rx(), which follows a similar pattern
> to stmmac_msi_intr_tx().
> 
> I also note that in those functions "invalid dev pointer" seems misleading,
> perhaps it ought to be "invalid queue" pointer.
> 
> As these problems seem to all have been introduced at the same time,
> perhaps it is appropriate to fix them all in one patch?

IMO we can just drop these and the noted in the patch checks. Before
actually making a decision about that there are three general
questions we'd need to answer to:

1. Do we trust the IRQ-subsystem to supply a correct cookie pointer
specified during the IRQ request procedure?

2. Do we trust the driver code for correctly performing the IRQs
request?

3. If we don't trust to any of that then what is caused if the problem
happens and there is no sanity checks implemented?

Here are my thoughts regarding that:

1. If no dev_id sanity checks implemented in the handlers then having
the IRQ requested with NULL argument passed even though the handlers
imply the netdev pointer will for sure cause troubles right away since
the driver won't work and the system will likely crash. So it will be
spotted during the initial test/debug stage of the respective change.

2. If for some reason the IRQ subsystem supplied a NULL pointer
instead of the cookie pointer, then something is really wrong and the
entire system likely won't work correctly. If this case is possible
to happen then all the kernel IRQ handlers should have been
implemented with such sanity check, which I don't see in practice.

3. If IRQ was caused by the DW *MAC controller, but NULL pointer is
passed and the handler returns IRQ_NONE state, then the actual IRQ
won't be handled AFAICS causing the spurious IRQs detected. Eventually
the IRQ will be effectively disabled. In anyway the driver will stop
working. But even if this happens see points 1. and 2. for the
problem cause implications.

4. The common IRQ handler doesn't have such check in the driver.
Though unlike the rest of the handlers it's assigned with the
IRQF_SHARED flag which requires the cookie pointer passed. Anyway the
sanity check was removed from the common IRQ handler in the commit
f42234ffd531 ("stmmac: fix pointer check after utilization in
stmmac_interrupt") with a justification as being _paranoidal_ and
pointless in the respective context. But in about a year afterwards
the individual IRQ handlers were introduced with the same check but
this time in a bit more reasonable context. Still it doesn't make
the check existence less paranoidal.

5. I took a look at first 20 Ethernet device drivers. None of them has
such checks implemented even though about half of them request IRQs as
non-shared (so the cookie pointer is optional).

6. Finally the checks are implemented in the hard IRQ handlers for
which the less code the better.

To sum all the above up from my point of view the checks are redundant
of course unless we turn on the paranoidal mode and stop trusting the
driver code and the IRQ subsystem.

-Serge(y)

> 
> > ---
> >  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > index 4727f7be4f86..5ab5148013cd 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > @@ -5848,7 +5848,7 @@ static irqreturn_t stmmac_mac_interrupt(int irq, void *dev_id)
> >  	struct stmmac_priv *priv = netdev_priv(dev);
> > 
> >  	if (unlikely(!dev)) {
> > -		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
> > +		netdev_err(dev, "%s: invalid dev pointer\n", __func__);
> >  		return IRQ_NONE;
> >  	}
> > 
> > @@ -5868,7 +5868,7 @@ static irqreturn_t stmmac_safety_interrupt(int irq, void *dev_id)
> >  	struct stmmac_priv *priv = netdev_priv(dev);
> > 
> >  	if (unlikely(!dev)) {
> > -		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
> > +		netdev_err(dev, "%s: invalid dev pointer\n", __func__);
> >  		return IRQ_NONE;
> >  	}
> > 
> > 
> 


From ulf.hansson at linaro.org  Wed Feb  7 03:39:38 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 7 Feb 2024 12:39:38 +0100
Subject: [PATCH v3 0/5] PM: domains: Add helpers for multi PM domains to
 avoid open-coding
In-Reply-To: <20240130123951.236243-1-ulf.hansson@linaro.org>
References: <20240130123951.236243-1-ulf.hansson@linaro.org>
Message-ID: <CAPDyKFruKJhOLRLbxibF3ChDGMcJDvdOmCekRNTDYunbnKgQpw@mail.gmail.com>

On Tue, 30 Jan 2024 at 13:39, Ulf Hansson <ulf.hansson at linaro.org> wrote:
>
> Rafael, my plan is queue up this series via my pmdomain tree. Please let me know
> if you see any issues with that, especially around patch1.
>
> Updates in v3:
>         - Added tested-by, reviewed-by and suggested-by tags. No other changes
>         have been made.
>
> Updates in v2:
>         - Ccing Daniel Baluta and Iuliana Prodan the NXP remoteproc patches to
>         requests help with testing.
>         - Fixed NULL pointer bug in patch1, pointed out by Nikunj.
>         - Added some tested/reviewed-by tags.
>
> Attaching/detaching of a device to multiple PM domains has started to become a
> common operation for many drivers, typically during ->probe() and ->remove().
> In most cases, this has lead to lots of boilerplate code in the drivers.
>
> This series adds a pair of helper functions to manage the attach/detach of a
> device to its multiple PM domains. Moreover, a couple of drivers have been
> converted to use the new helpers as a proof of concept.
>
> Note 1)
> The changes in the drivers have only been compile tested, while the helpers
> have been tested along with a couple of local dummy drivers that I have hacked
> up to model both genpd providers and genpd consumers.
>
> Note 2)
> I was struggling to make up mind if we should have a separate helper to attach
> all available power-domains described in DT, rather than providing "NULL" to the
> dev_pm_domain_attach_list(). I decided not to, but please let me know if you
> prefer the other option.
>
> Note 3)
> For OPP integration, as a follow up I am striving to make the
> dev_pm_opp_attach_genpd() redundant. Instead I think we should move towards
> using dev_pm_opp_set_config()->_opp_set_required_devs(), which would allow us to
> use the helpers that $subject series is adding.
>
> Kind regards
> Ulf Hansson
>
> Ulf Hansson (5):
>   PM: domains: Add helper functions to attach/detach multiple PM domains
>   remoteproc: imx_dsp_rproc: Convert to
>     dev_pm_domain_attach|detach_list()
>   remoteproc: imx_rproc: Convert to dev_pm_domain_attach|detach_list()
>   remoteproc: qcom_q6v5_adsp: Convert to
>     dev_pm_domain_attach|detach_list()
>   media: venus: Convert to dev_pm_domain_attach|detach_list() for vcodec
>
>  drivers/base/power/common.c                   | 134 +++++++++++++++
>  drivers/media/platform/qcom/venus/core.c      |  12 +-
>  drivers/media/platform/qcom/venus/core.h      |   7 +-
>  .../media/platform/qcom/venus/pm_helpers.c    |  48 ++----
>  drivers/remoteproc/imx_dsp_rproc.c            |  82 +--------
>  drivers/remoteproc/imx_rproc.c                |  73 +-------
>  drivers/remoteproc/qcom_q6v5_adsp.c           | 160 ++++++++----------
>  include/linux/pm_domain.h                     |  38 +++++
>  8 files changed, 289 insertions(+), 265 deletions(-)
>
>

I have now applied this to my next branch to my pmdomain tree, to get
it more tested in linux-next.

Please let me know if there are objections to this or if any of you
want to provide an ack/tested/reviewed-by tag, thanks!

Kind regards
Uffe


From peter.griffin at linaro.org  Wed Feb  7 03:42:03 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 7 Feb 2024 11:42:03 +0000
Subject: [PATCH v2 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <99828589-c0b5-456d-b250-6ad3e6085a91@linaro.org>
References: <20240129211912.3068411-1-peter.griffin@linaro.org>
 <20240129211912.3068411-2-peter.griffin@linaro.org> <fb530eb8-e32b-4faf-81f3-efc334ebf241@linaro.org>
 <CADrjBPoQmTRsFYRtxBxdvAoKK816O8XN3=hOJ3vBt8wbbbk-=Q@mail.gmail.com> <99828589-c0b5-456d-b250-6ad3e6085a91@linaro.org>
Message-ID: <CADrjBPrWH8uFrFmn_CZpr+fAnPrzbDT4i9XuMXJqKfzeouPpKg@mail.gmail.com>

Hi Krzysztof,

Thanks for your review feedback.

On Mon, 5 Feb 2024 at 13:13, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 01/02/2024 13:51, Peter Griffin wrote:
> > Hi Krzysztof,
> >
> > On Tue, 30 Jan 2024 at 16:01, Krzysztof Kozlowski
> > <krzysztof.kozlowski at linaro.org> wrote:
> >>
> >> On 29/01/2024 22:19, Peter Griffin wrote:
> >>> Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> >>> security hardening reasons so that they are only accessible in el3 via an
> >>> SMC call.
> >>>
> >>> As most Exynos drivers that need to write PMU registers currently obtain a
> >>> regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> >>> is implemented in this driver using a custom regmap similar to syscon to
> >>> handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> >>> regmap like before. As regmaps abstract out the underlying register access
> >>> changes to the leaf drivers are minimal.
> >>>
> >>> A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> >>> that currently use syscon_regmap_lookup_by_phandle(). This also handles
> >>> deferred probing.
> >>>
> >>> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> >>> ---
> >>>  drivers/soc/samsung/exynos-pmu.c       | 227 ++++++++++++++++++++++++-
> >>>  include/linux/soc/samsung/exynos-pmu.h |  10 ++
> >>>  2 files changed, 236 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> >>> index 250537d7cfd6..7bcc144e53a2 100644
> >>> --- a/drivers/soc/samsung/exynos-pmu.c
> >>> +++ b/drivers/soc/samsung/exynos-pmu.c
> >>> @@ -5,6 +5,7 @@
> >>>  //
> >>>  // Exynos - CPU PMU(Power Management Unit) support
> >>>
> >>> +#include <linux/arm-smccc.h>
> >>>  #include <linux/of.h>
> >>>  #include <linux/of_address.h>
> >>>  #include <linux/mfd/core.h>
> >>> @@ -12,20 +13,159 @@
> >>>  #include <linux/of_platform.h>
> >>>  #include <linux/platform_device.h>
> >>>  #include <linux/delay.h>
> >>> +#include <linux/regmap.h>
> >>>
> >>>  #include <linux/soc/samsung/exynos-regs-pmu.h>
> >>>  #include <linux/soc/samsung/exynos-pmu.h>
> >>>
> >>>  #include "exynos-pmu.h"
> >>>
> >>> +static struct platform_driver exynos_pmu_driver;
> >>
> >> I don't understand why do you need it. You can have only one
> >> pmu_context. The moment you probe second one, previous becomes invalid.
> >>
> >> I guess you want to parse phandle and check if just in case if it points
> >> to the right device, but still the original code is not ready for two
> >> PMU devices. I say either this problem should be solved entirely,
> >> allowing two devices, or just compare device node from phandle with
> >> device node of exynos_pmu_context->dev and return -EINVAL on mismatches.
> >
> > Apologies I didn't answer your original question. This wasn't about
> > having partial support for multiple pmu devices. It is being used by
> > driver_find_device_by_of_node() in exynos_get_pmu_regmap_by_phandle()
> > to determine that the exynos-pmu device has probed and therefore a
> > pmu_context exists and a regmap has been created and can be returned
> > to the caller (as opposed to doing a -EPROBE_DEFER).
> >
> > Is there some better/other API you recommend for this purpose? Just
> > checking pmu_context directly seems racy, so I don't think we should
> > do that.
>
> Hm, I don't quite get why you cannot use of_find_device_by_node()?

of_find_device_by_node() returns a platform_device, even if the driver
hasn't probed. Whereas driver_find_device_by_of_node() iterates
devices bound to a driver.

If using of_find_device_by_node() API I could check the result of
platform_get_drvdata(), and -EPROBE_DEFER if NULL (that pattern seems
to be used by a few drivers). But that AFAIK only guarantees you
reached the platform_set_drvdata() call in your driver probe()
function, not that it has completed.

IMHO the drivers using driver_find_device_by_of_node() for probe
deferral are doing it more robustly than those using
of_find_device_by_node()  and checking if platform_get_drvdata() is
NULL.

Or is there some other way you had in mind of using
of_find_device_by_node() I've not thought of to implement this?

Thanks,

Peter.


From dmitry.baryshkov at linaro.org  Wed Feb  7 03:45:15 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 7 Feb 2024 13:45:15 +0200
Subject: [PATCH RFC 1/2] spmi: Add support for multi-master
In-Reply-To: <ZcNIddeG6VHxBEOQ@linaro.org>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
 <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>
 <CAA8EJpqsJmv36=o1aTjVH6eMHXMg8BHNpiDvs+Q8YB23ezVGtQ@mail.gmail.com>
 <ZcMvFtAwQQjAZhk6@linaro.org> <CAA8EJprqWLX7_yWZzKp3FAKFGkSkk041f9hj1uXuRBrbH5APyQ@mail.gmail.com>
 <ZcNIddeG6VHxBEOQ@linaro.org>
Message-ID: <CAA8EJpo-16u34Yc6MLmHSqFrQ0VrZAq6TwGeVc5WFwMmhruqoA@mail.gmail.com>

On Wed, 7 Feb 2024 at 11:08, Abel Vesa <abel.vesa at linaro.org> wrote:
>
> On 24-02-07 09:23:09, Dmitry Baryshkov wrote:
> > On Wed, 7 Feb 2024 at 09:19, Abel Vesa <abel.vesa at linaro.org> wrote:
> > >
> > > On 24-02-07 01:55:39, Dmitry Baryshkov wrote:
> > > > On Wed, 7 Feb 2024 at 01:34, Abel Vesa <abel.vesa at linaro.org> wrote:
> > > > >
> > > > > Some newer SPMI controllers support multiple bus masters.
> > > > > Such a master can control multiple slave devices. The generic
> > > > > framework needs to be able to pass on the master id to the
> > > > > controller-specific driver. So do that. The framework will
> > > > > check if the devicetree child nodes are actually bus masters
> > > > > and will register the devices for each master. The legacy
> > > > > approach will still be supported for backwards compatibility.
> > > >
> > > > Please remind me, are those two actual bus musters driving a single
> > > > bus in parallel or two SPMI buses being handled by a single device? In
> > > > the latter case this implementation is incorrect. There should be
> > > > multiple spmi_controller instances, one for each bus. Allocate them in
> > > > a loop and set ctrl->dev.of_node after allocating.
> > >
> > > It's two SPMI buses (two sets of wires) handled by the same controller,
> > > HW-wise.
> > >
> > > If we register two spmi controllers with the kernel framework, it will
> > > be HW inaccurate, because there is just one controller which has
> > > multiple masters.
> >
> > struct spmi_controller is a controller for a single bus. Inside your
> > device you have two SPMI buses, each can be controlled by its own
> > struct spmi_controller. Just like devices that control multiple I2C,
> > SPI or USB busses register a separate instance of the bus controller.
>
> Well, this is what this patchset is trying to do in the generic part.
> The SPMI controller supports multiple buses (HW-wise) and therefore SW
> implementation shouldn't be tied to single bus requirement.

So, after the off-line discussion:
- add new compatible string for sm8450+
- register two spmi controller instances
- drop the master-id from the SPMI interface
- optionally: think about having a new separate driver for v7 SPMI.

>
> >
> > >
> > > I'm not saying it might not work. But, to me, it looks more like a hack.
> > >
> > > Basically, we would be mapping HW bus masters to kernel controllers.
> >
> > Buses, not just masters.
> >
> > >
> > > >
> > > > >
> > > > > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > > > > ---
> > > > >  drivers/spmi/spmi-mtk-pmif.c |  6 ++--
> > > > >  drivers/spmi/spmi-pmic-arb.c | 10 +++---
> > > > >  drivers/spmi/spmi.c          | 76 ++++++++++++++++++++++++++++++--------------
> > > > >  include/linux/spmi.h         | 10 +++---
> > > > >  4 files changed, 67 insertions(+), 35 deletions(-)
> > > >
> > > > --
> > > > With best wishes
> > > > Dmitry
> >
> >
> >
> > --
> > With best wishes
> > Dmitry



-- 
With best wishes
Dmitry


From jonathanh at nvidia.com  Wed Feb  7 03:56:26 2024
From: jonathanh at nvidia.com (Jon Hunter)
Date: Wed, 7 Feb 2024 11:56:26 +0000
Subject: [PATCH net v4] net: stmmac: xgmac: fix handling of DPP safety
 error for DMA channels
In-Reply-To: <20240203051439.1127090-1-0x1207@gmail.com>
References: <20240203051439.1127090-1-0x1207@gmail.com>
Message-ID: <c25eb595-8d91-40ea-9f52-efa15ebafdbc@nvidia.com>


On 03/02/2024 05:14, Furong Xu wrote:
> Commit 56e58d6c8a56 ("net: stmmac: Implement Safety Features in
> XGMAC core") checks and reports safety errors, but leaves the
> Data Path Parity Errors for each channel in DMA unhandled at all, lead to
> a storm of interrupt.
> Fix it by checking and clearing the DMA_DPP_Interrupt_Status register.
> 
> Fixes: 56e58d6c8a56 ("net: stmmac: Implement Safety Features in XGMAC core")
> Signed-off-by: Furong Xu <0x1207 at gmail.com>
> Reviewed-by: Simon Horman <horms at kernel.org>
> Reviewed-by: Serge Semin <fancer.lancer at gmail.com>
> ---
> Changes in v4:
>   - fix a typo name of DDPP bit, thanks Serge Semin
> 
> Changes in v3:
>   - code style fix, thanks Paolo Abeni
> 
> Changes in v2:
>    - explicit enable Data Path Parity Protection
>    - add new counters to stmmac_safety_stats
>    - add detailed log
> ---
>   drivers/net/ethernet/stmicro/stmmac/common.h  |  1 +
>   .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  3 +
>   .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 57 ++++++++++++++++++-
>   3 files changed, 60 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 721c1f8e892f..b4f60ab078d6 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -216,6 +216,7 @@ struct stmmac_safety_stats {
>   	unsigned long mac_errors[32];
>   	unsigned long mtl_errors[32];
>   	unsigned long dma_errors[32];
> +	unsigned long dma_dpp_errors[32];
>   };
>   
>   /* Number of fields in Safety Stats */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> index 207ff1799f2c..5c67a3f89f08 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> @@ -303,6 +303,8 @@
>   #define XGMAC_RXCEIE			BIT(4)
>   #define XGMAC_TXCEIE			BIT(0)
>   #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
> +#define XGMAC_MTL_DPP_CONTROL		0x000010e0
> +#define XGMAC_DPP_DISABLE		BIT(0)
>   #define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
>   #define XGMAC_TQS			GENMASK(25, 16)
>   #define XGMAC_TQS_SHIFT			16
> @@ -385,6 +387,7 @@
>   #define XGMAC_DCEIE			BIT(1)
>   #define XGMAC_TCEIE			BIT(0)
>   #define XGMAC_DMA_ECC_INT_STATUS	0x0000306c
> +#define XGMAC_DMA_DPP_INT_STATUS	0x00003074
>   #define XGMAC_DMA_CH_CONTROL(x)		(0x00003100 + (0x80 * (x)))
>   #define XGMAC_SPH			BIT(24)
>   #define XGMAC_PBLx8			BIT(16)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> index eb48211d9b0e..04d7c4dc2e35 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> @@ -830,6 +830,43 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
>   	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
>   };
>   
> +static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
> +static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
> +static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
> +	{ true, "TDPES0", dpp_tx_err },
> +	{ true, "TDPES1", dpp_tx_err },
> +	{ true, "TDPES2", dpp_tx_err },
> +	{ true, "TDPES3", dpp_tx_err },
> +	{ true, "TDPES4", dpp_tx_err },
> +	{ true, "TDPES5", dpp_tx_err },
> +	{ true, "TDPES6", dpp_tx_err },
> +	{ true, "TDPES7", dpp_tx_err },
> +	{ true, "TDPES8", dpp_tx_err },
> +	{ true, "TDPES9", dpp_tx_err },
> +	{ true, "TDPES10", dpp_tx_err },
> +	{ true, "TDPES11", dpp_tx_err },
> +	{ true, "TDPES12", dpp_tx_err },
> +	{ true, "TDPES13", dpp_tx_err },
> +	{ true, "TDPES14", dpp_tx_err },
> +	{ true, "TDPES15", dpp_tx_err },
> +	{ true, "RDPES0", dpp_rx_err },
> +	{ true, "RDPES1", dpp_rx_err },
> +	{ true, "RDPES2", dpp_rx_err },
> +	{ true, "RDPES3", dpp_rx_err },
> +	{ true, "RDPES4", dpp_rx_err },
> +	{ true, "RDPES5", dpp_rx_err },
> +	{ true, "RDPES6", dpp_rx_err },
> +	{ true, "RDPES7", dpp_rx_err },
> +	{ true, "RDPES8", dpp_rx_err },
> +	{ true, "RDPES9", dpp_rx_err },
> +	{ true, "RDPES10", dpp_rx_err },
> +	{ true, "RDPES11", dpp_rx_err },
> +	{ true, "RDPES12", dpp_rx_err },
> +	{ true, "RDPES13", dpp_rx_err },
> +	{ true, "RDPES14", dpp_rx_err },
> +	{ true, "RDPES15", dpp_rx_err },
> +};
> +
>   static void dwxgmac3_handle_dma_err(struct net_device *ndev,
>   				    void __iomem *ioaddr, bool correctable,
>   				    struct stmmac_safety_stats *stats)
> @@ -841,6 +878,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev,
>   
>   	dwxgmac3_log_error(ndev, value, correctable, "DMA",
>   			   dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats);
> +
> +	value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS);
> +	writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS);
> +
> +	dwxgmac3_log_error(ndev, value, false, "DMA_DPP",
> +			   dwxgmac3_dma_dpp_errors,
> +			   STAT_OFF(dma_dpp_errors), stats);
>   }
>   
>   static int
> @@ -881,6 +925,12 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
>   	value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */
>   	writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL);
>   
> +	/* 5. Enable Data Path Parity Protection */
> +	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
> +	/* already enabled by default, explicit enable it again */
> +	value &= ~XGMAC_DPP_DISABLE;
> +	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
> +
>   	return 0;
>   }
>   
> @@ -914,7 +964,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev,
>   		ret |= !corr;
>   	}
>   
> -	err = dma & (XGMAC_DEUIS | XGMAC_DECIS);
> +	/* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in
> +	 * DMA_Safety_Interrupt_Status, so we handle DMA Data Path
> +	 * Parity Errors here
> +	 */
> +	err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS);
>   	corr = dma & XGMAC_DECIS;
>   	if (err) {
>   		dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats);
> @@ -930,6 +984,7 @@ static const struct dwxgmac3_error {
>   	{ dwxgmac3_mac_errors },
>   	{ dwxgmac3_mtl_errors },
>   	{ dwxgmac3_dma_errors },
> +	{ dwxgmac3_dma_dpp_errors },
>   };
>   
>   static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats,


This change is breaking the build on some of our builders that are still using GCC 6.x ...

drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:836:20: error: initialiser element is not constant
   { true, "TDPES0", dpp_tx_err },
                     ^~~~~~~~~~
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:836:20: note: (near initialisation for ?dwxgmac3_dma_dpp_errors[0].detailed_desc?)
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:837:20: error: initialiser element is not constant
   { true, "TDPES1", dpp_tx_err },
                     ^~~~~~~~~~
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:837:20: note: (near initialisation for ?dwxgmac3_dma_dpp_errors[1].detailed_desc?)
...

I know that this is quite old but the minimum supported by the kernel is v5.1 ...

https://www.kernel.org/doc/html/next/process/changes.html

Jon

-- 
nvpublic


From aford173 at gmail.com  Wed Feb  7 04:00:37 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed, 7 Feb 2024 06:00:37 -0600
Subject: [PATCH] drm/bridge: imx8mp-hdmi-pvi: Fix build warnings
In-Reply-To: <7b71ab7f-7ea5-4144-a7c5-d0b66ab13476@linaro.org>
References: <20240207002305.618499-1-aford173@gmail.com> <CAOMZO5A1yiXiLOtR=H_4vJYAMGwjpqrErCzvSkmLoB_f6_rN_w@mail.gmail.com>
 <7b71ab7f-7ea5-4144-a7c5-d0b66ab13476@linaro.org>
Message-ID: <CAHCN7xJRWr8Og6E7Q10hAzd=8bb4kqOPJHQ9Rs98b5gqF8a3vg@mail.gmail.com>

On Wed, Feb 7, 2024 at 3:24?AM Neil Armstrong <neil.armstrong at linaro.org> wrote:
>
> On 07/02/2024 10:22, Fabio Estevam wrote:
> > Hi Adam,
> >
> > On Tue, Feb 6, 2024 at 9:23?PM Adam Ford <aford173 at gmail.com> wrote:
> >>
> >> Two separate build warnings were reported.  One from an
> >> uninitialized variable, and the other from returning 0
> >> instead of NULL from a pointer.
> >>
> >> Fixes: 059c53e877ca ("drm/bridge: imx: add driver for HDMI TX Parallel Video Interface")
> >> Reported-by: nathan at kernel.org
> >
> > The Reported-by line format can be improved:
> >
Sorry about .that

> > Reported-by: Nathan Chancellor <nathan at kernel.org>
> >
> > Thanks
>
> Fixed while applying,

Thank you!

adam
>
> Thanks,
> Neil


From Dave.Martin at arm.com  Wed Feb  7 04:01:43 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 7 Feb 2024 12:01:43 +0000
Subject: [PATCH] arm64/sve: Document that __SVE_VQ_MAX is much larger
 than needed
In-Reply-To: <20240206-arm64-sve-vl-max-comment-v1-1-dddf16414412@kernel.org>
References: <20240206-arm64-sve-vl-max-comment-v1-1-dddf16414412@kernel.org>
Message-ID: <ZcNxJ56+bvcUTGlT@e133380.arm.com>

On Tue, Feb 06, 2024 at 04:27:01PM +0000, Mark Brown wrote:
> __SVE_VQ_MAX is defined without comment as 512 but the actual
> architectural maximum is 16, a substantial difference which might not
> be obvious to readers especially given the several different units used
> for specifying vector sizes in various contexts and the fact that it's
> often used via macros.  In an effort to minimise surprises for users who
> might assume the value is the architectural maximum and use it to do
> things like size allocations add a comment noting the difference.

Well, the value 512 was semi-deliberately chosen to be surprising.

But the point about units is valid: to the casual reader, "512" does
look suspiciously like a bit count when it really really isn't...

> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/include/uapi/asm/sve_context.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm64/include/uapi/asm/sve_context.h b/arch/arm64/include/uapi/asm/sve_context.h
> index 754ab751b523..59f283f373a6 100644
> --- a/arch/arm64/include/uapi/asm/sve_context.h
> +++ b/arch/arm64/include/uapi/asm/sve_context.h
> @@ -13,6 +13,10 @@
>  
>  #define __SVE_VQ_BYTES		16	/* number of bytes per quadword */
>  
> +/*
> + * Note that for future proofing __SVE_VQ_MAX is defined much larger
> + * than the actual architecture maximum of 16.
> + */

I think that putting shadow #defines in comments in UAPI headers is a
really bad idea...  is this a normative statement about the user API,
or what?

My concern is that if we muddy the waters here different bits of
software will do different things and we will get a mess with no
advantages.

Portability issues may ensue if userspace software feels it can
substitute some other value for this constant, since we can't control
what userspace uses it for.

>  #define __SVE_VQ_MIN		1

Would it be sufficient to say something like:

/*
 * Yes, this is 512 QUADWORDS.
 * Never allocate memory or size structures based on the value of this
 * constant.
 */
>  #define __SVE_VQ_MAX		512

Though comments might be better placed alongsize SVE_VQ_MAX at al., in
ptrace.h and sigcontext.h rather than here.  The leading __ should at
least be a hint that __SVE_VQ_MAX shouldn't be used directly by
anyone...

Cheers
---Dave


From tudor.ambarus at linaro.org  Wed Feb  7 04:04:14 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:14 +0000
Subject: [PATCH v5 00/17] spi: s3c64xx: straightforward cleanup
Message-ID: <20240207120431.2766269-1-tudor.ambarus@linaro.org>

The patch set has no dependency although Sam prefers to have this simple
cleanup queued after the gs101 patches from:
https://lore.kernel.org/linux-spi/20240207111516.2563218-1-tudor.ambarus at linaro.org/

Tested with gs101-spi.

Changes in v5:
- don't abuse the Fixes tag, it was wrongly used for:
    - explicit header inclusions
    - possible negative array index fix, which is just a posibility,
      it never happened
    - typo fix
- reorder patches, sort headers then explicitly include the missing ones
- new patch: "spi: s3c64xx: explicitly include <linux/types.h>"
- collect R-b tags

v4:
- drop "spi: s3c64xx: use bitfield access macros" patch as there was
  no agreement on how the reg fields should be handled.
- don't change the style in s3c64xx_spi_dt_match(), drop just the
  unneeded casts
- collect Sam's R-b  tags

v3:
- reworked the bitfied access macros patch so that the bit operations
  are the same as before the patch. Fix S3C64XX_SPI_PSR_MASK value,
  drop S3C64XX_SPI_CS_NSC_CNT_MASK.
- add a new patches to explicitly remove a duplicated definition and to
  drop a superfluous bitwise NOT operation.
- collect R-b tags

v2:
https://lore.kernel.org/linux-arm-kernel/36a664b1-666d-4fc4-90d9-35b42e56973d at linaro.org/

Tudor Ambarus (17):
  spi: s3c64xx: sort headers alphabetically
  spi: s3c64xx: explicitly include <linux/io.h>
  spi: s3c64xx: explicitly include <linux/bits.h>
  spi: s3c64xx: explicitly include <linux/types.h>
  spi: s3c64xx: avoid possible negative array index
  spi: s3c64xx: fix typo, s/configuartion/configuration
  spi: s3c64xx: remove unneeded (void *) casts in of_match_table
  spi: s3c64xx: remove else after return
  spi: s3c64xx: move common code outside if else
  spi: s3c64xx: check return code of dmaengine_slave_config()
  spi: s3c64xx: propagate the dma_submit_error() error code
  spi: s3c64xx: rename prepare_dma() to s3c64xx_prepare_dma()
  spi: s3c64xx: return ETIMEDOUT for wait_for_completion_timeout()
  spi: s3c64xx: drop blank line between declarations
  spi: s3c64xx: downgrade dev_warn to dev_dbg for optional dt props
  spi: s3c64xx: remove duplicated definition
  spi: s3c64xx: drop a superfluous bitwise NOT operation

 drivers/spi/spi-s3c64xx.c | 81 ++++++++++++++++++++-------------------
 1 file changed, 41 insertions(+), 40 deletions(-)

-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:15 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:15 +0000
Subject: [PATCH v5 01/17] spi: s3c64xx: sort headers alphabetically
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-2-tudor.ambarus@linaro.org>

Sorting headers alphabetically helps locating duplicates,
and makes it easier to figure out where to insert new headers.

Reviewed-by: Andi Shyti <andi.shyti at kernel.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 7ab3f3c2e9aa..1455cbd2fa8d 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -3,19 +3,18 @@
 // Copyright (c) 2009 Samsung Electronics Co., Ltd.
 //      Jaswinder Singh <jassi.brar at samsung.com>
 
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_data/spi-s3c64xx.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/spi/spi.h>
-#include <linux/of.h>
-
-#include <linux/platform_data/spi-s3c64xx.h>
 
 #define MAX_SPI_PORTS		16
 #define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1)
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:16 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:16 +0000
Subject: [PATCH v5 02/17] spi: s3c64xx: explicitly include <linux/io.h>
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-3-tudor.ambarus@linaro.org>

The driver uses readl() but does not include <linux/io.h>.

It is good practice to directly include all headers used, it avoids
implicit dependencies and spurious breakage if someone rearranges
headers and causes the implicit include to vanish.

Include the missing header.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 1455cbd2fa8d..9882eb0f4bea 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -9,6 +9,7 @@
 #include <linux/dmaengine.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_data/spi-s3c64xx.h>
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:18 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:18 +0000
Subject: [PATCH v5 04/17] spi: s3c64xx: explicitly include <linux/types.h>
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-5-tudor.ambarus@linaro.org>

The driver uses u32 and relies on an implicit inclusion of
<linux/types.h>.

It is good practice to directly include all headers used, it avoids
implicit dependencies and spurious breakage if someone rearranges
headers and causes the implicit include to vanish.

Include the missing header.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index b1564a447a6e..0a30d034e288 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/spi/spi.h>
+#include <linux/types.h>
 
 #define MAX_SPI_PORTS		16
 #define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1)
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:17 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:17 +0000
Subject: [PATCH v5 03/17] spi: s3c64xx: explicitly include <linux/bits.h>
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-4-tudor.ambarus@linaro.org>

The driver uses GENMASK() but does not include <linux/bits.h>.

It is good practice to directly include all headers used, it avoids
implicit dependencies and spurious breakage if someone rearranges
headers and causes the implicit include to vanish.

Include the missing header.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 9882eb0f4bea..b1564a447a6e 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -3,6 +3,7 @@
 // Copyright (c) 2009 Samsung Electronics Co., Ltd.
 //      Jaswinder Singh <jassi.brar at samsung.com>
 
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:19 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:19 +0000
Subject: [PATCH v5 05/17] spi: s3c64xx: avoid possible negative array index
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-6-tudor.ambarus@linaro.org>

The platform id is used as an index into the fifo_lvl_mask array.
Platforms can come with a negative device ID, PLATFORM_DEVID_NONE (-1),
thus we risked a negative array index. Catch such cases and fail to
probe.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 0a30d034e288..dfe78ddfa233 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1228,6 +1228,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 					     "Failed to get alias id\n");
 		sdd->port_id = ret;
 	} else {
+		if (pdev->id < 0)
+			return dev_err_probe(&pdev->dev, -EINVAL,
+					     "Negative platform ID is not allowed\n");
 		sdd->port_id = pdev->id;
 	}
 
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:20 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:20 +0000
Subject: [PATCH v5 06/17] spi: s3c64xx: fix typo, s/configuartion/configuration
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-7-tudor.ambarus@linaro.org>

Fix typo, s/configuartion/configuration.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index dfe78ddfa233..93d0e55e1249 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -182,7 +182,7 @@ struct s3c64xx_spi_port_config {
  * @cur_speed: Current clock speed
  * @rx_dma: Local receive DMA data (e.g. chan and direction)
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
- * @port_conf: Local SPI port configuartion data
+ * @port_conf: Local SPI port configuration data
  * @port_id: Port identification number
  */
 struct s3c64xx_spi_driver_data {
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:21 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:21 +0000
Subject: [PATCH v5 07/17] spi: s3c64xx: remove unneeded (void *) casts in of_match_table
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-8-tudor.ambarus@linaro.org>

of_device_id::data is an opaque pointer. No explicit cast is needed.
Remove unneeded (void *) casts in of_match_table.

Reviewed-by: Andi Shyti <andi.shyti at kernel.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 93d0e55e1249..e3e7d625f3fe 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1568,31 +1568,31 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {
 			.data = &gs101_spi_port_config,
 	},
 	{ .compatible = "samsung,s3c2443-spi",
-			.data = (void *)&s3c2443_spi_port_config,
+			.data = &s3c2443_spi_port_config,
 	},
 	{ .compatible = "samsung,s3c6410-spi",
-			.data = (void *)&s3c6410_spi_port_config,
+			.data = &s3c6410_spi_port_config,
 	},
 	{ .compatible = "samsung,s5pv210-spi",
-			.data = (void *)&s5pv210_spi_port_config,
+			.data = &s5pv210_spi_port_config,
 	},
 	{ .compatible = "samsung,exynos4210-spi",
-			.data = (void *)&exynos4_spi_port_config,
+			.data = &exynos4_spi_port_config,
 	},
 	{ .compatible = "samsung,exynos7-spi",
-			.data = (void *)&exynos7_spi_port_config,
+			.data = &exynos7_spi_port_config,
 	},
 	{ .compatible = "samsung,exynos5433-spi",
-			.data = (void *)&exynos5433_spi_port_config,
+			.data = &exynos5433_spi_port_config,
 	},
 	{ .compatible = "samsung,exynos850-spi",
-			.data = (void *)&exynos850_spi_port_config,
+			.data = &exynos850_spi_port_config,
 	},
 	{ .compatible = "samsung,exynosautov9-spi",
-			.data = (void *)&exynosautov9_spi_port_config,
+			.data = &exynosautov9_spi_port_config,
 	},
 	{ .compatible = "tesla,fsd-spi",
-			.data = (void *)&fsd_spi_port_config,
+			.data = &fsd_spi_port_config,
 	},
 	{ },
 };
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:22 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:22 +0000
Subject: [PATCH v5 08/17] spi: s3c64xx: remove else after return
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-9-tudor.ambarus@linaro.org>

Else case is not needed after a return, remove it.

Reviewed-by: Andi Shyti <andi.shyti at kernel.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index e3e7d625f3fe..0b42d28d2019 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -410,12 +410,10 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
 {
 	struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
 
-	if (sdd->rx_dma.ch && sdd->tx_dma.ch) {
+	if (sdd->rx_dma.ch && sdd->tx_dma.ch)
 		return xfer->len > FIFO_DEPTH(sdd);
-	} else {
-		return false;
-	}
 
+	return false;
 }
 
 static void s3c64xx_iowrite8_32_rep(volatile void __iomem *addr,
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:23 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:23 +0000
Subject: [PATCH v5 09/17] spi: s3c64xx: move common code outside if else
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-10-tudor.ambarus@linaro.org>

Move common code outside if else to avoid code duplication.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 0b42d28d2019..4ce6cb3b43f6 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -294,20 +294,18 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
 	if (dma->direction == DMA_DEV_TO_MEM) {
 		sdd = container_of((void *)dma,
 			struct s3c64xx_spi_driver_data, rx_dma);
-		config.direction = dma->direction;
 		config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
 		config.src_addr_width = sdd->cur_bpw / 8;
 		config.src_maxburst = 1;
-		dmaengine_slave_config(dma->ch, &config);
 	} else {
 		sdd = container_of((void *)dma,
 			struct s3c64xx_spi_driver_data, tx_dma);
-		config.direction = dma->direction;
 		config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
 		config.dst_addr_width = sdd->cur_bpw / 8;
 		config.dst_maxburst = 1;
-		dmaengine_slave_config(dma->ch, &config);
 	}
+	config.direction = dma->direction;
+	dmaengine_slave_config(dma->ch, &config);
 
 	desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents,
 				       dma->direction, DMA_PREP_INTERRUPT);
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:24 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:24 +0000
Subject: [PATCH v5 10/17] spi: s3c64xx: check return code of dmaengine_slave_config()
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-11-tudor.ambarus@linaro.org>

Check the return code of dmaengine_slave_config().

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 4ce6cb3b43f6..1f7356f6e5d2 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -305,7 +305,9 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
 		config.dst_maxburst = 1;
 	}
 	config.direction = dma->direction;
-	dmaengine_slave_config(dma->ch, &config);
+	ret = dmaengine_slave_config(dma->ch, &config);
+	if (ret)
+		return ret;
 
 	desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents,
 				       dma->direction, DMA_PREP_INTERRUPT);
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:25 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:25 +0000
Subject: [PATCH v5 11/17] spi: s3c64xx: propagate the dma_submit_error() error code
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-12-tudor.ambarus@linaro.org>

DMA submit should just add the dma descriptor to a queue, without firing
it. EIO is misleading and hides what happens in DMA. Propagate the
dma_submit_error() error code, don't overwrite it.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 1f7356f6e5d2..ba17c5a04eef 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -324,7 +324,7 @@ static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
 	ret = dma_submit_error(dma->cookie);
 	if (ret) {
 		dev_err(&sdd->pdev->dev, "DMA submission failed");
-		return -EIO;
+		return ret;
 	}
 
 	dma_async_issue_pending(dma->ch);
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:26 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:26 +0000
Subject: [PATCH v5 12/17] spi: s3c64xx: rename prepare_dma() to s3c64xx_prepare_dma()
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-13-tudor.ambarus@linaro.org>

Don't monopolize the name. Prepend the driver prefix to the function
name.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index ba17c5a04eef..4cafec877931 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -281,8 +281,8 @@ static void s3c64xx_spi_dmacb(void *data)
 	spin_unlock_irqrestore(&sdd->lock, flags);
 }
 
-static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
-			struct sg_table *sgt)
+static int s3c64xx_prepare_dma(struct s3c64xx_spi_dma_data *dma,
+			       struct sg_table *sgt)
 {
 	struct s3c64xx_spi_driver_data *sdd;
 	struct dma_slave_config config;
@@ -497,7 +497,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 		chcfg |= S3C64XX_SPI_CH_TXCH_ON;
 		if (dma_mode) {
 			modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
-			ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
+			ret = s3c64xx_prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
 		} else {
 			s3c64xx_iowrite_rep(sdd, xfer);
 		}
@@ -516,7 +516,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 			writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
 					| S3C64XX_SPI_PACKET_CNT_EN,
 					regs + S3C64XX_SPI_PACKET_CNT);
-			ret = prepare_dma(&sdd->rx_dma, &xfer->rx_sg);
+			ret = s3c64xx_prepare_dma(&sdd->rx_dma, &xfer->rx_sg);
 		}
 	}
 
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:27 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:27 +0000
Subject: [PATCH v5 13/17] spi: s3c64xx: return ETIMEDOUT for wait_for_completion_timeout()
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-14-tudor.ambarus@linaro.org>

ETIMEDOUT is more specific than EIO, use it for
wait_for_completion_timeout().

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 4cafec877931..bcc00cb5e0d1 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -566,7 +566,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
 
 	/*
 	 * If the previous xfer was completed within timeout, then
-	 * proceed further else return -EIO.
+	 * proceed further else return -ETIMEDOUT.
 	 * DmaTx returns after simply writing data in the FIFO,
 	 * w/o waiting for real transmission on the bus to finish.
 	 * DmaRx returns only after Dma read data from FIFO which
@@ -587,7 +587,7 @@ static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
 
 	/* If timed out while checking rx/tx status return error */
 	if (!val)
-		return -EIO;
+		return -ETIMEDOUT;
 
 	return 0;
 }
@@ -617,7 +617,7 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
 	if (use_irq) {
 		val = msecs_to_jiffies(ms);
 		if (!wait_for_completion_timeout(&sdd->xfer_completion, val))
-			return -EIO;
+			return -ETIMEDOUT;
 	}
 
 	val = msecs_to_loops(ms);
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:28 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:28 +0000
Subject: [PATCH v5 14/17] spi: s3c64xx: drop blank line between declarations
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-15-tudor.ambarus@linaro.org>

Drop the blank line and move the logical operation in the body of the
function rather than in initialization list.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index bcc00cb5e0d1..d257c4f5623e 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1360,8 +1360,9 @@ static int s3c64xx_spi_suspend(struct device *dev)
 {
 	struct spi_controller *host = dev_get_drvdata(dev);
 	struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
+	int ret;
 
-	int ret = spi_controller_suspend(host);
+	ret = spi_controller_suspend(host);
 	if (ret)
 		return ret;
 
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:29 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:29 +0000
Subject: [PATCH v5 15/17] spi: s3c64xx: downgrade dev_warn to dev_dbg for optional dt props
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-16-tudor.ambarus@linaro.org>

"samsung,spi-src-clk" and "num-cs" are optional dt properties. Downgrade
the message from warning to debug message.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index d257c4f5623e..8ad28ec3e6c1 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1149,14 +1149,14 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
 		return ERR_PTR(-ENOMEM);
 
 	if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) {
-		dev_warn(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n");
+		dev_dbg(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n");
 		sci->src_clk_nr = 0;
 	} else {
 		sci->src_clk_nr = temp;
 	}
 
 	if (of_property_read_u32(dev->of_node, "num-cs", &temp)) {
-		dev_warn(dev, "number of chip select lines not specified, assuming 1 chip select line\n");
+		dev_dbg(dev, "number of chip select lines not specified, assuming 1 chip select line\n");
 		sci->num_cs = 1;
 	} else {
 		sci->num_cs = temp;
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:30 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:30 +0000
Subject: [PATCH v5 16/17] spi: s3c64xx: remove duplicated definition
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-17-tudor.ambarus@linaro.org>

S3C64XX_SPI_TRAILCNT brings no benefit in terms of name over
S3C64XX_SPI_MAX_TRAILCNT. Remove the duplicated definition.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 8ad28ec3e6c1..b618efba0509 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -116,8 +116,6 @@
 #define S3C64XX_SPI_MAX_TRAILCNT	0x3ff
 #define S3C64XX_SPI_TRAILCNT_OFF	19
 
-#define S3C64XX_SPI_TRAILCNT		S3C64XX_SPI_MAX_TRAILCNT
-
 #define S3C64XX_SPI_POLLING_SIZE	32
 
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
@@ -1132,7 +1130,7 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd)
 	val = readl(regs + S3C64XX_SPI_MODE_CFG);
 	val &= ~S3C64XX_SPI_MODE_4BURST;
 	val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
-	val |= (S3C64XX_SPI_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
+	val |= (S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
 	writel(val, regs + S3C64XX_SPI_MODE_CFG);
 
 	s3c64xx_flush_fifo(sdd);
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Wed Feb  7 04:04:31 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed,  7 Feb 2024 12:04:31 +0000
Subject: [PATCH v5 17/17] spi: s3c64xx: drop a superfluous bitwise NOT operation
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <20240207120431.2766269-18-tudor.ambarus@linaro.org>

val &= ~mask;
val |= mask;

is equivalent to:
val |= mask;

Drop the superfluous bitwise NOT operation.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index b618efba0509..6f29dca68491 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1129,7 +1129,6 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd)
 
 	val = readl(regs + S3C64XX_SPI_MODE_CFG);
 	val &= ~S3C64XX_SPI_MODE_4BURST;
-	val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
 	val |= (S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
 	writel(val, regs + S3C64XX_SPI_MODE_CFG);
 
-- 
2.43.0.687.g38aa6559b0-goog



From will at kernel.org  Wed Feb  7 04:11:25 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 7 Feb 2024 12:11:25 +0000
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <ZcNnrdlb3fe0kGHK@casper.infradead.org>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com>
 <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
 <ZcNnrdlb3fe0kGHK@casper.infradead.org>
Message-ID: <20240207121125.GA22234@willie-the-truck>

On Wed, Feb 07, 2024 at 11:21:17AM +0000, Matthew Wilcox wrote:
> On Wed, Feb 07, 2024 at 11:12:52AM +0000, Will Deacon wrote:
> > On Sat, Jan 27, 2024 at 01:04:15PM +0800, Nanyong Sun wrote:
> > > 
> > > On 2024/1/26 2:06, Catalin Marinas wrote:
> > > > On Sat, Jan 13, 2024 at 05:44:33PM +0800, Nanyong Sun wrote:
> > > > > HVO was previously disabled on arm64 [1] due to the lack of necessary
> > > > > BBM(break-before-make) logic when changing page tables.
> > > > > This set of patches fix this by adding necessary BBM sequence when
> > > > > changing page table, and supporting vmemmap page fault handling to
> > > > > fixup kernel address translation fault if vmemmap is concurrently accessed.
> > > > I'm not keen on this approach. I'm not even sure it's safe. In the
> > > > second patch, you take the init_mm.page_table_lock on the fault path but
> > > > are we sure this is unlocked when the fault was taken?
> > > I think this situation is impossible. In the implementation of the second
> > > patch, when the page table is being corrupted
> > > (the time window when a page fault may occur), vmemmap_update_pte() already
> > > holds the init_mm.page_table_lock,
> > > and unlock it until page table update is done.Another thread could not hold
> > > the init_mm.page_table_lock and
> > > also trigger a page fault at the same time.
> > > If I have missed any points in my thinking, please correct me. Thank you.
> > 
> > It still strikes me as incredibly fragile to handle the fault and trying
> > to reason about all the users of 'struct page' is impossible. For example,
> > can the fault happen from irq context?
> 
> The pte lock cannot be taken in irq context (which I think is what
> you're asking?)  While it is not possible to reason about all users of
> struct page, we are somewhat relieved of that work by noting that this is
> only for hugetlbfs, so we don't need to reason about slab, page tables,
> netmem or zsmalloc.

My concern is that an interrupt handler tries to access a 'struct page'
which faults due to another core splitting a pmd mapping for the vmemmap.
In this case, I think we'll end up trying to resolve the fault from irq
context, which will try to take the spinlock.

Avoiding the fault would make this considerably more robust and the
architecture has introduced features to avoid break-before-make in some
circumstances (see FEAT_BBM and its levels), so having this optimisation
conditional on that would seem to be a better approach in my opinion.

Will


From catalin.marinas at arm.com  Wed Feb  7 04:20:21 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 7 Feb 2024 12:20:21 +0000
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <ZcNnrdlb3fe0kGHK@casper.infradead.org>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com>
 <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
 <ZcNnrdlb3fe0kGHK@casper.infradead.org>
Message-ID: <ZcN1hTrAhy-B1P2_@arm.com>

On Wed, Feb 07, 2024 at 11:21:17AM +0000, Matthew Wilcox wrote:
> On Wed, Feb 07, 2024 at 11:12:52AM +0000, Will Deacon wrote:
> > On Sat, Jan 27, 2024 at 01:04:15PM +0800, Nanyong Sun wrote:
> > > On 2024/1/26 2:06, Catalin Marinas wrote:
> > > > On Sat, Jan 13, 2024 at 05:44:33PM +0800, Nanyong Sun wrote:
> > > > > HVO was previously disabled on arm64 [1] due to the lack of necessary
> > > > > BBM(break-before-make) logic when changing page tables.
> > > > > This set of patches fix this by adding necessary BBM sequence when
> > > > > changing page table, and supporting vmemmap page fault handling to
> > > > > fixup kernel address translation fault if vmemmap is concurrently accessed.
> > > > I'm not keen on this approach. I'm not even sure it's safe. In the
> > > > second patch, you take the init_mm.page_table_lock on the fault path but
> > > > are we sure this is unlocked when the fault was taken?
> > > I think this situation is impossible. In the implementation of the second
> > > patch, when the page table is being corrupted
> > > (the time window when a page fault may occur), vmemmap_update_pte() already
> > > holds the init_mm.page_table_lock,
> > > and unlock it until page table update is done.Another thread could not hold
> > > the init_mm.page_table_lock and
> > > also trigger a page fault at the same time.
> > > If I have missed any points in my thinking, please correct me. Thank you.
> > 
> > It still strikes me as incredibly fragile to handle the fault and trying
> > to reason about all the users of 'struct page' is impossible. For example,
> > can the fault happen from irq context?
> 
> The pte lock cannot be taken in irq context (which I think is what
> you're asking?)

With this patchset, I think it can: IRQ -> interrupt handler accesses
vmemmap -> faults -> fault handler in patch 2 takes the
init_mm.page_table_lock to wait for the vmemmap rewriting to complete.
Maybe it works if the hugetlb code disabled the IRQs but, as Will said,
such fault in any kernel context looks fragile.

-- 
Catalin


From mark.rutland at arm.com  Wed Feb  7 04:21:49 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 7 Feb 2024 12:21:49 +0000
Subject: [PATCH v3 2/3] arm64: mm: HVO: support BBM of vmemmap pgtable
 safely
In-Reply-To: <20240113094436.2506396-3-sunnanyong@huawei.com>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <20240113094436.2506396-3-sunnanyong@huawei.com>
Message-ID: <ZcN13R1L1CYu9gs1@FVFF77S0Q05N.cambridge.arm.com>

On Sat, Jan 13, 2024 at 05:44:35PM +0800, Nanyong Sun wrote:
> Implement vmemmap_update_pmd and vmemmap_update_pte on arm64 to do
> BBM(break-before-make) logic when change the page table of vmemmap
> address, they will under the init_mm.page_table_lock.
> If a translation fault of vmemmap address concurrently happened after
> pte/pmd cleared, vmemmap page fault handler will acquire the
> init_mm.page_table_lock to wait for vmemmap update to complete,
> by then the virtual address is valid again, so PF can return and
> access can continue.

Is that wait bounded? ... and is it event guaranteed to make progress?

Under a hypervisor, the vCPU doing the BBM could be preempted between the break
and the make, so the thread waiting might be waiting a long time for that to
come back and finish the make step.

Further, under PREEMPT_RT regular spinlocks don't inhibit preemption, and I suspect
that means this can deadlock on RT -- the thread doing the BBM could be
preempted, the newly-scheduled thread could try to access the vmemmap, and then
get stuck in the fault handler (e.g. on a single CPU system). There's nothing
below describing how that's prevented.

I've concerned this may be subtly broken, and it feels like this is going to be
*very* painful to maintain and test. IMO this is trying to be overly clever and
I'd much rather that we avoided the transient broken step. On CPUs with
FEAT_BBM level 2 we can avoid that broken step, can we make this depend
dynamically on whether the CPU has FEAT_BBM?

> In other case, do the traditional kernel fault.
> 
> Implement vmemmap_flush_tlb_all/range on arm64 with nothing
> to do because tlb already flushed in every single BBM.
> 
> Signed-off-by: Nanyong Sun <sunnanyong at huawei.com>
> ---
>  arch/arm64/include/asm/esr.h      |  4 ++
>  arch/arm64/include/asm/pgtable.h  |  8 ++++
>  arch/arm64/include/asm/tlbflush.h | 16 +++++++
>  arch/arm64/mm/fault.c             | 78 +++++++++++++++++++++++++++++--
>  arch/arm64/mm/mmu.c               | 28 +++++++++++
>  5 files changed, 131 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index ae35939f395b..1c63256efd25 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -116,6 +116,10 @@
>  #define ESR_ELx_FSC_SERROR	(0x11)
>  #define ESR_ELx_FSC_ACCESS	(0x08)
>  #define ESR_ELx_FSC_FAULT	(0x04)
> +#define ESR_ELx_FSC_FAULT_L0    (0x04)
> +#define ESR_ELx_FSC_FAULT_L1    (0x05)
> +#define ESR_ELx_FSC_FAULT_L2    (0x06)
> +#define ESR_ELx_FSC_FAULT_L3    (0x07)
>  #define ESR_ELx_FSC_PERM	(0x0C)
>  #define ESR_ELx_FSC_SEA_TTW0	(0x14)
>  #define ESR_ELx_FSC_SEA_TTW1	(0x15)
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 79ce70fbb751..b50270107e2f 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -1124,6 +1124,14 @@ extern pte_t ptep_modify_prot_start(struct vm_area_struct *vma,
>  extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
>  				    unsigned long addr, pte_t *ptep,
>  				    pte_t old_pte, pte_t new_pte);
> +
> +#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
> +void vmemmap_update_pmd(unsigned long addr, pmd_t *pmdp, pte_t *ptep);
> +#define vmemmap_update_pmd vmemmap_update_pmd
> +void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
> +#define vmemmap_update_pte vmemmap_update_pte
> +#endif
> +
>  #endif /* !__ASSEMBLY__ */
>  
>  #endif /* __ASM_PGTABLE_H */
> diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
> index 1deb5d789c2e..79e932a1bdf8 100644
> --- a/arch/arm64/include/asm/tlbflush.h
> +++ b/arch/arm64/include/asm/tlbflush.h
> @@ -504,6 +504,22 @@ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr)
>  	dsb(ish);
>  	isb();
>  }
> +
> +#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
> +static inline void vmemmap_flush_tlb_all(void)
> +{
> +	/* do nothing, already flushed tlb in every single BBM */
> +}
> +#define vmemmap_flush_tlb_all vmemmap_flush_tlb_all
> +
> +static inline void vmemmap_flush_tlb_range(unsigned long start,
> +					   unsigned long end)
> +{
> +	/* do nothing, already flushed tlb in every single BBM */
> +}
> +#define vmemmap_flush_tlb_range vmemmap_flush_tlb_range
> +#endif
> +
>  #endif
>  
>  #endif
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 55f6455a8284..13189322a38f 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -368,6 +368,75 @@ static bool is_el1_mte_sync_tag_check_fault(unsigned long esr)
>  	return false;
>  }
>  
> +#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
> +static inline bool vmemmap_fault_may_fixup(unsigned long addr,
> +					   unsigned long esr)
> +{
> +	if (addr < VMEMMAP_START || addr >= VMEMMAP_END)
> +		return false;
> +
> +	/*
> +	 * Only try to handle translation fault level 2 or level 3,
> +	 * because hugetlb vmemmap optimize only clear pmd or pte.
> +	 */
> +	switch (esr & ESR_ELx_FSC) {
> +	case ESR_ELx_FSC_FAULT_L2:
> +	case ESR_ELx_FSC_FAULT_L3:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +/*
> + * PMD mapped vmemmap should has been split as PTE mapped
> + * by HVO now, here we only check this case, other cases
> + * should fail.

Sorry, I can't parse what this is trying to say.

> + * Also should check the addr is healthy enough that will not cause
> + * a level2 or level3 translation fault again after page fault
> + * handled with success, so we need check both bits[1:0] of PMD and
> + * PTE as ARM Spec mentioned below:

Which spec? Iassume you mean the ARM ARM? Are you referring to a specific part
within that?

> + * A Translation fault is generated if bits[1:0] of a translation
> + * table descriptor identify the descriptor as either a Fault
> + * encoding or a reserved encoding.
> + */
> +static inline bool vmemmap_addr_healthy(unsigned long addr)
> +{
> +	pmd_t *pmdp, pmd;
> +	pte_t *ptep, pte;
> +
> +	pmdp = pmd_off_k(addr);
> +	pmd = pmdp_get(pmdp);
> +	if (!pmd_table(pmd))
> +		return false;

Is a block (i.e. hugetlb) entry not considered healthy? I thought the whole
point of this optimization was that you'd use a block PMD entry?

> +
> +	ptep = pte_offset_kernel(pmdp, addr);
> +	pte = ptep_get(ptep);
> +	return (pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_PAGE;
> +}
> +
> +static bool vmemmap_handle_page_fault(unsigned long addr,
> +				      unsigned long esr)
> +{
> +	bool ret;
> +
> +	if (likely(!vmemmap_fault_may_fixup(addr, esr)))
> +		return false;
> +
> +	spin_lock(&init_mm.page_table_lock);
> +	ret = vmemmap_addr_healthy(addr);
> +	spin_unlock(&init_mm.page_table_lock);

As above, I'm pretty sure this is only safe is the code doing the BBM has IRQs
disabled, otherwise the thread can be preempted, and we can get stuck in here
while the entry is broken.

So at minimum this needs some explanation of why that doesn't happen in a
comment.

> +
> +	return ret;
> +}
> +#else
> +static inline bool vmemmap_handle_page_fault(unsigned long addr,
> +					     unsigned long esr)
> +{
> +	return false;
> +}
> +#endif /* CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP */
> +
>  static bool is_translation_fault(unsigned long esr)
>  {
>  	return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT;
> @@ -405,9 +474,12 @@ static void __do_kernel_fault(unsigned long addr, unsigned long esr,
>  	} else if (addr < PAGE_SIZE) {
>  		msg = "NULL pointer dereference";
>  	} else {
> -		if (is_translation_fault(esr) &&
> -		    kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
> -			return;
> +		if (is_translation_fault(esr)) {
> +			if (kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
> +				return;
> +			if (vmemmap_handle_page_fault(addr, esr))
> +				return;
> +		}
>  
>  		msg = "paging request";
>  	}
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 1ac7467d34c9..d794b2f4b5a3 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -1146,6 +1146,34 @@ int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node,
>  	return 1;
>  }
>  
> +#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
> +/*
> + * In the window between the page table entry is cleared and filled
> + * with a new value, other threads have the opportunity to concurrently
> + * access the vmemmap area then page translation fault occur.
> + * Therefore, we need to ensure that the init_mm.page_table_lock is held
> + * to synchronize the vmemmap page fault handling which will wait for
> + * this lock to be released to ensure that the page table entry has been
> + * refreshed with a new valid value.
> + */
> +void vmemmap_update_pmd(unsigned long addr, pmd_t *pmdp, pte_t *ptep)
> +{
> +	lockdep_assert_held(&init_mm.page_table_lock);
> +	pmd_clear(pmdp);
> +	flush_tlb_kernel_range(addr, addr + PMD_SIZE);
> +	pmd_populate_kernel(&init_mm, pmdp, ptep);
> +}
> +
> +void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte)
> +{
> +	spin_lock(&init_mm.page_table_lock);
> +	pte_clear(&init_mm, addr, ptep);
> +	flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
> +	set_pte_at(&init_mm, addr, ptep, pte);
> +	spin_unlock(&init_mm.page_table_lock);
> +}

As above, if this happens with IRQs unmasked, the thread can potentially be
preempted and we can get stuck in the fault handler (at least on RT).

I can't tell whether this is safe, and I think that at minimum this needs
comments and/or lockdep assertions, but I'd much rather we didn't try to play
this sort of game.

Mark.


From Dave.Martin at arm.com  Wed Feb  7 04:23:56 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 7 Feb 2024 12:23:56 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <ZcEd2zU/JpeIwn5f@finisterre.sirena.org.uk>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
 <ZcEW3y0IlEctOYBA@e133380.arm.com>
 <ZcEd2zU/JpeIwn5f@finisterre.sirena.org.uk>
Message-ID: <ZcN2XMkvqxNnsz5K@e133380.arm.com>

On Mon, Feb 05, 2024 at 05:41:47PM +0000, Mark Brown wrote:
> On Mon, Feb 05, 2024 at 05:11:59PM +0000, Dave Martin wrote:
> > On Sat, Feb 03, 2024 at 12:16:49PM +0000, Mark Brown wrote:
> 
> > > We could also teach the ptrace core about runtime discoverable regset sizes
> > > but that would be a more invasive change and this is being observed in
> > > practical systems.
> 
> > This is not hard at all: see
> > 27e64b4be4b8 ("regset: Add support for dynamically sized regsets") 
> 
> > But since this is precisely what was ripped out, I guess adding it back
> > may be controversial (?)
> 
> Also just that people might want to backport and while it's not super
> *hard* I tend to prefer to do something as minimal as possible as a fix,
> the less we do the less the chances that we mess up.

Totally agree with that: the core code has now gone in another direction,
so we should consider that a done deal.  I'm just using the old patch as
an illustration of the (low) level of complexity.

> > > We should probably also use the actual architectural limit for the
> > > bitmasks we use in the VL enumeration code, though that's both a little
> > > bit more involved and less immediately a problem.
> 
> > Since these masks are 64 bytes each and rarely accessed, it seemed
> > pointless complexity to make them resizeable...
> 
> I was suggesting making them use the architectural maximum rather than
> making them dynamic.
> 
> > > +#define ARCH_SVE_VQ_MAX 16
> > >  #define SME_VQ_MAX	16
> 
> > Ack, though part of the reason for not doing this was to discourage
> > people from allocating statically sized buffers in general.
> 
> I was going to do a patch adding a comment to the header noting that
> this is not actually the architectural maximum since at present it's
> a bit of a landmine, people who have some idea of the architecture
> likely have a rough idea what sort of allocation size is needed for the
> maximum SVE state and are likely to not double check the value provided
> (I think that's what happened with the refactoring to remove the dynamic
> sizing).  A comment in the header is still very missable but it'd be
> something.
> 
> > If the kernel is now juggling two #defines for the maximum vector size,
> > this feels like it may seed bitrot...
> 
> Ideally we'd just not have the existing define externally but it's there
> and it's been used.

To clarify, is this intended as a temporary band-aid against silly
behaviour while a cleaner solution is found, or a permanent limitation?

We'd need to change various things if the architectural max VL actually
grew, so no forward-portability is lost immediately if the kernel
adopts 16 internally, but I'm still a little concerned that people may
poke about in the kernel code as a reference and this will muddy the
waters regarding how to do the right thing in userspace (I know people
shouldn't, but...)

[...]

Cheers
---Dave


From mark.rutland at arm.com  Wed Feb  7 04:24:26 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 7 Feb 2024 12:24:26 +0000
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <20240207121125.GA22234@willie-the-truck>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com>
 <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
 <ZcNnrdlb3fe0kGHK@casper.infradead.org>
 <20240207121125.GA22234@willie-the-truck>
Message-ID: <ZcN2emKK8jrJ6Gyt@FVFF77S0Q05N.cambridge.arm.com>

On Wed, Feb 07, 2024 at 12:11:25PM +0000, Will Deacon wrote:
> On Wed, Feb 07, 2024 at 11:21:17AM +0000, Matthew Wilcox wrote:
> > On Wed, Feb 07, 2024 at 11:12:52AM +0000, Will Deacon wrote:
> > > On Sat, Jan 27, 2024 at 01:04:15PM +0800, Nanyong Sun wrote:
> > > > 
> > > > On 2024/1/26 2:06, Catalin Marinas wrote:
> > > > > On Sat, Jan 13, 2024 at 05:44:33PM +0800, Nanyong Sun wrote:
> > > > > > HVO was previously disabled on arm64 [1] due to the lack of necessary
> > > > > > BBM(break-before-make) logic when changing page tables.
> > > > > > This set of patches fix this by adding necessary BBM sequence when
> > > > > > changing page table, and supporting vmemmap page fault handling to
> > > > > > fixup kernel address translation fault if vmemmap is concurrently accessed.
> > > > > I'm not keen on this approach. I'm not even sure it's safe. In the
> > > > > second patch, you take the init_mm.page_table_lock on the fault path but
> > > > > are we sure this is unlocked when the fault was taken?
> > > > I think this situation is impossible. In the implementation of the second
> > > > patch, when the page table is being corrupted
> > > > (the time window when a page fault may occur), vmemmap_update_pte() already
> > > > holds the init_mm.page_table_lock,
> > > > and unlock it until page table update is done.Another thread could not hold
> > > > the init_mm.page_table_lock and
> > > > also trigger a page fault at the same time.
> > > > If I have missed any points in my thinking, please correct me. Thank you.
> > > 
> > > It still strikes me as incredibly fragile to handle the fault and trying
> > > to reason about all the users of 'struct page' is impossible. For example,
> > > can the fault happen from irq context?
> > 
> > The pte lock cannot be taken in irq context (which I think is what
> > you're asking?)  While it is not possible to reason about all users of
> > struct page, we are somewhat relieved of that work by noting that this is
> > only for hugetlbfs, so we don't need to reason about slab, page tables,
> > netmem or zsmalloc.
> 
> My concern is that an interrupt handler tries to access a 'struct page'
> which faults due to another core splitting a pmd mapping for the vmemmap.
> In this case, I think we'll end up trying to resolve the fault from irq
> context, which will try to take the spinlock.

I think that (as per my comments on patch 2), a similar deadlock can happen on
RT even if the vmemmap is only accessed in regular process context, and at
minimum this needs better comentary and/or lockdep assertions.

I'd also prefer that we dropped this for now.

> Avoiding the fault would make this considerably more robust and the
> architecture has introduced features to avoid break-before-make in some
> circumstances (see FEAT_BBM and its levels), so having this optimisation
> conditional on that would seem to be a better approach in my opinion.

FWIW, that's my position too.

Mark.


From Dave.Martin at arm.com  Wed Feb  7 04:25:23 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 7 Feb 2024 12:25:23 +0000
Subject: [RFC PATCH] arm64/sve,sme: Refine scalable regset sizes at boot
In-Reply-To: <ZcIS6ySfoGzwv31M@finisterre.sirena.org.uk>
References: <ZcEaeLeEG8ve+Yp7@e133380.arm.com>
 <ZcIS6ySfoGzwv31M@finisterre.sirena.org.uk>
Message-ID: <ZcN2syiQfgzdMiDF@e133380.arm.com>

On Tue, Feb 06, 2024 at 11:07:23AM +0000, Mark Brown wrote:
> On Mon, Feb 05, 2024 at 05:27:20PM +0000, Dave Martin wrote:
> 
> > --- a/arch/arm64/kernel/ptrace.c
> > +++ b/arch/arm64/kernel/ptrace.c
> > @@ -9,6 +9,7 @@
> >   */
> >  
> >  #include <linux/audit.h>
> > +#include <linux/cache.h>
> >  #include <linux/compat.h>
> >  #include <linux/kernel.h>
> >  #include <linux/sched/signal.h>
> 
> Why?

include/linux/cache.h:#define __ro_after_init

(Yes, I was a bit surprised too, but that's where it is.)

Cheers
---Dave


From Jonathan.Cameron at Huawei.com  Wed Feb  7 04:27:43 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Wed, 7 Feb 2024 12:27:43 +0000
Subject: [PATCH v2] perf: CXL: fix mismatched cpmu event opcode
In-Reply-To: <20240207042235epcms2p358e40f0409e25bd9e875ad1ae0dd0764@epcms2p3>
References: <CGME20240207042235epcms2p358e40f0409e25bd9e875ad1ae0dd0764@epcms2p3>
	<20240207042235epcms2p358e40f0409e25bd9e875ad1ae0dd0764@epcms2p3>
Message-ID: <20240207122743.00004acc@Huawei.com>

On Wed, 07 Feb 2024 13:22:35 +0900
Hojin Nam <hj96.nam at samsung.com> wrote:

> S2M NDR BI-ConflictAck opcode is described as 4 in the CXL
> r3.1 3.3.9 Table 3.50. However, it is defined as 3 in macro definition. Also
> adds s2m_ndr_cmpm for bit 3 that was added in CXL r3.1.
> 
> Fixes: 5d7107c72796 ("perf: CXL Performance Monitoring Unit driver")
> Signed-off-by: Hojin Nam <hj96.nam at samsung.com>

Ah. Sorry I've mislead you. I lazily assumed this was in the 3.0 spec as well
without checking.

As a fix, we should not add the cmpm or update the reference comment.

So should be the v1 patch with a reference to table 3-43 in r3.0
and the fixes tag.

A follow up patch to add the 3.1 definitions would be excellent but we shouldn't
be looking to backport that so it doesn't belong in the fix :(


Jonathan


> ---
> 
> Hi Jonathan,
> I've modified the commit messsge and code to reflect you mentioned. Thank you!
> 
> Changes since v1:
> - Add s2m_ndr_cmpm event attribute (Jonathan)
> 
> 
>  drivers/perf/cxl_pmu.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
> index 365d964b0f6a..d85d53d907a6 100644
> --- a/drivers/perf/cxl_pmu.c
> +++ b/drivers/perf/cxl_pmu.c
> @@ -415,11 +415,12 @@ static struct attribute *cxl_pmu_event_attrs[] = {
>         CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_curblk,                CXL_PMU_GID_S2M_BISNP, BIT(4)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_datblk,                CXL_PMU_GID_S2M_BISNP, BIT(5)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_invblk,                CXL_PMU_GID_S2M_BISNP, BIT(6)),
> -       /* CXL rev 3.0 Table 3-43 S2M NDR Opcopdes */
> +       /* CXL rev 3.1 Table 3-50 S2M NDR Opcopdes */
>         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmp,                     CXL_PMU_GID_S2M_NDR, BIT(0)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmps,                    CXL_PMU_GID_S2M_NDR, BIT(1)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmpe,                    CXL_PMU_GID_S2M_NDR, BIT(2)),
> -       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(3)),
> +       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmpm,                    CXL_PMU_GID_S2M_NDR, BIT(3)),
> +       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(4)),
>         /* CXL rev 3.0 Table 3-46 S2M DRS opcodes */
>         CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdata,                 CXL_PMU_GID_S2M_DRS, BIT(0)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdatanxm,              CXL_PMU_GID_S2M_DRS, BIT(1)),
> --
> 2.34.1



From Dave.Martin at arm.com  Wed Feb  7 04:32:48 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 7 Feb 2024 12:32:48 +0000
Subject: [RFC PATCH] arm64/sve,sme: Refine scalable regset sizes at boot
In-Reply-To: <ZcNVyMyiFB3Nndth@finisterre.sirena.org.uk>
References: <ZcEaeLeEG8ve+Yp7@e133380.arm.com>
 <ZcNVyMyiFB3Nndth@finisterre.sirena.org.uk>
Message-ID: <ZcN4cGb66qjSId/B@e133380.arm.com>

On Wed, Feb 07, 2024 at 10:04:56AM +0000, Mark Brown wrote:
> On Mon, Feb 05, 2024 at 05:27:20PM +0000, Dave Martin wrote:
> 
> > index a5dc6f764195..5c2f91f84c31 100644
> > --- a/arch/arm64/kernel/fpsimd.c
> > +++ b/arch/arm64/kernel/fpsimd.c
> > @@ -1189,6 +1189,7 @@ void __init sve_setup(void)
> >  		pr_warn("%s: unvirtualisable vector lengths present\n",
> >  			info->name);
> >  
> > +	arch_ptrace_sve_init(sve_vq_from_vl(info->max_vl));
> >  	sve_efi_setup();
> >  }
> 
> This will only get run if the system actually supports SVE since the
> first thing that sve_setup() does is to exit if the system does not
> support SVE.  That means that the size limiting will only be done on
> systems that have SVE, but since we unconditionally register all our
> regsets if the system doesn't have SVE it will end up with a maximally
> sized SVE regset registered which doesn't seem ideal.  As I mentioned in
> the other thread we should probably just not be registering unsupported
> regsets with the core, that would avoid the issue without a change to
> this patch.
> 
> A similar issue applies for SME.

Good point.

I guess if we're following this approach we also do have the option
to knock out entries of the array altogether once cpufeatures are
finalised.

If we want a quick fix the silly memory allocation triggering for
Douglas' splat then this probably isn't it, but if removing regsets at
boot time is desirable anyway, we might kill two birds with one stone
here.

I'll wait for progress on the other threads before digging too deeply
into this (but anyone wanting to see this patch expedited, please
shout!)

Cheers
---Dave


From cristian.ciocaltea at collabora.com  Wed Feb  7 04:39:36 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 7 Feb 2024 14:39:36 +0200
Subject: [PATCH v2 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <ZcNYlFgT0rXiCGbo@matsya>
References: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
 <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>
 <ZcNYlFgT0rXiCGbo@matsya>
Message-ID: <374f5069-9f3d-4ad2-a6da-b38a143a0c99@collabora.com>

On 2/7/24 12:16, Vinod Koul wrote:
> On 05-02-24, 13:24, Cristian Ciocaltea wrote:
>> Add driver for the HDMI/eDP TX Combo PHY found on Rockchip RK3588 SoC.

[...]

>> +static const struct reg_sequence hdtpx_common_cmn_init_seq[] = {
>> +	REG_SEQ0(CMN_REG(0009), 0x0c),
>> +	REG_SEQ0(CMN_REG(000A), 0x83),
>> +	REG_SEQ0(CMN_REG(000B), 0x06),
>> +	REG_SEQ0(CMN_REG(000C), 0x20),
>> +	REG_SEQ0(CMN_REG(000D), 0xb8),
>> +	REG_SEQ0(CMN_REG(000E), 0x0f),
>> +	REG_SEQ0(CMN_REG(000F), 0x0f),
> 
> Any reason for these to be mixed case, lets have lower case pls
> everywhere

These were initially part of the register name defines, as specified in
the RK3588 Technical Reference Manual, e.g. HDPTXPHY_CMN_REG000A.  But
consistency is more important, I assume, hence I will do a lower case
conversion.

[...]

>> +static int hdptx_write(struct rockchip_hdptx_phy *hdptx, u32 reg, u8 val)
>> +{
>> +	return regmap_write(hdptx->regmap, reg, val);
>> +}
>> +
>> +#define hdptx_multi_reg_write(hdptx, seq) \
>> +	regmap_multi_reg_write((hdptx)->regmap, seq, ARRAY_SIZE(seq))
>> +
>> +static int hdptx_update_bits(struct rockchip_hdptx_phy *hdptx, u32 reg,
>> +			     u8 mask, u8 val)
>> +{
>> +	return regmap_update_bits(hdptx->regmap, reg, mask, val);
>> +}
>> +
>> +static int hdptx_grf_write(struct rockchip_hdptx_phy *hdptx, u32 reg, u32 val)
>> +{
>> +	return regmap_write(hdptx->grf, reg, val);
>> +}
>> +
>> +static u8 hdptx_grf_read(struct rockchip_hdptx_phy *hdptx, u32 reg)
>> +{
>> +	u32 val;
>> +
>> +	regmap_read(hdptx->grf, reg, &val);
>> +
>> +	return val;
>> +}
> 
> why use wrappers, why not call regmap_ apis directly

Agree, no real benefit, will drop them, except probably
hdptx_multi_reg_write() for the extra savings.

So I'd keep using that one if there's no strong reason against.

[...]

>> +	hdptx_write(hdptx, CMN_REG(0059), (cfg->pms_pdiv << 4) | cfg->pms_refdiv);
>> +	hdptx_write(hdptx, CMN_REG(005A), cfg->pms_sdiv << 4);
> 
> small case here as well pls

Yes, will make sure to handle them all.

Thanks for the review,
Cristian


From rogerq at kernel.org  Wed Feb  7 04:42:14 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 7 Feb 2024 14:42:14 +0200
Subject: [PATCH v4 3/3] arm64: dts: ti: k3-am62p: add the USB sub-system
In-Reply-To: <8f9e8ec5-fc78-4b51-b36f-3ba06768ce62@ti.com>
References: <20240205135908.54656-1-rogerq@kernel.org>
 <20240205135908.54656-4-rogerq@kernel.org>
 <45a0ed98-8dd2-4c5b-8e89-40c70e3fe831@ti.com>
 <77f7b127-e609-45e3-90aa-67aa7838ce6b@kernel.org>
 <8f9e8ec5-fc78-4b51-b36f-3ba06768ce62@ti.com>
Message-ID: <db95dba7-c749-48d3-bbba-01a45dfb9815@kernel.org>



On 06/02/2024 19:34, Andrew Davis wrote:
> On 2/6/24 6:30 AM, Roger Quadros wrote:
>>
>>
>> On 05/02/2024 19:34, Andrew Davis wrote:
>>> On 2/5/24 7:59 AM, Roger Quadros wrote:
>>>> There are two USB instances available on the am62p5 starter kit. Include
>>>> and enable them for use on the board.
>>>>
>>>> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
>>>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>>>> ---
>>>>
>>>> Notes:
>>>> ????? Changelog:
>>>> ????? ???? v4 - no change
>>>> ????? ???? v3 - no change
>>>> ????? https://lore.kernel.org/all/20240201120332.4811-4-rogerq at kernel.org/
>>>> ????? ???? v2:
>>>> ????? - added USB PHY CTRL node changes here
>>>> ????? - changed USB wrapper node names to usb@
>>>> ????? - changed Type-C chip node name to usb-power-control@
>>>>
>>>> ?? arch/arm64/boot/dts/ti/k3-am62p-main.dtsi?? | 46 ++++++++++++++
>>>> ?? arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi | 10 +++
>>>> ?? arch/arm64/boot/dts/ti/k3-am62p5-sk.dts???? | 67 +++++++++++++++++++++
>>>> ?? 3 files changed, 123 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
>>>> index 4c51bae06b57..17d28390d587 100644
>>>> --- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
>>>> +++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
>>>> @@ -560,6 +560,52 @@ sdhci2: mmc at fa20000 {
>>>> ?????????? status = "disabled";
>>>> ?????? };
>>>> ?? +??? usbss0: usb at f900000 {
>>>> +??????? compatible = "ti,am62-usb";
>>>> +??????? reg = <0x00 0x0f900000 0x00 0x800>;
>>>> +??????? clocks = <&k3_clks 161 3>;
>>>> +??????? clock-names = "ref";
>>>> +??????? ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
>>>> +??????? #address-cells = <2>;
>>>> +??????? #size-cells = <2>;
>>>> +??????? power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
>>>> +??????? ranges;
>>>> +??????? status = "disabled";
>>>> +
>>>> +??????? usb0: usb at 31000000 {
>>>> +??????????? compatible = "snps,dwc3";
>>>> +??????????? reg = <0x00 0x31000000 0x00 0x50000>;
>>>> +??????????? interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
>>>> +??????????? <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
>>>> +??????????? interrupt-names = "host", "peripheral";
>>>> +??????????? maximum-speed = "high-speed";
>>>> +??????????? dr_mode = "otg";
>>>> +??????? };
>>>> +??? };
>>>> +
>>>> +??? usbss1: usb at f910000 {
>>>> +??????? compatible = "ti,am62-usb";
>>>> +??????? reg = <0x00 0x0f910000 0x00 0x800>;
>>>> +??????? clocks = <&k3_clks 162 3>;
>>>> +??????? clock-names = "ref";
>>>> +??????? ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
>>>> +??????? #address-cells = <2>;
>>>> +??????? #size-cells = <2>;
>>>> +??????? power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
>>>> +??????? ranges;
>>>> +??????? status = "disabled";
>>>> +
>>>> +??????? usb1: usb at 31100000 {
>>>> +??????????? compatible = "snps,dwc3";
>>>> +??????????? reg = <0x00 0x31100000 0x00 0x50000>;
>>>> +??????????? interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
>>>> +??????????? <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
>>>> +??????????? interrupt-names = "host", "peripheral";
>>>> +??????????? maximum-speed = "high-speed";
>>>> +??????????? dr_mode = "otg";
>>>> +??????? };
>>>> +??? };
>>>> +
>>>> ?????? fss: bus at fc00000 {
>>>> ?????????? compatible = "simple-bus";
>>>> ?????????? reg = <0x00 0x0fc00000 0x00 0x70000>;
>>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
>>>> index 19f42b39394e..00dd38b02a52 100644
>>>> --- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
>>>> +++ b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
>>>> @@ -18,6 +18,16 @@ chipid: chipid at 14 {
>>>> ?????????????? reg = <0x14 0x4>;
>>>> ?????????????? bootph-all;
>>>> ?????????? };
>>>> +
>>>> +??????? usb0_phy_ctrl: syscon at 4008 {
>>>> +??????????? compatible = "ti,am62-usb-phy-ctrl", "syscon";
>>>> +??????????? reg = <0x4008 0x4>;
>>>> +??????? };
>>>> +
>>>> +??????? usb1_phy_ctrl: syscon at 4018 {
>>>> +??????????? compatible = "ti,am62-usb-phy-ctrl", "syscon";
>>>> +??????????? reg = <0x4018 0x4>;
>>>> +??????? };
>>>> ?????? };
>>>> ?? ????? wkup_uart0: serial at 2b300000 {
>>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>>>> index 1773c05f752c..80be56c0a4e0 100644
>>>> --- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>>>> +++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>>>> @@ -27,6 +27,8 @@ aliases {
>>>> ?????????? spi0 = &ospi0;
>>>> ?????????? ethernet0 = &cpsw_port1;
>>>> ?????????? ethernet1 = &cpsw_port2;
>>>> +??????? usb0 = &usb0;
>>>> +??????? usb1 = &usb1;
>>>> ?????? };
>>>> ?? ????? chosen {
>>>> @@ -297,6 +299,12 @@ AM62PX_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (G20) MCASP0_ACLKR.UART1_TXD */
>>>> ?????????? bootph-all;
>>>> ?????? };
>>>> ?? +??? main_usb1_pins_default: main-usb1-default-pins {
>>>> +??????? pinctrl-single,pins = <
>>>> +??????????? AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
>>>> +??????? >;
>>>> +??? };
>>>> +
>>>> ?????? main_wlirq_pins_default: main-wlirq-default-pins {
>>>> ?????????? pinctrl-single,pins = <
>>>> ?????????????? AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
>>>> @@ -340,6 +348,36 @@ AM62PX_IOPAD(0x0124, PIN_INPUT, 7) /* (J25) MMC2_SDCD.GPIO0_71 */
>>>> ?????? };
>>>> ?? };
>>>> ?? +&main_i2c0 {
>>>> +??? status = "okay";
>>>> +??? pinctrl-names = "default";
>>>> +??? pinctrl-0 = <&main_i2c0_pins_default>;
>>>> +??? clock-frequency = <400000>;
>>>> +
>>>> +??? typec_pd0: usb-power-controller at 3f {
>>>> +??????? compatible = "ti,tps6598x";
>>>> +??????? reg = <0x3f>;
>>>> +
>>>> +??????? connector {
>>>> +??????????? compatible = "usb-c-connector";
>>>> +??????????? label = "USB-C";
>>>> +??????????? self-powered;
>>>> +??????????? data-role = "dual";
>>>> +??????????? power-role = "sink";
>>>> +??????????? ports {
>>>> +??????????????? #address-cells = <1>;
>>>> +??????????????? #size-cells = <0>;
>>>> +??????????????? port at 0 {
>>>> +??????????????????? reg = <0>;
>>>> +??????????????????? usb_con_hs: endpoint {
>>>> +??????????????????????? remote-endpoint = <&usb0_hs_ep>;
>>>> +??????????????????? };
>>>> +??????????????? };
>>>> +??????????? };
>>>> +??????? };
>>>> +??? };
>>>> +};
>>>> +
>>>> ?? &main_i2c1 {
>>>> ?????? status = "okay";
>>>> ?????? pinctrl-names = "default";
>>>> @@ -460,6 +498,35 @@ cpsw3g_phy1: ethernet-phy at 1 {
>>>> ?????? };
>>>> ?? };
>>>> ?? +&usbss0 {
>>>> +??? status = "okay";
>>>> +??? ti,vbus-divider;
>>>> +};
>>>> +
>>>> +&usbss1 {
>>>> +??? status = "okay";
>>>> +??? ti,vbus-divider;
>>>> +};
>>>> +
>>>> +&usb0 {
>>>> +??? usb-role-switch;
>>>> +??? #address-cells = <1>;
>>>> +??? #size-cells = <0>;
>>>> +
>>>> +??? port at 0 {
>>>> +??????? reg = <0>;
>>>> +??????? usb0_hs_ep: endpoint {
>>>> +??????????? remote-endpoint = <&usb_con_hs>;
>>>> +??????? };
>>>> +??? };
>>>> +};
>>>> +
>>>> +&usb1 {
>>>> +??? dr_mode = "host";
>>>> +??? pinctrl-names = "default";
>>>> +??? pinctrl-0 = <&main_usb1_pins_default>;
>>>
>>> I'm not super familiar with USB, but I see this pinmux for the
>>> "DRVVBUS" pin is usually added the the parent USB subsystem node (usbss).
>>> Does this pin belong to the subsystem or the specific USB instance?
>>>
>> There is only 1 USB instance per USB sub-system.
>> The "DRVVBUS" pin is a control signal to enable the VBUS regulator
>> while in host mode.
>>
>> Just probing the usbss1 driver has no use of "DRVVBUS".
>> I think usb1 is the right place as it is used there.
>>
> 
> Seems reasonable, so if there ever was more than 1 instance
> per sub-system, each instance would need its own pin?

Yes.

> 
> We should move these pinctrl to the instance node in the other
> dts files at some point then.
> 
> Reviewed-by: Andrew Davis <afd at ti.com>

Thanks!

> 
>>> Andrew
>>>
>>>> +};
>>>> +
>>>> ?? &mcasp1 {
>>>> ?????? status = "okay";
>>>> ?????? #sound-dai-cells = <0>;
>>

-- 
cheers,
-roger


From catalin.marinas at arm.com  Wed Feb  7 04:44:47 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 7 Feb 2024 12:44:47 +0000
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com>
 <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
Message-ID: <ZcN7P0CGUOOgki71@arm.com>

On Sat, Jan 27, 2024 at 01:04:15PM +0800, Nanyong Sun wrote:
> On 2024/1/26 2:06, Catalin Marinas wrote:
> > On Sat, Jan 13, 2024 at 05:44:33PM +0800, Nanyong Sun wrote:
> > > HVO was previously disabled on arm64 [1] due to the lack of necessary
> > > BBM(break-before-make) logic when changing page tables.
> > > This set of patches fix this by adding necessary BBM sequence when
> > > changing page table, and supporting vmemmap page fault handling to
> > > fixup kernel address translation fault if vmemmap is concurrently accessed.
[...]
> > How often is this code path called? I wonder whether a stop_machine()
> > approach would be simpler.
> As long as allocating or releasing hugetlb is called.? We cannot limit users
> to only allocate or release hugetlb
> when booting or not running any workload on all other cpus, so if use
> stop_machine(), it will be triggered
> 8 times every 2M and 4096 times every 1G, which is probably too expensive.

I'm hoping this can be batched somehow and not do a stop_machine() (or
8) for every 2MB huge page.

Just to make sure I understand - is the goal to be able to free struct
pages corresponding to hugetlbfs pages? Can we not leave the vmemmap in
place and just release that memory to the page allocator? The physical
RAM for those struct pages isn't going anywhere, we just have a vmemmap
alias to it (cacheable).

-- 
Catalin


From angelogioacchino.delregno at collabora.com  Wed Feb  7 04:46:38 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 7 Feb 2024 13:46:38 +0100
Subject: [PATCH RFC 1/2] spmi: Add support for multi-master
In-Reply-To: <CAA8EJpo-16u34Yc6MLmHSqFrQ0VrZAq6TwGeVc5WFwMmhruqoA@mail.gmail.com>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
 <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>
 <CAA8EJpqsJmv36=o1aTjVH6eMHXMg8BHNpiDvs+Q8YB23ezVGtQ@mail.gmail.com>
 <ZcMvFtAwQQjAZhk6@linaro.org>
 <CAA8EJprqWLX7_yWZzKp3FAKFGkSkk041f9hj1uXuRBrbH5APyQ@mail.gmail.com>
 <ZcNIddeG6VHxBEOQ@linaro.org>
 <CAA8EJpo-16u34Yc6MLmHSqFrQ0VrZAq6TwGeVc5WFwMmhruqoA@mail.gmail.com>
Message-ID: <b4018932-2fcb-4a15-9ec4-e29e5761d3e0@collabora.com>

Il 07/02/24 12:45, Dmitry Baryshkov ha scritto:
> On Wed, 7 Feb 2024 at 11:08, Abel Vesa <abel.vesa at linaro.org> wrote:
>>
>> On 24-02-07 09:23:09, Dmitry Baryshkov wrote:
>>> On Wed, 7 Feb 2024 at 09:19, Abel Vesa <abel.vesa at linaro.org> wrote:
>>>>
>>>> On 24-02-07 01:55:39, Dmitry Baryshkov wrote:
>>>>> On Wed, 7 Feb 2024 at 01:34, Abel Vesa <abel.vesa at linaro.org> wrote:
>>>>>>
>>>>>> Some newer SPMI controllers support multiple bus masters.
>>>>>> Such a master can control multiple slave devices. The generic
>>>>>> framework needs to be able to pass on the master id to the
>>>>>> controller-specific driver. So do that. The framework will
>>>>>> check if the devicetree child nodes are actually bus masters
>>>>>> and will register the devices for each master. The legacy
>>>>>> approach will still be supported for backwards compatibility.
>>>>>
>>>>> Please remind me, are those two actual bus musters driving a single
>>>>> bus in parallel or two SPMI buses being handled by a single device? In
>>>>> the latter case this implementation is incorrect. There should be
>>>>> multiple spmi_controller instances, one for each bus. Allocate them in
>>>>> a loop and set ctrl->dev.of_node after allocating.
>>>>
>>>> It's two SPMI buses (two sets of wires) handled by the same controller,
>>>> HW-wise.
>>>>
>>>> If we register two spmi controllers with the kernel framework, it will
>>>> be HW inaccurate, because there is just one controller which has
>>>> multiple masters.
>>>
>>> struct spmi_controller is a controller for a single bus. Inside your
>>> device you have two SPMI buses, each can be controlled by its own
>>> struct spmi_controller. Just like devices that control multiple I2C,
>>> SPI or USB busses register a separate instance of the bus controller.
>>
>> Well, this is what this patchset is trying to do in the generic part.
>> The SPMI controller supports multiple buses (HW-wise) and therefore SW
>> implementation shouldn't be tied to single bus requirement.
> 
> So, after the off-line discussion:
> - add new compatible string for sm8450+
> - register two spmi controller instances

Well, I don't know about the actual hardware that you're trying to implement
but, in my opinion, the "idea" of this series does actually make sense.

The SPMI specification says that SPMI supports up to 4 masters, and up to
16 slaves.

Just my two cents.

Cheers,
Angelo

> - drop the master-id from the SPMI interface
> - optionally: think about having a new separate driver for v7 SPMI.
> 
>>
>>>
>>>>
>>>> I'm not saying it might not work. But, to me, it looks more like a hack.
>>>>
>>>> Basically, we would be mapping HW bus masters to kernel controllers.
>>>
>>> Buses, not just masters.
>>>
>>>>
>>>>>
>>>>>>
>>>>>> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
>>>>>> ---
>>>>>>   drivers/spmi/spmi-mtk-pmif.c |  6 ++--
>>>>>>   drivers/spmi/spmi-pmic-arb.c | 10 +++---
>>>>>>   drivers/spmi/spmi.c          | 76 ++++++++++++++++++++++++++++++--------------
>>>>>>   include/linux/spmi.h         | 10 +++---
>>>>>>   4 files changed, 67 insertions(+), 35 deletions(-)
>>>>>
>>>>> --
>>>>> With best wishes
>>>>> Dmitry
>>>
>>>
>>>
>>> --
>>> With best wishes
>>> Dmitry
> 
> 
> 




From broonie at kernel.org  Wed Feb  7 04:48:58 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 7 Feb 2024 12:48:58 +0000
Subject: [PATCH] arm64/sve: Document that __SVE_VQ_MAX is much larger
 than needed
In-Reply-To: <ZcNxJ56+bvcUTGlT@e133380.arm.com>
References: <20240206-arm64-sve-vl-max-comment-v1-1-dddf16414412@kernel.org>
 <ZcNxJ56+bvcUTGlT@e133380.arm.com>
Message-ID: <ZcN8OltRDUlDlTHQ@finisterre.sirena.org.uk>

On Wed, Feb 07, 2024 at 12:01:43PM +0000, Dave Martin wrote:
> On Tue, Feb 06, 2024 at 04:27:01PM +0000, Mark Brown wrote:

> > +/*
> > + * Note that for future proofing __SVE_VQ_MAX is defined much larger
> > + * than the actual architecture maximum of 16.
> > + */

> I think that putting shadow #defines in comments in UAPI headers is a
> really bad idea...  is this a normative statement about the user API,
> or what?

Well, the only reason I'm mentioning the constant here is that
__SVE_VQ_MIN is defined too and has a perfectly good value, things look
a bit neater with a shared comment block.  I'm not sure there's a hugely
meaingful difference between having a comment adjacent to a named
constant in a header and one a couple of lines away that mentions the
constant by name.

> My concern is that if we muddy the waters here different bits of
> software will do different things and we will get a mess with no
> advantages.

> Portability issues may ensue if userspace software feels it can
> substitute some other value for this constant, since we can't control
> what userspace uses it for.

I don't think we want people using this at all, ideally we'd remove it
but it's in the uapi.

> Would it be sufficient to say something like:

> /*
>  * Yes, this is 512 QUADWORDS.
>  * Never allocate memory or size structures based on the value of this
>  * constant.
>  */
> >  #define __SVE_VQ_MAX		512

I think the fact that this vector length is more than an order of
magnitude more than is architecturally supported at present needs to be
conveyed, it's perfectly reasonable for people to not want to do dynamic
allocation/sizing of buffers in some applications and the above sounds
more like stylistic guidance about using dynamic sizing to improve
memory usage.

> Though comments might be better placed alongsize SVE_VQ_MAX at al., in
> ptrace.h and sigcontext.h rather than here.  The leading __ should at
> least be a hint that __SVE_VQ_MAX shouldn't be used directly by
> anyone...

Yeah, the multiple layers of indirection aren't helpful here.  We
probably need to comment it in both places 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/20240207/e1877577/attachment-0001.sig>

From nm at ti.com  Wed Feb  7 04:54:10 2024
From: nm at ti.com (Nishanth Menon)
Date: Wed, 7 Feb 2024 06:54:10 -0600
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240207091100.4001428-1-u-kumar1@ti.com>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
Message-ID: <20240207125410.r2q3jcplvif7dvt2@tumbling>

On 14:41-20240207, Udit Kumar wrote:
> Most of clocks and their parents are defined in contiguous range,
> But in few cases, there is gap in clock numbers[0].
> Driver assumes clocks to be in contiguous range, and add their clock
> ids incrementally.
> 
> New firmware started returning error while calling get_freq and is_on
> API for non-available clock ids.
> 
> In this fix, driver checks and adds only valid clock ids.
> 
> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
> 
> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> Section Clocks for NAVSS0_CPTS_0 Device,
> clock id 12-15 not present.
> 
> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
> ---
> Changelog
> Changes in v3
> - instead of get_freq, is_auto API is used to check validilty of clock
> - Address comments of v2, to have preindex increment
> Link to v2 https://lore.kernel.org/all/20240206104357.3803517-1-u-kumar1 at ti.com/
> 
> Changes in v2
> - Updated commit message
> - Simplified logic for valid clock id
> link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/
> 
> 
> P.S
> Firmawre returns total num_parents count including non available ids.
> For above device id NAVSS0_CPTS_0, number of parents clocks are 16
> i.e from id 2 to 17. But out of these ids few are not valid.
> So driver adds only valid clock ids out ot total.
> 
> Original logs
> https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
> Line 2630 for error
> 
> Logs with fix v3
> https://gist.github.com/uditkumarti/94e3e28d62282fd708dbfe37435ce1d9#file-v3
> Line 2586
> 
> 
>  drivers/clk/keystone/sci-clk.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> index 35fe197dd303..31b7df05d7bb 100644
> --- a/drivers/clk/keystone/sci-clk.c
> +++ b/drivers/clk/keystone/sci-clk.c
> @@ -516,6 +516,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  	struct sci_clk *sci_clk, *prev;
>  	int num_clks = 0;
>  	int num_parents;
> +	bool state;
>  	int clk_id;
>  	const char * const clk_names[] = {
>  		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
> @@ -583,16 +584,23 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  					num_parents = 255;
>  				}
>  
> -				clk_id = args.args[1] + 1;
> +				clk_id = args.args[1];
>  
>  				while (num_parents--) {
> +					/* Check if this clock id is valid */
> +					ret = provider->ops->is_auto(provider->sci,
> +						sci_clk->dev_id, ++clk_id, &state);

A bit too nice coding ;) => I had been confused momentarily by clk_id = args.args[1]
change just above till I saw that you are pre-incrementing
clk_id - Is there a harm in leaving the original clk_id increment logic
alone (it was much simpler to read up)?

> +
> +					if (ret)
> +						continue;
> +
>  					sci_clk = devm_kzalloc(dev,
>  							       sizeof(*sci_clk),
>  							       GFP_KERNEL);
>  					if (!sci_clk)
>  						return -ENOMEM;
>  					sci_clk->dev_id = args.args[0];
> -					sci_clk->clk_id = clk_id++;
> +					sci_clk->clk_id = clk_id;
>  					sci_clk->provider = provider;
>  					list_add_tail(&sci_clk->node, &clks);
>  
> -- 
> 2.34.1
> 

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From bjorn at kernel.org  Wed Feb  7 04:55:39 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Wed, 07 Feb 2024 13:55:39 +0100
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <87plx8y5s3.fsf@all.your.base.are.belong.to.us>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <87h6ily53k.fsf@all.your.base.are.belong.to.us>
 <CAAhSdy2PPjS6++Edh8NkgiBmcovTUjS5oXE2eR5ZwPfAfVA0ng@mail.gmail.com>
 <874jekag3w.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2XJYTfY4nXWtjK9OP1iXLDXBVF-=mN1SmJDmJ_dO5CohA@mail.gmail.com>
 <87plx8y5s3.fsf@all.your.base.are.belong.to.us>
Message-ID: <87sf24mo1g.fsf@all.your.base.are.belong.to.us>

Bj?rn T?pel <bjorn at kernel.org> writes:

>>> Hmm, seems like we're talking past each other, or at least I get the
>>> feeling I can't get my opinions out right. I'll try to do a quick PoC,
>>> to show you what I mean. That's probably easier than just talking about
>>> it. ...and maybe I'll come realizing I'm all wrong!
>>
>> I suggest to wait for my v13 and try something on top of that
>> otherwise we might duplicate efforts.
>
> OK!

I did some really rough code sketching, and I'm confident that you can
get rid of all ids_enabled_bitmap, hwirqs_used_bitmap, and the
corresponding functions/locks. I'd say one lock is enough, and the key
is having the per-cpu imsic_local_priv.vectors change from struct
imsic_vector * to struct imsic_vector **.

Using smp_call_function_single() to IPI enable (and disable if you don't
want to use the lazy timer disable mechanism) seems feasible as well!

(Let me know if you don't have the spare cycles, and I can help out.)


Bj?rn


From apatel at ventanamicro.com  Wed Feb  7 05:08:59 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 7 Feb 2024 18:38:59 +0530
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <87sf24mo1g.fsf@all.your.base.are.belong.to.us>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <87h6ily53k.fsf@all.your.base.are.belong.to.us> <CAAhSdy2PPjS6++Edh8NkgiBmcovTUjS5oXE2eR5ZwPfAfVA0ng@mail.gmail.com>
 <874jekag3w.fsf@all.your.base.are.belong.to.us> <CAK9=C2XJYTfY4nXWtjK9OP1iXLDXBVF-=mN1SmJDmJ_dO5CohA@mail.gmail.com>
 <87plx8y5s3.fsf@all.your.base.are.belong.to.us> <87sf24mo1g.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAK9=C2UiOXS7NE91ykvQHc8h8-DUAUwEuMphwC-df3__zK1dVg@mail.gmail.com>

On Wed, Feb 7, 2024 at 6:25?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Bj?rn T?pel <bjorn at kernel.org> writes:
>
> >>> Hmm, seems like we're talking past each other, or at least I get the
> >>> feeling I can't get my opinions out right. I'll try to do a quick PoC,
> >>> to show you what I mean. That's probably easier than just talking about
> >>> it. ...and maybe I'll come realizing I'm all wrong!
> >>
> >> I suggest to wait for my v13 and try something on top of that
> >> otherwise we might duplicate efforts.
> >
> > OK!
>
> I did some really rough code sketching, and I'm confident that you can
> get rid of all ids_enabled_bitmap, hwirqs_used_bitmap, and the
> corresponding functions/locks. I'd say one lock is enough, and the key
> is having the per-cpu imsic_local_priv.vectors change from struct
> imsic_vector * to struct imsic_vector **.

I have managed to remove hwirqs_bitmap (and related function).

Now, I am trying another approach to simplify locking using atomics.

>
> Using smp_call_function_single() to IPI enable (and disable if you don't
> want to use the lazy timer disable mechanism) seems feasible as well!

We have intentionally kept separate virq for synchronization because
this allows us to gather stats for debugging. Calling smp_call_function_single()
will not allow us to separately gather stats for sync IPIs.

The smp_call_function_single() eventually leads to __ipi_send_mask()
via send_ipi_mask() in arch/riscv so directly calling __ipi_send_mask()
for sync IPI is faster.

>
> (Let me know if you don't have the spare cycles, and I can help out.)
>
>
> Bj?rn

Regards,
Anup


From broonie at kernel.org  Wed Feb  7 05:09:51 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 7 Feb 2024 13:09:51 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <ZcN2XMkvqxNnsz5K@e133380.arm.com>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
 <ZcEW3y0IlEctOYBA@e133380.arm.com>
 <ZcEd2zU/JpeIwn5f@finisterre.sirena.org.uk>
 <ZcN2XMkvqxNnsz5K@e133380.arm.com>
Message-ID: <ZcOBH7ip/KMhLYGO@finisterre.sirena.org.uk>

On Wed, Feb 07, 2024 at 12:23:56PM +0000, Dave Martin wrote:
> On Mon, Feb 05, 2024 at 05:41:47PM +0000, Mark Brown wrote:
> > On Mon, Feb 05, 2024 at 05:11:59PM +0000, Dave Martin wrote:

> > > If the kernel is now juggling two #defines for the maximum vector size,
> > > this feels like it may seed bitrot...

> > Ideally we'd just not have the existing define externally but it's there
> > and it's been used.

> To clarify, is this intended as a temporary band-aid against silly
> behaviour while a cleaner solution is found, or a permanent limitation?

Ideally we'd just make everything dynamic, other than the regset issue
and the bitmasks used for VL enumeration we're there already.  Making
the bitmasks dynamically sized is more painful but are also doing
enumeration that userspace doesn't need to do.

> We'd need to change various things if the architectural max VL actually
> grew, so no forward-portability is lost immediately if the kernel
> adopts 16 internally, but I'm still a little concerned that people may
> poke about in the kernel code as a reference and this will muddy the
> waters regarding how to do the right thing in userspace (I know people
> shouldn't, but...)

I think if we fix the ptrace regset issue we're doing a good enough job
of just using fully dynamic sizing with no limits other than what's been
enumerated there.  We could possibly deal with the enumberation code by
changing it to use ZCR/SMCR_ELx_LEN_ based defines so that it's
obviously coming from what we can possibly write to the register but
it's a bit less clear how to do that neatly.
-------------- 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/20240207/92858ccb/attachment.sig>

From apatel at ventanamicro.com  Wed Feb  7 05:10:40 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 7 Feb 2024 18:40:40 +0530
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <87sf24mo1g.fsf@all.your.base.are.belong.to.us>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <87h6ily53k.fsf@all.your.base.are.belong.to.us> <CAAhSdy2PPjS6++Edh8NkgiBmcovTUjS5oXE2eR5ZwPfAfVA0ng@mail.gmail.com>
 <874jekag3w.fsf@all.your.base.are.belong.to.us> <CAK9=C2XJYTfY4nXWtjK9OP1iXLDXBVF-=mN1SmJDmJ_dO5CohA@mail.gmail.com>
 <87plx8y5s3.fsf@all.your.base.are.belong.to.us> <87sf24mo1g.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAK9=C2VLf96D8cm86D26=hJMsqehUM5x_=Cjyy+7kVcAZ5KrUQ@mail.gmail.com>

On Wed, Feb 7, 2024 at 6:25?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Bj?rn T?pel <bjorn at kernel.org> writes:
>
> >>> Hmm, seems like we're talking past each other, or at least I get the
> >>> feeling I can't get my opinions out right. I'll try to do a quick PoC,
> >>> to show you what I mean. That's probably easier than just talking about
> >>> it. ...and maybe I'll come realizing I'm all wrong!
> >>
> >> I suggest to wait for my v13 and try something on top of that
> >> otherwise we might duplicate efforts.
> >
> > OK!
>
> I did some really rough code sketching, and I'm confident that you can
> get rid of all ids_enabled_bitmap, hwirqs_used_bitmap, and the
> corresponding functions/locks. I'd say one lock is enough, and the key
> is having the per-cpu imsic_local_priv.vectors change from struct
> imsic_vector * to struct imsic_vector **.
>
> Using smp_call_function_single() to IPI enable (and disable if you don't
> want to use the lazy timer disable mechanism) seems feasible as well!
>
> (Let me know if you don't have the spare cycles, and I can help out.)

If you can help upstream IOMMU driver then that would be awesome.

Regards,
Anup


From colin.i.king at gmail.com  Wed Feb  7 05:11:13 2024
From: colin.i.king at gmail.com (Colin Ian King)
Date: Wed,  7 Feb 2024 13:11:13 +0000
Subject: [PATCH][next] mt76: Remove redundant assignment to variable tidno
Message-ID: <20240207131113.2450297-1-colin.i.king@gmail.com>

The variable tidno is being assigned a value that is not being read
and is being re-assigned a new value a few statements later.
The assignment is redundant and can be removed.

Cleans up clang scan warning:
drivers/net/wireless/mediatek/mt76/agg-rx.c:125:5: warning: Value stored
to 'tidno' during its initialization is never read [deadcode.DeadStores]

Signed-off-by: Colin Ian King <colin.i.king at gmail.com>
---
 drivers/net/wireless/mediatek/mt76/agg-rx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c b/drivers/net/wireless/mediatek/mt76/agg-rx.c
index 10cbd9e560e7..07c386c7b4d0 100644
--- a/drivers/net/wireless/mediatek/mt76/agg-rx.c
+++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c
@@ -122,7 +122,7 @@ mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
 	struct ieee80211_bar *bar = mt76_skb_get_hdr(skb);
 	struct mt76_wcid *wcid = status->wcid;
 	struct mt76_rx_tid *tid;
-	u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
+	u8 tidno;
 	u16 seqno;
 
 	if (!ieee80211_is_ctl(bar->frame_control))
-- 
2.39.2



From khalasa at piap.pl  Wed Feb  7 05:13:05 2024
From: khalasa at piap.pl (=?utf-8?Q?Krzysztof_Ha=C5=82asa?=)
Date: Wed, 07 Feb 2024 14:13:05 +0100
Subject: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <20240206134155.GB2827@pendragon.ideasonboard.com> (Laurent
	Pinchart's message of "Tue, 6 Feb 2024 15:41:55 +0200")
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
	<87r0hqnvxc.wl-kuninori.morimoto.gx@renesas.com>
	<20240206134155.GB2827@pendragon.ideasonboard.com>
Message-ID: <m3il30zace.fsf@t19.piap.pl>

Laurent,

Laurent Pinchart <laurent.pinchart at ideasonboard.com> writes:

>> +++ b/drivers/media/i2c/adv7604.c
>> @@ -3205,7 +3205,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
>>       np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
>>
>>       /* Parse the endpoint. */
>> -     endpoint = of_graph_get_next_endpoint(np, NULL);
>> +     endpoint = of_graph_get_endpoint_by_regs(np, 0, -1);
>
> I think this should be port 1 for the adv7611 and port2 for the adv7612.
> The adv7610 may need to use port 1 too, but the bindings likely need to
> be updated.

To be honest I have no idea about ADV7611 and 7612.
The 7610 I have on Tinyrex "mobo" seems to be single port.

ADV7611 seems to be mostly a 7610 in a different package (LQFP 64
instead of some BGA 76). The driver simply treats ADV7610 as a 7611.

ADV7612 is apparently dual port (only one port can be used at a time)
though:

[ADV7612] = {
        .type = ADV7612,
        .has_afe = false,
        .max_port = ADV76XX_PAD_HDMI_PORT_A,    /* B not supported */
        .num_dv_ports = 1,                      /* normally 2 */


All related in-tree DTS entries (as of v6.8.0-rc1) seem to be ADV7612.

To me it seems all known devices use the first port only.
-- 
Krzysztof "Chris" Ha?asa

Sie? Badawcza ?ukasiewicz
Przemys?owy Instytut Automatyki i Pomiar?w PIAP
Al. Jerozolimskie 202, 02-486 Warszawa


From khalasa at piap.pl  Wed Feb  7 05:14:33 2024
From: khalasa at piap.pl (=?utf-8?Q?Krzysztof_Ha=C5=82asa?=)
Date: Wed, 07 Feb 2024 14:14:33 +0100
Subject: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <9d1e99b0-892d-4a72-a9b3-886b8ed094b0@xs4all.nl> (Hans Verkuil's
	message of "Tue, 6 Feb 2024 15:44:45 +0100")
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
	<87r0hqnvxc.wl-kuninori.morimoto.gx@renesas.com>
	<20240206134155.GB2827@pendragon.ideasonboard.com>
	<9d1e99b0-892d-4a72-a9b3-886b8ed094b0@xs4all.nl>
Message-ID: <m3eddoza9y.fsf@t19.piap.pl>

Hans,

Hans Verkuil <hverkuil-cisco at xs4all.nl> writes:

> Ideally someone would have to actually test this, perhaps with one of those
> Renesas boards. While I do have one, it got bricked after I attempted a
> u-boot update :-(

May be reversible, though.
-- 
Krzysztof "Chris" Ha?asa

Sie? Badawcza ?ukasiewicz
Przemys?owy Instytut Automatyki i Pomiar?w PIAP
Al. Jerozolimskie 202, 02-486 Warszawa


From tongtiangen at huawei.com  Wed Feb  7 05:22:00 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Wed, 7 Feb 2024 21:22:00 +0800
Subject: [PATCH v11 1/5] uaccess: add generic fallback version of copy_mc_to_user()
In-Reply-To: <20240207132204.1720444-1-tongtiangen@huawei.com>
References: <20240207132204.1720444-1-tongtiangen@huawei.com>
Message-ID: <20240207132204.1720444-2-tongtiangen@huawei.com>

x86/powerpc has it's implementation of copy_mc_to_user(), we add generic
fallback in include/linux/uaccess.h prepare for other architechures to
enable CONFIG_ARCH_HAS_COPY_MC.

Signed-off-by: Tong Tiangen <tongtiangen at huawei.com>
Acked-by: Michael Ellerman <mpe at ellerman.id.au>
---
 arch/powerpc/include/asm/uaccess.h | 1 +
 arch/x86/include/asm/uaccess.h     | 1 +
 include/linux/uaccess.h            | 9 +++++++++
 3 files changed, 11 insertions(+)

diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index f1f9890f50d3..4bfd1e6f0702 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -381,6 +381,7 @@ copy_mc_to_user(void __user *to, const void *from, unsigned long n)
 
 	return n;
 }
+#define copy_mc_to_user copy_mc_to_user
 #endif
 
 extern long __copy_from_user_flushcache(void *dst, const void __user *src,
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 5c367c1290c3..fd56282ee9a8 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -497,6 +497,7 @@ copy_mc_to_kernel(void *to, const void *from, unsigned len);
 
 unsigned long __must_check
 copy_mc_to_user(void __user *to, const void *from, unsigned len);
+#define copy_mc_to_user copy_mc_to_user
 #endif
 
 /*
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 3064314f4832..550287c92990 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -205,6 +205,15 @@ copy_mc_to_kernel(void *dst, const void *src, size_t cnt)
 }
 #endif
 
+#ifndef copy_mc_to_user
+static inline unsigned long __must_check
+copy_mc_to_user(void *dst, const void *src, size_t cnt)
+{
+	check_object_size(src, cnt, true);
+	return raw_copy_to_user(dst, src, cnt);
+}
+#endif
+
 static __always_inline void pagefault_disabled_inc(void)
 {
 	current->pagefault_disabled++;
-- 
2.25.1



From tongtiangen at huawei.com  Wed Feb  7 05:22:04 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Wed, 7 Feb 2024 21:22:04 +0800
Subject: [PATCH v11 5/5] arm64: send SIGBUS to user process for SEA exception
In-Reply-To: <20240207132204.1720444-1-tongtiangen@huawei.com>
References: <20240207132204.1720444-1-tongtiangen@huawei.com>
Message-ID: <20240207132204.1720444-6-tongtiangen@huawei.com>

For SEA exception, kernel require take some action to recover from memory
error, such as isolate poison page adn kill failure thread, which are done
in memory_failure().

During the test, the failure thread cannot be killed due to this issue[1],
Here, I temporarily workaround this issue by sending signals to user
processes (!(PF_KTHREAD|PF_IO_WORKER|PF_WQ_WORKER|PF_USER_WORKER)) in
do_sea(). After [1] is merged, this patch can be rolled back or the SIGBUS
will be sent repeated.

[1]https://lore.kernel.org/lkml/20240204080144.7977-1-xueshuai at linux.alibaba.com/

Signed-off-by: Tong Tiangen <tongtiangen at huawei.com>
---
 arch/arm64/mm/fault.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 78f9d5ce83bb..a27bb2de1a7c 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -824,9 +824,6 @@ static int do_sea(unsigned long far, unsigned long esr, struct pt_regs *regs)
 	const struct fault_info *inf;
 	unsigned long siaddr;
 
-	if (do_apei_claim_sea(regs))
-		return 0;
-
 	inf = esr_to_fault_info(esr);
 	if (esr & ESR_ELx_FnV) {
 		siaddr = 0;
@@ -838,6 +835,19 @@ static int do_sea(unsigned long far, unsigned long esr, struct pt_regs *regs)
 		 */
 		siaddr  = untagged_addr(far);
 	}
+
+	if (do_apei_claim_sea(regs)) {
+		if (!(current->flags & (PF_KTHREAD |
+					PF_USER_WORKER |
+					PF_WQ_WORKER |
+					PF_IO_WORKER))) {
+			set_thread_esr(0, esr);
+			arm64_force_sig_fault(inf->sig, inf->code, siaddr,
+				"Uncorrected memory error on access to poison memory\n");
+		}
+		return 0;
+	}
+
 	arm64_notify_die(inf->name, regs, inf->sig, inf->code, siaddr, esr);
 
 	return 0;
-- 
2.25.1



From tongtiangen at huawei.com  Wed Feb  7 05:22:02 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Wed, 7 Feb 2024 21:22:02 +0800
Subject: [PATCH v11 3/5] mm/hwpoison: return -EFAULT when copy fail in copy_mc_[user]_highpage()
In-Reply-To: <20240207132204.1720444-1-tongtiangen@huawei.com>
References: <20240207132204.1720444-1-tongtiangen@huawei.com>
Message-ID: <20240207132204.1720444-4-tongtiangen@huawei.com>

If hardware errors are encountered during page copying, returning the bytes
not copied is not meaningful, and the caller cannot do any processing on
the remaining data. Returning -EFAULT is more reasonable, which represents
a hardware error encountered during the copying.

Signed-off-by: Tong Tiangen <tongtiangen at huawei.com>
---
 include/linux/highmem.h | 8 ++++----
 mm/khugepaged.c         | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 451c1dff0e87..c5ca1a1fc4f5 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -335,8 +335,8 @@ static inline void copy_highpage(struct page *to, struct page *from)
 /*
  * If architecture supports machine check exception handling, define the
  * #MC versions of copy_user_highpage and copy_highpage. They copy a memory
- * page with #MC in source page (@from) handled, and return the number
- * of bytes not copied if there was a #MC, otherwise 0 for success.
+ * page with #MC in source page (@from) handled, and return -EFAULT if there
+ * was a #MC, otherwise 0 for success.
  */
 static inline int copy_mc_user_highpage(struct page *to, struct page *from,
 					unsigned long vaddr, struct vm_area_struct *vma)
@@ -352,7 +352,7 @@ static inline int copy_mc_user_highpage(struct page *to, struct page *from,
 	kunmap_local(vto);
 	kunmap_local(vfrom);
 
-	return ret;
+	return ret ? -EFAULT : 0;
 }
 
 static inline int copy_mc_highpage(struct page *to, struct page *from)
@@ -368,7 +368,7 @@ static inline int copy_mc_highpage(struct page *to, struct page *from)
 	kunmap_local(vto);
 	kunmap_local(vfrom);
 
-	return ret;
+	return ret ? -EFAULT : 0;
 }
 #else
 static inline int copy_mc_user_highpage(struct page *to, struct page *from,
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index fe43fbc44525..d0f40c42f620 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -797,7 +797,7 @@ static int __collapse_huge_page_copy(pte_t *pte,
 			continue;
 		}
 		src_page = pte_page(pteval);
-		if (copy_mc_user_highpage(page, src_page, _address, vma) > 0) {
+		if (copy_mc_user_highpage(page, src_page, _address, vma)) {
 			result = SCAN_COPY_MC;
 			break;
 		}
@@ -2053,7 +2053,7 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr,
 			clear_highpage(hpage + (index % HPAGE_PMD_NR));
 			index++;
 		}
-		if (copy_mc_highpage(hpage + (page->index % HPAGE_PMD_NR), page) > 0) {
+		if (copy_mc_highpage(hpage + (page->index % HPAGE_PMD_NR), page)) {
 			result = SCAN_COPY_MC;
 			goto rollback;
 		}
-- 
2.25.1



From tongtiangen at huawei.com  Wed Feb  7 05:21:59 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Wed, 7 Feb 2024 21:21:59 +0800
Subject: [PATCH v11 0/5]arm64: add ARCH_HAS_COPY_MC support
Message-ID: <20240207132204.1720444-1-tongtiangen@huawei.com>

With the increase of memory capacity and density, the probability of memory
error also increases. The increasing size and density of server RAM in data
centers and clouds have shown increased uncorrectable memory errors.

Currently, more and more scenarios that can tolerate memory errors???such as
CoW[1,2], KSM copy[3], coredump copy[4], khugepaged[5,6], uaccess copy[7],
etc.

This patchset introduces a new processing framework on ARM64, which enables
ARM64 to support error recovery in the above scenarios, and more scenarios
can be expanded based on this in the future.

In arm64, memory error handling in do_sea(), which is divided into two cases:
 1. If the user state consumed the memory errors, the solution is to kill
    the user process and isolate the error page.
 2. If the kernel state consumed the memory errors, the solution is to
    panic.

For case 2, Undifferentiated panic may not be the optimal choice, as it can
be handled better. In some scenarios, we can avoid panic, such as uaccess,
if the uaccess fails due to memory error, only the user process will be
affected, killing the user process and isolating the user page with
hardware memory errors is a better choice.

[1] commit d302c2398ba2 ("mm, hwpoison: when copy-on-write hits poison, take page offline")
[2] commit 1cb9dc4b475c ("mm: hwpoison: support recovery from HugePage copy-on-write faults")
[3] commit 6b970599e807 ("mm: hwpoison: support recovery from ksm_might_need_to_copy()")
[4] commit 245f09226893 ("mm: hwpoison: coredump: support recovery from dump_user_range()")
[5] commit 98c76c9f1ef7 ("mm/khugepaged: recover from poisoned anonymous memory")
[6] commit 12904d953364 ("mm/khugepaged: recover from poisoned file-backed memory")
[7] commit 278b917f8cb9 ("x86/mce: Add _ASM_EXTABLE_CPY for copy user access")

------------------
Test result:

1. copy_page(), copy_mc_page() basic function test pass, and the disassembly
   contents remains the same before and after refactor.

2. copy_to/from_user() access kernel NULL pointer raise translation fault
   and dump error message then die(), test pass.

3. Test following scenarios: copy_from_user(), get_user(), COW.

   Before patched: trigger a hardware memory error then panic.
   After  patched: trigger a hardware memory error without panic.

   Testing step:
   step1. start an user-process.
   step2. poison(einj) the user-process's page.
   step3: user-process access the poison page in kernel mode, then trigger SEA.
   step4: the kernel will not panic, only the user process is killed, the poison
          page is isolated. (before patched, the kernel will panic in do_sea())

------------------

Since V10:
 Accroding Mark's suggestion:
 1. Merge V10's patch2 and patch3 to V11's patch2.
 2. Patch2(V11): use new fixup_type for ld* in copy_to_user(), fix fatal
    issues (NULL kernel pointeraccess) been fixup incorrectly.
 3. Patch2(V11): refactoring the logic of do_sea().
 4. Patch4(V11): Remove duplicate assembly logic and remove do_mte().

 Besides:
 1. Patch2(V11): remove st* insn's fixup, st* generally not trigger memory error.
 2. Split a part of the logic of patch2(V11) to patch5(V11), for detail,
    see patch5(V11)'s commit msg.
 3. Remove patch6(v10) ???arm64: introduce copy_mc_to_kernel() implementation???.
    During modification, some problems that cannot be solved in a short
    period are found. The patch will be released after the problems are
    solved.
 4. Add test result in this patch.
 5. Modify patchset title, do not use machine check and remove "-next".

Since V9:
 1. Rebase to latest kernel version 6.8-rc2.
 2. Add patch 6/6 to support copy_mc_to_kernel().

Since V8:
 1. Rebase to latest kernel version and fix topo in some of the patches.
 2. According to the suggestion of Catalin, I attempted to modify the
    return value of function copy_mc_[user]_highpage() to bytes not copied.
    During the modification process, I found that it would be more
    reasonable to return -EFAULT when copy error occurs (referring to the
    newly added patch 4). 

    For ARM64, the implementation of copy_mc_[user]_highpage() needs to
    consider MTE. Considering the scenario where data copying is successful
    but the MTE tag copying fails, it is also not reasonable to return
    bytes not copied.
 3. Considering the recent addition of machine check safe support for
    multiple scenarios, modify commit message for patch 5 (patch 4 for V8).

Since V7:
 Currently, there are patches supporting recover from poison
 consumption for the cow scenario[1]. Therefore, Supporting cow
 scenario under the arm64 architecture only needs to modify the relevant
 code under the arch/.
 [1]https://lore.kernel.org/lkml/20221031201029.102123-1-tony.luck at intel.com/

Since V6:
 Resend patches that are not merged into the mainline in V6.

Since V5:
 1. Add patch2/3 to add uaccess assembly helpers.
 2. Optimize the implementation logic of arm64_do_kernel_sea() in patch8.
 3. Remove kernel access fixup in patch9.
 All suggestion are from Mark. 

Since V4:
 1. According Michael's suggestion, add patch5.
 2. According Mark's suggestiog, do some restructuring to arm64
 extable, then a new adaptation of machine check safe support is made based
 on this.
 3. According Mark's suggestion, support machine check safe in do_mte() in
 cow scene.
 4. In V4, two patches have been merged into -next, so V5 not send these
 two patches.

Since V3:
 1. According to Robin's suggestion, direct modify user_ldst and
 user_ldp in asm-uaccess.h and modify mte.S.
 2. Add new macro USER_MC in asm-uaccess.h, used in copy_from_user.S
 and copy_to_user.S.
 3. According to Robin's suggestion, using micro in copy_page_mc.S to
 simplify code.
 4. According to KeFeng's suggestion, modify powerpc code in patch1.
 5. According to KeFeng's suggestion, modify mm/extable.c and some code
 optimization.

Since V2:
 1. According to Mark's suggestion, all uaccess can be recovered due to
    memory error.
 2. Scenario pagecache reading is also supported as part of uaccess
    (copy_to_user()) and duplication code problem is also solved. 
    Thanks for Robin's suggestion.
 3. According Mark's suggestion, update commit message of patch 2/5.
 4. According Borisllav's suggestion, update commit message of patch 1/5.

Since V1:
 1.Consistent with PPC/x86, Using CONFIG_ARCH_HAS_COPY_MC instead of
   ARM64_UCE_KERNEL_RECOVERY.
 2.Add two new scenes, cow and pagecache reading.
 3.Fix two small bug(the first two patch).

V1 in here:
https://lore.kernel.org/lkml/20220323033705.3966643-1-tongtiangen at huawei.com/

Tong Tiangen (5):
  uaccess: add generic fallback version of copy_mc_to_user()
  arm64: add support for ARCH_HAS_COPY_MC
  mm/hwpoison: return -EFAULT when copy fail in
    copy_mc_[user]_highpage()
  arm64: support copy_mc_[user]_highpage()
  arm64: send SIGBUS to user process for SEA exception

 arch/arm64/Kconfig                   |  1 +
 arch/arm64/include/asm/asm-extable.h | 31 ++++++++++++---
 arch/arm64/include/asm/asm-uaccess.h |  4 ++
 arch/arm64/include/asm/extable.h     |  1 +
 arch/arm64/include/asm/mte.h         |  9 +++++
 arch/arm64/include/asm/page.h        | 10 +++++
 arch/arm64/lib/Makefile              |  2 +
 arch/arm64/lib/copy_mc_page.S        | 37 ++++++++++++++++++
 arch/arm64/lib/copy_page.S           | 50 +++----------------------
 arch/arm64/lib/copy_page_template.S  | 56 ++++++++++++++++++++++++++++
 arch/arm64/lib/copy_to_user.S        | 10 ++---
 arch/arm64/lib/mte.S                 | 29 ++++++++++++++
 arch/arm64/mm/copypage.c             | 45 ++++++++++++++++++++++
 arch/arm64/mm/extable.c              | 19 ++++++++++
 arch/arm64/mm/fault.c                | 39 ++++++++++++++-----
 arch/powerpc/include/asm/uaccess.h   |  1 +
 arch/x86/include/asm/uaccess.h       |  1 +
 include/linux/highmem.h              | 16 ++++++--
 include/linux/uaccess.h              |  9 +++++
 mm/khugepaged.c                      |  4 +-
 20 files changed, 304 insertions(+), 70 deletions(-)
 create mode 100644 arch/arm64/lib/copy_mc_page.S
 create mode 100644 arch/arm64/lib/copy_page_template.S

-- 
2.25.1



From tongtiangen at huawei.com  Wed Feb  7 05:22:03 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Wed, 7 Feb 2024 21:22:03 +0800
Subject: [PATCH v11 4/5] arm64: support copy_mc_[user]_highpage()
In-Reply-To: <20240207132204.1720444-1-tongtiangen@huawei.com>
References: <20240207132204.1720444-1-tongtiangen@huawei.com>
Message-ID: <20240207132204.1720444-5-tongtiangen@huawei.com>

Currently, many scenarios that can tolerate memory errors when copying page
have been supported in the kernel[1~5], all of which are implemented by
copy_mc_[user]_highpage(). arm64 should also support this mechanism.

Due to mte, arm64 needs to have its own copy_mc_[user]_highpage()
architecture implementation, macros __HAVE_ARCH_COPY_MC_HIGHPAGE and
__HAVE_ARCH_COPY_MC_USER_HIGHPAGE have been added to control it.

Add new helper copy_mc_page() which provide a page copy implementation with
hardware memory error safe. The code logic of copy_mc_page() is the same as
copy_page(), the main difference is that the ldp insn of copy_mc_page()
contains the fixup type EX_TYPE_KACCESS_ERR_ZERO_ME_SAFE, therefore, the
main logic is extracted to copy_page_template.S.

[1] commit d302c2398ba2 ("mm, hwpoison: when copy-on-write hits poison, take page offline")
[2] commit 1cb9dc4b475c ("mm: hwpoison: support recovery from HugePage copy-on-write faults")
[3] commit 6b970599e807 ("mm: hwpoison: support recovery from ksm_might_need_to_copy()")
[4] commit 98c76c9f1ef7 ("mm/khugepaged: recover from poisoned anonymous memory")
[5] commit 12904d953364 ("mm/khugepaged: recover from poisoned file-backed memory")

Signed-off-by: Tong Tiangen <tongtiangen at huawei.com>
---
 arch/arm64/include/asm/mte.h        |  9 +++++
 arch/arm64/include/asm/page.h       | 10 ++++++
 arch/arm64/lib/Makefile             |  2 ++
 arch/arm64/lib/copy_mc_page.S       | 37 +++++++++++++++++++
 arch/arm64/lib/copy_page.S          | 50 +++-----------------------
 arch/arm64/lib/copy_page_template.S | 56 +++++++++++++++++++++++++++++
 arch/arm64/lib/mte.S                | 29 +++++++++++++++
 arch/arm64/mm/copypage.c            | 45 +++++++++++++++++++++++
 include/linux/highmem.h             |  8 +++++
 9 files changed, 201 insertions(+), 45 deletions(-)
 create mode 100644 arch/arm64/lib/copy_mc_page.S
 create mode 100644 arch/arm64/lib/copy_page_template.S

diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
index 91fbd5c8a391..dc68337c2623 100644
--- a/arch/arm64/include/asm/mte.h
+++ b/arch/arm64/include/asm/mte.h
@@ -92,6 +92,11 @@ static inline bool try_page_mte_tagging(struct page *page)
 void mte_zero_clear_page_tags(void *addr);
 void mte_sync_tags(pte_t pte, unsigned int nr_pages);
 void mte_copy_page_tags(void *kto, const void *kfrom);
+
+#ifdef CONFIG_ARCH_HAS_COPY_MC
+int mte_copy_mc_page_tags(void *kto, const void *kfrom);
+#endif
+
 void mte_thread_init_user(void);
 void mte_thread_switch(struct task_struct *next);
 void mte_cpu_setup(void);
@@ -128,6 +133,10 @@ static inline void mte_sync_tags(pte_t pte, unsigned int nr_pages)
 static inline void mte_copy_page_tags(void *kto, const void *kfrom)
 {
 }
+static inline int mte_copy_mc_page_tags(void *kto, const void *kfrom)
+{
+	return 0;
+}
 static inline void mte_thread_init_user(void)
 {
 }
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 2312e6ee595f..304cc86b8a10 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -29,6 +29,16 @@ void copy_user_highpage(struct page *to, struct page *from,
 void copy_highpage(struct page *to, struct page *from);
 #define __HAVE_ARCH_COPY_HIGHPAGE
 
+#ifdef CONFIG_ARCH_HAS_COPY_MC
+int copy_mc_page(void *to, const void *from);
+int copy_mc_highpage(struct page *to, struct page *from);
+#define __HAVE_ARCH_COPY_MC_HIGHPAGE
+
+int copy_mc_user_highpage(struct page *to, struct page *from,
+		unsigned long vaddr, struct vm_area_struct *vma);
+#define __HAVE_ARCH_COPY_MC_USER_HIGHPAGE
+#endif
+
 struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma,
 						unsigned long vaddr);
 #define vma_alloc_zeroed_movable_folio vma_alloc_zeroed_movable_folio
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 29490be2546b..a2fd865b816d 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -15,6 +15,8 @@ endif
 
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
 
+lib-$(CONFIG_ARCH_HAS_COPY_MC) += copy_mc_page.o
+
 obj-$(CONFIG_CRC32) += crc32.o
 
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
diff --git a/arch/arm64/lib/copy_mc_page.S b/arch/arm64/lib/copy_mc_page.S
new file mode 100644
index 000000000000..1e5fe6952869
--- /dev/null
+++ b/arch/arm64/lib/copy_mc_page.S
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/assembler.h>
+#include <asm/page.h>
+#include <asm/cpufeature.h>
+#include <asm/alternative.h>
+#include <asm/asm-extable.h>
+#include <asm/asm-uaccess.h>
+
+/*
+ * Copy a page from src to dest (both are page aligned) with memory error safe
+ *
+ * Parameters:
+ *	x0 - dest
+ *	x1 - src
+ * Returns:
+ * 	x0 - Return 0 if copy success, or -EFAULT if anything goes wrong
+ *	     while copying.
+ */
+	.macro ldp1 reg1, reg2, ptr, val
+	KERNEL_ME_SAFE(9998f, ldp \reg1, \reg2, [\ptr, \val])
+	.endm
+
+SYM_FUNC_START(__pi_copy_mc_page)
+#include "copy_page_template.S"
+
+	mov x0, #0
+	ret
+
+9998:	mov x0, #-EFAULT
+	ret
+
+SYM_FUNC_END(__pi_copy_mc_page)
+SYM_FUNC_ALIAS(copy_mc_page, __pi_copy_mc_page)
+EXPORT_SYMBOL(copy_mc_page)
diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S
index 6a56d7cf309d..5499f507bb75 100644
--- a/arch/arm64/lib/copy_page.S
+++ b/arch/arm64/lib/copy_page.S
@@ -17,52 +17,12 @@
  *	x0 - dest
  *	x1 - src
  */
-SYM_FUNC_START(__pi_copy_page)
-	ldp	x2, x3, [x1]
-	ldp	x4, x5, [x1, #16]
-	ldp	x6, x7, [x1, #32]
-	ldp	x8, x9, [x1, #48]
-	ldp	x10, x11, [x1, #64]
-	ldp	x12, x13, [x1, #80]
-	ldp	x14, x15, [x1, #96]
-	ldp	x16, x17, [x1, #112]
-
-	add	x0, x0, #256
-	add	x1, x1, #128
-1:
-	tst	x0, #(PAGE_SIZE - 1)
-
-	stnp	x2, x3, [x0, #-256]
-	ldp	x2, x3, [x1]
-	stnp	x4, x5, [x0, #16 - 256]
-	ldp	x4, x5, [x1, #16]
-	stnp	x6, x7, [x0, #32 - 256]
-	ldp	x6, x7, [x1, #32]
-	stnp	x8, x9, [x0, #48 - 256]
-	ldp	x8, x9, [x1, #48]
-	stnp	x10, x11, [x0, #64 - 256]
-	ldp	x10, x11, [x1, #64]
-	stnp	x12, x13, [x0, #80 - 256]
-	ldp	x12, x13, [x1, #80]
-	stnp	x14, x15, [x0, #96 - 256]
-	ldp	x14, x15, [x1, #96]
-	stnp	x16, x17, [x0, #112 - 256]
-	ldp	x16, x17, [x1, #112]
-
-	add	x0, x0, #128
-	add	x1, x1, #128
-
-	b.ne	1b
-
-	stnp	x2, x3, [x0, #-256]
-	stnp	x4, x5, [x0, #16 - 256]
-	stnp	x6, x7, [x0, #32 - 256]
-	stnp	x8, x9, [x0, #48 - 256]
-	stnp	x10, x11, [x0, #64 - 256]
-	stnp	x12, x13, [x0, #80 - 256]
-	stnp	x14, x15, [x0, #96 - 256]
-	stnp	x16, x17, [x0, #112 - 256]
+	.macro ldp1 reg1, reg2, ptr, val
+	ldp \reg1, \reg2, [\ptr, \val]
+	.endm
 
+SYM_FUNC_START(__pi_copy_page)
+#include "copy_page_template.S"
 	ret
 SYM_FUNC_END(__pi_copy_page)
 SYM_FUNC_ALIAS(copy_page, __pi_copy_page)
diff --git a/arch/arm64/lib/copy_page_template.S b/arch/arm64/lib/copy_page_template.S
new file mode 100644
index 000000000000..b3ddec2c7a27
--- /dev/null
+++ b/arch/arm64/lib/copy_page_template.S
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ */
+
+/*
+ * Copy a page from src to dest (both are page aligned)
+ *
+ * Parameters:
+ *	x0 - dest
+ *	x1 - src
+ */
+	ldp1	x2, x3, x1, #0
+	ldp1	x4, x5, x1, #16
+	ldp1	x6, x7, x1, #32
+	ldp1	x8, x9, x1, #48
+	ldp1	x10, x11, x1, #64
+	ldp1	x12, x13, x1, #80
+	ldp1	x14, x15, x1, #96
+	ldp1	x16, x17, x1, #112
+
+	add	x0, x0, #256
+	add	x1, x1, #128
+1:
+	tst	x0, #(PAGE_SIZE - 1)
+
+	stnp	x2, x3, [x0, #-256]
+	ldp1	x2, x3, x1, #0
+	stnp	x4, x5, [x0, #16 - 256]
+	ldp1	x4, x5, x1, #16
+	stnp	x6, x7, [x0, #32 - 256]
+	ldp1	x6, x7, x1, #32
+	stnp	x8, x9, [x0, #48 - 256]
+	ldp1	x8, x9, x1, #48
+	stnp	x10, x11, [x0, #64 - 256]
+	ldp1	x10, x11, x1, #64
+	stnp	x12, x13, [x0, #80 - 256]
+	ldp1	x12, x13, x1, #80
+	stnp	x14, x15, [x0, #96 - 256]
+	ldp1	x14, x15, x1, #96
+	stnp	x16, x17, [x0, #112 - 256]
+	ldp1	x16, x17, x1, #112
+
+	add	x0, x0, #128
+	add	x1, x1, #128
+
+	b.ne	1b
+
+	stnp	x2, x3, [x0, #-256]
+	stnp	x4, x5, [x0, #16 - 256]
+	stnp	x6, x7, [x0, #32 - 256]
+	stnp	x8, x9, [x0, #48 - 256]
+	stnp	x10, x11, [x0, #64 - 256]
+	stnp	x12, x13, [x0, #80 - 256]
+	stnp	x14, x15, [x0, #96 - 256]
+	stnp	x16, x17, [x0, #112 - 256]
diff --git a/arch/arm64/lib/mte.S b/arch/arm64/lib/mte.S
index 5018ac03b6bf..50ef24318281 100644
--- a/arch/arm64/lib/mte.S
+++ b/arch/arm64/lib/mte.S
@@ -80,6 +80,35 @@ SYM_FUNC_START(mte_copy_page_tags)
 	ret
 SYM_FUNC_END(mte_copy_page_tags)
 
+#ifdef CONFIG_ARCH_HAS_COPY_MC
+/*
+ * Copy the tags from the source page to the destination one wiht machine check safe
+ *   x0 - address of the destination page
+ *   x1 - address of the source page
+ * Returns:
+ *   x0 - Return 0 if copy success, or
+ *        -EFAULT if anything goes wrong while copying.
+ */
+SYM_FUNC_START(mte_copy_mc_page_tags)
+	mov	x2, x0
+	mov	x3, x1
+	multitag_transfer_size x5, x6
+1:
+KERNEL_ME_SAFE(2f, ldgm	x4, [x3])
+	stgm	x4, [x2]
+	add	x2, x2, x5
+	add	x3, x3, x5
+	tst	x2, #(PAGE_SIZE - 1)
+	b.ne	1b
+
+	mov x0, #0
+	ret
+
+2:	mov x0, #-EFAULT
+	ret
+SYM_FUNC_END(mte_copy_mc_page_tags)
+#endif
+
 /*
  * Read tags from a user buffer (one tag per byte) and set the corresponding
  * tags at the given kernel address. Used by PTRACE_POKEMTETAGS.
diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
index a7bb20055ce0..ff0d9ceea2a4 100644
--- a/arch/arm64/mm/copypage.c
+++ b/arch/arm64/mm/copypage.c
@@ -40,3 +40,48 @@ void copy_user_highpage(struct page *to, struct page *from,
 	flush_dcache_page(to);
 }
 EXPORT_SYMBOL_GPL(copy_user_highpage);
+
+#ifdef CONFIG_ARCH_HAS_COPY_MC
+/*
+ * Return -EFAULT if anything goes wrong while copying page or mte.
+ */
+int copy_mc_highpage(struct page *to, struct page *from)
+{
+	void *kto = page_address(to);
+	void *kfrom = page_address(from);
+	int ret;
+
+	ret = copy_mc_page(kto, kfrom);
+	if (ret)
+		return -EFAULT;
+
+	if (kasan_hw_tags_enabled())
+		page_kasan_tag_reset(to);
+
+	if (system_supports_mte() && page_mte_tagged(from)) {
+		/* It's a new page, shouldn't have been tagged yet */
+		WARN_ON_ONCE(!try_page_mte_tagging(to));
+		ret = mte_copy_mc_page_tags(kto, kfrom);
+		if (ret)
+			return -EFAULT;
+
+		set_page_mte_tagged(to);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(copy_mc_highpage);
+
+int copy_mc_user_highpage(struct page *to, struct page *from,
+			unsigned long vaddr, struct vm_area_struct *vma)
+{
+	int ret;
+
+	ret = copy_mc_highpage(to, from);
+	if (!ret)
+		flush_dcache_page(to);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(copy_mc_user_highpage);
+#endif
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index c5ca1a1fc4f5..a42470ca42f2 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -332,6 +332,7 @@ static inline void copy_highpage(struct page *to, struct page *from)
 #endif
 
 #ifdef copy_mc_to_kernel
+#ifndef __HAVE_ARCH_COPY_MC_USER_HIGHPAGE
 /*
  * If architecture supports machine check exception handling, define the
  * #MC versions of copy_user_highpage and copy_highpage. They copy a memory
@@ -354,7 +355,9 @@ static inline int copy_mc_user_highpage(struct page *to, struct page *from,
 
 	return ret ? -EFAULT : 0;
 }
+#endif
 
+#ifndef __HAVE_ARCH_COPY_MC_HIGHPAGE
 static inline int copy_mc_highpage(struct page *to, struct page *from)
 {
 	unsigned long ret;
@@ -370,20 +373,25 @@ static inline int copy_mc_highpage(struct page *to, struct page *from)
 
 	return ret ? -EFAULT : 0;
 }
+#endif
 #else
+#ifndef __HAVE_ARCH_COPY_MC_USER_HIGHPAGE
 static inline int copy_mc_user_highpage(struct page *to, struct page *from,
 					unsigned long vaddr, struct vm_area_struct *vma)
 {
 	copy_user_highpage(to, from, vaddr, vma);
 	return 0;
 }
+#endif
 
+#ifndef __HAVE_ARCH_COPY_MC_HIGHPAGE
 static inline int copy_mc_highpage(struct page *to, struct page *from)
 {
 	copy_highpage(to, from);
 	return 0;
 }
 #endif
+#endif
 
 static inline void memcpy_page(struct page *dst_page, size_t dst_off,
 			       struct page *src_page, size_t src_off,
-- 
2.25.1



From tongtiangen at huawei.com  Wed Feb  7 05:22:01 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Wed, 7 Feb 2024 21:22:01 +0800
Subject: [PATCH v11 2/5] arm64: add support for ARCH_HAS_COPY_MC
In-Reply-To: <20240207132204.1720444-1-tongtiangen@huawei.com>
References: <20240207132204.1720444-1-tongtiangen@huawei.com>
Message-ID: <20240207132204.1720444-3-tongtiangen@huawei.com>

For the arm64 kernel, when it processes hardware memory errors for
synchronize notifications(do_sea()), if the errors is consumed within the
kernel, the current processing is panic. However, it is not optimal.

Take copy_from/to_user for example, If ld* triggers a memory error, even in
kernel mode, only the associated process is affected. Killing the user
process and isolating the corrupt page is a better choice.

New fixup type EX_TYPE_KACCESS_ERR_ZERO_ME_SAFE is added to identify insn
that can recover from memory errors triggered by access to kernel memory.

Signed-off-by: Tong Tiangen <tongtiangen at huawei.com>
---
 arch/arm64/Kconfig                   |  1 +
 arch/arm64/include/asm/asm-extable.h | 31 +++++++++++++++++++++++-----
 arch/arm64/include/asm/asm-uaccess.h |  4 ++++
 arch/arm64/include/asm/extable.h     |  1 +
 arch/arm64/lib/copy_to_user.S        | 10 ++++-----
 arch/arm64/mm/extable.c              | 19 +++++++++++++++++
 arch/arm64/mm/fault.c                | 27 +++++++++++++++++-------
 7 files changed, 75 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 96fb363d2f52..72b651c461d5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -20,6 +20,7 @@ config ARM64
 	select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
 	select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
 	select ARCH_HAS_CACHE_LINE_SIZE
+	select ARCH_HAS_COPY_MC if ACPI_APEI_GHES
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE
diff --git a/arch/arm64/include/asm/asm-extable.h b/arch/arm64/include/asm/asm-extable.h
index 980d1dd8e1a3..9c0664fe1eb1 100644
--- a/arch/arm64/include/asm/asm-extable.h
+++ b/arch/arm64/include/asm/asm-extable.h
@@ -5,11 +5,13 @@
 #include <linux/bits.h>
 #include <asm/gpr-num.h>
 
-#define EX_TYPE_NONE			0
-#define EX_TYPE_BPF			1
-#define EX_TYPE_UACCESS_ERR_ZERO	2
-#define EX_TYPE_KACCESS_ERR_ZERO	3
-#define EX_TYPE_LOAD_UNALIGNED_ZEROPAD	4
+#define EX_TYPE_NONE				0
+#define EX_TYPE_BPF				1
+#define EX_TYPE_UACCESS_ERR_ZERO		2
+#define EX_TYPE_KACCESS_ERR_ZERO		3
+#define EX_TYPE_LOAD_UNALIGNED_ZEROPAD		4
+/* kernel access memory error safe */
+#define EX_TYPE_KACCESS_ERR_ZERO_ME_SAFE	5
 
 /* Data fields for EX_TYPE_UACCESS_ERR_ZERO */
 #define EX_DATA_REG_ERR_SHIFT	0
@@ -51,6 +53,17 @@
 #define _ASM_EXTABLE_UACCESS(insn, fixup)				\
 	_ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, wzr, wzr)
 
+#define _ASM_EXTABLE_KACCESS_ERR_ZERO_ME_SAFE(insn, fixup, err, zero)	\
+	__ASM_EXTABLE_RAW(insn, fixup, 					\
+			  EX_TYPE_KACCESS_ERR_ZERO_ME_SAFE,		\
+			  (						\
+			    EX_DATA_REG(ERR, err) |			\
+			    EX_DATA_REG(ZERO, zero)			\
+			  ))
+
+#define _ASM_EXTABLE_KACCESS_ME_SAFE(insn, fixup)			\
+	_ASM_EXTABLE_KACCESS_ERR_ZERO_ME_SAFE(insn, fixup, wzr, wzr)
+
 /*
  * Create an exception table entry for uaccess `insn`, which will branch to `fixup`
  * when an unhandled fault is taken.
@@ -69,6 +82,14 @@
 	.endif
 	.endm
 
+/*
+ * Create an exception table entry for kaccess me(memory error) safe `insn`, which
+ * will branch to `fixup` when an unhandled fault is taken.
+ */
+	.macro          _asm_extable_kaccess_me_safe, insn, fixup
+	_ASM_EXTABLE_KACCESS_ME_SAFE(\insn, \fixup)
+	.endm
+
 #else /* __ASSEMBLY__ */
 
 #include <linux/stringify.h>
diff --git a/arch/arm64/include/asm/asm-uaccess.h b/arch/arm64/include/asm/asm-uaccess.h
index 5b6efe8abeeb..7bbebfa5b710 100644
--- a/arch/arm64/include/asm/asm-uaccess.h
+++ b/arch/arm64/include/asm/asm-uaccess.h
@@ -57,6 +57,10 @@ alternative_else_nop_endif
 	.endm
 #endif
 
+#define KERNEL_ME_SAFE(l, x...)			\
+9999:	x;					\
+	_asm_extable_kaccess_me_safe	9999b, l
+
 #define USER(l, x...)				\
 9999:	x;					\
 	_asm_extable_uaccess	9999b, l
diff --git a/arch/arm64/include/asm/extable.h b/arch/arm64/include/asm/extable.h
index 72b0e71cc3de..bc49443bc502 100644
--- a/arch/arm64/include/asm/extable.h
+++ b/arch/arm64/include/asm/extable.h
@@ -46,4 +46,5 @@ bool ex_handler_bpf(const struct exception_table_entry *ex,
 #endif /* !CONFIG_BPF_JIT */
 
 bool fixup_exception(struct pt_regs *regs);
+bool fixup_exception_me(struct pt_regs *regs);
 #endif
diff --git a/arch/arm64/lib/copy_to_user.S b/arch/arm64/lib/copy_to_user.S
index 802231772608..2ac716c0d6d8 100644
--- a/arch/arm64/lib/copy_to_user.S
+++ b/arch/arm64/lib/copy_to_user.S
@@ -20,7 +20,7 @@
  *	x0 - bytes not copied
  */
 	.macro ldrb1 reg, ptr, val
-	ldrb  \reg, [\ptr], \val
+	KERNEL_ME_SAFE(9998f, ldrb  \reg, [\ptr], \val)
 	.endm
 
 	.macro strb1 reg, ptr, val
@@ -28,7 +28,7 @@
 	.endm
 
 	.macro ldrh1 reg, ptr, val
-	ldrh  \reg, [\ptr], \val
+	KERNEL_ME_SAFE(9998f, ldrh  \reg, [\ptr], \val)
 	.endm
 
 	.macro strh1 reg, ptr, val
@@ -36,7 +36,7 @@
 	.endm
 
 	.macro ldr1 reg, ptr, val
-	ldr \reg, [\ptr], \val
+	KERNEL_ME_SAFE(9998f, ldr \reg, [\ptr], \val)
 	.endm
 
 	.macro str1 reg, ptr, val
@@ -44,7 +44,7 @@
 	.endm
 
 	.macro ldp1 reg1, reg2, ptr, val
-	ldp \reg1, \reg2, [\ptr], \val
+	KERNEL_ME_SAFE(9998f, ldp \reg1, \reg2, [\ptr], \val)
 	.endm
 
 	.macro stp1 reg1, reg2, ptr, val
@@ -64,7 +64,7 @@ SYM_FUNC_START(__arch_copy_to_user)
 9997:	cmp	dst, dstin
 	b.ne	9998f
 	// Before being absolutely sure we couldn't copy anything, try harder
-	ldrb	tmp1w, [srcin]
+KERNEL_ME_SAFE(9998f, ldrb	tmp1w, [srcin])
 USER(9998f, sttrb tmp1w, [dst])
 	add	dst, dst, #1
 9998:	sub	x0, end, dst			// bytes not copied
diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c
index 228d681a8715..8c690ae61944 100644
--- a/arch/arm64/mm/extable.c
+++ b/arch/arm64/mm/extable.c
@@ -72,7 +72,26 @@ bool fixup_exception(struct pt_regs *regs)
 		return ex_handler_uaccess_err_zero(ex, regs);
 	case EX_TYPE_LOAD_UNALIGNED_ZEROPAD:
 		return ex_handler_load_unaligned_zeropad(ex, regs);
+	case EX_TYPE_KACCESS_ERR_ZERO_ME_SAFE:
+		return false;
 	}
 
 	BUG();
 }
+
+bool fixup_exception_me(struct pt_regs *regs)
+{
+	const struct exception_table_entry *ex;
+
+	ex = search_exception_tables(instruction_pointer(regs));
+	if (!ex)
+		return false;
+
+	switch (ex->type) {
+	case EX_TYPE_UACCESS_ERR_ZERO:
+	case EX_TYPE_KACCESS_ERR_ZERO_ME_SAFE:
+		return ex_handler_uaccess_err_zero(ex, regs);
+	}
+
+	return false;
+}
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 13189322a38f..78f9d5ce83bb 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -802,21 +802,32 @@ static int do_bad(unsigned long far, unsigned long esr, struct pt_regs *regs)
 	return 1; /* "fault" */
 }
 
+/*
+ * APEI claimed this as a firmware-first notification.
+ * Some processing deferred to task_work before ret_to_user().
+ */
+static bool do_apei_claim_sea(struct pt_regs *regs)
+{
+	if (user_mode(regs)) {
+		if (!apei_claim_sea(regs))
+			return true;
+	} else if (IS_ENABLED(CONFIG_ARCH_HAS_COPY_MC)) {
+		if (fixup_exception_me(regs) && !apei_claim_sea(regs))
+			return true;
+	}
+
+	return false;
+}
+
 static int do_sea(unsigned long far, unsigned long esr, struct pt_regs *regs)
 {
 	const struct fault_info *inf;
 	unsigned long siaddr;
 
-	inf = esr_to_fault_info(esr);
-
-	if (user_mode(regs) && apei_claim_sea(regs) == 0) {
-		/*
-		 * APEI claimed this as a firmware-first notification.
-		 * Some processing deferred to task_work before ret_to_user().
-		 */
+	if (do_apei_claim_sea(regs))
 		return 0;
-	}
 
+	inf = esr_to_fault_info(esr);
 	if (esr & ESR_ELx_FnV) {
 		siaddr = 0;
 	} else {
-- 
2.25.1



From lukas.bulwahn at gmail.com  Wed Feb  7 05:22:31 2024
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Wed,  7 Feb 2024 14:22:31 +0100
Subject: [PATCH] MAINTAINERS: repair entry for MICROCHIP MCP16502 PMIC DRIVER
Message-ID: <20240207132231.16392-1-lukas.bulwahn@gmail.com>

Commit 64db3e8d7be0 ("regulator: dt-bindings: microchip,mcp16502: convert
to YAML") converts mcp16502-regulator.txt to microchip,mcp16502.yaml, but
misses to adjust its reference in MAINTAINERS.

Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a
broken reference.

Repair this file reference in MICROCHIP MCP16502 PMIC DRIVER.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
Mark, please pick this minor clean-up patch on top of the commit above.

 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index bb234d11f21e..e5087e4659f3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14415,7 +14415,7 @@ MICROCHIP MCP16502 PMIC DRIVER
 M:	Claudiu Beznea <claudiu.beznea at tuxon.dev>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Supported
-F:	Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
+F:	Documentation/devicetree/bindings/regulator/microchip,mcp16502.yaml
 F:	drivers/regulator/mcp16502.c
 
 MICROCHIP MCP3564 ADC DRIVER
-- 
2.17.1



From tomi.valkeinen at ideasonboard.com  Wed Feb  7 05:24:17 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Wed, 7 Feb 2024 15:24:17 +0200
Subject: [PATCH v3 0/5] Fixing live video input in ZynqMP DPSUB
In-Reply-To: <20240124025402.373620-1-anatoliy.klymenko@amd.com>
References: <20240124025402.373620-1-anatoliy.klymenko@amd.com>
Message-ID: <b7148c0e-bda7-4d20-bb92-4f81d62ed7a7@ideasonboard.com>

On 24/01/2024 04:53, Anatoliy Klymenko wrote:
> Add few missing pieces to support ZynqMP DPSUB live video in mode.
> 
> ZynqMP DPSUB supports 2 modes of operations in regard to video data
> input.
>      
> In the first mode, DPSUB uses DMA engine to pull video data from memory
> buffers. To support this the driver implements CRTC and DRM bridge
> representing DP encoder.
>      
> In the second mode, DPSUB acquires video data pushed from FPGA and
> passes it downstream to DP output. This mode of operation is modeled in
> the driver as a DRM bridge that should be attached to some external
> CRTC.
> 
> Patches 1/5,2/5,3/5,4/5 are minor fixes.
> 
> DPSUB requires input live video format to be configured.
> Patch 5/5: The DP Subsystem requires the input live video format to be
> configured. In this patch, we are assuming that the CRTC's bus format is
> fixed (typical for FPGA CRTC) and comes from the device tree. This is a
> proposed solution, as there is no API to query CRTC output bus format
> or negotiate it in any other way.
> 
> Changes in v2:
> - Address reviewers' comments:
>    - More elaborate and consistent comments / commit messages
>    - Fix includes' order
>    - Replace of_property_read_u32_index() with of_property_read_u32()
> 
> Changes in v3:
> - Split patch #3 into 3) moving status register clear immediately after
>    read; 4) masking status against interrupts' mask
> 
> Link to v1: https://lore.kernel.org/all/20240112234222.913138-1-anatoliy.klymenko at amd.com/
> Link to v2: https://lore.kernel.org/all/20240119055437.2549149-1-anatoliy.klymenko at amd.com/
> 
> Anatoliy Klymenko (5):
>    drm: xlnx: zynqmp_dpsub: Make drm bridge discoverable
>    drm: xlnx: zynqmp_dpsub: Fix timing for live mode
>    drm: xlnx: zynqmp_dpsub: Clear status register ASAP
>    drm: xlnx: zynqmp_dpsub: Filter interrupts against mask
>    drm: xlnx: zynqmp_dpsub: Set live video in format
> 
>   drivers/gpu/drm/xlnx/zynqmp_disp.c      | 111 +++++++++++++++++++++---
>   drivers/gpu/drm/xlnx/zynqmp_disp.h      |   3 +-
>   drivers/gpu/drm/xlnx/zynqmp_disp_regs.h |   8 +-
>   drivers/gpu/drm/xlnx/zynqmp_dp.c        |  16 +++-
>   drivers/gpu/drm/xlnx/zynqmp_kms.c       |   2 +-
>   5 files changed, 119 insertions(+), 21 deletions(-)
> 

Thanks! I have pushed patches 1 to 4 to drm-misc-next. As Laurent said, 
the fifth one needs some more work.

  Tomi



From kvalo at kernel.org  Wed Feb  7 05:31:40 2024
From: kvalo at kernel.org (Kalle Valo)
Date: Wed, 07 Feb 2024 15:31:40 +0200
Subject: [PATCH][next] mt76: Remove redundant assignment to variable tidno
In-Reply-To: <20240207131113.2450297-1-colin.i.king@gmail.com> (Colin Ian
	King's message of "Wed, 7 Feb 2024 13:11:13 +0000")
References: <20240207131113.2450297-1-colin.i.king@gmail.com>
Message-ID: <87il30h03n.fsf@kernel.org>

Colin Ian King <colin.i.king at gmail.com> writes:

> The variable tidno is being assigned a value that is not being read
> and is being re-assigned a new value a few statements later.
> The assignment is redundant and can be removed.
>
> Cleans up clang scan warning:
> drivers/net/wireless/mediatek/mt76/agg-rx.c:125:5: warning: Value stored
> to 'tidno' during its initialization is never read [deadcode.DeadStores]
>
> Signed-off-by: Colin Ian King <colin.i.king at gmail.com>

"wifi:" missing from title.

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


From Dave.Martin at arm.com  Wed Feb  7 05:39:13 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 7 Feb 2024 13:39:13 +0000
Subject: [PATCH] arm64/sve: Document that __SVE_VQ_MAX is much larger
 than needed
In-Reply-To: <ZcN8OltRDUlDlTHQ@finisterre.sirena.org.uk>
References: <20240206-arm64-sve-vl-max-comment-v1-1-dddf16414412@kernel.org>
 <ZcNxJ56+bvcUTGlT@e133380.arm.com>
 <ZcN8OltRDUlDlTHQ@finisterre.sirena.org.uk>
Message-ID: <ZcOIAck16ZyUi/yj@e133380.arm.com>

On Wed, Feb 07, 2024 at 12:48:58PM +0000, Mark Brown wrote:
> On Wed, Feb 07, 2024 at 12:01:43PM +0000, Dave Martin wrote:
> > On Tue, Feb 06, 2024 at 04:27:01PM +0000, Mark Brown wrote:
> 
> > > +/*
> > > + * Note that for future proofing __SVE_VQ_MAX is defined much larger
> > > + * than the actual architecture maximum of 16.
> > > + */
> 
> > I think that putting shadow #defines in comments in UAPI headers is a
> > really bad idea...  is this a normative statement about the user API,
> > or what?
> 
> Well, the only reason I'm mentioning the constant here is that
> __SVE_VQ_MIN is defined too and has a perfectly good value, things look
> a bit neater with a shared comment block.  I'm not sure there's a hugely
> meaingful difference between having a comment adjacent to a named
> constant in a header and one a couple of lines away that mentions the
> constant by name.

It wasn't so much the exact location that concerned me, rather putting
it in a UAPI header at all.

Maybe so long as the comment doesn't quote a literal value for the arch
max VQ that would be better.  If there is a value there, we may be kind
of legitimising its use even if it's in a comment...

> 
> > My concern is that if we muddy the waters here different bits of
> > software will do different things and we will get a mess with no
> > advantages.
> 
> > Portability issues may ensue if userspace software feels it can
> > substitute some other value for this constant, since we can't control
> > what userspace uses it for.
> 
> I don't think we want people using this at all, ideally we'd remove it
> but it's in the uapi.

I think the main legitimate uses are for implementing sve_vl_valid() and
for type selection purposes (analogous to the C <limits.h> constants --
though all the "obvious" types are fine so this is a but redundant).
But yeah, it's there now.

> > Would it be sufficient to say something like:
> 
> > /*
> >  * Yes, this is 512 QUADWORDS.
> >  * Never allocate memory or size structures based on the value of this
> >  * constant.
> >  */
> > >  #define __SVE_VQ_MAX		512
> 
> I think the fact that this vector length is more than an order of
> magnitude more than is architecturally supported at present needs to be
> conveyed, it's perfectly reasonable for people to not want to do dynamic
> allocation/sizing of buffers in some applications and the above sounds
> more like stylistic guidance about using dynamic sizing to improve
> memory usage.

I guess that's true; people need to know that they'll be allocating a
silly amount of memory if they use the existing _MAX constants directly.
Laziness is a perfectly good reason for doing this for development hacks
that aren't going to be published, less so for code that ends up in
libraries or otherwise gets into the wild...

I preferred to encourage people to size dynamically, but we don't have
a way to enforce it.

Ideally there would be a direct way to read out the system-wide max VL
to provide userspace with a sensible default allocation size, but that
doesn't really exist today (though ptrace and PR_SVE_{SET,GEL}_VL
provide ways to find out, but it's a bit grungy).

How about something along the lines of:

/*
 * Yes, this is 512 QUADWORDS.
 * To help ensure forward portability, this is much larger than the
 * current maximum value defined by the SVE architecture.
 * While arrays or static allocations can be sized based on this value,
 * watch out!  It will waste a surprisingly large amount of memory.
 * Dynamic sizing based on the actual runtime vector length is likely to
 * be preferable for most purposes.
 */

> 
> > Though comments might be better placed alongsize SVE_VQ_MAX at al., in
> > ptrace.h and sigcontext.h rather than here.  The leading __ should at
> > least be a hint that __SVE_VQ_MAX shouldn't be used directly by
> > anyone...
> 
> Yeah, the multiple layers of indirection aren't helpful here.  We
> probably need to comment it in both places TBH.

Agreed, part of that came from a desire to avoid duplicating
information.  I think the indirection via sve_context.h was introduced
to work around a bad interaction with user C library headers, but I'm a
bit hazy on that now without digging through the history.

Cheers
---Dave


From kamlesh at ti.com  Wed Feb  7 05:45:38 2024
From: kamlesh at ti.com (Kamlesh Gurudasani)
Date: Wed, 7 Feb 2024 19:15:38 +0530
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240207125410.r2q3jcplvif7dvt2@tumbling>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
 <20240207125410.r2q3jcplvif7dvt2@tumbling>
Message-ID: <87il30xu9p.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>

Nishanth Menon <nm at ti.com> writes:

>
> A bit too nice coding ;) => I had been confused momentarily by clk_id = args.args[1]
> change just above till I saw that you are pre-incrementing
> clk_id - Is there a harm in leaving the original clk_id increment logic
> alone (it was much simpler to read up)?
>
Personlly, I think this is simpler as this keeps everything related to
parents inside while loop and increment only at one place.

The other logic will have increment inside condition and also at 2 other
places.

Let's Udit take a call.

Kamlesh


From Dave.Martin at arm.com  Wed Feb  7 05:51:42 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 7 Feb 2024 13:51:42 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <ZcOBH7ip/KMhLYGO@finisterre.sirena.org.uk>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
 <ZcEW3y0IlEctOYBA@e133380.arm.com>
 <ZcEd2zU/JpeIwn5f@finisterre.sirena.org.uk>
 <ZcN2XMkvqxNnsz5K@e133380.arm.com>
 <ZcOBH7ip/KMhLYGO@finisterre.sirena.org.uk>
Message-ID: <ZcOK7oIe2f/BFlDj@e133380.arm.com>

On Wed, Feb 07, 2024 at 01:09:51PM +0000, Mark Brown wrote:
> On Wed, Feb 07, 2024 at 12:23:56PM +0000, Dave Martin wrote:
> > On Mon, Feb 05, 2024 at 05:41:47PM +0000, Mark Brown wrote:
> > > On Mon, Feb 05, 2024 at 05:11:59PM +0000, Dave Martin wrote:
> 
> > > > If the kernel is now juggling two #defines for the maximum vector size,
> > > > this feels like it may seed bitrot...
> 
> > > Ideally we'd just not have the existing define externally but it's there
> > > and it's been used.
> 
> > To clarify, is this intended as a temporary band-aid against silly
> > behaviour while a cleaner solution is found, or a permanent limitation?
> 
> Ideally we'd just make everything dynamic, other than the regset issue
> and the bitmasks used for VL enumeration we're there already.  Making
> the bitmasks dynamically sized is more painful but are also doing
> enumeration that userspace doesn't need to do.

For the bitmasks, we'd be saving (512 - 16) / 8 = 62 bytes for each of
SVE and SME (I think).

The tradeoff really didn't seem worth it...

> 
> > We'd need to change various things if the architectural max VL actually
> > grew, so no forward-portability is lost immediately if the kernel
> > adopts 16 internally, but I'm still a little concerned that people may
> > poke about in the kernel code as a reference and this will muddy the
> > waters regarding how to do the right thing in userspace (I know people
> > shouldn't, but...)
> 
> I think if we fix the ptrace regset issue we're doing a good enough job
> of just using fully dynamic sizing with no limits other than what's been
> enumerated there.  We could possibly deal with the enumberation code by
> changing it to use ZCR/SMCR_ELx_LEN_ based defines so that it's
> obviously coming from what we can possibly write to the register but
> it's a bit less clear how to do that neatly.

OK, but we still seem to have two competing approaches: clamp SVE_VQ_MAX
for kernel internal purposes, or restore the dynamic sizing of
NT_ARM_SVE based on the new regset core behaviour.

Are you saying we should or both, or otherwise which one?

Cheers
---Dave


From laurent.pinchart at ideasonboard.com  Wed Feb  7 05:51:52 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 7 Feb 2024 15:51:52 +0200
Subject: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <m3eddoza9y.fsf@t19.piap.pl>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
 <87r0hqnvxc.wl-kuninori.morimoto.gx@renesas.com>
 <20240206134155.GB2827@pendragon.ideasonboard.com>
 <9d1e99b0-892d-4a72-a9b3-886b8ed094b0@xs4all.nl>
 <m3eddoza9y.fsf@t19.piap.pl>
Message-ID: <20240207135152.GG2827@pendragon.ideasonboard.com>

On Wed, Feb 07, 2024 at 02:14:33PM +0100, Krzysztof Ha?asa wrote:
> Hans,
> 
> Hans Verkuil <hverkuil-cisco at xs4all.nl> writes:
> 
> > Ideally someone would have to actually test this, perhaps with one of those
> > Renesas boards. While I do have one, it got bricked after I attempted a
> > u-boot update :-(
> 
> May be reversible, though.

Maybe Morimoto-san could help ? :-) What board did you use Hans ?

-- 
Regards,

Laurent Pinchart


From olteanv at gmail.com  Wed Feb  7 05:52:19 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Wed, 7 Feb 2024 15:52:19 +0200
Subject: [PATCH net-next v2 6/6] net: dsa: b53: remove
 eee_enabled/eee_active in b53_get_mac_eee()
In-Reply-To: <57406055-ff3c-4788-bbf7-8476f63f90db@gmail.com>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
 <E1rWbNI-002cCz-4x@rmk-PC.armlinux.org.uk>
 <20240206112024.3jxtcru3dupeirnj@skbuf>
 <ZcIwQcn3qlk0UjS4@shell.armlinux.org.uk>
 <20240206132923.eypnqvqwe3cga5tp@skbuf>
 <57406055-ff3c-4788-bbf7-8476f63f90db@gmail.com>
Message-ID: <20240207135219.7wr4hctzjuanotxv@skbuf>

On Tue, Feb 06, 2024 at 08:25:17PM -0800, Florian Fainelli wrote:
> 
> 
> On 2/6/2024 5:29 AM, Vladimir Oltean wrote:
> > On Tue, Feb 06, 2024 at 01:12:33PM +0000, Russell King (Oracle) wrote:
> > > > I know next to nothing about EEE and especially the implementation on
> > > > Broadcom switches. But is the information brought by B53_EEE_LPI_INDICATE
> > > > completely redundant? Is it actually in the system's best interest to
> > > > ignore it?
> > > 
> > > That's a review comment that should have been made when the original
> > > change to phylib was done, because it's already ignored in kernels
> > > today since the commit changing phylib that I've referenced in this
> > > series - since e->eee_enabled and e->eee_active will be overwritten by
> > > phylib.
> > 
> > That's fair, but commit d1420bb99515 ("net: phy: improve generic EEE
> > ethtool functions") is dated November 2018, and my involvement with the
> > kernel started in March 2019. So it would have been a bit difficult for
> > me to make this observation back then.
> > 
> > > If we need B53_EEE_LPI_INDICATE to do something, then we need to have
> > > a discussion about it, and decide how that fits in with the EEE
> > > interface, and how to work around phylib's implementation.
> > 
> > Hopefully Florian or Doug can quickly clarify whether this is the case
> > or not.
> 
> Russell's replacement is actually a better one because it will return a
> stable state. B53_EEE_LPI_INDICATE would indicate when the switch port's
> built-in PHY asserts the LPI signal to its MAC, which could be transient
> AFAICT.
> -- 
> Florian

Thanks, Florian.


From hverkuil-cisco at xs4all.nl  Wed Feb  7 05:54:56 2024
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Wed, 7 Feb 2024 14:54:56 +0100
Subject: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <20240207135152.GG2827@pendragon.ideasonboard.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
 <87r0hqnvxc.wl-kuninori.morimoto.gx@renesas.com>
 <20240206134155.GB2827@pendragon.ideasonboard.com>
 <9d1e99b0-892d-4a72-a9b3-886b8ed094b0@xs4all.nl> <m3eddoza9y.fsf@t19.piap.pl>
 <20240207135152.GG2827@pendragon.ideasonboard.com>
Message-ID: <9bc65445-8f50-4227-ad3c-04dd32832419@xs4all.nl>

On 07/02/2024 14:51, Laurent Pinchart wrote:
> On Wed, Feb 07, 2024 at 02:14:33PM +0100, Krzysztof Ha?asa wrote:
>> Hans,
>>
>> Hans Verkuil <hverkuil-cisco at xs4all.nl> writes:
>>
>>> Ideally someone would have to actually test this, perhaps with one of those
>>> Renesas boards. While I do have one, it got bricked after I attempted a
>>> u-boot update :-(
>>
>> May be reversible, though.
> 
> Maybe Morimoto-san could help ? :-) What board did you use Hans ?
> 

I have a Koelsch. I tried to update uboot at one time, but bricked it and was
unable to get a different uboot installed.

It would be nice if it can be revived.

Regards,

	Hans


From olteanv at gmail.com  Wed Feb  7 05:55:20 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Wed, 7 Feb 2024 15:55:20 +0200
Subject: [PATCH net-next v2 6/6] net: dsa: b53: remove
 eee_enabled/eee_active in b53_get_mac_eee()
In-Reply-To: <E1rWbNI-002cCz-4x@rmk-PC.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
 <E1rWbNI-002cCz-4x@rmk-PC.armlinux.org.uk>
Message-ID: <20240207135520.2zvinnv5w3v7kruk@skbuf>

On Sun, Feb 04, 2024 at 12:13:28PM +0000, Russell King (Oracle) wrote:
> b53_get_mac_eee() sets both eee_enabled and eee_active, and then
> returns zero.
> 
> dsa_slave_get_eee(), which calls this function, will then continue to
> call phylink_ethtool_get_eee(), which will return -EOPNOTSUPP if there
> is no PHY present, otherwise calling phy_ethtool_get_eee() which in
> turn will call genphy_c45_ethtool_get_eee().
> 
> genphy_c45_ethtool_get_eee() will overwrite eee_enabled and eee_active
> with its own interpretation from the PHYs settings and negotiation
> result.
> 
> Thus, when there is no PHY, dsa_slave_get_eee() will fail with
> -EOPNOTSUPP, meaning eee_enabled and eee_active will not be returned to
> userspace. When there is a PHY, eee_enabled and eee_active will be
> overwritten by phylib, making the setting of these members in
> b53_get_mac_eee() entirely unnecessary.
> 
> Remove this code, thus simplifying b53_get_mac_eee().
> 
> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>

I see the series was put in "Changes Requested", possibly due to my
clarification question. Let's see if I can change that.

---
pw-bot: under-review


From laurent.pinchart at ideasonboard.com  Wed Feb  7 05:55:51 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 7 Feb 2024 15:55:51 +0200
Subject: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <m3il30zace.fsf@t19.piap.pl>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
 <87r0hqnvxc.wl-kuninori.morimoto.gx@renesas.com>
 <20240206134155.GB2827@pendragon.ideasonboard.com>
 <m3il30zace.fsf@t19.piap.pl>
Message-ID: <20240207135551.GH2827@pendragon.ideasonboard.com>

On Wed, Feb 07, 2024 at 02:13:05PM +0100, Krzysztof Ha?asa wrote:
> Laurent,
> 
> Laurent Pinchart <laurent.pinchart at ideasonboard.com> writes:
> 
> >> +++ b/drivers/media/i2c/adv7604.c
> >> @@ -3205,7 +3205,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
> >>       np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
> >>
> >>       /* Parse the endpoint. */
> >> -     endpoint = of_graph_get_next_endpoint(np, NULL);
> >> +     endpoint = of_graph_get_endpoint_by_regs(np, 0, -1);
> >
> > I think this should be port 1 for the adv7611 and port2 for the adv7612.
> > The adv7610 may need to use port 1 too, but the bindings likely need to
> > be updated.
> 
> To be honest I have no idea about ADV7611 and 7612.
> The 7610 I have on Tinyrex "mobo" seems to be single port.

One issue is that the commit that added the adv7610 compatible string to
the DT bindings (commit 901a52c43359, "media: Add ADV7610 support for
adv7604 driver - DT docs.") didn't extend the conditional rules further
down in the file that defines what ports are needed. That's why I don't
know what was intended. I believe the adv7610 should be treated like the
adv7611, given that the driver has

        { .compatible = "adi,adv7610", .data = &adv76xx_chip_info[ADV7611] },
        { .compatible = "adi,adv7611", .data = &adv76xx_chip_info[ADV7611] },

Could you send a patch to address that in the DT bindings ?

> ADV7611 seems to be mostly a 7610 in a different package (LQFP 64
> instead of some BGA 76). The driver simply treats ADV7610 as a 7611.
> 
> ADV7612 is apparently dual port (only one port can be used at a time)
> though:
> 
> [ADV7612] = {
>         .type = ADV7612,
>         .has_afe = false,
>         .max_port = ADV76XX_PAD_HDMI_PORT_A,    /* B not supported */
>         .num_dv_ports = 1,                      /* normally 2 */
> 
> 
> All related in-tree DTS entries (as of v6.8.0-rc1) seem to be ADV7612.
> 
> To me it seems all known devices use the first port only.

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Wed Feb  7 05:57:37 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 7 Feb 2024 15:57:37 +0200
Subject: [PATCH 3/4] media: platform: replace of_graph_get_next_endpoint()
In-Reply-To: <875xz1tave.wl-kuninori.morimoto.gx@renesas.com>
References: <87ttmmnvzh.wl-kuninori.morimoto.gx@renesas.com>
 <87plxanvx1.wl-kuninori.morimoto.gx@renesas.com>
 <20240206162506.GC2827@pendragon.ideasonboard.com>
 <875xz1tave.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <20240207135737.GI2827@pendragon.ideasonboard.com>

On Tue, Feb 06, 2024 at 11:45:58PM +0000, Kuninori Morimoto wrote:
> 
> Hi Laurent
> 
> Thank you for your review
> 
> > > diff --git a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> > > index 686ca8753ba2..3f8bea2e3934 100644
> > > --- a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> > > +++ b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> > > @@ -728,7 +728,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
> > >  				 &state->max_num_lanes))
> > >  		return -EINVAL;
> > >  
> > > -	node = of_graph_get_next_endpoint(node, NULL);
> > > +	node = of_graph_get_endpoint_by_regs(node, 0, -1);
> > 
> > This is not correct, see
> > Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml.
> 
> Hmm... Then, It can be like this ?
> 
> 	+ node = of_graph_get_endpoint_by_regs(node, -1, -1);

I suppose that would work, even if we should really try not to pass -1
for the port. Rob, any opinion ?

-- 
Regards,

Laurent Pinchart


From vkoul at kernel.org  Wed Feb  7 06:01:06 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 07 Feb 2024 15:01:06 +0100
Subject: [PATCH v2 1/1] phy: freescale: phy-fsl-imx8-mipi-dphy: Fix
 alias name to use dashes
In-Reply-To: <20240110093343.468810-1-alexander.stein@ew.tq-group.com>
References: <20240110093343.468810-1-alexander.stein@ew.tq-group.com>
Message-ID: <170731446669.147017.11490277771179269015.b4-ty@kernel.org>


On Wed, 10 Jan 2024 10:33:43 +0100, Alexander Stein wrote:
> Devicetree spec lists only dashes as valid characters for alias names.
> Table 3.2: Valid characters for alias names, Devicee Specification,
> Release v0.4
> 
> 

Applied, thanks!

[1/1] phy: freescale: phy-fsl-imx8-mipi-dphy: Fix alias name to use dashes
      commit: 7936378cb6d87073163130e1e1fc1e5f76a597cf

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Wed Feb  7 06:01:28 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 07 Feb 2024 15:01:28 +0100
Subject: [PATCH v5 2/2] phy: mtk-mipi-csi: add driver for CSI phy
In-Reply-To: <20240111101738.468916-1-jstephan@baylibre.com>
References: <20240111101738.468916-1-jstephan@baylibre.com>
Message-ID: <170731448892.147119.12389092200889790020.b4-ty@kernel.org>


On Thu, 11 Jan 2024 11:17:30 +0100, Julien Stephan wrote:
> This is a new driver that supports the MIPI CSI CD-PHY version 0.5
> 
> The number of PHYs depend on the SoC.
> Each PHY can support D-PHY only or CD-PHY configuration.
> The driver supports only D-PHY mode, so CD-PHY
> compatible PHY are configured in D-PHY mode.
> 
> [...]

Applied, thanks!

[2/2] phy: mtk-mipi-csi: add driver for CSI phy
      commit: 673d70cb3c652ad6d97594e03225bbdf20226216

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Wed Feb  7 06:06:37 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 7 Feb 2024 15:06:37 +0100
Subject: [PATCH v2 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <374f5069-9f3d-4ad2-a6da-b38a143a0c99@collabora.com>
References: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
 <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>
 <ZcNYlFgT0rXiCGbo@matsya>
 <374f5069-9f3d-4ad2-a6da-b38a143a0c99@collabora.com>
Message-ID: <ZcOObdUvxmRzdHnE@matsya>

On 07-02-24, 14:39, Cristian Ciocaltea wrote:
> On 2/7/24 12:16, Vinod Koul wrote:
> > On 05-02-24, 13:24, Cristian Ciocaltea wrote:

> >> +static u8 hdptx_grf_read(struct rockchip_hdptx_phy *hdptx, u32 reg)
> >> +{
> >> +	u32 val;
> >> +
> >> +	regmap_read(hdptx->grf, reg, &val);
> >> +
> >> +	return val;
> >> +}
> > 
> > why use wrappers, why not call regmap_ apis directly
> 
> Agree, no real benefit, will drop them, except probably
> hdptx_multi_reg_write() for the extra savings.

That one is fine as there is good logic on the helper
 
> So I'd keep using that one if there's no strong reason against.

ok

-- 
~Vinod


From peter.griffin at linaro.org  Wed Feb  7 06:11:45 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 7 Feb 2024 14:11:45 +0000
Subject: [PATCH 2/4] arm64: dts: exynos: gs101: add chipid node
In-Reply-To: <b199ba24-403b-44fa-b807-9b98f9e98913@linaro.org>
References: <20240201172224.574238-1-alexey.klimov@linaro.org>
 <20240201172224.574238-2-alexey.klimov@linaro.org> <CADrjBPpqHx1uoVZCYDX51kW+JdOr_-+4oryOjXcUMFkmLGTBLw@mail.gmail.com>
 <b199ba24-403b-44fa-b807-9b98f9e98913@linaro.org>
Message-ID: <CADrjBPpNukp+YQ0AmsZAE1f=MEk_auPPZit=tV8gk4szQ8MqRg@mail.gmail.com>

Hi Krzysztof,

Thanks for your feedback.

On Tue, 6 Feb 2024 at 10:10, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 05/02/2024 15:36, Peter Griffin wrote:
> > Hi Alexey & Krysztof,
> >
> > On Thu, 1 Feb 2024 at 17:22, Alexey Klimov <alexey.klimov at linaro.org> wrote:
> >>
> >> Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
> >> ---
> >>  arch/arm64/boot/dts/exynos/google/gs101.dtsi | 5 +++++
> >>  1 file changed, 5 insertions(+)
> >>
> >> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> >> index d838e3a7af6e..156fec2575bc 100644
> >> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> >> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> >> @@ -283,6 +283,11 @@ soc: soc at 0 {
> >>                 #size-cells = <1>;
> >>                 ranges = <0x0 0x0 0x0 0x40000000>;
> >>
> >> +               chipid at 10000000 {
> >> +                       compatible = "google,gs101-chipid";
> >> +                       reg = <0x10000000 0xd000>;
> >> +               };
> >> +
> >
> > I was wondering about the 0xd000 size here, as most upstream platforms
> > use a chipid size of 0x100 or 0x24. I see the downstream gs101 kernel
> > also uses 0xd000. Looking a bit more, that is because gs-chipid.c also
> > has support for dumping other areas of the OTP SFR bank like asv table
> > (offset 0x9000) hpm_asv (offset 0xa000) and hw_tune (0xc000).
> >
> > I checked Exynos850 and that also has ASV tables at those same offsets
> > above, but it currently uses a chipid size of 0x100 upstream.
> > Exynos-asv.c driver is part of exynos-chipid.c upstream so it seems
> > reasonable to have the increased size including those SFR registers.
> > Currently exynos-asv.c driver only supports Exynos5422 upstream.
> >
> > @Krzysztof - From a process PoV what is the best/correct thing to do
> > here? Have the increased size in DT that includes ASV parts of the OTP
> > bank from the get-go?
>
> ChipID so far had only size of 0x30 or something like that. What you
> refer to does not look like old ChipID but full blown OTP, which also
> includes ChipID.

OK so in some previous Exynos SoCs chipid had its own separate memory
mapped SFRs as well as being present in the OTP area?

>  Although I am not entirely sure about that, either.
> Depends whether they share clocks, for example.

This address is the OTP area, and I can't see chipid regs mentioned
anywhere else in the memory map other than OTP. Unfortunately there
are lots of separate docs for different IP blocks, so it isn't just a
case of searching a giant SoC TRM pdf.

e850 though looks to be the same (the address defined in DT is the otp
area), that is one large PDF and the chipid regs aren't mentioned
anywhere else, Given the chipid reg offset is the same (0x10000000)
for exynosautov9.dtsi, exynosautov920.dtsi, exynos850.dtsi, exynos7885
and exynos5433 I suspect this could be the same for all those SoCs as
well.

>
> I don't have any GS101 information so I don't know what's there. It
> seems you ask me to give you decision based on guessing... If you have
> one block, so if there is OTP, which contains ChipID, then define OTP.

I believe there is one block that contains ChipID, therefore based on
the above info we should define full OTP size?

> Not ChipID+OTP.
>
> I think Exynos850 DTSI is wrong here. That's OTP block, not ChipID.

Yes agreed, and quite possibly the other Exynos SoCs as well.

Thanks,

Peter.


From willy at infradead.org  Wed Feb  7 06:17:31 2024
From: willy at infradead.org (Matthew Wilcox)
Date: Wed, 7 Feb 2024 14:17:31 +0000
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <20240207121125.GA22234@willie-the-truck>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com>
 <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
 <ZcNnrdlb3fe0kGHK@casper.infradead.org>
 <20240207121125.GA22234@willie-the-truck>
Message-ID: <ZcOQ-0pzA16AEbct@casper.infradead.org>

On Wed, Feb 07, 2024 at 12:11:25PM +0000, Will Deacon wrote:
> On Wed, Feb 07, 2024 at 11:21:17AM +0000, Matthew Wilcox wrote:
> > The pte lock cannot be taken in irq context (which I think is what
> > you're asking?)  While it is not possible to reason about all users of
> > struct page, we are somewhat relieved of that work by noting that this is
> > only for hugetlbfs, so we don't need to reason about slab, page tables,
> > netmem or zsmalloc.
> 
> My concern is that an interrupt handler tries to access a 'struct page'
> which faults due to another core splitting a pmd mapping for the vmemmap.
> In this case, I think we'll end up trying to resolve the fault from irq
> context, which will try to take the spinlock.

Yes, this absolutely can happen (with this patch), and this patch should
be dropped for now.

While this array of ~512 pages have been allocated to hugetlbfs, and one
would think that there would be no way that there could still be
references to them, another CPU can have a pointer to this struct page
(eg attempting a speculative page cache reference or
get_user_pages_fast()).  That means it will try to call
atomic_add_unless(&page->_refcount, 1, 0);

Actually, I wonder if this isn't a problem on x86 too?  Do we need to
explicitly go through an RCU grace period before freeing the pages
for use by somebody else?



From dmitry.baryshkov at linaro.org  Wed Feb  7 06:22:59 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 7 Feb 2024 16:22:59 +0200
Subject: [PATCH RFC 1/2] spmi: Add support for multi-master
In-Reply-To: <b4018932-2fcb-4a15-9ec4-e29e5761d3e0@collabora.com>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
 <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>
 <CAA8EJpqsJmv36=o1aTjVH6eMHXMg8BHNpiDvs+Q8YB23ezVGtQ@mail.gmail.com>
 <ZcMvFtAwQQjAZhk6@linaro.org> <CAA8EJprqWLX7_yWZzKp3FAKFGkSkk041f9hj1uXuRBrbH5APyQ@mail.gmail.com>
 <ZcNIddeG6VHxBEOQ@linaro.org> <CAA8EJpo-16u34Yc6MLmHSqFrQ0VrZAq6TwGeVc5WFwMmhruqoA@mail.gmail.com>
 <b4018932-2fcb-4a15-9ec4-e29e5761d3e0@collabora.com>
Message-ID: <CAA8EJpo5bb+AWJra26MoDPKE_vF+eBAJAGoxenkMtGWz2N5Tuw@mail.gmail.com>

On Wed, 7 Feb 2024 at 14:46, AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Il 07/02/24 12:45, Dmitry Baryshkov ha scritto:
> > On Wed, 7 Feb 2024 at 11:08, Abel Vesa <abel.vesa at linaro.org> wrote:
> >>
> >> On 24-02-07 09:23:09, Dmitry Baryshkov wrote:
> >>> On Wed, 7 Feb 2024 at 09:19, Abel Vesa <abel.vesa at linaro.org> wrote:
> >>>>
> >>>> On 24-02-07 01:55:39, Dmitry Baryshkov wrote:
> >>>>> On Wed, 7 Feb 2024 at 01:34, Abel Vesa <abel.vesa at linaro.org> wrote:
> >>>>>>
> >>>>>> Some newer SPMI controllers support multiple bus masters.
> >>>>>> Such a master can control multiple slave devices. The generic
> >>>>>> framework needs to be able to pass on the master id to the
> >>>>>> controller-specific driver. So do that. The framework will
> >>>>>> check if the devicetree child nodes are actually bus masters
> >>>>>> and will register the devices for each master. The legacy
> >>>>>> approach will still be supported for backwards compatibility.
> >>>>>
> >>>>> Please remind me, are those two actual bus musters driving a single
> >>>>> bus in parallel or two SPMI buses being handled by a single device? In
> >>>>> the latter case this implementation is incorrect. There should be
> >>>>> multiple spmi_controller instances, one for each bus. Allocate them in
> >>>>> a loop and set ctrl->dev.of_node after allocating.
> >>>>
> >>>> It's two SPMI buses (two sets of wires) handled by the same controller,
> >>>> HW-wise.
> >>>>
> >>>> If we register two spmi controllers with the kernel framework, it will
> >>>> be HW inaccurate, because there is just one controller which has
> >>>> multiple masters.
> >>>
> >>> struct spmi_controller is a controller for a single bus. Inside your
> >>> device you have two SPMI buses, each can be controlled by its own
> >>> struct spmi_controller. Just like devices that control multiple I2C,
> >>> SPI or USB busses register a separate instance of the bus controller.
> >>
> >> Well, this is what this patchset is trying to do in the generic part.
> >> The SPMI controller supports multiple buses (HW-wise) and therefore SW
> >> implementation shouldn't be tied to single bus requirement.
> >
> > So, after the off-line discussion:
> > - add new compatible string for sm8450+
> > - register two spmi controller instances
>
> Well, I don't know about the actual hardware that you're trying to implement
> but, in my opinion, the "idea" of this series does actually make sense.
>
> The SPMI specification says that SPMI supports up to 4 masters, and up to
> 16 slaves.

So, that is my main question: whether this supports multiple masters
on a same bus or multiple buses. From the SoC pins description I
assume the latter is the case.

>
> Just my two cents.
>
> Cheers,
> Angelo
>
> > - drop the master-id from the SPMI interface
> > - optionally: think about having a new separate driver for v7 SPMI.
> >
> >>
> >>>
> >>>>
> >>>> I'm not saying it might not work. But, to me, it looks more like a hack.
> >>>>
> >>>> Basically, we would be mapping HW bus masters to kernel controllers.
> >>>
> >>> Buses, not just masters.
> >>>
> >>>>
> >>>>>
> >>>>>>
> >>>>>> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> >>>>>> ---
> >>>>>>   drivers/spmi/spmi-mtk-pmif.c |  6 ++--
> >>>>>>   drivers/spmi/spmi-pmic-arb.c | 10 +++---
> >>>>>>   drivers/spmi/spmi.c          | 76 ++++++++++++++++++++++++++++++--------------
> >>>>>>   include/linux/spmi.h         | 10 +++---
> >>>>>>   4 files changed, 67 insertions(+), 35 deletions(-)
> >>>>>
> >>>>> --
> >>>>> With best wishes
> >>>>> Dmitry
> >>>
> >>>
> >>>
> >>> --
> >>> With best wishes
> >>> Dmitry
> >
> >
> >
>
>


-- 
With best wishes
Dmitry


From u-kumar1 at ti.com  Wed Feb  7 06:23:55 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Wed, 7 Feb 2024 19:53:55 +0530
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240207125410.r2q3jcplvif7dvt2@tumbling>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
 <20240207125410.r2q3jcplvif7dvt2@tumbling>
Message-ID: <3a7c4a18-5463-414f-82df-39aaed861148@ti.com>

Hi?Nishanth,

On 2/7/2024 6:24 PM, Nishanth Menon wrote:
> On 14:41-20240207, Udit Kumar wrote:
>> Most of clocks and their parents are defined in contiguous range,
>> But in few cases, there is gap in clock numbers[0].
>> Driver assumes clocks to be in contiguous range, and add their clock
>> ids incrementally.
>>
>> New firmware started returning error while calling get_freq and is_on
>> API for non-available clock ids.
>>
>> In this fix, driver checks and adds only valid clock ids.
>>
>> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
>>
>> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
>> Section Clocks for NAVSS0_CPTS_0 Device,
>> clock id 12-15 not present.
>>
>> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
>> ---
>> Changelog
>> Changes in v3
>> - instead of get_freq, is_auto API is used to check validilty of clock
>> - Address comments of v2, to have preindex increment
>> Link to v2 https://lore.kernel.org/all/20240206104357.3803517-1-u-kumar1 at ti.com/
>>
>> Changes in v2
>> - Updated commit message
>> - Simplified logic for valid clock id
>> link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/
>>
>>
>> P.S
>> Firmawre returns total num_parents count including non available ids.
>> For above device id NAVSS0_CPTS_0, number of parents clocks are 16
>> i.e from id 2 to 17. But out of these ids few are not valid.
>> So driver adds only valid clock ids out ot total.
>>
>> Original logs
>> https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
>> Line 2630 for error
>>
>> Logs with fix v3
>> https://gist.github.com/uditkumarti/94e3e28d62282fd708dbfe37435ce1d9#file-v3
>> Line 2586
>>
>>
>>   drivers/clk/keystone/sci-clk.c | 12 ++++++++++--
>>   1 file changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
>> index 35fe197dd303..31b7df05d7bb 100644
>> --- a/drivers/clk/keystone/sci-clk.c
>> +++ b/drivers/clk/keystone/sci-clk.c
>> @@ -516,6 +516,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>>   	struct sci_clk *sci_clk, *prev;
>>   	int num_clks = 0;
>>   	int num_parents;
>> [..]					/* Check if this clock id is valid */
>> +					ret = provider->ops->is_auto(provider->sci,
>> +						sci_clk->dev_id, ++clk_id, &state);
> A bit too nice coding ;) => I had been confused momentarily by clk_id = args.args[1]
> change just above till I saw that you are pre-incrementing
> clk_id - Is there a harm in leaving the original clk_id increment logic
> alone (it was much simpler to read up)?

No warm in using original code but want to avoid, two statement for 
increment in case of failure and success.

Let me know, if i need to add few comments around this

or if you think, code is confusing I can move to original one



>> +
>> +					if (ret)
>> +						continue;
>> +
>>   					sci_clk = devm_kzalloc(dev,
>>   							       sizeof(*sci_clk),
>>   							       GFP_KERNEL);
>>   					if (!sci_clk)
>>   						return -ENOMEM;
>>   					sci_clk->dev_id = args.args[0];
>> -					sci_clk->clk_id = clk_id++;
>> +					sci_clk->clk_id = clk_id;
>>   					sci_clk->provider = provider;
>>   					list_add_tail(&sci_clk->node, &clks);
>>   
>> -- 
>> 2.34.1
>>


From u-kumar1 at ti.com  Wed Feb  7 06:25:04 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Wed, 7 Feb 2024 19:55:04 +0530
Subject: [PATCH V2 0/2] Add CAN and OSPI support for AM69-SK platform
In-Reply-To: <20240205200744.216572-1-sabiya.d@ti.com>
References: <20240205200744.216572-1-sabiya.d@ti.com>
Message-ID: <1d5c0570-fa10-4b87-9833-1710f33db01f@ti.com>


On 2/6/2024 1:37 AM, sabiya.d at mistralsolutions.com wrote:
> From: Dasnavis Sabiya <sabiya.d at ti.com>
>
> Hi All,
>
> This series adds support for the below interfaces on AM69-SK platform:
> -  CAN support on both MCU and MAIN domains
> -  OSPI NOR flash support
>
> v2: Changelog:
> 1) Removed CAN interface aliasing.
> 2) Updated bootph property on the leaf nodes.
>
> Link to v1: https://lore.kernel.org/lkml/20240118153524.4135901-1-sabiya.d at ti.com/
>
> Dasnavis Sabiya (2):
>    arm64: dts: ti: k3-am69-sk: Enable CAN interfaces for AM69 SK board
>    arm64: dts: ti: k3-am69-sk: Add support for OSPI flash


For Series

Reviewed-by: Udit Kumar <u-kumar1 at ti.com>


>   arch/arm64/boot/dts/ti/k3-am69-sk.dts | 162 ++++++++++++++++++++++++++
>   1 file changed, 162 insertions(+)
>


From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:42:36 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 7 Feb 2024 15:42:36 +0100
Subject: [PATCH v4 1/2] media: dt-bindings: i2c: add GalaxyCore GC08A3
 image sensor
In-Reply-To: <20240204061538.2105-2-zhi.mao@mediatek.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
 <20240204061538.2105-2-zhi.mao@mediatek.com>
Message-ID: <420ee120-2962-4848-b76f-b32ed70e70b0@collabora.com>

Il 04/02/24 07:15, Zhi Mao ha scritto:
> Add YAML device tree binding for GC08A3 CMOS image sensor,
> and the relevant MAINTAINERS entries.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:42:31 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 7 Feb 2024 15:42:31 +0100
Subject: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <20240204061538.2105-3-zhi.mao@mediatek.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
 <20240204061538.2105-3-zhi.mao@mediatek.com>
Message-ID: <21370bd8-502b-4b4e-8c9b-6d13c60685d5@collabora.com>

Il 04/02/24 07:15, Zhi Mao ha scritto:
> Add a V4L2 sub-device driver for Galaxycore GC08A3 image sensor.
> 
> Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> ---
>   drivers/media/i2c/Kconfig  |   10 +
>   drivers/media/i2c/Makefile |    1 +
>   drivers/media/i2c/gc08a3.c | 1448 ++++++++++++++++++++++++++++++++++++
>   3 files changed, 1459 insertions(+)
>   create mode 100644 drivers/media/i2c/gc08a3.c
> 
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 56f276b920ab..e4da68835683 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -70,6 +70,16 @@ config VIDEO_GC0308
>   	  To compile this driver as a module, choose M here: the
>   	  module will be called gc0308.
>   
> +config VIDEO_GC08A3
> +	tristate "GalaxyCore gc08a3 sensor support"
> +	select V4L2_CCI_I2C
> +	help
> +	  This is a Video4Linux2 sensor driver for the GalaxyCore gc08a3
> +	  camera.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called gc08a3.
> +
>   config VIDEO_GC2145
>   	select V4L2_CCI_I2C
>   	tristate "GalaxyCore GC2145 sensor support"
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index dfbe6448b549..b82e99ca7578 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
>   obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
>   obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
>   obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
> +obj-$(CONFIG_VIDEO_GC08A3) += gc08a3.o
>   obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
>   obj-$(CONFIG_VIDEO_HI556) += hi556.o
>   obj-$(CONFIG_VIDEO_HI846) += hi846.o
> diff --git a/drivers/media/i2c/gc08a3.c b/drivers/media/i2c/gc08a3.c
> new file mode 100644
> index 000000000000..3fc7fffb815c
> --- /dev/null
> +++ b/drivers/media/i2c/gc08a3.c
> @@ -0,0 +1,1448 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * gc08a3.c - gc08a3 sensor driver
> + *
> + * Copyright 2023 MediaTek
> + *
> + * Zhi Mao <zhi.mao at mediatek.com>
> + */
> +

..snip..

> +
> +static const struct gc08a3_link_freq_config gc08a3_link_freq_336m_configs = {
> +	.reg_list = {
> +		.num_of_regs = ARRAY_SIZE(mode_table_common),
> +		.regs = mode_table_common,
> +	}
> +};
> +
> +static const struct gc08a3_link_freq_config gc08a3_link_freq_207m_configs = {
> +	.reg_list = {
> +		.num_of_regs = ARRAY_SIZE(mode_table_common),
> +		.regs = mode_table_common,
> +	}
> +};
> +

Since you're documenting this structure anyway, why not kerneldoc? :-)

> +struct gc08a3_mode {
> +	u32 width;
> +	u32 height;
> +	const struct gc08a3_reg_list reg_list;
> +
> +	u32 hts; /* Horizontal timining size */
> +	u32 vts_def; /* Default vertical timining size */
> +	u32 vts_min; /* Min vertical timining size */
> +	u32 max_framerate;
> +	const struct gc08a3_link_freq_config *link_freq_configs;
> +};
> +
> +/*
> + * Declare modes in order, from biggest
> + * to smallest height.
> + */

one line is enough for this comment.

> +static const struct gc08a3_mode gc08a3_modes[] = {
> +	{
> +		.width = GC08A3_NATIVE_WIDTH,
> +		.height = GC08A3_NATIVE_HEIGHT,
> +		.reg_list = {
> +			.num_of_regs = ARRAY_SIZE(mode_3264x2448),
> +			.regs = mode_3264x2448,
> +		},
> +		.link_freq_configs = &gc08a3_link_freq_336m_configs,
> +
> +		.hts = GC08A3_HTS_30FPS,
> +		.vts_def = GC08A3_VTS_30FPS,
> +		.vts_min = GC08A3_VTS_30FPS_MIN,
> +		.max_framerate = 300,
> +	},
> +	{
> +		.width = 1920,
> +		.height = 1080,
> +		.reg_list = {
> +			.num_of_regs = ARRAY_SIZE(mode_1920x1080),
> +			.regs = mode_1920x1080,
> +		},
> +		.link_freq_configs = &gc08a3_link_freq_207m_configs,
> +
> +		.hts = GC08A3_HTS_60FPS,
> +		.vts_def = GC08A3_VTS_60FPS,
> +		.vts_min = GC08A3_VTS_60FPS_MIN,
> +		.max_framerate = 600,
> +	},
> +};
> +
> +static u64 to_pixel_rate(u32 f_index)
> +{
> +	u64 pixel_rate = link_freq_menu_items[f_index] * 2 * GC08A3_DATA_LANES;
> +
> +	do_div(pixel_rate, GC08A3_RGB_DEPTH);

The divisor is (less than) 32 bits and the dividend is always 64 bits: that will
break on builds for 32-bits CPUs.

Just do....

	return div_u64(pixel_rate, GB08A3_RGB_DEPTH);

> +
> +	return pixel_rate;
> +}
> +
> +static int gc08a3_identify_module(struct gc08a3 *gc08a3)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
> +	u64 val = 0;

u64 val;

> +	int ret;
> +

Either log here or in the probe function, otherwise it's just redudant.

> +	ret = cci_read(gc08a3->regmap, GC08A3_REG_CHIP_ID, &val, NULL);
> +	if (ret) {
> +		dev_err(&client->dev,
> +			"failed to read chip id: 0x%x", GC08A3_CHIP_ID);
> +		return ret;
> +	}
> +
> +	if (val != GC08A3_CHIP_ID) {
> +		dev_err(&client->dev, "chip id mismatch: 0x%x!=0x%llx",
> +			GC08A3_CHIP_ID, val);
> +		return -ENXIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static inline struct gc08a3 *to_gc08a3(struct v4l2_subdev *sd)
> +{
> +	return container_of(sd, struct gc08a3, sd);
> +}
> +

..snip..

> +
> +static int gc08a3_update_cur_mode_controls(struct gc08a3 *gc08a3,
> +					   const struct gc08a3_mode *mode)
> +{
> +	s64 exposure_max, h_blank;
> +	int ret = 0;
> +
> +	ret = __v4l2_ctrl_modify_range(gc08a3->vblank,
> +				       mode->vts_min - mode->height,
> +				       GC08A3_VTS_MAX - mode->height, 1,
> +				       mode->vts_def - mode->height);
> +	if (ret)
> +		dev_err(gc08a3->dev, "VB ctrl range update failed\n");
> +
> +	h_blank = mode->hts - mode->width;
> +	ret = __v4l2_ctrl_modify_range(gc08a3->hblank, h_blank, h_blank, 1,
> +				       h_blank);
> +	if (ret)
> +		dev_err(gc08a3->dev, "HB ctrl range update failed\n");
> +
> +	exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
> +	ret = __v4l2_ctrl_modify_range(gc08a3->exposure, GC08A3_EXP_MIN,
> +				       exposure_max, GC08A3_EXP_STEP,
> +				       exposure_max);
> +	if (ret)
> +		dev_err(gc08a3->dev, "exposure ctrl range update failed\n");

No. You're not returning anywhere for error. That's not okay.
Besides...

	if (ret) {
		dev_err..
		return ret;
	}

	return 0;

> +
> +	return ret;
> +}
> +
> +static void gc08a3_update_pad_format(struct gc08a3 *gc08a3,
> +				     const struct gc08a3_mode *mode,
> +				     struct v4l2_mbus_framefmt *fmt)
> +{
> +	fmt->width = mode->width;
> +	fmt->height = mode->height;
> +	fmt->code = GC08A3_MBUS_CODE;
> +	fmt->field = V4L2_FIELD_NONE;
> +	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);
> +}
> +
> +static int gc08a3_set_format(struct v4l2_subdev *sd,
> +			     struct v4l2_subdev_state *state,
> +			     struct v4l2_subdev_format *fmt)
> +{
> +	struct gc08a3 *gc08a3 = to_gc08a3(sd);
> +	struct v4l2_mbus_framefmt *mbus_fmt;
> +	struct v4l2_rect *crop;
> +	const struct gc08a3_mode *mode;
> +
> +	mode = v4l2_find_nearest_size(gc08a3_modes, ARRAY_SIZE(gc08a3_modes),
> +				      width, height, fmt->format.width,
> +				      fmt->format.height);
> +
> +	/*update crop info to subdev state*/
> +	crop = v4l2_subdev_state_get_crop(state, 0);
> +	crop->width = mode->width;
> +	crop->height = mode->height;
> +
> +	/*update fmt info to subdev state*/
> +	gc08a3_update_pad_format(gc08a3, mode, &fmt->format);
> +	mbus_fmt = v4l2_subdev_state_get_format(state, 0);
> +	*mbus_fmt = fmt->format;
> +
> +	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
> +		return 0;
> +
> +	gc08a3->cur_mode = mode;
> +	gc08a3_update_cur_mode_controls(gc08a3, mode);
> +
> +	return 0;
> +}
> +
> +static int gc08a3_get_selection(struct v4l2_subdev *sd,
> +				struct v4l2_subdev_state *state,
> +				struct v4l2_subdev_selection *sel)
> +{
> +	struct gc08a3 *gc08a3 = to_gc08a3(sd);
> +
> +	switch (sel->target) {
> +	case V4L2_SEL_TGT_CROP:
> +		sel->r = *v4l2_subdev_state_get_crop(state, 0);
> +		break;
> +	case V4L2_SEL_TGT_CROP_BOUNDS:
> +		sel->r.top = 0;
> +		sel->r.left = 0;
> +		sel->r.width = GC08A3_NATIVE_WIDTH;
> +		sel->r.height = GC08A3_NATIVE_HEIGHT;
> +		break;
> +	case V4L2_SEL_TGT_CROP_DEFAULT:
> +		if (gc08a3->cur_mode->width == GC08A3_NATIVE_WIDTH) {
> +			sel->r.top = 0;
> +			sel->r.left = 0;
> +			sel->r.width = gc08a3_modes[0].width;
> +			sel->r.height = gc08a3_modes[0].height;
> +		} else {
> +			sel->r.top = 0;
> +			sel->r.left = 0;
> +			sel->r.width = gc08a3_modes[1].width;
> +			sel->r.height = gc08a3_modes[1].height;
> +		}
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int gc08a3_init_state(struct v4l2_subdev *sd,
> +			     struct v4l2_subdev_state *state)
> +{
> +	struct v4l2_subdev_format fmt = {
> +		.which = V4L2_SUBDEV_FORMAT_TRY,
> +		.pad = 0,
> +		.format = {
> +			.code = GC08A3_MBUS_CODE,
> +			.width = gc08a3_modes[0].width,
> +			.height = gc08a3_modes[0].height,
> +		},
> +	};
> +
> +	gc08a3_set_format(sd, state, &fmt);
> +
> +	return 0;
> +}
> +
> +static int gc08a3_set_ctrl_hflip(struct gc08a3 *gc08a3, u32 ctrl_val)
> +{
> +	int ret;
> +	u64 val;
> +
> +	ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
> +	if (ret) {
> +		dev_err(gc08a3->dev, "read hflip register failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	val = ctrl_val ? (val | GC08A3_FLIP_H_MASK) :
> +			   (val & ~GC08A3_FLIP_H_MASK);
> +	ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
> +	if (ret < 0)
> +		dev_err(gc08a3->dev, "Error %d\n", ret);
> +
> +	return ret;
> +}
> +
> +static int gc08a3_set_ctrl_vflip(struct gc08a3 *gc08a3, u32 ctrl_val)
> +{
> +	int ret;
> +	u64 val;
> +
> +	ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
> +	if (ret) {
> +		dev_err(gc08a3->dev, "read vflip register failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	val = ctrl_val ? (val | GC08A3_FLIP_V_MASK) :
> +			   (val & ~GC08A3_FLIP_V_MASK);
> +	ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
> +	if (ret < 0)
> +		dev_err(gc08a3->dev, "Error %d\n", ret);
> +
> +	return ret;
> +}
> +
> +static int gc08a3_test_pattern(struct gc08a3 *gc08a3, u32 pattern_menu)
> +{
> +	u32 pattern = 0;
> +	int ret;

ret not initialized is ok here;

> +
> +	if (pattern_menu) {
> +		switch (pattern_menu) {
> +		case 1:
> +			pattern = 0x00;
> +			break;
> +		case 2:
> +			pattern = 0x10;
> +			break;
> +		case 3:
> +		case 4:
> +		case 5:
> +		case 6:
> +		case 7:
> +			pattern = pattern_menu + 1;
> +			break;
> +		}
> +
> +		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
> +				GC08A3_TEST_PATTERN_EN, NULL);
> +		if (ret)
> +			return ret;
> +
> +		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_IDX,
> +				pattern, NULL);

if (ret)
	return ret;

> +
> +	} else {
> +		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
> +				0x00, NULL);

if (ret)
	return ret;

> +	}
> +

	return 0;

> +	return ret;
> +}
> +
> +static int gc08a3_set_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	struct gc08a3 *gc08a3 =
> +		container_of(ctrl->handler, struct gc08a3, ctrls);
> +	int ret = 0;

int ret;

> +	s64 exposure_max;
> +
> +	if (ctrl->id == V4L2_CID_VBLANK) {
> +		/* Update max exposure while meeting expected vblanking */
> +		exposure_max = gc08a3->cur_mode->height + ctrl->val -
> +			       GC08A3_EXP_MARGIN;
> +		__v4l2_ctrl_modify_range(gc08a3->exposure,
> +					 gc08a3->exposure->minimum,
> +					 exposure_max, gc08a3->exposure->step,
> +					 exposure_max);
> +	}
> +
> +	/*
> +	 * Applying V4L2 control value only happens
> +	 * when power is on for streaming
> +	 */
> +	if (!pm_runtime_get_if_in_use(gc08a3->dev))
> +		return 0;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_EXPOSURE:
> +		ret = cci_write(gc08a3->regmap, GC08A3_EXP_REG,
> +				ctrl->val, NULL);
> +		break;
> +
> +	case V4L2_CID_ANALOGUE_GAIN:
> +		ret = cci_write(gc08a3->regmap, GC08A3_AGAIN_REG,
> +				ctrl->val, NULL);
> +		break;
> +
> +	case V4L2_CID_VBLANK:
> +		ret = cci_write(gc08a3->regmap, GC08A3_FRAME_LENGTH_REG,
> +				gc08a3->cur_mode->height + ctrl->val, NULL);
> +		break;
> +
> +	case V4L2_CID_HFLIP:
> +		ret = gc08a3_set_ctrl_hflip(gc08a3, ctrl->val);
> +		break;
> +
> +	case V4L2_CID_VFLIP:
> +		ret = gc08a3_set_ctrl_vflip(gc08a3, ctrl->val);
> +		break;
> +
> +	case V4L2_CID_TEST_PATTERN:
> +		ret = gc08a3_test_pattern(gc08a3, ctrl->val);
> +		break;
> +
> +	default:
> +		break;
> +	}
> +
> +	pm_runtime_put(gc08a3->dev);

if (ret)
	return ret;

return 0;

> +
> +	return ret;
> +}
> +

...and I've ignored some more stuff as other reviewers already gave you feedback.

Regards,
Angelo



From maz at kernel.org  Wed Feb  7 06:46:11 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  7 Feb 2024 14:46:11 +0000
Subject: [PATCH 0/2] KVM/arm64 fixes for 6.8, take #1
Message-ID: <20240207144611.1128848-1-maz@kernel.org>

Hi Paolo,

Things have been pretty quiet on the fixes front, and I'm tired of
waiting for people to find bugs. So here's what i have so far, which
is pretty little: Sebastian found yet another instance of locking
order issue with pKVM, and Masahiro has offered a cleanup of the
Kconfig file. None of them is majorly critical at this stage, but
better fix them now.

Please pull,

	M.

Masahiro Yamada (1):
  KVM: arm64: Do not source virt/lib/Kconfig twice

Sebastian Ene (1):
  KVM: arm64: Fix circular locking dependency

 arch/arm64/kvm/Kconfig |  1 -
 arch/arm64/kvm/pkvm.c  | 27 +++++++++++++++++----------
 2 files changed, 17 insertions(+), 11 deletions(-)

-- 
2.39.2

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-fixes-6.8-1

for you to fetch changes up to 42dfa94d802a48c871e2017cbf86153270c86632:

  KVM: arm64: Do not source virt/lib/Kconfig twice (2024-02-04 13:08:28 +0000)

----------------------------------------------------------------
KVM/arm64 fixes for 6.8, take #1

- Don't source the VFIO Kconfig twice

- Fix protected-mode locking order between kvm and vcpus

----------------------------------------------------------------
Masahiro Yamada (1):
      KVM: arm64: Do not source virt/lib/Kconfig twice

Sebastian Ene (1):
      KVM: arm64: Fix circular locking dependency

 arch/arm64/kvm/Kconfig |  1 -
 arch/arm64/kvm/pkvm.c  | 27 +++++++++++++++++----------
 2 files changed, 17 insertions(+), 11 deletions(-)


From krzysztof.kozlowski at linaro.org  Wed Feb  7 06:48:18 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 7 Feb 2024 15:48:18 +0100
Subject: [PATCH v2 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <CADrjBPrWH8uFrFmn_CZpr+fAnPrzbDT4i9XuMXJqKfzeouPpKg@mail.gmail.com>
References: <20240129211912.3068411-1-peter.griffin@linaro.org>
 <20240129211912.3068411-2-peter.griffin@linaro.org>
 <fb530eb8-e32b-4faf-81f3-efc334ebf241@linaro.org>
 <CADrjBPoQmTRsFYRtxBxdvAoKK816O8XN3=hOJ3vBt8wbbbk-=Q@mail.gmail.com>
 <99828589-c0b5-456d-b250-6ad3e6085a91@linaro.org>
 <CADrjBPrWH8uFrFmn_CZpr+fAnPrzbDT4i9XuMXJqKfzeouPpKg@mail.gmail.com>
Message-ID: <d367bd65-605e-44b7-9400-acd463dec0b6@linaro.org>

On 07/02/2024 12:42, Peter Griffin wrote:
>>>>>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>>>>>  #include <linux/soc/samsung/exynos-pmu.h>
>>>>>
>>>>>  #include "exynos-pmu.h"
>>>>>
>>>>> +static struct platform_driver exynos_pmu_driver;
>>>>
>>>> I don't understand why do you need it. You can have only one
>>>> pmu_context. The moment you probe second one, previous becomes invalid.
>>>>
>>>> I guess you want to parse phandle and check if just in case if it points
>>>> to the right device, but still the original code is not ready for two
>>>> PMU devices. I say either this problem should be solved entirely,
>>>> allowing two devices, or just compare device node from phandle with
>>>> device node of exynos_pmu_context->dev and return -EINVAL on mismatches.
>>>
>>> Apologies I didn't answer your original question. This wasn't about
>>> having partial support for multiple pmu devices. It is being used by
>>> driver_find_device_by_of_node() in exynos_get_pmu_regmap_by_phandle()
>>> to determine that the exynos-pmu device has probed and therefore a
>>> pmu_context exists and a regmap has been created and can be returned
>>> to the caller (as opposed to doing a -EPROBE_DEFER).
>>>
>>> Is there some better/other API you recommend for this purpose? Just
>>> checking pmu_context directly seems racy, so I don't think we should
>>> do that.
>>
>> Hm, I don't quite get why you cannot use of_find_device_by_node()?
> 
> of_find_device_by_node() returns a platform_device, even if the driver
> hasn't probed. Whereas driver_find_device_by_of_node() iterates
> devices bound to a driver.
> 
> If using of_find_device_by_node() API I could check the result of
> platform_get_drvdata(), and -EPROBE_DEFER if NULL (that pattern seems
> to be used by a few drivers). But that AFAIK only guarantees you
> reached the platform_set_drvdata() call in your driver probe()
> function, not that it has completed.

All drivers, except two, use of_find_device_by_node(), so basically you
claim they are all broken. If that's true, the core API and these
drivers should be fixed, instead of implementing here entirely different
pattern.

of_find_device_by_node() goes via platform_bus_type->sp->klist_devices
and devices are added to the list in device_add() after
bus_probe_device(dev), regardless of its success. Therefore after
successful first probe, you will have the same result.


> 
> IMHO the drivers using driver_find_device_by_of_node() for probe
> deferral are doing it more robustly than those using
> of_find_device_by_node()  and checking if platform_get_drvdata() is
> NULL.

Some are checking dev->driver, but this also looks buggy, because it is
called before actual drv->probe().

OK, let's go with this method. I dislike the difference from everyone
else, but it seems everyone else is doing it wrong. :(

Best regards,
Krzysztof



From sebastianene at google.com  Wed Feb  7 06:48:30 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Wed,  7 Feb 2024 14:48:30 +0000
Subject: [PATCH v5 1/4] arm64: ptdump: Expose the attribute parsing functionality
In-Reply-To: <20240207144832.1017815-2-sebastianene@google.com>
References: <20240207144832.1017815-2-sebastianene@google.com>
Message-ID: <20240207144832.1017815-3-sebastianene@google.com>

To keep the same output format as the arch specific ptdump and for the
sake of reusability, move the parser's state tracking code out
of the arch specific.

Signed-off-by: Sebastian Ene <sebastianene at google.com>
---
 arch/arm64/include/asm/ptdump.h | 41 ++++++++++++++++++++++++++++++++-
 arch/arm64/mm/ptdump.c          | 36 ++---------------------------
 2 files changed, 42 insertions(+), 35 deletions(-)

diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
index 581caac525b0..23510be35084 100644
--- a/arch/arm64/include/asm/ptdump.h
+++ b/arch/arm64/include/asm/ptdump.h
@@ -9,6 +9,8 @@
 
 #include <linux/mm_types.h>
 #include <linux/seq_file.h>
+#include <linux/ptdump.h>
+
 
 struct addr_marker {
 	unsigned long start_address;
@@ -21,15 +23,52 @@ struct ptdump_info {
 	unsigned long			base_addr;
 };
 
+struct prot_bits {
+	u64		mask;
+	u64		val;
+	const char	*set;
+	const char	*clear;
+};
+
+struct pg_level {
+	const struct prot_bits	*bits;
+	const char		*name;
+	size_t			num;
+	u64			mask;
+};
+
+/*
+ * The page dumper groups page table entries of the same type into a single
+ * description. It uses pg_state to track the range information while
+ * iterating over the pte entries. When the continuity is broken it then
+ * dumps out a description of the range.
+ */
+struct pg_state {
+	struct ptdump_state		ptdump;
+	struct seq_file			*seq;
+	const struct addr_marker	*marker;
+	unsigned long			start_address;
+	int				level;
+	u64				current_prot;
+	bool				check_wx;
+	unsigned long			wx_pages;
+	unsigned long			uxn_pages;
+};
+
 void ptdump_walk(struct seq_file *s, struct ptdump_info *info);
+void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
+	       u64 val);
 #ifdef CONFIG_PTDUMP_DEBUGFS
 #define EFI_RUNTIME_MAP_END	DEFAULT_MAP_WINDOW_64
 void __init ptdump_debugfs_register(struct ptdump_info *info, const char *name);
 #else
 static inline void ptdump_debugfs_register(struct ptdump_info *info,
 					   const char *name) { }
-#endif
+#endif /* CONFIG_PTDUMP_DEBUGFS */
 void ptdump_check_wx(void);
+#else
+static inline void note_page(void *pt_st, unsigned long addr,
+			     int level, u64 val) { }
 #endif /* CONFIG_PTDUMP_CORE */
 
 #ifdef CONFIG_DEBUG_WX
diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
index e305b6593c4e..64127c70b109 100644
--- a/arch/arm64/mm/ptdump.c
+++ b/arch/arm64/mm/ptdump.c
@@ -66,31 +66,6 @@ static struct addr_marker address_markers[] = {
 		seq_printf(m, fmt);	\
 })
 
-/*
- * The page dumper groups page table entries of the same type into a single
- * description. It uses pg_state to track the range information while
- * iterating over the pte entries. When the continuity is broken it then
- * dumps out a description of the range.
- */
-struct pg_state {
-	struct ptdump_state ptdump;
-	struct seq_file *seq;
-	const struct addr_marker *marker;
-	unsigned long start_address;
-	int level;
-	u64 current_prot;
-	bool check_wx;
-	unsigned long wx_pages;
-	unsigned long uxn_pages;
-};
-
-struct prot_bits {
-	u64		mask;
-	u64		val;
-	const char	*set;
-	const char	*clear;
-};
-
 static const struct prot_bits pte_bits[] = {
 	{
 		.mask	= PTE_VALID,
@@ -170,13 +145,6 @@ static const struct prot_bits pte_bits[] = {
 	}
 };
 
-struct pg_level {
-	const struct prot_bits *bits;
-	const char *name;
-	size_t num;
-	u64 mask;
-};
-
 static struct pg_level pg_level[] = {
 	{ /* pgd */
 		.name	= "PGD",
@@ -248,8 +216,8 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
 	st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
 }
 
-static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
-		      u64 val)
+void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
+	       u64 val)
 {
 	struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
 	static const char units[] = "KMGTPE";
-- 
2.43.0.594.gd9cf4e227d-goog



From sebastianene at google.com  Wed Feb  7 06:48:29 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Wed,  7 Feb 2024 14:48:29 +0000
Subject: [PATCH v5 0/4] arm64: ptdump: View the second stage page-tables
Message-ID: <20240207144832.1017815-2-sebastianene@google.com>

Hi,

This is the first part of the series which enables dumping of the guest
stage-2 pagetables. The support for dumping the host stage-2 pagetables
which is pKVM specific will be part of a follow-up series as per the
feedback received in v4. 

When CONFIG_PTDUMP_STAGE2_DEBUGFS is enabled, ptdump registers 
'/sys/debug/kvm/<guest_id>/stage2_page_tables' entry with debugfs
upon guest creation. This allows userspace tools (eg. cat) to dump the
stage-2 pagetables by reading the registered file.

Reading the debugfs file shows stage-2 memory ranges in following format:
<IPA range> <size> <descriptor type> <access permissions> <mem_attributes>

Below is the output of a guest stage-2 pagetable mappings running under
Qemu:

---[ IPA bits 33 start lvl 2 ]---
0x0000000000000000-0x0000000080000000           2G PGD
0x0000000080000000-0x0000000080c00000          12M PGD      R W AF        BLK
0x0000000080c00000-0x0000000080e00000           2M PGD   XN R W AF        BLK
0x0000000080e00000-0x0000000081000000           2M PGD      R W AF        BLK
0x0000000081000000-0x0000000081400000           4M PGD   XN R W AF        BLK
0x0000000081400000-0x000000008fe00000         234M PGD
0x000000008fe00000-0x0000000090000000           2M PGD   XN R W AF        BLK
0x0000000090000000-0x00000000fa000000        1696M PGD
0x00000000fa000000-0x00000000fe000000          64M PGD   XN R W AF        BLK
0x00000000fe000000-0x0000000100000000          32M PGD
0x0000000100000000-0x0000000101c00000          28M PGD   XN R W AF        BLK
0x0000000101c00000-0x0000000102000000           4M PGD
0x0000000102000000-0x0000000102200000           2M PGD   XN R W AF        BLK
0x0000000102200000-0x000000017b000000        1934M PGD
0x000000017b000000-0x0000000180000000          80M PGD   XN R W AF        BLK

Link to v4:
https://lore.kernel.org/all/20231218135859.2513568-2-sebastianene at google.com/

Link to v3:
https://lore.kernel.org/all/20231115171639.2852644-2-sebastianene at google.com/

Changelog:
 v4 -> current_version:
 * refactorization: split the series into two parts as per the feedback
   received from Oliver. Introduce the base support which allows dumping
   of the guest stage-2 pagetables.
 
 * removed the *ops* struct wrapper built on top of the file_ops and
   simplify the ptdump interface access.
 
 * keep the page table walker away from the ptdump specific code

  v3 -> current_version:
  * refactorization: moved all the **KVM** specific components under
    kvm/ as suggested by Oliver. Introduced a new file
    arm64/kvm/ptdump.c which handled the second stage translation.
    re-used only the display portion from mm/ptdump.c

  * pagetable snapshot creation now uses memory donated from the host.
    The memory is no longer shared with the host as this can pose a security
    risk if the host has access to manipulate the pagetable copy while
    the hypervisor iterates it.

  * fixed a memory leak: while memory was used from the memcache for
    building the snapshot pagetable, it was no longer giving back the
    pages to the host for freeing. A separate array was introduced to
    keep track of the pages allocated from the memcache.

  v2 -> v3:
  * register the stage-2 debugfs entry for the host under
    /sys/debug/kvm/host_stage2_page_tables and in
    /sys/debug/kvm/<guest_id>/stage2_page_tables for guests.

  * don't use a static array for parsing the attributes description,
    generate it dynamically based on the number of pagetable levels

  * remove the lock that was guarding the seq_file private inode data,
    and keep the data private to the open file session.

  * minor fixes & renaming of CONFIG_NVHE_EL2_PTDUMP_DEBUGFS to
    CONFIG_PTDUMP_STAGE2_DEBUGFS

  v1 -> v2:
  * use the stage-2 pagetable walker for dumping descriptors instead of
    the one provided by ptdump.

  * support for guests pagetables dumping under VHE/nVHE non-protected

Thanks,

Sebastian Ene (4):
  arm64: ptdump: Expose the attribute parsing functionality
  arm64: ptdump: Use the mask from the state structure
  KVM: arm64: Register ptdump with debugfs on guest creation
  KVM: arm64: Initialize the ptdump parser with stage-2 attributes

 arch/arm64/include/asm/ptdump.h |  42 +++++-
 arch/arm64/kvm/Kconfig          |  13 ++
 arch/arm64/kvm/Makefile         |   1 +
 arch/arm64/kvm/debug.c          |   7 +
 arch/arm64/kvm/kvm_ptdump.h     |  20 +++
 arch/arm64/kvm/ptdump.c         | 235 ++++++++++++++++++++++++++++++++
 arch/arm64/mm/ptdump.c          |  49 ++-----
 7 files changed, 327 insertions(+), 40 deletions(-)
 create mode 100644 arch/arm64/kvm/kvm_ptdump.h
 create mode 100644 arch/arm64/kvm/ptdump.c

-- 
2.43.0.594.gd9cf4e227d-goog



From sebastianene at google.com  Wed Feb  7 06:48:31 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Wed,  7 Feb 2024 14:48:31 +0000
Subject: [PATCH v5 2/4] arm64: ptdump: Use the mask from the state structure
In-Reply-To: <20240207144832.1017815-2-sebastianene@google.com>
References: <20240207144832.1017815-2-sebastianene@google.com>
Message-ID: <20240207144832.1017815-4-sebastianene@google.com>

Printing the descriptor attributes requires accessing a mask which has a
different set of attributes for stage-2. In preparation for adding support
for the stage-2 pagetables dumping, use the mask from the local context
and not from the globally defined pg_level array. Store a pointer to
the pg_level array in the ptdump state structure. This will allow us to
extract the mask which is wrapped in the pg_level array and use it for
descriptor parsing in the note_page.

Signed-off-by: Sebastian Ene <sebastianene at google.com>
---
 arch/arm64/include/asm/ptdump.h |  1 +
 arch/arm64/mm/ptdump.c          | 13 ++++++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
index 23510be35084..4e728d2a1f2c 100644
--- a/arch/arm64/include/asm/ptdump.h
+++ b/arch/arm64/include/asm/ptdump.h
@@ -45,6 +45,7 @@ struct pg_level {
  */
 struct pg_state {
 	struct ptdump_state		ptdump;
+	struct pg_level			*pg_level;
 	struct seq_file			*seq;
 	const struct addr_marker	*marker;
 	unsigned long			start_address;
diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
index 64127c70b109..015ed65d3e9b 100644
--- a/arch/arm64/mm/ptdump.c
+++ b/arch/arm64/mm/ptdump.c
@@ -220,11 +220,12 @@ void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
 	       u64 val)
 {
 	struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
+	struct pg_level *pg_info = st->pg_level;
 	static const char units[] = "KMGTPE";
 	u64 prot = 0;
 
 	if (level >= 0)
-		prot = val & pg_level[level].mask;
+		prot = val & pg_info[level].mask;
 
 	if (st->level == -1) {
 		st->level = level;
@@ -250,10 +251,10 @@ void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
 			unit++;
 		}
 		pt_dump_seq_printf(st->seq, "%9lu%c %s", delta, *unit,
-				   pg_level[st->level].name);
-		if (st->current_prot && pg_level[st->level].bits)
-			dump_prot(st, pg_level[st->level].bits,
-				  pg_level[st->level].num);
+				   pg_info[st->level].name);
+		if (st->current_prot && pg_info[st->level].bits)
+			dump_prot(st, pg_info[st->level].bits,
+				  pg_info[st->level].num);
 		pt_dump_seq_puts(st->seq, "\n");
 
 		if (addr >= st->marker[1].start_address) {
@@ -284,6 +285,7 @@ void ptdump_walk(struct seq_file *s, struct ptdump_info *info)
 	st = (struct pg_state){
 		.seq = s,
 		.marker = info->markers,
+		.pg_level = &pg_level[0],
 		.level = -1,
 		.ptdump = {
 			.note_page = note_page,
@@ -321,6 +323,7 @@ void ptdump_check_wx(void)
 			{ 0, NULL},
 			{ -1, NULL},
 		},
+		.pg_level = &pg_level[0],
 		.level = -1,
 		.check_wx = true,
 		.ptdump = {
-- 
2.43.0.594.gd9cf4e227d-goog



From sebastianene at google.com  Wed Feb  7 06:48:32 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Wed,  7 Feb 2024 14:48:32 +0000
Subject: [PATCH v5 3/4] KVM: arm64: Register ptdump with debugfs on guest creation
In-Reply-To: <20240207144832.1017815-2-sebastianene@google.com>
References: <20240207144832.1017815-2-sebastianene@google.com>
Message-ID: <20240207144832.1017815-5-sebastianene@google.com>

While arch/*/mem/ptdump handles the kernel pagetable dumping code,
introduce KVM/ptdump which shows the guest stage-2 pagetables. The
separation is necessary because most of the definitions from the
stage-2 pagetable reside in the KVM path and we will be invoking
functionality **specific** to KVM.

When a guest is created, register a new file entry under the guest
debugfs dir which allows userspace to show the contents of the guest
stage-2 pagetables when accessed.

Signed-off-by: Sebastian Ene <sebastianene at google.com>
---
 arch/arm64/kvm/Kconfig      | 13 ++++++
 arch/arm64/kvm/Makefile     |  1 +
 arch/arm64/kvm/debug.c      |  7 ++++
 arch/arm64/kvm/kvm_ptdump.h | 20 ++++++++++
 arch/arm64/kvm/ptdump.c     | 79 +++++++++++++++++++++++++++++++++++++
 5 files changed, 120 insertions(+)
 create mode 100644 arch/arm64/kvm/kvm_ptdump.h
 create mode 100644 arch/arm64/kvm/ptdump.c

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6c3c8ca73e7f..28097dd72174 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -68,4 +68,17 @@ config PROTECTED_NVHE_STACKTRACE
 
 	  If unsure, or not using protected nVHE (pKVM), say N.
 
+config PTDUMP_STAGE2_DEBUGFS
+       bool "Present the stage-2 pagetables to debugfs"
+       depends on PTDUMP_DEBUGFS && KVM
+       default n
+       help
+         Say Y here if you want to show the stage-2 kernel pagetables
+         layout in a debugfs file. This information is only useful for kernel developers
+         who are working in architecture specific areas of the kernel.
+         It is probably not a good idea to enable this feature in a production
+         kernel.
+
+         If in doubt, say N.
+
 endif # VIRTUALIZATION
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index c0c050e53157..190eac17538c 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -23,6 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 vgic/vgic-its.o vgic/vgic-debug.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
+kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
 
 always-y := hyp_constants.h hyp-constants.s
 
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 8725291cb00a..aef52836cd90 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -14,6 +14,8 @@
 #include <asm/kvm_arm.h>
 #include <asm/kvm_emulate.h>
 
+#include <kvm_ptdump.h>
+
 #include "trace.h"
 
 /* These are the bits of MDSCR_EL1 we may manipulate */
@@ -342,3 +344,8 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
 }
+
+int kvm_arch_create_vm_debugfs(struct kvm *kvm)
+{
+	return kvm_ptdump_guest_register(kvm);
+}
diff --git a/arch/arm64/kvm/kvm_ptdump.h b/arch/arm64/kvm/kvm_ptdump.h
new file mode 100644
index 000000000000..a7c00a28481b
--- /dev/null
+++ b/arch/arm64/kvm/kvm_ptdump.h
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) Google, 2023
+ * Author: Sebastian Ene <sebastianene at google.com>
+ */
+
+#ifndef __KVM_PTDUMP_H
+#define __KVM_PTDUMP_H
+
+#include <linux/kvm_host.h>
+#include <asm/ptdump.h>
+
+
+#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
+int kvm_ptdump_guest_register(struct kvm *kvm);
+#else
+static inline int kvm_ptdump_guest_register(struct kvm *kvm) { return 0; }
+#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
+
+#endif /* __KVM_PTDUMP_H */
diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
new file mode 100644
index 000000000000..a4e984da8aa7
--- /dev/null
+++ b/arch/arm64/kvm/ptdump.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Debug helper used to dump the stage-2 pagetables of the system and their
+// associated permissions.
+//
+// Copyright (C) Google, 2023
+// Author: Sebastian Ene <sebastianene at google.com>
+
+#include <linux/debugfs.h>
+#include <linux/kvm_host.h>
+#include <linux/seq_file.h>
+
+#include <asm/kvm_pkvm.h>
+#include <kvm_ptdump.h>
+
+
+static int kvm_ptdump_guest_open(struct inode *inode, struct file *file);
+static int kvm_ptdump_guest_show(struct seq_file *m, void *);
+
+static const struct file_operations kvm_ptdump_guest_fops = {
+	.open		= kvm_ptdump_guest_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int kvm_ptdump_guest_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, kvm_ptdump_guest_show, inode->i_private);
+}
+
+static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
+			      enum kvm_pgtable_walk_flags visit)
+{
+	struct pg_state *st = ctx->arg;
+	struct ptdump_state *pt_st = &st->ptdump;
+
+	note_page(pt_st, ctx->addr, ctx->level, ctx->old);
+	return 0;
+}
+
+static int kvm_ptdump_show_common(struct seq_file *m,
+				  struct kvm_pgtable *pgtable,
+				  struct pg_state *parser_state)
+{
+	struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker) {
+		.cb     = kvm_ptdump_visitor,
+		.arg	= parser_state,
+		.flags	= KVM_PGTABLE_WALK_LEAF,
+	};
+
+	return kvm_pgtable_walk(pgtable, 0, BIT(pgtable->ia_bits), &walker);
+}
+
+static int kvm_ptdump_guest_show(struct seq_file *m, void *)
+{
+	struct kvm *guest_kvm = m->private;
+	struct kvm_s2_mmu *mmu = &guest_kvm->arch.mmu;
+	struct pg_state parser_state = {0};
+	int ret;
+
+	write_lock(&guest_kvm->mmu_lock);
+	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
+	write_unlock(&guest_kvm->mmu_lock);
+
+	return ret;
+}
+
+int kvm_ptdump_guest_register(struct kvm *kvm)
+{
+	struct dentry *parent;
+
+	parent = debugfs_create_file("stage2_page_tables", 0400,
+				     kvm->debugfs_dentry, kvm,
+				     &kvm_ptdump_guest_fops);
+	if (IS_ERR(parent))
+		return PTR_ERR(parent);
+	return 0;
+}
-- 
2.43.0.594.gd9cf4e227d-goog



From sebastianene at google.com  Wed Feb  7 06:48:33 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Wed,  7 Feb 2024 14:48:33 +0000
Subject: [PATCH v5 4/4] KVM: arm64: Initialize the ptdump parser with stage-2 attributes
In-Reply-To: <20240207144832.1017815-2-sebastianene@google.com>
References: <20240207144832.1017815-2-sebastianene@google.com>
Message-ID: <20240207144832.1017815-6-sebastianene@google.com>

Define a set of attributes used by the ptdump parser to display the
properties of a guest memory region covered by a pagetable descriptor.
Build a description of the pagetable levels and initialize the parser
with this configuration.

Signed-off-by: Sebastian Ene <sebastianene at google.com>
---
 arch/arm64/kvm/ptdump.c | 156 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 156 insertions(+)

diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
index a4e984da8aa7..60725d46f17b 100644
--- a/arch/arm64/kvm/ptdump.c
+++ b/arch/arm64/kvm/ptdump.c
@@ -14,6 +14,69 @@
 #include <kvm_ptdump.h>
 
 
+#define ADDR_MARKER_LEN		(2)
+#define MARKER_MSG_LEN		(32)
+
+static const struct prot_bits stage2_pte_bits[] = {
+	{
+		.mask	= PTE_VALID,
+		.val	= PTE_VALID,
+		.set	= " ",
+		.clear	= "F",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
+		.set	= "XN",
+		.clear	= "  ",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
+		.set	= "R",
+		.clear	= " ",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
+		.set	= "W",
+		.clear	= " ",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
+		.set	= "AF",
+		.clear	= "  ",
+	}, {
+		.mask	= PTE_NG,
+		.val	= PTE_NG,
+		.set	= "FnXS",
+		.clear	= "  ",
+	}, {
+		.mask	= PTE_CONT | PTE_VALID,
+		.val	= PTE_CONT | PTE_VALID,
+		.set	= "CON",
+		.clear	= "   ",
+	}, {
+		.mask	= PTE_TABLE_BIT,
+		.val	= PTE_TABLE_BIT,
+		.set	= "   ",
+		.clear	= "BLK",
+	}, {
+		.mask	= KVM_PGTABLE_PROT_SW0,
+		.val	= KVM_PGTABLE_PROT_SW0,
+		.set	= "SW0", /* PKVM_PAGE_SHARED_OWNED */
+	}, {
+		.mask   = KVM_PGTABLE_PROT_SW1,
+		.val	= KVM_PGTABLE_PROT_SW1,
+		.set	= "SW1", /* PKVM_PAGE_SHARED_BORROWED */
+	}, {
+		.mask	= KVM_PGTABLE_PROT_SW2,
+		.val	= KVM_PGTABLE_PROT_SW2,
+		.set	= "SW2",
+	}, {
+		.mask   = KVM_PGTABLE_PROT_SW3,
+		.val	= KVM_PGTABLE_PROT_SW3,
+		.set	= "SW3",
+	},
+};
+
 static int kvm_ptdump_guest_open(struct inode *inode, struct file *file);
 static int kvm_ptdump_guest_show(struct seq_file *m, void *);
 
@@ -52,6 +115,94 @@ static int kvm_ptdump_show_common(struct seq_file *m,
 	return kvm_pgtable_walk(pgtable, 0, BIT(pgtable->ia_bits), &walker);
 }
 
+static void kvm_ptdump_build_levels(struct pg_level *level, u32 start_lvl)
+{
+	static const char * const level_names[] = {"PGD", "PUD", "PMD", "PTE"};
+	u32 i = 0;
+	u64 mask_lvl = 0;
+
+	if (start_lvl > 2) {
+		pr_err("invalid start_lvl %u\n", start_lvl);
+		return;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(stage2_pte_bits); i++)
+		mask_lvl |= stage2_pte_bits[i].mask;
+
+	for (i = start_lvl; i <= KVM_PGTABLE_LAST_LEVEL; i++) {
+		level[i].name = level_names[i];
+		level[i].num = ARRAY_SIZE(stage2_pte_bits);
+		level[i].bits = stage2_pte_bits;
+		level[i].mask = mask_lvl;
+	}
+
+	if (start_lvl > 0)
+		level[start_lvl].name = level_names[0];
+}
+
+static int kvm_ptdump_parser_init(struct pg_state *st,
+				  struct kvm_pgtable *pgtable,
+				  struct seq_file *m)
+{
+	struct addr_marker *ipa_addr_marker;
+	char *marker_msg;
+	struct pg_level *level_descr;
+	struct ptdump_range *range;
+
+	ipa_addr_marker = kzalloc(sizeof(struct addr_marker) * ADDR_MARKER_LEN,
+				  GFP_KERNEL_ACCOUNT);
+	if (!ipa_addr_marker)
+		return -ENOMEM;
+
+	marker_msg = kzalloc(MARKER_MSG_LEN, GFP_KERNEL_ACCOUNT);
+	if (!marker_msg)
+		goto free_with_marker;
+
+	level_descr = kzalloc(sizeof(struct pg_level) * (KVM_PGTABLE_LAST_LEVEL + 1),
+			      GFP_KERNEL_ACCOUNT);
+	if (!level_descr)
+		goto free_with_msg;
+
+	range = kzalloc(sizeof(struct ptdump_range) * ADDR_MARKER_LEN,
+			GFP_KERNEL_ACCOUNT);
+	if (!range)
+		goto free_with_level;
+
+	kvm_ptdump_build_levels(level_descr, pgtable->start_level);
+
+	snprintf(marker_msg, MARKER_MSG_LEN, "IPA bits %2u start lvl %1d",
+		 pgtable->ia_bits, pgtable->start_level);
+
+	ipa_addr_marker[0].name = marker_msg;
+	ipa_addr_marker[1].start_address = BIT(pgtable->ia_bits);
+	range[0].end = BIT(pgtable->ia_bits);
+
+	st->seq = m;
+	st->marker = ipa_addr_marker;
+	st->level = -1,
+	st->pg_level = level_descr,
+	st->ptdump.range = range;
+	return 0;
+
+free_with_level:
+	kfree(level_descr);
+free_with_msg:
+	kfree(marker_msg);
+free_with_marker:
+	kfree(ipa_addr_marker);
+	return -ENOMEM;
+}
+
+static void kvm_ptdump_parser_teardown(struct pg_state *st)
+{
+	const struct addr_marker *ipa_addr_marker = st->marker;
+
+	kfree(ipa_addr_marker[0].name);
+	kfree(ipa_addr_marker);
+	kfree(st->pg_level);
+	kfree(st->ptdump.range);
+}
+
 static int kvm_ptdump_guest_show(struct seq_file *m, void *)
 {
 	struct kvm *guest_kvm = m->private;
@@ -59,10 +210,15 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *)
 	struct pg_state parser_state = {0};
 	int ret;
 
+	ret = kvm_ptdump_parser_init(&parser_state, mmu->pgt, m);
+	if (ret)
+		return ret;
+
 	write_lock(&guest_kvm->mmu_lock);
 	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
 	write_unlock(&guest_kvm->mmu_lock);
 
+	kvm_ptdump_parser_teardown(&parser_state);
 	return ret;
 }
 
-- 
2.43.0.594.gd9cf4e227d-goog



From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:52:58 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed,  7 Feb 2024 15:52:58 +0100
Subject: [PATCH v5 0/9] MediaTek DRM - DSI driver cleanups
Message-ID: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>

Changes in v5:
 - Changed patch 1 to not fix the DSI_PS_SEL mask for newer SoCs

Changes in v4:
 - Added a fix for RGB666 formats setting and for wrong register
   definitions for packed vs loosely packed formats
 - Added a commit to make use of mipi_dsi_pixel_format_to_bpp() helper
   instead of open coding the same

Changes in v3:
 - Rebased over next-20240131
 - Added bitfield.h inclusion in patch 3
 - Added three more cleanup commits to the mix to simplify
   the probe function and remove gotos.

Changes in v2:
 - Rebased over next-20231213

This series performs some cleanups for mtk_dsi, enhancing human
readability, using kernel provided macros where possible and
also reducing code size.

Tested on MT8173 and MT8192 Chromebooks (using a DSI<->DP bridge)
and on MT6795 Sony Xperia M5 (DSI video mode panel).


AngeloGioacchino Del Regno (9):
  drm/mediatek: dsi: Use GENMASK() for register mask definitions
  drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
  drm/mediatek: dsi: Cleanup functions mtk_dsi_ps_control{_vact}()
  drm/mediatek: dsi: Use bitfield macros where useful
  drm/mediatek: dsi: Replace open-coded instance of HZ_PER_MHZ
  drm/mediatek: dsi: Register DSI host after acquiring clocks and PHY
  drm/mediatek: dsi: Simplify with dev_err_probe and remove gotos
  drm/mediatek: dsi: Compress of_device_id entries and add sentinel
  drm/mediatek: dsi: Use mipi_dsi_pixel_format_to_bpp() helper function

 drivers/gpu/drm/mediatek/mtk_dsi.c | 310 ++++++++++++-----------------
 1 file changed, 126 insertions(+), 184 deletions(-)

-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:52:59 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed,  7 Feb 2024 15:52:59 +0100
Subject: [PATCH v5 1/9] drm/mediatek: dsi: Use GENMASK() for register mask definitions
In-Reply-To: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240207145307.1626009-2-angelogioacchino.delregno@collabora.com>

Change magic numerical masks with usage of the GENMASK() macro
to improve readability.

This commit brings no functional changes.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 45 +++++++++++++++---------------
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index a2fdfc8ddb15..c66e18006070 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -58,18 +58,18 @@
 
 #define DSI_TXRX_CTRL		0x18
 #define VC_NUM				BIT(1)
-#define LANE_NUM			(0xf << 2)
+#define LANE_NUM			GENMASK(5, 2)
 #define DIS_EOT				BIT(6)
 #define NULL_EN				BIT(7)
 #define TE_FREERUN			BIT(8)
 #define EXT_TE_EN			BIT(9)
 #define EXT_TE_EDGE			BIT(10)
-#define MAX_RTN_SIZE			(0xf << 12)
+#define MAX_RTN_SIZE			GENMASK(15, 12)
 #define HSTX_CKLP_EN			BIT(16)
 
 #define DSI_PSCTRL		0x1c
-#define DSI_PS_WC			0x3fff
-#define DSI_PS_SEL			(3 << 16)
+#define DSI_PS_WC			GENMASK(13, 0)
+#define DSI_PS_SEL			GENMASK(17, 16)
 #define PACKED_PS_16BIT_RGB565		(0 << 16)
 #define LOOSELY_PS_18BIT_RGB666		(1 << 16)
 #define PACKED_PS_18BIT_RGB666		(2 << 16)
@@ -109,26 +109,26 @@
 #define LD0_WAKEUP_EN			BIT(2)
 
 #define DSI_PHY_TIMECON0	0x110
-#define LPX				(0xff << 0)
-#define HS_PREP				(0xff << 8)
-#define HS_ZERO				(0xff << 16)
-#define HS_TRAIL			(0xff << 24)
+#define LPX				GENMASK(7, 0)
+#define HS_PREP				GENMASK(15, 8)
+#define HS_ZERO				GENMASK(23, 16)
+#define HS_TRAIL			GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON1	0x114
-#define TA_GO				(0xff << 0)
-#define TA_SURE				(0xff << 8)
-#define TA_GET				(0xff << 16)
-#define DA_HS_EXIT			(0xff << 24)
+#define TA_GO				GENMASK(7, 0)
+#define TA_SURE				GENMASK(15, 8)
+#define TA_GET				GENMASK(23, 16)
+#define DA_HS_EXIT			GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON2	0x118
-#define CONT_DET			(0xff << 0)
-#define CLK_ZERO			(0xff << 16)
-#define CLK_TRAIL			(0xff << 24)
+#define CONT_DET			GENMASK(7, 0)
+#define CLK_ZERO			GENMASK(23, 16)
+#define CLK_TRAIL			GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON3	0x11c
-#define CLK_HS_PREP			(0xff << 0)
-#define CLK_HS_POST			(0xff << 8)
-#define CLK_HS_EXIT			(0xff << 16)
+#define CLK_HS_PREP			GENMASK(7, 0)
+#define CLK_HS_POST			GENMASK(15, 8)
+#define CLK_HS_EXIT			GENMASK(23, 16)
 
 #define DSI_VM_CMD_CON		0x130
 #define VM_CMD_EN			BIT(0)
@@ -138,13 +138,14 @@
 #define FORCE_COMMIT			BIT(0)
 #define BYPASS_SHADOW			BIT(1)
 
-#define CONFIG				(0xff << 0)
+/* CMDQ related bits */
+#define CONFIG				GENMASK(7, 0)
 #define SHORT_PACKET			0
 #define LONG_PACKET			2
 #define BTA				BIT(2)
-#define DATA_ID				(0xff << 8)
-#define DATA_0				(0xff << 16)
-#define DATA_1				(0xff << 24)
+#define DATA_ID				GENMASK(15, 8)
+#define DATA_0				GENMASK(23, 16)
+#define DATA_1				GENMASK(31, 24)
 
 #define NS_TO_CYCLE(n, c)    ((n) / (c) + (((n) % (c)) ? 1 : 0))
 
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:53:01 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed,  7 Feb 2024 15:53:01 +0100
Subject: [PATCH v5 3/9] drm/mediatek: dsi: Cleanup functions mtk_dsi_ps_control{_vact}()
In-Reply-To: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240207145307.1626009-4-angelogioacchino.delregno@collabora.com>

Function mtk_dsi_ps_control() is a subset of mtk_dsi_ps_control_vact():
merge the two in one mtk_dsi_ps_control() function by adding one
function parameter `config_vact` which, when true, writes the VACT
related registers.

Reviewed-by: Fei Shao <fshao at chromium.org>
Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 76 +++++++++---------------------
 1 file changed, 23 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 8af0afbe9e3d..7d38e9500700 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -351,40 +351,6 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
 	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
 }
 
-static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
-{
-	struct videomode *vm = &dsi->vm;
-	u32 dsi_buf_bpp, ps_wc;
-	u32 ps_bpp_mode;
-
-	if (dsi->format == MIPI_DSI_FMT_RGB565)
-		dsi_buf_bpp = 2;
-	else
-		dsi_buf_bpp = 3;
-
-	ps_wc = vm->hactive * dsi_buf_bpp;
-	ps_bpp_mode = ps_wc;
-
-	switch (dsi->format) {
-	case MIPI_DSI_FMT_RGB888:
-		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
-		break;
-	case MIPI_DSI_FMT_RGB666:
-		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
-		break;
-	case MIPI_DSI_FMT_RGB666_PACKED:
-		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
-		break;
-	case MIPI_DSI_FMT_RGB565:
-		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
-		break;
-	}
-
-	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
-	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
-	writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
-}
-
 static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 {
 	u32 tmp_reg;
@@ -416,36 +382,40 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 	writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
 }
 
-static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
+static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
 {
-	u32 dsi_tmp_buf_bpp;
-	u32 tmp_reg;
+	struct videomode *vm = &dsi->vm;
+	u32 dsi_buf_bpp, ps_wc;
+	u32 ps_bpp_mode;
+
+	if (dsi->format == MIPI_DSI_FMT_RGB565)
+		dsi_buf_bpp = 2;
+	else
+		dsi_buf_bpp = 3;
+
+	ps_wc = vm->hactive * dsi_buf_bpp;
+	ps_bpp_mode = ps_wc;
 
 	switch (dsi->format) {
 	case MIPI_DSI_FMT_RGB888:
-		tmp_reg = PACKED_PS_24BIT_RGB888;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		tmp_reg = LOOSELY_PS_24BIT_RGB666;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-		tmp_reg = PACKED_PS_18BIT_RGB666;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB565:
-		tmp_reg = PACKED_PS_16BIT_RGB565;
-		dsi_tmp_buf_bpp = 2;
-		break;
-	default:
-		tmp_reg = PACKED_PS_24BIT_RGB888;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
 		break;
 	}
 
-	tmp_reg += dsi->vm.hactive * dsi_tmp_buf_bpp & DSI_PS_WC;
-	writel(tmp_reg, dsi->regs + DSI_PSCTRL);
+	if (config_vact) {
+		writel(vm->vactive, dsi->regs + DSI_VACT_NL);
+		writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
+	}
+	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
 }
 
 static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
@@ -521,7 +491,7 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
 	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
 
-	mtk_dsi_ps_control(dsi);
+	mtk_dsi_ps_control(dsi, false);
 }
 
 static void mtk_dsi_start(struct mtk_dsi *dsi)
@@ -666,7 +636,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	mtk_dsi_reset_engine(dsi);
 	mtk_dsi_phy_timconfig(dsi);
 
-	mtk_dsi_ps_control_vact(dsi);
+	mtk_dsi_ps_control(dsi, true);
 	mtk_dsi_set_vm_cmd(dsi);
 	mtk_dsi_config_vdo_timing(dsi);
 	mtk_dsi_set_interrupt_enable(dsi);
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:53:00 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed,  7 Feb 2024 15:53:00 +0100
Subject: [PATCH v5 2/9] drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
In-Reply-To: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240207145307.1626009-3-angelogioacchino.delregno@collabora.com>

The register bits definitions for RGB666 formats are wrong in multiple
ways: first, in the DSI_PS_SEL bits region, the Packed 18-bits RGB666
format is selected with bit 1, while the Loosely Packed one is bit 2,
and second - the definition name "LOOSELY_PS_18BIT_RGB666" is wrong
because the loosely packed format is 24 bits instead!

Either way, functions mtk_dsi_ps_control_vact() and mtk_dsi_ps_control()
do not even agree on the DSI_PS_SEL bit to set in DSI_PSCTRL: one sets
loosely packed (24) on RGB666, the other sets packed (18), and the other
way around for RGB666_PACKED.

Fixing this entire stack of issues is done in one go:
 - Use the correct bit for the Loosely Packed RGB666 definition
 - Rename LOOSELY_PS_18BIT_RGB666 to LOOSELY_PS_24BIT_RGB666
 - Change ps_bpp_mode in mtk_dsi_ps_control_vact() to set:
    - Loosely Packed, 24-bits for MIPI_DSI_FMT_RGB666
    - Packed, 18-bits for MIPI_DSI_FMT_RGB666_PACKED

Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index c66e18006070..8af0afbe9e3d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -71,8 +71,8 @@
 #define DSI_PS_WC			GENMASK(13, 0)
 #define DSI_PS_SEL			GENMASK(17, 16)
 #define PACKED_PS_16BIT_RGB565		(0 << 16)
-#define LOOSELY_PS_18BIT_RGB666		(1 << 16)
-#define PACKED_PS_18BIT_RGB666		(2 << 16)
+#define PACKED_PS_18BIT_RGB666		(1 << 16)
+#define LOOSELY_PS_24BIT_RGB666		(2 << 16)
 #define PACKED_PS_24BIT_RGB888		(3 << 16)
 
 #define DSI_VSA_NL		0x20
@@ -370,10 +370,10 @@ static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
 		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
+		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-		ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;
+		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB565:
 		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
@@ -427,7 +427,7 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
 		dsi_tmp_buf_bpp = 3;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		tmp_reg = LOOSELY_PS_18BIT_RGB666;
+		tmp_reg = LOOSELY_PS_24BIT_RGB666;
 		dsi_tmp_buf_bpp = 3;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:53:02 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed,  7 Feb 2024 15:53:02 +0100
Subject: [PATCH v5 4/9] drm/mediatek: dsi: Use bitfield macros where useful
In-Reply-To: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240207145307.1626009-5-angelogioacchino.delregno@collabora.com>

Instead of open coding bitshifting for various register fields,
use the bitfield macro FIELD_PREP(): this allows to enhance the
human readability, decrease likeliness of mistakes (and register
field overflowing) and also to simplify the code.
The latter is especially seen in mtk_dsi_rxtx_control(), where
it was possible to change a switch to a short for loop and to
also remove the need to check for maximum DSI lanes == 4 thanks
to the FIELD_PREP macro masking the value.

While at it, also add the missing DA_HS_SYNC bitmask, used in
mtk_dsi_phy_timconfig().

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 97 ++++++++++++++++--------------
 1 file changed, 52 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 7d38e9500700..a330bb94c44a 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2015 MediaTek Inc.
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/iopoll.h>
@@ -70,16 +71,19 @@
 #define DSI_PSCTRL		0x1c
 #define DSI_PS_WC			GENMASK(13, 0)
 #define DSI_PS_SEL			GENMASK(17, 16)
-#define PACKED_PS_16BIT_RGB565		(0 << 16)
-#define PACKED_PS_18BIT_RGB666		(1 << 16)
-#define LOOSELY_PS_24BIT_RGB666		(2 << 16)
-#define PACKED_PS_24BIT_RGB888		(3 << 16)
+#define PACKED_PS_16BIT_RGB565		0
+#define PACKED_PS_18BIT_RGB666		1
+#define LOOSELY_PS_24BIT_RGB666		2
+#define PACKED_PS_24BIT_RGB888		3
 
 #define DSI_VSA_NL		0x20
 #define DSI_VBP_NL		0x24
 #define DSI_VFP_NL		0x28
 #define DSI_VACT_NL		0x2C
+#define VACT_NL				GENMASK(14, 0)
 #define DSI_SIZE_CON		0x38
+#define DSI_HEIGHT				GENMASK(30, 16)
+#define DSI_WIDTH				GENMASK(14, 0)
 #define DSI_HSA_WC		0x50
 #define DSI_HBP_WC		0x54
 #define DSI_HFP_WC		0x58
@@ -122,6 +126,7 @@
 
 #define DSI_PHY_TIMECON2	0x118
 #define CONT_DET			GENMASK(7, 0)
+#define DA_HS_SYNC			GENMASK(15, 8)
 #define CLK_ZERO			GENMASK(23, 16)
 #define CLK_TRAIL			GENMASK(31, 24)
 
@@ -253,14 +258,23 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
 	timing->clk_hs_zero = timing->clk_hs_trail * 4;
 	timing->clk_hs_exit = 2 * timing->clk_hs_trail;
 
-	timcon0 = timing->lpx | timing->da_hs_prepare << 8 |
-		  timing->da_hs_zero << 16 | timing->da_hs_trail << 24;
-	timcon1 = timing->ta_go | timing->ta_sure << 8 |
-		  timing->ta_get << 16 | timing->da_hs_exit << 24;
-	timcon2 = 1 << 8 | timing->clk_hs_zero << 16 |
-		  timing->clk_hs_trail << 24;
-	timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 |
-		  timing->clk_hs_exit << 16;
+	timcon0 = FIELD_PREP(LPX, timing->lpx) |
+		  FIELD_PREP(HS_PREP, timing->da_hs_prepare) |
+		  FIELD_PREP(HS_ZERO, timing->da_hs_zero) |
+		  FIELD_PREP(HS_TRAIL, timing->da_hs_trail);
+
+	timcon1 = FIELD_PREP(TA_GO, timing->ta_go) |
+		  FIELD_PREP(TA_SURE, timing->ta_sure) |
+		  FIELD_PREP(TA_GET, timing->ta_get) |
+		  FIELD_PREP(DA_HS_EXIT, timing->da_hs_exit);
+
+	timcon2 = FIELD_PREP(DA_HS_SYNC, 1) |
+		  FIELD_PREP(CLK_ZERO, timing->clk_hs_zero) |
+		  FIELD_PREP(CLK_TRAIL, timing->clk_hs_trail);
+
+	timcon3 = FIELD_PREP(CLK_HS_PREP, timing->clk_hs_prepare) |
+		  FIELD_PREP(CLK_HS_POST, timing->clk_hs_post) |
+		  FIELD_PREP(CLK_HS_EXIT, timing->clk_hs_exit);
 
 	writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
 	writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
@@ -353,69 +367,61 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
 
 static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 {
-	u32 tmp_reg;
+	u32 regval, tmp_reg = 0;
+	u8 i;
 
-	switch (dsi->lanes) {
-	case 1:
-		tmp_reg = 1 << 2;
-		break;
-	case 2:
-		tmp_reg = 3 << 2;
-		break;
-	case 3:
-		tmp_reg = 7 << 2;
-		break;
-	case 4:
-		tmp_reg = 0xf << 2;
-		break;
-	default:
-		tmp_reg = 0xf << 2;
-		break;
-	}
+	/* Number of DSI lanes (max 4 lanes), each bit enables one DSI lane. */
+	for (i = 0; i < dsi->lanes; i++)
+		tmp_reg |= BIT(i);
+
+	regval = FIELD_PREP(LANE_NUM, tmp_reg);
 
 	if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
-		tmp_reg |= HSTX_CKLP_EN;
+		regval |= HSTX_CKLP_EN;
 
 	if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
-		tmp_reg |= DIS_EOT;
+		regval |= DIS_EOT;
 
-	writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
+	writel(regval, dsi->regs + DSI_TXRX_CTRL);
 }
 
 static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
 {
-	struct videomode *vm = &dsi->vm;
-	u32 dsi_buf_bpp, ps_wc;
-	u32 ps_bpp_mode;
+	u32 dsi_buf_bpp, ps_val, ps_wc, vact_nl;
 
 	if (dsi->format == MIPI_DSI_FMT_RGB565)
 		dsi_buf_bpp = 2;
 	else
 		dsi_buf_bpp = 3;
 
-	ps_wc = vm->hactive * dsi_buf_bpp;
-	ps_bpp_mode = ps_wc;
+	/* Word count */
+	ps_wc = FIELD_PREP(DSI_PS_WC, dsi->vm.hactive * dsi_buf_bpp);
+	ps_val = ps_wc;
 
+	/* Pixel Stream type */
 	switch (dsi->format) {
+	default:
+		fallthrough;
 	case MIPI_DSI_FMT_RGB888:
-		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_24BIT_RGB888);
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, LOOSELY_PS_24BIT_RGB666);
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_18BIT_RGB666);
 		break;
 	case MIPI_DSI_FMT_RGB565:
-		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_16BIT_RGB565);
 		break;
 	}
 
 	if (config_vact) {
-		writel(vm->vactive, dsi->regs + DSI_VACT_NL);
+		vact_nl = FIELD_PREP(VACT_NL, dsi->vm.vactive);
+		writel(vact_nl, dsi->regs + DSI_VACT_NL);
 		writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
 	}
-	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
+	writel(ps_val, dsi->regs + DSI_PSCTRL);
 }
 
 static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
@@ -442,7 +448,8 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
 
 	if (dsi->driver_data->has_size_ctl)
-		writel(vm->vactive << 16 | vm->hactive,
+		writel(FIELD_PREP(DSI_HEIGHT, vm->vactive) |
+		       FIELD_PREP(DSI_WIDTH, vm->hactive),
 		       dsi->regs + DSI_SIZE_CON);
 
 	horizontal_sync_active_byte = (vm->hsync_len * dsi_tmp_buf_bpp - 10);
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:53:03 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed,  7 Feb 2024 15:53:03 +0100
Subject: [PATCH v5 5/9] drm/mediatek: dsi: Replace open-coded instance of HZ_PER_MHZ
In-Reply-To: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240207145307.1626009-6-angelogioacchino.delregno@collabora.com>

In mtk_dsi_phy_timconfig(), we're dividing the `data_rate` variable,
expressed in Hz to retrieve a value in MHz: instead of open-coding,
use the HZ_PER_MHZ definition, available in linux/units.h.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index a330bb94c44a..52758cab0abf 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -13,6 +13,7 @@
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
+#include <linux/units.h>
 
 #include <video/mipi_display.h>
 #include <video/videomode.h>
@@ -238,7 +239,7 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, u32 mask, u32 data)
 static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
 {
 	u32 timcon0, timcon1, timcon2, timcon3;
-	u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, 1000000);
+	u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, HZ_PER_MHZ);
 	struct mtk_phy_timing *timing = &dsi->phy_timing;
 
 	timing->lpx = (60 * data_rate_mhz / (8 * 1000)) + 1;
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:53:05 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed,  7 Feb 2024 15:53:05 +0100
Subject: [PATCH v5 7/9] drm/mediatek: dsi: Simplify with dev_err_probe and remove gotos
In-Reply-To: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240207145307.1626009-8-angelogioacchino.delregno@collabora.com>

Most of the functions that are called in the probe callback are
devm managed, or all but mipi_dsi_host_register(): simplify the probe
function's error paths with dev_err_probe() and remove the lonely
instance of `goto err_unregister_host` by just directly calling the
mipi_dsi_host_unregister() function in the devm_request_irq() error
path, allowing to also remove the same label.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 60 +++++++++---------------------
 1 file changed, 18 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index b3dd6251d611..195ff4dfc3a3 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1117,64 +1117,44 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
-	if (IS_ERR(dsi->engine_clk)) {
-		ret = PTR_ERR(dsi->engine_clk);
+	if (IS_ERR(dsi->engine_clk))
+		return dev_err_probe(dev, PTR_ERR(dsi->engine_clk),
+				     "Failed to get engine clock\n");
 
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get engine clock: %d\n", ret);
-		return ret;
-	}
 
 	dsi->digital_clk = devm_clk_get(dev, "digital");
-	if (IS_ERR(dsi->digital_clk)) {
-		ret = PTR_ERR(dsi->digital_clk);
-
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get digital clock: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->digital_clk))
+		return dev_err_probe(dev, PTR_ERR(dsi->digital_clk),
+				     "Failed to get digital clock\n");
 
 	dsi->hs_clk = devm_clk_get(dev, "hs");
-	if (IS_ERR(dsi->hs_clk)) {
-		ret = PTR_ERR(dsi->hs_clk);
-		dev_err(dev, "Failed to get hs clock: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->hs_clk))
+		return dev_err_probe(dev, PTR_ERR(dsi->hs_clk), "Failed to get hs clock\n");
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dsi->regs = devm_ioremap_resource(dev, regs);
-	if (IS_ERR(dsi->regs)) {
-		ret = PTR_ERR(dsi->regs);
-		dev_err(dev, "Failed to ioremap memory: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->regs))
+		return dev_err_probe(dev, PTR_ERR(dsi->regs), "Failed to ioremap memory\n");
 
 	dsi->phy = devm_phy_get(dev, "dphy");
-	if (IS_ERR(dsi->phy)) {
-		ret = PTR_ERR(dsi->phy);
-		dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->phy))
+		return dev_err_probe(dev, PTR_ERR(dsi->phy), "Failed to get MIPI-DPHY\n");
 
 	irq_num = platform_get_irq(pdev, 0);
-	if (irq_num < 0) {
-		ret = irq_num;
-		return ret;
-	}
+	if (irq_num < 0)
+		return irq_num;
 
 	dsi->host.ops = &mtk_dsi_ops;
 	dsi->host.dev = dev;
 	ret = mipi_dsi_host_register(&dsi->host);
-	if (ret < 0) {
-		dev_err(dev, "failed to register DSI host: %d\n", ret);
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to register DSI host\n");
 
 	ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq,
 			       IRQF_TRIGGER_NONE, dev_name(&pdev->dev), dsi);
 	if (ret) {
-		dev_err(&pdev->dev, "failed to request mediatek dsi irq\n");
-		goto err_unregister_host;
+		mipi_dsi_host_unregister(&dsi->host);
+		return dev_err_probe(&pdev->dev, ret, "Failed to request DSI irq\n");
 	}
 
 	init_waitqueue_head(&dsi->irq_wait_queue);
@@ -1186,10 +1166,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
 	return 0;
-
-err_unregister_host:
-	mipi_dsi_host_unregister(&dsi->host);
-	return ret;
 }
 
 static void mtk_dsi_remove(struct platform_device *pdev)
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:53:04 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed,  7 Feb 2024 15:53:04 +0100
Subject: [PATCH v5 6/9] drm/mediatek: dsi: Register DSI host after acquiring clocks and PHY
In-Reply-To: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240207145307.1626009-7-angelogioacchino.delregno@collabora.com>

Registering the dsi host with its ops before getting dsi->regs is
simply wrong: even though there's nothing (for now) asynchronously
calling those ops before the end of the probe function, installing
ops that are using iospace(s) and clocks before even initializing
those is too fragile.

Register the DSI host after getting clocks, iospace and PHY.
This wil also allow to simplify the error paths in a later commit.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 52758cab0abf..b3dd6251d611 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1114,14 +1114,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	if (!dsi)
 		return -ENOMEM;
 
-	dsi->host.ops = &mtk_dsi_ops;
-	dsi->host.dev = dev;
-	ret = mipi_dsi_host_register(&dsi->host);
-	if (ret < 0) {
-		dev_err(dev, "failed to register DSI host: %d\n", ret);
-		return ret;
-	}
-
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
@@ -1130,7 +1122,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 
 		if (ret != -EPROBE_DEFER)
 			dev_err(dev, "Failed to get engine clock: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	dsi->digital_clk = devm_clk_get(dev, "digital");
@@ -1139,14 +1131,14 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 
 		if (ret != -EPROBE_DEFER)
 			dev_err(dev, "Failed to get digital clock: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	dsi->hs_clk = devm_clk_get(dev, "hs");
 	if (IS_ERR(dsi->hs_clk)) {
 		ret = PTR_ERR(dsi->hs_clk);
 		dev_err(dev, "Failed to get hs clock: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1154,20 +1146,28 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	if (IS_ERR(dsi->regs)) {
 		ret = PTR_ERR(dsi->regs);
 		dev_err(dev, "Failed to ioremap memory: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	dsi->phy = devm_phy_get(dev, "dphy");
 	if (IS_ERR(dsi->phy)) {
 		ret = PTR_ERR(dsi->phy);
 		dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	irq_num = platform_get_irq(pdev, 0);
 	if (irq_num < 0) {
 		ret = irq_num;
-		goto err_unregister_host;
+		return ret;
+	}
+
+	dsi->host.ops = &mtk_dsi_ops;
+	dsi->host.dev = dev;
+	ret = mipi_dsi_host_register(&dsi->host);
+	if (ret < 0) {
+		dev_err(dev, "failed to register DSI host: %d\n", ret);
+		return ret;
 	}
 
 	ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq,
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:53:06 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed,  7 Feb 2024 15:53:06 +0100
Subject: [PATCH v5 8/9] drm/mediatek: dsi: Compress of_device_id entries and add sentinel
In-Reply-To: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240207145307.1626009-9-angelogioacchino.delregno@collabora.com>

All entries fit in 82 columns, which is acceptable: compress all of
the mtk_dsi_of_match[] entries to a single line for each.

While at it, also add the usual sentinel comment to the last entry.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 195ff4dfc3a3..b644505de98a 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1204,17 +1204,12 @@ static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = {
 };
 
 static const struct of_device_id mtk_dsi_of_match[] = {
-	{ .compatible = "mediatek,mt2701-dsi",
-	  .data = &mt2701_dsi_driver_data },
-	{ .compatible = "mediatek,mt8173-dsi",
-	  .data = &mt8173_dsi_driver_data },
-	{ .compatible = "mediatek,mt8183-dsi",
-	  .data = &mt8183_dsi_driver_data },
-	{ .compatible = "mediatek,mt8186-dsi",
-	  .data = &mt8186_dsi_driver_data },
-	{ .compatible = "mediatek,mt8188-dsi",
-	  .data = &mt8188_dsi_driver_data },
-	{ },
+	{ .compatible = "mediatek,mt2701-dsi", .data = &mt2701_dsi_driver_data },
+	{ .compatible = "mediatek,mt8173-dsi", .data = &mt8173_dsi_driver_data },
+	{ .compatible = "mediatek,mt8183-dsi", .data = &mt8183_dsi_driver_data },
+	{ .compatible = "mediatek,mt8186-dsi", .data = &mt8186_dsi_driver_data },
+	{ .compatible = "mediatek,mt8188-dsi", .data = &mt8188_dsi_driver_data },
+	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mtk_dsi_of_match);
 
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Wed Feb  7 06:53:07 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed,  7 Feb 2024 15:53:07 +0100
Subject: [PATCH v5 9/9] drm/mediatek: dsi: Use mipi_dsi_pixel_format_to_bpp() helper function
In-Reply-To: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240207145307.1626009-10-angelogioacchino.delregno@collabora.com>

Instead of open coding, use the mipi_dsi_pixel_format_to_bpp() helper
function from drm_mipi_dsi.h in mtk_dsi_poweron() and for validation
in mtk_dsi_bridge_mode_valid().

Note that this function changes the behavior of this driver: previously,
in case of unknown formats, it would (wrongly) assume that it should
account for a 24-bits format - now it will return an error and refuse
to set clocks and/or enable the DSI.

This is done because setting the wrong data rate will only produce a
garbage output that the display will misinterpret both because this
driver doesn't actually provide any extra-spec format support and/or
because the data rate (hence, the HS clock) will be wrong.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index b644505de98a..9501f4019199 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -598,19 +598,12 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	if (++dsi->refcount != 1)
 		return 0;
 
-	switch (dsi->format) {
-	case MIPI_DSI_FMT_RGB565:
-		bit_per_pixel = 16;
-		break;
-	case MIPI_DSI_FMT_RGB666_PACKED:
-		bit_per_pixel = 18;
-		break;
-	case MIPI_DSI_FMT_RGB666:
-	case MIPI_DSI_FMT_RGB888:
-	default:
-		bit_per_pixel = 24;
-		break;
+	ret = mipi_dsi_pixel_format_to_bpp(dsi->format);
+	if (ret < 0) {
+		dev_err(dev, "Unknown MIPI DSI format %d\n", dsi->format);
+		return ret;
 	}
+	bit_per_pixel = ret;
 
 	dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock * bit_per_pixel,
 					  dsi->lanes);
@@ -793,12 +786,11 @@ mtk_dsi_bridge_mode_valid(struct drm_bridge *bridge,
 			  const struct drm_display_mode *mode)
 {
 	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
-	u32 bpp;
+	int bpp;
 
-	if (dsi->format == MIPI_DSI_FMT_RGB565)
-		bpp = 16;
-	else
-		bpp = 24;
+	bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+	if (bpp < 0)
+		return MODE_ERROR;
 
 	if (mode->clock * bpp / dsi->lanes > 1500000)
 		return MODE_CLOCK_HIGH;
-- 
2.43.0



From colin.i.king at gmail.com  Wed Feb  7 06:53:51 2024
From: colin.i.king at gmail.com (Colin King (gmail))
Date: Wed, 7 Feb 2024 14:53:51 +0000
Subject: [PATCH][next] mt76: Remove redundant assignment to variable tidno
In-Reply-To: <87il30h03n.fsf@kernel.org>
References: <20240207131113.2450297-1-colin.i.king@gmail.com>
 <87il30h03n.fsf@kernel.org>
Message-ID: <13e2f96c-2434-4266-8a5e-25b267d1fb0e@gmail.com>

On 07/02/2024 13:31, Kalle Valo wrote:
> Colin Ian King <colin.i.king at gmail.com> writes:
> 
>> The variable tidno is being assigned a value that is not being read
>> and is being re-assigned a new value a few statements later.
>> The assignment is redundant and can be removed.
>>
>> Cleans up clang scan warning:
>> drivers/net/wireless/mediatek/mt76/agg-rx.c:125:5: warning: Value stored
>> to 'tidno' during its initialization is never read [deadcode.DeadStores]
>>
>> Signed-off-by: Colin Ian King <colin.i.king at gmail.com>
> 
> "wifi:" missing from title.
> 
does this require a V2?


From kvalo at kernel.org  Wed Feb  7 06:56:20 2024
From: kvalo at kernel.org (Kalle Valo)
Date: Wed, 07 Feb 2024 16:56:20 +0200
Subject: [PATCH][next] mt76: Remove redundant assignment to variable tidno
In-Reply-To: <13e2f96c-2434-4266-8a5e-25b267d1fb0e@gmail.com> (Colin King's
	message of "Wed, 7 Feb 2024 14:53:51 +0000")
References: <20240207131113.2450297-1-colin.i.king@gmail.com>
	<87il30h03n.fsf@kernel.org>
	<13e2f96c-2434-4266-8a5e-25b267d1fb0e@gmail.com>
Message-ID: <87wmrgpbl7.fsf@kernel.org>

"Colin King (gmail)" <colin.i.king at gmail.com> writes:

> On 07/02/2024 13:31, Kalle Valo wrote:
>> Colin Ian King <colin.i.king at gmail.com> writes:
>> 
>>> The variable tidno is being assigned a value that is not being read
>>> and is being re-assigned a new value a few statements later.
>>> The assignment is redundant and can be removed.
>>>
>>> Cleans up clang scan warning:
>>> drivers/net/wireless/mediatek/mt76/agg-rx.c:125:5: warning: Value stored
>>> to 'tidno' during its initialization is never read [deadcode.DeadStores]
>>>
>>> Signed-off-by: Colin Ian King <colin.i.king at gmail.com>
>> "wifi:" missing from title.
>> 
> does this require a V2?

Up to Felix, my guess is that he can add it during commit.


-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


From neil.armstrong at linaro.org  Wed Feb  7 06:57:56 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Wed, 7 Feb 2024 15:57:56 +0100
Subject: [PATCH RFC 1/2] spmi: Add support for multi-master
In-Reply-To: <CAA8EJpo5bb+AWJra26MoDPKE_vF+eBAJAGoxenkMtGWz2N5Tuw@mail.gmail.com>
References: <20240207-spmi-multi-master-support-v1-0-ce57f301c7fd@linaro.org>
 <20240207-spmi-multi-master-support-v1-1-ce57f301c7fd@linaro.org>
 <CAA8EJpqsJmv36=o1aTjVH6eMHXMg8BHNpiDvs+Q8YB23ezVGtQ@mail.gmail.com>
 <ZcMvFtAwQQjAZhk6@linaro.org>
 <CAA8EJprqWLX7_yWZzKp3FAKFGkSkk041f9hj1uXuRBrbH5APyQ@mail.gmail.com>
 <ZcNIddeG6VHxBEOQ@linaro.org>
 <CAA8EJpo-16u34Yc6MLmHSqFrQ0VrZAq6TwGeVc5WFwMmhruqoA@mail.gmail.com>
 <b4018932-2fcb-4a15-9ec4-e29e5761d3e0@collabora.com>
 <CAA8EJpo5bb+AWJra26MoDPKE_vF+eBAJAGoxenkMtGWz2N5Tuw@mail.gmail.com>
Message-ID: <cc48bced-7591-4394-a1ad-4e7cd77a7844@linaro.org>

On 07/02/2024 15:22, Dmitry Baryshkov wrote:
> On Wed, 7 Feb 2024 at 14:46, AngeloGioacchino Del Regno
> <angelogioacchino.delregno at collabora.com> wrote:
>>
>> Il 07/02/24 12:45, Dmitry Baryshkov ha scritto:
>>> On Wed, 7 Feb 2024 at 11:08, Abel Vesa <abel.vesa at linaro.org> wrote:
>>>>
>>>> On 24-02-07 09:23:09, Dmitry Baryshkov wrote:
>>>>> On Wed, 7 Feb 2024 at 09:19, Abel Vesa <abel.vesa at linaro.org> wrote:
>>>>>>
>>>>>> On 24-02-07 01:55:39, Dmitry Baryshkov wrote:
>>>>>>> On Wed, 7 Feb 2024 at 01:34, Abel Vesa <abel.vesa at linaro.org> wrote:
>>>>>>>>
>>>>>>>> Some newer SPMI controllers support multiple bus masters.
>>>>>>>> Such a master can control multiple slave devices. The generic
>>>>>>>> framework needs to be able to pass on the master id to the
>>>>>>>> controller-specific driver. So do that. The framework will
>>>>>>>> check if the devicetree child nodes are actually bus masters
>>>>>>>> and will register the devices for each master. The legacy
>>>>>>>> approach will still be supported for backwards compatibility.
>>>>>>>
>>>>>>> Please remind me, are those two actual bus musters driving a single
>>>>>>> bus in parallel or two SPMI buses being handled by a single device? In
>>>>>>> the latter case this implementation is incorrect. There should be
>>>>>>> multiple spmi_controller instances, one for each bus. Allocate them in
>>>>>>> a loop and set ctrl->dev.of_node after allocating.
>>>>>>
>>>>>> It's two SPMI buses (two sets of wires) handled by the same controller,
>>>>>> HW-wise.
>>>>>>
>>>>>> If we register two spmi controllers with the kernel framework, it will
>>>>>> be HW inaccurate, because there is just one controller which has
>>>>>> multiple masters.
>>>>>
>>>>> struct spmi_controller is a controller for a single bus. Inside your
>>>>> device you have two SPMI buses, each can be controlled by its own
>>>>> struct spmi_controller. Just like devices that control multiple I2C,
>>>>> SPI or USB busses register a separate instance of the bus controller.
>>>>
>>>> Well, this is what this patchset is trying to do in the generic part.
>>>> The SPMI controller supports multiple buses (HW-wise) and therefore SW
>>>> implementation shouldn't be tied to single bus requirement.
>>>
>>> So, after the off-line discussion:
>>> - add new compatible string for sm8450+
>>> - register two spmi controller instances
>>
>> Well, I don't know about the actual hardware that you're trying to implement
>> but, in my opinion, the "idea" of this series does actually make sense.
>>
>> The SPMI specification says that SPMI supports up to 4 masters, and up to
>> 16 slaves.
> 
> So, that is my main question: whether this supports multiple masters
> on a same bus or multiple buses. From the SoC pins description I
> assume the latter is the case.

This is clearly 2 separate physically separate busses, not 2 masters on the same bus.

We registers separate controllers for i2c, spi, 1w, ... in this case, why not here ?

Neil

> 
>>
>> Just my two cents.
>>
>> Cheers,
>> Angelo
>>
>>> - drop the master-id from the SPMI interface
>>> - optionally: think about having a new separate driver for v7 SPMI.
>>>
>>>>
>>>>>
>>>>>>
>>>>>> I'm not saying it might not work. But, to me, it looks more like a hack.
>>>>>>
>>>>>> Basically, we would be mapping HW bus masters to kernel controllers.
>>>>>
>>>>> Buses, not just masters.
>>>>>
>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
>>>>>>>> ---
>>>>>>>>    drivers/spmi/spmi-mtk-pmif.c |  6 ++--
>>>>>>>>    drivers/spmi/spmi-pmic-arb.c | 10 +++---
>>>>>>>>    drivers/spmi/spmi.c          | 76 ++++++++++++++++++++++++++++++--------------
>>>>>>>>    include/linux/spmi.h         | 10 +++---
>>>>>>>>    4 files changed, 67 insertions(+), 35 deletions(-)
>>>>>>>
>>>>>>> --
>>>>>>> With best wishes
>>>>>>> Dmitry
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> With best wishes
>>>>> Dmitry
>>>
>>>
>>>
>>
>>
> 
> 



From angelogioacchino.delregno at collabora.com  Wed Feb  7 07:00:52 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 7 Feb 2024 16:00:52 +0100
Subject: [PATCH][next] mt76: Remove redundant assignment to variable tidno
In-Reply-To: <20240207131113.2450297-1-colin.i.king@gmail.com>
References: <20240207131113.2450297-1-colin.i.king@gmail.com>
Message-ID: <2b91bd5e-9e66-402e-87fe-c2894e5a1d5a@collabora.com>

Il 07/02/24 14:11, Colin Ian King ha scritto:
> The variable tidno is being assigned a value that is not being read
> and is being re-assigned a new value a few statements later.
> The assignment is redundant and can be removed.
> 
> Cleans up clang scan warning:
> drivers/net/wireless/mediatek/mt76/agg-rx.c:125:5: warning: Value stored
> to 'tidno' during its initialization is never read [deadcode.DeadStores]
> 
> Signed-off-by: Colin Ian King <colin.i.king at gmail.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/net/wireless/mediatek/mt76/agg-rx.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c b/drivers/net/wireless/mediatek/mt76/agg-rx.c
> index 10cbd9e560e7..07c386c7b4d0 100644
> --- a/drivers/net/wireless/mediatek/mt76/agg-rx.c
> +++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c
> @@ -122,7 +122,7 @@ mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
>   	struct ieee80211_bar *bar = mt76_skb_get_hdr(skb);
>   	struct mt76_wcid *wcid = status->wcid;
>   	struct mt76_rx_tid *tid;
> -	u8 tidno = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
> +	u8 tidno;
>   	u16 seqno;
>   
>   	if (!ieee80211_is_ctl(bar->frame_control))




From krzysztof.kozlowski at linaro.org  Wed Feb  7 07:05:22 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 7 Feb 2024 16:05:22 +0100
Subject: [PATCH 2/4] arm64: dts: exynos: gs101: add chipid node
In-Reply-To: <CADrjBPpNukp+YQ0AmsZAE1f=MEk_auPPZit=tV8gk4szQ8MqRg@mail.gmail.com>
References: <20240201172224.574238-1-alexey.klimov@linaro.org>
 <20240201172224.574238-2-alexey.klimov@linaro.org>
 <CADrjBPpqHx1uoVZCYDX51kW+JdOr_-+4oryOjXcUMFkmLGTBLw@mail.gmail.com>
 <b199ba24-403b-44fa-b807-9b98f9e98913@linaro.org>
 <CADrjBPpNukp+YQ0AmsZAE1f=MEk_auPPZit=tV8gk4szQ8MqRg@mail.gmail.com>
Message-ID: <b7fbbf3e-1e53-46a9-b26c-8acb5f9ccde7@linaro.org>

On 07/02/2024 15:11, Peter Griffin wrote:
> Hi Krzysztof,
> 
> Thanks for your feedback.
> 
> On Tue, 6 Feb 2024 at 10:10, Krzysztof Kozlowski
> <krzysztof.kozlowski at linaro.org> wrote:
>>
>> On 05/02/2024 15:36, Peter Griffin wrote:
>>> Hi Alexey & Krysztof,
>>>
>>> On Thu, 1 Feb 2024 at 17:22, Alexey Klimov <alexey.klimov at linaro.org> wrote:
>>>>
>>>> Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
>>>> ---
>>>>  arch/arm64/boot/dts/exynos/google/gs101.dtsi | 5 +++++
>>>>  1 file changed, 5 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>>>> index d838e3a7af6e..156fec2575bc 100644
>>>> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>>>> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
>>>> @@ -283,6 +283,11 @@ soc: soc at 0 {
>>>>                 #size-cells = <1>;
>>>>                 ranges = <0x0 0x0 0x0 0x40000000>;
>>>>
>>>> +               chipid at 10000000 {
>>>> +                       compatible = "google,gs101-chipid";
>>>> +                       reg = <0x10000000 0xd000>;
>>>> +               };
>>>> +
>>>
>>> I was wondering about the 0xd000 size here, as most upstream platforms
>>> use a chipid size of 0x100 or 0x24. I see the downstream gs101 kernel
>>> also uses 0xd000. Looking a bit more, that is because gs-chipid.c also
>>> has support for dumping other areas of the OTP SFR bank like asv table
>>> (offset 0x9000) hpm_asv (offset 0xa000) and hw_tune (0xc000).
>>>
>>> I checked Exynos850 and that also has ASV tables at those same offsets
>>> above, but it currently uses a chipid size of 0x100 upstream.
>>> Exynos-asv.c driver is part of exynos-chipid.c upstream so it seems
>>> reasonable to have the increased size including those SFR registers.
>>> Currently exynos-asv.c driver only supports Exynos5422 upstream.
>>>
>>> @Krzysztof - From a process PoV what is the best/correct thing to do
>>> here? Have the increased size in DT that includes ASV parts of the OTP
>>> bank from the get-go?
>>
>> ChipID so far had only size of 0x30 or something like that. What you
>> refer to does not look like old ChipID but full blown OTP, which also
>> includes ChipID.
> 
> OK so in some previous Exynos SoCs chipid had its own separate memory
> mapped SFRs as well as being present in the OTP area?

None of the Exynos I know, have OTP area. There was only chipid. It
seems that few newer designs come with OTP, in entirely separate address
space. Exynos850 looks like the first which comes with integrated chipid
into OTP, so OTP is not separate address.

> 
>>  Although I am not entirely sure about that, either.
>> Depends whether they share clocks, for example.
> 
> This address is the OTP area, and I can't see chipid regs mentioned
> anywhere else in the memory map other than OTP. Unfortunately there
> are lots of separate docs for different IP blocks, so it isn't just a
> case of searching a giant SoC TRM pdf.
> 
> e850 though looks to be the same (the address defined in DT is the otp
> area), that is one large PDF and the chipid regs aren't mentioned
> anywhere else, Given the chipid reg offset is the same (0x10000000)
> for exynosautov9.dtsi, exynosautov920.dtsi, exynos850.dtsi, exynos7885
> and exynos5433 I suspect this could be the same for all those SoCs as
> well.
> 
>>
>> I don't have any GS101 information so I don't know what's there. It
>> seems you ask me to give you decision based on guessing... If you have
>> one block, so if there is OTP, which contains ChipID, then define OTP.
> 
> I believe there is one block that contains ChipID, therefore based on
> the above info we should define full OTP size?
> 
>> Not ChipID+OTP.
>>
>> I think Exynos850 DTSI is wrong here. That's OTP block, not ChipID.
> 
> Yes agreed, and quite possibly the other Exynos SoCs as well.

If ChipID and OTP are in the same block (in OTP), then assume they both
might need the same clocks or some other resources. Therefore we should
not model them as two separate device nodes ChipID and OTP. Instead
there should be one device node with entire OTP address space, which
should not use ChipID compatible to avoid confusion.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Wed Feb  7 07:07:09 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 7 Feb 2024 16:07:09 +0100
Subject: [PATCH v2 1/2] dt-bindings: phy: mediatek,mt7988-xfi-tphy: add
 new bindings
In-Reply-To: <ZcJQyaTotW_bCWGU@makrotopia.org>
References: <3251ac3db1a739e0c18ded0a824edae981c1e2df.1707153425.git.daniel@makrotopia.org>
 <31d2c56a-5108-4265-a267-6733e1ba328e@linaro.org>
 <ZcJQyaTotW_bCWGU@makrotopia.org>
Message-ID: <f0921985-db06-4a66-aa85-69337665d2a9@linaro.org>

On 06/02/2024 16:31, Daniel Golle wrote:
> Hi Krzysztof,
> 
> On Tue, Feb 06, 2024 at 11:53:55AM +0100, Krzysztof Kozlowski wrote:
>> On 05/02/2024 18:28, Daniel Golle wrote:
>>> Add bindings for the MediaTek XFI Ethernet SerDes T-PHY found in the
>>> MediaTek MT7988 SoC which can operate at various interfaces modes:
>>>
>>> via USXGMII PCS:
>>>  * USXGMII
>>>  * 10GBase-R
>>>  * 5GBase-R
>>>
>>> via LynxI SGMII PCS:
>>>  * 2500Base-X
>>>  * 1000Base-X
>>>  * Cisco SGMII (MAC side)
>>>
>>> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
>>> ---
>>> v2: unify filename and compatible as requested
>>
>> Several comments, from me and Rob, were ignored. Please respond to them.
> 
> I'm sorry if I have missed something. I just checked again on
> patchwork, just in case I would have missed an email reply to this or
> any of the preceding posts of this patch as part of the old series
> going to netdev.
> 
> Comments you have made which I have addressed:
>  - removed $nodename
>  - use compatible as filename
> 
> And the only thing I found that I didn't either fix or reply to is this:
>> Can you explain what is this issue and errata about (except performance)?
> 
> Not overwriting that (undocumented) value in that (undocumented)
> register results in 10GBase-R having performance issues according to a
> commit in MediaTek's SDK, see here:
> 
> https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/a500d94cd%5E%21/#F0
> 
> Maybe Bc or SkyLake of MediaTek (added to Cc) can explain this in more
> detail?
> 
> 
> What I did miss was Rob's comment at the very bottom of this reply:
>> What is PEXTP?
> 
> I can again only answer by referencing to MediaTek's SDK sources:
> 
> https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c#96
> 
> Here this reset is called XFI_PEXTP0_GRST.
> 
> I personally find that name confusing (as this PHY has nothing to do with
> _P_ci _EX_press) and have tried to get rid of it where it isn't either part
> of official documentation or already merged drivers (like Sam's clock driver).
> 
> If there have been any other issues with this patch which I'm not aware
> of, please point them out to me.

These both cases should be explained in the binding somehow.

Best regards,
Krzysztof



From broonie at kernel.org  Wed Feb  7 07:07:38 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 7 Feb 2024 15:07:38 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <ZcOK7oIe2f/BFlDj@e133380.arm.com>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
 <ZcEW3y0IlEctOYBA@e133380.arm.com>
 <ZcEd2zU/JpeIwn5f@finisterre.sirena.org.uk>
 <ZcN2XMkvqxNnsz5K@e133380.arm.com>
 <ZcOBH7ip/KMhLYGO@finisterre.sirena.org.uk>
 <ZcOK7oIe2f/BFlDj@e133380.arm.com>
Message-ID: <ZcOcumjBZSYvWya1@finisterre.sirena.org.uk>

On Wed, Feb 07, 2024 at 01:51:42PM +0000, Dave Martin wrote:
> On Wed, Feb 07, 2024 at 01:09:51PM +0000, Mark Brown wrote:

> > I think if we fix the ptrace regset issue we're doing a good enough job
> > of just using fully dynamic sizing with no limits other than what's been
> > enumerated there.  We could possibly deal with the enumberation code by
> > changing it to use ZCR/SMCR_ELx_LEN_ based defines so that it's
> > obviously coming from what we can possibly write to the register but
> > it's a bit less clear how to do that neatly.

> OK, but we still seem to have two competing approaches: clamp SVE_VQ_MAX
> for kernel internal purposes, or restore the dynamic sizing of
> NT_ARM_SVE based on the new regset core behaviour.

> Are you saying we should or both, or otherwise which one?

I'd like to remove uses of SVE_VQ_MAX, to the extent possible by making
things dynamic but if not by not using it I would like to not use
SVE_VQ_MAX partly due to the considerations you mentioned about people
picking up from looking at the kernel source that it's a good idea.
-------------- 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/20240207/61791675/attachment-0001.sig>

From broonie at kernel.org  Wed Feb  7 07:10:28 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 7 Feb 2024 15:10:28 +0000
Subject: [PATCH] arm64/sve: Document that __SVE_VQ_MAX is much larger
 than needed
In-Reply-To: <ZcOIAck16ZyUi/yj@e133380.arm.com>
References: <20240206-arm64-sve-vl-max-comment-v1-1-dddf16414412@kernel.org>
 <ZcNxJ56+bvcUTGlT@e133380.arm.com>
 <ZcN8OltRDUlDlTHQ@finisterre.sirena.org.uk>
 <ZcOIAck16ZyUi/yj@e133380.arm.com>
Message-ID: <ZcOdZNEDXy14OGGI@finisterre.sirena.org.uk>

On Wed, Feb 07, 2024 at 01:39:13PM +0000, Dave Martin wrote:

> How about something along the lines of:

> /*
>  * Yes, this is 512 QUADWORDS.
>  * To help ensure forward portability, this is much larger than the
>  * current maximum value defined by the SVE architecture.
>  * While arrays or static allocations can be sized based on this value,
>  * watch out!  It will waste a surprisingly large amount of memory.
>  * Dynamic sizing based on the actual runtime vector length is likely to
>  * be preferable for most purposes.
>  */

That works for me.  The cost of initialising can also add up in
emulation.
-------------- 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/20240207/bcb0ab84/attachment.sig>

From krzysztof.kozlowski at linaro.org  Wed Feb  7 07:11:31 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 7 Feb 2024 16:11:31 +0100
Subject: [PATCH] ASoC: dt-bindings: atmel,asoc-wm8904: Convert to
 json-schema
In-Reply-To: <20240207094144.195397-1-dharma.b@microchip.com>
References: <20240207094144.195397-1-dharma.b@microchip.com>
Message-ID: <cd2c5ad8-902c-4ea3-8bb1-7f71f130bcc9@linaro.org>

On 07/02/2024 10:41, Dharma Balasubiramani wrote:
> Convert atmel,asoc-wm8904 devicetree binding to json-schema.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Wed Feb  7 07:15:21 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 7 Feb 2024 16:15:21 +0100
Subject: [PATCH] dt-bindings: input: atmel,captouch: convert bindings to
 YAML
In-Reply-To: <20240207090853.188400-1-dharma.b@microchip.com>
References: <20240207090853.188400-1-dharma.b@microchip.com>
Message-ID: <982e81db-3bf9-49e9-b57f-a91612d62f5c@linaro.org>

On 07/02/2024 10:08, Dharma Balasubiramani wrote:
> Convert the Atmel capacitive touchscreen bindings to YAML format.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.co

Thank you for your patch. There is something to discuss/improve.

> +
> +properties:
> +  compatible:
> +    const: atmel,captouch
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  linux,keycodes:
> +    minItems: 1
> +    maxItems: 8
> +
> +  autorepeat:
> +    type: boolean

You can drop entire property, coming from input.yaml.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - linux,keycodes
> +
> +additionalProperties: false

Instead:
unevaluatedProperties: false

> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/input/linux-event-codes.h>
> +    i2c {
> +      #address-cells = <1>;
> +      #size-cells = <0>;
> +      atmel-captouch at 51 {

Instead:
touchscreen? touchpad? if none of these, then just "touch at 51"

> +        compatible = "atmel,captouch";
> +        reg = <0x51>;


Best regards,
Krzysztof



From broonie at kernel.org  Wed Feb  7 07:21:16 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 07 Feb 2024 15:21:16 +0000
Subject: [PATCH] spi: drop gpf arg from __spi_split_transfer_maxsize()
In-Reply-To: <20240206200648.1782234-1-dlechner@baylibre.com>
References: <20240206200648.1782234-1-dlechner@baylibre.com>
Message-ID: <170731927648.1061486.14426168465610494014.b4-ty@kernel.org>

On Tue, 06 Feb 2024 14:06:46 -0600, David Lechner wrote:
> The __spi_split_transfer_maxsize() function has a gpf argument to allow
> callers to specify the type of memory allocation that needs to be used.
> However, this function only allocates struct spi_transfer and is not
> intended to be used from atomic contexts so this type should always be
> GFP_KERNEL, so we can just drop the argument.
> 
> Some callers of these functions also passed GFP_DMA, but since only
> struct spi_transfer is allocated and not any tx/rx buffers, this is
> not actually necessary and is removed in this commit.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: drop gpf arg from __spi_split_transfer_maxsize()
      commit: c0c0293cf7a0f21ef461956d44e4add718574f3f

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 krzysztof.kozlowski at linaro.org  Wed Feb  7 07:23:18 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 7 Feb 2024 16:23:18 +0100
Subject: [PATCH v3 0/7] gs101 oriole: peripheral block 1 (peric1) and
 i2c12 support
In-Reply-To: <20240201161258.1013664-1-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
Message-ID: <6feff535-d9d7-4f4c-8e7c-956c4bba1713@linaro.org>

On 01/02/2024 17:11, Andr? Draszik wrote:
> Hi,
> 
> This patch series implements support for the 2nd connectivity
> peripheral block on gs101.
> This block contains an additional 6 USI, 1 I3C and 1 PWM
> interfaces/busses.
> 
> i2cdetect shows all expected devices on the one i2c bus that this patch
> series enables.
> Everything that's in scope in this series works also without the
> clk_ignore_unused kernel command line argument.
> 
> While working on this, I noticed the existing peric0 support for gs101
> has a couple issues. That explains why there are differences compared
> to it and a separate patch series has been sent to fix up peric0
> support.
> 
> Cheers,
> Andre'
> 
> Changes in v3:
> - drop samsung,mode = <USI_V2_NONE> default assignment in patch #6

I am confused. I have "another" v3 with different changelog.

Best regards,
Krzysztof



From andre.draszik at linaro.org  Wed Feb  7 07:28:50 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Wed, 07 Feb 2024 15:28:50 +0000
Subject: [PATCH v3 0/7] gs101 oriole: peripheral block 1 (peric1) and
 i2c12 support
In-Reply-To: <6feff535-d9d7-4f4c-8e7c-956c4bba1713@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
	 <6feff535-d9d7-4f4c-8e7c-956c4bba1713@linaro.org>
Message-ID: <5f7e36040a769d92e0cc382c393293bfc8f46d5b.camel@linaro.org>

Hi Krzysztof,

On Wed, 2024-02-07 at 16:23 +0100, Krzysztof Kozlowski wrote:
> > Changes in v3:
> > - drop samsung,mode = <USI_V2_NONE> default assignment in patch #6
> 
> I am confused. I have "another" v3 with different changelog.

You're right and I forgot to take a note of the other one when I did :-(

Should I send these again, with the reroll count updated to v4?

Cheers,
Andre'



From krzysztof.kozlowski at linaro.org  Wed Feb  7 07:30:11 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 7 Feb 2024 16:30:11 +0100
Subject: [PATCH v3 2/7] dt-bindings: clock: google,gs101-clock: add PERIC1
 clock management unit
In-Reply-To: <20240201161258.1013664-3-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
 <20240201161258.1013664-3-andre.draszik@linaro.org>
Message-ID: <23963f63-7410-46be-8bac-c6862fedfbef@linaro.org>

On 01/02/2024 17:11, Andr? Draszik wrote:
> Add dt-schema documentation and clock IDs for the Connectivity
> Peripheral 1 (PERIC1) clock management unit.
> 
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> Reviewed-by: Peter Griffin <peter.griffin at linaro.org>
> Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> Reviewed-by: Rob Herring <robh at kernel.org>
> 

I was waiting a bit to be sure these are the last bindings you send for
this cycle. I assume that's the case, so I will go ahead with this one.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Wed Feb  7 07:38:13 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed,  7 Feb 2024 16:38:13 +0100
Subject: (subset) [PATCH v3 1/7] clk: samsung: gs-101: drop extra empty line
In-Reply-To: <20240201161258.1013664-2-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org> <20240201161258.1013664-2-andre.draszik@linaro.org>
Message-ID: <170732026216.120770.3894842773933291237.b4-ty@linaro.org>


On Thu, 01 Feb 2024 16:11:37 +0000, Andr? Draszik wrote:
> There is an extra empty line here which doesn't exist in any of the
> other cmu code blocks in this file.
> 
> Drop it to align cmu_top with the rest of the file.
> 
> 

Applied, thanks!

[1/7] clk: samsung: gs-101: drop extra empty line
      https://git.kernel.org/krzk/linux/c/d16f237bda057b7432f8e42f86d23da2cf088a2e

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>


From krzysztof.kozlowski at linaro.org  Wed Feb  7 07:38:14 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed,  7 Feb 2024 16:38:14 +0100
Subject: (subset) [PATCH v3 2/7] dt-bindings: clock: google,gs101-clock: add PERIC1 clock management unit
In-Reply-To: <20240201161258.1013664-3-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org> <20240201161258.1013664-3-andre.draszik@linaro.org>
Message-ID: <170732026217.120770.4845846715003793085.b4-ty@linaro.org>


On Thu, 01 Feb 2024 16:11:38 +0000, Andr? Draszik wrote:
> Add dt-schema documentation and clock IDs for the Connectivity
> Peripheral 1 (PERIC1) clock management unit.
> 
> 

Applied, thanks!

[2/7] dt-bindings: clock: google,gs101-clock: add PERIC1 clock management unit
      https://git.kernel.org/krzk/linux/c/455061eb32434d5db11836a4de72ea2f4bdf61c8

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>


From krzysztof.kozlowski at linaro.org  Wed Feb  7 07:38:16 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed,  7 Feb 2024 16:38:16 +0100
Subject: (subset) [PATCH v3 4/7] dt-bindings: samsung: exynos-sysreg: gs101-peric1 requires a clock
In-Reply-To: <20240201161258.1013664-5-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org> <20240201161258.1013664-5-andre.draszik@linaro.org>
Message-ID: <170732026219.120770.13575234760770994560.b4-ty@linaro.org>


On Thu, 01 Feb 2024 16:11:40 +0000, Andr? Draszik wrote:
> Otherwise it won't be accessible.
> 
> 

Applied, thanks!

[4/7] dt-bindings: samsung: exynos-sysreg: gs101-peric1 requires a clock
      (no commit info)

Squashed.

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>


From krzysztof.kozlowski at linaro.org  Wed Feb  7 07:38:15 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed,  7 Feb 2024 16:38:15 +0100
Subject: (subset) [PATCH v3 3/7] clk: samsung: gs101: add support for cmu_peric1
In-Reply-To: <20240201161258.1013664-4-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org> <20240201161258.1013664-4-andre.draszik@linaro.org>
Message-ID: <170732026218.120770.1198714836508934799.b4-ty@linaro.org>


On Thu, 01 Feb 2024 16:11:39 +0000, Andr? Draszik wrote:
> CMU_PERIC1 is the clock management unit used for the peric1 block which
> is used for additional USI, I3C and PWM interfaces/busses. Add support
> for muxes, dividers and gates of cmu_peric1, except for
> CLK_GOUT_PERIC1_IP which isn't well described in the datasheet and
> which downstream also ignores (similar to cmu_peric0).
> 
> Two clocks have been marked as CLK_IS_CRITICAL for the following
> reason:
>     * disabling them makes it impossible to access any peric1
>       registers, (including those two registers).
>     * disabling gout_peric1_lhm_axi_p_peric1_i_clk sometimes has the
>       additional effect of making the whole system unresponsive.
> 
> [...]

Applied, thanks!

[3/7] clk: samsung: gs101: add support for cmu_peric1
      https://git.kernel.org/krzk/linux/c/2999e786d7e9596a0057d70098e339d59d7e72f9

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>


From krzysztof.kozlowski at linaro.org  Wed Feb  7 07:38:17 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed,  7 Feb 2024 16:38:17 +0100
Subject: [PATCH v2] ARM: dts: samsung: exynos5420-galaxy-tab-common: add wifi node
In-Reply-To: <20240206-galaxy-tab-s-cleanup-v2-1-89025c6c66c5@grimler.se>
References: <20240206-galaxy-tab-s-cleanup-v2-1-89025c6c66c5@grimler.se>
Message-ID: <170732026212.120770.6589907576886281410.b4-ty@linaro.org>


On Tue, 06 Feb 2024 17:02:27 +0100, Henrik Grimler wrote:
> By using brcm/brcmfmac4354-sdio.bin from linux-firmware together with
> nvram.txt from vendor firmware wifi works well on the chagall-wifi and
> klimt-lte.
> 
> 

Applied, thanks!

[1/1] ARM: dts: samsung: exynos5420-galaxy-tab-common: add wifi node
      https://git.kernel.org/krzk/linux/c/60f1164e21cc04666d23b63e1153af74e7a5650d

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>


From semen.protsenko at linaro.org  Wed Feb  7 07:42:20 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 7 Feb 2024 09:42:20 -0600
Subject: [PATCH 1/4] spi: s3c64xx: explicitly include <linux/types.h>
In-Reply-To: <16a5e423-1111-49ff-ad6c-b0bb89a4879a@linaro.org>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
 <20240206085238.1208256-2-tudor.ambarus@linaro.org> <CAPLW+4=Xd+B=ZncqPgU4qaJ8zY8JJvJZApdUW_v0w6yr2cy9Sg@mail.gmail.com>
 <16a5e423-1111-49ff-ad6c-b0bb89a4879a@linaro.org>
Message-ID: <CAPLW+4n_1yBOuzW3Ke2DKh_0EBZMUrd3nyGd=U0TeOML_2dXuw@mail.gmail.com>

On Wed, Feb 7, 2024 at 12:21?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
>
>
> On 2/6/24 18:02, Sam Protsenko wrote:
> > On Tue, Feb 6, 2024 at 2:52?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
> >>
> >> The driver uses u32 and relies on an implicit inclusion of
> >> <linux/types.h>.
> >>
> >> It is good practice to directly include all headers used, it avoids
> >> implicit dependencies and spurious breakage if someone rearranges
> >> headers and causes the implicit include to vanish.
> >>
> >> Include the missing header.
> >>
> >> Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver")
> >
> > Not sure if Fixes tag is needed here.
>
> We have already talked about this. If a patch that causes the implicit
> include to vanish is backported to stable, it will reveal the missing
> header here and will result in backporting this patch as well. So, as a
> good practice let's allow this patch to be queued to stable, it will
> avoid possible compilation errors.
>
> I guess Mark has to break the tie again. Or Greg if he cares, I added
> him in To:.
>
> >
> >> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> >> ---
> >>  drivers/spi/spi-s3c64xx.c | 1 +
> >>  1 file changed, 1 insertion(+)
> >>
> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> >> index 72c35dbe53b2..c15ca6a910dc 100644
> >> --- a/drivers/spi/spi-s3c64xx.c
> >> +++ b/drivers/spi/spi-s3c64xx.c
> >> @@ -17,6 +17,7 @@
> >>  #include <linux/platform_device.h>
> >>  #include <linux/pm_runtime.h>
> >>  #include <linux/spi/spi.h>
> >> +#include <linux/types.h>
> >
> > Is this really needed for the further patches in this series?
> >
>
> Yes, because in patch 3/4 I use u8 and u16 and I don't want to use those
> without having the header included. Do you find this wrong?
>

I'd say if this header is really needed for your patch 3/4 to have a
successful build, just merge this patch into the patch 3/4 then.

> >>
> >>  #define MAX_SPI_PORTS          12
> >>  #define S3C64XX_SPI_QUIRK_CS_AUTO      (1 << 1)
> >> --
> >> 2.43.0.594.gd9cf4e227d-goog
> >>


From semen.protsenko at linaro.org  Wed Feb  7 07:44:27 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 7 Feb 2024 09:44:27 -0600
Subject: [PATCH v2 2/4] spi: s3c64xx: prepare for a different flavor of
 iowrite rep
In-Reply-To: <20240207111516.2563218-3-tudor.ambarus@linaro.org>
References: <20240207111516.2563218-1-tudor.ambarus@linaro.org> <20240207111516.2563218-3-tudor.ambarus@linaro.org>
Message-ID: <CAPLW+4nyYxeZcvmrK8FJ4cvpxOs4=mPzBC5JcCPB5yNBNqkVAg@mail.gmail.com>

On Wed, Feb 7, 2024 at 5:15?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
> There are SoCs (gs101) that allow only 32 bit register accesses. As the
> requirement is rare enough, for those SoCs we'll open code in the driver
> some s3c64xx_iowrite{8,16}_32_rep() accessors. Prepare for such addition.
>
> Suggested-by: Sam Protsenko <semen.protsenko at linaro.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---

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

>  drivers/spi/spi-s3c64xx.c | 35 +++++++++++++++++++++--------------
>  1 file changed, 21 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index 7f7eb8f742e4..eb79c6e4f509 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -414,6 +414,26 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
>
>  }
>
> +static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd,
> +                               struct spi_transfer *xfer)
> +{
> +       void __iomem *addr = sdd->regs + S3C64XX_SPI_TX_DATA;
> +       const void *buf = xfer->tx_buf;
> +       unsigned int len = xfer->len;
> +
> +       switch (sdd->cur_bpw) {
> +       case 32:
> +               iowrite32_rep(addr, buf, len / 4);
> +               break;
> +       case 16:
> +               iowrite16_rep(addr, buf, len / 2);
> +               break;
> +       default:
> +               iowrite8_rep(addr, buf, len);
> +               break;
> +       }
> +}
> +
>  static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>                                     struct spi_transfer *xfer, int dma_mode)
>  {
> @@ -447,20 +467,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
>                         modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
>                         ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
>                 } else {
> -                       switch (sdd->cur_bpw) {
> -                       case 32:
> -                               iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
> -                                       xfer->tx_buf, xfer->len / 4);
> -                               break;
> -                       case 16:
> -                               iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
> -                                       xfer->tx_buf, xfer->len / 2);
> -                               break;
> -                       default:
> -                               iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
> -                                       xfer->tx_buf, xfer->len);
> -                               break;
> -                       }
> +                       s3c64xx_iowrite_rep(sdd, xfer);
>                 }
>         }
>
> --
> 2.43.0.687.g38aa6559b0-goog
>


From conor at kernel.org  Wed Feb  7 07:52:19 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 7 Feb 2024 15:52:19 +0000
Subject: [PATCH v3 1/4] dt-bindings: display: bridge: add sam9x75-lvds
 compatible
In-Reply-To: <20240207102802.200220-2-dharma.b@microchip.com>
References: <20240207102802.200220-1-dharma.b@microchip.com>
 <20240207102802.200220-2-dharma.b@microchip.com>
Message-ID: <20240207-raving-chatty-7961fb5c5d43@spud>

$subject: dt-bindings: display: bridge: add sam9x75-lvds compatible

If there's a respin for some reason, please update the subject to match
what the commit is actually doing (adding a whole binding).

Cheers,
Conor.
-------------- 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/20240207/bde3084e/attachment.sig>

From broonie at kernel.org  Wed Feb  7 08:07:24 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 7 Feb 2024 16:07:24 +0000
Subject: [PATCH 1/4] spi: s3c64xx: explicitly include <linux/types.h>
In-Reply-To: <CAPLW+4n_1yBOuzW3Ke2DKh_0EBZMUrd3nyGd=U0TeOML_2dXuw@mail.gmail.com>
References: <20240206085238.1208256-1-tudor.ambarus@linaro.org>
 <20240206085238.1208256-2-tudor.ambarus@linaro.org>
 <CAPLW+4=Xd+B=ZncqPgU4qaJ8zY8JJvJZApdUW_v0w6yr2cy9Sg@mail.gmail.com>
 <16a5e423-1111-49ff-ad6c-b0bb89a4879a@linaro.org>
 <CAPLW+4n_1yBOuzW3Ke2DKh_0EBZMUrd3nyGd=U0TeOML_2dXuw@mail.gmail.com>
Message-ID: <ZcOqvEPJIff69L8H@finisterre.sirena.org.uk>

On Wed, Feb 07, 2024 at 09:42:20AM -0600, Sam Protsenko wrote:
> On Wed, Feb 7, 2024 at 12:21?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:

> > Yes, because in patch 3/4 I use u8 and u16 and I don't want to use those
> > without having the header included. Do you find this wrong?

> I'd say if this header is really needed for your patch 3/4 to have a
> successful build, just merge this patch into the patch 3/4 then.

The series was already resent, not worth a new version just for this...
-------------- 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/20240207/25d756af/attachment.sig>

From eichest at gmail.com  Wed Feb  7 08:15:48 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Wed, 7 Feb 2024 17:15:48 +0100
Subject: [PATCH 3/3] arm64: dts: armada-ap807: update thermal compatible
In-Reply-To: <E1qA7yZ-00Ea50-OC@rmk-PC.armlinux.org.uk>
References: <ZIxMYXDCTB7IvsDk@shell.armlinux.org.uk>
 <E1qA7yZ-00Ea50-OC@rmk-PC.armlinux.org.uk>
Message-ID: <ZcOsjRzE8V73wNtT@eichest-laptop>

Hi Russell and Alex,

On Fri, Jun 16, 2023 at 12:50:47PM +0100, Russell King wrote:
> From: Alex Leibovich <alexl at marvell.com>
> 
> Use the correct thermal coefficients for the Armada AP807 dies.
> 
> Signed-off-by: Alex Leibovich <alexl at marvell.com>
> Reviewed-by: Stefan Chulski <stefanc at marvell.com>
> Tested-by: Stefan Chulski <stefanc at marvell.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
>  arch/arm64/boot/dts/marvell/armada-ap807.dtsi | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
> index 4a23f65d475f..a3328d05fc94 100644
> --- a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
> +++ b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
> @@ -33,3 +33,6 @@ &ap_sdhci0 {
>  		     "marvell,armada-ap806-sdhci"; /* Backward compatibility */
>  };
>  
> +&ap_thermal {
> +	compatible = "marvell,armada-ap807-thermal";
> +};

While working on some thermal optimizations, our hardware team
discovered that this patch is still missing upstream. Is something
missing or did it get lost?

Regards,
Stefan


From conor at kernel.org  Wed Feb  7 08:22:37 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 7 Feb 2024 16:22:37 +0000
Subject: [PATCH v4 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <0c784113-9288-46bd-a34e-49bf0f1651bb@solid-run.com>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
 <20240202-add-am64-som-v4-2-5f8b12af5e71@solid-run.com>
 <20240203-prolonged-backfield-c659e0016d70@spud>
 <20240203-tummy-egomaniac-5aba55889a83@spud>
 <0c784113-9288-46bd-a34e-49bf0f1651bb@solid-run.com>
Message-ID: <20240207-astride-banister-371ce4d36edf@spud>

On Tue, Feb 06, 2024 at 02:44:24PM +0000, Josua Mayer wrote:

> > Ahh I now realise what your intent was here. All you need to do is add
> > | interrupts:
> > |   maxItems: 1
> > to your binding and it should do what you're looking for.
> 
> Yes, that is in line with everything else.
> 
> What bugs me is what to do about interrupt-parent,
> and whether to include it in example.

I am pretty sure you don't need to add it.
-------------- 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/20240207/15ae4d58/attachment-0001.sig>

From andrew at lunn.ch  Wed Feb  7 08:25:59 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 7 Feb 2024 17:25:59 +0100
Subject: [PATCH 3/3] arm64: dts: armada-ap807: update thermal compatible
In-Reply-To: <ZcOsjRzE8V73wNtT@eichest-laptop>
References: <ZIxMYXDCTB7IvsDk@shell.armlinux.org.uk>
 <E1qA7yZ-00Ea50-OC@rmk-PC.armlinux.org.uk>
 <ZcOsjRzE8V73wNtT@eichest-laptop>
Message-ID: <13ab003d-7449-4d6f-861a-fa2d0c3f4ad2@lunn.ch>

On Wed, Feb 07, 2024 at 05:15:48PM +0100, Stefan Eichenberger wrote:
> Hi Russell and Alex,
> 
> On Fri, Jun 16, 2023 at 12:50:47PM +0100, Russell King wrote:
> > From: Alex Leibovich <alexl at marvell.com>
> > 
> > Use the correct thermal coefficients for the Armada AP807 dies.
> > 
> > Signed-off-by: Alex Leibovich <alexl at marvell.com>
> > Reviewed-by: Stefan Chulski <stefanc at marvell.com>
> > Tested-by: Stefan Chulski <stefanc at marvell.com>
> > Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> > ---
> >  arch/arm64/boot/dts/marvell/armada-ap807.dtsi | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
> > index 4a23f65d475f..a3328d05fc94 100644
> > --- a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
> > +++ b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
> > @@ -33,3 +33,6 @@ &ap_sdhci0 {
> >  		     "marvell,armada-ap806-sdhci"; /* Backward compatibility */
> >  };
> >  
> > +&ap_thermal {
> > +	compatible = "marvell,armada-ap807-thermal";
> > +};
> 
> While working on some thermal optimizations, our hardware team
> discovered that this patch is still missing upstream. Is something
> missing or did it get lost?

Patch 1/3 had a change request. Was it ever reposted with the
requested change?

It would also be nice to convert the .txt to .yaml. The DT Maintainers
might insist on that when it is reposted?

      Andrew



From linux at armlinux.org.uk  Wed Feb  7 08:29:59 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 7 Feb 2024 16:29:59 +0000
Subject: [PATCH 3/3] arm64: dts: armada-ap807: update thermal compatible
In-Reply-To: <13ab003d-7449-4d6f-861a-fa2d0c3f4ad2@lunn.ch>
References: <ZIxMYXDCTB7IvsDk@shell.armlinux.org.uk>
 <E1qA7yZ-00Ea50-OC@rmk-PC.armlinux.org.uk>
 <ZcOsjRzE8V73wNtT@eichest-laptop>
 <13ab003d-7449-4d6f-861a-fa2d0c3f4ad2@lunn.ch>
Message-ID: <ZcOwB5xShhRoX5yh@shell.armlinux.org.uk>

On Wed, Feb 07, 2024 at 05:25:59PM +0100, Andrew Lunn wrote:
> On Wed, Feb 07, 2024 at 05:15:48PM +0100, Stefan Eichenberger wrote:
> > Hi Russell and Alex,
> > 
> > On Fri, Jun 16, 2023 at 12:50:47PM +0100, Russell King wrote:
> > > From: Alex Leibovich <alexl at marvell.com>
> > > 
> > > Use the correct thermal coefficients for the Armada AP807 dies.
> > > 
> > > Signed-off-by: Alex Leibovich <alexl at marvell.com>
> > > Reviewed-by: Stefan Chulski <stefanc at marvell.com>
> > > Tested-by: Stefan Chulski <stefanc at marvell.com>
> > > Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> > > ---
> > >  arch/arm64/boot/dts/marvell/armada-ap807.dtsi | 3 +++
> > >  1 file changed, 3 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
> > > index 4a23f65d475f..a3328d05fc94 100644
> > > --- a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
> > > +++ b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
> > > @@ -33,3 +33,6 @@ &ap_sdhci0 {
> > >  		     "marvell,armada-ap806-sdhci"; /* Backward compatibility */
> > >  };
> > >  
> > > +&ap_thermal {
> > > +	compatible = "marvell,armada-ap807-thermal";
> > > +};
> > 
> > While working on some thermal optimizations, our hardware team
> > discovered that this patch is still missing upstream. Is something
> > missing or did it get lost?
> 
> Patch 1/3 had a change request. Was it ever reposted with the
> requested change?

I don't think so, it's just another patch series of many that I have
that's basically low priority, and other stuff probably overrode it
and I then forgot about it.

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


From brgl at bgdev.pl  Wed Feb  7 08:32:38 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Wed, 7 Feb 2024 17:32:38 +0100
Subject: [PATCH 4/9] PCI: create platform devices for child OF
 nodes of the port node
In-Reply-To: <CAMRc=McT8wt6UbKtyofkJo3WcyJ-S4d2MPp8oZmjWbX6LGbETQ@mail.gmail.com>
References: <20240117160748.37682-1-brgl@bgdev.pl> <20240117160748.37682-5-brgl@bgdev.pl>
 <2024011707-alibi-pregnancy-a64b@gregkh> <CAMRc=Mef7wxRccnfQ=EDLckpb1YN4DNLoC=AYL8v1LLJ=uFH2Q@mail.gmail.com>
 <2024011836-wok-treadmill-c517@gregkh> <d2he3ufg6m46zos4swww4t3peyq55blxhirsx37ou37rwqxmz2@5khumvic62je>
 <CAMRc=MeXJjpJhDjyn_P-SGo4rDnEuT9kGN5jAbRcuM_c7_aDzQ@mail.gmail.com>
 <oiwvcvu6wdmpvhss3t7uaqkl5q73mki5pz6liuv66bap4dr2mp@jtjjwzlvt6za> <CAMRc=McT8wt6UbKtyofkJo3WcyJ-S4d2MPp8oZmjWbX6LGbETQ@mail.gmail.com>
Message-ID: <CAMRc=MeWgp27YcS=-dbYdN1is1MEuZ2ar=pW_p9oY0Nf1EbFHA@mail.gmail.com>

On Fri, Feb 2, 2024 at 11:02?AM Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> On Fri, Feb 2, 2024 at 1:03?AM Bjorn Andersson <andersson at kernel.org> wrote:
> >
>
> [snip]
>
> > > >
> > > > I believe I missed this part of the discussion, why does this need to be
> > > > a platform_device? What does the platform_bus bring that can't be
> > > > provided by some other bus?
> > > >
> > >
> > > Does it need to be a platform_device? No, of course not. Does it make
> > > sense for it to be one? Yes, for two reasons:
> > >
> > > 1. The ATH11K WLAN module is represented on the device tree like a
> > > platform device, we know it's always there and it consumes regulators
> > > from another platform device. The fact it uses PCIe doesn't change the
> > > fact that it is logically a platform device.
> >
> > Are you referring to the ath11k SNOC (firmware running on co-processor
> > in the SoC) variant?
> >
> > Afaict the PCIe-attached ath11k is not represented as a platform_device
> > in DeviceTree.
> >
>
> My bad. In RB5 it isn't (yet - I want to add it in the power
> sequencing series). It is in X13s though[1].
>
> > Said platform_device is also not a child under the PCIe bus, so this
> > would be a different platform_device...
> >
>
> It's the child of the PCIe port node but there's a reason for it to
> have the `compatible` property. It's because it's an entity of whose
> existence we are aware before the system boots.
>
> > > 2. The platform bus already provides us with the entire infrastructure
> > > that we'd now need to duplicate (possibly adding bugs) in order to
> > > introduce a "power sequencing bus".
> > >
> >
> > This is a perfectly reasonable desire. Look at our PMICs, they are full
> > of platform_devices. But through the years it's been said many times,
> > that this is not a valid or good reason for using platform_devices, and
> > as a result we have e.g. auxiliary bus.
> >
>
> Ok, so I cannot find this information anywhere (nor any example). Do
> you happen to know if the auxiliary bus offers any software node
> integration so that the `compatible` property from DT can get
> seamlessly mapped to auxiliary device IDs?
>

So I was just trying to port this to using the auxiliary bus, only to
find myself literally reimplementing functions from
drivers/of/device.c. I have a feeling that this is simply wrong. If
we're instantiating devices well defined on the device-tree then IMO
we *should* make them platform devices. Anything else and we'll be
reimplementing drivers/of/ because we will need to parse the device
nodes, check the compatible, match it against drivers etc. Things that
are already implemented for the platform bus and of_* APIs.

Greg: Could you chime in and confirm that it's alright to use the
platform bus here? Or maybe there is some infrastructure to create
auxiliary devices from software nodes?

Bartosz

> > Anyway, (please) don't claim that "we need to", when it actually is "we
> > want to use platform_device because that's more convenient"!
>
> Bart
>
> [snip]
>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts#n744


From eichest at gmail.com  Wed Feb  7 08:46:56 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Wed, 7 Feb 2024 17:46:56 +0100
Subject: [PATCH 3/3] arm64: dts: armada-ap807: update thermal compatible
In-Reply-To: <ZcOwB5xShhRoX5yh@shell.armlinux.org.uk>
References: <ZIxMYXDCTB7IvsDk@shell.armlinux.org.uk>
 <E1qA7yZ-00Ea50-OC@rmk-PC.armlinux.org.uk>
 <ZcOsjRzE8V73wNtT@eichest-laptop>
 <13ab003d-7449-4d6f-861a-fa2d0c3f4ad2@lunn.ch>
 <ZcOwB5xShhRoX5yh@shell.armlinux.org.uk>
Message-ID: <ZcO0AAzK+P8sYHdX@eichest-laptop>

On Wed, Feb 07, 2024 at 04:29:59PM +0000, Russell King (Oracle) wrote:
> On Wed, Feb 07, 2024 at 05:25:59PM +0100, Andrew Lunn wrote:
> > > While working on some thermal optimizations, our hardware team
> > > discovered that this patch is still missing upstream. Is something
> > > missing or did it get lost?
> > 
> > Patch 1/3 had a change request. Was it ever reposted with the
> > requested change?

I forgot to mention that the other patches were applied, so it is only
the one missing without change request.

> 
> I don't think so, it's just another patch series of many that I have
> that's basically low priority, and other stuff probably overrode it
> and I then forgot about it.

No problem at all, thanks a lot for the feedback.

Regards,
Stefan


From patchwork-bot+netdevbpf at kernel.org  Wed Feb  7 09:10:29 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 07 Feb 2024 17:10:29 +0000
Subject: [PATCH net-next v2 0/6] net: eee network driver cleanups
In-Reply-To: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
References: <Zb9/O81fVAZw4ANr@shell.armlinux.org.uk>
Message-ID: <170732582935.14396.12248558616645018742.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Sun, 4 Feb 2024 12:12:43 +0000 you wrote:
> Hi,
> 
> Since commit d1420bb99515 ("net: phy: improve generic EEE ethtool
> functions") changed phylib to set eee->eee_active and eee->eee_enabled,
> overriding anything that drivers have set these to prior to calling
> phy_ethtool_get_eee().
> 
> [...]

Here is the summary with links:
  - [net-next,v2,1/6] net: stmmac: remove eee_enabled/eee_active in stmmac_ethtool_op_get_eee()
    https://git.kernel.org/netdev/net-next/c/0cb6daf549f9
  - [net-next,v2,2/6] net: sxgbe: remove eee_enabled/eee_active in sxgbe_get_eee()
    https://git.kernel.org/netdev/net-next/c/d0d8c548789d
  - [net-next,v2,3/6] net: fec: remove eee_enabled/eee_active in fec_enet_get_eee()
    https://git.kernel.org/netdev/net-next/c/b573cb0a5586
  - [net-next,v2,4/6] net: bcmgenet: remove eee_enabled/eee_active in bcmgenet_get_eee()
    https://git.kernel.org/netdev/net-next/c/409359c1c2ef
  - [net-next,v2,5/6] net: bcmasp: remove eee_enabled/eee_active in bcmasp_get_eee()
    https://git.kernel.org/netdev/net-next/c/0cbfdfe3fb80
  - [net-next,v2,6/6] net: dsa: b53: remove eee_enabled/eee_active in b53_get_mac_eee()
    https://git.kernel.org/netdev/net-next/c/3465df5533af

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From nmorrisson at phytec.com  Wed Feb  7 09:28:20 2024
From: nmorrisson at phytec.com (Nathan Morrisson)
Date: Wed,  7 Feb 2024 09:28:20 -0800
Subject: [PATCH] arm64: dts: ti: am62-phyboard-lyra: Add overlay to enable a GPIO fan
Message-ID: <20240207172820.478332-1-nmorrisson@phytec.com>

The phyBOARD-Lyra has a GPIO fan header. This overlay enables the fan
header and sets the fan to turn on at 65C.

Signed-off-by: Nathan Morrisson <nmorrisson at phytec.com>
---
 arch/arm64/boot/dts/ti/Makefile               |  1 +
 .../ti/k3-am62-phyboard-lyra-gpio-fan.dtso    | 51 +++++++++++++++++++
 2 files changed, 52 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..379fb4f31a1f 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -23,6 +23,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-mallow.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62-phyboard-lyra-gpio-fan.dtbo
 
 # Boards with AM62Ax SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso b/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
new file mode 100644
index 000000000000..9c05748bdd9d
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2024 PHYTEC America LLC
+ * Author: Garrett Giordano <ggiordano at phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	fan: gpio-fan {
+		compatible = "gpio-fan";
+		gpio-fan,speed-map = <0 0 8600 1>;
+		gpios = <&main_gpio0 40 GPIO_ACTIVE_LOW>;
+		#cooling-cells = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_fan_pins_default>;
+		status = "okay";
+	};
+};
+
+&main_pmx0 {
+	gpio_fan_pins_default: gpio-fan-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0a4, PIN_OUTPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
+		>;
+	};
+};
+
+&thermal_zones {
+	main0_thermal: main0-thermal {
+		trips {
+			main0_thermal_trip0: main0-thermal-trip {
+				temperature = <65000>;  /* millicelsius */
+				hysteresis = <2000>;    /* millicelsius */
+				type = "active";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&main0_thermal_trip0>;
+				cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+};
-- 
2.25.1



From daniel at makrotopia.org  Wed Feb  7 09:42:41 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Wed, 7 Feb 2024 17:42:41 +0000
Subject: [PATCH] soc: mediatek: mtk-socinfo: depends on CONFIG_SOC_BUS
Message-ID: <cc8f7f7da5bdccce514a320e0ae7468659cf7346.1707327680.git.daniel@makrotopia.org>

The mtk-socinfo driver uses symbols 'soc_device_register' and
'soc_device_unregister' which are part of the bus driver for
System-on-Chip devices.

Select SOC_BUS to make sure that driver is built and the symbols are
available.

Fixes: 423a54da3c7e ("soc: mediatek: mtk-socinfo: Add driver for getting chip information")
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 drivers/soc/mediatek/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 50c664b65f4d4..1b7afb19ccd63 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -72,6 +72,7 @@ config MTK_SOCINFO
 	tristate "MediaTek SoC Information"
 	default y
 	depends on NVMEM_MTK_EFUSE
+	select SOC_BUS
 	help
 	  The MediaTek SoC Information (mtk-socinfo) driver provides
 	  information about the SoC to the userspace including the
-- 
2.43.0



From charles.perry at savoirfairelinux.com  Wed Feb  7 10:01:25 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Wed,  7 Feb 2024 13:01:25 -0500
Subject: [PATCH v3 2/5] dt-bindings: fpga: xlnx,fpga-slave-serial: rename gpios
In-Reply-To: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
Message-ID: <20240207180142.79625-3-charles.perry@savoirfairelinux.com>

By convention, gpio consumer names should not contain underscores
(prog_b here) and shouldn't contain active low suffixes (-b here).

Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
---
 .../bindings/fpga/xlnx,fpga-slave-serial.yaml        | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml b/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml
index 614d86ad825f3..650a4d8792b64 100644
--- a/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml
+++ b/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml
@@ -36,7 +36,7 @@ properties:
   reg:
     maxItems: 1
 
-  prog_b-gpios:
+  prog-gpios:
     description:
       config pin (referred to as PROGRAM_B in the manual)
     maxItems: 1
@@ -46,7 +46,7 @@ properties:
       config status pin (referred to as DONE in the manual)
     maxItems: 1
 
-  init-b-gpios:
+  init-gpios:
     description:
       initialization status and configuration error pin
       (referred to as INIT_B in the manual)
@@ -55,9 +55,9 @@ properties:
 required:
   - compatible
   - reg
-  - prog_b-gpios
+  - prog-gpios
   - done-gpios
-  - init-b-gpios
+  - init-gpios
 
 additionalProperties: false
 
@@ -72,8 +72,8 @@ examples:
         spi-max-frequency = <60000000>;
         spi-cpha;
         reg = <0>;
-        prog_b-gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
-        init-b-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
+        prog-gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+        init-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
         done-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
       };
     };
-- 
2.43.0



From charles.perry at savoirfairelinux.com  Wed Feb  7 10:01:23 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Wed,  7 Feb 2024 13:01:23 -0500
Subject: [PATCH v3 0/5] fpga: xilinx-selectmap: add new driver
Message-ID: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>

Hello,

This patchset adds a new driver for the 7 series FPGA's SelectMAP
interface.

The SelectMAP interface shares a common GPIO protocol with the SPI
interface which is already in the kernel (drivers/fpga/xilinx-spi.c).
The approach proposed in this patchset is to refactor xilinx-spi.c into
xilinx-core.c which would handle the common GPIO protocol. This is then
used to build two drivers, the already existing xilinx-spi.c driver and
a newly added xilinx-selectmap.c driver.

The SelectMAP driver proposed only supports 8 bit mode. This is because
the 16 and 32 bits mode have limitations with regards to compressed
bitstream support as well as introducing endianness considerations.

I'm testing xilinx-selectmap.c on a custom i.MX6 board connected to an
Artix 7 FPGA. Flashing a 913K bitstream takes 0.44 seconds.

Changes since v2:
 * Inserted patch 2 and 3 which rename "prog_b" and "init-b" into "prog"
   and "init" for the SPI driver.
 * From Krzysztof Kozlowski review's:
   * Use more specific compatible names
   * Remove other missing occurences of the slave word missed in v2.
 * From Xu Yilun review's:
   * Fix vertical whitespace in get_done_gpio().
   * Combine write() and write_one_dummy_byte() together.
   * Eliminate most of the xilinx_core_probe() arguments, the driver
     needs to populate those directly into the xilinx_fpga_core struct.
     Added some documentation to struct xilinx_fpga_core to clarify
     this.
   * Removed typedefs from xilinx-core.h.
   * Moved null checks in xilinx_core_probe() to first patch.
   * Move csi_b and rdwr_b out of xilinx_selectmap_conf as they are not
     used out of the probe function.

Changes since v1: (from Krzysztof Kozlowski review's)
  * Use more conventional names for gpio DT bindings
  * fix example in DT bindings
  * add mc-peripheral-props.yaml to DT bindings
  * fix various formatting mistakes
  * Remove all occurences of the "slave" word.


Charles Perry (5):
  fpga: xilinx-spi: extract a common driver core
  dt-bindings: fpga: xlnx,fpga-slave-serial: rename gpios
  fpga: xilinx-core: rename "prog_b" and "init-b" gpios
  dt-bindings: fpga: xlnx,fpga-selectmap: add DT schema
  fpga: xilinx-selectmap: add new driver

 .../bindings/fpga/xlnx,fpga-selectmap.yaml    |  86 +++++++
 .../bindings/fpga/xlnx,fpga-slave-serial.yaml |  12 +-
 drivers/fpga/Kconfig                          |  12 +
 drivers/fpga/Makefile                         |   2 +
 drivers/fpga/xilinx-core.c                    | 232 ++++++++++++++++++
 drivers/fpga/xilinx-core.h                    |  28 +++
 drivers/fpga/xilinx-selectmap.c               |  97 ++++++++
 drivers/fpga/xilinx-spi.c                     | 212 +---------------
 8 files changed, 476 insertions(+), 205 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
 create mode 100644 drivers/fpga/xilinx-core.c
 create mode 100644 drivers/fpga/xilinx-core.h
 create mode 100644 drivers/fpga/xilinx-selectmap.c

--
2.43.0


From charles.perry at savoirfairelinux.com  Wed Feb  7 10:01:24 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Wed,  7 Feb 2024 13:01:24 -0500
Subject: [PATCH v3 1/5] fpga: xilinx-spi: extract a common driver core
In-Reply-To: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
Message-ID: <20240207180142.79625-2-charles.perry@savoirfairelinux.com>

Factor out the gpio handshaking (using PROGRAM_B, INIT_B and DONE)
protocol in xilinx-core so that it can be reused for another driver.
This commit does not change anything functionally to xilinx-spi.

xilinx-core expects drivers to provide a single operation:

 * ->write(const char* buf, size_t count): write to the device

As well as a struct device* for resource management.

Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
---
 drivers/fpga/Kconfig       |   4 +
 drivers/fpga/Makefile      |   1 +
 drivers/fpga/xilinx-core.c | 208 ++++++++++++++++++++++++++++++++++++
 drivers/fpga/xilinx-core.h |  28 +++++
 drivers/fpga/xilinx-spi.c  | 212 +++----------------------------------
 5 files changed, 254 insertions(+), 199 deletions(-)
 create mode 100644 drivers/fpga/xilinx-core.c
 create mode 100644 drivers/fpga/xilinx-core.h

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 2f689ac4ba3a3..d27a1ebf40838 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -64,9 +64,13 @@ config FPGA_MGR_STRATIX10_SOC
 	help
 	  FPGA manager driver support for the Intel Stratix10 SoC.
 
+config FPGA_MGR_XILINX_CORE
+	tristate
+
 config FPGA_MGR_XILINX_SPI
 	tristate "Xilinx Configuration over Slave Serial (SPI)"
 	depends on SPI
+	select FPGA_MGR_XILINX_CORE
 	help
 	  FPGA manager driver support for Xilinx FPGA configuration
 	  over slave serial interface.
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 352a2612623e0..7ec795b6a5a70 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
 obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
 obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC)	+= stratix10-soc.o
 obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
+obj-$(CONFIG_FPGA_MGR_XILINX_CORE)	+= xilinx-core.o
 obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
 obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
 obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA)	+= zynqmp-fpga.o
diff --git a/drivers/fpga/xilinx-core.c b/drivers/fpga/xilinx-core.c
new file mode 100644
index 0000000000000..597e8b7a530b7
--- /dev/null
+++ b/drivers/fpga/xilinx-core.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Common parts of the Xilinx Spartan6 and 7 Series FPGA manager drivers.
+ *
+ * Copyright (C) 2017 DENX Software Engineering
+ *
+ * Anatolij Gustschin <agust at denx.de>
+ */
+
+#include "xilinx-core.h"
+
+#include <linux/delay.h>
+#include <linux/fpga/fpga-mgr.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of.h>
+
+static int get_done_gpio(struct fpga_manager *mgr)
+{
+	struct xilinx_fpga_core *core = mgr->priv;
+	int ret;
+
+	ret = gpiod_get_value(core->done);
+	if (ret < 0)
+		dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret);
+
+	return ret;
+}
+
+static enum fpga_mgr_states xilinx_core_state(struct fpga_manager *mgr)
+{
+	if (!get_done_gpio(mgr))
+		return FPGA_MGR_STATE_RESET;
+
+	return FPGA_MGR_STATE_UNKNOWN;
+}
+
+/**
+ * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
+ * a given delay if the pin is unavailable
+ *
+ * @mgr:        The FPGA manager object
+ * @value:      Value INIT_B to wait for (1 = asserted = low)
+ * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
+ *
+ * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
+ * too much time passed waiting for that. If no INIT_B GPIO is available
+ * then always return 0.
+ */
+static int wait_for_init_b(struct fpga_manager *mgr, int value,
+			   unsigned long alt_udelay)
+{
+	struct xilinx_fpga_core *core = mgr->priv;
+	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+
+	if (core->init_b) {
+		while (time_before(jiffies, timeout)) {
+			int ret = gpiod_get_value(core->init_b);
+
+			if (ret == value)
+				return 0;
+
+			if (ret < 0) {
+				dev_err(&mgr->dev,
+					"Error reading INIT_B (%d)\n", ret);
+				return ret;
+			}
+
+			usleep_range(100, 400);
+		}
+
+		dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n",
+			value ? "assert" : "deassert");
+		return -ETIMEDOUT;
+	}
+
+	udelay(alt_udelay);
+
+	return 0;
+}
+
+static int xilinx_core_write_init(struct fpga_manager *mgr,
+				  struct fpga_image_info *info, const char *buf,
+				  size_t count)
+{
+	struct xilinx_fpga_core *core = mgr->priv;
+	int err;
+
+	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
+		dev_err(&mgr->dev, "Partial reconfiguration not supported\n");
+		return -EINVAL;
+	}
+
+	gpiod_set_value(core->prog_b, 1);
+
+	err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */
+	if (err) {
+		gpiod_set_value(core->prog_b, 0);
+		return err;
+	}
+
+	gpiod_set_value(core->prog_b, 0);
+
+	err = wait_for_init_b(mgr, 0, 0);
+	if (err)
+		return err;
+
+	if (get_done_gpio(mgr)) {
+		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
+		return -EIO;
+	}
+
+	/* program latency */
+	usleep_range(7500, 7600);
+	return 0;
+}
+
+static int xilinx_core_write(struct fpga_manager *mgr, const char *buf,
+			     size_t count)
+{
+	struct xilinx_fpga_core *core = mgr->priv;
+
+	return core->write(core, buf, count);
+}
+
+static int xilinx_core_write_complete(struct fpga_manager *mgr,
+				      struct fpga_image_info *info)
+{
+	struct xilinx_fpga_core *core = mgr->priv;
+	unsigned long timeout =
+		jiffies + usecs_to_jiffies(info->config_complete_timeout_us);
+	bool expired = false;
+	int done;
+	int ret;
+	const char padding[1] = { 0xff };
+
+	/*
+	 * This loop is carefully written such that if the driver is
+	 * scheduled out for more than 'timeout', we still check for DONE
+	 * before giving up and we apply 8 extra CCLK cycles in all cases.
+	 */
+	while (!expired) {
+		expired = time_after(jiffies, timeout);
+
+		done = get_done_gpio(mgr);
+		if (done < 0)
+			return done;
+
+		ret = core->write(core, padding, 1);
+		if (ret)
+			return ret;
+
+		if (done)
+			return 0;
+	}
+
+	if (core->init_b) {
+		ret = gpiod_get_value(core->init_b);
+
+		if (ret < 0) {
+			dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
+			return ret;
+		}
+
+		dev_err(&mgr->dev,
+			ret ? "CRC error or invalid device\n" :
+			      "Missing sync word or incomplete bitstream\n");
+	} else {
+		dev_err(&mgr->dev, "Timeout after config data transfer\n");
+	}
+
+	return -ETIMEDOUT;
+}
+
+static const struct fpga_manager_ops xilinx_core_ops = {
+	.state = xilinx_core_state,
+	.write_init = xilinx_core_write_init,
+	.write = xilinx_core_write,
+	.write_complete = xilinx_core_write_complete,
+};
+
+int xilinx_core_probe(struct xilinx_fpga_core *core)
+{
+	struct fpga_manager *mgr;
+
+	if (!core || !core->dev || !core->write)
+		return -EINVAL;
+
+	/* PROGRAM_B is active low */
+	core->prog_b = devm_gpiod_get(core->dev, "prog_b", GPIOD_OUT_LOW);
+	if (IS_ERR(core->prog_b))
+		return dev_err_probe(core->dev, PTR_ERR(core->prog_b),
+				     "Failed to get PROGRAM_B gpio\n");
+
+	core->init_b = devm_gpiod_get_optional(core->dev, "init-b", GPIOD_IN);
+	if (IS_ERR(core->init_b))
+		return dev_err_probe(core->dev, PTR_ERR(core->init_b),
+				     "Failed to get INIT_B gpio\n");
+
+	core->done = devm_gpiod_get(core->dev, "done", GPIOD_IN);
+	if (IS_ERR(core->done))
+		return dev_err_probe(core->dev, PTR_ERR(core->done),
+				     "Failed to get DONE gpio\n");
+
+	mgr = devm_fpga_mgr_register(core->dev,
+				     "Xilinx Slave Serial FPGA Manager",
+				     &xilinx_core_ops, core);
+	return PTR_ERR_OR_ZERO(mgr);
+}
diff --git a/drivers/fpga/xilinx-core.h b/drivers/fpga/xilinx-core.h
new file mode 100644
index 0000000000000..bea190287b403
--- /dev/null
+++ b/drivers/fpga/xilinx-core.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __XILINX_CORE_H
+#define __XILINX_CORE_H
+
+#include <linux/device.h>
+
+/**
+ * struct xilinx_fpga_core - interface between the driver and the core manager
+ *                           of Xilinx 7 Series FPGA manager
+ * @dev:       device node, must be set by the driver
+ * @write:     write callback of the driver, must be set by the driver
+ * @prog_b:    PROGRAM_B gpio, handled by the core manager
+ * @init_b:    INIT_B gpio, handled by the core manager
+ * @done:      DONE gpio, handled by the core manager
+ */
+struct xilinx_fpga_core {
+	struct device *dev;
+	int (*write)(struct xilinx_fpga_core *core, const char *buf,
+		     size_t count);
+	struct gpio_desc *prog_b;
+	struct gpio_desc *init_b;
+	struct gpio_desc *done;
+};
+
+int xilinx_core_probe(struct xilinx_fpga_core *core);
+
+#endif /* __XILINX_CORE_H */
diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c
index e1a227e7ff2ae..12f401502a53a 100644
--- a/drivers/fpga/xilinx-spi.c
+++ b/drivers/fpga/xilinx-spi.c
@@ -10,127 +10,24 @@
  * the slave serial configuration interface.
  */
 
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/fpga/fpga-mgr.h>
-#include <linux/gpio/consumer.h>
+#include "xilinx-core.h"
+
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
 #include <linux/of.h>
 #include <linux/spi/spi.h>
-#include <linux/sizes.h>
 
 struct xilinx_spi_conf {
+	struct xilinx_fpga_core core;
 	struct spi_device *spi;
-	struct gpio_desc *prog_b;
-	struct gpio_desc *init_b;
-	struct gpio_desc *done;
 };
 
-static int get_done_gpio(struct fpga_manager *mgr)
-{
-	struct xilinx_spi_conf *conf = mgr->priv;
-	int ret;
-
-	ret = gpiod_get_value(conf->done);
-
-	if (ret < 0)
-		dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret);
-
-	return ret;
-}
-
-static enum fpga_mgr_states xilinx_spi_state(struct fpga_manager *mgr)
-{
-	if (!get_done_gpio(mgr))
-		return FPGA_MGR_STATE_RESET;
-
-	return FPGA_MGR_STATE_UNKNOWN;
-}
-
-/**
- * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
- * a given delay if the pin is unavailable
- *
- * @mgr:        The FPGA manager object
- * @value:      Value INIT_B to wait for (1 = asserted = low)
- * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
- *
- * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
- * too much time passed waiting for that. If no INIT_B GPIO is available
- * then always return 0.
- */
-static int wait_for_init_b(struct fpga_manager *mgr, int value,
-			   unsigned long alt_udelay)
-{
-	struct xilinx_spi_conf *conf = mgr->priv;
-	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
-
-	if (conf->init_b) {
-		while (time_before(jiffies, timeout)) {
-			int ret = gpiod_get_value(conf->init_b);
-
-			if (ret == value)
-				return 0;
-
-			if (ret < 0) {
-				dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
-				return ret;
-			}
-
-			usleep_range(100, 400);
-		}
-
-		dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n",
-			value ? "assert" : "deassert");
-		return -ETIMEDOUT;
-	}
-
-	udelay(alt_udelay);
-
-	return 0;
-}
-
-static int xilinx_spi_write_init(struct fpga_manager *mgr,
-				 struct fpga_image_info *info,
-				 const char *buf, size_t count)
-{
-	struct xilinx_spi_conf *conf = mgr->priv;
-	int err;
-
-	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
-		dev_err(&mgr->dev, "Partial reconfiguration not supported\n");
-		return -EINVAL;
-	}
-
-	gpiod_set_value(conf->prog_b, 1);
-
-	err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */
-	if (err) {
-		gpiod_set_value(conf->prog_b, 0);
-		return err;
-	}
-
-	gpiod_set_value(conf->prog_b, 0);
+#define to_xilinx_spi_conf(obj) container_of(obj, struct xilinx_spi_conf, core)
 
-	err = wait_for_init_b(mgr, 0, 0);
-	if (err)
-		return err;
-
-	if (get_done_gpio(mgr)) {
-		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
-		return -EIO;
-	}
-
-	/* program latency */
-	usleep_range(7500, 7600);
-	return 0;
-}
-
-static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
+static int xilinx_spi_write(struct xilinx_fpga_core *core, const char *buf,
 			    size_t count)
 {
-	struct xilinx_spi_conf *conf = mgr->priv;
+	struct xilinx_spi_conf *conf = to_xilinx_spi_conf(core);
 	const char *fw_data = buf;
 	const char *fw_data_end = fw_data + count;
 
@@ -143,7 +40,7 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
 
 		ret = spi_write(conf->spi, fw_data, stride);
 		if (ret) {
-			dev_err(&mgr->dev, "SPI error in firmware write: %d\n",
+			dev_err(core->dev, "SPI error in firmware write: %d\n",
 				ret);
 			return ret;
 		}
@@ -153,109 +50,26 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
 	return 0;
 }
 
-static int xilinx_spi_apply_cclk_cycles(struct xilinx_spi_conf *conf)
-{
-	struct spi_device *spi = conf->spi;
-	const u8 din_data[1] = { 0xff };
-	int ret;
-
-	ret = spi_write(conf->spi, din_data, sizeof(din_data));
-	if (ret)
-		dev_err(&spi->dev, "applying CCLK cycles failed: %d\n", ret);
-
-	return ret;
-}
-
-static int xilinx_spi_write_complete(struct fpga_manager *mgr,
-				     struct fpga_image_info *info)
-{
-	struct xilinx_spi_conf *conf = mgr->priv;
-	unsigned long timeout = jiffies + usecs_to_jiffies(info->config_complete_timeout_us);
-	bool expired = false;
-	int done;
-	int ret;
-
-	/*
-	 * This loop is carefully written such that if the driver is
-	 * scheduled out for more than 'timeout', we still check for DONE
-	 * before giving up and we apply 8 extra CCLK cycles in all cases.
-	 */
-	while (!expired) {
-		expired = time_after(jiffies, timeout);
-
-		done = get_done_gpio(mgr);
-		if (done < 0)
-			return done;
-
-		ret = xilinx_spi_apply_cclk_cycles(conf);
-		if (ret)
-			return ret;
-
-		if (done)
-			return 0;
-	}
-
-	if (conf->init_b) {
-		ret = gpiod_get_value(conf->init_b);
-
-		if (ret < 0) {
-			dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
-			return ret;
-		}
-
-		dev_err(&mgr->dev,
-			ret ? "CRC error or invalid device\n"
-			: "Missing sync word or incomplete bitstream\n");
-	} else {
-		dev_err(&mgr->dev, "Timeout after config data transfer\n");
-	}
-
-	return -ETIMEDOUT;
-}
-
-static const struct fpga_manager_ops xilinx_spi_ops = {
-	.state = xilinx_spi_state,
-	.write_init = xilinx_spi_write_init,
-	.write = xilinx_spi_write,
-	.write_complete = xilinx_spi_write_complete,
-};
-
 static int xilinx_spi_probe(struct spi_device *spi)
 {
 	struct xilinx_spi_conf *conf;
-	struct fpga_manager *mgr;
 
 	conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL);
 	if (!conf)
 		return -ENOMEM;
 
+	conf->core.dev = &spi->dev;
+	conf->core.write = xilinx_spi_write;
 	conf->spi = spi;
 
-	/* PROGRAM_B is active low */
-	conf->prog_b = devm_gpiod_get(&spi->dev, "prog_b", GPIOD_OUT_LOW);
-	if (IS_ERR(conf->prog_b))
-		return dev_err_probe(&spi->dev, PTR_ERR(conf->prog_b),
-				     "Failed to get PROGRAM_B gpio\n");
-
-	conf->init_b = devm_gpiod_get_optional(&spi->dev, "init-b", GPIOD_IN);
-	if (IS_ERR(conf->init_b))
-		return dev_err_probe(&spi->dev, PTR_ERR(conf->init_b),
-				     "Failed to get INIT_B gpio\n");
-
-	conf->done = devm_gpiod_get(&spi->dev, "done", GPIOD_IN);
-	if (IS_ERR(conf->done))
-		return dev_err_probe(&spi->dev, PTR_ERR(conf->done),
-				     "Failed to get DONE gpio\n");
-
-	mgr = devm_fpga_mgr_register(&spi->dev,
-				     "Xilinx Slave Serial FPGA Manager",
-				     &xilinx_spi_ops, conf);
-	return PTR_ERR_OR_ZERO(mgr);
+	return xilinx_core_probe(&conf->core);
 }
 
 #ifdef CONFIG_OF
 static const struct of_device_id xlnx_spi_of_match[] = {
-	{ .compatible = "xlnx,fpga-slave-serial", },
+	{
+		.compatible = "xlnx,fpga-slave-serial",
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, xlnx_spi_of_match);
-- 
2.43.0



From charles.perry at savoirfairelinux.com  Wed Feb  7 10:01:26 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Wed,  7 Feb 2024 13:01:26 -0500
Subject: [PATCH v3 3/5] fpga: xilinx-core: rename "prog_b" and "init-b" gpios
In-Reply-To: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
Message-ID: <20240207180142.79625-4-charles.perry@savoirfairelinux.com>

New bindings use "prog" and "init". The legacy name is used as a
fallback.

Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
---
 drivers/fpga/xilinx-core.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/fpga/xilinx-core.c b/drivers/fpga/xilinx-core.c
index 597e8b7a530b7..4d2416e71d59c 100644
--- a/drivers/fpga/xilinx-core.c
+++ b/drivers/fpga/xilinx-core.c
@@ -171,6 +171,28 @@ static int xilinx_core_write_complete(struct fpga_manager *mgr,
 	return -ETIMEDOUT;
 }
 
+/**
+ * xilinx_core_devm_gpiod_get - Obtain a resource-managed GPIO using a
+ *                              legacy consumer name fallback.
+ *
+ * @dev:           Device managing the GPIO
+ * @con_id:        Consumer id
+ * @legacy_con_id: Legacy consumer id
+ * @flags:         optional GPIO initialization flags
+ */
+static inline struct gpio_desc *
+xilinx_core_devm_gpiod_get(struct device *dev, const char *con_id,
+			   const char *legacy_con_id, enum gpiod_flags flags)
+{
+	struct gpio_desc *desc;
+
+	desc = devm_gpiod_get(dev, con_id, flags);
+	if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT)
+		desc = devm_gpiod_get(dev, legacy_con_id, flags);
+
+	return desc;
+}
+
 static const struct fpga_manager_ops xilinx_core_ops = {
 	.state = xilinx_core_state,
 	.write_init = xilinx_core_write_init,
@@ -186,12 +208,14 @@ int xilinx_core_probe(struct xilinx_fpga_core *core)
 		return -EINVAL;
 
 	/* PROGRAM_B is active low */
-	core->prog_b = devm_gpiod_get(core->dev, "prog_b", GPIOD_OUT_LOW);
+	core->prog_b = xilinx_core_devm_gpiod_get(core->dev, "prog", "prog_b",
+						  GPIOD_OUT_LOW);
 	if (IS_ERR(core->prog_b))
 		return dev_err_probe(core->dev, PTR_ERR(core->prog_b),
 				     "Failed to get PROGRAM_B gpio\n");
 
-	core->init_b = devm_gpiod_get_optional(core->dev, "init-b", GPIOD_IN);
+	core->init_b = xilinx_core_devm_gpiod_get(core->dev, "init", "init-b",
+						  GPIOD_IN);
 	if (IS_ERR(core->init_b))
 		return dev_err_probe(core->dev, PTR_ERR(core->init_b),
 				     "Failed to get INIT_B gpio\n");
-- 
2.43.0



From charles.perry at savoirfairelinux.com  Wed Feb  7 10:01:28 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Wed,  7 Feb 2024 13:01:28 -0500
Subject: [PATCH v3 5/5] fpga: xilinx-selectmap: add new driver
In-Reply-To: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
Message-ID: <20240207180142.79625-6-charles.perry@savoirfairelinux.com>

Xilinx 7 series FPGA can be programmed using a parallel port named
the SelectMAP interface in the datasheet. This interface is compatible
with the i.MX6 EIM bus controller but other types of external memory
mapped parallel bus might work.

xilinx-selectmap currently only supports the x8 mode where data is loaded
at one byte per rising edge of the clock, with the MSb of each byte
presented to the D0 pin.

Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
---
 drivers/fpga/Kconfig            |  8 +++
 drivers/fpga/Makefile           |  1 +
 drivers/fpga/xilinx-selectmap.c | 97 +++++++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+)
 create mode 100644 drivers/fpga/xilinx-selectmap.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index d27a1ebf40838..37b35f58f0dfb 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -67,6 +67,14 @@ config FPGA_MGR_STRATIX10_SOC
 config FPGA_MGR_XILINX_CORE
 	tristate
 
+config FPGA_MGR_XILINX_SELECTMAP
+	tristate "Xilinx Configuration over SelectMAP"
+	depends on HAS_IOMEM
+	select FPGA_MGR_XILINX_CORE
+	help
+	  FPGA manager driver support for Xilinx FPGA configuration
+	  over SelectMAP interface.
+
 config FPGA_MGR_XILINX_SPI
 	tristate "Xilinx Configuration over Slave Serial (SPI)"
 	depends on SPI
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 7ec795b6a5a70..aeb89bb13517e 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
 obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC)	+= stratix10-soc.o
 obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
 obj-$(CONFIG_FPGA_MGR_XILINX_CORE)	+= xilinx-core.o
+obj-$(CONFIG_FPGA_MGR_XILINX_SELECTMAP)	+= xilinx-selectmap.o
 obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
 obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
 obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA)	+= zynqmp-fpga.o
diff --git a/drivers/fpga/xilinx-selectmap.c b/drivers/fpga/xilinx-selectmap.c
new file mode 100644
index 0000000000000..b63f4623f8b2c
--- /dev/null
+++ b/drivers/fpga/xilinx-selectmap.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Xilinx Spartan6 and 7 Series SelectMAP interface driver
+ *
+ * (C) 2024 Charles Perry <charles.perry at savoirfairelinux.com>
+ *
+ * Manage Xilinx FPGA firmware loaded over the SelectMAP configuration
+ * interface.
+ */
+
+#include "xilinx-core.h"
+
+#include <linux/platform_device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/io.h>
+
+struct xilinx_selectmap_conf {
+	struct xilinx_fpga_core core;
+	void __iomem *base;
+};
+
+#define to_xilinx_selectmap_conf(obj) \
+	container_of(obj, struct xilinx_selectmap_conf, core)
+
+static int xilinx_selectmap_write(struct xilinx_fpga_core *core,
+				  const char *buf, size_t count)
+{
+	struct xilinx_selectmap_conf *conf = to_xilinx_selectmap_conf(core);
+	u32 i;
+
+	for (i = 0; i < count; ++i)
+		writeb(buf[i], conf->base);
+
+	return 0;
+}
+
+static int xilinx_selectmap_probe(struct platform_device *pdev)
+{
+	struct xilinx_selectmap_conf *conf;
+	struct resource *r;
+	void __iomem *base;
+	struct gpio_desc *csi_b;
+	struct gpio_desc *rdwr_b;
+
+	conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL);
+	if (!conf)
+		return -ENOMEM;
+
+	conf->core.dev = &pdev->dev;
+	conf->core.write = xilinx_selectmap_write;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
+	if (IS_ERR(base))
+		return dev_err_probe(&pdev->dev, PTR_ERR(base),
+				     "ioremap error\n");
+	conf->base = base;
+
+	/* CSI_B is active low */
+	csi_b = devm_gpiod_get_optional(&pdev->dev, "csi", GPIOD_OUT_HIGH);
+	if (IS_ERR(csi_b))
+		return dev_err_probe(&pdev->dev, PTR_ERR(csi_b),
+				     "Failed to get CSI_B gpio\n");
+
+	/* RDWR_B is active low */
+	rdwr_b = devm_gpiod_get_optional(&pdev->dev, "rdwr", GPIOD_OUT_HIGH);
+	if (IS_ERR(rdwr_b))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rdwr_b),
+				     "Failed to get RDWR_B gpio\n");
+
+	return xilinx_core_probe(&conf->core);
+}
+
+static const struct of_device_id xlnx_selectmap_of_match[] = {
+	{ .compatible = "xlnx,fpga-xc7s-selectmap", }, // Spartan-7
+	{ .compatible = "xlnx,fpga-xc7a-selectmap", }, // Artix-7
+	{ .compatible = "xlnx,fpga-xc7k-selectmap", }, // Kintex-7
+	{ .compatible = "xlnx,fpga-xc7v-selectmap", }, // Virtex-7
+	{},
+};
+MODULE_DEVICE_TABLE(of, xlnx_selectmap_of_match);
+
+static struct platform_driver xilinx_selectmap_driver = {
+	.driver = {
+		.name = "xilinx-selectmap",
+		.of_match_table = xlnx_selectmap_of_match,
+	},
+	.probe  = xilinx_selectmap_probe,
+};
+
+module_platform_driver(xilinx_selectmap_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Charles Perry <charles.perry at savoirfairelinux.com>");
+MODULE_DESCRIPTION("Load Xilinx FPGA firmware over SelectMap");
-- 
2.43.0



From charles.perry at savoirfairelinux.com  Wed Feb  7 10:01:27 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Wed,  7 Feb 2024 13:01:27 -0500
Subject: [PATCH v3 4/5] dt-bindings: fpga: xlnx,fpga-selectmap: add DT schema
In-Reply-To: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
Message-ID: <20240207180142.79625-5-charles.perry@savoirfairelinux.com>

Document the SelectMAP interface of Xilinx 7 series FPGA.

Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
---
 .../bindings/fpga/xlnx,fpga-selectmap.yaml    | 86 +++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml

diff --git a/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
new file mode 100644
index 0000000000000..c54bb2ecc30e9
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/fpga/xlnx,fpga-selectmap.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xilinx SelectMAP FPGA interface
+
+maintainers:
+  - Charles Perry <charles.perry at savoirfairelinux.com>
+
+description: |
+  Xilinx 7 Series FPGAs support a method of loading the bitstream over a
+  parallel port named the SelectMAP interface in the documentation. Only
+  the x8 mode is supported where data is loaded at one byte per rising edge of
+  the clock, with the MSB of each byte presented to the D0 pin.
+
+  Datasheets:
+    https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf
+
+allOf:
+  - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml#
+
+properties:
+  compatible:
+    enum:
+      - xlnx,fpga-xc7s-selectmap
+      - xlnx,fpga-xc7a-selectmap
+      - xlnx,fpga-xc7k-selectmap
+      - xlnx,fpga-xc7v-selectmap
+
+  reg:
+    description:
+      At least 1 byte of memory mapped IO
+    maxItems: 1
+
+  prog-gpios:
+    description:
+      config pin (referred to as PROGRAM_B in the manual)
+    maxItems: 1
+
+  done-gpios:
+    description:
+      config status pin (referred to as DONE in the manual)
+    maxItems: 1
+
+  init-gpios:
+    description:
+      initialization status and configuration error pin
+      (referred to as INIT_B in the manual)
+    maxItems: 1
+
+  csi-gpios:
+    description:
+      chip select pin (referred to as CSI_B in the manual)
+      Optional gpio for if the bus controller does not provide a chip select.
+    maxItems: 1
+
+  rdwr-gpios:
+    description:
+      read/write select pin (referred to as RDWR_B in the manual)
+      Optional gpio for if the bus controller does not provide this pin.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - prog-gpios
+  - done-gpios
+  - init-gpios
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    fpga-mgr at 8000000 {
+      compatible = "xlnx,fpga-selectmap";
+      reg = <0x8000000 0x4>;
+      prog-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>;
+      init-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
+      done-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>;
+      csi-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
+      rdwr-gpios = <&gpio3 10 GPIO_ACTIVE_LOW>;
+    };
+...
-- 
2.43.0



From broonie at kernel.org  Wed Feb  7 10:09:11 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 07 Feb 2024 18:09:11 +0000
Subject: [PATCH] ASoC: dt-bindings: atmel,asoc-wm8904: Convert to
 json-schema
In-Reply-To: <20240207094144.195397-1-dharma.b@microchip.com>
References: <20240207094144.195397-1-dharma.b@microchip.com>
Message-ID: <170732935198.1089483.14612569471427120930.b4-ty@kernel.org>

On Wed, 07 Feb 2024 15:11:44 +0530, Dharma Balasubiramani wrote:
> Convert atmel,asoc-wm8904 devicetree binding to json-schema.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: dt-bindings: atmel,asoc-wm8904: Convert to json-schema
      commit: 565abf586f3554c94c81027b1f0af1f6a6beea1b

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 Feb  7 10:21:03 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 07 Feb 2024 18:21:03 +0000
Subject: [PATCH] MAINTAINERS: repair entry for MICROCHIP MCP16502 PMIC
 DRIVER
In-Reply-To: <20240207132231.16392-1-lukas.bulwahn@gmail.com>
References: <20240207132231.16392-1-lukas.bulwahn@gmail.com>
Message-ID: <170733006365.1096853.3231034830633743082.b4-ty@kernel.org>

On Wed, 07 Feb 2024 14:22:31 +0100, Lukas Bulwahn wrote:
> Commit 64db3e8d7be0 ("regulator: dt-bindings: microchip,mcp16502: convert
> to YAML") converts mcp16502-regulator.txt to microchip,mcp16502.yaml, but
> misses to adjust its reference in MAINTAINERS.
> 
> Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a
> broken reference.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next

Thanks!

[1/1] MAINTAINERS: repair entry for MICROCHIP MCP16502 PMIC DRIVER
      commit: 46d5baf046abeffcb3754321fbc2551027fe7de9

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 florian.fainelli at broadcom.com  Wed Feb  7 10:22:26 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Wed, 7 Feb 2024 10:22:26 -0800
Subject: [PATCH RFC 0/2] pinctrl: bcm2835: Implement pin_conf_get
In-Reply-To: <1709f26f-0486-4856-8b2d-ba5e6fd492e2@gmx.net>
References: <20240204165852.166157-1-wahrenst@gmx.net>
 <CACRpkda=VsgiH0-iJVLry4hy6kLeJ_20mzMs8OrqR6Fr8eAp-g@mail.gmail.com>
 <1709f26f-0486-4856-8b2d-ba5e6fd492e2@gmx.net>
Message-ID: <553aa585-c442-4329-8a4d-fcf2f9c110c1@broadcom.com>

On 2/7/24 03:33, Stefan Wahren wrote:
> Hi Linus,
> 
> Am 07.02.24 um 11:56 schrieb Linus Walleij:
>> On Sun, Feb 4, 2024 at 5:59?PM Stefan Wahren <wahrenst at gmx.net> wrote:
>>
>>> For years, the Raspberry Pi users relied on userspace programs to read
>>> the pin configuration. In the meantime, it has become apparent that this
>>> approach has reached its limits for various reasons.
>>>
>>> This patch series now attempts to improve the debugging possibilities on
>>> the kernel side in order to reduce the dependency on these userspace
>>> programs.
>>>
>>> Stefan Wahren (2):
>>> ?? pinctrl: bcm2835: Implement bcm2835_pinconf_get
>>> ?? pinctrl: bcm2835: Implement bcm2711_pinconf_get
>> I don't see any problems with this, can I just apply the patches or do 
>> you
>> want to first resend them as non-RFC?
> since the second patch hasn't been tested with BCM7211, it would be nice
> to get a feedback from Florian or someone else with this hardware?

Give me a few days to get there and I will run a test.
-- 
Florian

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240207/593fd8c6/attachment-0001.p7s>

From andrew at lunn.ch  Wed Feb  7 10:26:54 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 7 Feb 2024 19:26:54 +0100
Subject: [PATCH 3/3] arm64: dts: armada-ap807: update thermal compatible
In-Reply-To: <ZcO0AAzK+P8sYHdX@eichest-laptop>
References: <ZIxMYXDCTB7IvsDk@shell.armlinux.org.uk>
 <E1qA7yZ-00Ea50-OC@rmk-PC.armlinux.org.uk>
 <ZcOsjRzE8V73wNtT@eichest-laptop>
 <13ab003d-7449-4d6f-861a-fa2d0c3f4ad2@lunn.ch>
 <ZcOwB5xShhRoX5yh@shell.armlinux.org.uk>
 <ZcO0AAzK+P8sYHdX@eichest-laptop>
Message-ID: <d454015d-7c38-4fd8-839f-13d72d041d53@lunn.ch>

On Wed, Feb 07, 2024 at 05:46:56PM +0100, Stefan Eichenberger wrote:
> On Wed, Feb 07, 2024 at 04:29:59PM +0000, Russell King (Oracle) wrote:
> > On Wed, Feb 07, 2024 at 05:25:59PM +0100, Andrew Lunn wrote:
> > > > While working on some thermal optimizations, our hardware team
> > > > discovered that this patch is still missing upstream. Is something
> > > > missing or did it get lost?
> > > 
> > > Patch 1/3 had a change request. Was it ever reposted with the
> > > requested change?
> 
> I forgot to mention that the other patches were applied, so it is only
> the one missing without change request.

Ah. O.K. Repost it to the MVEBU Maintainers.

    Andrew


From u.kleine-koenig at pengutronix.de  Wed Feb  7 10:40:36 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed,  7 Feb 2024 19:40:36 +0100
Subject: [PATCH v3 22/32] spi: slave-mt27xx: Follow renaming of SPI "master" to "controller"
In-Reply-To: <cover.1707324793.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707324793.git.u.kleine-koenig@pengutronix.de>
Message-ID: <184a5263af2ec01fd5ad9b8db667ae4d6cbec948.1707324794.git.u.kleine-koenig@pengutronix.de>

In commit 8caab75fd2c2 ("spi: Generalize SPI "master" to "controller"")
some functions and struct members were renamed. To not break all drivers
compatibility macros were provided.

To be able to remove these compatibility macros push the renaming into
this driver.

Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/spi/spi-slave-mt27xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-slave-mt27xx.c b/drivers/spi/spi-slave-mt27xx.c
index 6d6772974783..f1ddf4c099a3 100644
--- a/drivers/spi/spi-slave-mt27xx.c
+++ b/drivers/spi/spi-slave-mt27xx.c
@@ -297,7 +297,7 @@ static int mtk_spi_slave_transfer_one(struct spi_controller *ctlr,
 
 static int mtk_spi_slave_setup(struct spi_device *spi)
 {
-	struct mtk_spi_slave *mdata = spi_controller_get_devdata(spi->master);
+	struct mtk_spi_slave *mdata = spi_controller_get_devdata(spi->controller);
 	u32 reg_val;
 
 	reg_val = DMA_DONE_EN | DATA_DONE_EN |
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb  7 10:40:30 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed,  7 Feb 2024 19:40:30 +0100
Subject: [PATCH v3 16/32] spi: bitbang: Follow renaming of SPI "master" to "controller"
In-Reply-To: <cover.1707324793.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707324793.git.u.kleine-koenig@pengutronix.de>
Message-ID: <f7f949feb803acb8bea75798f41371a13287f4e8.1707324794.git.u.kleine-koenig@pengutronix.de>

In commit 8caab75fd2c2 ("spi: Generalize SPI "master" to "controller"")
some functions and struct members were renamed. To not break all drivers
compatibility macros were provided.

To be able to remove these compatibility macros push the renaming into
the SPI bitbang controller drivers.

Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/spi/spi-ath79.c         |  4 +--
 drivers/spi/spi-au1550.c        |  2 +-
 drivers/spi/spi-bitbang.c       | 64 ++++++++++++++++-----------------
 drivers/spi/spi-butterfly.c     |  6 ++--
 drivers/spi/spi-davinci.c       |  6 ++--
 drivers/spi/spi-gpio.c          |  2 +-
 drivers/spi/spi-lm70llp.c       |  6 ++--
 drivers/spi/spi-oc-tiny.c       |  6 ++--
 drivers/spi/spi-omap-uwire.c    |  4 +--
 drivers/spi/spi-sh-sci.c        | 10 +++---
 drivers/spi/spi-xilinx.c        |  4 +--
 drivers/spi/spi-xtensa-xtfpga.c |  2 +-
 include/linux/spi/spi_bitbang.h |  2 +-
 13 files changed, 59 insertions(+), 59 deletions(-)

diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c
index b7ada981464a..d78762d4db98 100644
--- a/drivers/spi/spi-ath79.c
+++ b/drivers/spi/spi-ath79.c
@@ -189,7 +189,7 @@ static int ath79_spi_probe(struct platform_device *pdev)
 	host->num_chipselect = 3;
 	host->mem_ops = &ath79_mem_ops;
 
-	sp->bitbang.master = host;
+	sp->bitbang.ctlr = host;
 	sp->bitbang.chipselect = ath79_spi_chipselect;
 	sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
 	sp->bitbang.flags = SPI_CS_HIGH;
@@ -237,7 +237,7 @@ static void ath79_spi_remove(struct platform_device *pdev)
 
 	spi_bitbang_stop(&sp->bitbang);
 	ath79_spi_disable(sp);
-	spi_controller_put(sp->bitbang.master);
+	spi_controller_put(sp->bitbang.ctlr);
 }
 
 static void ath79_spi_shutdown(struct platform_device *pdev)
diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c
index 1011b1a8f241..825d2f1cdff8 100644
--- a/drivers/spi/spi-au1550.c
+++ b/drivers/spi/spi-au1550.c
@@ -800,7 +800,7 @@ static int au1550_spi_probe(struct platform_device *pdev)
 
 	init_completion(&hw->host_done);
 
-	hw->bitbang.master = hw->host;
+	hw->bitbang.ctlr = hw->host;
 	hw->bitbang.setup_transfer = au1550_spi_setupxfer;
 	hw->bitbang.chipselect = au1550_spi_chipsel;
 	hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs;
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
index ecd44016c197..a0e2204fc039 100644
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -187,7 +187,7 @@ int spi_bitbang_setup(struct spi_device *spi)
 	bool			initial_setup = false;
 	int			retval;
 
-	bitbang = spi_master_get_devdata(spi->master);
+	bitbang = spi_controller_get_devdata(spi->controller);
 
 	if (!cs) {
 		cs = kzalloc(sizeof(*cs), GFP_KERNEL);
@@ -236,7 +236,7 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
 	unsigned		nsecs = cs->nsecs;
 	struct spi_bitbang	*bitbang;
 
-	bitbang = spi_master_get_devdata(spi->master);
+	bitbang = spi_controller_get_devdata(spi->controller);
 	if (bitbang->set_line_direction) {
 		int err;
 
@@ -268,11 +268,11 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
  * transfer-at-a-time ones to leverage dma or fifo hardware.
  */
 
-static int spi_bitbang_prepare_hardware(struct spi_master *spi)
+static int spi_bitbang_prepare_hardware(struct spi_controller *spi)
 {
 	struct spi_bitbang	*bitbang;
 
-	bitbang = spi_master_get_devdata(spi);
+	bitbang = spi_controller_get_devdata(spi);
 
 	mutex_lock(&bitbang->lock);
 	bitbang->busy = 1;
@@ -281,11 +281,11 @@ static int spi_bitbang_prepare_hardware(struct spi_master *spi)
 	return 0;
 }
 
-static int spi_bitbang_transfer_one(struct spi_master *master,
+static int spi_bitbang_transfer_one(struct spi_controller *ctlr,
 				    struct spi_device *spi,
 				    struct spi_transfer *transfer)
 {
-	struct spi_bitbang *bitbang = spi_master_get_devdata(master);
+	struct spi_bitbang *bitbang = spi_controller_get_devdata(ctlr);
 	int status = 0;
 
 	if (bitbang->setup_transfer) {
@@ -303,16 +303,16 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
 		status = -EREMOTEIO;
 
 out:
-	spi_finalize_current_transfer(master);
+	spi_finalize_current_transfer(ctlr);
 
 	return status;
 }
 
-static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
+static int spi_bitbang_unprepare_hardware(struct spi_controller *spi)
 {
 	struct spi_bitbang	*bitbang;
 
-	bitbang = spi_master_get_devdata(spi);
+	bitbang = spi_controller_get_devdata(spi);
 
 	mutex_lock(&bitbang->lock);
 	bitbang->busy = 0;
@@ -323,7 +323,7 @@ static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
 
 static void spi_bitbang_set_cs(struct spi_device *spi, bool enable)
 {
-	struct spi_bitbang *bitbang = spi_master_get_devdata(spi->master);
+	struct spi_bitbang *bitbang = spi_controller_get_devdata(spi->controller);
 
 	/* SPI core provides CS high / low, but bitbang driver
 	 * expects CS active
@@ -341,10 +341,10 @@ static void spi_bitbang_set_cs(struct spi_device *spi, bool enable)
 
 int spi_bitbang_init(struct spi_bitbang *bitbang)
 {
-	struct spi_master *master = bitbang->master;
+	struct spi_controller *ctlr = bitbang->ctlr;
 	bool custom_cs;
 
-	if (!master)
+	if (!ctlr)
 		return -EINVAL;
 	/*
 	 * We only need the chipselect callback if we are actually using it.
@@ -352,39 +352,39 @@ int spi_bitbang_init(struct spi_bitbang *bitbang)
 	 * SPI_CONTROLLER_GPIO_SS flag is set, we always need to call the
 	 * driver-specific chipselect routine.
 	 */
-	custom_cs = (!master->use_gpio_descriptors ||
-		     (master->flags & SPI_CONTROLLER_GPIO_SS));
+	custom_cs = (!ctlr->use_gpio_descriptors ||
+		     (ctlr->flags & SPI_CONTROLLER_GPIO_SS));
 
 	if (custom_cs && !bitbang->chipselect)
 		return -EINVAL;
 
 	mutex_init(&bitbang->lock);
 
-	if (!master->mode_bits)
-		master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
+	if (!ctlr->mode_bits)
+		ctlr->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
 
-	if (master->transfer || master->transfer_one_message)
+	if (ctlr->transfer || ctlr->transfer_one_message)
 		return -EINVAL;
 
-	master->prepare_transfer_hardware = spi_bitbang_prepare_hardware;
-	master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware;
-	master->transfer_one = spi_bitbang_transfer_one;
+	ctlr->prepare_transfer_hardware = spi_bitbang_prepare_hardware;
+	ctlr->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware;
+	ctlr->transfer_one = spi_bitbang_transfer_one;
 	/*
 	 * When using GPIO descriptors, the ->set_cs() callback doesn't even
 	 * get called unless SPI_CONTROLLER_GPIO_SS is set.
 	 */
 	if (custom_cs)
-		master->set_cs = spi_bitbang_set_cs;
+		ctlr->set_cs = spi_bitbang_set_cs;
 
 	if (!bitbang->txrx_bufs) {
 		bitbang->use_dma = 0;
 		bitbang->txrx_bufs = spi_bitbang_bufs;
-		if (!master->setup) {
+		if (!ctlr->setup) {
 			if (!bitbang->setup_transfer)
 				bitbang->setup_transfer =
 					 spi_bitbang_setup_transfer;
-			master->setup = spi_bitbang_setup;
-			master->cleanup = spi_bitbang_cleanup;
+			ctlr->setup = spi_bitbang_setup;
+			ctlr->cleanup = spi_bitbang_cleanup;
 		}
 	}
 
@@ -411,18 +411,18 @@ EXPORT_SYMBOL_GPL(spi_bitbang_init);
  * master methods.  Those methods are the defaults if the bitbang->txrx_bufs
  * routine isn't initialized.
  *
- * This routine registers the spi_master, which will process requests in a
+ * This routine registers the spi_controller, which will process requests in a
  * dedicated task, keeping IRQs unblocked most of the time.  To stop
  * processing those requests, call spi_bitbang_stop().
  *
- * On success, this routine will take a reference to master. The caller is
- * responsible for calling spi_bitbang_stop() to decrement the reference and
- * spi_master_put() as counterpart of spi_alloc_master() to prevent a memory
+ * On success, this routine will take a reference to the controller. The caller
+ * is responsible for calling spi_bitbang_stop() to decrement the reference and
+ * spi_controller_put() as counterpart of spi_alloc_master() to prevent a memory
  * leak.
  */
 int spi_bitbang_start(struct spi_bitbang *bitbang)
 {
-	struct spi_master *master = bitbang->master;
+	struct spi_controller *ctlr = bitbang->ctlr;
 	int ret;
 
 	ret = spi_bitbang_init(bitbang);
@@ -432,9 +432,9 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
 	/* driver may get busy before register() returns, especially
 	 * if someone registered boardinfo for devices
 	 */
-	ret = spi_register_master(spi_master_get(master));
+	ret = spi_register_controller(spi_controller_get(ctlr));
 	if (ret)
-		spi_master_put(master);
+		spi_controller_put(ctlr);
 
 	return ret;
 }
@@ -445,7 +445,7 @@ EXPORT_SYMBOL_GPL(spi_bitbang_start);
  */
 void spi_bitbang_stop(struct spi_bitbang *bitbang)
 {
-	spi_unregister_master(bitbang->master);
+	spi_unregister_controller(bitbang->ctlr);
 }
 EXPORT_SYMBOL_GPL(spi_bitbang_stop);
 
diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c
index 289b4454242a..1d267e6c22a4 100644
--- a/drivers/spi/spi-butterfly.c
+++ b/drivers/spi/spi-butterfly.c
@@ -205,7 +205,7 @@ static void butterfly_attach(struct parport *p)
 	host->bus_num = 42;
 	host->num_chipselect = 2;
 
-	pp->bitbang.master = host;
+	pp->bitbang.ctlr = host;
 	pp->bitbang.chipselect = butterfly_chipselect;
 	pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0;
 
@@ -263,7 +263,7 @@ static void butterfly_attach(struct parport *p)
 	pp->info[0].platform_data = &flash;
 	pp->info[0].chip_select = 1;
 	pp->info[0].controller_data = pp;
-	pp->dataflash = spi_new_device(pp->bitbang.master, &pp->info[0]);
+	pp->dataflash = spi_new_device(pp->bitbang.ctlr, &pp->info[0]);
 	if (pp->dataflash)
 		pr_debug("%s: dataflash at %s\n", p->name,
 			 dev_name(&pp->dataflash->dev));
@@ -308,7 +308,7 @@ static void butterfly_detach(struct parport *p)
 	parport_release(pp->pd);
 	parport_unregister_device(pp->pd);
 
-	spi_controller_put(pp->bitbang.master);
+	spi_controller_put(pp->bitbang.ctlr);
 }
 
 static struct parport_driver butterfly_driver = {
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c
index 5688be245c68..be3998104bfb 100644
--- a/drivers/spi/spi-davinci.c
+++ b/drivers/spi/spi-davinci.c
@@ -459,7 +459,7 @@ static bool davinci_spi_can_dma(struct spi_controller *host,
 
 static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status)
 {
-	struct device *sdev = dspi->bitbang.master->dev.parent;
+	struct device *sdev = dspi->bitbang.ctlr->dev.parent;
 
 	if (int_status & SPIFLG_TIMEOUT_MASK) {
 		dev_err(sdev, "SPI Time-out Error\n");
@@ -742,7 +742,7 @@ static irqreturn_t davinci_spi_irq(s32 irq, void *data)
 
 static int davinci_spi_request_dma(struct davinci_spi *dspi)
 {
-	struct device *sdev = dspi->bitbang.master->dev.parent;
+	struct device *sdev = dspi->bitbang.ctlr->dev.parent;
 
 	dspi->dma_rx = dma_request_chan(sdev, "rx");
 	if (IS_ERR(dspi->dma_rx))
@@ -913,7 +913,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
 	if (ret)
 		goto free_host;
 
-	dspi->bitbang.master = host;
+	dspi->bitbang.ctlr = host;
 
 	dspi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(dspi->clk)) {
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
index d8db4564b406..909cce109bba 100644
--- a/drivers/spi/spi-gpio.c
+++ b/drivers/spi/spi-gpio.c
@@ -427,7 +427,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
 	host->cleanup = spi_gpio_cleanup;
 
 	bb = &spi_gpio->bitbang;
-	bb->master = host;
+	bb->ctlr = host;
 	/*
 	 * There is some additional business, apart from driving the CS GPIO
 	 * line, that we need to do on selection. This makes the local
diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c
index e6a65b5c8c31..f982bdebd028 100644
--- a/drivers/spi/spi-lm70llp.c
+++ b/drivers/spi/spi-lm70llp.c
@@ -212,7 +212,7 @@ static void spi_lm70llp_attach(struct parport *p)
 	/*
 	 * SPI and bitbang hookup.
 	 */
-	pp->bitbang.master = host;
+	pp->bitbang.ctlr = host;
 	pp->bitbang.chipselect = lm70_chipselect;
 	pp->bitbang.txrx_word[SPI_MODE_0] = lm70_txrx;
 	pp->bitbang.flags = SPI_3WIRE;
@@ -264,7 +264,7 @@ static void spi_lm70llp_attach(struct parport *p)
 	 * the board info's (void *)controller_data.
 	 */
 	pp->info.controller_data = pp;
-	pp->spidev_lm70 = spi_new_device(pp->bitbang.master, &pp->info);
+	pp->spidev_lm70 = spi_new_device(pp->bitbang.ctlr, &pp->info);
 	if (pp->spidev_lm70)
 		dev_dbg(&pp->spidev_lm70->dev, "spidev_lm70 at %s\n",
 			dev_name(&pp->spidev_lm70->dev));
@@ -309,7 +309,7 @@ static void spi_lm70llp_detach(struct parport *p)
 	parport_release(pp->pd);
 	parport_unregister_device(pp->pd);
 
-	spi_controller_put(pp->bitbang.master);
+	spi_controller_put(pp->bitbang.ctlr);
 
 	lm70llp = NULL;
 }
diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c
index cf7c111088a6..6ea38f5e7d64 100644
--- a/drivers/spi/spi-oc-tiny.c
+++ b/drivers/spi/spi-oc-tiny.c
@@ -194,7 +194,7 @@ static int tiny_spi_of_probe(struct platform_device *pdev)
 
 	if (!np)
 		return 0;
-	hw->bitbang.master->dev.of_node = pdev->dev.of_node;
+	hw->bitbang.ctlr->dev.of_node = pdev->dev.of_node;
 	if (!of_property_read_u32(np, "clock-frequency", &val))
 		hw->freq = val;
 	if (!of_property_read_u32(np, "baud-width", &val))
@@ -229,7 +229,7 @@ static int tiny_spi_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, hw);
 
 	/* setup the state for the bitbang driver */
-	hw->bitbang.master = host;
+	hw->bitbang.ctlr = host;
 	hw->bitbang.setup_transfer = tiny_spi_setup_transfer;
 	hw->bitbang.txrx_bufs = tiny_spi_txrx_bufs;
 
@@ -274,7 +274,7 @@ static int tiny_spi_probe(struct platform_device *pdev)
 static void tiny_spi_remove(struct platform_device *pdev)
 {
 	struct tiny_spi *hw = platform_get_drvdata(pdev);
-	struct spi_controller *host = hw->bitbang.master;
+	struct spi_controller *host = hw->bitbang.ctlr;
 
 	spi_bitbang_stop(&hw->bitbang);
 	spi_controller_put(host);
diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c
index 2dd1c1bcf4bf..210a98d903fa 100644
--- a/drivers/spi/spi-omap-uwire.c
+++ b/drivers/spi/spi-omap-uwire.c
@@ -448,7 +448,7 @@ static void uwire_off(struct uwire_spi *uwire)
 {
 	uwire_write_reg(UWIRE_SR3, 0);
 	clk_disable_unprepare(uwire->ck);
-	spi_controller_put(uwire->bitbang.master);
+	spi_controller_put(uwire->bitbang.ctlr);
 }
 
 static int uwire_probe(struct platform_device *pdev)
@@ -493,7 +493,7 @@ static int uwire_probe(struct platform_device *pdev)
 	host->setup = uwire_setup;
 	host->cleanup = uwire_cleanup;
 
-	uwire->bitbang.master = host;
+	uwire->bitbang.ctlr = host;
 	uwire->bitbang.chipselect = uwire_chipselect;
 	uwire->bitbang.setup_transfer = uwire_setup_transfer;
 	uwire->bitbang.txrx_bufs = uwire_txrx;
diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c
index 148d615d2f38..3d560b154ad3 100644
--- a/drivers/spi/spi-sh-sci.c
+++ b/drivers/spi/spi-sh-sci.c
@@ -136,9 +136,9 @@ static int sh_sci_spi_probe(struct platform_device *dev)
 	}
 
 	/* setup spi bitbang adaptor */
-	sp->bitbang.master = host;
-	sp->bitbang.master->bus_num = sp->info->bus_num;
-	sp->bitbang.master->num_chipselect = sp->info->num_chipselect;
+	sp->bitbang.ctlr = host;
+	sp->bitbang.ctlr->bus_num = sp->info->bus_num;
+	sp->bitbang.ctlr->num_chipselect = sp->info->num_chipselect;
 	sp->bitbang.chipselect = sh_sci_spi_chipselect;
 
 	sp->bitbang.txrx_word[SPI_MODE_0] = sh_sci_spi_txrx_mode0;
@@ -166,7 +166,7 @@ static int sh_sci_spi_probe(struct platform_device *dev)
 	setbits(sp, PIN_INIT, 0);
 	iounmap(sp->membase);
  err1:
-	spi_controller_put(sp->bitbang.master);
+	spi_controller_put(sp->bitbang.ctlr);
  err0:
 	return ret;
 }
@@ -178,7 +178,7 @@ static void sh_sci_spi_remove(struct platform_device *dev)
 	spi_bitbang_stop(&sp->bitbang);
 	setbits(sp, PIN_INIT, 0);
 	iounmap(sp->membase);
-	spi_controller_put(sp->bitbang.master);
+	spi_controller_put(sp->bitbang.ctlr);
 }
 
 static struct platform_driver sh_sci_spi_drv = {
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index 12355957be97..7795328427a6 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -434,7 +434,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)
 
 	xspi = spi_controller_get_devdata(host);
 	xspi->cs_inactive = 0xffffffff;
-	xspi->bitbang.master = host;
+	xspi->bitbang.ctlr = host;
 	xspi->bitbang.chipselect = xilinx_spi_chipselect;
 	xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
 	xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
@@ -516,7 +516,7 @@ static void xilinx_spi_remove(struct platform_device *pdev)
 	/* Disable the global IPIF interrupt */
 	xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET);
 
-	spi_controller_put(xspi->bitbang.master);
+	spi_controller_put(xspi->bitbang.ctlr);
 }
 
 /* work with hotplug and coldplug */
diff --git a/drivers/spi/spi-xtensa-xtfpga.c b/drivers/spi/spi-xtensa-xtfpga.c
index 3c7721894376..3c2cda315397 100644
--- a/drivers/spi/spi-xtensa-xtfpga.c
+++ b/drivers/spi/spi-xtensa-xtfpga.c
@@ -93,7 +93,7 @@ static int xtfpga_spi_probe(struct platform_device *pdev)
 	host->dev.of_node = pdev->dev.of_node;
 
 	xspi = spi_controller_get_devdata(host);
-	xspi->bitbang.master = host;
+	xspi->bitbang.ctlr = host;
 	xspi->bitbang.chipselect = xtfpga_spi_chipselect;
 	xspi->bitbang.txrx_word[SPI_MODE_0] = xtfpga_spi_txrx_word;
 	xspi->regs = devm_platform_ioremap_resource(pdev, 0);
diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h
index 4444c2a992cb..b930eca2ef7b 100644
--- a/include/linux/spi/spi_bitbang.h
+++ b/include/linux/spi/spi_bitbang.h
@@ -10,7 +10,7 @@ struct spi_bitbang {
 	u8			use_dma;
 	u16			flags;		/* extra spi->mode support */
 
-	struct spi_master	*master;
+	struct spi_controller	*ctlr;
 
 	/* setup_transfer() changes clock and/or wordsize to match settings
 	 * for this transfer; zeroes restore defaults from spi_device.
-- 
2.43.0



From bwicaksono at nvidia.com  Wed Feb  7 12:08:51 2024
From: bwicaksono at nvidia.com (Besar Wicaksono)
Date: Wed, 7 Feb 2024 20:08:51 +0000
Subject: [PATCH v3 5/5] perf/arm_cspmu: Add devicetree support
In-Reply-To: <836722034302ff62f2df56aaeb0036e71945a5d1.1706718007.git.robin.murphy@arm.com>
References: <cover.1706718007.git.robin.murphy@arm.com>
 <836722034302ff62f2df56aaeb0036e71945a5d1.1706718007.git.robin.murphy@arm.com>
Message-ID: <SJ0PR12MB56766B7D9D4278C25B4405D7A0452@SJ0PR12MB5676.namprd12.prod.outlook.com>



> -----Original Message-----
> From: Robin Murphy <robin.murphy at arm.com>
> Sent: Tuesday, February 6, 2024 4:28 AM
> To: will at kernel.org
> Cc: mark.rutland at arm.com; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; suzuki.poulose at arm.com;
> ilkka at os.amperecomputing.com; Besar Wicaksono
> <bwicaksono at nvidia.com>; Yifei Wan <YWan at nvidia.com>; Richard Wiley
> <rwiley at nvidia.com>
> Subject: [PATCH v3 5/5] perf/arm_cspmu: Add devicetree support
> 
> External email: Use caution opening links or attachments
> 
> 
> Hook up devicetree probing support. For now let's hope that people
> implement PMIIDR properly and we don't need an override property or
> match data mechanism.
> 
> Reviewed-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Reviewed-by: Besar Wicaksono <bwicaksono at nvidia.com>
Tested-by: Besar Wicaksono <bwicaksono at nvidia.com>

Regards,
Besar

> ---
> v2: Use APMT node to distinguish ACPI; adjust for binding change
> v3: Handle NULL APMT node properly, fix phandle iteration.
> ---
>  drivers/perf/arm_cspmu/arm_cspmu.c | 67 ++++++++++++++++++++++++-
> -----
>  1 file changed, 55 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/perf/arm_cspmu/arm_cspmu.c
> b/drivers/perf/arm_cspmu/arm_cspmu.c
> index b54dc7fd6ca5..6bc21ef96250 100644
> --- a/drivers/perf/arm_cspmu/arm_cspmu.c
> +++ b/drivers/perf/arm_cspmu/arm_cspmu.c
> @@ -27,6 +27,7 @@
>  #include <linux/io-64-nonatomic-lo-hi.h>
>  #include <linux/module.h>
>  #include <linux/mutex.h>
> +#include <linux/of.h>
>  #include <linux/perf_event.h>
>  #include <linux/platform_device.h>
> 
> @@ -114,7 +115,9 @@ static void arm_cspmu_set_ev_filter(struct
> arm_cspmu *cspmu,
> 
>  static struct acpi_apmt_node *arm_cspmu_apmt_node(struct device *dev)
>  {
> -       return *(struct acpi_apmt_node **)dev_get_platdata(dev);
> +       struct acpi_apmt_node **ptr = dev_get_platdata(dev);
> +
> +       return ptr ? *ptr : NULL;
>  }
> 
>  /*
> @@ -310,6 +313,10 @@ static const char *arm_cspmu_get_name(const
> struct arm_cspmu *cspmu)
> 
>         dev = cspmu->dev;
>         apmt_node = arm_cspmu_apmt_node(dev);
> +       if (!apmt_node)
> +               return devm_kasprintf(dev, GFP_KERNEL, PMUNAME "_%u",
> +                                     atomic_fetch_inc(&pmu_idx[0]));
> +
>         pmu_type = apmt_node->type;
> 
>         if (pmu_type >= ACPI_APMT_NODE_TYPE_COUNT) {
> @@ -425,7 +432,7 @@ static int arm_cspmu_init_impl_ops(struct
> arm_cspmu *cspmu)
>         };
> 
>         /* Firmware may override implementer/product ID from PMIIDR */
> -       if (apmt_node->impl_id)
> +       if (apmt_node && apmt_node->impl_id)
>                 cspmu->impl.pmiidr = apmt_node->impl_id;
> 
>         /* Find implementer specific attribute ops. */
> @@ -940,7 +947,14 @@ static struct arm_cspmu *arm_cspmu_alloc(struct
> platform_device *pdev)
>         platform_set_drvdata(pdev, cspmu);
> 
>         apmt_node = arm_cspmu_apmt_node(dev);
> -       cspmu->has_atomic_dword = apmt_node->flags &
> ACPI_APMT_FLAGS_ATOMIC;
> +       if (apmt_node) {
> +               cspmu->has_atomic_dword = apmt_node->flags &
> ACPI_APMT_FLAGS_ATOMIC;
> +       } else {
> +               u32 width = 0;
> +
> +               device_property_read_u32(dev, "reg-io-width", &width);
> +               cspmu->has_atomic_dword = (width == 8);
> +       }
> 
>         return cspmu;
>  }
> @@ -1131,11 +1145,6 @@ static int arm_cspmu_acpi_get_cpus(struct
> arm_cspmu *cspmu)
>                 }
>         }
> 
> -       if (cpumask_empty(&cspmu->associated_cpus)) {
> -               dev_dbg(cspmu->dev, "No cpu associated with the PMU\n");
> -               return -ENODEV;
> -       }
> -
>         return 0;
>  }
>  #else
> @@ -1145,9 +1154,36 @@ static int arm_cspmu_acpi_get_cpus(struct
> arm_cspmu *cspmu)
>  }
>  #endif
> 
> +static int arm_cspmu_of_get_cpus(struct arm_cspmu *cspmu)
> +{
> +       struct of_phandle_iterator it;
> +       int ret, cpu;
> +
> +       of_for_each_phandle(&it, ret, dev_of_node(cspmu->dev), "cpus", NULL,
> 0) {
> +               cpu = of_cpu_node_to_id(it.node);
> +               if (cpu < 0)
> +                       continue;
> +               cpumask_set_cpu(cpu, &cspmu->associated_cpus);
> +       }
> +       return ret == -ENOENT ? 0 : ret;
> +}
> +
>  static int arm_cspmu_get_cpus(struct arm_cspmu *cspmu)
>  {
> -       return arm_cspmu_acpi_get_cpus(cspmu);
> +       int ret = 0;
> +
> +       if (arm_cspmu_apmt_node(cspmu->dev))
> +               ret = arm_cspmu_acpi_get_cpus(cspmu);
> +       else if (device_property_present(cspmu->dev, "cpus"))
> +               ret = arm_cspmu_of_get_cpus(cspmu);
> +       else
> +               cpumask_copy(&cspmu->associated_cpus, cpu_possible_mask);
> +
> +       if (!ret && cpumask_empty(&cspmu->associated_cpus)) {
> +               dev_dbg(cspmu->dev, "No cpu associated with the PMU\n");
> +               ret = -ENODEV;
> +       }
> +       return ret;
>  }
> 
>  static int arm_cspmu_register_pmu(struct arm_cspmu *cspmu)
> @@ -1244,11 +1280,18 @@ static const struct platform_device_id
> arm_cspmu_id[] = {
>  };
>  MODULE_DEVICE_TABLE(platform, arm_cspmu_id);
> 
> +static const struct of_device_id arm_cspmu_of_match[] = {
> +       { .compatible = "arm,coresight-pmu" },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, arm_cspmu_of_match);
> +
>  static struct platform_driver arm_cspmu_driver = {
>         .driver = {
> -                       .name = DRVNAME,
> -                       .suppress_bind_attrs = true,
> -               },
> +               .name = DRVNAME,
> +               .of_match_table = arm_cspmu_of_match,
> +               .suppress_bind_attrs = true,
> +       },
>         .probe = arm_cspmu_device_probe,
>         .remove = arm_cspmu_device_remove,
>         .id_table = arm_cspmu_id,
> --
> 2.39.2.101.g768bb238c484.dirty



From nfraprado at collabora.com  Wed Feb  7 12:08:42 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Wed, 07 Feb 2024 15:08:42 -0500
Subject: [PATCH RESEND] arm64: dts: mediatek: mt8192-asurada: Remove CrosEC
 base detection node
Message-ID: <20240207-mt8192-asurada-cbas-remove-v1-1-04cb65951975@collabora.com>

The commit adding the ChromeOS EC to the Asurada Devicetree mistakenly
added a base detection node. While tablet mode detection is supported by
CrosEC and used by Hayato, it is done through the cros-ec-keyb driver.
The base detection node, which is handled by the hid-google-hammer
driver, also provides tablet mode detection but by checking base
attachment status on the CrosEC, which is not supported for Asurada.

Hence, remove the unused CrosEC base detection node for Asurada.

Fixes: eb188a2aaa82 ("arm64: dts: mediatek: asurada: Add ChromeOS EC")
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
index 6867c4ad04a9..9b738f6a5d21 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -1337,10 +1337,6 @@ cros_ec: ec at 0 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		base_detection: cbas {
-			compatible = "google,cros-cbas";
-		};
-
 		cros_ec_pwm: pwm {
 			compatible = "google,cros-ec-pwm";
 			#pwm-cells = <1>;

---
base-commit: 2ae0a045e6814c8c1d676d6153c605a65746aa29
change-id: 20240207-mt8192-asurada-cbas-remove-ca5e1dc89b5a

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From william.zhang at broadcom.com  Wed Feb  7 12:22:45 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:45 -0800
Subject: [PATCH v5 00/12] mtd: rawnand: brcmnand: driver and doc updates
Message-ID: <20240207202257.271784-1-william.zhang@broadcom.com>

This patch series is an update from the previous version [1] after
exex_op support and fixes (patch 1 to 4 from the previous version.)

It updates all the BCMBCA SoC to support the nand controller and add
functions to handle BCMBCA specific needs on ECC and Write Protection
usage. The device tree document is also updated accordingly with the new
properties needed by the driver.

In addition there is a bug fix for exec_op helper functions and log
level adjustment on uncorrectable ECC error.

[1] https://lore.kernel.org/lkml/20230606231252.94838-1-william.zhang at broadcom.com/

Changes in v5:
- Add reviewed-by tag for the first patch of the yaml change
- Update the description for the WP connection and strap ecc properties
  based on the feedbacks
- Add check in dts binding to ensure the strap ecc property and core 
  nand ecc property can not be used at the same time
- Update the commit message for the log level change patch

Changes in v4:
- Split the yaml changes into three patches.
- Move the WP pin property to a new patch and change it to boolean type.
- Move ecc strap property to a new patch and remove some non-binding 
  related text from the description
- Add a new patch for bcm4908 based router board dts update
- Move the board related dts setting from SoC dtsi to board dts
- Update the comments for ecc setting selection
- Use the new brcm,wp-not-connected property based on the dts binding
  change
- Fix the commit id in the fixes tag
- Revert the log level change for correctable ecc error

Changes in v3:
- Update brcm,nand-use-wp description
- Revert the description change to BCM63168 SoC-specific NAND controller
- Updated bcmbca_read_data_bus comment

Changes in v2:
- Revert the new compatible string nand-bcmbca
- Drop the BCM63168 compatible fix to avoid any potential ABI
  incompatibility issue
- Simplify the explanation for brcm,nand-use-wp
- Keep the interrupt name requirement when interrupt number is specified
- Add nand controller node label for 4908 so it is consistent with other
  SoC's and can be referenced by board dts file
- Drop the is_param argument to the read data bus function now that we
  have the exec_op API to read the parameter page and ONFI data
- Minor cosmetic fixes
- Added patches 8, 9, 10 to patch series

David Regan (2):
  mtd: rawnand: brcmnand: exec_op helper functions return type fixes
  mtd: rawnand: brcmnand: update log level messages

William Zhang (10):
  dt-bindings: mtd: brcmnand: Updates for bcmbca SoCs
  dt-bindings: mtd: brcmnand: Add WP pin connection property
  dt-bindings: mtd: brcmnand: Add ecc strap property
  ARM: dts: broadcom: bcmbca: Add NAND controller node
  arm64: dts: broadcom: bcmbca: Add NAND controller node
  arm64: dts: broadcom: bcmbca: Update router boards
  mtd: rawnand: brcmnand: Rename bcm63138 nand driver
  mtd: rawnand: brcmnand: Add BCMBCA read data bus interface
  mtd: rawnand: brcmnand: Add support for getting ecc setting from strap
  mtd: rawnand: brcmnand: Support write protection setting from dts

 .../bindings/mtd/brcm,brcmnand.yaml           |  39 +++++-
 arch/arm/boot/dts/broadcom/bcm47622.dtsi      |  14 ++
 arch/arm/boot/dts/broadcom/bcm63138.dtsi      |   7 +-
 arch/arm/boot/dts/broadcom/bcm63148.dtsi      |  14 ++
 arch/arm/boot/dts/broadcom/bcm63178.dtsi      |  14 ++
 arch/arm/boot/dts/broadcom/bcm6756.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm6846.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm6855.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm6878.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm947622.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm963138.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm963138dvt.dts   |  14 +-
 arch/arm/boot/dts/broadcom/bcm963148.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm963178.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm96756.dts       |  10 ++
 arch/arm/boot/dts/broadcom/bcm96846.dts       |  10 ++
 arch/arm/boot/dts/broadcom/bcm96855.dts       |  10 ++
 arch/arm/boot/dts/broadcom/bcm96878.dts       |  10 ++
 .../bcmbca/bcm4906-netgear-r8000p.dts         |   5 +
 .../bcmbca/bcm4906-tplink-archer-c2300-v1.dts |   5 +
 .../bcmbca/bcm4908-asus-gt-ac5300.dts         |   6 +-
 .../boot/dts/broadcom/bcmbca/bcm4908.dtsi     |   4 +-
 .../boot/dts/broadcom/bcmbca/bcm4912.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm63146.dtsi    |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm63158.dtsi    |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm6813.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm6856.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm6858.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm94908.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm94912.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm963146.dts    |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm963158.dts    |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm96813.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm96856.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm96858.dts     |  10 ++
 drivers/mtd/nand/raw/brcmnand/Makefile        |   2 +-
 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c |  99 --------------
 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c   | 126 ++++++++++++++++++
 drivers/mtd/nand/raw/brcmnand/brcmnand.c      | 126 +++++++++++++++---
 drivers/mtd/nand/raw/brcmnand/brcmnand.h      |   2 +
 40 files changed, 633 insertions(+), 134 deletions(-)
 delete mode 100644 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
 create mode 100644 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c

-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:46 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:46 -0800
Subject: [PATCH v5 01/12] dt-bindings: mtd: brcmnand: Updates for bcmbca SoCs
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-2-william.zhang@broadcom.com>

Update the descriptions to reflect different families of broadband SoC and
use the general name bcmbca for ARM based SoC.

Remove the requirement of interrupts property to reflect the driver
code and only require interrupt-names when interrupts property present.

Also add myself to the list of maintainers.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>
Reviewed-by: Rob Herring <robh at kernel.org>

---

Changes in v5:
- Add reviewed-by tag

Changes in v4:
- Split the yaml changes into three patches. This is the first one

Changes in v3:
- Update brcm,nand-use-wp description
- Revert the description change to BCM63168 SoC-specific NAND controller

Changes in v2:
- Revert the new compatible string nand-bcmbca
- Drop the BCM63168 compatible fix to avoid any potential ABI
incompatibility issue
- Simplify the explanation for brcm,nand-use-wp
- Keep the interrupt name requirement when interrupt number is specified

 .../devicetree/bindings/mtd/brcm,brcmnand.yaml      | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
index f57e96374e67..e54ca08a798a 100644
--- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
+++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
@@ -9,6 +9,7 @@ title: Broadcom STB NAND Controller
 maintainers:
   - Brian Norris <computersforpeace at gmail.com>
   - Kamal Dasu <kdasu.kdev at gmail.com>
+  - William Zhang <william.zhang at broadcom.com>
 
 description: |
   The Broadcom Set-Top Box NAND controller supports low-level access to raw NAND
@@ -18,9 +19,10 @@ description: |
   supports basic PROGRAM and READ functions, among other features.
 
   This controller was originally designed for STB SoCs (BCM7xxx) but is now
-  available on a variety of Broadcom SoCs, including some BCM3xxx, BCM63xx, and
-  iProc/Cygnus. Its history includes several similar (but not fully register
-  compatible) versions.
+  available on a variety of Broadcom SoCs, including some BCM3xxx, MIPS based
+  Broadband SoC (BCM63xx), ARM based Broadband SoC (BCMBCA) and iProc/Cygnus.
+  Its history includes several similar (but not fully register compatible)
+  versions.
 
   -- Additional SoC-specific NAND controller properties --
 
@@ -53,7 +55,7 @@ properties:
               - brcm,brcmnand-v7.2
               - brcm,brcmnand-v7.3
           - const: brcm,brcmnand
-      - description: BCM63138 SoC-specific NAND controller
+      - description: BCMBCA SoC-specific NAND controller
         items:
           - const: brcm,nand-bcm63138
           - enum:
@@ -177,6 +179,8 @@ allOf:
             - const: iproc-idm
             - const: iproc-ext
   - if:
+      required:
+        - interrupts
       properties:
         interrupts:
           minItems: 2
@@ -189,7 +193,6 @@ unevaluatedProperties: false
 required:
   - reg
   - reg-names
-  - interrupts
 
 examples:
   - |
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:47 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:47 -0800
Subject: [PATCH v5 02/12] dt-bindings: mtd: brcmnand: Add WP pin connection property
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-3-william.zhang@broadcom.com>

Add brcm,wp-not-connected property to have an option for disabling this
feature on broadband board design that does not connect WP pin.

Signed-off-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v5:
- Update the description of this new property

Changes in v4:
- Move the WP pin property to this separate patch and change it to
boolean type.

Changes in v3: None
Changes in v2: None

 Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
index e54ca08a798a..6a717bcedfd3 100644
--- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
+++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
@@ -113,6 +113,13 @@ properties:
       earlier versions of this core that include WP
     type: boolean
 
+  brcm,wp-not-connected:
+    description:
+      Use this property when WP pin is not physically wired to the NAND chip.
+      Write protection feature cannot be used. By default, controller assumes
+      the pin is connected and feature is used.
+    $ref: /schemas/types.yaml#/definitions/flag
+
 patternProperties:
   "^nand@[a-f0-9]$":
     type: object
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:48 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:48 -0800
Subject: [PATCH v5 03/12] dt-bindings: mtd: brcmnand: Add ecc strap property
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-4-william.zhang@broadcom.com>

Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
board boot strap for broadband board designs because they do not specify
ecc setting in dts but rather using the strap setting.

Signed-off-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v5:
- Update the description for this ecc strap property
- Add check to make sure brcm,nand-ecc-use-strap and
  nand-ecc-strength/brcm,nand-oob-sector-size can not be used at the
  same time

Changes in v4:
- Move ecc strap property to this separate patch and remove some
non-binding related text from the description

Changes in v3: None
Changes in v2: None

 .../bindings/mtd/brcm,brcmnand.yaml           | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
index 6a717bcedfd3..52a4c993b6f1 100644
--- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
+++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
@@ -146,6 +146,13 @@ patternProperties:
           layout.
         $ref: /schemas/types.yaml#/definitions/uint32
 
+      brcm,nand-ecc-use-strap:
+        description:
+          This property requires the host system to get the ECC strength
+          and step size from the SoC NAND boot strap setting. This is a
+          common hardware design on BCMBCA based boards.
+        $ref: /schemas/types.yaml#/definitions/flag
+
     unevaluatedProperties: false
 
 allOf:
@@ -195,6 +202,18 @@ allOf:
       required:
         - interrupt-names
 
+  - if:
+      patternProperties:
+        "^nand@[a-f0-9]$":
+          required:
+            - brcm,nand-ecc-use-strap
+    then:
+      patternProperties:
+        "^nand@[a-f0-9]$":
+          properties:
+            nand-ecc-strength: false
+            brcm,nand-oob-sector-size: false
+
 unevaluatedProperties: false
 
 required:
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:49 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:49 -0800
Subject: [PATCH v5 04/12] ARM: dts: broadcom: bcmbca: Add NAND controller node
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-5-william.zhang@broadcom.com>

Add support for Broadcom STB NAND controller in BCMBCA ARMv7 chip dts
files.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v5: None
Changes in v4:
- Move the board related dts setting from SoC dtsi to board dts

Changes in v3: None
Changes in v2: None

 arch/arm/boot/dts/broadcom/bcm47622.dtsi    | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm63138.dtsi    |  7 ++++++-
 arch/arm/boot/dts/broadcom/bcm63148.dtsi    | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm63178.dtsi    | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6756.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6846.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6855.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6878.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm947622.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm963138.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm963138dvt.dts | 14 +++++++-------
 arch/arm/boot/dts/broadcom/bcm963148.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm963178.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96756.dts     | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96846.dts     | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96855.dts     | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96878.dts     | 10 ++++++++++
 17 files changed, 191 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/broadcom/bcm47622.dtsi b/arch/arm/boot/dts/broadcom/bcm47622.dtsi
index 7cd38de118c3..485863f9c420 100644
--- a/arch/arm/boot/dts/broadcom/bcm47622.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm47622.dtsi
@@ -138,6 +138,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm63138.dtsi b/arch/arm/boot/dts/broadcom/bcm63138.dtsi
index 4ef02283612b..e74ba6bf370d 100644
--- a/arch/arm/boot/dts/broadcom/bcm63138.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63138.dtsi
@@ -229,7 +229,12 @@ nand_controller: nand-controller at 2000 {
 			reg-names = "nand", "nand-int-base";
 			status = "disabled";
 			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "nand";
+			interrupt-names = "nand_ctlrdy";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
 		};
 
 		serial at 4400 {
diff --git a/arch/arm/boot/dts/broadcom/bcm63148.dtsi b/arch/arm/boot/dts/broadcom/bcm63148.dtsi
index 24431de1810e..53703827ee3f 100644
--- a/arch/arm/boot/dts/broadcom/bcm63148.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63148.dtsi
@@ -119,5 +119,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 2000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x2000 0x600>, <0xf0 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/broadcom/bcm63178.dtsi b/arch/arm/boot/dts/broadcom/bcm63178.dtsi
index 3f9aed96babf..6d8d33498983 100644
--- a/arch/arm/boot/dts/broadcom/bcm63178.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63178.dtsi
@@ -129,6 +129,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6756.dtsi b/arch/arm/boot/dts/broadcom/bcm6756.dtsi
index 1d8d957d65dd..6433f8fa5eff 100644
--- a/arch/arm/boot/dts/broadcom/bcm6756.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6756.dtsi
@@ -139,6 +139,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6846.dtsi b/arch/arm/boot/dts/broadcom/bcm6846.dtsi
index cf92cf8c4693..ee361cb00b7c 100644
--- a/arch/arm/boot/dts/broadcom/bcm6846.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6846.dtsi
@@ -119,5 +119,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/broadcom/bcm6855.dtsi b/arch/arm/boot/dts/broadcom/bcm6855.dtsi
index 52d6bc89f9f8..52915ec6f339 100644
--- a/arch/arm/boot/dts/broadcom/bcm6855.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6855.dtsi
@@ -129,6 +129,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6878.dtsi b/arch/arm/boot/dts/broadcom/bcm6878.dtsi
index 2c5d706bac7e..70cf23a65fdb 100644
--- a/arch/arm/boot/dts/broadcom/bcm6878.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6878.dtsi
@@ -120,6 +120,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm947622.dts b/arch/arm/boot/dts/broadcom/bcm947622.dts
index 93b8ce22678d..6241485408d3 100644
--- a/arch/arm/boot/dts/broadcom/bcm947622.dts
+++ b/arch/arm/boot/dts/broadcom/bcm947622.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963138.dts b/arch/arm/boot/dts/broadcom/bcm963138.dts
index 1b405c249213..7fd87e05ec20 100644
--- a/arch/arm/boot/dts/broadcom/bcm963138.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963138.dts
@@ -29,3 +29,13 @@ &serial0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963138dvt.dts b/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
index b5af61853a07..f60d09908ab9 100644
--- a/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
@@ -32,15 +32,15 @@ &serial1 {
 };
 
 &nand_controller {
+	brcm,wp-not-connected;
 	status = "okay";
+};
 
-	nand at 0 {
-		compatible = "brcm,nandcs";
-		reg = <0>;
-		nand-ecc-strength = <4>;
-		nand-ecc-step-size = <512>;
-		brcm,nand-oob-sectors-size = <16>;
-	};
+&nandcs {
+	nand-ecc-strength = <4>;
+	nand-ecc-step-size = <512>;
+	brcm,nand-oob-sector-size = <16>;
+	nand-on-flash-bbt;
 };
 
 &ahci {
diff --git a/arch/arm/boot/dts/broadcom/bcm963148.dts b/arch/arm/boot/dts/broadcom/bcm963148.dts
index 1f5d6d783f09..44bca063a327 100644
--- a/arch/arm/boot/dts/broadcom/bcm963148.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963148.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963178.dts b/arch/arm/boot/dts/broadcom/bcm963178.dts
index d036e99dd8d1..098a222cd71a 100644
--- a/arch/arm/boot/dts/broadcom/bcm963178.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963178.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96756.dts b/arch/arm/boot/dts/broadcom/bcm96756.dts
index 8b104f3fb14a..402038d3cd0c 100644
--- a/arch/arm/boot/dts/broadcom/bcm96756.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96756.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96846.dts b/arch/arm/boot/dts/broadcom/bcm96846.dts
index 55852c229608..943896afb7cc 100644
--- a/arch/arm/boot/dts/broadcom/bcm96846.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96846.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96855.dts b/arch/arm/boot/dts/broadcom/bcm96855.dts
index 2ad880af2104..571663d9a1ea 100644
--- a/arch/arm/boot/dts/broadcom/bcm96855.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96855.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96878.dts b/arch/arm/boot/dts/broadcom/bcm96878.dts
index b7af8ade7a9d..8d6eddd54c6e 100644
--- a/arch/arm/boot/dts/broadcom/bcm96878.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96878.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:50 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:50 -0800
Subject: [PATCH v5 05/12] arm64: dts: broadcom: bcmbca: Add NAND controller node
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-6-william.zhang@broadcom.com>

Add support for Broadcom STB NAND controller in BCMBCA ARMv8 chip dts
files.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v5: None
Changes in v4:
- Move the board related dts setting from SoC dtsi to board dts

Changes in v3: None
Changes in v2:
- Add nand controller node label for 4908 so it is consistent with other
SoCs and can be referenced by board dts file

 arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi  |  4 ++--
 arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts  | 10 ++++++++++
 14 files changed, 156 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
index 2f124b027bbf..336016e334d9 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
@@ -589,7 +589,7 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
-		nand-controller at 1800 {
+		nand_controller: nand-controller at 1800 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
@@ -597,7 +597,7 @@ nand-controller at 1800 {
 			reg-names = "nand", "nand-int-base";
 			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "nand_ctlrdy";
-			status = "okay";
+			status = "disabled";
 
 			nandcs: nand at 0 {
 				compatible = "brcm,nandcs";
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
index d658c81f7285..14b2adfb817c 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
@@ -138,6 +138,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
index 4f474d47022e..589b8a1efc72 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
@@ -119,6 +119,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
index 909f254dc47d..48d618e75866 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
@@ -137,6 +137,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
index 685ae32951c9..1d1303cf90f3 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
@@ -138,6 +138,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
index 820553ce541b..00c62c1e5df0 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
@@ -119,5 +119,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
index 0eb93c298297..caeaf428dc15 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
@@ -156,5 +156,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
index c4e6e71f6310..030ffa5364fb 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
index e69cd683211a..4b779e6c22e1 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
index db2c82d6dfd8..2851e8e41bf4 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
index 25c12bc63545..17dc594fe83f 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
index faba21f03120..34832a734734 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
index 9808331eede2..e1396b5544b7 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
index 1f561c8e13b0..30bbf6f2917e 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:52 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:52 -0800
Subject: [PATCH v5 07/12] mtd: rawnand: brcmnand: Rename bcm63138 nand driver
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-8-william.zhang@broadcom.com>

In preparing to support multiple BCMBCA SoCs, rename bcm63138 to bcmbca
in the driver code and driver file name.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>
Acked-by: Florian Fainelli <florian.fainelli at broadcom.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/mtd/nand/raw/brcmnand/Makefile        |  2 +-
 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c | 99 -------------------
 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c   | 99 +++++++++++++++++++
 3 files changed, 100 insertions(+), 100 deletions(-)
 delete mode 100644 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
 create mode 100644 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c

diff --git a/drivers/mtd/nand/raw/brcmnand/Makefile b/drivers/mtd/nand/raw/brcmnand/Makefile
index 9907e3ec4bb2..0536568c6467 100644
--- a/drivers/mtd/nand/raw/brcmnand/Makefile
+++ b/drivers/mtd/nand/raw/brcmnand/Makefile
@@ -2,7 +2,7 @@
 # link order matters; don't link the more generic brcmstb_nand.o before the
 # more specific iproc_nand.o, for instance
 obj-$(CONFIG_MTD_NAND_BRCMNAND_IPROC)	+= iproc_nand.o
-obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMBCA)	+= bcm63138_nand.o
+obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMBCA)	+= bcmbca_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND_BCM63XX)	+= bcm6368_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND_BRCMSTB)	+= brcmstb_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmnand.o
diff --git a/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c b/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
deleted file mode 100644
index 968c5b674b08..000000000000
--- a/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
+++ /dev/null
@@ -1,99 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright ? 2015 Broadcom Corporation
- */
-
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include "brcmnand.h"
-
-struct bcm63138_nand_soc {
-	struct brcmnand_soc soc;
-	void __iomem *base;
-};
-
-#define BCM63138_NAND_INT_STATUS		0x00
-#define BCM63138_NAND_INT_EN			0x04
-
-enum {
-	BCM63138_CTLRDY		= BIT(4),
-};
-
-static bool bcm63138_nand_intc_ack(struct brcmnand_soc *soc)
-{
-	struct bcm63138_nand_soc *priv =
-			container_of(soc, struct bcm63138_nand_soc, soc);
-	void __iomem *mmio = priv->base + BCM63138_NAND_INT_STATUS;
-	u32 val = brcmnand_readl(mmio);
-
-	if (val & BCM63138_CTLRDY) {
-		brcmnand_writel(val & ~BCM63138_CTLRDY, mmio);
-		return true;
-	}
-
-	return false;
-}
-
-static void bcm63138_nand_intc_set(struct brcmnand_soc *soc, bool en)
-{
-	struct bcm63138_nand_soc *priv =
-			container_of(soc, struct bcm63138_nand_soc, soc);
-	void __iomem *mmio = priv->base + BCM63138_NAND_INT_EN;
-	u32 val = brcmnand_readl(mmio);
-
-	if (en)
-		val |= BCM63138_CTLRDY;
-	else
-		val &= ~BCM63138_CTLRDY;
-
-	brcmnand_writel(val, mmio);
-}
-
-static int bcm63138_nand_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct bcm63138_nand_soc *priv;
-	struct brcmnand_soc *soc;
-
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-	soc = &priv->soc;
-
-	priv->base = devm_platform_ioremap_resource_byname(pdev, "nand-int-base");
-	if (IS_ERR(priv->base))
-		return PTR_ERR(priv->base);
-
-	soc->ctlrdy_ack = bcm63138_nand_intc_ack;
-	soc->ctlrdy_set_enabled = bcm63138_nand_intc_set;
-
-	return brcmnand_probe(pdev, soc);
-}
-
-static const struct of_device_id bcm63138_nand_of_match[] = {
-	{ .compatible = "brcm,nand-bcm63138" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, bcm63138_nand_of_match);
-
-static struct platform_driver bcm63138_nand_driver = {
-	.probe			= bcm63138_nand_probe,
-	.remove_new		= brcmnand_remove,
-	.driver = {
-		.name		= "bcm63138_nand",
-		.pm		= &brcmnand_pm_ops,
-		.of_match_table	= bcm63138_nand_of_match,
-	}
-};
-module_platform_driver(bcm63138_nand_driver);
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Brian Norris");
-MODULE_DESCRIPTION("NAND driver for BCM63138");
diff --git a/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
new file mode 100644
index 000000000000..3e2f3b79788d
--- /dev/null
+++ b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright ? 2015 Broadcom Corporation
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "brcmnand.h"
+
+struct bcmbca_nand_soc {
+	struct brcmnand_soc soc;
+	void __iomem *base;
+};
+
+#define BCMBCA_NAND_INT_STATUS		0x00
+#define BCMBCA_NAND_INT_EN			0x04
+
+enum {
+	BCMBCA_CTLRDY		= BIT(4),
+};
+
+static bool bcmbca_nand_intc_ack(struct brcmnand_soc *soc)
+{
+	struct bcmbca_nand_soc *priv =
+			container_of(soc, struct bcmbca_nand_soc, soc);
+	void __iomem *mmio = priv->base + BCMBCA_NAND_INT_STATUS;
+	u32 val = brcmnand_readl(mmio);
+
+	if (val & BCMBCA_CTLRDY) {
+		brcmnand_writel(val & ~BCMBCA_CTLRDY, mmio);
+		return true;
+	}
+
+	return false;
+}
+
+static void bcmbca_nand_intc_set(struct brcmnand_soc *soc, bool en)
+{
+	struct bcmbca_nand_soc *priv =
+			container_of(soc, struct bcmbca_nand_soc, soc);
+	void __iomem *mmio = priv->base + BCMBCA_NAND_INT_EN;
+	u32 val = brcmnand_readl(mmio);
+
+	if (en)
+		val |= BCMBCA_CTLRDY;
+	else
+		val &= ~BCMBCA_CTLRDY;
+
+	brcmnand_writel(val, mmio);
+}
+
+static int bcmbca_nand_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct bcmbca_nand_soc *priv;
+	struct brcmnand_soc *soc;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	soc = &priv->soc;
+
+	priv->base = devm_platform_ioremap_resource_byname(pdev, "nand-int-base");
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	soc->ctlrdy_ack = bcmbca_nand_intc_ack;
+	soc->ctlrdy_set_enabled = bcmbca_nand_intc_set;
+
+	return brcmnand_probe(pdev, soc);
+}
+
+static const struct of_device_id bcmbca_nand_of_match[] = {
+	{ .compatible = "brcm,nand-bcm63138" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcmbca_nand_of_match);
+
+static struct platform_driver bcmbca_nand_driver = {
+	.probe			= bcmbca_nand_probe,
+	.remove_new		= brcmnand_remove,
+	.driver = {
+		.name		= "bcmbca_nand",
+		.pm		= &brcmnand_pm_ops,
+		.of_match_table	= bcmbca_nand_of_match,
+	}
+};
+module_platform_driver(bcmbca_nand_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Brian Norris");
+MODULE_DESCRIPTION("NAND driver for BCMBCA");
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:51 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:51 -0800
Subject: [PATCH v5 06/12] arm64: dts: broadcom: bcmbca: Update router boards
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-7-william.zhang@broadcom.com>

Enable the nand controller and add WP pin connection property in actual
board dts as they are board level properties now that they are disabled
and moved out from SoC dtsi.

Also remove the unnecessary brcm,nand-has-wp property from AC5300 board.
This property is only needed for some old controller that this board
does not apply.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 .../boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts     | 5 +++++
 .../dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts  | 5 +++++
 .../boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts     | 6 +++++-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
index 78204d71ecd2..999d93730240 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
@@ -125,6 +125,11 @@ port at 7 {
 	};
 };
 
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
 &nandcs {
 	nand-ecc-strength = <4>;
 	nand-ecc-step-size = <512>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
index fcf092c81b59..19fc03ef47a0 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
@@ -155,6 +155,11 @@ port at 7 {
 	};
 };
 
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
 &nandcs {
 	nand-ecc-strength = <4>;
 	nand-ecc-step-size = <512>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
index d94a53d68320..52f928dbfa3c 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
@@ -166,11 +166,15 @@ led at 19 {
 	};
 };
 
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
 &nandcs {
 	nand-ecc-strength = <4>;
 	nand-ecc-step-size = <512>;
 	nand-on-flash-bbt;
-	brcm,nand-has-wp;
 
 	#address-cells = <1>;
 	#size-cells = <0>;
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:53 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:53 -0800
Subject: [PATCH v5 08/12] mtd: rawnand: brcmnand: Add BCMBCA read data bus interface
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-9-william.zhang@broadcom.com>

The BCMBCA broadband SoC integrates the NAND controller differently than
STB, iProc and other SoCs.  It has different endianness for NAND cache
data.

Add a SoC read data bus shim for BCMBCA to meet the specific SoC need
and performance improvement using the optimized memcpy function on NAND
cache memory.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v5: None
Changes in v4: None
Changes in v3:
- Updated bcmbca_read_data_bus comment

Changes in v2:
- Drop the is_param argument to the read data bus function now that we
have the exec_op API to read the parameter page and ONFI data
- Remove be32_to_cpu from brcmnand_read_data_bus

 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c | 27 +++++++++++++++++++++
 drivers/mtd/nand/raw/brcmnand/brcmnand.c    | 20 ++++++++++++---
 drivers/mtd/nand/raw/brcmnand/brcmnand.h    |  2 ++
 3 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
index 3e2f3b79788d..7ad3e7a98f97 100644
--- a/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
+++ b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
@@ -26,6 +26,18 @@ enum {
 	BCMBCA_CTLRDY		= BIT(4),
 };
 
+#if defined(CONFIG_ARM64)
+#define ALIGN_REQ		8
+#else
+#define ALIGN_REQ		4
+#endif
+
+static inline bool bcmbca_nand_is_buf_aligned(void *flash_cache,  void *buffer)
+{
+	return IS_ALIGNED((uintptr_t)buffer, ALIGN_REQ) &&
+				IS_ALIGNED((uintptr_t)flash_cache, ALIGN_REQ);
+}
+
 static bool bcmbca_nand_intc_ack(struct brcmnand_soc *soc)
 {
 	struct bcmbca_nand_soc *priv =
@@ -56,6 +68,20 @@ static void bcmbca_nand_intc_set(struct brcmnand_soc *soc, bool en)
 	brcmnand_writel(val, mmio);
 }
 
+static void bcmbca_read_data_bus(struct brcmnand_soc *soc,
+				 void __iomem *flash_cache,  u32 *buffer, int fc_words)
+{
+	/*
+	 * memcpy can do unaligned aligned access depending on source
+	 * and dest address, which is incompatible with nand cache. Fallback
+	 * to the memcpy_fromio in such case
+	 */
+	if (bcmbca_nand_is_buf_aligned((void *)flash_cache, buffer))
+		memcpy((void *)buffer, (void *)flash_cache, fc_words * 4);
+	else
+		memcpy_fromio((void *)buffer, flash_cache, fc_words * 4);
+}
+
 static int bcmbca_nand_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -73,6 +99,7 @@ static int bcmbca_nand_probe(struct platform_device *pdev)
 
 	soc->ctlrdy_ack = bcmbca_nand_intc_ack;
 	soc->ctlrdy_set_enabled = bcmbca_nand_intc_set;
+	soc->read_data_bus = bcmbca_read_data_bus;
 
 	return brcmnand_probe(pdev, soc);
 }
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 8faca43ae1ff..73fdf7ce21aa 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -851,6 +851,20 @@ static inline u32 edu_readl(struct brcmnand_controller *ctrl,
 	return brcmnand_readl(ctrl->edu_base + offs);
 }
 
+static inline void brcmnand_read_data_bus(struct brcmnand_controller *ctrl,
+					  void __iomem *flash_cache, u32 *buffer, int fc_words)
+{
+	struct brcmnand_soc *soc = ctrl->soc;
+	int i;
+
+	if (soc->read_data_bus) {
+		soc->read_data_bus(soc, flash_cache, buffer, fc_words);
+	} else {
+		for (i = 0; i < fc_words; i++)
+			buffer[i] = brcmnand_read_fc(ctrl, i);
+	}
+}
+
 static void brcmnand_clear_ecc_addr(struct brcmnand_controller *ctrl)
 {
 
@@ -1975,7 +1989,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	struct brcmnand_host *host = nand_get_controller_data(chip);
 	struct brcmnand_controller *ctrl = host->ctrl;
-	int i, j, ret = 0;
+	int i, ret = 0;
 
 	brcmnand_clear_ecc_addr(ctrl);
 
@@ -1988,8 +2002,8 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
 		if (likely(buf)) {
 			brcmnand_soc_data_bus_prepare(ctrl->soc, false);
 
-			for (j = 0; j < FC_WORDS; j++, buf++)
-				*buf = brcmnand_read_fc(ctrl, j);
+			brcmnand_read_data_bus(ctrl, ctrl->nand_fc, buf, FC_WORDS);
+			buf += FC_WORDS;
 
 			brcmnand_soc_data_bus_unprepare(ctrl->soc, false);
 		}
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.h b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
index 928114c0be5e..7261a69989fe 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
@@ -24,6 +24,8 @@ struct brcmnand_soc {
 	void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
 	void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
 				 bool is_param);
+	void (*read_data_bus)(struct brcmnand_soc *soc, void __iomem *flash_cache,
+				  u32 *buffer, int fc_words);
 	const struct brcmnand_io_ops *ops;
 };
 
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:55 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:55 -0800
Subject: [PATCH v5 10/12] mtd: rawnand: brcmnand: Support write protection setting from dts
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-11-william.zhang@broadcom.com>

The write protection feature is controlled by the module parameter wp_on
with default set to enabled. But not all the board use this feature
especially in BCMBCA broadband board. And module parameter is not
sufficient as different board can have different option.  Add a device
tree property and allow this feature to be configured through the board
dts on per board basis.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
Reviewed-by: Kamal Dasu <kamal.dasu at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v5: None
Changes in v4:
- Use the new brcm,wp-not-connected property based on the dts binding
change

Changes in v3: None
Changes in v2: None

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index efeee9e80213..8c1489ff7bd6 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -3218,6 +3218,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 	/* Disable XOR addressing */
 	brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0);
 
+	/* Check if the board connects the WP pin */
+	if (of_property_read_bool(dn, "brcm,wp-not-connected"))
+		wp_on = 0;
+
 	if (ctrl->features & BRCMNAND_HAS_WP) {
 		/* Permanently disable write protection */
 		if (wp_on == 2)
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:56 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:56 -0800
Subject: [PATCH v5 11/12] mtd: rawnand: brcmnand: exec_op helper functions return type fixes
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-12-william.zhang@broadcom.com>

From: David Regan <dregan at broadcom.com>

fix return type for exec_op reset and status detect helper functions

Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
Signed-off-by: David Regan <dregan at broadcom.com>
Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v5: None
Changes in v4:
- Fix the commit id in the fixes tag

Changes in v3: None
Changes in v2:
- Added to patch series

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 8c1489ff7bd6..7ce2b267676f 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -625,7 +625,7 @@ enum {
 /* Only for v7.2 */
 #define	ACC_CONTROL_ECC_EXT_SHIFT		13
 
-static u8 brcmnand_status(struct brcmnand_host *host);
+static int brcmnand_status(struct brcmnand_host *host);
 
 static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
 {
@@ -1749,7 +1749,7 @@ static int brcmnand_waitfunc(struct nand_chip *chip)
 				 INTFC_FLASH_STATUS;
 }
 
-static u8 brcmnand_status(struct brcmnand_host *host)
+static int brcmnand_status(struct brcmnand_host *host)
 {
 	struct nand_chip *chip = &host->chip;
 	struct mtd_info *mtd = nand_to_mtd(chip);
@@ -1760,7 +1760,7 @@ static u8 brcmnand_status(struct brcmnand_host *host)
 	return brcmnand_waitfunc(chip);
 }
 
-static u8 brcmnand_reset(struct brcmnand_host *host)
+static int brcmnand_reset(struct brcmnand_host *host)
 {
 	struct nand_chip *chip = &host->chip;
 
@@ -2492,11 +2492,14 @@ static int brcmnand_exec_op(struct nand_chip *chip,
 
 	if (brcmnand_op_is_status(op)) {
 		status = op->instrs[1].ctx.data.buf.in;
-		*status = brcmnand_status(host);
+		ret = brcmnand_status(host);
+		if (ret < 0)
+			return ret;
+
+		*status = ret & 0xFF;
 
 		return 0;
-	}
-	else if (brcmnand_op_is_reset(op)) {
+	} else if (brcmnand_op_is_reset(op)) {
 		ret = brcmnand_reset(host);
 		if (ret < 0)
 			return ret;
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:54 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:54 -0800
Subject: [PATCH v5 09/12] mtd: rawnand: brcmnand: Add support for getting ecc setting from strap
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-10-william.zhang@broadcom.com>

BCMBCA broadband SoC based board design does not specify ecc setting in
dts but rather use the SoC NAND strap info to obtain the ecc strength
and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
this purpose and update driver to support this option.

The generic nand ecc settings still take precedence over this flag. For
example, if nand-ecc-strength is set in the dts, the driver ignores the
strap setting and falls back to original behavior. This makes sure that
the existing BCMBCA board dts still works the old way even the strap
flag is set in the BCMBCA chip dtsi.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v5: None
Changes in v4:
- Update the comments for ecc setting selection

Changes in v3: None
Changes in v2:
- Minor cosmetic fixes

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 83 ++++++++++++++++++++++--
 1 file changed, 76 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 73fdf7ce21aa..efeee9e80213 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1038,6 +1038,19 @@ static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl)
 		return -1;
 }
 
+static int brcmnand_get_sector_size_1k(struct brcmnand_host *host)
+{
+	struct brcmnand_controller *ctrl = host->ctrl;
+	int shift = brcmnand_sector_1k_shift(ctrl);
+	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+						  BRCMNAND_CS_ACC_CONTROL);
+
+	if (shift < 0)
+		return 0;
+
+	return (nand_readreg(ctrl, acc_control_offs) >> shift) & 0x1;
+}
+
 static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
 {
 	struct brcmnand_controller *ctrl = host->ctrl;
@@ -1055,6 +1068,38 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
 	nand_writereg(ctrl, acc_control_offs, tmp);
 }
 
+static int brcmnand_get_spare_size(struct brcmnand_host *host)
+{
+	struct brcmnand_controller *ctrl = host->ctrl;
+	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+						  BRCMNAND_CS_ACC_CONTROL);
+	u32 acc = nand_readreg(ctrl, acc_control_offs);
+
+	return (acc & brcmnand_spare_area_mask(ctrl));
+}
+
+static int brcmnand_get_ecc_strength(struct brcmnand_host *host)
+{
+	struct brcmnand_controller *ctrl = host->ctrl;
+	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+						  BRCMNAND_CS_ACC_CONTROL);
+	int sector_size_1k = brcmnand_get_sector_size_1k(host);
+	int spare_area_size, ecc_level, ecc_strength;
+	u32 acc;
+
+	spare_area_size = brcmnand_get_spare_size(host);
+	acc = nand_readreg(ctrl, acc_control_offs);
+	ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl->ecc_level_shift;
+	if (sector_size_1k)
+		ecc_strength = ecc_level * 2;
+	else if (spare_area_size == 16 && ecc_level == 15)
+		ecc_strength = 1; /* hamming */
+	else
+		ecc_strength = ecc_level;
+
+	return ecc_strength;
+}
+
 /***********************************************************************
  * CS_NAND_SELECT
  ***********************************************************************/
@@ -2622,19 +2667,43 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
 		nanddev_get_memorg(&chip->base);
 	struct brcmnand_controller *ctrl = host->ctrl;
 	struct brcmnand_cfg *cfg = &host->hwcfg;
-	char msg[128];
+	struct device_node *np = nand_get_flash_node(chip);
 	u32 offs, tmp, oob_sector;
-	int ret;
+	int ret, sector_size_1k = 0;
+	bool use_strap = false;
+	char msg[128];
 
 	memset(cfg, 0, sizeof(*cfg));
+	use_strap = of_property_read_bool(np, "brcm,nand-ecc-use-strap");
 
-	ret = of_property_read_u32(nand_get_flash_node(chip),
-				   "brcm,nand-oob-sector-size",
+	/*
+	 * Set ECC size and strength based on hw configuration from strap
+	 * if brcm,nand-ecc-use-strap is set. However if nand-ecc-strength
+	 * is set, its value will be used and ignore the strap setting.
+	 */
+	if (chip->ecc.strength)
+		use_strap = 0;
+
+	if (use_strap) {
+		chip->ecc.strength = brcmnand_get_ecc_strength(host);
+		sector_size_1k = brcmnand_get_sector_size_1k(host);
+		if (chip->ecc.size == 0) {
+			if (sector_size_1k < 0)
+				chip->ecc.size = 512;
+			else
+				chip->ecc.size = 512 << sector_size_1k;
+		}
+	}
+
+	ret = of_property_read_u32(np, "brcm,nand-oob-sector-size",
 				   &oob_sector);
 	if (ret) {
-		/* Use detected size */
-		cfg->spare_area_size = mtd->oobsize /
-					(mtd->writesize >> FC_SHIFT);
+		if (use_strap)
+			cfg->spare_area_size = brcmnand_get_spare_size(host);
+		else
+			/* Use detected size */
+			cfg->spare_area_size = mtd->oobsize /
+						(mtd->writesize >> FC_SHIFT);
 	} else {
 		cfg->spare_area_size = oob_sector;
 	}
-- 
2.37.3



From william.zhang at broadcom.com  Wed Feb  7 12:22:57 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed,  7 Feb 2024 12:22:57 -0800
Subject: [PATCH v5 12/12] mtd: rawnand: brcmnand: update log level messages
In-Reply-To: <20240207202257.271784-1-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
Message-ID: <20240207202257.271784-13-william.zhang@broadcom.com>

From: David Regan <dregan at broadcom.com>

Update log level messages so that more critical messages can be logged
to console and help the troubleshooting with field devices.

Signed-off-by: David Regan <dregan at broadcom.com>
Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v5:
- Update the commit message

Changes in v4:
- Revert the log level change for correctable ecc error

Changes in v3: None
Changes in v2:
- Added to patch series

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 7ce2b267676f..e50582b45182 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1143,7 +1143,7 @@ static int bcmnand_ctrl_poll_status(struct brcmnand_host *host,
 	if ((val & mask) == expected_val)
 		return 0;
 
-	dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
+	dev_err(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
 		 expected_val, val & mask);
 
 	return -ETIMEDOUT;
@@ -2196,7 +2196,7 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
 				return err;
 		}
 
-		dev_dbg(ctrl->dev, "uncorrectable error at 0x%llx\n",
+		dev_err(ctrl->dev, "uncorrectable error at 0x%llx\n",
 			(unsigned long long)err_addr);
 		mtd->ecc_stats.failed++;
 		/* NAND layer expects zero on ECC errors */
-- 
2.37.3



From ankita at nvidia.com  Wed Feb  7 12:46:48 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Thu, 8 Feb 2024 02:16:48 +0530
Subject: [PATCH v6 0/4] kvm: arm64: allow the VM to select DEVICE_* and NORMAL_NC for IO memory
Message-ID: <20240207204652.22954-1-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

Currently, KVM for ARM64 maps at stage 2 memory that is considered device
with DEVICE_nGnRE memory attributes; this setting overrides (per
ARM architecture [1]) any device MMIO mapping present at stage 1,
resulting in a set-up whereby a guest operating system cannot
determine device MMIO mapping memory attributes on its own but
it is always overridden by the KVM stage 2 default.

This set-up does not allow guest operating systems to select device
memory attributes independently from KVM stage-2 mappings
(refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
which turns out to be an issue in that guest operating systems
(e.g. Linux) may request to map devices MMIO regions with memory
attributes that guarantee better performance (e.g. gathering
attribute - that for some devices can generate larger PCIe memory
writes TLPs) and specific operations (e.g. unaligned transactions)
such as the NormalNC memory type.

The default device stage 2 mapping was chosen in KVM for ARM64 since
it was considered safer (i.e. it would not allow guests to trigger
uncontained failures ultimately crashing the machine) but this
turned out to be asynchronous (SError) defeating the purpose.

For these reasons, relax the KVM stage 2 device memory attributes
from DEVICE_nGnRE to Normal-NC.

Generalizing to other devices may be problematic, however. E.g.
GICv2 VCPU interface, which is effectively a shared peripheral, can
allow a guest to affect another guest's interrupt distribution. Hence
limit the change to VFIO PCI as caution. This is achieved by
making the VFIO PCI core module set a flag that is tested by KVM
to activate the code. This could be extended to other devices in
the future once that is deemed safe.

[1] section D8.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf

Applied over v6.8-rc2.

History
=======
v5 -> v6
- Rebased to v6.8-rc2

v4 -> v5
- Moved the cover letter description text to patch 1/4.
- Cleaned up stage2_set_prot_attr() based on Marc Zyngier suggestions.
- Moved the mm header file changes to a separate patch.
- Rebased to v6.7-rc3.

v3 -> v4
- Moved the vfio-pci change to use the VM_VFIO_ALLOW_WC into
  separate patch.
- Added check to warn on the case NORMAL_NC and DEVICE are
  set simultaneously.
- Fixed miscellaneous nitpicks suggested in v3.

v2 -> v3
- Added a new patch (and converted to patch series) suggested by
  Catalin Marinas to ensure the code changes are restricted to
  VFIO PCI devices.
- Introduced VM_VFIO_ALLOW_WC flag for VFIO PCI to communicate
  with VMM.
- Reverted GIC mapping to DEVICE.

v1 -> v2
- Updated commit log to the one posted by
  Lorenzo Pieralisi <lpieralisi at kernel.org> (Thanks!)
- Added new flag to represent the NORMAL_NC setting. Updated
  stage2_set_prot_attr() to handle new flag.

v5 Link:
https://lore.kernel.org/all/20231221154002.32622-1-ankita at nvidia.com/

Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>

Ankit Agrawal (4):
  kvm: arm64: introduce new flag for non-cacheable IO memory
  mm: introduce new flag to indicate wc safe
  kvm: arm64: set io memory s2 pte as normalnc for vfio pci device
  vfio: convey kvm that the vfio-pci device is wc safe

 arch/arm64/include/asm/kvm_pgtable.h |  2 ++
 arch/arm64/include/asm/memory.h      |  2 ++
 arch/arm64/kvm/hyp/pgtable.c         | 23 ++++++++++++++++++-----
 arch/arm64/kvm/mmu.c                 | 18 ++++++++++++++----
 drivers/vfio/pci/vfio_pci_core.c     |  3 ++-
 include/linux/mm.h                   | 14 ++++++++++++++
 6 files changed, 52 insertions(+), 10 deletions(-)

-- 
2.34.1



From ankita at nvidia.com  Wed Feb  7 12:46:49 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Thu, 8 Feb 2024 02:16:49 +0530
Subject: [PATCH v6 1/4] kvm: arm64: introduce new flag for non-cacheable IO memory
In-Reply-To: <20240207204652.22954-1-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
Message-ID: <20240207204652.22954-2-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

Currently, KVM for ARM64 maps at stage 2 memory that is considered device
(i.e. it is not RAM) with DEVICE_nGnRE memory attributes; this setting
overrides (as per the ARM architecture [1]) any device MMIO mapping
present at stage 1, resulting in a set-up whereby a guest operating
system cannot determine device MMIO mapping memory attributes on its
own but it is always overridden by the KVM stage 2 default.

This set-up does not allow guest operating systems to select device
memory attributes independently from KVM stage-2 mappings
(refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
which turns out to be an issue in that guest operating systems
(e.g. Linux) may request to map devices MMIO regions with memory
attributes that guarantee better performance (e.g. gathering
attribute - that for some devices can generate larger PCIe memory
writes TLPs) and specific operations (e.g. unaligned transactions)
such as the NormalNC memory type.

The default device stage 2 mapping was chosen in KVM for ARM64 since
it was considered safer (i.e. it would not allow guests to trigger
uncontained failures ultimately crashing the machine) but this
turned out to be asynchronous (SError) defeating the purpose.

Failures containability is a property of the platform and is independent
from the memory type used for MMIO device memory mappings.

Actually, DEVICE_nGnRE memory type is even more problematic than
Normal-NC memory type in terms of faults containability in that e.g.
aborts triggered on DEVICE_nGnRE loads cannot be made, architecturally,
synchronous (i.e. that would imply that the processor should issue at
most 1 load transaction at a time - it cannot pipeline them - otherwise
the synchronous abort semantics would break the no-speculation attribute
attached to DEVICE_XXX memory).

This means that regardless of the combined stage1+stage2 mappings a
platform is safe if and only if device transactions cannot trigger
uncontained failures and that in turn relies on platform capabilities
and the device type being assigned (i.e. PCIe AER/DPC error containment
and RAS architecture[3]); therefore the default KVM device stage 2
memory attributes play no role in making device assignment safer
for a given platform (if the platform design adheres to design
guidelines outlined in [3]) and therefore can be relaxed.

For all these reasons, relax the KVM stage 2 device memory attributes
from DEVICE_nGnRE to Normal-NC.

The NormalNC was chosen over a different Normal memory type default
at stage-2 (e.g. Normal Write-through) to avoid cache allocation/snooping.

Relaxing S2 KVM device MMIO mappings to Normal-NC is not expected to
trigger any issue on guest device reclaim use cases either (i.e. device
MMIO unmap followed by a device reset) at least for PCIe devices, in that
in PCIe a device reset is architected and carried out through PCI config
space transactions that are naturally ordered with respect to MMIO
transactions according to the PCI ordering rules.

Having Normal-NC S2 default puts guests in control (thanks to
stage1+stage2 combined memory attributes rules [1]) of device MMIO
regions memory mappings, according to the rules described in [1]
and summarized here ([(S1) - stage1], [(S2) - stage 2]):

S1           |  S2           | Result
NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>

It is worth noting that currently, to map devices MMIO space to user
space in a device pass-through use case the VFIO framework applies memory
attributes derived from pgprot_noncached() settings applied to VMAs, which
result in device-nGnRnE memory attributes for the stage-1 VMM mappings.

This means that a userspace mapping for device MMIO space carried
out with the current VFIO framework and a guest OS mapping for the same
MMIO space may result in a mismatched alias as described in [2].

Defaulting KVM device stage-2 mappings to Normal-NC attributes does not
change anything in this respect, in that the mismatched aliases would
only affect (refer to [2] for a detailed explanation) ordering between
the userspace and GuestOS mappings resulting stream of transactions
(i.e. it does not cause loss of property for either stream of
transactions on its own), which is harmless given that the userspace
and GuestOS access to the device is carried out through independent
transactions streams.

A Normal-NC flag is not present today. So add a new kvm_pgtable_prot
(KVM_PGTABLE_PROT_NORMAL_NC) flag for it, along with its
corresponding PTE value 0x5 (0b101) determined from [1].

Lastly, adapt the stage2 PTE property setter function
(stage2_set_prot_attr) to handle the NormalNC attribute.

[1] section D8.5.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
[2] section B2.8 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
[3] sections 1.7.7.3/1.8.5.2/appendix C - DEN0029H_SBSA_7.1.pdf

Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
---
 arch/arm64/include/asm/kvm_pgtable.h |  2 ++
 arch/arm64/include/asm/memory.h      |  2 ++
 arch/arm64/kvm/hyp/pgtable.c         | 23 ++++++++++++++++++-----
 3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index cfdf40f734b1..19278dfe7978 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -197,6 +197,7 @@ enum kvm_pgtable_stage2_flags {
  * @KVM_PGTABLE_PROT_W:		Write permission.
  * @KVM_PGTABLE_PROT_R:		Read permission.
  * @KVM_PGTABLE_PROT_DEVICE:	Device attributes.
+ * @KVM_PGTABLE_PROT_NORMAL_NC:	Normal noncacheable attributes.
  * @KVM_PGTABLE_PROT_SW0:	Software bit 0.
  * @KVM_PGTABLE_PROT_SW1:	Software bit 1.
  * @KVM_PGTABLE_PROT_SW2:	Software bit 2.
@@ -208,6 +209,7 @@ enum kvm_pgtable_prot {
 	KVM_PGTABLE_PROT_R			= BIT(2),
 
 	KVM_PGTABLE_PROT_DEVICE			= BIT(3),
+	KVM_PGTABLE_PROT_NORMAL_NC		= BIT(4),
 
 	KVM_PGTABLE_PROT_SW0			= BIT(55),
 	KVM_PGTABLE_PROT_SW1			= BIT(56),
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index d82305ab420f..449ca2ff1df6 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -173,6 +173,7 @@
  * Memory types for Stage-2 translation
  */
 #define MT_S2_NORMAL		0xf
+#define MT_S2_NORMAL_NC		0x5
 #define MT_S2_DEVICE_nGnRE	0x1
 
 /*
@@ -180,6 +181,7 @@
  * Stage-2 enforces Normal-WB and Device-nGnRE
  */
 #define MT_S2_FWB_NORMAL	6
+#define MT_S2_FWB_NORMAL_NC	5
 #define MT_S2_FWB_DEVICE_nGnRE	1
 
 #ifdef CONFIG_ARM64_4K_PAGES
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index c651df904fe3..2a893724ee9b 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -717,15 +717,28 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
 static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
 				kvm_pte_t *ptep)
 {
-	bool device = prot & KVM_PGTABLE_PROT_DEVICE;
-	kvm_pte_t attr = device ? KVM_S2_MEMATTR(pgt, DEVICE_nGnRE) :
-			    KVM_S2_MEMATTR(pgt, NORMAL);
+	kvm_pte_t attr;
 	u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS;
 
+	switch (prot & (KVM_PGTABLE_PROT_DEVICE |
+			KVM_PGTABLE_PROT_NORMAL_NC)) {
+	case 0:
+		attr = KVM_S2_MEMATTR(pgt, NORMAL);
+		break;
+	case KVM_PGTABLE_PROT_DEVICE:
+		if (prot & KVM_PGTABLE_PROT_X)
+			return -EINVAL;
+		attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
+		break;
+	case KVM_PGTABLE_PROT_NORMAL_NC:
+		attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
+		break;
+	default:
+		WARN_ON_ONCE(1);
+	}
+
 	if (!(prot & KVM_PGTABLE_PROT_X))
 		attr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
-	else if (device)
-		return -EINVAL;
 
 	if (prot & KVM_PGTABLE_PROT_R)
 		attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
-- 
2.34.1



From ankita at nvidia.com  Wed Feb  7 12:46:50 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Thu, 8 Feb 2024 02:16:50 +0530
Subject: [PATCH v6 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <20240207204652.22954-1-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
Message-ID: <20240207204652.22954-3-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

Generalizing S2 setting from DEVICE_nGnRE to NormalNc for non PCI
devices may be problematic. E.g. GICv2 vCPU interface, which is
effectively a shared peripheral, can allow a guest to affect another
guest's interrupt distribution. The issue may be solved by limiting
the relaxation to mappings that have a user VMA. Still there is
insufficient information and uncertainity in the behavior of
non PCI drivers.

Add a new flag VM_VFIO_ALLOW_WC to indicate KVM that the device is
WC capable and these S2 changes can be extended to it. KVM can use
this flag to activate the code.

Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Jason Gunthorpe <jgg at nvidia.com>
---
 include/linux/mm.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index f5a97dec5169..884c068a79eb 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -391,6 +391,20 @@ extern unsigned int kobjsize(const void *objp);
 # define VM_UFFD_MINOR		VM_NONE
 #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
 
+/*
+ * This flag is used to connect VFIO to arch specific KVM code. It
+ * indicates that the memory under this VMA is safe for use with any
+ * non-cachable memory type inside KVM. Some VFIO devices, on some
+ * platforms, are thought to be unsafe and can cause machine crashes if
+ * KVM does not lock down the memory type.
+ */
+#ifdef CONFIG_64BIT
+#define VM_VFIO_ALLOW_WC_BIT	39
+#define VM_VFIO_ALLOW_WC	BIT(VM_VFIO_ALLOW_WC_BIT)
+#else
+#define VM_VFIO_ALLOW_WC	VM_NONE
+#endif
+
 /* Bits set in the VMA until the stack is in its final location */
 #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
 
-- 
2.34.1



From ankita at nvidia.com  Wed Feb  7 12:46:51 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Thu, 8 Feb 2024 02:16:51 +0530
Subject: [PATCH v6 3/4] kvm: arm64: set io memory s2 pte as normalnc for vfio pci device
In-Reply-To: <20240207204652.22954-1-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
Message-ID: <20240207204652.22954-4-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

To provide VM with the ability to get device IO memory with NormalNC
property, map device MMIO in KVM for ARM64 at stage2 as NormalNC.
Having NormalNC S2 default puts guests in control (based on [1],
"Combining stage 1 and stage 2 memory type attributes") of device
MMIO regions memory mappings. The rules are summarized below:
([(S1) - stage1], [(S2) - stage 2])

S1           |  S2           | Result
NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>

Still this cannot be generalized to non PCI devices such as GICv2.
There is insufficient information and uncertainity in the behavior
of non PCI driver. A driver must indicate support using the
new flag VM_VFIO_ALLOW_WC.

Adapt KVM to make use of the flag VM_VFIO_ALLOW_WC as indicator to
activate the S2 setting to NormalNc.

[1] section D8.5.5 of DDI0487J_a_a-profile_architecture_reference_manual.pdf

Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Jason Gunthorpe <jgg at nvidia.com>
---
 arch/arm64/kvm/mmu.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index d14504821b79..e1e6847a793b 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1381,7 +1381,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	int ret = 0;
 	bool write_fault, writable, force_pte = false;
 	bool exec_fault, mte_allowed;
-	bool device = false;
+	bool device = false, vfio_allow_wc = false;
 	unsigned long mmu_seq;
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
@@ -1472,6 +1472,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	gfn = fault_ipa >> PAGE_SHIFT;
 	mte_allowed = kvm_vma_mte_allowed(vma);
 
+	vfio_allow_wc = (vma->vm_flags & VM_VFIO_ALLOW_WC);
+
 	/* Don't use the VMA after the unlock -- it may have vanished */
 	vma = NULL;
 
@@ -1557,10 +1559,18 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	if (exec_fault)
 		prot |= KVM_PGTABLE_PROT_X;
 
-	if (device)
-		prot |= KVM_PGTABLE_PROT_DEVICE;
-	else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
+	if (device) {
+		/*
+		 * To provide VM with the ability to get device IO memory
+		 * with NormalNC property, map device MMIO as NormalNC in S2.
+		 */
+		if (vfio_allow_wc)
+			prot |= KVM_PGTABLE_PROT_NORMAL_NC;
+		else
+			prot |= KVM_PGTABLE_PROT_DEVICE;
+	} else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) {
 		prot |= KVM_PGTABLE_PROT_X;
+	}
 
 	/*
 	 * Under the premise of getting a FSC_PERM fault, we just need to relax
-- 
2.34.1



From ankita at nvidia.com  Wed Feb  7 12:46:52 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Thu, 8 Feb 2024 02:16:52 +0530
Subject: [PATCH v6 4/4] vfio: convey kvm that the vfio-pci device is wc safe
In-Reply-To: <20240207204652.22954-1-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
Message-ID: <20240207204652.22954-5-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

The code to map the MMIO in S2 as NormalNC is enabled when conveyed
that the device is WC safe using a new flag VM_VFIO_ALLOW_WC.

Make vfio-pci set the VM_VFIO_ALLOW_WC flag.

This could be extended to other devices in the future once that
is deemed safe.

Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/vfio/pci/vfio_pci_core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 1cbc990d42e0..c3f95ec7fc3a 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1863,7 +1863,8 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
 	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
 	 * change vm_flags within the fault handler.  Set them now.
 	 */
-	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+	vm_flags_set(vma, VM_VFIO_ALLOW_WC | VM_IO | VM_PFNMAP |
+			VM_DONTEXPAND | VM_DONTDUMP);
 	vma->vm_ops = &vfio_pci_mmap_ops;
 
 	return 0;
-- 
2.34.1



From quic_obabatun at quicinc.com  Wed Feb  7 13:13:13 2024
From: quic_obabatun at quicinc.com (Oreoluwa Babatunde)
Date: Wed, 7 Feb 2024 13:13:13 -0800
Subject: [PATCH 00/46] Dynamic allocation of reserved_mem array.
In-Reply-To: <20240202152908.GA4045321-robh@kernel.org>
References: <20240126235425.12233-1-quic_obabatun@quicinc.com>
 <20240131000710.GA2581425-robh@kernel.org>
 <51dc64bb-3101-4b4a-a54f-c0df6c0b264c@quicinc.com>
 <20240201194653.GA1328565-robh@kernel.org>
 <d98288ed-a0d9-4fc1-87bc-d79cb528778c@quicinc.com>
 <20240202152908.GA4045321-robh@kernel.org>
Message-ID: <c9c3c7a0-9699-496e-a277-a1be6142ceb8@quicinc.com>


On 2/2/2024 7:29 AM, Rob Herring wrote:
> On Thu, Feb 01, 2024 at 01:10:18PM -0800, Oreoluwa Babatunde wrote:
>> On 2/1/2024 11:46 AM, Rob Herring wrote:
>>> On Thu, Feb 01, 2024 at 09:08:06AM -0800, Oreoluwa Babatunde wrote:
>>>> On 1/30/2024 4:07 PM, Rob Herring wrote:
>>>>> On Fri, Jan 26, 2024 at 03:53:39PM -0800, Oreoluwa Babatunde wrote:
>>>>>> The reserved_mem array is used to store data for the different
>>>>>> reserved memory regions defined in the DT of a device.  The array
>>>>>> stores information such as region name, node, start-address, and size
>>>>>> of the reserved memory regions.
>>>>>>
>>>>>> The array is currently statically allocated with a size of
>>>>>> MAX_RESERVED_REGIONS(64). This means that any system that specifies a
>>>>>> number of reserved memory regions greater than MAX_RESERVED_REGIONS(64)
>>>>>> will not have enough space to store the information for all the regions.
>>>>>>
>>>>>> Therefore, this series extends the use of the static array for
>>>>>> reserved_mem, and introduces a dynamically allocated array using
>>>>>> memblock_alloc() based on the number of reserved memory regions
>>>>>> specified in the DT.
>>>>>>
>>>>>> Some architectures such as arm64 require the page tables to be setup
>>>>>> before memblock allocated memory is writable.  Therefore, the dynamic
>>>>>> allocation of the reserved_mem array will need to be done after the
>>>>>> page tables have been setup on these architectures. In most cases that
>>>>>> will be after paging_init().
>>>>>>
>>>>>> Reserved memory regions can be divided into 2 groups.
>>>>>> i) Statically-placed reserved memory regions
>>>>>> i.e. regions defined in the DT using the @reg property.
>>>>>> ii) Dynamically-placed reserved memory regions.
>>>>>> i.e. regions specified in the DT using the @alloc_ranges
>>>>>>     and @size properties.
>>>>>>
>>>>>> It is possible to call memblock_reserve() and memblock_mark_nomap() on
>>>>>> the statically-placed reserved memory regions and not need to save them
>>>>>> to the reserved_mem array until memory is allocated for it using
>>>>>> memblock, which will be after the page tables have been setup.
>>>>>> For the dynamically-placed reserved memory regions, it is not possible
>>>>>> to wait to store its information because the starting address is
>>>>>> allocated only at run time, and hence they need to be stored somewhere
>>>>>> after they are allocated.
>>>>>> Waiting until after the page tables have been setup to allocate memory
>>>>>> for the dynamically-placed regions is also not an option because the
>>>>>> allocations will come from memory that have already been added to the
>>>>>> page tables, which is not good for memory that is supposed to be
>>>>>> reserved and/or marked as nomap.
>>>>>>
>>>>>> Therefore, this series splits up the processing of the reserved memory
>>>>>> regions into two stages, of which the first stage is carried out by
>>>>>> early_init_fdt_scan_reserved_mem() and the second is carried out by
>>>>>> fdt_init_reserved_mem().
>>>>>>
>>>>>> The early_init_fdt_scan_reserved_mem(), which is called before the page
>>>>>> tables are setup is used to:
>>>>>> 1. Call memblock_reserve() and memblock_mark_nomap() on all the
>>>>>>    statically-placed reserved memory regions as needed.
>>>>>> 2. Allocate memory from memblock for the dynamically-placed reserved
>>>>>>    memory regions and store them in the static array for reserved_mem.
>>>>>>    memblock_reserve() and memblock_mark_nomap() are also called as
>>>>>>    needed on all the memory allocated for the dynamically-placed
>>>>>>    regions.
>>>>>> 3. Count the total number of reserved memory regions found in the DT.
>>>>>>
>>>>>> fdt_init_reserved_mem(), which should be called after the page tables
>>>>>> have been setup, is used to carry out the following:
>>>>>> 1. Allocate memory for the reserved_mem array based on the number of
>>>>>>    reserved memory regions counted as mentioned above.
>>>>>> 2. Copy all the information for the dynamically-placed reserved memory
>>>>>>    regions from the static array into the new allocated memory for the
>>>>>>    reserved_mem array.
>>>>>> 3. Add the information for the statically-placed reserved memory into
>>>>>>    reserved_mem array.
>>>>>> 4. Run the region specific init functions for each of the reserve memory
>>>>>>    regions saved in the reserved_mem array.
>>>>> I don't see the need for fdt_init_reserved_mem() to be explicitly called 
>>>>> by arch code. I said this already, but that can be done at the same time 
>>>>> as unflattening the DT. The same conditions are needed for both: we need 
>>>>> to be able to allocate memory from memblock.
>>>>>
>>>>> To put it another way, if fdt_init_reserved_mem() can be called "early", 
>>>>> then unflattening could be moved earlier as well. Though I don't think 
>>>>> we should optimize that. I'd rather see all arches call the DT functions 
>>>>> at the same stages.
>>>> Hi Rob,
>>>>
>>>> The reason we moved fdt_init_reserved_mem() back into the arch specific code
>>>> was because we realized that there was no apparently obvious way to call
>>>> early_init_fdt_scan_reserved_mem() and fdt_init_reserved_mem() in the correct
>>>> order that will work for all archs if we placed fdt_init_reserved_mem() inside the
>>>> unflatten_devicetree() function.
>>>>
>>>> early_init_fdt_scan_reserved_mem() needs to be
>>>> called first before fdt_init_reserved_mem(). But on some archs,
>>>> unflatten_devicetree() is called before early_init_fdt_scan_reserved_mem(), which
>>>> means that if we have fdt_init_reserved_mem() inside the unflatten_devicetree()
>>>> function, it will be called before early_init_fdt_scan_reserved_mem().
>>>>
>>>> This is connected to your other comments on Patch 7 & Patch 14.
>>>> I agree, unflatten_devicetree() should NOT be getting called before we reserve
>>>> memory for the reserved memory regions because that could cause memory to be
>>>> allocated from regions that should be reserved.
>>>>
>>>> Hence, resolving this issue should allow us to call fdt_init_reserved_mem() from
>>>> the? unflatten_devicetree() function without it changing the order that we are
>>>> trying to have.
>>> There's one issue I've found which is unflatten_device_tree() isn't 
>>> called for ACPI case on arm64. Turns out we need /reserved-memory 
>>> handled in that case too. However, I think we're going to change 
>>> calling unflatten_device_tree() unconditionally for another reason[1]. 
>>>
>>> [1] https://lore.kernel.org/all/efe6a7886c3491cc9c225a903efa2b1e.sboyd at kernel.org/
>>>
>>>> I will work on implementing this and send another revision.
>>> I think we should go with a simpler route that's just copy the an 
>>> initial array in initdata to a properly sized, allocated array like the 
>>> patch below. Of course it will need some arch fixes and a follow-on 
>>> patch to increase the initial array size.
>>>
>>> 8<--------------------------------------------------------------------
>>> From: Rob Herring <robh at kernel.org>
>>> Date: Wed, 31 Jan 2024 16:26:23 -0600
>>> Subject: [PATCH] of: reserved-mem: Re-allocate reserved_mem array to actual
>>>  size
>>>
>>> In preparation to increase the static reserved_mem array size yet again,
>>> copy the initial array to an allocated array sized based on the actual
>>> size needed. Now increasing the the size of the static reserved_mem
>>> array only eats up the initdata space. For platforms with reasonable
>>> number of reserved regions, we have a net gain in free memory.
>>>
>>> In order to do memblock allocations, fdt_init_reserved_mem() is moved a
>>> bit later to unflatten_device_tree(). On some arches this is effectively
>>> a nop.
> [...]
>
>> Hi Rob,
>>
>> One thing that could come up with this is that? memory
>> for the dynamically-placed reserved memory regions
>> won't be allocated until we call fdt_init_reserved_mem().
>> (i.e. reserved memory regions defined using @alloc-ranges
>> and @size properties)
>>
>> Since fdt_init_reserved_mem() is now being called from
>> unflatten_device_tree(), the page tables would have been
>> setup on most architectures, which means we will be
>> allocating from memory that have already been mapped.
>>
>> Could this be an issue for memory that is supposed to be
>> reserved? 
> I suppose if the alloc-ranges region is not much bigger than the size 
> and the kernel already made some allocation that landed in the region, 
> then the allocation could fail. Not much we can do other than alloc the 
> reserved regions as soon as possible. Are there cases where that's not 
> happening?
Correct, the best thing we can do here is to make sure we allocate the
reserved memory regions as soon as possible to avoid other users from
allocating from these regions.
>
> I suppose the kernel could try and avoid all alloc-ranges until they've 
> been allocated, but that would have to be best effort. I've seen 
> optimizations where it's desired to spread buffers across DRAM banks, so 
> you could have N alloc-ranges for N banks that covers all of memory.
ack
>
> There's also the issue that if you have more fixed regions than memblock 
> can handle (128) before it can reallocate its arrays, then the 
> page tables themselves could be allocated in reserved regions.
True, this is also a limitation on the side of memblock, and there is
not much else we can do on this front as well.
> [ . . . ]
> 'no-map' is a hint, not a guarantee. Arm32 ignores it for regions 
> within the kernel's linear map (at least it used to). I don't think 
> anything changes here with it.
Anyone adding the "no-map" property to a reserved region is specifying that the region must not be mapped into the kernel page tables so that that there is no access from other users, not even speculative accesses.

This can be seen in the description of no-map here: https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/reserved-memory/reserved-memory.yaml#L79

I'm not sure about the arm32 architecture taking no-map as a hint, but I ran some tests on the arm64 architecture which I am currently testing on, and when a region is marked as no-map, it is excluded from the kernel page mappings (which is the correct behavior from the description of no-map above). But if we wait until after the page tables are setup to initialize reserved memory regions that are marked as no-map, then those regions would already be part of the page tables. And this defeats the purpose of users specifying no-map for their reserved memory. Hence, I think it is important to prioritize marking all nomap reserved memory regions as nomap before the page tables are setup so that this functionality is preserved. And we are able to achieve this with the code re-ordering that is being done in [PATCH 01/46] of this series. Regards, Oreoluwa


From sashal at kernel.org  Wed Feb  7 13:20:43 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  7 Feb 2024 16:20:43 -0500
Subject: [PATCH AUTOSEL 6.7 16/44] ASoC: sunxi: sun4i-spdif: Add support for Allwinner H616
In-Reply-To: <20240207212142.1399-1-sashal@kernel.org>
References: <20240207212142.1399-1-sashal@kernel.org>
Message-ID: <20240207212142.1399-16-sashal@kernel.org>

From: Chen-Yu Tsai <wens at csie.org>

[ Upstream commit 0adf963b8463faa44653e22e56ce55f747e68868 ]

The SPDIF hardware block found in the H616 SoC has the same layout as
the one found in the H6 SoC, except that it is missing the receiver
side.

Since the driver currently only supports the transmit function, support
for the H616 is identical to what is currently done for the H6.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
Link: https://msgid.link/r/20240127163247.384439-4-wens at kernel.org
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/sunxi/sun4i-spdif.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index 702386823d17..f41c30955857 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -577,6 +577,11 @@ static const struct of_device_id sun4i_spdif_of_match[] = {
 		.compatible = "allwinner,sun50i-h6-spdif",
 		.data = &sun50i_h6_spdif_quirks,
 	},
+	{
+		.compatible = "allwinner,sun50i-h616-spdif",
+		/* Essentially the same as the H6, but without RX */
+		.data = &sun50i_h6_spdif_quirks,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match);
-- 
2.43.0



From sashal at kernel.org  Wed Feb  7 13:23:02 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  7 Feb 2024 16:23:02 -0500
Subject: [PATCH AUTOSEL 6.6 16/38] ASoC: sunxi: sun4i-spdif: Add support for Allwinner H616
In-Reply-To: <20240207212337.2351-1-sashal@kernel.org>
References: <20240207212337.2351-1-sashal@kernel.org>
Message-ID: <20240207212337.2351-16-sashal@kernel.org>

From: Chen-Yu Tsai <wens at csie.org>

[ Upstream commit 0adf963b8463faa44653e22e56ce55f747e68868 ]

The SPDIF hardware block found in the H616 SoC has the same layout as
the one found in the H6 SoC, except that it is missing the receiver
side.

Since the driver currently only supports the transmit function, support
for the H616 is identical to what is currently done for the H6.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
Link: https://msgid.link/r/20240127163247.384439-4-wens at kernel.org
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/sunxi/sun4i-spdif.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index b849bb7cf58e..2347aeb049bc 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -578,6 +578,11 @@ static const struct of_device_id sun4i_spdif_of_match[] = {
 		.compatible = "allwinner,sun50i-h6-spdif",
 		.data = &sun50i_h6_spdif_quirks,
 	},
+	{
+		.compatible = "allwinner,sun50i-h616-spdif",
+		/* Essentially the same as the H6, but without RX */
+		.data = &sun50i_h6_spdif_quirks,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match);
-- 
2.43.0



From sashal at kernel.org  Wed Feb  7 13:24:36 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  7 Feb 2024 16:24:36 -0500
Subject: [PATCH AUTOSEL 6.1 11/29] ASoC: sunxi: sun4i-spdif: Add support for Allwinner H616
In-Reply-To: <20240207212505.3169-1-sashal@kernel.org>
References: <20240207212505.3169-1-sashal@kernel.org>
Message-ID: <20240207212505.3169-11-sashal@kernel.org>

From: Chen-Yu Tsai <wens at csie.org>

[ Upstream commit 0adf963b8463faa44653e22e56ce55f747e68868 ]

The SPDIF hardware block found in the H616 SoC has the same layout as
the one found in the H6 SoC, except that it is missing the receiver
side.

Since the driver currently only supports the transmit function, support
for the H616 is identical to what is currently done for the H6.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
Link: https://msgid.link/r/20240127163247.384439-4-wens at kernel.org
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/sunxi/sun4i-spdif.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index bcceebca915a..484b0e7c2def 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -578,6 +578,11 @@ static const struct of_device_id sun4i_spdif_of_match[] = {
 		.compatible = "allwinner,sun50i-h6-spdif",
 		.data = &sun50i_h6_spdif_quirks,
 	},
+	{
+		.compatible = "allwinner,sun50i-h616-spdif",
+		/* Essentially the same as the H6, but without RX */
+		.data = &sun50i_h6_spdif_quirks,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match);
-- 
2.43.0



From robh at kernel.org  Wed Feb  7 13:25:57 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 07 Feb 2024 21:25:57 +0000
Subject: [PATCH v3 4/5] dt-bindings: fpga: xlnx,fpga-selectmap: add DT
 schema
In-Reply-To: <20240207180142.79625-5-charles.perry@savoirfairelinux.com>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
 <20240207180142.79625-5-charles.perry@savoirfairelinux.com>
Message-ID: <170734115258.3199432.9793593609172465868.robh@kernel.org>


On Wed, 07 Feb 2024 13:01:27 -0500, Charles Perry wrote:
> Document the SelectMAP interface of Xilinx 7 series FPGA.
> 
> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
> ---
>  .../bindings/fpga/xlnx,fpga-selectmap.yaml    | 86 +++++++++++++++++++
>  1 file changed, 86 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.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/fpga/xlnx,fpga-selectmap.example.dtb: /example-0/fpga-mgr at 8000000: failed to match any schema with compatible: ['xlnx,fpga-selectmap']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240207180142.79625-5-charles.perry at savoirfairelinux.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From sashal at kernel.org  Wed Feb  7 13:25:50 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  7 Feb 2024 16:25:50 -0500
Subject: [PATCH AUTOSEL 5.15 09/23] ASoC: sunxi: sun4i-spdif: Add support for Allwinner H616
In-Reply-To: <20240207212611.3793-1-sashal@kernel.org>
References: <20240207212611.3793-1-sashal@kernel.org>
Message-ID: <20240207212611.3793-9-sashal@kernel.org>

From: Chen-Yu Tsai <wens at csie.org>

[ Upstream commit 0adf963b8463faa44653e22e56ce55f747e68868 ]

The SPDIF hardware block found in the H616 SoC has the same layout as
the one found in the H6 SoC, except that it is missing the receiver
side.

Since the driver currently only supports the transmit function, support
for the H616 is identical to what is currently done for the H6.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
Link: https://msgid.link/r/20240127163247.384439-4-wens at kernel.org
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/sunxi/sun4i-spdif.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index a10949bf0ca1..dd8d13f3fd12 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -464,6 +464,11 @@ static const struct of_device_id sun4i_spdif_of_match[] = {
 		.compatible = "allwinner,sun50i-h6-spdif",
 		.data = &sun50i_h6_spdif_quirks,
 	},
+	{
+		.compatible = "allwinner,sun50i-h616-spdif",
+		/* Essentially the same as the H6, but without RX */
+		.data = &sun50i_h6_spdif_quirks,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match);
-- 
2.43.0



From sashal at kernel.org  Wed Feb  7 13:26:47 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  7 Feb 2024 16:26:47 -0500
Subject: [PATCH AUTOSEL 5.10 07/16] ASoC: sunxi: sun4i-spdif: Add support for Allwinner H616
In-Reply-To: <20240207212700.4287-1-sashal@kernel.org>
References: <20240207212700.4287-1-sashal@kernel.org>
Message-ID: <20240207212700.4287-7-sashal@kernel.org>

From: Chen-Yu Tsai <wens at csie.org>

[ Upstream commit 0adf963b8463faa44653e22e56ce55f747e68868 ]

The SPDIF hardware block found in the H616 SoC has the same layout as
the one found in the H6 SoC, except that it is missing the receiver
side.

Since the driver currently only supports the transmit function, support
for the H616 is identical to what is currently done for the H6.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
Link: https://msgid.link/r/20240127163247.384439-4-wens at kernel.org
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/sunxi/sun4i-spdif.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index 228485fe0734..6dcad1aa2503 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -464,6 +464,11 @@ static const struct of_device_id sun4i_spdif_of_match[] = {
 		.compatible = "allwinner,sun50i-h6-spdif",
 		.data = &sun50i_h6_spdif_quirks,
 	},
+	{
+		.compatible = "allwinner,sun50i-h616-spdif",
+		/* Essentially the same as the H6, but without RX */
+		.data = &sun50i_h6_spdif_quirks,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match);
-- 
2.43.0



From sashal at kernel.org  Wed Feb  7 13:27:29 2024
From: sashal at kernel.org (Sasha Levin)
Date: Wed,  7 Feb 2024 16:27:29 -0500
Subject: [PATCH AUTOSEL 5.4 5/7] ASoC: sunxi: sun4i-spdif: Add support for Allwinner H616
In-Reply-To: <20240207212732.4627-1-sashal@kernel.org>
References: <20240207212732.4627-1-sashal@kernel.org>
Message-ID: <20240207212732.4627-5-sashal@kernel.org>

From: Chen-Yu Tsai <wens at csie.org>

[ Upstream commit 0adf963b8463faa44653e22e56ce55f747e68868 ]

The SPDIF hardware block found in the H616 SoC has the same layout as
the one found in the H6 SoC, except that it is missing the receiver
side.

Since the driver currently only supports the transmit function, support
for the H616 is identical to what is currently done for the H6.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
Link: https://msgid.link/r/20240127163247.384439-4-wens at kernel.org
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/sunxi/sun4i-spdif.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index cbe598b0fb10..680d64e0d69f 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -464,6 +464,11 @@ static const struct of_device_id sun4i_spdif_of_match[] = {
 		.compatible = "allwinner,sun50i-h6-spdif",
 		.data = &sun50i_h6_spdif_quirks,
 	},
+	{
+		.compatible = "allwinner,sun50i-h616-spdif",
+		/* Essentially the same as the H6, but without RX */
+		.data = &sun50i_h6_spdif_quirks,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match);
-- 
2.43.0



From afd at ti.com  Wed Feb  7 14:20:39 2024
From: afd at ti.com (Andrew Davis)
Date: Wed, 7 Feb 2024 16:20:39 -0600
Subject: [PATCH] arm64: dts: ti: am62-phyboard-lyra: Add overlay to enable
 a GPIO fan
In-Reply-To: <20240207172820.478332-1-nmorrisson@phytec.com>
References: <20240207172820.478332-1-nmorrisson@phytec.com>
Message-ID: <acd3c7f2-930d-46c0-9924-9775e9795fca@ti.com>

On 2/7/24 11:28 AM, Nathan Morrisson wrote:
> The phyBOARD-Lyra has a GPIO fan header. This overlay enables the fan
> header and sets the fan to turn on at 65C.
> 
> Signed-off-by: Nathan Morrisson <nmorrisson at phytec.com>
> ---
>   arch/arm64/boot/dts/ti/Makefile               |  1 +
>   .../ti/k3-am62-phyboard-lyra-gpio-fan.dtso    | 51 +++++++++++++++++++
>   2 files changed, 52 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
> 
> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
> index 52c1dc910308..379fb4f31a1f 100644
> --- a/arch/arm64/boot/dts/ti/Makefile
> +++ b/arch/arm64/boot/dts/ti/Makefile
> @@ -23,6 +23,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-mallow.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
> +dtb-$(CONFIG_ARCH_K3) += k3-am62-phyboard-lyra-gpio-fan.dtbo

Why not call this k3-am625-phyboard-lyra-gpio-fan.dtbo to match the
name of the base board it applies to better?

Andrew

>   
>   # Boards with AM62Ax SoC
>   dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso b/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
> new file mode 100644
> index 000000000000..9c05748bdd9d
> --- /dev/null
> +++ b/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
> @@ -0,0 +1,51 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +/*
> + * Copyright (C) 2024 PHYTEC America LLC
> + * Author: Garrett Giordano <ggiordano at phytec.com>
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/thermal/thermal.h>
> +#include "k3-pinctrl.h"
> +
> +&{/} {
> +	fan: gpio-fan {
> +		compatible = "gpio-fan";
> +		gpio-fan,speed-map = <0 0 8600 1>;
> +		gpios = <&main_gpio0 40 GPIO_ACTIVE_LOW>;
> +		#cooling-cells = <2>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&gpio_fan_pins_default>;
> +		status = "okay";
> +	};
> +};
> +
> +&main_pmx0 {
> +	gpio_fan_pins_default: gpio-fan-default-pins {
> +		pinctrl-single,pins = <
> +			AM62X_IOPAD(0x0a4, PIN_OUTPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
> +		>;
> +	};
> +};
> +
> +&thermal_zones {
> +	main0_thermal: main0-thermal {
> +		trips {
> +			main0_thermal_trip0: main0-thermal-trip {
> +				temperature = <65000>;  /* millicelsius */
> +				hysteresis = <2000>;    /* millicelsius */
> +				type = "active";
> +			};
> +		};
> +
> +		cooling-maps {
> +			map0 {
> +				trip = <&main0_thermal_trip0>;
> +				cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> +			};
> +		};
> +	};
> +};


From quic_abchauha at quicinc.com  Wed Feb  7 14:40:01 2024
From: quic_abchauha at quicinc.com (Abhishek Chauhan)
Date: Wed,  7 Feb 2024 14:40:01 -0800
Subject: [PATCH net-next v3] net: stmmac: dwmac-qcom-ethqos: Enable TBS on all queues but 0
Message-ID: <20240207224001.2109224-1-quic_abchauha@quicinc.com>

TSO and TBS cannot co-exist. TBS requires special descriptor to be
allocated at bootup. Initialising Tx queues at probe to support
TSO and TBS can help in allocating those resources at bootup.

TX queues with TBS can support etf qdisc hw offload.

This is similar to the patch raised by NXP
commit 3b12ec8f618e ("net: stmmac: dwmac-imx: set TSO/TBS TX queues default 
settings")

Changes since v2:
- Fixed the styling of comment in the dwmac-qcom-ethqos.c
- Followed the upstream format to give other glue
  driver references to solve the same problem
- Appended  the subject with net-next
- Discussion of why this patch is required is discussed in
https://lore.kernel.org/netdev/c2497eef-1041-4cd0-8220-42622c8902f4 at quicinc.com/

Changes since v1:
- Subject is changed as per upstream guidelines
- Added a reference of a similar change done by NXP in
  body of the commit message

Signed-off-by: Abhishek Chauhan <quic_abchauha at quicinc.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 31631e3f89d0..2691a250a5a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -728,7 +728,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	struct stmmac_resources stmmac_res;
 	struct device *dev = &pdev->dev;
 	struct qcom_ethqos *ethqos;
-	int ret;
+	int ret, i;
 
 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
 	if (ret)
@@ -822,6 +822,10 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
 	}
 
+	/* Enable TSO on queue0 and enable TBS on rest of the queues */
+	for (i = 1; i < plat_dat->tx_queues_to_use; i++)
+		plat_dat->tx_queues_cfg[i].tbs_en = 1;
+
 	return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
 }
 
-- 
2.25.1



From jm at ti.com  Wed Feb  7 14:55:24 2024
From: jm at ti.com (Judith Mendez)
Date: Wed, 7 Feb 2024 16:55:24 -0600
Subject: [PATCH v1 7/9] arm64: dts: ti: k3-am6*: Fix ti,clkbuf-sel property in MMC nodes
In-Reply-To: <20240207225526.3953230-1-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
Message-ID: <20240207225526.3953230-8-jm@ti.com>

Move ti,clkbuf-sel property above the OTAP/ITAP delay values.
While there is no error with where it is currently at, it is
easier to read the MMC node if ti,clkbuf-sel is located above
the OTAP/ITAP delay values consistently across MMC nodes.

Add missing ti,clkbuf-sel for MMC0 in k3-am64-main.

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi  | 4 ++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 2 +-
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi  | 3 ++-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 79ed5cbbbda1..410b390ce5d5 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -579,6 +579,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
@@ -590,7 +591,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x1>;
 		ti,itap-del-sel-sdr12 = <0xa>;
 		ti,itap-del-sel-sdr25 = <0x1>;
-		ti,clkbuf-sel = <0x7>;
 		bus-width = <4>;
 		status = "disabled";
 	};
@@ -602,6 +602,7 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
@@ -613,7 +614,6 @@ sdhci2: mmc at fa20000 {
 		ti,itap-del-sel-sd-hs = <0xa>;
 		ti,itap-del-sel-sdr12 = <0xa>;
 		ti,itap-del-sel-sdr25 = <0x1>;
-		ti,clkbuf-sel = <0x7>;
 		status = "disabled";
 	};
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index f283777d54b4..ddb76cd66f88 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -561,6 +561,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
@@ -572,7 +573,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x0>;
 		ti,itap-del-sel-sdr12 = <0x0>;
 		ti,itap-del-sel-sdr25 = <0x0>;
-		ti,clkbuf-sel = <0x7>;
 		bus-width = <4>;
 		no-1-8-v;
 		status = "disabled";
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index a29847735c6e..bea05be7cb48 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -628,6 +628,7 @@ sdhci0: mmc at fa10000 {
 		clock-names = "clk_ahb", "clk_xin";
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
+		ti,clkbuf-sel = <0x7>;
 		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-mmc-hs = <0x0>;
@@ -646,6 +647,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
@@ -657,7 +659,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x0>;
 		ti,itap-del-sel-sdr12 = <0x0>;
 		ti,itap-del-sel-sdr25 = <0x0>;
-		ti,clkbuf-sel = <0x7>;
 		status = "disabled";
 	};
 
-- 
2.43.0



From jm at ti.com  Wed Feb  7 14:55:22 2024
From: jm at ti.com (Judith Mendez)
Date: Wed, 7 Feb 2024 16:55:22 -0600
Subject: [PATCH v1 5/9] arm64: dts: ti: k3-am62p: Add ITAP/OTAP values for MMC
In-Reply-To: <20240207225526.3953230-1-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
Message-ID: <20240207225526.3953230-6-jm@ti.com>

Add OTAP/ITAP values to enable HS400 timing for MMC0 and
SDR104 timing for MMC1/MMC2. Remove no-1-8-v property to
enable the highest speed mode possible.

Update MMC OTAP/ITAP values according to the datasheet
[0], refer to Table 7-79 for MMC0 and Table 7-97 for MMC1/MMC2.

[0] https://www.ti.com/lit/ds/symlink/am62p.pdf

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 44 +++++++++++++++++++++--
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts   |  1 -
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index ef1c982a90d8..e43530beb79f 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -534,7 +534,21 @@ sdhci0: mmc at fa10000 {
 		clock-names = "clk_ahb", "clk_xin";
 		assigned-clocks = <&k3_clks 57 2>;
 		assigned-clock-parents = <&k3_clks 57 4>;
-		ti,otap-del-sel-legacy = <0x0>;
+		bus-width = <8>;
+		mmc-ddr-1_8v;
+		mmc-hs200-1_8v;
+		mmc-hs400-1_8v;
+		ti,clkbuf-sel = <0x7>;
+		ti,strobe-sel = <0x77>;
+		ti,trm-icp = <0x8>;
+		ti,otap-del-sel-legacy = <0x1>;
+		ti,otap-del-sel-mmc-hs = <0x1>;
+		ti,otap-del-sel-ddr52 = <0x6>;
+		ti,otap-del-sel-hs200 = <0x8>;
+		ti,otap-del-sel-hs400 = <0x5>;
+		ti,itap-del-sel-legacy = <0x10>;
+		ti,itap-del-sel-mmc-hs = <0xa>;
+		ti,itap-del-sel-ddr52 = <0x3>;
 		status = "disabled";
 	};
 
@@ -545,7 +559,19 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,otap-del-sel-legacy = <0x8>;
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		status = "disabled";
 	};
 
@@ -556,7 +582,19 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,otap-del-sel-legacy = <0x8>;
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		status = "disabled";
 	};
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 95a0146279b1..8c73587b0b62 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -424,7 +424,6 @@ &sdhci1 {
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
-	no-1-8-v;
 	bootph-all;
 };
 
-- 
2.43.0



From jm at ti.com  Wed Feb  7 14:55:19 2024
From: jm at ti.com (Judith Mendez)
Date: Wed, 7 Feb 2024 16:55:19 -0600
Subject: [PATCH v1 2/9] arm64: dts: ti: k3-am62a-main: Add sdhci2 instance
In-Reply-To: <20240207225526.3953230-1-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
Message-ID: <20240207225526.3953230-3-jm@ti.com>

Add sdhci2 DT node in k3-am62a-main for mmc2. Add otap/itap
values according to the datasheet[0], Refer to Table 7-97.

[0] https://www.ti.com/lit/ds/symlink/am62a3.pdf

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 24 +++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index ce5f278235a4..6806288ec227 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -579,6 +579,30 @@ sdhci1: mmc at fa00000 {
 		status = "disabled";
 	};
 
+	sdhci2: mmc at fa20000 {
+		compatible = "ti,am62-sdhci";
+		reg = <0x00 0xfa20000 0x00 0x260>, <0x00 0xfa28000 0x00 0x134>;
+		interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
+		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
+		no-1-8-v;
+		status = "disabled";
+	};
+
 	usbss0: dwc3-usb at f900000 {
 		compatible = "ti,am62-usb";
 		reg = <0x00 0x0f900000 0x00 0x800>;
-- 
2.43.0



From jm at ti.com  Wed Feb  7 14:55:17 2024
From: jm at ti.com (Judith Mendez)
Date: Wed, 7 Feb 2024 16:55:17 -0600
Subject: [PATCH v1 0/9] Fix MMC properties on Sitara devices
Message-ID: <20240207225526.3953230-1-jm@ti.com>

This patch series aims to add or fix MMC properties:
OTAPDLY/ITAPDLY.

The DLL properties ti,trm-icp and ti,driver-strength-ohm
should also be updated since only AM64x and AM62p devices
have a DLL to enable, so remove these properties when not
applicable.

Also add support for eMMC on AM62ax platform.

This series was tested on:
- AM62a SK
- AM62x SK
- AM62p SK
- AM64x GP EVM
- AM64x SK EVM

Judith Mendez (7):
  arm64: dts: ti: k3-am62a-main: Add sdhci2 instance
  arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
  arm64: dts: ti: k3-am62p: Add ITAP/OTAP values for MMC
  arm64: dts: ti: k3-am6*: Remove DLL properties for soft PHYs
  arm64: dts: ti: k3-am6*: Fix ti,clkbuf-sel property in MMC nodes
  arm64: dts: ti: k3-am6*: Fix bus-width property in MMC nodes
  arm64: dts: ti: k3-am6*: Fix bootph-all property in MMC node

Nitin Yadav (2):
  arm64: dts: ti: k3-am62a-main: Add sdhci0 instance
  arm64: dts: ti: k3-am62a7-sk: Enable eMMC support

 arch/arm64/boot/dts/ti/k3-am62-main.dtsi      | 12 +++--
 .../arm64/boot/dts/ti/k3-am625-beagleplay.dts |  4 --
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi     | 45 ++++++++++++++++++-
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts       | 27 ++++++++++-
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi     | 44 ++++++++++++++++--
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts       |  5 +--
 .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi |  2 -
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi      | 15 +++++--
 arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  4 +-
 arch/arm64/boot/dts/ti/k3-am642-sk.dts        |  2 -
 10 files changed, 130 insertions(+), 30 deletions(-)


base-commit: 1e6bbc5185bcd113c8d2f7aa0a02f588a6bdbe5d
-- 
2.43.0



From jm at ti.com  Wed Feb  7 14:55:25 2024
From: jm at ti.com (Judith Mendez)
Date: Wed, 7 Feb 2024 16:55:25 -0600
Subject: [PATCH v1 8/9] arm64: dts: ti: k3-am6*: Fix bus-width property in MMC nodes
In-Reply-To: <20240207225526.3953230-1-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
Message-ID: <20240207225526.3953230-9-jm@ti.com>

Move bus-width property to *main.dtsi, above the OTAP/ITAP
delay values. While there is no error with where it is
currently at, it is easier to read the MMC node if the
bus-width property is located above the OTAP/ITAP delay
values consistently across MMC nodes.

Add missing bus-width for MMC2 in k3-am62-main.

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi       | 5 +++--
 arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 1 -
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi      | 2 +-
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi       | 2 ++
 arch/arm64/boot/dts/ti/k3-am642-evm.dts        | 2 --
 arch/arm64/boot/dts/ti/k3-am642-sk.dts         | 1 -
 6 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 410b390ce5d5..55420eb1c620 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -559,9 +559,9 @@ sdhci0: mmc at fa10000 {
 		clock-names = "clk_ahb", "clk_xin";
 		assigned-clocks = <&k3_clks 57 6>;
 		assigned-clock-parents = <&k3_clks 57 8>;
+		bus-width = <8>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
-		bus-width = <8>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-mmc-hs = <0x0>;
@@ -579,6 +579,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
@@ -591,7 +592,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x1>;
 		ti,itap-del-sel-sdr12 = <0xa>;
 		ti,itap-del-sel-sdr25 = <0x1>;
-		bus-width = <4>;
 		status = "disabled";
 	};
 
@@ -602,6 +602,7 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
index bb6a5837bcb3..a34e0df2ab86 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -842,7 +842,6 @@ &sdhci2 {
 	vmmc-supply = <&wlan_en>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&wifi_pins_default>, <&wifi_32k_clk>;
-	bus-width = <4>;
 	non-removable;
 	ti,fails-without-test-cd;
 	cap-power-off-card;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index ddb76cd66f88..253c1857eedf 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -561,6 +561,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
@@ -573,7 +574,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x0>;
 		ti,itap-del-sel-sdr12 = <0x0>;
 		ti,itap-del-sel-sdr25 = <0x0>;
-		bus-width = <4>;
 		no-1-8-v;
 		status = "disabled";
 	};
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index bea05be7cb48..bc9c9ff993e6 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -626,6 +626,7 @@ sdhci0: mmc at fa10000 {
 		power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 57 0>, <&k3_clks 57 1>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <8>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
 		ti,clkbuf-sel = <0x7>;
@@ -647,6 +648,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index f308076d608a..83f2b00726b5 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -494,7 +494,6 @@ eeprom at 0 {
 /* eMMC */
 &sdhci0 {
 	status = "okay";
-	bus-width = <8>;
 	non-removable;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
@@ -506,7 +505,6 @@ &sdhci1 {
 	status = "okay";
 	vmmc-supply = <&vdd_mmc1>;
 	pinctrl-names = "default";
-	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	disable-wp;
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index b286eaa02ada..67cd41bf806e 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -469,7 +469,6 @@ &sdhci1 {
 	status = "okay";
 	vmmc-supply = <&vdd_mmc1>;
 	pinctrl-names = "default";
-	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	disable-wp;
 };
-- 
2.43.0



From jm at ti.com  Wed Feb  7 14:55:21 2024
From: jm at ti.com (Judith Mendez)
Date: Wed, 7 Feb 2024 16:55:21 -0600
Subject: [PATCH v1 4/9] arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
In-Reply-To: <20240207225526.3953230-1-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
Message-ID: <20240207225526.3953230-5-jm@ti.com>

Update MMC0/MMC1 OTAP/ITAP values according to the datasheet
[0], refer to Table 7-68 for MMC0 and Table 7-77 for MMC1.

[0] https://www.ti.com/lit/ds/symlink/am6442.pdf

Fixes: 8abae9389bdb ("arm64: dts: ti: Add support for AM642 SoC")
Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index ddd382a0d735..9bfa0a969bfc 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -633,6 +633,9 @@ sdhci0: mmc at fa10000 {
 		ti,otap-del-sel-mmc-hs = <0x0>;
 		ti,otap-del-sel-ddr52 = <0x6>;
 		ti,otap-del-sel-hs200 = <0x7>;
+		ti,itap-del-sel-legacy = <0x10>;
+		ti,itap-del-sel-mmc-hs = <0xa>;
+		ti,itap-del-sel-ddr52 = <0x3>;
 		status = "disabled";
 	};
 
@@ -645,12 +648,16 @@ sdhci1: mmc at fa00000 {
 		clock-names = "clk_ahb", "clk_xin";
 		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
-		ti,otap-del-sel-sd-hs = <0xf>;
+		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
 		ti,otap-del-sel-sdr25 = <0xf>;
 		ti,otap-del-sel-sdr50 = <0xc>;
 		ti,otap-del-sel-sdr104 = <0x6>;
 		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		ti,clkbuf-sel = <0x7>;
 		status = "disabled";
 	};
-- 
2.43.0



From jm at ti.com  Wed Feb  7 14:55:23 2024
From: jm at ti.com (Judith Mendez)
Date: Wed, 7 Feb 2024 16:55:23 -0600
Subject: [PATCH v1 6/9] arm64: dts: ti: k3-am6*: Remove DLL properties for soft PHYs
In-Reply-To: <20240207225526.3953230-1-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
Message-ID: <20240207225526.3953230-7-jm@ti.com>

Remove DLL properties which are not applicable for soft PHYs
since these PHYs do not have a DLL to enable.

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi       | 3 ---
 arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 3 ---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi      | 1 -
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts        | 1 -
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts        | 1 -
 arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 2 --
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi       | 1 -
 arch/arm64/boot/dts/ti/k3-am642-evm.dts        | 1 -
 arch/arm64/boot/dts/ti/k3-am642-sk.dts         | 1 -
 9 files changed, 14 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index fe0cc4a9a501..79ed5cbbbda1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -561,7 +561,6 @@ sdhci0: mmc at fa10000 {
 		assigned-clock-parents = <&k3_clks 57 8>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
-		ti,trm-icp = <0x2>;
 		bus-width = <8>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
@@ -580,7 +579,6 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
@@ -604,7 +602,6 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
index 3b4246ce49de..bb6a5837bcb3 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -819,7 +819,6 @@ &sdhci0 {
 	bootph-all;
 	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	status = "okay";
 };
@@ -832,7 +831,6 @@ &sdhci1 {
 
 	vmmc-supply = <&vdd_3v3_sd>;
 	vqmmc-supply = <&vdd_sd_dv>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
 	cd-debounce-delay-ms = <100>;
@@ -849,7 +847,6 @@ &sdhci2 {
 	ti,fails-without-test-cd;
 	cap-power-off-card;
 	keep-power-in-suspend;
-	ti,driver-strength-ohm = <50>;
 	assigned-clocks = <&k3_clks 157 158>;
 	assigned-clock-parents = <&k3_clks 157 160>;
 	#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 6806288ec227..f283777d54b4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -561,7 +561,6 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index c99b2e90f76d..f241637a5642 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -582,7 +582,6 @@ &sdhci1 {
 	vmmc-supply = <&vdd_mmc1>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 8c73587b0b62..5c9b73726ebd 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -422,7 +422,6 @@ &sdhci1 {
 	vqmmc-supply = <&vddshv_sdio>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	bootph-all;
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
index 6dd496cd459a..3c45782ab2b7 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -411,7 +411,6 @@ &sdhci0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc0_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
@@ -421,7 +420,6 @@ &sdhci1 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index 9bfa0a969bfc..a29847735c6e 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -646,7 +646,6 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 5c546ae76d3e..f308076d608a 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -508,7 +508,6 @@ &sdhci1 {
 	pinctrl-names = "default";
 	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index cce04e188ff6..b286eaa02ada 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -471,7 +471,6 @@ &sdhci1 {
 	pinctrl-names = "default";
 	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
-- 
2.43.0



From jm at ti.com  Wed Feb  7 14:55:18 2024
From: jm at ti.com (Judith Mendez)
Date: Wed, 7 Feb 2024 16:55:18 -0600
Subject: [PATCH v1 1/9] arm64: dts: ti: k3-am62a-main: Add sdhci0 instance
In-Reply-To: <20240207225526.3953230-1-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
Message-ID: <20240207225526.3953230-2-jm@ti.com>

From: Nitin Yadav <n-yadav at ti.com>

Add sdhci0 DT node in k3-am62a-main for eMMC support. Add otap/itap
values according to the datasheet[0], refer to Table 7-79.

[0] https://www.ti.com/lit/ds/symlink/am62a3.pdf

Signed-off-by: Nitin Yadav <n-yadav at ti.com>
Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 972971159a62..ce5f278235a4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -536,6 +536,24 @@ main_gpio1: gpio at 601000 {
 		status = "disabled";
 	};
 
+	sdhci0: mmc at fa10000 {
+		compatible = "ti,am62-sdhci";
+		reg = <0x00 0xfa10000 0x00 0x260>, <0x00 0xfa18000 0x00 0x134>;
+		interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 57 5>, <&k3_clks 57 6>;
+		clock-names = "clk_ahb", "clk_xin";
+		assigned-clocks = <&k3_clks 57 6>;
+		assigned-clock-parents = <&k3_clks 57 8>;
+		bus-width = <8>;
+		mmc-hs200-1_8v;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-mmc-hs = <0x0>;
+		ti,otap-del-sel-hs200 = <0x6>;
+		status = "disabled";
+	};
+
 	sdhci1: mmc at fa00000 {
 		compatible = "ti,am62-sdhci";
 		reg = <0x00 0xfa00000 0x00 0x260>, <0x00 0xfa08000 0x00 0x134>;
-- 
2.43.0



From jm at ti.com  Wed Feb  7 14:55:20 2024
From: jm at ti.com (Judith Mendez)
Date: Wed, 7 Feb 2024 16:55:20 -0600
Subject: [PATCH v1 3/9] arm64: dts: ti: k3-am62a7-sk: Enable eMMC support
In-Reply-To: <20240207225526.3953230-1-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
Message-ID: <20240207225526.3953230-4-jm@ti.com>

From: Nitin Yadav <n-yadav at ti.com>

Add support for 32GB eMMC card on AM62A7 SK. Includes adding mmc0
pins settings. Add mmc0 alias for sdhci0 in k3-am62a7-sk.dts.

Signed-off-by: Nitin Yadav <n-yadav at ti.com>
Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts | 26 +++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index f5ae91bf1bdb..c99b2e90f76d 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -20,6 +20,7 @@ aliases {
 		serial0 = &wkup_uart0;
 		serial2 = &main_uart0;
 		serial3 = &main_uart1;
+		mmc0 = &sdhci0;
 		mmc1 = &sdhci1;
 	};
 
@@ -263,6 +264,22 @@ AM62AX_IOPAD(0x0b4, PIN_INPUT_PULLUP, 1) /* (K24) GPMC0_CSn3.I2C2_SDA */
 		>;
 	};
 
+	main_mmc0_pins_default: main-mmc0-default-pins {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */
+			AM62AX_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLKLB */
+			AM62AX_IOPAD(0x21c, PIN_INPUT, 0) /* (AB1) MMC0_CLK */
+			AM62AX_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */
+			AM62AX_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */
+			AM62AX_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */
+			AM62AX_IOPAD(0x208, PIN_INPUT_PULLUP, 0) /* (Y4) MMC0_DAT3 */
+			AM62AX_IOPAD(0x204, PIN_INPUT_PULLUP, 0) /* (AB2) MMC0_DAT4 */
+			AM62AX_IOPAD(0x200, PIN_INPUT_PULLUP, 0) /* (AC1) MMC0_DAT5 */
+			AM62AX_IOPAD(0x1fc, PIN_INPUT_PULLUP, 0) /* (AD2) MMC0_DAT6 */
+			AM62AX_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		pinctrl-single,pins = <
 			AM62AX_IOPAD(0x23c, PIN_INPUT, 0) /* (A21) MMC1_CMD */
@@ -550,6 +567,15 @@ &main_i2c2 {
 	clock-frequency = <400000>;
 };
 
+&sdhci0 {
+	/* eMMC */
+	status = "okay";
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc0_pins_default>;
+	disable-wp;
+};
+
 &sdhci1 {
 	/* SD/MMC */
 	status = "okay";
-- 
2.43.0



From jm at ti.com  Wed Feb  7 14:55:26 2024
From: jm at ti.com (Judith Mendez)
Date: Wed, 7 Feb 2024 16:55:26 -0600
Subject: [PATCH v1 9/9] arm64: dts: ti: k3-am6*: Fix bootph-all property in MMC node
In-Reply-To: <20240207225526.3953230-1-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
Message-ID: <20240207225526.3953230-10-jm@ti.com>

Add missing bootph-all property for AM62p MMC0 and AM64x
MMC0 nodes.

Move the location of bootph-all property in MMC1 for
k3-am62p5-sk to match Sitara board files.

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 3 ++-
 arch/arm64/boot/dts/ti/k3-am642-evm.dts | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 5c9b73726ebd..17c6c2fc0e09 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -410,6 +410,7 @@ &main_i2c2 {
 };
 
 &sdhci0 {
+	bootph-all;
 	status = "okay";
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
@@ -417,13 +418,13 @@ &sdhci0 {
 
 &sdhci1 {
 	/* SD/MMC */
+	bootph-all;
 	status = "okay";
 	vmmc-supply = <&vdd_mmc1>;
 	vqmmc-supply = <&vddshv_sdio>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	disable-wp;
-	bootph-all;
 };
 
 &cpsw3g {
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 83f2b00726b5..84619782e52d 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -493,6 +493,7 @@ eeprom at 0 {
 
 /* eMMC */
 &sdhci0 {
+	bootph-all;
 	status = "okay";
 	non-removable;
 	ti,driver-strength-ohm = <50>;
-- 
2.43.0



From quic_jjohnson at quicinc.com  Wed Feb  7 15:54:52 2024
From: quic_jjohnson at quicinc.com (Jeff Johnson)
Date: Wed, 7 Feb 2024 15:54:52 -0800
Subject: [PATCH net-next v3] net: stmmac: dwmac-qcom-ethqos: Enable TBS on
 all queues but 0
In-Reply-To: <20240207224001.2109224-1-quic_abchauha@quicinc.com>
References: <20240207224001.2109224-1-quic_abchauha@quicinc.com>
Message-ID: <182afe94-e6db-4329-8653-93f6315dea54@quicinc.com>

On 2/7/2024 2:40 PM, Abhishek Chauhan wrote:
> TSO and TBS cannot co-exist. TBS requires special descriptor to be
> allocated at bootup. Initialising Tx queues at probe to support
> TSO and TBS can help in allocating those resources at bootup.
> 
> TX queues with TBS can support etf qdisc hw offload.
> 
> This is similar to the patch raised by NXP
> commit 3b12ec8f618e ("net: stmmac: dwmac-imx: set TSO/TBS TX queues default 
> settings")
> 
> Changes since v2:
> - Fixed the styling of comment in the dwmac-qcom-ethqos.c
> - Followed the upstream format to give other glue
>   driver references to solve the same problem
> - Appended  the subject with net-next
> - Discussion of why this patch is required is discussed in
> https://lore.kernel.org/netdev/c2497eef-1041-4cd0-8220-42622c8902f4 at quicinc.com/
> 
> Changes since v1:
> - Subject is changed as per upstream guidelines
> - Added a reference of a similar change done by NXP in
>   body of the commit message

Note that your patch change history should not be part of your commit
text, but instead should be below the "---" line.
> 
> Signed-off-by: Abhishek Chauhan <quic_abchauha at quicinc.com>
> ---

in other words put it here. the change history will not be part of the
git history

I strongly suggest looking at b4 since it will manage your patch history:
https://b4.docs.kernel.org/en/latest/index.html#for-developers

>  drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> index 31631e3f89d0..2691a250a5a7 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> @@ -728,7 +728,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
>  	struct stmmac_resources stmmac_res;
>  	struct device *dev = &pdev->dev;
>  	struct qcom_ethqos *ethqos;
> -	int ret;
> +	int ret, i;
>  
>  	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
>  	if (ret)
> @@ -822,6 +822,10 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
>  		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
>  	}
>  
> +	/* Enable TSO on queue0 and enable TBS on rest of the queues */
> +	for (i = 1; i < plat_dat->tx_queues_to_use; i++)
> +		plat_dat->tx_queues_cfg[i].tbs_en = 1;
> +
>  	return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
>  }
>  



From akpm at linux-foundation.org  Wed Feb  7 15:56:23 2024
From: akpm at linux-foundation.org (Andrew Morton)
Date: Wed, 7 Feb 2024 15:56:23 -0800
Subject: [PATCH] scripts/gdb/vmalloc: fix vmallocinfo error
In-Reply-To: <20240207085856.11190-1-Kuan-Ying.Lee@mediatek.com>
References: <20240207085856.11190-1-Kuan-Ying.Lee@mediatek.com>
Message-ID: <20240207155623.a943328ba0b77859246e0d9f@linux-foundation.org>

On Wed, 7 Feb 2024 16:58:51 +0800 Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com> wrote:

> We met the gdb vmallocinfo issue as following.
> 
> (gdb) lx-vmallocinfo
> Python Exception <class 'gdb.error'>: No symbol "vmap_area_list" in current context.
> Error occurred in Python: No symbol "vmap_area_list" in current context.
> 
> Since Mitigate a vmap lock contention patchset [1], we
> remove the vmap_area_list.

I don't think that's correct?

> We need to use vmap_nodes to iterate all vmallocinfo.
> 
> [1] https://lore.kernel.org/linux-mm/20240102184633.748113-1-urezki at gmail.com/

vmap_area_list was removed by https://lkml.kernel.org/r/20240102184633.748113-6-urezki at gmail.com

So I think this patch is actually a fix against mm.git:mm-unstable's
mm-vmalloc-remove-vmap_area_list.patch?

However this gdb function was probably probably broken earlier in that
series, so perhaps this patch would be best staged as a predecessor to
Ulad's vmalloc series.

> Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
> Cc: Casper Li <casper.li at mediatek.com>
> ---
>  scripts/gdb/linux/vmalloc.py | 56 +++++++++++++++++++-----------------
>  1 file changed, 29 insertions(+), 27 deletions(-)
> 
> diff --git a/scripts/gdb/linux/vmalloc.py b/scripts/gdb/linux/vmalloc.py
> index d3c8a0274d1e..803f17371052 100644
> --- a/scripts/gdb/linux/vmalloc.py
> +++ b/scripts/gdb/linux/vmalloc.py
> @@ -29,32 +29,34 @@ class LxVmallocInfo(gdb.Command):
>          if not constants.LX_CONFIG_MMU:
>              raise gdb.GdbError("Requires MMU support")
>  
> -        vmap_area_list = gdb.parse_and_eval('vmap_area_list')
> -        for vmap_area in lists.list_for_each_entry(vmap_area_list, vmap_area_ptr_type, "list"):
> -            if not vmap_area['vm']:
> -                gdb.write("0x%x-0x%x %10d vm_map_ram\n" % (vmap_area['va_start'], vmap_area['va_end'],
> -                    vmap_area['va_end'] - vmap_area['va_start']))
> -                continue
> -            v = vmap_area['vm']
> -            gdb.write("0x%x-0x%x %10d" % (v['addr'], v['addr'] + v['size'], v['size']))
> -            if v['caller']:
> -                gdb.write(" %s" % str(v['caller']).split(' ')[-1])
> -            if v['nr_pages']:
> -                gdb.write(" pages=%d" % v['nr_pages'])
> -            if v['phys_addr']:
> -                gdb.write(" phys=0x%x" % v['phys_addr'])
> -            if v['flags'] & constants.LX_VM_IOREMAP:
> -                gdb.write(" ioremap")
> -            if v['flags'] & constants.LX_VM_ALLOC:
> -                gdb.write(" vmalloc")
> -            if v['flags'] & constants.LX_VM_MAP:
> -                gdb.write(" vmap")
> -            if v['flags'] & constants.LX_VM_USERMAP:
> -                gdb.write(" user")
> -            if v['flags'] & constants.LX_VM_DMA_COHERENT:
> -                gdb.write(" dma-coherent")
> -            if is_vmalloc_addr(v['pages']):
> -                gdb.write(" vpages")
> -            gdb.write("\n")
> +        nr_vmap_nodes = gdb.parse_and_eval('nr_vmap_nodes')
> +        for i in range(0, nr_vmap_nodes):
> +            vn = gdb.parse_and_eval('&vmap_nodes[%d]' % i)
> +            for vmap_area in lists.list_for_each_entry(vn['busy']['head'], vmap_area_ptr_type, "list"):
> +                if not vmap_area['vm']:
> +                    gdb.write("0x%x-0x%x %10d vm_map_ram\n" % (vmap_area['va_start'], vmap_area['va_end'],
> +                        vmap_area['va_end'] - vmap_area['va_start']))
> +                    continue
> +                v = vmap_area['vm']
> +                gdb.write("0x%x-0x%x %10d" % (v['addr'], v['addr'] + v['size'], v['size']))
> +                if v['caller']:
> +                    gdb.write(" %s" % str(v['caller']).split(' ')[-1])
> +                if v['nr_pages']:
> +                    gdb.write(" pages=%d" % v['nr_pages'])
> +                if v['phys_addr']:
> +                    gdb.write(" phys=0x%x" % v['phys_addr'])
> +                if v['flags'] & constants.LX_VM_IOREMAP:
> +                    gdb.write(" ioremap")
> +                if v['flags'] & constants.LX_VM_ALLOC:
> +                    gdb.write(" vmalloc")
> +                if v['flags'] & constants.LX_VM_MAP:
> +                    gdb.write(" vmap")
> +                if v['flags'] & constants.LX_VM_USERMAP:
> +                    gdb.write(" user")
> +                if v['flags'] & constants.LX_VM_DMA_COHERENT:
> +                    gdb.write(" dma-coherent")
> +                if is_vmalloc_addr(v['pages']):
> +                    gdb.write(" vpages")
> +                gdb.write("\n")
>  
>  LxVmallocInfo()
> -- 
> 2.18.0


From akpm at linux-foundation.org  Wed Feb  7 15:59:29 2024
From: akpm at linux-foundation.org (Andrew Morton)
Date: Wed, 7 Feb 2024 15:59:29 -0800
Subject: [PATCH] scripts/gdb/vmalloc: fix vmallocinfo error
In-Reply-To: <20240207155623.a943328ba0b77859246e0d9f@linux-foundation.org>
References: <20240207085856.11190-1-Kuan-Ying.Lee@mediatek.com>
	<20240207155623.a943328ba0b77859246e0d9f@linux-foundation.org>
Message-ID: <20240207155929.cc107bcc14b982789bdc9fab@linux-foundation.org>

On Wed, 7 Feb 2024 15:56:23 -0800 Andrew Morton <akpm at linux-foundation.org> wrote:

> > [1] https://lore.kernel.org/linux-mm/20240102184633.748113-1-urezki at gmail.com/
> 
> vmap_area_list was removed by https://lkml.kernel.org/r/20240102184633.748113-6-urezki at gmail.com
> 
> So I think this patch is actually a fix against mm.git:mm-unstable's
> mm-vmalloc-remove-vmap_area_list.patch?
> 
> However this gdb function was probably probably broken earlier in that
> series, so perhaps this patch would be best staged as a predecessor to
> Ulad's vmalloc series.

ie, this:


From: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
Subject: scripts/gdb/vmalloc: fix vmallocinfo error
Date: Wed, 7 Feb 2024 16:58:51 +0800

The patch series "Mitigate a vmap lock contention" removes vmap_area_list,
which will break the gdb vmallocinfo command:

(gdb) lx-vmallocinfo
Python Exception <class 'gdb.error'>: No symbol "vmap_area_list" in current context.
Error occurred in Python: No symbol "vmap_area_list" in current context.

So we can instead use vmap_nodes to iterate all vmallocinfo.

Link: https://lkml.kernel.org/r/20240207085856.11190-1-Kuan-Ying.Lee at mediatek.com
Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
Cc: Casper Li <casper.li at mediatek.com>
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Cc: Chinwen Chang <chinwen.chang at mediatek.com>
Cc: Jan Kiszka <jan.kiszka at siemens.com>
Cc: Kieran Bingham <kbingham at kernel.org>
Cc: Matthias Brugger <matthias.bgg at gmail.com>
Cc: Qun-Wei Lin <qun-wei.lin at mediatek.com>
Cc: Uladzislau Rezki (Sony) <urezki at gmail.com>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
---

 scripts/gdb/linux/vmalloc.py |   56 +++++++++++++++++----------------
 1 file changed, 29 insertions(+), 27 deletions(-)

--- a/scripts/gdb/linux/vmalloc.py~scripts-gdb-vmalloc-fix-vmallocinfo-error
+++ a/scripts/gdb/linux/vmalloc.py
@@ -29,32 +29,34 @@ class LxVmallocInfo(gdb.Command):
         if not constants.LX_CONFIG_MMU:
             raise gdb.GdbError("Requires MMU support")
 
-        vmap_area_list = gdb.parse_and_eval('vmap_area_list')
-        for vmap_area in lists.list_for_each_entry(vmap_area_list, vmap_area_ptr_type, "list"):
-            if not vmap_area['vm']:
-                gdb.write("0x%x-0x%x %10d vm_map_ram\n" % (vmap_area['va_start'], vmap_area['va_end'],
-                    vmap_area['va_end'] - vmap_area['va_start']))
-                continue
-            v = vmap_area['vm']
-            gdb.write("0x%x-0x%x %10d" % (v['addr'], v['addr'] + v['size'], v['size']))
-            if v['caller']:
-                gdb.write(" %s" % str(v['caller']).split(' ')[-1])
-            if v['nr_pages']:
-                gdb.write(" pages=%d" % v['nr_pages'])
-            if v['phys_addr']:
-                gdb.write(" phys=0x%x" % v['phys_addr'])
-            if v['flags'] & constants.LX_VM_IOREMAP:
-                gdb.write(" ioremap")
-            if v['flags'] & constants.LX_VM_ALLOC:
-                gdb.write(" vmalloc")
-            if v['flags'] & constants.LX_VM_MAP:
-                gdb.write(" vmap")
-            if v['flags'] & constants.LX_VM_USERMAP:
-                gdb.write(" user")
-            if v['flags'] & constants.LX_VM_DMA_COHERENT:
-                gdb.write(" dma-coherent")
-            if is_vmalloc_addr(v['pages']):
-                gdb.write(" vpages")
-            gdb.write("\n")
+        nr_vmap_nodes = gdb.parse_and_eval('nr_vmap_nodes')
+        for i in range(0, nr_vmap_nodes):
+            vn = gdb.parse_and_eval('&vmap_nodes[%d]' % i)
+            for vmap_area in lists.list_for_each_entry(vn['busy']['head'], vmap_area_ptr_type, "list"):
+                if not vmap_area['vm']:
+                    gdb.write("0x%x-0x%x %10d vm_map_ram\n" % (vmap_area['va_start'], vmap_area['va_end'],
+                        vmap_area['va_end'] - vmap_area['va_start']))
+                    continue
+                v = vmap_area['vm']
+                gdb.write("0x%x-0x%x %10d" % (v['addr'], v['addr'] + v['size'], v['size']))
+                if v['caller']:
+                    gdb.write(" %s" % str(v['caller']).split(' ')[-1])
+                if v['nr_pages']:
+                    gdb.write(" pages=%d" % v['nr_pages'])
+                if v['phys_addr']:
+                    gdb.write(" phys=0x%x" % v['phys_addr'])
+                if v['flags'] & constants.LX_VM_IOREMAP:
+                    gdb.write(" ioremap")
+                if v['flags'] & constants.LX_VM_ALLOC:
+                    gdb.write(" vmalloc")
+                if v['flags'] & constants.LX_VM_MAP:
+                    gdb.write(" vmap")
+                if v['flags'] & constants.LX_VM_USERMAP:
+                    gdb.write(" user")
+                if v['flags'] & constants.LX_VM_DMA_COHERENT:
+                    gdb.write(" dma-coherent")
+                if is_vmalloc_addr(v['pages']):
+                    gdb.write(" vpages")
+                gdb.write("\n")
 
 LxVmallocInfo()
_



From zev at bewilderbeest.net  Wed Feb  7 17:26:20 2024
From: zev at bewilderbeest.net (Zev Weiss)
Date: Wed,  7 Feb 2024 17:26:20 -0800
Subject: [PATCH 2/2] ARM: prctl: Reject PR_SET_MDWE on pre-ARMv6
In-Reply-To: <20240208012620.32604-4-zev@bewilderbeest.net>
References: <20240208012620.32604-4-zev@bewilderbeest.net>
Message-ID: <20240208012620.32604-6-zev@bewilderbeest.net>

On v5 and lower CPUs we can't provide MDWE protection, so ensure we
fail any attempt to enable it via prctl(PR_SET_MDWE).

Previously such an attempt would misleadingly succeed, leading to any
subsequent mmap(PROT_READ|PROT_WRITE) or execve() failing
unconditionally (the latter somewhat violently via
force_fatal_sig(SIGSEGV) due to READ_IMPLIES_EXEC).

Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
Cc: <stable at vger.kernel.org> # v6.3+
---
 arch/arm/include/asm/mman.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 arch/arm/include/asm/mman.h

diff --git a/arch/arm/include/asm/mman.h b/arch/arm/include/asm/mman.h
new file mode 100644
index 000000000000..2189e507c8e0
--- /dev/null
+++ b/arch/arm/include/asm/mman.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#include <asm/system_info.h>
+#include <uapi/asm/mman.h>
+
+static inline bool arch_memory_deny_write_exec_supported(void)
+{
+	return cpu_architecture() >= CPU_ARCH_ARMv6;
+}
+#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
+
+#endif /* __ASM_MMAN_H__ */
-- 
2.43.0



From zev at bewilderbeest.net  Wed Feb  7 17:26:18 2024
From: zev at bewilderbeest.net (Zev Weiss)
Date: Wed,  7 Feb 2024 17:26:18 -0800
Subject: [PATCH 0/2] ARM: prctl: Reject PR_SET_MDWE where not supported
Message-ID: <20240208012620.32604-4-zev@bewilderbeest.net>

Hello,

I noticed after a recent kernel update that my ARM926 system started
segfaulting on any execve() after calling prctl(PR_SET_MDWE).  After
some investigation it appears that ARMv5 is incapable of providing the
appropriate protections for MDWE, since any readable memory is also
implicitly executable.

(Note that I'm not an expert in either ARM arch details or the mm
subsystem, so please bear with me if I've botched something in the
above analysis.)

The prctl_set_mdwe() function already had some special-case logic
added disabling it on PARISC (commit 793838138c15, "prctl: Disable
prctl(PR_SET_MDWE) on parisc"); this patch series (1) generalizes that
check to use an arch_*() function, and (2) adds a corresponding
override for ARM to disable MDWE on pre-ARMv6 CPUs.

With the series applied, prctl(PR_SET_MDWE) is rejected on ARMv5 and
subsequent execve() calls (as well as mmap(PROT_READ|PROT_WRITE)) can
succeed instead of unconditionally failing; on ARMv6 the prctl works
as it did previously.

Since this was effectively a userspace-breaking change in v6.3 (with
newer MDWE-aware userspace on older pre-MDWE kernels the prctl would
simply fail safely) I've CCed -stable for v6.3+, though since the
patches depend on the PARISC one above it will only apply cleanly on
the linux-6.6.y and linux-6.7.y branches, since at least at time of
writing the 6.3 through 6.5 branches don't have that patch backported
(due to further missing dependencies [0]).


Thanks,
Zev

[0] https://lore.kernel.org/all/2023112456-linked-nape-bf19 at gregkh/

Zev Weiss (2):
  prctl: Generalize PR_SET_MDWE support check to be per-arch
  ARM: prctl: Reject PR_SET_MDWE on pre-ARMv6

 arch/arm/include/asm/mman.h    | 14 ++++++++++++++
 arch/parisc/include/asm/mman.h | 14 ++++++++++++++
 include/linux/mman.h           |  8 ++++++++
 kernel/sys.c                   |  7 +++++--
 4 files changed, 41 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/include/asm/mman.h
 create mode 100644 arch/parisc/include/asm/mman.h

-- 
2.43.0



From hj96.nam at samsung.com  Wed Feb  7 17:34:15 2024
From: hj96.nam at samsung.com (Hojin Nam)
Date: Thu, 08 Feb 2024 10:34:15 +0900
Subject: [PATCH v3] perf: CXL: fix mismatched cpmu event opcode
References: <CGME20240208013415epcms2p2904187c8a863f4d0d2adc980fb91a2dc@epcms2p2>
Message-ID: <20240208013415epcms2p2904187c8a863f4d0d2adc980fb91a2dc@epcms2p2>

S2M NDR BI-ConflictAck opcode is described as 4 in the CXL
r3.0 3.3.9 Table 3.43. However, it is defined as 3 in macro definition.

Fixes: 5d7107c72796 ("perf: CXL Performance Monitoring Unit driver")
Signed-off-by: Hojin Nam <hj96.nam at samsung.com>
---

Hi Jonathan,
Sorry, I misunderstood your guide. 
I roll-backed to v1 patch keeping fixes tag. Thank you!

Changes since v2:
- Remove s2m_ndr_cmpm attribute and referecne added at v2 (Jonathan)

Changes since v1:
- Add s2m_ndr_cmpm event attribute
- Add fixes tag (Jonathan)


 drivers/perf/cxl_pmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index 365d964b0f6a..bc0d414a6aff 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -419,7 +419,7 @@ static struct attribute *cxl_pmu_event_attrs[] = {
        CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmp,                     CXL_PMU_GID_S2M_NDR, BIT(0)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmps,                    CXL_PMU_GID_S2M_NDR, BIT(1)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmpe,                    CXL_PMU_GID_S2M_NDR, BIT(2)),
-       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(3)),
+       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(4)),
        /* CXL rev 3.0 Table 3-46 S2M DRS opcodes */
        CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdata,                 CXL_PMU_GID_S2M_DRS, BIT(0)),
        CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdatanxm,              CXL_PMU_GID_S2M_DRS, BIT(1)),
--
2.34.1


From jane.chu at oracle.com  Wed Feb  7 18:24:52 2024
From: jane.chu at oracle.com (Jane Chu)
Date: Wed, 7 Feb 2024 18:24:52 -0800
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <ZcOQ-0pzA16AEbct@casper.infradead.org>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com> <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
 <ZcNnrdlb3fe0kGHK@casper.infradead.org>
 <20240207121125.GA22234@willie-the-truck>
 <ZcOQ-0pzA16AEbct@casper.infradead.org>
Message-ID: <908066c7-b749-4f95-b006-ce9b5bd1a909@oracle.com>

On 2/7/2024 6:17 AM, Matthew Wilcox wrote:

> On Wed, Feb 07, 2024 at 12:11:25PM +0000, Will Deacon wrote:
>> On Wed, Feb 07, 2024 at 11:21:17AM +0000, Matthew Wilcox wrote:
>>> The pte lock cannot be taken in irq context (which I think is what
>>> you're asking?)  While it is not possible to reason about all users of
>>> struct page, we are somewhat relieved of that work by noting that this is
>>> only for hugetlbfs, so we don't need to reason about slab, page tables,
>>> netmem or zsmalloc.
>> My concern is that an interrupt handler tries to access a 'struct page'
>> which faults due to another core splitting a pmd mapping for the vmemmap.
>> In this case, I think we'll end up trying to resolve the fault from irq
>> context, which will try to take the spinlock.
> Yes, this absolutely can happen (with this patch), and this patch should
> be dropped for now.
>
> While this array of ~512 pages have been allocated to hugetlbfs, and one
> would think that there would be no way that there could still be
> references to them, another CPU can have a pointer to this struct page
> (eg attempting a speculative page cache reference or
> get_user_pages_fast()).  That means it will try to call
> atomic_add_unless(&page->_refcount, 1, 0);
>
> Actually, I wonder if this isn't a problem on x86 too?  Do we need to
> explicitly go through an RCU grace period before freeing the pages
> for use by somebody else?
>
Sorry, not sure what I'm missing, please help.

 From hugetlb allocation perspective,? one of the scenarios is run time 
hugetlb page allocation (say 2M pages), starting from the buddy 
allocator returns compound pages, then the head page is set to frozen, 
then the folio(compound pages) is put thru the HVO process, one of which 
is vmemmap_split_pmd() in case a vmemmap page is a PMD page.

Until the HVO process completes, none of the vmemmap represented pages 
are available to any threads, so what are the causes for IRQ threads to 
access their vmemmap pages?

thanks!

-jane




From itaru.kitayama at linux.dev  Wed Feb  7 18:28:32 2024
From: itaru.kitayama at linux.dev (Itaru Kitayama)
Date: Thu, 8 Feb 2024 11:28:32 +0900
Subject: [PATCH 0/3] arm64: cleanup DAIF handling for EL0 returns
In-Reply-To: <20240206123848.1696480-1-mark.rutland@arm.com>
References: <20240206123848.1696480-1-mark.rutland@arm.com>
Message-ID: <ZcQ8UKRNz0TLvJRB@vm3>

On Tue, Feb 06, 2024 at 12:38:45PM +0000, Mark Rutland wrote:
> Hi,
> 
> These patches rework DAIF handling when returning to EL0, simplifiying
> the logic in do_notify_resume() and allowing Debug + SError to be
> unmasked for a little longer during exception return.
> 
> My primary motivation for these changes is to centralize entry/exit DAIF
> management within entry-common.c, as this will allow entry/exit
> sequences to be specialised, and make it much easier to add support for
> FEAT_NMI. With specialized entry DAIF management, it will also be
> possible to simplify local_daif_{save,restore}() and
> local_irq_{save,restore}().
> 
> I'm sending this out on its own as (IMO) it's a nice cleanup on its own,
> and I don't believe that I'll have the remainder of the DAIF rework
> ready for this cycle.
> 
> The series is based on v6.8-rc3.
> 
> Mark.
> 
> Mark Rutland (3):
>   arm64: Simplify do_notify_resume() DAIF masking
>   arm64: Move do_notify_resume() to entry-common.c
>   arm64: Unmask Debug + SError in do_notify_resume()
> 
>  arch/arm64/include/asm/exception.h |  2 +-
>  arch/arm64/kernel/entry-common.c   | 36 ++++++++++++++++++++++++++-
>  arch/arm64/kernel/signal.c         | 39 ++----------------------------
>  3 files changed, 38 insertions(+), 39 deletions(-)

Boot tested on RevC FVP and kselftest arm64 subcategory runs without an error
on RevC FVP too.

Itaru.

> 
> -- 
> 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 jane.chu at oracle.com  Wed Feb  7 18:35:41 2024
From: jane.chu at oracle.com (Jane Chu)
Date: Wed, 7 Feb 2024 18:35:41 -0800
Subject: [PATCH 2/3] arm64: mm: HVO: support BBM of vmemmap pgtable safely
In-Reply-To: <50f082a8-b805-5d66-45f4-2af58e99a67f@linux.dev>
References: <20231214073912.1938330-1-sunnanyong@huawei.com>
 <20231214073912.1938330-3-sunnanyong@huawei.com>
 <50f082a8-b805-5d66-45f4-2af58e99a67f@linux.dev>
Message-ID: <21c3c12a-c591-4548-891c-9ac66f0a615c@oracle.com>

On 12/14/2023 8:36 PM, Muchun Song wrote:

>
> On 2023/12/14 15:39, Nanyong Sun wrote:
>> Implement vmemmap_update_pmd and vmemmap_update_pte on arm64 to do
>> BBM(break-before-make) logic when change the page table of vmemmap
>> address, they will under the init_mm.page_table_lock.
>> If a translation fault of vmemmap address concurrently happened after
>> pte/pmd cleared, vmemmap page fault handler will acquire the
>> init_mm.page_table_lock to wait for vmemmap update to complete,
>> by then the virtual address is valid again, so PF can return and
>> access can continue.
>> In other case, do the traditional kernel fault.
>
> Yes. BTW, we already use the same scheme to support arm64
> in our internal production. So the whole approach LGTM.

Glad to hear that.? I have a question to both of you then.

How long does it take to allocate 3/4 of 1TB memory to hugetlb pool?? 
and to free them?

thanks!

-jane

>
>> Implement flush_tlb_vmemmap_all and flush_tlb_vmemmap_range on arm64
>> with nothing to do because tlb already flushed in every single BBM.
>>
>> Signed-off-by: Nanyong Sun <sunnanyong at huawei.com>
>> ---
>> ? arch/arm64/include/asm/esr.h |? 4 ++
>> ? arch/arm64/include/asm/mmu.h | 20 ++++++++
>> ? arch/arm64/mm/fault.c??????? | 94 ++++++++++++++++++++++++++++++++++++
>> ? arch/arm64/mm/mmu.c????????? | 28 +++++++++++
>> ? 4 files changed, 146 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
>> index ae35939f395b..1c63256efd25 100644
>> --- a/arch/arm64/include/asm/esr.h
>> +++ b/arch/arm64/include/asm/esr.h
>> @@ -116,6 +116,10 @@
>> ? #define ESR_ELx_FSC_SERROR??? (0x11)
>> ? #define ESR_ELx_FSC_ACCESS??? (0x08)
>> ? #define ESR_ELx_FSC_FAULT??? (0x04)
>> +#define ESR_ELx_FSC_FAULT_L0??? (0x04)
>> +#define ESR_ELx_FSC_FAULT_L1??? (0x05)
>> +#define ESR_ELx_FSC_FAULT_L2??? (0x06)
>> +#define ESR_ELx_FSC_FAULT_L3??? (0x07)
>> ? #define ESR_ELx_FSC_PERM??? (0x0C)
>> ? #define ESR_ELx_FSC_SEA_TTW0??? (0x14)
>> ? #define ESR_ELx_FSC_SEA_TTW1??? (0x15)
>> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
>> index 2fcf51231d6e..fcec5827f54f 100644
>> --- a/arch/arm64/include/asm/mmu.h
>> +++ b/arch/arm64/include/asm/mmu.h
>> @@ -76,5 +76,25 @@ extern bool kaslr_requires_kpti(void);
>> ? #define INIT_MM_CONTEXT(name)??? \
>> ????? .pgd = init_pg_dir,
>> ? +#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
>> +void vmemmap_update_pmd(unsigned long start, pmd_t *pmd, pte_t 
>> *pgtable);
>> +#define vmemmap_update_pmd vmemmap_update_pmd
>> +void vmemmap_update_pte(unsigned long addr, pte_t *pte, pte_t entry);
>> +#define vmemmap_update_pte vmemmap_update_pte
>> +
>> +static inline void flush_tlb_vmemmap_all(void)
>> +{
>> +??? /* do nothing, already flushed tlb in every single BBM */
>> +}
>> +#define flush_tlb_vmemmap_all flush_tlb_vmemmap_all
>> +
>> +static inline void flush_tlb_vmemmap_range(unsigned long start,
>> +?????????????????????? unsigned long end)
>> +{
>> +??? /* do nothing, already flushed tlb in every single BBM */
>> +}
>> +#define flush_tlb_vmemmap_range flush_tlb_vmemmap_range
>> +#endif
>> +
>> ? #endif??? /* !__ASSEMBLY__ */
>> ? #endif
>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>> index 460d799e1296..7066a273c1e0 100644
>> --- a/arch/arm64/mm/fault.c
>> +++ b/arch/arm64/mm/fault.c
>> @@ -368,6 +368,97 @@ static bool 
>> is_el1_mte_sync_tag_check_fault(unsigned long esr)
>> ????? return false;
>> ? }
>> ? +#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
>> +static inline bool is_vmemmap_address(unsigned long addr)
>> +{
>> +??? return (addr >= VMEMMAP_START) && (addr < VMEMMAP_END);
>> +}
>> +
>> +static inline bool vmemmap_fault_may_fixup(unsigned long addr,
>> +?????????????????????? unsigned long esr)
>> +{
>> +??? if (!is_vmemmap_address(addr))
>> +??????? return false;
>> +
>> +??? /*
>> +???? * Only try to handle translation fault level 2 or level 3,
>> +???? * because hugetlb vmemmap optimize only clear pmd or pte.
>> +???? */
>> +??? switch (esr & ESR_ELx_FSC) {
>> +??? case ESR_ELx_FSC_FAULT_L2:
>> +??? case ESR_ELx_FSC_FAULT_L3:
>> +??????? return true;
>> +??? default:
>> +??????? return false;
>> +??? }
>> +}
>> +
>> +/*
>> + * PMD mapped vmemmap should has been split as PTE mapped
>> + * by HVO now, here we only check this case, other cases
>> + * should fail.
>> + * Also should check the addr is healthy enough that will not cause
>> + * a level2 or level3 translation fault again after page fault
>> + * handled with success, so we need check both bits[1:0] of PMD and
>> + * PTE as ARM Spec mentioned below:
>> + * A Translation fault is generated if bits[1:0] of a translation
>> + * table descriptor identify the descriptor as either a Fault
>> + * encoding or a reserved encoding.
>> + */
>> +static inline bool vmemmap_addr_healthy(unsigned long addr)
>> +{
>> +??? pgd_t *pgdp;
>> +??? p4d_t *p4dp;
>> +??? pud_t *pudp, pud;
>> +??? pmd_t *pmdp, pmd;
>> +??? pte_t *ptep, pte;
>> +
>> +??? pgdp = pgd_offset_k(addr);
>> +??? if (pgd_none(READ_ONCE(*pgdp)))
>> +??????? return false;
>> +
>> +??? p4dp = p4d_offset(pgdp, addr);
>> +??? if (p4d_none(READ_ONCE(*p4dp)))
>> +??????? return false;
>> +
>> +??? pudp = pud_offset(p4dp, addr);
>> +??? pud = READ_ONCE(*pudp);
>> +??? if (pud_none(pud))
>> +??????? return false;
>> +
>> +??? pmdp = pmd_offset(pudp, addr);
>
> We already make sure it is a translation fault of level 2 or 3
> here, so we could use pmd_offset_k() macro to simplify the code
> a little. Right?
>
>> +??? pmd = READ_ONCE(*pmdp);
>> +??? if (!pmd_table(pmd))
>> +??????? return false;
>> +
>> +??? ptep = pte_offset_kernel(pmdp, addr);
>> +??? pte = READ_ONCE(*ptep);
>
> Please use ptep_get (which is supposed to do this) to access the
> raw pte, see commit c33c794828f21217.
>
>> +??? return (pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_PAGE;
>> +}
>> +
>> +static bool vmemmap_handle_page_fault(unsigned long addr,
>> +????????????????????? unsigned long esr)
>> +{
>> +??? bool ret = false;
>> +
>> +??? if (likely(!vmemmap_fault_may_fixup(addr, esr)))
>> +??????? return false;
>> +
>> +??? spin_lock(&init_mm.page_table_lock);
>> +??? if (vmemmap_addr_healthy(addr))
>> +??????? ret = true;
>
> It is to assign the return value to ret directly. Like:
>
> ??? ??? ret = vmemmap_addr_healthy(addr);
>
> The the initializetion to ret also can be dropped.
>
>> + spin_unlock(&init_mm.page_table_lock);
>> +
>> +??? return ret;
>> +}
>> +#else
>> +static inline bool vmemmap_handle_page_fault(unsigned long addr,
>> +???????????????????????? unsigned long esr)
>> +{
>> +??? return false;
>> +}
>> +#endif /*CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP */
> ????????? ^
> Miss a blank between "*" and "C" here.
>
> Thanks.
>
>> +
>> ? static bool is_translation_fault(unsigned long esr)
>> ? {
>> ????? return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT;
>> @@ -409,6 +500,9 @@ static void __do_kernel_fault(unsigned long addr, 
>> unsigned long esr,
>> ????????????? kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
>> ????????????? return;
>> ? +??????? if (vmemmap_handle_page_fault(addr, esr))
>> +??????????? return;
>> +
>> ????????? msg = "paging request";
>> ????? }
>> ? diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
>> index 15f6347d23b6..81a600ccac7c 100644
>> --- a/arch/arm64/mm/mmu.c
>> +++ b/arch/arm64/mm/mmu.c
>> @@ -1146,6 +1146,34 @@ int __meminit vmemmap_check_pmd(pmd_t *pmdp, 
>> int node,
>> ????? return 1;
>> ? }
>> ? +#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
>> +/*
>> + * In the window between the page table entry is cleared and filled
>> + * with a new value, other threads have the opportunity to concurrently
>> + * access the vmemmap area then page translation fault occur.
>> + * Therefore, we need to ensure that the init_mm.page_table_lock is 
>> held
>> + * to synchronize the vmemmap page fault handling which will wait for
>> + * this lock to be released to ensure that the page table entry has 
>> been
>> + * refreshed with a new valid value.
>> + */
>> +void vmemmap_update_pmd(unsigned long start, pmd_t *pmd, pte_t 
>> *pgtable)
>> +{
>> +??? lockdep_assert_held(&init_mm.page_table_lock);
>> +??? pmd_clear(pmd);
>> +??? flush_tlb_kernel_range(start, start + PMD_SIZE);
>> +??? pmd_populate_kernel(&init_mm, pmd, pgtable);
>> +}
>> +
>> +void vmemmap_update_pte(unsigned long addr, pte_t *pte, pte_t entry)
>> +{
>> +??? spin_lock(&init_mm.page_table_lock);
>> +??? pte_clear(&init_mm, addr, pte);
>> +??? flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
>> +??? set_pte_at(&init_mm, addr, pte, entry);
>> +??? spin_unlock(&init_mm.page_table_lock);
>> +}
>> +#endif
>> +
>> ? int __meminit vmemmap_populate(unsigned long start, unsigned long 
>> end, int node,
>> ????????? struct vmem_altmap *altmap)
>> ? {
>
>


From yangyicong at huawei.com  Wed Feb  7 18:40:26 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Thu, 8 Feb 2024 10:40:26 +0800
Subject: [PATCH v5] perf stat: Support per-cluster aggregation
Message-ID: <20240208024026.2691-1-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Some platforms have 'cluster' topology and CPUs in the cluster will
share resources like L3 Cache Tag (for HiSilicon Kunpeng SoC) or L2
cache (for Intel Jacobsville). Currently parsing and building cluster
topology have been supported since [1].

perf stat has already supported aggregation for other topologies like
die or socket, etc. It'll be useful to aggregate per-cluster to find
problems like L3T bandwidth contention.

This patch add support for "--per-cluster" option for per-cluster
aggregation. Also update the docs and related test. The output will
be like:

[root at localhost tmp]# perf stat -a -e LLC-load --per-cluster -- sleep 5

 Performance counter stats for 'system wide':

S56-D0-CLS158    4      1,321,521,570      LLC-load
S56-D0-CLS594    4        794,211,453      LLC-load
S56-D0-CLS1030    4             41,623      LLC-load
S56-D0-CLS1466    4             41,646      LLC-load
S56-D0-CLS1902    4             16,863      LLC-load
S56-D0-CLS2338    4             15,721      LLC-load
S56-D0-CLS2774    4             22,671      LLC-load
[...]

On a legacy system without cluster or cluster support, the output will
be look like:
[root at localhost perf]# perf stat -a -e cycles --per-cluster -- sleep 1

 Performance counter stats for 'system wide':

S56-D0-CLS0   64         18,011,485      cycles
S7182-D0-CLS0   64         16,548,835      cycles

Note that this patch doesn't mix the cluster information in the outputs
of --per-core to avoid breaking any tools/scripts using it.

Note that perf recently supports "--per-cache" aggregation, but it's not
the same with the cluster although cluster CPUs may share some cache
resources. For example on my machine all clusters within a die share the
same L3 cache:
$ cat /sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list
0-31
$ cat /sys/devices/system/cpu/cpu0/topology/cluster_cpus_list
0-3

[1] commit c5e22feffdd7 ("topology: Represent clusters of CPUs within a die")

Tested-by: Jie Zhan <zhanjie9 at hisilicon.com>
Reviewed-by: Tim Chen <tim.c.chen at linux.intel.com>
Reviewed-by: Ian Rogers <irogers at google.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
Change since v4:
- Add the Tag from Ian, Thanks.
- Fix the code style in cpu__get_cluster_id(), per Ian
Link: https://lore.kernel.org/linux-perf-users/20240206082016.22292-1-yangyicong at huawei.com/

Change since v3:
- Rebase on v6.7-rc4 and resolve the conflicts
Link: https://lore.kernel.org/all/20230404104951.27537-1-yangyicong at huawei.com/

Change since v2:
- Use 0 as cluster ID on legacy system without cluster support, keep consistenct
  with what --per-die does.
Link: https://lore.kernel.org/all/20230328112717.19573-1-yangyicong at huawei.com/

Change since v1:
- Provides the information about how to map the cluster to the CPUs in the manual
- Thanks the review from Tim and test from Jie.
Link: https://lore.kernel.org/all/20230313085911.61359-1-yangyicong at huawei.com/

 tools/perf/Documentation/perf-stat.txt        | 11 ++++
 tools/perf/builtin-stat.c                     | 52 +++++++++++++++++--
 .../tests/shell/lib/perf_json_output_lint.py  |  4 +-
 tools/perf/tests/shell/lib/stat_output.sh     | 12 +++++
 tools/perf/tests/shell/stat+csv_output.sh     |  2 +
 tools/perf/tests/shell/stat+json_output.sh    | 13 +++++
 tools/perf/tests/shell/stat+std_output.sh     |  2 +
 tools/perf/util/cpumap.c                      | 33 +++++++++++-
 tools/perf/util/cpumap.h                      | 19 +++++--
 tools/perf/util/env.h                         |  1 +
 tools/perf/util/stat-display.c                | 13 +++++
 tools/perf/util/stat.h                        |  1 +
 12 files changed, 154 insertions(+), 9 deletions(-)

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 5af2e432b54f..29756a87ab6f 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -308,6 +308,14 @@ use --per-die in addition to -a. (system-wide).  The output includes the
 die number and the number of online processors on that die. This is
 useful to gauge the amount of aggregation.
 
+--per-cluster::
+Aggregate counts per processor cluster for system-wide mode measurement.  This
+is a useful mode to detect imbalance between clusters.  To enable this mode,
+use --per-cluster in addition to -a. (system-wide).  The output includes the
+cluster number and the number of online processors on that cluster. This is
+useful to gauge the amount of aggregation. The information of cluster ID and
+related CPUs can be gotten from /sys/devices/system/cpu/cpuX/topology/cluster_{id, cpus}.
+
 --per-cache::
 Aggregate counts per cache instance for system-wide mode measurements.  By
 default, the aggregation happens for the cache level at the highest index
@@ -396,6 +404,9 @@ Aggregate counts per processor socket for system-wide mode measurements.
 --per-die::
 Aggregate counts per processor die for system-wide mode measurements.
 
+--per-cluster::
+Aggregate counts perf processor cluster for system-wide mode measurements.
+
 --per-cache::
 Aggregate counts per cache instance for system-wide mode measurements.  By
 default, the aggregation happens for the cache level at the highest index
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 5fe9abc6a524..6bba1a89d030 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1238,6 +1238,8 @@ static struct option stat_options[] = {
 		     "aggregate counts per processor socket", AGGR_SOCKET),
 	OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
 		     "aggregate counts per processor die", AGGR_DIE),
+	OPT_SET_UINT(0, "per-cluster", &stat_config.aggr_mode,
+		     "aggregate counts per processor cluster", AGGR_CLUSTER),
 	OPT_CALLBACK_OPTARG(0, "per-cache", &stat_config.aggr_mode, &stat_config.aggr_level,
 			    "cache level", "aggregate count at this cache level (Default: LLC)",
 			    parse_cache_level),
@@ -1428,6 +1430,7 @@ static struct aggr_cpu_id aggr_cpu_id__cache(struct perf_cpu cpu, void *data)
 static const char *const aggr_mode__string[] = {
 	[AGGR_CORE] = "core",
 	[AGGR_CACHE] = "cache",
+	[AGGR_CLUSTER] = "cluster",
 	[AGGR_DIE] = "die",
 	[AGGR_GLOBAL] = "global",
 	[AGGR_NODE] = "node",
@@ -1455,6 +1458,12 @@ static struct aggr_cpu_id perf_stat__get_cache_id(struct perf_stat_config *confi
 	return aggr_cpu_id__cache(cpu, /*data=*/NULL);
 }
 
+static struct aggr_cpu_id perf_stat__get_cluster(struct perf_stat_config *config __maybe_unused,
+						 struct perf_cpu cpu)
+{
+	return aggr_cpu_id__cluster(cpu, /*data=*/NULL);
+}
+
 static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
 					      struct perf_cpu cpu)
 {
@@ -1507,6 +1516,12 @@ static struct aggr_cpu_id perf_stat__get_die_cached(struct perf_stat_config *con
 	return perf_stat__get_aggr(config, perf_stat__get_die, cpu);
 }
 
+static struct aggr_cpu_id perf_stat__get_cluster_cached(struct perf_stat_config *config,
+							struct perf_cpu cpu)
+{
+	return perf_stat__get_aggr(config, perf_stat__get_cluster, cpu);
+}
+
 static struct aggr_cpu_id perf_stat__get_cache_id_cached(struct perf_stat_config *config,
 							 struct perf_cpu cpu)
 {
@@ -1544,6 +1559,8 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode)
 		return aggr_cpu_id__socket;
 	case AGGR_DIE:
 		return aggr_cpu_id__die;
+	case AGGR_CLUSTER:
+		return aggr_cpu_id__cluster;
 	case AGGR_CACHE:
 		return aggr_cpu_id__cache;
 	case AGGR_CORE:
@@ -1569,6 +1586,8 @@ static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode)
 		return perf_stat__get_socket_cached;
 	case AGGR_DIE:
 		return perf_stat__get_die_cached;
+	case AGGR_CLUSTER:
+		return perf_stat__get_cluster_cached;
 	case AGGR_CACHE:
 		return perf_stat__get_cache_id_cached;
 	case AGGR_CORE:
@@ -1737,6 +1756,21 @@ static struct aggr_cpu_id perf_env__get_cache_aggr_by_cpu(struct perf_cpu cpu,
 	return id;
 }
 
+static struct aggr_cpu_id perf_env__get_cluster_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.cpu != -1) {
+		id.socket = env->cpu[cpu.cpu].socket_id;
+		id.die = env->cpu[cpu.cpu].die_id;
+		id.cluster = env->cpu[cpu.cpu].cluster_id;
+	}
+
+	return id;
+}
+
 static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, void *data)
 {
 	struct perf_env *env = data;
@@ -1744,12 +1778,12 @@ static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, vo
 
 	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
+		 * core_id is relative to socket, die and cluster, we need a
+		 * global id. So we set socket, die id, cluster id and core id.
 		 */
 		id.socket = env->cpu[cpu.cpu].socket_id;
 		id.die = env->cpu[cpu.cpu].die_id;
+		id.cluster = env->cpu[cpu.cpu].cluster_id;
 		id.core = env->cpu[cpu.cpu].core_id;
 	}
 
@@ -1805,6 +1839,12 @@ static struct aggr_cpu_id perf_stat__get_die_file(struct perf_stat_config *confi
 	return perf_env__get_die_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
 
+static struct aggr_cpu_id perf_stat__get_cluster_file(struct perf_stat_config *config __maybe_unused,
+						      struct perf_cpu cpu)
+{
+	return perf_env__get_cluster_aggr_by_cpu(cpu, &perf_stat.session->header.env);
+}
+
 static struct aggr_cpu_id perf_stat__get_cache_file(struct perf_stat_config *config __maybe_unused,
 						    struct perf_cpu cpu)
 {
@@ -1842,6 +1882,8 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode)
 		return perf_env__get_socket_aggr_by_cpu;
 	case AGGR_DIE:
 		return perf_env__get_die_aggr_by_cpu;
+	case AGGR_CLUSTER:
+		return perf_env__get_cluster_aggr_by_cpu;
 	case AGGR_CACHE:
 		return perf_env__get_cache_aggr_by_cpu;
 	case AGGR_CORE:
@@ -1867,6 +1909,8 @@ static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode)
 		return perf_stat__get_socket_file;
 	case AGGR_DIE:
 		return perf_stat__get_die_file;
+	case AGGR_CLUSTER:
+		return perf_stat__get_cluster_file;
 	case AGGR_CACHE:
 		return perf_stat__get_cache_file;
 	case AGGR_CORE:
@@ -2398,6 +2442,8 @@ static int __cmd_report(int argc, const char **argv)
 		     "aggregate counts per processor socket", AGGR_SOCKET),
 	OPT_SET_UINT(0, "per-die", &perf_stat.aggr_mode,
 		     "aggregate counts per processor die", AGGR_DIE),
+	OPT_SET_UINT(0, "per-cluster", &perf_stat.aggr_mode,
+		     "aggregate counts perf processor cluster", AGGR_CLUSTER),
 	OPT_CALLBACK_OPTARG(0, "per-cache", &perf_stat.aggr_mode, &perf_stat.aggr_level,
 			    "cache level",
 			    "aggregate count at this cache level (Default: LLC)",
diff --git a/tools/perf/tests/shell/lib/perf_json_output_lint.py b/tools/perf/tests/shell/lib/perf_json_output_lint.py
index ea55d5ea1ced..abc1fd737782 100644
--- a/tools/perf/tests/shell/lib/perf_json_output_lint.py
+++ b/tools/perf/tests/shell/lib/perf_json_output_lint.py
@@ -15,6 +15,7 @@ ap.add_argument('--event', action='store_true')
 ap.add_argument('--per-core', action='store_true')
 ap.add_argument('--per-thread', action='store_true')
 ap.add_argument('--per-cache', action='store_true')
+ap.add_argument('--per-cluster', action='store_true')
 ap.add_argument('--per-die', action='store_true')
 ap.add_argument('--per-node', action='store_true')
 ap.add_argument('--per-socket', action='store_true')
@@ -49,6 +50,7 @@ def check_json_output(expected_items):
       'cgroup': lambda x: True,
       'cpu': lambda x: isint(x),
       'cache': lambda x: True,
+      'cluster': lambda x: True,
       'die': lambda x: True,
       'event': lambda x: True,
       'event-runtime': lambda x: isfloat(x),
@@ -88,7 +90,7 @@ try:
     expected_items = 7
   elif args.interval or args.per_thread or args.system_wide_no_aggr:
     expected_items = 8
-  elif args.per_core or args.per_socket or args.per_node or args.per_die or args.per_cache:
+  elif args.per_core or args.per_socket or args.per_node or args.per_die or args.per_cluster or args.per_cache:
     expected_items = 9
   else:
     # If no option is specified, don't check the number of items.
diff --git a/tools/perf/tests/shell/lib/stat_output.sh b/tools/perf/tests/shell/lib/stat_output.sh
index 3cc158a64326..c81d6a9f7983 100644
--- a/tools/perf/tests/shell/lib/stat_output.sh
+++ b/tools/perf/tests/shell/lib/stat_output.sh
@@ -97,6 +97,18 @@ check_per_cache_instance()
 	echo "[Success]"
 }
 
+check_per_cluster()
+{
+	echo -n "Checking $1 output: per cluster "
+	if ParanoidAndNotRoot 0
+	then
+		echo "[Skip] paranoid and not root"
+		return
+	fi
+	perf stat --per-cluster -a $2 true
+	echo "[Success]"
+}
+
 check_per_die()
 {
 	echo -n "Checking $1 output: per die "
diff --git a/tools/perf/tests/shell/stat+csv_output.sh b/tools/perf/tests/shell/stat+csv_output.sh
index f1818fa6d9ce..fc2d8cc6e5e0 100755
--- a/tools/perf/tests/shell/stat+csv_output.sh
+++ b/tools/perf/tests/shell/stat+csv_output.sh
@@ -42,6 +42,7 @@ function commachecker()
 	;; "--per-socket")	exp=8
 	;; "--per-node")	exp=8
 	;; "--per-die")		exp=8
+	;; "--per-cluster")	exp=8
 	;; "--per-cache")	exp=8
 	esac
 
@@ -79,6 +80,7 @@ then
 	check_system_wide_no_aggr "CSV" "$perf_cmd"
 	check_per_core "CSV" "$perf_cmd"
 	check_per_cache_instance "CSV" "$perf_cmd"
+	check_per_cluster "CSV" "$perf_cmd"
 	check_per_die "CSV" "$perf_cmd"
 	check_per_socket "CSV" "$perf_cmd"
 else
diff --git a/tools/perf/tests/shell/stat+json_output.sh b/tools/perf/tests/shell/stat+json_output.sh
index 3bc900533a5d..2b9c6212dffc 100755
--- a/tools/perf/tests/shell/stat+json_output.sh
+++ b/tools/perf/tests/shell/stat+json_output.sh
@@ -122,6 +122,18 @@ check_per_cache_instance()
 	echo "[Success]"
 }
 
+check_per_cluster()
+{
+	echo -n "Checking json output: per cluster "
+	if ParanoidAndNotRoot 0
+	then
+		echo "[Skip] paranoia and not root"
+		return
+	fi
+	perf stat -j --per-cluster -a true 2>&1 | $PYTHON $pythonchecker --per-cluster
+	echo "[Success]"
+}
+
 check_per_die()
 {
 	echo -n "Checking json output: per die "
@@ -200,6 +212,7 @@ then
 	check_system_wide_no_aggr
 	check_per_core
 	check_per_cache_instance
+	check_per_cluster
 	check_per_die
 	check_per_socket
 else
diff --git a/tools/perf/tests/shell/stat+std_output.sh b/tools/perf/tests/shell/stat+std_output.sh
index 4fcdd1a9142c..16f61e86afc5 100755
--- a/tools/perf/tests/shell/stat+std_output.sh
+++ b/tools/perf/tests/shell/stat+std_output.sh
@@ -40,6 +40,7 @@ function commachecker()
 	;; "--per-node")	prefix=3
 	;; "--per-die")		prefix=3
 	;; "--per-cache")	prefix=3
+	;; "--per-cluster")	prefix=3
 	esac
 
 	while read line
@@ -99,6 +100,7 @@ then
 	check_system_wide_no_aggr "STD" "$perf_cmd"
 	check_per_core "STD" "$perf_cmd"
 	check_per_cache_instance "STD" "$perf_cmd"
+	check_per_cluster "STD" "$perf_cmd"
 	check_per_die "STD" "$perf_cmd"
 	check_per_socket "STD" "$perf_cmd"
 else
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 0581ee0fa5f2..356e30c42cd8 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -222,6 +222,8 @@ static int aggr_cpu_id__cmp(const void *a_pointer, const void *b_pointer)
 		return a->socket - b->socket;
 	else if (a->die != b->die)
 		return a->die - b->die;
+	else if (a->cluster != b->cluster)
+		return a->cluster - b->cluster;
 	else if (a->cache_lvl != b->cache_lvl)
 		return a->cache_lvl - b->cache_lvl;
 	else if (a->cache != b->cache)
@@ -309,6 +311,30 @@ struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data)
 	return id;
 }
 
+int cpu__get_cluster_id(struct perf_cpu cpu)
+{
+	int value, ret = cpu__get_topology_int(cpu.cpu, "cluster_id", &value);
+
+	return ret ?: value;
+}
+
+struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data)
+{
+	int cluster = cpu__get_cluster_id(cpu);
+	struct aggr_cpu_id id;
+
+	/* There is no cluster_id on legacy system. */
+	if (cluster == -1)
+		cluster = 0;
+
+	id = aggr_cpu_id__die(cpu, data);
+	if (aggr_cpu_id__is_empty(&id))
+		return id;
+
+	id.cluster = cluster;
+	return id;
+}
+
 int cpu__get_core_id(struct perf_cpu cpu)
 {
 	int value, ret = cpu__get_topology_int(cpu.cpu, "core_id", &value);
@@ -320,8 +346,8 @@ 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);
 
-	/* aggr_cpu_id__die returns a struct with socket and die set. */
-	id = aggr_cpu_id__die(cpu, data);
+	/* aggr_cpu_id__die returns a struct with socket die, and cluster set. */
+	id = aggr_cpu_id__cluster(cpu, data);
 	if (aggr_cpu_id__is_empty(&id))
 		return id;
 
@@ -683,6 +709,7 @@ 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->cluster == b->cluster &&
 		a->cache_lvl == b->cache_lvl &&
 		a->cache == b->cache &&
 		a->core == b->core &&
@@ -695,6 +722,7 @@ bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a)
 		a->node == -1 &&
 		a->socket == -1 &&
 		a->die == -1 &&
+		a->cluster == -1 &&
 		a->cache_lvl == -1 &&
 		a->cache == -1 &&
 		a->core == -1 &&
@@ -708,6 +736,7 @@ struct aggr_cpu_id aggr_cpu_id__empty(void)
 		.node = -1,
 		.socket = -1,
 		.die = -1,
+		.cluster = -1,
 		.cache_lvl = -1,
 		.cache = -1,
 		.core = -1,
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 9df2aeb34d3d..26cf76c693f5 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -20,6 +20,8 @@ struct aggr_cpu_id {
 	int socket;
 	/** The die id as read from /sys/devices/system/cpu/cpuX/topology/die_id. */
 	int die;
+	/** The cluster id as read from /sys/devices/system/cpu/cpuX/topology/cluster_id */
+	int cluster;
 	/** The cache level as read from /sys/devices/system/cpu/cpuX/cache/indexY/level */
 	int cache_lvl;
 	/**
@@ -86,6 +88,11 @@ int cpu__get_socket_id(struct perf_cpu cpu);
  * /sys/devices/system/cpu/cpuX/topology/die_id for the given CPU.
  */
 int cpu__get_die_id(struct perf_cpu cpu);
+/**
+ * cpu__get_cluster_id - Returns the cluster id as read from
+ * /sys/devices/system/cpu/cpuX/topology/cluster_id for the given CPU
+ */
+int cpu__get_cluster_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.
@@ -127,9 +134,15 @@ struct aggr_cpu_id aggr_cpu_id__socket(struct perf_cpu 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.
+ * aggr_cpu_id__cluster - Create an aggr_cpu_id with cluster, die and socket
+ * populated with the cluster, die and socket for cpu. The function signature
+ * is compatible with aggr_cpu_id_get_t.
+ */
+struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data);
+/**
+ * aggr_cpu_id__core - Create an aggr_cpu_id with the core, cluster, 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(struct perf_cpu cpu, void *data);
 /**
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 7c527e65c186..2a2c37cc40b7 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -12,6 +12,7 @@ struct perf_cpu_map;
 struct cpu_topology_map {
 	int	socket_id;
 	int	die_id;
+	int	cluster_id;
 	int	core_id;
 };
 
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 8c61f8627ebc..4dfe7d9517a9 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -201,6 +201,9 @@ static void print_aggr_id_std(struct perf_stat_config *config,
 		snprintf(buf, sizeof(buf), "S%d-D%d-L%d-ID%d",
 			 id.socket, id.die, id.cache_lvl, id.cache);
 		break;
+	case AGGR_CLUSTER:
+		snprintf(buf, sizeof(buf), "S%d-D%d-CLS%d", id.socket, id.die, id.cluster);
+		break;
 	case AGGR_DIE:
 		snprintf(buf, sizeof(buf), "S%d-D%d", id.socket, id.die);
 		break;
@@ -251,6 +254,10 @@ static void print_aggr_id_csv(struct perf_stat_config *config,
 		fprintf(config->output, "S%d-D%d-L%d-ID%d%s%d%s",
 			id.socket, id.die, id.cache_lvl, id.cache, sep, aggr_nr, sep);
 		break;
+	case AGGR_CLUSTER:
+		fprintf(config->output, "S%d-D%d-CLS%d%s%d%s",
+			id.socket, id.die, id.cluster, sep, aggr_nr, sep);
+		break;
 	case AGGR_DIE:
 		fprintf(output, "S%d-D%d%s%d%s",
 			id.socket, id.die, sep, aggr_nr, sep);
@@ -300,6 +307,10 @@ static void print_aggr_id_json(struct perf_stat_config *config,
 		fprintf(output, "\"cache\" : \"S%d-D%d-L%d-ID%d\", \"aggregate-number\" : %d, ",
 			id.socket, id.die, id.cache_lvl, id.cache, aggr_nr);
 		break;
+	case AGGR_CLUSTER:
+		fprintf(output, "\"cluster\" : \"S%d-D%d-CLS%d\", \"aggregate-number\" : %d, ",
+			id.socket, id.die, id.cluster, aggr_nr);
+		break;
 	case AGGR_DIE:
 		fprintf(output, "\"die\" : \"S%d-D%d\", \"aggregate-number\" : %d, ",
 			id.socket, id.die, aggr_nr);
@@ -1248,6 +1259,7 @@ static void print_header_interval_std(struct perf_stat_config *config,
 	case AGGR_NODE:
 	case AGGR_SOCKET:
 	case AGGR_DIE:
+	case AGGR_CLUSTER:
 	case AGGR_CACHE:
 	case AGGR_CORE:
 		fprintf(output, "#%*s %-*s cpus",
@@ -1550,6 +1562,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
 	switch (config->aggr_mode) {
 	case AGGR_CORE:
 	case AGGR_CACHE:
+	case AGGR_CLUSTER:
 	case AGGR_DIE:
 	case AGGR_SOCKET:
 	case AGGR_NODE:
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 4357ba114822..d6e5c8787ba2 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -48,6 +48,7 @@ enum aggr_mode {
 	AGGR_GLOBAL,
 	AGGR_SOCKET,
 	AGGR_DIE,
+	AGGR_CLUSTER,
 	AGGR_CACHE,
 	AGGR_CORE,
 	AGGR_THREAD,
-- 
2.24.0



From patchwork-bot+netdevbpf at kernel.org  Wed Feb  7 19:10:31 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Thu, 08 Feb 2024 03:10:31 +0000
Subject: [PATCH net-next v5 0/7] MT7530 DSA Subdriver Improvements Act II
In-Reply-To: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
References: <20240206-for-netnext-mt7530-improvements-2-v5-0-d7d92a185cb1@arinc9.com>
Message-ID: <170736183112.28016.638375642700204813.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Tue, 06 Feb 2024 01:08:01 +0300 you wrote:
> Hello!
> 
> This is the second patch series with the goal of simplifying the MT7530 DSA
> subdriver and improving support for MT7530, MT7531, and the switch on the
> MT7988 SoC.
> 
> I have done a simple ping test to confirm basic communication on all switch
> ports on MCM and standalone MT7530, and MT7531 switch with this patch
> series applied.
> 
> [...]

Here is the summary with links:
  - [net-next,v5,1/7] net: dsa: mt7530: empty default case on mt7530_setup_port5()
    https://git.kernel.org/netdev/net-next/c/01fc42942e30
  - [net-next,v5,2/7] net: dsa: mt7530: move XTAL check to mt7530_setup()
    https://git.kernel.org/netdev/net-next/c/fd7929095a52
  - [net-next,v5,3/7] net: dsa: mt7530: simplify mt7530_pad_clk_setup()
    https://git.kernel.org/netdev/net-next/c/4eec447ef640
  - [net-next,v5,4/7] net: dsa: mt7530: call port 6 setup from mt7530_mac_config()
    https://git.kernel.org/netdev/net-next/c/4ea4c040ddc8
  - [net-next,v5,5/7] net: dsa: mt7530: remove pad_setup function pointer
    https://git.kernel.org/netdev/net-next/c/8c2703f55837
  - [net-next,v5,6/7] net: dsa: mt7530: correct port capabilities of MT7988
    https://git.kernel.org/netdev/net-next/c/c9d70a1d3d64
  - [net-next,v5,7/7] net: dsa: mt7530: do not clear config->supported_interfaces
    https://git.kernel.org/netdev/net-next/c/b43990bc552e

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From yangyicong at huawei.com  Wed Feb  7 19:25:18 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Thu, 8 Feb 2024 11:25:18 +0800
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
Message-ID: <20240208032518.25830-1-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Some HiSilicon platforms provide PCIe PMU devices for monitoring the
throughput and latency of PCIe traffic. With the support of PCIe PMU
we can enable the perf iostat mode.

The HiSilicon PCIe PMU can support measuring the throughput of certain
TLP types and of certain root port. Totally 6 metrics are provided in
the unit of MB:

- Inbound MWR: The memory write TLPs from the devices downstream the root port
- Inbound MRD: The memory read TLPs from the devices downstream the root port
- Inbound CPL: The completion TLPs from the devices downstream the root port
- Outbound MWR: The memory write TLPs from the CPU to the downstream devices
- Outbound MRD: The memory read TLPs from the CPU to the downstream devices
- Outbound CPL: The completions TLPs from the CPU to the downstream devices

Since the PMU measures the throughput in DWords. So we need to calculate
the throughput in MB like:
  Count * 4B / 1024 / 1024

Some of the display of the `perf iostat` will be like:
[root at localhost tmp]# ./perf iostat list
hisi_pcie0_core2<0000:40:00.0>
hisi_pcie2_core2<0000:5f:00.0>
hisi_pcie0_core1<0000:16:00.0>
hisi_pcie0_core1<0000:16:04.0>
[root at localhost tmp]# ./perf iostat --timeout 10000

 Performance counter stats for 'system wide':

    port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
0000:40:00.0                    0                    0                    0                    0                    0                    0
0000:5f:00.0                    0                    0                    0                    0                    0                    0
0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
0000:16:04.0                    0                    0                    0                    0                    0                    0

      10.008227512 seconds time elapsed

[root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
-numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
-norandommap -group_reporting -runtime=10 -time_based -bs=64k

 Performance counter stats for 'system wide':

    port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
0000:40:00.0                    0                    0                    0                    0                    0                    0
0000:5f:00.0                    0                    0                    0                    0                    0                    0
0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
0000:16:04.0                    0                    0                    0                    0                    0                    0

      10.168561767 seconds time elapsed

       0.465373000 seconds user
       1.952948000 seconds sys

More information of the HiSilicon PCIe PMU can be found at
Documentation/admin-guide/perf/hisi-pcie-pmu.rst.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
Change since v1:
- Tweak the comments per Jonathan
- Use an enum to define the metrics and relevant command templates per Jonathan
Thanks!
Link: https://lore.kernel.org/linux-perf-users/20240123071201.30914-1-yangyicong at huawei.com/

 tools/perf/arch/arm64/util/Build         |   1 +
 tools/perf/arch/arm64/util/hisi-iostat.c | 439 +++++++++++++++++++++++
 2 files changed, 440 insertions(+)
 create mode 100644 tools/perf/arch/arm64/util/hisi-iostat.c

diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
index 78ef7115be3d..4e8dabf98b29 100644
--- a/tools/perf/arch/arm64/util/Build
+++ b/tools/perf/arch/arm64/util/Build
@@ -3,6 +3,7 @@ perf-y += machine.o
 perf-y += perf_regs.o
 perf-y += tsc.o
 perf-y += pmu.o
+perf-y += hisi-iostat.o
 perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
 perf-$(CONFIG_DWARF)     += dwarf-regs.o
 perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
diff --git a/tools/perf/arch/arm64/util/hisi-iostat.c b/tools/perf/arch/arm64/util/hisi-iostat.c
new file mode 100644
index 000000000000..43df43b83f3f
--- /dev/null
+++ b/tools/perf/arch/arm64/util/hisi-iostat.c
@@ -0,0 +1,439 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * perf iostat support for HiSilicon PCIe PMU.
+ * Partly derived from tools/perf/arch/x86/util/iostat.c.
+ *
+ * Copyright (c) 2024 HiSilicon Technologies Co., Ltd.
+ * Author: Yicong Yang <yangyicong at hisilicon.com>
+ */
+
+#include <api/fs/fs.h>
+#include <linux/err.h>
+#include <linux/zalloc.h>
+#include <linux/limits.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "util/counts.h"
+#include "util/cpumap.h"
+#include "util/debug.h"
+#include "util/iostat.h"
+#include "util/pmu.h"
+
+#define PCI_DEFAULT_DOMAIN		0
+#define PCI_DEVICE_NAME_PATTERN		"%04x:%02hhx:%02hhx.%hhu"
+#define PCI_ROOT_BUS_DEVICES_PATH	"bus/pci/devices"
+
+enum hisi_iostat_metric_type {
+	METRIC_IN_MWR,		/* Inbound Memory Write */
+	METRIC_IN_MRD,		/* Inbound Memory Read */
+	METRIC_IN_CPL,		/* Inbound Memory Completion */
+	METRIC_OUT_MWR,		/* Outbound Memory Write */
+	METRIC_OUT_MRD,		/* Outbound Memory Read */
+	METRIC_OUT_CPL,		/* Outbound Memory Completion */
+	METRIC_TYPE_MAX,
+};
+
+static const char * const hisi_iostat_metrics[] = {
+	[METRIC_IN_MWR] = "Inbound MWR(MB)",
+	[METRIC_IN_MRD] = "Inbound MRD(MB)",
+	[METRIC_IN_CPL] = "Inbound CPL(MB)",
+	[METRIC_OUT_MWR] = "Outbound MWR(MB)",
+	[METRIC_OUT_MRD] = "Outbound MRD(MB)",
+	[METRIC_OUT_CPL] = "Outbound CPL(MB)",
+};
+
+static const char * const hisi_iostat_cmd_template[] = {
+	[METRIC_IN_MWR] = "hisi_pcie%hu_core%hu/event=0x0104,port=0x%hx/",
+	[METRIC_IN_MRD] = "hisi_pcie%hu_core%hu/event=0x0804,port=0x%hx/",
+	[METRIC_IN_CPL] = "hisi_pcie%hu_core%hu/event=0x2004,port=0x%hx/",
+	[METRIC_OUT_MWR] = "hisi_pcie%hu_core%hu/event=0x0105,port=0x%hx/",
+	[METRIC_OUT_MRD] = "hisi_pcie%hu_core%hu/event=0x0405,port=0x%hx/",
+	[METRIC_OUT_CPL] = "hisi_pcie%hu_core%hu/event=0x1005,port=0x%hx/",
+};
+
+struct hisi_pcie_root_port {
+	struct list_head list;
+	/* Is this Root Port selected for monitoring */
+	bool selected;
+	/* IDs to locate the PMU */
+	u16 sicl_id;
+	u16 core_id;
+	/* Filter mask for this Root Port */
+	u16 mask;
+	/* PCIe Root Port's <domain>:<bus>:<device>.<function> */
+	u32 domain;
+	u8 bus;
+	u8 dev;
+	u8 fn;
+};
+
+LIST_HEAD(hisi_pcie_root_ports_list);
+static int hisi_pcie_root_ports_num;
+
+static void hisi_pcie_init_root_port_mask(struct hisi_pcie_root_port *rp)
+{
+	rp->mask = BIT(rp->dev << 1);
+}
+
+/*
+ * Select specific Root Port to monitor. Return 0 if successfully find the
+ * Root Port, Otherwise -EINVAL.
+ */
+static int hisi_pcie_root_ports_select_one(u32 domain, u8 bus, u8 dev, u8 fn)
+{
+	struct hisi_pcie_root_port *rp;
+
+	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list)
+		if (domain == rp->domain && bus == rp->bus &&
+		    dev == rp->dev && fn == rp->fn) {
+			rp->selected = true;
+			return 0;
+		}
+
+	return -EINVAL;
+}
+
+static void hisi_pcie_root_ports_select_all(void)
+{
+	struct hisi_pcie_root_port *rp;
+
+	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list)
+		rp->selected = true;
+}
+
+static void hisi_pcie_root_ports_add(u16 sicl_id, u16 core_id, u8 target_bus)
+{
+	const char *sysfs = sysfs__mountpoint();
+	struct hisi_pcie_root_port *rp;
+	struct dirent *dent;
+	char path[PATH_MAX];
+	u8 bus, dev, fn;
+	u32 domain;
+	DIR *dir;
+	int ret;
+
+	snprintf(path, PATH_MAX, "%s/%s", sysfs, PCI_ROOT_BUS_DEVICES_PATH);
+	dir = opendir(path);
+	if (!dir)
+		return;
+
+	/* Scan the PCI root bus to find the match root port on @target_bus */
+	while ((dent = readdir(dir))) {
+		ret = sscanf(dent->d_name, PCI_DEVICE_NAME_PATTERN,
+			     &domain, &bus, &dev, &fn);
+		if (ret != 4 || bus != target_bus)
+			continue;
+
+		rp = zalloc(sizeof(*rp));
+		if (!rp)
+			continue;
+
+		rp->selected = false;
+		rp->sicl_id = sicl_id;
+		rp->core_id = core_id;
+		rp->domain = domain;
+		rp->bus = bus;
+		rp->dev = dev;
+		rp->fn = fn;
+
+		hisi_pcie_init_root_port_mask(rp);
+
+		list_add(&rp->list, &hisi_pcie_root_ports_list);
+		hisi_pcie_root_ports_num++;
+
+		pr_debug3("Found root port %s\n", dent->d_name);
+	}
+
+	closedir(dir);
+}
+
+/* Scan the PMUs and build the mapping of the Root Ports to the PMU */
+static int hisi_pcie_root_ports_init(void)
+{
+	char event_source[PATH_MAX], bus_path[PATH_MAX];
+	unsigned long long bus;
+	u16 sicl_id, core_id;
+	struct dirent *dent;
+	DIR *dir;
+
+	perf_pmu__event_source_devices_scnprintf(event_source, sizeof(event_source));
+	dir = opendir(event_source);
+	if (!dir)
+		return -ENOENT;
+
+	while ((dent = readdir(dir))) {
+		/*
+		 * This HiSilicon PCIe PMU will be named as:
+		 *   hisi_pcie<sicl_id>_core<core_id>
+		 */
+		if ((sscanf(dent->d_name, "hisi_pcie%hu_core%hu", &sicl_id, &core_id)) != 2)
+			continue;
+
+		/*
+		 * Driver will export the root port it can monitor through
+		 * the "bus" sysfs attribute.
+		 */
+		scnprintf(bus_path, sizeof(bus_path), "%s/hisi_pcie%hu_core%hu/bus",
+			  event_source, sicl_id, core_id);
+
+		/*
+		 * Per PCIe spec the bus should be 8bit, use unsigned long long
+		 * for the convience of the library function.
+		 */
+		if (filename__read_ull(bus_path, &bus))
+			continue;
+
+		pr_debug3("Found pmu %s bus 0x%llx\n", dent->d_name, bus);
+
+		hisi_pcie_root_ports_add(sicl_id, core_id, (u8)bus);
+	}
+
+	closedir(dir);
+	return hisi_pcie_root_ports_num > 0 ? 0 : -ENOENT;
+}
+
+static void hisi_pcie_root_ports_free(void)
+{
+	struct hisi_pcie_root_port *rp, *tmp;
+
+	if (hisi_pcie_root_ports_num == 0)
+		return;
+
+	list_for_each_entry_safe(rp, tmp, &hisi_pcie_root_ports_list, list) {
+		list_del(&rp->list);
+		zfree(&rp);
+		hisi_pcie_root_ports_num--;
+	}
+}
+
+static int hisi_iostat_add_events(struct evlist *evl)
+{
+	struct hisi_pcie_root_port *rp;
+	struct evsel *evsel;
+	unsigned int i, j;
+	char *iostat_cmd;
+	int pos = 0;
+	int ret;
+
+	if (!hisi_pcie_root_ports_num)
+		return -ENOENT;
+
+	iostat_cmd = zalloc(PATH_MAX);
+	if (!iostat_cmd)
+		return -ENOMEM;
+
+	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list) {
+		if (!rp->selected)
+			continue;
+
+		iostat_cmd[pos++] = '{';
+		for (j = 0; j < METRIC_TYPE_MAX; j++) {
+			pos += snprintf(iostat_cmd + pos, ARG_MAX - pos - 1,
+					hisi_iostat_cmd_template[j],
+					rp->sicl_id, rp->core_id, rp->mask);
+
+			if (j == METRIC_TYPE_MAX - 1)
+				iostat_cmd[pos++] = '}';
+			else
+				iostat_cmd[pos++] = ',';
+		}
+
+		ret = parse_event(evl, iostat_cmd);
+		if (ret)
+			break;
+
+		i = 0;
+		evlist__for_each_entry_reverse(evl, evsel) {
+			if (i == METRIC_TYPE_MAX)
+				break;
+
+			evsel->priv = rp;
+			i++;
+		}
+
+		memset(iostat_cmd, 0, PATH_MAX);
+		pos = 0;
+	}
+
+	zfree(&iostat_cmd);
+	return ret;
+}
+
+int iostat_prepare(struct evlist *evlist,
+		   struct perf_stat_config *config)
+{
+	if (evlist->core.nr_entries > 0) {
+		pr_warning("The -e and -M options are not supported."
+			   "All chosen events/metrics will be dropped\n");
+		evlist__delete(evlist);
+		evlist = evlist__new();
+		if (!evlist)
+			return -ENOMEM;
+	}
+
+	config->metric_only = true;
+	config->aggr_mode = AGGR_GLOBAL;
+
+	return hisi_iostat_add_events(evlist);
+}
+
+static int hisi_pcie_root_ports_list_filter(const char *str)
+{
+	char *tok, *tmp, *copy = NULL;
+	u8 bus, dev, fn;
+	u32 domain;
+	int ret;
+
+	copy = strdup(str);
+	if (!copy)
+		return -ENOMEM;
+
+	for (tok = strtok_r(copy, ",", &tmp); tok; tok = strtok_r(NULL, ",", &tmp)) {
+		ret = sscanf(tok, PCI_DEVICE_NAME_PATTERN, &domain, &bus, &dev, &fn);
+		if (ret != 4) {
+			ret = -EINVAL;
+			break;
+		}
+
+		ret = hisi_pcie_root_ports_select_one(domain, bus, dev, fn);
+		if (ret)
+			break;
+	}
+
+	zfree(&copy);
+	return ret;
+}
+
+int iostat_parse(const struct option *opt, const char *str, int unset __maybe_unused)
+{
+	struct perf_stat_config *config = (struct perf_stat_config *)opt->data;
+	int ret;
+
+	ret = hisi_pcie_root_ports_init();
+	if (!ret) {
+		config->iostat_run = true;
+
+		if (!str) {
+			iostat_mode = IOSTAT_RUN;
+			hisi_pcie_root_ports_select_all();
+		} else if (!strcmp(str, "list")) {
+			iostat_mode = IOSTAT_LIST;
+			hisi_pcie_root_ports_select_all();
+		} else {
+			iostat_mode = IOSTAT_RUN;
+			ret = hisi_pcie_root_ports_list_filter(str);
+		}
+	}
+
+	return ret;
+}
+
+static void hisi_pcie_root_port_show(FILE *output,
+				     const struct hisi_pcie_root_port * const rp)
+{
+	if (output && rp)
+		fprintf(output, "hisi_pcie%hu_core%hu<" PCI_DEVICE_NAME_PATTERN ">\n",
+			rp->sicl_id, rp->core_id, rp->domain, rp->bus, rp->dev, rp->fn);
+}
+
+void iostat_list(struct evlist *evlist __maybe_unused, struct perf_stat_config *config)
+{
+	struct hisi_pcie_root_port *rp = NULL;
+	struct evsel *evsel;
+
+	evlist__for_each_entry(evlist, evsel) {
+		if (rp != evsel->priv) {
+			hisi_pcie_root_port_show(config->output, evsel->priv);
+			rp = evsel->priv;
+		}
+	}
+}
+
+void iostat_release(struct evlist *evlist)
+{
+	struct evsel *evsel;
+
+	evlist__for_each_entry(evlist, evsel)
+		evsel->priv = NULL;
+
+	hisi_pcie_root_ports_free();
+}
+
+void iostat_print_header_prefix(struct perf_stat_config *config)
+{
+	if (config->csv_output)
+		fputs("port,", config->output);
+	else if (config->interval)
+		fprintf(config->output, "#          time    port         ");
+	else
+		fprintf(config->output, "   port         ");
+}
+
+void iostat_print_metric(struct perf_stat_config *config, struct evsel *evsel,
+			 struct perf_stat_output_ctx *out)
+{
+	struct perf_counts_values *count;
+	const char *iostat_metric;
+	double iostat_value;
+
+	iostat_metric = hisi_iostat_metrics[evsel->core.idx % METRIC_TYPE_MAX];
+
+	/* We're using AGGR_GLOBAL so there's only one aggr counts aggr[0]. */
+	count = &evsel->stats->aggr[0].counts;
+
+	/* The counts has been scaled, we can use it directly. */
+	iostat_value = (double)count->val;
+
+	/*
+	 * Calculate the bandwidth in MiB since the PMU counts in DWord.
+	 * Display two digits after decimal point for better accuracy if the
+	 * value is non-zero.
+	 */
+	out->print_metric(config, out->ctx, NULL,
+			  iostat_value > 0 ? "%8.2f" : "%8.0f", iostat_metric,
+			  iostat_value * sizeof(uint32_t) / (1024 * 1024));
+}
+
+void iostat_prefix(struct evlist *evlist, struct perf_stat_config *config,
+		   char *prefix, struct timespec *ts)
+{
+	struct hisi_pcie_root_port *rp = evlist->selected->priv;
+
+	if (rp) {
+		if (ts)
+			sprintf(prefix, "%6lu.%09lu%s" PCI_DEVICE_NAME_PATTERN "%s",
+				ts->tv_sec, ts->tv_nsec, config->csv_sep,
+				rp->domain, rp->bus, rp->dev, rp->fn,
+				config->csv_sep);
+		else
+			sprintf(prefix, PCI_DEVICE_NAME_PATTERN "%s",
+				rp->domain, rp->bus, rp->dev, rp->fn,
+				config->csv_sep);
+	}
+}
+
+void iostat_print_counters(struct evlist *evlist, struct perf_stat_config *config,
+			   struct timespec *ts, char *prefix,
+			   iostat_print_counter_t print_cnt_cb, void *arg)
+{
+	struct evsel *counter = evlist__first(evlist);
+	void *perf_device;
+
+	evlist__set_selected(evlist, counter);
+	iostat_prefix(evlist, config, prefix, ts);
+	fprintf(config->output, "%s", prefix);
+	evlist__for_each_entry(evlist, counter) {
+		perf_device = evlist->selected->priv;
+		if (perf_device && perf_device != counter->priv) {
+			evlist__set_selected(evlist, counter);
+			iostat_prefix(evlist, config, prefix, ts);
+			fprintf(config->output, "\n%s", prefix);
+		}
+		print_cnt_cb(config, counter, arg);
+	}
+	fputc('\n', config->output);
+}
-- 
2.24.0



From Dharma.B at microchip.com  Wed Feb  7 19:59:55 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Thu, 8 Feb 2024 03:59:55 +0000
Subject: [PATCH] dt-bindings: input: atmel,captouch: convert bindings to
 YAML
In-Reply-To: <982e81db-3bf9-49e9-b57f-a91612d62f5c@linaro.org>
References: <20240207090853.188400-1-dharma.b@microchip.com>
 <982e81db-3bf9-49e9-b57f-a91612d62f5c@linaro.org>
Message-ID: <09c25824-f56b-4598-b8cc-1df992812754@microchip.com>

Hi Krzysztof,

On 07/02/24 8:45 pm, Krzysztof Kozlowski wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On 07/02/2024 10:08, Dharma Balasubiramani wrote:
>> Convert the Atmel capacitive touchscreen bindings to YAML format.
>>
>> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.co
> 
> Thank you for your patch. There is something to discuss/improve.
> 
>> +
>> +properties:
>> +  compatible:
>> +    const: atmel,captouch
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  linux,keycodes:
>> +    minItems: 1
>> +    maxItems: 8
>> +
>> +  autorepeat:
>> +    type: boolean
> 
> You can drop entire property, coming from input.yaml.

Sure, I will drop the 'linux,keycodes' and 'autorepeat' properties.
> 
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - interrupts
>> +  - linux,keycodes
>> +
>> +additionalProperties: false
> 
> Instead:
> unevaluatedProperties: false

Noted, Thanks.
> 
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/interrupt-controller/irq.h>
>> +    #include <dt-bindings/input/linux-event-codes.h>
>> +    i2c {
>> +      #address-cells = <1>;
>> +      #size-cells = <0>;
>> +      atmel-captouch at 51 {
> 
> Instead:
> touchscreen? touchpad? if none of these, then just "touch at 51"

I will go with touch at 51.

Thanks.
> 
>> +        compatible = "atmel,captouch";
>> +        reg = <0x51>;
> 
> 
> Best regards,
> Krzysztof
> 

-- 
With Best Regards,
Dharma B.


From vigneshr at ti.com  Wed Feb  7 20:24:05 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 8 Feb 2024 09:54:05 +0530
Subject: [PATCH 3/3] arm64: dts: ti: Add DT overlay for PCIe + USB3.0
 SERDES personality card
In-Reply-To: <a576961e-b737-49a8-80a5-65c87fff845d@kernel.org>
References: <20240126114530.40913-1-rogerq@kernel.org>
 <20240126114530.40913-4-rogerq@kernel.org>
 <547d7069-3457-4ee3-ad1c-fedc9db5da62@ti.com>
 <a576961e-b737-49a8-80a5-65c87fff845d@kernel.org>
Message-ID: <f0a05e0f-a40b-425d-883f-f3222f323dcd@ti.com>



On 06/02/24 19:06, Roger Quadros wrote:
> 
> 
> On 05/02/2024 16:46, Vignesh Raghavendra wrote:
>>
>>
>> On 26/01/24 17:15, Roger Quadros wrote:
>>> From: Kishon Vijay Abraham I <kishon at ti.com>
>>>
>>
>> [...]
>>
>>>  # Boards with J7200 SoC
>>>  k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso
>>> new file mode 100644
>>> index 000000000000..c63b7241c005
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso
>>> @@ -0,0 +1,67 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
>>> +/**
>>> + * DT overlay for SERDES personality card: 1lane PCIe + USB3.0 DRD on AM654 EVM
>>> + *
>>> + * Copyright (C) 2018-2024 Texas Instruments Incorporated - http://www.ti.com/
>>> + */
>>> +
>>> +/dts-v1/;
>>> +/plugin/;
>>> +#include <dt-bindings/gpio/gpio.h>
>>> +#include <dt-bindings/phy/phy.h>
>>> +#include <dt-bindings/phy/phy-am654-serdes.h>
>>> +
>>> +#include "k3-pinctrl.h"
>>> +
>>> +&serdes1 {
>>> +	status = "okay";
>>> +};
>>> +
>>> +&pcie1_rc {
>>> +	num-lanes = <1>;
>>> +	phys = <&serdes1 PHY_TYPE_PCIE 0>;
>>> +	phy-names = "pcie-phy0";
>>> +	reset-gpios = <&pca9555 5 GPIO_ACTIVE_HIGH>;
>>> +	status = "okay";
>>> +};
>>> +
>>> +&pcie1_ep {
>>> +	num-lanes = <1>;
>>> +	phys = <&serdes1 PHY_TYPE_PCIE 0>;
>>> +	phy-names = "pcie-phy0";
>>> +};
>>> +
>>> +&main_pmx0 {
>>> +	usb0_pins_default: usb0_pins_default {
>>
>> No underscores in node-name and also should end with -pins
>>
>>> +		pinctrl-single,pins = <
>>> +			AM65X_IOPAD(0x02bc, PIN_OUTPUT, 0) /* (AD9) USB0_DRVVBUS */
>>> +		>;
>>> +	};
>>> +};
>>> +
>>> +&serdes0 {
>>> +	status = "okay";
>>> +	assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
>>> +	assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
>>> +};
>>> +
>>> +&dwc3_0 {
>>> +	status = "okay";
>>> +	assigned-clock-parents = <&k3_clks 151 4>,      /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
>>> +	<&k3_clks 151 8>;      /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */
>>> +	phys = <&serdes0 PHY_TYPE_USB3 0>;
>>> +	phy-names = "usb3-phy";
>>> +};
>>> +
>>> +&usb0 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&usb0_pins_default>;
>>> +	dr_mode = "host";
>>> +	maximum-speed = "super-speed";
>>> +	snps,dis-u1-entry-quirk;
>>> +	snps,dis-u2-entry-quirk;
>>> +};
>>> +
>>> +&usb0_phy {
>>> +	status = "okay";
>>> +};
>>
>>
>> BTW, this breaks build on 6.8-rc1
>>
>>
>>   DTOVL   arch/arm64/boot/dts/ti/k3-am654-gp-evm.dtb
>>
>> Failed to apply 'arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtbo': FDT_ERR_NOTFOUND
>>
>>
> 
> It builds fine for me. Did the 3rd patch apply cleanly for you?
> 


Yes, build failure is due to the fact that I picked up Andrew's patch to
remove pcie_ep node. Could you please respin this on top of ti-next /
linux-next?

--
Regards
Vignesh


From yuzenghui at huawei.com  Wed Feb  7 21:00:08 2024
From: yuzenghui at huawei.com (Zenghui Yu)
Date: Thu, 8 Feb 2024 13:00:08 +0800
Subject: [PATCH] KVM: selftests: Fix GUEST_PRINTF() format warnings in ARM
 code
In-Reply-To: <20240202234603.366925-1-seanjc@google.com>
References: <20240202234603.366925-1-seanjc@google.com>
Message-ID: <3188e6f1-f150-f7d0-6c2b-5b7608b0b012@huawei.com>

On 2024/2/3 7:46, Sean Christopherson wrote:
> Fix a pile of -Wformat warnings in the KVM ARM selftests code, almost all
> of which are benign "long" versus "long long" issues (selftests are 64-bit
> only, and the guest printf code treats "ll" the same as "l").  The code
> itself isn't problematic, but the warnings make it impossible to build ARM
> selftests with -Werror, which does detect real issues from time to time.
> 
> Opportunistically have GUEST_ASSERT_BITMAP_REG() interpret set_expected,
> which is a bool, as an unsigned decimal value, i.e. have it print '0' or
> '1' instead of '0x0' or '0x1'.
> 
> Signed-off-by: Sean Christopherson <seanjc at google.com>

Tested-by: Zenghui Yu <yuzenghui at huawei.com>

> diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> index 274b8465b42a..d5e8f365aa01 100644
> --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
> +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> @@ -158,9 +158,9 @@ static void guest_validate_irq(unsigned int intid,
>   
>   	/* Basic 'timer condition met' check */
>   	__GUEST_ASSERT(xcnt >= cval,
> -		       "xcnt = 0x%llx, cval = 0x%llx, xcnt_diff_us = 0x%llx",
> +		       "xcnt = 0x%lx, cval = 0x%lx, xcnt_diff_us = 0x%lx",
>   		       xcnt, cval, xcnt_diff_us);
> -	__GUEST_ASSERT(xctl & CTL_ISTATUS, "xcnt = 0x%llx", xcnt);
> +	__GUEST_ASSERT(xctl & CTL_ISTATUS, "xcnt = 0x%lx", xcnt);

Unrelated to your patch, but it looks to me that we actually want to
print 'xctl' instead of 'xcnt' in the second __GUEST_ASSERT().

Thanks,
Zenghui


From devnull+arinc.unal.arinc9.com at kernel.org  Wed Feb  7 21:51:33 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Thu, 08 Feb 2024 08:51:33 +0300
Subject: [PATCH netnext 5/8] net: dsa: mt7530: get rid of
 priv->info->cpu_port_config()
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
Message-ID: <20240208-for-netnext-mt7530-improvements-3-v1-5-d7c1cfd502ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

priv->info->cpu_port_config() is used for MT7531 and the switch on the
MT7988 SoC. It sets up the ports described as a CPU port earlier than the
phylink code path would do.

This function is useless as:
- Configuring the MACs can be done from the phylink_mac_config code path
  instead.
- All the link configuration it does on the CPU ports are later undone with
  the port_enable, phylink_mac_config, and then phylink_mac_link_up code
  path [1].

priv->p5_interface and priv->p6_interface were being used to prevent
configuring the MACs from the phylink_mac_config code path. Remove them now
that they hold no purpose.

Remove priv->info->cpu_port_config(). On mt753x_phylink_mac_config, switch
to if statements to simplify the code.

Remove the overwriting of the speed and duplex interfaces for certain
interface modes. Phylink already provides the speed and duplex variables
with proper values. Phylink already sets the max speed of TRGMII to
SPEED_1000. Add SPEED_2500 for PHY_INTERFACE_MODE_2500BASEX to where the
speed and EEE bits are set instead.

On the switch on the MT7988 SoC, PHY_INTERFACE_MODE_INTERNAL is being used
to describe the interface mode of the 10G MAC, which is of port 6. On
mt7988_cpu_port_config() PMCR_FORCE_SPEED_1000 was set via the
PMCR_CPU_PORT_SETTING() mask. Add SPEED_10000 case to where the speed bits
are set to cover this. No need to add it to where the EEE bits are set as
the "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version)
v0.1" document shows that these bits don't exist on the MT7530_PMCR_P(6)
register.

Remove the definition of PMCR_CPU_PORT_SETTING() now that it holds no
purpose.

Change mt753x_cpu_port_enable() to void now that there're no error cases
left.

Link: https://lore.kernel.org/netdev/ZHy2jQLesdYFMQtO at shell.armlinux.org.uk/ [1]
Suggested-by: Russell King (Oracle) <linux at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 114 +++--------------------------------------------
 drivers/net/dsa/mt7530.h |  11 -----
 2 files changed, 7 insertions(+), 118 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index c069bf273733..80b65f064310 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -966,18 +966,10 @@ mt753x_trap_frames(struct mt7530_priv *priv)
 		   MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY));
 }
 
-static int
+static void
 mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
 {
 	struct mt7530_priv *priv = ds->priv;
-	int ret;
-
-	/* Setup max capability of CPU port at first */
-	if (priv->info->cpu_port_config) {
-		ret = priv->info->cpu_port_config(ds, port);
-		if (ret)
-			return ret;
-	}
 
 	/* Enable Mediatek header mode on the cpu port */
 	mt7530_write(priv, MT7530_PVC_P(port),
@@ -1003,8 +995,6 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
 	/* Set to fallback mode for independent VLAN learning */
 	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
 		   MT7530_PORT_FALLBACK_MODE);
-
-	return 0;
 }
 
 static int
@@ -2261,8 +2251,6 @@ mt7530_setup(struct dsa_switch *ds)
 	val |= MHWTRAP_MANUAL;
 	mt7530_write(priv, MT7530_MHWTRAP, val);
 
-	priv->p6_interface = PHY_INTERFACE_MODE_NA;
-
 	mt753x_trap_frames(priv);
 
 	/* Enable and reset MIB counters */
@@ -2277,9 +2265,7 @@ mt7530_setup(struct dsa_switch *ds)
 		mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
 
 		if (dsa_is_cpu_port(ds, i)) {
-			ret = mt753x_cpu_port_enable(ds, i);
-			if (ret)
-				return ret;
+			mt753x_cpu_port_enable(ds, i);
 		} else {
 			mt7530_port_disable(ds, i);
 
@@ -2383,9 +2369,7 @@ mt7531_setup_common(struct dsa_switch *ds)
 		mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
 
 		if (dsa_is_cpu_port(ds, i)) {
-			ret = mt753x_cpu_port_enable(ds, i);
-			if (ret)
-				return ret;
+			mt753x_cpu_port_enable(ds, i);
 		} else {
 			mt7530_port_disable(ds, i);
 
@@ -2474,10 +2458,6 @@ mt7531_setup(struct dsa_switch *ds)
 	mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
 		   MT7531_GPIO0_INTERRUPT);
 
-	/* Let phylink decide the interface later. */
-	priv->p5_interface = PHY_INTERFACE_MODE_NA;
-	priv->p6_interface = PHY_INTERFACE_MODE_NA;
-
 	/* Enable PHY core PLL, since phy_device has not yet been created
 	 * provided for phy_[read,write]_mmd_indirect is called, we provide
 	 * our own mt7531_ind_mmd_phy_[read,write] to complete this
@@ -2689,26 +2669,9 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 	struct mt7530_priv *priv = ds->priv;
 	u32 mcr_cur, mcr_new;
 
-	switch (port) {
-	case 5:
-		if (priv->p5_interface == state->interface)
-			break;
-
+	if (port == 5 || port == 6)
 		mt753x_mac_config(ds, port, mode, state);
 
-		if (priv->p5_intf_sel != P5_DISABLED)
-			priv->p5_interface = state->interface;
-		break;
-	case 6:
-		if (priv->p6_interface == state->interface)
-			break;
-
-		mt753x_mac_config(ds, port, mode, state);
-
-		priv->p6_interface = state->interface;
-		break;
-	}
-
 	mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
 	mcr_new = mcr_cur;
 	mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
@@ -2744,17 +2707,10 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
 
 	mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
 
-	/* MT753x MAC works in 1G full duplex mode for all up-clocked
-	 * variants.
-	 */
-	if (interface == PHY_INTERFACE_MODE_TRGMII ||
-	    (phy_interface_mode_is_8023z(interface))) {
-		speed = SPEED_1000;
-		duplex = DUPLEX_FULL;
-	}
-
 	switch (speed) {
 	case SPEED_1000:
+	case SPEED_2500:
+	case SPEED_10000:
 		mcr |= PMCR_FORCE_SPEED_1000;
 		break;
 	case SPEED_100:
@@ -2772,6 +2728,7 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
 	if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) {
 		switch (speed) {
 		case SPEED_1000:
+		case SPEED_2500:
 			mcr |= PMCR_FORCE_EEE1G;
 			break;
 		case SPEED_100:
@@ -2783,61 +2740,6 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
 	mt7530_set(priv, MT7530_PMCR_P(port), mcr);
 }
 
-static int
-mt7531_cpu_port_config(struct dsa_switch *ds, int port)
-{
-	struct mt7530_priv *priv = ds->priv;
-	phy_interface_t interface;
-	int speed;
-
-	switch (port) {
-	case 5:
-		if (!priv->p5_sgmii)
-			interface = PHY_INTERFACE_MODE_RGMII;
-		else
-			interface = PHY_INTERFACE_MODE_2500BASEX;
-
-		priv->p5_interface = interface;
-		break;
-	case 6:
-		interface = PHY_INTERFACE_MODE_2500BASEX;
-
-		priv->p6_interface = interface;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (interface == PHY_INTERFACE_MODE_2500BASEX)
-		speed = SPEED_2500;
-	else
-		speed = SPEED_1000;
-
-	mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
-
-	mt7530_write(priv, MT7530_PMCR_P(port),
-		     PMCR_CPU_PORT_SETTING(priv->id));
-	mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
-				   speed, DUPLEX_FULL, true, true);
-
-	return 0;
-}
-
-static int
-mt7988_cpu_port_config(struct dsa_switch *ds, int port)
-{
-	struct mt7530_priv *priv = ds->priv;
-
-	mt7530_write(priv, MT7530_PMCR_P(port),
-		     PMCR_CPU_PORT_SETTING(priv->id));
-
-	mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED,
-				   PHY_INTERFACE_MODE_INTERNAL, NULL,
-				   SPEED_10000, DUPLEX_FULL, true, true);
-
-	return 0;
-}
-
 static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
 				    struct phylink_config *config)
 {
@@ -3096,7 +2998,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7531_ind_c22_phy_write,
 		.phy_read_c45 = mt7531_ind_c45_phy_read,
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
-		.cpu_port_config = mt7531_cpu_port_config,
 		.mac_port_get_caps = mt7531_mac_port_get_caps,
 		.mac_port_config = mt7531_mac_config,
 	},
@@ -3108,7 +3009,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7531_ind_c22_phy_write,
 		.phy_read_c45 = mt7531_ind_c45_phy_read,
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
-		.cpu_port_config = mt7988_cpu_port_config,
 		.mac_port_get_caps = mt7988_mac_port_get_caps,
 	},
 };
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index b1665de7f640..8a8144868eaa 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -311,13 +311,6 @@ enum mt7530_vlan_port_acc_frm {
 					 PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
 					 PMCR_FORCE_FDX | PMCR_FORCE_LNK | \
 					 PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100)
-#define  PMCR_CPU_PORT_SETTING(id)	(PMCR_FORCE_MODE_ID((id)) | \
-					 PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
-					 PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \
-					 PMCR_TX_EN | PMCR_RX_EN | \
-					 PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
-					 PMCR_FORCE_SPEED_1000 | \
-					 PMCR_FORCE_FDX | PMCR_FORCE_LNK)
 
 #define MT7530_PMEEECR_P(x)		(0x3004 + (x) * 0x100)
 #define  WAKEUP_TIME_1000(x)		(((x) & 0xFF) << 24)
@@ -724,7 +717,6 @@ struct mt753x_info {
 			    int regnum);
 	int (*phy_write_c45)(struct mt7530_priv *priv, int port, int devad,
 			     int regnum, u16 val);
-	int (*cpu_port_config)(struct dsa_switch *ds, int port);
 	void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
 				  struct phylink_config *config);
 	void (*mac_port_validate)(struct dsa_switch *ds, int port,
@@ -750,7 +742,6 @@ struct mt753x_info {
  * @ports:		Holding the state among ports
  * @reg_mutex:		The lock for protecting among process accessing
  *			registers
- * @p6_interface	Holding the current port 6 interface
  * @p5_intf_sel:	Holding the current port 5 interface select
  * @p5_sgmii:		Flag for distinguishing if port 5 of the MT7531 switch
  *			has got SGMII
@@ -772,8 +763,6 @@ struct mt7530_priv {
 	const struct mt753x_info *info;
 	unsigned int		id;
 	bool			mcm;
-	phy_interface_t		p6_interface;
-	phy_interface_t		p5_interface;
 	enum p5_interface_select p5_intf_sel;
 	bool			p5_sgmii;
 	u8			mirror_rx;

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Wed Feb  7 21:51:32 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Thu, 08 Feb 2024 08:51:32 +0300
Subject: [PATCH netnext 4/8] net: dsa: mt7530: get rid of useless error
 returns on phylink code path
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
Message-ID: <20240208-for-netnext-mt7530-improvements-3-v1-4-d7c1cfd502ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

Remove error returns on the cases where they are already handled with the
function the mac_port_get_caps member in mt753x_table points to.

mt7531_mac_config() is also called from mt7531_cpu_port_config() outside of
phylink but the port and interface modes are already handled there.

Change the functions and the mac_port_config function pointer to void now
that there're no error returns anymore.

Remove mt753x_is_mac_port() that used to help the said error returns.

On mt7531_mac_config(), switch to if statements to simplify the code.

Remove internal phy cases from mt753x_phylink_mac_config(), there is no
need to check the interface mode as that's already handled with the
function the mac_port_get_caps member in mt753x_table points to.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Acked-by: Daniel Golle <daniel at makrotopia.org>
Tested-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 81 ++++++++++--------------------------------------
 drivers/net/dsa/mt7530.h |  6 ++--
 2 files changed, 19 insertions(+), 68 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 296711fd5c43..c069bf273733 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2587,7 +2587,7 @@ static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 	}
 }
 
-static int
+static void
 mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
 {
@@ -2597,22 +2597,14 @@ mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		mt7530_setup_port5(priv->ds, interface);
 	else if (port == 6)
 		mt7530_setup_port6(priv->ds, interface);
-
-	return 0;
 }
 
-static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
-			      phy_interface_t interface,
-			      struct phy_device *phydev)
+static void mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
+			       phy_interface_t interface,
+			       struct phy_device *phydev)
 {
 	u32 val;
 
-	if (priv->p5_sgmii) {
-		dev_err(priv->dev, "RGMII mode is not available for port %d\n",
-			port);
-		return -EINVAL;
-	}
-
 	val = mt7530_read(priv, MT7531_CLKGEN_CTRL);
 	val |= GP_CLK_EN;
 	val &= ~GP_MODE_MASK;
@@ -2640,20 +2632,14 @@ static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
 		case PHY_INTERFACE_MODE_RGMII_ID:
 			break;
 		default:
-			return -EINVAL;
+			break;
 		}
 	}
-	mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
-
-	return 0;
-}
 
-static bool mt753x_is_mac_port(u32 port)
-{
-	return (port == 5 || port == 6);
+	mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
 }
 
-static int
+static void
 mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
 {
@@ -2661,42 +2647,21 @@ mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 	struct phy_device *phydev;
 	struct dsa_port *dp;
 
-	if (!mt753x_is_mac_port(port)) {
-		dev_err(priv->dev, "port %d is not a MAC port\n", port);
-		return -EINVAL;
-	}
-
-	switch (interface) {
-	case PHY_INTERFACE_MODE_RGMII:
-	case PHY_INTERFACE_MODE_RGMII_ID:
-	case PHY_INTERFACE_MODE_RGMII_RXID:
-	case PHY_INTERFACE_MODE_RGMII_TXID:
+	if (phy_interface_mode_is_rgmii(interface)) {
 		dp = dsa_to_port(ds, port);
 		phydev = dp->user->phydev;
-		return mt7531_rgmii_setup(priv, port, interface, phydev);
-	case PHY_INTERFACE_MODE_SGMII:
-	case PHY_INTERFACE_MODE_NA:
-	case PHY_INTERFACE_MODE_1000BASEX:
-	case PHY_INTERFACE_MODE_2500BASEX:
-		/* handled in SGMII PCS driver */
-		return 0;
-	default:
-		return -EINVAL;
+		mt7531_rgmii_setup(priv, port, interface, phydev);
 	}
-
-	return -EINVAL;
 }
 
-static int
+static void
 mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  const struct phylink_link_state *state)
 {
 	struct mt7530_priv *priv = ds->priv;
 
-	if (!priv->info->mac_port_config)
-		return 0;
-
-	return priv->info->mac_port_config(ds, port, mode, state->interface);
+	if (priv->info->mac_port_config)
+		priv->info->mac_port_config(ds, port, mode, state->interface);
 }
 
 static struct phylink_pcs *
@@ -2725,17 +2690,11 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 	u32 mcr_cur, mcr_new;
 
 	switch (port) {
-	case 0 ... 4:
-		if (state->interface != PHY_INTERFACE_MODE_GMII &&
-		    state->interface != PHY_INTERFACE_MODE_INTERNAL)
-			goto unsupported;
-		break;
 	case 5:
 		if (priv->p5_interface == state->interface)
 			break;
 
-		if (mt753x_mac_config(ds, port, mode, state) < 0)
-			goto unsupported;
+		mt753x_mac_config(ds, port, mode, state);
 
 		if (priv->p5_intf_sel != P5_DISABLED)
 			priv->p5_interface = state->interface;
@@ -2744,16 +2703,10 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		if (priv->p6_interface == state->interface)
 			break;
 
-		if (mt753x_mac_config(ds, port, mode, state) < 0)
-			goto unsupported;
+		mt753x_mac_config(ds, port, mode, state);
 
 		priv->p6_interface = state->interface;
 		break;
-	default:
-unsupported:
-		dev_err(ds->dev, "%s: unsupported %s port: %i\n",
-			__func__, phy_modes(state->interface), port);
-		return;
 	}
 
 	mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
@@ -2836,7 +2789,6 @@ mt7531_cpu_port_config(struct dsa_switch *ds, int port)
 	struct mt7530_priv *priv = ds->priv;
 	phy_interface_t interface;
 	int speed;
-	int ret;
 
 	switch (port) {
 	case 5:
@@ -2861,9 +2813,8 @@ mt7531_cpu_port_config(struct dsa_switch *ds, int port)
 	else
 		speed = SPEED_1000;
 
-	ret = mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
-	if (ret)
-		return ret;
+	mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
+
 	mt7530_write(priv, MT7530_PMCR_P(port),
 		     PMCR_CPU_PORT_SETTING(priv->id));
 	mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 26a6d2160c08..b1665de7f640 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -730,9 +730,9 @@ struct mt753x_info {
 	void (*mac_port_validate)(struct dsa_switch *ds, int port,
 				  phy_interface_t interface,
 				  unsigned long *supported);
-	int (*mac_port_config)(struct dsa_switch *ds, int port,
-			       unsigned int mode,
-			       phy_interface_t interface);
+	void (*mac_port_config)(struct dsa_switch *ds, int port,
+				unsigned int mode,
+				phy_interface_t interface);
 };
 
 /* struct mt7530_priv -	This is the main data structure for holding the state

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Wed Feb  7 21:51:30 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Thu, 08 Feb 2024 08:51:30 +0300
Subject: [PATCH netnext 2/8] net: dsa: mt7530: set interrupt register only
 for MT7530
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
Message-ID: <20240208-for-netnext-mt7530-improvements-3-v1-2-d7c1cfd502ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

Setting this register related to interrupts is only needed for the MT7530
switch. Make an exclusive check to ensure this.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Acked-by: Daniel Golle <daniel at makrotopia.org>
Tested-by: Daniel Golle <daniel at makrotopia.org>
---
 drivers/net/dsa/mt7530.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 94d4b2c87799..5cfd303b773f 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2055,7 +2055,7 @@ mt7530_setup_irq(struct mt7530_priv *priv)
 	}
 
 	/* This register must be set for MT7530 to properly fire interrupts */
-	if (priv->id != ID_MT7531)
+	if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
 		mt7530_set(priv, MT7530_TOP_SIG_CTRL, TOP_SIG_CTRL_NORMAL);
 
 	ret = request_threaded_irq(priv->irq, NULL, mt7530_irq_thread_fn,

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Wed Feb  7 21:51:29 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Thu, 08 Feb 2024 08:51:29 +0300
Subject: [PATCH netnext 1/8] net: dsa: mt7530: remove .mac_port_config for
 MT7988 and make it optional
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
Message-ID: <20240208-for-netnext-mt7530-improvements-3-v1-1-d7c1cfd502ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

For the switch on the MT7988 SoC, the mac_port_config member for ID_MT7988
in mt753x_table is not needed as the interfaces of all MACs are already
handled on mt7988_mac_port_get_caps().

Therefore, remove the mac_port_config member from ID_MT7988 in
mt753x_table. Before calling priv->info->mac_port_config(), if there's no
mac_port_config member in mt753x_table, exit mt753x_mac_config()
successfully.

Remove calling priv->info->mac_port_config() from the sanity check as the
sanity check requires a pointer to a mac_port_config function to be
non-NULL. This will fail for MT7988 as mac_port_config won't be a member of
its info table.

Co-developed-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
---
 drivers/net/dsa/mt7530.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 03d966fa67b2..94d4b2c87799 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2655,17 +2655,6 @@ static bool mt753x_is_mac_port(u32 port)
 	return (port == 5 || port == 6);
 }
 
-static int
-mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-		  phy_interface_t interface)
-{
-	if (dsa_is_cpu_port(ds, port) &&
-	    interface == PHY_INTERFACE_MODE_INTERNAL)
-		return 0;
-
-	return -EINVAL;
-}
-
 static int
 mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
@@ -2706,6 +2695,9 @@ mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 {
 	struct mt7530_priv *priv = ds->priv;
 
+	if (!priv->info->mac_port_config)
+		return 0;
+
 	return priv->info->mac_port_config(ds, port, mode, state->interface);
 }
 
@@ -3169,7 +3161,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
 		.cpu_port_config = mt7988_cpu_port_config,
 		.mac_port_get_caps = mt7988_mac_port_get_caps,
-		.mac_port_config = mt7988_mac_config,
 	},
 };
 EXPORT_SYMBOL_GPL(mt753x_table);
@@ -3197,8 +3188,7 @@ mt7530_probe_common(struct mt7530_priv *priv)
 	 * properly.
 	 */
 	if (!priv->info->sw_setup || !priv->info->phy_read_c22 ||
-	    !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps ||
-	    !priv->info->mac_port_config)
+	    !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps)
 		return -EINVAL;
 
 	priv->id = priv->info->id;

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Wed Feb  7 21:51:31 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Thu, 08 Feb 2024 08:51:31 +0300
Subject: [PATCH netnext 3/8] net: dsa: mt7530: do not use SW_PHY_RST to
 reset MT7531 switch
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
Message-ID: <20240208-for-netnext-mt7530-improvements-3-v1-3-d7c1cfd502ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

According to the document MT7531 Reference Manual for Development Board
v1.0, the SW_PHY_RST bit on the SYS_CTRL register doesn't exist for
MT7531. This is likely why forcing link down on all ports is necessary for
MT7531.

Therefore, do not set SW_PHY_RST on mt7531_setup().

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 5cfd303b773f..296711fd5c43 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2451,14 +2451,12 @@ mt7531_setup(struct dsa_switch *ds)
 	val = mt7530_read(priv, MT7531_TOP_SIG_SR);
 	priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
 
-	/* all MACs must be forced link-down before sw reset */
+	/* Force link down on all ports before internal reset */
 	for (i = 0; i < MT7530_NUM_PORTS; i++)
 		mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
 
 	/* Reset the switch through internal reset */
-	mt7530_write(priv, MT7530_SYS_CTRL,
-		     SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
-		     SYS_CTRL_REG_RST);
+	mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
 
 	if (!priv->p5_sgmii) {
 		mt7531_pll_setup(priv);

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Wed Feb  7 21:51:28 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Thu, 08 Feb 2024 08:51:28 +0300
Subject: [PATCH netnext 0/8] MT7530 DSA Subdriver Improvements Act III
Message-ID: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>

Hello!

This is the third patch series with the goal of simplifying the MT7530 DSA
subdriver and improving support for MT7530, MT7531, and the switch on the
MT7988 SoC.

I have done a simple ping test to confirm basic communication on all switch
ports on MCM and standalone MT7530, and MT7531 switch with this patch
series applied.

MT7621 Unielec, MCM MT7530:

rgmii-only-gmac0-mt7621-unielec-u7621-06-16m.dtb
gmac0-and-gmac1-mt7621-unielec-u7621-06-16m.dtb

tftpboot 0x80008000 mips-uzImage.bin; tftpboot 0x83000000 mips-rootfs.cpio.uboot; tftpboot 0x83f00000 $dtb; bootm 0x80008000 0x83000000 0x83f00000

MT7622 Bananapi, MT7531:

gmac0-and-gmac1-mt7622-bananapi-bpi-r64.dtb

tftpboot 0x40000000 arm64-Image; tftpboot 0x45000000 arm64-rootfs.cpio.uboot; tftpboot 0x4a000000 $dtb; booti 0x40000000 0x45000000 0x4a000000

MT7623 Bananapi, standalone MT7530:

rgmii-only-gmac0-mt7623n-bananapi-bpi-r2.dtb
gmac0-and-gmac1-mt7623n-bananapi-bpi-r2.dtb

tftpboot 0x80008000 arm-zImage; tftpboot 0x83000000 arm-rootfs.cpio.uboot; tftpboot 0x83f00000 $dtb; bootz 0x80008000 0x83000000 0x83f00000

This patch series is the continuation of the patch series linked below.

https://lore.kernel.org/r/20230522121532.86610-1-arinc.unal at arinc9.com

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
Ar?n? ?NAL (8):
      net: dsa: mt7530: remove .mac_port_config for MT7988 and make it optional
      net: dsa: mt7530: set interrupt register only for MT7530
      net: dsa: mt7530: do not use SW_PHY_RST to reset MT7531 switch
      net: dsa: mt7530: get rid of useless error returns on phylink code path
      net: dsa: mt7530: get rid of priv->info->cpu_port_config()
      net: dsa: mt7530: get rid of mt753x_mac_config()
      net: dsa: mt7530: put initialising PCS devices code back to original order
      net: dsa: mt7530: simplify link operations and force link down on all ports

 drivers/net/dsa/mt7530.c | 259 ++++++++---------------------------------------
 drivers/net/dsa/mt7530.h |  19 +---
 2 files changed, 47 insertions(+), 231 deletions(-)
---
base-commit: b6b614558ed5b2ca50edacc0f2fbf5f52158c86c
change-id: 20240131-for-netnext-mt7530-improvements-3-a8ac49d4f7c2

Best regards,
-- 
Ar?n? ?NAL <arinc.unal at arinc9.com>



From devnull+arinc.unal.arinc9.com at kernel.org  Wed Feb  7 21:51:34 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Thu, 08 Feb 2024 08:51:34 +0300
Subject: [PATCH netnext 6/8] net: dsa: mt7530: get rid of
 mt753x_mac_config()
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
Message-ID: <20240208-for-netnext-mt7530-improvements-3-v1-6-d7c1cfd502ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

There is no need for a separate function to call
priv->info->mac_port_config(). Call it from mt753x_phylink_mac_config()
instead and remove mt753x_mac_config().

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 80b65f064310..e353c03dd1db 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2634,16 +2634,6 @@ mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 	}
 }
 
-static void
-mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-		  const struct phylink_link_state *state)
-{
-	struct mt7530_priv *priv = ds->priv;
-
-	if (priv->info->mac_port_config)
-		priv->info->mac_port_config(ds, port, mode, state->interface);
-}
-
 static struct phylink_pcs *
 mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
 			      phy_interface_t interface)
@@ -2669,8 +2659,8 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 	struct mt7530_priv *priv = ds->priv;
 	u32 mcr_cur, mcr_new;
 
-	if (port == 5 || port == 6)
-		mt753x_mac_config(ds, port, mode, state);
+	if ((port == 5 || port == 6) && priv->info->mac_port_config)
+		priv->info->mac_port_config(ds, port, mode, state->interface);
 
 	mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
 	mcr_new = mcr_cur;

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Wed Feb  7 21:51:35 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Thu, 08 Feb 2024 08:51:35 +0300
Subject: [PATCH netnext 7/8] net: dsa: mt7530: put initialising PCS devices
 code back to original order
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
Message-ID: <20240208-for-netnext-mt7530-improvements-3-v1-7-d7c1cfd502ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

The commit fae463084032 ("net: dsa: mt753x: fix pcs conversion regression")
fixes regression caused by cpu_port_config manually calling phylink
operations. cpu_port_config was deemed useless and was removed. Therefore,
put initialising PCS devices code back to its original order.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index e353c03dd1db..5c8ad41ce8cd 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2812,17 +2812,9 @@ static int
 mt753x_setup(struct dsa_switch *ds)
 {
 	struct mt7530_priv *priv = ds->priv;
-	int i, ret;
-
-	/* Initialise the PCS devices */
-	for (i = 0; i < priv->ds->num_ports; i++) {
-		priv->pcs[i].pcs.ops = priv->info->pcs_ops;
-		priv->pcs[i].pcs.neg_mode = true;
-		priv->pcs[i].priv = priv;
-		priv->pcs[i].port = i;
-	}
+	int ret = priv->info->sw_setup(ds);
+	int i;
 
-	ret = priv->info->sw_setup(ds);
 	if (ret)
 		return ret;
 
@@ -2834,6 +2826,14 @@ mt753x_setup(struct dsa_switch *ds)
 	if (ret && priv->irq)
 		mt7530_free_irq_common(priv);
 
+	/* Initialise the PCS devices */
+	for (i = 0; i < priv->ds->num_ports; i++) {
+		priv->pcs[i].pcs.ops = priv->info->pcs_ops;
+		priv->pcs[i].pcs.neg_mode = true;
+		priv->pcs[i].priv = priv;
+		priv->pcs[i].port = i;
+	}
+
 	if (priv->create_sgmii) {
 		ret = priv->create_sgmii(priv);
 		if (ret && priv->irq)

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Wed Feb  7 21:51:36 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Thu, 08 Feb 2024 08:51:36 +0300
Subject: [PATCH netnext 8/8] net: dsa: mt7530: simplify link operations and
 force link down on all ports
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
Message-ID: <20240208-for-netnext-mt7530-improvements-3-v1-8-d7c1cfd502ca@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

Currently, the link operations for switch MACs are scattered across
port_enable, port_disable, phylink_mac_config, phylink_mac_link_up, and
phylink_mac_link_down.

port_enable and port_disable clears the link settings. Move that to
mt7530_setup() and mt7531_setup_common() which set up the switches. This
way, the link settings are cleared on all ports at setup, and then only
once with phylink_mac_link_down() when a link goes down.

Enable force mode at setup to apply the force part of the link settings.
This ensures that only active ports will have their link up.

Now that the bit for setting the port on force mode is done on
mt7530_setup() and mt7531_setup_common(), get rid of PMCR_FORCE_MODE_ID()
which helped determine which bit to use for the switch model.

The "MT7621 Giga Switch Programming Guide v0.3", "MT7531 Reference Manual
for Development Board v1.0", and "MT7988A Wi-Fi 7 Generation Router
Platform: Datasheet (Open Version) v0.1" documents show that these bits are
enabled at reset:

PMCR_IFG_XMIT(1) (not part of PMCR_LINK_SETTINGS_MASK)
PMCR_MAC_MODE (not part of PMCR_LINK_SETTINGS_MASK)
PMCR_TX_EN
PMCR_RX_EN
PMCR_BACKOFF_EN (not part of PMCR_LINK_SETTINGS_MASK)
PMCR_BACKPR_EN (not part of PMCR_LINK_SETTINGS_MASK)
PMCR_TX_FC_EN
PMCR_RX_FC_EN

These bits also don't exist on the MT7530_PMCR_P(6) register of the switch
on the MT7988 SoC:

PMCR_IFG_XMIT()
PMCR_MAC_MODE
PMCR_BACKOFF_EN
PMCR_BACKPR_EN

Remove the setting of the bits not part of PMCR_LINK_SETTINGS_MASK on
phylink_mac_config as they're already set.

Suggested-by: Vladimir Oltean <olteanv at gmail.com>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 26 +++++++++++++-------------
 drivers/net/dsa/mt7530.h |  2 --
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 5c8ad41ce8cd..f67db577d1c0 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1018,7 +1018,6 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
 	priv->ports[port].enable = true;
 	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
 		   priv->ports[port].pm);
-	mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
 
 	mutex_unlock(&priv->reg_mutex);
 
@@ -1038,7 +1037,6 @@ mt7530_port_disable(struct dsa_switch *ds, int port)
 	priv->ports[port].enable = false;
 	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
 		   PCR_MATRIX_CLR);
-	mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
 
 	mutex_unlock(&priv->reg_mutex);
 }
@@ -2257,6 +2255,12 @@ mt7530_setup(struct dsa_switch *ds)
 	mt7530_mib_reset(ds);
 
 	for (i = 0; i < MT7530_NUM_PORTS; i++) {
+		/* Clear link settings and enable force mode to force link down
+		 * on all ports until they're enabled later.
+		 */
+		mt7530_clear(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK);
+		mt7530_set(priv, MT7530_PMCR_P(i), PMCR_FORCE_MODE);
+
 		/* Disable forwarding by default on all ports */
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
@@ -2359,6 +2363,12 @@ mt7531_setup_common(struct dsa_switch *ds)
 		     UNU_FFP_MASK);
 
 	for (i = 0; i < MT7530_NUM_PORTS; i++) {
+		/* Clear link settings and enable force mode to force link down
+		 * on all ports until they're enabled later.
+		 */
+		mt7530_clear(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK);
+		mt7530_set(priv, MT7530_PMCR_P(i), MT7531_FORCE_MODE);
+
 		/* Disable forwarding by default on all ports */
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
@@ -2657,23 +2667,13 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 			  const struct phylink_link_state *state)
 {
 	struct mt7530_priv *priv = ds->priv;
-	u32 mcr_cur, mcr_new;
 
 	if ((port == 5 || port == 6) && priv->info->mac_port_config)
 		priv->info->mac_port_config(ds, port, mode, state->interface);
 
-	mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
-	mcr_new = mcr_cur;
-	mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
-	mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
-		   PMCR_BACKPR_EN | PMCR_FORCE_MODE_ID(priv->id);
-
 	/* Are we connected to external phy */
 	if (port == 5 && dsa_is_user_port(ds, 5))
-		mcr_new |= PMCR_EXT_PHY;
-
-	if (mcr_new != mcr_cur)
-		mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
+		mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
 }
 
 static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 8a8144868eaa..a71166e0a7fc 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -304,8 +304,6 @@ enum mt7530_vlan_port_acc_frm {
 					 MT7531_FORCE_DPX | \
 					 MT7531_FORCE_RX_FC | \
 					 MT7531_FORCE_TX_FC)
-#define  PMCR_FORCE_MODE_ID(id)		((((id) == ID_MT7531) || ((id) == ID_MT7988)) ?	\
-					 MT7531_FORCE_MODE : PMCR_FORCE_MODE)
 #define  PMCR_LINK_SETTINGS_MASK	(PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
 					 PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
 					 PMCR_TX_FC_EN | PMCR_RX_FC_EN | \

-- 
2.40.1



From w.egorov at phytec.de  Wed Feb  7 21:57:54 2024
From: w.egorov at phytec.de (Wadim Egorov)
Date: Thu, 8 Feb 2024 06:57:54 +0100
Subject: [PATCH] arm64: dts: ti: am62-phyboard-lyra: Add overlay to enable
 a GPIO fan
In-Reply-To: <acd3c7f2-930d-46c0-9924-9775e9795fca@ti.com>
References: <20240207172820.478332-1-nmorrisson@phytec.com>
 <acd3c7f2-930d-46c0-9924-9775e9795fca@ti.com>
Message-ID: <033de6e2-4ca4-46bc-a0a7-e9921ed15977@phytec.de>

Hi Andrew,

Am 07.02.24 um 23:20 schrieb Andrew Davis:
> On 2/7/24 11:28 AM, Nathan Morrisson wrote:
>> The phyBOARD-Lyra has a GPIO fan header. This overlay enables the fan
>> header and sets the fan to turn on at 65C.
>>
>> Signed-off-by: Nathan Morrisson <nmorrisson at phytec.com>
>> ---
>> ? arch/arm64/boot/dts/ti/Makefile?????????????? |? 1 +
>> ? .../ti/k3-am62-phyboard-lyra-gpio-fan.dtso??? | 51 +++++++++++++++++++
>> ? 2 files changed, 52 insertions(+)
>> ? create mode 100644 
>> arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
>>
>> diff --git a/arch/arm64/boot/dts/ti/Makefile 
>> b/arch/arm64/boot/dts/ti/Makefile
>> index 52c1dc910308..379fb4f31a1f 100644
>> --- a/arch/arm64/boot/dts/ti/Makefile
>> +++ b/arch/arm64/boot/dts/ti/Makefile
>> @@ -23,6 +23,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-mallow.dtb
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
>> +dtb-$(CONFIG_ARCH_K3) += k3-am62-phyboard-lyra-gpio-fan.dtbo
>
> Why not call this k3-am625-phyboard-lyra-gpio-fan.dtbo to match the
> name of the base board it applies to better?

We are able to reuse this overlay for different SoMs (am625 and am62a) 
that are using the same carrier board (lyra).

Regards,
Wadim


>
> Andrew
>
>> ? ? # Boards with AM62Ax SoC
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
>> diff --git 
>> a/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso 
>> b/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
>> new file mode 100644
>> index 000000000000..9c05748bdd9d
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
>> @@ -0,0 +1,51 @@
>> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
>> +/*
>> + * Copyright (C) 2024 PHYTEC America LLC
>> + * Author: Garrett Giordano <ggiordano at phytec.com>
>> + */
>> +
>> +/dts-v1/;
>> +/plugin/;
>> +
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include <dt-bindings/thermal/thermal.h>
>> +#include "k3-pinctrl.h"
>> +
>> +&{/} {
>> +??? fan: gpio-fan {
>> +??????? compatible = "gpio-fan";
>> +??????? gpio-fan,speed-map = <0 0 8600 1>;
>> +??????? gpios = <&main_gpio0 40 GPIO_ACTIVE_LOW>;
>> +??????? #cooling-cells = <2>;
>> +??????? pinctrl-names = "default";
>> +??????? pinctrl-0 = <&gpio_fan_pins_default>;
>> +??????? status = "okay";
>> +??? };
>> +};
>> +
>> +&main_pmx0 {
>> +??? gpio_fan_pins_default: gpio-fan-default-pins {
>> +??????? pinctrl-single,pins = <
>> +??????????? AM62X_IOPAD(0x0a4, PIN_OUTPUT, 7) /* (M22) 
>> GPMC0_DIR.GPIO0_40 */
>> +??????? >;
>> +??? };
>> +};
>> +
>> +&thermal_zones {
>> +??? main0_thermal: main0-thermal {
>> +??????? trips {
>> +??????????? main0_thermal_trip0: main0-thermal-trip {
>> +??????????????? temperature = <65000>;? /* millicelsius */
>> +??????????????? hysteresis = <2000>;??? /* millicelsius */
>> +??????????????? type = "active";
>> +??????????? };
>> +??????? };
>> +
>> +??????? cooling-maps {
>> +??????????? map0 {
>> +??????????????? trip = <&main0_thermal_trip0>;
>> +??????????????? cooling-device = <&fan THERMAL_NO_LIMIT 
>> THERMAL_NO_LIMIT>;
>> +??????????? };
>> +??????? };
>> +??? };
>> +};
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From j-luthra at ti.com  Wed Feb  7 22:02:30 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 8 Feb 2024 11:32:30 +0530
Subject: [PATCH] arm64: dts: ti: am62-phyboard-lyra: Add overlay to
 enable a GPIO fan
In-Reply-To: <20240207172820.478332-1-nmorrisson@phytec.com>
References: <20240207172820.478332-1-nmorrisson@phytec.com>
Message-ID: <ynrdlauwefl6ckabxtk5qykeffcyisi6wivlforzbij3sga6uo@xdgewvanjgug>

Hi Nathan,

Thanks for the patch.

On Feb 07, 2024 at 09:28:20 -0800, Nathan Morrisson wrote:
> The phyBOARD-Lyra has a GPIO fan header. This overlay enables the fan
> header and sets the fan to turn on at 65C.
> 
> Signed-off-by: Nathan Morrisson <nmorrisson at phytec.com>
> ---
>  arch/arm64/boot/dts/ti/Makefile               |  1 +
>  .../ti/k3-am62-phyboard-lyra-gpio-fan.dtso    | 51 +++++++++++++++++++
>  2 files changed, 52 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
> 
> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
> index 52c1dc910308..379fb4f31a1f 100644
> --- a/arch/arm64/boot/dts/ti/Makefile
> +++ b/arch/arm64/boot/dts/ti/Makefile
> @@ -23,6 +23,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
>  dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-mallow.dtb
>  dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
>  dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
> +dtb-$(CONFIG_ARCH_K3) += k3-am62-phyboard-lyra-gpio-fan.dtbo

You can also add a compile time test, to check if this applies cleanly 
on your phyboard base DTB.

Please see the "Build time test only, enabled by CONFIG_OF_ALL_DTBS" 
section below in this file.

>  
>  # Boards with AM62Ax SoC
>  dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso b/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
> new file mode 100644
> index 000000000000..9c05748bdd9d
> --- /dev/null
> +++ b/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
> @@ -0,0 +1,51 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +/*
> + * Copyright (C) 2024 PHYTEC America LLC
> + * Author: Garrett Giordano <ggiordano at phytec.com>
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/thermal/thermal.h>
> +#include "k3-pinctrl.h"
> +
> +&{/} {
> +	fan: gpio-fan {
> +		compatible = "gpio-fan";
> +		gpio-fan,speed-map = <0 0 8600 1>;
> +		gpios = <&main_gpio0 40 GPIO_ACTIVE_LOW>;
> +		#cooling-cells = <2>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&gpio_fan_pins_default>;
> +		status = "okay";
> +	};
> +};
> +
> +&main_pmx0 {
> +	gpio_fan_pins_default: gpio-fan-default-pins {
> +		pinctrl-single,pins = <
> +			AM62X_IOPAD(0x0a4, PIN_OUTPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
> +		>;
> +	};
> +};
> +
> +&thermal_zones {
> +	main0_thermal: main0-thermal {
> +		trips {
> +			main0_thermal_trip0: main0-thermal-trip {
> +				temperature = <65000>;  /* millicelsius */
> +				hysteresis = <2000>;    /* millicelsius */
> +				type = "active";
> +			};
> +		};
> +
> +		cooling-maps {
> +			map0 {
> +				trip = <&main0_thermal_trip0>;
> +				cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> +			};
> +		};
> +	};
> +};
> -- 
> 2.25.1
> 

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240208/efdd438b/attachment-0001.sig>

From rppt at kernel.org  Wed Feb  7 22:10:59 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:10:59 +0200
Subject: [PATCH v3 01/15] arm64/mm: Make set_ptes() robust when OAs cross
 48-bit boundary
In-Reply-To: <20240129124649.189745-2-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-2-david@redhat.com>
Message-ID: <ZcRwc2mEDHIXxgGa@kernel.org>

On Mon, Jan 29, 2024 at 01:46:35PM +0100, David Hildenbrand wrote:
> From: Ryan Roberts <ryan.roberts at arm.com>
> 
> Since the high bits [51:48] of an OA are not stored contiguously in the
> PTE, there is a theoretical bug in set_ptes(), which just adds PAGE_SIZE
> to the pte to get the pte with the next pfn. This works until the pfn
> crosses the 48-bit boundary, at which point we overflow into the upper
> attributes.
> 
> Of course one could argue (and Matthew Wilcox has :) that we will never
> see a folio cross this boundary because we only allow naturally aligned
> power-of-2 allocation, so this would require a half-petabyte folio. So
> its only a theoretical bug. But its better that the code is robust
> regardless.
> 
> I've implemented pte_next_pfn() as part of the fix, which is an opt-in
> core-mm interface. So that is now available to the core-mm, which will
> be needed shortly to support forthcoming fork()-batching optimizations.
> 
> Link: https://lkml.kernel.org/r/20240125173534.1659317-1-ryan.roberts at arm.com
> Fixes: 4a169d61c2ed ("arm64: implement the new page table range API")
> Closes: https://lore.kernel.org/linux-mm/fdaeb9a5-d890-499a-92c8-d171df43ad01 at arm.com/
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
> Reviewed-by: David Hildenbrand <david at redhat.com>
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  arch/arm64/include/asm/pgtable.h | 28 +++++++++++++++++-----------
>  1 file changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index b50270107e2f..9428801c1040 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -341,6 +341,22 @@ static inline void __sync_cache_and_tags(pte_t pte, unsigned int nr_pages)
>  		mte_sync_tags(pte, nr_pages);
>  }
>  
> +/*
> + * Select all bits except the pfn
> + */
> +static inline pgprot_t pte_pgprot(pte_t pte)
> +{
> +	unsigned long pfn = pte_pfn(pte);
> +
> +	return __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte));
> +}
> +
> +#define pte_next_pfn pte_next_pfn
> +static inline pte_t pte_next_pfn(pte_t pte)
> +{
> +	return pfn_pte(pte_pfn(pte) + 1, pte_pgprot(pte));
> +}
> +
>  static inline void set_ptes(struct mm_struct *mm,
>  			    unsigned long __always_unused addr,
>  			    pte_t *ptep, pte_t pte, unsigned int nr)
> @@ -354,7 +370,7 @@ static inline void set_ptes(struct mm_struct *mm,
>  		if (--nr == 0)
>  			break;
>  		ptep++;
> -		pte_val(pte) += PAGE_SIZE;
> +		pte = pte_next_pfn(pte);
>  	}
>  }
>  #define set_ptes set_ptes
> @@ -433,16 +449,6 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
>  	return clear_pte_bit(pte, __pgprot(PTE_SWP_EXCLUSIVE));
>  }
>  
> -/*
> - * Select all bits except the pfn
> - */
> -static inline pgprot_t pte_pgprot(pte_t pte)
> -{
> -	unsigned long pfn = pte_pfn(pte);
> -
> -	return __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte));
> -}
> -
>  #ifdef CONFIG_NUMA_BALANCING
>  /*
>   * See the comment in include/linux/pgtable.h
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:11:54 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:11:54 +0200
Subject: [PATCH v3 02/15] arm/pgtable: define PFN_PTE_SHIFT
In-Reply-To: <20240129124649.189745-3-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-3-david@redhat.com>
Message-ID: <ZcRwqizngdTmd7G8@kernel.org>

On Mon, Jan 29, 2024 at 01:46:36PM +0100, David Hildenbrand wrote:
> We want to make use of pte_next_pfn() outside of set_ptes(). Let's
> simply define PFN_PTE_SHIFT, required by pte_next_pfn().
> 
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  arch/arm/include/asm/pgtable.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
> index d657b84b6bf7..be91e376df79 100644
> --- a/arch/arm/include/asm/pgtable.h
> +++ b/arch/arm/include/asm/pgtable.h
> @@ -209,6 +209,8 @@ static inline void __sync_icache_dcache(pte_t pteval)
>  extern void __sync_icache_dcache(pte_t pteval);
>  #endif
>  
> +#define PFN_PTE_SHIFT		PAGE_SHIFT
> +
>  void set_ptes(struct mm_struct *mm, unsigned long addr,
>  		      pte_t *ptep, pte_t pteval, unsigned int nr);
>  #define set_ptes set_ptes
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:12:44 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:12:44 +0200
Subject: [PATCH v3 03/15] nios2/pgtable: define PFN_PTE_SHIFT
In-Reply-To: <20240129124649.189745-4-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-4-david@redhat.com>
Message-ID: <ZcRw3GoICHW_KgT4@kernel.org>

On Mon, Jan 29, 2024 at 01:46:37PM +0100, David Hildenbrand wrote:
> We want to make use of pte_next_pfn() outside of set_ptes(). Let's
> simply define PFN_PTE_SHIFT, required by pte_next_pfn().
> 
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  arch/nios2/include/asm/pgtable.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/nios2/include/asm/pgtable.h b/arch/nios2/include/asm/pgtable.h
> index 5144506dfa69..d052dfcbe8d3 100644
> --- a/arch/nios2/include/asm/pgtable.h
> +++ b/arch/nios2/include/asm/pgtable.h
> @@ -178,6 +178,8 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
>  	*ptep = pteval;
>  }
>  
> +#define PFN_PTE_SHIFT		0
> +
>  static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
>  		pte_t *ptep, pte_t pte, unsigned int nr)
>  {
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:13:42 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:13:42 +0200
Subject: [PATCH v3 04/15] powerpc/pgtable: define PFN_PTE_SHIFT
In-Reply-To: <20240129124649.189745-5-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-5-david@redhat.com>
Message-ID: <ZcRxFksWIcN5Cdgx@kernel.org>

On Mon, Jan 29, 2024 at 01:46:38PM +0100, David Hildenbrand wrote:
> We want to make use of pte_next_pfn() outside of set_ptes(). Let's
> simply define PFN_PTE_SHIFT, required by pte_next_pfn().
> 
> Reviewed-by: Christophe Leroy <christophe.leroy at csgroup.eu>
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  arch/powerpc/include/asm/pgtable.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
> index 9224f23065ff..7a1ba8889aea 100644
> --- a/arch/powerpc/include/asm/pgtable.h
> +++ b/arch/powerpc/include/asm/pgtable.h
> @@ -41,6 +41,8 @@ struct mm_struct;
>  
>  #ifndef __ASSEMBLY__
>  
> +#define PFN_PTE_SHIFT		PTE_RPN_SHIFT
> +
>  void set_ptes(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
>  		pte_t pte, unsigned int nr);
>  #define set_ptes set_ptes
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:14:47 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:14:47 +0200
Subject: [PATCH v3 05/15] riscv/pgtable: define PFN_PTE_SHIFT
In-Reply-To: <20240129124649.189745-6-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-6-david@redhat.com>
Message-ID: <ZcRxVwWdvIjva9Vz@kernel.org>

On Mon, Jan 29, 2024 at 01:46:39PM +0100, David Hildenbrand wrote:
> We want to make use of pte_next_pfn() outside of set_ptes(). Let's
> simply define PFN_PTE_SHIFT, required by pte_next_pfn().
> 
> Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  arch/riscv/include/asm/pgtable.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> index 0c94260b5d0c..add5cd30ab34 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -523,6 +523,8 @@ static inline void __set_pte_at(pte_t *ptep, pte_t pteval)
>  	set_pte(ptep, pteval);
>  }
>  
> +#define PFN_PTE_SHIFT		_PAGE_PFN_SHIFT
> +
>  static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
>  		pte_t *ptep, pte_t pteval, unsigned int nr)
>  {
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:15:27 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:15:27 +0200
Subject: [PATCH v3 06/15] s390/pgtable: define PFN_PTE_SHIFT
In-Reply-To: <20240129124649.189745-7-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-7-david@redhat.com>
Message-ID: <ZcRxfx4Ze-_KXzE7@kernel.org>

On Mon, Jan 29, 2024 at 01:46:40PM +0100, David Hildenbrand wrote:
> We want to make use of pte_next_pfn() outside of set_ptes(). Let's
> simply define PFN_PTE_SHIFT, required by pte_next_pfn().
> 
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  arch/s390/include/asm/pgtable.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
> index 1299b56e43f6..4b91e65c85d9 100644
> --- a/arch/s390/include/asm/pgtable.h
> +++ b/arch/s390/include/asm/pgtable.h
> @@ -1316,6 +1316,8 @@ pgprot_t pgprot_writecombine(pgprot_t prot);
>  #define pgprot_writethrough	pgprot_writethrough
>  pgprot_t pgprot_writethrough(pgprot_t prot);
>  
> +#define PFN_PTE_SHIFT		PAGE_SHIFT
> +
>  /*
>   * Set multiple PTEs to consecutive pages with a single call.  All PTEs
>   * are within the same folio, PMD and VMA.
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:18:55 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:18:55 +0200
Subject: [PATCH v3 07/15] sparc/pgtable: define PFN_PTE_SHIFT
In-Reply-To: <20240129124649.189745-8-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-8-david@redhat.com>
Message-ID: <ZcRyT9qil3f-Jot5@kernel.org>

On Mon, Jan 29, 2024 at 01:46:41PM +0100, David Hildenbrand wrote:
> We want to make use of pte_next_pfn() outside of set_ptes(). Let's
> simply define PFN_PTE_SHIFT, required by pte_next_pfn().
> 
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  arch/sparc/include/asm/pgtable_64.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
> index a8c871b7d786..652af9d63fa2 100644
> --- a/arch/sparc/include/asm/pgtable_64.h
> +++ b/arch/sparc/include/asm/pgtable_64.h
> @@ -929,6 +929,8 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
>  	maybe_tlb_batch_add(mm, addr, ptep, orig, fullmm, PAGE_SHIFT);
>  }
>  
> +#define PFN_PTE_SHIFT		PAGE_SHIFT
> +
>  static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
>  		pte_t *ptep, pte_t pte, unsigned int nr)
>  {
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:19:27 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:19:27 +0200
Subject: [PATCH v3 08/15] mm/pgtable: make pte_next_pfn() independent of
 set_ptes()
In-Reply-To: <20240129124649.189745-9-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-9-david@redhat.com>
Message-ID: <ZcRyb2o_lq2XITH_@kernel.org>

On Mon, Jan 29, 2024 at 01:46:42PM +0100, David Hildenbrand wrote:
> Let's provide pte_next_pfn(), independently of set_ptes(). This allows for
> using the generic pte_next_pfn() version in some arch-specific set_ptes()
> implementations, and prepares for reusing pte_next_pfn() in other context.
> 
> Reviewed-by: Christophe Leroy <christophe.leroy at csgroup.eu>
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  include/linux/pgtable.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index f6d0e3513948..351cd9dc7194 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -212,7 +212,6 @@ static inline int pmd_dirty(pmd_t pmd)
>  #define arch_flush_lazy_mmu_mode()	do {} while (0)
>  #endif
>  
> -#ifndef set_ptes
>  
>  #ifndef pte_next_pfn
>  static inline pte_t pte_next_pfn(pte_t pte)
> @@ -221,6 +220,7 @@ static inline pte_t pte_next_pfn(pte_t pte)
>  }
>  #endif
>  
> +#ifndef set_ptes
>  /**
>   * set_ptes - Map consecutive pages to a contiguous range of addresses.
>   * @mm: Address space to map the pages into.
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:20:09 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:20:09 +0200
Subject: [PATCH v3 09/15] arm/mm: use pte_next_pfn() in set_ptes()
In-Reply-To: <20240129124649.189745-10-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-10-david@redhat.com>
Message-ID: <ZcRymY35KnPAuuzY@kernel.org>

On Mon, Jan 29, 2024 at 01:46:43PM +0100, David Hildenbrand wrote:
> Let's use our handy helper now that it's available on all archs.
> 
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  arch/arm/mm/mmu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index 674ed71573a8..c24e29c0b9a4 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -1814,6 +1814,6 @@ void set_ptes(struct mm_struct *mm, unsigned long addr,
>  		if (--nr == 0)
>  			break;
>  		ptep++;
> -		pte_val(pteval) += PAGE_SIZE;
> +		pteval = pte_next_pfn(pteval);
>  	}
>  }
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:20:57 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:20:57 +0200
Subject: [PATCH v3 10/15] powerpc/mm: use pte_next_pfn() in set_ptes()
In-Reply-To: <20240129124649.189745-11-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-11-david@redhat.com>
Message-ID: <ZcRyyTjbq8jxoPWC@kernel.org>

On Mon, Jan 29, 2024 at 01:46:44PM +0100, David Hildenbrand wrote:
> Let's use our handy new helper. Note that the implementation is slightly
> different, but shouldn't really make a difference in practice.
> 
> Reviewed-by: Christophe Leroy <christophe.leroy at csgroup.eu>
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  arch/powerpc/mm/pgtable.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
> index a04ae4449a02..549a440ed7f6 100644
> --- a/arch/powerpc/mm/pgtable.c
> +++ b/arch/powerpc/mm/pgtable.c
> @@ -220,10 +220,7 @@ void set_ptes(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
>  			break;
>  		ptep++;
>  		addr += PAGE_SIZE;
> -		/*
> -		 * increment the pfn.
> -		 */
> -		pte = pfn_pte(pte_pfn(pte) + 1, pte_pgprot((pte)));
> +		pte = pte_next_pfn(pte);
>  	}
>  }
>  
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:27:24 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:27:24 +0200
Subject: [PATCH v3 12/15] mm/memory: pass PTE to copy_present_pte()
In-Reply-To: <20240129124649.189745-13-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-13-david@redhat.com>
Message-ID: <ZcR0TF5d75ucLjBm@kernel.org>

On Mon, Jan 29, 2024 at 01:46:46PM +0100, David Hildenbrand wrote:
> We already read it, let's just forward it.
> 
> This patch is based on work by Ryan Roberts.
> 
> Reviewed-by: Ryan Roberts <ryan.roberts at arm.com>
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  mm/memory.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/mm/memory.c b/mm/memory.c
> index a3bdb25f4c8d..41b24da5be38 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -959,10 +959,9 @@ static inline void __copy_present_pte(struct vm_area_struct *dst_vma,
>   */
>  static inline int
>  copy_present_pte(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
> -		 pte_t *dst_pte, pte_t *src_pte, unsigned long addr, int *rss,
> -		 struct folio **prealloc)
> +		 pte_t *dst_pte, pte_t *src_pte, pte_t pte, unsigned long addr,
> +		 int *rss, struct folio **prealloc)
>  {
> -	pte_t pte = ptep_get(src_pte);
>  	struct page *page;
>  	struct folio *folio;
>  
> @@ -1103,7 +1102,7 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  		}
>  		/* copy_present_pte() will clear `*prealloc' if consumed */
>  		ret = copy_present_pte(dst_vma, src_vma, dst_pte, src_pte,
> -				       addr, rss, &prealloc);
> +				       ptent, addr, rss, &prealloc);
>  		/*
>  		 * If we need a pre-allocated page for this pte, drop the
>  		 * locks, allocate, and try again.
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:29:21 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:29:21 +0200
Subject: [PATCH v3 11/15] mm/memory: factor out copying the actual PTE in
 copy_present_pte()
In-Reply-To: <20240129124649.189745-12-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-12-david@redhat.com>
Message-ID: <ZcR0waPgUzfQgyGQ@kernel.org>

On Mon, Jan 29, 2024 at 01:46:45PM +0100, David Hildenbrand wrote:
> Let's prepare for further changes.
> 
> Reviewed-by: Ryan Roberts <ryan.roberts at arm.com>
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  mm/memory.c | 63 ++++++++++++++++++++++++++++-------------------------
>  1 file changed, 33 insertions(+), 30 deletions(-)
> 
> diff --git a/mm/memory.c b/mm/memory.c
> index 8d14ba440929..a3bdb25f4c8d 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -930,6 +930,29 @@ copy_present_page(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma
>  	return 0;
>  }
>  
> +static inline void __copy_present_pte(struct vm_area_struct *dst_vma,
> +		struct vm_area_struct *src_vma, pte_t *dst_pte, pte_t *src_pte,
> +		pte_t pte, unsigned long addr)
> +{
> +	struct mm_struct *src_mm = src_vma->vm_mm;
> +
> +	/* If it's a COW mapping, write protect it both processes. */
> +	if (is_cow_mapping(src_vma->vm_flags) && pte_write(pte)) {
> +		ptep_set_wrprotect(src_mm, addr, src_pte);
> +		pte = pte_wrprotect(pte);
> +	}
> +
> +	/* If it's a shared mapping, mark it clean in the child. */
> +	if (src_vma->vm_flags & VM_SHARED)
> +		pte = pte_mkclean(pte);
> +	pte = pte_mkold(pte);
> +
> +	if (!userfaultfd_wp(dst_vma))
> +		pte = pte_clear_uffd_wp(pte);
> +
> +	set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte);
> +}
> +
>  /*
>   * Copy one pte.  Returns 0 if succeeded, or -EAGAIN if one preallocated page
>   * is required to copy this pte.
> @@ -939,23 +962,23 @@ copy_present_pte(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  		 pte_t *dst_pte, pte_t *src_pte, unsigned long addr, int *rss,
>  		 struct folio **prealloc)
>  {
> -	struct mm_struct *src_mm = src_vma->vm_mm;
> -	unsigned long vm_flags = src_vma->vm_flags;
>  	pte_t pte = ptep_get(src_pte);
>  	struct page *page;
>  	struct folio *folio;
>  
>  	page = vm_normal_page(src_vma, addr, pte);
> -	if (page)
> -		folio = page_folio(page);
> -	if (page && folio_test_anon(folio)) {
> +	if (unlikely(!page))
> +		goto copy_pte;
> +
> +	folio = page_folio(page);
> +	folio_get(folio);
> +	if (folio_test_anon(folio)) {
>  		/*
>  		 * If this page may have been pinned by the parent process,
>  		 * copy the page immediately for the child so that we'll always
>  		 * guarantee the pinned page won't be randomly replaced in the
>  		 * future.
>  		 */
> -		folio_get(folio);
>  		if (unlikely(folio_try_dup_anon_rmap_pte(folio, page, src_vma))) {
>  			/* Page may be pinned, we have to copy. */
>  			folio_put(folio);
> @@ -963,34 +986,14 @@ copy_present_pte(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  						 addr, rss, prealloc, page);
>  		}
>  		rss[MM_ANONPAGES]++;
> -	} else if (page) {
> -		folio_get(folio);
> +		VM_WARN_ON_FOLIO(PageAnonExclusive(page), folio);
> +	} else {
>  		folio_dup_file_rmap_pte(folio, page);
>  		rss[mm_counter_file(folio)]++;
>  	}
>  
> -	/*
> -	 * If it's a COW mapping, write protect it both
> -	 * in the parent and the child
> -	 */
> -	if (is_cow_mapping(vm_flags) && pte_write(pte)) {
> -		ptep_set_wrprotect(src_mm, addr, src_pte);
> -		pte = pte_wrprotect(pte);
> -	}
> -	VM_BUG_ON(page && folio_test_anon(folio) && PageAnonExclusive(page));
> -
> -	/*
> -	 * If it's a shared mapping, mark it clean in
> -	 * the child
> -	 */
> -	if (vm_flags & VM_SHARED)
> -		pte = pte_mkclean(pte);
> -	pte = pte_mkold(pte);
> -
> -	if (!userfaultfd_wp(dst_vma))
> -		pte = pte_clear_uffd_wp(pte);
> -
> -	set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte);
> +copy_pte:
> +	__copy_present_pte(dst_vma, src_vma, dst_pte, src_pte, pte, addr);
>  	return 0;
>  }
>  
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Feb  7 22:41:56 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 8 Feb 2024 08:41:56 +0200
Subject: [PATCH v3 13/15] mm/memory: optimize fork() with PTE-mapped THP
In-Reply-To: <20240129124649.189745-14-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-14-david@redhat.com>
Message-ID: <ZcR3tBy9n0Yp5eq2@kernel.org>

On Mon, Jan 29, 2024 at 01:46:47PM +0100, David Hildenbrand wrote:
> Let's implement PTE batching when consecutive (present) PTEs map
> consecutive pages of the same large folio, and all other PTE bits besides
> the PFNs are equal.
> 
> We will optimize folio_pte_batch() separately, to ignore selected
> PTE bits. This patch is based on work by Ryan Roberts.
> 
> Use __always_inline for __copy_present_ptes() and keep the handling for
> single PTEs completely separate from the multi-PTE case: we really want
> the compiler to optimize for the single-PTE case with small folios, to
> not degrade performance.
> 
> Note that PTE batching will never exceed a single page table and will
> always stay within VMA boundaries.
> 
> Further, processing PTE-mapped THP that maybe pinned and have
> PageAnonExclusive set on at least one subpage should work as expected,
> but there is room for improvement: We will repeatedly (1) detect a PTE
> batch (2) detect that we have to copy a page (3) fall back and allocate a
> single page to copy a single page. For now we won't care as pinned pages
> are a corner case, and we should rather look into maintaining only a
> single PageAnonExclusive bit for large folios.
> 
> Reviewed-by: Ryan Roberts <ryan.roberts at arm.com>
> Signed-off-by: David Hildenbrand <david at redhat.com>

Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

> ---
>  include/linux/pgtable.h |  31 +++++++++++
>  mm/memory.c             | 112 +++++++++++++++++++++++++++++++++-------
>  2 files changed, 124 insertions(+), 19 deletions(-)
> 
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 351cd9dc7194..aab227e12493 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -650,6 +650,37 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
>  }
>  #endif
>  
> +#ifndef wrprotect_ptes
> +/**
> + * wrprotect_ptes - Write-protect PTEs that map consecutive pages of the same
> + *		    folio.
> + * @mm: Address space the pages are mapped into.
> + * @addr: Address the first page is mapped at.
> + * @ptep: Page table pointer for the first entry.
> + * @nr: Number of entries to write-protect.
> + *
> + * May be overridden by the architecture; otherwise, implemented as a simple
> + * loop over ptep_set_wrprotect().
> + *
> + * Note that PTE bits in the PTE range besides the PFN can differ. For example,
> + * some PTEs might be write-protected.
> + *
> + * Context: The caller holds the page table lock.  The PTEs map consecutive
> + * pages that belong to the same folio.  The PTEs are all in the same PMD.
> + */
> +static inline void wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
> +		pte_t *ptep, unsigned int nr)
> +{
> +	for (;;) {
> +		ptep_set_wrprotect(mm, addr, ptep);
> +		if (--nr == 0)
> +			break;
> +		ptep++;
> +		addr += PAGE_SIZE;
> +	}
> +}
> +#endif
> +
>  /*
>   * On some architectures hardware does not set page access bit when accessing
>   * memory page, it is responsibility of software setting this bit. It brings
> diff --git a/mm/memory.c b/mm/memory.c
> index 41b24da5be38..86f8a0021c8e 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -930,15 +930,15 @@ copy_present_page(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma
>  	return 0;
>  }
>  
> -static inline void __copy_present_pte(struct vm_area_struct *dst_vma,
> +static __always_inline void __copy_present_ptes(struct vm_area_struct *dst_vma,
>  		struct vm_area_struct *src_vma, pte_t *dst_pte, pte_t *src_pte,
> -		pte_t pte, unsigned long addr)
> +		pte_t pte, unsigned long addr, int nr)
>  {
>  	struct mm_struct *src_mm = src_vma->vm_mm;
>  
>  	/* If it's a COW mapping, write protect it both processes. */
>  	if (is_cow_mapping(src_vma->vm_flags) && pte_write(pte)) {
> -		ptep_set_wrprotect(src_mm, addr, src_pte);
> +		wrprotect_ptes(src_mm, addr, src_pte, nr);
>  		pte = pte_wrprotect(pte);
>  	}
>  
> @@ -950,26 +950,93 @@ static inline void __copy_present_pte(struct vm_area_struct *dst_vma,
>  	if (!userfaultfd_wp(dst_vma))
>  		pte = pte_clear_uffd_wp(pte);
>  
> -	set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte);
> +	set_ptes(dst_vma->vm_mm, addr, dst_pte, pte, nr);
> +}
> +
> +/*
> + * Detect a PTE batch: consecutive (present) PTEs that map consecutive
> + * pages of the same folio.
> + *
> + * All PTEs inside a PTE batch have the same PTE bits set, excluding the PFN.
> + */
> +static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
> +		pte_t *start_ptep, pte_t pte, int max_nr)
> +{
> +	unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio);
> +	const pte_t *end_ptep = start_ptep + max_nr;
> +	pte_t expected_pte = pte_next_pfn(pte);
> +	pte_t *ptep = start_ptep + 1;
> +
> +	VM_WARN_ON_FOLIO(!pte_present(pte), folio);
> +
> +	while (ptep != end_ptep) {
> +		pte = ptep_get(ptep);
> +
> +		if (!pte_same(pte, expected_pte))
> +			break;
> +
> +		/*
> +		 * Stop immediately once we reached the end of the folio. In
> +		 * corner cases the next PFN might fall into a different
> +		 * folio.
> +		 */
> +		if (pte_pfn(pte) == folio_end_pfn)
> +			break;
> +
> +		expected_pte = pte_next_pfn(expected_pte);
> +		ptep++;
> +	}
> +
> +	return ptep - start_ptep;
>  }
>  
>  /*
> - * Copy one pte.  Returns 0 if succeeded, or -EAGAIN if one preallocated page
> - * is required to copy this pte.
> + * Copy one present PTE, trying to batch-process subsequent PTEs that map
> + * consecutive pages of the same folio by copying them as well.
> + *
> + * Returns -EAGAIN if one preallocated page is required to copy the next PTE.
> + * Otherwise, returns the number of copied PTEs (at least 1).
>   */
>  static inline int
> -copy_present_pte(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
> +copy_present_ptes(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  		 pte_t *dst_pte, pte_t *src_pte, pte_t pte, unsigned long addr,
> -		 int *rss, struct folio **prealloc)
> +		 int max_nr, int *rss, struct folio **prealloc)
>  {
>  	struct page *page;
>  	struct folio *folio;
> +	int err, nr;
>  
>  	page = vm_normal_page(src_vma, addr, pte);
>  	if (unlikely(!page))
>  		goto copy_pte;
>  
>  	folio = page_folio(page);
> +
> +	/*
> +	 * If we likely have to copy, just don't bother with batching. Make
> +	 * sure that the common "small folio" case is as fast as possible
> +	 * by keeping the batching logic separate.
> +	 */
> +	if (unlikely(!*prealloc && folio_test_large(folio) && max_nr != 1)) {
> +		nr = folio_pte_batch(folio, addr, src_pte, pte, max_nr);
> +		folio_ref_add(folio, nr);
> +		if (folio_test_anon(folio)) {
> +			if (unlikely(folio_try_dup_anon_rmap_ptes(folio, page,
> +								  nr, src_vma))) {
> +				folio_ref_sub(folio, nr);
> +				return -EAGAIN;
> +			}
> +			rss[MM_ANONPAGES] += nr;
> +			VM_WARN_ON_FOLIO(PageAnonExclusive(page), folio);
> +		} else {
> +			folio_dup_file_rmap_ptes(folio, page, nr);
> +			rss[mm_counter_file(folio)] += nr;
> +		}
> +		__copy_present_ptes(dst_vma, src_vma, dst_pte, src_pte, pte,
> +				    addr, nr);
> +		return nr;
> +	}
> +
>  	folio_get(folio);
>  	if (folio_test_anon(folio)) {
>  		/*
> @@ -981,8 +1048,9 @@ copy_present_pte(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  		if (unlikely(folio_try_dup_anon_rmap_pte(folio, page, src_vma))) {
>  			/* Page may be pinned, we have to copy. */
>  			folio_put(folio);
> -			return copy_present_page(dst_vma, src_vma, dst_pte, src_pte,
> -						 addr, rss, prealloc, page);
> +			err = copy_present_page(dst_vma, src_vma, dst_pte, src_pte,
> +						addr, rss, prealloc, page);
> +			return err ? err : 1;
>  		}
>  		rss[MM_ANONPAGES]++;
>  		VM_WARN_ON_FOLIO(PageAnonExclusive(page), folio);
> @@ -992,8 +1060,8 @@ copy_present_pte(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  	}
>  
>  copy_pte:
> -	__copy_present_pte(dst_vma, src_vma, dst_pte, src_pte, pte, addr);
> -	return 0;
> +	__copy_present_ptes(dst_vma, src_vma, dst_pte, src_pte, pte, addr, 1);
> +	return 1;
>  }
>  
>  static inline struct folio *folio_prealloc(struct mm_struct *src_mm,
> @@ -1030,10 +1098,11 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  	pte_t *src_pte, *dst_pte;
>  	pte_t ptent;
>  	spinlock_t *src_ptl, *dst_ptl;
> -	int progress, ret = 0;
> +	int progress, max_nr, ret = 0;
>  	int rss[NR_MM_COUNTERS];
>  	swp_entry_t entry = (swp_entry_t){0};
>  	struct folio *prealloc = NULL;
> +	int nr;
>  
>  again:
>  	progress = 0;
> @@ -1064,6 +1133,8 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  	arch_enter_lazy_mmu_mode();
>  
>  	do {
> +		nr = 1;
> +
>  		/*
>  		 * We are holding two locks at this point - either of them
>  		 * could generate latencies in another task on another CPU.
> @@ -1100,9 +1171,10 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  			 */
>  			WARN_ON_ONCE(ret != -ENOENT);
>  		}
> -		/* copy_present_pte() will clear `*prealloc' if consumed */
> -		ret = copy_present_pte(dst_vma, src_vma, dst_pte, src_pte,
> -				       ptent, addr, rss, &prealloc);
> +		/* copy_present_ptes() will clear `*prealloc' if consumed */
> +		max_nr = (end - addr) / PAGE_SIZE;
> +		ret = copy_present_ptes(dst_vma, src_vma, dst_pte, src_pte,
> +					ptent, addr, max_nr, rss, &prealloc);
>  		/*
>  		 * If we need a pre-allocated page for this pte, drop the
>  		 * locks, allocate, and try again.
> @@ -1119,8 +1191,10 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  			folio_put(prealloc);
>  			prealloc = NULL;
>  		}
> -		progress += 8;
> -	} while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);
> +		nr = ret;
> +		progress += 8 * nr;
> +	} while (dst_pte += nr, src_pte += nr, addr += PAGE_SIZE * nr,
> +		 addr != end);
>  
>  	arch_leave_lazy_mmu_mode();
>  	pte_unmap_unlock(orig_src_pte, src_ptl);
> @@ -1141,7 +1215,7 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>  		prealloc = folio_prealloc(src_mm, src_vma, addr, false);
>  		if (!prealloc)
>  			return -ENOMEM;
> -	} else if (ret) {
> +	} else if (ret < 0) {
>  		VM_WARN_ON_ONCE(1);
>  	}
>  
> -- 
> 2.43.0
> 
> 

-- 
Sincerely yours,
Mike.


From kalyani.akula at amd.com  Wed Feb  7 22:47:52 2024
From: kalyani.akula at amd.com (Akula, Kalyani)
Date: Thu, 8 Feb 2024 06:47:52 +0000
Subject: [PATCH V4 2/4] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
In-Reply-To: <20240202113843.17999-3-praveen.teja.kundanala@amd.com>
References: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
 <20240202113843.17999-3-praveen.teja.kundanala@amd.com>
Message-ID: <DM6PR12MB41547758296EEDAF2B5DFFF3F8442@DM6PR12MB4154.namprd12.prod.outlook.com>



>-----Original Message-----
>From: Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
>Sent: Friday, February 2, 2024 5:09 PM
>To: srinivas.kandagatla at linaro.org; Simek, Michal <michal.simek at amd.com>;
>Akula, Kalyani <kalyani.akula at amd.com>; Kundanala, Praveen Teja
><praveen.teja.kundanala at amd.com>; devicetree at vger.kernel.org; linux-arm-
>kernel at lists.infradead.org
>Cc: linux-kernel at vger.kernel.org
>Subject: [PATCH V4 2/4] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe
>cleanup
>
>- Remove static nvmem_config declaration
>- Remove zynqmp_nvmem_data
>
>Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
>---
> drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------
> 1 file changed, 12 insertions(+), 25 deletions(-)
>
>diff --git a/drivers/nvmem/zynqmp_nvmem.c
>b/drivers/nvmem/zynqmp_nvmem.c index 7f15aa89a9d0..391d8e88b270
>100644
>--- a/drivers/nvmem/zynqmp_nvmem.c
>+++ b/drivers/nvmem/zynqmp_nvmem.c
>@@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0+
> /*
>  * Copyright (C) 2019 Xilinx, Inc.
>+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
>  */
>
> #include <linux/module.h>
>@@ -11,36 +12,25 @@
>
> #define SILICON_REVISION_MASK 0xF
>
>-struct zynqmp_nvmem_data {
>-	struct device *dev;
>-	struct nvmem_device *nvmem;
>-};
>
> static int zynqmp_nvmem_read(void *context, unsigned int offset,
> 			     void *val, size_t bytes)
> {
>+	struct device *dev = context;
> 	int ret;
>-	int idcode, version;
>-	struct zynqmp_nvmem_data *priv = context;
>+	int idcode;
>+	int version;
>
> 	ret = zynqmp_pm_get_chipid(&idcode, &version);
> 	if (ret < 0)
> 		return ret;
>
>-	dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version);
>+	dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
> 	*(int *)val = version & SILICON_REVISION_MASK;
>
> 	return 0;
> }
>
>-static struct nvmem_config econfig = {
>-	.name = "zynqmp-nvmem",
>-	.owner = THIS_MODULE,
>-	.word_size = 1,
>-	.size = 1,
>-	.read_only = true,
>-};
>-
> static const struct of_device_id zynqmp_nvmem_match[] = {
> 	{ .compatible = "xlnx,zynqmp-nvmem-fw", },
> 	{ /* sentinel */ },
>@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_match);
>static int zynqmp_nvmem_probe(struct platform_device *pdev)  {
> 	struct device *dev = &pdev->dev;
>-	struct zynqmp_nvmem_data *priv;
>+	struct nvmem_config econfig = {};
>
>-	priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data),
>GFP_KERNEL);
>-	if (!priv)
>-		return -ENOMEM;
>-
>-	priv->dev = dev;
>+	econfig.name = "zynqmp-nvmem";
>+	econfig.owner = THIS_MODULE;
>+	econfig.word_size = 1;
>+	econfig.size = 1;
> 	econfig.dev = dev;
> 	econfig.add_legacy_fixed_of_cells = true;
>+	econfig.read_only = true;
> 	econfig.reg_read = zynqmp_nvmem_read;
>-	econfig.priv = priv;
>-
>-	priv->nvmem = devm_nvmem_register(dev, &econfig);
>
>-	return PTR_ERR_OR_ZERO(priv->nvmem);
>+	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
> }
>
> static struct platform_driver zynqmp_nvmem_driver = {
>--
>2.37.6

Acked-by: Kalyani Akula <Kalyani.akula at amd.com>
 
Regards,
Kalyani


From kalyani.akula at amd.com  Wed Feb  7 22:48:36 2024
From: kalyani.akula at amd.com (Akula, Kalyani)
Date: Thu, 8 Feb 2024 06:48:36 +0000
Subject: [PATCH V4 3/4] nvmem: zynqmp_nvmem: Add support to access efuse
In-Reply-To: <20240202113843.17999-4-praveen.teja.kundanala@amd.com>
References: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
 <20240202113843.17999-4-praveen.teja.kundanala@amd.com>
Message-ID: <DM6PR12MB41543B4250DE257853937EC7F8442@DM6PR12MB4154.namprd12.prod.outlook.com>



>-----Original Message-----
>From: Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
>Sent: Friday, February 2, 2024 5:09 PM
>To: srinivas.kandagatla at linaro.org; Simek, Michal <michal.simek at amd.com>;
>Akula, Kalyani <kalyani.akula at amd.com>; Kundanala, Praveen Teja
><praveen.teja.kundanala at amd.com>; devicetree at vger.kernel.org; linux-arm-
>kernel at lists.infradead.org
>Cc: linux-kernel at vger.kernel.org
>Subject: [PATCH V4 3/4] nvmem: zynqmp_nvmem: Add support to access efuse
>
>Add support to read/write efuse memory map of ZynqMP.
>Below are the offsets of ZynqMP efuse memory map
>	0 - SOC version(read only)
>	0xC - 0xFC -ZynqMP specific purpose efuses
>	0x100 - 0x17F - Physical Unclonable Function(PUF)
>                efuses repurposed as user efuses
>
>Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala at amd.com>
>---
> drivers/nvmem/zynqmp_nvmem.c | 186
>+++++++++++++++++++++++++++++++++--
> 1 file changed, 176 insertions(+), 10 deletions(-)
>
>diff --git a/drivers/nvmem/zynqmp_nvmem.c
>b/drivers/nvmem/zynqmp_nvmem.c index 391d8e88b270..8682adaacd69
>100644
>--- a/drivers/nvmem/zynqmp_nvmem.c
>+++ b/drivers/nvmem/zynqmp_nvmem.c
>@@ -4,6 +4,7 @@
>  * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
>  */
>
>+#include <linux/dma-mapping.h>
> #include <linux/module.h>
> #include <linux/nvmem-provider.h>
> #include <linux/of.h>
>@@ -11,24 +12,189 @@
> #include <linux/firmware/xlnx-zynqmp.h>
>
> #define SILICON_REVISION_MASK 0xF
>+#define P_USER_0_64_UPPER_MASK	GENMASK(31, 16)
>+#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0)
>+#define WORD_INBYTES		4
>+#define SOC_VER_SIZE		0x4
>+#define EFUSE_MEMORY_SIZE	0x177
>+#define UNUSED_SPACE		0x8
>+#define ZYNQMP_NVMEM_SIZE	(SOC_VER_SIZE + UNUSED_SPACE + \
>+				 EFUSE_MEMORY_SIZE)
>+#define SOC_VERSION_OFFSET	0x0
>+#define EFUSE_START_OFFSET	0xC
>+#define EFUSE_END_OFFSET	0xFC
>+#define EFUSE_PUF_START_OFFSET	0x100
>+#define EFUSE_PUF_MID_OFFSET	0x140
>+#define EFUSE_PUF_END_OFFSET	0x17F
>+#define EFUSE_NOT_ENABLED	29
>
>+/*
>+ * efuse access type
>+ */
>+enum efuse_access {
>+	EFUSE_READ = 0,
>+	EFUSE_WRITE
>+};
>+
>+/**
>+ * struct xilinx_efuse - the basic structure
>+ * @src:	address of the buffer to store the data to be write/read
>+ * @size:	read/write word count
>+ * @offset:	read/write offset
>+ * @flag:	0 - represents efuse read and 1- represents efuse write
>+ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write
>+ *		1 - represents puf user fuse row number.
>+ *
>+ * this structure stores all the required details to
>+ * read/write efuse memory.
>+ */
>+struct xilinx_efuse {
>+	u64 src;
>+	u32 size;
>+	u32 offset;
>+	enum efuse_access flag;
>+	u32 pufuserfuse;
>+};
>+
>+static int zynqmp_efuse_access(void *context, unsigned int offset,
>+			       void *val, size_t bytes, enum efuse_access flag,
>+			       unsigned int pufflag)
>+{
>+	struct device *dev = context;
>+	struct xilinx_efuse *efuse;
>+	dma_addr_t dma_addr;
>+	dma_addr_t dma_buf;
>+	size_t words = bytes / WORD_INBYTES;
>+	int ret;
>+	int value;
>+	char *data;
>+
>+	if (bytes % WORD_INBYTES != 0) {
>+		dev_err(dev, "Bytes requested should be word aligned\n");
>+		return -EOPNOTSUPP;
>+	}
>+
>+	if (pufflag == 0 && offset % WORD_INBYTES) {
>+		dev_err(dev, "Offset requested should be word aligned\n");
>+		return -EOPNOTSUPP;
>+	}
>+
>+	if (pufflag == 1 && flag == EFUSE_WRITE) {
>+		memcpy(&value, val, bytes);
>+		if ((offset == EFUSE_PUF_START_OFFSET ||
>+		     offset == EFUSE_PUF_MID_OFFSET) &&
>+		    value & P_USER_0_64_UPPER_MASK) {
>+			dev_err(dev, "Only lower 4 bytes are allowed to be
>programmed in P_USER_0 & P_USER_64\n");
>+			return -EOPNOTSUPP;
>+		}
>+
>+		if (offset == EFUSE_PUF_END_OFFSET &&
>+		    (value & P_USER_127_LOWER_4_BIT_MASK)) {
>+			dev_err(dev, "Only MSB 28 bits are allowed to be
>programmed for P_USER_127\n");
>+			return -EOPNOTSUPP;
>+		}
>+	}
>+
>+	efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse),
>+				   &dma_addr, GFP_KERNEL);
>+	if (!efuse)
>+		return -ENOMEM;
>
>-static int zynqmp_nvmem_read(void *context, unsigned int offset,
>-			     void *val, size_t bytes)
>+	data = dma_alloc_coherent(dev, sizeof(bytes),
>+				  &dma_buf, GFP_KERNEL);
>+	if (!data) {
>+		ret = -ENOMEM;
>+		goto efuse_data_fail;
>+	}
>+
>+	if (flag == EFUSE_WRITE) {
>+		memcpy(data, val, bytes);
>+		efuse->flag = EFUSE_WRITE;
>+	} else {
>+		efuse->flag = EFUSE_READ;
>+	}
>+
>+	efuse->src = dma_buf;
>+	efuse->size = words;
>+	efuse->offset = offset;
>+	efuse->pufuserfuse = pufflag;
>+
>+	zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret);
>+	if (ret != 0) {
>+		if (ret == EFUSE_NOT_ENABLED) {
>+			dev_err(dev, "efuse access is not enabled\n");
>+			ret = -EOPNOTSUPP;
>+		} else {
>+			dev_err(dev, "Error in efuse read %x\n", ret);
>+			ret = -EPERM;
>+		}
>+		goto efuse_access_err;
>+	}
>+
>+	if (flag == EFUSE_READ)
>+		memcpy(val, data, bytes);
>+efuse_access_err:
>+	dma_free_coherent(dev, sizeof(bytes),
>+			  data, dma_buf);
>+efuse_data_fail:
>+	dma_free_coherent(dev, sizeof(struct xilinx_efuse),
>+			  efuse, dma_addr);
>+
>+	return ret;
>+}
>+
>+static int zynqmp_nvmem_read(void *context, unsigned int offset, void
>+*val, size_t bytes)
> {
> 	struct device *dev = context;
> 	int ret;
>+	int pufflag = 0;
> 	int idcode;
> 	int version;
>
>-	ret = zynqmp_pm_get_chipid(&idcode, &version);
>-	if (ret < 0)
>-		return ret;
>+	if (offset >= EFUSE_PUF_START_OFFSET && offset <=
>EFUSE_PUF_END_OFFSET)
>+		pufflag = 1;
>+
>+	switch (offset) {
>+	/* Soc version offset is zero */
>+	case SOC_VERSION_OFFSET:
>+		if (bytes != SOC_VER_SIZE)
>+			return -EOPNOTSUPP;
>+
>+		ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32
>*)&version);
>+		if (ret < 0)
>+			return ret;
>+
>+		dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
>+		*(int *)val = version & SILICON_REVISION_MASK;
>+		break;
>+	/* Efuse offset starts from 0xc */
>+	case EFUSE_START_OFFSET ... EFUSE_END_OFFSET:
>+	case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET:
>+		ret = zynqmp_efuse_access(context, offset, val,
>+					  bytes, EFUSE_READ, pufflag);
>+		break;
>+	default:
>+		*(u32 *)val = 0xDEADBEEF;
>+		ret = 0;
>+		break;
>+	}
>+
>+	return ret;
>+}
>+
>+static int zynqmp_nvmem_write(void *context,
>+			      unsigned int offset, void *val, size_t bytes) {
>+	int pufflag = 0;
>+
>+	if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET)
>+		return -EOPNOTSUPP;
>
>-	dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
>-	*(int *)val = version & SILICON_REVISION_MASK;
>+	if (offset >= EFUSE_PUF_START_OFFSET && offset <=
>EFUSE_PUF_END_OFFSET)
>+		pufflag = 1;
>
>-	return 0;
>+	return zynqmp_efuse_access(context, offset,
>+				   val, bytes, EFUSE_WRITE, pufflag);
> }
>
> static const struct of_device_id zynqmp_nvmem_match[] = { @@ -45,11
>+211,11 @@ static int zynqmp_nvmem_probe(struct platform_device *pdev)
> 	econfig.name = "zynqmp-nvmem";
> 	econfig.owner = THIS_MODULE;
> 	econfig.word_size = 1;
>-	econfig.size = 1;
>+	econfig.size = ZYNQMP_NVMEM_SIZE;
> 	econfig.dev = dev;
> 	econfig.add_legacy_fixed_of_cells = true;
>-	econfig.read_only = true;
> 	econfig.reg_read = zynqmp_nvmem_read;
>+	econfig.reg_write = zynqmp_nvmem_write;
>
> 	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));  }
>--
>2.37.6

Acked-by: Kalyani Akula <Kalyani.akula at amd.com>
 
Regards,
Kalyani


From deller at gmx.de  Wed Feb  7 23:02:24 2024
From: deller at gmx.de (Helge Deller)
Date: Thu, 8 Feb 2024 08:02:24 +0100
Subject: [PATCH 0/2] ARM: prctl: Reject PR_SET_MDWE where not supported
In-Reply-To: <20240208012620.32604-4-zev@bewilderbeest.net>
References: <20240208012620.32604-4-zev@bewilderbeest.net>
Message-ID: <385d72eb-2443-42e5-858d-0cc083a29a26@gmx.de>

Hi Zev,

On 2/8/24 02:26, Zev Weiss wrote:
> Hello,
>
> I noticed after a recent kernel update that my ARM926 system started
> segfaulting on any execve() after calling prctl(PR_SET_MDWE).  After
> some investigation it appears that ARMv5 is incapable of providing the
> appropriate protections for MDWE, since any readable memory is also
> implicitly executable.
>
> (Note that I'm not an expert in either ARM arch details or the mm
> subsystem, so please bear with me if I've botched something in the
> above analysis.)
>
> The prctl_set_mdwe() function already had some special-case logic
> added disabling it on PARISC (commit 793838138c15, "prctl: Disable
> prctl(PR_SET_MDWE) on parisc"); this patch series (1) generalizes that
> check to use an arch_*() function, and (2) adds a corresponding
> override for ARM to disable MDWE on pre-ARMv6 CPUs.

Instead of splitting it out to a new function in mman.h,
I'd prefer having it as config option, e.g. ARCH_HAS_NO_MDWE_SUPPORT (?)
which could be checked instead.
For parisc we still want to allow mdwe in the future, we just have
to wait until most user-space programs have updated to the latest
binaries which don't need an executable stack any longer.

> With the series applied, prctl(PR_SET_MDWE) is rejected on ARMv5 and
> subsequent execve() calls (as well as mmap(PROT_READ|PROT_WRITE)) can
> succeed instead of unconditionally failing; on ARMv6 the prctl works
> as it did previously.
>
> Since this was effectively a userspace-breaking change in v6.3 (with
> newer MDWE-aware userspace on older pre-MDWE kernels the prctl would
> simply fail safely) I've CCed -stable for v6.3+, though since the
> patches depend on the PARISC one above it will only apply cleanly on
> the linux-6.6.y and linux-6.7.y branches, since at least at time of
> writing the 6.3 through 6.5 branches don't have that patch backported
> (due to further missing dependencies [0]).
> [0] https://lore.kernel.org/all/2023112456-linked-nape-bf19 at gregkh/

I think you don't need to worry about that, since stable kernel series
for 6.3 up to 6.5 were stopped...

> Zev Weiss (2):
>    prctl: Generalize PR_SET_MDWE support check to be per-arch
>    ARM: prctl: Reject PR_SET_MDWE on pre-ARMv6
>
>   arch/arm/include/asm/mman.h    | 14 ++++++++++++++
>   arch/parisc/include/asm/mman.h | 14 ++++++++++++++
>   include/linux/mman.h           |  8 ++++++++
>   kernel/sys.c                   |  7 +++++--
>   4 files changed, 41 insertions(+), 2 deletions(-)
>   create mode 100644 arch/arm/include/asm/mman.h
>   create mode 100644 arch/parisc/include/asm/mman.h
>



From j-luthra at ti.com  Wed Feb  7 23:22:35 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 8 Feb 2024 12:52:35 +0530
Subject: [PATCH] arm64: dts: ti: am62-phyboard-lyra: Add overlay to
 enable a GPIO fan
In-Reply-To: <033de6e2-4ca4-46bc-a0a7-e9921ed15977@phytec.de>
References: <20240207172820.478332-1-nmorrisson@phytec.com>
 <acd3c7f2-930d-46c0-9924-9775e9795fca@ti.com>
 <033de6e2-4ca4-46bc-a0a7-e9921ed15977@phytec.de>
Message-ID: <7zzhg5tgypia7nta3pz6ocu3linrfghmilnd7icdvsoupzyepp@4vbmmkh2jtc7>

Hi Wadim,

On Feb 08, 2024 at 06:57:54 +0100, Wadim Egorov wrote:
> Hi Andrew,
> 
> Am 07.02.24 um 23:20 schrieb Andrew Davis:
> > On 2/7/24 11:28 AM, Nathan Morrisson wrote:
> > > The phyBOARD-Lyra has a GPIO fan header. This overlay enables the fan
> > > header and sets the fan to turn on at 65C.
> > > 
> > > Signed-off-by: Nathan Morrisson <nmorrisson at phytec.com>
> > > ---
> > > ? arch/arm64/boot/dts/ti/Makefile?????????????? |? 1 +
> > > ? .../ti/k3-am62-phyboard-lyra-gpio-fan.dtso??? | 51 +++++++++++++++++++
> > > ? 2 files changed, 52 insertions(+)
> > > ? create mode 100644
> > > arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
> > > 
> > > diff --git a/arch/arm64/boot/dts/ti/Makefile
> > > b/arch/arm64/boot/dts/ti/Makefile
> > > index 52c1dc910308..379fb4f31a1f 100644
> > > --- a/arch/arm64/boot/dts/ti/Makefile
> > > +++ b/arch/arm64/boot/dts/ti/Makefile
> > > @@ -23,6 +23,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
> > > ? dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-mallow.dtb
> > > ? dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
> > > ? dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
> > > +dtb-$(CONFIG_ARCH_K3) += k3-am62-phyboard-lyra-gpio-fan.dtbo
> > 
> > Why not call this k3-am625-phyboard-lyra-gpio-fan.dtbo to match the
> > name of the base board it applies to better?
> 
> We are able to reuse this overlay for different SoMs (am625 and am62a) that
> are using the same carrier board (lyra).

In that case do you mind calling it k3-am62x-phyboard-*? It would match 
the existing convention we have for camera sensor overlays that can be 
applied on SK-AM62, SK-AM62A, SK-AM62P etc.
> 
> Regards,
> Wadim
> 
> 
> > 
> > Andrew
> > 
> > > ? ? # Boards with AM62Ax SoC
> > > ? dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
> > > diff --git
> > > a/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
> > > b/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
> > > new file mode 100644
> > > index 000000000000..9c05748bdd9d
> > > --- /dev/null
> > > +++ b/arch/arm64/boot/dts/ti/k3-am62-phyboard-lyra-gpio-fan.dtso
> > > @@ -0,0 +1,51 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> > > +/*
> > > + * Copyright (C) 2024 PHYTEC America LLC
> > > + * Author: Garrett Giordano <ggiordano at phytec.com>
> > > + */
> > > +
> > > +/dts-v1/;
> > > +/plugin/;
> > > +
> > > +#include <dt-bindings/gpio/gpio.h>
> > > +#include <dt-bindings/thermal/thermal.h>
> > > +#include "k3-pinctrl.h"
> > > +
> > > +&{/} {
> > > +??? fan: gpio-fan {
> > > +??????? compatible = "gpio-fan";
> > > +??????? gpio-fan,speed-map = <0 0 8600 1>;
> > > +??????? gpios = <&main_gpio0 40 GPIO_ACTIVE_LOW>;
> > > +??????? #cooling-cells = <2>;
> > > +??????? pinctrl-names = "default";
> > > +??????? pinctrl-0 = <&gpio_fan_pins_default>;
> > > +??????? status = "okay";
> > > +??? };
> > > +};
> > > +
> > > +&main_pmx0 {
> > > +??? gpio_fan_pins_default: gpio-fan-default-pins {
> > > +??????? pinctrl-single,pins = <
> > > +??????????? AM62X_IOPAD(0x0a4, PIN_OUTPUT, 7) /* (M22)
> > > GPMC0_DIR.GPIO0_40 */
> > > +??????? >;
> > > +??? };
> > > +};
> > > +
> > > +&thermal_zones {
> > > +??? main0_thermal: main0-thermal {
> > > +??????? trips {
> > > +??????????? main0_thermal_trip0: main0-thermal-trip {
> > > +??????????????? temperature = <65000>;? /* millicelsius */
> > > +??????????????? hysteresis = <2000>;??? /* millicelsius */
> > > +??????????????? type = "active";
> > > +??????????? };
> > > +??????? };
> > > +
> > > +??????? cooling-maps {
> > > +??????????? map0 {
> > > +??????????????? trip = <&main0_thermal_trip0>;
> > > +??????????????? cooling-device = <&fan THERMAL_NO_LIMIT
> > > THERMAL_NO_LIMIT>;
> > > +??????????? };
> > > +??????? };
> > > +??? };
> > > +};
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240208/4aad205c/attachment.sig>

From krzysztof.kozlowski at linaro.org  Wed Feb  7 23:29:41 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 8 Feb 2024 08:29:41 +0100
Subject: [PATCH] dt-bindings: input: atmel,captouch: convert bindings to
 YAML
In-Reply-To: <09c25824-f56b-4598-b8cc-1df992812754@microchip.com>
References: <20240207090853.188400-1-dharma.b@microchip.com>
 <982e81db-3bf9-49e9-b57f-a91612d62f5c@linaro.org>
 <09c25824-f56b-4598-b8cc-1df992812754@microchip.com>
Message-ID: <6e703599-0389-435e-b163-55e5a046a8f5@linaro.org>

On 08/02/2024 04:59, Dharma.B at microchip.com wrote:
>>> +
>>> +properties:
>>> +  compatible:
>>> +    const: atmel,captouch
>>> +
>>> +  reg:
>>> +    maxItems: 1
>>> +
>>> +  interrupts:
>>> +    maxItems: 1
>>> +
>>> +  linux,keycodes:
>>> +    minItems: 1
>>> +    maxItems: 8
>>> +
>>> +  autorepeat:
>>> +    type: boolean
>>
>> You can drop entire property, coming from input.yaml.
> 
> Sure, I will drop the 'linux,keycodes' and 'autorepeat' properties.

Why linux,keycodes? Is the size restricted in any other referenced schema?

Best regards,
Krzysztof



From zev at bewilderbeest.net  Wed Feb  7 23:42:27 2024
From: zev at bewilderbeest.net (Zev Weiss)
Date: Wed, 7 Feb 2024 23:42:27 -0800
Subject: [PATCH 0/2] ARM: prctl: Reject PR_SET_MDWE where not supported
In-Reply-To: <385d72eb-2443-42e5-858d-0cc083a29a26@gmx.de>
References: <20240208012620.32604-4-zev@bewilderbeest.net>
 <385d72eb-2443-42e5-858d-0cc083a29a26@gmx.de>
Message-ID: <aee52007-b805-40a0-976b-eee52c98099c@hatter.bewilderbeest.net>

Hi Helge,

Thanks for taking a look!

On Wed, Feb 07, 2024 at 11:02:24PM PST, Helge Deller wrote:
>Hi Zev,
>
>On 2/8/24 02:26, Zev Weiss wrote:
>>Hello,
>>
>>I noticed after a recent kernel update that my ARM926 system started
>>segfaulting on any execve() after calling prctl(PR_SET_MDWE).  After
>>some investigation it appears that ARMv5 is incapable of providing the
>>appropriate protections for MDWE, since any readable memory is also
>>implicitly executable.
>>
>>(Note that I'm not an expert in either ARM arch details or the mm
>>subsystem, so please bear with me if I've botched something in the
>>above analysis.)
>>
>>The prctl_set_mdwe() function already had some special-case logic
>>added disabling it on PARISC (commit 793838138c15, "prctl: Disable
>>prctl(PR_SET_MDWE) on parisc"); this patch series (1) generalizes that
>>check to use an arch_*() function, and (2) adds a corresponding
>>override for ARM to disable MDWE on pre-ARMv6 CPUs.
>
>Instead of splitting it out to a new function in mman.h,
>I'd prefer having it as config option, e.g. ARCH_HAS_NO_MDWE_SUPPORT (?)
>which could be checked instead.
>For parisc we still want to allow mdwe in the future, we just have
>to wait until most user-space programs have updated to the latest
>binaries which don't need an executable stack any longer.
>

I considered that, but it seems that ARM kernels at least may not know 
the answer to that question at compile-time -- see patch 2, where the 
ARM implementation does a runtime check on cpu_architecture().

>>With the series applied, prctl(PR_SET_MDWE) is rejected on ARMv5 and
>>subsequent execve() calls (as well as mmap(PROT_READ|PROT_WRITE)) can
>>succeed instead of unconditionally failing; on ARMv6 the prctl works
>>as it did previously.
>>
>>Since this was effectively a userspace-breaking change in v6.3 (with
>>newer MDWE-aware userspace on older pre-MDWE kernels the prctl would
>>simply fail safely) I've CCed -stable for v6.3+, though since the
>>patches depend on the PARISC one above it will only apply cleanly on
>>the linux-6.6.y and linux-6.7.y branches, since at least at time of
>>writing the 6.3 through 6.5 branches don't have that patch backported
>>(due to further missing dependencies [0]).
>>[0] https://lore.kernel.org/all/2023112456-linked-nape-bf19 at gregkh/
>
>I think you don't need to worry about that, since stable kernel series
>for 6.3 up to 6.5 were stopped...
>

Ah, hadn't realized that -- thanks for the tip.


Zev



From heiko at sntech.de  Thu Feb  8 00:00:30 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 08 Feb 2024 09:00:30 +0100
Subject: [PATCH v2 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver
In-Reply-To: <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>
References: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
 <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>
Message-ID: <2670318.X9hSmTKtgW@diego>

Am Montag, 5. Februar 2024, 12:24:25 CET schrieb Cristian Ciocaltea:
> Add driver for the HDMI/eDP TX Combo PHY found on Rockchip RK3588 SoC.
> 
> The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
> and eDP links.  The maximum data rate is 12Gbps (FRL), while the minimum
> is 250Mbps (TMDS).
> 
> Only the TMDS link is currently supported.
> 
> Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
> Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>

on a rk3588-jaguar
Tested-by: Heiko Stuebner <heiko at sntech.de>




From krzysztof.kozlowski at linaro.org  Thu Feb  8 00:08:29 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 08 Feb 2024 09:08:29 +0100
Subject: (subset) [PATCH v3 5/7] arm64: dts: exynos: gs101: enable
 cmu-peric1 clock controller
In-Reply-To: <20240201161258.1013664-6-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
 <20240201161258.1013664-6-andre.draszik@linaro.org>
Message-ID: <170737970922.52344.8745596407204525515.b4-ty@linaro.org>


On Thu, 01 Feb 2024 16:11:41 +0000, Andr? Draszik wrote:
> Enable the cmu-peric1 clock controller. It feeds additional USI, I3C
> and PWM interfaces / busses.
> 
> Note that &sysreg_peric1 needs a clock to be able to access its
> registers and now that Linux knows about this clock, we need to add it
> in this commit as well so as to keep &sysreg_peric1 working, so that
> the clock can be enabled as and when needed.
> 
> [...]

Applied, thanks!

[5/7] arm64: dts: exynos: gs101: enable cmu-peric1 clock controller
      https://git.kernel.org/krzk/linux/c/7d66d98b5bf376a999df13c65bbc0aac3cc9de02

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Thu Feb  8 00:08:35 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 08 Feb 2024 09:08:35 +0100
Subject: (subset) [PATCH v3 6/7] arm64: dts: exynos: gs101: define
 USI12 with I2C configuration
In-Reply-To: <20240201161258.1013664-7-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
 <20240201161258.1013664-7-andre.draszik@linaro.org>
Message-ID: <170737971569.52344.5797056301424786699.b4-ty@linaro.org>


On Thu, 01 Feb 2024 16:11:42 +0000, Andr? Draszik wrote:
> On the gs101-oriole board, i2c bus 12 has various USB-related
> controllers attached to it.
> 
> Note the selection of the USI protocol is intentionally left for the
> board dts file.
> 
> 
> [...]

Applied, thanks!

[6/7] arm64: dts: exynos: gs101: define USI12 with I2C configuration
      https://git.kernel.org/krzk/linux/c/118261df42496241713cf8190535e9c90e7011f0

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Thu Feb  8 00:08:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 08 Feb 2024 09:08:38 +0100
Subject: (subset) [PATCH v3 7/7] arm64: dts: exynos: gs101: enable i2c
 bus 12 on gs101-oriole
In-Reply-To: <20240201161258.1013664-8-andre.draszik@linaro.org>
References: <20240201161258.1013664-1-andre.draszik@linaro.org>
 <20240201161258.1013664-8-andre.draszik@linaro.org>
Message-ID: <170737971829.52344.1899996118843728800.b4-ty@linaro.org>


On Thu, 01 Feb 2024 16:11:43 +0000, Andr? Draszik wrote:
> This bus has three USB-related devices attached to it:
>     0x25: Maxim 77759 Type-C port controller
>     0x35: Maxim 20339EWB Surge protection IC
>     0x36: Maxim 77759 Fuel gauge
>     0x57: NXP PCA9468 Battery charger
>     0x66: Maxim 77759 PMIC
>     0x69: Maxim 77759 Charger
> where the Maxim 77759 has multiple i2c slave addresses.
> 
> [...]

Applied, thanks!

[7/7] arm64: dts: exynos: gs101: enable i2c bus 12 on gs101-oriole
      https://git.kernel.org/krzk/linux/c/f9555ac036e253ca99a4d6d55e7e9402b77df77d

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Thu Feb  8 00:08:40 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 08 Feb 2024 09:08:40 +0100
Subject: [PATCH] arm64: dts: exynos: gs101: add stable i2c aliases for
 gs101-oriole
In-Reply-To: <20240130233700.2287442-1-andre.draszik@linaro.org>
References: <20240130233700.2287442-1-andre.draszik@linaro.org>
Message-ID: <170737972037.52344.9107022607101399076.b4-ty@linaro.org>


On Tue, 30 Jan 2024 23:37:00 +0000, Andr? Draszik wrote:
> Now that we have more than i2c interface, add aliases to ensure
> deterministic bus number assignment.
> 
> So as to keep compatibility with existing Pixel userspace builds, use
> the same bus numbers for hsi2c_8 and hsi2c_12 as the downstream
> drivers with the intention to eventually add all the earlier busses as
> well.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: exynos: gs101: add stable i2c aliases for gs101-oriole
      https://git.kernel.org/krzk/linux/c/72ccd925dcbd2ad6935a4874679b6cf5b3de7156

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From eichest at gmail.com  Thu Feb  8 00:14:13 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Thu,  8 Feb 2024 09:14:13 +0100
Subject: [PATCH v2] arm64: dts: armada-ap807: update thermal compatible
Message-ID: <20240208081413.7923-1-eichest@gmail.com>

From: Alex Leibovich <alexl at marvell.com>

Use the correct thermal coefficients for the Armada AP807 dies.

Signed-off-by: Alex Leibovich <alexl at marvell.com>
Reviewed-by: Stefan Chulski <stefanc at marvell.com>
Tested-by: Stefan Chulski <stefanc at marvell.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Stefan Eichenberger <eichest at gmail.com>
---
Changes in v2:
- Added me as last signed-off-by
- Besides that it is the third patch of this series:
https://lore.kernel.org/all/ZIxMYXDCTB7IvsDk at shell.armlinux.org.uk/
- The first two patches in the series are already applied
---
 arch/arm64/boot/dts/marvell/armada-ap807.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
index 4a23f65d475f..a3328d05fc94 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
@@ -33,3 +33,6 @@ &ap_sdhci0 {
 		     "marvell,armada-ap806-sdhci"; /* Backward compatibility */
 };
 
+&ap_thermal {
+	compatible = "marvell,armada-ap807-thermal";
+};
-- 
2.40.1



From Dharma.B at microchip.com  Thu Feb  8 00:36:08 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Thu, 8 Feb 2024 08:36:08 +0000
Subject: [PATCH] dt-bindings: input: atmel,captouch: convert bindings to
 YAML
In-Reply-To: <6e703599-0389-435e-b163-55e5a046a8f5@linaro.org>
References: <20240207090853.188400-1-dharma.b@microchip.com>
 <982e81db-3bf9-49e9-b57f-a91612d62f5c@linaro.org>
 <09c25824-f56b-4598-b8cc-1df992812754@microchip.com>
 <6e703599-0389-435e-b163-55e5a046a8f5@linaro.org>
Message-ID: <070f94b5-afe9-4098-8a6c-ae98104f94bb@microchip.com>

Hi Krzysztof,

On 08/02/24 12:59 pm, Krzysztof Kozlowski wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On 08/02/2024 04:59, Dharma.B at microchip.com wrote:
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    const: atmel,captouch
>>>> +
>>>> +  reg:
>>>> +    maxItems: 1
>>>> +
>>>> +  interrupts:
>>>> +    maxItems: 1
>>>> +
>>>> +  linux,keycodes:
>>>> +    minItems: 1
>>>> +    maxItems: 8
>>>> +
>>>> +  autorepeat:
>>>> +    type: boolean
>>>
>>> You can drop entire property, coming from input.yaml.
>>
>> Sure, I will drop the 'linux,keycodes' and 'autorepeat' properties.
> 
> Why linux,keycodes? Is the size restricted in any other referenced schema?

Sorry, I misinterpreted the statement "entire property(ies) coming from 
input.yaml".

The linux,keycodes size should be restricted to maxitems 8 here.

I will drop only the optional property "autorepeat".

Thanks.

> 
> Best regards,
> Krzysztof
> 

-- 
With Best Regards,
Dharma B.


From krzysztof.kozlowski at linaro.org  Thu Feb  8 00:38:36 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 8 Feb 2024 09:38:36 +0100
Subject: [PATCH v3 16/20] dt-bindings: crypto: meson: support new SoC's
In-Reply-To: <20240205155521.1795552-17-avromanov@salutedevices.com>
References: <20240205155521.1795552-1-avromanov@salutedevices.com>
 <20240205155521.1795552-17-avromanov@salutedevices.com>
Message-ID: <b2e4ac25-5b07-46c7-a96f-8390a95584ea@linaro.org>

On 05/02/2024 16:55, Alexey Romanov wrote:
> Now crypto module available at G12A/G12B/S4/A1/SM1/AXG.
> 
> 1. Add new compatibles:
>   - amlogic,g12a-crypto
>   - amlogic,s4-crypto (uses g12a-crypto as fallback)
>   - amlogic,a1-crypto (uses g12a-crypto as fallback)
>   - amlogic,axg-crypto
> 
> 2. All SoC's, exclude GXL, doesn't take a clock input for
> Crypto IP. Make it required only for amlogic,gxl-crypto.
> 
> 3. All SoC's, exclude GXL, uses only one interrupt flow
> for Crypto IP.
> 
> 4. Add power-domains in schema.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>  .../bindings/crypto/amlogic,gxl-crypto.yaml   | 44 +++++++++++++++----
>  1 file changed, 36 insertions(+), 8 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
> index 948e11ebe4ee..62f772036b06 100644
> --- a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
> +++ b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
> @@ -11,20 +11,30 @@ maintainers:
>  
>  properties:
>    compatible:
> -    items:
> -      - const: amlogic,gxl-crypto
> +    oneOf:
> +      - items:
> +          - enum:
> +              - amlogic,a1-crypto
> +              - amlogic,s4-crypto
> +          - const: amlogic,g12a-crypto
> +      - items:
> +          - const: amlogic,gxl-crypto
> +      - items:
> +          - const: amlogic,axg-crypto
> +      - items:
> +          - const: amlogic,g12a-crypto

You just ignored my comment, so repeat: that's just enum with three entries.

>  
>    reg:
>      maxItems: 1
>  
> -  interrupts:
> -    items:
> -      - description: Interrupt for flow 0
> -      - description: Interrupt for flow 1
> +  interrupts: true

No, you need widest constraints here.

>  
>    clocks:
>      maxItems: 1
>  
> +  power-domains:
> +    maxItems: 1
> +
>    clock-names:
>      const: blkmv
>  
> @@ -32,8 +42,26 @@ required:
>    - compatible
>    - reg
>    - interrupts
> -  - clocks
> -  - clock-names
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: amlogic,gxl-crypto
> +    then:
> +      required:
> +        - clocks
> +        - clock-names
> +      properties:
> +        interrupts:
> +          maxItems: 2
> +          minItems: 2

Instead describe items like it was in original code.

> +    else:
> +      properties:
> +        interrupts:
> +          maxItems: 1
> +          minItems: 1

and what interrupt is expected here?

>  
>  additionalProperties: false
>  

Best regards,
Krzysztof



From vaishnav.a at ti.com  Thu Feb  8 00:42:47 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:12:47 +0530
Subject: [PATCH v2 2/9] arm64: dts: ti: k3-j784s4-evm: Enable camera peripherals
In-Reply-To: <20240208084254.295289-1-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
Message-ID: <20240208084254.295289-3-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On J784S4 EVM, this is routed
to I2C-5, so enable the instance and the TCA6408 GPIO expander
on the bus.

J784S4 EVM schematics: https://www.ti.com/lit/zip/sprr458

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with schematics.

 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 25 ++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
index 57e7cb8ea2b8..bb2558b68381 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -297,6 +297,13 @@ J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */
 		>;
 	};
 
+	main_i2c5_pins_default: main-i2c5-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x01c, PIN_INPUT, 8) /* (AG34) MCAN15_TX.I2C5_SCL */
+			J784S4_IOPAD(0x018, PIN_INPUT, 8) /* (AK36) MCAN14_RX.I2C5_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
@@ -761,6 +768,24 @@ exp2: gpio at 22 {
 	};
 };
 
+&main_i2c5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c5_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	exp5: gpio at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI2_EXP_RSTZ", "CSI2_EXP_A_GPIO0",
+				  "CSI2_EXP_A_GPIO1", "CSI2_EXP_A_GPIO3",
+				  "CSI2_EXP_B_GPIO1", "CSI2_EXP_B_GPIO2",
+				  "CSI2_EXP_B_GPIO3", "CSI2_EXP_B_GPIO4";
+	};
+};
+
 &main_sdhci0 {
 	bootph-all;
 	/* eMMC */
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 00:42:46 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:12:46 +0530
Subject: [PATCH v2 1/9] arm64: dts: ti: k3-j721s2-common-proc-board: Enable camera peripherals
In-Reply-To: <20240208084254.295289-1-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
Message-ID: <20240208084254.295289-2-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On J721S2 Common Processor Board,
this is routed to I2C-5, so enable the instance and the TCA6408
GPIO expander on the bus.

Common Processor Board schematics: https://www.ti.com/lit/zip/sprr411
J721S2 SoM schematics: https://www.ti.com/lit/zip/sprr439

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with schematics.

 .../dts/ti/k3-j721s2-common-proc-board.dts    | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
index 361365bb5523..5631735c9b7a 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -147,6 +147,13 @@ J721S2_IOPAD(0x060, PIN_INPUT_PULLUP, 13) /* (AC27) MCASP2_AXR1.I2C3_SDA */
 		>;
 	};
 
+	main_i2c5_pins_default: main-i2c5-default-pins {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x01c, PIN_INPUT, 8) /* (Y24) MCAN15_TX.I2C5_SCL */
+			J721S2_IOPAD(0x018, PIN_INPUT, 8) /* (W23) MCAN14_RX.I2C5_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		pinctrl-single,pins = <
 			J721S2_IOPAD(0x104, PIN_INPUT, 0) /* (P23) MMC1_CLK */
@@ -356,6 +363,24 @@ exp2: gpio at 22 {
 	};
 };
 
+&main_i2c5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c5_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	exp5: gpio at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI2_EXP_RSTZ", "CSI2_EXP_A_GPIO0",
+				  "CSI2_EXP_A_GPIO1", "CSI2_EXP_A_GPIO2",
+				  "CSI2_EXP_B_GPIO1", "CSI2_EXP_B_GPIO2",
+				  "CSI2_EXP_B_GPIO3", "CSI2_EXP_B_GPIO4";
+	};
+};
+
 &main_sdhci0 {
 	/* eMMC */
 	status = "okay";
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 00:42:50 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:12:50 +0530
Subject: [PATCH v2 5/9] arm64: dts: ti: k3-j721e-sk: Model CSI2RX connector mux
In-Reply-To: <20240208084254.295289-1-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
Message-ID: <20240208084254.295289-6-vaishnav.a@ti.com>

J721E SK has the CSI2RX routed to a MIPI CSI connector and to 15-pin
RPi camera connector through an analog mux with GPIO control, model that
so that an overlay can control the mux state according to connected
cameras. Also provide labels to the I2C mux bus instances so that a
generic overlay can be used across multiple platforms.

J721E SK schematics: https://www.ti.com/lit/zip/sprr438

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with schematics.

 arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
index 6950b1ff124f..5dbc85bc5038 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
@@ -286,6 +286,15 @@ tfp410_out: endpoint {
 			};
 		};
 	};
+
+	csi_mux: mux-controller {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&main_gpio0 88 GPIO_ACTIVE_HIGH>;
+		idle-state = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_csi_mux_sel_pins_default>;
+	};
 };
 
 &main_pmx0 {
@@ -352,6 +361,12 @@ J721E_IOPAD(0x214, PIN_OUTPUT, 4) /* (V4) MCAN1_TX.USB1_DRVVBUS */
 		>;
 	};
 
+	main_csi_mux_sel_pins_default: main-csi-mux-sel-default-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x164, PIN_OUTPUT, 7) /* (V29) RGMII5_TD2 */
+		>;
+	};
+
 	dp0_pins_default: dp0-default-pins {
 		pinctrl-single,pins = <
 			J721E_IOPAD(0x1c4, PIN_INPUT, 5) /* SPI0_CS1.DP0_HPD */
@@ -858,14 +873,14 @@ i2c-mux at 70 {
 		reg = <0x70>;
 
 		/* CSI0 I2C */
-		i2c at 0 {
+		cam0_i2c: i2c at 0 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0>;
 		};
 
 		/* CSI1 I2C */
-		i2c at 1 {
+		cam1_i2c: i2c at 1 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <1>;
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 00:42:49 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:12:49 +0530
Subject: [PATCH v2 4/9] arm64: dts: ti: k3-am69-sk: Enable camera peripherals
In-Reply-To: <20240208084254.295289-1-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
Message-ID: <20240208084254.295289-5-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On AM69 Starter Kit, this is routed
to I2C-1, so enable the instance, TCA9543 I2C switch and the TCA6408
GPIO expander on the bus. AM69 SK has the CSI2RX routed to a MIPI CSI
connector and to 22-pin RPi camera connector through an analog mux with
GPIO control, model that so that an overlay can control the mux state
according to connected cameras.

AM69 SK schematics: https://www.ti.com/lit/zip/sprr466

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with schematics.

 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 51 +++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 5f0a43a69333..46cf90bb3eb8 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -322,6 +322,14 @@ tfp410_out: endpoint {
 			};
 		};
 	};
+
+	csi_mux: mux-controller {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&exp2 1 GPIO_ACTIVE_HIGH>;
+		idle-state = <0>;
+	};
+
 };
 
 &main_pmx0 {
@@ -341,6 +349,13 @@ J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */
 		>;
 	};
 
+	main_i2c1_pins_default: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0ac, PIN_INPUT_PULLUP, 13) /* (AE34) MCASP0_AXR15.I2C1_SCL */
+			J784S4_IOPAD(0x0b0, PIN_INPUT_PULLUP, 13) /* (AL33) MCASP1_AXR3.I2C1_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
@@ -775,6 +790,42 @@ exp1: gpio at 21 {
 	};
 };
 
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	exp2: gpio at 21 {
+		compatible = "ti,tca6408";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI_VIO_SEL", "CSI_MUX_SEL_2", "CSI2_RSTz",
+				  "IO_EXP_CAM0_GPIO1", "IO_EXP_CAM1_GPIO1";
+	};
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		cam0_i2c: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		cam1_i2c: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+	};
+};
+
 &main_sdhci0 {
 	bootph-all;
 	/* eMMC */
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 00:42:51 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:12:51 +0530
Subject: [PATCH v2 6/9] arm64: dts: ti: k3-j721e-main: Add CSI2RX capture nodes
In-Reply-To: <20240208084254.295289-1-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
Message-ID: <20240208084254.295289-7-vaishnav.a@ti.com>

J721E has two CSI2RX capture subsystem featuring Cadence CSI2RX,
DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
keep them disabled by default.

J721E TRM (Section 12.7 Camera Subsystem):
	https://www.ti.com/lit/zip/spruil1

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with TRM.

 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 122 ++++++++++++++++++++++
 1 file changed, 122 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index 062a6fca5a31..8df1eed80996 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -572,6 +572,128 @@ main_timerio_output: pinctrl at 104280 {
 		pinctrl-single,function-mask = <0x0000001f>;
 	};
 
+	ti_csi2rx0: ticsi2rx at 4500000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		dmas = <&main_udmap 0x4940>;
+		dma-names = "rx0";
+		reg = <0x0 0x4500000 0x0 0x1000>;
+		power-domains = <&k3_pds 26 TI_SCI_PD_EXCLUSIVE>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 4504000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x0 0x4504000 0x0 0x1000>;
+			clocks = <&k3_clks 26 2>, <&k3_clks 26 0>, <&k3_clks 26 2>,
+				<&k3_clks 26 2>, <&k3_clks 26 3>, <&k3_clks 26 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx1: ticsi2rx at 4510000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		dmas = <&main_udmap 0x4960>;
+		dma-names = "rx0";
+		reg = <0x0 0x4510000 0x0 0x1000>;
+		power-domains = <&k3_pds 27 TI_SCI_PD_EXCLUSIVE>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		cdns_csi2rx1: csi-bridge at 4514000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x0 0x4514000 0x0 0x1000>;
+			clocks = <&k3_clks 27 2>, <&k3_clks 27 0>, <&k3_clks 27 2>,
+				 <&k3_clks 27 2>, <&k3_clks 27 3>, <&k3_clks 27 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				      "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy1>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi1_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi1_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi1_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi1_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi1_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 4580000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x0 0x4580000 0x0 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy1: phy at 4590000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x0 0x4590000 0x0 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 148 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
 	serdes_wiz0: wiz at 5000000 {
 		compatible = "ti,j721e-wiz-16g";
 		#address-cells = <1>;
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 00:42:52 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:12:52 +0530
Subject: [PATCH v2 7/9] arm64: dts: ti: k3-j721s2-main: Add CSI2RX capture nodes
In-Reply-To: <20240208084254.295289-1-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
Message-ID: <20240208084254.295289-8-vaishnav.a@ti.com>

J721S2 has two CSI2RX capture subsystem featuring Cadence CSI2RX,
DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
keep them disabled by default. J721S2 uses a dedicated BCDMA instance
for CSI-RX traffic, so enable that as well.

J721S2 TRM (Section 12.7 Camera Subsystem):
	https://www.ti.com/lit/zip/spruj28

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with TRM.

 arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi | 123 ++++++++++++++++++++-
 1 file changed, 122 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
index dcaa4da0d678..a401e84a2eb2 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -1122,7 +1122,6 @@ main_bcdma_csi: dma-controller at 311a0000 {
 			ti,sci-dev-id = <225>;
 			ti,sci-rm-range-rchan = <0x21>;
 			ti,sci-rm-range-tchan = <0x22>;
-			status = "disabled";
 		};
 
 		cpts at 310d0000 {
@@ -1233,6 +1232,128 @@ usb0: usb at 6000000 {
 		};
 	};
 
+	ti_csi2rx0: ticsi2rx at 4500000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		dmas = <&main_bcdma_csi 0 0x4940 0>;
+		dma-names = "rx0";
+		reg = <0x00 0x04500000 0x00 0x1000>;
+		power-domains = <&k3_pds 38 TI_SCI_PD_EXCLUSIVE>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 4504000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04504000 0x00 0x1000>;
+			clocks = <&k3_clks 38 3>, <&k3_clks 38 1>, <&k3_clks 38 3>,
+				<&k3_clks 38 3>, <&k3_clks 38 4>, <&k3_clks 38 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx1: ticsi2rx at 4510000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		dmas = <&main_bcdma_csi 0 0x4960 0>;
+		dma-names = "rx0";
+		reg = <0x00 0x04510000 0x00 0x1000>;
+		power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		cdns_csi2rx1: csi-bridge at 4514000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04514000 0x00 0x1000>;
+			clocks = <&k3_clks 39 3>, <&k3_clks 39 1>, <&k3_clks 39 3>,
+				<&k3_clks 39 3>, <&k3_clks 39 4>, <&k3_clks 39 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy1>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi1_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi1_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi1_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi1_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi1_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 4580000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04580000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy1: phy at 4590000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04590000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
 	serdes_wiz0: wiz at 5060000 {
 		compatible = "ti,j721s2-wiz-10g";
 		#address-cells = <1>;
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 00:42:45 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:12:45 +0530
Subject: [PATCH v2 0/9] Add CSI2RX capture support on TI J7 platforms
Message-ID: <20240208084254.295289-1-vaishnav.a@ti.com>

Hi,

This series adds support for CSI2RX capture support on J7 platforms,
series was tested for CSI2RX capture on OV5640 sensor and RPI camera
v2 IMX219 sensor on J721e Common Processor Board, J721E Starter kit,
J721S2 Common Processor Board, AM68 Starter Kit, J784s4 EVM and AM69
Starter kit.

V1: https://lore.kernel.org/all/20240129132742.1189783-1-vaishnav.a at ti.com/

Changelog:

V1->V2:
  * Address feedback from Jai and Andrew
    * Rename overlays to indicate first platform supported/dual camera.
    * Add missed build test.
    * Add board schematics for all commit messages.


Test logs:
J721E EVM OV5640 - https://gist.github.com/vaishnavachath/b08521386cfbe1939facf39b8b2d796b
J721S2 EVM OV5640 - https://gist.github.com/vaishnavachath/1b0d60da6b6464cf12334cd5e161a79b
J784s4 EVM OV5640 - https://gist.github.com/vaishnavachath/02b70df94d2d41662eff99f4ce966d67
TDA4VM SK IMX219 - https://gist.github.com/vaishnavachath/64fc6edd6cc060027812bebd6573df07
AM68 SK IMX219 - https://gist.github.com/vaishnavachath/d522254ff5e797bc853e0706fbea932a
AM69 SK IMX219 - https://gist.github.com/vaishnavachath/8dbd960cc89d691886df371c53aac399

Only a single set of overlays for dual RPI IMX219 is included in the series
for reference and other overlays to test OV5640 can be found here:
https://gist.github.com/vaishnavachath/d0a052106892fe9f3096733931e9ad5f

Vaishnav Achath (9):
  arm64: dts: ti: k3-j721s2-common-proc-board: Enable camera peripherals
  arm64: dts: ti: k3-j784s4-evm: Enable camera peripherals
  arm64: dts: ti: k3-am68-sk-base-board: Enable camera peripherals
  arm64: dts: ti: k3-am69-sk: Enable camera peripherals
  arm64: dts: ti: k3-j721e-sk: Model CSI2RX connector mux
  arm64: dts: ti: k3-j721e-main: Add CSI2RX capture nodes
  arm64: dts: ti: k3-j721s2-main: Add CSI2RX capture nodes
  arm64: dts: ti: k3-j784s4-main: Add CSI2RX capture nodes
  arm64: dts: ti: k3-j721e-sk: Add overlay for IMX219

 arch/arm64/boot/dts/ti/Makefile               |  13 ++
 .../boot/dts/ti/k3-am68-sk-base-board.dts     |  50 +++++
 arch/arm64/boot/dts/ti/k3-am69-sk.dts         |  51 +++++
 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi     | 122 ++++++++++++
 .../dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso  | 125 ++++++++++++
 arch/arm64/boot/dts/ti/k3-j721e-sk.dts        |  19 +-
 .../dts/ti/k3-j721s2-common-proc-board.dts    |  25 +++
 arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi    | 123 +++++++++++-
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts      |  25 +++
 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi    | 183 +++++++++++++++++-
 10 files changed, 732 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso

-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 00:42:48 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:12:48 +0530
Subject: [PATCH v2 3/9] arm64: dts: ti: k3-am68-sk-base-board: Enable camera peripherals
In-Reply-To: <20240208084254.295289-1-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
Message-ID: <20240208084254.295289-4-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On AM68 Starter Kit, this is routed
to I2C-1, so enable the instance and the TCA9543 I2C switch on the bus.

AM68 SK schematics: https://www.ti.com/lit/zip/sprr463

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with schematics.

 .../boot/dts/ti/k3-am68-sk-base-board.dts     | 50 +++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
index f48155dd16a3..d743f023cdd9 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
@@ -169,6 +169,13 @@ tfp410_out: endpoint {
 			};
 		};
 	};
+
+	csi_mux: mux-controller {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&exp3 1 GPIO_ACTIVE_HIGH>;
+		idle-state = <0>;
+	};
 };
 
 &main_pmx0 {
@@ -186,6 +193,13 @@ J721S2_IOPAD(0x0e4, PIN_INPUT, 0) /* (AE24) I2C0_SDA */
 		>;
 	};
 
+	main_i2c1_pins_default: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x0ac, PIN_INPUT, 13) /* (AC25) MCASP0_AXR15.I2C1_SCL */
+			J721S2_IOPAD(0x0b0, PIN_INPUT, 13) /* (AD26) MCASP1_AXR3.I2C1_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		pinctrl-single,pins = <
 			J721S2_IOPAD(0x104, PIN_INPUT, 0) /* (P23) MMC1_CLK */
@@ -431,6 +445,42 @@ exp1: gpio at 21 {
 	};
 };
 
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	status = "okay";
+
+	exp3: gpio at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI_VIO_SEL", "CSI_SEL_FPC_EXPn",
+				  "IO_EXP_CSI2_EXP_RSTz","CSI0_B_GPIO1",
+				  "CSI1_B_GPIO1";
+	};
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		cam0_i2c: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		cam1_i2c: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+	};
+};
+
 &main_i2c4 {
 	status = "okay";
 	pinctrl-names = "default";
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 00:42:53 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:12:53 +0530
Subject: [PATCH v2 8/9] arm64: dts: ti: k3-j784s4-main: Add CSI2RX capture nodes
In-Reply-To: <20240208084254.295289-1-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
Message-ID: <20240208084254.295289-9-vaishnav.a@ti.com>

J784S4 has three CSI2RX capture subsystem featuring Cadence CSI2RX,
DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
keep them disabled by default. J784S4 uses a dedicated BCDMA instance
for CSI-RX traffic, so enable that as well.

J784S4 TRM (Section 12.7 Camera Subsystem):
	https://www.ti.com/lit/zip/spruj52

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with TRM.

 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 183 ++++++++++++++++++++-
 1 file changed, 182 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
index 3cb964982792..e3820ee52dbb 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -662,6 +662,188 @@ main_i2c6: i2c at 2060000 {
 		status = "disabled";
 	};
 
+	ti_csi2rx0: ticsi2rx at 4500000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		dmas = <&main_bcdma_csi 0 0x4940 0>;
+		dma-names = "rx0";
+		reg = <0x00 0x04500000 0x00 0x00001000>;
+		power-domains = <&k3_pds 72 TI_SCI_PD_EXCLUSIVE>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 4504000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04504000 0x00 0x00001000>;
+			clocks = <&k3_clks 72 2>, <&k3_clks 72 0>, <&k3_clks 72 2>,
+				<&k3_clks 72 2>, <&k3_clks 72 3>, <&k3_clks 72 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx1: ticsi2rx at 4510000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		dmas = <&main_bcdma_csi 0 0x4960 0>;
+		dma-names = "rx0";
+		reg = <0x00 0x04510000 0x00 0x1000>;
+		power-domains = <&k3_pds 73 TI_SCI_PD_EXCLUSIVE>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		cdns_csi2rx1: csi-bridge at 4514000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04514000 0x00 0x00001000>;
+			clocks = <&k3_clks 73 2>, <&k3_clks 73 0>, <&k3_clks 73 2>,
+				<&k3_clks 73 2>, <&k3_clks 73 3>, <&k3_clks 73 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy1>;
+			phy-names = "dphy";
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi1_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi1_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi1_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi1_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi1_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx2: ticsi2rx at 4520000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		dmas = <&main_bcdma_csi 0 0x4980 0>;
+		dma-names = "rx0";
+		reg = <0x00 0x04520000 0x00 0x00001000>;
+		power-domains = <&k3_pds 74 TI_SCI_PD_EXCLUSIVE>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		cdns_csi2rx2: csi-bridge at 4524000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04524000 0x00 0x00001000>;
+			clocks = <&k3_clks 74 2>, <&k3_clks 74 0>, <&k3_clks 74 2>,
+				<&k3_clks 74 2>, <&k3_clks 74 3>, <&k3_clks 74 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy2>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi2_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi2_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi2_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi2_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi2_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 4580000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04580000 0x00 0x00001100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 212 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy1: phy at 4590000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04590000 0x00 0x00001100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 213 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy2: phy at 45a0000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x045a0000 0x00 0x00001100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 214 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
 	main_sdhci0: mmc at 4f80000 {
 		compatible = "ti,j721e-sdhci-8bit";
 		reg = <0x00 0x04f80000 0x00 0x1000>,
@@ -1224,7 +1406,6 @@ main_bcdma_csi: dma-controller at 311a0000 {
 			ti,sci-dev-id = <281>;
 			ti,sci-rm-range-rchan = <0x21>;
 			ti,sci-rm-range-tchan = <0x22>;
-			status = "disabled";
 		};
 
 		cpts at 310d0000 {
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 00:42:54 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:12:54 +0530
Subject: [PATCH v2 9/9] arm64: dts: ti: k3-j721e-sk: Add overlay for IMX219
In-Reply-To: <20240208084254.295289-1-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
Message-ID: <20240208084254.295289-10-vaishnav.a@ti.com>

RPi v2 Camera (IMX219) is an 8MP camera that can be used with SK-AM69,
J721E SK, and AM68 SK through the 22-pin CSI-RX connector.

Add a reference overlay for dual IMX219 RPI camera v2 modules
which can be used across AM68 SK, AM69 SK, TDA4VM SK boards
that have a 15/22-pin FFC connector. Also enable build testing
and symbols for all the three platforms.

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2:
 * Rename overlays to indicate first platform (j721e-sk) supported
   and dual camera.
 * Add missed build test, fix missing newline.

 arch/arm64/boot/dts/ti/Makefile               |  13 ++
 .../dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso  | 125 ++++++++++++++++++
 2 files changed, 138 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 4a570dffb638..e019efd3ce94 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -69,6 +69,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi-exp-board.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-dual-imx219.dtbo
 
 # Boards with J721s2 SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board.dtb
@@ -106,8 +107,14 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
+k3-am68-sk-base-board-csi2-dual-imx219-dtbs := k3-am68-sk-base-board.dtb \
+	k3-j721e-sk-csi2-dual-imx219.dtbo
+k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
+	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
 	k3-j721e-evm-pcie0-ep.dtbo
+k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
+	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
 	k3-j721s2-evm-pcie1-ep.dtbo
 dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
@@ -122,7 +129,10 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am62a7-sk-hdmi-audio.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
+	k3-am68-sk-base-board-csi2-dual-imx219-dtbs \
+	k3-am69-sk-csi2-dual-imx219-dtbs \
 	k3-j721e-evm-pcie0-ep.dtb \
+	k3-j721e-sk-csi2-dual-imx219-dtbs \
 	k3-j721s2-evm-pcie1-ep.dtb
 
 # Enable support for device-tree overlays
@@ -132,5 +142,8 @@ DTC_FLAGS_k3-am62-lp-sk += -@
 DTC_FLAGS_k3-am62a7-sk += -@
 DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
 DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
+DTC_FLAGS_k3-am68-sk-base-board += -@
+DTC_FLAGS_k3-am69-sk += -@
 DTC_FLAGS_k3-j721e-common-proc-board += -@
+DTC_FLAGS_k3-j721e-sk += -@
 DTC_FLAGS_k3-j721s2-common-proc-board += -@
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso b/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso
new file mode 100644
index 000000000000..65d7cefb6063
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for dual RPi Camera V2.1 (Sony IMX219) interfaced with CSI2
+ * on J721E SK, AM68 SK or AM69-SK board.
+ * https://datasheets.raspberrypi.org/camera/camera-v2-schematic.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	clk_imx219_fixed: imx219-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&csi_mux {
+	idle-state = <1>;
+};
+
+/* CAM0 I2C */
+&cam0_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	imx219_0: imx219_0 at 10 {
+		compatible = "sony,imx219";
+		reg = <0x10>;
+
+		clocks = <&clk_imx219_fixed>;
+		clock-names = "xclk";
+
+		port {
+			csi2_cam0: endpoint {
+				remote-endpoint = <&csi2rx0_in_sensor>;
+				link-frequencies = /bits/ 64 <456000000>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+/* CAM1 I2C */
+&cam1_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	imx219_1: imx219_1 at 10 {
+		compatible = "sony,imx219";
+		reg = <0x10>;
+
+		clocks = <&clk_imx219_fixed>;
+		clock-names = "xclk";
+
+		port {
+			csi2_cam1: endpoint {
+				remote-endpoint = <&csi2rx1_in_sensor>;
+				link-frequencies = /bits/ 64 <456000000>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port at 0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port at 0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx1_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam1>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&dphy1 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 00:53:48 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:23:48 +0530
Subject: [PATCH 9/9] arm64: dts: ti: k3-am69-sk: Add overlay for IMX219
In-Reply-To: <jzzoifrpcchpvvyy3k5xkcxveuopqdpkakv2ppv35wowvkc3uf@zlfel5wytyji>
References: <20240129132742.1189783-1-vaishnav.a@ti.com>
 <20240129132742.1189783-10-vaishnav.a@ti.com>
 <jzzoifrpcchpvvyy3k5xkcxveuopqdpkakv2ppv35wowvkc3uf@zlfel5wytyji>
Message-ID: <0a52b6eb-1fc5-4fd6-9016-72e1cb97fcc4@ti.com>

Hi Jai, Andrew,

On 31/01/24 13:45, Jai Luthra wrote:
> Hi Vaishnav,
> 
> Thanks for the patch.
> 
> On Jan 29, 2024 at 18:57:42 +0530, Vaishnav Achath wrote:
>> RPi v2 Camera (IMX219) is an 8MP camera that can be used with SK-AM69
>> through the 22-pin CSI-RX connector.
>>
>> Same overlay can be used across AM68 SK, TDA4VM SK boards that have a
>> 15/22-pin FFC connector. Also enable build testing and symbols for
>> all the three platforms.
> 
> In that case, the overlay should be named something generic following
> how it is done for SK-AM62* family of boards.
> 
> IMO, it would also make more sense to have separate overlays for CSI0
> and CSI1 ports, unless there are no usecases to plug-in different
> sensors on the board.
> 
> Even if that is done later, at least this overlay should be named in a
> way to make it clear it enables 2x IMX219 on both CSI-RX ports, to avoid
> confusion.
> 
> So, something like k3-<jacinto?>-sk-csi2-dual-imx219.dtso
> 
> This will leave room for a CSI1 only overlay to be called
> k3-<>-sk-csi2-1-<sensor>.dtso
> 


Thank you for the review, for now I have renamed the overlay to the 
first supported platform(j721e-sk), like AM62X family it is difficult
to pick a common name for these platforms (TDA4VM SK, AM68 SK, AM69 SK),
also jacinto-*.dtso gives the wrong impression that these might work 
with the EVMs, so for now I have picked the name to follow the first 
supported platfor j721e-sk and clarified in comments and commit message 
that this can be reused with other platforms.

>>
>> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
>> ---
>>   arch/arm64/boot/dts/ti/Makefile               |   6 +
>>   .../boot/dts/ti/k3-am69-sk-csi2-imx219.dtso   | 124 ++++++++++++++++++
>>   2 files changed, 130 insertions(+)
>>   create mode 100644 arch/arm64/boot/dts/ti/k3-am69-sk-csi2-imx219.dtso
>>
>> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
>> index 52c1dc910308..9fc8d68f7d26 100644
>> --- a/arch/arm64/boot/dts/ti/Makefile
>> +++ b/arch/arm64/boot/dts/ti/Makefile
>> @@ -80,6 +80,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-pcie1-ep.dtbo
>>   
>>   # Boards with J784s4 SoC
>>   dtb-$(CONFIG_ARCH_K3) += k3-am69-sk.dtb
>> +dtb-$(CONFIG_ARCH_K3) += k3-am69-sk-csi2-imx219.dtbo
>>   dtb-$(CONFIG_ARCH_K3) += k3-j784s4-evm.dtb
>>   
>>   # Build time test only, enabled by CONFIG_OF_ALL_DTBS
>> @@ -105,6 +106,8 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
>>   	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>>   k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
>>   	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
>> +k3-am69-sk-csi2-imx219-dtbs := k3-am69-sk.dtb \
>> +	k3-am69-sk-csi2-imx219.dtbo
> 
> Andrew already pointed out that the base dtb should be added in the dtb-
> += entry at the end of this section.
> 
> Along with that, I think the overlay should be build-tested for each
> base DTB (AM68, TDA4VM) it is applicable on. Same is already done for
> the shared IMX219/OV5640 overlays between SK-AM62 and SK-AM62A.
> 

Fixed in V2: 
https://lore.kernel.org/all/20240208084254.295289-1-vaishnav.a at ti.com/

Thanks and Regards,
Vaishnav

>>   k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
>>   	k3-j721e-evm-pcie0-ep.dtbo
>>   k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
>> @@ -130,5 +133,8 @@ DTC_FLAGS_k3-am62-lp-sk += -@
>>   DTC_FLAGS_k3-am62a7-sk += -@
>>   DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
>>   DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
>> +DTC_FLAGS_k3-am68-sk-base-board += -@
>> +DTC_FLAGS_k3-am69-sk += -@
>>   DTC_FLAGS_k3-j721e-common-proc-board += -@
>>   DTC_FLAGS_k3-j721s2-common-proc-board += -@
>> +DTC_FLAGS_k3-j721e-sk += -@
>> diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk-csi2-imx219.dtso b/arch/arm64/boot/dts/ti/k3-am69-sk-csi2-imx219.dtso
>> new file mode 100644
>> index 000000000000..4cd1d8d5004a
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/ti/k3-am69-sk-csi2-imx219.dtso
>> @@ -0,0 +1,124 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/**
>> + * DT Overlay for RPi Camera V2.1 (Sony IMX219) interfaced with CSI2 on AM68-SK board.
> 
> Overlay name says AM69 but comment says AM68 here.
> 
>> + * https://datasheets.raspberrypi.org/camera/camera-v2-schematic.pdf
>> + *
>> + * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
> 
> s/2023/2024
> 
>> + */
>> +
>> +/dts-v1/;
>> +/plugin/;
>> +
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include "k3-pinctrl.h"
>> +
>> +&{/} {
>> +	clk_imx219_fixed: imx219-xclk {
>> +		compatible = "fixed-clock";
>> +		#clock-cells = <0>;
>> +		clock-frequency = <24000000>;
>> +	};
>> +};
>> +
>> +&csi_mux {
>> +	idle-state = <1>;
>> +};
>> +
>> +/* CAM0 I2C */
>> +&cam0_i2c {
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
>> +	imx219_0: imx219_0 at 10 {
>> +		compatible = "sony,imx219";
>> +		reg = <0x10>;
>> +
>> +		clocks = <&clk_imx219_fixed>;
>> +		clock-names = "xclk";
>> +
>> +		port {
>> +			csi2_cam0: endpoint {
>> +				remote-endpoint = <&csi2rx0_in_sensor>;
>> +				link-frequencies = /bits/ 64 <456000000>;
>> +				clock-lanes = <0>;
>> +				data-lanes = <1 2>;
>> +			};
>> +		};
>> +	};
>> +};
>> +
>> +/* CAM1 I2C */
>> +&cam1_i2c {
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
>> +	imx219_1: imx219_1 at 10 {
>> +		compatible = "sony,imx219";
>> +		reg = <0x10>;
>> +
>> +		clocks = <&clk_imx219_fixed>;
>> +		clock-names = "xclk";
>> +
>> +		port {
>> +			csi2_cam1: endpoint {
>> +				remote-endpoint = <&csi2rx1_in_sensor>;
>> +				link-frequencies = /bits/ 64 <456000000>;
>> +				clock-lanes = <0>;
>> +				data-lanes = <1 2>;
>> +			};
>> +		};
>> +	};
>> +};
>> +
>> +
>> +&cdns_csi2rx0 {
>> +	ports {
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		csi0_port0: port at 0 {
>> +			reg = <0>;
>> +			status = "okay";
>> +
>> +			csi2rx0_in_sensor: endpoint {
>> +				remote-endpoint = <&csi2_cam0>;
>> +				bus-type = <4>; /* CSI2 DPHY. */
>> +				clock-lanes = <0>;
>> +				data-lanes = <1 2>;
>> +			};
>> +		};
>> +	};
>> +};
>> +
>> +&dphy0 {
>> +	status = "okay";
>> +};
>> +
>> +&ti_csi2rx0 {
>> +	status = "okay";
>> +};
>> +
>> +&cdns_csi2rx1 {
>> +	ports {
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		csi1_port0: port at 0 {
>> +			reg = <0>;
>> +			status = "okay";
>> +
>> +			csi2rx1_in_sensor: endpoint {
>> +				remote-endpoint = <&csi2_cam1>;
>> +				bus-type = <4>; /* CSI2 DPHY. */
>> +				clock-lanes = <0>;
>> +				data-lanes = <1 2>;
>> +			};
>> +		};
>> +	};
>> +};
>> +
>> +&dphy1 {
>> +	status = "okay";
>> +};
>> +
>> +&ti_csi2rx1 {
>> +	status = "okay";
>> +};
>> \ No newline at end of file
>> -- 
>> 2.34.1
>>
> 


From vaishnav.a at ti.com  Thu Feb  8 00:58:05 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 14:28:05 +0530
Subject: [PATCH v2 0/3] arm64: dts: ti: Introduce J722S SoC and EVM
In-Reply-To: <20240206100608.127702-1-vaishnav.a@ti.com>
References: <20240206100608.127702-1-vaishnav.a@ti.com>
Message-ID: <d6bdb2e7-56f0-4f7d-afbc-a12ba4c5fd4b@ti.com>

Hi all,

On 06/02/24 15:36, Vaishnav Achath wrote:
> This series adds basic support for J722S family of SoCs. Also add
> J722S EVM support with basic peripheral like MMC and UART.
> 
> TRM: https://www.ti.com/lit/zip/sprujb3
> EVM Schematics: https://www.ti.com/lit/zip/sprr495
> 
> Bootlog (6.8.0-rc3-next-20240206):
> https://gist.github.com/vaishnavachath/23d859925277df9ccd628190e7c23371
> 

I missed to add link to V1 here, this a V2 of the below series with the 
feedback addressed:

https://lore.kernel.org/all/20231213124930.3012-1-vaishnav.a at ti.com/

Thanks and Regards,
Vaishnav

> Changelog:
> V1->V2:
>    * Address feedback from Nishanth to reuse from AM62P5 dtsi.
>    * Remove bootph-all from root nodes.
>    * Change License to GPL-2.0-only OR MIT as followed for other
>      K3 files.
> 
> Vaishnav Achath (3):
>    dt-bindings: arm: ti: Add bindings for J722S SoCs
>    arm64: dts: ti: Introduce J722S family of SoCs
>    arm64: dts: ti: Add support for TI J722S Evaluation Module
> 
>   .../devicetree/bindings/arm/ti/k3.yaml        |   6 +
>   arch/arm64/boot/dts/ti/Makefile               |   3 +
>   arch/arm64/boot/dts/ti/k3-j722s-evm.dts       | 251 ++++++++++++++++++
>   arch/arm64/boot/dts/ti/k3-j722s.dtsi          |  89 +++++++
>   arch/arm64/boot/dts/ti/k3-pinctrl.h           |   3 +
>   5 files changed, 352 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/ti/k3-j722s-evm.dts
>   create mode 100644 arch/arm64/boot/dts/ti/k3-j722s.dtsi
> 


From krzk at kernel.org  Thu Feb  8 01:01:30 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 8 Feb 2024 10:01:30 +0100
Subject: [PATCH v3 1/4] dt-bindings: display: bridge: add sam9x75-lvds
 compatible
In-Reply-To: <20240207102802.200220-2-dharma.b@microchip.com>
References: <20240207102802.200220-1-dharma.b@microchip.com>
 <20240207102802.200220-2-dharma.b@microchip.com>
Message-ID: <2219df60-7235-4c37-b79c-25e7225cb7a9@kernel.org>

On 07/02/2024 11:27, Dharma Balasubiramani wrote:
> Add the 'sam9x75-lvds' compatible binding, which describes the Low Voltage
> Differential Signaling (LVDS) Controller found on some Microchip's sam9x7
> series System-on-Chip (SoC) devices. This binding will be used to define
> the properties and configuration for the LVDS Controller in DT.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>

Not tested...

Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline), work on fork of kernel
(don't, instead use mainline) or you ignore some maintainers (really
don't). Just use b4 and everything should be fine, although remember
about `b4 prep --auto-to-cc` if you added new patches to the patchset.

You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time.

Please kindly resend and include all necessary To/Cc entries.


Best regards,
Krzysztof



From dharma.b at microchip.com  Thu Feb  8 01:20:15 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Thu, 8 Feb 2024 14:50:15 +0530
Subject: [PATCH] dt-bindings: interrupt-controller: Convert Atmel AIC to json-schema
Message-ID: <20240208092015.263210-1-dharma.b@microchip.com>

Convert the Atmel AIC binding document to DT schema format using
json-schema.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
Note: I get the following warnings on latest kernel but not in 6.7.
Should I be worried?

usage: yamllint [-h] [-] [-c CONFIG_FILE | -d CONFIG_DATA] [--list-files] [-f {parsable,standard,colored,github,auto}] [-s] [--no-warnings] [-v] [FILE_OR_DIR [FILE_OR_DIR ...]]
yamllint: error: one of the arguments FILE_OR_DIR - is required

 .../interrupt-controller/atmel,aic.txt        | 43 ---------
 .../interrupt-controller/atmel,aic.yaml       | 88 +++++++++++++++++++
 2 files changed, 88 insertions(+), 43 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
deleted file mode 100644
index 7079d44bf3ba..000000000000
--- a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-* Advanced Interrupt Controller (AIC)
-
-Required properties:
-- compatible: Should be:
-    - "atmel,<chip>-aic" where  <chip> can be "at91rm9200", "sama5d2",
-      "sama5d3" or "sama5d4"
-    - "microchip,<chip>-aic" where <chip> can be "sam9x60"
-
-- interrupt-controller: Identifies the node as an interrupt controller.
-- #interrupt-cells: The number of cells to define the interrupts. It should be 3.
-  The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet).
-  The second cell is used to specify flags:
-    bits[3:0] trigger type and level flags:
-      1 = low-to-high edge triggered.
-      2 = high-to-low edge triggered.
-      4 = active high level-sensitive.
-      8 = active low level-sensitive.
-      Valid combinations are 1, 2, 3, 4, 8.
-      Default flag for internal sources should be set to 4 (active high).
-  The third cell is used to specify the irq priority from 0 (lowest) to 7
-  (highest).
-- reg: Should contain AIC registers location and length
-- atmel,external-irqs: u32 array of external irqs.
-
-Examples:
-	/*
-	 * AIC
-	 */
-	aic: interrupt-controller at fffff000 {
-		compatible = "atmel,at91rm9200-aic";
-		interrupt-controller;
-		#interrupt-cells = <3>;
-		reg = <0xfffff000 0x200>;
-	};
-
-	/*
-	 * An interrupt generating device that is wired to an AIC.
-	 */
-	dma: dma-controller at ffffec00 {
-		compatible = "atmel,at91sam9g45-dma";
-		reg = <0xffffec00 0x200>;
-		interrupts = <21 4 5>;
-	};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
new file mode 100644
index 000000000000..396eac53da3a
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/atmel,aic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Advanced Interrupt Controller (AIC)
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Dharma balasubiramani <dharma.b at microchip.com>
+
+description: |
+  The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
+  maskable, vectored interrupt controller providing handling of up to one
+  hundred and twenty-eight interrupt sources. It is designed to substantially
+  reduce the software and real-time overhead in handling internal and external
+  interrupts.
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - atmel,at91rm9200-aic
+      - atmel,sama5d2-aic
+      - atmel,sama5d3-aic
+      - atmel,sama5d4-aic
+      - microchip,sam9x60-aic
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 3
+    description: |
+      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
+      The 2nd cell specifies flags:
+        bits[3:0] trigger type and level flags:
+          1 = low-to-high edge triggered.
+          2 = high-to-low edge triggered.
+          4 = active high level-sensitive.
+          8 = active low level-sensitive.
+        Valid combinations: 1, 2, 3, 4, 8.
+        Default for internal sources: 4 (active high).
+      The 3rd cell specifies irq priority from 0 (lowest) to 7 (highest).
+
+  interrupts:
+    description: Interrupt source of the parent interrupt controller.
+    maxItems: 1
+
+  reg:
+    description: Specifies base physical address(s) and size of the AIC registers.
+    maxItems: 1
+
+  atmel,external-irqs:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: u32 array of external irqs.
+
+required:
+  - compatible
+  - interrupt-controller
+  - "#interrupt-cells"
+  - reg
+  - atmel,external-irqs
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    /* AIC */
+    aic: interrupt-controller at fffff000 {
+      compatible = "atmel,at91rm9200-aic";
+      interrupt-controller;
+      #interrupt-cells = <3>;
+      reg = <0xfffff000 0x200>;
+      atmel,external-irqs = <31>;
+    };
+
+  - |
+    /* An interrupt generating device that is wired to an AIC. */
+    dma: dma-controller at ffffec00 {
+      compatible = "atmel,at91sam9g45-dma";
+      #dma-cells = <2>;
+      reg = <0xffffec00 0x200>;
+      interrupts = <21 4 5>;
+    };
+...

base-commit: 047371968ffc470769f541d6933e262dc7085456
-- 
2.25.1



From linux at armlinux.org.uk  Thu Feb  8 01:20:57 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 8 Feb 2024 09:20:57 +0000
Subject: [PATCH 0/2] ARM: prctl: Reject PR_SET_MDWE where not supported
In-Reply-To: <20240208012620.32604-4-zev@bewilderbeest.net>
References: <20240208012620.32604-4-zev@bewilderbeest.net>
Message-ID: <ZcSc+ftxHY8RyinQ@shell.armlinux.org.uk>

Hi,

Where is patch 1 of this series? It doesn't seem to have been Cc'd to
linux-arm-kernel. Therefore, this can't be reviewed.

Thanks.

On Wed, Feb 07, 2024 at 05:26:18PM -0800, Zev Weiss wrote:
> Hello,
> 
> I noticed after a recent kernel update that my ARM926 system started
> segfaulting on any execve() after calling prctl(PR_SET_MDWE).  After
> some investigation it appears that ARMv5 is incapable of providing the
> appropriate protections for MDWE, since any readable memory is also
> implicitly executable.
> 
> (Note that I'm not an expert in either ARM arch details or the mm
> subsystem, so please bear with me if I've botched something in the
> above analysis.)
> 
> The prctl_set_mdwe() function already had some special-case logic
> added disabling it on PARISC (commit 793838138c15, "prctl: Disable
> prctl(PR_SET_MDWE) on parisc"); this patch series (1) generalizes that
> check to use an arch_*() function, and (2) adds a corresponding
> override for ARM to disable MDWE on pre-ARMv6 CPUs.
> 
> With the series applied, prctl(PR_SET_MDWE) is rejected on ARMv5 and
> subsequent execve() calls (as well as mmap(PROT_READ|PROT_WRITE)) can
> succeed instead of unconditionally failing; on ARMv6 the prctl works
> as it did previously.
> 
> Since this was effectively a userspace-breaking change in v6.3 (with
> newer MDWE-aware userspace on older pre-MDWE kernels the prctl would
> simply fail safely) I've CCed -stable for v6.3+, though since the
> patches depend on the PARISC one above it will only apply cleanly on
> the linux-6.6.y and linux-6.7.y branches, since at least at time of
> writing the 6.3 through 6.5 branches don't have that patch backported
> (due to further missing dependencies [0]).
> 
> 
> Thanks,
> Zev
> 
> [0] https://lore.kernel.org/all/2023112456-linked-nape-bf19 at gregkh/
> 
> Zev Weiss (2):
>   prctl: Generalize PR_SET_MDWE support check to be per-arch
>   ARM: prctl: Reject PR_SET_MDWE on pre-ARMv6
> 
>  arch/arm/include/asm/mman.h    | 14 ++++++++++++++
>  arch/parisc/include/asm/mman.h | 14 ++++++++++++++
>  include/linux/mman.h           |  8 ++++++++
>  kernel/sys.c                   |  7 +++++--
>  4 files changed, 41 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm/include/asm/mman.h
>  create mode 100644 arch/parisc/include/asm/mman.h
> 
> -- 
> 2.43.0
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

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


From angelogioacchino.delregno at collabora.com  Thu Feb  8 01:24:24 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu,  8 Feb 2024 10:24:24 +0100
Subject: [PATCH RESEND] arm64: dts: mediatek: mt8192-asurada: Remove CrosEC base detection node
In-Reply-To: <20240207-mt8192-asurada-cbas-remove-v1-1-04cb65951975@collabora.com>
References: <20240207-mt8192-asurada-cbas-remove-v1-1-04cb65951975@collabora.com>
Message-ID: <170738399283.53206.14134622870926393347.b4-ty@collabora.com>


On Wed, 07 Feb 2024 15:08:42 -0500, N?colas F. R. A. Prado wrote:
> The commit adding the ChromeOS EC to the Asurada Devicetree mistakenly
> added a base detection node. While tablet mode detection is supported by
> CrosEC and used by Hayato, it is done through the cros-ec-keyb driver.
> The base detection node, which is handled by the hid-google-hammer
> driver, also provides tablet mode detection but by checking base
> attachment status on the CrosEC, which is not supported for Asurada.
> 
> [...]

Applied to v6.8-fixes/dts64, thanks!

[1/1] arm64: dts: mediatek: mt8192-asurada: Remove CrosEC base detection node
      https://git.kernel.org/mediatek/c/12356a73

Cheers,
Angelo



From horms at kernel.org  Thu Feb  8 01:26:27 2024
From: horms at kernel.org (Simon Horman)
Date: Thu, 8 Feb 2024 09:26:27 +0000
Subject: [PATCH net v4] net: stmmac: xgmac: fix handling of DPP safety
 error for DMA channels
In-Reply-To: <c25eb595-8d91-40ea-9f52-efa15ebafdbc@nvidia.com>
References: <20240203051439.1127090-1-0x1207@gmail.com>
 <c25eb595-8d91-40ea-9f52-efa15ebafdbc@nvidia.com>
Message-ID: <20240208092627.GP1297511@kernel.org>

On Wed, Feb 07, 2024 at 11:56:26AM +0000, Jon Hunter wrote:
> 
> On 03/02/2024 05:14, Furong Xu wrote:
> > Commit 56e58d6c8a56 ("net: stmmac: Implement Safety Features in
> > XGMAC core") checks and reports safety errors, but leaves the
> > Data Path Parity Errors for each channel in DMA unhandled at all, lead to
> > a storm of interrupt.
> > Fix it by checking and clearing the DMA_DPP_Interrupt_Status register.
> > 
> > Fixes: 56e58d6c8a56 ("net: stmmac: Implement Safety Features in XGMAC core")
> > Signed-off-by: Furong Xu <0x1207 at gmail.com>
> > Reviewed-by: Simon Horman <horms at kernel.org>
> > Reviewed-by: Serge Semin <fancer.lancer at gmail.com>
> > ---
> > Changes in v4:
> >   - fix a typo name of DDPP bit, thanks Serge Semin
> > 
> > Changes in v3:
> >   - code style fix, thanks Paolo Abeni
> > 
> > Changes in v2:
> >    - explicit enable Data Path Parity Protection
> >    - add new counters to stmmac_safety_stats
> >    - add detailed log
> > ---
> >   drivers/net/ethernet/stmicro/stmmac/common.h  |  1 +
> >   .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  3 +
> >   .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 57 ++++++++++++++++++-
> >   3 files changed, 60 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> > index 721c1f8e892f..b4f60ab078d6 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> > +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> > @@ -216,6 +216,7 @@ struct stmmac_safety_stats {
> >   	unsigned long mac_errors[32];
> >   	unsigned long mtl_errors[32];
> >   	unsigned long dma_errors[32];
> > +	unsigned long dma_dpp_errors[32];
> >   };
> >   /* Number of fields in Safety Stats */
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> > index 207ff1799f2c..5c67a3f89f08 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> > @@ -303,6 +303,8 @@
> >   #define XGMAC_RXCEIE			BIT(4)
> >   #define XGMAC_TXCEIE			BIT(0)
> >   #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
> > +#define XGMAC_MTL_DPP_CONTROL		0x000010e0
> > +#define XGMAC_DPP_DISABLE		BIT(0)
> >   #define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
> >   #define XGMAC_TQS			GENMASK(25, 16)
> >   #define XGMAC_TQS_SHIFT			16
> > @@ -385,6 +387,7 @@
> >   #define XGMAC_DCEIE			BIT(1)
> >   #define XGMAC_TCEIE			BIT(0)
> >   #define XGMAC_DMA_ECC_INT_STATUS	0x0000306c
> > +#define XGMAC_DMA_DPP_INT_STATUS	0x00003074
> >   #define XGMAC_DMA_CH_CONTROL(x)		(0x00003100 + (0x80 * (x)))
> >   #define XGMAC_SPH			BIT(24)
> >   #define XGMAC_PBLx8			BIT(16)
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > index eb48211d9b0e..04d7c4dc2e35 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > @@ -830,6 +830,43 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
> >   	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
> >   };
> > +static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
> > +static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
> > +static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
> > +	{ true, "TDPES0", dpp_tx_err },
> > +	{ true, "TDPES1", dpp_tx_err },
> > +	{ true, "TDPES2", dpp_tx_err },
> > +	{ true, "TDPES3", dpp_tx_err },
> > +	{ true, "TDPES4", dpp_tx_err },
> > +	{ true, "TDPES5", dpp_tx_err },
> > +	{ true, "TDPES6", dpp_tx_err },
> > +	{ true, "TDPES7", dpp_tx_err },
> > +	{ true, "TDPES8", dpp_tx_err },
> > +	{ true, "TDPES9", dpp_tx_err },
> > +	{ true, "TDPES10", dpp_tx_err },
> > +	{ true, "TDPES11", dpp_tx_err },
> > +	{ true, "TDPES12", dpp_tx_err },
> > +	{ true, "TDPES13", dpp_tx_err },
> > +	{ true, "TDPES14", dpp_tx_err },
> > +	{ true, "TDPES15", dpp_tx_err },
> > +	{ true, "RDPES0", dpp_rx_err },
> > +	{ true, "RDPES1", dpp_rx_err },
> > +	{ true, "RDPES2", dpp_rx_err },
> > +	{ true, "RDPES3", dpp_rx_err },
> > +	{ true, "RDPES4", dpp_rx_err },
> > +	{ true, "RDPES5", dpp_rx_err },
> > +	{ true, "RDPES6", dpp_rx_err },
> > +	{ true, "RDPES7", dpp_rx_err },
> > +	{ true, "RDPES8", dpp_rx_err },
> > +	{ true, "RDPES9", dpp_rx_err },
> > +	{ true, "RDPES10", dpp_rx_err },
> > +	{ true, "RDPES11", dpp_rx_err },
> > +	{ true, "RDPES12", dpp_rx_err },
> > +	{ true, "RDPES13", dpp_rx_err },
> > +	{ true, "RDPES14", dpp_rx_err },
> > +	{ true, "RDPES15", dpp_rx_err },
> > +};
> > +
> >   static void dwxgmac3_handle_dma_err(struct net_device *ndev,
> >   				    void __iomem *ioaddr, bool correctable,
> >   				    struct stmmac_safety_stats *stats)
> > @@ -841,6 +878,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev,
> >   	dwxgmac3_log_error(ndev, value, correctable, "DMA",
> >   			   dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats);
> > +
> > +	value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS);
> > +	writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS);
> > +
> > +	dwxgmac3_log_error(ndev, value, false, "DMA_DPP",
> > +			   dwxgmac3_dma_dpp_errors,
> > +			   STAT_OFF(dma_dpp_errors), stats);
> >   }
> >   static int
> > @@ -881,6 +925,12 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
> >   	value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */
> >   	writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL);
> > +	/* 5. Enable Data Path Parity Protection */
> > +	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
> > +	/* already enabled by default, explicit enable it again */
> > +	value &= ~XGMAC_DPP_DISABLE;
> > +	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
> > +
> >   	return 0;
> >   }
> > @@ -914,7 +964,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev,
> >   		ret |= !corr;
> >   	}
> > -	err = dma & (XGMAC_DEUIS | XGMAC_DECIS);
> > +	/* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in
> > +	 * DMA_Safety_Interrupt_Status, so we handle DMA Data Path
> > +	 * Parity Errors here
> > +	 */
> > +	err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS);
> >   	corr = dma & XGMAC_DECIS;
> >   	if (err) {
> >   		dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats);
> > @@ -930,6 +984,7 @@ static const struct dwxgmac3_error {
> >   	{ dwxgmac3_mac_errors },
> >   	{ dwxgmac3_mtl_errors },
> >   	{ dwxgmac3_dma_errors },
> > +	{ dwxgmac3_dma_dpp_errors },
> >   };
> >   static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats,
> 
> 
> This change is breaking the build on some of our builders that are still using GCC 6.x ...
> 
> drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:836:20: error: initialiser element is not constant
>   { true, "TDPES0", dpp_tx_err },
>                     ^~~~~~~~~~
> drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:836:20: note: (near initialisation for ?dwxgmac3_dma_dpp_errors[0].detailed_desc?)
> drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:837:20: error: initialiser element is not constant
>   { true, "TDPES1", dpp_tx_err },
>                     ^~~~~~~~~~
> drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:837:20: note: (near initialisation for ?dwxgmac3_dma_dpp_errors[1].detailed_desc?)
> ...
> 
> I know that this is quite old but the minimum supported by the kernel is v5.1 ...
> 
> https://www.kernel.org/doc/html/next/process/changes.html

Thanks Jon,

I separately received a notification about this occurring with gcc 7.

https://lore.kernel.org/oe-kbuild-all/202402081135.lAxxBXHk-lkp at intel.com/

It is unclear to me why this occurs, as dpp_tx_err and dpp_tx_err are const.
But I do seem to be able to address this problem by using #defines for
these values instead.

I plan to post a patch shortly.


From bhargav.r at ltts.com  Thu Feb  8 01:21:53 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 14:51:53 +0530
Subject: [PATCH v1 13/13] arch: arm64: dts: ti: k3-am62p5-sk: Add TPS65224 PMIC support in AM62P dts
Message-ID: <20240208092153.1207321-1-bhargav.r@ltts.com>

Add support for TPS65224 PMIC in device tree of AM62P EVM. Adds
regulator configuration, pinmux configurations and pmic device nodes.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 95 +++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 1773c05f7..5d8e4321b 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -112,6 +112,16 @@ vddshv_sdio: regulator-3 {
 		bootph-all;
 	};
 
+	vcc_3v3_main: regulator-4 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_main";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vmain_pd>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -580,6 +590,12 @@ &main_uart1 {
 &mcu_pmx0 {
 	bootph-all;
 
+	pmic_irq_pins_default: pmic-irq-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_MCU_IOPAD(0x000, PIN_INPUT, 7) /* (B10) MCU_GPIO0_0 */
+		>;
+	};
+
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
 			AM62PX_MCU_IOPAD(0x02c, PIN_INPUT, 0)	/* (C7) WKUP_UART0_CTSn */
@@ -589,6 +605,13 @@ AM62PX_MCU_IOPAD(0x028, PIN_OUTPUT, 0)	/* (D7) WKUP_UART0_TXD */
 		>;
 		bootph-all;
 	};
+
+	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_MCU_IOPAD(0x04c, PIN_INPUT, 0) /* (A13) WKUP_I2C0_SCL */
+			AM62PX_MCU_IOPAD(0x050, PIN_INPUT, 0) /* (C11) WKUP_I2C0_SDA */
+		>;
+	};
 };
 
 &wkup_uart0 {
@@ -599,6 +622,78 @@ &wkup_uart0 {
 	bootph-all;
 };
 
+&wkup_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_i2c0_pins_default>;
+	clock-frequency = <400000>;
+
+	tps65224: pmic at 48 {
+		compatible = "ti,tps65224-q1";
+		reg = <0x48>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_irq_pins_default>;
+		interrupt-parent = <&mcu_gpio0>;
+		interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+		ti,primary-pmic;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		buck12-supply = <&vcc_3v3_main>;
+		buck3-supply = <&vcc_3v3_main>;
+		buck4-supply = <&vcc_3v3_main>;
+
+		ldo1-supply = <&vcc_3v3_main>;
+		ldo2-supply = <&vcc_3v3_main>;
+		ldo3-supply = <&vcc1v8_sys>;
+
+		regulators {
+			vcc_core: buck12 {
+				regulator-name = "vcc_core_buck12";
+				regulator-min-microvolt = <715000>;
+				regulator-max-microvolt = <895000>;
+				regulator-always-on;
+			};
+
+			vcc1v8_sys: buck3 {
+				regulator-name = "vcc1v8_sys_buck3";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			vcc1v1: buck4 {
+				regulator-name = "vcc1v1_buck4";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			vdda1v8: ldo1 {
+				regulator-name = "vdda1v8_ldo1";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			dvdd3v3: ldo2 {
+				regulator-name = "dvdd3v3_ldo2";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vcc_0v85: ldo3 {
+				regulator-name = "vcc_0v85_ldo3";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
 /* mcu_gpio0 and mcu_gpio_intr are reserved for mcu firmware usage */
 &mcu_gpio0 {
 	status = "reserved";
-- 
2.25.1



From sunnanyong at huawei.com  Thu Feb  8 01:30:28 2024
From: sunnanyong at huawei.com (Nanyong Sun)
Date: Thu, 8 Feb 2024 17:30:28 +0800
Subject: [PATCH v3 2/3] arm64: mm: HVO: support BBM of vmemmap pgtable
 safely
In-Reply-To: <ZcN13R1L1CYu9gs1@FVFF77S0Q05N.cambridge.arm.com>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <20240113094436.2506396-3-sunnanyong@huawei.com>
 <ZcN13R1L1CYu9gs1@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <2372364b-d02a-9082-de6b-d17655ad229a@huawei.com>

On 2024/2/7 20:21, Mark Rutland wrote:

> On Sat, Jan 13, 2024 at 05:44:35PM +0800, Nanyong Sun wrote:
>> Implement vmemmap_update_pmd and vmemmap_update_pte on arm64 to do
>> BBM(break-before-make) logic when change the page table of vmemmap
>> address, they will under the init_mm.page_table_lock.
>> If a translation fault of vmemmap address concurrently happened after
>> pte/pmd cleared, vmemmap page fault handler will acquire the
>> init_mm.page_table_lock to wait for vmemmap update to complete,
>> by then the virtual address is valid again, so PF can return and
>> access can continue.
> Is that wait bounded? ... and is it event guaranteed to make progress?
>
> Under a hypervisor, the vCPU doing the BBM could be preempted between the break
> and the make, so the thread waiting might be waiting a long time for that to
> come back and finish the make step.
>
> Further, under PREEMPT_RT regular spinlocks don't inhibit preemption, and I suspect
> that means this can deadlock on RT -- the thread doing the BBM could be
> preempted, the newly-scheduled thread could try to access the vmemmap, and then
> get stuck in the fault handler (e.g. on a single CPU system). There's nothing
> below describing how that's prevented.
>
> I've concerned this may be subtly broken, and it feels like this is going to be
> *very* painful to maintain and test. IMO this is trying to be overly clever and
> I'd much rather that we avoided the transient broken step. On CPUs with
> FEAT_BBM level 2 we can avoid that broken step, can we make this depend
> dynamically on whether the CPU has FEAT_BBM?
If I understand correctly, FEAT_BBM is only used for changing block 
size. But in HVO
we not only need changing block size in vmemmap_split_pmd(), but also 
need changing
output address of PTE in vmemmap_remap_pte().
So I would like to ask if FEAT_BBM can cover these scenarios?
>
>> In other case, do the traditional kernel fault.
>>
>> Implement vmemmap_flush_tlb_all/range on arm64 with nothing
>> to do because tlb already flushed in every single BBM.
>>
>> Signed-off-by: Nanyong Sun <sunnanyong at huawei.com>
>> ---
>>
>> +
>> +/*
>> + * PMD mapped vmemmap should has been split as PTE mapped
>> + * by HVO now, here we only check this case, other cases
>> + * should fail.
> Sorry, I can't parse what this is trying to say.
>
>> + * Also should check the addr is healthy enough that will not cause
>> + * a level2 or level3 translation fault again after page fault
>> + * handled with success, so we need check both bits[1:0] of PMD and
>> + * PTE as ARM Spec mentioned below:
> Which spec? Iassume you mean the ARM ARM? Are you referring to a specific part
> within that?

Yes, I referenced section D5.8.1 "Types of MMU faults" from Arm ARM.

>
>> + * A Translation fault is generated if bits[1:0] of a translation
>> + * table descriptor identify the descriptor as either a Fault
>> + * encoding or a reserved encoding.
>> + */
>> +static inline bool vmemmap_addr_healthy(unsigned long addr)
>> +{
>> +	pmd_t *pmdp, pmd;
>> +	pte_t *ptep, pte;
>> +
>> +	pmdp = pmd_off_k(addr);
>> +	pmd = pmdp_get(pmdp);
>> +	if (!pmd_table(pmd))
>> +		return false;
> Is a block (i.e. hugetlb) entry not considered healthy? I thought the whole
> point of this optimization was that you'd use a block PMD entry?
Yes, this patch only condiser the user is HVO and then recheck here, and 
in HVO, only PMD split and
PTE remap can happen. Any other scenarios should be treated as regular 
kernel fault and then panic.
>
>> +
>> +	ptep = pte_offset_kernel(pmdp, addr);
>> +	pte = ptep_get(ptep);
>> +	return (pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_PAGE;
>> +}
>> +
>> +static bool vmemmap_handle_page_fault(unsigned long addr,
>> +				      unsigned long esr)
>> +{
>> +	bool ret;
>> +
>> +	if (likely(!vmemmap_fault_may_fixup(addr, esr)))
>> +		return false;
>> +
>> +	spin_lock(&init_mm.page_table_lock);
>> +	ret = vmemmap_addr_healthy(addr);
>> +	spin_unlock(&init_mm.page_table_lock);
> As above, I'm pretty sure this is only safe is the code doing the BBM has IRQs
> disabled, otherwise the thread can be preempted, and we can get stuck in here
> while the entry is broken.
>
> So at minimum this needs some explanation of why that doesn't happen in a
> comment.
>
>
> As above, if this happens with IRQs unmasked, the thread can potentially be
> preempted and we can get stuck in the fault handler (at least on RT).
>
> I can't tell whether this is safe, and I think that at minimum this needs
> comments and/or lockdep assertions, but I'd much rather we didn't try to play
> this sort of game.
>
> Mark.
>
> .

For IRQ context problem, I wonder if take a new spin lock with irq 
disabled can solve it?

eg.

+void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte)
+{
+	spin_lock_irq(NEW_LOCK);
+	pte_clear(&init_mm, addr, ptep);
+	flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+	set_pte_at(&init_mm, addr, ptep, pte);
+	spin_unlock_irq(NEW_LOCK);
+}



From ghennadi.procopciuc at oss.nxp.com  Thu Feb  8 01:34:58 2024
From: ghennadi.procopciuc at oss.nxp.com (Ghennadi Procopciuc)
Date: Thu, 8 Feb 2024 11:34:58 +0200
Subject: [PATCH v2 0/2] add uSDHC and SCMI nodes to the S32G2 SoC
In-Reply-To: <20240122140602.1006813-1-ghennadi.procopciuc@oss.nxp.com>
References: <20240122140602.1006813-1-ghennadi.procopciuc@oss.nxp.com>
Message-ID: <a7a55dc6-c204-4aad-adff-9806d3302b6b@oss.nxp.com>

On 1/22/24 16:05, Ghennadi Procopciuc wrote:
> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> 
> This patchset adds device tree support for S32G2 SCMI firmware and uSDHC
> node. The SCMI clock IDs are based on a downstream version of the TF-A
> stored on GitHub [0].
> 
> I can send the patches individually if you prefer that instead of
> submitting them all at once.??
> 
> [0] https://github.com/nxp-auto-linux/arm-trusted-firmware
> 
> Changes in v2:
>  - The SCMI clock bindings header has been removed.
> 
> Ghennadi Procopciuc (2):
>   arm64: dts: s32g: add SCMI firmware node
>   arm64: dts: s32g: add uSDHC node
> 
>  arch/arm64/boot/dts/freescale/s32g2.dtsi      | 37 ++++++++++++++++++-
>  .../arm64/boot/dts/freescale/s32g274a-evb.dts |  6 ++-
>  .../boot/dts/freescale/s32g274a-rdb2.dts      |  6 ++-
>  3 files changed, 46 insertions(+), 3 deletions(-)
> 
Hi Chester,

I want to confirm if you are open to accepting the proposed changes for
ARM/NXP S32G architecture, given your maintainer role. Please let me
know if any revisions or adaptations are required.

Regards,
Ghennadi



From sunnanyong at huawei.com  Thu Feb  8 01:44:48 2024
From: sunnanyong at huawei.com (Nanyong Sun)
Date: Thu, 8 Feb 2024 17:44:48 +0800
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <ZcN1hTrAhy-B1P2_@arm.com>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com> <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
 <ZcNnrdlb3fe0kGHK@casper.infradead.org> <ZcN1hTrAhy-B1P2_@arm.com>
Message-ID: <44075bc2-ac5f-ffcd-0d2f-4093351a6151@huawei.com>


? 2024/2/7 20:20, Catalin Marinas ??:
> On Wed, Feb 07, 2024 at 11:21:17AM +0000, Matthew Wilcox wrote:
>> On Wed, Feb 07, 2024 at 11:12:52AM +0000, Will Deacon wrote:
>>> On Sat, Jan 27, 2024 at 01:04:15PM +0800, Nanyong Sun wrote:
>>>> On 2024/1/26 2:06, Catalin Marinas wrote:
>>>>> On Sat, Jan 13, 2024 at 05:44:33PM +0800, Nanyong Sun wrote:
>>>>>> HVO was previously disabled on arm64 [1] due to the lack of necessary
>>>>>> BBM(break-before-make) logic when changing page tables.
>>>>>> This set of patches fix this by adding necessary BBM sequence when
>>>>>> changing page table, and supporting vmemmap page fault handling to
>>>>>> fixup kernel address translation fault if vmemmap is concurrently accessed.
>>>>> I'm not keen on this approach. I'm not even sure it's safe. In the
>>>>> second patch, you take the init_mm.page_table_lock on the fault path but
>>>>> are we sure this is unlocked when the fault was taken?
>>>> I think this situation is impossible. In the implementation of the second
>>>> patch, when the page table is being corrupted
>>>> (the time window when a page fault may occur), vmemmap_update_pte() already
>>>> holds the init_mm.page_table_lock,
>>>> and unlock it until page table update is done.Another thread could not hold
>>>> the init_mm.page_table_lock and
>>>> also trigger a page fault at the same time.
>>>> If I have missed any points in my thinking, please correct me. Thank you.
>>> It still strikes me as incredibly fragile to handle the fault and trying
>>> to reason about all the users of 'struct page' is impossible. For example,
>>> can the fault happen from irq context?
>> The pte lock cannot be taken in irq context (which I think is what
>> you're asking?)
> With this patchset, I think it can: IRQ -> interrupt handler accesses
> vmemmap -> faults -> fault handler in patch 2 takes the
> init_mm.page_table_lock to wait for the vmemmap rewriting to complete.
> Maybe it works if the hugetlb code disabled the IRQs but, as Will said,
> such fault in any kernel context looks fragile.
How about take a new lock with irq disabled during BBM, like:

+void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte)
+{
+??? spin_lock_irq(NEW_LOCK);
+??? pte_clear(&init_mm, addr, ptep);
+??? flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+??? set_pte_at(&init_mm, addr, ptep, pte);
+??? spin_unlock_irq(NEW_LOCK);
+}


From horms at kernel.org  Thu Feb  8 01:48:27 2024
From: horms at kernel.org (Simon Horman)
Date: Thu, 08 Feb 2024 09:48:27 +0000
Subject: [PATCH net] net: stmmac: xgmac: use #define for string constants
Message-ID: <20240208-xgmac-const-v1-1-e69a1eeabfc8@kernel.org>

The cited commit introduces and uses the string constants dpp_tx_err and
dpp_rx_err. These are assigned to constant fields of the array
dwxgmac3_error_desc.

It has been reported that on GCC 6 and 7.5.0 this results in warnings
such as:

  .../dwxgmac2_core.c:836:20: error: initialiser element is not constant
   { true, "TDPES0", dpp_tx_err },

I have been able to reproduce this using: GCC 7.5.0, 8.4.0, 9.4.0 and 10.5.0.
But not GCC 13.2.0.

So it seems this effects older compilers but not newer ones.
As Jon points out in his report, the minimum compiler supported by
the kernel is GCC 5.1, so it does seem that this ought to be fixed.

It is not clear to me what combination of 'const', if any, would address
this problem.  So this patch takes of using #defines for the string
constants

Compile tested only.

Fixes: 46eba193d04f ("net: stmmac: xgmac: fix handling of DPP safety error for DMA channels")
Reported-by: Jon Hunter <jonathanh at nvidia.com>
Closes: https://lore.kernel.org/netdev/c25eb595-8d91-40ea-9f52-efa15ebafdbc at nvidia.com/
Reported-by: kernel test robot <lkp at intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202402081135.lAxxBXHk-lkp at intel.com/
Signed-off-by: Simon Horman <horms at kernel.org>
---
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c    | 69 +++++++++++-----------
 1 file changed, 35 insertions(+), 34 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index 323c57f03c93..1af2f89a0504 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -830,41 +830,42 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
 	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
 };
 
-static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
-static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
+#define DPP_RX_ERR "Read Rx Descriptor Parity checker Error"
+#define DPP_TX_ERR "Read Tx Descriptor Parity checker Error"
+
 static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
-	{ true, "TDPES0", dpp_tx_err },
-	{ true, "TDPES1", dpp_tx_err },
-	{ true, "TDPES2", dpp_tx_err },
-	{ true, "TDPES3", dpp_tx_err },
-	{ true, "TDPES4", dpp_tx_err },
-	{ true, "TDPES5", dpp_tx_err },
-	{ true, "TDPES6", dpp_tx_err },
-	{ true, "TDPES7", dpp_tx_err },
-	{ true, "TDPES8", dpp_tx_err },
-	{ true, "TDPES9", dpp_tx_err },
-	{ true, "TDPES10", dpp_tx_err },
-	{ true, "TDPES11", dpp_tx_err },
-	{ true, "TDPES12", dpp_tx_err },
-	{ true, "TDPES13", dpp_tx_err },
-	{ true, "TDPES14", dpp_tx_err },
-	{ true, "TDPES15", dpp_tx_err },
-	{ true, "RDPES0", dpp_rx_err },
-	{ true, "RDPES1", dpp_rx_err },
-	{ true, "RDPES2", dpp_rx_err },
-	{ true, "RDPES3", dpp_rx_err },
-	{ true, "RDPES4", dpp_rx_err },
-	{ true, "RDPES5", dpp_rx_err },
-	{ true, "RDPES6", dpp_rx_err },
-	{ true, "RDPES7", dpp_rx_err },
-	{ true, "RDPES8", dpp_rx_err },
-	{ true, "RDPES9", dpp_rx_err },
-	{ true, "RDPES10", dpp_rx_err },
-	{ true, "RDPES11", dpp_rx_err },
-	{ true, "RDPES12", dpp_rx_err },
-	{ true, "RDPES13", dpp_rx_err },
-	{ true, "RDPES14", dpp_rx_err },
-	{ true, "RDPES15", dpp_rx_err },
+	{ true, "TDPES0", DPP_TX_ERR },
+	{ true, "TDPES1", DPP_TX_ERR },
+	{ true, "TDPES2", DPP_TX_ERR },
+	{ true, "TDPES3", DPP_TX_ERR },
+	{ true, "TDPES4", DPP_TX_ERR },
+	{ true, "TDPES5", DPP_TX_ERR },
+	{ true, "TDPES6", DPP_TX_ERR },
+	{ true, "TDPES7", DPP_TX_ERR },
+	{ true, "TDPES8", DPP_TX_ERR },
+	{ true, "TDPES9", DPP_TX_ERR },
+	{ true, "TDPES10", DPP_TX_ERR },
+	{ true, "TDPES11", DPP_TX_ERR },
+	{ true, "TDPES12", DPP_TX_ERR },
+	{ true, "TDPES13", DPP_TX_ERR },
+	{ true, "TDPES14", DPP_TX_ERR },
+	{ true, "TDPES15", DPP_TX_ERR },
+	{ true, "RDPES0", DPP_RX_ERR },
+	{ true, "RDPES1", DPP_RX_ERR },
+	{ true, "RDPES2", DPP_RX_ERR },
+	{ true, "RDPES3", DPP_RX_ERR },
+	{ true, "RDPES4", DPP_RX_ERR },
+	{ true, "RDPES5", DPP_RX_ERR },
+	{ true, "RDPES6", DPP_RX_ERR },
+	{ true, "RDPES7", DPP_RX_ERR },
+	{ true, "RDPES8", DPP_RX_ERR },
+	{ true, "RDPES9", DPP_RX_ERR },
+	{ true, "RDPES10", DPP_RX_ERR },
+	{ true, "RDPES11", DPP_RX_ERR },
+	{ true, "RDPES12", DPP_RX_ERR },
+	{ true, "RDPES13", DPP_RX_ERR },
+	{ true, "RDPES14", DPP_RX_ERR },
+	{ true, "RDPES15", DPP_RX_ERR },
 };
 
 static void dwxgmac3_handle_dma_err(struct net_device *ndev,



From horms at kernel.org  Thu Feb  8 01:53:48 2024
From: horms at kernel.org (Simon Horman)
Date: Thu, 8 Feb 2024 09:53:48 +0000
Subject: [PATCH net v4] net: stmmac: xgmac: fix handling of DPP safety
 error for DMA channels
In-Reply-To: <20240208092627.GP1297511@kernel.org>
References: <20240203051439.1127090-1-0x1207@gmail.com>
 <c25eb595-8d91-40ea-9f52-efa15ebafdbc@nvidia.com>
 <20240208092627.GP1297511@kernel.org>
Message-ID: <20240208095348.GA1435458@kernel.org>

On Thu, Feb 08, 2024 at 09:26:27AM +0000, Simon Horman wrote:
> On Wed, Feb 07, 2024 at 11:56:26AM +0000, Jon Hunter wrote:
> > 
> > On 03/02/2024 05:14, Furong Xu wrote:
> > > Commit 56e58d6c8a56 ("net: stmmac: Implement Safety Features in
> > > XGMAC core") checks and reports safety errors, but leaves the
> > > Data Path Parity Errors for each channel in DMA unhandled at all, lead to
> > > a storm of interrupt.
> > > Fix it by checking and clearing the DMA_DPP_Interrupt_Status register.
> > > 
> > > Fixes: 56e58d6c8a56 ("net: stmmac: Implement Safety Features in XGMAC core")
> > > Signed-off-by: Furong Xu <0x1207 at gmail.com>
> > > Reviewed-by: Simon Horman <horms at kernel.org>
> > > Reviewed-by: Serge Semin <fancer.lancer at gmail.com>
> > > ---
> > > Changes in v4:
> > >   - fix a typo name of DDPP bit, thanks Serge Semin
> > > 
> > > Changes in v3:
> > >   - code style fix, thanks Paolo Abeni
> > > 
> > > Changes in v2:
> > >    - explicit enable Data Path Parity Protection
> > >    - add new counters to stmmac_safety_stats
> > >    - add detailed log
> > > ---
> > >   drivers/net/ethernet/stmicro/stmmac/common.h  |  1 +
> > >   .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  3 +
> > >   .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 57 ++++++++++++++++++-
> > >   3 files changed, 60 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> > > index 721c1f8e892f..b4f60ab078d6 100644
> > > --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> > > +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> > > @@ -216,6 +216,7 @@ struct stmmac_safety_stats {
> > >   	unsigned long mac_errors[32];
> > >   	unsigned long mtl_errors[32];
> > >   	unsigned long dma_errors[32];
> > > +	unsigned long dma_dpp_errors[32];
> > >   };
> > >   /* Number of fields in Safety Stats */
> > > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> > > index 207ff1799f2c..5c67a3f89f08 100644
> > > --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> > > +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
> > > @@ -303,6 +303,8 @@
> > >   #define XGMAC_RXCEIE			BIT(4)
> > >   #define XGMAC_TXCEIE			BIT(0)
> > >   #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
> > > +#define XGMAC_MTL_DPP_CONTROL		0x000010e0
> > > +#define XGMAC_DPP_DISABLE		BIT(0)
> > >   #define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
> > >   #define XGMAC_TQS			GENMASK(25, 16)
> > >   #define XGMAC_TQS_SHIFT			16
> > > @@ -385,6 +387,7 @@
> > >   #define XGMAC_DCEIE			BIT(1)
> > >   #define XGMAC_TCEIE			BIT(0)
> > >   #define XGMAC_DMA_ECC_INT_STATUS	0x0000306c
> > > +#define XGMAC_DMA_DPP_INT_STATUS	0x00003074
> > >   #define XGMAC_DMA_CH_CONTROL(x)		(0x00003100 + (0x80 * (x)))
> > >   #define XGMAC_SPH			BIT(24)
> > >   #define XGMAC_PBLx8			BIT(16)
> > > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > > index eb48211d9b0e..04d7c4dc2e35 100644
> > > --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > > +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > > @@ -830,6 +830,43 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
> > >   	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
> > >   };
> > > +static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
> > > +static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
> > > +static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
> > > +	{ true, "TDPES0", dpp_tx_err },
> > > +	{ true, "TDPES1", dpp_tx_err },
> > > +	{ true, "TDPES2", dpp_tx_err },
> > > +	{ true, "TDPES3", dpp_tx_err },
> > > +	{ true, "TDPES4", dpp_tx_err },
> > > +	{ true, "TDPES5", dpp_tx_err },
> > > +	{ true, "TDPES6", dpp_tx_err },
> > > +	{ true, "TDPES7", dpp_tx_err },
> > > +	{ true, "TDPES8", dpp_tx_err },
> > > +	{ true, "TDPES9", dpp_tx_err },
> > > +	{ true, "TDPES10", dpp_tx_err },
> > > +	{ true, "TDPES11", dpp_tx_err },
> > > +	{ true, "TDPES12", dpp_tx_err },
> > > +	{ true, "TDPES13", dpp_tx_err },
> > > +	{ true, "TDPES14", dpp_tx_err },
> > > +	{ true, "TDPES15", dpp_tx_err },
> > > +	{ true, "RDPES0", dpp_rx_err },
> > > +	{ true, "RDPES1", dpp_rx_err },
> > > +	{ true, "RDPES2", dpp_rx_err },
> > > +	{ true, "RDPES3", dpp_rx_err },
> > > +	{ true, "RDPES4", dpp_rx_err },
> > > +	{ true, "RDPES5", dpp_rx_err },
> > > +	{ true, "RDPES6", dpp_rx_err },
> > > +	{ true, "RDPES7", dpp_rx_err },
> > > +	{ true, "RDPES8", dpp_rx_err },
> > > +	{ true, "RDPES9", dpp_rx_err },
> > > +	{ true, "RDPES10", dpp_rx_err },
> > > +	{ true, "RDPES11", dpp_rx_err },
> > > +	{ true, "RDPES12", dpp_rx_err },
> > > +	{ true, "RDPES13", dpp_rx_err },
> > > +	{ true, "RDPES14", dpp_rx_err },
> > > +	{ true, "RDPES15", dpp_rx_err },
> > > +};
> > > +
> > >   static void dwxgmac3_handle_dma_err(struct net_device *ndev,
> > >   				    void __iomem *ioaddr, bool correctable,
> > >   				    struct stmmac_safety_stats *stats)
> > > @@ -841,6 +878,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev,
> > >   	dwxgmac3_log_error(ndev, value, correctable, "DMA",
> > >   			   dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats);
> > > +
> > > +	value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS);
> > > +	writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS);
> > > +
> > > +	dwxgmac3_log_error(ndev, value, false, "DMA_DPP",
> > > +			   dwxgmac3_dma_dpp_errors,
> > > +			   STAT_OFF(dma_dpp_errors), stats);
> > >   }
> > >   static int
> > > @@ -881,6 +925,12 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
> > >   	value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */
> > >   	writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL);
> > > +	/* 5. Enable Data Path Parity Protection */
> > > +	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
> > > +	/* already enabled by default, explicit enable it again */
> > > +	value &= ~XGMAC_DPP_DISABLE;
> > > +	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
> > > +
> > >   	return 0;
> > >   }
> > > @@ -914,7 +964,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev,
> > >   		ret |= !corr;
> > >   	}
> > > -	err = dma & (XGMAC_DEUIS | XGMAC_DECIS);
> > > +	/* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in
> > > +	 * DMA_Safety_Interrupt_Status, so we handle DMA Data Path
> > > +	 * Parity Errors here
> > > +	 */
> > > +	err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS);
> > >   	corr = dma & XGMAC_DECIS;
> > >   	if (err) {
> > >   		dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats);
> > > @@ -930,6 +984,7 @@ static const struct dwxgmac3_error {
> > >   	{ dwxgmac3_mac_errors },
> > >   	{ dwxgmac3_mtl_errors },
> > >   	{ dwxgmac3_dma_errors },
> > > +	{ dwxgmac3_dma_dpp_errors },
> > >   };
> > >   static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats,
> > 
> > 
> > This change is breaking the build on some of our builders that are still using GCC 6.x ...
> > 
> > drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:836:20: error: initialiser element is not constant
> >   { true, "TDPES0", dpp_tx_err },
> >                     ^~~~~~~~~~
> > drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:836:20: note: (near initialisation for ?dwxgmac3_dma_dpp_errors[0].detailed_desc?)
> > drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:837:20: error: initialiser element is not constant
> >   { true, "TDPES1", dpp_tx_err },
> >                     ^~~~~~~~~~
> > drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:837:20: note: (near initialisation for ?dwxgmac3_dma_dpp_errors[1].detailed_desc?)
> > ...
> > 
> > I know that this is quite old but the minimum supported by the kernel is v5.1 ...
> > 
> > https://www.kernel.org/doc/html/next/process/changes.html
> 
> Thanks Jon,
> 
> I separately received a notification about this occurring with gcc 7.
> 
> https://lore.kernel.org/oe-kbuild-all/202402081135.lAxxBXHk-lkp at intel.com/
> 
> It is unclear to me why this occurs, as dpp_tx_err and dpp_tx_err are const.
> But I do seem to be able to address this problem by using #defines for
> these values instead.
> 
> I plan to post a patch shortly.

Patch posted:
- [PATCH net] net: stmmac: xgmac: use #define for string constants
  https://lore.kernel.org/netdev/20240208-xgmac-const-v1-1-e69a1eeabfc8 at kernel.org/



From parri.andrea at gmail.com  Thu Feb  8 02:10:50 2024
From: parri.andrea at gmail.com (Andrea Parri)
Date: Thu, 8 Feb 2024 11:10:50 +0100
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <20240127161753.114685-1-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
Message-ID: <ZcSoqkexSipQsrLZ@andrea>

Hi Anup,

I understand that some refactoring is in progress, but I don't see the
report below; adding it here hoping that it can be useful towards v13.
(Unfortunately, I didn't have enough time to debug this yet...)


>   irqchip/sifive-plic: Convert PLIC driver into a platform driver

I'm seeing the following LOCKDEP warning with this series, bisected to
the commit above.  This is a defconfig + PROVE_LOCKING=y build, booted
using -machine virt,aia=none.

[    0.953473] ========================================================
[    0.953704] WARNING: possible irq lock inversion dependency detected
[    0.953955] 6.8.0-rc1-00039-gd9b9d6eb987f #1122 Not tainted
[    0.954224] --------------------------------------------------------
[    0.954444] swapper/0/0 just changed the state of lock:
[    0.954664] ffffaf808109d0c8 (&irq_desc_lock_class){-...}-{2:2}, at: handle_fasteoi_irq+0x24/0x1da
[    0.955699] but this lock took another, HARDIRQ-unsafe lock in the past:
[    0.955942]  (&handler->enable_lock){+.+.}-{2:2}
[    0.955974] 
               
               and interrupts could create inverse lock ordering between them.

[    0.956507] 
               other info that might help us debug this:
[    0.956775]  Possible interrupt unsafe locking scenario:

[    0.956998]        CPU0                    CPU1
[    0.957247]        ----                    ----
[    0.957439]   lock(&handler->enable_lock);
[    0.957607]                                local_irq_disable();
[    0.957793]                                lock(&irq_desc_lock_class);
[    0.958021]                                lock(&handler->enable_lock);
[    0.958246]   <Interrupt>
[    0.958342]     lock(&irq_desc_lock_class);
[    0.958501] 
                *** DEADLOCK ***

[    0.958715] no locks held by swapper/0/0.
[    0.958870] 
               the shortest dependencies between 2nd lock and 1st lock:
[    0.959152]  -> (&handler->enable_lock){+.+.}-{2:2} {
[    0.959372]     HARDIRQ-ON-W at:
[    0.959522]                       __lock_acquire+0x884/0x1f5c
[    0.959745]                       lock_acquire+0xf0/0x292
[    0.959913]                       _raw_spin_lock+0x2c/0x40
[    0.960090]                       plic_probe+0x322/0x65c
[    0.960257]                       platform_probe+0x4e/0x92
[    0.960432]                       really_probe+0x82/0x210
[    0.960598]                       __driver_probe_device+0x5c/0xd0
[    0.960784]                       driver_probe_device+0x2c/0xb0
[    0.960964]                       __driver_attach+0x72/0x10a
[    0.961151]                       bus_for_each_dev+0x60/0xac
[    0.961330]                       driver_attach+0x1a/0x22
[    0.961496]                       bus_add_driver+0xd4/0x19e
[    0.961666]                       driver_register+0x3e/0xd8
[    0.961835]                       __platform_driver_register+0x1c/0x24
[    0.962030]                       plic_driver_init+0x1a/0x22
[    0.962201]                       do_one_initcall+0x80/0x268
[    0.962371]                       kernel_init_freeable+0x296/0x300
[    0.962554]                       kernel_init+0x1e/0x10a
[    0.962713]                       ret_from_fork+0xe/0x1c
[    0.962884]     SOFTIRQ-ON-W at:
[    0.962994]                       __lock_acquire+0x89e/0x1f5c
[    0.963169]                       lock_acquire+0xf0/0x292
[    0.963336]                       _raw_spin_lock+0x2c/0x40
[    0.963497]                       plic_probe+0x322/0x65c
[    0.963664]                       platform_probe+0x4e/0x92
[    0.963849]                       really_probe+0x82/0x210
[    0.964054]                       __driver_probe_device+0x5c/0xd0
[    0.964255]                       driver_probe_device+0x2c/0xb0
[    0.964428]                       __driver_attach+0x72/0x10a
[    0.964603]                       bus_for_each_dev+0x60/0xac
[    0.964777]                       driver_attach+0x1a/0x22
[    0.964943]                       bus_add_driver+0xd4/0x19e
[    0.965343]                       driver_register+0x3e/0xd8
[    0.965527]                       __platform_driver_register+0x1c/0x24
[    0.965732]                       plic_driver_init+0x1a/0x22
[    0.965908]                       do_one_initcall+0x80/0x268
[    0.966078]                       kernel_init_freeable+0x296/0x300
[    0.966268]                       kernel_init+0x1e/0x10a
[    0.966436]                       ret_from_fork+0xe/0x1c
[    0.966599]     INITIAL USE at:
[    0.966716]                      __lock_acquire+0x3fc/0x1f5c
[    0.966891]                      lock_acquire+0xf0/0x292
[    0.967048]                      _raw_spin_lock+0x2c/0x40
[    0.967206]                      plic_probe+0x322/0x65c
[    0.967360]                      platform_probe+0x4e/0x92
[    0.967522]                      really_probe+0x82/0x210
[    0.967678]                      __driver_probe_device+0x5c/0xd0
[    0.967853]                      driver_probe_device+0x2c/0xb0
[    0.968025]                      __driver_attach+0x72/0x10a
[    0.968185]                      bus_for_each_dev+0x60/0xac
[    0.968348]                      driver_attach+0x1a/0x22
[    0.968513]                      bus_add_driver+0xd4/0x19e
[    0.968678]                      driver_register+0x3e/0xd8
[    0.968839]                      __platform_driver_register+0x1c/0x24
[    0.969035]                      plic_driver_init+0x1a/0x22
[    0.969239]                      do_one_initcall+0x80/0x268
[    0.969431]                      kernel_init_freeable+0x296/0x300
[    0.969610]                      kernel_init+0x1e/0x10a
[    0.969766]                      ret_from_fork+0xe/0x1c
[    0.969936]   }
[    0.970010]   ... key      at: [<ffffffff824f4138>] __key.2+0x0/0x10
[    0.970224]   ... acquired at:
[    0.970353]    lock_acquire+0xf0/0x292
[    0.970482]    _raw_spin_lock+0x2c/0x40
[    0.970609]    plic_irq_enable+0x7e/0x140
[    0.970739]    irq_enable+0x2c/0x60
[    0.970882]    __irq_startup+0x58/0x60
[    0.971008]    irq_startup+0x5e/0x13c
[    0.971126]    __setup_irq+0x4de/0x5da
[    0.971248]    request_threaded_irq+0xcc/0x12e
[    0.971394]    vm_find_vqs+0x62/0x50a
[    0.971518]    probe_common+0xfe/0x1d2
[    0.971635]    virtrng_probe+0xc/0x14
[    0.971751]    virtio_dev_probe+0x154/0x1fc
[    0.971878]    really_probe+0x82/0x210
[    0.972008]    __driver_probe_device+0x5c/0xd0
[    0.972147]    driver_probe_device+0x2c/0xb0
[    0.972280]    __driver_attach+0x72/0x10a
[    0.972407]    bus_for_each_dev+0x60/0xac
[    0.972540]    driver_attach+0x1a/0x22
[    0.972656]    bus_add_driver+0xd4/0x19e
[    0.972777]    driver_register+0x3e/0xd8
[    0.972896]    register_virtio_driver+0x1c/0x2a
[    0.973049]    virtio_rng_driver_init+0x18/0x20
[    0.973236]    do_one_initcall+0x80/0x268
[    0.973399]    kernel_init_freeable+0x296/0x300
[    0.973540]    kernel_init+0x1e/0x10a
[    0.973658]    ret_from_fork+0xe/0x1c

[    0.973858] -> (&irq_desc_lock_class){-...}-{2:2} {
[    0.974036]    IN-HARDIRQ-W at:
[    0.974142]                     __lock_acquire+0xa82/0x1f5c
[    0.974309]                     lock_acquire+0xf0/0x292
[    0.974467]                     _raw_spin_lock+0x2c/0x40
[    0.974625]                     handle_fasteoi_irq+0x24/0x1da
[    0.974794]                     generic_handle_domain_irq+0x1c/0x2a
[    0.974982]                     plic_handle_irq+0x7e/0xf0
[    0.975143]                     generic_handle_domain_irq+0x1c/0x2a
[    0.975329]                     riscv_intc_irq+0x2e/0x46
[    0.975488]                     handle_riscv_irq+0x4a/0x74
[    0.975652]                     call_on_irq_stack+0x32/0x40
[    0.975817]    INITIAL USE at:
[    0.975923]                    __lock_acquire+0x3fc/0x1f5c
[    0.976087]                    lock_acquire+0xf0/0x292
[    0.976244]                    _raw_spin_lock_irqsave+0x3a/0x64
[    0.976423]                    __irq_get_desc_lock+0x5a/0x84
[    0.976594]                    irq_modify_status+0x2a/0x106
[    0.976764]                    irq_set_percpu_devid+0x62/0x78
[    0.976939]                    riscv_intc_domain_map+0x1e/0x54
[    0.977133]                    irq_domain_associate_locked+0x42/0xe4
[    0.977363]                    irq_create_mapping_affinity+0x98/0xd4
[    0.977570]                    sbi_ipi_init+0x70/0x142
[    0.977744]                    init_IRQ+0xfe/0x11a
[    0.977906]                    start_kernel+0x4ae/0x790
[    0.978082]  }
[    0.978151]  ... key      at: [<ffffffff824bbee0>] irq_desc_lock_class+0x0/0x10
[    0.978389]  ... acquired at:
[    0.978494]    mark_lock+0x3fe/0x8c2
[    0.978624]    __lock_acquire+0xa82/0x1f5c
[    0.978766]    lock_acquire+0xf0/0x292
[    0.978897]    _raw_spin_lock+0x2c/0x40
[    0.979029]    handle_fasteoi_irq+0x24/0x1da
[    0.979171]    generic_handle_domain_irq+0x1c/0x2a
[    0.979326]    plic_handle_irq+0x7e/0xf0
[    0.979460]    generic_handle_domain_irq+0x1c/0x2a
[    0.979618]    riscv_intc_irq+0x2e/0x46
[    0.979751]    handle_riscv_irq+0x4a/0x74
[    0.979888]    call_on_irq_stack+0x32/0x40

[    0.980110] 
               stack backtrace:
[    0.980358] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.8.0-rc1-00039-gd9b9d6eb987f #1122
[    0.980662] Hardware name: riscv-virtio,qemu (DT)
[    0.980913] Call Trace:
[    0.981042] [<ffffffff80007198>] dump_backtrace+0x1c/0x24
[    0.981246] [<ffffffff80ae020a>] show_stack+0x2c/0x38
[    0.981456] [<ffffffff80aedac4>] dump_stack_lvl+0x5a/0x7c
[    0.981648] [<ffffffff80aedafa>] dump_stack+0x14/0x1c
[    0.981813] [<ffffffff80ae17a4>] print_irq_inversion_bug.part.0+0x162/0x176
[    0.982031] [<ffffffff8007c6e6>] mark_lock+0x3fe/0x8c2
[    0.982198] [<ffffffff8007d888>] __lock_acquire+0xa82/0x1f5c
[    0.982377] [<ffffffff8007f59e>] lock_acquire+0xf0/0x292
[    0.982549] [<ffffffff80af9962>] _raw_spin_lock+0x2c/0x40
[    0.982721] [<ffffffff8008f3fe>] handle_fasteoi_irq+0x24/0x1da
[    0.982904] [<ffffffff8008a4a4>] generic_handle_domain_irq+0x1c/0x2a
[    0.983112] [<ffffffff80581dc0>] plic_handle_irq+0x7e/0xf0
[    0.983293] [<ffffffff8008a4a4>] generic_handle_domain_irq+0x1c/0x2a
[    0.983495] [<ffffffff8057fb1a>] riscv_intc_irq+0x2e/0x46
[    0.983671] [<ffffffff80aedb4c>] handle_riscv_irq+0x4a/0x74
[    0.983856] [<ffffffff80afa756>] call_on_irq_stack+0x32/0x40


When I switch to -machine virt,aia=aplic-imsic (same config as above), I
get:

[    0.971406] ============================================
[    0.971439] WARNING: possible recursive locking detected
[    0.971497] 6.8.0-rc1-00039-gd9b9d6eb987f #1122 Not tainted
[    0.971583] --------------------------------------------
[    0.971612] swapper/0/1 is trying to acquire lock:
[    0.971662] ffffaf83fefa8e78 (&lpriv->ids_lock){-...}-{2:2}, at: imsic_vector_move+0x92/0x146
[    0.971927] 
               but task is already holding lock:
[    0.971975] ffffaf83fef6ee78 (&lpriv->ids_lock){-...}-{2:2}, at: imsic_vector_move+0x86/0x146
[    0.972045] 
               other info that might help us debug this:
[    0.972085]  Possible unsafe locking scenario:

[    0.972114]        CPU0
[    0.972133]        ----
[    0.972153]   lock(&lpriv->ids_lock);
[    0.972191]   lock(&lpriv->ids_lock);
[    0.972228] 
                *** DEADLOCK ***

[    0.972258]  May be due to missing lock nesting notation

[    0.972306] 6 locks held by swapper/0/1:
[    0.972338]  #0: ffffaf8081f65970 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x6a/0x10a
[    0.972413]  #1: ffffaf808217c240 (&desc->request_mutex){+.+.}-{3:3}, at: __setup_irq+0xa2/0x5da
[    0.972492]  #2: ffffaf808217c0c8 (&irq_desc_lock_class){....}-{2:2}, at: __setup_irq+0xbe/0x5da
[    0.972555]  #3: ffffffff81892ac0 (mask_lock){....}-{2:2}, at: irq_setup_affinity+0x38/0xc6
[    0.972617]  #4: ffffffff81892a80 (tmp_mask_lock){....}-{2:2}, at: irq_do_set_affinity+0x3a/0x164
[    0.972681]  #5: ffffaf83fef6ee78 (&lpriv->ids_lock){-...}-{2:2}, at: imsic_vector_move+0x86/0x146
[    0.972753] 
               stack backtrace:
[    0.972852] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc1-00039-gd9b9d6eb987f #1122
[    0.972900] Hardware name: riscv-virtio,qemu (DT)
[    0.972987] Call Trace:
[    0.973019] [<ffffffff80007198>] dump_backtrace+0x1c/0x24
[    0.973054] [<ffffffff80ae020a>] show_stack+0x2c/0x38
[    0.973083] [<ffffffff80aedac4>] dump_stack_lvl+0x5a/0x7c
[    0.973112] [<ffffffff80aedafa>] dump_stack+0x14/0x1c
[    0.973139] [<ffffffff8007ad5e>] print_deadlock_bug+0x282/0x328
[    0.973168] [<ffffffff8007e15c>] __lock_acquire+0x1356/0x1f5c
[    0.973198] [<ffffffff8007f59e>] lock_acquire+0xf0/0x292
[    0.973225] [<ffffffff80af9adc>] _raw_spin_lock_irqsave+0x3a/0x64
[    0.973255] [<ffffffff80581210>] imsic_vector_move+0x92/0x146
[    0.973285] [<ffffffff80581a04>] imsic_irq_set_affinity+0x8e/0xc6
[    0.973315] [<ffffffff8008c86a>] irq_do_set_affinity+0x142/0x164
[    0.973345] [<ffffffff8008cc22>] irq_setup_affinity+0x68/0xc6
[    0.973374] [<ffffffff8008fa82>] irq_startup+0x72/0x13c
[    0.973401] [<ffffffff8008d40c>] __setup_irq+0x4de/0x5da
[    0.973430] [<ffffffff8008d5d4>] request_threaded_irq+0xcc/0x12e
[    0.973460] [<ffffffff806346d8>] vp_find_vqs_msix+0x114/0x376
[    0.973491] [<ffffffff80634970>] vp_find_vqs+0x36/0x136
[    0.973518] [<ffffffff80633280>] vp_modern_find_vqs+0x16/0x4e
[    0.973547] [<ffffffff80ab31f8>] p9_virtio_probe+0x8e/0x31c
[    0.973576] [<ffffffff8062d982>] virtio_dev_probe+0x154/0x1fc
[    0.973605] [<ffffffff80693738>] really_probe+0x82/0x210
[    0.973632] [<ffffffff80693922>] __driver_probe_device+0x5c/0xd0
[    0.973661] [<ffffffff806939c2>] driver_probe_device+0x2c/0xb0
[    0.973690] [<ffffffff80693b46>] __driver_attach+0x72/0x10a
[    0.973718] [<ffffffff8069191a>] bus_for_each_dev+0x60/0xac
[    0.973746] [<ffffffff80693164>] driver_attach+0x1a/0x22
[    0.973773] [<ffffffff80692ade>] bus_add_driver+0xd4/0x19e
[    0.973801] [<ffffffff8069487e>] driver_register+0x3e/0xd8
[    0.973829] [<ffffffff8062d1ce>] register_virtio_driver+0x1c/0x2a
[    0.973858] [<ffffffff80c3da52>] p9_virtio_init+0x36/0x56
[    0.973887] [<ffffffff800028fe>] do_one_initcall+0x80/0x268
[    0.973915] [<ffffffff80c01144>] kernel_init_freeable+0x296/0x300
[    0.973944] [<ffffffff80af05dc>] kernel_init+0x1e/0x10a
[    0.973972] [<ffffffff80afa716>] ret_from_fork+0xe/0x1c


FWIW, the full Qemu command I used was as follows:

	sudo /home/andrea/Downloads/qemu/build/qemu-system-riscv64 \
		-append "root=/dev/root rw rootfstype=9p rootflags=version=9p2000.L,trans=virtio,cache=mmap,access=any raid=noautodetect security=none loglevel=7" \
		-cpu rv64,sv57=off,svadu=off,svnapot=off \
		-device virtio-net-device,netdev=net0 \
		-device virtio-rng-device,rng=rng0 \
		-device virtio-9p-pci,fsdev=root,mount_tag=/dev/root \
		-fsdev local,id=root,path=/home/andrea/Downloads/jammy/,security_model=none \
		-kernel /home/andrea/linux/arch/riscv/boot/Image \
		-m 16G \
		-machine virt,aia=<either "none" or "aplic-imsic"> \
		-monitor telnet:127.0.0.1:55555,server,nowait \
		-netdev user,id=net0,host=10.0.2.10,hostfwd=tcp::10022-:22 \
		-nographic \
		-object rng-random,filename=/dev/urandom,id=rng0 \
		-serial mon:stdio \
		-smp 5


  Andrea


From Jonathan.Cameron at Huawei.com  Thu Feb  8 02:10:52 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 10:10:52 +0000
Subject: [PATCH v3] perf: CXL: fix mismatched cpmu event opcode
In-Reply-To: <20240208013415epcms2p2904187c8a863f4d0d2adc980fb91a2dc@epcms2p2>
References: <CGME20240208013415epcms2p2904187c8a863f4d0d2adc980fb91a2dc@epcms2p2>
	<20240208013415epcms2p2904187c8a863f4d0d2adc980fb91a2dc@epcms2p2>
Message-ID: <20240208101052.000018d7@Huawei.com>

On Thu, 08 Feb 2024 10:34:15 +0900
Hojin Nam <hj96.nam at samsung.com> wrote:

> S2M NDR BI-ConflictAck opcode is described as 4 in the CXL
> r3.0 3.3.9 Table 3.43. However, it is defined as 3 in macro definition.
> 
> Fixes: 5d7107c72796 ("perf: CXL Performance Monitoring Unit driver")
> Signed-off-by: Hojin Nam <hj96.nam at samsung.com>

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

Thanks,

Jonathan

> ---
> 
> Hi Jonathan,
> Sorry, I misunderstood your guide. 
> I roll-backed to v1 patch keeping fixes tag. Thank you!
> 
> Changes since v2:
> - Remove s2m_ndr_cmpm attribute and referecne added at v2 (Jonathan)
> 
> Changes since v1:
> - Add s2m_ndr_cmpm event attribute
> - Add fixes tag (Jonathan)
> 
> 
>  drivers/perf/cxl_pmu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
> index 365d964b0f6a..bc0d414a6aff 100644
> --- a/drivers/perf/cxl_pmu.c
> +++ b/drivers/perf/cxl_pmu.c
> @@ -419,7 +419,7 @@ static struct attribute *cxl_pmu_event_attrs[] = {
>         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmp,                     CXL_PMU_GID_S2M_NDR, BIT(0)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmps,                    CXL_PMU_GID_S2M_NDR, BIT(1)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmpe,                    CXL_PMU_GID_S2M_NDR, BIT(2)),
> -       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(3)),
> +       CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack,           CXL_PMU_GID_S2M_NDR, BIT(4)),
>         /* CXL rev 3.0 Table 3-46 S2M DRS opcodes */
>         CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdata,                 CXL_PMU_GID_S2M_DRS, BIT(0)),
>         CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdatanxm,              CXL_PMU_GID_S2M_DRS, BIT(1)),
> --
> 2.34.1



From zev at bewilderbeest.net  Thu Feb  8 02:17:27 2024
From: zev at bewilderbeest.net (Zev Weiss)
Date: Thu, 8 Feb 2024 02:17:27 -0800
Subject: [PATCH 0/2] ARM: prctl: Reject PR_SET_MDWE where not supported
In-Reply-To: <ZcSc+ftxHY8RyinQ@shell.armlinux.org.uk>
References: <20240208012620.32604-4-zev@bewilderbeest.net>
 <ZcSc+ftxHY8RyinQ@shell.armlinux.org.uk>
Message-ID: <3c8dd43f-9ab0-4b98-bad2-71c5f3da0348@hatter.bewilderbeest.net>

On Thu, Feb 08, 2024 at 01:20:57AM PST, Russell King (Oracle) wrote:
>Hi,
>
>Where is patch 1 of this series? It doesn't seem to have been Cc'd to
>linux-arm-kernel. Therefore, this can't be reviewed.
>

It went to (among others) the linux-parisc list, but not 
linux-arm-kernel as scripts/get_maintainers.pl didn't list it for that 
patch:
https://lore.kernel.org/lkml/20240208012620.32604-5-zev at bewilderbeest.net/

I think I've gotten differing opinions from different subsystem 
maintainers on this, but FWIW my usual default approach is to use 
scripts/get_maintainer.pl on each patch and then add the set-union of 
them all to the cover letter for context; I'll try to remember the 
preference for linux-arm-kernel though.

Is the link above sufficient for now, or shall I resend the series?


Thanks,
Zev


>Thanks.
>
>On Wed, Feb 07, 2024 at 05:26:18PM -0800, Zev Weiss wrote:
>> Hello,
>>
>> I noticed after a recent kernel update that my ARM926 system started
>> segfaulting on any execve() after calling prctl(PR_SET_MDWE).  After
>> some investigation it appears that ARMv5 is incapable of providing the
>> appropriate protections for MDWE, since any readable memory is also
>> implicitly executable.
>>
>> (Note that I'm not an expert in either ARM arch details or the mm
>> subsystem, so please bear with me if I've botched something in the
>> above analysis.)
>>
>> The prctl_set_mdwe() function already had some special-case logic
>> added disabling it on PARISC (commit 793838138c15, "prctl: Disable
>> prctl(PR_SET_MDWE) on parisc"); this patch series (1) generalizes that
>> check to use an arch_*() function, and (2) adds a corresponding
>> override for ARM to disable MDWE on pre-ARMv6 CPUs.
>>
>> With the series applied, prctl(PR_SET_MDWE) is rejected on ARMv5 and
>> subsequent execve() calls (as well as mmap(PROT_READ|PROT_WRITE)) can
>> succeed instead of unconditionally failing; on ARMv6 the prctl works
>> as it did previously.
>>
>> Since this was effectively a userspace-breaking change in v6.3 (with
>> newer MDWE-aware userspace on older pre-MDWE kernels the prctl would
>> simply fail safely) I've CCed -stable for v6.3+, though since the
>> patches depend on the PARISC one above it will only apply cleanly on
>> the linux-6.6.y and linux-6.7.y branches, since at least at time of
>> writing the 6.3 through 6.5 branches don't have that patch backported
>> (due to further missing dependencies [0]).
>>
>>
>> Thanks,
>> Zev
>>
>> [0] https://lore.kernel.org/all/2023112456-linked-nape-bf19 at gregkh/
>>
>> Zev Weiss (2):
>>   prctl: Generalize PR_SET_MDWE support check to be per-arch
>>   ARM: prctl: Reject PR_SET_MDWE on pre-ARMv6
>>
>>  arch/arm/include/asm/mman.h    | 14 ++++++++++++++
>>  arch/parisc/include/asm/mman.h | 14 ++++++++++++++
>>  include/linux/mman.h           |  8 ++++++++
>>  kernel/sys.c                   |  7 +++++--
>>  4 files changed, 41 insertions(+), 2 deletions(-)
>>  create mode 100644 arch/arm/include/asm/mman.h
>>  create mode 100644 arch/parisc/include/asm/mman.h
>>
>> --
>> 2.43.0
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>
>-- 
>RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
>FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


From j-luthra at ti.com  Thu Feb  8 02:19:16 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 8 Feb 2024 15:49:16 +0530
Subject: [PATCH v2 9/9] arm64: dts: ti: k3-j721e-sk: Add overlay for
 IMX219
In-Reply-To: <20240208084254.295289-10-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
 <20240208084254.295289-10-vaishnav.a@ti.com>
Message-ID: <ldviqflcfc55gas3fwkldgdjrlcuiudr7iw5yutjqwsyhlr7fs@h3hbcypsukiw>

Hi Vaishnav,

Thanks for the patch.

On Feb 08, 2024 at 14:12:54 +0530, Vaishnav Achath wrote:
> RPi v2 Camera (IMX219) is an 8MP camera that can be used with SK-AM69,
> J721E SK, and AM68 SK through the 22-pin CSI-RX connector.
> 
> Add a reference overlay for dual IMX219 RPI camera v2 modules
> which can be used across AM68 SK, AM69 SK, TDA4VM SK boards
> that have a 15/22-pin FFC connector. Also enable build testing
> and symbols for all the three platforms.
> 
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>

Reviewed-by: Jai Luthra <j-luthra at ti.com>

> ---
> 
> V1->V2:
>  * Rename overlays to indicate first platform (j721e-sk) supported
>    and dual camera.
>  * Add missed build test, fix missing newline.
> 
>  arch/arm64/boot/dts/ti/Makefile               |  13 ++
>  .../dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso  | 125 ++++++++++++++++++
>  2 files changed, 138 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso
> 
> [...] 
>

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240208/6e0c7121/attachment.sig>

From j-luthra at ti.com  Thu Feb  8 02:21:49 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 8 Feb 2024 15:51:49 +0530
Subject: [PATCH v2 6/9] arm64: dts: ti: k3-j721e-main: Add CSI2RX capture
 nodes
In-Reply-To: <20240208084254.295289-7-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
 <20240208084254.295289-7-vaishnav.a@ti.com>
Message-ID: <wul2gec2tcoetofczwhro2firk5hofh4hk4pdpkw7ltilsy4da@fwxtdkwd3r7q>

Hi Vaishnav,

Thanks for the patch.

On Feb 08, 2024 at 14:12:51 +0530, Vaishnav Achath wrote:
> J721E has two CSI2RX capture subsystem featuring Cadence CSI2RX,
> DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
> keep them disabled by default.
> 
> J721E TRM (Section 12.7 Camera Subsystem):
> 	https://www.ti.com/lit/zip/spruil1
> 
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
> ---
> 
> V1->V2: Update commit message with TRM.
> 
>  arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 122 ++++++++++++++++++++++
>  1 file changed, 122 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
> index 062a6fca5a31..8df1eed80996 100644
> --- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
> @@ -572,6 +572,128 @@ main_timerio_output: pinctrl at 104280 {
>  		pinctrl-single,function-mask = <0x0000001f>;
>  	};
>  
> +	ti_csi2rx0: ticsi2rx at 4500000 {
> +		compatible = "ti,j721e-csi2rx-shim";
> +		dmas = <&main_udmap 0x4940>;
> +		dma-names = "rx0";
> +		reg = <0x0 0x4500000 0x0 0x1000>;
> +		power-domains = <&k3_pds 26 TI_SCI_PD_EXCLUSIVE>;
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +		status = "disabled";
> +
> +		cdns_csi2rx0: csi-bridge at 4504000 {
> +			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
> +			reg = <0x0 0x4504000 0x0 0x1000>;
> +			clocks = <&k3_clks 26 2>, <&k3_clks 26 0>, <&k3_clks 26 2>,
> +				<&k3_clks 26 2>, <&k3_clks 26 3>, <&k3_clks 26 3>;
> +			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
> +				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
> +			phys = <&dphy0>;
> +			phy-names = "dphy";

New nodes should follow the property order as described in the dts 
coding style:
https://www.kernel.org/doc/html/latest/devicetree/bindings/dts-coding-style.html

For reference, I tried to do the same for my AM62P CSI series:
https://lore.kernel.org/all/20240201-am62p_csi-v1-3-c83bb9eaeb49 at ti.com/

Same comment applies to PATCH 7 and 8 as well.

> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				csi0_port0: port at 0 {
> +					reg = <0>;
> +					status = "disabled";
> +				};
> +
> +				csi0_port1: port at 1 {
> +					reg = <1>;
> +					status = "disabled";
> +				};
> +
> +				csi0_port2: port at 2 {
> +					reg = <2>;
> +					status = "disabled";
> +				};
> +
> +				csi0_port3: port at 3 {
> +					reg = <3>;
> +					status = "disabled";
> +				};
> +
> +				csi0_port4: port at 4 {
> +					reg = <4>;
> +					status = "disabled";
> +				};
> +			};
> +		};
> +	};
> +
> +	ti_csi2rx1: ticsi2rx at 4510000 {
> +		compatible = "ti,j721e-csi2rx-shim";
> +		dmas = <&main_udmap 0x4960>;
> +		dma-names = "rx0";
> +		reg = <0x0 0x4510000 0x0 0x1000>;
> +		power-domains = <&k3_pds 27 TI_SCI_PD_EXCLUSIVE>;
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +		status = "disabled";
> +
> +		cdns_csi2rx1: csi-bridge at 4514000 {
> +			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
> +			reg = <0x0 0x4514000 0x0 0x1000>;
> +			clocks = <&k3_clks 27 2>, <&k3_clks 27 0>, <&k3_clks 27 2>,
> +				 <&k3_clks 27 2>, <&k3_clks 27 3>, <&k3_clks 27 3>;
> +			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
> +				      "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
> +			phys = <&dphy1>;
> +			phy-names = "dphy";
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				csi1_port0: port at 0 {
> +					reg = <0>;
> +					status = "disabled";
> +				};
> +
> +				csi1_port1: port at 1 {
> +					reg = <1>;
> +					status = "disabled";
> +				};
> +
> +				csi1_port2: port at 2 {
> +					reg = <2>;
> +					status = "disabled";
> +				};
> +
> +				csi1_port3: port at 3 {
> +					reg = <3>;
> +					status = "disabled";
> +				};
> +
> +				csi1_port4: port at 4 {
> +					reg = <4>;
> +					status = "disabled";
> +				};
> +			};
> +		};
> +	};
> +
> +	dphy0: phy at 4580000 {
> +		compatible = "cdns,dphy-rx";
> +		reg = <0x0 0x4580000 0x0 0x1100>;
> +		#phy-cells = <0>;
> +		power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
> +	};
> +
> +	dphy1: phy at 4590000 {
> +		compatible = "cdns,dphy-rx";
> +		reg = <0x0 0x4590000 0x0 0x1100>;
> +		#phy-cells = <0>;
> +		power-domains = <&k3_pds 148 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
> +	};
> +
>  	serdes_wiz0: wiz at 5000000 {
>  		compatible = "ti,j721e-wiz-16g";
>  		#address-cells = <1>;
> -- 
> 2.34.1
> 

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240208/275058f1/attachment-0001.sig>

From j-luthra at ti.com  Thu Feb  8 02:23:09 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 8 Feb 2024 15:53:09 +0530
Subject: [PATCH v2 1/9] arm64: dts: ti: k3-j721s2-common-proc-board:
 Enable camera peripherals
In-Reply-To: <20240208084254.295289-2-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
 <20240208084254.295289-2-vaishnav.a@ti.com>
Message-ID: <sdzlljxyxhfffddg6iyviwv7idivknwsauqzs73fmcpmi3zvvi@ymeshye735pz>

On Feb 08, 2024 at 14:12:46 +0530, Vaishnav Achath wrote:
> CSI cameras are controlled using I2C. On J721S2 Common Processor Board,
> this is routed to I2C-5, so enable the instance and the TCA6408
> GPIO expander on the bus.
> 
> Common Processor Board schematics: https://www.ti.com/lit/zip/sprr411
> J721S2 SoM schematics: https://www.ti.com/lit/zip/sprr439
> 
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>

Reviewed-by: Jai Luthra <j-luthra at ti.com>

> ---
> 
> V1->V2: Update commit message with schematics.
> 
>  .../dts/ti/k3-j721s2-common-proc-board.dts    | 25 +++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> [...] 

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240208/57a27f2e/attachment.sig>

From j-luthra at ti.com  Thu Feb  8 02:23:56 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 8 Feb 2024 15:53:56 +0530
Subject: [PATCH v2 2/9] arm64: dts: ti: k3-j784s4-evm: Enable camera
 peripherals
In-Reply-To: <20240208084254.295289-3-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
 <20240208084254.295289-3-vaishnav.a@ti.com>
Message-ID: <hp2dfxyhx2qmxgpyily5aksjditkkd5fqfgketec3um33fuxlg@dqaxoqcspg3v>

On Feb 08, 2024 at 14:12:47 +0530, Vaishnav Achath wrote:
> CSI cameras are controlled using I2C. On J784S4 EVM, this is routed
> to I2C-5, so enable the instance and the TCA6408 GPIO expander
> on the bus.
> 
> J784S4 EVM schematics: https://www.ti.com/lit/zip/sprr458
> 
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>

Reviewed-by: Jai Luthra <j-luthra at ti.com>

> ---
> 
> V1->V2: Update commit message with schematics.
> 
>  arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 25 ++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> [...]
> 

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240208/0d59bf73/attachment.sig>

From j-luthra at ti.com  Thu Feb  8 02:24:29 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 8 Feb 2024 15:54:29 +0530
Subject: [PATCH v2 3/9] arm64: dts: ti: k3-am68-sk-base-board: Enable
 camera peripherals
In-Reply-To: <20240208084254.295289-4-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
 <20240208084254.295289-4-vaishnav.a@ti.com>
Message-ID: <apb7w6l5rgsd4ghzr4jvmlwujuw7ksmuxzgurq5zyoglydlvux@fznvmwzzyfxs>

On Feb 08, 2024 at 14:12:48 +0530, Vaishnav Achath wrote:
> CSI cameras are controlled using I2C. On AM68 Starter Kit, this is routed
> to I2C-1, so enable the instance and the TCA9543 I2C switch on the bus.
> 
> AM68 SK schematics: https://www.ti.com/lit/zip/sprr463
> 
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>

Reviewed-by: Jai Luthra <j-luthra at ti.com>

> ---
> 
> V1->V2: Update commit message with schematics.
> 
>  .../boot/dts/ti/k3-am68-sk-base-board.dts     | 50 +++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> [...] 

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240208/240c68c7/attachment.sig>

From j-luthra at ti.com  Thu Feb  8 02:27:08 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 8 Feb 2024 15:57:08 +0530
Subject: [PATCH v2 4/9] arm64: dts: ti: k3-am69-sk: Enable camera
 peripherals
In-Reply-To: <20240208084254.295289-5-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
 <20240208084254.295289-5-vaishnav.a@ti.com>
Message-ID: <wbvrqqpf7hhpgwgtsjkoblja4gxr22mgt7ehwoy7qokeds4wna@rljhzoapwevw>

On Feb 08, 2024 at 14:12:49 +0530, Vaishnav Achath wrote:
> CSI cameras are controlled using I2C. On AM69 Starter Kit, this is routed
> to I2C-1, so enable the instance, TCA9543 I2C switch and the TCA6408
> GPIO expander on the bus. AM69 SK has the CSI2RX routed to a MIPI CSI
> connector and to 22-pin RPi camera connector through an analog mux with
> GPIO control, model that so that an overlay can control the mux state
> according to connected cameras.
> 
> AM69 SK schematics: https://www.ti.com/lit/zip/sprr466
> 
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>

Reviewed-by: Jai Luthra <j-luthra at ti.com>

> ---
> 
> V1->V2: Update commit message with schematics.
> 
>  arch/arm64/boot/dts/ti/k3-am69-sk.dts | 51 +++++++++++++++++++++++++++
>  1 file changed, 51 insertions(+)
> 
> [...] 

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240208/8720fd60/attachment.sig>

From j-luthra at ti.com  Thu Feb  8 02:28:19 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Thu, 8 Feb 2024 15:58:19 +0530
Subject: [PATCH v2 5/9] arm64: dts: ti: k3-j721e-sk: Model CSI2RX
 connector mux
In-Reply-To: <20240208084254.295289-6-vaishnav.a@ti.com>
References: <20240208084254.295289-1-vaishnav.a@ti.com>
 <20240208084254.295289-6-vaishnav.a@ti.com>
Message-ID: <5klycf32whuy5k7s2jcivpgkaomtanudn72pxkktea3i5wbpdm@d37czhrqxsud>

On Feb 08, 2024 at 14:12:50 +0530, Vaishnav Achath wrote:
> J721E SK has the CSI2RX routed to a MIPI CSI connector and to 15-pin
> RPi camera connector through an analog mux with GPIO control, model that
> so that an overlay can control the mux state according to connected
> cameras. Also provide labels to the I2C mux bus instances so that a
> generic overlay can be used across multiple platforms.
> 
> J721E SK schematics: https://www.ti.com/lit/zip/sprr438
> 
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>

Reviewed-by: Jai Luthra <j-luthra at ti.com>

> ---
> 
> V1->V2: Update commit message with schematics.
> 
>  arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> [...] 

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240208/20a92f97/attachment-0001.sig>

From kurt at linutronix.de  Thu Feb  8 02:35:25 2024
From: kurt at linutronix.de (Kurt Kanzenbach)
Date: Thu, 08 Feb 2024 11:35:25 +0100
Subject: [PATCH net-next] net: stmmac: Simplify mtl IRQ status checking
Message-ID: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>

Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO overflow
interrupts") disabled the RX FIFO overflow interrupts. However, it left the
status variable around, but never checks it.

As stmmac_host_mtl_irq_status() returns only 0 now, the code can be
simplified.

Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 04d817dc5899..10ce2f272b62 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -6036,10 +6036,8 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv)
 				priv->tx_path_in_lpi_mode = false;
 		}
 
-		for (queue = 0; queue < queues_count; queue++) {
-			status = stmmac_host_mtl_irq_status(priv, priv->hw,
-							    queue);
-		}
+		for (queue = 0; queue < queues_count; queue++)
+			stmmac_host_mtl_irq_status(priv, priv->hw, queue);
 
 		/* PCS link status */
 		if (priv->hw->pcs &&

---
base-commit: 006e89649fa913e285b931f1b8dfd6485d153ca7
change-id: 20240208-stmmac_irq-57682fa778c9

Best regards,
-- 
Kurt Kanzenbach <kurt at linutronix.de>



From lee at kernel.org  Thu Feb  8 02:38:21 2024
From: lee at kernel.org (Lee Jones)
Date: Thu, 08 Feb 2024 10:38:21 +0000
Subject: (subset) [linux][PATCH v5 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <20240131033523.577450-4-dharma.b@microchip.com>
References: <20240131033523.577450-1-dharma.b@microchip.com>
 <20240131033523.577450-4-dharma.b@microchip.com>
Message-ID: <170738870103.916068.17422553727568917627.b4-ty@kernel.org>

On Wed, 31 Jan 2024 09:05:23 +0530, Dharma Balasubiramani wrote:
> Convert the atmel,hlcdc binding to DT schema format.
> 
> Align clocks and clock-names properties to clearly indicate that the LCD
> controller expects lvds_pll_clk when interfaced with the lvds display. This
> alignment with the specific hardware requirements ensures accurate device tree
> configuration for systems utilizing the HLCDC IP.
> 
> [...]

Applied, thanks!

[3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
      commit: 7dd93269787781869d3dbb23138ec1455d26b047

--
Lee Jones [???]



From lee at kernel.org  Thu Feb  8 02:43:12 2024
From: lee at kernel.org (Lee Jones)
Date: Thu, 08 Feb 2024 10:43:12 +0000
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <20240202001733.91455-4-dharma.b@microchip.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
Message-ID: <170738899221.920003.15342446791449663430.b4-ty@kernel.org>

On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
> Convert the atmel,hlcdc binding to DT schema format.
> 
> Align clocks and clock-names properties to clearly indicate that the LCD
> controller expects lvds_pll_clk when interfaced with the lvds display. This
> alignment with the specific hardware requirements ensures accurate device tree
> configuration for systems utilizing the HLCDC IP.
> 
> [...]

Applied, thanks!

[3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
      commit: cb946db1335b599ece363d33966bf653ed0fa58a

--
Lee Jones [???]



From lee at kernel.org  Thu Feb  8 02:43:44 2024
From: lee at kernel.org (Lee Jones)
Date: Thu, 8 Feb 2024 10:43:44 +0000
Subject: (subset) [linux][PATCH v5 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <170738870103.916068.17422553727568917627.b4-ty@kernel.org>
References: <20240131033523.577450-1-dharma.b@microchip.com>
 <20240131033523.577450-4-dharma.b@microchip.com>
 <170738870103.916068.17422553727568917627.b4-ty@kernel.org>
Message-ID: <20240208104344.GG689448@google.com>

On Thu, 08 Feb 2024, Lee Jones wrote:

> On Wed, 31 Jan 2024 09:05:23 +0530, Dharma Balasubiramani wrote:
> > Convert the atmel,hlcdc binding to DT schema format.
> > 
> > Align clocks and clock-names properties to clearly indicate that the LCD
> > controller expects lvds_pll_clk when interfaced with the lvds display. This
> > alignment with the specific hardware requirements ensures accurate device tree
> > configuration for systems utilizing the HLCDC IP.
> > 
> > [...]
> 
> Applied, thanks!
> 
> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
>       commit: 7dd93269787781869d3dbb23138ec1455d26b047

Replaced with v6.

-- 
Lee Jones [???]


From devarsht at ti.com  Thu Feb  8 02:43:48 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Thu, 8 Feb 2024 16:13:48 +0530
Subject: [RFC PATCH 1/3] dt-bindings: display: ti,am65x-dss: Add support
 for display sharing mode
In-Reply-To: <CAL_JsqKVMs92DkzVTmOuJzxzcm90SGOmwQXdk=kydBa5S_ySmg@mail.gmail.com>
References: <20240116134142.2092483-1-devarsht@ti.com>
 <20240116134142.2092483-2-devarsht@ti.com>
 <20240117201342.GA3041972-robh@kernel.org>
 <57805224-f4f9-7773-03e3-4bdff8936c9c@ti.com>
 <CAL_JsqKVMs92DkzVTmOuJzxzcm90SGOmwQXdk=kydBa5S_ySmg@mail.gmail.com>
Message-ID: <96af9fac-aad6-747d-dd89-295c7309f535@ti.com>

Hi Rob,

Thanks for the review.

On 19/01/24 19:25, Rob Herring wrote:
> On Thu, Jan 18, 2024 at 7:59?AM Devarsh Thakkar <devarsht at ti.com> wrote:
>>
>> Hi Rob,
>>
>> Thanks for the quick review.
>>
>> On 18/01/24 01:43, Rob Herring wrote:
>>> On Tue, Jan 16, 2024 at 07:11:40PM +0530, Devarsh Thakkar wrote:
>>>> Add support for using TI Keystone DSS hardware present in display
>>>> sharing mode.
>>>>
>>>> TI Keystone DSS hardware supports partitioning of resources between
>>>> multiple hosts as it provides separate register space and unique
>>>> interrupt line to each host.
>>>>
>>>> The DSS hardware can be used in shared mode in such a way that one or
>>>> more of video planes can be owned by Linux wherease other planes can be
>>>> owned by remote cores.
>>>>
>>>> One or more of the video ports can be dedicated exclusively to a
>>>> processing core, wherease some of the video ports can be shared between
>>>> two hosts too with only one of them having write access.
>>>>
>>>> Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
>>>> ---
>>>>  .../bindings/display/ti/ti,am65x-dss.yaml     | 82 +++++++++++++++++++
>>>>  1 file changed, 82 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
>>>> index 55e3e490d0e6..d9bc69fbf1fb 100644
>>>> --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
>>>> +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
>>>> @@ -112,6 +112,86 @@ properties:
>>>>        Input memory (from main memory to dispc) bandwidth limit in
>>>>        bytes per second
>>>>
>>>> +  ti,dss-shared-mode:
>>>> +    type: boolean
>>>> +    description:
>>>> +      TI DSS7 supports sharing of display between multiple hosts
>>>> +      as it provides separate register space for display configuration and
>>>> +      unique interrupt line to each host.
>>>
>>> If you care about line breaks, you need '|'.
>>>
>>
>> Noted.
>>
>>>> +      One of the host is provided access to the global display
>>>> +      configuration labelled as "common" region of DSS allows that host
>>>> +      exclusive access to global registers of DSS while other host can
>>>> +      configure the display for it's usage using a separate register
>>>> +      space labelled as "common1".
>>>> +      The DSS resources can be partitioned in such a way that one or more
>>>> +      of the video planes are owned by Linux whereas other video planes
>>>
>>> Your h/w can only run Linux?
>>>
>>> What if you want to use this same binding to define the configuration to
>>> the 'remote processor'? You can easily s/Linux/the OS/, but it all
>>> should be reworded to describe things in terms of the local processor.
>>>
>>
>> It can run both Linux and RTOS or for that matter any other OS too. But yes I
>> got your point, will reword accordingly.
>>
>>>> +      can be owned by a remote core.
>>>> +      The video port controlling these planes acts as a shared video port
>>>> +      and it can be configured with write access either by Linux or the
>>>> +      remote core in which case Linux only has read-only access to that
>>>> +      video port.
>>>
>>> What is the purpose of this property when all the other properties are
>>> required?
>>>
>>
>> The ti,dss-shared-mode and below group of properties are optional. But
>> if ti,dss-shared-mode is set then only driver should parse below set of
>> properties.
> 
> Let me re-phrase. Drop this property. It serves no purpose since all
> the properties have to be present anyway.
> 

Noted.

>>>> +  ti,dss-shared-mode-planes:
>>>> +    description:
>>>> +      The video layer that is owned by processing core running Linux.
>>>> +      The display driver running from Linux has exclusive write access to
>>>> +      this video layer.
>>>> +    $ref: /schemas/types.yaml#/definitions/string
>>>> +    enum: [vidl, vid]
>>>> +
>>>> +  ti,dss-shared-mode-vp:
>>>> +    description:
>>>> +      The video port that is being used in context of processing core
>>>> +      running Linux with display susbsytem being used in shared mode.
>>>> +      This can be owned either by the processing core running Linux in
>>>> +      which case Linux has the write access and the responsibility to
>>>> +      configure this video port and the associated overlay manager or
>>>> +      it can be shared between core running Linux and a remote core
>>>> +      with remote core provided with write access to this video port and
>>>> +      associated overlay managers and remote core configures and drives
>>>> +      this video port also feeding data from one or more of the
>>>> +      video planes owned by Linux, with Linux only having read-only access
>>>> +      to this video port and associated overlay managers.
>>>> +
>>>> +    $ref: /schemas/types.yaml#/definitions/string
>>>> +    enum: [vp1, vp2]
>>>> +
>>>> +  ti,dss-shared-mode-common:
>>>> +    description:
>>>> +      The DSS register region owned by processing core running Linux.
>>>> +    $ref: /schemas/types.yaml#/definitions/string
>>>> +    enum: [common, common1]
>>>> +
>>>> +  ti,dss-shared-mode-vp-owned:
>>>> +    description:
>>>> +      This tells whether processing core running Linux has write access to
>>>> +      the video ports enlisted in ti,dss-shared-mode-vps.
>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>> +    enum: [0, 1]
>>>
>>> This can be boolean. Do writes abort or just get ignored? The latter can
>>> be probed and doesn't need a property.
>>>
>>
>> Although we have kept all these properties as enums, but actually in driver we
>> are treating them as array of enums and using device_property_read_u32_array.
>>
>> The reason being that for SoCs using am65x-dss bindings they can only have
>> single entry either vp1 or vp2 or 0 or 1 as there are only two video ports. So
>> for them the device tree overlay would look like :
>> &dss0 {
>>
>>         ti,dss-shared-mode;
>>
>>         ti,dss-shared-mode-vp = "vp1";
>>
>>         ti,dss-shared-mode-vp-owned = <0>;
>>
>>         ti,dss-shared-mode-common = "common1";
>>
>>         ti,dss-shared-mode-planes = "vid";
>>
>>         ti,dss-shared-mode-plane-zorder = <0>;
>>
>>         interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_>;
>> }
>>
>> But we also plan to extend these bindings to SoCs using
>> Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml where there are
>> multiple video ports. So in that the driver and bindings should support below
>> configuration :
> 
> What are you waiting for? In that case, all these properties need to
> be in a shared schema file and referenced here. Otherwise you will be
> defining their types twice (and different types too if some are
> changed to arrays).
> 

Noted, thanks for suggesting this, shared schema file indeed looks like
a better idea.

>> &dss0 {
>>
>>         ti,dss-shared-mode;
>>
>>         ti,dss-shared-mode-vp = "vp1 vp2";
>>
>>         ti,dss-shared-mode-vp-owned = <0 1>;
>>
>>         ti,dss-shared-mode-common = "common_s1";
>>
>>         ti,dss-shared-mode-planes = "vid1 vidl1";
>>
>>         ti,dss-shared-mode-plane-zorder = <0 1>;
>>
>>         interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_>;
>> }
>>
>> As I am using device_property_read_u32_array in driver I thought to keep this
>> as uint32 in enum for am65x.yaml which works well with the driver.
> 
> The type and what accessor functions the kernel uses should match. I
> plan to add (debug) checking on this. Debug only because as there's no
> type info in the DTB, it all has to be extracted from schemas and put
> into the kernel.
> 

Yes, with the shared schema it should be array instead of integer.

>>>> +
>>>> +  ti,dss-shared-mode-plane-zorder:
>>>> +    description:
>>>> +      The zorder of the planes owned by Linux.
>>>> +      For the scenario where Linux is not having write access to associated
>>>> +      video port, this field is just for
>>>> +      informational purpose to enumerate the zorder configuration
>>>> +      being used by remote core.
>>>> +
>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>> +    enum: [0, 1]
>>>
>>> I don't understand how 0 or 1 defines Z-order.
>>>
>>
>> As there are only two planes in total so z-order can be either 0 or 1 for the
>> shared mode plane as there is only a single entry of plane.
>> For e.g. if ti,dss-shared-mode-plane-zorder is 1 then it means the plane owned
>> by Linux is programmed as topmost plane wherease the plane owned by remote
>> core is programmed as the underneath one.
> 
> Please reword the description to make all this clear. The index is the
> plane number and value is the z-order with 0 being bottom and N being
> the top. I guess this should be an array as well.
> 


Yes, this was kept as uint32 since with am65x-dss only one plane was
available for sharing, but with the shared schema this too should be an
array instead of integer.

Regards
Devarsh

> Rob
> 


From Jonathan.Cameron at Huawei.com  Thu Feb  8 02:46:42 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 10:46:42 +0000
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <20240208032518.25830-1-yangyicong@huawei.com>
References: <20240208032518.25830-1-yangyicong@huawei.com>
Message-ID: <20240208104642.000001ad@Huawei.com>

On Thu, 8 Feb 2024 11:25:18 +0800
Yicong Yang <yangyicong at huawei.com> wrote:

> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
> throughput and latency of PCIe traffic. With the support of PCIe PMU
> we can enable the perf iostat mode.
> 
> The HiSilicon PCIe PMU can support measuring the throughput of certain
> TLP types and of certain root port. Totally 6 metrics are provided in
> the unit of MB:
> 
> - Inbound MWR: The memory write TLPs from the devices downstream the root port
> - Inbound MRD: The memory read TLPs from the devices downstream the root port
> - Inbound CPL: The completion TLPs from the devices downstream the root port
> - Outbound MWR: The memory write TLPs from the CPU to the downstream devices
> - Outbound MRD: The memory read TLPs from the CPU to the downstream devices
> - Outbound CPL: The completions TLPs from the CPU to the downstream devices
> 
> Since the PMU measures the throughput in DWords. So we need to calculate
> the throughput in MB like:
>   Count * 4B / 1024 / 1024
> 
> Some of the display of the `perf iostat` will be like:
> [root at localhost tmp]# ./perf iostat list
> hisi_pcie0_core2<0000:40:00.0>
> hisi_pcie2_core2<0000:5f:00.0>
> hisi_pcie0_core1<0000:16:00.0>
> hisi_pcie0_core1<0000:16:04.0>
> [root at localhost tmp]# ./perf iostat --timeout 10000
> 
>  Performance counter stats for 'system wide':
> 
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
> 
>       10.008227512 seconds time elapsed
> 
> [root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
> -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
> -norandommap -group_reporting -runtime=10 -time_based -bs=64k
> 
>  Performance counter stats for 'system wide':
> 
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
> 
>       10.168561767 seconds time elapsed
> 
>        0.465373000 seconds user
>        1.952948000 seconds sys
> 
> More information of the HiSilicon PCIe PMU can be found at
> Documentation/admin-guide/perf/hisi-pcie-pmu.rst.
> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
If you are doing a v3 for any reason, one trivial comment inline.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

> +
> +enum hisi_iostat_metric_type {
> +	METRIC_IN_MWR,		/* Inbound Memory Write */
> +	METRIC_IN_MRD,		/* Inbound Memory Read */
> +	METRIC_IN_CPL,		/* Inbound Memory Completion */
> +	METRIC_OUT_MWR,		/* Outbound Memory Write */
> +	METRIC_OUT_MRD,		/* Outbound Memory Read */
> +	METRIC_OUT_CPL,		/* Outbound Memory Completion */
> +	METRIC_TYPE_MAX,

Given it is the terminator, no comma needed.

> +};


From horms at kernel.org  Thu Feb  8 02:47:00 2024
From: horms at kernel.org (Simon Horman)
Date: Thu, 8 Feb 2024 10:47:00 +0000
Subject: [PATCH net] net: ti: icssg-prueth: Remove duplicate cleanup
 calls in emac_ndo_stop()
In-Reply-To: <20240206152052.98217-1-diogo.ivo@siemens.com>
References: <20240206152052.98217-1-diogo.ivo@siemens.com>
Message-ID: <20240208104700.GF1435458@kernel.org>

On Tue, Feb 06, 2024 at 03:20:51PM +0000, Diogo Ivo wrote:
> Remove the duplicate calls to prueth_emac_stop() and
> prueth_cleanup_tx_chns() in emac_ndo_stop().
> 
> Fixes: 128d5874c082 ("net: ti: icssg-prueth: Add ICSSG ethernet driver")
> Fixes: 186734c15886 ("net: ti: icssg-prueth: add packet timestamping and ptp support")
> Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>

Hi Doigo,

I see that there are indeed duplicate calls,
but I do wonder if this is a cleanup rather than a bug:
is there a user-visible problem that this addresses?

If so, I think it would be good to spell this out in the commit message.

...


From Jonathan.Cameron at Huawei.com  Thu Feb  8 02:50:47 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 10:50:47 +0000
Subject: [PATCH] drivers/perf: hisi: Enable HiSilicon Erratum 162700402
 quirk for UC PMU
In-Reply-To: <20240207094245.34195-1-hejunhao3@huawei.com>
References: <20240207094245.34195-1-hejunhao3@huawei.com>
Message-ID: <20240208105047.000023c7@Huawei.com>

On Wed, 7 Feb 2024 17:42:45 +0800
Junhao He <hejunhao3 at huawei.com> wrote:

> HiSilicon UC PMU v2 suffers the erratum 162700402 that the PMU counter
> cannot be set due to the lack of clock under power saving mode. This will
> lead to error or inaccurate counts. The clock can be enabled by the PMU
> global enabling control.
> 
> This patch tries to fix this by set the UC PMU enable before set event
> period to turn on the clock, and then restore the UC PMU configuration.
> The counter register can hold its value without a clock.
> 
> Signed-off-by: Junhao He <hejunhao3 at huawei.com>

Hi.

Some very minor comments about the comments inline.

Jonathan

> ---
>  drivers/perf/hisilicon/hisi_uncore_uc_pmu.c | 40 ++++++++++++++++++++-
>  1 file changed, 39 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
> index 636fb79647c8..8e7a9e1f419a 100644
> --- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
> +++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
> @@ -287,10 +287,48 @@ static u64 hisi_uc_pmu_read_counter(struct hisi_pmu *uc_pmu,
>  	return readq(uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
>  }
>  
> -static void hisi_uc_pmu_write_counter(struct hisi_pmu *uc_pmu,
> +static bool hisi_uc_pmu_get_glb_en_state(struct hisi_pmu *uc_pmu)
> +{
> +	u32 val;
> +
> +	val = readl(uc_pmu->base + HISI_UC_EVENT_CTRL_REG);
> +	return !!FIELD_GET(HISI_UC_EVENT_GLB_EN, val);
> +}
> +
> +static void hisi_uc_pmu_write_counter_quirk_hip09(struct hisi_pmu *uc_pmu,
>  				      struct hw_perf_event *hwc, u64 val)
>  {
> +	bool enable = hisi_uc_pmu_get_glb_en_state(uc_pmu);
> +
> +	/* Set the UC PMU enable to turn on the clock. */

Comment from below here but adjusted to say which path has the device
already enabled.

> +	if (!enable)
> +		hisi_uc_pmu_start_counters(uc_pmu);
> +
>  	writeq(val, uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
> +
> +	/*
> +	 * The counter register can hold its value without a clock. We need
> +	 * restore the UC PMU configuration. The irq handler will also call
> +	 * the function to set period. At this time, PMU is still enabled and
> +	 * we cannot directly disable the PMU.
I think the comment is more relevant above...
> +	 */
> +	if (!enable)
> +		hisi_uc_pmu_stop_counters(uc_pmu);
> +}
> +
> +static void hisi_uc_pmu_write_counter(struct hisi_pmu *uc_pmu,
> +				      struct hw_perf_event *hwc, u64 val)
> +{
> +	/*
> +	 * HiSilicon UC PMU v2 suffers the erratum 162700402 that the PMU
> +	 * counter cannot be set due to the lack of clock under power saving
> +	 * mode. This will lead to error or inaccurate counts. The clock can
> +	 * be enabled by the PMU global enabling control.

I'd move the comment to next to the quirk function so that people can immediately
see what is being done.  Down here we just need to know there is a quirk.

> +	 */
> +	if (uc_pmu->identifier == HISI_PMU_V2)
> +		hisi_uc_pmu_write_counter_quirk_hip09(uc_pmu, hwc, val);
> +	else
> +		writeq(val, uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
>  }
>  
>  static void hisi_uc_pmu_enable_counter_int(struct hisi_pmu *uc_pmu,



From krzysztof.kozlowski at linaro.org  Thu Feb  8 02:51:29 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 11:51:29 +0100
Subject: [PATCH] arm64: dts: rk3588: minor whitespace cleanup
Message-ID: <20240208105129.128561-1-krzysztof.kozlowski@linaro.org>

The DTS code coding style expects exactly one space before '{'
character.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
index 3d0ea9e34049..ad8e36a339dc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
@@ -212,19 +212,19 @@ &cpu_l3 {
 	cpu-supply = <&vdd_cpu_lit_s0>;
 };
 
-&cpu_b0{
+&cpu_b0 {
 	cpu-supply = <&vdd_cpu_big0_s0>;
 };
 
-&cpu_b1{
+&cpu_b1 {
 	cpu-supply = <&vdd_cpu_big0_s0>;
 };
 
-&cpu_b2{
+&cpu_b2 {
 	cpu-supply = <&vdd_cpu_big1_s0>;
 };
 
-&cpu_b3{
+&cpu_b3 {
 	cpu-supply = <&vdd_cpu_big1_s0>;
 };
 
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb  8 02:51:46 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 11:51:46 +0100
Subject: [PATCH 2/2] ARM: dts: ti: omap: minor whitespace cleanup
In-Reply-To: <20240208105146.128645-1-krzysztof.kozlowski@linaro.org>
References: <20240208105146.128645-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240208105146.128645-2-krzysztof.kozlowski@linaro.org>

The DTS code coding style expects exactly one space before '{'
character.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm/boot/dts/ti/omap/am33xx.dtsi | 8 ++++----
 arch/arm/boot/dts/ti/omap/am4372.dtsi | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/ti/omap/am33xx.dtsi b/arch/arm/boot/dts/ti/omap/am33xx.dtsi
index 989d5a6edeed..0614ffdc1578 100644
--- a/arch/arm/boot/dts/ti/omap/am33xx.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am33xx.dtsi
@@ -80,7 +80,7 @@ cpu0_opp_table: opp-table {
 		 * because the can not be enabled simultaneously on a
 		 * single SoC.
 		 */
-		opp-50-300000000{
+		opp-50-300000000 {
 			/* OPP50 */
 			opp-hz = /bits/ 64 <300000000>;
 			opp-microvolt = <950000 931000 969000>;
@@ -88,7 +88,7 @@ opp-50-300000000{
 			opp-suspend;
 		};
 
-		opp-100-275000000{
+		opp-100-275000000 {
 			/* OPP100-1 */
 			opp-hz = /bits/ 64 <275000000>;
 			opp-microvolt = <1100000 1078000 1122000>;
@@ -96,7 +96,7 @@ opp-100-275000000{
 			opp-suspend;
 		};
 
-		opp-100-300000000{
+		opp-100-300000000 {
 			/* OPP100-2 */
 			opp-hz = /bits/ 64 <300000000>;
 			opp-microvolt = <1100000 1078000 1122000>;
@@ -104,7 +104,7 @@ opp-100-300000000{
 			opp-suspend;
 		};
 
-		opp-100-500000000{
+		opp-100-500000000 {
 			/* OPP100-3 */
 			opp-hz = /bits/ 64 <500000000>;
 			opp-microvolt = <1100000 1078000 1122000>;
diff --git a/arch/arm/boot/dts/ti/omap/am4372.dtsi b/arch/arm/boot/dts/ti/omap/am4372.dtsi
index 5fd1b380ece6..0a1df30f2818 100644
--- a/arch/arm/boot/dts/ti/omap/am4372.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am4372.dtsi
@@ -92,7 +92,7 @@ opp-120-720000000 {
 			opp-supported-hw = <0xFF 0x08>;
 		};
 
-		opp-800000000{
+		opp-800000000 {
 			/* OPP Turbo */
 			opp-hz = /bits/ 64 <800000000>;
 			opp-microvolt = <1260000 1234800 1285200>;
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb  8 02:51:45 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 11:51:45 +0100
Subject: [PATCH 1/2] arm64: dts: ti: k3-am62p5-sk: minor whitespace cleanup
Message-ID: <20240208105146.128645-1-krzysztof.kozlowski@linaro.org>

The DTS code coding style expects exactly one space before '{'
character.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 95a0146279b1..21aa40878cd1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -494,7 +494,7 @@ &ospi0 {
 	pinctrl-0 = <&ospi0_pins_default>;
 	bootph-all;
 
-	flash at 0{
+	flash at 0 {
 		compatible = "jedec,spi-nor";
 		reg = <0x0>;
 		spi-tx-bus-width = <8>;
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb  8 02:52:17 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 11:52:17 +0100
Subject: [PATCH] arm64: dts: freescale: minor whitespace cleanup
Message-ID: <20240208105217.128748-1-krzysztof.kozlowski@linaro.org>

The DTS code coding style expects exactly one space before '{'
character.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts | 2 +-
 arch/arm64/boot/dts/freescale/mba8xx.dtsi     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index 69dd8e31027c..24bb253b938d 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -37,7 +37,7 @@ m33_reserved: noncacheable-section at a8600000 {
 			no-map;
 		};
 
-		rsc_table: rsc-table at 1fff8000{
+		rsc_table: rsc-table at 1fff8000 {
 			reg = <0 0x1fff8000 0 0x1000>;
 			no-map;
 		};
diff --git a/arch/arm64/boot/dts/freescale/mba8xx.dtsi b/arch/arm64/boot/dts/freescale/mba8xx.dtsi
index 6164fefb9218..3b4c5fa21f31 100644
--- a/arch/arm64/boot/dts/freescale/mba8xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8xx.dtsi
@@ -466,7 +466,7 @@ pinctrl_pca9538: pca9538grp {
 		fsl,pins = <IMX8QXP_USDHC1_RESET_B_LSIO_GPIO4_IO19	0x00000020>;
 	};
 
-	pinctrl_pcieb: pcieagrp{
+	pinctrl_pcieb: pcieagrp {
 		fsl,pins = <IMX8QXP_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00	0x06000041>,
 			   <IMX8QXP_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO01	0x06000041>,
 			   <IMX8QXP_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO02	0x04000041>;
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb  8 02:52:43 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 11:52:43 +0100
Subject: [PATCH] arm64: dts: exynos: gs101: minor whitespace cleanup
Message-ID: <20240208105243.128875-1-krzysztof.kozlowski@linaro.org>

The DTS code coding style expects exactly one space before '{' and
around '=' characters.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../boot/dts/exynos/google/gs101-pinctrl.dtsi    |  2 +-
 arch/arm64/boot/dts/exynos/google/gs101.dtsi     | 16 ++++++++--------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
index e6a9776d4d62..a675f822acec 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
@@ -251,7 +251,7 @@ gph1: gph1-gpio-bank {
 		#interrupt-cells = <2>;
 	};
 
-	pcie0_clkreq: pcie0-clkreq-pins{
+	pcie0_clkreq: pcie0-clkreq-pins {
 		samsung,pins = "gph0-1";
 		samsung,pin-function = <GS101_PIN_FUNC_2>;
 		samsung,pin-pud = <GS101_PIN_PULL_UP>;
diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index c7a9e81d23b9..80cc933cca3d 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -73,7 +73,7 @@ cpu0: cpu at 0 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0000>;
 			enable-method = "psci";
-			cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
+			cpu-idle-states = <&ANANKE_CPU_SLEEP>;
 			capacity-dmips-mhz = <250>;
 			dynamic-power-coefficient = <70>;
 		};
@@ -83,7 +83,7 @@ cpu1: cpu at 100 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0100>;
 			enable-method = "psci";
-			cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
+			cpu-idle-states = <&ANANKE_CPU_SLEEP>;
 			capacity-dmips-mhz = <250>;
 			dynamic-power-coefficient = <70>;
 		};
@@ -93,7 +93,7 @@ cpu2: cpu at 200 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0200>;
 			enable-method = "psci";
-			cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
+			cpu-idle-states = <&ANANKE_CPU_SLEEP>;
 			capacity-dmips-mhz = <250>;
 			dynamic-power-coefficient = <70>;
 		};
@@ -103,7 +103,7 @@ cpu3: cpu at 300 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0300>;
 			enable-method = "psci";
-			cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
+			cpu-idle-states = <&ANANKE_CPU_SLEEP>;
 			capacity-dmips-mhz = <250>;
 			dynamic-power-coefficient = <70>;
 		};
@@ -113,7 +113,7 @@ cpu4: cpu at 400 {
 			compatible = "arm,cortex-a76";
 			reg = <0x0400>;
 			enable-method = "psci";
-			cpu-idle-states =  <&ENYO_CPU_SLEEP>;
+			cpu-idle-states = <&ENYO_CPU_SLEEP>;
 			capacity-dmips-mhz = <620>;
 			dynamic-power-coefficient = <284>;
 		};
@@ -123,7 +123,7 @@ cpu5: cpu at 500 {
 			compatible = "arm,cortex-a76";
 			reg = <0x0500>;
 			enable-method = "psci";
-			cpu-idle-states =  <&ENYO_CPU_SLEEP>;
+			cpu-idle-states = <&ENYO_CPU_SLEEP>;
 			capacity-dmips-mhz = <620>;
 			dynamic-power-coefficient = <284>;
 		};
@@ -133,7 +133,7 @@ cpu6: cpu at 600 {
 			compatible = "arm,cortex-x1";
 			reg = <0x0600>;
 			enable-method = "psci";
-			cpu-idle-states =  <&HERA_CPU_SLEEP>;
+			cpu-idle-states = <&HERA_CPU_SLEEP>;
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <650>;
 		};
@@ -143,7 +143,7 @@ cpu7: cpu at 700 {
 			compatible = "arm,cortex-x1";
 			reg = <0x0700>;
 			enable-method = "psci";
-			cpu-idle-states =  <&HERA_CPU_SLEEP>;
+			cpu-idle-states = <&HERA_CPU_SLEEP>;
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <650>;
 		};
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb  8 02:52:52 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 11:52:52 +0100
Subject: [PATCH] arm64: dts: amlogic: t7: minor whitespace cleanup
Message-ID: <20240208105252.128940-1-krzysztof.kozlowski@linaro.org>

The DTS code coding style expects exactly one space before '{'
character.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index a03c7667d2b6..ad1cac42e9d8 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -54,7 +54,7 @@ cpu100: cpu at 100 {
 			enable-method = "psci";
 		};
 
-		cpu101: cpu at 101{
+		cpu101: cpu at 101 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x101>;
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb  8 02:53:01 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 11:53:01 +0100
Subject: [PATCH 2/2] arm64: dts: allwinner: h616: minor whitespace cleanup
In-Reply-To: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>
References: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240208105301.129005-2-krzysztof.kozlowski@linaro.org>

The DTS code coding style expects exactly one space before '{'
character.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
index b2988f500231..af421ba24ce0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
@@ -93,7 +93,7 @@ axp313a: pmic at 36 {
 		interrupt-controller;
 		#interrupt-cells = <1>;
 
-		regulators{
+		regulators {
 			reg_dcdc1: dcdc1 {
 				regulator-name = "vdd-gpu-sys";
 				regulator-min-microvolt = <810000>;
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb  8 02:53:00 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 11:53:00 +0100
Subject: [PATCH 1/2] arm64: dts: allwinner: use capital "OR" for multiple licenses in SPDX
Message-ID: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>

Documentation/process/license-rules.rst and checkpatch expect the SPDX
identifier syntax for multiple licenses to use capital "OR".  Correct it
to keep consistent format and avoid copy-paste issues.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts    | 2 +-
 arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi  | 2 +-
 arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
index dbce61b355d6..4bfb52609c94 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2023 Martin Botka <martin.botka at somainline.org>.
  */
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
index 1fed2b46cfe8..b2988f500231 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2023 Martin Botka <martin.botka at somainline.org>.
  */
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
index 832f08b2b260..ff84a3794470 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2023 Martin Botka <martin at biqu3d.com>.
  */
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb  8 02:53:14 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 11:53:14 +0100
Subject: [PATCH] arm64: dts: amd: use capital "OR" for multiple licenses in SPDX
Message-ID: <20240208105314.129095-1-krzysztof.kozlowski@linaro.org>

Documentation/process/license-rules.rst and checkpatch expect the SPDX
identifier syntax for multiple licenses to use capital "OR".  Correct it
to keep consistent format and avoid copy-paste issues.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/boot/dts/amd/elba-16core.dtsi      | 2 +-
 arch/arm64/boot/dts/amd/elba-asic-common.dtsi | 2 +-
 arch/arm64/boot/dts/amd/elba-asic.dts         | 2 +-
 arch/arm64/boot/dts/amd/elba-flash-parts.dtsi | 2 +-
 arch/arm64/boot/dts/amd/elba.dtsi             | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/amd/elba-16core.dtsi b/arch/arm64/boot/dts/amd/elba-16core.dtsi
index 568bcc39ce9f..6c1b7b8fe354 100644
--- a/arch/arm64/boot/dts/amd/elba-16core.dtsi
+++ b/arch/arm64/boot/dts/amd/elba-16core.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
  * Copyright 2020-2023 Advanced Micro Devices, Inc.
  */
diff --git a/arch/arm64/boot/dts/amd/elba-asic-common.dtsi b/arch/arm64/boot/dts/amd/elba-asic-common.dtsi
index 46b6c6783f58..d12e9a7b5587 100644
--- a/arch/arm64/boot/dts/amd/elba-asic-common.dtsi
+++ b/arch/arm64/boot/dts/amd/elba-asic-common.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
  * Copyright 2020-2022 Advanced Micro Devices, Inc.
  */
diff --git a/arch/arm64/boot/dts/amd/elba-asic.dts b/arch/arm64/boot/dts/amd/elba-asic.dts
index c3f4da2f7449..20b0fa0807a1 100644
--- a/arch/arm64/boot/dts/amd/elba-asic.dts
+++ b/arch/arm64/boot/dts/amd/elba-asic.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
  * Device Tree file for AMD Pensando Elba Board.
  *
diff --git a/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi b/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi
index cf761a05a81f..6ea2d777c8c9 100644
--- a/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi
+++ b/arch/arm64/boot/dts/amd/elba-flash-parts.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
  * Copyright 2020-2023 Advanced Micro Devices, Inc.
  */
diff --git a/arch/arm64/boot/dts/amd/elba.dtsi b/arch/arm64/boot/dts/amd/elba.dtsi
index 674890cf2a34..758bce0a0b2a 100644
--- a/arch/arm64/boot/dts/amd/elba.dtsi
+++ b/arch/arm64/boot/dts/amd/elba.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
  * Copyright 2020-2022 Advanced Micro Devices, Inc.
  */
-- 
2.34.1



From joey.gouly at arm.com  Thu Feb  8 02:54:20 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Thu,  8 Feb 2024 10:54:20 +0000
Subject: [PATCH v1 0/2] small kern_hyp_va() cleanups
Message-ID: <20240208105422.3444159-1-joey.gouly@arm.com>

Hello,

I wanted to add some comments to __kern_hyp_va(), since I was recently trying
to understand it, and I think it could be helpful for someone looking at it in
the future.

The second patch removes the assembly macro version, since it is unused. Maybe
(out-of-tree) pkvm uses it or it's just worth keeping around in case someone
needs it in the future. So if that patch isn't applied it's not too important.

Thanks,
Joey

Joey Gouly (2):
  KVM: arm64: add comments to __kern_hyp_va
  KVM: arm64: removed unused kern_hyp_va asm macro

 arch/arm64/include/asm/kvm_mmu.h | 41 ++++++++++++--------------------
 1 file changed, 15 insertions(+), 26 deletions(-)

-- 
2.25.1



From joey.gouly at arm.com  Thu Feb  8 02:54:22 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Thu,  8 Feb 2024 10:54:22 +0000
Subject: [PATCH v1 2/2] KVM: arm64: removed unused kern_hyp_va asm macro
In-Reply-To: <20240208105422.3444159-1-joey.gouly@arm.com>
References: <20240208105422.3444159-1-joey.gouly@arm.com>
Message-ID: <20240208105422.3444159-3-joey.gouly@arm.com>

The last usage of this macro was removed in:
    commit 5dc33bd199ca ("KVM: arm64: nVHE: Pass pointers consistently to hyp-init")

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/include/asm/kvm_mmu.h | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index d248a7ae627a..961d4431654b 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -53,27 +53,6 @@
 
 #include <asm/alternative.h>
 
-/*
- * Convert a kernel VA into a HYP VA.
- * reg: VA to be converted.
- *
- * The actual code generation takes place in kvm_update_va_mask, and
- * the instructions below are only there to reserve the space and
- * perform the register allocation (kvm_update_va_mask uses the
- * specific registers encoded in the instructions).
- */
-.macro kern_hyp_va	reg
-#ifndef __KVM_VHE_HYPERVISOR__
-alternative_cb ARM64_ALWAYS_SYSTEM, kvm_update_va_mask
-	and     \reg, \reg, #1		/* mask with va_mask */
-	ror	\reg, \reg, #1		/* rotate to the first tag bit */
-	add	\reg, \reg, #0		/* insert the low 12 bits of the tag */
-	add	\reg, \reg, #0, lsl 12	/* insert the top 12 bits of the tag */
-	ror	\reg, \reg, #63		/* rotate back */
-alternative_cb_end
-#endif
-.endm
-
 /*
  * Convert a hypervisor VA to a PA
  * reg: hypervisor address to be converted in place
-- 
2.25.1



From joey.gouly at arm.com  Thu Feb  8 02:54:21 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Thu,  8 Feb 2024 10:54:21 +0000
Subject: [PATCH v1 1/2] KVM: arm64: add comments to __kern_hyp_va
In-Reply-To: <20240208105422.3444159-1-joey.gouly@arm.com>
References: <20240208105422.3444159-1-joey.gouly@arm.com>
Message-ID: <20240208105422.3444159-2-joey.gouly@arm.com>

Document this function a little, to make it easier to understand.

The assembly comments were copied from the kern_hyp_va asm macro.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oliver.upton at linux.dev>
---
 arch/arm64/include/asm/kvm_mmu.h | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index e3e793d0ec30..d248a7ae627a 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -127,14 +127,24 @@ void kvm_apply_hyp_relocations(void);
 
 #define __hyp_pa(x) (((phys_addr_t)(x)) + hyp_physvirt_offset)
 
+/*
+ * Convert a kernel VA into a HYP VA.
+ *
+ * Can be called from hyp or non-hyp context.
+ */
 static __always_inline unsigned long __kern_hyp_va(unsigned long v)
 {
+/*
+ * This #ifndef is an optimisation for when this is called from VHE hyp
+ * context.  When called from a VHE non-hyp context, kvm_update_va_mask() will
+ * replace the instructions with `nop`s.
+ */
 #ifndef __KVM_VHE_HYPERVISOR__
-	asm volatile(ALTERNATIVE_CB("and %0, %0, #1\n"
-				    "ror %0, %0, #1\n"
-				    "add %0, %0, #0\n"
-				    "add %0, %0, #0, lsl 12\n"
-				    "ror %0, %0, #63\n",
+	asm volatile(ALTERNATIVE_CB("and %0, %0, #1\n"         /* mask with va_mask */
+				    "ror %0, %0, #1\n"         /* rotate to the first tag bit */
+				    "add %0, %0, #0\n"         /* insert the low 12 bits of the tag */
+				    "add %0, %0, #0, lsl 12\n" /* insert the top 12 bits of the tag */
+				    "ror %0, %0, #63\n",       /* rotate back */
 				    ARM64_ALWAYS_SYSTEM,
 				    kvm_update_va_mask)
 		     : "+r" (v));
-- 
2.25.1



From andre.przywara at arm.com  Thu Feb  8 03:01:11 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Thu, 8 Feb 2024 11:01:11 +0000
Subject: [PATCH 1/2] arm64: dts: allwinner: use capital "OR" for
 multiple licenses in SPDX
In-Reply-To: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>
References: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240208110111.3ed4e5f4@donnerap.manchester.arm.com>

On Thu,  8 Feb 2024 11:53:00 +0100
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:

Hi,

> Documentation/process/license-rules.rst and checkpatch expect the SPDX
> identifier syntax for multiple licenses to use capital "OR".  Correct it
> to keep consistent format and avoid copy-paste issues.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Thanks,
Andre

> ---
>  .../boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts    | 2 +-
>  arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi  | 2 +-
>  arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts    | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
> index dbce61b355d6..4bfb52609c94 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
> @@ -1,4 +1,4 @@
> -// SPDX-License-Identifier: (GPL-2.0+ or MIT)
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>  /*
>   * Copyright (C) 2023 Martin Botka <martin.botka at somainline.org>.
>   */
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
> index 1fed2b46cfe8..b2988f500231 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
> @@ -1,4 +1,4 @@
> -// SPDX-License-Identifier: (GPL-2.0+ or MIT)
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>  /*
>   * Copyright (C) 2023 Martin Botka <martin.botka at somainline.org>.
>   */
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
> index 832f08b2b260..ff84a3794470 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
> @@ -1,4 +1,4 @@
> -// SPDX-License-Identifier: (GPL-2.0+ or MIT)
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>  /*
>   * Copyright (C) 2023 Martin Botka <martin at biqu3d.com>.
>   */



From bhargav.r at ltts.com  Thu Feb  8 02:53:30 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:30 +0530
Subject: [RESEND PATCH v1 00/13] Add support for TI TPS65224 PMIC
Message-ID: <20240208105343.1212902-1-bhargav.r@ltts.com>

This series modifies the existing TPS6594 drivers to add support for the
TPS65224 PMIC device that is a derivative of TPS6594. TPS65224 has a
similar register map to TPS6594 with a few differences. SPI, I2C, ESM,
PFSM, Regulators and GPIO features overlap between the two devices.

TPS65224 is a Power Management IC (PMIC) which provides regulators and
other features like GPIOs, Watchdog, Error Signal Monitor (ESM) and
Pre-configurable Finite State Machine (PFSM). The SoC and the PMIC can
communicate through the I2C or SPI interfaces. The PMIC TPS65224
additionally has a 12-bit ADC.
Data Sheet for TPS65224: https://www.ti.com/product/TPS65224-Q1

Driver re-use is applied following the advice of the following series:
https://lore.kernel.org/lkml/2f467b0a-1d11-4ec7-8ca6-6c4ba66e5887 at baylibre.com/

The features implemented in this series are:
- TPS65224 Register definitions
- Core (MFD I2C and SPI entry points)
- PFSM	
- ESM
- Regulators
- Pinctrl

TPS65224 Register definitions:
This patch adds macros for register field definitions of TPS65224
to the existing TPS6594 driver.  

Core description:
I2C and SPI interface protocols are implemented, with and without
the bit-integrity error detection feature (CRC mode).

PFSM description:
Strictly speaking, PFSM is not hardware. It is a piece of code.
PMIC integrates a state machine which manages operational modes.
Depending on the current operational mode, some voltage domains
remain energized while others can be off.
PFSM driver can be used to trigger transitions between configured
states.

ESM description:
This device monitors the SoC error output signal at its nERR_MCU
input pin. On error detection, ESM driver toggles the PMIC nRSTOUT pin
to reset the SoC.

Regulators description:
4 BUCKs and 3 LDOs.
BUCK12 can be used in dual-phase mode.

Pinctrl description:
TPS65224 family has 6 GPIOs. Those GPIOs can also serve different
functions such as I2C or SPI interface or watchdog disable functions.
The driver provides both pinmuxing for the functions and GPIO capability.

This series was tested on linux-next tag: next-20240118

Test logs can be found here:
https://gist.github.com/LeonardMH/58ec135921fb1062ffd4a8b384831eb0

Bhargav Raviprakash (10):
  mfd: tps6594: use volatile_table instead of volatile_reg
  dt-bindings: mfd: ti,tps6594: Add TI TPS65224 PMIC
  mfd: tps6594-i2c: Add TI TPS65224 PMIC I2C
  mfd: tps6594-spi: Add TI TPS65224 PMIC SPI
  mfd: tps6594-core: Add TI TPS65224 PMIC core
  misc: tps6594-pfsm: Add TI TPS65224 PMIC PFSM
  misc: tps6594-esm: reversion check limited to TPS6594 family
  misc: tps6594-esm: use regmap_field
  misc: tps6594-esm: Add TI TPS65224 PMIC ESM
  arch: arm64: dts: ti: k3-am62p5-sk: Add TPS65224 PMIC support in AM62P
    dts

Nirmala Devi Mal Nadar (3):
  mfd: tps6594: Add register definitions for TI TPS65224 PMIC
  regulator: tps6594-regulator: Add TI TPS65224 PMIC regulators
  pinctrl: pinctrl-tps6594: Add TPS65224 PMIC pinctrl and GPIO

 .../devicetree/bindings/mfd/ti,tps6594.yaml   |   1 +
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts       |  95 +++++
 drivers/mfd/tps6594-core.c                    | 258 ++++++++++++-
 drivers/mfd/tps6594-i2c.c                     |  20 +-
 drivers/mfd/tps6594-spi.c                     |  18 +-
 drivers/misc/tps6594-esm.c                    |  89 +++--
 drivers/misc/tps6594-pfsm.c                   |  55 ++-
 drivers/pinctrl/pinctrl-tps6594.c             | 287 ++++++++++++--
 drivers/regulator/Kconfig                     |   4 +-
 drivers/regulator/tps6594-regulator.c         | 244 ++++++++++--
 include/linux/mfd/tps6594.h                   | 358 +++++++++++++++++-
 11 files changed, 1272 insertions(+), 157 deletions(-)


base-commit: 2863b714f3ad0a9686f2de1b779228ad8c7a8052
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:32 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:32 +0530
Subject: [RESEND PATCH v1 02/13] mfd: tps6594: use volatile_table instead of volatile_reg
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-3-bhargav.r@ltts.com>

In regmap_config use volatile_table instead of volatile_reg.
This change makes it easier to add support for TPS65224 PMIC.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/mfd/tps6594-core.c  | 16 ++++++++++------
 drivers/mfd/tps6594-i2c.c   |  2 +-
 drivers/mfd/tps6594-spi.c   |  2 +-
 include/linux/mfd/tps6594.h |  4 +++-
 4 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/tps6594-core.c b/drivers/mfd/tps6594-core.c
index 783ee5990..089ab8cc8 100644
--- a/drivers/mfd/tps6594-core.c
+++ b/drivers/mfd/tps6594-core.c
@@ -319,12 +319,16 @@ static struct regmap_irq_chip tps6594_irq_chip = {
 	.handle_post_irq = tps6594_handle_post_irq,
 };
 
-bool tps6594_is_volatile_reg(struct device *dev, unsigned int reg)
-{
-	return (reg >= TPS6594_REG_INT_TOP && reg <= TPS6594_REG_STAT_READBACK_ERR) ||
-	       reg == TPS6594_REG_RTC_STATUS;
-}
-EXPORT_SYMBOL_GPL(tps6594_is_volatile_reg);
+static const struct regmap_range tps6594_volatile_ranges[] = {
+	regmap_reg_range(TPS6594_REG_INT_TOP, TPS6594_REG_STAT_READBACK_ERR),
+	regmap_reg_range(TPS6594_REG_RTC_STATUS, TPS6594_REG_RTC_STATUS),
+};
+
+const struct regmap_access_table tps6594_volatile_table = {
+	.yes_ranges = tps6594_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(tps6594_volatile_ranges),
+};
+EXPORT_SYMBOL_GPL(tps6594_volatile_table);
 
 static int tps6594_check_crc_mode(struct tps6594 *tps, bool primary_pmic)
 {
diff --git a/drivers/mfd/tps6594-i2c.c b/drivers/mfd/tps6594-i2c.c
index 899c88c0f..c125b474b 100644
--- a/drivers/mfd/tps6594-i2c.c
+++ b/drivers/mfd/tps6594-i2c.c
@@ -187,7 +187,7 @@ static const struct regmap_config tps6594_i2c_regmap_config = {
 	.reg_bits = 16,
 	.val_bits = 8,
 	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
-	.volatile_reg = tps6594_is_volatile_reg,
+	.volatile_table = &tps6594_volatile_table,
 	.read = tps6594_i2c_read,
 	.write = tps6594_i2c_write,
 };
diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
index 24b72847e..5afb1736f 100644
--- a/drivers/mfd/tps6594-spi.c
+++ b/drivers/mfd/tps6594-spi.c
@@ -70,7 +70,7 @@ static const struct regmap_config tps6594_spi_regmap_config = {
 	.reg_bits = 16,
 	.val_bits = 8,
 	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
-	.volatile_reg = tps6594_is_volatile_reg,
+	.volatile_table = &tps6594_volatile_table,
 	.reg_read = tps6594_spi_reg_read,
 	.reg_write = tps6594_spi_reg_write,
 	.use_single_read = true,
diff --git a/include/linux/mfd/tps6594.h b/include/linux/mfd/tps6594.h
index 1d8969594..6c5a2889f 100644
--- a/include/linux/mfd/tps6594.h
+++ b/include/linux/mfd/tps6594.h
@@ -1344,7 +1344,9 @@ struct tps6594 {
 	struct regmap_irq_chip_data *irq_data;
 };
 
-bool tps6594_is_volatile_reg(struct device *dev, unsigned int reg);
+extern const struct regmap_access_table tps6594_volatile_table;
+extern const struct regmap_access_table tps65224_volatile_table;
+
 int tps6594_device_init(struct tps6594 *tps, bool enable_crc);
 
 #endif /*  __LINUX_MFD_TPS6594_H */
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:33 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:33 +0530
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI TPS65224 PMIC
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-4-bhargav.r@ltts.com>

TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
regulators, it includes additional features like GPIOs, watchdog, ESMs
(Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
managing the state of the device.
TPS6594 and TPS65224 have significant functional overlap.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 Documentation/devicetree/bindings/mfd/ti,tps6594.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
index 9d43376be..6341b6070 100644
--- a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
+++ b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
@@ -21,6 +21,7 @@ properties:
       - ti,lp8764-q1
       - ti,tps6593-q1
       - ti,tps6594-q1
+      - ti,tps65224-q1
 
   reg:
     description: I2C slave address or SPI chip select number.
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:31 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:31 +0530
Subject: [RESEND PATCH v1 01/13] mfd: tps6594: Add register definitions for TI TPS65224 PMIC
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-2-bhargav.r@ltts.com>

From: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>

Extend TPS6594 PMIC register and field definitions to support TPS65224
power management IC.

TPS65224 is software compatible to TPS6594 and can re-use many of the
same definitions, new definitions are added to support additional
controls available on TPS65224.

Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
---
 include/linux/mfd/tps6594.h | 354 ++++++++++++++++++++++++++++++++++--
 1 file changed, 342 insertions(+), 12 deletions(-)

diff --git a/include/linux/mfd/tps6594.h b/include/linux/mfd/tps6594.h
index 3f7c5e23c..1d8969594 100644
--- a/include/linux/mfd/tps6594.h
+++ b/include/linux/mfd/tps6594.h
@@ -18,12 +18,13 @@ enum pmic_id {
 	TPS6594,
 	TPS6593,
 	LP8764,
+	TPS65224,
 };
 
 /* Macro to get page index from register address */
 #define TPS6594_REG_TO_PAGE(reg)	((reg) >> 8)
 
-/* Registers for page 0 of TPS6594 */
+/* Registers for page 0 */
 #define TPS6594_REG_DEV_REV				0x01
 
 #define TPS6594_REG_NVM_CODE_1				0x02
@@ -56,9 +57,6 @@ enum pmic_id {
 #define TPS6594_REG_GPIOX_OUT(gpio_inst)		(TPS6594_REG_GPIO_OUT_1 + (gpio_inst) / 8)
 #define TPS6594_REG_GPIOX_IN(gpio_inst)			(TPS6594_REG_GPIO_IN_1 + (gpio_inst) / 8)
 
-#define TPS6594_REG_GPIO_IN_1				0x3f
-#define TPS6594_REG_GPIO_IN_2				0x40
-
 #define TPS6594_REG_RAIL_SEL_1				0x41
 #define TPS6594_REG_RAIL_SEL_2				0x42
 #define TPS6594_REG_RAIL_SEL_3				0x43
@@ -70,13 +68,15 @@ enum pmic_id {
 #define TPS6594_REG_FSM_TRIG_MASK_3			0x48
 
 #define TPS6594_REG_MASK_BUCK1_2			0x49
+#define TPS65224_REG_MASK_BUCKS				0x49
 #define TPS6594_REG_MASK_BUCK3_4			0x4a
 #define TPS6594_REG_MASK_BUCK5				0x4b
 #define TPS6594_REG_MASK_LDO1_2				0x4c
+#define TPS65224_REG_MASK_LDOS				0x4c
 #define TPS6594_REG_MASK_LDO3_4				0x4d
 #define TPS6594_REG_MASK_VMON				0x4e
-#define TPS6594_REG_MASK_GPIO1_8_FALL			0x4f
-#define TPS6594_REG_MASK_GPIO1_8_RISE			0x50
+#define TPS6594_REG_MASK_GPIO_FALL			0x4f
+#define TPS6594_REG_MASK_GPIO_RISE			0x50
 #define TPS6594_REG_MASK_GPIO9_11			0x51
 #define TPS6594_REG_MASK_STARTUP			0x52
 #define TPS6594_REG_MASK_MISC				0x53
@@ -174,6 +174,10 @@ enum pmic_id {
 
 #define TPS6594_REG_REGISTER_LOCK			0xa1
 
+#define TPS65224_REG_SRAM_ACCESS_1			0xa2
+#define TPS65224_REG_SRAM_ACCESS_2			0xa3
+#define TPS65224_REG_SRAM_ADDR_CTRL			0xa4
+#define TPS65224_REG_RECOV_CNT_PFSM_INCR		0xa5
 #define TPS6594_REG_MANUFACTURING_VER			0xa6
 
 #define TPS6594_REG_CUSTOMER_NVM_ID_REG			0xa7
@@ -182,6 +186,9 @@ enum pmic_id {
 
 #define TPS6594_REG_SOFT_REBOOT_REG			0xab
 
+#define TPS65224_REG_ADC_CTRL				0xac
+#define TPS65224_REG_ADC_RESULT_REG_1			0xad
+#define TPS65224_REG_ADC_RESULT_REG_2			0xae
 #define TPS6594_REG_RTC_SECONDS				0xb5
 #define TPS6594_REG_RTC_MINUTES				0xb6
 #define TPS6594_REG_RTC_HOURS				0xb7
@@ -199,6 +206,7 @@ enum pmic_id {
 
 #define TPS6594_REG_RTC_CTRL_1				0xc2
 #define TPS6594_REG_RTC_CTRL_2				0xc3
+#define TPS65224_REG_STARTUP_CTRL			0xc3
 #define TPS6594_REG_RTC_STATUS				0xc4
 #define TPS6594_REG_RTC_INTERRUPTS			0xc5
 #define TPS6594_REG_RTC_COMP_LSB			0xc6
@@ -214,13 +222,17 @@ enum pmic_id {
 #define TPS6594_REG_PFSM_DELAY_REG_2			0xce
 #define TPS6594_REG_PFSM_DELAY_REG_3			0xcf
 #define TPS6594_REG_PFSM_DELAY_REG_4			0xd0
+#define TPS65224_REG_ADC_GAIN_COMP_REG			0xd0
+#define TPS65224_REG_CRC_CALC_CONTROL			0xef
+#define TPS65224_REG_REGMAP_USER_CRC_LOW		0xf0
+#define TPS65224_REG_REGMAP_USER_CRC_HIGH		0xf1
 
-/* Registers for page 1 of TPS6594 */
+/* Registers for page 1 */
 #define TPS6594_REG_SERIAL_IF_CONFIG			0x11a
 #define TPS6594_REG_I2C1_ID				0x122
 #define TPS6594_REG_I2C2_ID				0x123
 
-/* Registers for page 4 of TPS6594 */
+/* Registers for page 4 */
 #define TPS6594_REG_WD_ANSWER_REG			0x401
 #define TPS6594_REG_WD_QUESTION_ANSW_CNT		0x402
 #define TPS6594_REG_WD_WIN1_CFG				0x403
@@ -241,16 +253,26 @@ enum pmic_id {
 #define TPS6594_BIT_BUCK_PLDN				BIT(5)
 #define TPS6594_BIT_BUCK_RV_SEL				BIT(7)
 
-/* BUCKX_CONF register field definition */
+/* TPS6594 BUCKX_CONF register field definition */
 #define TPS6594_MASK_BUCK_SLEW_RATE			GENMASK(2, 0)
 #define TPS6594_MASK_BUCK_ILIM				GENMASK(5, 3)
 
-/* BUCKX_PG_WINDOW register field definition */
+/* TPS65224 BUCKX_CONF register field definition */
+#define TPS65224_MASK_BUCK_SLEW_RATE			GENMASK(1, 0)
+
+/* TPS6594 BUCKX_PG_WINDOW register field definition */
 #define TPS6594_MASK_BUCK_OV_THR			GENMASK(2, 0)
 #define TPS6594_MASK_BUCK_UV_THR			GENMASK(5, 3)
 
-/* BUCKX VSET */
-#define TPS6594_MASK_BUCKS_VSET GENMASK(7, 0)
+/* TPS65224 BUCKX_PG_WINDOW register field definition */
+#define TPS65224_MASK_BUCK_VMON_THR			GENMASK(1, 0)
+
+/* TPS6594 BUCKX_VOUT register field definition */
+#define TPS6594_MASK_BUCKS_VSET				GENMASK(7, 0)
+
+/* TPS65224 BUCKX_VOUT register field definition */
+#define TPS65224_MASK_BUCK1_VSET			GENMASK(7, 0)
+#define TPS65224_MASK_BUCKS_VSET			GENMASK(6, 0)
 
 /* LDOX_CTRL register field definition */
 #define TPS6594_BIT_LDO_EN				BIT(0)
@@ -258,6 +280,7 @@ enum pmic_id {
 #define TPS6594_BIT_LDO_VMON_EN				BIT(4)
 #define TPS6594_MASK_LDO_PLDN				GENMASK(6, 5)
 #define TPS6594_BIT_LDO_RV_SEL				BIT(7)
+#define TPS65224_BIT_LDO_DISCHARGE_EN			BIT(5)
 
 /* LDORTC_CTRL register field definition */
 #define TPS6594_BIT_LDORTC_DIS				BIT(0)
@@ -271,6 +294,9 @@ enum pmic_id {
 #define TPS6594_MASK_LDO_OV_THR				GENMASK(2, 0)
 #define TPS6594_MASK_LDO_UV_THR				GENMASK(5, 3)
 
+/* LDOX_PG_WINDOW register field definition */
+#define TPS65224_MASK_LDO_VMON_THR			GENMASK(1, 0)
+
 /* VCCA_VMON_CTRL register field definition */
 #define TPS6594_BIT_VMON_EN				BIT(0)
 #define TPS6594_BIT_VMON1_EN				BIT(1)
@@ -278,10 +304,12 @@ enum pmic_id {
 #define TPS6594_BIT_VMON2_EN				BIT(3)
 #define TPS6594_BIT_VMON2_RV_SEL			BIT(4)
 #define TPS6594_BIT_VMON_DEGLITCH_SEL			BIT(5)
+#define TPS65224_BIT_VMON_DEGLITCH_SEL			GENMASK(7, 5)
 
 /* VCCA_PG_WINDOW register field definition */
 #define TPS6594_MASK_VCCA_OV_THR			GENMASK(2, 0)
 #define TPS6594_MASK_VCCA_UV_THR			GENMASK(5, 3)
+#define TPS65224_MASK_VCCA_VMON_THR			GENMASK(1, 0)
 #define TPS6594_BIT_VCCA_PG_SET				BIT(6)
 
 /* VMONX_PG_WINDOW register field definition */
@@ -289,6 +317,9 @@ enum pmic_id {
 #define TPS6594_MASK_VMONX_UV_THR			GENMASK(5, 3)
 #define TPS6594_BIT_VMONX_RANGE				BIT(6)
 
+/* VMONX_PG_WINDOW register field definition */
+#define TPS65224_MASK_VMONX_THR				GENMASK(1, 0)
+
 /* GPIOX_CONF register field definition */
 #define TPS6594_BIT_GPIO_DIR				BIT(0)
 #define TPS6594_BIT_GPIO_OD				BIT(1)
@@ -296,6 +327,8 @@ enum pmic_id {
 #define TPS6594_BIT_GPIO_PU_PD_EN			BIT(3)
 #define TPS6594_BIT_GPIO_DEGLITCH_EN			BIT(4)
 #define TPS6594_MASK_GPIO_SEL				GENMASK(7, 5)
+#define TPS65224_MASK_GPIO_SEL				GENMASK(6, 5)
+#define TPS65224_MASK_GPIO_SEL_GPIO6			GENMASK(7, 5)
 
 /* NPWRON_CONF register field definition */
 #define TPS6594_BIT_NRSTOUT_OD				BIT(0)
@@ -305,6 +338,12 @@ enum pmic_id {
 #define TPS6594_BIT_ENABLE_POL				BIT(5)
 #define TPS6594_MASK_NPWRON_SEL				GENMASK(7, 6)
 
+/* POWER_ON_CONFIG register field definition */
+#define TPS65224_BIT_NINT_ENDRV_PU_SEL			BIT(0)
+#define TPS65224_BIT_NINT_ENDRV_SEL			BIT(1)
+#define TPS65224_BIT_EN_PB_DEGL				BIT(5)
+#define TPS65224_MASK_EN_PB_VSENSE_CONFIG		GENMASK(7, 6)
+
 /* GPIO_OUT_X register field definition */
 #define TPS6594_BIT_GPIOX_OUT(gpio_inst)		BIT((gpio_inst) % 8)
 
@@ -312,6 +351,12 @@ enum pmic_id {
 #define TPS6594_BIT_GPIOX_IN(gpio_inst)			BIT((gpio_inst) % 8)
 #define TPS6594_BIT_NPWRON_IN				BIT(3)
 
+/* GPIO_OUT_X register field definition */
+#define TPS65224_BIT_GPIOX_OUT(gpio_inst)		BIT((gpio_inst))
+
+/* GPIO_IN_X register field definition */
+#define TPS65224_BIT_GPIOX_IN(gpio_inst)		BIT((gpio_inst))
+
 /* RAIL_SEL_1 register field definition */
 #define TPS6594_MASK_BUCK1_GRP_SEL			GENMASK(1, 0)
 #define TPS6594_MASK_BUCK2_GRP_SEL			GENMASK(3, 2)
@@ -343,6 +388,9 @@ enum pmic_id {
 #define TPS6594_BIT_GPIOX_FSM_MASK(gpio_inst)		BIT(((gpio_inst) << 1) % 8)
 #define TPS6594_BIT_GPIOX_FSM_MASK_POL(gpio_inst)	BIT(((gpio_inst) << 1) % 8 + 1)
 
+#define TPS65224_BIT_GPIOX_FSM_MASK(gpio_inst)		BIT(((gpio_inst) << 1) % 6)
+#define TPS65224_BIT_GPIOX_FSM_MASK_POL(gpio_inst)	BIT(((gpio_inst) << 1) % 6 + 1)
+
 /* MASK_BUCKX register field definition */
 #define TPS6594_BIT_BUCKX_OV_MASK(buck_inst)		BIT(((buck_inst) << 2) % 8)
 #define TPS6594_BIT_BUCKX_UV_MASK(buck_inst)		BIT(((buck_inst) << 2) % 8 + 1)
@@ -361,22 +409,46 @@ enum pmic_id {
 #define TPS6594_BIT_VMON2_OV_MASK			BIT(5)
 #define TPS6594_BIT_VMON2_UV_MASK			BIT(6)
 
+/* MASK_BUCK Register field definition */
+#define TPS65224_BIT_BUCK1_UVOV_MASK			BIT(0)
+#define TPS65224_BIT_BUCK2_UVOV_MASK			BIT(1)
+#define TPS65224_BIT_BUCK3_UVOV_MASK			BIT(2)
+#define TPS65224_BIT_BUCK4_UVOV_MASK			BIT(4)
+
+/* MASK_LDO_VMON register field definition */
+#define TPS65224_BIT_LDO1_UVOV_MASK			BIT(0)
+#define TPS65224_BIT_LDO2_UVOV_MASK			BIT(1)
+#define TPS65224_BIT_LDO3_UVOV_MASK			BIT(2)
+#define TPS65224_BIT_VCCA_UVOV_MASK			BIT(4)
+#define TPS65224_BIT_VMON1_UVOV_MASK			BIT(5)
+#define TPS65224_BIT_VMON2_UVOV_MASK			BIT(6)
+
 /* MASK_GPIOX register field definition */
 #define TPS6594_BIT_GPIOX_FALL_MASK(gpio_inst)		BIT((gpio_inst) < 8 ? \
 							    (gpio_inst) : (gpio_inst) % 8)
 #define TPS6594_BIT_GPIOX_RISE_MASK(gpio_inst)		BIT((gpio_inst) < 8 ? \
 							    (gpio_inst) : (gpio_inst) % 8 + 3)
+/* MASK_GPIOX register field definition */
+#define TPS65224_BIT_GPIOX_FALL_MASK(gpio_inst)		BIT((gpio_inst))
+#define TPS65224_BIT_GPIOX_RISE_MASK(gpio_inst)		BIT((gpio_inst))
 
 /* MASK_STARTUP register field definition */
 #define TPS6594_BIT_NPWRON_START_MASK			BIT(0)
 #define TPS6594_BIT_ENABLE_MASK				BIT(1)
 #define TPS6594_BIT_FSD_MASK				BIT(4)
 #define TPS6594_BIT_SOFT_REBOOT_MASK			BIT(5)
+#define TPS65224_BIT_VSENSE_MASK			BIT(0)
+#define TPS65224_BIT_PB_SHORT_MASK			BIT(2)
 
 /* MASK_MISC register field definition */
 #define TPS6594_BIT_BIST_PASS_MASK			BIT(0)
 #define TPS6594_BIT_EXT_CLK_MASK			BIT(1)
+#define TPS65224_BIT_REG_UNLOCK_MASK			BIT(2)
 #define TPS6594_BIT_TWARN_MASK				BIT(3)
+#define TPS65224_BIT_PB_LONG_MASK			BIT(4)
+#define TPS65224_BIT_PB_FALL_MASK			BIT(5)
+#define TPS65224_BIT_PB_RISE_MASK			BIT(6)
+#define TPS65224_BIT_ADC_CONV_READY_MASK		BIT(7)
 
 /* MASK_MODERATE_ERR register field definition */
 #define TPS6594_BIT_BIST_FAIL_MASK			BIT(1)
@@ -391,6 +463,8 @@ enum pmic_id {
 #define TPS6594_BIT_ORD_SHUTDOWN_MASK			BIT(1)
 #define TPS6594_BIT_MCU_PWR_ERR_MASK			BIT(2)
 #define TPS6594_BIT_SOC_PWR_ERR_MASK			BIT(3)
+#define TPS65224_BIT_COMM_ERR_MASK			BIT(4)
+#define TPS65224_BIT_I2C2_ERR_MASK			BIT(5)
 
 /* MASK_COMM_ERR register field definition */
 #define TPS6594_BIT_COMM_FRM_ERR_MASK			BIT(0)
@@ -426,6 +500,12 @@ enum pmic_id {
 #define TPS6594_BIT_BUCK3_4_INT				BIT(1)
 #define TPS6594_BIT_BUCK5_INT				BIT(2)
 
+/* INT_BUCK register field definition */
+#define TPS65224_BIT_BUCK1_UVOV_INT			BIT(0)
+#define TPS65224_BIT_BUCK2_UVOV_INT			BIT(1)
+#define TPS65224_BIT_BUCK3_UVOV_INT			BIT(2)
+#define TPS65224_BIT_BUCK4_UVOV_INT			BIT(3)
+
 /* INT_BUCKX register field definition */
 #define TPS6594_BIT_BUCKX_OV_INT(buck_inst)		BIT(((buck_inst) << 2) % 8)
 #define TPS6594_BIT_BUCKX_UV_INT(buck_inst)		BIT(((buck_inst) << 2) % 8 + 1)
@@ -437,6 +517,14 @@ enum pmic_id {
 #define TPS6594_BIT_LDO3_4_INT				BIT(1)
 #define TPS6594_BIT_VCCA_INT				BIT(4)
 
+/* INT_LDO_VMON register field definition */
+#define TPS65224_BIT_LDO1_UVOV_INT			BIT(0)
+#define TPS65224_BIT_LDO2_UVOV_INT			BIT(1)
+#define TPS65224_BIT_LDO3_UVOV_INT			BIT(2)
+#define TPS65224_BIT_VCCA_UVOV_INT			BIT(4)
+#define TPS65224_BIT_VMON1_UVOV_INT			BIT(5)
+#define TPS65224_BIT_VMON2_UVOV_INT			BIT(6)
+
 /* INT_LDOX register field definition */
 #define TPS6594_BIT_LDOX_OV_INT(ldo_inst)		BIT(((ldo_inst) << 2) % 8)
 #define TPS6594_BIT_LDOX_UV_INT(ldo_inst)		BIT(((ldo_inst) << 2) % 8 + 1)
@@ -462,17 +550,32 @@ enum pmic_id {
 /* INT_GPIOX register field definition */
 #define TPS6594_BIT_GPIOX_INT(gpio_inst)		BIT(gpio_inst)
 
+/* INT_GPIO register field definition */
+#define TPS65224_BIT_GPIO1_INT				BIT(0)
+#define TPS65224_BIT_GPIO2_INT				BIT(1)
+#define TPS65224_BIT_GPIO3_INT				BIT(2)
+#define TPS65224_BIT_GPIO4_INT				BIT(3)
+#define TPS65224_BIT_GPIO5_INT				BIT(4)
+#define TPS65224_BIT_GPIO6_INT				BIT(5)
+
 /* INT_STARTUP register field definition */
 #define TPS6594_BIT_NPWRON_START_INT			BIT(0)
+#define TPS65224_BIT_VSENSE_INT				BIT(0)
 #define TPS6594_BIT_ENABLE_INT				BIT(1)
 #define TPS6594_BIT_RTC_INT				BIT(2)
+#define TPS65224_BIT_PB_SHORT_INT			BIT(2)
 #define TPS6594_BIT_FSD_INT				BIT(4)
 #define TPS6594_BIT_SOFT_REBOOT_INT			BIT(5)
 
 /* INT_MISC register field definition */
 #define TPS6594_BIT_BIST_PASS_INT			BIT(0)
 #define TPS6594_BIT_EXT_CLK_INT				BIT(1)
+#define TPS65224_BIT_REG_UNLOCK_INT			BIT(2)
 #define TPS6594_BIT_TWARN_INT				BIT(3)
+#define TPS65224_BIT_PB_LONG_INT			BIT(4)
+#define TPS65224_BIT_PB_FALL_INT			BIT(5)
+#define TPS65224_BIT_PB_RISE_INT			BIT(6)
+#define TPS65224_BIT_ADC_CONV_READY_INT			BIT(7)
 
 /* INT_MODERATE_ERR register field definition */
 #define TPS6594_BIT_TSD_ORD_INT				BIT(0)
@@ -488,6 +591,7 @@ enum pmic_id {
 #define TPS6594_BIT_TSD_IMM_INT				BIT(0)
 #define TPS6594_BIT_VCCA_OVP_INT			BIT(1)
 #define TPS6594_BIT_PFSM_ERR_INT			BIT(2)
+#define TPS65224_BIT_BG_XMON_INT			BIT(3)
 
 /* INT_FSM_ERR register field definition */
 #define TPS6594_BIT_IMM_SHUTDOWN_INT			BIT(0)
@@ -496,6 +600,7 @@ enum pmic_id {
 #define TPS6594_BIT_SOC_PWR_ERR_INT			BIT(3)
 #define TPS6594_BIT_COMM_ERR_INT			BIT(4)
 #define TPS6594_BIT_READBACK_ERR_INT			BIT(5)
+#define TPS65224_BIT_I2C2_ERR_INT			BIT(5)
 #define TPS6594_BIT_ESM_INT				BIT(6)
 #define TPS6594_BIT_WD_INT				BIT(7)
 
@@ -536,8 +641,18 @@ enum pmic_id {
 #define TPS6594_BIT_VMON2_OV_STAT			BIT(5)
 #define TPS6594_BIT_VMON2_UV_STAT			BIT(6)
 
+/* STAT_LDO_VMON register field definition */
+#define TPS65224_BIT_LDO1_UVOV_STAT			BIT(0)
+#define TPS65224_BIT_LDO2_UVOV_STAT			BIT(1)
+#define TPS65224_BIT_LDO3_UVOV_STAT			BIT(2)
+#define TPS65224_BIT_VCCA_UVOV_STAT			BIT(4)
+#define TPS65224_BIT_VMON1_UVOV_STAT			BIT(5)
+#define TPS65224_BIT_VMON2_UVOV_STAT			BIT(6)
+
 /* STAT_STARTUP register field definition */
+#define TPS65224_BIT_VSENSE_STAT			BIT(0)
 #define TPS6594_BIT_ENABLE_STAT				BIT(1)
+#define TPS65224_BIT_PB_LEVEL_STAT			BIT(2)
 
 /* STAT_MISC register field definition */
 #define TPS6594_BIT_EXT_CLK_STAT			BIT(1)
@@ -549,6 +664,7 @@ enum pmic_id {
 /* STAT_SEVERE_ERR register field definition */
 #define TPS6594_BIT_TSD_IMM_STAT			BIT(0)
 #define TPS6594_BIT_VCCA_OVP_STAT			BIT(1)
+#define TPS65224_BIT_BG_XMON_STAT			BIT(3)
 
 /* STAT_READBACK_ERR register field definition */
 #define TPS6594_BIT_EN_DRV_READBACK_STAT		BIT(0)
@@ -597,6 +713,8 @@ enum pmic_id {
 #define TPS6594_BIT_BB_CHARGER_EN			BIT(0)
 #define TPS6594_BIT_BB_ICHR				BIT(1)
 #define TPS6594_MASK_BB_VEOC				GENMASK(3, 2)
+#define TPS65224_BIT_I2C1_SPI_CRC_EN			BIT(4)
+#define TPS65224_BIT_I2C2_CRC_EN			BIT(5)
 #define TPS6594_BB_EOC_RDY				BIT(7)
 
 /* ENABLE_DRV_REG register field definition */
@@ -617,6 +735,7 @@ enum pmic_id {
 #define TPS6594_BIT_NRSTOUT_SOC_IN			BIT(2)
 #define TPS6594_BIT_FORCE_EN_DRV_LOW			BIT(3)
 #define TPS6594_BIT_SPMI_LPM_EN				BIT(4)
+#define TPS65224_BIT_TSD_DISABLE			BIT(5)
 
 /* RECOV_CNT_REG_1 register field definition */
 #define TPS6594_MASK_RECOV_CNT				GENMASK(3, 0)
@@ -671,15 +790,27 @@ enum pmic_id {
 /* ESM_SOC_START_REG register field definition */
 #define TPS6594_BIT_ESM_SOC_START			BIT(0)
 
+/* ESM_MCU_START_REG register field definition */
+#define TPS65224_BIT_ESM_MCU_START			BIT(0)
+
 /* ESM_SOC_MODE_CFG register field definition */
 #define TPS6594_MASK_ESM_SOC_ERR_CNT_TH			GENMASK(3, 0)
 #define TPS6594_BIT_ESM_SOC_ENDRV			BIT(5)
 #define TPS6594_BIT_ESM_SOC_EN				BIT(6)
 #define TPS6594_BIT_ESM_SOC_MODE			BIT(7)
 
+/* ESM_MCU_MODE_CFG register field definition */
+#define TPS65224_MASK_ESM_MCU_ERR_CNT_TH		GENMASK(3, 0)
+#define TPS65224_BIT_ESM_MCU_ENDRV			BIT(5)
+#define TPS65224_BIT_ESM_MCU_EN				BIT(6)
+#define TPS65224_BIT_ESM_MCU_MODE			BIT(7)
+
 /* ESM_SOC_ERR_CNT_REG register field definition */
 #define TPS6594_MASK_ESM_SOC_ERR_CNT			GENMASK(4, 0)
 
+/* ESM_MCU_ERR_CNT_REG register field definition */
+#define TPS6594_MASK_ESM_MCU_ERR_CNT			GENMASK(4, 0)
+
 /* REGISTER_LOCK register field definition */
 #define TPS6594_BIT_REGISTER_LOCK_STATUS		BIT(0)
 
@@ -687,6 +818,29 @@ enum pmic_id {
 #define TPS6594_MASK_VMON1_SLEW_RATE			GENMASK(2, 0)
 #define TPS6594_MASK_VMON2_SLEW_RATE			GENMASK(5, 3)
 
+/* SRAM_ACCESS_1 Register field definition */
+#define TPS65224_MASk_SRAM_UNLOCK_SEQ			GENMASK(7, 0)
+
+/* SRAM_ACCESS_2 Register field definition */
+#define TPS65224_BIT_SRAM_WRITE_MODE			BIT(0)
+#define TPS65224_BIT_OTP_PROG_USER			BIT(1)
+#define TPS65224_BIT_OTP_PROG_PFSM			BIT(2)
+#define TPS65224_BIT_OTP_PROG_STATUS			BIT(3)
+#define TPS65224_BIT_SRAM_UNLOCKED			BIT(6)
+#define TPS65224_USER_PROG_ALLOWED			BIT(7)
+
+/* SRAM_ADDR_CTRL Register field definition */
+#define TPS65224_MASk_SRAM_SEL				GENMASK(1, 0)
+
+/* RECOV_CNT_PFSM_INCR Register field definition */
+#define TPS65224_BIT_INCREMENT_RECOV_CNT		BIT(0)
+
+/* MANUFACTURING_VER Register field definition */
+#define TPS65224_MASK_SILICON_REV			GENMASK(7, 0)
+
+/* CUSTOMER_NVM_ID_REG Register field definition */
+#define TPS65224_MASK_CUSTOMER_NVM_ID			GENMASK(7, 0)
+
 /* SOFT_REBOOT_REG register field definition */
 #define TPS6594_BIT_SOFT_REBOOT				BIT(0)
 
@@ -755,14 +909,83 @@ enum pmic_id {
 #define TPS6594_BIT_I2C2_CRC_EN				BIT(2)
 #define TPS6594_MASK_T_CRC				GENMASK(7, 3)
 
+/* ADC_CTRL Register field definition */
+#define TPS65224_BIT_ADC_START				BIT(0)
+#define TPS65224_BIT_ADC_CONT_CONV			BIT(1)
+#define TPS65224_BIT_ADC_THERMAL_SEL			BIT(2)
+#define TPS65224_BIT_ADC_RDIV_EN			BIT(3)
+#define TPS65224_BIT_ADC_STATUS				BIT(7)
+
+/* ADC_RESULT_REG_1 Register field definition */
+#define TPS65224_MASK_ADC_RESULT_11_4			GENMASK(7, 0)
+
+/* ADC_RESULT_REG_2 Register field definition */
+#define TPS65224_MASK_ADC_RESULT_3_0			GENMASK(7, 4)
+
+/* STARTUP_CTRL Register field definition */
+#define TPS65224_MASK_STARTUP_DEST			GENMASK(6, 5)
+#define TPS65224_BIT_FIRST_STARTUP_DONE			BIT(7)
+
+/* SCRATCH_PAD_REG_1 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_1			GENMASK(7, 0)
+
+/* SCRATCH_PAD_REG_2 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_2			GENMASK(7, 0)
+
+/* SCRATCH_PAD_REG_3 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_3			GENMASK(7, 0)
+
+/* SCRATCH_PAD_REG_4 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_4			GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_1 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY1			GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_2 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY2			GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_3 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY3			GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_4 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY4			GENMASK(7, 0)
+
+/* CRC_CALC_CONTROL Register field definition */
+#define TPS65224_BIT_RUN_CRC_BIST			BIT(0)
+#define TPS65224_BIT_RUN_CRC_UPDATE			BIT(1)
+
+/* ADC_GAIN_COMP_REG Register field definition */
+#define TPS65224_MASK_ADC_GAIN_COMP			GENMASK(7, 0)
+
+/* REGMAP_USER_CRC_LOW Register field definition */
+#define TPS65224_MASK_REGMAP_USER_CRC16_LOW		GENMASK(7, 0)
+
+/* REGMAP_USER_CRC_HIGH Register field definition */
+#define TPS65224_MASK_REGMAP_USER_CRC16_HIGH		GENMASK(7, 0)
+
+/* WD_ANSWER_REG Register field definition */
+#define TPS6594_MASK_WD_ANSWER				GENMASK(7, 0)
+
 /* WD_QUESTION_ANSW_CNT register field definition */
 #define TPS6594_MASK_WD_QUESTION			GENMASK(3, 0)
 #define TPS6594_MASK_WD_ANSW_CNT			GENMASK(5, 4)
+#define TPS65224_BIT_INT_TOP_STATUS			BIT(7)
+
+/* WD WIN1_CFG register field definition */
+#define TPS6594_MASK_WD_WIN1_CFG			GENMASK(6, 0)
+
+/* WD WIN2_CFG register field definition */
+#define TPS6594_MASK_WD_WIN2_CFG			GENMASK(6, 0)
+
+/* WD LongWin register field definition */
+#define TPS6594_MASK_WD_LONGWIN_CFG			GENMASK(7, 0)
 
 /* WD_MODE_REG register field definition */
 #define TPS6594_BIT_WD_RETURN_LONGWIN			BIT(0)
 #define TPS6594_BIT_WD_MODE_SELECT			BIT(1)
 #define TPS6594_BIT_WD_PWRHOLD				BIT(2)
+#define TPS65224_BIT_WD_ENDRV_SEL			BIT(6)
+#define TPS65224_BIT_WD_CNT_SEL				BIT(7)
 
 /* WD_QA_CFG register field definition */
 #define TPS6594_MASK_WD_QUESTION_SEED			GENMASK(3, 0)
@@ -993,6 +1216,113 @@ enum tps6594_irqs {
 #define TPS6594_IRQ_NAME_ALARM			"alarm"
 #define TPS6594_IRQ_NAME_POWERUP		"powerup"
 
+/* IRQs */
+enum tps65224_irqs {
+	/* INT_BUCK register */
+	TPS65224_IRQ_BUCK1_UVOV,
+	TPS65224_IRQ_BUCK2_UVOV,
+	TPS65224_IRQ_BUCK3_UVOV,
+	TPS65224_IRQ_BUCK4_UVOV,
+	/* INT_LDO_VMON register */
+	TPS65224_IRQ_LDO1_UVOV,
+	TPS65224_IRQ_LDO2_UVOV,
+	TPS65224_IRQ_LDO3_UVOV,
+	TPS65224_IRQ_VCCA_UVOV,
+	TPS65224_IRQ_VMON1_UVOV,
+	TPS65224_IRQ_VMON2_UVOV,
+	/* INT_GPIO register */
+	TPS65224_IRQ_GPIO1,
+	TPS65224_IRQ_GPIO2,
+	TPS65224_IRQ_GPIO3,
+	TPS65224_IRQ_GPIO4,
+	TPS65224_IRQ_GPIO5,
+	TPS65224_IRQ_GPIO6,
+	/* INT_STARTUP register */
+	TPS65224_IRQ_VSENSE,
+	TPS65224_IRQ_ENABLE,
+	TPS65224_IRQ_PB_SHORT,
+	TPS65224_IRQ_FSD,
+	TPS65224_IRQ_SOFT_REBOOT,
+	/* INT_MISC register */
+	TPS65224_IRQ_BIST_PASS,
+	TPS65224_IRQ_EXT_CLK,
+	TPS65224_IRQ_REG_UNLOCK,
+	TPS65224_IRQ_TWARN,
+	TPS65224_IRQ_PB_LONG,
+	TPS65224_IRQ_PB_FALL,
+	TPS65224_IRQ_PB_RISE,
+	TPS65224_IRQ_ADC_CONV_READY,
+	/* INT_MODERATE_ERR register */
+	TPS65224_IRQ_TSD_ORD,
+	TPS65224_IRQ_BIST_FAIL,
+	TPS65224_IRQ_REG_CRC_ERR,
+	TPS65224_IRQ_RECOV_CNT,
+	/* INT_SEVERE_ERR register */
+	TPS65224_IRQ_TSD_IMM,
+	TPS65224_IRQ_VCCA_OVP,
+	TPS65224_IRQ_PFSM_ERR,
+	TPS65224_IRQ_BG_XMON,
+	/* INT_FSM_ERR register */
+	TPS65224_IRQ_IMM_SHUTDOWN,
+	TPS65224_IRQ_ORD_SHUTDOWN,
+	TPS65224_IRQ_MCU_PWR_ERR,
+	TPS65224_IRQ_SOC_PWR_ERR,
+	TPS65224_IRQ_COMM_ERR,
+	TPS65224_IRQ_I2C2_ERR,
+	/* INT_ESM register */
+	TPS65224_IRQ_ESM_MCU_PIN,
+	TPS65224_IRQ_ESM_MCU_FAIL,
+	TPS65224_IRQ_ESM_MCU_RST,
+};
+
+#define TPS65224_IRQ_NAME_BUCK1_UVOV		"buck1_uvov"
+#define TPS65224_IRQ_NAME_BUCK2_UVOV		"buck2_uvov"
+#define TPS65224_IRQ_NAME_BUCK3_UVOV		"buck3_uvov"
+#define TPS65224_IRQ_NAME_BUCK4_UVOV		"buck4_uvov"
+#define TPS65224_IRQ_NAME_LDO1_UVOV		"ldo1_uvov"
+#define TPS65224_IRQ_NAME_LDO2_UVOV		"ldo2_uvov"
+#define TPS65224_IRQ_NAME_LDO3_UVOV		"ldo3_uvov"
+#define TPS65224_IRQ_NAME_VCCA_UVOV		"vcca_uvov"
+#define TPS65224_IRQ_NAME_VMON1_UVOV		"vmon1_uvov"
+#define TPS65224_IRQ_NAME_VMON2_UVOV		"vmon2_uvov"
+#define TPS65224_IRQ_NAME_GPIO1			"gpio1"
+#define TPS65224_IRQ_NAME_GPIO2			"gpio2"
+#define TPS65224_IRQ_NAME_GPIO3			"gpio3"
+#define TPS65224_IRQ_NAME_GPIO4			"gpio4"
+#define TPS65224_IRQ_NAME_GPIO5			"gpio5"
+#define TPS65224_IRQ_NAME_GPIO6			"gpio6"
+#define TPS65224_IRQ_NAME_VSENSE	        "vsense"
+#define TPS65224_IRQ_NAME_ENABLE		"enable"
+#define TPS65224_IRQ_NAME_PB_SHORT		"pb_short"
+#define TPS65224_IRQ_NAME_FSD			"fsd"
+#define TPS65224_IRQ_NAME_SOFT_REBOOT		"soft_reboot"
+#define TPS65224_IRQ_NAME_BIST_PASS		"bist_pass"
+#define TPS65224_IRQ_NAME_EXT_CLK		"ext_clk"
+#define TPS65224_IRQ_NAME_REG_UNLOCK		"reg_unlock"
+#define TPS65224_IRQ_NAME_TWARN			"twarn"
+#define TPS65224_IRQ_NAME_PB_LONG		"pb_long"
+#define TPS65224_IRQ_NAME_PB_FALL		"pb_fall"
+#define TPS65224_IRQ_NAME_PB_RISE		"pb_rise"
+#define TPS65224_IRQ_NAME_ADC_CONV_READY	"adc_conv_ready"
+#define TPS65224_IRQ_NAME_TSD_ORD		"tsd_ord"
+#define TPS65224_IRQ_NAME_BIST_FAIL		"bist_fail"
+#define TPS65224_IRQ_NAME_REG_CRC_ERR		"reg_crc_err"
+#define TPS65224_IRQ_NAME_RECOV_CNT		"recov_cnt"
+#define TPS65224_IRQ_NAME_TSD_IMM		"tsd_imm"
+#define TPS65224_IRQ_NAME_VCCA_OVP		"vcca_ovp"
+#define TPS65224_IRQ_NAME_PFSM_ERR		"pfsm_err"
+#define TPS65224_IRQ_NAME_BG_XMON		"bg_xmon"
+#define TPS65224_IRQ_NAME_IMM_SHUTDOWN		"imm_shutdown"
+#define TPS65224_IRQ_NAME_ORD_SHUTDOWN		"ord_shutdown"
+#define TPS65224_IRQ_NAME_MCU_PWR_ERR		"mcu_pwr_err"
+#define TPS65224_IRQ_NAME_SOC_PWR_ERR		"soc_pwr_err"
+#define TPS65224_IRQ_NAME_COMM_ERR		"comm_err"
+#define TPS65224_IRQ_NAME_I2C2_ERR		"i2c2_err"
+#define TPS65224_IRQ_NAME_ESM_MCU_PIN		"esm_mcu_pin"
+#define TPS65224_IRQ_NAME_ESM_MCU_FAIL		"esm_mcu_fail"
+#define TPS65224_IRQ_NAME_ESM_MCU_RST		"esm_mcu_rst"
+#define TPS65224_IRQ_NAME_POWERUP		"powerup"
+
 /**
  * struct tps6594 - device private data structure
  *
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:34 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:34 +0530
Subject: [RESEND PATCH v1 04/13] mfd: tps6594-i2c: Add TI TPS65224 PMIC I2C
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-5-bhargav.r@ltts.com>

Add support for TPS65224 PMIC in TPS6594's I2C driver which has
significant functional overlap.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/mfd/tps6594-i2c.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/mfd/tps6594-i2c.c b/drivers/mfd/tps6594-i2c.c
index c125b474b..4ab91c34d 100644
--- a/drivers/mfd/tps6594-i2c.c
+++ b/drivers/mfd/tps6594-i2c.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * I2C access driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * I2C access driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
@@ -183,7 +183,7 @@ static int tps6594_i2c_write(void *context, const void *data, size_t count)
 	return ret;
 }
 
-static const struct regmap_config tps6594_i2c_regmap_config = {
+static struct regmap_config tps6594_i2c_regmap_config = {
 	.reg_bits = 16,
 	.val_bits = 8,
 	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
@@ -196,6 +196,7 @@ static const struct of_device_id tps6594_i2c_of_match_table[] = {
 	{ .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
 	{ .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
 	{ .compatible = "ti,lp8764-q1",  .data = (void *)LP8764,  },
+	{ .compatible = "ti,tps65224-q1", .data = (void *)TPS65224, },
 	{}
 };
 MODULE_DEVICE_TABLE(of, tps6594_i2c_of_match_table);
@@ -216,15 +217,18 @@ static int tps6594_i2c_probe(struct i2c_client *client)
 	tps->reg = client->addr;
 	tps->irq = client->irq;
 
-	tps->regmap = devm_regmap_init(dev, NULL, client, &tps6594_i2c_regmap_config);
-	if (IS_ERR(tps->regmap))
-		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
-
 	match = of_match_device(tps6594_i2c_of_match_table, dev);
 	if (!match)
 		return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n");
 	tps->chip_id = (unsigned long)match->data;
 
+	if (tps->chip_id == TPS65224)
+		tps6594_i2c_regmap_config.volatile_table = &tps65224_volatile_table;
+
+	tps->regmap = devm_regmap_init(dev, NULL, client, &tps6594_i2c_regmap_config);
+	if (IS_ERR(tps->regmap))
+		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
+
 	crc8_populate_msb(tps6594_i2c_crc_table, TPS6594_CRC8_POLYNOMIAL);
 
 	return tps6594_device_init(tps, enable_crc);
@@ -240,5 +244,5 @@ static struct i2c_driver tps6594_i2c_driver = {
 module_i2c_driver(tps6594_i2c_driver);
 
 MODULE_AUTHOR("Julien Panis <jpanis at baylibre.com>");
-MODULE_DESCRIPTION("TPS6594 I2C Interface Driver");
+MODULE_DESCRIPTION("I2C Interface Driver for TPS65224, TPS6594/3, and LP8764");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:35 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:35 +0530
Subject: [RESEND PATCH v1 05/13] mfd: tps6594-spi: Add TI TPS65224 PMIC SPI
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-6-bhargav.r@ltts.com>

Add support for TPS65224 PMIC in the TPS6594 driver as they share
significant functional overlap.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/mfd/tps6594-spi.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
index 5afb1736f..7ec66d31b 100644
--- a/drivers/mfd/tps6594-spi.c
+++ b/drivers/mfd/tps6594-spi.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SPI access driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * SPI access driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
@@ -66,7 +66,7 @@ static int tps6594_spi_reg_write(void *context, unsigned int reg, unsigned int v
 	return spi_write(spi, buf, count);
 }
 
-static const struct regmap_config tps6594_spi_regmap_config = {
+static struct regmap_config tps6594_spi_regmap_config = {
 	.reg_bits = 16,
 	.val_bits = 8,
 	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
@@ -81,6 +81,7 @@ static const struct of_device_id tps6594_spi_of_match_table[] = {
 	{ .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
 	{ .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
 	{ .compatible = "ti,lp8764-q1",  .data = (void *)LP8764,  },
+	{ .compatible = "ti,tps65224-q1", .data = (void *)TPS65224, },
 	{}
 };
 MODULE_DEVICE_TABLE(of, tps6594_spi_of_match_table);
@@ -101,15 +102,18 @@ static int tps6594_spi_probe(struct spi_device *spi)
 	tps->reg = spi_get_chipselect(spi, 0);
 	tps->irq = spi->irq;
 
-	tps->regmap = devm_regmap_init(dev, NULL, spi, &tps6594_spi_regmap_config);
-	if (IS_ERR(tps->regmap))
-		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
-
 	match = of_match_device(tps6594_spi_of_match_table, dev);
 	if (!match)
 		return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n");
 	tps->chip_id = (unsigned long)match->data;
 
+	if (tps->chip_id == TPS65224)
+		tps6594_spi_regmap_config.volatile_table = &tps65224_volatile_table;
+
+	tps->regmap = devm_regmap_init(dev, NULL, spi, &tps6594_spi_regmap_config);
+	if (IS_ERR(tps->regmap))
+		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
+
 	crc8_populate_msb(tps6594_spi_crc_table, TPS6594_CRC8_POLYNOMIAL);
 
 	return tps6594_device_init(tps, enable_crc);
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:36 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:36 +0530
Subject: [RESEND PATCH v1 06/13] mfd: tps6594-core: Add TI TPS65224 PMIC core
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-7-bhargav.r@ltts.com>

Add functionality of the TPS65224 PMIC to the TPS6594 core driver. This
includes adding IRQ resource, MFD cells, and device initialization for
TPS65224.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/mfd/tps6594-core.c | 242 ++++++++++++++++++++++++++++++++++---
 1 file changed, 228 insertions(+), 14 deletions(-)

diff --git a/drivers/mfd/tps6594-core.c b/drivers/mfd/tps6594-core.c
index 089ab8cc8..f18663560 100644
--- a/drivers/mfd/tps6594-core.c
+++ b/drivers/mfd/tps6594-core.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Core functions for TI TPS6594/TPS6593/LP8764 PMICs
+ * Core functions for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
@@ -278,16 +278,172 @@ static const unsigned int tps6594_irq_reg[] = {
 	TPS6594_REG_RTC_STATUS,
 };
 
+/* TPS65224 Resources */
+
+static const struct resource tps65224_regulator_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BUCK1_UVOV, TPS65224_IRQ_NAME_BUCK1_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BUCK2_UVOV, TPS65224_IRQ_NAME_BUCK2_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BUCK3_UVOV, TPS65224_IRQ_NAME_BUCK3_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BUCK4_UVOV, TPS65224_IRQ_NAME_BUCK4_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_LDO1_UVOV, TPS65224_IRQ_NAME_LDO1_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_LDO2_UVOV, TPS65224_IRQ_NAME_LDO2_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_LDO3_UVOV, TPS65224_IRQ_NAME_LDO3_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_VCCA_UVOV, TPS65224_IRQ_NAME_VCCA_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_VMON1_UVOV, TPS65224_IRQ_NAME_VMON1_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_VMON2_UVOV, TPS65224_IRQ_NAME_VMON2_UVOV),
+};
+
+static const struct resource tps65224_pinctrl_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO1, TPS65224_IRQ_NAME_GPIO1),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO2, TPS65224_IRQ_NAME_GPIO2),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO3, TPS65224_IRQ_NAME_GPIO3),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO4, TPS65224_IRQ_NAME_GPIO4),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO5, TPS65224_IRQ_NAME_GPIO5),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO6, TPS65224_IRQ_NAME_GPIO6),
+};
+
+static const struct resource tps65224_pfsm_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_VSENSE, TPS65224_IRQ_NAME_VSENSE),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ENABLE, TPS65224_IRQ_NAME_ENABLE),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_SHORT, TPS65224_IRQ_NAME_PB_SHORT),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_FSD, TPS65224_IRQ_NAME_FSD),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_SOFT_REBOOT, TPS65224_IRQ_NAME_SOFT_REBOOT),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BIST_PASS, TPS65224_IRQ_NAME_BIST_PASS),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_EXT_CLK, TPS65224_IRQ_NAME_EXT_CLK),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_REG_UNLOCK, TPS65224_IRQ_NAME_REG_UNLOCK),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_TWARN, TPS65224_IRQ_NAME_TWARN),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_LONG, TPS65224_IRQ_NAME_PB_LONG),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_FALL, TPS65224_IRQ_NAME_PB_FALL),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_RISE, TPS65224_IRQ_NAME_PB_RISE),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_TSD_ORD, TPS65224_IRQ_NAME_TSD_ORD),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BIST_FAIL, TPS65224_IRQ_NAME_BIST_FAIL),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_REG_CRC_ERR, TPS65224_IRQ_NAME_REG_CRC_ERR),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_RECOV_CNT, TPS65224_IRQ_NAME_RECOV_CNT),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_TSD_IMM, TPS65224_IRQ_NAME_TSD_IMM),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_VCCA_OVP, TPS65224_IRQ_NAME_VCCA_OVP),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PFSM_ERR, TPS65224_IRQ_NAME_PFSM_ERR),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BG_XMON, TPS65224_IRQ_NAME_BG_XMON),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_IMM_SHUTDOWN, TPS65224_IRQ_NAME_IMM_SHUTDOWN),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ORD_SHUTDOWN, TPS65224_IRQ_NAME_ORD_SHUTDOWN),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_MCU_PWR_ERR, TPS65224_IRQ_NAME_MCU_PWR_ERR),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_SOC_PWR_ERR, TPS65224_IRQ_NAME_SOC_PWR_ERR),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_COMM_ERR, TPS65224_IRQ_NAME_COMM_ERR),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_I2C2_ERR, TPS65224_IRQ_NAME_I2C2_ERR),
+};
+
+static const struct resource tps65224_esm_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ESM_MCU_PIN, TPS65224_IRQ_NAME_ESM_MCU_PIN),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ESM_MCU_FAIL, TPS65224_IRQ_NAME_ESM_MCU_FAIL),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ESM_MCU_RST, TPS65224_IRQ_NAME_ESM_MCU_RST),
+};
+
+static const struct resource tps65224_adc_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ADC_CONV_READY, TPS65224_IRQ_NAME_ADC_CONV_READY),
+};
+
+static const struct mfd_cell tps65224_common_cells[] = {
+	MFD_CELL_RES("tps65224-adc", tps65224_adc_resources),
+	MFD_CELL_RES("tps6594-esm", tps65224_esm_resources),
+	MFD_CELL_RES("tps6594-pfsm", tps65224_pfsm_resources),
+	MFD_CELL_RES("tps6594-pinctrl", tps65224_pinctrl_resources),
+	MFD_CELL_RES("tps6594-regulator", tps65224_regulator_resources),
+};
+
+static const struct regmap_irq tps65224_irqs[] = {
+	/* INT_BUCK register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_BUCK1_UVOV, 0, TPS65224_BIT_BUCK1_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_BUCK2_UVOV, 0, TPS65224_BIT_BUCK2_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_BUCK3_UVOV, 0, TPS65224_BIT_BUCK3_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_BUCK4_UVOV, 0, TPS65224_BIT_BUCK4_UVOV_INT),
+
+	/* INT_VMON_LDO register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_LDO1_UVOV, 1, TPS65224_BIT_LDO1_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_LDO2_UVOV, 1, TPS65224_BIT_LDO2_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_LDO3_UVOV, 1, TPS65224_BIT_LDO3_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_VCCA_UVOV, 1, TPS65224_BIT_VCCA_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_VMON1_UVOV, 1, TPS65224_BIT_VMON1_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_VMON2_UVOV, 1, TPS65224_BIT_VMON2_UVOV_INT),
+
+	/* INT_GPIO register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO1, 2, TPS65224_BIT_GPIO1_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO2, 2, TPS65224_BIT_GPIO2_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO3, 2, TPS65224_BIT_GPIO3_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO4, 2, TPS65224_BIT_GPIO4_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO5, 2, TPS65224_BIT_GPIO5_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO6, 2, TPS65224_BIT_GPIO6_INT),
+
+	/* INT_STARTUP register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_VSENSE, 3, TPS65224_BIT_VSENSE_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_ENABLE, 3, TPS6594_BIT_ENABLE_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_PB_SHORT, 3, TPS65224_BIT_PB_SHORT_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_FSD, 3, TPS6594_BIT_FSD_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_SOFT_REBOOT, 3, TPS6594_BIT_SOFT_REBOOT_INT),
+
+	/* INT_MISC register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_BIST_PASS, 4, TPS6594_BIT_BIST_PASS_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_EXT_CLK, 4, TPS6594_BIT_EXT_CLK_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_REG_UNLOCK, 4, TPS65224_BIT_REG_UNLOCK_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_TWARN, 4, TPS6594_BIT_TWARN_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_PB_LONG, 4, TPS65224_BIT_PB_LONG_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_PB_FALL, 4, TPS65224_BIT_PB_FALL_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_PB_RISE, 4, TPS65224_BIT_PB_RISE_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_ADC_CONV_READY, 4, TPS65224_BIT_ADC_CONV_READY_INT),
+
+	/* INT_MODERATE_ERR register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_TSD_ORD, 5, TPS6594_BIT_TSD_ORD_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_BIST_FAIL, 5, TPS6594_BIT_BIST_FAIL_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_REG_CRC_ERR, 5, TPS6594_BIT_REG_CRC_ERR_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_RECOV_CNT, 5, TPS6594_BIT_RECOV_CNT_INT),
+
+	/* INT_SEVERE_ERR register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_TSD_IMM, 6, TPS6594_BIT_TSD_IMM_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_VCCA_OVP, 6, TPS6594_BIT_VCCA_OVP_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_PFSM_ERR, 6, TPS6594_BIT_PFSM_ERR_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_BG_XMON, 6, TPS65224_BIT_BG_XMON_INT),
+
+	/* INT_FSM_ERR register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_IMM_SHUTDOWN, 7, TPS6594_BIT_IMM_SHUTDOWN_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_ORD_SHUTDOWN, 7, TPS6594_BIT_ORD_SHUTDOWN_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_MCU_PWR_ERR, 7, TPS6594_BIT_MCU_PWR_ERR_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_SOC_PWR_ERR, 7, TPS6594_BIT_SOC_PWR_ERR_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_COMM_ERR, 7, TPS6594_BIT_COMM_ERR_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_I2C2_ERR, 7, TPS65224_BIT_I2C2_ERR_INT),
+
+	/* INT_ESM register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_ESM_MCU_PIN, 8, TPS6594_BIT_ESM_MCU_PIN_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_ESM_MCU_FAIL, 8, TPS6594_BIT_ESM_MCU_FAIL_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_ESM_MCU_RST, 8, TPS6594_BIT_ESM_MCU_RST_INT),
+};
+
+static const unsigned int tps65224_irq_reg[] = {
+	TPS6594_REG_INT_BUCK,
+	TPS6594_REG_INT_LDO_VMON,
+	TPS6594_REG_INT_GPIO,
+	TPS6594_REG_INT_STARTUP,
+	TPS6594_REG_INT_MISC,
+	TPS6594_REG_INT_MODERATE_ERR,
+	TPS6594_REG_INT_SEVERE_ERR,
+	TPS6594_REG_INT_FSM_ERR,
+	TPS6594_REG_INT_ESM,
+};
+
 static inline unsigned int tps6594_get_irq_reg(struct regmap_irq_chip_data *data,
 					       unsigned int base, int index)
 {
 	return tps6594_irq_reg[index];
 };
 
+static inline unsigned int tps65224_get_irq_reg(struct regmap_irq_chip_data *data,
+						unsigned int base, int index)
+{
+	return tps65224_irq_reg[index];
+};
+
 static int tps6594_handle_post_irq(void *irq_drv_data)
 {
 	struct tps6594 *tps = irq_drv_data;
 	int ret = 0;
+	unsigned int regmap_reg, mask_val;
 
 	/*
 	 * When CRC is enabled, writing to a read-only bit triggers an error,
@@ -299,10 +455,17 @@ static int tps6594_handle_post_irq(void *irq_drv_data)
 	 * COMM_ADR_ERR_INT bit set. Clear immediately this bit to avoid raising
 	 * a new interrupt.
 	 */
-	if (tps->use_crc)
-		ret = regmap_write_bits(tps->regmap, TPS6594_REG_INT_COMM_ERR,
-					TPS6594_BIT_COMM_ADR_ERR_INT,
-					TPS6594_BIT_COMM_ADR_ERR_INT);
+	if (tps->use_crc) {
+		if (tps->chip_id == TPS65224) {
+			regmap_reg = TPS6594_REG_INT_FSM_ERR;
+			mask_val = TPS6594_BIT_COMM_ERR_INT;
+		} else {
+			regmap_reg = TPS6594_REG_INT_COMM_ERR;
+			mask_val = TPS6594_BIT_COMM_ADR_ERR_INT;
+		}
+
+		ret = regmap_write_bits(tps->regmap, regmap_reg, mask_val, mask_val);
+	}
 
 	return ret;
 };
@@ -319,6 +482,18 @@ static struct regmap_irq_chip tps6594_irq_chip = {
 	.handle_post_irq = tps6594_handle_post_irq,
 };
 
+static struct regmap_irq_chip tps65224_irq_chip = {
+	.ack_base = TPS6594_REG_INT_BUCK,
+	.ack_invert = 1,
+	.clear_ack = 1,
+	.init_ack_masked = 1,
+	.num_regs = ARRAY_SIZE(tps65224_irq_reg),
+	.irqs = tps65224_irqs,
+	.num_irqs = ARRAY_SIZE(tps65224_irqs),
+	.get_irq_reg = tps65224_get_irq_reg,
+	.handle_post_irq = tps6594_handle_post_irq,
+};
+
 static const struct regmap_range tps6594_volatile_ranges[] = {
 	regmap_reg_range(TPS6594_REG_INT_TOP, TPS6594_REG_STAT_READBACK_ERR),
 	regmap_reg_range(TPS6594_REG_RTC_STATUS, TPS6594_REG_RTC_STATUS),
@@ -330,17 +505,35 @@ const struct regmap_access_table tps6594_volatile_table = {
 };
 EXPORT_SYMBOL_GPL(tps6594_volatile_table);
 
+static const struct regmap_range tps65224_volatile_ranges[] = {
+	regmap_reg_range(TPS6594_REG_INT_TOP, TPS6594_REG_STAT_SEVERE_ERR),
+};
+
+const struct regmap_access_table tps65224_volatile_table = {
+	.yes_ranges = tps65224_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(tps65224_volatile_ranges),
+};
+EXPORT_SYMBOL_GPL(tps65224_volatile_table);
+
 static int tps6594_check_crc_mode(struct tps6594 *tps, bool primary_pmic)
 {
 	int ret;
+	unsigned int regmap_reg, mask_val;
+
+	if (tps->chip_id == TPS65224) {
+		regmap_reg = TPS6594_REG_CONFIG_2;
+		mask_val = TPS65224_BIT_I2C1_SPI_CRC_EN;
+	} else {
+		regmap_reg = TPS6594_REG_SERIAL_IF_CONFIG;
+		mask_val = TPS6594_BIT_I2C1_SPI_CRC_EN;
+	};
 
 	/*
 	 * Check if CRC is enabled.
 	 * Once CRC is enabled, it can't be disabled until next power cycle.
 	 */
 	tps->use_crc = true;
-	ret = regmap_test_bits(tps->regmap, TPS6594_REG_SERIAL_IF_CONFIG,
-			       TPS6594_BIT_I2C1_SPI_CRC_EN);
+	ret = regmap_test_bits(tps->regmap, regmap_reg, mask_val);
 	if (ret == 0) {
 		ret = -EIO;
 	} else if (ret > 0) {
@@ -355,6 +548,15 @@ static int tps6594_check_crc_mode(struct tps6594 *tps, bool primary_pmic)
 static int tps6594_set_crc_feature(struct tps6594 *tps)
 {
 	int ret;
+	unsigned int regmap_reg, mask_val;
+
+	if (tps->chip_id == TPS65224) {
+		regmap_reg = TPS6594_REG_CONFIG_2;
+		mask_val = TPS65224_BIT_I2C1_SPI_CRC_EN;
+	} else {
+		regmap_reg = TPS6594_REG_FSM_I2C_TRIGGERS;
+		mask_val = TPS6594_BIT_TRIGGER_I2C(2);
+	}
 
 	ret = tps6594_check_crc_mode(tps, true);
 	if (ret) {
@@ -363,8 +565,7 @@ static int tps6594_set_crc_feature(struct tps6594 *tps)
 		 * on primary PMIC.
 		 */
 		tps->use_crc = false;
-		ret = regmap_write_bits(tps->regmap, TPS6594_REG_FSM_I2C_TRIGGERS,
-					TPS6594_BIT_TRIGGER_I2C(2), TPS6594_BIT_TRIGGER_I2C(2));
+		ret = regmap_write_bits(tps->regmap, regmap_reg, mask_val, mask_val);
 		if (ret)
 			return ret;
 
@@ -420,6 +621,9 @@ int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
 {
 	struct device *dev = tps->dev;
 	int ret;
+	struct regmap_irq_chip *irq_chip;
+	const struct mfd_cell *cells;
+	int n_cells;
 
 	if (enable_crc) {
 		ret = tps6594_enable_crc(tps);
@@ -440,19 +644,28 @@ int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
 	if (!tps6594_irq_chip.name)
 		return -ENOMEM;
 
+	if (tps->chip_id == TPS65224) {
+		irq_chip = &tps65224_irq_chip;
+		n_cells = ARRAY_SIZE(tps65224_common_cells);
+		cells = tps65224_common_cells;
+	} else {
+		irq_chip = &tps6594_irq_chip;
+		n_cells = ARRAY_SIZE(tps6594_common_cells);
+		cells = tps6594_common_cells;
+	}
+
 	ret = devm_regmap_add_irq_chip(dev, tps->regmap, tps->irq, IRQF_SHARED | IRQF_ONESHOT,
-				       0, &tps6594_irq_chip, &tps->irq_data);
+				       0, irq_chip, &tps->irq_data);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to add regmap IRQ\n");
 
-	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, tps6594_common_cells,
-				   ARRAY_SIZE(tps6594_common_cells), NULL, 0,
+	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, n_cells, NULL, 0,
 				   regmap_irq_get_domain(tps->irq_data));
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to add common child devices\n");
 
-	/* No RTC for LP8764 */
-	if (tps->chip_id != LP8764) {
+	/* No RTC for LP8764 and TPS65224 */
+	if (tps->chip_id != LP8764 && tps->chip_id != TPS65224) {
 		ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, tps6594_rtc_cells,
 					   ARRAY_SIZE(tps6594_rtc_cells), NULL, 0,
 					   regmap_irq_get_domain(tps->irq_data));
@@ -465,5 +678,6 @@ int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
 EXPORT_SYMBOL_GPL(tps6594_device_init);
 
 MODULE_AUTHOR("Julien Panis <jpanis at baylibre.com>");
+MODULE_AUTHOR("Bhargav Raviprakash <bhargav.r at ltts.com");
 MODULE_DESCRIPTION("TPS6594 Driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:37 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:37 +0530
Subject: [RESEND PATCH v1 07/13] misc: tps6594-pfsm: Add TI TPS65224 PMIC PFSM
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-8-bhargav.r@ltts.com>

Add support for TPS65224 PFSM in the TPS6594 PFSM driver
as they share significant functionality.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/misc/tps6594-pfsm.c | 55 +++++++++++++++++++++++++++----------
 1 file changed, 40 insertions(+), 15 deletions(-)

diff --git a/drivers/misc/tps6594-pfsm.c b/drivers/misc/tps6594-pfsm.c
index 88dcac814..4fa071093 100644
--- a/drivers/misc/tps6594-pfsm.c
+++ b/drivers/misc/tps6594-pfsm.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * PFSM (Pre-configurable Finite State Machine) driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * PFSM (Pre-configurable Finite State Machine) driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
@@ -34,15 +34,17 @@
 
 #define TPS6594_FILE_TO_PFSM(f) container_of((f)->private_data, struct tps6594_pfsm, miscdev)
 
-/**
+/*
  * struct tps6594_pfsm - device private data structure
  *
  * @miscdev: misc device infos
  * @regmap:  regmap for accessing the device registers
+ * @chip_id: chip identifier of the device
  */
 struct tps6594_pfsm {
 	struct miscdevice miscdev;
 	struct regmap *regmap;
+	unsigned long chip_id;
 };
 
 static ssize_t tps6594_pfsm_read(struct file *f, char __user *buf,
@@ -133,21 +135,29 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
 	struct tps6594_pfsm *pfsm = TPS6594_FILE_TO_PFSM(f);
 	struct pmic_state_opt state_opt;
 	void __user *argp = (void __user *)arg;
+	unsigned int regmap_reg, mask;
 	int ret = -ENOIOCTLCMD;
 
 	switch (cmd) {
 	case PMIC_GOTO_STANDBY:
-		/* Disable LP mode */
-		ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
-					TPS6594_BIT_LP_STANDBY_SEL);
-		if (ret)
-			return ret;
+		/* Disable LP mode on TPS6594 Family PMIC */
+		if (pfsm->chip_id != TPS65224) {
+			ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
+						TPS6594_BIT_LP_STANDBY_SEL);
+
+			if (ret)
+				return ret;
+		}
 
 		/* Force trigger */
 		ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_FSM_I2C_TRIGGERS,
 					TPS6594_BIT_TRIGGER_I2C(0), TPS6594_BIT_TRIGGER_I2C(0));
 		break;
 	case PMIC_GOTO_LP_STANDBY:
+		/* TPS65224 does not support LP STANDBY */
+		if (pfsm->chip_id == TPS65224)
+			return ret;
+
 		/* Enable LP mode */
 		ret = regmap_set_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
 				      TPS6594_BIT_LP_STANDBY_SEL);
@@ -169,6 +179,10 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
 				      TPS6594_BIT_NSLEEP1B | TPS6594_BIT_NSLEEP2B);
 		break;
 	case PMIC_SET_MCU_ONLY_STATE:
+		/* TPS65224 does not support MCU_ONLY_STATE */
+		if (pfsm->chip_id == TPS65224)
+			return ret;
+
 		if (copy_from_user(&state_opt, argp, sizeof(state_opt)))
 			return -EFAULT;
 
@@ -192,14 +206,20 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
 			return -EFAULT;
 
 		/* Configure wake-up destination */
+		if (pfsm->chip_id == TPS65224) {
+			regmap_reg = TPS65224_REG_STARTUP_CTRL;
+			mask = TPS65224_MASK_STARTUP_DEST;
+		} else {
+			regmap_reg = TPS6594_REG_RTC_CTRL_2;
+			mask = TPS6594_MASK_STARTUP_DEST;
+		}
+
 		if (state_opt.mcu_only_startup_dest)
-			ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
-						TPS6594_MASK_STARTUP_DEST,
-						TPS6594_STARTUP_DEST_MCU_ONLY);
+			ret = regmap_write_bits(pfsm->regmap, regmap_reg,
+						mask, TPS6594_STARTUP_DEST_MCU_ONLY);
 		else
-			ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
-						TPS6594_MASK_STARTUP_DEST,
-						TPS6594_STARTUP_DEST_ACTIVE);
+			ret = regmap_write_bits(pfsm->regmap, regmap_reg,
+						mask, TPS6594_STARTUP_DEST_ACTIVE);
 		if (ret)
 			return ret;
 
@@ -210,8 +230,12 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
 			return ret;
 
 		/* Modify NSLEEP1-2 bits */
-		ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
-					TPS6594_BIT_NSLEEP2B);
+		if (pfsm->chip_id == TPS65224)
+			ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
+						TPS6594_BIT_NSLEEP1B);
+		else
+			ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
+						TPS6594_BIT_NSLEEP2B);
 		break;
 	}
 
@@ -262,6 +286,7 @@ static int tps6594_pfsm_probe(struct platform_device *pdev)
 					    tps->chip_id, tps->reg);
 	pfsm->miscdev.fops = &tps6594_pfsm_fops;
 	pfsm->miscdev.parent = dev->parent;
+	pfsm->chip_id = tps->chip_id;
 
 	for (i = 0 ; i < pdev->num_resources ; i++) {
 		irq = platform_get_irq_byname(pdev, pdev->resource[i].name);
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:38 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:38 +0530
Subject: [RESEND PATCH v1 08/13] misc: tps6594-esm: reversion check limited to TPS6594 family
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-9-bhargav.r@ltts.com>

The reversion check is only applicable on TPS6594 family of PMICs.
Conditionally add that check if the chip_id is one of the PMIC in
the TPS6594 family.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/misc/tps6594-esm.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/misc/tps6594-esm.c b/drivers/misc/tps6594-esm.c
index b4d67a1a2..8ec5af9dc 100644
--- a/drivers/misc/tps6594-esm.c
+++ b/drivers/misc/tps6594-esm.c
@@ -45,13 +45,17 @@ static int tps6594_esm_probe(struct platform_device *pdev)
 	 * As a consequence, ESM can not be used on those PMIC.
 	 * Check the version and return an error in case of revision 1.
 	 */
-	ret = regmap_read(tps->regmap, TPS6594_REG_DEV_REV, &rev);
-	if (ret)
-		return dev_err_probe(dev, ret,
-				     "Failed to read PMIC revision\n");
-	if (rev == TPS6594_DEV_REV_1)
-		return dev_err_probe(dev, -ENODEV,
-			      "ESM not supported for revision 1 PMIC\n");
+	if (tps->chip_id == TPS6594 ||
+	    tps->chip_id == TPS6593 ||
+	    tps->chip_id == LP8764) {
+		ret = regmap_read(tps->regmap, TPS6594_REG_DEV_REV, &rev);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "Failed to read PMIC revision\n");
+		if (rev == TPS6594_DEV_REV_1)
+			return dev_err_probe(dev, -ENODEV,
+				      "ESM not supported for revision 1 PMIC\n");
+	}
 
 	for (i = 0; i < pdev->num_resources; i++) {
 		irq = platform_get_irq_byname(pdev, pdev->resource[i].name);
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:39 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:39 +0530
Subject: [RESEND PATCH v1 09/13] misc: tps6594-esm: use regmap_field
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-10-bhargav.r@ltts.com>

Use regmap_field and associated APIs to update the ESM_MODE_CFG and
ESM_START registers. This helps in adding support for TPS65224 PMIC.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/misc/tps6594-esm.c | 60 ++++++++++++++++++++++++++++----------
 1 file changed, 45 insertions(+), 15 deletions(-)

diff --git a/drivers/misc/tps6594-esm.c b/drivers/misc/tps6594-esm.c
index 8ec5af9dc..d0f86b0e9 100644
--- a/drivers/misc/tps6594-esm.c
+++ b/drivers/misc/tps6594-esm.c
@@ -15,6 +15,19 @@
 
 #define TPS6594_DEV_REV_1 0x08
 
+#define ESM_MODE_CFG_SET  0xff
+#define ESM_START_SET     0xff
+#define ESM_MODE_CFG_CLR  0x0
+#define ESM_START_CLR     0x0
+
+static struct reg_field tps6594_esm_mode_cfg  = REG_FIELD(TPS6594_REG_ESM_SOC_MODE_CFG,  5, 6);
+static struct reg_field tps6594_esm_start     = REG_FIELD(TPS6594_REG_ESM_SOC_START_REG, 0, 0);
+
+struct tps6594_esm {
+	struct regmap_field *esm_mode_cfg;
+	struct regmap_field *esm_start;
+};
+
 static irqreturn_t tps6594_esm_isr(int irq, void *dev_id)
 {
 	struct platform_device *pdev = dev_id;
@@ -34,6 +47,7 @@ static int tps6594_esm_probe(struct platform_device *pdev)
 {
 	struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
 	struct device *dev = &pdev->dev;
+	struct tps6594_esm *esm;
 	unsigned int rev;
 	int irq;
 	int ret;
@@ -69,13 +83,30 @@ static int tps6594_esm_probe(struct platform_device *pdev)
 			return dev_err_probe(dev, ret, "Failed to request irq\n");
 	}
 
-	ret = regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_MODE_CFG,
-			      TPS6594_BIT_ESM_SOC_EN | TPS6594_BIT_ESM_SOC_ENDRV);
+	esm = devm_kzalloc(dev, sizeof(struct tps6594_esm), GFP_KERNEL);
+	if (!esm)
+		return -ENOMEM;
+
+	esm->esm_mode_cfg = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_mode_cfg);
+	esm->esm_start = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_start);
+
+	if (IS_ERR(esm->esm_mode_cfg)) {
+		dev_err(dev, "esm_mode_cfg reg field init failed\n");
+		return PTR_ERR(esm->esm_mode_cfg);
+	}
+
+	if (IS_ERR(esm->esm_start)) {
+		dev_err(dev, "esm_start reg field init failed\n");
+		return PTR_ERR(esm->esm_start);
+	}
+
+	platform_set_drvdata(pdev, esm);
+
+	ret = regmap_field_write(esm->esm_mode_cfg, ESM_MODE_CFG_SET);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to configure ESM\n");
 
-	ret = regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG,
-			      TPS6594_BIT_ESM_SOC_START);
+	ret = regmap_field_write(esm->esm_start, ESM_START_SET);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to start ESM\n");
 
@@ -87,19 +118,17 @@ static int tps6594_esm_probe(struct platform_device *pdev)
 
 static void tps6594_esm_remove(struct platform_device *pdev)
 {
-	struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
 	struct device *dev = &pdev->dev;
+	struct tps6594_esm *esm = platform_get_drvdata(pdev);
 	int ret;
 
-	ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG,
-				TPS6594_BIT_ESM_SOC_START);
+	ret = regmap_field_write(esm->esm_start, ESM_START_CLR);
 	if (ret) {
 		dev_err(dev, "Failed to stop ESM\n");
 		goto out;
 	}
 
-	ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_MODE_CFG,
-				TPS6594_BIT_ESM_SOC_EN | TPS6594_BIT_ESM_SOC_ENDRV);
+	ret = regmap_field_write(esm->esm_mode_cfg, ESM_MODE_CFG_CLR);
 	if (ret)
 		dev_err(dev, "Failed to unconfigure ESM\n");
 
@@ -110,11 +139,12 @@ static void tps6594_esm_remove(struct platform_device *pdev)
 
 static int tps6594_esm_suspend(struct device *dev)
 {
-	struct tps6594 *tps = dev_get_drvdata(dev->parent);
+	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
+	struct tps6594_esm *esm = platform_get_drvdata(pdev);
+
 	int ret;
 
-	ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG,
-				TPS6594_BIT_ESM_SOC_START);
+	ret = regmap_field_write(esm->esm_start, ESM_START_CLR);
 
 	pm_runtime_put_sync(dev);
 
@@ -123,12 +153,12 @@ static int tps6594_esm_suspend(struct device *dev)
 
 static int tps6594_esm_resume(struct device *dev)
 {
-	struct tps6594 *tps = dev_get_drvdata(dev->parent);
+	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
+	struct tps6594_esm *esm = platform_get_drvdata(pdev);
 
 	pm_runtime_get_sync(dev);
 
-	return regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG,
-			       TPS6594_BIT_ESM_SOC_START);
+	return regmap_field_write(esm->esm_start, ESM_START_SET);
 }
 
 static DEFINE_SIMPLE_DEV_PM_OPS(tps6594_esm_pm_ops, tps6594_esm_suspend, tps6594_esm_resume);
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:40 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:40 +0530
Subject: [RESEND PATCH v1 10/13] misc: tps6594-esm: Add TI TPS65224 PMIC ESM
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-11-bhargav.r@ltts.com>

Add support for TPS65224 Error Signal Monitor in the TPS6594 ESM driver
as they share significant functionality.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/misc/tps6594-esm.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/tps6594-esm.c b/drivers/misc/tps6594-esm.c
index d0f86b0e9..445d82bd3 100644
--- a/drivers/misc/tps6594-esm.c
+++ b/drivers/misc/tps6594-esm.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * ESM (Error Signal Monitor) driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * ESM (Error Signal Monitor) driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
@@ -20,6 +20,8 @@
 #define ESM_MODE_CFG_CLR  0x0
 #define ESM_START_CLR     0x0
 
+static struct reg_field tps65224_esm_mode_cfg = REG_FIELD(TPS6594_REG_ESM_MCU_MODE_CFG,  5, 6);
+static struct reg_field tps65224_esm_start    = REG_FIELD(TPS6594_REG_ESM_MCU_START_REG, 0, 0);
 static struct reg_field tps6594_esm_mode_cfg  = REG_FIELD(TPS6594_REG_ESM_SOC_MODE_CFG,  5, 6);
 static struct reg_field tps6594_esm_start     = REG_FIELD(TPS6594_REG_ESM_SOC_START_REG, 0, 0);
 
@@ -87,8 +89,14 @@ static int tps6594_esm_probe(struct platform_device *pdev)
 	if (!esm)
 		return -ENOMEM;
 
-	esm->esm_mode_cfg = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_mode_cfg);
-	esm->esm_start = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_start);
+	if (tps->chip_id == TPS65224) {
+		esm->esm_mode_cfg = devm_regmap_field_alloc(dev, tps->regmap,
+							    tps65224_esm_mode_cfg);
+		esm->esm_start = devm_regmap_field_alloc(dev, tps->regmap, tps65224_esm_start);
+	} else {
+		esm->esm_mode_cfg = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_mode_cfg);
+		esm->esm_start = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_start);
+	}
 
 	if (IS_ERR(esm->esm_mode_cfg)) {
 		dev_err(dev, "esm_mode_cfg reg field init failed\n");
@@ -176,5 +184,6 @@ module_platform_driver(tps6594_esm_driver);
 
 MODULE_ALIAS("platform:tps6594-esm");
 MODULE_AUTHOR("Julien Panis <jpanis at baylibre.com>");
+MODULE_AUTHOR("Bhargav Raviprakash <bhargav.r at ltts.com>");
 MODULE_DESCRIPTION("TPS6594 Error Signal Monitor Driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:41 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:41 +0530
Subject: [RESEND PATCH v1 11/13] regulator: tps6594-regulator: Add TI TPS65224 PMIC regulators
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-12-bhargav.r@ltts.com>

From: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>

Add support for TPS65224 regulators (bucks and LDOs) to TPS6594 driver
as they have significant functional overlap.
TPS65224 PMIC has 4 buck regulators and 3 LDOs. BUCK12 can operate in
dual phase.
The output voltages are configurable and are meant to supply power to
the main processor and other components.

Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
---
 drivers/regulator/Kconfig             |   4 +-
 drivers/regulator/tps6594-regulator.c | 244 +++++++++++++++++++++++---
 2 files changed, 218 insertions(+), 30 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 7db0a29b5..1e4119f00 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1563,13 +1563,15 @@ config REGULATOR_TPS6594
 	depends on MFD_TPS6594 && OF
 	default MFD_TPS6594
 	help
-	  This driver supports TPS6594 voltage regulator chips.
+	  This driver supports TPS6594 series and TPS65224 voltage regulator chips.
 	  TPS6594 series of PMICs have 5 BUCKs and 4 LDOs
 	  voltage regulators.
 	  BUCKs 1,2,3,4 can be used in single phase or multiphase mode.
 	  Part number defines which single or multiphase mode is i used.
 	  It supports software based voltage control
 	  for different voltage domains.
+	  TPS65224 PMIC has 4 BUCKs and 3 LDOs. BUCK12 can be used in dual phase.
+	  All BUCKs and LDOs volatge can be controlled through software.
 
 config REGULATOR_TPS6524X
 	tristate "TI TPS6524X Power regulators"
diff --git a/drivers/regulator/tps6594-regulator.c b/drivers/regulator/tps6594-regulator.c
index b7f0c8779..3f32dba90 100644
--- a/drivers/regulator/tps6594-regulator.c
+++ b/drivers/regulator/tps6594-regulator.c
@@ -66,6 +66,15 @@ static struct tps6594_regulator_irq_type tps6594_ext_regulator_irq_types[] = {
 	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
 };
 
+static struct tps6594_regulator_irq_type tps65224_ext_regulator_irq_types[] = {
+	{ TPS65224_IRQ_NAME_VCCA_UVOV, "VCCA", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ TPS65224_IRQ_NAME_VMON1_UVOV, "VMON1", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ TPS65224_IRQ_NAME_VMON2_UVOV, "VMON2", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
 struct tps6594_regulator_irq_data {
 	struct device *dev;
 	struct tps6594_regulator_irq_type *type;
@@ -122,6 +131,27 @@ static const struct linear_range ldos_4_ranges[] = {
 	REGULATOR_LINEAR_RANGE(1200000, 0x20, 0x74, 25000),
 };
 
+/* Voltage range for TPS65224 Bucks and LDOs */
+static const struct linear_range tps65224_bucks_1_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0x0a, 0x0e, 20000),
+	REGULATOR_LINEAR_RANGE(600000, 0x0f, 0x72, 5000),
+	REGULATOR_LINEAR_RANGE(1100000, 0x73, 0xaa, 10000),
+	REGULATOR_LINEAR_RANGE(1660000, 0xab, 0xfd, 20000),
+};
+
+static const struct linear_range tps65224_bucks_2_3_4_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0x0, 0x1a, 25000),
+	REGULATOR_LINEAR_RANGE(1200000, 0x1b, 0x45, 50000),
+};
+
+static const struct linear_range tps65224_ldos_1_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1200000, 0xC, 0x36, 50000),
+};
+
+static const struct linear_range tps65224_ldos_2_3_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x38, 50000),
+};
+
 /* Operations permitted on BUCK1/2/3/4/5 */
 static const struct regulator_ops tps6594_bucks_ops = {
 	.is_enabled		= regulator_is_enabled_regmap,
@@ -197,6 +227,38 @@ static const struct regulator_desc buck_regs[] = {
 			  4, 0, 0, NULL, 0, 0),
 };
 
+/* Buck configuration for TPS65224 */
+static const struct regulator_desc tps65224_buck_regs[] = {
+	TPS6594_REGULATOR("BUCK1", "buck1", TPS6594_BUCK_1,
+			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCK1_VSET,
+			  TPS6594_REG_BUCKX_VOUT_1(0),
+			  TPS65224_MASK_BUCK1_VSET,
+			  TPS6594_REG_BUCKX_CTRL(0),
+			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_1_ranges,
+			  4, 0, 0, NULL, 0, 0),
+	TPS6594_REGULATOR("BUCK2", "buck2", TPS6594_BUCK_2,
+			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_VOUT_1(1),
+			  TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_CTRL(1),
+			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
+			  4, 0, 0, NULL, 0, 0),
+	TPS6594_REGULATOR("BUCK3", "buck3", TPS6594_BUCK_3,
+			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_VOUT_1(2),
+			  TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_CTRL(2),
+			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
+			  4, 0, 0, NULL, 0, 0),
+	TPS6594_REGULATOR("BUCK4", "buck4", TPS6594_BUCK_4,
+			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_VOUT_1(3),
+			  TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_CTRL(3),
+			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
+			  4, 0, 0, NULL, 0, 0),
+};
+
 static struct tps6594_regulator_irq_type tps6594_buck1_irq_types[] = {
 	{ TPS6594_IRQ_NAME_BUCK1_OV, "BUCK1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
 	{ TPS6594_IRQ_NAME_BUCK1_UV, "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
@@ -269,6 +331,41 @@ static struct tps6594_regulator_irq_type tps6594_ldo4_irq_types[] = {
 	  REGULATOR_EVENT_OVER_CURRENT },
 };
 
+static struct tps6594_regulator_irq_type tps65224_buck1_irq_types[] = {
+	{ TPS65224_IRQ_NAME_BUCK1_UVOV, "BUCK1", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_buck2_irq_types[] = {
+	{ TPS65224_IRQ_NAME_BUCK2_UVOV, "BUCK2", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_buck3_irq_types[] = {
+	{ TPS65224_IRQ_NAME_BUCK3_UVOV, "BUCK3", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_buck4_irq_types[] = {
+	{ TPS65224_IRQ_NAME_BUCK4_UVOV, "BUCK4", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_ldo1_irq_types[] = {
+	{ TPS65224_IRQ_NAME_LDO1_UVOV, "LDO1", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_ldo2_irq_types[] = {
+	{ TPS65224_IRQ_NAME_LDO2_UVOV, "LDO2", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_ldo3_irq_types[] = {
+	{ TPS65224_IRQ_NAME_LDO3_UVOV, "LDO3", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
 static struct tps6594_regulator_irq_type *tps6594_bucks_irq_types[] = {
 	tps6594_buck1_irq_types,
 	tps6594_buck2_irq_types,
@@ -284,7 +381,20 @@ static struct tps6594_regulator_irq_type *tps6594_ldos_irq_types[] = {
 	tps6594_ldo4_irq_types,
 };
 
-static const struct regulator_desc multi_regs[] = {
+static struct tps6594_regulator_irq_type *tps65224_bucks_irq_types[] = {
+	tps65224_buck1_irq_types,
+	tps65224_buck2_irq_types,
+	tps65224_buck3_irq_types,
+	tps65224_buck4_irq_types,
+};
+
+static struct tps6594_regulator_irq_type *tps65224_ldos_irq_types[] = {
+	tps65224_ldo1_irq_types,
+	tps65224_ldo2_irq_types,
+	tps65224_ldo3_irq_types,
+};
+
+static const struct regulator_desc tps6594_multi_regs[] = {
 	TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,
 			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
 			  TPS6594_REG_BUCKX_VOUT_1(1),
@@ -315,7 +425,17 @@ static const struct regulator_desc multi_regs[] = {
 			  4, 4000, 0, NULL, 0, 0),
 };
 
-static const struct regulator_desc ldo_regs[] = {
+static const struct regulator_desc tps65224_multi_regs[] = {
+	TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,
+			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCK1_VSET,
+			  TPS6594_REG_BUCKX_VOUT_1(0),
+			  TPS65224_MASK_BUCK1_VSET,
+			  TPS6594_REG_BUCKX_CTRL(0),
+			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_1_ranges,
+			  4, 4000, 0, NULL, 0, 0),
+};
+
+static const struct regulator_desc tps6594_ldo_regs[] = {
 	TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,
 			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
 			  TPS6594_REG_LDOX_VOUT(0),
@@ -346,6 +466,30 @@ static const struct regulator_desc ldo_regs[] = {
 			  1, 0, 0, NULL, 0, 0),
 };
 
+static const struct regulator_desc tps65224_ldo_regs[] = {
+	TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,
+			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_VOUT(0),
+			  TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_CTRL(0),
+			  TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_1_ranges,
+			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+	TPS6594_REGULATOR("LDO2", "ldo2", TPS6594_LDO_2,
+			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_VOUT(1),
+			  TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_CTRL(1),
+			  TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_2_3_ranges,
+			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+	TPS6594_REGULATOR("LDO3", "ldo3", TPS6594_LDO_3,
+			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_VOUT(2),
+			  TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_CTRL(2),
+			  TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_2_3_ranges,
+			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+};
+
 static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data)
 {
 	struct tps6594_regulator_irq_data *irq_data = data;
@@ -374,11 +518,17 @@ static int tps6594_request_reg_irqs(struct platform_device *pdev,
 {
 	struct tps6594_regulator_irq_type *irq_type;
 	struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
-	int j;
+	size_t j;
 	int irq;
 	int error;
+	size_t interrupt_cnt;
 
-	for (j = 0; j < REGS_INT_NB; j++) {
+	/* Number of interrupts supported by each voltage source */
+	interrupt_cnt = (tps->chip_id == TPS6594) ?
+			 ARRAY_SIZE(tps6594_buck1_irq_types) :
+			 ARRAY_SIZE(tps65224_buck1_irq_types);
+
+	for (j = 0; j < interrupt_cnt; j++) {
 		irq_type = &tps6594_regs_irq_types[j];
 		irq = platform_get_irq_byname(pdev, irq_type->irq_name);
 		if (irq < 0)
@@ -412,14 +562,20 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 	struct tps6594_ext_regulator_irq_data *irq_ext_reg_data;
 	struct tps6594_regulator_irq_type *irq_type;
 	u8 buck_configured[BUCK_NB] = { 0 };
+	u8 ldo_configured[LDO_NB] = { 0 };
 	u8 buck_multi[MULTI_PHASE_NB] = { 0 };
 	static const char * const multiphases[] = {"buck12", "buck123", "buck1234", "buck34"};
+	static const char * const tps65224_multiphases[] = {"buck12"};
 	static const char *npname;
 	int error, i, irq, multi, delta;
 	int irq_idx = 0;
 	int buck_idx = 0;
+	unsigned int multi_phase_cnt = 0;
 	size_t ext_reg_irq_nb = 2;
 	size_t reg_irq_nb;
+	struct tps6594_regulator_irq_type **bucks_irq_types = (tps->chip_id == TPS65224) ?
+							       tps65224_bucks_irq_types :
+							       tps6594_bucks_irq_types;
 	enum {
 		MULTI_BUCK12,
 		MULTI_BUCK123,
@@ -434,6 +590,10 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 	config.driver_data = tps;
 	config.regmap = tps->regmap;
 
+	multi_phase_cnt = (tps->chip_id == TPS65224) ?
+			   ARRAY_SIZE(tps65224_multiphases) :
+			   ARRAY_SIZE(multiphases);
+
 	/*
 	 * Switch case defines different possible multi phase config
 	 * This is based on dts buck node name.
@@ -442,7 +602,7 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 	 * In case of Multiphase configuration, value should be defined for
 	 * buck_configured to avoid creating bucks for every buck in multiphase
 	 */
-	for (multi = MULTI_FIRST; multi < MULTI_NUM; multi++) {
+	for (multi = MULTI_FIRST; multi < multi_phase_cnt; multi++) {
 		np = of_find_node_by_name(tps->dev->of_node, multiphases[multi]);
 		npname = of_node_full_name(np);
 		np_pmic_parent = of_get_parent(of_get_parent(np));
@@ -486,6 +646,11 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 		/* There is only 4 buck on LP8764 */
 		buck_configured[4] = 1;
 		reg_irq_nb = size_mul(REGS_INT_NB, (BUCK_NB - 1));
+	} else if (tps->chip_id == TPS65224) {
+		/* TPS65224 has 4 bucks and 3 LDOs. 1 Interrupt for each buck and ldo */
+		buck_configured[4] = 1;
+		ldo_configured[3] = 1;
+		reg_irq_nb = size_mul(1, (size_add((BUCK_NB - 1), (LDO_NB - 1))));
 	} else {
 		reg_irq_nb = size_mul(REGS_INT_NB, (size_add(BUCK_NB, LDO_NB)));
 	}
@@ -495,25 +660,30 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 	if (!irq_data)
 		return -ENOMEM;
 
-	for (i = 0; i < MULTI_PHASE_NB; i++) {
+	for (i = 0; i < multi_phase_cnt; i++) {
 		if (buck_multi[i] == 0)
 			continue;
 
+		const struct regulator_desc *multi_regs = (tps->chip_id == TPS65224) ?
+							   tps65224_multi_regs :
+							   tps6594_multi_regs;
 		rdev = devm_regulator_register(&pdev->dev, &multi_regs[i], &config);
-		if (IS_ERR(rdev))
-			return dev_err_probe(tps->dev, PTR_ERR(rdev),
-					     "failed to register %s regulator\n",
-					     pdev->name);
+			if (IS_ERR(rdev))
+				return dev_err_probe(tps->dev, PTR_ERR(rdev),
+						     "failed to register %s regulator\n",
+						     pdev->name);
 
 		/* config multiphase buck12+buck34 */
 		if (i == 1)
 			buck_idx = 2;
+
 		error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
-						 tps6594_bucks_irq_types[buck_idx], &irq_idx);
+						 bucks_irq_types[buck_idx], &irq_idx);
 		if (error)
 			return error;
+
 		error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
-						 tps6594_bucks_irq_types[buck_idx + 1], &irq_idx);
+						 bucks_irq_types[buck_idx + 1], &irq_idx);
 		if (error)
 			return error;
 
@@ -537,37 +707,49 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 		if (buck_configured[i] == 1)
 			continue;
 
-		rdev = devm_regulator_register(&pdev->dev, &buck_regs[i], &config);
+		const struct regulator_desc *buck_cfg = (tps->chip_id == TPS65224) ?
+							 tps65224_buck_regs : buck_regs;
+
+		rdev = devm_regulator_register(&pdev->dev, &buck_cfg[i], &config);
 		if (IS_ERR(rdev))
 			return dev_err_probe(tps->dev, PTR_ERR(rdev),
-					     "failed to register %s regulator\n",
-					     pdev->name);
+					     "failed to register %s regulator\n", pdev->name);
 
 		error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
-						 tps6594_bucks_irq_types[i], &irq_idx);
+						 bucks_irq_types[i], &irq_idx);
 		if (error)
 			return error;
 	}
 
-	/* LP8764 dosen't have LDO */
+	/* LP8764 doesn't have LDO */
 	if (tps->chip_id != LP8764) {
-		for (i = 0; i < ARRAY_SIZE(ldo_regs); i++) {
-			rdev = devm_regulator_register(&pdev->dev, &ldo_regs[i], &config);
-			if (IS_ERR(rdev))
-				return dev_err_probe(tps->dev, PTR_ERR(rdev),
-						     "failed to register %s regulator\n",
-						     pdev->name);
+		for (i = 0; i < LDO_NB; i++) {
+			if (ldo_configured[i] == 1)
+				continue;
 
-			error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
-							 tps6594_ldos_irq_types[i],
-							 &irq_idx);
-			if (error)
-				return error;
+		struct tps6594_regulator_irq_type **ldos_irq_types = (tps->chip_id == TPS65224) ?
+								       tps65224_ldos_irq_types :
+								       tps6594_ldos_irq_types;
+
+		const struct regulator_desc *ldo_regs = (tps->chip_id == TPS65224) ?
+							 tps65224_ldo_regs :
+							 tps6594_ldo_regs;
+
+		rdev = devm_regulator_register(&pdev->dev, &ldo_regs[i], &config);
+		if (IS_ERR(rdev))
+			return dev_err_probe(tps->dev, PTR_ERR(rdev),
+					     "failed to register %s regulator\n", pdev->name);
+
+		error = tps6594_request_reg_irqs(pdev, rdev, irq_data, ldos_irq_types[i], &irq_idx);
+		if (error)
+			return error;
 		}
 	}
 
 	if (tps->chip_id == LP8764)
 		ext_reg_irq_nb = ARRAY_SIZE(tps6594_ext_regulator_irq_types);
+	else if (tps->chip_id == TPS65224)
+		ext_reg_irq_nb = ARRAY_SIZE(tps65224_ext_regulator_irq_types);
 
 	irq_ext_reg_data = devm_kmalloc_array(tps->dev,
 					ext_reg_irq_nb,
@@ -577,7 +759,10 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	for (i = 0; i < ext_reg_irq_nb; ++i) {
-		irq_type = &tps6594_ext_regulator_irq_types[i];
+		if (tps->chip_id == TPS65224)
+			irq_type = &tps65224_ext_regulator_irq_types[i];
+		else
+			irq_type = &tps6594_ext_regulator_irq_types[i];
 
 		irq = platform_get_irq_byname(pdev, irq_type->irq_name);
 		if (irq < 0)
@@ -610,5 +795,6 @@ module_platform_driver(tps6594_regulator_driver);
 
 MODULE_ALIAS("platform:tps6594-regulator");
 MODULE_AUTHOR("Jerome Neanne <jneanne at baylibre.com>");
+MODULE_AUTHOR("Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>");
 MODULE_DESCRIPTION("TPS6594 voltage regulator driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:43 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:43 +0530
Subject: [RESEND PATCH v1 13/13] arch: arm64: dts: ti: k3-am62p5-sk: Add TPS65224 PMIC support in AM62P dts
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-14-bhargav.r@ltts.com>

Add support for TPS65224 PMIC in device tree of AM62P EVM. Adds
regulator configuration, pinmux configurations and pmic device nodes.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 95 +++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 1773c05f7..5d8e4321b 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -112,6 +112,16 @@ vddshv_sdio: regulator-3 {
 		bootph-all;
 	};
 
+	vcc_3v3_main: regulator-4 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_main";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vmain_pd>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -580,6 +590,12 @@ &main_uart1 {
 &mcu_pmx0 {
 	bootph-all;
 
+	pmic_irq_pins_default: pmic-irq-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_MCU_IOPAD(0x000, PIN_INPUT, 7) /* (B10) MCU_GPIO0_0 */
+		>;
+	};
+
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
 			AM62PX_MCU_IOPAD(0x02c, PIN_INPUT, 0)	/* (C7) WKUP_UART0_CTSn */
@@ -589,6 +605,13 @@ AM62PX_MCU_IOPAD(0x028, PIN_OUTPUT, 0)	/* (D7) WKUP_UART0_TXD */
 		>;
 		bootph-all;
 	};
+
+	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_MCU_IOPAD(0x04c, PIN_INPUT, 0) /* (A13) WKUP_I2C0_SCL */
+			AM62PX_MCU_IOPAD(0x050, PIN_INPUT, 0) /* (C11) WKUP_I2C0_SDA */
+		>;
+	};
 };
 
 &wkup_uart0 {
@@ -599,6 +622,78 @@ &wkup_uart0 {
 	bootph-all;
 };
 
+&wkup_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_i2c0_pins_default>;
+	clock-frequency = <400000>;
+
+	tps65224: pmic at 48 {
+		compatible = "ti,tps65224-q1";
+		reg = <0x48>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_irq_pins_default>;
+		interrupt-parent = <&mcu_gpio0>;
+		interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+		ti,primary-pmic;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		buck12-supply = <&vcc_3v3_main>;
+		buck3-supply = <&vcc_3v3_main>;
+		buck4-supply = <&vcc_3v3_main>;
+
+		ldo1-supply = <&vcc_3v3_main>;
+		ldo2-supply = <&vcc_3v3_main>;
+		ldo3-supply = <&vcc1v8_sys>;
+
+		regulators {
+			vcc_core: buck12 {
+				regulator-name = "vcc_core_buck12";
+				regulator-min-microvolt = <715000>;
+				regulator-max-microvolt = <895000>;
+				regulator-always-on;
+			};
+
+			vcc1v8_sys: buck3 {
+				regulator-name = "vcc1v8_sys_buck3";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			vcc1v1: buck4 {
+				regulator-name = "vcc1v1_buck4";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			vdda1v8: ldo1 {
+				regulator-name = "vdda1v8_ldo1";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			dvdd3v3: ldo2 {
+				regulator-name = "dvdd3v3_ldo2";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vcc_0v85: ldo3 {
+				regulator-name = "vcc_0v85_ldo3";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
 /* mcu_gpio0 and mcu_gpio_intr are reserved for mcu firmware usage */
 &mcu_gpio0 {
 	status = "reserved";
-- 
2.25.1



From bhargav.r at ltts.com  Thu Feb  8 02:53:42 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu,  8 Feb 2024 16:23:42 +0530
Subject: [RESEND PATCH v1 12/13] pinctrl: pinctrl-tps6594: Add TPS65224 PMIC pinctrl and GPIO
In-Reply-To: <20240208105343.1212902-1-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
Message-ID: <20240208105343.1212902-13-bhargav.r@ltts.com>

From: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>

Add support for TPS65224 pinctrl and GPIOs to TPS6594 driver as they
have significant functional overlap.
TPS65224 PMIC has 6 GPIOS which can be configured as GPIO or other
dedicated device functions.

Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
---
 drivers/pinctrl/pinctrl-tps6594.c | 287 +++++++++++++++++++++++++-----
 1 file changed, 246 insertions(+), 41 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-tps6594.c b/drivers/pinctrl/pinctrl-tps6594.c
index 66985e54b..5da21aa14 100644
--- a/drivers/pinctrl/pinctrl-tps6594.c
+++ b/drivers/pinctrl/pinctrl-tps6594.c
@@ -14,8 +14,6 @@
 
 #include <linux/mfd/tps6594.h>
 
-#define TPS6594_PINCTRL_PINS_NB 11
-
 #define TPS6594_PINCTRL_GPIO_FUNCTION 0
 #define TPS6594_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION 1
 #define TPS6594_PINCTRL_TRIG_WDOG_FUNCTION 1
@@ -40,17 +38,40 @@
 #define TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION_GPIO8 3
 #define TPS6594_PINCTRL_CLK32KOUT_FUNCTION_GPIO9 3
 
+/* TPS65224 pin muxval */
+#define TPS65224_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION 1
+#define TPS65224_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION 1
+#define TPS65224_PINCTRL_VMON1_FUNCTION 1
+#define TPS65224_PINCTRL_VMON2_FUNCTION 1
+#define TPS65224_PINCTRL_WKUP_FUNCTION 1
+#define TPS65224_PINCTRL_NSLEEP2_FUNCTION 2
+#define TPS65224_PINCTRL_NSLEEP1_FUNCTION 2
+#define TPS65224_PINCTRL_SYNCCLKIN_FUNCTION 2
+#define TPS65224_PINCTRL_NERR_MCU_FUNCTION 2
+#define TPS65224_PINCTRL_NINT_FUNCTION 3
+#define TPS65224_PINCTRL_TRIG_WDOG_FUNCTION 3
+#define TPS65224_PINCTRL_PB_FUNCTION 3
+#define TPS65224_PINCTRL_ADC_IN_FUNCTION 3
+
+/* TPS65224 Special muxval for recalcitrant pins */
+#define TPS65224_PINCTRL_NSLEEP2_FUNCTION_GPIO5 1
+#define TPS65224_PINCTRL_WKUP_FUNCTION_GPIO5 4
+#define TPS65224_PINCTRL_SYNCCLKIN_FUNCTION_GPIO5 3
+
 #define TPS6594_OFFSET_GPIO_SEL 5
 
-#define FUNCTION(fname, v)									\
+#define TPS65224_NGPIO_PER_REG 6
+#define TPS6594_NGPIO_PER_REG  8
+
+#define FUNCTION(dev_name, fname, v)							\
 {											\
 	.pinfunction = PINCTRL_PINFUNCTION(#fname,					\
-					tps6594_##fname##_func_group_names,		\
-					ARRAY_SIZE(tps6594_##fname##_func_group_names)),\
+					dev_name##_##fname##_func_group_names,		\
+					ARRAY_SIZE(dev_name##_##fname##_func_group_names)),\
 	.muxval = v,									\
 }
 
-static const struct pinctrl_pin_desc tps6594_pins[TPS6594_PINCTRL_PINS_NB] = {
+static const struct pinctrl_pin_desc tps6594_pins[] = {
 	PINCTRL_PIN(0, "GPIO0"),   PINCTRL_PIN(1, "GPIO1"),
 	PINCTRL_PIN(2, "GPIO2"),   PINCTRL_PIN(3, "GPIO3"),
 	PINCTRL_PIN(4, "GPIO4"),   PINCTRL_PIN(5, "GPIO5"),
@@ -143,30 +164,127 @@ static const char *const tps6594_syncclkin_func_group_names[] = {
 	"GPIO9",
 };
 
+static const struct pinctrl_pin_desc tps65224_pins[] = {
+	PINCTRL_PIN(0, "GPIO0"),   PINCTRL_PIN(1, "GPIO1"),
+	PINCTRL_PIN(2, "GPIO2"),   PINCTRL_PIN(3, "GPIO3"),
+	PINCTRL_PIN(4, "GPIO4"),   PINCTRL_PIN(5, "GPIO5"),
+};
+
+static const char *const tps65224_gpio_func_group_names[] = {
+	"GPIO0", "GPIO1", "GPIO2", "GPIO3", "GPIO4", "GPIO5",
+};
+
+static const char *const tps65224_sda_i2c2_sdo_spi_func_group_names[] = {
+	"GPIO0",
+};
+
+static const char *const tps65224_nsleep2_func_group_names[] = {
+	"GPIO0", "GPIO5",
+};
+
+static const char *const tps65224_nint_func_group_names[] = {
+	"GPIO0",
+};
+
+static const char *const tps65224_scl_i2c2_cs_spi_func_group_names[] = {
+	"GPIO1",
+};
+
+static const char *const tps65224_nsleep1_func_group_names[] = {
+	"GPIO1", "GPIO2", "GPIO3",
+};
+
+static const char *const tps65224_trig_wdog_func_group_names[] = {
+	"GPIO1",
+};
+
+static const char *const tps65224_vmon1_func_group_names[] = {
+	"GPIO2",
+};
+
+static const char *const tps65224_pb_func_group_names[] = {
+	"GPIO2",
+};
+
+static const char *const tps65224_vmon2_func_group_names[] = {
+	"GPIO3",
+};
+
+static const char *const tps65224_adc_in_func_group_names[] = {
+	"GPIO3", "GPIO4",
+};
+
+static const char *const tps65224_wkup_func_group_names[] = {
+	"GPIO4", "GPIO5",
+};
+
+static const char *const tps65224_syncclkin_func_group_names[] = {
+	"GPIO4", "GPIO5",
+};
+
+static const char *const tps65224_nerr_mcu_func_group_names[] = {
+	"GPIO5",
+};
+
 struct tps6594_pinctrl_function {
 	struct pinfunction pinfunction;
 	u8 muxval;
 };
 
+struct muxval_remap {
+	unsigned int group;
+	u8 muxval;
+	u8 remap;
+};
+
+struct muxval_remap tps65224_muxval_remap[] = {
+	{5, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION, TPS65224_PINCTRL_WKUP_FUNCTION_GPIO5},
+	{5, TPS65224_PINCTRL_SYNCCLKIN_FUNCTION, TPS65224_PINCTRL_SYNCCLKIN_FUNCTION_GPIO5},
+	{5, TPS65224_PINCTRL_NSLEEP2_FUNCTION, TPS65224_PINCTRL_NSLEEP2_FUNCTION_GPIO5},
+};
+
+struct muxval_remap tps6594_muxval_remap[] = {
+	{8, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION_GPIO8},
+	{8, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION_GPIO8},
+	{9, TPS6594_PINCTRL_CLK32KOUT_FUNCTION, TPS6594_PINCTRL_CLK32KOUT_FUNCTION_GPIO9},
+};
+
 static const struct tps6594_pinctrl_function pinctrl_functions[] = {
-	FUNCTION(gpio, TPS6594_PINCTRL_GPIO_FUNCTION),
-	FUNCTION(nsleep1, TPS6594_PINCTRL_NSLEEP1_FUNCTION),
-	FUNCTION(nsleep2, TPS6594_PINCTRL_NSLEEP2_FUNCTION),
-	FUNCTION(wkup1, TPS6594_PINCTRL_WKUP1_FUNCTION),
-	FUNCTION(wkup2, TPS6594_PINCTRL_WKUP2_FUNCTION),
-	FUNCTION(scl_i2c2_cs_spi, TPS6594_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION),
-	FUNCTION(nrstout_soc, TPS6594_PINCTRL_NRSTOUT_SOC_FUNCTION),
-	FUNCTION(trig_wdog, TPS6594_PINCTRL_TRIG_WDOG_FUNCTION),
-	FUNCTION(sda_i2c2_sdo_spi, TPS6594_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION),
-	FUNCTION(clk32kout, TPS6594_PINCTRL_CLK32KOUT_FUNCTION),
-	FUNCTION(nerr_soc, TPS6594_PINCTRL_NERR_SOC_FUNCTION),
-	FUNCTION(sclk_spmi, TPS6594_PINCTRL_SCLK_SPMI_FUNCTION),
-	FUNCTION(sdata_spmi, TPS6594_PINCTRL_SDATA_SPMI_FUNCTION),
-	FUNCTION(nerr_mcu, TPS6594_PINCTRL_NERR_MCU_FUNCTION),
-	FUNCTION(syncclkout, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION),
-	FUNCTION(disable_wdog, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION),
-	FUNCTION(pdog, TPS6594_PINCTRL_PDOG_FUNCTION),
-	FUNCTION(syncclkin, TPS6594_PINCTRL_SYNCCLKIN_FUNCTION),
+	FUNCTION(tps6594, gpio, TPS6594_PINCTRL_GPIO_FUNCTION),
+	FUNCTION(tps6594, nsleep1, TPS6594_PINCTRL_NSLEEP1_FUNCTION),
+	FUNCTION(tps6594, nsleep2, TPS6594_PINCTRL_NSLEEP2_FUNCTION),
+	FUNCTION(tps6594, wkup1, TPS6594_PINCTRL_WKUP1_FUNCTION),
+	FUNCTION(tps6594, wkup2, TPS6594_PINCTRL_WKUP2_FUNCTION),
+	FUNCTION(tps6594, scl_i2c2_cs_spi, TPS6594_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION),
+	FUNCTION(tps6594, nrstout_soc, TPS6594_PINCTRL_NRSTOUT_SOC_FUNCTION),
+	FUNCTION(tps6594, trig_wdog, TPS6594_PINCTRL_TRIG_WDOG_FUNCTION),
+	FUNCTION(tps6594, sda_i2c2_sdo_spi, TPS6594_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION),
+	FUNCTION(tps6594, clk32kout, TPS6594_PINCTRL_CLK32KOUT_FUNCTION),
+	FUNCTION(tps6594, nerr_soc, TPS6594_PINCTRL_NERR_SOC_FUNCTION),
+	FUNCTION(tps6594, sclk_spmi, TPS6594_PINCTRL_SCLK_SPMI_FUNCTION),
+	FUNCTION(tps6594, sdata_spmi, TPS6594_PINCTRL_SDATA_SPMI_FUNCTION),
+	FUNCTION(tps6594, nerr_mcu, TPS6594_PINCTRL_NERR_MCU_FUNCTION),
+	FUNCTION(tps6594, syncclkout, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION),
+	FUNCTION(tps6594, disable_wdog, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION),
+	FUNCTION(tps6594, pdog, TPS6594_PINCTRL_PDOG_FUNCTION),
+	FUNCTION(tps6594, syncclkin, TPS6594_PINCTRL_SYNCCLKIN_FUNCTION),
+};
+
+static const struct tps6594_pinctrl_function tps65224_pinctrl_functions[] = {
+	FUNCTION(tps65224, gpio, TPS6594_PINCTRL_GPIO_FUNCTION),
+	FUNCTION(tps65224, sda_i2c2_sdo_spi, TPS65224_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION),
+	FUNCTION(tps65224, nsleep2, TPS65224_PINCTRL_NSLEEP2_FUNCTION),
+	FUNCTION(tps65224, nint, TPS65224_PINCTRL_NINT_FUNCTION),
+	FUNCTION(tps65224, scl_i2c2_cs_spi, TPS65224_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION),
+	FUNCTION(tps65224, nsleep1, TPS65224_PINCTRL_NSLEEP1_FUNCTION),
+	FUNCTION(tps65224, trig_wdog, TPS65224_PINCTRL_TRIG_WDOG_FUNCTION),
+	FUNCTION(tps65224, vmon1, TPS65224_PINCTRL_VMON1_FUNCTION),
+	FUNCTION(tps65224, pb, TPS65224_PINCTRL_PB_FUNCTION),
+	FUNCTION(tps65224, vmon2, TPS65224_PINCTRL_VMON2_FUNCTION),
+	FUNCTION(tps65224, adc_in, TPS65224_PINCTRL_ADC_IN_FUNCTION),
+	FUNCTION(tps65224, wkup, TPS65224_PINCTRL_WKUP_FUNCTION),
+	FUNCTION(tps65224, syncclkin, TPS65224_PINCTRL_SYNCCLKIN_FUNCTION),
+	FUNCTION(tps65224, nerr_mcu, TPS65224_PINCTRL_NERR_MCU_FUNCTION),
 };
 
 struct tps6594_pinctrl {
@@ -201,7 +319,21 @@ static int tps6594_gpio_regmap_xlate(struct gpio_regmap *gpio,
 
 static int tps6594_pmx_func_cnt(struct pinctrl_dev *pctldev)
 {
-	return ARRAY_SIZE(pinctrl_functions);
+	struct tps6594_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+	int func_cnt = 0;
+
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		func_cnt = ARRAY_SIZE(tps65224_pinctrl_functions);
+		break;
+	case TPS6594:
+		func_cnt = ARRAY_SIZE(pinctrl_functions);
+		break;
+	default:
+		break;
+	}
+
+	return func_cnt;
 }
 
 static const char *tps6594_pmx_func_name(struct pinctrl_dev *pctldev,
@@ -229,10 +361,26 @@ static int tps6594_pmx_set(struct tps6594_pinctrl *pinctrl, unsigned int pin,
 			   u8 muxval)
 {
 	u8 mux_sel_val = muxval << TPS6594_OFFSET_GPIO_SEL;
+	u8 mux_sel_mask = 0;
+
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		mux_sel_mask = TPS65224_MASK_GPIO_SEL;
+		/* GPIO6 has a different mask in TPS65224*/
+		if (pin == 5)
+			mux_sel_mask = TPS65224_MASK_GPIO_SEL_GPIO6;
+		mux_sel_mask = TPS6594_MASK_GPIO_SEL;
+		break;
+	case TPS6594:
+		mux_sel_mask = TPS6594_MASK_GPIO_SEL;
+		break;
+	default:
+		break;
+	}
 
 	return regmap_update_bits(pinctrl->tps->regmap,
 				  TPS6594_REG_GPIOX_CONF(pin),
-				  TPS6594_MASK_GPIO_SEL, mux_sel_val);
+				  mux_sel_mask, mux_sel_val);
 }
 
 static int tps6594_pmx_set_mux(struct pinctrl_dev *pctldev,
@@ -240,16 +388,28 @@ static int tps6594_pmx_set_mux(struct pinctrl_dev *pctldev,
 {
 	struct tps6594_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
 	u8 muxval = pinctrl->funcs[function].muxval;
+	unsigned int remap_cnt = 0;
+	struct muxval_remap *remap;
 
 	/* Some pins don't have the same muxval for the same function... */
-	if (group == 8) {
-		if (muxval == TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION)
-			muxval = TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION_GPIO8;
-		else if (muxval == TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION)
-			muxval = TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION_GPIO8;
-	} else if (group == 9) {
-		if (muxval == TPS6594_PINCTRL_CLK32KOUT_FUNCTION)
-			muxval = TPS6594_PINCTRL_CLK32KOUT_FUNCTION_GPIO9;
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		remap = tps65224_muxval_remap;
+		remap_cnt = ARRAY_SIZE(tps65224_muxval_remap);
+		break;
+	case TPS6594:
+		remap = tps6594_muxval_remap;
+		remap_cnt = ARRAY_SIZE(tps6594_muxval_remap);
+		break;
+	default:
+		break;
+	}
+
+	for (unsigned int i = 0; i < remap_cnt; i++) {
+		if (group == remap[i].group && muxval == remap[i].muxval) {
+			muxval = remap[i].remap;
+			break;
+		}
 	}
 
 	return tps6594_pmx_set(pinctrl, group, muxval);
@@ -276,7 +436,21 @@ static const struct pinmux_ops tps6594_pmx_ops = {
 
 static int tps6594_groups_cnt(struct pinctrl_dev *pctldev)
 {
-	return ARRAY_SIZE(tps6594_pins);
+	struct tps6594_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+	int num_pins = 0;
+
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		num_pins = ARRAY_SIZE(tps65224_pins);
+		break;
+	case TPS6594:
+		num_pins = ARRAY_SIZE(tps6594_pins);
+		break;
+	default:
+		break;
+	}
+
+	return num_pins;
 }
 
 static int tps6594_group_pins(struct pinctrl_dev *pctldev,
@@ -320,8 +494,18 @@ static int tps6594_pinctrl_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	pctrl_desc->name = dev_name(dev);
 	pctrl_desc->owner = THIS_MODULE;
-	pctrl_desc->pins = tps6594_pins;
-	pctrl_desc->npins = ARRAY_SIZE(tps6594_pins);
+	switch (tps->chip_id) {
+	case TPS65224:
+		pctrl_desc->pins = tps65224_pins;
+		pctrl_desc->npins = ARRAY_SIZE(tps65224_pins);
+		break;
+	case TPS6594:
+		pctrl_desc->pins = tps6594_pins;
+		pctrl_desc->npins = ARRAY_SIZE(tps6594_pins);
+		break;
+	default:
+		break;
+	}
 	pctrl_desc->pctlops = &tps6594_pctrl_ops;
 	pctrl_desc->pmxops = &tps6594_pmx_ops;
 
@@ -329,8 +513,18 @@ static int tps6594_pinctrl_probe(struct platform_device *pdev)
 	if (!pinctrl)
 		return -ENOMEM;
 	pinctrl->tps = dev_get_drvdata(dev->parent);
-	pinctrl->funcs = pinctrl_functions;
-	pinctrl->pins = tps6594_pins;
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		pinctrl->funcs = tps65224_pinctrl_functions;
+		pinctrl->pins = tps65224_pins;
+		break;
+	case TPS6594:
+		pinctrl->funcs = pinctrl_functions;
+		pinctrl->pins = tps6594_pins;
+		break;
+	default:
+		break;
+	}
 	pinctrl->pctl_dev = devm_pinctrl_register(dev, pctrl_desc, pinctrl);
 	if (IS_ERR(pinctrl->pctl_dev))
 		return dev_err_probe(dev, PTR_ERR(pinctrl->pctl_dev),
@@ -338,8 +532,18 @@ static int tps6594_pinctrl_probe(struct platform_device *pdev)
 
 	config.parent = tps->dev;
 	config.regmap = tps->regmap;
-	config.ngpio = TPS6594_PINCTRL_PINS_NB;
-	config.ngpio_per_reg = 8;
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		config.ngpio = ARRAY_SIZE(tps65224_gpio_func_group_names);
+		config.ngpio_per_reg = TPS65224_NGPIO_PER_REG;
+		break;
+	case TPS6594:
+		config.ngpio = ARRAY_SIZE(tps6594_gpio_func_group_names);
+		config.ngpio_per_reg = TPS6594_NGPIO_PER_REG;
+		break;
+	default:
+		break;
+	}
 	config.reg_dat_base = TPS6594_REG_GPIO_IN_1;
 	config.reg_set_base = TPS6594_REG_GPIO_OUT_1;
 	config.reg_dir_out_base = TPS6594_REG_GPIOX_CONF(0);
@@ -369,5 +573,6 @@ static struct platform_driver tps6594_pinctrl_driver = {
 module_platform_driver(tps6594_pinctrl_driver);
 
 MODULE_AUTHOR("Esteban Blanc <eblanc at baylibre.com>");
+MODULE_AUTHOR("Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>");
 MODULE_DESCRIPTION("TPS6594 pinctrl and GPIO driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From andre.przywara at arm.com  Thu Feb  8 03:02:44 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Thu, 8 Feb 2024 11:02:44 +0000
Subject: [PATCH 2/2] arm64: dts: allwinner: h616: minor whitespace
 cleanup
In-Reply-To: <20240208105301.129005-2-krzysztof.kozlowski@linaro.org>
References: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>
	<20240208105301.129005-2-krzysztof.kozlowski@linaro.org>
Message-ID: <20240208110244.2a39382a@donnerap.manchester.arm.com>

On Thu,  8 Feb 2024 11:53:01 +0100
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:

Hi,

> The DTS code coding style expects exactly one space before '{'
> character.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Thanks,
Andre

> ---
>  arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
> index b2988f500231..af421ba24ce0 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
> @@ -93,7 +93,7 @@ axp313a: pmic at 36 {
>  		interrupt-controller;
>  		#interrupt-cells = <1>;
>  
> -		regulators{
> +		regulators {
>  			reg_dcdc1: dcdc1 {
>  				regulator-name = "vdd-gpu-sys";
>  				regulator-min-microvolt = <810000>;



From devarsht at ti.com  Thu Feb  8 03:05:27 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Thu, 8 Feb 2024 16:35:27 +0530
Subject: [RFC PATCH 3/3] arm64: dts: ti: k3-am62x: Add overlay to use DSS
 in display sharing mode
In-Reply-To: <e452c6ae-e889-44a9-9fbf-99527f5c50b9@ideasonboard.com>
References: <20240116134142.2092483-1-devarsht@ti.com>
 <20240116134142.2092483-4-devarsht@ti.com>
 <e452c6ae-e889-44a9-9fbf-99527f5c50b9@ideasonboard.com>
Message-ID: <91bafebd-ccbe-d6ea-134d-77c8d9776ac8@ti.com>

Hi Tomi,

Thanks for the review.

On 23/01/24 13:59, Tomi Valkeinen wrote:
> Hi,
> 
> On 16/01/2024 15:41, Devarsh Thakkar wrote:
>> This overlay needs to be used with display sharing supported device
>> manager firmware only.
>>
>> Remote core running this firmware has write access to "common" register
>> space, VIDL pipeline, OVR1 overlay and VP1 videoport.
>>
>> The processing core running Linux is provided write access to VID
>> pipeline and "common1" register space.
>>
>> The VP1 video port is shared between Linux and remote core with remote
>> core configuring the overlay manager to set Zorder 1 for VID pipeline
>> and Zorder 2 for VIDL pipeline.
>>
>> Add reserved memory region for framebuffer region used by remote core in
>> dss shared mode overlay file so that Linux does not re-use the same
>> while allocating memory.
> 
> I don't understand this one. Why is RAM used by RTOS accessible by Linux
> in the first place?
> 

Well, I think the R5 SPL initializes full DDR before starting firmwares
on remote cores and the regions used by this remote cores be it for IPC
or Code/data are marked as reserved both in Linux as well as U-boot so
that Linux/U-boot does not use it [1].

Same scheme is followed here w.r. t RTOS framebuffer too.

[1] :
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi?h=v6.7#n63

Regards
Devarsh

> ?Tomi
> 
>> Also add a label for reserved memory region in base device-tree file so
>> that it can be referred back in overlay file.
>>
>> Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
>> ---
>> ? arch/arm64/boot/dts/ti/Makefile?????????????? |? 1 +
>> ? .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi |? 2 +-
>> ? .../dts/ti/k3-am62x-sk-dss-shared-mode.dtso?? | 33 +++++++++++++++++++
>> ? 3 files changed, 35 insertions(+), 1 deletion(-)
>> ? create mode 100644
>> arch/arm64/boot/dts/ti/k3-am62x-sk-dss-shared-mode.dtso
>>
>> diff --git a/arch/arm64/boot/dts/ti/Makefile
>> b/arch/arm64/boot/dts/ti/Makefile
>> index 52c1dc910308..ff832741b367 100644
>> --- a/arch/arm64/boot/dts/ti/Makefile
>> +++ b/arch/arm64/boot/dts/ti/Makefile
>> @@ -35,6 +35,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-ov5640.dtbo
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-tevi-ov5640.dtbo
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-imx219.dtbo
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-hdmi-audio.dtbo
>> +dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-dss-shared-mode.dtbo
>> ? ? # Boards with AM64x SoC
>> ? dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
>> b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
>> index 33768c02d8eb..8b55ca10102f 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
>> @@ -34,7 +34,7 @@ memory at 80000000 {
>> ????????? reg = <0x00000000 0x80000000 0x00000000 0x80000000>;
>> ????? };
>> ? -??? reserved-memory {
>> +??? reserved_memory: reserved-memory {
>> ????????? #address-cells = <2>;
>> ????????? #size-cells = <2>;
>> ????????? ranges;
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-dss-shared-mode.dtso
>> b/arch/arm64/boot/dts/ti/k3-am62x-sk-dss-shared-mode.dtso
>> new file mode 100644
>> index 000000000000..02153748a5c2
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-dss-shared-mode.dtso
>> @@ -0,0 +1,33 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/**
>> + * DT overlay to enable display sharing mode for AM62P DSS0
>> + * This is compatible with custom AM62 Device Manager firmware
>> + *
>> + * Copyright (C) 2023 Texas Instruments Incorporated -
>> http://www.ti.com/
>> + */
>> +
>> +/dts-v1/;
>> +/plugin/;
>> +
>> +#include <dt-bindings/interrupt-controller/irq.h>
>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>> +
>> +&dss0 {
>> +??? ti,dss-shared-mode;
>> +??? ti,dss-shared-mode-vp = "vp1";
>> +??? ti,dss-shared-mode-vp-owned = <0>;
>> +??? ti,dss-shared-mode-common = "common1";
>> +??? ti,dss-shared-mode-planes = "vid";
>> +??? ti,dss-shared-mode-plane-zorder = <0>;
>> +??? interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
>> +};
>> +
>> +&reserved_memory {
>> +??? #address-cells = <2>;
>> +??? #size-cells = <2>;
>> +??? rtos_framebuffer_memory_region: rtos-framebuffer-memory at 94800000 {
>> +??????? compatible = "shared-dma-pool";
>> +??????? reg = <0x00 0x94800000 0x00 0x08000000>;
>> +??????? no-map;
>> +??? };
>> +};
> 
> 


From angelogioacchino.delregno at collabora.com  Thu Feb  8 03:05:57 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 8 Feb 2024 12:05:57 +0100
Subject: [PATCH] arm64: dts: mediatek: mt8186: Add video decoder device
 nodes
In-Reply-To: <20231220133302.39411-1-eugen.hristev@collabora.com>
References: <20231220133302.39411-1-eugen.hristev@collabora.com>
Message-ID: <7e834188-2838-40fb-961c-fc28bdfca169@collabora.com>

Il 20/12/23 14:33, Eugen Hristev ha scritto:
> From: Yunfei Dong <yunfei.dong at mediatek.com>
> 
> Add mt8186 video decoder device nodes.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> Signed-off-by: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
> Reviewed-by: Hsin-Yi Wang <hsinyi at chromium.org>
> [eugen.hristev at collabora.com: minor cleanup]
> Signed-off-by: Eugen Hristev <eugen.hristev at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From b-kapoor at ti.com  Thu Feb  8 03:05:59 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Thu, 8 Feb 2024 16:35:59 +0530
Subject: [PATCH 0/3] arm64: dts: ti: Modify pinmux for wakeup and mcu uart
Message-ID: <20240208110602.931573-1-b-kapoor@ti.com>

WKUP_PADCONFIG registers for wakeup and mcu uart lies
under wkup_pmx2 for J7200. Thus, modify pinmux for both
of them.

Only Tx and Rx Signal lines for wakeup uart are brought out on
J721S2 Common Proc Board and J784S4 EVM, but CTS and RTS signal
lines are not brought out. Thus, remove pinmux for CTS and RTS signal
lines for wake up uart in J721S2 and J784S4.

Rebased to 20240208

Bhavya Kapoor (3):
  arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for wakeup
    and mcu uart
  arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and
    RTS in Wakeup Uart
  arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in Wakeup
    Uart

 .../boot/dts/ti/k3-j7200-common-proc-board.dts | 18 +++++++++---------
 .../dts/ti/k3-j721s2-common-proc-board.dts     |  2 --
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts       |  2 --
 3 files changed, 9 insertions(+), 13 deletions(-)

-- 
2.34.1



From b-kapoor at ti.com  Thu Feb  8 03:06:01 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Thu, 8 Feb 2024 16:36:01 +0530
Subject: [PATCH 2/3] arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and RTS in Wakeup Uart
In-Reply-To: <20240208110602.931573-1-b-kapoor@ti.com>
References: <20240208110602.931573-1-b-kapoor@ti.com>
Message-ID: <20240208110602.931573-3-b-kapoor@ti.com>

Only Tx and Rx Signal lines for wake up uart are brought out on
the Common Proc Board through SoM, but CTS and RTS signal lines
are not brought on the board. Thus, remove pinmux for CTS and RTS
signal lines for wake up uart in J721S2.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
index 361365bb5523..6371cb1c1fe7 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -190,8 +190,6 @@ J721S2_IOPAD(0x038, PIN_OUTPUT, 0) /* (AB28) MCASP0_ACLKX.MCAN5_TX */
 &wkup_pmx2 {
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (E25) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-			J721S2_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (F28) WKUP_GPIO0_7.WKUP_UART0_RTSn */
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */
 		>;
-- 
2.34.1



From b-kapoor at ti.com  Thu Feb  8 03:06:02 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Thu, 8 Feb 2024 16:36:02 +0530
Subject: [PATCH 3/3] arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in Wakeup Uart
In-Reply-To: <20240208110602.931573-1-b-kapoor@ti.com>
References: <20240208110602.931573-1-b-kapoor@ti.com>
Message-ID: <20240208110602.931573-4-b-kapoor@ti.com>

Only Tx and Rx Signal lines for wake up uart are brought out on
the J784S4 EVM from SoC, but CTS and RTS signal lines are not
brought on the EVM. Thus, remove pinmux for CTS and RTS signal
lines for wake up uart in J784S4.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
index 57e7cb8ea2b8..9f16642ccd5f 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -336,8 +336,6 @@ &wkup_pmx2 {
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
-			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-			J721S2_WKUP_IOPAD(0x074, PIN_INPUT, 0) /* (L36) WKUP_GPIO0_7.WKUP_UART0_RTSn */
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_INPUT, 0) /* (K34) WKUP_UART0_TXD */
 		>;
-- 
2.34.1



From b-kapoor at ti.com  Thu Feb  8 03:06:00 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Thu, 8 Feb 2024 16:36:00 +0530
Subject: [PATCH 1/3] arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for wakeup and mcu uart
In-Reply-To: <20240208110602.931573-1-b-kapoor@ti.com>
References: <20240208110602.931573-1-b-kapoor@ti.com>
Message-ID: <20240208110602.931573-2-b-kapoor@ti.com>

WKUP_PADCONFIG registers for wakeup and mcu uart lies
under wkup_pmx2 for J7200. Thus, modify pinmux for both
of them.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 .../boot/dts/ti/k3-j7200-common-proc-board.dts | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
index 1d8bddcae90e..6593c5da82c0 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -119,24 +119,25 @@ transceiver3: can-phy3 {
 };
 
 &wkup_pmx0 {
+};
+
+&wkup_pmx2 {
 	mcu_uart0_pins_default: mcu-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0xf4, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
-			J721E_WKUP_IOPAD(0xf0, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
-			J721E_WKUP_IOPAD(0xf8, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
-			J721E_WKUP_IOPAD(0xfc, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+			J721E_WKUP_IOPAD(0x90, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
+			J721E_WKUP_IOPAD(0x94, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+			J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
+			J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
 		>;
 	};
 
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0xb0, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
-			J721E_WKUP_IOPAD(0xb4, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
+			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
+			J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
 		>;
 	};
-};
 
-&wkup_pmx2 {
 	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
 		pinctrl-single,pins = <
 			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
@@ -272,7 +273,6 @@ &mcu_uart0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_uart0_pins_default>;
-	clock-frequency = <96000000>;
 };
 
 &main_uart0 {
-- 
2.34.1



From peter.griffin at linaro.org  Thu Feb  8 03:14:37 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu, 8 Feb 2024 11:14:37 +0000
Subject: [PATCH] arm64: dts: exynos: gs101: minor whitespace cleanup
In-Reply-To: <20240208105243.128875-1-krzysztof.kozlowski@linaro.org>
References: <20240208105243.128875-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CADrjBPqscNwMpGmDiHSnAti_RzJZRCQNpcjJ+9vrPt7TAyctVQ@mail.gmail.com>

On Thu, 8 Feb 2024 at 10:52, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> The DTS code coding style expects exactly one space before '{' and
> around '=' characters.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>

>  .../boot/dts/exynos/google/gs101-pinctrl.dtsi    |  2 +-
>  arch/arm64/boot/dts/exynos/google/gs101.dtsi     | 16 ++++++++--------
>  2 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
> index e6a9776d4d62..a675f822acec 100644
> --- a/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
> +++ b/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
> @@ -251,7 +251,7 @@ gph1: gph1-gpio-bank {
>                 #interrupt-cells = <2>;
>         };
>
> -       pcie0_clkreq: pcie0-clkreq-pins{
> +       pcie0_clkreq: pcie0-clkreq-pins {
>                 samsung,pins = "gph0-1";
>                 samsung,pin-function = <GS101_PIN_FUNC_2>;
>                 samsung,pin-pud = <GS101_PIN_PULL_UP>;
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> index c7a9e81d23b9..80cc933cca3d 100644
> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> @@ -73,7 +73,7 @@ cpu0: cpu at 0 {
>                         compatible = "arm,cortex-a55";
>                         reg = <0x0000>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
> +                       cpu-idle-states = <&ANANKE_CPU_SLEEP>;
>                         capacity-dmips-mhz = <250>;
>                         dynamic-power-coefficient = <70>;
>                 };
> @@ -83,7 +83,7 @@ cpu1: cpu at 100 {
>                         compatible = "arm,cortex-a55";
>                         reg = <0x0100>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
> +                       cpu-idle-states = <&ANANKE_CPU_SLEEP>;
>                         capacity-dmips-mhz = <250>;
>                         dynamic-power-coefficient = <70>;
>                 };
> @@ -93,7 +93,7 @@ cpu2: cpu at 200 {
>                         compatible = "arm,cortex-a55";
>                         reg = <0x0200>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
> +                       cpu-idle-states = <&ANANKE_CPU_SLEEP>;
>                         capacity-dmips-mhz = <250>;
>                         dynamic-power-coefficient = <70>;
>                 };
> @@ -103,7 +103,7 @@ cpu3: cpu at 300 {
>                         compatible = "arm,cortex-a55";
>                         reg = <0x0300>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
> +                       cpu-idle-states = <&ANANKE_CPU_SLEEP>;
>                         capacity-dmips-mhz = <250>;
>                         dynamic-power-coefficient = <70>;
>                 };
> @@ -113,7 +113,7 @@ cpu4: cpu at 400 {
>                         compatible = "arm,cortex-a76";
>                         reg = <0x0400>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ENYO_CPU_SLEEP>;
> +                       cpu-idle-states = <&ENYO_CPU_SLEEP>;
>                         capacity-dmips-mhz = <620>;
>                         dynamic-power-coefficient = <284>;
>                 };
> @@ -123,7 +123,7 @@ cpu5: cpu at 500 {
>                         compatible = "arm,cortex-a76";
>                         reg = <0x0500>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ENYO_CPU_SLEEP>;
> +                       cpu-idle-states = <&ENYO_CPU_SLEEP>;
>                         capacity-dmips-mhz = <620>;
>                         dynamic-power-coefficient = <284>;
>                 };
> @@ -133,7 +133,7 @@ cpu6: cpu at 600 {
>                         compatible = "arm,cortex-x1";
>                         reg = <0x0600>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&HERA_CPU_SLEEP>;
> +                       cpu-idle-states = <&HERA_CPU_SLEEP>;
>                         capacity-dmips-mhz = <1024>;
>                         dynamic-power-coefficient = <650>;
>                 };
> @@ -143,7 +143,7 @@ cpu7: cpu at 700 {
>                         compatible = "arm,cortex-x1";
>                         reg = <0x0700>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&HERA_CPU_SLEEP>;
> +                       cpu-idle-states = <&HERA_CPU_SLEEP>;
>                         capacity-dmips-mhz = <1024>;
>                         dynamic-power-coefficient = <650>;
>                 };
> --
> 2.34.1
>


From quic_snehshah at quicinc.com  Thu Feb  8 03:17:14 2024
From: quic_snehshah at quicinc.com (Sneh Shah)
Date: Thu,  8 Feb 2024 16:47:14 +0530
Subject: [PATCH net-next v4] net: stmmac: dwmac-qcom-ethqos: Add support for 2.5G SGMII
Message-ID: <20240208111714.11456-1-quic_snehshah@quicinc.com>

Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000
mode for 1G/100M/10M speed.
Added changes to configure serdes phy and mac based on link speed.
Changing serdes phy speed involves multiple register writes for
serdes block. To avoid redundant write operations only update serdes
phy when new speed is different.

Signed-off-by: Sneh Shah <quic_snehshah at quicinc.com>
---
v4 changelog:
- Made cosmetic changes
v3 changelog:
- updated commit message
---
v2 changelog:
- updated stmmac_pcs_ane to support autoneg disable
- Update serdes speed to 1000 for 100M and 10M also---
 .../stmicro/stmmac/dwmac-qcom-ethqos.c        | 26 +++++++++++++++++++
 .../net/ethernet/stmicro/stmmac/stmmac_pcs.h  |  2 ++
 2 files changed, 28 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 31631e3f89d0..6bbdbb7bef44 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -106,6 +106,7 @@ struct qcom_ethqos {
 	struct clk *link_clk;
 	struct phy *serdes_phy;
 	unsigned int speed;
+	int serdes_speed;
 	phy_interface_t phy_mode;
 
 	const struct ethqos_emac_por *por;
@@ -606,19 +607,39 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos)
  */
 static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
 {
+	struct net_device *dev = platform_get_drvdata(ethqos->pdev);
+	struct stmmac_priv *priv = netdev_priv(dev);
 	int val;
 
 	val = readl(ethqos->mac_base + MAC_CTRL_REG);
 
 	switch (ethqos->speed) {
+	case SPEED_2500:
+		val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
+		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_IO_MACRO_CONFIG2);
+		if (ethqos->serdes_speed != SPEED_2500)
+			phy_set_speed(ethqos->serdes_phy, SPEED_2500);
+		ethqos->serdes_speed = SPEED_2500;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 0, 0, 0);
+		break;
 	case SPEED_1000:
 		val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
 		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
 			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
 			      RGMII_IO_MACRO_CONFIG2);
+		if (ethqos->serdes_speed != SPEED_1000)
+			phy_set_speed(ethqos->serdes_phy, SPEED_1000);
+		ethqos->serdes_speed = SPEED_1000;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
 		break;
 	case SPEED_100:
 		val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE;
+		if (ethqos->serdes_speed != SPEED_1000)
+			phy_set_speed(ethqos->serdes_phy, SPEED_1000);
+		ethqos->serdes_speed = SPEED_1000;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
 		break;
 	case SPEED_10:
 		val |= ETHQOS_MAC_CTRL_PORT_SEL;
@@ -627,6 +648,10 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
 			      FIELD_PREP(RGMII_CONFIG_SGMII_CLK_DVDR,
 					 SGMII_10M_RX_CLK_DVDR),
 			      RGMII_IO_MACRO_CONFIG);
+		if (ethqos->serdes_speed != SPEED_1000)
+			phy_set_speed(ethqos->serdes_phy, ethqos->speed);
+		ethqos->serdes_speed = SPEED_1000;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
 		break;
 	}
 
@@ -799,6 +824,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 				     "Failed to get serdes phy\n");
 
 	ethqos->speed = SPEED_1000;
+	ethqos->serdes_speed = SPEED_1000;
 	ethqos_update_link_clk(ethqos, SPEED_1000);
 	ethqos_set_func_clk_en(ethqos);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
index aefc121464b5..13a30e6df4c1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
@@ -110,6 +110,8 @@ static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane,
 	/* Enable and restart the Auto-Negotiation */
 	if (ane)
 		value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN;
+	else
+		value &= ~GMAC_AN_CTRL_ANE;
 
 	/* In case of MAC-2-MAC connection, block is configured to operate
 	 * according to MAC conf register.
-- 
2.17.1



From oliver.upton at linux.dev  Thu Feb  8 03:22:03 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 8 Feb 2024 11:22:03 +0000
Subject: [PATCH v1 0/2] small kern_hyp_va() cleanups
In-Reply-To: <20240208105422.3444159-1-joey.gouly@arm.com>
References: <20240208105422.3444159-1-joey.gouly@arm.com>
Message-ID: <ZcS5W0xl92g-RVM6@linux.dev>

Hi Joey,

Thanks for having a look.

On Thu, Feb 08, 2024 at 10:54:20AM +0000, Joey Gouly wrote:
> I wanted to add some comments to __kern_hyp_va(), since I was recently trying
> to understand it, and I think it could be helpful for someone looking at it in
> the future.

That part is definitely a bit screwy :)

> The second patch removes the assembly macro version, since it is unused. Maybe
> (out-of-tree) pkvm uses it or it's just worth keeping around in case someone
> needs it in the future. So if that patch isn't applied it's not too important.

Keeping unused code hanging around is rarely useful. While it is nice to
give consideration to the pKVM folks (looks like they don't need it), it
is easy enough to re-introduce later on.

-- 
Thanks,
Oliver


From adrian.hunter at intel.com  Thu Feb  8 03:31:15 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:15 +0200
Subject: [PATCH V5 00/12] perf/core: Add ability for an event to "pause" or "resume" AUX area tracing
Message-ID: <20240208113127.22216-1-adrian.hunter@intel.com>

Hi

Hardware traces, such as instruction traces, can produce a vast amount of
trace data, so being able to reduce tracing to more specific circumstances
can be useful.

The ability to pause or resume tracing when another event happens, can do
that.

These patches add such a facilty and show how it would work for Intel
Processor Trace.

Maintainers of other AUX area tracing implementations are requested to
consider if this is something they might employ and then whether or not
the ABI would work for them.  Note, thank you to James Clark (ARM) for
evaluating the API for Coresight.  Suzuki K Poulose (ARM) also responded
positively to the RFC.

Changes to perf tools are now (since V4) fleshed out.


Changes in V5:

    perf/core: Add aux_pause, aux_resume, aux_start_paused
	Added James' Ack

    perf/x86/intel: Do not enable large PEBS for events with aux actions or aux sampling
	New patch

    perf tools
	Added Ian's Ack

Changes in V4:

    perf/core: Add aux_pause, aux_resume, aux_start_paused
	Rename aux_output_cfg -> aux_action
	Reorder aux_action bits from:
		aux_pause, aux_resume, aux_start_paused
	to:
		aux_start_paused, aux_pause, aux_resume
	Fix aux_action bits __u64 -> __u32

    coresight: Have a stab at support for pause / resume
	Dropped

    perf tools
	All new patches

Changes in RFC V3:

    coresight: Have a stab at support for pause / resume
	'mode' -> 'flags' so it at least compiles

Changes in RFC V2:

	Use ->stop() / ->start() instead of ->pause_resume()
	Move aux_start_paused bit into aux_output_cfg
	Tighten up when Intel PT pause / resume is allowed
	Add an example of how it might work for CoreSight


Adrian Hunter (12):
      perf/core: Add aux_pause, aux_resume, aux_start_paused
      perf/x86/intel/pt: Add support for pause / resume
      perf/x86/intel: Do not enable large PEBS for events with aux actions or aux sampling
      perf tools: Enable evsel__is_aux_event() to work for ARM/ARM64
      perf tools: Enable evsel__is_aux_event() to work for S390_CPUMSF
      perf tools: Add aux_start_paused, aux_pause and aux_resume
      perf tools: Add aux-action config term
      perf tools: Parse aux-action
      perf tools: Add missing_features for aux_start_paused, aux_pause, aux_resume
      perf intel-pt: Improve man page format
      perf intel-pt: Add documentation for pause / resume
      perf intel-pt: Add a test for pause / resume

 arch/x86/events/intel/core.c               |  10 +-
 arch/x86/events/intel/pt.c                 |  63 ++-
 arch/x86/events/intel/pt.h                 |   4 +
 include/linux/perf_event.h                 |  15 +
 include/uapi/linux/perf_event.h            |  11 +-
 kernel/events/core.c                       |  72 +++-
 kernel/events/internal.h                   |   1 +
 tools/include/uapi/linux/perf_event.h      |  11 +-
 tools/perf/Documentation/perf-intel-pt.txt | 596 ++++++++++++++++++-----------
 tools/perf/Documentation/perf-record.txt   |   4 +
 tools/perf/arch/arm/util/pmu.c             |   3 +
 tools/perf/builtin-record.c                |   4 +-
 tools/perf/tests/shell/test_intel_pt.sh    |  28 ++
 tools/perf/util/auxtrace.c                 |  67 +++-
 tools/perf/util/auxtrace.h                 |   6 +-
 tools/perf/util/evsel.c                    |  13 +-
 tools/perf/util/evsel.h                    |   1 +
 tools/perf/util/evsel_config.h             |   1 +
 tools/perf/util/parse-events.c             |  10 +
 tools/perf/util/parse-events.h             |   1 +
 tools/perf/util/parse-events.l             |   1 +
 tools/perf/util/perf_event_attr_fprintf.c  |   3 +
 tools/perf/util/pmu.c                      |   6 +-
 23 files changed, 691 insertions(+), 240 deletions(-)


Regards
Adrian


From adrian.hunter at intel.com  Thu Feb  8 03:31:16 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:16 +0200
Subject: [PATCH V5 01/12] perf/core: Add aux_pause, aux_resume, aux_start_paused
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-2-adrian.hunter@intel.com>

Hardware traces, such as instruction traces, can produce a vast amount of
trace data, so being able to reduce tracing to more specific circumstances
can be useful.

The ability to pause or resume tracing when another event happens, can do
that.

Add ability for an event to "pause" or "resume" AUX area tracing.

Add aux_pause bit to perf_event_attr to indicate that, if the event
happens, the associated AUX area tracing should be paused. Ditto
aux_resume. Do not allow aux_pause and aux_resume to be set together.

Add aux_start_paused bit to perf_event_attr to indicate to an AUX area
event that it should start in a "paused" state.

Add aux_paused to struct perf_event for AUX area events to keep track of
the "paused" state. aux_paused is initialized to aux_start_paused.

Add PERF_EF_PAUSE and PERF_EF_RESUME modes for ->stop() and ->start()
callbacks. Call as needed, during __perf_event_output(). Add
aux_in_pause_resume to struct perf_buffer to prevent races with the NMI
handler. Pause/resume in NMI context will miss out if it coincides with
another pause/resume.

To use aux_pause or aux_resume, an event must be in a group with the AUX
area event as the group leader.

Example (requires Intel PT and tools patches also):

 $ perf record --kcore -e intel_pt/aux-action=start-paused/k,syscalls:sys_enter_newuname/aux-action=resume/,syscalls:sys_exit_newuname/aux-action=pause/ uname
 Linux
 [ perf record: Woken up 1 times to write data ]
 [ perf record: Captured and wrote 0.043 MB perf.data ]
 $ perf script --call-trace
 uname   30805 [000] 24001.058782799: name: 0x7ffc9c1865b0
 uname   30805 [000] 24001.058784424:  psb offs: 0
 uname   30805 [000] 24001.058784424:  cbr: 39 freq: 3904 MHz (139%)
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])        debug_smp_processor_id
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])        __x64_sys_newuname
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])            down_read
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                __cond_resched
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                preempt_count_add
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                    in_lock_functions
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                preempt_count_sub
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])            up_read
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                preempt_count_add
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                    in_lock_functions
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                preempt_count_sub
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])            _copy_to_user
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])        syscall_exit_to_user_mode
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])            syscall_exit_work
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                perf_syscall_exit
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                    debug_smp_processor_id
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                    perf_trace_buf_alloc
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        perf_swevent_get_recursion_context
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            debug_smp_processor_id
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        debug_smp_processor_id
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                    perf_tp_event
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        perf_trace_buf_update
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            tracing_gen_ctx_irq_test
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        perf_swevent_event
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            __perf_event_account_interrupt
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                __this_cpu_preempt_check
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            perf_event_output_forward
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                perf_event_aux_pause
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                    ring_buffer_get
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                        __rcu_read_lock
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                        __rcu_read_unlock
 uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                    pt_event_stop
 uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                        debug_smp_processor_id
 uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                        debug_smp_processor_id
 uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                        native_write_msr
 uname   30805 [000] 24001.058785463: ([kernel.kallsyms])                                        native_write_msr
 uname   30805 [000] 24001.058785639: 0x0

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: James Clark <james.clark at arm.com>
---


Changes in V5:
	Added James' Ack

Changes in V4:
	Rename aux_output_cfg -> aux_action
	Reorder aux_action bits from:
		aux_pause, aux_resume, aux_start_paused
	to:
		aux_start_paused, aux_pause, aux_resume
	Fix aux_action bits __u64 -> __u32


 include/linux/perf_event.h      | 15 +++++++
 include/uapi/linux/perf_event.h | 11 ++++-
 kernel/events/core.c            | 72 +++++++++++++++++++++++++++++++--
 kernel/events/internal.h        |  1 +
 4 files changed, 95 insertions(+), 4 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index d2a15c0c6f8a..6c1600b9bdb3 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -291,6 +291,7 @@ struct perf_event_pmu_context;
 #define PERF_PMU_CAP_NO_EXCLUDE			0x0040
 #define PERF_PMU_CAP_AUX_OUTPUT			0x0080
 #define PERF_PMU_CAP_EXTENDED_HW_TYPE		0x0100
+#define PERF_PMU_CAP_AUX_PAUSE			0x0200
 
 struct perf_output_handle;
 
@@ -363,6 +364,8 @@ struct pmu {
 #define PERF_EF_START	0x01		/* start the counter when adding    */
 #define PERF_EF_RELOAD	0x02		/* reload the counter when starting */
 #define PERF_EF_UPDATE	0x04		/* update the counter when stopping */
+#define PERF_EF_PAUSE	0x08		/* AUX area event, pause tracing */
+#define PERF_EF_RESUME	0x10		/* AUX area event, resume tracing */
 
 	/*
 	 * Adds/Removes a counter to/from the PMU, can be done inside a
@@ -402,6 +405,15 @@ struct pmu {
 	 *
 	 * ->start() with PERF_EF_RELOAD will reprogram the counter
 	 *  value, must be preceded by a ->stop() with PERF_EF_UPDATE.
+	 *
+	 * ->stop() with PERF_EF_PAUSE will stop as simply as possible. Will not
+	 * overlap another ->stop() with PERF_EF_PAUSE nor ->start() with
+	 * PERF_EF_RESUME.
+	 *
+	 * ->start() with PERF_EF_RESUME will start as simply as possible but
+	 * only if the counter is not otherwise stopped. Will not overlap
+	 * another ->start() with PERF_EF_RESUME nor ->stop() with
+	 * PERF_EF_PAUSE.
 	 */
 	void (*start)			(struct perf_event *event, int flags);
 	void (*stop)			(struct perf_event *event, int flags);
@@ -798,6 +810,9 @@ struct perf_event {
 	/* for aux_output events */
 	struct perf_event		*aux_event;
 
+	/* for AUX area events */
+	unsigned int			aux_paused;
+
 	void (*destroy)(struct perf_event *);
 	struct rcu_head			rcu_head;
 
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 3a64499b0f5d..0c557f0a17b3 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -511,7 +511,16 @@ struct perf_event_attr {
 	__u16	sample_max_stack;
 	__u16	__reserved_2;
 	__u32	aux_sample_size;
-	__u32	__reserved_3;
+
+	union {
+		__u32	aux_action;
+		struct {
+			__u32	aux_start_paused :  1, /* start AUX area tracing paused */
+				aux_pause        :  1, /* on overflow, pause AUX area tracing */
+				aux_resume       :  1, /* on overflow, resume AUX area tracing */
+				__reserved_3     : 29;
+		};
+	};
 
 	/*
 	 * User provided data if sigtrap=1, passed back to user via
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f0f0f71213a1..00f6d0a327e8 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -2097,7 +2097,8 @@ static void perf_put_aux_event(struct perf_event *event)
 
 static bool perf_need_aux_event(struct perf_event *event)
 {
-	return !!event->attr.aux_output || !!event->attr.aux_sample_size;
+	return event->attr.aux_output || event->attr.aux_sample_size ||
+	       event->attr.aux_pause || event->attr.aux_resume;
 }
 
 static int perf_get_aux_event(struct perf_event *event,
@@ -2122,6 +2123,10 @@ static int perf_get_aux_event(struct perf_event *event,
 	    !perf_aux_output_match(event, group_leader))
 		return 0;
 
+	if ((event->attr.aux_pause || event->attr.aux_resume) &&
+	    !(group_leader->pmu->capabilities & PERF_PMU_CAP_AUX_PAUSE))
+		return 0;
+
 	if (event->attr.aux_sample_size && !group_leader->pmu->snapshot_aux)
 		return 0;
 
@@ -7854,6 +7859,47 @@ void perf_prepare_header(struct perf_event_header *header,
 	WARN_ON_ONCE(header->size & 7);
 }
 
+static void __perf_event_aux_pause(struct perf_event *event, bool pause)
+{
+	if (pause) {
+		if (!READ_ONCE(event->aux_paused)) {
+			WRITE_ONCE(event->aux_paused, 1);
+			event->pmu->stop(event, PERF_EF_PAUSE);
+		}
+	} else {
+		if (READ_ONCE(event->aux_paused)) {
+			WRITE_ONCE(event->aux_paused, 0);
+			event->pmu->start(event, PERF_EF_RESUME);
+		}
+	}
+}
+
+static void perf_event_aux_pause(struct perf_event *event, bool pause)
+{
+	struct perf_buffer *rb;
+	unsigned long flags;
+
+	if (WARN_ON_ONCE(!event))
+		return;
+
+	rb = ring_buffer_get(event);
+	if (!rb)
+		return;
+
+	local_irq_save(flags);
+	/* Guard against NMI, NMI loses here */
+	if (READ_ONCE(rb->aux_in_pause_resume))
+		goto out_restore;
+	WRITE_ONCE(rb->aux_in_pause_resume, 1);
+	barrier();
+	__perf_event_aux_pause(event, pause);
+	barrier();
+	WRITE_ONCE(rb->aux_in_pause_resume, 0);
+out_restore:
+	local_irq_restore(flags);
+	ring_buffer_put(rb);
+}
+
 static __always_inline int
 __perf_event_output(struct perf_event *event,
 		    struct perf_sample_data *data,
@@ -7867,6 +7913,9 @@ __perf_event_output(struct perf_event *event,
 	struct perf_event_header header;
 	int err;
 
+	if (event->attr.aux_pause)
+		perf_event_aux_pause(event->aux_event, true);
+
 	/* protect the callchain buffers */
 	rcu_read_lock();
 
@@ -7883,6 +7932,10 @@ __perf_event_output(struct perf_event *event,
 
 exit:
 	rcu_read_unlock();
+
+	if (event->attr.aux_resume)
+		perf_event_aux_pause(event->aux_event, false);
+
 	return err;
 }
 
@@ -12036,10 +12089,23 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
 	}
 
 	if (event->attr.aux_output &&
-	    !(pmu->capabilities & PERF_PMU_CAP_AUX_OUTPUT)) {
+	    (!(pmu->capabilities & PERF_PMU_CAP_AUX_OUTPUT) ||
+	     event->attr.aux_pause || event->attr.aux_resume)) {
+		err = -EOPNOTSUPP;
+		goto err_pmu;
+	}
+
+	if (event->attr.aux_pause && event->attr.aux_resume) {
+		err = -EINVAL;
+		goto err_pmu;
+	}
+
+	if (event->attr.aux_start_paused &&
+	    !(pmu->capabilities & PERF_PMU_CAP_AUX_PAUSE)) {
 		err = -EOPNOTSUPP;
 		goto err_pmu;
 	}
+	event->aux_paused = event->attr.aux_start_paused;
 
 	if (cgroup_fd != -1) {
 		err = perf_cgroup_connect(cgroup_fd, event, attr, group_leader);
@@ -12836,7 +12902,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
 	 * Grouping is not supported for kernel events, neither is 'AUX',
 	 * make sure the caller's intentions are adjusted.
 	 */
-	if (attr->aux_output)
+	if (attr->aux_output || attr->aux_action)
 		return ERR_PTR(-EINVAL);
 
 	event = perf_event_alloc(attr, cpu, task, NULL, NULL,
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index 5150d5f84c03..3320f78117dc 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -51,6 +51,7 @@ struct perf_buffer {
 	void				(*free_aux)(void *);
 	refcount_t			aux_refcount;
 	int				aux_in_sampling;
+	int				aux_in_pause_resume;
 	void				**aux_pages;
 	void				*aux_priv;
 
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:17 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:17 +0200
Subject: [PATCH V5 02/12] perf/x86/intel/pt: Add support for pause / resume
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-3-adrian.hunter@intel.com>

Prevent tracing to start if aux_paused.

Implement support for PERF_EF_PAUSE / PERF_EF_RESUME. When aux_paused, stop
tracing. When not aux_paused, only start tracing if it isn't currently
meant to be stopped.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
---
 arch/x86/events/intel/pt.c | 63 ++++++++++++++++++++++++++++++++++++--
 arch/x86/events/intel/pt.h |  4 +++
 2 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index 8e2a12235e62..b6e838f2c6d5 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -418,6 +418,9 @@ static void pt_config_start(struct perf_event *event)
 	struct pt *pt = this_cpu_ptr(&pt_ctx);
 	u64 ctl = event->hw.config;
 
+	if (READ_ONCE(event->aux_paused))
+		return;
+
 	ctl |= RTIT_CTL_TRACEEN;
 	if (READ_ONCE(pt->vmx_on))
 		perf_aux_output_flag(&pt->handle, PERF_AUX_FLAG_PARTIAL);
@@ -534,7 +537,20 @@ static void pt_config(struct perf_event *event)
 	reg |= (event->attr.config & PT_CONFIG_MASK);
 
 	event->hw.config = reg;
+
+	/*
+	 * Allow resume before starting so as not to overwrite a value set by a
+	 * PMI.
+	 */
+	WRITE_ONCE(pt->resume_allowed, 1);
+
 	pt_config_start(event);
+
+	/*
+	 * Allow pause after starting so its pt_config_stop() doesn't race with
+	 * pt_config_start().
+	 */
+	WRITE_ONCE(pt->pause_allowed, 1);
 }
 
 static void pt_config_stop(struct perf_event *event)
@@ -1511,6 +1527,7 @@ void intel_pt_interrupt(void)
 		buf = perf_aux_output_begin(&pt->handle, event);
 		if (!buf) {
 			event->hw.state = PERF_HES_STOPPED;
+			pt->resume_allowed = 0;
 			return;
 		}
 
@@ -1519,6 +1536,7 @@ void intel_pt_interrupt(void)
 		ret = pt_buffer_reset_markers(buf, &pt->handle);
 		if (ret) {
 			perf_aux_output_end(&pt->handle, 0);
+			pt->resume_allowed = 0;
 			return;
 		}
 
@@ -1573,6 +1591,26 @@ static void pt_event_start(struct perf_event *event, int mode)
 	struct pt *pt = this_cpu_ptr(&pt_ctx);
 	struct pt_buffer *buf;
 
+	if (mode & PERF_EF_RESUME) {
+		if (READ_ONCE(pt->resume_allowed)) {
+			u64 status;
+
+			/*
+			 * Only if the trace is not active and the error and
+			 * stopped bits are clear, is it safe to start, but a
+			 * PMI might have just cleared these, so resume_allowed
+			 * must be checked again also.
+			 */
+			rdmsrl(MSR_IA32_RTIT_STATUS, status);
+			if (!(status & (RTIT_STATUS_TRIGGEREN |
+					RTIT_STATUS_ERROR |
+					RTIT_STATUS_STOPPED)) &&
+			   READ_ONCE(pt->resume_allowed))
+				pt_config_start(event);
+		}
+		return;
+	}
+
 	buf = perf_aux_output_begin(&pt->handle, event);
 	if (!buf)
 		goto fail_stop;
@@ -1601,6 +1639,16 @@ static void pt_event_stop(struct perf_event *event, int mode)
 {
 	struct pt *pt = this_cpu_ptr(&pt_ctx);
 
+	if (mode & PERF_EF_PAUSE) {
+		if (READ_ONCE(pt->pause_allowed))
+			pt_config_stop(event);
+		return;
+	}
+
+	/* Protect against racing */
+	WRITE_ONCE(pt->pause_allowed, 0);
+	WRITE_ONCE(pt->resume_allowed, 0);
+
 	/*
 	 * Protect against the PMI racing with disabling wrmsr,
 	 * see comment in intel_pt_interrupt().
@@ -1659,8 +1707,12 @@ static long pt_event_snapshot_aux(struct perf_event *event,
 	/*
 	 * Here, handle_nmi tells us if the tracing is on
 	 */
-	if (READ_ONCE(pt->handle_nmi))
+	if (READ_ONCE(pt->handle_nmi)) {
+		/* Protect against racing */
+		WRITE_ONCE(pt->pause_allowed, 0);
+		WRITE_ONCE(pt->resume_allowed, 0);
 		pt_config_stop(event);
+	}
 
 	pt_read_offset(buf);
 	pt_update_head(pt);
@@ -1677,8 +1729,11 @@ static long pt_event_snapshot_aux(struct perf_event *event,
 	 * Compiler barrier not needed as we couldn't have been
 	 * preempted by anything that touches pt->handle_nmi.
 	 */
-	if (pt->handle_nmi)
+	if (pt->handle_nmi) {
+		WRITE_ONCE(pt->resume_allowed, 1);
 		pt_config_start(event);
+		WRITE_ONCE(pt->pause_allowed, 1);
+	}
 
 	return ret;
 }
@@ -1794,7 +1849,9 @@ static __init int pt_init(void)
 	if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries))
 		pt_pmu.pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG;
 
-	pt_pmu.pmu.capabilities	|= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE;
+	pt_pmu.pmu.capabilities		|= PERF_PMU_CAP_EXCLUSIVE |
+					   PERF_PMU_CAP_ITRACE |
+					   PERF_PMU_CAP_AUX_PAUSE;
 	pt_pmu.pmu.attr_groups		 = pt_attr_groups;
 	pt_pmu.pmu.task_ctx_nr		 = perf_sw_context;
 	pt_pmu.pmu.event_init		 = pt_event_init;
diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h
index 96906a62aacd..b9527205e028 100644
--- a/arch/x86/events/intel/pt.h
+++ b/arch/x86/events/intel/pt.h
@@ -117,6 +117,8 @@ struct pt_filters {
  * @filters:		last configured filters
  * @handle_nmi:		do handle PT PMI on this cpu, there's an active event
  * @vmx_on:		1 if VMX is ON on this cpu
+ * @pause_allowed:	PERF_EF_PAUSE is allowed to stop tracing
+ * @resume_allowed:	PERF_EF_RESUME is allowed to start tracing
  * @output_base:	cached RTIT_OUTPUT_BASE MSR value
  * @output_mask:	cached RTIT_OUTPUT_MASK MSR value
  */
@@ -125,6 +127,8 @@ struct pt {
 	struct pt_filters	filters;
 	int			handle_nmi;
 	int			vmx_on;
+	int			pause_allowed;
+	int			resume_allowed;
 	u64			output_base;
 	u64			output_mask;
 };
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:18 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:18 +0200
Subject: [PATCH V5 03/12] perf/x86/intel: Do not enable large PEBS for events with aux actions or aux sampling
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-4-adrian.hunter@intel.com>

Events with aux actions or aux sampling expect the PMI to coincide with the
event, which does not happen for large PEBS, so do not enable large PEBS in
that case.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
---
 arch/x86/events/intel/core.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 3804f21ab049..d50f4325d42a 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -3885,6 +3885,12 @@ static inline bool intel_pmu_has_cap(struct perf_event *event, int idx)
 	return test_bit(idx, (unsigned long *)&intel_cap->capabilities);
 }
 
+static inline bool has_aux_action(struct perf_event *event)
+{
+	return event->attr.aux_pause || event->attr.aux_resume ||
+	       event->attr.aux_sample_size;
+}
+
 static int intel_pmu_hw_config(struct perf_event *event)
 {
 	int ret = x86_pmu_hw_config(event);
@@ -3902,8 +3908,8 @@ static int intel_pmu_hw_config(struct perf_event *event)
 
 		if (!(event->attr.freq || (event->attr.wakeup_events && !event->attr.watermark))) {
 			event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
-			if (!(event->attr.sample_type &
-			      ~intel_pmu_large_pebs_flags(event))) {
+			if (!(event->attr.sample_type & ~intel_pmu_large_pebs_flags(event)) &&
+			    !has_aux_action(event)) {
 				event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS;
 				event->attach_state |= PERF_ATTACH_SCHED_CB;
 			}
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:19 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:19 +0200
Subject: [PATCH V5 04/12] perf tools: Enable evsel__is_aux_event() to work for ARM/ARM64
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-5-adrian.hunter@intel.com>

Set pmu->auxtrace on ARM/ARM64 AUX area PMUs. evsel__is_aux_event() needs
the setting to identify AUX area tracing selected events.

Currently, the features that use evsel__is_aux_event() are used only by
Intel PT, but that may change in the future.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm/util/pmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/arch/arm/util/pmu.c b/tools/perf/arch/arm/util/pmu.c
index 8b7cb68ba1a8..668a4310cb69 100644
--- a/tools/perf/arch/arm/util/pmu.c
+++ b/tools/perf/arch/arm/util/pmu.c
@@ -20,16 +20,19 @@ void perf_pmu__arch_init(struct perf_pmu *pmu __maybe_unused)
 #ifdef HAVE_AUXTRACE_SUPPORT
 	if (!strcmp(pmu->name, CORESIGHT_ETM_PMU_NAME)) {
 		/* add ETM default config here */
+		pmu->auxtrace = true;
 		pmu->selectable = true;
 		pmu->perf_event_attr_init_default = cs_etm_get_default_config;
 #if defined(__aarch64__)
 	} else if (strstarts(pmu->name, ARM_SPE_PMU_NAME)) {
+		pmu->auxtrace = true;
 		pmu->selectable = true;
 		pmu->is_uncore = false;
 		pmu->perf_event_attr_init_default = arm_spe_pmu_default_config;
 		if (!strcmp(pmu->name, "arm_spe_0"))
 			pmu->mem_events = perf_mem_events_arm;
 	} else if (strstarts(pmu->name, HISI_PTT_PMU_NAME)) {
+		pmu->auxtrace = true;
 		pmu->selectable = true;
 #endif
 	}
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:20 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:20 +0200
Subject: [PATCH V5 05/12] perf tools: Enable evsel__is_aux_event() to work for S390_CPUMSF
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-6-adrian.hunter@intel.com>

evsel__is_aux_event() identifies AUX area tracing selected events.

S390_CPUMSF uses a raw event type (PERF_TYPE_RAW - refer
s390_cpumsf_evsel_is_auxtrace()) not a PMU type value that could be checked
in evsel__is_aux_event(). However it sets needs_auxtrace_mmap (refer
auxtrace_record__init()), so check that first.

Currently, the features that use evsel__is_aux_event() are used only by
Intel PT, but that may change in the future.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/pmu.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 437386dedd5c..40be43f1f648 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -1099,8 +1099,12 @@ void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu)
 
 bool evsel__is_aux_event(const struct evsel *evsel)
 {
-	struct perf_pmu *pmu = evsel__find_pmu(evsel);
+	struct perf_pmu *pmu;
+
+	if (evsel->needs_auxtrace_mmap)
+		return true;
 
+	pmu = evsel__find_pmu(evsel);
 	return pmu && pmu->auxtrace;
 }
 
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:21 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:21 +0200
Subject: [PATCH V5 06/12] perf tools: Add aux_start_paused, aux_pause and aux_resume
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-7-adrian.hunter@intel.com>

Add struct perf_event_attr members to support pause and resume of AUX area
tracing.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: Ian Rogers <irogers at google.com>
---
 tools/include/uapi/linux/perf_event.h     | 11 ++++++++++-
 tools/perf/util/perf_event_attr_fprintf.c |  3 +++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index 3a64499b0f5d..0c557f0a17b3 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -511,7 +511,16 @@ struct perf_event_attr {
 	__u16	sample_max_stack;
 	__u16	__reserved_2;
 	__u32	aux_sample_size;
-	__u32	__reserved_3;
+
+	union {
+		__u32	aux_action;
+		struct {
+			__u32	aux_start_paused :  1, /* start AUX area tracing paused */
+				aux_pause        :  1, /* on overflow, pause AUX area tracing */
+				aux_resume       :  1, /* on overflow, resume AUX area tracing */
+				__reserved_3     : 29;
+		};
+	};
 
 	/*
 	 * User provided data if sigtrap=1, passed back to user via
diff --git a/tools/perf/util/perf_event_attr_fprintf.c b/tools/perf/util/perf_event_attr_fprintf.c
index 8f04d3b7f3ec..0e3cb35aab33 100644
--- a/tools/perf/util/perf_event_attr_fprintf.c
+++ b/tools/perf/util/perf_event_attr_fprintf.c
@@ -323,6 +323,9 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
 	PRINT_ATTRf(sample_max_stack, p_unsigned);
 	PRINT_ATTRf(aux_sample_size, p_unsigned);
 	PRINT_ATTRf(sig_data, p_unsigned);
+	PRINT_ATTRf(aux_start_paused, p_unsigned);
+	PRINT_ATTRf(aux_pause, p_unsigned);
+	PRINT_ATTRf(aux_resume, p_unsigned);
 
 	return ret;
 }
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:22 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:22 +0200
Subject: [PATCH V5 07/12] perf tools: Add aux-action config term
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-8-adrian.hunter@intel.com>

Add a new common config term "aux-action" to use for configuring AUX area
trace pause / resume. The value is a string that will be parsed in a
subsequent patch.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/evsel.c        |  2 ++
 tools/perf/util/evsel_config.h |  1 +
 tools/perf/util/parse-events.c | 10 ++++++++++
 tools/perf/util/parse-events.h |  1 +
 tools/perf/util/parse-events.l |  1 +
 5 files changed, 15 insertions(+)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3536404e9447..866c69f83595 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1001,6 +1001,8 @@ static void evsel__apply_config_terms(struct evsel *evsel,
 		case EVSEL__CONFIG_TERM_AUX_OUTPUT:
 			attr->aux_output = term->val.aux_output ? 1 : 0;
 			break;
+		case EVSEL__CONFIG_TERM_AUX_ACTION:
+			break;
 		case EVSEL__CONFIG_TERM_AUX_SAMPLE_SIZE:
 			/* Already applied by auxtrace */
 			break;
diff --git a/tools/perf/util/evsel_config.h b/tools/perf/util/evsel_config.h
index aee6f808b512..af52a1516d0b 100644
--- a/tools/perf/util/evsel_config.h
+++ b/tools/perf/util/evsel_config.h
@@ -25,6 +25,7 @@ enum evsel_term_type {
 	EVSEL__CONFIG_TERM_BRANCH,
 	EVSEL__CONFIG_TERM_PERCORE,
 	EVSEL__CONFIG_TERM_AUX_OUTPUT,
+	EVSEL__CONFIG_TERM_AUX_ACTION,
 	EVSEL__CONFIG_TERM_AUX_SAMPLE_SIZE,
 	EVSEL__CONFIG_TERM_CFG_CHG,
 };
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6f8b0fa17689..75ebc515faba 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -768,6 +768,7 @@ static const char *config_term_name(enum parse_events__term_type term_type)
 		[PARSE_EVENTS__TERM_TYPE_DRV_CFG]		= "driver-config",
 		[PARSE_EVENTS__TERM_TYPE_PERCORE]		= "percore",
 		[PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT]		= "aux-output",
+		[PARSE_EVENTS__TERM_TYPE_AUX_ACTION]		= "aux-action",
 		[PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE]	= "aux-sample-size",
 		[PARSE_EVENTS__TERM_TYPE_METRIC_ID]		= "metric-id",
 		[PARSE_EVENTS__TERM_TYPE_RAW]                   = "raw",
@@ -817,6 +818,7 @@ config_term_avail(enum parse_events__term_type term_type, struct parse_events_er
 	case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
 	case PARSE_EVENTS__TERM_TYPE_DRV_CFG:
 	case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
+	case PARSE_EVENTS__TERM_TYPE_AUX_ACTION:
 	case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
 	case PARSE_EVENTS__TERM_TYPE_RAW:
 	case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE:
@@ -936,6 +938,9 @@ do {									   \
 	case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
 		CHECK_TYPE_VAL(NUM);
 		break;
+	case PARSE_EVENTS__TERM_TYPE_AUX_ACTION:
+		CHECK_TYPE_VAL(STR);
+		break;
 	case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
 		CHECK_TYPE_VAL(NUM);
 		if (term->val.num > UINT_MAX) {
@@ -1053,6 +1058,7 @@ static int config_term_tracepoint(struct perf_event_attr *attr,
 	case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
 	case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
 	case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
+	case PARSE_EVENTS__TERM_TYPE_AUX_ACTION:
 	case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
 		return config_term_common(attr, term, err);
 	case PARSE_EVENTS__TERM_TYPE_USER:
@@ -1187,6 +1193,9 @@ do {								\
 			ADD_CONFIG_TERM_VAL(AUX_OUTPUT, aux_output,
 					    term->val.num ? 1 : 0, term->weak);
 			break;
+		case PARSE_EVENTS__TERM_TYPE_AUX_ACTION:
+			ADD_CONFIG_TERM_STR(AUX_ACTION, term->val.str, term->weak);
+			break;
 		case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
 			ADD_CONFIG_TERM_VAL(AUX_SAMPLE_SIZE, aux_sample_size,
 					    term->val.num, term->weak);
@@ -1249,6 +1258,7 @@ static int get_config_chgs(struct perf_pmu *pmu, struct parse_events_terms *head
 		case PARSE_EVENTS__TERM_TYPE_DRV_CFG:
 		case PARSE_EVENTS__TERM_TYPE_PERCORE:
 		case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
+		case PARSE_EVENTS__TERM_TYPE_AUX_ACTION:
 		case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
 		case PARSE_EVENTS__TERM_TYPE_METRIC_ID:
 		case PARSE_EVENTS__TERM_TYPE_RAW:
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 809359e8544e..7e467ff71f19 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -74,6 +74,7 @@ enum parse_events__term_type {
 	PARSE_EVENTS__TERM_TYPE_DRV_CFG,
 	PARSE_EVENTS__TERM_TYPE_PERCORE,
 	PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT,
+	PARSE_EVENTS__TERM_TYPE_AUX_ACTION,
 	PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE,
 	PARSE_EVENTS__TERM_TYPE_METRIC_ID,
 	PARSE_EVENTS__TERM_TYPE_RAW,
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index e86c45675e1d..26a60ad5853c 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -244,6 +244,7 @@ overwrite		{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); }
 no-overwrite		{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); }
 percore			{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_PERCORE); }
 aux-output		{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT); }
+aux-action		{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_ACTION); }
 aux-sample-size		{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE); }
 metric-id		{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_METRIC_ID); }
 cpu-cycles|cycles				{ return hw_term(yyscanner, PERF_COUNT_HW_CPU_CYCLES); }
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:23 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:23 +0200
Subject: [PATCH V5 08/12] perf tools: Parse aux-action
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-9-adrian.hunter@intel.com>

Add parsing for aux-action to accept "pause", "resume" or "start-paused"
values.

"start-paused" is valid only for AUX area events.

"pause" and "resume" are valid only for events grouped with an AUX area
event as the group leader.  However, like with aux-output, the events
will be automatically grouped if they are not currently in a group, and
the AUX area event precedes the other events.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: Ian Rogers <irogers at google.com>
---
 tools/perf/Documentation/perf-record.txt |  4 ++
 tools/perf/builtin-record.c              |  4 +-
 tools/perf/util/auxtrace.c               | 67 ++++++++++++++++++++++--
 tools/perf/util/auxtrace.h               |  6 ++-
 tools/perf/util/evsel.c                  |  1 +
 5 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 6015fdd08fb6..ccdba551e52d 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -68,6 +68,10 @@ OPTIONS
 		    like this: name=\'CPU_CLK_UNHALTED.THREAD:cmask=0x1\'.
 	  - 'aux-output': Generate AUX records instead of events. This requires
 			  that an AUX area event is also provided.
+	  - 'aux-action': "pause" or "resume" to pause or resume an AUX
+			  area event (the group leader) when this event occurs.
+			  "start-paused" on an AUX area event itself, will
+			  start in a paused state.
 	  - 'aux-sample-size': Set sample size for AUX area sampling. If the
 	  '--aux-sample' option has been used, set aux-sample-size=0 to disable
 	  AUX area sampling for the event.
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index c310eaad56ce..684a2768cf18 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -850,7 +850,9 @@ static int record__auxtrace_init(struct record *rec)
 	if (err)
 		return err;
 
-	auxtrace_regroup_aux_output(rec->evlist);
+	err = auxtrace_parse_aux_action(rec->evlist);
+	if (err)
+		return err;
 
 	return auxtrace_parse_filters(rec->evlist);
 }
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 3684e6009b63..67bd33ea2eaf 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -805,19 +805,76 @@ int auxtrace_parse_sample_options(struct auxtrace_record *itr,
 	return auxtrace_validate_aux_sample_size(evlist, opts);
 }
 
-void auxtrace_regroup_aux_output(struct evlist *evlist)
+static struct aux_action_opt {
+	const char *str;
+	u32 aux_action;
+	bool aux_event_opt;
+} aux_action_opts[] = {
+	{"start-paused", BIT(0), true},
+	{"pause",        BIT(1), false},
+	{"resume",       BIT(2), false},
+	{NULL},
+};
+
+static const struct aux_action_opt *auxtrace_parse_aux_action_str(const char *str)
+{
+	const struct aux_action_opt *opt;
+
+	if (!str)
+		return NULL;
+
+	for (opt = aux_action_opts; opt->str; opt++)
+		if (!strcmp(str, opt->str))
+			return opt;
+
+	return NULL;
+}
+
+int auxtrace_parse_aux_action(struct evlist *evlist)
 {
-	struct evsel *evsel, *aux_evsel = NULL;
 	struct evsel_config_term *term;
+	struct evsel *aux_evsel = NULL;
+	struct evsel *evsel;
 
 	evlist__for_each_entry(evlist, evsel) {
-		if (evsel__is_aux_event(evsel))
+		bool is_aux_event = evsel__is_aux_event(evsel);
+		const struct aux_action_opt *opt;
+
+		if (is_aux_event)
 			aux_evsel = evsel;
-		term = evsel__get_config_term(evsel, AUX_OUTPUT);
+		term = evsel__get_config_term(evsel, AUX_ACTION);
+		if (!term) {
+			if (evsel__get_config_term(evsel, AUX_OUTPUT))
+				goto regroup;
+			continue;
+		}
+		opt = auxtrace_parse_aux_action_str(term->val.str);
+		if (!opt) {
+			pr_err("Bad aux-action '%s'\n", term->val.str);
+			return -EINVAL;
+		}
+		if (opt->aux_event_opt && !is_aux_event) {
+			pr_err("aux-action '%s' can only be used with AUX area event\n",
+			       term->val.str);
+			return -EINVAL;
+		}
+		if (!opt->aux_event_opt && is_aux_event) {
+			pr_err("aux-action '%s' cannot be used for AUX area event itself\n",
+			       term->val.str);
+			return -EINVAL;
+		}
+		evsel->core.attr.aux_action = opt->aux_action;
+regroup:
 		/* If possible, group with the AUX event */
-		if (term && aux_evsel)
+		if (aux_evsel)
 			evlist__regroup(evlist, aux_evsel, evsel);
+		if (!evsel__is_aux_event(evsel__leader(evsel))) {
+			pr_err("Events with aux-action must have AUX area event group leader\n");
+			return -EINVAL;
+		}
 	}
+
+	return 0;
 }
 
 struct auxtrace_record *__weak
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index 55702215a82d..35324ad12aad 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -579,7 +579,7 @@ int auxtrace_parse_snapshot_options(struct auxtrace_record *itr,
 int auxtrace_parse_sample_options(struct auxtrace_record *itr,
 				  struct evlist *evlist,
 				  struct record_opts *opts, const char *str);
-void auxtrace_regroup_aux_output(struct evlist *evlist);
+int auxtrace_parse_aux_action(struct evlist *evlist);
 int auxtrace_record__options(struct auxtrace_record *itr,
 			     struct evlist *evlist,
 			     struct record_opts *opts);
@@ -800,8 +800,10 @@ int auxtrace_parse_sample_options(struct auxtrace_record *itr __maybe_unused,
 }
 
 static inline
-void auxtrace_regroup_aux_output(struct evlist *evlist __maybe_unused)
+int auxtrace_parse_aux_action(struct evlist *evlist __maybe_unused)
 {
+	pr_err("AUX area tracing not supported\n");
+	return -EINVAL;
 }
 
 static inline
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 866c69f83595..8401685461bf 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1002,6 +1002,7 @@ static void evsel__apply_config_terms(struct evsel *evsel,
 			attr->aux_output = term->val.aux_output ? 1 : 0;
 			break;
 		case EVSEL__CONFIG_TERM_AUX_ACTION:
+			/* Already applied by auxtrace */
 			break;
 		case EVSEL__CONFIG_TERM_AUX_SAMPLE_SIZE:
 			/* Already applied by auxtrace */
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:24 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:24 +0200
Subject: [PATCH V5 09/12] perf tools: Add missing_features for aux_start_paused, aux_pause, aux_resume
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-10-adrian.hunter@intel.com>

Display "feature is not supported" error message if aux_start_paused,
aux_pause or aux_resume result in a perf_event_open() error.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/evsel.c | 10 +++++++++-
 tools/perf/util/evsel.h |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 8401685461bf..9d2fde919604 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1890,7 +1890,13 @@ bool evsel__detect_missing_features(struct evsel *evsel)
 	 * Must probe features in the order they were added to the
 	 * perf_event_attr interface.
 	 */
-	if (!perf_missing_features.branch_counters &&
+	if (!perf_missing_features.aux_pause_resume &&
+	    (evsel->core.attr.aux_pause || evsel->core.attr.aux_resume ||
+	     evsel->core.attr.aux_start_paused)) {
+		perf_missing_features.aux_pause_resume = true;
+		pr_debug2_peo("Kernel has no aux_pause/aux_resume support, bailing out\n");
+		return false;
+	} else if (!perf_missing_features.branch_counters &&
 	    (evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS)) {
 		perf_missing_features.branch_counters = true;
 		pr_debug2("switching off branch counters support\n");
@@ -3089,6 +3095,8 @@ int evsel__open_strerror(struct evsel *evsel, struct target *target,
 			return scnprintf(msg, size, "clockid feature not supported.");
 		if (perf_missing_features.clockid_wrong)
 			return scnprintf(msg, size, "wrong clockid (%d).", clockid);
+		if (perf_missing_features.aux_pause_resume)
+			return scnprintf(msg, size, "The 'aux_pause / aux_resume' feature is not supported, update the kernel.");
 		if (perf_missing_features.aux_output)
 			return scnprintf(msg, size, "The 'aux_output' feature is not supported, update the kernel.");
 		if (!target__has_cpu(target))
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 517cff431de2..8ef5a6fdbd45 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -192,6 +192,7 @@ struct perf_missing_features {
 	bool weight_struct;
 	bool read_lost;
 	bool branch_counters;
+	bool aux_pause_resume;
 };
 
 extern struct perf_missing_features perf_missing_features;
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:25 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:25 +0200
Subject: [PATCH V5 10/12] perf intel-pt: Improve man page format
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-11-adrian.hunter@intel.com>

Improve format of config terms and section references.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: Ian Rogers <irogers at google.com>
---
 tools/perf/Documentation/perf-intel-pt.txt | 486 +++++++++++----------
 1 file changed, 267 insertions(+), 219 deletions(-)

diff --git a/tools/perf/Documentation/perf-intel-pt.txt b/tools/perf/Documentation/perf-intel-pt.txt
index 2109690b0d5f..b5fa7c7ad7f5 100644
--- a/tools/perf/Documentation/perf-intel-pt.txt
+++ b/tools/perf/Documentation/perf-intel-pt.txt
@@ -147,7 +147,7 @@ displayed as follows:
 There are two ways that instructions-per-cycle (IPC) can be calculated depending
 on the recording.
 
-If the 'cyc' config term (see config terms section below) was used, then IPC
+If the 'cyc' config term (see <<_config_terms,config terms>> section below) was used, then IPC
 and cycle events are calculated using the cycle count from CYC packets, otherwise
 MTC packets are used - refer to the 'mtc' config term.  When MTC is used, however,
 the values are less accurate because the timing is less accurate.
@@ -235,7 +235,7 @@ which is the same as
 
 	-e intel_pt/tsc=1,noretcomp=0/
 
-Note there are now new config terms - see section 'config terms' further below.
+Note there are other config terms - see section <<_config_terms,config terms>> further below.
 
 The config terms are listed in /sys/devices/intel_pt/format.  They are bit
 fields within the config member of the struct perf_event_attr which is
@@ -307,217 +307,264 @@ perf_event_attr is displayed if the -vv option is used e.g.
 config terms
 ~~~~~~~~~~~~
 
-The June 2015 version of Intel 64 and IA-32 Architectures Software Developer
-Manuals, Chapter 36 Intel Processor Trace, defined new Intel PT features.
-Some of the features are reflect in new config terms.  All the config terms are
-described below.
-
-tsc		Always supported.  Produces TSC timestamp packets to provide
-		timing information.  In some cases it is possible to decode
-		without timing information, for example a per-thread context
-		that does not overlap executable memory maps.
-
-		The default config selects tsc (i.e. tsc=1).
-
-noretcomp	Always supported.  Disables "return compression" so a TIP packet
-		is produced when a function returns.  Causes more packets to be
-		produced but might make decoding more reliable.
-
-		The default config does not select noretcomp (i.e. noretcomp=0).
-
-psb_period	Allows the frequency of PSB packets to be specified.
-
-		The PSB packet is a synchronization packet that provides a
-		starting point for decoding or recovery from errors.
-
-		Support for psb_period is indicated by:
-
-			/sys/bus/event_source/devices/intel_pt/caps/psb_cyc
-
-		which contains "1" if the feature is supported and "0"
-		otherwise.
-
-		Valid values are given by:
-
-			/sys/bus/event_source/devices/intel_pt/caps/psb_periods
-
-		which contains a hexadecimal value, the bits of which represent
-		valid values e.g. bit 2 set means value 2 is valid.
-
-		The psb_period value is converted to the approximate number of
-		trace bytes between PSB packets as:
-
-			2 ^ (value + 11)
-
-		e.g. value 3 means 16KiB bytes between PSBs
-
-		If an invalid value is entered, the error message
-		will give a list of valid values e.g.
-
-			$ perf record -e intel_pt/psb_period=15/u uname
-			Invalid psb_period for intel_pt. Valid values are: 0-5
-
-		If MTC packets are selected, the default config selects a value
-		of 3 (i.e. psb_period=3) or the nearest lower value that is
-		supported (0 is always supported).  Otherwise the default is 0.
-
-		If decoding is expected to be reliable and the buffer is large
-		then a large PSB period can be used.
-
-		Because a TSC packet is produced with PSB, the PSB period can
-		also affect the granularity to timing information in the absence
-		of MTC or CYC.
-
-mtc		Produces MTC timing packets.
-
-		MTC packets provide finer grain timestamp information than TSC
-		packets.  MTC packets record time using the hardware crystal
-		clock (CTC) which is related to TSC packets using a TMA packet.
-
-		Support for this feature is indicated by:
-
-			/sys/bus/event_source/devices/intel_pt/caps/mtc
-
-		which contains "1" if the feature is supported and
-		"0" otherwise.
-
-		The frequency of MTC packets can also be specified - see
-		mtc_period below.
-
-mtc_period	Specifies how frequently MTC packets are produced - see mtc
-		above for how to determine if MTC packets are supported.
-
-		Valid values are given by:
-
-			/sys/bus/event_source/devices/intel_pt/caps/mtc_periods
-
-		which contains a hexadecimal value, the bits of which represent
-		valid values e.g. bit 2 set means value 2 is valid.
-
-		The mtc_period value is converted to the MTC frequency as:
-
-			CTC-frequency / (2 ^ value)
-
-		e.g. value 3 means one eighth of CTC-frequency
-
-		Where CTC is the hardware crystal clock, the frequency of which
-		can be related to TSC via values provided in cpuid leaf 0x15.
-
-		If an invalid value is entered, the error message
-		will give a list of valid values e.g.
-
-			$ perf record -e intel_pt/mtc_period=15/u uname
-			Invalid mtc_period for intel_pt. Valid values are: 0,3,6,9
-
-		The default value is 3 or the nearest lower value
-		that is supported (0 is always supported).
-
-cyc		Produces CYC timing packets.
-
-		CYC packets provide even finer grain timestamp information than
-		MTC and TSC packets.  A CYC packet contains the number of CPU
-		cycles since the last CYC packet. Unlike MTC and TSC packets,
-		CYC packets are only sent when another packet is also sent.
-
-		Support for this feature is indicated by:
-
-			/sys/bus/event_source/devices/intel_pt/caps/psb_cyc
-
-		which contains "1" if the feature is supported and
-		"0" otherwise.
-
-		The number of CYC packets produced can be reduced by specifying
-		a threshold - see cyc_thresh below.
-
-cyc_thresh	Specifies how frequently CYC packets are produced - see cyc
-		above for how to determine if CYC packets are supported.
-
-		Valid cyc_thresh values are given by:
-
-			/sys/bus/event_source/devices/intel_pt/caps/cycle_thresholds
-
-		which contains a hexadecimal value, the bits of which represent
-		valid values e.g. bit 2 set means value 2 is valid.
-
-		The cyc_thresh value represents the minimum number of CPU cycles
-		that must have passed before a CYC packet can be sent.  The
-		number of CPU cycles is:
-
-			2 ^ (value - 1)
-
-		e.g. value 4 means 8 CPU cycles must pass before a CYC packet
-		can be sent.  Note a CYC packet is still only sent when another
-		packet is sent, not at, e.g. every 8 CPU cycles.
-
-		If an invalid value is entered, the error message
-		will give a list of valid values e.g.
-
-			$ perf record -e intel_pt/cyc,cyc_thresh=15/u uname
-			Invalid cyc_thresh for intel_pt. Valid values are: 0-12
-
-		CYC packets are not requested by default.
-
-pt		Specifies pass-through which enables the 'branch' config term.
-
-		The default config selects 'pt' if it is available, so a user will
-		never need to specify this term.
-
-branch		Enable branch tracing.  Branch tracing is enabled by default so to
-		disable branch tracing use 'branch=0'.
-
-		The default config selects 'branch' if it is available.
-
-ptw		Enable PTWRITE packets which are produced when a ptwrite instruction
-		is executed.
-
-		Support for this feature is indicated by:
-
-			/sys/bus/event_source/devices/intel_pt/caps/ptwrite
-
-		which contains "1" if the feature is supported and
-		"0" otherwise.
-
-		As an alternative, refer to "Emulated PTWRITE" further below.
-
-fup_on_ptw	Enable a FUP packet to follow the PTWRITE packet.  The FUP packet
-		provides the address of the ptwrite instruction.  In the absence of
-		fup_on_ptw, the decoder will use the address of the previous branch
-		if branch tracing is enabled, otherwise the address will be zero.
-		Note that fup_on_ptw will work even when branch tracing is disabled.
-
-pwr_evt		Enable power events.  The power events provide information about
-		changes to the CPU C-state.
-
-		Support for this feature is indicated by:
-
-			/sys/bus/event_source/devices/intel_pt/caps/power_event_trace
-
-		which contains "1" if the feature is supported and
-		"0" otherwise.
-
-event		Enable Event Trace.  The events provide information about asynchronous
-		events.
-
-		Support for this feature is indicated by:
-
-			/sys/bus/event_source/devices/intel_pt/caps/event_trace
-
-		which contains "1" if the feature is supported and
-		"0" otherwise.
-
-notnt		Disable TNT packets.  Without TNT packets, it is not possible to walk
-		executable code to reconstruct control flow, however FUP, TIP, TIP.PGE
-		and TIP.PGD packets still indicate asynchronous control flow, and (if
-		return compression is disabled - see noretcomp) return statements.
-		The advantage of eliminating TNT packets is reducing the size of the
-		trace and corresponding tracing overhead.
-
-		Support for this feature is indicated by:
-
-			/sys/bus/event_source/devices/intel_pt/caps/tnt_disable
-
-		which contains "1" if the feature is supported and
-		"0" otherwise.
+Config terms are parameters specified with the -e intel_pt// event option,
+for example:
+
+	-e intel_pt/cyc/
+
+which selects cycle accurate mode. Each config term can have a value which
+defaults to 1, so the above is the same as:
+
+	-e intel_pt/cyc=1/
+
+Some terms are set by default, so must be set to 0 to turn them off. For
+example, to turn off branch tracing:
+
+	-e intel_pt/branch=0/
+
+Multiple config terms are separated by commas, for example:
+
+	-e intel_pt/cyc,mtc_period=9/
+
+There are also common config terms, see linkperf:perf-record[1] documentation.
+
+Intel PT config terms are described below.
+
+*tsc*::
+Always supported.  Produces TSC timestamp packets to provide
+timing information.  In some cases it is possible to decode
+without timing information, for example a per-thread context
+that does not overlap executable memory maps.
++
+The default config selects tsc (i.e. tsc=1).
+
+*noretcomp*::
+Always supported.  Disables "return compression" so a TIP packet
+is produced when a function returns.  Causes more packets to be
+produced but might make decoding more reliable.
++
+The default config does not select noretcomp (i.e. noretcomp=0).
+
+*psb_period*::
+Allows the frequency of PSB packets to be specified.
++
+The PSB packet is a synchronization packet that provides a
+starting point for decoding or recovery from errors.
++
+Support for psb_period is indicated by:
++
+	/sys/bus/event_source/devices/intel_pt/caps/psb_cyc
++
+which contains "1" if the feature is supported and "0"
+otherwise.
++
+Valid values are given by:
++
+	/sys/bus/event_source/devices/intel_pt/caps/psb_periods
++
+which contains a hexadecimal value, the bits of which represent
+valid values e.g. bit 2 set means value 2 is valid.
++
+The psb_period value is converted to the approximate number of
+trace bytes between PSB packets as:
++
+	2 ^ (value + 11)
++
+e.g. value 3 means 16KiB bytes between PSBs
++
+If an invalid value is entered, the error message
+will give a list of valid values e.g.
++
+	$ perf record -e intel_pt/psb_period=15/u uname
+	Invalid psb_period for intel_pt. Valid values are: 0-5
++
+If MTC packets are selected, the default config selects a value
+of 3 (i.e. psb_period=3) or the nearest lower value that is
+supported (0 is always supported).  Otherwise the default is 0.
++
+If decoding is expected to be reliable and the buffer is large
+then a large PSB period can be used.
++
+Because a TSC packet is produced with PSB, the PSB period can
+also affect the granularity to timing information in the absence
+of MTC or CYC.
+
+*mtc*::
+Produces MTC timing packets.
++
+MTC packets provide finer grain timestamp information than TSC
+packets.  MTC packets record time using the hardware crystal
+clock (CTC) which is related to TSC packets using a TMA packet.
++
+Support for this feature is indicated by:
++
+	/sys/bus/event_source/devices/intel_pt/caps/mtc
++
+which contains "1" if the feature is supported and
+"0" otherwise.
++
+The frequency of MTC packets can also be specified - see
+mtc_period below.
+
+*mtc_period*::
+Specifies how frequently MTC packets are produced - see mtc
+above for how to determine if MTC packets are supported.
++
+Valid values are given by:
++
+	/sys/bus/event_source/devices/intel_pt/caps/mtc_periods
++
+which contains a hexadecimal value, the bits of which represent
+valid values e.g. bit 2 set means value 2 is valid.
++
+The mtc_period value is converted to the MTC frequency as:
+
+	CTC-frequency / (2 ^ value)
++
+e.g. value 3 means one eighth of CTC-frequency
++
+Where CTC is the hardware crystal clock, the frequency of which
+can be related to TSC via values provided in cpuid leaf 0x15.
++
+If an invalid value is entered, the error message
+will give a list of valid values e.g.
++
+	$ perf record -e intel_pt/mtc_period=15/u uname
+	Invalid mtc_period for intel_pt. Valid values are: 0,3,6,9
++
+The default value is 3 or the nearest lower value
+that is supported (0 is always supported).
+
+*cyc*::
+Produces CYC timing packets.
++
+CYC packets provide even finer grain timestamp information than
+MTC and TSC packets.  A CYC packet contains the number of CPU
+cycles since the last CYC packet. Unlike MTC and TSC packets,
+CYC packets are only sent when another packet is also sent.
++
+Support for this feature is indicated by:
++
+	/sys/bus/event_source/devices/intel_pt/caps/psb_cyc
++
+which contains "1" if the feature is supported and
+"0" otherwise.
++
+The number of CYC packets produced can be reduced by specifying
+a threshold - see cyc_thresh below.
+
+*cyc_thresh*::
+Specifies how frequently CYC packets are produced - see cyc
+above for how to determine if CYC packets are supported.
++
+Valid cyc_thresh values are given by:
++
+	/sys/bus/event_source/devices/intel_pt/caps/cycle_thresholds
++
+which contains a hexadecimal value, the bits of which represent
+valid values e.g. bit 2 set means value 2 is valid.
++
+The cyc_thresh value represents the minimum number of CPU cycles
+that must have passed before a CYC packet can be sent.  The
+number of CPU cycles is:
++
+	2 ^ (value - 1)
++
+e.g. value 4 means 8 CPU cycles must pass before a CYC packet
+can be sent.  Note a CYC packet is still only sent when another
+packet is sent, not at, e.g. every 8 CPU cycles.
++
+If an invalid value is entered, the error message
+will give a list of valid values e.g.
++
+	$ perf record -e intel_pt/cyc,cyc_thresh=15/u uname
+	Invalid cyc_thresh for intel_pt. Valid values are: 0-12
++
+CYC packets are not requested by default.
+
+*pt*::
+Specifies pass-through which enables the 'branch' config term.
++
+The default config selects 'pt' if it is available, so a user will
+never need to specify this term.
+
+*branch*::
+Enable branch tracing.  Branch tracing is enabled by default so to
+disable branch tracing use 'branch=0'.
++
+The default config selects 'branch' if it is available.
+
+*ptw*::
+Enable PTWRITE packets which are produced when a ptwrite instruction
+is executed.
++
+Support for this feature is indicated by:
++
+	/sys/bus/event_source/devices/intel_pt/caps/ptwrite
++
+which contains "1" if the feature is supported and
+"0" otherwise.
++
+As an alternative, refer to "Emulated PTWRITE" further below.
+
+*fup_on_ptw*::
+Enable a FUP packet to follow the PTWRITE packet.  The FUP packet
+provides the address of the ptwrite instruction.  In the absence of
+fup_on_ptw, the decoder will use the address of the previous branch
+if branch tracing is enabled, otherwise the address will be zero.
+Note that fup_on_ptw will work even when branch tracing is disabled.
+
+*pwr_evt*::
+Enable power events.  The power events provide information about
+changes to the CPU C-state.
++
+Support for this feature is indicated by:
++
+	/sys/bus/event_source/devices/intel_pt/caps/power_event_trace
++
+which contains "1" if the feature is supported and
+"0" otherwise.
+
+*event*::
+Enable Event Trace.  The events provide information about asynchronous
+events.
++
+Support for this feature is indicated by:
++
+	/sys/bus/event_source/devices/intel_pt/caps/event_trace
++
+which contains "1" if the feature is supported and
+"0" otherwise.
+
+*notnt*::
+Disable TNT packets.  Without TNT packets, it is not possible to walk
+executable code to reconstruct control flow, however FUP, TIP, TIP.PGE
+and TIP.PGD packets still indicate asynchronous control flow, and (if
+return compression is disabled - see noretcomp) return statements.
+The advantage of eliminating TNT packets is reducing the size of the
+trace and corresponding tracing overhead.
++
+Support for this feature is indicated by:
++
+	/sys/bus/event_source/devices/intel_pt/caps/tnt_disable
++
+which contains "1" if the feature is supported and
+"0" otherwise.
+
+
+config terms on other events
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some Intel PT features work with other events, features such as AUX area sampling
+and PEBS-via-PT.  In those cases, the other events can have config terms below:
+
+*aux-sample-size*::
+		Used to set the AUX area sample size, refer to the section
+		<<_aux_area_sampling_option,AUX area sampling option>>
+
+*aux-output*::
+		Used to select PEBS-via-PT, refer to the
+		section <<_pebs_via_intel_pt,PEBS via Intel PT>>
 
 
 AUX area sampling option
@@ -592,7 +639,8 @@ The default snapshot size is the auxtrace mmap size.  If neither auxtrace mmap s
 nor snapshot size is specified, then the default is 4MiB for privileged users
 (or if /proc/sys/kernel/perf_event_paranoid < 0), 128KiB for unprivileged users.
 If an unprivileged user does not specify mmap pages, the mmap pages will be
-reduced as described in the 'new auxtrace mmap size option' section below.
+reduced as described in the <<_new_auxtrace_mmap_size_option,new auxtrace mmap size option>>
+section below.
 
 The snapshot size is displayed if the option -vv is used e.g.
 
@@ -948,11 +996,11 @@ transaction start, commit or abort.
 
 Note that "instructions", "cycles", "branches" and "transactions" events
 depend on code flow packets which can be disabled by using the config term
-"branch=0".  Refer to the config terms section above.
+"branch=0".  Refer to the <<_config_terms,config terms>> section above.
 
 "ptwrite" events record the payload of the ptwrite instruction and whether
 "fup_on_ptw" was used.  "ptwrite" events depend on PTWRITE packets which are
-recorded only if the "ptw" config term was used.  Refer to the config terms
+recorded only if the "ptw" config term was used.  Refer to the <<_config_terms,config terms>>
 section above.  perf script "synth" field displays "ptwrite" information like
 this: "ip: 0 payload: 0x123456789abcdef0"  where "ip" is 1 if "fup_on_ptw" was
 used.
@@ -960,7 +1008,7 @@ used.
 "Power" events correspond to power event packets and CBR (core-to-bus ratio)
 packets.  While CBR packets are always recorded when tracing is enabled, power
 event packets are recorded only if the "pwr_evt" config term was used.  Refer to
-the config terms section above.  The power events record information about
+the <<_config_terms,config terms>> section above.  The power events record information about
 C-state changes, whereas CBR is indicative of CPU frequency.  perf script
 "event,synth" fields display information like this:
 
@@ -1116,7 +1164,7 @@ What *will* be decoded with the (single) q option:
 	- asynchronous branches such as interrupts
 	- indirect branches
 	- function return target address *if* the noretcomp config term (refer
-	config terms section) was used
+	<<_config_terms,config terms>> section) was used
 	- start of (control-flow) tracing
 	- end of (control-flow) tracing, if it is not out of context
 	- power events, ptwrite, transaction start and abort
@@ -1129,7 +1177,7 @@ Repeating the q option (double-q i.e. qq) results in even faster decoding and ev
 less detail.  The decoder decodes only extended PSB (PSB+) packets, getting the
 instruction pointer if there is a FUP packet within PSB+ (i.e. between PSB and
 PSBEND).  Note PSB packets occur regularly in the trace based on the psb_period
-config term (refer config terms section).  There will be a FUP packet if the
+config term (refer <<_config_terms,config terms>> section).  There will be a FUP packet if the
 PSB+ occurs while control flow is being traced.
 
 What will *not* be decoded with the qq option:
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:26 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:26 +0200
Subject: [PATCH V5 11/12] perf intel-pt: Add documentation for pause / resume
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-12-adrian.hunter@intel.com>

Document the use of aux-action config term and provide a simple example.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: Ian Rogers <irogers at google.com>
---


Changes in V5:
	Added more examples


 tools/perf/Documentation/perf-intel-pt.txt | 108 +++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/tools/perf/Documentation/perf-intel-pt.txt b/tools/perf/Documentation/perf-intel-pt.txt
index b5fa7c7ad7f5..c86deae170e4 100644
--- a/tools/perf/Documentation/perf-intel-pt.txt
+++ b/tools/perf/Documentation/perf-intel-pt.txt
@@ -551,6 +551,9 @@ Support for this feature is indicated by:
 which contains "1" if the feature is supported and
 "0" otherwise.
 
+*aux-action=start-paused*::
+Start tracing paused, refer to the section <<_pause_or_resume_tracing,Pause or Resume Tracing>>
+
 
 config terms on other events
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -566,6 +569,9 @@ and PEBS-via-PT.  In those cases, the other events can have config terms below:
 		Used to select PEBS-via-PT, refer to the
 		section <<_pebs_via_intel_pt,PEBS via Intel PT>>
 
+*aux-action*::
+		Used to pause or resume tracing, refer to the section
+		<<_pause_or_resume_tracing,Pause or Resume Tracing>>
 
 AUX area sampling option
 ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1911,6 +1917,108 @@ For pipe mode, the order of events and timestamps can presumably
 be messed up.
 
 
+Pause or Resume Tracing
+-----------------------
+
+With newer Kernels, it is possible to use other selected events to pause
+or resume Intel PT tracing.  This is configured by using the "aux-action"
+config term:
+
+"aux-action=pause" is used with events that are to pause Intel PT tracing.
+
+"aux-action=resume" is used with events that are to resume Intel PT tracing.
+
+"aux-action=start-paused" is used with the Intel PT event to start in a
+paused state.
+
+For example, to trace only the uname system call (sys_newuname) when running the
+command line utility uname:
+
+ $ perf record --kcore -e intel_pt/aux-action=start-paused/k,syscalls:sys_enter_newuname/aux-action=resume/,syscalls:sys_exit_newuname/aux-action=pause/ uname
+ Linux
+ [ perf record: Woken up 1 times to write data ]
+ [ perf record: Captured and wrote 0.043 MB perf.data ]
+ $ perf script --call-trace
+ uname   30805 [000] 24001.058782799: name: 0x7ffc9c1865b0
+ uname   30805 [000] 24001.058784424:  psb offs: 0
+ uname   30805 [000] 24001.058784424:  cbr: 39 freq: 3904 MHz (139%)
+ uname   30805 [000] 24001.058784629: ([kernel.kallsyms])        debug_smp_processor_id
+ uname   30805 [000] 24001.058784629: ([kernel.kallsyms])        __x64_sys_newuname
+ uname   30805 [000] 24001.058784629: ([kernel.kallsyms])            down_read
+ uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                __cond_resched
+ uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                preempt_count_add
+ uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                    in_lock_functions
+ uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                preempt_count_sub
+ uname   30805 [000] 24001.058784629: ([kernel.kallsyms])            up_read
+ uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                preempt_count_add
+ uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                    in_lock_functions
+ uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                preempt_count_sub
+ uname   30805 [000] 24001.058784838: ([kernel.kallsyms])            _copy_to_user
+ uname   30805 [000] 24001.058784838: ([kernel.kallsyms])        syscall_exit_to_user_mode
+ uname   30805 [000] 24001.058784838: ([kernel.kallsyms])            syscall_exit_work
+ uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                perf_syscall_exit
+ uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                    debug_smp_processor_id
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                    perf_trace_buf_alloc
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        perf_swevent_get_recursion_context
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            debug_smp_processor_id
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        debug_smp_processor_id
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                    perf_tp_event
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        perf_trace_buf_update
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            tracing_gen_ctx_irq_test
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        perf_swevent_event
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            __perf_event_account_interrupt
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                __this_cpu_preempt_check
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            perf_event_output_forward
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                perf_event_aux_pause
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                    ring_buffer_get
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                        __rcu_read_lock
+ uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                        __rcu_read_unlock
+ uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                    pt_event_stop
+ uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                        debug_smp_processor_id
+ uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                        debug_smp_processor_id
+ uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                        native_write_msr
+ uname   30805 [000] 24001.058785463: ([kernel.kallsyms])                                        native_write_msr
+ uname   30805 [000] 24001.058785639: 0x0
+
+The example above uses tracepoints, but any kind of sampled event can be used.
+
+For example:
+
+ Tracing between arch_cpu_idle_enter() and arch_cpu_idle_exit() using breakpoint events:
+
+ $ sudo cat /proc/kallsyms | sort | grep ' arch_cpu_idle_enter\| arch_cpu_idle_exit'
+ ffffffffb605bf60 T arch_cpu_idle_enter
+ ffffffffb614d8a0 W arch_cpu_idle_exit
+ $ sudo perf record --kcore -a -e intel_pt/aux-action=start-paused/k -e mem:0xffffffffb605bf60:x/aux-action=resume/ -e mem:0xffffffffb614d8a0:x/aux-action=pause/ -- sleep 1
+ [ perf record: Woken up 1 times to write data ]
+ [ perf record: Captured and wrote 1.387 MB perf.data ]
+
+ Tracing __alloc_pages() using kprobes:
+
+ $ sudo perf probe --add '__alloc_pages order'
+ Added new event:  probe:__alloc_pages  (on __alloc_pages with order)
+ $ sudo perf probe --add __alloc_pages%return
+ Added new event:  probe:__alloc_pages__return (on __alloc_pages%return)
+ $ sudo perf record --kcore -aR -e intel_pt/aux-action=start-paused/k -e probe:__alloc_pages/aux-action=resume/ -e probe:__alloc_pages__return/aux-action=pause/ -- sleep 1
+ [ perf record: Woken up 1 times to write data ]
+ [ perf record: Captured and wrote 1.490 MB perf.data ]
+
+ Tracing starting at main() using a uprobe event:
+
+ $ sudo perf probe -x /usr/bin/uname main
+ Added new event:  probe_uname:main     (on main in /usr/bin/uname)
+ $ sudo perf record -e intel_pt/-aux-action=start-paused/u -e probe_uname:main/aux-action=resume/ -- uname
+ Linux
+ [ perf record: Woken up 1 times to write data ]
+ [ perf record: Captured and wrote 0.031 MB perf.data ]
+
+ Tracing occassionally using cycles events with different periods:
+
+ $ perf record --kcore -a -m,64M -e intel_pt/aux-action=start-paused/k -e cycles/aux-action=pause,period=1000000/Pk -e cycles/aux-action=resume,period=10500000/Pk -- firefox
+ [ perf record: Woken up 19 times to write data ]
+ [ perf record: Captured and wrote 16.561 MB perf.data ]
+
+
 EXAMPLE
 -------
 
-- 
2.34.1



From adrian.hunter at intel.com  Thu Feb  8 03:31:27 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu,  8 Feb 2024 13:31:27 +0200
Subject: [PATCH V5 12/12] perf intel-pt: Add a test for pause / resume
In-Reply-To: <20240208113127.22216-1-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
Message-ID: <20240208113127.22216-13-adrian.hunter@intel.com>

Add a simple sub-test to the "Miscellaneous Intel PT testing" test to
check pause / resume.

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/shell/test_intel_pt.sh | 28 +++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh
index 723ec501f99a..e359db0d0ff2 100755
--- a/tools/perf/tests/shell/test_intel_pt.sh
+++ b/tools/perf/tests/shell/test_intel_pt.sh
@@ -644,6 +644,33 @@ test_pipe()
 	return 0
 }
 
+test_pause_resume()
+{
+	echo "--- Test with pause / resume ---"
+	if ! perf_record_no_decode -o "${perfdatafile}" -e intel_pt/aux-action=start-paused/u uname ; then
+		echo "SKIP: pause / resume is not supported"
+		return 2
+	fi
+	if ! perf_record_no_bpf -o "${perfdatafile}" \
+			-e intel_pt/aux-action=start-paused/u \
+			-e instructions/period=50000,aux-action=resume,name=Resume/u \
+			-e instructions/period=100000,aux-action=pause,name=Pause/u uname  ; then
+		echo "perf record with pause / resume failed"
+		return 1
+	fi
+	if ! perf script -i "${perfdatafile}" --itrace=b -Fperiod,event | \
+			awk 'BEGIN {paused=1;branches=0}
+			     /Resume/ {paused=0}
+			     /branches/ {if (paused) exit 1;branches=1}
+			     /Pause/ {paused=1}
+			     END {if (!branches) exit 1}' ; then
+		echo "perf record with pause / resume failed"
+		return 1
+	fi
+	echo OK
+	return 0
+}
+
 count_result()
 {
 	if [ "$1" -eq 2 ] ; then
@@ -672,6 +699,7 @@ test_power_event			|| ret=$? ; count_result $ret ; ret=0
 test_no_tnt				|| ret=$? ; count_result $ret ; ret=0
 test_event_trace			|| ret=$? ; count_result $ret ; ret=0
 test_pipe				|| ret=$? ; count_result $ret ; ret=0
+test_pause_resume			|| ret=$? ; count_result $ret ; ret=0
 
 cleanup
 
-- 
2.34.1



From catalin.marinas at arm.com  Thu Feb  8 03:40:39 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 11:40:39 +0000
Subject: [PATCH v4 01/10] arm64: Add macro to compose a sysreg field value
In-Reply-To: <20240122181344.258974-2-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
 <20240122181344.258974-2-maz@kernel.org>
Message-ID: <ZcS9t1IvSnGSN4tM@arm.com>

On Mon, Jan 22, 2024 at 06:13:35PM +0000, Marc Zyngier wrote:
> A common idiom is to compose a tupple (reg, field, val) into
> a symbol matching an autogenerated definition.
> 
> Add a help performing the concatenation and replace it when
> open-coded implementations exist.
> 
> Suggested-by: Oliver Upton <oliver.upton at linux.dev>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From adrian.hunter at intel.com  Thu Feb  8 03:40:57 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu, 8 Feb 2024 13:40:57 +0200
Subject: [PATCH V4 00/11] perf/core: Add ability for an event to "pause"
 or "resume" AUX area tracing
In-Reply-To: <a4c616ff-12bf-592b-b74d-407013a68cb7@arm.com>
References: <20240111081914.3123-1-adrian.hunter@intel.com>
 <31bae596-ecb1-4b9c-9f1c-aaec4bcefd38@intel.com>
 <CAP-5=fUo96EABpH6=7i2cXFmZhAB2MM=UsnG-+vL4HJtLGS=bA@mail.gmail.com>
 <a4c616ff-12bf-592b-b74d-407013a68cb7@arm.com>
Message-ID: <86490ec4-423e-4a7d-881b-56c47b3320ce@intel.com>

On 1/02/24 18:29, James Clark wrote:
> 
> 
> On 31/01/2024 16:53, Ian Rogers wrote:
>> On Mon, Jan 29, 2024 at 4:49?AM Adrian Hunter <adrian.hunter at intel.com> wrote:
>>>
>>> On 11/01/24 10:19, Adrian Hunter wrote:
>>>> Hi
>>>>
>>>> Hardware traces, such as instruction traces, can produce a vast amount of
>>>> trace data, so being able to reduce tracing to more specific circumstances
>>>> can be useful.
>>>>
>>>> The ability to pause or resume tracing when another event happens, can do
>>>> that.
>>>>
>>>> These patches add such a facilty and show how it would work for Intel
>>>> Processor Trace.
>>>>
>>>> Maintainers of other AUX area tracing implementations are requested to
>>>> consider if this is something they might employ and then whether or not
>>>> the ABI would work for them.
>>>>
>>>> Changes to perf tools are now (since V4) fleshed out.
>>>>
>>>>
>>>> Changes in V4:
>>>>
>>>>     perf/core: Add aux_pause, aux_resume, aux_start_paused
>>>>       Rename aux_output_cfg -> aux_action
>>>>       Reorder aux_action bits from:
>>>>               aux_pause, aux_resume, aux_start_paused
>>>>       to:
>>>>               aux_start_paused, aux_pause, aux_resume
>>>>       Fix aux_action bits __u64 -> __u32
>>>>
>>>>     coresight: Have a stab at support for pause / resume
>>>>       Dropped
>>>>
>>>>     perf tools
>>>>       All new patches
>>>>
>>>> Changes in RFC V3:
>>>>
>>>>     coresight: Have a stab at support for pause / resume
>>>>       'mode' -> 'flags' so it at least compiles
>>>>
>>>> Changes in RFC V2:
>>>>
>>>>       Use ->stop() / ->start() instead of ->pause_resume()
>>>>       Move aux_start_paused bit into aux_output_cfg
>>>>       Tighten up when Intel PT pause / resume is allowed
>>>>       Add an example of how it might work for CoreSight
>>>
>>> Any more comments?
>>
>> I think the tools side looks good. The parsing changes match the
>> existing style. I wonder if it wouldn't be better to handle the valid
>> strings (pause, resume, etc.) in the lexer rather than a separate
>> parse function, but the pattern used matches the existing one. You can
>> have my Acked-by on the tools changes, although the subtleties of ARM
>> PMUs makes me somewhat nervous in this regard.
>>
>> Thanks,
>> Ian
> 
> Acked-by: James Clark <james.clark at arm.com>
> 
> I will get round to adding the Coresight support at some point. I
> checked the new parsing in this version and it seems to work ok.

Thanks James and Ian!


From rogerq at kernel.org  Thu Feb  8 03:52:29 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 8 Feb 2024 13:52:29 +0200
Subject: [PATCH net] net: ti: icssg-prueth: Remove duplicate cleanup calls
 in emac_ndo_stop()
In-Reply-To: <20240206152052.98217-1-diogo.ivo@siemens.com>
References: <20240206152052.98217-1-diogo.ivo@siemens.com>
Message-ID: <a6187f1a-41f7-45df-a700-5e840d0d5d9f@kernel.org>



On 06/02/2024 17:20, Diogo Ivo wrote:
> Remove the duplicate calls to prueth_emac_stop() and
> prueth_cleanup_tx_chns() in emac_ndo_stop().
> 
> Fixes: 128d5874c082 ("net: ti: icssg-prueth: Add ICSSG ethernet driver")
> Fixes: 186734c15886 ("net: ti: icssg-prueth: add packet timestamping and ptp support")
> Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>

Reviewed-by: Roger Quadros <rogerq at kernel.org>


From cristian.ciocaltea at collabora.com  Thu Feb  8 03:56:30 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Thu, 8 Feb 2024 13:56:30 +0200
Subject: [PATCH v2 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <2670318.X9hSmTKtgW@diego>
References: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
 <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>
 <2670318.X9hSmTKtgW@diego>
Message-ID: <a15ce51b-5778-4978-946a-4b8350205c08@collabora.com>

On 2/8/24 10:00, Heiko St?bner wrote:
> Am Montag, 5. Februar 2024, 12:24:25 CET schrieb Cristian Ciocaltea:
>> Add driver for the HDMI/eDP TX Combo PHY found on Rockchip RK3588 SoC.
>>
>> The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
>> and eDP links.  The maximum data rate is 12Gbps (FRL), while the minimum
>> is 250Mbps (TMDS).
>>
>> Only the TMDS link is currently supported.
>>
>> Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
>> Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> 
> on a rk3588-jaguar
> Tested-by: Heiko Stuebner <heiko at sntech.de>

Thanks for testing this!  Will send v3 soon.

Regards,
Cristian


From rogerq at kernel.org  Thu Feb  8 04:04:49 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 8 Feb 2024 14:04:49 +0200
Subject: [PATCH v4 1/3] arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
In-Reply-To: <20240205090546.4000446-2-danishanwar@ti.com>
References: <20240205090546.4000446-1-danishanwar@ti.com>
 <20240205090546.4000446-2-danishanwar@ti.com>
Message-ID: <ce5cc093-be51-419b-9560-541bde00e2c1@kernel.org>



On 05/02/2024 11:05, MD Danish Anwar wrote:
> From: Suman Anna <s-anna at ti.com>
> 
> The ICSSG IP on AM64x SoCs have two Industrial Ethernet Peripherals (IEPs)
> to manage/generate Industrial Ethernet functions such as time stamping.
> Each IEP sub-module is sourced from an internal clock mux that can be
> derived from either of the IP instance's ICSSG_IEP_GCLK or from another
> internal ICSSG CORE_CLK mux. Add both the IEP nodes for both the ICSSG
> instances. The IEP clock is currently configured to be derived
> indirectly from the ICSSG_ICLK running at 250 MHz.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
> Signed-off-by: Suman Anna <s-anna at ti.com>
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> Reviewed-by: Ravi Gunasekaran <r-gunasekaran at ti.com>

Reviewed-by: Roger Quadros <rogerq at kernel.org>


From Jonathan.Cameron at Huawei.com  Thu Feb  8 04:06:43 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 12:06:43 +0000
Subject: [PATCH 1/7] drivers/perf: hisi_pcie: Introduce
 hisi_pcie_pmu_get_filter()
In-Reply-To: <20240204074527.47110-2-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
	<20240204074527.47110-2-yangyicong@huawei.com>
Message-ID: <20240208120643.000042fa@Huawei.com>

On Sun, 4 Feb 2024 15:45:21 +0800
Yicong Yang <yangyicong at huawei.com> wrote:

> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> Factor out retrieving of the register value for the
> corresponding event from hisi_pcie_config_filter() into a
> new function hisi_pcie_pmu_get_filter() allowing future reuse.
> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

> ---
>  drivers/perf/hisilicon/hisi_pcie_pmu.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> index b90ba8aca3fa..11a819cd07f2 100644
> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> @@ -216,10 +216,8 @@ static void hisi_pcie_pmu_writeq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
>  	writeq_relaxed(val, pcie_pmu->base + offset);
>  }
>  
> -static void hisi_pcie_pmu_config_filter(struct perf_event *event)
> +static u64 hisi_pcie_pmu_get_filter(struct perf_event *event)
>  {
> -	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
> -	struct hw_perf_event *hwc = &event->hw;
>  	u64 port, trig_len, thr_len, len_mode;
>  	u64 reg = HISI_PCIE_INIT_SET;
>  
> @@ -256,6 +254,15 @@ static void hisi_pcie_pmu_config_filter(struct perf_event *event)
>  	else
>  		reg |= FIELD_PREP(HISI_PCIE_LEN_M, HISI_PCIE_LEN_M_DEFAULT);
>  
> +	return reg;
> +}
> +
> +static void hisi_pcie_pmu_config_filter(struct perf_event *event)
> +{
> +	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	u64 reg = hisi_pcie_pmu_get_filter(event);
> +
>  	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
>  }
>  



From catalin.marinas at arm.com  Thu Feb  8 04:13:54 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 12:13:54 +0000
Subject: [PATCH v4 02/10] arm64: cpufeatures: Correctly handle signed
 values
In-Reply-To: <20240122181344.258974-3-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
 <20240122181344.258974-3-maz@kernel.org>
Message-ID: <ZcTFgpm8HlmP2XUK@arm.com>

On Mon, Jan 22, 2024 at 06:13:36PM +0000, Marc Zyngier wrote:
> Although we've had signed values for some features such as PMUv3
> and FP, the code that handles the comparaison with some limit
> has a couple of annoying issues:
> 
> - the min_field_value is always unsigned, meaning that we cannot
>   easily compare it with a negative value
> 
> - it is not possible to have a range of values, let alone a range
>   of negative values
> 
> Fix this by:
> 
> - adding an upper limit to the comparison, defaulting to all bits
>   being set to the maximum positive value
> 
> - ensuring that the signess of the min and max values are taken into
>   account
> 
> A ARM64_CPUID_FIELDS_NEG() macro is provided for signed features, but
> nothing is using it yet.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From rogerq at kernel.org  Thu Feb  8 04:14:05 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 8 Feb 2024 14:14:05 +0200
Subject: [PATCH v4 2/3] arm64: dts: ti: k3-am642-evm: add ICSSG1 Ethernet
 support
In-Reply-To: <20240205090546.4000446-3-danishanwar@ti.com>
References: <20240205090546.4000446-1-danishanwar@ti.com>
 <20240205090546.4000446-3-danishanwar@ti.com>
Message-ID: <93f6ed54-2173-453e-8b57-373a303d725b@kernel.org>



On 05/02/2024 11:05, MD Danish Anwar wrote:
> ICSSG1 provides dual Gigabit Ethernet support with proper FW loaded.
> 
> The ICSSG1 MII0 (RGMII1) has DP83869 PHY attached to it. The ICSSG1 shares
> MII1 (RGMII2) PHY DP83869 with CPSW3g and it's assigned by default to
> CPSW3g. The MDIO access to MII1 (RGMII2) PHY DP83869 is controlled by MDIO
> bus switch and also assigned to CPSW3g. Therefore the ICSSG1 MII1 (RGMII2)
> port is kept disable and ICSSG1 is enabled in single MAC mode by
> default.
> 
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> Reviewed-by: Ravi Gunasekaran <r-gunasekaran at ti.com>
> ---
>  arch/arm64/boot/dts/ti/k3-am642-evm.dts | 97 +++++++++++++++++++++++++
>  1 file changed, 97 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> index 8c5651d2cf5d..6b97e447c486 100644
> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> @@ -32,6 +32,7 @@ aliases {
>  		mmc1 = &sdhci1;
>  		ethernet0 = &cpsw_port1;
>  		ethernet1 = &cpsw_port2;
> +		ethernet2 = &icssg1_emac0;
>  	};
>  
>  	memory at 80000000 {
> @@ -229,6 +230,66 @@ transceiver2: can-phy1 {
>  		max-bitrate = <5000000>;
>  		standby-gpios = <&exp1 9 GPIO_ACTIVE_HIGH>;
>  	};
> +
> +	icssg1_eth: icssg1-eth {
> +		compatible = "ti,am642-icssg-prueth";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&icssg1_rgmii1_pins_default>;
> +		sram = <&oc_sram>;
> +		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
> +		firmware-name = "ti-pruss/am64x-sr2-pru0-prueth-fw.elf",
> +				"ti-pruss/am64x-sr2-rtu0-prueth-fw.elf",
> +				"ti-pruss/am64x-sr2-txpru0-prueth-fw.elf",
> +				"ti-pruss/am64x-sr2-pru1-prueth-fw.elf",
> +				"ti-pruss/am64x-sr2-rtu1-prueth-fw.elf",
> +				"ti-pruss/am64x-sr2-txpru1-prueth-fw.elf";
> +
> +		ti,pruss-gp-mux-sel = <2>,	/* MII mode */
> +				      <2>,
> +				      <2>,
> +				      <2>,	/* MII mode */
> +				      <2>,
> +				      <2>;
> +		ti,mii-g-rt = <&icssg1_mii_g_rt>;
> +		ti,mii-rt = <&icssg1_mii_rt>;
> +		ti,iep = <&icssg1_iep0>,  <&icssg1_iep1>;
> +		interrupt-parent = <&icssg1_intc>;
> +		interrupts = <24 0 2>, <25 1 3>;
> +		interrupt-names = "tx_ts0", "tx_ts1";
> +		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
> +		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
> +		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
> +		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
> +		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
> +		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
> +		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
> +		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
> +			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
> +			    "rx0", "rx1";
> +
> +		ethernet-ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			icssg1_emac0: port at 0 {
> +				reg = <0>;
> +				phy-handle = <&icssg1_phy1>;
> +				phy-mode = "rgmii-id";
> +				ti,syscon-rgmii-delay = <&main_conf 0x4110>;

"syscon" compatible will be eventually dropped from the main_conf node.
It is not there on other platforms e.g. am62p

One solution is to add a device tree node in main_conf and reference to
that.
e.g.
https://lore.kernel.org/all/20240205135908.54656-3-rogerq at kernel.org/

> +				/* Filled in by bootloader */
> +				local-mac-address = [00 00 00 00 00 00];
> +			};
> +			icssg1_emac1: port at 1 {
> +				reg = <1>;
> +				ti,syscon-rgmii-delay = <&main_conf 0x4114>;

here too

> +				/* Filled in by bootloader */
> +				local-mac-address = [00 00 00 00 00 00];
> +				status = "disabled";
> +			};
> +		};
> +	};
>  };
>  
>  &main_pmx0 {
> @@ -383,6 +444,30 @@ ddr_vtt_pins_default: ddr-vtt-default-pins {
>  			AM64X_IOPAD(0x0030, PIN_OUTPUT_PULLUP, 7) /* (L18) OSPI0_CSN1.GPIO0_12 */
>  		>;
>  	};
> +
> +	icssg1_mdio1_pins_default: icssg1-mdio1-default-pins {
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0) /* (Y6) PRG1_MDIO0_MDC */
> +			AM64X_IOPAD(0x0158, PIN_INPUT, 0) /* (AA6) PRG1_MDIO0_MDIO */
> +		>;
> +	};
> +
> +	icssg1_rgmii1_pins_default: icssg1-rgmii1-default-pins{
> +		pinctrl-single,pins = <
> +			AM64X_IOPAD(0x00b8, PIN_INPUT, 2) /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
> +			AM64X_IOPAD(0x00bc, PIN_INPUT, 2) /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
> +			AM64X_IOPAD(0x00c0, PIN_INPUT, 2) /* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
> +			AM64X_IOPAD(0x00c4, PIN_INPUT, 2) /* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
> +			AM64X_IOPAD(0x00d0, PIN_INPUT, 2) /* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
> +			AM64X_IOPAD(0x00c8, PIN_INPUT, 2) /* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
> +			AM64X_IOPAD(0x00e4, PIN_INPUT, 2) /* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
> +			AM64X_IOPAD(0x00e8, PIN_INPUT, 2) /* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
> +			AM64X_IOPAD(0x00ec, PIN_INPUT, 2) /* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
> +			AM64X_IOPAD(0x00f0, PIN_INPUT, 2) /* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
> +			AM64X_IOPAD(0x00f8, PIN_INPUT, 2) /* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
> +			AM64X_IOPAD(0x00f4, PIN_INPUT, 2) /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
> +		>;
> +	};
>  };
>  
>  &main_uart0 {
> @@ -731,3 +816,15 @@ &main_mcan1 {
>  	pinctrl-0 = <&main_mcan1_pins_default>;
>  	phys = <&transceiver2>;
>  };
> +
> +&icssg1_mdio {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&icssg1_mdio1_pins_default>;
> +
> +	icssg1_phy1: ethernet-phy at f {
> +		reg = <0xf>;
> +		tx-internal-delay-ps = <250>;
> +		rx-internal-delay-ps = <2000>;
> +	};
> +};

-- 
cheers,
-roger


From catalin.marinas at arm.com  Thu Feb  8 04:14:42 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 12:14:42 +0000
Subject: [PATCH v4 03/10] arm64: cpufeature: Correctly display signed
 override values
In-Reply-To: <20240122181344.258974-4-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
 <20240122181344.258974-4-maz@kernel.org>
Message-ID: <ZcTFsmVpAt9QMxwj@arm.com>

On Mon, Jan 22, 2024 at 06:13:37PM +0000, Marc Zyngier wrote:
> When a field gets overriden, the kernel indicates the result of
> the override in dmesg. This works well with unsigned fields, but
> results in a pretty ugly output when the field is signed.
> 
> Truncate the field to its width before displaying it.
> 
> Reviewed-by: Oliver Upton <oliver.upton at linux.dev>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From mripard at kernel.org  Thu Feb  8 04:16:27 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 8 Feb 2024 13:16:27 +0100
Subject: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum
 rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>
Message-ID: <exb2lvjcozak5fayrgyenrd3ntii4jfxgvqork4klyz5pky2aq@dj2zyw5su6pv>

On Mon, Feb 05, 2024 at 04:22:26PM +0100, Frank Oltmanns wrote:
> According to the Allwinner User Manual, the Allwinner A64 requires
> PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.
> 
> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> ---
>  drivers/clk/sunxi-ng/ccu_nkm.c | 13 +++++++++++++
>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index 1168d894d636..7d135908d6e0 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -181,6 +181,12 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
>  	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
>  		rate *= nkm->fixed_post_div;
>  
> +	if (nkm->min_rate && rate < nkm->min_rate)
> +		rate = nkm->min_rate;
> +
> +	if (nkm->max_rate && rate > nkm->max_rate)
> +		rate = nkm->max_rate;
> +

This is provided by the clock range already. If you call
clk_hw_set_rate_range, it should work just fine.

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/20240208/e088cc28/attachment.sig>

From linus.walleij at linaro.org  Thu Feb  8 04:17:11 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 8 Feb 2024 13:17:11 +0100
Subject: [PATCH v3 0/6] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <DU0PR04MB9417335A3A41BE4E373B915188472@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20240121-pinctrl-scmi-v3-0-8d94ba79dca8@nxp.com>
 <f88d07ef-83b2-4d14-976a-6dbbd71e036f@oss.nxp.com> <CACRpkdYV=qYQ9qDUWYTLDAV1niay30gYH5S=zjfi31GpeY5o-A@mail.gmail.com>
 <DU0PR04MB9417A9074C5DC49AE689E65288432@DU0PR04MB9417.eurprd04.prod.outlook.com>
 <Zbt-QkWhz5d9P-v6@pluto> <DU0PR04MB9417CA6CF089B264112C32A088402@DU0PR04MB9417.eurprd04.prod.outlook.com>
 <CACRpkdYCrbNB8wu4rO3Yx0qomxR3kTt0P7YH7kc2HPCbrgt=tg@mail.gmail.com> <DU0PR04MB9417335A3A41BE4E373B915188472@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <CACRpkdbguqMvx5w2fEDaNkNTmNtwphns-W1c2i+ntoi1CHqaVg@mail.gmail.com>

On Mon, Feb 5, 2024 at 10:11?AM Peng Fan <peng.fan at nxp.com> wrote:
> [Me]

> > This is very much to the core of the problem isn't it?
>
> Yes. Code size should be as small as possible.

This is a valid argument, I don't know how big your SCMI FW is, or
if it has to fit into some on-chip memory or so.

> And using SCMI generic pinconf, there will be multiple
> SCMI calls(not MMIO access), such as setting mux(ops->set_mux)
> needs an SCMI call, pad settings(ops->pin_config_set) needs an SCMI call.
> And maybe ops->get_function_name  needs an extra SCMI call.
>
> With current i.MX design, only one SCMI call is used, which
> use less time.

I think this could be fixed in the spec, let's see what the spec author says.

In any case: pin control is pretty much never on a hot path, a few
microseconds more or less doesn't matter. It's usually just used
and probe, suspend/resume and maybe shutdown. All usecases on
the slowpath, so I think it's a premature optimization.

> > Over the years I have come to regret it a bit, I think insisting on groups and
> > functions as strings is better for abstraction. And the point of firmware is to
> > abstract things so they work the same on all systems.
>
> With current:
>         pinctrl_uart1: uart1grp {
>                 fsl,pins = <
>                         IMX95_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX      0x31e
>                         IMX95_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX      0x31e
>                 >;
>         };
>
> It is very easy for people to know the meaning from reading reference manual.

Yes If the defines are provided it's quite readable. And I think Freescale
people really get used to it.

But from a maintenance and standardization point of view, it's nice if
everything works the same way and looks the same.

> If using generic pinconf, the dt node will be like
> Uartgrp {
>         pins = "uart1txd", "uart1rxd";
>         functions = "uart1";
>         bias-xx
>         drive-strength =
> };

Well that looks good to me :)

It looks the same as e.g. Qualcomm or nVidia pins. So it's easy for me
to read and understand, and that's my perspective as a maintainer.

> The firmware needs add more code to export functions, pack the conf settings,
> each pins needs a function name per current i.MX HW logic.

Indeed, but I think any standard requires a bit of code to implement.
How much is "too much" code is a matter of taste and physical contraints.
(A PC UEFI BIOS isn't exactly small either.)

I understand your point of view, and I think it is pretty much
the same stance that the Freescale maintainers put forward for the DT
bindings for Freescale.

Yours,
Linus Walleij


From rogerq at kernel.org  Thu Feb  8 04:17:57 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 8 Feb 2024 14:17:57 +0200
Subject: [PATCH v4 3/3] arm64: dts: ti: k3-am642-evm: add overlay for
 icssg1 2nd port
In-Reply-To: <20240205090546.4000446-4-danishanwar@ti.com>
References: <20240205090546.4000446-1-danishanwar@ti.com>
 <20240205090546.4000446-4-danishanwar@ti.com>
Message-ID: <daec387f-987e-43c6-a9d4-caa4580d1113@kernel.org>



On 05/02/2024 11:05, MD Danish Anwar wrote:
> The am642-evm doesn't allow to enable 2 x CPSW3g ports and 2 x ICSSG1 ports
> all together, so base k3-am642-evm.dts enables by default 2 x CPSW3g ports
> and 1 x ICSSG1 ports, but it is also possible to support 1 x CPSW3g ports
> and 2 x ICSSG1 ports configuration.
> 
> This patch adds overlay to support 1 x CPSW3g ports and 2 x ICSSG1 ports
> configuration:
> - Renames 'mdio-mux-1' node to 'mdio-mux at 1'
> - Add label name 'mdio_mux_1' for 'mdio-mux at 1' node so that the node
>   'mdio-mux at 1' can be disabled in the overlay using the label name.
> - disable 2nd CPSW3g port
> - update CPSW3g pinmuxes to not use RGMII2
> - disable mdio-mux-1 and define mdio-mux-2 to route ICSSG1 MDIO to the
>   shared DP83869 PHY
> - add and enable ICSSG1 RGMII2 pinmuxes
> - enable ICSSG1 MII1 port

/icssg1/ICSSG1 in subject

> 
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> Reviewed-by: Ravi Gunasekaran <r-gunasekaran at ti.com>

Reviewed-by: Roger Quadros <rogerq at kernel.org>


From Jonathan.Cameron at Huawei.com  Thu Feb  8 04:18:15 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 12:18:15 +0000
Subject: [PATCH 1/7] drivers/perf: hisi_pcie: Introduce
 hisi_pcie_pmu_get_filter()
In-Reply-To: <20240208120643.000042fa@Huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
	<20240204074527.47110-2-yangyicong@huawei.com>
	<20240208120643.000042fa@Huawei.com>
Message-ID: <20240208121800.000057a2@huawei.com>

On Thu, 8 Feb 2024 12:06:43 +0000
Jonathan Cameron <Jonathan.Cameron at Huawei.com> wrote:

> On Sun, 4 Feb 2024 15:45:21 +0800
> Yicong Yang <yangyicong at huawei.com> wrote:
> 
> > From: Yicong Yang <yangyicong at hisilicon.com>
> > 
> > Factor out retrieving of the register value for the
> > corresponding event from hisi_pcie_config_filter() into a
> > new function hisi_pcie_pmu_get_filter() allowing future reuse.
> > 
> > Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>  
> 
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

On second thoughts, this might benefit from a clearer name.
Perhaps just call it exactly what it is
hisi_pcie_pmu_get_ctrl_reg_val_to_set()

It incorporates the event code as well as the filter.
Maybe we want to rename pmu_config_filter() as well to
pmu_config_counter() which I think is the real meaning?


> 
> > ---
> >  drivers/perf/hisilicon/hisi_pcie_pmu.c | 13 ++++++++++---
> >  1 file changed, 10 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> > index b90ba8aca3fa..11a819cd07f2 100644
> > --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
> > +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> > @@ -216,10 +216,8 @@ static void hisi_pcie_pmu_writeq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
> >  	writeq_relaxed(val, pcie_pmu->base + offset);
> >  }
> >  
> > -static void hisi_pcie_pmu_config_filter(struct perf_event *event)
> > +static u64 hisi_pcie_pmu_get_filter(struct perf_event *event)
> >  {
> > -	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
> > -	struct hw_perf_event *hwc = &event->hw;
> >  	u64 port, trig_len, thr_len, len_mode;
> >  	u64 reg = HISI_PCIE_INIT_SET;
> >  
> > @@ -256,6 +254,15 @@ static void hisi_pcie_pmu_config_filter(struct perf_event *event)
> >  	else
> >  		reg |= FIELD_PREP(HISI_PCIE_LEN_M, HISI_PCIE_LEN_M_DEFAULT);
> >  
> > +	return reg;
> > +}
> > +
> > +static void hisi_pcie_pmu_config_filter(struct perf_event *event)
> > +{
> > +	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	u64 reg = hisi_pcie_pmu_get_filter(event);
> > +
> >  	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
> >  }
> >    
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From Jonathan.Cameron at Huawei.com  Thu Feb  8 04:19:12 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 12:19:12 +0000
Subject: [PATCH 2/7] drivers/perf: hisi_pcie: Fix incorrect counting
 under metric mode
In-Reply-To: <20240204074527.47110-3-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
	<20240204074527.47110-3-yangyicong@huawei.com>
Message-ID: <20240208121912.00001fd7@Huawei.com>

On Sun, 4 Feb 2024 15:45:22 +0800
Yicong Yang <yangyicong at huawei.com> wrote:

> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> The metric counting shows incorrect results if the events in the
> metric group using the same event but different filter options.
> This is because we only judge the event code to decide whether
> the event in the metric group should share the same hardware
> counter, but ignore the settings of the filter.
> 
> For example, on a platform of 2 ports 0x1 and 0x2 but only port
> 0x1 has a downstream PCIe NVME device. The metric counting
> shows both ports have the same counts because we misassign these
> two events to one same hardware counter:
> [root at localhost perf-iostat]# ./perf stat -e '{hisi_pcie0_core1/event=0x0104,port=0x2/,hisi_pcie0_core1/event=0x0104,port=0x1/}'
> 
>  Performance counter stats for 'system wide':
> 
>         7907484924      hisi_pcie0_core1/event=0x0104,port=0x2/
>         7907484924      hisi_pcie0_core1/event=0x0104,port=0x1/
> 
>       10.153863691 seconds time elapsed
> 
> Fix this by using the whole config rather than the event only
> to judge whether two events are the same and should share the
> same hardware counter. With this patch, the metric counting in
> the above case tends to be corrected:
> 
> [root at localhost perf-iostat]# ./perf stat -e '{hisi_pcie0_core1/event=0x0104,port=0x2/,hisi_pcie0_core1/event=0x0104,port=0x1/}'
> 
>  Performance counter stats for 'system wide':
> 
>                  0      hisi_pcie0_core1/event=0x0104,port=0x2/
>         8123122077      hisi_pcie0_core1/event=0x0104,port=0x1/
> 
>       10.152875631 seconds time elapsed
> 
> Fixes: 8404b0fbc7fb ("drivers/perf: hisi: Add driver for HiSilicon PCIe PMU")
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
>  drivers/perf/hisilicon/hisi_pcie_pmu.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> index 11a819cd07f2..9623bed93876 100644
> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> @@ -314,10 +314,15 @@ static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
>  	return true;
>  }
>  
> +/*
> + * Check Whether two events share the same config. The same config means not
> + * only the event code, but also the filter settings of the two events are
> + * the same.
> + */
>  static bool hisi_pcie_pmu_cmp_event(struct perf_event *target,
>  					struct perf_event *event)
>  {
> -	return hisi_pcie_get_real_event(target) == hisi_pcie_get_real_event(event);
> +	return hisi_pcie_pmu_get_filter(target) == hisi_pcie_pmu_get_filter(event);

This is why I looked more closely at what get_filter() was doing in previous patch.
Not obvious from the naming here that this compares the event + filters rather than
now just comparing the filters.

>  }
>  
>  static bool hisi_pcie_pmu_validate_event_group(struct perf_event *event)



From dsimic at manjaro.org  Thu Feb  8 04:19:30 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu, 08 Feb 2024 13:19:30 +0100
Subject: [PATCH v2 4/4] arm64: dts: rockchip: Add further granularity in
 RK3588 CPU OPPs
In-Reply-To: <400e19a3f7b2de674a1db457b675233f@manjaro.org>
References: <20240130-rk-dts-additions-v2-0-c6222c4c78df@gmail.com>
 <20240130-rk-dts-additions-v2-4-c6222c4c78df@gmail.com>
 <400e19a3f7b2de674a1db457b675233f@manjaro.org>
Message-ID: <d2f17fdc111bba89a0e107c058d4fca0@manjaro.org>

Hello Alexey,

On 2024-01-31 06:08, Dragan Simic wrote:
> On 2024-01-30 19:21, Alexey Charkov wrote:
>> This introduces additional OPPs that share the same voltage as
>> another OPP already present in the .dtsi but with lower frequency.
>> 
>> The idea is to try and limit system throughput more gradually upon
>> reaching the throttling condition for workloads that are close to
>> sustainable power already, thus avoiding needless performance loss.
>> 
>> My limited synthetic benchmarking [1] showed around 3.8% performance
>> benefit when these are in place, other things equal (not meant to
>> be comprehensive though).
> 
> I'm fine with this two-patch approach, so this important new feature
> can be merged quicker, hopefully in the current merge window.  We can
> add more OPPs later, after the additional testing is performed, of
> course if all checks out as expected.

Thanks to Radxa providing a sample Rock 5B to me, I'll be able to
join the testing in the new few days, or maybe early next week.
Looking forward to the test results. :)

>> [1] 
>> https://lore.kernel.org/linux-rockchip/CABjd4YxqarUCbZ-a2XLe3TWJ-qjphGkyq=wDnctnEhdoSdPPpw at mail.gmail.com/T/#me92aa0ee25e6eeb1d1501ce85f5af4e58b3b13c5
>> 
>> Signed-off-by: Alexey Charkov <alchark at gmail.com>
>> ---
>>  arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 87 
>> +++++++++++++++++++++++++++++++
>>  1 file changed, 87 insertions(+)
>> 
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
>> b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
>> index af8b932a04c1..506676985a7e 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
>> @@ -360,6 +360,21 @@ cluster0_opp_table: opp-table-cluster0 {
>>  		compatible = "operating-points-v2";
>>  		opp-shared;
>> 
>> +		opp-408000000 {
>> +			opp-hz = /bits/ 64 <408000000>;
>> +			opp-microvolt = <675000 675000 950000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>> +		opp-600000000 {
>> +			opp-hz = /bits/ 64 <600000000>;
>> +			opp-microvolt = <675000 675000 950000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>> +		opp-816000000 {
>> +			opp-hz = /bits/ 64 <816000000>;
>> +			opp-microvolt = <675000 675000 950000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>>  		opp-1008000000 {
>>  			opp-hz = /bits/ 64 <1008000000>;
>>  			opp-microvolt = <675000 675000 950000>;
>> @@ -392,6 +407,27 @@ cluster1_opp_table: opp-table-cluster1 {
>>  		compatible = "operating-points-v2";
>>  		opp-shared;
>> 
>> +		opp-408000000 {
>> +			opp-hz = /bits/ 64 <408000000>;
>> +			opp-microvolt = <675000 675000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +			opp-suspend;
>> +		};
>> +		opp-600000000 {
>> +			opp-hz = /bits/ 64 <600000000>;
>> +			opp-microvolt = <675000 675000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>> +		opp-816000000 {
>> +			opp-hz = /bits/ 64 <816000000>;
>> +			opp-microvolt = <675000 675000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>> +		opp-1008000000 {
>> +			opp-hz = /bits/ 64 <1008000000>;
>> +			opp-microvolt = <675000 675000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>>  		opp-1200000000 {
>>  			opp-hz = /bits/ 64 <1200000000>;
>>  			opp-microvolt = <675000 675000 1000000>;
>> @@ -422,6 +458,21 @@ opp-2208000000 {
>>  			opp-microvolt = <987500 987500 1000000>;
>>  			clock-latency-ns = <40000>;
>>  		};
>> +		opp-2256000000 {
>> +			opp-hz = /bits/ 64 <2256000000>;
>> +			opp-microvolt = <1000000 1000000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>> +		opp-2304000000 {
>> +			opp-hz = /bits/ 64 <2304000000>;
>> +			opp-microvolt = <1000000 1000000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>> +		opp-2352000000 {
>> +			opp-hz = /bits/ 64 <2352000000>;
>> +			opp-microvolt = <1000000 1000000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>>  		opp-2400000000 {
>>  			opp-hz = /bits/ 64 <2400000000>;
>>  			opp-microvolt = <1000000 1000000 1000000>;
>> @@ -433,6 +484,27 @@ cluster2_opp_table: opp-table-cluster2 {
>>  		compatible = "operating-points-v2";
>>  		opp-shared;
>> 
>> +		opp-408000000 {
>> +			opp-hz = /bits/ 64 <408000000>;
>> +			opp-microvolt = <675000 675000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +			opp-suspend;
>> +		};
>> +		opp-600000000 {
>> +			opp-hz = /bits/ 64 <600000000>;
>> +			opp-microvolt = <675000 675000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>> +		opp-816000000 {
>> +			opp-hz = /bits/ 64 <816000000>;
>> +			opp-microvolt = <675000 675000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>> +		opp-1008000000 {
>> +			opp-hz = /bits/ 64 <1008000000>;
>> +			opp-microvolt = <675000 675000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>>  		opp-1200000000 {
>>  			opp-hz = /bits/ 64 <1200000000>;
>>  			opp-microvolt = <675000 675000 1000000>;
>> @@ -463,6 +535,21 @@ opp-2208000000 {
>>  			opp-microvolt = <987500 987500 1000000>;
>>  			clock-latency-ns = <40000>;
>>  		};
>> +		opp-2256000000 {
>> +			opp-hz = /bits/ 64 <2256000000>;
>> +			opp-microvolt = <1000000 1000000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>> +		opp-2304000000 {
>> +			opp-hz = /bits/ 64 <2304000000>;
>> +			opp-microvolt = <1000000 1000000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>> +		opp-2352000000 {
>> +			opp-hz = /bits/ 64 <2352000000>;
>> +			opp-microvolt = <1000000 1000000 1000000>;
>> +			clock-latency-ns = <40000>;
>> +		};
>>  		opp-2400000000 {
>>  			opp-hz = /bits/ 64 <2400000000>;
>>  			opp-microvolt = <1000000 1000000 1000000>;
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From Jonathan.Cameron at Huawei.com  Thu Feb  8 04:20:29 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 12:20:29 +0000
Subject: [PATCH 3/7] drivers/perf: hisi_pcie: Add more events for
 counting TLP bandwidth
In-Reply-To: <20240204074527.47110-4-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
	<20240204074527.47110-4-yangyicong@huawei.com>
Message-ID: <20240208122029.000005e1@Huawei.com>

On Sun, 4 Feb 2024 15:45:23 +0800
Yicong Yang <yangyicong at huawei.com> wrote:

> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> A typical PCIe transaction is consisted of various TLP packets in both
> direction. For counting bandwidth only memory read events are exported
> currently. Add memory write and completion counting events of both
> direction to complementation.

complementation?

> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

> ---
>  drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> index 9623bed93876..83be3390686c 100644
> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> @@ -726,10 +726,18 @@ static struct attribute *hisi_pcie_pmu_events_attr[] = {
>  	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
>  	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
>  	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
> +	HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_flux, 0x0104),
> +	HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_time, 0x10104),
>  	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x0804),
>  	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x10804),
> +	HISI_PCIE_PMU_EVENT_ATTR(rx_cpl_flux, 0x2004),
> +	HISI_PCIE_PMU_EVENT_ATTR(rx_cpl_time, 0x12004),
> +	HISI_PCIE_PMU_EVENT_ATTR(tx_mwr_flux, 0x0105),
> +	HISI_PCIE_PMU_EVENT_ATTR(tx_mwr_time, 0x10105),
>  	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x0405),
>  	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x10405),
> +	HISI_PCIE_PMU_EVENT_ATTR(tx_cpl_flux, 0x1005),
> +	HISI_PCIE_PMU_EVENT_ATTR(tx_cpl_time, 0x11005),
>  	NULL
>  };
>  



From manuel.traut at mt.com  Thu Feb  8 04:19:59 2024
From: manuel.traut at mt.com (Manuel Traut)
Date: Thu,  8 Feb 2024 13:19:59 +0100
Subject: [PATCH] ARM: dts: imx6ul: Set macaddress location in ocotp
Message-ID: <20240208122012.1959628-1-manuel.traut@mt.com>

If a bootloader does not configure the MAC address, devices come up with
a random MAC at the moment.

ocotp provides registers for storing the mac-address.
Configure those for i.MX6UL and i.MX6ULL allows net/core to retrieve it from
there.

Signed-off-by: Manuel Traut <manuel.traut at mt.com>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index a27a7554c2e7..e5e8bf814f77 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -538,6 +538,8 @@ fec2: ethernet at 20b4000 {
 				fsl,num-rx-queues = <1>;
 				fsl,stop-mode = <&gpr 0x10 4>;
 				fsl,magic-packet;
+				nvmem-cells = <&fec2_mac_addr>;
+				nvmem-cell-names = "mac-address";
 				status = "disabled";
 			};
 
@@ -897,6 +899,8 @@ fec1: ethernet at 2188000 {
 				fsl,num-rx-queues = <1>;
 				fsl,stop-mode = <&gpr 0x10 3>;
 				fsl,magic-packet;
+				nvmem-cells = <&fec1_mac_addr>;
+				nvmem-cell-names = "mac-address";
 				status = "disabled";
 			};
 
@@ -1004,6 +1008,14 @@ tempmon_temp_grade: temp-grade at 20 {
 				cpu_speed_grade: speed-grade at 10 {
 					reg = <0x10 4>;
 				};
+				fec1_mac_addr: mac-addr at 88 {
+					reg = <0x88 6>;
+				};
+
+				fec2_mac_addr: mac-addr at 8e {
+					reg = <0x8e 6>;
+				};
+
 			};
 
 			csi: csi at 21c4000 {
-- 
2.43.0



From catalin.marinas at arm.com  Thu Feb  8 04:25:19 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 12:25:19 +0000
Subject: [PATCH v4 04/10] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1
In-Reply-To: <20240122181344.258974-5-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
 <20240122181344.258974-5-maz@kernel.org>
Message-ID: <ZcTILxL_jeGvP0Z0@arm.com>

On Mon, Jan 22, 2024 at 06:13:38PM +0000, Marc Zyngier wrote:
> ARMv9.5 has infroduced ID_AA64MMFR4_EL1 with a bunch of new features.
> Add the corresponding layout.
> 
> This is extracted from the public ARM SysReg_xml_A_profile-2023-09
> delivery, timestamped d55f5af8e09052abe92a02adf820deea2eaed717.
> 
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Feb  8 04:25:41 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 12:25:41 +0000
Subject: [PATCH v4 05/10] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling
In-Reply-To: <20240122181344.258974-6-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
 <20240122181344.258974-6-maz@kernel.org>
Message-ID: <ZcTIRQ4s7kiqosgw@arm.com>

On Mon, Jan 22, 2024 at 06:13:39PM +0000, Marc Zyngier wrote:
> Add ID_AA64MMFR4_EL1 to the list of idregs the kernel knows about,
> and describe the E2H0 field.
> 
> Reviewed-by: Oliver Upton <oliver.upton at linux.dev>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Feb  8 04:26:23 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 12:26:23 +0000
Subject: [PATCH v4 06/10] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0
In-Reply-To: <20240122181344.258974-7-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
 <20240122181344.258974-7-maz@kernel.org>
Message-ID: <ZcTIb66ALlbskvTC@arm.com>

On Mon, Jan 22, 2024 at 06:13:40PM +0000, Marc Zyngier wrote:
> A variant of FEAT_E2H0 not being implemented exists in the form of
> HCR_EL2.E2H being RES1 *and* HCR_EL2.NV1 being RES0 (indicating that
> only VHE is supported on the host and nested guests).
> 
> Add the necessary infrastructure for this new CPU capability.
> 
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Feb  8 04:27:23 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 12:27:23 +0000
Subject: [PATCH v4 06/10] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0
In-Reply-To: <20240122181344.258974-7-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
 <20240122181344.258974-7-maz@kernel.org>
Message-ID: <ZcTIqxG98VecY4_0@arm.com>

On Mon, Jan 22, 2024 at 06:13:40PM +0000, Marc Zyngier wrote:
> A variant of FEAT_E2H0 not being implemented exists in the form of
> HCR_EL2.E2H being RES1 *and* HCR_EL2.NV1 being RES0 (indicating that
> only VHE is supported on the host and nested guests).
> 
> Add the necessary infrastructure for this new CPU capability.
> 
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Feb  8 04:27:52 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 12:27:52 +0000
Subject: [PATCH v4 07/10] arm64: Treat HCR_EL2.E2H as RES1 when
 ID_AA64MMFR4_EL1.E2H0 is negative
In-Reply-To: <20240122181344.258974-8-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
 <20240122181344.258974-8-maz@kernel.org>
Message-ID: <ZcTIyM6W4_2RnOkt@arm.com>

On Mon, Jan 22, 2024 at 06:13:41PM +0000, Marc Zyngier wrote:
> For CPUs that have ID_AA64MMFR4_EL1.E2H0 as negative, it is important
> to avoid the boot path that sets HCR_EL2.E2H=0. Fortunately, we
> already have this path to cope with fruity CPUs.
> 
> Tweak init_el2 to look at ID_AA64MMFR4_EL1.E2H0 first.
> 
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From Jonathan.Cameron at Huawei.com  Thu Feb  8 04:29:02 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 12:29:02 +0000
Subject: [PATCH 4/7] drivers/perf: hisi_pcie: Check the target filter
 properly
In-Reply-To: <20240204074527.47110-5-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
	<20240204074527.47110-5-yangyicong@huawei.com>
Message-ID: <20240208122902.0000768f@Huawei.com>

On Sun, 4 Feb 2024 15:45:24 +0800
Yicong Yang <yangyicong at huawei.com> wrote:

> From: Junhao He <hejunhao3 at huawei.com>
> 
> The PMU can monitor traffic of certain target Root Port or downstream
> target Endpoint. User can specify the target filter by the "port" or
> "bdf" option respectively. The PMU can only monitor the Root Port or
> Endpoint on the same PCIe core so the value of "port" or "bdf" should
> be valid and will be checked by the driver.
> 
> Currently at least and only one of "port" and "bdf" option must be set.
> If "port" filter is not set or is set explicitly to zero (default),
> driver will regard the user specifies a "bdf" option since "port" option
> is a bitmask of the target Root Ports and zero is not a valid
> value.
> 
> If user not explicitly set "port" or "bdf" filter, the driver uses "bdf"
> default value (zero) to set target filter, but driver will skip the
> check of bdf=0, although it's a valid value (meaning 0000:000:00.0).
> Then the user just gets zero.
> 
> Therefore, we need to check if both "port" and "bdf" are invalid, then
> return failure and report warning.
> 
> Testing:
> before the patch:
>                    0      hisi_pcie0_core1/rx_mrd_flux/
>                    0      hisi_pcie0_core1/rx_mrd_flux,port=0/
>               24,124      hisi_pcie0_core1/rx_mrd_flux,port=1/
>                    0      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
>      <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/

Nice to include an example that works for bdf
			    hisi_pcie0_core1/rx_mrd_flux,bdf=1,port=0 
or something like that?
> 
> after the patch:
>      <not supported>      hisi_pcie0_core1/rx_mrd_flux/
>      <not supported>      hisi_pcie0_core1/rx_mrd_flux,port=0/
>               24,153      hisi_pcie0_core1/rx_mrd_flux,port=1/
>      <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
>      <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/
> 
> Signed-off-by: Junhao He <hejunhao3 at huawei.com>
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>

Clearly the current situation is wrong, but perhaps we can
have a more intuitive scheme (could be added as a follow up patch)
and have the driver figure out which port the bdf lies below?

Maybe that's a job for userspace tooling rather than the driver, but
the driver already has verification code and it wouldn't be hard
to not just check the rp is ours, but also set the filter to specify
that rp, or maybe just set the mask to include them all?

Jonathan


> ---
>  drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> index 83be3390686c..b91f03c02c57 100644
> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> @@ -306,10 +306,10 @@ static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
>  	if (hisi_pcie_get_trig_len(event) > HISI_PCIE_TRIG_MAX_VAL)
>  		return false;
>  
> -	if (requester_id) {
> -		if (!hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
> -			return false;
> -	}
> +	/* Need to explicitly set filter of "port" or "bdf" */
> +	if (!hisi_pcie_get_port(event) &&
> +	    !hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
> +		return false;
>  
>  	return true;
>  }



From catalin.marinas at arm.com  Thu Feb  8 04:29:13 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 12:29:13 +0000
Subject: [PATCH v4 10/10] KVM: arm64: Handle Apple M2 as not having
 HCR_EL2.NV1 implemented
In-Reply-To: <20240122181344.258974-11-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
 <20240122181344.258974-11-maz@kernel.org>
Message-ID: <ZcTJGQmk51HgbH4p@arm.com>

On Mon, Jan 22, 2024 at 06:13:44PM +0000, Marc Zyngier wrote:
> Although the Apple M2 family of CPUs can have HCR_EL2.NV1 being
> set and clear, with the change in trap behaviour being OK, they
> explode spectacularily on an EL2 S1 page table using the nVHE
> format. This is no good.
> 
> Let's pretend this HW doesn't have NV1, and move along.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Feb  8 04:30:20 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 12:30:20 +0000
Subject: [PATCH v4 00/10] arm64: Add support for FEAT_E2H0, or lack
 thereof
In-Reply-To: <Zb08fXz23JUiF4hD@linux.dev>
References: <20240122181344.258974-1-maz@kernel.org>
 <Zb08fXz23JUiF4hD@linux.dev>
Message-ID: <ZcTJXBThmtRmNbG8@arm.com>

On Fri, Feb 02, 2024 at 07:03:25PM +0000, Oliver Upton wrote:
> On Mon, Jan 22, 2024 at 06:13:34PM +0000, Marc Zyngier wrote:
> > Since ARMv8.1, the architecture has grown the VHE feature, which makes
> > EL2 a superset of EL1. With ARMv9.5 (and retroactively allowed from
> > ARMv8.1), the architecture allows implementations to have VHE as the
> > *only* implemented behaviour, meaning that HCR_EL2.E2H can be
> > implemented as RES1. As a follow-up, HCR_EL2.NV1 can also be
> > implemented as RES0, making the VHE-ness of the architecture
> > recursive.
> > 
> > This has a number of consequences, both at boot time and for KVM,
> > though the changes at that level are pretty minor.
> > 
> > The real meat of this series is on the cpufeature front, as FEAT_E2H0
> > is a *negative* feature, where 0b1111 (-1) represents E2H being RES1
> > and 0b1110 (-2) additionally indicates that NV1 is RES0. Fun, isn't
> > it?
> 
> This looks good to me. Catalin + Will, are you comfortable with the
> cpufeature changes at this point?

Yes, I acked those touching the arm64 files.

> No strong opinions on which tree these patches get applied to. Most of
> the series is non-KVM code, so I'd understand if y'all wanted it to go
> through arm64. OTOH, there are some other KVM features that might appear
> in 6.9 that build on top of this, so at minimum I'd probably need a
> shared branch.

Please take it through the arm64 kvm tree but keep it on a separate
stable branch in case I need to pull it.

-- 
Catalin


From vaishnav.a at ti.com  Thu Feb  8 04:32:24 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 18:02:24 +0530
Subject: [PATCH v3 0/9] Add CSI2RX capture support on TI J7 platforms
Message-ID: <20240208123233.391115-1-vaishnav.a@ti.com>

Hi,

This series adds support for CSI2RX capture support on J7 platforms,
series was tested for CSI2RX capture on OV5640 sensor and RPI camera
v2 IMX219 sensor on J721e Common Processor Board, J721E Starter kit,
J721S2 Common Processor Board, AM68 Starter Kit, J784s4 EVM and AM69
Starter kit.

V1: https://lore.kernel.org/all/20240129132742.1189783-1-vaishnav.a at ti.com/
V2: https://lore.kernel.org/all/20240208084254.295289-1-vaishnav.a at ti.com/

Changelog:
V2->V3:
  * Fix order of properties in patch 6/7/8 as per dts coding style.
V1->V2:
  * Address feedback from Jai and Andrew
    * Rename overlays to indicate first platform supported/dual camera.
    * Add missed build test.
    * Add board schematics for all commit messages.

Test logs:
J721E EVM OV5640 - https://gist.github.com/vaishnavachath/b08521386cfbe1939facf39b8b2d796b
J721S2 EVM OV5640 - https://gist.github.com/vaishnavachath/1b0d60da6b6464cf12334cd5e161a79b
J784s4 EVM OV5640 - https://gist.github.com/vaishnavachath/02b70df94d2d41662eff99f4ce966d67
TDA4VM SK IMX219 - https://gist.github.com/vaishnavachath/64fc6edd6cc060027812bebd6573df07
AM68 SK IMX219 - https://gist.github.com/vaishnavachath/d522254ff5e797bc853e0706fbea932a
AM69 SK IMX219 - https://gist.github.com/vaishnavachath/8dbd960cc89d691886df371c53aac399

Only a single set of overlays for dual RPI IMX219 is included in the series
for reference and other overlays to test OV5640 can be found here:
https://gist.github.com/vaishnavachath/d0a052106892fe9f3096733931e9ad5f

Vaishnav Achath (9):
  arm64: dts: ti: k3-j721s2-common-proc-board: Enable camera peripherals
  arm64: dts: ti: k3-j784s4-evm: Enable camera peripherals
  arm64: dts: ti: k3-am68-sk-base-board: Enable camera peripherals
  arm64: dts: ti: k3-am69-sk: Enable camera peripherals
  arm64: dts: ti: k3-j721e-sk: Model CSI2RX connector mux
  arm64: dts: ti: k3-j721e-main: Add CSI2RX capture nodes
  arm64: dts: ti: k3-j721s2-main: Add CSI2RX capture nodes
  arm64: dts: ti: k3-j784s4-main: Add CSI2RX capture nodes
  arm64: dts: ti: k3-j721e-sk: Add overlay for IMX219

 arch/arm64/boot/dts/ti/Makefile               |  13 ++
 .../boot/dts/ti/k3-am68-sk-base-board.dts     |  50 +++++
 arch/arm64/boot/dts/ti/k3-am69-sk.dts         |  51 +++++
 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi     | 122 ++++++++++++
 .../dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso  | 125 ++++++++++++
 arch/arm64/boot/dts/ti/k3-j721e-sk.dts        |  19 +-
 .../dts/ti/k3-j721s2-common-proc-board.dts    |  25 +++
 arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi    | 123 +++++++++++-
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts      |  25 +++
 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi    | 183 +++++++++++++++++-
 10 files changed, 732 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso

-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 04:32:25 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 18:02:25 +0530
Subject: [PATCH v3 1/9] arm64: dts: ti: k3-j721s2-common-proc-board: Enable camera peripherals
In-Reply-To: <20240208123233.391115-1-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
Message-ID: <20240208123233.391115-2-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On J721S2 Common Processor Board,
this is routed to I2C-5, so enable the instance and the TCA6408
GPIO expander on the bus.

Common Processor Board schematics: https://www.ti.com/lit/zip/sprr411
J721S2 SoM schematics: https://www.ti.com/lit/zip/sprr439

Reviewed-by: Jai Luthra <j-luthra at ti.com>
Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with schematics.

 .../dts/ti/k3-j721s2-common-proc-board.dts    | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
index 361365bb5523..5631735c9b7a 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -147,6 +147,13 @@ J721S2_IOPAD(0x060, PIN_INPUT_PULLUP, 13) /* (AC27) MCASP2_AXR1.I2C3_SDA */
 		>;
 	};
 
+	main_i2c5_pins_default: main-i2c5-default-pins {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x01c, PIN_INPUT, 8) /* (Y24) MCAN15_TX.I2C5_SCL */
+			J721S2_IOPAD(0x018, PIN_INPUT, 8) /* (W23) MCAN14_RX.I2C5_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		pinctrl-single,pins = <
 			J721S2_IOPAD(0x104, PIN_INPUT, 0) /* (P23) MMC1_CLK */
@@ -356,6 +363,24 @@ exp2: gpio at 22 {
 	};
 };
 
+&main_i2c5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c5_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	exp5: gpio at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI2_EXP_RSTZ", "CSI2_EXP_A_GPIO0",
+				  "CSI2_EXP_A_GPIO1", "CSI2_EXP_A_GPIO2",
+				  "CSI2_EXP_B_GPIO1", "CSI2_EXP_B_GPIO2",
+				  "CSI2_EXP_B_GPIO3", "CSI2_EXP_B_GPIO4";
+	};
+};
+
 &main_sdhci0 {
 	/* eMMC */
 	status = "okay";
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 04:32:26 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 18:02:26 +0530
Subject: [PATCH v3 2/9] arm64: dts: ti: k3-j784s4-evm: Enable camera peripherals
In-Reply-To: <20240208123233.391115-1-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
Message-ID: <20240208123233.391115-3-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On J784S4 EVM, this is routed
to I2C-5, so enable the instance and the TCA6408 GPIO expander
on the bus.

J784S4 EVM schematics: https://www.ti.com/lit/zip/sprr458

Reviewed-by: Jai Luthra <j-luthra at ti.com>
Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with schematics.

 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 25 ++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
index 57e7cb8ea2b8..bb2558b68381 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -297,6 +297,13 @@ J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */
 		>;
 	};
 
+	main_i2c5_pins_default: main-i2c5-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x01c, PIN_INPUT, 8) /* (AG34) MCAN15_TX.I2C5_SCL */
+			J784S4_IOPAD(0x018, PIN_INPUT, 8) /* (AK36) MCAN14_RX.I2C5_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
@@ -761,6 +768,24 @@ exp2: gpio at 22 {
 	};
 };
 
+&main_i2c5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c5_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	exp5: gpio at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI2_EXP_RSTZ", "CSI2_EXP_A_GPIO0",
+				  "CSI2_EXP_A_GPIO1", "CSI2_EXP_A_GPIO3",
+				  "CSI2_EXP_B_GPIO1", "CSI2_EXP_B_GPIO2",
+				  "CSI2_EXP_B_GPIO3", "CSI2_EXP_B_GPIO4";
+	};
+};
+
 &main_sdhci0 {
 	bootph-all;
 	/* eMMC */
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 04:32:27 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 18:02:27 +0530
Subject: [PATCH v3 3/9] arm64: dts: ti: k3-am68-sk-base-board: Enable camera peripherals
In-Reply-To: <20240208123233.391115-1-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
Message-ID: <20240208123233.391115-4-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On AM68 Starter Kit, this is routed
to I2C-1, so enable the instance and the TCA9543 I2C switch on the bus.

AM68 SK schematics: https://www.ti.com/lit/zip/sprr463

Reviewed-by: Jai Luthra <j-luthra at ti.com>
Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with schematics.

 .../boot/dts/ti/k3-am68-sk-base-board.dts     | 50 +++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
index f48155dd16a3..d743f023cdd9 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
@@ -169,6 +169,13 @@ tfp410_out: endpoint {
 			};
 		};
 	};
+
+	csi_mux: mux-controller {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&exp3 1 GPIO_ACTIVE_HIGH>;
+		idle-state = <0>;
+	};
 };
 
 &main_pmx0 {
@@ -186,6 +193,13 @@ J721S2_IOPAD(0x0e4, PIN_INPUT, 0) /* (AE24) I2C0_SDA */
 		>;
 	};
 
+	main_i2c1_pins_default: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x0ac, PIN_INPUT, 13) /* (AC25) MCASP0_AXR15.I2C1_SCL */
+			J721S2_IOPAD(0x0b0, PIN_INPUT, 13) /* (AD26) MCASP1_AXR3.I2C1_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		pinctrl-single,pins = <
 			J721S2_IOPAD(0x104, PIN_INPUT, 0) /* (P23) MMC1_CLK */
@@ -431,6 +445,42 @@ exp1: gpio at 21 {
 	};
 };
 
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	status = "okay";
+
+	exp3: gpio at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI_VIO_SEL", "CSI_SEL_FPC_EXPn",
+				  "IO_EXP_CSI2_EXP_RSTz","CSI0_B_GPIO1",
+				  "CSI1_B_GPIO1";
+	};
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		cam0_i2c: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		cam1_i2c: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+	};
+};
+
 &main_i2c4 {
 	status = "okay";
 	pinctrl-names = "default";
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 04:32:28 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 18:02:28 +0530
Subject: [PATCH v3 4/9] arm64: dts: ti: k3-am69-sk: Enable camera peripherals
In-Reply-To: <20240208123233.391115-1-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
Message-ID: <20240208123233.391115-5-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On AM69 Starter Kit, this is routed
to I2C-1, so enable the instance, TCA9543 I2C switch and the TCA6408
GPIO expander on the bus. AM69 SK has the CSI2RX routed to a MIPI CSI
connector and to 22-pin RPi camera connector through an analog mux with
GPIO control, model that so that an overlay can control the mux state
according to connected cameras.

AM69 SK schematics: https://www.ti.com/lit/zip/sprr466

Reviewed-by: Jai Luthra <j-luthra at ti.com>
Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with schematics.

 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 51 +++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 5f0a43a69333..46cf90bb3eb8 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -322,6 +322,14 @@ tfp410_out: endpoint {
 			};
 		};
 	};
+
+	csi_mux: mux-controller {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&exp2 1 GPIO_ACTIVE_HIGH>;
+		idle-state = <0>;
+	};
+
 };
 
 &main_pmx0 {
@@ -341,6 +349,13 @@ J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */
 		>;
 	};
 
+	main_i2c1_pins_default: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0ac, PIN_INPUT_PULLUP, 13) /* (AE34) MCASP0_AXR15.I2C1_SCL */
+			J784S4_IOPAD(0x0b0, PIN_INPUT_PULLUP, 13) /* (AL33) MCASP1_AXR3.I2C1_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
@@ -775,6 +790,42 @@ exp1: gpio at 21 {
 	};
 };
 
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	exp2: gpio at 21 {
+		compatible = "ti,tca6408";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI_VIO_SEL", "CSI_MUX_SEL_2", "CSI2_RSTz",
+				  "IO_EXP_CAM0_GPIO1", "IO_EXP_CAM1_GPIO1";
+	};
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		cam0_i2c: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		cam1_i2c: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+	};
+};
+
 &main_sdhci0 {
 	bootph-all;
 	/* eMMC */
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 04:32:29 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 18:02:29 +0530
Subject: [PATCH v3 5/9] arm64: dts: ti: k3-j721e-sk: Model CSI2RX connector mux
In-Reply-To: <20240208123233.391115-1-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
Message-ID: <20240208123233.391115-6-vaishnav.a@ti.com>

J721E SK has the CSI2RX routed to a MIPI CSI connector and to 15-pin
RPi camera connector through an analog mux with GPIO control, model that
so that an overlay can control the mux state according to connected
cameras. Also provide labels to the I2C mux bus instances so that a
generic overlay can be used across multiple platforms.

J721E SK schematics: https://www.ti.com/lit/zip/sprr438

Reviewed-by: Jai Luthra <j-luthra at ti.com>
Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2: Update commit message with schematics.

 arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
index 6950b1ff124f..5dbc85bc5038 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
@@ -286,6 +286,15 @@ tfp410_out: endpoint {
 			};
 		};
 	};
+
+	csi_mux: mux-controller {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&main_gpio0 88 GPIO_ACTIVE_HIGH>;
+		idle-state = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_csi_mux_sel_pins_default>;
+	};
 };
 
 &main_pmx0 {
@@ -352,6 +361,12 @@ J721E_IOPAD(0x214, PIN_OUTPUT, 4) /* (V4) MCAN1_TX.USB1_DRVVBUS */
 		>;
 	};
 
+	main_csi_mux_sel_pins_default: main-csi-mux-sel-default-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x164, PIN_OUTPUT, 7) /* (V29) RGMII5_TD2 */
+		>;
+	};
+
 	dp0_pins_default: dp0-default-pins {
 		pinctrl-single,pins = <
 			J721E_IOPAD(0x1c4, PIN_INPUT, 5) /* SPI0_CS1.DP0_HPD */
@@ -858,14 +873,14 @@ i2c-mux at 70 {
 		reg = <0x70>;
 
 		/* CSI0 I2C */
-		i2c at 0 {
+		cam0_i2c: i2c at 0 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0>;
 		};
 
 		/* CSI1 I2C */
-		i2c at 1 {
+		cam1_i2c: i2c at 1 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <1>;
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 04:32:30 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 18:02:30 +0530
Subject: [PATCH v3 6/9] arm64: dts: ti: k3-j721e-main: Add CSI2RX capture nodes
In-Reply-To: <20240208123233.391115-1-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
Message-ID: <20240208123233.391115-7-vaishnav.a@ti.com>

J721E has two CSI2RX capture subsystem featuring Cadence CSI2RX,
DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
keep them disabled by default.

J721E TRM (Section 12.7 Camera Subsystem):
	https://www.ti.com/lit/zip/spruil1

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V2->V3: Fix order of properties as per dts coding style.
V1->V2: Update commit message with TRM.

 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 122 ++++++++++++++++++++++
 1 file changed, 122 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index 062a6fca5a31..841752d20de1 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -572,6 +572,128 @@ main_timerio_output: pinctrl at 104280 {
 		pinctrl-single,function-mask = <0x0000001f>;
 	};
 
+	ti_csi2rx0: ticsi2rx at 4500000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x0 0x4500000 0x0 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_udmap 0x4940>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 26 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 4504000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x0 0x4504000 0x0 0x1000>;
+			clocks = <&k3_clks 26 2>, <&k3_clks 26 0>, <&k3_clks 26 2>,
+				<&k3_clks 26 2>, <&k3_clks 26 3>, <&k3_clks 26 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx1: ticsi2rx at 4510000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x0 0x4510000 0x0 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_udmap 0x4960>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 27 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx1: csi-bridge at 4514000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x0 0x4514000 0x0 0x1000>;
+			clocks = <&k3_clks 27 2>, <&k3_clks 27 0>, <&k3_clks 27 2>,
+				 <&k3_clks 27 2>, <&k3_clks 27 3>, <&k3_clks 27 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				      "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy1>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi1_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi1_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi1_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi1_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi1_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 4580000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x0 0x4580000 0x0 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy1: phy at 4590000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x0 0x4590000 0x0 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 148 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
 	serdes_wiz0: wiz at 5000000 {
 		compatible = "ti,j721e-wiz-16g";
 		#address-cells = <1>;
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 04:32:31 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 18:02:31 +0530
Subject: [PATCH v3 7/9] arm64: dts: ti: k3-j721s2-main: Add CSI2RX capture nodes
In-Reply-To: <20240208123233.391115-1-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
Message-ID: <20240208123233.391115-8-vaishnav.a@ti.com>

J721S2 has two CSI2RX capture subsystem featuring Cadence CSI2RX,
DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
keep them disabled by default. J721S2 uses a dedicated BCDMA instance
for CSI-RX traffic, so enable that as well.

J721S2 TRM (Section 12.7 Camera Subsystem):
	https://www.ti.com/lit/zip/spruj28

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V2->V3: Fix order of properties as per dts coding style.
V1->V2: Update commit message with TRM.

 arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi | 123 ++++++++++++++++++++-
 1 file changed, 122 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
index dcaa4da0d678..9063aa609993 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -1122,7 +1122,6 @@ main_bcdma_csi: dma-controller at 311a0000 {
 			ti,sci-dev-id = <225>;
 			ti,sci-rm-range-rchan = <0x21>;
 			ti,sci-rm-range-tchan = <0x22>;
-			status = "disabled";
 		};
 
 		cpts at 310d0000 {
@@ -1233,6 +1232,128 @@ usb0: usb at 6000000 {
 		};
 	};
 
+	ti_csi2rx0: ticsi2rx at 4500000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x04500000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x4940 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 38 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 4504000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04504000 0x00 0x1000>;
+			clocks = <&k3_clks 38 3>, <&k3_clks 38 1>, <&k3_clks 38 3>,
+				<&k3_clks 38 3>, <&k3_clks 38 4>, <&k3_clks 38 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx1: ticsi2rx at 4510000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x04510000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x4960 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx1: csi-bridge at 4514000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04514000 0x00 0x1000>;
+			clocks = <&k3_clks 39 3>, <&k3_clks 39 1>, <&k3_clks 39 3>,
+				<&k3_clks 39 3>, <&k3_clks 39 4>, <&k3_clks 39 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy1>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi1_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi1_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi1_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi1_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi1_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 4580000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04580000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy1: phy at 4590000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04590000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
 	serdes_wiz0: wiz at 5060000 {
 		compatible = "ti,j721s2-wiz-10g";
 		#address-cells = <1>;
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 04:32:32 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 18:02:32 +0530
Subject: [PATCH v3 8/9] arm64: dts: ti: k3-j784s4-main: Add CSI2RX capture nodes
In-Reply-To: <20240208123233.391115-1-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
Message-ID: <20240208123233.391115-9-vaishnav.a@ti.com>

J784S4 has three CSI2RX capture subsystem featuring Cadence CSI2RX,
DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
keep them disabled by default. J784S4 uses a dedicated BCDMA instance
for CSI-RX traffic, so enable that as well.

J784S4 TRM (Section 12.7 Camera Subsystem):
	https://www.ti.com/lit/zip/spruj52

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V2->V3: Fix order of properties as per dts coding style.
V1->V2: Update commit message with TRM.

 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 183 ++++++++++++++++++++-
 1 file changed, 182 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
index 3cb964982792..42e4ca1d0b65 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -662,6 +662,188 @@ main_i2c6: i2c at 2060000 {
 		status = "disabled";
 	};
 
+	ti_csi2rx0: ticsi2rx at 4500000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x04500000 0x00 0x00001000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x4940 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 72 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 4504000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04504000 0x00 0x00001000>;
+			clocks = <&k3_clks 72 2>, <&k3_clks 72 0>, <&k3_clks 72 2>,
+				<&k3_clks 72 2>, <&k3_clks 72 3>, <&k3_clks 72 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx1: ticsi2rx at 4510000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x04510000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x4960 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 73 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx1: csi-bridge at 4514000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04514000 0x00 0x00001000>;
+			clocks = <&k3_clks 73 2>, <&k3_clks 73 0>, <&k3_clks 73 2>,
+				<&k3_clks 73 2>, <&k3_clks 73 3>, <&k3_clks 73 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy1>;
+			phy-names = "dphy";
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi1_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi1_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi1_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi1_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi1_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx2: ticsi2rx at 4520000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x04520000 0x00 0x00001000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x4980 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 74 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx2: csi-bridge at 4524000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04524000 0x00 0x00001000>;
+			clocks = <&k3_clks 74 2>, <&k3_clks 74 0>, <&k3_clks 74 2>,
+				<&k3_clks 74 2>, <&k3_clks 74 3>, <&k3_clks 74 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy2>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi2_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi2_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi2_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi2_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi2_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 4580000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04580000 0x00 0x00001100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 212 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy1: phy at 4590000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04590000 0x00 0x00001100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 213 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy2: phy at 45a0000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x045a0000 0x00 0x00001100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 214 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
 	main_sdhci0: mmc at 4f80000 {
 		compatible = "ti,j721e-sdhci-8bit";
 		reg = <0x00 0x04f80000 0x00 0x1000>,
@@ -1224,7 +1406,6 @@ main_bcdma_csi: dma-controller at 311a0000 {
 			ti,sci-dev-id = <281>;
 			ti,sci-rm-range-rchan = <0x21>;
 			ti,sci-rm-range-tchan = <0x22>;
-			status = "disabled";
 		};
 
 		cpts at 310d0000 {
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb  8 04:32:33 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 8 Feb 2024 18:02:33 +0530
Subject: [PATCH v3 9/9] arm64: dts: ti: k3-j721e-sk: Add overlay for IMX219
In-Reply-To: <20240208123233.391115-1-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
Message-ID: <20240208123233.391115-10-vaishnav.a@ti.com>

RPi v2 Camera (IMX219) is an 8MP camera that can be used with SK-AM69,
J721E SK, and AM68 SK through the 22-pin CSI-RX connector.

Add a reference overlay for dual IMX219 RPI camera v2 modules
which can be used across AM68 SK, AM69 SK, TDA4VM SK boards
that have a 15/22-pin FFC connector. Also enable build testing
and symbols for all the three platforms.

Reviewed-by: Jai Luthra <j-luthra at ti.com>
Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2:
 * Rename overlays to indicate first platform (j721e-sk) supported
   and dual camera.
 * Add missed build test, fix missing newline.

 arch/arm64/boot/dts/ti/Makefile               |  13 ++
 .../dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso  | 125 ++++++++++++++++++
 2 files changed, 138 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 4a570dffb638..e019efd3ce94 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -69,6 +69,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi-exp-board.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-dual-imx219.dtbo
 
 # Boards with J721s2 SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board.dtb
@@ -106,8 +107,14 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
+k3-am68-sk-base-board-csi2-dual-imx219-dtbs := k3-am68-sk-base-board.dtb \
+	k3-j721e-sk-csi2-dual-imx219.dtbo
+k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
+	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
 	k3-j721e-evm-pcie0-ep.dtbo
+k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
+	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
 	k3-j721s2-evm-pcie1-ep.dtbo
 dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
@@ -122,7 +129,10 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am62a7-sk-hdmi-audio.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
+	k3-am68-sk-base-board-csi2-dual-imx219-dtbs \
+	k3-am69-sk-csi2-dual-imx219-dtbs \
 	k3-j721e-evm-pcie0-ep.dtb \
+	k3-j721e-sk-csi2-dual-imx219-dtbs \
 	k3-j721s2-evm-pcie1-ep.dtb
 
 # Enable support for device-tree overlays
@@ -132,5 +142,8 @@ DTC_FLAGS_k3-am62-lp-sk += -@
 DTC_FLAGS_k3-am62a7-sk += -@
 DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
 DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
+DTC_FLAGS_k3-am68-sk-base-board += -@
+DTC_FLAGS_k3-am69-sk += -@
 DTC_FLAGS_k3-j721e-common-proc-board += -@
+DTC_FLAGS_k3-j721e-sk += -@
 DTC_FLAGS_k3-j721s2-common-proc-board += -@
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso b/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso
new file mode 100644
index 000000000000..65d7cefb6063
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for dual RPi Camera V2.1 (Sony IMX219) interfaced with CSI2
+ * on J721E SK, AM68 SK or AM69-SK board.
+ * https://datasheets.raspberrypi.org/camera/camera-v2-schematic.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	clk_imx219_fixed: imx219-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&csi_mux {
+	idle-state = <1>;
+};
+
+/* CAM0 I2C */
+&cam0_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	imx219_0: imx219_0 at 10 {
+		compatible = "sony,imx219";
+		reg = <0x10>;
+
+		clocks = <&clk_imx219_fixed>;
+		clock-names = "xclk";
+
+		port {
+			csi2_cam0: endpoint {
+				remote-endpoint = <&csi2rx0_in_sensor>;
+				link-frequencies = /bits/ 64 <456000000>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+/* CAM1 I2C */
+&cam1_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	imx219_1: imx219_1 at 10 {
+		compatible = "sony,imx219";
+		reg = <0x10>;
+
+		clocks = <&clk_imx219_fixed>;
+		clock-names = "xclk";
+
+		port {
+			csi2_cam1: endpoint {
+				remote-endpoint = <&csi2rx1_in_sensor>;
+				link-frequencies = /bits/ 64 <456000000>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port at 0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port at 0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx1_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam1>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&dphy1 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
-- 
2.34.1



From mark.rutland at arm.com  Thu Feb  8 04:38:12 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 8 Feb 2024 12:38:12 +0000
Subject: [PATCH 0/3] arm64: cleanup DAIF handling for EL0 returns
In-Reply-To: <ZcQ8UKRNz0TLvJRB@vm3>
References: <20240206123848.1696480-1-mark.rutland@arm.com>
 <ZcQ8UKRNz0TLvJRB@vm3>
Message-ID: <ZcTLND4GNTFP53Yg@FVFF77S0Q05N.cambridge.arm.com>

On Thu, Feb 08, 2024 at 11:28:32AM +0900, Itaru Kitayama wrote:
> On Tue, Feb 06, 2024 at 12:38:45PM +0000, Mark Rutland wrote:
> > Hi,
> > 
> > These patches rework DAIF handling when returning to EL0, simplifiying
> > the logic in do_notify_resume() and allowing Debug + SError to be
> > unmasked for a little longer during exception return.
> > 
> > My primary motivation for these changes is to centralize entry/exit DAIF
> > management within entry-common.c, as this will allow entry/exit
> > sequences to be specialised, and make it much easier to add support for
> > FEAT_NMI. With specialized entry DAIF management, it will also be
> > possible to simplify local_daif_{save,restore}() and
> > local_irq_{save,restore}().
> > 
> > I'm sending this out on its own as (IMO) it's a nice cleanup on its own,
> > and I don't believe that I'll have the remainder of the DAIF rework
> > ready for this cycle.
> > 
> > The series is based on v6.8-rc3.
> > 
> > Mark.
> > 
> > Mark Rutland (3):
> >   arm64: Simplify do_notify_resume() DAIF masking
> >   arm64: Move do_notify_resume() to entry-common.c
> >   arm64: Unmask Debug + SError in do_notify_resume()
> > 
> >  arch/arm64/include/asm/exception.h |  2 +-
> >  arch/arm64/kernel/entry-common.c   | 36 ++++++++++++++++++++++++++-
> >  arch/arm64/kernel/signal.c         | 39 ++----------------------------
> >  3 files changed, 38 insertions(+), 39 deletions(-)
> 
> Boot tested on RevC FVP and kselftest arm64 subcategory runs without an error
> on RevC FVP too.

Thanks for testing! Would you be happy for that to imply a tested-by tag, e.g.

  Tested-by: Itaru Kitayama <itaru.kitayama at linux.dev>

... ?

Mark.


From maz at kernel.org  Thu Feb  8 04:38:43 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 08 Feb 2024 12:38:43 +0000
Subject: [PATCH v1 0/2] small kern_hyp_va() cleanups
In-Reply-To: <20240208105422.3444159-1-joey.gouly@arm.com>
References: <20240208105422.3444159-1-joey.gouly@arm.com>
Message-ID: <86le7v5dws.wl-maz@kernel.org>

On Thu, 08 Feb 2024 10:54:20 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> Hello,
> 
> I wanted to add some comments to __kern_hyp_va(), since I was recently trying
> to understand it, and I think it could be helpful for someone looking at it in
> the future.
> 
> The second patch removes the assembly macro version, since it is unused. Maybe
> (out-of-tree) pkvm uses it or it's just worth keeping around in case someone
> needs it in the future. So if that patch isn't applied it's not too important.

I checked with Fuad, and he confirmed that there is no assembly code
using kern_hyp_va() left in pKVM either, so this guys is definitely a
goner.

For the series,

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

	M.

-- 
Without deviation from the norm, progress is not possible.


From Jonathan.Cameron at Huawei.com  Thu Feb  8 04:39:46 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 12:39:46 +0000
Subject: [PATCH 6/7] drivers/perf: hisi_pcie: Merge find_related_event()
 and get_event_idx()
In-Reply-To: <20240204074527.47110-7-yangyicong@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
	<20240204074527.47110-7-yangyicong@huawei.com>
Message-ID: <20240208123946.00006618@Huawei.com>

On Sun, 4 Feb 2024 15:45:26 +0800
Yicong Yang <yangyicong at huawei.com> wrote:

> From: Junhao He <hejunhao3 at huawei.com>
> 
> The function xxx_find_related_event() scan all working events to find
> related events. During this process, we also can find the idle counters.
> If not found related events, return the first idle counter to simplify
> the code.
> 
> Signed-off-by: Junhao He <hejunhao3 at huawei.com>
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>

A suggestion inline to avoid the magic HISI_PCIE_MAX_COUNTER value
being used outside of the function. 

> ---
>  drivers/perf/hisilicon/hisi_pcie_pmu.c | 55 ++++++++++----------------
>  1 file changed, 21 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> index 1b45aeb82859..2edde66675e7 100644
> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
> @@ -397,16 +397,24 @@ static u64 hisi_pcie_pmu_read_counter(struct perf_event *event)
>  	return hisi_pcie_pmu_readq(pcie_pmu, event->hw.event_base, idx);
>  }
>  
> -static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
> -					    struct perf_event *event)
> +/*
> + * Check all work events, if a relevant event is found then we return it
> + * first, otherwise return the first idle counter (need to reset).
> + */
> +static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu,
> +					struct perf_event *event)
>  {
> +	int first_idle = HISI_PCIE_MAX_COUNTERS;
	int first_idle = -EAGAIN;
>  	struct perf_event *sibling;
>  	int idx;
>  
>  	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
>  		sibling = pcie_pmu->hw_events[idx];
> -		if (!sibling)
> +		if (!sibling) {
> +			if (first_idle == HISI_PCIE_MAX_COUNTERS)
if (first_idle == -EAGAIN)

> +				first_idle = idx;
>  			continue;
> +		}
>  
>  		/* Related events must be used in group */
>  		if (hisi_pcie_pmu_cmp_event(sibling, event) &&
> @@ -414,19 +422,7 @@ static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
>  			return idx;
>  	}
>  
> -	return idx;
> -}
> -
> -static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu)
> -{
> -	int idx;
> -
> -	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
> -		if (!pcie_pmu->hw_events[idx])
> -			return idx;
> -	}
> -
> -	return -EINVAL;
> +	return first_idle;
Then this will return -EAGAIN;
>  }
>  
>  static void hisi_pcie_pmu_event_update(struct perf_event *event)
> @@ -552,27 +548,18 @@ static int hisi_pcie_pmu_add(struct perf_event *event, int flags)
>  
>  	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
>  
> -	/* Check all working events to find a related event. */
> -	idx = hisi_pcie_pmu_find_related_event(pcie_pmu, event);
> -	if (idx < 0)
> -		return idx;
> -
> -	/* Current event shares an enabled counter with the related event */
> -	if (idx < HISI_PCIE_MAX_COUNTERS) {
> -		hwc->idx = idx;
> -		goto start_count;
> -	}
> -
> -	idx = hisi_pcie_pmu_get_event_idx(pcie_pmu);
> -	if (idx < 0)
> -		return idx;
> +	idx = hisi_pcie_pmu_get_event_idx(pcie_pmu, event);
> +	if (idx == HISI_PCIE_MAX_COUNTERS)
> +		return -EAGAIN;

Perhaps simpler to handle first_idle == HISI_PCIE_MAX_COUNTERS as
an error return in hisi_pcie_pmu_get_event_idx - see above.

 	if (idx < 0)
		return idx;


>  
>  	hwc->idx = idx;
> -	pcie_pmu->hw_events[idx] = event;
> -	/* Reset Counter to avoid previous statistic interference. */
> -	hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
>  
> -start_count:
> +	/* No enabled counter found with related event, reset it */
> +	if (!pcie_pmu->hw_events[idx]) {
> +		hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
> +		pcie_pmu->hw_events[idx] = event;
> +	}
> +
>  	if (flags & PERF_EF_START)
>  		hisi_pcie_pmu_start(event, PERF_EF_RELOAD);
>  



From semen.protsenko at linaro.org  Thu Feb  8 04:41:10 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 8 Feb 2024 06:41:10 -0600
Subject: [PATCH] arm64: dts: exynos: gs101: minor whitespace cleanup
In-Reply-To: <20240208105243.128875-1-krzysztof.kozlowski@linaro.org>
References: <20240208105243.128875-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CAPLW+4n5LqENFgUZYDb2rF+Db59Ry4tdAfKLiL-W-ZG6mP=kjw@mail.gmail.com>

On Thu, Feb 8, 2024 at 4:55?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> The DTS code coding style expects exactly one space before '{' and
> around '=' characters.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---

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

>  .../boot/dts/exynos/google/gs101-pinctrl.dtsi    |  2 +-
>  arch/arm64/boot/dts/exynos/google/gs101.dtsi     | 16 ++++++++--------
>  2 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
> index e6a9776d4d62..a675f822acec 100644
> --- a/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
> +++ b/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
> @@ -251,7 +251,7 @@ gph1: gph1-gpio-bank {
>                 #interrupt-cells = <2>;
>         };
>
> -       pcie0_clkreq: pcie0-clkreq-pins{
> +       pcie0_clkreq: pcie0-clkreq-pins {
>                 samsung,pins = "gph0-1";
>                 samsung,pin-function = <GS101_PIN_FUNC_2>;
>                 samsung,pin-pud = <GS101_PIN_PULL_UP>;
> diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> index c7a9e81d23b9..80cc933cca3d 100644
> --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
> @@ -73,7 +73,7 @@ cpu0: cpu at 0 {
>                         compatible = "arm,cortex-a55";
>                         reg = <0x0000>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
> +                       cpu-idle-states = <&ANANKE_CPU_SLEEP>;
>                         capacity-dmips-mhz = <250>;
>                         dynamic-power-coefficient = <70>;
>                 };
> @@ -83,7 +83,7 @@ cpu1: cpu at 100 {
>                         compatible = "arm,cortex-a55";
>                         reg = <0x0100>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
> +                       cpu-idle-states = <&ANANKE_CPU_SLEEP>;
>                         capacity-dmips-mhz = <250>;
>                         dynamic-power-coefficient = <70>;
>                 };
> @@ -93,7 +93,7 @@ cpu2: cpu at 200 {
>                         compatible = "arm,cortex-a55";
>                         reg = <0x0200>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
> +                       cpu-idle-states = <&ANANKE_CPU_SLEEP>;
>                         capacity-dmips-mhz = <250>;
>                         dynamic-power-coefficient = <70>;
>                 };
> @@ -103,7 +103,7 @@ cpu3: cpu at 300 {
>                         compatible = "arm,cortex-a55";
>                         reg = <0x0300>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ANANKE_CPU_SLEEP>;
> +                       cpu-idle-states = <&ANANKE_CPU_SLEEP>;
>                         capacity-dmips-mhz = <250>;
>                         dynamic-power-coefficient = <70>;
>                 };
> @@ -113,7 +113,7 @@ cpu4: cpu at 400 {
>                         compatible = "arm,cortex-a76";
>                         reg = <0x0400>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ENYO_CPU_SLEEP>;
> +                       cpu-idle-states = <&ENYO_CPU_SLEEP>;
>                         capacity-dmips-mhz = <620>;
>                         dynamic-power-coefficient = <284>;
>                 };
> @@ -123,7 +123,7 @@ cpu5: cpu at 500 {
>                         compatible = "arm,cortex-a76";
>                         reg = <0x0500>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&ENYO_CPU_SLEEP>;
> +                       cpu-idle-states = <&ENYO_CPU_SLEEP>;
>                         capacity-dmips-mhz = <620>;
>                         dynamic-power-coefficient = <284>;
>                 };
> @@ -133,7 +133,7 @@ cpu6: cpu at 600 {
>                         compatible = "arm,cortex-x1";
>                         reg = <0x0600>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&HERA_CPU_SLEEP>;
> +                       cpu-idle-states = <&HERA_CPU_SLEEP>;
>                         capacity-dmips-mhz = <1024>;
>                         dynamic-power-coefficient = <650>;
>                 };
> @@ -143,7 +143,7 @@ cpu7: cpu at 700 {
>                         compatible = "arm,cortex-x1";
>                         reg = <0x0700>;
>                         enable-method = "psci";
> -                       cpu-idle-states =  <&HERA_CPU_SLEEP>;
> +                       cpu-idle-states = <&HERA_CPU_SLEEP>;
>                         capacity-dmips-mhz = <1024>;
>                         dynamic-power-coefficient = <650>;
>                 };
> --
> 2.34.1
>
>


From maz at kernel.org  Thu Feb  8 04:42:25 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 08 Feb 2024 12:42:25 +0000
Subject: [PATCH v1 2/2] KVM: arm64: removed unused kern_hyp_va asm macro
In-Reply-To: <20240208105422.3444159-3-joey.gouly@arm.com>
References: <20240208105422.3444159-1-joey.gouly@arm.com>
	<20240208105422.3444159-3-joey.gouly@arm.com>
Message-ID: <86jznf5dqm.wl-maz@kernel.org>

On Thu, 08 Feb 2024 10:54:22 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> The last usage of this macro was removed in:
>     commit 5dc33bd199ca ("KVM: arm64: nVHE: Pass pointers consistently to hyp-init")
> 
> Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oliver.upton at linux.dev>
> ---
>  arch/arm64/include/asm/kvm_mmu.h | 21 ---------------------
>  1 file changed, 21 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index d248a7ae627a..961d4431654b 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -53,27 +53,6 @@
>  
>  #include <asm/alternative.h>
>  
> -/*
> - * Convert a kernel VA into a HYP VA.
> - * reg: VA to be converted.
> - *
> - * The actual code generation takes place in kvm_update_va_mask, and
> - * the instructions below are only there to reserve the space and
> - * perform the register allocation (kvm_update_va_mask uses the
> - * specific registers encoded in the instructions).

Consider moving this comment to the C version instead of deleting it
completely (the part about the register allocation is pretty crucial).

Oliver can probably fix this when applying it, and my previous Ack
still stands.

	M.

-- 
Without deviation from the norm, progress is not possible.


From maciej.fijalkowski at intel.com  Thu Feb  8 04:46:03 2024
From: maciej.fijalkowski at intel.com (Maciej Fijalkowski)
Date: Thu, 8 Feb 2024 13:46:03 +0100
Subject: [PATCH net-next] net: stmmac: Simplify mtl IRQ status checking
In-Reply-To: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>
References: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>
Message-ID: <ZcTNCxrWTAfj90Es@boxer>

On Thu, Feb 08, 2024 at 11:35:25AM +0100, Kurt Kanzenbach wrote:
> Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO overflow
> interrupts") disabled the RX FIFO overflow interrupts. However, it left the
> status variable around, but never checks it.
> 
> As stmmac_host_mtl_irq_status() returns only 0 now, the code can be
> simplified.
> 
> Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
> ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 04d817dc5899..10ce2f272b62 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -6036,10 +6036,8 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv)
>  				priv->tx_path_in_lpi_mode = false;
>  		}
>  
> -		for (queue = 0; queue < queues_count; queue++) {
> -			status = stmmac_host_mtl_irq_status(priv, priv->hw,
> -							    queue);
> -		}
> +		for (queue = 0; queue < queues_count; queue++)
> +			stmmac_host_mtl_irq_status(priv, priv->hw, queue);

Hey Kurt,

looks to me that all of the current callbacks just return 0 so why not
make them return void instead?

>  
>  		/* PCS link status */
>  		if (priv->hw->pcs &&
> 
> ---
> base-commit: 006e89649fa913e285b931f1b8dfd6485d153ca7
> change-id: 20240208-stmmac_irq-57682fa778c9
> 
> Best regards,
> -- 
> Kurt Kanzenbach <kurt at linutronix.de>
> 
> 


From devarsht at ti.com  Thu Feb  8 04:56:17 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Thu, 8 Feb 2024 18:26:17 +0530
Subject: [RFC PATCH 2/3] drm/tidss: Add support for display sharing
In-Reply-To: <vgfzhamtiwkpdyk5ndagsb63subclinotoe6tsi3wu6z7454ec@igxfzjc5gyqm>
References: <20240116134142.2092483-1-devarsht@ti.com>
 <20240116134142.2092483-3-devarsht@ti.com>
 <vgfzhamtiwkpdyk5ndagsb63subclinotoe6tsi3wu6z7454ec@igxfzjc5gyqm>
Message-ID: <88018f5f-a7db-7278-e5c3-bb1dbf0e3f14@ti.com>

Hi Maxime,

Thanks a lot for checking on this.

On 26/01/24 17:45, Maxime Ripard wrote:
> Hi,
> 
> Thanks a lot for working on that.
> 
> On Tue, Jan 16, 2024 at 07:11:41PM +0530, Devarsh Thakkar wrote:
>> Display subsystem present in TI Keystone family of devices supports sharing
>> of display between multiple hosts as it provides separate register space
>> (common* region) for each host to programming display controller and also a
>> unique interrupt line for each host.
>>
>> This adds support for display sharing, by allowing partitioning of
>> resources either at video port level or at video plane level as
>> described below :
>>
>> 1) Linux can own (i.e have write access) completely one or more of video
>> ports along with corresponding resources (viz. overlay managers,
>> video planes) used by Linux in context of those video ports.
>> Even if Linux is owning
>> these video ports it can still share this video port with a remote core
>> which can own one or more video planes associated with this video port.
>>
>> 2) Linux owns one or more of the video planes with video port
>> (along with corresponding overlay manager) associated with these planes
>> being owned and controlled by a remote core. Linux still has read-only
>> access to the associated video port and overlay managers so that it can
>> parse the settings made by remote core.
> 
> So, just to make sure we're on the same page. 1) means Linux drives the
> whole display engine, but can lend planes to the R5? How does that work,
> is Linux aware of the workload being there (plane size, format, etc) ?
> 

Well, there is no dynamic procedure being followed for lending. The
partitioning scheme is decided and known before hand, and the remote
core firmware updated and compiled accordingly, and similarly the
device-tree overlay for Linux is also updated with partitioning
information before bootup.

What would happen here is that Linux will know before-hand this
partitioning information via device-tree properties and won't enumerate
the plane owned by RTOS, but it will enumerate the rest of the display
components and initialize the DSS, after which user can load the DSS
firmware on remote core and this firmware will only have control of
plane as it was compiled with that configuration.


> And 2) would mean that the display engine is under the R5 control and
> Linux only gets to fill the plane and let the firmware know of what it
> wants?
> 

Here too the partitioning information is pre-decided and remote core
firmware and device-tree overlay for Linux updated accordingly. But in
this case as remote core firmware owns the display (minus the plane
owned by Linux) it is started and initialized during the bootloader
phase itself where it initializes the DSS and starts rendering using the
plane owned by it and Linux just latches to the DSS without
re-initializing it, with write access only to the plane that is owned by
Linux. You can refer [1] for more details on this.


> If so, do we even need the tidss driver in the second case? We could
> just write a fwkms driver of some sorts that could be used by multiple
> implementations of the same "defer to firmware" logic.
> 

This feature of static partitioning of DSS resources is specific to DSS7
hardware (which is controlled by tidss driver) which supports dedicated
register space and interrupt line for each of the hosts [0], so that
multiple hosts can drive the display controller simultaneously as  per
the desired static partitioning of resources, and so I don't think a
separate driver is required here and tidss seems the right place to
support this, where using this device-tree approach different resource
partitioning schemas can be achieved as described here [1]. This was
also aligned with Tomi too where we discussed that tidss is the right
place to support this as we are simply leveraging the DSS hardware
capabilities of static partitioning here.


>> For both the cases, the resources used in context of processing core
>> running Linux along with ownership information are exposed by user as
>> part of device-tree blob and driver uses an updated feature list tailored
>> for this shared mode accordingly. The driver also auto-populates
>> matching overlay managers and output types from shared video
>> port list provided in device-tree blob.
>> In dispc_feature struct remove const access specfier for output_type
>> array as it is required to be updated dynamically in run-time for shared
>> mode.
> 
> I'm also not entirely sure that the device tree is the right path there.
> Surely the firmware capabilities will evolve over time, while the device
> tree won't. Is there some way to make it discoverable at probe time by
> the driver?
> 

I think the main highlight of the sharing feature is the hardware
capability where each host is provided separate irq and register space
to program display for their display context independently and without
any sort of inter-processor communication and the current implementation
just mirrors by specifying the display context information in the form
of device-tree properties instead of relying on any inter-processor
communication or negotiation phase.

Having said that, for the second case Linux still has read access to
display registers which can be read to infer some of the display
configuration set by the RTOS and we are infact using that to infer some
of the context like for e.g. what was the display mode set by RTOS, but
we don't want to rely completely on register reads of RTOS programmed
registers to gather full information regarding partitioning or even to
infer that we are in sharing mode.

The remote core firmware is compiled with the partitioning information
known before-hand and same is fed in the form of DT properties to Linux
and this looks much cleaner, simple and reliable to us.

But yes we wanted to support firmwares with different partitioning
schemes/capabilities as you said and so the tidss-shared-mode
device-tree properties were designed keeping in mind that they should be
adequate and flexible enough to define all different partition schemes
which can be supported, this is also demonstrated with an example here [1]

[0]:
https://software-dl.ti.com/processor-sdk-linux/esd/AM62PX/09_01_00_08/exports/docs/linux/Foundational_Components/Kernel/Kernel_Drivers/Display/DSS7.html#soc-hardware-description


[1]:
https://software-dl.ti.com/processor-sdk-linux/esd/AM62PX/09_01_00_08/exports/docs/linux/How_to_Guides/Target/How_to_enable_display_sharing_between_remotecore_and_Linux.html


Regards
Devarsh


> Maxime


From will at kernel.org  Thu Feb  8 04:58:47 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 8 Feb 2024 12:58:47 +0000
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
Message-ID: <20240208125846.GA23290@willie-the-truck>

On Fri, Feb 02, 2024 at 10:28:05AM -0400, Jason Gunthorpe wrote:
> If the SMMU is configured to use a two level CD table then
> arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
> GFP_KERNEL. Due to recent changes this is being done under a spinlock to
> iterate over the device list - thus it will trigger a sleeping while
> atomic warning:
> 
>   arm_smmu_sva_set_dev_pasid()
>     mutex_lock(&sva_lock);
>     __arm_smmu_sva_bind()
>      arm_smmu_mmu_notifier_get()
>       spin_lock_irqsave()
>       arm_smmu_write_ctx_desc()
> 	arm_smmu_get_cd_ptr()
>          arm_smmu_alloc_cd_leaf_table()
> 	  dmam_alloc_coherent(GFP_KERNEL)
> 
> This is a 64K high order allocation and really should not be done
> atomically.
> 
> The proper answer is to sequence CD programming in a way that does not
> require the device list or a spinlock. Part two of my lager series does
> this and already solves this bug.
> 
> In the mean time we can solve the functional issue by preallocating the CD
> entry outside any locking. CD leafs are effectively never freed so this
> guarantees the arm_smmu_write_ctx_desc() inside the lock will not take the
> allocation path.
> 
> Fixes: 24503148c545 ("iommu/arm-smmu-v3: Refactor write_ctx_desc")
> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> Closes: https://lore.kernel.org/all/4e25d161-0cf8-4050-9aa3-dfa21cd63e56 at moroto.mountain/
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 5 +++++
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c     | 2 +-
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h     | 2 ++
>  3 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> index 05722121f00e70..068d60732e6481 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> @@ -588,6 +588,11 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
>  {
>  	int ret = 0;
>  	struct mm_struct *mm = domain->mm;
> +	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> +
> +	/* Preallocate the required leafs outside locks */
> +	if (!arm_smmu_get_cd_ptr(master, id))
> +		return -ENOMEM;

What guarantees that all the masters in the domain share the same l2 CD
table? The only reason we need the spinlock is to walk over the device
list, so if that's not necessary then we could push this down into
arm_smmu_mmu_notifier_get().

Will


From catalin.marinas at arm.com  Thu Feb  8 05:00:59 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 13:00:59 +0000
Subject: [PATCH v6 1/4] kvm: arm64: introduce new flag for non-cacheable
 IO memory
In-Reply-To: <20240207204652.22954-2-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-2-ankita@nvidia.com>
Message-ID: <ZcTQi0wWZgvl05LB@arm.com>

On Thu, Feb 08, 2024 at 02:16:49AM +0530, ankita at nvidia.com wrote:
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index c651df904fe3..2a893724ee9b 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -717,15 +717,28 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
>  static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
>  				kvm_pte_t *ptep)
>  {
> -	bool device = prot & KVM_PGTABLE_PROT_DEVICE;
> -	kvm_pte_t attr = device ? KVM_S2_MEMATTR(pgt, DEVICE_nGnRE) :
> -			    KVM_S2_MEMATTR(pgt, NORMAL);
> +	kvm_pte_t attr;
>  	u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS;
>  
> +	switch (prot & (KVM_PGTABLE_PROT_DEVICE |
> +			KVM_PGTABLE_PROT_NORMAL_NC)) {
> +	case 0:
> +		attr = KVM_S2_MEMATTR(pgt, NORMAL);
> +		break;
> +	case KVM_PGTABLE_PROT_DEVICE:
> +		if (prot & KVM_PGTABLE_PROT_X)
> +			return -EINVAL;
> +		attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
> +		break;
> +	case KVM_PGTABLE_PROT_NORMAL_NC:
> +		attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
> +		break;

Does it make sense to allow executable here as well? I don't think it's
harmful but not sure there's a use-case for it either.

> +	default:
> +		WARN_ON_ONCE(1);

Return -EINVAL?

-- 
Catalin


From lee at kernel.org  Thu Feb  8 05:02:13 2024
From: lee at kernel.org (Lee Jones)
Date: Thu, 08 Feb 2024 13:02:13 +0000
Subject: (subset) [PATCH v2] dt-bindings: mfd: syscon: Add
 ti,j784s4-pcie-ctrl compatible
In-Reply-To: <20240204090336.3209063-1-s-vadapalli@ti.com>
References: <20240204090336.3209063-1-s-vadapalli@ti.com>
Message-ID: <170739733329.994918.10245368447305915989.b4-ty@kernel.org>

On Sun, 04 Feb 2024 14:33:36 +0530, Siddharth Vadapalli wrote:
> The PCIE_CTRL registers within the CTRL_MMR space of TI's J784S4 SoC
> are used to configure the link speed, lane count and mode of operation
> of the respective PCIe instance. Add compatible for allowing the PCIe
> driver to obtain a regmap for the PCIE_CTRL register within the System
> Controller device-tree node in order to configure the PCIe instance
> accordingly.
> 
> [...]

Applied, thanks!

[1/1] dt-bindings: mfd: syscon: Add ti,j784s4-pcie-ctrl compatible
      commit: 90ba55d8e3bce146a7368d271cea1b7a1d0643bb

--
Lee Jones [???]



From catalin.marinas at arm.com  Thu Feb  8 05:03:27 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 13:03:27 +0000
Subject: [PATCH v6 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <20240207204652.22954-3-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-3-ankita@nvidia.com>
Message-ID: <ZcTRH1rzfPbuQ_qj@arm.com>

On Thu, Feb 08, 2024 at 02:16:50AM +0530, ankita at nvidia.com wrote:
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index f5a97dec5169..884c068a79eb 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -391,6 +391,20 @@ extern unsigned int kobjsize(const void *objp);
>  # define VM_UFFD_MINOR		VM_NONE
>  #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
>  
> +/*
> + * This flag is used to connect VFIO to arch specific KVM code. It
> + * indicates that the memory under this VMA is safe for use with any
> + * non-cachable memory type inside KVM. Some VFIO devices, on some
> + * platforms, are thought to be unsafe and can cause machine crashes if
> + * KVM does not lock down the memory type.
> + */
> +#ifdef CONFIG_64BIT
> +#define VM_VFIO_ALLOW_WC_BIT	39
> +#define VM_VFIO_ALLOW_WC	BIT(VM_VFIO_ALLOW_WC_BIT)
> +#else
> +#define VM_VFIO_ALLOW_WC	VM_NONE
> +#endif

Adding David Hildenbrand to this thread as well since we briefly
discussed potential alternatives (not sure we came to any conclusion).

-- 
Catalin


From miguel.luis at oracle.com  Thu Feb  8 05:06:52 2024
From: miguel.luis at oracle.com (Miguel Luis)
Date: Thu, 8 Feb 2024 13:06:52 +0000
Subject: [PATCH v4 04/10] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1
In-Reply-To: <20240122181344.258974-5-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
 <20240122181344.258974-5-maz@kernel.org>
Message-ID: <FFB5BF90-BD6C-489B-BDBF-78FC6D529262@oracle.com>

Hi Marc,

> On 22 Jan 2024, at 17:13, Marc Zyngier <maz at kernel.org> wrote:
> 
> ARMv9.5 has infroduced ID_AA64MMFR4_EL1 with a bunch of new features.
> Add the corresponding layout.
> 
> This is extracted from the public ARM SysReg_xml_A_profile-2023-09
> delivery, timestamped d55f5af8e09052abe92a02adf820deea2eaed717.
> 
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
> arch/arm64/tools/sysreg | 37 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 37 insertions(+)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 4c9b67934367..fa3fe0856880 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -1791,6 +1791,43 @@ UnsignedEnum 3:0 TCRX
> EndEnum
> EndSysreg
> 
> +Sysreg ID_AA64MMFR4_EL1 3 0 0 7 4
> +Res0 63:40
> +UnsignedEnum 39:36 E3DSE
> + 0b0000 NI
> + 0b0001 IMP
> +EndEnum
> +Res0 35:28
> +SignedEnum 27:24 E2H0
> + 0b0000 IMP
> + 0b1110 NI_NV1
> + 0b1111 NI
> +EndEnum
> +UnsignedEnum 23:20 NV_frac
> + 0b0000 NV_NV2
> + 0b0001 NV2_ONLY
> +EndEnum
> +UnsignedEnum 19:16 FGWTE3
> + 0b0000 NI
> + 0b0001 IMP
> +EndEnum
> +UnsignedEnum 15:12 HACDBS
> + 0b0000 NI
> + 0b0001 IMP
> +EndEnum
> +UnsignedEnum 11:8 ASID2
> + 0b0000 NI
> + 0b0001 IMP
> +EndEnum
> +SignedEnum 7:4 EIESB
> + 0b0000 NI
> + 0b0001 ToEL3
> + 0b0010 ToELx
> + 0b1111 ANY
> +EndEnum
> +Res0 3:0
> +EndSysreg
> +

Reviewed-by: Miguel Luis <miguel.luis at oracle.com>

Would you please help me understand how the kernel would cope with E2H0?s
0b0000  value on systems prior to ARMv9.5 where a read to
ID_AA64MMFR4_EL1 would be RES0 ?

Thanks

Miguel

> Sysreg SCTLR_EL1 3 0 1 0 0
> Field 63 TIDCP
> Field 62 SPINTMASK
> -- 
> 2.39.2
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From jonathanh at nvidia.com  Thu Feb  8 05:11:16 2024
From: jonathanh at nvidia.com (Jon Hunter)
Date: Thu, 8 Feb 2024 13:11:16 +0000
Subject: [PATCH net v4] net: stmmac: xgmac: fix handling of DPP safety
 error for DMA channels
In-Reply-To: <20240208095348.GA1435458@kernel.org>
References: <20240203051439.1127090-1-0x1207@gmail.com>
 <c25eb595-8d91-40ea-9f52-efa15ebafdbc@nvidia.com>
 <20240208092627.GP1297511@kernel.org> <20240208095348.GA1435458@kernel.org>
Message-ID: <d46a4d9c-7253-4318-90b7-08646493e7db@nvidia.com>


On 08/02/2024 09:53, Simon Horman wrote:
> On Thu, Feb 08, 2024 at 09:26:27AM +0000, Simon Horman wrote:
>> On Wed, Feb 07, 2024 at 11:56:26AM +0000, Jon Hunter wrote:
>>>
>>> On 03/02/2024 05:14, Furong Xu wrote:
>>>> Commit 56e58d6c8a56 ("net: stmmac: Implement Safety Features in
>>>> XGMAC core") checks and reports safety errors, but leaves the
>>>> Data Path Parity Errors for each channel in DMA unhandled at all, lead to
>>>> a storm of interrupt.
>>>> Fix it by checking and clearing the DMA_DPP_Interrupt_Status register.
>>>>
>>>> Fixes: 56e58d6c8a56 ("net: stmmac: Implement Safety Features in XGMAC core")
>>>> Signed-off-by: Furong Xu <0x1207 at gmail.com>
>>>> Reviewed-by: Simon Horman <horms at kernel.org>
>>>> Reviewed-by: Serge Semin <fancer.lancer at gmail.com>
>>>> ---
>>>> Changes in v4:
>>>>    - fix a typo name of DDPP bit, thanks Serge Semin
>>>>
>>>> Changes in v3:
>>>>    - code style fix, thanks Paolo Abeni
>>>>
>>>> Changes in v2:
>>>>     - explicit enable Data Path Parity Protection
>>>>     - add new counters to stmmac_safety_stats
>>>>     - add detailed log
>>>> ---
>>>>    drivers/net/ethernet/stmicro/stmmac/common.h  |  1 +
>>>>    .../net/ethernet/stmicro/stmmac/dwxgmac2.h    |  3 +
>>>>    .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 57 ++++++++++++++++++-
>>>>    3 files changed, 60 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
>>>> index 721c1f8e892f..b4f60ab078d6 100644
>>>> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
>>>> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
>>>> @@ -216,6 +216,7 @@ struct stmmac_safety_stats {
>>>>    	unsigned long mac_errors[32];
>>>>    	unsigned long mtl_errors[32];
>>>>    	unsigned long dma_errors[32];
>>>> +	unsigned long dma_dpp_errors[32];
>>>>    };
>>>>    /* Number of fields in Safety Stats */
>>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
>>>> index 207ff1799f2c..5c67a3f89f08 100644
>>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
>>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
>>>> @@ -303,6 +303,8 @@
>>>>    #define XGMAC_RXCEIE			BIT(4)
>>>>    #define XGMAC_TXCEIE			BIT(0)
>>>>    #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
>>>> +#define XGMAC_MTL_DPP_CONTROL		0x000010e0
>>>> +#define XGMAC_DPP_DISABLE		BIT(0)
>>>>    #define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
>>>>    #define XGMAC_TQS			GENMASK(25, 16)
>>>>    #define XGMAC_TQS_SHIFT			16
>>>> @@ -385,6 +387,7 @@
>>>>    #define XGMAC_DCEIE			BIT(1)
>>>>    #define XGMAC_TCEIE			BIT(0)
>>>>    #define XGMAC_DMA_ECC_INT_STATUS	0x0000306c
>>>> +#define XGMAC_DMA_DPP_INT_STATUS	0x00003074
>>>>    #define XGMAC_DMA_CH_CONTROL(x)		(0x00003100 + (0x80 * (x)))
>>>>    #define XGMAC_SPH			BIT(24)
>>>>    #define XGMAC_PBLx8			BIT(16)
>>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>>>> index eb48211d9b0e..04d7c4dc2e35 100644
>>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>>>> @@ -830,6 +830,43 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
>>>>    	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
>>>>    };
>>>> +static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
>>>> +static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
>>>> +static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
>>>> +	{ true, "TDPES0", dpp_tx_err },
>>>> +	{ true, "TDPES1", dpp_tx_err },
>>>> +	{ true, "TDPES2", dpp_tx_err },
>>>> +	{ true, "TDPES3", dpp_tx_err },
>>>> +	{ true, "TDPES4", dpp_tx_err },
>>>> +	{ true, "TDPES5", dpp_tx_err },
>>>> +	{ true, "TDPES6", dpp_tx_err },
>>>> +	{ true, "TDPES7", dpp_tx_err },
>>>> +	{ true, "TDPES8", dpp_tx_err },
>>>> +	{ true, "TDPES9", dpp_tx_err },
>>>> +	{ true, "TDPES10", dpp_tx_err },
>>>> +	{ true, "TDPES11", dpp_tx_err },
>>>> +	{ true, "TDPES12", dpp_tx_err },
>>>> +	{ true, "TDPES13", dpp_tx_err },
>>>> +	{ true, "TDPES14", dpp_tx_err },
>>>> +	{ true, "TDPES15", dpp_tx_err },
>>>> +	{ true, "RDPES0", dpp_rx_err },
>>>> +	{ true, "RDPES1", dpp_rx_err },
>>>> +	{ true, "RDPES2", dpp_rx_err },
>>>> +	{ true, "RDPES3", dpp_rx_err },
>>>> +	{ true, "RDPES4", dpp_rx_err },
>>>> +	{ true, "RDPES5", dpp_rx_err },
>>>> +	{ true, "RDPES6", dpp_rx_err },
>>>> +	{ true, "RDPES7", dpp_rx_err },
>>>> +	{ true, "RDPES8", dpp_rx_err },
>>>> +	{ true, "RDPES9", dpp_rx_err },
>>>> +	{ true, "RDPES10", dpp_rx_err },
>>>> +	{ true, "RDPES11", dpp_rx_err },
>>>> +	{ true, "RDPES12", dpp_rx_err },
>>>> +	{ true, "RDPES13", dpp_rx_err },
>>>> +	{ true, "RDPES14", dpp_rx_err },
>>>> +	{ true, "RDPES15", dpp_rx_err },
>>>> +};
>>>> +
>>>>    static void dwxgmac3_handle_dma_err(struct net_device *ndev,
>>>>    				    void __iomem *ioaddr, bool correctable,
>>>>    				    struct stmmac_safety_stats *stats)
>>>> @@ -841,6 +878,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev,
>>>>    	dwxgmac3_log_error(ndev, value, correctable, "DMA",
>>>>    			   dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats);
>>>> +
>>>> +	value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS);
>>>> +	writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS);
>>>> +
>>>> +	dwxgmac3_log_error(ndev, value, false, "DMA_DPP",
>>>> +			   dwxgmac3_dma_dpp_errors,
>>>> +			   STAT_OFF(dma_dpp_errors), stats);
>>>>    }
>>>>    static int
>>>> @@ -881,6 +925,12 @@ dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp,
>>>>    	value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */
>>>>    	writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL);
>>>> +	/* 5. Enable Data Path Parity Protection */
>>>> +	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
>>>> +	/* already enabled by default, explicit enable it again */
>>>> +	value &= ~XGMAC_DPP_DISABLE;
>>>> +	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);
>>>> +
>>>>    	return 0;
>>>>    }
>>>> @@ -914,7 +964,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev,
>>>>    		ret |= !corr;
>>>>    	}
>>>> -	err = dma & (XGMAC_DEUIS | XGMAC_DECIS);
>>>> +	/* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in
>>>> +	 * DMA_Safety_Interrupt_Status, so we handle DMA Data Path
>>>> +	 * Parity Errors here
>>>> +	 */
>>>> +	err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS);
>>>>    	corr = dma & XGMAC_DECIS;
>>>>    	if (err) {
>>>>    		dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats);
>>>> @@ -930,6 +984,7 @@ static const struct dwxgmac3_error {
>>>>    	{ dwxgmac3_mac_errors },
>>>>    	{ dwxgmac3_mtl_errors },
>>>>    	{ dwxgmac3_dma_errors },
>>>> +	{ dwxgmac3_dma_dpp_errors },
>>>>    };
>>>>    static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats,
>>>
>>>
>>> This change is breaking the build on some of our builders that are still using GCC 6.x ...
>>>
>>> drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:836:20: error: initialiser element is not constant
>>>    { true, "TDPES0", dpp_tx_err },
>>>                      ^~~~~~~~~~
>>> drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:836:20: note: (near initialisation for ?dwxgmac3_dma_dpp_errors[0].detailed_desc?)
>>> drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:837:20: error: initialiser element is not constant
>>>    { true, "TDPES1", dpp_tx_err },
>>>                      ^~~~~~~~~~
>>> drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c:837:20: note: (near initialisation for ?dwxgmac3_dma_dpp_errors[1].detailed_desc?)
>>> ...
>>>
>>> I know that this is quite old but the minimum supported by the kernel is v5.1 ...
>>>
>>> https://www.kernel.org/doc/html/next/process/changes.html
>>
>> Thanks Jon,
>>
>> I separately received a notification about this occurring with gcc 7.
>>
>> https://lore.kernel.org/oe-kbuild-all/202402081135.lAxxBXHk-lkp at intel.com/
>>
>> It is unclear to me why this occurs, as dpp_tx_err and dpp_tx_err are const.
>> But I do seem to be able to address this problem by using #defines for
>> these values instead.
>>
>> I plan to post a patch shortly.
> 
> Patch posted:
> - [PATCH net] net: stmmac: xgmac: use #define for string constants
>    https://lore.kernel.org/netdev/20240208-xgmac-const-v1-1-e69a1eeabfc8 at kernel.org/
> 


Thanks for fixing! Works for me.

Jon

-- 
nvpublic


From maz at kernel.org  Thu Feb  8 05:15:27 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 08 Feb 2024 13:15:27 +0000
Subject: [PATCH v4 04/10] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1
In-Reply-To: <FFB5BF90-BD6C-489B-BDBF-78FC6D529262@oracle.com>
References: <20240122181344.258974-1-maz@kernel.org>
	<20240122181344.258974-5-maz@kernel.org>
	<FFB5BF90-BD6C-489B-BDBF-78FC6D529262@oracle.com>
Message-ID: <86il2z5c7k.wl-maz@kernel.org>

On Thu, 08 Feb 2024 13:06:52 +0000,
Miguel Luis <miguel.luis at oracle.com> wrote:
> 
> Hi Marc,
> 
> > On 22 Jan 2024, at 17:13, Marc Zyngier <maz at kernel.org> wrote:
> > 
> > ARMv9.5 has infroduced ID_AA64MMFR4_EL1 with a bunch of new features.
> > Add the corresponding layout.
> > 
> > This is extracted from the public ARM SysReg_xml_A_profile-2023-09
> > delivery, timestamped d55f5af8e09052abe92a02adf820deea2eaed717.
> > 
> > Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> > arch/arm64/tools/sysreg | 37 +++++++++++++++++++++++++++++++++++++
> > 1 file changed, 37 insertions(+)
> > 
> > diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> > index 4c9b67934367..fa3fe0856880 100644
> > --- a/arch/arm64/tools/sysreg
> > +++ b/arch/arm64/tools/sysreg
> > @@ -1791,6 +1791,43 @@ UnsignedEnum 3:0 TCRX
> > EndEnum
> > EndSysreg
> > 
> > +Sysreg ID_AA64MMFR4_EL1 3 0 0 7 4
> > +Res0 63:40
> > +UnsignedEnum 39:36 E3DSE
> > + 0b0000 NI
> > + 0b0001 IMP
> > +EndEnum
> > +Res0 35:28
> > +SignedEnum 27:24 E2H0
> > + 0b0000 IMP
> > + 0b1110 NI_NV1
> > + 0b1111 NI
> > +EndEnum
> > +UnsignedEnum 23:20 NV_frac
> > + 0b0000 NV_NV2
> > + 0b0001 NV2_ONLY
> > +EndEnum
> > +UnsignedEnum 19:16 FGWTE3
> > + 0b0000 NI
> > + 0b0001 IMP
> > +EndEnum
> > +UnsignedEnum 15:12 HACDBS
> > + 0b0000 NI
> > + 0b0001 IMP
> > +EndEnum
> > +UnsignedEnum 11:8 ASID2
> > + 0b0000 NI
> > + 0b0001 IMP
> > +EndEnum
> > +SignedEnum 7:4 EIESB
> > + 0b0000 NI
> > + 0b0001 ToEL3
> > + 0b0010 ToELx
> > + 0b1111 ANY
> > +EndEnum
> > +Res0 3:0
> > +EndSysreg
> > +
> 
> Reviewed-by: Miguel Luis <miguel.luis at oracle.com>
> 
> Would you please help me understand how the kernel would cope with E2H0?s
> 0b0000  value on systems prior to ARMv9.5 where a read to
> ID_AA64MMFR4_EL1 would be RES0 ?

E2H0==0 means that E2H can be set to 0. Which is what MMFR4 always
indicated before the introduction of this anti-feature. On any system
where E2H0 reports 0, there is no change at all for SW. Only if you
want to correctly deal with a system where E2H0 reports something
other than 0 would you need to do something different. Which is what
this series is about, mostly.

ARMv9.5 doesn't come into play, as this is an allowed anti-feature
from ARMv8.1.

	M.

-- 
Without deviation from the norm, progress is not possible.


From will at kernel.org  Thu Feb  8 05:17:34 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 8 Feb 2024 13:17:34 +0000
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <44075bc2-ac5f-ffcd-0d2f-4093351a6151@huawei.com>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com>
 <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
 <ZcNnrdlb3fe0kGHK@casper.infradead.org>
 <ZcN1hTrAhy-B1P2_@arm.com>
 <44075bc2-ac5f-ffcd-0d2f-4093351a6151@huawei.com>
Message-ID: <20240208131734.GA23428@willie-the-truck>

On Thu, Feb 08, 2024 at 05:44:48PM +0800, Nanyong Sun wrote:
> 
> ? 2024/2/7 20:20, Catalin Marinas ??:
> > On Wed, Feb 07, 2024 at 11:21:17AM +0000, Matthew Wilcox wrote:
> > > On Wed, Feb 07, 2024 at 11:12:52AM +0000, Will Deacon wrote:
> > > > On Sat, Jan 27, 2024 at 01:04:15PM +0800, Nanyong Sun wrote:
> > > > > On 2024/1/26 2:06, Catalin Marinas wrote:
> > > > > > On Sat, Jan 13, 2024 at 05:44:33PM +0800, Nanyong Sun wrote:
> > > > > > > HVO was previously disabled on arm64 [1] due to the lack of necessary
> > > > > > > BBM(break-before-make) logic when changing page tables.
> > > > > > > This set of patches fix this by adding necessary BBM sequence when
> > > > > > > changing page table, and supporting vmemmap page fault handling to
> > > > > > > fixup kernel address translation fault if vmemmap is concurrently accessed.
> > > > > > I'm not keen on this approach. I'm not even sure it's safe. In the
> > > > > > second patch, you take the init_mm.page_table_lock on the fault path but
> > > > > > are we sure this is unlocked when the fault was taken?
> > > > > I think this situation is impossible. In the implementation of the second
> > > > > patch, when the page table is being corrupted
> > > > > (the time window when a page fault may occur), vmemmap_update_pte() already
> > > > > holds the init_mm.page_table_lock,
> > > > > and unlock it until page table update is done.Another thread could not hold
> > > > > the init_mm.page_table_lock and
> > > > > also trigger a page fault at the same time.
> > > > > If I have missed any points in my thinking, please correct me. Thank you.
> > > > It still strikes me as incredibly fragile to handle the fault and trying
> > > > to reason about all the users of 'struct page' is impossible. For example,
> > > > can the fault happen from irq context?
> > > The pte lock cannot be taken in irq context (which I think is what
> > > you're asking?)
> > With this patchset, I think it can: IRQ -> interrupt handler accesses
> > vmemmap -> faults -> fault handler in patch 2 takes the
> > init_mm.page_table_lock to wait for the vmemmap rewriting to complete.
> > Maybe it works if the hugetlb code disabled the IRQs but, as Will said,
> > such fault in any kernel context looks fragile.
> How about take a new lock with irq disabled during BBM, like:
> 
> +void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte)
> +{
> +??? spin_lock_irq(NEW_LOCK);
> +??? pte_clear(&init_mm, addr, ptep);
> +??? flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
> +??? set_pte_at(&init_mm, addr, ptep, pte);
> +??? spin_unlock_irq(NEW_LOCK);
> +}

I really think the only maintainable way to achieve this is to avoid the
possibility of a fault altogether.

Will


From abel.vesa at linaro.org  Thu Feb  8 05:19:00 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Thu, 08 Feb 2024 15:19:00 +0200
Subject: [PATCH] arm64: defconfig: Enable X1E80100 multimedia clock
 controllers configs
Message-ID: <20240208-x1e80100-configs-v1-1-9e027bee5209@linaro.org>

Enable as modules the CAM, GPU, DISP and TCSR clock controllers for
Qualcomm X1E80100 platform.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 arch/arm64/configs/defconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f44b3abf3cef..c9c1b1aa4625 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1253,7 +1253,11 @@ CONFIG_COMMON_CLK_MT8192_SCP_ADSP=y
 CONFIG_COMMON_CLK_MT8192_VDECSYS=y
 CONFIG_COMMON_CLK_MT8192_VENCSYS=y
 CONFIG_COMMON_CLK_QCOM=y
+CONFIG_CLK_X1E80100_CAMCC=m
+CONFIG_CLK_X1E80100_DISPCC=m
 CONFIG_CLK_X1E80100_GCC=y
+CONFIG_CLK_X1E80100_GPUCC=m
+CONFIG_CLK_X1E80100_TCSRCC=y
 CONFIG_QCOM_A53PLL=y
 CONFIG_QCOM_CLK_APCS_MSM8916=y
 CONFIG_QCOM_CLK_APCC_MSM8996=y

---
base-commit: b1d3a0e70c3881d2f8cf6692ccf7c2a4fb2d030d
change-id: 20231201-x1e80100-configs-a0f4507ca23a

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>



From will at kernel.org  Thu Feb  8 05:19:39 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 8 Feb 2024 13:19:39 +0000
Subject: [PATCH v6 1/4] kvm: arm64: introduce new flag for non-cacheable
 IO memory
In-Reply-To: <20240207204652.22954-2-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-2-ankita@nvidia.com>
Message-ID: <20240208131938.GB23428@willie-the-truck>

On Thu, Feb 08, 2024 at 02:16:49AM +0530, ankita at nvidia.com wrote:
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index c651df904fe3..2a893724ee9b 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -717,15 +717,28 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
>  static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
>  				kvm_pte_t *ptep)
>  {
> -	bool device = prot & KVM_PGTABLE_PROT_DEVICE;
> -	kvm_pte_t attr = device ? KVM_S2_MEMATTR(pgt, DEVICE_nGnRE) :
> -			    KVM_S2_MEMATTR(pgt, NORMAL);
> +	kvm_pte_t attr;
>  	u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS;
>  
> +	switch (prot & (KVM_PGTABLE_PROT_DEVICE |
> +			KVM_PGTABLE_PROT_NORMAL_NC)) {
> +	case 0:
> +		attr = KVM_S2_MEMATTR(pgt, NORMAL);
> +		break;
> +	case KVM_PGTABLE_PROT_DEVICE:
> +		if (prot & KVM_PGTABLE_PROT_X)
> +			return -EINVAL;
> +		attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
> +		break;
> +	case KVM_PGTABLE_PROT_NORMAL_NC:
> +		attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
> +		break;
> +	default:
> +		WARN_ON_ONCE(1);
> +	}

Cosmetic nit, but I'd find this a little easier to read if the normal
case was the default (i.e. drop 'case 0') and we returned an error for
DEVICE | NC.

Will


From oliver.upton at linux.dev  Thu Feb  8 05:24:59 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 8 Feb 2024 13:24:59 +0000
Subject: [PATCH v6 1/4] kvm: arm64: introduce new flag for non-cacheable
 IO memory
In-Reply-To: <ZcTQi0wWZgvl05LB@arm.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-2-ankita@nvidia.com>
 <ZcTQi0wWZgvl05LB@arm.com>
Message-ID: <ZcTWK6TksvugSlI-@linux.dev>

On Thu, Feb 08, 2024 at 01:00:59PM +0000, Catalin Marinas wrote:
> On Thu, Feb 08, 2024 at 02:16:49AM +0530, ankita at nvidia.com wrote:
> > diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> > index c651df904fe3..2a893724ee9b 100644
> > --- a/arch/arm64/kvm/hyp/pgtable.c
> > +++ b/arch/arm64/kvm/hyp/pgtable.c
> > @@ -717,15 +717,28 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
> >  static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
> >  				kvm_pte_t *ptep)
> >  {
> > -	bool device = prot & KVM_PGTABLE_PROT_DEVICE;
> > -	kvm_pte_t attr = device ? KVM_S2_MEMATTR(pgt, DEVICE_nGnRE) :
> > -			    KVM_S2_MEMATTR(pgt, NORMAL);
> > +	kvm_pte_t attr;
> >  	u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS;
> >  
> > +	switch (prot & (KVM_PGTABLE_PROT_DEVICE |
> > +			KVM_PGTABLE_PROT_NORMAL_NC)) {
> > +	case 0:
> > +		attr = KVM_S2_MEMATTR(pgt, NORMAL);
> > +		break;
> > +	case KVM_PGTABLE_PROT_DEVICE:
> > +		if (prot & KVM_PGTABLE_PROT_X)
> > +			return -EINVAL;
> > +		attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
> > +		break;
> > +	case KVM_PGTABLE_PROT_NORMAL_NC:
> > +		attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
> > +		break;
> 
> Does it make sense to allow executable here as well? I don't think it's
> harmful but not sure there's a use-case for it either.

Ah, we should just return EINVAL for that too.

I get that the memory attribute itself is not problematic, but since
we're only using this thing for MMIO it'd be a rather massive
bug in KVM... We reject attempts to do this earlier in user_mem_abort().

If, for some reason, we wanted to do Normal-NC actual memory then we
would need to make sure that KVM does the appropriate cache maintenance
at map / unmap.

-- 
Thanks,
Oliver


From oliver.upton at linux.dev  Thu Feb  8 05:26:52 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 8 Feb 2024 13:26:52 +0000
Subject: [PATCH v6 3/4] kvm: arm64: set io memory s2 pte as normalnc for
 vfio pci device
In-Reply-To: <20240207204652.22954-4-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-4-ankita@nvidia.com>
Message-ID: <ZcTWnDBfAtMriXqp@linux.dev>

On Thu, Feb 08, 2024 at 02:16:51AM +0530, ankita at nvidia.com wrote:
> @@ -1557,10 +1559,18 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  	if (exec_fault)
>  		prot |= KVM_PGTABLE_PROT_X;
>  
> -	if (device)
> -		prot |= KVM_PGTABLE_PROT_DEVICE;
> -	else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
> +	if (device) {
> +		/*
> +		 * To provide VM with the ability to get device IO memory
> +		 * with NormalNC property, map device MMIO as NormalNC in S2.
> +		 */

nit: the comment doesn't provide anything of value, the logic is rather
straightforward here.

> +		if (vfio_allow_wc)
> +			prot |= KVM_PGTABLE_PROT_NORMAL_NC;
> +		else
> +			prot |= KVM_PGTABLE_PROT_DEVICE;
> +	} else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) {
>  		prot |= KVM_PGTABLE_PROT_X;
> +	}
>  
>  	/*
>  	 * Under the premise of getting a FSC_PERM fault, we just need to relax
> -- 
> 2.34.1
>

-- 
Thanks,
Oliver


From oliver.upton at linux.dev  Thu Feb  8 05:28:03 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 8 Feb 2024 13:28:03 +0000
Subject: [PATCH v1 2/2] KVM: arm64: removed unused kern_hyp_va asm macro
In-Reply-To: <86jznf5dqm.wl-maz@kernel.org>
References: <20240208105422.3444159-1-joey.gouly@arm.com>
 <20240208105422.3444159-3-joey.gouly@arm.com>
 <86jznf5dqm.wl-maz@kernel.org>
Message-ID: <ZcTW43v46Z3oT4Qf@linux.dev>

On Thu, Feb 08, 2024 at 12:42:25PM +0000, Marc Zyngier wrote:
> On Thu, 08 Feb 2024 10:54:22 +0000,
> Joey Gouly <joey.gouly at arm.com> wrote:
> > 
> > The last usage of this macro was removed in:
> >     commit 5dc33bd199ca ("KVM: arm64: nVHE: Pass pointers consistently to hyp-init")
> > 
> > Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> > Cc: Marc Zyngier <maz at kernel.org>
> > Cc: Oliver Upton <oliver.upton at linux.dev>
> > ---
> >  arch/arm64/include/asm/kvm_mmu.h | 21 ---------------------
> >  1 file changed, 21 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> > index d248a7ae627a..961d4431654b 100644
> > --- a/arch/arm64/include/asm/kvm_mmu.h
> > +++ b/arch/arm64/include/asm/kvm_mmu.h
> > @@ -53,27 +53,6 @@
> >  
> >  #include <asm/alternative.h>
> >  
> > -/*
> > - * Convert a kernel VA into a HYP VA.
> > - * reg: VA to be converted.
> > - *
> > - * The actual code generation takes place in kvm_update_va_mask, and
> > - * the instructions below are only there to reserve the space and
> > - * perform the register allocation (kvm_update_va_mask uses the
> > - * specific registers encoded in the instructions).
> 
> Consider moving this comment to the C version instead of deleting it
> completely (the part about the register allocation is pretty crucial).
> 
> Oliver can probably fix this when applying it, and my previous Ack
> still stands.

Yeah -- this comment is still rather useful. I'll fix it up when I apply
the series.

-- 
Thanks,
Oliver


From dan.carpenter at linaro.org  Thu Feb  8 05:33:33 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Thu, 8 Feb 2024 16:33:33 +0300
Subject: [PATCH net] net: ti: icssg-prueth: Remove duplicate cleanup
 calls in emac_ndo_stop()
In-Reply-To: <20240208104700.GF1435458@kernel.org>
References: <20240206152052.98217-1-diogo.ivo@siemens.com>
 <20240208104700.GF1435458@kernel.org>
Message-ID: <2fa5f053-6b4f-40e4-86f5-807c3c6dfee9@moroto.mountain>

On Thu, Feb 08, 2024 at 10:47:00AM +0000, Simon Horman wrote:
> On Tue, Feb 06, 2024 at 03:20:51PM +0000, Diogo Ivo wrote:
> > Remove the duplicate calls to prueth_emac_stop() and
> > prueth_cleanup_tx_chns() in emac_ndo_stop().
> > 
> > Fixes: 128d5874c082 ("net: ti: icssg-prueth: Add ICSSG ethernet driver")
> > Fixes: 186734c15886 ("net: ti: icssg-prueth: add packet timestamping and ptp support")
> > Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
> 
> Hi Doigo,
> 
> I see that there are indeed duplicate calls,
> but I do wonder if this is a cleanup rather than a bug:
> is there a user-visible problem that this addresses?
> 
> If so, I think it would be good to spell this out in the commit message.
> 
> ...

So far as I can see from reviewing the code there is no user visible
effect.

rproc_shutdown() calls rproc_stop() which sets "rproc->state = RPROC_OFFLINE;"
so the second call will return be a no-op and return -EINVAL.  But the
return value is not checked so no problem.

prueth_cleanup_tx_chns() uses memset to zero out the emac->tx_chns[] so
the second call will be a no-op.

regards,
dan carpenter


From Jonathan.Cameron at Huawei.com  Thu Feb  8 05:38:18 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 13:38:18 +0000
Subject: [PATCH v11 1/5] uaccess: add generic fallback version of
 copy_mc_to_user()
In-Reply-To: <20240207132204.1720444-2-tongtiangen@huawei.com>
References: <20240207132204.1720444-1-tongtiangen@huawei.com>
	<20240207132204.1720444-2-tongtiangen@huawei.com>
Message-ID: <20240208133818.000009ea@Huawei.com>

On Wed, 7 Feb 2024 21:22:00 +0800
Tong Tiangen <tongtiangen at huawei.com> wrote:

> x86/powerpc has it's implementation of copy_mc_to_user(), we add generic
> fallback in include/linux/uaccess.h prepare for other architechures to
architectures

(only bother fixing if you end up doing a v12 - hence off list reply!)

> enable CONFIG_ARCH_HAS_COPY_MC.
> 
> Signed-off-by: Tong Tiangen <tongtiangen at huawei.com>
> Acked-by: Michael Ellerman <mpe at ellerman.id.au>
> ---
>  arch/powerpc/include/asm/uaccess.h | 1 +
>  arch/x86/include/asm/uaccess.h     | 1 +
>  include/linux/uaccess.h            | 9 +++++++++
>  3 files changed, 11 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
> index f1f9890f50d3..4bfd1e6f0702 100644
> --- a/arch/powerpc/include/asm/uaccess.h
> +++ b/arch/powerpc/include/asm/uaccess.h
> @@ -381,6 +381,7 @@ copy_mc_to_user(void __user *to, const void *from, unsigned long n)
>  
>  	return n;
>  }
> +#define copy_mc_to_user copy_mc_to_user
>  #endif
>  
>  extern long __copy_from_user_flushcache(void *dst, const void __user *src,
> diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
> index 5c367c1290c3..fd56282ee9a8 100644
> --- a/arch/x86/include/asm/uaccess.h
> +++ b/arch/x86/include/asm/uaccess.h
> @@ -497,6 +497,7 @@ copy_mc_to_kernel(void *to, const void *from, unsigned len);
>  
>  unsigned long __must_check
>  copy_mc_to_user(void __user *to, const void *from, unsigned len);
> +#define copy_mc_to_user copy_mc_to_user
>  #endif
>  
>  /*
> diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
> index 3064314f4832..550287c92990 100644
> --- a/include/linux/uaccess.h
> +++ b/include/linux/uaccess.h
> @@ -205,6 +205,15 @@ copy_mc_to_kernel(void *dst, const void *src, size_t cnt)
>  }
>  #endif
>  
> +#ifndef copy_mc_to_user
> +static inline unsigned long __must_check
> +copy_mc_to_user(void *dst, const void *src, size_t cnt)
> +{
> +	check_object_size(src, cnt, true);
> +	return raw_copy_to_user(dst, src, cnt);
> +}
> +#endif
> +
>  static __always_inline void pagefault_disabled_inc(void)
>  {
>  	current->pagefault_disabled++;



From Jonathan.Cameron at Huawei.com  Thu Feb  8 05:39:58 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 8 Feb 2024 13:39:58 +0000
Subject: [PATCH v11 1/5] uaccess: add generic fallback version of
 copy_mc_to_user()
In-Reply-To: <20240208133818.000009ea@Huawei.com>
References: <20240207132204.1720444-1-tongtiangen@huawei.com>
	<20240207132204.1720444-2-tongtiangen@huawei.com>
	<20240208133818.000009ea@Huawei.com>
Message-ID: <20240208133958.00004002@Huawei.com>

On Thu, 8 Feb 2024 13:38:18 +0000
Jonathan Cameron <Jonathan.Cameron at Huawei.com> wrote:

> On Wed, 7 Feb 2024 21:22:00 +0800
> Tong Tiangen <tongtiangen at huawei.com> wrote:
> 
> > x86/powerpc has it's implementation of copy_mc_to_user(), we add generic
> > fallback in include/linux/uaccess.h prepare for other architechures to
> architectures
> 
> (only bother fixing if you end up doing a v12 - hence off list reply!)
gah. Email mess up and I missed the cancel button.
Anyhow, harmless feedback ;)



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:35 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:35 +0000
Subject: [PATCH 02/12] spi: s3c64xx: define a magic value
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-3-tudor.ambarus@linaro.org>

Define a magic value, it will be used in the next patch as well.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 6f29dca68491..6ff3b25b6feb 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -78,6 +78,7 @@
 #define S3C64XX_SPI_INT_RX_FIFORDY_EN		(1<<1)
 #define S3C64XX_SPI_INT_TX_FIFORDY_EN		(1<<0)
 
+#define S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT	6
 #define S3C64XX_SPI_ST_RX_OVERRUN_ERR		(1<<5)
 #define S3C64XX_SPI_ST_RX_UNDERRUN_ERR		(1<<4)
 #define S3C64XX_SPI_ST_TX_OVERRUN_ERR		(1<<3)
@@ -108,7 +109,8 @@
 #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
 #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \
 				(1 << (i)->port_conf->tx_st_done)) ? 1 : 0)
-#define TX_FIFO_LVL(v, i) (((v) >> 6) & FIFO_LVL_MASK(i))
+#define TX_FIFO_LVL(v, i) (((v) >> S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT) &	\
+			   FIFO_LVL_MASK(i))
 #define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \
 					FIFO_LVL_MASK(i))
 #define FIFO_DEPTH(i) ((FIFO_LVL_MASK(i) >> 1) + 1)
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:33 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:33 +0000
Subject: [PATCH 00/12] spi: s3c64xx: remove OF alias ID dependency
Message-ID: <20240208135045.3728927-1-tudor.ambarus@linaro.org>

The driver was wrong as it assumed that the alias values in devicetree
have a particular meaning in identifying instances. This immediately
breaks when there is a dtb file that does not use the same alias values,
e.g. because it only needs some of the SPI ports.

Tested gs101 SPI with spi-loopback-test, all went fine. I updated
exynos850 as it uses the same USI.SPI_VERSION as gs101. Maybe Sam can
test exynos850, if not, we can drop that patch.

The patch set has some dependencies. One has to apply first the gs101
addition [1], then the simple cleanup from [2], then this patch set.
[1] https://lore.kernel.org/linux-spi/20240207111516.2563218-1-tudor.ambarus at linaro.org/
[2] https://lore.kernel.org/linux-spi/20240207120431.2766269-1-tudor.ambarus at linaro.org/

Cheers,
ta

Tudor Ambarus (12):
  spi: dt-bindings: introduce the ``fifo-depth`` property
  spi: s3c64xx: define a magic value
  spi: s3c64xx: allow full FIFO masks
  spi: s3c64xx: determine the fifo depth only once
  spi: s3c64xx: retrieve the FIFO depth from the device tree
  spi: s3c64xx: allow FIFO depth to be determined from the compatible
  spi: s3c64xx: let the SPI core determine the bus number
  spi: s3c64xx: introduce s3c64xx_spi_set_port_id()
  spi: s3c64xx: get rid of the OF alias ID dependency
  spi: s3c64xx: deprecate fifo_lvl_mask, rx_lvl_offset and port_id
  spi: s3c64xx: switch gs101 to new port config data
  spi: s3c64xx: switch exynos850 to new port config data

 .../bindings/spi/spi-controller.yaml          |   5 +
 drivers/spi/spi-s3c64xx.c                     | 142 ++++++++++++++----
 2 files changed, 116 insertions(+), 31 deletions(-)

-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:34 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:34 +0000
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth`` property
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-2-tudor.ambarus@linaro.org>

There are instances of the same IP that are configured by the integrator
with different FIFO depths. Introduce the fifo-depth property to allow
such nodes to specify their FIFO depth.

We haven't seen SPI IPs with different FIFO depths for RX and TX, thus
introduce a single property.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 Documentation/devicetree/bindings/spi/spi-controller.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml
index 524f6fe8c27b..99272e6f115e 100644
--- a/Documentation/devicetree/bindings/spi/spi-controller.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml
@@ -69,6 +69,11 @@ properties:
          Should be generally avoided and be replaced by
          spi-cs-high + ACTIVE_HIGH.
 
+  fifo-depth:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Size of the data FIFO in bytes.
+
   num-cs:
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:37 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:37 +0000
Subject: [PATCH 04/12] spi: s3c64xx: determine the fifo depth only once
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-5-tudor.ambarus@linaro.org>

Determine the FIFO depth only once, at probe time.
``sdd->fifo_depth`` can be set later on with the FIFO depth
specified in the device tree.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 338ca3f03ea5..72572e23cde5 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -191,6 +191,7 @@ struct s3c64xx_spi_port_config {
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
  * @port_conf: Local SPI port configuration data
  * @port_id: Port identification number
+ * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
  * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
@@ -214,6 +215,7 @@ struct s3c64xx_spi_driver_data {
 	struct s3c64xx_spi_dma_data	tx_dma;
 	const struct s3c64xx_spi_port_config	*port_conf;
 	unsigned int			port_id;
+	unsigned int			fifo_depth;
 	u32				rx_fifomask;
 	u32				tx_fifomask;
 };
@@ -424,7 +426,7 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
 	struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
 
 	if (sdd->rx_dma.ch && sdd->tx_dma.ch)
-		return xfer->len > FIFO_DEPTH(sdd);
+		return xfer->len > sdd->fifo_depth;
 
 	return false;
 }
@@ -548,7 +550,7 @@ static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,
 	void __iomem *regs = sdd->regs;
 	unsigned long val = 1;
 	u32 status;
-	u32 max_fifo = FIFO_DEPTH(sdd);
+	u32 max_fifo = sdd->fifo_depth;
 
 	if (timeout_ms)
 		val = msecs_to_loops(timeout_ms);
@@ -655,7 +657,7 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
 	 * For any size less than the fifo size the below code is
 	 * executed atleast once.
 	 */
-	loops = xfer->len / FIFO_DEPTH(sdd);
+	loops = xfer->len / sdd->fifo_depth;
 	buf = xfer->rx_buf;
 	do {
 		/* wait for data to be received in the fifo */
@@ -792,7 +794,7 @@ static int s3c64xx_spi_transfer_one(struct spi_controller *host,
 				    struct spi_transfer *xfer)
 {
 	struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
-	const unsigned int fifo_len = FIFO_DEPTH(sdd);
+	const unsigned int fifo_len = sdd->fifo_depth;
 	const void *tx_buf = NULL;
 	void *rx_buf = NULL;
 	int target_len = 0, origin_len = 0;
@@ -1261,6 +1263,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
+	sdd->fifo_depth = FIFO_DEPTH(sdd);
+
 	s3c64xx_spi_set_fifomask(sdd);
 
 	sdd->cur_bpw = 8;
@@ -1352,7 +1356,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Targets attached\n",
 					sdd->port_id, host->num_chipselect);
 	dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\n",
-					mem_res, FIFO_DEPTH(sdd));
+		mem_res, sdd->fifo_depth);
 
 	pm_runtime_mark_last_busy(&pdev->dev);
 	pm_runtime_put_autosuspend(&pdev->dev);
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:36 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:36 +0000
Subject: [PATCH 03/12] spi: s3c64xx: allow full FIFO masks
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-4-tudor.ambarus@linaro.org>

The driver is wrong because is using partial register field masks for the
SPI_STATUS.{RX, TX}_FIFO_LVL register fields.

We see s3c64xx_spi_port_config.fifo_lvl_mask with different values for
different instances of the same IP. Take s5pv210_spi_port_config for
example, it defines:
	.fifo_lvl_mask  = { 0x1ff, 0x7F },

fifo_lvl_mask is used to determine the FIFO depth of the instance of the
IP. In this case, the integrator uses a 256 bytes FIFO for the first SPI
instance of the IP, and a 64 bytes FIFO for the second instance. While
the first mask reflects the SPI_STATUS.{RX, TX}_FIFO_LVL register
fields, the second one is two bits short. Using partial field masks is
misleading and can hide problems of the driver's logic.

Allow platforms to specify the full FIFO mask, regardless of the FIFO
depth.

Introduce {rx, tx}_fifomask to represent the SPI_STATUS.{RX, TX}_FIFO_LVL
register fields. It's a shifted mask defining the field's length and
position. We'll be able to deprecate the use of @rx_lvl_offset, as the
shift value can be determined from the mask. The existing compatibles
shall start using {rx, tx}_fifomask so that they use the full field mask
and to avoid shifting the mask to position, and then shifting it back to
zero in the {TX, RX}_FIFO_LVL macros.

@rx_lvl_offset will be deprecated in a further patch, after we have the
infrastructure to deprecate @fifo_lvl_mask as well.

No functional change intended.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 40 +++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 6ff3b25b6feb..338ca3f03ea5 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -3,6 +3,7 @@
 // Copyright (c) 2009 Samsung Electronics Co., Ltd.
 //      Jaswinder Singh <jassi.brar at samsung.com>
 
+#include <linux/bitops.h>
 #include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
@@ -109,10 +110,10 @@
 #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
 #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \
 				(1 << (i)->port_conf->tx_st_done)) ? 1 : 0)
-#define TX_FIFO_LVL(v, i) (((v) >> S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT) &	\
-			   FIFO_LVL_MASK(i))
-#define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \
-					FIFO_LVL_MASK(i))
+#define TX_FIFO_LVL(v, sdd)	(((v) & (sdd)->tx_fifomask) >>		\
+				 __ffs((sdd)->tx_fifomask))
+#define RX_FIFO_LVL(v, sdd)	(((v) & (sdd)->rx_fifomask) >>		\
+				 __ffs((sdd)->rx_fifomask))
 #define FIFO_DEPTH(i) ((FIFO_LVL_MASK(i) >> 1) + 1)
 
 #define S3C64XX_SPI_MAX_TRAILCNT	0x3ff
@@ -136,6 +137,10 @@ struct s3c64xx_spi_dma_data {
  * struct s3c64xx_spi_port_config - SPI Controller hardware info
  * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
  * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
+ * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
+ * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
  * @tx_st_done: Bit offset of TX_DONE bit in SPI_STATUS regiter.
  * @clk_div: Internal clock divider
  * @quirks: Bitmask of known quirks
@@ -154,6 +159,8 @@ struct s3c64xx_spi_dma_data {
 struct s3c64xx_spi_port_config {
 	int	fifo_lvl_mask[MAX_SPI_PORTS];
 	int	rx_lvl_offset;
+	u32	rx_fifomask;
+	u32	tx_fifomask;
 	int	tx_st_done;
 	int	quirks;
 	int	clk_div;
@@ -184,6 +191,10 @@ struct s3c64xx_spi_port_config {
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
  * @port_conf: Local SPI port configuration data
  * @port_id: Port identification number
+ * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
+ * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
  */
 struct s3c64xx_spi_driver_data {
 	void __iomem                    *regs;
@@ -203,6 +214,8 @@ struct s3c64xx_spi_driver_data {
 	struct s3c64xx_spi_dma_data	tx_dma;
 	const struct s3c64xx_spi_port_config	*port_conf;
 	unsigned int			port_id;
+	u32				rx_fifomask;
+	u32				tx_fifomask;
 };
 
 static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd)
@@ -1183,6 +1196,23 @@ static inline const struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
 	return (const struct s3c64xx_spi_port_config *)platform_get_device_id(pdev)->driver_data;
 }
 
+static void s3c64xx_spi_set_fifomask(struct s3c64xx_spi_driver_data *sdd)
+{
+	const struct s3c64xx_spi_port_config *port_conf = sdd->port_conf;
+
+	if (port_conf->rx_fifomask)
+		sdd->rx_fifomask = port_conf->rx_fifomask;
+	else
+		sdd->rx_fifomask = FIFO_LVL_MASK(sdd) <<
+			port_conf->rx_lvl_offset;
+
+	if (port_conf->tx_fifomask)
+		sdd->tx_fifomask = port_conf->tx_fifomask;
+	else
+		sdd->tx_fifomask = FIFO_LVL_MASK(sdd) <<
+			S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT;
+}
+
 static int s3c64xx_spi_probe(struct platform_device *pdev)
 {
 	struct resource	*mem_res;
@@ -1231,6 +1261,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
+	s3c64xx_spi_set_fifomask(sdd);
+
 	sdd->cur_bpw = 8;
 
 	sdd->tx_dma.direction = DMA_MEM_TO_DEV;
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:38 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:38 +0000
Subject: [PATCH 05/12] spi: s3c64xx: retrieve the FIFO depth from the device tree
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-6-tudor.ambarus@linaro.org>

There are SoCs that configure different FIFO depths for their instances
of the SPI IP. See the fifo_lvl_mask defined for exynos4_spi_port_config
for example:
        .fifo_lvl_mask  = { 0x1ff, 0x7F, 0x7F },
The first instance of the IP is configured with 256 bytes FIFOs, whereas
the last two are configured with 64 bytes FIFOs.

Instead of mangling with the .fifo_lvl_mask and its dependency of the DT
alias ID, allow such SoCs to determine the FIFO depth via the
``fifo-depth`` DT property.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 72572e23cde5..b1c63f75021d 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1263,7 +1263,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
-	sdd->fifo_depth = FIFO_DEPTH(sdd);
+	if (of_property_read_u32(pdev->dev.of_node, "fifo-depth",
+				 &sdd->fifo_depth))
+		sdd->fifo_depth = FIFO_DEPTH(sdd);
 
 	s3c64xx_spi_set_fifomask(sdd);
 
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:39 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:39 +0000
Subject: [PATCH 06/12] spi: s3c64xx: allow FIFO depth to be determined from the compatible
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-7-tudor.ambarus@linaro.org>

There are SoCs that use the same FIFO depth for all the instances of the
SPI IP. See the fifo_lvl_mask defined for gs101 for example:
    .fifo_lvl_mask  = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
                        0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},

Instead of specifying the FIFO depth with the same value for all 16
nodes in this case, allow such SoCs to infer the FIFO depth from the
compatible. There are other SoCs than can benefit of this, see:
{gs101, fsd, exynos850, s3c641, s3c2443}_spi_port_config.

The FIFO depth inferred from the compatible has a higher precedence than
the one that might be specified via device tree, the driver shall know
better.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index b1c63f75021d..68f95c04d092 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -137,6 +137,7 @@ struct s3c64xx_spi_dma_data {
  * struct s3c64xx_spi_port_config - SPI Controller hardware info
  * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
  * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
+ * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
  * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
@@ -159,6 +160,7 @@ struct s3c64xx_spi_dma_data {
 struct s3c64xx_spi_port_config {
 	int	fifo_lvl_mask[MAX_SPI_PORTS];
 	int	rx_lvl_offset;
+	unsigned int fifo_depth;
 	u32	rx_fifomask;
 	u32	tx_fifomask;
 	int	tx_st_done;
@@ -1263,8 +1265,10 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
-	if (of_property_read_u32(pdev->dev.of_node, "fifo-depth",
-				 &sdd->fifo_depth))
+	if (sdd->port_conf->fifo_depth)
+		sdd->fifo_depth = sdd->port_conf->fifo_depth;
+	else if (of_property_read_u32(pdev->dev.of_node, "fifo-depth",
+				      &sdd->fifo_depth))
 		sdd->fifo_depth = FIFO_DEPTH(sdd);
 
 	s3c64xx_spi_set_fifomask(sdd);
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:41 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:41 +0000
Subject: [PATCH 08/12] spi: s3c64xx: introduce s3c64xx_spi_set_port_id()
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-9-tudor.ambarus@linaro.org>

Prepare driver to get rid of the of alias ID dependency. Split the
port_id logic into a dedicated method.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index ac47755beb02..40de325bd094 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1200,6 +1200,27 @@ static inline const struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
 	return (const struct s3c64xx_spi_port_config *)platform_get_device_id(pdev)->driver_data;
 }
 
+static int s3c64xx_spi_set_port_id(struct platform_device *pdev,
+				   struct s3c64xx_spi_driver_data *sdd)
+{
+	int ret;
+
+	if (pdev->dev.of_node) {
+		ret = of_alias_get_id(pdev->dev.of_node, "spi");
+		if (ret < 0)
+			return dev_err_probe(&pdev->dev, ret,
+					     "Failed to get alias id\n");
+		sdd->port_id = ret;
+	} else {
+		if (pdev->id < 0)
+			return dev_err_probe(&pdev->dev, -EINVAL,
+					     "Negative platform ID is not allowed\n");
+		sdd->port_id = pdev->id;
+	}
+
+	return 0;
+}
+
 static void s3c64xx_spi_set_fifomask(struct s3c64xx_spi_driver_data *sdd)
 {
 	const struct s3c64xx_spi_port_config *port_conf = sdd->port_conf;
@@ -1252,18 +1273,10 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	sdd->host = host;
 	sdd->cntrlr_info = sci;
 	sdd->pdev = pdev;
-	if (pdev->dev.of_node) {
-		ret = of_alias_get_id(pdev->dev.of_node, "spi");
-		if (ret < 0)
-			return dev_err_probe(&pdev->dev, ret,
-					     "Failed to get alias id\n");
-		sdd->port_id = ret;
-	} else {
-		if (pdev->id < 0)
-			return dev_err_probe(&pdev->dev, -EINVAL,
-					     "Negative platform ID is not allowed\n");
-		sdd->port_id = pdev->id;
-	}
+
+	ret = s3c64xx_spi_set_port_id(pdev, sdd);
+	if (ret)
+		return ret;
 
 	if (sdd->port_conf->fifo_depth)
 		sdd->fifo_depth = sdd->port_conf->fifo_depth;
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:40 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:40 +0000
Subject: [PATCH 07/12] spi: s3c64xx: let the SPI core determine the bus number
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-8-tudor.ambarus@linaro.org>

Let the core determine the bus number, either by getting the alias ID
(as the driver forces now), or by allocating a dynamic bus number when
the alias is absent. Prepare the driver to allow dt aliases to be
absent.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 68f95c04d092..ac47755beb02 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1279,7 +1279,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	sdd->rx_dma.direction = DMA_DEV_TO_MEM;
 
 	host->dev.of_node = pdev->dev.of_node;
-	host->bus_num = sdd->port_id;
+	host->bus_num = -1;
 	host->setup = s3c64xx_spi_setup;
 	host->cleanup = s3c64xx_spi_cleanup;
 	host->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
@@ -1360,7 +1360,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	}
 
 	dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Targets attached\n",
-					sdd->port_id, host->num_chipselect);
+		host->bus_num, host->num_chipselect);
 	dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\n",
 		mem_res, sdd->fifo_depth);
 
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:42 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:42 +0000
Subject: [PATCH 09/12] spi: s3c64xx: get rid of the OF alias ID dependency
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-10-tudor.ambarus@linaro.org>

Compatibles that set ``port_conf->{rx, tx}_fifomask`` are now safe to
get rid of the OF alias ID dependency. Let the driver probe even without
the alias for these.

With this we also protect the FIFO_LVL_MASK calls from
s3c64xx_spi_set_fifomask().

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 40de325bd094..d2d1c9767145 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1203,8 +1203,12 @@ static inline const struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
 static int s3c64xx_spi_set_port_id(struct platform_device *pdev,
 				   struct s3c64xx_spi_driver_data *sdd)
 {
+	const struct s3c64xx_spi_port_config *port_conf = sdd->port_conf;
 	int ret;
 
+	if (port_conf->rx_fifomask && port_conf->tx_fifomask)
+		return 0;
+
 	if (pdev->dev.of_node) {
 		ret = of_alias_get_id(pdev->dev.of_node, "spi");
 		if (ret < 0)
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:43 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:43 +0000
Subject: [PATCH 10/12] spi: s3c64xx: deprecate fifo_lvl_mask, rx_lvl_offset and port_id
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-11-tudor.ambarus@linaro.org>

Deprecate fifo_lvl_mask, rx_lvl_offset and port_id. One shall use
{rx, tx}_fifomask instead. Add messages to each port configuration.

Suggested-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index d2d1c9767145..128f4a7c4bd9 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -135,8 +135,8 @@ struct s3c64xx_spi_dma_data {
 
 /**
  * struct s3c64xx_spi_port_config - SPI Controller hardware info
- * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
- * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
+ * @fifo_lvl_mask: [DEPRECATED] use @{rx, tx}_fifomask instead.
+ * @rx_lvl_offset: [DEPRECATED] use @{rx,tx}_fifomask instead.
  * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
@@ -192,7 +192,7 @@ struct s3c64xx_spi_port_config {
  * @rx_dma: Local receive DMA data (e.g. chan and direction)
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
  * @port_conf: Local SPI port configuration data
- * @port_id: Port identification number
+ * @port_id: [DEPRECATED] use @{rx,tx}_fifomask instead.
  * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
@@ -1508,7 +1508,9 @@ static const struct dev_pm_ops s3c64xx_spi_pm = {
 };
 
 static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 13,
 	.tx_st_done	= 21,
 	.clk_div	= 2,
@@ -1516,14 +1518,18 @@ static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config s3c6410_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7F },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 13,
 	.tx_st_done	= 21,
 	.clk_div	= 2,
 };
 
 static const struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7F },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1531,7 +1537,9 @@ static const struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos4_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7F, 0x7F },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1541,7 +1549,9 @@ static const struct s3c64xx_spi_port_config exynos4_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos7_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7F, 0x7F, 0x7F, 0x7F, 0x1ff},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1551,7 +1561,9 @@ static const struct s3c64xx_spi_port_config exynos7_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1562,7 +1574,9 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos850_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
@@ -1573,8 +1587,10 @@ static const struct s3c64xx_spi_port_config exynos850_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynosautov9_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff, 0x7f,
 			    0x7f, 0x7f, 0x7f, 0x7f},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
@@ -1586,7 +1602,9 @@ static const struct s3c64xx_spi_port_config exynosautov9_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1597,8 +1615,10 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
 			    0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:44 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:44 +0000
Subject: [PATCH 11/12] spi: s3c64xx: switch gs101 to new port config data
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-12-tudor.ambarus@linaro.org>

Drop the fifo_lvl_mask and rx_lvl_offset and switch to the new port
config data.

Advantages of the change:
- drop dependency on the OF alias ID.
- FIFO depth is inferred from the compatible. Exynos850 integrates 3 SPI
  IPs, all with 64 bytes FIFO depths.
- use full mask for SPI_STATUS.{RX, TX}_FIFO_LVL fields. Using partial
  masks is misleading and can hide problems of the driver logic.

S3C64XX_SPI_ST_TX_FIFO_RDY_V2 was defined based on the USI's
SPI_VERSION.USI_IP_VERSION register field, which has value 2 at reset.

MAX_SPI_PORTS is updated to reflect the maximum number of ports for the
rest of the compatibles.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 128f4a7c4bd9..784786407d2e 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -20,7 +20,7 @@
 #include <linux/spi/spi.h>
 #include <linux/types.h>
 
-#define MAX_SPI_PORTS		16
+#define MAX_SPI_PORTS		12
 #define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1)
 #define AUTOSUSPEND_TIMEOUT	2000
 
@@ -79,6 +79,8 @@
 #define S3C64XX_SPI_INT_RX_FIFORDY_EN		(1<<1)
 #define S3C64XX_SPI_INT_TX_FIFORDY_EN		(1<<0)
 
+#define S3C64XX_SPI_ST_RX_FIFO_RDY_V2		GENMASK(23, 15)
+#define S3C64XX_SPI_ST_TX_FIFO_RDY_V2		GENMASK(14, 6)
 #define S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT	6
 #define S3C64XX_SPI_ST_RX_OVERRUN_ERR		(1<<5)
 #define S3C64XX_SPI_ST_RX_UNDERRUN_ERR		(1<<4)
@@ -1615,11 +1617,9 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
-	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
-	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-			    0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
-	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
-	.rx_lvl_offset	= 15,
+	.fifo_depth	= 64,
+	.rx_fifomask	= S3C64XX_SPI_ST_RX_FIFO_RDY_V2,
+	.tx_fifomask	= S3C64XX_SPI_ST_TX_FIFO_RDY_V2,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
 	.high_speed	= true,
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Thu Feb  8 05:50:45 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu,  8 Feb 2024 13:50:45 +0000
Subject: [PATCH 12/12] spi: s3c64xx: switch exynos850 to new port config data
In-Reply-To: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
Message-ID: <20240208135045.3728927-13-tudor.ambarus@linaro.org>

Exynos850 has the same version of USI SPI (v2.1) as GS101.
Drop the fifo_lvl_mask and rx_lvl_offset and switch to the new port
config data.

Backward compatibility with DT is not broken because when alises are
set:
- the SPI core will set the bus number according to the alias ID
- the FIFO depth is always the same size for exynos850 (64 bytes) no
  matter the alias ID number.

Advantages of the change:
- drop dependency on the OF alias ID.
- FIFO depth is inferred from the compatible. Exynos850 integrates 3 SPI
  IPs, all with 64 bytes FIFO depths.
- use full mask for SPI_STATUS.{RX, TX}_FIFO_LVL fields. Using partial
  masks is misleading and can hide problems of the driver logic.

Just compiled tested.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 784786407d2e..9fcbe040cb2f 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1576,10 +1576,9 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos850_spi_port_config = {
-	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
-	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f },
-	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
-	.rx_lvl_offset	= 15,
+	.fifo_depth	= 64,
+	.rx_fifomask	= S3C64XX_SPI_ST_RX_FIFO_RDY_V2,
+	.tx_fifomask	= S3C64XX_SPI_ST_TX_FIFO_RDY_V2,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
 	.high_speed	= true,
-- 
2.43.0.687.g38aa6559b0-goog



From rogerq at kernel.org  Thu Feb  8 05:51:42 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 08 Feb 2024 15:51:42 +0200
Subject: [PATCH v2 0/3] arm64: dts: ti: am65x: Add PCIe + USB DT overlay
 files
Message-ID: <20240208-for-v6-9-am65-overlays-2-0-v2-0-70bae3e91597@kernel.org>

Hi,

There are 2 types of (PCIe + USB) expansion cards that are provided with
the AM654 board configurations.

1) 2 lane PCIe + USB 2.0 card is supplied with the AM65 IDK
configuration [1]

2) 1 lane PCIe + USB 3.0 card is supplied with the AM65 GP EVM
configuration [2]

Add DT overlay files for both cards.

[1] - https://www.ti.com/lit/ug/spruim6a/spruim6a.pdf
[2] - https://www.ti.com/lit/ug/spruim7/spruim7.pdf

Changelog in each file
v1: https://lore.kernel.org/all/20240126114530.40913-1-rogerq at kernel.org/

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
Kishon Vijay Abraham I (1):
      arm64: dts: ti: Add DT overlay for PCIe + USB3.0 SERDES personality card

Roger Quadros (2):
      arm64: dts: ti: am65x: Fix dtbs_install for Rocktech OLDI overlay
      arm64: dts: ti: Add DT overlay for PCIe + USB2.0 SERDES personality card

 arch/arm64/boot/dts/ti/Makefile                |  9 +++-
 arch/arm64/boot/dts/ti/k3-am654-pcie-usb2.dtso | 59 +++++++++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso | 61 ++++++++++++++++++++++++++
 3 files changed, 127 insertions(+), 2 deletions(-)
---
base-commit: 1e6bbc5185bcd113c8d2f7aa0a02f588a6bdbe5d
change-id: 20240208-for-v6-9-am65-overlays-2-0-b26b02a7731f

Best regards,
-- 
Roger Quadros <rogerq at kernel.org>



From rogerq at kernel.org  Thu Feb  8 05:51:43 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 08 Feb 2024 15:51:43 +0200
Subject: [PATCH v2 1/3] arm64: dts: ti: am65x: Fix dtbs_install for
 Rocktech OLDI overlay
In-Reply-To: <20240208-for-v6-9-am65-overlays-2-0-v2-0-70bae3e91597@kernel.org>
References: <20240208-for-v6-9-am65-overlays-2-0-v2-0-70bae3e91597@kernel.org>
Message-ID: <20240208-for-v6-9-am65-overlays-2-0-v2-1-70bae3e91597@kernel.org>

Add the overlay dtbo file to a Makefile target so it can be
picked by the dtbs_install command.

Fixes: b8690ed3d1d1 ("arm64: dts: ti: am65x: Add Rocktech OLDI panel DT overlay")
Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
Changelog:

v2: no change
v1: https://lore.kernel.org/all/20240126114530.40913-2-rogerq at kernel.org/
---
 arch/arm64/boot/dts/ti/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 4a570dffb638..bfcc86ff8e24 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -57,6 +57,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-gp-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-idk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board-rocktech-rk101-panel.dtbo
 
 # Boards with J7200 SoC
 k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo

-- 
2.34.1



From rogerq at kernel.org  Thu Feb  8 05:51:44 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 08 Feb 2024 15:51:44 +0200
Subject: [PATCH v2 2/3] arm64: dts: ti: Add DT overlay for PCIe + USB2.0
 SERDES personality card
In-Reply-To: <20240208-for-v6-9-am65-overlays-2-0-v2-0-70bae3e91597@kernel.org>
References: <20240208-for-v6-9-am65-overlays-2-0-v2-0-70bae3e91597@kernel.org>
Message-ID: <20240208-for-v6-9-am65-overlays-2-0-v2-2-70bae3e91597@kernel.org>

From: Roger Quadros <rogerq at ti.com>

Enable both SERDES and PCIe DT nodes in order to get PCIe working on
the SERDES PCIe x2 personality card.

The daughter card also has a USB 2.0 dual-role port. As the base board
already supports a 2.0 dual-role port, enable the port on the SERDES
card to be a host only port.

This will prevent user confusion as having 2 ports in device mode often
leads to confusion as to which port is bound to the gadget function driver.

The PCIe x2 card is provided with the AM65x IDK configuration [1]
so apply the overlay to k3-am654-idk.dtb

[1] https://www.ti.com/lit/ug/spruim6a/spruim6a.pdf

Co-developed-by: Kishon Vijay Abraham I <kishon at ti.com>
Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Signed-off-by: Roger Quadros <rogerq at ti.com>
---
Changelog:

v2:
- Drop PCIe endpoint settings as it no longer exists in base tree.

v1: https://lore.kernel.org/all/20240126114530.40913-3-rogerq at kernel.org/
---
 arch/arm64/boot/dts/ti/Makefile                |  3 +-
 arch/arm64/boot/dts/ti/k3-am654-pcie-usb2.dtso | 59 ++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index bfcc86ff8e24..f534c373c958 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -47,7 +47,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
 # Boards with AM65x SoC
 k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
 k3-am654-evm-dtbs := k3-am654-base-board.dtb k3-am654-icssg2.dtbo
-k3-am654-idk-dtbs := k3-am654-evm.dtb k3-am654-idk.dtbo
+k3-am654-idk-dtbs := k3-am654-evm.dtb k3-am654-idk.dtbo k3-am654-pcie-usb2.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic-pg2.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced.dtb
@@ -58,6 +58,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am654-gp-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-idk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board-rocktech-rk101-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am654-pcie-usb2.dtbo
 
 # Boards with J7200 SoC
 k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo
diff --git a/arch/arm64/boot/dts/ti/k3-am654-pcie-usb2.dtso b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb2.dtso
new file mode 100644
index 000000000000..dd701e0c1750
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb2.dtso
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT overlay for SERDES personality card: 2lane PCIe + USB2.0 Host on AM654 EVM
+ *
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-am654-serdes.h>
+#include "k3-pinctrl.h"
+
+&serdes0 {
+	assigned-clocks = <&k3_clks 153 4>,
+			  <&serdes0 AM654_SERDES_CMU_REFCLK>,
+			  <&serdes0 AM654_SERDES_RO_REFCLK>;
+	assigned-clock-parents = <&k3_clks 153 8>,
+				 <&k3_clks 153 4>,
+				 <&k3_clks 153 4>;
+	status = "okay";
+};
+
+&serdes1 {
+	assigned-clocks = <&serdes1 AM654_SERDES_CMU_REFCLK>;
+	assigned-clock-parents = <&serdes0 AM654_SERDES_RO_REFCLK>;
+	status = "okay";
+};
+
+&pcie0_rc {
+	num-lanes = <2>;
+	phys = <&serdes0 PHY_TYPE_PCIE 1>, <&serdes1 PHY_TYPE_PCIE 1>;
+	phy-names = "pcie-phy0", "pcie-phy1";
+	reset-gpios = <&pca9555 5 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&main_pmx0 {
+       usb0_pins_default: usb0-pins-default {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x02bc, PIN_OUTPUT, 0) /* (AD9) USB0_DRVVBUS */
+		>;
+	};
+};
+
+&dwc3_0 {
+	status = "okay";
+};
+
+&usb0_phy {
+	status = "okay";
+};
+
+&usb0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins_default>;
+	dr_mode = "host";
+};

-- 
2.34.1



From rogerq at kernel.org  Thu Feb  8 05:51:45 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 08 Feb 2024 15:51:45 +0200
Subject: [PATCH v2 3/3] arm64: dts: ti: Add DT overlay for PCIe + USB3.0
 SERDES personality card
In-Reply-To: <20240208-for-v6-9-am65-overlays-2-0-v2-0-70bae3e91597@kernel.org>
References: <20240208-for-v6-9-am65-overlays-2-0-v2-0-70bae3e91597@kernel.org>
Message-ID: <20240208-for-v6-9-am65-overlays-2-0-v2-3-70bae3e91597@kernel.org>

From: Kishon Vijay Abraham I <kishon at ti.com>

Add overlay for PCIe (uses the second instance of PCIe in AM654x) and
USB3.0 SERDES personality card

The PCI3/USB3 card is provided with the AM65x GP EVM configurtion [1]
so apply the overlay to k3-am654-gp-evm.dtb

[1] https://www.ti.com/lit/ug/spruim7/spruim7.pdf

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
Changelog:

v2:
- drop PCIe endpoint settings as it no longer exists in base tree.

v1: https://lore.kernel.org/all/20240126114530.40913-4-rogerq at kernel.org/
---
 arch/arm64/boot/dts/ti/Makefile                |  5 ++-
 arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso | 61 ++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index f534c373c958..75033b6e8693 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -45,7 +45,9 @@ dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
 
 # Boards with AM65x SoC
-k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
+k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb \
+	k3-am654-base-board-rocktech-rk101-panel.dtbo \
+	k3-am654-pcie-usb3.dtbo
 k3-am654-evm-dtbs := k3-am654-base-board.dtb k3-am654-icssg2.dtbo
 k3-am654-idk-dtbs := k3-am654-evm.dtb k3-am654-idk.dtbo k3-am654-pcie-usb2.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic.dtb
@@ -59,6 +61,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am654-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-idk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board-rocktech-rk101-panel.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am654-pcie-usb2.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am654-pcie-usb3.dtbo
 
 # Boards with J7200 SoC
 k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo
diff --git a/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso
new file mode 100644
index 000000000000..e463163f2b7b
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT overlay for SERDES personality card: 1lane PCIe + USB3.0 DRD on AM654 EVM
+ *
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-am654-serdes.h>
+
+#include "k3-pinctrl.h"
+
+&serdes1 {
+	status = "okay";
+};
+
+&pcie1_rc {
+	num-lanes = <1>;
+	phys = <&serdes1 PHY_TYPE_PCIE 0>;
+	phy-names = "pcie-phy0";
+	reset-gpios = <&pca9555 5 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&main_pmx0 {
+	usb0_pins_default: usb0_pins_default {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x02bc, PIN_OUTPUT, 0) /* (AD9) USB0_DRVVBUS */
+		>;
+	};
+};
+
+&serdes0 {
+	status = "okay";
+	assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
+	assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
+};
+
+&dwc3_0 {
+	status = "okay";
+	assigned-clock-parents = <&k3_clks 151 4>,      /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
+	<&k3_clks 151 8>;      /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */
+	phys = <&serdes0 PHY_TYPE_USB3 0>;
+	phy-names = "usb3-phy";
+};
+
+&usb0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins_default>;
+	dr_mode = "host";
+	maximum-speed = "super-speed";
+	snps,dis-u1-entry-quirk;
+	snps,dis-u2-entry-quirk;
+};
+
+&usb0_phy {
+	status = "okay";
+};

-- 
2.34.1



From linus.walleij at linaro.org  Thu Feb  8 05:54:07 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 8 Feb 2024 14:54:07 +0100
Subject: [PATCH] pinctrl: stm32: fix PM support for stm32mp257
In-Reply-To: <20240207104604.174843-1-antonio.borneo@foss.st.com>
References: <20240207104604.174843-1-antonio.borneo@foss.st.com>
Message-ID: <CACRpkdZ=Lf+Db7-QwM-X1RqqRJUNH20Yc6tJYjz9DK4RDxP6-w@mail.gmail.com>

On Wed, Feb 7, 2024 at 11:46?AM Antonio Borneo
<antonio.borneo at foss.st.com> wrote:

> The driver for stm32mp257 is missing the suspend callback in
> struct dev_pm_ops.
>
> Add the callback, using the common stm32_pinctrl_suspend()
> function.
>
> Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
> Fixes: 619f8ca4a73d ("pinctrl: stm32: add stm32mp257 pinctrl support")

Patch applied!

Yours,
Linus Walleij


From broonie at kernel.org  Thu Feb  8 06:04:57 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 8 Feb 2024 14:04:57 +0000
Subject: [PATCH 1/3] arm64: Simplify do_notify_resume() DAIF masking
In-Reply-To: <20240206123848.1696480-2-mark.rutland@arm.com>
References: <20240206123848.1696480-1-mark.rutland@arm.com>
 <20240206123848.1696480-2-mark.rutland@arm.com>
Message-ID: <ZcTfifu+AgZ+lwVN@finisterre.sirena.org.uk>

On Tue, Feb 06, 2024 at 12:38:46PM +0000, Mark Rutland wrote:
> In do_notify_resume, we handle _TIF_NEED_RESCHED differently from all
> other flags, leaving IRQ+FIQ masked when calling into schedule(). This
> masking is a historical artifact, and it is not currently necessary
> to mask IRQ+FIQ when calling into schedule (as evidenced by the generic
> exit_to_user_mode_loop(), which unmasks IRQs before checking
> _TIF_NEED_RESCHED and calling schedule()).

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/20240208/b3fa579e/attachment.sig>

From broonie at kernel.org  Thu Feb  8 06:08:27 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 8 Feb 2024 14:08:27 +0000
Subject: [PATCH 3/3] arm64: Unmask Debug + SError in do_notify_resume()
In-Reply-To: <20240206123848.1696480-4-mark.rutland@arm.com>
References: <20240206123848.1696480-1-mark.rutland@arm.com>
 <20240206123848.1696480-4-mark.rutland@arm.com>
Message-ID: <ZcTgW2sW1jvtAL7h@finisterre.sirena.org.uk>

On Tue, Feb 06, 2024 at 12:38:48PM +0000, Mark Rutland wrote:
> When returning to a user context, the arm64 entry code masks all DAIF
> exceptions before handling pending work in exit_to_user_mode_prepare()
> and do_notify_resume(), where it will transiently unmask all DAIF
> exceptions. This is a holdover from the old entry assembly, which
> conservatively masked all DAIF exceptions, and it's only necessary to
> mask interrupts at this point during the exception return path, so long
> as we subsequently mask all DAIF exceptions before the actual exception
> return.

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/20240208/0c28efc3/attachment.sig>

From diogo.ivo at siemens.com  Thu Feb  8 06:11:07 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Thu, 8 Feb 2024 14:11:07 +0000
Subject: [PATCH net] net: ti: icssg-prueth: Remove duplicate cleanup calls
 in emac_ndo_stop()
In-Reply-To: <2fa5f053-6b4f-40e4-86f5-807c3c6dfee9@moroto.mountain>
References: <20240206152052.98217-1-diogo.ivo@siemens.com>
 <20240208104700.GF1435458@kernel.org>
 <2fa5f053-6b4f-40e4-86f5-807c3c6dfee9@moroto.mountain>
Message-ID: <ca56b654-c088-4c04-8b00-b24067dd2ec1@siemens.com>


On 2/8/24 13:33, Dan Carpenter wrote:
> On Thu, Feb 08, 2024 at 10:47:00AM +0000, Simon Horman wrote:
>> On Tue, Feb 06, 2024 at 03:20:51PM +0000, Diogo Ivo wrote:
>>> Remove the duplicate calls to prueth_emac_stop() and
>>> prueth_cleanup_tx_chns() in emac_ndo_stop().
>>>
>>> Fixes: 128d5874c082 ("net: ti: icssg-prueth: Add ICSSG ethernet driver")
>>> Fixes: 186734c15886 ("net: ti: icssg-prueth: add packet timestamping and ptp support")
>>> Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
>> Hi Doigo,
>>
>> I see that there are indeed duplicate calls,
>> but I do wonder if this is a cleanup rather than a bug:
>> is there a user-visible problem that this addresses?
>>
>> If so, I think it would be good to spell this out in the commit message.
>>
>> ...
> So far as I can see from reviewing the code there is no user visible
> effect.
>
> rproc_shutdown() calls rproc_stop() which sets "rproc->state = RPROC_OFFLINE;"
> so the second call will return be a no-op and return -EINVAL.  But the
> return value is not checked so no problem.
>
> prueth_cleanup_tx_chns() uses memset to zero out the emac->tx_chns[] so
> the second call will be a no-op.
>
> regards,
> dan carpenter

Yes, it is just a code cleanup. Is the commit message fine as it is?


Best regards,

Diogo



From gabriel.fernandez at foss.st.com  Thu Feb  8 06:22:58 2024
From: gabriel.fernandez at foss.st.com (gabriel.fernandez at foss.st.com)
Date: Thu, 8 Feb 2024 15:22:58 +0100
Subject: [PATCH v9 1/4] clk: stm32mp13: use platform device APIs
In-Reply-To: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
References: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
Message-ID: <20240208142301.155698-2-gabriel.fernandez@foss.st.com>

From: Gabriel Fernandez <gabriel.fernandez at foss.st.com>

Convert devm_platform_ioremap_resource() and remove unnecessary
dependency check with SCMI clock driver.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
---
 drivers/clk/stm32/clk-stm32-core.c | 11 +++--
 drivers/clk/stm32/clk-stm32mp13.c  | 72 +++---------------------------
 2 files changed, 10 insertions(+), 73 deletions(-)

diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c
index 58705fcad334..1721a3ed7386 100644
--- a/drivers/clk/stm32/clk-stm32-core.c
+++ b/drivers/clk/stm32/clk-stm32-core.c
@@ -25,7 +25,6 @@ static int stm32_rcc_clock_init(struct device *dev,
 {
 	const struct stm32_rcc_match_data *data = match->data;
 	struct clk_hw_onecell_data *clk_data = data->hw_clks;
-	struct device_node *np = dev_of_node(dev);
 	struct clk_hw **hws;
 	int n, max_binding;
 
@@ -64,7 +63,7 @@ static int stm32_rcc_clock_init(struct device *dev,
 			hws[cfg_clock->id] = hw;
 	}
 
-	return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
 }
 
 int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data,
@@ -638,7 +637,7 @@ struct clk_hw *clk_stm32_mux_register(struct device *dev,
 	mux->lock = lock;
 	mux->clock_data = data->clock_data;
 
-	err = clk_hw_register(dev, hw);
+	err = devm_clk_hw_register(dev, hw);
 	if (err)
 		return ERR_PTR(err);
 
@@ -659,7 +658,7 @@ struct clk_hw *clk_stm32_gate_register(struct device *dev,
 	gate->lock = lock;
 	gate->clock_data = data->clock_data;
 
-	err = clk_hw_register(dev, hw);
+	err = devm_clk_hw_register(dev, hw);
 	if (err)
 		return ERR_PTR(err);
 
@@ -680,7 +679,7 @@ struct clk_hw *clk_stm32_div_register(struct device *dev,
 	div->lock = lock;
 	div->clock_data = data->clock_data;
 
-	err = clk_hw_register(dev, hw);
+	err = devm_clk_hw_register(dev, hw);
 	if (err)
 		return ERR_PTR(err);
 
@@ -701,7 +700,7 @@ struct clk_hw *clk_stm32_composite_register(struct device *dev,
 	composite->lock = lock;
 	composite->clock_data = data->clock_data;
 
-	err = clk_hw_register(dev, hw);
+	err = devm_clk_hw_register(dev, hw);
 	if (err)
 		return ERR_PTR(err);
 
diff --git a/drivers/clk/stm32/clk-stm32mp13.c b/drivers/clk/stm32/clk-stm32mp13.c
index d4ecb3c34a1b..bf81d7491708 100644
--- a/drivers/clk/stm32/clk-stm32mp13.c
+++ b/drivers/clk/stm32/clk-stm32mp13.c
@@ -1536,77 +1536,16 @@ static const struct of_device_id stm32mp13_match_data[] = {
 };
 MODULE_DEVICE_TABLE(of, stm32mp13_match_data);
 
-static int stm32mp1_rcc_init(struct device *dev)
-{
-	void __iomem *rcc_base;
-	int ret = -ENOMEM;
-
-	rcc_base = of_iomap(dev_of_node(dev), 0);
-	if (!rcc_base) {
-		dev_err(dev, "%pOFn: unable to map resource", dev_of_node(dev));
-		goto out;
-	}
-
-	ret = stm32_rcc_init(dev, stm32mp13_match_data, rcc_base);
-out:
-	if (ret) {
-		if (rcc_base)
-			iounmap(rcc_base);
-
-		of_node_put(dev_of_node(dev));
-	}
-
-	return ret;
-}
-
-static int get_clock_deps(struct device *dev)
-{
-	static const char * const clock_deps_name[] = {
-		"hsi", "hse", "csi", "lsi", "lse",
-	};
-	size_t deps_size = sizeof(struct clk *) * ARRAY_SIZE(clock_deps_name);
-	struct clk **clk_deps;
-	int i;
-
-	clk_deps = devm_kzalloc(dev, deps_size, GFP_KERNEL);
-	if (!clk_deps)
-		return -ENOMEM;
-
-	for (i = 0; i < ARRAY_SIZE(clock_deps_name); i++) {
-		struct clk *clk = of_clk_get_by_name(dev_of_node(dev),
-						     clock_deps_name[i]);
-
-		if (IS_ERR(clk)) {
-			if (PTR_ERR(clk) != -EINVAL && PTR_ERR(clk) != -ENOENT)
-				return PTR_ERR(clk);
-		} else {
-			/* Device gets a reference count on the clock */
-			clk_deps[i] = devm_clk_get(dev, __clk_get_name(clk));
-			clk_put(clk);
-		}
-	}
-
-	return 0;
-}
-
 static int stm32mp1_rcc_clocks_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	int ret = get_clock_deps(dev);
+	void __iomem *base;
 
-	if (!ret)
-		ret = stm32mp1_rcc_init(dev);
-
-	return ret;
-}
-
-static void stm32mp1_rcc_clocks_remove(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct device_node *child, *np = dev_of_node(dev);
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (WARN_ON(IS_ERR(base)))
+		return PTR_ERR(base);
 
-	for_each_available_child_of_node(np, child)
-		of_clk_del_provider(child);
+	return stm32_rcc_init(dev, stm32mp13_match_data, base);
 }
 
 static struct platform_driver stm32mp13_rcc_clocks_driver = {
@@ -1615,7 +1554,6 @@ static struct platform_driver stm32mp13_rcc_clocks_driver = {
 		.of_match_table = stm32mp13_match_data,
 	},
 	.probe = stm32mp1_rcc_clocks_probe,
-	.remove_new = stm32mp1_rcc_clocks_remove,
 };
 
 static int __init stm32mp13_clocks_init(void)
-- 
2.25.1



From gabriel.fernandez at foss.st.com  Thu Feb  8 06:22:59 2024
From: gabriel.fernandez at foss.st.com (gabriel.fernandez at foss.st.com)
Date: Thu, 8 Feb 2024 15:22:59 +0100
Subject: [PATCH v9 2/4] dt-bindings: stm32: update DT bingding for stm32mp25
In-Reply-To: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
References: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
Message-ID: <20240208142301.155698-3-gabriel.fernandez@foss.st.com>

From: Gabriel Fernandez <gabriel.fernandez at foss.st.com>

Now RCC driver use '.index' of clk_parent_data struct to define a parent.
The majority of parents are SCMI clocks, then dt-bindings must be fixed.

Fixes: b5be49db3d47 ("dt-bindings: stm32: add clocks and reset binding for stm32mp25 platform")

Signed-off-by: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
---
 .../bindings/clock/st,stm32mp25-rcc.yaml      | 171 ++++++++++++++++--
 1 file changed, 155 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml b/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml
index 7732e79a42b9..57bd4e7157bd 100644
--- a/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml
+++ b/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml
@@ -38,22 +38,87 @@ properties:
       - description: CK_SCMI_MSI Low Power Internal oscillator (~ 4 MHz or ~ 16 MHz)
       - description: CK_SCMI_LSE Low Speed External oscillator (32 KHz)
       - description: CK_SCMI_LSI Low Speed Internal oscillator (~ 32 KHz)
-
-  clock-names:
-    items:
-      - const: hse
-      - const: hsi
-      - const: msi
-      - const: lse
-      - const: lsi
-
+      - description: CK_SCMI_HSE_DIV2 CK_SCMI_HSE divided by 2 (coud be gated)
+      - description: CK_SCMI_ICN_HS_MCU High Speed interconnect bus clock
+      - description: CK_SCMI_ICN_LS_MCU Low Speed interconnect bus clock
+      - description: CK_SCMI_ICN_SDMMC SDMMC interconnect bus clock
+      - description: CK_SCMI_ICN_DDR DDR interconnect bus clock
+      - description: CK_SCMI_ICN_DISPLAY Display interconnect bus clock
+      - description: CK_SCMI_ICN_HSL HSL interconnect bus clock
+      - description: CK_SCMI_ICN_NIC NIC interconnect bus clock
+      - description: CK_SCMI_ICN_VID Video interconnect bus clock
+      - description: CK_SCMI_FLEXGEN_07 flexgen clock 7
+      - description: CK_SCMI_FLEXGEN_08 flexgen clock 8
+      - description: CK_SCMI_FLEXGEN_09 flexgen clock 9
+      - description: CK_SCMI_FLEXGEN_10 flexgen clock 10
+      - description: CK_SCMI_FLEXGEN_11 flexgen clock 11
+      - description: CK_SCMI_FLEXGEN_12 flexgen clock 12
+      - description: CK_SCMI_FLEXGEN_13 flexgen clock 13
+      - description: CK_SCMI_FLEXGEN_14 flexgen clock 14
+      - description: CK_SCMI_FLEXGEN_15 flexgen clock 15
+      - description: CK_SCMI_FLEXGEN_16 flexgen clock 16
+      - description: CK_SCMI_FLEXGEN_17 flexgen clock 17
+      - description: CK_SCMI_FLEXGEN_18 flexgen clock 18
+      - description: CK_SCMI_FLEXGEN_19 flexgen clock 19
+      - description: CK_SCMI_FLEXGEN_20 flexgen clock 20
+      - description: CK_SCMI_FLEXGEN_21 flexgen clock 21
+      - description: CK_SCMI_FLEXGEN_22 flexgen clock 22
+      - description: CK_SCMI_FLEXGEN_23 flexgen clock 23
+      - description: CK_SCMI_FLEXGEN_24 flexgen clock 24
+      - description: CK_SCMI_FLEXGEN_25 flexgen clock 25
+      - description: CK_SCMI_FLEXGEN_26 flexgen clock 26
+      - description: CK_SCMI_FLEXGEN_27 flexgen clock 27
+      - description: CK_SCMI_FLEXGEN_28 flexgen clock 28
+      - description: CK_SCMI_FLEXGEN_29 flexgen clock 29
+      - description: CK_SCMI_FLEXGEN_30 flexgen clock 30
+      - description: CK_SCMI_FLEXGEN_31 flexgen clock 31
+      - description: CK_SCMI_FLEXGEN_32 flexgen clock 32
+      - description: CK_SCMI_FLEXGEN_33 flexgen clock 33
+      - description: CK_SCMI_FLEXGEN_34 flexgen clock 34
+      - description: CK_SCMI_FLEXGEN_35 flexgen clock 35
+      - description: CK_SCMI_FLEXGEN_36 flexgen clock 36
+      - description: CK_SCMI_FLEXGEN_37 flexgen clock 37
+      - description: CK_SCMI_FLEXGEN_38 flexgen clock 38
+      - description: CK_SCMI_FLEXGEN_39 flexgen clock 39
+      - description: CK_SCMI_FLEXGEN_40 flexgen clock 40
+      - description: CK_SCMI_FLEXGEN_41 flexgen clock 41
+      - description: CK_SCMI_FLEXGEN_42 flexgen clock 42
+      - description: CK_SCMI_FLEXGEN_43 flexgen clock 43
+      - description: CK_SCMI_FLEXGEN_44 flexgen clock 44
+      - description: CK_SCMI_FLEXGEN_45 flexgen clock 45
+      - description: CK_SCMI_FLEXGEN_46 flexgen clock 46
+      - description: CK_SCMI_FLEXGEN_47 flexgen clock 47
+      - description: CK_SCMI_FLEXGEN_48 flexgen clock 48
+      - description: CK_SCMI_FLEXGEN_49 flexgen clock 49
+      - description: CK_SCMI_FLEXGEN_50 flexgen clock 50
+      - description: CK_SCMI_FLEXGEN_51 flexgen clock 51
+      - description: CK_SCMI_FLEXGEN_52 flexgen clock 52
+      - description: CK_SCMI_FLEXGEN_53 flexgen clock 53
+      - description: CK_SCMI_FLEXGEN_54 flexgen clock 54
+      - description: CK_SCMI_FLEXGEN_55 flexgen clock 55
+      - description: CK_SCMI_FLEXGEN_56 flexgen clock 56
+      - description: CK_SCMI_FLEXGEN_57 flexgen clock 57
+      - description: CK_SCMI_FLEXGEN_58 flexgen clock 58
+      - description: CK_SCMI_FLEXGEN_59 flexgen clock 59
+      - description: CK_SCMI_FLEXGEN_60 flexgen clock 60
+      - description: CK_SCMI_FLEXGEN_61 flexgen clock 61
+      - description: CK_SCMI_FLEXGEN_62 flexgen clock 62
+      - description: CK_SCMI_FLEXGEN_63 flexgen clock 63
+      - description: CK_SCMI_ICN_APB1 Peripheral bridge 1
+      - description: CK_SCMI_ICN_APB2 Peripheral bridge 2
+      - description: CK_SCMI_ICN_APB3 Peripheral bridge 3
+      - description: CK_SCMI_ICN_APB4 Peripheral bridge 4
+      - description: CK_SCMI_ICN_APBDBG Peripheral bridge for degub
+      - description: CK_SCMI_TIMG1 Peripheral bridge for timer1
+      - description: CK_SCMI_TIMG2 Peripheral bridge for timer2
+      - description: CK_SCMI_PLL3 PLL3 clock
+      - description: clk_dsi_txbyte DSI byte clock
 required:
   - compatible
   - reg
   - '#clock-cells'
   - '#reset-cells'
   - clocks
-  - clock-names
 
 additionalProperties: false
 
@@ -66,11 +131,85 @@ examples:
         reg = <0x44200000 0x10000>;
         #clock-cells = <1>;
         #reset-cells = <1>;
-        clock-names = "hse", "hsi", "msi", "lse", "lsi";
-        clocks = <&scmi_clk CK_SCMI_HSE>,
-                 <&scmi_clk CK_SCMI_HSI>,
-                 <&scmi_clk CK_SCMI_MSI>,
-                 <&scmi_clk CK_SCMI_LSE>,
-                 <&scmi_clk CK_SCMI_LSI>;
+        clocks =  <&scmi_clk CK_SCMI_HSE>,
+                  <&scmi_clk CK_SCMI_HSI>,
+                  <&scmi_clk CK_SCMI_MSI>,
+                  <&scmi_clk CK_SCMI_LSE>,
+                  <&scmi_clk CK_SCMI_LSI>,
+                  <&scmi_clk CK_SCMI_HSE_DIV2>,
+                  <&scmi_clk CK_SCMI_ICN_HS_MCU>,
+                  <&scmi_clk CK_SCMI_ICN_LS_MCU>,
+                  <&scmi_clk CK_SCMI_ICN_SDMMC>,
+                  <&scmi_clk CK_SCMI_ICN_DDR>,
+                  <&scmi_clk CK_SCMI_ICN_DISPLAY>,
+                  <&scmi_clk CK_SCMI_ICN_HSL>,
+                  <&scmi_clk CK_SCMI_ICN_NIC>,
+                  <&scmi_clk CK_SCMI_ICN_VID>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_07>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_08>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_09>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_10>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_11>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_12>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_13>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_14>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_15>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_16>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_17>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_18>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_19>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_20>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_21>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_22>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_23>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_24>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_25>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_26>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_27>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_28>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_29>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_30>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_31>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_32>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_33>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_34>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_35>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_36>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_37>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_38>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_39>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_40>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_41>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_42>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_43>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_44>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_45>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_46>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_47>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_48>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_49>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_50>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_51>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_52>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_53>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_54>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_55>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_56>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_57>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_58>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_59>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_60>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_61>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_62>,
+                  <&scmi_clk CK_SCMI_FLEXGEN_63>,
+                  <&scmi_clk CK_SCMI_ICN_APB1>,
+                  <&scmi_clk CK_SCMI_ICN_APB2>,
+                  <&scmi_clk CK_SCMI_ICN_APB3>,
+                  <&scmi_clk CK_SCMI_ICN_APB4>,
+                  <&scmi_clk CK_SCMI_ICN_APBDBG>,
+                  <&scmi_clk CK_SCMI_TIMG1>,
+                  <&scmi_clk CK_SCMI_TIMG2>,
+                  <&scmi_clk CK_SCMI_PLL3>,
+                  <&clk_dsi_txbyte>;
     };
 ...
-- 
2.25.1



From gabriel.fernandez at foss.st.com  Thu Feb  8 06:22:57 2024
From: gabriel.fernandez at foss.st.com (gabriel.fernandez at foss.st.com)
Date: Thu, 8 Feb 2024 15:22:57 +0100
Subject: [PATCH v9 0/4] Introduce STM32MP257 clock driver
Message-ID: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>

From: Gabriel Fernandez <gabriel.fernandez at foss.st.com>

v9: base on next-20240207
  - update dt binding documentation with v8 modidification on RCC driver
    (use .index of clk_parent_data struct to define a parent)
  - rebase patch "arm64: dts: st: add rcc support for STM32MP25"
     with next-20240207 tag

v8:
  - use .index of clk_parent_data struct to define a parent
  - remove unnecessary dependency check with SCMI clock driver
  - convert to platform device APIs
  - convert to devm_of_clk_add_hw_provider()
  - convert single value enum to a define

v7: base on next-20231219
  - These patches below are applied to clk-next:
      clk: stm32mp1: move stm32mp1 clock driver into stm32 directory
      clk: stm32mp1: use stm32mp13 reset driver
      dt-bindings: stm32: add clocks and reset binding for stm32mp25
  - remove unnecessary includes
  - migrate clock parents to struct clk_parent_data and remove
    CLK_STM32_XXX() macros  to have a more readble code
  - use platform device APIs (devm_of_iomap() instead of_iomap())
  - move content of stm32mp25_rcc_init() to stm32mp25_rcc_clocks_probe()
  - simply get_clock_deps()
  - add const to stm32mp25_data struct
  - remove ck_icn_p_serc clock (will be integrate later with security
    management)

v6:
  - remove useless defines in drivers/clk/stm32/stm32mp25_rcc.h

v5:
  - Fix sparse warnings: was not declared. Should it be static?
    drivers/clk/stm32/clk-stm32mp13.c:1516:29: symbol 'stm32mp13_reset_data'
    drivers/clk/stm32/clk-stm32mp1.c:2148:29: symbol 'stm32mp1_reset_data'
    drivers/clk/stm32/clk-stm32mp25.c:1003:5: symbol 'stm32mp25_cpt_gate'
    drivers/clk/stm32/clk-stm32mp25.c:1005:29: symbol 'stm32mp25_clock_data'
    drivers/clk/stm32/clk-stm32mp25.c:1011:29: symbol 'stm32mp25_reset_data'

v4:
  - use GPL-2.0-only OR BSD-2-Clause for clock and reset binding files
  - use quotes ' for #clock-cells and #reset-cells in YAML documentation
  - reset binding start now to 0 instead 1
  - improve management of reset lines that are not managed

v3:
  - from Rob Herring change clock item description in YAML documentation
v2:
  - rework reset binding (use ID witch start from 0)
  - rework reset driver to manage STM32MP13 / STM32MP15 / STM32MP25
  - rework YAML documentation

Gabriel Fernandez (4):
  clk: stm32mp13: use platform device APIs
  dt-bindings: stm32: update DT bingding for stm32mp25
  clk: stm32: introduce clocks for STM32MP257 platform
  arm64: dts: st: add rcc support for STM32MP25

 .../bindings/clock/st,stm32mp25-rcc.yaml      |  171 +-
 arch/arm64/boot/dts/st/stm32mp251.dtsi        |  144 +-
 arch/arm64/boot/dts/st/stm32mp255.dtsi        |    4 +-
 drivers/clk/stm32/Kconfig                     |    7 +
 drivers/clk/stm32/Makefile                    |    1 +
 drivers/clk/stm32/clk-stm32-core.c            |   11 +-
 drivers/clk/stm32/clk-stm32mp13.c             |   72 +-
 drivers/clk/stm32/clk-stm32mp25.c             | 1876 +++++++++++++++++
 drivers/clk/stm32/reset-stm32.c               |   59 +-
 drivers/clk/stm32/reset-stm32.h               |    7 +
 drivers/clk/stm32/stm32mp25_rcc.h             |  712 +++++++
 11 files changed, 2922 insertions(+), 142 deletions(-)
 create mode 100644 drivers/clk/stm32/clk-stm32mp25.c
 create mode 100644 drivers/clk/stm32/stm32mp25_rcc.h

-- 
2.25.1



From gabriel.fernandez at foss.st.com  Thu Feb  8 06:23:00 2024
From: gabriel.fernandez at foss.st.com (gabriel.fernandez at foss.st.com)
Date: Thu, 8 Feb 2024 15:23:00 +0100
Subject: [PATCH v9 3/4] clk: stm32: introduce clocks for STM32MP257 platform
In-Reply-To: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
References: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
Message-ID: <20240208142301.155698-4-gabriel.fernandez@foss.st.com>

From: Gabriel Fernandez <gabriel.fernandez at foss.st.com>

This driver is intended for the STM32MP25 clock family and utilizes
the stm32-core API, similar to the stm32mp13 clock driver.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
---
 drivers/clk/stm32/Kconfig         |    7 +
 drivers/clk/stm32/Makefile        |    1 +
 drivers/clk/stm32/clk-stm32mp25.c | 1876 +++++++++++++++++++++++++++++
 drivers/clk/stm32/reset-stm32.c   |   59 +-
 drivers/clk/stm32/reset-stm32.h   |    7 +
 drivers/clk/stm32/stm32mp25_rcc.h |  712 +++++++++++
 6 files changed, 2647 insertions(+), 15 deletions(-)
 create mode 100644 drivers/clk/stm32/clk-stm32mp25.c
 create mode 100644 drivers/clk/stm32/stm32mp25_rcc.h

diff --git a/drivers/clk/stm32/Kconfig b/drivers/clk/stm32/Kconfig
index 3c8493a94a11..dca409d52652 100644
--- a/drivers/clk/stm32/Kconfig
+++ b/drivers/clk/stm32/Kconfig
@@ -25,5 +25,12 @@ config COMMON_CLK_STM32MP157
 	help
 	  Support for stm32mp15x SoC family clocks.
 
+config COMMON_CLK_STM32MP257
+	bool "Clock driver for stm32mp25x clocks"
+	depends on ARM64 || COMPILE_TEST
+	default y
+	help
+	  Support for stm32mp25x SoC family clocks.
+
 endif
 
diff --git a/drivers/clk/stm32/Makefile b/drivers/clk/stm32/Makefile
index 5ced7fe3ddec..0a627164fcce 100644
--- a/drivers/clk/stm32/Makefile
+++ b/drivers/clk/stm32/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_COMMON_CLK_STM32MP135)	+= clk-stm32mp13.o clk-stm32-core.o reset-stm32.o
 obj-$(CONFIG_COMMON_CLK_STM32MP157)	+= clk-stm32mp1.o reset-stm32.o
+obj-$(CONFIG_COMMON_CLK_STM32MP257)	+= clk-stm32mp25.o clk-stm32-core.o reset-stm32.o
diff --git a/drivers/clk/stm32/clk-stm32mp25.c b/drivers/clk/stm32/clk-stm32mp25.c
new file mode 100644
index 000000000000..701b6142dbab
--- /dev/null
+++ b/drivers/clk/stm32/clk-stm32mp25.c
@@ -0,0 +1,1876 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez at foss.st.com> for STMicroelectronics.
+ */
+
+#include <linux/clk.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "clk-stm32-core.h"
+#include "reset-stm32.h"
+#include "stm32mp25_rcc.h"
+
+#include <dt-bindings/clock/st,stm32mp25-rcc.h>
+#include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+enum {
+	HSE,
+	HSI,
+	MSI,
+	LSE,
+	LSI,
+	HSE_DIV2,
+	ICN_HS_MCU,
+	ICN_LS_MCU,
+	ICN_SDMMC,
+	ICN_DDR,
+	ICN_DISPLAY,
+	ICN_HSL,
+	ICN_NIC,
+	ICN_VID,
+	FLEXGEN_07,
+	FLEXGEN_08,
+	FLEXGEN_09,
+	FLEXGEN_10,
+	FLEXGEN_11,
+	FLEXGEN_12,
+	FLEXGEN_13,
+	FLEXGEN_14,
+	FLEXGEN_15,
+	FLEXGEN_16,
+	FLEXGEN_17,
+	FLEXGEN_18,
+	FLEXGEN_19,
+	FLEXGEN_20,
+	FLEXGEN_21,
+	FLEXGEN_22,
+	FLEXGEN_23,
+	FLEXGEN_24,
+	FLEXGEN_25,
+	FLEXGEN_26,
+	FLEXGEN_27,
+	FLEXGEN_28,
+	FLEXGEN_29,
+	FLEXGEN_30,
+	FLEXGEN_31,
+	FLEXGEN_32,
+	FLEXGEN_33,
+	FLEXGEN_34,
+	FLEXGEN_35,
+	FLEXGEN_36,
+	FLEXGEN_37,
+	FLEXGEN_38,
+	FLEXGEN_39,
+	FLEXGEN_40,
+	FLEXGEN_41,
+	FLEXGEN_42,
+	FLEXGEN_43,
+	FLEXGEN_44,
+	FLEXGEN_45,
+	FLEXGEN_46,
+	FLEXGEN_47,
+	FLEXGEN_48,
+	FLEXGEN_49,
+	FLEXGEN_50,
+	FLEXGEN_51,
+	FLEXGEN_52,
+	FLEXGEN_53,
+	FLEXGEN_54,
+	FLEXGEN_55,
+	FLEXGEN_56,
+	FLEXGEN_57,
+	FLEXGEN_58,
+	FLEXGEN_59,
+	FLEXGEN_60,
+	FLEXGEN_61,
+	FLEXGEN_62,
+	FLEXGEN_63,
+	ICN_APB1,
+	ICN_APB2,
+	ICN_APB3,
+	ICN_APB4,
+	ICN_APBDBG,
+	TIMG1,
+	TIMG2,
+	PLL3,
+	DSI_TXBYTE,
+};
+
+static const struct clk_parent_data adc12_src[] = {
+	{ .index = FLEXGEN_46 },
+	{ .index = ICN_LS_MCU },
+};
+
+static const struct clk_parent_data adc3_src[] = {
+	{ .index = FLEXGEN_47 },
+	{ .index = ICN_LS_MCU },
+	{ .index = FLEXGEN_46 },
+};
+
+static const struct clk_parent_data usb2phy1_src[] = {
+	{ .index = FLEXGEN_57 },
+	{ .index = HSE_DIV2 },
+};
+
+static const struct clk_parent_data usb2phy2_src[] = {
+	{ .index = FLEXGEN_58 },
+	{ .index = HSE_DIV2 },
+};
+
+static const struct clk_parent_data usb3pciphy_src[] = {
+	{ .index = FLEXGEN_34 },
+	{ .index = HSE_DIV2 },
+};
+
+static struct clk_stm32_gate ck_ker_ltdc;
+
+static const struct clk_parent_data dsiblane_src[] = {
+	{ .index = DSI_TXBYTE },
+	{ .hw = &ck_ker_ltdc.hw },
+};
+
+static const struct clk_parent_data dsiphy_src[] = {
+	{ .index = FLEXGEN_28 },
+	{ .index = HSE },
+};
+
+static const struct clk_parent_data lvdsphy_src[] = {
+	{ .index = FLEXGEN_32 },
+	{ .index = HSE },
+};
+
+static const struct clk_parent_data dts_src[] = {
+	{ .index = HSI },
+	{ .index = HSE },
+	{ .index = MSI },
+};
+
+static const struct clk_parent_data mco1_src[] = {
+	{ .index = FLEXGEN_61 },
+};
+
+static const struct clk_parent_data mco2_src[] = {
+	{ .index = FLEXGEN_62 },
+};
+
+enum enum_mux_cfg {
+	MUX_ADC12,
+	MUX_ADC3,
+	MUX_DSIBLANE,
+	MUX_DSIPHY,
+	MUX_DTS,
+	MUX_LVDSPHY,
+	MUX_MCO1,
+	MUX_MCO2,
+	MUX_USB2PHY1,
+	MUX_USB2PHY2,
+	MUX_USB3PCIEPHY,
+	MUX_NB
+};
+
+#define MUX_CFG(id, _offset, _shift, _witdh)	\
+	[id] = {				\
+		.offset		= (_offset),	\
+		.shift		= (_shift),	\
+		.width		= (_witdh),	\
+	}
+
+static const struct stm32_mux_cfg stm32mp25_muxes[MUX_NB] = {
+	MUX_CFG(MUX_ADC12,		RCC_ADC12CFGR,		12,	1),
+	MUX_CFG(MUX_ADC3,		RCC_ADC3CFGR,		12,	2),
+	MUX_CFG(MUX_DSIBLANE,		RCC_DSICFGR,		12,	1),
+	MUX_CFG(MUX_DSIPHY,		RCC_DSICFGR,		15,	1),
+	MUX_CFG(MUX_DTS,		RCC_DTSCFGR,		12,	2),
+	MUX_CFG(MUX_LVDSPHY,		RCC_LVDSCFGR,		15,	1),
+	MUX_CFG(MUX_MCO1,		RCC_MCO1CFGR,		0,	1),
+	MUX_CFG(MUX_MCO2,		RCC_MCO2CFGR,		0,	1),
+	MUX_CFG(MUX_USB2PHY1,		RCC_USB2PHY1CFGR,	15,	1),
+	MUX_CFG(MUX_USB2PHY2,		RCC_USB2PHY2CFGR,	15,	1),
+	MUX_CFG(MUX_USB3PCIEPHY,	RCC_USB3PCIEPHYCFGR,	15,	1),
+};
+
+enum enum_gate_cfg {
+	GATE_ADC12,
+	GATE_ADC3,
+	GATE_ADF1,
+	GATE_CCI,
+	GATE_CRC,
+	GATE_CRYP1,
+	GATE_CRYP2,
+	GATE_CSI,
+	GATE_DCMIPP,
+	GATE_DSI,
+	GATE_DTS,
+	GATE_ETH1,
+	GATE_ETH1MAC,
+	GATE_ETH1RX,
+	GATE_ETH1STP,
+	GATE_ETH1TX,
+	GATE_ETH2,
+	GATE_ETH2MAC,
+	GATE_ETH2RX,
+	GATE_ETH2STP,
+	GATE_ETH2TX,
+	GATE_ETHSW,
+	GATE_ETHSWACMCFG,
+	GATE_ETHSWACMMSG,
+	GATE_ETHSWMAC,
+	GATE_ETHSWREF,
+	GATE_FDCAN,
+	GATE_GPU,
+	GATE_HASH,
+	GATE_HDP,
+	GATE_I2C1,
+	GATE_I2C2,
+	GATE_I2C3,
+	GATE_I2C4,
+	GATE_I2C5,
+	GATE_I2C6,
+	GATE_I2C7,
+	GATE_I2C8,
+	GATE_I3C1,
+	GATE_I3C2,
+	GATE_I3C3,
+	GATE_I3C4,
+	GATE_IS2M,
+	GATE_IWDG1,
+	GATE_IWDG2,
+	GATE_IWDG3,
+	GATE_IWDG4,
+	GATE_IWDG5,
+	GATE_LPTIM1,
+	GATE_LPTIM2,
+	GATE_LPTIM3,
+	GATE_LPTIM4,
+	GATE_LPTIM5,
+	GATE_LPUART1,
+	GATE_LTDC,
+	GATE_LVDS,
+	GATE_MCO1,
+	GATE_MCO2,
+	GATE_MDF1,
+	GATE_OSPIIOM,
+	GATE_PCIE,
+	GATE_PKA,
+	GATE_RNG,
+	GATE_SAES,
+	GATE_SAI1,
+	GATE_SAI2,
+	GATE_SAI3,
+	GATE_SAI4,
+	GATE_SDMMC1,
+	GATE_SDMMC2,
+	GATE_SDMMC3,
+	GATE_SERC,
+	GATE_SPDIFRX,
+	GATE_SPI1,
+	GATE_SPI2,
+	GATE_SPI3,
+	GATE_SPI4,
+	GATE_SPI5,
+	GATE_SPI6,
+	GATE_SPI7,
+	GATE_SPI8,
+	GATE_TIM1,
+	GATE_TIM10,
+	GATE_TIM11,
+	GATE_TIM12,
+	GATE_TIM13,
+	GATE_TIM14,
+	GATE_TIM15,
+	GATE_TIM16,
+	GATE_TIM17,
+	GATE_TIM2,
+	GATE_TIM20,
+	GATE_TIM3,
+	GATE_TIM4,
+	GATE_TIM5,
+	GATE_TIM6,
+	GATE_TIM7,
+	GATE_TIM8,
+	GATE_UART4,
+	GATE_UART5,
+	GATE_UART7,
+	GATE_UART8,
+	GATE_UART9,
+	GATE_USART1,
+	GATE_USART2,
+	GATE_USART3,
+	GATE_USART6,
+	GATE_USB2,
+	GATE_USB2PHY1,
+	GATE_USB2PHY2,
+	GATE_USB3DR,
+	GATE_USB3PCIEPHY,
+	GATE_USBTC,
+	GATE_VDEC,
+	GATE_VENC,
+	GATE_VREF,
+	GATE_WWDG1,
+	GATE_WWDG2,
+	GATE_NB
+};
+
+#define GATE_CFG(id, _offset, _bit_idx, _offset_clr)	\
+	[id] = {					\
+		.offset		= (_offset),		\
+		.bit_idx	= (_bit_idx),		\
+		.set_clr	= (_offset_clr),	\
+	}
+
+static const struct stm32_gate_cfg stm32mp25_gates[GATE_NB] = {
+	GATE_CFG(GATE_ADC12,		RCC_ADC12CFGR,		1,	0),
+	GATE_CFG(GATE_ADC3,		RCC_ADC3CFGR,		1,	0),
+	GATE_CFG(GATE_ADF1,		RCC_ADF1CFGR,		1,	0),
+	GATE_CFG(GATE_CCI,		RCC_CCICFGR,		1,	0),
+	GATE_CFG(GATE_CRC,		RCC_CRCCFGR,		1,	0),
+	GATE_CFG(GATE_CRYP1,		RCC_CRYP1CFGR,		1,	0),
+	GATE_CFG(GATE_CRYP2,		RCC_CRYP2CFGR,		1,	0),
+	GATE_CFG(GATE_CSI,		RCC_CSICFGR,		1,	0),
+	GATE_CFG(GATE_DCMIPP,		RCC_DCMIPPCFGR,		1,	0),
+	GATE_CFG(GATE_DSI,		RCC_DSICFGR,		1,	0),
+	GATE_CFG(GATE_DTS,		RCC_DTSCFGR,		1,	0),
+	GATE_CFG(GATE_ETH1,		RCC_ETH1CFGR,		5,	0),
+	GATE_CFG(GATE_ETH1MAC,		RCC_ETH1CFGR,		1,	0),
+	GATE_CFG(GATE_ETH1RX,		RCC_ETH1CFGR,		10,	0),
+	GATE_CFG(GATE_ETH1STP,		RCC_ETH1CFGR,		4,	0),
+	GATE_CFG(GATE_ETH1TX,		RCC_ETH1CFGR,		8,	0),
+	GATE_CFG(GATE_ETH2,		RCC_ETH2CFGR,		5,	0),
+	GATE_CFG(GATE_ETH2MAC,		RCC_ETH2CFGR,		1,	0),
+	GATE_CFG(GATE_ETH2RX,		RCC_ETH2CFGR,		10,	0),
+	GATE_CFG(GATE_ETH2STP,		RCC_ETH2CFGR,		4,	0),
+	GATE_CFG(GATE_ETH2TX,		RCC_ETH2CFGR,		8,	0),
+	GATE_CFG(GATE_ETHSW,		RCC_ETHSWCFGR,		5,	0),
+	GATE_CFG(GATE_ETHSWACMCFG,	RCC_ETHSWACMCFGR,	1,	0),
+	GATE_CFG(GATE_ETHSWACMMSG,	RCC_ETHSWACMMSGCFGR,	1,	0),
+	GATE_CFG(GATE_ETHSWMAC,		RCC_ETHSWCFGR,		1,	0),
+	GATE_CFG(GATE_ETHSWREF,		RCC_ETHSWCFGR,		21,	0),
+	GATE_CFG(GATE_FDCAN,		RCC_FDCANCFGR,		1,	0),
+	GATE_CFG(GATE_GPU,		RCC_GPUCFGR,		1,	0),
+	GATE_CFG(GATE_HASH,		RCC_HASHCFGR,		1,	0),
+	GATE_CFG(GATE_HDP,		RCC_HDPCFGR,		1,	0),
+	GATE_CFG(GATE_I2C1,		RCC_I2C1CFGR,		1,	0),
+	GATE_CFG(GATE_I2C2,		RCC_I2C2CFGR,		1,	0),
+	GATE_CFG(GATE_I2C3,		RCC_I2C3CFGR,		1,	0),
+	GATE_CFG(GATE_I2C4,		RCC_I2C4CFGR,		1,	0),
+	GATE_CFG(GATE_I2C5,		RCC_I2C5CFGR,		1,	0),
+	GATE_CFG(GATE_I2C6,		RCC_I2C6CFGR,		1,	0),
+	GATE_CFG(GATE_I2C7,		RCC_I2C7CFGR,		1,	0),
+	GATE_CFG(GATE_I2C8,		RCC_I2C8CFGR,		1,	0),
+	GATE_CFG(GATE_I3C1,		RCC_I3C1CFGR,		1,	0),
+	GATE_CFG(GATE_I3C2,		RCC_I3C2CFGR,		1,	0),
+	GATE_CFG(GATE_I3C3,		RCC_I3C3CFGR,		1,	0),
+	GATE_CFG(GATE_I3C4,		RCC_I3C4CFGR,		1,	0),
+	GATE_CFG(GATE_IS2M,		RCC_IS2MCFGR,		1,	0),
+	GATE_CFG(GATE_IWDG1,		RCC_IWDG1CFGR,		1,	0),
+	GATE_CFG(GATE_IWDG2,		RCC_IWDG2CFGR,		1,	0),
+	GATE_CFG(GATE_IWDG3,		RCC_IWDG3CFGR,		1,	0),
+	GATE_CFG(GATE_IWDG4,		RCC_IWDG4CFGR,		1,	0),
+	GATE_CFG(GATE_IWDG5,		RCC_IWDG5CFGR,		1,	0),
+	GATE_CFG(GATE_LPTIM1,		RCC_LPTIM1CFGR,		1,	0),
+	GATE_CFG(GATE_LPTIM2,		RCC_LPTIM2CFGR,		1,	0),
+	GATE_CFG(GATE_LPTIM3,		RCC_LPTIM3CFGR,		1,	0),
+	GATE_CFG(GATE_LPTIM4,		RCC_LPTIM4CFGR,		1,	0),
+	GATE_CFG(GATE_LPTIM5,		RCC_LPTIM5CFGR,		1,	0),
+	GATE_CFG(GATE_LPUART1,		RCC_LPUART1CFGR,	1,	0),
+	GATE_CFG(GATE_LTDC,		RCC_LTDCCFGR,		1,	0),
+	GATE_CFG(GATE_LVDS,		RCC_LVDSCFGR,		1,	0),
+	GATE_CFG(GATE_MCO1,		RCC_MCO1CFGR,		8,	0),
+	GATE_CFG(GATE_MCO2,		RCC_MCO2CFGR,		8,	0),
+	GATE_CFG(GATE_MDF1,		RCC_MDF1CFGR,		1,	0),
+	GATE_CFG(GATE_OSPIIOM,		RCC_OSPIIOMCFGR,	1,	0),
+	GATE_CFG(GATE_PCIE,		RCC_PCIECFGR,		1,	0),
+	GATE_CFG(GATE_PKA,		RCC_PKACFGR,		1,	0),
+	GATE_CFG(GATE_RNG,		RCC_RNGCFGR,		1,	0),
+	GATE_CFG(GATE_SAES,		RCC_SAESCFGR,		1,	0),
+	GATE_CFG(GATE_SAI1,		RCC_SAI1CFGR,		1,	0),
+	GATE_CFG(GATE_SAI2,		RCC_SAI2CFGR,		1,	0),
+	GATE_CFG(GATE_SAI3,		RCC_SAI3CFGR,		1,	0),
+	GATE_CFG(GATE_SAI4,		RCC_SAI4CFGR,		1,	0),
+	GATE_CFG(GATE_SDMMC1,		RCC_SDMMC1CFGR,		1,	0),
+	GATE_CFG(GATE_SDMMC2,		RCC_SDMMC2CFGR,		1,	0),
+	GATE_CFG(GATE_SDMMC3,		RCC_SDMMC3CFGR,		1,	0),
+	GATE_CFG(GATE_SERC,		RCC_SERCCFGR,		1,	0),
+	GATE_CFG(GATE_SPDIFRX,		RCC_SPDIFRXCFGR,	1,	0),
+	GATE_CFG(GATE_SPI1,		RCC_SPI1CFGR,		1,	0),
+	GATE_CFG(GATE_SPI2,		RCC_SPI2CFGR,		1,	0),
+	GATE_CFG(GATE_SPI3,		RCC_SPI3CFGR,		1,	0),
+	GATE_CFG(GATE_SPI4,		RCC_SPI4CFGR,		1,	0),
+	GATE_CFG(GATE_SPI5,		RCC_SPI5CFGR,		1,	0),
+	GATE_CFG(GATE_SPI6,		RCC_SPI6CFGR,		1,	0),
+	GATE_CFG(GATE_SPI7,		RCC_SPI7CFGR,		1,	0),
+	GATE_CFG(GATE_SPI8,		RCC_SPI8CFGR,		1,	0),
+	GATE_CFG(GATE_TIM1,		RCC_TIM1CFGR,		1,	0),
+	GATE_CFG(GATE_TIM10,		RCC_TIM10CFGR,		1,	0),
+	GATE_CFG(GATE_TIM11,		RCC_TIM11CFGR,		1,	0),
+	GATE_CFG(GATE_TIM12,		RCC_TIM12CFGR,		1,	0),
+	GATE_CFG(GATE_TIM13,		RCC_TIM13CFGR,		1,	0),
+	GATE_CFG(GATE_TIM14,		RCC_TIM14CFGR,		1,	0),
+	GATE_CFG(GATE_TIM15,		RCC_TIM15CFGR,		1,	0),
+	GATE_CFG(GATE_TIM16,		RCC_TIM16CFGR,		1,	0),
+	GATE_CFG(GATE_TIM17,		RCC_TIM17CFGR,		1,	0),
+	GATE_CFG(GATE_TIM2,		RCC_TIM2CFGR,		1,	0),
+	GATE_CFG(GATE_TIM20,		RCC_TIM20CFGR,		1,	0),
+	GATE_CFG(GATE_TIM3,		RCC_TIM3CFGR,		1,	0),
+	GATE_CFG(GATE_TIM4,		RCC_TIM4CFGR,		1,	0),
+	GATE_CFG(GATE_TIM5,		RCC_TIM5CFGR,		1,	0),
+	GATE_CFG(GATE_TIM6,		RCC_TIM6CFGR,		1,	0),
+	GATE_CFG(GATE_TIM7,		RCC_TIM7CFGR,		1,	0),
+	GATE_CFG(GATE_TIM8,		RCC_TIM8CFGR,		1,	0),
+	GATE_CFG(GATE_UART4,		RCC_UART4CFGR,		1,	0),
+	GATE_CFG(GATE_UART5,		RCC_UART5CFGR,		1,	0),
+	GATE_CFG(GATE_UART7,		RCC_UART7CFGR,		1,	0),
+	GATE_CFG(GATE_UART8,		RCC_UART8CFGR,		1,	0),
+	GATE_CFG(GATE_UART9,		RCC_UART9CFGR,		1,	0),
+	GATE_CFG(GATE_USART1,		RCC_USART1CFGR,		1,	0),
+	GATE_CFG(GATE_USART2,		RCC_USART2CFGR,		1,	0),
+	GATE_CFG(GATE_USART3,		RCC_USART3CFGR,		1,	0),
+	GATE_CFG(GATE_USART6,		RCC_USART6CFGR,		1,	0),
+	GATE_CFG(GATE_USB2,		RCC_USB2CFGR,		1,	0),
+	GATE_CFG(GATE_USB2PHY1,		RCC_USB2PHY1CFGR,	1,	0),
+	GATE_CFG(GATE_USB2PHY2,		RCC_USB2PHY2CFGR,	1,	0),
+	GATE_CFG(GATE_USB3DR,		RCC_USB3DRCFGR,		1,	0),
+	GATE_CFG(GATE_USB3PCIEPHY,	RCC_USB3PCIEPHYCFGR,	1,	0),
+	GATE_CFG(GATE_USBTC,		RCC_USBTCCFGR,		1,	0),
+	GATE_CFG(GATE_VDEC,		RCC_VDECCFGR,		1,	0),
+	GATE_CFG(GATE_VENC,		RCC_VENCCFGR,		1,	0),
+	GATE_CFG(GATE_VREF,		RCC_VREFCFGR,		1,	0),
+	GATE_CFG(GATE_WWDG1,		RCC_WWDG1CFGR,		1,	0),
+	GATE_CFG(GATE_WWDG2,		RCC_WWDG2CFGR,		1,	0),
+};
+
+#define CLK_HW_INIT_INDEX(_name, _parent, _ops, _flags)		\
+	(&(struct clk_init_data) {					\
+		.flags		= _flags,				\
+		.name		= _name,				\
+		.parent_data	= (const struct clk_parent_data[]) {	\
+					{ .index = _parent },		\
+				  },					\
+		.num_parents	= 1,					\
+		.ops		= _ops,					\
+	})
+
+/* ADC */
+static struct clk_stm32_gate ck_icn_p_adc12 = {
+	.gate_id = GATE_ADC12,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_adc12", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_composite ck_ker_adc12 = {
+	.gate_id = GATE_ADC12,
+	.mux_id = MUX_ADC12,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_adc12", adc12_src, &clk_stm32_composite_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_adc3 = {
+	.gate_id = GATE_ADC3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_adc3", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_composite ck_ker_adc3 = {
+	.gate_id = GATE_ADC3,
+	.mux_id = MUX_ADC3,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_adc3", adc3_src, &clk_stm32_composite_ops, 0),
+};
+
+/* ADF */
+static struct clk_stm32_gate ck_icn_p_adf1 = {
+	.gate_id = GATE_ADF1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_adf1", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_adf1 = {
+	.gate_id = GATE_ADF1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_adf1", FLEXGEN_42, &clk_stm32_gate_ops, 0),
+};
+
+/* DCMI */
+static struct clk_stm32_gate ck_icn_p_cci = {
+	.gate_id = GATE_CCI,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_cci", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+/* CSI-HOST */
+static struct clk_stm32_gate ck_icn_p_csi = {
+	.gate_id = GATE_CSI,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_csi", ICN_APB4, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_csi = {
+	.gate_id = GATE_CSI,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_csi", FLEXGEN_29, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_csitxesc = {
+	.gate_id = GATE_CSI,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_csitxesc", FLEXGEN_30, &clk_stm32_gate_ops, 0),
+};
+
+/* CSI-PHY */
+static struct clk_stm32_gate ck_ker_csiphy = {
+	.gate_id = GATE_CSI,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_csiphy", FLEXGEN_31, &clk_stm32_gate_ops, 0),
+};
+
+/* DCMIPP */
+static struct clk_stm32_gate ck_icn_p_dcmipp = {
+	.gate_id = GATE_DCMIPP,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_dcmipp", ICN_APB4, &clk_stm32_gate_ops, 0),
+};
+
+/* CRC */
+static struct clk_stm32_gate ck_icn_p_crc = {
+	.gate_id = GATE_CRC,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_crc", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+/* CRYP */
+static struct clk_stm32_gate ck_icn_p_cryp1 = {
+	.gate_id = GATE_CRYP1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_cryp1", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_cryp2 = {
+	.gate_id = GATE_CRYP2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_cryp2", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+/* DBG & TRACE*/
+/* Trace and debug clocks are managed by SCMI */
+
+/* LTDC */
+static struct clk_stm32_gate ck_icn_p_ltdc = {
+	.gate_id = GATE_LTDC,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_ltdc", ICN_APB4, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_ltdc = {
+	.gate_id = GATE_LTDC,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_ltdc", FLEXGEN_27, &clk_stm32_gate_ops,
+				       CLK_SET_RATE_PARENT),
+};
+
+/* DSI */
+static struct clk_stm32_gate ck_icn_p_dsi = {
+	.gate_id = GATE_DSI,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_dsi", ICN_APB4, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_composite clk_lanebyte = {
+	.gate_id = GATE_DSI,
+	.mux_id = MUX_DSIBLANE,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("clk_lanebyte", dsiblane_src,
+					    &clk_stm32_composite_ops, 0),
+};
+
+/* LVDS */
+static struct clk_stm32_gate ck_icn_p_lvds = {
+	.gate_id = GATE_LVDS,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lvds", ICN_APB4, &clk_stm32_gate_ops, 0),
+};
+
+/* DSI PHY */
+static struct clk_stm32_composite clk_phy_dsi = {
+	.gate_id = GATE_DSI,
+	.mux_id = MUX_DSIPHY,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("clk_phy_dsi", dsiphy_src,
+					    &clk_stm32_composite_ops, 0),
+};
+
+/* LVDS PHY */
+static struct clk_stm32_composite ck_ker_lvdsphy = {
+	.gate_id = GATE_LVDS,
+	.mux_id = MUX_LVDSPHY,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_lvdsphy", lvdsphy_src,
+					    &clk_stm32_composite_ops, 0),
+};
+
+/* DTS */
+static struct clk_stm32_composite ck_ker_dts = {
+	.gate_id = GATE_DTS,
+	.mux_id = MUX_DTS,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_dts", dts_src,
+					    &clk_stm32_composite_ops, 0),
+};
+
+/* ETHERNET */
+static struct clk_stm32_gate ck_icn_p_eth1 = {
+	.gate_id = GATE_ETH1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_eth1", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth1stp = {
+	.gate_id = GATE_ETH1STP,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1stp", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth1 = {
+	.gate_id = GATE_ETH1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1", FLEXGEN_54, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth1ptp = {
+	.gate_id = GATE_ETH1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1ptp", FLEXGEN_56, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth1mac = {
+	.gate_id = GATE_ETH1MAC,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1mac", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth1tx = {
+	.gate_id = GATE_ETH1TX,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1tx", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth1rx = {
+	.gate_id = GATE_ETH1RX,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1rx", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_eth2 = {
+	.gate_id = GATE_ETH2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_eth2", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth2stp = {
+	.gate_id = GATE_ETH2STP,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2stp", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth2 = {
+	.gate_id = GATE_ETH2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2", FLEXGEN_55, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth2ptp = {
+	.gate_id = GATE_ETH2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2ptp", FLEXGEN_56, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth2mac = {
+	.gate_id = GATE_ETH2MAC,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2mac", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth2tx = {
+	.gate_id = GATE_ETH2TX,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2tx", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_eth2rx = {
+	.gate_id = GATE_ETH2RX,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2rx", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_ethsw = {
+	.gate_id = GATE_ETHSWMAC,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_ethsw", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_ethsw = {
+	.gate_id = GATE_ETHSW,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_ethsw", FLEXGEN_54, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_ethswref = {
+	.gate_id = GATE_ETHSWREF,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_ethswref", FLEXGEN_60, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_ethsw_acm_cfg = {
+	.gate_id = GATE_ETHSWACMCFG,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_ethsw_acm_cfg", ICN_LS_MCU,
+				       &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_ethsw_acm_msg = {
+	.gate_id = GATE_ETHSWACMMSG,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_ethsw_acm_msg", ICN_LS_MCU,
+				       &clk_stm32_gate_ops, 0),
+};
+
+/* FDCAN */
+static struct clk_stm32_gate ck_icn_p_fdcan = {
+	.gate_id = GATE_FDCAN,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_fdcan", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_fdcan = {
+	.gate_id = GATE_FDCAN,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_fdcan", FLEXGEN_26, &clk_stm32_gate_ops, 0),
+};
+
+/* GPU */
+static struct clk_stm32_gate ck_icn_m_gpu = {
+	.gate_id = GATE_GPU,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_m_gpu", FLEXGEN_59, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_gpu = {
+	.gate_id = GATE_GPU,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_gpu", PLL3, &clk_stm32_gate_ops, 0),
+};
+
+/* HASH */
+static struct clk_stm32_gate ck_icn_p_hash = {
+	.gate_id = GATE_HASH,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_hash", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+/* HDP */
+static struct clk_stm32_gate ck_icn_p_hdp = {
+	.gate_id = GATE_HDP,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_hdp", ICN_APB3, &clk_stm32_gate_ops, 0),
+};
+
+/* I2C */
+static struct clk_stm32_gate ck_icn_p_i2c8 = {
+	.gate_id = GATE_I2C8,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c8", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_i2c1 = {
+	.gate_id = GATE_I2C1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c1", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_i2c2 = {
+	.gate_id = GATE_I2C2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c2", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_i2c3 = {
+	.gate_id = GATE_I2C3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c3", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_i2c4 = {
+	.gate_id = GATE_I2C4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c4", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_i2c5 = {
+	.gate_id = GATE_I2C5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c5", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_i2c6 = {
+	.gate_id = GATE_I2C6,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c6", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_i2c7 = {
+	.gate_id = GATE_I2C7,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c7", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i2c1 = {
+	.gate_id = GATE_I2C1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c1", FLEXGEN_12, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i2c2 = {
+	.gate_id = GATE_I2C2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c2", FLEXGEN_12, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i2c3 = {
+	.gate_id = GATE_I2C3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c3", FLEXGEN_13, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i2c5 = {
+	.gate_id = GATE_I2C5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c5", FLEXGEN_13, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i2c4 = {
+	.gate_id = GATE_I2C4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c4", FLEXGEN_14, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i2c6 = {
+	.gate_id = GATE_I2C6,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c6", FLEXGEN_14, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i2c7 = {
+	.gate_id = GATE_I2C7,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c7", FLEXGEN_15, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i2c8 = {
+	.gate_id = GATE_I2C8,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c8", FLEXGEN_38, &clk_stm32_gate_ops, 0),
+};
+
+/* I3C */
+static struct clk_stm32_gate ck_icn_p_i3c1 = {
+	.gate_id = GATE_I3C1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i3c1", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_i3c2 = {
+	.gate_id = GATE_I3C2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i3c2", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_i3c3 = {
+	.gate_id = GATE_I3C3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i3c3", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_i3c4 = {
+	.gate_id = GATE_I3C4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i3c4", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i3c1 = {
+	.gate_id = GATE_I3C1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i3c1", FLEXGEN_12, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i3c2 = {
+	.gate_id = GATE_I3C2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i3c2", FLEXGEN_12, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i3c3 = {
+	.gate_id = GATE_I3C3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i3c3", FLEXGEN_13, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_i3c4 = {
+	.gate_id = GATE_I3C4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_i3c4", FLEXGEN_36, &clk_stm32_gate_ops, 0),
+};
+
+/* I2S */
+static struct clk_stm32_gate ck_icn_p_is2m = {
+	.gate_id = GATE_IS2M,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_is2m", ICN_APB3, &clk_stm32_gate_ops, 0),
+};
+
+/* IWDG */
+static struct clk_stm32_gate ck_icn_p_iwdg2 = {
+	.gate_id = GATE_IWDG2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_iwdg2", ICN_APB3, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_iwdg3 = {
+	.gate_id = GATE_IWDG3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_iwdg3", ICN_APB3, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_iwdg4 = {
+	.gate_id = GATE_IWDG4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_iwdg4", ICN_APB3, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_iwdg5 = {
+	.gate_id = GATE_IWDG5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_iwdg5", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+/* LPTIM */
+static struct clk_stm32_gate ck_icn_p_lptim1 = {
+	.gate_id = GATE_LPTIM1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lptim1", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_lptim2 = {
+	.gate_id = GATE_LPTIM2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lptim2", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_lptim3 = {
+	.gate_id = GATE_LPTIM3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lptim3", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_lptim4 = {
+	.gate_id = GATE_LPTIM4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lptim4", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_lptim5 = {
+	.gate_id = GATE_LPTIM5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lptim5", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_lptim1 = {
+	.gate_id = GATE_LPTIM1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_lptim1", FLEXGEN_07, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_lptim2 = {
+	.gate_id = GATE_LPTIM2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_lptim2", FLEXGEN_07, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_lptim3 = {
+	.gate_id = GATE_LPTIM3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_lptim3", FLEXGEN_40, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_lptim4 = {
+	.gate_id = GATE_LPTIM4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_lptim4", FLEXGEN_41, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_lptim5 = {
+	.gate_id = GATE_LPTIM5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_lptim5", FLEXGEN_41, &clk_stm32_gate_ops, 0),
+};
+
+/* LPUART */
+static struct clk_stm32_gate ck_icn_p_lpuart1 = {
+	.gate_id = GATE_LPUART1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lpuart1", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_lpuart1 = {
+	.gate_id = GATE_LPUART1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_lpuart1", FLEXGEN_39, &clk_stm32_gate_ops, 0),
+};
+
+/* MCO1 & MCO2 */
+static struct clk_stm32_composite ck_mco1 = {
+	.gate_id = GATE_MCO1,
+	.mux_id = MUX_MCO1,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("ck_mco1", mco1_src, &clk_stm32_composite_ops, 0),
+};
+
+static struct clk_stm32_composite ck_mco2 = {
+	.gate_id = GATE_MCO2,
+	.mux_id = MUX_MCO2,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("ck_mco2", mco2_src, &clk_stm32_composite_ops, 0),
+};
+
+/* MDF */
+static struct clk_stm32_gate ck_icn_p_mdf1 = {
+	.gate_id = GATE_MDF1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_mdf1", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_mdf1 = {
+	.gate_id = GATE_MDF1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_mdf1", FLEXGEN_23, &clk_stm32_gate_ops, 0),
+};
+
+/* OSPI */
+static struct clk_stm32_gate ck_icn_p_ospiiom = {
+	.gate_id = GATE_OSPIIOM,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_ospiiom", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+/* PCIE */
+static struct clk_stm32_gate ck_icn_p_pcie = {
+	.gate_id = GATE_PCIE,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_pcie", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+/* SAI */
+static struct clk_stm32_gate ck_icn_p_sai1 = {
+	.gate_id = GATE_SAI1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_sai1", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_sai2 = {
+	.gate_id = GATE_SAI2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_sai2", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_sai3 = {
+	.gate_id = GATE_SAI3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_sai3", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_sai4 = {
+	.gate_id = GATE_SAI4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_sai4", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_sai1 = {
+	.gate_id = GATE_SAI1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_sai1", FLEXGEN_23, &clk_stm32_gate_ops,
+				       CLK_SET_RATE_PARENT),
+};
+
+static struct clk_stm32_gate ck_ker_sai2 = {
+	.gate_id = GATE_SAI2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_sai2", FLEXGEN_24, &clk_stm32_gate_ops,
+				       CLK_SET_RATE_PARENT),
+};
+
+static struct clk_stm32_gate ck_ker_sai3 = {
+	.gate_id = GATE_SAI3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_sai3", FLEXGEN_25, &clk_stm32_gate_ops,
+				       CLK_SET_RATE_PARENT),
+};
+
+static struct clk_stm32_gate ck_ker_sai4 = {
+	.gate_id = GATE_SAI4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_sai4", FLEXGEN_25, &clk_stm32_gate_ops,
+				       CLK_SET_RATE_PARENT),
+};
+
+/* SDMMC */
+static struct clk_stm32_gate ck_icn_m_sdmmc1 = {
+	.gate_id = GATE_SDMMC1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_m_sdmmc1", ICN_SDMMC, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_m_sdmmc2 = {
+	.gate_id = GATE_SDMMC2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_m_sdmmc2", ICN_SDMMC, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_m_sdmmc3 = {
+	.gate_id = GATE_SDMMC3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_m_sdmmc3", ICN_SDMMC, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_sdmmc1 = {
+	.gate_id = GATE_SDMMC1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_sdmmc1", FLEXGEN_51, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_sdmmc2 = {
+	.gate_id = GATE_SDMMC2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_sdmmc2", FLEXGEN_52, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_sdmmc3 = {
+	.gate_id = GATE_SDMMC3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_sdmmc3", FLEXGEN_53, &clk_stm32_gate_ops, 0),
+};
+
+/* SPDIF */
+static struct clk_stm32_gate ck_icn_p_spdifrx = {
+	.gate_id = GATE_SPDIFRX,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spdifrx", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_spdifrx = {
+	.gate_id = GATE_SPDIFRX,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_spdifrx", FLEXGEN_11, &clk_stm32_gate_ops, 0),
+};
+
+/* SPI */
+static struct clk_stm32_gate ck_icn_p_spi1 = {
+	.gate_id = GATE_SPI1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi1", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_spi2 = {
+	.gate_id = GATE_SPI2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi2", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_spi3 = {
+	.gate_id = GATE_SPI3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi3", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_spi4 = {
+	.gate_id = GATE_SPI4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi4", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_spi5 = {
+	.gate_id = GATE_SPI5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi5", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_spi6 = {
+	.gate_id = GATE_SPI6,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi6", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_spi7 = {
+	.gate_id = GATE_SPI7,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi7", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_spi8 = {
+	.gate_id = GATE_SPI8,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi8", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_spi1 = {
+	.gate_id = GATE_SPI1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_spi1", FLEXGEN_16, &clk_stm32_gate_ops,
+				     CLK_SET_RATE_PARENT),
+};
+
+static struct clk_stm32_gate ck_ker_spi2 = {
+	.gate_id = GATE_SPI2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_spi2", FLEXGEN_10, &clk_stm32_gate_ops,
+				       CLK_SET_RATE_PARENT),
+};
+
+static struct clk_stm32_gate ck_ker_spi3 = {
+	.gate_id = GATE_SPI3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_spi3", FLEXGEN_10, &clk_stm32_gate_ops,
+				       CLK_SET_RATE_PARENT),
+};
+
+static struct clk_stm32_gate ck_ker_spi4 = {
+	.gate_id = GATE_SPI4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_spi4", FLEXGEN_17, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_spi5 = {
+	.gate_id = GATE_SPI5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_spi5", FLEXGEN_17, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_spi6 = {
+	.gate_id = GATE_SPI6,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_spi6", FLEXGEN_18, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_spi7 = {
+	.gate_id = GATE_SPI7,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_spi7", FLEXGEN_18, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_spi8 = {
+	.gate_id = GATE_SPI8,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_spi8", FLEXGEN_37, &clk_stm32_gate_ops, 0),
+};
+
+/* Timers */
+static struct clk_stm32_gate ck_icn_p_tim2 = {
+	.gate_id = GATE_TIM2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim2", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim3 = {
+	.gate_id = GATE_TIM3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim3", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim4 = {
+	.gate_id = GATE_TIM4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim4", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim5 = {
+	.gate_id = GATE_TIM5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim5", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim6 = {
+	.gate_id = GATE_TIM6,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim6", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim7 = {
+	.gate_id = GATE_TIM7,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim7", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim10 = {
+	.gate_id = GATE_TIM10,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim10", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim11 = {
+	.gate_id = GATE_TIM11,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim11", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim12 = {
+	.gate_id = GATE_TIM12,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim12", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim13 = {
+	.gate_id = GATE_TIM13,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim13", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim14 = {
+	.gate_id = GATE_TIM14,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim14", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim1 = {
+	.gate_id = GATE_TIM1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim1", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim8 = {
+	.gate_id = GATE_TIM8,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim8", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim15 = {
+	.gate_id = GATE_TIM15,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim15", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim16 = {
+	.gate_id = GATE_TIM16,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim16", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim17 = {
+	.gate_id = GATE_TIM17,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim17", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_tim20 = {
+	.gate_id = GATE_TIM20,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim20", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim2 = {
+	.gate_id = GATE_TIM2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim2", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim3 = {
+	.gate_id = GATE_TIM3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim3", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim4 = {
+	.gate_id = GATE_TIM4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim4", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim5 = {
+	.gate_id = GATE_TIM5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim5", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim6 = {
+	.gate_id = GATE_TIM6,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim6", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim7 = {
+	.gate_id = GATE_TIM7,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim7", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim10 = {
+	.gate_id = GATE_TIM10,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim10", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim11 = {
+	.gate_id = GATE_TIM11,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim11", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim12 = {
+	.gate_id = GATE_TIM12,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim12", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim13 = {
+	.gate_id = GATE_TIM13,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim13", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim14 = {
+	.gate_id = GATE_TIM14,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim14", TIMG1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim1 = {
+	.gate_id = GATE_TIM1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim1", TIMG2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim8 = {
+	.gate_id = GATE_TIM8,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim8", TIMG2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim15 = {
+	.gate_id = GATE_TIM15,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim15", TIMG2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim16 = {
+	.gate_id = GATE_TIM16,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim16", TIMG2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim17 = {
+	.gate_id = GATE_TIM17,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim17", TIMG2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_tim20 = {
+	.gate_id = GATE_TIM20,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_tim20", TIMG2, &clk_stm32_gate_ops, 0),
+};
+
+/* UART/USART */
+static struct clk_stm32_gate ck_icn_p_usart2 = {
+	.gate_id = GATE_USART2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_usart2", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_usart3 = {
+	.gate_id = GATE_USART3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_usart3", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_uart4 = {
+	.gate_id = GATE_UART4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_uart4", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_uart5 = {
+	.gate_id = GATE_UART5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_uart5", ICN_APB1, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_usart1 = {
+	.gate_id = GATE_USART1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_usart1", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_usart6 = {
+	.gate_id = GATE_USART6,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_usart6", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_uart7 = {
+	.gate_id = GATE_UART7,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_uart7", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_uart8 = {
+	.gate_id = GATE_UART8,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_uart8", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_uart9 = {
+	.gate_id = GATE_UART9,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_uart9", ICN_APB2, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_usart2 = {
+	.gate_id = GATE_USART2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_usart2", FLEXGEN_08, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_uart4 = {
+	.gate_id = GATE_UART4,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_uart4", FLEXGEN_08, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_usart3 = {
+	.gate_id = GATE_USART3,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_usart3", FLEXGEN_09, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_uart5 = {
+	.gate_id = GATE_UART5,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_uart5", FLEXGEN_09, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_usart1 = {
+	.gate_id = GATE_USART1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_usart1", FLEXGEN_19, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_usart6 = {
+	.gate_id = GATE_USART6,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_usart6", FLEXGEN_20, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_uart7 = {
+	.gate_id = GATE_UART7,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_uart7", FLEXGEN_21, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_uart8 = {
+	.gate_id = GATE_UART8,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_uart8", FLEXGEN_21, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_uart9 = {
+	.gate_id = GATE_UART9,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_uart9", FLEXGEN_22, &clk_stm32_gate_ops, 0),
+};
+
+/* USB2PHY1 */
+static struct clk_stm32_composite ck_ker_usb2phy1 = {
+	.gate_id = GATE_USB2PHY1,
+	.mux_id = MUX_USB2PHY1,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_usb2phy1", usb2phy1_src,
+					    &clk_stm32_composite_ops, 0),
+};
+
+/* USB2H */
+static struct clk_stm32_gate ck_icn_m_usb2ehci = {
+	.gate_id = GATE_USB2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_m_usb2ehci", ICN_HSL, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_m_usb2ohci = {
+	.gate_id = GATE_USB2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_m_usb2ohci", ICN_HSL, &clk_stm32_gate_ops, 0),
+};
+
+/* USB2PHY2 */
+static struct clk_stm32_composite ck_ker_usb2phy2_en = {
+	.gate_id = GATE_USB2PHY2,
+	.mux_id = MUX_USB2PHY2,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_usb2phy2_en", usb2phy2_src,
+					    &clk_stm32_composite_ops, 0),
+};
+
+/* USB3 PCIe COMBOPHY */
+static struct clk_stm32_gate ck_icn_p_usb3pciephy = {
+	.gate_id = GATE_USB3PCIEPHY,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_usb3pciephy", ICN_APB4, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_composite ck_ker_usb3pciephy = {
+	.gate_id = GATE_USB3PCIEPHY,
+	.mux_id = MUX_USB3PCIEPHY,
+	.div_id = NO_STM32_DIV,
+	.hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_usb3pciephy", usb3pciphy_src,
+					    &clk_stm32_composite_ops, 0),
+};
+
+/* USB3 DRD */
+static struct clk_stm32_gate ck_icn_m_usb3dr = {
+	.gate_id = GATE_USB3DR,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_m_usb3dr", ICN_HSL, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_usb2phy2 = {
+	.gate_id = GATE_USB3DR,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_usb2phy2", FLEXGEN_58, &clk_stm32_gate_ops, 0),
+};
+
+/* USBTC */
+static struct clk_stm32_gate ck_icn_p_usbtc = {
+	.gate_id = GATE_USBTC,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_usbtc", ICN_APB4, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_ker_usbtc = {
+	.gate_id = GATE_USBTC,
+	.hw.init = CLK_HW_INIT_INDEX("ck_ker_usbtc", FLEXGEN_35, &clk_stm32_gate_ops, 0),
+};
+
+/* VDEC / VENC */
+static struct clk_stm32_gate ck_icn_p_vdec = {
+	.gate_id = GATE_VDEC,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_vdec", ICN_APB4, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_venc = {
+	.gate_id = GATE_VENC,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_venc", ICN_APB4, &clk_stm32_gate_ops, 0),
+};
+
+/* VREF */
+static struct clk_stm32_gate ck_icn_p_vref = {
+	.gate_id = GATE_VREF,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_vref", ICN_APB3, &clk_stm32_gate_ops, 0),
+};
+
+/* WWDG */
+static struct clk_stm32_gate ck_icn_p_wwdg1 = {
+	.gate_id = GATE_WWDG1,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_wwdg1", ICN_APB3, &clk_stm32_gate_ops, 0),
+};
+
+static struct clk_stm32_gate ck_icn_p_wwdg2 = {
+	.gate_id = GATE_WWDG2,
+	.hw.init = CLK_HW_INIT_INDEX("ck_icn_p_wwdg2", ICN_LS_MCU, &clk_stm32_gate_ops, 0),
+};
+
+#define SECF_NONE -1
+
+static const struct clock_config stm32mp25_clock_cfg[] = {
+	STM32_GATE_CFG(CK_BUS_ETH1,		ck_icn_p_eth1,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_ETH2,		ck_icn_p_eth2,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_PCIE,		ck_icn_p_pcie,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_ETHSW,		ck_icn_p_ethsw,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_ADC12,		ck_icn_p_adc12,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_ADC3,		ck_icn_p_adc3,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_CCI,		ck_icn_p_cci,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_CRC,		ck_icn_p_crc,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_MDF1,		ck_icn_p_mdf1,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_OSPIIOM,		ck_icn_p_ospiiom,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_HASH,		ck_icn_p_hash,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_CRYP1,		ck_icn_p_cryp1,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_CRYP2,		ck_icn_p_cryp2,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_ADF1,		ck_icn_p_adf1,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SPI8,		ck_icn_p_spi8,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_LPUART1,		ck_icn_p_lpuart1,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I2C8,		ck_icn_p_i2c8,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_LPTIM3,		ck_icn_p_lptim3,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_LPTIM4,		ck_icn_p_lptim4,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_LPTIM5,		ck_icn_p_lptim5,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_IWDG5,		ck_icn_p_iwdg5,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_WWDG2,		ck_icn_p_wwdg2,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I3C4,		ck_icn_p_i3c4,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SDMMC1,		ck_icn_m_sdmmc1,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SDMMC2,		ck_icn_m_sdmmc2,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SDMMC3,		ck_icn_m_sdmmc3,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_USB2OHCI,		ck_icn_m_usb2ohci,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_USB2EHCI,		ck_icn_m_usb2ehci,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_USB3DR,		ck_icn_m_usb3dr,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM2,		ck_icn_p_tim2,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM3,		ck_icn_p_tim3,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM4,		ck_icn_p_tim4,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM5,		ck_icn_p_tim5,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM6,		ck_icn_p_tim6,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM7,		ck_icn_p_tim7,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM10,		ck_icn_p_tim10,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM11,		ck_icn_p_tim11,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM12,		ck_icn_p_tim12,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM13,		ck_icn_p_tim13,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM14,		ck_icn_p_tim14,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_LPTIM1,		ck_icn_p_lptim1,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_LPTIM2,		ck_icn_p_lptim2,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SPI2,		ck_icn_p_spi2,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SPI3,		ck_icn_p_spi3,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SPDIFRX,		ck_icn_p_spdifrx,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_USART2,		ck_icn_p_usart2,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_USART3,		ck_icn_p_usart3,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_UART4,		ck_icn_p_uart4,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_UART5,		ck_icn_p_uart5,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I2C1,		ck_icn_p_i2c1,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I2C2,		ck_icn_p_i2c2,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I2C3,		ck_icn_p_i2c3,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I2C4,		ck_icn_p_i2c4,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I2C5,		ck_icn_p_i2c5,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I2C6,		ck_icn_p_i2c6,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I2C7,		ck_icn_p_i2c7,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I3C1,		ck_icn_p_i3c1,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I3C2,		ck_icn_p_i3c2,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_I3C3,		ck_icn_p_i3c3,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM1,		ck_icn_p_tim1,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM8,		ck_icn_p_tim8,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM15,		ck_icn_p_tim15,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM16,		ck_icn_p_tim16,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM17,		ck_icn_p_tim17,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_TIM20,		ck_icn_p_tim20,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SAI1,		ck_icn_p_sai1,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SAI2,		ck_icn_p_sai2,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SAI3,		ck_icn_p_sai3,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SAI4,		ck_icn_p_sai4,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_USART1,		ck_icn_p_usart1,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_USART6,		ck_icn_p_usart6,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_UART7,		ck_icn_p_uart7,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_UART8,		ck_icn_p_uart8,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_UART9,		ck_icn_p_uart9,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_FDCAN,		ck_icn_p_fdcan,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SPI1,		ck_icn_p_spi1,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SPI4,		ck_icn_p_spi4,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SPI5,		ck_icn_p_spi5,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SPI6,		ck_icn_p_spi6,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_SPI7,		ck_icn_p_spi7,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_IWDG2,		ck_icn_p_iwdg2,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_IWDG3,		ck_icn_p_iwdg3,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_IWDG4,		ck_icn_p_iwdg4,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_WWDG1,		ck_icn_p_wwdg1,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_VREF,		ck_icn_p_vref,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_HDP,		ck_icn_p_hdp,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_IS2M,		ck_icn_p_is2m,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_DSI,		ck_icn_p_dsi,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_LTDC,		ck_icn_p_ltdc,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_CSI,		ck_icn_p_csi,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_DCMIPP,		ck_icn_p_dcmipp,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_LVDS,		ck_icn_p_lvds,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_USBTC,		ck_icn_p_usbtc,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_USB3PCIEPHY,	ck_icn_p_usb3pciephy,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_VDEC,		ck_icn_p_vdec,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_VENC,		ck_icn_p_venc,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM2,		ck_ker_tim2,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM3,		ck_ker_tim3,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM4,		ck_ker_tim4,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM5,		ck_ker_tim5,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM6,		ck_ker_tim6,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM7,		ck_ker_tim7,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM10,		ck_ker_tim10,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM11,		ck_ker_tim11,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM12,		ck_ker_tim12,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM13,		ck_ker_tim13,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM14,		ck_ker_tim14,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM1,		ck_ker_tim1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM8,		ck_ker_tim8,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM15,		ck_ker_tim15,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM16,		ck_ker_tim16,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM17,		ck_ker_tim17,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_TIM20,		ck_ker_tim20,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_LPTIM1,		ck_ker_lptim1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_LPTIM2,		ck_ker_lptim2,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_USART2,		ck_ker_usart2,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_UART4,		ck_ker_uart4,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_USART3,		ck_ker_usart3,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_UART5,		ck_ker_uart5,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SPI2,		ck_ker_spi2,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SPI3,		ck_ker_spi3,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SPDIFRX,		ck_ker_spdifrx,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I2C1,		ck_ker_i2c1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I2C2,		ck_ker_i2c2,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I3C1,		ck_ker_i3c1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I3C2,		ck_ker_i3c2,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I2C3,		ck_ker_i2c3,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I2C5,		ck_ker_i2c5,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I3C3,		ck_ker_i3c3,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I2C4,		ck_ker_i2c4,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I2C6,		ck_ker_i2c6,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I2C7,		ck_ker_i2c7,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SPI1,		ck_ker_spi1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SPI4,		ck_ker_spi4,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SPI5,		ck_ker_spi5,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SPI6,		ck_ker_spi6,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SPI7,		ck_ker_spi7,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_USART1,		ck_ker_usart1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_USART6,		ck_ker_usart6,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_UART7,		ck_ker_uart7,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_UART8,		ck_ker_uart8,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_UART9,		ck_ker_uart9,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_MDF1,		ck_ker_mdf1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SAI1,		ck_ker_sai1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SAI2,		ck_ker_sai2,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SAI3,		ck_ker_sai3,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SAI4,		ck_ker_sai4,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_FDCAN,		ck_ker_fdcan,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_CSI,		ck_ker_csi,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_CSITXESC,		ck_ker_csitxesc,	SECF_NONE),
+	STM32_GATE_CFG(CK_KER_CSIPHY,		ck_ker_csiphy,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_USBTC,		ck_ker_usbtc,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I3C4,		ck_ker_i3c4,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SPI8,		ck_ker_spi8,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_I2C8,		ck_ker_i2c8,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_LPUART1,		ck_ker_lpuart1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_LPTIM3,		ck_ker_lptim3,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_LPTIM4,		ck_ker_lptim4,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_LPTIM5,		ck_ker_lptim5,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_ADF1,		ck_ker_adf1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SDMMC1,		ck_ker_sdmmc1,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SDMMC2,		ck_ker_sdmmc2,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_SDMMC3,		ck_ker_sdmmc3,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_ETH1,		ck_ker_eth1,		SECF_NONE),
+	STM32_GATE_CFG(CK_ETH1_STP,		ck_ker_eth1stp,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_ETHSW,		ck_ker_ethsw,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_ETH2,		ck_ker_eth2,		SECF_NONE),
+	STM32_GATE_CFG(CK_ETH2_STP,		ck_ker_eth2stp,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_ETH1PTP,		ck_ker_eth1ptp,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_ETH2PTP,		ck_ker_eth2ptp,		SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_GPU,		ck_icn_m_gpu,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_GPU,		ck_ker_gpu,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_ETHSWREF,		ck_ker_ethswref,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_ETHSWACMCFG,	ck_icn_p_ethsw_acm_cfg,	SECF_NONE),
+	STM32_GATE_CFG(CK_BUS_ETHSWACMMSG, ck_icn_p_ethsw_acm_msg,	SECF_NONE),
+	STM32_GATE_CFG(CK_ETH1_MAC,		ck_ker_eth1mac,		SECF_NONE),
+	STM32_GATE_CFG(CK_ETH1_TX,		ck_ker_eth1tx,		SECF_NONE),
+	STM32_GATE_CFG(CK_ETH1_RX,		ck_ker_eth1rx,		SECF_NONE),
+	STM32_GATE_CFG(CK_ETH2_MAC,		ck_ker_eth2mac,		SECF_NONE),
+	STM32_GATE_CFG(CK_ETH2_TX,		ck_ker_eth2tx,		SECF_NONE),
+	STM32_GATE_CFG(CK_ETH2_RX,		ck_ker_eth2rx,		SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_MCO1,		ck_mco1,		SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_MCO2,		ck_mco2,		SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_KER_ADC12,	ck_ker_adc12,		SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_KER_ADC3,	ck_ker_adc3,		SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_KER_USB2PHY1,	ck_ker_usb2phy1,	SECF_NONE),
+	STM32_GATE_CFG(CK_KER_USB2PHY2,		ck_ker_usb2phy2,	SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_KER_USB2PHY2EN,	ck_ker_usb2phy2_en,	SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_KER_USB3PCIEPHY,	ck_ker_usb3pciephy,	SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_KER_DSIBLANE,	clk_lanebyte,		SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_KER_DSIPHY,	clk_phy_dsi,		SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_KER_LVDSPHY,	ck_ker_lvdsphy,		SECF_NONE),
+	STM32_COMPOSITE_CFG(CK_KER_DTS,		ck_ker_dts,		SECF_NONE),
+	STM32_GATE_CFG(CK_KER_LTDC,		ck_ker_ltdc,		SECF_NONE),
+};
+
+#define RESET_MP25(id, _offset, _bit_idx, _set_clr)	\
+	[id] = &(struct stm32_reset_cfg){		\
+		.offset		= (_offset),		\
+		.bit_idx	= (_bit_idx),		\
+		.set_clr	= (_set_clr),		\
+	}
+
+static const struct stm32_reset_cfg *stm32mp25_reset_cfg[STM32MP25_LAST_RESET] = {
+	RESET_MP25(TIM1_R,		RCC_TIM1CFGR,		0,	0),
+	RESET_MP25(TIM2_R,		RCC_TIM2CFGR,		0,	0),
+	RESET_MP25(TIM3_R,		RCC_TIM3CFGR,		0,	0),
+	RESET_MP25(TIM4_R,		RCC_TIM4CFGR,		0,	0),
+	RESET_MP25(TIM5_R,		RCC_TIM5CFGR,		0,	0),
+	RESET_MP25(TIM6_R,		RCC_TIM6CFGR,		0,	0),
+	RESET_MP25(TIM7_R,		RCC_TIM7CFGR,		0,	0),
+	RESET_MP25(TIM8_R,		RCC_TIM8CFGR,		0,	0),
+	RESET_MP25(TIM10_R,		RCC_TIM10CFGR,		0,	0),
+	RESET_MP25(TIM11_R,		RCC_TIM11CFGR,		0,	0),
+	RESET_MP25(TIM12_R,		RCC_TIM12CFGR,		0,	0),
+	RESET_MP25(TIM13_R,		RCC_TIM13CFGR,		0,	0),
+	RESET_MP25(TIM14_R,		RCC_TIM14CFGR,		0,	0),
+	RESET_MP25(TIM15_R,		RCC_TIM15CFGR,		0,	0),
+	RESET_MP25(TIM16_R,		RCC_TIM16CFGR,		0,	0),
+	RESET_MP25(TIM17_R,		RCC_TIM17CFGR,		0,	0),
+	RESET_MP25(TIM20_R,		RCC_TIM20CFGR,		0,	0),
+	RESET_MP25(LPTIM1_R,		RCC_LPTIM1CFGR,		0,	0),
+	RESET_MP25(LPTIM2_R,		RCC_LPTIM2CFGR,		0,	0),
+	RESET_MP25(LPTIM3_R,		RCC_LPTIM3CFGR,		0,	0),
+	RESET_MP25(LPTIM4_R,		RCC_LPTIM4CFGR,		0,	0),
+	RESET_MP25(LPTIM5_R,		RCC_LPTIM5CFGR,		0,	0),
+	RESET_MP25(SPI1_R,		RCC_SPI1CFGR,		0,	0),
+	RESET_MP25(SPI2_R,		RCC_SPI2CFGR,		0,	0),
+	RESET_MP25(SPI3_R,		RCC_SPI3CFGR,		0,	0),
+	RESET_MP25(SPI4_R,		RCC_SPI4CFGR,		0,	0),
+	RESET_MP25(SPI5_R,		RCC_SPI5CFGR,		0,	0),
+	RESET_MP25(SPI6_R,		RCC_SPI6CFGR,		0,	0),
+	RESET_MP25(SPI7_R,		RCC_SPI7CFGR,		0,	0),
+	RESET_MP25(SPI8_R,		RCC_SPI8CFGR,		0,	0),
+	RESET_MP25(SPDIFRX_R,		RCC_SPDIFRXCFGR,	0,	0),
+	RESET_MP25(USART1_R,		RCC_USART1CFGR,		0,	0),
+	RESET_MP25(USART2_R,		RCC_USART2CFGR,		0,	0),
+	RESET_MP25(USART3_R,		RCC_USART3CFGR,		0,	0),
+	RESET_MP25(UART4_R,		RCC_UART4CFGR,		0,	0),
+	RESET_MP25(UART5_R,		RCC_UART5CFGR,		0,	0),
+	RESET_MP25(USART6_R,		RCC_USART6CFGR,		0,	0),
+	RESET_MP25(UART7_R,		RCC_UART7CFGR,		0,	0),
+	RESET_MP25(UART8_R,		RCC_UART8CFGR,		0,	0),
+	RESET_MP25(UART9_R,		RCC_UART9CFGR,		0,	0),
+	RESET_MP25(LPUART1_R,		RCC_LPUART1CFGR,	0,	0),
+	RESET_MP25(IS2M_R,		RCC_IS2MCFGR,		0,	0),
+	RESET_MP25(I2C1_R,		RCC_I2C1CFGR,		0,	0),
+	RESET_MP25(I2C2_R,		RCC_I2C2CFGR,		0,	0),
+	RESET_MP25(I2C3_R,		RCC_I2C3CFGR,		0,	0),
+	RESET_MP25(I2C4_R,		RCC_I2C4CFGR,		0,	0),
+	RESET_MP25(I2C5_R,		RCC_I2C5CFGR,		0,	0),
+	RESET_MP25(I2C6_R,		RCC_I2C6CFGR,		0,	0),
+	RESET_MP25(I2C7_R,		RCC_I2C7CFGR,		0,	0),
+	RESET_MP25(I2C8_R,		RCC_I2C8CFGR,		0,	0),
+	RESET_MP25(SAI1_R,		RCC_SAI1CFGR,		0,	0),
+	RESET_MP25(SAI2_R,		RCC_SAI2CFGR,		0,	0),
+	RESET_MP25(SAI3_R,		RCC_SAI3CFGR,		0,	0),
+	RESET_MP25(SAI4_R,		RCC_SAI4CFGR,		0,	0),
+	RESET_MP25(MDF1_R,		RCC_MDF1CFGR,		0,	0),
+	RESET_MP25(MDF2_R,		RCC_ADF1CFGR,		0,	0),
+	RESET_MP25(FDCAN_R,		RCC_FDCANCFGR,		0,	0),
+	RESET_MP25(HDP_R,		RCC_HDPCFGR,		0,	0),
+	RESET_MP25(ADC12_R,		RCC_ADC12CFGR,		0,	0),
+	RESET_MP25(ADC3_R,		RCC_ADC3CFGR,		0,	0),
+	RESET_MP25(ETH1_R,		RCC_ETH1CFGR,		0,	0),
+	RESET_MP25(ETH2_R,		RCC_ETH2CFGR,		0,	0),
+	RESET_MP25(USB2_R,		RCC_USB2CFGR,		0,	0),
+	RESET_MP25(USB2PHY1_R,		RCC_USB2PHY1CFGR,	0,	0),
+	RESET_MP25(USB2PHY2_R,		RCC_USB2PHY2CFGR,	0,	0),
+	RESET_MP25(USB3DR_R,		RCC_USB3DRCFGR,		0,	0),
+	RESET_MP25(USB3PCIEPHY_R,	RCC_USB3PCIEPHYCFGR,	0,	0),
+	RESET_MP25(USBTC_R,		RCC_USBTCCFGR,		0,	0),
+	RESET_MP25(ETHSW_R,		RCC_ETHSWCFGR,		0,	0),
+	RESET_MP25(SDMMC1_R,		RCC_SDMMC1CFGR,		0,	0),
+	RESET_MP25(SDMMC1DLL_R,		RCC_SDMMC1CFGR,		16,	0),
+	RESET_MP25(SDMMC2_R,		RCC_SDMMC2CFGR,		0,	0),
+	RESET_MP25(SDMMC2DLL_R,		RCC_SDMMC2CFGR,		16,	0),
+	RESET_MP25(SDMMC3_R,		RCC_SDMMC3CFGR,		0,	0),
+	RESET_MP25(SDMMC3DLL_R,		RCC_SDMMC3CFGR,		16,	0),
+	RESET_MP25(GPU_R,		RCC_GPUCFGR,		0,	0),
+	RESET_MP25(LTDC_R,		RCC_LTDCCFGR,		0,	0),
+	RESET_MP25(DSI_R,		RCC_DSICFGR,		0,	0),
+	RESET_MP25(LVDS_R,		RCC_LVDSCFGR,		0,	0),
+	RESET_MP25(CSI_R,		RCC_CSICFGR,		0,	0),
+	RESET_MP25(DCMIPP_R,		RCC_DCMIPPCFGR,		0,	0),
+	RESET_MP25(CCI_R,		RCC_CCICFGR,		0,	0),
+	RESET_MP25(VDEC_R,		RCC_VDECCFGR,		0,	0),
+	RESET_MP25(VENC_R,		RCC_VENCCFGR,		0,	0),
+	RESET_MP25(WWDG1_R,		RCC_WWDG1CFGR,		0,	0),
+	RESET_MP25(WWDG2_R,		RCC_WWDG2CFGR,		0,	0),
+	RESET_MP25(VREF_R,		RCC_VREFCFGR,		0,	0),
+	RESET_MP25(DTS_R,		RCC_DTSCFGR,		0,	0),
+	RESET_MP25(CRC_R,		RCC_CRCCFGR,		0,	0),
+	RESET_MP25(SERC_R,		RCC_SERCCFGR,		0,	0),
+	RESET_MP25(OSPIIOM_R,		RCC_OSPIIOMCFGR,	0,	0),
+	RESET_MP25(I3C1_R,		RCC_I3C1CFGR,		0,	0),
+	RESET_MP25(I3C2_R,		RCC_I3C2CFGR,		0,	0),
+	RESET_MP25(I3C3_R,		RCC_I3C3CFGR,		0,	0),
+	RESET_MP25(I3C4_R,		RCC_I3C4CFGR,		0,	0),
+	RESET_MP25(IWDG2_KER_R,		RCC_IWDGC1CFGSETR,	18,	1),
+	RESET_MP25(IWDG4_KER_R,		RCC_IWDGC2CFGSETR,	18,	1),
+	RESET_MP25(RNG_R,		RCC_RNGCFGR,		0,	0),
+	RESET_MP25(PKA_R,		RCC_PKACFGR,		0,	0),
+	RESET_MP25(SAES_R,		RCC_SAESCFGR,		0,	0),
+	RESET_MP25(HASH_R,		RCC_HASHCFGR,		0,	0),
+	RESET_MP25(CRYP1_R,		RCC_CRYP1CFGR,		0,	0),
+	RESET_MP25(CRYP2_R,		RCC_CRYP2CFGR,		0,	0),
+	RESET_MP25(PCIE_R,		RCC_PCIECFGR,		0,	0),
+};
+
+static u16 stm32mp25_cpt_gate[GATE_NB];
+
+static struct clk_stm32_clock_data stm32mp25_clock_data = {
+	.gate_cpt	= stm32mp25_cpt_gate,
+	.gates		= stm32mp25_gates,
+	.muxes		= stm32mp25_muxes,
+};
+
+static struct clk_stm32_reset_data stm32mp25_reset_data = {
+	.reset_lines	= stm32mp25_reset_cfg,
+	.nr_lines	= ARRAY_SIZE(stm32mp25_reset_cfg),
+};
+
+static const struct stm32_rcc_match_data stm32mp25_data = {
+	.tab_clocks	= stm32mp25_clock_cfg,
+	.num_clocks	= ARRAY_SIZE(stm32mp25_clock_cfg),
+	.maxbinding	= STM32MP25_LAST_CLK,
+	.clock_data	= &stm32mp25_clock_data,
+	.reset_data	= &stm32mp25_reset_data,
+};
+
+static const struct of_device_id stm32mp25_match_data[] = {
+	{ .compatible = "st,stm32mp25-rcc", .data = &stm32mp25_data, },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, stm32mp25_match_data);
+
+static int stm32mp25_rcc_clocks_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (WARN_ON(IS_ERR(base)))
+		return PTR_ERR(base);
+
+	return stm32_rcc_init(dev, stm32mp25_match_data, base);
+}
+
+static struct platform_driver stm32mp25_rcc_clocks_driver = {
+	.driver	= {
+		.name = "stm32mp25_rcc",
+		.of_match_table = stm32mp25_match_data,
+	},
+	.probe = stm32mp25_rcc_clocks_probe,
+};
+
+static int __init stm32mp25_clocks_init(void)
+{
+	return platform_driver_register(&stm32mp25_rcc_clocks_driver);
+}
+
+core_initcall(stm32mp25_clocks_init);
diff --git a/drivers/clk/stm32/reset-stm32.c b/drivers/clk/stm32/reset-stm32.c
index 14c2ee1eebee..5a8f525842ce 100644
--- a/drivers/clk/stm32/reset-stm32.c
+++ b/drivers/clk/stm32/reset-stm32.c
@@ -19,6 +19,7 @@ struct stm32_reset_data {
 	struct reset_controller_dev	rcdev;
 	void __iomem			*membase;
 	u32				clear_offset;
+	const struct stm32_reset_cfg	**reset_lines;
 };
 
 static inline struct stm32_reset_data *
@@ -27,22 +28,46 @@ to_stm32_reset_data(struct reset_controller_dev *rcdev)
 	return container_of(rcdev, struct stm32_reset_data, rcdev);
 }
 
+static const struct stm32_reset_cfg *stm32_get_reset_line(struct reset_controller_dev *rcdev,
+							  unsigned long id,
+							  struct stm32_reset_cfg *line)
+{
+	struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
+
+	if (!data->reset_lines) {
+		int reg_width = sizeof(u32);
+		int bank = id / (reg_width * BITS_PER_BYTE);
+		int offset = id % (reg_width * BITS_PER_BYTE);
+
+		line->offset = bank * reg_width;
+		line->bit_idx = offset;
+		line->set_clr = (data->clear_offset ? true : false);
+
+		return line;
+	}
+
+	return data->reset_lines[id];
+}
+
 static int stm32_reset_update(struct reset_controller_dev *rcdev,
 			      unsigned long id, bool assert)
 {
 	struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
-	int reg_width = sizeof(u32);
-	int bank = id / (reg_width * BITS_PER_BYTE);
-	int offset = id % (reg_width * BITS_PER_BYTE);
+	struct stm32_reset_cfg line_reset;
+	const struct stm32_reset_cfg *ptr_line;
 
-	if (data->clear_offset) {
+	ptr_line = stm32_get_reset_line(rcdev, id, &line_reset);
+	if (!ptr_line)
+		return -EPERM;
+
+	if (ptr_line->set_clr) {
 		void __iomem *addr;
 
-		addr = data->membase + (bank * reg_width);
+		addr = data->membase + ptr_line->offset;
 		if (!assert)
 			addr += data->clear_offset;
 
-		writel(BIT(offset), addr);
+		writel(BIT(ptr_line->bit_idx), addr);
 
 	} else {
 		unsigned long flags;
@@ -50,14 +75,14 @@ static int stm32_reset_update(struct reset_controller_dev *rcdev,
 
 		spin_lock_irqsave(&data->lock, flags);
 
-		reg = readl(data->membase + (bank * reg_width));
+		reg = readl(data->membase + ptr_line->offset);
 
 		if (assert)
-			reg |= BIT(offset);
+			reg |= BIT(ptr_line->bit_idx);
 		else
-			reg &= ~BIT(offset);
+			reg &= ~BIT(ptr_line->bit_idx);
 
-		writel(reg, data->membase + (bank * reg_width));
+		writel(reg, data->membase + ptr_line->offset);
 
 		spin_unlock_irqrestore(&data->lock, flags);
 	}
@@ -81,14 +106,17 @@ static int stm32_reset_status(struct reset_controller_dev *rcdev,
 			      unsigned long id)
 {
 	struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
-	int reg_width = sizeof(u32);
-	int bank = id / (reg_width * BITS_PER_BYTE);
-	int offset = id % (reg_width * BITS_PER_BYTE);
+	struct stm32_reset_cfg line_reset;
+	const struct stm32_reset_cfg *ptr_line;
 	u32 reg;
 
-	reg = readl(data->membase + (bank * reg_width));
+	ptr_line = stm32_get_reset_line(rcdev, id, &line_reset);
+	if (!ptr_line)
+		return -EPERM;
+
+	reg = readl(data->membase + ptr_line->offset);
 
-	return !!(reg & BIT(offset));
+	return !!(reg & BIT(ptr_line->bit_idx));
 }
 
 static const struct reset_control_ops stm32_reset_ops = {
@@ -113,6 +141,7 @@ int stm32_rcc_reset_init(struct device *dev, struct clk_stm32_reset_data *data,
 	reset_data->rcdev.ops = &stm32_reset_ops;
 	reset_data->rcdev.of_node = dev_of_node(dev);
 	reset_data->rcdev.nr_resets = data->nr_lines;
+	reset_data->reset_lines = data->reset_lines;
 	reset_data->clear_offset = data->clear_offset;
 
 	return reset_controller_register(&reset_data->rcdev);
diff --git a/drivers/clk/stm32/reset-stm32.h b/drivers/clk/stm32/reset-stm32.h
index 8cf1cc9be480..f79cad21dfd6 100644
--- a/drivers/clk/stm32/reset-stm32.h
+++ b/drivers/clk/stm32/reset-stm32.h
@@ -4,8 +4,15 @@
  * Author: Gabriel Fernandez <gabriel.fernandez at foss.st.com> for STMicroelectronics.
  */
 
+struct stm32_reset_cfg {
+	u16 offset;
+	u8 bit_idx;
+	bool set_clr;
+};
+
 struct clk_stm32_reset_data {
 	const struct reset_control_ops *ops;
+	const struct stm32_reset_cfg **reset_lines;
 	unsigned int nr_lines;
 	u32 clear_offset;
 };
diff --git a/drivers/clk/stm32/stm32mp25_rcc.h b/drivers/clk/stm32/stm32mp25_rcc.h
new file mode 100644
index 000000000000..6ba13cc2ae16
--- /dev/null
+++ b/drivers/clk/stm32/stm32mp25_rcc.h
@@ -0,0 +1,712 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez at foss.st.com> for STMicroelectronics.
+ */
+
+#ifndef STM32MP25_RCC_H
+#define STM32MP25_RCC_H
+
+#define RCC_SECCFGR0				0x0
+#define RCC_SECCFGR1				0x4
+#define RCC_SECCFGR2				0x8
+#define RCC_SECCFGR3				0xC
+#define RCC_PRIVCFGR0				0x10
+#define RCC_PRIVCFGR1				0x14
+#define RCC_PRIVCFGR2				0x18
+#define RCC_PRIVCFGR3				0x1C
+#define RCC_RCFGLOCKR0				0x20
+#define RCC_RCFGLOCKR1				0x24
+#define RCC_RCFGLOCKR2				0x28
+#define RCC_RCFGLOCKR3				0x2C
+#define RCC_R0CIDCFGR				0x30
+#define RCC_R0SEMCR				0x34
+#define RCC_R1CIDCFGR				0x38
+#define RCC_R1SEMCR				0x3C
+#define RCC_R2CIDCFGR				0x40
+#define RCC_R2SEMCR				0x44
+#define RCC_R3CIDCFGR				0x48
+#define RCC_R3SEMCR				0x4C
+#define RCC_R4CIDCFGR				0x50
+#define RCC_R4SEMCR				0x54
+#define RCC_R5CIDCFGR				0x58
+#define RCC_R5SEMCR				0x5C
+#define RCC_R6CIDCFGR				0x60
+#define RCC_R6SEMCR				0x64
+#define RCC_R7CIDCFGR				0x68
+#define RCC_R7SEMCR				0x6C
+#define RCC_R8CIDCFGR				0x70
+#define RCC_R8SEMCR				0x74
+#define RCC_R9CIDCFGR				0x78
+#define RCC_R9SEMCR				0x7C
+#define RCC_R10CIDCFGR				0x80
+#define RCC_R10SEMCR				0x84
+#define RCC_R11CIDCFGR				0x88
+#define RCC_R11SEMCR				0x8C
+#define RCC_R12CIDCFGR				0x90
+#define RCC_R12SEMCR				0x94
+#define RCC_R13CIDCFGR				0x98
+#define RCC_R13SEMCR				0x9C
+#define RCC_R14CIDCFGR				0xA0
+#define RCC_R14SEMCR				0xA4
+#define RCC_R15CIDCFGR				0xA8
+#define RCC_R15SEMCR				0xAC
+#define RCC_R16CIDCFGR				0xB0
+#define RCC_R16SEMCR				0xB4
+#define RCC_R17CIDCFGR				0xB8
+#define RCC_R17SEMCR				0xBC
+#define RCC_R18CIDCFGR				0xC0
+#define RCC_R18SEMCR				0xC4
+#define RCC_R19CIDCFGR				0xC8
+#define RCC_R19SEMCR				0xCC
+#define RCC_R20CIDCFGR				0xD0
+#define RCC_R20SEMCR				0xD4
+#define RCC_R21CIDCFGR				0xD8
+#define RCC_R21SEMCR				0xDC
+#define RCC_R22CIDCFGR				0xE0
+#define RCC_R22SEMCR				0xE4
+#define RCC_R23CIDCFGR				0xE8
+#define RCC_R23SEMCR				0xEC
+#define RCC_R24CIDCFGR				0xF0
+#define RCC_R24SEMCR				0xF4
+#define RCC_R25CIDCFGR				0xF8
+#define RCC_R25SEMCR				0xFC
+#define RCC_R26CIDCFGR				0x100
+#define RCC_R26SEMCR				0x104
+#define RCC_R27CIDCFGR				0x108
+#define RCC_R27SEMCR				0x10C
+#define RCC_R28CIDCFGR				0x110
+#define RCC_R28SEMCR				0x114
+#define RCC_R29CIDCFGR				0x118
+#define RCC_R29SEMCR				0x11C
+#define RCC_R30CIDCFGR				0x120
+#define RCC_R30SEMCR				0x124
+#define RCC_R31CIDCFGR				0x128
+#define RCC_R31SEMCR				0x12C
+#define RCC_R32CIDCFGR				0x130
+#define RCC_R32SEMCR				0x134
+#define RCC_R33CIDCFGR				0x138
+#define RCC_R33SEMCR				0x13C
+#define RCC_R34CIDCFGR				0x140
+#define RCC_R34SEMCR				0x144
+#define RCC_R35CIDCFGR				0x148
+#define RCC_R35SEMCR				0x14C
+#define RCC_R36CIDCFGR				0x150
+#define RCC_R36SEMCR				0x154
+#define RCC_R37CIDCFGR				0x158
+#define RCC_R37SEMCR				0x15C
+#define RCC_R38CIDCFGR				0x160
+#define RCC_R38SEMCR				0x164
+#define RCC_R39CIDCFGR				0x168
+#define RCC_R39SEMCR				0x16C
+#define RCC_R40CIDCFGR				0x170
+#define RCC_R40SEMCR				0x174
+#define RCC_R41CIDCFGR				0x178
+#define RCC_R41SEMCR				0x17C
+#define RCC_R42CIDCFGR				0x180
+#define RCC_R42SEMCR				0x184
+#define RCC_R43CIDCFGR				0x188
+#define RCC_R43SEMCR				0x18C
+#define RCC_R44CIDCFGR				0x190
+#define RCC_R44SEMCR				0x194
+#define RCC_R45CIDCFGR				0x198
+#define RCC_R45SEMCR				0x19C
+#define RCC_R46CIDCFGR				0x1A0
+#define RCC_R46SEMCR				0x1A4
+#define RCC_R47CIDCFGR				0x1A8
+#define RCC_R47SEMCR				0x1AC
+#define RCC_R48CIDCFGR				0x1B0
+#define RCC_R48SEMCR				0x1B4
+#define RCC_R49CIDCFGR				0x1B8
+#define RCC_R49SEMCR				0x1BC
+#define RCC_R50CIDCFGR				0x1C0
+#define RCC_R50SEMCR				0x1C4
+#define RCC_R51CIDCFGR				0x1C8
+#define RCC_R51SEMCR				0x1CC
+#define RCC_R52CIDCFGR				0x1D0
+#define RCC_R52SEMCR				0x1D4
+#define RCC_R53CIDCFGR				0x1D8
+#define RCC_R53SEMCR				0x1DC
+#define RCC_R54CIDCFGR				0x1E0
+#define RCC_R54SEMCR				0x1E4
+#define RCC_R55CIDCFGR				0x1E8
+#define RCC_R55SEMCR				0x1EC
+#define RCC_R56CIDCFGR				0x1F0
+#define RCC_R56SEMCR				0x1F4
+#define RCC_R57CIDCFGR				0x1F8
+#define RCC_R57SEMCR				0x1FC
+#define RCC_R58CIDCFGR				0x200
+#define RCC_R58SEMCR				0x204
+#define RCC_R59CIDCFGR				0x208
+#define RCC_R59SEMCR				0x20C
+#define RCC_R60CIDCFGR				0x210
+#define RCC_R60SEMCR				0x214
+#define RCC_R61CIDCFGR				0x218
+#define RCC_R61SEMCR				0x21C
+#define RCC_R62CIDCFGR				0x220
+#define RCC_R62SEMCR				0x224
+#define RCC_R63CIDCFGR				0x228
+#define RCC_R63SEMCR				0x22C
+#define RCC_R64CIDCFGR				0x230
+#define RCC_R64SEMCR				0x234
+#define RCC_R65CIDCFGR				0x238
+#define RCC_R65SEMCR				0x23C
+#define RCC_R66CIDCFGR				0x240
+#define RCC_R66SEMCR				0x244
+#define RCC_R67CIDCFGR				0x248
+#define RCC_R67SEMCR				0x24C
+#define RCC_R68CIDCFGR				0x250
+#define RCC_R68SEMCR				0x254
+#define RCC_R69CIDCFGR				0x258
+#define RCC_R69SEMCR				0x25C
+#define RCC_R70CIDCFGR				0x260
+#define RCC_R70SEMCR				0x264
+#define RCC_R71CIDCFGR				0x268
+#define RCC_R71SEMCR				0x26C
+#define RCC_R72CIDCFGR				0x270
+#define RCC_R72SEMCR				0x274
+#define RCC_R73CIDCFGR				0x278
+#define RCC_R73SEMCR				0x27C
+#define RCC_R74CIDCFGR				0x280
+#define RCC_R74SEMCR				0x284
+#define RCC_R75CIDCFGR				0x288
+#define RCC_R75SEMCR				0x28C
+#define RCC_R76CIDCFGR				0x290
+#define RCC_R76SEMCR				0x294
+#define RCC_R77CIDCFGR				0x298
+#define RCC_R77SEMCR				0x29C
+#define RCC_R78CIDCFGR				0x2A0
+#define RCC_R78SEMCR				0x2A4
+#define RCC_R79CIDCFGR				0x2A8
+#define RCC_R79SEMCR				0x2AC
+#define RCC_R80CIDCFGR				0x2B0
+#define RCC_R80SEMCR				0x2B4
+#define RCC_R81CIDCFGR				0x2B8
+#define RCC_R81SEMCR				0x2BC
+#define RCC_R82CIDCFGR				0x2C0
+#define RCC_R82SEMCR				0x2C4
+#define RCC_R83CIDCFGR				0x2C8
+#define RCC_R83SEMCR				0x2CC
+#define RCC_R84CIDCFGR				0x2D0
+#define RCC_R84SEMCR				0x2D4
+#define RCC_R85CIDCFGR				0x2D8
+#define RCC_R85SEMCR				0x2DC
+#define RCC_R86CIDCFGR				0x2E0
+#define RCC_R86SEMCR				0x2E4
+#define RCC_R87CIDCFGR				0x2E8
+#define RCC_R87SEMCR				0x2EC
+#define RCC_R88CIDCFGR				0x2F0
+#define RCC_R88SEMCR				0x2F4
+#define RCC_R89CIDCFGR				0x2F8
+#define RCC_R89SEMCR				0x2FC
+#define RCC_R90CIDCFGR				0x300
+#define RCC_R90SEMCR				0x304
+#define RCC_R91CIDCFGR				0x308
+#define RCC_R91SEMCR				0x30C
+#define RCC_R92CIDCFGR				0x310
+#define RCC_R92SEMCR				0x314
+#define RCC_R93CIDCFGR				0x318
+#define RCC_R93SEMCR				0x31C
+#define RCC_R94CIDCFGR				0x320
+#define RCC_R94SEMCR				0x324
+#define RCC_R95CIDCFGR				0x328
+#define RCC_R95SEMCR				0x32C
+#define RCC_R96CIDCFGR				0x330
+#define RCC_R96SEMCR				0x334
+#define RCC_R97CIDCFGR				0x338
+#define RCC_R97SEMCR				0x33C
+#define RCC_R98CIDCFGR				0x340
+#define RCC_R98SEMCR				0x344
+#define RCC_R99CIDCFGR				0x348
+#define RCC_R99SEMCR				0x34C
+#define RCC_R100CIDCFGR				0x350
+#define RCC_R100SEMCR				0x354
+#define RCC_R101CIDCFGR				0x358
+#define RCC_R101SEMCR				0x35C
+#define RCC_R102CIDCFGR				0x360
+#define RCC_R102SEMCR				0x364
+#define RCC_R103CIDCFGR				0x368
+#define RCC_R103SEMCR				0x36C
+#define RCC_R104CIDCFGR				0x370
+#define RCC_R104SEMCR				0x374
+#define RCC_R105CIDCFGR				0x378
+#define RCC_R105SEMCR				0x37C
+#define RCC_R106CIDCFGR				0x380
+#define RCC_R106SEMCR				0x384
+#define RCC_R107CIDCFGR				0x388
+#define RCC_R107SEMCR				0x38C
+#define RCC_R108CIDCFGR				0x390
+#define RCC_R108SEMCR				0x394
+#define RCC_R109CIDCFGR				0x398
+#define RCC_R109SEMCR				0x39C
+#define RCC_R110CIDCFGR				0x3A0
+#define RCC_R110SEMCR				0x3A4
+#define RCC_R111CIDCFGR				0x3A8
+#define RCC_R111SEMCR				0x3AC
+#define RCC_R112CIDCFGR				0x3B0
+#define RCC_R112SEMCR				0x3B4
+#define RCC_R113CIDCFGR				0x3B8
+#define RCC_R113SEMCR				0x3BC
+#define RCC_GRSTCSETR				0x400
+#define RCC_C1RSTCSETR				0x404
+#define RCC_C1P1RSTCSETR			0x408
+#define RCC_C2RSTCSETR				0x40C
+#define RCC_HWRSTSCLRR				0x410
+#define RCC_C1HWRSTSCLRR			0x414
+#define RCC_C2HWRSTSCLRR			0x418
+#define RCC_C1BOOTRSTSSETR			0x41C
+#define RCC_C1BOOTRSTSCLRR			0x420
+#define RCC_C2BOOTRSTSSETR			0x424
+#define RCC_C2BOOTRSTSCLRR			0x428
+#define RCC_C1SREQSETR				0x42C
+#define RCC_C1SREQCLRR				0x430
+#define RCC_CPUBOOTCR				0x434
+#define RCC_STBYBOOTCR				0x438
+#define RCC_LEGBOOTCR				0x43C
+#define RCC_BDCR				0x440
+#define RCC_D3DCR				0x444
+#define RCC_D3DSR				0x448
+#define RCC_RDCR				0x44C
+#define RCC_C1MSRDCR				0x450
+#define RCC_PWRLPDLYCR				0x454
+#define RCC_C1CIESETR				0x458
+#define RCC_C1CIFCLRR				0x45C
+#define RCC_C2CIESETR				0x460
+#define RCC_C2CIFCLRR				0x464
+#define RCC_IWDGC1FZSETR			0x468
+#define RCC_IWDGC1FZCLRR			0x46C
+#define RCC_IWDGC1CFGSETR			0x470
+#define RCC_IWDGC1CFGCLRR			0x474
+#define RCC_IWDGC2FZSETR			0x478
+#define RCC_IWDGC2FZCLRR			0x47C
+#define RCC_IWDGC2CFGSETR			0x480
+#define RCC_IWDGC2CFGCLRR			0x484
+#define RCC_IWDGC3CFGSETR			0x488
+#define RCC_IWDGC3CFGCLRR			0x48C
+#define RCC_C3CFGR				0x490
+#define RCC_MCO1CFGR				0x494
+#define RCC_MCO2CFGR				0x498
+#define RCC_OCENSETR				0x49C
+#define RCC_OCENCLRR				0x4A0
+#define RCC_OCRDYR				0x4A4
+#define RCC_HSICFGR				0x4A8
+#define RCC_MSICFGR				0x4AC
+#define RCC_RTCDIVR				0x4B0
+#define RCC_APB1DIVR				0x4B4
+#define RCC_APB2DIVR				0x4B8
+#define RCC_APB3DIVR				0x4BC
+#define RCC_APB4DIVR				0x4C0
+#define RCC_APBDBGDIVR				0x4C4
+#define RCC_TIMG1PRER				0x4C8
+#define RCC_TIMG2PRER				0x4CC
+#define RCC_LSMCUDIVR				0x4D0
+#define RCC_DDRCPCFGR				0x4D4
+#define RCC_DDRCAPBCFGR				0x4D8
+#define RCC_DDRPHYCAPBCFGR			0x4DC
+#define RCC_DDRPHYCCFGR				0x4E0
+#define RCC_DDRCFGR				0x4E4
+#define RCC_DDRITFCFGR				0x4E8
+#define RCC_SYSRAMCFGR				0x4F0
+#define RCC_VDERAMCFGR				0x4F4
+#define RCC_SRAM1CFGR				0x4F8
+#define RCC_SRAM2CFGR				0x4FC
+#define RCC_RETRAMCFGR				0x500
+#define RCC_BKPSRAMCFGR				0x504
+#define RCC_LPSRAM1CFGR				0x508
+#define RCC_LPSRAM2CFGR				0x50C
+#define RCC_LPSRAM3CFGR				0x510
+#define RCC_OSPI1CFGR				0x514
+#define RCC_OSPI2CFGR				0x518
+#define RCC_FMCCFGR				0x51C
+#define RCC_DBGCFGR				0x520
+#define RCC_STM500CFGR				0x524
+#define RCC_ETRCFGR				0x528
+#define RCC_GPIOACFGR				0x52C
+#define RCC_GPIOBCFGR				0x530
+#define RCC_GPIOCCFGR				0x534
+#define RCC_GPIODCFGR				0x538
+#define RCC_GPIOECFGR				0x53C
+#define RCC_GPIOFCFGR				0x540
+#define RCC_GPIOGCFGR				0x544
+#define RCC_GPIOHCFGR				0x548
+#define RCC_GPIOICFGR				0x54C
+#define RCC_GPIOJCFGR				0x550
+#define RCC_GPIOKCFGR				0x554
+#define RCC_GPIOZCFGR				0x558
+#define RCC_HPDMA1CFGR				0x55C
+#define RCC_HPDMA2CFGR				0x560
+#define RCC_HPDMA3CFGR				0x564
+#define RCC_LPDMACFGR				0x568
+#define RCC_HSEMCFGR				0x56C
+#define RCC_IPCC1CFGR				0x570
+#define RCC_IPCC2CFGR				0x574
+#define RCC_RTCCFGR				0x578
+#define RCC_SYSCPU1CFGR				0x580
+#define RCC_BSECCFGR				0x584
+#define RCC_IS2MCFGR				0x58C
+#define RCC_PLL2CFGR1				0x590
+#define RCC_PLL2CFGR2				0x594
+#define RCC_PLL2CFGR3				0x598
+#define RCC_PLL2CFGR4				0x59C
+#define RCC_PLL2CFGR5				0x5A0
+#define RCC_PLL2CFGR6				0x5A8
+#define RCC_PLL2CFGR7				0x5AC
+#define RCC_PLL3CFGR1				0x5B8
+#define RCC_PLL3CFGR2				0x5BC
+#define RCC_PLL3CFGR3				0x5C0
+#define RCC_PLL3CFGR4				0x5C4
+#define RCC_PLL3CFGR5				0x5C8
+#define RCC_PLL3CFGR6				0x5D0
+#define RCC_PLL3CFGR7				0x5D4
+#define RCC_HSIFMONCR				0x5E0
+#define RCC_HSIFVALR				0x5E4
+#define RCC_TIM1CFGR				0x700
+#define RCC_TIM2CFGR				0x704
+#define RCC_TIM3CFGR				0x708
+#define RCC_TIM4CFGR				0x70C
+#define RCC_TIM5CFGR				0x710
+#define RCC_TIM6CFGR				0x714
+#define RCC_TIM7CFGR				0x718
+#define RCC_TIM8CFGR				0x71C
+#define RCC_TIM10CFGR				0x720
+#define RCC_TIM11CFGR				0x724
+#define RCC_TIM12CFGR				0x728
+#define RCC_TIM13CFGR				0x72C
+#define RCC_TIM14CFGR				0x730
+#define RCC_TIM15CFGR				0x734
+#define RCC_TIM16CFGR				0x738
+#define RCC_TIM17CFGR				0x73C
+#define RCC_TIM20CFGR				0x740
+#define RCC_LPTIM1CFGR				0x744
+#define RCC_LPTIM2CFGR				0x748
+#define RCC_LPTIM3CFGR				0x74C
+#define RCC_LPTIM4CFGR				0x750
+#define RCC_LPTIM5CFGR				0x754
+#define RCC_SPI1CFGR				0x758
+#define RCC_SPI2CFGR				0x75C
+#define RCC_SPI3CFGR				0x760
+#define RCC_SPI4CFGR				0x764
+#define RCC_SPI5CFGR				0x768
+#define RCC_SPI6CFGR				0x76C
+#define RCC_SPI7CFGR				0x770
+#define RCC_SPI8CFGR				0x774
+#define RCC_SPDIFRXCFGR				0x778
+#define RCC_USART1CFGR				0x77C
+#define RCC_USART2CFGR				0x780
+#define RCC_USART3CFGR				0x784
+#define RCC_UART4CFGR				0x788
+#define RCC_UART5CFGR				0x78C
+#define RCC_USART6CFGR				0x790
+#define RCC_UART7CFGR				0x794
+#define RCC_UART8CFGR				0x798
+#define RCC_UART9CFGR				0x79C
+#define RCC_LPUART1CFGR				0x7A0
+#define RCC_I2C1CFGR				0x7A4
+#define RCC_I2C2CFGR				0x7A8
+#define RCC_I2C3CFGR				0x7AC
+#define RCC_I2C4CFGR				0x7B0
+#define RCC_I2C5CFGR				0x7B4
+#define RCC_I2C6CFGR				0x7B8
+#define RCC_I2C7CFGR				0x7BC
+#define RCC_I2C8CFGR				0x7C0
+#define RCC_SAI1CFGR				0x7C4
+#define RCC_SAI2CFGR				0x7C8
+#define RCC_SAI3CFGR				0x7CC
+#define RCC_SAI4CFGR				0x7D0
+#define RCC_MDF1CFGR				0x7D8
+#define RCC_ADF1CFGR				0x7DC
+#define RCC_FDCANCFGR				0x7E0
+#define RCC_HDPCFGR				0x7E4
+#define RCC_ADC12CFGR				0x7E8
+#define RCC_ADC3CFGR				0x7EC
+#define RCC_ETH1CFGR				0x7F0
+#define RCC_ETH2CFGR				0x7F4
+#define RCC_USB2CFGR				0x7FC
+#define RCC_USB2PHY1CFGR			0x800
+#define RCC_USB2PHY2CFGR			0x804
+#define RCC_USB3DRCFGR				0x808
+#define RCC_USB3PCIEPHYCFGR			0x80C
+#define RCC_PCIECFGR				0x810
+#define RCC_USBTCCFGR				0x814
+#define RCC_ETHSWCFGR				0x818
+#define RCC_ETHSWACMCFGR			0x81C
+#define RCC_ETHSWACMMSGCFGR			0x820
+#define RCC_STGENCFGR				0x824
+#define RCC_SDMMC1CFGR				0x830
+#define RCC_SDMMC2CFGR				0x834
+#define RCC_SDMMC3CFGR				0x838
+#define RCC_GPUCFGR				0x83C
+#define RCC_LTDCCFGR				0x840
+#define RCC_DSICFGR				0x844
+#define RCC_LVDSCFGR				0x850
+#define RCC_CSICFGR				0x858
+#define RCC_DCMIPPCFGR				0x85C
+#define RCC_CCICFGR				0x860
+#define RCC_VDECCFGR				0x864
+#define RCC_VENCCFGR				0x868
+#define RCC_RNGCFGR				0x870
+#define RCC_PKACFGR				0x874
+#define RCC_SAESCFGR				0x878
+#define RCC_HASHCFGR				0x87C
+#define RCC_CRYP1CFGR				0x880
+#define RCC_CRYP2CFGR				0x884
+#define RCC_IWDG1CFGR				0x888
+#define RCC_IWDG2CFGR				0x88C
+#define RCC_IWDG3CFGR				0x890
+#define RCC_IWDG4CFGR				0x894
+#define RCC_IWDG5CFGR				0x898
+#define RCC_WWDG1CFGR				0x89C
+#define RCC_WWDG2CFGR				0x8A0
+#define RCC_VREFCFGR				0x8A8
+#define RCC_DTSCFGR				0x8AC
+#define RCC_CRCCFGR				0x8B4
+#define RCC_SERCCFGR				0x8B8
+#define RCC_OSPIIOMCFGR				0x8BC
+#define RCC_GICV2MCFGR				0x8C0
+#define RCC_I3C1CFGR				0x8C8
+#define RCC_I3C2CFGR				0x8CC
+#define RCC_I3C3CFGR				0x8D0
+#define RCC_I3C4CFGR				0x8D4
+#define RCC_MUXSELCFGR				0x1000
+#define RCC_XBAR0CFGR				0x1018
+#define RCC_XBAR1CFGR				0x101C
+#define RCC_XBAR2CFGR				0x1020
+#define RCC_XBAR3CFGR				0x1024
+#define RCC_XBAR4CFGR				0x1028
+#define RCC_XBAR5CFGR				0x102C
+#define RCC_XBAR6CFGR				0x1030
+#define RCC_XBAR7CFGR				0x1034
+#define RCC_XBAR8CFGR				0x1038
+#define RCC_XBAR9CFGR				0x103C
+#define RCC_XBAR10CFGR				0x1040
+#define RCC_XBAR11CFGR				0x1044
+#define RCC_XBAR12CFGR				0x1048
+#define RCC_XBAR13CFGR				0x104C
+#define RCC_XBAR14CFGR				0x1050
+#define RCC_XBAR15CFGR				0x1054
+#define RCC_XBAR16CFGR				0x1058
+#define RCC_XBAR17CFGR				0x105C
+#define RCC_XBAR18CFGR				0x1060
+#define RCC_XBAR19CFGR				0x1064
+#define RCC_XBAR20CFGR				0x1068
+#define RCC_XBAR21CFGR				0x106C
+#define RCC_XBAR22CFGR				0x1070
+#define RCC_XBAR23CFGR				0x1074
+#define RCC_XBAR24CFGR				0x1078
+#define RCC_XBAR25CFGR				0x107C
+#define RCC_XBAR26CFGR				0x1080
+#define RCC_XBAR27CFGR				0x1084
+#define RCC_XBAR28CFGR				0x1088
+#define RCC_XBAR29CFGR				0x108C
+#define RCC_XBAR30CFGR				0x1090
+#define RCC_XBAR31CFGR				0x1094
+#define RCC_XBAR32CFGR				0x1098
+#define RCC_XBAR33CFGR				0x109C
+#define RCC_XBAR34CFGR				0x10A0
+#define RCC_XBAR35CFGR				0x10A4
+#define RCC_XBAR36CFGR				0x10A8
+#define RCC_XBAR37CFGR				0x10AC
+#define RCC_XBAR38CFGR				0x10B0
+#define RCC_XBAR39CFGR				0x10B4
+#define RCC_XBAR40CFGR				0x10B8
+#define RCC_XBAR41CFGR				0x10BC
+#define RCC_XBAR42CFGR				0x10C0
+#define RCC_XBAR43CFGR				0x10C4
+#define RCC_XBAR44CFGR				0x10C8
+#define RCC_XBAR45CFGR				0x10CC
+#define RCC_XBAR46CFGR				0x10D0
+#define RCC_XBAR47CFGR				0x10D4
+#define RCC_XBAR48CFGR				0x10D8
+#define RCC_XBAR49CFGR				0x10DC
+#define RCC_XBAR50CFGR				0x10E0
+#define RCC_XBAR51CFGR				0x10E4
+#define RCC_XBAR52CFGR				0x10E8
+#define RCC_XBAR53CFGR				0x10EC
+#define RCC_XBAR54CFGR				0x10F0
+#define RCC_XBAR55CFGR				0x10F4
+#define RCC_XBAR56CFGR				0x10F8
+#define RCC_XBAR57CFGR				0x10FC
+#define RCC_XBAR58CFGR				0x1100
+#define RCC_XBAR59CFGR				0x1104
+#define RCC_XBAR60CFGR				0x1108
+#define RCC_XBAR61CFGR				0x110C
+#define RCC_XBAR62CFGR				0x1110
+#define RCC_XBAR63CFGR				0x1114
+#define RCC_PREDIV0CFGR				0x1118
+#define RCC_PREDIV1CFGR				0x111C
+#define RCC_PREDIV2CFGR				0x1120
+#define RCC_PREDIV3CFGR				0x1124
+#define RCC_PREDIV4CFGR				0x1128
+#define RCC_PREDIV5CFGR				0x112C
+#define RCC_PREDIV6CFGR				0x1130
+#define RCC_PREDIV7CFGR				0x1134
+#define RCC_PREDIV8CFGR				0x1138
+#define RCC_PREDIV9CFGR				0x113C
+#define RCC_PREDIV10CFGR			0x1140
+#define RCC_PREDIV11CFGR			0x1144
+#define RCC_PREDIV12CFGR			0x1148
+#define RCC_PREDIV13CFGR			0x114C
+#define RCC_PREDIV14CFGR			0x1150
+#define RCC_PREDIV15CFGR			0x1154
+#define RCC_PREDIV16CFGR			0x1158
+#define RCC_PREDIV17CFGR			0x115C
+#define RCC_PREDIV18CFGR			0x1160
+#define RCC_PREDIV19CFGR			0x1164
+#define RCC_PREDIV20CFGR			0x1168
+#define RCC_PREDIV21CFGR			0x116C
+#define RCC_PREDIV22CFGR			0x1170
+#define RCC_PREDIV23CFGR			0x1174
+#define RCC_PREDIV24CFGR			0x1178
+#define RCC_PREDIV25CFGR			0x117C
+#define RCC_PREDIV26CFGR			0x1180
+#define RCC_PREDIV27CFGR			0x1184
+#define RCC_PREDIV28CFGR			0x1188
+#define RCC_PREDIV29CFGR			0x118C
+#define RCC_PREDIV30CFGR			0x1190
+#define RCC_PREDIV31CFGR			0x1194
+#define RCC_PREDIV32CFGR			0x1198
+#define RCC_PREDIV33CFGR			0x119C
+#define RCC_PREDIV34CFGR			0x11A0
+#define RCC_PREDIV35CFGR			0x11A4
+#define RCC_PREDIV36CFGR			0x11A8
+#define RCC_PREDIV37CFGR			0x11AC
+#define RCC_PREDIV38CFGR			0x11B0
+#define RCC_PREDIV39CFGR			0x11B4
+#define RCC_PREDIV40CFGR			0x11B8
+#define RCC_PREDIV41CFGR			0x11BC
+#define RCC_PREDIV42CFGR			0x11C0
+#define RCC_PREDIV43CFGR			0x11C4
+#define RCC_PREDIV44CFGR			0x11C8
+#define RCC_PREDIV45CFGR			0x11CC
+#define RCC_PREDIV46CFGR			0x11D0
+#define RCC_PREDIV47CFGR			0x11D4
+#define RCC_PREDIV48CFGR			0x11D8
+#define RCC_PREDIV49CFGR			0x11DC
+#define RCC_PREDIV50CFGR			0x11E0
+#define RCC_PREDIV51CFGR			0x11E4
+#define RCC_PREDIV52CFGR			0x11E8
+#define RCC_PREDIV53CFGR			0x11EC
+#define RCC_PREDIV54CFGR			0x11F0
+#define RCC_PREDIV55CFGR			0x11F4
+#define RCC_PREDIV56CFGR			0x11F8
+#define RCC_PREDIV57CFGR			0x11FC
+#define RCC_PREDIV58CFGR			0x1200
+#define RCC_PREDIV59CFGR			0x1204
+#define RCC_PREDIV60CFGR			0x1208
+#define RCC_PREDIV61CFGR			0x120C
+#define RCC_PREDIV62CFGR			0x1210
+#define RCC_PREDIV63CFGR			0x1214
+#define RCC_PREDIVSR1				0x1218
+#define RCC_PREDIVSR2				0x121C
+#define RCC_FINDIV0CFGR				0x1224
+#define RCC_FINDIV1CFGR				0x1228
+#define RCC_FINDIV2CFGR				0x122C
+#define RCC_FINDIV3CFGR				0x1230
+#define RCC_FINDIV4CFGR				0x1234
+#define RCC_FINDIV5CFGR				0x1238
+#define RCC_FINDIV6CFGR				0x123C
+#define RCC_FINDIV7CFGR				0x1240
+#define RCC_FINDIV8CFGR				0x1244
+#define RCC_FINDIV9CFGR				0x1248
+#define RCC_FINDIV10CFGR			0x124C
+#define RCC_FINDIV11CFGR			0x1250
+#define RCC_FINDIV12CFGR			0x1254
+#define RCC_FINDIV13CFGR			0x1258
+#define RCC_FINDIV14CFGR			0x125C
+#define RCC_FINDIV15CFGR			0x1260
+#define RCC_FINDIV16CFGR			0x1264
+#define RCC_FINDIV17CFGR			0x1268
+#define RCC_FINDIV18CFGR			0x126C
+#define RCC_FINDIV19CFGR			0x1270
+#define RCC_FINDIV20CFGR			0x1274
+#define RCC_FINDIV21CFGR			0x1278
+#define RCC_FINDIV22CFGR			0x127C
+#define RCC_FINDIV23CFGR			0x1280
+#define RCC_FINDIV24CFGR			0x1284
+#define RCC_FINDIV25CFGR			0x1288
+#define RCC_FINDIV26CFGR			0x128C
+#define RCC_FINDIV27CFGR			0x1290
+#define RCC_FINDIV28CFGR			0x1294
+#define RCC_FINDIV29CFGR			0x1298
+#define RCC_FINDIV30CFGR			0x129C
+#define RCC_FINDIV31CFGR			0x12A0
+#define RCC_FINDIV32CFGR			0x12A4
+#define RCC_FINDIV33CFGR			0x12A8
+#define RCC_FINDIV34CFGR			0x12AC
+#define RCC_FINDIV35CFGR			0x12B0
+#define RCC_FINDIV36CFGR			0x12B4
+#define RCC_FINDIV37CFGR			0x12B8
+#define RCC_FINDIV38CFGR			0x12BC
+#define RCC_FINDIV39CFGR			0x12C0
+#define RCC_FINDIV40CFGR			0x12C4
+#define RCC_FINDIV41CFGR			0x12C8
+#define RCC_FINDIV42CFGR			0x12CC
+#define RCC_FINDIV43CFGR			0x12D0
+#define RCC_FINDIV44CFGR			0x12D4
+#define RCC_FINDIV45CFGR			0x12D8
+#define RCC_FINDIV46CFGR			0x12DC
+#define RCC_FINDIV47CFGR			0x12E0
+#define RCC_FINDIV48CFGR			0x12E4
+#define RCC_FINDIV49CFGR			0x12E8
+#define RCC_FINDIV50CFGR			0x12EC
+#define RCC_FINDIV51CFGR			0x12F0
+#define RCC_FINDIV52CFGR			0x12F4
+#define RCC_FINDIV53CFGR			0x12F8
+#define RCC_FINDIV54CFGR			0x12FC
+#define RCC_FINDIV55CFGR			0x1300
+#define RCC_FINDIV56CFGR			0x1304
+#define RCC_FINDIV57CFGR			0x1308
+#define RCC_FINDIV58CFGR			0x130C
+#define RCC_FINDIV59CFGR			0x1310
+#define RCC_FINDIV60CFGR			0x1314
+#define RCC_FINDIV61CFGR			0x1318
+#define RCC_FINDIV62CFGR			0x131C
+#define RCC_FINDIV63CFGR			0x1320
+#define RCC_FINDIVSR1				0x1324
+#define RCC_FINDIVSR2				0x1328
+#define RCC_FCALCOBS0CFGR			0x1340
+#define RCC_FCALCOBS1CFGR			0x1344
+#define RCC_FCALCREFCFGR			0x1348
+#define RCC_FCALCCR1				0x134C
+#define RCC_FCALCCR2				0x1354
+#define RCC_FCALCSR				0x1358
+#define RCC_PLL4CFGR1				0x1360
+#define RCC_PLL4CFGR2				0x1364
+#define RCC_PLL4CFGR3				0x1368
+#define RCC_PLL4CFGR4				0x136C
+#define RCC_PLL4CFGR5				0x1370
+#define RCC_PLL4CFGR6				0x1378
+#define RCC_PLL4CFGR7				0x137C
+#define RCC_PLL5CFGR1				0x1388
+#define RCC_PLL5CFGR2				0x138C
+#define RCC_PLL5CFGR3				0x1390
+#define RCC_PLL5CFGR4				0x1394
+#define RCC_PLL5CFGR5				0x1398
+#define RCC_PLL5CFGR6				0x13A0
+#define RCC_PLL5CFGR7				0x13A4
+#define RCC_PLL6CFGR1				0x13B0
+#define RCC_PLL6CFGR2				0x13B4
+#define RCC_PLL6CFGR3				0x13B8
+#define RCC_PLL6CFGR4				0x13BC
+#define RCC_PLL6CFGR5				0x13C0
+#define RCC_PLL6CFGR6				0x13C8
+#define RCC_PLL6CFGR7				0x13CC
+#define RCC_PLL7CFGR1				0x13D8
+#define RCC_PLL7CFGR2				0x13DC
+#define RCC_PLL7CFGR3				0x13E0
+#define RCC_PLL7CFGR4				0x13E4
+#define RCC_PLL7CFGR5				0x13E8
+#define RCC_PLL7CFGR6				0x13F0
+#define RCC_PLL7CFGR7				0x13F4
+#define RCC_PLL8CFGR1				0x1400
+#define RCC_PLL8CFGR2				0x1404
+#define RCC_PLL8CFGR3				0x1408
+#define RCC_PLL8CFGR4				0x140C
+#define RCC_PLL8CFGR5				0x1410
+#define RCC_PLL8CFGR6				0x1418
+#define RCC_PLL8CFGR7				0x141C
+#define RCC_VERR				0xFFF4
+#define RCC_IDR					0xFFF8
+#define RCC_SIDR				0xFFFC
+
+#endif /* STM32MP25_RCC_H */
-- 
2.25.1



From gabriel.fernandez at foss.st.com  Thu Feb  8 06:23:01 2024
From: gabriel.fernandez at foss.st.com (gabriel.fernandez at foss.st.com)
Date: Thu, 8 Feb 2024 15:23:01 +0100
Subject: [PATCH v9 4/4] arm64: dts: st: add rcc support for STM32MP25
In-Reply-To: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
References: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
Message-ID: <20240208142301.155698-5-gabriel.fernandez@foss.st.com>

From: Gabriel Fernandez <gabriel.fernandez at foss.st.com>

Add RCC support to manage clocks and resets on the STM32MP25.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 144 ++++++++++++++++++-------
 arch/arm64/boot/dts/st/stm32mp255.dtsi |   4 +-
 2 files changed, 110 insertions(+), 38 deletions(-)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 5dd4f3580a60..15b79d26d1c6 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -3,7 +3,9 @@
  * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue at foss.st.com> for STMicroelectronics.
  */
+#include <dt-bindings/clock/st,stm32mp25-rcc.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/st,stm32mp25-rcc.h>
 
 / {
 	#address-cells = <2>;
@@ -35,34 +37,16 @@ arm_wdt: watchdog {
 	};
 
 	clocks {
-		ck_flexgen_08: ck-flexgen-08 {
+		clk_dsi_txbyte: txbyteclk {
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
-			clock-frequency = <100000000>;
+			clock-frequency = <0>;
 		};
 
-		ck_flexgen_51: ck-flexgen-51 {
+		clk_rcbsec: clk-rcbsec {
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
-			clock-frequency = <200000000>;
-		};
-
-		ck_icn_ls_mcu: ck-icn-ls-mcu {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <200000000>;
-		};
-
-		ck_icn_p_vdec: ck-icn-p-vdec {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <200000000>;
-		};
-
-		ck_icn_p_venc: ck-icn-p-venc {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <200000000>;
+			clock-frequency = <64000000>;
 		};
 	};
 
@@ -134,7 +118,7 @@ usart2: serial at 400e0000 {
 				compatible = "st,stm32h7-uart";
 				reg = <0x400e0000 0x400>;
 				interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&ck_flexgen_08>;
+				clocks = <&rcc CK_KER_USART2>;
 				status = "disabled";
 			};
 
@@ -143,8 +127,9 @@ sdmmc1: mmc at 48220000 {
 				arm,primecell-periphid = <0x00353180>;
 				reg = <0x48220000 0x400>, <0x44230400 0x8>;
 				interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&ck_flexgen_51>;
+				clocks = <&rcc CK_KER_SDMMC1 >;
 				clock-names = "apb_pclk";
+				resets = <&rcc SDMMC1_R>;
 				cap-sd-highspeed;
 				cap-mmc-highspeed;
 				max-frequency = <120000000>;
@@ -168,6 +153,93 @@ package_otp at 1e8 {
 			};
 		};
 
+		rcc: clock-controller at 44200000 {
+			compatible = "st,stm32mp25-rcc";
+			reg = <0x44200000 0x10000>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			clocks = <&scmi_clk CK_SCMI_HSE>,
+				<&scmi_clk CK_SCMI_HSI>,
+				<&scmi_clk CK_SCMI_MSI>,
+				<&scmi_clk CK_SCMI_LSE>,
+				<&scmi_clk CK_SCMI_LSI>,
+				<&scmi_clk CK_SCMI_HSE_DIV2>,
+				<&scmi_clk CK_SCMI_ICN_HS_MCU>,
+				<&scmi_clk CK_SCMI_ICN_LS_MCU>,
+				<&scmi_clk CK_SCMI_ICN_SDMMC>,
+				<&scmi_clk CK_SCMI_ICN_DDR>,
+				<&scmi_clk CK_SCMI_ICN_DISPLAY>,
+				<&scmi_clk CK_SCMI_ICN_HSL>,
+				<&scmi_clk CK_SCMI_ICN_NIC>,
+				<&scmi_clk CK_SCMI_ICN_VID>,
+				<&scmi_clk CK_SCMI_FLEXGEN_07>,
+				<&scmi_clk CK_SCMI_FLEXGEN_08>,
+				<&scmi_clk CK_SCMI_FLEXGEN_09>,
+				<&scmi_clk CK_SCMI_FLEXGEN_10>,
+				<&scmi_clk CK_SCMI_FLEXGEN_11>,
+				<&scmi_clk CK_SCMI_FLEXGEN_12>,
+				<&scmi_clk CK_SCMI_FLEXGEN_13>,
+				<&scmi_clk CK_SCMI_FLEXGEN_14>,
+				<&scmi_clk CK_SCMI_FLEXGEN_15>,
+				<&scmi_clk CK_SCMI_FLEXGEN_16>,
+				<&scmi_clk CK_SCMI_FLEXGEN_17>,
+				<&scmi_clk CK_SCMI_FLEXGEN_18>,
+				<&scmi_clk CK_SCMI_FLEXGEN_19>,
+				<&scmi_clk CK_SCMI_FLEXGEN_20>,
+				<&scmi_clk CK_SCMI_FLEXGEN_21>,
+				<&scmi_clk CK_SCMI_FLEXGEN_22>,
+				<&scmi_clk CK_SCMI_FLEXGEN_23>,
+				<&scmi_clk CK_SCMI_FLEXGEN_24>,
+				<&scmi_clk CK_SCMI_FLEXGEN_25>,
+				<&scmi_clk CK_SCMI_FLEXGEN_26>,
+				<&scmi_clk CK_SCMI_FLEXGEN_27>,
+				<&scmi_clk CK_SCMI_FLEXGEN_28>,
+				<&scmi_clk CK_SCMI_FLEXGEN_29>,
+				<&scmi_clk CK_SCMI_FLEXGEN_30>,
+				<&scmi_clk CK_SCMI_FLEXGEN_31>,
+				<&scmi_clk CK_SCMI_FLEXGEN_32>,
+				<&scmi_clk CK_SCMI_FLEXGEN_33>,
+				<&scmi_clk CK_SCMI_FLEXGEN_34>,
+				<&scmi_clk CK_SCMI_FLEXGEN_35>,
+				<&scmi_clk CK_SCMI_FLEXGEN_36>,
+				<&scmi_clk CK_SCMI_FLEXGEN_37>,
+				<&scmi_clk CK_SCMI_FLEXGEN_38>,
+				<&scmi_clk CK_SCMI_FLEXGEN_39>,
+				<&scmi_clk CK_SCMI_FLEXGEN_40>,
+				<&scmi_clk CK_SCMI_FLEXGEN_41>,
+				<&scmi_clk CK_SCMI_FLEXGEN_42>,
+				<&scmi_clk CK_SCMI_FLEXGEN_43>,
+				<&scmi_clk CK_SCMI_FLEXGEN_44>,
+				<&scmi_clk CK_SCMI_FLEXGEN_45>,
+				<&scmi_clk CK_SCMI_FLEXGEN_46>,
+				<&scmi_clk CK_SCMI_FLEXGEN_47>,
+				<&scmi_clk CK_SCMI_FLEXGEN_48>,
+				<&scmi_clk CK_SCMI_FLEXGEN_49>,
+				<&scmi_clk CK_SCMI_FLEXGEN_50>,
+				<&scmi_clk CK_SCMI_FLEXGEN_51>,
+				<&scmi_clk CK_SCMI_FLEXGEN_52>,
+				<&scmi_clk CK_SCMI_FLEXGEN_53>,
+				<&scmi_clk CK_SCMI_FLEXGEN_54>,
+				<&scmi_clk CK_SCMI_FLEXGEN_55>,
+				<&scmi_clk CK_SCMI_FLEXGEN_56>,
+				<&scmi_clk CK_SCMI_FLEXGEN_57>,
+				<&scmi_clk CK_SCMI_FLEXGEN_58>,
+				<&scmi_clk CK_SCMI_FLEXGEN_59>,
+				<&scmi_clk CK_SCMI_FLEXGEN_60>,
+				<&scmi_clk CK_SCMI_FLEXGEN_61>,
+				<&scmi_clk CK_SCMI_FLEXGEN_62>,
+				<&scmi_clk CK_SCMI_FLEXGEN_63>,
+				<&scmi_clk CK_SCMI_ICN_APB1>,
+				<&scmi_clk CK_SCMI_ICN_APB2>,
+				<&scmi_clk CK_SCMI_ICN_APB3>,
+				<&scmi_clk CK_SCMI_ICN_APB4>,
+				<&scmi_clk CK_SCMI_ICN_APBDBG>,
+				<&scmi_clk CK_SCMI_TIMG1>,
+				<&scmi_clk CK_SCMI_TIMG2>,
+				<&scmi_clk CK_SCMI_PLL3>,
+				<&clk_dsi_txbyte>;
+		};
+
 		syscfg: syscon at 44230000 {
 			compatible = "st,stm32mp25-syscfg", "syscon";
 			reg = <0x44230000 0x10000>;
@@ -186,7 +258,7 @@ gpioa: gpio at 44240000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0x0 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOA>;
 				st,bank-name = "GPIOA";
 				status = "disabled";
 			};
@@ -197,7 +269,7 @@ gpiob: gpio at 44250000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0x10000 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOB>;
 				st,bank-name = "GPIOB";
 				status = "disabled";
 			};
@@ -208,7 +280,7 @@ gpioc: gpio at 44260000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0x20000 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOC>;
 				st,bank-name = "GPIOC";
 				status = "disabled";
 			};
@@ -219,7 +291,7 @@ gpiod: gpio at 44270000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0x30000 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOD>;
 				st,bank-name = "GPIOD";
 				status = "disabled";
 			};
@@ -230,7 +302,7 @@ gpioe: gpio at 44280000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0x40000 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOE>;
 				st,bank-name = "GPIOE";
 				status = "disabled";
 			};
@@ -241,7 +313,7 @@ gpiof: gpio at 44290000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0x50000 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOF>;
 				st,bank-name = "GPIOF";
 				status = "disabled";
 			};
@@ -252,7 +324,7 @@ gpiog: gpio at 442a0000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0x60000 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOG>;
 				st,bank-name = "GPIOG";
 				status = "disabled";
 			};
@@ -263,7 +335,7 @@ gpioh: gpio at 442b0000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0x70000 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOH>;
 				st,bank-name = "GPIOH";
 				status = "disabled";
 			};
@@ -274,7 +346,7 @@ gpioi: gpio at 442c0000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0x80000 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOI>;
 				st,bank-name = "GPIOI";
 				status = "disabled";
 			};
@@ -285,7 +357,7 @@ gpioj: gpio at 442d0000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0x90000 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOJ>;
 				st,bank-name = "GPIOJ";
 				status = "disabled";
 			};
@@ -296,7 +368,7 @@ gpiok: gpio at 442e0000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0xa0000 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOK>;
 				st,bank-name = "GPIOK";
 				status = "disabled";
 			};
@@ -315,7 +387,7 @@ gpioz: gpio at 46200000 {
 				interrupt-controller;
 				#interrupt-cells = <2>;
 				reg = <0 0x400>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&scmi_clk CK_SCMI_GPIOZ>;
 				st,bank-name = "GPIOZ";
 				st,bank-ioport = <11>;
 				status = "disabled";
diff --git a/arch/arm64/boot/dts/st/stm32mp255.dtsi b/arch/arm64/boot/dts/st/stm32mp255.dtsi
index 17f197c5b22b..d5175a1f339c 100644
--- a/arch/arm64/boot/dts/st/stm32mp255.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp255.dtsi
@@ -12,14 +12,14 @@ vdec: vdec at 480d0000 {
 				compatible = "st,stm32mp25-vdec";
 				reg = <0x480d0000 0x3c8>;
 				interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&ck_icn_p_vdec>;
+				clocks = <&rcc CK_BUS_VDEC>;
 			};
 
 			venc: venc at 480e0000 {
 				compatible = "st,stm32mp25-venc";
 				reg = <0x480e0000 0x800>;
 				interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&ck_icn_ls_mcu>;
+				clocks = <&rcc CK_BUS_VENC>;
 			};
 		};
 	};
-- 
2.25.1



From lee at kernel.org  Thu Feb  8 06:24:57 2024
From: lee at kernel.org (Lee Jones)
Date: Thu, 08 Feb 2024 14:24:57 +0000
Subject: [PATCH 00/18] mfd: convert to use maple tree register cache
In-Reply-To: <20240206071314.8721-1-liubo03@inspur.com>
References: <20240206071314.8721-1-liubo03@inspur.com>
Message-ID: <170740229742.1068783.15434523911244194304.b4-ty@kernel.org>

On Tue, 06 Feb 2024 02:12:56 -0500, Bo Liu wrote:
> The maple tree register cache is based on a much more modern data structure
> than the rbtree cache and makes optimisation choices which are probably
> more appropriate for modern systems than those made by the rbtree cache.
> 
> Bo Liu (18):
>   mfd: ac100: convert to use maple tree register cache
>   mfd: as3711: convert to use maple tree register cache
>   mfd: as3722: convert to use maple tree register cache
>   mfd: axp20x: convert to use maple tree register cache
>   mfd: bcm590xx: convert to use maple tree register cache
>   mfd: bd9571mwv: convert to use maple tree register cache
>   mfd: dialog: convert to use maple tree register cache
>   mfd: khadas-mcu: convert to use maple tree register cache
>   mfd: lochnagar-i2c: convert to use maple tree register cache
>   mfd: wolfson: convert to use maple tree register cache
>   mfd: rohm: convert to use maple tree register cache
>   mfd: rk8xx: convert to use maple tree register cache
>   mfd: rn5t618: convert to use maple tree register cache
>   mfd: rsmu_i2c: convert to use maple tree register cache
>   mfd: si476x: convert to use maple tree register cache
>   mfd: stmfx: convert to use maple tree register cache
>   mfd: stpmic1: convert to use maple tree register cache
>   mfd: rc5t583: convert to use maple tree register cache
> 
> [...]

Applied, thanks!

[01/18] mfd: ac100: convert to use maple tree register cache
        commit: 8745a81ac22f42c7233fbddc6aa5922b231aac2a
[02/18] mfd: as3711: convert to use maple tree register cache
        commit: 780b1aa441a3d64e400cb2ea96bc3e162322eb31
[03/18] mfd: as3722: convert to use maple tree register cache
        commit: aea5c3cbc51eee3ac25ff8f936252901c4549011
[04/18] mfd: axp20x: convert to use maple tree register cache
        commit: 009073d504f67146d936cc45f21cc27c1bc15490
[05/18] mfd: bcm590xx: convert to use maple tree register cache
        commit: 684c1f0b79417cf08810dfd57c5a549a9741ad7a
[06/18] mfd: bd9571mwv: convert to use maple tree register cache
        commit: 35b1b8622ca3172b3c6b2a377e5913bac0367634
[07/18] mfd: dialog: convert to use maple tree register cache
        commit: 1cb7a3bca56c124ca9e5c13fcac7de884c195c5c
[08/18] mfd: khadas-mcu: convert to use maple tree register cache
        commit: 5f734f5f374f68960afd2130a5ce982912c14c15
[09/18] mfd: lochnagar-i2c: convert to use maple tree register cache
        commit: 8881896e05b6a91251dde0ce21ce79c2c201888d
[10/18] mfd: wolfson: convert to use maple tree register cache
        commit: f353b2c639e4f4ac9831d94c8237026cebaa8e73
[11/18] mfd: rohm: convert to use maple tree register cache
        commit: aabd38f3779b8108b65cc7ae8b5c20a6c352b0a2
[12/18] mfd: rk8xx: convert to use maple tree register cache
        commit: 08aa1e797a5cc97d2106476263f938342e72015e
[13/18] mfd: rn5t618: convert to use maple tree register cache
        commit: a011cacb63c3ff6562bd86afae8cdd49d0f075c9
[14/18] mfd: rsmu_i2c: convert to use maple tree register cache
        commit: b85821cecdf933420a6ba93658e1e4710644f5c1
[15/18] mfd: si476x: convert to use maple tree register cache
        commit: 030473871c3f4f126bd43018517abfcb070f6b95
[16/18] mfd: stmfx: convert to use maple tree register cache
        commit: 87a48e35ce2ef992287b828b1268bedc7415d2de
[17/18] mfd: stpmic1: convert to use maple tree register cache
        commit: ab993d2d68951db3ebfeaa44567a790ec566526d
[18/18] mfd: rc5t583: convert to use maple tree register cache
        commit: d5132d176d6f21742ac67fd311ccc61fe830e999

--
Lee Jones [???]



From lee at kernel.org  Thu Feb  8 06:26:27 2024
From: lee at kernel.org (Lee Jones)
Date: Thu, 8 Feb 2024 14:26:27 +0000
Subject: [PATCH 00/18] mfd: convert to use maple tree register cache
In-Reply-To: <170740229742.1068783.15434523911244194304.b4-ty@kernel.org>
References: <20240206071314.8721-1-liubo03@inspur.com>
 <170740229742.1068783.15434523911244194304.b4-ty@kernel.org>
Message-ID: <20240208142627.GT689448@google.com>

On Thu, 08 Feb 2024, Lee Jones wrote:

> On Tue, 06 Feb 2024 02:12:56 -0500, Bo Liu wrote:
> > The maple tree register cache is based on a much more modern data structure
> > than the rbtree cache and makes optimisation choices which are probably
> > more appropriate for modern systems than those made by the rbtree cache.
> > 
> > Bo Liu (18):
> >   mfd: ac100: convert to use maple tree register cache
> >   mfd: as3711: convert to use maple tree register cache
> >   mfd: as3722: convert to use maple tree register cache
> >   mfd: axp20x: convert to use maple tree register cache
> >   mfd: bcm590xx: convert to use maple tree register cache
> >   mfd: bd9571mwv: convert to use maple tree register cache
> >   mfd: dialog: convert to use maple tree register cache
> >   mfd: khadas-mcu: convert to use maple tree register cache
> >   mfd: lochnagar-i2c: convert to use maple tree register cache
> >   mfd: wolfson: convert to use maple tree register cache
> >   mfd: rohm: convert to use maple tree register cache
> >   mfd: rk8xx: convert to use maple tree register cache
> >   mfd: rn5t618: convert to use maple tree register cache
> >   mfd: rsmu_i2c: convert to use maple tree register cache
> >   mfd: si476x: convert to use maple tree register cache
> >   mfd: stmfx: convert to use maple tree register cache
> >   mfd: stpmic1: convert to use maple tree register cache
> >   mfd: rc5t583: convert to use maple tree register cache
> > 
> > [...]
> 
> Applied, thanks!
> 
> [01/18] mfd: ac100: convert to use maple tree register cache
>         commit: 8745a81ac22f42c7233fbddc6aa5922b231aac2a
> [02/18] mfd: as3711: convert to use maple tree register cache
>         commit: 780b1aa441a3d64e400cb2ea96bc3e162322eb31
> [03/18] mfd: as3722: convert to use maple tree register cache
>         commit: aea5c3cbc51eee3ac25ff8f936252901c4549011
> [04/18] mfd: axp20x: convert to use maple tree register cache
>         commit: 009073d504f67146d936cc45f21cc27c1bc15490
> [05/18] mfd: bcm590xx: convert to use maple tree register cache
>         commit: 684c1f0b79417cf08810dfd57c5a549a9741ad7a
> [06/18] mfd: bd9571mwv: convert to use maple tree register cache
>         commit: 35b1b8622ca3172b3c6b2a377e5913bac0367634
> [07/18] mfd: dialog: convert to use maple tree register cache
>         commit: 1cb7a3bca56c124ca9e5c13fcac7de884c195c5c
> [08/18] mfd: khadas-mcu: convert to use maple tree register cache
>         commit: 5f734f5f374f68960afd2130a5ce982912c14c15
> [09/18] mfd: lochnagar-i2c: convert to use maple tree register cache
>         commit: 8881896e05b6a91251dde0ce21ce79c2c201888d
> [10/18] mfd: wolfson: convert to use maple tree register cache
>         commit: f353b2c639e4f4ac9831d94c8237026cebaa8e73
> [11/18] mfd: rohm: convert to use maple tree register cache
>         commit: aabd38f3779b8108b65cc7ae8b5c20a6c352b0a2
> [12/18] mfd: rk8xx: convert to use maple tree register cache
>         commit: 08aa1e797a5cc97d2106476263f938342e72015e
> [13/18] mfd: rn5t618: convert to use maple tree register cache
>         commit: a011cacb63c3ff6562bd86afae8cdd49d0f075c9
> [14/18] mfd: rsmu_i2c: convert to use maple tree register cache
>         commit: b85821cecdf933420a6ba93658e1e4710644f5c1
> [15/18] mfd: si476x: convert to use maple tree register cache
>         commit: 030473871c3f4f126bd43018517abfcb070f6b95
> [16/18] mfd: stmfx: convert to use maple tree register cache
>         commit: 87a48e35ce2ef992287b828b1268bedc7415d2de
> [17/18] mfd: stpmic1: convert to use maple tree register cache
>         commit: ab993d2d68951db3ebfeaa44567a790ec566526d
> [18/18] mfd: rc5t583: convert to use maple tree register cache
>         commit: d5132d176d6f21742ac67fd311ccc61fe830e999

Next time you send a large patch-set, could you please ensure the
subject line format matches that of the subsystem you're submitting to
please?  It would have a saved me from a whole bunch of fix-ups.

Thanks.

-- 
Lee Jones [???]


From jgg at nvidia.com  Thu Feb  8 06:27:29 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 8 Feb 2024 10:27:29 -0400
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240208125846.GA23290@willie-the-truck>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
 <20240208125846.GA23290@willie-the-truck>
Message-ID: <20240208142729.GH10476@nvidia.com>

On Thu, Feb 08, 2024 at 12:58:47PM +0000, Will Deacon wrote:
> On Fri, Feb 02, 2024 at 10:28:05AM -0400, Jason Gunthorpe wrote:
> > If the SMMU is configured to use a two level CD table then
> > arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
> > GFP_KERNEL. Due to recent changes this is being done under a spinlock to
> > iterate over the device list - thus it will trigger a sleeping while
> > atomic warning:
> > 
> >   arm_smmu_sva_set_dev_pasid()
> >     mutex_lock(&sva_lock);
> >     __arm_smmu_sva_bind()
> >      arm_smmu_mmu_notifier_get()
> >       spin_lock_irqsave()
> >       arm_smmu_write_ctx_desc()
> > 	arm_smmu_get_cd_ptr()
> >          arm_smmu_alloc_cd_leaf_table()
> > 	  dmam_alloc_coherent(GFP_KERNEL)
> > 
> > This is a 64K high order allocation and really should not be done
> > atomically.
> > 
> > The proper answer is to sequence CD programming in a way that does not
> > require the device list or a spinlock. Part two of my lager series does
> > this and already solves this bug.
> > 
> > In the mean time we can solve the functional issue by preallocating the CD
> > entry outside any locking. CD leafs are effectively never freed so this
> > guarantees the arm_smmu_write_ctx_desc() inside the lock will not take the
> > allocation path.
> > 
> > Fixes: 24503148c545 ("iommu/arm-smmu-v3: Refactor write_ctx_desc")
> > Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> > Closes: https://lore.kernel.org/all/4e25d161-0cf8-4050-9aa3-dfa21cd63e56 at moroto.mountain/
> > Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> > ---
> >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 5 +++++
> >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c     | 2 +-
> >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h     | 2 ++
> >  3 files changed, 8 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> > index 05722121f00e70..068d60732e6481 100644
> > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> > @@ -588,6 +588,11 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
> >  {
> >  	int ret = 0;
> >  	struct mm_struct *mm = domain->mm;
> > +	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> > +
> > +	/* Preallocate the required leafs outside locks */
> > +	if (!arm_smmu_get_cd_ptr(master, id))
> > +		return -ENOMEM;
> 
> What guarantees that all the masters in the domain share the same l2 CD
> table?

Nothing, in fact they don't.

However, a multi-master RID domain is something that doesn't fully
work with SVA today. This code is functionally/security wrong to
install the PASID into all the masters that share the RID domain.

In practice that doesn't happen because the iommu group size when
PASID is enabled is restricted to 1 and the DMA API is the thing that
has created a unique per-group domain to be able to turn SVA on at
all.

So, the RID domain's list has one master entry that is the same as the
set_dev_pasid's master.

Which is why this patch works, it prealloctes the only master that
matters for the only configuration where SVA works and is used today.

iommufd could violate these assumptions which is part of why I'm
fixing all of this in preparation to enable PASID support for all
drivers in iommufd.

> The only reason we need the spinlock is to walk over the device
> list, so if that's not necessary then we could push this down into
> arm_smmu_mmu_notifier_get().

Pushing stuff down into arm_smmu_mmu_notifier_get() is the wrong
direction. CD manipulation needs to be lifted up and out into the
generic PASID level, not pushed down toward more SVA specific code.

This patch is where I got rid of the device list iteration:

https://lore.kernel.org/linux-iommu/11-v4-e7091cdd9e8d+43b1-smmuv3_newapi_p2_jgg at nvidia.com/

By lifting the CD programming up and then into the developing generic
PASID layer.

It is worth to jump ahead to the end, once part 2 is done the
set_dev_pasid SVA op looks like this:

static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
				      struct device *dev, ioasid_t id)
{
	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
	struct arm_smmu_cd target;
	int ret;

	/* Prevent arm_smmu_mm_release from being called while we are attaching */
	if (!mmget_not_zero(domain->mm))
		return -EINVAL;

	/*
	 * This does not need the arm_smmu_asid_lock because SVA domains never
	 * get reassigned
	 */
	arm_smmu_make_sva_cd(&target, master, smmu_domain->domain.mm,
			     smmu_domain->asid,
			     smmu_domain->btm_invalidation);

	ret = arm_smmu_set_pasid(master, smmu_domain, id, &target);

	mmput(domain->mm);
	return ret;
}

Where the cd programming is in arm_smmu_set_pasid() and that code is
fully shared between attaching a normal S1 paging domain and a SVA to
a PASID.

Jason


From kurt at linutronix.de  Thu Feb  8 06:32:30 2024
From: kurt at linutronix.de (Kurt Kanzenbach)
Date: Thu, 08 Feb 2024 15:32:30 +0100
Subject: [PATCH net-next] net: stmmac: Simplify mtl IRQ status checking
In-Reply-To: <ZcTNCxrWTAfj90Es@boxer>
References: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>
 <ZcTNCxrWTAfj90Es@boxer>
Message-ID: <871q9n81s1.fsf@kurt.kurt.home>

On Thu Feb 08 2024, Maciej Fijalkowski wrote:
> On Thu, Feb 08, 2024 at 11:35:25AM +0100, Kurt Kanzenbach wrote:
>> Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO overflow
>> interrupts") disabled the RX FIFO overflow interrupts. However, it left the
>> status variable around, but never checks it.
>> 
>> As stmmac_host_mtl_irq_status() returns only 0 now, the code can be
>> simplified.
>> 
>> Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
>> ---
>>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++----
>>  1 file changed, 2 insertions(+), 4 deletions(-)
>> 
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> index 04d817dc5899..10ce2f272b62 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> @@ -6036,10 +6036,8 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv)
>>  				priv->tx_path_in_lpi_mode = false;
>>  		}
>>  
>> -		for (queue = 0; queue < queues_count; queue++) {
>> -			status = stmmac_host_mtl_irq_status(priv, priv->hw,
>> -							    queue);
>> -		}
>> +		for (queue = 0; queue < queues_count; queue++)
>> +			stmmac_host_mtl_irq_status(priv, priv->hw, queue);
>
> Hey Kurt,
>
> looks to me that all of the current callbacks just return 0 so why not
> make them return void instead?

Well, there are two callbacks of this in dwmac4 and dwxgmac2. Both of
them still have the code for handling the overflow interrupt (and then
returning != 0). However, as of commit 8a7cb245cf28 the interrupt
shouldn't fire. So yes, it could be changed to void along with some
code removal. But, maybe i'm missing something.

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

From jgg at nvidia.com  Thu Feb  8 06:34:14 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 8 Feb 2024 10:34:14 -0400
Subject: [PATCH v6 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <ZcTRH1rzfPbuQ_qj@arm.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-3-ankita@nvidia.com>
 <ZcTRH1rzfPbuQ_qj@arm.com>
Message-ID: <20240208143414.GJ10476@nvidia.com>

On Thu, Feb 08, 2024 at 01:03:27PM +0000, Catalin Marinas wrote:
> On Thu, Feb 08, 2024 at 02:16:50AM +0530, ankita at nvidia.com wrote:
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index f5a97dec5169..884c068a79eb 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -391,6 +391,20 @@ extern unsigned int kobjsize(const void *objp);
> >  # define VM_UFFD_MINOR		VM_NONE
> >  #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
> >  
> > +/*
> > + * This flag is used to connect VFIO to arch specific KVM code. It
> > + * indicates that the memory under this VMA is safe for use with any
> > + * non-cachable memory type inside KVM. Some VFIO devices, on some
> > + * platforms, are thought to be unsafe and can cause machine crashes if
> > + * KVM does not lock down the memory type.
> > + */
> > +#ifdef CONFIG_64BIT
> > +#define VM_VFIO_ALLOW_WC_BIT	39
> > +#define VM_VFIO_ALLOW_WC	BIT(VM_VFIO_ALLOW_WC_BIT)
> > +#else
> > +#define VM_VFIO_ALLOW_WC	VM_NONE
> > +#endif
> 
> Adding David Hildenbrand to this thread as well since we briefly
> discussed potential alternatives (not sure we came to any conclusion).

FWIW, with my mm hat on:

Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>

But I'm interested if David has an alternative. We don't have a
shortage of bits here so I'm not sure it is worth much fuss.

Jason


From alexander.stein at ew.tq-group.com  Thu Feb  8 06:43:47 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Thu, 08 Feb 2024 15:43:47 +0100
Subject: [PATCH] arm64: dts: freescale: minor whitespace cleanup
In-Reply-To: <20240208105217.128748-1-krzysztof.kozlowski@linaro.org>
References: <20240208105217.128748-1-krzysztof.kozlowski@linaro.org>
Message-ID: <3548464.iIbC2pHGDl@steina-w>

Hi Krzysztof,

Am Donnerstag, 8. Februar 2024, 11:52:26 CET schrieb Krzysztof Kozlowski:
> The DTS code coding style expects exactly one space before '{'
> character.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Thanks.
Reviewed-by: Alexander Stein <alexander.stein at ew.tq-group.com>

> ---
>  arch/arm64/boot/dts/freescale/imx8ulp-evk.dts | 2 +-
>  arch/arm64/boot/dts/freescale/mba8xx.dtsi     | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
> b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts index
> 69dd8e31027c..24bb253b938d 100644
> --- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
> @@ -37,7 +37,7 @@ m33_reserved: noncacheable-section at a8600000 {
>  			no-map;
>  		};
> 
> -		rsc_table: rsc-table at 1fff8000{
> +		rsc_table: rsc-table at 1fff8000 {
>  			reg = <0 0x1fff8000 0 0x1000>;
>  			no-map;
>  		};
> diff --git a/arch/arm64/boot/dts/freescale/mba8xx.dtsi
> b/arch/arm64/boot/dts/freescale/mba8xx.dtsi index
> 6164fefb9218..3b4c5fa21f31 100644
> --- a/arch/arm64/boot/dts/freescale/mba8xx.dtsi
> +++ b/arch/arm64/boot/dts/freescale/mba8xx.dtsi
> @@ -466,7 +466,7 @@ pinctrl_pca9538: pca9538grp {
>  		fsl,pins = <IMX8QXP_USDHC1_RESET_B_LSIO_GPIO4_IO19	
0x00000020>;
>  	};
> 
> -	pinctrl_pcieb: pcieagrp{
> +	pinctrl_pcieb: pcieagrp {
>  		fsl,pins = <IMX8QXP_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00	
0x06000041>,
>  			   <IMX8QXP_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO01	
0x06000041>,
>  			   <IMX8QXP_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO02	
0x04000041>;


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From catalin.marinas at arm.com  Thu Feb  8 06:51:30 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 14:51:30 +0000
Subject: [PATCH v6 3/4] kvm: arm64: set io memory s2 pte as normalnc for
 vfio pci device
In-Reply-To: <20240207204652.22954-4-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-4-ankita@nvidia.com>
Message-ID: <ZcTqcqE69zkLZgQx@arm.com>

On Thu, Feb 08, 2024 at 02:16:51AM +0530, ankita at nvidia.com wrote:
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index d14504821b79..e1e6847a793b 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1381,7 +1381,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  	int ret = 0;
>  	bool write_fault, writable, force_pte = false;
>  	bool exec_fault, mte_allowed;
> -	bool device = false;
> +	bool device = false, vfio_allow_wc = false;
>  	unsigned long mmu_seq;
>  	struct kvm *kvm = vcpu->kvm;
>  	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
> @@ -1472,6 +1472,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
>  	gfn = fault_ipa >> PAGE_SHIFT;
>  	mte_allowed = kvm_vma_mte_allowed(vma);
>  
> +	vfio_allow_wc = (vma->vm_flags & VM_VFIO_ALLOW_WC);

Nitpick: no need for brackets, '=' has a pretty low precedence.

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From maciej.fijalkowski at intel.com  Thu Feb  8 06:52:27 2024
From: maciej.fijalkowski at intel.com (Maciej Fijalkowski)
Date: Thu, 8 Feb 2024 15:52:27 +0100
Subject: [PATCH net-next] net: stmmac: Simplify mtl IRQ status checking
In-Reply-To: <871q9n81s1.fsf@kurt.kurt.home>
References: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>
 <ZcTNCxrWTAfj90Es@boxer>
 <871q9n81s1.fsf@kurt.kurt.home>
Message-ID: <ZcTqqwmGTIEq6bfO@boxer>

On Thu, Feb 08, 2024 at 03:32:30PM +0100, Kurt Kanzenbach wrote:
> On Thu Feb 08 2024, Maciej Fijalkowski wrote:
> > On Thu, Feb 08, 2024 at 11:35:25AM +0100, Kurt Kanzenbach wrote:
> >> Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO overflow
> >> interrupts") disabled the RX FIFO overflow interrupts. However, it left the
> >> status variable around, but never checks it.
> >> 
> >> As stmmac_host_mtl_irq_status() returns only 0 now, the code can be
> >> simplified.
> >> 
> >> Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
> >> ---
> >>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++----
> >>  1 file changed, 2 insertions(+), 4 deletions(-)
> >> 
> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> >> index 04d817dc5899..10ce2f272b62 100644
> >> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> >> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> >> @@ -6036,10 +6036,8 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv)
> >>  				priv->tx_path_in_lpi_mode = false;
> >>  		}
> >>  
> >> -		for (queue = 0; queue < queues_count; queue++) {
> >> -			status = stmmac_host_mtl_irq_status(priv, priv->hw,
> >> -							    queue);
> >> -		}
> >> +		for (queue = 0; queue < queues_count; queue++)
> >> +			stmmac_host_mtl_irq_status(priv, priv->hw, queue);
> >
> > Hey Kurt,
> >
> > looks to me that all of the current callbacks just return 0 so why not
> > make them return void instead?
> 
> Well, there are two callbacks of this in dwmac4 and dwxgmac2. Both of
> them still have the code for handling the overflow interrupt (and then
> returning != 0). However, as of commit 8a7cb245cf28 the interrupt
> shouldn't fire. So yes, it could be changed to void along with some
> code removal. But, maybe i'm missing something.

Hmm, ok, my 'quick' glance over the code was too quick :) I missed
overflow encoding to ret within callbacks, sorry. But it seems that even
though they can return nonzero values they would be ignored, correct?

> 
> Thanks,
> Kurt




From a0501179 at ti.com  Thu Feb  8 06:53:27 2024
From: a0501179 at ti.com (Anwar, Md Danish)
Date: Thu, 8 Feb 2024 20:23:27 +0530
Subject: [PATCH net] net: ti: icssg-prueth: Remove duplicate cleanup calls
 in emac_ndo_stop()
In-Reply-To: <20240206152052.98217-1-diogo.ivo@siemens.com>
References: <20240206152052.98217-1-diogo.ivo@siemens.com>
Message-ID: <b4ae0bdf-0763-4cc0-87c3-0b7fd87f6633@ti.com>



On 2/6/2024 8:50 PM, Diogo Ivo wrote:
> Remove the duplicate calls to prueth_emac_stop() and
> prueth_cleanup_tx_chns() in emac_ndo_stop().
> 
> Fixes: 128d5874c082 ("net: ti: icssg-prueth: Add ICSSG ethernet driver")
> Fixes: 186734c15886 ("net: ti: icssg-prueth: add packet timestamping and ptp support")
> Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>

Reviewed-by: MD Danish Anwar <danishanwar at ti.com>

-- 
Thanks and Regards,
Md Danish Anwar


From catalin.marinas at arm.com  Thu Feb  8 06:53:45 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 8 Feb 2024 14:53:45 +0000
Subject: [PATCH v6 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240207204652.22954-5-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-5-ankita@nvidia.com>
Message-ID: <ZcTq-ecgVAP892X2@arm.com>

+ David H

On Thu, Feb 08, 2024 at 02:16:52AM +0530, ankita at nvidia.com wrote:
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> The code to map the MMIO in S2 as NormalNC is enabled when conveyed
> that the device is WC safe using a new flag VM_VFIO_ALLOW_WC.
> 
> Make vfio-pci set the VM_VFIO_ALLOW_WC flag.
> 
> This could be extended to other devices in the future once that
> is deemed safe.
> 
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Acked-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/vfio/pci/vfio_pci_core.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 1cbc990d42e0..c3f95ec7fc3a 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -1863,7 +1863,8 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
>  	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
>  	 * change vm_flags within the fault handler.  Set them now.
>  	 */
> -	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
> +	vm_flags_set(vma, VM_VFIO_ALLOW_WC | VM_IO | VM_PFNMAP |
> +			VM_DONTEXPAND | VM_DONTDUMP);
>  	vma->vm_ops = &vfio_pci_mmap_ops;
>  
>  	return 0;

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From supvenka at amd.com  Thu Feb  8 06:57:16 2024
From: supvenka at amd.com (Supreeth Venkatesh)
Date: Thu, 8 Feb 2024 08:57:16 -0600
Subject: [PATCH 1/1] ARM:dts:aspeed: Initial device tree for AMD Onyx
 Platform
In-Reply-To: <20240110033543.799919-1-supreeth.venkatesh@amd.com>
References: <20240110033543.799919-1-supreeth.venkatesh@amd.com>
Message-ID: <d4fe8b55-a1ea-4ce7-89ac-ce17e8ff4e45@amd.com>

This patch is pending for a month now.

Can DT maintainers please help review this and provide feedback?

On 1/9/24 21:35, Supreeth Venkatesh wrote:
> This patch adds initial device tree and makefile updates for
> AMD Onyx platform.
>
> AMD Onyx platform is an AMD customer reference board with an Aspeed
> ast2600 BMC manufactured by AMD.
> It describes I2c devices, Fans, Kcs devices, Uarts, Mac, LEDs, etc.
> present on AMD Onyx platform.
>
> Signed-off-by: Supreeth Venkatesh <supreeth.venkatesh at amd.com>
> ---
>   arch/arm/boot/dts/aspeed/Makefile             |  1 +
>   .../boot/dts/aspeed/aspeed-bmc-amd-onyx.dts   | 98 +++++++++++++++++++
>   2 files changed, 99 insertions(+)
>   create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts
>
> diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
> index fb9cc95f1b60..2b27d377aae2 100644
> --- a/arch/arm/boot/dts/aspeed/Makefile
> +++ b/arch/arm/boot/dts/aspeed/Makefile
> @@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
>   	aspeed-ast2600-evb.dtb \
>   	aspeed-bmc-amd-daytonax.dtb \
>   	aspeed-bmc-amd-ethanolx.dtb \
> +	aspeed-bmc-amd-onyx.dtb \
>   	aspeed-bmc-ampere-mtjade.dtb \
>   	aspeed-bmc-ampere-mtmitchell.dtb \
>   	aspeed-bmc-arm-stardragon4800-rep2.dtb \
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts
> new file mode 100644
> index 000000000000..a7056cd29553
> --- /dev/null
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts
> @@ -0,0 +1,98 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +// Copyright (c) 2021 - 2024 AMD Inc.
> +// Author: Supreeth Venkatesh <supreeth.venkatesh at amd.com>
> +
> +/dts-v1/;
> +
> +#include "aspeed-g6.dtsi"
> +#include <dt-bindings/gpio/aspeed-gpio.h>
> +
> +/ {
> +       model = "AMD Onyx BMC";
> +       compatible = "amd,onyx-bmc", "aspeed,ast2600";
> +
> +       aliases {
> +               serial0 = &uart1;
> +               serial4 = &uart5;
> +      };
> +
> +       chosen {
> +               stdout-path = &uart5;
> +               bootargs = "console=ttyS4,115200 earlyprintk vmalloc=512MB";
> +       };
> +
> +       memory at 80000000 {
> +               device_type = "memory";
> +               reg = <0x80000000 0x80000000>;
> +       };
> +
> +};
> +
> +&mdio0 {
> +       status = "okay";
> +
> +       ethphy0: ethernet-phy at 0 {
> +               compatible = "ethernet-phy-ieee802.3-c22";
> +               reg = <0>;
> +       };
> +};
> +
> +&mac3 {
> +       status = "okay";
> +       phy-mode = "rgmii";
> +       phy-handle = <&ethphy0>;
> +
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pinctrl_rgmii4_default>;
> +};
> +
> +
> +
> +&fmc {
> +       status = "okay";
> +       flash at 0 {
> +               compatible = "jedec,spi-nor";
> +               status = "okay";
> +               #include "openbmc-flash-layout-128.dtsi"
> +       };
> +};
> +
> +//Host Console
> +&uart1 {
> +       status = "okay";
> +};
> +
> +//BMC Console
> +&uart5 {
> +       status = "okay";
> +};
> +
> +&gpio0 {
> +        gpio-line-names =
> +        /*A0-A7*/       "","","","","","","","",
> +        /*B0-B7*/       "","","","","MON_POST_COMPLETE","P0_PRESENT_L","","",
> +        /*C0-C7*/       "","","","","","","","",
> +        /*D0-D7*/       "","","","","","","","",
> +        /*E0-E7*/       "","","","","","","","",
> +        /*F0-F7*/       "","","","","","","","",
> +        /*G0-G7*/       "","","","","","","","",
> +        /*H0-H7*/       "","ASSERT_WARM_RST_BTN_L","ASSERT_SOC_RST_BTN_L","","","","","",
> +        /*I0-I7*/       "","","","","","","","P0_I3C_APML_ALERT_L",
> +        /*J0-J7*/       "","","","","","","","",
> +        /*K0-K7*/       "","","","","","","","",
> +        /*L0-L7*/       "","","","","","","","",
> +        /*M0-M7*/       "","","","","","","","",
> +        /*N0-N7*/       "","","","","","","PSP_SOFT_FUSE_NOTIFY","ASSERT_BMC_READY",
> +        /*O0-O7*/       "","","HDT_SEL","HDT_XTRIG5","HDT_XTRIG6","JTAG_TRST_N","","",
> +        /*P0-P7*/       "MON_RST_BTN_L","ASSERT_RST_BTN_L","MON_PWR_BTN_L","ASSERT_PWR_BTN_L","HPM_FPGA_LOCKOUT","ASSERT_NMI_BTN_L","MON_PWR_GOOD","",
> +        /*Q0-Q7*/       "","","HDT_DBREQ_L","","BIOS_SPD_MUX_CTRL_RELEASED_L","","","",
> +        /*R0-R7*/       "","","","","","","","",
> +        /*S0-S7*/       "","","","","","","P0_DIMM_AF_ERROR","P0_DIMM_GL_ERROR",
> +        /*T0-T7*/       "","","","","","","","",
> +        /*U0-U7*/       "","","","","","","","",
> +        /*V0-V7*/       "","","","","","","","",
> +        /*W0-W7*/       "","","","","","","","",
> +        /*X0-X7*/       "","","","","","","","",
> +        /*Y0-Y7*/       "","","","","","","","",
> +        /*Z0-Z7*/       "","","","","","","","";
> +};


From mark.rutland at arm.com  Thu Feb  8 06:59:16 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu,  8 Feb 2024 14:59:16 +0000
Subject: [PATCH] arm64: kretprobes: acquire the regs via a BRK exception
Message-ID: <20240208145916.2004154-1-mark.rutland@arm.com>

On arm64, kprobes always take an exception and so create a struct
pt_regs through the usual exception entry logic. Similarly kretprobes
taskes and exception for function entry, but for function returns it
uses a trampoline which attempts to create a struct pt_regs without
taking an exception.

This is problematic for a few reasons, including:

1) The kretprobes trampoline neither saves nor restores all of the
   portions of PSTATE. Before invoking the handler it saves a number of
   portions of PSTATE, and after returning from the handler it restores
   NZCV before returning to the original return address provided by the
   handler.

2) The kretprobe trampoline constructs the PSTATE value piecemeal from
   special purpose registers as it cannot read all of PSTATE atomically
   without taking an exception. This is somewhat fragile, and it's not
   possible to reliably recover PSTATE information which only exists on
   some physical CPUs (e.g. when SSBS support is mismatched).

   Today the kretprobes trampoline does not record:

   - BTYPE
   - SSBS
   - ALLINT
   - SS
   - PAN
   - UAO
   - DIT
   - TCO

   ... and this will only get worse with future architecture extensions
   which add more PSTATE bits.

3) The kretprobes trampoline doesn't store portions of struct pt_regs
   (e.g. the PMR value when using pseudo-NMIs). Due to this, helpers
   which operate on a struct pt_regs, such as interrupts_enabled(), may
   not work correctly.

4) The function entry and function exit handlers run in different
   contexts. The entry handler will always be run in a debug exception
   context (which is currently treated as an NMI), but the return will
   be treated as whatever context the instrumented function was executed
   in. The differences between these contexts are liable to cause
   problems (e.g. as the two can be differently interruptible or
   preemptible, adversely affecting synchronization between the
   handlers).

5) As the kretprobes trampoline runs in the same context as the code
   being probed, it is subject to the same single-stepping context,
   which may not be desirable if this is being driven by the kprobes
   handlers.

Overall, this is fragile, painful to maintain, and gets in the way of
supporting other things (e.g. RELIABLE_STACKTRACE, FEAT_NMI).

This patch addresses these issues by replacing the kretprobes trampoline
with a `BRK` instruction, and using an exception boundary to acquire and
restore the regs, in the same way as the regular kprobes trampoline.

Ive tested this atop v6.8-rc3:

| KTAP version 1
| 1..1
|     KTAP version 1
|     # Subtest: kprobes_test
|     # module: test_kprobes
|     1..7
|     ok 1 test_kprobe
|     ok 2 test_kprobes
|     ok 3 test_kprobe_missed
|     ok 4 test_kretprobe
|     ok 5 test_kretprobes
|     ok 6 test_stacktrace_on_kretprobe
|     ok 7 test_stacktrace_on_nested_kretprobe
| # kprobes_test: pass:7 fail:0 skip:0 total:7
| # Totals: pass:7 fail:0 skip:0 total:7
| ok 1 kprobes_test

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Florent Revest <revest at chromium.org>
Cc: Masami Hiramatsu <mhiramat at kernel.org>
Cc: Steven Rostedt <rostedt at goodmis.org>
---
 arch/arm64/include/asm/brk-imm.h              |  2 +
 arch/arm64/kernel/probes/kprobes.c            | 21 +++--
 arch/arm64/kernel/probes/kprobes_trampoline.S | 78 ++-----------------
 3 files changed, 24 insertions(+), 77 deletions(-)

diff --git a/arch/arm64/include/asm/brk-imm.h b/arch/arm64/include/asm/brk-imm.h
index 1abdcd508a113..beb42c62b6acc 100644
--- a/arch/arm64/include/asm/brk-imm.h
+++ b/arch/arm64/include/asm/brk-imm.h
@@ -11,6 +11,7 @@
  * 0x004: for installing kprobes
  * 0x005: for installing uprobes
  * 0x006: for kprobe software single-step
+ * 0x007: for kretprobe return
  * Allowed values for kgdb are 0x400 - 0x7ff
  * 0x100: for triggering a fault on purpose (reserved)
  * 0x400: for dynamic BRK instruction
@@ -23,6 +24,7 @@
 #define KPROBES_BRK_IMM			0x004
 #define UPROBES_BRK_IMM			0x005
 #define KPROBES_BRK_SS_IMM		0x006
+#define KRETPROBES_BRK_IMM		0x007
 #define FAULT_BRK_IMM			0x100
 #define KGDB_DYN_DBG_BRK_IMM		0x400
 #define KGDB_COMPILED_DBG_BRK_IMM	0x401
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
index 70b91a8c6bb3f..327855a11df2f 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -371,6 +371,21 @@ static struct break_hook kprobes_break_ss_hook = {
 	.fn = kprobe_breakpoint_ss_handler,
 };
 
+static int __kprobes
+kretprobe_breakpoint_handler(struct pt_regs *regs, unsigned long esr)
+{
+	if (regs->pc != (unsigned long)__kretprobe_trampoline)
+		return DBG_HOOK_ERROR;
+
+	regs->pc = kretprobe_trampoline_handler(regs, (void *)regs->regs[29]);
+	return DBG_HOOK_HANDLED;
+}
+
+static struct break_hook kretprobes_break_hook = {
+	.imm = KRETPROBES_BRK_IMM,
+	.fn = kretprobe_breakpoint_handler,
+};
+
 /*
  * Provide a blacklist of symbols identifying ranges which cannot be kprobed.
  * This blacklist is exposed to userspace via debugfs (kprobes/blacklist).
@@ -396,11 +411,6 @@ int __init arch_populate_kprobe_blacklist(void)
 	return ret;
 }
 
-void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
-{
-	return (void *)kretprobe_trampoline_handler(regs, (void *)regs->regs[29]);
-}
-
 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
 				      struct pt_regs *regs)
 {
@@ -420,6 +430,7 @@ int __init arch_init_kprobes(void)
 {
 	register_kernel_break_hook(&kprobes_break_hook);
 	register_kernel_break_hook(&kprobes_break_ss_hook);
+	register_kernel_break_hook(&kretprobes_break_hook);
 
 	return 0;
 }
diff --git a/arch/arm64/kernel/probes/kprobes_trampoline.S b/arch/arm64/kernel/probes/kprobes_trampoline.S
index 9a6499bed58b0..a362f3dbb3d11 100644
--- a/arch/arm64/kernel/probes/kprobes_trampoline.S
+++ b/arch/arm64/kernel/probes/kprobes_trampoline.S
@@ -4,83 +4,17 @@
  */
 
 #include <linux/linkage.h>
-#include <asm/asm-offsets.h>
+#include <asm/asm-bug.h>
 #include <asm/assembler.h>
 
 	.text
 
-	.macro	save_all_base_regs
-	stp x0, x1, [sp, #S_X0]
-	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 x0, sp, #PT_REGS_SIZE
-	stp lr, x0, [sp, #S_LR]
-	/*
-	 * Construct a useful saved PSTATE
-	 */
-	mrs x0, nzcv
-	mrs x1, daif
-	orr x0, x0, x1
-	mrs x1, CurrentEL
-	orr x0, x0, x1
-	mrs x1, SPSel
-	orr x0, x0, x1
-	stp xzr, x0, [sp, #S_PC]
-	.endm
-
-	.macro	restore_all_base_regs
-	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]
-	.endm
-
 SYM_CODE_START(__kretprobe_trampoline)
-	sub sp, sp, #PT_REGS_SIZE
-
-	save_all_base_regs
-
-	/* Setup a frame pointer. */
-	add x29, sp, #S_FP
-
-	mov x0, sp
-	bl trampoline_probe_handler
 	/*
-	 * Replace trampoline address in lr with actual orig_ret_addr return
-	 * address.
+	 * Trigger a breakpoint exception. The PC will be adjusted by
+	 * kretprobe_breakpoint_handler(), and no subsequent instructions will
+	 * be executed from the trampoline.
 	 */
-	mov lr, x0
-
-	/* The frame pointer (x29) is restored with other registers. */
-	restore_all_base_regs
-
-	add sp, sp, #PT_REGS_SIZE
-	ret
-
+	brk #KRETPROBES_BRK_IMM
+	ASM_BUG()
 SYM_CODE_END(__kretprobe_trampoline)
-- 
2.30.2



From kurt at linutronix.de  Thu Feb  8 07:08:00 2024
From: kurt at linutronix.de (Kurt Kanzenbach)
Date: Thu, 08 Feb 2024 16:08:00 +0100
Subject: [PATCH net-next] net: stmmac: Simplify mtl IRQ status checking
In-Reply-To: <ZcTqqwmGTIEq6bfO@boxer>
References: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>
 <ZcTNCxrWTAfj90Es@boxer> <871q9n81s1.fsf@kurt.kurt.home>
 <ZcTqqwmGTIEq6bfO@boxer>
Message-ID: <87y1bv6lkf.fsf@kurt.kurt.home>

On Thu Feb 08 2024, Maciej Fijalkowski wrote:
> On Thu, Feb 08, 2024 at 03:32:30PM +0100, Kurt Kanzenbach wrote:
>> On Thu Feb 08 2024, Maciej Fijalkowski wrote:
>> > On Thu, Feb 08, 2024 at 11:35:25AM +0100, Kurt Kanzenbach wrote:
>> >> Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO overflow
>> >> interrupts") disabled the RX FIFO overflow interrupts. However, it left the
>> >> status variable around, but never checks it.
>> >> 
>> >> As stmmac_host_mtl_irq_status() returns only 0 now, the code can be
>> >> simplified.
>> >> 
>> >> Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
>> >> ---
>> >>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++----
>> >>  1 file changed, 2 insertions(+), 4 deletions(-)
>> >> 
>> >> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> >> index 04d817dc5899..10ce2f272b62 100644
>> >> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> >> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> >> @@ -6036,10 +6036,8 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv)
>> >>  				priv->tx_path_in_lpi_mode = false;
>> >>  		}
>> >>  
>> >> -		for (queue = 0; queue < queues_count; queue++) {
>> >> -			status = stmmac_host_mtl_irq_status(priv, priv->hw,
>> >> -							    queue);
>> >> -		}
>> >> +		for (queue = 0; queue < queues_count; queue++)
>> >> +			stmmac_host_mtl_irq_status(priv, priv->hw, queue);
>> >
>> > Hey Kurt,
>> >
>> > looks to me that all of the current callbacks just return 0 so why not
>> > make them return void instead?
>> 
>> Well, there are two callbacks of this in dwmac4 and dwxgmac2. Both of
>> them still have the code for handling the overflow interrupt (and then
>> returning != 0). However, as of commit 8a7cb245cf28 the interrupt
>> shouldn't fire. So yes, it could be changed to void along with some
>> code removal. But, maybe i'm missing something.
>
> Hmm, ok, my 'quick' glance over the code was too quick :) I missed
> overflow encoding to ret within callbacks, sorry. But it seems that even
> though they can return nonzero values they would be ignored, correct?

Yeah, they are ignored.

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

From andrew at lunn.ch  Thu Feb  8 07:08:51 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Thu, 8 Feb 2024 16:08:51 +0100
Subject: [PATCH v2] arm64: dts: armada-ap807: update thermal compatible
In-Reply-To: <20240208081413.7923-1-eichest@gmail.com>
References: <20240208081413.7923-1-eichest@gmail.com>
Message-ID: <249b89ef-f520-4828-a575-471d805f8434@lunn.ch>

On Thu, Feb 08, 2024 at 09:14:13AM +0100, Stefan Eichenberger wrote:
> From: Alex Leibovich <alexl at marvell.com>
> 
> Use the correct thermal coefficients for the Armada AP807 dies.
> 
> Signed-off-by: Alex Leibovich <alexl at marvell.com>
> Reviewed-by: Stefan Chulski <stefanc at marvell.com>
> Tested-by: Stefan Chulski <stefanc at marvell.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Signed-off-by: Stefan Eichenberger <eichest at gmail.com>

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

    Andrew


From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 07:18:31 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 8 Feb 2024 15:18:31 +0000
Subject: [RFC PATCH v2 1/7] KVM: Add generic infrastructure to support pinned VMIDs
In-Reply-To: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208151837.35068-2-shameerali.kolothum.thodi@huawei.com>

Provide generic helper functions to get/put pinned VMIDs if the arch
supports it.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 include/linux/kvm_host.h | 18 ++++++++++++++++++
 virt/kvm/Kconfig         |  3 +++
 virt/kvm/kvm_main.c      | 23 +++++++++++++++++++++++
 3 files changed, 44 insertions(+)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 7e7fd25b09b3..610e239bea46 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -2311,6 +2311,24 @@ static inline void kvm_handle_signal_exit(struct kvm_vcpu *vcpu)
 }
 #endif /* CONFIG_KVM_XFER_TO_GUEST_WORK */
 
+#ifdef CONFIG_HAVE_KVM_PINNED_VMID
+int kvm_arch_pinned_vmid_get(struct kvm *kvm);
+void kvm_arch_pinned_vmid_put(struct kvm *kvm);
+#endif
+
+#ifdef CONFIG_HAVE_KVM_PINNED_VMID
+int kvm_pinned_vmid_get(struct kvm *kvm);
+void kvm_pinned_vmid_put(struct kvm *kvm);
+#else
+static inline int kvm_pinned_vmid_get(struct kvm *kvm)
+{
+	return -EINVAL;
+}
+
+static inline void kvm_pinned_vmid_put(struct kvm *kvm)
+{
+}
+#endif
 /*
  * If more than one page is being (un)accounted, @virt must be the address of
  * the first page of a block of pages what were allocated together (i.e
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index 184dab4ee871..a3052c8e3ac4 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -108,3 +108,6 @@ config KVM_GENERIC_PRIVATE_MEM
        select KVM_GENERIC_MEMORY_ATTRIBUTES
        select KVM_PRIVATE_MEM
        bool
+
+config HAVE_KVM_PINNED_VMID
+       bool
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 10bfc88a69f7..f84d6da5f464 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3918,6 +3918,29 @@ bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu)
 }
 EXPORT_SYMBOL_GPL(kvm_vcpu_wake_up);
 
+#ifdef CONFIG_HAVE_KVM_PINNED_VMID
+int kvm_pinned_vmid_get(struct kvm *kvm)
+{
+	int ret;
+
+	if (!kvm_get_kvm_safe(kvm))
+		return -ENOENT;
+	ret  = kvm_arch_pinned_vmid_get(kvm);
+	if (ret < 0)
+		kvm_put_kvm(kvm);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(kvm_pinned_vmid_get);
+
+void kvm_pinned_vmid_put(struct kvm *kvm)
+{
+	kvm_arch_pinned_vmid_put(kvm);
+	kvm_put_kvm(kvm);
+}
+EXPORT_SYMBOL_GPL(kvm_pinned_vmid_put);
+#endif
+
 #ifndef CONFIG_S390
 /*
  * Kick a sleeping VCPU, or a guest VCPU in guest mode, into host kernel mode.
-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 07:18:30 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 8 Feb 2024 15:18:30 +0000
Subject: [RFC PATCH v2 0/7] iommu/arm-smmu-v3: Use pinned KVM VMID for stage 2
Message-ID: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>

Hi,

On an ARM64 system with a SMMUv3 implementation that fully supports
Broadcast TLB Maintenance(BTM) feature as part of the Distributed
Virtual Memory(DVM) protocol, the CPU TLB invalidate instructions are
received by SMMUv3. This is very useful when the SMMUv3 shares the
page tables with the CPU(eg: Guest SVA use case). For this to work,
the SMMUv3 must use the same VMID that is allocated by KVM to configure
the nested stage 2(S2) translations.

An earlier proposal sent out[1] a while back resulted in changing the
ARM64/KVM VMID allocator similar to the ASID allocator to make it
better suited for this.

This RFC adds,
 -Support for pinned KVM VMID.
 -Support associating KVM pointer and iommufd ctx.
 -Changes to domain_alloc_user() to receive a kvm pointer.
 -Configure SMMUV3 S2 using KVM VMID
 -Finally enable BTM only if SMMUV3 supports S1 translation. This
  is to make sure that PAGING domains always use S1 and S2 is only
  used for nested domains with a valid KVM. The idea is to make sure
  when BTM is enabled in Guest, we use KVM VMID for S2.

Not sure I miss any explicit TLB invalidations with any use case
that may configure a S2 with a private VMID that matches a KVM
one.

This is based on Jason's ongoing SMMUv3 refactor series[2].

Please take a look and let me know.

Thanks,
Shameer

1. https://lore.kernel.org/linux-arm-kernel/20210222155338.26132-1-shameerali.kolothum.thodi at huawei.com/
2. https://lore.kernel.org/linux-arm-kernel/0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg at nvidia.com/

Jean-Philippe Brucker (1):
  iommu/arm-smmu-v3: Enable broadcast TLB maintenance

Shameer Kolothum (6):
  KVM: Add generic infrastructure to support pinned VMIDs
  KVM: arm64: Introduce support to pin VMIDs
  KVM: arm64: Add interfaces for pinned VMID support
  iommufd: Associate kvm pointer to iommufd ctx
  iommu: Pass in kvm pointer to domain_alloc_user
  iommu/arm-smmu-v3: Use KVM VMID for s2 stage

 arch/arm64/include/asm/kvm_host.h           |  3 +
 arch/arm64/kvm/Kconfig                      |  1 +
 arch/arm64/kvm/arm.c                        | 14 ++++
 arch/arm64/kvm/vmid.c                       | 84 ++++++++++++++++++++-
 drivers/iommu/amd/iommu.c                   |  1 +
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 42 +++++++++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  3 +
 drivers/iommu/intel/iommu.c                 |  1 +
 drivers/iommu/iommufd/hw_pagetable.c        |  5 +-
 drivers/iommu/iommufd/iommufd_private.h     |  3 +
 drivers/iommu/iommufd/main.c                | 14 ++++
 drivers/iommu/iommufd/selftest.c            |  1 +
 drivers/vfio/device_cdev.c                  |  3 +
 include/linux/iommu.h                       |  3 +-
 include/linux/iommufd.h                     |  7 ++
 include/linux/kvm_host.h                    | 18 +++++
 virt/kvm/Kconfig                            |  3 +
 virt/kvm/kvm_main.c                         | 23 ++++++
 18 files changed, 218 insertions(+), 11 deletions(-)

-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 07:18:32 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 8 Feb 2024 15:18:32 +0000
Subject: [RFC PATCH v2 2/7] KVM: arm64: Introduce support to pin VMIDs
In-Reply-To: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208151837.35068-3-shameerali.kolothum.thodi@huawei.com>

Introduce kvm_arm_pinned_vmid_get() and kvm_arm_pinned_vmid_put(), to pin
a VMID associated with a KVM instance. This will guarantee that VMID
remains the same after a rollover.

This is in preparation of introducing support in the SMMUv3 driver to use
the KVM VMID for S2 stage configuration in nested mode.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 arch/arm64/include/asm/kvm_host.h |  3 ++
 arch/arm64/kvm/vmid.c             | 84 ++++++++++++++++++++++++++++++-
 2 files changed, 86 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 21c57b812569..20fb00d29f48 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -141,6 +141,7 @@ int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages);
 
 struct kvm_vmid {
 	atomic64_t id;
+	refcount_t pinned;
 };
 
 struct kvm_s2_mmu {
@@ -1097,6 +1098,8 @@ int __init kvm_arm_vmid_alloc_init(void);
 void __init kvm_arm_vmid_alloc_free(void);
 bool kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid);
 void kvm_arm_vmid_clear_active(void);
+unsigned long kvm_arm_pinned_vmid_get(struct kvm_vmid *kvm_vmid);
+void kvm_arm_pinned_vmid_put(struct kvm_vmid *kvm_vmid);
 
 static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch *vcpu_arch)
 {
diff --git a/arch/arm64/kvm/vmid.c b/arch/arm64/kvm/vmid.c
index 806223b7022a..0ffe24683071 100644
--- a/arch/arm64/kvm/vmid.c
+++ b/arch/arm64/kvm/vmid.c
@@ -25,6 +25,10 @@ static unsigned long *vmid_map;
 static DEFINE_PER_CPU(atomic64_t, active_vmids);
 static DEFINE_PER_CPU(u64, reserved_vmids);
 
+static unsigned long max_pinned_vmids;
+static unsigned long nr_pinned_vmids;
+static unsigned long *pinned_vmid_map;
+
 #define VMID_MASK		(~GENMASK(kvm_arm_vmid_bits - 1, 0))
 #define VMID_FIRST_VERSION	(1UL << kvm_arm_vmid_bits)
 
@@ -47,7 +51,10 @@ static void flush_context(void)
 	int cpu;
 	u64 vmid;
 
-	bitmap_zero(vmid_map, NUM_USER_VMIDS);
+	if (pinned_vmid_map)
+		bitmap_copy(vmid_map, pinned_vmid_map, NUM_USER_VMIDS);
+	else
+		bitmap_zero(vmid_map, NUM_USER_VMIDS);
 
 	for_each_possible_cpu(cpu) {
 		vmid = atomic64_xchg_relaxed(&per_cpu(active_vmids, cpu), 0);
@@ -103,6 +110,14 @@ static u64 new_vmid(struct kvm_vmid *kvm_vmid)
 			return newvmid;
 		}
 
+		/*
+		 * If it is pinned, we can keep using it. Note that reserved
+		 * takes priority, because even if it is also pinned, we need to
+		 * update the generation into the reserved_vmids.
+		 */
+		if (refcount_read(&kvm_vmid->pinned))
+			return newvmid;
+
 		if (!__test_and_set_bit(vmid2idx(vmid), vmid_map)) {
 			atomic64_set(&kvm_vmid->id, newvmid);
 			return newvmid;
@@ -174,6 +189,63 @@ bool kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
 	return updated;
 }
 
+unsigned long kvm_arm_pinned_vmid_get(struct kvm_vmid *kvm_vmid)
+{
+	unsigned long flags;
+	u64 vmid;
+
+	if (!pinned_vmid_map)
+		return 0;
+
+	raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
+
+	vmid = atomic64_read(&kvm_vmid->id);
+
+	if (refcount_inc_not_zero(&kvm_vmid->pinned))
+		goto out_unlock;
+
+	if (nr_pinned_vmids >= max_pinned_vmids) {
+		vmid = 0;
+		goto out_unlock;
+	}
+
+	/*
+	 * If we went through one or more rollover since that VMID was
+	 * used, make sure it is still valid, or generate a new one.
+	 */
+	if (!vmid_gen_match(vmid))
+		vmid = new_vmid(kvm_vmid);
+
+	nr_pinned_vmids++;
+	__set_bit(vmid2idx(vmid), pinned_vmid_map);
+	refcount_set(&kvm_vmid->pinned, 1);
+
+out_unlock:
+	raw_spin_unlock_irqrestore(&cpu_vmid_lock, flags);
+
+	vmid &= ~VMID_MASK;
+
+	return vmid;
+}
+
+void kvm_arm_pinned_vmid_put(struct kvm_vmid *kvm_vmid)
+{
+	unsigned long flags;
+	u64 vmid = atomic64_read(&kvm_vmid->id);
+
+	if (!pinned_vmid_map)
+		return;
+
+	raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
+
+	if (refcount_dec_and_test(&kvm_vmid->pinned)) {
+		__clear_bit(vmid2idx(vmid), pinned_vmid_map);
+		nr_pinned_vmids--;
+	}
+
+	raw_spin_unlock_irqrestore(&cpu_vmid_lock, flags);
+}
+
 /*
  * Initialize the VMID allocator
  */
@@ -191,10 +263,20 @@ int __init kvm_arm_vmid_alloc_init(void)
 	if (!vmid_map)
 		return -ENOMEM;
 
+	pinned_vmid_map = bitmap_zalloc(NUM_USER_VMIDS, GFP_KERNEL);
+	nr_pinned_vmids = 0;
+
+	/*
+	 * Ensure we have at least one emty slot available after rollover
+	 * and maximum number of VMIDs are pinned. VMID#0 is reserved.
+	 */
+	max_pinned_vmids = NUM_USER_VMIDS - num_possible_cpus() - 2;
+
 	return 0;
 }
 
 void __init kvm_arm_vmid_alloc_free(void)
 {
+	bitmap_free(pinned_vmid_map);
 	bitmap_free(vmid_map);
 }
-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 07:18:33 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 8 Feb 2024 15:18:33 +0000
Subject: [RFC PATCH v2 3/7] KVM: arm64: Add interfaces for pinned VMID support
In-Reply-To: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208151837.35068-4-shameerali.kolothum.thodi@huawei.com>

Provide interfaces to get/put pinned VMIDs from KVM VMID allocator.
This will be used by SMMUv3 driver in subsequent patch.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 arch/arm64/kvm/Kconfig |  1 +
 arch/arm64/kvm/arm.c   | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6c3c8ca73e7f..29ff79f112ba 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -40,6 +40,7 @@ menuconfig KVM
 	select SCHED_INFO
 	select GUEST_PERF_EVENTS if PERF_EVENTS
 	select XARRAY_MULTI
+	select HAVE_KVM_PINNED_VMID
 	help
 	  Support hosting virtualized guest machines.
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a25265aca432..ed905da6e9ab 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -711,6 +711,20 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
 	return ret;
 }
 
+int kvm_arch_pinned_vmid_get(struct kvm *kvm)
+{
+	int vmid;
+
+	vmid = kvm_arm_pinned_vmid_get(&kvm->arch.mmu.vmid);
+
+	return (vmid == 0) ? -EINVAL : vmid;
+}
+
+void kvm_arch_pinned_vmid_put(struct kvm *kvm)
+{
+	kvm_arm_pinned_vmid_put(&kvm->arch.mmu.vmid);
+}
+
 bool kvm_arch_intc_initialized(struct kvm *kvm)
 {
 	return vgic_initialized(kvm);
-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 07:18:34 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 8 Feb 2024 15:18:34 +0000
Subject: [RFC PATCH v2 4/7] iommufd: Associate kvm pointer to iommufd ctx
In-Reply-To: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208151837.35068-5-shameerali.kolothum.thodi@huawei.com>

Introduce an API to set the KVM pointer to the iommufd ctx
and set the same when a vfio dev is bind to iommufd.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/iommufd/iommufd_private.h |  3 +++
 drivers/iommu/iommufd/main.c            | 14 ++++++++++++++
 drivers/vfio/device_cdev.c              |  3 +++
 include/linux/iommufd.h                 |  7 +++++++
 4 files changed, 27 insertions(+)

diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index 991f864d1f9b..28ede82bb1a6 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -16,6 +16,7 @@ struct iommu_domain;
 struct iommu_group;
 struct iommu_option;
 struct iommufd_device;
+struct kvm;
 
 struct iommufd_ctx {
 	struct file *file;
@@ -27,6 +28,8 @@ struct iommufd_ctx {
 	/* Compatibility with VFIO no iommu */
 	u8 no_iommu_mode;
 	struct iommufd_ioas *vfio_ioas;
+	/* Associated KVM pointer */
+	struct kvm *kvm;
 };
 
 /*
diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
index 39b32932c61e..28272510fba4 100644
--- a/drivers/iommu/iommufd/main.c
+++ b/drivers/iommu/iommufd/main.c
@@ -495,6 +495,20 @@ void iommufd_ctx_put(struct iommufd_ctx *ictx)
 }
 EXPORT_SYMBOL_NS_GPL(iommufd_ctx_put, IOMMUFD);
 
+/**
+ * iommufd_ctx_set_kvm - Called to set a KVM pointer to iommufd context
+ * @ictx: Context to operate on
+ * @kvm: KVM pointer with a reference taken using kvm_get_kvm_safe()
+ */
+void iommufd_ctx_set_kvm(struct iommufd_ctx *ictx, struct kvm *kvm)
+{
+	xa_lock(&ictx->objects);
+	if (!ictx->kvm)
+		ictx->kvm = kvm;
+	xa_unlock(&ictx->objects);
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_ctx_set_kvm, IOMMUFD);
+
 static const struct iommufd_object_ops iommufd_object_ops[] = {
 	[IOMMUFD_OBJ_ACCESS] = {
 		.destroy = iommufd_access_destroy_object,
diff --git a/drivers/vfio/device_cdev.c b/drivers/vfio/device_cdev.c
index e75da0a70d1f..e75e96fb57cb 100644
--- a/drivers/vfio/device_cdev.c
+++ b/drivers/vfio/device_cdev.c
@@ -101,6 +101,9 @@ long vfio_df_ioctl_bind_iommufd(struct vfio_device_file *df,
 	 */
 	vfio_df_get_kvm_safe(df);
 
+	if (df->kvm)
+		iommufd_ctx_set_kvm(df->iommufd, df->kvm);
+
 	ret = vfio_df_open(df);
 	if (ret)
 		goto out_put_kvm;
diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index ffc3a949f837..7408b620d0b8 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -17,6 +17,7 @@ struct iommufd_ctx;
 struct iommufd_access;
 struct file;
 struct iommu_group;
+struct kvm;
 
 struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx,
 					   struct device *dev, u32 *id);
@@ -59,6 +60,7 @@ struct iommufd_ctx *iommufd_ctx_from_file(struct file *file);
 struct iommufd_ctx *iommufd_ctx_from_fd(int fd);
 void iommufd_ctx_put(struct iommufd_ctx *ictx);
 bool iommufd_ctx_has_group(struct iommufd_ctx *ictx, struct iommu_group *group);
+void iommufd_ctx_set_kvm(struct iommufd_ctx *ictx, struct kvm *kvm);
 
 int iommufd_access_pin_pages(struct iommufd_access *access, unsigned long iova,
 			     unsigned long length, struct page **out_pages,
@@ -80,6 +82,11 @@ static inline void iommufd_ctx_put(struct iommufd_ctx *ictx)
 {
 }
 
+static inline void iommufd_ctx_set_kvm(struct iommufd_ctx *ictx,
+				       struct kvm *kvm)
+{
+}
+
 static inline int iommufd_access_pin_pages(struct iommufd_access *access,
 					   unsigned long iova,
 					   unsigned long length,
-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 07:18:35 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 8 Feb 2024 15:18:35 +0000
Subject: [RFC PATCH v2 5/7] iommu: Pass in kvm pointer to domain_alloc_user
In-Reply-To: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208151837.35068-6-shameerali.kolothum.thodi@huawei.com>

No functional changes.

This will be used in a later patch to add support to use
KVM VMID in ARM SMMUv3 s2 stage configuration.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/amd/iommu.c                   | 1 +
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 +
 drivers/iommu/intel/iommu.c                 | 1 +
 drivers/iommu/iommufd/hw_pagetable.c        | 5 +++--
 drivers/iommu/iommufd/selftest.c            | 1 +
 include/linux/iommu.h                       | 3 ++-
 6 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 4283dd8191f0..75e0f4e9253a 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2244,6 +2244,7 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned int type)
 static struct iommu_domain *
 amd_iommu_domain_alloc_user(struct device *dev, u32 flags,
 			    struct iommu_domain *parent,
+			    struct kvm *kvm,
 			    const struct iommu_user_data *user_data)
 
 {
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 0606166a8781..b41d77787a2f 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3190,6 +3190,7 @@ arm_smmu_domain_alloc_nesting(struct device *dev, u32 flags,
 static struct iommu_domain *
 arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
 			   struct iommu_domain *parent,
+			   struct kvm *kvm,
 			   const struct iommu_user_data *user_data)
 {
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 6fb5f6fceea1..992a2f233198 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -3877,6 +3877,7 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 static struct iommu_domain *
 intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
 			      struct iommu_domain *parent,
+			      struct kvm *kvm,
 			      const struct iommu_user_data *user_data)
 {
 	struct device_domain_info *info = dev_iommu_priv_get(dev);
diff --git a/drivers/iommu/iommufd/hw_pagetable.c b/drivers/iommu/iommufd/hw_pagetable.c
index 3f3f1fa1a0a9..1efc4ef863ac 100644
--- a/drivers/iommu/iommufd/hw_pagetable.c
+++ b/drivers/iommu/iommufd/hw_pagetable.c
@@ -129,7 +129,7 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
 
 	if (ops->domain_alloc_user) {
 		hwpt->domain = ops->domain_alloc_user(idev->dev, flags, NULL,
-						      user_data);
+						      ictx->kvm, user_data);
 		if (IS_ERR(hwpt->domain)) {
 			rc = PTR_ERR(hwpt->domain);
 			hwpt->domain = NULL;
@@ -228,7 +228,8 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
 	hwpt_nested->parent = parent;
 
 	hwpt->domain = ops->domain_alloc_user(idev->dev, flags,
-					      parent->common.domain, user_data);
+					      parent->common.domain,
+					      ictx->kvm, user_data);
 	if (IS_ERR(hwpt->domain)) {
 		rc = PTR_ERR(hwpt->domain);
 		hwpt->domain = NULL;
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index d9e9920c7eba..483bb7216235 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -269,6 +269,7 @@ __mock_domain_alloc_nested(struct mock_iommu_domain *mock_parent,
 static struct iommu_domain *
 mock_domain_alloc_user(struct device *dev, u32 flags,
 		       struct iommu_domain *parent,
+		       struct kvm *kvm,
 		       const struct iommu_user_data *user_data)
 {
 	struct mock_iommu_domain *mock_parent;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 1446e3718642..ad14cdc22863 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -43,6 +43,7 @@ struct notifier_block;
 struct iommu_sva;
 struct iommu_fault_event;
 struct iommu_dma_cookie;
+struct kvm;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ	0x0
@@ -458,7 +459,7 @@ struct iommu_ops {
 	struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
 	struct iommu_domain *(*domain_alloc_user)(
 		struct device *dev, u32 flags, struct iommu_domain *parent,
-		const struct iommu_user_data *user_data);
+		struct kvm *kvm, const struct iommu_user_data *user_data);
 	struct iommu_domain *(*domain_alloc_paging)(struct device *dev);
 	struct iommu_domain *(*domain_alloc_sva)(struct device *dev,
 						 struct mm_struct *mm);
-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 07:18:36 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 8 Feb 2024 15:18:36 +0000
Subject: [RFC PATCH v2 6/7] iommu/arm-smmu-v3: Use KVM VMID for s2 stage
In-Reply-To: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208151837.35068-7-shameerali.kolothum.thodi@huawei.com>

If kvm is available make use of kvm pinned VMID interfaces to
set the s2 stage VMID for nested domains.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 +++++++++++++-----
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  2 ++
 2 files changed, 15 insertions(+), 5 deletions(-)

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 b41d77787a2f..18e3e04b50f4 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/io-pgtable.h>
 #include <linux/iopoll.h>
+#include <linux/kvm_host.h>
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of.h>
@@ -2399,9 +2400,13 @@ int arm_smmu_domain_alloc_id(struct arm_smmu_device *smmu,
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2) {
 		int vmid;
 
-		/* Reserve VMID 0 for stage-2 bypass STEs */
-		vmid = ida_alloc_range(&smmu->vmid_map, 1,
-				       (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
+		if (smmu_domain->kvm) {
+			vmid = kvm_pinned_vmid_get(smmu_domain->kvm);
+		} else {
+			/* Reserve VMID 0 for stage-2 bypass STEs */
+			vmid = ida_alloc_range(&smmu->vmid_map, 1,
+					       (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
+		}
 		if (vmid < 0)
 			return vmid;
 		smmu_domain->vmid = vmid;
@@ -2431,7 +2436,10 @@ void arm_smmu_domain_free_id(struct arm_smmu_domain *smmu_domain)
 	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2 &&
 		   smmu_domain->vmid) {
 		arm_smmu_tlb_inv_all_s2(smmu_domain);
-		ida_free(&smmu->vmid_map, smmu_domain->vmid);
+		if (smmu_domain->kvm)
+			kvm_pinned_vmid_put(smmu_domain->kvm);
+		else
+			ida_free(&smmu->vmid_map, smmu_domain->vmid);
 	}
 }
 
@@ -3217,7 +3225,7 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
 			goto err_free;
 		}
 		smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
-		smmu_domain->nesting_parent = true;
+		smmu_domain->kvm = kvm;
 	}
 
 	smmu_domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 45bcd72fcda4..7d732ea2a6ee 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -758,6 +758,8 @@ struct arm_smmu_domain {
 	struct mmu_notifier		mmu_notifier;
 	bool				btm_invalidation : 1;
 	bool				nesting_parent : 1;
+
+	struct kvm			*kvm;
 };
 
 struct arm_smmu_nested_domain {
-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 07:18:37 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 8 Feb 2024 15:18:37 +0000
Subject: [RFC PATCH v2 7/7] iommu/arm-smmu-v3: Enable broadcast TLB maintenance
In-Reply-To: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208151837.35068-8-shameerali.kolothum.thodi@huawei.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

The SMMUv3 can handle invalidation targeted at TLB entries with shared
ASIDs. If the implementation supports broadcast TLB maintenance, enable it
and keep track of it in a feature bit. The SMMU will then be affected by
inner-shareable TLB invalidations from other agents.

In order to avoid over invalidation with stage-2 translation contexts,
enable BTM only when SMMUv3 supports eiher S1 or both S1 & S2 transaltion
contexts. In this way the default domain will use stage-1 and stage 2 will
be only used for NESTED Domain setup.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
[Shameer: Enable BTM only if S1 is supported]
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 23 +++++++++++++++++++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  1 +
 2 files changed, 22 insertions(+), 2 deletions(-)

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 18e3e04b50f4..f40912de9e9f 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4060,11 +4060,14 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 	writel_relaxed(reg, smmu->base + ARM_SMMU_CR1);
 
 	/* CR2 (random crap) */
-	reg = CR2_PTM | CR2_RECINVSID;
+	reg = CR2_RECINVSID;
 
 	if (smmu->features & ARM_SMMU_FEAT_E2H)
 		reg |= CR2_E2H;
 
+	if (!(smmu->features & ARM_SMMU_FEAT_BTM))
+		reg |= CR2_PTM;
+
 	writel_relaxed(reg, smmu->base + ARM_SMMU_CR2);
 
 	/* Stream table */
@@ -4209,6 +4212,7 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 {
 	u32 reg;
 	bool coherent = smmu->features & ARM_SMMU_FEAT_COHERENCY;
+	bool vhe = cpus_have_cap(ARM64_HAS_VIRT_HOST_EXTN);
 
 	/* IDR0 */
 	reg = readl_relaxed(smmu->base + ARM_SMMU_IDR0);
@@ -4261,7 +4265,7 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 
 	if (reg & IDR0_HYP) {
 		smmu->features |= ARM_SMMU_FEAT_HYP;
-		if (cpus_have_cap(ARM64_HAS_VIRT_HOST_EXTN))
+		if (vhe)
 			smmu->features |= ARM_SMMU_FEAT_E2H;
 	}
 
@@ -4286,6 +4290,21 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 
 	if (reg & IDR0_S2P)
 		smmu->features |= ARM_SMMU_FEAT_TRANS_S2;
+	/*
+	 * If S1 is supported, check we can enable BTM. This means if S2 is available,
+	 * we will use S2 for nested domain only with a KVM VMID. BTM is useful when
+	 * CPU shares the page tables with SMMUv3(eg: vSVA)
+	 */
+	if (reg & IDR0_S1P) {
+		/*
+		 * If the CPU is using VHE, but the SMMU doesn't support it, the SMMU
+		 * will create TLB entries for NH-EL1 world and will miss the
+		 * broadcasted TLB invalidations that target EL2-E2H world. Don't enable
+		 * BTM in that case.
+		 */
+		if (reg & IDR0_BTM && (!vhe || reg & IDR0_HYP))
+			smmu->features |= ARM_SMMU_FEAT_BTM;
+	}
 
 	if (!(reg & (IDR0_S1P | IDR0_S2P))) {
 		dev_err(smmu->dev, "no translation support!\n");
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 7d732ea2a6ee..ff3de784d1be 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -33,6 +33,7 @@
 #define IDR0_ASID16			(1 << 12)
 #define IDR0_ATS			(1 << 10)
 #define IDR0_HYP			(1 << 9)
+#define IDR0_BTM			(1 << 5)
 #define IDR0_COHACC			(1 << 4)
 #define IDR0_TTF			GENMASK(3, 2)
 #define IDR0_TTF_AARCH64		2
-- 
2.34.1



From oliver.upton at linux.dev  Thu Feb  8 07:24:40 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu,  8 Feb 2024 15:24:40 +0000
Subject: [PATCH v4 00/10] arm64: Add support for FEAT_E2H0, or lack thereof
In-Reply-To: <20240122181344.258974-1-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
Message-ID: <170740573023.1221433.14646653483482850488.b4-ty@linux.dev>

On Mon, 22 Jan 2024 18:13:34 +0000, Marc Zyngier wrote:
> Since ARMv8.1, the architecture has grown the VHE feature, which makes
> EL2 a superset of EL1. With ARMv9.5 (and retroactively allowed from
> ARMv8.1), the architecture allows implementations to have VHE as the
> *only* implemented behaviour, meaning that HCR_EL2.E2H can be
> implemented as RES1. As a follow-up, HCR_EL2.NV1 can also be
> implemented as RES0, making the VHE-ness of the architecture
> recursive.
> 
> [...]

Thanks folks for having taken a look at the series. I've pushed it out
to kvmarm/next.

Catalin, as requested here is the shared branch:

  https://git.kernel.org/pub/scm/linux/kernel/git/oupton/linux.git/log/?h=kvm-arm64/feat_e2h0

[01/10] arm64: Add macro to compose a sysreg field value
        https://git.kernel.org/kvmarm/kvmarm/c/53eaeb7fbe27
[02/10] arm64: cpufeatures: Correctly handle signed values
        https://git.kernel.org/kvmarm/kvmarm/c/d9a065914dcc
[03/10] arm64: cpufeature: Correctly display signed override values
        https://git.kernel.org/kvmarm/kvmarm/c/d42bf63fd4db
[04/10] arm64: sysreg: Add layout for ID_AA64MMFR4_EL1
        https://git.kernel.org/kvmarm/kvmarm/c/cfc680bb04c5
[05/10] arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling
        https://git.kernel.org/kvmarm/kvmarm/c/805bb61f8279
[06/10] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0
        https://git.kernel.org/kvmarm/kvmarm/c/da9af5071b25
[07/10] arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is negative
        https://git.kernel.org/kvmarm/kvmarm/c/3944382fa6f2
[08/10] KVM: arm64: Expose ID_AA64MMFR4_EL1 to guests
        https://git.kernel.org/kvmarm/kvmarm/c/c21df6e43f0e
[09/10] KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented
        https://git.kernel.org/kvmarm/kvmarm/c/94f29ab2d801
[10/10] KVM: arm64: Handle Apple M2 as not having HCR_EL2.NV1 implemented
        https://git.kernel.org/kvmarm/kvmarm/c/aade38faca63

--
Best,
Oliver


From jgg at ziepe.ca  Thu Feb  8 07:35:32 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Thu, 8 Feb 2024 11:35:32 -0400
Subject: [RFC PATCH v2 0/7] iommu/arm-smmu-v3: Use pinned KVM VMID for
 stage 2
In-Reply-To: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208153532.GO31743@ziepe.ca>

On Thu, Feb 08, 2024 at 03:18:30PM +0000, Shameer Kolothum wrote:
> Hi,
> 
> On an ARM64 system with a SMMUv3 implementation that fully supports
> Broadcast TLB Maintenance(BTM) feature as part of the Distributed
> Virtual Memory(DVM) protocol, the CPU TLB invalidate instructions are
> received by SMMUv3. This is very useful when the SMMUv3 shares the
> page tables with the CPU(eg: Guest SVA use case). For this to work,
> the SMMUv3 must use the same VMID that is allocated by KVM to configure
> the nested stage 2(S2) translations.

Ah so you are going all the way and looking to enable BTM within a
vSVA environment too?

> An earlier proposal sent out[1] a while back resulted in changing the
> ARM64/KVM VMID allocator similar to the ASID allocator to make it
> better suited for this.
> 
> This RFC adds,
>  -Support for pinned KVM VMID.
>  -Support associating KVM pointer and iommufd ctx.
>  -Changes to domain_alloc_user() to receive a kvm pointer.
>  -Configure SMMUV3 S2 using KVM VMID
>  -Finally enable BTM only if SMMUV3 supports S1 translation. This
>   is to make sure that PAGING domains always use S1 and S2 is only
>   used for nested domains with a valid KVM. The idea is to make sure
>   when BTM is enabled in Guest, we use KVM VMID for S2.
> 
> Not sure I miss any explicit TLB invalidations with any use case
> that may configure a S2 with a private VMID that matches a KVM
> one.
> 
> This is based on Jason's ongoing SMMUv3 refactor series[2].

I'm glad to see this, thank you for finishing the BTM stuff!

If someone is using it I wonder if we need to get a more solid answer
on the races with invalidation an ASID reassign.. I added some notes
in comments in part 2 after I audited all of it.

Jason


From farouk.bouabid at theobroma-systems.com  Thu Feb  8 07:39:55 2024
From: farouk.bouabid at theobroma-systems.com (Farouk Bouabid)
Date: Thu, 08 Feb 2024 16:39:55 +0100
Subject: [PATCH v6 1/2] arm64: dts: rockchip: rk3399-puma-haikou: add rs485
 support on uart2
In-Reply-To: <20240208-dev-rx-enable-v6-0-39e68e17a339@theobroma-systems.com>
References: <20240208-dev-rx-enable-v6-0-39e68e17a339@theobroma-systems.com>
Message-ID: <20240208-dev-rx-enable-v6-1-39e68e17a339@theobroma-systems.com>

A hardware switch can set the rs485 transceiver into half or full duplex
mode.

Switching to the half-duplex mode requires the user to enable em485 on
uart5 using ioctl, DE/RE are both connected to GPIO2_C3 which is the
RTS signal for uart0. Implement GPIO2_C3 as rts-gpios with RTS_ON_SEND
option enabled (default) so that driver mode gets enabled while sending
(RTS high) and receiver mode gets enabled while not sending (RTS low).

In full-duplex mode (em485 is disabled), DE is connected to GPIO2_C3 and
RE is grounded (enabled). Since GPIO2_C3 is implemented as rts-gpios, the
driver mode gets enabled whenever we want to send something and RE is not
affected (always enabled) in this case by the state of RTS.

Signed-off-by: Farouk Bouabid <farouk.bouabid at theobroma-systems.com>
---
 arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
index 18a98c4648ea..2c3984a880af 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
@@ -273,11 +273,12 @@ &u2phy0_host {
 
 &uart0 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+	pinctrl-0 = <&uart0_xfer>;
 	status = "okay";
 };
 
 &uart2 {
+	rts-gpios = <&gpio2 RK_PC3 GPIO_ACTIVE_HIGH>;
 	status = "okay";
 };
 

-- 
2.34.1



From farouk.bouabid at theobroma-systems.com  Thu Feb  8 07:39:54 2024
From: farouk.bouabid at theobroma-systems.com (Farouk Bouabid)
Date: Thu, 08 Feb 2024 16:39:54 +0100
Subject: [PATCH v6 0/2] serial: 8250: Add support for rs485 half/full
 duplex on puma/ringneck-haikou
Message-ID: <20240208-dev-rx-enable-v6-0-39e68e17a339@theobroma-systems.com>

On the boards that we are using (ringneck/puma-haikou) a hardware switch
can set the rs485 transceiver into half or full duplex mode.

In half-duplex mode the DE/RE signal of the rs485 transceiver is not
connected to an RTS signal whose control is already handled in the rs485
emulation (start/stop callbacks), but rather to a gpio. And since enabling
the receiver requires setting this gpio active we need to do that in em485
while receiving and disable it while sending to enable the driver mode.

In full-duplex mode RE is grounded and separated from DE. Meanwhile the
rx-enable gpio remains connected to the DE pin. In this case the
receiver-enable gpio should be disabled to enable driver mode in parallel
to the enabled receiver.

This patch-series adds support for controlling the driver/receiver mode
using rts-gpios.

Changes in v6:
- "rts-gpios" property is used instead of implementing "rs485-rx-enable-gpios"
- "rs485-rx-enable-inactive-when-rs485-disabled" property is no longer
  implemented, since rts-gpios is already controlled outside of the em485
  context
- Link to v5: https://lore.kernel.org/r/20240126-dev-rx-enable-v5-0-5d934eda05ca at theobroma-systems.com

Changes in v5:
- set port->rs485_re_gpio in "serial: 8250: Support separate rs485 rx-enable GPIO"
- Link to v4: https://lore.kernel.org/r/20240126-dev-rx-enable-v4-0-45aaf4d96328 at theobroma-systems.com

Changes in v4:
- define the state of rx-enable gpio when em485 is disabled
- add rs485 half/full duplex support to ringneck/puma-haikou
- use dev_err_probe instead of dev_err if error is -EPROBE_DEFER

Changes from the 2020 submission include:
- external gpio for optional receiver-enable handling
- Link to v3: https://lore.kernel.org/all/20200517215610.2131618-1-heiko at sntech.de/

---
Farouk Bouabid (2):
      arm64: dts: rockchip: rk3399-puma-haikou: add rs485 support on uart2
      arm64: dts: rockchip: px30-ringneck-haikou: add rs485 support on uart5

 arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts | 1 +
 arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts   | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)
---
base-commit: 5ebe731c2a586b379103f736cd498bcca3cf1ea9
change-id: 20240125-dev-rx-enable-d8818dbf7c28

Best regards,
-- 
Farouk Bouabid <farouk.bouabid at theobroma-systems.com>



From farouk.bouabid at theobroma-systems.com  Thu Feb  8 07:39:56 2024
From: farouk.bouabid at theobroma-systems.com (Farouk Bouabid)
Date: Thu, 08 Feb 2024 16:39:56 +0100
Subject: [PATCH v6 2/2] arm64: dts: rockchip: px30-ringneck-haikou: add
 rs485 support on uart5
In-Reply-To: <20240208-dev-rx-enable-v6-0-39e68e17a339@theobroma-systems.com>
References: <20240208-dev-rx-enable-v6-0-39e68e17a339@theobroma-systems.com>
Message-ID: <20240208-dev-rx-enable-v6-2-39e68e17a339@theobroma-systems.com>

A hardware switch can set the rs485 transceiver into half or full duplex
mode.

Switching to the half-duplex mode requires the user to enable em485 on
uart5 using ioctl, DE/RE are both connected to GPIO0_B5 which is the
RTS signal for uart0. Implement GPIO0_B5 as rts-gpios with RTS_ON_SEND
option enabled (default) so that driver mode gets enabled while sending
(RTS high) and receiver mode gets enabled while not sending (RTS low).

In full-duplex mode (em485 is disabled), DE is connected to GPIO0_B5 and
RE is grounded (enabled). Since GPIO0_B5 is implemented as rts-gpios, the
driver mode gets enabled whenever we want to send something and RE is not
affected (always enabled) in this case by the state of RTS.

Signed-off-by: Farouk Bouabid <farouk.bouabid at theobroma-systems.com>
---
 arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts b/arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts
index 16798eb77077..ae398acdcf45 100644
--- a/arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts
+++ b/arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts
@@ -227,6 +227,7 @@ &uart0 {
 
 &uart5 {
 	pinctrl-0 = <&uart5_xfer>;
+	rts-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
 	status = "okay";
 };
 

-- 
2.34.1



From jgg at ziepe.ca  Thu Feb  8 07:42:10 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Thu, 8 Feb 2024 11:42:10 -0400
Subject: [RFC PATCH v2 4/7] iommufd: Associate kvm pointer to iommufd ctx
In-Reply-To: <20240208151837.35068-5-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
 <20240208151837.35068-5-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208154210.GP31743@ziepe.ca>

On Thu, Feb 08, 2024 at 03:18:34PM +0000, Shameer Kolothum wrote:

> diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
> index 991f864d1f9b..28ede82bb1a6 100644
> --- a/drivers/iommu/iommufd/iommufd_private.h
> +++ b/drivers/iommu/iommufd/iommufd_private.h
> @@ -16,6 +16,7 @@ struct iommu_domain;
>  struct iommu_group;
>  struct iommu_option;
>  struct iommufd_device;
> +struct kvm;
>  
>  struct iommufd_ctx {
>  	struct file *file;
> @@ -27,6 +28,8 @@ struct iommufd_ctx {
>  	/* Compatibility with VFIO no iommu */
>  	u8 no_iommu_mode;
>  	struct iommufd_ioas *vfio_ioas;
> +	/* Associated KVM pointer */
> +	struct kvm *kvm;
>  };

Associating the KVM with the entire iommufd is a big hammer, is this
what we want to do?

I know it has to be linked to domain allocation and the coming
"viommu" object, and it is already linked to VFIO.

It means we support one KVM per iommufd (which doesn't seem
unreasonable, but also the first time we've had such a limitation)

The other option would be to pass in the kvm to the individual sub
objects.

Kevin?

Sean would you be OK with this approach considering your other series
to try to make more of this private?

Jason


From jgg at ziepe.ca  Thu Feb  8 07:43:43 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Thu, 8 Feb 2024 11:43:43 -0400
Subject: [RFC PATCH v2 5/7] iommu: Pass in kvm pointer to
 domain_alloc_user
In-Reply-To: <20240208151837.35068-6-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
 <20240208151837.35068-6-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208154343.GQ31743@ziepe.ca>

On Thu, Feb 08, 2024 at 03:18:35PM +0000, Shameer Kolothum wrote:
> diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
> index 4283dd8191f0..75e0f4e9253a 100644
> --- a/drivers/iommu/amd/iommu.c
> +++ b/drivers/iommu/amd/iommu.c
> @@ -2244,6 +2244,7 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned int type)
>  static struct iommu_domain *
>  amd_iommu_domain_alloc_user(struct device *dev, u32 flags,
>  			    struct iommu_domain *parent,
> +			    struct kvm *kvm,
>  			    const struct iommu_user_data *user_data)

It would also be fine to stick this in iommu_user_data - since it is
fully optional to any driver. 

The other parameters are things the drivers must check and do
something with.

Jason


From farouk.bouabid at theobroma-systems.com  Thu Feb  8 07:46:18 2024
From: farouk.bouabid at theobroma-systems.com (Farouk Bouabid)
Date: Thu, 8 Feb 2024 16:46:18 +0100
Subject: [PATCH v5 2/6] serial: 8250: Support separate rs485 rx-enable
 GPIO
In-Reply-To: <3d31b17ffd4a4f02aaaa1b6c33a09009@dh-electronics.com>
References: <20240126-dev-rx-enable-v5-0-5d934eda05ca@theobroma-systems.com>
 <20240126-dev-rx-enable-v5-2-5d934eda05ca@theobroma-systems.com>
 <098216ce-50b3-43e4-ad1a-42228c58b761@gmx.de>
 <37522087-d3ac-4cc7-b11b-c844d36206ba@theobroma-systems.com>
 <3d31b17ffd4a4f02aaaa1b6c33a09009@dh-electronics.com>
Message-ID: <af4d5f3a-b514-47f9-9a8c-54d7bfd565f2@theobroma-systems.com>

Hi Christoph,


On 30.01.24 13:29, Christoph Niedermaier wrote:
> [Einige Personen, die diese Nachricht erhalten haben, erhalten h?ufig keine E-Mails von cniedermaier at dh-electronics.com. Weitere Informationen, warum dies wichtig ist, finden Sie unter https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Farouk Bouabid
> Sent: Monday, January 29, 2024 9:57 AM
>
> Hi,
>
>> On 26.01.24 20:58, Lino Sanfilippo wrote:
>>> [Some people who received this message don't often get email from linosanfilippo at gmx.de. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>>>
>>> Hi,
>>>
>>> On 26.01.24 18:27, Farouk Bouabid wrote:
>>>> From: Heiko Stuebner <heiko.stuebner at cherry.de>
>>>>
>>>> The RE signal is used to control the duplex mode of transmissions,
>>>> aka receiving data while sending in full duplex mode, while stopping
>>>> receiving data in half-duplex mode.
>>>>
>>>> On a number of boards the !RE signal is tied to ground so reception
>>>> is always enabled except if the UART allows disabling the receiver.
>>>> This can be taken advantage of to implement half-duplex mode - like
>>>> done on 8250_bcm2835aux.
>>>>
>>>> Another solution is to tie !RE to RTS always forcing half-duplex mode.
>>>>
>>>> And finally there is the option to control the RE signal separately,
>>>> like done here by introducing a new rs485-specific gpio that can be
>>>> set depending on the RX_DURING_TX setting in the common em485 callbacks.
>>>>
>>> we just added the rx_during_tx_gpio to the serial core.
>>> Why cant you use this GPIO for your purpose?
>>>
>>> Regards,
>>> Lino.
>> What we are trying to implement is a gpio that emulates the RTS signal
>> itself as we do not have a dedicated RTS signal that can be controlled
>> through MCR. The rx during tx state in our case is a fixed state of
>> "NO_RX_WHILE_TX"
> Why can't the property rts-gpios be used here for this purpose?


Yes that indeed serves our purpose. Thank you for the suggestion.


Regards

Farouk

>
>
> Regards
> Christoph


From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 07:49:20 2024
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Thu, 8 Feb 2024 15:49:20 +0000
Subject: [RFC PATCH v2 0/7] iommu/arm-smmu-v3: Use pinned KVM VMID for
 stage 2
In-Reply-To: <20240208153532.GO31743@ziepe.ca>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
 <20240208153532.GO31743@ziepe.ca>
Message-ID: <416d8150d3ce4a67901a3ff7a596e4e8@huawei.com>



> -----Original Message-----
> From: Jason Gunthorpe <jgg at ziepe.ca>
> Sent: Thursday, February 8, 2024 3:36 PM
> To: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Cc: kvmarm at lists.linux.dev; iommu at lists.linux.dev; linux-arm-
> kernel at lists.infradead.org; linuxarm at huawei.com; kevin.tian at intel.com;
> alex.williamson at redhat.com; maz at kernel.org; oliver.upton at linux.dev;
> will at kernel.org; robin.murphy at arm.com; jean-philippe at linaro.org;
> jonathan.cameron at huawei.com
> Subject: Re: [RFC PATCH v2 0/7] iommu/arm-smmu-v3: Use pinned KVM VMID
> for stage 2
> 
> On Thu, Feb 08, 2024 at 03:18:30PM +0000, Shameer Kolothum wrote:
> > Hi,
> >
> > On an ARM64 system with a SMMUv3 implementation that fully supports
> > Broadcast TLB Maintenance(BTM) feature as part of the Distributed
> > Virtual Memory(DVM) protocol, the CPU TLB invalidate instructions are
> > received by SMMUv3. This is very useful when the SMMUv3 shares the
> > page tables with the CPU(eg: Guest SVA use case). For this to work,
> > the SMMUv3 must use the same VMID that is allocated by KVM to configure
> > the nested stage 2(S2) translations.
> 
> Ah so you are going all the way and looking to enable BTM within a
> vSVA environment too?

Yes, eager to get the vSVA support ? Its been ages and tired of rebasing for our
private git for the vSVA cases!.

Also for Host SVA, since we are using S1 now, I don?t think this matters that much.

(I do have some questions on the iommufd based vSVA , but I will come back to it,
once I cleanup my Qemu branch for that.)

> 
> > An earlier proposal sent out[1] a while back resulted in changing the
> > ARM64/KVM VMID allocator similar to the ASID allocator to make it
> > better suited for this.
> >
> > This RFC adds,
> >  -Support for pinned KVM VMID.
> >  -Support associating KVM pointer and iommufd ctx.
> >  -Changes to domain_alloc_user() to receive a kvm pointer.
> >  -Configure SMMUV3 S2 using KVM VMID
> >  -Finally enable BTM only if SMMUV3 supports S1 translation. This
> >   is to make sure that PAGING domains always use S1 and S2 is only
> >   used for nested domains with a valid KVM. The idea is to make sure
> >   when BTM is enabled in Guest, we use KVM VMID for S2.
> >
> > Not sure I miss any explicit TLB invalidations with any use case
> > that may configure a S2 with a private VMID that matches a KVM
> > one.
> >
> > This is based on Jason's ongoing SMMUv3 refactor series[2].
> 
> I'm glad to see this, thank you for finishing the BTM stuff!
> 
> If someone is using it I wonder if we need to get a more solid answer
> on the races with invalidation an ASID reassign.. I added some notes
> in comments in part 2 after I audited all of it.

I saw that one. The main point here is, if we guarantee that BTM is only used
for a nested S2 case and there will be a pinned KVM VMID for that, I am 
not sure we need to worry about any S2 related conflicts in TLBIs.

Thanks,
Shameer

From willy at infradead.org  Thu Feb  8 07:49:32 2024
From: willy at infradead.org (Matthew Wilcox)
Date: Thu, 8 Feb 2024 15:49:32 +0000
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <908066c7-b749-4f95-b006-ce9b5bd1a909@oracle.com>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com>
 <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
 <ZcNnrdlb3fe0kGHK@casper.infradead.org>
 <20240207121125.GA22234@willie-the-truck>
 <ZcOQ-0pzA16AEbct@casper.infradead.org>
 <908066c7-b749-4f95-b006-ce9b5bd1a909@oracle.com>
Message-ID: <ZcT4DH7VE1XLBvVc@casper.infradead.org>

On Wed, Feb 07, 2024 at 06:24:52PM -0800, Jane Chu wrote:
> On 2/7/2024 6:17 AM, Matthew Wilcox wrote:
> > While this array of ~512 pages have been allocated to hugetlbfs, and one
> > would think that there would be no way that there could still be
> > references to them, another CPU can have a pointer to this struct page
> > (eg attempting a speculative page cache reference or
> > get_user_pages_fast()).  That means it will try to call
> > atomic_add_unless(&page->_refcount, 1, 0);
> > 
> > Actually, I wonder if this isn't a problem on x86 too?  Do we need to
> > explicitly go through an RCU grace period before freeing the pages
> > for use by somebody else?
> > 
> Sorry, not sure what I'm missing, please help.

Having written out the analysis, I now think it can't happen on x86,
but let's walk through it because it's non-obvious (and I think it
illustrates what people are afraid of on Arm).

CPU A calls either get_user_pages_fast() or __filemap_get_folio().
Let's do the latter this time.

        folio = filemap_get_entry(mapping, index);
filemap_get_entry:
	rcu_read_lock();
        folio = xas_load(&xas);
        if (!folio_try_get_rcu(folio))
                goto repeat;
        if (unlikely(folio != xas_reload(&xas))) {
                folio_put(folio);
                goto repeat;
        }
folio_try_get_rcu:
	folio_ref_try_add_rcu(folio, 1);
folio_ref_try_add_rcu:
        if (unlikely(!folio_ref_add_unless(folio, count, 0))) {
                /* Either the folio has been freed, or will be freed. */
                return false;
folio_ref_add_unless:
        return page_ref_add_unless(&folio->page, nr, u);
page_ref_add_unless:
	atomic_add_unless(&page->_refcount, nr, u);

A rather deep callchain there, but for our purposes the important part
is: we take the RCU read lock, we look up a folio, we increment its
refcount if it's not zero, then check that looking up this index gets
the same folio; if it doesn't, we decrement the refcount again and retry
the lookup.

For this analysis, we can be preempted at any point after we've got the
folio pointer from xa_load().

> From hugetlb allocation perspective,? one of the scenarios is run time
> hugetlb page allocation (say 2M pages), starting from the buddy allocator
> returns compound pages, then the head page is set to frozen, then the
> folio(compound pages) is put thru the HVO process, one of which is
> vmemmap_split_pmd() in case a vmemmap page is a PMD page.
> 
> Until the HVO process completes, none of the vmemmap represented pages are
> available to any threads, so what are the causes for IRQ threads to access
> their vmemmap pages?

Yup, this sounds like enough, but it's not.  The problem is the person
who's looking up the folio in the pagecache under RCU.  They've got
the folio pointer and have been preempted.  So now what happens to our
victim folio?

Something happens to remove it from the page cache.  Maybe the file is
truncated, perhaps vmscan comes along and kicks it out.  Either way, it's
removed from the xarray and gets its refcount set to 0.  If the lookup
were to continue at this time, everything would be fine because it would
see a refcount of 0 and not increment it (in page_ref_add_unless()).
And this is where my analysis of RCU tends to go wrong, because I only
think of interleaving event A and B.  I don't think about B and then C
happening before A resumes.  But it can!  Let's follow the journey of
this struct page.

Now that it's been removed from the page cache, it's allocated by hugetlb,
as you describe.  And it's one of the tail pages towards the end of
the 512 contiguous struct pages.  That means that we alter vmemmap so
that the pointer to struct page now points to a different struct page
(one of the earlier ones).  Then the original page of vmemmap containing
our lucky struct page is returned to the page allocator.  At this point,
it no longer contains struct pages; it can contain literally anything.

Where my analysis went wrong was that CPU A _no longer has a pointer
to it_.  CPU A has a pointer into vmemmap.  So it will access the
replacement struct page (which definitely has a refcount 0) instead of
the one which has been freed.  I had thought that CPU A would access the
original memory which has now been allocated to someone else.  But no,
it can't because its pointer is virtual, not physical.


---

Now I'm thinking more about this and there's another scenario which I
thought might go wrong, and doesn't.  For 7 of the 512 pages which are
freed, the struct page pointer gathered by CPU A will not point to a
page with a refcount of 0.  Instead it will point to an alias of the
head page with a positive refcount.  For those pages, CPU A will see
folio_try_get_rcu() succeed.  Then it will call xas_reload() and see
the folio isn't there any more, so it will call folio_put() on something
which used to be a folio, and isn't any more.

But folio_put() calls folio_put_testzero() which calls put_page_testzero()
without asserting that the pointer is actually to a folio.
So everything's fine, but really only by coincidence; I don't think
anybody's thought about this scenario before (maybe Muchun has, but I
don't remember it being discussed).


From robh at kernel.org  Thu Feb  8 07:51:31 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 08 Feb 2024 15:51:31 +0000
Subject: [PATCH] dt-bindings: interrupt-controller: Convert Atmel AIC
 to json-schema
In-Reply-To: <20240208092015.263210-1-dharma.b@microchip.com>
References: <20240208092015.263210-1-dharma.b@microchip.com>
Message-ID: <170740748922.3230402.17318224112819715619.robh@kernel.org>


On Thu, 08 Feb 2024 14:50:15 +0530, Dharma Balasubiramani wrote:
> Convert the Atmel AIC binding document to DT schema format using
> json-schema.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> ---
> Note: I get the following warnings on latest kernel but not in 6.7.
> Should I be worried?
> 
> usage: yamllint [-h] [-] [-c CONFIG_FILE | -d CONFIG_DATA] [--list-files] [-f {parsable,standard,colored,github,auto}] [-s] [--no-warnings] [-v] [FILE_OR_DIR [FILE_OR_DIR ...]]
> yamllint: error: one of the arguments FILE_OR_DIR - is required
> 
>  .../interrupt-controller/atmel,aic.txt        | 43 ---------
>  .../interrupt-controller/atmel,aic.yaml       | 88 +++++++++++++++++++
>  2 files changed, 88 insertions(+), 43 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.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/interrupt-controller/atmel,aic.example.dtb: /example-1/dma-controller at ffffec00: failed to match any schema with compatible: ['atmel,at91sam9g45-dma']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240208092015.263210-1-dharma.b at microchip.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From thomas.richard at bootlin.com  Thu Feb  8 07:52:24 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 8 Feb 2024 16:52:24 +0100
Subject: [PATCH v2 02/15] pinctrl: pinctrl-single: move suspend()/resume()
 callbacks to noirq
In-Reply-To: <6hyubhrho6xbki6yxtmqedylc2gpeyj4yu5gtrjrq4nsthcr7g@elfukmqeve2a>
References: <20240102-j7200-pcie-s2r-v2-0-8e4f7d228ec2@bootlin.com>
 <20240102-j7200-pcie-s2r-v2-2-8e4f7d228ec2@bootlin.com>
 <CACRpkdYBnQ6xh2yNsnvquTOq5r7NeDhot6To9myfuNbonKcgzQ@mail.gmail.com>
 <6hyubhrho6xbki6yxtmqedylc2gpeyj4yu5gtrjrq4nsthcr7g@elfukmqeve2a>
Message-ID: <8228b76f-ce15-4335-8a09-08d0d57974b1@bootlin.com>

On 1/29/24 23:49, Andi Shyti wrote:
> Hi Linus,
> 
> On Sat, Jan 27, 2024 at 11:31:11PM +0100, Linus Walleij wrote:
>> On Fri, Jan 26, 2024 at 3:37?PM Thomas Richard
>> <thomas.richard at bootlin.com> wrote:
>>
>>> The goal is to extend the active period of pinctrl.
>>> Some devices may need active pinctrl after suspend() and/or before
>>> resume().
>>> So move suspend()/resume() to suspend_noirq()/resume_noirq() in order to
>>> have active pinctrl until suspend_noirq() (included), and from
>>> resume_noirq() (included).
>>>
>>> The deprecated API has been removed to use the new one (dev_pm_ops struct).
>>>
>>> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
>>
>> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
>>
>> Do you want to merge this as a series or is this something I
>> should just apply?
> 
> there is still a comment from me pending.

Hi Andi,

Based on your comment, for the next iteration, I will move the cleanup
in a dedicated patch.

@Linus, you can apply pinctrl patches once everything is ok for you.

Regards,

-- 
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From hiagofranco at gmail.com  Thu Feb  8 07:58:02 2024
From: hiagofranco at gmail.com (Hiago De Franco)
Date: Thu, 8 Feb 2024 12:58:02 -0300
Subject: MXSFB error: -ENODEV: Cannot connect bridge
Message-ID: <34yzygh3mbwpqr2re7nxmhyxy3s7qmqy4vhxvoyxnoguktriur@z66m7gvpqlia>

Hello all,

while doing some tests with kernel v6.8-rc3 and Colibri iMX7D, we
noticed the following error:

[    0.432547] mxsfb 30730000.lcdif: error -ENODEV: Cannot connect bridge

This was introduced by commit edbbae7fba495284f72f05768696572691231558
("ARM: dts: imx7: add MIPI-DSI support"). This patch is routing the
lcdif to the mipi_dsi_in_lcdif endpoint, however we do not have the DSI
pins available in our edge connector. Instead, we use the parallel RGB
LCD interface directly with, as example, an external LVDS transmitter:

&lcdif {
...
	status = "disabled";

	port {
		lcdif_out: endpoint {
			remote-endpoint = <&lcd_panel_in>;
		};
	};
};

By applying the following patch, the issue is gone and the LVDS works
again:

diff --git a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
index ebf7befcc11e..9c81c6baa2d3 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
@@ -834,16 +834,6 @@ lcdif: lcdif at 30730000 {
 					<&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>;
 				clock-names = "pix", "axi";
 				status = "disabled";
-
-				port {
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					lcdif_out_mipi_dsi: endpoint at 0 {
-						reg = <0>;
-						remote-endpoint = <&mipi_dsi_in_lcdif>;
-					};
-				};
 			};
 
 			mipi_csi: mipi-csi at 30750000 {
@@ -895,22 +885,6 @@ mipi_dsi: dsi at 30760000 {
 				samsung,esc-clock-frequency = <20000000>;
 				samsung,pll-clock-frequency = <24000000>;
 				status = "disabled";
-
-				ports {
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					port at 0 {
-						reg = <0>;
-						#address-cells = <1>;
-						#size-cells = <0>;
-
-						mipi_dsi_in_lcdif: endpoint at 0 {
-							reg = <0>;
-							remote-endpoint = <&lcdif_out_mipi_dsi>;
-						};
-					};
-				};
 			};
 		};

I would like to know your opinion about this patch before sending it,
does it makes sense for you? I understand that routing to endpoint
should be done in the SoM device tree, so we are free to rout other
endpoint without issues.

Regards,
Hiago.


From jgg at ziepe.ca  Thu Feb  8 07:59:15 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Thu, 8 Feb 2024 11:59:15 -0400
Subject: [RFC PATCH v2 6/7] iommu/arm-smmu-v3: Use KVM VMID for s2 stage
In-Reply-To: <20240208151837.35068-7-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
 <20240208151837.35068-7-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240208155915.GR31743@ziepe.ca>

On Thu, Feb 08, 2024 at 03:18:36PM +0000, Shameer Kolothum wrote:
> If kvm is available make use of kvm pinned VMID interfaces to
> set the s2 stage VMID for nested domains.
> 
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 +++++++++++++-----
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  2 ++
>  2 files changed, 15 insertions(+), 5 deletions(-)
> 
> 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 b41d77787a2f..18e3e04b50f4 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -18,6 +18,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/io-pgtable.h>
>  #include <linux/iopoll.h>
> +#include <linux/kvm_host.h>
>  #include <linux/module.h>
>  #include <linux/msi.h>
>  #include <linux/of.h>
> @@ -2399,9 +2400,13 @@ int arm_smmu_domain_alloc_id(struct arm_smmu_device *smmu,
>  	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2) {
>  		int vmid;
>  
> -		/* Reserve VMID 0 for stage-2 bypass STEs */
> -		vmid = ida_alloc_range(&smmu->vmid_map, 1,
> -				       (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
> +		if (smmu_domain->kvm) {
> +			vmid = kvm_pinned_vmid_get(smmu_domain->kvm);
> +		} else {
> +			/* Reserve VMID 0 for stage-2 bypass STEs */
> +			vmid = ida_alloc_range(&smmu->vmid_map, 1,
> +					       (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
> +		}

We cannot allow the two different STEs to be programmed with the same
VMID but different translations, so somehow the two allocators have to
work together.

This is why the SVA BTM code has that complex ASID reassignment logic
so it can get away with two allocators. However ASID also has SMMU HW
ASET support to opt-in to the BTM broadcast.

My suggestion is to avoid two allocators and make iommu instances that
support BTM always use the KVM owned VMID allocator by forbidding a S2
domain from being created with a NULL KVM.

IOW all the DMA API/etc will use S1 domains and the only way to get to
a S2 is to allocate a nesting parent via iommufd - for BTM systems
only.

Since the S2 can't opt-out of the BTM broadcast this means the VMIDs
are cleanly assigned and we never get an issue where the KVM TLBI's
are flushing an unrelated S2.

Jason


From tudor.ambarus at linaro.org  Thu Feb  8 08:01:44 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Thu, 8 Feb 2024 16:01:44 +0000
Subject: [PATCH 11/12] spi: s3c64xx: switch gs101 to new port config data
In-Reply-To: <20240208135045.3728927-12-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
 <20240208135045.3728927-12-tudor.ambarus@linaro.org>
Message-ID: <7dd1567f-1b66-4932-8e6e-fb8e394b796d@linaro.org>



On 2/8/24 13:50, Tudor Ambarus wrote:
> Exynos850 integrates 3 SPI

I should have replaced this with "GS101 integrates 16 SPI", as here I'm
updating gs101.


From jgg at ziepe.ca  Thu Feb  8 08:07:27 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Thu, 8 Feb 2024 12:07:27 -0400
Subject: [RFC PATCH v2 0/7] iommu/arm-smmu-v3: Use pinned KVM VMID for
 stage 2
In-Reply-To: <416d8150d3ce4a67901a3ff7a596e4e8@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
 <20240208153532.GO31743@ziepe.ca>
 <416d8150d3ce4a67901a3ff7a596e4e8@huawei.com>
Message-ID: <20240208160727.GS31743@ziepe.ca>

On Thu, Feb 08, 2024 at 03:49:20PM +0000, Shameerali Kolothum Thodi wrote:
> > On Thu, Feb 08, 2024 at 03:18:30PM +0000, Shameer Kolothum wrote:
> > > Hi,
> > >
> > > On an ARM64 system with a SMMUv3 implementation that fully supports
> > > Broadcast TLB Maintenance(BTM) feature as part of the Distributed
> > > Virtual Memory(DVM) protocol, the CPU TLB invalidate instructions are
> > > received by SMMUv3. This is very useful when the SMMUv3 shares the
> > > page tables with the CPU(eg: Guest SVA use case). For this to work,
> > > the SMMUv3 must use the same VMID that is allocated by KVM to configure
> > > the nested stage 2(S2) translations.
> > 
> > Ah so you are going all the way and looking to enable BTM within a
> > vSVA environment too?
> 
> Yes, eager to get the vSVA support ? Its been ages and tired of rebasing for our
> private git for the vSVA cases!.
> 
> Also for Host SVA, since we are using S1 now, I don?t think this matters that much.
> 
> (I do have some questions on the iommufd based vSVA , but I will come back to it,
> once I cleanup my Qemu branch for that.)

Oh, I think I left a comment someplace that you also need to signal to the
VMM that the kernel supports vBTM, probably via new flag in the
iommu_hw_info_arm_smmuv3

+ *
+ * Note that these values reflect the raw HW capability, without any insight if
+ * any required kernel driver support is present. Bits may be set indicating the
+ * HW has functionality that is lacking kernel software support, such as BTM. If
+ * a VMM is using this information to construct emulated copies of these
+ * registers it should only forward bits that it knows it can support.
+ *
+ * In future, presence of required kernel support will be indicated in flags.
+ */

> > If someone is using it I wonder if we need to get a more solid answer
> > on the races with invalidation an ASID reassign.. I added some notes
> > in comments in part 2 after I audited all of it.
> 
> I saw that one. The main point here is, if we guarantee that BTM is only used
> for a nested S2 case and there will be a pinned KVM VMID for that, I am 
> not sure we need to worry about any S2 related conflicts in TLBIs.

Sure for the S2, aside my other note, but my remark here was about the
S1 ASID reassign logic. I was sort of OK to leave it as it was under
the idea that BTM support wasn't turned on.

I'm concerned it is another iommufd triggerable security problem..

Jason


From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 08:14:07 2024
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Thu, 8 Feb 2024 16:14:07 +0000
Subject: [RFC PATCH v2 6/7] iommu/arm-smmu-v3: Use KVM VMID for s2 stage
In-Reply-To: <20240208155915.GR31743@ziepe.ca>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
 <20240208151837.35068-7-shameerali.kolothum.thodi@huawei.com>
 <20240208155915.GR31743@ziepe.ca>
Message-ID: <8bfca4c5bfe7424691efdae0f686ece4@huawei.com>



> -----Original Message-----
> From: Jason Gunthorpe <jgg at ziepe.ca>
> Sent: Thursday, February 8, 2024 3:59 PM
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: kvmarm at lists.linux.dev; iommu at lists.linux.dev; linux-arm-
> kernel at lists.infradead.org; Linuxarm <linuxarm at huawei.com>;
> kevin.tian at intel.com; alex.williamson at redhat.com; maz at kernel.org;
> oliver.upton at linux.dev; will at kernel.org; robin.murphy at arm.com; jean-
> philippe at linaro.org; Jonathan Cameron <jonathan.cameron at huawei.com>
> Subject: Re: [RFC PATCH v2 6/7] iommu/arm-smmu-v3: Use KVM VMID for s2
> stage
> 
> On Thu, Feb 08, 2024 at 03:18:36PM +0000, Shameer Kolothum wrote:
> > If kvm is available make use of kvm pinned VMID interfaces to
> > set the s2 stage VMID for nested domains.
> >
> > Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> > ---
> >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 +++++++++++++-----
> >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  2 ++
> >  2 files changed, 15 insertions(+), 5 deletions(-)
> >
> > 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 b41d77787a2f..18e3e04b50f4 100644
> > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > @@ -18,6 +18,7 @@
> >  #include <linux/interrupt.h>
> >  #include <linux/io-pgtable.h>
> >  #include <linux/iopoll.h>
> > +#include <linux/kvm_host.h>
> >  #include <linux/module.h>
> >  #include <linux/msi.h>
> >  #include <linux/of.h>
> > @@ -2399,9 +2400,13 @@ int arm_smmu_domain_alloc_id(struct
> arm_smmu_device *smmu,
> >  	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2) {
> >  		int vmid;
> >
> > -		/* Reserve VMID 0 for stage-2 bypass STEs */
> > -		vmid = ida_alloc_range(&smmu->vmid_map, 1,
> > -				       (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
> > +		if (smmu_domain->kvm) {
> > +			vmid = kvm_pinned_vmid_get(smmu_domain->kvm);
> > +		} else {
> > +			/* Reserve VMID 0 for stage-2 bypass STEs */
> > +			vmid = ida_alloc_range(&smmu->vmid_map, 1,
> > +					       (1 << smmu->vmid_bits) - 1,
> GFP_KERNEL);
> > +		}
> 
> We cannot allow the two different STEs to be programmed with the same
> VMID but different translations, so somehow the two allocators have to
> work together.

My idea was, we only set smmu_domain->kvm in the nested parent case
and that means SMMUv3 supports both S1 & S2. So all the non-nested domains
are using S1.

> 
> This is why the SVA BTM code has that complex ASID reassignment logic
> so it can get away with two allocators. However ASID also has SMMU HW
> ASET support to opt-in to the BTM broadcast.
> 
> My suggestion is to avoid two allocators and make iommu instances that
> support BTM always use the KVM owned VMID allocator by forbidding a S2
> domain from being created with a NULL KVM.

This is what I was trying to do. But not sure we have systems out there where
only S2  is supported and that may require a private VMID without KVM.

> 
> IOW all the DMA API/etc will use S1 domains and the only way to get to
> a S2 is to allocate a nesting parent via iommufd - for BTM systems
> only.
> 
> Since the S2 can't opt-out of the BTM broadcast this means the VMIDs
> are cleanly assigned and we never get an issue where the KVM TLBI's
> are flushing an unrelated S2.

In the last patch we only enable BTM if only S1 is supported. Meaning we will
always have a KVM VMID associated for S2(if it supports that). 

Did I miss something here?

Thanks,
Shameer


From thomas.richard at bootlin.com  Thu Feb  8 08:19:25 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 8 Feb 2024 17:19:25 +0100
Subject: [PATCH 01/14] gpio: pca953x: move suspend/resume to
 suspend_noirq/resume_noirq
In-Reply-To: <CACRpkdYUVbFoDq91uLbUy8twtG_AiD+CY2+nqzCyHV7ZyBC3sA@mail.gmail.com>
References: <20240102-j7200-pcie-s2r-v1-0-84e55da52400@bootlin.com>
 <20240102-j7200-pcie-s2r-v1-1-84e55da52400@bootlin.com>
 <20240116074333.GO5185@atomide.com>
 <31c42f08-7d5e-4b91-87e9-bfc7e2cfdefe@bootlin.com>
 <CACRpkdYUVbFoDq91uLbUy8twtG_AiD+CY2+nqzCyHV7ZyBC3sA@mail.gmail.com>
Message-ID: <95032042-787e-494a-bad9-81b62653de52@bootlin.com>

On 1/28/24 01:12, Linus Walleij wrote:
> On Fri, Jan 19, 2024 at 6:01?PM Thomas Richard
> <thomas.richard at bootlin.com> wrote:
>> On 1/16/24 08:43, Tony Lindgren wrote:
>>> * Thomas Richard <thomas.richard at bootlin.com> [240115 16:16]:
>>>> Some IOs can be needed during suspend_noirq/resume_noirq.
>>>> So move suspend/resume callbacks to noirq.
>>>
>>> So have you checked that the pca953x_save_context() and restore works
>>> this way? There's i2c traffic and regulators may sleep.. I wonder if
>>> you instead just need to leave gpio-pca953x enabled in some cases
>>> instead?
>>>
>>
>> Yes I tested it, and it works (with my setup).
>> But this patch may have an impact for other people.
>> How could I leave it enabled in some cases ?
> 
> I guess you could define both pca953x_suspend() and
> pca953x_suspend_noirq() and selectively bail out on one
> path on some systems?

Yes.

What do you think if I use a property like for example "ti,pm-noirq" to
select the right path ?
Is a property relevant for this use case ?

Regards,

> 
> Worst case using if (of_machine_is_compatible("my,machine"))...
> 
> Yours,
> Linus Walleij
-- 
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From peter.griffin at linaro.org  Thu Feb  8 08:16:58 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu,  8 Feb 2024 16:16:58 +0000
Subject: [PATCH v4 0/2] Add regmap support to exynos-pmu for protected PMU regs
Message-ID: <20240208161700.268570-1-peter.griffin@linaro.org>

Hi folks,

This is a v4 of the series to add support for protected PMU registers found
on gs101 and derivative SoCs. In v2 and later it was re-worked to be based
on a regmap abstraction that I think leads to a much neater overall
solution.

The advantage of the regmap abstraction is that most leaf drivers that
read/write PMU registers need minimal changes.

Example of Exynos drivers that require PMU register access are:
* watchdog
* usb phy
* mipi phy
* ufs phy

This series has been tested on Pixel 6 / gs101. If the various maintainers/
contributors of other Exynos SoCs like exynos850, exynosautov9, exynos5422
etc can test these patches on your respective systems that would be most
appreciated.

The expectation is this series would be merged via Krzysztofs Samsung
Exynos tree.

regards,

Peter

Changes since v3:
 - Fix PMUALIVE_MASK
 - Add TENSOR_ prefix
 - clear SET_BITS bits on each loop iteration
 - change set_bit to set_bits func name
 - Fix some alignment
 - Add missing return on dev_err_probe
 - Reduce indentation in loop

Changes since v2
 - Add select REGMAP to Kconfig
 - Add constant for SET/CLEAR bits
 - Replace kerneldoc with one line comment
 - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
 - remove superfluous extern keyword
 - dev_err_probe() on probe error
 - shorten regmcfg name
 - no compatibles inside probe, use match data
 - don't mix declarations with/without initializations
 - tensor_sec_reg_read() use mmio to avoid access restrictions
 - Collect up Reviewed-by
 - const for regmap_config structs

Changes since v1:
 - Refactor to use custom regmap to abstract SMC register access
   (Sam / Guenter)
 - Add deferred probing support (Saravana / Krzysztof)

v3 lore: https://lore.kernel.org/linux-arm-kernel/20240202145731.4082033-1-peter.griffin at linaro.org/
v2 lore: https://lore.kernel.org/lkml/20240129211912.3068411-1-peter.griffin at linaro.org/
v1 lore: https://lore.kernel.org/all/20240122225710.1952066-1-peter.griffin at linaro.org/

Peter Griffin (2):
  soc: samsung: exynos-pmu: Add regmap support for SoCs that protect PMU
    regs
  watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU
    regs

 drivers/soc/samsung/Kconfig            |   1 +
 drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
 drivers/soc/samsung/exynos-pmu.h       |   1 +
 drivers/watchdog/Kconfig               |   1 -
 drivers/watchdog/s3c2410_wdt.c         |   8 +-
 include/linux/soc/samsung/exynos-pmu.h |  11 +-
 6 files changed, 247 insertions(+), 10 deletions(-)

-- 
2.43.0.594.gd9cf4e227d-goog



From peter.griffin at linaro.org  Thu Feb  8 08:17:00 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu,  8 Feb 2024 16:17:00 +0000
Subject: [PATCH v4 2/2] watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs
In-Reply-To: <20240208161700.268570-1-peter.griffin@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org>
Message-ID: <20240208161700.268570-3-peter.griffin@linaro.org>

Obtain the PMU regmap using the new API added to exynos-pmu driver rather
than syscon_regmap_lookup_by_phandle(). As this driver no longer depends
on mfd syscon remove that header and Kconfig dependency.

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 drivers/watchdog/Kconfig       | 1 -
 drivers/watchdog/s3c2410_wdt.c | 8 ++++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7d22051b15a2..d78fe7137799 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -512,7 +512,6 @@ config S3C2410_WATCHDOG
 	tristate "S3C6410/S5Pv210/Exynos Watchdog"
 	depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
 	select WATCHDOG_CORE
-	select MFD_SYSCON if ARCH_EXYNOS
 	help
 	  Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos
 	  SoCs. This will reboot the system when the timer expires with
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 349d30462c8c..686cf544d0ae 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -24,9 +24,9 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/of.h>
-#include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/delay.h>
+#include <linux/soc/samsung/exynos-pmu.h>
 
 #define S3C2410_WTCON		0x00
 #define S3C2410_WTDAT		0x04
@@ -699,11 +699,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
 		return ret;
 
 	if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
-		wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
-						"samsung,syscon-phandle");
+		wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node,
+						 "samsung,syscon-phandle");
 		if (IS_ERR(wdt->pmureg))
 			return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
-					     "syscon regmap lookup failed.\n");
+					     "PMU regmap lookup failed.\n");
 	}
 
 	wdt_irq = platform_get_irq(pdev, 0);
-- 
2.43.0.594.gd9cf4e227d-goog



From peter.griffin at linaro.org  Thu Feb  8 08:16:59 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu,  8 Feb 2024 16:16:59 +0000
Subject: [PATCH v4 1/2] soc: samsung: exynos-pmu: Add regmap support for SoCs that protect PMU regs
In-Reply-To: <20240208161700.268570-1-peter.griffin@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org>
Message-ID: <20240208161700.268570-2-peter.griffin@linaro.org>

Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
security hardening reasons so that they are only write accessible in el3
via an SMC call.

As most Exynos drivers that need to write PMU registers currently obtain a
regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
is implemented in this driver using a custom regmap similar to syscon to
handle the SMC call. Platforms that don't secure PMU registers, get a mmio
regmap like before. As regmaps abstract out the underlying register access
changes to the leaf drivers are minimal.

A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
that currently use syscon_regmap_lookup_by_phandle(). This also handles
deferred probing.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
Changes since v3:
 - Fix PMUALIVE_MASK
 - Add TENSOR_ prefix
 - clear SET_BITS bits on each loop iteration
 - change set_bit to set_bits in func name
 - Fix some alignment
 - Add missing return on dev_err_probe
 - Reduce indentation in loop

Changes since v2
 - Add select REGMAP to Kconfig
 - Add constant for SET/CLEAR bits
 - Replace kerneldoc with one line comment
 - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
 - remove superfluous extern keyword
 - dev_err_probe() on probe error
 - shorten regmcfg name
 - no compatibles inside probe, use match data
 - don't mix declarations with/without initializations
 - tensor_sec_reg_read() use mmio to avoid access restrictions
 - Collect up Reviewed-by
 - const for regmap_config structs
---
 drivers/soc/samsung/Kconfig            |   1 +
 drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
 drivers/soc/samsung/exynos-pmu.h       |   1 +
 include/linux/soc/samsung/exynos-pmu.h |  11 +-
 4 files changed, 243 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 27ec99af77e3..1a5dfdc978dc 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -42,6 +42,7 @@ config EXYNOS_PMU
 	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
 	select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
 	select MFD_CORE
+	select REGMAP_MMIO
 
 # There is no need to enable these drivers for ARMv8
 config EXYNOS_PMU_ARM_DRIVERS
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index 250537d7cfd6..b846e343fcdd 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -5,6 +5,7 @@
 //
 // Exynos - CPU PMU(Power Management Unit) support
 
+#include <linux/arm-smccc.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/mfd/core.h>
@@ -12,19 +13,132 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/regmap.h>
 
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/soc/samsung/exynos-pmu.h>
 
 #include "exynos-pmu.h"
 
+#define PMUALIVE_MASK			GENMASK(13, 0)
+#define TENSOR_SET_BITS			(BIT(15) | BIT(14))
+#define TENSOR_CLR_BITS			BIT(15)
+#define TENSOR_SMC_PMU_SEC_REG		0x82000504
+#define TENSOR_PMUREG_READ		0
+#define TENSOR_PMUREG_WRITE		1
+#define TENSOR_PMUREG_RMW		2
+
 struct exynos_pmu_context {
 	struct device *dev;
 	const struct exynos_pmu_data *pmu_data;
+	struct regmap *pmureg;
 };
 
 void __iomem *pmu_base_addr;
 static struct exynos_pmu_context *pmu_context;
+/* forward declaration */
+static struct platform_driver exynos_pmu_driver;
+
+/*
+ * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
+ * from EL3, but are still read accessible. As Linux needs to write some of
+ * these registers, the following functions are provided and exposed via
+ * regmap.
+ *
+ * Note: This SMC interface is known to be implemented on gs101 and derivative
+ * SoCs.
+ */
+
+/* Write to a protected PMU register. */
+static int tensor_sec_reg_write(void *base, unsigned int reg, unsigned int val)
+{
+	struct arm_smccc_res res;
+	unsigned long pmu_base = (unsigned long)base;
+
+	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
+		      TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
+
+	/* returns -EINVAL if access isn't allowed or 0 */
+	if (res.a0)
+		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
+
+	return (int)res.a0;
+}
+
+/* Read/Modify/Write a protected PMU register. */
+static int tensor_sec_reg_rmw(void *base, unsigned int reg,
+			      unsigned int mask, unsigned int val)
+{
+	struct arm_smccc_res res;
+	unsigned long pmu_base = (unsigned long)base;
+
+	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
+		      TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
+
+	/* returns -EINVAL if access isn't allowed or 0 */
+	if (res.a0)
+		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
+
+	return (int)res.a0;
+}
+
+/*
+ * Read a protected PMU register. All PMU registers can be read by Linux.
+ * Note: The SMC read register is not used, as only registers that can be
+ * written are readable via SMC.
+ */
+static int tensor_sec_reg_read(void *base, unsigned int reg, unsigned int *val)
+{
+	*val = pmu_raw_readl(reg);
+	return 0;
+}
+
+/*
+ * For SoCs that have set/clear bit hardware this function can be used when
+ * the PMU register will be accessed by multiple masters.
+ *
+ * For example, to set bits 13:8 in PMU reg offset 0x3e80
+ * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00);
+ *
+ * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80
+ * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00);
+ */
+static inline int tensor_set_bits_atomic(void *ctx, unsigned int offset,
+					 u32 val, u32 mask)
+{
+	int ret;
+	unsigned int i;
+
+	for (i = 0; i < 32; i++) {
+		if (!(mask & BIT(i)))
+			continue;
+
+		offset &= ~TENSOR_SET_BITS;
+
+		if (val & BIT(i))
+			offset |= TENSOR_SET_BITS;
+		else
+			offset |= TENSOR_CLR_BITS;
+
+		ret = tensor_sec_reg_write(ctx, offset, i);
+		if (ret)
+			return ret;
+	}
+	return ret;
+}
+
+static int tensor_sec_update_bits(void *ctx, unsigned int reg,
+				  unsigned int mask, unsigned int val)
+{
+	/*
+	 * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
+	 * as the target registers can be accessed by multiple masters.
+	 */
+	if (reg > PMUALIVE_MASK)
+		return tensor_sec_reg_rmw(ctx, reg, mask, val);
+
+	return tensor_set_bits_atomic(ctx, reg, val, mask);
+}
 
 void pmu_raw_writel(u32 val, u32 offset)
 {
@@ -75,11 +189,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
 #define exynos_pmu_data_arm_ptr(data)	NULL
 #endif
 
+static const struct regmap_config regmap_smccfg = {
+	.name = "pmu_regs",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.use_single_read = true,
+	.use_single_write = true,
+	.reg_read = tensor_sec_reg_read,
+	.reg_write = tensor_sec_reg_write,
+	.reg_update_bits = tensor_sec_update_bits,
+};
+
+static const struct regmap_config regmap_mmiocfg = {
+	.name = "pmu_regs",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.use_single_read = true,
+	.use_single_write = true,
+};
+
+static const struct exynos_pmu_data gs101_pmu_data = {
+	.pmu_secure = true
+};
+
 /*
  * PMU platform driver and devicetree bindings.
  */
 static const struct of_device_id exynos_pmu_of_device_ids[] = {
 	{
+		.compatible = "google,gs101-pmu",
+		.data = &gs101_pmu_data,
+	}, {
 		.compatible = "samsung,exynos3250-pmu",
 		.data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
 	}, {
@@ -113,19 +257,73 @@ static const struct mfd_cell exynos_pmu_devs[] = {
 	{ .name = "exynos-clkout", },
 };
 
+/**
+ * exynos_get_pmu_regmap() - Obtain pmureg regmap
+ *
+ * Find the pmureg regmap previously configured in probe() and return regmap
+ * pointer.
+ *
+ * Return: A pointer to regmap if found or ERR_PTR error value.
+ */
 struct regmap *exynos_get_pmu_regmap(void)
 {
 	struct device_node *np = of_find_matching_node(NULL,
 						      exynos_pmu_of_device_ids);
 	if (np)
-		return syscon_node_to_regmap(np);
+		return exynos_get_pmu_regmap_by_phandle(np, NULL);
 	return ERR_PTR(-ENODEV);
 }
 EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
 
+/**
+ * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
+ * @np: Pointer to device's Device Tree node
+ * @property: Device Tree property name which references the pmu
+ *
+ * Find the pmureg regmap previously configured in probe() and return regmap
+ * pointer.
+ *
+ * Return: A pointer to regmap if found or ERR_PTR error value.
+ */
+struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+						const char *property)
+{
+	struct device *dev;
+	struct exynos_pmu_context *ctx;
+	struct device_node *pmu_np;
+
+	if (property)
+		pmu_np = of_parse_phandle(np, property, 0);
+	else
+		pmu_np = np;
+
+	if (!pmu_np)
+		return ERR_PTR(-ENODEV);
+
+	/*
+	 * Determine if exynos-pmu device has probed and therefore regmap
+	 * has been created and can be returned to the caller. Otherwise we
+	 * return -EPROBE_DEFER.
+	 */
+	dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
+					    (void *)pmu_np);
+
+	of_node_put(pmu_np);
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	ctx = dev_get_drvdata(dev);
+
+	return ctx->pmureg;
+}
+EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
+
 static int exynos_pmu_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct regmap_config pmu_regmcfg;
+	struct regmap *regmap;
+	struct resource *res;
 	int ret;
 
 	pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
@@ -133,13 +331,42 @@ static int exynos_pmu_probe(struct platform_device *pdev)
 		return PTR_ERR(pmu_base_addr);
 
 	pmu_context = devm_kzalloc(&pdev->dev,
-			sizeof(struct exynos_pmu_context),
-			GFP_KERNEL);
+				   sizeof(struct exynos_pmu_context),
+				   GFP_KERNEL);
 	if (!pmu_context)
 		return -ENOMEM;
-	pmu_context->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
 	pmu_context->pmu_data = of_device_get_match_data(dev);
 
+	/* For SoCs that secure PMU register writes use custom regmap */
+	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_secure) {
+		pmu_regmcfg = regmap_smccfg;
+		pmu_regmcfg.max_register = resource_size(res) -
+					   pmu_regmcfg.reg_stride;
+		/* Need physical address for SMC call */
+		regmap = devm_regmap_init(dev, NULL,
+					  (void *)(uintptr_t)res->start,
+					  &pmu_regmcfg);
+	} else {
+		/* All other SoCs use a MMIO regmap */
+		pmu_regmcfg = regmap_mmiocfg;
+		pmu_regmcfg.max_register = resource_size(res) -
+					   pmu_regmcfg.reg_stride;
+		regmap = devm_regmap_init_mmio(dev, pmu_base_addr,
+					       &pmu_regmcfg);
+	}
+
+	if (IS_ERR(regmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(regmap),
+				     "regmap init failed\n");
+
+	pmu_context->pmureg = regmap;
+	pmu_context->dev = dev;
+
 	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init)
 		pmu_context->pmu_data->pmu_init();
 
diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
index 1c652ffd79b4..0a49a2c9a08e 100644
--- a/drivers/soc/samsung/exynos-pmu.h
+++ b/drivers/soc/samsung/exynos-pmu.h
@@ -21,6 +21,7 @@ struct exynos_pmu_conf {
 struct exynos_pmu_data {
 	const struct exynos_pmu_conf *pmu_config;
 	const struct exynos_pmu_conf *pmu_config_extra;
+	bool pmu_secure;
 
 	void (*pmu_init)(void);
 	void (*powerdown_conf)(enum sys_powerdown);
diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
index a4f5516cc956..e1c86640f6f7 100644
--- a/include/linux/soc/samsung/exynos-pmu.h
+++ b/include/linux/soc/samsung/exynos-pmu.h
@@ -10,6 +10,7 @@
 #define __LINUX_SOC_EXYNOS_PMU_H
 
 struct regmap;
+struct device_node;
 
 enum sys_powerdown {
 	SYS_AFTR,
@@ -20,12 +21,20 @@ enum sys_powerdown {
 
 extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
 #ifdef CONFIG_EXYNOS_PMU
-extern struct regmap *exynos_get_pmu_regmap(void);
+struct regmap *exynos_get_pmu_regmap(void);
+struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+						const char *property);
 #else
 static inline struct regmap *exynos_get_pmu_regmap(void)
 {
 	return ERR_PTR(-ENODEV);
 }
+
+static inline struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+							      const char *property)
+{
+	return ERR_PTR(-ENODEV);
+}
 #endif
 
 #endif /* __LINUX_SOC_EXYNOS_PMU_H */
-- 
2.43.0.594.gd9cf4e227d-goog



From daniel at makrotopia.org  Thu Feb  8 08:22:07 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Thu, 8 Feb 2024 16:22:07 +0000
Subject: [PATCH netnext 8/8] net: dsa: mt7530: simplify link operations
 and force link down on all ports
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-8-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
 <20240208-for-netnext-mt7530-improvements-3-v1-8-d7c1cfd502ca@arinc9.com>
Message-ID: <ZcT_r68mStRAC3Uk@makrotopia.org>

On Thu, Feb 08, 2024 at 08:51:36AM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> Currently, the link operations for switch MACs are scattered across
> port_enable, port_disable, phylink_mac_config, phylink_mac_link_up, and
> phylink_mac_link_down.
> 
> port_enable and port_disable clears the link settings. Move that to
> mt7530_setup() and mt7531_setup_common() which set up the switches. This
> way, the link settings are cleared on all ports at setup, and then only
> once with phylink_mac_link_down() when a link goes down.
> 
> Enable force mode at setup to apply the force part of the link settings.
> This ensures that only active ports will have their link up.
> 
> Now that the bit for setting the port on force mode is done on
> mt7530_setup() and mt7531_setup_common(), get rid of PMCR_FORCE_MODE_ID()
> which helped determine which bit to use for the switch model.
> 
> The "MT7621 Giga Switch Programming Guide v0.3", "MT7531 Reference Manual
> for Development Board v1.0", and "MT7988A Wi-Fi 7 Generation Router
> Platform: Datasheet (Open Version) v0.1" documents show that these bits are
> enabled at reset:
> 
> PMCR_IFG_XMIT(1) (not part of PMCR_LINK_SETTINGS_MASK)
> PMCR_MAC_MODE (not part of PMCR_LINK_SETTINGS_MASK)
> PMCR_TX_EN
> PMCR_RX_EN
> PMCR_BACKOFF_EN (not part of PMCR_LINK_SETTINGS_MASK)
> PMCR_BACKPR_EN (not part of PMCR_LINK_SETTINGS_MASK)
> PMCR_TX_FC_EN
> PMCR_RX_FC_EN
> 
> These bits also don't exist on the MT7530_PMCR_P(6) register of the switch
> on the MT7988 SoC:
> 
> PMCR_IFG_XMIT()
> PMCR_MAC_MODE
> PMCR_BACKOFF_EN
> PMCR_BACKPR_EN
> 
> Remove the setting of the bits not part of PMCR_LINK_SETTINGS_MASK on
> phylink_mac_config as they're already set.
> 
> Suggested-by: Vladimir Oltean <olteanv at gmail.com>
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> ---
>  drivers/net/dsa/mt7530.c | 26 +++++++++++++-------------
>  drivers/net/dsa/mt7530.h |  2 --
>  2 files changed, 13 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index 5c8ad41ce8cd..f67db577d1c0 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -1018,7 +1018,6 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
>  	priv->ports[port].enable = true;
>  	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
>  		   priv->ports[port].pm);
> -	mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
>  
>  	mutex_unlock(&priv->reg_mutex);
>  
> @@ -1038,7 +1037,6 @@ mt7530_port_disable(struct dsa_switch *ds, int port)
>  	priv->ports[port].enable = false;
>  	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
>  		   PCR_MATRIX_CLR);
> -	mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
>  
>  	mutex_unlock(&priv->reg_mutex);
>  }
> @@ -2257,6 +2255,12 @@ mt7530_setup(struct dsa_switch *ds)
>  	mt7530_mib_reset(ds);
>  
>  	for (i = 0; i < MT7530_NUM_PORTS; i++) {
> +		/* Clear link settings and enable force mode to force link down
> +		 * on all ports until they're enabled later.
> +		 */
> +		mt7530_clear(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK);
> +		mt7530_set(priv, MT7530_PMCR_P(i), PMCR_FORCE_MODE);

Any reason to not combine the two lines above into a single call:

mt7530_rmw(priv, MT7530_PMCR_P(i),
	   PMCR_LINK_SETTINGS_MASK | PMCR_FORCE_MODE,
	   PMCR_FORCE_MODE);

> +
>  		/* Disable forwarding by default on all ports */
>  		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
>  			   PCR_MATRIX_CLR);
> @@ -2359,6 +2363,12 @@ mt7531_setup_common(struct dsa_switch *ds)
>  		     UNU_FFP_MASK);
>  
>  	for (i = 0; i < MT7530_NUM_PORTS; i++) {
> +		/* Clear link settings and enable force mode to force link down
> +		 * on all ports until they're enabled later.
> +		 */
> +		mt7530_clear(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK);
> +		mt7530_set(priv, MT7530_PMCR_P(i), MT7531_FORCE_MODE);
> +

Same here obviously.

>  		/* Disable forwarding by default on all ports */
>  		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
>  			   PCR_MATRIX_CLR);
> @@ -2657,23 +2667,13 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
>  			  const struct phylink_link_state *state)
>  {
>  	struct mt7530_priv *priv = ds->priv;
> -	u32 mcr_cur, mcr_new;
>  
>  	if ((port == 5 || port == 6) && priv->info->mac_port_config)
>  		priv->info->mac_port_config(ds, port, mode, state->interface);
>  
> -	mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
> -	mcr_new = mcr_cur;
> -	mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
> -	mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
> -		   PMCR_BACKPR_EN | PMCR_FORCE_MODE_ID(priv->id);
> -
>  	/* Are we connected to external phy */
>  	if (port == 5 && dsa_is_user_port(ds, 5))
> -		mcr_new |= PMCR_EXT_PHY;
> -
> -	if (mcr_new != mcr_cur)
> -		mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
> +		mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
>  }
>  
>  static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
> diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
> index 8a8144868eaa..a71166e0a7fc 100644
> --- a/drivers/net/dsa/mt7530.h
> +++ b/drivers/net/dsa/mt7530.h
> @@ -304,8 +304,6 @@ enum mt7530_vlan_port_acc_frm {
>  					 MT7531_FORCE_DPX | \
>  					 MT7531_FORCE_RX_FC | \
>  					 MT7531_FORCE_TX_FC)
> -#define  PMCR_FORCE_MODE_ID(id)		((((id) == ID_MT7531) || ((id) == ID_MT7988)) ?	\
> -					 MT7531_FORCE_MODE : PMCR_FORCE_MODE)
>  #define  PMCR_LINK_SETTINGS_MASK	(PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
>  					 PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
>  					 PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
> 
> -- 
> 2.40.1
> 


From jgg at ziepe.ca  Thu Feb  8 08:26:05 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Thu, 8 Feb 2024 12:26:05 -0400
Subject: [RFC PATCH v2 6/7] iommu/arm-smmu-v3: Use KVM VMID for s2 stage
In-Reply-To: <8bfca4c5bfe7424691efdae0f686ece4@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
 <20240208151837.35068-7-shameerali.kolothum.thodi@huawei.com>
 <20240208155915.GR31743@ziepe.ca>
 <8bfca4c5bfe7424691efdae0f686ece4@huawei.com>
Message-ID: <20240208162605.GU31743@ziepe.ca>

On Thu, Feb 08, 2024 at 04:14:07PM +0000, Shameerali Kolothum Thodi wrote:
> > >  #include <linux/of.h>
> > > @@ -2399,9 +2400,13 @@ int arm_smmu_domain_alloc_id(struct
> > arm_smmu_device *smmu,
> > >  	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2) {
> > >  		int vmid;
> > >
> > > -		/* Reserve VMID 0 for stage-2 bypass STEs */
> > > -		vmid = ida_alloc_range(&smmu->vmid_map, 1,
> > > -				       (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
> > > +		if (smmu_domain->kvm) {
> > > +			vmid = kvm_pinned_vmid_get(smmu_domain->kvm);
> > > +		} else {
> > > +			/* Reserve VMID 0 for stage-2 bypass STEs */
> > > +			vmid = ida_alloc_range(&smmu->vmid_map, 1,
> > > +					       (1 << smmu->vmid_bits) - 1,
> > GFP_KERNEL);
> > > +		}
> > 
> > We cannot allow the two different STEs to be programmed with the same
> > VMID but different translations, so somehow the two allocators have to
> > work together.
> 
> My idea was, we only set smmu_domain->kvm in the nested parent case
> and that means SMMUv3 supports both S1 & S2. So all the non-nested domains
> are using S1.

Okay, that is what I was thinking to get to.

The logic needs to reflect this directly though:

/*
 * There can only be one allocator for VMIDs active at once. If BTM is
 * turned on then KVM's allocator always supplies the VMID, and the
 * VMID is matched by CPU invalidation of the KVM S2. Right now there
 * is no API to get an unused VMID from KVM so this also means BTM systems
 * cannot support S2 without an associated KVM.
 */
if ((smmu->feature & ARM_SMMU_FEAT_BTM)) {
   if (!smmu_domain->kvm)
      vmid = -EOPNOTSUPP;
   else
       vmid = kvm_pinned_vmid_get(smmu_domain->kvm);
} else {
	/* Reserve VMID 0 for stage-2 bypass STEs */
	vmid = ida_alloc_range(&smmu->vmid_map, 1,
		       (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
}

(and matching change to the free side)

> This is what I was trying to do. But not sure we have systems out there where
> only S2  is supported and that may require a private VMID without KVM.

iommufd can ask for a nesting parent without supplying a KVM fd, which
would cause vmid aliasing between the two allocators. That needs to be
blocked as above

Jason


From shameerali.kolothum.thodi at huawei.com  Thu Feb  8 08:36:57 2024
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Thu, 8 Feb 2024 16:36:57 +0000
Subject: [RFC PATCH v2 6/7] iommu/arm-smmu-v3: Use KVM VMID for s2 stage
In-Reply-To: <20240208162605.GU31743@ziepe.ca>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
 <20240208151837.35068-7-shameerali.kolothum.thodi@huawei.com>
 <20240208155915.GR31743@ziepe.ca>
 <8bfca4c5bfe7424691efdae0f686ece4@huawei.com>
 <20240208162605.GU31743@ziepe.ca>
Message-ID: <d94a9c134e5148889f60ee07f14239d7@huawei.com>



> -----Original Message-----
> From: Jason Gunthorpe <jgg at ziepe.ca>
> Sent: Thursday, February 8, 2024 4:26 PM
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: kvmarm at lists.linux.dev; iommu at lists.linux.dev; linux-arm-
> kernel at lists.infradead.org; Linuxarm <linuxarm at huawei.com>;
> kevin.tian at intel.com; alex.williamson at redhat.com; maz at kernel.org;
> oliver.upton at linux.dev; will at kernel.org; robin.murphy at arm.com; jean-
> philippe at linaro.org; Jonathan Cameron <jonathan.cameron at huawei.com>
> Subject: Re: [RFC PATCH v2 6/7] iommu/arm-smmu-v3: Use KVM VMID for s2
> stage
> 
> On Thu, Feb 08, 2024 at 04:14:07PM +0000, Shameerali Kolothum Thodi wrote:
> > > >  #include <linux/of.h>
> > > > @@ -2399,9 +2400,13 @@ int arm_smmu_domain_alloc_id(struct
> > > arm_smmu_device *smmu,
> > > >  	} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2) {
> > > >  		int vmid;
> > > >
> > > > -		/* Reserve VMID 0 for stage-2 bypass STEs */
> > > > -		vmid = ida_alloc_range(&smmu->vmid_map, 1,
> > > > -				       (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
> > > > +		if (smmu_domain->kvm) {
> > > > +			vmid = kvm_pinned_vmid_get(smmu_domain->kvm);
> > > > +		} else {
> > > > +			/* Reserve VMID 0 for stage-2 bypass STEs */
> > > > +			vmid = ida_alloc_range(&smmu->vmid_map, 1,
> > > > +					       (1 << smmu->vmid_bits) - 1,
> > > GFP_KERNEL);
> > > > +		}
> > >
> > > We cannot allow the two different STEs to be programmed with the same
> > > VMID but different translations, so somehow the two allocators have to
> > > work together.
> >
> > My idea was, we only set smmu_domain->kvm in the nested parent case
> > and that means SMMUv3 supports both S1 & S2. So all the non-nested
> domains
> > are using S1.
> 
> Okay, that is what I was thinking to get to.
> 
> The logic needs to reflect this directly though:
> 
> /*
>  * There can only be one allocator for VMIDs active at once. If BTM is
>  * turned on then KVM's allocator always supplies the VMID, and the
>  * VMID is matched by CPU invalidation of the KVM S2. Right now there
>  * is no API to get an unused VMID from KVM so this also means BTM systems
>  * cannot support S2 without an associated KVM.
>  */
> if ((smmu->feature & ARM_SMMU_FEAT_BTM)) {
>    if (!smmu_domain->kvm)
>       vmid = -EOPNOTSUPP;
>    else
>        vmid = kvm_pinned_vmid_get(smmu_domain->kvm);
> } else {
> 	/* Reserve VMID 0 for stage-2 bypass STEs */
> 	vmid = ida_alloc_range(&smmu->vmid_map, 1,
> 		       (1 << smmu->vmid_bits) - 1, GFP_KERNEL);
> }
> 
> (and matching change to the free side)
> 
> > This is what I was trying to do. But not sure we have systems out there where
> > only S2  is supported and that may require a private VMID without KVM.
> 
> iommufd can ask for a nesting parent without supplying a KVM fd, which
> would cause vmid aliasing between the two allocators. That needs to be
> blocked as above

Ah..That's right. Missed that case where KVM can be NULL, but still there is a 
request for nested domain.

Thanks,
Shameer


From krzysztof.kozlowski at linaro.org  Thu Feb  8 08:37:10 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 17:37:10 +0100
Subject: [PATCH] clk: constify the of_phandle_args argument of of_clk_provider
Message-ID: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>

None of the implementations of the get() and get_hw() callbacks of
"struct of_clk_provider" modify the contents of received of_phandle_args
pointer.  They treat it as read-only variable used to find the clock to
return.  Make obvious that implementations are not supposed to modify
the of_phandle_args, by making it a pointer to const.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 drivers/clk/at91/pmc.c                        |  3 +-
 drivers/clk/at91/pmc.h                        |  3 +-
 drivers/clk/baikal-t1/clk-ccu-div.c           |  2 +-
 drivers/clk/baikal-t1/clk-ccu-pll.c           |  2 +-
 drivers/clk/bcm/clk-kona-setup.c              |  2 +-
 drivers/clk/clk-axm5516.c                     |  2 +-
 drivers/clk/clk-cdce706.c                     |  2 +-
 drivers/clk/clk-cdce925.c                     |  2 +-
 drivers/clk/clk-k210.c                        |  2 +-
 drivers/clk/clk-lochnagar.c                   |  2 +-
 drivers/clk/clk-max77686.c                    |  2 +-
 drivers/clk/clk-max9485.c                     |  2 +-
 drivers/clk/clk-qoriq.c                       |  3 +-
 drivers/clk/clk-renesas-pcie.c                |  2 +-
 drivers/clk/clk-rk808.c                       |  2 +-
 drivers/clk/clk-scpi.c                        |  2 +-
 drivers/clk/clk-si521xx.c                     |  2 +-
 drivers/clk/clk-si5341.c                      |  2 +-
 drivers/clk/clk-si5351.c                      |  4 +--
 drivers/clk/clk-sparx5.c                      |  3 +-
 drivers/clk/clk-stm32f4.c                     |  2 +-
 drivers/clk/clk-versaclock3.c                 |  2 +-
 drivers/clk/clk-versaclock5.c                 |  2 +-
 drivers/clk/clk-versaclock7.c                 |  2 +-
 drivers/clk/clk.c                             | 30 ++++++++++---------
 drivers/clk/hisilicon/clk-hi3660-stub.c       |  2 +-
 drivers/clk/imx/clk-imx8qxp-lpcg.c            |  2 +-
 drivers/clk/imx/clk-scu.c                     |  2 +-
 drivers/clk/imx/clk-scu.h                     |  2 +-
 drivers/clk/keystone/sci-clk.c                |  3 +-
 drivers/clk/meson/meson-clkc-utils.c          |  3 +-
 drivers/clk/meson/meson-clkc-utils.h          |  3 +-
 drivers/clk/mvebu/common.c                    |  2 +-
 drivers/clk/mvebu/cp110-system-controller.c   |  2 +-
 drivers/clk/mvebu/kirkwood.c                  |  2 +-
 drivers/clk/nxp/clk-lpc18xx-ccu.c             |  2 +-
 drivers/clk/qcom/clk-rpm.c                    |  2 +-
 drivers/clk/qcom/clk-rpmh.c                   |  2 +-
 drivers/clk/qcom/clk-smd-rpm.c                |  2 +-
 drivers/clk/qcom/clk-spmi-pmic-div.c          |  2 +-
 drivers/clk/qcom/common.c                     |  2 +-
 drivers/clk/qcom/krait-cc.c                   |  2 +-
 drivers/clk/renesas/r9a06g032-clocks.c        |  2 +-
 drivers/clk/renesas/renesas-cpg-mssr.c        |  2 +-
 drivers/clk/renesas/rzg2l-cpg.c               |  2 +-
 .../clk/starfive/clk-starfive-jh7100-audio.c  |  3 +-
 drivers/clk/starfive/clk-starfive-jh7100.c    |  3 +-
 .../clk/starfive/clk-starfive-jh7110-aon.c    |  3 +-
 .../clk/starfive/clk-starfive-jh7110-isp.c    |  3 +-
 .../clk/starfive/clk-starfive-jh7110-pll.c    |  3 +-
 .../clk/starfive/clk-starfive-jh7110-stg.c    |  3 +-
 .../clk/starfive/clk-starfive-jh7110-sys.c    |  3 +-
 .../clk/starfive/clk-starfive-jh7110-vout.c   |  3 +-
 drivers/clk/tegra/clk-bpmp.c                  |  2 +-
 drivers/clk/tegra/clk-tegra124.c              |  2 +-
 drivers/clk/tegra/clk-tegra20.c               |  2 +-
 drivers/clk/tegra/clk-tegra30.c               |  2 +-
 drivers/clk/ti/clkctrl.c                      |  2 +-
 drivers/clk/ux500/u8500_of_clk.c              |  4 +--
 drivers/clk/versatile/clk-sp810.c             |  2 +-
 drivers/media/platform/ti/omap3isp/isp.c      |  3 +-
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c     |  6 ++--
 include/linux/clk-provider.h                  | 28 ++++++++---------
 include/linux/clk.h                           |  4 +--
 sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c     |  2 +-
 65 files changed, 115 insertions(+), 95 deletions(-)

diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 5aa9c1f1c886..64ec624ffc15 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -44,7 +44,8 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname,
 }
 EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
 
-struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
+struct clk_hw *of_clk_hw_pmc_get(const struct of_phandle_args *clkspec,
+				 void *data)
 {
 	unsigned int type = clkspec->args[0];
 	unsigned int idx = clkspec->args[1];
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 0f52e80bcd49..09ae26d0cece 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -126,7 +126,8 @@ struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
 int of_at91_get_clk_range(struct device_node *np, const char *propname,
 			  struct clk_range *range);
 
-struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data);
+struct clk_hw *of_clk_hw_pmc_get(const struct of_phandle_args *clkspec,
+				 void *data);
 
 struct clk_hw * __init
 at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name,
diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c
index 84555a00f950..97ea3d747a78 100644
--- a/drivers/clk/baikal-t1/clk-ccu-div.c
+++ b/drivers/clk/baikal-t1/clk-ccu-div.c
@@ -322,7 +322,7 @@ static int ccu_div_find_sys_regs(struct ccu_div_data *data)
 	return 0;
 }
 
-static struct clk_hw *ccu_div_of_clk_hw_get(struct of_phandle_args *clkspec,
+static struct clk_hw *ccu_div_of_clk_hw_get(const struct of_phandle_args *clkspec,
 					    void *priv)
 {
 	struct ccu_div_data *data = priv;
diff --git a/drivers/clk/baikal-t1/clk-ccu-pll.c b/drivers/clk/baikal-t1/clk-ccu-pll.c
index fce02ce77347..0e71d5967794 100644
--- a/drivers/clk/baikal-t1/clk-ccu-pll.c
+++ b/drivers/clk/baikal-t1/clk-ccu-pll.c
@@ -126,7 +126,7 @@ static int ccu_pll_find_sys_regs(struct ccu_pll_data *data)
 	return 0;
 }
 
-static struct clk_hw *ccu_pll_of_clk_hw_get(struct of_phandle_args *clkspec,
+static struct clk_hw *ccu_pll_of_clk_hw_get(const struct of_phandle_args *clkspec,
 					    void *priv)
 {
 	struct ccu_pll_data *data = priv;
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c
index 338558f6fbae..1149bcd7617f 100644
--- a/drivers/clk/bcm/clk-kona-setup.c
+++ b/drivers/clk/bcm/clk-kona-setup.c
@@ -773,7 +773,7 @@ static bool ccu_data_valid(struct ccu_data *ccu)
 }
 
 static struct clk_hw *
-of_clk_kona_onecell_get(struct of_phandle_args *clkspec, void *data)
+of_clk_kona_onecell_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct ccu_data *ccu = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-axm5516.c b/drivers/clk/clk-axm5516.c
index 4a3462ee8f3e..458f44f4c08e 100644
--- a/drivers/clk/clk-axm5516.c
+++ b/drivers/clk/clk-axm5516.c
@@ -512,7 +512,7 @@ static struct axxia_clk *axmclk_clocks[] = {
 };
 
 static struct clk_hw *
-of_clk_axmclk_get(struct of_phandle_args *clkspec, void *unused)
+of_clk_axmclk_get(const struct of_phandle_args *clkspec, void *unused)
 {
 	unsigned int idx = clkspec->args[0];
 
diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c
index dd3d42d9ad86..1db9fc5d2af7 100644
--- a/drivers/clk/clk-cdce706.c
+++ b/drivers/clk/clk-cdce706.c
@@ -618,7 +618,7 @@ static int cdce706_register_clkouts(struct cdce706_dev_data *cdce)
 }
 
 static struct clk_hw *
-of_clk_cdce_get(struct of_phandle_args *clkspec, void *data)
+of_clk_cdce_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct cdce706_dev_data *cdce = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c
index b0122093c6ff..48135ee578c5 100644
--- a/drivers/clk/clk-cdce925.c
+++ b/drivers/clk/clk-cdce925.c
@@ -576,7 +576,7 @@ static int cdce925_regmap_i2c_read(void *context,
 }
 
 static struct clk_hw *
-of_clk_cdce925_get(struct of_phandle_args *clkspec, void *_data)
+of_clk_cdce925_get(const struct of_phandle_args *clkspec, void *_data)
 {
 	struct clk_cdce925_chip *data = _data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-k210.c b/drivers/clk/clk-k210.c
index 7b7329a907ab..2333ed3ed7a2 100644
--- a/drivers/clk/clk-k210.c
+++ b/drivers/clk/clk-k210.c
@@ -875,7 +875,7 @@ static inline void __init k210_register_clk_child(struct device_node *np,
 	k210_register_clk(np, ksc, id, &parent_data, 1, 0);
 }
 
-static struct clk_hw *k210_clk_hw_onecell_get(struct of_phandle_args *clkspec,
+static struct clk_hw *k210_clk_hw_onecell_get(const struct of_phandle_args *clkspec,
 					      void *data)
 {
 	struct k210_sysclk *ksc = data;
diff --git a/drivers/clk/clk-lochnagar.c b/drivers/clk/clk-lochnagar.c
index 5561a2c66b69..5b773787a225 100644
--- a/drivers/clk/clk-lochnagar.c
+++ b/drivers/clk/clk-lochnagar.c
@@ -215,7 +215,7 @@ static const struct clk_ops lochnagar_clk_ops = {
 };
 
 static struct clk_hw *
-lochnagar_of_clk_hw_get(struct of_phandle_args *clkspec, void *data)
+lochnagar_of_clk_hw_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct lochnagar_clk_priv *priv = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
index 3727d5472450..3ce2453c116c 100644
--- a/drivers/clk/clk-max77686.c
+++ b/drivers/clk/clk-max77686.c
@@ -145,7 +145,7 @@ static const struct clk_ops max77686_clk_ops = {
 };
 
 static struct clk_hw *
-of_clk_max77686_get(struct of_phandle_args *clkspec, void *data)
+of_clk_max77686_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct max77686_clk_driver_data *drv_data = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-max9485.c b/drivers/clk/clk-max9485.c
index be9020b6c789..050246008514 100644
--- a/drivers/clk/clk-max9485.c
+++ b/drivers/clk/clk-max9485.c
@@ -246,7 +246,7 @@ static const struct max9485_clk max9485_clks[MAX9485_NUM_CLKS] = {
 };
 
 static struct clk_hw *
-max9485_of_clk_get(struct of_phandle_args *clkspec, void *data)
+max9485_of_clk_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct max9485_driver_data *drvdata = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index 4dcde305944c..95baeca8c031 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -1384,7 +1384,8 @@ static void __init core_pll_init(struct device_node *np)
 	}
 }
 
-static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data)
+static struct clk *clockgen_clk_get(const struct of_phandle_args *clkspec,
+				    void *data)
 {
 	struct clockgen *cg = data;
 	struct clk *clk;
diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c
index 53e21ac302e6..0fad48ff0f95 100644
--- a/drivers/clk/clk-renesas-pcie.c
+++ b/drivers/clk/clk-renesas-pcie.c
@@ -270,7 +270,7 @@ static void rs9_update_config(struct rs9_driver_data *rs9)
 }
 
 static struct clk_hw *
-rs9_of_clk_get(struct of_phandle_args *clkspec, void *data)
+rs9_of_clk_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct rs9_driver_data *rs9 = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c
index f7412b137e5e..05e5047e7ce8 100644
--- a/drivers/clk/clk-rk808.c
+++ b/drivers/clk/clk-rk808.c
@@ -72,7 +72,7 @@ static const struct clk_ops rk808_clkout2_ops = {
 };
 
 static struct clk_hw *
-of_clk_rk808_get(struct of_phandle_args *clkspec, void *data)
+of_clk_rk808_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct rk808_clkout *rk808_clkout = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c
index 108b697bd317..8125e6ac7916 100644
--- a/drivers/clk/clk-scpi.c
+++ b/drivers/clk/clk-scpi.c
@@ -172,7 +172,7 @@ struct scpi_clk_data {
 };
 
 static struct clk_hw *
-scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data)
+scpi_of_clk_src_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct scpi_clk *sclk;
 	struct scpi_clk_data *clk_data = data;
diff --git a/drivers/clk/clk-si521xx.c b/drivers/clk/clk-si521xx.c
index 4f7b74f889f1..5912bc5ad375 100644
--- a/drivers/clk/clk-si521xx.c
+++ b/drivers/clk/clk-si521xx.c
@@ -269,7 +269,7 @@ static void si521xx_diff_idx_to_reg_bit(const u16 chip_info, const int idx,
 }
 
 static struct clk_hw *
-si521xx_of_clk_get(struct of_phandle_args *clkspec, void *data)
+si521xx_of_clk_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct si521xx *si = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
index 6e8dd7387cfd..4acf1daabcdf 100644
--- a/drivers/clk/clk-si5341.c
+++ b/drivers/clk/clk-si5341.c
@@ -957,7 +957,7 @@ static int si5341_is_programmed_already(struct clk_si5341 *data)
 }
 
 static struct clk_hw *
-of_clk_si5341_get(struct of_phandle_args *clkspec, void *_data)
+of_clk_si5341_get(const struct of_phandle_args *clkspec, void *_data)
 {
 	struct clk_si5341 *data = _data;
 	unsigned int idx = clkspec->args[1];
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 4ce83c5265b8..3b325167c072 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -1390,7 +1390,7 @@ static int si5351_dt_parse(struct i2c_client *client,
 }
 
 static struct clk_hw *
-si53351_of_clk_get(struct of_phandle_args *clkspec, void *data)
+si53351_of_clk_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct si5351_driver_data *drvdata = data;
 	unsigned int idx = clkspec->args[0];
@@ -1409,7 +1409,7 @@ static int si5351_dt_parse(struct i2c_client *client, enum si5351_variant varian
 }
 
 static struct clk_hw *
-si53351_of_clk_get(struct of_phandle_args *clkspec, void *data)
+si53351_of_clk_get(const struct of_phandle_args *clkspec, void *data)
 {
 	return NULL;
 }
diff --git a/drivers/clk/clk-sparx5.c b/drivers/clk/clk-sparx5.c
index 0fad0c1a0186..b352cdc289b6 100644
--- a/drivers/clk/clk-sparx5.c
+++ b/drivers/clk/clk-sparx5.c
@@ -229,7 +229,8 @@ static const struct clk_ops s5_pll_ops = {
 	.recalc_rate	= s5_pll_recalc_rate,
 };
 
-static struct clk_hw *s5_clk_hw_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *s5_clk_hw_get(const struct of_phandle_args *clkspec,
+				    void *data)
 {
 	struct s5_clk_data *s5_clk = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index 07c13ebe327d..daa21cc8851b 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -872,7 +872,7 @@ static int stm32f4_rcc_lookup_clk_idx(u8 primary, u8 secondary)
 }
 
 static struct clk_hw *
-stm32f4_rcc_lookup_clk(struct of_phandle_args *clkspec, void *data)
+stm32f4_rcc_lookup_clk(const struct of_phandle_args *clkspec, void *data)
 {
 	int i = stm32f4_rcc_lookup_clk_idx(clkspec->args[0], clkspec->args[1]);
 
diff --git a/drivers/clk/clk-versaclock3.c b/drivers/clk/clk-versaclock3.c
index 76d7ea1964c3..257160509310 100644
--- a/drivers/clk/clk-versaclock3.c
+++ b/drivers/clk/clk-versaclock3.c
@@ -964,7 +964,7 @@ static struct vc3_hw_data clk_mux[] = {
 	}
 };
 
-static struct clk_hw *vc3_of_clk_get(struct of_phandle_args *clkspec,
+static struct clk_hw *vc3_of_clk_get(const struct of_phandle_args *clkspec,
 				     void *data)
 {
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index 6d31cd54d7cf..9a25e96955bd 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -731,7 +731,7 @@ static const struct clk_ops vc5_clk_out_ops = {
 	.get_parent	= vc5_clk_out_get_parent,
 };
 
-static struct clk_hw *vc5_of_clk_get(struct of_phandle_args *clkspec,
+static struct clk_hw *vc5_of_clk_get(const struct of_phandle_args *clkspec,
 				     void *data)
 {
 	struct vc5_driver_data *vc5 = data;
diff --git a/drivers/clk/clk-versaclock7.c b/drivers/clk/clk-versaclock7.c
index f323263e32c3..8345a946c1ec 100644
--- a/drivers/clk/clk-versaclock7.c
+++ b/drivers/clk/clk-versaclock7.c
@@ -174,7 +174,7 @@ struct vc7_bank_src_map {
 	} src;
 };
 
-static struct clk_hw *vc7_of_clk_get(struct of_phandle_args *clkspec,
+static struct clk_hw *vc7_of_clk_get(const struct of_phandle_args *clkspec,
 				     void *data)
 {
 	struct vc7_driver_data *vc7 = data;
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 2253c154a824..cfb1dfeeb329 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -342,7 +342,7 @@ static struct clk_core *clk_core_lookup(const char *name)
 static int of_parse_clkspec(const struct device_node *np, int index,
 			    const char *name, struct of_phandle_args *out_args);
 static struct clk_hw *
-of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec);
+of_clk_get_hw_from_clkspec(const struct of_phandle_args *clkspec);
 #else
 static inline int of_parse_clkspec(const struct device_node *np, int index,
 				   const char *name,
@@ -351,7 +351,7 @@ static inline int of_parse_clkspec(const struct device_node *np, int index,
 	return -ENOENT;
 }
 static inline struct clk_hw *
-of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
+of_clk_get_hw_from_clkspec(const struct of_phandle_args *clkspec)
 {
 	return ERR_PTR(-ENOENT);
 }
@@ -4818,8 +4818,8 @@ struct of_clk_provider {
 	struct list_head link;
 
 	struct device_node *node;
-	struct clk *(*get)(struct of_phandle_args *clkspec, void *data);
-	struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);
+	struct clk *(*get)(const struct of_phandle_args *clkspec, void *data);
+	struct clk_hw *(*get_hw)(const struct of_phandle_args *clkspec, void *data);
 	void *data;
 };
 
@@ -4830,20 +4830,22 @@ static const struct of_device_id __clk_of_table_sentinel
 static LIST_HEAD(of_clk_providers);
 static DEFINE_MUTEX(of_clk_mutex);
 
-struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
+struct clk *of_clk_src_simple_get(const struct of_phandle_args *clkspec,
 				     void *data)
 {
 	return data;
 }
 EXPORT_SYMBOL_GPL(of_clk_src_simple_get);
 
-struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
+struct clk_hw *of_clk_hw_simple_get(const struct of_phandle_args *clkspec,
+				    void *data)
 {
 	return data;
 }
 EXPORT_SYMBOL_GPL(of_clk_hw_simple_get);
 
-struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
+struct clk *of_clk_src_onecell_get(const struct of_phandle_args *clkspec,
+				   void *data)
 {
 	struct clk_onecell_data *clk_data = data;
 	unsigned int idx = clkspec->args[0];
@@ -4858,7 +4860,7 @@ struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
 EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
 
 struct clk_hw *
-of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
+of_clk_hw_onecell_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct clk_hw_onecell_data *hw_data = data;
 	unsigned int idx = clkspec->args[0];
@@ -4881,7 +4883,7 @@ EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get);
  * This function is *deprecated*. Use of_clk_add_hw_provider() instead.
  */
 int of_clk_add_provider(struct device_node *np,
-			struct clk *(*clk_src_get)(struct of_phandle_args *clkspec,
+			struct clk *(*clk_src_get)(const struct of_phandle_args *clkspec,
 						   void *data),
 			void *data)
 {
@@ -4923,7 +4925,7 @@ EXPORT_SYMBOL_GPL(of_clk_add_provider);
  * @data: context pointer for @get callback.
  */
 int of_clk_add_hw_provider(struct device_node *np,
-			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+			   struct clk_hw *(*get)(const struct of_phandle_args *clkspec,
 						 void *data),
 			   void *data)
 {
@@ -4997,7 +4999,7 @@ static struct device_node *get_clk_provider_node(struct device *dev)
  * Return: 0 on success or an errno on failure.
  */
 int devm_of_clk_add_hw_provider(struct device *dev,
-			struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+			struct clk_hw *(*get)(const struct of_phandle_args *clkspec,
 					      void *data),
 			void *data)
 {
@@ -5123,7 +5125,7 @@ static int of_parse_clkspec(const struct device_node *np, int index,
 
 static struct clk_hw *
 __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
-			      struct of_phandle_args *clkspec)
+			      const struct of_phandle_args *clkspec)
 {
 	struct clk *clk;
 
@@ -5137,7 +5139,7 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
 }
 
 static struct clk_hw *
-of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
+of_clk_get_hw_from_clkspec(const struct of_phandle_args *clkspec)
 {
 	struct of_clk_provider *provider;
 	struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
@@ -5166,7 +5168,7 @@ of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
  * providers, an input is a clock specifier data structure as returned
  * from the of_parse_phandle_with_args() function call.
  */
-struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
+struct clk *of_clk_get_from_provider(const struct of_phandle_args *clkspec)
 {
 	struct clk_hw *hw = of_clk_get_hw_from_clkspec(clkspec);
 
diff --git a/drivers/clk/hisilicon/clk-hi3660-stub.c b/drivers/clk/hisilicon/clk-hi3660-stub.c
index 3a653d54bee0..1dd7fb7cfa5b 100644
--- a/drivers/clk/hisilicon/clk-hi3660-stub.c
+++ b/drivers/clk/hisilicon/clk-hi3660-stub.c
@@ -108,7 +108,7 @@ static struct hi3660_stub_clk hi3660_stub_clks[HI3660_CLK_STUB_NUM] = {
 	DEFINE_CLK_STUB(HI3660_CLK_STUB_DDR, 0x00040309, "clk-ddrc")
 };
 
-static struct clk_hw *hi3660_stub_clk_hw_get(struct of_phandle_args *clkspec,
+static struct clk_hw *hi3660_stub_clk_hw_get(const struct of_phandle_args *clkspec,
 					     void *data)
 {
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c
index d0ccaa040225..feb2e4a61b6c 100644
--- a/drivers/clk/imx/clk-imx8qxp-lpcg.c
+++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c
@@ -159,7 +159,7 @@ static const struct imx8qxp_ss_lpcg imx8qxp_ss_lsio = {
 
 #define IMX_LPCG_MAX_CLKS	8
 
-static struct clk_hw *imx_lpcg_of_clk_src_get(struct of_phandle_args *clkspec,
+static struct clk_hw *imx_lpcg_of_clk_src_get(const struct of_phandle_args *clkspec,
 					      void *data)
 {
 	struct clk_hw_onecell_data *hw_data = data;
diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
index e48a904c0013..d357dc337741 100644
--- a/drivers/clk/imx/clk-scu.c
+++ b/drivers/clk/imx/clk-scu.c
@@ -517,7 +517,7 @@ struct clk_hw *__imx_clk_scu(struct device *dev, const char *name,
 	return hw;
 }
 
-struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec,
+struct clk_hw *imx_scu_of_clk_src_get(const struct of_phandle_args *clkspec,
 				      void *data)
 {
 	unsigned int rsrc = clkspec->args[0];
diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h
index af7b697f51ca..38db6a1905d0 100644
--- a/drivers/clk/imx/clk-scu.h
+++ b/drivers/clk/imx/clk-scu.h
@@ -27,7 +27,7 @@ extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qm;
 
 int imx_clk_scu_init(struct device_node *np,
 		     const struct imx_clk_scu_rsrc_table *data);
-struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec,
+struct clk_hw *imx_scu_of_clk_src_get(const struct of_phandle_args *clkspec,
 				      void *data);
 struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
 				     const char * const *parents,
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 35fe197dd303..ba27fb22f973 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -375,7 +375,8 @@ static int _cmp_sci_clk(const void *a, const void *b)
  * when a corresponding of_clk_get call is executed. Returns a pointer
  * to the TI SCI hw clock struct, or ERR_PTR value in failure.
  */
-static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *sci_clk_get(const struct of_phandle_args *clkspec,
+				  void *data)
 {
 	struct sci_clk_provider *provider = data;
 	struct sci_clk **clk;
diff --git a/drivers/clk/meson/meson-clkc-utils.c b/drivers/clk/meson/meson-clkc-utils.c
index 7370644e8092..904b482bf47b 100644
--- a/drivers/clk/meson/meson-clkc-utils.c
+++ b/drivers/clk/meson/meson-clkc-utils.c
@@ -8,7 +8,8 @@
 #include <linux/module.h>
 #include "meson-clkc-utils.h"
 
-struct clk_hw *meson_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_data)
+struct clk_hw *meson_clk_hw_get(const struct of_phandle_args *clkspec,
+				void *clk_hw_data)
 {
 	const struct meson_clk_hw_data *data = clk_hw_data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/meson/meson-clkc-utils.h b/drivers/clk/meson/meson-clkc-utils.h
index fe6f40728949..3889ead76a07 100644
--- a/drivers/clk/meson/meson-clkc-utils.h
+++ b/drivers/clk/meson/meson-clkc-utils.h
@@ -14,6 +14,7 @@ struct meson_clk_hw_data {
 	unsigned int	num;
 };
 
-struct clk_hw *meson_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_data);
+struct clk_hw *meson_clk_hw_get(const struct of_phandle_args *clkspec,
+				void *clk_hw_data);
 
 #endif
diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c
index 785dbede4835..19cd62152175 100644
--- a/drivers/clk/mvebu/common.c
+++ b/drivers/clk/mvebu/common.c
@@ -199,7 +199,7 @@ struct clk_gating_ctrl {
 static struct clk_gating_ctrl *ctrl;
 
 static struct clk *clk_gating_get_src(
-	struct of_phandle_args *clkspec, void *data)
+	const struct of_phandle_args *clkspec, void *data)
 {
 	int n;
 
diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
index 03c59bf22106..8f6e2dd3e044 100644
--- a/drivers/clk/mvebu/cp110-system-controller.c
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -192,7 +192,7 @@ static void cp110_unregister_gate(struct clk_hw *hw)
 	kfree(to_cp110_gate_clk(hw));
 }
 
-static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec,
+static struct clk_hw *cp110_of_clk_get(const struct of_phandle_args *clkspec,
 				       void *data)
 {
 	struct clk_hw_onecell_data *clk_data = data;
diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c
index 8bc893df4736..b2b9a7a7a8fb 100644
--- a/drivers/clk/mvebu/kirkwood.c
+++ b/drivers/clk/mvebu/kirkwood.c
@@ -269,7 +269,7 @@ static const struct clk_muxing_soc_desc kirkwood_mux_desc[] __initconst = {
 };
 
 static struct clk *clk_muxing_get_src(
-	struct of_phandle_args *clkspec, void *data)
+	const struct of_phandle_args *clkspec, void *data)
 {
 	struct clk_muxing_ctrl *ctrl = (struct clk_muxing_ctrl *)data;
 	int n;
diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c
index ddb28b38f549..3d8299b7e790 100644
--- a/drivers/clk/nxp/clk-lpc18xx-ccu.c
+++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c
@@ -109,7 +109,7 @@ static struct lpc18xx_clk_branch clk_branches[] = {
 	{"base_sdio_clk",  "sdio",		CLK_SDIO,		0},
 };
 
-static struct clk *lpc18xx_ccu_branch_clk_get(struct of_phandle_args *clkspec,
+static struct clk *lpc18xx_ccu_branch_clk_get(const struct of_phandle_args *clkspec,
 					      void *data)
 {
 	struct lpc18xx_branch_clk_data *clk_data = data;
diff --git a/drivers/clk/qcom/clk-rpm.c b/drivers/clk/qcom/clk-rpm.c
index 745026ef4d9c..b7e048237bc0 100644
--- a/drivers/clk/qcom/clk-rpm.c
+++ b/drivers/clk/qcom/clk-rpm.c
@@ -514,7 +514,7 @@ static const struct of_device_id rpm_clk_match_table[] = {
 };
 MODULE_DEVICE_TABLE(of, rpm_clk_match_table);
 
-static struct clk_hw *qcom_rpm_clk_hw_get(struct of_phandle_args *clkspec,
+static struct clk_hw *qcom_rpm_clk_hw_get(const struct of_phandle_args *clkspec,
 					  void *data)
 {
 	struct rpm_cc *rcc = data;
diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c
index bb82abeed88f..8c2c6aa3a793 100644
--- a/drivers/clk/qcom/clk-rpmh.c
+++ b/drivers/clk/qcom/clk-rpmh.c
@@ -793,7 +793,7 @@ static const struct clk_rpmh_desc clk_rpmh_x1e80100 = {
 	.num_clks = ARRAY_SIZE(x1e80100_rpmh_clocks),
 };
 
-static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
+static struct clk_hw *of_clk_rpmh_hw_get(const struct of_phandle_args *clkspec,
 					 void *data)
 {
 	struct clk_rpmh_desc *rpmh = data;
diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c
index 8602c02047d0..5d7e0cd2d450 100644
--- a/drivers/clk/qcom/clk-smd-rpm.c
+++ b/drivers/clk/qcom/clk-smd-rpm.c
@@ -1232,7 +1232,7 @@ static const struct of_device_id rpm_smd_clk_match_table[] = {
 };
 MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
 
-static struct clk_hw *qcom_smdrpm_clk_hw_get(struct of_phandle_args *clkspec,
+static struct clk_hw *qcom_smdrpm_clk_hw_get(const struct of_phandle_args *clkspec,
 					     void *data)
 {
 	const struct rpm_smd_clk_desc *desc = data;
diff --git a/drivers/clk/qcom/clk-spmi-pmic-div.c b/drivers/clk/qcom/clk-spmi-pmic-div.c
index f394031eb0e5..3f65aead519d 100644
--- a/drivers/clk/qcom/clk-spmi-pmic-div.c
+++ b/drivers/clk/qcom/clk-spmi-pmic-div.c
@@ -181,7 +181,7 @@ struct spmi_pmic_div_clk_cc {
 };
 
 static struct clk_hw *
-spmi_pmic_div_clk_hw_get(struct of_phandle_args *clkspec, void *data)
+spmi_pmic_div_clk_hw_get(const struct of_phandle_args *clkspec, void *data)
 {
 	struct spmi_pmic_div_clk_cc *cc = data;
 	int idx = clkspec->args[0] - 1; /* Start at 1 instead of 0 */
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index 75f09e6e057e..0ae6f8ea607a 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -220,7 +220,7 @@ static void qcom_cc_drop_protected(struct device *dev, struct qcom_cc *cc)
 	}
 }
 
-static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec,
+static struct clk_hw *qcom_cc_clk_hw_get(const struct of_phandle_args *clkspec,
 					 void *data)
 {
 	struct qcom_cc *cc = data;
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
index ae325f4e1047..181f4096a506 100644
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -324,7 +324,7 @@ static struct clk_hw *krait_add_clks(struct device *dev, int id, bool unique_aux
 	return pri_mux;
 }
 
-static struct clk *krait_of_get(struct of_phandle_args *clkspec, void *data)
+static struct clk *krait_of_get(const struct of_phandle_args *clkspec, void *data)
 {
 	unsigned int idx = clkspec->args[0];
 	struct clk **clks = data;
diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
index c1348e2d450c..f8ea88663fca 100644
--- a/drivers/clk/renesas/r9a06g032-clocks.c
+++ b/drivers/clk/renesas/r9a06g032-clocks.c
@@ -733,7 +733,7 @@ struct r9a06g032_clk_gate {
 
 #define to_r9a06g032_gate(_hw) container_of(_hw, struct r9a06g032_clk_gate, hw)
 
-static int create_add_module_clock(struct of_phandle_args *clkspec,
+static int create_add_module_clock(const struct of_phandle_args *clkspec,
 				   struct device *dev)
 {
 	struct clk *clk;
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index 1b421b809796..c172444ee766 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -273,7 +273,7 @@ static const struct clk_ops cpg_mstp_clock_ops = {
 };
 
 static
-struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
+struct clk *cpg_mssr_clk_src_twocell_get(const struct of_phandle_args *clkspec,
 					 void *data)
 {
 	unsigned int clkidx = clkspec->args[1];
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index 3d2daa4ba2a4..7464a298b2e5 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -1052,7 +1052,7 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
 }
 
 static struct clk
-*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec,
+*rzg2l_cpg_clk_src_twocell_get(const struct of_phandle_args *clkspec,
 			       void *data)
 {
 	unsigned int clkidx = clkspec->args[1];
diff --git a/drivers/clk/starfive/clk-starfive-jh7100-audio.c b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
index 1fcf4e62f347..79feba75ea43 100644
--- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
+++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
@@ -84,7 +84,8 @@ static const struct jh71x0_clk_data jh7100_audclk_data[] = {
 		    JH7100_AUDCLK_AUDIO_12288),
 };
 
-static struct clk_hw *jh7100_audclk_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *jh7100_audclk_get(const struct of_phandle_args *clkspec,
+					void *data)
 {
 	struct jh71x0_clk_priv *priv = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
index 03f6f26a15d8..b7e43f4847d2 100644
--- a/drivers/clk/starfive/clk-starfive-jh7100.c
+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
@@ -267,7 +267,8 @@ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
 	JH71X0_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
 };
 
-static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *jh7100_clk_get(const struct of_phandle_args *clkspec,
+				     void *data)
 {
 	struct jh71x0_clk_priv *priv = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-aon.c b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
index 418efdad719b..d05da683a544 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-aon.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
@@ -54,7 +54,8 @@ static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
 	JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
 };
 
-static struct clk_hw *jh7110_aonclk_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *jh7110_aonclk_get(const struct of_phandle_args *clkspec,
+					void *data)
 {
 	struct jh71x0_clk_priv *priv = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
index 929b8788279e..518c4a8d4200 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-isp.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
@@ -75,7 +75,8 @@ static inline int jh7110_isp_top_rst_init(struct jh71x0_clk_priv *priv)
 	return reset_control_deassert(top_rsts);
 }
 
-static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *jh7110_ispclk_get(const struct of_phandle_args *clkspec,
+					void *data)
 {
 	struct jh71x0_clk_priv *priv = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-pll.c b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
index 3598390e8fd0..3c53459c554b 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-pll.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
@@ -442,7 +442,8 @@ static const struct clk_ops jh7110_pll_ops = {
 	.debug_init = jh7110_pll_debug_init,
 };
 
-static struct clk_hw *jh7110_pll_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *jh7110_pll_get(const struct of_phandle_args *clkspec,
+				     void *data)
 {
 	struct jh7110_pll_priv *priv = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-stg.c b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
index dafcb7190592..0fba5de830e9 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-stg.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
@@ -75,7 +75,8 @@ static const struct jh71x0_clk_data jh7110_stgclk_data[] = {
 	JH71X0_GATE(JH7110_STGCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
 };
 
-static struct clk_hw *jh7110_stgclk_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *jh7110_stgclk_get(const struct of_phandle_args *clkspec,
+					void *data)
 {
 	struct jh71x0_clk_priv *priv = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
index 8f5e5abfa178..6ea25b959091 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
@@ -323,7 +323,8 @@ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
 		    JH7110_SYSCLK_OSC),
 };
 
-static struct clk_hw *jh7110_sysclk_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *jh7110_sysclk_get(const struct of_phandle_args *clkspec,
+					void *data)
 {
 	struct jh71x0_clk_priv *priv = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
index 10cc1ec43925..7f69a4d75126 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-vout.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
@@ -80,7 +80,8 @@ static int jh7110_vout_top_rst_init(struct jh71x0_clk_priv *priv)
 	return reset_control_deassert(top_rst);
 }
 
-static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *jh7110_voutclk_get(const struct of_phandle_args *clkspec,
+					 void *data)
 {
 	struct jh71x0_clk_priv *priv = data;
 	unsigned int idx = clkspec->args[0];
diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c
index 7bfba0afd778..9c53ab9b8a00 100644
--- a/drivers/clk/tegra/clk-bpmp.c
+++ b/drivers/clk/tegra/clk-bpmp.c
@@ -654,7 +654,7 @@ static void tegra_bpmp_unregister_clocks(struct tegra_bpmp *bpmp)
 		clk_hw_unregister(&bpmp->clocks[i]->hw);
 }
 
-static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec,
+static struct clk_hw *tegra_bpmp_clk_of_xlate(const struct of_phandle_args *clkspec,
 					      void *data)
 {
 	unsigned int id = clkspec->args[0], i;
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 6c46592d794e..87f1e5bc5c0e 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1502,7 +1502,7 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
 	writel(plld_base, clk_base + PLLD_BASE);
 }
 
-static struct clk *tegra124_clk_src_onecell_get(struct of_phandle_args *clkspec,
+static struct clk *tegra124_clk_src_onecell_get(const struct of_phandle_args *clkspec,
 						void *data)
 {
 	struct clk_hw *hw;
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 2c58ce25af75..8a7e17d3379a 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -1069,7 +1069,7 @@ static const struct of_device_id pmc_match[] __initconst = {
 
 static bool tegra20_car_initialized;
 
-static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
+static struct clk *tegra20_clk_src_onecell_get(const struct of_phandle_args *clkspec,
 					       void *data)
 {
 	struct clk_hw *parent_hw;
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index 82a8cb9545eb..4317c68cdeb4 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -1273,7 +1273,7 @@ static struct tegra_audio_clk_info tegra30_audio_plls[] = {
 
 static bool tegra30_car_initialized;
 
-static struct clk *tegra30_clk_src_onecell_get(struct of_phandle_args *clkspec,
+static struct clk *tegra30_clk_src_onecell_get(const struct of_phandle_args *clkspec,
 					       void *data)
 {
 	struct clk_hw *hw;
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c
index 607e34d8e289..31df051c116c 100644
--- a/drivers/clk/ti/clkctrl.c
+++ b/drivers/clk/ti/clkctrl.c
@@ -221,7 +221,7 @@ static const struct clk_ops omap4_clkctrl_clk_ops = {
 	.init		= omap2_init_clk_clkdm,
 };
 
-static struct clk_hw *_ti_omap4_clkctrl_xlate(struct of_phandle_args *clkspec,
+static struct clk_hw *_ti_omap4_clkctrl_xlate(const struct of_phandle_args *clkspec,
 					      void *data)
 {
 	struct omap_clkctrl_provider *provider = data;
diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c
index 8e2f6c65db2a..aba91ca5ca07 100644
--- a/drivers/clk/ux500/u8500_of_clk.c
+++ b/drivers/clk/ux500/u8500_of_clk.c
@@ -26,7 +26,7 @@ static struct clk_hw *clkout_clk[2];
 #define PRCC_KCLK_STORE(clk, base, bit)        \
 	prcc_kclk[(base * PRCC_PERIPHS_PER_CLUSTER) + bit] = clk
 
-static struct clk *ux500_twocell_get(struct of_phandle_args *clkspec,
+static struct clk *ux500_twocell_get(const struct of_phandle_args *clkspec,
 				     void *data)
 {
 	struct clk **clk_data = data;
@@ -71,7 +71,7 @@ static const char * const u8500_clkout_parents[] = {
 	"clk009",
 };
 
-static struct clk_hw *ux500_clkout_get(struct of_phandle_args *clkspec,
+static struct clk_hw *ux500_clkout_get(const struct of_phandle_args *clkspec,
 				       void *data)
 {
 	u32 id, source, divider;
diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c
index 45adac1b4630..5fd21c13f546 100644
--- a/drivers/clk/versatile/clk-sp810.c
+++ b/drivers/clk/versatile/clk-sp810.c
@@ -68,7 +68,7 @@ static const struct clk_ops clk_sp810_timerclken_ops = {
 	.set_parent = clk_sp810_timerclken_set_parent,
 };
 
-static struct clk *clk_sp810_timerclken_of_get(struct of_phandle_args *clkspec,
+static struct clk *clk_sp810_timerclken_of_get(const struct of_phandle_args *clkspec,
 		void *data)
 {
 	struct clk_sp810 *sp810 = data;
diff --git a/drivers/media/platform/ti/omap3isp/isp.c b/drivers/media/platform/ti/omap3isp/isp.c
index 1cda23244c7b..e2c78f9ab797 100644
--- a/drivers/media/platform/ti/omap3isp/isp.c
+++ b/drivers/media/platform/ti/omap3isp/isp.c
@@ -281,7 +281,8 @@ static const struct clk_ops isp_xclk_ops = {
 
 static const char *isp_xclk_parent_name = "cam_mclk";
 
-static struct clk *isp_xclk_src_get(struct of_phandle_args *clkspec, void *data)
+static struct clk *isp_xclk_src_get(const struct of_phandle_args *clkspec,
+				    void *data)
 {
 	unsigned int idx = clkspec->args[0];
 	struct isp_device *isp = data;
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index b6908a03da58..46a77df32dff 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -3136,7 +3136,8 @@ static const struct clk_ops qmp_dp_link_clk_ops = {
 	.recalc_rate	= qmp_dp_link_clk_recalc_rate,
 };
 
-static struct clk_hw *qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *qmp_dp_clks_hw_get(const struct of_phandle_args *clkspec,
+					 void *data)
 {
 	struct qmp_combo *qmp = data;
 	unsigned int idx = clkspec->args[0];
@@ -3177,7 +3178,8 @@ static int phy_dp_clks_register(struct qmp_combo *qmp, struct device_node *np)
 	return 0;
 }
 
-static struct clk_hw *qmp_combo_clk_hw_get(struct of_phandle_args *clkspec, void *data)
+static struct clk_hw *qmp_combo_clk_hw_get(const struct of_phandle_args *clkspec,
+					   void *data)
 {
 	struct qmp_combo *qmp = data;
 
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 1293c38ddb7f..d58313368924 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -1532,25 +1532,25 @@ struct clk_hw_onecell_data {
 
 #ifdef CONFIG_OF
 int of_clk_add_provider(struct device_node *np,
-			struct clk *(*clk_src_get)(struct of_phandle_args *args,
+			struct clk *(*clk_src_get)(const struct of_phandle_args *args,
 						   void *data),
 			void *data);
 int of_clk_add_hw_provider(struct device_node *np,
-			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+			   struct clk_hw *(*get)(const struct of_phandle_args *clkspec,
 						 void *data),
 			   void *data);
 int devm_of_clk_add_hw_provider(struct device *dev,
-			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+			   struct clk_hw *(*get)(const struct of_phandle_args *clkspec,
 						 void *data),
 			   void *data);
 void of_clk_del_provider(struct device_node *np);
 
-struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
+struct clk *of_clk_src_simple_get(const struct of_phandle_args *clkspec,
 				  void *data);
-struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec,
+struct clk_hw *of_clk_hw_simple_get(const struct of_phandle_args *clkspec,
 				    void *data);
-struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data);
-struct clk_hw *of_clk_hw_onecell_get(struct of_phandle_args *clkspec,
+struct clk *of_clk_src_onecell_get(const struct of_phandle_args *clkspec, void *data);
+struct clk_hw *of_clk_hw_onecell_get(const struct of_phandle_args *clkspec,
 				     void *data);
 int of_clk_parent_fill(struct device_node *np, const char **parents,
 		       unsigned int size);
@@ -1560,21 +1560,21 @@ int of_clk_detect_critical(struct device_node *np, int index,
 #else /* !CONFIG_OF */
 
 static inline int of_clk_add_provider(struct device_node *np,
-			struct clk *(*clk_src_get)(struct of_phandle_args *args,
+			struct clk *(*clk_src_get)(const struct of_phandle_args *args,
 						   void *data),
 			void *data)
 {
 	return 0;
 }
 static inline int of_clk_add_hw_provider(struct device_node *np,
-			struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+			struct clk_hw *(*get)(const struct of_phandle_args *clkspec,
 					      void *data),
 			void *data)
 {
 	return 0;
 }
 static inline int devm_of_clk_add_hw_provider(struct device *dev,
-			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+			   struct clk_hw *(*get)(const struct of_phandle_args *clkspec,
 						 void *data),
 			   void *data)
 {
@@ -1583,22 +1583,22 @@ static inline int devm_of_clk_add_hw_provider(struct device *dev,
 static inline void of_clk_del_provider(struct device_node *np) {}
 
 static inline struct clk *of_clk_src_simple_get(
-	struct of_phandle_args *clkspec, void *data)
+	const struct of_phandle_args *clkspec, void *data)
 {
 	return ERR_PTR(-ENOENT);
 }
 static inline struct clk_hw *
-of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
+of_clk_hw_simple_get(const struct of_phandle_args *clkspec, void *data)
 {
 	return ERR_PTR(-ENOENT);
 }
 static inline struct clk *of_clk_src_onecell_get(
-	struct of_phandle_args *clkspec, void *data)
+	const struct of_phandle_args *clkspec, void *data)
 {
 	return ERR_PTR(-ENOENT);
 }
 static inline struct clk_hw *
-of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
+of_clk_hw_onecell_get(const struct of_phandle_args *clkspec, void *data)
 {
 	return ERR_PTR(-ENOENT);
 }
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 06f1b292f8a0..8e3c44ff89da 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -1141,7 +1141,7 @@ static inline struct clk *clk_get_optional(struct device *dev, const char *id)
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
-struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);
+struct clk *of_clk_get_from_provider(const struct of_phandle_args *clkspec);
 #else
 static inline struct clk *of_clk_get(struct device_node *np, int index)
 {
@@ -1152,7 +1152,7 @@ static inline struct clk *of_clk_get_by_name(struct device_node *np,
 {
 	return ERR_PTR(-ENOENT);
 }
-static inline struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
+static inline struct clk *of_clk_get_from_provider(const struct of_phandle_args *clkspec)
 {
 	return ERR_PTR(-ENOENT);
 }
diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
index e758411603be..b846707baa89 100644
--- a/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
+++ b/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
@@ -106,7 +106,7 @@ static const struct clk_ops clk_vote_q6dsp_ops = {
 };
 
 
-static struct clk_hw *q6dsp_of_clk_hw_get(struct of_phandle_args *clkspec,
+static struct clk_hw *q6dsp_of_clk_hw_get(const struct of_phandle_args *clkspec,
 					  void *data)
 {
 	struct q6dsp_cc *cc = data;
-- 
2.34.1



From brgl at bgdev.pl  Thu Feb  8 08:53:50 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 8 Feb 2024 17:53:50 +0100
Subject: [PATCH 01/14] gpio: pca953x: move suspend/resume to suspend_noirq/resume_noirq
In-Reply-To: <95032042-787e-494a-bad9-81b62653de52@bootlin.com>
References: <20240102-j7200-pcie-s2r-v1-0-84e55da52400@bootlin.com>
 <20240102-j7200-pcie-s2r-v1-1-84e55da52400@bootlin.com> <20240116074333.GO5185@atomide.com>
 <31c42f08-7d5e-4b91-87e9-bfc7e2cfdefe@bootlin.com> <CACRpkdYUVbFoDq91uLbUy8twtG_AiD+CY2+nqzCyHV7ZyBC3sA@mail.gmail.com>
 <95032042-787e-494a-bad9-81b62653de52@bootlin.com>
Message-ID: <CAMRc=MfSkuYocKMGyVjqQ5qk=MSkR_W4F5PNs+M6HwBkmjcK0Q@mail.gmail.com>

On Thu, Feb 8, 2024 at 5:19?PM Thomas Richard
<thomas.richard at bootlin.com> wrote:
>
> On 1/28/24 01:12, Linus Walleij wrote:
> > On Fri, Jan 19, 2024 at 6:01?PM Thomas Richard
> > <thomas.richard at bootlin.com> wrote:
> >> On 1/16/24 08:43, Tony Lindgren wrote:
> >>> * Thomas Richard <thomas.richard at bootlin.com> [240115 16:16]:
> >>>> Some IOs can be needed during suspend_noirq/resume_noirq.
> >>>> So move suspend/resume callbacks to noirq.
> >>>
> >>> So have you checked that the pca953x_save_context() and restore works
> >>> this way? There's i2c traffic and regulators may sleep.. I wonder if
> >>> you instead just need to leave gpio-pca953x enabled in some cases
> >>> instead?
> >>>
> >>
> >> Yes I tested it, and it works (with my setup).
> >> But this patch may have an impact for other people.
> >> How could I leave it enabled in some cases ?
> >
> > I guess you could define both pca953x_suspend() and
> > pca953x_suspend_noirq() and selectively bail out on one
> > path on some systems?
>
> Yes.
>
> What do you think if I use a property like for example "ti,pm-noirq" to
> select the right path ?
> Is a property relevant for this use case ?
>

I prefer a new property than calling of_machine_is_compatible().
Please do run it by the DT maintainers, I think it should be fine.
Maybe even don't limit it to TI but make it a generic property.

Bart

> Regards,
>
> >
> > Worst case using if (of_machine_is_compatible("my,machine"))...
> >
> > Yours,
> > Linus Walleij
> --
> Thomas Richard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
>


From afd at ti.com  Thu Feb  8 09:03:57 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:03:57 -0600
Subject: [PATCH v3 06/19] power: reset: tps65086-restart: Remove unneeded device data struct
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-7-afd@ti.com>

We only need one member of the struct tps65086_restart, pass that
tps65086_restart_notify() directly. Remove that struct and its
allocation.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/tps65086-restart.c | 35 ++++++--------------------
 1 file changed, 8 insertions(+), 27 deletions(-)

diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c
index 82d7a761a0385..6976dbcac74fa 100644
--- a/drivers/power/reset/tps65086-restart.c
+++ b/drivers/power/reset/tps65086-restart.c
@@ -9,19 +9,14 @@
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
 
-struct tps65086_restart {
-	struct device *dev;
-};
-
 static int tps65086_restart_notify(struct sys_off_data *data)
 {
-	struct tps65086_restart *tps65086_restart = data->cb_data;
-	struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent);
+	struct tps65086 *tps65086 = data->cb_data;
 	int ret;
 
 	ret = regmap_write(tps65086->regmap, TPS65086_FORCESHUTDN, 1);
 	if (ret) {
-		dev_err(tps65086_restart->dev, "%s: error writing to tps65086 pmic: %d\n",
+		dev_err(tps65086->dev, "%s: error writing to tps65086 pmic: %d\n",
 			__func__, ret);
 		return NOTIFY_DONE;
 	}
@@ -36,27 +31,13 @@ static int tps65086_restart_notify(struct sys_off_data *data)
 
 static int tps65086_restart_probe(struct platform_device *pdev)
 {
-	struct tps65086_restart *tps65086_restart;
-	int ret;
-
-	tps65086_restart = devm_kzalloc(&pdev->dev, sizeof(*tps65086_restart), GFP_KERNEL);
-	if (!tps65086_restart)
-		return -ENOMEM;
-
-	tps65086_restart->dev = &pdev->dev;
-
-	ret = devm_register_sys_off_handler(&pdev->dev,
-					    SYS_OFF_MODE_RESTART,
-					    SYS_OFF_PRIO_HIGH,
-					    tps65086_restart_notify,
-					    tps65086_restart);
-	if (ret) {
-		dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
-			__func__, ret);
-		return -ENODEV;
-	}
+	struct tps65086 *tps65086 = dev_get_drvdata(pdev->dev.parent);
 
-	return 0;
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_RESTART,
+					     SYS_OFF_PRIO_HIGH,
+					     tps65086_restart_notify,
+					     tps65086);
 }
 
 static const struct platform_device_id tps65086_restart_id_table[] = {
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:02 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:02 -0600
Subject: [PATCH v3 11/19] power: reset: mt6323-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-12-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/mt6323-poweroff.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c
index 57a63c0ab7fb7..c663347547f97 100644
--- a/drivers/power/reset/mt6323-poweroff.c
+++ b/drivers/power/reset/mt6323-poweroff.c
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/mfd/mt6397/core.h>
 #include <linux/mfd/mt6397/rtc.h>
+#include <linux/reboot.h>
 
 struct mt6323_pwrc {
 	struct device *dev;
@@ -21,11 +22,9 @@ struct mt6323_pwrc {
 	u32 base;
 };
 
-static struct mt6323_pwrc *mt_pwrc;
-
-static void mt6323_do_pwroff(void)
+static int mt6323_do_pwroff(struct sys_off_data *data)
 {
-	struct mt6323_pwrc *pwrc = mt_pwrc;
+	struct mt6323_pwrc *pwrc = data->cb_data;
 	unsigned int val;
 	int ret;
 
@@ -44,6 +43,8 @@ static void mt6323_do_pwroff(void)
 	mdelay(1000);
 
 	WARN_ONCE(1, "Unable to power off system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int mt6323_pwrc_probe(struct platform_device *pdev)
@@ -51,6 +52,7 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
 	struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
 	struct mt6323_pwrc *pwrc;
 	struct resource *res;
+	int ret;
 
 	pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
 	if (!pwrc)
@@ -63,19 +65,18 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
 	pwrc->base = res->start;
 	pwrc->regmap = mt6397_chip->regmap;
 	pwrc->dev = &pdev->dev;
-	mt_pwrc = pwrc;
 
-	pm_power_off = &mt6323_do_pwroff;
+	ret = devm_register_sys_off_handler(pwrc->dev,
+					    SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    mt6323_do_pwroff,
+					    pwrc);
+	if (ret)
+		return dev_err_probe(pwrc->dev, ret, "failed to register power-off handler\n");
 
 	return 0;
 }
 
-static void mt6323_pwrc_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &mt6323_do_pwroff)
-		pm_power_off = NULL;
-}
-
 static const struct of_device_id mt6323_pwrc_dt_match[] = {
 	{ .compatible = "mediatek,mt6323-pwrc" },
 	{},
@@ -84,7 +85,6 @@ MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match);
 
 static struct platform_driver mt6323_pwrc_driver = {
 	.probe          = mt6323_pwrc_probe,
-	.remove_new     = mt6323_pwrc_remove,
 	.driver         = {
 		.name   = "mt6323-pwrc",
 		.of_match_table = mt6323_pwrc_dt_match,
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:03:55 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:03:55 -0600
Subject: [PATCH v3 04/19] power: reset: xgene-reboot: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-5-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/xgene-reboot.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
index 6b545a83d8889..867162dfe7eae 100644
--- a/drivers/power/reset/xgene-reboot.c
+++ b/drivers/power/reset/xgene-reboot.c
@@ -24,15 +24,11 @@ struct xgene_reboot_context {
 	struct device *dev;
 	void __iomem *csr;
 	u32 mask;
-	struct notifier_block restart_handler;
 };
 
-static int xgene_restart_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int xgene_restart_handler(struct sys_off_data *data)
 {
-	struct xgene_reboot_context *ctx =
-		container_of(this, struct xgene_reboot_context,
-			     restart_handler);
+	struct xgene_reboot_context *ctx = data->cb_data;
 
 	/* Issue the reboot */
 	writel(ctx->mask, ctx->csr);
@@ -64,9 +60,8 @@ static int xgene_reboot_probe(struct platform_device *pdev)
 		ctx->mask = 0xFFFFFFFF;
 
 	ctx->dev = dev;
-	ctx->restart_handler.notifier_call = xgene_restart_handler;
-	ctx->restart_handler.priority = 128;
-	err = register_restart_handler(&ctx->restart_handler);
+	err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, 128,
+					    xgene_restart_handler, ctx);
 	if (err)
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
 
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:00 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:00 -0600
Subject: [PATCH v3 09/19] power: reset: rmobile-reset: Use devm_platform_ioremap_resource() helper
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-10-afd@ti.com>

Use device life-cycle managed ioremap function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/rmobile-reset.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c
index 5df9b41c68c79..29c17ed2d4de9 100644
--- a/drivers/power/reset/rmobile-reset.c
+++ b/drivers/power/reset/rmobile-reset.c
@@ -41,28 +41,23 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 {
 	int error;
 
-	sysc_base2 = of_iomap(pdev->dev.of_node, 1);
-	if (!sysc_base2)
-		return -ENODEV;
+	sysc_base2 = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(sysc_base2))
+		return PTR_ERR(sysc_base2);
 
 	error = register_restart_handler(&rmobile_reset_nb);
 	if (error) {
 		dev_err(&pdev->dev,
 			"cannot register restart handler (err=%d)\n", error);
-		goto fail_unmap;
+		return error;
 	}
 
 	return 0;
-
-fail_unmap:
-	iounmap(sysc_base2);
-	return error;
 }
 
 static void rmobile_reset_remove(struct platform_device *pdev)
 {
 	unregister_restart_handler(&rmobile_reset_nb);
-	iounmap(sysc_base2);
 }
 
 static const struct of_device_id rmobile_reset_of_match[] = {
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:03:52 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:03:52 -0600
Subject: [PATCH v3 01/19] power: reset: atc260x-poweroff: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-2-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/atc260x-poweroff.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/power/reset/atc260x-poweroff.c b/drivers/power/reset/atc260x-poweroff.c
index b4aa50e9685e1..ce2748d3282c3 100644
--- a/drivers/power/reset/atc260x-poweroff.c
+++ b/drivers/power/reset/atc260x-poweroff.c
@@ -16,7 +16,6 @@
 struct atc260x_pwrc {
 	struct device *dev;
 	struct regmap *regmap;
-	struct notifier_block restart_nb;
 	int (*do_poweroff)(const struct atc260x_pwrc *pwrc, bool restart);
 };
 
@@ -172,11 +171,9 @@ static void atc260x_pwrc_pm_handler(void)
 	WARN_ONCE(1, "Unable to power off system\n");
 }
 
-static int atc260x_pwrc_restart_handler(struct notifier_block *nb,
-					unsigned long mode, void *cmd)
+static int atc260x_pwrc_restart_handler(struct sys_off_data *data)
 {
-	struct atc260x_pwrc *pwrc = container_of(nb, struct atc260x_pwrc,
-						 restart_nb);
+	struct atc260x_pwrc *pwrc = data->cb_data;
 	pwrc->do_poweroff(pwrc, true);
 
 	return NOTIFY_DONE;
@@ -194,8 +191,6 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 
 	priv->dev = &pdev->dev;
 	priv->regmap = atc260x->regmap;
-	priv->restart_nb.notifier_call = atc260x_pwrc_restart_handler;
-	priv->restart_nb.priority = 192;
 
 	switch (atc260x->ic_type) {
 	case ATC2603C:
@@ -225,7 +220,11 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 		dev_warn(priv->dev, "Poweroff callback already assigned\n");
 	}
 
-	ret = register_restart_handler(&priv->restart_nb);
+	ret = devm_register_sys_off_handler(priv->dev,
+					    SYS_OFF_MODE_RESTART,
+					    SYS_OFF_PRIO_HIGH,
+					    atc260x_pwrc_restart_handler,
+					    priv);
 	if (ret)
 		dev_err(priv->dev, "failed to register restart handler: %d\n",
 			ret);
@@ -241,8 +240,6 @@ static void atc260x_pwrc_remove(struct platform_device *pdev)
 		pm_power_off = NULL;
 		atc260x_pwrc_data = NULL;
 	}
-
-	unregister_restart_handler(&priv->restart_nb);
 }
 
 static struct platform_driver atc260x_pwrc_driver = {
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:03:58 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:03:58 -0600
Subject: [PATCH v3 07/19] power: reset: brcm-kona-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-8-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/brcm-kona-reset.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/power/reset/brcm-kona-reset.c b/drivers/power/reset/brcm-kona-reset.c
index d05728b1db097..ee3f1bb976530 100644
--- a/drivers/power/reset/brcm-kona-reset.c
+++ b/drivers/power/reset/brcm-kona-reset.c
@@ -15,8 +15,7 @@
 
 static void __iomem *kona_reset_base;
 
-static int kona_reset_handler(struct notifier_block *this,
-				unsigned long mode, void *cmd)
+static int kona_reset_handler(struct sys_off_data *data)
 {
 	/*
 	 * A soft reset is triggered by writing a 0 to bit 0 of the soft reset
@@ -31,18 +30,14 @@ static int kona_reset_handler(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block kona_reset_nb = {
-	.notifier_call = kona_reset_handler,
-	.priority = 128,
-};
-
 static int kona_reset_probe(struct platform_device *pdev)
 {
 	kona_reset_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(kona_reset_base))
 		return PTR_ERR(kona_reset_base);
 
-	return register_restart_handler(&kona_reset_nb);
+	return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+					     128, kona_reset_handler, NULL);
 }
 
 static const struct of_device_id of_match[] = {
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:03:56 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:03:56 -0600
Subject: [PATCH v3 05/19] power: reset: tps65086-restart: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-6-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/tps65086-restart.c | 35 ++++++--------------------
 1 file changed, 7 insertions(+), 28 deletions(-)

diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c
index ee8e9f4b837ea..82d7a761a0385 100644
--- a/drivers/power/reset/tps65086-restart.c
+++ b/drivers/power/reset/tps65086-restart.c
@@ -10,15 +10,12 @@
 #include <linux/reboot.h>
 
 struct tps65086_restart {
-	struct notifier_block handler;
 	struct device *dev;
 };
 
-static int tps65086_restart_notify(struct notifier_block *this,
-				   unsigned long mode, void *cmd)
+static int tps65086_restart_notify(struct sys_off_data *data)
 {
-	struct tps65086_restart *tps65086_restart =
-		container_of(this, struct tps65086_restart, handler);
+	struct tps65086_restart *tps65086_restart = data->cb_data;
 	struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent);
 	int ret;
 
@@ -46,13 +43,13 @@ static int tps65086_restart_probe(struct platform_device *pdev)
 	if (!tps65086_restart)
 		return -ENOMEM;
 
-	platform_set_drvdata(pdev, tps65086_restart);
-
-	tps65086_restart->handler.notifier_call = tps65086_restart_notify;
-	tps65086_restart->handler.priority = 192;
 	tps65086_restart->dev = &pdev->dev;
 
-	ret = register_restart_handler(&tps65086_restart->handler);
+	ret = devm_register_sys_off_handler(&pdev->dev,
+					    SYS_OFF_MODE_RESTART,
+					    SYS_OFF_PRIO_HIGH,
+					    tps65086_restart_notify,
+					    tps65086_restart);
 	if (ret) {
 		dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
 			__func__, ret);
@@ -62,23 +59,6 @@ static int tps65086_restart_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static void tps65086_restart_remove(struct platform_device *pdev)
-{
-	struct tps65086_restart *tps65086_restart = platform_get_drvdata(pdev);
-	int ret;
-
-	ret = unregister_restart_handler(&tps65086_restart->handler);
-	if (ret) {
-		/*
-		 * tps65086_restart_probe() registered the restart handler. So
-		 * unregistering should work fine. Checking the error code
-		 * shouldn't be needed, still doing it for completeness.
-		 */
-		dev_err(&pdev->dev, "%s: cannot unregister restart handler: %d\n",
-			__func__, ret);
-	}
-}
-
 static const struct platform_device_id tps65086_restart_id_table[] = {
 	{ "tps65086-reset", },
 	{ /* sentinel */ }
@@ -90,7 +70,6 @@ static struct platform_driver tps65086_restart_driver = {
 		.name = "tps65086-restart",
 	},
 	.probe = tps65086_restart_probe,
-	.remove_new = tps65086_restart_remove,
 	.id_table = tps65086_restart_id_table,
 };
 module_platform_driver(tps65086_restart_driver);
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:03:51 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:03:51 -0600
Subject: [PATCH v3 00/19] Remove pm_power_off use in drivers/power/reset
Message-ID: <20240208170410.67975-1-afd@ti.com>

Hello all,

Use of pm_power_off is considered legacy and should be replaced with
register_sys_off*(). Same for register_restart_handler(). Do this
for the drivers/power/reset subsystem for all trivial cases.

Thanks,
Andrew

Changes for v3:
 - Use dev_err_probe() in patch [11/19]
 - Add review tags in patches [18/19] and [19/19]

Changes for v2:
 - Fix sparse warning in 7/19 and 10/19
 - Add new patch fixing an already existing sparse warning (3/19)
 - Rebase on v6.8-rc3

Andrew Davis (19):
  power: reset: atc260x-poweroff: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: atc260x-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: xgene-reboot: Use devm_platform_ioremap_resource()
    helper
  power: reset: xgene-reboot: Use devm_register_sys_off_handler(RESTART)
  power: reset: tps65086-restart: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: tps65086-restart: Remove unneeded device data struct
  power: reset: brcm-kona-reset: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: axxia-reset: Use devm_register_sys_off_handler(RESTART)
  power: reset: rmobile-reset: Use devm_platform_ioremap_resource()
    helper
  power: reset: rmobile-reset: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: mt6323-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: msm-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: msm-poweroff: Use devm_register_sys_off_handler(RESTART)
  power: reset: regulator-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: as3722-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: gemini-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: restart-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: syscon-poweroff: Move device data into a struct
  power: reset: syscon-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)

 drivers/power/reset/as3722-poweroff.c    | 30 ++++-------
 drivers/power/reset/atc260x-poweroff.c   | 55 ++++++++------------
 drivers/power/reset/axxia-reset.c        | 16 +++---
 drivers/power/reset/brcm-kona-reset.c    | 11 ++--
 drivers/power/reset/gemini-poweroff.c    | 16 +++---
 drivers/power/reset/msm-poweroff.c       | 25 ++++-----
 drivers/power/reset/mt6323-poweroff.c    | 26 +++++-----
 drivers/power/reset/regulator-poweroff.c | 36 +++++--------
 drivers/power/reset/restart-poweroff.c   | 25 +++------
 drivers/power/reset/rmobile-reset.c      | 35 ++++---------
 drivers/power/reset/syscon-poweroff.c    | 66 ++++++++++++------------
 drivers/power/reset/tps65086-restart.c   | 58 ++++-----------------
 drivers/power/reset/xgene-reboot.c       | 21 +++-----
 13 files changed, 152 insertions(+), 268 deletions(-)

-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:03:53 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:03:53 -0600
Subject: [PATCH v3 02/19] power: reset: atc260x-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-3-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/atc260x-poweroff.c | 38 ++++++++++----------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/drivers/power/reset/atc260x-poweroff.c b/drivers/power/reset/atc260x-poweroff.c
index ce2748d3282c3..e3e4621ccb1dd 100644
--- a/drivers/power/reset/atc260x-poweroff.c
+++ b/drivers/power/reset/atc260x-poweroff.c
@@ -19,9 +19,6 @@ struct atc260x_pwrc {
 	int (*do_poweroff)(const struct atc260x_pwrc *pwrc, bool restart);
 };
 
-/* Global variable needed only for pm_power_off */
-static struct atc260x_pwrc *atc260x_pwrc_data;
-
 static int atc2603c_do_poweroff(const struct atc260x_pwrc *pwrc, bool restart)
 {
 	int ret, deep_sleep = 0;
@@ -164,11 +161,15 @@ static int atc2609a_init(const struct atc260x_pwrc *pwrc)
 	return ret;
 }
 
-static void atc260x_pwrc_pm_handler(void)
+static int atc260x_pwrc_pm_handler(struct sys_off_data *data)
 {
-	atc260x_pwrc_data->do_poweroff(atc260x_pwrc_data, false);
+	struct atc260x_pwrc *pwrc = data->cb_data;
+
+	pwrc->do_poweroff(pwrc, false);
 
 	WARN_ONCE(1, "Unable to power off system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int atc260x_pwrc_restart_handler(struct sys_off_data *data)
@@ -211,14 +212,14 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	platform_set_drvdata(pdev, priv);
-
-	if (!pm_power_off) {
-		atc260x_pwrc_data = priv;
-		pm_power_off = atc260x_pwrc_pm_handler;
-	} else {
-		dev_warn(priv->dev, "Poweroff callback already assigned\n");
-	}
+	ret = devm_register_sys_off_handler(priv->dev,
+					    SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    atc260x_pwrc_pm_handler,
+					    priv);
+	if (ret)
+		dev_err(priv->dev, "failed to register power-off handler: %d\n",
+			ret);
 
 	ret = devm_register_sys_off_handler(priv->dev,
 					    SYS_OFF_MODE_RESTART,
@@ -232,19 +233,8 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static void atc260x_pwrc_remove(struct platform_device *pdev)
-{
-	struct atc260x_pwrc *priv = platform_get_drvdata(pdev);
-
-	if (atc260x_pwrc_data == priv) {
-		pm_power_off = NULL;
-		atc260x_pwrc_data = NULL;
-	}
-}
-
 static struct platform_driver atc260x_pwrc_driver = {
 	.probe = atc260x_pwrc_probe,
-	.remove_new = atc260x_pwrc_remove,
 	.driver = {
 		.name = "atc260x-pwrc",
 	},
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:03:59 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:03:59 -0600
Subject: [PATCH v3 08/19] power: reset: axxia-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-9-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/axxia-reset.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/power/reset/axxia-reset.c b/drivers/power/reset/axxia-reset.c
index 24946766760c3..797bf6773860e 100644
--- a/drivers/power/reset/axxia-reset.c
+++ b/drivers/power/reset/axxia-reset.c
@@ -26,11 +26,10 @@
 #define SC_EFUSE_INT_STATUS	0x180c
 #define   EFUSE_READ_DONE	(1<<31)
 
-static struct regmap *syscon;
-
-static int axxia_restart_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int axxia_restart_handler(struct sys_off_data *data)
 {
+	struct regmap *syscon = data->cb_data;
+
 	/* Access Key (0xab) */
 	regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab);
 	/* Select internal boot from 0xffff0000 */
@@ -44,14 +43,10 @@ static int axxia_restart_handler(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block axxia_restart_nb = {
-	.notifier_call = axxia_restart_handler,
-	.priority = 128,
-};
-
 static int axxia_reset_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct regmap *syscon;
 	int err;
 
 	syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
@@ -60,7 +55,8 @@ static int axxia_reset_probe(struct platform_device *pdev)
 		return PTR_ERR(syscon);
 	}
 
-	err = register_restart_handler(&axxia_restart_nb);
+	err = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+					    128, axxia_restart_handler, syscon);
 	if (err)
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
 
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:03:54 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:03:54 -0600
Subject: [PATCH v3 03/19] power: reset: xgene-reboot: Use devm_platform_ioremap_resource() helper
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-4-afd@ti.com>

Use device life-cycle managed ioremap function to simplify probe and
exit paths.

While here add __iomem to the returned pointer to fix a sparse warning.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/xgene-reboot.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
index c2e5a99940d37..6b545a83d8889 100644
--- a/drivers/power/reset/xgene-reboot.c
+++ b/drivers/power/reset/xgene-reboot.c
@@ -22,7 +22,7 @@
 
 struct xgene_reboot_context {
 	struct device *dev;
-	void *csr;
+	void __iomem *csr;
 	u32 mask;
 	struct notifier_block restart_handler;
 };
@@ -54,7 +54,7 @@ static int xgene_reboot_probe(struct platform_device *pdev)
 	if (!ctx)
 		return -ENOMEM;
 
-	ctx->csr = of_iomap(dev->of_node, 0);
+	ctx->csr = devm_platform_ioremap_resource(pdev, 0);
 	if (!ctx->csr) {
 		dev_err(dev, "can not map resource\n");
 		return -ENODEV;
@@ -67,10 +67,8 @@ static int xgene_reboot_probe(struct platform_device *pdev)
 	ctx->restart_handler.notifier_call = xgene_restart_handler;
 	ctx->restart_handler.priority = 128;
 	err = register_restart_handler(&ctx->restart_handler);
-	if (err) {
-		iounmap(ctx->csr);
+	if (err)
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
-	}
 
 	return err;
 }
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:01 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:01 -0600
Subject: [PATCH v3 10/19] power: reset: rmobile-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-11-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/rmobile-reset.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c
index 29c17ed2d4de9..80265608c18e0 100644
--- a/drivers/power/reset/rmobile-reset.c
+++ b/drivers/power/reset/rmobile-reset.c
@@ -21,22 +21,14 @@
 
 static void __iomem *sysc_base2;
 
-static int rmobile_reset_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int rmobile_reset_handler(struct sys_off_data *data)
 {
-	pr_debug("%s %lu\n", __func__, mode);
-
 	/* Let's assume we have acquired the HPB semaphore */
 	writel(RESCNT2_PRES, sysc_base2 + RESCNT2);
 
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block rmobile_reset_nb = {
-	.notifier_call = rmobile_reset_handler,
-	.priority = 192,
-};
-
 static int rmobile_reset_probe(struct platform_device *pdev)
 {
 	int error;
@@ -45,7 +37,11 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 	if (IS_ERR(sysc_base2))
 		return PTR_ERR(sysc_base2);
 
-	error = register_restart_handler(&rmobile_reset_nb);
+	error = devm_register_sys_off_handler(&pdev->dev,
+					      SYS_OFF_MODE_RESTART,
+					      SYS_OFF_PRIO_HIGH,
+					      rmobile_reset_handler,
+					      NULL);
 	if (error) {
 		dev_err(&pdev->dev,
 			"cannot register restart handler (err=%d)\n", error);
@@ -55,11 +51,6 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static void rmobile_reset_remove(struct platform_device *pdev)
-{
-	unregister_restart_handler(&rmobile_reset_nb);
-}
-
 static const struct of_device_id rmobile_reset_of_match[] = {
 	{ .compatible = "renesas,sysc-rmobile", },
 	{ /* sentinel */ }
@@ -68,7 +59,6 @@ MODULE_DEVICE_TABLE(of, rmobile_reset_of_match);
 
 static struct platform_driver rmobile_reset_driver = {
 	.probe = rmobile_reset_probe,
-	.remove_new = rmobile_reset_remove,
 	.driver = {
 		.name = "rmobile_reset",
 		.of_match_table = rmobile_reset_of_match,
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:05 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:05 -0600
Subject: [PATCH v3 14/19] power: reset: regulator-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-15-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/regulator-poweroff.c | 36 +++++++++---------------
 1 file changed, 13 insertions(+), 23 deletions(-)

diff --git a/drivers/power/reset/regulator-poweroff.c b/drivers/power/reset/regulator-poweroff.c
index 15160809c423a..fed4978e38580 100644
--- a/drivers/power/reset/regulator-poweroff.c
+++ b/drivers/power/reset/regulator-poweroff.c
@@ -13,18 +13,15 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+#include <linux/reboot.h>
 #include <linux/regulator/consumer.h>
 
 #define TIMEOUT_MS 3000
 
-/*
- * Hold configuration here, cannot be more than one instance of the driver
- * since pm_power_off itself is global.
- */
-static struct regulator *cpu_regulator;
-
-static void regulator_poweroff_do_poweroff(void)
+static int regulator_poweroff_do_poweroff(struct sys_off_data *data)
 {
+	struct regulator *cpu_regulator = data->cb_data;
+
 	if (cpu_regulator && regulator_is_enabled(cpu_regulator))
 		regulator_force_disable(cpu_regulator);
 
@@ -32,30 +29,24 @@ static void regulator_poweroff_do_poweroff(void)
 	mdelay(TIMEOUT_MS);
 
 	WARN_ON(1);
+
+	return NOTIFY_DONE;
 }
 
 static int regulator_poweroff_probe(struct platform_device *pdev)
 {
-	/* If a pm_power_off function has already been added, leave it alone */
-	if (pm_power_off != NULL) {
-		dev_err(&pdev->dev,
-			"%s: pm_power_off function already registered\n",
-			__func__);
-		return -EBUSY;
-	}
+	struct regulator *cpu_regulator;
 
 	cpu_regulator = devm_regulator_get(&pdev->dev, "cpu");
 	if (IS_ERR(cpu_regulator))
 		return PTR_ERR(cpu_regulator);
 
-	pm_power_off = &regulator_poweroff_do_poweroff;
-	return 0;
-}
-
-static void regulator_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &regulator_poweroff_do_poweroff)
-		pm_power_off = NULL;
+	/* Set this handler to low priority to not override an existing handler */
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_LOW,
+					     regulator_poweroff_do_poweroff,
+					     cpu_regulator);
 }
 
 static const struct of_device_id of_regulator_poweroff_match[] = {
@@ -66,7 +57,6 @@ MODULE_DEVICE_TABLE(of, of_regulator_poweroff_match);
 
 static struct platform_driver regulator_poweroff_driver = {
 	.probe = regulator_poweroff_probe,
-	.remove_new = regulator_poweroff_remove,
 	.driver = {
 		.name = "poweroff-regulator",
 		.of_match_table = of_regulator_poweroff_match,
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:04 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:04 -0600
Subject: [PATCH v3 13/19] power: reset: msm-poweroff: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-14-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/msm-poweroff.c | 23 ++++++-----------------
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index bcf04491e7022..c5831c46f69e2 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -13,35 +13,24 @@
 #include <linux/reboot.h>
 #include <linux/pm.h>
 
-static void __iomem *msm_ps_hold;
-static int deassert_pshold(struct notifier_block *nb, unsigned long action,
-			   void *data)
+static int do_msm_poweroff(struct sys_off_data *data)
 {
+	void __iomem *msm_ps_hold = data->cb_data;
+
 	writel(0, msm_ps_hold);
 	mdelay(10000);
 
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block restart_nb = {
-	.notifier_call = deassert_pshold,
-	.priority = 128,
-};
-
-static int do_msm_poweroff(struct sys_off_data *data)
-{
-	deassert_pshold(&restart_nb, 0, NULL);
-
-	return NOTIFY_DONE;
-}
-
 static int msm_restart_probe(struct platform_device *pdev)
 {
-	msm_ps_hold = devm_platform_ioremap_resource(pdev, 0);
+	void __iomem *msm_ps_hold = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(msm_ps_hold))
 		return PTR_ERR(msm_ps_hold);
 
-	register_restart_handler(&restart_nb);
+	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+				      128, do_msm_poweroff, msm_ps_hold);
 
 	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
 				      SYS_OFF_PRIO_DEFAULT, do_msm_poweroff,
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:07 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:07 -0600
Subject: [PATCH v3 16/19] power: reset: gemini-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-17-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/gemini-poweroff.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/power/reset/gemini-poweroff.c b/drivers/power/reset/gemini-poweroff.c
index d309b610142ce..06d6992dec892 100644
--- a/drivers/power/reset/gemini-poweroff.c
+++ b/drivers/power/reset/gemini-poweroff.c
@@ -70,12 +70,9 @@ static irqreturn_t gemini_powerbutton_interrupt(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-/* This callback needs this static local as it has void as argument */
-static struct gemini_powercon *gpw_poweroff;
-
-static void gemini_poweroff(void)
+static int gemini_poweroff(struct sys_off_data *data)
 {
-	struct gemini_powercon *gpw = gpw_poweroff;
+	struct gemini_powercon *gpw = data->cb_data;
 	u32 val;
 
 	dev_crit(gpw->dev, "Gemini power off\n");
@@ -86,6 +83,8 @@ static void gemini_poweroff(void)
 	val &= ~GEMINI_CTRL_ENABLE;
 	val |= GEMINI_CTRL_SHUTDOWN;
 	writel(val, gpw->base + GEMINI_PWC_CTRLREG);
+
+	return NOTIFY_DONE;
 }
 
 static int gemini_poweroff_probe(struct platform_device *pdev)
@@ -148,8 +147,11 @@ static int gemini_poweroff_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	pm_power_off = gemini_poweroff;
-	gpw_poweroff = gpw;
+	ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    gemini_poweroff, gpw);
+	if (ret)
+		return ret;
 
 	dev_info(dev, "Gemini poweroff driver registered\n");
 
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:03 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:03 -0600
Subject: [PATCH v3 12/19] power: reset: msm-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-13-afd@ti.com>

Use this helper to register sys_off handler. Drivers should move away from
setting pm_power_off directly as it only allows for one handler. The new
way allows for trying multiple if the first one doesn't work.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/msm-poweroff.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index d96d248a6e25b..bcf04491e7022 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -28,9 +28,11 @@ static struct notifier_block restart_nb = {
 	.priority = 128,
 };
 
-static void do_msm_poweroff(void)
+static int do_msm_poweroff(struct sys_off_data *data)
 {
 	deassert_pshold(&restart_nb, 0, NULL);
+
+	return NOTIFY_DONE;
 }
 
 static int msm_restart_probe(struct platform_device *pdev)
@@ -41,7 +43,9 @@ static int msm_restart_probe(struct platform_device *pdev)
 
 	register_restart_handler(&restart_nb);
 
-	pm_power_off = do_msm_poweroff;
+	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
+				      SYS_OFF_PRIO_DEFAULT, do_msm_poweroff,
+				      msm_ps_hold);
 
 	return 0;
 }
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:08 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:08 -0600
Subject: [PATCH v3 17/19] power: reset: restart-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-18-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/restart-poweroff.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
index f4d6004793d3a..fcd588f9ae9d3 100644
--- a/drivers/power/reset/restart-poweroff.c
+++ b/drivers/power/reset/restart-poweroff.c
@@ -14,29 +14,21 @@
 #include <linux/module.h>
 #include <linux/reboot.h>
 
-static void restart_poweroff_do_poweroff(void)
+static int restart_poweroff_do_poweroff(struct sys_off_data *data)
 {
 	reboot_mode = REBOOT_HARD;
 	machine_restart(NULL);
+	return NOTIFY_DONE;
 }
 
 static int restart_poweroff_probe(struct platform_device *pdev)
 {
-	/* If a pm_power_off function has already been added, leave it alone */
-	if (pm_power_off != NULL) {
-		dev_err(&pdev->dev,
-			"pm_power_off function already registered");
-		return -EBUSY;
-	}
-
-	pm_power_off = &restart_poweroff_do_poweroff;
-	return 0;
-}
-
-static void restart_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &restart_poweroff_do_poweroff)
-		pm_power_off = NULL;
+	/* Set this handler to low priority to not override an existing handler */
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_LOW,
+					     restart_poweroff_do_poweroff,
+					     NULL);
 }
 
 static const struct of_device_id of_restart_poweroff_match[] = {
@@ -47,7 +39,6 @@ MODULE_DEVICE_TABLE(of, of_restart_poweroff_match);
 
 static struct platform_driver restart_poweroff_driver = {
 	.probe = restart_poweroff_probe,
-	.remove_new = restart_poweroff_remove,
 	.driver = {
 		.name = "poweroff-restart",
 		.of_match_table = of_restart_poweroff_match,
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:09 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:09 -0600
Subject: [PATCH v3 18/19] power: reset: syscon-poweroff: Move device data into a struct
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-19-afd@ti.com>

Currently all these device data elements are top level global variables.
Move these into a struct. This will be used in the next patch when
the global variable usage is removed. Doing this in two steps makes
the patches easier to read.

Signed-off-by: Andrew Davis <afd at ti.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/power/reset/syscon-poweroff.c | 36 +++++++++++++++------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
index 1b2ce7734260c..4899a019256e8 100644
--- a/drivers/power/reset/syscon-poweroff.c
+++ b/drivers/power/reset/syscon-poweroff.c
@@ -15,15 +15,19 @@
 #include <linux/pm.h>
 #include <linux/regmap.h>
 
-static struct regmap *map;
-static u32 offset;
-static u32 value;
-static u32 mask;
+struct syscon_poweroff_data {
+	struct regmap *map;
+	u32 offset;
+	u32 value;
+	u32 mask;
+};
+
+static struct syscon_poweroff_data *data;
 
 static void syscon_poweroff(void)
 {
 	/* Issue the poweroff */
-	regmap_update_bits(map, offset, mask, value);
+	regmap_update_bits(data->map, data->offset, data->mask, data->value);
 
 	mdelay(1000);
 
@@ -35,22 +39,22 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	int mask_err, value_err;
 
-	map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
-	if (IS_ERR(map)) {
-		map = syscon_node_to_regmap(dev->parent->of_node);
-		if (IS_ERR(map)) {
+	data->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
+	if (IS_ERR(data->map)) {
+		data->map = syscon_node_to_regmap(dev->parent->of_node);
+		if (IS_ERR(data->map)) {
 			dev_err(dev, "unable to get syscon");
-			return PTR_ERR(map);
+			return PTR_ERR(data->map);
 		}
 	}
 
-	if (of_property_read_u32(dev->of_node, "offset", &offset)) {
+	if (of_property_read_u32(dev->of_node, "offset", &data->offset)) {
 		dev_err(dev, "unable to read 'offset'");
 		return -EINVAL;
 	}
 
-	value_err = of_property_read_u32(dev->of_node, "value", &value);
-	mask_err = of_property_read_u32(dev->of_node, "mask", &mask);
+	value_err = of_property_read_u32(dev->of_node, "value", &data->value);
+	mask_err = of_property_read_u32(dev->of_node, "mask", &data->mask);
 	if (value_err && mask_err) {
 		dev_err(dev, "unable to read 'value' and 'mask'");
 		return -EINVAL;
@@ -58,11 +62,11 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 
 	if (value_err) {
 		/* support old binding */
-		value = mask;
-		mask = 0xFFFFFFFF;
+		data->value = data->mask;
+		data->mask = 0xFFFFFFFF;
 	} else if (mask_err) {
 		/* support value without mask*/
-		mask = 0xFFFFFFFF;
+		data->mask = 0xFFFFFFFF;
 	}
 
 	if (pm_power_off) {
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:10 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:10 -0600
Subject: [PATCH v3 19/19] power: reset: syscon-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-20-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/power/reset/syscon-poweroff.c | 34 ++++++++++++---------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
index 4899a019256e8..203936f4c544f 100644
--- a/drivers/power/reset/syscon-poweroff.c
+++ b/drivers/power/reset/syscon-poweroff.c
@@ -13,6 +13,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+#include <linux/reboot.h>
 #include <linux/regmap.h>
 
 struct syscon_poweroff_data {
@@ -22,23 +23,30 @@ struct syscon_poweroff_data {
 	u32 mask;
 };
 
-static struct syscon_poweroff_data *data;
-
-static void syscon_poweroff(void)
+static int syscon_poweroff(struct sys_off_data *off_data)
 {
+	struct syscon_poweroff_data *data = off_data->cb_data;
+
 	/* Issue the poweroff */
 	regmap_update_bits(data->map, data->offset, data->mask, data->value);
 
 	mdelay(1000);
 
 	pr_emerg("Unable to poweroff system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int syscon_poweroff_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct syscon_poweroff_data *data;
 	int mask_err, value_err;
 
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
 	data->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
 	if (IS_ERR(data->map)) {
 		data->map = syscon_node_to_regmap(dev->parent->of_node);
@@ -69,21 +77,10 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 		data->mask = 0xFFFFFFFF;
 	}
 
-	if (pm_power_off) {
-		dev_err(dev, "pm_power_off already claimed for %ps",
-			pm_power_off);
-		return -EBUSY;
-	}
-
-	pm_power_off = syscon_poweroff;
-
-	return 0;
-}
-
-static void syscon_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == syscon_poweroff)
-		pm_power_off = NULL;
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_DEFAULT,
+					     syscon_poweroff, data);
 }
 
 static const struct of_device_id syscon_poweroff_of_match[] = {
@@ -93,7 +90,6 @@ static const struct of_device_id syscon_poweroff_of_match[] = {
 
 static struct platform_driver syscon_poweroff_driver = {
 	.probe = syscon_poweroff_probe,
-	.remove_new = syscon_poweroff_remove,
 	.driver = {
 		.name = "syscon-poweroff",
 		.of_match_table = syscon_poweroff_of_match,
-- 
2.39.2



From afd at ti.com  Thu Feb  8 09:04:06 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 8 Feb 2024 11:04:06 -0600
Subject: [PATCH v3 15/19] power: reset: as3722-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <20240208170410.67975-16-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/as3722-poweroff.c | 30 ++++++++++-----------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/power/reset/as3722-poweroff.c b/drivers/power/reset/as3722-poweroff.c
index ab3350ce2d621..bb26fa6fa67ca 100644
--- a/drivers/power/reset/as3722-poweroff.c
+++ b/drivers/power/reset/as3722-poweroff.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/slab.h>
 
 struct as3722_poweroff {
@@ -18,22 +19,18 @@ struct as3722_poweroff {
 	struct as3722 *as3722;
 };
 
-static struct as3722_poweroff *as3722_pm_poweroff;
-
-static void as3722_pm_power_off(void)
+static int as3722_pm_power_off(struct sys_off_data *data)
 {
+	struct as3722_poweroff *as3722_pm_poweroff = data->cb_data;
 	int ret;
 
-	if (!as3722_pm_poweroff) {
-		pr_err("AS3722 poweroff is not initialised\n");
-		return;
-	}
-
 	ret = as3722_update_bits(as3722_pm_poweroff->as3722,
 		AS3722_RESET_CONTROL_REG, AS3722_POWER_OFF, AS3722_POWER_OFF);
 	if (ret < 0)
 		dev_err(as3722_pm_poweroff->dev,
 			"RESET_CONTROL_REG update failed, %d\n", ret);
+
+	return NOTIFY_DONE;
 }
 
 static int as3722_poweroff_probe(struct platform_device *pdev)
@@ -54,18 +51,14 @@ static int as3722_poweroff_probe(struct platform_device *pdev)
 
 	as3722_poweroff->as3722 = dev_get_drvdata(pdev->dev.parent);
 	as3722_poweroff->dev = &pdev->dev;
-	as3722_pm_poweroff = as3722_poweroff;
-	if (!pm_power_off)
-		pm_power_off = as3722_pm_power_off;
 
-	return 0;
-}
+	return devm_register_sys_off_handler(as3722_poweroff->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_DEFAULT,
+					     as3722_pm_power_off,
+					     as3722_poweroff);
 
-static void as3722_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == as3722_pm_power_off)
-		pm_power_off = NULL;
-	as3722_pm_poweroff = NULL;
+	return 0;
 }
 
 static struct platform_driver as3722_poweroff_driver = {
@@ -73,7 +66,6 @@ static struct platform_driver as3722_poweroff_driver = {
 		.name = "as3722-power-off",
 	},
 	.probe = as3722_poweroff_probe,
-	.remove_new = as3722_poweroff_remove,
 };
 
 module_platform_driver(as3722_poweroff_driver);
-- 
2.39.2



From alex.williamson at redhat.com  Thu Feb  8 09:30:22 2024
From: alex.williamson at redhat.com (Alex Williamson)
Date: Thu, 8 Feb 2024 10:30:22 -0700
Subject: [PATCH v6 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240207204652.22954-5-ankita@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
	<20240207204652.22954-5-ankita@nvidia.com>
Message-ID: <20240208103022.452a1ba3.alex.williamson@redhat.com>

On Thu, 8 Feb 2024 02:16:52 +0530
<ankita at nvidia.com> wrote:

> From: Ankit Agrawal <ankita at nvidia.com>
> 
> The code to map the MMIO in S2 as NormalNC is enabled when conveyed
> that the device is WC safe using a new flag VM_VFIO_ALLOW_WC.
> 
> Make vfio-pci set the VM_VFIO_ALLOW_WC flag.
> 
> This could be extended to other devices in the future once that
> is deemed safe.
> 
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Acked-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/vfio/pci/vfio_pci_core.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 1cbc990d42e0..c3f95ec7fc3a 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -1863,7 +1863,8 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
>  	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
>  	 * change vm_flags within the fault handler.  Set them now.
>  	 */
> -	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
> +	vm_flags_set(vma, VM_VFIO_ALLOW_WC | VM_IO | VM_PFNMAP |
> +			VM_DONTEXPAND | VM_DONTDUMP);
>  	vma->vm_ops = &vfio_pci_mmap_ops;
>  
>  	return 0;

The comment above this is justifying the flags as equivalent to those
set by the remap_pfn_range() path.  That's no longer the case and the
additional flag needs to be described there.

I'm honestly surprised that a vm_flags bit named so specifically for a
single driver has gotten this far.  It seems like the vfio use case for
this and associated FUD for other use cases could all be encompassed in
the comment where the bit is defined and we could use a name like
VM_ALLOW_ANY_UNCACHED or VM_IO_ANY.  Thanks,

Alex



From mark.rutland at arm.com  Thu Feb  8 09:34:33 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 8 Feb 2024 17:34:33 +0000
Subject: [PATCH v5 00/25] Transparent Contiguous PTEs for User Mappings
In-Reply-To: <20240202080756.1453939-1-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
Message-ID: <ZcUQqfg39zCS2BAv@FVFF77S0Q05N.cambridge.arm.com>

On Fri, Feb 02, 2024 at 08:07:31AM +0000, Ryan Roberts wrote:
> Hi All,

Hi Ryan,

I assume this is the same as your 'features/granule_perf/contpte-lkml_v' branch
on https://gitlab.arm.com/linux-arm/linux-rr/

I've taken a quick look, and I have a few initial/superficial comments before
digging into the detail on the important changes.

> Patch Layout
> ============
> 
> In this version, I've split the patches to better show each optimization:
> 
>   - 1-2:    mm prep: misc code and docs cleanups

I'm not confident enough to comment on patch 2, but these look reasonable to
me.

>   - 3-8:    mm,arm,arm64,powerpc,x86 prep: Replace pte_next_pfn() with more
>             general pte_advance_pfn()

These look fine to me.

>   - 9-18:   arm64 prep: Refactor ptep helpers into new layer

The result of patches 9-17 looks good to me, but the intermediate stages where
some functions are converted is a bit odd, and it's a bit painful for review
since you need to skip ahead a few patches to see the end result to tell that
the conversions are consistent and complete.

IMO it'd be easier for review if that were three patches:

1) Convert READ_ONCE() -> ptep_get()
2) Convert set_pte_at() -> set_ptes()
3) All the "New layer" renames and addition of the trivial wrappers

Patch 18 looks fine to me.

>   - 19:     functional contpte implementation
>   - 20-25:  various optimizations on top of the contpte implementation

I'll try to dig into these over the next few days.

Mark.


From linux at roeck-us.net  Thu Feb  8 09:38:47 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 8 Feb 2024 09:38:47 -0800
Subject: [PATCH v4 2/2] watchdog: s3c2410_wdt: use
 exynos_get_pmu_regmap_by_phandle() for PMU regs
In-Reply-To: <20240208161700.268570-3-peter.griffin@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org>
 <20240208161700.268570-3-peter.griffin@linaro.org>
Message-ID: <a19d2728-c734-4102-8a6b-dbd9e2eba6a0@roeck-us.net>

On 2/8/24 08:17, Peter Griffin wrote:
> Obtain the PMU regmap using the new API added to exynos-pmu driver rather
> than syscon_regmap_lookup_by_phandle(). As this driver no longer depends
> on mfd syscon remove that header and Kconfig dependency.
> 
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>

Acked-by: Guenter Roeck <linux at roeck-us.net>

> ---
>   drivers/watchdog/Kconfig       | 1 -
>   drivers/watchdog/s3c2410_wdt.c | 8 ++++----
>   2 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 7d22051b15a2..d78fe7137799 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -512,7 +512,6 @@ config S3C2410_WATCHDOG
>   	tristate "S3C6410/S5Pv210/Exynos Watchdog"
>   	depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
>   	select WATCHDOG_CORE
> -	select MFD_SYSCON if ARCH_EXYNOS
>   	help
>   	  Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos
>   	  SoCs. This will reboot the system when the timer expires with
> diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
> index 349d30462c8c..686cf544d0ae 100644
> --- a/drivers/watchdog/s3c2410_wdt.c
> +++ b/drivers/watchdog/s3c2410_wdt.c
> @@ -24,9 +24,9 @@
>   #include <linux/slab.h>
>   #include <linux/err.h>
>   #include <linux/of.h>
> -#include <linux/mfd/syscon.h>
>   #include <linux/regmap.h>
>   #include <linux/delay.h>
> +#include <linux/soc/samsung/exynos-pmu.h>
>   
>   #define S3C2410_WTCON		0x00
>   #define S3C2410_WTDAT		0x04
> @@ -699,11 +699,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
>   		return ret;
>   
>   	if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
> -		wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
> -						"samsung,syscon-phandle");
> +		wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node,
> +						 "samsung,syscon-phandle");
>   		if (IS_ERR(wdt->pmureg))
>   			return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
> -					     "syscon regmap lookup failed.\n");
> +					     "PMU regmap lookup failed.\n");
>   	}
>   
>   	wdt_irq = platform_get_irq(pdev, 0);



From semen.protsenko at linaro.org  Thu Feb  8 09:47:07 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 8 Feb 2024 11:47:07 -0600
Subject: [PATCH v4 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <20240208161700.268570-2-peter.griffin@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org> <20240208161700.268570-2-peter.griffin@linaro.org>
Message-ID: <CAPLW+4myUZoGf3hpbp=sFjcKxS_iGQPyv=e84HRrPjEYRMvv=Q@mail.gmail.com>

On Thu, Feb 8, 2024 at 10:21?AM Peter Griffin <peter.griffin at linaro.org> wrote:
>
> Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> security hardening reasons so that they are only write accessible in el3
> via an SMC call.
>
> As most Exynos drivers that need to write PMU registers currently obtain a
> regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> is implemented in this driver using a custom regmap similar to syscon to
> handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> regmap like before. As regmaps abstract out the underlying register access
> changes to the leaf drivers are minimal.
>
> A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> that currently use syscon_regmap_lookup_by_phandle(). This also handles
> deferred probing.
>
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---

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

I'll test it on E850-96 shortly.

> Changes since v3:
>  - Fix PMUALIVE_MASK
>  - Add TENSOR_ prefix
>  - clear SET_BITS bits on each loop iteration
>  - change set_bit to set_bits in func name
>  - Fix some alignment
>  - Add missing return on dev_err_probe
>  - Reduce indentation in loop
>
> Changes since v2
>  - Add select REGMAP to Kconfig
>  - Add constant for SET/CLEAR bits
>  - Replace kerneldoc with one line comment
>  - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
>  - remove superfluous extern keyword
>  - dev_err_probe() on probe error
>  - shorten regmcfg name
>  - no compatibles inside probe, use match data
>  - don't mix declarations with/without initializations
>  - tensor_sec_reg_read() use mmio to avoid access restrictions
>  - Collect up Reviewed-by
>  - const for regmap_config structs
> ---
>  drivers/soc/samsung/Kconfig            |   1 +
>  drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
>  drivers/soc/samsung/exynos-pmu.h       |   1 +
>  include/linux/soc/samsung/exynos-pmu.h |  11 +-
>  4 files changed, 243 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 27ec99af77e3..1a5dfdc978dc 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -42,6 +42,7 @@ config EXYNOS_PMU
>         depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
>         select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
>         select MFD_CORE
> +       select REGMAP_MMIO
>
>  # There is no need to enable these drivers for ARMv8
>  config EXYNOS_PMU_ARM_DRIVERS
> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> index 250537d7cfd6..b846e343fcdd 100644
> --- a/drivers/soc/samsung/exynos-pmu.c
> +++ b/drivers/soc/samsung/exynos-pmu.c
> @@ -5,6 +5,7 @@
>  //
>  // Exynos - CPU PMU(Power Management Unit) support
>
> +#include <linux/arm-smccc.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/mfd/core.h>
> @@ -12,19 +13,132 @@
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/delay.h>
> +#include <linux/regmap.h>
>
>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>  #include <linux/soc/samsung/exynos-pmu.h>
>
>  #include "exynos-pmu.h"
>
> +#define PMUALIVE_MASK                  GENMASK(13, 0)
> +#define TENSOR_SET_BITS                        (BIT(15) | BIT(14))
> +#define TENSOR_CLR_BITS                        BIT(15)
> +#define TENSOR_SMC_PMU_SEC_REG         0x82000504
> +#define TENSOR_PMUREG_READ             0
> +#define TENSOR_PMUREG_WRITE            1
> +#define TENSOR_PMUREG_RMW              2
> +
>  struct exynos_pmu_context {
>         struct device *dev;
>         const struct exynos_pmu_data *pmu_data;
> +       struct regmap *pmureg;
>  };
>
>  void __iomem *pmu_base_addr;
>  static struct exynos_pmu_context *pmu_context;
> +/* forward declaration */
> +static struct platform_driver exynos_pmu_driver;
> +
> +/*
> + * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
> + * from EL3, but are still read accessible. As Linux needs to write some of
> + * these registers, the following functions are provided and exposed via
> + * regmap.
> + *
> + * Note: This SMC interface is known to be implemented on gs101 and derivative
> + * SoCs.
> + */
> +
> +/* Write to a protected PMU register. */
> +static int tensor_sec_reg_write(void *base, unsigned int reg, unsigned int val)
> +{
> +       struct arm_smccc_res res;
> +       unsigned long pmu_base = (unsigned long)base;
> +
> +       arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> +                     TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
> +
> +       /* returns -EINVAL if access isn't allowed or 0 */
> +       if (res.a0)
> +               pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> +
> +       return (int)res.a0;
> +}
> +
> +/* Read/Modify/Write a protected PMU register. */
> +static int tensor_sec_reg_rmw(void *base, unsigned int reg,
> +                             unsigned int mask, unsigned int val)
> +{
> +       struct arm_smccc_res res;
> +       unsigned long pmu_base = (unsigned long)base;
> +
> +       arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> +                     TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
> +
> +       /* returns -EINVAL if access isn't allowed or 0 */
> +       if (res.a0)
> +               pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> +
> +       return (int)res.a0;
> +}
> +
> +/*
> + * Read a protected PMU register. All PMU registers can be read by Linux.
> + * Note: The SMC read register is not used, as only registers that can be
> + * written are readable via SMC.
> + */
> +static int tensor_sec_reg_read(void *base, unsigned int reg, unsigned int *val)
> +{
> +       *val = pmu_raw_readl(reg);
> +       return 0;
> +}
> +
> +/*
> + * For SoCs that have set/clear bit hardware this function can be used when
> + * the PMU register will be accessed by multiple masters.
> + *
> + * For example, to set bits 13:8 in PMU reg offset 0x3e80
> + * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00);
> + *
> + * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80
> + * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00);
> + */
> +static inline int tensor_set_bits_atomic(void *ctx, unsigned int offset,
> +                                        u32 val, u32 mask)
> +{
> +       int ret;
> +       unsigned int i;
> +
> +       for (i = 0; i < 32; i++) {
> +               if (!(mask & BIT(i)))
> +                       continue;
> +
> +               offset &= ~TENSOR_SET_BITS;
> +
> +               if (val & BIT(i))
> +                       offset |= TENSOR_SET_BITS;
> +               else
> +                       offset |= TENSOR_CLR_BITS;
> +
> +               ret = tensor_sec_reg_write(ctx, offset, i);
> +               if (ret)
> +                       return ret;
> +       }
> +       return ret;
> +}
> +
> +static int tensor_sec_update_bits(void *ctx, unsigned int reg,
> +                                 unsigned int mask, unsigned int val)
> +{
> +       /*
> +        * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
> +        * as the target registers can be accessed by multiple masters.
> +        */
> +       if (reg > PMUALIVE_MASK)
> +               return tensor_sec_reg_rmw(ctx, reg, mask, val);
> +
> +       return tensor_set_bits_atomic(ctx, reg, val, mask);
> +}
>
>  void pmu_raw_writel(u32 val, u32 offset)
>  {
> @@ -75,11 +189,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
>  #define exynos_pmu_data_arm_ptr(data)  NULL
>  #endif
>
> +static const struct regmap_config regmap_smccfg = {
> +       .name = "pmu_regs",
> +       .reg_bits = 32,
> +       .reg_stride = 4,
> +       .val_bits = 32,
> +       .fast_io = true,
> +       .use_single_read = true,
> +       .use_single_write = true,
> +       .reg_read = tensor_sec_reg_read,
> +       .reg_write = tensor_sec_reg_write,
> +       .reg_update_bits = tensor_sec_update_bits,
> +};
> +
> +static const struct regmap_config regmap_mmiocfg = {
> +       .name = "pmu_regs",
> +       .reg_bits = 32,
> +       .reg_stride = 4,
> +       .val_bits = 32,
> +       .fast_io = true,
> +       .use_single_read = true,
> +       .use_single_write = true,
> +};
> +
> +static const struct exynos_pmu_data gs101_pmu_data = {
> +       .pmu_secure = true
> +};
> +
>  /*
>   * PMU platform driver and devicetree bindings.
>   */
>  static const struct of_device_id exynos_pmu_of_device_ids[] = {
>         {
> +               .compatible = "google,gs101-pmu",
> +               .data = &gs101_pmu_data,
> +       }, {
>                 .compatible = "samsung,exynos3250-pmu",
>                 .data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
>         }, {
> @@ -113,19 +257,73 @@ static const struct mfd_cell exynos_pmu_devs[] = {
>         { .name = "exynos-clkout", },
>  };
>
> +/**
> + * exynos_get_pmu_regmap() - Obtain pmureg regmap
> + *
> + * Find the pmureg regmap previously configured in probe() and return regmap
> + * pointer.
> + *
> + * Return: A pointer to regmap if found or ERR_PTR error value.
> + */
>  struct regmap *exynos_get_pmu_regmap(void)
>  {
>         struct device_node *np = of_find_matching_node(NULL,
>                                                       exynos_pmu_of_device_ids);
>         if (np)
> -               return syscon_node_to_regmap(np);
> +               return exynos_get_pmu_regmap_by_phandle(np, NULL);
>         return ERR_PTR(-ENODEV);
>  }
>  EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
>
> +/**
> + * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
> + * @np: Pointer to device's Device Tree node
> + * @property: Device Tree property name which references the pmu
> + *
> + * Find the pmureg regmap previously configured in probe() and return regmap
> + * pointer.
> + *
> + * Return: A pointer to regmap if found or ERR_PTR error value.
> + */
> +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> +                                               const char *property)
> +{
> +       struct device *dev;
> +       struct exynos_pmu_context *ctx;
> +       struct device_node *pmu_np;
> +
> +       if (property)
> +               pmu_np = of_parse_phandle(np, property, 0);
> +       else
> +               pmu_np = np;
> +
> +       if (!pmu_np)
> +               return ERR_PTR(-ENODEV);
> +
> +       /*
> +        * Determine if exynos-pmu device has probed and therefore regmap
> +        * has been created and can be returned to the caller. Otherwise we
> +        * return -EPROBE_DEFER.
> +        */
> +       dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
> +                                           (void *)pmu_np);
> +
> +       of_node_put(pmu_np);
> +       if (!dev)
> +               return ERR_PTR(-EPROBE_DEFER);
> +
> +       ctx = dev_get_drvdata(dev);
> +
> +       return ctx->pmureg;
> +}
> +EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
> +
>  static int exynos_pmu_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> +       struct regmap_config pmu_regmcfg;
> +       struct regmap *regmap;
> +       struct resource *res;
>         int ret;
>
>         pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
> @@ -133,13 +331,42 @@ static int exynos_pmu_probe(struct platform_device *pdev)
>                 return PTR_ERR(pmu_base_addr);
>
>         pmu_context = devm_kzalloc(&pdev->dev,
> -                       sizeof(struct exynos_pmu_context),
> -                       GFP_KERNEL);
> +                                  sizeof(struct exynos_pmu_context),
> +                                  GFP_KERNEL);
>         if (!pmu_context)
>                 return -ENOMEM;
> -       pmu_context->dev = dev;
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!res)
> +               return -ENODEV;
> +
>         pmu_context->pmu_data = of_device_get_match_data(dev);
>
> +       /* For SoCs that secure PMU register writes use custom regmap */
> +       if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_secure) {
> +               pmu_regmcfg = regmap_smccfg;
> +               pmu_regmcfg.max_register = resource_size(res) -
> +                                          pmu_regmcfg.reg_stride;
> +               /* Need physical address for SMC call */
> +               regmap = devm_regmap_init(dev, NULL,
> +                                         (void *)(uintptr_t)res->start,
> +                                         &pmu_regmcfg);
> +       } else {
> +               /* All other SoCs use a MMIO regmap */
> +               pmu_regmcfg = regmap_mmiocfg;
> +               pmu_regmcfg.max_register = resource_size(res) -
> +                                          pmu_regmcfg.reg_stride;
> +               regmap = devm_regmap_init_mmio(dev, pmu_base_addr,
> +                                              &pmu_regmcfg);
> +       }
> +
> +       if (IS_ERR(regmap))
> +               return dev_err_probe(&pdev->dev, PTR_ERR(regmap),
> +                                    "regmap init failed\n");
> +
> +       pmu_context->pmureg = regmap;
> +       pmu_context->dev = dev;
> +
>         if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init)
>                 pmu_context->pmu_data->pmu_init();
>
> diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
> index 1c652ffd79b4..0a49a2c9a08e 100644
> --- a/drivers/soc/samsung/exynos-pmu.h
> +++ b/drivers/soc/samsung/exynos-pmu.h
> @@ -21,6 +21,7 @@ struct exynos_pmu_conf {
>  struct exynos_pmu_data {
>         const struct exynos_pmu_conf *pmu_config;
>         const struct exynos_pmu_conf *pmu_config_extra;
> +       bool pmu_secure;
>
>         void (*pmu_init)(void);
>         void (*powerdown_conf)(enum sys_powerdown);
> diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
> index a4f5516cc956..e1c86640f6f7 100644
> --- a/include/linux/soc/samsung/exynos-pmu.h
> +++ b/include/linux/soc/samsung/exynos-pmu.h
> @@ -10,6 +10,7 @@
>  #define __LINUX_SOC_EXYNOS_PMU_H
>
>  struct regmap;
> +struct device_node;
>
>  enum sys_powerdown {
>         SYS_AFTR,
> @@ -20,12 +21,20 @@ enum sys_powerdown {
>
>  extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
>  #ifdef CONFIG_EXYNOS_PMU
> -extern struct regmap *exynos_get_pmu_regmap(void);
> +struct regmap *exynos_get_pmu_regmap(void);
> +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> +                                               const char *property);
>  #else
>  static inline struct regmap *exynos_get_pmu_regmap(void)
>  {
>         return ERR_PTR(-ENODEV);
>  }
> +
> +static inline struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> +                                                             const char *property)
> +{
> +       return ERR_PTR(-ENODEV);
> +}
>  #endif
>
>  #endif /* __LINUX_SOC_EXYNOS_PMU_H */
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From jgg at nvidia.com  Thu Feb  8 09:54:37 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 8 Feb 2024 13:54:37 -0400
Subject: [PATCH v6 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240208103022.452a1ba3.alex.williamson@redhat.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-5-ankita@nvidia.com>
 <20240208103022.452a1ba3.alex.williamson@redhat.com>
Message-ID: <20240208175437.GN10476@nvidia.com>

On Thu, Feb 08, 2024 at 10:30:22AM -0700, Alex Williamson wrote:
> On Thu, 8 Feb 2024 02:16:52 +0530
> <ankita at nvidia.com> wrote:
> 
> > From: Ankit Agrawal <ankita at nvidia.com>
> > 
> > The code to map the MMIO in S2 as NormalNC is enabled when conveyed
> > that the device is WC safe using a new flag VM_VFIO_ALLOW_WC.
> > 
> > Make vfio-pci set the VM_VFIO_ALLOW_WC flag.
> > 
> > This could be extended to other devices in the future once that
> > is deemed safe.
> > 
> > Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> > Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> > Acked-by: Jason Gunthorpe <jgg at nvidia.com>
> > ---
> >  drivers/vfio/pci/vfio_pci_core.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> > index 1cbc990d42e0..c3f95ec7fc3a 100644
> > --- a/drivers/vfio/pci/vfio_pci_core.c
> > +++ b/drivers/vfio/pci/vfio_pci_core.c
> > @@ -1863,7 +1863,8 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
> >  	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
> >  	 * change vm_flags within the fault handler.  Set them now.
> >  	 */
> > -	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
> > +	vm_flags_set(vma, VM_VFIO_ALLOW_WC | VM_IO | VM_PFNMAP |
> > +			VM_DONTEXPAND | VM_DONTDUMP);
> >  	vma->vm_ops = &vfio_pci_mmap_ops;
> >  
> >  	return 0;
> 
> The comment above this is justifying the flags as equivalent to those
> set by the remap_pfn_range() path.  That's no longer the case and the
> additional flag needs to be described there.
> 
> I'm honestly surprised that a vm_flags bit named so specifically for a
> single driver has gotten this far.  

IIRC there was a small bike shed and this is what we came up
with. Realistically it should not be used by anything but VFIO and KVM
together. Generic names do sometimes invite abuse :)

> It seems like the vfio use case for
> this and associated FUD for other use cases could all be encompassed
> in

I think Ankit is talking about vfio-platform drivers by "other
devices".

This is largely why it exists at all, there is a fear that the non-PCI
VFIO devices will not be implemented the same as the PCI devices. If
any platform devices have workloads that require WC and have HW that
is safe then they will set the flag somehow in the vfio platform
drivers.

> the comment where the bit is defined and we could use a name like
> VM_ALLOW_ANY_UNCACHED or VM_IO_ANY.  Thanks,

I'd pick VM_ALLOW_ANY_UNCACHED of those two

Thanks,
Jason


From conor at kernel.org  Thu Feb  8 10:06:00 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 8 Feb 2024 18:06:00 +0000
Subject: [PATCH v9 2/4] dt-bindings: stm32: update DT bingding for
 stm32mp25
In-Reply-To: <20240208142301.155698-3-gabriel.fernandez@foss.st.com>
References: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
 <20240208142301.155698-3-gabriel.fernandez@foss.st.com>
Message-ID: <20240208-syndrome-storeroom-5cc8bdd07c05@spud>

On Thu, Feb 08, 2024 at 03:22:59PM +0100, gabriel.fernandez at foss.st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> 
> Now RCC driver use '.index' of clk_parent_data struct to define a parent.

The RCC driver in linux might have stopped using the names, but they
were a required property that could be replied upon by other software
too. Have you checked U-Boot or *BSD etc to make sure clock-names are
not used there?

Thanks,
Conor.

> The majority of parents are SCMI clocks, then dt-bindings must be fixed.
> 
> Fixes: b5be49db3d47 ("dt-bindings: stm32: add clocks and reset binding for stm32mp25 platform")
> 
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> ---
>  .../bindings/clock/st,stm32mp25-rcc.yaml      | 171 ++++++++++++++++--
>  1 file changed, 155 insertions(+), 16 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml b/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml
> index 7732e79a42b9..57bd4e7157bd 100644
> --- a/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml
> +++ b/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml
> @@ -38,22 +38,87 @@ properties:
>        - description: CK_SCMI_MSI Low Power Internal oscillator (~ 4 MHz or ~ 16 MHz)
>        - description: CK_SCMI_LSE Low Speed External oscillator (32 KHz)
>        - description: CK_SCMI_LSI Low Speed Internal oscillator (~ 32 KHz)
> -
> -  clock-names:
> -    items:
> -      - const: hse
> -      - const: hsi
> -      - const: msi
> -      - const: lse
> -      - const: lsi
> -
> +      - description: CK_SCMI_HSE_DIV2 CK_SCMI_HSE divided by 2 (coud be gated)
> +      - description: CK_SCMI_ICN_HS_MCU High Speed interconnect bus clock
> +      - description: CK_SCMI_ICN_LS_MCU Low Speed interconnect bus clock
> +      - description: CK_SCMI_ICN_SDMMC SDMMC interconnect bus clock
> +      - description: CK_SCMI_ICN_DDR DDR interconnect bus clock
> +      - description: CK_SCMI_ICN_DISPLAY Display interconnect bus clock
> +      - description: CK_SCMI_ICN_HSL HSL interconnect bus clock
> +      - description: CK_SCMI_ICN_NIC NIC interconnect bus clock
> +      - description: CK_SCMI_ICN_VID Video interconnect bus clock
> +      - description: CK_SCMI_FLEXGEN_07 flexgen clock 7
> +      - description: CK_SCMI_FLEXGEN_08 flexgen clock 8
> +      - description: CK_SCMI_FLEXGEN_09 flexgen clock 9
> +      - description: CK_SCMI_FLEXGEN_10 flexgen clock 10
> +      - description: CK_SCMI_FLEXGEN_11 flexgen clock 11
> +      - description: CK_SCMI_FLEXGEN_12 flexgen clock 12
> +      - description: CK_SCMI_FLEXGEN_13 flexgen clock 13
> +      - description: CK_SCMI_FLEXGEN_14 flexgen clock 14
> +      - description: CK_SCMI_FLEXGEN_15 flexgen clock 15
> +      - description: CK_SCMI_FLEXGEN_16 flexgen clock 16
> +      - description: CK_SCMI_FLEXGEN_17 flexgen clock 17
> +      - description: CK_SCMI_FLEXGEN_18 flexgen clock 18
> +      - description: CK_SCMI_FLEXGEN_19 flexgen clock 19
> +      - description: CK_SCMI_FLEXGEN_20 flexgen clock 20
> +      - description: CK_SCMI_FLEXGEN_21 flexgen clock 21
> +      - description: CK_SCMI_FLEXGEN_22 flexgen clock 22
> +      - description: CK_SCMI_FLEXGEN_23 flexgen clock 23
> +      - description: CK_SCMI_FLEXGEN_24 flexgen clock 24
> +      - description: CK_SCMI_FLEXGEN_25 flexgen clock 25
> +      - description: CK_SCMI_FLEXGEN_26 flexgen clock 26
> +      - description: CK_SCMI_FLEXGEN_27 flexgen clock 27
> +      - description: CK_SCMI_FLEXGEN_28 flexgen clock 28
> +      - description: CK_SCMI_FLEXGEN_29 flexgen clock 29
> +      - description: CK_SCMI_FLEXGEN_30 flexgen clock 30
> +      - description: CK_SCMI_FLEXGEN_31 flexgen clock 31
> +      - description: CK_SCMI_FLEXGEN_32 flexgen clock 32
> +      - description: CK_SCMI_FLEXGEN_33 flexgen clock 33
> +      - description: CK_SCMI_FLEXGEN_34 flexgen clock 34
> +      - description: CK_SCMI_FLEXGEN_35 flexgen clock 35
> +      - description: CK_SCMI_FLEXGEN_36 flexgen clock 36
> +      - description: CK_SCMI_FLEXGEN_37 flexgen clock 37
> +      - description: CK_SCMI_FLEXGEN_38 flexgen clock 38
> +      - description: CK_SCMI_FLEXGEN_39 flexgen clock 39
> +      - description: CK_SCMI_FLEXGEN_40 flexgen clock 40
> +      - description: CK_SCMI_FLEXGEN_41 flexgen clock 41
> +      - description: CK_SCMI_FLEXGEN_42 flexgen clock 42
> +      - description: CK_SCMI_FLEXGEN_43 flexgen clock 43
> +      - description: CK_SCMI_FLEXGEN_44 flexgen clock 44
> +      - description: CK_SCMI_FLEXGEN_45 flexgen clock 45
> +      - description: CK_SCMI_FLEXGEN_46 flexgen clock 46
> +      - description: CK_SCMI_FLEXGEN_47 flexgen clock 47
> +      - description: CK_SCMI_FLEXGEN_48 flexgen clock 48
> +      - description: CK_SCMI_FLEXGEN_49 flexgen clock 49
> +      - description: CK_SCMI_FLEXGEN_50 flexgen clock 50
> +      - description: CK_SCMI_FLEXGEN_51 flexgen clock 51
> +      - description: CK_SCMI_FLEXGEN_52 flexgen clock 52
> +      - description: CK_SCMI_FLEXGEN_53 flexgen clock 53
> +      - description: CK_SCMI_FLEXGEN_54 flexgen clock 54
> +      - description: CK_SCMI_FLEXGEN_55 flexgen clock 55
> +      - description: CK_SCMI_FLEXGEN_56 flexgen clock 56
> +      - description: CK_SCMI_FLEXGEN_57 flexgen clock 57
> +      - description: CK_SCMI_FLEXGEN_58 flexgen clock 58
> +      - description: CK_SCMI_FLEXGEN_59 flexgen clock 59
> +      - description: CK_SCMI_FLEXGEN_60 flexgen clock 60
> +      - description: CK_SCMI_FLEXGEN_61 flexgen clock 61
> +      - description: CK_SCMI_FLEXGEN_62 flexgen clock 62
> +      - description: CK_SCMI_FLEXGEN_63 flexgen clock 63
> +      - description: CK_SCMI_ICN_APB1 Peripheral bridge 1
> +      - description: CK_SCMI_ICN_APB2 Peripheral bridge 2
> +      - description: CK_SCMI_ICN_APB3 Peripheral bridge 3
> +      - description: CK_SCMI_ICN_APB4 Peripheral bridge 4
> +      - description: CK_SCMI_ICN_APBDBG Peripheral bridge for degub
> +      - description: CK_SCMI_TIMG1 Peripheral bridge for timer1
> +      - description: CK_SCMI_TIMG2 Peripheral bridge for timer2
> +      - description: CK_SCMI_PLL3 PLL3 clock
> +      - description: clk_dsi_txbyte DSI byte clock
>  required:
>    - compatible
>    - reg
>    - '#clock-cells'
>    - '#reset-cells'
>    - clocks
> -  - clock-names
>  
>  additionalProperties: false
>  
> @@ -66,11 +131,85 @@ examples:
>          reg = <0x44200000 0x10000>;
>          #clock-cells = <1>;
>          #reset-cells = <1>;
> -        clock-names = "hse", "hsi", "msi", "lse", "lsi";
> -        clocks = <&scmi_clk CK_SCMI_HSE>,
> -                 <&scmi_clk CK_SCMI_HSI>,
> -                 <&scmi_clk CK_SCMI_MSI>,
> -                 <&scmi_clk CK_SCMI_LSE>,
> -                 <&scmi_clk CK_SCMI_LSI>;
> +        clocks =  <&scmi_clk CK_SCMI_HSE>,
> +                  <&scmi_clk CK_SCMI_HSI>,
> +                  <&scmi_clk CK_SCMI_MSI>,
> +                  <&scmi_clk CK_SCMI_LSE>,
> +                  <&scmi_clk CK_SCMI_LSI>,
> +                  <&scmi_clk CK_SCMI_HSE_DIV2>,
> +                  <&scmi_clk CK_SCMI_ICN_HS_MCU>,
> +                  <&scmi_clk CK_SCMI_ICN_LS_MCU>,
> +                  <&scmi_clk CK_SCMI_ICN_SDMMC>,
> +                  <&scmi_clk CK_SCMI_ICN_DDR>,
> +                  <&scmi_clk CK_SCMI_ICN_DISPLAY>,
> +                  <&scmi_clk CK_SCMI_ICN_HSL>,
> +                  <&scmi_clk CK_SCMI_ICN_NIC>,
> +                  <&scmi_clk CK_SCMI_ICN_VID>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_07>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_08>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_09>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_10>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_11>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_12>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_13>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_14>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_15>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_16>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_17>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_18>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_19>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_20>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_21>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_22>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_23>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_24>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_25>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_26>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_27>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_28>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_29>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_30>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_31>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_32>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_33>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_34>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_35>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_36>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_37>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_38>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_39>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_40>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_41>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_42>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_43>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_44>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_45>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_46>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_47>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_48>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_49>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_50>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_51>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_52>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_53>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_54>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_55>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_56>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_57>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_58>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_59>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_60>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_61>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_62>,
> +                  <&scmi_clk CK_SCMI_FLEXGEN_63>,
> +                  <&scmi_clk CK_SCMI_ICN_APB1>,
> +                  <&scmi_clk CK_SCMI_ICN_APB2>,
> +                  <&scmi_clk CK_SCMI_ICN_APB3>,
> +                  <&scmi_clk CK_SCMI_ICN_APB4>,
> +                  <&scmi_clk CK_SCMI_ICN_APBDBG>,
> +                  <&scmi_clk CK_SCMI_TIMG1>,
> +                  <&scmi_clk CK_SCMI_TIMG2>,
> +                  <&scmi_clk CK_SCMI_PLL3>,
> +                  <&clk_dsi_txbyte>;
>      };
>  ...
> -- 
> 2.25.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/20240208/36e4d866/attachment.sig>

From conor at kernel.org  Thu Feb  8 10:24:12 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 8 Feb 2024 18:24:12 +0000
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth``
 property
In-Reply-To: <20240208135045.3728927-2-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
 <20240208135045.3728927-2-tudor.ambarus@linaro.org>
Message-ID: <20240208-grating-legwarmer-0a04cfb04d61@spud>

On Thu, Feb 08, 2024 at 01:50:34PM +0000, Tudor Ambarus wrote:
> There are instances of the same IP that are configured by the integrator
> with different FIFO depths. Introduce the fifo-depth property to allow
> such nodes to specify their FIFO depth.
> 
> We haven't seen SPI IPs with different FIFO depths for RX and TX, thus
> introduce a single property.

Some citation attached to this would be nice. "We haven't seen" offers
no detail as to what IPs that allow this sort of configuration of FIFO
size that you have actually checked.

I went and checked our IP that we use in FPGA fabric, which has a
configurable fifo depth. It only has a single knob for both RX and TX
FIFOs. The Xilinx xps spi core also has configurable FIFOs, but again RX
and TX sizes are tied there. At least that's a sample size of three.

One of our guys is working on support for the IP I just mentioned and
would be defining a vendor property for this, so
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Thanks,
Conor.

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  Documentation/devicetree/bindings/spi/spi-controller.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml
> index 524f6fe8c27b..99272e6f115e 100644
> --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml
> +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml
> @@ -69,6 +69,11 @@ properties:
>           Should be generally avoided and be replaced by
>           spi-cs-high + ACTIVE_HIGH.
>  
> +  fifo-depth:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Size of the data FIFO in bytes.
> +
>    num-cs:
>      $ref: /schemas/types.yaml#/definitions/uint32
>      description:
> -- 
> 2.43.0.687.g38aa6559b0-goog
> 
-------------- 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/20240208/b2ecb163/attachment-0001.sig>

From urezki at gmail.com  Thu Feb  8 10:27:39 2024
From: urezki at gmail.com (Uladzislau Rezki)
Date: Thu, 8 Feb 2024 19:27:39 +0100
Subject: [PATCH] scripts/gdb/vmalloc: fix vmallocinfo error
In-Reply-To: <20240207155929.cc107bcc14b982789bdc9fab@linux-foundation.org>
References: <20240207085856.11190-1-Kuan-Ying.Lee@mediatek.com>
 <20240207155623.a943328ba0b77859246e0d9f@linux-foundation.org>
 <20240207155929.cc107bcc14b982789bdc9fab@linux-foundation.org>
Message-ID: <ZcUdG5snmTW1ldx3@pc636>

On Wed, Feb 07, 2024 at 03:59:29PM -0800, Andrew Morton wrote:
> On Wed, 7 Feb 2024 15:56:23 -0800 Andrew Morton <akpm at linux-foundation.org> wrote:
> 
> > > [1] https://lore.kernel.org/linux-mm/20240102184633.748113-1-urezki at gmail.com/
> > 
> > vmap_area_list was removed by https://lkml.kernel.org/r/20240102184633.748113-6-urezki at gmail.com
> > 
> > So I think this patch is actually a fix against mm.git:mm-unstable's
> > mm-vmalloc-remove-vmap_area_list.patch?
> > 
> > However this gdb function was probably probably broken earlier in that
> > series, so perhaps this patch would be best staged as a predecessor to
> > Ulad's vmalloc series.
> 
> ie, this:
> 
> 
> From: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
> Subject: scripts/gdb/vmalloc: fix vmallocinfo error
> Date: Wed, 7 Feb 2024 16:58:51 +0800
> 
> The patch series "Mitigate a vmap lock contention" removes vmap_area_list,
> which will break the gdb vmallocinfo command:
> 
> (gdb) lx-vmallocinfo
> Python Exception <class 'gdb.error'>: No symbol "vmap_area_list" in current context.
> Error occurred in Python: No symbol "vmap_area_list" in current context.
> 
> So we can instead use vmap_nodes to iterate all vmallocinfo.
> 
> Link: https://lkml.kernel.org/r/20240207085856.11190-1-Kuan-Ying.Lee at mediatek.com
> Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
> Cc: Casper Li <casper.li at mediatek.com>
> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Cc: Chinwen Chang <chinwen.chang at mediatek.com>
> Cc: Jan Kiszka <jan.kiszka at siemens.com>
> Cc: Kieran Bingham <kbingham at kernel.org>
> Cc: Matthias Brugger <matthias.bgg at gmail.com>
> Cc: Qun-Wei Lin <qun-wei.lin at mediatek.com>
> Cc: Uladzislau Rezki (Sony) <urezki at gmail.com>
> Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
> ---
> 
>  scripts/gdb/linux/vmalloc.py |   56 +++++++++++++++++----------------
>  1 file changed, 29 insertions(+), 27 deletions(-)
> 
> --- a/scripts/gdb/linux/vmalloc.py~scripts-gdb-vmalloc-fix-vmallocinfo-error
> +++ a/scripts/gdb/linux/vmalloc.py
> @@ -29,32 +29,34 @@ class LxVmallocInfo(gdb.Command):
>          if not constants.LX_CONFIG_MMU:
>              raise gdb.GdbError("Requires MMU support")
>  
> -        vmap_area_list = gdb.parse_and_eval('vmap_area_list')
> -        for vmap_area in lists.list_for_each_entry(vmap_area_list, vmap_area_ptr_type, "list"):
> -            if not vmap_area['vm']:
> -                gdb.write("0x%x-0x%x %10d vm_map_ram\n" % (vmap_area['va_start'], vmap_area['va_end'],
> -                    vmap_area['va_end'] - vmap_area['va_start']))
> -                continue
> -            v = vmap_area['vm']
> -            gdb.write("0x%x-0x%x %10d" % (v['addr'], v['addr'] + v['size'], v['size']))
> -            if v['caller']:
> -                gdb.write(" %s" % str(v['caller']).split(' ')[-1])
> -            if v['nr_pages']:
> -                gdb.write(" pages=%d" % v['nr_pages'])
> -            if v['phys_addr']:
> -                gdb.write(" phys=0x%x" % v['phys_addr'])
> -            if v['flags'] & constants.LX_VM_IOREMAP:
> -                gdb.write(" ioremap")
> -            if v['flags'] & constants.LX_VM_ALLOC:
> -                gdb.write(" vmalloc")
> -            if v['flags'] & constants.LX_VM_MAP:
> -                gdb.write(" vmap")
> -            if v['flags'] & constants.LX_VM_USERMAP:
> -                gdb.write(" user")
> -            if v['flags'] & constants.LX_VM_DMA_COHERENT:
> -                gdb.write(" dma-coherent")
> -            if is_vmalloc_addr(v['pages']):
> -                gdb.write(" vpages")
> -            gdb.write("\n")
> +        nr_vmap_nodes = gdb.parse_and_eval('nr_vmap_nodes')
> +        for i in range(0, nr_vmap_nodes):
> +            vn = gdb.parse_and_eval('&vmap_nodes[%d]' % i)
> +            for vmap_area in lists.list_for_each_entry(vn['busy']['head'], vmap_area_ptr_type, "list"):
> +                if not vmap_area['vm']:
> +                    gdb.write("0x%x-0x%x %10d vm_map_ram\n" % (vmap_area['va_start'], vmap_area['va_end'],
> +                        vmap_area['va_end'] - vmap_area['va_start']))
> +                    continue
> +                v = vmap_area['vm']
> +                gdb.write("0x%x-0x%x %10d" % (v['addr'], v['addr'] + v['size'], v['size']))
> +                if v['caller']:
> +                    gdb.write(" %s" % str(v['caller']).split(' ')[-1])
> +                if v['nr_pages']:
> +                    gdb.write(" pages=%d" % v['nr_pages'])
> +                if v['phys_addr']:
> +                    gdb.write(" phys=0x%x" % v['phys_addr'])
> +                if v['flags'] & constants.LX_VM_IOREMAP:
> +                    gdb.write(" ioremap")
> +                if v['flags'] & constants.LX_VM_ALLOC:
> +                    gdb.write(" vmalloc")
> +                if v['flags'] & constants.LX_VM_MAP:
> +                    gdb.write(" vmap")
> +                if v['flags'] & constants.LX_VM_USERMAP:
> +                    gdb.write(" user")
> +                if v['flags'] & constants.LX_VM_DMA_COHERENT:
> +                    gdb.write(" dma-coherent")
> +                if is_vmalloc_addr(v['pages']):
> +                    gdb.write(" vpages")
> +                gdb.write("\n")
>  
>  LxVmallocInfo()
> _
> 
Thanks for fixing and helping!

--
Uladzislau Rezki


From conor at kernel.org  Thu Feb  8 10:49:12 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 8 Feb 2024 18:49:12 +0000
Subject: [PATCH] dt-bindings: interrupt-controller: Convert Atmel AIC to
 json-schema
In-Reply-To: <170740748922.3230402.17318224112819715619.robh@kernel.org>
References: <20240208092015.263210-1-dharma.b@microchip.com>
 <170740748922.3230402.17318224112819715619.robh@kernel.org>
Message-ID: <20240208-acuteness-visible-b60cd37c2b32@spud>

Hey Dharma,

On Thu, Feb 08, 2024 at 03:51:31PM +0000, Rob Herring wrote:
> 
> On Thu, 08 Feb 2024 14:50:15 +0530, Dharma Balasubiramani wrote:
> > Convert the Atmel AIC binding document to DT schema format using
> > json-schema.
> > 
> > Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> > ---
> > Note: I get the following warnings on latest kernel but not in 6.7.
> > Should I be worried?
> > usage: yamllint [-h] [-] [-c CONFIG_FILE | -d CONFIG_DATA] [--list-files] [-f {parsable,standard,colored,github,auto}] [-s] [--no-warnings] [-v] [FILE_OR_DIR [FILE_OR_DIR ...]]
> > yamllint: error: one of the arguments FILE_OR_DIR - is required

Hard to say, how were you envoking the command? There were some issues
recently with dt_binding_check, but I thought those had been fixed.

> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/interrupt-controller/atmel,aic.example.dtb: /example-1/dma-controller at ffffec00: failed to match any schema with compatible: ['atmel,at91sam9g45-dma']

But you didn't see this warning?
I think you can resolve it by just dropping the "user" example from the
binding entirely. I don't think it adds anything at all.

Cheers,
Conor.
-------------- 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/20240208/f75339e7/attachment.sig>

From mripard at kernel.org  Thu Feb  8 11:05:08 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 8 Feb 2024 20:05:08 +0100
Subject: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher
 clock rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-5-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-5-96a46a2d8c9b@oltmanns.dev>
Message-ID: <poua4bzyciiwt65sqjf2whqfdumvoe4h3bkjpf64px2vwgumrf@sai73byg2iju>

Hi Frank,

On Mon, Feb 05, 2024 at 04:22:28PM +0100, Frank Oltmanns wrote:
> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
> The SOC requires pll-mipi to run at more than 500 MHz.
> 
> This is the relevant clock tree:
>  pll-mipi
>     tcon0
>        tcon-data-clock
> 
> tcon-data-clock has to run at 1/4 the DSI per-lane bit rate. The XBD599
> has 24 bpp and 4 lanes. Therefore, the resulting requested
> tcon-data-clock rate is:
>     crtc_clock * 1000 * (24 / 4) / 4
> 
> tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it requests a
> parent rate of
>     4 * (crtc_clock * 1000 * (24 / 4) / 4)
> 
> Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate of pll-mipi.
> 
> pll-mipi's constraint to run at 500MHz or higher forces us to have a
> crtc_clock >= 83333 kHz if we want a 60 Hz vertical refresh rate.
> 
> Change [hv]sync_(start|end) so that we reach a clock rate of 83502 kHz
> so that it is high enough to align with pll-pipi limits.
> 
> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>

That commit log is great, but it's kind of off-topic. It's a panel
driver, it can be used on any MIPI-DSI controller, the only relevant
information there should be the panel timings required in the datasheet.

The PLL setup is something for the MIPI-DSI driver to adjust, not for
the panel to care for.

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/20240208/9908ed95/attachment.sig>

From eahariha at linux.microsoft.com  Thu Feb  8 11:16:06 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Thu, 8 Feb 2024 11:16:06 -0800
Subject: [RFC PATCH] KVM: arm64: Override Microsoft Azure Cobalt 100 MIDR
 value with ARM Neoverse N2
In-Reply-To: <86r0ho61ta.wl-maz@kernel.org>
References: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
 <86r0ho61ta.wl-maz@kernel.org>
Message-ID: <7e6add2c-f519-4838-9dd9-57841c50e538@linux.microsoft.com>

On 2/7/2024 1:50 AM, Marc Zyngier wrote:
> On Tue, 06 Feb 2024 19:58:16 +0000,
> Easwar Hariharan <eahariha at linux.microsoft.com> wrote:
>>
>> Several workload optimizations and errata depend on validating that the
>> optimization or errata are applicable to the particular CPU by checking
>> the MIDR_EL1 system register value. With the Microsoft implementer ID
>> for Azure Cobalt 100, the value doesn't match and ~20-25% performance
>> regression is seen in these workloads. Override the Azure Cobalt 100
>> value and replace it with the default ARM Neoverse N2 value that Azure
>> Cobalt 100 is based on.
> 
> Since you don't disclose *why* this particular value should have any
> impact on the behaviour of the kernel, the answer should be "Thanks,
> but no, thanks".
>

The optimizations mentioned in the commit message reside in userspace
and depend on the MIDR value exposed to userspace by the kernel. As
mentioned in my response to Anshuman, this patch was a proof of concept
to have userspace apply the Neoverse N2 optimizations to Azure Cobalt 100
as well.

> Whatever the reason is for doing so, you should make it plain what you
> are working around. Blindly overriding ID registers is not an option,
> and you should simply add your MIDR value to whatever errata list that
> actually matches your implementation.
>

Thank you, I will do that.

>>
>> Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>
>> ---
>>  arch/arm64/include/asm/cputype.h   | 3 ++-
>>  arch/arm64/include/asm/el2_setup.h | 5 +++++
>>  arch/arm64/kvm/sys_regs.c          | 9 ++++++++-
>>  3 files changed, 15 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
>> index 7c7493cb571f..0450c6c32377 100644
>> --- a/arch/arm64/include/asm/cputype.h
>> +++ b/arch/arm64/include/asm/cputype.h
>> @@ -262,7 +262,8 @@ is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
>>   */
>>  static inline u32 __attribute_const__ read_cpuid_id(void)
>>  {
>> -	return read_cpuid(MIDR_EL1);
>> +	return (read_cpuid(MIDR_EL1) == 0x6D0FD490 ? 0x410FD490 :
>> +			read_cpuid(MIDR_EL1));
>>  }
>>  
>>  static inline u64 __attribute_const__ read_cpuid_mpidr(void)
>> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
>> index b7afaa026842..502a14e54a31 100644
>> --- a/arch/arm64/include/asm/el2_setup.h
>> +++ b/arch/arm64/include/asm/el2_setup.h
>> @@ -138,6 +138,11 @@
>>  .macro __init_el2_nvhe_idregs
>>  	mrs	x0, midr_el1
>>  	mrs	x1, mpidr_el1
>> +	ldr	x2, =0x6D0FD490
>> +	cmp	x0, x2
>> +	bne	.Loverride_cobalt100_\@
>> +	ldr	x0, =0x410FD490
>> +.Loverride_cobalt100_\@:
>>  	msr	vpidr_el2, x0
>>  	msr	vmpidr_el2, x1
>>  .endm
>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>> index 30253bd19917..8ea9c7fdabdb 100644
>> --- a/arch/arm64/kvm/sys_regs.c
>> +++ b/arch/arm64/kvm/sys_regs.c
>> @@ -3574,7 +3574,14 @@ id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id,
>>  		return ((struct sys_reg_desc *)r)->val;			\
>>  	}
>>  
>> -FUNCTION_INVARIANT(midr_el1)
>> +static u64 get_midr_el1(struct kvm_vcpu *v, const struct sys_reg_desc *r)
>> +{
>> +	((struct sys_reg_desc *)r)->val = read_sysreg(midr_el1);
>> +	if (((struct sys_reg_desc *)r)->val == 0x6D0FD490)
>> +		((struct sys_reg_desc *)r)->val == 0x410FD490;
> 
> As pointed out to me by Joey, this line is really interesting, and
> shows that you didn't really test this patch.
>

That has clearly escaped my notice, but we did test the patch and
validate that the Neoverse N2 MIDR value showed up where we looked.
Being new to arch/arm64, it's very possible that I may have modified
this hunk without needing to.

> Thanks,
> 
> 	M.
> 



From eahariha at linux.microsoft.com  Thu Feb  8 11:16:10 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Thu, 8 Feb 2024 11:16:10 -0800
Subject: [RFC PATCH] KVM: arm64: Override Microsoft Azure Cobalt 100 MIDR
 value with ARM Neoverse N2
In-Reply-To: <ZcNSI089xqia6lho@FVFF77S0Q05N.cambridge.arm.com>
References: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
 <ZcNSI089xqia6lho@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <ed6c25dc-d5c7-4f15-8fdc-f2adf209e638@linux.microsoft.com>

On 2/7/2024 1:49 AM, Mark Rutland wrote:
> On Tue, Feb 06, 2024 at 07:58:16PM +0000, Easwar Hariharan wrote:
>> Several workload optimizations and errata depend on validating that the
>> optimization or errata are applicable to the particular CPU by checking
>> the MIDR_EL1 system register value. With the Microsoft implementer ID
>> for Azure Cobalt 100, the value doesn't match and ~20-25% performance
>> regression is seen in these workloads. Override the Azure Cobalt 100
>> value and replace it with the default ARM Neoverse N2 value that Azure
>> Cobalt 100 is based on.
> 
> NAK to rewriting the MIDR in the kernel; we do not lie to userspace about the
> MIDR, and this is not a can of worms we're going to open.
> 
> If you desire some microarchitectural performance optimizations in particular
> projects, please submit patches to those projects to understand your MIDR
> value.

Understood.

> 
> Further, if Azure Cobalt 100 is based on ARM Neoverse N2, you presumably suffer
> from the same errata; can you comment on that at all? e.g. are there any
> changes in this part that *might* lead to differences in errata and/or
> workarounds? How do the MIDR_EL1.{Variant,Revision} values compare to that of
> Neoverse N2?
>

Yes, Azure Cobalt 100 suffers from the same errata as Neoverse N2. We had changes
in the implementation, but according to our hardware folks, the Neoverse N2 errata
we are affected by so far aren't affected by the changes made for Azure Cobalt 100.

> Mark.
> 
>> Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>
>> ---
>>  arch/arm64/include/asm/cputype.h   | 3 ++-
>>  arch/arm64/include/asm/el2_setup.h | 5 +++++
>>  arch/arm64/kvm/sys_regs.c          | 9 ++++++++-
>>  3 files changed, 15 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
>> index 7c7493cb571f..0450c6c32377 100644
>> --- a/arch/arm64/include/asm/cputype.h
>> +++ b/arch/arm64/include/asm/cputype.h
>> @@ -262,7 +262,8 @@ is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
>>   */
>>  static inline u32 __attribute_const__ read_cpuid_id(void)
>>  {
>> -	return read_cpuid(MIDR_EL1);
>> +	return (read_cpuid(MIDR_EL1) == 0x6D0FD490 ? 0x410FD490 :
>> +			read_cpuid(MIDR_EL1));
>>  }
>>  
>>  static inline u64 __attribute_const__ read_cpuid_mpidr(void)
>> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
>> index b7afaa026842..502a14e54a31 100644
>> --- a/arch/arm64/include/asm/el2_setup.h
>> +++ b/arch/arm64/include/asm/el2_setup.h
>> @@ -138,6 +138,11 @@
>>  .macro __init_el2_nvhe_idregs
>>  	mrs	x0, midr_el1
>>  	mrs	x1, mpidr_el1
>> +	ldr	x2, =0x6D0FD490
>> +	cmp	x0, x2
>> +	bne	.Loverride_cobalt100_\@
>> +	ldr	x0, =0x410FD490
>> +.Loverride_cobalt100_\@:
>>  	msr	vpidr_el2, x0
>>  	msr	vmpidr_el2, x1
>>  .endm
>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>> index 30253bd19917..8ea9c7fdabdb 100644
>> --- a/arch/arm64/kvm/sys_regs.c
>> +++ b/arch/arm64/kvm/sys_regs.c
>> @@ -3574,7 +3574,14 @@ id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id,
>>  		return ((struct sys_reg_desc *)r)->val;			\
>>  	}
>>  
>> -FUNCTION_INVARIANT(midr_el1)
>> +static u64 get_midr_el1(struct kvm_vcpu *v, const struct sys_reg_desc *r)
>> +{
>> +	((struct sys_reg_desc *)r)->val = read_sysreg(midr_el1);
>> +	if (((struct sys_reg_desc *)r)->val == 0x6D0FD490)
>> +		((struct sys_reg_desc *)r)->val == 0x410FD490;
>> +	return ((struct sys_reg_desc *)r)->val;
>> +}
>> +
>>  FUNCTION_INVARIANT(revidr_el1)
>>  FUNCTION_INVARIANT(aidr_el1)
>>  
>> -- 
>> 2.34.1
>>
>>



From eahariha at linux.microsoft.com  Thu Feb  8 11:16:15 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Thu, 8 Feb 2024 11:16:15 -0800
Subject: [RFC PATCH] KVM: arm64: Override Microsoft Azure Cobalt 100 MIDR
 value with ARM Neoverse N2
In-Reply-To: <df731836-04ab-41b9-b317-434a1060ad61@arm.com>
References: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
 <df731836-04ab-41b9-b317-434a1060ad61@arm.com>
Message-ID: <7ef4b699-0b62-4610-bcd1-68c9d253959c@linux.microsoft.com>

On 2/6/2024 11:54 PM, Anshuman Khandual wrote:
> 
> On 2/7/24 01:28, Easwar Hariharan wrote:
>> Several workload optimizations and errata depend on validating that the
>> optimization or errata are applicable to the particular CPU by checking
>> the MIDR_EL1 system register value. With the Microsoft implementer ID
> 
> Which is how it should be done.
> 
>> for Azure Cobalt 100, the value doesn't match and ~20-25% performance
>> regression is seen in these workloads. Override the Azure Cobalt 100
>> value and replace it with the default ARM Neoverse N2 value that Azure
>> Cobalt 100 is based on.
> 
> Why cannot these MIDR values be classified as required and subscribed to
> the existing erratas that is affecting such implementations. Hence these
> work arounds will be triggered as and when applicable. Why then override
> MIDR value instead ?
>

Thanks for the feedback, I will go ahead and add the Azure Cobalt 100 MIDR
value to the range of MIDRs affected by the Neoverse N2 errata. This
patch was a proof of concept to have userspace apply the Neoverse N2
optimizations to Azure Cobalt 100 as well. As Mark mentioned in a sibling
response, this is not an acceptable way to accomplish this.

>>
>> Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>
>> ---
>>  arch/arm64/include/asm/cputype.h   | 3 ++-
>>  arch/arm64/include/asm/el2_setup.h | 5 +++++
>>  arch/arm64/kvm/sys_regs.c          | 9 ++++++++-
>>  3 files changed, 15 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
>> index 7c7493cb571f..0450c6c32377 100644
>> --- a/arch/arm64/include/asm/cputype.h
>> +++ b/arch/arm64/include/asm/cputype.h
>> @@ -262,7 +262,8 @@ is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
>>   */
>>  static inline u32 __attribute_const__ read_cpuid_id(void)
>>  {
>> -	return read_cpuid(MIDR_EL1);
>> +	return (read_cpuid(MIDR_EL1) == 0x6D0FD490 ? 0x410FD490 :
>> +			read_cpuid(MIDR_EL1));
>>  }
>>  
>>  static inline u64 __attribute_const__ read_cpuid_mpidr(void)
>> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
>> index b7afaa026842..502a14e54a31 100644
>> --- a/arch/arm64/include/asm/el2_setup.h
>> +++ b/arch/arm64/include/asm/el2_setup.h
>> @@ -138,6 +138,11 @@
>>  .macro __init_el2_nvhe_idregs
>>  	mrs	x0, midr_el1
>>  	mrs	x1, mpidr_el1
>> +	ldr	x2, =0x6D0FD490
>> +	cmp	x0, x2
>> +	bne	.Loverride_cobalt100_\@
>> +	ldr	x0, =0x410FD490
>> +.Loverride_cobalt100_\@:
>>  	msr	vpidr_el2, x0
>>  	msr	vmpidr_el2, x1
>>  .endm
>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>> index 30253bd19917..8ea9c7fdabdb 100644
>> --- a/arch/arm64/kvm/sys_regs.c
>> +++ b/arch/arm64/kvm/sys_regs.c
>> @@ -3574,7 +3574,14 @@ id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id,
>>  		return ((struct sys_reg_desc *)r)->val;			\
>>  	}
>>  
>> -FUNCTION_INVARIANT(midr_el1)
>> +static u64 get_midr_el1(struct kvm_vcpu *v, const struct sys_reg_desc *r)
>> +{
>> +	((struct sys_reg_desc *)r)->val = read_sysreg(midr_el1);
>> +	if (((struct sys_reg_desc *)r)->val == 0x6D0FD490)
>> +		((struct sys_reg_desc *)r)->val == 0x410FD490;
>> +	return ((struct sys_reg_desc *)r)->val;
>> +}
>> +
>>  FUNCTION_INVARIANT(revidr_el1)
>>  FUNCTION_INVARIANT(aidr_el1)
>>  



From ricardo at marliere.net  Thu Feb  8 11:17:50 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Thu, 08 Feb 2024 16:17:50 -0300
Subject: [PATCH 0/2] staging: struct bus_type cleanup
Message-ID: <20240208-bus_cleanup-staging2-v1-0-cfe906133a2c@marliere.net>

This series is part of an effort to cleanup the users of the driver
core.

Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
Ricardo B. Marliere (2):
      staging: vc04_services: vchiq_arm: make vchiq_bus_type const
      staging: vme: make vme_bus_type const

 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c | 2 +-
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h | 2 +-
 drivers/staging/vme_user/vme.c                                | 2 +-
 drivers/staging/vme_user/vme.h                                | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)
---
base-commit: ce54e9342124ededf0a00ed4e8a8aee535bfbf00
change-id: 20240208-bus_cleanup-staging2-d8906b09f1d0

Best regards,
-- 
Ricardo B. Marliere <ricardo at marliere.net>



From ricardo at marliere.net  Thu Feb  8 11:17:51 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Thu, 08 Feb 2024 16:17:51 -0300
Subject: [PATCH 1/2] staging: vc04_services: vchiq_arm: make vchiq_bus_type
 const
In-Reply-To: <20240208-bus_cleanup-staging2-v1-0-cfe906133a2c@marliere.net>
References: <20240208-bus_cleanup-staging2-v1-0-cfe906133a2c@marliere.net>
Message-ID: <20240208-bus_cleanup-staging2-v1-1-cfe906133a2c@marliere.net>

Now that the driver core can properly handle constant struct bus_type,
move the vchiq_bus_type variable to be a constant structure as well,
placing it into read-only memory which can not be modified at runtime.

Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c | 2 +-
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c
index 933027e0011e..68f830d75531 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c
@@ -37,7 +37,7 @@ static int vchiq_bus_probe(struct device *dev)
 	return driver->probe(device);
 }
 
-struct bus_type vchiq_bus_type = {
+const struct bus_type vchiq_bus_type = {
 	.name   = "vchiq-bus",
 	.match  = vchiq_bus_type_match,
 	.uevent = vchiq_bus_uevent,
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h
index caa6fdf25bb1..4db86e76edbd 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h
@@ -34,7 +34,7 @@ static inline struct vchiq_driver *to_vchiq_driver(struct device_driver *d)
 	return container_of(d, struct vchiq_driver, driver);
 }
 
-extern struct bus_type vchiq_bus_type;
+extern const struct bus_type vchiq_bus_type;
 
 struct vchiq_device *
 vchiq_device_register(struct device *parent, const char *name);

-- 
2.43.0



From ricardo at marliere.net  Thu Feb  8 11:17:52 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Thu, 08 Feb 2024 16:17:52 -0300
Subject: [PATCH 2/2] staging: vme: make vme_bus_type const
In-Reply-To: <20240208-bus_cleanup-staging2-v1-0-cfe906133a2c@marliere.net>
References: <20240208-bus_cleanup-staging2-v1-0-cfe906133a2c@marliere.net>
Message-ID: <20240208-bus_cleanup-staging2-v1-2-cfe906133a2c@marliere.net>

Now that the driver core can properly handle constant struct bus_type,
move the vme_bus_type variable to be a constant structure as well,
placing it into read-only memory which can not be modified at runtime.

Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 drivers/staging/vme_user/vme.c | 2 +-
 drivers/staging/vme_user/vme.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/vme_user/vme.c b/drivers/staging/vme_user/vme.c
index e9461a7a7ab8..0cd370ab1008 100644
--- a/drivers/staging/vme_user/vme.c
+++ b/drivers/staging/vme_user/vme.c
@@ -1970,7 +1970,7 @@ static void vme_bus_remove(struct device *dev)
 		driver->remove(vdev);
 }
 
-struct bus_type vme_bus_type = {
+const struct bus_type vme_bus_type = {
 	.name = "vme",
 	.match = vme_bus_match,
 	.probe = vme_bus_probe,
diff --git a/drivers/staging/vme_user/vme.h b/drivers/staging/vme_user/vme.h
index 06504dccd5ff..26aa40f78a74 100644
--- a/drivers/staging/vme_user/vme.h
+++ b/drivers/staging/vme_user/vme.h
@@ -81,7 +81,7 @@ struct vme_resource {
 	struct list_head *entry;
 };
 
-extern struct bus_type vme_bus_type;
+extern const struct bus_type vme_bus_type;
 
 /* Number of VME interrupt vectors */
 #define VME_NUM_STATUSID	256

-- 
2.43.0



From jane.chu at oracle.com  Thu Feb  8 11:21:19 2024
From: jane.chu at oracle.com (Jane Chu)
Date: Thu, 8 Feb 2024 11:21:19 -0800
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <ZcT4DH7VE1XLBvVc@casper.infradead.org>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com> <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
 <ZcNnrdlb3fe0kGHK@casper.infradead.org>
 <20240207121125.GA22234@willie-the-truck>
 <ZcOQ-0pzA16AEbct@casper.infradead.org>
 <908066c7-b749-4f95-b006-ce9b5bd1a909@oracle.com>
 <ZcT4DH7VE1XLBvVc@casper.infradead.org>
Message-ID: <78eee4ef-99ed-46a3-a776-a74bcd83ba44@oracle.com>

On 2/8/2024 7:49 AM, Matthew Wilcox wrote:

> On Wed, Feb 07, 2024 at 06:24:52PM -0800, Jane Chu wrote:
>> On 2/7/2024 6:17 AM, Matthew Wilcox wrote:
>>> While this array of ~512 pages have been allocated to hugetlbfs, and one
>>> would think that there would be no way that there could still be
>>> references to them, another CPU can have a pointer to this struct page
>>> (eg attempting a speculative page cache reference or
>>> get_user_pages_fast()).  That means it will try to call
>>> atomic_add_unless(&page->_refcount, 1, 0);
>>>
>>> Actually, I wonder if this isn't a problem on x86 too?  Do we need to
>>> explicitly go through an RCU grace period before freeing the pages
>>> for use by somebody else?
>>>
>> Sorry, not sure what I'm missing, please help.
> Having written out the analysis, I now think it can't happen on x86,
> but let's walk through it because it's non-obvious (and I think it
> illustrates what people are afraid of on Arm).
>
> CPU A calls either get_user_pages_fast() or __filemap_get_folio().
> Let's do the latter this time.
>
>          folio = filemap_get_entry(mapping, index);
> filemap_get_entry:
> 	rcu_read_lock();
>          folio = xas_load(&xas);
>          if (!folio_try_get_rcu(folio))
>                  goto repeat;
>          if (unlikely(folio != xas_reload(&xas))) {
>                  folio_put(folio);
>                  goto repeat;
>          }
> folio_try_get_rcu:
> 	folio_ref_try_add_rcu(folio, 1);
> folio_ref_try_add_rcu:
>          if (unlikely(!folio_ref_add_unless(folio, count, 0))) {
>                  /* Either the folio has been freed, or will be freed. */
>                  return false;
> folio_ref_add_unless:
>          return page_ref_add_unless(&folio->page, nr, u);
> page_ref_add_unless:
> 	atomic_add_unless(&page->_refcount, nr, u);
>
> A rather deep callchain there, but for our purposes the important part
> is: we take the RCU read lock, we look up a folio, we increment its
> refcount if it's not zero, then check that looking up this index gets
> the same folio; if it doesn't, we decrement the refcount again and retry
> the lookup.
>
> For this analysis, we can be preempted at any point after we've got the
> folio pointer from xa_load().
>
>>  From hugetlb allocation perspective,? one of the scenarios is run time
>> hugetlb page allocation (say 2M pages), starting from the buddy allocator
>> returns compound pages, then the head page is set to frozen, then the
>> folio(compound pages) is put thru the HVO process, one of which is
>> vmemmap_split_pmd() in case a vmemmap page is a PMD page.
>>
>> Until the HVO process completes, none of the vmemmap represented pages are
>> available to any threads, so what are the causes for IRQ threads to access
>> their vmemmap pages?
> Yup, this sounds like enough, but it's not.  The problem is the person
> who's looking up the folio in the pagecache under RCU.  They've got
> the folio pointer and have been preempted.  So now what happens to our
> victim folio?
>
> Something happens to remove it from the page cache.  Maybe the file is
> truncated, perhaps vmscan comes along and kicks it out.  Either way, it's
> removed from the xarray and gets its refcount set to 0.  If the lookup
> were to continue at this time, everything would be fine because it would
> see a refcount of 0 and not increment it (in page_ref_add_unless()).
> And this is where my analysis of RCU tends to go wrong, because I only
> think of interleaving event A and B.  I don't think about B and then C
> happening before A resumes.  But it can!  Let's follow the journey of
> this struct page.
>
> Now that it's been removed from the page cache, it's allocated by hugetlb,
> as you describe.  And it's one of the tail pages towards the end of
> the 512 contiguous struct pages.  That means that we alter vmemmap so
> that the pointer to struct page now points to a different struct page
> (one of the earlier ones).  Then the original page of vmemmap containing
> our lucky struct page is returned to the page allocator.  At this point,
> it no longer contains struct pages; it can contain literally anything.
>
> Where my analysis went wrong was that CPU A _no longer has a pointer
> to it_.  CPU A has a pointer into vmemmap.  So it will access the
> replacement struct page (which definitely has a refcount 0) instead of
> the one which has been freed.  I had thought that CPU A would access the
> original memory which has now been allocated to someone else.  But no,
> it can't because its pointer is virtual, not physical.
>
>
> ---
>
> Now I'm thinking more about this and there's another scenario which I
> thought might go wrong, and doesn't.  For 7 of the 512 pages which are
> freed, the struct page pointer gathered by CPU A will not point to a
> page with a refcount of 0.  Instead it will point to an alias of the
> head page with a positive refcount.  For those pages, CPU A will see
> folio_try_get_rcu() succeed.  Then it will call xas_reload() and see
> the folio isn't there any more, so it will call folio_put() on something
> which used to be a folio, and isn't any more.
>
> But folio_put() calls folio_put_testzero() which calls put_page_testzero()
> without asserting that the pointer is actually to a folio.
> So everything's fine, but really only by coincidence; I don't think
> anybody's thought about this scenario before (maybe Muchun has, but I
> don't remember it being discussed).

Wow!? Marvelous analysis, thank you!

So is the solution simple as making folio_put_testzero() to check 
whether the folio pointer actually points to a folio?

or there is more to consider?

Thanks a lot!

-jane



From arinc.unal at arinc9.com  Thu Feb  8 11:35:53 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Thu, 8 Feb 2024 22:35:53 +0300
Subject: [PATCH netnext 8/8] net: dsa: mt7530: simplify link operations
 and force link down on all ports
In-Reply-To: <ZcT_r68mStRAC3Uk@makrotopia.org>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
 <20240208-for-netnext-mt7530-improvements-3-v1-8-d7c1cfd502ca@arinc9.com>
 <ZcT_r68mStRAC3Uk@makrotopia.org>
Message-ID: <2a6a8d93-beae-4bec-a792-0e093b4c4ecd@arinc9.com>

On 8.02.2024 19:22, Daniel Golle wrote:
> On Thu, Feb 08, 2024 at 08:51:36AM +0300, Ar?n? ?NAL via B4 Relay wrote:
>> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
>>
>> Currently, the link operations for switch MACs are scattered across
>> port_enable, port_disable, phylink_mac_config, phylink_mac_link_up, and
>> phylink_mac_link_down.
>>
>> port_enable and port_disable clears the link settings. Move that to
>> mt7530_setup() and mt7531_setup_common() which set up the switches. This
>> way, the link settings are cleared on all ports at setup, and then only
>> once with phylink_mac_link_down() when a link goes down.
>>
>> Enable force mode at setup to apply the force part of the link settings.
>> This ensures that only active ports will have their link up.
>>
>> Now that the bit for setting the port on force mode is done on
>> mt7530_setup() and mt7531_setup_common(), get rid of PMCR_FORCE_MODE_ID()
>> which helped determine which bit to use for the switch model.
>>
>> The "MT7621 Giga Switch Programming Guide v0.3", "MT7531 Reference Manual
>> for Development Board v1.0", and "MT7988A Wi-Fi 7 Generation Router
>> Platform: Datasheet (Open Version) v0.1" documents show that these bits are
>> enabled at reset:
>>
>> PMCR_IFG_XMIT(1) (not part of PMCR_LINK_SETTINGS_MASK)
>> PMCR_MAC_MODE (not part of PMCR_LINK_SETTINGS_MASK)
>> PMCR_TX_EN
>> PMCR_RX_EN
>> PMCR_BACKOFF_EN (not part of PMCR_LINK_SETTINGS_MASK)
>> PMCR_BACKPR_EN (not part of PMCR_LINK_SETTINGS_MASK)
>> PMCR_TX_FC_EN
>> PMCR_RX_FC_EN
>>
>> These bits also don't exist on the MT7530_PMCR_P(6) register of the switch
>> on the MT7988 SoC:
>>
>> PMCR_IFG_XMIT()
>> PMCR_MAC_MODE
>> PMCR_BACKOFF_EN
>> PMCR_BACKPR_EN
>>
>> Remove the setting of the bits not part of PMCR_LINK_SETTINGS_MASK on
>> phylink_mac_config as they're already set.
>>
>> Suggested-by: Vladimir Oltean <olteanv at gmail.com>
>> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
>> ---
>>   drivers/net/dsa/mt7530.c | 26 +++++++++++++-------------
>>   drivers/net/dsa/mt7530.h |  2 --
>>   2 files changed, 13 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
>> index 5c8ad41ce8cd..f67db577d1c0 100644
>> --- a/drivers/net/dsa/mt7530.c
>> +++ b/drivers/net/dsa/mt7530.c
>> @@ -1018,7 +1018,6 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
>>   	priv->ports[port].enable = true;
>>   	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
>>   		   priv->ports[port].pm);
>> -	mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
>>   
>>   	mutex_unlock(&priv->reg_mutex);
>>   
>> @@ -1038,7 +1037,6 @@ mt7530_port_disable(struct dsa_switch *ds, int port)
>>   	priv->ports[port].enable = false;
>>   	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
>>   		   PCR_MATRIX_CLR);
>> -	mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
>>   
>>   	mutex_unlock(&priv->reg_mutex);
>>   }
>> @@ -2257,6 +2255,12 @@ mt7530_setup(struct dsa_switch *ds)
>>   	mt7530_mib_reset(ds);
>>   
>>   	for (i = 0; i < MT7530_NUM_PORTS; i++) {
>> +		/* Clear link settings and enable force mode to force link down
>> +		 * on all ports until they're enabled later.
>> +		 */
>> +		mt7530_clear(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK);
>> +		mt7530_set(priv, MT7530_PMCR_P(i), PMCR_FORCE_MODE);
> 
> Any reason to not combine the two lines above into a single call:
> 
> mt7530_rmw(priv, MT7530_PMCR_P(i),
> 	   PMCR_LINK_SETTINGS_MASK | PMCR_FORCE_MODE,
> 	   PMCR_FORCE_MODE);

No reason whatsoever, I'll do this. Thanks!

Ar?n?


From ahalaney at redhat.com  Thu Feb  8 12:06:41 2024
From: ahalaney at redhat.com (Andrew Halaney)
Date: Thu, 8 Feb 2024 14:06:41 -0600
Subject: [PATCH net-next v3] net: stmmac: dwmac-qcom-ethqos: Enable TBS
 on all queues but 0
In-Reply-To: <20240207224001.2109224-1-quic_abchauha@quicinc.com>
References: <20240207224001.2109224-1-quic_abchauha@quicinc.com>
Message-ID: <yamtu6i6bzre2ewmgh5eert35j74ofcw65554zr2g57ydzsjqa@crxdyszih4tw>

On Wed, Feb 07, 2024 at 02:40:01PM -0800, Abhishek Chauhan wrote:
> TSO and TBS cannot co-exist. TBS requires special descriptor to be
> allocated at bootup. Initialising Tx queues at probe to support
> TSO and TBS can help in allocating those resources at bootup.
> 
> TX queues with TBS can support etf qdisc hw offload.
> 
> This is similar to the patch raised by NXP
> commit 3b12ec8f618e ("net: stmmac: dwmac-imx: set TSO/TBS TX queues default 
> settings")
> 
> Changes since v2:
> - Fixed the styling of comment in the dwmac-qcom-ethqos.c
> - Followed the upstream format to give other glue
>   driver references to solve the same problem
> - Appended  the subject with net-next
> - Discussion of why this patch is required is discussed in
> https://lore.kernel.org/netdev/c2497eef-1041-4cd0-8220-42622c8902f4 at quicinc.com/
> 
> Changes since v1:
> - Subject is changed as per upstream guidelines
> - Added a reference of a similar change done by NXP in
>   body of the commit message
> 
> Signed-off-by: Abhishek Chauhan <quic_abchauha at quicinc.com>

Please add my:

    Tested-by: Andrew Halaney <ahalaney at redhat.com> # sa8775p-ride

when submitting v4 with the changelog moved as Jeff mentioned. This
seems to work well (I can enable ETF on all queues but 0, and as far as
I can tell after trying to test that for a while it seems to work as
expected).

Thanks,
Andrew

> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> index 31631e3f89d0..2691a250a5a7 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> @@ -728,7 +728,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
>  	struct stmmac_resources stmmac_res;
>  	struct device *dev = &pdev->dev;
>  	struct qcom_ethqos *ethqos;
> -	int ret;
> +	int ret, i;
>  
>  	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
>  	if (ret)
> @@ -822,6 +822,10 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
>  		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
>  	}
>  
> +	/* Enable TSO on queue0 and enable TBS on rest of the queues */
> +	for (i = 1; i < plat_dat->tx_queues_to_use; i++)
> +		plat_dat->tx_queues_cfg[i].tbs_en = 1;
> +
>  	return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
>  }
>  
> -- 
> 2.25.1
> 



From krzysztof.kozlowski at linaro.org  Thu Feb  8 12:21:13 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 21:21:13 +0100
Subject: [PATCH] mtd: lpc32xx: use typedef for dma_filter_fn
Message-ID: <20240208202113.630190-1-krzysztof.kozlowski@linaro.org>

Use existing typedef for dma_filter_fn to avoid duplicating type
definition.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 include/linux/mtd/lpc32xx_mlc.h | 2 +-
 include/linux/mtd/lpc32xx_slc.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/mtd/lpc32xx_mlc.h b/include/linux/mtd/lpc32xx_mlc.h
index d168c628c0d5..35e971be0950 100644
--- a/include/linux/mtd/lpc32xx_mlc.h
+++ b/include/linux/mtd/lpc32xx_mlc.h
@@ -11,7 +11,7 @@
 #include <linux/dmaengine.h>
 
 struct lpc32xx_mlc_platform_data {
-	bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
+	dma_filter_fn dma_filter;
 };
 
 #endif  /* __LINUX_MTD_LPC32XX_MLC_H */
diff --git a/include/linux/mtd/lpc32xx_slc.h b/include/linux/mtd/lpc32xx_slc.h
index cf54a9f80460..a044b806566b 100644
--- a/include/linux/mtd/lpc32xx_slc.h
+++ b/include/linux/mtd/lpc32xx_slc.h
@@ -11,7 +11,7 @@
 #include <linux/dmaengine.h>
 
 struct lpc32xx_slc_platform_data {
-	bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
+	dma_filter_fn dma_filter;
 };
 
 #endif  /* __LINUX_MTD_LPC32XX_SLC_H */
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb  8 12:28:21 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 21:28:21 +0100
Subject: [PATCH 1/2] pmdomain: constify of_phandle_args in xlate
Message-ID: <20240208202822.631449-1-krzysztof.kozlowski@linaro.org>

The xlate callbacks are supposed to translate of_phandle_args to proper
provider without modifying the of_phandle_args.  Make the argument
pointer to const for code safety and readability.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 drivers/pmdomain/core.c                     | 4 ++--
 drivers/pmdomain/imx/scu-pd.c               | 2 +-
 drivers/pmdomain/tegra/powergate-bpmp.c     | 2 +-
 drivers/pmdomain/ti/ti_sci_pm_domains.c     | 2 +-
 drivers/pmdomain/xilinx/zynqmp-pm-domains.c | 2 +-
 include/linux/pm_domain.h                   | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 46331e71108a..ea4b29475206 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2266,7 +2266,7 @@ static DEFINE_MUTEX(of_genpd_mutex);
  * to be a valid pointer to struct generic_pm_domain.
  */
 static struct generic_pm_domain *genpd_xlate_simple(
-					struct of_phandle_args *genpdspec,
+					const struct of_phandle_args *genpdspec,
 					void *data)
 {
 	return data;
@@ -2283,7 +2283,7 @@ static struct generic_pm_domain *genpd_xlate_simple(
  * the genpd_onecell_data struct when registering the provider.
  */
 static struct generic_pm_domain *genpd_xlate_onecell(
-					struct of_phandle_args *genpdspec,
+					const struct of_phandle_args *genpdspec,
 					void *data)
 {
 	struct genpd_onecell_data *genpd_data = data;
diff --git a/drivers/pmdomain/imx/scu-pd.c b/drivers/pmdomain/imx/scu-pd.c
index 891c1d925a9d..05841b0bf7f3 100644
--- a/drivers/pmdomain/imx/scu-pd.c
+++ b/drivers/pmdomain/imx/scu-pd.c
@@ -393,7 +393,7 @@ static int imx_sc_pd_power_off(struct generic_pm_domain *domain)
 	return imx_sc_pd_power(domain, false);
 }
 
-static struct generic_pm_domain *imx_scu_pd_xlate(struct of_phandle_args *spec,
+static struct generic_pm_domain *imx_scu_pd_xlate(const struct of_phandle_args *spec,
 						  void *data)
 {
 	struct generic_pm_domain *domain = ERR_PTR(-ENOENT);
diff --git a/drivers/pmdomain/tegra/powergate-bpmp.c b/drivers/pmdomain/tegra/powergate-bpmp.c
index 179ed895c279..b0138ca9f851 100644
--- a/drivers/pmdomain/tegra/powergate-bpmp.c
+++ b/drivers/pmdomain/tegra/powergate-bpmp.c
@@ -305,7 +305,7 @@ static void tegra_bpmp_remove_powergates(struct tegra_bpmp *bpmp)
 }
 
 static struct generic_pm_domain *
-tegra_powergate_xlate(struct of_phandle_args *spec, void *data)
+tegra_powergate_xlate(const struct of_phandle_args *spec, void *data)
 {
 	struct generic_pm_domain *domain = ERR_PTR(-ENOENT);
 	struct genpd_onecell_data *genpd = data;
diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
index c091d569ecd5..9dddf227a3a6 100644
--- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
+++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
@@ -85,7 +85,7 @@ static int ti_sci_pd_power_on(struct generic_pm_domain *domain)
  * @data: genpd core data for all the powerdomains on the device
  */
 static struct generic_pm_domain *ti_sci_pd_xlate(
-					struct of_phandle_args *genpdspec,
+					const struct of_phandle_args *genpdspec,
 					void *data)
 {
 	struct genpd_onecell_data *genpd_data = data;
diff --git a/drivers/pmdomain/xilinx/zynqmp-pm-domains.c b/drivers/pmdomain/xilinx/zynqmp-pm-domains.c
index 6fd514286d82..0b5831e5ba1b 100644
--- a/drivers/pmdomain/xilinx/zynqmp-pm-domains.c
+++ b/drivers/pmdomain/xilinx/zynqmp-pm-domains.c
@@ -210,7 +210,7 @@ static void zynqmp_gpd_detach_dev(struct generic_pm_domain *domain,
 }
 
 static struct generic_pm_domain *zynqmp_gpd_xlate
-				(struct of_phandle_args *genpdspec, void *data)
+				(const struct of_phandle_args *genpdspec, void *data)
 {
 	struct genpd_onecell_data *genpd_data = data;
 	unsigned int i, idx = genpdspec->args[0];
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index fb91770ba4ba..1a391ef1b6f8 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -349,7 +349,7 @@ static inline void dev_pm_genpd_resume(struct device *dev) {}
 /* OF PM domain providers */
 struct of_device_id;
 
-typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args,
+typedef struct generic_pm_domain *(*genpd_xlate_t)(const struct of_phandle_args *args,
 						   void *data);
 
 struct genpd_onecell_data {
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb  8 12:28:22 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu,  8 Feb 2024 21:28:22 +0100
Subject: [PATCH 2/2] pmdomain: constify of_phandle_args in add device and subdomain
In-Reply-To: <20240208202822.631449-1-krzysztof.kozlowski@linaro.org>
References: <20240208202822.631449-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240208202822.631449-2-krzysztof.kozlowski@linaro.org>

Pointer to of_phandle_args is not modified by of_genpd_add_device() and
of_genpd_add_subdomain(), so it can be made pointer to const for code
safety and readability.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 drivers/pmdomain/core.c   | 12 ++++++------
 include/linux/pm_domain.h | 20 ++++++++++----------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index ea4b29475206..4215ffd9b11c 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2526,7 +2526,7 @@ EXPORT_SYMBOL_GPL(of_genpd_del_provider);
  * on failure.
  */
 static struct generic_pm_domain *genpd_get_from_provider(
-					struct of_phandle_args *genpdspec)
+					const struct of_phandle_args *genpdspec)
 {
 	struct generic_pm_domain *genpd = ERR_PTR(-ENOENT);
 	struct of_genpd_provider *provider;
@@ -2557,7 +2557,7 @@ static struct generic_pm_domain *genpd_get_from_provider(
  * Looks-up an I/O PM domain based upon phandle args provided and adds
  * the device to the PM domain. Returns a negative error code on failure.
  */
-int of_genpd_add_device(struct of_phandle_args *genpdspec, struct device *dev)
+int of_genpd_add_device(const struct of_phandle_args *genpdspec, struct device *dev)
 {
 	struct generic_pm_domain *genpd;
 	int ret;
@@ -2591,8 +2591,8 @@ EXPORT_SYMBOL_GPL(of_genpd_add_device);
  * provided and adds the subdomain to the parent PM domain. Returns a
  * negative error code on failure.
  */
-int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
-			   struct of_phandle_args *subdomain_spec)
+int of_genpd_add_subdomain(const struct of_phandle_args *parent_spec,
+			   const struct of_phandle_args *subdomain_spec)
 {
 	struct generic_pm_domain *parent, *subdomain;
 	int ret;
@@ -2629,8 +2629,8 @@ EXPORT_SYMBOL_GPL(of_genpd_add_subdomain);
  * provided and removes the subdomain from the parent PM domain. Returns a
  * negative error code on failure.
  */
-int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
-			      struct of_phandle_args *subdomain_spec)
+int of_genpd_remove_subdomain(const struct of_phandle_args *parent_spec,
+			      const struct of_phandle_args *subdomain_spec)
 {
 	struct generic_pm_domain *parent, *subdomain;
 	int ret;
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 1a391ef1b6f8..772d3280d35f 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -364,11 +364,11 @@ int of_genpd_add_provider_simple(struct device_node *np,
 int of_genpd_add_provider_onecell(struct device_node *np,
 				  struct genpd_onecell_data *data);
 void of_genpd_del_provider(struct device_node *np);
-int of_genpd_add_device(struct of_phandle_args *args, struct device *dev);
-int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
-			   struct of_phandle_args *subdomain_spec);
-int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
-			      struct of_phandle_args *subdomain_spec);
+int of_genpd_add_device(const struct of_phandle_args *args, struct device *dev);
+int of_genpd_add_subdomain(const struct of_phandle_args *parent_spec,
+			   const struct of_phandle_args *subdomain_spec);
+int of_genpd_remove_subdomain(const struct of_phandle_args *parent_spec,
+			      const struct of_phandle_args *subdomain_spec);
 struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
 int of_genpd_parse_idle_states(struct device_node *dn,
 			       struct genpd_power_state **states, int *n);
@@ -393,20 +393,20 @@ static inline int of_genpd_add_provider_onecell(struct device_node *np,
 
 static inline void of_genpd_del_provider(struct device_node *np) {}
 
-static inline int of_genpd_add_device(struct of_phandle_args *args,
+static inline int of_genpd_add_device(const struct of_phandle_args *args,
 				      struct device *dev)
 {
 	return -ENODEV;
 }
 
-static inline int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
-					 struct of_phandle_args *subdomain_spec)
+static inline int of_genpd_add_subdomain(const struct of_phandle_args *parent_spec,
+					 const struct of_phandle_args *subdomain_spec)
 {
 	return -ENODEV;
 }
 
-static inline int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
-					struct of_phandle_args *subdomain_spec)
+static inline int of_genpd_remove_subdomain(const struct of_phandle_args *parent_spec,
+					    const struct of_phandle_args *subdomain_spec)
 {
 	return -ENODEV;
 }
-- 
2.34.1



From itaru.kitayama at linux.dev  Thu Feb  8 12:53:31 2024
From: itaru.kitayama at linux.dev (Itaru Kitayama)
Date: Fri, 9 Feb 2024 05:53:31 +0900
Subject: [PATCH 0/3] arm64: cleanup DAIF handling for EL0 returns
In-Reply-To: <ZcTLND4GNTFP53Yg@FVFF77S0Q05N.cambridge.arm.com>
References: <20240206123848.1696480-1-mark.rutland@arm.com>
 <ZcQ8UKRNz0TLvJRB@vm3>
 <ZcTLND4GNTFP53Yg@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <ZcU/S2CysnjLIn0j@vm3>

On Thu, Feb 08, 2024 at 12:38:12PM +0000, Mark Rutland wrote:
> On Thu, Feb 08, 2024 at 11:28:32AM +0900, Itaru Kitayama wrote:
> > On Tue, Feb 06, 2024 at 12:38:45PM +0000, Mark Rutland wrote:
> > > Hi,
> > > 
> > > These patches rework DAIF handling when returning to EL0, simplifiying
> > > the logic in do_notify_resume() and allowing Debug + SError to be
> > > unmasked for a little longer during exception return.
> > > 
> > > My primary motivation for these changes is to centralize entry/exit DAIF
> > > management within entry-common.c, as this will allow entry/exit
> > > sequences to be specialised, and make it much easier to add support for
> > > FEAT_NMI. With specialized entry DAIF management, it will also be
> > > possible to simplify local_daif_{save,restore}() and
> > > local_irq_{save,restore}().
> > > 
> > > I'm sending this out on its own as (IMO) it's a nice cleanup on its own,
> > > and I don't believe that I'll have the remainder of the DAIF rework
> > > ready for this cycle.
> > > 
> > > The series is based on v6.8-rc3.
> > > 
> > > Mark.
> > > 
> > > Mark Rutland (3):
> > >   arm64: Simplify do_notify_resume() DAIF masking
> > >   arm64: Move do_notify_resume() to entry-common.c
> > >   arm64: Unmask Debug + SError in do_notify_resume()
> > > 
> > >  arch/arm64/include/asm/exception.h |  2 +-
> > >  arch/arm64/kernel/entry-common.c   | 36 ++++++++++++++++++++++++++-
> > >  arch/arm64/kernel/signal.c         | 39 ++----------------------------
> > >  3 files changed, 38 insertions(+), 39 deletions(-)
> > 
> > Boot tested on RevC FVP and kselftest arm64 subcategory runs without an error
> > on RevC FVP too.
> 
> Thanks for testing! Would you be happy for that to imply a tested-by tag, e.g.
> 
>   Tested-by: Itaru Kitayama <itaru.kitayama at linux.dev>
> 
> ... ?

If it's worth it, yes please.

Thanks,
Itaru.
> 
> Mark.


From broonie at kernel.org  Thu Feb  8 13:21:55 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 08 Feb 2024 21:21:55 +0000
Subject: [PATCH v2 0/4] spi: s3c64xx: add support for google,gs101-spi
In-Reply-To: <20240207111516.2563218-1-tudor.ambarus@linaro.org>
References: <20240207111516.2563218-1-tudor.ambarus@linaro.org>
Message-ID: <170742731537.2266792.3851016361229293846.b4-ty@kernel.org>

On Wed, 07 Feb 2024 11:15:12 +0000, Tudor Ambarus wrote:
> This applies on Mark's for-next branch. It can be queued before the
> simple cleanup patches.
> 
> v2:
> - drop the include linux/types.h patch
> - patch 2 is a preparation step as per Sam's suggestion
> - contrary to Sam's suggestion, I kept the style for the
>   s3c64xx_iowrite{8,16}_32_rep() methods, to be consistent with the
>   generic implementations from asm-generic/io.h.
> - s/just/only
> - collect R-b tags.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/4] spi: dt-bindings: samsung: add google,gs101-spi compatible
      commit: ff690e75d64b0ca119adbfc3bd0b444bc1d0a1c5
[2/4] spi: s3c64xx: prepare for a different flavor of iowrite rep
      commit: 80d3204a3b1dbef570ed29d4d375e4d6922da82d
[3/4] spi: s3c64xx: add s3c64xx_iowrite{8,16}_32_rep accessors
      commit: b7bafb9f54fc4609ff84ecd633f918f6f973f471
[4/4] spi: s3c64xx: add support for google,gs101-spi
      commit: 0f0212558bc9e33fad4148d3f44745a367076b20

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  Thu Feb  8 13:21:59 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 08 Feb 2024 21:21:59 +0000
Subject: [PATCH v5 00/17] spi: s3c64xx: straightforward cleanup
In-Reply-To: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
References: <20240207120431.2766269-1-tudor.ambarus@linaro.org>
Message-ID: <170742731939.2266792.15383830101755255462.b4-ty@kernel.org>

On Wed, 07 Feb 2024 12:04:14 +0000, Tudor Ambarus wrote:
> The patch set has no dependency although Sam prefers to have this simple
> cleanup queued after the gs101 patches from:
> https://lore.kernel.org/linux-spi/20240207111516.2563218-1-tudor.ambarus at linaro.org/
> 
> Tested with gs101-spi.
> 
> Changes in v5:
> - don't abuse the Fixes tag, it was wrongly used for:
>     - explicit header inclusions
>     - possible negative array index fix, which is just a posibility,
>       it never happened
>     - typo fix
> - reorder patches, sort headers then explicitly include the missing ones
> - new patch: "spi: s3c64xx: explicitly include <linux/types.h>"
> - collect R-b tags
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[01/17] spi: s3c64xx: sort headers alphabetically
        commit: a77ce80f63f06d7ae933c332ed77c79136fa69b0
[02/17] spi: s3c64xx: explicitly include <linux/io.h>
        commit: 42a9ac378d918176e17592cbe79d8b0606f951e4
[03/17] spi: s3c64xx: explicitly include <linux/bits.h>
        commit: 4568fa574fcef3811a8140702979f076ef0f5bc0
[04/17] spi: s3c64xx: explicitly include <linux/types.h>
        commit: 7256d6bdd4fe0eac6d4bcd138c3d87f95f79c750
[05/17] spi: s3c64xx: avoid possible negative array index
        commit: a336d41bbea51e11e3e4f56bd3877a535c077129
[06/17] spi: s3c64xx: fix typo, s/configuartion/configuration
        commit: 97b63f4707046b2ef99d077dd4d333c3acca06ae
[07/17] spi: s3c64xx: remove unneeded (void *) casts in of_match_table
        commit: 271f18816b3ba2f75785660e427c16585b7302f2
[08/17] spi: s3c64xx: remove else after return
        commit: 9d47e411f4d636519a8d26587928d34cf52c0c1f
[09/17] spi: s3c64xx: move common code outside if else
        commit: 5d7f4f4367079992c7a1bb1654ffea87ddc82be8
[10/17] spi: s3c64xx: check return code of dmaengine_slave_config()
        commit: e9c49effde70fb4b10d0ad9c94b69fe6314fc608
[11/17] spi: s3c64xx: propagate the dma_submit_error() error code
        commit: 60dc8d342e933097eb82db5859edcac9077a6db5
[12/17] spi: s3c64xx: rename prepare_dma() to s3c64xx_prepare_dma()
        commit: 4c6452050530b741daf108de0c02cd2299f8f5d1
[13/17] spi: s3c64xx: return ETIMEDOUT for wait_for_completion_timeout()
        commit: 1a234accc93191a3a73eb4cc264abb6d79d63430
[14/17] spi: s3c64xx: drop blank line between declarations
        commit: 91a9b8e6b63eeb3634e736a4b65ae536c08155b2
[15/17] spi: s3c64xx: downgrade dev_warn to dev_dbg for optional dt props
        commit: f186d34071fb2a7db7249b09d5e1796b18b37d7d
[16/17] spi: s3c64xx: remove duplicated definition
        commit: eb8096c30ad07e6201830816e398b3ad603cc096
[17/17] spi: s3c64xx: drop a superfluous bitwise NOT operation
        commit: acd6c7b1d2765fd30b7d7487aff50dc824db314e

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 romain.naour at smile.fr  Thu Feb  8 13:24:21 2024
From: romain.naour at smile.fr (Romain Naour)
Date: Thu,  8 Feb 2024 22:24:21 +0100
Subject: [PATCH 1/2] arm64: dts: ti: k3-am69-sk: fix PMIC interrupt number
Message-ID: <20240208212422.213693-1-romain.naour@smile.fr>

The tps659413 node set WKUP_GPIO0_83 (AA37) pin as input to be used as
PMIC interrupt but uses 39 (WKUP_GPIO0_39) as "interrupts" property.

Replace 39 by 83 after checking in the board schematic [1].

[1] https://www.ti.com/tool/SK-AM69

Fixes: 865a1593bf99 ("arm64: dts: ti: k3-am69-sk: Add support for TPS6594 PMIC")
Cc: Neha Malcom Francis <n-francis at ti.com>
Signed-off-by: Romain Naour <romain.naour at smile.fr>
---
 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 8da591579868..95c9d3da59d3 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -646,7 +646,7 @@ tps659413: pmic at 48 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pmic_irq_pins_default>;
 		interrupt-parent = <&wkup_gpio0>;
-		interrupts = <39 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <83 IRQ_TYPE_EDGE_FALLING>;
 		gpio-controller;
 		#gpio-cells = <2>;
 		ti,primary-pmic;
-- 
2.43.0



From romain.naour at smile.fr  Thu Feb  8 13:24:22 2024
From: romain.naour at smile.fr (Romain Naour)
Date: Thu,  8 Feb 2024 22:24:22 +0100
Subject: [PATCH 2/2] arm64: dts: ti: k3-j721e-sk: fix PMIC interrupt number
In-Reply-To: <20240208212422.213693-1-romain.naour@smile.fr>
References: <20240208212422.213693-1-romain.naour@smile.fr>
Message-ID: <20240208212422.213693-2-romain.naour@smile.fr>

The tps659413 node set WKUP_GPIO0_7 (G28) pin as input to be used as
PMIC interrupt but uses 9 (WKUP_GPIO0_9) as "interrupts" property.

Replace 9 by 7 after checking in the board schematic [1].

[1] https://www.ti.com/tool/SK-TDA4VM

Fixes: b808cef0be46 ("arm64: dts: ti: k3-j721e-sk: Add TPS6594 family PMICs")
Cc: Neha Malcom Francis <n-francis at ti.com>
Signed-off-by: Romain Naour <romain.naour at smile.fr>
---
 arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
index 188dfe291a32..6a8866055f77 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
@@ -574,7 +574,7 @@ tps659413: pmic at 48 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pmic_irq_pins_default>;
 		interrupt-parent = <&wkup_gpio0>;
-		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
 		gpio-controller;
 		#gpio-cells = <2>;
 		ti,primary-pmic;
-- 
2.43.0



From linus.walleij at linaro.org  Thu Feb  8 13:29:11 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 8 Feb 2024 22:29:11 +0100
Subject: [PATCH 01/14] gpio: pca953x: move suspend/resume to suspend_noirq/resume_noirq
In-Reply-To: <95032042-787e-494a-bad9-81b62653de52@bootlin.com>
References: <20240102-j7200-pcie-s2r-v1-0-84e55da52400@bootlin.com>
 <20240102-j7200-pcie-s2r-v1-1-84e55da52400@bootlin.com> <20240116074333.GO5185@atomide.com>
 <31c42f08-7d5e-4b91-87e9-bfc7e2cfdefe@bootlin.com> <CACRpkdYUVbFoDq91uLbUy8twtG_AiD+CY2+nqzCyHV7ZyBC3sA@mail.gmail.com>
 <95032042-787e-494a-bad9-81b62653de52@bootlin.com>
Message-ID: <CACRpkdY2wiw1zH8FsEv7S1FW044PBSXpLPqanF5yyH1R4oteEA@mail.gmail.com>

On Thu, Feb 8, 2024 at 5:19?PM Thomas Richard
<thomas.richard at bootlin.com> wrote:
> On 1/28/24 01:12, Linus Walleij wrote:

> > I guess you could define both pca953x_suspend() and
> > pca953x_suspend_noirq() and selectively bail out on one
> > path on some systems?
>
> Yes.
>
> What do you think if I use a property like for example "ti,pm-noirq" to
> select the right path ?
> Is a property relevant for this use case ?

That's a Linux-specific property and that's useless for other operating
systems and not normally allowed. PM noirq is just some Linux thing.

*FIRST* we should check if putting the callbacks to noirq is fine with
other systems too, and I don't see why not. Perhaps we need to even
merge it if we don't get any test results.

If it doesn't work we can think of other options.

Yours,
Linus Walleij


From andrew at codeconstruct.com.au  Thu Feb  8 13:48:54 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Fri, 09 Feb 2024 08:18:54 +1030
Subject: [PATCH 1/1] ARM:dts:aspeed: Initial device tree for AMD Onyx
 Platform
In-Reply-To: <d4fe8b55-a1ea-4ce7-89ac-ce17e8ff4e45@amd.com>
References: <20240110033543.799919-1-supreeth.venkatesh@amd.com>
	 <d4fe8b55-a1ea-4ce7-89ac-ce17e8ff4e45@amd.com>
Message-ID: <d5d488f2777b34d744d07fbd94f525ae381dca44.camel@codeconstruct.com.au>

On Thu, 2024-02-08 at 08:57 -0600, Supreeth Venkatesh wrote:
> This patch is pending for a month now.
> 
> Can DT maintainers please help review this and provide feedback?

Joel's on leave and I'm having to manage some personal concerns as well
as other professional priorities.

I'm trying to find time to address the BMC patch backlog but it really
is a best-effort thing at the moment.

Andrew


From zajec5 at gmail.com  Thu Feb  8 13:59:23 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu,  8 Feb 2024 22:59:23 +0100
Subject: [PATCH V2 0/3] dt-bindings: arm: mediatek: convert MT7622-related bindings to the json-schema
Message-ID: <20240208215926.10085-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

There are more MediaTek bindings to convert but for now I focused on
those used by MT7622.

V2: Move bindings to /clock/
    Use clock-controller@ nodenames
    Drop incorrectly specified "syscon"

Rafa? Mi?ecki (3):
  dt-bindings: arm: mediatek: convert hifsys to the json-schema clock
  dt-bindings: arm: mediatek: convert PCIESYS to the json-schema clock
  dt-bindings: arm: mediatek: convert SSUSBSYS to the json-schema clock

 .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
 .../arm/mediatek/mediatek,pciesys.txt         | 25 ---------
 .../arm/mediatek/mediatek,ssusbsys.txt        | 25 ---------
 .../clock/mediatek,mt2701-hifsys.yaml         | 51 +++++++++++++++++++
 .../clock/mediatek,mt7622-pciesys.yaml        | 45 ++++++++++++++++
 .../clock/mediatek,mt7622-ssusbsys.yaml       | 45 ++++++++++++++++
 6 files changed, 141 insertions(+), 76 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml

-- 
2.35.3



From zajec5 at gmail.com  Thu Feb  8 13:59:24 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu,  8 Feb 2024 22:59:24 +0100
Subject: [PATCH V2 1/3] dt-bindings: arm: mediatek: convert hifsys to the json-schema clock
In-Reply-To: <20240208215926.10085-1-zajec5@gmail.com>
References: <20240208215926.10085-1-zajec5@gmail.com>
Message-ID: <20240208215926.10085-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Documented "reg" property
2. Documented "#reset-cells" property
3. Dropped "syscon" as it was incorrectly used
4. Adjusted "compatible" and "reg" in example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
 .../clock/mediatek,mt2701-hifsys.yaml         | 51 +++++++++++++++++++
 2 files changed, 51 insertions(+), 26 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
deleted file mode 100644
index 323905af82c3..000000000000
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Mediatek hifsys controller
-============================
-
-The Mediatek hifsys controller provides various clocks and reset
-outputs to the system.
-
-Required Properties:
-
-- compatible: Should be:
-	- "mediatek,mt2701-hifsys", "syscon"
-	- "mediatek,mt7622-hifsys", "syscon"
-	- "mediatek,mt7623-hifsys", "mediatek,mt2701-hifsys", "syscon"
-- #clock-cells: Must be 1
-
-The hifsys controller uses the common clk binding from
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-
-Example:
-
-hifsys: clock-controller at 1a000000 {
-	compatible = "mediatek,mt2701-hifsys", "syscon";
-	reg = <0 0x1a000000 0 0x1000>;
-	#clock-cells = <1>;
-	#reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
new file mode 100644
index 000000000000..eb429337cdf4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt2701-hifsys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek hifsys controller
+
+description:
+  The Mediatek hifsys controller provides various clocks and reset outputs to
+  the system.
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - mediatek,mt2701-hifsys
+              - mediatek,mt7622-hifsys
+      - items:
+          - enum:
+              - mediatek,mt7623-hifsys
+          - const: mediatek,mt2701-hifsys
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+    description: The available clocks are defined in dt-bindings/clock/mt*-clk.h
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - reg
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 1a000000 {
+        compatible = "mediatek,mt2701-hifsys";
+        reg = <0x1a000000 0x1000>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
-- 
2.35.3



From zajec5 at gmail.com  Thu Feb  8 13:59:25 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu,  8 Feb 2024 22:59:25 +0100
Subject: [PATCH V2 2/3] dt-bindings: arm: mediatek: convert PCIESYS to the json-schema clock
In-Reply-To: <20240208215926.10085-1-zajec5@gmail.com>
References: <20240208215926.10085-1-zajec5@gmail.com>
Message-ID: <20240208215926.10085-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Documented "reg" property
2. Dropped "syscon" as it was incorrectly used
3. Adjusted nodename, "compatible" and "reg" in example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../arm/mediatek/mediatek,pciesys.txt         | 25 -----------
 .../clock/mediatek,mt7622-pciesys.yaml        | 45 +++++++++++++++++++
 2 files changed, 45 insertions(+), 25 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
deleted file mode 100644
index d179a61536f4..000000000000
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-MediaTek PCIESYS controller
-============================
-
-The MediaTek PCIESYS controller provides various clocks to the system.
-
-Required Properties:
-
-- compatible: Should be:
-	- "mediatek,mt7622-pciesys", "syscon"
-	- "mediatek,mt7629-pciesys", "syscon"
-- #clock-cells: Must be 1
-- #reset-cells: Must be 1
-
-The PCIESYS controller uses the common clk binding from
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-
-Example:
-
-pciesys: pciesys at 1a100800 {
-	compatible = "mediatek,mt7622-pciesys", "syscon";
-	reg = <0 0x1a100800 0 0x1000>;
-	#clock-cells = <1>;
-	#reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml
new file mode 100644
index 000000000000..27b19d5e3a85
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt7622-pciesys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek PCIESYS controller
+
+description:
+  The MediaTek PCIESYS controller provides various clocks to the system.
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7622-pciesys
+      - mediatek,mt7629-pciesys
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+    description: The available clocks are defined in dt-bindings/clock/mt*-clk.h
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 1a100800 {
+        compatible = "mediatek,mt7622-pciesys";
+        reg = <0x1a100800 0x1000>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
-- 
2.35.3



From zajec5 at gmail.com  Thu Feb  8 13:59:26 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu,  8 Feb 2024 22:59:26 +0100
Subject: [PATCH V2 3/3] dt-bindings: arm: mediatek: convert SSUSBSYS to the json-schema clock
In-Reply-To: <20240208215926.10085-1-zajec5@gmail.com>
References: <20240208215926.10085-1-zajec5@gmail.com>
Message-ID: <20240208215926.10085-4-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Documented "reg" property
2. Dropped "syscon" as it was incorrectly used
3. Adjusted nodename, "compatible" and "reg" in example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../arm/mediatek/mediatek,ssusbsys.txt        | 25 -----------
 .../clock/mediatek,mt7622-ssusbsys.yaml       | 45 +++++++++++++++++++
 2 files changed, 45 insertions(+), 25 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
deleted file mode 100644
index 7cb02c930613..000000000000
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-MediaTek SSUSBSYS controller
-============================
-
-The MediaTek SSUSBSYS controller provides various clocks to the system.
-
-Required Properties:
-
-- compatible: Should be:
-	- "mediatek,mt7622-ssusbsys", "syscon"
-	- "mediatek,mt7629-ssusbsys", "syscon"
-- #clock-cells: Must be 1
-- #reset-cells: Must be 1
-
-The SSUSBSYS controller uses the common clk binding from
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-
-Example:
-
-ssusbsys: ssusbsys at 1a000000 {
-	compatible = "mediatek,mt7622-ssusbsys", "syscon";
-	reg = <0 0x1a000000 0 0x1000>;
-	#clock-cells = <1>;
-	#reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml
new file mode 100644
index 000000000000..5e48c2d3ff11
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt7622-ssusbsys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek SSUSBSYS controller
+
+description:
+  The MediaTek SSUSBSYS controller provides various clocks to the system.
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7622-ssusbsys
+      - mediatek,mt7629-ssusbsys
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+    description: The available clocks are defined in dt-bindings/clock/mt*-clk.h
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 1a000000 {
+        compatible = "mediatek,mt7622-ssusbsys";
+        reg = <0x1a000000 0x1000>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
-- 
2.35.3



From vz at mleia.com  Thu Feb  8 14:50:15 2024
From: vz at mleia.com (Vladimir Zapolskiy)
Date: Fri, 9 Feb 2024 00:50:15 +0200
Subject: [PATCH] mtd: lpc32xx: use typedef for dma_filter_fn
In-Reply-To: <20240208202113.630190-1-krzysztof.kozlowski@linaro.org>
References: <20240208202113.630190-1-krzysztof.kozlowski@linaro.org>
Message-ID: <b42ee1d3-f7b4-5d9d-3df2-1afddac1881a@mleia.com>

On 2/8/24 22:21, Krzysztof Kozlowski wrote:
> Use existing typedef for dma_filter_fn to avoid duplicating type
> definition.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Acked-by: Vladimir Zapolskiy <vz at mleia.com>

--
Best wishes,
Vladimir


From conor at kernel.org  Thu Feb  8 15:10:32 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 8 Feb 2024 23:10:32 +0000
Subject: [PATCH] dt-bindings: interrupt-controller: Convert Atmel AIC to
 json-schema
In-Reply-To: <20240208092015.263210-1-dharma.b@microchip.com>
References: <20240208092015.263210-1-dharma.b@microchip.com>
Message-ID: <20240208-daintily-craftsman-c7f514d49c0f@spud>

Hey Dharma,

Overall this looks alright, but I have a few comments for you.

On Thu, Feb 08, 2024 at 02:50:15PM +0530, Dharma Balasubiramani wrote:

> diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
> new file mode 100644
> index 000000000000..396eac53da3a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
> @@ -0,0 +1,88 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interrupt-controller/atmel,aic.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Advanced Interrupt Controller (AIC)
> +
> +maintainers:
> +  - Nicolas Ferre <nicolas.ferre at microchip.com>
> +  - Dharma balasubiramani <dharma.b at microchip.com>
> +
> +description: |

The chomping operator, |, is not needed here as you have no formatting
to preserve.

> +  The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
> +  maskable, vectored interrupt controller providing handling of up to one
> +  hundred and twenty-eight interrupt sources.

> It is designed to substantially
> +  reduce the software and real-time overhead in handling internal and external
> +  interrupts.

This reeks of a marketing statement and should be removed IMO.

> +allOf:
> +  - $ref: /schemas/interrupt-controller.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - atmel,at91rm9200-aic
> +      - atmel,sama5d2-aic
> +      - atmel,sama5d3-aic
> +      - atmel,sama5d4-aic
> +      - microchip,sam9x60-aic
> +
> +  interrupt-controller: true
> +
> +  "#interrupt-cells":
> +    const: 3
> +    description: |
> +      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
> +      The 2nd cell specifies flags:
> +        bits[3:0] trigger type and level flags:
> +          1 = low-to-high edge triggered.
> +          2 = high-to-low edge triggered.
> +          4 = active high level-sensitive.
> +          8 = active low level-sensitive.
> +        Valid combinations: 1, 2, 3, 4, 8.

Shame that these are not aligned with the IRQ_TYPE defines :(

> +        Default for internal sources: 4 (active high).
> +      The 3rd cell specifies irq priority from 0 (lowest) to 7 (highest).
> +
> +  interrupts:

> +    description: Interrupt source of the parent interrupt controller.

Drop the description, it's obvious.

> +    maxItems: 1
> +
> +  reg:

A nit, but I would put reg after compatible.

> +    description: Specifies base physical address(s) and size of the AIC registers.

Same here.

> +    maxItems: 1
> +
> +  atmel,external-irqs:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description: u32 array of external irqs.
> +
> +required:
> +  - compatible
> +  - interrupt-controller
> +  - "#interrupt-cells"
> +  - reg

A nit, but I would put reg after compatible

> +  - atmel,external-irqs
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    /* AIC */

Drop the comment, its obvious.

> +    aic: interrupt-controller at fffff000 {

The node name here is not used, drop it.

> +      compatible = "atmel,at91rm9200-aic";
> +      interrupt-controller;
> +      #interrupt-cells = <3>;
> +      reg = <0xfffff000 0x200>;
> +      atmel,external-irqs = <31>;
> +    };
> +

> +  - |
> +    /* An interrupt generating device that is wired to an AIC. */
> +    dma: dma-controller at ffffec00 {
> +      compatible = "atmel,at91sam9g45-dma";
> +      #dma-cells = <2>;
> +      reg = <0xffffec00 0x200>;
> +      interrupts = <21 4 5>;
> +    };

And delete this whole example :)

Cheers,
Conor.

-------------- 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/20240208/d1cdecb1/attachment-0001.sig>

From quic_abchauha at quicinc.com  Thu Feb  8 15:11:45 2024
From: quic_abchauha at quicinc.com (Abhishek Chauhan)
Date: Thu,  8 Feb 2024 15:11:45 -0800
Subject: [PATCH net-next v4] net: stmmac: dwmac-qcom-ethqos: Enable TBS on all queues but 0
Message-ID: <20240208231145.2732931-1-quic_abchauha@quicinc.com>

TSO and TBS cannot co-exist. TBS requires special descriptor to be
allocated at bootup. Initialising Tx queues at probe to support
TSO and TBS can help in allocating those resources at bootup.

TX queues with TBS can support etf qdisc hw offload.

This is similar to the patch raised by NXP
commit 3b12ec8f618e ("net: stmmac: dwmac-imx: set TSO/TBS TX queues default settings")

Tested-by: Andrew Halaney <ahalaney at redhat.com> # sa8775p-ride
Signed-off-by: Abhishek Chauhan <quic_abchauha at quicinc.com>
---
Changes since v3:
- The change is Tested-by Andrew Halaney <ahalaney at redhat.com>
  on Qualcomm Ride platform
- Change log is removed from the commit text

Changes since v2:
- Fixed the styling of comment in the dwmac-qcom-ethqos.c
- Followed the upstream format to give other glue
  driver references to solve the same problem
- Appended  the subject with net-next
- Discussion of why this patch is required is discussed in
https://lore.kernel.org/netdev/c2497eef-1041-4cd0-8220-42622c8902f4 at quicinc.com/

Changes since v1:
- Subject is changed as per upstream guidelines
- Added a reference of a similar change done by NXP in
  body of the commit message

 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 31631e3f89d0..2691a250a5a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -728,7 +728,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	struct stmmac_resources stmmac_res;
 	struct device *dev = &pdev->dev;
 	struct qcom_ethqos *ethqos;
-	int ret;
+	int ret, i;
 
 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
 	if (ret)
@@ -822,6 +822,10 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
 	}
 
+	/* Enable TSO on queue0 and enable TBS on rest of the queues */
+	for (i = 1; i < plat_dat->tx_queues_to_use; i++)
+		plat_dat->tx_queues_cfg[i].tbs_en = 1;
+
 	return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
 }
 
-- 
2.25.1



From namhyung at kernel.org  Thu Feb  8 15:58:11 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Thu, 8 Feb 2024 15:58:11 -0800
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <20240208032518.25830-1-yangyicong@huawei.com>
References: <20240208032518.25830-1-yangyicong@huawei.com>
Message-ID: <CAM9d7cga2rzcpUCa+5sZKQ3g_nC5=5XhSdkX1bRCQQUJca8uSw@mail.gmail.com>

Hello,

On Wed, Feb 7, 2024 at 7:29?PM Yicong Yang <yangyicong at huawei.com> wrote:
>
> From: Yicong Yang <yangyicong at hisilicon.com>
>
> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
> throughput and latency of PCIe traffic. With the support of PCIe PMU
> we can enable the perf iostat mode.

Hmm.. so it only works for HiSilicon.  What if users run it on a different
platform?  I think ARM should care about this.

Thanks,
Namhyung


>
> The HiSilicon PCIe PMU can support measuring the throughput of certain
> TLP types and of certain root port. Totally 6 metrics are provided in
> the unit of MB:
>
> - Inbound MWR: The memory write TLPs from the devices downstream the root port
> - Inbound MRD: The memory read TLPs from the devices downstream the root port
> - Inbound CPL: The completion TLPs from the devices downstream the root port
> - Outbound MWR: The memory write TLPs from the CPU to the downstream devices
> - Outbound MRD: The memory read TLPs from the CPU to the downstream devices
> - Outbound CPL: The completions TLPs from the CPU to the downstream devices
>
> Since the PMU measures the throughput in DWords. So we need to calculate
> the throughput in MB like:
>   Count * 4B / 1024 / 1024
>
> Some of the display of the `perf iostat` will be like:
> [root at localhost tmp]# ./perf iostat list
> hisi_pcie0_core2<0000:40:00.0>
> hisi_pcie2_core2<0000:5f:00.0>
> hisi_pcie0_core1<0000:16:00.0>
> hisi_pcie0_core1<0000:16:04.0>
> [root at localhost tmp]# ./perf iostat --timeout 10000
>
>  Performance counter stats for 'system wide':
>
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
>
>       10.008227512 seconds time elapsed
>
> [root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
> -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
> -norandommap -group_reporting -runtime=10 -time_based -bs=64k
>
>  Performance counter stats for 'system wide':
>
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
>
>       10.168561767 seconds time elapsed
>
>        0.465373000 seconds user
>        1.952948000 seconds sys
>
> More information of the HiSilicon PCIe PMU can be found at
> Documentation/admin-guide/perf/hisi-pcie-pmu.rst.
>
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>


From quic_jjohnson at quicinc.com  Thu Feb  8 16:02:21 2024
From: quic_jjohnson at quicinc.com (Jeff Johnson)
Date: Thu, 8 Feb 2024 16:02:21 -0800
Subject: [PATCH net-next v4] net: stmmac: dwmac-qcom-ethqos: Enable TBS on
 all queues but 0
In-Reply-To: <20240208231145.2732931-1-quic_abchauha@quicinc.com>
References: <20240208231145.2732931-1-quic_abchauha@quicinc.com>
Message-ID: <79ae310b-5536-49a3-b3f7-3e4cd2328632@quicinc.com>

On 2/8/2024 3:11 PM, Abhishek Chauhan wrote:
> TSO and TBS cannot co-exist. TBS requires special descriptor to be
> allocated at bootup. Initialising Tx queues at probe to support
> TSO and TBS can help in allocating those resources at bootup.
> 
> TX queues with TBS can support etf qdisc hw offload.
> 
> This is similar to the patch raised by NXP
> commit 3b12ec8f618e ("net: stmmac: dwmac-imx: set TSO/TBS TX queues default settings")
> 
> Tested-by: Andrew Halaney <ahalaney at redhat.com> # sa8775p-ride
> Signed-off-by: Abhishek Chauhan <quic_abchauha at quicinc.com>
Reviewed-by: Jeff Johnson <quic_jjohnson at quicinc.com>



From ak at linux.intel.com  Thu Feb  8 16:13:31 2024
From: ak at linux.intel.com (Andi Kleen)
Date: Thu, 8 Feb 2024 16:13:31 -0800
Subject: [PATCH V5 01/12] perf/core: Add aux_pause, aux_resume,
 aux_start_paused
In-Reply-To: <20240208113127.22216-2-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
 <20240208113127.22216-2-adrian.hunter@intel.com>
Message-ID: <ZcVuK1nnxG18ps-a@tassilo>

> +static void __perf_event_aux_pause(struct perf_event *event, bool pause)
> +{
> +	if (pause) {
> +		if (!READ_ONCE(event->aux_paused)) {
> +			WRITE_ONCE(event->aux_paused, 1);
> +			event->pmu->stop(event, PERF_EF_PAUSE);
> +		}
> +	} else {
> +		if (READ_ONCE(event->aux_paused)) {
> +			WRITE_ONCE(event->aux_paused, 0);
> +			event->pmu->start(event, PERF_EF_RESUME);
> +		}

This doesn't look atomic. Either the READ/WRITE once are not needed,
or you need an actually atomic construct.

> +
> +	rb = ring_buffer_get(event);
> +	if (!rb)
> +		return;
> +
> +	local_irq_save(flags);
> +	/* Guard against NMI, NMI loses here */
> +	if (READ_ONCE(rb->aux_in_pause_resume))
> +		goto out_restore;
> +	WRITE_ONCE(rb->aux_in_pause_resume, 1);


> +	barrier();
> +	__perf_event_aux_pause(event, pause);
> +	barrier();
> +	WRITE_ONCE(rb->aux_in_pause_resume, 0);

Dito.

-Andi


From ak at linux.intel.com  Thu Feb  8 16:16:32 2024
From: ak at linux.intel.com (Andi Kleen)
Date: Thu, 8 Feb 2024 16:16:32 -0800
Subject: [PATCH V5 12/12] perf intel-pt: Add a test for pause / resume
In-Reply-To: <20240208113127.22216-13-adrian.hunter@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
 <20240208113127.22216-13-adrian.hunter@intel.com>
Message-ID: <ZcVu4PPZKgyI1jeO@tassilo>


For Patch 2-12:

Reviewed-by: Andi Kleen <ak at linux.intel.com>



From nmorrisson at phytec.com  Thu Feb  8 16:29:16 2024
From: nmorrisson at phytec.com (Nathan Morrisson)
Date: Thu,  8 Feb 2024 16:29:16 -0800
Subject: [PATCH v2] arm64: dts: ti: am62-phyboard-lyra: Add overlay to enable a GPIO fan
Message-ID: <20240209002916.1284433-1-nmorrisson@phytec.com>

The phyBOARD-Lyra has a GPIO fan header. This overlay enables the fan
header and sets the fan to turn on at 65C.

Signed-off-by: Nathan Morrisson <nmorrisson at phytec.com>
---
v2:
- Change overlay name from k3-am62-... to k3-am62x-...
- Add compile time test

 arch/arm64/boot/dts/ti/Makefile               |  3 ++
 .../ti/k3-am62x-phyboard-lyra-gpio-fan.dtso   | 51 +++++++++++++++++++
 2 files changed, 54 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..bfeb496d5039 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -22,6 +22,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dahlia.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-mallow.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-phyboard-lyra-gpio-fan.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
 
 # Boards with AM62Ax SoC
@@ -87,6 +88,8 @@ k3-am625-beagleplay-csi2-ov5640-dtbs := k3-am625-beagleplay.dtb \
 	k3-am625-beagleplay-csi2-ov5640.dtbo
 k3-am625-beagleplay-csi2-tevi-ov5640-dtbs := k3-am625-beagleplay.dtb \
 	k3-am625-beagleplay-csi2-tevi-ov5640.dtbo
+k3-am625-phyboard-lyra-gpio-fan-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
+	k3-am62x-phyboard-lyra-gpio-fan.dtbo
 k3-am625-sk-csi2-imx219-dtbs := k3-am625-sk.dtb \
 	k3-am62x-sk-csi2-imx219.dtbo
 k3-am625-sk-csi2-ov5640-dtbs := k3-am625-sk.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso
new file mode 100644
index 000000000000..9c05748bdd9d
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2024 PHYTEC America LLC
+ * Author: Garrett Giordano <ggiordano at phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	fan: gpio-fan {
+		compatible = "gpio-fan";
+		gpio-fan,speed-map = <0 0 8600 1>;
+		gpios = <&main_gpio0 40 GPIO_ACTIVE_LOW>;
+		#cooling-cells = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_fan_pins_default>;
+		status = "okay";
+	};
+};
+
+&main_pmx0 {
+	gpio_fan_pins_default: gpio-fan-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0a4, PIN_OUTPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
+		>;
+	};
+};
+
+&thermal_zones {
+	main0_thermal: main0-thermal {
+		trips {
+			main0_thermal_trip0: main0-thermal-trip {
+				temperature = <65000>;  /* millicelsius */
+				hysteresis = <2000>;    /* millicelsius */
+				type = "active";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&main0_thermal_trip0>;
+				cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+};
-- 
2.25.1



From andre.przywara at arm.com  Thu Feb  8 16:54:46 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 9 Feb 2024 00:54:46 +0000
Subject: [PATCH 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC
 support
In-Reply-To: <1957012.PYKUYFuaPT@jernej-laptop>
References: <20240204094404.149776-1-andre.przywara@arm.com>
	<8d9d1d7c-8066-4400-8fe4-68aa0e28023d@arm.com>
	<10413667.nUPlyArG6x@jernej-laptop>
	<1957012.PYKUYFuaPT@jernej-laptop>
Message-ID: <20240209005446.7fb50882@minigeek.lan>

On Tue, 06 Feb 2024 19:27:22 +0100
Jernej ?krabec <jernej.skrabec at gmail.com> wrote:

Hi,

....

> > > >>>>> +&mmc2 {
> > > >>>>> +	pinctrl-names = "default";
> > > >>>>> +	pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
> > > >>>>> +	vmmc-supply = <&reg_dcdc1>;
> > > >>>>> +	vqmmc-supply = <&reg_eldo1>;
> > > >>>>> +	bus-width = <8>;
> > > >>>>> +	non-removable;
> > > >>>>> +	mmc-ddr-1_8v;
> > > >>>>> +	mmc-hs200-1_8v;  
> > > >>>>
> > > >>>> Aren't these speed modes enabled by default?  
> > > >>
> > > >> Enabled by who? Our current sunxi-mmc driver? I cannot find anything in
> > > >> the binding that suggests that there would be some default settings.  
> > > > 
> > > > Looking at Linux sunxi mmc driver, mmc-ddr-1_8v is enabled by default for
> > > > "new timings" variants except for H5. Anyway...  
> > > 
> > > But this is a Linux implementation detail, which we should not rely on 
> > > in a DT? And if I remember Maxime correctly back then, the plan was to 
> > > avoid those driver hacks and just say what we support in the DT, going 
> > > forward. This might be needed for other OSes, which might not support 
> > > HS-200?  
> > > >>> Sorry, mmc-hs200-1_8v is ok, but mmc-ddr-1_8v should be
> > > >>> removed.  
> > > >>
> > > >> Mmh, I am confused: I thought after the H5 eMMC mishap we figured that
> > > >> all speed modes supported by the eMMC chip should be listed in the DT?  
> > > > 
> > > > I think H5 just has (had?) driver issue. From what I can see, only highest
> > > > supported mode by kernel and chip is specified in all Allwinner DTs.
> > > > mmc-ddr-1_8v is only specified by two recent board addition, where I missed
> > > > it while reviewing.
> > > >   
> > > >> So any driver wouldn't need to make assumptions, and if a particular
> > > >> mode shows problems on a board, we just remove that mode from the DT.
> > > >> Actually, thinking about that, I guess I should list HS-400 as well? The
> > > >> BSP kernel uses that mode.  
> > > > 
> > > > Sure, but it also calibrates timing for it. If you'll specify HS400, kernel
> > > > will try to use it, but it won't work.  
> > > 
> > > But this is also a limitation of the current Linux kernel driver. And 
> > > since we indeed don't support HS-400, we explicitly remove it from the 
> > > capability list, *after* the call to mmc_of_parse():
> > > 
> > > drivers/mmc/host/sunxi-mmc.c:1460
> > >          /* TODO: This driver doesn't support HS400 mode yet */
> > >          mmc->caps2 &= ~MMC_CAP2_HS400;
> > > 
> > > So I think this should be safe?  
> > 
> > Right. Can you test it?
> > 
> > Best regards,
> > Jernej
> >   
> > > 
> > > Cheers,
> > > Andre
> > >   
> > > >   
> > > >> Or do you mean to say that in particular DDR (@1.8V) is problematic? I
> > > >> cannot test at the moment, but could try later to force that mode.  
> > > > 
> > > > No, no need.  
> 
> If we go in new direction, then it would be good to test it.

So I did this, and curiously enough MMC DDR didn't work. It's a bit
odd, since 50 MHz DDR sounds less problematic than 200 MHz SDR, but
apparently there is more than just the frequency at play here.
Announcing HS-400 didn't make a difference in Linux, as expected, since
the driver filters it out.

So I will drop mmc-ddr-1_8v, but add mmc-hs400-1_8v.

Thanks,
Andre


> 
> Best regards,
> Jernej
> 
> > > > 
> > > > Best regards,
> > > > Jernej
> > > >   
> > > >>
> > > >> Cheers,
> > > >> Andre
> > > >>
> > > >>  
> > > >>>>> +	cap-mmc-hw-reset;
> > > >>>>> +	status = "okay";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&ohci0 {
> > > >>>>> +	status = "okay";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&ohci1 {
> > > >>>>> +	status = "okay";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&pio {
> > > >>>>> +	vcc-pb-supply = <&reg_dcdc1>;
> > > >>>>> +	vcc-pc-supply = <&reg_dcdc1>;
> > > >>>>> +	vcc-pd-supply = <&reg_dcdc1>;
> > > >>>>> +	vcc-pe-supply = <&reg_dcdc1>;
> > > >>>>> +	vcc-pf-supply = <&reg_dcdc1>;
> > > >>>>> +	vcc-pg-supply = <&reg_dldo4>;
> > > >>>>> +	vcc-ph-supply = <&reg_dcdc1>;
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&r_ir {
> > > >>>>> +	status = "okay";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&r_pio {
> > > >>>>> +	/*
> > > >>>>> +	 * We cannot add that supply for now since it would create a circular
> > > >>>>> +	 * dependency between pinctrl, the regulator and the RSB Bus.
> > > >>>>> +	 *
> > > >>>>> +	 * vcc-pl-supply = <&reg_aldo2>;
> > > >>>>> +	 */
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&r_rsb {
> > > >>>>> +	status = "okay";
> > > >>>>> +
> > > >>>>> +	axp803: pmic at 3a3 {
> > > >>>>> +		compatible = "x-powers,axp803";
> > > >>>>> +		reg = <0x3a3>;
> > > >>>>> +		interrupt-parent = <&r_intc>;
> > > >>>>> +		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
> > > >>>>> +		x-powers,drive-vbus-en;
> > > >>>>> +
> > > >>>>> +		vin1-supply = <&reg_vcc5v>;
> > > >>>>> +		vin2-supply = <&reg_vcc5v>;
> > > >>>>> +		vin3-supply = <&reg_vcc5v>;
> > > >>>>> +		vin5-supply = <&reg_vcc5v>;
> > > >>>>> +		vin6-supply = <&reg_vcc5v>;
> > > >>>>> +		aldoin-supply = <&reg_vcc5v>;
> > > >>>>> +		dldoin-supply = <&reg_vcc5v>;
> > > >>>>> +		eldoin-supply = <&reg_vcc5v>;
> > > >>>>> +		fldoin-supply = <&reg_vcc5v>;
> > > >>>>> +		drivevbus-supply = <&reg_vcc5v>;
> > > >>>>> +		ips-supply = <&reg_vcc5v>;
> > > >>>>> +
> > > >>>>> +		status = "okay";
> > > >>>>> +	};
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +#include "axp803.dtsi"
> > > >>>>> +
> > > >>>>> +&ac_power_supply {
> > > >>>>> +	status = "okay";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&reg_dcdc1 {
> > > >>>>> +	regulator-always-on;
> > > >>>>> +	regulator-min-microvolt = <3300000>;
> > > >>>>> +	regulator-max-microvolt = <3300000>;
> > > >>>>> +	regulator-name = "vcc-3v3";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&reg_dcdc2 {
> > > >>>>> +	regulator-always-on;
> > > >>>>> +	regulator-min-microvolt = <1040000>;
> > > >>>>> +	regulator-max-microvolt = <1300000>;
> > > >>>>> +	regulator-name = "vdd-cpux";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +/* DCDC3 is polyphased with DCDC2 */
> > > >>>>> +
> > > >>>>> +&reg_dcdc5 {
> > > >>>>> +	regulator-always-on;
> > > >>>>> +	regulator-min-microvolt = <1500000>;
> > > >>>>> +	regulator-max-microvolt = <1500000>;
> > > >>>>> +	regulator-name = "vcc-dram";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +/* Deviates from the reset default of 1.1V. */
> > > >>>>> +&reg_dcdc6 {
> > > >>>>> +	regulator-always-on;
> > > >>>>> +	regulator-min-microvolt = <1200000>;
> > > >>>>> +	regulator-max-microvolt = <1200000>;
> > > >>>>> +	regulator-name = "vdd-sys";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&reg_aldo1 {
> > > >>>>> +	regulator-min-microvolt = <3300000>;
> > > >>>>> +	regulator-max-microvolt = <3300000>;
> > > >>>>> +	regulator-name = "vcc-wifi";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&reg_aldo2 {
> > > >>>>> +	/* Specifying R_PIO consumer would create circular dependency. */
> > > >>>>> +	regulator-always-on;
> > > >>>>> +	regulator-min-microvolt = <3300000>;
> > > >>>>> +	regulator-max-microvolt = <3300000>;
> > > >>>>> +	regulator-name = "vcc-pl";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&reg_aldo3 {
> > > >>>>> +	regulator-always-on;
> > > >>>>> +	regulator-min-microvolt = <3000000>;
> > > >>>>> +	regulator-max-microvolt = <3000000>;
> > > >>>>> +	regulator-name = "vcc-pll-avcc";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +/* AC200 power supply */
> > > >>>>> +&reg_dldo1 {
> > > >>>>> +	regulator-always-on;
> > > >>>>> +	regulator-min-microvolt = <3300000>;
> > > >>>>> +	regulator-max-microvolt = <3300000>;
> > > >>>>> +	regulator-name = "vcc-ave-33";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&reg_dldo4 {
> > > >>>>> +	regulator-min-microvolt = <3300000>;
> > > >>>>> +	regulator-max-microvolt = <3300000>;
> > > >>>>> +	regulator-name = "vcc-wifi-io";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&reg_drivevbus {
> > > >>>>> +	regulator-name = "usb0-vbus";
> > > >>>>> +	status = "okay";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&reg_eldo1 {
> > > >>>>> +	regulator-always-on;
> > > >>>>> +	regulator-min-microvolt = <1800000>;
> > > >>>>> +	regulator-max-microvolt = <1800000>;
> > > >>>>> +	regulator-name = "vcc-cpvdd-dram-emmc";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +/* Supplies the arisc management core, needed by TF-A to power off cores. */
> > > >>>>> +&reg_fldo2 {
> > > >>>>> +	regulator-always-on;
> > > >>>>> +	regulator-min-microvolt = <1100000>;
> > > >>>>> +	regulator-max-microvolt = <1100000>;
> > > >>>>> +	regulator-name = "vdd-cpus";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&reg_rtc_ldo {
> > > >>>>> +	regulator-name = "vcc-rtc";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&simplefb_hdmi {
> > > >>>>> +	vcc-hdmi-supply = <&reg_dcdc1>;
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&sound {
> > > >>>>> +	simple-audio-card,aux-devs = <&codec_analog>;
> > > >>>>> +	simple-audio-card,widgets = "Microphone", "Microphone Jack",
> > > >>>>> +				    "Headphone", "Headphone Jack";
> > > >>>>> +	simple-audio-card,routing =
> > > >>>>> +			"Left DAC", "DACL",
> > > >>>>> +			"Right DAC", "DACR",
> > > >>>>> +			"Headphone Jack", "HP",
> > > >>>>> +			"ADCL", "Left ADC",
> > > >>>>> +			"ADCR", "Right ADC",
> > > >>>>> +			"MIC2", "Microphone Jack";
> > > >>>>> +	status = "okay";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +/* On the (unpopulated) UART pads. */
> > > >>>>> +&uart0 {
> > > >>>>> +	pinctrl-names = "default";
> > > >>>>> +	pinctrl-0 = <&uart0_pb_pins>;
> > > >>>>> +	status = "okay";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&uart1 {
> > > >>>>> +	pinctrl-names = "default";
> > > >>>>> +	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
> > > >>>>> +	uart-has-rtscts;
> > > >>>>> +	status = "okay";
> > > >>>>> +
> > > >>>>> +	bluetooth {
> > > >>>>> +		compatible = "realtek,rtl8723bs-bt";
> > > >>>>> +		enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
> > > >>>>> +		max-speed = <1500000>;
> > > >>>>> +	};
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&usb_otg {
> > > >>>>> +	dr_mode = "host";
> > > >>>>> +	status = "okay";
> > > >>>>> +};
> > > >>>>> +
> > > >>>>> +&usbphy {
> > > >>>>> +	usb0_vbus-supply = <&reg_drivevbus>;
> > > >>>>> +	usb1_vbus-supply = <&reg_drivevbus>;
> > > >>>>> +	status = "okay";
> > > >>>>> +};
> > > >>>>>  
> > > >>>>
> > > >>>>
> > > >>>>
> > > >>>>
> > > >>>>  
> > > >>>
> > > >>>
> > > >>>
> > > >>>  
> > > >>  
> > > > 
> > > > 
> > > > 
> > > >   
> > >   
> > 
> > 
> > 
> > 
> >   
> 
> 
> 
> 
> 



From leo.yan at linaro.org  Thu Feb  8 17:08:51 2024
From: leo.yan at linaro.org (Leo Yan)
Date: Fri, 9 Feb 2024 09:08:51 +0800
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <CAM9d7cga2rzcpUCa+5sZKQ3g_nC5=5XhSdkX1bRCQQUJca8uSw@mail.gmail.com>
References: <20240208032518.25830-1-yangyicong@huawei.com>
 <CAM9d7cga2rzcpUCa+5sZKQ3g_nC5=5XhSdkX1bRCQQUJca8uSw@mail.gmail.com>
Message-ID: <20240209010851.GB297921@leoy-yangtze.lan>

On Thu, Feb 08, 2024 at 03:58:11PM -0800, Namhyung Kim wrote:
> Hello,
> 
> On Wed, Feb 7, 2024 at 7:29???PM Yicong Yang <yangyicong at huawei.com> wrote:
> >
> > From: Yicong Yang <yangyicong at hisilicon.com>
> >
> > Some HiSilicon platforms provide PCIe PMU devices for monitoring the
> > throughput and latency of PCIe traffic. With the support of PCIe PMU
> > we can enable the perf iostat mode.
> 
> Hmm.. so it only works for HiSilicon.  What if users run it on a different
> platform?  I think ARM should care about this.

I will give a review for this patch.

Thanks,
Leo


From wsa+renesas at sang-engineering.com  Thu Feb  8 17:58:15 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Fri,  9 Feb 2024 02:58:15 +0100
Subject: [PATCH 0/6] mfd: tmio: simplify header and move to platform_data
Message-ID: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>

The MFD parts of the TMIO have been removed by Arnd, so that only the
SD/MMC related functionality is left. Remove the outdated remains in the
public header file and then move it to platform_data as the data is now
specific for the SD/MMC part.

Based on 6.8-rc3, build bot is happy. Branch is here:

git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/sdhi/tmio-simplification

I'd suggest this goes via the MFD tree, so the series would need acks
from the MMC and SH maintainers. Is that okay with everyone?

All the best!

   Wolfram


Wolfram Sang (6):
  mfd: tmio: remove obsolete platform_data
  mfd: tmio: remove obsolete io accessors
  mmc: tmio/sdhi: fix includes
  mfd: tmio: update include files
  mfd: tmio: sanitize comments
  mfd: tmio: move header to platform_data

 MAINTAINERS                                   |   2 +-
 arch/sh/boards/board-sh7757lcr.c              |   2 +-
 arch/sh/boards/mach-ap325rxa/setup.c          |   2 +-
 arch/sh/boards/mach-ecovec24/setup.c          |   2 +-
 arch/sh/boards/mach-kfr2r09/setup.c           |   2 +-
 arch/sh/boards/mach-migor/setup.c             |   2 +-
 arch/sh/boards/mach-se/7724/setup.c           |   2 +-
 drivers/mmc/host/renesas_sdhi_core.c          |   2 +-
 drivers/mmc/host/renesas_sdhi_internal_dmac.c |   5 +-
 drivers/mmc/host/renesas_sdhi_sys_dmac.c      |   5 +-
 drivers/mmc/host/tmio_mmc_core.c              |   3 +-
 drivers/mmc/host/uniphier-sd.c                |   2 +-
 include/linux/mfd/tmio.h                      | 133 ------------------
 include/linux/platform_data/tmio.h            |  64 +++++++++
 14 files changed, 81 insertions(+), 147 deletions(-)
 delete mode 100644 include/linux/mfd/tmio.h
 create mode 100644 include/linux/platform_data/tmio.h

-- 
2.43.0



From wsa+renesas at sang-engineering.com  Thu Feb  8 17:58:21 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Fri,  9 Feb 2024 02:58:21 +0100
Subject: [PATCH 6/6] mfd: tmio: move header to platform_data
In-Reply-To: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
References: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
Message-ID: <20240209015817.14627-14-wsa+renesas@sang-engineering.com>

All the MFD components are gone from the header meanwhile. Only the MMC
relevant data is left which makes it a platform_data for the MMC
controller. Move the header to the now fitting directory.

Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
---
 MAINTAINERS                                   | 2 +-
 arch/sh/boards/board-sh7757lcr.c              | 2 +-
 arch/sh/boards/mach-ap325rxa/setup.c          | 2 +-
 arch/sh/boards/mach-ecovec24/setup.c          | 2 +-
 arch/sh/boards/mach-kfr2r09/setup.c           | 2 +-
 arch/sh/boards/mach-migor/setup.c             | 2 +-
 arch/sh/boards/mach-se/7724/setup.c           | 2 +-
 drivers/mmc/host/renesas_sdhi_core.c          | 2 +-
 drivers/mmc/host/renesas_sdhi_internal_dmac.c | 2 +-
 drivers/mmc/host/renesas_sdhi_sys_dmac.c      | 2 +-
 drivers/mmc/host/tmio_mmc_core.c              | 2 +-
 drivers/mmc/host/uniphier-sd.c                | 2 +-
 include/linux/{mfd => platform_data}/tmio.h   | 0
 13 files changed, 12 insertions(+), 12 deletions(-)
 rename include/linux/{mfd => platform_data}/tmio.h (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 960512bec428..c4e20abd177b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22154,7 +22154,7 @@ L:	linux-renesas-soc at vger.kernel.org
 S:	Supported
 F:	drivers/mmc/host/renesas_sdhi*
 F:	drivers/mmc/host/tmio_mmc*
-F:	include/linux/mfd/tmio.h
+F:	include/linux/platform_data/tmio.h
 
 TMP401 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux at roeck-us.net>
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
index f39c8196efdf..4014c042d2a5 100644
--- a/arch/sh/boards/board-sh7757lcr.c
+++ b/arch/sh/boards/board-sh7757lcr.c
@@ -14,9 +14,9 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/io.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_data/sh_mmcif.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/sh_eth.h>
 #include <linux/sh_intc.h>
 #include <linux/usb/renesas_usbhs.h>
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 645cccf3da88..bb5004a8ac02 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -24,10 +24,10 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/sh_flctl.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 30d117f9ad7e..6f13557eecd6 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -17,13 +17,13 @@
 #include <linux/input/sh_keysc.h>
 #include <linux/interrupt.h>
 #include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_data/sh_mmcif.h>
 #include <linux/mtd/physmap.h>
 #include <linux/gpio.h>
 #include <linux/gpio/machine.h>
 #include <linux/platform_data/gpio_backlight.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_data/tsc2007.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/fixed.h>
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 6b775eae85c0..70236859919d 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -22,10 +22,10 @@
 #include <linux/input/sh_keysc.h>
 #include <linux/interrupt.h>
 #include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_data/lv5207lp.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 773ee767d0c4..1853e6319a66 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -7,6 +7,7 @@
 #include <linux/clkdev.h>
 #include <linux/dma-map-ops.h>
 #include <linux/init.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
@@ -14,7 +15,6 @@
 #include <linux/memblock.h>
 #include <linux/mmc/host.h>
 #include <linux/mtd/physmap.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mtd/platnand.h>
 #include <linux/i2c.h>
 #include <linux/regulator/fixed.h>
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 787ddd3c627a..e500feb91053 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -21,9 +21,9 @@
 #include <linux/input/sh_keysc.h>
 #include <linux/interrupt.h>
 #include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mtd/physmap.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index c675dec587ef..f84f60139bcf 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -22,13 +22,13 @@
 #include <linux/delay.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/slot-gpio.h>
 #include <linux/module.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/pinctrl-state.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/regulator/consumer.h>
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
index 24e1c17908d7..97cd55fec0bf 100644
--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
@@ -11,12 +11,12 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io-64-nonatomic-hi-lo.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pagemap.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
index c18581897f8a..68e31c37cce6 100644
--- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
@@ -11,12 +11,12 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pagemap.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index c39141a5bd23..0c4397b3cffd 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -31,7 +31,6 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
@@ -39,6 +38,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pagemap.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c
index 1404989e6151..bd231dbe90ba 100644
--- a/drivers/mmc/host/uniphier-sd.c
+++ b/drivers/mmc/host/uniphier-sd.c
@@ -9,11 +9,11 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/mfd/syscon.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pinctrl/consumer.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
diff --git a/include/linux/mfd/tmio.h b/include/linux/platform_data/tmio.h
similarity index 100%
rename from include/linux/mfd/tmio.h
rename to include/linux/platform_data/tmio.h
-- 
2.43.0



From vigneshr at ti.com  Thu Feb  8 20:31:57 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Fri, 9 Feb 2024 10:01:57 +0530
Subject: [PATCH 1/3] arm64: dts: ti: k3-j7200-common-proc-board: Modify
 Pinmux for wakeup and mcu uart
In-Reply-To: <20240208110602.931573-2-b-kapoor@ti.com>
References: <20240208110602.931573-1-b-kapoor@ti.com>
 <20240208110602.931573-2-b-kapoor@ti.com>
Message-ID: <f9030cae-d059-4083-91d3-d790a889d012@ti.com>



On 08/02/24 16:36, Bhavya Kapoor wrote:
> WKUP_PADCONFIG registers for wakeup and mcu uart lies
> under wkup_pmx2 for J7200. Thus, modify pinmux for both
> of them.
> 
> Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
> ---
>  .../boot/dts/ti/k3-j7200-common-proc-board.dts | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
> index 1d8bddcae90e..6593c5da82c0 100644
> --- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
> +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
> @@ -119,24 +119,25 @@ transceiver3: can-phy3 {
>  };
>  
>  &wkup_pmx0 {
> +};
> +
> +&wkup_pmx2 {
>  	mcu_uart0_pins_default: mcu-uart0-default-pins {
>  		pinctrl-single,pins = <
> -			J721E_WKUP_IOPAD(0xf4, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
> -			J721E_WKUP_IOPAD(0xf0, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
> -			J721E_WKUP_IOPAD(0xf8, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
> -			J721E_WKUP_IOPAD(0xfc, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
> +			J721E_WKUP_IOPAD(0x90, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
> +			J721E_WKUP_IOPAD(0x94, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
> +			J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
> +			J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
>  		>;
>  	};
>  
>  	wkup_uart0_pins_default: wkup-uart0-default-pins {
>  		pinctrl-single,pins = <
> -			J721E_WKUP_IOPAD(0xb0, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
> -			J721E_WKUP_IOPAD(0xb4, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
> +			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
> +			J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
>  		>;
>  	};
> -};
>  
> -&wkup_pmx2 {
>  	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
>  		pinctrl-single,pins = <
>  			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
> @@ -272,7 +273,6 @@ &mcu_uart0 {
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&mcu_uart0_pins_default>;
> -	clock-frequency = <96000000>;

You are not only modifying pinmux but also dropping clock-frequency for
mcu_uart. Please split that out into separate patch with rationale for
the same.


>  };
>  
>  &main_uart0 {

-- 
Regards
Vignesh


From vigneshr at ti.com  Thu Feb  8 20:37:21 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Fri, 9 Feb 2024 10:07:21 +0530
Subject: [PATCH 2/3] arm64: dts: ti: k3-j721s2-common-proc-board: Remove
 Pinmux for CTS and RTS in Wakeup Uart
In-Reply-To: <20240208110602.931573-3-b-kapoor@ti.com>
References: <20240208110602.931573-1-b-kapoor@ti.com>
 <20240208110602.931573-3-b-kapoor@ti.com>
Message-ID: <eec99081-cb76-4170-ad99-5faf47e17cd8@ti.com>



On 08/02/24 16:36, Bhavya Kapoor wrote:
> Only Tx and Rx Signal lines for wake up uart are brought out on

Please be consistent when referring to instance names

s/wake up uart/wkup_uart0

applies to $subject and in commit msg (same issue in patch 3/3 too)

> the Common Proc Board through SoM, but CTS and RTS signal lines
> are not brought on the board. Thus, remove pinmux for CTS and RTS
> signal lines for wake up uart in J721S2.
> 
> Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
> ---
>  arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
> index 361365bb5523..6371cb1c1fe7 100644
> --- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
> +++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
> @@ -190,8 +190,6 @@ J721S2_IOPAD(0x038, PIN_OUTPUT, 0) /* (AB28) MCASP0_ACLKX.MCAN5_TX */
>  &wkup_pmx2 {
>  	wkup_uart0_pins_default: wkup-uart0-default-pins {
>  		pinctrl-single,pins = <
> -			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (E25) WKUP_GPIO0_6.WKUP_UART0_CTSn */
> -			J721S2_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (F28) WKUP_GPIO0_7.WKUP_UART0_RTSn */
>  			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */
>  			J721S2_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */
>  		>;

-- 
Regards
Vignesh


From herbert at gondor.apana.org.au  Thu Feb  8 21:00:00 2024
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 9 Feb 2024 13:00:00 +0800
Subject: [PATCH] crypto: xilinx: call finalize with bh disabled
In-Reply-To: <20240128042906.557038-1-quanyang.wang@windriver.com>
References: <20240128042906.557038-1-quanyang.wang@windriver.com>
Message-ID: <ZcWxUMVA2LjP0/Dw@gondor.apana.org.au>

On Sun, Jan 28, 2024 at 12:29:06PM +0800, quanyang.wang at windriver.com wrote:
> From: Quanyang Wang <quanyang.wang at windriver.com>
> 
> When calling crypto_finalize_request, BH should be disabled to avoid
> triggering the following calltrace:
> 
>     ------------[ cut here ]------------
>     WARNING: CPU: 2 PID: 74 at crypto/crypto_engine.c:58 crypto_finalize_request+0xa0/0x118
>     Modules linked in: cryptodev(O)
>     CPU: 2 PID: 74 Comm: firmware:zynqmp Tainted: G           O       6.8.0-rc1-yocto-standard #323
>     Hardware name: ZynqMP ZCU102 Rev1.0 (DT)
>     pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>     pc : crypto_finalize_request+0xa0/0x118
>     lr : crypto_finalize_request+0x104/0x118
>     sp : ffffffc085353ce0
>     x29: ffffffc085353ce0 x28: 0000000000000000 x27: ffffff8808ea8688
>     x26: ffffffc081715038 x25: 0000000000000000 x24: ffffff880100db00
>     x23: ffffff880100da80 x22: 0000000000000000 x21: 0000000000000000
>     x20: ffffff8805b14000 x19: ffffff880100da80 x18: 0000000000010450
>     x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>     x14: 0000000000000003 x13: 0000000000000000 x12: ffffff880100dad0
>     x11: 0000000000000000 x10: ffffffc0832dcd08 x9 : ffffffc0812416d8
>     x8 : 00000000000001f4 x7 : ffffffc0830d2830 x6 : 0000000000000001
>     x5 : ffffffc082091000 x4 : ffffffc082091658 x3 : 0000000000000000
>     x2 : ffffffc7f9653000 x1 : 0000000000000000 x0 : ffffff8802d20000
>     Call trace:
>      crypto_finalize_request+0xa0/0x118
>      crypto_finalize_aead_request+0x18/0x30
>      zynqmp_handle_aes_req+0xcc/0x388
>      crypto_pump_work+0x168/0x2d8
>      kthread_worker_fn+0xfc/0x3a0
>      kthread+0x118/0x138
>      ret_from_fork+0x10/0x20
>     irq event stamp: 40
>     hardirqs last  enabled at (39): [<ffffffc0812416f8>] _raw_spin_unlock_irqrestore+0x70/0xb0
>     hardirqs last disabled at (40): [<ffffffc08122d208>] el1_dbg+0x28/0x90
>     softirqs last  enabled at (36): [<ffffffc080017dec>] kernel_neon_begin+0x8c/0xf0
>     softirqs last disabled at (34): [<ffffffc080017dc0>] kernel_neon_begin+0x60/0xf0
>     ---[ end trace 0000000000000000 ]---
> 
> Signed-off-by: Quanyang Wang <quanyang.wang at windriver.com>
> ---
>  drivers/crypto/xilinx/zynqmp-aes-gcm.c | 3 +++
>  1 file changed, 3 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 w.egorov at phytec.de  Thu Feb  8 21:26:18 2024
From: w.egorov at phytec.de (Wadim Egorov)
Date: Fri, 9 Feb 2024 06:26:18 +0100
Subject: [PATCH v2] arm64: dts: ti: am62-phyboard-lyra: Add overlay to
 enable a GPIO fan
In-Reply-To: <20240209002916.1284433-1-nmorrisson@phytec.com>
References: <20240209002916.1284433-1-nmorrisson@phytec.com>
Message-ID: <1ab1d500-1429-4dc2-b31a-fc24d171206f@phytec.de>

Hi Nathan,

Am 09.02.24 um 01:29 schrieb Nathan Morrisson:
> The phyBOARD-Lyra has a GPIO fan header. This overlay enables the fan
> header and sets the fan to turn on at 65C.
>
> Signed-off-by: Nathan Morrisson <nmorrisson at phytec.com>
> ---
> v2:
> - Change overlay name from k3-am62-... to k3-am62x-...
> - Add compile time test
>
>   arch/arm64/boot/dts/ti/Makefile               |  3 ++
>   .../ti/k3-am62x-phyboard-lyra-gpio-fan.dtso   | 51 +++++++++++++++++++
>   2 files changed, 54 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso
>
> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
> index 52c1dc910308..bfeb496d5039 100644
> --- a/arch/arm64/boot/dts/ti/Makefile
> +++ b/arch/arm64/boot/dts/ti/Makefile
> @@ -22,6 +22,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dahlia.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-mallow.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
> +dtb-$(CONFIG_ARCH_K3) += k3-am62x-phyboard-lyra-gpio-fan.dtbo
>   dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
>   
>   # Boards with AM62Ax SoC
> @@ -87,6 +88,8 @@ k3-am625-beagleplay-csi2-ov5640-dtbs := k3-am625-beagleplay.dtb \
>   	k3-am625-beagleplay-csi2-ov5640.dtbo
>   k3-am625-beagleplay-csi2-tevi-ov5640-dtbs := k3-am625-beagleplay.dtb \
>   	k3-am625-beagleplay-csi2-tevi-ov5640.dtbo
> +k3-am625-phyboard-lyra-gpio-fan-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
> +	k3-am62x-phyboard-lyra-gpio-fan.dtbo
>   k3-am625-sk-csi2-imx219-dtbs := k3-am625-sk.dtb \
>   	k3-am62x-sk-csi2-imx219.dtbo
>   k3-am625-sk-csi2-ov5640-dtbs := k3-am625-sk.dtb \
> diff --git a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso
> new file mode 100644
> index 000000000000..9c05748bdd9d
> --- /dev/null
> +++ b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso
> @@ -0,0 +1,51 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +/*
> + * Copyright (C) 2024 PHYTEC America LLC
> + * Author: Garrett Giordano <ggiordano at phytec.com>
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/thermal/thermal.h>
> +#include "k3-pinctrl.h"
> +
> +&{/} {
> +	fan: gpio-fan {
> +		compatible = "gpio-fan";
> +		gpio-fan,speed-map = <0 0 8600 1>;
> +		gpios = <&main_gpio0 40 GPIO_ACTIVE_LOW>;
> +		#cooling-cells = <2>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&gpio_fan_pins_default>;
> +		status = "okay";

There is no need to set the status. If no status is present, it also 
indicates that the node is activated.

With this change,

Reviewed-by: Wadim Egorov <w.egorov at phytec.de>


> +	};
> +};
> +
> +&main_pmx0 {
> +	gpio_fan_pins_default: gpio-fan-default-pins {
> +		pinctrl-single,pins = <
> +			AM62X_IOPAD(0x0a4, PIN_OUTPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
> +		>;
> +	};
> +};
> +
> +&thermal_zones {
> +	main0_thermal: main0-thermal {
> +		trips {
> +			main0_thermal_trip0: main0-thermal-trip {
> +				temperature = <65000>;  /* millicelsius */
> +				hysteresis = <2000>;    /* millicelsius */
> +				type = "active";
> +			};
> +		};
> +
> +		cooling-maps {
> +			map0 {
> +				trip = <&main0_thermal_trip0>;
> +				cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> +			};
> +		};
> +	};
> +};


From anshuman.khandual at arm.com  Thu Feb  8 21:42:21 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri,  9 Feb 2024 11:12:21 +0530
Subject: [PATCH] mm/hugetlb: Move page order check inside hugetlb_cma_reserve()
Message-ID: <20240209054221.1403364-1-anshuman.khandual@arm.com>

All platforms could benefit from page order check against MAX_PAGE_ORDER
before allocating a CMA area for gigantic hugetlb pages. Let's move this
check from individual platforms to generic hugetlb.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Michael Ellerman <mpe at ellerman.id.au>
Cc: Nicholas Piggin <npiggin at gmail.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linuxppc-dev at lists.ozlabs.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 v6.8-rc3
 
 arch/arm64/mm/hugetlbpage.c   | 7 -------
 arch/powerpc/mm/hugetlbpage.c | 4 +---
 mm/hugetlb.c                  | 7 +++++++
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 8116ac599f80..6720ec8d50e7 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -45,13 +45,6 @@ void __init arm64_hugetlb_cma_reserve(void)
 	else
 		order = CONT_PMD_SHIFT - PAGE_SHIFT;
 
-	/*
-	 * HugeTLB CMA reservation is required for gigantic
-	 * huge pages which could not be allocated via the
-	 * page allocator. Just warn if there is any change
-	 * breaking this assumption.
-	 */
-	WARN_ON(order <= MAX_PAGE_ORDER);
 	hugetlb_cma_reserve(order);
 }
 #endif /* CONFIG_CMA */
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 0a540b37aab6..16557d008eef 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -614,8 +614,6 @@ void __init gigantic_hugetlb_cma_reserve(void)
 		 */
 		order = mmu_psize_to_shift(MMU_PAGE_16G) - PAGE_SHIFT;
 
-	if (order) {
-		VM_WARN_ON(order <= MAX_PAGE_ORDER);
+	if (order)
 		hugetlb_cma_reserve(order);
-	}
 }
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index cf9c9b2906ea..345b3524df35 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -7699,6 +7699,13 @@ void __init hugetlb_cma_reserve(int order)
 	bool node_specific_cma_alloc = false;
 	int nid;
 
+	/*
+	 * HugeTLB CMA reservation is required for gigantic
+	 * huge pages which could not be allocated via the
+	 * page allocator. Just warn if there is any change
+	 * breaking this assumption.
+	 */
+	VM_WARN_ON(order <= MAX_PAGE_ORDER);
 	cma_reserve_called = true;
 
 	if (!hugetlb_cma_size)
-- 
2.25.1



From zajec5 at gmail.com  Thu Feb  8 21:52:03 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri,  9 Feb 2024 06:52:03 +0100
Subject: [PATCH V2] dt-bindings: thermal: mediatek,thermal: document AUXADC 32k clock
Message-ID: <20240209055203.17144-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

SoCs MT7981 and MT7986 include a newer thermal block (V3) that requires
enabling one more clock called AUXADC 32k. Require it in binding.

Cc: Daniel Golle <daniel at makrotopia.org>
Cc: Sam Shih <sam.shih at mediatek.com>
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Disallow "adc_32k" on other chipsets (maxItems: 2)

 .../bindings/thermal/mediatek,thermal.yaml    | 31 +++++++++++++++++--
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/thermal/mediatek,thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,thermal.yaml
index d96a2e32bd8f..e7373d78618c 100644
--- a/Documentation/devicetree/bindings/thermal/mediatek,thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/mediatek,thermal.yaml
@@ -15,9 +15,6 @@ description:
   controls a mux in the apmixedsys register space via AHB bus accesses, so a
   phandle to the APMIXEDSYS is also needed.
 
-allOf:
-  - $ref: thermal-sensor.yaml#
-
 properties:
   compatible:
     enum:
@@ -38,14 +35,18 @@ properties:
     maxItems: 1
 
   clocks:
+    minItems: 2
     items:
       - description: Main clock needed for register access
       - description: The AUXADC clock
+      - description: AUXADC 32k clock
 
   clock-names:
+    minItems: 2
     items:
       - const: therm
       - const: auxadc
+      - const: adc_32k
 
   mediatek,auxadc:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -76,6 +77,30 @@ required:
   - mediatek,auxadc
   - mediatek,apmixedsys
 
+allOf:
+  - $ref: thermal-sensor.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt7981-thermal
+              - mediatek,mt7986-thermal
+    then:
+      properties:
+        clocks:
+          minItems: 3
+
+        clock-names:
+          minItems: 3
+    else:
+      properties:
+        clocks:
+          maxItems: 2
+
+        clock-names:
+          maxItems: 2
+
 unevaluatedProperties: false
 
 examples:
-- 
2.35.3



From j-luthra at ti.com  Thu Feb  8 22:02:24 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Fri, 9 Feb 2024 11:32:24 +0530
Subject: [PATCH v3 6/9] arm64: dts: ti: k3-j721e-main: Add CSI2RX capture
 nodes
In-Reply-To: <20240208123233.391115-7-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
 <20240208123233.391115-7-vaishnav.a@ti.com>
Message-ID: <5ajmkzqje7vdpmzduyjnjdcqoux2fcs3aonfkf5424h3ickzkr@gdvs64lsqtxm>

On Feb 08, 2024 at 18:02:30 +0530, Vaishnav Achath wrote:
> J721E has two CSI2RX capture subsystem featuring Cadence CSI2RX,
> DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
> keep them disabled by default.
> 
> J721E TRM (Section 12.7 Camera Subsystem):
> 	https://www.ti.com/lit/zip/spruil1
> 
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>

Reviewed-By: Jai Luthra <j-luthra at ti.com>

> ---
> 
> V2->V3: Fix order of properties as per dts coding style.
> V1->V2: Update commit message with TRM.
> 
>  arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 122 ++++++++++++++++++++++
>  1 file changed, 122 insertions(+)
> 
> [...]

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240209/0a406acf/attachment-0001.sig>

From j-luthra at ti.com  Thu Feb  8 22:02:50 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Fri, 9 Feb 2024 11:32:50 +0530
Subject: [PATCH v3 7/9] arm64: dts: ti: k3-j721s2-main: Add CSI2RX
 capture nodes
In-Reply-To: <20240208123233.391115-8-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
 <20240208123233.391115-8-vaishnav.a@ti.com>
Message-ID: <2ilg2t6jzooc7rgzvku2zlqbi3mbeyj4uto6foqr5zjcsssxwj@qmniu3y26qpy>

On Feb 08, 2024 at 18:02:31 +0530, Vaishnav Achath wrote:
> J721S2 has two CSI2RX capture subsystem featuring Cadence CSI2RX,
> DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
> keep them disabled by default. J721S2 uses a dedicated BCDMA instance
> for CSI-RX traffic, so enable that as well.
> 
> J721S2 TRM (Section 12.7 Camera Subsystem):
> 	https://www.ti.com/lit/zip/spruj28
> 
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>

Reviewed-By: Jai Luthra <j-luthra at ti.com>

> ---
> 
> V2->V3: Fix order of properties as per dts coding style.
> V1->V2: Update commit message with TRM.
> 
>  arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi | 123 ++++++++++++++++++++-
>  1 file changed, 122 insertions(+), 1 deletion(-)
> 
> [...] 

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240209/e8f0da19/attachment.sig>

From j-luthra at ti.com  Thu Feb  8 22:03:16 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Fri, 9 Feb 2024 11:33:16 +0530
Subject: [PATCH v3 8/9] arm64: dts: ti: k3-j784s4-main: Add CSI2RX
 capture nodes
In-Reply-To: <20240208123233.391115-9-vaishnav.a@ti.com>
References: <20240208123233.391115-1-vaishnav.a@ti.com>
 <20240208123233.391115-9-vaishnav.a@ti.com>
Message-ID: <i3urr5pl67pacpj325cvrjpkdkuwec2qmr2bjbefhinq4pq22g@zhziylox5c3m>

On Feb 08, 2024 at 18:02:32 +0530, Vaishnav Achath wrote:
> J784S4 has three CSI2RX capture subsystem featuring Cadence CSI2RX,
> DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
> keep them disabled by default. J784S4 uses a dedicated BCDMA instance
> for CSI-RX traffic, so enable that as well.
> 
> J784S4 TRM (Section 12.7 Camera Subsystem):
> 	https://www.ti.com/lit/zip/spruj52
> 
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>

Reviewed-By: Jai Luthra <j-luthra at ti.com>

> ---
> 
> V2->V3: Fix order of properties as per dts coding style.
> V1->V2: Update commit message with TRM.
> 
>  arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 183 ++++++++++++++++++++-
>  1 file changed, 182 insertions(+), 1 deletion(-)
> 
> [...] 

-- 
Thanks,
Jai

GPG Fingerprint: 4DE0 D818 E5D5 75E8 D45A AFC5 43DE 91F9 249A 7145
-------------- 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/20240209/cfac300a/attachment.sig>

From Dharma.B at microchip.com  Thu Feb  8 22:31:15 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Fri, 9 Feb 2024 06:31:15 +0000
Subject: [PATCH] dt-bindings: interrupt-controller: Convert Atmel AIC to
 json-schema
In-Reply-To: <20240208-acuteness-visible-b60cd37c2b32@spud>
References: <20240208092015.263210-1-dharma.b@microchip.com>
 <170740748922.3230402.17318224112819715619.robh@kernel.org>
 <20240208-acuteness-visible-b60cd37c2b32@spud>
Message-ID: <8dcae60c-1aba-4e76-99cd-de78c2c4ba6a@microchip.com>

Hi Conor,

On 09/02/24 12:19 am, Conor Dooley wrote:
> Hey Dharma,
> 
> On Thu, Feb 08, 2024 at 03:51:31PM +0000, Rob Herring wrote:
>> On Thu, 08 Feb 2024 14:50:15 +0530, Dharma Balasubiramani wrote:
>>> Convert the Atmel AIC binding document to DT schema format using
>>> json-schema.
>>>
>>> Signed-off-by: Dharma Balasubiramani<dharma.b at microchip.com>
>>> ---
>>> Note: I get the following warnings on latest kernel but not in 6.7.
>>> Should I be worried?
>>> usage: yamllint [-h] [-] [-c CONFIG_FILE | -d CONFIG_DATA] [--list-files] [-f {parsable,standard,colored,github,auto}] [-s] [--no-warnings] [-v] [FILE_OR_DIR [FILE_OR_DIR ...]]
>>> yamllint: error: one of the arguments FILE_OR_DIR - is required
> Hard to say, how were you envoking the command? There were some issues
> recently with dt_binding_check, but I thought those had been fixed.

I use this command to validate

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- dt_binding_check 
DT_SCHEMA_FILES=Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml

and also dtbs_check.

version = yamllint 1.32.0
> 
>> dtschema/dtc warnings/errors:
>> Documentation/devicetree/bindings/interrupt-controller/atmel,aic.example.dtb: /example-1/dma-controller at ffffec00: failed to match any schema with compatible: ['atmel,at91sam9g45-dma']
> But you didn't see this warning?

No I didn't see this warning when applied on tag:6.7. Don't know why.

> I think you can resolve it by just dropping the "user" example from the
> binding entirely. I don't think it adds anything at all.

I intentionally checked the generated example dts file and found that 
both the examples look correct.

     example-0 {
         #address-cells = <1>;
         #size-cells = <1>;

         /* AIC */
         aic: interrupt-controller at fffff000 {
           compatible = "atmel,at91rm9200-aic";
           interrupt-controller;
           #interrupt-cells = <3>;
           reg = <0xfffff000 0x200>;
           atmel,external-irqs = <31>;
         };

     };

     example-1 {
         #address-cells = <1>;
         #size-cells = <1>;

         interrupt-parent = <&fake_intc1>;
         fake_intc1: fake-interrupt-controller {
             interrupt-controller;
             #interrupt-cells = < 3 >;
         };

         /* An interrupt generating device that is wired to an AIC. */
         dma: dma-controller at ffffec00 {
           compatible = "atmel,at91sam9g45-dma";
           #dma-cells = <2>;
           reg = <0xffffec00 0x200>;
           interrupts = <21 4 5>;
         };

     };

> 
> Cheers,
> Conor.

Please correct me if I'm doing something wrong here.

-- 
With Best Regards,
Dharma B.


From jane.chu at oracle.com  Thu Feb  8 22:41:23 2024
From: jane.chu at oracle.com (Jane Chu)
Date: Thu, 8 Feb 2024 22:41:23 -0800
Subject: [PATCH] mm/hugetlb: Move page order check inside
 hugetlb_cma_reserve()
In-Reply-To: <20240209054221.1403364-1-anshuman.khandual@arm.com>
References: <20240209054221.1403364-1-anshuman.khandual@arm.com>
Message-ID: <75803311-29fc-42ab-9c39-0b18cf875347@oracle.com>

On 2/8/2024 9:42 PM, Anshuman Khandual wrote:

> All platforms could benefit from page order check against MAX_PAGE_ORDER
> before allocating a CMA area for gigantic hugetlb pages. Let's move this
> check from individual platforms to generic hugetlb.
>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Michael Ellerman <mpe at ellerman.id.au>
> Cc: Nicholas Piggin <npiggin at gmail.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linuxppc-dev at lists.ozlabs.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 v6.8-rc3
>   
>   arch/arm64/mm/hugetlbpage.c   | 7 -------
>   arch/powerpc/mm/hugetlbpage.c | 4 +---
>   mm/hugetlb.c                  | 7 +++++++
>   3 files changed, 8 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 8116ac599f80..6720ec8d50e7 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -45,13 +45,6 @@ void __init arm64_hugetlb_cma_reserve(void)
>   	else
>   		order = CONT_PMD_SHIFT - PAGE_SHIFT;
>   
> -	/*
> -	 * HugeTLB CMA reservation is required for gigantic
> -	 * huge pages which could not be allocated via the
> -	 * page allocator. Just warn if there is any change
> -	 * breaking this assumption.
> -	 */
> -	WARN_ON(order <= MAX_PAGE_ORDER);
>   	hugetlb_cma_reserve(order);
>   }
>   #endif /* CONFIG_CMA */
> diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
> index 0a540b37aab6..16557d008eef 100644
> --- a/arch/powerpc/mm/hugetlbpage.c
> +++ b/arch/powerpc/mm/hugetlbpage.c
> @@ -614,8 +614,6 @@ void __init gigantic_hugetlb_cma_reserve(void)
>   		 */
>   		order = mmu_psize_to_shift(MMU_PAGE_16G) - PAGE_SHIFT;
>   
> -	if (order) {
> -		VM_WARN_ON(order <= MAX_PAGE_ORDER);
> +	if (order)
>   		hugetlb_cma_reserve(order);
> -	}
>   }
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index cf9c9b2906ea..345b3524df35 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -7699,6 +7699,13 @@ void __init hugetlb_cma_reserve(int order)
>   	bool node_specific_cma_alloc = false;
>   	int nid;
>   
> +	/*
> +	 * HugeTLB CMA reservation is required for gigantic
> +	 * huge pages which could not be allocated via the
> +	 * page allocator. Just warn if there is any change
> +	 * breaking this assumption.
> +	 */
> +	VM_WARN_ON(order <= MAX_PAGE_ORDER);
>   	cma_reserve_called = true;
>   
>   	if (!hugetlb_cma_size)

Looks straight forward to me.

Reviewed-by: Jane Chu <jane.chu at oracle.com>




From dharma.b at microchip.com  Thu Feb  8 22:47:55 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 9 Feb 2024 12:17:55 +0530
Subject: [PATCH v2] dt-bindings: input: atmel,captouch: convert bindings to YAML
Message-ID: <20240209064755.47516-1-dharma.b@microchip.com>

Convert the Atmel capacitive touchscreen bindings to YAML format.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
Changelog
v1 -> v2
- Drop autorepeat property.
- Use unevaluatedProperties instead of additionalProperties.
- Use node name "touch at 51" instead of "atmel-captouch at 51".
---
 .../bindings/input/atmel,captouch.txt         | 36 -----------
 .../bindings/input/atmel,captouch.yaml        | 59 +++++++++++++++++++
 2 files changed, 59 insertions(+), 36 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/input/atmel,captouch.txt
 create mode 100644 Documentation/devicetree/bindings/input/atmel,captouch.yaml

diff --git a/Documentation/devicetree/bindings/input/atmel,captouch.txt b/Documentation/devicetree/bindings/input/atmel,captouch.txt
deleted file mode 100644
index fe9ee5c53bcc..000000000000
--- a/Documentation/devicetree/bindings/input/atmel,captouch.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-Device tree bindings for Atmel capacitive touch device, typically
-an Atmel touch sensor connected to AtmegaXX MCU running firmware
-based on Qtouch library.
-
-The node for this device must be a child of a I2C controller node, as the
-device communicates via I2C.
-
-Required properties:
-
-	compatible:	Must be "atmel,captouch".
-	reg:		The I2C slave address of the device.
-	interrupts:	Property describing the interrupt line the device
-			is connected to. The device only has one interrupt
-			source.
-	linux,keycodes:	Specifies an array of numeric keycode values to
-			be used for reporting button presses. The array can
-			contain up to 8 entries.
-
-Optional properties:
-
-	autorepeat:	Enables the Linux input system's autorepeat
-			feature on the input device.
-
-Example:
-
-	atmel-captouch at 51 {
-		compatible = "atmel,captouch";
-		reg = <0x51>;
-		interrupt-parent = <&tlmm>;
-		interrupts = <67 IRQ_TYPE_EDGE_FALLING>;
-		linux,keycodes = <BTN_0>, <BTN_1>,
-			<BTN_2>, <BTN_3>,
-			<BTN_4>, <BTN_5>,
-			<BTN_6>, <BTN_7>;
-		autorepeat;
-	};
diff --git a/Documentation/devicetree/bindings/input/atmel,captouch.yaml b/Documentation/devicetree/bindings/input/atmel,captouch.yaml
new file mode 100644
index 000000000000..f7477091d5a6
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/atmel,captouch.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/atmel,captouch.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel capacitive touch device
+
+maintainers:
+  - Dharma balasubiramani <dharma.b at microchip.com>
+
+description:
+  Atmel capacitive touch device, typically an Atmel touch sensor connected to
+  AtmegaXX MCU running firmware based on Qtouch library.
+
+allOf:
+  - $ref: input.yaml#
+
+properties:
+  compatible:
+    const: atmel,captouch
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  linux,keycodes:
+    minItems: 1
+    maxItems: 8
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - linux,keycodes
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/input/linux-event-codes.h>
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      touch at 51 {
+        compatible = "atmel,captouch";
+        reg = <0x51>;
+        interrupt-parent = <&tlmm>;
+        interrupts = <67 IRQ_TYPE_EDGE_FALLING>;
+        linux,keycodes = <BTN_0>, <BTN_1>,
+                         <BTN_2>, <BTN_3>,
+                         <BTN_4>, <BTN_5>,
+                         <BTN_6>, <BTN_7>;
+        autorepeat;
+      };
+    };

base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
-- 
2.25.1



From jan.kiszka at siemens.com  Thu Feb  8 23:23:15 2024
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Fri,  9 Feb 2024 08:23:15 +0100
Subject: [PATCH v3 1/7] dt-bindings: arm: ti: Add binding for Siemens IOT2050 SM variant
In-Reply-To: <cover.1707463401.git.jan.kiszka@siemens.com>
References: <cover.1707463401.git.jan.kiszka@siemens.com>
Message-ID: <595d8d79647a0f5e6e635a22ee0fee011f8a5c5e.1707463401.git.jan.kiszka@siemens.com>

From: Su Bao Cheng <baocheng.su at siemens.com>

This new variant is derived from the Advanced PG2 board, removing the
Arduino interface, and adding a new ASIC for communicating with the
PLC 1200 signal modules.

Signed-off-by: Su Bao Cheng <baocheng.su at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/ti/k3.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
index c6506bccfe88..1723e1fa7fee 100644
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -93,6 +93,7 @@ properties:
               - siemens,iot2050-advanced
               - siemens,iot2050-advanced-m2
               - siemens,iot2050-advanced-pg2
+              - siemens,iot2050-advanced-sm
               - siemens,iot2050-basic
               - siemens,iot2050-basic-pg2
               - ti,am654-evm
-- 
2.35.3



From jan.kiszka at siemens.com  Thu Feb  8 23:23:16 2024
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Fri,  9 Feb 2024 08:23:16 +0100
Subject: [PATCH v3 2/7] arm64: dts: ti: iot2050: Disable R5 lockstep for all PG2 boards
In-Reply-To: <cover.1707463401.git.jan.kiszka@siemens.com>
References: <cover.1707463401.git.jan.kiszka@siemens.com>
Message-ID: <f692d0211915aefd4de7c9ecff5234683c9c7d59.1707463401.git.jan.kiszka@siemens.com>

From: Baocheng Su <baocheng.su at siemens.com>

The R5 lockstep disabling should be common for all PG2 boards, move it
from variants dts to common-pg2.dtsi.

As now the Basic PG2 consumes this twice, move Basic disabling to the
PG1 variant.

Signed-off-by: Baocheng Su <baocheng.su at siemens.com>
[Jan: avoid duplication of disabling for Basic PG2]
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
---
 arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi     | 7 ++++++-
 arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi | 5 -----
 arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts         | 5 +++++
 arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts   | 5 -----
 arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts  | 7 +------
 5 files changed, 12 insertions(+), 17 deletions(-)

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 e9b57b87e42e..42adb8815f38 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
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) Siemens AG, 2021
+ * Copyright (c) Siemens AG, 2021-2023
  *
  * Authors:
  *   Chao Zeng <chao.zeng at siemens.com>
@@ -9,6 +9,11 @@
  * Common bits of the IOT2050 Basic and Advanced variants, PG2
  */
 
+&mcu_r5fss0 {
+	/* lock-step mode not supported on PG2 boards */
+	ti,cluster-mode = <0>;
+};
+
 &main_pmx0 {
 	cp2102n_reset_pin_default: cp2102n-reset-default-pins {
 		pinctrl-single,pins = <
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 1d6cddb11991..3bb6bcb0a5d3 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
@@ -40,8 +40,3 @@ &main_uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_uart0_pins_default>;
 };
-
-&mcu_r5fss0 {
-	/* lock-step mode not supported on Basic boards */
-	ti,cluster-mode = <0>;
-};
diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts
index 87928ff28214..be9c8db4c43a 100644
--- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts
@@ -22,3 +22,8 @@ / {
 	compatible = "siemens,iot2050-basic", "ti,am654";
 	model = "SIMATIC IOT2050 Basic";
 };
+
+&mcu_r5fss0 {
+	/* lock-step mode not supported on this board */
+	ti,cluster-mode = <0>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
index bd6f2e696e94..1e5d4d98b69b 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
@@ -21,11 +21,6 @@ / {
 	model = "SIMATIC IOT2050 Advanced M2";
 };
 
-&mcu_r5fss0 {
-	/* lock-step mode not supported on this board */
-	ti,cluster-mode = <0>;
-};
-
 &main_pmx0 {
 	main_bkey_pcie_reset: main-bkey-pcie-reset-default-pins {
 		pinctrl-single,pins = <
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
index f00dc86d01b9..a8ce8c891894 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) Siemens AG, 2018-2021
+ * Copyright (c) Siemens AG, 2018-2023
  *
  * Authors:
  *   Le Jin <le.jin at siemens.com>
@@ -22,8 +22,3 @@ / {
 	compatible = "siemens,iot2050-advanced-pg2", "ti,am654";
 	model = "SIMATIC IOT2050 Advanced PG2";
 };
-
-&mcu_r5fss0 {
-	/* lock-step mode not supported on this board */
-	ti,cluster-mode = <0>;
-};
-- 
2.35.3



From jan.kiszka at siemens.com  Thu Feb  8 23:23:20 2024
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Fri,  9 Feb 2024 08:23:20 +0100
Subject: [PATCH v3 6/7] arm64: dts: ti: iot2050: Annotate LED nodes
In-Reply-To: <cover.1707463401.git.jan.kiszka@siemens.com>
References: <cover.1707463401.git.jan.kiszka@siemens.com>
Message-ID: <331f8756483e3f896a3e50e069b3e2c0fae7a8ac.1707463401.git.jan.kiszka@siemens.com>

From: Jan Kiszka <jan.kiszka at siemens.com>

Add function and color properties and use the common scheme for the node
name. We can't change the user-visible labels, though, due to existing
userspace relying on the current format.

Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
---
 .../boot/dts/ti/k3-am65-iot2050-common.dtsi   | 33 +++++++++++++++----
 1 file changed, 26 insertions(+), 7 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 bffc9e251289..caaf6862ae1d 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) Siemens AG, 2018-2021
+ * Copyright (c) Siemens AG, 2018-2024
  *
  * Authors:
  *   Le Jin <le.jin at siemens.com>
@@ -9,6 +9,7 @@
  * Common bits of the IOT2050 Basic and Advanced variants, PG1 and PG2
  */
 
+#include <dt-bindings/leds/common.h>
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/net/ti-dp83867.h>
 
@@ -88,28 +89,46 @@ leds {
 		pinctrl-names = "default";
 		pinctrl-0 = <&leds_pins_default>;
 
-		status-led-red {
+		led-0 {
+			color = <LED_COLOR_ID_RED>;
+			function = LED_FUNCTION_STATUS;
+			label = "status-led-red";
 			gpios = <&wkup_gpio0 32 GPIO_ACTIVE_HIGH>;
 			panic-indicator;
 		};
 
-		status-led-green {
+		led-1 {
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_STATUS;
+			label = "status-led-green";
 			gpios = <&wkup_gpio0 24 GPIO_ACTIVE_HIGH>;
 		};
 
-		user-led1-red {
+		led-2 {
+			color = <LED_COLOR_ID_RED>;
+			function = LED_FUNCTION_INDICATOR;
+			label = "user-led1-red";
 			gpios = <&pcal9535_3 14 GPIO_ACTIVE_HIGH>;
 		};
 
-		user-led1-green {
+		led-3 {
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_INDICATOR;
+			label = "user-led1-green";
 			gpios = <&pcal9535_2 15 GPIO_ACTIVE_HIGH>;
 		};
 
-		user-led2-red {
+		led-4 {
+			color = <LED_COLOR_ID_RED>;
+			function = LED_FUNCTION_INDICATOR;
+			label = "user-led2-red";
 			gpios = <&wkup_gpio0 17 GPIO_ACTIVE_HIGH>;
 		};
 
-		user-led2-green {
+		led-5 {
+			color = <LED_COLOR_ID_RED>;
+			function = LED_FUNCTION_INDICATOR;
+			label = "user-led2-green";
 			gpios = <&wkup_gpio0 22 GPIO_ACTIVE_HIGH>;
 		};
 	};
-- 
2.35.3



From jan.kiszka at siemens.com  Thu Feb  8 23:23:19 2024
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Fri,  9 Feb 2024 08:23:19 +0100
Subject: [PATCH v3 5/7] arm64: dts: ti: iot2050: Factor out DP related bits
In-Reply-To: <cover.1707463401.git.jan.kiszka@siemens.com>
References: <cover.1707463401.git.jan.kiszka@siemens.com>
Message-ID: <3397d917d7c97f7aec05bc5f65eef3a6fe843650.1707463401.git.jan.kiszka@siemens.com>

From: Jan Kiszka <jan.kiszka at siemens.com>

There is a variant coming which does not support the Display Port. Move
all related bits into a separate dtsi so that only those variants
supporting the interface can include it.

Along that, remove a redundant clock setting from
k3-am65-iot2050-common-pg1.dtsi.

Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
---
 .../dts/ti/k3-am65-iot2050-common-pg1.dtsi    |  5 +-
 .../boot/dts/ti/k3-am65-iot2050-common.dtsi   | 85 ----------------
 .../arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi | 98 +++++++++++++++++++
 .../dts/ti/k3-am6528-iot2050-basic-pg2.dts    |  1 +
 .../dts/ti/k3-am6548-iot2050-advanced-m2.dts  |  1 +
 .../dts/ti/k3-am6548-iot2050-advanced-pg2.dts |  1 +
 6 files changed, 102 insertions(+), 89 deletions(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi

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 1d1979859583..3f09d49d7dff 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
@@ -8,10 +8,7 @@
  * Common bits of the IOT2050 Basic and Advanced variants, PG1
  */
 
-&dss {
-	assigned-clocks = <&k3_clks 67 2>;
-	assigned-clock-parents = <&k3_clks 67 5>;
-};
+#include "k3-am65-iot2050-dp.dtsi"
 
 &serdes0 {
 	status = "disabled";
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 3ba81866599e..bffc9e251289 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
@@ -318,45 +318,6 @@ AM65X_IOPAD(0x02c0, PIN_OUTPUT, 0)  /* (AC8) USB1_DRVVBUS */
 		>;
 	};
 
-	dss_vout1_pins_default: dss-vout1-default-pins {
-		pinctrl-single,pins = <
-			AM65X_IOPAD(0x0000, PIN_OUTPUT, 1)  /* VOUT1_DATA0 */
-			AM65X_IOPAD(0x0004, PIN_OUTPUT, 1)  /* VOUT1_DATA1 */
-			AM65X_IOPAD(0x0008, PIN_OUTPUT, 1)  /* VOUT1_DATA2 */
-			AM65X_IOPAD(0x000c, PIN_OUTPUT, 1)  /* VOUT1_DATA3 */
-			AM65X_IOPAD(0x0010, PIN_OUTPUT, 1)  /* VOUT1_DATA4 */
-			AM65X_IOPAD(0x0014, PIN_OUTPUT, 1)  /* VOUT1_DATA5 */
-			AM65X_IOPAD(0x0018, PIN_OUTPUT, 1)  /* VOUT1_DATA6 */
-			AM65X_IOPAD(0x001c, PIN_OUTPUT, 1)  /* VOUT1_DATA7 */
-			AM65X_IOPAD(0x0020, PIN_OUTPUT, 1)  /* VOUT1_DATA8 */
-			AM65X_IOPAD(0x0024, PIN_OUTPUT, 1)  /* VOUT1_DATA9 */
-			AM65X_IOPAD(0x0028, PIN_OUTPUT, 1)  /* VOUT1_DATA10 */
-			AM65X_IOPAD(0x002c, PIN_OUTPUT, 1)  /* VOUT1_DATA11 */
-			AM65X_IOPAD(0x0030, PIN_OUTPUT, 1)  /* VOUT1_DATA12 */
-			AM65X_IOPAD(0x0034, PIN_OUTPUT, 1)  /* VOUT1_DATA13 */
-			AM65X_IOPAD(0x0038, PIN_OUTPUT, 1)  /* VOUT1_DATA14 */
-			AM65X_IOPAD(0x003c, PIN_OUTPUT, 1)  /* VOUT1_DATA15 */
-			AM65X_IOPAD(0x0040, PIN_OUTPUT, 1)  /* VOUT1_DATA16 */
-			AM65X_IOPAD(0x0044, PIN_OUTPUT, 1)  /* VOUT1_DATA17 */
-			AM65X_IOPAD(0x0048, PIN_OUTPUT, 1)  /* VOUT1_DATA18 */
-			AM65X_IOPAD(0x004c, PIN_OUTPUT, 1)  /* VOUT1_DATA19 */
-			AM65X_IOPAD(0x0050, PIN_OUTPUT, 1)  /* VOUT1_DATA20 */
-			AM65X_IOPAD(0x0054, PIN_OUTPUT, 1)  /* VOUT1_DATA21 */
-			AM65X_IOPAD(0x0058, PIN_OUTPUT, 1)  /* VOUT1_DATA22 */
-			AM65X_IOPAD(0x005c, PIN_OUTPUT, 1)  /* VOUT1_DATA23 */
-			AM65X_IOPAD(0x0060, PIN_OUTPUT, 1)  /* VOUT1_VSYNC */
-			AM65X_IOPAD(0x0064, PIN_OUTPUT, 1)  /* VOUT1_HSYNC */
-			AM65X_IOPAD(0x0068, PIN_OUTPUT, 1)  /* VOUT1_PCLK */
-			AM65X_IOPAD(0x006c, PIN_OUTPUT, 1)  /* VOUT1_DE */
-		>;
-	};
-
-	dp_pins_default: dp-default-pins {
-		pinctrl-single,pins = <
-			AM65X_IOPAD(0x0078, PIN_OUTPUT, 7)  /* (AF18) DP rst_n */
-		>;
-	};
-
 	main_i2c2_pins_default: main-i2c2-default-pins {
 		pinctrl-single,pins = <
 			AM65X_IOPAD(0x0074, PIN_INPUT,  5)  /* (T27) I2C2_SCL */
@@ -493,32 +454,6 @@ &main_i2c3 {
 
 	#address-cells = <1>;
 	#size-cells = <0>;
-
-	edp-bridge at f {
-		compatible = "toshiba,tc358767";
-		reg = <0x0f>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&dp_pins_default>;
-		reset-gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
-
-		clock-names = "ref";
-		clocks = <&dp_refclk>;
-
-		toshiba,hpd-pin = <0>;
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 1 {
-				reg = <1>;
-
-				bridge_in: endpoint {
-					remote-endpoint = <&dpi_out>;
-				};
-			};
-		};
-	};
 };
 
 &mcu_cpsw {
@@ -617,26 +552,6 @@ seboot-backup at e80000 {
 	};
 };
 
-&dss {
-	pinctrl-names = "default";
-	pinctrl-0 = <&dss_vout1_pins_default>;
-
-	assigned-clocks = <&k3_clks 67 2>;
-	assigned-clock-parents = <&k3_clks 67 5>;
-};
-
-&dss_ports {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	port at 1 {
-		reg = <1>;
-
-		dpi_out: endpoint {
-			remote-endpoint = <&bridge_in>;
-		};
-	};
-};
-
 &pcie1_rc {
 	status = "okay";
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi
new file mode 100644
index 000000000000..07a0ea872f5b
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) Siemens AG, 2024
+ *
+ * Authors:
+ *   Jan Kiszka <jan.kiszka at siemens.com>
+ *
+ * Common bits for IOT2050 variants with Display Port
+ */
+
+&main_pmx0 {
+	dss_vout1_pins_default: dss-vout1-default-pins {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x0000, PIN_OUTPUT, 1)  /* VOUT1_DATA0 */
+			AM65X_IOPAD(0x0004, PIN_OUTPUT, 1)  /* VOUT1_DATA1 */
+			AM65X_IOPAD(0x0008, PIN_OUTPUT, 1)  /* VOUT1_DATA2 */
+			AM65X_IOPAD(0x000c, PIN_OUTPUT, 1)  /* VOUT1_DATA3 */
+			AM65X_IOPAD(0x0010, PIN_OUTPUT, 1)  /* VOUT1_DATA4 */
+			AM65X_IOPAD(0x0014, PIN_OUTPUT, 1)  /* VOUT1_DATA5 */
+			AM65X_IOPAD(0x0018, PIN_OUTPUT, 1)  /* VOUT1_DATA6 */
+			AM65X_IOPAD(0x001c, PIN_OUTPUT, 1)  /* VOUT1_DATA7 */
+			AM65X_IOPAD(0x0020, PIN_OUTPUT, 1)  /* VOUT1_DATA8 */
+			AM65X_IOPAD(0x0024, PIN_OUTPUT, 1)  /* VOUT1_DATA9 */
+			AM65X_IOPAD(0x0028, PIN_OUTPUT, 1)  /* VOUT1_DATA10 */
+			AM65X_IOPAD(0x002c, PIN_OUTPUT, 1)  /* VOUT1_DATA11 */
+			AM65X_IOPAD(0x0030, PIN_OUTPUT, 1)  /* VOUT1_DATA12 */
+			AM65X_IOPAD(0x0034, PIN_OUTPUT, 1)  /* VOUT1_DATA13 */
+			AM65X_IOPAD(0x0038, PIN_OUTPUT, 1)  /* VOUT1_DATA14 */
+			AM65X_IOPAD(0x003c, PIN_OUTPUT, 1)  /* VOUT1_DATA15 */
+			AM65X_IOPAD(0x0040, PIN_OUTPUT, 1)  /* VOUT1_DATA16 */
+			AM65X_IOPAD(0x0044, PIN_OUTPUT, 1)  /* VOUT1_DATA17 */
+			AM65X_IOPAD(0x0048, PIN_OUTPUT, 1)  /* VOUT1_DATA18 */
+			AM65X_IOPAD(0x004c, PIN_OUTPUT, 1)  /* VOUT1_DATA19 */
+			AM65X_IOPAD(0x0050, PIN_OUTPUT, 1)  /* VOUT1_DATA20 */
+			AM65X_IOPAD(0x0054, PIN_OUTPUT, 1)  /* VOUT1_DATA21 */
+			AM65X_IOPAD(0x0058, PIN_OUTPUT, 1)  /* VOUT1_DATA22 */
+			AM65X_IOPAD(0x005c, PIN_OUTPUT, 1)  /* VOUT1_DATA23 */
+			AM65X_IOPAD(0x0060, PIN_OUTPUT, 1)  /* VOUT1_VSYNC */
+			AM65X_IOPAD(0x0064, PIN_OUTPUT, 1)  /* VOUT1_HSYNC */
+			AM65X_IOPAD(0x0068, PIN_OUTPUT, 1)  /* VOUT1_PCLK */
+			AM65X_IOPAD(0x006c, PIN_OUTPUT, 1)  /* VOUT1_DE */
+		>;
+	};
+
+	dp_pins_default: dp-default-pins {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x0078, PIN_OUTPUT, 7)  /* (AF18) DP rst_n */
+		>;
+	};
+};
+
+&main_i2c3 {
+	edp-bridge at f {
+		compatible = "toshiba,tc358767";
+		reg = <0x0f>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&dp_pins_default>;
+		reset-gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
+
+		clock-names = "ref";
+		clocks = <&dp_refclk>;
+
+		toshiba,hpd-pin = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 1 {
+				reg = <1>;
+
+				bridge_in: endpoint {
+					remote-endpoint = <&dpi_out>;
+				};
+			};
+		};
+	};
+};
+
+&dss {
+	pinctrl-names = "default";
+	pinctrl-0 = <&dss_vout1_pins_default>;
+
+	assigned-clocks = <&k3_clks 67 2>;
+	assigned-clock-parents = <&k3_clks 67 5>;
+};
+
+&dss_ports {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	port at 1 {
+		reg = <1>;
+
+		dpi_out: endpoint {
+			remote-endpoint = <&bridge_in>;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts
index 8be3370d3de1..cba0c3d46263 100644
--- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts
@@ -17,6 +17,7 @@
 
 #include "k3-am6528-iot2050-basic-common.dtsi"
 #include "k3-am65-iot2050-common-pg2.dtsi"
+#include "k3-am65-iot2050-dp.dtsi"
 #include "k3-am65-iot2050-usb3.dtsi"
 
 / {
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
index 38623501a14f..484a31a64cff 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
@@ -16,6 +16,7 @@
 #include "k3-am6548-iot2050-advanced-common.dtsi"
 #include "k3-am65-iot2050-common-pg2.dtsi"
 #include "k3-am65-iot2050-arduino-connector.dtsi"
+#include "k3-am65-iot2050-dp.dtsi"
 
 / {
 	compatible = "siemens,iot2050-advanced-m2", "ti,am654";
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
index b6e878a31c27..9e1ebfea3f8f 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
@@ -18,6 +18,7 @@
 #include "k3-am6548-iot2050-advanced-common.dtsi"
 #include "k3-am65-iot2050-common-pg2.dtsi"
 #include "k3-am65-iot2050-arduino-connector.dtsi"
+#include "k3-am65-iot2050-dp.dtsi"
 #include "k3-am65-iot2050-usb3.dtsi"
 
 / {
-- 
2.35.3



From jan.kiszka at siemens.com  Thu Feb  8 23:23:14 2024
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Fri,  9 Feb 2024 08:23:14 +0100
Subject: [PATCH v3 0/7] arm64: dts: iot2050: Add support for new SM variant
Message-ID: <cover.1707463401.git.jan.kiszka@siemens.com>

Changes in v3:
 - rebased

Changes in v2:
 - LED improvements
 - factor out DP and USB3 dtsi files
 - fix subject of last patch

This bring support for yet another IOT2050 device variant, see last
patch for details. The rest is binding and refactoring to make that
happen. Plus, LED nodes are improved by adding function and color
properties.

Jan

Baocheng Su (2):
  arm64: dts: ti: iot2050: Disable R5 lockstep for all PG2 boards
  arm64: dts: ti: iot2050: Support IOT2050-SM variant

Jan Kiszka (4):
  arm64: dts: ti: iot2050: Factor out arduino connector bits
  arm64: dts: ti: iot2050: Factor out enabling of USB3 support
  arm64: dts: ti: iot2050: Factor out DP related bits
  arm64: dts: ti: iot2050: Annotate LED nodes

Su Bao Cheng (1):
  dt-bindings: arm: ti: Add binding for Siemens IOT2050 SM variant

 .../devicetree/bindings/arm/ti/k3.yaml        |   1 +
 arch/arm64/boot/dts/ti/Makefile               |   1 +
 .../ti/k3-am65-iot2050-arduino-connector.dtsi | 768 +++++++++++++++
 .../dts/ti/k3-am65-iot2050-common-pg1.dtsi    |   5 +-
 .../dts/ti/k3-am65-iot2050-common-pg2.dtsi    |  25 +-
 .../boot/dts/ti/k3-am65-iot2050-common.dtsi   | 871 +-----------------
 .../arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi |  98 ++
 .../boot/dts/ti/k3-am65-iot2050-usb3.dtsi     |  27 +
 .../ti/k3-am6528-iot2050-basic-common.dtsi    |   6 +-
 .../dts/ti/k3-am6528-iot2050-basic-pg2.dts    |   2 +
 .../boot/dts/ti/k3-am6528-iot2050-basic.dts   |   5 +
 .../dts/ti/k3-am6548-iot2050-advanced-m2.dts  |  20 +-
 .../dts/ti/k3-am6548-iot2050-advanced-pg2.dts |  10 +-
 .../dts/ti/k3-am6548-iot2050-advanced-sm.dts  | 189 ++++
 .../dts/ti/k3-am6548-iot2050-advanced.dts     |   1 +
 15 files changed, 1132 insertions(+), 897 deletions(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
 create mode 100644 arch/arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi
 create mode 100644 arch/arm64/boot/dts/ti/k3-am65-iot2050-usb3.dtsi
 create mode 100644 arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-sm.dts

-- 
2.35.3



From jan.kiszka at siemens.com  Thu Feb  8 23:23:18 2024
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Fri,  9 Feb 2024 08:23:18 +0100
Subject: [PATCH v3 4/7] arm64: dts: ti: iot2050: Factor out enabling of USB3 support
In-Reply-To: <cover.1707463401.git.jan.kiszka@siemens.com>
References: <cover.1707463401.git.jan.kiszka@siemens.com>
Message-ID: <51d9be5ddbf74f90bc915ab5473b9ea9a4b0cdf7.1707463401.git.jan.kiszka@siemens.com>

From: Jan Kiszka <jan.kiszka at siemens.com>

Already simplifies the existing code by avoid the switch back in the m2
variant to what k3-am65-main.dtsi provided as base.

Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
---
 .../dts/ti/k3-am65-iot2050-common-pg2.dtsi    | 18 -------------
 .../boot/dts/ti/k3-am65-iot2050-usb3.dtsi     | 27 +++++++++++++++++++
 .../dts/ti/k3-am6528-iot2050-basic-pg2.dts    |  1 +
 .../dts/ti/k3-am6548-iot2050-advanced-m2.dts  | 13 ---------
 .../dts/ti/k3-am6548-iot2050-advanced-pg2.dts |  1 +
 5 files changed, 29 insertions(+), 31 deletions(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am65-iot2050-usb3.dtsi

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 42adb8815f38..93d966b67d8d 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
@@ -38,21 +38,3 @@ &dss {
 	/* Workaround needed to get DP clock of 154Mhz */
 	assigned-clocks = <&k3_clks 67 0>;
 };
-
-&serdes0 {
-	assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
-	assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
-};
-
-&dwc3_0 {
-	assigned-clock-parents = <&k3_clks 151 4>,  /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
-				 <&k3_clks 151 8>;  /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */
-	phys = <&serdes0 PHY_TYPE_USB3 0>;
-	phy-names = "usb3-phy";
-};
-
-&usb0 {
-	maximum-speed = "super-speed";
-	snps,dis-u1-entry-quirk;
-	snps,dis-u2-entry-quirk;
-};
diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-usb3.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-usb3.dtsi
new file mode 100644
index 000000000000..3f5fe4c38ebc
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-usb3.dtsi
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) Siemens AG, 2024
+ *
+ * Authors:
+ *   Jan Kiszka <jan.kiszka at siemens.com>
+ *
+ * Common bits for IOT2050 variants with USB3 support
+ */
+
+&serdes0 {
+	assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
+	assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
+};
+
+&dwc3_0 {
+	assigned-clock-parents = <&k3_clks 151 4>,  /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
+				 <&k3_clks 151 8>;  /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */
+	phys = <&serdes0 PHY_TYPE_USB3 0>;
+	phy-names = "usb3-phy";
+};
+
+&usb0 {
+	maximum-speed = "super-speed";
+	snps,dis-u1-entry-quirk;
+	snps,dis-u2-entry-quirk;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts
index c62549a4b436..8be3370d3de1 100644
--- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts
@@ -17,6 +17,7 @@
 
 #include "k3-am6528-iot2050-basic-common.dtsi"
 #include "k3-am65-iot2050-common-pg2.dtsi"
+#include "k3-am65-iot2050-usb3.dtsi"
 
 / {
 	compatible = "siemens,iot2050-basic-pg2", "ti,am654";
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
index 2401cbe2b66c..38623501a14f 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
@@ -92,16 +92,3 @@ &pcie0_rc {
 &pcie1_rc {
 	status = "disabled";
 };
-
-&dwc3_0 {
-	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) */
-	/delete-property/ phys;
-	/delete-property/ phy-names;
-};
-
-&usb0 {
-	maximum-speed = "high-speed";
-	/delete-property/ snps,dis-u1-entry-quirk;
-	/delete-property/ snps,dis-u2-entry-quirk;
-};
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
index c1205feef54e..b6e878a31c27 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
@@ -18,6 +18,7 @@
 #include "k3-am6548-iot2050-advanced-common.dtsi"
 #include "k3-am65-iot2050-common-pg2.dtsi"
 #include "k3-am65-iot2050-arduino-connector.dtsi"
+#include "k3-am65-iot2050-usb3.dtsi"
 
 / {
 	compatible = "siemens,iot2050-advanced-pg2", "ti,am654";
-- 
2.35.3



From jan.kiszka at siemens.com  Thu Feb  8 23:23:21 2024
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Fri,  9 Feb 2024 08:23:21 +0100
Subject: [PATCH v3 7/7] arm64: dts: ti: iot2050: Support IOT2050-SM variant
In-Reply-To: <cover.1707463401.git.jan.kiszka@siemens.com>
References: <cover.1707463401.git.jan.kiszka@siemens.com>
Message-ID: <d24e920547986499f6e8e39c833e414679b12ab4.1707463401.git.jan.kiszka@siemens.com>

From: Baocheng Su <baocheng.su at siemens.com>

Main differences between the new variant and Advanced PG2:

1. Arduino interface is removed. Instead, an new ASIC is added for
   communicating with PLC 1200 signal modules.
2. USB 3.0 type A connector is removed, only USB 2.0 type A connector is
   available.
3. DP interface is removed. Instead, to communicate with PLC 1200 signal
   modules, a USB 3.0 type B connector is added but the signals are
   actually not USB.
4. DDR size is increased to 4 GB.
5. Two sensors are added, one tilt sensor and one light sensor.

The light sensor it not yet added to the DT at this stage as it depends
on to-be-added bindings.

Co-developed-by: Chao Zeng <chao.zeng at siemens.com>
Signed-off-by: Chao Zeng <chao.zeng at siemens.com>
Co-developed-by: Li Hua Qian <huaqian.li at siemens.com>
Signed-off-by: Li Hua Qian <huaqian.li at siemens.com>
Signed-off-by: Baocheng Su <baocheng.su at siemens.com>
[Jan: rebase over dtsi refactorings, split-out light sensor, improve LEDs]
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
---
 arch/arm64/boot/dts/ti/Makefile               |   1 +
 .../dts/ti/k3-am6548-iot2050-advanced-sm.dts  | 189 ++++++++++++++++++
 2 files changed, 190 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-sm.dts

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..cd7f3a429778 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -53,6 +53,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic-pg2.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-m2.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-pg2.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-sm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-gp-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-evm.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-sm.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-sm.dts
new file mode 100644
index 000000000000..338834fda566
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-sm.dts
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) Siemens AG, 2023
+ *
+ * Authors:
+ *   Baocheng Su <baocheng.su at siemens.com>
+ *   Chao Zeng <chao.zeng at siemens.com>
+ *   Huaqian Li <huaqian.li at siemens.com>
+ *
+ * AM6548-based (quad-core) IOT2050 SM variant, Product Generation 2
+ * 4 GB RAM, 16 GB eMMC, USB-serial converter on connector X30
+ *
+ * Product homepage:
+ * https://new.siemens.com/global/en/products/automation/pc-based/iot-gateways/simatic-iot2050.html
+ */
+
+/dts-v1/;
+
+#include "k3-am6548-iot2050-advanced-common.dtsi"
+#include "k3-am65-iot2050-common-pg2.dtsi"
+
+/ {
+	compatible = "siemens,iot2050-advanced-sm", "ti,am654";
+	model = "SIMATIC IOT2050 Advanced SM";
+
+	memory at 80000000 {
+		device_type = "memory";
+		/* 4G RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+		      <0x00000008 0x80000000 0x00000000 0x80000000>;
+	};
+
+	aliases {
+		spi1 = &main_spi0;
+	};
+
+	leds {
+		pinctrl-0 = <&leds_pins_default>, <&user1_led_pins>;
+
+		led-2 {
+			gpios = <&wkup_gpio0 52 GPIO_ACTIVE_HIGH>;
+		};
+
+		led-3 {
+			gpios = <&wkup_gpio0 53 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&main_pmx0 {
+	main_pcie_enable_pins_default: main-pcie-enable-default-pins {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x01d8, PIN_OUTPUT, 7)  /* (AH12) GPIO1_22 */
+		>;
+	};
+
+	main_spi0_pins: main-spi0-default-pins  {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x01c4, PIN_INPUT, 0) /* (AH13) SPI0_CLK */
+			AM65X_IOPAD(0x01c8, PIN_INPUT, 0) /* (AE13) SPI0_D0 */
+			AM65X_IOPAD(0x01cc, PIN_INPUT, 0) /* (AD13) SPI0_D1 */
+			AM65X_IOPAD(0x01bc, PIN_OUTPUT, 0) /* (AG13) SPI0_CS0 */
+		>;
+	};
+};
+
+&main_pmx1 {
+	asic_spi_mux_ctrl_pin: asic-spi-mux-ctrl-default-pins {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x0010, PIN_OUTPUT, 7)  /* (D21) GPIO1_86 */
+		>;
+	};
+};
+
+&wkup_pmx0 {
+	user1_led_pins: user1-led-default-pins {
+		pinctrl-single,pins = <
+			/* (AB1) WKUP_UART0_RXD:WKUP_GPIO0_52, as USER 1 led red */
+			AM65X_WKUP_IOPAD(0x00a0, PIN_OUTPUT, 7)
+			/* (AB5) WKUP_UART0_TXD:WKUP_GPIO0_53, as USER 1 led green */
+			AM65X_WKUP_IOPAD(0x00a4, PIN_OUTPUT, 7)
+		>;
+	};
+
+	soc_asic_pins: soc-asic-default-pins {
+		pinctrl-single,pins = <
+			AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 7)  /* (P4) WKUP_GPIO0_29 */
+			AM65X_WKUP_IOPAD(0x0048, PIN_INPUT, 7)  /* (P5) WKUP_GPIO0_30 */
+			AM65X_WKUP_IOPAD(0x004c, PIN_INPUT, 7)  /* (P1) WKUP_GPIO0_31 */
+		>;
+	};
+};
+
+&main_gpio0 {
+	gpio-line-names = "main_gpio0-base";
+};
+
+&main_gpio1 {
+	pinctrl-names = "default";
+	pinctrl-0 =
+		<&cp2102n_reset_pin_default>,
+		<&main_pcie_enable_pins_default>,
+		<&asic_spi_mux_ctrl_pin>;
+	gpio-line-names =
+		/* 0..9 */
+		"", "", "", "", "", "", "", "", "", "",
+		/* 10..19 */
+		"", "", "", "", "", "", "", "", "", "",
+		/* 20..29 */
+		"", "", "", "", "CP2102N-RESET", "", "", "", "", "",
+		/* 30..39 */
+		"", "", "", "", "", "", "", "", "", "",
+		/* 40..49 */
+		"", "", "", "", "", "", "", "", "", "",
+		/* 50..59 */
+		"", "", "", "", "", "", "", "", "", "",
+		/* 60..69 */
+		"", "", "", "", "", "", "", "", "", "",
+		/* 70..79 */
+		"", "", "", "", "", "", "", "", "", "",
+		/* 80..86 */
+		"", "", "", "", "", "", "ASIC-spi-mux-ctrl";
+};
+
+&wkup_gpio0 {
+	pinctrl-names = "default";
+	pinctrl-0 =
+		<&push_button_pins_default>,
+		<&db9_com_mode_pins_default>,
+		<&soc_asic_pins>;
+	gpio-line-names =
+		/* 0..9 */
+		"wkup_gpio0-base", "", "", "", "UART0-mode1", "UART0-mode0",
+		"UART0-enable", "UART0-terminate", "", "WIFI-disable",
+		/* 10..19 */
+		"", "", "", "", "", "", "", "", "", "",
+		/* 20..29 */
+		"", "", "", "", "", "USER-button", "", "", "","ASIC-gpio-0",
+		/* 30..31 */
+		"ASIC-gpio-1", "ASIC-gpio-2";
+};
+
+&main_spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_spi0_pins>;
+
+	#address-cells = <1>;
+	#size-cells= <0>;
+};
+
+&mcu_spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_spi0_pins_default>;
+};
+
+&main_i2c3 {
+	accelerometer: lsm6dso at 6a {
+		compatible = "st,lsm6dso";
+		reg = <0x6a>;
+	};
+};
+
+&dss {
+	status = "disabled";
+};
+
+&serdes0 {
+	assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
+	assigned-clock-parents = <&k3_clks 153 8>, <&k3_clks 153 4>;
+};
+
+&serdes1 {
+	status = "disabled";
+};
+
+&pcie0_rc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&minipcie_pins_default>;
+
+	num-lanes = <1>;
+	phys = <&serdes0 PHY_TYPE_PCIE 1>;
+	phy-names = "pcie-phy0";
+	reset-gpios = <&wkup_gpio0 27 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&pcie1_rc {
+	status = "disabled";
+};
-- 
2.35.3



From jan.kiszka at siemens.com  Thu Feb  8 23:23:17 2024
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Fri,  9 Feb 2024 08:23:17 +0100
Subject: [PATCH v3 3/7] arm64: dts: ti: iot2050: Factor out arduino connector bits
In-Reply-To: <cover.1707463401.git.jan.kiszka@siemens.com>
References: <cover.1707463401.git.jan.kiszka@siemens.com>
Message-ID: <3366367dc9f190c9e21027b9a810886791e99245.1707463401.git.jan.kiszka@siemens.com>

From: Jan Kiszka <jan.kiszka at siemens.com>

A new variant is to be added which will not have a arduino connector
like the existing ones. Factor out all bits that are specific to this
connector.

The split is not perfect because wkup_gpio0 is defined based on what is
common to all variants having the connector, thus containing also
connector-unrelated information. But this is still cleaner than
replicating this node into all 4 variants.

Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
---
 .../ti/k3-am65-iot2050-arduino-connector.dtsi | 768 ++++++++++++++++++
 .../boot/dts/ti/k3-am65-iot2050-common.dtsi   | 753 -----------------
 .../ti/k3-am6528-iot2050-basic-common.dtsi    |   1 +
 .../dts/ti/k3-am6548-iot2050-advanced-m2.dts  |   1 +
 .../dts/ti/k3-am6548-iot2050-advanced-pg2.dts |   1 +
 .../dts/ti/k3-am6548-iot2050-advanced.dts     |   1 +
 6 files changed, 772 insertions(+), 753 deletions(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi

diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
new file mode 100644
index 000000000000..cd86f412b837
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
@@ -0,0 +1,768 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) Siemens AG, 2018-2023
+ *
+ * Authors:
+ *   Le Jin <le.jin at siemens.com>
+ *   Jan Kiszka <jan.kiszka at siemens.com>
+ *
+ * Common bits for IOT2050 variants with Arduino connector
+ */
+
+&wkup_pmx0 {
+	pinctrl-names =
+		"default",
+		"d0-uart0-rxd",  "d0-gpio",  "d0-gpio-pullup",  "d0-gpio-pulldown",
+		"d1-uart0-txd",  "d1-gpio",  "d1-gpio-pullup",  "d1-gpio-pulldown",
+		"d2-uart0-ctsn", "d2-gpio",  "d2-gpio-pullup",  "d2-gpio-pulldown",
+		"d3-uart0-rtsn", "d3-gpio",  "d3-gpio-pullup",  "d3-gpio-pulldown",
+		"d10-spi0-cs0",  "d10-gpio", "d10-gpio-pullup", "d10-gpio-pulldown",
+		"d11-spi0-d0",   "d11-gpio", "d11-gpio-pullup", "d11-gpio-pulldown",
+		"d12-spi0-d1",   "d12-gpio", "d12-gpio-pullup", "d12-gpio-pulldown",
+		"d13-spi0-clk",  "d13-gpio", "d13-gpio-pullup", "d13-gpio-pulldown",
+		"a0-gpio", "a0-gpio-pullup", "a0-gpio-pulldown",
+		"a1-gpio", "a1-gpio-pullup", "a1-gpio-pulldown",
+		"a2-gpio", "a2-gpio-pullup", "a2-gpio-pulldown",
+		"a3-gpio", "a3-gpio-pullup", "a3-gpio-pulldown",
+		"a4-gpio", "a4-gpio-pullup", "a4-gpio-pulldown",
+		"a5-gpio", "a5-gpio-pullup", "a5-gpio-pulldown";
+
+	pinctrl-0 = <&d0_uart0_rxd>;
+	pinctrl-1 = <&d0_uart0_rxd>;
+	pinctrl-2 = <&d0_gpio>;
+	pinctrl-3 = <&d0_gpio_pullup>;
+	pinctrl-4 = <&d0_gpio_pulldown>;
+	pinctrl-5 = <&d1_uart0_txd>;
+	pinctrl-6 = <&d1_gpio>;
+	pinctrl-7 = <&d1_gpio_pullup>;
+	pinctrl-8 = <&d1_gpio_pulldown>;
+	pinctrl-9 = <&d2_uart0_ctsn>;
+	pinctrl-10 = <&d2_gpio>;
+	pinctrl-11 = <&d2_gpio_pullup>;
+	pinctrl-12 = <&d2_gpio_pulldown>;
+	pinctrl-13 = <&d3_uart0_rtsn>;
+	pinctrl-14 = <&d3_gpio>;
+	pinctrl-15 = <&d3_gpio_pullup>;
+	pinctrl-16 = <&d3_gpio_pulldown>;
+	pinctrl-17 = <&d10_spi0_cs0>;
+	pinctrl-18 = <&d10_gpio>;
+	pinctrl-19 = <&d10_gpio_pullup>;
+	pinctrl-20 = <&d10_gpio_pulldown>;
+	pinctrl-21 = <&d11_spi0_d0>;
+	pinctrl-22 = <&d11_gpio>;
+	pinctrl-23 = <&d11_gpio_pullup>;
+	pinctrl-24 = <&d11_gpio_pulldown>;
+	pinctrl-25 = <&d12_spi0_d1>;
+	pinctrl-26 = <&d12_gpio>;
+	pinctrl-27 = <&d12_gpio_pullup>;
+	pinctrl-28 = <&d12_gpio_pulldown>;
+	pinctrl-29 = <&d13_spi0_clk>;
+	pinctrl-30 = <&d13_gpio>;
+	pinctrl-31 = <&d13_gpio_pullup>;
+	pinctrl-32 = <&d13_gpio_pulldown>;
+	pinctrl-33 = <&a0_gpio>;
+	pinctrl-34 = <&a0_gpio_pullup>;
+	pinctrl-35 = <&a0_gpio_pulldown>;
+	pinctrl-36 = <&a1_gpio>;
+	pinctrl-37 = <&a1_gpio_pullup>;
+	pinctrl-38 = <&a1_gpio_pulldown>;
+	pinctrl-39 = <&a2_gpio>;
+	pinctrl-40 = <&a2_gpio_pullup>;
+	pinctrl-41 = <&a2_gpio_pulldown>;
+	pinctrl-42 = <&a3_gpio>;
+	pinctrl-43 = <&a3_gpio_pullup>;
+	pinctrl-44 = <&a3_gpio_pulldown>;
+	pinctrl-45 = <&a4_gpio>;
+	pinctrl-46 = <&a4_gpio_pullup>;
+	pinctrl-47 = <&a4_gpio_pulldown>;
+	pinctrl-48 = <&a5_gpio>;
+	pinctrl-49 = <&a5_gpio_pullup>;
+	pinctrl-50 = <&a5_gpio_pulldown>;
+
+	d0_uart0_rxd: d0-uart0-rxd-pins {
+		pinctrl-single,pins = <
+			/* (P4) MCU_UART0_RXD */
+			AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 4)
+		>;
+	};
+
+	d0_gpio: d0-gpio-pins {
+		pinctrl-single,pins = <
+			/* (P4) WKUP_GPIO0_29 */
+			AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 7)
+		>;
+	};
+
+	d0_gpio_pullup: d0-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (P4) WKUP_GPIO0_29 */
+			AM65X_WKUP_IOPAD(0x0044, PIN_INPUT_PULLUP, 7)
+		>;
+	};
+
+	d0_gpio_pulldown: d0-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (P4) WKUP_GPIO0_29 */
+			AM65X_WKUP_IOPAD(0x0044, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d1_uart0_txd: d1-uart0-txd-pins {
+		pinctrl-single,pins = <
+			/* (P5) MCU_UART0_TXD */
+			AM65X_WKUP_IOPAD(0x0048, PIN_OUTPUT, 4)
+		>;
+	};
+
+	d1_gpio: d1-gpio-pins {
+		pinctrl-single,pins = <
+			/* (P5) WKUP_GPIO0_30 */
+			AM65X_WKUP_IOPAD(0x0048, PIN_INPUT, 7)
+		>;
+	};
+
+	d1_gpio_pullup: d1-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (P5) WKUP_GPIO0_30 */
+			AM65X_WKUP_IOPAD(0x0048, PIN_INPUT, 7)
+		>;
+	};
+
+	d1_gpio_pulldown: d1-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (P5) WKUP_GPIO0_30 */
+			AM65X_WKUP_IOPAD(0x0048, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d2_uart0_ctsn: d2-uart0-ctsn-pins {
+		pinctrl-single,pins = <
+			/* (P1) MCU_UART0_CTSn */
+			AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 4)
+		>;
+	};
+
+	d2_gpio: d2-gpio-pins {
+		pinctrl-single,pins = <
+			/* (P5) WKUP_GPIO0_31 */
+			AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 7)
+		>;
+	};
+
+	d2_gpio_pullup: d2-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (P5) WKUP_GPIO0_31 */
+			AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 7)
+		>;
+	};
+
+	d2_gpio_pulldown: d2-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (P5) WKUP_GPIO0_31 */
+			AM65X_WKUP_IOPAD(0x004C, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d3_uart0_rtsn: d3-uart0-rtsn-pins {
+		pinctrl-single,pins = <
+			/* (N3) MCU_UART0_RTSn */
+			AM65X_WKUP_IOPAD(0x0054, PIN_OUTPUT, 4)
+		>;
+	};
+
+	d3_gpio: d3-gpio-pins {
+		pinctrl-single,pins = <
+			/* (N3) WKUP_GPIO0_33 */
+			AM65X_WKUP_IOPAD(0x0054, PIN_INPUT, 7)
+		>;
+	};
+
+	d3_gpio_pullup: d3-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (N3) WKUP_GPIO0_33 */
+			AM65X_WKUP_IOPAD(0x0054, PIN_INPUT, 7)
+		>;
+	};
+
+	d3_gpio_pulldown: d3-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (N3) WKUP_GPIO0_33 */
+			AM65X_WKUP_IOPAD(0x0054, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d10_spi0_cs0: d10-spi0-cs0-pins {
+		pinctrl-single,pins = <
+			/* (Y4) MCU_SPI0_CS0 */
+			AM65X_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0)
+		>;
+	};
+
+	d10_gpio: d10-gpio-pins {
+		pinctrl-single,pins = <
+			/* (Y4) WKUP_GPIO0_51 */
+			AM65X_WKUP_IOPAD(0x009c, PIN_INPUT, 7)
+		>;
+	};
+
+	d10_gpio_pullup: d10-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (Y4) WKUP_GPIO0_51 */
+			AM65X_WKUP_IOPAD(0x009c, PIN_INPUT, 7)
+		>;
+	};
+
+	d10_gpio_pulldown: d10-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (Y4) WKUP_GPIO0_51 */
+			AM65X_WKUP_IOPAD(0x009c, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d11_spi0_d0: d11-spi0-d0-pins {
+		pinctrl-single,pins = <
+			/* (Y3) MCU_SPI0_D0 */
+			AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 0)
+		>;
+	};
+
+	d11_gpio: d11-gpio-pins {
+		pinctrl-single,pins = <
+			/* (Y3) WKUP_GPIO0_49 */
+			AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 7)
+		>;
+	};
+
+	d11_gpio_pullup: d11-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (Y3) WKUP_GPIO0_49 */
+			AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 7)
+		>;
+	};
+
+	d11_gpio_pulldown: d11-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (Y3) WKUP_GPIO0_49 */
+			AM65X_WKUP_IOPAD(0x0094, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d12_spi0_d1: d12-spi0-d1-pins {
+		pinctrl-single,pins = <
+			/* (Y2) MCU_SPI0_D1 */
+			AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 0)
+		>;
+	};
+
+	d12_gpio: d12-gpio-pins {
+		pinctrl-single,pins = <
+			/* (Y2) WKUP_GPIO0_50 */
+			AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 7)
+		>;
+	};
+
+	d12_gpio_pullup: d12-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (Y2) WKUP_GPIO0_50 */
+			AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 7)
+		>;
+	};
+
+	d12_gpio_pulldown: d12-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (Y2) WKUP_GPIO0_50 */
+			AM65X_WKUP_IOPAD(0x0098, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d13_spi0_clk: d13-spi0-clk-pins {
+		pinctrl-single,pins = <
+			/* (Y1) MCU_SPI0_CLK */
+			AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 0)
+		>;
+	};
+
+	d13_gpio: d13-gpio-pins {
+		pinctrl-single,pins = <
+			/* (Y1) WKUP_GPIO0_48 */
+			AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 7)
+		>;
+	};
+
+	d13_gpio_pullup: d13-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (Y1) WKUP_GPIO0_48 */
+			AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 7)
+		>;
+	};
+
+	d13_gpio_pulldown: d13-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (Y1) WKUP_GPIO0_48 */
+			AM65X_WKUP_IOPAD(0x0090, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	a0_gpio: a0-gpio-pins {
+		pinctrl-single,pins = <
+			/* (L6) WKUP_GPIO0_45 */
+			AM65X_WKUP_IOPAD(0x0084, PIN_INPUT, 7)
+		>;
+	};
+
+	a0_gpio_pullup: a0-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (L6) WKUP_GPIO0_45 */
+			AM65X_WKUP_IOPAD(0x0084, PIN_INPUT, 7)
+		>;
+	};
+
+	a0_gpio_pulldown: a0-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (L6) WKUP_GPIO0_45 */
+			AM65X_WKUP_IOPAD(0x0084, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	a1_gpio: a1-gpio-pins {
+		pinctrl-single,pins = <
+			/* (M6) WKUP_GPIO0_44 */
+			AM65X_WKUP_IOPAD(0x0080, PIN_INPUT, 7)
+		>;
+	};
+
+	a1_gpio_pullup: a1-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (M6) WKUP_GPIO0_44 */
+			AM65X_WKUP_IOPAD(0x0080, PIN_INPUT, 7)
+		>;
+	};
+
+	a1_gpio_pulldown: a1-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (M6) WKUP_GPIO0_44 */
+			AM65X_WKUP_IOPAD(0x0080, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	a2_gpio: a2-gpio-pins {
+		pinctrl-single,pins = <
+			/* (L5) WKUP_GPIO0_43 */
+			AM65X_WKUP_IOPAD(0x007C, PIN_INPUT, 7)
+		>;
+	};
+
+	a2_gpio_pullup: a2-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (L5) WKUP_GPIO0_43 */
+			AM65X_WKUP_IOPAD(0x007C, PIN_INPUT, 7)
+		>;
+	};
+
+	a2_gpio_pulldown: a2-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (L5) WKUP_GPIO0_43 */
+			AM65X_WKUP_IOPAD(0x007C, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	a3_gpio: a3-gpio-pins {
+		pinctrl-single,pins = <
+			/* (M5) WKUP_GPIO0_39 */
+			AM65X_WKUP_IOPAD(0x006C, PIN_INPUT, 7)
+		>;
+	};
+
+	a3_gpio_pullup: a3-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (M5) WKUP_GPIO0_39 */
+			AM65X_WKUP_IOPAD(0x006C, PIN_INPUT, 7)
+		>;
+	};
+
+	a3_gpio_pulldown: a3-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (M5) WKUP_GPIO0_39 */
+			AM65X_WKUP_IOPAD(0x006C, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	a4_gpio: a4-gpio-pins {
+		pinctrl-single,pins = <
+			/* (L2) WKUP_GPIO0_42 */
+			AM65X_WKUP_IOPAD(0x0078, PIN_INPUT, 7)
+		>;
+	};
+
+	a4_gpio_pullup: a4-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (L2) WKUP_GPIO0_42 */
+			AM65X_WKUP_IOPAD(0x0078, PIN_INPUT, 7)
+		>;
+	};
+
+	a4_gpio_pulldown: a4-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (L2) WKUP_GPIO0_42 */
+			AM65X_WKUP_IOPAD(0x0078, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	a5_gpio: a5-gpio-pins {
+		pinctrl-single,pins = <
+			/* (N5) WKUP_GPIO0_35 */
+			AM65X_WKUP_IOPAD(0x005C, PIN_INPUT, 7)
+		>;
+	};
+
+	a5_gpio_pullup: a5-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (N5) WKUP_GPIO0_35 */
+			AM65X_WKUP_IOPAD(0x005C, PIN_INPUT_PULLUP, 7)
+		>;
+	};
+
+	a5_gpio_pulldown: a5-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (N5) WKUP_GPIO0_35 */
+			AM65X_WKUP_IOPAD(0x005C, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+		pinctrl-single,pins = <
+			/* (AC7) WKUP_I2C0_SCL */
+			AM65X_WKUP_IOPAD(0x00e0, PIN_INPUT,  0)
+			/* (AD6) WKUP_I2C0_SDA */
+			AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT,  0)
+		>;
+	};
+
+	arduino_i2c_aio_switch_pins_default: arduino-i2c-aio-switch-default-pins {
+		pinctrl-single,pins = <
+			/* (R2) WKUP_GPIO0_21 */
+			AM65X_WKUP_IOPAD(0x0024, PIN_OUTPUT, 7)
+		>;
+	};
+
+	arduino_io_oe_pins_default: arduino-io-oe-default-pins {
+		pinctrl-single,pins = <
+			/* (N4) WKUP_GPIO0_34 */
+			AM65X_WKUP_IOPAD(0x0058, PIN_OUTPUT, 7)
+			/* (M2) WKUP_GPIO0_36 */
+			AM65X_WKUP_IOPAD(0x0060, PIN_OUTPUT, 7)
+			/* (M3) WKUP_GPIO0_37 */
+			AM65X_WKUP_IOPAD(0x0064, PIN_OUTPUT, 7)
+			/* (M4) WKUP_GPIO0_38 */
+			AM65X_WKUP_IOPAD(0x0068, PIN_OUTPUT, 7)
+			/* (M1) WKUP_GPIO0_41 */
+			AM65X_WKUP_IOPAD(0x0074, PIN_OUTPUT, 7)
+		>;
+	};
+};
+
+&main_pmx0 {
+	pinctrl-names =
+		"default",
+		"d4-ehrpwm0-a", "d4-gpio", "d4-gpio-pullup", "d4-gpio-pulldown",
+		"d5-ehrpwm1-a", "d5-gpio", "d5-gpio-pullup", "d5-gpio-pulldown",
+		"d6-ehrpwm2-a", "d6-gpio", "d6-gpio-pullup", "d6-gpio-pulldown",
+		"d7-ehrpwm3-a", "d7-gpio", "d7-gpio-pullup", "d7-gpio-pulldown",
+		"d8-ehrpwm4-a", "d8-gpio", "d8-gpio-pullup", "d8-gpio-pulldown",
+		"d9-ehrpwm5-a", "d9-gpio", "d9-gpio-pullup", "d9-gpio-pulldown";
+
+	pinctrl-0 = <&d4_ehrpwm0_a>;
+	pinctrl-1 = <&d4_ehrpwm0_a>;
+	pinctrl-2 = <&d4_gpio>;
+	pinctrl-3 = <&d4_gpio_pullup>;
+	pinctrl-4 = <&d4_gpio_pulldown>;
+
+	pinctrl-5 = <&d5_ehrpwm1_a>;
+	pinctrl-6 = <&d5_gpio>;
+	pinctrl-7 = <&d5_gpio_pullup>;
+	pinctrl-8 = <&d5_gpio_pulldown>;
+
+	pinctrl-9 = <&d6_ehrpwm2_a>;
+	pinctrl-10 = <&d6_gpio>;
+	pinctrl-11 = <&d6_gpio_pullup>;
+	pinctrl-12 = <&d6_gpio_pulldown>;
+
+	pinctrl-13 = <&d7_ehrpwm3_a>;
+	pinctrl-14 = <&d7_gpio>;
+	pinctrl-15 = <&d7_gpio_pullup>;
+	pinctrl-16 = <&d7_gpio_pulldown>;
+
+	pinctrl-17 = <&d8_ehrpwm4_a>;
+	pinctrl-18 = <&d8_gpio>;
+	pinctrl-19 = <&d8_gpio_pullup>;
+	pinctrl-20 = <&d8_gpio_pulldown>;
+
+	pinctrl-21 = <&d9_ehrpwm5_a>;
+	pinctrl-22 = <&d9_gpio>;
+	pinctrl-23 = <&d9_gpio_pullup>;
+	pinctrl-24 = <&d9_gpio_pulldown>;
+
+	d4_ehrpwm0_a: d4-ehrpwm0-a-pins {
+		pinctrl-single,pins = <
+			/* (AG18) EHRPWM0_A */
+			AM65X_IOPAD(0x0084, PIN_OUTPUT, 5)
+		>;
+	};
+
+	d4_gpio: d4-gpio-pins {
+		pinctrl-single,pins = <
+			/* (AG18) GPIO0_33 */
+			AM65X_IOPAD(0x0084, PIN_INPUT, 7)
+		>;
+	};
+
+	d4_gpio_pullup: d4-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (AG18) GPIO0_33 */
+			AM65X_IOPAD(0x0084, PIN_INPUT_PULLUP, 7)
+		>;
+	};
+
+	d4_gpio_pulldown: d4-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (AG18) GPIO0_33 */
+			AM65X_IOPAD(0x0084, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d5_ehrpwm1_a: d5-ehrpwm1-a-pins {
+		pinctrl-single,pins = <
+			/* (AF17) EHRPWM1_A */
+			AM65X_IOPAD(0x008C, PIN_OUTPUT, 5)
+		>;
+	};
+
+	d5_gpio: d5-gpio-pins {
+		pinctrl-single,pins = <
+			/* (AF17) GPIO0_35 */
+			AM65X_IOPAD(0x008C, PIN_INPUT, 7)
+		>;
+	};
+
+	d5_gpio_pullup: d5-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (AF17) GPIO0_35 */
+			AM65X_IOPAD(0x008C, PIN_INPUT_PULLUP, 7)
+		>;
+	};
+
+	d5_gpio_pulldown: d5-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (AF17) GPIO0_35 */
+			AM65X_IOPAD(0x008C, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d6_ehrpwm2_a: d6-ehrpwm2-a-pins {
+		pinctrl-single,pins = <
+			/* (AH16) EHRPWM2_A */
+			AM65X_IOPAD(0x0098, PIN_OUTPUT, 5)
+		>;
+	};
+
+	d6_gpio: d6-gpio-pins {
+		pinctrl-single,pins = <
+			/* (AH16) GPIO0_38 */
+			AM65X_IOPAD(0x0098, PIN_INPUT, 7)
+		>;
+	};
+
+	d6_gpio_pullup: d6-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (AH16) GPIO0_38 */
+			AM65X_IOPAD(0x0098, PIN_INPUT_PULLUP, 7)
+		>;
+	};
+
+	d6_gpio_pulldown: d6-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (AH16) GPIO0_38 */
+			AM65X_IOPAD(0x0098, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d7_ehrpwm3_a: d7-ehrpwm3-a-pins {
+		pinctrl-single,pins = <
+			/* (AH15) EHRPWM3_A */
+			AM65X_IOPAD(0x00AC, PIN_OUTPUT, 5)
+		>;
+	};
+
+	d7_gpio: d7-gpio-pins {
+		pinctrl-single,pins = <
+			/* (AH15) GPIO0_43 */
+			AM65X_IOPAD(0x00AC, PIN_INPUT, 7)
+		>;
+	};
+
+	d7_gpio_pullup: d7-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (AH15) GPIO0_43 */
+			AM65X_IOPAD(0x00AC, PIN_INPUT_PULLUP, 7)
+		>;
+	};
+
+	d7_gpio_pulldown: d7-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (AH15) GPIO0_43 */
+			AM65X_IOPAD(0x00AC, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d8_ehrpwm4_a: d8-ehrpwm4-a-pins {
+		pinctrl-single,pins = <
+			/* (AG15) EHRPWM4_A */
+			AM65X_IOPAD(0x00C0, PIN_OUTPUT, 5)
+		>;
+	};
+
+	d8_gpio: d8-gpio-pins {
+		pinctrl-single,pins = <
+			/* (AG15) GPIO0_48 */
+			AM65X_IOPAD(0x00C0, PIN_INPUT, 7)
+		>;
+	};
+
+	d8_gpio_pullup: d8-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (AG15) GPIO0_48 */
+			AM65X_IOPAD(0x00C0, PIN_INPUT_PULLUP, 7)
+		>;
+	};
+
+	d8_gpio_pulldown: d8-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (AG15) GPIO0_48 */
+			AM65X_IOPAD(0x00C0, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+
+	d9_ehrpwm5_a: d9-ehrpwm5-a-pins {
+		pinctrl-single,pins = <
+			/* (AD15) EHRPWM5_A */
+			AM65X_IOPAD(0x00CC, PIN_OUTPUT, 5)
+		>;
+	};
+
+	d9_gpio: d9-gpio-pins {
+		pinctrl-single,pins = <
+			/* (AD15) GPIO0_51 */
+			AM65X_IOPAD(0x00CC, PIN_INPUT, 7)
+		>;
+	};
+
+	d9_gpio_pullup: d9-gpio-pullup-pins {
+		pinctrl-single,pins = <
+			/* (AD15) GPIO0_51 */
+			AM65X_IOPAD(0x00CC, PIN_INPUT_PULLUP, 7)
+		>;
+	};
+
+	d9_gpio_pulldown: d9-gpio-pulldown-pins {
+		pinctrl-single,pins = <
+			/* (AD15) GPIO0_51 */
+			AM65X_IOPAD(0x00CC, PIN_INPUT_PULLDOWN, 7)
+		>;
+	};
+};
+
+&main_gpio0 {
+	gpio-line-names =
+		"main_gpio0-base", "", "", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "", "", "",
+		"", "", "", "IO4", "", "IO5", "", "", "IO6", "",
+		"", "", "", "IO7", "", "", "", "", "IO8", "",
+		"", "IO9";
+};
+
+&wkup_gpio0 {
+	pinctrl-names = "default";
+	pinctrl-0 =
+		<&arduino_i2c_aio_switch_pins_default>,
+		<&arduino_io_oe_pins_default>,
+		<&push_button_pins_default>,
+		<&db9_com_mode_pins_default>;
+	gpio-line-names =
+		/* 0..9 */
+		"wkup_gpio0-base", "", "", "", "UART0-mode1", "UART0-mode0",
+		"UART0-enable", "UART0-terminate", "", "WIFI-disable",
+		/* 10..19 */
+		"", "", "", "", "", "", "", "", "", "",
+		/* 20..29 */
+		"", "A4A5-I2C-mux", "", "", "", "USER-button", "", "", "","IO0",
+		/* 30..39 */
+		"IO1", "IO2", "", "IO3", "IO17-direction", "A5",
+		"IO16-direction", "IO15-direction", "IO14-direction", "A3",
+		/* 40..49 */
+		"", "IO18-direction", "A4", "A2", "A1", "A0", "", "", "IO13",
+		"IO11",
+		/* 50..51 */
+		"IO12", "IO10";
+};
+
+&wkup_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_i2c0_pins_default>;
+	clock-frequency = <400000>;
+};
+
+&mcu_i2c0 {
+	/* D4200 */
+	pcal9535_1: gpio at 20 {
+		compatible = "nxp,pcal9535";
+		reg = <0x20>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-line-names =
+			"A0-pull", "A1-pull", "A2-pull", "A3-pull", "A4-pull",
+			"A5-pull", "", "",
+			"IO14-enable", "IO15-enable", "IO16-enable",
+			"IO17-enable", "IO18-enable", "IO19-enable";
+	};
+
+	/* D4201 */
+	pcal9535_2: gpio at 21 {
+		compatible = "nxp,pcal9535";
+		reg = <0x21>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-line-names =
+			"IO0-direction", "IO1-direction", "IO2-direction",
+			"IO3-direction", "IO4-direction", "IO5-direction",
+			"IO6-direction", "IO7-direction",
+			"IO8-direction", "IO9-direction", "IO10-direction",
+			"IO11-direction", "IO12-direction", "IO13-direction",
+			"IO19-direction";
+	};
+
+	/* D4202 */
+	pcal9535_3: gpio at 25 {
+		compatible = "nxp,pcal9535";
+		reg = <0x25>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-line-names =
+			"IO0-pull", "IO1-pull", "IO2-pull", "IO3-pull",
+			"IO4-pull", "IO5-pull", "IO6-pull", "IO7-pull",
+			"IO8-pull", "IO9-pull", "IO10-pull", "IO11-pull",
+			"IO12-pull", "IO13-pull";
+	};
+};
+
+&mcu_uart0 {
+	status = "okay";
+};
+
+&tscadc1 {
+	status = "okay";
+	adc {
+		ti,adc-channels = <0 1 2 3 4 5>;
+	};
+};
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 148fb8880089..3ba81866599e 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
@@ -192,434 +192,6 @@ icssg0_emac1: port at 1 {
 };
 
 &wkup_pmx0 {
-	pinctrl-names =
-		"default",
-		"d0-uart0-rxd",  "d0-gpio",  "d0-gpio-pullup",  "d0-gpio-pulldown",
-		"d1-uart0-txd",  "d1-gpio",  "d1-gpio-pullup",  "d1-gpio-pulldown",
-		"d2-uart0-ctsn", "d2-gpio",  "d2-gpio-pullup",  "d2-gpio-pulldown",
-		"d3-uart0-rtsn", "d3-gpio",  "d3-gpio-pullup",  "d3-gpio-pulldown",
-		"d10-spi0-cs0",  "d10-gpio", "d10-gpio-pullup", "d10-gpio-pulldown",
-		"d11-spi0-d0",   "d11-gpio", "d11-gpio-pullup", "d11-gpio-pulldown",
-		"d12-spi0-d1",   "d12-gpio", "d12-gpio-pullup", "d12-gpio-pulldown",
-		"d13-spi0-clk",  "d13-gpio", "d13-gpio-pullup", "d13-gpio-pulldown",
-		"a0-gpio", "a0-gpio-pullup", "a0-gpio-pulldown",
-		"a1-gpio", "a1-gpio-pullup", "a1-gpio-pulldown",
-		"a2-gpio", "a2-gpio-pullup", "a2-gpio-pulldown",
-		"a3-gpio", "a3-gpio-pullup", "a3-gpio-pulldown",
-		"a4-gpio", "a4-gpio-pullup", "a4-gpio-pulldown",
-		"a5-gpio", "a5-gpio-pullup", "a5-gpio-pulldown";
-
-	pinctrl-0 = <&d0_uart0_rxd>;
-	pinctrl-1 = <&d0_uart0_rxd>;
-	pinctrl-2 = <&d0_gpio>;
-	pinctrl-3 = <&d0_gpio_pullup>;
-	pinctrl-4 = <&d0_gpio_pulldown>;
-	pinctrl-5 = <&d1_uart0_txd>;
-	pinctrl-6 = <&d1_gpio>;
-	pinctrl-7 = <&d1_gpio_pullup>;
-	pinctrl-8 = <&d1_gpio_pulldown>;
-	pinctrl-9 = <&d2_uart0_ctsn>;
-	pinctrl-10 = <&d2_gpio>;
-	pinctrl-11 = <&d2_gpio_pullup>;
-	pinctrl-12 = <&d2_gpio_pulldown>;
-	pinctrl-13 = <&d3_uart0_rtsn>;
-	pinctrl-14 = <&d3_gpio>;
-	pinctrl-15 = <&d3_gpio_pullup>;
-	pinctrl-16 = <&d3_gpio_pulldown>;
-	pinctrl-17 = <&d10_spi0_cs0>;
-	pinctrl-18 = <&d10_gpio>;
-	pinctrl-19 = <&d10_gpio_pullup>;
-	pinctrl-20 = <&d10_gpio_pulldown>;
-	pinctrl-21 = <&d11_spi0_d0>;
-	pinctrl-22 = <&d11_gpio>;
-	pinctrl-23 = <&d11_gpio_pullup>;
-	pinctrl-24 = <&d11_gpio_pulldown>;
-	pinctrl-25 = <&d12_spi0_d1>;
-	pinctrl-26 = <&d12_gpio>;
-	pinctrl-27 = <&d12_gpio_pullup>;
-	pinctrl-28 = <&d12_gpio_pulldown>;
-	pinctrl-29 = <&d13_spi0_clk>;
-	pinctrl-30 = <&d13_gpio>;
-	pinctrl-31 = <&d13_gpio_pullup>;
-	pinctrl-32 = <&d13_gpio_pulldown>;
-	pinctrl-33 = <&a0_gpio>;
-	pinctrl-34 = <&a0_gpio_pullup>;
-	pinctrl-35 = <&a0_gpio_pulldown>;
-	pinctrl-36 = <&a1_gpio>;
-	pinctrl-37 = <&a1_gpio_pullup>;
-	pinctrl-38 = <&a1_gpio_pulldown>;
-	pinctrl-39 = <&a2_gpio>;
-	pinctrl-40 = <&a2_gpio_pullup>;
-	pinctrl-41 = <&a2_gpio_pulldown>;
-	pinctrl-42 = <&a3_gpio>;
-	pinctrl-43 = <&a3_gpio_pullup>;
-	pinctrl-44 = <&a3_gpio_pulldown>;
-	pinctrl-45 = <&a4_gpio>;
-	pinctrl-46 = <&a4_gpio_pullup>;
-	pinctrl-47 = <&a4_gpio_pulldown>;
-	pinctrl-48 = <&a5_gpio>;
-	pinctrl-49 = <&a5_gpio_pullup>;
-	pinctrl-50 = <&a5_gpio_pulldown>;
-
-	d0_uart0_rxd: d0-uart0-rxd-pins {
-		pinctrl-single,pins = <
-			/* (P4) MCU_UART0_RXD */
-			AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 4)
-		>;
-	};
-
-	d0_gpio: d0-gpio-pins {
-		pinctrl-single,pins = <
-			/* (P4) WKUP_GPIO0_29 */
-			AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 7)
-		>;
-	};
-
-	d0_gpio_pullup: d0-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (P4) WKUP_GPIO0_29 */
-			AM65X_WKUP_IOPAD(0x0044, PIN_INPUT_PULLUP, 7)
-		>;
-	};
-
-	d0_gpio_pulldown: d0-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (P4) WKUP_GPIO0_29 */
-			AM65X_WKUP_IOPAD(0x0044, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d1_uart0_txd: d1-uart0-txd-pins {
-		pinctrl-single,pins = <
-			/* (P5) MCU_UART0_TXD */
-			AM65X_WKUP_IOPAD(0x0048, PIN_OUTPUT, 4)
-		>;
-	};
-
-	d1_gpio: d1-gpio-pins {
-		pinctrl-single,pins = <
-			/* (P5) WKUP_GPIO0_30 */
-			AM65X_WKUP_IOPAD(0x0048, PIN_INPUT, 7)
-		>;
-	};
-
-	d1_gpio_pullup: d1-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (P5) WKUP_GPIO0_30 */
-			AM65X_WKUP_IOPAD(0x0048, PIN_INPUT, 7)
-		>;
-	};
-
-	d1_gpio_pulldown: d1-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (P5) WKUP_GPIO0_30 */
-			AM65X_WKUP_IOPAD(0x0048, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d2_uart0_ctsn: d2-uart0-ctsn-pins {
-		pinctrl-single,pins = <
-			/* (P1) MCU_UART0_CTSn */
-			AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 4)
-		>;
-	};
-
-	d2_gpio: d2-gpio-pins {
-		pinctrl-single,pins = <
-			/* (P5) WKUP_GPIO0_31 */
-			AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 7)
-		>;
-	};
-
-	d2_gpio_pullup: d2-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (P5) WKUP_GPIO0_31 */
-			AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 7)
-		>;
-	};
-
-	d2_gpio_pulldown: d2-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (P5) WKUP_GPIO0_31 */
-			AM65X_WKUP_IOPAD(0x004C, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d3_uart0_rtsn: d3-uart0-rtsn-pins {
-		pinctrl-single,pins = <
-			/* (N3) MCU_UART0_RTSn */
-			AM65X_WKUP_IOPAD(0x0054, PIN_OUTPUT, 4)
-		>;
-	};
-
-	d3_gpio: d3-gpio-pins {
-		pinctrl-single,pins = <
-			/* (N3) WKUP_GPIO0_33 */
-			AM65X_WKUP_IOPAD(0x0054, PIN_INPUT, 7)
-		>;
-	};
-
-	d3_gpio_pullup: d3-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (N3) WKUP_GPIO0_33 */
-			AM65X_WKUP_IOPAD(0x0054, PIN_INPUT, 7)
-		>;
-	};
-
-	d3_gpio_pulldown: d3-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (N3) WKUP_GPIO0_33 */
-			AM65X_WKUP_IOPAD(0x0054, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d10_spi0_cs0: d10-spi0-cs0-pins {
-		pinctrl-single,pins = <
-			/* (Y4) MCU_SPI0_CS0 */
-			AM65X_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0)
-		>;
-	};
-
-	d10_gpio: d10-gpio-pins {
-		pinctrl-single,pins = <
-			/* (Y4) WKUP_GPIO0_51 */
-			AM65X_WKUP_IOPAD(0x009c, PIN_INPUT, 7)
-		>;
-	};
-
-	d10_gpio_pullup: d10-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (Y4) WKUP_GPIO0_51 */
-			AM65X_WKUP_IOPAD(0x009c, PIN_INPUT, 7)
-		>;
-	};
-
-	d10_gpio_pulldown: d10-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (Y4) WKUP_GPIO0_51 */
-			AM65X_WKUP_IOPAD(0x009c, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d11_spi0_d0: d11-spi0-d0-pins {
-		pinctrl-single,pins = <
-			/* (Y3) MCU_SPI0_D0 */
-			AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 0)
-		>;
-	};
-
-	d11_gpio: d11-gpio-pins {
-		pinctrl-single,pins = <
-			/* (Y3) WKUP_GPIO0_49 */
-			AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 7)
-		>;
-	};
-
-	d11_gpio_pullup: d11-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (Y3) WKUP_GPIO0_49 */
-			AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 7)
-		>;
-	};
-
-	d11_gpio_pulldown: d11-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (Y3) WKUP_GPIO0_49 */
-			AM65X_WKUP_IOPAD(0x0094, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d12_spi0_d1: d12-spi0-d1-pins {
-		pinctrl-single,pins = <
-			/* (Y2) MCU_SPI0_D1 */
-			AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 0)
-		>;
-	};
-
-	d12_gpio: d12-gpio-pins {
-		pinctrl-single,pins = <
-			/* (Y2) WKUP_GPIO0_50 */
-			AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 7)
-		>;
-	};
-
-	d12_gpio_pullup: d12-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (Y2) WKUP_GPIO0_50 */
-			AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 7)
-		>;
-	};
-
-	d12_gpio_pulldown: d12-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (Y2) WKUP_GPIO0_50 */
-			AM65X_WKUP_IOPAD(0x0098, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d13_spi0_clk: d13-spi0-clk-pins {
-		pinctrl-single,pins = <
-			/* (Y1) MCU_SPI0_CLK */
-			AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 0)
-		>;
-	};
-
-	d13_gpio: d13-gpio-pins {
-		pinctrl-single,pins = <
-			/* (Y1) WKUP_GPIO0_48 */
-			AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 7)
-		>;
-	};
-
-	d13_gpio_pullup: d13-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (Y1) WKUP_GPIO0_48 */
-			AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 7)
-		>;
-	};
-
-	d13_gpio_pulldown: d13-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (Y1) WKUP_GPIO0_48 */
-			AM65X_WKUP_IOPAD(0x0090, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	a0_gpio: a0-gpio-pins {
-		pinctrl-single,pins = <
-			/* (L6) WKUP_GPIO0_45 */
-			AM65X_WKUP_IOPAD(0x0084, PIN_INPUT, 7)
-		>;
-	};
-
-	a0_gpio_pullup: a0-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (L6) WKUP_GPIO0_45 */
-			AM65X_WKUP_IOPAD(0x0084, PIN_INPUT, 7)
-		>;
-	};
-
-	a0_gpio_pulldown: a0-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (L6) WKUP_GPIO0_45 */
-			AM65X_WKUP_IOPAD(0x0084, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	a1_gpio: a1-gpio-pins {
-		pinctrl-single,pins = <
-			/* (M6) WKUP_GPIO0_44 */
-			AM65X_WKUP_IOPAD(0x0080, PIN_INPUT, 7)
-		>;
-	};
-
-	a1_gpio_pullup: a1-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (M6) WKUP_GPIO0_44 */
-			AM65X_WKUP_IOPAD(0x0080, PIN_INPUT, 7)
-		>;
-	};
-
-	a1_gpio_pulldown: a1-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (M6) WKUP_GPIO0_44 */
-			AM65X_WKUP_IOPAD(0x0080, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	a2_gpio: a2-gpio-pins {
-		pinctrl-single,pins = <
-			/* (L5) WKUP_GPIO0_43 */
-			AM65X_WKUP_IOPAD(0x007C, PIN_INPUT, 7)
-		>;
-	};
-
-	a2_gpio_pullup: a2-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (L5) WKUP_GPIO0_43 */
-			AM65X_WKUP_IOPAD(0x007C, PIN_INPUT, 7)
-		>;
-	};
-
-	a2_gpio_pulldown: a2-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (L5) WKUP_GPIO0_43 */
-			AM65X_WKUP_IOPAD(0x007C, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	a3_gpio: a3-gpio-pins {
-		pinctrl-single,pins = <
-			/* (M5) WKUP_GPIO0_39 */
-			AM65X_WKUP_IOPAD(0x006C, PIN_INPUT, 7)
-		>;
-	};
-
-	a3_gpio_pullup: a3-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (M5) WKUP_GPIO0_39 */
-			AM65X_WKUP_IOPAD(0x006C, PIN_INPUT, 7)
-		>;
-	};
-
-	a3_gpio_pulldown: a3-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (M5) WKUP_GPIO0_39 */
-			AM65X_WKUP_IOPAD(0x006C, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	a4_gpio: a4-gpio-pins {
-		pinctrl-single,pins = <
-			/* (L2) WKUP_GPIO0_42 */
-			AM65X_WKUP_IOPAD(0x0078, PIN_INPUT, 7)
-		>;
-	};
-
-	a4_gpio_pullup: a4-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (L2) WKUP_GPIO0_42 */
-			AM65X_WKUP_IOPAD(0x0078, PIN_INPUT, 7)
-		>;
-	};
-
-	a4_gpio_pulldown: a4-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (L2) WKUP_GPIO0_42 */
-			AM65X_WKUP_IOPAD(0x0078, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	a5_gpio: a5-gpio-pins {
-		pinctrl-single,pins = <
-			/* (N5) WKUP_GPIO0_35 */
-			AM65X_WKUP_IOPAD(0x005C, PIN_INPUT, 7)
-		>;
-	};
-
-	a5_gpio_pullup: a5-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (N5) WKUP_GPIO0_35 */
-			AM65X_WKUP_IOPAD(0x005C, PIN_INPUT_PULLUP, 7)
-		>;
-	};
-
-	a5_gpio_pulldown: a5-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (N5) WKUP_GPIO0_35 */
-			AM65X_WKUP_IOPAD(0x005C, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
-		pinctrl-single,pins = <
-			/* (AC7) WKUP_I2C0_SCL */
-			AM65X_WKUP_IOPAD(0x00e0, PIN_INPUT,  0)
-			/* (AD6) WKUP_I2C0_SDA */
-			AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT,  0)
-		>;
-	};
-
 	mcu_i2c0_pins_default: mcu-i2c0-default-pins {
 		pinctrl-single,pins = <
 			/* (AD8) MCU_I2C0_SCL */
@@ -629,13 +201,6 @@ AM65X_WKUP_IOPAD(0x00ec, PIN_INPUT,  0)
 		>;
 	};
 
-	arduino_i2c_aio_switch_pins_default: arduino-i2c-aio-switch-default-pins {
-		pinctrl-single,pins = <
-			/* (R2) WKUP_GPIO0_21 */
-			AM65X_WKUP_IOPAD(0x0024, PIN_OUTPUT, 7)
-		>;
-	};
-
 	push_button_pins_default: push-button-default-pins {
 		pinctrl-single,pins = <
 			/* (T1) MCU_OSPI1_CLK.WKUP_GPIO0_25 */
@@ -643,22 +208,6 @@ AM65X_WKUP_IOPAD(0x0034, PIN_INPUT,  7)
 		>;
 	};
 
-
-	arduino_io_oe_pins_default: arduino-io-oe-default-pins {
-		pinctrl-single,pins = <
-			/* (N4) WKUP_GPIO0_34 */
-			AM65X_WKUP_IOPAD(0x0058, PIN_OUTPUT, 7)
-			/* (M2) WKUP_GPIO0_36 */
-			AM65X_WKUP_IOPAD(0x0060, PIN_OUTPUT, 7)
-			/* (M3) WKUP_GPIO0_37 */
-			AM65X_WKUP_IOPAD(0x0064, PIN_OUTPUT, 7)
-			/* (M4) WKUP_GPIO0_38 */
-			AM65X_WKUP_IOPAD(0x0068, PIN_OUTPUT, 7)
-			/* (M1) WKUP_GPIO0_41 */
-			AM65X_WKUP_IOPAD(0x0074, PIN_OUTPUT, 7)
-		>;
-	};
-
 	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-default-pins {
 		pinctrl-single,pins = <
 			/* (V1) MCU_OSPI0_CLK */
@@ -722,214 +271,6 @@ AM65X_WKUP_IOPAD(0x003C, PIN_OUTPUT, 7)
 };
 
 &main_pmx0 {
-	pinctrl-names =
-		"default",
-		"d4-ehrpwm0-a", "d4-gpio", "d4-gpio-pullup", "d4-gpio-pulldown",
-		"d5-ehrpwm1-a", "d5-gpio", "d5-gpio-pullup", "d5-gpio-pulldown",
-		"d6-ehrpwm2-a", "d6-gpio", "d6-gpio-pullup", "d6-gpio-pulldown",
-		"d7-ehrpwm3-a", "d7-gpio", "d7-gpio-pullup", "d7-gpio-pulldown",
-		"d8-ehrpwm4-a", "d8-gpio", "d8-gpio-pullup", "d8-gpio-pulldown",
-		"d9-ehrpwm5-a", "d9-gpio", "d9-gpio-pullup", "d9-gpio-pulldown";
-
-	pinctrl-0 = <&d4_ehrpwm0_a>;
-	pinctrl-1 = <&d4_ehrpwm0_a>;
-	pinctrl-2 = <&d4_gpio>;
-	pinctrl-3 = <&d4_gpio_pullup>;
-	pinctrl-4 = <&d4_gpio_pulldown>;
-
-	pinctrl-5 = <&d5_ehrpwm1_a>;
-	pinctrl-6 = <&d5_gpio>;
-	pinctrl-7 = <&d5_gpio_pullup>;
-	pinctrl-8 = <&d5_gpio_pulldown>;
-
-	pinctrl-9 = <&d6_ehrpwm2_a>;
-	pinctrl-10 = <&d6_gpio>;
-	pinctrl-11 = <&d6_gpio_pullup>;
-	pinctrl-12 = <&d6_gpio_pulldown>;
-
-	pinctrl-13 = <&d7_ehrpwm3_a>;
-	pinctrl-14 = <&d7_gpio>;
-	pinctrl-15 = <&d7_gpio_pullup>;
-	pinctrl-16 = <&d7_gpio_pulldown>;
-
-	pinctrl-17 = <&d8_ehrpwm4_a>;
-	pinctrl-18 = <&d8_gpio>;
-	pinctrl-19 = <&d8_gpio_pullup>;
-	pinctrl-20 = <&d8_gpio_pulldown>;
-
-	pinctrl-21 = <&d9_ehrpwm5_a>;
-	pinctrl-22 = <&d9_gpio>;
-	pinctrl-23 = <&d9_gpio_pullup>;
-	pinctrl-24 = <&d9_gpio_pulldown>;
-
-	d4_ehrpwm0_a: d4-ehrpwm0-a-pins {
-		pinctrl-single,pins = <
-			/* (AG18) EHRPWM0_A */
-			AM65X_IOPAD(0x0084, PIN_OUTPUT, 5)
-		>;
-	};
-
-	d4_gpio: d4-gpio-pins {
-		pinctrl-single,pins = <
-			/* (AG18) GPIO0_33 */
-			AM65X_IOPAD(0x0084, PIN_INPUT, 7)
-		>;
-	};
-
-	d4_gpio_pullup: d4-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (AG18) GPIO0_33 */
-			AM65X_IOPAD(0x0084, PIN_INPUT_PULLUP, 7)
-		>;
-	};
-
-	d4_gpio_pulldown: d4-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (AG18) GPIO0_33 */
-			AM65X_IOPAD(0x0084, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d5_ehrpwm1_a: d5-ehrpwm1-a-pins {
-		pinctrl-single,pins = <
-			/* (AF17) EHRPWM1_A */
-			AM65X_IOPAD(0x008C, PIN_OUTPUT, 5)
-		>;
-	};
-
-	d5_gpio: d5-gpio-pins {
-		pinctrl-single,pins = <
-			/* (AF17) GPIO0_35 */
-			AM65X_IOPAD(0x008C, PIN_INPUT, 7)
-		>;
-	};
-
-	d5_gpio_pullup: d5-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (AF17) GPIO0_35 */
-			AM65X_IOPAD(0x008C, PIN_INPUT_PULLUP, 7)
-		>;
-	};
-
-	d5_gpio_pulldown: d5-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (AF17) GPIO0_35 */
-			AM65X_IOPAD(0x008C, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d6_ehrpwm2_a: d6-ehrpwm2-a-pins {
-		pinctrl-single,pins = <
-			/* (AH16) EHRPWM2_A */
-			AM65X_IOPAD(0x0098, PIN_OUTPUT, 5)
-		>;
-	};
-
-	d6_gpio: d6-gpio-pins {
-		pinctrl-single,pins = <
-			/* (AH16) GPIO0_38 */
-			AM65X_IOPAD(0x0098, PIN_INPUT, 7)
-		>;
-	};
-
-	d6_gpio_pullup: d6-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (AH16) GPIO0_38 */
-			AM65X_IOPAD(0x0098, PIN_INPUT_PULLUP, 7)
-		>;
-	};
-
-	d6_gpio_pulldown: d6-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (AH16) GPIO0_38 */
-			AM65X_IOPAD(0x0098, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d7_ehrpwm3_a: d7-ehrpwm3-a-pins {
-		pinctrl-single,pins = <
-			/* (AH15) EHRPWM3_A */
-			AM65X_IOPAD(0x00AC, PIN_OUTPUT, 5)
-		>;
-	};
-
-	d7_gpio: d7-gpio-pins {
-		pinctrl-single,pins = <
-			/* (AH15) GPIO0_43 */
-			AM65X_IOPAD(0x00AC, PIN_INPUT, 7)
-		>;
-	};
-
-	d7_gpio_pullup: d7-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (AH15) GPIO0_43 */
-			AM65X_IOPAD(0x00AC, PIN_INPUT_PULLUP, 7)
-		>;
-	};
-
-	d7_gpio_pulldown: d7-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (AH15) GPIO0_43 */
-			AM65X_IOPAD(0x00AC, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d8_ehrpwm4_a: d8-ehrpwm4-a-pins {
-		pinctrl-single,pins = <
-			/* (AG15) EHRPWM4_A */
-			AM65X_IOPAD(0x00C0, PIN_OUTPUT, 5)
-		>;
-	};
-
-	d8_gpio: d8-gpio-pins {
-		pinctrl-single,pins = <
-			/* (AG15) GPIO0_48 */
-			AM65X_IOPAD(0x00C0, PIN_INPUT, 7)
-		>;
-	};
-
-	d8_gpio_pullup: d8-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (AG15) GPIO0_48 */
-			AM65X_IOPAD(0x00C0, PIN_INPUT_PULLUP, 7)
-		>;
-	};
-
-	d8_gpio_pulldown: d8-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (AG15) GPIO0_48 */
-			AM65X_IOPAD(0x00C0, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
-	d9_ehrpwm5_a: d9-ehrpwm5-a-pins {
-		pinctrl-single,pins = <
-			/* (AD15) EHRPWM5_A */
-			AM65X_IOPAD(0x00CC, PIN_OUTPUT, 5)
-		>;
-	};
-
-	d9_gpio: d9-gpio-pins {
-		pinctrl-single,pins = <
-			/* (AD15) GPIO0_51 */
-			AM65X_IOPAD(0x00CC, PIN_INPUT, 7)
-		>;
-	};
-
-	d9_gpio_pullup: d9-gpio-pullup-pins {
-		pinctrl-single,pins = <
-			/* (AD15) GPIO0_51 */
-			AM65X_IOPAD(0x00CC, PIN_INPUT_PULLUP, 7)
-		>;
-	};
-
-	d9_gpio_pulldown: d9-gpio-pulldown-pins {
-		pinctrl-single,pins = <
-			/* (AD15) GPIO0_51 */
-			AM65X_IOPAD(0x00CC, PIN_INPUT_PULLDOWN, 7)
-		>;
-	};
-
 	main_pcie_enable_pins_default: main-pcie-enable-default-pins {
 		pinctrl-single,pins = <
 			AM65X_IOPAD(0x01c4, PIN_INPUT_PULLUP, 7)  /* (AH13) GPIO1_17 */
@@ -1088,57 +429,11 @@ &main_uart1 {
 	pinctrl-0 = <&main_uart1_pins_default>;
 };
 
-&mcu_uart0 {
-	status = "okay";
-};
-
-&main_gpio0 {
-	gpio-line-names =
-		"main_gpio0-base", "", "", "", "", "", "", "", "", "",
-		"", "", "", "", "", "", "", "", "", "",
-		"", "", "", "", "", "", "", "", "", "",
-		"", "", "", "IO4", "", "IO5", "", "", "IO6", "",
-		"", "", "", "IO7", "", "", "", "", "IO8", "",
-		"", "IO9";
-};
-
 &main_gpio1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_pcie_enable_pins_default>;
 };
 
-&wkup_gpio0 {
-	pinctrl-names = "default";
-	pinctrl-0 =
-		<&arduino_i2c_aio_switch_pins_default>,
-		<&arduino_io_oe_pins_default>,
-		<&push_button_pins_default>,
-		<&db9_com_mode_pins_default>;
-	gpio-line-names =
-		/* 0..9 */
-		"wkup_gpio0-base", "", "", "", "UART0-mode1", "UART0-mode0",
-		"UART0-enable", "UART0-terminate", "", "WIFI-disable",
-		/* 10..19 */
-		"", "", "", "", "", "", "", "", "", "",
-		/* 20..29 */
-		"", "A4A5-I2C-mux", "", "", "", "USER-button", "", "", "","IO0",
-		/* 30..39 */
-		"IO1", "IO2", "", "IO3", "IO17-direction", "A5",
-		"IO16-direction", "IO15-direction", "IO14-direction", "A3",
-		/* 40..49 */
-		"", "IO18-direction", "A4", "A2", "A1", "A0", "", "", "IO13",
-		"IO11",
-		/* 50..51 */
-		"IO12", "IO10";
-};
-
-&wkup_i2c0 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&wkup_i2c0_pins_default>;
-	clock-frequency = <400000>;
-};
-
 &mcu_i2c0 {
 	status = "okay";
 	pinctrl-names = "default";
@@ -1156,47 +451,6 @@ psu: regulator at 60 {
 		ti,vsel1-state-high;
 		ti,enable-vout-discharge;
 	};
-
-	/* D4200 */
-	pcal9535_1: gpio at 20 {
-		compatible = "nxp,pcal9535";
-		reg = <0x20>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-line-names =
-			"A0-pull", "A1-pull", "A2-pull", "A3-pull", "A4-pull",
-			"A5-pull", "", "",
-			"IO14-enable", "IO15-enable", "IO16-enable",
-			"IO17-enable", "IO18-enable", "IO19-enable";
-	};
-
-	/* D4201 */
-	pcal9535_2: gpio at 21 {
-		compatible = "nxp,pcal9535";
-		reg = <0x21>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-line-names =
-			"IO0-direction", "IO1-direction", "IO2-direction",
-			"IO3-direction", "IO4-direction", "IO5-direction",
-			"IO6-direction", "IO7-direction",
-			"IO8-direction", "IO9-direction", "IO10-direction",
-			"IO11-direction", "IO12-direction", "IO13-direction",
-			"IO19-direction";
-	};
-
-	/* D4202 */
-	pcal9535_3: gpio at 25 {
-		compatible = "nxp,pcal9535";
-		reg = <0x25>;
-		#gpio-cells = <2>;
-		gpio-controller;
-		gpio-line-names =
-			"IO0-pull", "IO1-pull", "IO2-pull", "IO3-pull",
-			"IO4-pull", "IO5-pull", "IO6-pull", "IO7-pull",
-			"IO8-pull", "IO9-pull", "IO10-pull", "IO11-pull",
-			"IO12-pull", "IO13-pull";
-	};
 };
 
 &main_i2c0 {
@@ -1298,13 +552,6 @@ &mcu_spi0 {
 	ti,pindir-d0-out-d1-in;
 };
 
-&tscadc1 {
-	status = "okay";
-	adc {
-		ti,adc-channels = <0 1 2 3 4 5>;
-	};
-};
-
 &ospi0 {
 	status = "okay";
 	pinctrl-names = "default";
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 3bb6bcb0a5d3..da0a34425c4d 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
@@ -11,6 +11,7 @@
 
 #include "k3-am652.dtsi"
 #include "k3-am65-iot2050-common.dtsi"
+#include "k3-am65-iot2050-arduino-connector.dtsi"
 
 / {
 	memory at 80000000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
index 1e5d4d98b69b..2401cbe2b66c 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
@@ -15,6 +15,7 @@
 
 #include "k3-am6548-iot2050-advanced-common.dtsi"
 #include "k3-am65-iot2050-common-pg2.dtsi"
+#include "k3-am65-iot2050-arduino-connector.dtsi"
 
 / {
 	compatible = "siemens,iot2050-advanced-m2", "ti,am654";
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
index a8ce8c891894..c1205feef54e 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
@@ -17,6 +17,7 @@
 
 #include "k3-am6548-iot2050-advanced-common.dtsi"
 #include "k3-am65-iot2050-common-pg2.dtsi"
+#include "k3-am65-iot2050-arduino-connector.dtsi"
 
 / {
 	compatible = "siemens,iot2050-advanced-pg2", "ti,am654";
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts
index 077f165bdc68..b66965f992b9 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts
@@ -17,6 +17,7 @@
 
 #include "k3-am6548-iot2050-advanced-common.dtsi"
 #include "k3-am65-iot2050-common-pg1.dtsi"
+#include "k3-am65-iot2050-arduino-connector.dtsi"
 
 / {
 	compatible = "siemens,iot2050-advanced", "ti,am654";
-- 
2.35.3



From zajec5 at gmail.com  Thu Feb  8 23:24:56 2024
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Fri, 9 Feb 2024 08:24:56 +0100
Subject: [PATCH] dt-bindings: media: convert Mediatek consumer IR to the
 json-schema
In-Reply-To: <62fca33c-eb1a-42ad-b7f7-31b14f0aa446@collabora.com>
References: <20240124095230.25704-1-zajec5@gmail.com>
 <62fca33c-eb1a-42ad-b7f7-31b14f0aa446@collabora.com>
Message-ID: <6012ec99-4246-41b6-adb2-1bcd4dd159ac@gmail.com>

On 24.01.2024 13:33, AngeloGioacchino Del Regno wrote:
> The driver says:
> 
>  ????ir->bus = devm_clk_get(dev, "bus");
>  ????if (IS_ERR(ir->bus)) {
>  ??????? /*
>  ???????? * For compatibility with older device trees try unnamed
>  ???????? * ir->bus uses the same clock as ir->clock.
>  ???????? */
>  ??????? ir->bus = ir->clk;
>  ????}
> 
> This makes me think that requiring *one* clock on MT7623 would be a mistake
> and the devicetree should use clk, bus - CLK_INFRA_IRRX_PD, CLK_TOP_F10M_REF_SEL.

Looking at mt2701-clk.h I can see CLK_INFRA_IRRX (which I guess you
meant above).

I can't find CLK_TOP_F10M_REF_SEL however. This seems to be available on
MT7622 and MT7629 only.
Could you take another look at it, please? Can you somehow verify what
clock should be used by IR on MT7623?


From krzysztof.kozlowski at linaro.org  Thu Feb  8 23:29:31 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 09 Feb 2024 08:29:31 +0100
Subject: [PATCH] arm64: dts: exynos: gs101: minor whitespace cleanup
In-Reply-To: <20240208105243.128875-1-krzysztof.kozlowski@linaro.org>
References: <20240208105243.128875-1-krzysztof.kozlowski@linaro.org>
Message-ID: <170746377133.4997.4404186295778440756.b4-ty@linaro.org>


On Thu, 08 Feb 2024 11:52:43 +0100, Krzysztof Kozlowski wrote:
> The DTS code coding style expects exactly one space before '{' and
> around '=' characters.
> 
> 

Applied, thanks!

[1/1] arm64: dts: exynos: gs101: minor whitespace cleanup
      https://git.kernel.org/krzk/linux/c/28fafd554d233ef2344ee4a8709175b69bc93787

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Thu Feb  8 23:29:32 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 09 Feb 2024 08:29:32 +0100
Subject: [PATCH v2] arm64: dts: fsd: Add fifosize for UART in Device
 Tree
In-Reply-To: <20240205082625.39259-1-m.shams@samsung.com>
References: <CGME20240205082631epcas5p170b45d20431bfe0b9410caf470216e92@epcas5p1.samsung.com>
 <20240205082625.39259-1-m.shams@samsung.com>
Message-ID: <170746377270.4997.2411756438071063883.b4-ty@linaro.org>


On Mon, 05 Feb 2024 13:56:25 +0530, Tamseel Shams wrote:
> UART in FSD SoC has fifosize of 64 bytes.
> Set fifosize as 64 bytes for UART from Device Tree.
> 
> 

Applied, thanks!

[1/1] arm64: dts: fsd: Add fifosize for UART in Device Tree
      https://git.kernel.org/krzk/linux/c/3197329072f0ed2b1272af98ad4299a290036f65

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From thomas.richard at bootlin.com  Thu Feb  8 23:44:39 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Fri, 9 Feb 2024 08:44:39 +0100
Subject: [PATCH 01/14] gpio: pca953x: move suspend/resume to
 suspend_noirq/resume_noirq
In-Reply-To: <CACRpkdY2wiw1zH8FsEv7S1FW044PBSXpLPqanF5yyH1R4oteEA@mail.gmail.com>
References: <20240102-j7200-pcie-s2r-v1-0-84e55da52400@bootlin.com>
 <20240102-j7200-pcie-s2r-v1-1-84e55da52400@bootlin.com>
 <20240116074333.GO5185@atomide.com>
 <31c42f08-7d5e-4b91-87e9-bfc7e2cfdefe@bootlin.com>
 <CACRpkdYUVbFoDq91uLbUy8twtG_AiD+CY2+nqzCyHV7ZyBC3sA@mail.gmail.com>
 <95032042-787e-494a-bad9-81b62653de52@bootlin.com>
 <CACRpkdY2wiw1zH8FsEv7S1FW044PBSXpLPqanF5yyH1R4oteEA@mail.gmail.com>
Message-ID: <68d4a1bb-5b40-47fe-a117-647d77009b43@bootlin.com>

On 2/8/24 22:29, Linus Walleij wrote:
> On Thu, Feb 8, 2024 at 5:19?PM Thomas Richard
> <thomas.richard at bootlin.com> wrote:
>> On 1/28/24 01:12, Linus Walleij wrote:
> 
>>> I guess you could define both pca953x_suspend() and
>>> pca953x_suspend_noirq() and selectively bail out on one
>>> path on some systems?
>>
>> Yes.
>>
>> What do you think if I use a property like for example "ti,pm-noirq" to
>> select the right path ?
>> Is a property relevant for this use case ?
> 
> That's a Linux-specific property and that's useless for other operating
> systems and not normally allowed. PM noirq is just some Linux thing.
> 
> *FIRST* we should check if putting the callbacks to noirq is fine with
> other systems too, and I don't see why not. Perhaps we need to even
> merge it if we don't get any test results.
> 
> If it doesn't work we can think of other options.

I think all systems using a i2c controller which uses autosuspend should
be impacted.
I guess a patch (like I did in this series for i2c-omap [1]) should be
applied for all i2c controller which use autosuspend.

[1]
https://lore.kernel.org/all/hqnxyffdsiqz5t43bexcqrwmynpjubxbzjchjaagxecso75dc7 at y7lznovxg3go/

Regards,

-- 
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From krzysztof.kozlowski at linaro.org  Thu Feb  8 23:49:00 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 9 Feb 2024 08:49:00 +0100
Subject: [PATCH V2 1/3] dt-bindings: arm: mediatek: convert hifsys to the
 json-schema clock
In-Reply-To: <20240208215926.10085-2-zajec5@gmail.com>
References: <20240208215926.10085-1-zajec5@gmail.com>
 <20240208215926.10085-2-zajec5@gmail.com>
Message-ID: <7311143a-ea03-4619-99a5-05307704a561@linaro.org>

On 08/02/2024 22:59, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files. Introduced changes:
> 1. Documented "reg" property
> 2. Documented "#reset-cells" property
> 3. Dropped "syscon" as it was incorrectly used
> 4. Adjusted "compatible" and "reg" in example
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
>  .../clock/mediatek,mt2701-hifsys.yaml         | 51 +++++++++++++++++++
>  2 files changed, 51 insertions(+), 26 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
> deleted file mode 100644
> index 323905af82c3..000000000000
> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
> +++ /dev/null
> @@ -1,26 +0,0 @@
> -Mediatek hifsys controller
> -============================
> -
> -The Mediatek hifsys controller provides various clocks and reset
> -outputs to the system.
> -
> -Required Properties:
> -
> -- compatible: Should be:
> -	- "mediatek,mt2701-hifsys", "syscon"
> -	- "mediatek,mt7622-hifsys", "syscon"
> -	- "mediatek,mt7623-hifsys", "mediatek,mt2701-hifsys", "syscon"
> -- #clock-cells: Must be 1
> -
> -The hifsys controller uses the common clk binding from
> -Documentation/devicetree/bindings/clock/clock-bindings.txt
> -The available clocks are defined in dt-bindings/clock/mt*-clk.h.
> -
> -Example:
> -
> -hifsys: clock-controller at 1a000000 {
> -	compatible = "mediatek,mt2701-hifsys", "syscon";
> -	reg = <0 0x1a000000 0 0x1000>;
> -	#clock-cells = <1>;
> -	#reset-cells = <1>;
> -};
> diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
> new file mode 100644
> index 000000000000..eb429337cdf4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/mediatek,mt2701-hifsys.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek hifsys controller
> +
> +description:
> +  The Mediatek hifsys controller provides various clocks and reset outputs to
> +  the system.
> +
> +maintainers:
> +  - Matthias Brugger <matthias.bgg at gmail.com>
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:

If there is going to be resend, drop items here, it's just an enum.

Anyway:

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb  8 23:49:48 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 9 Feb 2024 08:49:48 +0100
Subject: [PATCH V2 2/3] dt-bindings: arm: mediatek: convert PCIESYS to the
 json-schema clock
In-Reply-To: <20240208215926.10085-3-zajec5@gmail.com>
References: <20240208215926.10085-1-zajec5@gmail.com>
 <20240208215926.10085-3-zajec5@gmail.com>
Message-ID: <40d5bb84-a65a-4ac3-a17c-062ad4b8ea4a@linaro.org>

On 08/02/2024 22:59, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files. Introduced changes:
> 1. Documented "reg" property
> 2. Dropped "syscon" as it was incorrectly used
> 3. Adjusted nodename, "compatible" and "reg" in example
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb  8 23:50:22 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 9 Feb 2024 08:50:22 +0100
Subject: [PATCH V2 3/3] dt-bindings: arm: mediatek: convert SSUSBSYS to
 the json-schema clock
In-Reply-To: <20240208215926.10085-4-zajec5@gmail.com>
References: <20240208215926.10085-1-zajec5@gmail.com>
 <20240208215926.10085-4-zajec5@gmail.com>
Message-ID: <3746a7ff-0b27-47f1-b4e8-cb33f6cac12f@linaro.org>

On 08/02/2024 22:59, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files. Introduced changes:
> 1. Documented "reg" property
> 2. Dropped "syscon" as it was incorrectly used
> 3. Adjusted nodename, "compatible" and "reg" in example
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From lee at kernel.org  Thu Feb  8 23:56:24 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 9 Feb 2024 07:56:24 +0000
Subject: [PATCH 6/6] mfd: tmio: move header to platform_data
In-Reply-To: <20240209015817.14627-14-wsa+renesas@sang-engineering.com>
References: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
 <20240209015817.14627-14-wsa+renesas@sang-engineering.com>
Message-ID: <20240209075624.GG689448@google.com>

On Fri, 09 Feb 2024, Wolfram Sang wrote:

> All the MFD components are gone from the header meanwhile. Only the MMC
> relevant data is left which makes it a platform_data for the MMC
> controller. Move the header to the now fitting directory.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
> ---
>  MAINTAINERS                                   | 2 +-
>  arch/sh/boards/board-sh7757lcr.c              | 2 +-
>  arch/sh/boards/mach-ap325rxa/setup.c          | 2 +-
>  arch/sh/boards/mach-ecovec24/setup.c          | 2 +-
>  arch/sh/boards/mach-kfr2r09/setup.c           | 2 +-
>  arch/sh/boards/mach-migor/setup.c             | 2 +-
>  arch/sh/boards/mach-se/7724/setup.c           | 2 +-
>  drivers/mmc/host/renesas_sdhi_core.c          | 2 +-
>  drivers/mmc/host/renesas_sdhi_internal_dmac.c | 2 +-
>  drivers/mmc/host/renesas_sdhi_sys_dmac.c      | 2 +-
>  drivers/mmc/host/tmio_mmc_core.c              | 2 +-
>  drivers/mmc/host/uniphier-sd.c                | 2 +-
>  include/linux/{mfd => platform_data}/tmio.h   | 0
>  13 files changed, 12 insertions(+), 12 deletions(-)
>  rename include/linux/{mfd => platform_data}/tmio.h (100%)

Acked-by: Lee Jones <lee at kernel.org>

> diff --git a/MAINTAINERS b/MAINTAINERS
> index 960512bec428..c4e20abd177b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -22154,7 +22154,7 @@ L:	linux-renesas-soc at vger.kernel.org
>  S:	Supported
>  F:	drivers/mmc/host/renesas_sdhi*
>  F:	drivers/mmc/host/tmio_mmc*
> -F:	include/linux/mfd/tmio.h
> +F:	include/linux/platform_data/tmio.h
>  
>  TMP401 HARDWARE MONITOR DRIVER
>  M:	Guenter Roeck <linux at roeck-us.net>
> diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
> index f39c8196efdf..4014c042d2a5 100644
> --- a/arch/sh/boards/board-sh7757lcr.c
> +++ b/arch/sh/boards/board-sh7757lcr.c
> @@ -14,9 +14,9 @@
>  #include <linux/spi/spi.h>
>  #include <linux/spi/flash.h>
>  #include <linux/io.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/platform_data/sh_mmcif.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/sh_eth.h>
>  #include <linux/sh_intc.h>
>  #include <linux/usb/renesas_usbhs.h>
> diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
> index 645cccf3da88..bb5004a8ac02 100644
> --- a/arch/sh/boards/mach-ap325rxa/setup.c
> +++ b/arch/sh/boards/mach-ap325rxa/setup.c
> @@ -24,10 +24,10 @@
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
>  #include <linux/memblock.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mtd/physmap.h>
>  #include <linux/mtd/sh_flctl.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/fixed.h>
>  #include <linux/regulator/machine.h>
> diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
> index 30d117f9ad7e..6f13557eecd6 100644
> --- a/arch/sh/boards/mach-ecovec24/setup.c
> +++ b/arch/sh/boards/mach-ecovec24/setup.c
> @@ -17,13 +17,13 @@
>  #include <linux/input/sh_keysc.h>
>  #include <linux/interrupt.h>
>  #include <linux/memblock.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/platform_data/sh_mmcif.h>
>  #include <linux/mtd/physmap.h>
>  #include <linux/gpio.h>
>  #include <linux/gpio/machine.h>
>  #include <linux/platform_data/gpio_backlight.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_data/tsc2007.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/fixed.h>
> diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
> index 6b775eae85c0..70236859919d 100644
> --- a/arch/sh/boards/mach-kfr2r09/setup.c
> +++ b/arch/sh/boards/mach-kfr2r09/setup.c
> @@ -22,10 +22,10 @@
>  #include <linux/input/sh_keysc.h>
>  #include <linux/interrupt.h>
>  #include <linux/memblock.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mtd/physmap.h>
>  #include <linux/platform_data/lv5207lp.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/fixed.h>
>  #include <linux/regulator/machine.h>
> diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
> index 773ee767d0c4..1853e6319a66 100644
> --- a/arch/sh/boards/mach-migor/setup.c
> +++ b/arch/sh/boards/mach-migor/setup.c
> @@ -7,6 +7,7 @@
>  #include <linux/clkdev.h>
>  #include <linux/dma-map-ops.h>
>  #include <linux/init.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/interrupt.h>
>  #include <linux/input.h>
> @@ -14,7 +15,6 @@
>  #include <linux/memblock.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mtd/physmap.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mtd/platnand.h>
>  #include <linux/i2c.h>
>  #include <linux/regulator/fixed.h>
> diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
> index 787ddd3c627a..e500feb91053 100644
> --- a/arch/sh/boards/mach-se/7724/setup.c
> +++ b/arch/sh/boards/mach-se/7724/setup.c
> @@ -21,9 +21,9 @@
>  #include <linux/input/sh_keysc.h>
>  #include <linux/interrupt.h>
>  #include <linux/memblock.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mtd/physmap.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/fixed.h>
>  #include <linux/regulator/machine.h>
> diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
> index c675dec587ef..f84f60139bcf 100644
> --- a/drivers/mmc/host/renesas_sdhi_core.c
> +++ b/drivers/mmc/host/renesas_sdhi_core.c
> @@ -22,13 +22,13 @@
>  #include <linux/delay.h>
>  #include <linux/iopoll.h>
>  #include <linux/kernel.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mmc/mmc.h>
>  #include <linux/mmc/slot-gpio.h>
>  #include <linux/module.h>
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/pinctrl/pinctrl-state.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_domain.h>
>  #include <linux/regulator/consumer.h>
> diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> index 24e1c17908d7..97cd55fec0bf 100644
> --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> @@ -11,12 +11,12 @@
>  #include <linux/device.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/io-64-nonatomic-hi-lo.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/pagemap.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/scatterlist.h>
> diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> index c18581897f8a..68e31c37cce6 100644
> --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> @@ -11,12 +11,12 @@
>  #include <linux/device.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/dmaengine.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/pagemap.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/scatterlist.h>
> diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
> index c39141a5bd23..0c4397b3cffd 100644
> --- a/drivers/mmc/host/tmio_mmc_core.c
> +++ b/drivers/mmc/host/tmio_mmc_core.c
> @@ -31,7 +31,6 @@
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/irq.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/card.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mmc/mmc.h>
> @@ -39,6 +38,7 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/pagemap.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_qos.h>
>  #include <linux/pm_runtime.h>
> diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c
> index 1404989e6151..bd231dbe90ba 100644
> --- a/drivers/mmc/host/uniphier-sd.c
> +++ b/drivers/mmc/host/uniphier-sd.c
> @@ -9,11 +9,11 @@
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/mfd/syscon.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/pinctrl/consumer.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/regmap.h>
>  #include <linux/reset.h>
> diff --git a/include/linux/mfd/tmio.h b/include/linux/platform_data/tmio.h
> similarity index 100%
> rename from include/linux/mfd/tmio.h
> rename to include/linux/platform_data/tmio.h
> -- 
> 2.43.0
> 

-- 
Lee Jones [???]


From lee at kernel.org  Thu Feb  8 23:58:39 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 9 Feb 2024 07:58:39 +0000
Subject: [PATCH 0/6] mfd: tmio: simplify header and move to platform_data
In-Reply-To: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
References: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
Message-ID: <20240209075839.GH689448@google.com>

On Fri, 09 Feb 2024, Wolfram Sang wrote:

> The MFD parts of the TMIO have been removed by Arnd, so that only the
> SD/MMC related functionality is left. Remove the outdated remains in the
> public header file and then move it to platform_data as the data is now
> specific for the SD/MMC part.
> 
> Based on 6.8-rc3, build bot is happy. Branch is here:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/sdhi/tmio-simplification
> 
> I'd suggest this goes via the MFD tree, so the series would need acks
> from the MMC and SH maintainers. Is that okay with everyone?
> 
> All the best!
> 
>    Wolfram

Could you please change all of the subject lines with "mfd" in them
i.e. all of the commits which touch include/linux/mfd and ensure the
description starts with an upper case char?

I like all commits that touch drivers/mfd and include/linux/mfd to have
the same formatting structure.

Thanks.

> Wolfram Sang (6):
>   mfd: tmio: remove obsolete platform_data
>   mfd: tmio: remove obsolete io accessors
>   mmc: tmio/sdhi: fix includes
>   mfd: tmio: update include files
>   mfd: tmio: sanitize comments
>   mfd: tmio: move header to platform_data
> 
>  MAINTAINERS                                   |   2 +-
>  arch/sh/boards/board-sh7757lcr.c              |   2 +-
>  arch/sh/boards/mach-ap325rxa/setup.c          |   2 +-
>  arch/sh/boards/mach-ecovec24/setup.c          |   2 +-
>  arch/sh/boards/mach-kfr2r09/setup.c           |   2 +-
>  arch/sh/boards/mach-migor/setup.c             |   2 +-
>  arch/sh/boards/mach-se/7724/setup.c           |   2 +-
>  drivers/mmc/host/renesas_sdhi_core.c          |   2 +-
>  drivers/mmc/host/renesas_sdhi_internal_dmac.c |   5 +-
>  drivers/mmc/host/renesas_sdhi_sys_dmac.c      |   5 +-
>  drivers/mmc/host/tmio_mmc_core.c              |   3 +-
>  drivers/mmc/host/uniphier-sd.c                |   2 +-
>  include/linux/mfd/tmio.h                      | 133 ------------------
>  include/linux/platform_data/tmio.h            |  64 +++++++++
>  14 files changed, 81 insertions(+), 147 deletions(-)
>  delete mode 100644 include/linux/mfd/tmio.h
>  create mode 100644 include/linux/platform_data/tmio.h
> 
> -- 
> 2.43.0
> 

-- 
Lee Jones [???]


From adrian.hunter at intel.com  Fri Feb  9 00:14:44 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Fri, 9 Feb 2024 10:14:44 +0200
Subject: [PATCH V5 01/12] perf/core: Add aux_pause, aux_resume,
 aux_start_paused
In-Reply-To: <ZcVuK1nnxG18ps-a@tassilo>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
 <20240208113127.22216-2-adrian.hunter@intel.com> <ZcVuK1nnxG18ps-a@tassilo>
Message-ID: <d53ef26d-a7e6-4b3b-b593-be75425c0e77@intel.com>

On 9/02/24 02:13, Andi Kleen wrote:
>> +static void __perf_event_aux_pause(struct perf_event *event, bool pause)
>> +{
>> +	if (pause) {
>> +		if (!READ_ONCE(event->aux_paused)) {
>> +			WRITE_ONCE(event->aux_paused, 1);
>> +			event->pmu->stop(event, PERF_EF_PAUSE);
>> +		}
>> +	} else {
>> +		if (READ_ONCE(event->aux_paused)) {
>> +			WRITE_ONCE(event->aux_paused, 0);
>> +			event->pmu->start(event, PERF_EF_RESUME);
>> +		}
> 
> This doesn't look atomic. Either the READ/WRITE once are not needed,
> or you need an actually atomic construct.

Yes READ_ONCE / WRITE_ONCE is not really needed here.

> 
>> +
>> +	rb = ring_buffer_get(event);
>> +	if (!rb)
>> +		return;
>> +
>> +	local_irq_save(flags);
>> +	/* Guard against NMI, NMI loses here */
>> +	if (READ_ONCE(rb->aux_in_pause_resume))
>> +		goto out_restore;
>> +	WRITE_ONCE(rb->aux_in_pause_resume, 1);
> 
> 
>> +	barrier();
>> +	__perf_event_aux_pause(event, pause);
>> +	barrier();
>> +	WRITE_ONCE(rb->aux_in_pause_resume, 0);
> 
> Dito.
> 

The writes to rb->aux_in_pause_resume must be done
only once.  It might be possible to get away without
WRITE_ONCE(), but really the compiler should be informed
not to make assumptions.



From a-bhatia1 at ti.com  Fri Feb  9 00:27:43 2024
From: a-bhatia1 at ti.com (Aradhya Bhatia)
Date: Fri, 9 Feb 2024 13:57:43 +0530
Subject: [PATCH v2 1/3] arm64: dts: ti: am65x: Fix dtbs_install for
 Rocktech OLDI overlay
In-Reply-To: <20240208-for-v6-9-am65-overlays-2-0-v2-1-70bae3e91597@kernel.org>
References: <20240208-for-v6-9-am65-overlays-2-0-v2-0-70bae3e91597@kernel.org>
 <20240208-for-v6-9-am65-overlays-2-0-v2-1-70bae3e91597@kernel.org>
Message-ID: <f3548adc-4256-4b05-b072-631133bda4da@ti.com>



On 08-Feb-24 19:21, Roger Quadros wrote:
> Add the overlay dtbo file to a Makefile target so it can be
> picked by the dtbs_install command.
> 
> Fixes: b8690ed3d1d1 ("arm64: dts: ti: am65x: Add Rocktech OLDI panel DT overlay")
> Signed-off-by: Roger Quadros <rogerq at kernel.org>

Reviewed-by: Aradhya Bhatia <a-bhatia1 at ti.com>

Regards
Aradhya

> ---
> Changelog:
> 
> v2: no change
> v1: https://lore.kernel.org/all/20240126114530.40913-2-rogerq at kernel.org/
> ---
>  arch/arm64/boot/dts/ti/Makefile | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
> index 4a570dffb638..bfcc86ff8e24 100644
> --- a/arch/arm64/boot/dts/ti/Makefile
> +++ b/arch/arm64/boot/dts/ti/Makefile
> @@ -57,6 +57,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb
>  dtb-$(CONFIG_ARCH_K3) += k3-am654-gp-evm.dtb
>  dtb-$(CONFIG_ARCH_K3) += k3-am654-evm.dtb
>  dtb-$(CONFIG_ARCH_K3) += k3-am654-idk.dtb
> +dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board-rocktech-rk101-panel.dtbo
>  
>  # Boards with J7200 SoC
>  k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo
> 


From angelogioacchino.delregno at collabora.com  Fri Feb  9 00:40:16 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 9 Feb 2024 09:40:16 +0100
Subject: [PATCH] dt-bindings: media: convert Mediatek consumer IR to the
 json-schema
In-Reply-To: <6012ec99-4246-41b6-adb2-1bcd4dd159ac@gmail.com>
References: <20240124095230.25704-1-zajec5@gmail.com>
 <62fca33c-eb1a-42ad-b7f7-31b14f0aa446@collabora.com>
 <6012ec99-4246-41b6-adb2-1bcd4dd159ac@gmail.com>
Message-ID: <023a1706-f6ca-481e-8a95-bc9e0e7e46ad@collabora.com>

Il 09/02/24 08:24, Rafa? Mi?ecki ha scritto:
> On 24.01.2024 13:33, AngeloGioacchino Del Regno wrote:
>> The driver says:
>>
>> ?????ir->bus = devm_clk_get(dev, "bus");
>> ?????if (IS_ERR(ir->bus)) {
>> ???????? /*
>> ????????? * For compatibility with older device trees try unnamed
>> ????????? * ir->bus uses the same clock as ir->clock.
>> ????????? */
>> ???????? ir->bus = ir->clk;
>> ?????}
>>
>> This makes me think that requiring *one* clock on MT7623 would be a mistake
>> and the devicetree should use clk, bus - CLK_INFRA_IRRX_PD, CLK_TOP_F10M_REF_SEL.
> 
> Looking at mt2701-clk.h I can see CLK_INFRA_IRRX (which I guess you
> meant above).
> 
> I can't find CLK_TOP_F10M_REF_SEL however. This seems to be available on
> MT7622 and MT7629 only.
> Could you take another look at it, please? Can you somehow verify what
> clock should be used by IR on MT7623?

For MT2701/MT7623N you can use topckgen CLK_TOP_AXI_SEL as bus clock.

Cheers,
Angelo


From krzysztof.kozlowski at linaro.org  Fri Feb  9 00:40:44 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 9 Feb 2024 09:40:44 +0100
Subject: [PATCH V2] dt-bindings: thermal: mediatek,thermal: document
 AUXADC 32k clock
In-Reply-To: <20240209055203.17144-1-zajec5@gmail.com>
References: <20240209055203.17144-1-zajec5@gmail.com>
Message-ID: <6a4f516e-dd86-4a88-ada1-89b1dbac0560@linaro.org>

On 09/02/2024 06:52, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> SoCs MT7981 and MT7986 include a newer thermal block (V3) that requires
> enabling one more clock called AUXADC 32k. Require it in binding.
> 
> Cc: Daniel Golle <daniel at makrotopia.org>
> Cc: Sam Shih <sam.shih at mediatek.com>


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From eichest at gmail.com  Fri Feb  9 00:45:41 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Fri,  9 Feb 2024 09:45:41 +0100
Subject: [PATCH v3 0/2] Add a property to turn off the max touch controller in suspend mode
Message-ID: <20240209084543.14726-1-eichest@gmail.com>

Our hardware has a shared regulator that powers various peripherals such
as the display, touch, USB hub, etc. Since the Maxtouch controller
doesn't currently allow it to be turned off, this regulator has to stay
on in suspend mode. This increases the overall power consumption. In
order to turn off the controller when the system goes into suspend mode,
this series adds a device tree property to the maxtouch driver that
allows the controller to be turned off completely and ensurs that it can
resume from the power off state.

Changes since v2:
- Add Reviewed-by tags from Linus and Krzysztof to the dt-bindings patch

Changes since v1:
- Rename the property and change the description (Krzysztof, Linus,
Dmitry, Conor)

Stefan Eichenberger (2):
  dt-bindings: input: atmel,maxtouch: add poweroff-sleep property
  Input: atmel_mxt_ts - support poweroff in suspend

 .../bindings/input/atmel,maxtouch.yaml        |  6 ++
 drivers/input/touchscreen/atmel_mxt_ts.c      | 72 ++++++++++++++-----
 2 files changed, 61 insertions(+), 17 deletions(-)

-- 
2.40.1



From eichest at gmail.com  Fri Feb  9 00:45:42 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Fri,  9 Feb 2024 09:45:42 +0100
Subject: [PATCH v3 1/2] dt-bindings: input: atmel,maxtouch: add poweroff-sleep property
In-Reply-To: <20240209084543.14726-1-eichest@gmail.com>
References: <20240209084543.14726-1-eichest@gmail.com>
Message-ID: <20240209084543.14726-2-eichest@gmail.com>

From: Stefan Eichenberger <stefan.eichenberger at toradex.com>

Add a new property to indicate that the device should power off rather
than use deep sleep. Deep sleep is a feature of the controller that
expects the controller to remain powered in suspend. However, if a
display shares its regulator with the touch controller, we may want to
do a power off so that the display and touch controller do not use any
power.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger at toradex.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/input/atmel,maxtouch.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml b/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
index c40799355ed7..8de5f539b30e 100644
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
@@ -87,6 +87,12 @@ properties:
       - 2 # ATMEL_MXT_WAKEUP_GPIO
     default: 0
 
+  atmel,poweroff-sleep:
+    description: |
+      Instead of using the deep sleep feature of the maXTouch controller,
+      poweroff the regulators.
+    type: boolean
+
   wakeup-source:
     type: boolean
 
-- 
2.40.1



From krzysztof.kozlowski at linaro.org  Fri Feb  9 00:47:10 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 9 Feb 2024 09:47:10 +0100
Subject: [PATCH v2] dt-bindings: input: atmel,captouch: convert bindings
 to YAML
In-Reply-To: <20240209064755.47516-1-dharma.b@microchip.com>
References: <20240209064755.47516-1-dharma.b@microchip.com>
Message-ID: <f6f19f9f-b94a-4194-a5e5-b549471cf47e@linaro.org>

On 09/02/2024 07:47, Dharma Balasubiramani wrote:
> Convert the Atmel capacitive touchscreen bindings to YAML format.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> ---
> Changelog
> v1 -> v2
> - Drop autorepeat property.
> - Use unevaluatedProperties instead of additionalProperties.
> - Use node name "touch at 51" instead of "atmel-captouch at 51".


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From eichest at gmail.com  Fri Feb  9 00:48:18 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Fri,  9 Feb 2024 09:48:18 +0100
Subject: [PATCH v3 2/2] Input: atmel_mxt_ts - support poweroff in suspend
Message-ID: <20240209084818.14925-1-eichest@gmail.com>

From: Stefan Eichenberger <stefan.eichenberger at toradex.com>

Add a new device tree property to indicate that the device should be
powered off in suspend mode. We have a shared regulator that powers the
display, a USB hub and some other peripherals. The maXTouch controller
doesn't normally disable the regulator in suspend mode, so our extra
peripherals stay powered on. This is not desirable as it consumes more
power. With this patch we add the option to disable the regulator in
suspend mode for the maXTouch and accept the longer initialisation time.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger at toradex.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 72 ++++++++++++++++++------
 1 file changed, 55 insertions(+), 17 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 542a31448c8f..2d5655385702 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -317,6 +317,7 @@ struct mxt_data {
 	struct gpio_desc *reset_gpio;
 	struct gpio_desc *wake_gpio;
 	bool use_retrigen_workaround;
+	bool poweroff_sleep;
 
 	/* Cached parameters from object table */
 	u16 T5_address;
@@ -2799,15 +2800,18 @@ static int mxt_configure_objects(struct mxt_data *data,
 			dev_warn(dev, "Error %d updating config\n", error);
 	}
 
-	if (data->multitouch) {
-		error = mxt_initialize_input_device(data);
-		if (error)
-			return error;
-	} else {
-		dev_warn(dev, "No touch object detected\n");
-	}
+	/* If input device is not already registered */
+	if (!data->input_dev) {
+		if (data->multitouch) {
+			error = mxt_initialize_input_device(data);
+			if (error)
+				return error;
+		} else {
+			dev_warn(dev, "No touch object detected\n");
+		}
 
-	mxt_debug_init(data);
+		mxt_debug_init(data);
+	}
 
 	return 0;
 }
@@ -3325,6 +3329,8 @@ static int mxt_probe(struct i2c_client *client)
 		msleep(MXT_RESET_INVALID_CHG);
 	}
 
+	data->poweroff_sleep = device_property_read_bool(&client->dev,
+							 "atmel,poweroff-sleep");
 	/*
 	 * Controllers like mXT1386 have a dedicated WAKE line that could be
 	 * connected to a GPIO or to I2C SCL pin, or permanently asserted low.
@@ -3387,12 +3393,21 @@ static int mxt_suspend(struct device *dev)
 	if (!input_dev)
 		return 0;
 
-	mutex_lock(&input_dev->mutex);
+	if (!device_may_wakeup(dev) && data->poweroff_sleep) {
+		if (data->reset_gpio)
+			gpiod_set_value(data->reset_gpio, 1);
 
-	if (input_device_enabled(input_dev))
-		mxt_stop(data);
+		regulator_bulk_disable(ARRAY_SIZE(data->regulators),
+				data->regulators);
+		data->T44_address = 0;
+	} else {
+		mutex_lock(&input_dev->mutex);
+
+		if (input_device_enabled(input_dev))
+			mxt_stop(data);
 
-	mutex_unlock(&input_dev->mutex);
+		mutex_unlock(&input_dev->mutex);
+	}
 
 	disable_irq(data->irq);
 
@@ -3408,14 +3423,37 @@ static int mxt_resume(struct device *dev)
 	if (!input_dev)
 		return 0;
 
-	enable_irq(data->irq);
+	if (!device_may_wakeup(dev) && data->poweroff_sleep) {
+		int ret;
 
-	mutex_lock(&input_dev->mutex);
+		ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
+				data->regulators);
+		if (ret) {
+			dev_err(dev, "failed to enable regulators: %d\n",
+					ret);
+			return ret;
+		}
+		msleep(MXT_BACKUP_TIME);
 
-	if (input_device_enabled(input_dev))
-		mxt_start(data);
+		if (data->reset_gpio) {
+			/* Wait a while and then de-assert the RESET GPIO line */
+			msleep(MXT_RESET_GPIO_TIME);
+			gpiod_set_value(data->reset_gpio, 0);
+			msleep(MXT_RESET_INVALID_CHG);
+		}
 
-	mutex_unlock(&input_dev->mutex);
+		/* This also enables the irq again */
+		mxt_initialize(data);
+	} else {
+		enable_irq(data->irq);
+
+		mutex_lock(&input_dev->mutex);
+
+		if (input_device_enabled(input_dev))
+			mxt_start(data);
+
+		mutex_unlock(&input_dev->mutex);
+	}
 
 	return 0;
 }
-- 
2.40.1



From angelogioacchino.delregno at collabora.com  Fri Feb  9 00:53:06 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 9 Feb 2024 09:53:06 +0100
Subject: [PATCH V2 3/3] dt-bindings: arm: mediatek: convert SSUSBSYS to
 the json-schema clock
In-Reply-To: <20240208215926.10085-4-zajec5@gmail.com>
References: <20240208215926.10085-1-zajec5@gmail.com>
 <20240208215926.10085-4-zajec5@gmail.com>
Message-ID: <258f93ce-c927-451f-b9f0-7170c140eccb@collabora.com>

Il 08/02/24 22:59, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files. Introduced changes:
> 1. Documented "reg" property
> 2. Dropped "syscon" as it was incorrectly used
> 3. Adjusted nodename, "compatible" and "reg" in example
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Fri Feb  9 00:53:11 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 9 Feb 2024 09:53:11 +0100
Subject: [PATCH V2 2/3] dt-bindings: arm: mediatek: convert PCIESYS to the
 json-schema clock
In-Reply-To: <20240208215926.10085-3-zajec5@gmail.com>
References: <20240208215926.10085-1-zajec5@gmail.com>
 <20240208215926.10085-3-zajec5@gmail.com>
Message-ID: <c4bcd969-cd6f-4961-aac7-cd169da4bfeb@collabora.com>

Il 08/02/24 22:59, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files. Introduced changes:
> 1. Documented "reg" property
> 2. Dropped "syscon" as it was incorrectly used
> 3. Adjusted nodename, "compatible" and "reg" in example
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Fri Feb  9 00:53:18 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 9 Feb 2024 09:53:18 +0100
Subject: [PATCH V2 1/3] dt-bindings: arm: mediatek: convert hifsys to the
 json-schema clock
In-Reply-To: <20240208215926.10085-2-zajec5@gmail.com>
References: <20240208215926.10085-1-zajec5@gmail.com>
 <20240208215926.10085-2-zajec5@gmail.com>
Message-ID: <d4a4a468-4a81-413e-9de6-060c2ba9e0b6@collabora.com>

Il 08/02/24 22:59, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files. Introduced changes:
> 1. Documented "reg" property
> 2. Documented "#reset-cells" property
> 3. Dropped "syscon" as it was incorrectly used
> 4. Adjusted "compatible" and "reg" in example
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>   .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
>   .../clock/mediatek,mt2701-hifsys.yaml         | 51 +++++++++++++++++++
>   2 files changed, 51 insertions(+), 26 deletions(-)
>   delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
>   create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
> deleted file mode 100644
> index 323905af82c3..000000000000
> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
> +++ /dev/null
> @@ -1,26 +0,0 @@
> -Mediatek hifsys controller
> -============================
> -
> -The Mediatek hifsys controller provides various clocks and reset
> -outputs to the system.
> -
> -Required Properties:
> -
> -- compatible: Should be:
> -	- "mediatek,mt2701-hifsys", "syscon"
> -	- "mediatek,mt7622-hifsys", "syscon"
> -	- "mediatek,mt7623-hifsys", "mediatek,mt2701-hifsys", "syscon"
> -- #clock-cells: Must be 1
> -
> -The hifsys controller uses the common clk binding from
> -Documentation/devicetree/bindings/clock/clock-bindings.txt
> -The available clocks are defined in dt-bindings/clock/mt*-clk.h.
> -
> -Example:
> -
> -hifsys: clock-controller at 1a000000 {
> -	compatible = "mediatek,mt2701-hifsys", "syscon";
> -	reg = <0 0x1a000000 0 0x1000>;
> -	#clock-cells = <1>;
> -	#reset-cells = <1>;
> -};
> diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
> new file mode 100644
> index 000000000000..eb429337cdf4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/mediatek,mt2701-hifsys.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek hifsys controller

Please, "MediaTek HIFSYS controller"

> +
> +description:
> +  The Mediatek hifsys controller provides various clocks and reset outputs to
> +  the system.

Same here, "The MediaTek HIFSYS controller..."

Anyway, apart from that

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Cheers!


From ryan.roberts at arm.com  Fri Feb  9 00:54:34 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri, 9 Feb 2024 08:54:34 +0000
Subject: [PATCH v5 00/25] Transparent Contiguous PTEs for User Mappings
In-Reply-To: <ZcUQqfg39zCS2BAv@FVFF77S0Q05N.cambridge.arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <ZcUQqfg39zCS2BAv@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <3ba54c94-8e44-4dd6-9a25-2cf81b07336f@arm.com>

On 08/02/2024 17:34, Mark Rutland wrote:
> On Fri, Feb 02, 2024 at 08:07:31AM +0000, Ryan Roberts wrote:
>> Hi All,
> 
> Hi Ryan,
> 
> I assume this is the same as your 'features/granule_perf/contpte-lkml_v' branch
> on https://gitlab.arm.com/linux-arm/linux-rr/

Yep - great detective work! features/granule_perf/contpte-lkml_v5 corresponds
exactly to what I posted with all the dependencies in place.

> 
> I've taken a quick look, and I have a few initial/superficial comments before
> digging into the detail on the important changes.

Thanks for doing this!

> 
>> Patch Layout
>> ============
>>
>> In this version, I've split the patches to better show each optimization:
>>
>>   - 1-2:    mm prep: misc code and docs cleanups
> 
> I'm not confident enough to comment on patch 2, but these look reasonable to
> me.

Thanks. David has acked patch 2 already so I think we are good there.

> 
>>   - 3-8:    mm,arm,arm64,powerpc,x86 prep: Replace pte_next_pfn() with more
>>             general pte_advance_pfn()
> 
> These look fine to me.

Thanks!

> 
>>   - 9-18:   arm64 prep: Refactor ptep helpers into new layer
> 
> The result of patches 9-17 looks good to me, but the intermediate stages where
> some functions are converted is a bit odd, and it's a bit painful for review
> since you need to skip ahead a few patches to see the end result to tell that
> the conversions are consistent and complete.
> 
> IMO it'd be easier for review if that were three patches:
> 
> 1) Convert READ_ONCE() -> ptep_get()
> 2) Convert set_pte_at() -> set_ptes()
> 3) All the "New layer" renames and addition of the trivial wrappers

Yep that makes sense. I'll start prepping that today. I'll hold off reposting
until I have your comments on 19-25. I'm also hoping that David will repost the
zap series today so that it can get into mm-unstable by mid-next week. Then I'll
repost on top of that, hopefully by end of next week, folding in all your
comments. This should give planty of time to soak in linux-next.

Thanks,
Ryan

> 
> Patch 18 looks fine to me.
> 
>>   - 19:     functional contpte implementation
>>   - 20-25:  various optimizations on top of the contpte implementation
> 
> I'll try to dig into these over the next few days.
> 
> Mark.



From angelogioacchino.delregno at collabora.com  Fri Feb  9 00:54:53 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 9 Feb 2024 09:54:53 +0100
Subject: [PATCH v3 11/19] power: reset: mt6323-poweroff: Use
 devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240208170410.67975-12-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
 <20240208170410.67975-12-afd@ti.com>
Message-ID: <90e0e76c-7bc9-4aa3-8d5e-4fe96c2687e4@collabora.com>

Il 08/02/24 18:04, Andrew Davis ha scritto:
> Use device life-cycle managed register function to simplify probe and
> exit paths.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From zajec5 at gmail.com  Fri Feb  9 00:56:16 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri,  9 Feb 2024 09:56:16 +0100
Subject: [PATCH V2] dt-bindings: media: convert Mediatek consumer IR to the json-schema
Message-ID: <20240209085616.1062-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Reworded title
2. Made "bus" clock required on MT7623 as well
3. Added required #include-s and adjusted "reg" & clocks in example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Extended "IR" in title
    Made "bus" required at MT7623 needs it as well
    Updated example

Thanks AngeloGioacchino!

 .../bindings/media/mediatek,mt7622-cir.yaml   | 55 +++++++++++++++++++
 .../devicetree/bindings/media/mtk-cir.txt     | 28 ----------
 2 files changed, 55 insertions(+), 28 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mt7622-cir.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mtk-cir.txt

diff --git a/Documentation/devicetree/bindings/media/mediatek,mt7622-cir.yaml b/Documentation/devicetree/bindings/media/mediatek,mt7622-cir.yaml
new file mode 100644
index 000000000000..c01210e053f9
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mt7622-cir.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,mt7622-cir.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Consumer Infrared Receiver on-SoC Controller
+
+maintainers:
+  - Sean Wang <sean.wang at mediatek.com>
+
+allOf:
+  - $ref: rc.yaml#
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7622-cir
+      - mediatek,mt7623-cir
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: clk
+      - const: bus
+
+required:
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt2701-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    ir at 10013000 {
+        compatible = "mediatek,mt7623-cir";
+        reg = <0x10013000 0x1000>;
+        interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_LOW>;
+        clocks = <&infracfg CLK_INFRA_IRRX>, <&topckgen CLK_TOP_AXI_SEL>;
+        clock-names = "clk", "bus";
+        linux,rc-map-name = "rc-rc6-mce";
+    };
diff --git a/Documentation/devicetree/bindings/media/mtk-cir.txt b/Documentation/devicetree/bindings/media/mtk-cir.txt
deleted file mode 100644
index 5e18087ce11f..000000000000
--- a/Documentation/devicetree/bindings/media/mtk-cir.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Device-Tree bindings for Mediatek consumer IR controller
-found in Mediatek SoC family
-
-Required properties:
-- compatible	    : Should be
-			"mediatek,mt7623-cir": for MT7623 SoC
-			"mediatek,mt7622-cir": for MT7622 SoC
-- clocks	    : list of clock specifiers, corresponding to
-		      entries in clock-names property;
-- clock-names	    : should contain
-			- "clk" entries: for MT7623 SoC
-			- "clk", "bus" entries: for MT7622 SoC
-- interrupts	    : should contain IR IRQ number;
-- reg		    : should contain IO map address for IR.
-
-Optional properties:
-- linux,rc-map-name : see rc.txt file in the same directory.
-
-Example:
-
-cir: cir at 10013000 {
-	compatible = "mediatek,mt7623-cir";
-	reg = <0 0x10013000 0 0x1000>;
-	interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_LOW>;
-	clocks = <&infracfg CLK_INFRA_IRRX>;
-	clock-names = "clk";
-	linux,rc-map-name = "rc-rc6-mce";
-};
-- 
2.35.3



From robh at kernel.org  Fri Feb  9 01:10:54 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 9 Feb 2024 09:10:54 +0000
Subject: [PATCH] dt-bindings: interrupt-controller: Convert Atmel AIC to
 json-schema
In-Reply-To: <8dcae60c-1aba-4e76-99cd-de78c2c4ba6a@microchip.com>
References: <20240208092015.263210-1-dharma.b@microchip.com>
 <170740748922.3230402.17318224112819715619.robh@kernel.org>
 <20240208-acuteness-visible-b60cd37c2b32@spud>
 <8dcae60c-1aba-4e76-99cd-de78c2c4ba6a@microchip.com>
Message-ID: <20240209091054.GA3291998-robh@kernel.org>

On Fri, Feb 09, 2024 at 06:31:15AM +0000, Dharma.B at microchip.com wrote:
> Hi Conor,
> 
> On 09/02/24 12:19 am, Conor Dooley wrote:
> > Hey Dharma,
> > 
> > On Thu, Feb 08, 2024 at 03:51:31PM +0000, Rob Herring wrote:
> >> On Thu, 08 Feb 2024 14:50:15 +0530, Dharma Balasubiramani wrote:
> >>> Convert the Atmel AIC binding document to DT schema format using
> >>> json-schema.
> >>>
> >>> Signed-off-by: Dharma Balasubiramani<dharma.b at microchip.com>
> >>> ---
> >>> Note: I get the following warnings on latest kernel but not in 6.7.
> >>> Should I be worried?
> >>> usage: yamllint [-h] [-] [-c CONFIG_FILE | -d CONFIG_DATA] [--list-files] [-f {parsable,standard,colored,github,auto}] [-s] [--no-warnings] [-v] [FILE_OR_DIR [FILE_OR_DIR ...]]
> >>> yamllint: error: one of the arguments FILE_OR_DIR - is required
> > Hard to say, how were you envoking the command? There were some issues
> > recently with dt_binding_check, but I thought those had been fixed.
> 
> I use this command to validate
> 
> make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- dt_binding_check 
> DT_SCHEMA_FILES=Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml

Humm, not sure. Will have to investigate.


> and also dtbs_check.
> 
> version = yamllint 1.32.0
> > 
> >> dtschema/dtc warnings/errors:
> >> Documentation/devicetree/bindings/interrupt-controller/atmel,aic.example.dtb: /example-1/dma-controller at ffffec00: failed to match any schema with compatible: ['atmel,at91sam9g45-dma']
> > But you didn't see this warning?
> 
> No I didn't see this warning when applied on tag:6.7. Don't know why.

That's because it just got enabled by default.

> 
> > I think you can resolve it by just dropping the "user" example from the
> > binding entirely. I don't think it adds anything at all.
> 
> I intentionally checked the generated example dts file and found that 
> both the examples look correct.

Maybe so, but how do we know with no schema? Your choices are drop from 
the example or add a schema for the DMA controller.

Rob


From angelogioacchino.delregno at collabora.com  Fri Feb  9 01:13:42 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 9 Feb 2024 10:13:42 +0100
Subject: [PATCH V2] dt-bindings: thermal: mediatek,thermal: document
 AUXADC 32k clock
In-Reply-To: <20240209055203.17144-1-zajec5@gmail.com>
References: <20240209055203.17144-1-zajec5@gmail.com>
Message-ID: <17d143aa-576e-4d67-a0ea-b79f3518b81c@collabora.com>

Il 09/02/24 06:52, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> SoCs MT7981 and MT7986 include a newer thermal block (V3) that requires
> enabling one more clock called AUXADC 32k. Require it in binding.
> 
> Cc: Daniel Golle <daniel at makrotopia.org>
> Cc: Sam Shih <sam.shih at mediatek.com>
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

So, I've made some research on this matter.. and this is a NACK.

I'll keep it short: you don't really have any 32KHz clock input for the ADC in
the infracfg clock controller (nor others).

What you're trying to say here is that you have a FastRC Oscillator input clock
(in your case, this is CLK_INFRA_ADC_FRC_CK): this clock is responsible for
providing an input clock of either 26MHz or something that is MPLL/16 (I do not
know what MPLL outputs on your platform, but those PLLs are usually giving out
"big numbers").

The FRC osc in the AUXADC will perhaps output a 32KHz clock for internal reference
and/or whatever else, but I'm not even sure that it's really going to be 32k then
internally to the IP block.

(I said "I'll keep it short" btw :-P)

Anyway.

The FRC clock is also required for the INFRA_ADC_26M clock to work correctly and,
in the clock controller driver(s) of both 7981 and 7986, that is parented to....
... surprise surprise ... INFRA_ADC_FRC_CK :-)


Finally, you do *not* need this commit, INFRA does *not* provide an adc_32k clock
to the thermal block, and you do *not* need to add the FRC clock in the devicetree
of 7981, nor 7986.

Mind you - at least in mt7986a.dtsi, there is an adc_32k clock in the thermal node,
so the right way to get your thermal node validated is not to modify the binding,
but to adhere to it by removing the extra, unneeded, clock.

Cheers!
Angelo




From Dharma.B at microchip.com  Fri Feb  9 01:16:18 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Fri, 9 Feb 2024 09:16:18 +0000
Subject: [PATCH] dt-bindings: interrupt-controller: Convert Atmel AIC to
 json-schema
In-Reply-To: <20240209091054.GA3291998-robh@kernel.org>
References: <20240208092015.263210-1-dharma.b@microchip.com>
 <170740748922.3230402.17318224112819715619.robh@kernel.org>
 <20240208-acuteness-visible-b60cd37c2b32@spud>
 <8dcae60c-1aba-4e76-99cd-de78c2c4ba6a@microchip.com>
 <20240209091054.GA3291998-robh@kernel.org>
Message-ID: <e8ad01fd-8ec0-42c9-bfdf-b1c80467371f@microchip.com>

Hi Rob,

On 09/02/24 2:40 pm, Rob Herring wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Fri, Feb 09, 2024 at 06:31:15AM +0000, Dharma.B at microchip.com wrote:
>> Hi Conor,
>>
>> On 09/02/24 12:19 am, Conor Dooley wrote:
>>> Hey Dharma,
>>>
>>> On Thu, Feb 08, 2024 at 03:51:31PM +0000, Rob Herring wrote:
>>>> On Thu, 08 Feb 2024 14:50:15 +0530, Dharma Balasubiramani wrote:
>>>>> Convert the Atmel AIC binding document to DT schema format using
>>>>> json-schema.
>>>>>
>>>>> Signed-off-by: Dharma Balasubiramani<dharma.b at microchip.com>
>>>>> ---
>>>>> Note: I get the following warnings on latest kernel but not in 6.7.
>>>>> Should I be worried?
>>>>> usage: yamllint [-h] [-] [-c CONFIG_FILE | -d CONFIG_DATA] [--list-files] [-f {parsable,standard,colored,github,auto}] [-s] [--no-warnings] [-v] [FILE_OR_DIR [FILE_OR_DIR ...]]
>>>>> yamllint: error: one of the arguments FILE_OR_DIR - is required
>>> Hard to say, how were you envoking the command? There were some issues
>>> recently with dt_binding_check, but I thought those had been fixed.
>>
>> I use this command to validate
>>
>> make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- dt_binding_check
>> DT_SCHEMA_FILES=Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
> 
> Humm, not sure. Will have to investigate.
> 
> 
>> and also dtbs_check.
>>
>> version = yamllint 1.32.0
>>>
>>>> dtschema/dtc warnings/errors:
>>>> Documentation/devicetree/bindings/interrupt-controller/atmel,aic.example.dtb: /example-1/dma-controller at ffffec00: failed to match any schema with compatible: ['atmel,at91sam9g45-dma']
>>> But you didn't see this warning?
>>
>> No I didn't see this warning when applied on tag:6.7. Don't know why.
> 
> That's because it just got enabled by default.
> 
>>
>>> I think you can resolve it by just dropping the "user" example from the
>>> binding entirely. I don't think it adds anything at all.
>>
>> I intentionally checked the generated example dts file and found that
>> both the examples look correct.
> 
> Maybe so, but how do we know with no schema? Your choices are drop from
> the example or add a schema for the DMA controller.

Currently, my colleague is actively working on adding the schema for 
DMA, anyway I will drop the dma example in the interrupt controller for now.

Thanks.
> 
> Rob

-- 
With Best Regards,
Dharma B.


From krzysztof.kozlowski at linaro.org  Fri Feb  9 01:17:01 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 9 Feb 2024 10:17:01 +0100
Subject: [PATCH V2 1/3] dt-bindings: arm: mediatek: convert hifsys to the
 json-schema clock
In-Reply-To: <d4a4a468-4a81-413e-9de6-060c2ba9e0b6@collabora.com>
References: <20240208215926.10085-1-zajec5@gmail.com>
 <20240208215926.10085-2-zajec5@gmail.com>
 <d4a4a468-4a81-413e-9de6-060c2ba9e0b6@collabora.com>
Message-ID: <502836d9-5a57-4614-b908-2adc0f01df33@linaro.org>

On 09/02/2024 09:53, AngeloGioacchino Del Regno wrote:
> Il 08/02/24 22:59, Rafa? Mi?ecki ha scritto:
>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>
>> This helps validating DTS files. Introduced changes:
>> 1. Documented "reg" property
>> 2. Documented "#reset-cells" property
>> 3. Dropped "syscon" as it was incorrectly used
>> 4. Adjusted "compatible" and "reg" in example
>>
>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>> ---
>>   .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
>>   .../clock/mediatek,mt2701-hifsys.yaml         | 51 +++++++++++++++++++
>>   2 files changed, 51 insertions(+), 26 deletions(-)
>>   delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
>>   create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
>> deleted file mode 100644
>> index 323905af82c3..000000000000
>> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
>> +++ /dev/null
>> @@ -1,26 +0,0 @@
>> -Mediatek hifsys controller
>> -============================
>> -
>> -The Mediatek hifsys controller provides various clocks and reset
>> -outputs to the system.
>> -
>> -Required Properties:
>> -
>> -- compatible: Should be:
>> -	- "mediatek,mt2701-hifsys", "syscon"
>> -	- "mediatek,mt7622-hifsys", "syscon"
>> -	- "mediatek,mt7623-hifsys", "mediatek,mt2701-hifsys", "syscon"
>> -- #clock-cells: Must be 1
>> -
>> -The hifsys controller uses the common clk binding from
>> -Documentation/devicetree/bindings/clock/clock-bindings.txt
>> -The available clocks are defined in dt-bindings/clock/mt*-clk.h.
>> -
>> -Example:
>> -
>> -hifsys: clock-controller at 1a000000 {
>> -	compatible = "mediatek,mt2701-hifsys", "syscon";
>> -	reg = <0 0x1a000000 0 0x1000>;
>> -	#clock-cells = <1>;
>> -	#reset-cells = <1>;
>> -};
>> diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
>> new file mode 100644
>> index 000000000000..eb429337cdf4
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
>> @@ -0,0 +1,51 @@
>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/mediatek,mt2701-hifsys.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Mediatek hifsys controller
> 
> Please, "MediaTek HIFSYS controller"

Them maybe "clock controller" or "clock and reset controller"?


Best regards,
Krzysztof



From angelogioacchino.delregno at collabora.com  Fri Feb  9 01:21:45 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 9 Feb 2024 10:21:45 +0100
Subject: [PATCH V2 1/3] dt-bindings: arm: mediatek: convert hifsys to the
 json-schema clock
In-Reply-To: <502836d9-5a57-4614-b908-2adc0f01df33@linaro.org>
References: <20240208215926.10085-1-zajec5@gmail.com>
 <20240208215926.10085-2-zajec5@gmail.com>
 <d4a4a468-4a81-413e-9de6-060c2ba9e0b6@collabora.com>
 <502836d9-5a57-4614-b908-2adc0f01df33@linaro.org>
Message-ID: <185865bb-983e-467f-be2d-4978c8f4d6dc@collabora.com>

Il 09/02/24 10:17, Krzysztof Kozlowski ha scritto:
> On 09/02/2024 09:53, AngeloGioacchino Del Regno wrote:
>> Il 08/02/24 22:59, Rafa? Mi?ecki ha scritto:
>>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>>
>>> This helps validating DTS files. Introduced changes:
>>> 1. Documented "reg" property
>>> 2. Documented "#reset-cells" property
>>> 3. Dropped "syscon" as it was incorrectly used
>>> 4. Adjusted "compatible" and "reg" in example
>>>
>>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>>> ---
>>>    .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
>>>    .../clock/mediatek,mt2701-hifsys.yaml         | 51 +++++++++++++++++++
>>>    2 files changed, 51 insertions(+), 26 deletions(-)
>>>    delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
>>>    create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
>>> deleted file mode 100644
>>> index 323905af82c3..000000000000
>>> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
>>> +++ /dev/null
>>> @@ -1,26 +0,0 @@
>>> -Mediatek hifsys controller
>>> -============================
>>> -
>>> -The Mediatek hifsys controller provides various clocks and reset
>>> -outputs to the system.
>>> -
>>> -Required Properties:
>>> -
>>> -- compatible: Should be:
>>> -	- "mediatek,mt2701-hifsys", "syscon"
>>> -	- "mediatek,mt7622-hifsys", "syscon"
>>> -	- "mediatek,mt7623-hifsys", "mediatek,mt2701-hifsys", "syscon"
>>> -- #clock-cells: Must be 1
>>> -
>>> -The hifsys controller uses the common clk binding from
>>> -Documentation/devicetree/bindings/clock/clock-bindings.txt
>>> -The available clocks are defined in dt-bindings/clock/mt*-clk.h.
>>> -
>>> -Example:
>>> -
>>> -hifsys: clock-controller at 1a000000 {
>>> -	compatible = "mediatek,mt2701-hifsys", "syscon";
>>> -	reg = <0 0x1a000000 0 0x1000>;
>>> -	#clock-cells = <1>;
>>> -	#reset-cells = <1>;
>>> -};
>>> diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
>>> new file mode 100644
>>> index 000000000000..eb429337cdf4
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
>>> @@ -0,0 +1,51 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/clock/mediatek,mt2701-hifsys.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Mediatek hifsys controller
>>
>> Please, "MediaTek HIFSYS controller"
> 
> Them maybe "clock controller" or "clock and reset controller"?

Yeah, that's right, let's prefer "clock and reset controller", as this binding does
describe exactly only those two functionalities of the whole HIFSYS block.

Cheers,
Angelo

> 
> 
> Best regards,
> Krzysztof
> 





From angelogioacchino.delregno at collabora.com  Fri Feb  9 01:24:58 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 9 Feb 2024 10:24:58 +0100
Subject: [PATCH V2] dt-bindings: media: convert Mediatek consumer IR to
 the json-schema
In-Reply-To: <20240209085616.1062-1-zajec5@gmail.com>
References: <20240209085616.1062-1-zajec5@gmail.com>
Message-ID: <76d31dea-2fcf-46ce-8d73-2d84edab797a@collabora.com>

Il 09/02/24 09:56, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files. Introduced changes:
> 1. Reworded title
> 2. Made "bus" clock required on MT7623 as well
> 3. Added required #include-s and adjusted "reg" & clocks in example
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
> V2: Extended "IR" in title
>      Made "bus" required at MT7623 needs it as well
>      Updated example
> 
> Thanks AngeloGioacchino!

You're welcome :-)

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> 
>   .../bindings/media/mediatek,mt7622-cir.yaml   | 55 +++++++++++++++++++
>   .../devicetree/bindings/media/mtk-cir.txt     | 28 ----------
>   2 files changed, 55 insertions(+), 28 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/media/mediatek,mt7622-cir.yaml
>   delete mode 100644 Documentation/devicetree/bindings/media/mtk-cir.txt
> 
> diff --git a/Documentation/devicetree/bindings/media/mediatek,mt7622-cir.yaml b/Documentation/devicetree/bindings/media/mediatek,mt7622-cir.yaml
> new file mode 100644
> index 000000000000..c01210e053f9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,mt7622-cir.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,mt7622-cir.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek Consumer Infrared Receiver on-SoC Controller
> +
> +maintainers:
> +  - Sean Wang <sean.wang at mediatek.com>
> +
> +allOf:
> +  - $ref: rc.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt7622-cir
> +      - mediatek,mt7623-cir
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 2
> +
> +  clock-names:
> +    items:
> +      - const: clk
> +      - const: bus
> +
> +required:
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mt2701-clk.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    ir at 10013000 {
> +        compatible = "mediatek,mt7623-cir";
> +        reg = <0x10013000 0x1000>;
> +        interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_LOW>;
> +        clocks = <&infracfg CLK_INFRA_IRRX>, <&topckgen CLK_TOP_AXI_SEL>;
> +        clock-names = "clk", "bus";
> +        linux,rc-map-name = "rc-rc6-mce";
> +    };
> diff --git a/Documentation/devicetree/bindings/media/mtk-cir.txt b/Documentation/devicetree/bindings/media/mtk-cir.txt
> deleted file mode 100644
> index 5e18087ce11f..000000000000
> --- a/Documentation/devicetree/bindings/media/mtk-cir.txt
> +++ /dev/null
> @@ -1,28 +0,0 @@
> -Device-Tree bindings for Mediatek consumer IR controller
> -found in Mediatek SoC family
> -
> -Required properties:
> -- compatible	    : Should be
> -			"mediatek,mt7623-cir": for MT7623 SoC
> -			"mediatek,mt7622-cir": for MT7622 SoC
> -- clocks	    : list of clock specifiers, corresponding to
> -		      entries in clock-names property;
> -- clock-names	    : should contain
> -			- "clk" entries: for MT7623 SoC
> -			- "clk", "bus" entries: for MT7622 SoC
> -- interrupts	    : should contain IR IRQ number;
> -- reg		    : should contain IO map address for IR.
> -
> -Optional properties:
> -- linux,rc-map-name : see rc.txt file in the same directory.
> -
> -Example:
> -
> -cir: cir at 10013000 {
> -	compatible = "mediatek,mt7623-cir";
> -	reg = <0 0x10013000 0 0x1000>;
> -	interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_LOW>;
> -	clocks = <&infracfg CLK_INFRA_IRRX>;
> -	clock-names = "clk";
> -	linux,rc-map-name = "rc-rc6-mce";
> -};



From conor at kernel.org  Fri Feb  9 01:41:25 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 9 Feb 2024 09:41:25 +0000
Subject: [PATCH] dt-bindings: interrupt-controller: Convert Atmel AIC to
 json-schema
In-Reply-To: <20240208-daintily-craftsman-c7f514d49c0f@spud>
References: <20240208092015.263210-1-dharma.b@microchip.com>
 <20240208-daintily-craftsman-c7f514d49c0f@spud>
Message-ID: <20240209-scrambled-prankish-77032c31ec62@spud>

On Thu, Feb 08, 2024 at 11:10:32PM +0000, Conor Dooley wrote:
> On Thu, Feb 08, 2024 at 02:50:15PM +0530, Dharma Balasubiramani wrote:
> > +  "#interrupt-cells":
> > +    const: 3
> > +    description: |
> > +      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
> > +      The 2nd cell specifies flags:
> > +        bits[3:0] trigger type and level flags:
> > +          1 = low-to-high edge triggered.
> > +          2 = high-to-low edge triggered.
> > +          4 = active high level-sensitive.
> > +          8 = active low level-sensitive.
> > +        Valid combinations: 1, 2, 3, 4, 8.
> 
> Shame that these are not aligned with the IRQ_TYPE defines :(

Dharma pointed out to me that these are the same and I just looked at
the wrong header file.
-------------- 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/20240209/e5a86870/attachment.sig>

From Dharma.B at microchip.com  Fri Feb  9 01:44:32 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Fri, 9 Feb 2024 09:44:32 +0000
Subject: [PATCH] dt-bindings: interrupt-controller: Convert Atmel AIC to
 json-schema
In-Reply-To: <20240208-daintily-craftsman-c7f514d49c0f@spud>
References: <20240208092015.263210-1-dharma.b@microchip.com>
 <20240208-daintily-craftsman-c7f514d49c0f@spud>
Message-ID: <af5c5d55-99b8-4de8-9719-c2d76bf2a9c8@microchip.com>

Hi Conor,

On 09/02/24 4:40 am, Conor Dooley wrote:
> Hey Dharma,
> 
> Overall this looks alright, but I have a few comments for you.
> 
> On Thu, Feb 08, 2024 at 02:50:15PM +0530, Dharma Balasubiramani wrote:
> 
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
>> new file mode 100644
>> index 000000000000..396eac53da3a
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
>> @@ -0,0 +1,88 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id:http://devicetree.org/schemas/interrupt-controller/atmel,aic.yaml#
>> +$schema:http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Advanced Interrupt Controller (AIC)
>> +
>> +maintainers:
>> +  - Nicolas Ferre<nicolas.ferre at microchip.com>
>> +  - Dharma balasubiramani<dharma.b at microchip.com>
>> +
>> +description: |
> The chomping operator, |, is not needed here as you have no formatting
> to preserve.

I missed it again, I will fix it.
> 
>> +  The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
>> +  maskable, vectored interrupt controller providing handling of up to one
>> +  hundred and twenty-eight interrupt sources.
>> It is designed to substantially
>> +  reduce the software and real-time overhead in handling internal and external
>> +  interrupts.
> This reeks of a marketing statement and should be removed IMO.

Noted. I will remove it.
> 
>> +allOf:
>> +  - $ref: /schemas/interrupt-controller.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - atmel,at91rm9200-aic
>> +      - atmel,sama5d2-aic
>> +      - atmel,sama5d3-aic
>> +      - atmel,sama5d4-aic
>> +      - microchip,sam9x60-aic
>> +
>> +  interrupt-controller: true
>> +
>> +  "#interrupt-cells":
>> +    const: 3
>> +    description: |
>> +      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
>> +      The 2nd cell specifies flags:
>> +        bits[3:0] trigger type and level flags:
>> +          1 = low-to-high edge triggered.
>> +          2 = high-to-low edge triggered.
>> +          4 = active high level-sensitive.
>> +          8 = active low level-sensitive.
>> +        Valid combinations: 1, 2, 3, 4, 8.
> Shame that these are not aligned with the IRQ_TYPE defines ?
> 
>> +        Default for internal sources: 4 (active high).
>> +      The 3rd cell specifies irq priority from 0 (lowest) to 7 (highest).
>> +
>> +  interrupts:
>> +    description: Interrupt source of the parent interrupt controller.
> Drop the description, it's obvious.

Sure.
> 
>> +    maxItems: 1
>> +
>> +  reg:
> A nit, but I would put reg after compatible.

Sure.
> 
>> +    description: Specifies base physical address(s) and size of the AIC registers.
> Same here.

Sure, I will drop the description.
> 
>> +    maxItems: 1
>> +
>> +  atmel,external-irqs:
>> +    $ref: /schemas/types.yaml#/definitions/uint32-array
>> +    description: u32 array of external irqs.
>> +
>> +required:
>> +  - compatible
>> +  - interrupt-controller
>> +  - "#interrupt-cells"
>> +  - reg
> A nit, but I would put reg after compatible

Sure.
> 
>> +  - atmel,external-irqs
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    /* AIC */
> Drop the comment, its obvious.

Sure, I will drop it
> 
>> +    aic: interrupt-controller at fffff000 {
> The node name here is not used, drop it.

Sure, I will drop the aic and use just interrupt-controller at fffff000.
> 
>> +      compatible = "atmel,at91rm9200-aic";
>> +      interrupt-controller;
>> +      #interrupt-cells = <3>;
>> +      reg = <0xfffff000 0x200>;
>> +      atmel,external-irqs = <31>;
>> +    };
>> +
>> +  - |
>> +    /* An interrupt generating device that is wired to an AIC. */
>> +    dma: dma-controller at ffffec00 {
>> +      compatible = "atmel,at91sam9g45-dma";
>> +      #dma-cells = <2>;
>> +      reg = <0xffffec00 0x200>;
>> +      interrupts = <21 4 5>;
>> +    };
> And delete this whole example ?

Sure, I will delete this example.
> 
> Cheers,
> Conor.
> 

-- 
With Best Regards,
Dharma B.


From gabriel.fernandez at foss.st.com  Fri Feb  9 01:46:14 2024
From: gabriel.fernandez at foss.st.com (Gabriel FERNANDEZ)
Date: Fri, 9 Feb 2024 10:46:14 +0100
Subject: [PATCH v9 2/4] dt-bindings: stm32: update DT bingding for
 stm32mp25
In-Reply-To: <20240208-syndrome-storeroom-5cc8bdd07c05@spud>
References: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
 <20240208142301.155698-3-gabriel.fernandez@foss.st.com>
 <20240208-syndrome-storeroom-5cc8bdd07c05@spud>
Message-ID: <768067ff-cd69-4a55-aa5a-fc1eae5c1116@foss.st.com>

Hi Conor,

Thank's for your review.

Yes, I have checked that point. I have also written the RCC driver for 
TFA/OPTE/UBOOT and once

I receive Ack in the Kernel, I will upstream the other components.

Best Regards

Gabriel


On 2/8/24 19:06, Conor Dooley wrote:

> On Thu, Feb 08, 2024 at 03:22:59PM +0100, gabriel.fernandez at foss.st.com wrote:
>> From: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
>>
>> Now RCC driver use '.index' of clk_parent_data struct to define a parent.
> The RCC driver in linux might have stopped using the names, but they
> were a required property that could be replied upon by other software
> too. Have you checked U-Boot or *BSD etc to make sure clock-names are
> not used there?
>
> Thanks,
> Conor.
>
>> The majority of parents are SCMI clocks, then dt-bindings must be fixed.
>>
>> Fixes: b5be49db3d47 ("dt-bindings: stm32: add clocks and reset binding for stm32mp25 platform")
>>
>> Signed-off-by: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
>> ---
>>   .../bindings/clock/st,stm32mp25-rcc.yaml      | 171 ++++++++++++++++--
>>   1 file changed, 155 insertions(+), 16 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml b/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml
>> index 7732e79a42b9..57bd4e7157bd 100644
>> --- a/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml
>> +++ b/Documentation/devicetree/bindings/clock/st,stm32mp25-rcc.yaml
>> @@ -38,22 +38,87 @@ properties:
>>         - description: CK_SCMI_MSI Low Power Internal oscillator (~ 4 MHz or ~ 16 MHz)
>>         - description: CK_SCMI_LSE Low Speed External oscillator (32 KHz)
>>         - description: CK_SCMI_LSI Low Speed Internal oscillator (~ 32 KHz)
>> -
>> -  clock-names:
>> -    items:
>> -      - const: hse
>> -      - const: hsi
>> -      - const: msi
>> -      - const: lse
>> -      - const: lsi
>> -
>> +      - description: CK_SCMI_HSE_DIV2 CK_SCMI_HSE divided by 2 (coud be gated)
>> +      - description: CK_SCMI_ICN_HS_MCU High Speed interconnect bus clock
>> +      - description: CK_SCMI_ICN_LS_MCU Low Speed interconnect bus clock
>> +      - description: CK_SCMI_ICN_SDMMC SDMMC interconnect bus clock
>> +      - description: CK_SCMI_ICN_DDR DDR interconnect bus clock
>> +      - description: CK_SCMI_ICN_DISPLAY Display interconnect bus clock
>> +      - description: CK_SCMI_ICN_HSL HSL interconnect bus clock
>> +      - description: CK_SCMI_ICN_NIC NIC interconnect bus clock
>> +      - description: CK_SCMI_ICN_VID Video interconnect bus clock
>> +      - description: CK_SCMI_FLEXGEN_07 flexgen clock 7
>> +      - description: CK_SCMI_FLEXGEN_08 flexgen clock 8
>> +      - description: CK_SCMI_FLEXGEN_09 flexgen clock 9
>> +      - description: CK_SCMI_FLEXGEN_10 flexgen clock 10
>> +      - description: CK_SCMI_FLEXGEN_11 flexgen clock 11
>> +      - description: CK_SCMI_FLEXGEN_12 flexgen clock 12
>> +      - description: CK_SCMI_FLEXGEN_13 flexgen clock 13
>> +      - description: CK_SCMI_FLEXGEN_14 flexgen clock 14
>> +      - description: CK_SCMI_FLEXGEN_15 flexgen clock 15
>> +      - description: CK_SCMI_FLEXGEN_16 flexgen clock 16
>> +      - description: CK_SCMI_FLEXGEN_17 flexgen clock 17
>> +      - description: CK_SCMI_FLEXGEN_18 flexgen clock 18
>> +      - description: CK_SCMI_FLEXGEN_19 flexgen clock 19
>> +      - description: CK_SCMI_FLEXGEN_20 flexgen clock 20
>> +      - description: CK_SCMI_FLEXGEN_21 flexgen clock 21
>> +      - description: CK_SCMI_FLEXGEN_22 flexgen clock 22
>> +      - description: CK_SCMI_FLEXGEN_23 flexgen clock 23
>> +      - description: CK_SCMI_FLEXGEN_24 flexgen clock 24
>> +      - description: CK_SCMI_FLEXGEN_25 flexgen clock 25
>> +      - description: CK_SCMI_FLEXGEN_26 flexgen clock 26
>> +      - description: CK_SCMI_FLEXGEN_27 flexgen clock 27
>> +      - description: CK_SCMI_FLEXGEN_28 flexgen clock 28
>> +      - description: CK_SCMI_FLEXGEN_29 flexgen clock 29
>> +      - description: CK_SCMI_FLEXGEN_30 flexgen clock 30
>> +      - description: CK_SCMI_FLEXGEN_31 flexgen clock 31
>> +      - description: CK_SCMI_FLEXGEN_32 flexgen clock 32
>> +      - description: CK_SCMI_FLEXGEN_33 flexgen clock 33
>> +      - description: CK_SCMI_FLEXGEN_34 flexgen clock 34
>> +      - description: CK_SCMI_FLEXGEN_35 flexgen clock 35
>> +      - description: CK_SCMI_FLEXGEN_36 flexgen clock 36
>> +      - description: CK_SCMI_FLEXGEN_37 flexgen clock 37
>> +      - description: CK_SCMI_FLEXGEN_38 flexgen clock 38
>> +      - description: CK_SCMI_FLEXGEN_39 flexgen clock 39
>> +      - description: CK_SCMI_FLEXGEN_40 flexgen clock 40
>> +      - description: CK_SCMI_FLEXGEN_41 flexgen clock 41
>> +      - description: CK_SCMI_FLEXGEN_42 flexgen clock 42
>> +      - description: CK_SCMI_FLEXGEN_43 flexgen clock 43
>> +      - description: CK_SCMI_FLEXGEN_44 flexgen clock 44
>> +      - description: CK_SCMI_FLEXGEN_45 flexgen clock 45
>> +      - description: CK_SCMI_FLEXGEN_46 flexgen clock 46
>> +      - description: CK_SCMI_FLEXGEN_47 flexgen clock 47
>> +      - description: CK_SCMI_FLEXGEN_48 flexgen clock 48
>> +      - description: CK_SCMI_FLEXGEN_49 flexgen clock 49
>> +      - description: CK_SCMI_FLEXGEN_50 flexgen clock 50
>> +      - description: CK_SCMI_FLEXGEN_51 flexgen clock 51
>> +      - description: CK_SCMI_FLEXGEN_52 flexgen clock 52
>> +      - description: CK_SCMI_FLEXGEN_53 flexgen clock 53
>> +      - description: CK_SCMI_FLEXGEN_54 flexgen clock 54
>> +      - description: CK_SCMI_FLEXGEN_55 flexgen clock 55
>> +      - description: CK_SCMI_FLEXGEN_56 flexgen clock 56
>> +      - description: CK_SCMI_FLEXGEN_57 flexgen clock 57
>> +      - description: CK_SCMI_FLEXGEN_58 flexgen clock 58
>> +      - description: CK_SCMI_FLEXGEN_59 flexgen clock 59
>> +      - description: CK_SCMI_FLEXGEN_60 flexgen clock 60
>> +      - description: CK_SCMI_FLEXGEN_61 flexgen clock 61
>> +      - description: CK_SCMI_FLEXGEN_62 flexgen clock 62
>> +      - description: CK_SCMI_FLEXGEN_63 flexgen clock 63
>> +      - description: CK_SCMI_ICN_APB1 Peripheral bridge 1
>> +      - description: CK_SCMI_ICN_APB2 Peripheral bridge 2
>> +      - description: CK_SCMI_ICN_APB3 Peripheral bridge 3
>> +      - description: CK_SCMI_ICN_APB4 Peripheral bridge 4
>> +      - description: CK_SCMI_ICN_APBDBG Peripheral bridge for degub
>> +      - description: CK_SCMI_TIMG1 Peripheral bridge for timer1
>> +      - description: CK_SCMI_TIMG2 Peripheral bridge for timer2
>> +      - description: CK_SCMI_PLL3 PLL3 clock
>> +      - description: clk_dsi_txbyte DSI byte clock
>>   required:
>>     - compatible
>>     - reg
>>     - '#clock-cells'
>>     - '#reset-cells'
>>     - clocks
>> -  - clock-names
>>   
>>   additionalProperties: false
>>   
>> @@ -66,11 +131,85 @@ examples:
>>           reg = <0x44200000 0x10000>;
>>           #clock-cells = <1>;
>>           #reset-cells = <1>;
>> -        clock-names = "hse", "hsi", "msi", "lse", "lsi";
>> -        clocks = <&scmi_clk CK_SCMI_HSE>,
>> -                 <&scmi_clk CK_SCMI_HSI>,
>> -                 <&scmi_clk CK_SCMI_MSI>,
>> -                 <&scmi_clk CK_SCMI_LSE>,
>> -                 <&scmi_clk CK_SCMI_LSI>;
>> +        clocks =  <&scmi_clk CK_SCMI_HSE>,
>> +                  <&scmi_clk CK_SCMI_HSI>,
>> +                  <&scmi_clk CK_SCMI_MSI>,
>> +                  <&scmi_clk CK_SCMI_LSE>,
>> +                  <&scmi_clk CK_SCMI_LSI>,
>> +                  <&scmi_clk CK_SCMI_HSE_DIV2>,
>> +                  <&scmi_clk CK_SCMI_ICN_HS_MCU>,
>> +                  <&scmi_clk CK_SCMI_ICN_LS_MCU>,
>> +                  <&scmi_clk CK_SCMI_ICN_SDMMC>,
>> +                  <&scmi_clk CK_SCMI_ICN_DDR>,
>> +                  <&scmi_clk CK_SCMI_ICN_DISPLAY>,
>> +                  <&scmi_clk CK_SCMI_ICN_HSL>,
>> +                  <&scmi_clk CK_SCMI_ICN_NIC>,
>> +                  <&scmi_clk CK_SCMI_ICN_VID>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_07>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_08>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_09>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_10>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_11>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_12>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_13>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_14>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_15>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_16>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_17>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_18>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_19>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_20>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_21>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_22>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_23>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_24>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_25>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_26>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_27>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_28>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_29>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_30>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_31>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_32>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_33>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_34>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_35>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_36>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_37>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_38>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_39>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_40>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_41>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_42>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_43>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_44>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_45>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_46>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_47>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_48>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_49>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_50>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_51>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_52>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_53>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_54>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_55>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_56>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_57>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_58>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_59>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_60>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_61>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_62>,
>> +                  <&scmi_clk CK_SCMI_FLEXGEN_63>,
>> +                  <&scmi_clk CK_SCMI_ICN_APB1>,
>> +                  <&scmi_clk CK_SCMI_ICN_APB2>,
>> +                  <&scmi_clk CK_SCMI_ICN_APB3>,
>> +                  <&scmi_clk CK_SCMI_ICN_APB4>,
>> +                  <&scmi_clk CK_SCMI_ICN_APBDBG>,
>> +                  <&scmi_clk CK_SCMI_TIMG1>,
>> +                  <&scmi_clk CK_SCMI_TIMG2>,
>> +                  <&scmi_clk CK_SCMI_PLL3>,
>> +                  <&clk_dsi_txbyte>;
>>       };
>>   ...
>> -- 
>> 2.25.1
>>


From ak at linux.intel.com  Fri Feb  9 01:49:25 2024
From: ak at linux.intel.com (Andi Kleen)
Date: Fri, 9 Feb 2024 01:49:25 -0800
Subject: [PATCH V5 01/12] perf/core: Add aux_pause, aux_resume,
 aux_start_paused
In-Reply-To: <d53ef26d-a7e6-4b3b-b593-be75425c0e77@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
 <20240208113127.22216-2-adrian.hunter@intel.com>
 <ZcVuK1nnxG18ps-a@tassilo>
 <d53ef26d-a7e6-4b3b-b593-be75425c0e77@intel.com>
Message-ID: <ZcX1JUyMMpngyRqd@tassilo>

On Fri, Feb 09, 2024 at 10:14:44AM +0200, Adrian Hunter wrote:
> On 9/02/24 02:13, Andi Kleen wrote:
> >> +static void __perf_event_aux_pause(struct perf_event *event, bool pause)
> >> +{
> >> +	if (pause) {
> >> +		if (!READ_ONCE(event->aux_paused)) {
> >> +			WRITE_ONCE(event->aux_paused, 1);
> >> +			event->pmu->stop(event, PERF_EF_PAUSE);
> >> +		}
> >> +	} else {
> >> +		if (READ_ONCE(event->aux_paused)) {
> >> +			WRITE_ONCE(event->aux_paused, 0);
> >> +			event->pmu->start(event, PERF_EF_RESUME);
> >> +		}
> > 
> > This doesn't look atomic. Either the READ/WRITE once are not needed,
> > or you need an actually atomic construct.
> 
> Yes READ_ONCE / WRITE_ONCE is not really needed here.

Normally you are supposed to add a comment on what the interaction
is (similar to what is done for spinlock declarations)

-Andi


From quic_bibekkum at quicinc.com  Fri Feb  9 01:55:12 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Fri, 9 Feb 2024 15:25:12 +0530
Subject: [PATCH v9 3/5] iommu/arm-smmu: introduction of ACTLR for custom
 prefetcher settings
In-Reply-To: <20240123144543.9405-4-quic_bibekkum@quicinc.com>
References: <20240123144543.9405-1-quic_bibekkum@quicinc.com>
 <20240123144543.9405-4-quic_bibekkum@quicinc.com>
Message-ID: <292d65e5-909a-4db6-996b-c2f9be9bcc24@quicinc.com>

Hi,

Are there any additional inputs or suggestions on this patch?
Could you let me know please, incase there are any further concerns.
will try to address them.

Thanks & regards,
Bibek

On 1/23/2024 8:15 PM, Bibek Kumar Patro wrote:
> Currently in Qualcomm  SoCs the default prefetch is set to 1 which allows
> the TLB to fetch just the next page table. MMU-500 features ACTLR
> register which is implementation defined and is used for Qualcomm SoCs
> to have a custom prefetch setting enabling TLB to prefetch the next set
> of page tables accordingly allowing for faster translations.
> 
> ACTLR value is unique for each SMR (Stream matching register) and stored
> in a pre-populated table. This value is set to the register during
> context bank initialisation.
> 
> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
> ---
>   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 61 ++++++++++++++++++++++
>   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 16 +++++-
>   drivers/iommu/arm/arm-smmu/arm-smmu.c      |  5 +-
>   drivers/iommu/arm/arm-smmu/arm-smmu.h      |  5 ++
>   4 files changed, 84 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 333daeb18c1c..6004c6d9a7b2 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -215,10 +215,42 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
>   	return true;
>   }
> 
> +static void qcom_smmu_set_actlr(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
> +		const struct actlr_config *actlrcfg, const size_t num_actlrcfg)
> +{
> +	struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> +	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> +	struct arm_smmu_smr *smr;
> +	u16 mask;
> +	int idx;
> +	u16 id;
> +	int i;
> +	int j;
> +
> +	for (i = 0; i < num_actlrcfg; i++) {
> +		id = actlrcfg[i].sid;
> +		mask = actlrcfg[i].mask;
> +
> +		for_each_cfg_sme(cfg, fwspec, j, idx) {
> +			smr = &smmu->smrs[idx];
> +			if (smr_is_subset(smr, id, mask)) {
> +				arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR,
> +						actlrcfg[i].actlr);
> +				break;
> +			}
> +		}
> +	}
> +}
> +
>   static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>   		struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>   {
> +	struct arm_smmu_device *smmu = smmu_domain->smmu;
> +	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> +	const struct actlr_variant *actlrvar;
> +	int cbndx = smmu_domain->cfg.cbndx;
>   	struct adreno_smmu_priv *priv;
> +	int i;
> 
>   	smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
> 
> @@ -248,6 +280,18 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>   	priv->set_stall = qcom_adreno_smmu_set_stall;
>   	priv->resume_translation = qcom_adreno_smmu_resume_translation;
> 
> +	actlrvar = qsmmu->data->actlrvar;
> +	if (!actlrvar)
> +		return 0;
> +
> +	for (i = 0; i < qsmmu->data->num_smmu ; i++) {
> +		if (actlrvar[i].io_start == smmu->ioaddr) {
> +			qcom_smmu_set_actlr(dev, smmu, cbndx, actlrvar[i].actlrcfg,
> +				       actlrvar[i].num_actlrcfg);
> +			break;
> +		}
> +	}
> +
>   	return 0;
>   }
> 
> @@ -274,7 +318,24 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
>   static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>   		struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>   {
> +	struct arm_smmu_device *smmu = smmu_domain->smmu;
> +	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> +	const struct actlr_variant *actlrvar;
> +	int cbndx = smmu_domain->cfg.cbndx;
> +	int i;
> +
>   	smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
> +	actlrvar = qsmmu->data->actlrvar;
> +	if (!actlrvar)
> +		return 0;
> +
> +	for (i = 0; i < qsmmu->data->num_smmu ; i++) {
> +		if (actlrvar[i].io_start == smmu->ioaddr) {
> +			qcom_smmu_set_actlr(dev, smmu, cbndx, actlrvar[i].actlrcfg,
> +				       actlrvar[i].num_actlrcfg);
> +			break;
> +		}
> +	}
> 
>   	return 0;
>   }
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
> index f3b91963e234..3f651242de7c 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
> @@ -1,6 +1,6 @@
>   /* SPDX-License-Identifier: GPL-2.0-only */
>   /*
> - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
>    */
> 
>   #ifndef _ARM_SMMU_QCOM_H
> @@ -24,8 +24,22 @@ struct qcom_smmu_config {
>   	const u32 *reg_offset;
>   };
> 
> +struct actlr_config {
> +	u16 sid;
> +	u16 mask;
> +	u32 actlr;
> +};
> +
> +struct actlr_variant {
> +	const resource_size_t io_start;
> +	const struct actlr_config * const actlrcfg;
> +	const size_t num_actlrcfg;
> +};
> +
>   struct qcom_smmu_match_data {
> +	const struct actlr_variant * const actlrvar;
>   	const struct qcom_smmu_config *cfg;
> +	const size_t num_smmu;
>   	const struct arm_smmu_impl *impl;
>   	const struct arm_smmu_impl *adreno_impl;
>   };
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index d6d1a2a55cc0..0c7f700b27dd 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -990,9 +990,10 @@ static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
>   		 * expect simply identical entries for this case, but there's
>   		 * no harm in accommodating the generalisation.
>   		 */
> -		if ((mask & smrs[i].mask) == mask &&
> -		    !((id ^ smrs[i].id) & ~smrs[i].mask))
> +
> +		if (smr_is_subset(&smrs[i], id, mask))
>   			return i;
> +
>   		/*
>   		 * If the new entry has any other overlap with an existing one,
>   		 * though, then there always exists at least one stream ID
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> index 703fd5817ec1..2e4f65412c6b 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> @@ -501,6 +501,11 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
>   		writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
>   }
> 
> +static inline bool smr_is_subset(struct arm_smmu_smr *smrs, u16 id, u16 mask)
> +{
> +	return (mask & smrs->mask) == mask && !((id ^ smrs->id) & ~smrs->mask);
> +}
> +
>   #define ARM_SMMU_GR0		0
>   #define ARM_SMMU_GR1		1
>   #define ARM_SMMU_CB(s, n)	((s)->numpage + (n))
> --
> 2.17.1
> 


From dharma.b at microchip.com  Fri Feb  9 02:01:22 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 9 Feb 2024 15:31:22 +0530
Subject: [PATCH v2] dt-bindings: interrupt-controller: Convert Atmel AIC to json-schema
Message-ID: <20240209100122.61335-1-dharma.b@microchip.com>

Convert the Atmel AIC binding document to DT schema format using
json-schema.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
Changelog
v1 -> v2
- Drop the '|' as there is no formatting to preserve.
- Remove unnecessary marketing statement from description.
- Drop the description for interrupts and reg, it's obvious.
- Put reg after compatible.
- Drop comment in example.
- Drop the example of device that is wired to an AIC as it's(dma) binding is
  not yet available.
---
 .../interrupt-controller/atmel,aic.txt        | 43 -----------
 .../interrupt-controller/atmel,aic.yaml       | 74 +++++++++++++++++++
 2 files changed, 74 insertions(+), 43 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
deleted file mode 100644
index 7079d44bf3ba..000000000000
--- a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-* Advanced Interrupt Controller (AIC)
-
-Required properties:
-- compatible: Should be:
-    - "atmel,<chip>-aic" where  <chip> can be "at91rm9200", "sama5d2",
-      "sama5d3" or "sama5d4"
-    - "microchip,<chip>-aic" where <chip> can be "sam9x60"
-
-- interrupt-controller: Identifies the node as an interrupt controller.
-- #interrupt-cells: The number of cells to define the interrupts. It should be 3.
-  The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet).
-  The second cell is used to specify flags:
-    bits[3:0] trigger type and level flags:
-      1 = low-to-high edge triggered.
-      2 = high-to-low edge triggered.
-      4 = active high level-sensitive.
-      8 = active low level-sensitive.
-      Valid combinations are 1, 2, 3, 4, 8.
-      Default flag for internal sources should be set to 4 (active high).
-  The third cell is used to specify the irq priority from 0 (lowest) to 7
-  (highest).
-- reg: Should contain AIC registers location and length
-- atmel,external-irqs: u32 array of external irqs.
-
-Examples:
-	/*
-	 * AIC
-	 */
-	aic: interrupt-controller at fffff000 {
-		compatible = "atmel,at91rm9200-aic";
-		interrupt-controller;
-		#interrupt-cells = <3>;
-		reg = <0xfffff000 0x200>;
-	};
-
-	/*
-	 * An interrupt generating device that is wired to an AIC.
-	 */
-	dma: dma-controller at ffffec00 {
-		compatible = "atmel,at91sam9g45-dma";
-		reg = <0xffffec00 0x200>;
-		interrupts = <21 4 5>;
-	};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
new file mode 100644
index 000000000000..df81115a8b7f
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/atmel,aic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Advanced Interrupt Controller (AIC)
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Dharma balasubiramani <dharma.b at microchip.com>
+
+description:
+  The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
+  maskable, vectored interrupt controller providing handling of up to one
+  hundred and twenty-eight interrupt sources.
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - atmel,at91rm9200-aic
+      - atmel,sama5d2-aic
+      - atmel,sama5d3-aic
+      - atmel,sama5d4-aic
+      - microchip,sam9x60-aic
+
+  reg:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 3
+    description: |
+      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
+      The 2nd cell specifies flags:
+        bits[3:0] trigger type and level flags:
+          1 = low-to-high edge triggered.
+          2 = high-to-low edge triggered.
+          4 = active high level-sensitive.
+          8 = active low level-sensitive.
+        Valid combinations: 1, 2, 3, 4, 8.
+        Default for internal sources: 4 (active high).
+      The 3rd cell specifies irq priority from 0 (lowest) to 7 (highest).
+
+  interrupts:
+    maxItems: 1
+
+  atmel,external-irqs:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: u32 array of external irqs.
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - "#interrupt-cells"
+  - atmel,external-irqs
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    interrupt-controller at fffff000 {
+      compatible = "atmel,at91rm9200-aic";
+      interrupt-controller;
+      #interrupt-cells = <3>;
+      reg = <0xfffff000 0x200>;
+      atmel,external-irqs = <31>;
+    };
+...

base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
-- 
2.25.1



From wsa+renesas at sang-engineering.com  Fri Feb  9 02:02:38 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Fri, 9 Feb 2024 11:02:38 +0100
Subject: [PATCH 0/6] mfd: tmio: simplify header and move to platform_data
In-Reply-To: <20240209075839.GH689448@google.com>
References: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
 <20240209075839.GH689448@google.com>
Message-ID: <ZcX4PpvBXeyCmFie@shikoro>

On Fri, Feb 09, 2024 at 07:58:39AM +0000, Lee Jones wrote:
> On Fri, 09 Feb 2024, Wolfram Sang wrote:
> 
> > The MFD parts of the TMIO have been removed by Arnd, so that only the
> > SD/MMC related functionality is left. Remove the outdated remains in the
> > public header file and then move it to platform_data as the data is now
> > specific for the SD/MMC part.
> > 
> > Based on 6.8-rc3, build bot is happy. Branch is here:
> > 
> > git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/sdhi/tmio-simplification
> > 
> > I'd suggest this goes via the MFD tree, so the series would need acks
> > from the MMC and SH maintainers. Is that okay with everyone?
> > 
> > All the best!
> > 
> >    Wolfram
> 
> Could you please change all of the subject lines with "mfd" in them
> i.e. all of the commits which touch include/linux/mfd and ensure the
> description starts with an upper case char?
> 
> I like all commits that touch drivers/mfd and include/linux/mfd to have
> the same formatting structure.

Sure, I'll just wait one day for other review comments. Thanks for your
review!

-------------- 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/20240209/bfe8bde6/attachment.sig>

From alexey.klimov at linaro.org  Fri Feb  9 02:35:35 2024
From: alexey.klimov at linaro.org (Alexey Klimov)
Date: Fri, 9 Feb 2024 10:35:35 +0000
Subject: [PATCH v4 2/2] watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle()
 for PMU regs
In-Reply-To: <20240208161700.268570-3-peter.griffin@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org> <20240208161700.268570-3-peter.griffin@linaro.org>
Message-ID: <CANgGJDoaxDLxPBxc=2kFO+omF8FcTf_3et1=J3h1BF8X27XbaQ@mail.gmail.com>

On Thu, 8 Feb 2024 at 16:21, Peter Griffin <peter.griffin at linaro.org> wrote:
>
> Obtain the PMU regmap using the new API added to exynos-pmu driver rather
> than syscon_regmap_lookup_by_phandle(). As this driver no longer depends
> on mfd syscon remove that header and Kconfig dependency.
>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>

Tested-by: Alexey Klimov <alexey.klimov at linaro.org>

Tested on odroid xu3 (exynos5422). Watchdog works as expected and can
reset the system.

> ---
>  drivers/watchdog/Kconfig       | 1 -
>  drivers/watchdog/s3c2410_wdt.c | 8 ++++----
>  2 files changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 7d22051b15a2..d78fe7137799 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -512,7 +512,6 @@ config S3C2410_WATCHDOG
>         tristate "S3C6410/S5Pv210/Exynos Watchdog"
>         depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
>         select WATCHDOG_CORE
> -       select MFD_SYSCON if ARCH_EXYNOS
>         help
>           Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos
>           SoCs. This will reboot the system when the timer expires with
> diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
> index 349d30462c8c..686cf544d0ae 100644
> --- a/drivers/watchdog/s3c2410_wdt.c
> +++ b/drivers/watchdog/s3c2410_wdt.c
> @@ -24,9 +24,9 @@
>  #include <linux/slab.h>
>  #include <linux/err.h>
>  #include <linux/of.h>
> -#include <linux/mfd/syscon.h>
>  #include <linux/regmap.h>
>  #include <linux/delay.h>
> +#include <linux/soc/samsung/exynos-pmu.h>
>
>  #define S3C2410_WTCON          0x00
>  #define S3C2410_WTDAT          0x04
> @@ -699,11 +699,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
>                 return ret;
>
>         if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
> -               wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
> -                                               "samsung,syscon-phandle");
> +               wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node,
> +                                                "samsung,syscon-phandle");
>                 if (IS_ERR(wdt->pmureg))
>                         return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
> -                                            "syscon regmap lookup failed.\n");
> +                                            "PMU regmap lookup failed.\n");
>         }
>
>         wdt_irq = platform_get_irq(pdev, 0);
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From joey.gouly at arm.com  Fri Feb  9 02:37:19 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Fri,  9 Feb 2024 10:37:19 +0000
Subject: [PATCH v1] KVM: arm64: print Hyp mode
Message-ID: <20240209103719.3813599-1-joey.gouly@arm.com>

Print which of the hyp modes is being used (hVHE, nVHE).

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oliver.upton at linux.dev>
Cc: Mark Brown <broonie at kernel.org>
---

>From what I could tell there isn't a way to tell which of the two modes was
actually booted in, and this could be useful for looking at log outputs.

 arch/arm64/kvm/arm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a25265aca432..090dbc954157 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -2591,7 +2591,8 @@ static __init int kvm_arm_init(void)
 	} else if (in_hyp_mode) {
 		kvm_info("VHE mode initialized successfully\n");
 	} else {
-		kvm_info("Hyp mode initialized successfully\n");
+		char mode = cpus_have_final_cap(ARM64_KVM_HVHE) ? 'h' : 'n';
+		kvm_info("Hyp mode (%cVHE) initialized successfully\n", mode);
 	}
 
 	/*
-- 
2.25.1



From joro at 8bytes.org  Fri Feb  9 02:47:46 2024
From: joro at 8bytes.org (Joerg Roedel)
Date: Fri, 9 Feb 2024 11:47:46 +0100
Subject: [PATCH] iommu/ipmmu-vmsa: Minor cleanups
In-Reply-To: <791877b0d310dc2ab7dc616d2786ab24252b9b8e.1707151207.git.robin.murphy@arm.com>
References: <791877b0d310dc2ab7dc616d2786ab24252b9b8e.1707151207.git.robin.murphy@arm.com>
Message-ID: <ZcYC0g-bPsOITZ07@8bytes.org>

On Mon, Feb 05, 2024 at 04:43:27PM +0000, Robin Murphy wrote:
> Remove the of_match_ptr() which was supposed to have gone long ago, but
> managed to got lost in a fix-squashing mishap. On a similar theme, we
> may as well also modernise the PM ops to get rid of the clunky #ifdefs,
> and modernise the resource mapping to keep the checkpatch brigade happy.
> 
> Link: https://lore.kernel.org/linux-iommu/Yxni3d6CdI3FZ5D+ at 8bytes.org/
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>  drivers/iommu/ipmmu-vmsa.c | 15 ++++-----------
>  1 file changed, 4 insertions(+), 11 deletions(-)

Applied, thanks.


From linus.walleij at linaro.org  Fri Feb  9 02:50:01 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 9 Feb 2024 11:50:01 +0100
Subject: [PATCH 01/14] gpio: pca953x: move suspend/resume to suspend_noirq/resume_noirq
In-Reply-To: <68d4a1bb-5b40-47fe-a117-647d77009b43@bootlin.com>
References: <20240102-j7200-pcie-s2r-v1-0-84e55da52400@bootlin.com>
 <20240102-j7200-pcie-s2r-v1-1-84e55da52400@bootlin.com> <20240116074333.GO5185@atomide.com>
 <31c42f08-7d5e-4b91-87e9-bfc7e2cfdefe@bootlin.com> <CACRpkdYUVbFoDq91uLbUy8twtG_AiD+CY2+nqzCyHV7ZyBC3sA@mail.gmail.com>
 <95032042-787e-494a-bad9-81b62653de52@bootlin.com> <CACRpkdY2wiw1zH8FsEv7S1FW044PBSXpLPqanF5yyH1R4oteEA@mail.gmail.com>
 <68d4a1bb-5b40-47fe-a117-647d77009b43@bootlin.com>
Message-ID: <CACRpkdZOhZu8OjgFHtqjeuujav3-N4dQFEqB2yvM+5QKNP37QA@mail.gmail.com>

On Fri, Feb 9, 2024 at 8:44?AM Thomas Richard
<thomas.richard at bootlin.com> wrote:

> > *FIRST* we should check if putting the callbacks to noirq is fine with
> > other systems too, and I don't see why not. Perhaps we need to even
> > merge it if we don't get any test results.
> >
> > If it doesn't work we can think of other options.
>
> I think all systems using a i2c controller which uses autosuspend should
> be impacted.
> I guess a patch (like I did in this series for i2c-omap [1]) should be
> applied for all i2c controller which use autosuspend.
>
> [1]
> https://lore.kernel.org/all/hqnxyffdsiqz5t43bexcqrwmynpjubxbzjchjaagxecso75dc7 at y7lznovxg3go/

I think this is the right thing to do.

Maybe we should just go over all of them? (Also SPI controllers?)

We will soon merge a patch to move the pinctrl-single PM to noirq, and
that actually affects more than just OMAP, it also has effect on e.g.
HiSilicon so we can expect a bit of shakeout unless we take a global
approach to this.

Yours,
Linus Walleij


From eichest at gmail.com  Fri Feb  9 02:50:10 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Fri,  9 Feb 2024 11:50:10 +0100
Subject: [PATCH RESEND v3 0/2] Add a property to turn off the max touch controller in suspend mode
Message-ID: <20240209105012.22470-1-eichest@gmail.com>

Our hardware has a shared regulator that powers various peripherals such
as the display, touch, USB hub, etc. Since the Maxtouch controller
doesn't currently allow it to be turned off, this regulator has to stay
on in suspend mode. This increases the overall power consumption. In
order to turn off the controller when the system goes into suspend mode,
this series adds a device tree property to the maxtouch driver that
allows the controller to be turned off completely and ensurs that it can
resume from the power off state.

Resend v3:
- Previously I messed up the series because send-email crashed. This is
  a resend of the original series:
  https://lore.kernel.org/linux-input/20240209084543.14726-1-eichest at gmail.com/T/#t
  https://lore.kernel.org/linux-input/20240209084818.14925-1-eichest at gmail.com/T/#u

Changes since v2:
- Add Reviewed-by tags from Linus and Krzysztof to the dt-bindings patch

Changes since v1:
- Rename the property and change the description (Krzysztof, Linus,
Dmitry, Conor)

Stefan Eichenberger (2):
  dt-bindings: input: atmel,maxtouch: add poweroff-sleep property
  Input: atmel_mxt_ts - support poweroff in suspend

 .../bindings/input/atmel,maxtouch.yaml        |  6 ++
 drivers/input/touchscreen/atmel_mxt_ts.c      | 72 ++++++++++++++-----
 2 files changed, 61 insertions(+), 17 deletions(-)

-- 
2.40.1



From eichest at gmail.com  Fri Feb  9 02:50:11 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Fri,  9 Feb 2024 11:50:11 +0100
Subject: [PATCH RESEND v3 1/2] dt-bindings: input: atmel,maxtouch: add poweroff-sleep property
In-Reply-To: <20240209105012.22470-1-eichest@gmail.com>
References: <20240209105012.22470-1-eichest@gmail.com>
Message-ID: <20240209105012.22470-2-eichest@gmail.com>

From: Stefan Eichenberger <stefan.eichenberger at toradex.com>

Add a new property to indicate that the device should power off rather
than use deep sleep. Deep sleep is a feature of the controller that
expects the controller to remain powered in suspend. However, if a
display shares its regulator with the touch controller, we may want to
do a power off so that the display and touch controller do not use any
power.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger at toradex.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/input/atmel,maxtouch.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml b/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
index c40799355ed7..8de5f539b30e 100644
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
@@ -87,6 +87,12 @@ properties:
       - 2 # ATMEL_MXT_WAKEUP_GPIO
     default: 0
 
+  atmel,poweroff-sleep:
+    description: |
+      Instead of using the deep sleep feature of the maXTouch controller,
+      poweroff the regulators.
+    type: boolean
+
   wakeup-source:
     type: boolean
 
-- 
2.40.1



From eichest at gmail.com  Fri Feb  9 02:50:12 2024
From: eichest at gmail.com (Stefan Eichenberger)
Date: Fri,  9 Feb 2024 11:50:12 +0100
Subject: [PATCH RESEND v3 2/2] Input: atmel_mxt_ts - support poweroff in suspend
In-Reply-To: <20240209105012.22470-1-eichest@gmail.com>
References: <20240209105012.22470-1-eichest@gmail.com>
Message-ID: <20240209105012.22470-3-eichest@gmail.com>

From: Stefan Eichenberger <stefan.eichenberger at toradex.com>

Add a new device tree property to indicate that the device should be
powered off in suspend mode. We have a shared regulator that powers the
display, a USB hub and some other peripherals. The maXTouch controller
doesn't normally disable the regulator in suspend mode, so our extra
peripherals stay powered on. This is not desirable as it consumes more
power. With this patch we add the option to disable the regulator in
suspend mode for the maXTouch and accept the longer initialisation time.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger at toradex.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 72 ++++++++++++++++++------
 1 file changed, 55 insertions(+), 17 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 542a31448c8f..2d5655385702 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -317,6 +317,7 @@ struct mxt_data {
 	struct gpio_desc *reset_gpio;
 	struct gpio_desc *wake_gpio;
 	bool use_retrigen_workaround;
+	bool poweroff_sleep;
 
 	/* Cached parameters from object table */
 	u16 T5_address;
@@ -2799,15 +2800,18 @@ static int mxt_configure_objects(struct mxt_data *data,
 			dev_warn(dev, "Error %d updating config\n", error);
 	}
 
-	if (data->multitouch) {
-		error = mxt_initialize_input_device(data);
-		if (error)
-			return error;
-	} else {
-		dev_warn(dev, "No touch object detected\n");
-	}
+	/* If input device is not already registered */
+	if (!data->input_dev) {
+		if (data->multitouch) {
+			error = mxt_initialize_input_device(data);
+			if (error)
+				return error;
+		} else {
+			dev_warn(dev, "No touch object detected\n");
+		}
 
-	mxt_debug_init(data);
+		mxt_debug_init(data);
+	}
 
 	return 0;
 }
@@ -3325,6 +3329,8 @@ static int mxt_probe(struct i2c_client *client)
 		msleep(MXT_RESET_INVALID_CHG);
 	}
 
+	data->poweroff_sleep = device_property_read_bool(&client->dev,
+							 "atmel,poweroff-sleep");
 	/*
 	 * Controllers like mXT1386 have a dedicated WAKE line that could be
 	 * connected to a GPIO or to I2C SCL pin, or permanently asserted low.
@@ -3387,12 +3393,21 @@ static int mxt_suspend(struct device *dev)
 	if (!input_dev)
 		return 0;
 
-	mutex_lock(&input_dev->mutex);
+	if (!device_may_wakeup(dev) && data->poweroff_sleep) {
+		if (data->reset_gpio)
+			gpiod_set_value(data->reset_gpio, 1);
 
-	if (input_device_enabled(input_dev))
-		mxt_stop(data);
+		regulator_bulk_disable(ARRAY_SIZE(data->regulators),
+				data->regulators);
+		data->T44_address = 0;
+	} else {
+		mutex_lock(&input_dev->mutex);
+
+		if (input_device_enabled(input_dev))
+			mxt_stop(data);
 
-	mutex_unlock(&input_dev->mutex);
+		mutex_unlock(&input_dev->mutex);
+	}
 
 	disable_irq(data->irq);
 
@@ -3408,14 +3423,37 @@ static int mxt_resume(struct device *dev)
 	if (!input_dev)
 		return 0;
 
-	enable_irq(data->irq);
+	if (!device_may_wakeup(dev) && data->poweroff_sleep) {
+		int ret;
 
-	mutex_lock(&input_dev->mutex);
+		ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
+				data->regulators);
+		if (ret) {
+			dev_err(dev, "failed to enable regulators: %d\n",
+					ret);
+			return ret;
+		}
+		msleep(MXT_BACKUP_TIME);
 
-	if (input_device_enabled(input_dev))
-		mxt_start(data);
+		if (data->reset_gpio) {
+			/* Wait a while and then de-assert the RESET GPIO line */
+			msleep(MXT_RESET_GPIO_TIME);
+			gpiod_set_value(data->reset_gpio, 0);
+			msleep(MXT_RESET_INVALID_CHG);
+		}
 
-	mutex_unlock(&input_dev->mutex);
+		/* This also enables the irq again */
+		mxt_initialize(data);
+	} else {
+		enable_irq(data->irq);
+
+		mutex_lock(&input_dev->mutex);
+
+		if (input_device_enabled(input_dev))
+			mxt_start(data);
+
+		mutex_unlock(&input_dev->mutex);
+	}
 
 	return 0;
 }
-- 
2.40.1



From dmitry.baryshkov at linaro.org  Fri Feb  9 02:53:10 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 9 Feb 2024 12:53:10 +0200
Subject: [PATCH v9 3/5] iommu/arm-smmu: introduction of ACTLR for custom
 prefetcher settings
In-Reply-To: <20240123144543.9405-4-quic_bibekkum@quicinc.com>
References: <20240123144543.9405-1-quic_bibekkum@quicinc.com> <20240123144543.9405-4-quic_bibekkum@quicinc.com>
Message-ID: <CAA8EJpr3S1hGSjeBx+vhZZHq0OpyULCmyxasUzF6RGdTvXEBSg@mail.gmail.com>

On Tue, 23 Jan 2024 at 16:46, Bibek Kumar Patro
<quic_bibekkum at quicinc.com> wrote:
>
> Currently in Qualcomm  SoCs the default prefetch is set to 1 which allows
> the TLB to fetch just the next page table. MMU-500 features ACTLR
> register which is implementation defined and is used for Qualcomm SoCs
> to have a custom prefetch setting enabling TLB to prefetch the next set
> of page tables accordingly allowing for faster translations.
>
> ACTLR value is unique for each SMR (Stream matching register) and stored
> in a pre-populated table. This value is set to the register during
> context bank initialisation.
>
> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 61 ++++++++++++++++++++++
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 16 +++++-
>  drivers/iommu/arm/arm-smmu/arm-smmu.c      |  5 +-
>  drivers/iommu/arm/arm-smmu/arm-smmu.h      |  5 ++
>  4 files changed, 84 insertions(+), 3 deletions(-)


Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>


-- 
With best wishes
Dmitry


From beata.michalska at arm.com  Fri Feb  9 02:55:08 2024
From: beata.michalska at arm.com (Beata Michalska)
Date: Fri, 9 Feb 2024 11:55:08 +0100
Subject: [PATCH] cpufreq: CPPC: Resolve the large frequency discrepancy
 from cpuinfo_cur_freq
In-Reply-To: <4f66c62e-b089-a125-5a8d-4a98d4181618@huawei.com>
References: <ZZWfJOsDlEXWYHA5@arm.com>
 <9428a1ed-ba4d-1fe6-63e8-11e152bf1f09@huawei.com>
 <lnocwcitdbmgcyhd2dlczgdlhtfw4pfot2br2i3hqscnvr3xgq@nuxlauxum3nr>
 <d0f47e9d-6a58-8b46-89be-b3182abb69f0@huawei.com>
 <ZZwAmqp6hcmMF8aN@arm.com>
 <6505bdcb-5a5f-cba6-483b-75c51414a9c6@huawei.com>
 <ZaaOQzCpBjmW71xf@e129154.nice.arm.com>
 <a84a9749-97a5-a207-dfd3-8322a5a992d9@huawei.com>
 <Zbyi40XtqbqXm0CL@e129154.nice.arm.com>
 <4f66c62e-b089-a125-5a8d-4a98d4181618@huawei.com>
Message-ID: <ZcYEjMO7IhSaLAAF@e129154.nice.arm.com>

On Tue, Feb 06, 2024 at 04:02:15PM +0800, lihuisong (C) wrote:
> 
> ? 2024/2/2 16:08, Beata Michalska ??:
> > On Wed, Jan 17, 2024 at 05:18:40PM +0800, lihuisong (C) wrote:
> > 
> > Hi ,
> > 
> > Again, apologies for delay,
> > 
> > > Hi,
> > > 
> > > ? 2024/1/16 22:10, Beata Michalska ??:
> > > > Hi,
> > > > 
> > > > Apologies for jumping in so late....
> > > > 
> > > > On Wed, Jan 10, 2024 at 03:09:48PM +0800, lihuisong (C) wrote:
> > > > > Hi Ionela,
> > > > > 
> > > > > ? 2024/1/8 22:03, Ionela Voinescu ??:
> > > > > > Hi,
> > > > > > 
> > > > > > On Friday 05 Jan 2024 at 15:04:47 (+0800), lihuisong (C) wrote:
> > > > > > > Hi Vanshi,
> > > > > > > 
> > > > > > > ? 2024/1/5 8:48, Vanshidhar Konda ??:
> > > > > > > > On Thu, Jan 04, 2024 at 05:36:51PM +0800, lihuisong (C) wrote:
> > > > > > > > > ? 2024/1/4 1:53, Ionela Voinescu ??:
> > > > > > > > > > Hi,
> > > > > > > > > > 
> > > > > > > > > > On Tuesday 12 Dec 2023 at 15:26:17 (+0800), Huisong Li wrote:
> > > > > > > > > > > Many developers found that the cpu current frequency is greater than
> > > > > > > > > > > the maximum frequency of the platform, please see [1], [2] and [3].
> > > > > > > > > > > 
> > > > > > > > > > > In the scenarios with high memory access pressure, the patch [1] has
> > > > > > > > > > > proved the significant latency of cpc_read() which is used to obtain
> > > > > > > > > > > delivered and reference performance counter cause an absurd frequency.
> > > > > > > > > > > The sampling interval for this counters is very critical and
> > > > > > > > > > > is expected
> > > > > > > > > > > to be equal. However, the different latency of cpc_read() has a direct
> > > > > > > > > > > impact on their sampling interval.
> > > > > > > > > > > 
> > > > > > > > > > Would this [1] alternative solution work for you?
> > > > > > > > > It would work for me AFAICS.
> > > > > > > > > Because the "arch_freq_scale" is also from AMU core and constant
> > > > > > > > > counter, and read together.
> > > > > > > > > But, from their discuss line, it seems that there are some tricky
> > > > > > > > > points to clarify or consider.
> > > > > > > > I think the changes in [1] would work better when CPUs may be idle. With
> > > > > > > > this
> > > > > > > > patch we would have to wake any core that is in idle state to read the
> > > > > > > > AMU
> > > > > > > > counters. Worst case, if core 0 is trying to read the CPU frequency of
> > > > > > > > all
> > > > > > > > cores, it may need to wake up all the other cores to read the AMU
> > > > > > > > counters.
> > > > > > >    From the approach in [1], if all CPUs (one or more cores) under one policy
> > > > > > > are idle, they still cannot be obtained the CPU frequency, right?
> > > > > > > In this case, the [1] API will return 0 and have to back to call
> > > > > > > cpufreq_driver->get() for cpuinfo_cur_freq.
> > > > > > > Then we still need to face the issue this patch mentioned.
> > > > > > With the implementation at [1], arch_freq_get_on_cpu() will not return 0
> > > > > > for idle CPUs and the get() callback will not be called to wake up the
> > > > > > CPUs.
> > > > > Right, arch_freq_get_on_cpu() will not return 0 for idle CPUs.
> > > > > However, for no-housekeeping CPUs, it will return 0 and have to call get()
> > > > > callback, right?
> > > > > > Worst case, arch_freq_get_on_cpu() will return a frequency based on the
> > > > > > AMU counter values obtained on the last tick on that CPU. But if that CPU
> > > > > > is not a housekeeping CPU, a housekeeping CPU in the same policy will be
> > > > > > selected, as it would have had a more recent tick, and therefore a more
> > > > > > recent frequency value for the domain.
> > > > > But this frequency is from the last tick,
> > > > > this last tick is probably a long time ago and it doesn't update
> > > > > 'arch_freq_scale' for some reasons like CPU dile.
> > > > > In addition, I'm not sure if there is possible that amu_scale_freq_tick() is
> > > > > executed delayed under high stress case.
> > > > > It also have an impact on the accuracy of the cpu frequency we query.
> > > > > > I understand that the frequency returned here will not be up to date,
> > > > > > but there's no proper frequency feedback for an idle CPU. If one only
> > > > > > wakes up a CPU to sample counters, before the CPU goes back to sleep,
> > > > > > the obtained frequency feedback is meaningless.
> > > > > > 
> > > > > > > > For systems with 128 cores or more, this could be very expensive and
> > > > > > > > happen
> > > > > > > > very frequently.
> > > > > > > > 
> > > > > > > > AFAICS, the approach in [1] would avoid this cost.
> > > > > > > But the CPU frequency is just an average value for the last tick period
> > > > > > > instead of the current one the CPU actually runs at.
> > > > > > > In addition, there are some conditions to use 'arch_freq_scale' in this
> > > > > > > approach.
> > > > > > What are the conditions you are referring to?
> > > > > It depends on the housekeeping CPUs.
> > > > > > > So I'm not sure if this approach can entirely cover the frequency
> > > > > > > discrepancy issue.
> > > > > > Unfortunately there is no perfect frequency feedback. By the time you
> > > > > > observe/use the value of scaling_cur_freq/cpuinfo_cur_freq, the frequency
> > > > > > of the CPU might have already changed. Therefore, an average value might
> > > > > > be a better indication of the recent performance level of a CPU.
> > > > > An average value for CPU frequency is ok. It may be better if it has not any
> > > > > delaying.
> > > > > 
> > > > > The original implementation for cpuinfo_cur_freq can more reflect their
> > > > > meaning in the user-guide [1]. The user-guide said:
> > > > > "cpuinfo_cur_freq : Current frequency of the CPU as obtained from the
> > > > > hardware, in KHz.
> > > > > This is the frequency the CPU actually runs at."
> > > > > 
> > > > > 
> > > > > [1]https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt
> > > > > 
> > > > > > Would you be able to test [1] on your platform and usecase?
> > > > > I has tested it on my platform (CPU number: 64, SMT: off and CPU base
> > > > > frequency: 2.7GHz).
> > > > > Accoding to the testing result,
> > > > > 1> I found that patch [1] and [2] cannot cover the no housekeeping CPUs.
> > > > > They still have to face the large frequency discrepancy issue my patch
> > > > > mentioned.
> > > > > 2> Additionally, the frequency value of all CPUs are almost the same by
> > > > > using the 'arch_freq_scale' factor way. I'm not sure if it is ok.
> > > > > 
> > > > > The patch [1] has been modified silightly as below:
> > > > > -->
> > > > > @@ -1756,7 +1756,10 @@ static unsigned int
> > > > > cpufreq_verify_current_freq(struct cpufreq_policy *policy, b
> > > > >   ?{
> > > > >   ??????? unsigned int new_freq;
> > > > > 
> > > > > -?????? new_freq = cpufreq_driver->get(policy->cpu);
> > > > > +?????? new_freq = arch_freq_get_on_cpu(policy->cpu);
> > > > > +?????? if (!new_freq)
> > > > > +?????????????? new_freq = cpufreq_driver->get(policy->cpu);
> > > > > +
> > > > As pointed out this change will not make it to the next version of the patch.
> > > > So I'd say you can safely ignore it and assume that arch_freq_get_on_cpu will
> > > > only be wired for sysfs nodes for scaling_cur_freq/cpuinfo_cur_freq
> > > > >   ??????? if (!new_freq)
> > > > >   ??????????????? return 0;
> > > > > 
> > > > > And the result is as follows:
> > > > > *case 1:**No setting the nohz_full and cpufreq use performance governor*
> > > > > *--> Step1: *read 'cpuinfo_cur_freq' in no pressure
> > > > >   ? 0: 2699264???? 2: 2699264???? 4: 2699264???? 6: 2699264
> > > > >   ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2699264
> > > > >   ?16: 2699264??? 18: 2696628??? 20: 2699264??? 22: 2696628
> > > > >   ?24: 2699264??? 26: 2696628??? 28: 2699264??? 30: 2696628
> > > > >   ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
> > > > >   ?40: 2699264??? 42: 2699264??? 44: 2696628??? 46: 2696628
> > > > >   ?48: 2696628??? 50: 2699264??? 52: 2699264??? 54: 2696628
> > > > >   ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
> > > > >   ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2696628
> > > > >   ?72: 2699264??? 74: 2696628??? 76: 2696628??? 78: 2699264
> > > > >   ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
> > > > >   ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2699264
> > > > >   ?96: 2696628??? 98: 2699264?? 100: 2699264?? 102: 2696628
> > > > > 104: 2699264?? 106: 2699264?? 108: 2699264?? 110: 2696628
> > > > > 112: 2699264?? 114: 2699264?? 116: 2699264?? 118: 2699264
> > > > > 120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2699264
> > > > > Note: the frequency of all CPUs are almost the same.
> > > > Were you expecting smth else ?
> > > The frequency of each CPU might have a different value.
> > > All value of all CPUs is the same under high pressure.
> > > I don't know what the phenomenon is on other platform.
> > > Do you know who else tested it?
> > So I might have rushed a bit with my previous comment/question: apologies for
> > that.
> > The numbers above: those are on a fairly idle/lightly loaded system right?
> Yes.
> > Would you mind having another go with just the arch_freq_get_on_cpu
> > implementation beign added and dropping the changes in the cpufreq and
> All my tests are done when cpufreq policy is "performance" and OS isn't on a
> high load.
> Reading "scaling_cur_freq" or "scaling_cur_freq" for each physical core on
> platform
> 
> The testing result for "cpuinfo_cur_freq" with your changes on a fairly idle
> and high loaded system can also be found in this thread.
> *A: the result with your changes*
> --> Reading "scaling_cur_freq"
> ? 0: 2688720???? 2: 2696628???? 4: 2699264???? 6: 2696628
> ? 8: 2699264??? 10: 2696628??? 12: 2699264??? 14: 2699264
> ?16: 2699264??? 18: 2696628??? 20: 2696628??? 22: 2696628
> ?24: 2699264??? 26: 2696628??? 28: 2696628??? 30: 2696628
> ?32: 2699264??? 34: 2691356??? 36: 2696628??? 38: 2699264
> ?40: 2699264??? 42: 2696628??? 44: 2696628??? 46: 2699264
> ?48: 2699264??? 50: 2696628??? 52: 2696628??? 54: 2696628
> ?56: 2696628??? 58: 2699264??? 60: 2691356??? 62: 2696628
> ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
> ?72: 2696628??? 74: 2696628??? 76: 2699264??? 78: 2696628
> ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
> ?88: 2625456??? 90: 2696628??? 92: 2699264??? 94: 2696628
> ?96: 2696628??? 98: 2696628?? 100: 2699264?? 102: 2699264
> 104: 2699264?? 106: 2696628?? 108: 2699264?? 110: 2696628
> 112: 2699264?? 114: 2699264?? 116: 2696628?? 118: 2696628
> 120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2696628
> -->Reading? "cpuinfo_cur_freq"
> ? 0: 2696628???? 2: 2696628???? 4: 2699264???? 6: 2688720
> ? 8: 2699264??? 10: 2700000??? 12: 2696628??? 14: 2698322
> ?16: 2699264??? 18: 2699264??? 20: 2696628??? 22: 2699264
> ?24: 2699264??? 26: 2699264??? 28: 2699264??? 30: 2699264
> ?32: 2699264??? 34: 2693992??? 36: 2696628??? 38: 2696628
> ?40: 2699264??? 42: 2699264??? 44: 2699264??? 46: 2696628
> ?48: 2696628??? 50: 2699264??? 52: 2696628??? 54: 2696628
> ?56: 2699264??? 58: 2699264??? 60: 2696628??? 62: 2699264
> ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2699264
> ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2693992
> ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
> ?88: 2696628??? 90: 2699264??? 92: 2696628??? 94: 2699264
> ?96: 2699264??? 98: 2696628?? 100: 2699264?? 102: 2699264
> 104: 2691356?? 106: 2699264?? 108: 2699264?? 110: 2699264
> 112: 2699264?? 114: 2696628?? 116: 2699264?? 118: 2699264
> 120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628
> 
> *B: the result without your changes*
> -->Reading "scaling_cur_freq"
> ? 0: 2698245???? 2: 2706690???? 4: 2699649???? 6: 2702105
> ? 8: 2704362??? 10: 2697993??? 12: 2701672??? 14: 2704362
> ?16: 2701052??? 18: 2701052??? 20: 2694385??? 22: 2699650
> ?24: 2706802??? 26: 2702389??? 28: 2698299??? 30: 2698299
> ?32: 2697333??? 34: 2697993??? 36: 2701337??? 38: 2699328
> ?40: 2700330??? 42: 2700330??? 44: 2698019??? 46: 2697697
> ?48: 2699659??? 50: 2701700??? 52: 2703401??? 54: 2701700
> ?56: 2704013??? 58: 2697658??? 60: 2695000??? 62: 2697666
> ?64: 2697902??? 66: 2701052??? 68: 2698245??? 70: 2695789
> ?72: 2701315??? 74: 2696655??? 76: 2693666??? 78: 2695317
> ?80: 2704912??? 82: 2699649??? 84: 2698245??? 86: 2695454
> ?88: 2697966??? 90: 2697959??? 92: 2699319??? 94: 2700680
> ?96: 2695317??? 98: 2698996?? 100: 2700000?? 102: 2700334
> 104: 2701320?? 106: 2695065?? 108: 2700986?? 110: 2703960
> 112: 2697635?? 114: 2704421?? 116: 2700680?? 118: 2702040
> 120: 2700334?? 122: 2697993?? 124: 2700334?? 126: 2705351
> -->Reading "cpuinfo_cur_freq"
> ? 0: 2696853???? 2: 2695454???? 4: 2699649???? 6: 2706993
> ? 8: 2706060??? 10: 2704362??? 12: 2704362??? 14: 2697658
> ?16: 2707719??? 18: 2697192??? 20: 2702456??? 22: 2699650
> ?24: 2705782??? 26: 2698299??? 28: 2703061??? 30: 2705802
> ?32: 2700000??? 34: 2700671??? 36: 2701337??? 38: 2697658
> ?40: 2700330??? 42: 2700330??? 44: 2699672??? 46: 2697697
> ?48: 2703061??? 50: 2696610??? 52: 2692542??? 54: 2704406
> ?56: 2695317??? 58: 2699331??? 60: 2698996??? 62: 2702675
> ?64: 2704912??? 66: 2703859??? 68: 2699649??? 70: 2698596
> ?72: 2703908??? 74: 2703355??? 76: 2697658??? 78: 2695317
> ?80: 2702105??? 82: 2707719??? 84: 2702105??? 86: 2699649
> ?88: 2697966??? 90: 2691525??? 92: 2701700??? 94: 2700680
> ?96: 2695317??? 98: 2698996?? 100: 2698666?? 102: 2700334
> 104: 2690429?? 106: 2707590?? 108: 2700986?? 110: 2701320
> 112: 2696283?? 114: 2692881?? 116: 2697627?? 118: 2704421
> 120: 2698996?? 122: 2696321?? 124: 2696655?? 126: 2695000
>
So in both cases : whether you use arch_freq_get_on_cpu or not
(so with and without the patch) you get roughly the same frequencies
on all cores - or am I missing smth from the dump above ?
And those are reflecting max freq you have provided earlier (?)
Note that the arch_freq_get_on_cpu will return an average frequency for
the last tick, so even if your system is roughly idle with your performance
governor those numbers make sense (some/most of the cores might be idle
but you will see the last freq the core was running at before going to idle).
I do not think there is an agreement what should be shown for idle core when
querying their freq through sysfs. Showing last known freq makes sense, even
more than waking up core just to try to get one.

@Ionela: Please jump in if I got things wrong.

> > then read 'scaling_cur_freq', doing several reads in some intervals ?
> It seems that above phenomenon has not a lot to do with reading intervals.
> > The change has been tested on RD-N2 model (Neoverse N2 ref platform),
> > it has also been discussed here [1]
> I doesn't get the testing result on this platform in its thread.
It might be missing exact numbers but the conclusions should be here [1]

> > > > > *--> Step 2: *read 'cpuinfo_cur_freq' in the high memory access pressure.
> > > > >   ? 0: 2696628???? 2: 2696628???? 4: 2696628???? 6: 2696628
> > > > >   ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2696628
> > > > >   ?16: 2696628??? 18: 2696628??? 20: 2696628??? 22: 2696628
> > > > >   ?24: 2696628??? 26: 2696628??? 28: 2696628??? 30: 2696628
> > > > >   ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
> > > > >   ?40: 2696628??? 42: 2696628??? 44: 2696628??? 46: 2696628
> > > > >   ?48: 2696628??? 50: 2696628??? 52: 2696628??? 54: 2696628
> > > > >   ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
> > > > >   ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
> > > > >   ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2696628
> > > > >   ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
> > > > >   ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2696628
> > > > >   ?96: 2696628??? 98: 2696628?? 100: 2696628?? 102: 2696628
> > > > > 104: 2696628?? 106: 2696628?? 108: 2696628?? 110: 2696628
> > > > > 112: 2696628?? 114: 2696628?? 116: 2696628?? 118: 2696628
> > > > > 120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628
> > > > > 
> > > > > *Case 2: setting nohz_full and cpufreq use ondemand governor*
> > > > > There is "isolcpus=1-10,41-50 nohz_full=1-10,41-50 rcu_nocbs=1-10,41-50" in
> > > > > /proc/cmdline.
> > > > Right, so if I remember correctly nohz_full implies rcu_nocbs, so no need to
> > > > set that one.
> > > > Now, afair, isolcpus will make the selected CPUs to disappear from the
> > > > schedulers view (no balancing, no migrating), so unless you affine smth
> > > > explicitly to those CPUs, you will not see much of an activity there.
> > > Correct.
> > > > Need to double check though as it has been a while ...
> > > > > *--> Step 1: *setting ondemand governor to all policy and query
> > > > > 'cpuinfo_cur_freq' in no pressure case.
> > > > > And the frequency of CPUs all are about 400MHz.
> > > > > *--> Step 2:* read 'cpuinfo_cur_freq' in the high memory access pressure.
> > > > > The high memory access pressure is from the command: "stress-ng -c 64
> > > > > --cpu-load 100% --taskset 0-63"
> > > > I'm not entirely convinced that this will affine to isolated cpus, especially
> > > > that the affinity mask spans all available cpus. If that is the case, no wonder
> > > > your isolated cpus are getting wasted being idle. But I would have to double
> > > > check how this is being handled.
> > > > > The result:
> > > > >   ?0: 2696628???? 1:? 400000???? 2:? 400000???? 3:? 400909
> > > > >   ?4:? 400000???? 5:? 400000???? 6:? 400000???? 7:? 400000
> > > > >   ?8:? 400000???? 9:? 400000??? 10:? 400600??? 11: 2696628
> > > > > 12: 2696628??? 13: 2696628??? 14: 2696628??? 15: 2696628
> > > > > 16: 2696628??? 17: 2696628??? 18: 2696628??? 19: 2696628
> > > > > 20: 2696628??? 21: 2696628??? 22: 2696628??? 23: 2696628
> > > > > 24: 2696628??? 25: 2696628??? 26: 2696628??? 27: 2696628
> > > > > 28: 2696628??? 29: 2696628??? 30: 2696628??? 31: 2696628
> > > > > 32: 2696628??? 33: 2696628??? 34: 2696628??? 35: 2696628
> > > > > 36: 2696628??? 37: 2696628??? 38: 2696628??? 39: 2696628
> > > > > 40: 2696628??? 41:? 400000??? 42:? 400000??? 43:? 400000
> > > > > 44:? 400000??? 45:? 398847??? 46:? 400000??? 47:? 400000
> > > > > 48:? 400000??? 49:? 400000??? 50:? 400000??? 51: 2696628
> > > > > 52: 2696628??? 53: 2696628??? 54: 2696628??? 55: 2696628
> > > > > 56: 2696628??? 57: 2696628??? 58: 2696628??? 59: 2696628
> > > > > 60: 2696628??? 61: 2696628??? 62: 2696628??? 63: 2699264
> > > > > 
> > > > > Note:
> > > > > (1) The frequency of 1-10 and 41-50 CPUs work on the lowest frequency.
> > > > >   ???? It turned out that nohz full was already work.
> > > > >   ???? I guess that stress-ng cannot use the CPU in the range of nohz full.
> > > > >   ???? Because the CPU frequency will be increased to 2.7G by binding CPU to
> > > > > other application.
> > > > > (2) The frequency of the nohz full core is calculated by get() callback
> > > > > according to ftrace.
> > > > It is as there is no sched tick on those, and apparently there is nothing
> > > > running on them either.
> > > Yes.
> > > If we select your approach and the above phenomenon is normal,
> > > the large frequency discrepancy issue can be resolved for CPUs with sched
> > > tick by the way.
> > > But the nohz full cores still have to face this issue. So this patch is also
> > > needed.
> > > 
> > Yes, nohz cores full have to be handled by the cpufreq driver.
> Correct. So we still have to face the issue in this patch and push this
> patch.
> Beata, would you please review this patch?
Just to clarify for my benefit (apologies but I do have to contex switch
pretty often these days): by reviewing this patch do you mean:
1) review your changes (if so I think there are few comments already to be
addressed, but I can try to have another look)
2) review changes for AMU-based arch_freq_get_on_cpu ?

*note: I will still try to have a look at the non-housekeeping cpus case

---
[1] https://lore.kernel.org/lkml/691d3eb2-cd93-f0fc-a7a4-2a8c0d44262c at nvidia.com/
---

BR
Beata
> 
> 
> /Huisong
> > 
[...]


From robin.murphy at arm.com  Fri Feb  9 02:59:04 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 9 Feb 2024 10:59:04 +0000
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <CAM9d7cga2rzcpUCa+5sZKQ3g_nC5=5XhSdkX1bRCQQUJca8uSw@mail.gmail.com>
References: <20240208032518.25830-1-yangyicong@huawei.com>
 <CAM9d7cga2rzcpUCa+5sZKQ3g_nC5=5XhSdkX1bRCQQUJca8uSw@mail.gmail.com>
Message-ID: <4688a613-c94a-49b0-9d0f-09173c64082d@arm.com>

On 2024-02-08 11:58 pm, Namhyung Kim wrote:
> Hello,
> 
> On Wed, Feb 7, 2024 at 7:29?PM Yicong Yang <yangyicong at huawei.com> wrote:
>>
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
>> throughput and latency of PCIe traffic. With the support of PCIe PMU
>> we can enable the perf iostat mode.
> 
> Hmm.. so it only works for HiSilicon.  What if users run it on a different
> platform?

Same thing as if they run it on an AMD or older Intel platform ;)

>  I think ARM should care about this.

Arm don't make PCIe root ports, and there is no PMU standardisation 
between all the myriad different implementers and vendors of PCIe IP, so 
the best perf can reasonably do is simply support the particular PMUs 
that people want perf to support.

Thanks,
Robin.

> 
> Thanks,
> Namhyung
> 
> 
>>
>> The HiSilicon PCIe PMU can support measuring the throughput of certain
>> TLP types and of certain root port. Totally 6 metrics are provided in
>> the unit of MB:
>>
>> - Inbound MWR: The memory write TLPs from the devices downstream the root port
>> - Inbound MRD: The memory read TLPs from the devices downstream the root port
>> - Inbound CPL: The completion TLPs from the devices downstream the root port
>> - Outbound MWR: The memory write TLPs from the CPU to the downstream devices
>> - Outbound MRD: The memory read TLPs from the CPU to the downstream devices
>> - Outbound CPL: The completions TLPs from the CPU to the downstream devices
>>
>> Since the PMU measures the throughput in DWords. So we need to calculate
>> the throughput in MB like:
>>    Count * 4B / 1024 / 1024
>>
>> Some of the display of the `perf iostat` will be like:
>> [root at localhost tmp]# ./perf iostat list
>> hisi_pcie0_core2<0000:40:00.0>
>> hisi_pcie2_core2<0000:5f:00.0>
>> hisi_pcie0_core1<0000:16:00.0>
>> hisi_pcie0_core1<0000:16:04.0>
>> [root at localhost tmp]# ./perf iostat --timeout 10000
>>
>>   Performance counter stats for 'system wide':
>>
>>      port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
>> 0000:40:00.0                    0                    0                    0                    0                    0                    0
>> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
>> 0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
>> 0000:16:04.0                    0                    0                    0                    0                    0                    0
>>
>>        10.008227512 seconds time elapsed
>>
>> [root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
>> -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
>> -norandommap -group_reporting -runtime=10 -time_based -bs=64k
>>
>>   Performance counter stats for 'system wide':
>>
>>      port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
>> 0000:40:00.0                    0                    0                    0                    0                    0                    0
>> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
>> 0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
>> 0000:16:04.0                    0                    0                    0                    0                    0                    0
>>
>>        10.168561767 seconds time elapsed
>>
>>         0.465373000 seconds user
>>         1.952948000 seconds sys
>>
>> More information of the HiSilicon PCIe PMU can be found at
>> Documentation/admin-guide/perf/hisi-pcie-pmu.rst.
>>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From andrejs.cainikovs at gmail.com  Fri Feb  9 03:05:00 2024
From: andrejs.cainikovs at gmail.com (Andrejs Cainikovs)
Date: Fri,  9 Feb 2024 12:05:00 +0100
Subject: [PATCH v1] arm64: dts: ti: verdin-am62: add support for Verdin USB1 interface
Message-ID: <20240209110500.22193-1-andrejs.cainikovs@gmail.com>

From: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>

Add support for Verdin USB1 interface, implements role switch
functionality using "gpio-usb-b-connector", VBUS is also now
controlled with "regulator-fixed" using a standard GPIO.

Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
---
 arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi | 55 +++++++++++++++++-----
 1 file changed, 44 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
index 6a06724b6d16..bfd44f4a15cf 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
@@ -42,6 +42,22 @@ aliases {
 		usb1 = &usb1;
 	};
 
+	connector {
+		compatible = "gpio-usb-b-connector", "usb-b-connector";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usb0_id>;
+		id-gpios = <&main_gpio1 19 GPIO_ACTIVE_HIGH>;
+		label = "USB_1";
+		self-powered;
+		vbus-supply = <&reg_usb0_vbus>;
+
+		port {
+			usb_dr_connector: endpoint {
+				remote-endpoint = <&usb0_ep>;
+			};
+		};
+	};
+
 	verdin_gpio_keys: gpio-keys {
 		compatible = "gpio-keys";
 		pinctrl-names = "default";
@@ -151,6 +167,18 @@ reg_sdhc1_vqmmc: regulator-sdhci1-vqmmc {
 		vin-supply = <&reg_sd_3v3_1v8>;
 	};
 
+	reg_usb0_vbus: regulator-usb0-vbus {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usb0_en>;
+		enable-active-high;
+		/* Verdin USB_1_EN (SODIMM 155) */
+		gpio = <&main_gpio1 50 GPIO_ACTIVE_HIGH>;
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "USB_1_EN";
+	};
+
 	reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
@@ -436,6 +464,13 @@ AM62X_IOPAD(0x0244, PIN_INPUT_PULLUP, 7) /* (C17) MMC1_SDWP.GPIO1_49 */ /* SODIM
 		>;
 	};
 
+	/* Verdin USB_1_EN */
+	pinctrl_usb0_en: main-gpio1-50-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0254, PIN_INPUT, 7) /* (C20) USB0_DRVVBUS.GPIO1_50 */ /* SODIMM 155 */
+		>;
+	};
+
 	/* On-module I2C - PMIC_I2C */
 	pinctrl_i2c0: main-i2c0-default-pins {
 		pinctrl-single,pins = <
@@ -660,13 +695,6 @@ AM62X_IOPAD(0x0038, PIN_OUTPUT,       5) /* (E24) OSPI0_CSn3.UART5_TXD    */ /*
 		>;
 	};
 
-	/* Verdin USB_1 */
-	pinctrl_usb0: main-usb0-default-pins {
-		pinctrl-single,pins = <
-			AM62X_IOPAD(0x0254, PIN_OUTPUT, 0) /* (C20) USB0_DRVVBUS */ /* SODIMM 155 */
-		>;
-	};
-
 	/* Verdin USB_2 */
 	pinctrl_usb1: main-usb1-default-pins {
 		pinctrl-single,pins = <
@@ -1013,7 +1041,7 @@ &main_gpio1 {
 		"",
 		"",
 		"SODIMM_17",
-		"", /* 50 */
+		"SODIMM 155", /* 50 */
 		"",
 		"",
 		"",
@@ -1428,11 +1456,16 @@ &usbss0 {
 	status = "disabled";
 };
 
-/* TODO: role swich using ID pin */
 &usb0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb0_id>;
+	adp-disable;
+	usb-role-switch;
 	status = "disabled";
+
+	port {
+		usb0_ep: endpoint {
+			remote-endpoint = <&usb_dr_connector>;
+		};
+	};
 };
 
 /* Verdin USB_2 */
-- 
2.34.1



From tudor.ambarus at linaro.org  Fri Feb  9 03:06:20 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 9 Feb 2024 11:06:20 +0000
Subject: [PATCH v11 07/10] mtd: spi-nor: Add stacked memories support in
 spi-nor
In-Reply-To: <BN7PR12MB2802F288C6A6B1580CF07959DC95A@BN7PR12MB2802.namprd12.prod.outlook.com>
References: <20231125092137.2948-1-amit.kumar-mahapatra@amd.com>
 <e2305642-55f1-4893-bea3-b170ac0a5348@linaro.org>
 <BN7PR12MB2802BEDFB821A1748185794CDC8AA@BN7PR12MB2802.namprd12.prod.outlook.com>
 <f5a47024-514a-4846-bc16-08cf0f9af912@linaro.org>
 <BN7PR12MB2802BB3DA682D9C13EF7DE08DC8FA@BN7PR12MB2802.namprd12.prod.outlook.com>
 <5a6f6764-6779-42b0-b6c6-3f638b85ef78@linaro.org>
 <BN7PR12MB28029EB1A7D09882878499A2DC8FA@BN7PR12MB2802.namprd12.prod.outlook.com>
 <c3fa1e04-92ed-48ab-a509-98e43abd5cd6@linaro.org>
 <BN7PR12MB2802E87F1A6CD22D904CAEACDC93A@BN7PR12MB2802.namprd12.prod.outlook.com>
 <b3d3c457-a43b-478a-85b3-52558227d139@linaro.org>
 <BN7PR12MB28027E62D66460A374E3CFEADC93A@BN7PR12MB2802.namprd12.prod.outlook.com>
 <e212f9fa-83c5-4b9e-8636-c8c6183096ab@linaro.org>
 <BN7PR12MB280237CDD7BB148479932874DC93A@BN7PR12MB2802.namprd12.prod.outlook.com>
 <576d56ed-d24b-40f9-9ae4-a02c50eea2ab@linaro.org>
 <BN7PR12MB2802F288C6A6B1580CF07959DC95A@BN7PR12MB2802.namprd12.prod.outlook.com>
Message-ID: <c6f209c8-47da-4881-921d-683464b9ddd5@linaro.org>



On 12/21/23 06:54, Mahapatra, Amit Kumar wrote:
>> Something else to consider: I see that Micron has a twin quad mode:
>> https://media-www.micron.com/-
>> /media/client/global/documents/products/data-sheet/nor-flash/serial-
>> nor/mt25t/generation-
>> b/mt25t_qljs_l_512_xba_0.pdf?rev=de70b770c5dc4da8b8ead06b57c03500
>>
>> The micron's "Separate Chip-Select and Clock Signals" resembles the AMD's
>> dual parallel 8-bit.
> Yes, I agree.
> 
>> Micron's "Shared Chip-Select and Clock Signals" differs from the AMD's
>> stacked mode, as Micron uses DQ[3:0] and DQ[7:4], whereas AMD considers
>> both as DQ[3:0].
> Yes, correct.

Amit, please help me to assess this. I assume Micron and Microchip is
using the same concepts as AMD uses for the "Dual Parallel 8-bit IO
mode", but they call it "Twin Quad Mode".

I was wrong, the AMD datasheet [1] was misleading [2], it described the
IOs for both flashes as IO[3:0], but later on in the "Table QSPI
Interface Signals" the second flash is described with IO[7:4].

The AMD's 8-bit Dual Flash Parallel Interface is using dedicated CS# and
CLK# lines for each flash. As Micron does, isn't it?

Micron says [3] that:
"The device contains two quad I/O die, each able to operate
independently for a total of eight I/Os. The memory map applies to each
die. Each die has internal registers for status, configuration, and
device protection that can be set and read independently from one other.
Micron recommends that internal configuration settings for the two die
be set identically."

it also says that:
"When using quad commands in XIO-SPI or when using QIO-SPI,
DQ[3:0]/DQ[7:4] are I/O."

So I guess the upper layers just ask for a chunk of memory to be written
and the controller handles the cs# lines automatically. How is the AMD
controller working, do you have to drive the cs# lines manually, or you
just set the parallel mode and the controller takes care of everything?

I assume this is how mchp is handling things, they seem to just set a
bit the protocol into the QSPI_IFR.PROTTYP register field and that's all
[4]. They even seem to write the registers of both flashes at the same time.

In what regards the AMD's "dual stack interface", AMD is sharing the
clock and IO lines and uses dedicated CS# lines for the flashes, whereas
Micron shares the CS# and CLK# lines with different IO lines.

Amit, please study the architectures used by mchp, micron and amd and
let us know if they are the same or they differ, and if they differ what
are the differences.

I added Conor from mchp in cc, I see Nicolas is already there, and Bean
from micron.

Thanks,
ta

[1]
https://docs.xilinx.com/r/en-US/am011-versal-acap-trm/QSPI-Flash-Interface-Signals
[2]
https://docs.xilinx.com/viewer/attachment/dwmjhDJGICdJqD4swyVzcQ/fD8nv4ry78xM0_EF5kv4mA
[3]
https://media-www.micron.com/-/media/client/global/documents/products/data-sheet/nor-flash/serial-nor/mt25t/generation-b/mt25t_qljs_l_512_xba_0.pdf?rev=de70b770c5dc4da8b8ead06b57c03500
[4]
https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocuments/DataSheets/SAMA7G5-Series-Data-Sheet-DS60001765.pdf


From ardb+git at google.com  Fri Feb  9 03:09:02 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Fri,  9 Feb 2024 12:09:02 +0100
Subject: [PATCH] ARM: iwmmxt: Remove support for PJ4/PJ4B cores
Message-ID: <20240209110901.4032939-2-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
does not support this combination (its iWMMXt configuration always
implies v5te), and so there is no v6/v7 user space that actually makes
use of this, beyond generic support for things like setjmp() that
preserve/restore the iWMMXt register file using generic LDC/STC
instructions emitted in assembler. As [0] appears to imply, this logic
is triggered for the init process at boot, and so most processes will
have a iWMMXt register context associated with it, even though it is
never used.

This means that advertising iWMMXt support on these cores results in
context switch overhead without any associated benefit, and so it is
better to simply ignore the iWMMXt unit on these systems. So rip out the
support. Doing so also fixes the issue reported in [0] related to UNDEF
handling of co-processor #0/#1 instructions issued from user space
running in Thumb2 mode.

Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Nicolas Pitre <nico at fluxnic.net>
Cc: Russell King <linux at armlinux.org.uk>
Cc: Linus Walleij <linus.walleij at linaro.org>
Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/Kconfig          |   4 +-
 arch/arm/kernel/Makefile  |   2 -
 arch/arm/kernel/iwmmxt.S  |  51 ++++----------
 arch/arm/kernel/pj4-cp0.c | 135 --------------------------------------
 4 files changed, 15 insertions(+), 177 deletions(-)
 delete mode 100644 arch/arm/kernel/pj4-cp0.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0af6709570d1..0d4e316a389e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -503,8 +503,8 @@ source "arch/arm/mm/Kconfig"
 
 config IWMMXT
 	bool "Enable iWMMXt support"
-	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B
-	default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B
+	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
+	default y if PXA27x || PXA3xx || ARCH_MMP
 	help
 	  Enable support for iWMMXt context switching at run time if
 	  running on a CPU that supports it.
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 771264d4726a..ae2f2b2b4e5a 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -75,8 +75,6 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
 obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
-obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o
-obj-$(CONFIG_CPU_PJ4B)		+= pj4-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_regs.o perf_callchain.o
 obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event_xscale.o perf_event_v6.o \
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index a0218c4867b9..4a335d3c5969 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -18,18 +18,6 @@
 #include <asm/assembler.h>
 #include "iwmmxt.h"
 
-#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
-#define PJ4(code...)		code
-#define XSC(code...)
-#elif defined(CONFIG_CPU_MOHAWK) || \
-	defined(CONFIG_CPU_XSC3) || \
-	defined(CONFIG_CPU_XSCALE)
-#define PJ4(code...)
-#define XSC(code...)		code
-#else
-#error "Unsupported iWMMXt architecture"
-#endif
-
 #define MMX_WR0		 	(0x00)
 #define MMX_WR1		 	(0x08)
 #define MMX_WR2		 	(0x10)
@@ -81,17 +69,13 @@ ENDPROC(iwmmxt_undef_handler)
 ENTRY(iwmmxt_task_enable)
 	inc_preempt_count r10, r3
 
-	XSC(mrc	p15, 0, r2, c15, c1, 0)
-	PJ4(mrc p15, 0, r2, c1, c0, 2)
+	mrc	p15, 0, r2, c15, c1, 0
 	@ CP0 and CP1 accessible?
-	XSC(tst	r2, #0x3)
-	PJ4(tst	r2, #0xf)
+	tst	r2, #0x3
 	bne	4f				@ if so no business here
 	@ enable access to CP0 and CP1
-	XSC(orr	r2, r2, #0x3)
-	XSC(mcr	p15, 0, r2, c15, c1, 0)
-	PJ4(orr	r2, r2, #0xf)
-	PJ4(mcr	p15, 0, r2, c1, c0, 2)
+	orr	r2, r2, #0x3
+	mcr	p15, 0, r2, c15, c1, 0
 
 	ldr	r3, =concan_owner
 	ldr	r2, [r0, #S_PC]			@ current task pc value
@@ -218,12 +202,9 @@ ENTRY(iwmmxt_task_disable)
 	bne	1f				@ no: quit
 
 	@ enable access to CP0 and CP1
-	XSC(mrc	p15, 0, r4, c15, c1, 0)
-	XSC(orr	r4, r4, #0x3)
-	XSC(mcr	p15, 0, r4, c15, c1, 0)
-	PJ4(mrc p15, 0, r4, c1, c0, 2)
-	PJ4(orr	r4, r4, #0xf)
-	PJ4(mcr	p15, 0, r4, c1, c0, 2)
+	mrc	p15, 0, r4, c15, c1, 0
+	orr	r4, r4, #0x3
+	mcr	p15, 0, r4, c15, c1, 0
 
 	mov	r0, #0				@ nothing to load
 	str	r0, [r3]			@ no more current owner
@@ -232,10 +213,8 @@ ENTRY(iwmmxt_task_disable)
 	bl	concan_save
 
 	@ disable access to CP0 and CP1
-	XSC(bic	r4, r4, #0x3)
-	XSC(mcr	p15, 0, r4, c15, c1, 0)
-	PJ4(bic	r4, r4, #0xf)
-	PJ4(mcr	p15, 0, r4, c1, c0, 2)
+	bic	r4, r4, #0x3
+	mcr	p15, 0, r4, c15, c1, 0
 
 	mrc	p15, 0, r2, c2, c0, 0
 	mov	r2, r2				@ cpwait
@@ -330,11 +309,9 @@ ENDPROC(iwmmxt_task_restore)
  */
 ENTRY(iwmmxt_task_switch)
 
-	XSC(mrc	p15, 0, r1, c15, c1, 0)
-	PJ4(mrc	p15, 0, r1, c1, c0, 2)
+	mrc	p15, 0, r1, c15, c1, 0
 	@ CP0 and CP1 accessible?
-	XSC(tst	r1, #0x3)
-	PJ4(tst	r1, #0xf)
+	tst	r1, #0x3
 	bne	1f				@ yes: block them for next task
 
 	ldr	r2, =concan_owner
@@ -344,10 +321,8 @@ ENTRY(iwmmxt_task_switch)
 	retne	lr				@ no: leave Concan disabled
 
 1:	@ flip Concan access
-	XSC(eor	r1, r1, #0x3)
-	XSC(mcr	p15, 0, r1, c15, c1, 0)
-	PJ4(eor r1, r1, #0xf)
-	PJ4(mcr	p15, 0, r1, c1, c0, 2)
+	eor	r1, r1, #0x3
+	mcr	p15, 0, r1, c15, c1, 0
 
 	mrc	p15, 0, r1, c2, c0, 0
 	sub	pc, lr, r1, lsr #32		@ cpwait and return
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
deleted file mode 100644
index 4bca8098c4ff..000000000000
--- a/arch/arm/kernel/pj4-cp0.c
+++ /dev/null
@@ -1,135 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/kernel/pj4-cp0.c
- *
- * PJ4 iWMMXt coprocessor context switching and handling
- *
- * Copyright (c) 2010 Marvell International Inc.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <asm/thread_notify.h>
-#include <asm/cputype.h>
-
-static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
-{
-	struct thread_info *thread = t;
-
-	switch (cmd) {
-	case THREAD_NOTIFY_FLUSH:
-		/*
-		 * flush_thread() zeroes thread->fpstate, so no need
-		 * to do anything here.
-		 *
-		 * FALLTHROUGH: Ensure we don't try to overwrite our newly
-		 * initialised state information on the first fault.
-		 */
-
-	case THREAD_NOTIFY_EXIT:
-		iwmmxt_task_release(thread);
-		break;
-
-	case THREAD_NOTIFY_SWITCH:
-		iwmmxt_task_switch(thread);
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block __maybe_unused iwmmxt_notifier_block = {
-	.notifier_call	= iwmmxt_do,
-};
-
-
-static u32 __init pj4_cp_access_read(void)
-{
-	u32 value;
-
-	__asm__ __volatile__ (
-		"mrc	p15, 0, %0, c1, c0, 2\n\t"
-		: "=r" (value));
-	return value;
-}
-
-static void __init pj4_cp_access_write(u32 value)
-{
-	u32 temp;
-
-	__asm__ __volatile__ (
-		"mcr	p15, 0, %1, c1, c0, 2\n\t"
-#ifdef CONFIG_THUMB2_KERNEL
-		"isb\n\t"
-#else
-		"mrc	p15, 0, %0, c1, c0, 2\n\t"
-		"mov	%0, %0\n\t"
-		"sub	pc, pc, #4\n\t"
-#endif
-		: "=r" (temp) : "r" (value));
-}
-
-static int __init pj4_get_iwmmxt_version(void)
-{
-	u32 cp_access, wcid;
-
-	cp_access = pj4_cp_access_read();
-	pj4_cp_access_write(cp_access | 0xf);
-
-	/* check if coprocessor 0 and 1 are available */
-	if ((pj4_cp_access_read() & 0xf) != 0xf) {
-		pj4_cp_access_write(cp_access);
-		return -ENODEV;
-	}
-
-	/* read iWMMXt coprocessor id register p1, c0 */
-	__asm__ __volatile__ ("mrc    p1, 0, %0, c0, c0, 0\n" : "=r" (wcid));
-
-	pj4_cp_access_write(cp_access);
-
-	/* iWMMXt v1 */
-	if ((wcid & 0xffffff00) == 0x56051000)
-		return 1;
-	/* iWMMXt v2 */
-	if ((wcid & 0xffffff00) == 0x56052000)
-		return 2;
-
-	return -EINVAL;
-}
-
-/*
- * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
- * switch code handle iWMMXt context switching.
- */
-static int __init pj4_cp0_init(void)
-{
-	u32 __maybe_unused cp_access;
-	int vers;
-
-	if (!cpu_is_pj4())
-		return 0;
-
-	vers = pj4_get_iwmmxt_version();
-	if (vers < 0)
-		return 0;
-
-#ifndef CONFIG_IWMMXT
-	pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n");
-#else
-	cp_access = pj4_cp_access_read() & ~0xf;
-	pj4_cp_access_write(cp_access);
-
-	pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers);
-	elf_hwcap |= HWCAP_IWMMXT;
-	thread_register_notifier(&iwmmxt_notifier_block);
-	register_iwmmxt_undef_handler();
-#endif
-
-	return 0;
-}
-
-late_initcall(pj4_cp0_init);
-- 
2.43.0.687.g38aa6559b0-goog



From mark.rutland at arm.com  Fri Feb  9 03:11:05 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 9 Feb 2024 11:11:05 +0000
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <20240206074552.541154-1-maskray@google.com>
References: <20240206074552.541154-1-maskray@google.com>
Message-ID: <ZcYIOZdYMyvFQH5u@FVFF77S0Q05N.cambridge.arm.com>

On Mon, Feb 05, 2024 at 11:45:52PM -0800, Fangrui Song wrote:
> The generic constraint "i" seems to be copied from x86 or arm (and with
> a redundant generic operand modifier "c"). It works with -fno-PIE but
> not with -fPIE/-fPIC in GCC's aarch64 port.
> 
> The machine constraint "S", which denotes a symbol or label reference
> with a constant offset, supports PIC and has been available in GCC since
> 2012 and in Clang since 7.0. However, Clang before 19 does not support
> "S" on a symbol with a constant offset [1] (e.g.
> `static_key_false(&nf_hooks_needed[pf][hook])` in
> include/linux/netfilter.h), so we use "i" as a fallback.
> 
> Suggested-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Fangrui Song <maskray at google.com>
> Link: https://github.com/llvm/llvm-project/pull/80255 [1]

This looks reasonable to me, and works with the toolchains I've tried, so:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
> Changes from
> arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
> 
> * Use "Si" as Ard suggested to support Clang<19
> * Make branch a separate operand
> 
> Changes from v1:
> 
> * Use asmSymbolicName for readability
> ---
>  arch/arm64/include/asm/jump_label.h | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
> index 48ddc0f45d22..b7716b215f91 100644
> --- a/arch/arm64/include/asm/jump_label.h
> +++ b/arch/arm64/include/asm/jump_label.h
> @@ -15,6 +15,10 @@
>  
>  #define JUMP_LABEL_NOP_SIZE		AARCH64_INSN_SIZE
>  
> +/*
> + * Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
> + * support "S" on a symbol with a constant offset, so we use "i" as a fallback.
> + */
>  static __always_inline bool arch_static_branch(struct static_key * const key,
>  					       const bool branch)
>  {
> @@ -23,9 +27,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
>  		 "	.pushsection	__jump_table, \"aw\"	\n\t"
>  		 "	.align		3			\n\t"
>  		 "	.long		1b - ., %l[l_yes] - .	\n\t"
> -		 "	.quad		%c0 - .			\n\t"
> +		 "	.quad		(%[key] - .) + %[bit0]  \n\t"
>  		 "	.popsection				\n\t"
> -		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> +		 :  :  [key]"Si"(key), [bit0]"i"(branch) :  : l_yes);
>  
>  	return false;
>  l_yes:
> @@ -40,9 +44,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
>  		 "	.pushsection	__jump_table, \"aw\"	\n\t"
>  		 "	.align		3			\n\t"
>  		 "	.long		1b - ., %l[l_yes] - .	\n\t"
> -		 "	.quad		%c0 - .			\n\t"
> +		 "	.quad		(%[key] - .) + %[bit0]  \n\t"
>  		 "	.popsection				\n\t"
> -		 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> +		 :  :  [key]"Si"(key), [bit0]"i"(branch) :  : l_yes);
>  
>  	return false;
>  l_yes:
> -- 
> 2.43.0.594.gd9cf4e227d-goog
> 
> 


From francesco at dolcini.it  Fri Feb  9 03:18:17 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Fri, 9 Feb 2024 12:18:17 +0100
Subject: [PATCH v1] arm64: dts: ti: verdin-am62: add support for Verdin
 USB1 interface
In-Reply-To: <20240209110500.22193-1-andrejs.cainikovs@gmail.com>
References: <20240209110500.22193-1-andrejs.cainikovs@gmail.com>
Message-ID: <20240209111817.GA6769@francesco-nb>

On Fri, Feb 09, 2024 at 12:05:00PM +0100, Andrejs Cainikovs wrote:
> From: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
> 
> Add support for Verdin USB1 interface, implements role switch
> functionality using "gpio-usb-b-connector", VBUS is also now
> controlled with "regulator-fixed" using a standard GPIO.
> 
> Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>

Reviewed-by: Francesco Dolcini <francesco.dolcini at toradex.com>



From francesco at dolcini.it  Fri Feb  9 03:26:18 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Fri, 9 Feb 2024 12:26:18 +0100
Subject: [PATCH v1] arm64: dts: ti: verdin-am62: add support for Verdin
 USB1 interface
In-Reply-To: <20240209110500.22193-1-andrejs.cainikovs@gmail.com>
References: <20240209110500.22193-1-andrejs.cainikovs@gmail.com>
Message-ID: <20240209112618.GA7066@francesco-nb>

On Fri, Feb 09, 2024 at 12:05:00PM +0100, Andrejs Cainikovs wrote:
> From: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
> 
> Add support for Verdin USB1 interface, implements role switch
> functionality using "gpio-usb-b-connector", VBUS is also now
> controlled with "regulator-fixed" using a standard GPIO.
> 
> Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
> ---
>  arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi | 55 +++++++++++++++++-----
>  1 file changed, 44 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
> index 6a06724b6d16..bfd44f4a15cf 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
> @@ -1013,7 +1041,7 @@ &main_gpio1 {
>  		"",
>  		"",
>  		"SODIMM_17",
> -		"", /* 50 */
> +		"SODIMM 155", /* 50 */

this should be "SODIMM_155"

Francesco



From ole.orhagen at northern.tech  Fri Feb  9 03:28:01 2024
From: ole.orhagen at northern.tech (Ole P. Orhagen)
Date: Fri,  9 Feb 2024 12:28:01 +0100
Subject: [PATCH 1/1] ARM: dts: vexpress: Set stdout-path to serial0 in the chosen node
Message-ID: <20240209112807.1345164-2-ole.orhagen@northern.tech>

Specify v2m_serial0 as the device for boot console output through the
stdout-path in the chosen node.

Signed-off-by: Ole P. Orhagen <ole.orhagen at northern.tech>
---
 arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
index 5916e4877eac..8bf35666412b 100644
--- a/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
@@ -20,7 +20,9 @@ / {
 	#address-cells = <1>;
 	#size-cells = <1>;
 
-	chosen { };
+	chosen {
+		stdout-path = &v2m_serial0;
+	};
 
 	aliases {
 		serial0 = &v2m_serial0;
-- 
2.43.0



From mark.rutland at arm.com  Fri Feb  9 03:33:51 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 9 Feb 2024 11:33:51 +0000
Subject: [RFC PATCH] KVM: arm64: Override Microsoft Azure Cobalt 100 MIDR
 value with ARM Neoverse N2
In-Reply-To: <ed6c25dc-d5c7-4f15-8fdc-f2adf209e638@linux.microsoft.com>
References: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
 <ZcNSI089xqia6lho@FVFF77S0Q05N.cambridge.arm.com>
 <ed6c25dc-d5c7-4f15-8fdc-f2adf209e638@linux.microsoft.com>
Message-ID: <ZcYNn5LDmH1g2dDB@FVFF77S0Q05N.cambridge.arm.com>

On Thu, Feb 08, 2024 at 11:16:10AM -0800, Easwar Hariharan wrote:
> On 2/7/2024 1:49 AM, Mark Rutland wrote:
> > On Tue, Feb 06, 2024 at 07:58:16PM +0000, Easwar Hariharan wrote:
> > Further, if Azure Cobalt 100 is based on ARM Neoverse N2, you presumably suffer
> > from the same errata; can you comment on that at all? e.g. are there any
> > changes in this part that *might* lead to differences in errata and/or
> > workarounds? How do the MIDR_EL1.{Variant,Revision} values compare to that of
> > Neoverse N2?
> 
> Yes, Azure Cobalt 100 suffers from the same errata as Neoverse N2. We had changes
> in the implementation, but according to our hardware folks, the Neoverse N2 errata
> we are affected by so far aren't affected by the changes made for Azure Cobalt 100.

Ok, so of the currently-known-and-mitigated errata, you'll be affected by:

	ARM64_ERRATUM_2139208
	ARM64_ERRATUM_2067961
	ARM64_ERRATUM_2253138

... and we'll need to extend the midr_range lists for those errata to cover
Azure Cobalt 100.

>From your patch, it looks like the Azure Cobalt 100 MIDR value (0x6D0FD490) is
the same as the Arm Neoverse-N2 r0p0 MIDR value (0x410FD490), except the
'Implementer' field is 0x6D ('m' in ASCII) rather than 0x41 ('A' in ASCII).

Are you happy to send a patch extending arch/arm64/include/asm/cputype.h with
the relevant ARM_CPU_IMP_* and CPU_PART_* definitions, and use those to extend
the midr_range lists for those errata?

As above, if you could make any comment on how the MIDR_EL1.{Variant,Revision}
fields map to that of Arm Neoverse-N2, it would be very helpful. It's not clear
to me whether those fields correspond directly (and so this part is based on
r0p0), or whether you have a different scheme for revision numbers. That'll
matter for correctly matching any future errata and/or future revisions of
Azure Cobalt 100.

Mark.


From ulf.hansson at linaro.org  Fri Feb  9 03:34:05 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Fri, 9 Feb 2024 12:34:05 +0100
Subject: [PATCH 0/6] mfd: tmio: simplify header and move to platform_data
In-Reply-To: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
References: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
Message-ID: <CAPDyKFpmfgwJ5dJFmORhg1tBewzhB_jrWikpX=b23r-joN91SA@mail.gmail.com>

On Fri, 9 Feb 2024 at 02:59, Wolfram Sang
<wsa+renesas at sang-engineering.com> wrote:
>
> The MFD parts of the TMIO have been removed by Arnd, so that only the
> SD/MMC related functionality is left. Remove the outdated remains in the
> public header file and then move it to platform_data as the data is now
> specific for the SD/MMC part.
>
> Based on 6.8-rc3, build bot is happy. Branch is here:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/sdhi/tmio-simplification
>
> I'd suggest this goes via the MFD tree, so the series would need acks
> from the MMC and SH maintainers. Is that okay with everyone?

Wouldn't it be better to funnel this via the mmc tree? In that way, we
can easily avoid conflicts with additional renesas-mmc driver changes
that we have in pipe.

Or perhaps there are other changes that make the mfd tree preferred?

Kind regards
Uffe

>
> All the best!
>
>    Wolfram
>
>
> Wolfram Sang (6):
>   mfd: tmio: remove obsolete platform_data
>   mfd: tmio: remove obsolete io accessors
>   mmc: tmio/sdhi: fix includes
>   mfd: tmio: update include files
>   mfd: tmio: sanitize comments
>   mfd: tmio: move header to platform_data
>
>  MAINTAINERS                                   |   2 +-
>  arch/sh/boards/board-sh7757lcr.c              |   2 +-
>  arch/sh/boards/mach-ap325rxa/setup.c          |   2 +-
>  arch/sh/boards/mach-ecovec24/setup.c          |   2 +-
>  arch/sh/boards/mach-kfr2r09/setup.c           |   2 +-
>  arch/sh/boards/mach-migor/setup.c             |   2 +-
>  arch/sh/boards/mach-se/7724/setup.c           |   2 +-
>  drivers/mmc/host/renesas_sdhi_core.c          |   2 +-
>  drivers/mmc/host/renesas_sdhi_internal_dmac.c |   5 +-
>  drivers/mmc/host/renesas_sdhi_sys_dmac.c      |   5 +-
>  drivers/mmc/host/tmio_mmc_core.c              |   3 +-
>  drivers/mmc/host/uniphier-sd.c                |   2 +-
>  include/linux/mfd/tmio.h                      | 133 ------------------
>  include/linux/platform_data/tmio.h            |  64 +++++++++
>  14 files changed, 81 insertions(+), 147 deletions(-)
>  delete mode 100644 include/linux/mfd/tmio.h
>  create mode 100644 include/linux/platform_data/tmio.h
>
> --
> 2.43.0
>
>


From andre.przywara at arm.com  Fri Feb  9 03:40:16 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 11:40:16 +0000
Subject: [PATCH v2 1/3] dt-bindings: vendor-prefixes: add Jide
In-Reply-To: <20240209114018.3580370-1-andre.przywara@arm.com>
References: <20240209114018.3580370-1-andre.przywara@arm.com>
Message-ID: <20240209114018.3580370-2-andre.przywara@arm.com>

Jide tech once create the Remix OS Android system, and shipped it on
some custom hardware. Add their name to the bindings.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.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 1a0dc04f1db47..dfb834a9279f2 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -719,6 +719,8 @@ patternProperties:
     description: JetHome (IP Sokolov P.A.)
   "^jianda,.*":
     description: Jiandangjing Technology Co., Ltd.
+  "^jide,.*":
+    description: Jide Tech
   "^joz,.*":
     description: JOZ BV
   "^kam,.*":
-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 03:40:15 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 11:40:15 +0000
Subject: [PATCH v2 0/3] arm64: dts: allwinner: Add Remix Mini PC support
Message-ID: <20240209114018.3580370-1-andre.przywara@arm.com>

Hi,

a small update, addressing the review comments and adding tags. See
below for a changelog.

==========================================
These are the DT support patches for the Jide Remix Mini PC, a now
somewhat dated Mini-PC, once shipped with some kind of desktop Android OS.
It sports an Allwinner H64 SoC, which is basically the same as the
venerable A64.
To make it stick out of the crowd, the SoC has "secure boot" enabled,
which just means it needs a different (signed) boot code package, already
supported by mainline U-Boot. Fortunately there is no public key burned
into the SoC, so any key can be used: the U-Boot build system will just
make one up.
Apart from Ethernet (blocked by the AC200 PHY) everything should work,
including WiFi and Bluetooth.

Please have a look!

Changelog v1 .. v2:
- Update copyright year
- Remove not-working MMC DDR speed mode
- Add HS-400 speed mode property (used by the BSP kernel)
- Remove superfluous pinctrl-names property

Andre Przywara (3):
  dt-bindings: vendor-prefixes: add Jide
  dt-bindings: arm: sunxi: document Remix Mini PC name
  arm64: dts: allwinner: Add Jide Remix Mini PC support

 .../devicetree/bindings/arm/sunxi.yaml        |   6 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../allwinner/sun50i-h64-remix-mini-pc.dts    | 356 ++++++++++++++++++
 4 files changed, 365 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts

-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 03:40:17 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 11:40:17 +0000
Subject: [PATCH v2 2/3] dt-bindings: arm: sunxi: document Remix Mini PC name
In-Reply-To: <20240209114018.3580370-1-andre.przywara@arm.com>
References: <20240209114018.3580370-1-andre.przywara@arm.com>
Message-ID: <20240209114018.3580370-3-andre.przywara@arm.com>

The Jide Remix Mini PC is a mini computer that ships with the Remix OS
Android based system. The SoC is an Allwinner H64, which is very close,
if not identical to the Allwinner A64.

Add the board/SoC compatible string pair to the list of known boards.
There are some drivers that look explicitly for the A64 compatible name,
so retain this name to increase compatibility.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index a9d8e85565b89..dab7a248c88da 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -815,6 +815,12 @@ properties:
           - const: allwinner,r7-tv-dongle
           - const: allwinner,sun5i-a10s
 
+      - description: Remix Mini PC
+        items:
+          - const: jide,remix-mini-pc
+          - const: allwinner,sun50i-h64
+          - const: allwinner,sun50i-a64
+
       - description: RerVision H3-DVK
         items:
           - const: rervision,h3-dvk
-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 03:40:18 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 11:40:18 +0000
Subject: [PATCH v2 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC support
In-Reply-To: <20240209114018.3580370-1-andre.przywara@arm.com>
References: <20240209114018.3580370-1-andre.przywara@arm.com>
Message-ID: <20240209114018.3580370-4-andre.przywara@arm.com>

The Remix Mini PC is a "mini computer" using the Allwinner H64 SoC,
which appears to be just a relabelled A64. It was launched in 2015 by
the now defunct company Jide, and shipped with a desktop optimised
version of Android. It features
	- Allwinner H64 Soc (4 * Arm Cortex-A53 cores)
	- 1 or 2 GB DRAM
	- 8 or 16 GB eMMC flash
	- 100 MBit Ethernet port (using an X-Powers AC200 PHY)
	- RTL8723BS WiFi & Bluetooth chip
	- HDMI port
	- two USB 2.0 ports
	- 3.5mm AV port
	- microSD card slot

The devicetree covers most peripherals, though there is no agreed
binding for the PHY chip yet, so this is left out.
The eMMC did not work with the MMC DDR speed mode, so this mode property
is omitted.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../allwinner/sun50i-h64-remix-mini-pc.dts    | 356 ++++++++++++++++++
 2 files changed, 357 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 91d505b385de5..2db3b15ad09f2 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -16,6 +16,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab-early-adopter.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
new file mode 100644
index 0000000000000..b6e3c169797f0
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2023 ARM Ltd.
+
+/dts-v1/;
+
+#include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "Remix Mini PC";
+	compatible = "jide,remix-mini-pc", "allwinner,sun50i-h64",
+		     "allwinner,sun50i-a64";
+
+	aliases {
+		ethernet1 = &rtl8723bs;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	reg_vcc5v: regulator-5v {
+		/* board wide 5V supply directly from the DC input */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
+		post-power-on-delay-ms = <200>;
+	};
+};
+
+&codec {
+	status = "okay";
+};
+
+&codec_analog {
+	cpvdd-supply = <&reg_eldo1>;
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&dai {
+	status = "okay";
+};
+
+&de {
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&hdmi {
+	hvcc-supply = <&reg_dldo1>;
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+/* Connects to the AC200 chip */
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	status = "okay";
+};
+
+&i2c0_pins {
+	bias-pull-up;
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins>;
+	vmmc-supply = <&reg_dcdc1>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	vmmc-supply = <&reg_aldo1>;
+	vqmmc-supply = <&reg_dldo4>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	rtl8723bs: wifi at 1 {
+		reg = <1>;
+		interrupt-parent = <&r_pio>;
+		interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
+		interrupt-names = "host-wake";
+	};
+};
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
+	vmmc-supply = <&reg_dcdc1>;
+	vqmmc-supply = <&reg_eldo1>;
+	bus-width = <8>;
+	non-removable;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	cap-mmc-hw-reset;
+	status = "okay";
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&pio {
+	vcc-pb-supply = <&reg_dcdc1>;
+	vcc-pc-supply = <&reg_dcdc1>;
+	vcc-pd-supply = <&reg_dcdc1>;
+	vcc-pe-supply = <&reg_dcdc1>;
+	vcc-pf-supply = <&reg_dcdc1>;
+	vcc-pg-supply = <&reg_dldo4>;
+	vcc-ph-supply = <&reg_dcdc1>;
+};
+
+&r_ir {
+	status = "okay";
+};
+
+&r_pio {
+	/*
+	 * We cannot add that supply for now since it would create a circular
+	 * dependency between pinctrl, the regulator and the RSB Bus.
+	 *
+	 * vcc-pl-supply = <&reg_aldo2>;
+	 */
+};
+
+&r_rsb {
+	status = "okay";
+
+	axp803: pmic at 3a3 {
+		compatible = "x-powers,axp803";
+		reg = <0x3a3>;
+		interrupt-parent = <&r_intc>;
+		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
+		x-powers,drive-vbus-en;
+
+		vin1-supply = <&reg_vcc5v>;
+		vin2-supply = <&reg_vcc5v>;
+		vin3-supply = <&reg_vcc5v>;
+		vin5-supply = <&reg_vcc5v>;
+		vin6-supply = <&reg_vcc5v>;
+		aldoin-supply = <&reg_vcc5v>;
+		dldoin-supply = <&reg_vcc5v>;
+		eldoin-supply = <&reg_vcc5v>;
+		fldoin-supply = <&reg_vcc5v>;
+		drivevbus-supply = <&reg_vcc5v>;
+		ips-supply = <&reg_vcc5v>;
+
+		status = "okay";
+	};
+};
+
+#include "axp803.dtsi"
+
+&ac_power_supply {
+	status = "okay";
+};
+
+&reg_dcdc1 {
+	regulator-always-on;
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-3v3";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1040000>;
+	regulator-max-microvolt = <1300000>;
+	regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+&reg_dcdc5 {
+	regulator-always-on;
+	regulator-min-microvolt = <1500000>;
+	regulator-max-microvolt = <1500000>;
+	regulator-name = "vcc-dram";
+};
+
+/* Deviates from the reset default of 1.1V. */
+&reg_dcdc6 {
+	regulator-always-on;
+	regulator-min-microvolt = <1200000>;
+	regulator-max-microvolt = <1200000>;
+	regulator-name = "vdd-sys";
+};
+
+&reg_aldo1 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-wifi";
+};
+
+&reg_aldo2 {
+	/* Specifying R_PIO consumer would create circular dependency. */
+	regulator-always-on;
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-pl";
+};
+
+&reg_aldo3 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "vcc-pll-avcc";
+};
+
+/* AC200 power supply */
+&reg_dldo1 {
+	regulator-always-on;
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-ave-33";
+};
+
+&reg_dldo4 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-wifi-io";
+};
+
+&reg_drivevbus {
+	regulator-name = "usb0-vbus";
+	status = "okay";
+};
+
+&reg_eldo1 {
+	regulator-always-on;
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-name = "vcc-cpvdd-dram-emmc";
+};
+
+/* Supplies the arisc management core, needed by TF-A to power off cores. */
+&reg_fldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1100000>;
+	regulator-max-microvolt = <1100000>;
+	regulator-name = "vdd-cpus";
+};
+
+&reg_rtc_ldo {
+	regulator-name = "vcc-rtc";
+};
+
+&simplefb_hdmi {
+	vcc-hdmi-supply = <&reg_dcdc1>;
+};
+
+&sound {
+	simple-audio-card,aux-devs = <&codec_analog>;
+	simple-audio-card,widgets = "Microphone", "Microphone Jack",
+				    "Headphone", "Headphone Jack";
+	simple-audio-card,routing =
+			"Left DAC", "DACL",
+			"Right DAC", "DACR",
+			"Headphone Jack", "HP",
+			"ADCL", "Left ADC",
+			"ADCR", "Right ADC",
+			"MIC2", "Microphone Jack";
+	status = "okay";
+};
+
+/* On the (unpopulated) UART pads. */
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pb_pins>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+	uart-has-rtscts;
+	status = "okay";
+
+	bluetooth {
+		compatible = "realtek,rtl8723bs-bt";
+		enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
+		max-speed = <1500000>;
+	};
+};
+
+&usb_otg {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy {
+	usb0_vbus-supply = <&reg_drivevbus>;
+	usb1_vbus-supply = <&reg_drivevbus>;
+	status = "okay";
+};
-- 
2.25.1



From jernej.skrabec at gmail.com  Fri Feb  9 03:45:20 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Fri, 09 Feb 2024 12:45:20 +0100
Subject: [PATCH v2 3/3] arm64: dts: allwinner: Add Jide Remix Mini PC support
In-Reply-To: <20240209114018.3580370-4-andre.przywara@arm.com>
References: <20240209114018.3580370-1-andre.przywara@arm.com>
 <20240209114018.3580370-4-andre.przywara@arm.com>
Message-ID: <5752892.DvuYhMxLoT@jernej-laptop>

Dne petek, 09. februar 2024 ob 12:40:18 CET je Andre Przywara napisal(a):
> The Remix Mini PC is a "mini computer" using the Allwinner H64 SoC,
> which appears to be just a relabelled A64. It was launched in 2015 by
> the now defunct company Jide, and shipped with a desktop optimised
> version of Android. It features
> 	- Allwinner H64 Soc (4 * Arm Cortex-A53 cores)
> 	- 1 or 2 GB DRAM
> 	- 8 or 16 GB eMMC flash
> 	- 100 MBit Ethernet port (using an X-Powers AC200 PHY)
> 	- RTL8723BS WiFi & Bluetooth chip
> 	- HDMI port
> 	- two USB 2.0 ports
> 	- 3.5mm AV port
> 	- microSD card slot
> 
> The devicetree covers most peripherals, though there is no agreed
> binding for the PHY chip yet, so this is left out.
> The eMMC did not work with the MMC DDR speed mode, so this mode property
> is omitted.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From andre.przywara at arm.com  Fri Feb  9 03:57:57 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 11:57:57 +0000
Subject: [PATCH v2 0/2]  arm64: dts: allwinner: Add Transpeed WiFi nodes
Message-ID: <20240209115759.3582869-1-andre.przywara@arm.com>

Hi,

a tiny update, see below for the changelog.
======================================

This adds the WiFi DT nodes for the Transpeed 8K618T TV box. It uses a
Murata module with a Broadcom 4335 chip, which works fine with the
mainline Linux driver, given you provide the proper firmware files. We
found some in some LibreELEC repository.

Patch 1 adds the pinctrl node for the 32KHz clock fanout pin, patch 2
adds the actual SDIO WiFi node.

Please have a look!

Cheers,
Andre

Changelog v1 .. v2:
- add /omit-if-no-ref/ tag for clock fanout pin node
- update commit message to avoid mentioning Linux or driver

Andre Przywara (2):
  arm64: dts: allwinner: h616: Add 32K fanout pin
  arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes

 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi |  6 +++++
 .../sun50i-h618-transpeed-8k618-t.dts         | 23 +++++++++++++++++++
 2 files changed, 29 insertions(+)

-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 03:57:59 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 11:57:59 +0000
Subject: [PATCH v2 2/2] arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes
In-Reply-To: <20240209115759.3582869-1-andre.przywara@arm.com>
References: <20240209115759.3582869-1-andre.przywara@arm.com>
Message-ID: <20240209115759.3582869-3-andre.przywara@arm.com>

In contrast to other devices using Allwinner SoCs, the Transpeed 8K618-T
TV box uses a mainline supported WiFi chip: it's Broadcom 4335 compatible,
packaged by Murata.

Add the required DT nodes to let DT users know about the SDIO device.
There is an otherwise empty MMC device node, to receive the MAC address,
that firmware might want to write in there.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 .../sun50i-h618-transpeed-8k618-t.dts         | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
index 8ea1fd41aebaa..7ec4098e707bf 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
@@ -16,6 +16,7 @@ / {
 
 	aliases {
 		serial0 = &uart0;
+		ethernet1 = &sdio_wifi;
 	};
 
 	chosen {
@@ -39,6 +40,15 @@ reg_vcc3v3: vcc3v3 {
 		regulator-max-microvolt = <3300000>;
 		regulator-always-on;
 	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&rtc CLK_OSC32K_FANOUT>;
+		clock-names = "ext_clock";
+		pinctrl-0 = <&x32clk_fanout_pin>;
+		pinctrl-names = "default";
+		reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
+	};
 };
 
 &ehci0 {
@@ -60,6 +70,19 @@ &mmc0 {
 	status = "okay";
 };
 
+&mmc1 {
+	vmmc-supply = <&reg_dldo1>;
+	vqmmc-supply = <&reg_aldo1>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+
+	sdio_wifi: wifi at 1 {
+		reg = <1>;
+	};
+};
+
 &mmc2 {
 	vmmc-supply = <&reg_dldo1>;
 	vqmmc-supply = <&reg_aldo1>;
-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 03:57:58 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 11:57:58 +0000
Subject: [PATCH v2 1/2] arm64: dts: allwinner: h616: Add 32K fanout pin
In-Reply-To: <20240209115759.3582869-1-andre.przywara@arm.com>
References: <20240209115759.3582869-1-andre.przywara@arm.com>
Message-ID: <20240209115759.3582869-2-andre.przywara@arm.com>

On some boards the designers saved on a 32KHz crystal for some external
chips, so the SoC has to help out, with providing a 32 KHz clock signal.

Add a pinctrl group node to allow DT nodes to reference this fanout signal.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index d549d277d9729..12ffabc79bcde 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -256,6 +256,12 @@ uart1_rts_cts_pins: uart1-rts-cts-pins {
 				pins = "PG8", "PG9";
 				function = "uart1";
 			};
+
+			/omit-if-no-ref/
+			x32clk_fanout_pin: x32clk-fanout-pin {
+				pins = "PG10";
+				function = "clock";
+			};
 		};
 
 		gic: interrupt-controller at 3021000 {
-- 
2.25.1



From jean-philippe at linaro.org  Fri Feb  9 03:58:24 2024
From: jean-philippe at linaro.org (Jean-Philippe Brucker)
Date: Fri, 9 Feb 2024 11:58:24 +0000
Subject: [RFC PATCH v2 0/7] iommu/arm-smmu-v3: Use pinned KVM VMID for
 stage 2
In-Reply-To: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240209115824.GA2922446@myrica>

Hi Shameer,

On Thu, Feb 08, 2024 at 03:18:30PM +0000, Shameer Kolothum wrote:
> Hi,
> 
> On an ARM64 system with a SMMUv3 implementation that fully supports
> Broadcast TLB Maintenance(BTM) feature as part of the Distributed
> Virtual Memory(DVM) protocol, the CPU TLB invalidate instructions are
> received by SMMUv3. This is very useful when the SMMUv3 shares the
> page tables with the CPU(eg: Guest SVA use case). For this to work,
> the SMMUv3 must use the same VMID that is allocated by KVM to configure
> the nested stage 2(S2) translations.

The series makes sense to me. Maybe a little more detail to help the KVM
maintainers understand why we need something like this even though the s2
page tables aren't shared between CPU and SMMU:

* When enabling BTM in the SMMU, all TLB invalidations to the
  inner-shareable domain issued by the CPU are taken into account by the
  SMMU. That includes for example the TLBI IPAS2E1IS from
  __kvm_tlb_flush_vmid_range().

* BTM is enabled globally in the SMMU CR2 register. If we enable BTM for
  host SVA, then it also affects KVM.

* Stage-1 TLB entries in the SMMU have a bit (ASET) saying "this entry
  is private and does not participate in BTM", which we set for private
  SMMU address spaces.

  Annoyingly, the stage-2 TLB entries do not have it. With BTM all VMIDs
  are shared between CPU and SMMU.

* So, if the SMMU driver allocates VMID privately and we enable BTM, then
  CPU invalidations will remove unrelated SMMU TLB entries. Instead, the
  SMMU driver needs to coordinate with KVM on VMID allocation.

* Private stage-2 address spaces in the SMMU would need to allocate VMIDs
  that aren't used by KVM, but that's not a use-case at the moment:

  - For assigning devices to a host process or to a VM, we use private
    stage-1 mappings. stage-2 will be used to enable nesting translation,
    and will typically mirror the KVM stage-2 since it pins the guest
    address space.

  - If the SMMU doesn't support stage-1, the driver falls back to stage-2
    for private address spaces. For such an implementation we disable BTM.

  - The old VFIO_TYPE1_NESTING_IOMMU lets userspace allocate a private
    stage-2, and has only been used for testing as far as I know. I don't
    think I ever found a program that used it in the wild, but haven't
    checked recently.

    The effects of using it with BTM enabled is performance degradation:
    TLB entries of that VFIO container get invalidated by unrelated KVM
    activity, and maybe that can be used in a side-channel attack. 
 
    It needs to be deprecated over a few releases (starting with a
    warning maybe?), and the replacement API shouldn't allow creating a
    stage-2 without a KVM context.

Thanks,
Jean


> 
> An earlier proposal sent out[1] a while back resulted in changing the
> ARM64/KVM VMID allocator similar to the ASID allocator to make it
> better suited for this.
> 
> This RFC adds,
>  -Support for pinned KVM VMID.
>  -Support associating KVM pointer and iommufd ctx.
>  -Changes to domain_alloc_user() to receive a kvm pointer.
>  -Configure SMMUV3 S2 using KVM VMID
>  -Finally enable BTM only if SMMUV3 supports S1 translation. This
>   is to make sure that PAGING domains always use S1 and S2 is only
>   used for nested domains with a valid KVM. The idea is to make sure
>   when BTM is enabled in Guest, we use KVM VMID for S2.
> 
> Not sure I miss any explicit TLB invalidations with any use case
> that may configure a S2 with a private VMID that matches a KVM
> one.
> 
> This is based on Jason's ongoing SMMUv3 refactor series[2].
> 
> Please take a look and let me know.
> 
> Thanks,
> Shameer
> 
> 1. https://lore.kernel.org/linux-arm-kernel/20210222155338.26132-1-shameerali.kolothum.thodi at huawei.com/
> 2. https://lore.kernel.org/linux-arm-kernel/0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg at nvidia.com/
> 
> Jean-Philippe Brucker (1):
>   iommu/arm-smmu-v3: Enable broadcast TLB maintenance
> 
> Shameer Kolothum (6):
>   KVM: Add generic infrastructure to support pinned VMIDs
>   KVM: arm64: Introduce support to pin VMIDs
>   KVM: arm64: Add interfaces for pinned VMID support
>   iommufd: Associate kvm pointer to iommufd ctx
>   iommu: Pass in kvm pointer to domain_alloc_user
>   iommu/arm-smmu-v3: Use KVM VMID for s2 stage
> 
>  arch/arm64/include/asm/kvm_host.h           |  3 +
>  arch/arm64/kvm/Kconfig                      |  1 +
>  arch/arm64/kvm/arm.c                        | 14 ++++
>  arch/arm64/kvm/vmid.c                       | 84 ++++++++++++++++++++-
>  drivers/iommu/amd/iommu.c                   |  1 +
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 42 +++++++++--
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  3 +
>  drivers/iommu/intel/iommu.c                 |  1 +
>  drivers/iommu/iommufd/hw_pagetable.c        |  5 +-
>  drivers/iommu/iommufd/iommufd_private.h     |  3 +
>  drivers/iommu/iommufd/main.c                | 14 ++++
>  drivers/iommu/iommufd/selftest.c            |  1 +
>  drivers/vfio/device_cdev.c                  |  3 +
>  include/linux/iommu.h                       |  3 +-
>  include/linux/iommufd.h                     |  7 ++
>  include/linux/kvm_host.h                    | 18 +++++
>  virt/kvm/Kconfig                            |  3 +
>  virt/kvm/kvm_main.c                         | 23 ++++++
>  18 files changed, 218 insertions(+), 11 deletions(-)
> 
> -- 
> 2.34.1
> 


From jernej.skrabec at gmail.com  Fri Feb  9 04:21:07 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Fri, 09 Feb 2024 13:21:07 +0100
Subject: [PATCH v2 1/2] arm64: dts: allwinner: h616: Add 32K fanout pin
In-Reply-To: <20240209115759.3582869-2-andre.przywara@arm.com>
References: <20240209115759.3582869-1-andre.przywara@arm.com>
 <20240209115759.3582869-2-andre.przywara@arm.com>
Message-ID: <2716822.mvXUDI8C0e@jernej-laptop>

Dne petek, 09. februar 2024 ob 12:57:58 CET je Andre Przywara napisal(a):
> On some boards the designers saved on a 32KHz crystal for some external
> chips, so the SoC has to help out, with providing a 32 KHz clock signal.
> 
> Add a pinctrl group node to allow DT nodes to reference this fanout signal.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From jernej.skrabec at gmail.com  Fri Feb  9 04:21:39 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Fri, 09 Feb 2024 13:21:39 +0100
Subject: [PATCH v2 2/2] arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes
In-Reply-To: <20240209115759.3582869-3-andre.przywara@arm.com>
References: <20240209115759.3582869-1-andre.przywara@arm.com>
 <20240209115759.3582869-3-andre.przywara@arm.com>
Message-ID: <5751321.DvuYhMxLoT@jernej-laptop>

Dne petek, 09. februar 2024 ob 12:57:59 CET je Andre Przywara napisal(a):
> In contrast to other devices using Allwinner SoCs, the Transpeed 8K618-T
> TV box uses a mainline supported WiFi chip: it's Broadcom 4335 compatible,
> packaged by Murata.
> 
> Add the required DT nodes to let DT users know about the SDIO device.
> There is an otherwise empty MMC device node, to receive the MAC address,
> that firmware might want to write in there.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From jernej.skrabec at gmail.com  Fri Feb  9 04:22:36 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Fri, 09 Feb 2024 13:22:36 +0100
Subject: [PATCH v2 2/2] arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes
In-Reply-To: <20240209115759.3582869-3-andre.przywara@arm.com>
References: <20240209115759.3582869-1-andre.przywara@arm.com>
 <20240209115759.3582869-3-andre.przywara@arm.com>
Message-ID: <4894722.31r3eYUQgx@jernej-laptop>

Dne petek, 09. februar 2024 ob 12:57:59 CET je Andre Przywara napisal(a):
> In contrast to other devices using Allwinner SoCs, the Transpeed 8K618-T
> TV box uses a mainline supported WiFi chip: it's Broadcom 4335 compatible,
> packaged by Murata.
> 
> Add the required DT nodes to let DT users know about the SDIO device.
> There is an otherwise empty MMC device node, to receive the MAC address,
> that firmware might want to write in there.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  .../sun50i-h618-transpeed-8k618-t.dts         | 23 +++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> index 8ea1fd41aebaa..7ec4098e707bf 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
> @@ -16,6 +16,7 @@ / {
>  
>  	aliases {
>  		serial0 = &uart0;
> +		ethernet1 = &sdio_wifi;

Ah, this is not sorted alphabetically. I can fix this while applying.

Best regards,
Jernej

>  	};
>  
>  	chosen {
> @@ -39,6 +40,15 @@ reg_vcc3v3: vcc3v3 {
>  		regulator-max-microvolt = <3300000>;
>  		regulator-always-on;
>  	};
> +
> +	wifi_pwrseq: wifi_pwrseq {
> +		compatible = "mmc-pwrseq-simple";
> +		clocks = <&rtc CLK_OSC32K_FANOUT>;
> +		clock-names = "ext_clock";
> +		pinctrl-0 = <&x32clk_fanout_pin>;
> +		pinctrl-names = "default";
> +		reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
> +	};
>  };
>  
>  &ehci0 {
> @@ -60,6 +70,19 @@ &mmc0 {
>  	status = "okay";
>  };
>  
> +&mmc1 {
> +	vmmc-supply = <&reg_dldo1>;
> +	vqmmc-supply = <&reg_aldo1>;
> +	mmc-pwrseq = <&wifi_pwrseq>;
> +	bus-width = <4>;
> +	non-removable;
> +	status = "okay";
> +
> +	sdio_wifi: wifi at 1 {
> +		reg = <1>;
> +	};
> +};
> +
>  &mmc2 {
>  	vmmc-supply = <&reg_dldo1>;
>  	vqmmc-supply = <&reg_aldo1>;
> 






From ulf.hansson at linaro.org  Fri Feb  9 04:38:18 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Fri,  9 Feb 2024 13:38:18 +0100
Subject: [GIT PULL] pmdomain fixes for v6.8-rc4
Message-ID: <20240209123818.768037-1-ulf.hansson@linaro.org>

Hi Linus,

Here's a PR with a couple of pmdomain fixes for v6.8-rc4. Details about the
highlights are as usual found in the signed tag.

Please pull this in!

Kind regards
Ulf Hansson


The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git tags/pmdomain-v6.8-rc1

for you to fetch changes up to c41336f4d69057cbf88fed47951379b384540df5:

  pmdomain: mediatek: fix race conditions with genpd (2024-01-23 13:19:15 +0100)

----------------------------------------------------------------
Core:
 - Move the unused cleanup to a _sync initcall

Providers:
 - mediatek: Fix race conditions at probe/remove with genpd
 - renesas: r8a77980-sysc: CR7 must be always on

----------------------------------------------------------------
Eugen Hristev (1):
      pmdomain: mediatek: fix race conditions with genpd

Geert Uytterhoeven (1):
      pmdomain: renesas: r8a77980-sysc: CR7 must be always on

Konrad Dybcio (1):
      pmdomain: core: Move the unused cleanup to a _sync initcall

 drivers/pmdomain/core.c                    |  2 +-
 drivers/pmdomain/mediatek/mtk-pm-domains.c | 15 +++++++--------
 drivers/pmdomain/renesas/r8a77980-sysc.c   |  3 ++-
 3 files changed, 10 insertions(+), 10 deletions(-)


From krzysztof.kozlowski at linaro.org  Fri Feb  9 04:38:42 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 9 Feb 2024 13:38:42 +0100
Subject: [PATCH 1/1] ARM:dts:aspeed: Initial device tree for AMD Onyx
 Platform
In-Reply-To: <d4fe8b55-a1ea-4ce7-89ac-ce17e8ff4e45@amd.com>
References: <20240110033543.799919-1-supreeth.venkatesh@amd.com>
 <d4fe8b55-a1ea-4ce7-89ac-ce17e8ff4e45@amd.com>
Message-ID: <dda6c22e-8f35-4c18-9fea-6a6295dee3a1@linaro.org>

On 08/02/2024 15:57, Supreeth Venkatesh wrote:
> This patch is pending for a month now.
> 
> Can DT maintainers please help review this and provide feedback?

I don't have the original patch in my inbox anymore, so probably you
should resend. Anyway quick look points to obvious issues (comments below).

> 
> On 1/9/24 21:35, Supreeth Venkatesh wrote:
>> This patch adds initial device tree and makefile updates for
>> AMD Onyx platform.
>>
>> AMD Onyx platform is an AMD customer reference board with an Aspeed
>> ast2600 BMC manufactured by AMD.
>> It describes I2c devices, Fans, Kcs devices, Uarts, Mac, LEDs, etc.
>> present on AMD Onyx platform.
>>
>> Signed-off-by: Supreeth Venkatesh <supreeth.venkatesh at amd.com>
>> ---
>>   arch/arm/boot/dts/aspeed/Makefile             |  1 +
>>   .../boot/dts/aspeed/aspeed-bmc-amd-onyx.dts   | 98 +++++++++++++++++++
>>   2 files changed, 99 insertions(+)
>>   create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts
>>
>> diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
>> index fb9cc95f1b60..2b27d377aae2 100644
>> --- a/arch/arm/boot/dts/aspeed/Makefile
>> +++ b/arch/arm/boot/dts/aspeed/Makefile
>> @@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
>>   	aspeed-ast2600-evb.dtb \
>>   	aspeed-bmc-amd-daytonax.dtb \
>>   	aspeed-bmc-amd-ethanolx.dtb \
>> +	aspeed-bmc-amd-onyx.dtb \
>>   	aspeed-bmc-ampere-mtjade.dtb \
>>   	aspeed-bmc-ampere-mtmitchell.dtb \
>>   	aspeed-bmc-arm-stardragon4800-rep2.dtb \
>> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts
>> new file mode 100644
>> index 000000000000..a7056cd29553
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts
>> @@ -0,0 +1,98 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +// Copyright (c) 2021 - 2024 AMD Inc.
>> +// Author: Supreeth Venkatesh <supreeth.venkatesh at amd.com>
>> +
>> +/dts-v1/;
>> +
>> +#include "aspeed-g6.dtsi"
>> +#include <dt-bindings/gpio/aspeed-gpio.h>
>> +
>> +/ {
>> +       model = "AMD Onyx BMC";
>> +       compatible = "amd,onyx-bmc", "aspeed,ast2600";

Undocumented compatibles.

Please run scripts/checkpatch.pl and fix reported warnings. Some
warnings can be ignored, but the code here looks like it needs a fix.
Feel free to get in touch if the warning is not clear.

>> +
>> +       aliases {
>> +               serial0 = &uart1;
>> +               serial4 = &uart5;
>> +      };
>> +
>> +       chosen {
>> +               stdout-path = &uart5;
>> +               bootargs = "console=ttyS4,115200 earlyprintk vmalloc=512MB";

earlyprintk is debugging, not for mainline, so drop.

Console should be encoded in stdout-path.

vmalloc looks like OS tuning, so also not suitable for mainline DTS.


>> +       };
>> +
>> +       memory at 80000000 {
>> +               device_type = "memory";
>> +               reg = <0x80000000 0x80000000>;
>> +       };
>> +

Drop redundant blank lines.

>> +};
>> +
>> +&mdio0 {
>> +       status = "okay";
>> +
>> +       ethphy0: ethernet-phy at 0 {
>> +               compatible = "ethernet-phy-ieee802.3-c22";
>> +               reg = <0>;
>> +       };
>> +};
>> +
>> +&mac3 {
>> +       status = "okay";
>> +       phy-mode = "rgmii";
>> +       phy-handle = <&ethphy0>;
>> +
>> +       pinctrl-names = "default";
>> +       pinctrl-0 = <&pinctrl_rgmii4_default>;
>> +};
>> +
>> +>> +

Drop redundant blank lines. You can open existing, recent DTS from
maintained platforms like Qcom or TI and look there at coding style.



Best regards,
Krzysztof



From jgg at ziepe.ca  Fri Feb  9 04:48:29 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Fri, 9 Feb 2024 08:48:29 -0400
Subject: [RFC PATCH v2 0/7] iommu/arm-smmu-v3: Use pinned KVM VMID for
 stage 2
In-Reply-To: <20240209115824.GA2922446@myrica>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
 <20240209115824.GA2922446@myrica>
Message-ID: <20240209124829.GB31743@ziepe.ca>

On Fri, Feb 09, 2024 at 11:58:24AM +0000, Jean-Philippe Brucker wrote:

> * Stage-1 TLB entries in the SMMU have a bit (ASET) saying "this entry
>   is private and does not participate in BTM", which we set for private
>   SMMU address spaces.
> 
>   Annoyingly, the stage-2 TLB entries do not have it. With BTM all VMIDs
>   are shared between CPU and SMMU.

Right, the spec justified this decision like this:

 Note: Arm expects that SMMU stage 2 address spaces are generally
 shared with their respective PE virtual machine stage 2
 configuration. If broadcast invalidation is required to be avoided
 for a particular SMMU stage 2 address space, Arm recommends that a
 hypervisor configures the STE with a VMID that is not allocated for
 virtual machine use on the PEs.

Which doesn't match how Linux works and I think after the recent KVM
PUCK call on this topic we can say it does not match how Linux will
work going into the future. Assuming the KVM S2 and IOMMU S2 are
shared is not true.

So unfortuntely this creates a waste as the BTM will generate
worthless invalidation workload on the related IOMMU S2. We cannot do
as the spec suggests to avoid broadcast invalidation here with a
unique VMID as that will break vSVA vBTM invalidation to the S1.

I do wonder how much of a performance negative this will create. At
least the S1 isn't flushed so perhaps the performace hit is
small.

Anyhow, I view it as a defect that the HW doesn't have a BTM ignore
bit at the S2 level so that we can use the same VMID to make vBTM work
but not participate in CPU originated invalidations for a non-shared
S2. A global bit to disable S2 BTM would have been fine for Linux.

>   - The old VFIO_TYPE1_NESTING_IOMMU lets userspace allocate a private
>     stage-2, and has only been used for testing as far as I know. I don't
>     think I ever found a program that used it in the wild, but haven't
>     checked recently.

There isn't, it is useless and cannot do anything. A patch has been
waiting to remove it for a while now, I've got it in my part 3 right
now.

>     It needs to be deprecated over a few releases (starting with a
>     warning maybe?),

No need, we just NOP'd it. It has no user visible side effect,
replacing the S2 with a S1 is fine.

>     and the replacement API shouldn't allow creating a
>     stage-2 without a KVM context.

See my remarks yesterday.

Jason


From andrejs.cainikovs at gmail.com  Fri Feb  9 05:01:06 2024
From: andrejs.cainikovs at gmail.com (Andrejs Cainikovs)
Date: Fri,  9 Feb 2024 14:01:06 +0100
Subject: [PATCH v2] arm64: dts: ti: verdin-am62: add support for Verdin USB1 interface
Message-ID: <20240209130106.38739-1-andrejs.cainikovs@gmail.com>

From: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>

Add support for Verdin USB1 interface, implements role switch
functionality using "gpio-usb-b-connector", VBUS is also now
controlled with "regulator-fixed" using a standard GPIO.

Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
Reviewed-by: Francesco Dolcini <francesco.dolcini at toradex.com>
---
v1:
 - https://lore.kernel.org/all/20240209110500.22193-1-andrejs.cainikovs at gmail.com/
v2:
 - fix GPIO naming as per rest of the file
---
 arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi | 55 +++++++++++++++++-----
 1 file changed, 44 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
index 6a06724b6d16..7e9bdba438b1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
@@ -42,6 +42,22 @@ aliases {
 		usb1 = &usb1;
 	};
 
+	connector {
+		compatible = "gpio-usb-b-connector", "usb-b-connector";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usb0_id>;
+		id-gpios = <&main_gpio1 19 GPIO_ACTIVE_HIGH>;
+		label = "USB_1";
+		self-powered;
+		vbus-supply = <&reg_usb0_vbus>;
+
+		port {
+			usb_dr_connector: endpoint {
+				remote-endpoint = <&usb0_ep>;
+			};
+		};
+	};
+
 	verdin_gpio_keys: gpio-keys {
 		compatible = "gpio-keys";
 		pinctrl-names = "default";
@@ -151,6 +167,18 @@ reg_sdhc1_vqmmc: regulator-sdhci1-vqmmc {
 		vin-supply = <&reg_sd_3v3_1v8>;
 	};
 
+	reg_usb0_vbus: regulator-usb0-vbus {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usb0_en>;
+		enable-active-high;
+		/* Verdin USB_1_EN (SODIMM 155) */
+		gpio = <&main_gpio1 50 GPIO_ACTIVE_HIGH>;
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "USB_1_EN";
+	};
+
 	reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
@@ -436,6 +464,13 @@ AM62X_IOPAD(0x0244, PIN_INPUT_PULLUP, 7) /* (C17) MMC1_SDWP.GPIO1_49 */ /* SODIM
 		>;
 	};
 
+	/* Verdin USB_1_EN */
+	pinctrl_usb0_en: main-gpio1-50-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0254, PIN_INPUT, 7) /* (C20) USB0_DRVVBUS.GPIO1_50 */ /* SODIMM 155 */
+		>;
+	};
+
 	/* On-module I2C - PMIC_I2C */
 	pinctrl_i2c0: main-i2c0-default-pins {
 		pinctrl-single,pins = <
@@ -660,13 +695,6 @@ AM62X_IOPAD(0x0038, PIN_OUTPUT,       5) /* (E24) OSPI0_CSn3.UART5_TXD    */ /*
 		>;
 	};
 
-	/* Verdin USB_1 */
-	pinctrl_usb0: main-usb0-default-pins {
-		pinctrl-single,pins = <
-			AM62X_IOPAD(0x0254, PIN_OUTPUT, 0) /* (C20) USB0_DRVVBUS */ /* SODIMM 155 */
-		>;
-	};
-
 	/* Verdin USB_2 */
 	pinctrl_usb1: main-usb1-default-pins {
 		pinctrl-single,pins = <
@@ -1013,7 +1041,7 @@ &main_gpio1 {
 		"",
 		"",
 		"SODIMM_17",
-		"", /* 50 */
+		"SODIMM_155", /* 50 */
 		"",
 		"",
 		"",
@@ -1428,11 +1456,16 @@ &usbss0 {
 	status = "disabled";
 };
 
-/* TODO: role swich using ID pin */
 &usb0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb0_id>;
+	adp-disable;
+	usb-role-switch;
 	status = "disabled";
+
+	port {
+		usb0_ep: endpoint {
+			remote-endpoint = <&usb_dr_connector>;
+		};
+	};
 };
 
 /* Verdin USB_2 */
-- 
2.34.1



From andrejs.cainikovs at gmail.com  Fri Feb  9 05:02:12 2024
From: andrejs.cainikovs at gmail.com (Andrejs Cainikovs)
Date: Fri,  9 Feb 2024 14:02:12 +0100
Subject: [PATCH v1] arm64: dts: ti: k3-am62-main: disable usb lpm
Message-ID: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>

From: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>

AM62 USB works with some devices, while failing to operate with others.

[  560.189822] xhci-hcd xhci-hcd.4.auto: xHCI Host Controller
[  560.195631] xhci-hcd xhci-hcd.4.auto: new USB bus registered, assigned bus number 2
[  574.388509] xhci-hcd xhci-hcd.4.auto: can't setup: -110
[  574.393814] xhci-hcd xhci-hcd.4.auto: USB bus 2 deregistered
[  574.399544] xhci-hcd: probe of xhci-hcd.4.auto failed with error -110

This seems to be related to LPM (Link Power Management), and disabling it
turns USB into reliable working state.

As per AM62 reference manual:

> 4.8.2.1 USB2SS Unsupported Features
>
> The following features are not supported on this family of devices:
> ...
> - USB 2.0 ECN: Link Power Management (LPM)
> ...

Fixes: 2240f96cf3cd ("arm64: dts: ti: k3-am62-main: Add support for USB")
Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 464b7565d085..c49fbce5cb70 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -640,6 +640,8 @@ usb0: usb at 31000000 {
 			interrupt-names = "host", "peripheral";
 			maximum-speed = "high-speed";
 			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
 		};
 	};
 
@@ -663,6 +665,8 @@ usb1: usb at 31100000 {
 			interrupt-names = "host", "peripheral";
 			maximum-speed = "high-speed";
 			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
 		};
 	};
 
-- 
2.34.1



From linus.walleij at linaro.org  Fri Feb  9 05:02:23 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 9 Feb 2024 14:02:23 +0100
Subject: [PATCH 1/1] ARM: dts: vexpress: Set stdout-path to serial0 in the
 chosen node
In-Reply-To: <20240209112807.1345164-2-ole.orhagen@northern.tech>
References: <20240209112807.1345164-2-ole.orhagen@northern.tech>
Message-ID: <CACRpkda=b-uZmSfqRLkkC6Lp-JbSoi+YZpwhVn9-RMOPxiXszA@mail.gmail.com>

On Fri, Feb 9, 2024 at 12:29?PM Ole P. Orhagen
<ole.orhagen at northern.tech> wrote:

> Specify v2m_serial0 as the device for boot console output through the
> stdout-path in the chosen node.
>
> Signed-off-by: Ole P. Orhagen <ole.orhagen at northern.tech>

It's also the right way to do it.
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Sudeep: are you queueing Vexpress DTS changes or do you want me
to handle it with other Versatile-ish ARM DTS stuff?

Yours,
Linus Walleij


From ardb at kernel.org  Fri Feb  9 05:18:59 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 9 Feb 2024 13:18:59 +0000
Subject: [PATCH v7 00/50] arm64: Add support for LPA2 and WXN at stage 1
In-Reply-To: <20240123145258.1462979-52-ardb+git@google.com>
References: <20240123145258.1462979-52-ardb+git@google.com>
Message-ID: <CAMj1kXHdUy38a6y3Qy6PMuMqCsvZtHTpHk1Z5QyNO9byfmxVwQ@mail.gmail.com>

On Tue, 23 Jan 2024 at 14:54, Ard Biesheuvel <ardb+git at google.com> wrote:
>
> From: Ard Biesheuvel <ardb at kernel.org>
>
> This v7 covers the remaining changes that implement support for LPA2 and
> WXN at stage 1, now that some of the prerequisites are in place.
>
> Ryan's KVM series for LPA2 at stage 2 has been merged in the mean time,
> so the temporary changes to plug that hole have been dropped.
>

... and I ended up dropping a patch that is still required:

https://lore.kernel.org/all/20230912141549.278777-119-ardb at google.com/

which requires some minimal rebasing as well. I am not going to resend
the whole series because of the single patch until it gains some more
review traction.


-- 
Ard.


From lee at kernel.org  Fri Feb  9 05:28:37 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 9 Feb 2024 13:28:37 +0000
Subject: [PATCH 0/6] mfd: tmio: simplify header and move to platform_data
In-Reply-To: <CAPDyKFpmfgwJ5dJFmORhg1tBewzhB_jrWikpX=b23r-joN91SA@mail.gmail.com>
References: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
 <CAPDyKFpmfgwJ5dJFmORhg1tBewzhB_jrWikpX=b23r-joN91SA@mail.gmail.com>
Message-ID: <20240209132837.GJ689448@google.com>

On Fri, 09 Feb 2024, Ulf Hansson wrote:

> On Fri, 9 Feb 2024 at 02:59, Wolfram Sang
> <wsa+renesas at sang-engineering.com> wrote:
> >
> > The MFD parts of the TMIO have been removed by Arnd, so that only the
> > SD/MMC related functionality is left. Remove the outdated remains in the
> > public header file and then move it to platform_data as the data is now
> > specific for the SD/MMC part.
> >
> > Based on 6.8-rc3, build bot is happy. Branch is here:
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/sdhi/tmio-simplification
> >
> > I'd suggest this goes via the MFD tree, so the series would need acks
> > from the MMC and SH maintainers. Is that okay with everyone?
> 
> Wouldn't it be better to funnel this via the mmc tree? In that way, we
> can easily avoid conflicts with additional renesas-mmc driver changes
> that we have in pipe.

You could say the same about changes SH, MFD and Platform Data have in
the pipe.

> Or perhaps there are other changes that make the mfd tree preferred?

MFD is usually preferred since the parent device usually lives there and
we are well accustomed to merging multi-subsystem related sets.

It doesn't really matter how this is merged.  The only stipulation is
that whoever applies the set does so on a succinct, immutable, tagged
branch and sends out a pull-request for everyone else to pull from.

If you want to do that, there are no complains from me.

> > All the best!
> >
> >    Wolfram
> >
> >
> > Wolfram Sang (6):
> >   mfd: tmio: remove obsolete platform_data
> >   mfd: tmio: remove obsolete io accessors
> >   mmc: tmio/sdhi: fix includes
> >   mfd: tmio: update include files
> >   mfd: tmio: sanitize comments
> >   mfd: tmio: move header to platform_data
> >
> >  MAINTAINERS                                   |   2 +-
> >  arch/sh/boards/board-sh7757lcr.c              |   2 +-
> >  arch/sh/boards/mach-ap325rxa/setup.c          |   2 +-
> >  arch/sh/boards/mach-ecovec24/setup.c          |   2 +-
> >  arch/sh/boards/mach-kfr2r09/setup.c           |   2 +-
> >  arch/sh/boards/mach-migor/setup.c             |   2 +-
> >  arch/sh/boards/mach-se/7724/setup.c           |   2 +-
> >  drivers/mmc/host/renesas_sdhi_core.c          |   2 +-
> >  drivers/mmc/host/renesas_sdhi_internal_dmac.c |   5 +-
> >  drivers/mmc/host/renesas_sdhi_sys_dmac.c      |   5 +-
> >  drivers/mmc/host/tmio_mmc_core.c              |   3 +-
> >  drivers/mmc/host/uniphier-sd.c                |   2 +-
> >  include/linux/mfd/tmio.h                      | 133 ------------------
> >  include/linux/platform_data/tmio.h            |  64 +++++++++
> >  14 files changed, 81 insertions(+), 147 deletions(-)
> >  delete mode 100644 include/linux/mfd/tmio.h
> >  create mode 100644 include/linux/platform_data/tmio.h
> >
> > --
> > 2.43.0
> >
> >

-- 
Lee Jones [???]


From acme at kernel.org  Fri Feb  9 05:30:59 2024
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Fri, 9 Feb 2024 10:30:59 -0300
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <4688a613-c94a-49b0-9d0f-09173c64082d@arm.com>
References: <20240208032518.25830-1-yangyicong@huawei.com>
 <CAM9d7cga2rzcpUCa+5sZKQ3g_nC5=5XhSdkX1bRCQQUJca8uSw@mail.gmail.com>
 <4688a613-c94a-49b0-9d0f-09173c64082d@arm.com>
Message-ID: <ZcYpE35VxRClBP_W@x1>

On Fri, Feb 09, 2024 at 10:59:04AM +0000, Robin Murphy wrote:
> On 2024-02-08 11:58 pm, Namhyung Kim wrote:
> > On Wed, Feb 7, 2024 at 7:29?PM Yicong Yang <yangyicong at huawei.com> wrote:
> > > From: Yicong Yang <yangyicong at hisilicon.com>
> > > Some HiSilicon platforms provide PCIe PMU devices for monitoring the
> > > throughput and latency of PCIe traffic. With the support of PCIe PMU
> > > we can enable the perf iostat mode.

> > Hmm.. so it only works for HiSilicon.  What if users run it on a different
> > platform?
 
> Same thing as if they run it on an AMD or older Intel platform ;)
 
> >  I think ARM should care about this.
 
> Arm don't make PCIe root ports, and there is no PMU standardisation between
> all the myriad different implementers and vendors of PCIe IP, so the best
> perf can reasonably do is simply support the particular PMUs that people
> want perf to support.

yeah, that will make perf more useful to more people, which is good.

And it is reusing something we did in the past for a similar mode on
Intel, from what I remember and by looking at:

---------------------------
commit f9ed693e8bc0e7de9eb766a3c7178590e8bb6cd5
Author: Alexander Antonov <alexander.antonov at linux.intel.com>
Date:   Mon Apr 19 12:41:46 2021 +0300

    perf stat: Enable iostat mode for x86 platforms

    This functionality is based on recently introduced sysfs attributes for
    Intel? Xeon? Scalable processor family (code name Skylake-SP):

    Commit bb42b3d39781d7fc ("perf/x86/intel/uncore: Expose an Uncore unit to IIO PMON mapping")

    Mode is intended to provide four I/O performance metrics in MB per each
    PCIe root port:

     - Inbound Read: I/O devices below root port read from the host memory
     - Inbound Write: I/O devices below root port write to the host memory
     - Outbound Read: CPU reads from I/O devices below root port
     - Outbound Write: CPU writes to I/O devices below root port

    Each metric requiries only one uncore event which increments at every 4B
    transfer in corresponding direction. The formulas to compute metrics
    are generic:
        #EventCount * 4B / (1024 * 1024)
---------------------------

And tools/perf/perf-iostat.sh.

Right?

- Arnaldo


From acme at kernel.org  Fri Feb  9 05:47:56 2024
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Fri, 9 Feb 2024 10:47:56 -0300
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <20240208032518.25830-1-yangyicong@huawei.com>
References: <20240208032518.25830-1-yangyicong@huawei.com>
Message-ID: <ZcYtDHLr6NQ-BFbx@x1>

On Thu, Feb 08, 2024 at 11:25:18AM +0800, Yicong Yang wrote:
> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
> throughput and latency of PCIe traffic. With the support of PCIe PMU
> we can enable the perf iostat mode.
> 
> The HiSilicon PCIe PMU can support measuring the throughput of certain
> TLP types and of certain root port. Totally 6 metrics are provided in
> the unit of MB:
> 
> - Inbound MWR: The memory write TLPs from the devices downstream the root port
> - Inbound MRD: The memory read TLPs from the devices downstream the root port
> - Inbound CPL: The completion TLPs from the devices downstream the root port
> - Outbound MWR: The memory write TLPs from the CPU to the downstream devices
> - Outbound MRD: The memory read TLPs from the CPU to the downstream devices
> - Outbound CPL: The completions TLPs from the CPU to the downstream devices
> 
> Since the PMU measures the throughput in DWords. So we need to calculate
> the throughput in MB like:
>   Count * 4B / 1024 / 1024
> 
> Some of the display of the `perf iostat` will be like:
> [root at localhost tmp]# ./perf iostat list
> hisi_pcie0_core2<0000:40:00.0>
> hisi_pcie2_core2<0000:5f:00.0>
> hisi_pcie0_core1<0000:16:00.0>
> hisi_pcie0_core1<0000:16:04.0>
> [root at localhost tmp]# ./perf iostat --timeout 10000
> 
>  Performance counter stats for 'system wide':
> 
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
> 
>       10.008227512 seconds time elapsed
> 
> [root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
> -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
> -norandommap -group_reporting -runtime=10 -time_based -bs=64k
> 
>  Performance counter stats for 'system wide':
> 
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
> 
>       10.168561767 seconds time elapsed
> 
>        0.465373000 seconds user
>        1.952948000 seconds sys
> 
> More information of the HiSilicon PCIe PMU can be found at
> Documentation/admin-guide/perf/hisi-pcie-pmu.rst.
> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
> Change since v1:
> - Tweak the comments per Jonathan
> - Use an enum to define the metrics and relevant command templates per Jonathan
> Thanks!
> Link: https://lore.kernel.org/linux-perf-users/20240123071201.30914-1-yangyicong at huawei.com/
> 
>  tools/perf/arch/arm64/util/Build         |   1 +
>  tools/perf/arch/arm64/util/hisi-iostat.c | 439 +++++++++++++++++++++++
>  2 files changed, 440 insertions(+)
>  create mode 100644 tools/perf/arch/arm64/util/hisi-iostat.c
> 
> diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
> index 78ef7115be3d..4e8dabf98b29 100644
> --- a/tools/perf/arch/arm64/util/Build
> +++ b/tools/perf/arch/arm64/util/Build
> @@ -3,6 +3,7 @@ perf-y += machine.o
>  perf-y += perf_regs.o
>  perf-y += tsc.o
>  perf-y += pmu.o
> +perf-y += hisi-iostat.o
>  perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
>  perf-$(CONFIG_DWARF)     += dwarf-regs.o
>  perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
> diff --git a/tools/perf/arch/arm64/util/hisi-iostat.c b/tools/perf/arch/arm64/util/hisi-iostat.c
> new file mode 100644
> index 000000000000..43df43b83f3f
> --- /dev/null
> +++ b/tools/perf/arch/arm64/util/hisi-iostat.c
> @@ -0,0 +1,439 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * perf iostat support for HiSilicon PCIe PMU.
> + * Partly derived from tools/perf/arch/x86/util/iostat.c.
> + *
> + * Copyright (c) 2024 HiSilicon Technologies Co., Ltd.
> + * Author: Yicong Yang <yangyicong at hisilicon.com>
> + */
> +
> +#include <api/fs/fs.h>
> +#include <linux/err.h>
> +#include <linux/zalloc.h>
> +#include <linux/limits.h>
> +#include <dirent.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <stdint.h>
> +#include <stdlib.h>
> +
> +#include "util/counts.h"
> +#include "util/cpumap.h"
> +#include "util/debug.h"
> +#include "util/iostat.h"
> +#include "util/pmu.h"
> +
> +#define PCI_DEFAULT_DOMAIN		0
> +#define PCI_DEVICE_NAME_PATTERN		"%04x:%02hhx:%02hhx.%hhu"
> +#define PCI_ROOT_BUS_DEVICES_PATH	"bus/pci/devices"
> +
> +enum hisi_iostat_metric_type {
> +	METRIC_IN_MWR,		/* Inbound Memory Write */
> +	METRIC_IN_MRD,		/* Inbound Memory Read */
> +	METRIC_IN_CPL,		/* Inbound Memory Completion */
> +	METRIC_OUT_MWR,		/* Outbound Memory Write */
> +	METRIC_OUT_MRD,		/* Outbound Memory Read */
> +	METRIC_OUT_CPL,		/* Outbound Memory Completion */
> +	METRIC_TYPE_MAX,
> +};
> +
> +static const char * const hisi_iostat_metrics[] = {
> +	[METRIC_IN_MWR] = "Inbound MWR(MB)",
> +	[METRIC_IN_MRD] = "Inbound MRD(MB)",
> +	[METRIC_IN_CPL] = "Inbound CPL(MB)",
> +	[METRIC_OUT_MWR] = "Outbound MWR(MB)",
> +	[METRIC_OUT_MRD] = "Outbound MRD(MB)",
> +	[METRIC_OUT_CPL] = "Outbound CPL(MB)",
> +};
> +
> +static const char * const hisi_iostat_cmd_template[] = {
> +	[METRIC_IN_MWR] = "hisi_pcie%hu_core%hu/event=0x0104,port=0x%hx/",
> +	[METRIC_IN_MRD] = "hisi_pcie%hu_core%hu/event=0x0804,port=0x%hx/",
> +	[METRIC_IN_CPL] = "hisi_pcie%hu_core%hu/event=0x2004,port=0x%hx/",
> +	[METRIC_OUT_MWR] = "hisi_pcie%hu_core%hu/event=0x0105,port=0x%hx/",
> +	[METRIC_OUT_MRD] = "hisi_pcie%hu_core%hu/event=0x0405,port=0x%hx/",
> +	[METRIC_OUT_CPL] = "hisi_pcie%hu_core%hu/event=0x1005,port=0x%hx/",
> +};
> +
> +struct hisi_pcie_root_port {
> +	struct list_head list;
> +	/* Is this Root Port selected for monitoring */
> +	bool selected;
> +	/* IDs to locate the PMU */
> +	u16 sicl_id;
> +	u16 core_id;
> +	/* Filter mask for this Root Port */
> +	u16 mask;
> +	/* PCIe Root Port's <domain>:<bus>:<device>.<function> */
> +	u32 domain;
> +	u8 bus;
> +	u8 dev;
> +	u8 fn;
> +};
> +
> +LIST_HEAD(hisi_pcie_root_ports_list);
> +static int hisi_pcie_root_ports_num;
> +
> +static void hisi_pcie_init_root_port_mask(struct hisi_pcie_root_port *rp)
> +{
> +	rp->mask = BIT(rp->dev << 1);
> +}
> +
> +/*
> + * Select specific Root Port to monitor. Return 0 if successfully find the
> + * Root Port, Otherwise -EINVAL.
> + */
> +static int hisi_pcie_root_ports_select_one(u32 domain, u8 bus, u8 dev, u8 fn)
> +{
> +	struct hisi_pcie_root_port *rp;
> +
> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list)
> +		if (domain == rp->domain && bus == rp->bus &&
> +		    dev == rp->dev && fn == rp->fn) {
> +			rp->selected = true;
> +			return 0;
> +		}
> +
> +	return -EINVAL;
> +}
> +
> +static void hisi_pcie_root_ports_select_all(void)
> +{
> +	struct hisi_pcie_root_port *rp;
> +
> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list)
> +		rp->selected = true;
> +}
> +
> +static void hisi_pcie_root_ports_add(u16 sicl_id, u16 core_id, u8 target_bus)
> +{
> +	const char *sysfs = sysfs__mountpoint();
> +	struct hisi_pcie_root_port *rp;
> +	struct dirent *dent;
> +	char path[PATH_MAX];
> +	u8 bus, dev, fn;
> +	u32 domain;
> +	DIR *dir;
> +	int ret;
> +
> +	snprintf(path, PATH_MAX, "%s/%s", sysfs, PCI_ROOT_BUS_DEVICES_PATH);
> +	dir = opendir(path);
> +	if (!dir)
> +		return;
> +
> +	/* Scan the PCI root bus to find the match root port on @target_bus */
> +	while ((dent = readdir(dir))) {
> +		ret = sscanf(dent->d_name, PCI_DEVICE_NAME_PATTERN,
> +			     &domain, &bus, &dev, &fn);
> +		if (ret != 4 || bus != target_bus)
> +			continue;
> +
> +		rp = zalloc(sizeof(*rp));
> +		if (!rp)
> +			continue;

shouldn't it emit some pr_debug message? Like you did with that
pr_debug3() info message below.

> +
> +		rp->selected = false;
> +		rp->sicl_id = sicl_id;
> +		rp->core_id = core_id;
> +		rp->domain = domain;
> +		rp->bus = bus;
> +		rp->dev = dev;
> +		rp->fn = fn;
> +
> +		hisi_pcie_init_root_port_mask(rp);
> +
> +		list_add(&rp->list, &hisi_pcie_root_ports_list);
> +		hisi_pcie_root_ports_num++;
> +
> +		pr_debug3("Found root port %s\n", dent->d_name);
> +	}
> +
> +	closedir(dir);
> +}
> +
> +/* Scan the PMUs and build the mapping of the Root Ports to the PMU */
> +static int hisi_pcie_root_ports_init(void)
> +{
> +	char event_source[PATH_MAX], bus_path[PATH_MAX];
> +	unsigned long long bus;
> +	u16 sicl_id, core_id;
> +	struct dirent *dent;
> +	DIR *dir;
> +
> +	perf_pmu__event_source_devices_scnprintf(event_source, sizeof(event_source));
> +	dir = opendir(event_source);
> +	if (!dir)
> +		return -ENOENT;

Is this the only possibility? I.e. if a non root user tries this and the
file is there, shouldn't we inform that root permission is needed? Or
any other access mechanism that may be used.

For instance, in perf we have things like kernel.perf_event_paranoid,
capabilities, etc.

Take a look at the evsel__open_strerror() function, to see how it tries
to translate errors like the above to an informative message to help the
user setup its system.

> +
> +	while ((dent = readdir(dir))) {
> +		/*
> +		 * This HiSilicon PCIe PMU will be named as:
> +		 *   hisi_pcie<sicl_id>_core<core_id>
> +		 */
> +		if ((sscanf(dent->d_name, "hisi_pcie%hu_core%hu", &sicl_id, &core_id)) != 2)
> +			continue;
> +
> +		/*
> +		 * Driver will export the root port it can monitor through
> +		 * the "bus" sysfs attribute.
> +		 */
> +		scnprintf(bus_path, sizeof(bus_path), "%s/hisi_pcie%hu_core%hu/bus",
> +			  event_source, sicl_id, core_id);
> +
> +		/*
> +		 * Per PCIe spec the bus should be 8bit, use unsigned long long
> +		 * for the convience of the library function.
> +		 */
> +		if (filename__read_ull(bus_path, &bus))

Shouldn't we have a pr_debug3() here as well?

> +			continue;

> +
> +		pr_debug3("Found pmu %s bus 0x%llx\n", dent->d_name, bus);
> +
> +		hisi_pcie_root_ports_add(sicl_id, core_id, (u8)bus);
> +	}
> +
> +	closedir(dir);
> +	return hisi_pcie_root_ports_num > 0 ? 0 : -ENOENT;
> +}
> +
> +static void hisi_pcie_root_ports_free(void)
> +{
> +	struct hisi_pcie_root_port *rp, *tmp;
> +
> +	if (hisi_pcie_root_ports_num == 0)
> +		return;
> +
> +	list_for_each_entry_safe(rp, tmp, &hisi_pcie_root_ports_list, list) {
> +		list_del(&rp->list);

list_del_init()

> +		zfree(&rp);

No need to use zfree here, its a local variable, not something that is
in a data structure that may have some dangling connection somewhere and
thus we better initialize to zero instead of reading random deleted
memory.

> +		hisi_pcie_root_ports_num--;
> +	}
> +}
> +
> +static int hisi_iostat_add_events(struct evlist *evl)
> +{
> +	struct hisi_pcie_root_port *rp;
> +	struct evsel *evsel;
> +	unsigned int i, j;
> +	char *iostat_cmd;
> +	int pos = 0;
> +	int ret;
> +
> +	if (!hisi_pcie_root_ports_num)
> +		return -ENOENT;
> +
> +	iostat_cmd = zalloc(PATH_MAX);
> +	if (!iostat_cmd)
> +		return -ENOMEM;
> +
> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list) {
> +		if (!rp->selected)
> +			continue;
> +
> +		iostat_cmd[pos++] = '{';
> +		for (j = 0; j < METRIC_TYPE_MAX; j++) {
> +			pos += snprintf(iostat_cmd + pos, ARG_MAX - pos - 1,
> +					hisi_iostat_cmd_template[j],
> +					rp->sicl_id, rp->core_id, rp->mask);
> +
> +			if (j == METRIC_TYPE_MAX - 1)
> +				iostat_cmd[pos++] = '}';
> +			else
> +				iostat_cmd[pos++] = ',';
> +		}
> +
> +		ret = parse_event(evl, iostat_cmd);
> +		if (ret)

pr_debug3()?

> +			break;
> +
> +		i = 0;
> +		evlist__for_each_entry_reverse(evl, evsel) {
> +			if (i == METRIC_TYPE_MAX)
> +				break;
> +
> +			evsel->priv = rp;
> +			i++;
> +		}
> +
> +		memset(iostat_cmd, 0, PATH_MAX);
> +		pos = 0;
> +	}
> +
> +	zfree(&iostat_cmd);

no need for zfree here, again its a local variable.

> +	return ret;
> +}
> +
> +int iostat_prepare(struct evlist *evlist,
> +		   struct perf_stat_config *config)
> +{
> +	if (evlist->core.nr_entries > 0) {
> +		pr_warning("The -e and -M options are not supported."
> +			   "All chosen events/metrics will be dropped\n");
> +		evlist__delete(evlist);
> +		evlist = evlist__new();
> +		if (!evlist)
> +			return -ENOMEM;

Can you explain how this works? Shouldn't we just bail out completely
instead of creating an empty evlist?

> +	}
> +
> +	config->metric_only = true;
> +	config->aggr_mode = AGGR_GLOBAL;
> +
> +	return hisi_iostat_add_events(evlist);
> +}
> +
> +static int hisi_pcie_root_ports_list_filter(const char *str)
> +{
> +	char *tok, *tmp, *copy = NULL;
> +	u8 bus, dev, fn;
> +	u32 domain;
> +	int ret;
> +
> +	copy = strdup(str);
> +	if (!copy)
> +		return -ENOMEM;
> +
> +	for (tok = strtok_r(copy, ",", &tmp); tok; tok = strtok_r(NULL, ",", &tmp)) {
> +		ret = sscanf(tok, PCI_DEVICE_NAME_PATTERN, &domain, &bus, &dev, &fn);
> +		if (ret != 4) {
> +			ret = -EINVAL;
> +			break;
> +		}
> +
> +		ret = hisi_pcie_root_ports_select_one(domain, bus, dev, fn);
> +		if (ret)
> +			break;
> +	}
> +
> +	zfree(&copy);

No need for zfree()

> +	return ret;
> +}
> +
> +int iostat_parse(const struct option *opt, const char *str, int unset __maybe_unused)
> +{
> +	struct perf_stat_config *config = (struct perf_stat_config *)opt->data;
> +	int ret;
> +
> +	ret = hisi_pcie_root_ports_init();
> +	if (!ret) {
> +		config->iostat_run = true;
> +
> +		if (!str) {
> +			iostat_mode = IOSTAT_RUN;
> +			hisi_pcie_root_ports_select_all();
> +		} else if (!strcmp(str, "list")) {
> +			iostat_mode = IOSTAT_LIST;
> +			hisi_pcie_root_ports_select_all();
> +		} else {
> +			iostat_mode = IOSTAT_RUN;
> +			ret = hisi_pcie_root_ports_list_filter(str);
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static void hisi_pcie_root_port_show(FILE *output,
> +				     const struct hisi_pcie_root_port * const rp)
> +{
> +	if (output && rp)
> +		fprintf(output, "hisi_pcie%hu_core%hu<" PCI_DEVICE_NAME_PATTERN ">\n",
> +			rp->sicl_id, rp->core_id, rp->domain, rp->bus, rp->dev, rp->fn);

Multi line if blocks should be enclosed in {}

> +}
> +
> +void iostat_list(struct evlist *evlist __maybe_unused, struct perf_stat_config *config)
> +{
> +	struct hisi_pcie_root_port *rp = NULL;
> +	struct evsel *evsel;
> +
> +	evlist__for_each_entry(evlist, evsel) {

Can you add a comment explaining this evsel->priv check? Probably we
have multiple ports and some are shared with multiple evsels and we
don't have a ports list, so we reuse the evsel list, etc.

Having a comment with the above info may help future reviewers?

> +		if (rp != evsel->priv) {
> +			hisi_pcie_root_port_show(config->output, evsel->priv);
> +			rp = evsel->priv;
> +		}
> +	}
> +}
> +
> +void iostat_release(struct evlist *evlist)
> +{
> +	struct evsel *evsel;
> +
> +	evlist__for_each_entry(evlist, evsel)
> +		evsel->priv = NULL;
> +

But then here you zero out all the privs and still can iterate the list
of ports in the following function:

> +	hisi_pcie_root_ports_free();

Why not iterate on hisi_pcie_root_ports_list in iostat_list()?

> +}
> +
> +void iostat_print_header_prefix(struct perf_stat_config *config)
> +{
> +	if (config->csv_output)
> +		fputs("port,", config->output);
> +	else if (config->interval)
> +		fprintf(config->output, "#          time    port         ");
> +	else
> +		fprintf(config->output, "   port         ");
> +}
> +
> +void iostat_print_metric(struct perf_stat_config *config, struct evsel *evsel,
> +			 struct perf_stat_output_ctx *out)
> +{
> +	struct perf_counts_values *count;
> +	const char *iostat_metric;
> +	double iostat_value;
> +
> +	iostat_metric = hisi_iostat_metrics[evsel->core.idx % METRIC_TYPE_MAX];
> +
> +	/* We're using AGGR_GLOBAL so there's only one aggr counts aggr[0]. */
> +	count = &evsel->stats->aggr[0].counts;
> +
> +	/* The counts has been scaled, we can use it directly. */
> +	iostat_value = (double)count->val;
> +
> +	/*
> +	 * Calculate the bandwidth in MiB since the PMU counts in DWord.
> +	 * Display two digits after decimal point for better accuracy if the
> +	 * value is non-zero.
> +	 */
> +	out->print_metric(config, out->ctx, NULL,
> +			  iostat_value > 0 ? "%8.2f" : "%8.0f", iostat_metric,
> +			  iostat_value * sizeof(uint32_t) / (1024 * 1024));
> +}
> +
> +void iostat_prefix(struct evlist *evlist, struct perf_stat_config *config,
> +		   char *prefix, struct timespec *ts)
> +{
> +	struct hisi_pcie_root_port *rp = evlist->selected->priv;
> +
> +	if (rp) {
> +		if (ts)
> +			sprintf(prefix, "%6lu.%09lu%s" PCI_DEVICE_NAME_PATTERN "%s",

Can you use scnprintf? and pass the size of prefix to iostat_prefix()?

> +				ts->tv_sec, ts->tv_nsec, config->csv_sep,
> +				rp->domain, rp->bus, rp->dev, rp->fn,
> +				config->csv_sep);
> +		else
> +			sprintf(prefix, PCI_DEVICE_NAME_PATTERN "%s",
> +				rp->domain, rp->bus, rp->dev, rp->fn,
> +				config->csv_sep);
> +	}
> +}
> +
> +void iostat_print_counters(struct evlist *evlist, struct perf_stat_config *config,
> +			   struct timespec *ts, char *prefix,
> +			   iostat_print_counter_t print_cnt_cb, void *arg)
> +{
> +	struct evsel *counter = evlist__first(evlist);
> +	void *perf_device;
> +
> +	evlist__set_selected(evlist, counter);
> +	iostat_prefix(evlist, config, prefix, ts);
> +	fprintf(config->output, "%s", prefix);
> +	evlist__for_each_entry(evlist, counter) {
> +		perf_device = evlist->selected->priv;
> +		if (perf_device && perf_device != counter->priv) {
> +			evlist__set_selected(evlist, counter);
> +			iostat_prefix(evlist, config, prefix, ts);
> +			fprintf(config->output, "\n%s", prefix);
> +		}
> +		print_cnt_cb(config, counter, arg);
> +	}
> +	fputc('\n', config->output);
> +}
> -- 
> 2.24.0
> 


From leo.yan at linux.dev  Fri Feb  9 05:51:44 2024
From: leo.yan at linux.dev (Leo Yan)
Date: Fri, 9 Feb 2024 21:51:44 +0800
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <20240208032518.25830-1-yangyicong@huawei.com>
References: <20240208032518.25830-1-yangyicong@huawei.com>
Message-ID: <20240209135144.GA1498@debian-dev>

Hi Yicong,

On Thu, Feb 08, 2024 at 11:25:18AM +0800, Yicong Yang wrote:
> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
> throughput and latency of PCIe traffic. With the support of PCIe PMU
> we can enable the perf iostat mode.
> 
> The HiSilicon PCIe PMU can support measuring the throughput of certain
> TLP types and of certain root port. Totally 6 metrics are provided in
> the unit of MB:
> 
> - Inbound MWR: The memory write TLPs from the devices downstream the root port

I have no sufficient knowledge for PCI, but this description and below
2 lines are not clear for me. Should not it be: "The memory write TLPs
from the downstream devices to the root port"?

> - Inbound MRD: The memory read TLPs from the devices downstream the root port
> - Inbound CPL: The completion TLPs from the devices downstream the root port
> - Outbound MWR: The memory write TLPs from the CPU to the downstream devices
> - Outbound MRD: The memory read TLPs from the CPU to the downstream devices
> - Outbound CPL: The completions TLPs from the CPU to the downstream devices
> 
> Since the PMU measures the throughput in DWords. So we need to calculate
> the throughput in MB like:
>   Count * 4B / 1024 / 1024
> 
> Some of the display of the `perf iostat` will be like:
> [root at localhost tmp]# ./perf iostat list
> hisi_pcie0_core2<0000:40:00.0>
> hisi_pcie2_core2<0000:5f:00.0>
> hisi_pcie0_core1<0000:16:00.0>
> hisi_pcie0_core1<0000:16:04.0>
> [root at localhost tmp]# ./perf iostat --timeout 10000
> 
>  Performance counter stats for 'system wide':
> 
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
> 
>       10.008227512 seconds time elapsed
> 
> [root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
> -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
> -norandommap -group_reporting -runtime=10 -time_based -bs=64k
> 
>  Performance counter stats for 'system wide':
> 
>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
> 0000:40:00.0                    0                    0                    0                    0                    0                    0
> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
> 0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
> 0000:16:04.0                    0                    0                    0                    0                    0                    0
> 
>       10.168561767 seconds time elapsed
> 
>        0.465373000 seconds user
>        1.952948000 seconds sys

The command has specified the PCI port "0000:16:00.0", it still outputs
stats for 'system wide'. And it also outputs results for other ports.
This is confused.

> More information of the HiSilicon PCIe PMU can be found at
> Documentation/admin-guide/perf/hisi-pcie-pmu.rst.
> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> ---
> Change since v1:
> - Tweak the comments per Jonathan
> - Use an enum to define the metrics and relevant command templates per Jonathan
> Thanks!
> Link: https://lore.kernel.org/linux-perf-users/20240123071201.30914-1-yangyicong at huawei.com/
> 
>  tools/perf/arch/arm64/util/Build         |   1 +
>  tools/perf/arch/arm64/util/hisi-iostat.c | 439 +++++++++++++++++++++++
>  2 files changed, 440 insertions(+)
>  create mode 100644 tools/perf/arch/arm64/util/hisi-iostat.c
> 
> diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
> index 78ef7115be3d..4e8dabf98b29 100644
> --- a/tools/perf/arch/arm64/util/Build
> +++ b/tools/perf/arch/arm64/util/Build
> @@ -3,6 +3,7 @@ perf-y += machine.o
>  perf-y += perf_regs.o
>  perf-y += tsc.o
>  perf-y += pmu.o
> +perf-y += hisi-iostat.o
>  perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
>  perf-$(CONFIG_DWARF)     += dwarf-regs.o
>  perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
> diff --git a/tools/perf/arch/arm64/util/hisi-iostat.c b/tools/perf/arch/arm64/util/hisi-iostat.c
> new file mode 100644
> index 000000000000..43df43b83f3f
> --- /dev/null
> +++ b/tools/perf/arch/arm64/util/hisi-iostat.c
> @@ -0,0 +1,439 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * perf iostat support for HiSilicon PCIe PMU.
> + * Partly derived from tools/perf/arch/x86/util/iostat.c.
> + *
> + * Copyright (c) 2024 HiSilicon Technologies Co., Ltd.
> + * Author: Yicong Yang <yangyicong at hisilicon.com>
> + */
> +
> +#include <api/fs/fs.h>
> +#include <linux/err.h>
> +#include <linux/zalloc.h>
> +#include <linux/limits.h>
> +#include <dirent.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <stdint.h>
> +#include <stdlib.h>

It's good to alphabet ordered for headers.

> +
> +#include "util/counts.h"
> +#include "util/cpumap.h"
> +#include "util/debug.h"
> +#include "util/iostat.h"
> +#include "util/pmu.h"
> +
> +#define PCI_DEFAULT_DOMAIN		0

The macro is not used at all, remove it.

> +#define PCI_DEVICE_NAME_PATTERN		"%04x:%02hhx:%02hhx.%hhu"
> +#define PCI_ROOT_BUS_DEVICES_PATH	"bus/pci/devices"
> +
> +enum hisi_iostat_metric_type {
> +	METRIC_IN_MWR,		/* Inbound Memory Write */
> +	METRIC_IN_MRD,		/* Inbound Memory Read */
> +	METRIC_IN_CPL,		/* Inbound Memory Completion */
> +	METRIC_OUT_MWR,		/* Outbound Memory Write */
> +	METRIC_OUT_MRD,		/* Outbound Memory Read */
> +	METRIC_OUT_CPL,		/* Outbound Memory Completion */
> +	METRIC_TYPE_MAX,
> +};
> +
> +static const char * const hisi_iostat_metrics[] = {
> +	[METRIC_IN_MWR] = "Inbound MWR(MB)",
> +	[METRIC_IN_MRD] = "Inbound MRD(MB)",
> +	[METRIC_IN_CPL] = "Inbound CPL(MB)",
> +	[METRIC_OUT_MWR] = "Outbound MWR(MB)",
> +	[METRIC_OUT_MRD] = "Outbound MRD(MB)",
> +	[METRIC_OUT_CPL] = "Outbound CPL(MB)",
> +};
> +
> +static const char * const hisi_iostat_cmd_template[] = {
> +	[METRIC_IN_MWR] = "hisi_pcie%hu_core%hu/event=0x0104,port=0x%hx/",
> +	[METRIC_IN_MRD] = "hisi_pcie%hu_core%hu/event=0x0804,port=0x%hx/",
> +	[METRIC_IN_CPL] = "hisi_pcie%hu_core%hu/event=0x2004,port=0x%hx/",
> +	[METRIC_OUT_MWR] = "hisi_pcie%hu_core%hu/event=0x0105,port=0x%hx/",
> +	[METRIC_OUT_MRD] = "hisi_pcie%hu_core%hu/event=0x0405,port=0x%hx/",
> +	[METRIC_OUT_CPL] = "hisi_pcie%hu_core%hu/event=0x1005,port=0x%hx/",
> +};
> +
> +struct hisi_pcie_root_port {
> +	struct list_head list;
> +	/* Is this Root Port selected for monitoring */
> +	bool selected;
> +	/* IDs to locate the PMU */
> +	u16 sicl_id;
> +	u16 core_id;
> +	/* Filter mask for this Root Port */
> +	u16 mask;
> +	/* PCIe Root Port's <domain>:<bus>:<device>.<function> */
> +	u32 domain;
> +	u8 bus;
> +	u8 dev;
> +	u8 fn;
> +};
> +
> +LIST_HEAD(hisi_pcie_root_ports_list);

The list head can be 'static' type.

> +static int hisi_pcie_root_ports_num;

My feeling is 'hisi_pcie_root_ports_num' is redundant. You can check
if the list is empty with list_empty() in below code, therefore, the
variable 'hisi_pcie_root_ports_num' is not needed anymore.

> +
> +static void hisi_pcie_init_root_port_mask(struct hisi_pcie_root_port *rp)
> +{
> +	rp->mask = BIT(rp->dev << 1);

I also think 'rp->mask' is not necessary as it can be replaced by
BIT(rp->dev << 1).

And it's not necessary to create hisi_pcie_init_root_port_mask(), as
it's only used in a single place.

> +}
> +
> +/*
> + * Select specific Root Port to monitor. Return 0 if successfully find the
> + * Root Port, Otherwise -EINVAL.
> + */
> +static int hisi_pcie_root_ports_select_one(u32 domain, u8 bus, u8 dev, u8 fn)
> +{
> +	struct hisi_pcie_root_port *rp;
> +
> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list)
> +		if (domain == rp->domain && bus == rp->bus &&
> +		    dev == rp->dev && fn == rp->fn) {
> +			rp->selected = true;


The code firstly creates PCI port lists for all Hisilicon PCIe ports,
then it selects the port based on passed port name.

I am wandering why cannot create the PCI root port list based on the
passed PCI port name, if so, the field 'rp->selected' is not needed
anymore.

> +			return 0;
> +		}
> +
> +	return -EINVAL;
> +}
>
> +
> +static void hisi_pcie_root_ports_select_all(void)
> +{
> +	struct hisi_pcie_root_port *rp;
> +
> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list)
> +		rp->selected = true;
> +}

Same as the comment above, the function
hisi_pcie_root_ports_select_all() is not needed if a PCI list can be
created properly in the first place.

> +
> +static void hisi_pcie_root_ports_add(u16 sicl_id, u16 core_id, u8 target_bus)
> +{
> +	const char *sysfs = sysfs__mountpoint();
> +	struct hisi_pcie_root_port *rp;
> +	struct dirent *dent;
> +	char path[PATH_MAX];
> +	u8 bus, dev, fn;
> +	u32 domain;
> +	DIR *dir;
> +	int ret;
> +
> +	snprintf(path, PATH_MAX, "%s/%s", sysfs, PCI_ROOT_BUS_DEVICES_PATH);
> +	dir = opendir(path);
> +	if (!dir)
> +		return;
> +
> +	/* Scan the PCI root bus to find the match root port on @target_bus */
> +	while ((dent = readdir(dir))) {
> +		ret = sscanf(dent->d_name, PCI_DEVICE_NAME_PATTERN,
> +			     &domain, &bus, &dev, &fn);
> +		if (ret != 4 || bus != target_bus)
> +			continue;
> +
> +		rp = zalloc(sizeof(*rp));
> +		if (!rp)
> +			continue;
> +
> +		rp->selected = false;
> +		rp->sicl_id = sicl_id;
> +		rp->core_id = core_id;
> +		rp->domain = domain;
> +		rp->bus = bus;
> +		rp->dev = dev;
> +		rp->fn = fn;
> +
> +		hisi_pcie_init_root_port_mask(rp);
> +
> +		list_add(&rp->list, &hisi_pcie_root_ports_list);
> +		hisi_pcie_root_ports_num++;
> +
> +		pr_debug3("Found root port %s\n", dent->d_name);
> +	}
> +
> +	closedir(dir);
> +}
> +
> +/* Scan the PMUs and build the mapping of the Root Ports to the PMU */
> +static int hisi_pcie_root_ports_init(void)
> +{
> +	char event_source[PATH_MAX], bus_path[PATH_MAX];
> +	unsigned long long bus;
> +	u16 sicl_id, core_id;
> +	struct dirent *dent;
> +	DIR *dir;
> +
> +	perf_pmu__event_source_devices_scnprintf(event_source, sizeof(event_source));
> +	dir = opendir(event_source);
> +	if (!dir)
> +		return -ENOENT;
> +
> +	while ((dent = readdir(dir))) {
> +		/*
> +		 * This HiSilicon PCIe PMU will be named as:
> +		 *   hisi_pcie<sicl_id>_core<core_id>
> +		 */
> +		if ((sscanf(dent->d_name, "hisi_pcie%hu_core%hu", &sicl_id, &core_id)) != 2)
> +			continue;
> +
> +		/*
> +		 * Driver will export the root port it can monitor through
> +		 * the "bus" sysfs attribute.
> +		 */
> +		scnprintf(bus_path, sizeof(bus_path), "%s/hisi_pcie%hu_core%hu/bus",
> +			  event_source, sicl_id, core_id);
> +
> +		/*
> +		 * Per PCIe spec the bus should be 8bit, use unsigned long long
> +		 * for the convience of the library function.
> +		 */
> +		if (filename__read_ull(bus_path, &bus))
> +			continue;
> +
> +		pr_debug3("Found pmu %s bus 0x%llx\n", dent->d_name, bus);
> +
> +		hisi_pcie_root_ports_add(sicl_id, core_id, (u8)bus);
> +	}
> +
> +	closedir(dir);
> +	return hisi_pcie_root_ports_num > 0 ? 0 : -ENOENT;
> +}
> +
> +static void hisi_pcie_root_ports_free(void)
> +{
> +	struct hisi_pcie_root_port *rp, *tmp;
> +
> +	if (hisi_pcie_root_ports_num == 0)
> +		return;
> +
> +	list_for_each_entry_safe(rp, tmp, &hisi_pcie_root_ports_list, list) {
> +		list_del(&rp->list);
> +		zfree(&rp);
> +		hisi_pcie_root_ports_num--;
> +	}
> +}
> +
> +static int hisi_iostat_add_events(struct evlist *evl)
> +{
> +	struct hisi_pcie_root_port *rp;
> +	struct evsel *evsel;
> +	unsigned int i, j;
> +	char *iostat_cmd;
> +	int pos = 0;
> +	int ret;
> +
> +	if (!hisi_pcie_root_ports_num)
> +		return -ENOENT;
> +
> +	iostat_cmd = zalloc(PATH_MAX);
> +	if (!iostat_cmd)
> +		return -ENOMEM;
> +
> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list) {
> +		if (!rp->selected)
> +			continue;
> +
> +		iostat_cmd[pos++] = '{';
> +		for (j = 0; j < METRIC_TYPE_MAX; j++) {
> +			pos += snprintf(iostat_cmd + pos, ARG_MAX - pos - 1,
> +					hisi_iostat_cmd_template[j],
> +					rp->sicl_id, rp->core_id, rp->mask);
> +
> +			if (j == METRIC_TYPE_MAX - 1)
> +				iostat_cmd[pos++] = '}';
> +			else
> +				iostat_cmd[pos++] = ',';
> +		}

Here is hard coded that every event must contains the all 6 metrics (
IN_MWR/IN_MRD/IN_CPL/OUT_MWR/OUT_MRD/OUT_CPL). Thus, a user has no
chance to specify metrics for statistics.

> +
> +		ret = parse_event(evl, iostat_cmd);
> +		if (ret)
> +			break;
> +
> +		i = 0;
> +		evlist__for_each_entry_reverse(evl, evsel) {
> +			if (i == METRIC_TYPE_MAX)
> +				break;
> +
> +			evsel->priv = rp;
> +			i++;
> +		}
> +
> +		memset(iostat_cmd, 0, PATH_MAX);
> +		pos = 0;
> +	}
> +
> +	zfree(&iostat_cmd);
> +	return ret;
> +}
> +
> +int iostat_prepare(struct evlist *evlist,
> +		   struct perf_stat_config *config)
> +{
> +	if (evlist->core.nr_entries > 0) {
> +		pr_warning("The -e and -M options are not supported."
> +			   "All chosen events/metrics will be dropped\n");
> +		evlist__delete(evlist);
> +		evlist = evlist__new();
> +		if (!evlist)
> +			return -ENOMEM;
> +	}
> +
> +	config->metric_only = true;
> +	config->aggr_mode = AGGR_GLOBAL;
> +
> +	return hisi_iostat_add_events(evlist);

As Robin mentioned in another email, PCI root port statistics should
not bind to Arm architecture. After applying this code, it's binding
iostat exclusively with Hisilicon PCI root ports on Arm, as a result,
it is impossible to support other PMUs for iostat support.

I understand you saw the implementation 'arch/x86/util/iostat.c' which
binds the iostat with x86 arch. And your code just studies it to bind
PCI root port stats with Arm arch.

Here, I think the methodology should be: we need take Hisilicon PCI
root port as a general PMU for I/O stats, it should not bind to any
CPU arch. We need to consider to extend 'perf iostat' for this
purpose.

To be honest, I am not familiar with 'perf iostat', I will take a bit
more time to look into it and share back if I have more finding.

Thanks,
Leo


> +}
> +
> +static int hisi_pcie_root_ports_list_filter(const char *str)
> +{
> +	char *tok, *tmp, *copy = NULL;
> +	u8 bus, dev, fn;
> +	u32 domain;
> +	int ret;
> +
> +	copy = strdup(str);
> +	if (!copy)
> +		return -ENOMEM;
> +
> +	for (tok = strtok_r(copy, ",", &tmp); tok; tok = strtok_r(NULL, ",", &tmp)) {
> +		ret = sscanf(tok, PCI_DEVICE_NAME_PATTERN, &domain, &bus, &dev, &fn);
> +		if (ret != 4) {
> +			ret = -EINVAL;
> +			break;
> +		}
> +
> +		ret = hisi_pcie_root_ports_select_one(domain, bus, dev, fn);
> +		if (ret)
> +			break;
> +	}
> +
> +	zfree(&copy);
> +	return ret;
> +}
> +
> +int iostat_parse(const struct option *opt, const char *str, int unset __maybe_unused)
> +{
> +	struct perf_stat_config *config = (struct perf_stat_config *)opt->data;
> +	int ret;
> +
> +	ret = hisi_pcie_root_ports_init();
> +	if (!ret) {
> +		config->iostat_run = true;
> +
> +		if (!str) {
> +			iostat_mode = IOSTAT_RUN;
> +			hisi_pcie_root_ports_select_all();
> +		} else if (!strcmp(str, "list")) {
> +			iostat_mode = IOSTAT_LIST;
> +			hisi_pcie_root_ports_select_all();
> +		} else {
> +			iostat_mode = IOSTAT_RUN;
> +			ret = hisi_pcie_root_ports_list_filter(str);
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static void hisi_pcie_root_port_show(FILE *output,
> +				     const struct hisi_pcie_root_port * const rp)
> +{
> +	if (output && rp)
> +		fprintf(output, "hisi_pcie%hu_core%hu<" PCI_DEVICE_NAME_PATTERN ">\n",
> +			rp->sicl_id, rp->core_id, rp->domain, rp->bus, rp->dev, rp->fn);
> +}
> +
> +void iostat_list(struct evlist *evlist __maybe_unused, struct perf_stat_config *config)
> +{
> +	struct hisi_pcie_root_port *rp = NULL;
> +	struct evsel *evsel;
> +
> +	evlist__for_each_entry(evlist, evsel) {
> +		if (rp != evsel->priv) {
> +			hisi_pcie_root_port_show(config->output, evsel->priv);
> +			rp = evsel->priv;
> +		}
> +	}
> +}
> +
> +void iostat_release(struct evlist *evlist)
> +{
> +	struct evsel *evsel;
> +
> +	evlist__for_each_entry(evlist, evsel)
> +		evsel->priv = NULL;
> +
> +	hisi_pcie_root_ports_free();
> +}
> +
> +void iostat_print_header_prefix(struct perf_stat_config *config)
> +{
> +	if (config->csv_output)
> +		fputs("port,", config->output);
> +	else if (config->interval)
> +		fprintf(config->output, "#          time    port         ");
> +	else
> +		fprintf(config->output, "   port         ");
> +}
> +
> +void iostat_print_metric(struct perf_stat_config *config, struct evsel *evsel,
> +			 struct perf_stat_output_ctx *out)
> +{
> +	struct perf_counts_values *count;
> +	const char *iostat_metric;
> +	double iostat_value;
> +
> +	iostat_metric = hisi_iostat_metrics[evsel->core.idx % METRIC_TYPE_MAX];
> +
> +	/* We're using AGGR_GLOBAL so there's only one aggr counts aggr[0]. */
> +	count = &evsel->stats->aggr[0].counts;
> +
> +	/* The counts has been scaled, we can use it directly. */
> +	iostat_value = (double)count->val;
> +
> +	/*
> +	 * Calculate the bandwidth in MiB since the PMU counts in DWord.
> +	 * Display two digits after decimal point for better accuracy if the
> +	 * value is non-zero.
> +	 */
> +	out->print_metric(config, out->ctx, NULL,
> +			  iostat_value > 0 ? "%8.2f" : "%8.0f", iostat_metric,
> +			  iostat_value * sizeof(uint32_t) / (1024 * 1024));
> +}
> +
> +void iostat_prefix(struct evlist *evlist, struct perf_stat_config *config,
> +		   char *prefix, struct timespec *ts)
> +{
> +	struct hisi_pcie_root_port *rp = evlist->selected->priv;
> +
> +	if (rp) {
> +		if (ts)
> +			sprintf(prefix, "%6lu.%09lu%s" PCI_DEVICE_NAME_PATTERN "%s",
> +				ts->tv_sec, ts->tv_nsec, config->csv_sep,
> +				rp->domain, rp->bus, rp->dev, rp->fn,
> +				config->csv_sep);
> +		else
> +			sprintf(prefix, PCI_DEVICE_NAME_PATTERN "%s",
> +				rp->domain, rp->bus, rp->dev, rp->fn,
> +				config->csv_sep);
> +	}
> +}
> +
> +void iostat_print_counters(struct evlist *evlist, struct perf_stat_config *config,
> +			   struct timespec *ts, char *prefix,
> +			   iostat_print_counter_t print_cnt_cb, void *arg)
> +{
> +	struct evsel *counter = evlist__first(evlist);
> +	void *perf_device;
> +
> +	evlist__set_selected(evlist, counter);
> +	iostat_prefix(evlist, config, prefix, ts);
> +	fprintf(config->output, "%s", prefix);
> +	evlist__for_each_entry(evlist, counter) {
> +		perf_device = evlist->selected->priv;
> +		if (perf_device && perf_device != counter->priv) {
> +			evlist__set_selected(evlist, counter);
> +			iostat_prefix(evlist, config, prefix, ts);
> +			fprintf(config->output, "\n%s", prefix);
> +		}
> +		print_cnt_cb(config, counter, arg);
> +	}
> +	fputc('\n', config->output);
> +}
> -- 
> 2.24.0


From quic_kbajaj at quicinc.com  Fri Feb  9 05:53:32 2024
From: quic_kbajaj at quicinc.com (Komal Bajaj)
Date: Fri, 9 Feb 2024 19:23:32 +0530
Subject: [PATCH] arm64: defconfig: Enable GCC and interconnect for
 QDU1000/QRU1000
In-Reply-To: <b4d7d4cf-5bee-492c-819d-79af01e73cec@linaro.org>
References: <20230822132333.17580-1-quic_kbajaj@quicinc.com>
 <b4d7d4cf-5bee-492c-819d-79af01e73cec@linaro.org>
Message-ID: <14cfbfe0-de9f-e81f-60d6-5c8a6496d816@quicinc.com>



On 8/22/2023 7:54 PM, Konrad Dybcio wrote:
> On 22.08.2023 15:23, Komal Bajaj wrote:
>> Add the QDU1000/QRU1000 GCC and interconnect drivers as built-in.
>> These are necessary for the Qualcomm QDU1000/QRU1000 platform to boot
>> to shell.
>>
>> Signed-off-by: Komal Bajaj <quic_kbajaj at quicinc.com>
>> ---
> Acked-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> 
> Konrad

Can you please apply this patch?

Thanks
Komal


From shameerali.kolothum.thodi at huawei.com  Fri Feb  9 05:54:08 2024
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Fri, 9 Feb 2024 13:54:08 +0000
Subject: [RFC PATCH v2 0/7] iommu/arm-smmu-v3: Use pinned KVM VMID for
 stage 2
In-Reply-To: <20240209115824.GA2922446@myrica>
References: <20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com>
 <20240209115824.GA2922446@myrica>
Message-ID: <1f0e938bbf684fe69ad7050b8cb3cc29@huawei.com>



> -----Original Message-----
> From: Jean-Philippe Brucker <jean-philippe at linaro.org>
> Sent: Friday, February 9, 2024 11:58 AM
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: kvmarm at lists.linux.dev; iommu at lists.linux.dev; linux-arm-
> kernel at lists.infradead.org; Linuxarm <linuxarm at huawei.com>;
> kevin.tian at intel.com; jgg at ziepe.ca; alex.williamson at redhat.com;
> maz at kernel.org; oliver.upton at linux.dev; will at kernel.org;
> robin.murphy at arm.com; Jonathan Cameron
> <jonathan.cameron at huawei.com>
> Subject: Re: [RFC PATCH v2 0/7] iommu/arm-smmu-v3: Use pinned KVM
> VMID for stage 2
> 
> Hi Shameer,
> 
> On Thu, Feb 08, 2024 at 03:18:30PM +0000, Shameer Kolothum wrote:
> > Hi,
> >
> > On an ARM64 system with a SMMUv3 implementation that fully supports
> > Broadcast TLB Maintenance(BTM) feature as part of the Distributed
> > Virtual Memory(DVM) protocol, the CPU TLB invalidate instructions are
> > received by SMMUv3. This is very useful when the SMMUv3 shares the
> > page tables with the CPU(eg: Guest SVA use case). For this to work,
> > the SMMUv3 must use the same VMID that is allocated by KVM to
> configure
> > the nested stage 2(S2) translations.
> 
> The series makes sense to me. Maybe a little more detail to help the KVM
> maintainers understand why we need something like this even though the s2
> page tables aren't shared between CPU and SMMU:

Thanks Jean for the nice write up. I will use this for next revisions of this series.

Shameer


From linus.walleij at linaro.org  Fri Feb  9 05:54:32 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 9 Feb 2024 14:54:32 +0100
Subject: [PATCH] ARM: iwmmxt: Remove support for PJ4/PJ4B cores
In-Reply-To: <20240209110901.4032939-2-ardb+git@google.com>
References: <20240209110901.4032939-2-ardb+git@google.com>
Message-ID: <CACRpkdaMt_TXQMNnx3+k+yB6E_Yr2comO5j7UH2a9oRbtdDODQ@mail.gmail.com>

On Fri, Feb 9, 2024 at 12:09?PM Ard Biesheuvel <ardb+git at google.com> wrote:

> From: Ard Biesheuvel <ardb at kernel.org>
>
> PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
> does not support this combination (its iWMMXt configuration always
> implies v5te), and so there is no v6/v7 user space that actually makes
> use of this, beyond generic support for things like setjmp() that
> preserve/restore the iWMMXt register file using generic LDC/STC
> instructions emitted in assembler. As [0] appears to imply, this logic
> is triggered for the init process at boot, and so most processes will
> have a iWMMXt register context associated with it, even though it is
> never used.
>
> This means that advertising iWMMXt support on these cores results in
> context switch overhead without any associated benefit, and so it is
> better to simply ignore the iWMMXt unit on these systems. So rip out the
> support. Doing so also fixes the issue reported in [0] related to UNDEF
> handling of co-processor #0/#1 instructions issued from user space
> running in Thumb2 mode.
>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Nicolas Pitre <nico at fluxnic.net>
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

Acked-by: Linus Walleij <linus.walleij at linaro.org>

I would probably say in the commit message that the window for enabling
this in GCC and userspace was when the core was introduced and it
has long since passed; whoever was supposed to do this didn't exist
or care and thus the job never got done.

I was worried about some assembly in userspace making use of this,
so I checked libavcodec and it does not seem to have any iWMMX
optimizations at all. (Don't know what else to check.)

CC to Lubomir who made the Dell WYSE port which use MMP3 with PJ4
so he can check that he doesn't have userspace using this either and
can ACK this commit.

Yours,
Linus Walleij


From tudor.ambarus at linaro.org  Fri Feb  9 05:56:56 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 9 Feb 2024 13:56:56 +0000
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth``
 property
In-Reply-To: <20240208-grating-legwarmer-0a04cfb04d61@spud>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
 <20240208135045.3728927-2-tudor.ambarus@linaro.org>
 <20240208-grating-legwarmer-0a04cfb04d61@spud>
Message-ID: <c2b08463-cb13-4e9b-8797-8ebcf1047f66@linaro.org>


+ Geert

On 2/8/24 18:24, Conor Dooley wrote:
> On Thu, Feb 08, 2024 at 01:50:34PM +0000, Tudor Ambarus wrote:
>> There are instances of the same IP that are configured by the integrator
>> with different FIFO depths. Introduce the fifo-depth property to allow
>> such nodes to specify their FIFO depth.
>>
>> We haven't seen SPI IPs with different FIFO depths for RX and TX, thus
>> introduce a single property.
> 
> Some citation attached to this would be nice. "We haven't seen" offers
> no detail as to what IPs that allow this sort of configuration of FIFO
> size that you have actually checked.
> 
> I went and checked our IP that we use in FPGA fabric, which has a
> configurable fifo depth. It only has a single knob for both RX and TX
> FIFOs. The Xilinx xps spi core also has configurable FIFOs, but again RX
> and TX sizes are tied there. At least that's a sample size of three.
> 
> One of our guys is working on support for the IP I just mentioned and
> would be defining a vendor property for this, so
> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> 

Thanks, Conor. I had in mind that SPI has a shift register and it's
improbable to have different FIFO depths for RX and TX. At least I don't
see how it would work, I guess it will use the minimum depth between the
two?

I grepped by "fifo" in the spi bindings and I now see that renesas is
using dedicated properties for RX and TX, but I think that there too the
FIFOs have the same depths. Looking into drivers/spi/spi-sh-msiof.c I
see that the of_device_id.data contains 64 bytes FIFOs for RX and TX,
regardless of the compatible.

Geert, any idea if the FIFO depths can differ for RX and TX in
spi-sh-msiof.c?

Anyway, even if there are such imbalanced architectures, I guess we can
consider them when/if they appear? (add rx/tx-fifo-depth dt properties)

Cheers,
ta


----
$ git grep fifo Documentation/devicetree/bindings/spi/
Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml:
atmel,fifo-size:
Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml:
atmel,fifo-size = <32>;
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml:
cdns,fifo-depth:
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml:
cdns,fifo-depth:
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml:  cdns,fifo-depth:
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml:  cdns,fifo-width:
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml:  - cdns,fifo-depth
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml:  - cdns,fifo-width
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml:
cdns,fifo-depth = <128>;
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml:
cdns,fifo-width = <4>;
Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
renesas,tx-fifo-size:
Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
Override the default TX fifo size.  Unit is words.  Ignored if 0.
Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
renesas,rx-fifo-size:
Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
Override the default RX fifo size.  Unit is words.  Ignored if 0.
Documentation/devicetree/bindings/spi/spi-sifive.yaml:  sifive,fifo-depth:
Documentation/devicetree/bindings/spi/spi-sifive.yaml:
sifive,fifo-depth = <8>;


From ankita at nvidia.com  Fri Feb  9 06:02:26 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Fri, 9 Feb 2024 14:02:26 +0000
Subject: [PATCH v6 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240208175437.GN10476@nvidia.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-5-ankita@nvidia.com>
 <20240208103022.452a1ba3.alex.williamson@redhat.com>
 <20240208175437.GN10476@nvidia.com>
Message-ID: <MW4PR12MB7213C81E5CD611CF3AFCB0A9B04B2@MW4PR12MB7213.namprd12.prod.outlook.com>

> The comment above this is justifying the flags as equivalent to those
> set by the remap_pfn_range() path.  That's no longer the case and the
> additional flag needs to be described there.

Ack.

>> the comment where the bit is defined and we could use a name like
>> VM_ALLOW_ANY_UNCACHED or VM_IO_ANY.? Thanks,
>
> I'd pick VM_ALLOW_ANY_UNCACHED of those two

If there is consensus on this name, I'll make the change
s/VM_VFIO_ALLOW_WC/VM_ALLOW_ANY_UNCACHED.

From ankita at nvidia.com  Fri Feb  9 06:05:32 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Fri, 9 Feb 2024 14:05:32 +0000
Subject: [PATCH v6 3/4] kvm: arm64: set io memory s2 pte as normalnc for
 vfio pci device
In-Reply-To: <ZcTqcqE69zkLZgQx@arm.com>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-4-ankita@nvidia.com> <ZcTqcqE69zkLZgQx@arm.com>
Message-ID: <MW4PR12MB7213AB84261541A75F88FBFBB04B2@MW4PR12MB7213.namprd12.prod.outlook.com>

>> +		/*
>> +		 * To provide VM with the ability to get device IO memory
>> +		 * with NormalNC property, map device MMIO as NormalNC in S2.
>> +		 */
>
> nit: the comment doesn't provide anything of value, the logic is rather
> straightforward here.

Sure, will remove it.

>>
>> +???? vfio_allow_wc = (vma->vm_flags & VM_VFIO_ALLOW_WC);
>
> Nitpick: no need for brackets, '=' has a pretty low precedence.
> 
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>

Will change it. Thanks for the review.

From ankita at nvidia.com  Fri Feb  9 06:10:51 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Fri, 9 Feb 2024 14:10:51 +0000
Subject: [PATCH v6 1/4] kvm: arm64: introduce new flag for non-cacheable
 IO memory
In-Reply-To: <ZcTWK6TksvugSlI-@linux.dev>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-2-ankita@nvidia.com> <ZcTQi0wWZgvl05LB@arm.com>
 <ZcTWK6TksvugSlI-@linux.dev>
Message-ID: <MW4PR12MB72138D289232B5D62078158DB04B2@MW4PR12MB7213.namprd12.prod.outlook.com>

>> +	default:
>> +		WARN_ON_ONCE(1);
>
> Return -EINVAL?

Sure.

>> > +?? case KVM_PGTABLE_PROT_NORMAL_NC:
>> > +?????????? attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
>> > +?????????? break;
>>
>> Does it make sense to allow executable here as well? I don't think it's
>> harmful but not sure there's a use-case for it either.
>
> Ah, we should just return EINVAL for that too.
>
> I get that the memory attribute itself is not problematic, but since
> we're only using this thing for MMIO it'd be a rather massive
> bug in KVM... We reject attempts to do this earlier in user_mem_abort().

Ack, will change to test executable and return -EINVAL in that case.

From ankita at nvidia.com  Fri Feb  9 06:12:01 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Fri, 9 Feb 2024 14:12:01 +0000
Subject: [PATCH v6 1/4] kvm: arm64: introduce new flag for non-cacheable
 IO memory
In-Reply-To: <20240208131938.GB23428@willie-the-truck>
References: <20240207204652.22954-1-ankita@nvidia.com>
 <20240207204652.22954-2-ankita@nvidia.com>
 <20240208131938.GB23428@willie-the-truck>
Message-ID: <MW4PR12MB72133DAC9A35687D33DCCDC0B04B2@MW4PR12MB7213.namprd12.prod.outlook.com>

>>
>> +???? switch (prot & (KVM_PGTABLE_PROT_DEVICE |
>> +???????????????????? KVM_PGTABLE_PROT_NORMAL_NC)) {
>> +???? case 0:
>> +???????????? attr = KVM_S2_MEMATTR(pgt, NORMAL);
>> +???????????? break;
>> +???? case KVM_PGTABLE_PROT_DEVICE:
>> +???????????? if (prot & KVM_PGTABLE_PROT_X)
>> +???????????????????? return -EINVAL;
>> +???????????? attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
>> +???????????? break;
>> +???? case KVM_PGTABLE_PROT_NORMAL_NC:
>> +???????????? attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
>> +???????????? break;
>> +???? default:
>> +???????????? WARN_ON_ONCE(1);
>> +???? }
>
> Cosmetic nit, but I'd find this a little easier to read if the normal
> case was the default (i.e. drop 'case 0') and we returned an error for
> DEVICE | NC.

Makes sense, will update the logic accordingly.

From Dharma.B at microchip.com  Fri Feb  9 06:20:29 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Fri, 9 Feb 2024 14:20:29 +0000
Subject: [PATCH v3 1/4] dt-bindings: display: bridge: add sam9x75-lvds
 compatible
In-Reply-To: <2219df60-7235-4c37-b79c-25e7225cb7a9@kernel.org>
References: <20240207102802.200220-1-dharma.b@microchip.com>
 <20240207102802.200220-2-dharma.b@microchip.com>
 <2219df60-7235-4c37-b79c-25e7225cb7a9@kernel.org>
Message-ID: <b314e446-e79c-4fa0-9b86-c58fa96133bc@microchip.com>

On 08/02/24 2:31 pm, Krzysztof Kozlowski wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On 07/02/2024 11:27, Dharma Balasubiramani wrote:
>> Add the 'sam9x75-lvds' compatible binding, which describes the Low Voltage
>> Differential Signaling (LVDS) Controller found on some Microchip's sam9x7
>> series System-on-Chip (SoC) devices. This binding will be used to define
>> the properties and configuration for the LVDS Controller in DT.
>>
>> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> 
> Not tested...
> 
> Please use scripts/get_maintainers.pl to get a list of necessary people
> and lists to CC. It might happen, that command when run on an older
> kernel, gives you outdated entries. Therefore please be sure you base
> your patches on recent Linux kernel.
> 
> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
> people, so fix your workflow. Tools might also fail if you work on some
> ancient tree (don't, instead use mainline), work on fork of kernel
> (don't, instead use mainline) or you ignore some maintainers (really
> don't). Just use b4 and everything should be fine, although remember
> about `b4 prep --auto-to-cc` if you added new patches to the patchset.
> 
> You missed at least devicetree list (maybe more), so this won't be
> tested by automated tooling. Performing review on untested code might be
> a waste of time.

Apologies for the oversight, somehow it got missed.
> 
> Please kindly resend and include all necessary To/Cc entries.

I will resend the series including all necessary To/Cc entries.

Thanks.
> 
> 
> Best regards,
> Krzysztof
> 

-- 
With Best Regards,
Dharma B.


From Dharma.B at microchip.com  Fri Feb  9 06:22:28 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Fri, 9 Feb 2024 14:22:28 +0000
Subject: [PATCH v3 1/4] dt-bindings: display: bridge: add sam9x75-lvds
 compatible
In-Reply-To: <20240207-raving-chatty-7961fb5c5d43@spud>
References: <20240207102802.200220-1-dharma.b@microchip.com>
 <20240207102802.200220-2-dharma.b@microchip.com>
 <20240207-raving-chatty-7961fb5c5d43@spud>
Message-ID: <39afd835-13be-4949-8a7a-4a81e0f3498b@microchip.com>

Hi Conor,

On 07/02/24 9:22 pm, Conor Dooley wrote:
> $subject: dt-bindings: display: bridge: add sam9x75-lvds compatible
> 
> If there's a respin for some reason, please update the subject to match
> what the commit is actually doing (adding a whole binding).

Absolutely, I'll make the adjustment as follows: "dt-bindings: display: 
bridge: add sam9x75-lvds binding"
> 
> Cheers,
> Conor.

-- 
With Best Regards,
Dharma B.


From krzysztof.kozlowski at linaro.org  Fri Feb  9 06:24:28 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 9 Feb 2024 15:24:28 +0100
Subject: [PATCH] arm64: defconfig: Enable GCC and interconnect for
 QDU1000/QRU1000
In-Reply-To: <14cfbfe0-de9f-e81f-60d6-5c8a6496d816@quicinc.com>
References: <20230822132333.17580-1-quic_kbajaj@quicinc.com>
 <b4d7d4cf-5bee-492c-819d-79af01e73cec@linaro.org>
 <14cfbfe0-de9f-e81f-60d6-5c8a6496d816@quicinc.com>
Message-ID: <f0f52ab1-6c73-4c8c-96c3-fc3d0174223d@linaro.org>

On 09/02/2024 14:53, Komal Bajaj wrote:
> 
> 
> On 8/22/2023 7:54 PM, Konrad Dybcio wrote:
>> On 22.08.2023 15:23, Komal Bajaj wrote:
>>> Add the QDU1000/QRU1000 GCC and interconnect drivers as built-in.
>>> These are necessary for the Qualcomm QDU1000/QRU1000 platform to boot
>>> to shell.
>>>
>>> Signed-off-by: Komal Bajaj <quic_kbajaj at quicinc.com>
>>> ---
>> Acked-by: Konrad Dybcio <konrad.dybcio at linaro.org>
>>
>> Konrad
> 
> Can you please apply this patch?

You did not send it to proper folks and lists, so I would say: it cannot
be applied. You can easily check: go to MSM patchwork and look for this
patch.

The rule is the same for all SoC architectures - the SoC-related
defconfig changes go via SoC tree, so please follow CC-list for MSM and
resend with correct addresses.

Best regards,
Krzysztof



From arnd at arndb.de  Fri Feb  9 06:27:02 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 09 Feb 2024 15:27:02 +0100
Subject: [PATCH] ARM: iwmmxt: Remove support for PJ4/PJ4B cores
In-Reply-To: <20240209110901.4032939-2-ardb+git@google.com>
References: <20240209110901.4032939-2-ardb+git@google.com>
Message-ID: <0bc7c97c-6549-4ae1-9787-4702e7ab737e@app.fastmail.com>

On Fri, Feb 9, 2024, at 12:09, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb at kernel.org>
>
> PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
> does not support this combination (its iWMMXt configuration always
> implies v5te), and so there is no v6/v7 user space that actually makes
> use of this, beyond generic support for things like setjmp() that
> preserve/restore the iWMMXt register file using generic LDC/STC
> instructions emitted in assembler. As [0] appears to imply, this logic
> is triggered for the init process at boot, and so most processes will
> have a iWMMXt register context associated with it, even though it is
> never used.
>
> This means that advertising iWMMXt support on these cores results in
> context switch overhead without any associated benefit, and so it is
> better to simply ignore the iWMMXt unit on these systems. So rip out the
> support. Doing so also fixes the issue reported in [0] related to UNDEF
> handling of co-processor #0/#1 instructions issued from user space
> running in Thumb2 mode.
>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Nicolas Pitre <nico at fluxnic.net>
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

Acked-by: Arnd Bergmann <arnd at arndb.de>

Maybe add a bit about which cores are actually affected by this:

The PJ4 cores are used in four platforms: armada 370/xp, dove
(cubox, d2plug), mmp2 (xo-1.75) and berlin (chromecast 1).
Out of these, only the first is still widely used, but that
one actually doesn't have iwmmxt but instead has only
vfpv3-d16.

I've also added the maintainers of those platforms to Cc,
in case anyone has objections after all.

      Arnd


From andre.przywara at arm.com  Fri Feb  9 06:42:14 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 14:42:14 +0000
Subject: [PATCH v4 0/7] add support for H616 thermal system
Message-ID: <20240209144221.3602382-1-andre.przywara@arm.com>

Hi,

this is v4 of the series originally by Martin, complemented by patches
to fix the problem with way-too-high temperatures reported on
some boards, and some refactoring and simplifications, compared to the
original drop.

For the SYS_CFG bit poke code I now avoided the term "syscon" at all,
instead using "sram" instead, which seems to be less controversial. Apart
from that the register poke part hasn't changed much, but I hope it's more
acceptable now that it doesn't claim to be using a syscon device.

Many thanks to Maksim's investigation into the code, which revealed that
the calibrate functions between the H6 and H616 are actually the same,
just with support for more sensors. So his new patch 4/7 refactors the
existing function, to make it compatible to the H616, which makes the
actual support patch 6/7 very simple.

See the Changelog below for more details.

==================

This series introduces support for the thermal sensors in the Allwinner
H616 SoCs, which includes its siblings H618 and T507. The actual
temperature reading turns out to be very similar to the H6 SoC, just
with support for two more sensors. One nasty complication is caused
by reports about temperatures above 200C, which are related to the
firmware being run (because the vendor U-Boot contains a hack avoiding
this problem). Some investigation and digging in BSP code later
we identified that bit 16 in register 0x3000000 (SYS_CFG) needs to be
cleared for the raw temperature register values to contain reasonable
values.
To achieve this, patch 1/7 exports this very register from the already
existing SRAM/syscon device. Patch 5/7 then adds code to the thermal
driver to find that device via a new DT property, and query its regmap
to clear bit 16 in there.

I am open to suggestions on how to solve this in a better way, but the
current solution works, and uses an existing driver and an existing
scheme (in the EMAC driver).

The rest of the patches are fairly straight-forward and build on
Martin's original work, with some simplifications, resulting in more
code sharing.

Please have a look!

Cheers,
Andre

Changelog v3 .. v4:
- rebase on top of v6.8-rc2
- rework SYS_CFG bit poking patches to avoid syscon
- use sram lock for the SRAM driver regmap as well
- correctly advertise new allwinner,sram property in binding
- fix conditional definition of sram property
- new patch 4/7 to make the H6 and H616 calibrate functions compatible
- drop now obsolete definition of sun50i_h616_ths_calibrate()

Changelog v2 .. v3:
- rebase on top of v6.7-rc3
- add patches to clear bit 16 in SYS_CFG register 0x3000000
- add syscon to the binding documentation
- add patch explaining the unknown control register value

Changelog v1 .. v2:
- Fix typos
- Remove h616 calc and init functions
- Use TEMP_CALIB_MASK insteaf of 0xffff
- Adjust calibration function to new offset and scale
- Add proper comment to bindings patch
- Split delta calculations to 2 lines
- Add parentheses around caldata[2|3] >> 12
- Negate bindings if for clocks


Andre Przywara (3):
  soc: sunxi: sram: export register 0 for THS on H616
  thermal: sun8i: explain unknown H6 register value
  thermal: sun8i: add SRAM register access code

Maksim Kiselev (1):
  thermal: sun8i: extend H6 calibration to support 4 sensors

Martin Botka (3):
  dt-bindings: thermal: sun8i: Add H616 THS controller
  thermal: sun8i: add support for H616 THS controller
  arm64: dts: allwinner: h616: Add thermal sensor and zones

 .../thermal/allwinner,sun8i-a83t-ths.yaml     |  34 +++--
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi |  88 +++++++++++++
 drivers/soc/sunxi/sunxi_sram.c                |  23 ++++
 drivers/thermal/sun8i_thermal.c               | 122 +++++++++++++++---
 4 files changed, 235 insertions(+), 32 deletions(-)

-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 06:42:15 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 14:42:15 +0000
Subject: [PATCH v4 1/7] soc: sunxi: sram: export register 0 for THS on H616
In-Reply-To: <20240209144221.3602382-1-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
Message-ID: <20240209144221.3602382-2-andre.przywara@arm.com>

The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
in the SRAM control block. If bit 16 is set (the reset value), the
temperature readings of the THS are way off, leading to reports about
200C, at normal ambient temperatures. Clearing this bits brings the
reported values down to reasonable ranges.
The BSP code clears this bit in firmware (U-Boot), and has an explicit
comment about this, but offers no real explanation.

Since we should not rely on firmware settings, allow other code (the THS
driver) to access this register, by exporting it through the already
existing regmap. This mimics what we already do for the LDO control and
the EMAC register.

Since this bit is in the very same register as the actual SRAM switch,
we need to change the regmap lock to the SRAM lock. Fortunately regmap
has provisions for that, so we just need to hook in there.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/soc/sunxi/sunxi_sram.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index 4458b2e0562b0..71cdd1b257eeb 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -287,6 +287,7 @@ EXPORT_SYMBOL(sunxi_sram_release);
 struct sunxi_sramc_variant {
 	int num_emac_clocks;
 	bool has_ldo_ctrl;
+	bool has_ths_offset;
 };
 
 static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
@@ -308,8 +309,10 @@ static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
 
 static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
 	.num_emac_clocks = 2,
+	.has_ths_offset = true,
 };
 
+#define SUNXI_SRAM_THS_OFFSET_REG	0x0
 #define SUNXI_SRAM_EMAC_CLOCK_REG	0x30
 #define SUNXI_SYS_LDO_CTRL_REG		0x150
 
@@ -318,6 +321,8 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
 {
 	const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
 
+	if (reg == SUNXI_SRAM_THS_OFFSET_REG && variant->has_ths_offset)
+		return true;
 	if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG &&
 	    reg <  SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
 		return true;
@@ -327,6 +332,21 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
 	return false;
 }
 
+
+static void sunxi_sram_lock(void *_lock)
+{
+	spinlock_t *lock = _lock;
+
+	spin_lock(lock);
+}
+
+static void sunxi_sram_unlock(void *_lock)
+{
+	spinlock_t *lock = _lock;
+
+	spin_unlock(lock);
+}
+
 static struct regmap_config sunxi_sram_regmap_config = {
 	.reg_bits       = 32,
 	.val_bits       = 32,
@@ -336,6 +356,9 @@ static struct regmap_config sunxi_sram_regmap_config = {
 	/* other devices have no business accessing other registers */
 	.readable_reg	= sunxi_sram_regmap_accessible_reg,
 	.writeable_reg	= sunxi_sram_regmap_accessible_reg,
+	.lock		= sunxi_sram_lock,
+	.unlock		= sunxi_sram_unlock,
+	.lock_arg	= &sram_lock,
 };
 
 static int __init sunxi_sram_probe(struct platform_device *pdev)
-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 06:42:16 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 14:42:16 +0000
Subject: [PATCH v4 2/7] dt-bindings: thermal: sun8i: Add H616 THS controller
In-Reply-To: <20240209144221.3602382-1-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
Message-ID: <20240209144221.3602382-3-andre.przywara@arm.com>

From: Martin Botka <martin.botka at somainline.org>

This controller is similar to the H6, but covers four sensors and uses
slightly different calibration methods.
Also the H616 requires to poke a bit in the SYS_CFG register range for
correct operation, so add a phandle property to point there.

Signed-off-by: Martin Botka <martin.botka at somainline.org>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 .../thermal/allwinner,sun8i-a83t-ths.yaml     | 34 +++++++++++++------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
index 9b2272a9ec15d..6b3aea6d73b07 100644
--- a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
+++ b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
@@ -21,6 +21,7 @@ properties:
       - allwinner,sun50i-a100-ths
       - allwinner,sun50i-h5-ths
       - allwinner,sun50i-h6-ths
+      - allwinner,sun50i-h616-ths
 
   clocks:
     minItems: 1
@@ -50,6 +51,10 @@ properties:
   nvmem-cell-names:
     const: calibration
 
+  allwinner,sram:
+    maxItems: 1
+    description: phandle to device controlling temperate offset SYS_CFG register
+
   # See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for details
   "#thermal-sensor-cells":
     enum:
@@ -65,6 +70,7 @@ allOf:
               - allwinner,sun20i-d1-ths
               - allwinner,sun50i-a100-ths
               - allwinner,sun50i-h6-ths
+              - allwinner,sun50i-h616-ths
 
     then:
       properties:
@@ -82,6 +88,17 @@ allOf:
         clock-names:
           minItems: 2
 
+  - if:
+      not:
+        properties:
+          compatible:
+            contains:
+              const: allwinner,sun50i-h616-ths
+
+    then:
+      properties:
+        allwinner,sram: false
+
   - if:
       properties:
         compatible:
@@ -101,17 +118,12 @@ allOf:
           const: 1
 
   - if:
-      properties:
-        compatible:
-          contains:
-            enum:
-              - allwinner,sun8i-h3-ths
-              - allwinner,sun8i-r40-ths
-              - allwinner,sun20i-d1-ths
-              - allwinner,sun50i-a64-ths
-              - allwinner,sun50i-a100-ths
-              - allwinner,sun50i-h5-ths
-              - allwinner,sun50i-h6-ths
+      not:
+        properties:
+          compatible:
+            contains:
+              enum:
+                - allwinner,sun8i-a83t-ths
 
     then:
       required:
-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 06:42:17 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 14:42:17 +0000
Subject: [PATCH v4 3/7] thermal: sun8i: explain unknown H6 register value
In-Reply-To: <20240209144221.3602382-1-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
Message-ID: <20240209144221.3602382-4-andre.przywara@arm.com>

So far we were ORing in some "unknown" value into the THS control
register on the Allwinner H6. This part of the register is not explained
in the H6 manual, but the H616 manual details those bits, and on closer
inspection the THS IP blocks in both SoCs seem very close:
- The BSP code for both SoCs writes the same values into THS_CTRL.
- The reset values of at least the first three registers are the same.

Replace the "unknown" value with its proper meaning: "acquire time",
most probably the sample part of the sample & hold circuit of the ADC,
according to its explanation in the H616 manual.

No functional change, just a macro rename and adjustment.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/thermal/sun8i_thermal.c | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index 6a8e386dbc8dc..42bee03c4e507 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -50,7 +50,8 @@
 #define SUN8I_THS_CTRL2_T_ACQ1(x)		((GENMASK(15, 0) & (x)) << 16)
 #define SUN8I_THS_DATA_IRQ_STS(x)		BIT(x + 8)
 
-#define SUN50I_THS_CTRL0_T_ACQ(x)		((GENMASK(15, 0) & (x)) << 16)
+#define SUN50I_THS_CTRL0_T_ACQ(x)		(GENMASK(15, 0) & ((x) - 1))
+#define SUN50I_THS_CTRL0_T_SAMPLE_PER(x)	((GENMASK(15, 0) & ((x) - 1)) << 16)
 #define SUN50I_THS_FILTER_EN			BIT(2)
 #define SUN50I_THS_FILTER_TYPE(x)		(GENMASK(1, 0) & (x))
 #define SUN50I_H6_THS_PC_TEMP_PERIOD(x)		((GENMASK(19, 0) & (x)) << 12)
@@ -410,25 +411,27 @@ static int sun8i_h3_thermal_init(struct ths_device *tmdev)
 	return 0;
 }
 
-/*
- * Without this undocumented value, the returned temperatures would
- * be higher than real ones by about 20C.
- */
-#define SUN50I_H6_CTRL0_UNK 0x0000002f
-
 static int sun50i_h6_thermal_init(struct ths_device *tmdev)
 {
 	int val;
 
 	/*
-	 * T_acq = 20us
-	 * clkin = 24MHz
-	 *
-	 * x = T_acq * clkin - 1
-	 *   = 479
+	 * The manual recommends an overall sample frequency of 50 KHz (20us,
+	 * 480 cycles at 24 MHz), which provides plenty of time for both the
+	 * acquisition time (>24 cycles) and the actual conversion time
+	 * (>14 cycles).
+	 * The lower half of the CTRL register holds the "acquire time", in
+	 * clock cycles, which the manual recommends to be 2us:
+	 * 24MHz * 2us = 48 cycles.
+	 * The high half of THS_CTRL encodes the sample frequency, in clock
+	 * cycles: 24MHz * 20us = 480 cycles.
+	 * This is explained in the H616 manual, but apparently wrongly
+	 * described in the H6 manual, although the BSP code does the same
+	 * for both SoCs.
 	 */
 	regmap_write(tmdev->regmap, SUN50I_THS_CTRL0,
-		     SUN50I_H6_CTRL0_UNK | SUN50I_THS_CTRL0_T_ACQ(479));
+		     SUN50I_THS_CTRL0_T_ACQ(48) |
+		     SUN50I_THS_CTRL0_T_SAMPLE_PER(480));
 	/* average over 4 samples */
 	regmap_write(tmdev->regmap, SUN50I_H6_THS_MFC,
 		     SUN50I_THS_FILTER_EN |
-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 06:42:18 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 14:42:18 +0000
Subject: [PATCH v4 4/7] thermal: sun8i: extend H6 calibration to support 4 sensors
In-Reply-To: <20240209144221.3602382-1-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
Message-ID: <20240209144221.3602382-5-andre.przywara@arm.com>

From: Maksim Kiselev <bigunclemax at gmail.com>

The H616 SoC resembles the H6 thermal sensor controller, with a few
changes like four sensors.

Extend sun50i_h6_ths_calibrate() function to support calibration of
these sensors.

Signed-off-by: Maksim Kiselev <bigunclemax at gmail.com>
Co-developed-by: Martin Botka <martin.botka at somainline.org>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/thermal/sun8i_thermal.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index 42bee03c4e507..c919b0fd5e169 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -222,16 +222,21 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
 	struct device *dev = tmdev->dev;
 	int i, ft_temp;
 
-	if (!caldata[0] || callen < 2 + 2 * tmdev->chip->sensor_num)
+	if (!caldata[0])
 		return -EINVAL;
 
 	/*
 	 * efuse layout:
 	 *
-	 *	0   11  16	 32
-	 *	+-------+-------+-------+
-	 *	|temp|  |sensor0|sensor1|
-	 *	+-------+-------+-------+
+	 * 0      11  16     27   32     43   48    57
+	 * +----------+-----------+-----------+-----------+
+	 * |  temp |  |sensor0|   |sensor1|   |sensor2|   |
+	 * +----------+-----------+-----------+-----------+
+	 *                      ^           ^           ^
+	 *                      |           |           |
+	 *                      |           |           sensor3[11:8]
+	 *                      |           sensor3[7:4]
+	 *                      sensor3[3:0]
 	 *
 	 * The calibration data on the H6 is the ambient temperature and
 	 * sensor values that are filled during the factory test stage.
@@ -244,9 +249,16 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
 	ft_temp = (caldata[0] & FT_TEMP_MASK) * 100;
 
 	for (i = 0; i < tmdev->chip->sensor_num; i++) {
-		int sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK;
-		int cdata, offset;
-		int sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg);
+		int sensor_reg, sensor_temp, cdata, offset;
+
+		if (i == 3)
+			sensor_reg = (caldata[1] >> 12)
+				     | ((caldata[2] >> 12) << 4)
+				     | ((caldata[3] >> 12) << 8);
+		else
+			sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK;
+
+		sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg);
 
 		/*
 		 * Calibration data is CALIBRATE_DEFAULT - (calculated
-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 06:42:19 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 14:42:19 +0000
Subject: [PATCH v4 5/7] thermal: sun8i: add SRAM register access code
In-Reply-To: <20240209144221.3602382-1-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
Message-ID: <20240209144221.3602382-6-andre.przywara@arm.com>

The Allwinner H616 SoC needs to clear a bit in one register in the SRAM
controller, to report reasonable temperature values. On reset, bit 16 in
register 0x3000000 is set, which leads to the driver reporting
temperatures around 200C. Clearing this bit brings the values down to the
expected range. The BSP code does a one-time write in U-Boot, with a
comment just mentioning the effect on the THS, but offering no further
explanation.

To not rely on firmware to set things up for us, add code that queries
the SRAM controller device via a DT phandle link, then clear just this
single bit.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/thermal/sun8i_thermal.c | 50 +++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index c919b0fd5e169..8a9d2bdc71ece 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/nvmem-consumer.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
@@ -66,6 +67,7 @@ struct tsensor {
 struct ths_thermal_chip {
 	bool            has_mod_clk;
 	bool            has_bus_clk_reset;
+	bool		needs_sram;
 	int		sensor_num;
 	int		offset;
 	int		scale;
@@ -83,6 +85,7 @@ struct ths_device {
 	const struct ths_thermal_chip		*chip;
 	struct device				*dev;
 	struct regmap				*regmap;
+	struct regmap_field			*sram_regmap_field;
 	struct reset_control			*reset;
 	struct clk				*bus_clk;
 	struct clk                              *mod_clk;
@@ -337,6 +340,34 @@ static void sun8i_ths_reset_control_assert(void *data)
 	reset_control_assert(data);
 }
 
+static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node)
+{
+	struct device_node *sram_node;
+	struct platform_device *sram_pdev;
+	struct regmap *regmap = NULL;
+
+	sram_node = of_parse_phandle(node, "allwinner,sram", 0);
+	if (!sram_node)
+		return ERR_PTR(-ENODEV);
+
+	sram_pdev = of_find_device_by_node(sram_node);
+	if (!sram_pdev) {
+		/* platform device might not be probed yet */
+		regmap = ERR_PTR(-EPROBE_DEFER);
+		goto out_put_node;
+	}
+
+	/* If no regmap is found then the other device driver is at fault */
+	regmap = dev_get_regmap(&sram_pdev->dev, NULL);
+	if (!regmap)
+		regmap = ERR_PTR(-EINVAL);
+
+	platform_device_put(sram_pdev);
+out_put_node:
+	of_node_put(sram_node);
+	return regmap;
+}
+
 static int sun8i_ths_resource_init(struct ths_device *tmdev)
 {
 	struct device *dev = tmdev->dev;
@@ -381,6 +412,21 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev)
 	if (ret)
 		return ret;
 
+	if (tmdev->chip->needs_sram) {
+		const struct reg_field sun8i_sram_reg_field =
+			REG_FIELD(0x0, 16, 16);
+		struct regmap *regmap;
+
+		regmap = sun8i_ths_get_sram_regmap(dev->of_node);
+		if (IS_ERR(regmap))
+			return PTR_ERR(regmap);
+		tmdev->sram_regmap_field = devm_regmap_field_alloc(dev,
+						      regmap,
+						      sun8i_sram_reg_field);
+		if (IS_ERR(tmdev->sram_regmap_field))
+			return PTR_ERR(tmdev->sram_regmap_field);
+	}
+
 	ret = sun8i_ths_calibrate(tmdev);
 	if (ret)
 		return ret;
@@ -427,6 +473,10 @@ static int sun50i_h6_thermal_init(struct ths_device *tmdev)
 {
 	int val;
 
+	/* The H616 needs to have a bit in the SRAM control register cleared. */
+	if (tmdev->sram_regmap_field)
+		regmap_field_write(tmdev->sram_regmap_field, 0);
+
 	/*
 	 * The manual recommends an overall sample frequency of 50 KHz (20us,
 	 * 480 cycles at 24 MHz), which provides plenty of time for both the
-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 06:42:20 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 14:42:20 +0000
Subject: [PATCH v4 6/7] thermal: sun8i: add support for H616 THS controller
In-Reply-To: <20240209144221.3602382-1-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
Message-ID: <20240209144221.3602382-7-andre.przywara@arm.com>

From: Martin Botka <martin.botka at somainline.org>

Add support for the thermal sensor found in H616 SoCs, is the same as
the H6 thermal sensor controller, but with four sensors.
Also the registers readings are wrong, unless a bit in the first SYS_CFG
register cleared, so set exercise the SRAM regmap to take care of that.

Signed-off-by: Martin Botka <martin.botka at somainline.org>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/thermal/sun8i_thermal.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index 8a9d2bdc71ece..172410a9e0274 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -683,6 +683,20 @@ static const struct ths_thermal_chip sun20i_d1_ths = {
 	.calc_temp = sun8i_ths_calc_temp,
 };
 
+static const struct ths_thermal_chip sun50i_h616_ths = {
+	.sensor_num = 4,
+	.has_bus_clk_reset = true,
+	.needs_sram = true,
+	.ft_deviation = 8000,
+	.offset = 263655,
+	.scale = 810,
+	.temp_data_base = SUN50I_H6_THS_TEMP_DATA,
+	.calibrate = sun50i_h6_ths_calibrate,
+	.init = sun50i_h6_thermal_init,
+	.irq_ack = sun50i_h6_irq_ack,
+	.calc_temp = sun8i_ths_calc_temp,
+};
+
 static const struct of_device_id of_ths_match[] = {
 	{ .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths },
 	{ .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths },
@@ -692,6 +706,7 @@ static const struct of_device_id of_ths_match[] = {
 	{ .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths },
 	{ .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths },
 	{ .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths },
+	{ .compatible = "allwinner,sun50i-h616-ths", .data = &sun50i_h616_ths },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, of_ths_match);
-- 
2.25.1



From andre.przywara at arm.com  Fri Feb  9 06:42:21 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  9 Feb 2024 14:42:21 +0000
Subject: [PATCH v4 7/7] arm64: dts: allwinner: h616: Add thermal sensor and zones
In-Reply-To: <20240209144221.3602382-1-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
Message-ID: <20240209144221.3602382-8-andre.przywara@arm.com>

From: Martin Botka <martin.botka at somainline.org>

There are four thermal sensors:
- CPU
- GPU
- VE
- DRAM

Add the thermal sensor configuration and the thermal zones.

Signed-off-by: Martin Botka <martin.botka at somainline.org>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 88 +++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index 12ffabc79bcde..7c7d7c285505c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -9,6 +9,7 @@
 #include <dt-bindings/clock/sun6i-rtc.h>
 #include <dt-bindings/reset/sun50i-h616-ccu.h>
 #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -138,6 +139,10 @@ sid: efuse at 3006000 {
 			reg = <0x03006000 0x1000>;
 			#address-cells = <1>;
 			#size-cells = <1>;
+
+			ths_calibration: thermal-sensor-calibration at 14 {
+				reg = <0x14 0x8>;
+			};
 		};
 
 		watchdog: watchdog at 30090a0 {
@@ -517,6 +522,19 @@ mdio0: mdio {
 			};
 		};
 
+		ths: thermal-sensor at 5070400 {
+			compatible = "allwinner,sun50i-h616-ths";
+			reg = <0x05070400 0x400>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_THS>;
+			clock-names = "bus";
+			resets = <&ccu RST_BUS_THS>;
+			nvmem-cells = <&ths_calibration>;
+			nvmem-cell-names = "calibration";
+			allwinner,sram = <&syscon>;
+			#thermal-sensor-cells = <1>;
+		};
+
 		usbotg: usb at 5100000 {
 			compatible = "allwinner,sun50i-h616-musb",
 				     "allwinner,sun8i-h3-musb";
@@ -761,4 +779,74 @@ r_rsb: rsb at 7083000 {
 			#size-cells = <0>;
 		};
 	};
+
+	thermal-zones {
+		cpu-thermal {
+			polling-delay-passive = <500>;
+			polling-delay = <1000>;
+			thermal-sensors = <&ths 2>;
+			sustainable-power = <1000>;
+
+			trips {
+				cpu_threshold: cpu-trip-0 {
+					temperature = <60000>;
+					type = "passive";
+					hysteresis = <0>;
+				};
+				cpu_target: cpu-trip-1 {
+					temperature = <70000>;
+					type = "passive";
+					hysteresis = <0>;
+				};
+				cpu_critical: cpu-trip-2 {
+					temperature = <110000>;
+					type = "critical";
+					hysteresis = <0>;
+				};
+			};
+		};
+
+		gpu-thermal {
+			polling-delay-passive = <500>;
+			polling-delay = <1000>;
+			thermal-sensors = <&ths 0>;
+			sustainable-power = <1100>;
+
+			trips {
+				gpu_temp_critical: gpu-trip-0 {
+					temperature = <110000>;
+					type = "critical";
+					hysteresis = <0>;
+				};
+			};
+		};
+
+		ve-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&ths 1>;
+
+			trips {
+				ve_temp_critical: ve-trip-0 {
+					temperature = <110000>;
+					type = "critical";
+					hysteresis = <0>;
+				};
+			};
+		};
+
+		ddr-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&ths 3>;
+
+			trips {
+				ddr_temp_critical: ddr-trip-0 {
+					temperature = <110000>;
+					type = "critical";
+					hysteresis = <0>;
+				};
+			};
+		};
+	};
 };
-- 
2.25.1



From alexey.klimov at linaro.org  Fri Feb  9 06:52:20 2024
From: alexey.klimov at linaro.org (Alexey Klimov)
Date: Fri, 9 Feb 2024 14:52:20 +0000
Subject: [PATCH v4 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <20240208161700.268570-2-peter.griffin@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org> <20240208161700.268570-2-peter.griffin@linaro.org>
Message-ID: <CANgGJDpJX+ji1U3SN+2Q21FyckFQhmwb-Z2Qcx4-+GQ2ijmfCg@mail.gmail.com>

On Thu, 8 Feb 2024 at 16:21, Peter Griffin <peter.griffin at linaro.org> wrote:
>
> Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> security hardening reasons so that they are only write accessible in el3
> via an SMC call.
>
> As most Exynos drivers that need to write PMU registers currently obtain a
> regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> is implemented in this driver using a custom regmap similar to syscon to
> handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> regmap like before. As regmaps abstract out the underlying register access
> changes to the leaf drivers are minimal.
>
> A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> that currently use syscon_regmap_lookup_by_phandle(). This also handles
> deferred probing.
>
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>

Tested-by: Alexey Klimov <alexey.klimov at linaro.org>

Apparently it seems tested-by should be provided for both patches. This was
also tested on odroid xu3 and I also have WIP code that depends on this
SMC-based regmap. No issues are observed and behaves as expected.

> ---
> Changes since v3:
>  - Fix PMUALIVE_MASK
>  - Add TENSOR_ prefix
>  - clear SET_BITS bits on each loop iteration
>  - change set_bit to set_bits in func name
>  - Fix some alignment
>  - Add missing return on dev_err_probe
>  - Reduce indentation in loop

I no longer see the compilation warning related to struct device_node declared
inside parameter list with v4, I guess one line change addition in exynos-pmu.h
does the job.

Thank you!
BR,
Alexey


From Dharma.B at microchip.com  Fri Feb  9 07:02:25 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Fri, 9 Feb 2024 15:02:25 +0000
Subject: [PATCH v3 1/4] dt-bindings: display: bridge: add sam9x75-lvds
 compatible
In-Reply-To: <b314e446-e79c-4fa0-9b86-c58fa96133bc@microchip.com>
References: <20240207102802.200220-1-dharma.b@microchip.com>
 <20240207102802.200220-2-dharma.b@microchip.com>
 <2219df60-7235-4c37-b79c-25e7225cb7a9@kernel.org>
 <b314e446-e79c-4fa0-9b86-c58fa96133bc@microchip.com>
Message-ID: <c82a3843-1b58-46ea-994a-8350544aa30d@microchip.com>

On 09/02/24 7:50 pm, Dharma B wrote:
> On 08/02/24 2:31 pm, Krzysztof Kozlowski wrote:
>> EXTERNAL EMAIL: Do not click links or open attachments unless you know 
>> the content is safe
>>
>> On 07/02/2024 11:27, Dharma Balasubiramani wrote:
>>> Add the 'sam9x75-lvds' compatible binding, which describes the Low 
>>> Voltage
>>> Differential Signaling (LVDS) Controller found on some Microchip's 
>>> sam9x7
>>> series System-on-Chip (SoC) devices. This binding will be used to define
>>> the properties and configuration for the LVDS Controller in DT.
>>>
>>> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
>>
>> Not tested...
>>
>> Please use scripts/get_maintainers.pl to get a list of necessary people
>> and lists to CC. It might happen, that command when run on an older
>> kernel, gives you outdated entries. Therefore please be sure you base
>> your patches on recent Linux kernel.
>>
>> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
>> people, so fix your workflow. Tools might also fail if you work on some
>> ancient tree (don't, instead use mainline), work on fork of kernel
>> (don't, instead use mainline) or you ignore some maintainers (really
>> don't). Just use b4 and everything should be fine, although remember
>> about `b4 prep --auto-to-cc` if you added new patches to the patchset.
>>
>> You missed at least devicetree list (maybe more), so this won't be
>> tested by automated tooling. Performing review on untested code might be
>> a waste of time.
> 
> Apologies for the oversight, somehow it got missed.

The get_maintainer.pl seems to be inconsistent with the results.

linux$ ./scripts/get_maintainer.pl *patch | wc -l
./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
appear to be a patch.  Add -f to options?
31
linux$ ./scripts/get_maintainer.pl *patch | wc -l
./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
appear to be a patch.  Add -f to options?
29
linux$ ./scripts/get_maintainer.pl *patch | wc -l
./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
appear to be a patch.  Add -f to options?
30
linux$ ./scripts/get_maintainer.pl *patch | wc -l
./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
appear to be a patch.  Add -f to options?
30

Anyway, I will add the largest recipients list in v4.
>>
>> Please kindly resend and include all necessary To/Cc entries.
> 
> I will resend the series including all necessary To/Cc entries.
> 
> Thanks.
>>
>>
>> Best regards,
>> Krzysztof
>>
> 

-- 
With Best Regards,
Dharma B.


From dharma.b at microchip.com  Fri Feb  9 07:07:53 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 9 Feb 2024 20:37:53 +0530
Subject: [PATCH v4 0/4] LVDS Controller Support for SAM9X75 SoC
Message-ID: <20240209150757.66914-1-dharma.b@microchip.com>

This patch series introduces LVDS controller support for the SAM9X75 SoC. The
LVDS controller is designed to work with Microchip's sam9x7 series
System-on-Chip (SoC) devices, providing Low Voltage Differential Signaling
capabilities.

Patch series Changelog:
- Include configs: at91: Enable LVDS serializer
- include all necessary To/Cc entries.
The Individual Changelogs are available on the respective patches.

Dharma Balasubiramani (4):
  dt-bindings: display: bridge: add sam9x75-lvds binding
  drm/bridge: add lvds controller support for sam9x7
  MAINTAINERS: add SAM9X7 SoC's LVDS controller
  ARM: configs: at91: Enable LVDS serializer support

 .../bridge/microchip,sam9x75-lvds.yaml        |  55 +++++
 MAINTAINERS                                   |   8 +
 arch/arm/configs/at91_dt_defconfig            |   1 +
 drivers/gpu/drm/bridge/Kconfig                |   7 +
 drivers/gpu/drm/bridge/Makefile               |   1 +
 drivers/gpu/drm/bridge/microchip-lvds.c       | 228 ++++++++++++++++++
 6 files changed, 300 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/microchip,sam9x75-lvds.yaml
 create mode 100644 drivers/gpu/drm/bridge/microchip-lvds.c


base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
-- 
2.25.1



From dharma.b at microchip.com  Fri Feb  9 07:07:55 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 9 Feb 2024 20:37:55 +0530
Subject: [PATCH v4 2/4] drm/bridge: add lvds controller support for sam9x7
In-Reply-To: <20240209150757.66914-1-dharma.b@microchip.com>
References: <20240209150757.66914-1-dharma.b@microchip.com>
Message-ID: <20240209150757.66914-3-dharma.b@microchip.com>

Add a new LVDS controller driver for sam9x7 which does the following:
- Prepares and enables the LVDS Peripheral clock
- Defines its connector type as DRM_MODE_CONNECTOR_LVDS and adds itself
to the global bridge list.
- Identifies its output endpoint as panel and adds it to the encoder
display pipeline
- Enables the LVDS serializer

Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
Changelog
v3 -> v4
- No changes.
v2 ->v3
- Correct Typo error "serializer".
- Consolidate get() and prepare() functions and use devm_clk_get_prepared().
- Remove unused variable 'ret' in probe().
- Use devm_pm_runtime_enable() and drop the mchp_lvds_remove().
v1 -> v2
- Drop 'res' variable and combine two lines into one.
- Handle deferred probe properly, use dev_err_probe().
- Don't print anything on deferred probe. Dropped print.
- Remove the MODULE_ALIAS and add MODULE_DEVICE_TABLE().
- symbol 'mchp_lvds_driver' was not declared. It should be static.
---
 drivers/gpu/drm/bridge/Kconfig          |   7 +
 drivers/gpu/drm/bridge/Makefile         |   1 +
 drivers/gpu/drm/bridge/microchip-lvds.c | 228 ++++++++++++++++++++++++
 3 files changed, 236 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/microchip-lvds.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 3e6a4e2044c0..74ca0edb4e0d 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -173,6 +173,13 @@ config DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW
 	  to DP++. This is used with the i.MX6 imx-ldb
 	  driver. You are likely to say N here.
 
+config DRM_MICROCHIP_LVDS_SERIALIZER
+	tristate "Microchip LVDS serializer support"
+	depends on OF
+	depends on DRM_ATMEL_HLCDC
+	help
+	  Support for Microchip's LVDS serializer.
+
 config DRM_NWL_MIPI_DSI
 	tristate "Northwest Logic MIPI DSI Host controller"
 	depends on DRM
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 2b892b7ed59e..e3804e93d324 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
 obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o
 obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o
 obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
+obj-$(CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER) += microchip-lvds.o
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
 obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
diff --git a/drivers/gpu/drm/bridge/microchip-lvds.c b/drivers/gpu/drm/bridge/microchip-lvds.c
new file mode 100644
index 000000000000..d3fd9d722e36
--- /dev/null
+++ b/drivers/gpu/drm/bridge/microchip-lvds.c
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Manikandan Muralidharan <manikandan.m at microchip.com>
+ * Author: Dharma Balasubiramani <dharma.b at microchip.com>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_graph.h>
+#include <linux/pinctrl/devinfo.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+
+#define LVDS_POLL_TIMEOUT_MS 1000
+
+/* LVDSC register offsets */
+#define LVDSC_CR	0x00
+#define LVDSC_CFGR	0x04
+#define LVDSC_SR	0x0C
+#define LVDSC_WPMR	0xE4
+
+/* Bitfields in LVDSC_CR (Control Register) */
+#define LVDSC_CR_SER_EN	BIT(0)
+
+/* Bitfields in LVDSC_CFGR (Configuration Register) */
+#define LVDSC_CFGR_PIXSIZE_24BITS	0
+#define LVDSC_CFGR_DEN_POL_HIGH		0
+#define LVDSC_CFGR_DC_UNBALANCED	0
+#define LVDSC_CFGR_MAPPING_JEIDA	BIT(6)
+
+/*Bitfields in LVDSC_SR */
+#define LVDSC_SR_CS	BIT(0)
+
+/* Bitfields in LVDSC_WPMR (Write Protection Mode Register) */
+#define LVDSC_WPMR_WPKEY_MASK	GENMASK(31, 8)
+#define LVDSC_WPMR_WPKEY_PSSWD	0x4C5644
+
+struct mchp_lvds {
+	struct device *dev;
+	void __iomem *regs;
+	struct clk *pclk;
+	int format; /* vesa or jeida format */
+	struct drm_panel *panel;
+	struct drm_bridge bridge;
+	struct drm_bridge *panel_bridge;
+};
+
+static inline struct mchp_lvds *bridge_to_lvds(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct mchp_lvds, bridge);
+}
+
+static inline u32 lvds_readl(struct mchp_lvds *lvds, u32 offset)
+{
+	return readl_relaxed(lvds->regs + offset);
+}
+
+static inline void lvds_writel(struct mchp_lvds *lvds, u32 offset, u32 val)
+{
+	writel_relaxed(val, lvds->regs + offset);
+}
+
+static void lvds_serialiser_on(struct mchp_lvds *lvds)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(LVDS_POLL_TIMEOUT_MS);
+
+	/* The LVDSC registers can only be written if WPEN is cleared */
+	lvds_writel(lvds, LVDSC_WPMR, (LVDSC_WPMR_WPKEY_PSSWD &
+				LVDSC_WPMR_WPKEY_MASK));
+
+	/* Wait for the status of configuration registers to be changed */
+	while (lvds_readl(lvds, LVDSC_SR) & LVDSC_SR_CS) {
+		if (time_after(jiffies, timeout)) {
+			dev_err(lvds->dev, "%s: timeout error\n", __func__);
+			return;
+		}
+		usleep_range(1000, 2000);
+	}
+
+	/* Configure the LVDSC */
+	lvds_writel(lvds, LVDSC_CFGR, (LVDSC_CFGR_MAPPING_JEIDA |
+				LVDSC_CFGR_DC_UNBALANCED |
+				LVDSC_CFGR_DEN_POL_HIGH |
+				LVDSC_CFGR_PIXSIZE_24BITS));
+
+	/* Enable the LVDS serializer */
+	lvds_writel(lvds, LVDSC_CR, LVDSC_CR_SER_EN);
+}
+
+static int mchp_lvds_attach(struct drm_bridge *bridge,
+			    enum drm_bridge_attach_flags flags)
+{
+	struct mchp_lvds *lvds = bridge_to_lvds(bridge);
+
+	bridge->encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
+
+	return drm_bridge_attach(bridge->encoder, lvds->panel_bridge,
+				 bridge, flags);
+}
+
+static void mchp_lvds_enable(struct drm_bridge *bridge)
+{
+	struct mchp_lvds *lvds = bridge_to_lvds(bridge);
+	int ret;
+
+	ret = clk_enable(lvds->pclk);
+	if (ret < 0) {
+		DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
+		return;
+	}
+
+	ret = pm_runtime_get_sync(lvds->dev);
+	if (ret < 0) {
+		DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
+		clk_disable(lvds->pclk);
+		return;
+	}
+
+	lvds_serialiser_on(lvds);
+}
+
+static void mchp_lvds_disable(struct drm_bridge *bridge)
+{
+	struct mchp_lvds *lvds = bridge_to_lvds(bridge);
+
+	pm_runtime_put(lvds->dev);
+	clk_disable(lvds->pclk);
+}
+
+static const struct drm_bridge_funcs mchp_lvds_bridge_funcs = {
+	.attach = mchp_lvds_attach,
+	.enable = mchp_lvds_enable,
+	.disable = mchp_lvds_disable,
+};
+
+static int mchp_lvds_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mchp_lvds *lvds;
+	struct device_node *port;
+
+	if (!dev->of_node)
+		return -ENODEV;
+
+	lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL);
+	if (!lvds)
+		return -ENOMEM;
+
+	lvds->dev = dev;
+
+	lvds->regs = devm_ioremap_resource(lvds->dev,
+			platform_get_resource(pdev, IORESOURCE_MEM, 0));
+	if (IS_ERR(lvds->regs))
+		return PTR_ERR(lvds->regs);
+
+	lvds->pclk = devm_clk_get_prepared(lvds->dev, "pclk");
+	if (IS_ERR(lvds->pclk))
+		return dev_err_probe(lvds->dev, PTR_ERR(lvds->pclk),
+				"could not get pclk_lvds prepared\n");
+
+	port = of_graph_get_remote_node(dev->of_node, 1, 0);
+	if (!port) {
+		DRM_DEV_ERROR(dev,
+			      "can't find port point, please init lvds panel port!\n");
+		return -EINVAL;
+	}
+
+	lvds->panel = of_drm_find_panel(port);
+	of_node_put(port);
+
+	if (IS_ERR(lvds->panel))
+		return -EPROBE_DEFER;
+
+	lvds->panel_bridge = devm_drm_panel_bridge_add(dev, lvds->panel);
+
+	if (IS_ERR(lvds->panel_bridge))
+		return PTR_ERR(lvds->panel_bridge);
+
+	lvds->bridge.of_node = dev->of_node;
+	lvds->bridge.type = DRM_MODE_CONNECTOR_LVDS;
+	lvds->bridge.funcs = &mchp_lvds_bridge_funcs;
+
+	dev_set_drvdata(dev, lvds);
+	devm_pm_runtime_enable(dev);
+
+	drm_bridge_add(&lvds->bridge);
+
+	return 0;
+}
+
+static const struct of_device_id mchp_lvds_dt_ids[] = {
+	{
+		.compatible = "microchip,sam9x75-lvds",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mchp_lvds_dt_ids);
+
+static struct platform_driver mchp_lvds_driver = {
+	.probe = mchp_lvds_probe,
+	.driver = {
+		   .name = "microchip-lvds",
+		   .of_match_table = mchp_lvds_dt_ids,
+	},
+};
+module_platform_driver(mchp_lvds_driver);
+
+MODULE_AUTHOR("Manikandan Muralidharan <manikandan.m at microchip.com>");
+MODULE_AUTHOR("Dharma Balasubiramani <dharma.b at microchip.com>");
+MODULE_DESCRIPTION("Low Voltage Differential Signaling Controller Driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From dharma.b at microchip.com  Fri Feb  9 07:07:54 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 9 Feb 2024 20:37:54 +0530
Subject: [PATCH v4 1/4] dt-bindings: display: bridge: add sam9x75-lvds binding
In-Reply-To: <20240209150757.66914-1-dharma.b@microchip.com>
References: <20240209150757.66914-1-dharma.b@microchip.com>
Message-ID: <20240209150757.66914-2-dharma.b@microchip.com>

Add the 'sam9x75-lvds' compatible binding, which describes the Low Voltage
Differential Signaling (LVDS) Controller found on some Microchip's sam9x7
series System-on-Chip (SoC) devices. This binding will be used to define
the properties and configuration for the LVDS Controller in DT.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
Changelog
v3 -> v4
- Rephrase the commit subject.
v2 -> v3
- No changes.
v1 -> v2
- Remove '|' in description, as there is no formatting to preserve.
- Remove 'gclk' from clock-names as there is only one clock(pclk).
- Remove the unused headers and include only used ones.
- Change the compatible name specific to SoC (sam9x75) instead of entire series.
- Change file name to match the compatible name.
---
 .../bridge/microchip,sam9x75-lvds.yaml        | 55 +++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/microchip,sam9x75-lvds.yaml

diff --git a/Documentation/devicetree/bindings/display/bridge/microchip,sam9x75-lvds.yaml b/Documentation/devicetree/bindings/display/bridge/microchip,sam9x75-lvds.yaml
new file mode 100644
index 000000000000..862ef441ac9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/microchip,sam9x75-lvds.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/microchip,sam9x75-lvds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip SAM9X75 LVDS Controller
+
+maintainers:
+  - Dharma Balasubiramani <dharma.b at microchip.com>
+
+description:
+  The Low Voltage Differential Signaling Controller (LVDSC) manages data
+  format conversion from the LCD Controller internal DPI bus to OpenLDI
+  LVDS output signals. LVDSC functions include bit mapping, balanced mode
+  management, and serializer.
+
+properties:
+  compatible:
+    const: microchip,sam9x75-lvds
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Peripheral Bus Clock
+
+  clock-names:
+    items:
+      - const: pclk
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/at91.h>
+    lvds-controller at f8060000 {
+      compatible = "microchip,sam9x75-lvds";
+      reg = <0xf8060000 0x100>;
+      interrupts = <56 IRQ_TYPE_LEVEL_HIGH 0>;
+      clocks = <&pmc PMC_TYPE_PERIPHERAL 56>;
+      clock-names = "pclk";
+    };
-- 
2.25.1



From dharma.b at microchip.com  Fri Feb  9 07:07:56 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 9 Feb 2024 20:37:56 +0530
Subject: [PATCH v4 3/4] MAINTAINERS: add SAM9X7 SoC's LVDS controller
In-Reply-To: <20240209150757.66914-1-dharma.b@microchip.com>
References: <20240209150757.66914-1-dharma.b@microchip.com>
Message-ID: <20240209150757.66914-4-dharma.b@microchip.com>

Add the newly added LVDS controller for the SAM9X7 SoC to the existing
MAINTAINERS entry.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
Changelog
v3 ->v4
- No changes.
v2 -> v3
- Move the entry before "MICROCHIP SAMA5D2-COMPATIBLE ADC DRIVER".
v1 -> v2
- No Changes.
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a7c4cf8201e0..ce592b6cf375 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14216,6 +14216,14 @@ S:	Supported
 F:	Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml
 F:	drivers/pwm/pwm-atmel.c
 
+MICROCHIP SAM9x7-COMPATIBLE LVDS CONTROLLER
+M:	Manikandan Muralidharan <manikandan.m at microchip.com>
+M:	Dharma Balasubiramani <dharma.b at microchip.com>
+L:	dri-devel at lists.freedesktop.org
+S:	Supported
+F:	Documentation/devicetree/bindings/display/bridge/microchip,sam9x7-lvds.yaml
+F:	drivers/gpu/drm/bridge/microchip-lvds.c
+
 MICROCHIP SAMA5D2-COMPATIBLE ADC DRIVER
 M:	Eugen Hristev <eugen.hristev at microchip.com>
 L:	linux-iio at vger.kernel.org
-- 
2.25.1



From dharma.b at microchip.com  Fri Feb  9 07:07:57 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 9 Feb 2024 20:37:57 +0530
Subject: [PATCH v4 4/4] ARM: configs: at91: Enable LVDS serializer support
In-Reply-To: <20240209150757.66914-1-dharma.b@microchip.com>
References: <20240209150757.66914-1-dharma.b@microchip.com>
Message-ID: <20240209150757.66914-5-dharma.b@microchip.com>

Enable LVDS serializer support for display pipeline.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Acked-by: Hari Prasath Gujulan Elango <hari.prasathge at microchip.com>
Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
Changelog
v3 -> v4
- No Changes.
v2 -> v3
- No Changes.
---
 arch/arm/configs/at91_dt_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index 71b5acc78187..6a7714beb099 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -143,6 +143,7 @@ CONFIG_VIDEO_OV2640=m
 CONFIG_VIDEO_OV7740=m
 CONFIG_DRM=y
 CONFIG_DRM_ATMEL_HLCDC=y
+CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER=y
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_PANEL_EDP=y
 CONFIG_FB_ATMEL=y
-- 
2.25.1



From peter.griffin at linaro.org  Fri Feb  9 07:19:23 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 9 Feb 2024 15:19:23 +0000
Subject: [PATCH v4 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <CANgGJDpJX+ji1U3SN+2Q21FyckFQhmwb-Z2Qcx4-+GQ2ijmfCg@mail.gmail.com>
References: <20240208161700.268570-1-peter.griffin@linaro.org>
 <20240208161700.268570-2-peter.griffin@linaro.org> <CANgGJDpJX+ji1U3SN+2Q21FyckFQhmwb-Z2Qcx4-+GQ2ijmfCg@mail.gmail.com>
Message-ID: <CADrjBPqaUQXjkXLN8JagjF=HG6moXTRMULzKU93BCGo5iAqi-A@mail.gmail.com>

Hi Alexey,

On Fri, 9 Feb 2024 at 14:52, Alexey Klimov <alexey.klimov at linaro.org> wrote:
>
> On Thu, 8 Feb 2024 at 16:21, Peter Griffin <peter.griffin at linaro.org> wrote:
> >
> > Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> > security hardening reasons so that they are only write accessible in el3
> > via an SMC call.
> >
> > As most Exynos drivers that need to write PMU registers currently obtain a
> > regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> > is implemented in this driver using a custom regmap similar to syscon to
> > handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> > regmap like before. As regmaps abstract out the underlying register access
> > changes to the leaf drivers are minimal.
> >
> > A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> > that currently use syscon_regmap_lookup_by_phandle(). This also handles
> > deferred probing.
> >
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
>
> Tested-by: Alexey Klimov <alexey.klimov at linaro.org>

Thanks for testing this on odroid xu3 hardware!

>
> Apparently it seems tested-by should be provided for both patches. This was
> also tested on odroid xu3 and I also have WIP code that depends on this
> SMC-based regmap. No issues are observed and behaves as expected.
>
> > ---
> > Changes since v3:
> >  - Fix PMUALIVE_MASK
> >  - Add TENSOR_ prefix
> >  - clear SET_BITS bits on each loop iteration
> >  - change set_bit to set_bits in func name
> >  - Fix some alignment
> >  - Add missing return on dev_err_probe
> >  - Reduce indentation in loop
>
> I no longer see the compilation warning related to struct device_node declared
> inside parameter list with v4, I guess one line change addition in exynos-pmu.h
> does the job.

I added a forward declaration in the header to get rid of that
compiler warning in v4, but it's not explicitly mentioned in the above
changelog.

Thanks,

Peter.


Peter


From mripard at kernel.org  Fri Feb  9 07:41:54 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Fri, 9 Feb 2024 16:41:54 +0100
Subject: [PATCH 0/4] Fixing live video input in ZynqMP DPSUB
In-Reply-To: <20240204095618.GJ3094@pendragon.ideasonboard.com>
References: <20240112234222.913138-1-anatoliy.klymenko@amd.com>
 <6jhwss2wego6yoo5mwmphwawhsj5bbj62gwrzcpapoixwkrkli@g4fbxdooopby>
 <20240117142343.GD17920@pendragon.ideasonboard.com>
 <u5mngxudtdgy3vqkfbpgqng6tdahijnet2jtj345hrowbt47ce@t3e7hul45mr3>
 <MW4PR12MB7165D35189BEECA8769552AFE6792@MW4PR12MB7165.namprd12.prod.outlook.com>
 <2ytxhpti53e743b5pca3oa5jmscffi4vpsyeh727bcoh4v6cuw@zkz5pqkcv7v2>
 <20240204095618.GJ3094@pendragon.ideasonboard.com>
Message-ID: <casqzvlydzfckbn2glxn2n2ywtiqzuam2hyn3qpbroaykp5drv@ygeuniecym4w>

On Sun, Feb 04, 2024 at 11:56:18AM +0200, Laurent Pinchart wrote:
> On Thu, Feb 01, 2024 at 06:01:01PM +0100, Maxime Ripard wrote:
> > On Fri, Jan 26, 2024 at 11:18:30PM +0000, Klymenko, Anatoliy wrote:
> > > On Friday, January 26, 2024 4:26 AM, Maxime Ripard wrote:
> > > > On Wed, Jan 17, 2024 at 04:23:43PM +0200, Laurent Pinchart wrote:
> > > > > On Mon, Jan 15, 2024 at 09:28:39AM +0100, Maxime Ripard wrote:
> > > > > > On Fri, Jan 12, 2024 at 03:42:18PM -0800, Anatoliy Klymenko wrote:
> > > > > > > Patches 1/4,2/4,3/4 are minor fixes.
> > > > > > >
> > > > > > > DPSUB requires input live video format to be configured.
> > > > > > > Patch 4/4: The DP Subsystem requires the input live video format to be
> > > > > > > configured. In this patch we are assuming that the CRTC's bus format is fixed
> > > > > > > and comes from the device tree. This is a proposed solution, as there are no api
> > > > > > > to query CRTC output bus format.
> > > > > > >
> > > > > > > Is this a good approach to go with?
> > > > > >
> > > > > > I guess you would need to expand a bit on what "live video input" is? Is
> > > > > > it some kind of mechanism to bypass memory and take your pixels straight
> > > > > > from a FIFO from another device, or something else?
> > > > >
> > > > > Yes and no.
> > > > >
> > > > > The DPSUB integrates DMA engines, a blending engine (two planes), and a
> > > > > DP encoder. The dpsub driver supports all of this, and creates a DRM
> > > > > device. The DP encoder hardware always takes its input data from the
> > > > > output of the blending engine.
> > > > >
> > > > > The blending engine can optionally take input data from a bus connected
> > > > > to the FPGA fabric, instead of taking it from the DPSUB internal DMA
> > > > > engines. When operating in that mode, the dpsub driver exposes the DP
> > > > > encoder as a bridge, and internally programs the blending engine to
> > > > > disable blending. Typically, the FPGA fabric will then contain a CRTC of
> > > > > some sort, with a driver that will acquire the DP encoder bridge as
> > > > > usually done.
> > > > >
> > > > > In this mode of operation, it is typical for the IP cores in FPGA fabric
> > > > > to be synthesized with a fixed format (as that saves resources), while
> > > > > the DPSUB supports multiple input formats.
> > > > 
> > > > Where is that CRTC driver? It's not clear to me why the format would
> > > > need to be in the device tree at all. Format negociation between the
> > > > CRTC and whatever comes next is already done in a number of drivers so
> > > > it would be useful to have that kind of API outside of the bridge
> > > > support.
> > >
> > > One example of such CRTC driver:
> > > https://github.com/Xilinx/linux-xlnx/blob/master/drivers/gpu/drm/xlnx/xlnx_mixer.c It's not
> > > upstreamed yet. Bus format negotiations here are handled by utilizing Xilinx-specific bridge
> > > framework. Ideally, it would be nice to rework this to comply with the upstream DRM bridge
> > > framework.
> > >
> > > > > Bridge drivers in the upstream kernel work the other way around, with
> > > > > the bridge hardware supporting a limited set of formats, and the CRTC
> > > > > then being programmed with whatever the bridges chain needs. Here, the
> > > > > negotiation needs to go the other way around, as the CRTC is the
> > > > > limiting factor, not the bridge.
> > > > 
> > > > Sounds like there's something to rework in the API then?
> > > > 
> > > Adding an optional CRTC callback imposing CRTC specific bus format restrictions, which may be
> > > called from here https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/drm_bridge.c#L935
> > > would solve the problem.
> > 
> > CRTCs and bridges are orthogonal. If anything, I'd expect that callback
> > to be set at the CRTC, encoder and connector levels and filled by the
> > drm_bridge code if relevant.
> 
> I'm thinking about a new CRTC operation that would be called by the
> bridge chain format negotiation helper
> drm_atomic_bridge_chain_select_bus_fmts() (or one of the functions it
> calls), to filter the list of formats supported by the chain based on
> what the CRTC supports, or possibly to pick a format in that list. This
> needs to be prototyped

As long as we come up with something that works for regular encoders,
I'm fine with that.

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/20240209/4349a10c/attachment-0001.sig>

From broonie at kernel.org  Fri Feb  9 07:42:08 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 9 Feb 2024 15:42:08 +0000
Subject: [PATCH v1] KVM: arm64: print Hyp mode
In-Reply-To: <20240209103719.3813599-1-joey.gouly@arm.com>
References: <20240209103719.3813599-1-joey.gouly@arm.com>
Message-ID: <ZcZH0JKqoQbJ/fr5@finisterre.sirena.org.uk>

On Fri, Feb 09, 2024 at 10:37:19AM +0000, Joey Gouly wrote:
> Print which of the hyp modes is being used (hVHE, nVHE).
> 
> Signed-off-by: Joey Gouly <joey.gouly at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oliver.upton at linux.dev>
> Cc: Mark Brown <broonie at kernel.org>

> From what I could tell there isn't a way to tell which of the two modes was
> actually booted in, and this could be useful for looking at log outputs.

Something like this would be helpful catching errors getting test
coverage.

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/20240209/8a3dd6e9/attachment.sig>

From krzysztof.kozlowski at linaro.org  Fri Feb  9 08:05:45 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 9 Feb 2024 17:05:45 +0100
Subject: [PATCH v3 1/4] dt-bindings: display: bridge: add sam9x75-lvds
 compatible
In-Reply-To: <c82a3843-1b58-46ea-994a-8350544aa30d@microchip.com>
References: <20240207102802.200220-1-dharma.b@microchip.com>
 <20240207102802.200220-2-dharma.b@microchip.com>
 <2219df60-7235-4c37-b79c-25e7225cb7a9@kernel.org>
 <b314e446-e79c-4fa0-9b86-c58fa96133bc@microchip.com>
 <c82a3843-1b58-46ea-994a-8350544aa30d@microchip.com>
Message-ID: <e2e1490b-0e07-43ae-ab67-2efd6f21987e@linaro.org>

On 09/02/2024 16:02, Dharma.B at microchip.com wrote:
> On 09/02/24 7:50 pm, Dharma B wrote:
>> On 08/02/24 2:31 pm, Krzysztof Kozlowski wrote:
>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know 
>>> the content is safe
>>>
>>> On 07/02/2024 11:27, Dharma Balasubiramani wrote:
>>>> Add the 'sam9x75-lvds' compatible binding, which describes the Low 
>>>> Voltage
>>>> Differential Signaling (LVDS) Controller found on some Microchip's 
>>>> sam9x7
>>>> series System-on-Chip (SoC) devices. This binding will be used to define
>>>> the properties and configuration for the LVDS Controller in DT.
>>>>
>>>> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
>>>
>>> Not tested...
>>>
>>> Please use scripts/get_maintainers.pl to get a list of necessary people
>>> and lists to CC. It might happen, that command when run on an older
>>> kernel, gives you outdated entries. Therefore please be sure you base
>>> your patches on recent Linux kernel.
>>>
>>> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
>>> people, so fix your workflow. Tools might also fail if you work on some
>>> ancient tree (don't, instead use mainline), work on fork of kernel
>>> (don't, instead use mainline) or you ignore some maintainers (really
>>> don't). Just use b4 and everything should be fine, although remember
>>> about `b4 prep --auto-to-cc` if you added new patches to the patchset.
>>>
>>> You missed at least devicetree list (maybe more), so this won't be
>>> tested by automated tooling. Performing review on untested code might be
>>> a waste of time.
>>
>> Apologies for the oversight, somehow it got missed.
> 
> The get_maintainer.pl seems to be inconsistent with the results.
> 
> linux$ ./scripts/get_maintainer.pl *patch | wc -l
> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
> appear to be a patch.  Add -f to options?
> 31
> linux$ ./scripts/get_maintainer.pl *patch | wc -l
> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
> appear to be a patch.  Add -f to options?
> 29
> linux$ ./scripts/get_maintainer.pl *patch | wc -l
> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
> appear to be a patch.  Add -f to options?
> 30
> linux$ ./scripts/get_maintainer.pl *patch | wc -l
> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
> appear to be a patch.  Add -f to options?
> 30

Why would you add 30 addresses, including many unrelated people, to the
cc-list? You must add only maintainers (so also reviewers) and mailing
lists.

Best regards,
Krzysztof



From will at kernel.org  Fri Feb  9 08:09:06 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 9 Feb 2024 16:09:06 +0000
Subject: [PATCH] perf/arm_smmuv3: Omit the two judgements which done in
 framework
In-Reply-To: <20231221093802.20612-1-jialong.yang@shingroup.cn>
References: <20231221093802.20612-1-jialong.yang@shingroup.cn>
Message-ID: <20240209160905.GA24565@willie-the-truck>

On Thu, Dec 21, 2023 at 05:38:01PM +0800, JiaLong.Yang wrote:
> 'event->attr.type != event->pmu->type' has been done in
> core.c::perf_init_event() ,core.c::perf_event_modify_attr(), etc.
>
> This PMU is an uncore one. The core framework has disallowed
> uncore-task events. So the judgement to event->cpu < 0 is no mean.

It would be great to refer to the changes which added those checks to
the perf core code. From reading the code myself, I can't convince myself
that perf_try_init_event() won't call into the driver.

> 
> The two judgements have been done in kernel/events/core.c
> 
> Signed-off-by: JiaLong.Yang <jialong.yang at shingroup.cn>
> ---
>  drivers/perf/arm_smmuv3_pmu.c | 8 --------
>  1 file changed, 8 deletions(-)

It looks like _many_ perf drivers have these checks, so if they really
aren't needed, we can clean this up bveyond SMMU. However, as I said
above, I'm not quite convinced we can drop them.

Will


From krzysztof.kozlowski at linaro.org  Fri Feb  9 08:10:04 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 9 Feb 2024 17:10:04 +0100
Subject: [PATCH v3 1/4] dt-bindings: display: bridge: add sam9x75-lvds
 compatible
In-Reply-To: <e2e1490b-0e07-43ae-ab67-2efd6f21987e@linaro.org>
References: <20240207102802.200220-1-dharma.b@microchip.com>
 <20240207102802.200220-2-dharma.b@microchip.com>
 <2219df60-7235-4c37-b79c-25e7225cb7a9@kernel.org>
 <b314e446-e79c-4fa0-9b86-c58fa96133bc@microchip.com>
 <c82a3843-1b58-46ea-994a-8350544aa30d@microchip.com>
 <e2e1490b-0e07-43ae-ab67-2efd6f21987e@linaro.org>
Message-ID: <45aa6b3e-5e76-457e-b091-084adf324385@linaro.org>

On 09/02/2024 17:05, Krzysztof Kozlowski wrote:
> On 09/02/2024 16:02, Dharma.B at microchip.com wrote:
>> On 09/02/24 7:50 pm, Dharma B wrote:
>>> On 08/02/24 2:31 pm, Krzysztof Kozlowski wrote:
>>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know 
>>>> the content is safe
>>>>
>>>> On 07/02/2024 11:27, Dharma Balasubiramani wrote:
>>>>> Add the 'sam9x75-lvds' compatible binding, which describes the Low 
>>>>> Voltage
>>>>> Differential Signaling (LVDS) Controller found on some Microchip's 
>>>>> sam9x7
>>>>> series System-on-Chip (SoC) devices. This binding will be used to define
>>>>> the properties and configuration for the LVDS Controller in DT.
>>>>>
>>>>> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
>>>>
>>>> Not tested...
>>>>
>>>> Please use scripts/get_maintainers.pl to get a list of necessary people
>>>> and lists to CC. It might happen, that command when run on an older
>>>> kernel, gives you outdated entries. Therefore please be sure you base
>>>> your patches on recent Linux kernel.
>>>>
>>>> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
>>>> people, so fix your workflow. Tools might also fail if you work on some
>>>> ancient tree (don't, instead use mainline), work on fork of kernel
>>>> (don't, instead use mainline) or you ignore some maintainers (really
>>>> don't). Just use b4 and everything should be fine, although remember
>>>> about `b4 prep --auto-to-cc` if you added new patches to the patchset.
>>>>
>>>> You missed at least devicetree list (maybe more), so this won't be
>>>> tested by automated tooling. Performing review on untested code might be
>>>> a waste of time.
>>>
>>> Apologies for the oversight, somehow it got missed.
>>
>> The get_maintainer.pl seems to be inconsistent with the results.
>>
>> linux$ ./scripts/get_maintainer.pl *patch | wc -l
>> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
>> appear to be a patch.  Add -f to options?
>> 31
>> linux$ ./scripts/get_maintainer.pl *patch | wc -l
>> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
>> appear to be a patch.  Add -f to options?
>> 29
>> linux$ ./scripts/get_maintainer.pl *patch | wc -l
>> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
>> appear to be a patch.  Add -f to options?
>> 30
>> linux$ ./scripts/get_maintainer.pl *patch | wc -l
>> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't 
>> appear to be a patch.  Add -f to options?
>> 30
> 
> Why would you add 30 addresses, including many unrelated people, to the
> cc-list? You must add only maintainers (so also reviewers) and mailing
> lists.

Really, why do you Cc MM folks on this patch? Just read what
get_maintainer.pl tells you, e.g. when it says that someone made one
commit to maintainers file, shall this person be Cc-ed? No, it should be
obvious...

Best regards,
Krzysztof



From tudor.ambarus at linaro.org  Fri Feb  9 08:13:52 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 9 Feb 2024 16:13:52 +0000
Subject: [PATCH v11 07/10] mtd: spi-nor: Add stacked memories support in
 spi-nor
In-Reply-To: <c6f209c8-47da-4881-921d-683464b9ddd5@linaro.org>
References: <20231125092137.2948-1-amit.kumar-mahapatra@amd.com>
 <BN7PR12MB2802BEDFB821A1748185794CDC8AA@BN7PR12MB2802.namprd12.prod.outlook.com>
 <f5a47024-514a-4846-bc16-08cf0f9af912@linaro.org>
 <BN7PR12MB2802BB3DA682D9C13EF7DE08DC8FA@BN7PR12MB2802.namprd12.prod.outlook.com>
 <5a6f6764-6779-42b0-b6c6-3f638b85ef78@linaro.org>
 <BN7PR12MB28029EB1A7D09882878499A2DC8FA@BN7PR12MB2802.namprd12.prod.outlook.com>
 <c3fa1e04-92ed-48ab-a509-98e43abd5cd6@linaro.org>
 <BN7PR12MB2802E87F1A6CD22D904CAEACDC93A@BN7PR12MB2802.namprd12.prod.outlook.com>
 <b3d3c457-a43b-478a-85b3-52558227d139@linaro.org>
 <BN7PR12MB28027E62D66460A374E3CFEADC93A@BN7PR12MB2802.namprd12.prod.outlook.com>
 <e212f9fa-83c5-4b9e-8636-c8c6183096ab@linaro.org>
 <BN7PR12MB280237CDD7BB148479932874DC93A@BN7PR12MB2802.namprd12.prod.outlook.com>
 <576d56ed-d24b-40f9-9ae4-a02c50eea2ab@linaro.org>
 <BN7PR12MB2802F288C6A6B1580CF07959DC95A@BN7PR12MB2802.namprd12.prod.outlook.com>
 <c6f209c8-47da-4881-921d-683464b9ddd5@linaro.org>
Message-ID: <9cdb7f8b-e64f-46f6-94cb-194a25a42ccd@linaro.org>



On 2/9/24 11:06, Tudor Ambarus wrote:
> 
> 
> On 12/21/23 06:54, Mahapatra, Amit Kumar wrote:
>>> Something else to consider: I see that Micron has a twin quad mode:
>>> https://media-www.micron.com/-
>>> /media/client/global/documents/products/data-sheet/nor-flash/serial-
>>> nor/mt25t/generation-
>>> b/mt25t_qljs_l_512_xba_0.pdf?rev=de70b770c5dc4da8b8ead06b57c03500
>>>
>>> The micron's "Separate Chip-Select and Clock Signals" resembles the AMD's
>>> dual parallel 8-bit.
>> Yes, I agree.
>>
>>> Micron's "Shared Chip-Select and Clock Signals" differs from the AMD's
>>> stacked mode, as Micron uses DQ[3:0] and DQ[7:4], whereas AMD considers
>>> both as DQ[3:0].
>> Yes, correct.
> 
> Amit, please help me to assess this. I assume Micron and Microchip is
> using the same concepts as AMD uses for the "Dual Parallel 8-bit IO
> mode", but they call it "Twin Quad Mode".
> 
> I was wrong, the AMD datasheet [1] was misleading [2], it described the
> IOs for both flashes as IO[3:0], but later on in the "Table QSPI
> Interface Signals" the second flash is described with IO[7:4].
> 
> The AMD's 8-bit Dual Flash Parallel Interface is using dedicated CS# and
> CLK# lines for each flash. As Micron does, isn't it?
> 
> Micron says [3] that:
> "The device contains two quad I/O die, each able to operate
> independently for a total of eight I/Os. The memory map applies to each
> die. Each die has internal registers for status, configuration, and
> device protection that can be set and read independently from one other.
> Micron recommends that internal configuration settings for the two die
> be set identically."

Amit,

I forgot to say my first conclusion about the quote from above. Even if
the dies are in the same physical package, micron asks users to
configure each die as it is a self-standing entity, IOW to configure
each die as it is a flash on its own. To me it looks like 2 concatenated
flashes at first look. Thus identical to how AMD controller works.
Please clarify this.

> 
> it also says that:
> "When using quad commands in XIO-SPI or when using QIO-SPI,
> DQ[3:0]/DQ[7:4] are I/O."

and this would be a parallel concatenation of two flashes.

Then it would be good if you let us now the similarities and differences
between how amd and mchp controller work, I scrawled few ideas below.

thanks,
ta
> 
> So I guess the upper layers just ask for a chunk of memory to be written
> and the controller handles the cs# lines automatically. How is the AMD
> controller working, do you have to drive the cs# lines manually, or you
> just set the parallel mode and the controller takes care of everything?
> 
> I assume this is how mchp is handling things, they seem to just set a
> bit the protocol into the QSPI_IFR.PROTTYP register field and that's all
> [4]. They even seem to write the registers of both flashes at the same time.
> 
> In what regards the AMD's "dual stack interface", AMD is sharing the
> clock and IO lines and uses dedicated CS# lines for the flashes, whereas
> Micron shares the CS# and CLK# lines with different IO lines.
> 
> Amit, please study the architectures used by mchp, micron and amd and
> let us know if they are the same or they differ, and if they differ what
> are the differences.
> 
> I added Conor from mchp in cc, I see Nicolas is already there, and Bean
> from micron.
> 
> Thanks,
> ta
> 
> [1]
> https://docs.xilinx.com/r/en-US/am011-versal-acap-trm/QSPI-Flash-Interface-Signals
> [2]
> https://docs.xilinx.com/viewer/attachment/dwmjhDJGICdJqD4swyVzcQ/fD8nv4ry78xM0_EF5kv4mA
> [3]
> https://media-www.micron.com/-/media/client/global/documents/products/data-sheet/nor-flash/serial-nor/mt25t/generation-b/mt25t_qljs_l_512_xba_0.pdf?rev=de70b770c5dc4da8b8ead06b57c03500
> [4]
> https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocuments/DataSheets/SAMA7G5-Series-Data-Sheet-DS60001765.pdf


From conor at kernel.org  Fri Feb  9 08:21:16 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 9 Feb 2024 16:21:16 +0000
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth``
 property
In-Reply-To: <c2b08463-cb13-4e9b-8797-8ebcf1047f66@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
 <20240208135045.3728927-2-tudor.ambarus@linaro.org>
 <20240208-grating-legwarmer-0a04cfb04d61@spud>
 <c2b08463-cb13-4e9b-8797-8ebcf1047f66@linaro.org>
Message-ID: <20240209-chest-sleet-a119fc3d4243@spud>

On Fri, Feb 09, 2024 at 01:56:56PM +0000, Tudor Ambarus wrote:
> 
> + Geert
> 
> On 2/8/24 18:24, Conor Dooley wrote:
> > On Thu, Feb 08, 2024 at 01:50:34PM +0000, Tudor Ambarus wrote:
> >> There are instances of the same IP that are configured by the integrator
> >> with different FIFO depths. Introduce the fifo-depth property to allow
> >> such nodes to specify their FIFO depth.
> >>
> >> We haven't seen SPI IPs with different FIFO depths for RX and TX, thus
> >> introduce a single property.
> > 
> > Some citation attached to this would be nice. "We haven't seen" offers
> > no detail as to what IPs that allow this sort of configuration of FIFO
> > size that you have actually checked.
> > 
> > I went and checked our IP that we use in FPGA fabric, which has a
> > configurable fifo depth. It only has a single knob for both RX and TX
> > FIFOs. The Xilinx xps spi core also has configurable FIFOs, but again RX
> > and TX sizes are tied there. At least that's a sample size of three.
> > 
> > One of our guys is working on support for the IP I just mentioned and
> > would be defining a vendor property for this, so
> > Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> > 
> 
> Thanks, Conor. I had in mind that SPI has a shift register and it's
> improbable to have different FIFO depths for RX and TX.

IDK, but I've learned to expect the unexpectable, especially when it
comes to the IPs intended for use in FPGAs.

> At least I don't
> see how it would work, I guess it will use the minimum depth between the
> two?

I'm not really sure how it would work other than that in the general
case, but some use case specific configuration could work, but I do
agree that it is

> I grepped by "fifo" in the spi bindings and I now see that renesas is
> using dedicated properties for RX and TX, but I think that there too the
> FIFOs have the same depths. Looking into drivers/spi/spi-sh-msiof.c I
> see that the of_device_id.data contains 64 bytes FIFOs for RX and TX,
> regardless of the compatible.
> 
> Geert, any idea if the FIFO depths can differ for RX and TX in
> spi-sh-msiof.c?
> 
> Anyway, even if there are such imbalanced architectures, I guess we can
> consider them when/if they appear? (add rx/tx-fifo-depth dt properties)

I think so.

> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
> Override the default TX fifo size.  Unit is words.  Ignored if 0.
> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
> renesas,rx-fifo-size:
> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
> Override the default RX fifo size.  Unit is words.  Ignored if 0.

These renesas ones seemed interesting at first glance due to these
comments, but what's missed by grep the is "deprecated" marking on
these. They seem to have been replaced by soc-specific compatibles.
-------------- 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/20240209/16e63483/attachment.sig>

From robin.murphy at arm.com  Fri Feb  9 08:32:00 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 9 Feb 2024 16:32:00 +0000
Subject: [PATCH] perf/arm_smmuv3: Omit the two judgements which done in
 framework
In-Reply-To: <20240209160905.GA24565@willie-the-truck>
References: <20231221093802.20612-1-jialong.yang@shingroup.cn>
 <20240209160905.GA24565@willie-the-truck>
Message-ID: <a455e5db-676a-4cf8-8669-8a10e900361c@arm.com>

On 2024-02-09 4:09 pm, Will Deacon wrote:
> On Thu, Dec 21, 2023 at 05:38:01PM +0800, JiaLong.Yang wrote:
>> 'event->attr.type != event->pmu->type' has been done in
>> core.c::perf_init_event() ,core.c::perf_event_modify_attr(), etc.
>>
>> This PMU is an uncore one. The core framework has disallowed
>> uncore-task events. So the judgement to event->cpu < 0 is no mean.
> 
> It would be great to refer to the changes which added those checks to
> the perf core code. From reading the code myself, I can't convince myself
> that perf_try_init_event() won't call into the driver.
> 
>>
>> The two judgements have been done in kernel/events/core.c
>>
>> Signed-off-by: JiaLong.Yang <jialong.yang at shingroup.cn>
>> ---
>>   drivers/perf/arm_smmuv3_pmu.c | 8 --------
>>   1 file changed, 8 deletions(-)
> 
> It looks like _many_ perf drivers have these checks, so if they really
> aren't needed, we can clean this up bveyond SMMU. However, as I said
> above, I'm not quite convinced we can drop them.

Right, I think the logic prevents events with a specific PMU type being 
offered to other PMUs, but as far as I'm aware doesn't apply the other 
way round to stop generic events (PERF_TYPE_HARDWARE etc.) being offered 
to all PMUs, so it's those that system PMUs need to reject.

It's been on my wishlist for a long time to have a capability flag to 
say "I don't handle generic events, please only ever give me events of 
my exact type" so we *can* truly factor this into the core.

Thanks,
Robin.


From ahalaney at redhat.com  Fri Feb  9 08:44:19 2024
From: ahalaney at redhat.com (Andrew Halaney)
Date: Fri, 9 Feb 2024 10:44:19 -0600
Subject: [PATCH net-next v4] net: stmmac: dwmac-qcom-ethqos: Enable TBS
 on all queues but 0
In-Reply-To: <20240208231145.2732931-1-quic_abchauha@quicinc.com>
References: <20240208231145.2732931-1-quic_abchauha@quicinc.com>
Message-ID: <xtwaz7cma6tc42hwslpp3j5htxhsefkmgjntciihphhhkislk7@dy6kr4qfs7mf>

On Thu, Feb 08, 2024 at 03:11:45PM -0800, Abhishek Chauhan wrote:
> TSO and TBS cannot co-exist. TBS requires special descriptor to be
> allocated at bootup. Initialising Tx queues at probe to support
> TSO and TBS can help in allocating those resources at bootup.
> 
> TX queues with TBS can support etf qdisc hw offload.
> 
> This is similar to the patch raised by NXP
> commit 3b12ec8f618e ("net: stmmac: dwmac-imx: set TSO/TBS TX queues default settings")
> 
> Tested-by: Andrew Halaney <ahalaney at redhat.com> # sa8775p-ride
> Signed-off-by: Abhishek Chauhan <quic_abchauha at quicinc.com>

Reviewed-by: Andrew Halaney <ahalaney at redhat.com>

> ---
> Changes since v3:
> - The change is Tested-by Andrew Halaney <ahalaney at redhat.com>
>   on Qualcomm Ride platform
> - Change log is removed from the commit text
> 
> Changes since v2:
> - Fixed the styling of comment in the dwmac-qcom-ethqos.c
> - Followed the upstream format to give other glue
>   driver references to solve the same problem
> - Appended  the subject with net-next
> - Discussion of why this patch is required is discussed in
> https://lore.kernel.org/netdev/c2497eef-1041-4cd0-8220-42622c8902f4 at quicinc.com/
> 
> Changes since v1:
> - Subject is changed as per upstream guidelines
> - Added a reference of a similar change done by NXP in
>   body of the commit message
> 
>  drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> index 31631e3f89d0..2691a250a5a7 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> @@ -728,7 +728,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
>  	struct stmmac_resources stmmac_res;
>  	struct device *dev = &pdev->dev;
>  	struct qcom_ethqos *ethqos;
> -	int ret;
> +	int ret, i;
>  
>  	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
>  	if (ret)
> @@ -822,6 +822,10 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
>  		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
>  	}
>  
> +	/* Enable TSO on queue0 and enable TBS on rest of the queues */
> +	for (i = 1; i < plat_dat->tx_queues_to_use; i++)
> +		plat_dat->tx_queues_cfg[i].tbs_en = 1;
> +
>  	return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
>  }
>  
> -- 
> 2.25.1
> 



From will at kernel.org  Fri Feb  9 08:46:48 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 9 Feb 2024 16:46:48 +0000
Subject: [PATCH v2 1/2] arm64/sme: Restore SMCR on exit from suspend
In-Reply-To: <20240203-arm64-sme-resume-v2-1-a1fbaddc4425@kernel.org>
References: <20240203-arm64-sme-resume-v2-0-a1fbaddc4425@kernel.org>
 <20240203-arm64-sme-resume-v2-1-a1fbaddc4425@kernel.org>
Message-ID: <20240209164648.GA24829@willie-the-truck>

On Sat, Feb 03, 2024 at 01:00:40PM +0000, Mark Brown wrote:
> The fields in SMCR_EL1 reset to an architecturally UNKNOWN value. Since we
> do not otherwise manage the traps configured in this register at runtime we
> need to reconfigure them after a suspend in case nothing else was kind
> enough to preserve them for us.
> 
> The vector length will be restored as part of restoring the SME state for
> the next SME using task.
> 
> Fixes: a1f4ccd25cc2 (arm64/sme: Provide Kconfig for SME)
> Reported-by: Jackson Cooper-Driver <Jackson.Cooper-Driver at arm.com>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/include/asm/fpsimd.h |  2 ++
>  arch/arm64/kernel/fpsimd.c      | 14 ++++++++++++++
>  arch/arm64/kernel/suspend.c     |  3 +++
>  3 files changed, 19 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index 50e5f25d3024..7780d343ef08 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -386,6 +386,7 @@ extern void sme_alloc(struct task_struct *task, bool flush);
>  extern unsigned int sme_get_vl(void);
>  extern int sme_set_current_vl(unsigned long arg);
>  extern int sme_get_current_vl(void);
> +extern void sme_suspend_exit(void);
>  
>  /*
>   * Return how many bytes of memory are required to store the full SME
> @@ -421,6 +422,7 @@ 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; }
> +static inline void sme_suspend_exit(void) { }
>  
>  static inline size_t sme_state_size(struct task_struct const *task)
>  {
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index a5dc6f764195..8d2a5824d5d3 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -1311,6 +1311,20 @@ void __init sme_setup(void)
>  		get_sme_default_vl());
>  }
>  
> +void sme_suspend_exit(void)
> +{
> +	u64 smcr = 0;
> +
> +	if (!system_supports_sme())
> +		return;
> +
> +	if (system_supports_fa64())
> +		smcr |= SMCR_ELx_FA64;
> +
> +	write_sysreg_s(smcr, SYS_SMCR_EL1);
> +	write_sysreg_s(0, SYS_SMPRI_EL1);
> +}

Looking at the other places where we touch SMCR_EL1, it looks like we
always use a read-modify-write sequence. However, doesn't that mean we
inherit a bunch of unknown bits on cold boot? I'm basically wondering
whether we should be initialising these registers to a well-known value
earlier in the CPU init path, a bit like we do for the EL2 variants.

Will


From conor at kernel.org  Fri Feb  9 08:48:46 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 9 Feb 2024 16:48:46 +0000
Subject: [PATCH v2] dt-bindings: interrupt-controller: Convert Atmel AIC
 to json-schema
In-Reply-To: <20240209100122.61335-1-dharma.b@microchip.com>
References: <20240209100122.61335-1-dharma.b@microchip.com>
Message-ID: <20240209-trifocals-rejoice-27a17500584f@spud>

On Fri, Feb 09, 2024 at 03:31:22PM +0530, Dharma Balasubiramani wrote:

> +examples:
> +  - |
> +    interrupt-controller at fffff000 {
> +      compatible = "atmel,at91rm9200-aic";
> +      interrupt-controller;
> +      #interrupt-cells = <3>;
> +      reg = <0xfffff000 0x200>;

One nit if there's some other reason for a respin, reg before
interrupt-controller.

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

-------------- 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/20240209/a205ada6/attachment.sig>

From robin.murphy at arm.com  Fri Feb  9 08:49:58 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri,  9 Feb 2024 16:49:58 +0000
Subject: [PATCH v3 1/7] OF: Retire dma-ranges mask workaround
In-Reply-To: <cover.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
Message-ID: <3d759722a5bd898dc5736048b4a5f30689c33888.1707493264.git.robin.murphy@arm.com>

The fixup adding 1 to the dma-ranges size may have been for the benefit
of some early AMD Seattle DTs, or may have merely been a just-in-case,
but either way anyone who might have deserved to get the message has
hopefully seen the warning in the 9 years we've had it there. The modern
dma_range_map mechanism should happily handle odd-sized ranges with no
ill effect, so there's little need to care anyway now. Clean it up.

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
v2: Tweak commit message
---
 drivers/of/device.c | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index de89f9906375..a988bee2ee5a 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -129,22 +129,6 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 				dma_end = r->dma_start + r->size;
 		}
 		size = dma_end - dma_start;
-
-		/*
-		 * Add a work around to treat the size as mask + 1 in case
-		 * it is defined in DT as a mask.
-		 */
-		if (size & 1) {
-			dev_warn(dev, "Invalid size 0x%llx for dma-range(s)\n",
-				 size);
-			size = size + 1;
-		}
-
-		if (!size) {
-			dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
-			kfree(map);
-			return -EINVAL;
-		}
 	}
 
 	/*
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Fri Feb  9 08:49:57 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri,  9 Feb 2024 16:49:57 +0000
Subject: [PATCH v3 0/7] dma-mapping: Simplify arch_setup_dma_ops()
Message-ID: <cover.1707493264.git.robin.murphy@arm.com>

v2: https://lore.kernel.org/linux-iommu/cover.1702486837.git.robin.murphy at arm.com/

Hi all,

Here's v3, rebased and fixing the thinko from v2, so unless anything
else has changed behind my back I hope it's good to go (via the IOMMU
tree, as mentioned before).

Thanks,
Robin.


Robin Murphy (7):
  OF: Retire dma-ranges mask workaround
  OF: Simplify DMA range ca1lculations
  ACPI/IORT: Handle memory address size limits as limits
  dma-mapping: Add helpers for dma_range_map bounds
  iommu/dma: Make limit checks self-contained
  iommu/dma: Centralise iommu_setup_dma_ops()
  dma-mapping: Simplify arch_setup_dma_ops()

 arch/arc/mm/dma.c               |  3 +--
 arch/arm/mm/dma-mapping-nommu.c |  3 +--
 arch/arm/mm/dma-mapping.c       | 16 +++++++------
 arch/arm64/mm/dma-mapping.c     |  5 +---
 arch/loongarch/kernel/dma.c     |  9 ++-----
 arch/mips/mm/dma-noncoherent.c  |  3 +--
 arch/riscv/mm/dma-noncoherent.c |  3 +--
 drivers/acpi/arm64/dma.c        | 17 ++++---------
 drivers/acpi/arm64/iort.c       | 20 ++++++++--------
 drivers/acpi/scan.c             |  7 +-----
 drivers/hv/hv_common.c          |  6 +----
 drivers/iommu/amd/iommu.c       |  8 -------
 drivers/iommu/dma-iommu.c       | 39 ++++++++++++------------------
 drivers/iommu/dma-iommu.h       | 14 +++++------
 drivers/iommu/intel/iommu.c     |  7 ------
 drivers/iommu/iommu.c           | 20 ++++++----------
 drivers/iommu/s390-iommu.c      |  6 -----
 drivers/iommu/virtio-iommu.c    | 10 --------
 drivers/of/device.c             | 42 ++++++---------------------------
 include/linux/acpi_iort.h       |  4 ++--
 include/linux/dma-direct.h      | 18 ++++++++++++++
 include/linux/dma-map-ops.h     |  6 ++---
 include/linux/iommu.h           |  7 ------
 23 files changed, 89 insertions(+), 184 deletions(-)

-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Fri Feb  9 08:49:59 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri,  9 Feb 2024 16:49:59 +0000
Subject: [PATCH v3 2/7] OF: Simplify DMA range calculations
In-Reply-To: <cover.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
Message-ID: <a9ed545e927ded7c1a870636813386eff914d2fa.1707493264.git.robin.murphy@arm.com>

Juggling start, end, and size values for a range is somewhat redundant
and a little hard to follow. Consolidate down to just using inclusive
start and end, which saves us worrying about size overflows for full
64-bit ranges (note that passing a potentially-overflowed value through
to arch_setup_dma_ops() is benign for all current implementations, and
this is working towards removing that anyway).

Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/of/device.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index a988bee2ee5a..841ccd3a19d1 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -96,7 +96,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	const struct bus_dma_region *map = NULL;
 	struct device_node *bus_np;
 	u64 dma_start = 0;
-	u64 mask, end, size = 0;
+	u64 mask, end = 0;
 	bool coherent;
 	int iommu_ret;
 	int ret;
@@ -118,17 +118,15 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 			return ret == -ENODEV ? 0 : ret;
 	} else {
 		const struct bus_dma_region *r = map;
-		u64 dma_end = 0;
 
 		/* Determine the overall bounds of all DMA regions */
 		for (dma_start = ~0; r->size; r++) {
 			/* Take lower and upper limits */
 			if (r->dma_start < dma_start)
 				dma_start = r->dma_start;
-			if (r->dma_start + r->size > dma_end)
-				dma_end = r->dma_start + r->size;
+			if (r->dma_start + r->size > end)
+				end = r->dma_start + r->size;
 		}
-		size = dma_end - dma_start;
 	}
 
 	/*
@@ -142,16 +140,15 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 		dev->dma_mask = &dev->coherent_dma_mask;
 	}
 
-	if (!size && dev->coherent_dma_mask)
-		size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
-	else if (!size)
-		size = 1ULL << 32;
+	if (!end && dev->coherent_dma_mask)
+		end = dev->coherent_dma_mask;
+	else if (!end)
+		end = (1ULL << 32) - 1;
 
 	/*
 	 * Limit coherent and dma mask based on size and default mask
 	 * set by the driver.
 	 */
-	end = dma_start + size - 1;
 	mask = DMA_BIT_MASK(ilog2(end) + 1);
 	dev->coherent_dma_mask &= mask;
 	*dev->dma_mask &= mask;
@@ -185,7 +182,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	} else
 		dev_dbg(dev, "device is behind an iommu\n");
 
-	arch_setup_dma_ops(dev, dma_start, size, coherent);
+	arch_setup_dma_ops(dev, dma_start, end - dma_start + 1, coherent);
 
 	if (iommu_ret)
 		of_dma_set_restricted_buffer(dev, np);
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Fri Feb  9 08:50:00 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri,  9 Feb 2024 16:50:00 +0000
Subject: [PATCH v3 3/7] ACPI/IORT: Handle memory address size limits as limits
In-Reply-To: <cover.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
Message-ID: <5d52d580bf33d475053f9b05188fe3541cbe8798.1707493264.git.robin.murphy@arm.com>

Return the Root Complex/Named Component memory address size limit as an
inclusive limit value, rather than an exclusive size. This saves having
to fudge an off-by-one for the 64-bit case, and simplifies our caller.

Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
v2: Avoid undefined shifts (grr...)
---
 drivers/acpi/arm64/dma.c  |  9 +++------
 drivers/acpi/arm64/iort.c | 20 ++++++++++----------
 include/linux/acpi_iort.h |  4 ++--
 3 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/acpi/arm64/dma.c b/drivers/acpi/arm64/dma.c
index 93d796531af3..b98a149f8d50 100644
--- a/drivers/acpi/arm64/dma.c
+++ b/drivers/acpi/arm64/dma.c
@@ -8,7 +8,6 @@ void acpi_arch_dma_setup(struct device *dev)
 {
 	int ret;
 	u64 end, mask;
-	u64 size = 0;
 	const struct bus_dma_region *map = NULL;
 
 	/*
@@ -23,9 +22,9 @@ void acpi_arch_dma_setup(struct device *dev)
 	}
 
 	if (dev->coherent_dma_mask)
-		size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
+		end = dev->coherent_dma_mask;
 	else
-		size = 1ULL << 32;
+		end = (1ULL << 32) - 1;
 
 	ret = acpi_dma_get_range(dev, &map);
 	if (!ret && map) {
@@ -36,18 +35,16 @@ void acpi_arch_dma_setup(struct device *dev)
 				end = r->dma_start + r->size - 1;
 		}
 
-		size = end + 1;
 		dev->dma_range_map = map;
 	}
 
 	if (ret == -ENODEV)
-		ret = iort_dma_get_ranges(dev, &size);
+		ret = iort_dma_get_ranges(dev, &end);
 	if (!ret) {
 		/*
 		 * Limit coherent and dma mask based on size retrieved from
 		 * firmware.
 		 */
-		end = size - 1;
 		mask = DMA_BIT_MASK(ilog2(end) + 1);
 		dev->bus_dma_limit = end;
 		dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 6496ff5a6ba2..c0b1c2c19444 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1367,7 +1367,7 @@ int iort_iommu_configure_id(struct device *dev, const u32 *input_id)
 { return -ENODEV; }
 #endif
 
-static int nc_dma_get_range(struct device *dev, u64 *size)
+static int nc_dma_get_range(struct device *dev, u64 *limit)
 {
 	struct acpi_iort_node *node;
 	struct acpi_iort_named_component *ncomp;
@@ -1384,13 +1384,13 @@ static int nc_dma_get_range(struct device *dev, u64 *size)
 		return -EINVAL;
 	}
 
-	*size = ncomp->memory_address_limit >= 64 ? U64_MAX :
-			1ULL<<ncomp->memory_address_limit;
+	*limit = ncomp->memory_address_limit >= 64 ? U64_MAX :
+			(1ULL << ncomp->memory_address_limit) - 1;
 
 	return 0;
 }
 
-static int rc_dma_get_range(struct device *dev, u64 *size)
+static int rc_dma_get_range(struct device *dev, u64 *limit)
 {
 	struct acpi_iort_node *node;
 	struct acpi_iort_root_complex *rc;
@@ -1408,8 +1408,8 @@ static int rc_dma_get_range(struct device *dev, u64 *size)
 		return -EINVAL;
 	}
 
-	*size = rc->memory_address_limit >= 64 ? U64_MAX :
-			1ULL<<rc->memory_address_limit;
+	*limit = rc->memory_address_limit >= 64 ? U64_MAX :
+			(1ULL << rc->memory_address_limit) - 1;
 
 	return 0;
 }
@@ -1417,16 +1417,16 @@ static int rc_dma_get_range(struct device *dev, u64 *size)
 /**
  * iort_dma_get_ranges() - Look up DMA addressing limit for the device
  * @dev: device to lookup
- * @size: DMA range size result pointer
+ * @limit: DMA limit result pointer
  *
  * Return: 0 on success, an error otherwise.
  */
-int iort_dma_get_ranges(struct device *dev, u64 *size)
+int iort_dma_get_ranges(struct device *dev, u64 *limit)
 {
 	if (dev_is_pci(dev))
-		return rc_dma_get_range(dev, size);
+		return rc_dma_get_range(dev, limit);
 	else
-		return nc_dma_get_range(dev, size);
+		return nc_dma_get_range(dev, limit);
 }
 
 static void __init acpi_iort_register_irq(int hwirq, const char *name,
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 1cb65592c95d..d4ed5622cf2b 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -39,7 +39,7 @@ void iort_get_rmr_sids(struct fwnode_handle *iommu_fwnode,
 void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
 		       struct list_head *head);
 /* IOMMU interface */
-int iort_dma_get_ranges(struct device *dev, u64 *size);
+int iort_dma_get_ranges(struct device *dev, u64 *limit);
 int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
 void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
@@ -55,7 +55,7 @@ void iort_get_rmr_sids(struct fwnode_handle *iommu_fwnode, struct list_head *hea
 static inline
 void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode, struct list_head *head) { }
 /* IOMMU interface */
-static inline int iort_dma_get_ranges(struct device *dev, u64 *size)
+static inline int iort_dma_get_ranges(struct device *dev, u64 *limit)
 { return -ENODEV; }
 static inline int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 { return -ENODEV; }
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Fri Feb  9 08:50:01 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri,  9 Feb 2024 16:50:01 +0000
Subject: [PATCH v3 4/7] dma-mapping: Add helpers for dma_range_map bounds
In-Reply-To: <cover.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
Message-ID: <cc90d296daa52e9cfe9fdd6681c68df4773a5e6a.1707493264.git.robin.murphy@arm.com>

Several places want to compute the lower and/or upper bounds of a
dma_range_map, so let's factor that out into reusable helpers.

Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Christoph Hellwig <hch at lst.de>
Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
v2: fix warning for 32-bit builds
---
 arch/loongarch/kernel/dma.c |  9 ++-------
 drivers/acpi/arm64/dma.c    |  8 +-------
 drivers/of/device.c         | 11 ++---------
 include/linux/dma-direct.h  | 18 ++++++++++++++++++
 4 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/loongarch/kernel/dma.c b/arch/loongarch/kernel/dma.c
index 7a9c6a9dd2d0..429555fb4e13 100644
--- a/arch/loongarch/kernel/dma.c
+++ b/arch/loongarch/kernel/dma.c
@@ -8,17 +8,12 @@
 void acpi_arch_dma_setup(struct device *dev)
 {
 	int ret;
-	u64 mask, end = 0;
+	u64 mask, end;
 	const struct bus_dma_region *map = NULL;
 
 	ret = acpi_dma_get_range(dev, &map);
 	if (!ret && map) {
-		const struct bus_dma_region *r = map;
-
-		for (end = 0; r->size; r++) {
-			if (r->dma_start + r->size - 1 > end)
-				end = r->dma_start + r->size - 1;
-		}
+		end = dma_range_map_max(map);
 
 		mask = DMA_BIT_MASK(ilog2(end) + 1);
 		dev->bus_dma_limit = end;
diff --git a/drivers/acpi/arm64/dma.c b/drivers/acpi/arm64/dma.c
index b98a149f8d50..52b2abf88689 100644
--- a/drivers/acpi/arm64/dma.c
+++ b/drivers/acpi/arm64/dma.c
@@ -28,13 +28,7 @@ void acpi_arch_dma_setup(struct device *dev)
 
 	ret = acpi_dma_get_range(dev, &map);
 	if (!ret && map) {
-		const struct bus_dma_region *r = map;
-
-		for (end = 0; r->size; r++) {
-			if (r->dma_start + r->size - 1 > end)
-				end = r->dma_start + r->size - 1;
-		}
-
+		end = dma_range_map_max(map);
 		dev->dma_range_map = map;
 	}
 
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 841ccd3a19d1..9e7963972fa7 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -117,16 +117,9 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 		if (!force_dma)
 			return ret == -ENODEV ? 0 : ret;
 	} else {
-		const struct bus_dma_region *r = map;
-
 		/* Determine the overall bounds of all DMA regions */
-		for (dma_start = ~0; r->size; r++) {
-			/* Take lower and upper limits */
-			if (r->dma_start < dma_start)
-				dma_start = r->dma_start;
-			if (r->dma_start + r->size > end)
-				end = r->dma_start + r->size;
-		}
+		dma_start = dma_range_map_min(map);
+		end = dma_range_map_max(map);
 	}
 
 	/*
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index 3eb3589ff43e..edbe13d00776 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -54,6 +54,24 @@ static inline phys_addr_t translate_dma_to_phys(struct device *dev,
 	return (phys_addr_t)-1;
 }
 
+static inline dma_addr_t dma_range_map_min(const struct bus_dma_region *map)
+{
+	dma_addr_t ret = (dma_addr_t)U64_MAX;
+
+	for (; map->size; map++)
+		ret = min(ret, map->dma_start);
+	return ret;
+}
+
+static inline dma_addr_t dma_range_map_max(const struct bus_dma_region *map)
+{
+	dma_addr_t ret = 0;
+
+	for (; map->size; map++)
+		ret = max(ret, map->dma_start + map->size - 1);
+	return ret;
+}
+
 #ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
 #include <asm/dma-direct.h>
 #ifndef phys_to_dma_unencrypted
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Fri Feb  9 08:50:02 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri,  9 Feb 2024 16:50:02 +0000
Subject: [PATCH v3 5/7] iommu/dma: Make limit checks self-contained
In-Reply-To: <cover.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
Message-ID: <2f9fe1c4fd29043db3d61d265bdf9908bb7fa85c.1707493264.git.robin.murphy@arm.com>

It's now easy to retrieve the device's DMA limits if we want to check
them against the domain aperture, so do that ourselves instead of
relying on them being passed through the callchain.

Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/dma-iommu.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index dbe3c225e0d5..52126f73f690 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -660,19 +660,16 @@ static void iommu_dma_init_options(struct iommu_dma_options *options,
 /**
  * iommu_dma_init_domain - Initialise a DMA mapping domain
  * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie()
- * @base: IOVA at which the mappable address space starts
- * @limit: Last address of the IOVA space
  * @dev: Device the domain is being initialised for
  *
- * @base and @limit + 1 should be exact multiples of IOMMU page granularity to
- * avoid rounding surprises. If necessary, we reserve the page at address 0
+ * If the geometry and dma_range_map include address 0, we reserve that page
  * to ensure it is an invalid IOVA. It is safe to reinitialise a domain, but
  * any change which could make prior IOVAs invalid will fail.
  */
-static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
-				 dma_addr_t limit, struct device *dev)
+static int iommu_dma_init_domain(struct iommu_domain *domain, struct device *dev)
 {
 	struct iommu_dma_cookie *cookie = domain->iova_cookie;
+	const struct bus_dma_region *map = dev->dma_range_map;
 	unsigned long order, base_pfn;
 	struct iova_domain *iovad;
 	int ret;
@@ -684,18 +681,18 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
 
 	/* Use the smallest supported page size for IOVA granularity */
 	order = __ffs(domain->pgsize_bitmap);
-	base_pfn = max_t(unsigned long, 1, base >> order);
+	base_pfn = 1;
 
 	/* Check the domain allows at least some access to the device... */
-	if (domain->geometry.force_aperture) {
+	if (map) {
+		dma_addr_t base = dma_range_map_min(map);
 		if (base > domain->geometry.aperture_end ||
-		    limit < domain->geometry.aperture_start) {
+		    dma_range_map_max(map) < domain->geometry.aperture_start) {
 			pr_warn("specified DMA range outside IOMMU capability\n");
 			return -EFAULT;
 		}
 		/* ...then finally give it a kicking to make sure it fits */
-		base_pfn = max_t(unsigned long, base_pfn,
-				domain->geometry.aperture_start >> order);
+		base_pfn = max(base, domain->geometry.aperture_start) >> order;
 	}
 
 	/* start_pfn is always nonzero for an already-initialised domain */
@@ -1746,7 +1743,7 @@ void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit)
 	 * underlying IOMMU driver needs to support via the dma-iommu layer.
 	 */
 	if (iommu_is_dma_domain(domain)) {
-		if (iommu_dma_init_domain(domain, dma_base, dma_limit, dev))
+		if (iommu_dma_init_domain(domain, dev))
 			goto out_err;
 		dev->dma_ops = &iommu_dma_ops;
 	}
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Fri Feb  9 08:50:03 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri,  9 Feb 2024 16:50:03 +0000
Subject: [PATCH v3 6/7] iommu/dma: Centralise iommu_setup_dma_ops()
In-Reply-To: <cover.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
Message-ID: <202fcca3269201bc9c4a8198253f195433d0c4ff.1707493264.git.robin.murphy@arm.com>

It's somewhat hard to see, but arm64's arch_setup_dma_ops() should only
ever call iommu_setup_dma_ops() after a successful iommu_probe_device(),
which means there should be no harm in achieving the same order of
operations by running it off the back of iommu_probe_device() itself.
This then puts it in line with the x86 and s390 .probe_finalize bodges,
letting us pull it all into the main flow properly. As a bonus this lets
us fold in and de-scope the PCI workaround setup as well.

At this point we can also then pull the call up inside the group mutex,
and avoid having to think about whether iommu_group_store_type() could
theoretically race and free the domain if iommu_setup_dma_ops() ran just
*before* iommu_device_use_default_domain() claims it... Furthermore we
replace one .probe_finalize call completely, since the only remaining
implementations are now one which only needs to run once for the initial
boot-time probe, and two which themselves render that path unreachable.

This leaves us a big step closer to realistically being able to unpick
the variety of different things that iommu_setup_dma_ops() has been
muddling together, and further streamline iommu-dma into core API flows
in future.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
v2: Shuffle around to make sure the iommu_group_do_probe_finalize() case
    is covered as well, with bonus side-effects as above.
v3: *Really* do that, remembering the other two probe_finalize sites too.
---
 arch/arm64/mm/dma-mapping.c  |  2 --
 drivers/iommu/amd/iommu.c    |  8 --------
 drivers/iommu/dma-iommu.c    | 18 ++++++------------
 drivers/iommu/dma-iommu.h    | 14 ++++++--------
 drivers/iommu/intel/iommu.c  |  7 -------
 drivers/iommu/iommu.c        | 20 +++++++-------------
 drivers/iommu/s390-iommu.c   |  6 ------
 drivers/iommu/virtio-iommu.c | 10 ----------
 include/linux/iommu.h        |  7 -------
 9 files changed, 19 insertions(+), 73 deletions(-)

diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 61886e43e3a1..313d8938a2f0 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -58,8 +58,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 		   ARCH_DMA_MINALIGN, cls);
 
 	dev->dma_coherent = coherent;
-	if (device_iommu_mapped(dev))
-		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
 
 	xen_setup_dma_ops(dev);
 }
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 4283dd8191f0..00c0d5de1225 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1968,13 +1968,6 @@ static struct iommu_device *amd_iommu_probe_device(struct device *dev)
 	return iommu_dev;
 }
 
-static void amd_iommu_probe_finalize(struct device *dev)
-{
-	/* Domains are initialized for this device - have a look what we ended up with */
-	set_dma_ops(dev, NULL);
-	iommu_setup_dma_ops(dev, 0, U64_MAX);
-}
-
 static void amd_iommu_release_device(struct device *dev)
 {
 	struct amd_iommu *iommu;
@@ -2626,7 +2619,6 @@ const struct iommu_ops amd_iommu_ops = {
 	.domain_alloc_user = amd_iommu_domain_alloc_user,
 	.probe_device = amd_iommu_probe_device,
 	.release_device = amd_iommu_release_device,
-	.probe_finalize = amd_iommu_probe_finalize,
 	.device_group = amd_iommu_device_group,
 	.get_resv_regions = amd_iommu_get_resv_regions,
 	.is_attach_deferred = amd_iommu_is_attach_deferred,
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 52126f73f690..fa1cdca39da6 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -1727,25 +1727,20 @@ static const struct dma_map_ops iommu_dma_ops = {
 	.opt_mapping_size	= iommu_dma_opt_mapping_size,
 };
 
-/*
- * The IOMMU core code allocates the default DMA domain, which the underlying
- * IOMMU driver needs to support via the dma-iommu layer.
- */
-void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit)
+void iommu_setup_dma_ops(struct device *dev)
 {
 	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
 
-	if (!domain)
-		goto out_err;
+	if (dev_is_pci(dev))
+		dev->iommu->pci_32bit_workaround = !iommu_dma_forcedac;
 
-	/*
-	 * The IOMMU core code allocates the default DMA domain, which the
-	 * underlying IOMMU driver needs to support via the dma-iommu layer.
-	 */
 	if (iommu_is_dma_domain(domain)) {
 		if (iommu_dma_init_domain(domain, dev))
 			goto out_err;
 		dev->dma_ops = &iommu_dma_ops;
+	} else if (dev->dma_ops == &iommu_dma_ops) {
+		/* Clean up if we've switched *from* a DMA domain */
+		dev->dma_ops = NULL;
 	}
 
 	return;
@@ -1753,7 +1748,6 @@ void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit)
 	 pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
 		 dev_name(dev));
 }
-EXPORT_SYMBOL_GPL(iommu_setup_dma_ops);
 
 static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev,
 		phys_addr_t msi_addr, struct iommu_domain *domain)
diff --git a/drivers/iommu/dma-iommu.h b/drivers/iommu/dma-iommu.h
index c829f1f82a99..c12d63457c76 100644
--- a/drivers/iommu/dma-iommu.h
+++ b/drivers/iommu/dma-iommu.h
@@ -9,6 +9,8 @@
 
 #ifdef CONFIG_IOMMU_DMA
 
+void iommu_setup_dma_ops(struct device *dev);
+
 int iommu_get_dma_cookie(struct iommu_domain *domain);
 void iommu_put_dma_cookie(struct iommu_domain *domain);
 
@@ -17,13 +19,13 @@ int iommu_dma_init_fq(struct iommu_domain *domain);
 void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
 
 extern bool iommu_dma_forcedac;
-static inline void iommu_dma_set_pci_32bit_workaround(struct device *dev)
-{
-	dev->iommu->pci_32bit_workaround = !iommu_dma_forcedac;
-}
 
 #else /* CONFIG_IOMMU_DMA */
 
+static inline void iommu_setup_dma_ops(struct device *dev)
+{
+}
+
 static inline int iommu_dma_init_fq(struct iommu_domain *domain)
 {
 	return -EINVAL;
@@ -42,9 +44,5 @@ static inline void iommu_dma_get_resv_regions(struct device *dev, struct list_he
 {
 }
 
-static inline void iommu_dma_set_pci_32bit_workaround(struct device *dev)
-{
-}
-
 #endif	/* CONFIG_IOMMU_DMA */
 #endif	/* __DMA_IOMMU_H */
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 6fb5f6fceea1..f1c599429408 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4291,12 +4291,6 @@ static void intel_iommu_release_device(struct device *dev)
 	set_dma_ops(dev, NULL);
 }
 
-static void intel_iommu_probe_finalize(struct device *dev)
-{
-	set_dma_ops(dev, NULL);
-	iommu_setup_dma_ops(dev, 0, U64_MAX);
-}
-
 static void intel_iommu_get_resv_regions(struct device *device,
 					 struct list_head *head)
 {
@@ -4748,7 +4742,6 @@ const struct iommu_ops intel_iommu_ops = {
 	.domain_alloc		= intel_iommu_domain_alloc,
 	.domain_alloc_user	= intel_iommu_domain_alloc_user,
 	.probe_device		= intel_iommu_probe_device,
-	.probe_finalize		= intel_iommu_probe_finalize,
 	.release_device		= intel_iommu_release_device,
 	.get_resv_regions	= intel_iommu_get_resv_regions,
 	.device_group		= intel_iommu_device_group,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d14413916f93..e793b2f4bdc8 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -571,10 +571,11 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
 		if (list_empty(&group->entry))
 			list_add_tail(&group->entry, group_list);
 	}
-	mutex_unlock(&group->mutex);
 
-	if (dev_is_pci(dev))
-		iommu_dma_set_pci_32bit_workaround(dev);
+	if (group->default_domain)
+		iommu_setup_dma_ops(dev);
+
+	mutex_unlock(&group->mutex);
 
 	return 0;
 
@@ -2010,6 +2011,8 @@ int bus_iommu_probe(const struct bus_type *bus)
 			mutex_unlock(&group->mutex);
 			return ret;
 		}
+		for_each_group_device(group, gdev)
+			iommu_setup_dma_ops(gdev->dev);
 		mutex_unlock(&group->mutex);
 
 		/*
@@ -3248,18 +3251,9 @@ static ssize_t iommu_group_store_type(struct iommu_group *group,
 	if (ret)
 		goto out_unlock;
 
-	/*
-	 * Release the mutex here because ops->probe_finalize() call-back of
-	 * some vendor IOMMU drivers calls arm_iommu_attach_device() which
-	 * in-turn might call back into IOMMU core code, where it tries to take
-	 * group->mutex, resulting in a deadlock.
-	 */
-	mutex_unlock(&group->mutex);
-
 	/* Make sure dma_ops is appropriatley set */
 	for_each_group_device(group, gdev)
-		iommu_group_do_probe_finalize(gdev->dev);
-	return count;
+		iommu_setup_dma_ops(gdev->dev);
 
 out_unlock:
 	mutex_unlock(&group->mutex);
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index 9a5196f523de..d8eaa7ea380b 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -695,11 +695,6 @@ static size_t s390_iommu_unmap_pages(struct iommu_domain *domain,
 	return size;
 }
 
-static void s390_iommu_probe_finalize(struct device *dev)
-{
-	iommu_setup_dma_ops(dev, 0, U64_MAX);
-}
-
 struct zpci_iommu_ctrs *zpci_get_iommu_ctrs(struct zpci_dev *zdev)
 {
 	if (!zdev || !zdev->s390_domain)
@@ -785,7 +780,6 @@ static const struct iommu_ops s390_iommu_ops = {
 	.capable = s390_iommu_capable,
 	.domain_alloc_paging = s390_domain_alloc_paging,
 	.probe_device = s390_iommu_probe_device,
-	.probe_finalize = s390_iommu_probe_finalize,
 	.release_device = s390_iommu_release_device,
 	.device_group = generic_device_group,
 	.pgsize_bitmap = SZ_4K,
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 34db37fd9675..ec7640127125 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1025,15 +1025,6 @@ static struct iommu_device *viommu_probe_device(struct device *dev)
 	return ERR_PTR(ret);
 }
 
-static void viommu_probe_finalize(struct device *dev)
-{
-#ifndef CONFIG_ARCH_HAS_SETUP_DMA_OPS
-	/* First clear the DMA ops in case we're switching from a DMA domain */
-	set_dma_ops(dev, NULL);
-	iommu_setup_dma_ops(dev, 0, U64_MAX);
-#endif
-}
-
 static void viommu_release_device(struct device *dev)
 {
 	struct viommu_endpoint *vdev = dev_iommu_priv_get(dev);
@@ -1072,7 +1063,6 @@ static struct iommu_ops viommu_ops = {
 	.capable		= viommu_capable,
 	.domain_alloc		= viommu_domain_alloc,
 	.probe_device		= viommu_probe_device,
-	.probe_finalize		= viommu_probe_finalize,
 	.release_device		= viommu_release_device,
 	.device_group		= viommu_device_group,
 	.get_resv_regions	= viommu_get_resv_regions,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 79c3dac8be75..509add6699c8 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -1367,9 +1367,6 @@ static inline void iommu_debugfs_setup(void) {}
 #ifdef CONFIG_IOMMU_DMA
 #include <linux/msi.h>
 
-/* Setup call for arch DMA mapping code */
-void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit);
-
 int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base);
 
 int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr);
@@ -1380,10 +1377,6 @@ void iommu_dma_compose_msi_msg(struct msi_desc *desc, struct msi_msg *msg);
 struct msi_desc;
 struct msi_msg;
 
-static inline void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit)
-{
-}
-
 static inline int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base)
 {
 	return -ENODEV;
-- 
2.39.2.101.g768bb238c484.dirty



From robin.murphy at arm.com  Fri Feb  9 08:50:04 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri,  9 Feb 2024 16:50:04 +0000
Subject: [PATCH v3 7/7] dma-mapping: Simplify arch_setup_dma_ops()
In-Reply-To: <cover.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
Message-ID: <f0ea76846c89a65dfe42933d78d770004bb3de01.1707493264.git.robin.murphy@arm.com>

The dma_base, size and iommu arguments are only used by ARM, and can
now easily be deduced from the device itself, so there's no need to pass
them through the callchain as well.

Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Christoph Hellwig <hch at lst.de>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
v2: Make sure the ARM changes actually build (oops...)
---
 arch/arc/mm/dma.c               |  3 +--
 arch/arm/mm/dma-mapping-nommu.c |  3 +--
 arch/arm/mm/dma-mapping.c       | 16 +++++++++-------
 arch/arm64/mm/dma-mapping.c     |  3 +--
 arch/mips/mm/dma-noncoherent.c  |  3 +--
 arch/riscv/mm/dma-noncoherent.c |  3 +--
 drivers/acpi/scan.c             |  7 +------
 drivers/hv/hv_common.c          |  6 +-----
 drivers/of/device.c             |  4 +---
 include/linux/dma-map-ops.h     |  6 ++----
 10 files changed, 19 insertions(+), 35 deletions(-)

diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 197707bc7658..6b85e94f3275 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -90,8 +90,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 /*
  * Plug in direct dma map ops.
  */
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
 {
 	/*
 	 * IOC hardware snoops all DMA traffic keeping the caches consistent
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index b94850b57995..97db5397c320 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -33,8 +33,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 	}
 }
 
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
 {
 	if (IS_ENABLED(CONFIG_CPU_V7M)) {
 		/*
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f68db05eba29..5adf1769eee4 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1709,11 +1709,15 @@ void arm_iommu_detach_device(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
 
-static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    bool coherent)
+static void arm_setup_iommu_dma_ops(struct device *dev)
 {
 	struct dma_iommu_mapping *mapping;
+	u64 dma_base = 0, size = 1ULL << 32;
 
+	if (dev->dma_range_map) {
+		dma_base = dma_range_map_min(dev->dma_range_map);
+		size = dma_range_map_max(dev->dma_range_map) - dma_base;
+	}
 	mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
 	if (IS_ERR(mapping)) {
 		pr_warn("Failed to create %llu-byte IOMMU mapping for device %s\n",
@@ -1744,8 +1748,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
 
 #else
 
-static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				    bool coherent)
+static void arm_setup_iommu_dma_ops(struct device *dev)
 {
 }
 
@@ -1753,8 +1756,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
 
 #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
 
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
 {
 	/*
 	 * Due to legacy code that sets the ->dma_coherent flag from a bus
@@ -1774,7 +1776,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 		return;
 
 	if (device_iommu_mapped(dev))
-		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
+		arm_setup_iommu_dma_ops(dev);
 
 	xen_setup_dma_ops(dev);
 	dev->archdata.dma_ops_setup = true;
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 313d8938a2f0..0b320a25a471 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -46,8 +46,7 @@ void arch_teardown_dma_ops(struct device *dev)
 }
 #endif
 
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
 {
 	int cls = cache_line_size_of_cpu();
 
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index 0f3cec663a12..ab4f2a75a7d0 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -137,8 +137,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
 #endif
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
 {
 	dev->dma_coherent = coherent;
 }
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
index 843107f834b2..cb89d7e0ba88 100644
--- a/arch/riscv/mm/dma-noncoherent.c
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -128,8 +128,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 	ALT_CMO_OP(FLUSH, flush_addr, size, riscv_cbom_block_size);
 }
 
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-			bool coherent)
+void arch_setup_dma_ops(struct device *dev, bool coherent)
 {
 	WARN_TAINT(!coherent && riscv_cbom_block_size > ARCH_DMA_MINALIGN,
 		   TAINT_CPU_OUT_OF_SPEC,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e6ed1ba91e5c..f5df17d11717 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1640,12 +1640,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 	if (ret == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
-	/*
-	 * Historically this routine doesn't fail driver probing due to errors
-	 * in acpi_iommu_configure_id()
-	 */
-
-	arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT);
+	arch_setup_dma_ops(dev, attr == DEV_DMA_COHERENT);
 
 	return 0;
 }
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 0285a74363b3..0e2decd1167a 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -484,11 +484,7 @@ EXPORT_SYMBOL_GPL(hv_query_ext_cap);
 
 void hv_setup_dma_ops(struct device *dev, bool coherent)
 {
-	/*
-	 * Hyper-V does not offer a vIOMMU in the guest
-	 * VM, so pass 0/NULL for the IOMMU settings
-	 */
-	arch_setup_dma_ops(dev, 0, 0, coherent);
+	arch_setup_dma_ops(dev, coherent);
 }
 EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
 
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 9e7963972fa7..312c63361211 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -95,7 +95,6 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 {
 	const struct bus_dma_region *map = NULL;
 	struct device_node *bus_np;
-	u64 dma_start = 0;
 	u64 mask, end = 0;
 	bool coherent;
 	int iommu_ret;
@@ -118,7 +117,6 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 			return ret == -ENODEV ? 0 : ret;
 	} else {
 		/* Determine the overall bounds of all DMA regions */
-		dma_start = dma_range_map_min(map);
 		end = dma_range_map_max(map);
 	}
 
@@ -175,7 +173,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	} else
 		dev_dbg(dev, "device is behind an iommu\n");
 
-	arch_setup_dma_ops(dev, dma_start, end - dma_start + 1, coherent);
+	arch_setup_dma_ops(dev, coherent);
 
 	if (iommu_ret)
 		of_dma_set_restricted_buffer(dev, np);
diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
index 4abc60f04209..ed89e1ce0114 100644
--- a/include/linux/dma-map-ops.h
+++ b/include/linux/dma-map-ops.h
@@ -426,11 +426,9 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg,
 #endif
 
 #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
-void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-		bool coherent);
+void arch_setup_dma_ops(struct device *dev, bool coherent);
 #else
-static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
-		u64 size, bool coherent)
+static inline void arch_setup_dma_ops(struct device *dev, bool coherent)
 {
 }
 #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
-- 
2.39.2.101.g768bb238c484.dirty



From broonie at kernel.org  Fri Feb  9 08:53:36 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 09 Feb 2024 16:53:36 +0000
Subject: [PATCH v2] arm64/sve: Document that __SVE_VQ_MAX is much larger
 than needed
Message-ID: <20240209-arm64-sve-vl-max-comment-v2-1-111b283469ee@kernel.org>

__SVE_VQ_MAX is defined without comment as 512 but the actual
architectural maximum is 16, a substantial difference which might not
be obvious to readers especially given the several different units used
for specifying vector sizes in various contexts and the fact that it's
often used via macros.  In an effort to minimise surprises for users who
might assume the value is the architectural maximum and use it to do
things like size allocations add a comment noting the difference, and
add a note for SVE_VQ_MAX to aid discoverability.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
Changes in v2:
- Use new wording mostly provided by Dave Martin.
- Reference __SVE_VQ_MAX comment near SVE_VQ_MAX define.
- Link to v1: https://lore.kernel.org/r/20240206-arm64-sve-vl-max-comment-v1-1-dddf16414412 at kernel.org
---
 arch/arm64/include/uapi/asm/sve_context.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/sve_context.h b/arch/arm64/include/uapi/asm/sve_context.h
index 754ab751b523..72aefc081061 100644
--- a/arch/arm64/include/uapi/asm/sve_context.h
+++ b/arch/arm64/include/uapi/asm/sve_context.h
@@ -13,6 +13,17 @@
 
 #define __SVE_VQ_BYTES		16	/* number of bytes per quadword */
 
+/*
+ * Yes, __SVE_VQ_MAX is 512 QUADWORDS.
+ *
+ * To help ensure forward portability, this is much larger than the
+ * current maximum value defined by the SVE architecture.  While arrays
+ * or static allocations can be sized based on this value, watch out!
+ * It will waste a surprisingly large amount of memory.
+ *
+ * Dynamic sizing based on the actual runtime vector length is likely to
+ * be preferable for most purposes.
+ */
 #define __SVE_VQ_MIN		1
 #define __SVE_VQ_MAX		512
 

---
base-commit: 54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478
change-id: 20240206-arm64-sve-vl-max-comment-64efa3f03625

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From geert+renesas at glider.be  Fri Feb  9 08:54:53 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri,  9 Feb 2024 17:54:53 +0100
Subject: [GIT PULL 4/4] Renesas DTS updates for v6.9
In-Reply-To: <cover.1707487826.git.geert+renesas@glider.be>
References: <cover.1707487826.git.geert+renesas@glider.be>
Message-ID: <cover.1707487834.git.geert+renesas@glider.be>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-dts-for-v6.9-tag1

for you to fetch changes up to 785b3c25761a828c5e22b3361541c50fd3b92fde:

  arm64: dts: renesas: gray-hawk-single: Enable watchdog timer (2024-02-06 10:48:35 +0100)

----------------------------------------------------------------
Renesas DTS updates for v6.9

  - Add GPIO keys and watchdog support for the RZ/G3S SMARC development
    board,
  - Add GNSS support for Renesas ULCB development boards equipped with
    the Shimafuji Kingfisher extension,
  - Add support for the standalone White Hawk CPU board,
  - Add support for the R-Car V4H ES2.0 (R8A779G2) SoC and the White
    Hawk Single development board,
  - Add initial support for the R-Car V4M (R8A779H0) SoC and the Gray
    Hawk Single development board,
  - Add camera support for the RZ/G2UL SoC,
  - Miscellaneous fixes and improvements.

Note that this includes the "renesas-r8a779h0-dt-binding-defs-tag" tag,
which is based on the pmdomain immutable "dt" branch.  It contains DT
binding definitions for the Renesas R-Car V4M (R8A779H0) SoC, and is
shared by the pmdomain and clock drivers, and the DT source files.

----------------------------------------------------------------
Biju Das (1):
      arm64: dts: renesas: r9a07g043u: Add CSI and CRU nodes

Claudiu Beznea (3):
      arm64: dts: renesas: rzg3s-smarc: Add gpio keys
      arm64: dts: renesas: r9a08g045: Add watchdog node
      arm64: dts: renesas: rzg3s-smarc-som: Enable the watchdog interface

Duy Nguyen (3):
      dt-bindings: power: renesas,rcar-sysc: Document R-Car V4M support
      dt-bindings: power: Add r8a779h0 SYSC power domain definitions
      dt-bindings: clock: Add R8A779H0 V4M CPG Core Clock Definitions

Geert Uytterhoeven (19):
      ARM: dts: renesas: r8a73a4: Fix external clocks and clock rate
      ARM: dts: renesas: r8a73a4: Add cp clock
      ARM: dts: renesas: r8a73a4: Fix thermal parent clock
      arm64: dts: renesas: r8a779g0: Restore sort order
      arm64: dts: renesas: r8a779g0: Add standalone White Hawk CPU support
      arm64: dts: renesas: white-hawk-cpu: Restore sort order
      arm64: dts: renesas: white-hawk: Drop SoC parts from sub boards
      arm64: dts: renesas: white-hawk: Add SoC name to top-level comment
      arm64: dts: renesas: white-hawk-cpu: Factor out common parts
      arm64: dts: renesas: white-hawk: Factor out common parts
      arm64: dts: renesas: Add Renesas R8A779G2 SoC support
      arm64: dts: renesas: r8a779g2: Add White Hawk Single support
      dt-bindings: clock: renesas,cpg-mssr: Document R-Car V4M support
      arm64: dts: renesas: r8a779g0: Add missing SCIF_CLK2
      Merge tag 'renesas-r8a779h0-dt-binding-defs-tag' into renesas-dts-for-v6.9
      arm64: dts: renesas: Add Gray Hawk Single board support
      ARM: dts: renesas: Improve TMU interrupt descriptions
      arm64: dts: renesas: Improve TMU interrupt descriptions
      arm64: dts: renesas: gray-hawk-single: Enable watchdog timer

Hai Pham (1):
      arm64: dts: renesas: Add Renesas R8A779H0 SoC support

Minh Le (1):
      arm64: dts: renesas: r8a779h0: Add RWDT node

Wolfram Sang (2):
      arm64: dts: renesas: ulcb-kf: Drop duplicate 3.3v regulators
      arm64: dts: renesas: ulcb-kf: Add node for GNSS

 .../bindings/clock/renesas,cpg-mssr.yaml           |   1 +
 .../bindings/power/renesas,rcar-sysc.yaml          |   1 +
 arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts      |  12 +
 arch/arm/boot/dts/renesas/r8a73a4.dtsi             |  23 +-
 arch/arm/boot/dts/renesas/r8a7740.dtsi             |   2 +
 arch/arm/boot/dts/renesas/r8a7778.dtsi             |   9 +-
 arch/arm/boot/dts/renesas/r8a7779.dtsi             |   9 +-
 arch/arm64/boot/dts/renesas/Makefile               |   5 +
 arch/arm64/boot/dts/renesas/r8a774a1.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a774b1.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a774c0.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a774e1.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a77951.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a77960.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a77961.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a77965.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a77970.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a77980.dtsi          |  17 +-
 arch/arm64/boot/dts/renesas/r8a77990.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a77995.dtsi          |  11 +-
 arch/arm64/boot/dts/renesas/r8a779a0.dtsi          |  17 +-
 arch/arm64/boot/dts/renesas/r8a779f0.dtsi          |  17 +-
 .../boot/dts/renesas/r8a779g0-white-hawk-cpu.dts   |  13 +
 .../boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi  | 368 +-------------------
 .../arm64/boot/dts/renesas/r8a779g0-white-hawk.dts |  58 +---
 arch/arm64/boot/dts/renesas/r8a779g0.dtsi          | 101 +++---
 .../dts/renesas/r8a779g2-white-hawk-single.dts     |  26 ++
 arch/arm64/boot/dts/renesas/r8a779g2.dtsi          |  12 +
 .../boot/dts/renesas/r8a779h0-gray-hawk-single.dts |  57 ++++
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi          | 132 ++++++++
 arch/arm64/boot/dts/renesas/r9a07g043u.dtsi        |  69 ++++
 arch/arm64/boot/dts/renesas/r9a08g045.dtsi         |  14 +
 arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi   |   5 +
 arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi       |  53 +++
 arch/arm64/boot/dts/renesas/ulcb-kf.dtsi           |  42 +--
 arch/arm64/boot/dts/renesas/white-hawk-common.dtsi |  65 ++++
 .../boot/dts/renesas/white-hawk-cpu-common.dtsi    | 375 +++++++++++++++++++++
 ...e-hawk-csi-dsi.dtsi => white-hawk-csi-dsi.dtsi} |   2 +-
 ...hawk-ethernet.dtsi => white-hawk-ethernet.dtsi} |   2 +-
 .../dt-bindings/clock/renesas,r8a779h0-cpg-mssr.h  |  96 ++++++
 include/dt-bindings/power/renesas,r8a779h0-sysc.h  |  49 +++
 41 files changed, 1233 insertions(+), 540 deletions(-)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779g2.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779h0.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/white-hawk-common.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi
 rename arch/arm64/boot/dts/renesas/{r8a779g0-white-hawk-csi-dsi.dtsi => white-hawk-csi-dsi.dtsi} (97%)
 rename arch/arm64/boot/dts/renesas/{r8a779g0-white-hawk-ethernet.dtsi => white-hawk-ethernet.dtsi} (76%)
 create mode 100644 include/dt-bindings/clock/renesas,r8a779h0-cpg-mssr.h
 create mode 100644 include/dt-bindings/power/renesas,r8a779h0-sysc.h


From geert+renesas at glider.be  Fri Feb  9 08:54:52 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri,  9 Feb 2024 17:54:52 +0100
Subject: [GIT PULL 3/4] Renesas DT binding updates for v6.9
In-Reply-To: <cover.1707487826.git.geert+renesas@glider.be>
References: <cover.1707487826.git.geert+renesas@glider.be>
Message-ID: <cover.1707487832.git.geert+renesas@glider.be>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-dt-bindings-for-v6.9-tag1

for you to fetch changes up to 49558e814fefdf33bf0b2d1c46c30d6a3f9634f3:

  dt-bindings: soc: renesas: Document R-Car V4M Gray Hawk Single (2024-01-31 15:06:52 +0100)

----------------------------------------------------------------
Renesas DT binding updates for v6.9

  - Document support for the Renesas R-Car V4M (R8A779H0) SoC, and the
    White Hawk Single and Gray Hawk Single development boards.

----------------------------------------------------------------
Geert Uytterhoeven (3):
      dt-bindings: soc: renesas: Document R-Car V4H White Hawk Single
      dt-bindings: reset: renesas,rst: Document R-Car V4M support
      dt-bindings: soc: renesas: Document R-Car V4M Gray Hawk Single

 Documentation/devicetree/bindings/reset/renesas,rst.yaml   |  1 +
 Documentation/devicetree/bindings/soc/renesas/renesas.yaml | 13 +++++++++++++
 2 files changed, 14 insertions(+)


From geert+renesas at glider.be  Fri Feb  9 08:54:51 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri,  9 Feb 2024 17:54:51 +0100
Subject: [GIT PULL 2/4] Renesas driver updates for v6.9
In-Reply-To: <cover.1707487826.git.geert+renesas@glider.be>
References: <cover.1707487826.git.geert+renesas@glider.be>
Message-ID: <cover.1707487830.git.geert+renesas@glider.be>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-drivers-for-v6.9-tag1

for you to fetch changes up to 14656ed72fa5d0a2f98be0ffd56274db30171f49:

  soc: renesas: rcar-rst: Add support for R-Car V4M (2024-01-31 15:08:41 +0100)

----------------------------------------------------------------
Renesas driver updates for v6.9

  - Initial support for the Renesas R-Car V4M (R8A779H0) SoC.

----------------------------------------------------------------
Duy Nguyen (2):
      soc: renesas: Identify R-Car V4M
      soc: renesas: rcar-rst: Add support for R-Car V4M

Geert Uytterhoeven (1):
      soc: renesas: Introduce ARCH_RCAR_GEN4

 drivers/soc/renesas/Kconfig       | 17 ++++++++++++++---
 drivers/soc/renesas/rcar-rst.c    |  1 +
 drivers/soc/renesas/renesas-soc.c |  8 ++++++++
 3 files changed, 23 insertions(+), 3 deletions(-)


From geert+renesas at glider.be  Fri Feb  9 08:54:49 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri,  9 Feb 2024 17:54:49 +0100
Subject: [GIT PULL 0/4] Renesas SoC updates for v6.9
Message-ID: <cover.1707487826.git.geert+renesas@glider.be>

	Hi SoC folks,

This is my first pull request for the inclusion of Renesas SoC updates
for v6.9.

It consists of 4 parts:

  [GIT PULL 1/4] Renesas ARM defconfig updates for v6.9

    - Disable obsolete board staging support in the Renesas ARM and ARM V7
      multi-platform defconfigs,
    - Enable support for the Renesas R-Car V4M (R8A779H0) SoC in the ARM64
      defconfig.

  [GIT PULL 2/4] Renesas driver updates for v6.9

    - Initial support for the Renesas R-Car V4M (R8A779H0) SoC.

  [GIT PULL 3/4] Renesas DT binding updates for v6.9

    - Document support for the Renesas R-Car V4M (R8A779H0) SoC, and the
      White Hawk Single and Gray Hawk Single development boards.

  [GIT PULL 4/4] Renesas DTS updates for v6.9

    - Add GPIO keys and watchdog support for the RZ/G3S SMARC development
      board,
    - Add GNSS support for Renesas ULCB development boards equipped with
      the Shimafuji Kingfisher extension,
    - Add support for the standalone White Hawk CPU board,
    - Add support for the R-Car V4H ES2.0 (R8A779G2) SoC and the White
      Hawk Single development board,
    - Add initial support for the R-Car V4M (R8A779H0) SoC and the Gray
      Hawk Single development board,
    - Add camera support for the RZ/G2UL SoC,
    - Miscellaneous fixes and improvements.

Thanks for pulling!

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 geert+renesas at glider.be  Fri Feb  9 08:54:50 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri,  9 Feb 2024 17:54:50 +0100
Subject: [GIT PULL 1/4] Renesas ARM defconfig updates for v6.9
In-Reply-To: <cover.1707487826.git.geert+renesas@glider.be>
References: <cover.1707487826.git.geert+renesas@glider.be>
Message-ID: <cover.1707487828.git.geert+renesas@glider.be>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-arm-defconfig-for-v6.9-tag1

for you to fetch changes up to 93189f33fcb4e678c9494cddeff96b123ef5674f:

  arm64: defconfig: Enable R8A779H0 SoC (2024-01-31 15:01:24 +0100)

----------------------------------------------------------------
Renesas ARM defconfig updates for v6.9

  - Disable obsolete board staging support in the Renesas ARM and ARM V7
    multi-platform defconfigs,
  - Enable support for the Renesas R-Car V4M (R8A779H0) SoC in the ARM64
    defconfig.

----------------------------------------------------------------
Geert Uytterhoeven (2):
      ARM: shmobile: defconfig: Disable staging
      ARM: multi_v7_defconfig: Disable board staging

Linh Phung (1):
      arm64: defconfig: Enable R8A779H0 SoC

 arch/arm/configs/multi_v7_defconfig | 1 -
 arch/arm/configs/shmobile_defconfig | 2 --
 arch/arm64/configs/defconfig        | 1 +
 3 files changed, 1 insertion(+), 3 deletions(-)


From tudor.ambarus at linaro.org  Fri Feb  9 08:55:43 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 9 Feb 2024 16:55:43 +0000
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth``
 property
In-Reply-To: <20240209-chest-sleet-a119fc3d4243@spud>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
 <20240208135045.3728927-2-tudor.ambarus@linaro.org>
 <20240208-grating-legwarmer-0a04cfb04d61@spud>
 <c2b08463-cb13-4e9b-8797-8ebcf1047f66@linaro.org>
 <20240209-chest-sleet-a119fc3d4243@spud>
Message-ID: <0ac8d573-6486-458d-afb9-090b5f8d4a21@linaro.org>



On 2/9/24 16:21, Conor Dooley wrote:
> On Fri, Feb 09, 2024 at 01:56:56PM +0000, Tudor Ambarus wrote:
>>
>> + Geert
>>
>> On 2/8/24 18:24, Conor Dooley wrote:
>>> On Thu, Feb 08, 2024 at 01:50:34PM +0000, Tudor Ambarus wrote:
>>>> There are instances of the same IP that are configured by the integrator
>>>> with different FIFO depths. Introduce the fifo-depth property to allow
>>>> such nodes to specify their FIFO depth.
>>>>
>>>> We haven't seen SPI IPs with different FIFO depths for RX and TX, thus
>>>> introduce a single property.
>>>
>>> Some citation attached to this would be nice. "We haven't seen" offers
>>> no detail as to what IPs that allow this sort of configuration of FIFO
>>> size that you have actually checked.
>>>
>>> I went and checked our IP that we use in FPGA fabric, which has a
>>> configurable fifo depth. It only has a single knob for both RX and TX
>>> FIFOs. The Xilinx xps spi core also has configurable FIFOs, but again RX
>>> and TX sizes are tied there. At least that's a sample size of three.
>>>
>>> One of our guys is working on support for the IP I just mentioned and
>>> would be defining a vendor property for this, so
>>> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
>>>
>>
>> Thanks, Conor. I had in mind that SPI has a shift register and it's
>> improbable to have different FIFO depths for RX and TX.
> 
> IDK, but I've learned to expect the unexpectable, especially when it
> comes to the IPs intended for use in FPGAs.
> 
>> At least I don't
>> see how it would work, I guess it will use the minimum depth between the
>> two?
> 
> I'm not really sure how it would work other than that in the general
> case, but some use case specific configuration could work, but I do
> agree that it is
> 
>> I grepped by "fifo" in the spi bindings and I now see that renesas is
>> using dedicated properties for RX and TX, but I think that there too the
>> FIFOs have the same depths. Looking into drivers/spi/spi-sh-msiof.c I
>> see that the of_device_id.data contains 64 bytes FIFOs for RX and TX,
>> regardless of the compatible.
>>
>> Geert, any idea if the FIFO depths can differ for RX and TX in
>> spi-sh-msiof.c?
>>
>> Anyway, even if there are such imbalanced architectures, I guess we can
>> consider them when/if they appear? (add rx/tx-fifo-depth dt properties)
> 
> I think so.
> 
>> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
>> Override the default TX fifo size.  Unit is words.  Ignored if 0.
>> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
>> renesas,rx-fifo-size:
>> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
>> Override the default RX fifo size.  Unit is words.  Ignored if 0.
> 
> These renesas ones seemed interesting at first glance due to these
> comments, but what's missed by grep the is "deprecated" marking on
> these. They seem to have been replaced by soc-specific compatibles.

In the driver the renesas,{rx,tx}-fifo-size properties still have the
highest priority:

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git/tree/drivers/spi/spi-sh-msiof.c#n1350

Maybe something for Geert, as I see he was the one marking these
properties as deprecated. I guess he forgot to update the driver.

Anyway, I think we shall be fine, even if we don't hear from Geert.

Cheers,
ta


From prudo at redhat.com  Fri Feb  9 08:59:03 2024
From: prudo at redhat.com (Philipp Rudo)
Date: Fri, 9 Feb 2024 17:59:03 +0100
Subject: [PATCH v3 00/17] kexec: Allow preservation of ftrace buffers
In-Reply-To: <3bfbe6b3-d293-483f-9f30-b7d49440be22@amazon.com>
References: <20240117144704.602-1-graf@amazon.com>
	<20240129173450.038e46b7@rotkaeppchen>
	<3bfbe6b3-d293-483f-9f30-b7d49440be22@amazon.com>
Message-ID: <20240209175903.15dcc714@rotkaeppchen>

Hi Alex,

On Fri, 2 Feb 2024 13:58:52 +0100
Alexander Graf <graf at amazon.com> wrote:

> Hi Philipp,
> 
> On 29.01.24 17:34, Philipp Rudo wrote:
> > Hi Alex,
> >
> > adding linux-integrity as there are some synergies with IMA_KEXEC (in case we
> > get KHO to work).
> >
> > Fist of all I believe that having a generic framework to pass information from
> > one kernel to the other across kexec would be a good thing. But I'm afraid that  
> 
> 
> Thanks, I'm happy to hear that you agree with the basic motivation :). 
> There are fundamentally 2 problems with passing data:
> 
>  ? * Passing structured data in a cross-architecture way
>  ? * Passing memory
> 
> KHO tackles both. It proposes a common FDT based format that allows us 
> to pass per-subsystem properties. That way, a subsystem does not need to 
> know whether it's running on ARM, x86, RISC-V or s390x. It just gains 
> awareness for KHO and can pass data.
> 
> On top of that, it proposes a standardized "mem" property (and some 
> magic around that) which allows subsystems to pass memory.
> 
> 
> > you are ignoring some fundamental problems which makes it extremely hard, if
> > not impossible, to reliably transfer the kernel's state from one kernel to the
> > other.
> >
> > One thing I don't understand is how reusing the scratch area is working. Sure
> > you pass it's location via the dt/boot_params but I don't see any code that
> > makes it a CMA region. So IIUC the scratch area won't be available for the 2nd
> > kernel. Which is probably for the better as IIUC the 2nd kernel gets loaded and
> > runs inside that area and I don't believe the CMA design ever considered that
> > the kernel image could be included in a CMA area.  
> 
> 
> That one took me a lot to figure out sensibly (with recursion all the 
> way down) while building KHO :). I hope I detailed it sensibly in the 
> documentation - please let me know how to improve it in case it's 
> unclear: https://lore.kernel.org/lkml/20240117144704.602-8-graf at amazon.com/
> 
> Let me explain inline using different words as well what happens:
> 
> The first (and only the first) kernel that boots allocates a CMA region 
> as "scratch region". It loads the new kernel into that region. It passes 
> that region as "scratch region" to the next kernel. The next kernel now 
> takes it and marks every page block that the scratch region spans as CMA:
> 
> https://lore.kernel.org/lkml/20240117144704.602-3-graf at amazon.com/
> 
> The CMA hint doesn't mean we create an actual CMA region. It mostly 
> means that the kernel won't use this memory for any kernel allocations. 
> Kernel allocations up to this point are allocations we don't need to 
> pass on with KHO again. Kernel allocations past that point may be 
> allocations that we want to pass, so we just never place them into the 
> "scratch region" again.
> 
> And because we now already have a scratch region from the previous 
> kernel, we keep reusing that forever with any new KHO kexec.

Thanks for the explanation. I've missed the memblock_mark_scratch in
kho_populate. The code makes much more sense now :-)

Having that said, for complex series like this one I like to do the
review on a branch in my local git as that to avoid problems like that
(or at least make them less likely). But your patches didn't apply. Can
you tell me what your base is or make your git branch available. That
would be very helpful to me. Thanks!

> > Staying at reusing the scratch area. One thing that is broken for sure is that
> > you reuse the scratch area without ever checking the kho_scratch parameter of
> > the 2nd kernel's command line. Remember, with kexec you are dealing with two
> > different kernels with two different command lines. Meaning you can only reuse
> > the scratch area if the requested size in the 2nd kernel is identical to the
> > one of the 1st kernel. In all other cases you need to adjust the scratch area's
> > size or reserve a new one.  
> 
> 
> Hm. So you're saying a user may want to change the size of the scratch 
> area with a KHO kexec. That's insanely risky because you (as rightfully 
> pointed out below) may have significant fragmentation at that point. And 
> we will only know when we're in the new kernel so it's too late to 
> abort. IMHO it's better to just declare the scratch region as immutable 
> during KHO to avoid that pitfall.

Yes, a user can set any command line with kexec. My expectation as a
user is that the kernel respects whatever I set on the command line and
doesn't think it knows better and simply ignores what I tell it to do.
So even when you set the scratch area immutable during boot you have to
make sure that in the end kernel respects what the user has set on the
2nd kernel's command line.

> > This directly leads to the next problem. In kho_reserve_previous_mem you are
> > reusing the different memory regions wherever the 1st kernel allocated them.
> > But that also means you are handing over the 1st kernel's memory
> > fragmentation to the 2nd kernel and you do that extremely early during boot.
> > Which means that users who need to allocate large continuous physical memory,
> > like the scratch area or the crashkernel memory, will have increasing chance to
> > not find a suitable area. Which IMHO is unacceptable.  
> 
> 
> Correct :). It basically means you want to pass large allocations from 
> the 1st kernel that you want to preserve on to the next. So if the 1st 
> kernel allocated a large crash area, it's safest to pass that allocation 
> using KHO to ensure the next kernel also has the region fully reserved. 
> Otherwise the next kernel may accidentally place data into the 
> previously reserved crash region (which would be contiguously free at 
> early init of the 2nd kernel) and fragment it again.

I don't think that this is an option. For one your suggestion means that
every "large allocation" (whatever that means) needs to be tracked
manually for it to work together with KHO. In addition there is still
the problem that the 2nd kernel may need a larger allocation than the
1st one. Be it because it's a command line parameter, e.g. kho_scratch
or crashkernel, or just a new feature that requires additional memory
the 2nd kernel has. IMO it's inevitable that KHO finds a way to
remove/reduce memory fragmentation.

> > Finally, and that's the big elephant in the room, is your lax handling of the
> > unstable kernel internal ABI. Remember, you are dealing with two different
> > kernels, that also means two different source levels and two different configs.
> > So only because both the 1st and 2nd kernel have a e.g. struct buffer_page
> > doesn't means that they have the same struct buffer_page. But that's what your
> > code implicitly assumes. For KHO ever to make it upstream you need to make sure
> > that both kernels are "speaking the same language".  
> 
> 
> Wow, I hope it didn't come across as that! The whole point of using FDT 
> and compatible strings in KHO is to solve exactly that problem. Any time 
> a passed over data structure changes incompatibly, you would need to 
> modify the compatible string of the subsystem that owns the now 
> incompatible data.
> 
> So in the example of struct buffer_page, it means that if anyone changes 
> the few bits we care about in struct buffer_page, we need to ensure that 
> the new kernel emits "ftrace,cpu-v2" compatible strings. We can at that 
> point choose whether we want to implement compat handling for 
> "ftrace,cpu-v1" style struct buffer_pages or only support same version 
> ingestion.

Well, it came across like that because there was absolutely no
explanation on when those versions need to be bumped up so far.

> The one thing that we could improve on here today IMHO is to have 
> compile time errors if any part of struct buffer_page changes 
> semantically: So we'd create a few defines for the bits we want in 
> "ftrace,cpu-v1" as well as size of struct buffer_page and then compare 
> them to what the struct offsets are at compile time to ensure they stay 
> identical.

How do you imagine those macros to look like? How do they work with
structs that change their layout depending on the config?

Personally, I highly doubt that any system that manages these different
versions manually will work reliably. It might be possible for
something as simple as struct buffer_page but once it gets more
complicated, e.g. by depending on the kernel config or simply having
more dependencies to common data structures, it will be a constant
source of pain.
Just assume, although extremely unlikely, that struct list_head is
changed. Most likely the person who makes the change won't be from the
ftrace team and thus won't know that he/she/it needs to bump the
version. Even the compile time errors will only help if
CONFIG_FTRACE_KHO is enabled which most like won't be the case.
Ultimately this means that KHO will break silently until someone tries
to kexec in the new kernel with KHO enabled. But even then there will
only be a cryptic error message (if any) as you have basically
introduced a memory corruption to the 2nd kernel. The more complex the
structs become and the deeper the dependency list goes the more likely
it becomes that such a breaking change is made.

The way I see it there is no way around generating the version based on
the actual memory layout for this particular build.

> Please let me know how I can clarify that more in the documentation. It 
> really is the absolute core of KHO.
> 
> 
> > Personally I see two possible solutions:
> >
> > 1) You introduce a stable intermediate format for every subsystem similar to
> > what IMA_KEXEC does. This should work for simple types like struct buffer_page
> > but for complex ones like struct vfio_device that's basically impossible.  
> 
> 
> I don't see why. The only reason KHO passes struct buffer_page as memory 
> is because we want to be able to produce traces even after KHO 
> serialization is done. For vfio_device, I think it's perfectly 
> reasonable to serialize any data we need to preserve directly into FDT 
> properties.
> 
> 
> 
> > 2) You also hand over the ABI version for every given type (basically just a
> > hash over all fields including all the dependencies). So the 2nd kernel can
> > verify that the data handed over is in a format it can handle and if not bail
> > out with a descriptive error message rather than reading garbage. Plus side is
> > that once such a system is in place you can reuse it to automatically resolve
> > all dependencies so you no longer need to manually store the buffer_page and
> > its buffer_data_page separately.
> > Down side is that traversing the debuginfo (including the ones from modules) is
> > not a simple task and I expect that such a system will be way more complex than
> > the rest of KHO. In addition there are some cases that the versioning won't be
> > able to capture. For example if a type contains a "void *"-field. Then although
> > the definition of the type is identical in both kernels the field can be cast
> > to different types when used. An other problem will be function pointers which
> > you first need to resolve in the 1st kernel and then map to the identical
> > function in the 2nd kernel. This will become particularly "fun" when the
> > function is part of a module that isn't loaded at the time when you try to
> > recreate the kernel's state.  
> 
> 
> The whole point of KHO is to leave it to the subsystem which path they 
> want to take. The subsystem can either pass binary data and validate as 
> part of FDT properties (like compatible strings). That data can be 
> identical to today's in-kernel data structures (usually a bad idea) or 
> can be a new intermediate data format. But the subsystem can also choose 
> to fully serialize into FDT properties and not pass any memory at all 
> for state that would be in structs. Or something in between.

That's totally fine. My point is that there are simply too many ways to
fuck it up and break the 2nd kernel. That's why I don't believe that we
can rely on the subsystems to "do it right" and "remember to bump the
version". In other words, KHO needs to provide a reliable, automatic
mechanism with wich the 2nd kernel can decide if it can handle the
passed data or not.

> > So to summarize, while it would be nice to have a generic framework like KHO to
> > pass data from one kernel to the other via kexec there are good reasons why it
> > doesn't exist, yet.  
> 
> 
> I hope my explanations above clarify things a bit. Let me know if you're 
> at FOSDEM, happy to talk about the internals there as well :)

Sorry, I couldn't make it to FOSDEM but I plan to be at LPC later this
year. In fact I had your talk on my list last year. Unfortunately it was
parallel to the kernel debugger mc...

Thanks
Philipp

> Alex
> 
> 
> 
> 
> 
> Amazon Development Center Germany GmbH
> Krausenstr. 38
> 10117 Berlin
> Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
> Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
> Sitz: Berlin
> Ust-ID: DE 289 237 879
> 
> 
> _______________________________________________
> kexec mailing list
> kexec at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec



From will at kernel.org  Fri Feb  9 09:02:51 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 9 Feb 2024 17:02:51 +0000
Subject: [PATCH] perf/arm-cmn: Workaround AmpereOneX errata AC04_MESH_1
 (incorrect child count)
In-Reply-To: <8bf2275a-dea7-1817-731a-7d47d3b01d13@os.amperecomputing.com>
References: <20240205194655.1567434-1-ilkka@os.amperecomputing.com>
 <dd862d7a-11bd-482a-b248-60d4616fb6ef@arm.com>
 <8bf2275a-dea7-1817-731a-7d47d3b01d13@os.amperecomputing.com>
Message-ID: <20240209170251.GA25069@willie-the-truck>

On Tue, Feb 06, 2024 at 01:04:27PM -0800, Ilkka Koskinen wrote:
> On Tue, 6 Feb 2024, Robin Murphy wrote:
> > On 2024-02-05 7:46 pm, Ilkka Koskinen wrote:
> > diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> > index c584165b13ba..7e3aa7e2345f 100644
> > --- a/drivers/perf/arm-cmn.c
> > +++ b/drivers/perf/arm-cmn.c
> > @@ -2305,6 +2305,17 @@ static int arm_cmn_discover(struct arm_cmn *cmn,
> > unsigned int rgn_offset)
> > 				dev_dbg(cmn->dev, "ignoring external node %llx\n", reg);
> > 				continue;
> > 			}
> > +			/*
> > +			 * AmpereOneX erratum AC04_MESH_1 makes some XPs report a bogus
> > +			 * child count larger than the number of valid child pointers.
> > +			 * A child offset of 0 can only occur on CMN-600; otherwise it
> > +			 * would imply the root node being its own grandchild, which
> > +			 * we can safely dismiss in general.
> > +			 */
> > +			if (reg == 0 && cmn->part != PART_CMN600) {
> > +				dev_dbg(cmn->dev, "bogus child pointer?\n");
> > +				continue;
> > +			}
> >  			arm_cmn_init_node_info(cmn, reg & CMN_CHILD_NODE_ADDR, dn);
> > 
> 
> Tested-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>

Mind sending that out as a proper patch that I can pick up, please?

Cheers,

Will


From conor at kernel.org  Fri Feb  9 09:02:54 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 9 Feb 2024 17:02:54 +0000
Subject: [PATCH v9 2/4] dt-bindings: stm32: update DT bingding for
 stm32mp25
In-Reply-To: <768067ff-cd69-4a55-aa5a-fc1eae5c1116@foss.st.com>
References: <20240208142301.155698-1-gabriel.fernandez@foss.st.com>
 <20240208142301.155698-3-gabriel.fernandez@foss.st.com>
 <20240208-syndrome-storeroom-5cc8bdd07c05@spud>
 <768067ff-cd69-4a55-aa5a-fc1eae5c1116@foss.st.com>
Message-ID: <20240209-stinging-unwarlike-674ebb82d53e@spud>

On Fri, Feb 09, 2024 at 10:46:14AM +0100, Gabriel FERNANDEZ wrote:
> Hi Conor,
> 
> Thank's for your review.
> 
> Yes, I have checked that point. I have also written the RCC driver for
> TFA/OPTE/UBOOT and once
> 
> I receive Ack in the Kernel, I will upstream the other components.

Okay, if you know theres no other implementations:
Acked-by: Conor Dooley <conor.dooley at microchip.com>

btw, please avoid top posting in the future.

Thanks,
Conor.
-------------- 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/20240209/548fc9e9/attachment.sig>

From romain.naour at smile.fr  Fri Feb  9 09:09:41 2024
From: romain.naour at smile.fr (Romain Naour)
Date: Fri, 9 Feb 2024 18:09:41 +0100
Subject: [PATCH 2/2] arm64: dts: ti: k3-j721e-sk: fix PMIC interrupt
 number
In-Reply-To: <20240208212422.213693-2-romain.naour@smile.fr>
References: <20240208212422.213693-1-romain.naour@smile.fr>
 <20240208212422.213693-2-romain.naour@smile.fr>
Message-ID: <045d1d74-d369-40d7-ad34-2094afd2c47a@smile.fr>

Hello,

Le 08/02/2024 ? 22:24, Romain Naour a ?crit?:
> The tps659413 node set WKUP_GPIO0_7 (G28) pin as input to be used as
> PMIC interrupt but uses 9 (WKUP_GPIO0_9) as "interrupts" property.
> 
> Replace 9 by 7 after checking in the board schematic [1].
> 
> [1] https://www.ti.com/tool/SK-TDA4VM
> 
> Fixes: b808cef0be46 ("arm64: dts: ti: k3-j721e-sk: Add TPS6594 family PMICs")
> Cc: Neha Malcom Francis <n-francis at ti.com>
> Signed-off-by: Romain Naour <romain.naour at smile.fr>
> ---
>  arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
> index 188dfe291a32..6a8866055f77 100644
> --- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
> @@ -574,7 +574,7 @@ tps659413: pmic at 48 {
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&pmic_irq_pins_default>;
>  		interrupt-parent = <&wkup_gpio0>;
> -		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
> +		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;

We need to do this change for both tps659413 and tps659411 nodes for the
k3-j721e-sk board.

There is only one PMIC on k3-am69-sk.

I'll send a v2.

Best regards,
Romain


>  		gpio-controller;
>  		#gpio-cells = <2>;
>  		ti,primary-pmic;



From robin.murphy at arm.com  Fri Feb  9 09:11:09 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri,  9 Feb 2024 17:11:09 +0000
Subject: [PATCH v2] perf/arm-cmn: Workaround AmpereOneX errata AC04_MESH_1 (incorrect child count)
Message-ID: <ce4b1442135fe03d0de41859b04b268c88c854a3.1707498577.git.robin.murphy@arm.com>

From: Ilkka Koskinen <ilkka at os.amperecomputing.com>

AmpereOneX mesh implementation has a bug in HN-P nodes that makes them
report incorrect child count. The failing crosspoints report 8 children
while they only have two.

When the driver tries to access the inexistent child nodes, it believes it
has reached an invalid node type and probing fails. The workaround is to
ignore those incorrect child nodes and continue normally.

Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
[ rm: rewrote simpler generalised version ]
Tested-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/perf/arm-cmn.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index c584165b13ba..7e3aa7e2345f 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -2305,6 +2305,17 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
 				dev_dbg(cmn->dev, "ignoring external node %llx\n", reg);
 				continue;
 			}
+			/*
+			 * AmpereOneX erratum AC04_MESH_1 makes some XPs report a bogus
+			 * child count larger than the number of valid child pointers.
+			 * A child offset of 0 can only occur on CMN-600; otherwise it
+			 * would imply the root node being its own grandchild, which
+			 * we can safely dismiss in general.
+			 */
+			if (reg == 0 && cmn->part != PART_CMN600) {
+				dev_dbg(cmn->dev, "bogus child pointer?\n");
+				continue;
+			}
 
 			arm_cmn_init_node_info(cmn, reg & CMN_CHILD_NODE_ADDR, dn);
 
-- 
2.39.2.101.g768bb238c484.dirty



From romain.naour at smile.fr  Fri Feb  9 09:11:45 2024
From: romain.naour at smile.fr (Romain Naour)
Date: Fri,  9 Feb 2024 18:11:45 +0100
Subject: [PATCH v2 1/2] arm64: dts: ti: k3-am69-sk: fix PMIC interrupt number
Message-ID: <20240209171146.307465-1-romain.naour@smile.fr>

The tps659413 node set WKUP_GPIO0_83 (AA37) pin as input to be used as
PMIC interrupt but uses 39 (WKUP_GPIO0_39) as "interrupts" property.

Replace 39 by 83 after checking in the board schematic [1].

[1] https://www.ti.com/tool/SK-AM69

Fixes: 865a1593bf99 ("arm64: dts: ti: k3-am69-sk: Add support for TPS6594 PMIC")
Cc: Neha Malcom Francis <n-francis at ti.com>
Signed-off-by: Romain Naour <romain.naour at smile.fr>
---
 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 8da591579868..95c9d3da59d3 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -646,7 +646,7 @@ tps659413: pmic at 48 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pmic_irq_pins_default>;
 		interrupt-parent = <&wkup_gpio0>;
-		interrupts = <39 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <83 IRQ_TYPE_EDGE_FALLING>;
 		gpio-controller;
 		#gpio-cells = <2>;
 		ti,primary-pmic;
-- 
2.43.0



From conor at kernel.org  Fri Feb  9 09:11:46 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 9 Feb 2024 17:11:46 +0000
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI
 TPS65224 PMIC
In-Reply-To: <20240208105343.1212902-4-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
 <20240208105343.1212902-4-bhargav.r@ltts.com>
Message-ID: <20240209-blitz-fidgety-78469aa80d6d@spud>

On Thu, Feb 08, 2024 at 04:23:33PM +0530, Bhargav Raviprakash wrote:
> TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
> regulators, it includes additional features like GPIOs, watchdog, ESMs
> (Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
> managing the state of the device.

> TPS6594 and TPS65224 have significant functional overlap.

What does "significant functional overlap" mean? Does one implement a
compatible subset of the other? I assume the answer is no, given there
seems to be some core looking registers at different addresses.

Thanks,
Conor.

-------------- 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/20240209/8652ecb8/attachment.sig>

From romain.naour at smile.fr  Fri Feb  9 09:11:46 2024
From: romain.naour at smile.fr (Romain Naour)
Date: Fri,  9 Feb 2024 18:11:46 +0100
Subject: [PATCH v2 2/2] arm64: dts: ti: k3-j721e-sk: fix PMIC interrupt number
In-Reply-To: <20240209171146.307465-1-romain.naour@smile.fr>
References: <20240209171146.307465-1-romain.naour@smile.fr>
Message-ID: <20240209171146.307465-2-romain.naour@smile.fr>

The tps659413 and tps659411 nodes set WKUP_GPIO0_7 (G28) pin as input
to be used as PMIC interrupt but uses 9 (WKUP_GPIO0_9) as
"interrupts" property.

Replace 9 by 7 for both tps659413 and tps659411 after checking in the
board schematic [1].

[1] https://www.ti.com/tool/SK-TDA4VM

Fixes: b808cef0be46 ("arm64: dts: ti: k3-j721e-sk: Add TPS6594 family PMICs")
Cc: Neha Malcom Francis <n-francis at ti.com>
Signed-off-by: Romain Naour <romain.naour at smile.fr>
---
v2: update tps659411 interrupts parameter too.
---
 arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
index 188dfe291a32..658764f7d544 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
@@ -574,7 +574,7 @@ tps659413: pmic at 48 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pmic_irq_pins_default>;
 		interrupt-parent = <&wkup_gpio0>;
-		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
 		gpio-controller;
 		#gpio-cells = <2>;
 		ti,primary-pmic;
@@ -651,7 +651,7 @@ tps659411: pmic at 4c {
 		reg = <0x4c>;
 		system-power-controller;
 		interrupt-parent = <&wkup_gpio0>;
-		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
 		gpio-controller;
 		#gpio-cells = <2>;
 		buck1234-supply = <&vsys_3v3>;
-- 
2.43.0



From will at kernel.org  Fri Feb  9 09:11:55 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 9 Feb 2024 17:11:55 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <CAD=FV=XupbtO3_+P9=XO26vH_5nALSSLZZHZywPSR_hQsWxM0Q@mail.gmail.com>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
 <CAD=FV=XupbtO3_+P9=XO26vH_5nALSSLZZHZywPSR_hQsWxM0Q@mail.gmail.com>
Message-ID: <20240209171155.GB25069@willie-the-truck>

Hi Doug,

On Mon, Feb 05, 2024 at 09:02:08AM -0800, Doug Anderson wrote:
> Hi,
> 
> On Sat, Feb 3, 2024 at 4:18?AM Mark Brown <broonie at kernel.org> wrote:
> >
> > Doug Anderson observed that ChromeOS crashes are being reported which
> > include failing allocations of order 7 during core dumps due to ptrace
> > allocating storage for regsets:
> >
> >   chrome: page allocation failure: order:7,
> >           mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
> >           nodemask=(null),cpuset=urgent,mems_allowed=0
> >    ...
> >   regset_get_alloc+0x1c/0x28
> >   elf_core_dump+0x3d8/0xd8c
> >   do_coredump+0xeb8/0x1378
> >
> > with further investigation showing that this is:
> >
> >    [   66.957385] DOUG: Allocating 279584 bytes
> >
> > which is the maximum size of the SVE regset. As Doug observes it is not
> > entirely surprising that such a large allocation of contiguous memory might
> > fail on a long running system.
> >
> > The SVE regset is currently sized to hold SVE registers with a VQ of
> > SVE_VQ_MAX which is 512, substantially more than the architectural maximum
> > of 16 which we might see even in a system emulating the limits of the
> > architecture. Since we don't expose the size we tell the regset core
> > externally let's define ARCH_SVE_VQ_MAX with the actual architectural
> > maximum and use that for the regset, we'll still overallocate most of the
> > time but much less so which will be helpful even if the core is fixed to
> > not require contiguous allocations.
> >
> > We could also teach the ptrace core about runtime discoverable regset sizes
> > but that would be a more invasive change and this is being observed in
> > practical systems.
> >
> > Reported-by: Doug Anderson <dianders at chromium.org>
> > Signed-off-by: Mark Brown <broonie at kernel.org>
> 
> Confirmed that when I send a "quit" signal to Chrome now that the
> allocation I see for "core_note_type" NT_ARM_SVE goes down from
> 279,584 bytes (n=17474) to just 8,768 bytes (n=548). I'm not
> intimately familiar with this code so I'll skip the Reviewed-by unless
> someone thinks it would be valuable for me to analyze more. I think
> there are already plenty of people who know this well, so for now,
> just:
> 
> Tested-by: Douglas Anderson <dianders at chromium.org>

I can pick this up as a short-term hack if it solves the problem for you,
but I also saw that you posted:

https://lore.kernel.org/r/20240205092626.v2.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924 at changeid

to fallback onto vmalloc() for large allocations.

What's your preference for a fix?

Cheers,

Will


From geert at linux-m68k.org  Fri Feb  9 09:13:59 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 9 Feb 2024 18:13:59 +0100
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth`` property
In-Reply-To: <20240208135045.3728927-2-tudor.ambarus@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org> <20240208135045.3728927-2-tudor.ambarus@linaro.org>
Message-ID: <CAMuHMdU_Hx9PLmHf2Xm1KKTy_OF-TeCv7SzmA5CZWz+PLkbAGA@mail.gmail.com>

Hi Tudor,

On Thu, Feb 8, 2024 at 2:51?PM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
> There are instances of the same IP that are configured by the integrator
> with different FIFO depths. Introduce the fifo-depth property to allow
> such nodes to specify their FIFO depth.
>
> We haven't seen SPI IPs with different FIFO depths for RX and TX, thus
> introduce a single property.

Ha...

Current documentation for the Clock-Synchronized Serial Interface with
FIFO (MSIOF) on e.g. R-Car Gen2 and later states:

    FIFO capacity: 32 bits ? 64 stages for transmission and 32 bits ?
256 stages for reception

Initially (many years ago), there was some doubt about the validity
of these values (older variants on SH supported 64/64), hence
drivers/spi/spi-sh-msiof.c still has

    .tx_fifo_size = 64,
    .rx_fifo_size = 64,

Probably we should test and revisit this...

> --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml
> +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml
> @@ -69,6 +69,11 @@ properties:
>           Should be generally avoided and be replaced by
>           spi-cs-high + ACTIVE_HIGH.
>
> +  fifo-depth:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Size of the data FIFO in bytes.

I think it is prudent to consider the asymmetric case, too.
Whether that should be just two properties ("rx-fifo-depth" and
"tx-fifo-depth"), or also a third "fifo-depth", I defer to the DT
maintainers...

> +
>    num-cs:
>      $ref: /schemas/types.yaml#/definitions/uint32
>      description:

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 nico at fluxnic.net  Fri Feb  9 09:15:52 2024
From: nico at fluxnic.net (Nicolas Pitre)
Date: Fri, 9 Feb 2024 12:15:52 -0500 (EST)
Subject: [PATCH] ARM: iwmmxt: Remove support for PJ4/PJ4B cores
In-Reply-To: <20240209110901.4032939-2-ardb+git@google.com>
References: <20240209110901.4032939-2-ardb+git@google.com>
Message-ID: <24156p9r-6p97-rro2-pqrq-858q8so01s9r@syhkavp.arg>

On Fri, 9 Feb 2024, Ard Biesheuvel wrote:

> From: Ard Biesheuvel <ardb at kernel.org>
> 
> PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
> does not support this combination (its iWMMXt configuration always
> implies v5te), and so there is no v6/v7 user space that actually makes
> use of this, beyond generic support for things like setjmp() that
> preserve/restore the iWMMXt register file using generic LDC/STC
> instructions emitted in assembler. As [0] appears to imply, this logic
> is triggered for the init process at boot, and so most processes will
> have a iWMMXt register context associated with it, even though it is
> never used.
> 
> This means that advertising iWMMXt support on these cores results in
> context switch overhead without any associated benefit, and so it is
> better to simply ignore the iWMMXt unit on these systems. So rip out the
> support. Doing so also fixes the issue reported in [0] related to UNDEF
> handling of co-processor #0/#1 instructions issued from user space
> running in Thumb2 mode.
> 
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Nicolas Pitre <nico at fluxnic.net>
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

Acked-by: Nicolas Pitre <nico at fluxnic.net>

I think Arnd is right suggesting you augment the commit message with the 
list of affected targets so to make this commit easier to find if ever a 
revert is needed.


> ---
>  arch/arm/Kconfig          |   4 +-
>  arch/arm/kernel/Makefile  |   2 -
>  arch/arm/kernel/iwmmxt.S  |  51 ++++----------
>  arch/arm/kernel/pj4-cp0.c | 135 --------------------------------------
>  4 files changed, 15 insertions(+), 177 deletions(-)
>  delete mode 100644 arch/arm/kernel/pj4-cp0.c
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 0af6709570d1..0d4e316a389e 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -503,8 +503,8 @@ source "arch/arm/mm/Kconfig"
>  
>  config IWMMXT
>  	bool "Enable iWMMXt support"
> -	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B
> -	default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B
> +	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
> +	default y if PXA27x || PXA3xx || ARCH_MMP
>  	help
>  	  Enable support for iWMMXt context switching at run time if
>  	  running on a CPU that supports it.
> diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
> index 771264d4726a..ae2f2b2b4e5a 100644
> --- a/arch/arm/kernel/Makefile
> +++ b/arch/arm/kernel/Makefile
> @@ -75,8 +75,6 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
>  obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
>  obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
>  obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
> -obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o
> -obj-$(CONFIG_CPU_PJ4B)		+= pj4-cp0.o
>  obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
>  obj-$(CONFIG_PERF_EVENTS)	+= perf_regs.o perf_callchain.o
>  obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event_xscale.o perf_event_v6.o \
> diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
> index a0218c4867b9..4a335d3c5969 100644
> --- a/arch/arm/kernel/iwmmxt.S
> +++ b/arch/arm/kernel/iwmmxt.S
> @@ -18,18 +18,6 @@
>  #include <asm/assembler.h>
>  #include "iwmmxt.h"
>  
> -#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
> -#define PJ4(code...)		code
> -#define XSC(code...)
> -#elif defined(CONFIG_CPU_MOHAWK) || \
> -	defined(CONFIG_CPU_XSC3) || \
> -	defined(CONFIG_CPU_XSCALE)
> -#define PJ4(code...)
> -#define XSC(code...)		code
> -#else
> -#error "Unsupported iWMMXt architecture"
> -#endif
> -
>  #define MMX_WR0		 	(0x00)
>  #define MMX_WR1		 	(0x08)
>  #define MMX_WR2		 	(0x10)
> @@ -81,17 +69,13 @@ ENDPROC(iwmmxt_undef_handler)
>  ENTRY(iwmmxt_task_enable)
>  	inc_preempt_count r10, r3
>  
> -	XSC(mrc	p15, 0, r2, c15, c1, 0)
> -	PJ4(mrc p15, 0, r2, c1, c0, 2)
> +	mrc	p15, 0, r2, c15, c1, 0
>  	@ CP0 and CP1 accessible?
> -	XSC(tst	r2, #0x3)
> -	PJ4(tst	r2, #0xf)
> +	tst	r2, #0x3
>  	bne	4f				@ if so no business here
>  	@ enable access to CP0 and CP1
> -	XSC(orr	r2, r2, #0x3)
> -	XSC(mcr	p15, 0, r2, c15, c1, 0)
> -	PJ4(orr	r2, r2, #0xf)
> -	PJ4(mcr	p15, 0, r2, c1, c0, 2)
> +	orr	r2, r2, #0x3
> +	mcr	p15, 0, r2, c15, c1, 0
>  
>  	ldr	r3, =concan_owner
>  	ldr	r2, [r0, #S_PC]			@ current task pc value
> @@ -218,12 +202,9 @@ ENTRY(iwmmxt_task_disable)
>  	bne	1f				@ no: quit
>  
>  	@ enable access to CP0 and CP1
> -	XSC(mrc	p15, 0, r4, c15, c1, 0)
> -	XSC(orr	r4, r4, #0x3)
> -	XSC(mcr	p15, 0, r4, c15, c1, 0)
> -	PJ4(mrc p15, 0, r4, c1, c0, 2)
> -	PJ4(orr	r4, r4, #0xf)
> -	PJ4(mcr	p15, 0, r4, c1, c0, 2)
> +	mrc	p15, 0, r4, c15, c1, 0
> +	orr	r4, r4, #0x3
> +	mcr	p15, 0, r4, c15, c1, 0
>  
>  	mov	r0, #0				@ nothing to load
>  	str	r0, [r3]			@ no more current owner
> @@ -232,10 +213,8 @@ ENTRY(iwmmxt_task_disable)
>  	bl	concan_save
>  
>  	@ disable access to CP0 and CP1
> -	XSC(bic	r4, r4, #0x3)
> -	XSC(mcr	p15, 0, r4, c15, c1, 0)
> -	PJ4(bic	r4, r4, #0xf)
> -	PJ4(mcr	p15, 0, r4, c1, c0, 2)
> +	bic	r4, r4, #0x3
> +	mcr	p15, 0, r4, c15, c1, 0
>  
>  	mrc	p15, 0, r2, c2, c0, 0
>  	mov	r2, r2				@ cpwait
> @@ -330,11 +309,9 @@ ENDPROC(iwmmxt_task_restore)
>   */
>  ENTRY(iwmmxt_task_switch)
>  
> -	XSC(mrc	p15, 0, r1, c15, c1, 0)
> -	PJ4(mrc	p15, 0, r1, c1, c0, 2)
> +	mrc	p15, 0, r1, c15, c1, 0
>  	@ CP0 and CP1 accessible?
> -	XSC(tst	r1, #0x3)
> -	PJ4(tst	r1, #0xf)
> +	tst	r1, #0x3
>  	bne	1f				@ yes: block them for next task
>  
>  	ldr	r2, =concan_owner
> @@ -344,10 +321,8 @@ ENTRY(iwmmxt_task_switch)
>  	retne	lr				@ no: leave Concan disabled
>  
>  1:	@ flip Concan access
> -	XSC(eor	r1, r1, #0x3)
> -	XSC(mcr	p15, 0, r1, c15, c1, 0)
> -	PJ4(eor r1, r1, #0xf)
> -	PJ4(mcr	p15, 0, r1, c1, c0, 2)
> +	eor	r1, r1, #0x3
> +	mcr	p15, 0, r1, c15, c1, 0
>  
>  	mrc	p15, 0, r1, c2, c0, 0
>  	sub	pc, lr, r1, lsr #32		@ cpwait and return
> diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
> deleted file mode 100644
> index 4bca8098c4ff..000000000000
> --- a/arch/arm/kernel/pj4-cp0.c
> +++ /dev/null
> @@ -1,135 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * linux/arch/arm/kernel/pj4-cp0.c
> - *
> - * PJ4 iWMMXt coprocessor context switching and handling
> - *
> - * Copyright (c) 2010 Marvell International Inc.
> - */
> -
> -#include <linux/types.h>
> -#include <linux/kernel.h>
> -#include <linux/signal.h>
> -#include <linux/sched.h>
> -#include <linux/init.h>
> -#include <linux/io.h>
> -#include <asm/thread_notify.h>
> -#include <asm/cputype.h>
> -
> -static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
> -{
> -	struct thread_info *thread = t;
> -
> -	switch (cmd) {
> -	case THREAD_NOTIFY_FLUSH:
> -		/*
> -		 * flush_thread() zeroes thread->fpstate, so no need
> -		 * to do anything here.
> -		 *
> -		 * FALLTHROUGH: Ensure we don't try to overwrite our newly
> -		 * initialised state information on the first fault.
> -		 */
> -
> -	case THREAD_NOTIFY_EXIT:
> -		iwmmxt_task_release(thread);
> -		break;
> -
> -	case THREAD_NOTIFY_SWITCH:
> -		iwmmxt_task_switch(thread);
> -		break;
> -	}
> -
> -	return NOTIFY_DONE;
> -}
> -
> -static struct notifier_block __maybe_unused iwmmxt_notifier_block = {
> -	.notifier_call	= iwmmxt_do,
> -};
> -
> -
> -static u32 __init pj4_cp_access_read(void)
> -{
> -	u32 value;
> -
> -	__asm__ __volatile__ (
> -		"mrc	p15, 0, %0, c1, c0, 2\n\t"
> -		: "=r" (value));
> -	return value;
> -}
> -
> -static void __init pj4_cp_access_write(u32 value)
> -{
> -	u32 temp;
> -
> -	__asm__ __volatile__ (
> -		"mcr	p15, 0, %1, c1, c0, 2\n\t"
> -#ifdef CONFIG_THUMB2_KERNEL
> -		"isb\n\t"
> -#else
> -		"mrc	p15, 0, %0, c1, c0, 2\n\t"
> -		"mov	%0, %0\n\t"
> -		"sub	pc, pc, #4\n\t"
> -#endif
> -		: "=r" (temp) : "r" (value));
> -}
> -
> -static int __init pj4_get_iwmmxt_version(void)
> -{
> -	u32 cp_access, wcid;
> -
> -	cp_access = pj4_cp_access_read();
> -	pj4_cp_access_write(cp_access | 0xf);
> -
> -	/* check if coprocessor 0 and 1 are available */
> -	if ((pj4_cp_access_read() & 0xf) != 0xf) {
> -		pj4_cp_access_write(cp_access);
> -		return -ENODEV;
> -	}
> -
> -	/* read iWMMXt coprocessor id register p1, c0 */
> -	__asm__ __volatile__ ("mrc    p1, 0, %0, c0, c0, 0\n" : "=r" (wcid));
> -
> -	pj4_cp_access_write(cp_access);
> -
> -	/* iWMMXt v1 */
> -	if ((wcid & 0xffffff00) == 0x56051000)
> -		return 1;
> -	/* iWMMXt v2 */
> -	if ((wcid & 0xffffff00) == 0x56052000)
> -		return 2;
> -
> -	return -EINVAL;
> -}
> -
> -/*
> - * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
> - * switch code handle iWMMXt context switching.
> - */
> -static int __init pj4_cp0_init(void)
> -{
> -	u32 __maybe_unused cp_access;
> -	int vers;
> -
> -	if (!cpu_is_pj4())
> -		return 0;
> -
> -	vers = pj4_get_iwmmxt_version();
> -	if (vers < 0)
> -		return 0;
> -
> -#ifndef CONFIG_IWMMXT
> -	pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n");
> -#else
> -	cp_access = pj4_cp_access_read() & ~0xf;
> -	pj4_cp_access_write(cp_access);
> -
> -	pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers);
> -	elf_hwcap |= HWCAP_IWMMXT;
> -	thread_register_notifier(&iwmmxt_notifier_block);
> -	register_iwmmxt_undef_handler();
> -#endif
> -
> -	return 0;
> -}
> -
> -late_initcall(pj4_cp0_init);
> -- 
> 2.43.0.687.g38aa6559b0-goog
> 
> 


From broonie at kernel.org  Fri Feb  9 09:25:57 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 9 Feb 2024 17:25:57 +0000
Subject: [PATCH v2 1/2] arm64/sme: Restore SMCR on exit from suspend
In-Reply-To: <20240209164648.GA24829@willie-the-truck>
References: <20240203-arm64-sme-resume-v2-0-a1fbaddc4425@kernel.org>
 <20240203-arm64-sme-resume-v2-1-a1fbaddc4425@kernel.org>
 <20240209164648.GA24829@willie-the-truck>
Message-ID: <ZcZgJaZy+57ERBnm@finisterre.sirena.org.uk>

On Fri, Feb 09, 2024 at 04:46:48PM +0000, Will Deacon wrote:

> Looking at the other places where we touch SMCR_EL1, it looks like we
> always use a read-modify-write sequence. However, doesn't that mean we
> inherit a bunch of unknown bits on cold boot? I'm basically wondering
> whether we should be initialising these registers to a well-known value
> earlier in the CPU init path, a bit like we do for the EL2 variants.

That'd be safer from a future proofing point of view, yes - we've got a
similar pattern with ZCR as well from the looks of it.  I'll send a
separate 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/20240209/497da14f/attachment.sig>

From nm at ti.com  Fri Feb  9 09:25:55 2024
From: nm at ti.com (Nishanth Menon)
Date: Fri, 9 Feb 2024 11:25:55 -0600
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <3a7c4a18-5463-414f-82df-39aaed861148@ti.com>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
 <20240207125410.r2q3jcplvif7dvt2@tumbling>
 <3a7c4a18-5463-414f-82df-39aaed861148@ti.com>
Message-ID: <20240209172555.fxlxijhhbgrkyibo@agreeing>

On 19:53-20240207, Kumar, Udit wrote:
> Hi?Nishanth,
> 
> On 2/7/2024 6:24 PM, Nishanth Menon wrote:
> > On 14:41-20240207, Udit Kumar wrote:
> > > Most of clocks and their parents are defined in contiguous range,
> > > But in few cases, there is gap in clock numbers[0].
> > > Driver assumes clocks to be in contiguous range, and add their clock
> > > ids incrementally.
> > > 
> > > New firmware started returning error while calling get_freq and is_on
> > > API for non-available clock ids.
> > > 
> > > In this fix, driver checks and adds only valid clock ids.
> > > 
> > > Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
> > > 
> > > [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> > > Section Clocks for NAVSS0_CPTS_0 Device,
> > > clock id 12-15 not present.
> > > 
> > > Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
> > > ---
> > > Changelog
> > > Changes in v3
> > > - instead of get_freq, is_auto API is used to check validilty of clock
> > > - Address comments of v2, to have preindex increment
> > > Link to v2 https://lore.kernel.org/all/20240206104357.3803517-1-u-kumar1 at ti.com/
> > > 
> > > Changes in v2
> > > - Updated commit message
> > > - Simplified logic for valid clock id
> > > link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/
> > > 
> > > 
> > > P.S
> > > Firmawre returns total num_parents count including non available ids.
> > > For above device id NAVSS0_CPTS_0, number of parents clocks are 16
> > > i.e from id 2 to 17. But out of these ids few are not valid.
> > > So driver adds only valid clock ids out ot total.
> > > 
> > > Original logs
> > > https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
> > > Line 2630 for error
> > > 
> > > Logs with fix v3
> > > https://gist.github.com/uditkumarti/94e3e28d62282fd708dbfe37435ce1d9#file-v3
> > > Line 2586
> > > 
> > > 
> > >   drivers/clk/keystone/sci-clk.c | 12 ++++++++++--
> > >   1 file changed, 10 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> > > index 35fe197dd303..31b7df05d7bb 100644
> > > --- a/drivers/clk/keystone/sci-clk.c
> > > +++ b/drivers/clk/keystone/sci-clk.c
> > > @@ -516,6 +516,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
> > >   	struct sci_clk *sci_clk, *prev;
> > >   	int num_clks = 0;
> > >   	int num_parents;
> > > [..]					/* Check if this clock id is valid */
> > > +					ret = provider->ops->is_auto(provider->sci,
> > > +						sci_clk->dev_id, ++clk_id, &state);
> > A bit too nice coding ;) => I had been confused momentarily by clk_id = args.args[1]
> > change just above till I saw that you are pre-incrementing
> > clk_id - Is there a harm in leaving the original clk_id increment logic
> > alone (it was much simpler to read up)?
> 
> No warm in using original code but want to avoid, two statement for
> increment in case of failure and success.
> 
> Let me know, if i need to add few comments around this
> 
> or if you think, code is confusing I can move to original one

Yes, please drop the un-necessary changes. In this case, original
increment code should work just fine.

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From nm at ti.com  Fri Feb  9 09:27:45 2024
From: nm at ti.com (Nishanth Menon)
Date: Fri, 9 Feb 2024 11:27:45 -0600
Subject: [PATCH v1 9/9] arm64: dts: ti: k3-am6*: Fix bootph-all property
 in MMC node
In-Reply-To: <20240207225526.3953230-10-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
 <20240207225526.3953230-10-jm@ti.com>
Message-ID: <20240209172745.dswt5q6xnulubrjp@bagpipe>

On 16:55-20240207, Judith Mendez wrote:
>  &sdhci1 {
>  	/* SD/MMC */
> +	bootph-all;
>  	status = "okay";
>  	vmmc-supply = <&vdd_mmc1>;
>  	vqmmc-supply = <&vddshv_sdio>;
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_mmc1_pins_default>;
>  	disable-wp;
> -	bootph-all;

NAK! Read [1]


[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/dts-coding-style.rst#n117

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From conor at kernel.org  Fri Feb  9 09:33:02 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 9 Feb 2024 17:33:02 +0000
Subject: [PATCH V2] dt-bindings: media: convert Mediatek consumer IR to
 the json-schema
In-Reply-To: <20240209085616.1062-1-zajec5@gmail.com>
References: <20240209085616.1062-1-zajec5@gmail.com>
Message-ID: <20240209-dweeb-spending-40fe58e644cb@spud>

On Fri, Feb 09, 2024 at 09:56:16AM +0100, Rafa? Mi?ecki wrote:
> +    ir at 10013000 {

I think I prefer "ir-receiver" as the node name, but not worth a respin
IMO.

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.
-------------- 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/20240209/7527a268/attachment.sig>

From catalin.marinas at arm.com  Fri Feb  9 09:33:23 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 9 Feb 2024 17:33:23 +0000
Subject: [PATCH v7 5/7] arm64: vmemmap: Avoid base2 order of struct page
 size to dimension region
In-Reply-To: <ZXnCEWeCZKfm_7GG@FVFF77S0Q05N>
References: <20231213084024.2367360-9-ardb@google.com>
 <20231213084024.2367360-14-ardb@google.com>
 <ZXm2c5_oA5rPrfm8@FVFF77S0Q05N>
 <CAMj1kXHTPYrmBx3Zbd5aceAnB-yDhh5gC+Nt8n2VjhY2hcbeEw@mail.gmail.com>
 <ZXnCEWeCZKfm_7GG@FVFF77S0Q05N>
Message-ID: <ZcZh4y-IKHSUSmtI@arm.com>

On Wed, Dec 13, 2023 at 02:39:30PM +0000, Mark Rutland wrote:
> > On Wed, 13 Dec 2023 at 14:49, Mark Rutland <mark.rutland at arm.com> wrote:
> > > | #define GUARD_VA_SIZE          (UL(SZ_8M))
> > > |
> > > | #define FIXADDR_TOP            (-GUARD_VA_SIZE)
> > > | #define FIXADDR_SIZE_MAX       SZ_8M
> > > | #define FIXADDR_START_MIN      (FIXADDR_TOP - FIXADDR_SIZE_MAX)
> > > |
> > > | #define PCI_IO_END             (FIXADDR_START_MIN - GUARD_VA_SIZE)
> > > | #define PCI_IO_START           (PCI_IO_END - PCI_IO_SIZE)
> > > |
> > > | #define VMEMMAP_END            (ALIGN_DOWN(PCI_IO_START - GUARD_VA_SIZE, SZ_1G))
> > > | #define VMEMMAP_START          (VMEMMAP_END - VMEMMAP_SIZE)
> > >
> > > ... and in fixmap.h have:
> > >
> > > /* Ensure the estimate in memory.h was big enough */
> > > static_assert(FIXADDR_SIZE_MAX > FIXADDR_SIZE);
[...]
> What I'm trying to do is make the relationship between those regions clear *in
> one place*, so that this is easier to follow, as that was one of the things I
> found painful during review. That said, it's not clear cut, and I'll happily
> defer to the judgement of Will and Catalin.

I think Mark's proposal is slightly cleaner. There's no actual layout
change, just making the maximum fixaddr size explicit in memory.h.

I'm queuing this series, so Mark please send a patch on top (I'll kick
off b4 ty soon).

Thanks.

-- 
Catalin


From catalin.marinas at arm.com  Fri Feb  9 09:33:41 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri,  9 Feb 2024 17:33:41 +0000
Subject: [PATCH v7 0/7] arm64: Reorganize kernel VA space
In-Reply-To: <20231213084024.2367360-9-ardb@google.com>
References: <20231213084024.2367360-9-ardb@google.com>
Message-ID: <170750001609.1210851.13991410964181221359.b4-ty@arm.com>

On Wed, 13 Dec 2023 09:40:25 +0100, Ard Biesheuvel wrote:
> These seven patches were taken from [0] and tweaked to address the
> feedback by Mark Rutland. They reconfigure the upper region of the
> kernel VA space so that the vmemmap region can be resized dynamically
> on 52-bit builds running on 48-bit-only hardware. This is needed for
> LPA2 support.
> 
> They can be applied onto the arm62 lpa2-prep branch.
> 
> [...]

Applied to arm64 (for-next/reorg-va-space), thanks!

[1/7] arm64: mm: Move PCI I/O emulation region above the vmemmap region
      https://git.kernel.org/arm64/c/031e011d8b22
[2/7] arm64: mm: Move fixmap region above vmemmap region
      https://git.kernel.org/arm64/c/b730b0f2b1fc
[3/7] arm64: ptdump: Allow all region boundaries to be defined at boot time
      https://git.kernel.org/arm64/c/34f879fbe461
[4/7] arm64: ptdump: Discover start of vmemmap region at runtime
      https://git.kernel.org/arm64/c/f9cca2444187
[5/7] arm64: vmemmap: Avoid base2 order of struct page size to dimension region
      https://git.kernel.org/arm64/c/32697ff38287
[6/7] arm64: mm: Reclaim unused vmemmap region for vmalloc use
      https://git.kernel.org/arm64/c/d432b8d57c0c
[7/7] arm64: kaslr: Adjust randomization range dynamically
      https://git.kernel.org/arm64/c/3567fa63cb56

-- 
Catalin



From conor at kernel.org  Fri Feb  9 09:34:01 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 9 Feb 2024 17:34:01 +0000
Subject: [PATCH v5 02/12] dt-bindings: mtd: brcmnand: Add WP pin
 connection property
In-Reply-To: <20240207202257.271784-3-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-3-william.zhang@broadcom.com>
Message-ID: <20240209-buffoon-cleat-e0dd67e0c5f7@spud>

On Wed, Feb 07, 2024 at 12:22:47PM -0800, William Zhang wrote:
> Add brcm,wp-not-connected property to have an option for disabling this
> feature on broadband board design that does not connect WP pin.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Thanks,
Conor.
-------------- 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/20240209/e94571d9/attachment.sig>

From nm at ti.com  Fri Feb  9 09:35:17 2024
From: nm at ti.com (Nishanth Menon)
Date: Fri, 9 Feb 2024 11:35:17 -0600
Subject: [RESEND PATCH v1 01/13] mfd: tps6594: Add register definitions
 for TI TPS65224 PMIC
In-Reply-To: <20240208105343.1212902-2-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
 <20240208105343.1212902-2-bhargav.r@ltts.com>
Message-ID: <20240209173517.i67qttasxjum7oek@strum>

On 16:23-20240208, Bhargav Raviprakash wrote:
> From: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
> 
> Extend TPS6594 PMIC register and field definitions to support TPS65224
> power management IC.
> 
> TPS65224 is software compatible to TPS6594 and can re-use many of the
> same definitions, new definitions are added to support additional
> controls available on TPS65224.
> 
> Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>

You've got to Sign-off as part of recommendations read [1]


[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst#n451
-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From catalin.marinas at arm.com  Fri Feb  9 09:38:13 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri,  9 Feb 2024 17:38:13 +0000
Subject: [PATCH v4 0/2] Rust enablement for AArch64
In-Reply-To: <20231020155056.3495121-1-Jamie.Cunliffe@arm.com>
References: <20231020155056.3495121-1-Jamie.Cunliffe@arm.com>
Message-ID: <170750002897.1210949.14507303616035197246.b4-ty@arm.com>

On Fri, 20 Oct 2023 16:50:54 +0100, Jamie Cunliffe wrote:
> Enable Rust support for the AArch64 architecture.
> 
> Since the v3 this has been refactored to split up the x86 Makefile
> changes. Updated the x86-64 conditionals as suggested by Boqun and
> addressed the formatting issues Miguel raised.
> 
> 
> [...]

Applied to arm64 (for-next/rust-for-arm64), thanks!

I also folded Rui's loongarch fix into the first patch to avoid breaking
this arch:

https://github.com/heiher/linux/commit/c504d83a6edd963e2ba58ec538e3f06da78b187e.patch

[1/2] rust: Refactor the build target to allow the use of builtin targets
      https://git.kernel.org/arm64/c/f82811e22b48
[2/2] arm64: rust: Enable Rust support for AArch64
      https://git.kernel.org/arm64/c/724a75ac9542

-- 
Catalin



From broonie at kernel.org  Fri Feb  9 09:40:06 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 9 Feb 2024 17:40:06 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <20240209171155.GB25069@willie-the-truck>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
 <CAD=FV=XupbtO3_+P9=XO26vH_5nALSSLZZHZywPSR_hQsWxM0Q@mail.gmail.com>
 <20240209171155.GB25069@willie-the-truck>
Message-ID: <ZcZjdnchVblj4iP+@finisterre.sirena.org.uk>

On Fri, Feb 09, 2024 at 05:11:55PM +0000, Will Deacon wrote:

> I can pick this up as a short-term hack if it solves the problem for you,
> but I also saw that you posted:

> https://lore.kernel.org/r/20240205092626.v2.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924 at changeid

> to fallback onto vmalloc() for large allocations.

> What's your preference for a fix?

We need the change kvzalloc() regardless since the ZA regset is just
over 64K which is on the big side, I do think that reducing the reported
regset size is useful as a fix independently since even with kvzalloc()
it's still pointless and rude to ask for such a big allocation and we
might reasonably be generating core files or dumping crashing processes
under memory pressure.

Dave was looking at sizing the regsets dynamically but there's enough
going on there that it's not great if people want to pick it up for
stable.
-------------- 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/20240209/f867db46/attachment.sig>

From broonie at kernel.org  Fri Feb  9 09:41:51 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 9 Feb 2024 17:41:51 +0000
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth``
 property
In-Reply-To: <20240209-chest-sleet-a119fc3d4243@spud>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
 <20240208135045.3728927-2-tudor.ambarus@linaro.org>
 <20240208-grating-legwarmer-0a04cfb04d61@spud>
 <c2b08463-cb13-4e9b-8797-8ebcf1047f66@linaro.org>
 <20240209-chest-sleet-a119fc3d4243@spud>
Message-ID: <ZcZj3/0xI6HqP8n8@finisterre.sirena.org.uk>

On Fri, Feb 09, 2024 at 04:21:16PM +0000, Conor Dooley wrote:
> On Fri, Feb 09, 2024 at 01:56:56PM +0000, Tudor Ambarus wrote:

> > At least I don't
> > see how it would work, I guess it will use the minimum depth between the
> > two?

> I'm not really sure how it would work other than that in the general
> case, but some use case specific configuration could work, but I do
> agree that it is

You do get devices that are single duplex only where the mismatched
sizes wouldn't be a pressing issue.
-------------- 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/20240209/0828bf3b/attachment.sig>

From conor at kernel.org  Fri Feb  9 09:42:00 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 9 Feb 2024 17:42:00 +0000
Subject: [PATCH v5 03/12] dt-bindings: mtd: brcmnand: Add ecc strap
 property
In-Reply-To: <20240207202257.271784-4-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-4-william.zhang@broadcom.com>
Message-ID: <20240209-jalapeno-estate-a1371c281bc7@spud>

On Wed, Feb 07, 2024 at 12:22:48PM -0800, William Zhang wrote:
> Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
> board boot strap for broadband board designs because they do not specify
> ecc setting in dts but rather using the strap setting.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>

If Miquel is happy with this, then I am too.
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> 
> ---
> 
> Changes in v5:
> - Update the description for this ecc strap property
> - Add check to make sure brcm,nand-ecc-use-strap and
>   nand-ecc-strength/brcm,nand-oob-sector-size can not be used at the
>   same time
> 
> Changes in v4:
> - Move ecc strap property to this separate patch and remove some
> non-binding related text from the description
> 
> Changes in v3: None
> Changes in v2: None
> 
>  .../bindings/mtd/brcm,brcmnand.yaml           | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> index 6a717bcedfd3..52a4c993b6f1 100644
> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> @@ -146,6 +146,13 @@ patternProperties:
>            layout.
>          $ref: /schemas/types.yaml#/definitions/uint32
>  
> +      brcm,nand-ecc-use-strap:
> +        description:
> +          This property requires the host system to get the ECC strength
> +          and step size from the SoC NAND boot strap setting. This is a
> +          common hardware design on BCMBCA based boards.
> +        $ref: /schemas/types.yaml#/definitions/flag
> +
>      unevaluatedProperties: false
>  
>  allOf:
> @@ -195,6 +202,18 @@ allOf:
>        required:
>          - interrupt-names
>  
> +  - if:
> +      patternProperties:
> +        "^nand@[a-f0-9]$":
> +          required:
> +            - brcm,nand-ecc-use-strap
> +    then:
> +      patternProperties:
> +        "^nand@[a-f0-9]$":
> +          properties:
> +            nand-ecc-strength: false
> +            brcm,nand-oob-sector-size: false
> +
>  unevaluatedProperties: false
>  
>  required:
> -- 
> 2.37.3
> 
-------------- 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/20240209/56fd0cf8/attachment-0001.sig>

From francesco at dolcini.it  Fri Feb  9 10:05:15 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Fri, 9 Feb 2024 19:05:15 +0100
Subject: [PATCH v1 6/9] arm64: dts: ti: k3-am6*: Remove DLL properties
 for soft PHYs
In-Reply-To: <20240207225526.3953230-7-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
 <20240207225526.3953230-7-jm@ti.com>
Message-ID: <20240209180515.GA29650@francesco-nb>

On Wed, Feb 07, 2024 at 04:55:23PM -0600, Judith Mendez wrote:
> Remove DLL properties which are not applicable for soft PHYs
> since these PHYs do not have a DLL to enable.
> 
> Signed-off-by: Judith Mendez <jm at ti.com>
> ---
>  arch/arm64/boot/dts/ti/k3-am62-main.dtsi       | 3 ---
>  arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 3 ---
>  arch/arm64/boot/dts/ti/k3-am62a-main.dtsi      | 1 -
>  arch/arm64/boot/dts/ti/k3-am62a7-sk.dts        | 1 -
>  arch/arm64/boot/dts/ti/k3-am62p5-sk.dts        | 1 -
>  arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 2 --
>  arch/arm64/boot/dts/ti/k3-am64-main.dtsi       | 1 -
>  arch/arm64/boot/dts/ti/k3-am642-evm.dts        | 1 -
>  arch/arm64/boot/dts/ti/k3-am642-sk.dts         | 1 -
>  9 files changed, 14 deletions(-)

you missed k3-am62-verdin-dev.dtsi and more ?

$ ack --dts -g k3-am6[24] | ack -x -l ti,driver-strength-ohm
arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi
arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
arch/arm64/boot/dts/ti/k3-am642-evm.dts
arch/arm64/boot/dts/ti/k3-am642-sk.dts
arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi

Francesco



From will at kernel.org  Fri Feb  9 10:31:06 2024
From: will at kernel.org (Will Deacon)
Date: Fri,  9 Feb 2024 18:31:06 +0000
Subject: [PATCH v2] arm64/signal: Don't assume that TIF_SVE means we saved SVE state
In-Reply-To: <20240130-arm64-sve-signal-regs-v2-1-9fc6f9502782@kernel.org>
References: <20240130-arm64-sve-signal-regs-v2-1-9fc6f9502782@kernel.org>
Message-ID: <170749646399.2626752.9932899949301214148.b4-ty@kernel.org>

On Tue, 30 Jan 2024 15:43:53 +0000, Mark Brown wrote:
> When we are in a syscall we will only save the FPSIMD subset even though
> the task still has access to the full register set, and on context switch
> we will only remove TIF_SVE when loading the register state. This means
> that the signal handling code should not assume that TIF_SVE means that
> the register state is stored in SVE format, it should instead check the
> format that was recorded during save.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64/signal: Don't assume that TIF_SVE means we saved SVE state
      https://git.kernel.org/arm64/c/61da7c8e2a60

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Fri Feb  9 10:31:07 2024
From: will at kernel.org (Will Deacon)
Date: Fri,  9 Feb 2024 18:31:07 +0000
Subject: [PATCH v3] perf: CXL: fix mismatched cpmu event opcode
In-Reply-To: <20240208013415epcms2p2904187c8a863f4d0d2adc980fb91a2dc@epcms2p2>
References: <CGME20240208013415epcms2p2904187c8a863f4d0d2adc980fb91a2dc@epcms2p2> <20240208013415epcms2p2904187c8a863f4d0d2adc980fb91a2dc@epcms2p2>
Message-ID: <170749755450.2629231.7963849540411447249.b4-ty@kernel.org>

On Thu, 08 Feb 2024 10:34:15 +0900, Hojin Nam wrote:
> S2M NDR BI-ConflictAck opcode is described as 4 in the CXL
> r3.0 3.3.9 Table 3.43. However, it is defined as 3 in macro definition.
> 
> 

Applied to arm64 (for-next/fixes), thanks!

[1/1] perf: CXL: fix mismatched cpmu event opcode
      https://git.kernel.org/arm64/c/719da04f2d12

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Fri Feb  9 10:31:08 2024
From: will at kernel.org (Will Deacon)
Date: Fri,  9 Feb 2024 18:31:08 +0000
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <20240206074552.541154-1-maskray@google.com>
References: <20240206074552.541154-1-maskray@google.com>
Message-ID: <170749826521.2630324.4507897270923627883.b4-ty@kernel.org>

On Mon, 5 Feb 2024 23:45:52 -0800, Fangrui Song wrote:
> The generic constraint "i" seems to be copied from x86 or arm (and with
> a redundant generic operand modifier "c"). It works with -fno-PIE but
> not with -fPIE/-fPIC in GCC's aarch64 port.
> 
> The machine constraint "S", which denotes a symbol or label reference
> with a constant offset, supports PIC and has been available in GCC since
> 2012 and in Clang since 7.0. However, Clang before 19 does not support
> "S" on a symbol with a constant offset [1] (e.g.
> `static_key_false(&nf_hooks_needed[pf][hook])` in
> include/linux/netfilter.h), so we use "i" as a fallback.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: jump_label: use constraints "Si" instead of "i"
      https://git.kernel.org/arm64/c/f9daab0ad01c

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Fri Feb  9 10:31:09 2024
From: will at kernel.org (Will Deacon)
Date: Fri,  9 Feb 2024 18:31:09 +0000
Subject: [PATCH] perf/arm-cmn: Improve debugfs pretty-printing for large configs
In-Reply-To: <1d1517eadd1bac5992fab679c9dc531b381944da.1702484646.git.robin.murphy@arm.com>
References: <1d1517eadd1bac5992fab679c9dc531b381944da.1702484646.git.robin.murphy@arm.com>
Message-ID: <170749440928.2624620.9250663526104348578.b4-ty@kernel.org>

On Wed, 13 Dec 2023 16:24:07 +0000, Robin Murphy wrote:
> The debugfs pretty-printer was written for the CMN-600 assumptions of a
> maximum 8x8 mesh, but CMN-700 now allows coordinates and ID values up to
> 12 and 128 respectively, which can overflow the format strings, mess up
> the alignment of the table and hurt overall readability. This table does
> prove useful for double-checking that the driver is picking up the
> topology of new systems correctly and for verifying user expectations,
> so tweak the formatting to stay nice and readable with wider values.
> 
> [...]

Applied to will (for-next/perf), thanks!

[1/1] perf/arm-cmn: Improve debugfs pretty-printing for large configs
      https://git.kernel.org/will/c/a1083ee717e9

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Fri Feb  9 10:31:10 2024
From: will at kernel.org (Will Deacon)
Date: Fri,  9 Feb 2024 18:31:10 +0000
Subject: [PATCH v2] perf/arm-cmn: Workaround AmpereOneX errata AC04_MESH_1 (incorrect child count)
In-Reply-To: <ce4b1442135fe03d0de41859b04b268c88c854a3.1707498577.git.robin.murphy@arm.com>
References: <ce4b1442135fe03d0de41859b04b268c88c854a3.1707498577.git.robin.murphy@arm.com>
Message-ID: <170749884475.2631468.4908638699561214515.b4-ty@kernel.org>

On Fri, 9 Feb 2024 17:11:09 +0000, Robin Murphy wrote:
> From: Ilkka Koskinen <ilkka at os.amperecomputing.com>
> 
> AmpereOneX mesh implementation has a bug in HN-P nodes that makes them
> report incorrect child count. The failing crosspoints report 8 children
> while they only have two.
> 
> When the driver tries to access the inexistent child nodes, it believes it
> has reached an invalid node type and probing fails. The workaround is to
> ignore those incorrect child nodes and continue normally.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] perf/arm-cmn: Workaround AmpereOneX errata AC04_MESH_1 (incorrect child count)
      https://git.kernel.org/arm64/c/50572064ec71

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Fri Feb  9 10:31:11 2024
From: will at kernel.org (Will Deacon)
Date: Fri,  9 Feb 2024 18:31:11 +0000
Subject: [PATCH v3 0/5] perf/arm_cspmu: Add devicetree support
In-Reply-To: <cover.1706718007.git.robin.murphy@arm.com>
References: <cover.1706718007.git.robin.murphy@arm.com>
Message-ID: <170750007716.86336.8541411340118542148.b4-ty@kernel.org>

On Tue, 6 Feb 2024 10:27:53 +0000, Robin Murphy wrote:
> v2: https://lore.kernel.org/linux-arm-kernel/cover.1702571292.git.robin.murphy at arm.com/
> 
> Hi all,
> 
> Third time lucky... here's a hopefully-final spin to address the
> functional issues Besar pointed out, and give a little final polish to
> the binding (although I stand firm on teh point of a trivial example
> not being valuable :))
> 
> [...]

Applied to will (for-next/perf), thanks!

[1/5] perf/arm_cspmu: Simplify initialisation
      https://git.kernel.org/will/c/df2675ad7748
[2/5] perf/arm_cspmu: Simplify attribute groups
      https://git.kernel.org/will/c/7e6a3c3f8588
[3/5] perf/arm_cspmu: Simplify counter reset
      https://git.kernel.org/will/c/e7e8fa8e82af
[4/5] dt-bindings/perf: Add Arm CoreSight PMU
      https://git.kernel.org/will/c/7255cfb19941
[5/5] perf/arm_cspmu: Add devicetree support
      https://git.kernel.org/will/c/fd185a245155

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Fri Feb  9 10:31:12 2024
From: will at kernel.org (Will Deacon)
Date: Fri,  9 Feb 2024 18:31:12 +0000
Subject: [PATCH] arm64: fix typo in comments
In-Reply-To: <20240202013306.883777-1-sgsu.park@samsung.com>
References: <CGME20240202013414epcas1p28ce117bb1e5e7f03b68365ec0d3a9c89@epcas1p2.samsung.com> <20240202013306.883777-1-sgsu.park@samsung.com>
Message-ID: <170749765403.2629762.3573310365008007219.b4-ty@kernel.org>

On Fri, 2 Feb 2024 10:33:06 +0900, Seongsu Park wrote:
> fix typo in comments
> 
> thath -> that
> 
> 

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: fix typo in comments
      https://git.kernel.org/arm64/c/c0b26c06ed00

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Fri Feb  9 10:31:13 2024
From: will at kernel.org (Will Deacon)
Date: Fri,  9 Feb 2024 18:31:13 +0000
Subject: [PATCH 00/18] perf: Convert to platform remove callback returning void
In-Reply-To: <cover.1702648124.git.u.kleine-koenig@pengutronix.de>
References: <cover.1702648124.git.u.kleine-koenig@pengutronix.de>
Message-ID: <170749437153.2624333.6691453190868131616.b4-ty@kernel.org>

On Fri, 15 Dec 2023 14:59:00 +0100, Uwe Kleine-K?nig wrote:
> this series converts all drivers below drivers/perf to use
> .remove_new(). See commit 5c5a7680e67b ("platform: Provide a remove
> callback that returns no value") for an extended explanation and the
> eventual goal. The TL;DR; is to make it harder for driver authors to
> leak resources without noticing.
> 
> I based the patches on today's next, I had to revert commits
> 3115ee021bfb ("arm64: perf: Include threshold control fields in
> PMEVTYPER mask") and 816c26754447 ("arm64: perf: Add support for event
> counting threshold") to compile test on ARCH=arm (this is a problem in
> next, not in my patch series).
> 
> [...]

Applied to will (for-next/perf), thanks!

[01/18] perf: alibaba_uncore_drw: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/3bc9d71775ee
[02/18] perf: amlogic: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/94843f269abd
[03/18] perf: arm-cci: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/4df3bddf8707
[04/18] perf: arm-ccn: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/0767f1a48532
[05/18] perf: arm-cmn: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/3909cb3b5f8d
[06/18] perf: arm_cspmu: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/79dc1570b322
[07/18] perf: arm_dmc620: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/ca1e01c8d34a
[08/18] perf: arm_dsu: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/02d77ac1ac7e
[09/18] perf: arm_smmuv3: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/d67c3a61f063
[10/18] perf: arm_spe: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/e63b3aef186b
[11/18] perf: fsl_imx8_ddr: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/1bb639382d3f
[12/18] perf: fsl_imx9_ddr: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/78da2a93b55b
[13/18] perf: hisilicon: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/e07486a832bb
[14/18] perf: marvell_cn10k_ddr: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/c802bd9e354f
[15/18] perf: marvell_cn10k_tad: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/86e8963f9dba
[16/18] perf: qcom_l2: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/8a2e438e710c
[17/18] perf: thunderx2: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/d4c5cef73b25
[18/18] perf: xgene: Convert to platform remove callback returning void
        https://git.kernel.org/will/c/b07ebe8f1428

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From erick.archer at gmx.com  Fri Feb  9 10:31:28 2024
From: erick.archer at gmx.com (Erick Archer)
Date: Fri,  9 Feb 2024 19:31:28 +0100
Subject: [PATCH] irqchip/irq-bcm7038-l1: Prefer struct_size over open coded arithmetic
Message-ID: <20240209183128.10273-1-erick.archer@gmx.com>

This is an effort to get rid of all multiplications from allocation
functions in order to prevent integer overflows [1].

As the cpu variable is a pointer to "struct bcm7038_l1_cpu" and this
structure ends in a flexible array:

struct bcm7038_l1_cpu {
	void __iomem	*map_base;
	u32		mask_cache[];
};

the preferred way in the kernel is to use the struct_size() helper to
do the arithmetic instead of the argument "size + count * size" in the
kzalloc() function.

This way, the code is more readable and more safer.

Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
Link: https://github.com/KSPP/linux/issues/162 [2]

Signed-off-by: Erick Archer <erick.archer at gmx.com>
---
 drivers/irqchip/irq-bcm7038-l1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
index 24ca1d656adc..36e71af054e9 100644
--- a/drivers/irqchip/irq-bcm7038-l1.c
+++ b/drivers/irqchip/irq-bcm7038-l1.c
@@ -249,7 +249,7 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
 		return -EINVAL;
 	}

-	cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32),
+	cpu = intc->cpus[idx] = kzalloc(struct_size(cpu, mask_cache, n_words),
 					GFP_KERNEL);
 	if (!cpu)
 		return -ENOMEM;
--
2.25.1



From will at kernel.org  Fri Feb  9 10:39:16 2024
From: will at kernel.org (Will Deacon)
Date: Fri,  9 Feb 2024 18:39:16 +0000
Subject: [PATCH] arm64: errata: Don't enable workarounds for "rare" errata by default
Message-ID: <20240209183916.25860-1-will@kernel.org>

Arm classifies some of its CPU errata as "rare", indicating that the
hardware error is unlikely to occur in practice. Given that the cost of
errata workarounds can often be significant in terms of power and
performance, don't enable workarounds for "rare" errata by default and
update our documentation to reflect that.

Cc: James Morse <james.morse at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Will Deacon <will at kernel.org>
---
 Documentation/arch/arm64/silicon-errata.rst |  5 +++--
 arch/arm64/Kconfig                          | 25 +++++++++------------
 2 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index e8c2ce1f9df6..fa16b895c997 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -35,8 +35,9 @@ can be triggered by Linux).
 For software workarounds that may adversely impact systems unaffected by
 the erratum in question, a Kconfig entry is added under "Kernel
 Features" -> "ARM errata workarounds via the alternatives framework".
-These are enabled by default and patched in at runtime when an affected
-CPU is detected. For less-intrusive workarounds, a Kconfig option is not
+With the exception of workarounds for errata deemed "rare" by Arm, these
+are enabled by default and patched in at runtime when an affected CPU is
+detected. For less-intrusive workarounds, a Kconfig option is not
 available and the code is structured (preferably with a comment) in such
 a way that the erratum will not be hit.
 
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aa7c1d435139..430fabf20f17 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -547,9 +547,8 @@ config ARM64_ERRATUM_832075
 	  If unsure, say Y.
 
 config ARM64_ERRATUM_834220
-	bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault"
+	bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault (rare)"
 	depends on KVM
-	default y
 	help
 	  This option adds an alternative code sequence to work around ARM
 	  erratum 834220 on Cortex-A57 parts up to r1p2.
@@ -565,7 +564,7 @@ config ARM64_ERRATUM_834220
 	  as it depends on the alternative framework, which will only patch
 	  the kernel if an affected CPU is detected.
 
-	  If unsure, say Y.
+	  If unsure, say N.
 
 config ARM64_ERRATUM_1742098
 	bool "Cortex-A57/A72: 1742098: ELR recorded incorrectly on interrupt taken between cryptographic instructions in a sequence"
@@ -692,8 +691,7 @@ config ARM64_WORKAROUND_REPEAT_TLBI
 	bool
 
 config ARM64_ERRATUM_2441007
-	bool "Cortex-A55: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"
-	default y
+	bool "Cortex-A55: Completion of affected memory accesses might not be guaranteed by completion of a TLBI (rare)"
 	select ARM64_WORKAROUND_REPEAT_TLBI
 	help
 	  This option adds a workaround for ARM Cortex-A55 erratum #2441007.
@@ -706,11 +704,10 @@ config ARM64_ERRATUM_2441007
 	  Work around this by adding the affected CPUs to the list that needs
 	  TLB sequences to be done twice.
 
-	  If unsure, say Y.
+	  If unsure, say N.
 
 config ARM64_ERRATUM_1286807
-	bool "Cortex-A76: Modification of the translation table for a virtual address might lead to read-after-read ordering violation"
-	default y
+	bool "Cortex-A76: Modification of the translation table for a virtual address might lead to read-after-read ordering violation (rare)"
 	select ARM64_WORKAROUND_REPEAT_TLBI
 	help
 	  This option adds a workaround for ARM Cortex-A76 erratum 1286807.
@@ -724,6 +721,8 @@ config ARM64_ERRATUM_1286807
 	  invalidated has been observed by other observers. The
 	  workaround repeats the TLBI+DSB operation.
 
+	  If unsure, say N.
+
 config ARM64_ERRATUM_1463225
 	bool "Cortex-A76: Software Step might prevent interrupt recognition"
 	default y
@@ -743,8 +742,7 @@ config ARM64_ERRATUM_1463225
 	  If unsure, say Y.
 
 config ARM64_ERRATUM_1542419
-	bool "Neoverse-N1: workaround mis-ordering of instruction fetches"
-	default y
+	bool "Neoverse-N1: workaround mis-ordering of instruction fetches (rare)"
 	help
 	  This option adds a workaround for ARM Neoverse-N1 erratum
 	  1542419.
@@ -756,7 +754,7 @@ config ARM64_ERRATUM_1542419
 	  Workaround the issue by hiding the DIC feature from EL0. This
 	  forces user-space to perform cache maintenance.
 
-	  If unsure, say Y.
+	  If unsure, say N.
 
 config ARM64_ERRATUM_1508412
 	bool "Cortex-A77: 1508412: workaround deadlock on sequence of NC/Device load and store exclusive or PAR read"
@@ -931,8 +929,7 @@ config ARM64_ERRATUM_2224489
 	  If unsure, say Y.
 
 config ARM64_ERRATUM_2441009
-	bool "Cortex-A510: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"
-	default y
+	bool "Cortex-A510: Completion of affected memory accesses might not be guaranteed by completion of a TLBI (rare)"
 	select ARM64_WORKAROUND_REPEAT_TLBI
 	help
 	  This option adds a workaround for ARM Cortex-A510 erratum #2441009.
@@ -945,7 +942,7 @@ config ARM64_ERRATUM_2441009
 	  Work around this by adding the affected CPUs to the list that needs
 	  TLB sequences to be done twice.
 
-	  If unsure, say Y.
+	  If unsure, say N.
 
 config ARM64_ERRATUM_2064142
 	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
-- 
2.43.0.687.g38aa6559b0-goog



From gustavo at embeddedor.com  Fri Feb  9 10:40:36 2024
From: gustavo at embeddedor.com (Gustavo A. R. Silva)
Date: Fri, 9 Feb 2024 12:40:36 -0600
Subject: [PATCH] irqchip/irq-bcm7038-l1: Prefer struct_size over open
 coded arithmetic
In-Reply-To: <20240209183128.10273-1-erick.archer@gmx.com>
References: <20240209183128.10273-1-erick.archer@gmx.com>
Message-ID: <b7cd5217-e7dc-4b57-aab2-bef1b78dca7d@embeddedor.com>



On 2/9/24 12:31, Erick Archer wrote:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> As the cpu variable is a pointer to "struct bcm7038_l1_cpu" and this
> structure ends in a flexible array:
> 
> struct bcm7038_l1_cpu {
> 	void __iomem	*map_base;
> 	u32		mask_cache[];
> };
> 
> the preferred way in the kernel is to use the struct_size() helper to
> do the arithmetic instead of the argument "size + count * size" in the
> kzalloc() function.
> 
> This way, the code is more readable and more safer.
> 
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
> Link: https://github.com/KSPP/linux/issues/162 [2]
> 
> Signed-off-by: Erick Archer <erick.archer at gmx.com>

LGTM:

Reviewed-by: Gustavo A. R. Silva <gustavoars at kernel.org>

Thanks
-- 
Gustavo

> ---
>   drivers/irqchip/irq-bcm7038-l1.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
> index 24ca1d656adc..36e71af054e9 100644
> --- a/drivers/irqchip/irq-bcm7038-l1.c
> +++ b/drivers/irqchip/irq-bcm7038-l1.c
> @@ -249,7 +249,7 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
>   		return -EINVAL;
>   	}
> 
> -	cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32),
> +	cpu = intc->cpus[idx] = kzalloc(struct_size(cpu, mask_cache, n_words),
>   					GFP_KERNEL);
>   	if (!cpu)
>   		return -ENOMEM;
> --
> 2.25.1
> 


From pr-tracker-bot at kernel.org  Fri Feb  9 10:46:19 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 09 Feb 2024 18:46:19 +0000
Subject: [GIT PULL] pmdomain fixes for v6.8-rc4
In-Reply-To: <20240209123818.768037-1-ulf.hansson@linaro.org>
References: <20240209123818.768037-1-ulf.hansson@linaro.org>
Message-ID: <170750437919.872.9474856253417247586.pr-tracker-bot@kernel.org>

The pull request you sent on Fri,  9 Feb 2024 13:38:18 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git tags/pmdomain-v6.8-rc1

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/3760081ff414c4fec37396499f5b298464583b03

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From kamlesh at ti.com  Fri Feb  9 10:55:45 2024
From: kamlesh at ti.com (Kamlesh Gurudasani)
Date: Sat, 10 Feb 2024 00:25:45 +0530
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240209172555.fxlxijhhbgrkyibo@agreeing>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
 <20240207125410.r2q3jcplvif7dvt2@tumbling>
 <3a7c4a18-5463-414f-82df-39aaed861148@ti.com>
 <20240209172555.fxlxijhhbgrkyibo@agreeing>
Message-ID: <87y1btlb66.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>

Nishanth Menon <nm at ti.com> writes:

> On 19:53-20240207, Kumar, Udit wrote:
>> Hi?Nishanth,
>> 
>> On 2/7/2024 6:24 PM, Nishanth Menon wrote:
>> > On 14:41-20240207, Udit Kumar wrote:
>> > > Most of clocks and their parents are defined in contiguous range,
>> > > But in few cases, there is gap in clock numbers[0].
>> > > Driver assumes clocks to be in contiguous range, and add their clock
>> > > ids incrementally.
>> > > 
>> > > New firmware started returning error while calling get_freq and is_on
>> > > API for non-available clock ids.
>> > > 
>> > > In this fix, driver checks and adds only valid clock ids.
>> > > 
>> > > Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
>> > > 
>> > > [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
>> > > Section Clocks for NAVSS0_CPTS_0 Device,
>> > > clock id 12-15 not present.
>> > > 
>> > > Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
>> > > ---
>> > > Changelog
>> > > Changes in v3
>> > > - instead of get_freq, is_auto API is used to check validilty of clock
>> > > - Address comments of v2, to have preindex increment
>> > > Link to v2 https://lore.kernel.org/all/20240206104357.3803517-1-u-kumar1 at ti.com/
>> > > 
>> > > Changes in v2
>> > > - Updated commit message
>> > > - Simplified logic for valid clock id
>> > > link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/
>> > > 
>> > > 
>> > > P.S
>> > > Firmawre returns total num_parents count including non available ids.
>> > > For above device id NAVSS0_CPTS_0, number of parents clocks are 16
>> > > i.e from id 2 to 17. But out of these ids few are not valid.
>> > > So driver adds only valid clock ids out ot total.
>> > > 
>> > > Original logs
>> > > https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
>> > > Line 2630 for error
>> > > 
>> > > Logs with fix v3
>> > > https://gist.github.com/uditkumarti/94e3e28d62282fd708dbfe37435ce1d9#file-v3
>> > > Line 2586
>> > > 
>> > > 
>> > >   drivers/clk/keystone/sci-clk.c | 12 ++++++++++--
>> > >   1 file changed, 10 insertions(+), 2 deletions(-)
>> > > 
>> > > diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
>> > > index 35fe197dd303..31b7df05d7bb 100644
>> > > --- a/drivers/clk/keystone/sci-clk.c
>> > > +++ b/drivers/clk/keystone/sci-clk.c
>> > > @@ -516,6 +516,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>> > >   	struct sci_clk *sci_clk, *prev;
>> > >   	int num_clks = 0;
>> > >   	int num_parents;
>> > > [..]					/* Check if this clock id is valid */
>> > > +					ret = provider->ops->is_auto(provider->sci,
>> > > +						sci_clk->dev_id, ++clk_id, &state);
>> > A bit too nice coding ;) => I had been confused momentarily by clk_id = args.args[1]
>> > change just above till I saw that you are pre-incrementing
>> > clk_id - Is there a harm in leaving the original clk_id increment logic
>> > alone (it was much simpler to read up)?
>> 
>> No warm in using original code but want to avoid, two statement for
>> increment in case of failure and success.
>> 
>> Let me know, if i need to add few comments around this
>> 
>> or if you think, code is confusing I can move to original one
>
> Yes, please drop the un-necessary changes. In this case, original
> increment code should work just fine.
I wouldn't call it unnecessary, If I have to track increment/addition at
3 different places just to understand the loop, it is hard. On other
hand, pre-increment code is solving the problem by having increment at
only one place(easier to track). On the plus side, every clk_id belonging to
parent is handled completely inside the loop.

For a new person looking at this code, pre-increment code would be
actually easier to undertsand.

Also, Udit feels the same.

Would you please explain why do you think the original increment code
make more sense? It's not simple to understand or track, that's for sure.

Kamlesh
>\
> -- 
> Regards,
> Nishanth Menon
> Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From eahariha at linux.microsoft.com  Fri Feb  9 10:58:36 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Fri, 9 Feb 2024 10:58:36 -0800
Subject: [RFC PATCH] KVM: arm64: Override Microsoft Azure Cobalt 100 MIDR
 value with ARM Neoverse N2
In-Reply-To: <ZcYNn5LDmH1g2dDB@FVFF77S0Q05N.cambridge.arm.com>
References: <20240206195819.1146693-1-eahariha@linux.microsoft.com>
 <ZcNSI089xqia6lho@FVFF77S0Q05N.cambridge.arm.com>
 <ed6c25dc-d5c7-4f15-8fdc-f2adf209e638@linux.microsoft.com>
 <ZcYNn5LDmH1g2dDB@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <542e7f15-3898-4396-a8ff-7972d3308132@linux.microsoft.com>

On 2/9/2024 3:33 AM, Mark Rutland wrote:
> On Thu, Feb 08, 2024 at 11:16:10AM -0800, Easwar Hariharan wrote:
>> On 2/7/2024 1:49 AM, Mark Rutland wrote:
>>> On Tue, Feb 06, 2024 at 07:58:16PM +0000, Easwar Hariharan wrote:
>>> Further, if Azure Cobalt 100 is based on ARM Neoverse N2, you presumably suffer
>>> from the same errata; can you comment on that at all? e.g. are there any
>>> changes in this part that *might* lead to differences in errata and/or
>>> workarounds? How do the MIDR_EL1.{Variant,Revision} values compare to that of
>>> Neoverse N2?
>>
>> Yes, Azure Cobalt 100 suffers from the same errata as Neoverse N2. We had changes
>> in the implementation, but according to our hardware folks, the Neoverse N2 errata
>> we are affected by so far aren't affected by the changes made for Azure Cobalt 100.
> 
> Ok, so of the currently-known-and-mitigated errata, you'll be affected by:
> 
> 	ARM64_ERRATUM_2139208
> 	ARM64_ERRATUM_2067961
> 	ARM64_ERRATUM_2253138
> 
> ... and we'll need to extend the midr_range lists for those errata to cover
> Azure Cobalt 100.
> 
>>From your patch, it looks like the Azure Cobalt 100 MIDR value (0x6D0FD490) is
> the same as the Arm Neoverse-N2 r0p0 MIDR value (0x410FD490), except the
> 'Implementer' field is 0x6D ('m' in ASCII) rather than 0x41 ('A' in ASCII).
> 
> Are you happy to send a patch extending arch/arm64/include/asm/cputype.h with
> the relevant ARM_CPU_IMP_* and CPU_PART_* definitions, and use those to extend
> the midr_range lists for those errata?

Yes.

> 
> As above, if you could make any comment on how the MIDR_EL1.{Variant,Revision}
> fields map to that of Arm Neoverse-N2, it would be very helpful. It's not clear
> to me whether those fields correspond directly (and so this part is based on
> r0p0), or whether you have a different scheme for revision numbers. That'll
> matter for correctly matching any future errata and/or future revisions of
> Azure Cobalt 100.
> 

Thanks for the clarifying detail on your question. Azure Cobalt 100 is indeed based
on r0p0 of the Neoverse N-2 and we have not used a different scheme than Neoverse N2
for the Variant and Revision fields.


> Mark.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From nm at ti.com  Fri Feb  9 11:02:27 2024
From: nm at ti.com (Nishanth Menon)
Date: Fri, 9 Feb 2024 13:02:27 -0600
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <87y1btlb66.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
 <20240207125410.r2q3jcplvif7dvt2@tumbling>
 <3a7c4a18-5463-414f-82df-39aaed861148@ti.com>
 <20240209172555.fxlxijhhbgrkyibo@agreeing>
 <87y1btlb66.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
Message-ID: <20240209190227.lboi6n5s2oy7kxgc@pristine>

On 00:25-20240210, Kamlesh Gurudasani wrote:
> >> > > 
> >> > > diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> >> > > index 35fe197dd303..31b7df05d7bb 100644
> >> > > --- a/drivers/clk/keystone/sci-clk.c
> >> > > +++ b/drivers/clk/keystone/sci-clk.c
> >> > > @@ -516,6 +516,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
> >> > >   	struct sci_clk *sci_clk, *prev;
> >> > >   	int num_clks = 0;
> >> > >   	int num_parents;
> >> > > [..]					/* Check if this clock id is valid */
> >> > > +					ret = provider->ops->is_auto(provider->sci,
> >> > > +						sci_clk->dev_id, ++clk_id, &state);
> >> > A bit too nice coding ;) => I had been confused momentarily by clk_id = args.args[1]
> >> > change just above till I saw that you are pre-incrementing
> >> > clk_id - Is there a harm in leaving the original clk_id increment logic
> >> > alone (it was much simpler to read up)?
> >> 
> >> No warm in using original code but want to avoid, two statement for
> >> increment in case of failure and success.
> >> 
> >> Let me know, if i need to add few comments around this
> >> 
> >> or if you think, code is confusing I can move to original one
> >
> > Yes, please drop the un-necessary changes. In this case, original
> > increment code should work just fine.
> I wouldn't call it unnecessary, If I have to track increment/addition at
> 3 different places just to understand the loop, it is hard. On other
> hand, pre-increment code is solving the problem by having increment at
> only one place(easier to track). On the plus side, every clk_id belonging to
> parent is handled completely inside the loop.
> 
> For a new person looking at this code, pre-increment code would be
> actually easier to undertsand.
> 
> Also, Udit feels the same.
> 
> Would you please explain why do you think the original increment code
> make more sense? It's not simple to understand or track, that's for sure.

the context of the fix is the is_auto call to know what parent options
are valid or not. Do the absolutely what is necessary in the change. if
you want to beautify etc, move it to some other patch and debate about
it. So, this is un-necessary change in this patch.

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From bot at kernelci.org  Fri Feb  9 11:09:00 2024
From: bot at kernelci.org (kernelci.org bot)
Date: Fri, 09 Feb 2024 11:09:00 -0800 (PST)
Subject: arm64/for-kernelci build: 1 build: 0 failed, 1 passed,
 1 warning (v6.8-rc3-10-gf735966ee23c)
Message-ID: <65c6784c.170a0220.f2839.6762@mx.google.com>

arm64/for-kernelci build: 1 build: 0 failed, 1 passed, 1 warning (v6.8-rc3-10-gf735966ee23c)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v6.8-rc3-10-gf735966ee23c/

Tree: arm64
Branch: for-kernelci
Git Describe: v6.8-rc3-10-gf735966ee23c
Git Commit: f735966ee23ca0016261da96c9d10747c8238177
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

Warnings Detected:

arm64:
    defconfig (gcc-10): 1 warning


Warnings summary:

    1    security/security.c:810:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
defconfig (arm64, gcc-10) ? PASS, 0 errors, 1 warning, 0 section mismatches

Warnings:
    security/security.c:810:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

---
For more info write to <info at kernelci.org>


From mhklinux at outlook.com  Fri Feb  9 11:37:19 2024
From: mhklinux at outlook.com (Michael Kelley)
Date: Fri, 9 Feb 2024 19:37:19 +0000
Subject: [PATCH v3 7/7] dma-mapping: Simplify arch_setup_dma_ops()
In-Reply-To: <f0ea76846c89a65dfe42933d78d770004bb3de01.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
 <f0ea76846c89a65dfe42933d78d770004bb3de01.1707493264.git.robin.murphy@arm.com>
Message-ID: <SN6PR02MB4157B73801B450853E04369BD44B2@SN6PR02MB4157.namprd02.prod.outlook.com>

From: Robin Murphy <robin.murphy at arm.com> Sent: Friday, February 9, 2024 8:50 AM
> 
> The dma_base, size and iommu arguments are only used by ARM, and can
> now easily be deduced from the device itself, so there's no need to pass
> them through the callchain as well.
> 
> Acked-by: Rob Herring <robh at kernel.org>
> Reviewed-by: Christoph Hellwig <hch at lst.de>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
> v2: Make sure the ARM changes actually build (oops...)
> ---
>  arch/arc/mm/dma.c               |  3 +--
>  arch/arm/mm/dma-mapping-nommu.c |  3 +--
>  arch/arm/mm/dma-mapping.c       | 16 +++++++++-------
>  arch/arm64/mm/dma-mapping.c     |  3 +--
>  arch/mips/mm/dma-noncoherent.c  |  3 +--
>  arch/riscv/mm/dma-noncoherent.c |  3 +--
>  drivers/acpi/scan.c             |  7 +------
>  drivers/hv/hv_common.c          |  6 +-----
>  drivers/of/device.c             |  4 +---
>  include/linux/dma-map-ops.h     |  6 ++----
>  10 files changed, 19 insertions(+), 35 deletions(-)
> 

For the Hyper-V related change in drivers/hv/hv_common.c,

Reviewed-by: Michael Kelley <mhklinux at outlook.com>

> diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
> index 197707bc7658..6b85e94f3275 100644
> --- a/arch/arc/mm/dma.c
> +++ b/arch/arc/mm/dma.c
> @@ -90,8 +90,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t
> size,
>  /*
>   * Plug in direct dma map ops.
>   */
> -void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			bool coherent)
> +void arch_setup_dma_ops(struct device *dev, bool coherent)
>  {
>  	/*
>  	 * IOC hardware snoops all DMA traffic keeping the caches consistent
> diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-
> mapping-nommu.c
> index b94850b57995..97db5397c320 100644
> --- a/arch/arm/mm/dma-mapping-nommu.c
> +++ b/arch/arm/mm/dma-mapping-nommu.c
> @@ -33,8 +33,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t
> size,
>  	}
>  }
> 
> -void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			bool coherent)
> +void arch_setup_dma_ops(struct device *dev, bool coherent)
>  {
>  	if (IS_ENABLED(CONFIG_CPU_V7M)) {
>  		/*
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index f68db05eba29..5adf1769eee4 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1709,11 +1709,15 @@ void arm_iommu_detach_device(struct device
> *dev)
>  }
>  EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
> 
> -static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base,
> u64 size,
> -				    bool coherent)
> +static void arm_setup_iommu_dma_ops(struct device *dev)
>  {
>  	struct dma_iommu_mapping *mapping;
> +	u64 dma_base = 0, size = 1ULL << 32;
> 
> +	if (dev->dma_range_map) {
> +		dma_base = dma_range_map_min(dev->dma_range_map);
> +		size = dma_range_map_max(dev->dma_range_map) -
> dma_base;
> +	}
>  	mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
>  	if (IS_ERR(mapping)) {
>  		pr_warn("Failed to create %llu-byte IOMMU mapping for
> device %s\n",
> @@ -1744,8 +1748,7 @@ static void
> arm_teardown_iommu_dma_ops(struct device *dev)
> 
>  #else
> 
> -static void arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base,
> u64 size,
> -				    bool coherent)
> +static void arm_setup_iommu_dma_ops(struct device *dev)
>  {
>  }
> 
> @@ -1753,8 +1756,7 @@ static void
> arm_teardown_iommu_dma_ops(struct device *dev) { }
> 
>  #endif	/* CONFIG_ARM_DMA_USE_IOMMU */
> 
> -void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			bool coherent)
> +void arch_setup_dma_ops(struct device *dev, bool coherent)
>  {
>  	/*
>  	 * Due to legacy code that sets the ->dma_coherent flag from a bus
> @@ -1774,7 +1776,7 @@ void arch_setup_dma_ops(struct device *dev, u64
> dma_base, u64 size,
>  		return;
> 
>  	if (device_iommu_mapped(dev))
> -		arm_setup_iommu_dma_ops(dev, dma_base, size, coherent);
> +		arm_setup_iommu_dma_ops(dev);
> 
>  	xen_setup_dma_ops(dev);
>  	dev->archdata.dma_ops_setup = true;
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-
> mapping.c
> index 313d8938a2f0..0b320a25a471 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -46,8 +46,7 @@ void arch_teardown_dma_ops(struct device *dev)
>  }
>  #endif
> 
> -void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			bool coherent)
> +void arch_setup_dma_ops(struct device *dev, bool coherent)
>  {
>  	int cls = cache_line_size_of_cpu();
> 
> diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-
> noncoherent.c
> index 0f3cec663a12..ab4f2a75a7d0 100644
> --- a/arch/mips/mm/dma-noncoherent.c
> +++ b/arch/mips/mm/dma-noncoherent.c
> @@ -137,8 +137,7 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr,
> size_t size,
>  #endif
> 
>  #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
> -void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		bool coherent)
> +void arch_setup_dma_ops(struct device *dev, bool coherent)
>  {
>  	dev->dma_coherent = coherent;
>  }
> diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-
> noncoherent.c
> index 843107f834b2..cb89d7e0ba88 100644
> --- a/arch/riscv/mm/dma-noncoherent.c
> +++ b/arch/riscv/mm/dma-noncoherent.c
> @@ -128,8 +128,7 @@ void arch_dma_prep_coherent(struct page *page,
> size_t size)
>  	ALT_CMO_OP(FLUSH, flush_addr, size, riscv_cbom_block_size);
>  }
> 
> -void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -			bool coherent)
> +void arch_setup_dma_ops(struct device *dev, bool coherent)
>  {
>  	WARN_TAINT(!coherent && riscv_cbom_block_size >
> ARCH_DMA_MINALIGN,
>  		   TAINT_CPU_OUT_OF_SPEC,
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index e6ed1ba91e5c..f5df17d11717 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1640,12 +1640,7 @@ int acpi_dma_configure_id(struct device *dev,
> enum dev_dma_attr attr,
>  	if (ret == -EPROBE_DEFER)
>  		return -EPROBE_DEFER;
> 
> -	/*
> -	 * Historically this routine doesn't fail driver probing due to errors
> -	 * in acpi_iommu_configure_id()
> -	 */
> -
> -	arch_setup_dma_ops(dev, 0, U64_MAX, attr ==
> DEV_DMA_COHERENT);
> +	arch_setup_dma_ops(dev, attr == DEV_DMA_COHERENT);
> 
>  	return 0;
>  }
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index 0285a74363b3..0e2decd1167a 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -484,11 +484,7 @@ EXPORT_SYMBOL_GPL(hv_query_ext_cap);
> 
>  void hv_setup_dma_ops(struct device *dev, bool coherent)
>  {
> -	/*
> -	 * Hyper-V does not offer a vIOMMU in the guest
> -	 * VM, so pass 0/NULL for the IOMMU settings
> -	 */
> -	arch_setup_dma_ops(dev, 0, 0, coherent);
> +	arch_setup_dma_ops(dev, coherent);
>  }
>  EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
> 
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 9e7963972fa7..312c63361211 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -95,7 +95,6 @@ int of_dma_configure_id(struct device *dev, struct
> device_node *np,
>  {
>  	const struct bus_dma_region *map = NULL;
>  	struct device_node *bus_np;
> -	u64 dma_start = 0;
>  	u64 mask, end = 0;
>  	bool coherent;
>  	int iommu_ret;
> @@ -118,7 +117,6 @@ int of_dma_configure_id(struct device *dev, struct
> device_node *np,
>  			return ret == -ENODEV ? 0 : ret;
>  	} else {
>  		/* Determine the overall bounds of all DMA regions */
> -		dma_start = dma_range_map_min(map);
>  		end = dma_range_map_max(map);
>  	}
> 
> @@ -175,7 +173,7 @@ int of_dma_configure_id(struct device *dev, struct
> device_node *np,
>  	} else
>  		dev_dbg(dev, "device is behind an iommu\n");
> 
> -	arch_setup_dma_ops(dev, dma_start, end - dma_start + 1, coherent);
> +	arch_setup_dma_ops(dev, coherent);
> 
>  	if (iommu_ret)
>  		of_dma_set_restricted_buffer(dev, np);
> diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
> index 4abc60f04209..ed89e1ce0114 100644
> --- a/include/linux/dma-map-ops.h
> +++ b/include/linux/dma-map-ops.h
> @@ -426,11 +426,9 @@ bool arch_dma_unmap_sg_direct(struct device
> *dev, struct scatterlist *sg,
>  #endif
> 
>  #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
> -void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> -		bool coherent);
> +void arch_setup_dma_ops(struct device *dev, bool coherent);
>  #else
> -static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
> -		u64 size, bool coherent)
> +static inline void arch_setup_dma_ops(struct device *dev, bool coherent)
>  {
>  }
>  #endif /* CONFIG_ARCH_HAS_SETUP_DMA_OPS */
> --
> 2.39.2.101.g768bb238c484.dirty
> 



From bot at kernelci.org  Fri Feb  9 11:52:19 2024
From: bot at kernelci.org (kernelci.org bot)
Date: Fri, 09 Feb 2024 11:52:19 -0800 (PST)
Subject: arm64/for-kernelci baseline: 44 runs,
 7 regressions (v6.8-rc3-10-gf735966ee23c)
Message-ID: <65c68273.170a0220.a4679.6f3b@mx.google.com>

arm64/for-kernelci baseline: 44 runs, 7 regressions (v6.8-rc3-10-gf735966ee23c)

Regressions Summary
-------------------

platform               | arch  | lab         | compiler | defconfig | regressions
-----------------------+-------+-------------+----------+-----------+------------
kontron-kbox-a-230-ls  | arm64 | lab-kontron | gcc-10   | defconfig | 5          
kontron-sl28-var3-ads2 | arm64 | lab-kontron | gcc-10   | defconfig | 2          

  Details:  https://kernelci.org/test/job/arm64/branch/for-kernelci/kernel/v6.8-rc3-10-gf735966ee23c/plan/baseline/

  Test:     baseline
  Tree:     arm64
  Branch:   for-kernelci
  Describe: v6.8-rc3-10-gf735966ee23c
  URL:      https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
  SHA:      f735966ee23ca0016261da96c9d10747c8238177 


Test Regressions
---------------- 


platform               | arch  | lab         | compiler | defconfig | regressions
-----------------------+-------+-------------+----------+-----------+------------
kontron-kbox-a-230-ls  | arm64 | lab-kontron | gcc-10   | defconfig | 5          

  Details:     https://kernelci.org/test/plan/id/65c678478934dc68828e1e88

  Results:     90 PASS, 5 FAIL, 1 SKIP
  Full config: defconfig
  Compiler:    gcc-10 (aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc3-10-gf735966ee23c/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-kbox-a-230-ls.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc3-10-gf735966ee23c/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-kbox-a-230-ls.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230623.0/arm64/rootfs.cpio.gz 


  * baseline.bootrr.deferred-probe-empty: https://kernelci.org/test/case/id/65c678478934dc68828e1e8b
        failing since 10 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-09T19:08:26.037120  
    2024-02-09T19:08:26.138433  / # #export SHELL=/bin/sh
    2024-02-09T19:08:26.138966  
    2024-02-09T19:08:26.239954  / # export SHELL=/bin/sh. /lava-427932/environment
    2024-02-09T19:08:26.240551  
    2024-02-09T19:08:26.341580  / # . /lava-427932/environment/lava-427932/bin/lava-test-runner /lava-427932/1
    2024-02-09T19:08:26.342666  
    2024-02-09T19:08:26.348637  / # /lava-427932/bin/lava-test-runner /lava-427932/1
    2024-02-09T19:08:26.412590  + export 'TESTRUN_ID=1_bootrr'
    2024-02-09T19:08:26.446493  + cd /lava-427932/1/tests/1_bootrr 
    ... (14 line(s) more)  

  * baseline.bootrr.fsl_enetc-enetc2-probed: https://kernelci.org/test/case/id/65c678478934dc68828e1e8f
        failing since 10 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-09T19:08:28.662635  /lava-427932/1/../bin/lava-test-case
    2024-02-09T19:08:28.690377  <8>[   26.087205] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc2-probed RESULT=fail>   

  * baseline.bootrr.mscc_felix-probed: https://kernelci.org/test/case/id/65c678478934dc68828e1e91
        failing since 10 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-09T19:08:29.751762  /lava-427932/1/../bin/lava-test-case
    2024-02-09T19:08:29.778942  <8>[   27.174780] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=mscc_felix-probed RESULT=fail>   

  * baseline.bootrr.fsl_enetc-enetc0-probed: https://kernelci.org/test/case/id/65c678478934dc68828e1e96
        failing since 10 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-09T19:08:31.011271  /lava-427932/1/../bin/lava-test-case
    2024-02-09T19:08:31.038235  <8>[   28.434793] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc0-probed RESULT=fail>   

  * baseline.bootrr.fsl_enetc-enetc1-probed: https://kernelci.org/test/case/id/65c678478934dc68828e1e97
        failing since 10 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-09T19:08:32.061907  /lava-427932/1/../bin/lava-test-case
    2024-02-09T19:08:32.087854  <8>[   29.485124] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc1-probed RESULT=fail>   
 


platform               | arch  | lab         | compiler | defconfig | regressions
-----------------------+-------+-------------+----------+-----------+------------
kontron-sl28-var3-ads2 | arm64 | lab-kontron | gcc-10   | defconfig | 2          

  Details:     https://kernelci.org/test/plan/id/65c67859b1c25e91388e1e7b

  Results:     101 PASS, 2 FAIL, 1 SKIP
  Full config: defconfig
  Compiler:    gcc-10 (aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc3-10-gf735966ee23c/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-sl28-var3-ads2.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc3-10-gf735966ee23c/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-sl28-var3-ads2.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230623.0/arm64/rootfs.cpio.gz 


  * baseline.bootrr.deferred-probe-empty: https://kernelci.org/test/case/id/65c67859b1c25e91388e1e7e
        failing since 10 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-09T19:08:54.279322  / # #
    2024-02-09T19:08:54.381582  export SHELL=/bin/sh
    2024-02-09T19:08:54.382386  #
    2024-02-09T19:08:54.483962  / # export SHELL=/bin/sh. /lava-427933/environment
    2024-02-09T19:08:54.484721  
    2024-02-09T19:08:54.586116  / # . /lava-427933/environment/lava-427933/bin/lava-test-runner /lava-427933/1
    2024-02-09T19:08:54.587370  
    2024-02-09T19:08:54.605988  / # /lava-427933/bin/lava-test-runner /lava-427933/1
    2024-02-09T19:08:54.693900  + export 'TESTRUN_ID=1_bootrr'
    2024-02-09T19:08:54.694357  + cd /lava-427933/1/tests/1_bootrr 
    ... (10 line(s) more)  

  * baseline.bootrr.fsl_enetc-enetc0-probed: https://kernelci.org/test/case/id/65c67859b1c25e91388e1e91
        failing since 10 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-09T19:08:57.622422  /lava-427933/1/../bin/lava-test-case
    2024-02-09T19:08:57.651676  <8>[   27.052823] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc0-probed RESULT=fail>   
  


From kamlesh at ti.com  Fri Feb  9 12:01:09 2024
From: kamlesh at ti.com (Kamlesh Gurudasani)
Date: Sat, 10 Feb 2024 01:31:09 +0530
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240209190227.lboi6n5s2oy7kxgc@pristine>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
 <20240207125410.r2q3jcplvif7dvt2@tumbling>
 <3a7c4a18-5463-414f-82df-39aaed861148@ti.com>
 <20240209172555.fxlxijhhbgrkyibo@agreeing>
 <87y1btlb66.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
 <20240209190227.lboi6n5s2oy7kxgc@pristine>
Message-ID: <87v86xl856.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>

Nishanth Menon <nm at ti.com> writes:

> On 00:25-20240210, Kamlesh Gurudasani wrote:
>> >> > > 
>> >> > > diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
>> >> > > index 35fe197dd303..31b7df05d7bb 100644
>> >> > > --- a/drivers/clk/keystone/sci-clk.c
>> >> > > +++ b/drivers/clk/keystone/sci-clk.c
>> >> > > @@ -516,6 +516,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>> >> > >   	struct sci_clk *sci_clk, *prev;
>> >> > >   	int num_clks = 0;
>> >> > >   	int num_parents;
>> >> > > [..]					/* Check if this clock id is valid */
>> >> > > +					ret = provider->ops->is_auto(provider->sci,
>> >> > > +						sci_clk->dev_id, ++clk_id, &state);
>> >> > A bit too nice coding ;) => I had been confused momentarily by clk_id = args.args[1]
>> >> > change just above till I saw that you are pre-incrementing
>> >> > clk_id - Is there a harm in leaving the original clk_id increment logic
>> >> > alone (it was much simpler to read up)?
>> >> 
>> >> No warm in using original code but want to avoid, two statement for
>> >> increment in case of failure and success.
>> >> 
>> >> Let me know, if i need to add few comments around this
>> >> 
>> >> or if you think, code is confusing I can move to original one
>> >
>> > Yes, please drop the un-necessary changes. In this case, original
>> > increment code should work just fine.
>> I wouldn't call it unnecessary, If I have to track increment/addition at
>> 3 different places just to understand the loop, it is hard. On other
>> hand, pre-increment code is solving the problem by having increment at
>> only one place(easier to track). On the plus side, every clk_id belonging to
>> parent is handled completely inside the loop.
>> 
>> For a new person looking at this code, pre-increment code would be
>> actually easier to undertsand.
>> 
>> Also, Udit feels the same.
>> 
>> Would you please explain why do you think the original increment code
>> make more sense? It's not simple to understand or track, that's for sure.
>
> the context of the fix is the is_auto call to know what parent options
> are valid or not. Do the absolutely what is necessary in the change. if
> you want to beautify etc, move it to some other patch and debate about
> it. So, this is un-necessary change in this patch.
The context of the fix i.e. handling non contiguous parents is making
the loop logic complex. Before this patch, i.e. contiguous clock
handling was simple.

In this fix, we are solving the problem as well as keeping the loop
simple. clk_id is basically the part of the same loop and it's affecting
nothing but the loop count. 

This is not just beautification, this is also simplifying the logic and
improving the readibility. 

If the patch can provide the solution and avoid the complexity, then I don't
understand why we need a patch that introduce the complexity and another
patch to solve the complexity.

My original question below is still not answered so I guess there is no
debate here actually.
"Would you please explain why do you think the original increment code
 make more sense? It's not simple to understand or track, that's for
 sure."

Kamlesh
>
> -- 
> Regards,
> Nishanth Menon
> Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From dmitry.baryshkov at linaro.org  Fri Feb  9 12:05:38 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri,  9 Feb 2024 22:05:38 +0200
Subject: [PATCH v2 5/5] iommu/arm-smmu: Convert to domain_alloc_paging()
In-Reply-To: <5-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com>
References: <5-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com>
Message-ID: <20240209200538.917366-1-dmitry.baryshkov@linaro.org>

On Tue, 17 Oct 2023 Jason Gunthorpe <jgg at nvidia.com> wrote:
> Now that the BLOCKED and IDENTITY behaviors are managed with their own
> domains change to the domain_alloc_paging() op.
> 
> The check for using_legacy_binding is now redundant,
> arm_smmu_def_domain_type() always returns IOMMU_DOMAIN_IDENTITY for this
> mode, so the core code will never attempt to create a DMA domain in the
> first place.
> 
> Since commit a4fdd9762272 ("iommu: Use flush queue capability") the core
> code only passes in IDENTITY/BLOCKED/UNMANAGED/DMA domain types. It will
> not pass in IDENTITY or BLOCKED if the global statics exist, so the test
> for DMA is also redundant now too.
> 
> Call arm_smmu_init_domain_context() early if a dev is available.
> 
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu.c | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)

For some reason this patch breaks booting of the APQ8096 Dragonboard820c
(qcom/apq8096-db820c.dts). Dispbling display subsystem (mdss) and venus
devices makes the board boot in most of the cases. Most frequently the
last parts of the log loog in a following way:

arm-smmu b40000.iommu: probing hardware configuration...
arm-smmu b40000.iommu: SMMUv2 with:
arm-smmu b40000.iommu: 	stage 1 translation
arm-smmu b40000.iommu: 	address translation ops
arm-smmu b40000.iommu: 	non-coherent table walk
arm-smmu b40000.iommu: 	(IDR0.CTTW overridden by FW configuration)
arm-smmu b40000.iommu: 	stream matching with 2 register groups
arm-smmu b40000.iommu: 	2 context banks (0 stage-2 only)
arm-smmu b40000.iommu: 	Supported page sizes: 0x63315000
arm-smmu b40000.iommu: 	Stage-1: 48-bit VA -> 36-bit IPA
arm-smmu b40000.iommu: 	preserved 0 boot mappings
arm-smmu d00000.iommu: probing hardware configuration...
arm-smmu d00000.iommu: SMMUv2 with:
arm-smmu d00000.iommu: 	stage 1 translation
arm-smmu d00000.iommu: 	address translation ops
arm-smmu d00000.iommu: 	non-coherent table walk
arm-smmu d00000.iommu: 	(IDR0.CTTW overridden by FW configuration)
arm-smmu d00000.iommu: 	stream matching with 2 register groups
arm-smmu d00000.iommu: 	2 context banks (0 stage-2 only)
arm-smmu d00000.iommu: 	Supported page sizes: 0x63315000
arm-smmu d00000.iommu: 	Stage-1: 32-bit VA -> 36-bit IPA
arm-smmu d00000.iommu: 	preserved 0 boot mappings
arm-smmu d40000.iommu: probing hardware configuration...
arm-smmu d40000.iommu: SMMUv2 with:
arm-smmu d40000.iommu: 	stage 1 translation
arm-smmu d40000.iommu: 	address translation ops
arm-smmu d40000.iommu: 	non-coherent table walk
arm-smmu d40000.iommu: 	(IDR0.CTTW overridden by FW configuration)
arm-smmu d40000.iommu: 	stream matching with 42 register groups
arm-smmu d40000.iommu: 	7 context banks (0 stage-2 only)
arm-smmu d40000.iommu: 	Supported page sizes: 0x63315000
arm-smmu d40000.iommu: 	Stage-1: 32-bit VA -> 36-bit IPA
arm-smmu d40000.iommu: 	preserved 0 boot mappings
arm-smmu da0000.iommu: probing hardware configuration...
arm-smmu da0000.iommu: SMMUv2 with:
arm-smmu da0000.iommu: 	stage 1 translation
arm-smmu da0000.iommu: 	address translation ops
arm-smmu da0000.iommu: 	non-coherent table walk
arm-smmu da0000.iommu: 	(IDR0.CTTW overridden by FW configuration)
arm-smmu da0000.iommu: 	stream matching with 4 register groups
arm-smmu da0000.iommu: 	2 context banks (0 stage-2 only)
arm-smmu da0000.iommu: 	Supported page sizes: 0x63315000
arm-smmu da0000.iommu: 	Stage-1: 32-bit VA -> 36-bit IPA
arm-smmu da0000.iommu: 	preserved 0 boot mappings
arm-smmu 1600000.iommu: probing hardware configuration...
arm-smmu 1600000.iommu: SMMUv2 with:
arm-smmu 1600000.iommu: 	stage 1 translation
arm-smmu 1600000.iommu: 	address translation ops
arm-smmu 1600000.iommu: 	non-coherent table walk
arm-smmu 1600000.iommu: 	(IDR0.CTTW overridden by FW configuration)
arm-smmu 1600000.iommu: 	stream matching with 15 register groups
arm-smmu 1600000.iommu: 	12 context banks (0 stage-2 only)
arm-smmu 1600000.iommu: 	Supported page sizes: 0x63315000
arm-smmu 1600000.iommu: 	Stage-1: 36-bit VA -> 36-bit IPA
arm-smmu 1600000.iommu: 	preserved 0 boot mappings
adreno b00000.gpu: Adding to iommu group 0
Bluetooth: hci0: QCA Product ID   :0x00000008
Bluetooth: hci0: QCA SOC Version  :0x00000044
Bluetooth: hci0: QCA ROM Version  :0x00000302
Bluetooth: hci0: QCA Patch Version:0x00000111
Bluetooth: hci0: QCA controller version 0x00440302
platform 9a0000.hdmi-tx: Fixed dependency cycle(s) with /soc at 0/display-subsystem at 900000/display-controller at 901000/ports/port at 0/endpoint
Bluetooth: hci0: QCA Downloading qca/rampatch_00440302.bin
spi_qup 7575000.spi: IN:block:16, fifo:64, OUT:block:16, fifo:64
spi_qup 75ba000.spi: IN:block:16, fifo:64, OUT:block:16, fifo:64
phy phy-7411000.phy.5: QUSB2PHY pll lock failed: status reg = 0
phy phy-7411000.phy.5: phy init failed --> -16
dwc3 6a00000.usb: error -EBUSY: failed to initialize core
dwc3: probe of 6a00000.usb failed with error -16
phy phy-7412000.phy.6: QUSB2PHY pll lock failed: status reg = 0
phy phy-7412000.phy.6: phy init failed --> -16
dwc3 7600000.usb: error -EBUSY: failed to initialize core
dwc3: probe of 7600000.usb failed with error -16
i2c_qup 7577000.i2c: using default clock-frequency 100000
i2c_qup 75b5000.i2c: using default clock-frequency 100000
sdhci_msm 74a4900.mmc: Got CD GPIO
scsi host0: ufshcd
ufshcd-qcom 624000.ufshc: ufs_qcom_host_reset: reset control not set
remoteproc remoteproc0: 2080000.remoteproc is available
remoteproc remoteproc1: 9300000.remoteproc is available
mmc0: SDHCI controller on 74a4900.mmc [74a4900.mmc] using ADMA 64-bit
qcom-pcie 600000.pcie: host bridge /soc at 0/bus at 0/pcie at 600000 ranges:
qcom-pcie 608000.pcie: supply vddpe-3v3 not found, using dummy regulator

[ The board resets to the bootloader ]



From sebastian.wick at redhat.com  Fri Feb  9 12:30:46 2024
From: sebastian.wick at redhat.com (Sebastian Wick)
Date: Fri, 9 Feb 2024 21:30:46 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB
 property
In-Reply-To: <niqn7eql5neyfp5ficdfisdpmlwrprovqn5g7lgcfwoe74ds23@7fr4yv2miqe7>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <niqn7eql5neyfp5ficdfisdpmlwrprovqn5g7lgcfwoe74ds23@7fr4yv2miqe7>
Message-ID: <20240209203046.GA996172@toolbox>

On Fri, Feb 02, 2024 at 04:49:04PM +0100, Maxime Ripard wrote:
> Hi Sebastian,
> 
> On Mon, Jan 15, 2024 at 03:33:08PM +0100, Sebastian Wick wrote:
> > >  /**
> > >   * DOC: HDMI connector properties
> > >   *
> > > + * Broadcast RGB
> > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > + *      Infoframes will be generated according to that value.
> > > + *
> > > + *      The value of this property can be one of the following:
> > > + *
> > > + *      Automatic:
> > > + *              RGB Range is selected automatically based on the mode
> > > + *              according to the HDMI specifications.
> > > + *
> > > + *      Full:
> > > + *              Full RGB Range is forced.
> > > + *
> > > + *      Limited 16:235:
> > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > + *              this works for any number of bits-per-component.
> > > + *
> > > + *      Drivers can set up this property by calling
> > > + *      drm_connector_attach_broadcast_rgb_property().
> > > + *
> > 
> > This is a good time to document this in more detail. There might be two
> > different things being affected:
> > 
> > 1. The signalling (InfoFrame/SDP/...)
> > 2. The color pipeline processing
> > 
> > All values of Broadcast RGB always affect the color pipeline processing
> > such that a full-range input to the CRTC is converted to either full- or
> > limited-range, depending on what the monitor is supposed to accept.
> > 
> > When automatic is selected, does that mean that there is no signalling,
> > or that the signalling matches what the monitor is supposed to accept
> > according to the spec? Also, is this really HDMI specific?
> > 
> > When full or limited is selected and the monitor doesn't support the
> > signalling, what happens?
> 
> Leaving the YCbCr vs RGB discussion aside, would this be better ?

Yes, it is. Thanks.

We do have to resolve the YCbCr vs RGB issue though.

>  * Broadcast RGB (HDMI specific)
>  *      Indicates the Quantization Range (Full vs Limited) used. The color
>  *      processing pipeline will be adjusted to match the value of the

Ah, another thing no note here is that the CRTC as configured by user
space must always produce full range pixels.

>  *      property, and the Infoframes will be generated and sent accordingly.
>  *
>  *      The value of this property can be one of the following:
>  *
>  *      Automatic:
>  *              The quantization range is selected automatically based on the
>  *              mode according to the HDMI specifications (HDMI 1.4b - Section
>  *              6.6 - Video Quantization Ranges).
>  *
>  *      Full:
>  *              Full quantization range is forced.
>  *
>  *      Limited 16:235:
>  *              Limited quantization range is forced. Unlike the name suggests,
>  *              this works for any number of bits-per-component.
>  *
>  *      Property values other than Automatic can result in colors being off (if
>  *      limited is selected but the display expects full), or a black screen
>  *      (if full is selected but the display expects limited).
>  *
>  *      Drivers can set up this property by calling
>  *      drm_connector_attach_broadcast_rgb_property().
> 
> Thanks!
> Maxime




From sebastian.wick at redhat.com  Fri Feb  9 12:34:35 2024
From: sebastian.wick at redhat.com (Sebastian Wick)
Date: Fri, 9 Feb 2024 21:34:35 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast
 RGB property
In-Reply-To: <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
Message-ID: <20240209203435.GB996172@toolbox>

On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > Hi,
> > > > > 
> > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > >  /**
> > > > > > > >   * DOC: HDMI connector properties
> > > > > > > >   *
> > > > > > > > + * Broadcast RGB
> > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > + *
> > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > + *
> > > > > > > > + *      Automatic:
> > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > + *
> > > > > > > > + *      Full:
> > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > + *
> > > > > > > > + *      Limited 16:235:
> > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > + *
> > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > + *
> > > > > > > 
> > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > different things being affected:
> > > > > > > 
> > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > 2. The color pipeline processing
> > > > > > > 
> > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > 
> > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > 
> > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > signalling, what happens?
> > > > > > 
> > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > YCbCr?
> > > > > 
> > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > vc4 will follow the value of the property.
> > > > 
> > > > The property is literally called "Broadcast *RGB*".
> > > > That should explain why it's only affecting RGB.
> > > 
> > > Right. And the limited range option is called "Limited 16:235" despite
> > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > to make names inconsistent too, that's fine and not an argument in
> > > itself.
> > > 
> > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > to enable it.
> > > 
> > > vc4 supports it.
> > 
> > Someone implemented it incorrectly then.
> 
> Incorrectly according to what documentation / specification? I'm sorry,
> but I find it super ironic that i915 gets to do its own thing, not
> document any of it, and when people try to clean things up they get told
> that we got it all wrong.

FWIW, this was an i915 property and if another driver uses the same
property name it must have the same behavior. Yes, it isn't standardized
and yes, it's not documented (hence this effort here) but it's still on
vc4 to make the property compatible.

Trying to make the property handle YCbCr is very much in the "let's try
to fix the property" territory that I want to avoid, so I'm in favor of
adjusting vc4.

> > > > Eg. with DP it only became possible with the introduction of the VSC
> > > > SDP (and I don't recall if there's additional capability checks that
> > > > are also required). With DP MSA signalling full range YCbCr is not
> > > > possible at all.
> > > 
> > > This is for HDMI only.
> > > 
> > > > I don't recall right now what the HDMI requirements are.
> > > 
> > > HDMI has supported it for a while, and it's defined (for example) in the
> > > HDMI 1.4 spec in Section 6.6 - Video Quantization Ranges. It supports
> > > limited and full range on both RGB and YCbCr, as long as the EDIDs state
> > > so and the Infoframes signal it.
> > 
> > I think a good reason for not using a simple boolean like this 
> > YCbCr is that it doesn't cover the color encoding part at all,
> > which is probably more important than the quantization range.
> > So we need a new property anyway.
> 
> This isn't what is being discussed here, and as I've shown you, is
> completely orthogonal as far as HDMI is concerned.
> 
> Maxime




From semen.protsenko at linaro.org  Fri Feb  9 12:43:39 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 9 Feb 2024 14:43:39 -0600
Subject: [PATCH v4 2/2] watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle()
 for PMU regs
In-Reply-To: <20240208161700.268570-3-peter.griffin@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org> <20240208161700.268570-3-peter.griffin@linaro.org>
Message-ID: <CAPLW+4n6e2SQSMSAQ66U09JhYRc7gqkwBqU2LOg_=Z2Aqdd4cw@mail.gmail.com>

On Thu, Feb 8, 2024 at 10:21?AM Peter Griffin <peter.griffin at linaro.org> wrote:
>
> Obtain the PMU regmap using the new API added to exynos-pmu driver rather
> than syscon_regmap_lookup_by_phandle(). As this driver no longer depends
> on mfd syscon remove that header and Kconfig dependency.
>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---

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

Tested on my E850-96 board (Exynos850 chip) with Debian rootfs. Test procedure:

1. Added this to /chosen node in dts:

    bootargs = "s3c2410_wdt.tmr_atboot=1 s3c2410_wdt.nowayout=1
s3c2410_wdt.soft_noboot=0";

2. Check if watchdogs are active:

    # dmesg | grep watchdog
    [    1.488149] s3c2410-wdt 10050000.watchdog: starting watchdog timer
    [    1.489003] s3c2410-wdt 10050000.watchdog: watchdog active,
reset enabled, irq disabled
    [    1.496928] s3c2410-wdt 10060000.watchdog: starting watchdog timer
    [    1.502984] s3c2410-wdt 10060000.watchdog: watchdog active,
reset enabled, irq disabled

3. Generate a panic to cause wdt reset:

    #  echo c > /proc/sysrq-trigger

In 15 seconds (wdt timeout) reboot happens, and bootloader shows this
message for the reboot reason:

    Watchdog or Warm Reset Detected

That proves regmap works fine with this patch. Otherwise reboot wouldn't happen.

>  drivers/watchdog/Kconfig       | 1 -
>  drivers/watchdog/s3c2410_wdt.c | 8 ++++----
>  2 files changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 7d22051b15a2..d78fe7137799 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -512,7 +512,6 @@ config S3C2410_WATCHDOG
>         tristate "S3C6410/S5Pv210/Exynos Watchdog"
>         depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
>         select WATCHDOG_CORE
> -       select MFD_SYSCON if ARCH_EXYNOS
>         help
>           Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos
>           SoCs. This will reboot the system when the timer expires with
> diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
> index 349d30462c8c..686cf544d0ae 100644
> --- a/drivers/watchdog/s3c2410_wdt.c
> +++ b/drivers/watchdog/s3c2410_wdt.c
> @@ -24,9 +24,9 @@
>  #include <linux/slab.h>
>  #include <linux/err.h>
>  #include <linux/of.h>
> -#include <linux/mfd/syscon.h>
>  #include <linux/regmap.h>
>  #include <linux/delay.h>
> +#include <linux/soc/samsung/exynos-pmu.h>
>
>  #define S3C2410_WTCON          0x00
>  #define S3C2410_WTDAT          0x04
> @@ -699,11 +699,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
>                 return ret;
>
>         if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
> -               wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
> -                                               "samsung,syscon-phandle");
> +               wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node,
> +                                                "samsung,syscon-phandle");
>                 if (IS_ERR(wdt->pmureg))
>                         return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
> -                                            "syscon regmap lookup failed.\n");
> +                                            "PMU regmap lookup failed.\n");
>         }
>
>         wdt_irq = platform_get_irq(pdev, 0);
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From semen.protsenko at linaro.org  Fri Feb  9 12:50:48 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 9 Feb 2024 14:50:48 -0600
Subject: [PATCH v4 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <20240208161700.268570-2-peter.griffin@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org> <20240208161700.268570-2-peter.griffin@linaro.org>
Message-ID: <CAPLW+4mSyqnkzz5N1seFoaDAR1pd_jQEO3ThkGf3U_ozfwedyA@mail.gmail.com>

On Thu, Feb 8, 2024 at 10:21?AM Peter Griffin <peter.griffin at linaro.org> wrote:
>
> Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> security hardening reasons so that they are only write accessible in el3
> via an SMC call.
>
> As most Exynos drivers that need to write PMU registers currently obtain a
> regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> is implemented in this driver using a custom regmap similar to syscon to
> handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> regmap like before. As regmaps abstract out the underlying register access
> changes to the leaf drivers are minimal.
>
> A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> that currently use syscon_regmap_lookup_by_phandle(). This also handles
> deferred probing.
>
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
> Changes since v3:
>  - Fix PMUALIVE_MASK
>  - Add TENSOR_ prefix
>  - clear SET_BITS bits on each loop iteration
>  - change set_bit to set_bits in func name
>  - Fix some alignment
>  - Add missing return on dev_err_probe
>  - Reduce indentation in loop
>
> Changes since v2
>  - Add select REGMAP to Kconfig
>  - Add constant for SET/CLEAR bits
>  - Replace kerneldoc with one line comment
>  - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
>  - remove superfluous extern keyword
>  - dev_err_probe() on probe error
>  - shorten regmcfg name
>  - no compatibles inside probe, use match data
>  - don't mix declarations with/without initializations
>  - tensor_sec_reg_read() use mmio to avoid access restrictions
>  - Collect up Reviewed-by
>  - const for regmap_config structs
> ---

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

Tested on my E850-96. All modules that use PMU are still functional
with this patch (watchdog, USB host and Ethernet). No regressions.

[snip]


From ak at linux.intel.com  Fri Feb  9 13:10:27 2024
From: ak at linux.intel.com (Andi Kleen)
Date: Fri, 9 Feb 2024 13:10:27 -0800
Subject: [PATCH V5 01/12] perf/core: Add aux_pause, aux_resume,
 aux_start_paused
In-Reply-To: <d53ef26d-a7e6-4b3b-b593-be75425c0e77@intel.com>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
 <20240208113127.22216-2-adrian.hunter@intel.com>
 <ZcVuK1nnxG18ps-a@tassilo>
 <d53ef26d-a7e6-4b3b-b593-be75425c0e77@intel.com>
Message-ID: <ZcaUw4xQT0VcC7IO@tassilo>

> The writes to rb->aux_in_pause_resume must be done
> only once.  It might be possible to get away without
> WRITE_ONCE(), but really the compiler should be informed
> not to make assumptions.

What stops the NMI from firing here?

> >> +  if (READ_ONCE(rb->aux_in_pause_resume))
> >> +	/* Guard against NMI, NMI loses here */
> >> +          goto out_restore;
<----------------------- NMI
> >> +  WRITE_ONCE(rb->aux_in_pause_resume, 1);


Even if it isn't racy it needs a clear comment.

-Andi




From ddrokosov at salutedevices.com  Fri Feb  9 13:28:05 2024
From: ddrokosov at salutedevices.com (Dmitry Rokosov)
Date: Sat, 10 Feb 2024 00:28:05 +0300
Subject: [PATCH v1 1/2] arm64: dts: amlogic: axg: move cpu cooling-cells to common dtsi
In-Reply-To: <20240209212816.11187-1-ddrokosov@salutedevices.com>
References: <20240209212816.11187-1-ddrokosov@salutedevices.com>
Message-ID: <20240209212816.11187-2-ddrokosov@salutedevices.com>

The CPU cooling-cells property should be located in the meson-axg common
dtsi, as it is required for all AXG-based boards with DVFS.

Signed-off-by: Dmitry Rokosov <ddrokosov at salutedevices.com>
---
 .../amlogic/meson-axg-jethome-jethub-j1xx.dtsi   | 16 ----------------
 arch/arm64/boot/dts/amlogic/meson-axg.dtsi       |  4 ++++
 2 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
index db605f3a22b4..55802fb03a46 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
@@ -332,19 +332,3 @@ &gpio {
 		"", "", "", "", "", // 80 - 84
 		"", ""; // 85-86
 };
-
-&cpu0 {
-	#cooling-cells = <2>;
-};
-
-&cpu1 {
-	#cooling-cells = <2>;
-};
-
-&cpu2 {
-	#cooling-cells = <2>;
-};
-
-&cpu3 {
-	#cooling-cells = <2>;
-};
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 7e5ac9db93f8..ea96fef328e8 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -74,6 +74,7 @@ cpu0: cpu at 0 {
 			enable-method = "psci";
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
+			#cooling-cells = <2>;
 		};
 
 		cpu1: cpu at 1 {
@@ -83,6 +84,7 @@ cpu1: cpu at 1 {
 			enable-method = "psci";
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
+			#cooling-cells = <2>;
 		};
 
 		cpu2: cpu at 2 {
@@ -92,6 +94,7 @@ cpu2: cpu at 2 {
 			enable-method = "psci";
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
+			#cooling-cells = <2>;
 		};
 
 		cpu3: cpu at 3 {
@@ -101,6 +104,7 @@ cpu3: cpu at 3 {
 			enable-method = "psci";
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
+			#cooling-cells = <2>;
 		};
 
 		l2: l2-cache0 {
-- 
2.43.0



From ddrokosov at salutedevices.com  Fri Feb  9 13:28:04 2024
From: ddrokosov at salutedevices.com (Dmitry Rokosov)
Date: Sat, 10 Feb 2024 00:28:04 +0300
Subject: [PATCH v1 0/2] meson-axg: properly setup CPU power management
Message-ID: <20240209212816.11187-1-ddrokosov@salutedevices.com>

The Meson AXG leverages the SCPI ARM protocol for the management of CPU
power, thermal, and frequency. This series addresses several issues that
have impacted the functionality of the power_allocator thermal governor
and cpufreq cooling devices.

Dmitry Rokosov (2):
  arm64: dts: amlogic: axg: move cpu cooling-cells to common dtsi
  arm64: dts: amlogic: axg: initialize default SoC capacitance

 .../amlogic/meson-axg-jethome-jethub-j1xx.dtsi   | 16 ----------------
 arch/arm64/boot/dts/amlogic/meson-axg.dtsi       |  8 ++++++++
 2 files changed, 8 insertions(+), 16 deletions(-)

-- 
2.43.0



From ddrokosov at salutedevices.com  Fri Feb  9 13:28:06 2024
From: ddrokosov at salutedevices.com (Dmitry Rokosov)
Date: Sat, 10 Feb 2024 00:28:06 +0300
Subject: [PATCH v1 2/2] arm64: dts: amlogic: axg: initialize default SoC capacitance
In-Reply-To: <20240209212816.11187-1-ddrokosov@salutedevices.com>
References: <20240209212816.11187-1-ddrokosov@salutedevices.com>
Message-ID: <20240209212816.11187-3-ddrokosov@salutedevices.com>

The capacitance value is required for the usage of the cpufreq cooling
device and power_allocator thermal governor in the appropriate energy
model.

It helps to compute the power estimated by the SoC at the appropriate
frequency. If it is the frequency of an existing OPP, or at the
frequency of the first OPP above the requested value otherwise.

The power is estimated as P = C * V^2 * f, with C being the SoC's
capacitance and V and f respectively representing the voltage and
frequency of the OPP.

Since AXG SoC doesn't have SCMI protocol support, we need to initialize
capacitance using the 'dynamic-power-coefficient' DT entry. Its value is
retrieved from the vendor kernel, and it gives us the following
freq2power mapping:
    +-----------+--------+
    | frequency,| power, |
    |    MHz    |   uW   |
    +-----------+--------+
    |     100   |  10354 |
    +-----------+--------+
    |     250   |  27104 |
    +-----------+--------+
    |     500   |  55447 |
    +-----------+--------+
    |     667   |  77327 |
    +-----------+--------+
    |    1000   | 129024 |
    +-----------+--------+
    |    1200   | 164656 |
    +-----------+--------+
    |    1296   | 192489 |
    +-----------+--------+
    |    1416   | 239870 |
    +-----------+--------+

Signed-off-by: Dmitry Rokosov <ddrokosov at salutedevices.com>
---
 arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index ea96fef328e8..6d12b760b90f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -74,6 +74,7 @@ cpu0: cpu at 0 {
 			enable-method = "psci";
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
+			dynamic-power-coefficient = <140>;
 			#cooling-cells = <2>;
 		};
 
@@ -84,6 +85,7 @@ cpu1: cpu at 1 {
 			enable-method = "psci";
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
+			dynamic-power-coefficient = <140>;
 			#cooling-cells = <2>;
 		};
 
@@ -94,6 +96,7 @@ cpu2: cpu at 2 {
 			enable-method = "psci";
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
+			dynamic-power-coefficient = <140>;
 			#cooling-cells = <2>;
 		};
 
@@ -104,6 +107,7 @@ cpu3: cpu at 3 {
 			enable-method = "psci";
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
+			dynamic-power-coefficient = <140>;
 			#cooling-cells = <2>;
 		};
 
-- 
2.43.0



From cki-project at redhat.com  Fri Feb  9 13:41:29 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Fri, 09 Feb 2024 21:41:29 -0000
Subject: =?utf-8?b?4pyF?= PASS (MISSED 16 of 101): Test report for
 for-kernelci (6.8.0-rc3, arm-next, f735966e)
Message-ID: <86337.124020916412902605@us-mta-332.us.mimecast.lan>

Hi, we tested your kernel and here are the results:

    Overall result: PASSED
             Merge: OK
           Compile: OK
              Test: OK

Tested-by: CKI Project <cki-project at redhat.com>

Kernel information:
    Commit message: Merge branches 'for-next/reorg-va-space' and 'for-next/rust-for-arm64' into for-next/core

You can find all the details about the test run at
    https://datawarehouse.cki-project.org/kcidb/checkouts/128686

One or more kernel tests failed:
    We also see the following known issues which are not related to your changes:
        Issue: [rawhide] avc:  denied  { read write } for  pid=12364 comm="plymouthd" name="kmsg" dev="devtmpfs" ino=10 scontext=system_u:system_r:plymouthd_t:s0 tcontext=system_u:object_r:kmsg_device_t:s0 tclass=chr_file permissive=1
            URL: https://bugzilla.redhat.com/show_bug.cgi?id=2256442
            Affected tests:
                 aarch64 - Boot test
                 aarch64 - stress: stress-ng - cpu-cache
                 aarch64 - Reboot test
        Issue: [Rawhide] nvme-cli: hostid/hostnqn warnings to verbose level
            URL: https://github.com/linux-nvme/nvme-cli/commit/252929069d6c9042e9c95f41788006cb3eb2f452
            Affected tests:
                 aarch64 - Storage - blktests - blk
                 aarch64 - Storage - blktests - nvme-tcp
        Issue: [upstream] stress-ng: avc denial on secretmemory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1752
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: stress: stress-ng - memory: (panic) Comm: systemd-oomd Not tainted 6.1.0-rc3
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1461
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: Firmware test suite: mv: cannot stat 'dtcompilerparser.tab.c': No such file or directory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1544
            Affected tests:
                 aarch64 - Hardware - Firmware test suite


Tests that were not ran because of internal issues: 
     aarch64 - CKI/restraint
     aarch64 - SELinux Custom Module Setup
     aarch64 - machineinfo
     aarch64 - Boot test
     aarch64 - Hardware - IPMI driver test
     aarch64 - Hardware - IPMItool loop stress test
     aarch64 - Storage - blktests - blk
     aarch64 - Storage - blktests - nvme-tcp
     aarch64 - Storage - block - filesystem fio test
     aarch64 - Storage - block - queue scheduler test
     aarch64 - Storage - swraid scsi_raid
     aarch64 - stress: stress-ng - cpu-cache
     aarch64 - stress: stress-ng - memory
     aarch64 - Reboot test
     aarch64 - Memory function: memfd_create
     aarch64 - Memory function: memfd_create


If you find a failure unrelated to your changes, please ask the test maintainer to review it.
This will prevent the failures from being incorrectly reported in the future.

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
           `-'
______________________________________________________________________________



From miguel.ojeda.sandonis at gmail.com  Fri Feb  9 13:41:39 2024
From: miguel.ojeda.sandonis at gmail.com (Miguel Ojeda)
Date: Fri, 9 Feb 2024 22:41:39 +0100
Subject: [PATCH v4 0/2] Rust enablement for AArch64
In-Reply-To: <170750002897.1210949.14507303616035197246.b4-ty@arm.com>
References: <20231020155056.3495121-1-Jamie.Cunliffe@arm.com> <170750002897.1210949.14507303616035197246.b4-ty@arm.com>
Message-ID: <CANiq72=VOHDUkJTaDgwM_2rk4UrNa3MCnvn2OLPu9SSs7CPJmg@mail.gmail.com>

On Fri, Feb 9, 2024 at 6:38?PM Catalin Marinas <catalin.marinas at arm.com> wrote:
>
> Applied to arm64 (for-next/rust-for-arm64), thanks!
>
> I also folded Rui's loongarch fix into the first patch to avoid breaking
> this arch:
>
> https://github.com/heiher/linux/commit/c504d83a6edd963e2ba58ec538e3f06da78b187e.patch

Thanks Catalin!

I tested your branch `for-next/core` at f735966ee23c with arm64 and
x86_64 (and built-test loongarch64).

Cheers,
Miguel


From kuba at kernel.org  Fri Feb  9 13:42:35 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 9 Feb 2024 13:42:35 -0800
Subject: [PATCH] net: emaclite: Use
 devm_platform_get_and_ioremap_resource() in xemaclite_of_probe()
In-Reply-To: <f87065d0-e398-4ffa-bfa4-9ff99d73f206@web.de>
References: <f87065d0-e398-4ffa-bfa4-9ff99d73f206@web.de>
Message-ID: <20240209134235.0f14b93f@kernel.org>

Applied, thanks, but in the future please make sure that:

On Mon, 5 Feb 2024 14:55:23 +0100 Markus Elfring wrote:
> From: Markus Elfring <elfring at users.sourceforge.net>
> Date: Mon, 5 Feb 2024 14:44:20 +0100

You use git-send-email or otherwise get rid of these extra lines.
They appear to confuse the kernel.org patchwork reply bot.

> A wrapper function is available since the commit 890cc39a879906b63912482dfc41944579df2dc6

trim hashes to 12 characters.

> ("drivers: provide devm_platform_get_and_ioremap_resource()").
> Thus reuse existing functionality instead of keeping duplicate source code.
> 
> This issue was detected by using the Coccinelle software.


From david at redhat.com  Fri Feb  9 14:16:45 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 9 Feb 2024 23:16:45 +0100
Subject: [PATCH v5 00/25] Transparent Contiguous PTEs for User Mappings
In-Reply-To: <3ba54c94-8e44-4dd6-9a25-2cf81b07336f@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <ZcUQqfg39zCS2BAv@FVFF77S0Q05N.cambridge.arm.com>
 <3ba54c94-8e44-4dd6-9a25-2cf81b07336f@arm.com>
Message-ID: <216aa113-dc3f-45d4-964f-98f80969a927@redhat.com>

>> 1) Convert READ_ONCE() -> ptep_get()
>> 2) Convert set_pte_at() -> set_ptes()
>> 3) All the "New layer" renames and addition of the trivial wrappers
> 
> Yep that makes sense. I'll start prepping that today. I'll hold off reposting
> until I have your comments on 19-25. I'm also hoping that David will repost the
> zap series today so that it can get into mm-unstable by mid-next week. Then I'll
> repost on top of that, hopefully by end of next week, folding in all your
> comments. This should give planty of time to soak in linux-next.

Just sent out v2. Will review this series (early) next week.

Have a great weekend!

-- 
Cheers,

David / dhildenb



From jm at ti.com  Fri Feb  9 14:23:56 2024
From: jm at ti.com (Judith Mendez)
Date: Fri, 9 Feb 2024 16:23:56 -0600
Subject: [PATCH v1 6/9] arm64: dts: ti: k3-am6*: Remove DLL properties for
 soft PHYs
In-Reply-To: <20240209180515.GA29650@francesco-nb>
References: <20240207225526.3953230-1-jm@ti.com>
 <20240207225526.3953230-7-jm@ti.com> <20240209180515.GA29650@francesco-nb>
Message-ID: <d795c353-a009-4270-8652-1dedb9008d41@ti.com>

Hi Francesco,

On 2/9/24 12:05 PM, Francesco Dolcini wrote:
> On Wed, Feb 07, 2024 at 04:55:23PM -0600, Judith Mendez wrote:
>> Remove DLL properties which are not applicable for soft PHYs
>> since these PHYs do not have a DLL to enable.
>>
>> Signed-off-by: Judith Mendez <jm at ti.com>
>> ---
>>   arch/arm64/boot/dts/ti/k3-am62-main.dtsi       | 3 ---
>>   arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 3 ---
>>   arch/arm64/boot/dts/ti/k3-am62a-main.dtsi      | 1 -
>>   arch/arm64/boot/dts/ti/k3-am62a7-sk.dts        | 1 -
>>   arch/arm64/boot/dts/ti/k3-am62p5-sk.dts        | 1 -
>>   arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 2 --
>>   arch/arm64/boot/dts/ti/k3-am64-main.dtsi       | 1 -
>>   arch/arm64/boot/dts/ti/k3-am642-evm.dts        | 1 -
>>   arch/arm64/boot/dts/ti/k3-am642-sk.dts         | 1 -
>>   9 files changed, 14 deletions(-)
> 
> you missed k3-am62-verdin-dev.dtsi and more ?

ok, will include in v2.

> 
> $ ack --dts -g k3-am6[24] | ack -x -l ti,driver-strength-ohm
> arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
> arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
> arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
> arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
> arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
> arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
> arch/arm64/boot/dts/ti/k3-am642-tqma64xxl.dtsi
> arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
> arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
> arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
> arch/arm64/boot/dts/ti/k3-am642-evm.dts
> arch/arm64/boot/dts/ti/k3-am642-sk.dts
> arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
> arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
> arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
> arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
> 
> Francesco
> 

~ Judith


From jgg at nvidia.com  Fri Feb  9 14:23:49 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 9 Feb 2024 18:23:49 -0400
Subject: [PATCH v2 5/5] iommu/arm-smmu: Convert to domain_alloc_paging()
In-Reply-To: <20240209200538.917366-1-dmitry.baryshkov@linaro.org>
References: <5-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com>
 <20240209200538.917366-1-dmitry.baryshkov@linaro.org>
Message-ID: <20240209222349.GA923780@nvidia.com>

On Fri, Feb 09, 2024 at 10:05:38PM +0200, Dmitry Baryshkov wrote:
> On Tue, 17 Oct 2023 Jason Gunthorpe <jgg at nvidia.com> wrote:
> > Now that the BLOCKED and IDENTITY behaviors are managed with their own
> > domains change to the domain_alloc_paging() op.
> > 
> > The check for using_legacy_binding is now redundant,
> > arm_smmu_def_domain_type() always returns IOMMU_DOMAIN_IDENTITY for this
> > mode, so the core code will never attempt to create a DMA domain in the
> > first place.
> > 
> > Since commit a4fdd9762272 ("iommu: Use flush queue capability") the core
> > code only passes in IDENTITY/BLOCKED/UNMANAGED/DMA domain types. It will
> > not pass in IDENTITY or BLOCKED if the global statics exist, so the test
> > for DMA is also redundant now too.
> > 
> > Call arm_smmu_init_domain_context() early if a dev is available.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> > ---
> >  drivers/iommu/arm/arm-smmu/arm-smmu.c | 21 +++++++++++++++------
> >  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> For some reason this patch breaks booting of the APQ8096 Dragonboard820c
> (qcom/apq8096-db820c.dts). Dispbling display subsystem (mdss) and venus
> devices makes the board boot in most of the cases. Most frequently the
> last parts of the log loog in a following way:

It is surprising we tested this patch on some tegra systems with this
iommu and didn't hit anything..

The only real functional thing this changes is to move the domain
initialization up in time, potentially a lot in time in some
cases. That function does alot of things including touching HW so
possibly there is some surprising interaction with something else.

So, I would expect this to not WARN_ON and to make it work the same as
before the patch:

--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -875,7 +875,9 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
        mutex_init(&smmu_domain->init_mutex);
        spin_lock_init(&smmu_domain->cb_lock);
 
-       if (dev) {
+       WARN_ON(using_legacy_binding);
+
+/*     if (dev) {
                struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
 
                if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
@@ -883,7 +885,7 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
                        return NULL;
                }
        }
-
+*/
        return &smmu_domain->domain;
 }

Then I'd ask you to remove the comment and do:

@@ -878,7 +878,9 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
        if (dev) {
                struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
 
+               WARN_ON(true);
                if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
+                       printk("Allocation failure in arm_smmu_domain_alloc_paging()\n");
                        kfree(smmu_domain);
                        return NULL;
                }


And then we may get a clue from the backtraces it generates. I only
saw one iommu group reported in your log so I'd expect one trace?

Thanks,
Jason


From jm at ti.com  Fri Feb  9 14:27:29 2024
From: jm at ti.com (Judith Mendez)
Date: Fri, 9 Feb 2024 16:27:29 -0600
Subject: [PATCH v1 9/9] arm64: dts: ti: k3-am6*: Fix bootph-all property
 in MMC node
In-Reply-To: <20240209172745.dswt5q6xnulubrjp@bagpipe>
References: <20240207225526.3953230-1-jm@ti.com>
 <20240207225526.3953230-10-jm@ti.com>
 <20240209172745.dswt5q6xnulubrjp@bagpipe>
Message-ID: <15db1143-afe2-44b0-a6a5-bce871a6bd6b@ti.com>

Hi Nishanth,

On 2/9/24 11:27 AM, Nishanth Menon wrote:
> On 16:55-20240207, Judith Mendez wrote:
>>   &sdhci1 {
>>   	/* SD/MMC */
>> +	bootph-all;
>>   	status = "okay";
>>   	vmmc-supply = <&vdd_mmc1>;
>>   	vqmmc-supply = <&vddshv_sdio>;
>>   	pinctrl-names = "default";
>>   	pinctrl-0 = <&main_mmc1_pins_default>;
>>   	disable-wp;
>> -	bootph-all;
> 
> NAK! Read [1]
> 
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/dts-coding-style.rst#n117
> 

No worries, I can remove this change.

~ Judith


From david at redhat.com  Fri Feb  9 14:36:17 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 9 Feb 2024 23:36:17 +0100
Subject: [PATCH v3 01/15] arm64/mm: Make set_ptes() robust when OAs cross
 48-bit boundary
In-Reply-To: <ZcRwc2mEDHIXxgGa@kernel.org>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-2-david@redhat.com> <ZcRwc2mEDHIXxgGa@kernel.org>
Message-ID: <6b0d2c43-90cd-4429-baa9-078dd37fe207@redhat.com>

On 08.02.24 07:10, Mike Rapoport wrote:
> On Mon, Jan 29, 2024 at 01:46:35PM +0100, David Hildenbrand wrote:
>> From: Ryan Roberts <ryan.roberts at arm.com>
>>
>> Since the high bits [51:48] of an OA are not stored contiguously in the
>> PTE, there is a theoretical bug in set_ptes(), which just adds PAGE_SIZE
>> to the pte to get the pte with the next pfn. This works until the pfn
>> crosses the 48-bit boundary, at which point we overflow into the upper
>> attributes.
>>
>> Of course one could argue (and Matthew Wilcox has :) that we will never
>> see a folio cross this boundary because we only allow naturally aligned
>> power-of-2 allocation, so this would require a half-petabyte folio. So
>> its only a theoretical bug. But its better that the code is robust
>> regardless.
>>
>> I've implemented pte_next_pfn() as part of the fix, which is an opt-in
>> core-mm interface. So that is now available to the core-mm, which will
>> be needed shortly to support forthcoming fork()-batching optimizations.
>>
>> Link: https://lkml.kernel.org/r/20240125173534.1659317-1-ryan.roberts at arm.com
>> Fixes: 4a169d61c2ed ("arm64: implement the new page table range API")
>> Closes: https://lore.kernel.org/linux-mm/fdaeb9a5-d890-499a-92c8-d171df43ad01 at arm.com/
>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
>> Reviewed-by: David Hildenbrand <david at redhat.com>
>> Signed-off-by: David Hildenbrand <david at redhat.com>
> 
> Reviewed-by: Mike Rapoport (IBM) <rppt at kernel.org>

Thanks for the review Mike, appreciated!

-- 
Cheers,

David / dhildenb



From ryan.roberts at arm.com  Fri Feb  9 15:52:28 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri, 9 Feb 2024 23:52:28 +0000
Subject: [PATCH v5 00/25] Transparent Contiguous PTEs for User Mappings
In-Reply-To: <216aa113-dc3f-45d4-964f-98f80969a927@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <ZcUQqfg39zCS2BAv@FVFF77S0Q05N.cambridge.arm.com>
 <3ba54c94-8e44-4dd6-9a25-2cf81b07336f@arm.com>
 <216aa113-dc3f-45d4-964f-98f80969a927@redhat.com>
Message-ID: <633af0a7-0823-424f-b6ef-374d99483f05@arm.com>

On 09/02/2024 22:16, David Hildenbrand wrote:
>>> 1) Convert READ_ONCE() -> ptep_get()
>>> 2) Convert set_pte_at() -> set_ptes()
>>> 3) All the "New layer" renames and addition of the trivial wrappers
>>
>> Yep that makes sense. I'll start prepping that today. I'll hold off reposting
>> until I have your comments on 19-25. I'm also hoping that David will repost the
>> zap series today so that it can get into mm-unstable by mid-next week. Then I'll
>> repost on top of that, hopefully by end of next week, folding in all your
>> comments. This should give planty of time to soak in linux-next.
> 
> Just sent out v2. Will review this series (early) next week.
> 
> Have a great weekend!

Cheers, David - you too!

> 



From keescook at chromium.org  Fri Feb  9 16:20:11 2024
From: keescook at chromium.org (Kees Cook)
Date: Fri, 9 Feb 2024 16:20:11 -0800
Subject: [PATCH] irqchip/irq-bcm7038-l1: Prefer struct_size over open
 coded arithmetic
In-Reply-To: <20240209183128.10273-1-erick.archer@gmx.com>
References: <20240209183128.10273-1-erick.archer@gmx.com>
Message-ID: <202402091620.006E59FF9@keescook>

On Fri, Feb 09, 2024 at 07:31:28PM +0100, Erick Archer wrote:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> As the cpu variable is a pointer to "struct bcm7038_l1_cpu" and this
> structure ends in a flexible array:
> 
> struct bcm7038_l1_cpu {
> 	void __iomem	*map_base;
> 	u32		mask_cache[];
> };
> 
> the preferred way in the kernel is to use the struct_size() helper to
> do the arithmetic instead of the argument "size + count * size" in the
> kzalloc() function.
> 
> This way, the code is more readable and more safer.
> 
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
> Link: https://github.com/KSPP/linux/issues/162 [2]
> 
> Signed-off-by: Erick Archer <erick.archer at gmx.com>

Yeah, looks right to me.

Reviewed-by: Kees Cook <keescook at chromium.org>

-- 
Kees Cook


From florian.fainelli at broadcom.com  Fri Feb  9 17:21:13 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Fri, 9 Feb 2024 17:21:13 -0800
Subject: [PATCH] irqchip/irq-bcm7038-l1: Prefer struct_size over open
 coded arithmetic
In-Reply-To: <20240209183128.10273-1-erick.archer@gmx.com>
References: <20240209183128.10273-1-erick.archer@gmx.com>
Message-ID: <cbf50038-4124-484d-b045-9090c5f9ab06@broadcom.com>



On 2/9/2024 10:31 AM, Erick Archer wrote:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> As the cpu variable is a pointer to "struct bcm7038_l1_cpu" and this
> structure ends in a flexible array:
> 
> struct bcm7038_l1_cpu {
> 	void __iomem	*map_base;
> 	u32		mask_cache[];
> };
> 
> the preferred way in the kernel is to use the struct_size() helper to
> do the arithmetic instead of the argument "size + count * size" in the
> kzalloc() function.
> 
> This way, the code is more readable and more safer.
> 
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
> Link: https://github.com/KSPP/linux/issues/162 [2]
> 
> Signed-off-by: Erick Archer <erick.archer at gmx.com>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240209/b502a30c/attachment.p7s>

From sre at kernel.org  Fri Feb  9 17:18:05 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:05 +0100
Subject: [PATCH v1 01/14] dt-bindings: pinctrl: fsl,imx6ul-pinctrl: convert to YAML
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-2-sre@kernel.org>

Convert i.MX6UL pinctrl bindings to YAML.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt   |  37 ------
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.yaml  | 116 ++++++++++++++++++
 2 files changed, 116 insertions(+), 37 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
deleted file mode 100644
index 7ca4f6118d9a..000000000000
--- a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-* Freescale i.MX6 UltraLite IOMUX Controller
-
-Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
-and usage.
-
-Required properties:
-- compatible: "fsl,imx6ul-iomuxc" for main IOMUX controller or
-  "fsl,imx6ull-iomuxc-snvs" for i.MX 6ULL's SNVS IOMUX controller.
-- fsl,pins: each entry consists of 6 integers and represents the mux and config
-  setting for one pin.  The first 5 integers <mux_reg conf_reg input_reg mux_val
-  input_val> are specified using a PIN_FUNC_ID macro, which can be found in
-  imx6ul-pinfunc.h under device tree source folder.  The last integer CONFIG is
-  the pad setting value like pull-up on this pin.  Please refer to i.MX6 UltraLite
-  Reference Manual for detailed CONFIG settings.
-
-CONFIG bits definition:
-PAD_CTL_HYS                     (1 << 16)
-PAD_CTL_PUS_100K_DOWN           (0 << 14)
-PAD_CTL_PUS_47K_UP              (1 << 14)
-PAD_CTL_PUS_100K_UP             (2 << 14)
-PAD_CTL_PUS_22K_UP              (3 << 14)
-PAD_CTL_PUE                     (1 << 13)
-PAD_CTL_PKE                     (1 << 12)
-PAD_CTL_ODE                     (1 << 11)
-PAD_CTL_SPEED_LOW               (0 << 6)
-PAD_CTL_SPEED_MED               (1 << 6)
-PAD_CTL_SPEED_HIGH              (3 << 6)
-PAD_CTL_DSE_DISABLE             (0 << 3)
-PAD_CTL_DSE_260ohm              (1 << 3)
-PAD_CTL_DSE_130ohm              (2 << 3)
-PAD_CTL_DSE_87ohm               (3 << 3)
-PAD_CTL_DSE_65ohm               (4 << 3)
-PAD_CTL_DSE_52ohm               (5 << 3)
-PAD_CTL_DSE_43ohm               (6 << 3)
-PAD_CTL_DSE_37ohm               (7 << 3)
-PAD_CTL_SRE_FAST                (1 << 0)
-PAD_CTL_SRE_SLOW                (0 << 0)
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
new file mode 100644
index 000000000000..906b264a9e3c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
@@ -0,0 +1,116 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/fsl,imx6ul-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale IMX6UL IOMUX Controller
+
+maintainers:
+  - Dong Aisheng <aisheng.dong at nxp.com>
+
+description:
+  Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
+  for common binding part and usage.
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx6ul-iomuxc
+      - fsl,imx6ull-iomuxc-snvs
+
+  reg:
+    maxItems: 1
+
+# Client device subnode's properties
+patternProperties:
+  'grp$':
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+
+    properties:
+      fsl,pins:
+        description:
+          each entry consists of 6 integers and represents the mux and config
+          setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
+          mux_val input_val> are specified using a PIN_FUNC_ID macro, which can
+          be found in <arch/arm/boot/dts/imx6ul-pinfunc.h>. The last integer
+          CONFIG is the pad setting value like pull-up on this pin. Please
+          refer to i.MX6UL Reference Manual for detailed CONFIG settings.
+        $ref: /schemas/types.yaml#/definitions/uint32-matrix
+        items:
+          items:
+            - description: |
+                "mux_reg" indicates the offset of mux register.
+            - description: |
+                "conf_reg" indicates the offset of pad configuration register.
+            - description: |
+                "input_reg" indicates the offset of select input register.
+            - description: |
+                "mux_val" indicates the mux value to be applied.
+            - description: |
+                "input_val" indicates the select input value to be applied.
+            - description: |
+                "pad_setting" indicates the pad configuration value to be applied:
+                  PAD_CTL_HYS                     (1 << 16)
+                  PAD_CTL_PUS_100K_DOWN           (0 << 14)
+                  PAD_CTL_PUS_47K_UP              (1 << 14)
+                  PAD_CTL_PUS_100K_UP             (2 << 14)
+                  PAD_CTL_PUS_22K_UP              (3 << 14)
+                  PAD_CTL_PUE                     (1 << 13)
+                  PAD_CTL_PKE                     (1 << 12)
+                  PAD_CTL_ODE                     (1 << 11)
+                  PAD_CTL_SPEED_LOW               (0 << 6)
+                  PAD_CTL_SPEED_MED               (1 << 6)
+                  PAD_CTL_SPEED_HIGH              (3 << 6)
+                  PAD_CTL_DSE_DISABLE             (0 << 3)
+                  PAD_CTL_DSE_260ohm              (1 << 3)
+                  PAD_CTL_DSE_130ohm              (2 << 3)
+                  PAD_CTL_DSE_87ohm               (3 << 3)
+                  PAD_CTL_DSE_65ohm               (4 << 3)
+                  PAD_CTL_DSE_52ohm               (5 << 3)
+                  PAD_CTL_DSE_43ohm               (6 << 3)
+                  PAD_CTL_DSE_37ohm               (7 << 3)
+                  PAD_CTL_SRE_FAST                (1 << 0)
+                  PAD_CTL_SRE_SLOW                (0 << 0)
+
+    required:
+      - fsl,pins
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    iomuxc: pinctrl at 20e0000 {
+      compatible = "fsl,imx6ul-iomuxc";
+      reg = <0x020e0000 0x4000>;
+
+      mux_uart: uartgrp {
+        fsl,pins = <
+          0x0084 0x0310 0x0000 0 0 0x1b0b1
+          0x0088 0x0314 0x0624 0 3 0x1b0b1
+        >;
+      };
+    };
+  - |
+    iomuxc_snvs: pinctrl at 2290000 {
+      compatible = "fsl,imx6ull-iomuxc-snvs";
+      reg = <0x02290000 0x4000>;
+
+      pinctrl_snvs_usbc_det: snvsusbcdetgrp {
+        fsl,pins = <
+          0x0010 0x0054 0x0000 0x5 0x0 0x130b0
+        >;
+      };
+    };
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:08 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:08 +0100
Subject: [PATCH v1 04/14] dt-bindings: input: touchscreen: fsl,imx6ul-tsc convert to YAML
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-5-sre@kernel.org>

Convert the i.MX6UL touchscreen DT binding to YAML.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../input/touchscreen/fsl,imx6ul-tsc.yaml     | 92 +++++++++++++++++++
 .../bindings/input/touchscreen/imx6ul_tsc.txt | 38 --------
 2 files changed, 92 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
 delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml b/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
new file mode 100644
index 000000000000..db18f24978b1
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.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/fsl,imx6ul-tsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX6UL Touch Controller
+
+maintainers:
+  - Haibo Chen <haibo.chen at nxp.com>
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+properties:
+  compatible:
+    const: fsl,imx6ul-tsc
+
+  reg:
+    items:
+      - description: touch controller address
+      - description: ADC2 address
+
+  interrupts:
+    items:
+      - description: touch controller address
+      - description: ADC2 address
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: tsc
+      - const: adc
+
+  xnur-gpio:
+    description:
+      The X- gpio this controller connect to. This xnur-gpio returns to
+      low once the finger leave the touch screen (The last touch event
+      the touch controller capture).
+
+  measure-delay-time:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      The value of measure delay time. Before X-axis or Y-axis measurement,
+      the screen need some time before even potential distribution ready.
+    default: 0xffff
+    minimum: 0
+    maximum: 0xffffff
+
+  pre-charge-time:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      The touch screen need some time to precharge.
+    default: 0xfff
+    minimum: 0
+    maximum: 0xffffffff
+
+  touchscreen-average-samples:
+    description: Number of data samples which are averaged for each read.
+    enum: [ 1, 4, 8, 16, 32 ]
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - xnur-gpio
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/imx6ul-clock.h>
+    #include <dt-bindings/gpio/gpio.h>
+    tsc: tsc at 2040000 {
+        compatible = "fsl,imx6ul-tsc";
+        reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
+        interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX6UL_CLK_IPG>,
+                 <&clks IMX6UL_CLK_ADC2>;
+        clock-names = "tsc", "adc";
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_tsc>;
+        xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+        measure-delay-time = <0xfff>;
+        pre-charge-time = <0xffff>;
+        touchscreen-average-samples = <32>;
+    };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
deleted file mode 100644
index 164915004424..000000000000
--- a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-* Freescale i.MX6UL Touch Controller
-
-Required properties:
-- compatible: must be "fsl,imx6ul-tsc".
-- reg: this touch controller address and the ADC2 address.
-- interrupts: the interrupt of this touch controller and ADC2.
-- clocks: the root clock of touch controller and ADC2.
-- clock-names; must be "tsc" and "adc".
-- xnur-gpio: the X- gpio this controller connect to.
-  This xnur-gpio returns to low once the finger leave the touch screen (The
-  last touch event the touch controller capture).
-
-Optional properties:
-- measure-delay-time: the value of measure delay time.
-  Before X-axis or Y-axis measurement, the screen need some time before
-  even potential distribution ready.
-  This value depends on the touch screen.
-- pre-charge-time: the touch screen need some time to precharge.
-  This value depends on the touch screen.
-- touchscreen-average-samples: Number of data samples which are averaged for
-  each read. Valid values are 1, 4, 8, 16 and 32.
-
-Example:
-	tsc: tsc at 2040000 {
-		compatible = "fsl,imx6ul-tsc";
-		reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
-		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clks IMX6UL_CLK_IPG>,
-			 <&clks IMX6UL_CLK_ADC2>;
-		clock-names = "tsc", "adc";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_tsc>;
-		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
-		measure-delay-time = <0xfff>;
-		pre-charge-time = <0xffff>;
-		touchscreen-average-samples = <32>;
-	};
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:04 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:04 +0100
Subject: [PATCH v1 00/14] UNI-T UTi260B support
Message-ID: <20240210012114.489102-1-sre@kernel.org>

From: Sebastian Reichel <sebastian.reichel at collabora.com>

Hi,

This adds adds support for the UNI-T UTi260B thermal camera, which is
based on i.MX6ULL. Patches 1-11 clean up all warnings reported by
CHECK_DTBS for i.MX6ULL (i.e. for an empty board). They are not specific
to the UTi260B and in fact that machine has most of the IP handled by
these patches marked as disabled. Then patches 12+13 introduce the vendor
and board compatible DT bindings. Finally the last patches adds support
for the thermal camera itself.

The DT is based on reverse engineered information. More information about
the device can be found in this presentation from Embedded Recipes 2023:

 * https://embedded-recipes.org/2023/wp-content/uploads/2023/10/Running-FOSS-on-a-Thermal-Camera-Sebastian-Reichel-compressed.pdf
 * https://www.youtube.com/watch?v=uvObsCG-Cqo

I also prepared a branch with these patches (and a minimal kernel config)
and published it here:

https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/log/?h=uti260b

Greetings,

-- Sebastian

Sebastian Reichel (14):
  dt-bindings: pinctrl: fsl,imx6ul-pinctrl: convert to YAML
  dt-bindings: bus: imx-weim: convert to YAML
  dt-bindings: sound: fsl,imx-asrc: convert to YAML
  dt-bindings: input: touchscreen: fsl,imx6ul-tsc convert to YAML
  dt-bindings: soc: imx: fsl,imx-anatop: add binding
  dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add imx6
  dt-bindings: lcdif: Do not require power-domains for i.MX6ULL
  dt-bindings: fsl-imx-sdma: fix HDMI audio index
  ARM: dts: imx6ull: fix pinctrl node name
  ARM: dts: imx6ul: Remove fsl,anatop from usbotg1
  ARM: dts: imx6ul: add missing #thermal-sensor-cells
  dt-bindings: vendor-prefixes: add UNI-T
  dt-bindings: arm: add UNI-T UTi260b
  ARM: dts: imx6ull-uti260b: Add board

 .../devicetree/bindings/arm/fsl.yaml          |   1 +
 .../devicetree/bindings/bus/fsl,imx-weim.yaml | 225 +++++++
 .../devicetree/bindings/bus/imx-weim.txt      | 117 ----
 .../bindings/display/fsl,lcdif.yaml           |   8 +-
 .../devicetree/bindings/dma/fsl,imx-sdma.yaml |   3 +-
 .../input/touchscreen/fsl,imx6ul-tsc.yaml     |  92 +++
 .../bindings/input/touchscreen/imx6ul_tsc.txt |  38 --
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt   |  37 --
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.yaml  | 116 ++++
 .../bindings/soc/imx/fsl,imx-anatop.yaml      | 125 ++++
 .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml  |  18 +
 .../devicetree/bindings/sound/fsl,asrc.txt    |  80 ---
 .../bindings/sound/fsl,imx-asrc.yaml          | 159 +++++
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm/boot/dts/nxp/imx/Makefile            |   1 +
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi         |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts | 564 ++++++++++++++++++
 arch/arm/boot/dts/nxp/imx/imx6ull.dtsi        |   2 +-
 18 files changed, 1314 insertions(+), 276 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
 delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
 delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
 delete mode 100644 Documentation/devicetree/bindings/sound/fsl,asrc.txt
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts

-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:11 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:11 +0100
Subject: [PATCH v1 07/14] dt-bindings: lcdif: Do not require power-domains for i.MX6ULL
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-8-sre@kernel.org>

i.MX6UL(L) uses "fsl,imx6sx-lcdif" as fallback compatible string,
but has only very lightweight DISPLAY power domain. Its DISPLAY
power domain is not supported by the binding / Linux kernel at
the moment. Since the current setup is working, let's remove the
power-domain from being required for that platform to fix the warning
printed by CHECK_DTBS=y.

Fixes: f62678a77d58 ("dt-bindings: mxsfb: Document i.MX8M/i.MX6SX/i.MX6SL power-domains property")
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/display/fsl,lcdif.yaml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
index 1c2be8d6f633..0681fc49aa1b 100644
--- a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
+++ b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
@@ -120,13 +120,19 @@ allOf:
           maxItems: 1
         clock-names:
           maxItems: 1
+  - if:
+      properties:
+        compatible:
+          const: fsl,imx6sx-lcdif
+    then:
+      required:
+        - power-domains
   - if:
       properties:
         compatible:
           contains:
             enum:
               - fsl,imx6sl-lcdif
-              - fsl,imx6sx-lcdif
               - fsl,imx8mm-lcdif
               - fsl,imx8mn-lcdif
               - fsl,imx8mp-lcdif
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:13 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:13 +0100
Subject: [PATCH v1 09/14] ARM: dts: imx6ull: fix pinctrl node name
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-10-sre@kernel.org>

pinctrl node name must be either pinctrl or pinmux.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ull.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
index 2bccd45e9fc2..8a1776067ecc 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
@@ -75,7 +75,7 @@ rngb: rng at 2284000 {
 				clocks = <&clks IMX6UL_CLK_DUMMY>;
 			};
 
-			iomuxc_snvs: iomuxc-snvs at 2290000 {
+			iomuxc_snvs: pinctrl at 2290000 {
 				compatible = "fsl,imx6ull-iomuxc-snvs";
 				reg = <0x02290000 0x4000>;
 			};
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:07 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:07 +0100
Subject: [PATCH v1 03/14] dt-bindings: sound: fsl,imx-asrc: convert to YAML
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-4-sre@kernel.org>

Convert the i.MX ASRC DT binding to YAML.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../devicetree/bindings/sound/fsl,asrc.txt    |  80 ---------
 .../bindings/sound/fsl,imx-asrc.yaml          | 159 ++++++++++++++++++
 2 files changed, 159 insertions(+), 80 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/sound/fsl,asrc.txt
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
deleted file mode 100644
index 998b4c8a7f78..000000000000
--- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-Freescale Asynchronous Sample Rate Converter (ASRC) Controller
-
-The Asynchronous Sample Rate Converter (ASRC) converts the sampling rate of a
-signal associated with an input clock into a signal associated with a different
-output clock. The driver currently works as a Front End of DPCM with other Back
-Ends Audio controller such as ESAI, SSI and SAI. It has three pairs to support
-three substreams within totally 10 channels.
-
-Required properties:
-
-  - compatible		: Compatible list, should contain one of the following
-			  compatibles:
-			  "fsl,imx35-asrc",
-			  "fsl,imx53-asrc",
-			  "fsl,imx8qm-asrc",
-			  "fsl,imx8qxp-asrc",
-
-  - reg			: Offset and length of the register set for the device.
-
-  - interrupts		: Contains the spdif interrupt.
-
-  - dmas		: Generic dma devicetree binding as described in
-			  Documentation/devicetree/bindings/dma/dma.txt.
-
-  - dma-names		: Contains "rxa", "rxb", "rxc", "txa", "txb" and "txc".
-
-  - clocks		: Contains an entry for each entry in clock-names.
-
-  - clock-names		: Contains the following entries
-	"mem"		  Peripheral access clock to access registers.
-	"ipg"		  Peripheral clock to driver module.
-	"asrck_<0-f>"	  Clock sources for input and output clock.
-	"spba"		  The spba clock is required when ASRC is placed as a
-			  bus slave of the Shared Peripheral Bus and when two
-			  or more bus masters (CPU, DMA or DSP) try to access
-			  it. This property is optional depending on the SoC
-			  design.
-
-   - fsl,asrc-rate	: Defines a mutual sample rate used by DPCM Back Ends.
-
-   - fsl,asrc-width	: Defines a mutual sample width used by DPCM Back Ends.
-
-   - fsl,asrc-clk-map   : Defines clock map used in driver. which is required
-			  by imx8qm/imx8qxp platform
-			  <0> - select the map for asrc0 in imx8qm/imx8qxp
-			  <1> - select the map for asrc1 in imx8qm/imx8qxp
-
-Optional properties:
-
-   - big-endian		: If this property is absent, the little endian mode
-			  will be in use as default. Otherwise, the big endian
-			  mode will be in use for all the device registers.
-
-   - fsl,asrc-format	: Defines a mutual sample format used by DPCM Back
-			  Ends, which can replace the fsl,asrc-width.
-			  The value is 2 (S16_LE), or 6 (S24_LE).
-
-Example:
-
-asrc: asrc at 2034000 {
-	compatible = "fsl,imx53-asrc";
-	reg = <0x02034000 0x4000>;
-	interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
-	clocks = <&clks 107>, <&clks 107>, <&clks 0>,
-	       <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
-	       <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
-	       <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
-	       <&clks 107>, <&clks 0>, <&clks 0>;
-	clock-names = "mem", "ipg", "asrck0",
-		"asrck_1", "asrck_2", "asrck_3", "asrck_4",
-		"asrck_5", "asrck_6", "asrck_7", "asrck_8",
-		"asrck_9", "asrck_a", "asrck_b", "asrck_c",
-		"asrck_d", "asrck_e", "asrck_f";
-	dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
-	     <&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
-	dma-names = "rxa", "rxb", "rxc",
-		"txa", "txb", "txc";
-	fsl,asrc-rate  = <48000>;
-	fsl,asrc-width = <16>;
-};
diff --git a/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml
new file mode 100644
index 000000000000..bc1607ecf345
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml
@@ -0,0 +1,159 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,imx-asrc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale Asynchronous Sample Rate Converter (ASRC) Controller
+
+description:
+  The Asynchronous Sample Rate Converter (ASRC) converts the sampling rate of
+  a signal associated with an input clock into a signal associated with a
+  different output clock. The driver currently works as a Front End of DPCM
+  with other Back Ends Audio controller such as ESAI, SSI and SAI. It has
+  three pairs to support three substreams within totally 10 channels.
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - fsl,imx35-asrc
+          - fsl,imx53-asrc
+          - fsl,imx8qm-asrc
+          - fsl,imx8qxp-asrc
+      - items:
+          - enum:
+              - fsl,imx6sx-asrc
+              - fsl,imx6ul-asrc
+          - const: fsl,imx53-asrc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  dmas:
+    maxItems: 6
+
+  dma-names:
+    items:
+      - const: rxa
+      - const: rxb
+      - const: rxc
+      - const: txa
+      - const: txb
+      - const: txc
+
+  clocks:
+    maxItems: 19
+
+  clock-names:
+    items:
+      - const: mem
+      - const: ipg
+      - const: asrck_0
+      - const: asrck_1
+      - const: asrck_2
+      - const: asrck_3
+      - const: asrck_4
+      - const: asrck_5
+      - const: asrck_6
+      - const: asrck_7
+      - const: asrck_8
+      - const: asrck_9
+      - const: asrck_a
+      - const: asrck_b
+      - const: asrck_c
+      - const: asrck_d
+      - const: asrck_e
+      - const: asrck_f
+      - const: spba
+
+  fsl,asrc-rate:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: The mutual sample rate used by DPCM Back Ends
+
+  fsl,asrc-width:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: The mutual sample width used by DPCM Back Ends
+
+  fsl,asrc-clk-map:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines clock map used in driver
+      <0> - select the map for asrc0 in imx8qm/imx8qxp
+      <1> - select the map for asrc1 in imx8qm/imx8qxp
+
+  big-endian:
+    type: boolean
+    description:
+      If this property is absent, the little endian mode will be in use as
+      default. Otherwise, the big endian mode will be in use for all the
+      device registers.
+
+  fsl,asrc-format:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines a mutual sample format used by DPCM Back Ends, which can
+      replace the fsl,asrc-width. The value is 2 (S16_LE), or 6 (S24_LE).
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - dmas
+  - dma-names
+  - clocks
+  - clock-names
+  - fsl,asrc-rate
+  - fsl,asrc-width
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx8qm-asrc
+              - fsl,imx8qxp-asrc
+    then:
+      required:
+        - fsl,asrc-clk-map
+    else:
+      properties:
+        fsl,asrc-clk-map: false
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/imx6qdl-clock.h>
+    asrc: asrc at 2034000 {
+        compatible = "fsl,imx53-asrc";
+        reg = <0x02034000 0x4000>;
+        interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX6QDL_CLK_ASRC_IPG>,
+                 <&clks IMX6QDL_CLK_ASRC_MEM>, <&clks 0>,
+                 <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+                 <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+                 <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+                 <&clks IMX6QDL_CLK_ASRC>, <&clks 0>, <&clks 0>,
+                 <&clks IMX6QDL_CLK_SPBA>;
+        clock-names = "mem", "ipg", "asrck_0",
+                "asrck_1", "asrck_2", "asrck_3", "asrck_4",
+                "asrck_5", "asrck_6", "asrck_7", "asrck_8",
+                "asrck_9", "asrck_a", "asrck_b", "asrck_c",
+                "asrck_d", "asrck_e", "asrck_f", "spba";
+        dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
+               <&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
+        dma-names = "rxa", "rxb", "rxc",
+                    "txa", "txb", "txc";
+        fsl,asrc-rate  = <48000>;
+        fsl,asrc-width = <16>;
+    };
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:06 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:06 +0100
Subject: [PATCH v1 02/14] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-3-sre@kernel.org>

Convert the i.MX  Wireless External Interface Module binding to YAML.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../devicetree/bindings/bus/fsl,imx-weim.yaml | 225 ++++++++++++++++++
 .../devicetree/bindings/bus/imx-weim.txt      | 117 ---------
 2 files changed, 225 insertions(+), 117 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
 delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt

diff --git a/Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml b/Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
new file mode 100644
index 000000000000..3d27bdaef304
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
@@ -0,0 +1,225 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bus/fsl,imx-weim.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX Wireless External Interface Module (WEIM)
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+description:
+  The term "wireless" does not imply that the WEIM is literally an interface
+  without wires. It simply means that this module was originally designed for
+  wireless and mobile applications that use low-power technology. The actual
+  devices are instantiated from the child nodes of a WEIM node.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - fsl,imx1-weim
+          - fsl,imx27-weim
+          - fsl,imx50-weim
+          - fsl,imx51-weim
+          - fsl,imx6q-weim
+      - items:
+          - enum:
+              - fsl,imx31-weim
+              - fsl,imx35-weim
+          - const: fsl,imx27-weim
+      - items:
+          - enum:
+              - fsl,imx6sx-weim
+              - fsl,imx6ul-weim
+          - const: fsl,imx6q-weim
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  '#address-cells':
+    const: 2
+
+  '#size-cells':
+    const: 1
+
+  ranges: true
+
+  fsl,weim-cs-gpr:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Phandle to the system General Purpose Register controller that contains
+      WEIM CS GPR register, e.g. IOMUXC_GPR1 on i.MX6Q. IOMUXC_GPR1[11:0]
+      should be set up as one of the following 4 possible values depending on
+      the CS space configuration.
+
+      IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
+      ---------------------------------------------
+              05          128M     0M     0M     0M
+              033          64M    64M     0M     0M
+              0113         64M    32M    32M     0M
+              01111        32M    32M    32M    32M
+
+      In case that the property is absent, the reset value or what bootloader
+      sets up in IOMUXC_GPR1[11:0] will be used.
+
+  fsl,burst-clk-enable:
+    type: boolean
+    description:
+      The presence of this property indicates that the weim bus should operate
+      in Burst Clock Mode.
+
+  fsl,continuous-burst-clk:
+    type: boolean
+    description:
+      Make Burst Clock to output continuous clock. Without this option Burst
+      Clock will output clock only when necessary.
+
+patternProperties:
+  "^.*@[0-7],[0-9a-f]+$":
+    description: Devices attached to chip selects are represented as subnodes.
+    type: object
+    additionalProperties: true
+    properties:
+      fsl,weim-cs-timing:
+        $ref: /schemas/types.yaml#/definitions/uint32-array
+        description:
+          Timing values for the child node.
+    required:
+      - fsl,weim-cs-timing
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          not:
+            contains:
+              enum:
+                - fsl,imx50-weim
+                - fsl,imx6q-weim
+    then:
+      properties:
+        fsl,weim-cs-gpr: false
+        fsl,burst-clk-enable: false
+  - if:
+      properties:
+        fsl,burst-clk-enable: false
+    then:
+      properties:
+        fsl,continuous-burst-clk: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx1-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSxU
+                  - description: CSxL
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx27-weim
+              - fsl,imx31-weim
+              - fsl,imx35-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSCRxU
+                  - description: CSCRxL
+                  - description: CSCRxA
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx50-weim
+              - fsl,imx51-weim
+              - fsl,imx6q-weim
+              - fsl,imx6sx-weim
+              - fsl,imx6ul-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSxGCR1
+                  - description: CSxGCR2
+                  - description: CSxRCR1
+                  - description: CSxRCR2
+                  - description: CSxWCR1
+                  - description: CSxWCR2
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#address-cells'
+  - '#size-cells'
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    weim at 21b8000 {
+        compatible = "fsl,imx6q-weim";
+        reg = <0x021b8000 0x4000>;
+        clocks = <&clks 196>;
+        #address-cells = <2>;
+        #size-cells = <1>;
+        ranges = <0 0 0x08000000 0x08000000>;
+        fsl,weim-cs-gpr = <&gpr>;
+
+        nor at 0,0 {
+            compatible = "cfi-flash";
+            reg = <0 0 0x02000000>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            bank-width = <2>;
+            fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
+            0x0000c000 0x1404a38e 0x00000000>;
+        };
+    };
+  - |
+    weim at 21b8000 {
+        compatible = "fsl,imx6q-weim";
+        reg = <0x021b8000 0x4000>;
+        clocks = <&clks 196>;
+        #address-cells = <2>;
+        #size-cells = <1>;
+        ranges = <0 0 0x08000000 0x02000000
+                  1 0 0x0a000000 0x02000000
+                  2 0 0x0c000000 0x02000000
+                  3 0 0x0e000000 0x02000000>;
+        fsl,weim-cs-gpr = <&gpr>;
+
+        acme at 0,0 {
+            compatible = "acme,whatever";
+            reg = <0 0 0x100>, <0 0x400000 0x800>,
+                  <1 0x400000 0x800>;
+            fsl,weim-cs-timing = <0x024400b1 0x00001010 0x20081100
+                                  0x00000000 0xa0000240 0x00000000>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/bus/imx-weim.txt b/Documentation/devicetree/bindings/bus/imx-weim.txt
deleted file mode 100644
index e7f502070d77..000000000000
--- a/Documentation/devicetree/bindings/bus/imx-weim.txt
+++ /dev/null
@@ -1,117 +0,0 @@
-Device tree bindings for i.MX Wireless External Interface Module (WEIM)
-
-The term "wireless" does not imply that the WEIM is literally an interface
-without wires. It simply means that this module was originally designed for
-wireless and mobile applications that use low-power technology.
-
-The actual devices are instantiated from the child nodes of a WEIM node.
-
-Required properties:
-
- - compatible:		Should contain one of the following:
-			  "fsl,imx1-weim"
-			  "fsl,imx27-weim"
-			  "fsl,imx51-weim"
-			  "fsl,imx50-weim"
-			  "fsl,imx6q-weim"
- - reg:			A resource specifier for the register space
-			(see the example below)
- - clocks:		the clock, see the example below.
- - #address-cells:	Must be set to 2 to allow memory address translation
- - #size-cells:		Must be set to 1 to allow CS address passing
- - ranges:		Must be set up to reflect the memory layout with four
-			integer values for each chip-select line in use:
-
-			   <cs-number> 0 <physical address of mapping> <size>
-
-Optional properties:
-
- - fsl,weim-cs-gpr:	For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
-			devices, it should be the phandle to the system General
-			Purpose Register controller that contains WEIM CS GPR
-			register, e.g. IOMUXC_GPR1 on i.MX6Q.  IOMUXC_GPR1[11:0]
-			should be set up as one of the following 4 possible
-			values depending on the CS space configuration.
-
-			IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
-			---------------------------------------------
-				05	    128M     0M     0M     0M
-				033          64M    64M     0M     0M
-				0113         64M    32M    32M     0M
-				01111        32M    32M    32M    32M
-
-			In case that the property is absent, the reset value or
-			what bootloader sets up in IOMUXC_GPR1[11:0] will be
-			used.
-
- - fsl,burst-clk-enable	For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
-			devices, the presence of this property indicates that
-			the weim bus should operate in Burst Clock Mode.
-
- - fsl,continuous-burst-clk	Make Burst Clock to output continuous clock.
-			Without this option Burst Clock will output clock
-			only when necessary. This takes effect only if
-			"fsl,burst-clk-enable" is set.
-
-Timing property for child nodes. It is mandatory, not optional.
-
- - fsl,weim-cs-timing:	The timing array, contains timing values for the
-			child node. We get the CS indexes from the address
-			ranges in the child node's "reg" property.
-			The number of registers depends on the selected chip:
-			For i.MX1, i.MX21 ("fsl,imx1-weim") there are two
-			registers: CSxU, CSxL.
-			For i.MX25, i.MX27, i.MX31 and i.MX35 ("fsl,imx27-weim")
-			there are three registers: CSCRxU, CSCRxL, CSCRxA.
-			For i.MX50, i.MX53 ("fsl,imx50-weim"),
-			i.MX51 ("fsl,imx51-weim") and i.MX6Q ("fsl,imx6q-weim")
-			there are six registers: CSxGCR1, CSxGCR2, CSxRCR1,
-			CSxRCR2, CSxWCR1, CSxWCR2.
-
-Example for an imx6q-sabreauto board, the NOR flash connected to the WEIM:
-
-	weim: weim at 21b8000 {
-		compatible = "fsl,imx6q-weim";
-		reg = <0x021b8000 0x4000>;
-		clocks = <&clks 196>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x08000000>;
-		fsl,weim-cs-gpr = <&gpr>;
-
-		nor at 0,0 {
-			compatible = "cfi-flash";
-			reg = <0 0 0x02000000>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			bank-width = <2>;
-			fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
-					0x0000c000 0x1404a38e 0x00000000>;
-		};
-	};
-
-Example for an imx6q-based board, a multi-chipselect device connected to WEIM:
-
-In this case, both chip select 0 and 1 will be configured with the same timing
-array values.
-
-	weim: weim at 21b8000 {
-		compatible = "fsl,imx6q-weim";
-		reg = <0x021b8000 0x4000>;
-		clocks = <&clks 196>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x02000000
-			  1 0 0x0a000000 0x02000000
-			  2 0 0x0c000000 0x02000000
-			  3 0 0x0e000000 0x02000000>;
-		fsl,weim-cs-gpr = <&gpr>;
-
-		acme at 0 {
-			compatible = "acme,whatever";
-			reg = <0 0 0x100>, <0 0x400000 0x800>,
-				<1 0x400000 0x800>;
-			fsl,weim-cs-timing = <0x024400b1 0x00001010 0x20081100
-				0x00000000 0xa0000240 0x00000000>;
-		};
-	};
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:15 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:15 +0100
Subject: [PATCH v1 11/14] ARM: dts: imx6ul: add missing #thermal-sensor-cells
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-12-sre@kernel.org>

Fix the following warning found via CHECK_DTBS:

tempmon: '#thermal-sensor-cells' is a required property

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index 9eb4eee0c272..45b7605ac381 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -638,6 +638,7 @@ tempmon: tempmon {
 					nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
 					nvmem-cell-names = "calib", "temp_grade";
 					clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+					#thermal-sensor-cells = <0>;
 				};
 			};
 
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:17 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:17 +0100
Subject: [PATCH v1 13/14] dt-bindings: arm: add UNI-T UTi260b
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-14-sre@kernel.org>

Add compatible value for i.MX6ULL based UNI-T
UTi260b thermal camera.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 228dcc5c7d6f..fa20c2699530 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -708,6 +708,7 @@ properties:
               - toradex,colibri-imx6ull      # Colibri iMX6ULL Modules
               - toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module
               - toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Modules
+              - uni-t,imx6ull-uti260b   # UNI-T UTi260b
           - const: fsl,imx6ull
 
       - description: i.MX6ULL Armadeus Systems OPOS6ULDev Board
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:14 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:14 +0100
Subject: [PATCH v1 10/14] ARM: dts: imx6ul: Remove fsl,anatop from usbotg1
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-11-sre@kernel.org>

fsl,anatop should only be added to the usbphy nodes.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index a27a7554c2e7..9eb4eee0c272 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -855,7 +855,6 @@ usbotg1: usb at 2184000 {
 				clocks = <&clks IMX6UL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
-				fsl,anatop = <&anatop>;
 				ahb-burst-config = <0x0>;
 				tx-burst-size-dword = <0x10>;
 				rx-burst-size-dword = <0x10>;
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:12 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:12 +0100
Subject: [PATCH v1 08/14] dt-bindings: fsl-imx-sdma: fix HDMI audio index
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-9-sre@kernel.org>

HDMI Audio has been added to the DT binding documentation with an
incorrect index. DT and the driver use index 26. This happened,
because the binding is missing MULTI_SAI type, which is using
index 25.

Reported-by: Michael Yackavage <michaely at ips-yes.com>
Fixes: 7bdbd87d4008 ("dt-bindings: fsl-imx-sdma: Convert imx sdma to DT schema")
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml b/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
index b95dd8db5a30..37135fa024f9 100644
--- a/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
+++ b/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
@@ -92,7 +92,8 @@ properties:
               description: needs firmware more than ver 2
           - Shared ASRC: 23
           - SAI: 24
-          - HDMI Audio: 25
+          - Multi SAI: 25
+          - HDMI Audio: 26
 
        The third cell: transfer priority ID
          enum:
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:09 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:09 +0100
Subject: [PATCH v1 05/14] dt-bindings: soc: imx: fsl,imx-anatop: add binding
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-6-sre@kernel.org>

Add missing binding for i.MX anatop syscon.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/soc/imx/fsl,imx-anatop.yaml      | 125 ++++++++++++++++++
 1 file changed, 125 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
new file mode 100644
index 000000000000..436fdae1879e
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
@@ -0,0 +1,125 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/imx/fsl,imx-anatop.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ANATOP register
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - fsl,imx6sl-anatop
+              - fsl,imx6sll-anatop
+              - fsl,imx6sx-anatop
+              - fsl,imx6ul-anatop
+              - fsl,imx7d-anatop
+          - const: fsl,imx6q-anatop
+          - const: syscon
+          - const: simple-mfd
+      - items:
+          - const: fsl,imx6q-anatop
+          - const: syscon
+          - const: simple-mfd
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 3
+
+  tempmon:
+    type: object
+    unevaluatedProperties: false
+    $ref: /schemas/thermal/imx-thermal.yaml
+
+patternProperties:
+  "regulator-((3p0)|(vddcore)|(vddsoc))$":
+    type: object
+    unevaluatedProperties: false
+    $ref: /schemas/regulator/anatop-regulator.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx6ul-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    anatop: anatop at 20c8000 {
+        compatible = "fsl,imx6ul-anatop", "fsl,imx6q-anatop",
+                     "syscon", "simple-mfd";
+        reg = <0x020c8000 0x1000>;
+        interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+
+        reg_3p0: regulator-3p0 {
+            compatible = "fsl,anatop-regulator";
+                regulator-name = "vdd3p0";
+                regulator-min-microvolt = <2625000>;
+                regulator-max-microvolt = <3400000>;
+                anatop-reg-offset = <0x120>;
+                anatop-vol-bit-shift = <8>;
+                anatop-vol-bit-width = <5>;
+                anatop-min-bit-val = <0>;
+                anatop-min-voltage = <2625000>;
+                anatop-max-voltage = <3400000>;
+                anatop-enable-bit = <0>;
+        };
+
+        reg_arm: regulator-vddcore {
+            compatible = "fsl,anatop-regulator";
+                regulator-name = "cpu";
+                regulator-min-microvolt = <725000>;
+                regulator-max-microvolt = <1450000>;
+                regulator-always-on;
+                anatop-reg-offset = <0x140>;
+                anatop-vol-bit-shift = <0>;
+                anatop-vol-bit-width = <5>;
+                anatop-delay-reg-offset = <0x170>;
+                anatop-delay-bit-shift = <24>;
+                anatop-delay-bit-width = <2>;
+                anatop-min-bit-val = <1>;
+                anatop-min-voltage = <725000>;
+                anatop-max-voltage = <1450000>;
+        };
+
+        reg_soc: regulator-vddsoc {
+            compatible = "fsl,anatop-regulator";
+                regulator-name = "vddsoc";
+                regulator-min-microvolt = <725000>;
+                regulator-max-microvolt = <1450000>;
+                regulator-always-on;
+                anatop-reg-offset = <0x140>;
+                anatop-vol-bit-shift = <18>;
+                anatop-vol-bit-width = <5>;
+                anatop-delay-reg-offset = <0x170>;
+                anatop-delay-bit-shift = <28>;
+                anatop-delay-bit-width = <2>;
+                anatop-min-bit-val = <1>;
+                anatop-min-voltage = <725000>;
+                anatop-max-voltage = <1450000>;
+        };
+
+        tempmon: tempmon {
+            compatible = "fsl,imx6ul-tempmon", "fsl,imx6sx-tempmon";
+            interrupt-parent = <&gpc>;
+            interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+            fsl,tempmon = <&anatop>;
+            nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
+            nvmem-cell-names = "calib", "temp_grade";
+            clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+            #thermal-sensor-cells = <0>;
+        };
+    };
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:10 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:10 +0100
Subject: [PATCH v1 06/14] dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add imx6
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-7-sre@kernel.org>

Add compatibles used by different i.MX6 variants to the i.MX IOMUX
Controller GPR binding.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml   | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
index 1da1b758b4ae..6f229ffe20a5 100644
--- a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
@@ -16,6 +16,24 @@ description:
 properties:
   compatible:
     oneOf:
+      - items:
+          - const: fsl,imx6q-iomuxc-gpr
+          - const: syscon
+          - const: simple-mfd
+      - items:
+          - enum:
+              - fsl,imx6sl-iomuxc-gpr
+              - fsl,imx6sll-iomuxc-gpr
+              - fsl,imx6ul-iomuxc-gpr
+          - const: fsl,imx6q-iomuxc-gpr
+          - const: syscon
+      - items:
+          - enum:
+              - fsl,imx6sx-iomuxc-gpr
+              - fsl,imx7d-iomuxc-gpr
+          - const: fsl,imx6q-iomuxc-gpr
+          - const: syscon
+          - const: simple-mfd
       - items:
           - const: fsl,imx8mq-iomuxc-gpr
           - const: syscon
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:16 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:16 +0100
Subject: [PATCH v1 12/14] dt-bindings: vendor-prefixes: add UNI-T
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-13-sre@kernel.org>

Uni-Trend Technology is a manufacturer of measurement
and testing tools.

Signed-off-by: Sebastian Reichel <sre 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 1a0dc04f1db4..e945e76696c2 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1484,6 +1484,8 @@ patternProperties:
     description: Ufi Space Co., Ltd.
   "^ugoos,.*":
     description: Ugoos Industrial Co., Ltd.
+  "^uni-t,.*":
+    description: Uni-Trend Technology (China) Co., Ltd.
   "^uniwest,.*":
     description: United Western Technologies Corp (UniWest)
   "^upisemi,.*":
-- 
2.43.0



From sre at kernel.org  Fri Feb  9 17:18:18 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 10 Feb 2024 02:18:18 +0100
Subject: [PATCH v1 14/14] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <20240210012114.489102-1-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
Message-ID: <20240210012114.489102-15-sre@kernel.org>

Add UNI-T UTi260b thermal camera board.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/Makefile            |   1 +
 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts | 564 ++++++++++++++++++
 2 files changed, 565 insertions(+)
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts

diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile
index a724d1a7a9a0..47350cf3ddeb 100644
--- a/arch/arm/boot/dts/nxp/imx/Makefile
+++ b/arch/arm/boot/dts/nxp/imx/Makefile
@@ -349,6 +349,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
 	imx6ull-tarragon-slavext.dtb \
 	imx6ull-tqma6ull2-mba6ulx.dtb \
 	imx6ull-tqma6ull2l-mba6ulx.dtb \
+	imx6ull-uti260b.dtb \
 	imx6ulz-14x14-evk.dtb \
 	imx6ulz-bsh-smm-m2.dtb
 dtb-$(CONFIG_SOC_IMX7D) += \
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
new file mode 100644
index 000000000000..336727895fa4
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
@@ -0,0 +1,564 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright (C) 2022 Sebastian Reichel <sre at kernel.org>
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/clock/imx6ul-clock.h>
+
+/ {
+	model = "UNI-T UTi260B Thermal Camera";
+	compatible = "uni-t,imx6ull-uti260b", "fsl,imx6ull";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_led_ctrl>;
+
+		led {
+			label = "led";
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_gpio_keys>;
+		autorepeat;
+
+		up-key {
+			label = "Up";
+			gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_UP>;
+		};
+
+		down-key {
+			label = "Down";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_DOWN>;
+		};
+
+		left-key {
+			label = "Left";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_LEFT>;
+		};
+
+		right-key {
+			label = "Right";
+			gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RIGHT>;
+		};
+
+		ok-key {
+			label = "Ok";
+			gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_ENTER>;
+		};
+
+		return-key {
+			label = "Return";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_ESC>;
+		};
+
+		play-key {
+			label = "Media";
+			gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_MEDIA>;
+		};
+
+		trigger-key {
+			label = "Trigger";
+			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_TRIGGER>;
+		};
+
+		power-key {
+			label = "Power";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+
+		light-key {
+			label = "Light";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_LIGHTS_TOGGLE>;
+		};
+	};
+
+	panel_backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+		enable-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_backlight_enable>;
+		power-supply = <&reg_vsd>;
+		pwms = <&pwm1 0 50000 0>;
+	};
+
+	reg_vsd: regulator-vsd {
+		compatible = "regulator-fixed";
+		regulator-name = "VSD_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_vref: regulator-vref-4v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "VREF_4V2";
+		regulator-min-microvolt = <4200000>;
+		regulator-max-microvolt = <4200000>;
+	};
+
+	tp5000: charger {
+		compatible = "gpio-charger";
+		charger-type = "usb-sdp";
+		gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_charger_stat1>;
+	};
+
+	battery: battery {
+		compatible = "simple-battery";
+		/* generic 26650 battery */
+		device-chemistry = "lithium-ion";
+		charge-full-design-microamp-hours = <5000000>;
+		voltage-max-design-microvolt = <4200000>;
+		voltage-min-design-microvolt = <3300000>;
+	};
+
+	fuel-gauge {
+		compatible = "adc-battery";
+		charged-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		io-channel-names = "voltage";
+		io-channels = <&adc1 7>;
+		monitored-battery = <&battery>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_charger_stat2>;
+		power-supplies = <&tp5000>;
+	};
+
+	poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_poweroff>;
+	};
+};
+
+&gpio1 {
+	ir-reset-hog {
+		gpio-hog;
+		gpios = <3 GPIO_ACTIVE_LOW>;
+		line-name = "ir-reset-gpio";
+		output-low;
+		pinctrl-0 = <&mux_ir_reset>;
+	};
+};
+
+&gpio2 {
+	/* configuring this to output-high results in poweroff */
+	power-en-hog {
+		gpio-hog;
+		gpios = <6 GPIO_ACTIVE_HIGH>;
+		line-name = "power-en-gpio";
+		output-low;
+		pinctrl-0 = <&mux_poweroff2>;
+	};
+};
+
+&ecspi3 {
+	cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_spi3>, <&mux_spi3_cs>;
+	status = "okay";
+
+	panel at 0 {
+		compatible = "inanbo,t28cp45tn89-v17";
+		reg = <0>;
+		backlight = <&panel_backlight>;
+		power-supply = <&reg_vsd>;
+		spi-cpha;
+		spi-cpol;
+		spi-max-frequency = <100000>;
+		spi-rx-bus-width = <0>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&display_out>;
+			};
+		};
+	};
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_uart>;
+	status = "okay";
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_pwm>;
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_i2c1>;
+	status = "okay";
+
+	camera at 21 {
+		compatible = "galaxycore,gc0308";
+		reg = <0x21>;
+		clocks = <&clks IMX6UL_CLK_CSI>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_gc0308>;
+		powerdown-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+		vdd28-supply = <&reg_vsd>;
+
+		port {
+			gc0308_to_parallel: endpoint {
+				remote-endpoint = <&parallel_from_gc0308>;
+				bus-width = <8>;
+				data-shift = <2>; /* lines 9:2 are used */
+				hsync-active = <1>; /* active high */
+				vsync-active = <1>; /* active high */
+				data-active = <1>; /* active high */
+				pclk-sample = <1>; /* sample on rising edge */
+			};
+		};
+	};
+};
+
+&csi {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_csi>;
+
+	port {
+		parallel_from_gc0308: endpoint {
+			remote-endpoint = <&gc0308_to_parallel>;
+		};
+	};
+};
+
+&i2c2 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_i2c2>;
+	status = "okay";
+
+	rtc at 51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&lcdif {
+	assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_lcd_data>, <&mux_lcd_ctrl>;
+	status = "okay";
+
+	port {
+		display_out: endpoint {
+			remote-endpoint = <&panel_in>;
+		};
+	};
+};
+
+&usdhc1 {
+	cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+	keep-power-in-suspend;
+	no-1-8-v;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&mux_sdhc1>, <&mux_sdhc1_cd>;
+	pinctrl-1 = <&mux_sdhc1_100mhz>, <&mux_sdhc1_cd>;
+	pinctrl-2 = <&mux_sdhc1_200mhz>, <&mux_sdhc1_cd>;
+	wakeup-source;
+	vmmc-supply = <&reg_vsd>;
+	status = "okay";
+};
+
+&usdhc2 {
+	keep-power-in-suspend;
+	no-1-8-v;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_sdhc2>;
+	wakeup-source;
+	status = "okay";
+};
+
+&wdog1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_wdog>;
+};
+
+&adc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_adc>;
+	vref-supply = <&reg_vref>;
+	#io-channel-cells = <1>;
+	status = "okay";
+};
+
+&usbotg1 {
+	disable-over-current;
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbotg2 {
+	disable-over-current;
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy1 {
+	fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+	fsl,tx-d-cal = <106>;
+};
+
+&iomuxc {
+	mux_ir_reset: irresetgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03		0x3008
+		>;
+	};
+
+	mux_poweroff: poweroffgrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04		0x3008
+		>;
+	};
+
+	mux_poweroff2: poweroff2grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06		0x3008
+		>;
+	};
+
+	mux_charger_stat1: charger1grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01		0x3008
+		>;
+	};
+
+	mux_charger_stat2: charger2grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO02__GPIO1_IO02		0x3008
+		>;
+	};
+
+	mux_wdog: wdoggrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY		0x30b0
+		>;
+	};
+
+	mux_sdhc1_cd: sdhc1-cd-grp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_RTS_B__GPIO1_IO19		0x17059
+		>;
+	};
+
+	mux_sdhc1: sdhc1grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x17059
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x10071
+			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
+		>;
+	};
+
+	mux_sdhc1_100mhz: sdhc1-100mhz-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x170b9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x170b9
+			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
+		>;
+	};
+
+	mux_sdhc1_200mhz: sdhc1-200mhz-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x170f9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x170f9
+			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
+		>;
+	};
+
+	mux_sdhc2: sdhc2grp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_RE_B__USDHC2_CLK			0x10069
+			MX6UL_PAD_NAND_WE_B__USDHC2_CMD			0x17059
+			MX6UL_PAD_NAND_DATA00__USDHC2_DATA0		0x17059
+			MX6UL_PAD_NAND_DATA01__USDHC2_DATA1		0x17059
+			MX6UL_PAD_NAND_DATA02__USDHC2_DATA2		0x17059
+			MX6UL_PAD_NAND_DATA03__USDHC2_DATA3		0x17059
+			MX6UL_PAD_NAND_DATA04__USDHC2_DATA4		0x17059
+			MX6UL_PAD_NAND_DATA05__USDHC2_DATA5		0x17059
+			MX6UL_PAD_NAND_DATA06__USDHC2_DATA6		0x17059
+			MX6UL_PAD_NAND_DATA07__USDHC2_DATA7		0x17059
+		>;
+	};
+
+	mux_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6UL_PAD_UART4_TX_DATA__I2C1_SCL		0x4001b8b0
+			MX6UL_PAD_UART4_RX_DATA__I2C1_SDA		0x4001b8b0
+		>;
+	};
+
+	mux_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6UL_PAD_UART5_TX_DATA__I2C2_SCL		0x4001f8a8
+			MX6UL_PAD_UART5_RX_DATA__I2C2_SDA		0x4001f8a8
+		>;
+	};
+
+	mux_uart: uartgrp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX		0x1b0b1
+			MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX		0x1b0b1
+		>;
+	};
+
+	mux_gpio_keys: gpiokeygrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11		0x3008
+			MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12		0x3008
+			MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13		0x3008
+			MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10		0x3008
+			MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09		0x3008
+			MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15		0x3008
+			MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08		0x3008
+			MX6UL_PAD_ENET2_TX_CLK__GPIO2_IO14		0x3008
+			MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03		0x3008
+			MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01		0x3008
+		>;
+	};
+
+	mux_led_ctrl: ledctrlgrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02		0x3008
+		>;
+	};
+
+	mux_adc: adcgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO07__GPIO1_IO07		0xb0
+		>;
+	};
+
+	mux_pwm: pwm1grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO08__PWM1_OUT			0x110b0
+		>;
+	};
+
+	mux_backlight_enable: blenablegrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO09__GPIO1_IO09		0x3008
+		>;
+	};
+
+	mux_lcd_data: lcdifdatgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA00__LCDIF_DATA00		0x79
+			MX6UL_PAD_LCD_DATA01__LCDIF_DATA01		0x79
+			MX6UL_PAD_LCD_DATA02__LCDIF_DATA02		0x79
+			MX6UL_PAD_LCD_DATA03__LCDIF_DATA03		0x79
+			MX6UL_PAD_LCD_DATA04__LCDIF_DATA04		0x79
+			MX6UL_PAD_LCD_DATA05__LCDIF_DATA05		0x79
+			MX6UL_PAD_LCD_DATA06__LCDIF_DATA06		0x79
+			MX6UL_PAD_LCD_DATA07__LCDIF_DATA07		0x79
+			MX6UL_PAD_LCD_DATA08__LCDIF_DATA08		0x79
+			MX6UL_PAD_LCD_DATA09__LCDIF_DATA09		0x79
+			MX6UL_PAD_LCD_DATA10__LCDIF_DATA10		0x79
+			MX6UL_PAD_LCD_DATA11__LCDIF_DATA11		0x79
+			MX6UL_PAD_LCD_DATA12__LCDIF_DATA12		0x79
+			MX6UL_PAD_LCD_DATA13__LCDIF_DATA13		0x79
+			MX6UL_PAD_LCD_DATA14__LCDIF_DATA14		0x79
+			MX6UL_PAD_LCD_DATA15__LCDIF_DATA15		0x79
+			MX6UL_PAD_LCD_DATA16__LCDIF_DATA16		0x79
+			MX6UL_PAD_LCD_DATA17__LCDIF_DATA17		0x79
+		>;
+	};
+
+	mux_lcd_ctrl: lcdifctrlgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_CLK__LCDIF_CLK			0x79
+			MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE		0x79
+			MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC		0x79
+			MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC		0x79
+		>;
+	};
+
+	mux_csi: csi1grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK		0x1b088
+			MX6UL_PAD_CSI_VSYNC__CSI_VSYNC			0x1b088
+			MX6UL_PAD_CSI_HSYNC__CSI_HSYNC			0x1b088
+			MX6UL_PAD_CSI_DATA00__CSI_DATA02		0x1b088
+			MX6UL_PAD_CSI_DATA01__CSI_DATA03		0x1b088
+			MX6UL_PAD_CSI_DATA02__CSI_DATA04		0x1b088
+			MX6UL_PAD_CSI_DATA03__CSI_DATA05		0x1b088
+			MX6UL_PAD_CSI_DATA04__CSI_DATA06		0x1b088
+			MX6UL_PAD_CSI_DATA05__CSI_DATA07		0x1b088
+			MX6UL_PAD_CSI_DATA06__CSI_DATA08		0x1b088
+			MX6UL_PAD_CSI_DATA07__CSI_DATA09		0x1b088
+		>;
+	};
+
+	mux_gc0308: gc0308grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_MCLK__CSI_MCLK			0x1e038
+			MX6UL_PAD_GPIO1_IO05__GPIO1_IO05		0x1b088
+			MX6UL_PAD_GPIO1_IO06__GPIO1_IO06		0x1b088
+		>;
+	};
+
+
+	mux_spi3: ecspi3grp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI		0x100b1
+			MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK		0x100b1
+		>;
+	};
+
+	mux_spi3_cs: ecspi3_csgrp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20		0x3008
+		>;
+	};
+};
-- 
2.43.0



From florian.fainelli at broadcom.com  Fri Feb  9 17:24:49 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Fri,  9 Feb 2024 17:24:49 -0800
Subject: [PATCH v2] irqchip/irq-brcmstb-l2: add write memory barrier before exit
Message-ID: <20240210012449.3009125-1-florian.fainelli@broadcom.com>

From: Doug Berger <opendmb at gmail.com>

It was observed on Broadcom devices that use GIC v3 architecture
L1 interrupt controllers as the parent of brcmstb-l2 interrupt
controllers that the deactivation of the parent irq could happen
before the brcmstb-l2 deasserted its output. This would lead the
GIC to reactivate the irq only to find that no L2 interrupt was
pending. The result was a spurious interrupt invoking the
handle_bad_irq() with its associated messaging. While this did
not create a functional problem it is a waste of cycles.

The hazard exists because the memory mapped bus writes to the
brcmstb-l2 registers are buffered and the GIC v3 architecture
uses a very efficient system register write to deactivate the
interrupt. This commit adds a write memory barrier prior to
invoking chained_irq_exit() to introduce a dsb(st) on those
systems to ensure the system register write cannot be executed
until the memory mapped writes are visible to the system.

Signed-off-by: Doug Berger <opendmb at gmail.com>
Acked-by: Florian Fainelli <florian.fainelli at broadcom.com>
Fixes: 7f646e92766e ("irqchip: brcmstb-l2: Add Broadcom Set Top Box  Level-2 interrupt controller")
[florian: Added Fixes tag]
Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>
---
Changes in v2:

- add Fixes tag
- bump copyright

 drivers/irqchip/irq-brcmstb-l2.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c
index 5559c943f03f..63aed60dd3f1 100644
--- a/drivers/irqchip/irq-brcmstb-l2.c
+++ b/drivers/irqchip/irq-brcmstb-l2.c
@@ -2,7 +2,7 @@
 /*
  * Generic Broadcom Set Top Box Level 2 Interrupt controller driver
  *
- * Copyright (C) 2014-2017 Broadcom
+ * Copyright (C) 2014-2024 Broadcom
  */
 
 #define pr_fmt(fmt)	KBUILD_MODNAME	": " fmt
@@ -112,6 +112,9 @@ static void brcmstb_l2_intc_irq_handle(struct irq_desc *desc)
 		generic_handle_domain_irq(b->domain, irq);
 	} while (status);
 out:
+	/* Don't ack parent before all device writes are done */
+	wmb();
+
 	chained_irq_exit(chip, desc);
 }
 
-- 
2.34.1



From cassel at kernel.org  Fri Feb  9 17:26:24 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Sat, 10 Feb 2024 02:26:24 +0100
Subject: [PATCH 0/2] PCI endpoint BAR hardware description cleanup
Message-ID: <20240210012634.600301-1-cassel@kernel.org>

The series is based on top of:
https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=endpoint


Hello all,

This series cleans up the hardware description for PCI endpoint BARs.

The problems with the existing hardware description:
-The documentation is lackluster.
-Some of the names are confusingly similar, e.g. fixed_64bit and
 fixed_size, even though these are for completely unrelated things.
-The way that the BARs are defined in the endpoint controller drivers
 is messy, because the left hand side is not a BAR, so you can mark a
 BAR as e.g. both fixed size and reserved.

This series tries to address all the problems above.

Personally, I think that the code is more readable, both the endpoint
controller drivers, but also pci-epc-core.c.

(Oh, and as you can probably guess, I will be sending out a patch series
that adds BAR_RESIZABLE to enum pci_epc_bar_type in the coming week(s).)


Kind regards,
Niklas


Niklas Cassel (2):
  PCI: endpoint: Clean up hardware description for BARs
  PCI: endpoint: Drop only_64bit on reserved BARs

 drivers/pci/controller/dwc/pci-imx6.c         |  3 +-
 drivers/pci/controller/dwc/pci-keystone.c     | 12 +++---
 .../pci/controller/dwc/pci-layerscape-ep.c    |  5 ++-
 drivers/pci/controller/dwc/pcie-keembay.c     |  8 +++-
 drivers/pci/controller/dwc/pcie-rcar-gen4.c   |  4 +-
 drivers/pci/controller/dwc/pcie-tegra194.c    | 10 +++--
 drivers/pci/controller/dwc/pcie-uniphier-ep.c | 15 ++++++--
 drivers/pci/controller/pcie-rcar-ep.c         | 14 ++++---
 drivers/pci/endpoint/functions/pci-epf-ntb.c  |  4 +-
 drivers/pci/endpoint/functions/pci-epf-test.c |  8 ++--
 drivers/pci/endpoint/functions/pci-epf-vntb.c |  2 +-
 drivers/pci/endpoint/pci-epc-core.c           | 25 +++++-------
 drivers/pci/endpoint/pci-epf-core.c           | 15 ++++----
 include/linux/pci-epc.h                       | 38 ++++++++++++++++---
 14 files changed, 105 insertions(+), 58 deletions(-)

-- 
2.43.0



From cassel at kernel.org  Fri Feb  9 17:26:26 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Sat, 10 Feb 2024 02:26:26 +0100
Subject: [PATCH 2/2] PCI: endpoint: Drop only_64bit on reserved BARs
In-Reply-To: <20240210012634.600301-1-cassel@kernel.org>
References: <20240210012634.600301-1-cassel@kernel.org>
Message-ID: <20240210012634.600301-3-cassel@kernel.org>

The definition of a reserved BAR is that EPF drivers should not touch
them.

The definition of only_64bit is that the EPF driver must configure this
BAR as 64-bit. (An EPF driver is not allowed to choose if this BAR should
be configured as 32-bit or 64-bit.)

Thus, it does not make sense to put only_64bit of a BAR that EPF drivers
are not allow to touch.

Drop the only_64bit property from hardware descriptions that are of type
reserved BAR.

Signed-off-by: Niklas Cassel <cassel at kernel.org>
---
 drivers/pci/controller/dwc/pci-keystone.c     | 2 +-
 drivers/pci/controller/dwc/pcie-uniphier-ep.c | 2 +-
 drivers/pci/endpoint/pci-epc-core.c           | 7 -------
 include/linux/pci-epc.h                       | 4 ++++
 4 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index b2b93b4fa82d..844de4418724 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -924,7 +924,7 @@ static const struct pci_epc_features ks_pcie_am654_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
 	.msix_capable = true,
-	.bar[BAR_0] = { .type = BAR_RESERVED, .only_64bit = true, },
+	.bar[BAR_0] = { .type = BAR_RESERVED, },
 	.bar[BAR_1] = { .type = BAR_RESERVED, },
 	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
 	.bar[BAR_3] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
index 265f65fc673f..639bc2e12476 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
@@ -415,7 +415,7 @@ static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = {
 		.bar[BAR_1] = { .type = BAR_RESERVED, },
 		.bar[BAR_2] = { .only_64bit = true, },
 		.bar[BAR_3] = { .type = BAR_RESERVED, },
-		.bar[BAR_4] = { .type = BAR_RESERVED, .only_64bit = true, },
+		.bar[BAR_4] = { .type = BAR_RESERVED, },
 		.bar[BAR_5] = { .type = BAR_RESERVED, },
 	},
 };
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 7fe8f4336765..da3fc0795b0b 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -120,13 +120,6 @@ enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
 		/* If the BAR is not reserved, return it. */
 		if (epc_features->bar[i].type != BAR_RESERVED)
 			return i;
-
-		/*
-		 * If the BAR is reserved, and marked as 64-bit only, then the
-		 * succeeding BAR is also reserved.
-		 */
-		if (epc_features->bar[i].only_64bit)
-			i++;
 	}
 
 	return NO_BAR;
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 4ccb4f4f3883..bb9c4dfcea93 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -164,6 +164,10 @@ enum pci_epc_bar_type {
  *		should be configured as 32-bit or 64-bit, the EPF driver must
  *		configure this BAR as 64-bit. Additionally, the BAR succeeding
  *		this BAR must be set to type BAR_RESERVED.
+ *
+ *		only_64bit should not be set on a BAR of type BAR_RESERVED.
+ *		(If BARx is a 64-bit BAR that an EPF driver is not allowed to
+ *		touch, then you must set both BARx and BARx+1 as BAR_RESERVED.)
  */
 struct pci_epc_bar_desc {
 	enum pci_epc_bar_type type;
-- 
2.43.0



From cassel at kernel.org  Fri Feb  9 17:26:25 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Sat, 10 Feb 2024 02:26:25 +0100
Subject: [PATCH 1/2] PCI: endpoint: Clean up hardware description for BARs
In-Reply-To: <20240210012634.600301-1-cassel@kernel.org>
References: <20240210012634.600301-1-cassel@kernel.org>
Message-ID: <20240210012634.600301-2-cassel@kernel.org>

The hardware description for BARs is scattered in many different variables
in pci_epc_features. Some of these things are mutually exclusive, so it
can create confusion over which variable that has precedence over another.

Improve the situation by creating a struct pci_epc_bar_desc, and a new
enum pci_epc_bar_type, and convert the endpoint controller drivers to use
this more well defined format.

Signed-off-by: Niklas Cassel <cassel at kernel.org>
---
 drivers/pci/controller/dwc/pci-imx6.c         |  3 +-
 drivers/pci/controller/dwc/pci-keystone.c     | 12 +++----
 .../pci/controller/dwc/pci-layerscape-ep.c    |  5 ++-
 drivers/pci/controller/dwc/pcie-keembay.c     |  8 +++--
 drivers/pci/controller/dwc/pcie-rcar-gen4.c   |  4 ++-
 drivers/pci/controller/dwc/pcie-tegra194.c    | 10 ++++--
 drivers/pci/controller/dwc/pcie-uniphier-ep.c | 15 ++++++--
 drivers/pci/controller/pcie-rcar-ep.c         | 14 +++++---
 drivers/pci/endpoint/functions/pci-epf-ntb.c  |  4 +--
 drivers/pci/endpoint/functions/pci-epf-test.c |  8 ++---
 drivers/pci/endpoint/functions/pci-epf-vntb.c |  2 +-
 drivers/pci/endpoint/pci-epc-core.c           | 32 +++++++++--------
 drivers/pci/endpoint/pci-epf-core.c           | 15 ++++----
 include/linux/pci-epc.h                       | 34 +++++++++++++++----
 14 files changed, 108 insertions(+), 58 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index dc2c036ab28c..47a9a96484ed 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1081,7 +1081,8 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
 	.msix_capable = false,
-	.reserved_bar = 1 << BAR_1 | 1 << BAR_3,
+	.bar[BAR_1] = { .type = BAR_RESERVED, },
+	.bar[BAR_3] = { .type = BAR_RESERVED, },
 	.align = SZ_64K,
 };
 
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index c0c62533a3f1..b2b93b4fa82d 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -924,12 +924,12 @@ static const struct pci_epc_features ks_pcie_am654_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
 	.msix_capable = true,
-	.reserved_bar = 1 << BAR_0 | 1 << BAR_1,
-	.bar_fixed_64bit = 1 << BAR_0,
-	.bar_fixed_size[2] = SZ_1M,
-	.bar_fixed_size[3] = SZ_64K,
-	.bar_fixed_size[4] = 256,
-	.bar_fixed_size[5] = SZ_1M,
+	.bar[BAR_0] = { .type = BAR_RESERVED, .only_64bit = true, },
+	.bar[BAR_1] = { .type = BAR_RESERVED, },
+	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
+	.bar[BAR_3] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
+	.bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256, },
+	.bar[BAR_5] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
 	.align = SZ_1M,
 };
 
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index 2e398494e7c0..1f6ee1460ec2 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -250,7 +250,10 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
 	pci->dev = dev;
 	pci->ops = pcie->drvdata->dw_pcie_ops;
 
-	ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
+	ls_epc->bar[BAR_2].only_64bit = true;
+	ls_epc->bar[BAR_3].type = BAR_RESERVED;
+	ls_epc->bar[BAR_4].only_64bit = true;
+	ls_epc->bar[BAR_5].type = BAR_RESERVED;
 	ls_epc->linkup_notifier = true;
 
 	pcie->pci = pci;
diff --git a/drivers/pci/controller/dwc/pcie-keembay.c b/drivers/pci/controller/dwc/pcie-keembay.c
index 208d3b0ba196..5e8e54f597dd 100644
--- a/drivers/pci/controller/dwc/pcie-keembay.c
+++ b/drivers/pci/controller/dwc/pcie-keembay.c
@@ -312,8 +312,12 @@ static const struct pci_epc_features keembay_pcie_epc_features = {
 	.linkup_notifier	= false,
 	.msi_capable		= true,
 	.msix_capable		= true,
-	.reserved_bar		= BIT(BAR_1) | BIT(BAR_3) | BIT(BAR_5),
-	.bar_fixed_64bit	= BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
+	.bar[BAR_0]		= { .only_64bit = true, },
+	.bar[BAR_1]		= { .type = BAR_RESERVED, },
+	.bar[BAR_2]		= { .only_64bit = true, },
+	.bar[BAR_3]		= { .type = BAR_RESERVED, },
+	.bar[BAR_4]		= { .only_64bit = true, },
+	.bar[BAR_5]		= { .type = BAR_RESERVED, },
 	.align			= SZ_16K,
 };
 
diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index e9166619b1f9..0be760ed420b 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -383,7 +383,9 @@ static const struct pci_epc_features rcar_gen4_pcie_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
 	.msix_capable = false,
-	.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
+	.bar[BAR_1] = { .type = BAR_RESERVED, },
+	.bar[BAR_3] = { .type = BAR_RESERVED, },
+	.bar[BAR_5] = { .type = BAR_RESERVED, },
 	.align = SZ_1M,
 };
 
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 7afa9e9aabe2..1f7b662cb8e1 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -2007,9 +2007,13 @@ static const struct pci_epc_features tegra_pcie_epc_features = {
 	.core_init_notifier = true,
 	.msi_capable = false,
 	.msix_capable = false,
-	.reserved_bar = 1 << BAR_2 | 1 << BAR_3 | 1 << BAR_4 | 1 << BAR_5,
-	.bar_fixed_64bit = 1 << BAR_0,
-	.bar_fixed_size[0] = SZ_1M,
+	.bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = SZ_1M,
+			.only_64bit = true, },
+	.bar[BAR_1] = { .type = BAR_RESERVED, },
+	.bar[BAR_2] = { .type = BAR_RESERVED, },
+	.bar[BAR_3] = { .type = BAR_RESERVED, },
+	.bar[BAR_4] = { .type = BAR_RESERVED, },
+	.bar[BAR_5] = { .type = BAR_RESERVED, },
 };
 
 static const struct pci_epc_features*
diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
index 3fced0d3e851..265f65fc673f 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
@@ -411,8 +411,12 @@ static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = {
 		.msi_capable = true,
 		.msix_capable = false,
 		.align = 1 << 16,
-		.bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
-		.reserved_bar =  BIT(BAR_4),
+		.bar[BAR_0] = { .only_64bit = true, },
+		.bar[BAR_1] = { .type = BAR_RESERVED, },
+		.bar[BAR_2] = { .only_64bit = true, },
+		.bar[BAR_3] = { .type = BAR_RESERVED, },
+		.bar[BAR_4] = { .type = BAR_RESERVED, .only_64bit = true, },
+		.bar[BAR_5] = { .type = BAR_RESERVED, },
 	},
 };
 
@@ -425,7 +429,12 @@ static const struct uniphier_pcie_ep_soc_data uniphier_nx1_data = {
 		.msi_capable = true,
 		.msix_capable = false,
 		.align = 1 << 12,
-		.bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
+		.bar[BAR_0] = { .only_64bit = true, },
+		.bar[BAR_1] = { .type = BAR_RESERVED, },
+		.bar[BAR_2] = { .only_64bit = true, },
+		.bar[BAR_3] = { .type = BAR_RESERVED, },
+		.bar[BAR_4] = { .only_64bit = true, },
+		.bar[BAR_5] = { .type = BAR_RESERVED, },
 	},
 };
 
diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c
index e6909271def7..05967c6c0b42 100644
--- a/drivers/pci/controller/pcie-rcar-ep.c
+++ b/drivers/pci/controller/pcie-rcar-ep.c
@@ -440,11 +440,15 @@ static const struct pci_epc_features rcar_pcie_epc_features = {
 	.msi_capable = true,
 	.msix_capable = false,
 	/* use 64-bit BARs so mark BAR[1,3,5] as reserved */
-	.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
-	.bar_fixed_64bit = 1 << BAR_0 | 1 << BAR_2 | 1 << BAR_4,
-	.bar_fixed_size[0] = 128,
-	.bar_fixed_size[2] = 256,
-	.bar_fixed_size[4] = 256,
+	.bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = 128,
+			.only_64bit = true, },
+	.bar[BAR_1] = { .type = BAR_RESERVED, },
+	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = 256,
+			.only_64bit = true, },
+	.bar[BAR_3] = { .type = BAR_RESERVED, },
+	.bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256,
+			.only_64bit = true, },
+	.bar[BAR_5] = { .type = BAR_RESERVED, },
 };
 
 static const struct pci_epc_features*
diff --git a/drivers/pci/endpoint/functions/pci-epf-ntb.c b/drivers/pci/endpoint/functions/pci-epf-ntb.c
index 43cd309ce22f..e01a98e74d21 100644
--- a/drivers/pci/endpoint/functions/pci-epf-ntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-ntb.c
@@ -1012,13 +1012,13 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb,
 
 	epc_features = ntb_epc->epc_features;
 	barno = ntb_epc->epf_ntb_bar[BAR_CONFIG];
-	size = epc_features->bar_fixed_size[barno];
+	size = epc_features->bar[barno].fixed_size;
 	align = epc_features->align;
 
 	peer_ntb_epc = ntb->epc[!type];
 	peer_epc_features = peer_ntb_epc->epc_features;
 	peer_barno = ntb_epc->epf_ntb_bar[BAR_PEER_SPAD];
-	peer_size = peer_epc_features->bar_fixed_size[peer_barno];
+	peer_size = peer_epc_features->bar[peer_barno].fixed_size;
 
 	/* Check if epc_features is populated incorrectly */
 	if ((!IS_ALIGNED(size, align)))
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 981894e40681..cd4ffb39dcdc 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -729,7 +729,7 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
 		 */
 		add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
 
-		if (!!(epc_features->reserved_bar & (1 << bar)))
+		if (epc_features->bar[bar].type == BAR_RESERVED)
 			continue;
 
 		ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no,
@@ -856,7 +856,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
 		if (bar == test_reg_bar)
 			continue;
 
-		if (!!(epc_features->reserved_bar & (1 << bar)))
+		if (epc_features->bar[bar].type == BAR_RESERVED)
 			continue;
 
 		base = pci_epf_alloc_space(epf, bar_size[bar], bar,
@@ -874,13 +874,11 @@ static void pci_epf_configure_bar(struct pci_epf *epf,
 				  const struct pci_epc_features *epc_features)
 {
 	struct pci_epf_bar *epf_bar;
-	bool bar_fixed_64bit;
 	int i;
 
 	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
 		epf_bar = &epf->bar[i];
-		bar_fixed_64bit = !!(epc_features->bar_fixed_64bit & (1 << i));
-		if (bar_fixed_64bit)
+		if (epc_features->bar[i].only_64bit)
 			epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
 	}
 }
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index eda4b906868b..1de293411434 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -422,7 +422,7 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb)
 								epf->func_no,
 								epf->vfunc_no);
 	barno = ntb->epf_ntb_bar[BAR_CONFIG];
-	size = epc_features->bar_fixed_size[barno];
+	size = epc_features->bar[barno].fixed_size;
 	align = epc_features->align;
 
 	if ((!IS_ALIGNED(size, align)))
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index dcd4e66430c1..7fe8f4336765 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -87,7 +87,7 @@ EXPORT_SYMBOL_GPL(pci_epc_get);
  * @epc_features: pci_epc_features structure that holds the reserved bar bitmap
  *
  * Invoke to get the first unreserved BAR that can be used by the endpoint
- * function. For any incorrect value in reserved_bar return '0'.
+ * function.
  */
 enum pci_barno
 pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features)
@@ -102,32 +102,34 @@ EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
  * @bar: the starting BAR number from where unreserved BAR should be searched
  *
  * Invoke to get the next unreserved BAR starting from @bar that can be used
- * for endpoint function. For any incorrect value in reserved_bar return '0'.
+ * for endpoint function.
  */
 enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
 					 *epc_features, enum pci_barno bar)
 {
-	unsigned long free_bar;
+	int i;
 
 	if (!epc_features)
 		return BAR_0;
 
 	/* If 'bar - 1' is a 64-bit BAR, move to the next BAR */
-	if ((epc_features->bar_fixed_64bit << 1) & 1 << bar)
+	if (bar > 0 && epc_features->bar[bar - 1].only_64bit)
 		bar++;
 
-	/* Find if the reserved BAR is also a 64-bit BAR */
-	free_bar = epc_features->reserved_bar & epc_features->bar_fixed_64bit;
-
-	/* Set the adjacent bit if the reserved BAR is also a 64-bit BAR */
-	free_bar <<= 1;
-	free_bar |= epc_features->reserved_bar;
-
-	free_bar = find_next_zero_bit(&free_bar, 6, bar);
-	if (free_bar > 5)
-		return NO_BAR;
+	for (i = bar; i < PCI_STD_NUM_BARS; i++) {
+		/* If the BAR is not reserved, return it. */
+		if (epc_features->bar[i].type != BAR_RESERVED)
+			return i;
+
+		/*
+		 * If the BAR is reserved, and marked as 64-bit only, then the
+		 * succeeding BAR is also reserved.
+		 */
+		if (epc_features->bar[i].only_64bit)
+			i++;
+	}
 
-	return free_bar;
+	return NO_BAR;
 }
 EXPORT_SYMBOL_GPL(pci_epc_get_next_free_bar);
 
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index f2b4d34454c4..0a28a0b0911b 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -260,7 +260,7 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
 			  const struct pci_epc_features *epc_features,
 			  enum pci_epc_interface_type type)
 {
-	u64 bar_fixed_size = epc_features->bar_fixed_size[bar];
+	u64 bar_fixed_size = epc_features->bar[bar].fixed_size;
 	size_t align = epc_features->align;
 	struct pci_epf_bar *epf_bar;
 	dma_addr_t phys_addr;
@@ -271,13 +271,14 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
 	if (size < 128)
 		size = 128;
 
-	if (bar_fixed_size && size > bar_fixed_size) {
-		dev_err(&epf->dev, "requested BAR size is larger than fixed size\n");
-		return NULL;
-	}
-
-	if (bar_fixed_size)
+	if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) {
+		if (size > bar_fixed_size) {
+			dev_err(&epf->dev,
+				"requested BAR size is larger than fixed size\n");
+			return NULL;
+		}
 		size = bar_fixed_size;
+	}
 
 	if (align)
 		size = ALIGN(size, align);
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 40ea18f5aa02..4ccb4f4f3883 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -145,6 +145,32 @@ struct pci_epc {
 	unsigned long			function_num_map;
 };
 
+/**
+ * @BAR_PROGRAMMABLE: The BAR mask can be configured by the EPC.
+ * @BAR_FIXED: The BAR mask is fixed by the hardware.
+ * @BAR_RESERVED: The BAR should not be touched by an EPF driver.
+ */
+enum pci_epc_bar_type {
+	BAR_PROGRAMMABLE = 0,
+	BAR_FIXED,
+	BAR_RESERVED,
+};
+
+/**
+ * struct pci_epc_bar_desc - hardware description for a BAR
+ * @type: the type of the BAR
+ * @fixed_size: the fixed size, only applicable if type is BAR_FIXED_MASK.
+ * @only_64bit: if true, an EPF driver is not allowed to choose if this BAR
+ *		should be configured as 32-bit or 64-bit, the EPF driver must
+ *		configure this BAR as 64-bit. Additionally, the BAR succeeding
+ *		this BAR must be set to type BAR_RESERVED.
+ */
+struct pci_epc_bar_desc {
+	enum pci_epc_bar_type type;
+	u64 fixed_size;
+	bool only_64bit;
+};
+
 /**
  * struct pci_epc_features - features supported by a EPC device per function
  * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up
@@ -152,9 +178,7 @@ struct pci_epc {
  *			for initialization
  * @msi_capable: indicate if the endpoint function has MSI capability
  * @msix_capable: indicate if the endpoint function has MSI-X capability
- * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver
- * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs
- * @bar_fixed_size: Array specifying the size supported by each BAR
+ * @bar: array specifying the hardware description for each BAR
  * @align: alignment size required for BAR buffer allocation
  */
 struct pci_epc_features {
@@ -162,9 +186,7 @@ struct pci_epc_features {
 	unsigned int	core_init_notifier : 1;
 	unsigned int	msi_capable : 1;
 	unsigned int	msix_capable : 1;
-	u8	reserved_bar;
-	u8	bar_fixed_64bit;
-	u64	bar_fixed_size[PCI_STD_NUM_BARS];
+	struct	pci_epc_bar_desc bar[PCI_STD_NUM_BARS];
 	size_t	align;
 };
 
-- 
2.43.0



From daniel at makrotopia.org  Fri Feb  9 18:10:08 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sat, 10 Feb 2024 02:10:08 +0000
Subject: [PATCH v3 1/2] dt-bindings: phy: mediatek,mt7988-xfi-tphy: add new
 bindings
Message-ID: <745f8b46f676e94c1a396df8c46aefe0e8b4771c.1707530671.git.daniel@makrotopia.org>

Add bindings for the MediaTek XFI Ethernet SerDes T-PHY found in the
MediaTek MT7988 SoC which can operate at various interfaces modes:

via USXGMII PCS:
 * USXGMII
 * 10GBase-R
 * 5GBase-R

via LynxI SGMII PCS:
 * 2500Base-X
 * 1000Base-X
 * Cisco SGMII (MAC side)

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v3: Add reference to MediaTek-internal "pextp" name, better explain reset as
    well as 10GBase-R tuning work-around.
v2: unify filename and compatible as requested

 .../phy/mediatek,mt7988-xfi-tphy.yaml         | 80 +++++++++++++++++++
 1 file changed, 80 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml

diff --git a/Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml
new file mode 100644
index 0000000000000..c0ab444f9c687
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mediatek,mt7988-xfi-tphy.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/mediatek,mt7988-xfi-tphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek MT7988 XFI T-PHY
+
+maintainers:
+  - Daniel Golle <daniel at makrotopia.org>
+
+description:
+  The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes
+  used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in
+  MediaTek's 10G-capabale MT7988 SoC.
+  In MediaTek's SDK sources, this unit is referred to as "pextp".
+
+properties:
+  compatible:
+    const: mediatek,mt7988-xfi-tphy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: XFI PHY clock
+      - description: XFI register clock
+
+  clock-names:
+    items:
+      - const: xfipll
+      - const: topxtal
+
+  resets:
+    items:
+      - description: Reset controller corresponding to the phy instance.
+
+  mediatek,usxgmii-performance-errata:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      One instance of the T-PHY on MT7988 suffers from a performance
+      problem in 10GBase-R mode which needs a work-around in the driver.
+      This flag enables a work-around ajusting an analog phy setting and
+      is required for XFI Port0 of the MT7988 SoC to be in compliance with
+      the SFP specification.
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      phy at 11f20000 {
+        compatible = "mediatek,mt7988-xfi-tphy";
+        reg = <0 0x11f20000 0 0x10000>;
+        clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>,
+                 <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
+        clock-names = "xfipll", "topxtal";
+        resets = <&watchdog 14>;
+        mediatek,usxgmii-performance-errata;
+        #phy-cells = <0>;
+      };
+    };
+
+...
-- 
2.43.0


From daniel at makrotopia.org  Fri Feb  9 18:10:24 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sat, 10 Feb 2024 02:10:24 +0000
Subject: [PATCH v3 2/2] phy: add driver for MediaTek XFI T-PHY
In-Reply-To: <745f8b46f676e94c1a396df8c46aefe0e8b4771c.1707530671.git.daniel@makrotopia.org>
References: <745f8b46f676e94c1a396df8c46aefe0e8b4771c.1707530671.git.daniel@makrotopia.org>
Message-ID: <3bb95f1d795eede63284dbcb224e06ea6886b421.1707530671.git.daniel@makrotopia.org>

Add driver for MediaTek's XFI T-PHY which can be found in the MT7988
SoC. The XFI T-PHY is a 10 Gigabit/s Ethernet SerDes PHY with muxes on
the internal side to be used with either USXGMII PCS or LynxI PCS,
depending on the selected PHY interface mode.

The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
PHY_INTERFACE_MODE_* corresponding to the supported modes:

 * USXGMII                 \
 * 10GBase-R                }- USXGMII PCS - XGDM  \
 * 5GBase-R                /                        \
                                                     }- Ethernet MAC
 * 2500Base-X              \                        /
 * 1000Base-X               }- LynxI PCS - GDM     /
 * Cisco SGMII (MAC side)  /

In order to work-around a performance issue present on the first of
two XFI T-PHYs present in MT7988, special tuning is applied which can be
selected by adding the 'mediatek,usxgmii-performance-errata' property to
the device tree node.

There is no documentation for most registers used for the
analog/tuning part, however, most of the registers have been partially
reverse-engineered from MediaTek's SDK implementation (an opaque
sequence of 32-bit register writes) and descriptions for all relevant
digital registers and bits such as resets and muxes have been supplied
by MediaTek.

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v3: no changes
v2:
 * use IO helpers from mtk-io.h instead of rolling my own
 * use devm_clk_bulk_get()
 * yse devm_platform_ioremap_resource()
 * unify name and description everywhere
 * invert bool is_xgmii into bool use_lynxi_pcs and add comments
   describing the meaning of each of the stack variables
 * not much we can do about remaining magic values unless MTK provides
   definitions for them


 MAINTAINERS                             |   1 +
 drivers/phy/mediatek/Kconfig            |  12 +
 drivers/phy/mediatek/Makefile           |   1 +
 drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 360 ++++++++++++++++++++++++
 4 files changed, 374 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4be2fd097f261..616b86e3e62fd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13776,6 +13776,7 @@ L:	netdev at vger.kernel.org
 S:	Maintained
 F:	drivers/net/phy/mediatek-ge-soc.c
 F:	drivers/net/phy/mediatek-ge.c
+F:	drivers/phy/mediatek/phy-mtk-xfi-tphy.c
 
 MEDIATEK I2C CONTROLLER DRIVER
 M:	Qii Wang <qii.wang at mediatek.com>
diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index 3849b7c87d287..117d0e84c7360 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -13,6 +13,18 @@ config PHY_MTK_PCIE
 	  callback for PCIe GEN3 port, it supports software efuse
 	  initialization.
 
+config PHY_MTK_XFI_TPHY
+	tristate "MediaTek 10GE SerDes XFI T-PHY driver"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on OF && OF_ADDRESS
+	depends on HAS_IOMEM
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for MediaTek XFI T-PHY driver.
+	  The driver provides access to the Ethernet SerDes T-PHY supporting
+	  1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
+	  via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
+
 config PHY_MTK_TPHY
 	tristate "MediaTek T-PHY Driver"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index f6e24a47e0815..1b8088df71e84 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
 obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
 obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
+obj-$(CONFIG_PHY_MTK_XFI_TPHY)		+= phy-mtk-xfi-tphy.o
 
 phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
 phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
new file mode 100644
index 0000000000000..551d6cee33f94
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
@@ -0,0 +1,360 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* MediaTek 10GE SerDes XFI T-PHY driver
+ *
+ * Copyright (c) 2024 Daniel Golle <daniel at makrotopia.org>
+ *                    Bc-bocun Chen <bc-bocun.chen at mediatek.com>
+ * based on mtk_usxgmii.c and mtk_sgmii.c found in MediaTek's SDK (GPL-2.0)
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Henry Yen <henry.yen at mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
+
+#include "phy-mtk-io.h"
+
+#define MTK_XFI_TPHY_NUM_CLOCKS		2
+
+#define REG_DIG_GLB_70			0x0070
+#define  XTP_PCS_RX_EQ_IN_PROGRESS(x)	FIELD_PREP(GENMASK(25, 24), (x))
+#define  XTP_PCS_MODE_MASK		GENMASK(17, 16)
+#define  XTP_PCS_MODE(x)		FIELD_PREP(GENMASK(17, 16), (x))
+#define  XTP_PCS_RST_B			BIT(15)
+#define  XTP_FRC_PCS_RST_B		BIT(14)
+#define  XTP_PCS_PWD_SYNC_MASK		GENMASK(13, 12)
+#define  XTP_PCS_PWD_SYNC(x)		FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
+#define  XTP_PCS_PWD_ASYNC_MASK		GENMASK(11, 10)
+#define  XTP_PCS_PWD_ASYNC(x)		FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
+#define  XTP_FRC_PCS_PWD_ASYNC		BIT(8)
+#define  XTP_PCS_UPDT			BIT(4)
+#define  XTP_PCS_IN_FR_RG		BIT(0)
+
+#define REG_DIG_GLB_F4			0x00f4
+#define  XFI_DPHY_PCS_SEL		BIT(0)
+#define   XFI_DPHY_PCS_SEL_SGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 1)
+#define   XFI_DPHY_PCS_SEL_USXGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 0)
+#define  XFI_DPHY_AD_SGDT_FRC_EN	BIT(5)
+
+#define REG_DIG_LN_TRX_40		0x3040
+#define  XTP_LN_FRC_TX_DATA_EN		BIT(29)
+#define  XTP_LN_TX_DATA_EN		BIT(28)
+
+#define REG_DIG_LN_TRX_B0		0x30b0
+#define  XTP_LN_FRC_TX_MACCK_EN		BIT(5)
+#define  XTP_LN_TX_MACCK_EN		BIT(4)
+
+#define REG_ANA_GLB_D0			0x90d0
+#define  XTP_GLB_USXGMII_SEL_MASK	GENMASK(3, 1)
+#define  XTP_GLB_USXGMII_SEL(x)		FIELD_PREP(GENMASK(3, 1), (x))
+#define  XTP_GLB_USXGMII_EN		BIT(0)
+
+struct mtk_xfi_tphy {
+	void __iomem		*base;
+	struct device		*dev;
+	struct reset_control	*reset;
+	struct clk_bulk_data	clocks[MTK_XFI_TPHY_NUM_CLOCKS];
+	bool			da_war;
+};
+
+static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
+			       phy_interface_t interface)
+{
+	/* Override 10GBase-R tuning value if work-around is selected */
+	bool da_war = (xfi_tphy->da_war && (interface == PHY_INTERFACE_MODE_10GBASER));
+	/* Bools to make setting up values for specific PHY speeds easier */
+	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
+	bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
+		      interface == PHY_INTERFACE_MODE_SGMII);
+	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
+		       interface == PHY_INTERFACE_MODE_USXGMII);
+	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
+	/* Bool to configure input mux to either
+	 *  - USXGMII PCS (64b/66b coding) for 5G/10G
+	 *  - LynxI PCS (8b/10b coding) for 1G/2.5G
+	 */
+	bool use_lynxi_pcs = (is_1g || is_2p5g);
+
+	dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));
+
+	/* Setup PLL setting */
+	mtk_phy_update_bits(xfi_tphy->base + 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
+	mtk_phy_update_bits(xfi_tphy->base + 0x2030, 0x500, is_1g ? 0x0 : 0x500);
+	mtk_phy_update_bits(xfi_tphy->base + 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
+	mtk_phy_update_bits(xfi_tphy->base + 0x2040, 0x340000, is_1g ? 0x200000 : 0x140000);
+
+	/* Setup RXFE BW setting */
+	mtk_phy_update_bits(xfi_tphy->base + 0x50f0, 0xc10, is_1g ? 0x410 : is_5g ? 0x800 : 0x400);
+	mtk_phy_update_bits(xfi_tphy->base + 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
+
+	/* Setup RX CDR setting */
+	mtk_phy_update_bits(xfi_tphy->base + 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5078, 0xf000400, is_5g ? 0x8000000 :
+									0x7000400);
+	mtk_phy_update_bits(xfi_tphy->base + 0x507c, 0x5000500, is_5g ? 0x4000400 :
+									0x1000100);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5080, 0x1410, is_1g ? 0x400 : is_5g ? 0x1010 : 0x0);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5084, 0x30300, is_1g ? 0x30300 :
+							      is_5g ? 0x30100 :
+								      0x100);
+	mtk_phy_update_bits(xfi_tphy->base + 0x5088, 0x60200, is_1g ? 0x20200 :
+							      is_5g ? 0x40000 :
+								      0x20000);
+
+	/* Setting RXFE adaptation range setting */
+	mtk_phy_update_bits(xfi_tphy->base + 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
+	mtk_phy_update_bits(xfi_tphy->base + 0x50a8, 0xee0000, is_5g ? 0x800000 :
+								       0x6e0000);
+	mtk_phy_update_bits(xfi_tphy->base + 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);
+
+	if (is_10g)
+		writel(0x01423342, xfi_tphy->base + 0x00f8);
+	else if (is_5g)
+		writel(0x00a132a1, xfi_tphy->base + 0x00f8);
+	else if (is_2p5g)
+		writel(0x009c329c, xfi_tphy->base + 0x00f8);
+	else
+		writel(0x00fa32fa, xfi_tphy->base + 0x00f8);
+
+	/* Force SGDT_OUT off and select PCS */
+	mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_F4,
+			    XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
+			    XFI_DPHY_AD_SGDT_FRC_EN |
+			    (use_lynxi_pcs ? XFI_DPHY_PCS_SEL_SGMII :
+					     XFI_DPHY_PCS_SEL_USXGMII));
+
+	/* Force GLB_CKDET_OUT */
+	mtk_phy_set_bits(xfi_tphy->base + 0x0030, 0xc00);
+
+	/* Force AEQ on */
+	writel(XTP_PCS_RX_EQ_IN_PROGRESS(2) | XTP_PCS_PWD_SYNC(2) | XTP_PCS_PWD_ASYNC(2),
+	       xfi_tphy->base + REG_DIG_GLB_70);
+
+	usleep_range(1, 5);
+
+	/* Setup TX DA default value */
+	mtk_phy_update_bits(xfi_tphy->base + 0x30b0, 0x30, 0x20);
+	writel(0x00008a01, xfi_tphy->base + 0x3028);
+	writel(0x0000a884, xfi_tphy->base + 0x302c);
+	writel(0x00083002, xfi_tphy->base + 0x3024);
+
+	/* Setup RG default value */
+	if (use_lynxi_pcs) {
+		writel(0x00011110, xfi_tphy->base + 0x3010);
+		writel(0x40704000, xfi_tphy->base + 0x3048);
+	} else {
+		writel(0x00022220, xfi_tphy->base + 0x3010);
+		writel(0x0f020a01, xfi_tphy->base + 0x5064);
+		writel(0x06100600, xfi_tphy->base + 0x50b4);
+		if (interface == PHY_INTERFACE_MODE_USXGMII)
+			writel(0x40704000, xfi_tphy->base + 0x3048);
+		else
+			writel(0x47684100, xfi_tphy->base + 0x3048);
+	}
+
+	if (is_1g)
+		writel(0x0000c000, xfi_tphy->base + 0x3064);
+
+	/* Setup RX EQ initial value */
+	mtk_phy_update_bits(xfi_tphy->base + 0x3050, 0xa8000000,
+			    (interface != PHY_INTERFACE_MODE_10GBASER) ? 0xa8000000 : 0x0);
+	mtk_phy_update_bits(xfi_tphy->base + 0x3054, 0xaa,
+			    (interface != PHY_INTERFACE_MODE_10GBASER) ? 0xaa : 0x0);
+
+	if (!use_lynxi_pcs)
+		writel(0x00000f00, xfi_tphy->base + 0x306c);
+	else if (is_2p5g)
+		writel(0x22000f00, xfi_tphy->base + 0x306c);
+	else
+		writel(0x20200f00, xfi_tphy->base + 0x306c);
+
+	mtk_phy_update_bits(xfi_tphy->base + 0xa008, 0x10000, da_war ? 0x10000 : 0x0);
+
+	mtk_phy_update_bits(xfi_tphy->base + 0xa060, 0x50000, use_lynxi_pcs ? 0x50000 : 0x40000);
+
+	/* Setup PHYA speed */
+	mtk_phy_update_bits(xfi_tphy->base + REG_ANA_GLB_D0,
+			    XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
+			    is_10g ?  XTP_GLB_USXGMII_SEL(0) :
+			    is_5g ?   XTP_GLB_USXGMII_SEL(1) :
+			    is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
+				      XTP_GLB_USXGMII_SEL(3));
+	mtk_phy_set_bits(xfi_tphy->base + REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
+
+	/* Release reset */
+	mtk_phy_set_bits(xfi_tphy->base + REG_DIG_GLB_70,
+			 XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
+	usleep_range(150, 500);
+
+	/* Switch to P0 */
+	mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
+			    XTP_PCS_IN_FR_RG |
+			    XTP_FRC_PCS_PWD_ASYNC |
+			    XTP_PCS_PWD_ASYNC_MASK |
+			    XTP_PCS_PWD_SYNC_MASK |
+			    XTP_PCS_UPDT,
+			    XTP_PCS_IN_FR_RG |
+			    XTP_FRC_PCS_PWD_ASYNC |
+			    XTP_PCS_UPDT);
+	usleep_range(1, 5);
+
+	mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_70, XTP_PCS_UPDT);
+	usleep_range(15, 50);
+
+	if (use_lynxi_pcs) {
+		/* Switch to Gen2 */
+		mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
+				    XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
+				    XTP_PCS_MODE(1) | XTP_PCS_UPDT);
+	} else {
+		/* Switch to Gen3 */
+		mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
+				    XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
+				    XTP_PCS_MODE(2) | XTP_PCS_UPDT);
+	}
+	usleep_range(1, 5);
+
+	mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_70, XTP_PCS_UPDT);
+
+	usleep_range(100, 500);
+
+	/* Enable MAC CK */
+	mtk_phy_set_bits(xfi_tphy->base + REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
+	mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN);
+
+	/* Enable TX data */
+	mtk_phy_set_bits(xfi_tphy->base + REG_DIG_LN_TRX_40,
+			 XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
+	usleep_range(400, 1000);
+}
+
+static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int
+				 submode)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	if (mode != PHY_MODE_ETHERNET)
+		return -EINVAL;
+
+	switch (submode) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		mtk_xfi_tphy_setup(xfi_tphy, submode);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mtk_xfi_tphy_reset(struct phy *phy)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	reset_control_assert(xfi_tphy->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(xfi_tphy->reset);
+	usleep_range(1, 10);
+
+	return 0;
+}
+
+static int mtk_xfi_tphy_power_on(struct phy *phy)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
+}
+
+static int mtk_xfi_tphy_power_off(struct phy *phy)
+{
+	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
+
+	clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_xfi_tphy_ops = {
+	.power_on	= mtk_xfi_tphy_power_on,
+	.power_off	= mtk_xfi_tphy_power_off,
+	.set_mode	= mtk_xfi_tphy_set_mode,
+	.reset		= mtk_xfi_tphy_reset,
+	.owner		= THIS_MODULE,
+};
+
+static int mtk_xfi_tphy_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct phy_provider *phy_provider;
+	struct mtk_xfi_tphy *xfi_tphy;
+	struct phy *phy;
+	int ret;
+
+	if (!np)
+		return -ENODEV;
+
+	xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
+	if (!xfi_tphy)
+		return -ENOMEM;
+
+	xfi_tphy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(xfi_tphy->base))
+		return PTR_ERR(xfi_tphy->base);
+
+	xfi_tphy->dev = &pdev->dev;
+	xfi_tphy->clocks[0].id = "topxtal";
+	xfi_tphy->clocks[1].id = "xfipll";
+	ret = devm_clk_bulk_get(&pdev->dev, MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
+	if (ret)
+		return ret;
+
+	xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(xfi_tphy->reset))
+		return PTR_ERR(xfi_tphy->reset);
+
+	xfi_tphy->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata");
+
+	phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	phy_set_drvdata(phy, xfi_tphy);
+	phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id mtk_xfi_tphy_match[] = {
+	{ .compatible = "mediatek,mt7988-xfi-tphy", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
+
+static struct platform_driver mtk_xfi_tphy_driver = {
+	.probe = mtk_xfi_tphy_probe,
+	.driver = {
+		.name = "mtk-xfi-tphy",
+		.of_match_table = mtk_xfi_tphy_match,
+	},
+};
+module_platform_driver(mtk_xfi_tphy_driver);
+
+MODULE_DESCRIPTION("MediaTek 10GE SerDes XFI T-PHY driver");
+MODULE_AUTHOR("Daniel Golle <daniel at makrotopia.org>");
+MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen at mediatek.com>");
+MODULE_LICENSE("GPL");
-- 
2.43.0


From sboyd at kernel.org  Fri Feb  9 18:59:33 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 09 Feb 2024 18:59:33 -0800
Subject: [PATCH v3 7/7] of: Add KUnit test to confirm DTB is loaded
In-Reply-To: <CAMuHMdUuP5Ya2gU3V_ET=Ji_+yx+jr7eCch5uDJSqvQN9jJM3g@mail.gmail.com>
References: <20240202195909.3458162-1-sboyd@kernel.org> <20240202195909.3458162-8-sboyd@kernel.org> <CABVgOS=A8BQ6HHpBKFqg-N10ckk2XYavaS-MPXvZ0wenrVm=1g@mail.gmail.com> <89892ecd6b1b043db58258705c32b02b.sboyd@kernel.org> <CAMuHMdUuP5Ya2gU3V_ET=Ji_+yx+jr7eCch5uDJSqvQN9jJM3g@mail.gmail.com>
Message-ID: <2185a3cc3152a0b9a94b0c64353bc9a1.sboyd@kernel.org>

Quoting Geert Uytterhoeven (2024-02-05 11:55:29)
> On Mon, Feb 5, 2024 at 8:19?PM Stephen Boyd <sboyd at kernel.org> wrote:
> > Quoting David Gow (2024-02-02 20:10:17)
> > > On Sat, 3 Feb 2024 at 03:59, Stephen Boyd <sboyd at kernel.org> wrote:
> > > > Add a KUnit test that confirms a DTB has been loaded, i.e. there is a
> > > > root node, and that the of_have_populated_dt() API works properly.
> > > >
> > > > Cc: Rob Herring <robh+dt at kernel.org>
> > > > Cc: Frank Rowand <frowand.list at gmail.com>
> > > > Cc: David Gow <davidgow at google.com>
> > > > Cc: Brendan Higgins <brendan.higgins at linux.dev>
> > > > Signed-off-by: Stephen Boyd <sboyd at kernel.org>
> > > > ---
> > >
> > > This looks pretty good to me test-wise, though it still fails on m68k.
> > > (Everything else I tried it on works, though I've definitely not tried
> > > _every_ architecture.)
> > >
> > > aarch64: PASSED
> > > i386: PASSED
> > > x86_64: PASSED
> > > x86_64 KASAN: PASSED
> > > powerpc64: PASSED
> > > UML: PASSED
> > > UML LLVM: PASSED
> > > m68k: FAILED
> > > > $ qemu-system-m68k -nodefaults -m 1024 -kernel .kunit-all-m68k/vmlinux -append 'kunit.enable=1 console=hvc0 kunit_shutdown=reboot' -no-reboot -nographic -serial stdio -machine virt
> > > > [11:55:05] ===================== dtb (2 subtests) =====================
> > > > [11:55:05] # dtb_root_node_found_by_path: EXPECTATION FAILED at drivers/of/of_test.c:18
> > > > [11:55:05] Expected np is not null, but is
> > > > [11:55:05] [FAILED] dtb_root_node_found_by_path
> > > > [11:55:05] # dtb_root_node_populates_of_root: EXPECTATION FAILED at drivers/of/of_test.c:28
> > > > [11:55:05] Expected of_root is not null, but is
> > > > [11:55:05] [FAILED] dtb_root_node_populates_of_root
> > > > [11:55:05]     # module: of_test
> > > > [11:55:05] # dtb: pass:0 fail:2 skip:0 total:2
> > > > [11:55:05] # Totals: pass:0 fail:2 skip:0 total:2
> > > > [11:55:05] ======================= [FAILED] dtb =======================
> >
> > Ah yeah I forgot to mention that. m68k fails because it doesn't call the
> > unflatten_(and_copy)?_device_tree() function, so we don't populate a
> > root node on that architecture. One solution would be to make CONFIG_OF
> > unavailable on m68k. Or we have to make sure DT works on any
> > architecture. Rob, what do you prefer here?
> 
> I guess the latter?
> Alpha, hexagon, parisc, s390, and sparc are also lacking calls
> to unflatten.*device_tree().
> 

sparc does that on purpose. Perhaps it's simplest to call
unflatten_device_tree() if of_root is still NULL after setup_arch()
returns.

---8<---
diff --git a/init/main.c b/init/main.c
index e24b0780fdff..02f5cf8be6c1 100644
--- a/init/main.c
+++ b/init/main.c
@@ -97,6 +97,8 @@
 #include <linux/jump_label.h>
 #include <linux/kcsan.h>
 #include <linux/init_syscalls.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
 #include <linux/stackdepot.h>
 #include <linux/randomize_kstack.h>
 #include <net/net_namespace.h>
@@ -895,6 +897,8 @@ void start_kernel(void)
 	pr_notice("%s", linux_banner);
 	early_security_init();
 	setup_arch(&command_line);
+	if (!of_root)
+		unflatten_device_tree();
 	setup_boot_config();
 	setup_command_line(command_line);
 	setup_nr_cpu_ids();


From florian.fainelli at broadcom.com  Fri Feb  9 19:06:36 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Fri, 9 Feb 2024 19:06:36 -0800
Subject: [PATCH v3 07/19] power: reset: brcm-kona-reset: Use
 devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240208170410.67975-8-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
 <20240208170410.67975-8-afd@ti.com>
Message-ID: <22c84d5c-cbc6-42bf-9909-0e1aae512eb2@broadcom.com>



On 2/8/2024 9:03 AM, Andrew Davis wrote:
> Use device life-cycle managed register function to simplify probe.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240209/c7c516bb/attachment.p7s>

From swboyd at chromium.org  Fri Feb  9 23:09:11 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:11 -0800
Subject: [PATCH 00/22] platform/chrome: Add DT USB/DP muxing/topology to Trogdor
Message-ID: <20240210070934.2549994-1-swboyd@chromium.org>

This series adds support for fully describing the USB/DP topology on
ChromeOS Trogdor devices in DT. Trogdor devices have a single DP phy in
the AP that is muxed to one of two usb type-c connectors depending on
which port asserts HPD first to the EC. We'd like to know which port is
connected to an external monitor to provide a better experience to the
user about things like which type-c port is displaying DP or which
type-c hub is acting up, etc. Describing the connection all the way from
the source to the connector will allow us to do this. There will be some
more work to do after this to wire up sysfs connections, but that work
has already started or finished so it should be mostly minor changes to
support DT there.

This patch series is large, unfortunately, and is ordered in logical
groups: gpio, USB, DRM, typec, and finally dts to put it all together.
There's more that could be put in here, e.g. supporting ChromeOS Corsola
devices, but I wanted to get something out there early instead of
waiting to make this work with everything that exists today and posting
it then.

Onto the patches: 

First is the EC GPIO driver, which is dependency free and can be merged
at any time. It's only needed to provide information about which port
the EC is steering DP to, because the EC had a bug where it never told
the AP about which port has HPD asserted or not.

Second is the USB binding and hub patches. These are used to describe
how the USB hub is wired up on all the Trogdor devices, and make the
connect_type be something besides "unknown" on DT devices. ACPI has
supported setting a proper connect_type for some time now. These can
also be merged pretty much dependency free, except that the dt binding
will be needed to avoid DT binding check failures. I don't think those
checks are fatal though, so probably also fine to take this part
independently.

Third is the DRM bridge patches. These are used to implement lane
assignment for DP altmode configurations through the drm_bridge code.
The typec code will use this to tell the DP phy how many lanes of DP to
drive and which lanes to drive out to the USB type-c connector. Adding
support for lane assignment allows us to implement DP muxing as well,
physically splitting the DP lanes on the DP phy so that hardware doesn't
have to use an analog mux to steer two DP lanes to one or the other
type-c port. These are a hard dependency for the typec code.

Fourth is the typec patches, that ties together everything that comes
before it in this series. The EC typec switch driver implements a
drm_bridge that can signal HPD from the type-c connector through the
bridge chain, mux the DP phy in software so that we don't have to use an
analog mux, and implement orientation control for boards like Kukui that
directly connect the DP phy to the type-c port, necessitating lane
assignment to flip the lanes to match the cable orientation.

Finally, the dts patches wire everything up to fully describe the USB/DT
topology on Trogdor. This includes the USB hub, the EC gpios, the DP
controller, and the external connectors like the usb-c and usb-a
connectors.

After this initial version I will probably split this series and send
parts in pieces to more rapidly send new versions. Those parts will
refer back to this version in the cover letter so we can all get the
full context. I don't expect to merge this through one maintainer tree
immediately, so I set the 'To' line to chrome-platform to reflect the
overall target audience.

Prashant Malani (1):
  platform/chrome: cros_ec_typec: Purge blocking switch devlinks

Stephen Boyd (21):
  dt-bindings: gpio: Add binding for ChromeOS EC GPIO controller
  gpio: Add ChromeOS EC GPIO driver
  dt-bindings: usb: Add downstream facing ports to realtek binding
  usb: core: Set connect_type of ports based on DT node
  drm/atomic-helper: Introduce lane remapping support to bridges
  drm/bridge: Verify lane assignment is going to work during
    atomic_check
  device property: Add remote endpoint to devcon matcher
  platform/chrome: cros_typec_switch: Use read_poll_timeout helper
  platform/chrome: cros_typec_switch: Move port creation code to
    sub-function
  platform/chrome: cros_typec_switch: Use fwnode instead of ACPI APIs
  platform/chrome: cros_typec_switch: Use dev_err_probe()
  dt-bindings: chrome: Add google,cros-ec-typec-switch binding
  platform/chrome: cros_typec_switch: Add support for signaling HPD to
    drm_bridge
  platform/chrome: cros_typec_switch: Support DP muxing via DRM lane
    assignment
  platform/chrome: cros_typec_switch: Support orientation-switch
  platform/chrome: cros_typec_switch: Handle lack of HPD information
  dt-bindings: chrome: Add binding for ChromeOS Pogo pin connector
  arm64: dts: qcom: sc7180: quackingstick: Disable instead of delete
    usb_c1
  arm64: dts: qcom: sc7180: pazquel: Add missing comment header
  arm64: dts: qcom: sc7180-trogdor: Make clamshell/detachable fragments
  arm64: dts: qcom: sc7180-trogdor: Wire up USB and DP to
    usb-c-connectors

 .../chrome/google,cros-ec-typec-switch.yaml   | 365 ++++++++++++
 .../chrome/google,pogo-pin-connector.yaml     |  61 ++
 .../bindings/gpio/google,cros-ec-gpio.yaml    |  49 ++
 .../bindings/mfd/google,cros-ec.yaml          |   8 +
 .../bindings/usb/realtek,rts5411.yaml         |  50 ++
 .../dts/qcom/sc7180-trogdor-clamshell.dtsi    |  30 +
 .../boot/dts/qcom/sc7180-trogdor-coachz.dtsi  |  52 +-
 .../dts/qcom/sc7180-trogdor-detachable.dtsi   |  25 +
 .../dts/qcom/sc7180-trogdor-homestar.dtsi     |  54 +-
 .../dts/qcom/sc7180-trogdor-kingoftown.dts    |  57 +-
 .../boot/dts/qcom/sc7180-trogdor-lazor.dtsi   |  58 +-
 .../boot/dts/qcom/sc7180-trogdor-pazquel.dtsi |  59 +-
 .../boot/dts/qcom/sc7180-trogdor-pompom.dtsi  |  46 +-
 .../qcom/sc7180-trogdor-quackingstick.dtsi    |  46 +-
 .../arm64/boot/dts/qcom/sc7180-trogdor-r1.dts |   2 +-
 .../dts/qcom/sc7180-trogdor-wormdingler.dtsi  |  52 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  | 175 ++++++
 drivers/base/property.c                       |   7 +-
 drivers/gpio/Kconfig                          |  10 +
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-cros-ec.c                   | 218 +++++++
 drivers/gpu/drm/drm_atomic_state_helper.c     |   2 +
 drivers/gpu/drm/drm_bridge.c                  |  50 ++
 drivers/platform/chrome/Kconfig               |   3 +-
 drivers/platform/chrome/cros_ec_typec.c       |  10 +
 drivers/platform/chrome/cros_typec_switch.c   | 555 +++++++++++++++---
 drivers/usb/core/port.c                       |  37 ++
 drivers/usb/roles/class.c                     |   4 +-
 drivers/usb/typec/mux.c                       |   8 +
 drivers/usb/typec/retimer.c                   |   7 +-
 include/drm/drm_atomic.h                      |  31 +
 include/drm/drm_bridge.h                      |   4 +
 include/linux/property.h                      |   5 +-
 33 files changed, 2026 insertions(+), 115 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
 create mode 100644 Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml
 create mode 100644 Documentation/devicetree/bindings/gpio/google,cros-ec-gpio.yaml
 create mode 100644 arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
 create mode 100644 drivers/gpio/gpio-cros-ec.c

Cc: Alexandre Belloni <alexandre.belloni at bootlin.com>
Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Andy Gross <agross at kernel.org>
Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Cc: Bartosz Golaszewski <brgl at bgdev.pl>
Cc: Benson Leung <bleung at chromium.org>
Cc: Bjorn Andersson <andersson at kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: <cros-qcom-dts-watchers at chromium.org>
Cc: Daniel Scally <djrscally at gmail.com>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: David Airlie <airlied at gmail.com>
Cc: <devicetree at vger.kernel.org>
Cc: <dri-devel at lists.freedesktop.org>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Guenter Roeck <groeck at chromium.org>
Cc: Heikki Krogerus <heikki.krogerus at linux.intel.com>
Cc: Ivan Orlov <ivan.orlov0322 at gmail.com>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: Jonas Karlman <jonas at kwiboo.se>
Cc: Konrad Dybcio <konrad.dybcio at linaro.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
Cc: Lee Jones <lee at kernel.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: <linux-acpi at vger.kernel.org>
Cc: <linux-arm-msm at vger.kernel.org>
Cc: <linux-gpio at vger.kernel.org>
Cc: <linux-usb at vger.kernel.org>
Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Cc: maciek swiech <drmasquatch at google.com>
Cc: Matthias Kaehlcke <mka at chromium.org>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Mika Westerberg <mika.westerberg at linux.intel.com>
Cc: Neil Armstrong <neil.armstrong at linaro.org>
Cc: Pin-yen Lin <treapking at chromium.org>
Cc: Prashant Malani <pmalani at chromium.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki at intel.com>
Cc: Robert Foss <rfoss at kernel.org>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Sakari Ailus <sakari.ailus at linux.intel.com>
Cc: Thomas Zimmermann <tzimmermann at suse.de>
Cc: Tzung-Bi Shih <tzungbi at kernel.org>
Cc: Vinod Koul <vkoul at kernel.org>

base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
-- 
https://chromeos.dev


From swboyd at chromium.org  Fri Feb  9 23:09:12 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:12 -0800
Subject: [PATCH 01/22] dt-bindings: gpio: Add binding for ChromeOS EC GPIO controller
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-2-swboyd@chromium.org>

The ChromeOS embedded controller (EC) supports setting the state of
GPIOs when the system is unlocked, and getting the state of GPIOs in all
cases. The GPIOs are on the EC itself, so the EC acts similar to a GPIO
expander. Add a binding to describe these GPIOs in DT so that other
devices described in DT can read the GPIOs on the EC.

Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Bartosz Golaszewski <brgl at bgdev.pl>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: Lee Jones <lee at kernel.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Guenter Roeck <groeck at chromium.org>
Cc: <linux-gpio at vger.kernel.org>
Cc: <devicetree at vger.kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 .../bindings/gpio/google,cros-ec-gpio.yaml    | 49 +++++++++++++++++++
 .../bindings/mfd/google,cros-ec.yaml          |  3 ++
 2 files changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/google,cros-ec-gpio.yaml

diff --git a/Documentation/devicetree/bindings/gpio/google,cros-ec-gpio.yaml b/Documentation/devicetree/bindings/gpio/google,cros-ec-gpio.yaml
new file mode 100644
index 000000000000..a9f1d7784070
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/google,cros-ec-gpio.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/google,cros-ec-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GPIOs controlled by ChromeOS EC
+
+maintainers:
+  - Stephen Boyd <swboyd at chromium.org>
+
+description:
+  Google's ChromeOS EC has a gpio controller inside the Embedded Controller
+  (EC) and controlled via a host-command interface. The node for this
+  device should be under a cros-ec node like google,cros-ec-spi.
+
+properties:
+  compatible:
+    const: google,cros-ec-gpio
+
+  '#gpio-cells':
+    const: 2
+
+  gpio-controller: true
+
+required:
+  - compatible
+  - '#gpio-cells'
+  - gpio-controller
+
+additionalProperties: false
+
+examples:
+  - |
+    spi {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      cros-ec at 0 {
+        compatible = "google,cros-ec-spi";
+        reg = <0>;
+        interrupts = <101 0>;
+        gpio {
+          compatible = "google,cros-ec-gpio";
+          gpio-controller;
+          #gpio-cells = <2>;
+        };
+      };
+    };
diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
index e1ca4f297c6d..ded396b28fba 100644
--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
+++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
@@ -93,6 +93,9 @@ properties:
   '#size-cells':
     const: 0
 
+  gpio:
+    $ref: /schemas/gpio/google,cros-ec-gpio.yaml#
+
   typec:
     $ref: /schemas/chrome/google,cros-ec-typec.yaml#
 
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:13 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:13 -0800
Subject: [PATCH 02/22] gpio: Add ChromeOS EC GPIO driver
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-3-swboyd@chromium.org>

The ChromeOS embedded controller (EC) supports setting the state of
GPIOs when the system is unlocked, and getting the state of GPIOs in all
cases. The GPIOs are on the EC itself, so the EC acts similar to a GPIO
expander. Add a driver to get and set the GPIOs on the EC through the
host command interface.

Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Bartosz Golaszewski <brgl at bgdev.pl>
Cc: Benson Leung <bleung at chromium.org>
Cc: Guenter Roeck <groeck at chromium.org>
Cc: <linux-gpio at vger.kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/gpio/Kconfig        |  10 ++
 drivers/gpio/Makefile       |   1 +
 drivers/gpio/gpio-cros-ec.c | 218 ++++++++++++++++++++++++++++++++++++
 3 files changed, 229 insertions(+)
 create mode 100644 drivers/gpio/gpio-cros-ec.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b3a133ed31ee..62b0ae25a727 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1220,6 +1220,16 @@ config GPIO_BD9571MWV
 	  This driver can also be built as a module. If so, the module
 	  will be called gpio-bd9571mwv.
 
+config GPIO_CROS_EC
+	tristate "ChromeOS EC GPIO support"
+	depends on CROS_EC
+	help
+	  GPIO driver for exposing GPIOs on the ChromeOS Embedded
+	  Controller.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called gpio-cros-ec.
+
 config GPIO_CRYSTAL_COVE
 	tristate "GPIO support for Crystal Cove PMIC"
 	depends on (X86 || COMPILE_TEST) && INTEL_SOC_PMIC
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index eb73b5d633eb..2e66410c1da6 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_GPIO_BT8XX)		+= gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CADENCE)		+= gpio-cadence.o
 obj-$(CONFIG_GPIO_CLPS711X)		+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_SNPS_CREG)		+= gpio-creg-snps.o
+obj-$(CONFIG_GPIO_CROS_EC)		+= gpio-cros-ec.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)		+= gpio-crystalcove.o
 obj-$(CONFIG_GPIO_CS5535)		+= gpio-cs5535.o
 obj-$(CONFIG_GPIO_DA9052)		+= gpio-da9052.o
diff --git a/drivers/gpio/gpio-cros-ec.c b/drivers/gpio/gpio-cros-ec.c
new file mode 100644
index 000000000000..0d35558304bf
--- /dev/null
+++ b/drivers/gpio/gpio-cros-ec.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2024 Google LLC
+ *
+ * This driver provides the ability to control GPIOs on the Chrome OS EC.
+ * There isn't any direction control, and setting values on GPIOs is only
+ * possible when the system is unlocked.
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/gpio/driver.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_data/cros_ec_commands.h>
+#include <linux/platform_data/cros_ec_proto.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* Setting gpios is only supported when the system is unlocked */
+static void cros_ec_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	const char *name = gc->names[gpio];
+	struct cros_ec_device *cros_ec = gpiochip_get_data(gc);
+	struct ec_params_gpio_set params = {
+		.val = val,
+	};
+	int ret;
+	ssize_t copied;
+
+	copied = strscpy(params.name, name, sizeof(params.name));
+	if (copied < 0)
+		return;
+
+	ret = cros_ec_cmd(cros_ec, 0, EC_CMD_GPIO_SET, &params,
+			  sizeof(params), NULL, 0);
+	if (ret < 0)
+		dev_err(gc->parent, "error setting gpio%d (%s) on EC: %d\n", gpio, name, ret);
+}
+
+static int cros_ec_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+	const char *name = gc->names[gpio];
+	struct cros_ec_device *cros_ec = gpiochip_get_data(gc);
+	struct ec_params_gpio_get params;
+	struct ec_response_gpio_get response;
+	int ret;
+	ssize_t copied;
+
+	copied = strscpy(params.name, name, sizeof(params.name));
+	if (copied < 0)
+		return -EINVAL;
+
+	ret = cros_ec_cmd(cros_ec, 0, EC_CMD_GPIO_GET, &params,
+			  sizeof(params), &response, sizeof(response));
+	if (ret < 0) {
+		dev_err(gc->parent, "error getting gpio%d (%s) on EC: %d\n", gpio, name, ret);
+		return ret;
+	}
+
+	return response.val;
+}
+
+#define CROS_EC_GPIO_INPUT         BIT(8)
+#define CROS_EC_GPIO_OUTPUT        BIT(9)
+
+static int cros_ec_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)
+{
+	const char *name = gc->names[gpio];
+	struct cros_ec_device *cros_ec = gpiochip_get_data(gc);
+	struct ec_params_gpio_get_v1 params = {
+		.subcmd = EC_GPIO_GET_INFO,
+		.get_info.index = gpio,
+	};
+	struct ec_response_gpio_get_v1 response;
+	int ret;
+
+	ret = cros_ec_cmd(cros_ec, 1, EC_CMD_GPIO_GET, &params,
+			  sizeof(params), &response, sizeof(response));
+	if (ret < 0) {
+		dev_err(gc->parent, "error getting direction of gpio%d (%s) on EC: %d\n", gpio, name, ret);
+		return ret;
+	}
+
+	if (response.get_info.flags & CROS_EC_GPIO_INPUT)
+		return GPIO_LINE_DIRECTION_IN;
+
+	if (response.get_info.flags & CROS_EC_GPIO_OUTPUT)
+		return GPIO_LINE_DIRECTION_OUT;
+
+	return -EINVAL;
+}
+
+static int cros_ec_gpio_request(struct gpio_chip *chip, unsigned gpio_pin)
+{
+	if (gpio_pin < chip->ngpio)
+		return 0;
+
+	return -EINVAL;
+}
+
+/* Query EC for all gpio line names */
+static int cros_ec_gpio_init_names(struct cros_ec_device *cros_ec, struct gpio_chip *gc)
+{
+	struct ec_params_gpio_get_v1 params = {
+		.subcmd = EC_GPIO_GET_INFO,
+	};
+	struct ec_response_gpio_get_v1 response;
+	int ret, i;
+	/* EC may not NUL terminate */
+	size_t name_len = sizeof(response.get_info.name) + 1;
+	ssize_t copied;
+	const char **names;
+	char *str;
+
+	names = devm_kcalloc(gc->parent, gc->ngpio, sizeof(*names), GFP_KERNEL);
+	if (!names)
+		return -ENOMEM;
+	gc->names = names;
+
+	str = devm_kcalloc(gc->parent, gc->ngpio, name_len, GFP_KERNEL);
+	if (!str)
+		return -ENOMEM;
+
+	/* Get gpio line names one at a time */
+	for (i = 0; i < gc->ngpio; i++) {
+		params.get_info.index = i;
+		ret = cros_ec_cmd(cros_ec, 1, EC_CMD_GPIO_GET, &params,
+				  sizeof(params), &response, sizeof(response));
+		if (ret < 0) {
+			dev_err_probe(gc->parent, ret, "error getting gpio%d info\n", i);
+			return ret;
+		}
+
+		names[i] = str;
+		copied = strscpy(str, response.get_info.name, name_len);
+		if (copied < 0)
+			return copied;
+
+		str += copied + 1;
+	}
+
+	return 0;
+}
+
+/* Query EC for number of gpios */
+static int cros_ec_gpio_ngpios(struct cros_ec_device *cros_ec)
+{
+	struct ec_params_gpio_get_v1 params = {
+		.subcmd = EC_GPIO_GET_COUNT,
+	};
+	struct ec_response_gpio_get_v1 response;
+	int ret;
+
+	ret = cros_ec_cmd(cros_ec, 1, EC_CMD_GPIO_GET, &params,
+			  sizeof(params), &response, sizeof(response));
+	if (ret < 0)
+		return ret;
+
+	return response.get_count.val;
+}
+
+static int cros_ec_gpio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cros_ec_device *cros_ec = dev_get_drvdata(dev->parent);
+	struct gpio_chip *gc;
+	int ngpios;
+	int ret;
+
+	ngpios = cros_ec_gpio_ngpios(cros_ec);
+	if (ngpios < 0) {
+		dev_err_probe(dev, ngpios, "error getting gpio count\n");
+		return ngpios;
+	}
+
+	gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
+	if (!gc)
+		return -ENOMEM;
+
+	gc->ngpio = ngpios;
+	gc->parent = dev;
+	ret = cros_ec_gpio_init_names(cros_ec, gc);
+	if (ret)
+		return ret;
+
+	gc->can_sleep = true;
+	gc->label = dev_name(dev);
+	gc->base = -1;
+	gc->set = cros_ec_gpio_set;
+	gc->get = cros_ec_gpio_get;
+	gc->get_direction = cros_ec_gpio_get_direction;
+	gc->request = cros_ec_gpio_request;
+
+	return devm_gpiochip_add_data(&pdev->dev, gc, cros_ec);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id cros_ec_gpio_of_match[] = {
+	{ .compatible = "google,cros-ec-gpio" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, cros_ec_gpio_of_match);
+#endif
+
+static struct platform_driver cros_ec_gpio_driver = {
+	.probe = cros_ec_gpio_probe,
+	.driver = {
+		.name = "cros-ec-gpio",
+		.of_match_table = of_match_ptr(cros_ec_gpio_of_match),
+	},
+};
+module_platform_driver(cros_ec_gpio_driver);
+
+MODULE_DESCRIPTION("ChromeOS EC GPIO Driver");
+MODULE_LICENSE("GPL");
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:14 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:14 -0800
Subject: [PATCH 03/22] dt-bindings: usb: Add downstream facing ports to realtek binding
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-4-swboyd@chromium.org>

Add a graph with 4 output endpoints to this hub binding to support the
scenario where a downstream facing port is connected to a device that
isn't a connector or a USB device with a VID:PID. This will be used to
connect downstream facing ports to USB type-c switches so the USB
superspeed and high speed lanes can be put onto USB connectors.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: Matthias Kaehlcke <mka at chromium.org>
Cc: <linux-usb at vger.kernel.org>
Cc: <devicetree at vger.kernel.org>
Cc: Pin-yen Lin <treapking at chromium.org>
Cc: maciek swiech <drmasquatch at google.com>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 .../bindings/usb/realtek,rts5411.yaml         | 50 +++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/realtek,rts5411.yaml b/Documentation/devicetree/bindings/usb/realtek,rts5411.yaml
index f0784d2e86da..5480a31698be 100644
--- a/Documentation/devicetree/bindings/usb/realtek,rts5411.yaml
+++ b/Documentation/devicetree/bindings/usb/realtek,rts5411.yaml
@@ -21,6 +21,12 @@ properties:
 
   reg: true
 
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
   vdd-supply:
     description:
       phandle to the regulator that provides power to the hub.
@@ -30,6 +36,36 @@ properties:
     description:
       phandle to the peer hub on the controller.
 
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          1st downstream facing USB port
+
+      port at 2:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          2nd downstream facing USB port
+
+      port at 3:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          3rd downstream facing USB port
+
+      port at 4:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          4th downstream facing USB port
+
+patternProperties:
+  "^.*@[1-4]$":
+    description: The hard wired USB devices
+    type: object
+    $ref: /schemas/usb/usb-device.yaml
+
 required:
   - peer-hub
   - compatible
@@ -50,6 +86,11 @@ examples:
             reg = <1>;
             vdd-supply = <&pp3300_hub>;
             peer-hub = <&hub_3_0>;
+            /* USB 2.0 device on port 2 */
+            device at 2 {
+                compatible = "usb123,4567";
+                reg = <2>;
+            };
         };
 
         /* 3.0 hub on port 2 */
@@ -58,5 +99,14 @@ examples:
             reg = <2>;
             vdd-supply = <&pp3300_hub>;
             peer-hub = <&hub_2_0>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                port at 0 {
+                    reg = <0>;
+                    remote-endpoint = <&usb_a0_ss>;
+                };
+            };
         };
     };
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:15 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:15 -0800
Subject: [PATCH 04/22] usb: core: Set connect_type of ports based on DT node
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-5-swboyd@chromium.org>

When a USB hub is described in DT, such as any device that matches the
onboard-hub driver, the connect_type is set to "unknown" or
USB_PORT_CONNECT_TYPE_UNKNOWN. This makes any device plugged into that
USB port report their 'removable' device attribute as "unknown". Improve
the connect_type attribute for ports, and in turn the removable
attribute for USB devices, by looking for child devices with a reg
property or an OF graph when the device is described in DT.

If the graph exists, endpoints that are connected to a remote node must
be something like a usb-{a,b,c}-connector compatible node, or an
intermediate node like a redriver, and not a hardwired USB device on the
board. Set the connect_type to USB_PORT_CONNECT_TYPE_HOT_PLUG in this
case because the device is going to be plugged in. Set the connect_type
to USB_PORT_CONNECT_TYPE_HARD_WIRED if there's a child node for the port
like 'device at 2' for port2. Set the connect_type to USB_PORT_NOT_USED if
there isn't an endpoint or child node corresponding to the port number.

To make sure things don't change, only set the port to not used if
there are child nodes. This way an onboard hub connect_type doesn't
change until ports are added or child nodes are added to describe
hardwired devices. It's assumed that all ports or no ports will be
described for a device.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Matthias Kaehlcke <mka at chromium.org>
Cc: <linux-usb at vger.kernel.org>
Cc: <devicetree at vger.kernel.org>
Cc: Pin-yen Lin <treapking at chromium.org>
Cc: maciek swiech <drmasquatch at google.com>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/usb/core/port.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index c628c1abc907..622b8ada157c 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -9,6 +9,8 @@
 
 #include <linux/kstrtox.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/pm_qos.h>
 #include <linux/component.h>
 
@@ -696,7 +698,10 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 {
 	struct usb_port *port_dev;
 	struct usb_device *hdev = hub->hdev;
+	struct device_node *np, *child, *ep, *remote_np, *port_np;
 	int retval;
+	enum usb_port_connect_type connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
+	u32 reg;
 
 	port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
 	if (!port_dev)
@@ -708,6 +713,38 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 		return -ENOMEM;
 	}
 
+	np = hdev->dev.of_node;
+	/* Only set connect_type if binding has ports/hardwired devices. */
+	if (of_get_child_count(np))
+		connect_type = USB_PORT_NOT_USED;
+
+	/* Hotplug ports are connected and available in the OF graph. */
+	if (of_graph_is_present(np)) {
+		port_np = of_graph_get_port_by_id(np, port1);
+		if (port_np) {
+			ep = of_graph_get_endpoint_by_regs(np, port1, -1);
+			if (ep) {
+				remote_np = of_graph_get_remote_port_parent(ep);
+				of_node_put(ep);
+				if (of_device_is_available(remote_np))
+					connect_type = USB_PORT_CONNECT_TYPE_HOT_PLUG;
+				of_node_put(remote_np);
+			}
+		}
+		of_node_put(port_np);
+	}
+
+	/*
+	 * Hard-wired ports are child nodes with a reg property corresponding
+	 * to the port number.
+	 */
+	for_each_available_child_of_node(np, child) {
+		if (!of_property_read_u32(child, "reg", &reg) && reg == port1)
+			connect_type = USB_PORT_CONNECT_TYPE_HARD_WIRED;
+	}
+
+	port_dev->connect_type = connect_type;
+
 	hub->ports[port1 - 1] = port_dev;
 	port_dev->portnum = port1;
 	set_bit(port1, hub->power_bits);
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:16 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:16 -0800
Subject: [PATCH 05/22] drm/atomic-helper: Introduce lane remapping support to bridges
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-6-swboyd@chromium.org>

Add support to the DRM atomic logic to support lane remapping between
bridges, encoders and connectors. Typically lane mapping is handled
statically in firmware, e.g. on DT we use the data-lanes property to
assign lanes when connecting display bridges. Lane assignment is dynamic
with USB-C DisplayPort altmodes, e.g. pin conf D assigns 2 lanes of DP
to pins on the USB-C connector while pin conf C assigns 4 lanes of DP to
pins on the USB-C connector. The lane assignment can't be set statically
because the DP altmode repurposes USB-C pins for the DP lanes while also
limiting the number of DP lanes or their pin assignment at runtime.

Bridge drivers should point their 'struct drm_bus_cfg::lanes' pointer to
an allocated array of 'struct drm_lane_cfg' structures and indicate the
size of this allocated array with 'struct drm_bus_cfg::num_lanes' in
their atomic_check() callback. The previous bridge in the bridge chain
can look at this information by calling
drm_bridge_next_bridge_lane_cfg() in their atomic_check() callback to
figure out what lanes need to be logically assigned to the physical
output lanes to satisfy the next bridge's lane assignment.

Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Neil Armstrong <neil.armstrong at linaro.org>
Cc: Robert Foss <rfoss at kernel.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: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Thomas Zimmermann <tzimmermann at suse.de>
Cc: David Airlie <airlied at gmail.com>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: <dri-devel at lists.freedesktop.org>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c |  2 ++
 drivers/gpu/drm/drm_bridge.c              | 34 +++++++++++++++++++++++
 include/drm/drm_atomic.h                  | 31 +++++++++++++++++++++
 include/drm/drm_bridge.h                  |  4 +++
 4 files changed, 71 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 784e63d70a42..2e989fbeb503 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -764,6 +764,8 @@ EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state);
 void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge,
 					    struct drm_bridge_state *state)
 {
+	kfree(state->input_bus_cfg.lanes);
+	kfree(state->output_bus_cfg.lanes);
 	kfree(state);
 }
 EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state);
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 30d66bee0ec6..3fce0d8d7dcb 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -843,6 +843,40 @@ void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
 }
 EXPORT_SYMBOL(drm_atomic_bridge_chain_enable);
 
+/**
+ * drm_bridge_next_bridge_lane_cfg - get the lane configuration of the next bridge
+ * @bridge: bridge control structure
+ * @state: new atomic state
+ * @num_lanes: will contain the size of the returned array
+ *
+ * This function is typically called from &drm_bridge_funcs.atomic_check().
+ * The @bridge driver calls this function to determine what the next bridge in
+ * the bridge chain requires for the physical to logical lane assignments.
+ *
+ * Return: Lane configuration array of size @num_lanes for the next bridge
+ * after @bridge in the bridge chain, or NULL if the lane configuration is
+ * unchanged from the default.
+ */
+const struct drm_lane_cfg *
+drm_bridge_next_bridge_lane_cfg(struct drm_bridge *bridge,
+				struct drm_atomic_state *state,
+				u8 *num_lanes)
+{
+	const struct drm_bridge_state *next_bridge_state;
+	struct drm_bridge *next_bridge = drm_bridge_get_next_bridge(bridge);
+
+	next_bridge_state = drm_atomic_get_new_bridge_state(state, next_bridge);
+	if (!next_bridge_state) {
+		*num_lanes = 0;
+		return NULL;
+	}
+
+	*num_lanes = next_bridge_state->input_bus_cfg.num_lanes;
+
+	return next_bridge_state->input_bus_cfg.lanes;
+}
+EXPORT_SYMBOL(drm_bridge_next_bridge_lane_cfg);
+
 static int drm_atomic_bridge_check(struct drm_bridge *bridge,
 				   struct drm_crtc_state *crtc_state,
 				   struct drm_connector_state *conn_state)
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index cf8e1220a4ac..b206ae2654d8 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -1074,6 +1074,27 @@ drm_atomic_crtc_effectively_active(const struct drm_crtc_state *state)
 	return state->active || state->self_refresh_active;
 }
 
+/**
+ * struct drm_lane_cfg - lane configuration
+ *
+ * This structure stores the lange configuration of a physical bus between
+ * two components in an output pipeline, usually between two bridges, an
+ * encoder and a bridge, or a bridge and a connector.
+ *
+ * The lane configuration is stored in &drm_bus_cfg.
+ */
+struct drm_lane_cfg {
+	/**
+	 * @logical: Logical lane number
+	 */
+	u8 logical;
+
+	/**
+	 * @inverted: True if lane polarity is inverted, false otherwise
+	 */
+	bool inverted;
+};
+
 /**
  * struct drm_bus_cfg - bus configuration
  *
@@ -1104,6 +1125,16 @@ struct drm_bus_cfg {
 	 * @flags: DRM_BUS_* flags used on this bus
 	 */
 	u32 flags;
+
+	/**
+	 * @lanes: Lane mapping for this bus
+	 */
+	struct drm_lane_cfg *lanes;
+
+	/**
+	 * @num_lanes: Number of lanes in @lanes
+	 */
+	u8 num_lanes;
 };
 
 /**
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index cfb7dcdb66c4..5f64f6e822e1 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -884,6 +884,10 @@ drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge,
 					struct drm_connector_state *conn_state,
 					u32 output_fmt,
 					unsigned int *num_input_fmts);
+const struct drm_lane_cfg *
+drm_bridge_next_bridge_lane_cfg(struct drm_bridge *bridge,
+				struct drm_atomic_state *state,
+				u8 *num_lanes);
 
 enum drm_connector_status drm_bridge_detect(struct drm_bridge *bridge);
 int drm_bridge_get_modes(struct drm_bridge *bridge,
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:17 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:17 -0800
Subject: [PATCH 06/22] drm/bridge: Verify lane assignment is going to work during atomic_check
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-7-swboyd@chromium.org>

Verify during drm_atomic_bridge_check() that the lane assignment set in
a bridge's atomic_check() callback is going to be satisfied by the
previous bridge. If the next bridge is requiring something besides the
default 1:1 lane assignment on its input then there must be an output
lane assignment on the previous bridge's output. Otherwise the next
bridge won't get the lanes assigned that it needs.

Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Neil Armstrong <neil.armstrong at linaro.org>
Cc: Robert Foss <rfoss at kernel.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: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Thomas Zimmermann <tzimmermann at suse.de>
Cc: David Airlie <airlied at gmail.com>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: <dri-devel at lists.freedesktop.org>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/gpu/drm/drm_bridge.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 3fce0d8d7dcb..5097e7c65ddf 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -881,6 +881,10 @@ static int drm_atomic_bridge_check(struct drm_bridge *bridge,
 				   struct drm_crtc_state *crtc_state,
 				   struct drm_connector_state *conn_state)
 {
+	u8 num_input_lanes, num_output_lanes = 0;
+	const struct drm_lane_cfg *input_lanes;
+	int i;
+
 	if (bridge->funcs->atomic_check) {
 		struct drm_bridge_state *bridge_state;
 		int ret;
@@ -894,12 +898,24 @@ static int drm_atomic_bridge_check(struct drm_bridge *bridge,
 						  crtc_state, conn_state);
 		if (ret)
 			return ret;
+		num_output_lanes = bridge_state->output_bus_cfg.num_lanes;
 	} else if (bridge->funcs->mode_fixup) {
 		if (!bridge->funcs->mode_fixup(bridge, &crtc_state->mode,
 					       &crtc_state->adjusted_mode))
 			return -EINVAL;
 	}
 
+	input_lanes = drm_bridge_next_bridge_lane_cfg(bridge,
+						      crtc_state->state,
+						      &num_input_lanes);
+	/*
+	 * Ensure this bridge is aware that the next bridge wants to
+	 * reassign lanes.
+	 */
+	for (i = 0; i < num_input_lanes; i++)
+		if (i != input_lanes[i].logical && !num_output_lanes)
+			return -ENOTSUPP;
+
 	return 0;
 }
 
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:18 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:18 -0800
Subject: [PATCH 07/22] device property: Add remote endpoint to devcon matcher
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-8-swboyd@chromium.org>

When a single DT node has a graph connected to more than one
usb-c-connector node we can't differentiate which typec switch
registered for the device is associated with the USB connector because
the devcon matcher code assumes a 1:1 relationship between remote node
and typec switch. Furthermore, we don't have a #typec-switch-cells
property so there can only be one node per typec switch.

Support multiple USB typec switches exposed by one node by passing the
remote endpoint node in addition to the remote node to the devcon
matcher function (devcon_match_fn_t). With this change, typec switch
drivers can register switches with the device node pointer for a graph
endpoint so that they can support more than one typec switch if
necessary. Either way, a DT property like 'mode-switch' is always in the
graph's parent node and not in the endpoint node.

Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Cc: Daniel Scally <djrscally at gmail.com>
Cc: Heikki Krogerus <heikki.krogerus at linux.intel.com>
Cc: Sakari Ailus <sakari.ailus at linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Vinod Koul <vkoul at kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki at intel.com>
Cc: Mika Westerberg <mika.westerberg at linux.intel.com>
Cc: Alexandre Belloni <alexandre.belloni at bootlin.com>
Cc: Ivan Orlov <ivan.orlov0322 at gmail.com>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: <devicetree at vger.kernel.org>
Cc: <linux-usb at vger.kernel.org>
Cc: <linux-acpi at vger.kernel.org>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/base/property.c     | 7 +++++--
 drivers/usb/roles/class.c   | 4 ++--
 drivers/usb/typec/mux.c     | 8 ++++++++
 drivers/usb/typec/retimer.c | 7 ++++++-
 include/linux/property.h    | 5 +++--
 5 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/base/property.c b/drivers/base/property.c
index 8c40abed7852..cae81ed4e298 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -1289,6 +1289,7 @@ static unsigned int fwnode_graph_devcon_matches(const struct fwnode_handle *fwno
 {
 	struct fwnode_handle *node;
 	struct fwnode_handle *ep;
+	struct fwnode_handle *remote_ep;
 	unsigned int count = 0;
 	void *ret;
 
@@ -1304,7 +1305,9 @@ static unsigned int fwnode_graph_devcon_matches(const struct fwnode_handle *fwno
 			continue;
 		}
 
-		ret = match(node, con_id, data);
+		remote_ep = fwnode_graph_get_remote_endpoint(ep);
+		ret = match(node, remote_ep, con_id, data);
+		fwnode_handle_put(remote_ep);
 		fwnode_handle_put(node);
 		if (ret) {
 			if (matches)
@@ -1334,7 +1337,7 @@ static unsigned int fwnode_devcon_matches(const struct fwnode_handle *fwnode,
 		if (IS_ERR(node))
 			break;
 
-		ret = match(node, NULL, data);
+		ret = match(node, NULL, NULL, data);
 		fwnode_handle_put(node);
 		if (ret) {
 			if (matches)
diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
index ae41578bd014..9a0ef5fa0a19 100644
--- a/drivers/usb/roles/class.c
+++ b/drivers/usb/roles/class.c
@@ -89,8 +89,8 @@ enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw)
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_get_role);
 
-static void *usb_role_switch_match(const struct fwnode_handle *fwnode, const char *id,
-				   void *data)
+static void *usb_role_switch_match(const struct fwnode_handle *fwnode, const struct fwnode_handle *endpoint,
+				   const char *id, void *data)
 {
 	struct device *dev;
 
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 80dd91938d96..3eabd0d62f47 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -33,6 +33,7 @@ static int switch_fwnode_match(struct device *dev, const void *fwnode)
 }
 
 static void *typec_switch_match(const struct fwnode_handle *fwnode,
+				const struct fwnode_handle *endpoint,
 				const char *id, void *data)
 {
 	struct device *dev;
@@ -55,6 +56,9 @@ static void *typec_switch_match(const struct fwnode_handle *fwnode,
 	 */
 	dev = class_find_device(&typec_mux_class, NULL, fwnode,
 				switch_fwnode_match);
+	if (!dev)
+		dev = class_find_device(&typec_mux_class, NULL, endpoint,
+				switch_fwnode_match);
 
 	return dev ? to_typec_switch_dev(dev) : ERR_PTR(-EPROBE_DEFER);
 }
@@ -263,6 +267,7 @@ static int mux_fwnode_match(struct device *dev, const void *fwnode)
 }
 
 static void *typec_mux_match(const struct fwnode_handle *fwnode,
+			     const struct fwnode_handle *endpoint,
 			     const char *id, void *data)
 {
 	struct device *dev;
@@ -280,6 +285,9 @@ static void *typec_mux_match(const struct fwnode_handle *fwnode,
 
 	dev = class_find_device(&typec_mux_class, NULL, fwnode,
 				mux_fwnode_match);
+	if (!dev)
+		dev = class_find_device(&typec_mux_class, NULL, endpoint,
+					mux_fwnode_match);
 
 	return dev ? to_typec_mux_dev(dev) : ERR_PTR(-EPROBE_DEFER);
 }
diff --git a/drivers/usb/typec/retimer.c b/drivers/usb/typec/retimer.c
index 4a7d1b5c4d86..eb74abee6619 100644
--- a/drivers/usb/typec/retimer.c
+++ b/drivers/usb/typec/retimer.c
@@ -22,7 +22,9 @@ static int retimer_fwnode_match(struct device *dev, const void *fwnode)
 	return is_typec_retimer(dev) && device_match_fwnode(dev, fwnode);
 }
 
-static void *typec_retimer_match(const struct fwnode_handle *fwnode, const char *id, void *data)
+static void *typec_retimer_match(const struct fwnode_handle *fwnode,
+				 const struct fwnode_handle *endpoint,
+				 const char *id, void *data)
 {
 	struct device *dev;
 
@@ -31,6 +33,9 @@ static void *typec_retimer_match(const struct fwnode_handle *fwnode, const char
 
 	dev = class_find_device(&retimer_class, NULL, fwnode,
 				retimer_fwnode_match);
+	if (!dev)
+		dev = class_find_device(&retimer_class, NULL, endpoint,
+					retimer_fwnode_match);
 
 	return dev ? to_typec_retimer(dev) : ERR_PTR(-EPROBE_DEFER);
 }
diff --git a/include/linux/property.h b/include/linux/property.h
index 9f2585d705a8..0f20df1f0a49 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -455,8 +455,9 @@ unsigned int fwnode_graph_get_endpoint_count(const struct fwnode_handle *fwnode,
 int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
 				struct fwnode_endpoint *endpoint);
 
-typedef void *(*devcon_match_fn_t)(const struct fwnode_handle *fwnode, const char *id,
-				   void *data);
+typedef void *(*devcon_match_fn_t)(const struct fwnode_handle *fwnode,
+				   const struct fwnode_handle *endpoint,
+				   const char *id, void *data);
 
 void *fwnode_connection_find_match(const struct fwnode_handle *fwnode,
 				   const char *con_id, void *data,
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:19 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:19 -0800
Subject: [PATCH 08/22] platform/chrome: cros_ec_typec: Purge blocking switch devlinks
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-9-swboyd@chromium.org>

From: Prashant Malani <pmalani at chromium.org>

When using OF graph, the fw_devlink code will create links between the
individual port driver (cros-ec-typec here) and the parent device for
a Type-C switch (like mode-switch). Since the mode-switch will in turn
have the usb-c-connector (i.e the child of the port driver) as a
supplier, fw_devlink will not be able to resolve the cyclic dependency
correctly.

As a result, the mode-switch driver probe() never runs, so mode-switches
are never registered. Because of that, the port driver probe constantly
fails with -EPROBE_DEFER, because the Type-C connector class requires all
switch devices to be registered prior to port registration.

To break this deadlock and allow the mode-switch registration to occur,
purge all the usb-c-connector nodes' absent suppliers. This eliminates
the connector as a supplier for a switch and allows it to be probed.

Signed-off-by: Prashant Malani <pmalani at chromium.org>
Signed-off-by: Pin-yen Lin <treapking at chromium.org>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Tested-by: Chen-Yu Tsai <wenst at chromium.org>
Acked-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
Link: https://lore.kernel.org/r/20230331091145.737305-3-treapking at chromium.org
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/platform/chrome/cros_ec_typec.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index 2b2f14a1b711..cc5269a4b2f1 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -325,6 +325,16 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
 		return -EINVAL;
 	}
 
+	/*
+	 * OF graph may have set up some device links with switches,
+	 * since connectors have their own compatible. Purge these
+	 * to avoid a deadlock in switch probe (the switch mistakenly
+	 * assumes the connector is a supplier).
+	 */
+	if (dev_of_node(dev))
+		device_for_each_child_node(dev, fwnode)
+			fw_devlink_purge_absent_suppliers(fwnode);
+
 	/* DT uses "reg" to specify port number. */
 	port_prop = dev->of_node ? "reg" : "port-number";
 	device_for_each_child_node(dev, fwnode) {
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:20 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:20 -0800
Subject: [PATCH 09/22] platform/chrome: cros_typec_switch: Use read_poll_timeout helper
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-10-swboyd@chromium.org>

It's possible for this polling loop to get scheduled away for a long
time right after checking the status on the EC. If that happens, we will
never try to check the status at least one more time before giving up
and saying that it timed out. Let's use the read_poll_timeout() macro to
construct the loop with a proper timeout mechanism and the ability to
check that the condition is true once more when the timeout hits.

Cc: Prashant Malani <pmalani at chromium.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Tzung-Bi Shih <tzungbi at kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/platform/chrome/cros_typec_switch.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
index 07a19386dc4e..a23fe80d9d4b 100644
--- a/drivers/platform/chrome/cros_typec_switch.c
+++ b/drivers/platform/chrome/cros_typec_switch.c
@@ -8,7 +8,7 @@
 
 #include <linux/acpi.h>
 #include <linux/delay.h>
-#include <linux/jiffies.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
@@ -108,7 +108,6 @@ static bool cros_typec_check_event(struct cros_typec_switch_data *sdata, int por
 static int cros_typec_configure_mux(struct cros_typec_switch_data *sdata, int port_num, int index,
 				    unsigned long mode, struct typec_altmode *alt)
 {
-	unsigned long end;
 	u32 event_mask;
 	u8 mux_state;
 	int ret;
@@ -134,18 +133,14 @@ static int cros_typec_configure_mux(struct cros_typec_switch_data *sdata, int po
 		return ret;
 
 	/* Check for the mux set done event. */
-	end = jiffies + msecs_to_jiffies(1000);
-	do {
-		if (cros_typec_check_event(sdata, port_num, event_mask))
-			return 0;
+	if (read_poll_timeout(cros_typec_check_event, ret, ret == 0, 1000,
+			      1000 * 1000UL, false, sdata, port_num, event_mask)) {
+		dev_err(sdata->dev, "Timed out waiting for mux set done on index: %d, state: %d\n",
+			index, mux_state);
+		return -ETIMEDOUT;
+	}
 
-		usleep_range(500, 1000);
-	} while (time_before(jiffies, end));
-
-	dev_err(sdata->dev, "Timed out waiting for mux set done on index: %d, state: %d\n",
-		index, mux_state);
-
-	return -ETIMEDOUT;
+	return 0;
 }
 
 static int cros_typec_mode_switch_set(struct typec_mux_dev *mode_switch,
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:21 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:21 -0800
Subject: [PATCH 10/22] platform/chrome: cros_typec_switch: Move port creation code to sub-function
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-11-swboyd@chromium.org>

This driver will soon support devicetree firmwares. Extract the struct
cros_typec_port creation part of cros_typec_register_switches() into a
sub-function so that we can extend it for DT, where a graph is used
instead of child nodes.

Cc: Prashant Malani <pmalani at chromium.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Tzung-Bi Shih <tzungbi at kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/platform/chrome/cros_typec_switch.c | 113 +++++++++++---------
 1 file changed, 62 insertions(+), 51 deletions(-)

diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
index a23fe80d9d4b..1a718b661203 100644
--- a/drivers/platform/chrome/cros_typec_switch.c
+++ b/drivers/platform/chrome/cros_typec_switch.c
@@ -201,13 +201,69 @@ static int cros_typec_register_retimer(struct cros_typec_port *port, struct fwno
 	return PTR_ERR_OR_ZERO(port->retimer);
 }
 
-static int cros_typec_register_switches(struct cros_typec_switch_data *sdata)
+static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
+				    struct fwnode_handle *fwnode)
 {
 	struct cros_typec_port *port;
 	struct device *dev = sdata->dev;
-	struct fwnode_handle *fwnode;
 	struct acpi_device *adev;
 	unsigned long long index;
+	int ret;
+
+	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	adev = to_acpi_device_node(fwnode);
+	if (adev) {
+		ret = acpi_evaluate_integer(adev->handle, "_ADR", NULL, &index);
+		if (ACPI_FAILURE(ret)) {
+			dev_err(fwnode->dev, "_ADR wasn't evaluated\n");
+			return -ENODATA;
+		}
+	}
+
+	if (!adev) {
+		dev_err(fwnode->dev, "Couldn't get ACPI handle\n");
+		return -ENODEV;
+	}
+
+	if (index >= EC_USB_PD_MAX_PORTS) {
+		dev_err(fwnode->dev, "Invalid port index number: %llu\n", index);
+		return -EINVAL;
+	}
+	port->sdata = sdata;
+	port->port_num = index;
+	sdata->ports[index] = port;
+
+	if (fwnode_property_present(fwnode, "retimer-switch")) {
+		ret = cros_typec_register_retimer(port, fwnode);
+		if (ret) {
+			dev_err(dev, "Retimer switch register failed\n");
+			return ret;
+		}
+
+		dev_dbg(dev, "Retimer switch registered for index %llu\n", index);
+	}
+
+	if (!fwnode_property_present(fwnode, "mode-switch"))
+		return 0;
+
+	ret = cros_typec_register_mode_switch(port, fwnode);
+	if (ret) {
+		dev_err(dev, "Mode switch register failed\n");
+		return ret;
+	}
+
+	dev_dbg(dev, "Mode switch registered for index %llu\n", index);
+
+	return ret;
+}
+
+static int cros_typec_register_switches(struct cros_typec_switch_data *sdata)
+{
+	struct device *dev = sdata->dev;
+	struct fwnode_handle *fwnode;
 	int nports, ret;
 
 	nports = device_get_child_node_count(dev);
@@ -217,60 +273,15 @@ static int cros_typec_register_switches(struct cros_typec_switch_data *sdata)
 	}
 
 	device_for_each_child_node(dev, fwnode) {
-		port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
-		if (!port) {
-			ret = -ENOMEM;
-			goto err_switch;
-		}
-
-		adev = to_acpi_device_node(fwnode);
-		if (!adev) {
-			dev_err(fwnode->dev, "Couldn't get ACPI device handle\n");
-			ret = -ENODEV;
-			goto err_switch;
-		}
-
-		ret = acpi_evaluate_integer(adev->handle, "_ADR", NULL, &index);
-		if (ACPI_FAILURE(ret)) {
-			dev_err(fwnode->dev, "_ADR wasn't evaluated\n");
-			ret = -ENODATA;
-			goto err_switch;
-		}
-
-		if (index >= EC_USB_PD_MAX_PORTS) {
-			dev_err(fwnode->dev, "Invalid port index number: %llu\n", index);
-			ret = -EINVAL;
-			goto err_switch;
-		}
-		port->sdata = sdata;
-		port->port_num = index;
-		sdata->ports[index] = port;
-
-		if (fwnode_property_present(fwnode, "retimer-switch")) {
-			ret = cros_typec_register_retimer(port, fwnode);
-			if (ret) {
-				dev_err(dev, "Retimer switch register failed\n");
-				goto err_switch;
-			}
-
-			dev_dbg(dev, "Retimer switch registered for index %llu\n", index);
-		}
-
-		if (!fwnode_property_present(fwnode, "mode-switch"))
-			continue;
-
-		ret = cros_typec_register_mode_switch(port, fwnode);
+		ret = cros_typec_register_port(sdata, fwnode);
 		if (ret) {
-			dev_err(dev, "Mode switch register failed\n");
-			goto err_switch;
+			fwnode_handle_put(fwnode);
+			goto err;
 		}
-
-		dev_dbg(dev, "Mode switch registered for index %llu\n", index);
 	}
 
 	return 0;
-err_switch:
-	fwnode_handle_put(fwnode);
+err:
 	cros_typec_unregister_switches(sdata);
 	return ret;
 }
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:22 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:22 -0800
Subject: [PATCH 11/22] platform/chrome: cros_typec_switch: Use fwnode instead of ACPI APIs
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-12-swboyd@chromium.org>

Use fwnode APIs instead of ACPI ones because this driver will soon
support devicetree firmwares. Using fwnode APIs makes it easier to
support either ACPI or DT.

Cc: Prashant Malani <pmalani at chromium.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Tzung-Bi Shih <tzungbi at kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/platform/chrome/cros_typec_switch.c | 24 +++++++++++----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
index 1a718b661203..373e0e86ebfc 100644
--- a/drivers/platform/chrome/cros_typec_switch.c
+++ b/drivers/platform/chrome/cros_typec_switch.c
@@ -207,29 +207,31 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 	struct cros_typec_port *port;
 	struct device *dev = sdata->dev;
 	struct acpi_device *adev;
-	unsigned long long index;
+	u32 index;
 	int ret;
+	const char *prop_name;
 
 	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
 	if (!port)
 		return -ENOMEM;
 
 	adev = to_acpi_device_node(fwnode);
-	if (adev) {
-		ret = acpi_evaluate_integer(adev->handle, "_ADR", NULL, &index);
-		if (ACPI_FAILURE(ret)) {
-			dev_err(fwnode->dev, "_ADR wasn't evaluated\n");
-			return -ENODATA;
-		}
-	}
+	if (adev)
+		prop_name = "_ADR";
 
 	if (!adev) {
 		dev_err(fwnode->dev, "Couldn't get ACPI handle\n");
 		return -ENODEV;
 	}
 
+	ret = fwnode_property_read_u32(fwnode, prop_name, &index);
+	if (ret) {
+		dev_err(fwnode->dev, "%s property wasn't found\n", prop_name);
+		return ret;
+	}
+
 	if (index >= EC_USB_PD_MAX_PORTS) {
-		dev_err(fwnode->dev, "Invalid port index number: %llu\n", index);
+		dev_err(fwnode->dev, "Invalid port index number: %u\n", index);
 		return -EINVAL;
 	}
 	port->sdata = sdata;
@@ -243,7 +245,7 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 			return ret;
 		}
 
-		dev_dbg(dev, "Retimer switch registered for index %llu\n", index);
+		dev_dbg(dev, "Retimer switch registered for index %u\n", index);
 	}
 
 	if (!fwnode_property_present(fwnode, "mode-switch"))
@@ -255,7 +257,7 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 		return ret;
 	}
 
-	dev_dbg(dev, "Mode switch registered for index %llu\n", index);
+	dev_dbg(dev, "Mode switch registered for index %u\n", index);
 
 	return ret;
 }
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:23 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:23 -0800
Subject: [PATCH 12/22] platform/chrome: cros_typec_switch: Use dev_err_probe()
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-13-swboyd@chromium.org>

Use dev_err_probe() helper so we can get better diagnostics when driver
probes fails for any reason.

Cc: Prashant Malani <pmalani at chromium.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Tzung-Bi Shih <tzungbi at kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>

Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/platform/chrome/cros_typec_switch.c | 36 +++++++--------------
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
index 373e0e86ebfc..769de2889f2f 100644
--- a/drivers/platform/chrome/cros_typec_switch.c
+++ b/drivers/platform/chrome/cros_typec_switch.c
@@ -219,31 +219,23 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 	if (adev)
 		prop_name = "_ADR";
 
-	if (!adev) {
-		dev_err(fwnode->dev, "Couldn't get ACPI handle\n");
-		return -ENODEV;
-	}
+	if (!adev)
+		return dev_err_probe(fwnode->dev, -ENODEV, "Couldn't get ACPI handle\n");
 
 	ret = fwnode_property_read_u32(fwnode, prop_name, &index);
-	if (ret) {
-		dev_err(fwnode->dev, "%s property wasn't found\n", prop_name);
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(fwnode->dev, ret, "%s property wasn't found\n", prop_name);
 
-	if (index >= EC_USB_PD_MAX_PORTS) {
-		dev_err(fwnode->dev, "Invalid port index number: %u\n", index);
-		return -EINVAL;
-	}
+	if (index >= EC_USB_PD_MAX_PORTS)
+		return dev_err_probe(fwnode->dev, -EINVAL, "Invalid port index number: %u\n", index);
 	port->sdata = sdata;
 	port->port_num = index;
 	sdata->ports[index] = port;
 
 	if (fwnode_property_present(fwnode, "retimer-switch")) {
 		ret = cros_typec_register_retimer(port, fwnode);
-		if (ret) {
-			dev_err(dev, "Retimer switch register failed\n");
-			return ret;
-		}
+		if (ret)
+			return dev_err_probe(dev, ret, "Retimer switch register failed\n");
 
 		dev_dbg(dev, "Retimer switch registered for index %u\n", index);
 	}
@@ -252,10 +244,8 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 		return 0;
 
 	ret = cros_typec_register_mode_switch(port, fwnode);
-	if (ret) {
-		dev_err(dev, "Mode switch register failed\n");
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret, "Mode switch register failed\n");
 
 	dev_dbg(dev, "Mode switch registered for index %u\n", index);
 
@@ -269,10 +259,8 @@ static int cros_typec_register_switches(struct cros_typec_switch_data *sdata)
 	int nports, ret;
 
 	nports = device_get_child_node_count(dev);
-	if (nports == 0) {
-		dev_err(dev, "No switch devices found.\n");
-		return -ENODEV;
-	}
+	if (nports == 0)
+		return dev_err_probe(dev, -ENODEV, "No switch devices found\n");
 
 	device_for_each_child_node(dev, fwnode) {
 		ret = cros_typec_register_port(sdata, fwnode);
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:24 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:24 -0800
Subject: [PATCH 13/22] dt-bindings: chrome: Add google,cros-ec-typec-switch binding
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-14-swboyd@chromium.org>

Add a binding for the USB type-c switch controls found on some ChromeOS
Embedded Controllers (ECs). When this device is a mode switch, it takes
one DisplayPort (DP) port as input and some number (possibly zero) of
USB SuperSpeed ports (bundles of USB SS lanes) as input, and muxes those
lanes into USB type-c SuperSpeed lanes suitable for the SSTRX1/2 pins on
a usb-c-connector. When this device is an orientation switch, it
redirects the DP lanes to the proper USB type-c SSTRX lanes.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: Lee Jones <lee at kernel.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Guenter Roeck <groeck at chromium.org>
Cc: Prashant Malani <pmalani at chromium.org>
Cc: Tzung-Bi Shih <tzungbi at kernel.org>
Cc: <devicetree at vger.kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 .../chrome/google,cros-ec-typec-switch.yaml   | 365 ++++++++++++++++++
 .../bindings/mfd/google,cros-ec.yaml          |   5 +
 2 files changed, 370 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml

diff --git a/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml b/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
new file mode 100644
index 000000000000..17a0ba928f5d
--- /dev/null
+++ b/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
@@ -0,0 +1,365 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/chrome/google,cros-ec-typec-switch.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Google Chrome OS EC(Embedded Controller) USB Type C Switch
+
+maintainers:
+  - Benson Leung <bleung at chromium.org>
+  - Prashant Malani <pmalani at chromium.org>
+  - Stephen Boyd <swboyd at chromium.org>
+
+description:
+  Chrome OS devices have an Embedded Controller(EC) which has access to USB
+  Type C switching. This node is intended to allow the OS to control Type C
+  signal muxing for USB-C orientation and alternate modes. The node for this
+  device should be under a cros-ec node like google,cros-ec-spi.
+
+properties:
+  compatible:
+    const: google,cros-ec-typec-switch
+
+  mode-switch:
+    description: Indicates this device controls altmode switching
+    type: boolean
+
+  orientation-switch:
+    description: Indicates this device controls orientation switching
+    type: boolean
+
+  mux-gpios:
+    description: GPIOs indicating which way the DP mux is steered
+
+  no-hpd:
+    description: Indicates this device doesn't signal HPD for DisplayPort
+    type: boolean
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        description: Input port to receive DisplayPort (DP) data
+        unevaluatedProperties: false
+
+        properties:
+          endpoint at 0:
+            $ref: /schemas/graph.yaml#/$defs/endpoint-base
+            description: DisplayPort data
+            unevaluatedProperties: false
+            properties:
+              data-lanes:
+                $ref: /schemas/types.yaml#/definitions/uint32-array
+                description: |
+                  An array of physical DP data lane indexes
+                  - 0 is DP ML0 lane
+                  - 1 is DP ML1 lane
+                  - 2 is DP ML2 lane
+                  - 3 is DP ML3 lane
+                oneOf:
+                  - items:
+                      - const: 0
+                      - const: 1
+                  - items:
+                      - const: 0
+                      - const: 1
+                      - const: 2
+                      - const: 3
+
+        required:
+          - endpoint at 0
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Input port to receive USB SuperSpeed (SS) data
+        properties:
+          endpoint at 0:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+            description: USB SS data
+
+          endpoint at 1:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+            description: USB SS data
+
+        anyOf:
+          - required:
+              - endpoint at 0
+          - required:
+              - endpoint at 1
+
+      port at 2:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Output port for USB-C data
+        properties:
+          endpoint at 0:
+            $ref: /schemas/graph.yaml#/$defs/endpoint-base
+            description: USB-C data
+            unevaluatedProperties: false
+            properties:
+              data-lanes:
+                $ref: /schemas/types.yaml#/definitions/uint32-array
+                description: |
+                  An array of physical USB-C data lane indexes.
+                  - 0 is SSRX1 lane
+                  - 1 is SSTX1 lane
+                  - 2 is SSTX2 lane
+                  - 3 is SSRX2 lane
+                minItems: 4
+                maxItems: 4
+                items:
+                  maximum: 3
+
+          endpoint at 1:
+            $ref: /schemas/graph.yaml#/$defs/endpoint-base
+            description: USB-C data for EC's 1st type-c port
+            unevaluatedProperties: false
+            properties:
+              data-lanes:
+                $ref: /schemas/types.yaml#/definitions/uint32-array
+                description: |
+                  An array of physical USB-C data lane indexes.
+                  - 0 is SSRX1 lane
+                  - 1 is SSTX1 lane
+                  - 2 is SSTX2 lane
+                  - 3 is SSRX2 lane
+                minItems: 4
+                maxItems: 4
+                items:
+                  maximum: 3
+
+          endpoint at 2:
+            $ref: /schemas/graph.yaml#/$defs/endpoint-base
+            description: USB-C data for EC's 2nd type-c port
+            unevaluatedProperties: false
+            properties:
+              data-lanes:
+                $ref: /schemas/types.yaml#/definitions/uint32-array
+                description: |
+                  An array of physical USB-C data lane indexes.
+                  - 0 is SSRX1 lane
+                  - 1 is SSTX1 lane
+                  - 2 is SSTX2 lane
+                  - 3 is SSRX2 lane
+                minItems: 4
+                maxItems: 4
+                items:
+                  maximum: 3
+
+          endpoint at 3:
+            $ref: /schemas/graph.yaml#/$defs/endpoint-base
+            description: USB-C data for EC's 3rd type-c port
+            unevaluatedProperties: false
+            properties:
+              data-lanes:
+                $ref: /schemas/types.yaml#/definitions/uint32-array
+                description: |
+                  An array of physical USB-C data lane indexes.
+                  - 0 is SSRX1 lane
+                  - 1 is SSTX1 lane
+                  - 2 is SSTX2 lane
+                  - 3 is SSRX2 lane
+                minItems: 4
+                maxItems: 4
+                items:
+                  maximum: 3
+
+          endpoint at 4:
+            $ref: /schemas/graph.yaml#/$defs/endpoint-base
+            description: USB-C data for EC's 4th type-c port
+            unevaluatedProperties: false
+            properties:
+              data-lanes:
+                $ref: /schemas/types.yaml#/definitions/uint32-array
+                description: |
+                  An array of physical USB-C data lane indexes.
+                  - 0 is SSRX1 lane
+                  - 1 is SSTX1 lane
+                  - 2 is SSTX2 lane
+                  - 3 is SSRX2 lane
+                minItems: 4
+                maxItems: 4
+                items:
+                  maximum: 3
+
+          endpoint at 5:
+            $ref: /schemas/graph.yaml#/$defs/endpoint-base
+            description: USB-C data for EC's 5th type-c port
+            unevaluatedProperties: false
+            properties:
+              data-lanes:
+                $ref: /schemas/types.yaml#/definitions/uint32-array
+                description: |
+                  An array of physical USB-C data lane indexes.
+                  - 0 is SSRX1 lane
+                  - 1 is SSTX1 lane
+                  - 2 is SSTX2 lane
+                  - 3 is SSRX2 lane
+                minItems: 4
+                maxItems: 4
+                items:
+                  maximum: 3
+
+          endpoint at 6:
+            $ref: /schemas/graph.yaml#/$defs/endpoint-base
+            description: USB-C data for EC's 6th type-c port
+            unevaluatedProperties: false
+            properties:
+              data-lanes:
+                $ref: /schemas/types.yaml#/definitions/uint32-array
+                description: |
+                  An array of physical USB-C data lane indexes.
+                  - 0 is SSRX1 lane
+                  - 1 is SSTX1 lane
+                  - 2 is SSTX2 lane
+                  - 3 is SSRX2 lane
+                minItems: 4
+                maxItems: 4
+                items:
+                  maximum: 3
+
+          endpoint at 7:
+            $ref: /schemas/graph.yaml#/$defs/endpoint-base
+            description: USB-C data for EC's 7th type-c port
+            unevaluatedProperties: false
+            properties:
+              data-lanes:
+                $ref: /schemas/types.yaml#/definitions/uint32-array
+                description: |
+                  An array of physical USB-C data lane indexes.
+                  - 0 is SSRX1 lane
+                  - 1 is SSTX1 lane
+                  - 2 is SSTX2 lane
+                  - 3 is SSRX2 lane
+                minItems: 4
+                maxItems: 4
+                items:
+                  maximum: 3
+
+        anyOf:
+          - required:
+              - endpoint at 0
+          - required:
+              - endpoint at 1
+          - required:
+              - endpoint at 2
+          - required:
+              - endpoint at 3
+          - required:
+              - endpoint at 4
+          - required:
+              - endpoint at 5
+          - required:
+              - endpoint at 6
+          - required:
+              - endpoint at 7
+
+    required:
+      - port at 2
+    anyOf:
+      - required:
+          - port at 0
+      - required:
+          - port at 1
+
+required:
+  - compatible
+  - ports
+
+allOf:
+  - if:
+      properties:
+        no-hpd: true
+      required:
+        - no-hpd
+    then:
+      properties:
+        ports:
+          required:
+            - port at 0
+  - if:
+      properties:
+        mode-switch: true
+      required:
+        - mode-switch
+    then:
+      properties:
+        ports:
+          required:
+            - port at 0
+
+additionalProperties: false
+
+examples:
+  - |
+    spi {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      cros_ec: ec at 0 {
+        compatible = "google,cros-ec-spi";
+        reg = <0>;
+        interrupts = <35 0>;
+
+        typec-switch {
+          compatible = "google,cros-ec-typec-switch";
+          mode-switch;
+          orientation-switch;
+
+          ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+              reg = <0>;
+              #address-cells = <1>;
+              #size-cells = <0>;
+              dp_in: endpoint at 0 {
+                reg = <0>;
+                remote-endpoint = <&dp_phy>;
+                data-lanes = <0 1>;
+              };
+            };
+
+            port at 1 {
+              reg = <1>;
+              #address-cells = <1>;
+              #size-cells = <0>;
+
+              usb_in_0: endpoint at 0 {
+                reg = <0>;
+                remote-endpoint = <&usb_ss_0_out>;
+              };
+
+              usb_in_1: endpoint at 1 {
+                reg = <1>;
+                remote-endpoint = <&usb_ss_1_out>;
+              };
+            };
+
+            port at 2 {
+              reg = <2>;
+              #address-cells = <1>;
+              #size-cells = <0>;
+
+              cros_typec_c0_ss: endpoint at 0 {
+                reg = <0>;
+                remote-endpoint = <&usb_c0_ss>;
+              };
+
+              cros_typec_c1_ss: endpoint at 1 {
+                reg = <1>;
+                remote-endpoint = <&usb_c1_ss>;
+              };
+            };
+          };
+        };
+      };
+    };
+...
diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
index ded396b28fba..563c51a4a39c 100644
--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
+++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
@@ -164,6 +164,10 @@ patternProperties:
     type: object
     $ref: /schemas/extcon/extcon-usbc-cros-ec.yaml#
 
+  "^typec-switch[0-9]*$":
+    type: object
+    $ref: /schemas/chrome/google,cros-ec-typec-switch.yaml#
+
 required:
   - compatible
 
@@ -227,6 +231,7 @@ allOf:
         "^i2c-tunnel[0-9]*$": false
         "^regulator@[0-9]+$": false
         "^extcon[0-9]*$": false
+        "^typec-switch[0-9]*$": false
 
       # Using additionalProperties: false here and
       # listing true properties doesn't work
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:25 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:25 -0800
Subject: [PATCH 14/22] platform/chrome: cros_typec_switch: Add support for signaling HPD to drm_bridge
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-15-swboyd@chromium.org>

We can imagine that logically the EC is a device that has some number of
DisplayPort (DP) connector inputs, some number of USB3 connector inputs,
and some number of USB type-c connector outputs. If you squint enough it
looks like a USB type-c dock. Logically there's a crossbar pin
assignment capability within the EC that can assign USB and DP lanes to
USB type-c lanes in the connector (i.e. USB type-c pin configurations).
In reality, the EC is a microcontroller that has some TCPCs and
redrivers connected to it over something like i2c and DP/USB from the AP
is wired directly to those ICs, not the EC.

This design allows the EC to abstract many possible USB and DP hardware
configurations away from the AP (kernel) so that the AP can largely deal
with USB and DP without thinking about USB Type-C much at all. The DP
and USB data originate in the AP, not the EC, so it helps to think that
the EC takes the DP and USB data as input to mux onto USB type-c ports
even if it really doesn't do that. With this split design, the EC
forwards the DP HPD state to the AP via a GPIO that's connected to the
DP phy.

Having that HPD state signaled directly to the DP phy uses precious
hardware resources, a GPIO or two and a wire, and it also forces the
TCPM to live on the EC. If we want to save costs and move more control
of USB type-c to the kernel it's in our interest to get rid of the HPD
GPIO entirely and signal HPD to the DP phy some other way. Luckily, the
EC already exposes information about the USB Type-C stack to the kernel
via the host command interface in the "google,cros-ec-typec" compatible
driver, which parses EC messages related to USB type-c and effectively
"replays" those messages to the kernel's USB typec subsystem. This
includes the state of HPD, which can be interrogated and acted upon by
registering a 'struct typec_mux_dev' with the typec subsystem.

On DT based systems, the DP display pipeline is abstracted via a 'struct
drm_bridge'. If we want to signal HPD state within the kernel we need to
hook into the drm_bridge framework somehow to call
drm_bridge_hpd_notify() when HPD state changes in the typec framework.
Make a drm_bridge in the EC that attaches onto the end of the DP bridge
chain and logically moves the display data onto a usb-c-connector.
Signal HPD when the typec HPD state changes, as long as this new
drm_bridge is the one that's supposed to signal HPD. Do that by
registering a 'struct typec_mux_dev' with the typec framework and
associating that struct with a usb-c-connector node and a drm_bridge.

To keep this patch minimal, just signal HPD state to the drm_bridge
chain. Later patches will add more features. Eventually we'll be able to
inform userspace about which usb-c-connector node is displaying DP and
what USB devices are connected to a connector. Note that this code is
placed in the cros_typec_switch driver because that's where mode-switch
devices on the EC are controlled by the AP. Logically this drm_bridge
sits in front of the mode-switch on the EC, and if there is anything to
control on the EC the 'EC_FEATURE_TYPEC_AP_MUX_SET' feature will be set.

Cc: Prashant Malani <pmalani at chromium.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Tzung-Bi Shih <tzungbi at kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/platform/chrome/Kconfig             |   3 +-
 drivers/platform/chrome/cros_typec_switch.c | 218 ++++++++++++++++++--
 2 files changed, 204 insertions(+), 17 deletions(-)

diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index 7a83346bfa53..910aa8be9c84 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -287,7 +287,8 @@ config CHROMEOS_PRIVACY_SCREEN
 
 config CROS_TYPEC_SWITCH
 	tristate "ChromeOS EC Type-C Switch Control"
-	depends on MFD_CROS_EC_DEV && TYPEC && ACPI
+	depends on MFD_CROS_EC_DEV
+	depends on TYPEC
 	default MFD_CROS_EC_DEV
 	help
 	  If you say Y here, you get support for configuring the ChromeOS EC Type-C
diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
index 769de2889f2f..d8fb6662cf8d 100644
--- a/drivers/platform/chrome/cros_typec_switch.c
+++ b/drivers/platform/chrome/cros_typec_switch.c
@@ -10,6 +10,7 @@
 #include <linux/delay.h>
 #include <linux/iopoll.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
 #include <linux/platform_device.h>
@@ -18,6 +19,15 @@
 #include <linux/usb/typec_mux.h>
 #include <linux/usb/typec_retimer.h>
 
+#include <drm/drm_bridge.h>
+#include <drm/drm_print.h>
+
+struct cros_typec_dp_bridge {
+	struct cros_typec_switch_data *sdata;
+	bool hpd_enabled;
+	struct drm_bridge bridge;
+};
+
 /* Handles and other relevant data required for each port's switches. */
 struct cros_typec_port {
 	int port_num;
@@ -30,7 +40,9 @@ struct cros_typec_port {
 struct cros_typec_switch_data {
 	struct device *dev;
 	struct cros_ec_device *ec;
+	bool typec_cmd_supported;
 	struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
+	struct cros_typec_dp_bridge *typec_dp_bridge;
 };
 
 static int cros_typec_cmd_mux_set(struct cros_typec_switch_data *sdata, int port_num, u8 index,
@@ -143,13 +155,60 @@ static int cros_typec_configure_mux(struct cros_typec_switch_data *sdata, int po
 	return 0;
 }
 
+static int cros_typec_dp_port_switch_set(struct typec_mux_dev *mode_switch,
+					 struct typec_mux_state *state)
+{
+	struct cros_typec_port *port;
+	const struct typec_displayport_data *dp_data;
+	struct cros_typec_dp_bridge *typec_dp_bridge;
+	struct drm_bridge *bridge;
+	bool hpd_asserted;
+
+	port = typec_mux_get_drvdata(mode_switch);
+	typec_dp_bridge = port->sdata->typec_dp_bridge;
+	if (!typec_dp_bridge)
+		return 0;
+
+	bridge = &typec_dp_bridge->bridge;
+
+	if (state->mode == TYPEC_STATE_SAFE || state->mode == TYPEC_STATE_USB) {
+		if (typec_dp_bridge->hpd_enabled)
+			drm_bridge_hpd_notify(bridge, connector_status_disconnected);
+
+		return 0;
+	}
+
+	if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) {
+		if (typec_dp_bridge->hpd_enabled) {
+			dp_data = state->data;
+			hpd_asserted = dp_data->status & DP_STATUS_HPD_STATE;
+
+			if (hpd_asserted)
+				drm_bridge_hpd_notify(bridge, connector_status_connected);
+			else
+				drm_bridge_hpd_notify(bridge, connector_status_disconnected);
+		}
+	}
+
+	return 0;
+}
+
 static int cros_typec_mode_switch_set(struct typec_mux_dev *mode_switch,
 				      struct typec_mux_state *state)
 {
 	struct cros_typec_port *port = typec_mux_get_drvdata(mode_switch);
+	struct cros_typec_switch_data *sdata = port->sdata;
+	int ret;
+
+	ret = cros_typec_dp_port_switch_set(mode_switch, state);
+	if (ret)
+		return ret;
 
 	/* Mode switches have index 0. */
-	return cros_typec_configure_mux(port->sdata, port->port_num, 0, state->mode, state->alt);
+	if (sdata->typec_cmd_supported)
+		return cros_typec_configure_mux(port->sdata, port->port_num, 0, state->mode, state->alt);
+
+	return 0;
 }
 
 static int cros_typec_retimer_set(struct typec_retimer *retimer, struct typec_retimer_state *state)
@@ -201,12 +260,77 @@ static int cros_typec_register_retimer(struct cros_typec_port *port, struct fwno
 	return PTR_ERR_OR_ZERO(port->retimer);
 }
 
+static int
+cros_typec_dp_bridge_attach(struct drm_bridge *bridge,
+			    enum drm_bridge_attach_flags flags)
+{
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		DRM_ERROR("Fix bridge driver to make connector optional!\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct cros_typec_dp_bridge *
+bridge_to_cros_typec_dp_bridge(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct cros_typec_dp_bridge, bridge);
+}
+
+static void cros_typec_dp_bridge_hpd_enable(struct drm_bridge *bridge)
+{
+	struct cros_typec_dp_bridge *typec_dp_bridge;
+
+	typec_dp_bridge = bridge_to_cros_typec_dp_bridge(bridge);
+	typec_dp_bridge->hpd_enabled = true;
+}
+
+static void cros_typec_dp_bridge_hpd_disable(struct drm_bridge *bridge)
+{
+	struct cros_typec_dp_bridge *typec_dp_bridge;
+
+	typec_dp_bridge = bridge_to_cros_typec_dp_bridge(bridge);
+	typec_dp_bridge->hpd_enabled = false;
+}
+
+static const struct drm_bridge_funcs cros_typec_dp_bridge_funcs = {
+	.attach = cros_typec_dp_bridge_attach,
+	.hpd_enable = cros_typec_dp_bridge_hpd_enable,
+	.hpd_disable = cros_typec_dp_bridge_hpd_disable,
+};
+
+static int cros_typec_register_dp_bridge(struct cros_typec_switch_data *sdata,
+					 struct fwnode_handle *fwnode)
+{
+	struct cros_typec_dp_bridge *typec_dp_bridge;
+	struct drm_bridge *bridge;
+	struct device *dev = sdata->dev;
+
+	typec_dp_bridge = devm_kzalloc(dev, sizeof(*typec_dp_bridge), GFP_KERNEL);
+	if (!typec_dp_bridge)
+		return -ENOMEM;
+
+	typec_dp_bridge->sdata = sdata;
+	sdata->typec_dp_bridge = typec_dp_bridge;
+	bridge = &typec_dp_bridge->bridge;
+
+	bridge->funcs = &cros_typec_dp_bridge_funcs;
+	bridge->of_node = dev->of_node;
+	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
+	bridge->ops |= DRM_BRIDGE_OP_HPD;
+
+	return devm_drm_bridge_add(dev, bridge);
+}
+
 static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 				    struct fwnode_handle *fwnode)
 {
 	struct cros_typec_port *port;
 	struct device *dev = sdata->dev;
 	struct acpi_device *adev;
+	struct device_node *np;
+	struct fwnode_handle *port_node;
 	u32 index;
 	int ret;
 	const char *prop_name;
@@ -218,9 +342,12 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 	adev = to_acpi_device_node(fwnode);
 	if (adev)
 		prop_name = "_ADR";
+	np = to_of_node(fwnode);
+	if (np)
+		prop_name = "reg";
 
-	if (!adev)
-		return dev_err_probe(fwnode->dev, -ENODEV, "Couldn't get ACPI handle\n");
+	if (!adev && !np)
+		return dev_err_probe(fwnode->dev, -ENODEV, "Couldn't get ACPI/OF device handle\n");
 
 	ret = fwnode_property_read_u32(fwnode, prop_name, &index);
 	if (ret)
@@ -232,41 +359,84 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 	port->port_num = index;
 	sdata->ports[index] = port;
 
+	port_node = fwnode;
+	if (np)
+		fwnode = fwnode_graph_get_port_parent(fwnode);
+
 	if (fwnode_property_present(fwnode, "retimer-switch")) {
-		ret = cros_typec_register_retimer(port, fwnode);
-		if (ret)
-			return dev_err_probe(dev, ret, "Retimer switch register failed\n");
+		ret = cros_typec_register_retimer(port, port_node);
+		if (ret) {
+			dev_err_probe(dev, ret, "Retimer switch register failed\n");
+			goto out;
+		}
 
 		dev_dbg(dev, "Retimer switch registered for index %u\n", index);
 	}
 
-	if (!fwnode_property_present(fwnode, "mode-switch"))
-		return 0;
+	if (fwnode_property_present(fwnode, "mode-switch")) {
+		ret = cros_typec_register_mode_switch(port, port_node);
+		if (ret) {
+			dev_err_probe(dev, ret, "Mode switch register failed\n");
+			goto out;
+		}
 
-	ret = cros_typec_register_mode_switch(port, fwnode);
-	if (ret)
-		return dev_err_probe(dev, ret, "Mode switch register failed\n");
+		dev_dbg(dev, "Mode switch registered for index %u\n", index);
+	}
 
-	dev_dbg(dev, "Mode switch registered for index %u\n", index);
 
+out:
+	if (np)
+		fwnode_handle_put(fwnode);
 	return ret;
 }
 
 static int cros_typec_register_switches(struct cros_typec_switch_data *sdata)
 {
 	struct device *dev = sdata->dev;
+	struct fwnode_handle *devnode;
 	struct fwnode_handle *fwnode;
+	struct fwnode_endpoint endpoint;
 	int nports, ret;
 
 	nports = device_get_child_node_count(dev);
 	if (nports == 0)
 		return dev_err_probe(dev, -ENODEV, "No switch devices found\n");
 
-	device_for_each_child_node(dev, fwnode) {
-		ret = cros_typec_register_port(sdata, fwnode);
-		if (ret) {
+	devnode = dev_fwnode(dev);
+	if (fwnode_graph_get_endpoint_count(devnode, 0)) {
+		fwnode_graph_for_each_endpoint(devnode, fwnode) {
+			ret = fwnode_graph_parse_endpoint(fwnode, &endpoint);
+			if (ret) {
+				fwnode_handle_put(fwnode);
+				goto err;
+			}
+			/* Skip if not a type-c output port */
+			if (endpoint.port != 2)
+				continue;
+
+			ret = cros_typec_register_port(sdata, fwnode);
+			if (ret) {
+				fwnode_handle_put(fwnode);
+				goto err;
+			}
+		}
+	} else {
+		device_for_each_child_node(dev, fwnode) {
+			ret = cros_typec_register_port(sdata, fwnode);
+			if (ret) {
+				fwnode_handle_put(fwnode);
+				goto err;
+			}
+		}
+	}
+
+	if (fwnode_property_present(devnode, "mode-switch")) {
+		fwnode = fwnode_graph_get_endpoint_by_id(devnode, 0, 0, 0);
+		if (fwnode) {
+			ret = cros_typec_register_dp_bridge(sdata, fwnode);
 			fwnode_handle_put(fwnode);
-			goto err;
+			if (ret)
+				goto err;
 		}
 	}
 
@@ -280,6 +450,7 @@ static int cros_typec_switch_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct cros_typec_switch_data *sdata;
+	struct cros_ec_dev *ec_dev;
 
 	sdata = devm_kzalloc(dev, sizeof(*sdata), GFP_KERNEL);
 	if (!sdata)
@@ -288,6 +459,12 @@ static int cros_typec_switch_probe(struct platform_device *pdev)
 	sdata->dev = dev;
 	sdata->ec = dev_get_drvdata(pdev->dev.parent);
 
+	ec_dev = dev_get_drvdata(&sdata->ec->ec->dev);
+	if (!ec_dev)
+		return -EPROBE_DEFER;
+
+	sdata->typec_cmd_supported = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_AP_MUX_SET);
+
 	platform_set_drvdata(pdev, sdata);
 
 	return cros_typec_register_switches(sdata);
@@ -308,10 +485,19 @@ static const struct acpi_device_id cros_typec_switch_acpi_id[] = {
 MODULE_DEVICE_TABLE(acpi, cros_typec_switch_acpi_id);
 #endif
 
+#ifdef CONFIG_OF
+static const struct of_device_id cros_typec_switch_of_match_table[] = {
+	{ .compatible = "google,cros-ec-typec-switch" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, cros_typec_switch_of_match_table);
+#endif
+
 static struct platform_driver cros_typec_switch_driver = {
 	.driver	= {
 		.name = "cros-typec-switch",
 		.acpi_match_table = ACPI_PTR(cros_typec_switch_acpi_id),
+		.of_match_table = of_match_ptr(cros_typec_switch_of_match_table),
 	},
 	.probe = cros_typec_switch_probe,
 	.remove_new = cros_typec_switch_remove,
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:26 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:26 -0800
Subject: [PATCH 15/22] platform/chrome: cros_typec_switch: Support DP muxing via DRM lane assignment
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-16-swboyd@chromium.org>

Implement DP lane assignment in the drm_bridge atomic_check() callback
so that DP altmode configurations like pinconf D can be supported and DP
muxing can be implemented. In the DP altmode spec, pinconf C assigns all
4 SuperSpeed lanes in the usb-c-connector node to DP, while pinconf D
assigns 2 SuperSpeed lanes to DP and 2 SuperSpeed lanes to USB. Use the
'data-lanes' property from the input DP graph port to calculate the
maximum number of lanes coming from the DP source (either 2 or
4) and limit the lanes requested to the smaller of this or the pin
configuration.

Once we know the maximum number of lanes that can be assigned, map the
DP lanes to the active type-c output port with the assigned pin
configuration. Use the 'data-lanes' property from the active type-c
output port to determine which logical DP lanes should be assigned to
the output of the drm_bridge. For now assume the type-c pins are in the
normal orientation.

This design supports different DP altmode pin configurations and also
allows us to effectively mux one DP phy to two different USB type-c
connectors by wiring the physical DP lanes to one or the other USB
type-c connectors in the hardware. For example, DP ML0/ML1 are hardwired
to one USB type-c connector and DP ML2/ML3 are hardwired to the other
connector. The 'data-lanes' of the first USB type-c port would be the
default "<0 1 2 3>" while the 'data-lanes' of the second USB type-c port
would be "<2 3 0 1>". Depending on the active USB type-c port, map the
logical DP lane to the logical type-c lane, and then find the physical
type-c lane corresponding to that logical lane from the type-c port's
'data-lanes' property. Once we have that, map the physical type-c lane
to the physical DP lane and request that physical DP lane as the logical
DP lane through the DRM lane assignment logic on the input of the
drm_bridge.

Cc: Prashant Malani <pmalani at chromium.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Tzung-Bi Shih <tzungbi at kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/platform/chrome/cros_typec_switch.c | 136 +++++++++++++++++++-
 1 file changed, 131 insertions(+), 5 deletions(-)

diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
index d8fb6662cf8d..adcbf8f44c98 100644
--- a/drivers/platform/chrome/cros_typec_switch.c
+++ b/drivers/platform/chrome/cros_typec_switch.c
@@ -19,20 +19,28 @@
 #include <linux/usb/typec_mux.h>
 #include <linux/usb/typec_retimer.h>
 
+#include <drm/drm_atomic_state_helper.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_print.h>
 
 struct cros_typec_dp_bridge {
+	/* TODO: Add mutex lock to protect active_port with respect to drm/typec framework calls */
+	struct cros_typec_port *active_port;
 	struct cros_typec_switch_data *sdata;
+	size_t max_lanes;
 	bool hpd_enabled;
 	struct drm_bridge bridge;
 };
 
+#define USBC_LANES_COUNT 4
+
 /* Handles and other relevant data required for each port's switches. */
 struct cros_typec_port {
 	int port_num;
 	struct typec_mux_dev *mode_switch;
 	struct typec_retimer *retimer;
+	size_t num_dp_lanes;
+	u32 lane_mapping[USBC_LANES_COUNT];
 	struct cros_typec_switch_data *sdata;
 };
 
@@ -163,6 +171,8 @@ static int cros_typec_dp_port_switch_set(struct typec_mux_dev *mode_switch,
 	struct cros_typec_dp_bridge *typec_dp_bridge;
 	struct drm_bridge *bridge;
 	bool hpd_asserted;
+	u8 pin_assign;
+	size_t num_lanes, max_lanes;
 
 	port = typec_mux_get_drvdata(mode_switch);
 	typec_dp_bridge = port->sdata->typec_dp_bridge;
@@ -172,17 +182,41 @@ static int cros_typec_dp_port_switch_set(struct typec_mux_dev *mode_switch,
 	bridge = &typec_dp_bridge->bridge;
 
 	if (state->mode == TYPEC_STATE_SAFE || state->mode == TYPEC_STATE_USB) {
-		if (typec_dp_bridge->hpd_enabled)
-			drm_bridge_hpd_notify(bridge, connector_status_disconnected);
+		/* Clear active port when port isn't in DP mode */
+		port->num_dp_lanes = 0;
+		if (typec_dp_bridge->active_port == port) {
+			typec_dp_bridge->active_port = NULL;
+			if (typec_dp_bridge->hpd_enabled)
+				drm_bridge_hpd_notify(bridge, connector_status_disconnected);
+		}
 
 		return 0;
 	}
 
 	if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) {
-		if (typec_dp_bridge->hpd_enabled) {
-			dp_data = state->data;
-			hpd_asserted = dp_data->status & DP_STATUS_HPD_STATE;
+		dp_data = state->data;
+		hpd_asserted = dp_data->status & DP_STATUS_HPD_STATE;
+		/*
+		 * Assume the first port to have HPD asserted is the one muxed
+		 * to DP (i.e. active_port). When there's only one port this
+		 * delays setting the active_port until HPD is asserted, but
+		 * before that the drm_connector looks disconnected so
+		 * active_port doesn't need to be set.
+		 */
+		if (hpd_asserted && !typec_dp_bridge->active_port)
+			typec_dp_bridge->active_port = port;
 
+		/* Determine number of logical DP lanes from pin assignment */
+		pin_assign = DP_CONF_GET_PIN_ASSIGN(dp_data->conf);
+		if (pin_assign == DP_PIN_ASSIGN_D)
+			num_lanes = 2;
+		else
+			num_lanes = 4;
+		max_lanes = typec_dp_bridge->max_lanes;
+		port->num_dp_lanes = min(num_lanes, max_lanes);
+
+		/* Only notify hpd state for the port that has entered DP mode. */
+		if (typec_dp_bridge->hpd_enabled && typec_dp_bridge->active_port == port) {
 			if (hpd_asserted)
 				drm_bridge_hpd_notify(bridge, connector_status_connected);
 			else
@@ -278,6 +312,81 @@ bridge_to_cros_typec_dp_bridge(struct drm_bridge *bridge)
 	return container_of(bridge, struct cros_typec_dp_bridge, bridge);
 }
 
+static int dp_lane_to_typec_lane(unsigned int dp_lane)
+{
+	switch (dp_lane) {
+	case 0:
+		return 2;
+	case 1:
+		return 3;
+	case 2:
+		return 1;
+	case 3:
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int typec_to_dp_lane(unsigned int typec_lane)
+{
+	switch (typec_lane) {
+	case 0:
+		return 3;
+	case 1:
+		return 2;
+	case 2:
+		return 0;
+	case 3:
+		return 1;
+	}
+
+	return -EINVAL;
+}
+
+static int cros_typec_dp_bridge_atomic_check(struct drm_bridge *bridge,
+			    struct drm_bridge_state *bridge_state,
+			    struct drm_crtc_state *crtc_state,
+			    struct drm_connector_state *conn_state)
+{
+	struct cros_typec_dp_bridge *typec_dp_bridge;
+	struct drm_lane_cfg *in_lanes;
+	size_t num_lanes;
+	struct cros_typec_port *port;
+	int i, typec_lane;
+
+	typec_dp_bridge = bridge_to_cros_typec_dp_bridge(bridge);
+	if (!typec_dp_bridge->active_port)
+		return -ENODEV;
+
+	port = typec_dp_bridge->active_port;
+
+	num_lanes = port->num_dp_lanes;
+	in_lanes = kcalloc(num_lanes, sizeof(*in_lanes), GFP_KERNEL);
+	if (!in_lanes)
+		return -ENOMEM;
+
+	bridge_state->input_bus_cfg.lanes = in_lanes;
+	bridge_state->input_bus_cfg.num_lanes = num_lanes;
+
+	for (i = 0; i < num_lanes; i++) {
+		/* Get physical type-c lane for DP lane */
+		typec_lane = dp_lane_to_typec_lane(i);
+		if (typec_lane < 0) {
+			DRM_ERROR("Invalid type-c lane configuration\n");
+			return -EINVAL;
+		}
+
+		/* Map to logical type-c lane */
+		typec_lane = port->lane_mapping[typec_lane];
+
+		/* Map logical type-c lane to logical DP lane */
+		in_lanes[i].logical = typec_to_dp_lane(typec_lane);
+	}
+
+	return 0;
+}
+
 static void cros_typec_dp_bridge_hpd_enable(struct drm_bridge *bridge)
 {
 	struct cros_typec_dp_bridge *typec_dp_bridge;
@@ -296,6 +405,10 @@ static void cros_typec_dp_bridge_hpd_disable(struct drm_bridge *bridge)
 
 static const struct drm_bridge_funcs cros_typec_dp_bridge_funcs = {
 	.attach = cros_typec_dp_bridge_attach,
+	.atomic_check = cros_typec_dp_bridge_atomic_check,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
 	.hpd_enable = cros_typec_dp_bridge_hpd_enable,
 	.hpd_disable = cros_typec_dp_bridge_hpd_disable,
 };
@@ -305,6 +418,7 @@ static int cros_typec_register_dp_bridge(struct cros_typec_switch_data *sdata,
 {
 	struct cros_typec_dp_bridge *typec_dp_bridge;
 	struct drm_bridge *bridge;
+	int num_lanes;
 	struct device *dev = sdata->dev;
 
 	typec_dp_bridge = devm_kzalloc(dev, sizeof(*typec_dp_bridge), GFP_KERNEL);
@@ -313,6 +427,12 @@ static int cros_typec_register_dp_bridge(struct cros_typec_switch_data *sdata,
 
 	typec_dp_bridge->sdata = sdata;
 	sdata->typec_dp_bridge = typec_dp_bridge;
+
+	num_lanes = fwnode_property_count_u32(fwnode, "data-lanes");
+	if (num_lanes < 0)
+		num_lanes = 4;
+	typec_dp_bridge->max_lanes = num_lanes;
+
 	bridge = &typec_dp_bridge->bridge;
 
 	bridge->funcs = &cros_typec_dp_bridge_funcs;
@@ -333,6 +453,7 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 	struct fwnode_handle *port_node;
 	u32 index;
 	int ret;
+	const u32 default_lane_mapping[] = { 0, 1, 2, 3 };
 	const char *prop_name;
 
 	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
@@ -359,6 +480,11 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 	port->port_num = index;
 	sdata->ports[index] = port;
 
+	if (fwnode_property_read_u32_array(fwnode, "data-lanes",
+					   port->lane_mapping,
+					   ARRAY_SIZE(port->lane_mapping)))
+		memcpy(port->lane_mapping, default_lane_mapping, sizeof(default_lane_mapping));
+
 	port_node = fwnode;
 	if (np)
 		fwnode = fwnode_graph_get_port_parent(fwnode);
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:27 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:27 -0800
Subject: [PATCH 16/22] platform/chrome: cros_typec_switch: Support orientation-switch
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-17-swboyd@chromium.org>

Register an orientation switch with the typec subsystem when the
'orientation-switch' DT property is present. In these sorts of hardware
designs, the DP phy lanes are wired directly to the usb-c-connector. The
EC signals entry and exit of DP mode on the port, and the DP phy lanes
are assigned to the pins based on the port orientation (normal or
reverse).

Stash the orientation of the port and simply wait for the atomic_check
phase to request the desired DP lane assignment (normal or reverse).
Don't restrict this to the presence of the mode-switch property because
it's possible for this device to only be an orientation-switch, in which
case the DP mode entry is signaled externally (e.g. through an HPD pin
on the DP source).

Cc: Prashant Malani <pmalani at chromium.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Tzung-Bi Shih <tzungbi at kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/platform/chrome/cros_typec_switch.c | 84 ++++++++++++++++++---
 1 file changed, 72 insertions(+), 12 deletions(-)

diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
index adcbf8f44c98..c22c2531327a 100644
--- a/drivers/platform/chrome/cros_typec_switch.c
+++ b/drivers/platform/chrome/cros_typec_switch.c
@@ -38,9 +38,11 @@ struct cros_typec_dp_bridge {
 struct cros_typec_port {
 	int port_num;
 	struct typec_mux_dev *mode_switch;
+	struct typec_switch_dev *orientation_switch;
 	struct typec_retimer *retimer;
 	size_t num_dp_lanes;
 	u32 lane_mapping[USBC_LANES_COUNT];
+	enum typec_orientation orientation;
 	struct cros_typec_switch_data *sdata;
 };
 
@@ -245,6 +247,21 @@ static int cros_typec_mode_switch_set(struct typec_mux_dev *mode_switch,
 	return 0;
 }
 
+static int cros_typec_dp_port_orientation_set(struct typec_switch_dev *sw,
+					      enum typec_orientation orientation)
+{
+	struct cros_typec_port *port = typec_switch_get_drvdata(sw);
+
+	/*
+	 * Lane remapping is in cros_typec_dp_bridge_atomic_check(). Whenever
+	 * an orientation changes HPD will go low and then high again so the
+	 * atomic check handles the orientation change.
+	 */
+	port->orientation = orientation;
+
+	return 0;
+}
+
 static int cros_typec_retimer_set(struct typec_retimer *retimer, struct typec_retimer_state *state)
 {
 	struct cros_typec_port *port = typec_retimer_get_drvdata(retimer);
@@ -280,6 +297,21 @@ static int cros_typec_register_mode_switch(struct cros_typec_port *port,
 	return PTR_ERR_OR_ZERO(port->mode_switch);
 }
 
+static int cros_typec_register_orientation_switch(struct cros_typec_port *port,
+						  struct fwnode_handle *fwnode)
+{
+	struct typec_switch_desc orientation_switch_desc = {
+		.fwnode = fwnode,
+		.drvdata = port,
+		.name = fwnode_get_name(fwnode),
+		.set = cros_typec_dp_port_orientation_set,
+	};
+
+	port->orientation_switch = typec_switch_register(port->sdata->dev, &orientation_switch_desc);
+
+	return PTR_ERR_OR_ZERO(port->orientation_switch);
+}
+
 static int cros_typec_register_retimer(struct cros_typec_port *port, struct fwnode_handle *fwnode)
 {
 	struct typec_retimer_desc retimer_desc = {
@@ -328,17 +360,35 @@ static int dp_lane_to_typec_lane(unsigned int dp_lane)
 	return -EINVAL;
 }
 
-static int typec_to_dp_lane(unsigned int typec_lane)
+static int typec_to_dp_lane(unsigned int typec_lane,
+			    enum typec_orientation orientation)
 {
-	switch (typec_lane) {
-	case 0:
-		return 3;
-	case 1:
-		return 2;
-	case 2:
-		return 0;
-	case 3:
-		return 1;
+	switch (orientation) {
+	case TYPEC_ORIENTATION_NONE:
+	case TYPEC_ORIENTATION_NORMAL:
+		switch (typec_lane) {
+		case 0:
+			return 3;
+		case 1:
+			return 2;
+		case 2:
+			return 0;
+		case 3:
+			return 1;
+		}
+		break;
+	case TYPEC_ORIENTATION_REVERSE:
+		switch (typec_lane) {
+		case 0:
+			return 0;
+		case 1:
+			return 1;
+		case 2:
+			return 3;
+		case 3:
+			return 2;
+		}
+		break;
 	}
 
 	return -EINVAL;
@@ -381,7 +431,7 @@ static int cros_typec_dp_bridge_atomic_check(struct drm_bridge *bridge,
 		typec_lane = port->lane_mapping[typec_lane];
 
 		/* Map logical type-c lane to logical DP lane */
-		in_lanes[i].logical = typec_to_dp_lane(typec_lane);
+		in_lanes[i].logical = typec_to_dp_lane(typec_lane, port->orientation);
 	}
 
 	return 0;
@@ -509,6 +559,15 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
 		dev_dbg(dev, "Mode switch registered for index %u\n", index);
 	}
 
+	if (fwnode_property_present(fwnode, "orientation-switch")) {
+		ret = cros_typec_register_orientation_switch(port, port_node);
+		if (ret) {
+			dev_err(dev, "Orientation switch register failed\n");
+			goto out;
+		}
+
+		dev_dbg(dev, "Orientation switch registered for index %u\n", index);
+	}
 
 out:
 	if (np)
@@ -556,7 +615,8 @@ static int cros_typec_register_switches(struct cros_typec_switch_data *sdata)
 		}
 	}
 
-	if (fwnode_property_present(devnode, "mode-switch")) {
+	if (fwnode_property_present(devnode, "mode-switch") ||
+	    fwnode_property_present(devnode, "orientation-switch")) {
 		fwnode = fwnode_graph_get_endpoint_by_id(devnode, 0, 0, 0);
 		if (fwnode) {
 			ret = cros_typec_register_dp_bridge(sdata, fwnode);
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:28 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:28 -0800
Subject: [PATCH 17/22] platform/chrome: cros_typec_switch: Handle lack of HPD information
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-18-swboyd@chromium.org>

Some EC firmwares on Trogdor/Strongbad boards don't properly indicate
the state of DP HPD on a type-c port. Instead, the EC only indicates
that DP mode is entered or exited for a type-c port. To make matters
worse, on these firmwares the DP signal is muxed between two USB type-c
connectors, so we can't use the HPD state to figure out which type-c
port is actually displaying DP.

Read the state of the EC's analog mux from the hpd notification callback
to figure out which type-c port is displaying DP. This circumvents the
entire host command/message interface, because it doesn't work all the
time. Only do this when we have the mux-gpios property in DT, indicating
that we have to read the EC gpio state to figure this out. For now we
only support a single gpio "bit", so there can only be two USB type-c
ports.

Cc: Prashant Malani <pmalani at chromium.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Tzung-Bi Shih <tzungbi at kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 drivers/platform/chrome/cros_typec_switch.c | 33 ++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
index c22c2531327a..edd628eab7da 100644
--- a/drivers/platform/chrome/cros_typec_switch.c
+++ b/drivers/platform/chrome/cros_typec_switch.c
@@ -8,6 +8,7 @@
 
 #include <linux/acpi.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -26,6 +27,7 @@
 struct cros_typec_dp_bridge {
 	/* TODO: Add mutex lock to protect active_port with respect to drm/typec framework calls */
 	struct cros_typec_port *active_port;
+	struct gpio_desc *mux_gpio;
 	struct cros_typec_switch_data *sdata;
 	size_t max_lanes;
 	bool hpd_enabled;
@@ -453,6 +455,29 @@ static void cros_typec_dp_bridge_hpd_disable(struct drm_bridge *bridge)
 	typec_dp_bridge->hpd_enabled = false;
 }
 
+static void cros_typec_dp_bridge_hpd_notify(struct drm_bridge *bridge,
+					    enum drm_connector_status status)
+{
+	struct cros_typec_dp_bridge *typec_dp_bridge;
+	struct cros_typec_switch_data *sdata;
+	struct gpio_desc *mux_gpio;
+	int mux_val;
+
+	typec_dp_bridge = bridge_to_cros_typec_dp_bridge(bridge);
+	mux_gpio = typec_dp_bridge->mux_gpio;
+
+	/*
+	 * Some ECs don't notify AP when HPD goes high or low so we have to
+	 * read the EC GPIO that controls the mux to figure out which type-c
+	 * port is connected to DP.
+	 */
+	if (mux_gpio) {
+		sdata = typec_dp_bridge->sdata;
+		mux_val = gpiod_get_value_cansleep(mux_gpio);
+		typec_dp_bridge->active_port = sdata->ports[mux_val];
+	}
+}
+
 static const struct drm_bridge_funcs cros_typec_dp_bridge_funcs = {
 	.attach = cros_typec_dp_bridge_attach,
 	.atomic_check = cros_typec_dp_bridge_atomic_check,
@@ -461,6 +486,7 @@ static const struct drm_bridge_funcs cros_typec_dp_bridge_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
 	.hpd_enable = cros_typec_dp_bridge_hpd_enable,
 	.hpd_disable = cros_typec_dp_bridge_hpd_disable,
+	.hpd_notify = cros_typec_dp_bridge_hpd_notify,
 };
 
 static int cros_typec_register_dp_bridge(struct cros_typec_switch_data *sdata,
@@ -478,6 +504,10 @@ static int cros_typec_register_dp_bridge(struct cros_typec_switch_data *sdata,
 	typec_dp_bridge->sdata = sdata;
 	sdata->typec_dp_bridge = typec_dp_bridge;
 
+	typec_dp_bridge->mux_gpio = devm_gpiod_get_optional(dev, "mux", 0);
+	if (IS_ERR(typec_dp_bridge->mux_gpio))
+		return PTR_ERR(typec_dp_bridge->mux_gpio);
+
 	num_lanes = fwnode_property_count_u32(fwnode, "data-lanes");
 	if (num_lanes < 0)
 		num_lanes = 4;
@@ -488,7 +518,8 @@ static int cros_typec_register_dp_bridge(struct cros_typec_switch_data *sdata,
 	bridge->funcs = &cros_typec_dp_bridge_funcs;
 	bridge->of_node = dev->of_node;
 	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
-	bridge->ops |= DRM_BRIDGE_OP_HPD;
+	if (!fwnode_property_present(dev_fwnode(dev), "no-hpd"))
+		bridge->ops |= DRM_BRIDGE_OP_HPD;
 
 	return devm_drm_bridge_add(dev, bridge);
 }
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:29 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:29 -0800
Subject: [PATCH 18/22] dt-bindings: chrome: Add binding for ChromeOS Pogo pin connector
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-19-swboyd@chromium.org>

Describe the set of pins used to connect the detachable keyboard on
detachable ChromeOS devices. The set of pins is called the "pogo pins".
It's basically USB 2.0 with an extra pin for base detection. We expect
to find a keyboard on the other side of this connector with a specific
vid/pid, so describe that as a child device at the port of the usb
device connected upstream.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: Benson Leung <bleung at chromium.org>
Cc: Guenter Roeck <groeck at chromium.org>
Cc: <devicetree at vger.kernel.org>
Cc: <chrome-platform at lists.linux.dev>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 .../chrome/google,pogo-pin-connector.yaml     | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml

diff --git a/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml b/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml
new file mode 100644
index 000000000000..5ba68fd95fcd
--- /dev/null
+++ b/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/chrome/google,pogo-pin-connector.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Google Pogo Pin Connector
+
+maintainers:
+  - Stephen Boyd <swboyd at chromium.org>
+
+properties:
+  compatible:
+    const: google,pogo-pin-connector
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description: Connection to USB2 port providing USB signals
+    required:
+      - endpoint
+
+patternProperties:
+  "^keyboard@[0-9a-f]{1,2}$":
+    description: The detachable keyboard
+    type: object
+    $ref: /schemas/usb/usb-device.yaml
+
+required:
+  - compatible
+  - '#address-cells'
+  - '#size-cells'
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    connector {
+        compatible = "google,pogo-pin-connector";
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        keyboard at 2 {
+          compatible = "usb18d1,504c";
+          reg = <2>;
+        };
+
+        port {
+            pogo_connector_in: endpoint {
+                remote-endpoint = <&usb_hub_dsp3_hs>;
+            };
+        };
+    };
+
+...
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:30 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:30 -0800
Subject: [PATCH 19/22] arm64: dts: qcom: sc7180: quackingstick: Disable instead of delete usb_c1
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-20-swboyd@chromium.org>

It's simpler to reason about things if we disable nodes instead of
deleting them. Disable the second usb type-c connector node on
quackingstick instead of deleting it so that we can reason about ports
more easily.

Cc: <cros-qcom-dts-watchers at chromium.org>
Cc: Andy Gross <agross at kernel.org>
Cc: Bjorn Andersson <andersson at kernel.org>
Cc: Konrad Dybcio <konrad.dybcio at linaro.org>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: <linux-arm-msm at vger.kernel.org>
Cc: <devicetree at vger.kernel.org>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 .../arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
index 5f06842c683b..b7de9fd3fa20 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
@@ -10,9 +10,6 @@
 #include "sc7180-trogdor.dtsi"
 #include "sc7180-trogdor-rt5682i-sku.dtsi"
 
-/* This board only has 1 USB Type-C port. */
-/delete-node/ &usb_c1;
-
 / {
 	ppvar_lcd: ppvar-lcd-regulator {
 		compatible = "regulator-fixed";
@@ -136,6 +133,11 @@ pp3300_disp_on: &pp3300_dx_edp {
 	gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
 };
 
+/* This board only has 1 USB Type-C port. */
+&usb_c1 {
+	status = "disabled";
+};
+
 /* PINCTRL - modifications to sc7180-trogdor.dtsi */
 
 /*
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:31 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:31 -0800
Subject: [PATCH 20/22] arm64: dts: qcom: sc7180: pazquel: Add missing comment header
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-21-swboyd@chromium.org>

We put a header before modifying pinctrl nodes defined in
sc7180-trogdor.dtsi in every other file. Add one here so we know that
this section is for pinctrl modifications.

Cc: <cros-qcom-dts-watchers at chromium.org>
Cc: Andy Gross <agross at kernel.org>
Cc: Bjorn Andersson <andersson at kernel.org>
Cc: Konrad Dybcio <konrad.dybcio at linaro.org>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: <linux-arm-msm at vger.kernel.org>
Cc: <devicetree at vger.kernel.org>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
index 8823edbb4d6e..73aa75621721 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
@@ -83,6 +83,8 @@ &pp3300_dx_edp {
 	gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
 };
 
+/* PINCTRL - modifications to sc7180-trogdor.dtsi */
+
 &en_pp3300_dx_edp {
 	pins = "gpio67";
 };
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:32 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:32 -0800
Subject: [PATCH 21/22] arm64: dts: qcom: sc7180-trogdor: Make clamshell/detachable fragments
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-22-swboyd@chromium.org>

At a high-level, detachable Trogdors (sometimes known as Strongbads)
don't have a cros_ec keyboard, while all clamshell Trogdors (only known
as Trogdors) always have a cros_ec keyboard. Looking closer though, all
clamshells have a USB type-A connector and a hardwired USB camera. And
all detachables replace the USB camera with a MIPI based one and swap
the USB type-a connector for the detachable keyboard pogo pins.

Split the detachable and clamshell bits into different files so we can
describe these differences in one place instead of in each board that
includes sc7180-trogdor.dtsi. For now this is just the keyboard part,
but eventually this will include the type-a port and the pogo pins.

Cc: <cros-qcom-dts-watchers at chromium.org>
Cc: Andy Gross <agross at kernel.org>
Cc: Bjorn Andersson <andersson at kernel.org>
Cc: Konrad Dybcio <konrad.dybcio at linaro.org>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: <linux-arm-msm at vger.kernel.org>
Cc: <devicetree at vger.kernel.org>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 .../boot/dts/qcom/sc7180-trogdor-clamshell.dtsi      |  9 +++++++++
 arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi  |  5 +----
 .../boot/dts/qcom/sc7180-trogdor-detachable.dtsi     | 12 ++++++++++++
 .../arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi |  7 +------
 .../boot/dts/qcom/sc7180-trogdor-kingoftown.dts      |  2 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi   |  3 +--
 arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi |  2 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi  |  2 +-
 .../boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi  |  7 +------
 arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts       |  2 +-
 .../boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi    |  5 +----
 11 files changed, 30 insertions(+), 26 deletions(-)
 create mode 100644 arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
new file mode 100644
index 000000000000..bcf3df463f80
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Trogdor dts framgent for clamshells
+ *
+ * Copyright 2024 Google LLC.
+ */
+
+/* This file must be included after sc7180-trogdor.dtsi */
+#include <arm/cros-ec-keyboard.dtsi>
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
index 7765c8f64905..6e6a4643c4dd 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
@@ -7,6 +7,7 @@
 
 #include "sc7180-trogdor.dtsi"
 #include "sc7180-trogdor-ti-sn65dsi86.dtsi"
+#include "sc7180-trogdor-detachable.dtsi"
 
 /* Deleted nodes from sc7180-trogdor.dtsi */
 
@@ -80,10 +81,6 @@ &camcc {
 };
 
 &cros_ec {
-	keyboard-controller {
-		compatible = "google,cros-ec-keyb-switches";
-	};
-
 	cros_ec_proximity: proximity {
 		compatible = "google,cros-ec-mkbp-proximity";
 		label = "proximity-wifi";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
new file mode 100644
index 000000000000..ab0f30288871
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Trogdor dts framgent for detachables
+ *
+ * Copyright 2024 Google LLC.
+ */
+
+&cros_ec {
+	keyboard-controller {
+		compatible = "google,cros-ec-keyb-switches";
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
index 2ba3bbf3b9ad..a86a6c5c3f67 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
@@ -8,6 +8,7 @@
 /* This file must be included after sc7180-trogdor.dtsi */
 
 #include "sc7180-trogdor-rt5682i-sku.dtsi"
+#include "sc7180-trogdor-detachable.dtsi"
 
 / {
 	/* BOARD-SPECIFIC TOP LEVEL NODES */
@@ -135,12 +136,6 @@ &camcc {
 	status = "okay";
 };
 
-&cros_ec {
-	keyboard-controller {
-		compatible = "google,cros-ec-keyb-switches";
-	};
-};
-
 &panel {
 	compatible = "samsung,atna33xc20";
 	enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
index d6db7d83adcf..655bea928e52 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
@@ -9,7 +9,7 @@
 
 #include "sc7180-trogdor.dtsi"
 #include "sc7180-trogdor-parade-ps8640.dtsi"
-#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-clamshell.dtsi"
 #include "sc7180-trogdor-lte-sku.dtsi"
 #include "sc7180-trogdor-rt5682s-sku.dtsi"
 
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
index e9f213d27711..c3fd6760de7a 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
@@ -5,8 +5,7 @@
  * Copyright 2020 Google LLC.
  */
 
-/* This file must be included after sc7180-trogdor.dtsi */
-#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-clamshell.dtsi"
 
 &ap_sar_sensor {
 	semtech,cs0-ground;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
index 73aa75621721..60ccd3abddfc 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
@@ -6,7 +6,7 @@
  */
 
 /* This file must be included after sc7180-trogdor.dtsi */
-#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-clamshell.dtsi"
 
 &ap_sar_sensor {
 	compatible = "semtech,sx9324";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
index 0be62331f982..43b2583f0f26 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
@@ -7,7 +7,7 @@
 
 #include "sc7180-trogdor.dtsi"
 /* Must come after sc7180-trogdor.dtsi to modify cros_ec */
-#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-clamshell.dtsi"
 #include "sc7180-trogdor-rt5682i-sku.dtsi"
 #include "sc7180-trogdor-ti-sn65dsi86.dtsi"
 
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
index b7de9fd3fa20..00229b1515e6 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
@@ -9,6 +9,7 @@
 
 #include "sc7180-trogdor.dtsi"
 #include "sc7180-trogdor-rt5682i-sku.dtsi"
+#include "sc7180-trogdor-detachable.dtsi"
 
 / {
 	ppvar_lcd: ppvar-lcd-regulator {
@@ -44,12 +45,6 @@ &camcc {
 	status = "okay";
 };
 
-&cros_ec {
-	keyboard-controller {
-		compatible = "google,cros-ec-keyb-switches";
-	};
-};
-
 &gpio_keys {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts
index c9667751a990..4b43a9b273c0 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts
@@ -9,7 +9,7 @@
 
 #include "sc7180-trogdor.dtsi"
 /* Must come after sc7180-trogdor.dtsi to modify cros_ec */
-#include <arm/cros-ec-keyboard.dtsi>
+#include "sc7180-trogdor-clamshell.dtsi"
 #include "sc7180-trogdor-rt5682i-sku.dtsi"
 #include "sc7180-trogdor-ti-sn65dsi86.dtsi"
 
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
index 305ad127246e..1d9fc61b6550 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
@@ -8,6 +8,7 @@
 /dts-v1/;
 
 #include "sc7180-trogdor.dtsi"
+#include "sc7180-trogdor-detachable.dtsi"
 
 / {
 	avdd_lcd: avdd-lcd-regulator {
@@ -104,10 +105,6 @@ &cros_ec {
 	base_detection: cbas {
 		compatible = "google,cros-cbas";
 	};
-
-	keyboard-controller {
-		compatible = "google,cros-ec-keyb-switches";
-	};
 };
 
 &i2c4 {
-- 
https://chromeos.dev



From swboyd at chromium.org  Fri Feb  9 23:09:33 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Fri,  9 Feb 2024 23:09:33 -0800
Subject: [PATCH 22/22] arm64: dts: qcom: sc7180-trogdor: Wire up USB and DP to usb-c-connectors
In-Reply-To: <20240210070934.2549994-1-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
Message-ID: <20240210070934.2549994-23-swboyd@chromium.org>

Fully describe the USB type-c and DP topology on sc7180 Trogdor devices.
Most Trogdor devices have two USB type-c ports (i.e. usb-c-connector
nodes), but quackingstick only has one. Also, clamshell devices such as
Lazor have a USB webcam connected to the USB hub, while detachable
devices such as Wormdingler don't have a webcam, or a USB type-a
connector. Instead they have the pogo pins for the detachable keyboard.

Fully describing the topology like this will let us expose information
about what devices are connected to which physical USB connector (type-A
or type-C) and which port is connected to an external display for DP.

Cc: <cros-qcom-dts-watchers at chromium.org>
Cc: Andy Gross <agross at kernel.org>
Cc: Bjorn Andersson <andersson at kernel.org>
Cc: Konrad Dybcio <konrad.dybcio at linaro.org>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: <linux-arm-msm at vger.kernel.org>
Cc: <devicetree at vger.kernel.org>
Cc: Pin-yen Lin <treapking at chromium.org>
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 .../dts/qcom/sc7180-trogdor-clamshell.dtsi    |  21 +++
 .../boot/dts/qcom/sc7180-trogdor-coachz.dtsi  |  47 +++++
 .../dts/qcom/sc7180-trogdor-detachable.dtsi   |  13 ++
 .../dts/qcom/sc7180-trogdor-homestar.dtsi     |  47 +++++
 .../dts/qcom/sc7180-trogdor-kingoftown.dts    |  55 ++++++
 .../boot/dts/qcom/sc7180-trogdor-lazor.dtsi   |  55 ++++++
 .../boot/dts/qcom/sc7180-trogdor-pazquel.dtsi |  55 ++++++
 .../boot/dts/qcom/sc7180-trogdor-pompom.dtsi  |  44 +++++
 .../qcom/sc7180-trogdor-quackingstick.dtsi    |  31 ++++
 .../dts/qcom/sc7180-trogdor-wormdingler.dtsi  |  47 +++++
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  | 175 ++++++++++++++++++
 11 files changed, 590 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
index bcf3df463f80..96137202fc64 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
@@ -7,3 +7,24 @@
 
 /* This file must be included after sc7180-trogdor.dtsi */
 #include <arm/cros-ec-keyboard.dtsi>
+
+/ {
+	usb-a-connector {
+		compatible = "usb-a-connector";
+
+		port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			usb_a0_hs: endpoint at 0 {
+				reg = <0>;
+				/* Remote endpoint filled in by board */
+			};
+
+			usb_a0_ss: endpoint at 1 {
+				reg = <1>;
+				/* Remote endpoint filled in by board */
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
index 6e6a4643c4dd..4cf5b1e20b27 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
@@ -135,6 +135,17 @@ skin-temp-thermistor at 1 {
 	};
 };
 
+&pogo_pins {
+	keyboard at 4 {
+		compatible = "usb18d1,504c";
+		reg = <4>;
+	};
+};
+
+&pogo_pins_in {
+	remote-endpoint = <&usb_hub_dfp4_hs>;
+};
+
 &pp1800_uf_cam {
 	status = "okay";
 };
@@ -176,6 +187,42 @@ &sound_multimedia0_codec {
 	sound-dai = <&adau7002>;
 };
 
+&usb_c0_hs {
+	remote-endpoint = <&usb_hub_dfp1_hs>;
+};
+
+&usb_c0_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp1_ss>;
+};
+
+&usb_c1_hs {
+	remote-endpoint = <&usb_hub_dfp2_hs>;
+};
+
+&usb_c1_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp2_ss>;
+};
+
+&usb_hub_dfp1_hs {
+	remote-endpoint = <&usb_c0_hs>;
+};
+
+&usb_hub_dfp1_ss {
+	remote-endpoint = <&usb_c0_ss_rxtx>;
+};
+
+&usb_hub_dfp2_hs {
+	remote-endpoint = <&usb_c1_hs>;
+};
+
+&usb_hub_dfp2_ss {
+	remote-endpoint = <&usb_c1_ss_rxtx>;
+};
+
+&usb_hub_dfp4_hs {
+	remote-endpoint = <&pogo_pins_in>;
+};
+
 /* PINCTRL - modifications to sc7180-trogdor.dtsi */
 
 &en_pp3300_dx_edp {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
index ab0f30288871..b24a0213a477 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
@@ -5,6 +5,19 @@
  * Copyright 2024 Google LLC.
  */
 
+/ {
+	pogo_pins: pogo-pin-connector {
+		compatible = "google,pogo-pin-connector";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		/* Detachable keyboard populated for each board */
+		port {
+			pogo_pins_in: endpoint {
+			};
+		};
+	};
+};
+
 &cros_ec {
 	keyboard-controller {
 		compatible = "google,cros-ec-keyb-switches";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
index a86a6c5c3f67..9e32c984ab32 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
@@ -162,6 +162,17 @@ skin-temp-thermistor at 1 {
 	};
 };
 
+&pogo_pins {
+	keyboard at 3 {
+		compatible = "usb18d1,5052";
+		reg = <3>;
+	};
+};
+
+&pogo_pins_in {
+	remote-endpoint = <&usb_hub_dfp3_hs>;
+};
+
 &pp1800_uf_cam {
 	status = "okay";
 };
@@ -190,6 +201,42 @@ &sound_multimedia1_codec {
 	sound-dai = <&max98360a>, <&max98360a_1>, <&max98360a_2>, <&max98360a_3> ;
 };
 
+&usb_c0_hs {
+	remote-endpoint = <&usb_hub_dfp2_hs>;
+};
+
+&usb_c0_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp2_ss>;
+};
+
+&usb_c1_hs {
+	remote-endpoint = <&usb_hub_dfp4_hs>;
+};
+
+&usb_c1_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp4_ss>;
+};
+
+&usb_hub_dfp2_hs {
+	remote-endpoint = <&usb_c0_hs>;
+};
+
+&usb_hub_dfp2_ss {
+	remote-endpoint = <&usb_c0_ss_rxtx>;
+};
+
+&usb_hub_dfp3_hs {
+	remote-endpoint = <&pogo_pins_in>;
+};
+
+&usb_hub_dfp4_hs {
+	remote-endpoint = <&usb_c1_hs>;
+};
+
+&usb_hub_dfp4_ss {
+	remote-endpoint = <&usb_c1_ss_rxtx>;
+};
+
 &wifi {
 	qcom,ath10k-calibration-variant = "GO_HOMESTAR";
 };
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
index 655bea928e52..476c0a2f30da 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dts
@@ -78,6 +78,61 @@ &pp3300_dx_edp {
 	gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
 };
 
+&usb_a0_hs {
+	remote-endpoint = <&usb_hub_dfp3_hs>;
+};
+
+&usb_a0_ss {
+	remote-endpoint = <&usb_hub_dfp3_ss>;
+};
+
+&usb_c0_hs {
+	remote-endpoint = <&usb_hub_dfp1_hs>;
+};
+
+&usb_c0_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp1_ss>;
+};
+
+&usb_c1_hs {
+	remote-endpoint = <&usb_hub_dfp2_hs>;
+};
+
+&usb_c1_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp2_ss>;
+};
+
+&usb_hub_2_x {
+	camera at 4 {
+		compatible = "usb4f2,b75a";
+		reg = <4>;
+	};
+};
+
+&usb_hub_dfp1_hs {
+	remote-endpoint = <&usb_c0_hs>;
+};
+
+&usb_hub_dfp1_ss {
+	remote-endpoint = <&usb_c0_ss_rxtx>;
+};
+
+&usb_hub_dfp2_hs {
+	remote-endpoint = <&usb_c1_hs>;
+};
+
+&usb_hub_dfp2_ss {
+	remote-endpoint = <&usb_c1_ss_rxtx>;
+};
+
+&usb_hub_dfp3_hs {
+	remote-endpoint = <&usb_a0_hs>;
+};
+
+&usb_hub_dfp3_ss {
+	remote-endpoint = <&usb_a0_ss>;
+};
+
 &wifi {
 	qcom,ath10k-calibration-variant = "GO_KINGOFTOWN";
 };
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
index c3fd6760de7a..2603607ebd80 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
@@ -68,6 +68,61 @@ &trackpad {
 	interrupts = <58 IRQ_TYPE_EDGE_FALLING>;
 };
 
+&usb_hub_2_x {
+	camera at 1 {
+		compatible = "usb408,a092";
+		reg = <1>;
+	};
+};
+
+&usb_a0_hs {
+	remote-endpoint = <&usb_hub_dfp3_hs>;
+};
+
+&usb_a0_ss {
+	remote-endpoint = <&usb_hub_dfp3_ss>;
+};
+
+&usb_c0_hs {
+	remote-endpoint = <&usb_hub_dfp2_hs>;
+};
+
+&usb_c0_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp2_ss>;
+};
+
+&usb_c1_hs {
+	remote-endpoint = <&usb_hub_dfp4_hs>;
+};
+
+&usb_c1_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp4_ss>;
+};
+
+&usb_hub_dfp2_hs {
+	remote-endpoint = <&usb_c0_hs>;
+};
+
+&usb_hub_dfp2_ss {
+	remote-endpoint = <&usb_c0_ss_rxtx>;
+};
+
+&usb_hub_dfp3_hs {
+	remote-endpoint = <&usb_a0_hs>;
+};
+
+&usb_hub_dfp3_ss {
+	remote-endpoint = <&usb_a0_ss>;
+};
+
+&usb_hub_dfp4_hs {
+	remote-endpoint = <&usb_c1_hs>;
+};
+
+&usb_hub_dfp4_ss {
+	remote-endpoint = <&usb_c1_ss_rxtx>;
+};
+
 &wifi {
 	qcom,ath10k-calibration-variant = "GO_LAZOR";
 };
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
index 60ccd3abddfc..dee06c64b59a 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi
@@ -83,6 +83,61 @@ &pp3300_dx_edp {
 	gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
 };
 
+&usb_a0_hs {
+	remote-endpoint = <&usb_hub_dfp3_hs>;
+};
+
+&usb_a0_ss {
+	remote-endpoint = <&usb_hub_dfp3_ss>;
+};
+
+&usb_c0_hs {
+	remote-endpoint = <&usb_hub_dfp1_hs>;
+};
+
+&usb_c0_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp1_ss>;
+};
+
+&usb_c1_hs {
+	remote-endpoint = <&usb_hub_dfp2_hs>;
+};
+
+&usb_c1_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp2_ss>;
+};
+
+&usb_hub_2_x {
+	camera at 4 {
+		compatible = "usb5c8,b03";
+		reg = <4>;
+	};
+};
+
+&usb_hub_dfp1_hs {
+	remote-endpoint = <&usb_c0_hs>;
+};
+
+&usb_hub_dfp1_ss {
+	remote-endpoint = <&usb_c0_ss_rxtx>;
+};
+
+&usb_hub_dfp2_hs {
+	remote-endpoint = <&usb_c1_hs>;
+};
+
+&usb_hub_dfp2_ss {
+	remote-endpoint = <&usb_c1_ss_rxtx>;
+};
+
+&usb_hub_dfp3_hs {
+	remote-endpoint = <&usb_a0_hs>;
+};
+
+&usb_hub_dfp3_ss {
+	remote-endpoint = <&usb_a0_ss>;
+};
+
 /* PINCTRL - modifications to sc7180-trogdor.dtsi */
 
 &en_pp3300_dx_edp {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
index 43b2583f0f26..88ffa2331cd2 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
@@ -180,10 +180,54 @@ &sound {
 	dmic-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
 };
 
+&usb_a0_hs {
+	remote-endpoint = <&usb_hub_dfp4_hs>;
+};
+
+&usb_a0_ss {
+	remote-endpoint = <&usb_hub_dfp4_ss>;
+};
+
+&usb_c0_hs {
+	remote-endpoint = <&usb_hub_dfp3_hs>;
+};
+
+&usb_c0_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp3_ss>;
+};
+
 &usb_c1 {
 	status = "disabled";
 };
 
+&usb_hub_2_x {
+	camera at 1 {
+		compatible = "usb4f2,b718";
+		reg = <1>;
+	};
+
+	camera at 2 {
+		compatible = "usb13d3,56e9";
+		reg = <2>;
+	};
+};
+
+&usb_hub_dfp3_hs {
+	remote-endpoint = <&usb_c0_hs>;
+};
+
+&usb_hub_dfp3_ss {
+	remote-endpoint = <&usb_c0_ss_rxtx>;
+};
+
+&usb_hub_dfp4_hs {
+	remote-endpoint = <&usb_a0_hs>;
+};
+
+&usb_hub_dfp4_ss {
+	remote-endpoint = <&usb_a0_ss>;
+};
+
 &wifi {
 	qcom,ath10k-calibration-variant = "GO_POMPOM";
 };
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
index 00229b1515e6..d0d9871b74cb 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
@@ -104,6 +104,17 @@ &sdhc_2 {
 	status = "okay";
 };
 
+&pogo_pins {
+	keyboard at 1 {
+		compatible = "usb18d1,505b";
+		reg = <1>;
+	};
+};
+
+&pogo_pins_in {
+	remote-endpoint = <&usb_hub_dfp1_hs>;
+};
+
 &pp1800_uf_cam {
 	status = "okay";
 };
@@ -128,11 +139,31 @@ pp3300_disp_on: &pp3300_dx_edp {
 	gpio = <&tlmm 67 GPIO_ACTIVE_HIGH>;
 };
 
+&usb_c0_hs {
+	remote-endpoint = <&usb_hub_dfp2_hs>;
+};
+
+&usb_c0_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp2_ss>;
+};
+
 /* This board only has 1 USB Type-C port. */
 &usb_c1 {
 	status = "disabled";
 };
 
+&usb_hub_dfp2_hs {
+	remote-endpoint = <&usb_c0_hs>;
+};
+
+&usb_hub_dfp2_ss {
+	remote-endpoint = <&usb_c0_ss_rxtx>;
+};
+
+&usb_hub_dfp1_hs {
+	remote-endpoint = <&pogo_pins_in>;
+};
+
 /* PINCTRL - modifications to sc7180-trogdor.dtsi */
 
 /*
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
index 1d9fc61b6550..409d332fbc13 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
@@ -180,6 +180,17 @@ skin-temp-thermistor at 1 {
 	};
 };
 
+&pogo_pins {
+	keyboard at 3 {
+		compatible = "usb18d1,5057";
+		reg = <3>;
+	};
+};
+
+&pogo_pins_in {
+	remote-endpoint = <&usb_hub_dfp3_hs>;
+};
+
 &pp1800_uf_cam {
 	status = "okay";
 };
@@ -196,6 +207,42 @@ &pp2800_wf_cam {
 	status = "okay";
 };
 
+&usb_c0_hs {
+	remote-endpoint = <&usb_hub_dfp2_hs>;
+};
+
+&usb_c0_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp2_ss>;
+};
+
+&usb_c1_hs {
+	remote-endpoint = <&usb_hub_dfp4_hs>;
+};
+
+&usb_c1_ss_rxtx {
+	remote-endpoint = <&usb_hub_dfp3_ss>;
+};
+
+&usb_hub_dfp2_hs {
+	remote-endpoint = <&usb_c0_hs>;
+};
+
+&usb_hub_dfp2_ss {
+	remote-endpoint = <&usb_c0_ss_rxtx>;
+};
+
+&usb_hub_dfp4_hs {
+	remote-endpoint = <&usb_c1_hs>;
+};
+
+&usb_hub_dfp3_ss {
+	remote-endpoint = <&usb_c1_ss_rxtx>;
+};
+
+&usb_hub_dfp3_hs {
+	remote-endpoint = <&pogo_pins_in>;
+};
+
 &wifi {
 	qcom,ath10k-calibration-variant = "GO_WORMDINGLER";
 };
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 46aaeba28604..ee08a4ecade9 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -650,6 +650,12 @@ cros_ec: ec at 0 {
 		pinctrl-0 = <&ap_ec_int_l>;
 		spi-max-frequency = <3000000>;
 
+		cros_ec_gpio: gpio {
+			compatible = "google,cros-ec-gpio";
+			#gpio-cells = <2>;
+			gpio-controller;
+		};
+
 		cros_ec_pwm: pwm {
 			compatible = "google,cros-ec-pwm";
 			#pwm-cells = <1>;
@@ -662,6 +668,65 @@ i2c_tunnel: i2c-tunnel {
 			#size-cells = <0>;
 		};
 
+		typec-switch {
+			compatible = "google,cros-ec-typec-switch";
+			no-hpd;
+			mode-switch;
+			mux-gpios = <&cros_ec_gpio 42 GPIO_ACTIVE_HIGH>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					dp_ml0_ml1: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&mdss_dp_out>;
+						data-lanes = <0 1>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					usb_c0_ss_rxtx: endpoint at 0 {
+						reg = <0>;
+						/* Endpoint filled in by board */
+					};
+
+					usb_c1_ss_rxtx: endpoint at 1 {
+						reg = <1>;
+						/* Endpoint filled in by board */
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					cros_typec_c0_ss: endpoint at 0 {
+						reg = <0>;
+						remote-endpoint = <&usb_c0_ss>;
+						data-lanes = <0 1 2 3>;
+					};
+
+					cros_typec_c1_ss: endpoint at 1 {
+						reg = <1>;
+						remote-endpoint = <&usb_c1_ss>;
+						data-lanes = <0 1 2 3>;
+					};
+				};
+			};
+
+		};
+
 		typec {
 			compatible = "google,cros-ec-typec";
 			#address-cells = <1>;
@@ -674,6 +739,25 @@ usb_c0: connector at 0 {
 				power-role = "dual";
 				data-role = "host";
 				try-power-role = "source";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port at 0 {
+						reg = <0>;
+						usb_c0_hs: endpoint {
+							/* Endpoint filled in by board */
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+						usb_c0_ss: endpoint {
+							remote-endpoint = <&cros_typec_c0_ss>;
+						};
+					};
+				};
 			};
 
 			usb_c1: connector at 1 {
@@ -683,6 +767,25 @@ usb_c1: connector at 1 {
 				power-role = "dual";
 				data-role = "host";
 				try-power-role = "source";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port at 0 {
+						reg = <0>;
+						usb_c1_hs: endpoint {
+							/* Endpoint filled in by board */
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+						usb_c1_ss: endpoint {
+							remote-endpoint = <&cros_typec_c1_ss>;
+						};
+					};
+				};
 			};
 		};
 	};
@@ -794,6 +897,7 @@ &mdss_dp {
 &mdss_dp_out {
 	data-lanes = <0 1>;
 	link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000>;
+	remote-endpoint = <&dp_ml0_ml1>;
 };
 
 &mdss_dsi0 {
@@ -965,6 +1069,41 @@ usb_hub_2_x: hub at 1 {
 		reg = <1>;
 		vdd-supply = <&pp3300_hub>;
 		peer-hub = <&usb_hub_3_x>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usb_hub_2_x_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 1 {
+				reg = <1>;
+				usb_hub_dfp1_hs: endpoint {
+					/* Remote endpoint filled in by board */
+				};
+			};
+			port at 2 {
+				reg = <2>;
+				usb_hub_dfp2_hs: endpoint {
+					/* Remote endpoint filled in by board */
+				};
+			};
+
+			port at 3 {
+				reg = <3>;
+				usb_hub_dfp3_hs: endpoint {
+					/* Remote endpoint filled in by board */
+				};
+			};
+
+			port at 4 {
+				reg = <4>;
+				usb_hub_dfp4_hs: endpoint {
+					/* Remote endpoint filled in by board */
+				};
+			};
+		};
 	};
 
 	/* 3.x hub on port 2 */
@@ -973,6 +1112,42 @@ usb_hub_3_x: hub at 2 {
 		reg = <2>;
 		vdd-supply = <&pp3300_hub>;
 		peer-hub = <&usb_hub_2_x>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usb_hub_3_x_ports: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 1 {
+				reg = <1>;
+				usb_hub_dfp1_ss: endpoint {
+					/* Remote endpoint filled in by board */
+				};
+			};
+
+			port at 2 {
+				reg = <2>;
+				usb_hub_dfp2_ss: endpoint {
+					/* Remote endpoint filled in by board */
+				};
+			};
+
+			port at 3 {
+				reg = <3>;
+				usb_hub_dfp3_ss: endpoint {
+					/* Remote endpoint filled in by board */
+				};
+			};
+
+			port at 4 {
+				reg = <4>;
+				usb_hub_dfp4_ss: endpoint {
+					/* Remote endpoint filled in by board */
+				};
+			};
+		};
 	};
 };
 
-- 
https://chromeos.dev



From xtex at envs.net  Fri Feb  9 23:46:00 2024
From: xtex at envs.net (Zhang Bingwu)
Date: Sat, 10 Feb 2024 15:46:00 +0800
Subject: [PATCH 1/2] kbuild: Abort make on install failures
In-Reply-To: <20240210074601.5363-1-xtex@envs.net>
References: <20240210074601.5363-1-xtex@envs.net>
Message-ID: <20240210074601.5363-2-xtex@envs.net>

From: Zhang Bingwu <xtexchooser at duck.com>

Setting '-e' flag tells shells to exit with error exit code immediately
after any of commands fails, and causes make(1) to regard recipes as
failed.

Before this, make will still continue to succeed even after the
installation failed, for example, for insufficient permission or
directory does not exist.

Signed-off-by: Zhang Bingwu <xtexchooser at duck.com>
---
 arch/arm/boot/install.sh   | 2 ++
 arch/arm64/boot/install.sh | 2 ++
 arch/m68k/install.sh       | 2 ++
 arch/nios2/boot/install.sh | 2 ++
 arch/parisc/install.sh     | 2 ++
 arch/riscv/boot/install.sh | 2 ++
 arch/s390/boot/install.sh  | 2 ++
 arch/sparc/boot/install.sh | 2 ++
 arch/x86/boot/install.sh   | 2 ++
 9 files changed, 18 insertions(+)

diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh
index 9ec11fac7d8d..34e2c6e31fd1 100755
--- a/arch/arm/boot/install.sh
+++ b/arch/arm/boot/install.sh
@@ -17,6 +17,8 @@
 #   $3 - kernel map file
 #   $4 - default install path (blank if root directory)
 
+set -e
+
 if [ "$(basename $2)" = "zImage" ]; then
 # Compressed install
   echo "Installing compressed kernel"
diff --git a/arch/arm64/boot/install.sh b/arch/arm64/boot/install.sh
index 9b7a09808a3d..cc2f4ccca6c0 100755
--- a/arch/arm64/boot/install.sh
+++ b/arch/arm64/boot/install.sh
@@ -17,6 +17,8 @@
 #   $3 - kernel map file
 #   $4 - default install path (blank if root directory)
 
+set -e
+
 if [ "$(basename $2)" = "Image.gz" ] || [ "$(basename $2)" = "vmlinuz.efi" ]
 then
 # Compressed install
diff --git a/arch/m68k/install.sh b/arch/m68k/install.sh
index af65e16e5147..b6829b3942b3 100755
--- a/arch/m68k/install.sh
+++ b/arch/m68k/install.sh
@@ -16,6 +16,8 @@
 #   $3 - kernel map file
 #   $4 - default install path (blank if root directory)
 
+set -e
+
 if [ -f $4/vmlinuz ]; then
 	mv $4/vmlinuz $4/vmlinuz.old
 fi
diff --git a/arch/nios2/boot/install.sh b/arch/nios2/boot/install.sh
index 34a2feec42c8..1161f2bf59ec 100755
--- a/arch/nios2/boot/install.sh
+++ b/arch/nios2/boot/install.sh
@@ -16,6 +16,8 @@
 #   $3 - kernel map file
 #   $4 - default install path (blank if root directory)
 
+set -e
+
 if [ -f $4/vmlinuz ]; then
 	mv $4/vmlinuz $4/vmlinuz.old
 fi
diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh
index 933d031c249a..664c2d77f776 100755
--- a/arch/parisc/install.sh
+++ b/arch/parisc/install.sh
@@ -16,6 +16,8 @@
 #   $3 - kernel map file
 #   $4 - default install path (blank if root directory)
 
+set -e
+
 if [ "$(basename $2)" = "vmlinuz" ]; then
 # Compressed install
   echo "Installing compressed kernel"
diff --git a/arch/riscv/boot/install.sh b/arch/riscv/boot/install.sh
index 4c63f3f0643d..a59639dff64f 100755
--- a/arch/riscv/boot/install.sh
+++ b/arch/riscv/boot/install.sh
@@ -17,6 +17,8 @@
 #   $3 - kernel map file
 #   $4 - default install path (blank if root directory)
 
+set -e
+
 if [ "$(basename $2)" = "Image.gz" ]; then
 # Compressed install
   echo "Installing compressed kernel"
diff --git a/arch/s390/boot/install.sh b/arch/s390/boot/install.sh
index a13dd2f2aa1c..fa41486258ee 100755
--- a/arch/s390/boot/install.sh
+++ b/arch/s390/boot/install.sh
@@ -15,6 +15,8 @@
 #   $3 - kernel map file
 #   $4 - default install path (blank if root directory)
 
+set -e
+
 echo "Warning: '${INSTALLKERNEL}' command not available - additional " \
      "bootloader config required" >&2
 if [ -f "$4/vmlinuz-$1" ]; then mv -- "$4/vmlinuz-$1" "$4/vmlinuz-$1.old"; fi
diff --git a/arch/sparc/boot/install.sh b/arch/sparc/boot/install.sh
index 4f130f3f30d6..68de67c5621e 100755
--- a/arch/sparc/boot/install.sh
+++ b/arch/sparc/boot/install.sh
@@ -16,6 +16,8 @@
 #   $3 - kernel map file
 #   $4 - default install path (blank if root directory)
 
+set -e
+
 if [ -f $4/vmlinuz ]; then
 	mv $4/vmlinuz $4/vmlinuz.old
 fi
diff --git a/arch/x86/boot/install.sh b/arch/x86/boot/install.sh
index 0849f4b42745..93784abcd66d 100755
--- a/arch/x86/boot/install.sh
+++ b/arch/x86/boot/install.sh
@@ -16,6 +16,8 @@
 #   $3 - kernel map file
 #   $4 - default install path (blank if root directory)
 
+set -e
+
 if [ -f $4/vmlinuz ]; then
 	mv $4/vmlinuz $4/vmlinuz.old
 fi
-- 
2.43.0



From xtex at envs.net  Fri Feb  9 23:45:59 2024
From: xtex at envs.net (Zhang Bingwu)
Date: Sat, 10 Feb 2024 15:45:59 +0800
Subject: [PATCH 0/2] kbuild: Fix install errors when INSTALL_PATH does not exist
Message-ID: <20240210074601.5363-1-xtex@envs.net>

From: Zhang Bingwu <xtexchooser at duck.com>

When running 'make zinstall INSTALL_PATH=somepath'
 where 'somepath' does not exist, the install
 scripts (install.sh) print error messages
 but also return a success status code.
This will make 'make' regard 'install' (and 'zinstall', etc)
 succeeded.
When there are also other targets at the same time,
 for example, 'make zinstall dtbs_install modules_install',
 make will keep going on and other outputs will fill stdout,
 and make the error message hard to find.

dtbs_install and modules_install creates the target directory
 if it does not exist. install, zinstall and others should
 have the same behaviour.

If INSTALL_PATH is not a valid directory, we should create it.
If the installation process still fails with errors, for example,
 insufficient space on disk or permission denied, make should regard
 the install target failed, stop as soon as possible,
 and exit with error.

Zhang Bingwu (2):
  kbuild: Abort make on install failures
  kbuild: Create INSTALL_PATH directory if it does not exist

 arch/arm/boot/install.sh   | 2 ++
 arch/arm64/boot/install.sh | 2 ++
 arch/m68k/install.sh       | 2 ++
 arch/nios2/boot/install.sh | 2 ++
 arch/parisc/install.sh     | 2 ++
 arch/riscv/boot/install.sh | 2 ++
 arch/s390/boot/install.sh  | 2 ++
 arch/sparc/boot/install.sh | 2 ++
 arch/x86/boot/install.sh   | 2 ++
 scripts/install.sh         | 4 ++++
 10 files changed, 22 insertions(+)


base-commit: d0f86d080e3d7d5e1e75a56d88daf8e5f56a4146
-- 
2.43.0



From xtex at envs.net  Fri Feb  9 23:46:01 2024
From: xtex at envs.net (Zhang Bingwu)
Date: Sat, 10 Feb 2024 15:46:01 +0800
Subject: [PATCH 2/2] kbuild: Create INSTALL_PATH directory if it does not exist
In-Reply-To: <20240210074601.5363-1-xtex@envs.net>
References: <20240210074601.5363-1-xtex@envs.net>
Message-ID: <20240210074601.5363-3-xtex@envs.net>

From: Zhang Bingwu <xtexchooser at duck.com>

If INSTALL_PATH is not a valid directory, create it, like what
modules_install and dtbs_install will do in the same situation.

Signed-off-by: Zhang Bingwu <xtexchooser at duck.com>
---
 scripts/install.sh | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/scripts/install.sh b/scripts/install.sh
index 9bb0fb44f04a..02b845e7ab33 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -20,6 +20,10 @@ do
 	fi
 done
 
+if [ "${INSTALL_PATH}" != "" ] && ! [ -e "${INSTALL_PATH}" ]; then
+	mkdir -p "${INSTALL_PATH}"
+fi
+
 # User/arch may have a custom install script
 for file in "${HOME}/bin/${INSTALLKERNEL}"		\
 	    "/sbin/${INSTALLKERNEL}"			\
-- 
2.43.0



From maz at kernel.org  Sat Feb 10 01:32:21 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 10 Feb 2024 09:32:21 +0000
Subject: [PATCH v2] irqchip/irq-brcmstb-l2: add write memory barrier before exit
In-Reply-To: <20240210012449.3009125-1-florian.fainelli@broadcom.com>
References: <20240210012449.3009125-1-florian.fainelli@broadcom.com>
Message-ID: <87jzncwtp6.wl-maz@kernel.org>

On Sat, 10 Feb 2024 01:24:49 +0000,
Florian Fainelli <florian.fainelli at broadcom.com> wrote:
> 
> From: Doug Berger <opendmb at gmail.com>
> 
> It was observed on Broadcom devices that use GIC v3 architecture
> L1 interrupt controllers as the parent of brcmstb-l2 interrupt
> controllers that the deactivation of the parent irq could happen
> before the brcmstb-l2 deasserted its output. This would lead the
> GIC to reactivate the irq only to find that no L2 interrupt was
> pending. The result was a spurious interrupt invoking the
> handle_bad_irq() with its associated messaging. While this did
> not create a functional problem it is a waste of cycles.
> 
> The hazard exists because the memory mapped bus writes to the
> brcmstb-l2 registers are buffered and the GIC v3 architecture
> uses a very efficient system register write to deactivate the
> interrupt. This commit adds a write memory barrier prior to
> invoking chained_irq_exit() to introduce a dsb(st) on those
> systems to ensure the system register write cannot be executed
> until the memory mapped writes are visible to the system.
> 
> Signed-off-by: Doug Berger <opendmb at gmail.com>
> Acked-by: Florian Fainelli <florian.fainelli at broadcom.com>
> Fixes: 7f646e92766e ("irqchip: brcmstb-l2: Add Broadcom Set Top Box  Level-2 interrupt controller")
> [florian: Added Fixes tag]
> Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>

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

	M.

-- 
Without deviation from the norm, progress is not possible.


From linux at armlinux.org.uk  Sat Feb 10 02:29:00 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sat, 10 Feb 2024 10:29:00 +0000
Subject: [PATCH 1/2] kbuild: Abort make on install failures
In-Reply-To: <20240210074601.5363-2-xtex@envs.net>
References: <20240210074601.5363-1-xtex@envs.net>
 <20240210074601.5363-2-xtex@envs.net>
Message-ID: <ZcdP7CC+OMbp5ZMi@shell.armlinux.org.uk>

On Sat, Feb 10, 2024 at 03:46:00PM +0800, Zhang Bingwu wrote:
> From: Zhang Bingwu <xtexchooser at duck.com>
> 
> Setting '-e' flag tells shells to exit with error exit code immediately
> after any of commands fails, and causes make(1) to regard recipes as
> failed.
> 
> Before this, make will still continue to succeed even after the
> installation failed, for example, for insufficient permission or
> directory does not exist.
> 
> Signed-off-by: Zhang Bingwu <xtexchooser at duck.com>
> ---
>  arch/arm/boot/install.sh   | 2 ++
>  arch/arm64/boot/install.sh | 2 ++
>  arch/m68k/install.sh       | 2 ++
>  arch/nios2/boot/install.sh | 2 ++
>  arch/parisc/install.sh     | 2 ++
>  arch/riscv/boot/install.sh | 2 ++
>  arch/s390/boot/install.sh  | 2 ++
>  arch/sparc/boot/install.sh | 2 ++
>  arch/x86/boot/install.sh   | 2 ++
>  9 files changed, 18 insertions(+)
> 
> diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh
> index 9ec11fac7d8d..34e2c6e31fd1 100755
> --- a/arch/arm/boot/install.sh
> +++ b/arch/arm/boot/install.sh
> @@ -17,6 +17,8 @@
>  #   $3 - kernel map file
>  #   $4 - default install path (blank if root directory)
>  
> +set -e
> +

What about #!/bin/sh -e on the first line, which is the more normal way
to do this for an entire script?

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


From xtex at envs.net  Sat Feb 10 02:33:31 2024
From: xtex at envs.net (xtex)
Date: Sat, 10 Feb 2024 18:33:31 +0800
Subject: [PATCH 1/2] kbuild: Abort make on install failures
In-Reply-To: <ZcdP7CC+OMbp5ZMi@shell.armlinux.org.uk>
References: <20240210074601.5363-1-xtex@envs.net> <20240210074601.5363-2-xtex@envs.net>
 <ZcdP7CC+OMbp5ZMi@shell.armlinux.org.uk>
Message-ID: <4681093.vXUDI8C0e8@xtex>

On Saturday, February 10, 2024 6:29:00 PM CST Russell King (Oracle) wrote:
> What about #!/bin/sh -e on the first line, which is the more normal way
> to do this for an entire script?

Will do this in V2.

-- 
xtex @ Sat Feb 10 10:32:32 AM UTC 2024
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240210/4e249106/attachment.sig>

From baolu.lu at linux.intel.com  Sat Feb 10 03:27:46 2024
From: baolu.lu at linux.intel.com (Baolu Lu)
Date: Sat, 10 Feb 2024 19:27:46 +0800
Subject: [PATCH v3 6/7] iommu/dma: Centralise iommu_setup_dma_ops()
In-Reply-To: <202fcca3269201bc9c4a8198253f195433d0c4ff.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
 <202fcca3269201bc9c4a8198253f195433d0c4ff.1707493264.git.robin.murphy@arm.com>
Message-ID: <2a86f3d0-4aa7-4c32-afb9-e5a908a65d10@linux.intel.com>

On 2024/2/10 0:50, Robin Murphy wrote:
> It's somewhat hard to see, but arm64's arch_setup_dma_ops() should only
> ever call iommu_setup_dma_ops() after a successful iommu_probe_device(),
> which means there should be no harm in achieving the same order of
> operations by running it off the back of iommu_probe_device() itself.
> This then puts it in line with the x86 and s390 .probe_finalize bodges,
> letting us pull it all into the main flow properly. As a bonus this lets
> us fold in and de-scope the PCI workaround setup as well.
> 
> At this point we can also then pull the call up inside the group mutex,
> and avoid having to think about whether iommu_group_store_type() could
> theoretically race and free the domain if iommu_setup_dma_ops() ran just
> *before*  iommu_device_use_default_domain() claims it... Furthermore we
> replace one .probe_finalize call completely, since the only remaining
> implementations are now one which only needs to run once for the initial
> boot-time probe, and two which themselves render that path unreachable.
> 
> This leaves us a big step closer to realistically being able to unpick
> the variety of different things that iommu_setup_dma_ops() has been
> muddling together, and further streamline iommu-dma into core API flows
> in future.
> 
> Signed-off-by: Robin Murphy<robin.murphy at arm.com>
> ---
> v2: Shuffle around to make sure the iommu_group_do_probe_finalize() case
>      is covered as well, with bonus side-effects as above.
> v3:*Really*  do that, remembering the other two probe_finalize sites too.
> ---
>   arch/arm64/mm/dma-mapping.c  |  2 --
>   drivers/iommu/amd/iommu.c    |  8 --------
>   drivers/iommu/dma-iommu.c    | 18 ++++++------------
>   drivers/iommu/dma-iommu.h    | 14 ++++++--------
>   drivers/iommu/intel/iommu.c  |  7 -------
>   drivers/iommu/iommu.c        | 20 +++++++-------------
>   drivers/iommu/s390-iommu.c   |  6 ------
>   drivers/iommu/virtio-iommu.c | 10 ----------
>   include/linux/iommu.h        |  7 -------
>   9 files changed, 19 insertions(+), 73 deletions(-)

For changes in Intel IOMMU driver,

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>

Best regards,
baolu


From robh at kernel.org  Sat Feb 10 03:29:48 2024
From: robh at kernel.org (Rob Herring)
Date: Sat, 10 Feb 2024 11:29:48 +0000
Subject: [PATCH v1 02/14] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240210012114.489102-3-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-3-sre@kernel.org>
Message-ID: <170756458525.4188736.15197760675687420146.robh@kernel.org>


On Sat, 10 Feb 2024 02:18:06 +0100, Sebastian Reichel wrote:
> Convert the i.MX  Wireless External Interface Module binding to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../devicetree/bindings/bus/fsl,imx-weim.yaml | 225 ++++++++++++++++++
>  .../devicetree/bindings/bus/imx-weim.txt      | 117 ---------
>  2 files changed, 225 insertions(+), 117 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
>  delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.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/dt-review-ci/linux/Documentation/devicetree/bindings/bus/fsl,imx-weim.example.dtb: nor at 0,0: $nodename:0: 'nor at 0,0' does not match '^(flash|.*sram|nand)(@.*)?$'
	from schema $id: http://devicetree.org/schemas/mtd/mtd-physmap.yaml#
Documentation/devicetree/bindings/bus/fsl,imx-weim.example.dtb: /example-1/weim at 21b8000/acme at 0,0: failed to match any schema with compatible: ['acme,whatever']

doc reference errors (make refcheckdocs):
Warning: drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt references a file that doesn't exist: Documentation/devicetree/bindings/bus/imx-weim.txt
drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt: Documentation/devicetree/bindings/bus/imx-weim.txt

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240210012114.489102-3-sre at kernel.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From robh at kernel.org  Sat Feb 10 03:29:55 2024
From: robh at kernel.org (Rob Herring)
Date: Sat, 10 Feb 2024 11:29:55 +0000
Subject: [PATCH 03/22] dt-bindings: usb: Add downstream facing ports to
 realtek binding
In-Reply-To: <20240210070934.2549994-4-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
 <20240210070934.2549994-4-swboyd@chromium.org>
Message-ID: <170756458668.4188811.2636543966305409757.robh@kernel.org>


On Fri, 09 Feb 2024 23:09:14 -0800, Stephen Boyd wrote:
> Add a graph with 4 output endpoints to this hub binding to support the
> scenario where a downstream facing port is connected to a device that
> isn't a connector or a USB device with a VID:PID. This will be used to
> connect downstream facing ports to USB type-c switches so the USB
> superspeed and high speed lanes can be put onto USB connectors.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Matthias Kaehlcke <mka at chromium.org>
> Cc: <linux-usb at vger.kernel.org>
> Cc: <devicetree at vger.kernel.org>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Cc: maciek swiech <drmasquatch at google.com>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  .../bindings/usb/realtek,rts5411.yaml         | 50 +++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 

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/usb/realtek,rts5411.example.dts:32.21-31: Warning (reg_format): /example-0/usb/hub at 1/device at 2:reg: property has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
Documentation/devicetree/bindings/usb/realtek,rts5411.example.dtb: Warning (pci_device_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/usb/realtek,rts5411.example.dtb: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/usb/realtek,rts5411.example.dtb: Warning (simple_bus_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/usb/realtek,rts5411.example.dtb: Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/usb/realtek,rts5411.example.dtb: Warning (spi_bus_reg): Failed prerequisite 'reg_format'
Documentation/devicetree/bindings/usb/realtek,rts5411.example.dts:30.26-33.19: Warning (avoid_default_addr_size): /example-0/usb/hub at 1/device at 2: Relying on default #address-cells value
Documentation/devicetree/bindings/usb/realtek,rts5411.example.dts:30.26-33.19: Warning (avoid_default_addr_size): /example-0/usb/hub at 1/device at 2: Relying on default #size-cells value
Documentation/devicetree/bindings/usb/realtek,rts5411.example.dtb: Warning (unique_unit_address_if_enabled): Failed prerequisite 'avoid_default_addr_size'
Documentation/devicetree/bindings/usb/realtek,rts5411.example.dts:43.23-50.19: Warning (graph_port): /example-0/usb/hub at 2/ports: graph port node name should be 'port'
Documentation/devicetree/bindings/usb/realtek,rts5411.example.dts:46.28-49.23: Warning (graph_endpoint): /example-0/usb/hub at 2/ports/port at 0: graph endpoint node name should be 'endpoint'

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240210070934.2549994-4-swboyd at chromium.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From dmitry.baryshkov at linaro.org  Sat Feb 10 03:51:16 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 10 Feb 2024 13:51:16 +0200
Subject: [PATCH 19/22] arm64: dts: qcom: sc7180: quackingstick: Disable
 instead of delete usb_c1
In-Reply-To: <20240210070934.2549994-20-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-20-swboyd@chromium.org>
Message-ID: <CAA8EJpp2wqK3vEkU7Y3BxUKsSn11B0-X7LNF-w+sJ91bPTAVhw@mail.gmail.com>

On Sat, 10 Feb 2024 at 09:16, Stephen Boyd <swboyd at chromium.org> wrote:
>
> It's simpler to reason about things if we disable nodes instead of
> deleting them. Disable the second usb type-c connector node on
> quackingstick instead of deleting it so that we can reason about ports
> more easily.
>
> Cc: <cros-qcom-dts-watchers at chromium.org>
> Cc: Andy Gross <agross at kernel.org>
> Cc: Bjorn Andersson <andersson at kernel.org>
> Cc: Konrad Dybcio <konrad.dybcio at linaro.org>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: <linux-arm-msm at vger.kernel.org>
> Cc: <devicetree at vger.kernel.org>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  .../arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Sat Feb 10 03:51:40 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 10 Feb 2024 13:51:40 +0200
Subject: [PATCH 20/22] arm64: dts: qcom: sc7180: pazquel: Add missing
 comment header
In-Reply-To: <20240210070934.2549994-21-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-21-swboyd@chromium.org>
Message-ID: <CAA8EJpoS3+NJCMnR3HhGrh73W39ivz9O6PX3Fov_an3cY+sLLw@mail.gmail.com>

On Sat, 10 Feb 2024 at 09:16, Stephen Boyd <swboyd at chromium.org> wrote:
>
> We put a header before modifying pinctrl nodes defined in
> sc7180-trogdor.dtsi in every other file. Add one here so we know that
> this section is for pinctrl modifications.
>
> Cc: <cros-qcom-dts-watchers at chromium.org>
> Cc: Andy Gross <agross at kernel.org>
> Cc: Bjorn Andersson <andersson at kernel.org>
> Cc: Konrad Dybcio <konrad.dybcio at linaro.org>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: <linux-arm-msm at vger.kernel.org>
> Cc: <devicetree at vger.kernel.org>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>


-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Sat Feb 10 03:53:16 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 10 Feb 2024 13:53:16 +0200
Subject: [PATCH 21/22] arm64: dts: qcom: sc7180-trogdor: Make
 clamshell/detachable fragments
In-Reply-To: <20240210070934.2549994-22-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-22-swboyd@chromium.org>
Message-ID: <CAA8EJprROcMa5U0Q8fMk_aJpk6ecMoDKhtD31CCss-bHu2S+7Q@mail.gmail.com>

On Sat, 10 Feb 2024 at 09:17, Stephen Boyd <swboyd at chromium.org> wrote:
>
> At a high-level, detachable Trogdors (sometimes known as Strongbads)
> don't have a cros_ec keyboard, while all clamshell Trogdors (only known
> as Trogdors) always have a cros_ec keyboard. Looking closer though, all
> clamshells have a USB type-A connector and a hardwired USB camera. And
> all detachables replace the USB camera with a MIPI based one and swap
> the USB type-a connector for the detachable keyboard pogo pins.
>
> Split the detachable and clamshell bits into different files so we can
> describe these differences in one place instead of in each board that
> includes sc7180-trogdor.dtsi. For now this is just the keyboard part,
> but eventually this will include the type-a port and the pogo pins.
>
> Cc: <cros-qcom-dts-watchers at chromium.org>
> Cc: Andy Gross <agross at kernel.org>
> Cc: Bjorn Andersson <andersson at kernel.org>
> Cc: Konrad Dybcio <konrad.dybcio at linaro.org>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: <linux-arm-msm at vger.kernel.org>
> Cc: <devicetree at vger.kernel.org>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  .../boot/dts/qcom/sc7180-trogdor-clamshell.dtsi      |  9 +++++++++
>  arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi  |  5 +----
>  .../boot/dts/qcom/sc7180-trogdor-detachable.dtsi     | 12 ++++++++++++
>  .../arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi |  7 +------
>  .../boot/dts/qcom/sc7180-trogdor-kingoftown.dts      |  2 +-
>  arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi   |  3 +--
>  arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi |  2 +-
>  arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi  |  2 +-
>  .../boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi  |  7 +------
>  arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts       |  2 +-
>  .../boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi    |  5 +----
>  11 files changed, 30 insertions(+), 26 deletions(-)
>  create mode 100644 arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
>  create mode 100644 arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
>

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>


-- 
With best wishes
Dmitry


From eladwf at gmail.com  Sat Feb 10 03:53:28 2024
From: eladwf at gmail.com (Elad Yifee)
Date: Sat, 10 Feb 2024 13:53:28 +0200
Subject: [PATCH net-next v2] net: ethernet: mtk_eth_soc: ppe: add support for multiple PPEs
In-Reply-To: <20240130160854.5221-1-eladwf@gmail.com>
References: <20240130160854.5221-1-eladwf@gmail.com>
Message-ID: <20240210115420.27003-1-eladwf@gmail.com>

Add the missing pieces to allow multiple PPEs units, one for each GMAC.
mtk_gdm_config has been modified to work on targted mac ID,
the inner loop moved outside of the function to allow unrelated
operations like setting the MAC's PPE index.

Signed-off-by: Elad Yifee <eladwf at gmail.com>
---
v2: fixed CI warnings
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 86 +++++++++++--------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   | 15 +++-
 .../net/ethernet/mediatek/mtk_ppe_offload.c   |  6 +-
 3 files changed, 68 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index a6e91573f8da..5a50c22179af 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -2175,9 +2175,11 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
 				skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
 		}
 
-		if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-			mtk_ppe_check_skb(eth->ppe[0], skb, hash);
+		if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) {
+			unsigned int ppe_index = eth->mac[mac]->ppe_idx;
 
+			mtk_ppe_check_skb(eth->ppe[ppe_index], skb, hash);
+		}
 		skb_record_rx_queue(skb, 0);
 		napi_gro_receive(napi, skb);
 
@@ -3267,37 +3269,27 @@ static int mtk_start_dma(struct mtk_eth *eth)
 	return 0;
 }
 
-static void mtk_gdm_config(struct mtk_eth *eth, u32 config)
+static void mtk_gdm_config(struct mtk_eth *eth, u32 id, u32 config)
 {
-	int i;
+	u32 val;
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
 		return;
 
-	for (i = 0; i < MTK_MAX_DEVS; i++) {
-		u32 val;
-
-		if (!eth->netdev[i])
-			continue;
-
-		val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
+	val = mtk_r32(eth, MTK_GDMA_FWD_CFG(id));
 
-		/* default setup the forward port to send frame to PDMA */
-		val &= ~0xffff;
+	/* default setup the forward port to send frame to PDMA */
+	val &= ~0xffff;
 
-		/* Enable RX checksum */
-		val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN;
+	/* Enable RX checksum */
+	val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN;
 
-		val |= config;
+	val |= config;
 
-		if (netdev_uses_dsa(eth->netdev[i]))
-			val |= MTK_GDMA_SPECIAL_TAG;
+	if (eth->netdev[id] && netdev_uses_dsa(eth->netdev[id]))
+		val |= MTK_GDMA_SPECIAL_TAG;
 
-		mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
-	}
-	/* Reset and enable PSE */
-	mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
-	mtk_w32(eth, 0, MTK_RST_GL);
+	mtk_w32(eth, val, MTK_GDMA_FWD_CFG(id));
 }
 
 
@@ -3369,6 +3361,7 @@ static int mtk_open(struct net_device *dev)
 	/* we run 2 netdevs on the same dma ring so we only bring it up once */
 	if (!refcount_read(&eth->dma_refcnt)) {
 		const struct mtk_soc_data *soc = eth->soc;
+		const u32 ppe_num = mtk_get_ppe_num(eth);
 		u32 gdm_config;
 		int i;
 
@@ -3381,18 +3374,39 @@ static int mtk_open(struct net_device *dev)
 		for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
 			mtk_ppe_start(eth->ppe[i]);
 
-		gdm_config = soc->offload_version ? soc->reg_map->gdma_to_ppe
-						  : MTK_GDMA_TO_PDMA;
-		mtk_gdm_config(eth, gdm_config);
+		for (i = 0; i < MTK_MAX_DEVS; i++) {
+			if (!eth->netdev[i])
+				break;
+			struct mtk_mac *target_mac;
+
+			target_mac = netdev_priv(eth->netdev[i]);
+			if (!soc->offload_version) {
+				target_mac->ppe_idx = 0;
+				gdm_config = MTK_GDMA_TO_PDMA;
+			} else if (ppe_num >= 3 && target_mac->id == 2) {
+				target_mac->ppe_idx = 2;
+				gdm_config = MTK_GDMA_TO_PPE2;
+			} else if (ppe_num >= 2 && target_mac->id == 1) {
+				target_mac->ppe_idx = 1;
+				gdm_config = MTK_GDMA_TO_PPE1;
+			} else {
+				target_mac->ppe_idx = 0;
+				gdm_config = soc->reg_map->gdma_to_ppe;
+			}
+			mtk_gdm_config(eth, target_mac->id, gdm_config);
+		}
+		/* Reset and enable PSE */
+		mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
+		mtk_w32(eth, 0, MTK_RST_GL);
 
 		napi_enable(&eth->tx_napi);
 		napi_enable(&eth->rx_napi);
 		mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
 		mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask);
 		refcount_set(&eth->dma_refcnt, 1);
-	}
-	else
+	} else {
 		refcount_inc(&eth->dma_refcnt);
+	}
 
 	phylink_start(mac->phylink);
 	netif_tx_start_all_queues(dev);
@@ -3469,7 +3483,8 @@ static int mtk_stop(struct net_device *dev)
 	if (!refcount_dec_and_test(&eth->dma_refcnt))
 		return 0;
 
-	mtk_gdm_config(eth, MTK_GDMA_DROP_ALL);
+	for (i = 0; i < MTK_MAX_DEVS; i++)
+		mtk_gdm_config(eth, i, MTK_GDMA_DROP_ALL);
 
 	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
 	mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
@@ -4945,23 +4960,24 @@ static int mtk_probe(struct platform_device *pdev)
 	}
 
 	if (eth->soc->offload_version) {
-		u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1;
+		u32 num_ppe = mtk_get_ppe_num(eth);
 
 		num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
 		for (i = 0; i < num_ppe; i++) {
-			u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
+			u32 ppe_addr = eth->soc->reg_map->ppe_base;
 
+			ppe_addr += (i == 2 ? 0xC00 : i * 0x400);
 			eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
 
 			if (!eth->ppe[i]) {
 				err = -ENOMEM;
 				goto err_deinit_ppe;
 			}
-		}
+			err = mtk_eth_offload_init(eth, i);
 
-		err = mtk_eth_offload_init(eth);
-		if (err)
-			goto err_deinit_ppe;
+			if (err)
+				goto err_deinit_ppe;
+		}
 	}
 
 	for (i = 0; i < MTK_MAX_DEVS; i++) {
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 9ae3b8a71d0e..7654fa74e7fc 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -124,6 +124,8 @@
 #define MTK_GDMA_UCS_EN		BIT(20)
 #define MTK_GDMA_STRP_CRC	BIT(16)
 #define MTK_GDMA_TO_PDMA	0x0
+#define MTK_GDMA_TO_PPE1	0x4444
+#define MTK_GDMA_TO_PPE2	0xcccc
 #define MTK_GDMA_DROP_ALL       0x7777
 
 /* GDM Egress Control Register */
@@ -1286,7 +1288,7 @@ struct mtk_eth {
 
 	struct metadata_dst		*dsa_meta[MTK_MAX_DSA_PORTS];
 
-	struct mtk_ppe			*ppe[2];
+	struct mtk_ppe			*ppe[3];
 	struct rhashtable		flow_table;
 
 	struct bpf_prog			__rcu *prog;
@@ -1311,6 +1313,7 @@ struct mtk_eth {
 struct mtk_mac {
 	int				id;
 	phy_interface_t			interface;
+	unsigned int			ppe_idx;
 	int				speed;
 	struct device_node		*of_node;
 	struct phylink			*phylink;
@@ -1421,6 +1424,14 @@ static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
 	return MTK_FOE_IB2_MULTICAST;
 }
 
+static inline u32 mtk_get_ppe_num(struct mtk_eth *eth)
+{
+	if (!eth->soc->offload_version)
+		return 0;
+
+	return eth->soc->version;
+}
+
 /* read the hardware status register */
 void mtk_stats_update_mac(struct mtk_mac *mac);
 
@@ -1432,7 +1443,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
 
-int mtk_eth_offload_init(struct mtk_eth *eth);
+int mtk_eth_offload_init(struct mtk_eth *eth, int id);
 int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
 		     void *type_data);
 int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls,
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
index fbb5e9d5af13..220685f6daaa 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
@@ -570,7 +570,7 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_pri
 	if (type != TC_SETUP_CLSFLOWER)
 		return -EOPNOTSUPP;
 
-	return mtk_flow_offload_cmd(eth, cls, 0);
+	return mtk_flow_offload_cmd(eth, cls, mac->ppe_idx);
 }
 
 static int
@@ -633,7 +633,9 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
 	}
 }
 
-int mtk_eth_offload_init(struct mtk_eth *eth)
+int mtk_eth_offload_init(struct mtk_eth *eth, int id)
 {
+	if (!eth->ppe[id] || !eth->ppe[id]->foe_table)
+		return 0;
 	return rhashtable_init(&eth->flow_table, &mtk_flow_ht_params);
 }
-- 
2.43.0



From broonie at kernel.org  Sat Feb 10 04:28:41 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 10 Feb 2024 12:28:41 +0000
Subject: [PATCH v1 03/14] dt-bindings: sound: fsl,imx-asrc: convert to
 YAML
In-Reply-To: <20240210012114.489102-4-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-4-sre@kernel.org>
Message-ID: <Zcdr+fMEpxNiqxQN@finisterre.sirena.org.uk>

On Sat, Feb 10, 2024 at 02:18:07AM +0100, Sebastian Reichel wrote:
> Convert the i.MX ASRC DT binding to YAML.

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/20240210/2b2405ad/attachment.sig>

From daniel at makrotopia.org  Sat Feb 10 04:34:55 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sat, 10 Feb 2024 12:34:55 +0000
Subject: [PATCH net-next v2] net: ethernet: mtk_eth_soc: ppe: add support
 for multiple PPEs
In-Reply-To: <20240210115420.27003-1-eladwf@gmail.com>
References: <20240130160854.5221-1-eladwf@gmail.com>
 <20240210115420.27003-1-eladwf@gmail.com>
Message-ID: <Zcdtb-eyvxzX9yPe@makrotopia.org>

Hi Elad,

Given that this is what we want to do (assign each PPE to one of the
Ethernet MACs) the patch looks good in general, some minor details
in-line below.

On Sat, Feb 10, 2024 at 01:53:28PM +0200, Elad Yifee wrote:
> Add the missing pieces to allow multiple PPEs units, one for each GMAC.
> mtk_gdm_config has been modified to work on targted mac ID,
> the inner loop moved outside of the function to allow unrelated
> operations like setting the MAC's PPE index.
> 
> Signed-off-by: Elad Yifee <eladwf at gmail.com>
> ---
> v2: fixed CI warnings
> ---
>  drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 86 +++++++++++--------
>  drivers/net/ethernet/mediatek/mtk_eth_soc.h   | 15 +++-
>  .../net/ethernet/mediatek/mtk_ppe_offload.c   |  6 +-
>  3 files changed, 68 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> index a6e91573f8da..5a50c22179af 100644
> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> @@ -2175,9 +2175,11 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
>  				skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
>  		}
>  
> -		if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
> -			mtk_ppe_check_skb(eth->ppe[0], skb, hash);
> +		if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) {
> +			unsigned int ppe_index = eth->mac[mac]->ppe_idx;

Variable declarations should only be at the top of the function.

>  
> +			mtk_ppe_check_skb(eth->ppe[ppe_index], skb, hash);
> +		}
>  		skb_record_rx_queue(skb, 0);
>  		napi_gro_receive(napi, skb);
>  
> @@ -3267,37 +3269,27 @@ static int mtk_start_dma(struct mtk_eth *eth)
>  	return 0;
>  }
>  
> -static void mtk_gdm_config(struct mtk_eth *eth, u32 config)
> +static void mtk_gdm_config(struct mtk_eth *eth, u32 id, u32 config)
>  {
> -	int i;
> +	u32 val;
>  
>  	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
>  		return;
>  
> -	for (i = 0; i < MTK_MAX_DEVS; i++) {
> -		u32 val;
> -
> -		if (!eth->netdev[i])
> -			continue;
> -
> -		val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
> +	val = mtk_r32(eth, MTK_GDMA_FWD_CFG(id));
>  
> -		/* default setup the forward port to send frame to PDMA */
> -		val &= ~0xffff;
> +	/* default setup the forward port to send frame to PDMA */
> +	val &= ~0xffff;
>  
> -		/* Enable RX checksum */
> -		val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN;
> +	/* Enable RX checksum */
> +	val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN;
>  
> -		val |= config;
> +	val |= config;
>  
> -		if (netdev_uses_dsa(eth->netdev[i]))
> -			val |= MTK_GDMA_SPECIAL_TAG;
> +	if (eth->netdev[id] && netdev_uses_dsa(eth->netdev[id]))
> +		val |= MTK_GDMA_SPECIAL_TAG;
>  
> -		mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
> -	}
> -	/* Reset and enable PSE */
> -	mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
> -	mtk_w32(eth, 0, MTK_RST_GL);
> +	mtk_w32(eth, val, MTK_GDMA_FWD_CFG(id));
>  }
>  
>  
> @@ -3369,6 +3361,7 @@ static int mtk_open(struct net_device *dev)
>  	/* we run 2 netdevs on the same dma ring so we only bring it up once */
>  	if (!refcount_read(&eth->dma_refcnt)) {
>  		const struct mtk_soc_data *soc = eth->soc;
> +		const u32 ppe_num = mtk_get_ppe_num(eth);
>  		u32 gdm_config;
>  		int i;
>  
> @@ -3381,18 +3374,39 @@ static int mtk_open(struct net_device *dev)
>  		for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
>  			mtk_ppe_start(eth->ppe[i]);
>  
> -		gdm_config = soc->offload_version ? soc->reg_map->gdma_to_ppe
> -						  : MTK_GDMA_TO_PDMA;
> -		mtk_gdm_config(eth, gdm_config);
> +		for (i = 0; i < MTK_MAX_DEVS; i++) {
> +			if (!eth->netdev[i])
> +				break;
> +			struct mtk_mac *target_mac;
> +
> +			target_mac = netdev_priv(eth->netdev[i]);
> +			if (!soc->offload_version) {
> +				target_mac->ppe_idx = 0;
> +				gdm_config = MTK_GDMA_TO_PDMA;
> +			} else if (ppe_num >= 3 && target_mac->id == 2) {
> +				target_mac->ppe_idx = 2;
> +				gdm_config = MTK_GDMA_TO_PPE2;
> +			} else if (ppe_num >= 2 && target_mac->id == 1) {
> +				target_mac->ppe_idx = 1;
> +				gdm_config = MTK_GDMA_TO_PPE1;
> +			} else {
> +				target_mac->ppe_idx = 0;
> +				gdm_config = soc->reg_map->gdma_to_ppe;
> +			}
> +			mtk_gdm_config(eth, target_mac->id, gdm_config);
> +		}
> +		/* Reset and enable PSE */
> +		mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
> +		mtk_w32(eth, 0, MTK_RST_GL);
>  
>  		napi_enable(&eth->tx_napi);
>  		napi_enable(&eth->rx_napi);
>  		mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
>  		mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask);
>  		refcount_set(&eth->dma_refcnt, 1);
> -	}
> -	else
> +	} else {
>  		refcount_inc(&eth->dma_refcnt);
> +	}
>  
>  	phylink_start(mac->phylink);
>  	netif_tx_start_all_queues(dev);
> @@ -3469,7 +3483,8 @@ static int mtk_stop(struct net_device *dev)
>  	if (!refcount_dec_and_test(&eth->dma_refcnt))
>  		return 0;
>  
> -	mtk_gdm_config(eth, MTK_GDMA_DROP_ALL);
> +	for (i = 0; i < MTK_MAX_DEVS; i++)
> +		mtk_gdm_config(eth, i, MTK_GDMA_DROP_ALL);
>  
>  	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
>  	mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
> @@ -4945,23 +4960,24 @@ static int mtk_probe(struct platform_device *pdev)
>  	}
>  
>  	if (eth->soc->offload_version) {
> -		u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1;
> +		u32 num_ppe = mtk_get_ppe_num(eth);
>  
>  		num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
>  		for (i = 0; i < num_ppe; i++) {
> -			u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
> +			u32 ppe_addr = eth->soc->reg_map->ppe_base;
>  
> +			ppe_addr += (i == 2 ? 0xC00 : i * 0x400);

Hex numbers in all small letter please.

>  			eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
>  
>  			if (!eth->ppe[i]) {
>  				err = -ENOMEM;
>  				goto err_deinit_ppe;
>  			}
> -		}
> +			err = mtk_eth_offload_init(eth, i);
>  
> -		err = mtk_eth_offload_init(eth);
> -		if (err)
> -			goto err_deinit_ppe;
> +			if (err)
> +				goto err_deinit_ppe;
> +		}
>  	}
>  
>  	for (i = 0; i < MTK_MAX_DEVS; i++) {
> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> index 9ae3b8a71d0e..7654fa74e7fc 100644
> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> @@ -124,6 +124,8 @@
>  #define MTK_GDMA_UCS_EN		BIT(20)
>  #define MTK_GDMA_STRP_CRC	BIT(16)
>  #define MTK_GDMA_TO_PDMA	0x0
> +#define MTK_GDMA_TO_PPE1	0x4444
> +#define MTK_GDMA_TO_PPE2	0xcccc
>  #define MTK_GDMA_DROP_ALL       0x7777
>  
>  /* GDM Egress Control Register */
> @@ -1286,7 +1288,7 @@ struct mtk_eth {
>  
>  	struct metadata_dst		*dsa_meta[MTK_MAX_DSA_PORTS];
>  
> -	struct mtk_ppe			*ppe[2];
> +	struct mtk_ppe			*ppe[3];
>  	struct rhashtable		flow_table;
>  
>  	struct bpf_prog			__rcu *prog;
> @@ -1311,6 +1313,7 @@ struct mtk_eth {
>  struct mtk_mac {
>  	int				id;
>  	phy_interface_t			interface;
> +	unsigned int			ppe_idx;

u8 would be large enough.

>  	int				speed;
>  	struct device_node		*of_node;
>  	struct phylink			*phylink;
> @@ -1421,6 +1424,14 @@ static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
>  	return MTK_FOE_IB2_MULTICAST;
>  }
>  
> +static inline u32 mtk_get_ppe_num(struct mtk_eth *eth)
> +{
> +	if (!eth->soc->offload_version)
> +		return 0;
> +
> +	return eth->soc->version;
> +}
> +
>  /* read the hardware status register */
>  void mtk_stats_update_mac(struct mtk_mac *mac);
>  
> @@ -1432,7 +1443,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
>  int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
>  int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
>  
> -int mtk_eth_offload_init(struct mtk_eth *eth);
> +int mtk_eth_offload_init(struct mtk_eth *eth, int id);
>  int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
>  		     void *type_data);
>  int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls,
> diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
> index fbb5e9d5af13..220685f6daaa 100644
> --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
> +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
> @@ -570,7 +570,7 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_pri
>  	if (type != TC_SETUP_CLSFLOWER)
>  		return -EOPNOTSUPP;
>  
> -	return mtk_flow_offload_cmd(eth, cls, 0);
> +	return mtk_flow_offload_cmd(eth, cls, mac->ppe_idx);
>  }
>  
>  static int
> @@ -633,7 +633,9 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
>  	}
>  }
>  
> -int mtk_eth_offload_init(struct mtk_eth *eth)
> +int mtk_eth_offload_init(struct mtk_eth *eth, int id)
>  {
> +	if (!eth->ppe[id] || !eth->ppe[id]->foe_table)
> +		return 0;
>  	return rhashtable_init(&eth->flow_table, &mtk_flow_ht_params);
>  }
> -- 
> 2.43.0
> 
> 


From eladwf at gmail.com  Sat Feb 10 05:56:07 2024
From: eladwf at gmail.com (Elad Yifee)
Date: Sat, 10 Feb 2024 15:56:07 +0200
Subject: [PATCH net-next v3] net: ethernet: mtk_eth_soc: ppe: add support for multiple PPEs
In-Reply-To: <Zcdtb-eyvxzX9yPe@makrotopia.org>
References: <Zcdtb-eyvxzX9yPe@makrotopia.org>
Message-ID: <20240210135620.28368-1-eladwf@gmail.com>

Add the missing pieces to allow multiple PPEs units, one for each GMAC.
mtk_gdm_config has been modified to work on targted mac ID,
the inner loop moved outside of the function to allow unrelated
operations like setting the MAC's PPE index.

Signed-off-by: Elad Yifee <eladwf at gmail.com>
---
v3: applied changes suggested by Daniel Golle
v2: fixed CI warnings
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 86 +++++++++++--------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   | 15 +++-
 .../net/ethernet/mediatek/mtk_ppe_offload.c   |  6 +-
 3 files changed, 68 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index a6e91573f8da..5d5cf73a5d5a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -2010,6 +2010,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
 	struct mtk_rx_dma_v2 *rxd, trxd;
 	int done = 0, bytes = 0;
 	dma_addr_t dma_addr = DMA_MAPPING_ERROR;
+	u8 ppe_index = 0;
 
 	while (done < budget) {
 		unsigned int pktlen, *rxdcsum;
@@ -2053,6 +2054,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
 			goto release_desc;
 
 		netdev = eth->netdev[mac];
+		ppe_index = eth->mac[mac]->ppe_idx;
 
 		if (unlikely(test_bit(MTK_RESETTING, &eth->state)))
 			goto release_desc;
@@ -2176,7 +2178,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
 		}
 
 		if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-			mtk_ppe_check_skb(eth->ppe[0], skb, hash);
+			mtk_ppe_check_skb(eth->ppe[ppe_index], skb, hash);
 
 		skb_record_rx_queue(skb, 0);
 		napi_gro_receive(napi, skb);
@@ -3267,37 +3269,27 @@ static int mtk_start_dma(struct mtk_eth *eth)
 	return 0;
 }
 
-static void mtk_gdm_config(struct mtk_eth *eth, u32 config)
+static void mtk_gdm_config(struct mtk_eth *eth, u32 id, u32 config)
 {
-	int i;
+	u32 val;
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
 		return;
 
-	for (i = 0; i < MTK_MAX_DEVS; i++) {
-		u32 val;
-
-		if (!eth->netdev[i])
-			continue;
-
-		val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
+	val = mtk_r32(eth, MTK_GDMA_FWD_CFG(id));
 
-		/* default setup the forward port to send frame to PDMA */
-		val &= ~0xffff;
+	/* default setup the forward port to send frame to PDMA */
+	val &= ~0xffff;
 
-		/* Enable RX checksum */
-		val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN;
+	/* Enable RX checksum */
+	val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN;
 
-		val |= config;
+	val |= config;
 
-		if (netdev_uses_dsa(eth->netdev[i]))
-			val |= MTK_GDMA_SPECIAL_TAG;
+	if (eth->netdev[id] && netdev_uses_dsa(eth->netdev[id]))
+		val |= MTK_GDMA_SPECIAL_TAG;
 
-		mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
-	}
-	/* Reset and enable PSE */
-	mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
-	mtk_w32(eth, 0, MTK_RST_GL);
+	mtk_w32(eth, val, MTK_GDMA_FWD_CFG(id));
 }
 
 
@@ -3358,6 +3350,8 @@ static int mtk_open(struct net_device *dev)
 	struct mtk_mac *mac = netdev_priv(dev);
 	struct mtk_eth *eth = mac->hw;
 	int i, err;
+	struct mtk_mac *target_mac;
+	const u8 ppe_num = mtk_get_ppe_num(eth);
 
 	err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
 	if (err) {
@@ -3381,18 +3375,38 @@ static int mtk_open(struct net_device *dev)
 		for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
 			mtk_ppe_start(eth->ppe[i]);
 
-		gdm_config = soc->offload_version ? soc->reg_map->gdma_to_ppe
-						  : MTK_GDMA_TO_PDMA;
-		mtk_gdm_config(eth, gdm_config);
+		for (i = 0; i < MTK_MAX_DEVS; i++) {
+			if (!eth->netdev[i])
+				break;
+
+			target_mac = netdev_priv(eth->netdev[i]);
+			if (!soc->offload_version) {
+				target_mac->ppe_idx = 0;
+				gdm_config = MTK_GDMA_TO_PDMA;
+			} else if (ppe_num >= 3 && target_mac->id == 2) {
+				target_mac->ppe_idx = 2;
+				gdm_config = MTK_GDMA_TO_PPE2;
+			} else if (ppe_num >= 2 && target_mac->id == 1) {
+				target_mac->ppe_idx = 1;
+				gdm_config = MTK_GDMA_TO_PPE1;
+			} else {
+				target_mac->ppe_idx = 0;
+				gdm_config = soc->reg_map->gdma_to_ppe;
+			}
+			mtk_gdm_config(eth, target_mac->id, gdm_config);
+		}
+		/* Reset and enable PSE */
+		mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
+		mtk_w32(eth, 0, MTK_RST_GL);
 
 		napi_enable(&eth->tx_napi);
 		napi_enable(&eth->rx_napi);
 		mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
 		mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask);
 		refcount_set(&eth->dma_refcnt, 1);
-	}
-	else
+	} else {
 		refcount_inc(&eth->dma_refcnt);
+	}
 
 	phylink_start(mac->phylink);
 	netif_tx_start_all_queues(dev);
@@ -3469,7 +3483,8 @@ static int mtk_stop(struct net_device *dev)
 	if (!refcount_dec_and_test(&eth->dma_refcnt))
 		return 0;
 
-	mtk_gdm_config(eth, MTK_GDMA_DROP_ALL);
+	for (i = 0; i < MTK_MAX_DEVS; i++)
+		mtk_gdm_config(eth, i, MTK_GDMA_DROP_ALL);
 
 	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
 	mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
@@ -4945,23 +4960,24 @@ static int mtk_probe(struct platform_device *pdev)
 	}
 
 	if (eth->soc->offload_version) {
-		u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1;
+		u8 num_ppe = mtk_get_ppe_num(eth);
 
-		num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
+		num_ppe = min_t(u8, ARRAY_SIZE(eth->ppe), num_ppe);
 		for (i = 0; i < num_ppe; i++) {
-			u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
+			u32 ppe_addr = eth->soc->reg_map->ppe_base;
 
+			ppe_addr += (i == 2 ? 0xc00 : i * 0x400);
 			eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
 
 			if (!eth->ppe[i]) {
 				err = -ENOMEM;
 				goto err_deinit_ppe;
 			}
-		}
+			err = mtk_eth_offload_init(eth, i);
 
-		err = mtk_eth_offload_init(eth);
-		if (err)
-			goto err_deinit_ppe;
+			if (err)
+				goto err_deinit_ppe;
+		}
 	}
 
 	for (i = 0; i < MTK_MAX_DEVS; i++) {
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 9ae3b8a71d0e..9ff0d6951688 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -124,6 +124,8 @@
 #define MTK_GDMA_UCS_EN		BIT(20)
 #define MTK_GDMA_STRP_CRC	BIT(16)
 #define MTK_GDMA_TO_PDMA	0x0
+#define MTK_GDMA_TO_PPE1	0x4444
+#define MTK_GDMA_TO_PPE2	0xcccc
 #define MTK_GDMA_DROP_ALL       0x7777
 
 /* GDM Egress Control Register */
@@ -1286,7 +1288,7 @@ struct mtk_eth {
 
 	struct metadata_dst		*dsa_meta[MTK_MAX_DSA_PORTS];
 
-	struct mtk_ppe			*ppe[2];
+	struct mtk_ppe			*ppe[3];
 	struct rhashtable		flow_table;
 
 	struct bpf_prog			__rcu *prog;
@@ -1311,6 +1313,7 @@ struct mtk_eth {
 struct mtk_mac {
 	int				id;
 	phy_interface_t			interface;
+	u8			ppe_idx;
 	int				speed;
 	struct device_node		*of_node;
 	struct phylink			*phylink;
@@ -1421,6 +1424,14 @@ static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
 	return MTK_FOE_IB2_MULTICAST;
 }
 
+static inline u8 mtk_get_ppe_num(struct mtk_eth *eth)
+{
+	if (!eth->soc->offload_version)
+		return 0;
+
+	return eth->soc->version;
+}
+
 /* read the hardware status register */
 void mtk_stats_update_mac(struct mtk_mac *mac);
 
@@ -1432,7 +1443,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
 
-int mtk_eth_offload_init(struct mtk_eth *eth);
+int mtk_eth_offload_init(struct mtk_eth *eth, u8 id);
 int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
 		     void *type_data);
 int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls,
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
index fbb5e9d5af13..1079c20bc049 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
@@ -570,7 +570,7 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_pri
 	if (type != TC_SETUP_CLSFLOWER)
 		return -EOPNOTSUPP;
 
-	return mtk_flow_offload_cmd(eth, cls, 0);
+	return mtk_flow_offload_cmd(eth, cls, mac->ppe_idx);
 }
 
 static int
@@ -633,7 +633,9 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
 	}
 }
 
-int mtk_eth_offload_init(struct mtk_eth *eth)
+int mtk_eth_offload_init(struct mtk_eth *eth, u8 id)
 {
+	if (!eth->ppe[id] || !eth->ppe[id]->foe_table)
+		return 0;
 	return rhashtable_init(&eth->flow_table, &mtk_flow_ht_params);
 }
-- 
2.43.0



From dmitry.baryshkov at linaro.org  Sat Feb 10 06:10:31 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 10 Feb 2024 16:10:31 +0200
Subject: [PATCH 14/22] platform/chrome: cros_typec_switch: Add support for
 signaling HPD to drm_bridge
In-Reply-To: <20240210070934.2549994-15-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-15-swboyd@chromium.org>
Message-ID: <CAA8EJpo1g9QKq1skibqSj9yc3mNSfkcts9oVf_vGjVjDzVZwiA@mail.gmail.com>

On Sat, 10 Feb 2024 at 09:14, Stephen Boyd <swboyd at chromium.org> wrote:
>
> We can imagine that logically the EC is a device that has some number of
> DisplayPort (DP) connector inputs, some number of USB3 connector inputs,
> and some number of USB type-c connector outputs. If you squint enough it
> looks like a USB type-c dock. Logically there's a crossbar pin
> assignment capability within the EC that can assign USB and DP lanes to
> USB type-c lanes in the connector (i.e. USB type-c pin configurations).
> In reality, the EC is a microcontroller that has some TCPCs and
> redrivers connected to it over something like i2c and DP/USB from the AP
> is wired directly to those ICs, not the EC.
>
> This design allows the EC to abstract many possible USB and DP hardware
> configurations away from the AP (kernel) so that the AP can largely deal
> with USB and DP without thinking about USB Type-C much at all. The DP
> and USB data originate in the AP, not the EC, so it helps to think that
> the EC takes the DP and USB data as input to mux onto USB type-c ports
> even if it really doesn't do that. With this split design, the EC
> forwards the DP HPD state to the AP via a GPIO that's connected to the
> DP phy.
>
> Having that HPD state signaled directly to the DP phy uses precious
> hardware resources, a GPIO or two and a wire, and it also forces the
> TCPM to live on the EC. If we want to save costs and move more control
> of USB type-c to the kernel it's in our interest to get rid of the HPD
> GPIO entirely and signal HPD to the DP phy some other way. Luckily, the
> EC already exposes information about the USB Type-C stack to the kernel
> via the host command interface in the "google,cros-ec-typec" compatible
> driver, which parses EC messages related to USB type-c and effectively
> "replays" those messages to the kernel's USB typec subsystem. This
> includes the state of HPD, which can be interrogated and acted upon by
> registering a 'struct typec_mux_dev' with the typec subsystem.
>
> On DT based systems, the DP display pipeline is abstracted via a 'struct
> drm_bridge'. If we want to signal HPD state within the kernel we need to
> hook into the drm_bridge framework somehow to call
> drm_bridge_hpd_notify() when HPD state changes in the typec framework.
> Make a drm_bridge in the EC that attaches onto the end of the DP bridge
> chain and logically moves the display data onto a usb-c-connector.
> Signal HPD when the typec HPD state changes, as long as this new
> drm_bridge is the one that's supposed to signal HPD. Do that by
> registering a 'struct typec_mux_dev' with the typec framework and
> associating that struct with a usb-c-connector node and a drm_bridge.
>
> To keep this patch minimal, just signal HPD state to the drm_bridge
> chain. Later patches will add more features. Eventually we'll be able to
> inform userspace about which usb-c-connector node is displaying DP and
> what USB devices are connected to a connector. Note that this code is
> placed in the cros_typec_switch driver because that's where mode-switch
> devices on the EC are controlled by the AP. Logically this drm_bridge
> sits in front of the mode-switch on the EC, and if there is anything to
> control on the EC the 'EC_FEATURE_TYPEC_AP_MUX_SET' feature will be set.
>
> Cc: Prashant Malani <pmalani at chromium.org>
> Cc: Benson Leung <bleung at chromium.org>
> Cc: Tzung-Bi Shih <tzungbi at kernel.org>
> Cc: <chrome-platform at lists.linux.dev>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  drivers/platform/chrome/Kconfig             |   3 +-
>  drivers/platform/chrome/cros_typec_switch.c | 218 ++++++++++++++++++--
>  2 files changed, 204 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
> index 7a83346bfa53..910aa8be9c84 100644
> --- a/drivers/platform/chrome/Kconfig
> +++ b/drivers/platform/chrome/Kconfig
> @@ -287,7 +287,8 @@ config CHROMEOS_PRIVACY_SCREEN
>
>  config CROS_TYPEC_SWITCH
>         tristate "ChromeOS EC Type-C Switch Control"
> -       depends on MFD_CROS_EC_DEV && TYPEC && ACPI
> +       depends on MFD_CROS_EC_DEV
> +       depends on TYPEC
>         default MFD_CROS_EC_DEV
>         help
>           If you say Y here, you get support for configuring the ChromeOS EC Type-C
> diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
> index 769de2889f2f..d8fb6662cf8d 100644
> --- a/drivers/platform/chrome/cros_typec_switch.c
> +++ b/drivers/platform/chrome/cros_typec_switch.c
> @@ -10,6 +10,7 @@
>  #include <linux/delay.h>
>  #include <linux/iopoll.h>
>  #include <linux/module.h>
> +#include <linux/of.h>
>  #include <linux/platform_data/cros_ec_commands.h>
>  #include <linux/platform_data/cros_ec_proto.h>
>  #include <linux/platform_device.h>
> @@ -18,6 +19,15 @@
>  #include <linux/usb/typec_mux.h>
>  #include <linux/usb/typec_retimer.h>
>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_print.h>
> +
> +struct cros_typec_dp_bridge {
> +       struct cros_typec_switch_data *sdata;
> +       bool hpd_enabled;
> +       struct drm_bridge bridge;
> +};

Is there any chance that you can use drm_dp_hpd_bridge_register() /
drm_aux_hpd_bridge_notify() instead of implementing another
drm_bridge?
If something is missing from the existing implementation we can
probably work that out.

> +
>  /* Handles and other relevant data required for each port's switches. */
>  struct cros_typec_port {
>         int port_num;
> @@ -30,7 +40,9 @@ struct cros_typec_port {
>  struct cros_typec_switch_data {
>         struct device *dev;
>         struct cros_ec_device *ec;
> +       bool typec_cmd_supported;
>         struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
> +       struct cros_typec_dp_bridge *typec_dp_bridge;
>  };
>
>  static int cros_typec_cmd_mux_set(struct cros_typec_switch_data *sdata, int port_num, u8 index,
> @@ -143,13 +155,60 @@ static int cros_typec_configure_mux(struct cros_typec_switch_data *sdata, int po
>         return 0;
>  }
>
> +static int cros_typec_dp_port_switch_set(struct typec_mux_dev *mode_switch,
> +                                        struct typec_mux_state *state)
> +{
> +       struct cros_typec_port *port;
> +       const struct typec_displayport_data *dp_data;
> +       struct cros_typec_dp_bridge *typec_dp_bridge;
> +       struct drm_bridge *bridge;
> +       bool hpd_asserted;
> +
> +       port = typec_mux_get_drvdata(mode_switch);
> +       typec_dp_bridge = port->sdata->typec_dp_bridge;
> +       if (!typec_dp_bridge)
> +               return 0;
> +
> +       bridge = &typec_dp_bridge->bridge;
> +
> +       if (state->mode == TYPEC_STATE_SAFE || state->mode == TYPEC_STATE_USB) {
> +               if (typec_dp_bridge->hpd_enabled)
> +                       drm_bridge_hpd_notify(bridge, connector_status_disconnected);
> +
> +               return 0;
> +       }
> +
> +       if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) {
> +               if (typec_dp_bridge->hpd_enabled) {
> +                       dp_data = state->data;
> +                       hpd_asserted = dp_data->status & DP_STATUS_HPD_STATE;
> +
> +                       if (hpd_asserted)
> +                               drm_bridge_hpd_notify(bridge, connector_status_connected);
> +                       else
> +                               drm_bridge_hpd_notify(bridge, connector_status_disconnected);
> +               }
> +       }
> +
> +       return 0;
> +}
> +
>  static int cros_typec_mode_switch_set(struct typec_mux_dev *mode_switch,
>                                       struct typec_mux_state *state)
>  {
>         struct cros_typec_port *port = typec_mux_get_drvdata(mode_switch);
> +       struct cros_typec_switch_data *sdata = port->sdata;
> +       int ret;
> +
> +       ret = cros_typec_dp_port_switch_set(mode_switch, state);
> +       if (ret)
> +               return ret;
>
>         /* Mode switches have index 0. */
> -       return cros_typec_configure_mux(port->sdata, port->port_num, 0, state->mode, state->alt);
> +       if (sdata->typec_cmd_supported)
> +               return cros_typec_configure_mux(port->sdata, port->port_num, 0, state->mode, state->alt);
> +
> +       return 0;
>  }
>
>  static int cros_typec_retimer_set(struct typec_retimer *retimer, struct typec_retimer_state *state)
> @@ -201,12 +260,77 @@ static int cros_typec_register_retimer(struct cros_typec_port *port, struct fwno
>         return PTR_ERR_OR_ZERO(port->retimer);
>  }
>
> +static int
> +cros_typec_dp_bridge_attach(struct drm_bridge *bridge,
> +                           enum drm_bridge_attach_flags flags)
> +{
> +       if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
> +               DRM_ERROR("Fix bridge driver to make connector optional!\n");
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static struct cros_typec_dp_bridge *
> +bridge_to_cros_typec_dp_bridge(struct drm_bridge *bridge)
> +{
> +       return container_of(bridge, struct cros_typec_dp_bridge, bridge);
> +}
> +
> +static void cros_typec_dp_bridge_hpd_enable(struct drm_bridge *bridge)
> +{
> +       struct cros_typec_dp_bridge *typec_dp_bridge;
> +
> +       typec_dp_bridge = bridge_to_cros_typec_dp_bridge(bridge);
> +       typec_dp_bridge->hpd_enabled = true;
> +}
> +
> +static void cros_typec_dp_bridge_hpd_disable(struct drm_bridge *bridge)
> +{
> +       struct cros_typec_dp_bridge *typec_dp_bridge;
> +
> +       typec_dp_bridge = bridge_to_cros_typec_dp_bridge(bridge);
> +       typec_dp_bridge->hpd_enabled = false;
> +}
> +
> +static const struct drm_bridge_funcs cros_typec_dp_bridge_funcs = {
> +       .attach = cros_typec_dp_bridge_attach,
> +       .hpd_enable = cros_typec_dp_bridge_hpd_enable,
> +       .hpd_disable = cros_typec_dp_bridge_hpd_disable,
> +};
> +
> +static int cros_typec_register_dp_bridge(struct cros_typec_switch_data *sdata,
> +                                        struct fwnode_handle *fwnode)
> +{
> +       struct cros_typec_dp_bridge *typec_dp_bridge;
> +       struct drm_bridge *bridge;
> +       struct device *dev = sdata->dev;
> +
> +       typec_dp_bridge = devm_kzalloc(dev, sizeof(*typec_dp_bridge), GFP_KERNEL);
> +       if (!typec_dp_bridge)
> +               return -ENOMEM;
> +
> +       typec_dp_bridge->sdata = sdata;
> +       sdata->typec_dp_bridge = typec_dp_bridge;
> +       bridge = &typec_dp_bridge->bridge;
> +
> +       bridge->funcs = &cros_typec_dp_bridge_funcs;
> +       bridge->of_node = dev->of_node;
> +       bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
> +       bridge->ops |= DRM_BRIDGE_OP_HPD;
> +
> +       return devm_drm_bridge_add(dev, bridge);
> +}
> +
>  static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
>                                     struct fwnode_handle *fwnode)
>  {
>         struct cros_typec_port *port;
>         struct device *dev = sdata->dev;
>         struct acpi_device *adev;
> +       struct device_node *np;
> +       struct fwnode_handle *port_node;
>         u32 index;
>         int ret;
>         const char *prop_name;
> @@ -218,9 +342,12 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
>         adev = to_acpi_device_node(fwnode);
>         if (adev)
>                 prop_name = "_ADR";
> +       np = to_of_node(fwnode);
> +       if (np)
> +               prop_name = "reg";
>
> -       if (!adev)
> -               return dev_err_probe(fwnode->dev, -ENODEV, "Couldn't get ACPI handle\n");
> +       if (!adev && !np)
> +               return dev_err_probe(fwnode->dev, -ENODEV, "Couldn't get ACPI/OF device handle\n");
>
>         ret = fwnode_property_read_u32(fwnode, prop_name, &index);
>         if (ret)
> @@ -232,41 +359,84 @@ static int cros_typec_register_port(struct cros_typec_switch_data *sdata,
>         port->port_num = index;
>         sdata->ports[index] = port;
>
> +       port_node = fwnode;
> +       if (np)
> +               fwnode = fwnode_graph_get_port_parent(fwnode);
> +
>         if (fwnode_property_present(fwnode, "retimer-switch")) {
> -               ret = cros_typec_register_retimer(port, fwnode);
> -               if (ret)
> -                       return dev_err_probe(dev, ret, "Retimer switch register failed\n");
> +               ret = cros_typec_register_retimer(port, port_node);
> +               if (ret) {
> +                       dev_err_probe(dev, ret, "Retimer switch register failed\n");
> +                       goto out;
> +               }
>
>                 dev_dbg(dev, "Retimer switch registered for index %u\n", index);
>         }
>
> -       if (!fwnode_property_present(fwnode, "mode-switch"))
> -               return 0;
> +       if (fwnode_property_present(fwnode, "mode-switch")) {
> +               ret = cros_typec_register_mode_switch(port, port_node);
> +               if (ret) {
> +                       dev_err_probe(dev, ret, "Mode switch register failed\n");
> +                       goto out;
> +               }
>
> -       ret = cros_typec_register_mode_switch(port, fwnode);
> -       if (ret)
> -               return dev_err_probe(dev, ret, "Mode switch register failed\n");
> +               dev_dbg(dev, "Mode switch registered for index %u\n", index);
> +       }
>
> -       dev_dbg(dev, "Mode switch registered for index %u\n", index);
>
> +out:
> +       if (np)
> +               fwnode_handle_put(fwnode);
>         return ret;
>  }
>
>  static int cros_typec_register_switches(struct cros_typec_switch_data *sdata)
>  {
>         struct device *dev = sdata->dev;
> +       struct fwnode_handle *devnode;
>         struct fwnode_handle *fwnode;
> +       struct fwnode_endpoint endpoint;
>         int nports, ret;
>
>         nports = device_get_child_node_count(dev);
>         if (nports == 0)
>                 return dev_err_probe(dev, -ENODEV, "No switch devices found\n");
>
> -       device_for_each_child_node(dev, fwnode) {
> -               ret = cros_typec_register_port(sdata, fwnode);
> -               if (ret) {
> +       devnode = dev_fwnode(dev);
> +       if (fwnode_graph_get_endpoint_count(devnode, 0)) {
> +               fwnode_graph_for_each_endpoint(devnode, fwnode) {
> +                       ret = fwnode_graph_parse_endpoint(fwnode, &endpoint);
> +                       if (ret) {
> +                               fwnode_handle_put(fwnode);
> +                               goto err;
> +                       }
> +                       /* Skip if not a type-c output port */
> +                       if (endpoint.port != 2)
> +                               continue;
> +
> +                       ret = cros_typec_register_port(sdata, fwnode);
> +                       if (ret) {
> +                               fwnode_handle_put(fwnode);
> +                               goto err;
> +                       }
> +               }
> +       } else {
> +               device_for_each_child_node(dev, fwnode) {
> +                       ret = cros_typec_register_port(sdata, fwnode);
> +                       if (ret) {
> +                               fwnode_handle_put(fwnode);
> +                               goto err;
> +                       }
> +               }
> +       }
> +
> +       if (fwnode_property_present(devnode, "mode-switch")) {
> +               fwnode = fwnode_graph_get_endpoint_by_id(devnode, 0, 0, 0);
> +               if (fwnode) {
> +                       ret = cros_typec_register_dp_bridge(sdata, fwnode);
>                         fwnode_handle_put(fwnode);
> -                       goto err;
> +                       if (ret)
> +                               goto err;
>                 }
>         }
>
> @@ -280,6 +450,7 @@ static int cros_typec_switch_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
>         struct cros_typec_switch_data *sdata;
> +       struct cros_ec_dev *ec_dev;
>
>         sdata = devm_kzalloc(dev, sizeof(*sdata), GFP_KERNEL);
>         if (!sdata)
> @@ -288,6 +459,12 @@ static int cros_typec_switch_probe(struct platform_device *pdev)
>         sdata->dev = dev;
>         sdata->ec = dev_get_drvdata(pdev->dev.parent);
>
> +       ec_dev = dev_get_drvdata(&sdata->ec->ec->dev);
> +       if (!ec_dev)
> +               return -EPROBE_DEFER;
> +
> +       sdata->typec_cmd_supported = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_AP_MUX_SET);
> +
>         platform_set_drvdata(pdev, sdata);
>
>         return cros_typec_register_switches(sdata);
> @@ -308,10 +485,19 @@ static const struct acpi_device_id cros_typec_switch_acpi_id[] = {
>  MODULE_DEVICE_TABLE(acpi, cros_typec_switch_acpi_id);
>  #endif
>
> +#ifdef CONFIG_OF
> +static const struct of_device_id cros_typec_switch_of_match_table[] = {
> +       { .compatible = "google,cros-ec-typec-switch" },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, cros_typec_switch_of_match_table);
> +#endif
> +
>  static struct platform_driver cros_typec_switch_driver = {
>         .driver = {
>                 .name = "cros-typec-switch",
>                 .acpi_match_table = ACPI_PTR(cros_typec_switch_acpi_id),
> +               .of_match_table = of_match_ptr(cros_typec_switch_of_match_table),
>         },
>         .probe = cros_typec_switch_probe,
>         .remove_new = cros_typec_switch_remove,
> --
> https://chromeos.dev
>
>


-- 
With best wishes
Dmitry


From erick.archer at gmx.com  Sat Feb 10 08:16:19 2024
From: erick.archer at gmx.com (Erick Archer)
Date: Sat, 10 Feb 2024 17:16:19 +0100
Subject: [PATCH] mtd: rawnand: Prefer struct_size over open coded arithmetic
Message-ID: <20240210161619.12656-1-erick.archer@gmx.com>

This is an effort to get rid of all multiplications from allocation
functions in order to prevent integer overflows [1].

As the "chip" variable is a pointer to "struct mtk_nfc_nand_chip" and
this structure ends in a flexible array:

struct mtk_nfc_nand_chip {
	[...]
	u8 sels[] __counted_by(nsels);
};

the preferred way in the kernel is to use the struct_size() helper to
do the arithmetic instead of the argument "size + count * size" in the
devm_kzalloc() function.

This way, the code is more readable and more safer.

Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
Link: https://github.com/KSPP/linux/issues/160 [2]
Signed-off-by: Erick Archer <erick.archer at gmx.com>
---
 drivers/mtd/nand/raw/mtk_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
index 60198e33d2d5..17477bb2d48f 100644
--- a/drivers/mtd/nand/raw/mtk_nand.c
+++ b/drivers/mtd/nand/raw/mtk_nand.c
@@ -1356,7 +1356,7 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
 		return -EINVAL;
 	}

-	chip = devm_kzalloc(dev, sizeof(*chip) + nsels * sizeof(u8),
+	chip = devm_kzalloc(dev, struct_size(chip, sels, nsels),
 			    GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
--
2.25.1



From gustavo at embeddedor.com  Sat Feb 10 08:52:36 2024
From: gustavo at embeddedor.com (Gustavo A. R. Silva)
Date: Sat, 10 Feb 2024 10:52:36 -0600
Subject: [PATCH] mtd: rawnand: Prefer struct_size over open coded
 arithmetic
In-Reply-To: <20240210161619.12656-1-erick.archer@gmx.com>
References: <20240210161619.12656-1-erick.archer@gmx.com>
Message-ID: <91f29d89-8c9b-46c4-b059-687ea3c57682@embeddedor.com>



On 2/10/24 10:16, Erick Archer wrote:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> As the "chip" variable is a pointer to "struct mtk_nfc_nand_chip" and
> this structure ends in a flexible array:
> 
> struct mtk_nfc_nand_chip {
> 	[...]
> 	u8 sels[] __counted_by(nsels);
> };
> 
> the preferred way in the kernel is to use the struct_size() helper to
> do the arithmetic instead of the argument "size + count * size" in the
> devm_kzalloc() function.
> 
> This way, the code is more readable and more safer.
> 
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
> Link: https://github.com/KSPP/linux/issues/160 [2]
> Signed-off-by: Erick Archer <erick.archer at gmx.com>

LGTM:

Reviewed-by: Gustavo A. R. Silva <gustavoars at kernel.org>

Thanks!
-- 
Gustavo

> ---
>   drivers/mtd/nand/raw/mtk_nand.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
> index 60198e33d2d5..17477bb2d48f 100644
> --- a/drivers/mtd/nand/raw/mtk_nand.c
> +++ b/drivers/mtd/nand/raw/mtk_nand.c
> @@ -1356,7 +1356,7 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
>   		return -EINVAL;
>   	}
> 
> -	chip = devm_kzalloc(dev, sizeof(*chip) + nsels * sizeof(u8),
> +	chip = devm_kzalloc(dev, struct_size(chip, sels, nsels),
>   			    GFP_KERNEL);
>   	if (!chip)
>   		return -ENOMEM;
> --
> 2.25.1
> 
> 


From u.kleine-koenig at pengutronix.de  Sat Feb 10 09:22:39 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Sat, 10 Feb 2024 18:22:39 +0100
Subject: [PATCH] mtd: rawnand: Prefer struct_size over open coded
 arithmetic
In-Reply-To: <20240210161619.12656-1-erick.archer@gmx.com>
References: <20240210161619.12656-1-erick.archer@gmx.com>
Message-ID: <vm3fk7wbqxjl3i6kmd3dv2ofeszjxrvi2n7cd3ohasgjpi4j4g@d3f6estk2xol>

On Sat, Feb 10, 2024 at 05:16:19PM +0100, Erick Archer wrote:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> As the "chip" variable is a pointer to "struct mtk_nfc_nand_chip" and
> this structure ends in a flexible array:
> 
> struct mtk_nfc_nand_chip {
> 	[...]
> 	u8 sels[] __counted_by(nsels);
> };
> 
> the preferred way in the kernel is to use the struct_size() helper to
> do the arithmetic instead of the argument "size + count * size" in the
> devm_kzalloc() function.
> 
> This way, the code is more readable and more safer.

Unless you intend this non-English comparative: s/more safer/safer/

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/20240210/40cc8025/attachment.sig>

From aford173 at gmail.com  Sat Feb 10 12:45:56 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 10 Feb 2024 14:45:56 -0600
Subject: [PATCH V4 0/6] soc: imx8mp: Finish support for HDMI
Message-ID: <20240210204606.11944-1-aford173@gmail.com>

The i.MX8M Plus has an HDMI controller, which depends on several
other systems.  The Parallel Video Interface (PVI) and the
HDMI-TX are already in the Linux-Next staging area 20240209, but
the HDMI PHY driver and several device trees updates are still needed.

This series is adapted from multiple series from Lucas Stach with
edits and suggestions from feedback from various attemps, but it
since it's difficult to use and test them independently,
I merged them into on unified series.  The version history is a
bit ambiguous since different components were submitted at different
times and had different amount of attempts.  

The previous attempt I did used the wrong starting point for the PHY,
so this update includes a newer starting point with tags from that version
and fixes from various people's feedback.  I hope I caught them all, but 
I apologize if I missed something. Any tags from the previous attempt I
made were intentionally dropped, because of the significant change,
but I kept tags from the newer version I grabbed from patchwork.

Because several items from the last attempt were merged, this
series is only focussed on adding the HDMI PHY driver, and enabling
the power domain, irqsteer interrupt controller, and HDMI pipeline
in the device tree. The version numbers are a bit strange since
these all got pulled from various attempts with different versions,
but I wanted to push them together as a series to complete the pending
work.

Adam Ford (1):
  arm64: defconfig: Enable DRM_IMX8MP_DW_HDMI_BRIDGE as module

Lucas Stach (5):
  dt-bindings: phy: add binding for the i.MX8MP HDMI PHY
  phy: freescale: add Samsung HDMI PHY
  arm64: dts: imx8mp: add HDMI power-domains
  arm64: dts: imx8mp: add HDMI irqsteer
  arm64: dts: imx8mp: add HDMI display pipeline

 .../bindings/phy/fsl,imx8mp-hdmi-phy.yaml     |  62 ++
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     | 145 ++++
 arch/arm64/configs/defconfig                  |   1 +
 drivers/phy/freescale/Kconfig                 |   6 +
 drivers/phy/freescale/Makefile                |   1 +
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c  | 721 ++++++++++++++++++
 6 files changed, 936 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml
 create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c

-- 
2.43.0



From aford173 at gmail.com  Sat Feb 10 12:45:57 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 10 Feb 2024 14:45:57 -0600
Subject: [PATCH V4 1/6] dt-bindings: phy: add binding for the i.MX8MP HDMI PHY
In-Reply-To: <20240210204606.11944-1-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
Message-ID: <20240210204606.11944-2-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

Add a DT binding for the HDMI PHY found on the i.MX8MP SoC.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
V4:  No Change

V3:  Removed mintems at the request of Krzysztof and add his
     reviewed-by

V2:  I (Adam) tried to help move this along, so I took Lucas' patch
     and attempted to apply fixes based on feedback.  I don't have
     all the history, so apologies for that.

     Added phy-cells to the required list and fixed an error due
     to the word 'binding' being in the title.
---
 .../bindings/phy/fsl,imx8mp-hdmi-phy.yaml     | 62 +++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml
new file mode 100644
index 000000000000..c43e86a8c2e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,imx8mp-hdmi-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8MP HDMI PHY
+
+maintainers:
+  - Lucas Stach <l.stach at pengutronix.de>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mp-hdmi-phy
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 0
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: apb
+      - const: ref
+
+  "#phy-cells":
+    const: 0
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - "#phy-cells"
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mp-clock.h>
+    #include <dt-bindings/power/imx8mp-power.h>
+
+    phy at 32fdff00 {
+        compatible = "fsl,imx8mp-hdmi-phy";
+        reg = <0x32fdff00 0x100>;
+        clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+                 <&clk IMX8MP_CLK_HDMI_24M>;
+        clock-names = "apb", "ref";
+        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>;
+        #clock-cells = <0>;
+        #phy-cells = <0>;
+    };
-- 
2.43.0



From aford173 at gmail.com  Sat Feb 10 12:45:58 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 10 Feb 2024 14:45:58 -0600
Subject: [PATCH V4 2/6] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240210204606.11944-1-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
Message-ID: <20240210204606.11944-3-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the driver for the Samsung HDMI PHY found on the
i.MX8MP SoC. Based on downstream implementation from
Sandor Yu <Sandor.yu at nxp.com>.  According to the TRM, the PHY
receives parallel data from the link and serializes it.  It
also sets the PLL clock needed for the TX serializer.

Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v2)
Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
Co-developed-by: Marco Felsch <m.felsch at pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> # Kontron BL
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V4:
- I (Adam) added a comment in the code for clarifcation
  based on questions from Luca concerning a difference
  between the code and the ref manual.
- Fixed the GENMASK on REG14
- Expanded the commit message briefly describing
  a bit more of what this driver does.
- Removed some unnecessary include files.

v3:
- use GENMASK/FIELD_PREP
- lowercase hex values
- correct coding style
v2:
- use DEFINE_RUNTIME_DEV_PM_OPS
---
 drivers/phy/freescale/Kconfig                |   6 +
 drivers/phy/freescale/Makefile               |   1 +
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 721 +++++++++++++++++++
 3 files changed, 728 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index 853958fb2c06..5c2b73042dfc 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -35,6 +35,12 @@ config PHY_FSL_IMX8M_PCIE
 	  Enable this to add support for the PCIE PHY as found on
 	  i.MX8M family of SOCs.
 
+config PHY_FSL_SAMSUNG_HDMI_PHY
+	tristate "Samsung HDMI PHY support"
+	depends on OF && HAS_IOMEM
+	help
+	  Enable this to add support for the Samsung HDMI PHY in i.MX8MP.
+
 endif
 
 config PHY_FSL_LYNX_28G
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index cedb328bc4d2..c4386bfdb853 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
 obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)	+= phy-fsl-imx8m-pcie.o
 obj-$(CONFIG_PHY_FSL_LYNX_28G)		+= phy-fsl-lynx-28g.o
+obj-$(CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY)	+= phy-fsl-samsung-hdmi.o
diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
new file mode 100644
index 000000000000..91cf8e4668b2
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -0,0 +1,721 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 NXP
+ * Copyright 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#define PHY_REG_00		0x00
+#define PHY_REG_01		0x04
+#define PHY_REG_02		0x08
+#define PHY_REG_08		0x20
+#define PHY_REG_09		0x24
+#define PHY_REG_10		0x28
+#define PHY_REG_11		0x2c
+
+#define PHY_REG_12		0x30
+#define  REG12_CK_DIV_MASK	GENMASK(5, 4)
+
+#define PHY_REG_13		0x34
+#define  REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
+
+#define PHY_REG_14		0x38
+#define  REG14_TOL_MASK		GENMASK(7, 4)
+#define  REG14_RP_CODE_MASK	GENMASK(3, 1)
+#define  REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
+
+#define PHY_REG_15		0x3c
+#define PHY_REG_16		0x40
+#define PHY_REG_17		0x44
+#define PHY_REG_18		0x48
+#define PHY_REG_19		0x4c
+#define PHY_REG_20		0x50
+
+#define PHY_REG_21		0x54
+#define  REG21_SEL_TX_CK_INV	BIT(7)
+#define  REG21_PMS_S_MASK	GENMASK(3, 0)
+
+#define PHY_REG_22		0x58
+#define PHY_REG_23		0x5c
+#define PHY_REG_24		0x60
+#define PHY_REG_25		0x64
+#define PHY_REG_26		0x68
+#define PHY_REG_27		0x6c
+#define PHY_REG_28		0x70
+#define PHY_REG_29		0x74
+#define PHY_REG_30		0x78
+#define PHY_REG_31		0x7c
+#define PHY_REG_32		0x80
+
+/*
+ * REG33 does not match the ref manual. According to Sandor Yu from NXP,
+ * "There is a doc issue on the i.MX8MP latest RM"
+ * REG33 is being used per guidance from Sandor
+ */
+
+#define PHY_REG_33		0x84
+#define  REG33_MODE_SET_DONE	BIT(7)
+#define  REG33_FIX_DA		BIT(1)
+
+#define PHY_REG_34		0x88
+#define  REG34_PHY_READY	BIT(7)
+#define  REG34_PLL_LOCK		BIT(6)
+#define  REG34_PHY_CLK_READY	BIT(5)
+
+#define PHY_REG_35		0x8c
+#define PHY_REG_36		0x90
+#define PHY_REG_37		0x94
+#define PHY_REG_38		0x98
+#define PHY_REG_39		0x9c
+#define PHY_REG_40		0xa0
+#define PHY_REG_41		0xa4
+#define PHY_REG_42		0xa8
+#define PHY_REG_43		0xac
+#define PHY_REG_44		0xb0
+#define PHY_REG_45		0xb4
+#define PHY_REG_46		0xb8
+#define PHY_REG_47		0xbc
+
+#define PHY_PLL_DIV_REGS_NUM 6
+
+struct phy_config {
+	u32	pixclk;
+	u8	pll_div_regs[PHY_PLL_DIV_REGS_NUM];
+};
+
+const struct phy_config phy_pll_cfg[] = {
+	{
+		.pixclk = 22250000,
+		.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 23750000,
+		.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
+	}, {
+		.pixclk = 24000000,
+		.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 24024000,
+		.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
+	}, {
+		.pixclk = 25175000,
+		.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
+	}, {
+		.pixclk = 25200000,
+		.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 26750000,
+		.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 27000000,
+		.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 27027000,
+		.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 29500000,
+		.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 30750000,
+		.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
+	}, {
+		.pixclk = 30888000,
+		.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
+	}, {
+		.pixclk = 33750000,
+		.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
+	}, {
+		.pixclk = 35000000,
+		.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 36000000,
+		.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 36036000,
+		.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 40000000,
+		.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 43200000,
+		.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 43243200,
+		.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 44500000,
+		.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
+	}, {
+		.pixclk = 47000000,
+		.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
+	}, {
+		.pixclk = 47500000,
+		.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
+	}, {
+		.pixclk = 50349650,
+		.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
+	}, {
+		.pixclk = 50400000,
+		.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 53250000,
+		.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
+	}, {
+		.pixclk = 53500000,
+		.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 54000000,
+		.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 54054000,
+		.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 59000000,
+		.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 59340659,
+		.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
+	}, {
+		.pixclk = 59400000,
+		.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 61500000,
+		.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
+	}, {
+		.pixclk = 63500000,
+		.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 67500000,
+		.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
+	}, {
+		.pixclk = 70000000,
+		.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 72000000,
+		.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 72072000,
+		.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 74176000,
+		.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
+	}, {
+		.pixclk = 74250000,
+		.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
+	}, {
+		.pixclk = 78500000,
+		.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
+	}, {
+		.pixclk = 80000000,
+		.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 82000000,
+		.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
+	}, {
+		.pixclk = 82500000,
+		.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
+	}, {
+		.pixclk = 89000000,
+		.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
+	}, {
+		.pixclk = 90000000,
+		.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
+	}, {
+		.pixclk = 94000000,
+		.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
+	}, {
+		.pixclk = 95000000,
+		.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
+	}, {
+		.pixclk = 98901099,
+		.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
+	}, {
+		.pixclk = 99000000,
+		.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
+	}, {
+		.pixclk = 100699300,
+		.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
+	}, {
+		.pixclk = 100800000,
+		.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 102500000,
+		.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
+	}, {
+		.pixclk = 104750000,
+		.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
+	}, {
+		.pixclk = 106500000,
+		.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
+	}, {
+		.pixclk = 107000000,
+		.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 108000000,
+		.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 108108000,
+		.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 118000000,
+		.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 118800000,
+		.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 123000000,
+		.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
+	}, {
+		.pixclk = 127000000,
+		.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 135000000,
+		.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
+	}, {
+		.pixclk = 135580000,
+		.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
+	}, {
+		.pixclk = 137520000,
+		.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
+	}, {
+		.pixclk = 138750000,
+		.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
+	}, {
+		.pixclk = 140000000,
+		.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
+	}, {
+		.pixclk = 144000000,
+		.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 148352000,
+		.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
+	}, {
+		.pixclk = 148500000,
+		.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
+	}, {
+		.pixclk = 154000000,
+		.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
+	}, {
+		.pixclk = 157000000,
+		.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
+	}, {
+		.pixclk = 160000000,
+		.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
+	}, {
+		.pixclk = 162000000,
+		.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
+	}, {
+		.pixclk = 164000000,
+		.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
+	}, {
+		.pixclk = 165000000,
+		.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
+	}, {
+		.pixclk = 180000000,
+		.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 185625000,
+		.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
+	}, {
+		.pixclk = 188000000,
+		.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
+	}, {
+		.pixclk = 198000000,
+		.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
+	}, {
+		.pixclk = 205000000,
+		.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
+	}, {
+		.pixclk = 209500000,
+		.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
+	}, {
+		.pixclk = 213000000,
+		.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
+	}, {
+		.pixclk = 216000000,
+		.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 216216000,
+		.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 237600000,
+		.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 254000000,
+		.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 277500000,
+		.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
+	}, {
+		.pixclk = 288000000,
+		.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 297000000,
+		.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
+	},
+};
+
+struct reg_settings {
+	u8 reg;
+	u8 val;
+};
+
+const struct reg_settings common_phy_cfg[] = {
+	{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
+	{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
+	{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
+	/* REG12 pixclk specific */
+	/* REG13 pixclk specific */
+	/* REG14 pixclk specific */
+	{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
+	{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
+	{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
+	/* REG21 pixclk specific */
+	{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
+	{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
+	{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
+	{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
+	{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
+	{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
+	{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
+	{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
+	{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
+	{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
+	{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
+	{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
+	{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
+};
+
+struct fsl_samsung_hdmi_phy {
+	struct device *dev;
+	void __iomem *regs;
+	struct clk *apbclk;
+	struct clk *refclk;
+
+	/* clk provider */
+	struct clk_hw hw;
+	const struct phy_config *cur_cfg;
+};
+
+static inline struct fsl_samsung_hdmi_phy *
+to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
+{
+	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
+}
+
+static void
+fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
+				      const struct phy_config *cfg)
+{
+	u8 div;
+
+	switch (cfg->pixclk) {
+	case  22250000 ...  33750000:
+		div = 0xf;
+		break;
+	case  35000000 ...  40000000:
+		div = 0xb;
+		break;
+	case  43200000 ...  47500000:
+		div = 0x9;
+		break;
+	case  50349650 ...  63500000:
+		div = 0x7;
+		break;
+	case  67500000 ...  90000000:
+		div = 0x5;
+		break;
+	case  94000000 ... 148500000:
+		div = 0x3;
+		break;
+	case 154000000 ... 297000000:
+		div = 0x1;
+		break;
+	}
+
+	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
+	       phy->regs + PHY_REG_21);
+}
+
+static void
+fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
+					    const struct phy_config *cfg)
+{
+	u32 pclk = cfg->pixclk;
+	u32 fld_tg_code;
+	u32 pclk_khz;
+	u8 div;
+
+	switch (cfg->pixclk) {
+	case  22250000 ...  47500000:
+		div = 1;
+		break;
+	case  50349650 ...  99000000:
+		div = 2;
+		break;
+	case 100699300 ... 198000000:
+		div = 4;
+		break;
+	case 205000000 ... 297000000:
+		div = 8;
+		break;
+	}
+
+	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
+
+	/*
+	 * Calculation for the frequency lock detector target code (fld_tg_code)
+	 * is based on reference manual register description of PHY_REG13
+	 * (13.10.3.1.14.2):
+	 *   1st) Calculate int_pllclk which is determinded by FLD_CK_DIV
+	 *   2nd) Increase resolution to avoid rounding issues
+	 *   3th) Do the div (256 / Freq. of int_pllclk) * 24
+	 *   4th) Reduce the resolution and always round up since the NXP
+	 *        settings rounding up always too. TODO: Check if that is
+	 *        correct.
+	 */
+	pclk /= div;
+	pclk_khz = pclk / 1000;
+	fld_tg_code = 256 * 1000 * 1000 / pclk_khz * 24;
+	fld_tg_code = DIV_ROUND_UP(fld_tg_code, 1000);
+
+	/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
+	writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
+	       phy->regs + PHY_REG_13);
+	writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
+	       FIELD_PREP(REG14_RP_CODE_MASK, 2) |
+	       FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
+	       phy->regs + PHY_REG_14);
+}
+
+static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
+					  const struct phy_config *cfg)
+{
+	int i, ret;
+	u8 val;
+
+	/* HDMI PHY init */
+	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
+
+	/* common PHY registers */
+	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
+		writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
+
+	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
+	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
+
+	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
+	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
+
+	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
+
+	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
+				 val & REG34_PLL_LOCK, 50, 20000);
+	if (ret)
+		dev_err(phy->dev, "PLL failed to lock\n");
+
+	return ret;
+}
+
+static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
+
+	if (!phy->cur_cfg)
+		return 74250000;
+
+	return phy->cur_cfg->pixclk;
+}
+
+static long phy_clk_round_rate(struct clk_hw *hw,
+			       unsigned long rate, unsigned long *parent_rate)
+{
+	int i;
+
+	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
+		if (phy_pll_cfg[i].pixclk <= rate)
+			return phy_pll_cfg[i].pixclk;
+
+	return -EINVAL;
+}
+
+static int phy_clk_set_rate(struct clk_hw *hw,
+			    unsigned long rate, unsigned long parent_rate)
+{
+	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
+	int i;
+
+	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
+		if (phy_pll_cfg[i].pixclk <= rate)
+			break;
+
+	if (i < 0)
+		return -EINVAL;
+
+	phy->cur_cfg = &phy_pll_cfg[i];
+
+	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+}
+
+static const struct clk_ops phy_clk_ops = {
+	.recalc_rate = phy_clk_recalc_rate,
+	.round_rate = phy_clk_round_rate,
+	.set_rate = phy_clk_set_rate,
+};
+
+static int phy_clk_register(struct fsl_samsung_hdmi_phy *phy)
+{
+	struct device *dev = phy->dev;
+	struct device_node *np = dev->of_node;
+	struct clk_init_data init;
+	const char *parent_name;
+	struct clk *phyclk;
+	int ret;
+
+	parent_name = __clk_get_name(phy->refclk);
+
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	init.flags = 0;
+	init.name = "hdmi_pclk";
+	init.ops = &phy_clk_ops;
+
+	phy->hw.init = &init;
+
+	phyclk = devm_clk_register(dev, &phy->hw);
+	if (IS_ERR(phyclk))
+		return dev_err_probe(dev, PTR_ERR(phyclk),
+				     "failed to register clock\n");
+
+	ret = of_clk_add_provider(np, of_clk_src_simple_get, phyclk);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to register clock provider\n");
+
+	return 0;
+}
+
+static int fsl_samsung_hdmi_phy_probe(struct platform_device *pdev)
+{
+	struct fsl_samsung_hdmi_phy *phy;
+	int ret;
+
+	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, phy);
+	phy->dev = &pdev->dev;
+
+	phy->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->regs))
+		return PTR_ERR(phy->regs);
+
+	phy->apbclk = devm_clk_get(phy->dev, "apb");
+	if (IS_ERR(phy->apbclk))
+		return dev_err_probe(phy->dev, PTR_ERR(phy->apbclk),
+				     "failed to get apb clk\n");
+
+	phy->refclk = devm_clk_get(phy->dev, "ref");
+	if (IS_ERR(phy->refclk))
+		return dev_err_probe(phy->dev, PTR_ERR(phy->refclk),
+				     "failed to get ref clk\n");
+
+	ret = clk_prepare_enable(phy->apbclk);
+	if (ret) {
+		dev_err(phy->dev, "failed to enable apbclk\n");
+		return ret;
+	}
+
+	pm_runtime_get_noresume(phy->dev);
+	pm_runtime_set_active(phy->dev);
+	pm_runtime_enable(phy->dev);
+
+	ret = phy_clk_register(phy);
+	if (ret) {
+		dev_err(&pdev->dev, "register clk failed\n");
+		goto register_clk_failed;
+	}
+
+	pm_runtime_put(phy->dev);
+
+	return 0;
+
+register_clk_failed:
+	clk_disable_unprepare(phy->apbclk);
+
+	return ret;
+}
+
+static int fsl_samsung_hdmi_phy_remove(struct platform_device *pdev)
+{
+	of_clk_del_provider(pdev->dev.of_node);
+
+	return 0;
+}
+
+static int fsl_samsung_hdmi_phy_suspend(struct device *dev)
+{
+	struct fsl_samsung_hdmi_phy *phy = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(phy->apbclk);
+
+	return 0;
+}
+
+static int fsl_samsung_hdmi_phy_resume(struct device *dev)
+{
+	struct fsl_samsung_hdmi_phy *phy = dev_get_drvdata(dev);
+	int ret = 0;
+
+	ret = clk_prepare_enable(phy->apbclk);
+	if (ret) {
+		dev_err(phy->dev, "failed to enable apbclk\n");
+		return ret;
+	}
+
+	if (phy->cur_cfg)
+		ret = fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+
+	return ret;
+
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(fsl_samsung_hdmi_phy_pm_ops,
+				 fsl_samsung_hdmi_phy_suspend,
+				 fsl_samsung_hdmi_phy_resume, NULL);
+
+static const struct of_device_id fsl_samsung_hdmi_phy_of_match[] = {
+	{
+		.compatible = "fsl,imx8mp-hdmi-phy",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, fsl_samsung_hdmi_phy_of_match);
+
+static struct platform_driver fsl_samsung_hdmi_phy_driver = {
+	.probe  = fsl_samsung_hdmi_phy_probe,
+	.remove = fsl_samsung_hdmi_phy_remove,
+	.driver = {
+		.name = "fsl-samsung-hdmi-phy",
+		.of_match_table = fsl_samsung_hdmi_phy_of_match,
+		.pm = pm_ptr(&fsl_samsung_hdmi_phy_pm_ops),
+	},
+};
+module_platform_driver(fsl_samsung_hdmi_phy_driver);
+
+MODULE_AUTHOR("Sandor Yu <Sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("SAMSUNG HDMI 2.0 Transmitter PHY Driver");
+MODULE_LICENSE("GPL");
-- 
2.43.0



From aford173 at gmail.com  Sat Feb 10 12:45:59 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 10 Feb 2024 14:45:59 -0600
Subject: [PATCH V4 3/6] arm64: dts: imx8mp: add HDMI power-domains
In-Reply-To: <20240210204606.11944-1-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
Message-ID: <20240210204606.11944-4-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the PGC and HDMI blk-ctrl nodes providing power control for
HDMI subsystem peripherals.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
V4:  No Change

V3:  The hdmi_blk_ctrl was in the wrong place, so move it to AIPS4.
     power-domains@ fixed to read power-domain@

V2:  Add missing power-domains hdcp and hrv
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 38 +++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 9ab9c057f41e..0730d4cf9bc4 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -836,6 +836,23 @@ pgc_mediamix: power-domain at 10 {
 							 <&clk IMX8MP_CLK_MEDIA_APB_ROOT>;
 					};
 
+					pgc_hdmimix: power-domain at 14 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_HDMIMIX>;
+						clocks = <&clk IMX8MP_CLK_HDMI_ROOT>,
+							 <&clk IMX8MP_CLK_HDMI_APB>;
+						assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>,
+								  <&clk IMX8MP_CLK_HDMI_APB>;
+						assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>,
+									 <&clk IMX8MP_SYS_PLL1_133M>;
+						assigned-clock-rates = <500000000>, <133000000>;
+					};
+
+					pgc_hdmi_phy: power-domain at 15 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_HDMI_PHY>;
+					};
+
 					pgc_mipi_phy2: power-domain at 16 {
 						#power-domain-cells = <0>;
 						reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
@@ -1889,6 +1906,27 @@ hsio_blk_ctrl: blk-ctrl at 32f10000 {
 				#power-domain-cells = <1>;
 				#clock-cells = <0>;
 			};
+
+			hdmi_blk_ctrl: blk-ctrl at 32fc0000 {
+				compatible = "fsl,imx8mp-hdmi-blk-ctrl", "syscon";
+				reg = <0x32fc0000 0x1000>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_ROOT>,
+					 <&clk IMX8MP_CLK_HDMI_REF_266M>,
+					 <&clk IMX8MP_CLK_HDMI_24M>,
+					 <&clk IMX8MP_CLK_HDMI_FDCC_TST>;
+				clock-names = "apb", "axi", "ref_266m", "ref_24m", "fdcc";
+				power-domains = <&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmi_phy>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>;
+				power-domain-names = "bus", "irqsteer", "lcdif",
+						     "pai", "pvi", "trng",
+						     "hdmi-tx", "hdmi-tx-phy",
+						     "hdcp", "hrv";
+				#power-domain-cells = <1>;
+			};
 		};
 
 		pcie: pcie at 33800000 {
-- 
2.43.0



From aford173 at gmail.com  Sat Feb 10 12:46:00 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 10 Feb 2024 14:46:00 -0600
Subject: [PATCH V4 4/6] arm64: dts: imx8mp: add HDMI irqsteer
In-Reply-To: <20240210204606.11944-1-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
Message-ID: <20240210204606.11944-5-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

The HDMI irqsteer is a secondary interrupt controller within the HDMI
subsystem that maps all HDMI peripheral IRQs into a single upstream
IRQ line.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V2:  Add my (Adam) s-o-b and re-order position under AIPS4
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 0730d4cf9bc4..9b8ab367d774 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1927,6 +1927,19 @@ hdmi_blk_ctrl: blk-ctrl at 32fc0000 {
 						     "hdcp", "hrv";
 				#power-domain-cells = <1>;
 			};
+
+			irqsteer_hdmi: interrupt-controller at 32fc2000 {
+				compatible = "fsl,imx-irqsteer";
+				reg = <0x32fc2000 0x44>;
+				interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				fsl,channel = <1>;
+				fsl,num-irqs = <64>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>;
+				clock-names = "ipg";
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>;
+			};
 		};
 
 		pcie: pcie at 33800000 {
-- 
2.43.0



From aford173 at gmail.com  Sat Feb 10 12:46:01 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 10 Feb 2024 14:46:01 -0600
Subject: [PATCH V4 5/6] arm64: dts: imx8mp: add HDMI display pipeline
In-Reply-To: <20240210204606.11944-1-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
Message-ID: <20240210204606.11944-6-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the DT nodes for all the peripherals that make up the
HDMI display pipeline.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>
---
V3:  Re-ordered the HDMI parts to properly come after irqstree_hdmi
     inside AIPS4.  Change size of LCDIF3 and PVI to match TRM sizes
     of 4KB.

V2:  I took this from Lucas' original submission with the following:
     Removed extra clock from HDMI-TX since it is now part of the
     power domain
     Added interrupt-parent to PVI
     Changed the name of the HDMI tranmitter to fsl,imx8mp-hdmi-tx
     Added ports to HDMI-tx
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 94 +++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 9b8ab367d774..013c2d9824cd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1940,6 +1940,100 @@ irqsteer_hdmi: interrupt-controller at 32fc2000 {
 				clock-names = "ipg";
 				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>;
 			};
+
+			hdmi_pvi: display-bridge at 32fc4000 {
+				compatible = "fsl,imx8mp-hdmi-pvi";
+				reg = <0x32fc4000 0x1000>;
+				interrupt-parent = <&irqsteer_hdmi>;
+				interrupts = <12>;
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port at 0 {
+						reg = <0>;
+						pvi_from_lcdif3: endpoint {
+							remote-endpoint = <&lcdif3_to_pvi>;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+						pvi_to_hdmi_tx: endpoint {
+							remote-endpoint = <&hdmi_tx_from_pvi>;
+						};
+					};
+				};
+			};
+
+			lcdif3: display-controller at 32fc6000 {
+				compatible = "fsl,imx8mp-lcdif";
+				reg = <0x32fc6000 0x1000>;
+				interrupt-parent = <&irqsteer_hdmi>;
+				interrupts = <8>;
+				clocks = <&hdmi_tx_phy>,
+					 <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_ROOT>;
+				clock-names = "pix", "axi", "disp_axi";
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_LCDIF>;
+
+				port {
+					lcdif3_to_pvi: endpoint {
+						remote-endpoint = <&pvi_from_lcdif3>;
+					};
+				};
+			};
+
+			hdmi_tx: hdmi at 32fd8000 {
+				compatible = "fsl,imx8mp-hdmi-tx";
+				reg = <0x32fd8000 0x7eff>;
+				interrupt-parent = <&irqsteer_hdmi>;
+				interrupts = <0>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_REF_266M>,
+					 <&clk IMX8MP_CLK_32K>,
+					 <&hdmi_tx_phy>;
+				clock-names = "iahb", "isfr", "cec", "pix";
+				assigned-clocks = <&clk IMX8MP_CLK_HDMI_REF_266M>;
+				assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>;
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
+				reg-io-width = <1>;
+				status = "disabled";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port at 0 {
+						reg = <0>;
+
+						hdmi_tx_from_pvi: endpoint {
+							remote-endpoint = <&pvi_to_hdmi_tx>;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+						/* Point endpoint to the HDMI connector */
+					};
+				};
+			};
+
+			hdmi_tx_phy: phy at 32fdff00 {
+				compatible = "fsl,imx8mp-hdmi-phy";
+				reg = <0x32fdff00 0x100>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_24M>;
+				clock-names = "apb", "ref";
+				assigned-clocks = <&clk IMX8MP_CLK_HDMI_24M>;
+				assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>;
+				#clock-cells = <0>;
+				#phy-cells = <0>;
+				status = "disabled";
+			};
 		};
 
 		pcie: pcie at 33800000 {
-- 
2.43.0



From aford173 at gmail.com  Sat Feb 10 12:46:02 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 10 Feb 2024 14:46:02 -0600
Subject: [PATCH V4 6/6] arm64: defconfig: Enable DRM_IMX8MP_DW_HDMI_BRIDGE as module
In-Reply-To: <20240210204606.11944-1-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
Message-ID: <20240210204606.11944-7-aford173@gmail.com>

The i.MX8M Plus has support for an HDMI transmitter.  The
video is genereated by lcdif3, routed to the hdmi parallel
video interface, then fed to a DW HDMI bridge to support
up to 4K video output.

Signed-off-by: Adam Ford <aford173 at gmail.com>
---
No change since V1
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f44b3abf3cef..03ba9e89a0a5 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -886,6 +886,7 @@ CONFIG_DRM_ANALOGIX_ANX7625=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_DRM_CDNS_MHDP8546=m
+CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE=m
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
 CONFIG_DRM_DW_HDMI_CEC=m
 CONFIG_DRM_IMX_DCSS=m
-- 
2.43.0



From nicolas at fjasle.eu  Sat Feb 10 13:19:32 2024
From: nicolas at fjasle.eu (Nicolas Schier)
Date: Sat, 10 Feb 2024 22:19:32 +0100
Subject: [PATCH 1/2] kbuild: Abort make on install failures
In-Reply-To: <ZcdP7CC+OMbp5ZMi@shell.armlinux.org.uk>
References: <20240210074601.5363-1-xtex@envs.net>
 <20240210074601.5363-2-xtex@envs.net>
 <ZcdP7CC+OMbp5ZMi@shell.armlinux.org.uk>
Message-ID: <ZcfoZKJHkdEh5JmV@fjasle.eu>

On Sat, Feb 10, 2024 at 10:29:00AM +0000 Russell King (Oracle) wrote:
> On Sat, Feb 10, 2024 at 03:46:00PM +0800, Zhang Bingwu wrote:
> > From: Zhang Bingwu <xtexchooser at duck.com>
> > 
> > Setting '-e' flag tells shells to exit with error exit code immediately
> > after any of commands fails, and causes make(1) to regard recipes as
> > failed.
> > 
> > Before this, make will still continue to succeed even after the
> > installation failed, for example, for insufficient permission or
> > directory does not exist.
> >
> > Signed-off-by: Zhang Bingwu <xtexchooser at duck.com>
> > ---

Thanks for fixing!

[...]
> > diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh
> > index 9ec11fac7d8d..34e2c6e31fd1 100755
> > --- a/arch/arm/boot/install.sh
> > +++ b/arch/arm/boot/install.sh
> > @@ -17,6 +17,8 @@
> >  #   $3 - kernel map file
> >  #   $4 - default install path (blank if root directory)
> >  
> > +set -e
> > +
> 
> What about #!/bin/sh -e on the first line, which is the more normal way
> to do this for an entire script?

are you sure?  I can find many more occurrences of 'set -e' than the
shebang version in the Linux tree, especially in the kbuild scripts, thus
it's bike-shedding, isn't it?

Reviewed-by: Nicolas Schier <nicolas at fjasle.eu>

Kind regards,
Nicolas
-------------- 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/20240210/a72b1680/attachment.sig>

From nicolas at fjasle.eu  Sat Feb 10 13:26:09 2024
From: nicolas at fjasle.eu (Nicolas Schier)
Date: Sat, 10 Feb 2024 22:26:09 +0100
Subject: [PATCH 2/2] kbuild: Create INSTALL_PATH directory if it does not
 exist
In-Reply-To: <20240210074601.5363-3-xtex@envs.net>
References: <20240210074601.5363-1-xtex@envs.net>
 <20240210074601.5363-3-xtex@envs.net>
Message-ID: <Zcfp8fn7o74K08g0@fjasle.eu>

On Sat, Feb 10, 2024 at 03:46:01PM +0800 Zhang Bingwu wrote:
> From: Zhang Bingwu <xtexchooser at duck.com>
> 
> If INSTALL_PATH is not a valid directory, create it, like what
> modules_install and dtbs_install will do in the same situation.
> 
> Signed-off-by: Zhang Bingwu <xtexchooser at duck.com>
> ---
>  scripts/install.sh | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/scripts/install.sh b/scripts/install.sh
> index 9bb0fb44f04a..02b845e7ab33 100755
> --- a/scripts/install.sh
> +++ b/scripts/install.sh
> @@ -20,6 +20,10 @@ do
>  	fi
>  done
>  
> +if [ "${INSTALL_PATH}" != "" ] && ! [ -e "${INSTALL_PATH}" ]; then
> +	mkdir -p "${INSTALL_PATH}"
> +fi
> +
>  # User/arch may have a custom install script
>  for file in "${HOME}/bin/${INSTALLKERNEL}"		\
>  	    "/sbin/${INSTALLKERNEL}"			\
> -- 
> 2.43.0
> 

Thanks.

Reviewed-by: Nicolas Schier <nicolas at jasle.eu>
-------------- 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/20240210/78dbcea9/attachment.sig>

From avkrasnov at salutedevices.com  Sat Feb 10 13:45:51 2024
From: avkrasnov at salutedevices.com (Arseniy Krasnov)
Date: Sun, 11 Feb 2024 00:45:51 +0300
Subject: [PATCH v1] mtd: rawnand: meson: fix scrambling mode value in command macro
Message-ID: <20240210214551.441610-1-avkrasnov@salutedevices.com>

Scrambling mode is enabled by value (1 << 19). NFC_CMD_SCRAMBLER_ENABLE
is already (1 << 19), so there is no need to shift it again in CMDRWGEN
macro.

Signed-off-by: Arseniy Krasnov <avkrasnov at salutedevices.com>
Cc: <Stable at vger.kernel.org>
Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
---
 drivers/mtd/nand/raw/meson_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
index cdb58aca59c0..2a96a87cf79c 100644
--- a/drivers/mtd/nand/raw/meson_nand.c
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -63,7 +63,7 @@
 #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
 	(								\
 		(cmd_dir)			|			\
-		((ran) << 19)			|			\
+		(ran)				|			\
 		((bch) << 14)			|			\
 		((short_mode) << 13)		|			\
 		(((page_size) & 0x7f) << 6)	|			\
-- 
2.35.0



From masahiroy at kernel.org  Sat Feb 10 15:35:35 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Sun, 11 Feb 2024 08:35:35 +0900
Subject: [PATCH 1/2] kbuild: Abort make on install failures
In-Reply-To: <ZcfoZKJHkdEh5JmV@fjasle.eu>
References: <20240210074601.5363-1-xtex@envs.net> <20240210074601.5363-2-xtex@envs.net>
 <ZcdP7CC+OMbp5ZMi@shell.armlinux.org.uk> <ZcfoZKJHkdEh5JmV@fjasle.eu>
Message-ID: <CAK7LNAQPm7PXoKM+id25wX9AtVmmXvE7i8GrGB9etU__EMUwdg@mail.gmail.com>

On Sun, Feb 11, 2024 at 6:21?AM Nicolas Schier <nicolas at fjasle.eu> wrote:
>
> On Sat, Feb 10, 2024 at 10:29:00AM +0000 Russell King (Oracle) wrote:
> > On Sat, Feb 10, 2024 at 03:46:00PM +0800, Zhang Bingwu wrote:
> > > From: Zhang Bingwu <xtexchooser at duck.com>
> > >
> > > Setting '-e' flag tells shells to exit with error exit code immediately
> > > after any of commands fails, and causes make(1) to regard recipes as
> > > failed.
> > >
> > > Before this, make will still continue to succeed even after the
> > > installation failed, for example, for insufficient permission or
> > > directory does not exist.
> > >
> > > Signed-off-by: Zhang Bingwu <xtexchooser at duck.com>
> > > ---
>
> Thanks for fixing!
>
> [...]
> > > diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh
> > > index 9ec11fac7d8d..34e2c6e31fd1 100755
> > > --- a/arch/arm/boot/install.sh
> > > +++ b/arch/arm/boot/install.sh
> > > @@ -17,6 +17,8 @@
> > >  #   $3 - kernel map file
> > >  #   $4 - default install path (blank if root directory)
> > >
> > > +set -e
> > > +
> >
> > What about #!/bin/sh -e on the first line, which is the more normal way
> > to do this for an entire script?
>
> are you sure?  I can find many more occurrences of 'set -e' than the
> shebang version in the Linux tree, especially in the kbuild scripts, thus
> it's bike-shedding, isn't it?
>
> Reviewed-by: Nicolas Schier <nicolas at fjasle.eu>
>
> Kind regards,
> Nicolas






When you put -e on the shebang line, like

    #!/bin/sh -e

the option -e is set when you do:

    $ arch/arm/boot/install.sh


But, -e is not set when you do:

    $ sh arch/arm/boot/install.sh



The reason is obvious because the latter case
does not use the shebang line.




In Kbuild, some places run the script directly like the former case,
and others use CONFIG_SHELL like

   $(CONFIG_SHELL) arch/arm/boot/install.sh


The inconsistency is not nice, but that is a different issue.


The separate 'set -e' statement works for both cases,
so I think this is safer, though it is kind of bike-shedding.





-- 
Best Regards
Masahiro Yamada


From lkp at intel.com  Sat Feb 10 20:19:20 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 11 Feb 2024 12:19:20 +0800
Subject: [PATCH v4 4/4] pinctrl: nuvoton: Add ma35d1 pinctrl and GPIO
 driver
In-Reply-To: <20240206025223.35147-5-ychuang570808@gmail.com>
References: <20240206025223.35147-5-ychuang570808@gmail.com>
Message-ID: <202402111204.to88Twuu-lkp@intel.com>

Hi Jacky,

kernel test robot noticed the following build errors:

[auto build test ERROR on linusw-pinctrl/devel]
[also build test ERROR on linusw-pinctrl/for-next robh/for-next linus/master v6.8-rc3 next-20240209]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Jacky-Huang/dt-bindings-reset-Add-syscon-to-nuvoton-ma35d1-system-management-node/20240206-105502
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
patch link:    https://lore.kernel.org/r/20240206025223.35147-5-ychuang570808%40gmail.com
patch subject: [PATCH v4 4/4] pinctrl: nuvoton: Add ma35d1 pinctrl and GPIO driver
config: powerpc-randconfig-r122-20240208 (https://download.01.org/0day-ci/archive/20240211/202402111204.to88Twuu-lkp at intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project.git f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce: (https://download.01.org/0day-ci/archive/20240211/202402111204.to88Twuu-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402111204.to88Twuu-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/pinctrl/nuvoton/pinctrl-ma35d1.c:14:
   drivers/pinctrl/nuvoton/pinctrl-ma35.h:46:31: warning: declaration of 'struct platform_device' will not be visible outside of this function [-Wvisibility]
   int ma35_pinctrl_probe(struct platform_device *pdev, const struct ma35_pinctrl_soc_info *info);
                                 ^
   drivers/pinctrl/nuvoton/pinctrl-ma35d1.c:1770:40: warning: declaration of 'struct platform_device' will not be visible outside of this function [-Wvisibility]
   static int ma35d1_pinctrl_probe(struct platform_device *pdev)
                                          ^
   drivers/pinctrl/nuvoton/pinctrl-ma35d1.c:1772:28: error: incompatible pointer types passing 'struct platform_device *' to parameter of type 'struct platform_device *' [-Werror,-Wincompatible-pointer-types]
           return ma35_pinctrl_probe(pdev, &ma35d1_pinctrl_info);
                                     ^~~~
   drivers/pinctrl/nuvoton/pinctrl-ma35.h:46:48: note: passing argument to parameter 'pdev' here
   int ma35_pinctrl_probe(struct platform_device *pdev, const struct ma35_pinctrl_soc_info *info);
                                                  ^
   drivers/pinctrl/nuvoton/pinctrl-ma35d1.c:1780:31: error: variable has incomplete type 'struct platform_driver'
   static struct platform_driver ma35d1_pinctrl_driver = {
                                 ^
   drivers/pinctrl/nuvoton/pinctrl-ma35d1.c:1780:15: note: forward declaration of 'struct platform_driver'
   static struct platform_driver ma35d1_pinctrl_driver = {
                 ^
>> drivers/pinctrl/nuvoton/pinctrl-ma35d1.c:1791:9: error: implicit declaration of function 'platform_driver_register' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
           return platform_driver_register(&ma35d1_pinctrl_driver);
                  ^
   2 warnings and 3 errors generated.

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for ADB_CUDA
   Depends on [n]: MACINTOSH_DRIVERS [=n] && (ADB [=n] || PPC_PMAC [=y]) && !PPC_PMAC64 [=n]
   Selected by [y]:
   - PPC_PMAC [=y] && PPC_BOOK3S [=y] && CPU_BIG_ENDIAN [=y] && POWER_RESET [=y] && PPC32 [=y]


vim +/platform_driver_register +1791 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c

  1788	
  1789	static int __init ma35d1_pinctrl_init(void)
  1790	{
> 1791		return platform_driver_register(&ma35d1_pinctrl_driver);
  1792	}
  1793	arch_initcall(ma35d1_pinctrl_init);
  1794	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From jszhang at kernel.org  Sat Feb 10 23:01:15 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sun, 11 Feb 2024 15:01:15 +0800
Subject: [PATCH] ARM: iwmmxt: Remove support for PJ4/PJ4B cores
In-Reply-To: <0bc7c97c-6549-4ae1-9787-4702e7ab737e@app.fastmail.com>
References: <20240209110901.4032939-2-ardb+git@google.com>
 <0bc7c97c-6549-4ae1-9787-4702e7ab737e@app.fastmail.com>
Message-ID: <Zchwu2OqHLvEIgln@xhacker>

On Fri, Feb 09, 2024 at 03:27:02PM +0100, Arnd Bergmann wrote:
> On Fri, Feb 9, 2024, at 12:09, Ard Biesheuvel wrote:
> > From: Ard Biesheuvel <ardb at kernel.org>
> >
> > PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
> > does not support this combination (its iWMMXt configuration always
> > implies v5te), and so there is no v6/v7 user space that actually makes
> > use of this, beyond generic support for things like setjmp() that
> > preserve/restore the iWMMXt register file using generic LDC/STC
> > instructions emitted in assembler. As [0] appears to imply, this logic
> > is triggered for the init process at boot, and so most processes will
> > have a iWMMXt register context associated with it, even though it is
> > never used.
> >
> > This means that advertising iWMMXt support on these cores results in
> > context switch overhead without any associated benefit, and so it is
> > better to simply ignore the iWMMXt unit on these systems. So rip out the
> > support. Doing so also fixes the issue reported in [0] related to UNDEF
> > handling of co-processor #0/#1 instructions issued from user space
> > running in Thumb2 mode.
> >
> > Cc: Arnd Bergmann <arnd at arndb.de>
> > Cc: Nicolas Pitre <nico at fluxnic.net>
> > Cc: Russell King <linux at armlinux.org.uk>
> > Cc: Linus Walleij <linus.walleij at linaro.org>
> > Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
> > Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> 
> Acked-by: Arnd Bergmann <arnd at arndb.de>

For berlin SoC

Reviewed-by: Jisheng Zhang <jszhang at kernel.org>
> 
> Maybe add a bit about which cores are actually affected by this:
> 
> The PJ4 cores are used in four platforms: armada 370/xp, dove
> (cubox, d2plug), mmp2 (xo-1.75) and berlin (chromecast 1).

Per berlin2cd.dtsi, chromecast is powered by CA9 ;)

> Out of these, only the first is still widely used, but that
> one actually doesn't have iwmmxt but instead has only
> vfpv3-d16.
> 
> I've also added the maintainers of those platforms to Cc,
> in case anyone has objections after all.
> 
>       Arnd


From jernej.skrabec at gmail.com  Sat Feb 10 23:14:59 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Sun, 11 Feb 2024 08:14:59 +0100
Subject: [PATCH 1/2] arm64: dts: allwinner: use capital "OR" for multiple licenses
 in SPDX
In-Reply-To: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>
References: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>
Message-ID: <2720166.mvXUDI8C0e@jernej-laptop>

Dne ?etrtek, 08. februar 2024 ob 11:53:00 CET je Krzysztof Kozlowski napisal(a):
> Documentation/process/license-rules.rst and checkpatch expect the SPDX
> identifier syntax for multiple licenses to use capital "OR".  Correct it
> to keep consistent format and avoid copy-paste issues.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Acked-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From jernej.skrabec at gmail.com  Sat Feb 10 23:15:10 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Sun, 11 Feb 2024 08:15:10 +0100
Subject: [PATCH 2/2] arm64: dts: allwinner: h616: minor whitespace cleanup
In-Reply-To: <20240208105301.129005-2-krzysztof.kozlowski@linaro.org>
References: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>
 <20240208105301.129005-2-krzysztof.kozlowski@linaro.org>
Message-ID: <5754939.DvuYhMxLoT@jernej-laptop>

Dne ?etrtek, 08. februar 2024 ob 11:53:01 CET je Krzysztof Kozlowski napisal(a):
> The DTS code coding style expects exactly one space before '{'
> character.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Acked-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From jszhang at kernel.org  Sun Feb 11 00:17:38 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sun, 11 Feb 2024 16:17:38 +0800
Subject: [PATCH v3 1/2] dt-bindings: arm: sunxi: Add Sipeed Longan Module 3H and Longan Pi 3H
In-Reply-To: <20240211081739.395-1-jszhang@kernel.org>
References: <20240211081739.395-1-jszhang@kernel.org>
Message-ID: <20240211081739.395-2-jszhang@kernel.org>

Add name & compatible for the Sipeed Longan Module 3H and Longan PI 3H
board.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
---
 Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index a9d8e85565b8..a97d44ba10ac 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -835,6 +835,12 @@ properties:
           - const: sinlinx,sina33
           - const: allwinner,sun8i-a33
 
+      - description: Sipeed Longan Pi 3H board for the Sipeed Longan Module 3H
+        items:
+          - const: sipeed,longan-pi-3h
+          - const: sipeed,longan-module-3h
+          - const: allwinner,sun50i-h618
+
       - description: SourceParts PopStick v1.1
         items:
           - const: sourceparts,popstick-v1.1
-- 
2.43.0



From jszhang at kernel.org  Sun Feb 11 00:17:39 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sun, 11 Feb 2024 16:17:39 +0800
Subject: [PATCH v3 2/2] arm64: dts: allwinner: h616: Add Sipeed Longan SoM 3H and Pi 3H board support
In-Reply-To: <20240211081739.395-1-jszhang@kernel.org>
References: <20240211081739.395-1-jszhang@kernel.org>
Message-ID: <20240211081739.395-3-jszhang@kernel.org>

The Sipeed Longan SoM 3H is a system on module based on the Allwinner
H618 SoC. The SoM features:

- Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
- 2/4 GiB LPDDR4 DRAM SoMs
- AXP313a PMIC
- eMMC

The Sipeed Longan PI 3H is a development board based on the above SoM.
The board features:
- Longan SoM 3H
- Raspberry-Pi-1 compatible GPIO header
- 2 USB 2.0 host port
- 1 USB 2.0 type C port (power supply + OTG)
- MicroSD slot
- 1Gbps Ethernet port (via RTL8211 PHY)
- HDMI port
- WiFi/BT chip

Add the devicetree file describing the currently supported features,
namely PMIC, LEDs, UART, SD card, eMMC, USB and Ethernet.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../sun50i-h618-longan-module-3h.dtsi         |  75 +++++++++
 .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 144 ++++++++++++++++++
 3 files changed, 220 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 91d505b385de..4b9173a16efe 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -42,5 +42,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
new file mode 100644
index 000000000000..8c1263a3939e
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
+ */
+
+#include "sun50i-h616.dtsi"
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins>;
+	vmmc-supply = <&reg_dldo1>;
+	vqmmc-supply = <&reg_aldo1>;
+	bus-width = <8>;
+	non-removable;
+	cap-mmc-hw-reset;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	status = "okay";
+};
+
+&r_i2c {
+	status = "okay";
+
+	axp313: pmic at 36 {
+		compatible = "x-powers,axp313a";
+		reg = <0x36>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+
+		regulators {
+			reg_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc-1v8-pll";
+			};
+
+			reg_dldo1: dldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-3v3-io";
+			};
+
+			reg_dcdc1: dcdc1 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <990000>;
+				regulator-name = "vdd-gpu-sys";
+			};
+
+			reg_dcdc2: dcdc2 {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-cpu";
+			};
+
+			reg_dcdc3: dcdc3 {
+				regulator-always-on;
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-name = "vdd-dram";
+			};
+		};
+	};
+};
+
+&pio {
+	vcc-pc-supply = <&reg_dldo1>;
+	vcc-pf-supply = <&reg_dldo1>;
+	vcc-pg-supply = <&reg_aldo1>;
+	vcc-ph-supply = <&reg_dldo1>;
+	vcc-pi-supply = <&reg_dldo1>;
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
new file mode 100644
index 000000000000..18b29c6b867f
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h618-longan-module-3h.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "Sipeed Longan Pi 3H";
+	compatible = "sipeed,longan-pi-3h", "sipeed,longan-module-3h", "allwinner,sun50i-h618";
+
+	aliases {
+		ethernet0 = &emac0;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			color = <LED_COLOR_ID_ORANGE>;
+			function = LED_FUNCTION_INDICATOR;
+			function-enumerator = <0>;
+			gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */
+		};
+
+		led-1 {
+			color = <LED_COLOR_ID_ORANGE>;
+			function = LED_FUNCTION_INDICATOR;
+			function-enumerator = <1>;
+			gpios = <&pio 6 4 GPIO_ACTIVE_LOW>; /* PG4 */
+		};
+	};
+
+	reg_vcc5v: regulator-vcc5v {
+		/* board wide 5V supply directly from the USB-C socket */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	reg_vcc3v3: regulator-vcc3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		vin-supply = <&reg_vcc5v>;
+	};
+};
+
+&axp313 {
+	vin1-supply = <&reg_vcc5v>;
+	vin2-supply = <&reg_vcc5v>;
+	vin3-supply = <&reg_vcc5v>;
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&ehci2 {
+	status = "okay";
+};
+
+&ohci2 {
+	status = "okay";
+};
+
+/* WiFi & BT combo module is connected to this Host */
+&ehci3 {
+	status = "okay";
+};
+
+&ohci3 {
+	status = "okay";
+};
+
+&emac0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ext_rgmii_pins>;
+	phy-mode = "rgmii";
+	phy-handle = <&ext_rgmii_phy>;
+	allwinner,rx-delay-ps = <3100>;
+	allwinner,tx-delay-ps = <700>;
+	phy-supply = <&reg_vcc3v3>;
+	status = "okay";
+};
+
+&mdio0 {
+	ext_rgmii_phy: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <1>;
+	};
+};
+
+&mmc0 {
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;	/* PF6 */
+	vmmc-supply = <&reg_vcc3v3>;
+	status = "okay";
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&usbotg {
+	/*
+	 * PHY0 pins are connected to a USB-C socket, but a role switch
+	 * is not implemented: both CC pins are pulled to GND.
+	 * The VBUS pins power the device, so a fixed peripheral mode
+	 * is the best choice.
+	 * The board can be powered via GPIOs, in this case port0 *can*
+	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
+	 * then provided by the GPIOs. Any user of this setup would
+	 * need to adjust the DT accordingly: dr_mode set to "host",
+	 * enabling OHCI0 and EHCI0.
+	 */
+	dr_mode = "peripheral";
+	status = "okay";
+};
+
+&usbphy {
+	usb1_vbus-supply = <&reg_vcc5v>;
+	usb2_vbus-supply = <&reg_vcc5v>;
+	status = "okay";
+};
-- 
2.43.0



From jszhang at kernel.org  Sun Feb 11 00:17:37 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sun, 11 Feb 2024 16:17:37 +0800
Subject: [PATCH v3 0/2] arm64: dts: allwinner: h618: Add Sipeed Longan SoM 3H and Pi 3H board
Message-ID: <20240211081739.395-1-jszhang@kernel.org>

Add Sipeed Longan SoM 3H and Longan Pi 3H board support.

The Sipeed Longan SoM 3H is a system on module based on the Allwinner
H618 SoC. The SoM features:

- Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
- 2/4 GiB LPDDR4 DRAM SoMs
- AXP313a PMIC
- eMMC

The Sipeed Longan PI 3H is a development board based on the above SoM.
The board features:
- Longan SoM 3H
- Raspberry-Pi-1 compatible GPIO header
- 2 USB 2.0 host port
- 1 USB 2.0 type C port (power supply + OTG)
- MicroSD slot
- 1Gbps Ethernet port (via RTL8211 PHY)
- HDMI port
- WiFi/BT chip

Since v2:
  - collect Reviewed-by tag
  - add vin-supply property to reg_vcc3v3
  - fix reg_vcc3v3 voltage value
  - remove "interrupt-parent" and "interrupts" properties from axp313
    node

Since v1:
  - Use const rather than enum for "sipeed,longan-pi-3h" dt-binding
  - remove dts-v1, model and compatible from SoM dtsi
  - add interrupt related properties to axp313 dt node
  - use "vcc-1v8-pll" and "vcc-3v3-io" as regulator name
  - add dt node for board's discrete 5V->3.3V regulator and use it for
    eth\tfcard 3.3v supply
  - add usb2_vbus-supply property


Jisheng Zhang (2):
  dt-bindings: arm: sunxi: Add Sipeed Longan Module 3H and Longan Pi 3H
  arm64: dts: allwinner: h616: Add Sipeed Longan SoM 3H and Pi 3H board
    support

 .../devicetree/bindings/arm/sunxi.yaml        |   6 +
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../sun50i-h618-longan-module-3h.dtsi         |  75 +++++++++
 .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 144 ++++++++++++++++++
 4 files changed, 226 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts

-- 
2.43.0



From swboyd at chromium.org  Sun Feb 11 00:52:28 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Sun, 11 Feb 2024 03:52:28 -0500
Subject: [PATCH 14/22] platform/chrome: cros_typec_switch: Add support for
 signaling HPD to drm_bridge
In-Reply-To: <CAA8EJpo1g9QKq1skibqSj9yc3mNSfkcts9oVf_vGjVjDzVZwiA@mail.gmail.com>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-15-swboyd@chromium.org>
 <CAA8EJpo1g9QKq1skibqSj9yc3mNSfkcts9oVf_vGjVjDzVZwiA@mail.gmail.com>
Message-ID: <CAE-0n50xu83yYoXoFYEDrkuMw_exS=UGqsU+EwtTOGZyNW+k=Q@mail.gmail.com>

Quoting Dmitry Baryshkov (2024-02-10 06:10:31)
> On Sat, 10 Feb 2024 at 09:14, Stephen Boyd <swboyd at chromium.org> wrote:
> > diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
> > index 769de2889f2f..d8fb6662cf8d 100644
> > --- a/drivers/platform/chrome/cros_typec_switch.c
> > +++ b/drivers/platform/chrome/cros_typec_switch.c
> > @@ -18,6 +19,15 @@
> >  #include <linux/usb/typec_mux.h>
> >  #include <linux/usb/typec_retimer.h>
> >
> > +#include <drm/drm_bridge.h>
> > +#include <drm/drm_print.h>
> > +
> > +struct cros_typec_dp_bridge {
> > +       struct cros_typec_switch_data *sdata;
> > +       bool hpd_enabled;
> > +       struct drm_bridge bridge;
> > +};
>
> Is there any chance that you can use drm_dp_hpd_bridge_register() /
> drm_aux_hpd_bridge_notify() instead of implementing another
> drm_bridge?
> If something is missing from the existing implementation we can
> probably work that out.

Yeah I think that can work. I had put the drm_bridge in this driver
because I needed a 'struct device' per DP phy, but I think that problem
goes away with an auxiliary device, so that is nicely solved.

I'll have to add logic about typec ports to that auxiliary driver
though, like mapping data-lanes and handling lane assignments. And then
I'll move this code from the cros_typec_switch driver to the
cros_ec_typec driver so it can be called outside of the typec mux set
path. That's probably better because it's sort of bolted on to the
cros_typec_switch driver. We'll need to know if the DP phy needs to
handle orientation or if the EC is doing that somehow, so probably I'll
need to add a DT property to the google,cros-ec-typec binding to
indicate that orientation control is needed.

It looks like I should add a new auxiliary device, like
'dp_typec_bridge', and have some other function like
drm_dp_typec_bridge_register() for that. I can wrap the 'struct
drm_aux_hpd_bridge_data' with a 'struct drm_aux_typec_bridge_data' and
then the typec port information can live there. HPD can still be
signaled with drm_aux_hpd_bridge_notify() but other functions can be
used to set the active typec port, e.g.
drm_aux_typec_bridge_set_active_port(), and then get orientation with
typec_get_orientation() in the atomic_check().


From dmitry.baryshkov at linaro.org  Sun Feb 11 01:00:28 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sun, 11 Feb 2024 11:00:28 +0200
Subject: [PATCH 14/22] platform/chrome: cros_typec_switch: Add support for
 signaling HPD to drm_bridge
In-Reply-To: <CAE-0n50xu83yYoXoFYEDrkuMw_exS=UGqsU+EwtTOGZyNW+k=Q@mail.gmail.com>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-15-swboyd@chromium.org>
 <CAA8EJpo1g9QKq1skibqSj9yc3mNSfkcts9oVf_vGjVjDzVZwiA@mail.gmail.com> <CAE-0n50xu83yYoXoFYEDrkuMw_exS=UGqsU+EwtTOGZyNW+k=Q@mail.gmail.com>
Message-ID: <CAA8EJpp7NW0nT5vWdZcQ+A9GjreO9b20wfFBBnOZe6E6GcTNYg@mail.gmail.com>

On Sun, 11 Feb 2024 at 10:52, Stephen Boyd <swboyd at chromium.org> wrote:
>
> Quoting Dmitry Baryshkov (2024-02-10 06:10:31)
> > On Sat, 10 Feb 2024 at 09:14, Stephen Boyd <swboyd at chromium.org> wrote:
> > > diff --git a/drivers/platform/chrome/cros_typec_switch.c b/drivers/platform/chrome/cros_typec_switch.c
> > > index 769de2889f2f..d8fb6662cf8d 100644
> > > --- a/drivers/platform/chrome/cros_typec_switch.c
> > > +++ b/drivers/platform/chrome/cros_typec_switch.c
> > > @@ -18,6 +19,15 @@
> > >  #include <linux/usb/typec_mux.h>
> > >  #include <linux/usb/typec_retimer.h>
> > >
> > > +#include <drm/drm_bridge.h>
> > > +#include <drm/drm_print.h>
> > > +
> > > +struct cros_typec_dp_bridge {
> > > +       struct cros_typec_switch_data *sdata;
> > > +       bool hpd_enabled;
> > > +       struct drm_bridge bridge;
> > > +};
> >
> > Is there any chance that you can use drm_dp_hpd_bridge_register() /
> > drm_aux_hpd_bridge_notify() instead of implementing another
> > drm_bridge?
> > If something is missing from the existing implementation we can
> > probably work that out.
>
> Yeah I think that can work. I had put the drm_bridge in this driver
> because I needed a 'struct device' per DP phy, but I think that problem
> goes away with an auxiliary device, so that is nicely solved.
>
> I'll have to add logic about typec ports to that auxiliary driver
> though, like mapping data-lanes and handling lane assignments. And then
> I'll move this code from the cros_typec_switch driver to the
> cros_ec_typec driver so it can be called outside of the typec mux set
> path. That's probably better because it's sort of bolted on to the
> cros_typec_switch driver. We'll need to know if the DP phy needs to
> handle orientation or if the EC is doing that somehow, so probably I'll
> need to add a DT property to the google,cros-ec-typec binding to
> indicate that orientation control is needed.

I still haven't fully got into your usage of data-lanes. I hope to be
able to comment on that part and on the ports / endpoints tomorrow.

>
> It looks like I should add a new auxiliary device, like
> 'dp_typec_bridge', and have some other function like
> drm_dp_typec_bridge_register() for that. I can wrap the 'struct
> drm_aux_hpd_bridge_data' with a 'struct drm_aux_typec_bridge_data' and
> then the typec port information can live there. HPD can still be
> signaled with drm_aux_hpd_bridge_notify() but other functions can be
> used to set the active typec port, e.g.
> drm_aux_typec_bridge_set_active_port(), and then get orientation with
> typec_get_orientation() in the atomic_check().



-- 
With best wishes
Dmitry


From erick.archer at gmx.com  Sun Feb 11 01:16:33 2024
From: erick.archer at gmx.com (Erick Archer)
Date: Sun, 11 Feb 2024 10:16:33 +0100
Subject: [PATCH v2] mtd: rawnand: Prefer struct_size over open coded arithmetic
Message-ID: <20240211091633.4545-1-erick.archer@gmx.com>

This is an effort to get rid of all multiplications from allocation
functions in order to prevent integer overflows [1].

As the "chip" variable is a pointer to "struct mtk_nfc_nand_chip" and
this structure ends in a flexible array:

struct mtk_nfc_nand_chip {
	[...]
	u8 sels[] __counted_by(nsels);
};

the preferred way in the kernel is to use the struct_size() helper to
do the arithmetic instead of the argument "size + count * size" in the
devm_kzalloc() function.

This way, the code is more readable and safer.

Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
Link: https://github.com/KSPP/linux/issues/160 [2]
Reviewed-by: Gustavo A. R. Silva <gustavoars at kernel.org>
Signed-off-by: Erick Archer <erick.archer at gmx.com>
---
Changes in v2:
- Add the "Reviewed-by:" tag.
- Fix a spelling error in the commit message. Change "more safer" for
  "safer" (Uwe Kleine-K?nig)
---
 drivers/mtd/nand/raw/mtk_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
index 60198e33d2d5..17477bb2d48f 100644
--- a/drivers/mtd/nand/raw/mtk_nand.c
+++ b/drivers/mtd/nand/raw/mtk_nand.c
@@ -1356,7 +1356,7 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
 		return -EINVAL;
 	}

-	chip = devm_kzalloc(dev, sizeof(*chip) + nsels * sizeof(u8),
+	chip = devm_kzalloc(dev, struct_size(chip, sels, nsels),
 			    GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
--
2.25.1



From arnd at arndb.de  Sun Feb 11 02:21:34 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Sun, 11 Feb 2024 11:21:34 +0100
Subject: [PATCH] ARM: iwmmxt: Remove support for PJ4/PJ4B cores
In-Reply-To: <Zchwu2OqHLvEIgln@xhacker>
References: <20240209110901.4032939-2-ardb+git@google.com>
 <0bc7c97c-6549-4ae1-9787-4702e7ab737e@app.fastmail.com>
 <Zchwu2OqHLvEIgln@xhacker>
Message-ID: <970a39e9-913f-43c9-8f0d-189e0532401d@app.fastmail.com>

On Sun, Feb 11, 2024, at 08:01, Jisheng Zhang wrote:
> On Fri, Feb 09, 2024 at 03:27:02PM +0100, Arnd Bergmann wrote:
>>
>> Maybe add a bit about which cores are actually affected by this:
>> 
>> The PJ4 cores are used in four platforms: armada 370/xp, dove
>> (cubox, d2plug), mmp2 (xo-1.75) and berlin (chromecast 1).
>
> Per berlin2cd.dtsi, chromecast is powered by CA9 ;)

Right, I confused it with the one in the Google TV, had
not realized these were actually different variants of that
chip.

     Arnd


From xtex at envs.net  Sun Feb 11 02:31:36 2024
From: xtex at envs.net (xtex)
Date: Sun, 11 Feb 2024 18:31:36 +0800
Subject: [PATCH 1/2] kbuild: Abort make on install failures
In-Reply-To: <CAK7LNAQPm7PXoKM+id25wX9AtVmmXvE7i8GrGB9etU__EMUwdg@mail.gmail.com>
References: <20240210074601.5363-1-xtex@envs.net> <ZcfoZKJHkdEh5JmV@fjasle.eu>
 <CAK7LNAQPm7PXoKM+id25wX9AtVmmXvE7i8GrGB9etU__EMUwdg@mail.gmail.com>
Message-ID: <2646117.S0smAIiGLA@xtex>

On Sunday, February 11, 2024 7:35:35 AM CST Masahiro Yamada wrote:
> 
> The separate 'set -e' statement works for both cases,
> so I think this is safer, though it is kind of bike-shedding.

Thanks!
I also think it is safer to use 'set -e' in the case of 'sh install.sh',
 so I support not to use 'sh -e' in the shebang line. The planned V2 patch for 
this disappeared.

-- 
Zhang Bingwu @ Sun Feb 11 10:27:48 AM UTC 2024





From andrej.skvortzov at gmail.com  Sun Feb 11 02:53:26 2024
From: andrej.skvortzov at gmail.com (Andrey Skvortsov)
Date: Sun, 11 Feb 2024 13:53:26 +0300
Subject: [PATCH] arm64: dts: allwinner: a64: Add thermal trip points for GPU
Message-ID: <20240211105326.506049-1-andrej.skvortzov@gmail.com>

From: Alexey Klimov <alexey.klimov at linaro.org>

Without trip points for GPU, the following errors are printed in the
dmesg log and the sun8i-thermal driver fails to load:

thermal_sys: Failed to find 'trips' node
thermal_sys: Failed to find trip points for thermal-sensor id=1
sun8i-thermal: probe of 1c25000.thermal-sensor failed with error -22

When thermal zones are defined, trip points definitions are mandatory.
Trip values for the GPU are assumed to be the same values as the CPU
ones. The available specs do not provide any hints about thermal regimes
for the GPU and it seems GPU is implemented on the same die as the CPU.

'make dtbs_check' complains about problem in dts for 18 A64-based boards
supported by the kernel:

sun50i-a64-pine64.dtb: thermal-zones: gpu0-thermal: 'trips' is a required property
	from schema $id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#
sun50i-a64-pine64.dtb: thermal-zones: gpu1-thermal: 'trips' is a required property
	from schema $id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#

Tested on Pine a64+ and PinePhone 1.2.

Cc: Samuel Holland <samuel at sholland.org>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: Chen-Yu Tsai <wens at csie.org>
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: devicetree at vger.kernel.org
Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
Tested-by: Andrey Skvortsov <andrej.skvortzov at gmail.com>

---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 57ac18738c99..c25da7229e42 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -244,6 +244,29 @@ gpu0_thermal: gpu0-thermal {
 			polling-delay-passive = <0>;
 			polling-delay = <0>;
 			thermal-sensors = <&ths 1>;
+
+			trips {
+				gpu0_alert0: gpu0_alert0 {
+					/* milliCelsius */
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				gpu0_alert1: gpu0_alert1 {
+					/* milliCelsius */
+					temperature = <90000>;
+					hysteresis = <2000>;
+					type = "hot";
+				};
+
+				gpu0_crit: gpu0_crit {
+					/* milliCelsius */
+					temperature = <110000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
 		};
 
 		gpu1_thermal: gpu1-thermal {
@@ -251,6 +274,29 @@ gpu1_thermal: gpu1-thermal {
 			polling-delay-passive = <0>;
 			polling-delay = <0>;
 			thermal-sensors = <&ths 2>;
+
+			trips {
+				gpu1_alert0: gpu1_alert0 {
+					/* milliCelsius */
+					temperature = <75000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				gpu1_alert1: gpu1_alert1 {
+					/* milliCelsius */
+					temperature = <90000>;
+					hysteresis = <2000>;
+					type = "hot";
+				};
+
+				gpu1_crit: gpu1_crit {
+					/* milliCelsius */
+					temperature = <110000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
 		};
 	};
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Sun Feb 11 03:51:21 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Sun, 11 Feb 2024 12:51:21 +0100
Subject: [PATCH v2] mtd: rawnand: Prefer struct_size over open coded
 arithmetic
In-Reply-To: <20240211091633.4545-1-erick.archer@gmx.com>
References: <20240211091633.4545-1-erick.archer@gmx.com>
Message-ID: <rep3323evfhxh5ctmyd2biqrpg2ifej2jei5rsqpei7vuvnmsc@krh3gihuyoox>

On Sun, Feb 11, 2024 at 10:16:33AM +0100, Erick Archer wrote:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> As the "chip" variable is a pointer to "struct mtk_nfc_nand_chip" and
> this structure ends in a flexible array:
> 
> struct mtk_nfc_nand_chip {
> 	[...]
> 	u8 sels[] __counted_by(nsels);
> };
> 
> the preferred way in the kernel is to use the struct_size() helper to
> do the arithmetic instead of the argument "size + count * size" in the
> devm_kzalloc() function.
> 
> This way, the code is more readable and safer.
> 
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
> Link: https://github.com/KSPP/linux/issues/160 [2]
> Reviewed-by: Gustavo A. R. Silva <gustavoars at kernel.org>
> Signed-off-by: Erick Archer <erick.archer at gmx.com>

Acked-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

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/20240211/c3cd6b01/attachment.sig>

From muchun.song at linux.dev  Sun Feb 11 03:59:40 2024
From: muchun.song at linux.dev (Muchun Song)
Date: Sun, 11 Feb 2024 19:59:40 +0800
Subject: [PATCH v3 0/3] A Solution to Re-enable hugetlb vmemmap optimize
In-Reply-To: <ZcT4DH7VE1XLBvVc@casper.infradead.org>
References: <20240113094436.2506396-1-sunnanyong@huawei.com>
 <ZbKjHHeEdFYY1xR5@arm.com> <d1671959-74a4-8ea5-81f0-539df8d9c0f0@huawei.com>
 <20240207111252.GA22167@willie-the-truck>
 <ZcNnrdlb3fe0kGHK@casper.infradead.org>
 <20240207121125.GA22234@willie-the-truck>
 <ZcOQ-0pzA16AEbct@casper.infradead.org>
 <908066c7-b749-4f95-b006-ce9b5bd1a909@oracle.com>
 <ZcT4DH7VE1XLBvVc@casper.infradead.org>
Message-ID: <917FFC7F-0615-44DD-90EE-9F85F8EA9974@linux.dev>



> On Feb 8, 2024, at 23:49, Matthew Wilcox <willy at infradead.org> wrote:
> 
> On Wed, Feb 07, 2024 at 06:24:52PM -0800, Jane Chu wrote:
>> On 2/7/2024 6:17 AM, Matthew Wilcox wrote:
>>> While this array of ~512 pages have been allocated to hugetlbfs, and one
>>> would think that there would be no way that there could still be
>>> references to them, another CPU can have a pointer to this struct page
>>> (eg attempting a speculative page cache reference or
>>> get_user_pages_fast()).  That means it will try to call
>>> atomic_add_unless(&page->_refcount, 1, 0);
>>> 
>>> Actually, I wonder if this isn't a problem on x86 too?  Do we need to
>>> explicitly go through an RCU grace period before freeing the pages
>>> for use by somebody else?
>>> 
>> Sorry, not sure what I'm missing, please help.
> 
> Having written out the analysis, I now think it can't happen on x86,
> but let's walk through it because it's non-obvious (and I think it
> illustrates what people are afraid of on Arm).
> 
> CPU A calls either get_user_pages_fast() or __filemap_get_folio().
> Let's do the latter this time.
> 
>        folio = filemap_get_entry(mapping, index);
> filemap_get_entry:
>        rcu_read_lock();
>        folio = xas_load(&xas);
>        if (!folio_try_get_rcu(folio))
>                goto repeat;
>        if (unlikely(folio != xas_reload(&xas))) {
>                folio_put(folio);
>                goto repeat;
>        }
> folio_try_get_rcu:
>        folio_ref_try_add_rcu(folio, 1);
> folio_ref_try_add_rcu:
>        if (unlikely(!folio_ref_add_unless(folio, count, 0))) {
>                /* Either the folio has been freed, or will be freed. */
>                return false;
> folio_ref_add_unless:
>        return page_ref_add_unless(&folio->page, nr, u);
> page_ref_add_unless:
>        atomic_add_unless(&page->_refcount, nr, u);
> 
> A rather deep callchain there, but for our purposes the important part
> is: we take the RCU read lock, we look up a folio, we increment its
> refcount if it's not zero, then check that looking up this index gets
> the same folio; if it doesn't, we decrement the refcount again and retry
> the lookup.
> 
> For this analysis, we can be preempted at any point after we've got the
> folio pointer from xa_load().
> 
>> From hugetlb allocation perspective,  one of the scenarios is run time
>> hugetlb page allocation (say 2M pages), starting from the buddy allocator
>> returns compound pages, then the head page is set to frozen, then the
>> folio(compound pages) is put thru the HVO process, one of which is
>> vmemmap_split_pmd() in case a vmemmap page is a PMD page.
>> 
>> Until the HVO process completes, none of the vmemmap represented pages are
>> available to any threads, so what are the causes for IRQ threads to access
>> their vmemmap pages?
> 
> Yup, this sounds like enough, but it's not.  The problem is the person
> who's looking up the folio in the pagecache under RCU.  They've got
> the folio pointer and have been preempted.  So now what happens to our
> victim folio?
> 
> Something happens to remove it from the page cache.  Maybe the file is
> truncated, perhaps vmscan comes along and kicks it out.  Either way, it's
> removed from the xarray and gets its refcount set to 0.  If the lookup
> were to continue at this time, everything would be fine because it would
> see a refcount of 0 and not increment it (in page_ref_add_unless()).
> And this is where my analysis of RCU tends to go wrong, because I only
> think of interleaving event A and B.  I don't think about B and then C
> happening before A resumes.  But it can!  Let's follow the journey of
> this struct page.
> 
> Now that it's been removed from the page cache, it's allocated by hugetlb,
> as you describe.  And it's one of the tail pages towards the end of
> the 512 contiguous struct pages.  That means that we alter vmemmap so
> that the pointer to struct page now points to a different struct page
> (one of the earlier ones).  Then the original page of vmemmap containing
> our lucky struct page is returned to the page allocator.  At this point,
> it no longer contains struct pages; it can contain literally anything.
> 
> Where my analysis went wrong was that CPU A _no longer has a pointer
> to it_.  CPU A has a pointer into vmemmap.  So it will access the
> replacement struct page (which definitely has a refcount 0) instead of
> the one which has been freed.  I had thought that CPU A would access the
> original memory which has now been allocated to someone else.  But no,
> it can't because its pointer is virtual, not physical.
> 
> 
> ---
> 
> Now I'm thinking more about this and there's another scenario which I
> thought might go wrong, and doesn't.  For 7 of the 512 pages which are
> freed, the struct page pointer gathered by CPU A will not point to a
> page with a refcount of 0.  Instead it will point to an alias of the
> head page with a positive refcount.  For those pages, CPU A will see
> folio_try_get_rcu() succeed.  Then it will call xas_reload() and see
> the folio isn't there any more, so it will call folio_put() on something
> which used to be a folio, and isn't any more.
> 
> But folio_put() calls folio_put_testzero() which calls put_page_testzero()
> without asserting that the pointer is actually to a folio.
> So everything's fine, but really only by coincidence; I don't think
> anybody's thought about this scenario before (maybe Muchun has, but I
> don't remember it being discussed).

I have to say it is a really great analysis, I haven't thought about the
case of get_page_unless_zero() so deeply.

To avoid increasing a refcount to a tail page struct, I have made
all the 7 tail pages read-only when I first write those code. But it
is a really problem, because it will panic (due to RO permission)
when encountering the above scenario to increase its refcount.

In order to fix the race with __filemap_get_folio(), my first
thought of fixing this issue is to add a rcu_synchronize() after
the processing of HVO optimization and before being allocated to
users. Note that HugePage pages are frozen before going through
the precessing of HVO optimization meaning all the refcount of all
the struct pages are 0. Therefore, folio_try_get_rcu() in
__filemap_get_folio() will fail unless the HugeTLB page has been
allocated to the user.

But I realized there are some users who may pass a arbitrary
page struct (which may be those 7 special tail page structs,
alias of the head page struct, of a HugeTLB page) to the following
helpers, which also could get a refcount of a tail page struct.
Those helpers also need to be fixed.

  1) get_page_unless_zero
  2) folio_try_get
  3) folio_try_get_rcu

I have checked all the users of 1), If I am not wrong, all the users
already handle the HugeTLB pages before calling to get_page_unless_zero().
Although there is no problem with 1) now, it will be fragile to let users
guarantee that it will not pass any tail pages of a HugeTLB page to
1). So I want to change 1) to the following to fix this.

	static inline bool get_page_unless_zero(struct page *page)
	{
		if (page_ref_add_unless(page, 1, 0)) {
			/* @page must be a genuine head or alias head page here. */
			struct page *head = page_fixed_fake_head(page);

			if (likely(head == page))
				return true;
			put_page(head);
		}

		return false;
	}

2) and 3) should adopt the similar approach to make sure we cannot increase
tail pages' refcount. 2) and 3) will be like the following (only demonstrate
the key logic):

	static inline bool folio_try_get(struct folio *folio)/folio_ref_try_add_rcu
	{
		if (folio_ref_add_unless(folio, 1, 0)) {
			struct folio *genuine = page_folio(&folio->page);

			if (likely(genuine == folio))
				return true;
			folio_put(genuine);
		}

		return false;
	}

Additionally, we also should alter RO permission of those 7 tail pages
to RW to avoid panic().

There is no problem in the following helpers since all of them already
handle HVO case through _compound_head(), they will get the __genuine__
head page struct and increase its refcount.

  1) try_get_page
  2) folio_get
  3) get_page

Just some thoughts from mine, maybe you guys have more simple and graceful
approaches. Comments are welcome.

Muchun,
Thanks.



From krzysztof.kozlowski at linaro.org  Sun Feb 11 04:31:04 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 13:31:04 +0100
Subject: [PATCH v1 02/14] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240210012114.489102-3-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-3-sre@kernel.org>
Message-ID: <38e18310-4eba-4daa-b780-c719f38d3c5f@linaro.org>

On 10/02/2024 02:18, Sebastian Reichel wrote:
> Convert the i.MX  Wireless External Interface Module binding to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../devicetree/bindings/bus/fsl,imx-weim.yaml | 225 ++++++++++++++++++
>  .../devicetree/bindings/bus/imx-weim.txt      | 117 ---------
>  2 files changed, 225 insertions(+), 117 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
>  delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
> 
> diff --git a/Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml b/Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
> new file mode 100644
> index 000000000000..3d27bdaef304
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
> @@ -0,0 +1,225 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/bus/fsl,imx-weim.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: i.MX Wireless External Interface Module (WEIM)

This patchset does not do what I asked to, but maybe that's just
coincidence that you send conversion now.

To recall:

https://lore.kernel.org/all/cee1ca11-03bf-4a0b-9ff3-490457f9fbe8 at linaro.org/

> +
> +maintainers:
> +  - Shawn Guo <shawnguo at kernel.org>
> +  - Sascha Hauer <s.hauer at pengutronix.de>
> +
> +description:
> +  The term "wireless" does not imply that the WEIM is literally an interface
> +  without wires. It simply means that this module was originally designed for
> +  wireless and mobile applications that use low-power technology. The actual
> +  devices are instantiated from the child nodes of a WEIM node.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - enum:
> +          - fsl,imx1-weim
> +          - fsl,imx27-weim
> +          - fsl,imx50-weim
> +          - fsl,imx51-weim
> +          - fsl,imx6q-weim
> +      - items:
> +          - enum:
> +              - fsl,imx31-weim
> +              - fsl,imx35-weim
> +          - const: fsl,imx27-weim
> +      - items:
> +          - enum:
> +              - fsl,imx6sx-weim
> +              - fsl,imx6ul-weim
> +          - const: fsl,imx6q-weim
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  '#address-cells':
> +    const: 2
> +
> +  '#size-cells':
> +    const: 1
> +
> +  ranges: true
> +
> +  fsl,weim-cs-gpr:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: |
> +      Phandle to the system General Purpose Register controller that contains
> +      WEIM CS GPR register, e.g. IOMUXC_GPR1 on i.MX6Q. IOMUXC_GPR1[11:0]
> +      should be set up as one of the following 4 possible values depending on
> +      the CS space configuration.
> +
> +      IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
> +      ---------------------------------------------
> +              05          128M     0M     0M     0M
> +              033          64M    64M     0M     0M
> +              0113         64M    32M    32M     0M
> +              01111        32M    32M    32M    32M
> +
> +      In case that the property is absent, the reset value or what bootloader
> +      sets up in IOMUXC_GPR1[11:0] will be used.
> +
> +  fsl,burst-clk-enable:
> +    type: boolean
> +    description:
> +      The presence of this property indicates that the weim bus should operate
> +      in Burst Clock Mode.
> +
> +  fsl,continuous-burst-clk:
> +    type: boolean
> +    description:
> +      Make Burst Clock to output continuous clock. Without this option Burst
> +      Clock will output clock only when necessary.
> +
> +patternProperties:
> +  "^.*@[0-7],[0-9a-f]+$":
> +    description: Devices attached to chip selects are represented as subnodes.
> +    type: object
> +    additionalProperties: true
> +    properties:
> +      fsl,weim-cs-timing:
> +        $ref: /schemas/types.yaml#/definitions/uint32-array
> +        description:
> +          Timing values for the child node.
> +    required:
> +      - fsl,weim-cs-timing

You need to integrate it into mc-peripheral-props.yaml. Also check how
other bus controllers define children schema.


required: block goes here.

> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          not:
> +            contains:
> +              enum:
> +                - fsl,imx50-weim



Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 04:33:50 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 13:33:50 +0100
Subject: [PATCH v1 12/14] dt-bindings: vendor-prefixes: add UNI-T
In-Reply-To: <20240210012114.489102-13-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-13-sre@kernel.org>
Message-ID: <e086d382-299c-4b60-b8f7-0b13d92131c7@linaro.org>

On 10/02/2024 02:18, Sebastian Reichel wrote:
> Uni-Trend Technology is a manufacturer of measurement
> and testing tools.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 04:34:50 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 13:34:50 +0100
Subject: [PATCH v1 13/14] dt-bindings: arm: add UNI-T UTi260b
In-Reply-To: <20240210012114.489102-14-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-14-sre@kernel.org>
Message-ID: <f479f1c1-cf84-4738-8c6e-832869951b82@linaro.org>

On 10/02/2024 02:18, Sebastian Reichel wrote:
> Add compatible value for i.MX6ULL based UNI-T
> UTi260b thermal camera.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  Documentation/devicetree/bindings/arm/fsl.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
> index 228dcc5c7d6f..fa20c2699530 100644
> --- a/Documentation/devicetree/bindings/arm/fsl.yaml
> +++ b/Documentation/devicetree/bindings/arm/fsl.yaml
> @@ -708,6 +708,7 @@ properties:
>                - toradex,colibri-imx6ull      # Colibri iMX6ULL Modules
>                - toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module
>                - toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Modules
> +              - uni-t,imx6ull-uti260b   # UNI-T UTi260b

If the product name is "uti260b", then it is enough "uni-t,uti260b". If
you added the imx part because there is a SoM, then it is anyway not
correct representation of the SoM.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 04:39:29 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 13:39:29 +0100
Subject: [PATCH v1 05/14] dt-bindings: soc: imx: fsl,imx-anatop: add
 binding
In-Reply-To: <20240210012114.489102-6-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-6-sre@kernel.org>
Message-ID: <7e127492-f0ff-43d1-87f4-ad562604a836@linaro.org>

On 10/02/2024 02:18, Sebastian Reichel wrote:
> Add missing binding for i.MX anatop syscon.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../bindings/soc/imx/fsl,imx-anatop.yaml      | 125 ++++++++++++++++++
>  1 file changed, 125 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
> 
> diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
> new file mode 100644
> index 000000000000..436fdae1879e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
> @@ -0,0 +1,125 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/soc/imx/fsl,imx-anatop.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ANATOP register
> +
> +maintainers:
> +  - Shawn Guo <shawnguo at kernel.org>
> +  - Sascha Hauer <s.hauer at pengutronix.de>
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - enum:
> +              - fsl,imx6sl-anatop
> +              - fsl,imx6sll-anatop
> +              - fsl,imx6sx-anatop
> +              - fsl,imx6ul-anatop
> +              - fsl,imx7d-anatop
> +          - const: fsl,imx6q-anatop
> +          - const: syscon
> +          - const: simple-mfd
> +      - items:
> +          - const: fsl,imx6q-anatop
> +          - const: syscon
> +          - const: simple-mfd
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 3

You need to describe items instead (items: - description: ...)

> +
> +  tempmon:
> +    type: object
> +    unevaluatedProperties: false
> +    $ref: /schemas/thermal/imx-thermal.yaml

That's confusing. The imx-thermal has phandle to anatop and is a child
of it. Please sort it out, e.g. deprecate one way.

> +
> +patternProperties:
> +  "regulator-((3p0)|(vddcore)|(vddsoc))$":
> +    type: object
> +    unevaluatedProperties: false
> +    $ref: /schemas/regulator/anatop-regulator.yaml
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/imx6ul-clock.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    anatop: anatop at 20c8000 {
> +        compatible = "fsl,imx6ul-anatop", "fsl,imx6q-anatop",
> +                     "syscon", "simple-mfd";
> +        reg = <0x020c8000 0x1000>;
> +        interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
> +
> +        reg_3p0: regulator-3p0 {
> +            compatible = "fsl,anatop-regulator";
> +                regulator-name = "vdd3p0";

Messed indentation.



Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 04:46:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 13:46:26 +0100
Subject: [PATCH v1 04/14] dt-bindings: input: touchscreen: fsl,imx6ul-tsc
 convert to YAML
In-Reply-To: <20240210012114.489102-5-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-5-sre@kernel.org>
Message-ID: <2c2d8bee-e9c6-45db-a166-d344f7890e06@linaro.org>

On 10/02/2024 02:18, Sebastian Reichel wrote:
> Convert the i.MX6UL touchscreen DT binding to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---

...

> +
> +  interrupts:
> +    items:
> +      - description: touch controller address
> +      - description: ADC2 address
> +
> +  clocks:
> +    maxItems: 2
> +
> +  clock-names:
> +    items:
> +      - const: tsc
> +      - const: adc
> +
> +  xnur-gpio:

xnur-gpios:

Also you need:
maxItems: 1

> +    description:
> +      The X- gpio this controller connect to. This xnur-gpio returns to
> +      low once the finger leave the touch screen (The last touch event
> +      the touch controller capture).
> +
> +  measure-delay-time:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      The value of measure delay time. Before X-axis or Y-axis measurement,
> +      the screen need some time before even potential distribution ready.
> +    default: 0xffff
> +    minimum: 0
> +    maximum: 0xffffff

Time seems like something humans can grasp, so why using hexadecimal
numbers? Same question for pre-charge-time.


> +
> +  pre-charge-time:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      The touch screen need some time to precharge.
> +    default: 0xfff
> +    minimum: 0
> +    maximum: 0xffffffff
> +
> +  touchscreen-average-samples:
> +    description: Number of data samples which are averaged for each read.

This should fail the testing - judging by Rob's reports, you did not
test it. You don't have type for this property. Missing allOf: to
touchscreen.

> +    enum: [ 1, 4, 8, 16, 32 ]
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - xnur-gpio
> +


allOf: with $ref to touchscreen.

> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/imx6ul-clock.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +    tsc: tsc at 2040000 {

Drop label and just "touchscreen at 2040000"


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 04:47:23 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 13:47:23 +0100
Subject: [PATCH v1 06/14] dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add
 imx6
In-Reply-To: <20240210012114.489102-7-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-7-sre@kernel.org>
Message-ID: <bc73e76a-74da-4372-bb92-d52025b2b2aa@linaro.org>

On 10/02/2024 02:18, Sebastian Reichel wrote:
> Add compatibles used by different i.MX6 variants to the i.MX IOMUX
> Controller GPR binding.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml   | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
> index 1da1b758b4ae..6f229ffe20a5 100644
> --- a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
> +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
> @@ -16,6 +16,24 @@ description:
>  properties:
>    compatible:
>      oneOf:
> +      - items:
> +          - const: fsl,imx6q-iomuxc-gpr

Just change existing entry to enum and add it there.


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 04:48:05 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 13:48:05 +0100
Subject: [PATCH v1 07/14] dt-bindings: lcdif: Do not require power-domains
 for i.MX6ULL
In-Reply-To: <20240210012114.489102-8-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-8-sre@kernel.org>
Message-ID: <4671f082-c180-467a-8381-4f2ac31131b8@linaro.org>

On 10/02/2024 02:18, Sebastian Reichel wrote:
> i.MX6UL(L) uses "fsl,imx6sx-lcdif" as fallback compatible string,
> but has only very lightweight DISPLAY power domain. Its DISPLAY
> power domain is not supported by the binding / Linux kernel at
> the moment. Since the current setup is working, let's remove 


Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 04:48:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 13:48:26 +0100
Subject: [PATCH v1 08/14] dt-bindings: fsl-imx-sdma: fix HDMI audio index
In-Reply-To: <20240210012114.489102-9-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-9-sre@kernel.org>
Message-ID: <6312cdd5-ae58-4d6b-a89e-58a70a1ef5c4@linaro.org>

On 10/02/2024 02:18, Sebastian Reichel wrote:
> HDMI Audio has been added to the DT binding documentation with an
> incorrect index. DT and the driver use index 26. This happened,
> because the binding is missing MULTI_SAI type, which is using
> index 25.
> 
> Reported-by: Michael Yackavage <michaely at ips-yes.com>
> Fixes: 7bdbd87d4008 ("dt-bindings: fsl-imx-sdma: Convert imx sdma to DT schema")
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From andre.przywara at arm.com  Sun Feb 11 04:52:26 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun, 11 Feb 2024 12:52:26 +0000
Subject: [PATCH] arm64: dts: allwinner: a64: Add thermal trip points for
 GPU
In-Reply-To: <20240211105326.506049-1-andrej.skvortzov@gmail.com>
References: <20240211105326.506049-1-andrej.skvortzov@gmail.com>
Message-ID: <20240211125209.15d58462@minigeek.lan>

On Sun, 11 Feb 2024 13:53:26 +0300
Andrey Skvortsov <andrej.skvortzov at gmail.com> wrote:

Hi Andrey,

> From: Alexey Klimov <alexey.klimov at linaro.org>
> 
> Without trip points for GPU, the following errors are printed in the
> dmesg log and the sun8i-thermal driver fails to load:

So how does that post differ from Alexey one's a few weeks back:
https://lore.kernel.org/linux-arm-kernel/20240101000008.65747-1-alexey.klimov at linaro.org/
It seems like the same patch?

And Jernej and I had some comments (no mentioning of "Linux" in commit
message, add cooling maps, source of trip temperature values), can you
please try to address them?


> thermal_sys: Failed to find 'trips' node
> thermal_sys: Failed to find trip points for thermal-sensor id=1
> sun8i-thermal: probe of 1c25000.thermal-sensor failed with error -22

I think it's pretty obvious that the trip points are missing when they
shouldn't, so this does not need too much explanation or rationale in
the commit message, so you can cut this short.

> When thermal zones are defined, trip points definitions are mandatory.
> Trip values for the GPU are assumed to be the same values as the CPU
> ones. The available specs do not provide any hints about thermal regimes
> for the GPU and it seems GPU is implemented on the same die as the CPU.
> 
> 'make dtbs_check' complains about problem in dts for 18 A64-based boards
> supported by the kernel:
> 
> sun50i-a64-pine64.dtb: thermal-zones: gpu0-thermal: 'trips' is a required property
> 	from schema $id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#
> sun50i-a64-pine64.dtb: thermal-zones: gpu1-thermal: 'trips' is a required property
> 	from schema $id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#
> 
> Tested on Pine a64+ and PinePhone 1.2.
> 
> Cc: Samuel Holland <samuel at sholland.org>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: Chen-Yu Tsai <wens at csie.org>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: devicetree at vger.kernel.org
> Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
> Tested-by: Andrey Skvortsov <andrej.skvortzov at gmail.com>

You would need your Signed-off-by: here, since you send this, even when
on Alexey's behalf.

Cheers,
Andre

> 
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 46 +++++++++++++++++++
>  1 file changed, 46 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> index 57ac18738c99..c25da7229e42 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -244,6 +244,29 @@ gpu0_thermal: gpu0-thermal {
>  			polling-delay-passive = <0>;
>  			polling-delay = <0>;
>  			thermal-sensors = <&ths 1>;
> +
> +			trips {
> +				gpu0_alert0: gpu0_alert0 {
> +					/* milliCelsius */
> +					temperature = <75000>;
> +					hysteresis = <2000>;
> +					type = "passive";
> +				};
> +
> +				gpu0_alert1: gpu0_alert1 {
> +					/* milliCelsius */
> +					temperature = <90000>;
> +					hysteresis = <2000>;
> +					type = "hot";
> +				};
> +
> +				gpu0_crit: gpu0_crit {
> +					/* milliCelsius */
> +					temperature = <110000>;
> +					hysteresis = <2000>;
> +					type = "critical";
> +				};
> +			};
>  		};
>  
>  		gpu1_thermal: gpu1-thermal {
> @@ -251,6 +274,29 @@ gpu1_thermal: gpu1-thermal {
>  			polling-delay-passive = <0>;
>  			polling-delay = <0>;
>  			thermal-sensors = <&ths 2>;
> +
> +			trips {
> +				gpu1_alert0: gpu1_alert0 {
> +					/* milliCelsius */
> +					temperature = <75000>;
> +					hysteresis = <2000>;
> +					type = "passive";
> +				};
> +
> +				gpu1_alert1: gpu1_alert1 {
> +					/* milliCelsius */
> +					temperature = <90000>;
> +					hysteresis = <2000>;
> +					type = "hot";
> +				};
> +
> +				gpu1_crit: gpu1_crit {
> +					/* milliCelsius */
> +					temperature = <110000>;
> +					hysteresis = <2000>;
> +					type = "critical";
> +				};
> +			};
>  		};
>  	};
>  



From aford173 at gmail.com  Sun Feb 11 05:11:16 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 11 Feb 2024 07:11:16 -0600
Subject: [PATCH] arm64: dts: imx8mp-beacon: Enable Bluetooth
Message-ID: <20240211131116.66490-1-aford173@gmail.com>

The imx8mp-beacon SOM has wireless chip supporting Wi-Fi and
Bluetooth shared.  The Wi-Fi is already enabled via the SDIO
interface, so enable the Bluetooth via UART1.

Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
index e5da90804780..2ec282b91c42 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
@@ -206,6 +206,10 @@ &uart1 {
 	assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>;
 	uart-has-rtscts;
 	status = "okay";
+
+	bluetooth {
+		compatible = "nxp,88w8997-bt";
+	};
 };
 
 &usdhc1 {
-- 
2.43.0



From krzysztof.kozlowski at linaro.org  Sun Feb 11 05:26:33 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 14:26:33 +0100
Subject: [PATCH 01/22] dt-bindings: gpio: Add binding for ChromeOS EC GPIO
 controller
In-Reply-To: <20240210070934.2549994-2-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
 <20240210070934.2549994-2-swboyd@chromium.org>
Message-ID: <a6ce4811-2a3d-4df6-aad3-9942a1bcfedd@linaro.org>

On 10/02/2024 08:09, Stephen Boyd wrote:
> The ChromeOS embedded controller (EC) supports setting the state of
> GPIOs when the system is unlocked, and getting the state of GPIOs in all
> cases. The GPIOs are on the EC itself, so the EC acts similar to a GPIO
> expander. Add a binding to describe these GPIOs in DT so that other
> devices described in DT can read the GPIOs on the EC.

...

> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    spi {
> +      #address-cells = <1>;
> +      #size-cells = <0>;
> +
> +      cros-ec at 0 {
> +        compatible = "google,cros-ec-spi";
> +        reg = <0>;
> +        interrupts = <101 0>;

This is should be proper define but then are you sure interrupt is type
NONE? Does not look right.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 05:34:25 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 14:34:25 +0100
Subject: [PATCH 13/22] dt-bindings: chrome: Add
 google,cros-ec-typec-switch binding
In-Reply-To: <20240210070934.2549994-14-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
 <20240210070934.2549994-14-swboyd@chromium.org>
Message-ID: <46ac6ab8-b0a5-497d-91b6-1d2ced33184b@linaro.org>

On 10/02/2024 08:09, Stephen Boyd wrote:
> Add a binding for the USB type-c switch controls found on some ChromeOS
> Embedded Controllers (ECs). When this device is a mode switch, it takes
> one DisplayPort (DP) port as input and some number (possibly zero) of
> USB SuperSpeed ports (bundles of USB SS lanes) as input, and muxes those
> lanes into USB type-c SuperSpeed lanes suitable for the SSTRX1/2 pins on
> a usb-c-connector. When this device is an orientation switch, it
> redirects the DP lanes to the proper USB type-c SSTRX lanes.
> 
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Lee Jones <lee at kernel.org>
> Cc: Benson Leung <bleung at chromium.org>
> Cc: Guenter Roeck <groeck at chromium.org>
> Cc: Prashant Malani <pmalani at chromium.org>
> Cc: Tzung-Bi Shih <tzungbi at kernel.org>
> Cc: <devicetree at vger.kernel.org>
> Cc: <chrome-platform at lists.linux.dev>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  .../chrome/google,cros-ec-typec-switch.yaml   | 365 ++++++++++++++++++
>  .../bindings/mfd/google,cros-ec.yaml          |   5 +
>  2 files changed, 370 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
> 
> diff --git a/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml b/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
> new file mode 100644
> index 000000000000..17a0ba928f5d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
> @@ -0,0 +1,365 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/chrome/google,cros-ec-typec-switch.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Google Chrome OS EC(Embedded Controller) USB Type C Switch
> +
> +maintainers:
> +  - Benson Leung <bleung at chromium.org>
> +  - Prashant Malani <pmalani at chromium.org>
> +  - Stephen Boyd <swboyd at chromium.org>
> +
> +description:
> +  Chrome OS devices have an Embedded Controller(EC) which has access to USB
> +  Type C switching. This node is intended to allow the OS to control Type C
> +  signal muxing for USB-C orientation and alternate modes. The node for this
> +  device should be under a cros-ec node like google,cros-ec-spi.
> +

If this is USB Type C switch, then you miss reference to
usb-switch.yaml, but then ports look a bit different.

> +properties:
> +  compatible:
> +    const: google,cros-ec-typec-switch
> +
> +  mode-switch:
> +    description: Indicates this device controls altmode switching
> +    type: boolean
> +
> +  orientation-switch:
> +    description: Indicates this device controls orientation switching
> +    type: boolean
> +
> +  mux-gpios:
> +    description: GPIOs indicating which way the DP mux is steered

missing maxItems

> +
> +  no-hpd:
> +    description: Indicates this device doesn't signal HPD for DisplayPort
> +    type: boolean
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        description: Input port to receive DisplayPort (DP) data
> +        unevaluatedProperties: false
> +
> +        properties:
> +          endpoint at 0:
> +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
> +            description: DisplayPort data
> +            unevaluatedProperties: false
> +            properties:
> +              data-lanes:
> +                $ref: /schemas/types.yaml#/definitions/uint32-array
> +                description: |
> +                  An array of physical DP data lane indexes
> +                  - 0 is DP ML0 lane
> +                  - 1 is DP ML1 lane
> +                  - 2 is DP ML2 lane
> +                  - 3 is DP ML3 lane
> +                oneOf:
> +                  - items:
> +                      - const: 0
> +                      - const: 1
> +                  - items:
> +                      - const: 0
> +                      - const: 1
> +                      - const: 2
> +                      - const: 3
> +
> +        required:
> +          - endpoint at 0
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Input port to receive USB SuperSpeed (SS) data
> +        properties:
> +          endpoint at 0:
> +            $ref: /schemas/graph.yaml#/properties/endpoint
> +            description: USB SS data
> +
> +          endpoint at 1:
> +            $ref: /schemas/graph.yaml#/properties/endpoint
> +            description: USB SS data
> +
> +        anyOf:
> +          - required:
> +              - endpoint at 0
> +          - required:
> +              - endpoint at 1
> +
> +      port at 2:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description:
> +          Output port for USB-C data
> +        properties:
> +          endpoint at 0:
> +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
> +            description: USB-C data
> +            unevaluatedProperties: false
> +            properties:
> +              data-lanes:
> +                $ref: /schemas/types.yaml#/definitions/uint32-array
> +                description: |
> +                  An array of physical USB-C data lane indexes.
> +                  - 0 is SSRX1 lane
> +                  - 1 is SSTX1 lane
> +                  - 2 is SSTX2 lane
> +                  - 3 is SSRX2 lane
> +                minItems: 4
> +                maxItems: 4
> +                items:
> +                  maximum: 3
> +
> +          endpoint at 1:
> +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
> +            description: USB-C data for EC's 1st type-c port
> +            unevaluatedProperties: false
> +            properties:
> +              data-lanes:
> +                $ref: /schemas/types.yaml#/definitions/uint32-array
> +                description: |
> +                  An array of physical USB-C data lane indexes.
> +                  - 0 is SSRX1 lane
> +                  - 1 is SSTX1 lane
> +                  - 2 is SSTX2 lane
> +                  - 3 is SSRX2 lane
> +                minItems: 4
> +                maxItems: 4
> +                items:
> +                  maximum: 3
> +
> +          endpoint at 2:
> +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
> +            description: USB-C data for EC's 2nd type-c port
> +            unevaluatedProperties: false
> +            properties:
> +              data-lanes:
> +                $ref: /schemas/types.yaml#/definitions/uint32-array
> +                description: |
> +                  An array of physical USB-C data lane indexes.
> +                  - 0 is SSRX1 lane
> +                  - 1 is SSTX1 lane
> +                  - 2 is SSTX2 lane
> +                  - 3 is SSRX2 lane
> +                minItems: 4
> +                maxItems: 4
> +                items:
> +                  maximum: 3
> +
> +          endpoint at 3:
> +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
> +            description: USB-C data for EC's 3rd type-c port
> +            unevaluatedProperties: false
> +            properties:
> +              data-lanes:
> +                $ref: /schemas/types.yaml#/definitions/uint32-array
> +                description: |
> +                  An array of physical USB-C data lane indexes.
> +                  - 0 is SSRX1 lane
> +                  - 1 is SSTX1 lane
> +                  - 2 is SSTX2 lane
> +                  - 3 is SSRX2 lane
> +                minItems: 4
> +                maxItems: 4
> +                items:
> +                  maximum: 3
> +
> +          endpoint at 4:
> +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
> +            description: USB-C data for EC's 4th type-c port
> +            unevaluatedProperties: false
> +            properties:
> +              data-lanes:
> +                $ref: /schemas/types.yaml#/definitions/uint32-array
> +                description: |
> +                  An array of physical USB-C data lane indexes.
> +                  - 0 is SSRX1 lane
> +                  - 1 is SSTX1 lane
> +                  - 2 is SSTX2 lane
> +                  - 3 is SSRX2 lane
> +                minItems: 4
> +                maxItems: 4
> +                items:
> +                  maximum: 3
> +
> +          endpoint at 5:
> +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
> +            description: USB-C data for EC's 5th type-c port
> +            unevaluatedProperties: false
> +            properties:
> +              data-lanes:
> +                $ref: /schemas/types.yaml#/definitions/uint32-array
> +                description: |
> +                  An array of physical USB-C data lane indexes.
> +                  - 0 is SSRX1 lane
> +                  - 1 is SSTX1 lane
> +                  - 2 is SSTX2 lane
> +                  - 3 is SSRX2 lane
> +                minItems: 4
> +                maxItems: 4
> +                items:
> +                  maximum: 3
> +
> +          endpoint at 6:
> +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
> +            description: USB-C data for EC's 6th type-c port
> +            unevaluatedProperties: false
> +            properties:
> +              data-lanes:
> +                $ref: /schemas/types.yaml#/definitions/uint32-array
> +                description: |
> +                  An array of physical USB-C data lane indexes.
> +                  - 0 is SSRX1 lane
> +                  - 1 is SSTX1 lane
> +                  - 2 is SSTX2 lane
> +                  - 3 is SSRX2 lane
> +                minItems: 4
> +                maxItems: 4
> +                items:
> +                  maximum: 3
> +
> +          endpoint at 7:
> +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
> +            description: USB-C data for EC's 7th type-c port
> +            unevaluatedProperties: false
> +            properties:
> +              data-lanes:
> +                $ref: /schemas/types.yaml#/definitions/uint32-array
> +                description: |
> +                  An array of physical USB-C data lane indexes.
> +                  - 0 is SSRX1 lane
> +                  - 1 is SSTX1 lane
> +                  - 2 is SSTX2 lane
> +                  - 3 is SSRX2 lane
> +                minItems: 4
> +                maxItems: 4
> +                items:
> +                  maximum: 3
> +
> +        anyOf:
> +          - required:
> +              - endpoint at 0

I don't get what you want to say here. This anyOf should have no effect.

> +          - required:
> +              - endpoint at 1
> +          - required:
> +              - endpoint at 2
> +          - required:
> +              - endpoint at 3
> +          - required:
> +              - endpoint at 4
> +          - required:
> +              - endpoint at 5
> +          - required:
> +              - endpoint at 6
> +          - required:
> +              - endpoint at 7
> +
> +    required:
> +      - port at 2
> +    anyOf:
> +      - required:
> +          - port at 0
> +      - required:
> +          - port at 1

Same problem here

> +
> +required:
> +  - compatible
> +  - ports
> +
> +allOf:
> +  - if:
> +      properties:
> +        no-hpd: true

I don't understand this either. What is it for? Where did you see such
syntax?


> +      required:
> +        - no-hpd> +    then:
> +      properties:
> +        ports:
> +          required:
> +            - port at 0
> +  - if:
> +      properties:
> +        mode-switch: true
> +      required:
> +        - mode-switch
> +    then:
> +      properties:
> +        ports:
> +          required:
> +            - port at 0
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    spi {
> +      #address-cells = <1>;
> +      #size-cells = <0>;
> +
> +      cros_ec: ec at 0 {
> +        compatible = "google,cros-ec-spi";
> +        reg = <0>;
> +        interrupts = <35 0>;

Same concerns about interrupts.

> +
> +        typec-switch {
> +          compatible = "google,cros-ec-typec-switch";
> +          mode-switch;
> +          orientation-switch;
> +
> +          ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port at 0 {
> +              reg = <0>;
> +              #address-cells = <1>;
> +              #size-cells = <0>;
> +              dp_in: endpoint at 0 {
> +                reg = <0>;
> +                remote-endpoint = <&dp_phy>;
> +                data-lanes = <0 1>;
> +              };
> +            };
> +
> +            port at 1 {
> +              reg = <1>;
> +              #address-cells = <1>;
> +              #size-cells = <0>;
> +
> +              usb_in_0: endpoint at 0 {
> +                reg = <0>;
> +                remote-endpoint = <&usb_ss_0_out>;
> +              };
> +
> +              usb_in_1: endpoint at 1 {
> +                reg = <1>;
> +                remote-endpoint = <&usb_ss_1_out>;
> +              };
> +            };
> +
> +            port at 2 {
> +              reg = <2>;
> +              #address-cells = <1>;
> +              #size-cells = <0>;
> +
> +              cros_typec_c0_ss: endpoint at 0 {
> +                reg = <0>;
> +                remote-endpoint = <&usb_c0_ss>;
> +              };
> +
> +              cros_typec_c1_ss: endpoint at 1 {
> +                reg = <1>;
> +                remote-endpoint = <&usb_c1_ss>;
> +              };
> +            };
> +          };
> +        };
> +      };
> +    };
> +...
> diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
> index ded396b28fba..563c51a4a39c 100644
> --- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
> +++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
> @@ -164,6 +164,10 @@ patternProperties:
>      type: object
>      $ref: /schemas/extcon/extcon-usbc-cros-ec.yaml#
>  
> +  "^typec-switch[0-9]*$":

Missing - after typec-switch (e.g. typec-switch-1)

> +    type: object
> +    $ref: /schemas/chrome/google,cros-ec-typec-switch.yaml#


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 05:35:35 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 14:35:35 +0100
Subject: [PATCH 13/22] dt-bindings: chrome: Add
 google,cros-ec-typec-switch binding
In-Reply-To: <20240210070934.2549994-14-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
 <20240210070934.2549994-14-swboyd@chromium.org>
Message-ID: <8c7e41c9-8dcb-46f4-b8e6-8da2a6391993@linaro.org>

On 10/02/2024 08:09, Stephen Boyd wrote:
> Add a binding for the USB type-c switch controls found on some ChromeOS
> Embedded Controllers (ECs). When this device is a mode switch, it takes
> one DisplayPort (DP) port as input and some number (possibly zero) of
> USB SuperSpeed ports (bundles of USB SS lanes) as input, and muxes those
> lanes into USB type-c SuperSpeed lanes suitable for the SSTRX1/2 pins on
> a usb-c-connector. When this device is an orientation switch, it
> redirects the DP lanes to the proper USB type-c SSTRX lanes.
> 
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Lee Jones <lee at kernel.org>
> Cc: Benson Leung <bleung at chromium.org>
> Cc: Guenter Roeck <groeck at chromium.org>
> Cc: Prashant Malani <pmalani at chromium.org>
> Cc: Tzung-Bi Shih <tzungbi at kernel.org>
> Cc: <devicetree at vger.kernel.org>
> Cc: <chrome-platform at lists.linux.dev>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  .../chrome/google,cros-ec-typec-switch.yaml   | 365 ++++++++++++++++++
>  .../bindings/mfd/google,cros-ec.yaml          |   5 +
>  2 files changed, 370 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml

Ah, and wrong placement. There is no hardware called "chrome", please
don't stuff things there. USB switches go to other USB switches (git
grep usb-switch.yaml will give you hints).

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 05:39:36 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 14:39:36 +0100
Subject: [PATCH 18/22] dt-bindings: chrome: Add binding for ChromeOS Pogo
 pin connector
In-Reply-To: <20240210070934.2549994-19-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
 <20240210070934.2549994-19-swboyd@chromium.org>
Message-ID: <18ac05fb-a78d-4e95-a73d-461f509cdc5f@linaro.org>

On 10/02/2024 08:09, Stephen Boyd wrote:
> Describe the set of pins used to connect the detachable keyboard on
> detachable ChromeOS devices. The set of pins is called the "pogo pins".
> It's basically USB 2.0 with an extra pin for base detection. We expect
> to find a keyboard on the other side of this connector with a specific
> vid/pid, so describe that as a child device at the port of the usb
> device connected upstream.
> 
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Benson Leung <bleung at chromium.org>
> Cc: Guenter Roeck <groeck at chromium.org>
> Cc: <devicetree at vger.kernel.org>
> Cc: <chrome-platform at lists.linux.dev>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  .../chrome/google,pogo-pin-connector.yaml     | 61 +++++++++++++++++++
>  1 file changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml
> 
> diff --git a/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml b/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml
> new file mode 100644
> index 000000000000..5ba68fd95fcd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml
> @@ -0,0 +1,61 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/chrome/google,pogo-pin-connector.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Google Pogo Pin Connector
> +
> +maintainers:
> +  - Stephen Boyd <swboyd at chromium.org>
> +

Missing description describing the hardware.

> +properties:
> +  compatible:
> +    const: google,pogo-pin-connector
> +
> +  "#address-cells":
> +    const: 1
> +
> +  "#size-cells":
> +    const: 0
> +
> +  port:
> +    $ref: /schemas/graph.yaml#/properties/port
> +    description: Connection to USB2 port providing USB signals
> +    required:
> +      - endpoint

Drop required.


> +
> +patternProperties:
> +  "^keyboard@[0-9a-f]{1,2}$":
> +    description: The detachable keyboard

If this is detachable why do you define it in DT? Only hard-wired USB
devices, which need some sort of special handling. are described in DT.

> +    type: object
> +    $ref: /schemas/usb/usb-device.yaml

On this level:
unevaluatedProperties: false

> +
> +required:
> +  - compatible
> +  - '#address-cells'
> +  - '#size-cells'

Use one type of quotes, either ' or ".

> +  - port
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    connector {
> +        compatible = "google,pogo-pin-connector";
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        keyboard at 2 {
> +          compatible = "usb18d1,504c";

Messed indentation.

> +          reg = <2>;
> +        };
> +
Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 05:42:48 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 14:42:48 +0100
Subject: [PATCH v3 1/2] dt-bindings: phy: mediatek,mt7988-xfi-tphy: add
 new bindings
In-Reply-To: <745f8b46f676e94c1a396df8c46aefe0e8b4771c.1707530671.git.daniel@makrotopia.org>
References: <745f8b46f676e94c1a396df8c46aefe0e8b4771c.1707530671.git.daniel@makrotopia.org>
Message-ID: <b6c28118-a20c-46a5-b070-2306d4c0b2a1@linaro.org>

On 10/02/2024 03:10, Daniel Golle wrote:
> Add bindings for the MediaTek XFI Ethernet SerDes T-PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
> via USXGMII PCS:
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
> 
> via LynxI SGMII PCS:
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
> v3: Add reference to MediaTek-internal "pextp" name, better explain reset as
>     well as 10GBase-R tuning work-around.
> v2: unify filename and compatible as requested
> 

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 05:49:53 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 14:49:53 +0100
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth``
 property
In-Reply-To: <CAMuHMdU_Hx9PLmHf2Xm1KKTy_OF-TeCv7SzmA5CZWz+PLkbAGA@mail.gmail.com>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
 <20240208135045.3728927-2-tudor.ambarus@linaro.org>
 <CAMuHMdU_Hx9PLmHf2Xm1KKTy_OF-TeCv7SzmA5CZWz+PLkbAGA@mail.gmail.com>
Message-ID: <be84e32e-e11d-47fe-ad56-da8b0dec5007@linaro.org>

On 09/02/2024 18:13, Geert Uytterhoeven wrote:
> Hi Tudor,
> 
> On Thu, Feb 8, 2024 at 2:51?PM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>> There are instances of the same IP that are configured by the integrator
>> with different FIFO depths. Introduce the fifo-depth property to allow
>> such nodes to specify their FIFO depth.
>>
>> We haven't seen SPI IPs with different FIFO depths for RX and TX, thus
>> introduce a single property.
> 
> Ha...
> 
> Current documentation for the Clock-Synchronized Serial Interface with
> FIFO (MSIOF) on e.g. R-Car Gen2 and later states:
> 
>     FIFO capacity: 32 bits ? 64 stages for transmission and 32 bits ?
> 256 stages for reception
> 
> Initially (many years ago), there was some doubt about the validity
> of these values (older variants on SH supported 64/64), hence
> drivers/spi/spi-sh-msiof.c still has
> 
>     .tx_fifo_size = 64,
>     .rx_fifo_size = 64,
> 
> Probably we should test and revisit this...
> 
>> --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml
>> +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml
>> @@ -69,6 +69,11 @@ properties:
>>           Should be generally avoided and be replaced by
>>           spi-cs-high + ACTIVE_HIGH.
>>
>> +  fifo-depth:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description:
>> +      Size of the data FIFO in bytes.
> 
> I think it is prudent to consider the asymmetric case, too.
> Whether that should be just two properties ("rx-fifo-depth" and
> "tx-fifo-depth"), or also a third "fifo-depth", I defer to the DT
> maintainers...

Since most of the cases FIFO depth tx=rx, we could go with three
properties and:

allOf:
 - not:
     required:
       - fifo-depth
       - tx-fifo-depth
 - not:
     required:
       - fifo-depth
       - rx-fifo-depth

and probably dependencies between rx and tx (see example-schema).

Best regards,
Krzysztof



From aford173 at gmail.com  Sun Feb 11 05:55:34 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 11 Feb 2024 07:55:34 -0600
Subject: [PATCH] arm64: dts: imx8mp-beacon: Configure multiple queues on eqos
Message-ID: <20240211135535.68516-1-aford173@gmail.com>

The imx8mp-beacon SOM has an integrated PHY connected to
the EQOS ethernet controller which can support up to five
queues.  Configure these queues in the same manor as done
on the imx8mp-evk.

Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
index 2ec282b91c42..8be251b69378 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
@@ -50,6 +50,8 @@ &eqos {
 	phy-mode = "rgmii-id";
 	phy-handle = <&ethphy0>;
 	snps,force_thresh_dma_mode;
+	snps,mtl-rx-config = <&mtl_rx_setup>;
+	snps,mtl-tx-config = <&mtl_tx_setup>;
 	status = "okay";
 
 	mdio {
@@ -66,6 +68,71 @@ ethphy0: ethernet-phy at 3 {
 			interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
 		};
 	};
+
+	mtl_rx_setup: rx-queues-config {
+		snps,rx-queues-to-use = <5>;
+		snps,rx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,priority = <0x1>;
+			snps,map-to-dma-channel = <0>;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+			snps,priority = <0x2>;
+			snps,map-to-dma-channel = <1>;
+		};
+
+		queue2 {
+			snps,dcb-algorithm;
+			snps,priority = <0x4>;
+			snps,map-to-dma-channel = <2>;
+		};
+
+		queue3 {
+			snps,dcb-algorithm;
+			snps,priority = <0x8>;
+			snps,map-to-dma-channel = <3>;
+		};
+
+		queue4 {
+			snps,dcb-algorithm;
+			snps,priority = <0xf0>;
+			snps,map-to-dma-channel = <4>;
+		};
+	};
+
+	mtl_tx_setup: tx-queues-config {
+		snps,tx-queues-to-use = <5>;
+		snps,tx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,priority = <0x1>;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+			snps,priority = <0x2>;
+		};
+
+		queue2 {
+			snps,dcb-algorithm;
+			snps,priority = <0x4>;
+		};
+
+		queue3 {
+			snps,dcb-algorithm;
+			snps,priority = <0x8>;
+		};
+
+		queue4 {
+			snps,dcb-algorithm;
+			snps,priority = <0xf0>;
+		};
+	};
 };
 
 &flexspi {
-- 
2.43.0



From geert+renesas at glider.be  Sun Feb 11 06:21:29 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Sun, 11 Feb 2024 15:21:29 +0100
Subject: [PATCH 0/2] arm64: dts: renesas: rcar-gen4: Correct avb[01] reg sizes
Message-ID: <cover.1707660323.git.geert+renesas@glider.be>

	Hi all,

All Ethernet AVB instances on R-Car Gen4 SoCs have registers related to
UDP/IP support, starting at offset 0x800.  However, the register blocks
for some (but not all) instances are too small to cover them.

This patch series fixes this by extending the register block sizes where
needed.  Note that this has no immediate impact on actual operation, as
the Linux driver does not use the UDP/IP registers.  Besides, ioremap()
granulatity is PAGE_SIZE, so the registers are accessible anyway.

I also considered introducing a new reg tuplet to cover the UDP/IP
registers.  However, that would complicate handling as some instances
(on some R-Car Gen2/3 SoCs) already have two reg tuplets, and there are
no reg-names defined:

    reg:
      items:
	- description: MAC register block
	- description: Stream buffer

So I think just enlarging the first register block would be fine.

To be queued in renesas-devel for v6.9, if you agree.

Thanks for your comments!

Geert Uytterhoeven (2):
  arm64: dts: renesas: r8a779a0: Correct avb[01] reg sizes
  arm64: dts: renesas: r8a779g0: Correct avb[01] reg sizes

 arch/arm64/boot/dts/renesas/r8a779a0.dtsi | 4 ++--
 arch/arm64/boot/dts/renesas/r8a779g0.dtsi | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

-- 
2.34.1

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 geert+renesas at glider.be  Sun Feb 11 06:21:31 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Sun, 11 Feb 2024 15:21:31 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: r8a779g0: Correct avb[01] reg sizes
In-Reply-To: <cover.1707660323.git.geert+renesas@glider.be>
References: <cover.1707660323.git.geert+renesas@glider.be>
Message-ID: <83437778614a7c96f4d8f1be98dffeee29bb4a0b.1707660323.git.geert+renesas@glider.be>

All Ethernet AVB instances on R-Car V4H have registers related to UDP/IP
support, but the declared register blocks for the first two instances
are too small to cover them.

Fix this by extending the register block sizes.

Fixes: 848c82db56923a8b ("arm64: dts: renesas: r8a779g0: Add RAVB nodes")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/boot/dts/renesas/r8a779g0.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
index 7b05b9b3e0a85f44..9bc542bc616909d1 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
@@ -776,7 +776,7 @@ channel7 {
 		avb0: ethernet at e6800000 {
 			compatible = "renesas,etheravb-r8a779g0",
 				     "renesas,etheravb-rcar-gen4";
-			reg = <0 0xe6800000 0 0x800>;
+			reg = <0 0xe6800000 0 0x1000>;
 			interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
@@ -823,7 +823,7 @@ avb0: ethernet at e6800000 {
 		avb1: ethernet at e6810000 {
 			compatible = "renesas,etheravb-r8a779g0",
 				     "renesas,etheravb-rcar-gen4";
-			reg = <0 0xe6810000 0 0x800>;
+			reg = <0 0xe6810000 0 0x1000>;
 			interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.34.1



From geert+renesas at glider.be  Sun Feb 11 06:21:30 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Sun, 11 Feb 2024 15:21:30 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: r8a779a0: Correct avb[01] reg sizes
In-Reply-To: <cover.1707660323.git.geert+renesas@glider.be>
References: <cover.1707660323.git.geert+renesas@glider.be>
Message-ID: <ce6ce3c4b1495e02e7c1803fca810a7178a84500.1707660323.git.geert+renesas@glider.be>

All Ethernet AVB instances on R-Car V3U have registers related to UDP/IP
support, but the declared register blocks for the first two instances
are too small to cover them.

Fix this by extending the register block sizes.

Fixes: 5a633320f08b8c9b ("arm64: dts: renesas: r8a779a0: Add Ethernet-AVB support")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/boot/dts/renesas/r8a779a0.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
index 2f8f2ccab8c23728..cfa70b441e329a0b 100644
--- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
@@ -667,7 +667,7 @@ channel7 {
 		avb0: ethernet at e6800000 {
 			compatible = "renesas,etheravb-r8a779a0",
 				     "renesas,etheravb-rcar-gen4";
-			reg = <0 0xe6800000 0 0x800>;
+			reg = <0 0xe6800000 0 0x1000>;
 			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
@@ -715,7 +715,7 @@ avb0: ethernet at e6800000 {
 		avb1: ethernet at e6810000 {
 			compatible = "renesas,etheravb-r8a779a0",
 				     "renesas,etheravb-rcar-gen4";
-			reg = <0 0xe6810000 0 0x800>;
+			reg = <0 0xe6810000 0 0x1000>;
 			interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.34.1



From andrej.skvortzov at gmail.com  Sun Feb 11 06:24:19 2024
From: andrej.skvortzov at gmail.com (Andrey Skvortsov)
Date: Sun, 11 Feb 2024 17:24:19 +0300
Subject: [PATCH] arm64: dts: allwinner: a64: Add thermal trip points for
 GPU
In-Reply-To: <20240211125209.15d58462@minigeek.lan>
References: <20240211105326.506049-1-andrej.skvortzov@gmail.com>
 <20240211125209.15d58462@minigeek.lan>
Message-ID: <ZcjYk8MD4jotKNcq@skv.local>

Hi Andre,

On 24-02-11 12:52, Andre Przywara wrote:
> On Sun, 11 Feb 2024 13:53:26 +0300
> Andrey Skvortsov <andrej.skvortzov at gmail.com> wrote:
> 
> Hi Andrey,
> 
> > From: Alexey Klimov <alexey.klimov at linaro.org>
> > 
> > Without trip points for GPU, the following errors are printed in the
> > dmesg log and the sun8i-thermal driver fails to load:
> 
> So how does that post differ from Alexey one's a few weeks back:
> https://lore.kernel.org/linux-arm-kernel/20240101000008.65747-1-alexey.klimov at linaro.org/
> It seems like the same patch?

Yes, it's the same patch. I've added only information about failed
dtbs_check errors in already supported boards to commit message.
I've found this patch from June 2023 without any feedback. [1] Since I've
worked on dts changes for PinePhone A64, I've decided to resend
it. Sorry, I wasn't aware that Alexey resent it in the mean time. It's
better to continue discussion in original Alexey's patch.

> And Jernej and I had some comments (no mentioning of "Linux" in commit
> message, add cooling maps, source of trip temperature values), can you
> please try to address them?
> 
> 
> > thermal_sys: Failed to find 'trips' node
> > thermal_sys: Failed to find trip points for thermal-sensor id=1
> > sun8i-thermal: probe of 1c25000.thermal-sensor failed with error -22
> 
> I think it's pretty obvious that the trip points are missing when they
> shouldn't, so this does not need too much explanation or rationale in
> the commit message, so you can cut this short.
> 
> > When thermal zones are defined, trip points definitions are mandatory.
> > Trip values for the GPU are assumed to be the same values as the CPU
> > ones. The available specs do not provide any hints about thermal regimes
> > for the GPU and it seems GPU is implemented on the same die as the CPU.
> > 
> > 'make dtbs_check' complains about problem in dts for 18 A64-based boards
> > supported by the kernel:
> > 
> > sun50i-a64-pine64.dtb: thermal-zones: gpu0-thermal: 'trips' is a required property
> > 	from schema $id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#
> > sun50i-a64-pine64.dtb: thermal-zones: gpu1-thermal: 'trips' is a required property
> > 	from schema $id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#
> > 
> > Tested on Pine a64+ and PinePhone 1.2.
> > 
> > Cc: Samuel Holland <samuel at sholland.org>
> > Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> > Cc: Chen-Yu Tsai <wens at csie.org>
> > Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> > Cc: devicetree at vger.kernel.org
> > Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
> > Tested-by: Andrey Skvortsov <andrej.skvortzov at gmail.com>
> 
> You would need your Signed-off-by: here, since you send this, even when
> on Alexey's behalf.
> 
> Cheers,
> Andre
>

1.  https://lkml.org/lkml/2023/6/4/416

-- 
Best regards,
Andrey Skvortsov


From geert+renesas at glider.be  Sun Feb 11 06:30:46 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Sun, 11 Feb 2024 15:30:46 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: gray-hawk-single: Add Ethernet support
In-Reply-To: <cover.1707661382.git.geert+renesas@glider.be>
References: <cover.1707661382.git.geert+renesas@glider.be>
Message-ID: <b83b21b6477a0e31f99eaedbd36c03014b72ec8a.1707661382.git.geert+renesas@glider.be>

From: Thanh Quan <thanh.quan.xn at renesas.com>

Describe the wiring of the first Ethernet AVB instance to the Micrel
KSZ9031RNXVB PHY.

Signed-off-by: Thanh Quan <thanh.quan.xn at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Split in separate commits for SoC and board support,
  - Apply to r8a779h0-gray-hawk-single.dts.
---
 .../dts/renesas/r8a779h0-gray-hawk-single.dts | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
index 1bee27b2284d2eee..625e7448bc9fc1ce 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
+++ b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
@@ -15,6 +15,7 @@ / {
 
 	aliases {
 		serial0 = &hscif0;
+		ethernet0 = &avb0;
 	};
 
 	chosen {
@@ -34,6 +35,24 @@ memory at 480000000 {
 	};
 };
 
+&avb0 {
+	pinctrl-0 = <&avb0_pins>;
+	pinctrl-names = "default";
+	phy-handle = <&phy0>;
+	tx-internal-delay-ps = <2000>;
+	status = "okay";
+
+	phy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-id0022.1622",
+			     "ethernet-phy-ieee802.3-c22";
+		rxc-skew-ps = <1500>;
+		reg = <0>;
+		interrupt-parent = <&gpio7>;
+		interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&gpio7 10 GPIO_ACTIVE_LOW>;
+	};
+};
+
 &extal_clk {
 	clock-frequency = <16666666>;
 };
@@ -90,6 +109,24 @@ &pfc {
 	pinctrl-0 = <&scif_clk_pins>;
 	pinctrl-names = "default";
 
+	avb0_pins: avb0 {
+		mux {
+			groups = "avb0_link", "avb0_mdio", "avb0_rgmii",
+				 "avb0_txcrefclk";
+			function = "avb0";
+		};
+
+		pins_mdio {
+			groups = "avb0_mdio";
+			drive-strength = <21>;
+		};
+
+		pins_mii {
+			groups = "avb0_rgmii";
+			drive-strength = <21>;
+		};
+	};
+
 	hscif0_pins: hscif0 {
 		groups = "hscif0_data", "hscif0_ctrl";
 		function = "hscif0";
-- 
2.34.1



From geert+renesas at glider.be  Sun Feb 11 06:30:44 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Sun, 11 Feb 2024 15:30:44 +0100
Subject: [PATCH 0/2] arm64: dts: renesas: r8a779h0/gray-hawk-single: Add Ethernet support
Message-ID: <arm64-dts-renesas-r8a779h0-gray-hawk-single-Ethernet.geert+renesas@glider.be>

	Hi all,

This patch series adds Ethernet support for the Renesas R-Car V4M
(R8A779H0) Soc and the Gray Hawk Single development board.

This has been tested on Gray Hawk Single using TFTP.

I intend to queue this in renesas-devel for v6.9.

Thanks for your comments!

Thanh Quan (2):
  arm64: dts: renesas: r8a779h0: Add Ethernet-AVB support
  arm64: dts: renesas: gray-hawk-single: Add Ethernet support

 .../dts/renesas/r8a779h0-gray-hawk-single.dts |  37 +++++
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi     | 144 ++++++++++++++++++
 2 files changed, 181 insertions(+)

-- 
2.34.1

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 geert+renesas at glider.be  Sun Feb 11 06:30:45 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Sun, 11 Feb 2024 15:30:45 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: r8a779h0: Add Ethernet-AVB support
In-Reply-To: <cover.1707661382.git.geert+renesas@glider.be>
References: <cover.1707661382.git.geert+renesas@glider.be>
Message-ID: <ae7488c0065b455b45f23253c997a94f4850064f.1707661382.git.geert+renesas@glider.be>

From: Thanh Quan <thanh.quan.xn at renesas.com>

Add device nodes for the Renesas Ethernet AVB (EtherAVB-IF) blocks on
the Renesas R-Car V4M (R8A779H0) SoC.

Signed-off-by: Thanh Quan <thanh.quan.xn at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Split in separate patches for SoC and board support,
  - Correct reg size for avb[01] from 0x800 to 0x1000, to cover the
    register related to UDP/IP support, cfr. "[PATCH 0/2] arm64: dts: renesas:
    rcar-gen4: Correct avb[01] reg sizes"
    https://lore.kernel.org/r/cover.1707660323.git.geert+renesas at glider.be
  - Add clock-names properties,
  - Fix indentation of closing curly brace.
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 144 ++++++++++++++++++++++
 1 file changed, 144 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index 4e9e487ec51661fd..66a93c88f8742431 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -388,6 +388,150 @@ hscif0: serial at e6540000 {
 			status = "disabled";
 		};
 
+		avb0: ethernet at e6800000 {
+			compatible = "renesas,etheravb-r8a779h0",
+				     "renesas,etheravb-rcar-gen4";
+			reg = <0 0xe6800000 0 0x1000>;
+			interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>,
+				     <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>;
+			interrupt-names = "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15",
+					  "ch16", "ch17", "ch18", "ch19",
+					  "ch20", "ch21", "ch22", "ch23",
+					  "ch24";
+			clocks = <&cpg CPG_MOD 211>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A779H0_PD_C4>;
+			resets = <&cpg 211>;
+			phy-mode = "rgmii";
+			rx-internal-delay-ps = <0>;
+			tx-internal-delay-ps = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		avb1: ethernet at e6810000 {
+			compatible = "renesas,etheravb-r8a779h0",
+				     "renesas,etheravb-rcar-gen4";
+			reg = <0 0xe6810000 0 0x1000>;
+			interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 365 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 366 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 369 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 374 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15",
+					  "ch16", "ch17", "ch18", "ch19",
+					  "ch20", "ch21", "ch22", "ch23",
+					  "ch24";
+			clocks = <&cpg CPG_MOD 212>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A779H0_PD_C4>;
+			resets = <&cpg 212>;
+			phy-mode = "rgmii";
+			rx-internal-delay-ps = <0>;
+			tx-internal-delay-ps = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		avb2: ethernet at e6820000 {
+			compatible = "renesas,etheravb-r8a779h0",
+				     "renesas,etheravb-rcar-gen4";
+			reg = <0 0xe6820000 0 0x1000>;
+			interrupts = <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 388 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 389 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 390 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ch0", "ch1", "ch2", "ch3",
+					  "ch4", "ch5", "ch6", "ch7",
+					  "ch8", "ch9", "ch10", "ch11",
+					  "ch12", "ch13", "ch14", "ch15",
+					  "ch16", "ch17", "ch18", "ch19",
+					  "ch20", "ch21", "ch22", "ch23",
+					  "ch24";
+			clocks = <&cpg CPG_MOD 213>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A779H0_PD_C4>;
+			resets = <&cpg 213>;
+			phy-mode = "rgmii";
+			rx-internal-delay-ps = <0>;
+			tx-internal-delay-ps = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		gic: interrupt-controller at f1000000 {
 			compatible = "arm,gic-v3";
 			#interrupt-cells = <3>;
-- 
2.34.1



From josua at solid-run.com  Sun Feb 11 06:57:59 2024
From: josua at solid-run.com (Josua Mayer)
Date: Sun, 11 Feb 2024 14:57:59 +0000
Subject: [PATCH v4 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240203-prolonged-backfield-c659e0016d70@spud>
References: <20240202-add-am64-som-v4-0-5f8b12af5e71@solid-run.com>
 <20240202-add-am64-som-v4-2-5f8b12af5e71@solid-run.com>
 <20240203-prolonged-backfield-c659e0016d70@spud>
Message-ID: <eae2e8ab-7561-4990-9e5c-de1b158fbdd7@solid-run.com>

Am 03.02.24 um 16:08 schrieb Conor Dooley:
> Hey,
>
> On Fri, Feb 02, 2024 at 05:10:49PM +0100, Josua Mayer wrote:
>> Convert the abracon abx80x rtc text bindings to dt-schema format.
>>
>> In addition to the text description reference generic interrupts
>> properties and add an example.
>>
>> Signed-off-by: Josua Mayer <josua at solid-run.com>
>> ---
...
>> diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
>> new file mode 100644
>> index 000000000000..405b386a54b0
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
>> @@ -0,0 +1,74 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Abracon ABX80X I2C ultra low power RTC/Alarm chip
>> +
>> +maintainers:
>> +  - devicetree at vger.kernel.org
> Ideally you put someone here, not the DT list. Usually the original
> author is a good choice, which I think happens to be the subsystem
> maintainer... Failing that, the rtc subsystem list is likely a better
> choice than the DT one.
rtc-abx80x.c mentions:
MODULE_AUTHOR("Philippe De Muyter <phdm at macqel.be>");
MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni at bootlin.com>");

I personally prefer to put a list, since I don't know status of first author,
and second author / rtc subsystem maintainer is automatic.

So v5 will feature linux-rtc at vger.kernel.org.


From josua at solid-run.com  Sun Feb 11 07:07:56 2024
From: josua at solid-run.com (Josua Mayer)
Date: Sun, 11 Feb 2024 16:07:56 +0100
Subject: [PATCH v5 1/5] dt-bindings: arm: ti: Add bindings for SolidRun
 AM642 HummingBoard-T
In-Reply-To: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
Message-ID: <20240211-add-am64-som-v5-1-790ed7121249@solid-run.com>

Add bindings for SolidRun AM642 HummingBoard-T Board, which is the
evaluation board for SolidRun AM642 SoM.

Signed-off-by: Josua Mayer <josua at solid-run.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/ti/k3.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
index 03d2a0d79fb0..b9f2a8d36874 100644
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -85,6 +85,13 @@ properties:
           - const: tq,am642-tqma6442l
           - const: ti,am642
 
+      - description: K3 AM642 SoC SolidRun SoM based boards
+        items:
+          - enum:
+              - solidrun,am642-hummingboard-t
+          - const: solidrun,am642-sr-som
+          - const: ti,am642
+
       - description: K3 AM654 SoC
         items:
           - enum:

-- 
2.35.3



From josua at solid-run.com  Sun Feb 11 07:07:55 2024
From: josua at solid-run.com (Josua Mayer)
Date: Sun, 11 Feb 2024 16:07:55 +0100
Subject: [PATCH v5 0/5] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
Message-ID: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>

This series adds DT bindings and dts descriptions for SolidRun AM642
based SoM and Hummingboard EVB.

Additionally a commit from downstream vendor kernel are included,
enhancing support for pru based ethernet.
I wasn't sure how to properly annotate it in commit description /
signed-off area ...:

1. add description for "Industrial Ethernet Peripherals" (IEP) to am64
   https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/commit/arch/arm64/boot/dts/ti/k3-am64-main.dtsi?h=ti-linux-6.1.y-cicd&id=5afb73d82a014b59462162d960b350b8c58e5ae6
   IEP is already supported in-tree by a driver, and used in
   k3-am65-main.dtsi.

Unfortunately dtbs_check reported many problems, I put some remarks:

- 'mux-controller' does not match any of the regexes
  The expectation seems to be that a mux-controller at minimum has an
  address, something to put behind an @. However this is a gpio mux, not
  sure how to name it better.

- unevaluated properties: interrupts, interrupt-parent
  sensors and flash yaml are missing interrupt descriptions, but these
  parts definitely have an interrupt signal in this solidrun board.

- wrong names for pinctrl nodes
  Other TI DTSs consistently end with *-pins-default. Should a different
  naming convention be used?

- cdns,phy-type required property
  inherited from k3-am64-main.dtsi
  there is a PHY_NONE value in dt-bindings/phy/phy.h,
  but not allowed in phy-cadence-torrent.yaml

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
Changes in v5:
- abracon,abx80x.yaml:
  - reworded 'compatible' description
  - removed $ref to interrupts.yaml
  - nested example in fake i2c
  - changed maintainer to rtc list
  (reported by Conor Dooley <conor at kernel.org>)
- patch 4/5 dts:
  - re-added status properties for sdhci nodes
    k3-am64-main.dtsi has been changed in-tree since v1
    such that sdhci nodes are explicitly status disabled now.
  - picked up reviewed-by
  (reported by Andrew Davis <afd at ti.com>)
- Link to v4: https://lore.kernel.org/r/20240202-add-am64-som-v4-0-5f8b12af5e71 at solid-run.com

Changes in v4:
- abracon,abx80x.yaml: fixed dtc error in example irq reference
- Link to v3: https://lore.kernel.org/r/20240202-add-am64-som-v3-0-2f44023d50e9 at solid-run.com

Changes in v3:
- removed lots more status properties, double-checked against soc dtsi
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
  (reported by Andrew Davis <afd at ti.com>)
- removed intentionally-disabled pcie node from dts
- rewrote yaml bindings to use enum instead of anyof+const+description
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
- abracon yaml
  - added missing maintainer
  - added diode type property type
  - added example
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>)
  - added reference to /schemas/interrupts.yaml#
- use generic name for pru ethernet controller node
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>)
- removed unnamed dmas from pru ethernet controller node
- moved pcie/usb3 features to dtb overlays
- Link to v2: https://lore.kernel.org/r/20240112-add-am64-som-v2-0-1385246c428c at solid-run.com

Changes in v2:
- reordered patchset to drop separate patch adding iep handle to som
- moved dtbs_check warnings to cover letter
- converted abracon abx80x rtc bindings to yaml
- updated dts:
  - remove unnecessary status properties
  - changed non-generic node names
  - use color property for led descriptions,
    they have no default function on evaluation board
  - drop earlycon bootargs from chosen node
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
- converted charger node to comment, part not assembled, has no bindings
- picked up acked-by on board bindings patch
- Link to v1: https://lore.kernel.org/r/20240103-add-am64-som-v1-0-dda1f9227aef at solid-run.com

---
Josua Mayer (4):
      dt-bindings: arm: ti: Add bindings for SolidRun AM642 HummingBoard-T
      dt-bindings: rtc: abx80x: convert to yaml
      arm64: dts: add description for solidrun am642 som and evaluation board
      arm64: dts: ti: hummingboard-t: add overlays for m.2 pci-e and usb-3

Suman Anna (1):
      arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes

 Documentation/devicetree/bindings/arm/ti/k3.yaml   |   7 +
 .../devicetree/bindings/rtc/abracon,abx80x.txt     |  31 --
 .../devicetree/bindings/rtc/abracon,abx80x.yaml    |  79 +++
 arch/arm64/boot/dts/ti/Makefile                    |   7 +
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi           |  24 +
 .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  |  45 ++
 .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  |  44 ++
 arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 594 +++++++++++++++++++++
 9 files changed, 1092 insertions(+), 31 deletions(-)
---
base-commit: 798d1ee1675be84d5c7eb639480aab33f2c8791e
change-id: 20240101-add-am64-som-51a1ca47edf3

Sincerely,
-- 
Josua Mayer <josua at solid-run.com>



From josua at solid-run.com  Sun Feb 11 07:07:58 2024
From: josua at solid-run.com (Josua Mayer)
Date: Sun, 11 Feb 2024 16:07:58 +0100
Subject: [PATCH v5 3/5] arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
In-Reply-To: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
Message-ID: <20240211-add-am64-som-v5-3-790ed7121249@solid-run.com>

From: Suman Anna <s-anna at ti.com>

The ICSSG IP on AM64x SoCs have two Industrial Ethernet Peripherals (IEPs)
to manage/generate Industrial Ethernet functions such as time stamping.
Each IEP sub-module is sourced from an internal clock mux that can be
derived from either of the IP instance's ICSSG_IEP_GCLK or from another
internal ICSSG CORE_CLK mux. Add both the IEP nodes for both the ICSSG
instances. The IEP clock is currently configured to be derived
indirectly from the ICSSG_ICLK running at 250 MHz.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
Signed-off-by: Suman Anna <s-anna at ti.com>
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index 0be642bc1b86..8130ee02a3d9 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -1232,6 +1232,18 @@ icssg0_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg0_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
+		icssg0_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
 		icssg0_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
@@ -1373,6 +1385,18 @@ icssg1_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg1_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
+		icssg1_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
 		icssg1_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;

-- 
2.35.3



From josua at solid-run.com  Sun Feb 11 07:08:00 2024
From: josua at solid-run.com (Josua Mayer)
Date: Sun, 11 Feb 2024 16:08:00 +0100
Subject: [PATCH v5 5/5] arm64: dts: ti: hummingboard-t: add overlays for
 m.2 pci-e and usb-3
In-Reply-To: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
Message-ID: <20240211-add-am64-som-v5-5-790ed7121249@solid-run.com>

HummingBoard-T features two M.2 connectors labeled "M1" and "M2".
The single SerDes lane of the SoC can be routed to either M1 pci-e
signals, or M2 usb-3 signals by a gpio-controlled mux.

Add overlays for each configuration.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/Makefile                    |  6 +++
 .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  | 45 ++++++++++++++++++++++
 .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  | 44 +++++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 041c3b71155e..ace72b4b85b0 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -31,8 +31,14 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb
 
 # Boards with AM64x SoC
+k3-am642-hummingboard-t-pcie-dtbs := \
+	k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-pcie.dtbo
+k3-am642-hummingboard-t-usb3-dtbs := \
+	k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-usb3.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-pcie.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-usb3.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
new file mode 100644
index 000000000000..fd3f8d00c56a
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable PCI-E.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&pcie0_rc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_pins_default>;
+	reset-gpios = <&main_gpio1 15 GPIO_ACTIVE_HIGH>;
+	phys = <&serdes0_link>;
+	phy-names = "pcie-phy";
+	num-lanes = <1>;
+	status = "okay";
+};
+
+&serdes0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	serdes0_link: phy at 0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		cdns,phy-type = <PHY_TYPE_PCIE>;
+		#phy-cells = <0>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes_ln_ctrl {
+	idle-states = <AM64_SERDES0_LANE0_PCIE0>;
+};
+
+&serdes_mux {
+	idle-state = <1>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
new file mode 100644
index 000000000000..ffcc3bd3c7bc
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable USB-3.1.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&serdes0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	serdes0_link: phy at 0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		cdns,phy-type = <PHY_TYPE_USB3>;
+		#phy-cells = <0>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes_ln_ctrl {
+	idle-states = <AM64_SERDES0_LANE0_USB>;
+};
+
+&serdes_mux {
+	idle-state = <0>;
+};
+
+&usbss0 {
+	/delete-property/ ti,usb2-only;
+};
+
+&usb0 {
+	maximum-speed = "super-speed";
+	phys = <&serdes0_link>;
+	phy-names = "cdns3,usb3-phy";
+};

-- 
2.35.3



From josua at solid-run.com  Sun Feb 11 07:07:59 2024
From: josua at solid-run.com (Josua Mayer)
Date: Sun, 11 Feb 2024 16:07:59 +0100
Subject: [PATCH v5 4/5] arm64: dts: add description for solidrun am642 som
 and evaluation board
In-Reply-To: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
Message-ID: <20240211-add-am64-som-v5-4-790ed7121249@solid-run.com>

Add description for the SolidRun AM642 SoM, and HummingBoard-T
evaluation board.

The SoM features:
- 1x cpsw ethernet with phy
- 2x pru ethernet with phy
- eMMC
- spi flash (assembly option)

Additionally microSD and usb-2.0 otg are included in the SoM
description as they are supported boot sources for the SOC boot-rom.

The Carrier provides:
- 3x RJ45 connector
- 2x M.2 connector
- USB-2.0 Hub
- USB-A Connector
- LEDs
- 2x CAN transceiver
- 1x RS485 transceiver
- sensors

The M.2 connectors support either USB-3.1 or PCI-E depending on status
of a mux. By default the mux is switched off.

Signed-off-by: Josua Mayer <josua at solid-run.com>
Reviewed-by: Andrew Davis <afd at ti.com>
---
 arch/arm64/boot/dts/ti/Makefile                    |   1 +
 arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 594 +++++++++++++++++++++
 3 files changed, 887 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 77a347f9f47d..041c3b71155e 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -32,6 +32,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62p5-sk.dtb
 
 # Boards with AM64x SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
new file mode 100644
index 000000000000..ebaf281e1e1e
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * DTS for SolidRun AM642 HummingBoard-T,
+ * running on Cortex A53.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-am642.dtsi"
+#include "k3-am642-sr-som.dtsi"
+
+/ {
+	model = "SolidRun AM642 HummingBoard-T";
+	compatible = "solidrun,am642-hummingboard-t", "solidrun,am642-sr-som", "ti,am642";
+
+	aliases {
+		serial5 = &main_uart3;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&leds_pins_default>;
+
+		/* D24 */
+		led1: led-1 {
+			label = "led1";
+			gpios = <&main_gpio0 29 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		/* D25 */
+		led2: led-2 {
+			label = "led2";
+			gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		/* D26 */
+		led3: led-3 {
+			label = "led3";
+			gpios = <&main_gpio0 33 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+	};
+
+	regulator-m2-3v3 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&regulator_pcie_3v3_pins_default>;
+		regulator-name = "m2-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&main_gpio1 17 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	regulator-vpp-1v8 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&regulator_vpp_1v8_pins_default>;
+		regulator-name = "vpp-1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		gpio = <&main_gpio1 78 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	serdes_mux: mux-controller {
+		compatible = "gpio-mux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&serdes_mux_pins_default>;
+		#mux-control-cells = <0>;
+		/*
+		 * Mux has 2 IOs:
+		 * - select: 0 = USB-3 (M2); 1 = PCIE (M1)
+		 * - shutdown: 0 = active; 1 = disabled (high impedance)
+		 */
+		mux-gpios = <&main_gpio1 40 GPIO_ACTIVE_HIGH>, <&main_gpio1 41 GPIO_ACTIVE_HIGH>;
+		/* default disabled */
+		idle-state = <2>;
+	};
+};
+
+&main_gpio0 {
+	m2-reset-hog {
+		gpio-hog;
+		gpios = <12 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m2-reset";
+	};
+
+	m1-m2-w-disable1-hog {
+		gpio-hog;
+		gpios = <32 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m1-m2-pcie-w-disable1";
+	};
+
+	m1-m2-w-disable2-hog {
+		gpio-hog;
+		gpios = <34 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m1-m2-pcie-w-disable2";
+	};
+};
+
+&main_gpio1 {
+	m1-pcie-clkreq0-hog {
+		gpio-hog;
+		gpios = <11 GPIO_ACTIVE_LOW>;
+		input;
+		line-name = "m1-pcie-clkreq0";
+	};
+
+	m2-pcie-clkreq-hog {
+		gpio-hog;
+		gpios = <35 GPIO_ACTIVE_LOW>;
+		input;
+		line-name = "m2-pcie-clkreq";
+	};
+};
+
+&main_i2c0 {
+	pinctrl-0 = <&main_i2c0_pins_default>, <&main_i2c0_int_pins_default>;
+
+	humidity-sensor at 41 {
+		compatible = "ti,hdc2010";
+		reg = <0x41>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+	light-sensor at 44 {
+		compatible = "ti,opt3001";
+		reg = <0x44>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+	/* charger at 6a */
+};
+
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	status = "okay";
+
+	rtc at 69 {
+		compatible = "abracon,abx80x";
+		reg = <0x69>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtc_int_pins_default>;
+		abracon,tc-diode = "schottky";
+		abracon,tc-resistor = <3>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
+
+&main_mcan0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan0_pins_default>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <8000000>;
+	};
+};
+
+&main_mcan1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan1_pins_default>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <8000000>;
+	};
+};
+
+&main_pmx0 {
+	leds_pins_default: leds-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0074, PIN_OUTPUT, 7)	/* GPMC0_AD14.GPIO0_29 */
+			AM64X_IOPAD(0x0078, PIN_OUTPUT, 7)	/* GPMC0_AD15.GPIO0_30 */
+			AM64X_IOPAD(0x0088, PIN_OUTPUT, 7)	/* GPMC0_OEn_REn.GPIO0_33 */
+		>;
+	};
+
+	main_i2c0_int_pins_default: main-i2c0-pins-int-default {
+		pinctrl-single,pins = <
+			/* external pull-up on Carrier */
+			AM64X_IOPAD(0x0098, PIN_INPUT, 7)	/* GPMC0_WAIT0.GPIO0_37 */
+		>;
+	};
+
+	main_i2c1_pins_default: main-i2c1-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x0268, PIN_INPUT, 0)	/* I2C1_SCL.I2C1_SCL */
+			AM64X_IOPAD(0x026c, PIN_INPUT, 0)	/* I2C1_SDA.I2C1_SDA */
+		>;
+	};
+
+	main_mcan0_pins_default: main-mcan0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0254, PIN_INPUT, 0)	/* MCAN0_RX.MCAN0_RX */
+			AM64X_IOPAD(0x0250, PIN_OUTPUT, 0)	/* MCAN0_TX.MCAN0_TX */
+		>;
+	};
+
+	main_mcan1_pins_default: main-mcan1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x025c, PIN_INPUT, 0)	/* MCAN1_RX.MCAN1_RX */
+			AM64X_IOPAD(0x0258, PIN_OUTPUT, 0)	/* MCAN1_TX.MCAN1_TX */
+		>;
+	};
+
+	main_uart3_pins_default: main-uart3-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x016c, PIN_INPUT, 10)	/* PRG0_PRU0_GPO3.UART3_CTSn */
+			AM64X_IOPAD(0x0170, PIN_OUTPUT, 10)	/* PRG0_PRU0_GPO4.UART3_TXD */
+			AM64X_IOPAD(0x0174, PIN_OUTPUT, 10)	/* PRG0_PRU0_GPO5.UART3_RTSn */
+			AM64X_IOPAD(0x01ac, PIN_INPUT, 10)	/* PRG0_PRU0_GPO19.UART3_RXD */
+		>;
+	};
+
+	pcie0_pins_default: pcie0-pins-default {
+		pinctrl-single,pins = <
+			/* connector M2 RESET */
+			AM64X_IOPAD(0x0030, PIN_OUTPUT, 7)	/* OSPI0_CSn1.GPIO0_12 */
+			/* connectors M1 & M2 W_DISABLE1 */
+			AM64X_IOPAD(0x0084, PIN_OUTPUT, 7)	/* GPMC0_ADVN_ALE.GPIO0_32 */
+			/* connectors M1 & M2 W_DISABLE2 */
+			AM64X_IOPAD(0x008c, PIN_OUTPUT, 7)	/* GPMC0_WEN.GPIO0_34 */
+			/* connectors M1 & M2 PERST0 (PCI Reset) */
+			AM64X_IOPAD(0x019c, PIN_OUTPUT, 7)	/* PRG0_PRU0_GPO15.GPIO1_15 */
+			/* connector M1 CLKREQ0 */
+			AM64X_IOPAD(0x018c, PIN_INPUT, 7)	/* PRG0_PRU0_GPO11.GPIO1_11 */
+			/* connector M2 CLKREQ0 */
+			AM64X_IOPAD(0x01ec, PIN_INPUT, 7)	/* PRG0_PRU1_GPO15.GPIO1_35 */
+		>;
+	};
+
+	regulator_pcie_3v3_pins_default: regulator-pcie-3v3-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01a4, PIN_OUTPUT, 7)	/* PRG0_PRU0_GPO17.GPIO1_17 */
+		>;
+	};
+
+	regulator_vpp_1v8_pins_default: regulator-vpp-1v8-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x029c, PIN_OUTPUT, 7)	/* MMC1_SDWP.GPIO1_78 */
+		>;
+	};
+
+	rtc_int_pins_default: rtc-int-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-up on Carrier */
+			AM64X_IOPAD(0x00b4, PIN_INPUT, 7)	/* GPMC0_CSn3.GPIO0_44 */
+		>;
+	};
+
+	serdes_mux_pins_default: serdes-mux-pins-default {
+		pinctrl-single,pins = <
+			/* SEL, 10k pull-down on carrier, 2.2k pullup on SoM */
+			AM64X_IOPAD(0x0200, PIN_OUTPUT, 7)	/* PRG0_MDIO0_MDIO.GPIO1_40 */
+			/* EN */
+			AM64X_IOPAD(0x0204, PIN_OUTPUT, 7)	/* PRG0_MDIO0_MDC.GPIO1_41 */
+		>;
+	};
+};
+
+&main_uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart3_pins_default>;
+	uart-has-rtscts;
+	rs485-rts-active-low;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+&usb0 {
+	dr_mode = "host";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
new file mode 100644
index 000000000000..1602c3321165
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
@@ -0,0 +1,594 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ */
+
+#include <dt-bindings/net/ti-dp83869.h>
+
+/ {
+	model = "SolidRun AM642 SoM";
+	compatible = "solidrun,am642-sr-som", "ti,am642";
+
+	aliases {
+		ethernet0 = &cpsw_port1;
+		ethernet1 = &icssg1_emac0;
+		ethernet2 = &icssg1_emac1;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		serial2 = &main_uart0;
+	};
+
+	chosen {
+		/* SoC default UART console */
+		stdout-path = "serial2:115200n8";
+	};
+
+	/* PRU Ethernet Controller */
+	ethernet {
+		compatible = "ti,am642-icssg-prueth";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pru_rgmii1_pins_default>, <&pru_rgmii2_pins_default>;
+
+		sram = <&oc_sram>;
+		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
+		firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
+
+		/* configure internal pinmux for mii mode */
+		ti,pruss-gp-mux-sel = <2>, <2>, <2>, <2>, <2>, <2>;
+
+		ti,mii-g-rt = <&icssg1_mii_g_rt>;
+		ti,mii-rt = <&icssg1_mii_rt>;
+		ti,iep = <&icssg1_iep0>, <&icssg1_iep1>;
+
+		/*
+		 * Configure icssg interrupt controller to map pru-internal
+		 * interrupts 8/9 via channels 0/1 to host interrupts 0/1.
+		 *
+		 * For details see interrupt controller documentation:
+		 * Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
+		 */
+		interrupt-parent = <&icssg1_intc>;
+		interrupts = <24 0 2>, <25 1 3>;
+		interrupt-names = "tx_ts0", "tx_ts1";
+
+		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
+		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
+		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
+		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+			    "rx0", "rx1";
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			icssg1_emac0: port at 0 {
+				reg = <0>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4110>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				phy-handle = <&ethernet_phy2>;
+				phy-mode = "rgmii-id";
+			};
+
+			icssg1_emac1: port at 1 {
+				reg = <1>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4114>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				phy-handle = <&ethernet_phy1>;
+				phy-mode = "rgmii-id";
+			};
+		};
+	};
+
+	/* DDR16SS0:
+	 * - Bank 1 @ 0x080000000-0x0FFFFFFFF: max. 2GB in 32-bit address space
+	 * - Bank 2 @ 0x880000000-0x9FFFFFFFF: max. 6GB in 64-bit address space
+	 */
+	memory at 80000000 {
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+		      <0x00000008 0x80000000 0x00000001 0x80000000>;
+		device_type = "memory";
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		secure_ddr: optee at 9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+			no-map;
+		};
+
+		main_r5fss0_core0_dma_memory_region: r5f-dma-memory at a0000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_memory_region: r5f-memory at a0100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_dma_memory_region: r5f-dma-memory at a1000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_memory_region: r5f-memory at a1100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_dma_memory_region: r5f-dma-memory at a2000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_memory_region: r5f-memory at a2100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_dma_memory_region: r5f-dma-memory at a3000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_memory_region: r5f-memory at a3100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3100000 0x00 0xf00000>;
+			no-map;
+		};
+	};
+
+	vdd_mmc0: regulator-vdd-mmc0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd-mmc0";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&cpsw3g {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins_default>;
+};
+
+&cpsw3g_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio0_pins_default>;
+	status = "okay";
+
+	ethernet_phy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy0_pins_default>;
+		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 84 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+};
+
+&cpsw_port1 {
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy0>;
+};
+
+&cpsw_port2 {
+	status = "disabled";
+};
+
+&icssg1_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pru1_mdio0_pins_default>;
+	status = "okay";
+
+	ethernet_phy1: ethernet-phy at 3 {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy1_pins_default>;
+		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 20 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+
+	ethernet_phy2: ethernet-phy at f {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <0xf>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy2_pins_default>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 52 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+};
+
+&mailbox0_cluster2 {
+	status = "okay";
+
+	mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+
+	mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+		ti,mbox-rx = <2 0 2>;
+		ti,mbox-tx = <3 0 2>;
+	};
+};
+
+&mailbox0_cluster4 {
+	status = "okay";
+
+	mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+
+	mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+		ti,mbox-rx = <2 0 2>;
+		ti,mbox-tx = <3 0 2>;
+	};
+};
+
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	status = "okay";
+
+	som_eeprom: eeprom at 50 {
+		compatible = "atmel,24c01";
+		reg = <0x50>;
+		pagesize = <8>;
+	};
+};
+
+&main_pmx0 {
+	/* hog global functions */
+	pinctrl-names = "default";
+	pinctrl-0 = <&ethernet_phy_pins_default>;
+
+	ethernet_phy_pins_default: ethernet-phy-pins-default {
+		pinctrl-single,pins = <
+			/* interrupt / power-down, external pull-up on SoM */
+			AM64X_IOPAD(0x0278, PIN_INPUT, 7)	/* EXTINTn.GPIO1_70 */
+		>;
+	};
+
+	ethernet_phy0_pins_default: ethernet-phy0-pins-default {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x0154, PIN_OUTPUT, 7)	/* PRG1_PRU1_GPO19.GPIO0_84 */
+			/* reference clock */
+			AM64X_IOPAD(0x0274, PIN_OUTPUT, 5)	/* EXT_REFCLK1.CLKOUT0 */
+		>;
+	};
+
+	ethernet_phy1_pins_default: ethernet-phy1-pins-default {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x0150, PIN_OUTPUT, 7)	/* PRG1_PRU1_GPO18.GPIO0_20 */
+			/* led0, external pull-down on SoM */
+			AM64X_IOPAD(0x0128, PIN_INPUT, 7)	/* PRG1_PRU1_GPO8.GPIO0_73 */
+			/* led1/rxer */
+			AM64X_IOPAD(0x011c, PIN_INPUT, 7)	/* PRG1_PRU1_GPO5.GPIO0_70 */
+		>;
+	};
+
+	ethernet_phy2_pins_default: ethernet-phy2-pins-default {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x00d4, PIN_OUTPUT, 7)	/* PRG1_PRU0_GPO7.GPIO0_52 */
+			/* led0, external pull-down on SoM */
+			AM64X_IOPAD(0x00d8, PIN_INPUT, 7)	/* PRG1_PRU0_GPO8.GPIO0_53 */
+			/* led1/rxer */
+			AM64X_IOPAD(0x00cc, PIN_INPUT, 7)	/* PRG1_PRU0_GPO5.GPIO0_50 */
+		>;
+	};
+
+	main_i2c0_pins_default: main-i2c0-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x0260, PIN_INPUT, 0)	/* I2C0_SCL.I2C0_SCL */
+			AM64X_IOPAD(0x0264, PIN_INPUT, 0)	/* I2C0_SDA.I2C0_SDA */
+		>;
+	};
+
+	/*
+	 * main_mmc0_pins_default: main-mmc0-pins-default
+	 *
+	 * MMC0_CMD: no padconfig
+	 * MMC0_CLK: no padconfig, external pull-up on SoM
+	 * MMC0_DAT0: no padconfig
+	 * MMC0_DAT1: no padconfig
+	 * MMC0_DAT2: no padconfig
+	 * MMC0_DAT3: no padconfig
+	 * MMC0_DAT4: no padconfig
+	 * MMC0_DAT5: no padconfig
+	 * MMC0_DAT6: no padconfig
+	 * MMC0_DAT7: no padconfig
+	 * MMC0_DS: no padconfig, external pull-down on SoM
+	 */
+
+	main_mmc1_pins_default: main-mmc1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0294, PIN_INPUT_PULLUP, 0)	/* (J19) MMC1_CMD */
+			AM64X_IOPAD(0x028c, PIN_INPUT, 0)		/* MMC1_CLK.MMC1_CLK */
+			AM64X_IOPAD(0x0288, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT0.MMC1_DAT0 */
+			AM64X_IOPAD(0x0284, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT1.MMC1_DAT1 */
+			AM64X_IOPAD(0x0280, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT2.MMC1_DAT2 */
+			AM64X_IOPAD(0x027c, PIN_INPUT_PULLUP, 0)	/* MMC1_DAT3.MMC1_DAT3 */
+			/* external pull-down on SoM & Carrier */
+			AM64X_IOPAD(0x0298, PIN_INPUT_PULLUP, 0)	/* MMC1_SDCD.MMC1_SDCD */
+			AM64X_IOPAD(0x0290, PIN_INPUT, 0)		/* MMC1_CLKLB: clock loopback */
+		>;
+	};
+
+	main_uart0_pins_default: main-uart0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0230, PIN_INPUT, 0)		/* UART0_RXD.UART0_RXD */
+			AM64X_IOPAD(0x0234, PIN_OUTPUT, 0)		/* UART0_TXD.UART0_TXD */
+		>;
+	};
+
+	mdio0_pins_default: mdio0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01fc, PIN_OUTPUT, 4)		/* PRG0_PRU1_GPO19.MDIO0_MDC */
+			AM64X_IOPAD(0x01f8, PIN_INPUT, 4)		/* PRG0_PRU1_GPO18.MDIO0_MDIO */
+		>;
+	};
+
+	ospi0_pins_default: ospi0-pins-default {
+		pinctrl-single,pins = <
+			/* external pull-down on SoM */
+			AM64X_IOPAD(0x0000, PIN_OUTPUT, 0)		/* OSPI0_CLK.OSPI0_CLK */
+			AM64X_IOPAD(0x0008, PIN_OUTPUT, 0)		/* OSPI0_DQS.OSPI0_DQS */
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x002c, PIN_OUTPUT, 0)		/* OSPI0_CSn0.OSPI0_CSn0 */
+			AM64X_IOPAD(0x000c, PIN_INPUT, 0)		/* OSPI0_D0.OSPI0_D0 */
+			AM64X_IOPAD(0x0010, PIN_INPUT, 0)		/* OSPI0_D1.OSPI0_D1 */
+			AM64X_IOPAD(0x0014, PIN_INPUT, 0)		/* OSPI0_D2.OSPI0_D2 */
+			AM64X_IOPAD(0x0018, PIN_INPUT, 0)		/* OSPI0_D3.OSPI0_D3 */
+			AM64X_IOPAD(0x001c, PIN_INPUT, 0)		/* OSPI0_D4.OSPI0_D4 */
+			AM64X_IOPAD(0x0020, PIN_INPUT, 0)		/* OSPI0_D5.OSPI0_D5 */
+			AM64X_IOPAD(0x0024, PIN_INPUT, 0)		/* OSPI0_D6.OSPI0_D6 */
+			AM64X_IOPAD(0x0028, PIN_INPUT, 0)		/* OSPI0_D7.OSPI0_D7 */
+		>;
+	};
+
+	ospi0_flash0_pins_default: ospi0-flash0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0034, PIN_OUTPUT, 7)		/* OSPI0_CSn2.GPIO0_13 */
+			AM64X_IOPAD(0x0038, PIN_INPUT, 7)		/* OSPI0_CSn3.GPIO0_14 */
+		>;
+	};
+
+	pru1_mdio0_pins_default: pru1-mdio0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0)		/* PRG1_MDIO0_MDC.PRG1_MDIO0_MDC */
+			AM64X_IOPAD(0x0158, PIN_INPUT, 0)		/* PRG1_MDIO0_MDIO.PRG1_MDIO0_MDIO */
+		>;
+	};
+
+	pru_rgmii1_pins_default: pru-rgmii1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x00b8, PIN_INPUT, 2)		/* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
+			AM64X_IOPAD(0x00bc, PIN_INPUT, 2)		/* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
+			AM64X_IOPAD(0x00c0, PIN_INPUT, 2)		/* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
+			AM64X_IOPAD(0x00c4, PIN_INPUT, 2)		/* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
+			AM64X_IOPAD(0x00d0, PIN_INPUT, 2)		/* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
+			AM64X_IOPAD(0x00c8, PIN_INPUT, 2)		/* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
+			AM64X_IOPAD(0x00e4, PIN_OUTPUT, 2)		/* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
+			AM64X_IOPAD(0x00e8, PIN_OUTPUT, 2)		/* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
+			AM64X_IOPAD(0x00ec, PIN_OUTPUT, 2)		/* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
+			AM64X_IOPAD(0x00f0, PIN_OUTPUT, 2)		/* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
+			AM64X_IOPAD(0x00f8, PIN_INPUT, 2)		/* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
+			AM64X_IOPAD(0x00f4, PIN_OUTPUT, 2)		/* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
+		>;
+	};
+
+	pru_rgmii2_pins_default: pru-rgmii2-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0108, PIN_INPUT, 2)		/* PRG1_PRU1_GPO0.RGMII2_RD0 */
+			AM64X_IOPAD(0x010c, PIN_INPUT, 2)		/* PRG1_PRU1_GPO1.RGMII2_RD1 */
+			AM64X_IOPAD(0x0110, PIN_INPUT, 2)		/* PRG1_PRU1_GPO2.RGMII2_RD2 */
+			AM64X_IOPAD(0x0114, PIN_INPUT, 2)		/* PRG1_PRU1_GPO3.RGMII2_RD3 */
+			AM64X_IOPAD(0x0120, PIN_INPUT, 2)		/* PRG1_PRU1_GPO6.RGMII2_RXC */
+			AM64X_IOPAD(0x0118, PIN_INPUT, 2)		/* PRG1_PRU1_GPO4.RGMII2_RX_CTL */
+			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO11.RGMII2_TD0 */
+			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO12.RGMII2_TD1 */
+			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO13.RGMII2_TD2 */
+			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO14.RGMII2_TD3 */
+			AM64X_IOPAD(0x0148, PIN_INPUT, 2)		/* PRG1_PRU1_GPO16.RGMII2_TXC */
+			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2)		/* PRG1_PRU1_GPO15.RGMII2_TX_CTL */
+		>;
+	};
+
+	rgmii1_pins_default: rgmii1-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01cc, PIN_INPUT, 4)		/* PRG0_PRU1_GPO7.RGMII1_RD0 */
+			AM64X_IOPAD(0x01d4, PIN_INPUT, 4)		/* PRG0_PRU1_GPO9.RGMII1_RD1 */
+			AM64X_IOPAD(0x01d8, PIN_INPUT, 4)		/* PRG0_PRU1_GPO10.RGMII1_RD2 */
+			AM64X_IOPAD(0x01f4, PIN_INPUT, 4)		/* PRG0_PRU1_GPO17.RGMII1_RD3 */
+			AM64X_IOPAD(0x0188, PIN_INPUT, 4)		/* PRG0_PRU0_GPO10.RGMII1_RXC */
+			AM64X_IOPAD(0x0184, PIN_INPUT, 4)		/* PRG0_PRU0_GPO9.RGMII1_RX_CTL */
+			AM64X_IOPAD(0x0124, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO7.RGMII1_TD0 */
+			AM64X_IOPAD(0x012c, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO9.RGMII1_TD1 */
+			AM64X_IOPAD(0x0130, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO10.RGMII1_TD2 */
+			AM64X_IOPAD(0x014c, PIN_OUTPUT, 4)		/* PRG1_PRU1_GPO17.RGMII1_TD3 */
+			AM64X_IOPAD(0x00e0, PIN_INPUT, 4)		/* PRG1_PRU0_GPO10.RGMII1_TXC */
+			AM64X_IOPAD(0x00dc, PIN_OUTPUT, 4)		/* PRG1_PRU0_GPO9.RGMII1_TX_CTL */
+		>;
+	};
+
+	usb0_pins_default: usb0-pins-default {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0)		/* USB0_DRVVBUS.USB0_DRVVBUS */
+		>;
+	};
+};
+
+&main_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core0>;
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0_core1 {
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core1>;
+	memory-region = <&main_r5fss0_core1_dma_memory_region>,
+			<&main_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss1_core0 {
+	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core0>;
+	memory-region = <&main_r5fss1_core0_dma_memory_region>,
+			<&main_r5fss1_core0_memory_region>;
+};
+
+&main_r5fss1_core1 {
+	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core1>;
+	memory-region = <&main_r5fss1_core1_dma_memory_region>,
+			<&main_r5fss1_core1_memory_region>;
+};
+
+/* SoC default UART console */
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_pins_default>;
+	status = "okay";
+};
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_pins_default>;
+	num-cs = <1>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ospi0_flash0_pins_default>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <200000000>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
+		cdns,read-delay = <0>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&main_gpio0 13 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&sdhci0 {
+	/* mmc0 pins have no padconfig */
+	bus-width = <8>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+	non-removable;
+	cap-mmc-hw-reset;
+	no-sd;
+	/*
+	 * MMC controller supports switching between 1.8V and 3.3V signalling.
+	 * However MMC0 (unlike MMC1) does not integrate an LDO.
+	 * Explicitly link a regulator node for indicating to the driver which
+	 * voltages are actually usable.
+	 */
+	vqmmc-supply = <&vdd_mmc0>;
+	status = "okay";
+};
+
+/*
+ * microSD is on carrier - however since SoC can boot from it,
+ * configure it just in case.
+ */
+&sdhci1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_pins_default>;
+	bus-width = <4>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+	status = "okay";
+};
+
+/*
+ * USB settings are a carrier choice - however since SoC can boot from it,
+ * configure as USB-2.0 OTG here, keeping USB-3 serdes disabled.
+ */
+&usb0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins_default>;
+	dr_mode = "otg";
+	maximum-speed = "high-speed";
+};
+
+&usbss0 {
+	ti,vbus-divider;
+	ti,usb2-only;
+};

-- 
2.35.3



From josua at solid-run.com  Sun Feb 11 07:07:57 2024
From: josua at solid-run.com (Josua Mayer)
Date: Sun, 11 Feb 2024 16:07:57 +0100
Subject: [PATCH v5 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
Message-ID: <20240211-add-am64-som-v5-2-790ed7121249@solid-run.com>

Convert the abracon abx80x rtc text bindings to dt-schema format.

In addition to the text description reference generic interrupts
properties and add an example.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ---------
 .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 79 ++++++++++++++++++++++
 2 files changed, 79 insertions(+), 31 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
deleted file mode 100644
index 2405e35a1bc0..000000000000
--- a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-Abracon ABX80X I2C ultra low power RTC/Alarm chip
-
-The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
-ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
-is the superset of ab180x.
-
-Required properties:
-
- - "compatible": should one of:
-        "abracon,abx80x"
-        "abracon,ab0801"
-        "abracon,ab0803"
-        "abracon,ab0804"
-        "abracon,ab0805"
-        "abracon,ab1801"
-        "abracon,ab1803"
-        "abracon,ab1804"
-        "abracon,ab1805"
-        "microcrystal,rv1805"
-	Using "abracon,abx80x" will enable chip autodetection.
- - "reg": I2C bus address of the device
-
-Optional properties:
-
-The abx804 and abx805 have a trickle charger that is able to charge the
-connected battery or supercap. Both the following properties have to be defined
-and valid to enable charging:
-
- - "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
- - "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
-                          resistor, the other values are in kOhm.
diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
new file mode 100644
index 000000000000..58dbbca27deb
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Abracon ABX80X I2C ultra low power RTC/Alarm chip
+
+maintainers:
+  - linux-rtc at vger.kernel.org
+
+allOf:
+  - $ref: rtc.yaml#
+
+properties:
+  compatible:
+    description:
+      The wildcard 'abracon,abx80x' may be used to support a mix
+      of different abracon rtc`s. In this case the driver
+      must perform auto-detection from ID register.
+    enum:
+      - abracon,abx80x
+      - abracon,ab0801
+      - abracon,ab0803
+      - abracon,ab0804
+      - abracon,ab0805
+      - abracon,ab1801
+      - abracon,ab1803
+      - abracon,ab1804
+      - abracon,ab1805
+      - microcrystal,rv1805
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  abracon,tc-diode:
+    description:
+      Trickle-charge diode type.
+      Required to enable charging backup battery.
+
+      Supported are 'standard' diodes with a 0.6V drop
+      and 'schottky' diodes with a 0.3V drop.
+    $ref: /schemas/types.yaml#/definitions/string
+    enum:
+      - standard
+      - schottky
+
+  abracon,tc-resistor:
+    description:
+      Trickle-charge resistor value in kOhm.
+      Required to enable charging backup battery.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 3, 6, 11]
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        rtc at 69 {
+            compatible = "abracon,abx80x";
+            reg = <0x69>;
+            abracon,tc-diode = "schottky";
+            abracon,tc-resistor = <3>;
+            interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
+        };
+    };

-- 
2.35.3



From frank at oltmanns.dev  Sun Feb 11 07:09:16 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Sun, 11 Feb 2024 16:09:16 +0100
Subject: [PATCH v2 0/6] Pinephone video out fixes (flipping between two
 frames)
In-Reply-To: <bgyyemyi4shj3spo6qy4icvk56nrp5sihnzqurnozqdyktwugc@ikurx4ojoxpi>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <jzl3mlzk4j7qvgcedvipgale5nhinznefodrnaehwsqfnseiwc@7zzlxd4dpueh>
 <bgyyemyi4shj3spo6qy4icvk56nrp5sihnzqurnozqdyktwugc@ikurx4ojoxpi>
Message-ID: <87wmrbxckj.fsf@oltmanns.dev>

Hi Ond?ej,

On 2024-02-05 at 17:02:00 +0100, Ond?ej Jirman <megi at xff.cz> wrote:
> On Mon, Feb 05, 2024 at 04:54:07PM +0100, Ond?ej Jirman wrote:
>> On Mon, Feb 05, 2024 at 04:22:23PM +0100, Frank Oltmanns wrote:
>> > On some pinephones the video output sometimes freezes (flips between two
>> > frames) [1]. It seems to be that the reason for this behaviour is that
>> > PLL-MIPI, PLL-GPU and GPU are operating outside their limits.
>> >
>> > In this patch series I propose the followin changes:
>> >   1. sunxi-ng: Adhere to the following constraints given in the
>> >      Allwinner A64 Manual regarding PLL-MIPI:
>> >       * M/N <= 3
>> >       * (PLL_VIDEO0)/M >= 24MHz
>> >       * 500MHz <= clockrate <= 1400MHz
>> >
>> >   2. Choose a higher clock rate for the ST7703 based XDB599 panel, so
>> >      that the panel function well with the Allwinner A64 SOC. PLL-MIPI
>> >      must run between 500 MHz and 1.4 GHz. As PLL-MIPI runs at 6 times
>> >      the panel's clock rate, we need the panel's clock to be at least
>> >      83.333 MHz.
>> >
>> >   3. Increase the minimum frequency in the A64 DTS OPPs from 120 MHz to
>> >      192 MHz. This further reduces the issue.
>> >
>> > Unfortunately, with these patches the issue [1] is not completely gone,
>> > but becomes less likely.
>> >
>> > Note, that when pinning the GPU to 432 MHz the issue completely
>> > disappears for me. I've searched the BSP and could not find any
>> > indication that supports the idea of having the three OPPs. The only
>> > frequency I found in the BPSs for A64 is 432 MHz, that has also proven
>> > stable for me. So, while increasing the minimum frequency to 192 MHz
>> > reduces the issue, should we maybe instead set the GPU to a fixed 432
>> > MHz instead?
>>
>> Per A64 User Manual 1.1 page 81:
>>
>> (9). Clock output of PLL_GPU can be used for GPU;and dynamic frequency scaling is not supported;
>
> You may be able to elegantly work around this by pinning PLL_GPU to a certain
> frequency (assing it in DT and then don't decalre gpu clock as
> CLK_SET_RATE_PARENT). Say 432 MHz for PLL and then do the scaling via GPU_CLK_REG
> N divider between 432MHz and 216MHz and maybe 108MHz if that brings any gains.
>

I really like this idea. Unfortunately, it seems that the divisor of the
GPU_CLK_REG must always be set to 1. I tried to convey this info in the
commit message for PATCH 6. If using a different divisor than 1 the bug
I'm trying to fix here occurs within minutes. Nevertheless, I gave your
proposal a quick try - it seems so elegant. Unfortunately, but not
unexpectedly, the bug occured almost immediately.

> Then you can perhaps sidestep all these potential issues with PLL_GPU and
> lack of DVFS support decalred in the manual.
>
> regards,
> 	o.
>
>> Also sunxi-ng clk driver does apply NM factors at once to PLL_GPU clock,
>> which can cause sudden frequency increase beyond intended output frequency,
>> because division is applied immediately while multiplication is reflected
>> slowly.
>>
>> Eg. if you're changing divider from 7 to 1, you can get a sudden 7x output
>> frequency spike, before PLL VCO manages to lower the frequency through N clk
>> divider feedback loop and lock on again. This can mess up whatever's connected
>> to the output quite badly.
>>
>> You'd have to put logging on kernel writes to PLL_GPU register to see what
>> is written in there and if divider is lowered significantly on some GPU
>> devfreq frequency transitions.

By looking at the clocks in clk_summary in debugfs, the rate of PLL-GPU
always matches the rate of the GPU (at least at 120, 312, and 432 MHz).
This is further underlined by the fact, that none of the rates can be
achieved by integer dividing one of the other rates. sunxi-ng would
only favor a different rate for pll-gpu than the one that is requested
for the gpu, if pll-gpu is already running at a rate such that there
exists an M ? {1, 2, 3, 4, 5, 6, 7, 8}, where
  rate of pll-gpu / M = requested gpu rate
or if the requested rate could not be reached directly by pll-gpu. Both
is not the case for the rates in question (120, 192, 312, and 432 MHz).

This means that the following divisor/multipliers are used by sunxi-ng's
ccu_nm:
N =  5, M = 1 for 120 MHz (min value without PATCH 6)
N =  8, M = 1 for 192 MHz (min value after applying PATCH 6)
N = 13, M = 1 for 312 MHz
N = 18, M = 1 for 432 MHz

So, with or without PATCH 6, the divider stays constant and it's only
the multiplier that changes. This means, there should be no unexpected
frequency spikes, right?

>> It's also unclear what happens when FRAC_CLK_OUT or PLL_MODE_SEL changes.

Those are not changed once the clock is initialized. The bug however
occurs hours or days after booting. IMO, this makes it unlikely that this
could be the culprit.

>> Maybe not much because M is supposed to be set to 1, but you still need to
>> care when enabling fractional mode, and setting M to 1 because that's exactly
>> the bad scenario if M was previously higher than 1.
>>
>> It's tricky.
>>
>> Having GPU module clock gated during PLL config changes may help! You can
>> do that without locking yourself out, unlike with the CPU PLL.
>>
>> There's a gate enable bit for it at GPU_CLK_REG.SCLK_GATING. (page 122)

The GPU should already be properly gated:
https://elixir.bootlin.com/linux/v6.7.4/source/drivers/clk/sunxi-ng/ccu-sun50i-a64.c#L599

Thank you for your detailed proposal! It was insightful to read. But
while those were all great ideas, they have all already been taken care
of. I'm fresh out of ideas again (except for pinning the GPU rate).

Again, thank you so much,
  Frank

>>
>> Kind regards,
>> 	o.
>>
>> > I very much appreciate your feedback!
>> >
>> > [1] https://gitlab.com/postmarketOS/pmaports/-/issues/805
>> >
>> > Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
>> > ---
>> > Changes in v2:
>> > - dts: Increase minimum GPU frequency to 192 MHz.
>> > - nkm and a64: Add minimum and maximum rate for PLL-MIPI.
>> > - nkm: Use the same approach for skipping invalid rates in
>> >   ccu_nkm_find_best() as in ccu_nkm_find_best_with_parent_adj().
>> > - nkm: Improve names for ratio struct members and hence get rid of
>> >   describing comments.
>> > - nkm and a64: Correct description in the commit messages: M/N <= 3
>> > - Remove patches for nm as they were not needed.
>> > - st7703: Rework the commit message to cover more background for the
>> >   change.
>> > - Link to v1: https://lore.kernel.org/r/20231218-pinephone-pll-fixes-v1-0-e238b6ed6dc1 at oltmanns.dev
>> >
>> > ---
>> > Frank Oltmanns (6):
>> >       clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate
>> >       clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate
>> >       clk: sunxi-ng: nkm: Support minimum and maximum rate
>> >       clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
>> >       drm/panel: st7703: Drive XBD599 panel at higher clock rate
>> >       arm64: dts: allwinner: a64: Fix minimum GPU OPP rate
>> >
>> >  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  4 ++--
>> >  drivers/clk/sunxi-ng/ccu-sun50i-a64.c         | 14 +++++++----
>> >  drivers/clk/sunxi-ng/ccu_nkm.c                | 34 +++++++++++++++++++++++++++
>> >  drivers/clk/sunxi-ng/ccu_nkm.h                |  4 ++++
>> >  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++++------
>> >  5 files changed, 56 insertions(+), 14 deletions(-)
>> > ---
>> > base-commit: 059c53e877ca6e723e10490c27c1487a63e66efe
>> > change-id: 20231218-pinephone-pll-fixes-0ccdfde273e4
>> >
>> > Best regards,
>> > --
>> > Frank Oltmanns <frank at oltmanns.dev>
>> >


From krzysztof.kozlowski at linaro.org  Sun Feb 11 07:39:28 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 16:39:28 +0100
Subject: [PATCH v3 2/5] dt-bindings: fpga: xlnx,fpga-slave-serial: rename
 gpios
In-Reply-To: <20240207180142.79625-3-charles.perry@savoirfairelinux.com>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
 <20240207180142.79625-3-charles.perry@savoirfairelinux.com>
Message-ID: <69679d9a-02e9-498f-8f5a-7c029059a8c1@linaro.org>

On 07/02/2024 19:01, Charles Perry wrote:
> By convention, gpio consumer names should not contain underscores
> (prog_b here) and shouldn't contain active low suffixes (-b here).
> 
> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
> ---
>  .../bindings/fpga/xlnx,fpga-slave-serial.yaml        | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml b/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml
> index 614d86ad825f3..650a4d8792b64 100644
> --- a/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml
> +++ b/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml
> @@ -36,7 +36,7 @@ properties:
>    reg:
>      maxItems: 1
>  
> -  prog_b-gpios:
> +  prog-gpios:

Please deprecate old property and add allOf excluding the usage of both.
Driver still parses old property, so we should have it documented.

https://lore.kernel.org/all/20230118163208.GA117919-robh at kernel.org/

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 07:40:22 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 16:40:22 +0100
Subject: [PATCH v3 3/5] fpga: xilinx-core: rename "prog_b" and "init-b"
 gpios
In-Reply-To: <20240207180142.79625-4-charles.perry@savoirfairelinux.com>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
 <20240207180142.79625-4-charles.perry@savoirfairelinux.com>
Message-ID: <5d1d4bd7-a431-457d-b7f8-141bb609284b@linaro.org>

On 07/02/2024 19:01, Charles Perry wrote:
> New bindings use "prog" and "init". The legacy name is used as a
> fallback.
> 
> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
> ---
>  drivers/fpga/xilinx-core.c | 28 ++++++++++++++++++++++++++--
>  1 file changed, 26 insertions(+), 2 deletions(-)
> 

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From ricardo at marliere.net  Sun Feb 11 07:41:49 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 11 Feb 2024 12:41:49 -0300
Subject: [PATCH] ARM: s3c64xx: make s3c6410_subsys const
Message-ID: <20240211-bus_cleanup-arm-v1-1-5c0102bda0bd@marliere.net>

Now that the driver core can properly handle constant struct bus_type,
move the s3c6410_subsys variable to be a constant structure as well,
placing it into read-only memory which can not be modified at runtime.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 arch/arm/mach-s3c/cpu.h     | 2 +-
 arch/arm/mach-s3c/s3c6410.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-s3c/cpu.h b/arch/arm/mach-s3c/cpu.h
index d0adc9b40e25..a0187606b999 100644
--- a/arch/arm/mach-s3c/cpu.h
+++ b/arch/arm/mach-s3c/cpu.h
@@ -76,6 +76,6 @@ extern void s3c24xx_init_uartdevs(char *name,
 				  struct s3c24xx_uart_resources *res,
 				  struct s3c2410_uartcfg *cfg, int no);
 
-extern struct bus_type s3c6410_subsys;
+extern const struct bus_type s3c6410_subsys;
 
 #endif
diff --git a/arch/arm/mach-s3c/s3c6410.c b/arch/arm/mach-s3c/s3c6410.c
index e79f18d0ca81..a29276a4fde5 100644
--- a/arch/arm/mach-s3c/s3c6410.c
+++ b/arch/arm/mach-s3c/s3c6410.c
@@ -57,7 +57,7 @@ void __init s3c6410_init_irq(void)
 	s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
 }
 
-struct bus_type s3c6410_subsys = {
+const struct bus_type s3c6410_subsys = {
 	.name		= "s3c6410-core",
 	.dev_name	= "s3c6410-core",
 };

---
base-commit: fee3a71dc8d26629e5d87e20cff08763f522633f
change-id: 20240211-bus_cleanup-arm-da0f2550ca48

Best regards,
-- 
Ricardo B. Marliere <ricardo at marliere.net>



From frank at oltmanns.dev  Sun Feb 11 07:42:43 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Sun, 11 Feb 2024 16:42:43 +0100
Subject: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher
 clock rate
In-Reply-To: <poua4bzyciiwt65sqjf2whqfdumvoe4h3bkjpf64px2vwgumrf@sai73byg2iju>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-5-96a46a2d8c9b@oltmanns.dev>
 <poua4bzyciiwt65sqjf2whqfdumvoe4h3bkjpf64px2vwgumrf@sai73byg2iju>
Message-ID: <87sf1zxb0s.fsf@oltmanns.dev>


On 2024-02-08 at 20:05:08 +0100, Maxime Ripard <mripard at kernel.org> wrote:
> [[PGP Signed Part:Undecided]]
> Hi Frank,
>
> On Mon, Feb 05, 2024 at 04:22:28PM +0100, Frank Oltmanns wrote:
>> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
>> The SOC requires pll-mipi to run at more than 500 MHz.
>>
>> This is the relevant clock tree:
>>  pll-mipi
>>     tcon0
>>        tcon-data-clock
>>
>> tcon-data-clock has to run at 1/4 the DSI per-lane bit rate. The XBD599
>> has 24 bpp and 4 lanes. Therefore, the resulting requested
>> tcon-data-clock rate is:
>>     crtc_clock * 1000 * (24 / 4) / 4
>>
>> tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it requests a
>> parent rate of
>>     4 * (crtc_clock * 1000 * (24 / 4) / 4)
>>
>> Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate of pll-mipi.
>>
>> pll-mipi's constraint to run at 500MHz or higher forces us to have a
>> crtc_clock >= 83333 kHz if we want a 60 Hz vertical refresh rate.
>>
>> Change [hv]sync_(start|end) so that we reach a clock rate of 83502 kHz
>> so that it is high enough to align with pll-pipi limits.
>>
>> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
>
> That commit log is great, but it's kind of off-topic. It's a panel
> driver, it can be used on any MIPI-DSI controller, the only relevant
> information there should be the panel timings required in the datasheet.
>
> The PLL setup is something for the MIPI-DSI driver to adjust, not for
> the panel to care for.
>

I absolutely agree. It even was the reason for my submission of a
sunxi-ng patch series last year that was accepted, to make pll-mipi more
flexible. :)

The only remaining option I currently see for adjusting the sunxi-ng
driver to further accomodate the panel, is trying to use a higher
divisor than 4 for calculating tcon-data-clock from tcon0. I remember
reading a discussion about this, but as far as I remember that proposal
was rejected (by you, IIRC).

While I appreciate other suggestion as well, I'll look into options for
using a different divisor than 4.

Best regards,
  Frank

>
> Maxime
>
> [[End of PGP Signed Part]]


From ricardo at marliere.net  Sun Feb 11 07:45:06 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 11 Feb 2024 12:45:06 -0300
Subject: [PATCH 0/2] ARM: struct bus_type cleanup
Message-ID: <20240211-bus_cleanup-rmk-v1-0-65668e578d55@marliere.net>

This series is part of an effort to cleanup the users of the driver
core, as can be seen in many recent patches authored by Greg across the
tree (e.g. [1]).

---
[1]: https://lore.kernel.org/lkml/?q=f%3Agregkh%40linuxfoundation.org+s%3A%22make%22+and+s%3A%22const%22

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

---
Ricardo B. Marliere (2):
      ARM: sa1111: make sa1111_bus_type const
      ARM: ecard: make ecard_bus_type const

 arch/arm/common/sa1111.c               | 2 +-
 arch/arm/include/asm/ecard.h           | 2 +-
 arch/arm/include/asm/hardware/sa1111.h | 2 +-
 arch/arm/mach-rpc/ecard.c              | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)
---
base-commit: 8790fade1a19caf714ba1d91ce1fdceb9f2067f2
change-id: 20240211-bus_cleanup-rmk-7fcb4be84c26

Best regards,
-- 
Ricardo B. Marliere <ricardo at marliere.net>



From ricardo at marliere.net  Sun Feb 11 07:45:07 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 11 Feb 2024 12:45:07 -0300
Subject: [PATCH 1/2] ARM: sa1111: make sa1111_bus_type const
In-Reply-To: <20240211-bus_cleanup-rmk-v1-0-65668e578d55@marliere.net>
References: <20240211-bus_cleanup-rmk-v1-0-65668e578d55@marliere.net>
Message-ID: <20240211-bus_cleanup-rmk-v1-1-65668e578d55@marliere.net>

Now that the driver core can properly handle constant struct bus_type,
move the sa1111_bus_type variable to be a constant structure as well,
placing it into read-only memory which can not be modified at runtime.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 arch/arm/common/sa1111.c               | 2 +-
 arch/arm/include/asm/hardware/sa1111.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 1fbd7363cf11..de5eba0a11f6 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1367,7 +1367,7 @@ static void sa1111_bus_remove(struct device *dev)
 		drv->remove(sadev);
 }
 
-struct bus_type sa1111_bus_type = {
+const struct bus_type sa1111_bus_type = {
 	.name		= "sa1111-rab",
 	.match		= sa1111_match,
 	.probe		= sa1111_bus_probe,
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
index d8c6f8a99dfa..02f3f9ca8582 100644
--- a/arch/arm/include/asm/hardware/sa1111.h
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -368,7 +368,7 @@
 
 
 
-extern struct bus_type sa1111_bus_type;
+extern const struct bus_type sa1111_bus_type;
 
 #define SA1111_DEVID_SBI	(1 << 0)
 #define SA1111_DEVID_SK		(1 << 1)

-- 
2.43.0



From ricardo at marliere.net  Sun Feb 11 07:45:08 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 11 Feb 2024 12:45:08 -0300
Subject: [PATCH 2/2] ARM: ecard: make ecard_bus_type const
In-Reply-To: <20240211-bus_cleanup-rmk-v1-0-65668e578d55@marliere.net>
References: <20240211-bus_cleanup-rmk-v1-0-65668e578d55@marliere.net>
Message-ID: <20240211-bus_cleanup-rmk-v1-2-65668e578d55@marliere.net>

Now that the driver core can properly handle constant struct bus_type,
move the ecard_bus_type variable to be a constant structure as well,
placing it into read-only memory which can not be modified at runtime.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 arch/arm/include/asm/ecard.h | 2 +-
 arch/arm/mach-rpc/ecard.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/ecard.h b/arch/arm/include/asm/ecard.h
index 4befe8d2ae19..7cbe001bf9cc 100644
--- a/arch/arm/include/asm/ecard.h
+++ b/arch/arm/include/asm/ecard.h
@@ -195,7 +195,7 @@ void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
 			   unsigned long offset, unsigned long maxsize);
 #define ecardm_iounmap(__ec, __addr)	devm_iounmap(&(__ec)->dev, __addr)
 
-extern struct bus_type ecard_bus_type;
+extern const struct bus_type ecard_bus_type;
 
 #define ECARD_DEV(_d)	container_of((_d), struct expansion_card, dev)
 
diff --git a/arch/arm/mach-rpc/ecard.c b/arch/arm/mach-rpc/ecard.c
index c30df1097c52..4b843cffcac2 100644
--- a/arch/arm/mach-rpc/ecard.c
+++ b/arch/arm/mach-rpc/ecard.c
@@ -1124,7 +1124,7 @@ static int ecard_match(struct device *_dev, struct device_driver *_drv)
 	return ret;
 }
 
-struct bus_type ecard_bus_type = {
+const struct bus_type ecard_bus_type = {
 	.name		= "ecard",
 	.dev_groups	= ecard_dev_groups,
 	.match		= ecard_match,

-- 
2.43.0



From francesco at dolcini.it  Sun Feb 11 07:44:11 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Sun, 11 Feb 2024 16:44:11 +0100
Subject: [PATCH v1 0/9] Fix MMC properties on Sitara devices
In-Reply-To: <20240207225526.3953230-1-jm@ti.com>
References: <20240207225526.3953230-1-jm@ti.com>
Message-ID: <20240211154411.GA3360@francesco-nb>

Hello Judith and TI folks,

On Wed, Feb 07, 2024 at 04:55:17PM -0600, Judith Mendez wrote:
> This patch series aims to add or fix MMC properties:
> OTAPDLY/ITAPDLY.
> 
> The DLL properties ti,trm-icp and ti,driver-strength-ohm
> should also be updated since only AM64x and AM62p devices
> have a DLL to enable, so remove these properties when not
> applicable.

Do you have any reference regarding this change? TI reference manual or
anything like that?

No change needed in sdhci_am654.c? It seems that `drv_strength` is written
to some register unconditionally, is it ok to do so?

Do this change implies that there is no way to configure the drive
strength on such SoCs and MMC/SD trace impedance must be the nominal
50ohm?

Thanks,
Francesco



From krzysztof.kozlowski at linaro.org  Sun Feb 11 07:45:12 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 16:45:12 +0100
Subject: [PATCH] ARM: s3c64xx: make s3c6410_subsys const
In-Reply-To: <20240211-bus_cleanup-arm-v1-1-5c0102bda0bd@marliere.net>
References: <20240211-bus_cleanup-arm-v1-1-5c0102bda0bd@marliere.net>
Message-ID: <a51701ca-1b64-4716-b51d-59dafaec62de@linaro.org>

On 11/02/2024 16:41, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,

This "Now" was confusing last time and is still... There is often no
"Now" in multi-tree-repo-approach. If the patch allows it went through
different tree, this is still false. If this was already merged into
mainline, just say since which commit or which release.

I raised my concerns last time, so please fix all your future patches
after receiving such feedback.



Best regards,
Krzysztof



From ricardo at marliere.net  Sun Feb 11 07:51:28 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 11 Feb 2024 12:51:28 -0300
Subject: [PATCH 0/2] firmware: struct bus_type cleanup
Message-ID: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>

This series is part of an effort to cleanup the users of the driver
core, as can be seen in many recent patches authored by Greg across the
tree (e.g. [1]).

---
[1]: https://lore.kernel.org/lkml/?q=f%3Agregkh%40linuxfoundation.org+s%3A%22make%22+and+s%3A%22const%22

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

---
Ricardo B. Marliere (2):
      firmware: arm_ffa: Make ffa_bus_type const
      firmware: arm_scmi: make scmi_bus_type const

 drivers/firmware/arm_ffa/bus.c     | 2 +-
 drivers/firmware/arm_scmi/bus.c    | 2 +-
 drivers/firmware/arm_scmi/common.h | 2 +-
 include/linux/arm_ffa.h            | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)
---
base-commit: 047371968ffc470769f541d6933e262dc7085456
change-id: 20240211-bus_cleanup-firmware2-f5a633107921

Best regards,
-- 
Ricardo B. Marliere <ricardo at marliere.net>



From ricardo at marliere.net  Sun Feb 11 07:51:29 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 11 Feb 2024 12:51:29 -0300
Subject: [PATCH 1/2] firmware: arm_ffa: Make ffa_bus_type const
In-Reply-To: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
References: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
Message-ID: <20240211-bus_cleanup-firmware2-v1-1-1851c92c7be7@marliere.net>

Now that the driver core can properly handle constant struct bus_type,
move the ffa_bus_type variable to be a constant structure as well,
placing it into read-only memory which can not be modified at runtime.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 drivers/firmware/arm_ffa/bus.c | 2 +-
 include/linux/arm_ffa.h        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
index 1c7940ba5539..2f557e90f2eb 100644
--- a/drivers/firmware/arm_ffa/bus.c
+++ b/drivers/firmware/arm_ffa/bus.c
@@ -105,7 +105,7 @@ static struct attribute *ffa_device_attributes_attrs[] = {
 };
 ATTRIBUTE_GROUPS(ffa_device_attributes);
 
-struct bus_type ffa_bus_type = {
+const struct bus_type ffa_bus_type = {
 	.name		= "arm_ffa",
 	.match		= ffa_device_match,
 	.probe		= ffa_device_probe,
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index 3d0fde57ba90..c906f666ff5d 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -209,7 +209,7 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev) { return false; }
 #define module_ffa_driver(__ffa_driver)	\
 	module_driver(__ffa_driver, ffa_register, ffa_unregister)
 
-extern struct bus_type ffa_bus_type;
+extern const struct bus_type ffa_bus_type;
 
 /* FFA transport related */
 struct ffa_partition_info {

-- 
2.43.0



From ricardo at marliere.net  Sun Feb 11 07:51:30 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 11 Feb 2024 12:51:30 -0300
Subject: [PATCH 2/2] firmware: arm_scmi: make scmi_bus_type const
In-Reply-To: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
References: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
Message-ID: <20240211-bus_cleanup-firmware2-v1-2-1851c92c7be7@marliere.net>

Now that the driver core can properly handle constant struct bus_type,
move the scmi_bus_type variable to be a constant structure as well,
placing it into read-only memory which can not be modified at runtime.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 drivers/firmware/arm_scmi/bus.c    | 2 +-
 drivers/firmware/arm_scmi/common.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index c15928b8c5cc..609a6496c1d4 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -263,7 +263,7 @@ static void scmi_dev_remove(struct device *dev)
 		scmi_drv->remove(scmi_dev);
 }
 
-struct bus_type scmi_bus_type = {
+const struct bus_type scmi_bus_type = {
 	.name =	"scmi_protocol",
 	.match = scmi_dev_match,
 	.probe = scmi_dev_probe,
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 00b165d1f502..6affbfdd1dec 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -141,7 +141,7 @@ scmi_revision_area_get(const struct scmi_protocol_handle *ph);
 void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
 				     u8 *prot_imp);
 
-extern struct bus_type scmi_bus_type;
+extern const struct bus_type scmi_bus_type;
 
 #define SCMI_BUS_NOTIFY_DEVICE_REQUEST		0
 #define SCMI_BUS_NOTIFY_DEVICE_UNREQUEST	1

-- 
2.43.0



From francesco at dolcini.it  Sun Feb 11 07:54:59 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Sun, 11 Feb 2024 16:54:59 +0100
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240207091100.4001428-1-u-kumar1@ti.com>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
Message-ID: <20240211155459.GA4443@francesco-nb>

On Wed, Feb 07, 2024 at 02:41:00PM +0530, Udit Kumar wrote:
> Most of clocks and their parents are defined in contiguous range,
> But in few cases, there is gap in clock numbers[0].
> Driver assumes clocks to be in contiguous range, and add their clock
> ids incrementally.
> 
> New firmware started returning error while calling get_freq and is_on
> API for non-available clock ids.
> 
> In this fix, driver checks and adds only valid clock ids.
> 
> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
> 
> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> Section Clocks for NAVSS0_CPTS_0 Device,
> clock id 12-15 not present.
> 
> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>

no empty lines in between tags and only tags at the end of the commit
message, this [0] reference needs to be before or moved to a `Link:` tag,
whatever works best for you.

Francesco



From ricardo at marliere.net  Sun Feb 11 07:56:19 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 11 Feb 2024 12:56:19 -0300
Subject: [PATCH] ARM: s3c64xx: make s3c6410_subsys const
In-Reply-To: <a51701ca-1b64-4716-b51d-59dafaec62de@linaro.org>
References: <20240211-bus_cleanup-arm-v1-1-5c0102bda0bd@marliere.net>
 <a51701ca-1b64-4716-b51d-59dafaec62de@linaro.org>
Message-ID: <qvg4aimmo5eghq3uqf5wwioapafoabsqrm47axbkkp2jwx2rud@gh2xfqacq2rb>

Hi Krzysztof,

On 11 Feb 16:45, Krzysztof Kozlowski wrote:
> On 11/02/2024 16:41, Ricardo B. Marliere wrote:
> > Now that the driver core can properly handle constant struct bus_type,
> 
> This "Now" was confusing last time and is still... There is often no
> "Now" in multi-tree-repo-approach. If the patch allows it went through
> different tree, this is still false. If this was already merged into
> mainline, just say since which commit or which release.
> 
> I raised my concerns last time, so please fix all your future patches
> after receiving such feedback.

You're right, I'll keep this in mind. Will send a v2.

Thanks for reviewing,
-	Ricardo.


> 
> 
> 
> Best regards,
> Krzysztof
> 


From ricardo at marliere.net  Sun Feb 11 07:57:09 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Sun, 11 Feb 2024 12:57:09 -0300
Subject: [PATCH v2] ARM: s3c64xx: make s3c6410_subsys const
Message-ID: <20240211-bus_cleanup-arm-v2-1-3de9e8af7cbd@marliere.net>

Since commit d492cc2573a0 ("driver core: device.h: make struct bus_type
a const *"), the driver core can properly handle constant struct
bus_type, move the s3c6410_subsys variable to be a constant structure as
well, placing it into read-only memory which can not be modified at
runtime.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
Changes in v2:
- Instead of "Now", defined a specific commit in the changelog.
- Link to v1: https://lore.kernel.org/r/20240211-bus_cleanup-arm-v1-1-5c0102bda0bd at marliere.net
---
 arch/arm/mach-s3c/cpu.h     | 2 +-
 arch/arm/mach-s3c/s3c6410.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-s3c/cpu.h b/arch/arm/mach-s3c/cpu.h
index d0adc9b40e25..a0187606b999 100644
--- a/arch/arm/mach-s3c/cpu.h
+++ b/arch/arm/mach-s3c/cpu.h
@@ -76,6 +76,6 @@ extern void s3c24xx_init_uartdevs(char *name,
 				  struct s3c24xx_uart_resources *res,
 				  struct s3c2410_uartcfg *cfg, int no);
 
-extern struct bus_type s3c6410_subsys;
+extern const struct bus_type s3c6410_subsys;
 
 #endif
diff --git a/arch/arm/mach-s3c/s3c6410.c b/arch/arm/mach-s3c/s3c6410.c
index e79f18d0ca81..a29276a4fde5 100644
--- a/arch/arm/mach-s3c/s3c6410.c
+++ b/arch/arm/mach-s3c/s3c6410.c
@@ -57,7 +57,7 @@ void __init s3c6410_init_irq(void)
 	s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
 }
 
-struct bus_type s3c6410_subsys = {
+const struct bus_type s3c6410_subsys = {
 	.name		= "s3c6410-core",
 	.dev_name	= "s3c6410-core",
 };

---
base-commit: fee3a71dc8d26629e5d87e20cff08763f522633f
change-id: 20240211-bus_cleanup-arm-da0f2550ca48

Best regards,
-- 
Ricardo B. Marliere <ricardo at marliere.net>



From krzysztof.kozlowski at linaro.org  Sun Feb 11 08:22:20 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 17:22:20 +0100
Subject: [PATCH v5 2/5] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240211-add-am64-som-v5-2-790ed7121249@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
 <20240211-add-am64-som-v5-2-790ed7121249@solid-run.com>
Message-ID: <a5b049eb-275e-4386-be24-884575218d9d@linaro.org>

On 11/02/2024 16:07, Josua Mayer wrote:
> Convert the abracon abx80x rtc text bindings to dt-schema format.
> 
> In addition to the text description reference generic interrupts
> properties and add an example.
> 
> Signed-off-by: Josua Mayer <josua at solid-run.com>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 08:29:32 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 17:29:32 +0100
Subject: [PATCH v3 1/2] dt-bindings: arm: sunxi: Add Sipeed Longan Module
 3H and Longan Pi 3H
In-Reply-To: <20240211081739.395-2-jszhang@kernel.org>
References: <20240211081739.395-1-jszhang@kernel.org>
 <20240211081739.395-2-jszhang@kernel.org>
Message-ID: <7ee6df91-76fa-44e8-ab81-fd4b63b58ce9@linaro.org>

On 11/02/2024 09:17, Jisheng Zhang wrote:
> Add name & compatible for the Sipeed Longan Module 3H and Longan PI 3H
> board.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> Reviewed-by: Andre Przywara <andre.przywara at arm.com>
> ---

This is a friendly reminder during the review process.

It looks like you received a tag and forgot to add it.

If you do not know the process, here is a short explanation:
Please add Acked-by/Reviewed-by/Tested-by tags when posting new
versions, under or above your Signed-off-by tag. Tag is "received", when
provided in a message replied to you on the mailing list. Tools like b4
can help here. However, there's no need to repost patches *only* to add
the tags. The upstream maintainer will do that for tags received on the
version they apply.

https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577

If a tag was not added on purpose, please state why and what changed.
Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 11 08:31:10 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 11 Feb 2024 17:31:10 +0100
Subject: [PATCH v4 2/7] dt-bindings: thermal: sun8i: Add H616 THS
 controller
In-Reply-To: <20240209144221.3602382-3-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
 <20240209144221.3602382-3-andre.przywara@arm.com>
Message-ID: <647146ad-337e-4dc4-9db0-18daf4ef46d6@linaro.org>

On 09/02/2024 15:42, Andre Przywara wrote:
> From: Martin Botka <martin.botka at somainline.org>
> 
> This controller is similar to the H6, but covers four sensors and uses
> slightly different calibration methods.
> Also the H616 requires to poke a bit in the SYS_CFG register range for
> correct operation, so add a phandle property to point there.
> 
> Signed-off-by: Martin Botka <martin.botka at somainline.org>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From s.shtylyov at omp.ru  Sun Feb 11 09:01:06 2024
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Sun, 11 Feb 2024 20:01:06 +0300
Subject: [PATCH 0/2] arm64: dts: renesas: rcar-gen4: Correct avb[01] reg
 sizes
In-Reply-To: <cover.1707660323.git.geert+renesas@glider.be>
References: <cover.1707660323.git.geert+renesas@glider.be>
Message-ID: <2ad6b391-c27a-389d-1933-a6e12c21f713@omp.ru>

On 2/11/24 5:21 PM, Geert Uytterhoeven wrote:
> 	Hi all,
> 
> All Ethernet AVB instances on R-Car Gen4 SoCs have registers related to
> UDP/IP support, starting at offset 0x800.  However, the register blocks

   TCP/UDP/ICMP, actually.

> for some (but not all) instances are too small to cover them.
> 
> This patch series fixes this by extending the register block sizes where
> needed.  Note that this has no immediate impact on actual operation, as
> the Linux driver does not use the UDP/IP registers.  Besides, ioremap()

   In fact, it does write to CSR0 at offset 0x800... and in the net-next.git
the checksum offload is now used.

> granulatity is PAGE_SIZE, so the registers are accessible anyway.

   Ah, indeed, PAGE_SIZE is not less than 0x1000. :-)

> I also considered introducing a new reg tuplet to cover the UDP/IP
> registers.  However, that would complicate handling as some instances
> (on some R-Car Gen2/3 SoCs) already have two reg tuplets, and there are
> no reg-names defined:
> 
>     reg:
>       items:
> 	- description: MAC register block
> 	- description: Stream buffer
> 
> So I think just enlarging the first register block would be fine.

   Yep, thanks! :-)

> To be queued in renesas-devel for v6.9, if you agree.
> 
> Thanks for your comments!
> 
> Geert Uytterhoeven (2):
>   arm64: dts: renesas: r8a779a0: Correct avb[01] reg sizes
>   arm64: dts: renesas: r8a779g0: Correct avb[01] reg sizes
> 
>  arch/arm64/boot/dts/renesas/r8a779a0.dtsi | 4 ++--
>  arch/arm64/boot/dts/renesas/r8a779g0.dtsi | 4 ++--
>  2 files changed, 4 insertions(+), 4 deletions(-)

MBR, Sergey


From ankita at nvidia.com  Sun Feb 11 09:47:01 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Sun, 11 Feb 2024 23:17:01 +0530
Subject: [PATCH v7 0/4] kvm: arm64: allow the VM to select DEVICE_* and NORMAL_NC for IO memory
Message-ID: <20240211174705.31992-1-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

Currently, KVM for ARM64 maps at stage 2 memory that is considered device
with DEVICE_nGnRE memory attributes; this setting overrides (per
ARM architecture [1]) any device MMIO mapping present at stage 1,
resulting in a set-up whereby a guest operating system cannot
determine device MMIO mapping memory attributes on its own but
it is always overridden by the KVM stage 2 default.

This set-up does not allow guest operating systems to select device
memory attributes independently from KVM stage-2 mappings
(refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
which turns out to be an issue in that guest operating systems
(e.g. Linux) may request to map devices MMIO regions with memory
attributes that guarantee better performance (e.g. gathering
attribute - that for some devices can generate larger PCIe memory
writes TLPs) and specific operations (e.g. unaligned transactions)
such as the NormalNC memory type.

The default device stage 2 mapping was chosen in KVM for ARM64 since
it was considered safer (i.e. it would not allow guests to trigger
uncontained failures ultimately crashing the machine) but this
turned out to be asynchronous (SError) defeating the purpose.

For these reasons, relax the KVM stage 2 device memory attributes
from DEVICE_nGnRE to Normal-NC.

Generalizing to other devices may be problematic, however. E.g.
GICv2 VCPU interface, which is effectively a shared peripheral, can
allow a guest to affect another guest's interrupt distribution. Hence
limit the change to VFIO PCI as caution. This is achieved by
making the VFIO PCI core module set a flag that is tested by KVM
to activate the code. This could be extended to other devices in
the future once that is deemed safe.

[1] section D8.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf

Applied over v6.8-rc2.

History
=======
v6 -> v7
- Changed VM_VFIO_ALLOW_WC to VM_ALLOW_ANY_UNCACHED based on suggestion
  from Alex Williamson.
- Refactored stage2_set_prot_attr() based on Will's suggestion to
  reorganize the switch cases. Also updated the case to return -EINVAL
  when both KVM_PGTABLE_PROT_DEVICE and KVM_PGTABLE_PROT_NORMAL_NC set.
- Fixed nits pointed by Oliver and Catalin.

v5 -> v6
- Rebased to v6.8-rc2

v4 -> v5
- Moved the cover letter description text to patch 1/4.
- Cleaned up stage2_set_prot_attr() based on Marc Zyngier suggestions.
- Moved the mm header file changes to a separate patch.
- Rebased to v6.7-rc3.

v3 -> v4
- Moved the vfio-pci change to use the VM_VFIO_ALLOW_WC into
  separate patch.
- Added check to warn on the case NORMAL_NC and DEVICE are
  set simultaneously.
- Fixed miscellaneous nitpicks suggested in v3.

v2 -> v3
- Added a new patch (and converted to patch series) suggested by
  Catalin Marinas to ensure the code changes are restricted to
  VFIO PCI devices.
- Introduced VM_VFIO_ALLOW_WC flag for VFIO PCI to communicate
  with VMM.
- Reverted GIC mapping to DEVICE.

v1 -> v2
- Updated commit log to the one posted by
  Lorenzo Pieralisi <lpieralisi at kernel.org> (Thanks!)
- Added new flag to represent the NORMAL_NC setting. Updated
  stage2_set_prot_attr() to handle new flag.

v6 Link:
https://lore.kernel.org/all/20240207204652.22954-1-ankita at nvidia.com/

Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>

Ankit Agrawal (4):
  kvm: arm64: introduce new flag for non-cacheable IO memory
  mm: introduce new flag to indicate wc safe
  kvm: arm64: set io memory s2 pte as normalnc for vfio pci device
  vfio: convey kvm that the vfio-pci device is wc safe

 arch/arm64/include/asm/kvm_pgtable.h |  2 ++
 arch/arm64/include/asm/memory.h      |  2 ++
 arch/arm64/kvm/hyp/pgtable.c         | 24 +++++++++++++++++++-----
 arch/arm64/kvm/mmu.c                 | 14 ++++++++++----
 drivers/vfio/pci/vfio_pci_core.c     |  6 +++++-
 include/linux/mm.h                   | 14 ++++++++++++++
 6 files changed, 52 insertions(+), 10 deletions(-)

-- 
2.34.1



From ankita at nvidia.com  Sun Feb 11 09:47:03 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Sun, 11 Feb 2024 23:17:03 +0530
Subject: [PATCH v7 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <20240211174705.31992-1-ankita@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
Message-ID: <20240211174705.31992-3-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

Generalizing S2 setting from DEVICE_nGnRE to NormalNc for non PCI
devices may be problematic. E.g. GICv2 vCPU interface, which is
effectively a shared peripheral, can allow a guest to affect another
guest's interrupt distribution. The issue may be solved by limiting
the relaxation to mappings that have a user VMA. Still there is
insufficient information and uncertainity in the behavior of
non PCI drivers.

Add a new flag VM_ALLOW_ANY_UNCACHED to indicate KVM that the device
is WC capable and these S2 changes can be extended to it. KVM can use
this flag to activate the code.

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 include/linux/mm.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index f5a97dec5169..59576e56c58b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -391,6 +391,20 @@ extern unsigned int kobjsize(const void *objp);
 # define VM_UFFD_MINOR		VM_NONE
 #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
 
+/*
+ * This flag is used to connect VFIO to arch specific KVM code. It
+ * indicates that the memory under this VMA is safe for use with any
+ * non-cachable memory type inside KVM. Some VFIO devices, on some
+ * platforms, are thought to be unsafe and can cause machine crashes
+ * if KVM does not lock down the memory type.
+ */
+#ifdef CONFIG_64BIT
+#define VM_ALLOW_ANY_UNCACHED_BIT	39
+#define VM_ALLOW_ANY_UNCACHED		BIT(VM_ALLOW_ANY_UNCACHED_BIT)
+#else
+#define VM_ALLOW_ANY_UNCACHED		VM_NONE
+#endif
+
 /* Bits set in the VMA until the stack is in its final location */
 #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
 
-- 
2.34.1



From ankita at nvidia.com  Sun Feb 11 09:47:04 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Sun, 11 Feb 2024 23:17:04 +0530
Subject: [PATCH v7 3/4] kvm: arm64: set io memory s2 pte as normalnc for vfio pci device
In-Reply-To: <20240211174705.31992-1-ankita@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
Message-ID: <20240211174705.31992-4-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

To provide VM with the ability to get device IO memory with NormalNC
property, map device MMIO in KVM for ARM64 at stage2 as NormalNC.
Having NormalNC S2 default puts guests in control (based on [1],
"Combining stage 1 and stage 2 memory type attributes") of device
MMIO regions memory mappings. The rules are summarized below:
([(S1) - stage1], [(S2) - stage 2])

S1           |  S2           | Result
NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>

Still this cannot be generalized to non PCI devices such as GICv2.
There is insufficient information and uncertainity in the behavior
of non PCI driver. A driver must indicate support using the
new flag VM_ALLOW_ANY_UNCACHED.

Adapt KVM to make use of the flag VM_ALLOW_ANY_UNCACHED as indicator to
activate the S2 setting to NormalNc.

[1] section D8.5.5 of DDI0487J_a_a-profile_architecture_reference_manual.pdf

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Jason Gunthorpe <jgg at nvidia.com>
Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 arch/arm64/kvm/mmu.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index d14504821b79..1742fdccb432 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1381,7 +1381,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	int ret = 0;
 	bool write_fault, writable, force_pte = false;
 	bool exec_fault, mte_allowed;
-	bool device = false;
+	bool device = false, vfio_allow_any_uc = false;
 	unsigned long mmu_seq;
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
@@ -1472,6 +1472,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	gfn = fault_ipa >> PAGE_SHIFT;
 	mte_allowed = kvm_vma_mte_allowed(vma);
 
+	vfio_allow_any_uc = vma->vm_flags & VM_ALLOW_ANY_UNCACHED;
+
 	/* Don't use the VMA after the unlock -- it may have vanished */
 	vma = NULL;
 
@@ -1557,10 +1559,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	if (exec_fault)
 		prot |= KVM_PGTABLE_PROT_X;
 
-	if (device)
-		prot |= KVM_PGTABLE_PROT_DEVICE;
-	else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
+	if (device) {
+		if (vfio_allow_any_uc)
+			prot |= KVM_PGTABLE_PROT_NORMAL_NC;
+		else
+			prot |= KVM_PGTABLE_PROT_DEVICE;
+	} else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) {
 		prot |= KVM_PGTABLE_PROT_X;
+	}
 
 	/*
 	 * Under the premise of getting a FSC_PERM fault, we just need to relax
-- 
2.34.1



From ankita at nvidia.com  Sun Feb 11 09:47:05 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Sun, 11 Feb 2024 23:17:05 +0530
Subject: [PATCH v7 4/4] vfio: convey kvm that the vfio-pci device is wc safe
In-Reply-To: <20240211174705.31992-1-ankita@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
Message-ID: <20240211174705.31992-5-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

The code to map the MMIO in S2 as NormalNC is enabled when conveyed
that the device is WC safe using a new flag VM_ALLOW_ANY_UNCACHED.

Make vfio-pci set the VM_ALLOW_ANY_UNCACHED flag.

This could be extended to other devices in the future once that
is deemed safe.

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 drivers/vfio/pci/vfio_pci_core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 1cbc990d42e0..eba2146202f9 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1862,8 +1862,12 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
 	/*
 	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
 	 * change vm_flags within the fault handler.  Set them now.
+	 *
+	 * Set an additional flag VM_ALLOW_ANY_UNCACHED to convey kvm that
+	 * the device is wc safe.
 	 */
-	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+	vm_flags_set(vma, VM_ALLOW_ANY_UNCACHED | VM_IO | VM_PFNMAP |
+			VM_DONTEXPAND | VM_DONTDUMP);
 	vma->vm_ops = &vfio_pci_mmap_ops;
 
 	return 0;
-- 
2.34.1



From ankita at nvidia.com  Sun Feb 11 09:47:02 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Sun, 11 Feb 2024 23:17:02 +0530
Subject: [PATCH v7 1/4] kvm: arm64: introduce new flag for non-cacheable IO memory
In-Reply-To: <20240211174705.31992-1-ankita@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
Message-ID: <20240211174705.31992-2-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

Currently, KVM for ARM64 maps at stage 2 memory that is considered device
(i.e. it is not RAM) with DEVICE_nGnRE memory attributes; this setting
overrides (as per the ARM architecture [1]) any device MMIO mapping
present at stage 1, resulting in a set-up whereby a guest operating
system cannot determine device MMIO mapping memory attributes on its
own but it is always overridden by the KVM stage 2 default.

This set-up does not allow guest operating systems to select device
memory attributes independently from KVM stage-2 mappings
(refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
which turns out to be an issue in that guest operating systems
(e.g. Linux) may request to map devices MMIO regions with memory
attributes that guarantee better performance (e.g. gathering
attribute - that for some devices can generate larger PCIe memory
writes TLPs) and specific operations (e.g. unaligned transactions)
such as the NormalNC memory type.

The default device stage 2 mapping was chosen in KVM for ARM64 since
it was considered safer (i.e. it would not allow guests to trigger
uncontained failures ultimately crashing the machine) but this
turned out to be asynchronous (SError) defeating the purpose.

Failures containability is a property of the platform and is independent
from the memory type used for MMIO device memory mappings.

Actually, DEVICE_nGnRE memory type is even more problematic than
Normal-NC memory type in terms of faults containability in that e.g.
aborts triggered on DEVICE_nGnRE loads cannot be made, architecturally,
synchronous (i.e. that would imply that the processor should issue at
most 1 load transaction at a time - it cannot pipeline them - otherwise
the synchronous abort semantics would break the no-speculation attribute
attached to DEVICE_XXX memory).

This means that regardless of the combined stage1+stage2 mappings a
platform is safe if and only if device transactions cannot trigger
uncontained failures and that in turn relies on platform capabilities
and the device type being assigned (i.e. PCIe AER/DPC error containment
and RAS architecture[3]); therefore the default KVM device stage 2
memory attributes play no role in making device assignment safer
for a given platform (if the platform design adheres to design
guidelines outlined in [3]) and therefore can be relaxed.

For all these reasons, relax the KVM stage 2 device memory attributes
from DEVICE_nGnRE to Normal-NC.

The NormalNC was chosen over a different Normal memory type default
at stage-2 (e.g. Normal Write-through) to avoid cache allocation/snooping.

Relaxing S2 KVM device MMIO mappings to Normal-NC is not expected to
trigger any issue on guest device reclaim use cases either (i.e. device
MMIO unmap followed by a device reset) at least for PCIe devices, in that
in PCIe a device reset is architected and carried out through PCI config
space transactions that are naturally ordered with respect to MMIO
transactions according to the PCI ordering rules.

Having Normal-NC S2 default puts guests in control (thanks to
stage1+stage2 combined memory attributes rules [1]) of device MMIO
regions memory mappings, according to the rules described in [1]
and summarized here ([(S1) - stage1], [(S2) - stage 2]):

S1           |  S2           | Result
NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>

It is worth noting that currently, to map devices MMIO space to user
space in a device pass-through use case the VFIO framework applies memory
attributes derived from pgprot_noncached() settings applied to VMAs, which
result in device-nGnRnE memory attributes for the stage-1 VMM mappings.

This means that a userspace mapping for device MMIO space carried
out with the current VFIO framework and a guest OS mapping for the same
MMIO space may result in a mismatched alias as described in [2].

Defaulting KVM device stage-2 mappings to Normal-NC attributes does not
change anything in this respect, in that the mismatched aliases would
only affect (refer to [2] for a detailed explanation) ordering between
the userspace and GuestOS mappings resulting stream of transactions
(i.e. it does not cause loss of property for either stream of
transactions on its own), which is harmless given that the userspace
and GuestOS access to the device is carried out through independent
transactions streams.

A Normal-NC flag is not present today. So add a new kvm_pgtable_prot
(KVM_PGTABLE_PROT_NORMAL_NC) flag for it, along with its
corresponding PTE value 0x5 (0b101) determined from [1].

Lastly, adapt the stage2 PTE property setter function
(stage2_set_prot_attr) to handle the NormalNC attribute.

[1] section D8.5.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
[2] section B2.8 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
[3] sections 1.7.7.3/1.8.5.2/appendix C - DEN0029H_SBSA_7.1.pdf

Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 arch/arm64/include/asm/kvm_pgtable.h |  2 ++
 arch/arm64/include/asm/memory.h      |  2 ++
 arch/arm64/kvm/hyp/pgtable.c         | 24 +++++++++++++++++++-----
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index cfdf40f734b1..19278dfe7978 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -197,6 +197,7 @@ enum kvm_pgtable_stage2_flags {
  * @KVM_PGTABLE_PROT_W:		Write permission.
  * @KVM_PGTABLE_PROT_R:		Read permission.
  * @KVM_PGTABLE_PROT_DEVICE:	Device attributes.
+ * @KVM_PGTABLE_PROT_NORMAL_NC:	Normal noncacheable attributes.
  * @KVM_PGTABLE_PROT_SW0:	Software bit 0.
  * @KVM_PGTABLE_PROT_SW1:	Software bit 1.
  * @KVM_PGTABLE_PROT_SW2:	Software bit 2.
@@ -208,6 +209,7 @@ enum kvm_pgtable_prot {
 	KVM_PGTABLE_PROT_R			= BIT(2),
 
 	KVM_PGTABLE_PROT_DEVICE			= BIT(3),
+	KVM_PGTABLE_PROT_NORMAL_NC		= BIT(4),
 
 	KVM_PGTABLE_PROT_SW0			= BIT(55),
 	KVM_PGTABLE_PROT_SW1			= BIT(56),
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index d82305ab420f..449ca2ff1df6 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -173,6 +173,7 @@
  * Memory types for Stage-2 translation
  */
 #define MT_S2_NORMAL		0xf
+#define MT_S2_NORMAL_NC		0x5
 #define MT_S2_DEVICE_nGnRE	0x1
 
 /*
@@ -180,6 +181,7 @@
  * Stage-2 enforces Normal-WB and Device-nGnRE
  */
 #define MT_S2_FWB_NORMAL	6
+#define MT_S2_FWB_NORMAL_NC	5
 #define MT_S2_FWB_DEVICE_nGnRE	1
 
 #ifdef CONFIG_ARM64_4K_PAGES
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index c651df904fe3..e2982a8922c3 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -717,15 +717,29 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
 static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
 				kvm_pte_t *ptep)
 {
-	bool device = prot & KVM_PGTABLE_PROT_DEVICE;
-	kvm_pte_t attr = device ? KVM_S2_MEMATTR(pgt, DEVICE_nGnRE) :
-			    KVM_S2_MEMATTR(pgt, NORMAL);
+	kvm_pte_t attr;
 	u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS;
 
+	switch (prot & (KVM_PGTABLE_PROT_DEVICE |
+			KVM_PGTABLE_PROT_NORMAL_NC)) {
+	case KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC:
+		return -EINVAL;
+	case KVM_PGTABLE_PROT_DEVICE:
+		if (prot & KVM_PGTABLE_PROT_X)
+			return -EINVAL;
+		attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
+		break;
+	case KVM_PGTABLE_PROT_NORMAL_NC:
+		if (prot & KVM_PGTABLE_PROT_X)
+			return -EINVAL;
+		attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
+		break;
+	default:
+		attr = KVM_S2_MEMATTR(pgt, NORMAL);
+	}
+
 	if (!(prot & KVM_PGTABLE_PROT_X))
 		attr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
-	else if (device)
-		return -EINVAL;
 
 	if (prot & KVM_PGTABLE_PROT_R)
 		attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
-- 
2.34.1



From geert at linux-m68k.org  Sun Feb 11 10:17:07 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Sun, 11 Feb 2024 19:17:07 +0100
Subject: [PATCH 0/2] arm64: dts: renesas: rcar-gen4: Correct avb[01] reg sizes
In-Reply-To: <2ad6b391-c27a-389d-1933-a6e12c21f713@omp.ru>
References: <cover.1707660323.git.geert+renesas@glider.be> <2ad6b391-c27a-389d-1933-a6e12c21f713@omp.ru>
Message-ID: <CAMuHMdWqn8vtucjpo28Tw1atSTVKZrKRKPJL1FqdG2h_RMDfPw@mail.gmail.com>

Hi Sergey,

On Sun, Feb 11, 2024 at 6:01?PM Sergey Shtylyov <s.shtylyov at omp.ru> wrote:
> On 2/11/24 5:21 PM, Geert Uytterhoeven wrote:
> > All Ethernet AVB instances on R-Car Gen4 SoCs have registers related to
> > UDP/IP support, starting at offset 0x800.  However, the register blocks
>
>    TCP/UDP/ICMP, actually.

I think you are mixing up Ether AVB on R-Car and GbEth on RZ/G2L...

> > for some (but not all) instances are too small to cover them.
> >
> > This patch series fixes this by extending the register block sizes where
> > needed.  Note that this has no immediate impact on actual operation, as
> > the Linux driver does not use the UDP/IP registers.  Besides, ioremap()
>
>    In fact, it does write to CSR0 at offset 0x800... and in the net-next.git
> the checksum offload is now used.

It only does so on GbEth.
While Ether AVB on R-Car Gen4 has both CSR0 and CSR2 (but no CSR1),
and the register descriptions are the same, the documentation for the
bits is completely different. And later registers differ even more...

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 erick.archer at gmx.com  Sun Feb 11 10:22:50 2024
From: erick.archer at gmx.com (Erick Archer)
Date: Sun, 11 Feb 2024 19:22:50 +0100
Subject: [PATCH] iommu/mtk_iommu: Use devm_kcalloc() instead of devm_kzalloc()
Message-ID: <20240211182250.12656-1-erick.archer@gmx.com>

This is an effort to get rid of all multiplications from allocation
functions in order to prevent integer overflows [1].

Here the multiplication is obviously safe because MTK_PROTECT_PA_ALIGN
is defined as a literal value of 256 or 128.

For the "mtk_iommu.c" file: 256
For the "mtk_iommu_v1.c" file: 128

However, using devm_kcalloc() is more appropriate [2] and improves
readability. This patch has no effect on runtime behavior.

Link: https://github.com/KSPP/linux/issues/162 [1]
Link: https://www.kernel.org/doc/html/next/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [2]
Signed-off-by: Erick Archer <erick.archer at gmx.com>
---
 drivers/iommu/mtk_iommu.c    | 2 +-
 drivers/iommu/mtk_iommu_v1.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 7abe9e85a570..9aae6eb604b1 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1264,7 +1264,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_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN, GFP_KERNEL);
 	if (!protect)
 		return -ENOMEM;
 	data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 25b41222abae..45cd845d153f 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -621,8 +621,8 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev)
 	data->dev = dev;

 	/* Protect memory. HW will access here while translation fault.*/
-	protect = devm_kzalloc(dev, MTK_PROTECT_PA_ALIGN * 2,
-			GFP_KERNEL | GFP_DMA);
+	protect = devm_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN,
+			       GFP_KERNEL | GFP_DMA);
 	if (!protect)
 		return -ENOMEM;
 	data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
--
2.25.1



From marex at denx.de  Sun Feb 11 10:48:51 2024
From: marex at denx.de (Marek Vasut)
Date: Sun, 11 Feb 2024 19:48:51 +0100
Subject: [PATCH] drm/lcdif: Do not disable clock on already suspended
 hardware
In-Reply-To: <20240118183924.144221-1-marex@denx.de>
References: <20240118183924.144221-1-marex@denx.de>
Message-ID: <7d3670a5-dc7e-4311-b250-70d503a36f89@denx.de>

On 1/18/24 19:39, Marek Vasut wrote:
> In case the LCDIF is enabled in DT but unused, the clock used by the
> LCDIF are not enabled. Those clock may even have a use count of 0 in
> case there are no other users of those clock. This can happen e.g. in
> case the LCDIF drives HDMI bridge which has no panel plugged into the
> HDMI connector.
> 
> Do not attempt to disable clock in the suspend callback and re-enable
> clock in the resume callback unless the LCDIF is enabled and was in
> use before the system entered suspend, otherwise the driver might end
> up trying to disable clock which are already disabled with use count
> 0, and would trigger a warning from clock core about this condition.
> 
> Note that the lcdif_rpm_suspend() and lcdif_rpm_resume() functions
> internally perform the clock disable and enable operations and act
> as runtime PM hooks too.
> 
> Fixes: 9db35bb349a0 ("drm: lcdif: Add support for i.MX8MP LCDIF variant")
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: David Airlie <airlied at gmail.com>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: Liu Ying <victor.liu at nxp.com>
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
> Cc: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Stefan Agner <stefan at agner.ch>
> Cc: Thomas Zimmermann <tzimmermann at suse.de>
> Cc: dri-devel at lists.freedesktop.org
> Cc: linux-arm-kernel at lists.infradead.org
> ---
>   drivers/gpu/drm/mxsfb/lcdif_drv.c | 6 +++++-
>   1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> index ea10bf81582e9..0f895b8a99d62 100644
> --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
> +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> @@ -343,6 +343,9 @@ static int __maybe_unused lcdif_suspend(struct device *dev)
>   	if (ret)
>   		return ret;
>   
> +	if (pm_runtime_suspended(dev))
> +		return 0;
> +
>   	return lcdif_rpm_suspend(dev);
>   }
>   
> @@ -350,7 +353,8 @@ static int __maybe_unused lcdif_resume(struct device *dev)
>   {
>   	struct drm_device *drm = dev_get_drvdata(dev);
>   
> -	lcdif_rpm_resume(dev);
> +	if (!pm_runtime_suspended(dev))
> +		lcdif_rpm_resume(dev);
>   
>   	return drm_mode_config_helper_resume(drm);
>   }

Is this OK to pick up ? Some AB/RB/input would be appreciated, thanks !


From marex at denx.de  Sun Feb 11 10:51:33 2024
From: marex at denx.de (Marek Vasut)
Date: Sun, 11 Feb 2024 19:51:33 +0100
Subject: [PATCH V4 2/6] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240210204606.11944-3-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
 <20240210204606.11944-3-aford173@gmail.com>
Message-ID: <dda8ca75-1792-4933-9240-39259ae721b7@denx.de>

On 2/10/24 21:45, Adam Ford wrote:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the driver for the Samsung HDMI PHY found on the
> i.MX8MP SoC. Based on downstream implementation from
> Sandor Yu <Sandor.yu at nxp.com>.  According to the TRM, the PHY
> receives parallel data from the link and serializes it.  It
> also sets the PLL clock needed for the TX serializer.
> 
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v2)
> Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
> Co-developed-by: Marco Felsch <m.felsch at pengutronix.de>
> Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> # Kontron BL
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Tested-by: Marek Vasut <marex at denx.de>

Thanks !


From marex at denx.de  Sun Feb 11 10:51:53 2024
From: marex at denx.de (Marek Vasut)
Date: Sun, 11 Feb 2024 19:51:53 +0100
Subject: [PATCH V4 3/6] arm64: dts: imx8mp: add HDMI power-domains
In-Reply-To: <20240210204606.11944-4-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
 <20240210204606.11944-4-aford173@gmail.com>
Message-ID: <c7d50bc9-d6fc-4dd6-9db5-e88fcb19a5b9@denx.de>

On 2/10/24 21:45, Adam Ford wrote:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the PGC and HDMI blk-ctrl nodes providing power control for
> HDMI subsystem peripherals.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

Tested-by: Marek Vasut <marex at denx.de>

Thanks !


From marex at denx.de  Sun Feb 11 10:52:04 2024
From: marex at denx.de (Marek Vasut)
Date: Sun, 11 Feb 2024 19:52:04 +0100
Subject: [PATCH V4 4/6] arm64: dts: imx8mp: add HDMI irqsteer
In-Reply-To: <20240210204606.11944-5-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
 <20240210204606.11944-5-aford173@gmail.com>
Message-ID: <0128bac7-eac3-4b80-a888-90e6596320cc@denx.de>

On 2/10/24 21:46, Adam Ford wrote:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> The HDMI irqsteer is a secondary interrupt controller within the HDMI
> subsystem that maps all HDMI peripheral IRQs into a single upstream
> IRQ line.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Tested-by: Marek Vasut <marex at denx.de>

Thanks !


From marex at denx.de  Sun Feb 11 10:52:11 2024
From: marex at denx.de (Marek Vasut)
Date: Sun, 11 Feb 2024 19:52:11 +0100
Subject: [PATCH V4 5/6] arm64: dts: imx8mp: add HDMI display pipeline
In-Reply-To: <20240210204606.11944-6-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
 <20240210204606.11944-6-aford173@gmail.com>
Message-ID: <6ecffc5a-d464-412a-9bd7-c98a5536092d@denx.de>

On 2/10/24 21:46, Adam Ford wrote:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the DT nodes for all the peripherals that make up the
> HDMI display pipeline.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Tested-by: Marek Vasut <marex at denx.de>

Thanks !


From megi at xff.cz  Sun Feb 11 11:25:29 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Sun, 11 Feb 2024 20:25:29 +0100
Subject: [PATCH v2 0/6] Pinephone video out fixes (flipping between two
 frames)
In-Reply-To: <87wmrbxckj.fsf@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <jzl3mlzk4j7qvgcedvipgale5nhinznefodrnaehwsqfnseiwc@7zzlxd4dpueh>
 <bgyyemyi4shj3spo6qy4icvk56nrp5sihnzqurnozqdyktwugc@ikurx4ojoxpi>
 <87wmrbxckj.fsf@oltmanns.dev>
Message-ID: <s7uslavg5gzqzzdetwcushcknwe3nuicmqhfhb7gbapzxx2npy@srjc252uinqv>

Hi Frank,

On Sun, Feb 11, 2024 at 04:09:16PM +0100, Frank Oltmanns wrote:
> Hi Ond?ej,
> 
> On 2024-02-05 at 17:02:00 +0100, Ond?ej Jirman <megi at xff.cz> wrote:
> > On Mon, Feb 05, 2024 at 04:54:07PM +0100, Ond?ej Jirman wrote:
> >> On Mon, Feb 05, 2024 at 04:22:23PM +0100, Frank Oltmanns wrote:
> >>
> >> [...]
> >>
> >> Also sunxi-ng clk driver does apply NM factors at once to PLL_GPU clock,
> >> which can cause sudden frequency increase beyond intended output frequency,
> >> because division is applied immediately while multiplication is reflected
> >> slowly.
> >>
> >> Eg. if you're changing divider from 7 to 1, you can get a sudden 7x output
> >> frequency spike, before PLL VCO manages to lower the frequency through N clk
> >> divider feedback loop and lock on again. This can mess up whatever's connected
> >> to the output quite badly.
> >>
> >> You'd have to put logging on kernel writes to PLL_GPU register to see what
> >> is written in there and if divider is lowered significantly on some GPU
> >> devfreq frequency transitions.
> 
> By looking at the clocks in clk_summary in debugfs, the rate of PLL-GPU
> always matches the rate of the GPU (at least at 120, 312, and 432 MHz).
> This is further underlined by the fact, that none of the rates can be
> achieved by integer dividing one of the other rates. sunxi-ng would
> only favor a different rate for pll-gpu than the one that is requested
> for the gpu, if pll-gpu is already running at a rate such that there
> exists an M ? {1, 2, 3, 4, 5, 6, 7, 8}, where
>   rate of pll-gpu / M = requested gpu rate
> or if the requested rate could not be reached directly by pll-gpu. Both
> is not the case for the rates in question (120, 192, 312, and 432 MHz).
> 
> This means that the following divisor/multipliers are used by sunxi-ng's
> ccu_nm:
> N =  5, M = 1 for 120 MHz (min value without PATCH 6)
> N =  8, M = 1 for 192 MHz (min value after applying PATCH 6)
> N = 13, M = 1 for 312 MHz
> N = 18, M = 1 for 432 MHz
> 
> So, with or without PATCH 6, the divider stays constant and it's only
> the multiplier that changes. This means, there should be no unexpected
> frequency spikes, right?

Maybe. Thanks for giving it a try. There may still be other kinds of glitches
even if the divisor stays the same. It all depends how the register update is
implemented in the PLL block. It's hard to say. I guess, unless Allwinner
guarantees glitchless output from a given PLL when changing its parameters,
you can't rely on the output being clean during changes.

> >> It's also unclear what happens when FRAC_CLK_OUT or PLL_MODE_SEL changes.
> 
> Those are not changed once the clock is initialized. The bug however
> occurs hours or days after booting. IMO, this makes it unlikely that this
> could be the culprit.
> 
> >> Maybe not much because M is supposed to be set to 1, but you still need to
> >> care when enabling fractional mode, and setting M to 1 because that's exactly
> >> the bad scenario if M was previously higher than 1.
> >>
> >> It's tricky.
> >>
> >> Having GPU module clock gated during PLL config changes may help! You can
> >> do that without locking yourself out, unlike with the CPU PLL.
> >>
> >> There's a gate enable bit for it at GPU_CLK_REG.SCLK_GATING. (page 122)
> 
> The GPU should already be properly gated:
> https://elixir.bootlin.com/linux/v6.7.4/source/drivers/clk/sunxi-ng/ccu-sun50i-a64.c#L599

How so? That's just clock declaration. How does it guarantee the clock to the
module is gated during parent PLL configuration changes?

CLK_SET_RATE_PARENT only gates output on re-parenting, not on parent rate changes,
according to the header:

  https://elixir.bootlin.com/linux/v6.7.4/source/include/linux/clk-provider.h#L19

You'd need perhaps CLK_SET_RATE_GATE *and* still verify that it actually works
as expected via some tracing of gpu clock enable/disable/set_rate and pll-gpu
set_rate. CLK_SET_RATE_GATE seems confusingly docummented:

  https://elixir.bootlin.com/linux/v6.7.4/source/drivers/clk/clk.c#L1034

so I don't particularly trust it does exaclty what the header claims and what
would be needed to test the theory that gating gpu clock during rate change
might help.

kind regards,
	o.

> Thank you for your detailed proposal! It was insightful to read. But
> while those were all great ideas, they have all already been taken care
> of. I'm fresh out of ideas again (except for pinning the GPU rate).
> 
> Again, thank you so much,
>   Frank
> 
> >>
> >> Kind regards,
> >> 	o.
> >>
> >> > I very much appreciate your feedback!
> >> >
> >> > [1] https://gitlab.com/postmarketOS/pmaports/-/issues/805
> >> >
> >> > Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> >> > ---
> >> > Changes in v2:
> >> > - dts: Increase minimum GPU frequency to 192 MHz.
> >> > - nkm and a64: Add minimum and maximum rate for PLL-MIPI.
> >> > - nkm: Use the same approach for skipping invalid rates in
> >> >   ccu_nkm_find_best() as in ccu_nkm_find_best_with_parent_adj().
> >> > - nkm: Improve names for ratio struct members and hence get rid of
> >> >   describing comments.
> >> > - nkm and a64: Correct description in the commit messages: M/N <= 3
> >> > - Remove patches for nm as they were not needed.
> >> > - st7703: Rework the commit message to cover more background for the
> >> >   change.
> >> > - Link to v1: https://lore.kernel.org/r/20231218-pinephone-pll-fixes-v1-0-e238b6ed6dc1 at oltmanns.dev
> >> >
> >> > ---
> >> > Frank Oltmanns (6):
> >> >       clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate
> >> >       clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate
> >> >       clk: sunxi-ng: nkm: Support minimum and maximum rate
> >> >       clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
> >> >       drm/panel: st7703: Drive XBD599 panel at higher clock rate
> >> >       arm64: dts: allwinner: a64: Fix minimum GPU OPP rate
> >> >
> >> >  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  4 ++--
> >> >  drivers/clk/sunxi-ng/ccu-sun50i-a64.c         | 14 +++++++----
> >> >  drivers/clk/sunxi-ng/ccu_nkm.c                | 34 +++++++++++++++++++++++++++
> >> >  drivers/clk/sunxi-ng/ccu_nkm.h                |  4 ++++
> >> >  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++++------
> >> >  5 files changed, 56 insertions(+), 14 deletions(-)
> >> > ---
> >> > base-commit: 059c53e877ca6e723e10490c27c1487a63e66efe
> >> > change-id: 20231218-pinephone-pll-fixes-0ccdfde273e4
> >> >
> >> > Best regards,
> >> > --
> >> > Frank Oltmanns <frank at oltmanns.dev>
> >> >


From jernej.skrabec at gmail.com  Sun Feb 11 12:13:52 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Sun, 11 Feb 2024 21:13:52 +0100
Subject: [PATCH v2 0/3] arm64: dts: allwinner: Add Remix Mini PC support
In-Reply-To: <20240209114018.3580370-1-andre.przywara@arm.com>
References: <20240209114018.3580370-1-andre.przywara@arm.com>
Message-ID: <3283025.44csPzL39Z@jernej-laptop>

Dne petek, 09. februar 2024 ob 12:40:15 CET je Andre Przywara napisal(a):
> Hi,
> 
> a small update, addressing the review comments and adding tags. See
> below for a changelog.
> 
> ==========================================
> These are the DT support patches for the Jide Remix Mini PC, a now
> somewhat dated Mini-PC, once shipped with some kind of desktop Android OS.
> It sports an Allwinner H64 SoC, which is basically the same as the
> venerable A64.
> To make it stick out of the crowd, the SoC has "secure boot" enabled,
> which just means it needs a different (signed) boot code package, already
> supported by mainline U-Boot. Fortunately there is no public key burned
> into the SoC, so any key can be used: the U-Boot build system will just
> make one up.
> Apart from Ethernet (blocked by the AC200 PHY) everything should work,
> including WiFi and Bluetooth.
> 
> Please have a look!

Applied, thanks!

Best regards,
Jernej

> 
> Changelog v1 .. v2:
> - Update copyright year
> - Remove not-working MMC DDR speed mode
> - Add HS-400 speed mode property (used by the BSP kernel)
> - Remove superfluous pinctrl-names property
> 
> Andre Przywara (3):
>   dt-bindings: vendor-prefixes: add Jide
>   dt-bindings: arm: sunxi: document Remix Mini PC name
>   arm64: dts: allwinner: Add Jide Remix Mini PC support
> 
>  .../devicetree/bindings/arm/sunxi.yaml        |   6 +
>  .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
>  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
>  .../allwinner/sun50i-h64-remix-mini-pc.dts    | 356 ++++++++++++++++++
>  4 files changed, 365 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
> 
> 






From jernej.skrabec at gmail.com  Sun Feb 11 12:16:44 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Sun, 11 Feb 2024 21:16:44 +0100
Subject: [PATCH v2 0/2]  arm64: dts: allwinner: Add Transpeed WiFi nodes
In-Reply-To: <20240209115759.3582869-1-andre.przywara@arm.com>
References: <20240209115759.3582869-1-andre.przywara@arm.com>
Message-ID: <10418022.nUPlyArG6x@jernej-laptop>

Dne petek, 09. februar 2024 ob 12:57:57 CET je Andre Przywara napisal(a):
> Hi,
> 
> a tiny update, see below for the changelog.
> ======================================
> 
> This adds the WiFi DT nodes for the Transpeed 8K618T TV box. It uses a
> Murata module with a Broadcom 4335 chip, which works fine with the
> mainline Linux driver, given you provide the proper firmware files. We
> found some in some LibreELEC repository.
> 
> Patch 1 adds the pinctrl node for the 32KHz clock fanout pin, patch 2
> adds the actual SDIO WiFi node.
> 
> Please have a look!

Fixed order in patch 2 and applied, thanks!

Best regards,
Jernej

> 
> Cheers,
> Andre
> 
> Changelog v1 .. v2:
> - add /omit-if-no-ref/ tag for clock fanout pin node
> - update commit message to avoid mentioning Linux or driver
> 
> Andre Przywara (2):
>   arm64: dts: allwinner: h616: Add 32K fanout pin
>   arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes
> 
>  .../arm64/boot/dts/allwinner/sun50i-h616.dtsi |  6 +++++
>  .../sun50i-h618-transpeed-8k618-t.dts         | 23 +++++++++++++++++++
>  2 files changed, 29 insertions(+)
> 
> 






From jernej.skrabec at gmail.com  Sun Feb 11 12:18:44 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Sun, 11 Feb 2024 21:18:44 +0100
Subject: [PATCH 1/2] arm64: dts: allwinner: use capital "OR" for multiple licenses
 in SPDX
In-Reply-To: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>
References: <20240208105301.129005-1-krzysztof.kozlowski@linaro.org>
Message-ID: <1959194.PYKUYFuaPT@jernej-laptop>

Dne ?etrtek, 08. februar 2024 ob 11:53:00 CET je Krzysztof Kozlowski napisal(a):
> Documentation/process/license-rules.rst and checkpatch expect the SPDX
> identifier syntax for multiple licenses to use capital "OR".  Correct it
> to keep consistent format and avoid copy-paste issues.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Applied both, thanks!

Best regards,
Jernej

> ---
>  .../boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts    | 2 +-
>  arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi  | 2 +-
>  arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts    | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
> index dbce61b355d6..4bfb52609c94 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
> @@ -1,4 +1,4 @@
> -// SPDX-License-Identifier: (GPL-2.0+ or MIT)
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>  /*
>   * Copyright (C) 2023 Martin Botka <martin.botka at somainline.org>.
>   */
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
> index 1fed2b46cfe8..b2988f500231 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
> @@ -1,4 +1,4 @@
> -// SPDX-License-Identifier: (GPL-2.0+ or MIT)
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>  /*
>   * Copyright (C) 2023 Martin Botka <martin.botka at somainline.org>.
>   */
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
> index 832f08b2b260..ff84a3794470 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
> @@ -1,4 +1,4 @@
> -// SPDX-License-Identifier: (GPL-2.0+ or MIT)
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>  /*
>   * Copyright (C) 2023 Martin Botka <martin at biqu3d.com>.
>   */
> 






From jernej.skrabec at gmail.com  Sun Feb 11 12:22:11 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Sun, 11 Feb 2024 21:22:11 +0100
Subject: [PATCH v2 2/2] arm64: dts: allwinner: h618: add BananaPi M4 Berry board
In-Reply-To: <22174359.EfDdHjke4D@jernej-laptop>
References: <20240204101054.152012-1-andre.przywara@arm.com>
 <20240204101054.152012-3-andre.przywara@arm.com>
 <22174359.EfDdHjke4D@jernej-laptop>
Message-ID: <3791760.kQq0lBPeGt@jernej-laptop>

Hi Andre!

Dne ponedeljek, 05. februar 2024 ob 19:19:26 CET je Jernej ?krabec napisal(a):
> Dne nedelja, 04. februar 2024 ob 11:10:54 CET je Andre Przywara napisal(a):
> > The BananaPi M4 Berry is a development board using the Allwinner H618
> > SoC. It comes with the following specs:
> > 	- Allwinner H618 SoC (4 * Arm Cortex-A53 cores, 1MB L2 cache)
> > 	- 2 GiB LPDDR4 DRAM
> > 	- 8 GiB eMMC flash
> > 	- AXP313a PMIC
> > 	- Gigabit Ethernet, using RTL8211 PHY
> > 	- RTL8821CU USB WiFi chip
> > 	- HDMI port
> > 	- 4 * USB 2.0 ports, via an on-board hub chip
> > 	- microSD card slot
> > 	- 3.5mm A/V port
> > 	- power supply and USB-OTG via USB-C connector
> > 
> > Add a devicetree file describing the components that we already have
> > bindings for, that excludes audio and video at the moment.
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
> >  .../sun50i-h618-bananapi-m4-berry.dts         | 223 ++++++++++++++++++
> >  2 files changed, 224 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> > index 2db3b15ad09f..1c5c204a109b 100644
> > --- a/arch/arm64/boot/dts/allwinner/Makefile
> > +++ b/arch/arm64/boot/dts/allwinner/Makefile
> > @@ -43,5 +43,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
> > +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-bananapi-m4-berry.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
> >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
> > new file mode 100644
> > index 000000000000..a3f8ff75db42
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
> > @@ -0,0 +1,223 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Copyright (C) 2023 Arm Ltd.
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "sun50i-h616.dtsi"
> > +
> > +#include <dt-bindings/gpio/gpio.h>
> > +#include <dt-bindings/input/linux-event-codes.h>
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/leds/common.h>
> > +
> > +/ {
> > +	model = "BananaPi M4 Berry";
> > +	compatible = "sinovoip,bananapi-m4-berry", "allwinner,sun50i-h618";
> > +
> > +	aliases {
> > +		ethernet0 = &emac0;
> > +		serial0 = &uart0;
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +
> > +	leds {
> > +		compatible = "gpio-leds";
> > +
> > +		led-0 {
> > +			function = LED_FUNCTION_STATUS;
> > +			color = <LED_COLOR_ID_GREEN>;
> > +			gpios = <&pio 2 12 GPIO_ACTIVE_LOW>; /* PC12 */
> > +		};
> > +	};
> > +
> > +	gpio-keys {
> > +		compatible = "gpio-keys";
> > +
> > +		key-sw3 {
> > +			label = "sw3";
> > +			linux,code = <BTN_0>;
> > +			gpios = <&pio 2 7 GPIO_ACTIVE_LOW>;	/* PC7 */
> > +		};
> > +	};
> > +
> > +	reg_vcc5v: regulator-5v {
> > +		/* board wide 5V supply directly from the USB-C socket */
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "vcc-5v";
> > +		regulator-min-microvolt = <5000000>;
> > +		regulator-max-microvolt = <5000000>;
> > +		regulator-always-on;
> > +	};
> > +
> > +	reg_usb_vbus: regulator-usb-vbus {
> > +		/* separate discrete regulator for the USB ports */
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "usb-vbus";
> > +		regulator-min-microvolt = <5000000>;
> > +		regulator-max-microvolt = <5000000>;
> > +		vin-supply = <&reg_vcc5v>;
> > +	};
> > +
> > +	reg_3v3: regulator-3v3 {
> > +		/* separate discrete regulator for WiFi and Ethernet PHY */
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "vcc-3v3";
> > +		regulator-min-microvolt = <3300000>;
> > +		regulator-max-microvolt = <3300000>;
> > +		vin-supply = <&reg_vcc5v>;
> > +	};
> > +};
> > +
> > +&cpu0 {
> > +	cpu-supply = <&reg_dcdc2>;
> > +};
> > +
> > +/* Connected to an on-board RTL8821CU USB WiFi chip. */
> > +&ehci1 {
> > +	status = "okay";
> > +};
> > +
> > +/* EHCI2 is on unpopulated pins */
> > +
> > +/* Connected to an on-board FE1.1s USB hub chip, supplying 4 USB-A ports. */
> > +&ehci3 {
> > +	status = "okay";
> > +};
> > +
> > +&emac0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&ext_rgmii_pins>;
> > +	phy-mode = "rgmii";
> > +	phy-handle = <&ext_rgmii_phy>;
> > +	phy-supply = <&reg_3v3>;
> > +	allwinner,rx-delay-ps = <3100>;
> > +	allwinner,tx-delay-ps = <700>;
> > +	status = "okay";
> > +};
> > +
> > +&ir {
> > +	status = "okay";
> > +};
> > +
> > +&mdio0 {
> > +	ext_rgmii_phy: ethernet-phy at 1 {
> > +		compatible = "ethernet-phy-ieee802.3-c22";
> > +		reg = <1>;
> > +		reset-gpios = <&pio 8 16 GPIO_ACTIVE_LOW>;	/* PI16 */
> > +	};
> > +};
> > +
> > +&mmc0 {
> > +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;	/* PF6 */
> > +	vmmc-supply = <&reg_dldo1>;
> > +	bus-width = <4>;
> > +	status = "okay";
> > +};
> > +
> > +&mmc2 {
> > +	vmmc-supply = <&reg_dldo1>;
> > +	vqmmc-supply = <&reg_aldo1>;
> > +	bus-width = <8>;
> > +	non-removable;
> > +	cap-mmc-hw-reset;
> > +	mmc-ddr-1_8v;
> 
> This one should be dropped.

Can you please test this one? If it works, I'll merge this series.

Best regards,
Jernej
 
> > +	mmc-hs200-1_8v;
> > +	status = "okay";
> > +};
> > +
> > +/* USB ports 1 and 3 connect to onboard devices that are high-speed only. */
> > +
> > +/* OHCI2 is on unpopulated pins */
> > +
> > +&pio {
> > +	vcc-pc-supply = <&reg_aldo1>;
> > +	vcc-pf-supply = <&reg_dldo1>;
> > +	vcc-pg-supply = <&reg_dldo1>;
> > +	vcc-ph-supply = <&reg_dldo1>;
> > +	vcc-pi-supply = <&reg_dldo1>;
> > +};
> > +
> > +&r_i2c {
> > +	status = "okay";
> > +
> > +	axp313: pmic at 36 {
> > +		compatible = "x-powers,axp313a";
> > +		reg = <0x36>;
> > +		#interrupt-cells = <1>;
> > +		interrupt-controller;
> > +		interrupt-parent = <&pio>;
> > +
> > +		vin1-supply = <&reg_vcc5v>;
> > +		vin2-supply = <&reg_vcc5v>;
> > +		vin3-supply = <&reg_vcc5v>;
> > +
> > +		regulators {
> > +			reg_aldo1: aldo1 {
> > +				regulator-always-on;
> > +				regulator-min-microvolt = <1800000>;
> > +				regulator-max-microvolt = <1800000>;
> > +				regulator-name = "vcc-1v8-pll";
> > +			};
> > +
> > +			reg_dldo1: dldo1 {
> > +				regulator-always-on;
> > +				regulator-min-microvolt = <3300000>;
> > +				regulator-max-microvolt = <3300000>;
> > +				regulator-name = "vcc-3v3-io";
> > +			};
> > +
> > +			reg_dcdc1: dcdc1 {
> > +				regulator-always-on;
> > +				regulator-min-microvolt = <810000>;
> > +				regulator-max-microvolt = <990000>;
> > +				regulator-name = "vdd-gpu-sys";
> > +			};
> > +
> > +			reg_dcdc2: dcdc2 {
> > +				regulator-always-on;
> > +				regulator-min-microvolt = <810000>;
> > +				regulator-max-microvolt = <1100000>;
> > +				regulator-name = "vdd-cpu";
> > +			};
> > +
> > +			reg_dcdc3: dcdc3 {
> > +				regulator-always-on;
> > +				regulator-min-microvolt = <1100000>;
> > +				regulator-max-microvolt = <1100000>;
> > +				regulator-name = "vdd-dram";
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&uart0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&uart0_ph_pins>;
> > +	status = "okay";
> > +};
> > +
> > +&usbotg {
> > +	/*
> > +	 * PHY0 pins are connected to a USB-C socket, but a role switch is not
> > +	 * implemented: both CC pins are pulled to GND via a 5.1K resistor.
> > +	 * The VBUS pins power the device, so a fixed peripheral mode
> > +	 * is the best choice.
> > +	 * The board can be powered via GPIOs, in this case port0 *can*
> > +	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
> > +	 * then provided by the GPIOs. Any user of this setup would
> > +	 * need to adjust the DT accordingly: dr_mode set to "host",
> > +	 * enabling OHCI0 and EHCI0.
> > +	 */
> > +	dr_mode = "peripheral";
> > +	status = "okay";
> > +};
> > +
> > +&usbphy {
> > +	usb3_vbus-supply = <&reg_usb_vbus>;
> > +	status = "okay";
> > +};
> > 
> 
> 
> 
> 
> 






From jernej.skrabec at gmail.com  Sun Feb 11 12:25:29 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Sun, 11 Feb 2024 21:25:29 +0100
Subject: [PATCH] bus: sunxi-rsb: make sunxi_rsb_bus const
In-Reply-To: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
References: <20240204-bus_cleanup-bus-v1-1-bda309c4b829@marliere.net>
Message-ID: <9236043.CDJkKcVGEf@jernej-laptop>

Dne nedelja, 04. februar 2024 ob 16:56:44 CET je Ricardo B. Marliere napisal(a):
> Now that the driver core can properly handle constant struct bus_type,
> move the sunxi_rsb_bus variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Applied, thanks!

Best regards,
Jernej




From linus.walleij at linaro.org  Sun Feb 11 13:24:22 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 11 Feb 2024 22:24:22 +0100
Subject: [PATCH 0/4] ARM: dts: gemini: Fix some minor DTS issues
Message-ID: <20240211-gemini-dts-v1-0-6c09adeb4c2e@linaro.org>

We have recommended practices for node naming and we have
some keys that could be better represented. Some compatible
top-level should be updated to the recommendation from the
bindings. This small series fixes up these minor issues.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Linus Walleij (4):
      ARM: dts: gemini: Fix switch node names in the DIR-685
      ARM: dts: gemini: Fix wiligear compatible strings
      ARM: dts: gemini: Map reset keys to KEY_RESTART
      ARM: dts: gemini: Fix switch node names on Vitesse switches

 arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts | 30 +++++++++++------------
 arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts |  4 +--
 arch/arm/boot/dts/gemini/gemini-sl93512r.dts      | 16 ++++++------
 arch/arm/boot/dts/gemini/gemini-sq201.dts         | 16 ++++++------
 arch/arm/boot/dts/gemini/gemini-wbd111.dts        |  6 ++---
 arch/arm/boot/dts/gemini/gemini-wbd222.dts        |  6 ++---
 6 files changed, 39 insertions(+), 39 deletions(-)
---
base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
change-id: 20240209-gemini-dts-3efe33dec69e

Best regards,
-- 
Linus Walleij <linus.walleij at linaro.org>



From linus.walleij at linaro.org  Sun Feb 11 13:24:23 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 11 Feb 2024 22:24:23 +0100
Subject: [PATCH 1/4] ARM: dts: gemini: Fix switch node names in the DIR-685
In-Reply-To: <20240211-gemini-dts-v1-0-6c09adeb4c2e@linaro.org>
References: <20240211-gemini-dts-v1-0-6c09adeb4c2e@linaro.org>
Message-ID: <20240211-gemini-dts-v1-1-6c09adeb4c2e@linaro.org>

The formally correct node names have "ethernet-*" prefix on
switch, ports, port and phy, fix it up.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts | 26 +++++++++++------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
index 396149664297..30c931415680 100644
--- a/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
+++ b/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
@@ -187,7 +187,7 @@ touchkeys at 26 {
 	};
 
 	/* This is a RealTek RTL8366RB switch and PHY using SMI over GPIO */
-	switch {
+	ethernet-switch {
 		compatible = "realtek,rtl8366rb";
 		/* 22 = MDIO (has input reads), 21 = MDC (clock, output only) */
 		mdc-gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
@@ -204,36 +204,36 @@ switch_intc: interrupt-controller {
 			#interrupt-cells = <1>;
 		};
 
-		ports {
+		ethernet-ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
 
-			port at 0 {
+			ethernet-port at 0 {
 				reg = <0>;
 				label = "lan0";
 				phy-handle = <&phy0>;
 			};
-			port at 1 {
+			ethernet-port at 1 {
 				reg = <1>;
 				label = "lan1";
 				phy-handle = <&phy1>;
 			};
-			port at 2 {
+			ethernet-port at 2 {
 				reg = <2>;
 				label = "lan2";
 				phy-handle = <&phy2>;
 			};
-			port at 3 {
+			ethernet-port at 3 {
 				reg = <3>;
 				label = "lan3";
 				phy-handle = <&phy3>;
 			};
-			port at 4 {
+			ethernet-port at 4 {
 				reg = <4>;
 				label = "wan";
 				phy-handle = <&phy4>;
 			};
-			rtl8366rb_cpu_port: port at 5 {
+			rtl8366rb_cpu_port: ethernet-port at 5 {
 				reg = <5>;
 				label = "cpu";
 				ethernet = <&gmac0>;
@@ -252,27 +252,27 @@ mdio {
 			#address-cells = <1>;
 			#size-cells = <0>;
 
-			phy0: phy at 0 {
+			phy0: ethernet-phy at 0 {
 				reg = <0>;
 				interrupt-parent = <&switch_intc>;
 				interrupts = <0>;
 			};
-			phy1: phy at 1 {
+			phy1: ethernet-phy at 1 {
 				reg = <1>;
 				interrupt-parent = <&switch_intc>;
 				interrupts = <1>;
 			};
-			phy2: phy at 2 {
+			phy2: ethernet-phy at 2 {
 				reg = <2>;
 				interrupt-parent = <&switch_intc>;
 				interrupts = <2>;
 			};
-			phy3: phy at 3 {
+			phy3: ethernet-phy at 3 {
 				reg = <3>;
 				interrupt-parent = <&switch_intc>;
 				interrupts = <3>;
 			};
-			phy4: phy at 4 {
+			phy4: ethernet-phy at 4 {
 				reg = <4>;
 				interrupt-parent = <&switch_intc>;
 				interrupts = <12>;

-- 
2.34.1



From linus.walleij at linaro.org  Sun Feb 11 13:24:24 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 11 Feb 2024 22:24:24 +0100
Subject: [PATCH 2/4] ARM: dts: gemini: Fix wiligear compatible strings
In-Reply-To: <20240211-gemini-dts-v1-0-6c09adeb4c2e@linaro.org>
References: <20240211-gemini-dts-v1-0-6c09adeb4c2e@linaro.org>
Message-ID: <20240211-gemini-dts-v1-2-6c09adeb4c2e@linaro.org>

These board strings were deprecated in the bindings ages ago,
switch the boards over to the real names.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/boot/dts/gemini/gemini-wbd111.dts | 2 +-
 arch/arm/boot/dts/gemini/gemini-wbd222.dts | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/gemini/gemini-wbd111.dts b/arch/arm/boot/dts/gemini/gemini-wbd111.dts
index 3c88c59ab481..d4038930c70f 100644
--- a/arch/arm/boot/dts/gemini/gemini-wbd111.dts
+++ b/arch/arm/boot/dts/gemini/gemini-wbd111.dts
@@ -10,7 +10,7 @@
 
 / {
 	model = "Wiliboard WBD-111";
-	compatible = "wiliboard,wbd111", "cortina,gemini";
+	compatible = "wiligear,wiliboard-wbd111", "cortina,gemini";
 	#address-cells = <1>;
 	#size-cells = <1>;
 
diff --git a/arch/arm/boot/dts/gemini/gemini-wbd222.dts b/arch/arm/boot/dts/gemini/gemini-wbd222.dts
index ff72bbc4db3e..a503bcff5f4a 100644
--- a/arch/arm/boot/dts/gemini/gemini-wbd222.dts
+++ b/arch/arm/boot/dts/gemini/gemini-wbd222.dts
@@ -10,7 +10,7 @@
 
 / {
 	model = "Wiliboard WBD-222";
-	compatible = "wiliboard,wbd222", "cortina,gemini";
+	compatible = "wiligear,wiliboard-wbd222", "cortina,gemini";
 	#address-cells = <1>;
 	#size-cells = <1>;
 

-- 
2.34.1



From linus.walleij at linaro.org  Sun Feb 11 13:24:25 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 11 Feb 2024 22:24:25 +0100
Subject: [PATCH 3/4] ARM: dts: gemini: Map reset keys to KEY_RESTART
In-Reply-To: <20240211-gemini-dts-v1-0-6c09adeb4c2e@linaro.org>
References: <20240211-gemini-dts-v1-0-6c09adeb4c2e@linaro.org>
Message-ID: <20240211-gemini-dts-v1-3-6c09adeb4c2e@linaro.org>

This maps the misc "reset", "setup" and "facory reset" keys to the
only key a standard userspace is likely to understand: KEY_RESTART.
On OpenWrt this will simply restart the system under controlled
forms.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts | 4 ++--
 arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts | 4 ++--
 arch/arm/boot/dts/gemini/gemini-sl93512r.dts      | 2 +-
 arch/arm/boot/dts/gemini/gemini-sq201.dts         | 2 +-
 arch/arm/boot/dts/gemini/gemini-wbd111.dts        | 4 ++--
 arch/arm/boot/dts/gemini/gemini-wbd222.dts        | 4 ++--
 6 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
index 30c931415680..b4dbcf8f168e 100644
--- a/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
+++ b/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
@@ -27,10 +27,10 @@ chosen {
 	gpio_keys {
 		compatible = "gpio-keys";
 
-		button-esc {
+		button-reset {
 			debounce-interval = <100>;
 			wakeup-source;
-			linux,code = <KEY_ESC>;
+			linux,code = <KEY_RESTART>;
 			label = "reset";
 			/* Collides with LPC_LAD[0], UART DCD, SSP 97RST */
 			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts b/arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts
index 138c47e1ac1b..8c54d3a5a721 100644
--- a/arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts
+++ b/arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts
@@ -33,10 +33,10 @@ chosen {
 	gpio_keys {
 		compatible = "gpio-keys";
 
-		button-esc {
+		button-reset {
 			debounce-interval = <100>;
 			wakeup-source;
-			linux,code = <KEY_ESC>;
+			linux,code = <KEY_RESTART>;
 			label = "reset";
 			gpios = <&gpio1 31 GPIO_ACTIVE_LOW>;
 		};
diff --git a/arch/arm/boot/dts/gemini/gemini-sl93512r.dts b/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
index 91c19e8ebfe8..be06a3815e3a 100644
--- a/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
+++ b/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
@@ -43,7 +43,7 @@ button-wps {
 		button-setup {
 			debounce-interval = <50>;
 			wakeup-source;
-			linux,code = <KEY_SETUP>;
+			linux,code = <KEY_RESTART>;
 			label = "factory reset";
 			/* Conflict with NAND flash */
 			gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/gemini/gemini-sq201.dts b/arch/arm/boot/dts/gemini/gemini-sq201.dts
index d0efd76695da..05ef8b80f104 100644
--- a/arch/arm/boot/dts/gemini/gemini-sq201.dts
+++ b/arch/arm/boot/dts/gemini/gemini-sq201.dts
@@ -30,7 +30,7 @@ gpio_keys {
 		button-setup {
 			debounce-interval = <100>;
 			wakeup-source;
-			linux,code = <KEY_SETUP>;
+			linux,code = <KEY_RESTART>;
 			label = "factory reset";
 			/* Conflict with NAND flash */
 			gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/gemini/gemini-wbd111.dts b/arch/arm/boot/dts/gemini/gemini-wbd111.dts
index d4038930c70f..6a0c89e0c918 100644
--- a/arch/arm/boot/dts/gemini/gemini-wbd111.dts
+++ b/arch/arm/boot/dts/gemini/gemini-wbd111.dts
@@ -28,10 +28,10 @@ chosen {
 	gpio_keys {
 		compatible = "gpio-keys";
 
-		button-setup {
+		button-reset {
 			debounce-interval = <100>;
 			wakeup-source;
-			linux,code = <KEY_SETUP>;
+			linux,code = <KEY_RESTART>;
 			label = "reset";
 			/* Conflict with ICE */
 			gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/gemini/gemini-wbd222.dts b/arch/arm/boot/dts/gemini/gemini-wbd222.dts
index a503bcff5f4a..d8b34ebad4b0 100644
--- a/arch/arm/boot/dts/gemini/gemini-wbd222.dts
+++ b/arch/arm/boot/dts/gemini/gemini-wbd222.dts
@@ -27,10 +27,10 @@ chosen {
 	gpio_keys {
 		compatible = "gpio-keys";
 
-		button-setup {
+		button-reset {
 			debounce-interval = <100>;
 			wakeup-source;
-			linux,code = <KEY_SETUP>;
+			linux,code = <KEY_RESTART>;
 			label = "reset";
 			/* Conflict with ICE */
 			gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;

-- 
2.34.1



From linus.walleij at linaro.org  Sun Feb 11 13:24:26 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 11 Feb 2024 22:24:26 +0100
Subject: [PATCH 4/4] ARM: dts: gemini: Fix switch node names on Vitesse
 switches
In-Reply-To: <20240211-gemini-dts-v1-0-6c09adeb4c2e@linaro.org>
References: <20240211-gemini-dts-v1-0-6c09adeb4c2e@linaro.org>
Message-ID: <20240211-gemini-dts-v1-4-6c09adeb4c2e@linaro.org>

The formally correct node names have "ethernet-*" prefix on
switch, ports and port, fix it up.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/boot/dts/gemini/gemini-sl93512r.dts | 14 +++++++-------
 arch/arm/boot/dts/gemini/gemini-sq201.dts    | 14 +++++++-------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/arch/arm/boot/dts/gemini/gemini-sl93512r.dts b/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
index be06a3815e3a..4992ec276de9 100644
--- a/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
+++ b/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
@@ -93,7 +93,7 @@ spi {
 		cs-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
 		num-chipselects = <1>;
 
-		switch at 0 {
+		ethernet-switch at 0 {
 			compatible = "vitesse,vsc7385";
 			reg = <0>;
 			/* Specified for 2.5 MHz or below */
@@ -101,27 +101,27 @@ switch at 0 {
 			gpio-controller;
 			#gpio-cells = <2>;
 
-			ports {
+			ethernet-ports {
 				#address-cells = <1>;
 				#size-cells = <0>;
 
-				port at 0 {
+				ethernet-port at 0 {
 					reg = <0>;
 					label = "lan1";
 				};
-				port at 1 {
+				ethernet-port at 1 {
 					reg = <1>;
 					label = "lan2";
 				};
-				port at 2 {
+				ethernet-port at 2 {
 					reg = <2>;
 					label = "lan3";
 				};
-				port at 3 {
+				ethernet-port at 3 {
 					reg = <3>;
 					label = "lan4";
 				};
-				vsc: port at 6 {
+				vsc: ethernet-port at 6 {
 					reg = <6>;
 					label = "cpu";
 					ethernet = <&gmac1>;
diff --git a/arch/arm/boot/dts/gemini/gemini-sq201.dts b/arch/arm/boot/dts/gemini/gemini-sq201.dts
index 05ef8b80f104..f8c6f6e5cdea 100644
--- a/arch/arm/boot/dts/gemini/gemini-sq201.dts
+++ b/arch/arm/boot/dts/gemini/gemini-sq201.dts
@@ -78,7 +78,7 @@ spi {
 		cs-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
 		num-chipselects = <1>;
 
-		switch at 0 {
+		ethernet-switch at 0 {
 			compatible = "vitesse,vsc7395";
 			reg = <0>;
 			/* Specified for 2.5 MHz or below */
@@ -86,27 +86,27 @@ switch at 0 {
 			gpio-controller;
 			#gpio-cells = <2>;
 
-			ports {
+			ethernet-ports {
 				#address-cells = <1>;
 				#size-cells = <0>;
 
-				port at 0 {
+				ethernet-port at 0 {
 					reg = <0>;
 					label = "lan1";
 				};
-				port at 1 {
+				ethernet-port at 1 {
 					reg = <1>;
 					label = "lan2";
 				};
-				port at 2 {
+				ethernet-port at 2 {
 					reg = <2>;
 					label = "lan3";
 				};
-				port at 3 {
+				ethernet-port at 3 {
 					reg = <3>;
 					label = "lan4";
 				};
-				vsc: port at 6 {
+				vsc: ethernet-port at 6 {
 					reg = <6>;
 					label = "cpu";
 					ethernet = <&gmac1>;

-- 
2.34.1



From zajec5 at gmail.com  Sun Feb 11 13:39:22 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Sun, 11 Feb 2024 22:39:22 +0100
Subject: [PATCH V3 0/3] dt-bindings: arm: mediatek: convert MT7622-related bindings to the json-schema
Message-ID: <20240211213925.18348-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

There are more MediaTek bindings to convert but for now I focused on
those used by MT7622.

V2: Move bindings to /clock/
    Use clock-controller@ nodenames
    Drop incorrectly specified "syscon"

V3: Update titles of all 3 bindings
    Simplify HIFSYS compatbile (drop "items:")

Rafa? Mi?ecki (3):
  dt-bindings: arm: mediatek: convert hifsys to the json-schema clock
  dt-bindings: arm: mediatek: convert PCIESYS to the json-schema clock
  dt-bindings: arm: mediatek: convert SSUSBSYS to the json-schema clock

 .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
 .../arm/mediatek/mediatek,pciesys.txt         | 25 ----------
 .../arm/mediatek/mediatek,ssusbsys.txt        | 25 ----------
 .../clock/mediatek,mt2701-hifsys.yaml         | 50 +++++++++++++++++++
 .../clock/mediatek,mt7622-pciesys.yaml        | 45 +++++++++++++++++
 .../clock/mediatek,mt7622-ssusbsys.yaml       | 45 +++++++++++++++++
 6 files changed, 140 insertions(+), 76 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml

-- 
2.35.3



From zajec5 at gmail.com  Sun Feb 11 13:39:24 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Sun, 11 Feb 2024 22:39:24 +0100
Subject: [PATCH V3 2/3] dt-bindings: arm: mediatek: convert PCIESYS to the json-schema clock
In-Reply-To: <20240211213925.18348-1-zajec5@gmail.com>
References: <20240211213925.18348-1-zajec5@gmail.com>
Message-ID: <20240211213925.18348-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Documented "reg" property
2. Dropped "syscon" as it was incorrectly used
3. Adjusted nodename, "compatible" and "reg" in example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../arm/mediatek/mediatek,pciesys.txt         | 25 -----------
 .../clock/mediatek,mt7622-pciesys.yaml        | 45 +++++++++++++++++++
 2 files changed, 45 insertions(+), 25 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
deleted file mode 100644
index d179a61536f4..000000000000
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-MediaTek PCIESYS controller
-============================
-
-The MediaTek PCIESYS controller provides various clocks to the system.
-
-Required Properties:
-
-- compatible: Should be:
-	- "mediatek,mt7622-pciesys", "syscon"
-	- "mediatek,mt7629-pciesys", "syscon"
-- #clock-cells: Must be 1
-- #reset-cells: Must be 1
-
-The PCIESYS controller uses the common clk binding from
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-
-Example:
-
-pciesys: pciesys at 1a100800 {
-	compatible = "mediatek,mt7622-pciesys", "syscon";
-	reg = <0 0x1a100800 0 0x1000>;
-	#clock-cells = <1>;
-	#reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml
new file mode 100644
index 000000000000..c77111d10f90
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt7622-pciesys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek PCIESYS clock and reset controller
+
+description:
+  The MediaTek PCIESYS controller provides various clocks to the system.
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7622-pciesys
+      - mediatek,mt7629-pciesys
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+    description: The available clocks are defined in dt-bindings/clock/mt*-clk.h
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 1a100800 {
+        compatible = "mediatek,mt7622-pciesys";
+        reg = <0x1a100800 0x1000>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
-- 
2.35.3



From zajec5 at gmail.com  Sun Feb 11 13:39:23 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Sun, 11 Feb 2024 22:39:23 +0100
Subject: [PATCH V3 1/3] dt-bindings: arm: mediatek: convert HIFSYS to the json-schema clock
In-Reply-To: <20240211213925.18348-1-zajec5@gmail.com>
References: <20240211213925.18348-1-zajec5@gmail.com>
Message-ID: <20240211213925.18348-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Documented "reg" property
2. Documented "#reset-cells" property
3. Dropped "syscon" as it was incorrectly used
4. Adjusted "compatible" and "reg" in example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
 .../clock/mediatek,mt2701-hifsys.yaml         | 50 +++++++++++++++++++
 2 files changed, 50 insertions(+), 26 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
deleted file mode 100644
index 323905af82c3..000000000000
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Mediatek hifsys controller
-============================
-
-The Mediatek hifsys controller provides various clocks and reset
-outputs to the system.
-
-Required Properties:
-
-- compatible: Should be:
-	- "mediatek,mt2701-hifsys", "syscon"
-	- "mediatek,mt7622-hifsys", "syscon"
-	- "mediatek,mt7623-hifsys", "mediatek,mt2701-hifsys", "syscon"
-- #clock-cells: Must be 1
-
-The hifsys controller uses the common clk binding from
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-
-Example:
-
-hifsys: clock-controller at 1a000000 {
-	compatible = "mediatek,mt2701-hifsys", "syscon";
-	reg = <0 0x1a000000 0 0x1000>;
-	#clock-cells = <1>;
-	#reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
new file mode 100644
index 000000000000..9e7c725093aa
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt2701-hifsys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek HIFSYS clock and reset controller
+
+description:
+  The MediaTek HIFSYS controller provides various clocks and reset outputs to
+  the system.
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - mediatek,mt2701-hifsys
+          - mediatek,mt7622-hifsys
+      - items:
+          - enum:
+              - mediatek,mt7623-hifsys
+          - const: mediatek,mt2701-hifsys
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+    description: The available clocks are defined in dt-bindings/clock/mt*-clk.h
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - reg
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 1a000000 {
+        compatible = "mediatek,mt2701-hifsys";
+        reg = <0x1a000000 0x1000>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
-- 
2.35.3



From zajec5 at gmail.com  Sun Feb 11 13:39:25 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Sun, 11 Feb 2024 22:39:25 +0100
Subject: [PATCH V3 3/3] dt-bindings: arm: mediatek: convert SSUSBSYS to the json-schema clock
In-Reply-To: <20240211213925.18348-1-zajec5@gmail.com>
References: <20240211213925.18348-1-zajec5@gmail.com>
Message-ID: <20240211213925.18348-4-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Documented "reg" property
2. Dropped "syscon" as it was incorrectly used
3. Adjusted nodename, "compatible" and "reg" in example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../arm/mediatek/mediatek,ssusbsys.txt        | 25 -----------
 .../clock/mediatek,mt7622-ssusbsys.yaml       | 45 +++++++++++++++++++
 2 files changed, 45 insertions(+), 25 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
deleted file mode 100644
index 7cb02c930613..000000000000
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-MediaTek SSUSBSYS controller
-============================
-
-The MediaTek SSUSBSYS controller provides various clocks to the system.
-
-Required Properties:
-
-- compatible: Should be:
-	- "mediatek,mt7622-ssusbsys", "syscon"
-	- "mediatek,mt7629-ssusbsys", "syscon"
-- #clock-cells: Must be 1
-- #reset-cells: Must be 1
-
-The SSUSBSYS controller uses the common clk binding from
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-
-Example:
-
-ssusbsys: ssusbsys at 1a000000 {
-	compatible = "mediatek,mt7622-ssusbsys", "syscon";
-	reg = <0 0x1a000000 0 0x1000>;
-	#clock-cells = <1>;
-	#reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml
new file mode 100644
index 000000000000..da93eccdcfc1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt7622-ssusbsys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek SSUSBSYS clock and reset controller
+
+description:
+  The MediaTek SSUSBSYS controller provides various clocks to the system.
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7622-ssusbsys
+      - mediatek,mt7629-ssusbsys
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+    description: The available clocks are defined in dt-bindings/clock/mt*-clk.h
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 1a000000 {
+        compatible = "mediatek,mt7622-ssusbsys";
+        reg = <0x1a000000 0x1000>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
-- 
2.35.3



From andre.przywara at arm.com  Sun Feb 11 14:21:25 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun, 11 Feb 2024 22:21:25 +0000
Subject: [PATCH v2 2/2] arm64: dts: allwinner: h618: add BananaPi M4
 Berry board
In-Reply-To: <3791760.kQq0lBPeGt@jernej-laptop>
References: <20240204101054.152012-1-andre.przywara@arm.com>
	<20240204101054.152012-3-andre.przywara@arm.com>
	<22174359.EfDdHjke4D@jernej-laptop>
	<3791760.kQq0lBPeGt@jernej-laptop>
Message-ID: <20240211222125.5396a059@minigeek.lan>

On Sun, 11 Feb 2024 21:22:11 +0100
Jernej ?krabec <jernej.skrabec at gmail.com> wrote:

Hi Jernej,

> Hi Andre!
> 
> Dne ponedeljek, 05. februar 2024 ob 19:19:26 CET je Jernej ?krabec napisal(a):
> > Dne nedelja, 04. februar 2024 ob 11:10:54 CET je Andre Przywara napisal(a):  
> > > The BananaPi M4 Berry is a development board using the Allwinner H618
> > > SoC. It comes with the following specs:
> > > 	- Allwinner H618 SoC (4 * Arm Cortex-A53 cores, 1MB L2 cache)
> > > 	- 2 GiB LPDDR4 DRAM
> > > 	- 8 GiB eMMC flash
> > > 	- AXP313a PMIC
> > > 	- Gigabit Ethernet, using RTL8211 PHY
> > > 	- RTL8821CU USB WiFi chip
> > > 	- HDMI port
> > > 	- 4 * USB 2.0 ports, via an on-board hub chip
> > > 	- microSD card slot
> > > 	- 3.5mm A/V port
> > > 	- power supply and USB-OTG via USB-C connector
> > > 
> > > Add a devicetree file describing the components that we already have
> > > bindings for, that excludes audio and video at the moment.
> > > 
> > > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > > ---
> > >  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
> > >  .../sun50i-h618-bananapi-m4-berry.dts         | 223 ++++++++++++++++++
> > >  2 files changed, 224 insertions(+)
> > >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
> > > 
> > > diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> > > index 2db3b15ad09f..1c5c204a109b 100644
> > > --- a/arch/arm64/boot/dts/allwinner/Makefile
> > > +++ b/arch/arm64/boot/dts/allwinner/Makefile
> > > @@ -43,5 +43,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
> > >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
> > >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
> > >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
> > > +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-bananapi-m4-berry.dtb
> > >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
> > >  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
> > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
> > > new file mode 100644
> > > index 000000000000..a3f8ff75db42
> > > --- /dev/null
> > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-bananapi-m4-berry.dts
> > > @@ -0,0 +1,223 @@
> > > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > > +/*
> > > + * Copyright (C) 2023 Arm Ltd.
> > > + */
> > > +
> > > +/dts-v1/;
> > > +
> > > +#include "sun50i-h616.dtsi"
> > > +
> > > +#include <dt-bindings/gpio/gpio.h>
> > > +#include <dt-bindings/input/linux-event-codes.h>
> > > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > > +#include <dt-bindings/leds/common.h>
> > > +
> > > +/ {
> > > +	model = "BananaPi M4 Berry";
> > > +	compatible = "sinovoip,bananapi-m4-berry", "allwinner,sun50i-h618";
> > > +
> > > +	aliases {
> > > +		ethernet0 = &emac0;
> > > +		serial0 = &uart0;
> > > +	};
> > > +
> > > +	chosen {
> > > +		stdout-path = "serial0:115200n8";
> > > +	};
> > > +
> > > +	leds {
> > > +		compatible = "gpio-leds";
> > > +
> > > +		led-0 {
> > > +			function = LED_FUNCTION_STATUS;
> > > +			color = <LED_COLOR_ID_GREEN>;
> > > +			gpios = <&pio 2 12 GPIO_ACTIVE_LOW>; /* PC12 */
> > > +		};
> > > +	};
> > > +
> > > +	gpio-keys {
> > > +		compatible = "gpio-keys";
> > > +
> > > +		key-sw3 {
> > > +			label = "sw3";
> > > +			linux,code = <BTN_0>;
> > > +			gpios = <&pio 2 7 GPIO_ACTIVE_LOW>;	/* PC7 */
> > > +		};
> > > +	};
> > > +
> > > +	reg_vcc5v: regulator-5v {
> > > +		/* board wide 5V supply directly from the USB-C socket */
> > > +		compatible = "regulator-fixed";
> > > +		regulator-name = "vcc-5v";
> > > +		regulator-min-microvolt = <5000000>;
> > > +		regulator-max-microvolt = <5000000>;
> > > +		regulator-always-on;
> > > +	};
> > > +
> > > +	reg_usb_vbus: regulator-usb-vbus {
> > > +		/* separate discrete regulator for the USB ports */
> > > +		compatible = "regulator-fixed";
> > > +		regulator-name = "usb-vbus";
> > > +		regulator-min-microvolt = <5000000>;
> > > +		regulator-max-microvolt = <5000000>;
> > > +		vin-supply = <&reg_vcc5v>;
> > > +	};
> > > +
> > > +	reg_3v3: regulator-3v3 {
> > > +		/* separate discrete regulator for WiFi and Ethernet PHY */
> > > +		compatible = "regulator-fixed";
> > > +		regulator-name = "vcc-3v3";
> > > +		regulator-min-microvolt = <3300000>;
> > > +		regulator-max-microvolt = <3300000>;
> > > +		vin-supply = <&reg_vcc5v>;
> > > +	};
> > > +};
> > > +
> > > +&cpu0 {
> > > +	cpu-supply = <&reg_dcdc2>;
> > > +};
> > > +
> > > +/* Connected to an on-board RTL8821CU USB WiFi chip. */
> > > +&ehci1 {
> > > +	status = "okay";
> > > +};
> > > +
> > > +/* EHCI2 is on unpopulated pins */
> > > +
> > > +/* Connected to an on-board FE1.1s USB hub chip, supplying 4 USB-A ports. */
> > > +&ehci3 {
> > > +	status = "okay";
> > > +};
> > > +
> > > +&emac0 {
> > > +	pinctrl-names = "default";
> > > +	pinctrl-0 = <&ext_rgmii_pins>;
> > > +	phy-mode = "rgmii";
> > > +	phy-handle = <&ext_rgmii_phy>;
> > > +	phy-supply = <&reg_3v3>;
> > > +	allwinner,rx-delay-ps = <3100>;
> > > +	allwinner,tx-delay-ps = <700>;
> > > +	status = "okay";
> > > +};
> > > +
> > > +&ir {
> > > +	status = "okay";
> > > +};
> > > +
> > > +&mdio0 {
> > > +	ext_rgmii_phy: ethernet-phy at 1 {
> > > +		compatible = "ethernet-phy-ieee802.3-c22";
> > > +		reg = <1>;
> > > +		reset-gpios = <&pio 8 16 GPIO_ACTIVE_LOW>;	/* PI16 */
> > > +	};
> > > +};
> > > +
> > > +&mmc0 {
> > > +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;	/* PF6 */
> > > +	vmmc-supply = <&reg_dldo1>;
> > > +	bus-width = <4>;
> > > +	status = "okay";
> > > +};
> > > +
> > > +&mmc2 {
> > > +	vmmc-supply = <&reg_dldo1>;
> > > +	vqmmc-supply = <&reg_aldo1>;
> > > +	bus-width = <8>;
> > > +	non-removable;
> > > +	cap-mmc-hw-reset;
> > > +	mmc-ddr-1_8v;  
> > 
> > This one should be dropped.  
> 
> Can you please test this one? If it works, I'll merge this series.

Unfortunately I cannot test, because I don't have that board. The DT is
entirely based on the schematic. As stated in the cover letter, I was
hoping for people out there to test this.

To be honest, I would feel better if someome provides a Tested-by: tag
before we merge that. Devils is often in the details, even with
seemingly straight-forward DTs like this.

Cheers,
Andre
 
> Best regards,
> Jernej
>  
> > > +	mmc-hs200-1_8v;
> > > +	status = "okay";
> > > +};
> > > +
> > > +/* USB ports 1 and 3 connect to onboard devices that are high-speed only. */
> > > +
> > > +/* OHCI2 is on unpopulated pins */
> > > +
> > > +&pio {
> > > +	vcc-pc-supply = <&reg_aldo1>;
> > > +	vcc-pf-supply = <&reg_dldo1>;
> > > +	vcc-pg-supply = <&reg_dldo1>;
> > > +	vcc-ph-supply = <&reg_dldo1>;
> > > +	vcc-pi-supply = <&reg_dldo1>;
> > > +};
> > > +
> > > +&r_i2c {
> > > +	status = "okay";
> > > +
> > > +	axp313: pmic at 36 {
> > > +		compatible = "x-powers,axp313a";
> > > +		reg = <0x36>;
> > > +		#interrupt-cells = <1>;
> > > +		interrupt-controller;
> > > +		interrupt-parent = <&pio>;
> > > +
> > > +		vin1-supply = <&reg_vcc5v>;
> > > +		vin2-supply = <&reg_vcc5v>;
> > > +		vin3-supply = <&reg_vcc5v>;
> > > +
> > > +		regulators {
> > > +			reg_aldo1: aldo1 {
> > > +				regulator-always-on;
> > > +				regulator-min-microvolt = <1800000>;
> > > +				regulator-max-microvolt = <1800000>;
> > > +				regulator-name = "vcc-1v8-pll";
> > > +			};
> > > +
> > > +			reg_dldo1: dldo1 {
> > > +				regulator-always-on;
> > > +				regulator-min-microvolt = <3300000>;
> > > +				regulator-max-microvolt = <3300000>;
> > > +				regulator-name = "vcc-3v3-io";
> > > +			};
> > > +
> > > +			reg_dcdc1: dcdc1 {
> > > +				regulator-always-on;
> > > +				regulator-min-microvolt = <810000>;
> > > +				regulator-max-microvolt = <990000>;
> > > +				regulator-name = "vdd-gpu-sys";
> > > +			};
> > > +
> > > +			reg_dcdc2: dcdc2 {
> > > +				regulator-always-on;
> > > +				regulator-min-microvolt = <810000>;
> > > +				regulator-max-microvolt = <1100000>;
> > > +				regulator-name = "vdd-cpu";
> > > +			};
> > > +
> > > +			reg_dcdc3: dcdc3 {
> > > +				regulator-always-on;
> > > +				regulator-min-microvolt = <1100000>;
> > > +				regulator-max-microvolt = <1100000>;
> > > +				regulator-name = "vdd-dram";
> > > +			};
> > > +		};
> > > +	};
> > > +};
> > > +
> > > +&uart0 {
> > > +	pinctrl-names = "default";
> > > +	pinctrl-0 = <&uart0_ph_pins>;
> > > +	status = "okay";
> > > +};
> > > +
> > > +&usbotg {
> > > +	/*
> > > +	 * PHY0 pins are connected to a USB-C socket, but a role switch is not
> > > +	 * implemented: both CC pins are pulled to GND via a 5.1K resistor.
> > > +	 * The VBUS pins power the device, so a fixed peripheral mode
> > > +	 * is the best choice.
> > > +	 * The board can be powered via GPIOs, in this case port0 *can*
> > > +	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
> > > +	 * then provided by the GPIOs. Any user of this setup would
> > > +	 * need to adjust the DT accordingly: dr_mode set to "host",
> > > +	 * enabling OHCI0 and EHCI0.
> > > +	 */
> > > +	dr_mode = "peripheral";
> > > +	status = "okay";
> > > +};
> > > +
> > > +&usbphy {
> > > +	usb3_vbus-supply = <&reg_usb_vbus>;
> > > +	status = "okay";
> > > +};
> > >   
> > 
> > 
> > 
> > 
> >   
> 
> 
> 
> 
> 



From aford173 at gmail.com  Sun Feb 11 15:15:08 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 11 Feb 2024 17:15:08 -0600
Subject: [PATCH] arm64: dts: imx8mn: Slow default video_pll clock rate
Message-ID: <20240211231508.188567-1-aford173@gmail.com>

Since commit 8208181fe536 ("clk: imx: composite-8m:
Add imx8m_divider_determine_rate") the lcdif controller has
had the ability to set the disp_pixel_clk rate which propagates
up the tree and sets the video_pll rate automatically.

By setting this value low, it will force the recalculation of
video_pll to the lowest rate needed by lcdif instead of
dividing a larger clock down to the desired clock speed. This
has the  advantage of being able to lower the video_pll rate
from 594MHz to 148.5MHz when operating at 1080p. It can go even
lower when operating at lower resolutions and refresh rates.

Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index 136e75c51251..932c8b05c75f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -1168,7 +1168,7 @@ disp_blk_ctrl: blk-ctrl at 32e28000 {
 							 <&clk IMX8MN_SYS_PLL1_800M>;
 				assigned-clock-rates = <266000000>,
 						       <24000000>,
-						       <594000000>,
+						       <24000000>,
 						       <500000000>,
 						       <200000000>;
 				#power-domain-cells = <1>;
-- 
2.43.0



From aford173 at gmail.com  Sun Feb 11 15:18:02 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 11 Feb 2024 17:18:02 -0600
Subject: [PATCH] arm64: dts: imx8mn-beacon: Remove unnecessary clock configuration
Message-ID: <20240211231802.188843-1-aford173@gmail.com>

Since commit 8208181fe536 ("clk: imx: composite-8m:
Add imx8m_divider_determine_rate") the lcdif controller has
had the ability to set the disp_pixel_clk rate which propagates
up the tree and sets the video_pll rate automatically.

As such, there is no need to define it in the board file.

Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
index 35b8d2060cd9..bbd80896db96 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
@@ -99,8 +99,6 @@ adv7535_out: endpoint {
 };
 
 &lcdif {
-	assigned-clocks = <&clk IMX8MN_VIDEO_PLL1>;
-	assigned-clock-rates = <594000000>;
 	status = "okay";
 };
 
-- 
2.43.0



From andre.przywara at arm.com  Sun Feb 11 15:39:26 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun, 11 Feb 2024 23:39:26 +0000
Subject: [PATCH v3 2/2] arm64: dts: allwinner: h616: Add Sipeed Longan
 SoM 3H and Pi 3H board support
In-Reply-To: <20240211081739.395-3-jszhang@kernel.org>
References: <20240211081739.395-1-jszhang@kernel.org>
	<20240211081739.395-3-jszhang@kernel.org>
Message-ID: <20240211233926.70b327b1@minigeek.lan>

On Sun, 11 Feb 2024 16:17:39 +0800
Jisheng Zhang <jszhang at kernel.org> wrote:

Hi Jisheng,

thanks for the changes, and for spotting the 5V/3.3V issue yourself,
which I missed. This looks good to me now.

> The Sipeed Longan SoM 3H is a system on module based on the Allwinner
> H618 SoC. The SoM features:
> 
> - Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
> - 2/4 GiB LPDDR4 DRAM SoMs
> - AXP313a PMIC
> - eMMC
> 
> The Sipeed Longan PI 3H is a development board based on the above SoM.
> The board features:
> - Longan SoM 3H
> - Raspberry-Pi-1 compatible GPIO header
> - 2 USB 2.0 host port
> - 1 USB 2.0 type C port (power supply + OTG)
> - MicroSD slot
> - 1Gbps Ethernet port (via RTL8211 PHY)
> - HDMI port
> - WiFi/BT chip
> 
> Add the devicetree file describing the currently supported features,
> namely PMIC, LEDs, UART, SD card, eMMC, USB and Ethernet.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
>  .../sun50i-h618-longan-module-3h.dtsi         |  75 +++++++++
>  .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 144 ++++++++++++++++++
>  3 files changed, 220 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> 
> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> index 91d505b385de..4b9173a16efe 100644
> --- a/arch/arm64/boot/dts/allwinner/Makefile
> +++ b/arch/arm64/boot/dts/allwinner/Makefile
> @@ -42,5 +42,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> new file mode 100644
> index 000000000000..8c1263a3939e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
> @@ -0,0 +1,75 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
> + */
> +
> +#include "sun50i-h616.dtsi"
> +
> +&mmc2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc2_pins>;
> +	vmmc-supply = <&reg_dldo1>;
> +	vqmmc-supply = <&reg_aldo1>;
> +	bus-width = <8>;
> +	non-removable;
> +	cap-mmc-hw-reset;
> +	mmc-ddr-1_8v;
> +	mmc-hs200-1_8v;
> +	status = "okay";
> +};
> +
> +&r_i2c {
> +	status = "okay";
> +
> +	axp313: pmic at 36 {
> +		compatible = "x-powers,axp313a";
> +		reg = <0x36>;
> +		#interrupt-cells = <1>;
> +		interrupt-controller;
> +
> +		regulators {
> +			reg_aldo1: aldo1 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-name = "vcc-1v8-pll";
> +			};
> +
> +			reg_dldo1: dldo1 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-name = "vcc-3v3-io";
> +			};
> +
> +			reg_dcdc1: dcdc1 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <810000>;
> +				regulator-max-microvolt = <990000>;
> +				regulator-name = "vdd-gpu-sys";
> +			};
> +
> +			reg_dcdc2: dcdc2 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <810000>;
> +				regulator-max-microvolt = <1100000>;
> +				regulator-name = "vdd-cpu";
> +			};
> +
> +			reg_dcdc3: dcdc3 {
> +				regulator-always-on;
> +				regulator-min-microvolt = <1100000>;
> +				regulator-max-microvolt = <1100000>;
> +				regulator-name = "vdd-dram";
> +			};
> +		};
> +	};
> +};
> +
> +&pio {
> +	vcc-pc-supply = <&reg_dldo1>;
> +	vcc-pf-supply = <&reg_dldo1>;
> +	vcc-pg-supply = <&reg_aldo1>;
> +	vcc-ph-supply = <&reg_dldo1>;
> +	vcc-pi-supply = <&reg_dldo1>;
> +};
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> new file mode 100644
> index 000000000000..18b29c6b867f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> @@ -0,0 +1,144 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (C) Jisheng Zhang <jszhang at kernel.org>
> + */
> +
> +/dts-v1/;
> +
> +#include "sun50i-h618-longan-module-3h.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/leds/common.h>
> +
> +/ {
> +	model = "Sipeed Longan Pi 3H";
> +	compatible = "sipeed,longan-pi-3h", "sipeed,longan-module-3h", "allwinner,sun50i-h618";
> +
> +	aliases {
> +		ethernet0 = &emac0;
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		led-0 {
> +			color = <LED_COLOR_ID_ORANGE>;
> +			function = LED_FUNCTION_INDICATOR;
> +			function-enumerator = <0>;
> +			gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */
> +		};
> +
> +		led-1 {
> +			color = <LED_COLOR_ID_ORANGE>;
> +			function = LED_FUNCTION_INDICATOR;
> +			function-enumerator = <1>;
> +			gpios = <&pio 6 4 GPIO_ACTIVE_LOW>; /* PG4 */
> +		};
> +	};
> +
> +	reg_vcc5v: regulator-vcc5v {
> +		/* board wide 5V supply directly from the USB-C socket */
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc-5v";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-always-on;
> +	};
> +
> +	reg_vcc3v3: regulator-vcc3v3 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc-3v3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		regulator-always-on;
> +		vin-supply = <&reg_vcc5v>;
> +	};
> +};
> +
> +&axp313 {
> +	vin1-supply = <&reg_vcc5v>;
> +	vin2-supply = <&reg_vcc5v>;
> +	vin3-supply = <&reg_vcc5v>;
> +};
> +
> +&ehci1 {
> +	status = "okay";
> +};
> +
> +&ohci1 {
> +	status = "okay";
> +};
> +
> +&ehci2 {
> +	status = "okay";
> +};
> +
> +&ohci2 {
> +	status = "okay";
> +};
> +
> +/* WiFi & BT combo module is connected to this Host */
> +&ehci3 {
> +	status = "okay";
> +};
> +
> +&ohci3 {
> +	status = "okay";
> +};
> +
> +&emac0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&ext_rgmii_pins>;
> +	phy-mode = "rgmii";
> +	phy-handle = <&ext_rgmii_phy>;
> +	allwinner,rx-delay-ps = <3100>;
> +	allwinner,tx-delay-ps = <700>;
> +	phy-supply = <&reg_vcc3v3>;
> +	status = "okay";
> +};
> +
> +&mdio0 {
> +	ext_rgmii_phy: ethernet-phy at 1 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <1>;
> +	};
> +};
> +
> +&mmc0 {
> +	bus-width = <4>;
> +	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;	/* PF6 */
> +	vmmc-supply = <&reg_vcc3v3>;
> +	status = "okay";
> +};
> +
> +&uart0 {
> +	status = "okay";
> +};
> +
> +&usbotg {
> +	/*
> +	 * PHY0 pins are connected to a USB-C socket, but a role switch
> +	 * is not implemented: both CC pins are pulled to GND.
> +	 * The VBUS pins power the device, so a fixed peripheral mode
> +	 * is the best choice.
> +	 * The board can be powered via GPIOs, in this case port0 *can*
> +	 * act as a host (with a cable/adapter ignoring CC), as VBUS is
> +	 * then provided by the GPIOs. Any user of this setup would
> +	 * need to adjust the DT accordingly: dr_mode set to "host",
> +	 * enabling OHCI0 and EHCI0.
> +	 */
> +	dr_mode = "peripheral";
> +	status = "okay";
> +};
> +
> +&usbphy {
> +	usb1_vbus-supply = <&reg_vcc5v>;
> +	usb2_vbus-supply = <&reg_vcc5v>;
> +	status = "okay";
> +};



From sebastian.reichel at collabora.com  Sun Feb 11 15:52:10 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Mon, 12 Feb 2024 00:52:10 +0100
Subject: [PATCH v3 18/19] power: reset: syscon-poweroff: Move device data
 into a struct
In-Reply-To: <20240208170410.67975-19-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
 <20240208170410.67975-19-afd@ti.com>
Message-ID: <glaiaikudbtuahnwnqoduretcnmrpb7lg2gerlnntcltrjfcko@4vgjb4v66rad>

Hi Andrew,

On Thu, Feb 08, 2024 at 11:04:09AM -0600, Andrew Davis wrote:
> Currently all these device data elements are top level global variables.
> Move these into a struct. This will be used in the next patch when
> the global variable usage is removed. Doing this in two steps makes
> the patches easier to read.
> 
> Signed-off-by: Andrew Davis <afd at ti.com>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/power/reset/syscon-poweroff.c | 36 +++++++++++++++------------
>  1 file changed, 20 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
> index 1b2ce7734260c..4899a019256e8 100644
> --- a/drivers/power/reset/syscon-poweroff.c
> +++ b/drivers/power/reset/syscon-poweroff.c
> @@ -15,15 +15,19 @@
>  #include <linux/pm.h>
>  #include <linux/regmap.h>
>  
> -static struct regmap *map;
> -static u32 offset;
> -static u32 value;
> -static u32 mask;
> +struct syscon_poweroff_data {
> +	struct regmap *map;
> +	u32 offset;
> +	u32 value;
> +	u32 mask;
> +};
> +
> +static struct syscon_poweroff_data *data;

This patch is broken without the follow-up patch, since data is
never allocated. You need to move the memory allocation from the
next patch to this one.

Greetings,

-- Sebastian
-------------- 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/20240212/d489a63c/attachment.sig>

From sebastian.reichel at collabora.com  Sun Feb 11 15:54:27 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Mon, 12 Feb 2024 00:54:27 +0100
Subject: [PATCH v3 00/19] Remove pm_power_off use in drivers/power/reset
In-Reply-To: <20240208170410.67975-1-afd@ti.com>
References: <20240208170410.67975-1-afd@ti.com>
Message-ID: <iinovq4p3dn5pic6ipptqzi3minqz5dznfdzhzl2onttxb325k@l7bhoiibsxkz>

Hi,

On Thu, Feb 08, 2024 at 11:03:51AM -0600, Andrew Davis wrote:
> Use of pm_power_off is considered legacy and should be replaced
> with register_sys_off*(). Same for register_restart_handler(). Do
> this for the drivers/power/reset subsystem for all trivial cases.

Apart from the issue in patch 18 the series LGTM.

-- Sebastian
-------------- 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/20240212/fd97225f/attachment-0001.sig>

From andre.przywara at arm.com  Sun Feb 11 16:07:27 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 12 Feb 2024 00:07:27 +0000
Subject: [PATCH] arm64: dts: allwinner: a64: Add thermal trip points for
 GPU
In-Reply-To: <ZcjYk8MD4jotKNcq@skv.local>
References: <20240211105326.506049-1-andrej.skvortzov@gmail.com>
	<20240211125209.15d58462@minigeek.lan>
	<ZcjYk8MD4jotKNcq@skv.local>
Message-ID: <20240212000727.4690bdb6@minigeek.lan>

On Sun, 11 Feb 2024 17:24:19 +0300
Andrey Skvortsov <andrej.skvortzov at gmail.com> wrote:

Hi Andrey,

> Hi Andre,
> 
> On 24-02-11 12:52, Andre Przywara wrote:
> > On Sun, 11 Feb 2024 13:53:26 +0300
> > Andrey Skvortsov <andrej.skvortzov at gmail.com> wrote:
> > 
> > Hi Andrey,
> >   
> > > From: Alexey Klimov <alexey.klimov at linaro.org>
> > > 
> > > Without trip points for GPU, the following errors are printed in the
> > > dmesg log and the sun8i-thermal driver fails to load:  
> > 
> > So how does that post differ from Alexey one's a few weeks back:
> > https://lore.kernel.org/linux-arm-kernel/20240101000008.65747-1-alexey.klimov at linaro.org/
> > It seems like the same patch?  
> 
> Yes, it's the same patch. I've added only information about failed
> dtbs_check errors in already supported boards to commit message.
> I've found this patch from June 2023 without any feedback. [1] Since I've
> worked on dts changes for PinePhone A64, I've decided to resend
> it. Sorry, I wasn't aware that Alexey resent it in the mean time.

No worries, that's fine, thanks for the explanation.

> It's better to continue discussion in original Alexey's patch.

Will Alexey have time to reply and resend? If not, or if you are not
sure (it's been a while), it's fine to take over this series, and send a
v2, by yourself.

If you can just explicitly state that the GPU trip point values are
copied from the CPU ones (because they share a die), I am happy as far
as my comment is concerned. This is arguably somewhat mentioned in the
commit message already, but I missed it on the first read, so would like
to see this more prominently stated.

As mentioned before, and also stated by Jernej, consider this patch
purely device-specific, not related to any Linux behaviour, and give
rationale only based on the binding, which requires trip points.
Something simple as "The DT binding requires trip points, and
dt-validate complains about them missing for any A64 boards." should
suffice.

Thanks,
Andre

> > And Jernej and I had some comments (no mentioning of "Linux" in commit
> > message, add cooling maps, source of trip temperature values), can you
> > please try to address them?
> > 
> >   
> > > thermal_sys: Failed to find 'trips' node
> > > thermal_sys: Failed to find trip points for thermal-sensor id=1
> > > sun8i-thermal: probe of 1c25000.thermal-sensor failed with error -22  
> > 
> > I think it's pretty obvious that the trip points are missing when they
> > shouldn't, so this does not need too much explanation or rationale in
> > the commit message, so you can cut this short.
> >   
> > > When thermal zones are defined, trip points definitions are mandatory.
> > > Trip values for the GPU are assumed to be the same values as the CPU
> > > ones. The available specs do not provide any hints about thermal regimes
> > > for the GPU and it seems GPU is implemented on the same die as the CPU.
> > > 
> > > 'make dtbs_check' complains about problem in dts for 18 A64-based boards
> > > supported by the kernel:
> > > 
> > > sun50i-a64-pine64.dtb: thermal-zones: gpu0-thermal: 'trips' is a required property
> > > 	from schema $id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#
> > > sun50i-a64-pine64.dtb: thermal-zones: gpu1-thermal: 'trips' is a required property
> > > 	from schema $id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#
> > > 
> > > Tested on Pine a64+ and PinePhone 1.2.
> > > 
> > > Cc: Samuel Holland <samuel at sholland.org>
> > > Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> > > Cc: Chen-Yu Tsai <wens at csie.org>
> > > Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> > > Cc: devicetree at vger.kernel.org
> > > Signed-off-by: Alexey Klimov <alexey.klimov at linaro.org>
> > > Tested-by: Andrey Skvortsov <andrej.skvortzov at gmail.com>  
> > 
> > You would need your Signed-off-by: here, since you send this, even when
> > on Alexey's behalf.
> > 
> > Cheers,
> > Andre
> >  
> 
> 1.  https://lkml.org/lkml/2023/6/4/416
> 



From Dharma.B at microchip.com  Sun Feb 11 19:18:18 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Mon, 12 Feb 2024 03:18:18 +0000
Subject: [PATCH v3 1/4] dt-bindings: display: bridge: add sam9x75-lvds
 compatible
In-Reply-To: <45aa6b3e-5e76-457e-b091-084adf324385@linaro.org>
References: <20240207102802.200220-1-dharma.b@microchip.com>
 <20240207102802.200220-2-dharma.b@microchip.com>
 <2219df60-7235-4c37-b79c-25e7225cb7a9@kernel.org>
 <b314e446-e79c-4fa0-9b86-c58fa96133bc@microchip.com>
 <c82a3843-1b58-46ea-994a-8350544aa30d@microchip.com>
 <e2e1490b-0e07-43ae-ab67-2efd6f21987e@linaro.org>
 <45aa6b3e-5e76-457e-b091-084adf324385@linaro.org>
Message-ID: <00e7cfa0-ce94-4254-a349-580f9f9c3681@microchip.com>

Hi Krzysztof,

On 09/02/24 9:40 pm, Krzysztof Kozlowski wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On 09/02/2024 17:05, Krzysztof Kozlowski wrote:
>> On 09/02/2024 16:02, Dharma.B at microchip.com wrote:
>>> On 09/02/24 7:50 pm, Dharma B wrote:
>>>> On 08/02/24 2:31 pm, Krzysztof Kozlowski wrote:
>>>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know
>>>>> the content is safe
>>>>>
>>>>> On 07/02/2024 11:27, Dharma Balasubiramani wrote:
>>>>>> Add the 'sam9x75-lvds' compatible binding, which describes the Low
>>>>>> Voltage
>>>>>> Differential Signaling (LVDS) Controller found on some Microchip's
>>>>>> sam9x7
>>>>>> series System-on-Chip (SoC) devices. This binding will be used to define
>>>>>> the properties and configuration for the LVDS Controller in DT.
>>>>>>
>>>>>> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
>>>>>
>>>>> Not tested...
>>>>>
>>>>> Please use scripts/get_maintainers.pl to get a list of necessary people
>>>>> and lists to CC. It might happen, that command when run on an older
>>>>> kernel, gives you outdated entries. Therefore please be sure you base
>>>>> your patches on recent Linux kernel.
>>>>>
>>>>> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
>>>>> people, so fix your workflow. Tools might also fail if you work on some
>>>>> ancient tree (don't, instead use mainline), work on fork of kernel
>>>>> (don't, instead use mainline) or you ignore some maintainers (really
>>>>> don't). Just use b4 and everything should be fine, although remember
>>>>> about `b4 prep --auto-to-cc` if you added new patches to the patchset.
>>>>>
>>>>> You missed at least devicetree list (maybe more), so this won't be
>>>>> tested by automated tooling. Performing review on untested code might be
>>>>> a waste of time.
>>>>
>>>> Apologies for the oversight, somehow it got missed.
>>>
>>> The get_maintainer.pl seems to be inconsistent with the results.
>>>
>>> linux$ ./scripts/get_maintainer.pl *patch | wc -l
>>> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't
>>> appear to be a patch.  Add -f to options?
>>> 31
>>> linux$ ./scripts/get_maintainer.pl *patch | wc -l
>>> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't
>>> appear to be a patch.  Add -f to options?
>>> 29
>>> linux$ ./scripts/get_maintainer.pl *patch | wc -l
>>> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't
>>> appear to be a patch.  Add -f to options?
>>> 30
>>> linux$ ./scripts/get_maintainer.pl *patch | wc -l
>>> ./scripts/get_maintainer.pl: file '0000-cover-letter.patch' doesn't
>>> appear to be a patch.  Add -f to options?
>>> 30
>>
>> Why would you add 30 addresses, including many unrelated people, to the
>> cc-list? You must add only maintainers (so also reviewers) and mailing
>> lists.
> 
> Really, why do you Cc MM folks on this patch? Just read what
> get_maintainer.pl tells you, e.g. when it says that someone made one
> commit to maintainers file, shall this person be Cc-ed? No, it should be
> obvious...


Thank you for bringing this to my attention. I sincerely apologize for 
any oversight. Moving forward, I will ensure to utilize 'b4 prep 
--auto-to-cc' to obtain the accurate To and CC list.

> 
> Best regards,
> Krzysztof
> 

-- 
With Best Regards,
Dharma B.


From vigneshr at ti.com  Sun Feb 11 20:10:17 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Mon, 12 Feb 2024 09:40:17 +0530
Subject: [PATCH v5 0/5] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
In-Reply-To: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
Message-ID: <359993c5-3387-443c-8cef-30ee7ad1f521@ti.com>

Hi Josua,

On 11/02/24 20:37, Josua Mayer wrote:
> This series adds DT bindings and dts descriptions for SolidRun AM642
> based SoM and Hummingboard EVB.
> 
> Additionally a commit from downstream vendor kernel are included,
> enhancing support for pru based ethernet.
> I wasn't sure how to properly annotate it in commit description /
> signed-off area ...:
> 
> 1. add description for "Industrial Ethernet Peripherals" (IEP) to am64
>    https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/commit/arch/arm64/boot/dts/ti/k3-am64-main.dtsi?h=ti-linux-6.1.y-cicd&id=5afb73d82a014b59462162d960b350b8c58e5ae6
>    IEP is already supported in-tree by a driver, and used in
>    k3-am65-main.dtsi.
> 
> Unfortunately dtbs_check reported many problems, I put some remarks:
> 
> - 'mux-controller' does not match any of the regexes
>   The expectation seems to be that a mux-controller at minimum has an
>   address, something to put behind an @. However this is a gpio mux, not
>   sure how to name it better.
> 

I don't see this warning locally. Are you using updated dt-schema? reg
is not necessary gpio-mux as per gpio-mux.yaml

> - unevaluated properties: interrupts, interrupt-parent
>   sensors and flash yaml are missing interrupt descriptions, but these
>   parts definitely have an interrupt signal in this solidrun board.
> 

Please add them to appropriate schema as necessary

> - wrong names for pinctrl nodes
>   Other TI DTSs consistently end with *-pins-default. Should a different
>   naming convention be used?
> 

No, pinctrl nodes need to end in -pins. All TI boards have been updated
to new schema [0] and sysconfig tool on dev.ti.com/sysconfig generates
appropriately. Please fix


> - cdns,phy-type required property
>   inherited from k3-am64-main.dtsi
>   there is a PHY_NONE value in dt-bindings/phy/phy.h,
>   but not allowed in phy-cadence-torrent.yaml
>

Sorry, I didnt get what's the issue wrt cdns,phy-type ?


Note, I really don't want to accept patches that add new dtbs_check
issues especially for nodes that already have YAML bindings. Please
update the .yaml files as necessary.

[0]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a49568115143435390f20965902809471b6f830c


-- 
Regards
Vignesh


From linux at roeck-us.net  Sun Feb 11 20:30:21 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Sun, 11 Feb 2024 20:30:21 -0800
Subject: [PATCH net v3] net: stmmac: protect updates of 64-bit statistics
 counters
In-Reply-To: <20240203190927.19669-1-petr@tesarici.cz>
References: <20240203190927.19669-1-petr@tesarici.cz>
Message-ID: <ea1567d9-ce66-45e6-8168-ac40a47d1821@roeck-us.net>

Hi,

On Sat, Feb 03, 2024 at 08:09:27PM +0100, Petr Tesarik wrote:
> As explained by a comment in <linux/u64_stats_sync.h>, write side of struct
> u64_stats_sync must ensure mutual exclusion, or one seqcount update could
> be lost on 32-bit platforms, thus blocking readers forever. Such lockups
> have been observed in real world after stmmac_xmit() on one CPU raced with
> stmmac_napi_poll_tx() on another CPU.
> 
> To fix the issue without introducing a new lock, split the statics into
> three parts:
> 
> 1. fields updated only under the tx queue lock,
> 2. fields updated only during NAPI poll,
> 3. fields updated only from interrupt context,
> 
> Updates to fields in the first two groups are already serialized through
> other locks. It is sufficient to split the existing struct u64_stats_sync
> so that each group has its own.
> 
> Note that tx_set_ic_bit is updated from both contexts. Split this counter
> so that each context gets its own, and calculate their sum to get the total
> value in stmmac_get_ethtool_stats().
> 
> For the third group, multiple interrupts may be processed by different CPUs
> at the same time, but interrupts on the same CPU will not nest. Move fields
> from this group to a newly created per-cpu struct stmmac_pcpu_stats.
> 
> Fixes: 133466c3bbe1 ("net: stmmac: use per-queue 64 bit statistics where necessary")
> Link: https://lore.kernel.org/netdev/Za173PhviYg-1qIn at torres.zugschlus.de/t/
> Cc: stable at vger.kernel.org
> Signed-off-by: Petr Tesarik <petr at tesarici.cz>

This patch results in a lockdep splat. Backtrace and bisect results attached.

Guenter

---
[   33.736728] ================================
[   33.736805] WARNING: inconsistent lock state
[   33.736953] 6.8.0-rc4 #1 Tainted: G                 N
[   33.737080] --------------------------------
[   33.737155] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
[   33.737309] kworker/0:2/39 [HC1[1]:SC0[2]:HE0:SE0] takes:
[   33.737459] ef792074 (&syncp->seq#2){?...}-{0:0}, at: sun8i_dwmac_dma_interrupt+0x9c/0x28c
[   33.738206] {HARDIRQ-ON-W} state was registered at:
[   33.738318]   lock_acquire+0x11c/0x368
[   33.738431]   __u64_stats_update_begin+0x104/0x1ac
[   33.738525]   stmmac_xmit+0x4d0/0xc58
[   33.738605]   dev_hard_start_xmit+0xc4/0x2a0
[   33.738689]   sch_direct_xmit+0xf8/0x30c
[   33.738763]   __dev_queue_xmit+0x400/0xcc4
[   33.738831]   ip6_finish_output2+0x254/0xafc
[   33.738903]   mld_sendpack+0x260/0x5b0
[   33.738969]   mld_ifc_work+0x274/0x588
[   33.739032]   process_one_work+0x230/0x604
[   33.739101]   worker_thread+0x1dc/0x494
[   33.739165]   kthread+0x100/0x120
[   33.739225]   ret_from_fork+0x14/0x28
[   33.739302] irq event stamp: 3553
[   33.739371] hardirqs last  enabled at (3552): [<c03e884c>] __call_rcu_common.constprop.0+0x1a4/0x6b4
[   33.739515] hardirqs last disabled at (3553): [<c0300bd4>] __irq_svc+0x54/0xb8
[   33.739638] softirqs last  enabled at (3542): [<c1254a60>] neigh_resolve_output+0x1fc/0x254
[   33.739795] softirqs last disabled at (3546): [<c1243798>] __dev_queue_xmit+0x48/0xcc4
[   33.739919]
[   33.739919] other info that might help us debug this:
[   33.740021]  Possible unsafe locking scenario:
[   33.740021]
[   33.740111]        CPU0
[   33.740158]        ----
[   33.740204]   lock(&syncp->seq#2);
[   33.740314]   <Interrupt>
[   33.740363]     lock(&syncp->seq#2);
[   33.740511]
[   33.740511]  *** DEADLOCK ***
[   33.740511]
[   33.740665] 8 locks held by kworker/0:2/39:
[   33.740761]  #0: c4bfb2a8 ((wq_completion)mld){+.+.}-{0:0}, at: process_one_work+0x168/0x604
[   33.741025]  #1: f0909f20 ((work_completion)(&(&idev->mc_ifc_work)->work)){+.+.}-{0:0}, at: process_one_work+0x168/0x604
[   33.741230]  #2: c328baac (&idev->mc_lock){+.+.}-{3:3}, at: mld_ifc_work+0x24/0x588
[   33.741387]  #3: c2191488 (rcu_read_lock){....}-{1:2}, at: mld_sendpack+0x0/0x5b0
[   33.741553]  #4: c2191488 (rcu_read_lock){....}-{1:2}, at: ip6_finish_output2+0x174/0xafc
[   33.741716]  #5: c219149c (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x48/0xcc4
[   33.741877]  #6: c4d3a974 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: __dev_queue_xmit+0x334/0xcc4
[   33.742070]  #7: c49e5050 (_xmit_ETHER#2){+...}-{2:2}, at: sch_direct_xmit+0x158/0x30c
[   33.742250]
[   33.742250] stack backtrace:
[   33.742426] CPU: 0 PID: 39 Comm: kworker/0:2 Tainted: G                 N 6.8.0-rc4 #1
[   33.742578] Hardware name: Allwinner sun8i Family
[   33.742776] Workqueue: mld mld_ifc_work
[   33.742998]  unwind_backtrace from show_stack+0x10/0x14
[   33.743119]  show_stack from dump_stack_lvl+0x68/0x90
[   33.743232]  dump_stack_lvl from mark_lock.part.0+0xbd8/0x12d8
[   33.743345]  mark_lock.part.0 from __lock_acquire+0xad4/0x224c
[   33.743458]  __lock_acquire from lock_acquire+0x11c/0x368
[   33.743564]  lock_acquire from __u64_stats_update_begin+0x104/0x1ac
[   33.743683]  __u64_stats_update_begin from sun8i_dwmac_dma_interrupt+0x9c/0x28c
[   33.743805]  sun8i_dwmac_dma_interrupt from stmmac_napi_check+0x40/0x1c8
[   33.743917]  stmmac_napi_check from stmmac_interrupt+0xa4/0x154
[   33.744020]  stmmac_interrupt from __handle_irq_event_percpu+0xcc/0x2ec
[   33.744134]  __handle_irq_event_percpu from handle_irq_event+0x38/0x80
[   33.744243]  handle_irq_event from handle_fasteoi_irq+0x9c/0x1c4
[   33.744346]  handle_fasteoi_irq from generic_handle_domain_irq+0x28/0x38
[   33.744459]  generic_handle_domain_irq from gic_handle_irq+0x98/0xcc
[   33.744567]  gic_handle_irq from generic_handle_arch_irq+0x34/0x44
[   33.744673]  generic_handle_arch_irq from call_with_stack+0x18/0x20
[   33.744831]  call_with_stack from __irq_svc+0x9c/0xb8
[   33.745018] Exception stack(0xf0909c00 to 0xf0909c48)
[   33.745221] 9c00: f0ab0000 c49e506c 0000005a 00000000 c0000006 f0ab0014 0000005a c0f5da68
[   33.745387] 9c20: c35bd810 c4b50000 c4b50000 c365d300 00000000 f0909c50 c0f70a70 c0f70a74
[   33.745574] 9c40: 60000013 ffffffff
[   33.745668]  __irq_svc from sun8i_dwmac_enable_dma_transmission+0x20/0x24
[   33.745809]  sun8i_dwmac_enable_dma_transmission from stmmac_xmit+0x790/0xc58
[   33.745975]  stmmac_xmit from dev_hard_start_xmit+0xc4/0x2a0
[   33.746100]  dev_hard_start_xmit from sch_direct_xmit+0xf8/0x30c
[   33.746220]  sch_direct_xmit from __dev_queue_xmit+0x400/0xcc4
[   33.746350]  __dev_queue_xmit from ip6_finish_output2+0x254/0xafc
[   33.746462]  ip6_finish_output2 from mld_sendpack+0x260/0x5b0
[   33.746568]  mld_sendpack from mld_ifc_work+0x274/0x588
[   33.746670]  mld_ifc_work from process_one_work+0x230/0x604
[   33.746793]  process_one_work from worker_thread+0x1dc/0x494
[   33.746906]  worker_thread from kthread+0x100/0x120
[   33.746994]  kthread from ret_from_fork+0x14/0x28
[   33.747076] Exception stack(0xf0909fb0 to 0xf0909ff8)
[   33.747165] 9fa0:                                     00000000 00000000 00000000 00000000
[   33.747303] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   33.747433] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000

---
# bad: [841c35169323cd833294798e58b9bf63fa4fa1de] Linux 6.8-rc4
# good: [54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478] Linux 6.8-rc3
git bisect start 'HEAD' 'v6.8-rc3'
# bad: [c76b766ec50d3d43e2dacea53a733b285f4b730d] Merge tag 'drm-fixes-2024-02-09' of git://anongit.freedesktop.org/drm/drm
git bisect bad c76b766ec50d3d43e2dacea53a733b285f4b730d
# bad: [63e4b9d693e0f8c28359c7ea81e1ee510864c37b] Merge tag 'nf-24-02-08' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
git bisect bad 63e4b9d693e0f8c28359c7ea81e1ee510864c37b
# bad: [75428f537d7cae33c7e4dd726144074f78622c09] net: intel: fix old compiler regressions
git bisect bad 75428f537d7cae33c7e4dd726144074f78622c09
# good: [1a1c13303ff6d64e6f718dc8aa614e580ca8d9b4] nfp: flower: prevent re-adding mac index for bonded port
git bisect good 1a1c13303ff6d64e6f718dc8aa614e580ca8d9b4
# good: [3871aa01e1a779d866fa9dfdd5a836f342f4eb87] tipc: Check the bearer type before calling tipc_udp_nl_bearer_add()
git bisect good 3871aa01e1a779d866fa9dfdd5a836f342f4eb87
# good: [58086721b7781c3e35b19c9b78c8f5a791070ba3] devlink: avoid potential loop in devlink_rel_nested_in_notify_work()
git bisect good 58086721b7781c3e35b19c9b78c8f5a791070ba3
# bad: [38cc3c6dcc09dc3a1800b5ec22aef643ca11eab8] net: stmmac: protect updates of 64-bit statistics counters
git bisect bad 38cc3c6dcc09dc3a1800b5ec22aef643ca11eab8
# good: [cb88cb53badb8aeb3955ad6ce80b07b598e310b8] ppp_async: limit MRU to 64K
git bisect good cb88cb53badb8aeb3955ad6ce80b07b598e310b8
# first bad commit: [38cc3c6dcc09dc3a1800b5ec22aef643ca11eab8] net: stmmac: protect updates of 64-bit statistics counters


From rdunlap at infradead.org  Sun Feb 11 20:30:50 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Sun, 11 Feb 2024 20:30:50 -0800
Subject: [PATCH v2 RESEND] soc: fsl: fix kernel-doc warnings and typos
Message-ID: <20240212043050.28964-1-rdunlap@infradead.org>

Correct spelling of "list".

Fix a kernel-doc warning by describing the nested structure completely:

include/soc/fsl/dpaa2-fd.h:52: warning: Function parameter or member 'simple' not described in 'dpaa2_fd'

Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
Cc: Li Yang <leoyang.li at nxp.com>
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: Frank Li <Frank.Li at nxp.com>
Cc: Guanhua Gao <guanhua.gao at nxp.com>
Cc: Roy Pledge <Roy.Pledge at nxp.com>
---
v2:  update Cc: list, rebase

 include/soc/fsl/dpaa2-fd.h |   19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff -- a/include/soc/fsl/dpaa2-fd.h b/include/soc/fsl/dpaa2-fd.h
--- a/include/soc/fsl/dpaa2-fd.h
+++ b/include/soc/fsl/dpaa2-fd.h
@@ -25,14 +25,15 @@
 
 /**
  * struct dpaa2_fd - Struct describing FDs
- * @words:         for easier/faster copying the whole FD structure
- * @addr:          address in the FD
- * @len:           length in the FD
- * @bpid:          buffer pool ID
- * @format_offset: format, offset, and short-length fields
- * @frc:           frame context
- * @ctrl:          control bits...including dd, sc, va, err, etc
- * @flc:           flow context address
+ * @words:                for easier/faster copying the whole FD structure
+ * @simple:               struct for the FD fields
+ * @simple.addr:          address in the FD
+ * @simple.len:           length in the FD
+ * @simple.bpid:          buffer pool ID
+ * @simple.format_offset: format, offset, and short-length fields
+ * @simple.frc:           frame context
+ * @simple.ctrl:          control bits...including dd, sc, va, err, etc
+ * @simple.flc:           flow context address
  *
  * This structure represents the basic Frame Descriptor used in the system.
  */
@@ -497,7 +498,7 @@ static inline void dpaa2_fl_set_addr(str
  * dpaa2_fl_get_frc() - Get the frame context in the FLE
  * @fle: the given frame list entry
  *
- * Return the frame context field in the frame lsit entry.
+ * Return the frame context field in the frame list entry.
  */
 static inline u32 dpaa2_fl_get_frc(const struct dpaa2_fl_entry *fle)
 {


From rdunlap at infradead.org  Sun Feb 11 20:31:00 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Sun, 11 Feb 2024 20:31:00 -0800
Subject: [PATCH v2 RESEND] soc: fsl: dpio: fix kernel-doc typos
Message-ID: <20240212043100.28984-1-rdunlap@infradead.org>

Correct spelling of 2 words.

Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
Cc: Li Yang <leoyang.li at nxp.com>
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: Frank Li <Frank.Li at nxp.com>
Cc: Guanhua Gao <guanhua.gao at nxp.com>
Cc: Roy Pledge <Roy.Pledge at nxp.com>
---
v2:  update Cc: list, rebase

 include/soc/fsl/dpaa2-io.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff -- a/include/soc/fsl/dpaa2-io.h b/include/soc/fsl/dpaa2-io.h
--- a/include/soc/fsl/dpaa2-io.h
+++ b/include/soc/fsl/dpaa2-io.h
@@ -22,7 +22,7 @@ struct device;
  * DOC: DPIO Service
  *
  * The DPIO service provides APIs for users to interact with the datapath
- * by enqueueing and dequeing frame descriptors.
+ * by enqueueing and dequeueing frame descriptors.
  *
  * The following set of APIs can be used to enqueue and dequeue frames
  * as well as producing notification callbacks when data is available
@@ -33,7 +33,7 @@ struct device;
 
 /**
  * struct dpaa2_io_desc - The DPIO descriptor
- * @receives_notifications: Use notificaton mode. Non-zero if the DPIO
+ * @receives_notifications: Use notification mode. Non-zero if the DPIO
  *                  has a channel.
  * @has_8prio:      Set to non-zero for channel with 8 priority WQs.  Ignored
  *                  unless receives_notification is TRUE.


From u-kumar1 at ti.com  Sun Feb 11 20:36:30 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Mon, 12 Feb 2024 10:06:30 +0530
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240211155459.GA4443@francesco-nb>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
 <20240211155459.GA4443@francesco-nb>
Message-ID: <b27ea51f-ad29-4c8a-8f33-f51640f0c013@ti.com>


On 2/11/2024 9:24 PM, Francesco Dolcini wrote:
> On Wed, Feb 07, 2024 at 02:41:00PM +0530, Udit Kumar wrote:
>> Most of clocks and their parents are defined in contiguous range,
>> But in few cases, there is gap in clock numbers[0].
>> Driver assumes clocks to be in contiguous range, and add their clock
>> ids incrementally.
>>
>> New firmware started returning error while calling get_freq and is_on
>> API for non-available clock ids.
>>
>> In this fix, driver checks and adds only valid clock ids.
>>
>> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
>>
>> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
>> Section Clocks for NAVSS0_CPTS_0 Device,
>> clock id 12-15 not present.
>>
>> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
> no empty lines in between tags and only tags at the end of the commit
> message, this [0] reference needs to be before or moved to a `Link:` tag,
> whatever works best for you.


Thanks

will below works ?

[0]https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
Section Clocks for NAVSS0_CPTS_0 Device,
clock id 12-15 not present
Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for 
dynamically probing clocks")


Udit



From zajec5 at gmail.com  Sun Feb 11 22:11:47 2024
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Mon, 12 Feb 2024 07:11:47 +0100
Subject: [PATCH V2] dt-bindings: thermal: mediatek,thermal: document
 AUXADC 32k clock
In-Reply-To: <17d143aa-576e-4d67-a0ea-b79f3518b81c@collabora.com>
References: <20240209055203.17144-1-zajec5@gmail.com>
 <17d143aa-576e-4d67-a0ea-b79f3518b81c@collabora.com>
Message-ID: <ddec28a5-8d65-4e52-bb3c-9587acf7bca1@gmail.com>

On 9.02.2024 10:13, AngeloGioacchino Del Regno wrote:
> Il 09/02/24 06:52, Rafa? Mi?ecki ha scritto:
>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>
>> SoCs MT7981 and MT7986 include a newer thermal block (V3) that requires
>> enabling one more clock called AUXADC 32k. Require it in binding.
>>
>> Cc: Daniel Golle <daniel at makrotopia.org>
>> Cc: Sam Shih <sam.shih at mediatek.com>
>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> So, I've made some research on this matter.. and this is a NACK.

Well, I can only thank you for the research.

Let's drop this patch. I'll sort out the rest later.


From tudor.ambarus at linaro.org  Sun Feb 11 22:17:14 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 06:17:14 +0000
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth``
 property
In-Reply-To: <be84e32e-e11d-47fe-ad56-da8b0dec5007@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
 <20240208135045.3728927-2-tudor.ambarus@linaro.org>
 <CAMuHMdU_Hx9PLmHf2Xm1KKTy_OF-TeCv7SzmA5CZWz+PLkbAGA@mail.gmail.com>
 <be84e32e-e11d-47fe-ad56-da8b0dec5007@linaro.org>
Message-ID: <828d9947-ee96-4c2f-b856-0fac3640c863@linaro.org>



Hi, Geert, Krzysztof,

On 2/11/24 13:49, Krzysztof Kozlowski wrote:> On 09/02/2024 18:13, Geert
Uytterhoeven wrote:
>> Hi Tudor,
>>
>> On Thu, Feb 8, 2024 at 2:51?PM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>>> There are instances of the same IP that are configured by the integrator
>>> with different FIFO depths. Introduce the fifo-depth property to allow
>>> such nodes to specify their FIFO depth.
>>>
>>> We haven't seen SPI IPs with different FIFO depths for RX and TX, thus
>>> introduce a single property.
>>
>> Ha...
>>
>> Current documentation for the Clock-Synchronized Serial Interface with
>> FIFO (MSIOF) on e.g. R-Car Gen2 and later states:
>>
>>     FIFO capacity: 32 bits ? 64 stages for transmission and 32 bits ?
>> 256 stages for reception
>>
>> Initially (many years ago), there was some doubt about the validity
>> of these values (older variants on SH supported 64/64), hence
>> drivers/spi/spi-sh-msiof.c still has
>>
>>     .tx_fifo_size = 64,
>>     .rx_fifo_size = 64,
>>
>> Probably we should test and revisit this...
>>
>>> --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml
>>> +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml
>>> @@ -69,6 +69,11 @@ properties:
>>>           Should be generally avoided and be replaced by
>>>           spi-cs-high + ACTIVE_HIGH.
>>>
>>> +  fifo-depth:
>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>> +    description:
>>> +      Size of the data FIFO in bytes.
>>
>> I think it is prudent to consider the asymmetric case, too.
>> Whether that should be just two properties ("rx-fifo-depth" and
>> "tx-fifo-depth"), or also a third "fifo-depth", I defer to the DT
>> maintainers...

Thanks, Geert for the insight!
> 
> Since most of the cases FIFO depth tx=rx, we could go with three
> properties and:
> 
> allOf:
>  - not:
>      required:
>        - fifo-depth
>        - tx-fifo-depth
>  - not:
>      required:
>        - fifo-depth
>        - rx-fifo-depth
> 
> and probably dependencies between rx and tx (see example-schema).
> 
Great. Thanks, Krzysztof! I'll give it a try.
Cheers,
ta


From adrian.hunter at intel.com  Sun Feb 11 22:43:11 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Mon, 12 Feb 2024 08:43:11 +0200
Subject: [PATCH V5 01/12] perf/core: Add aux_pause, aux_resume,
 aux_start_paused
In-Reply-To: <ZcaUw4xQT0VcC7IO@tassilo>
References: <20240208113127.22216-1-adrian.hunter@intel.com>
 <20240208113127.22216-2-adrian.hunter@intel.com> <ZcVuK1nnxG18ps-a@tassilo>
 <d53ef26d-a7e6-4b3b-b593-be75425c0e77@intel.com> <ZcaUw4xQT0VcC7IO@tassilo>
Message-ID: <05ac66fc-ddda-46ff-b08d-c15943c16bc1@intel.com>

On 9/02/24 23:10, Andi Kleen wrote:
>> The writes to rb->aux_in_pause_resume must be done
>> only once.  It might be possible to get away without
>> WRITE_ONCE(), but really the compiler should be informed
>> not to make assumptions.
> 
> What stops the NMI from firing here?

That would be fine.

> 
>>>> +  if (READ_ONCE(rb->aux_in_pause_resume))
>>>> +	/* Guard against NMI, NMI loses here */
>>>> +          goto out_restore;
> <----------------------- NMI

That would be fine.

>>>> +  WRITE_ONCE(rb->aux_in_pause_resume, 1);

>From here on, the NMI will see rb->aux_in_pause_resume == 1
and do nothing, up to the point when rb->aux_in_pause_resume == 0
again.

This code is about guarding against NMI.  Interrupts are
disabled, and the rb and event only operate on 1 cpu at a time.

> 
> 
> Even if it isn't racy it needs a clear comment.

It has a comment, but it could be more explanatory.  The code
paradigm is also used in perf_pmu_snapshot_aux().



From zajec5 at gmail.com  Sun Feb 11 23:20:56 2024
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Mon, 12 Feb 2024 08:20:56 +0100
Subject: [PATCH v4] dt-bindings: net: wireless: mt76: add interrupts
 description for MT7986
In-Reply-To: <20231221032648.641-1-chui-hao.chiu@mediatek.com>
References: <20231221032648.641-1-chui-hao.chiu@mediatek.com>
Message-ID: <03d80cad-b72b-44d7-b726-cd8e3d4f81a9@gmail.com>

On 21.12.2023 04:26, Peter Chiu wrote:
> The mt7986 can support four interrupts to distribute the interrupts
> to different CPUs.

Can we have this patch picked up, please? Felix? Kalle?


From krzysztof.kozlowski at linaro.org  Sun Feb 11 23:31:13 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 08:31:13 +0100
Subject: [PATCH v2] ARM: s3c64xx: make s3c6410_subsys const
In-Reply-To: <20240211-bus_cleanup-arm-v2-1-3de9e8af7cbd@marliere.net>
References: <20240211-bus_cleanup-arm-v2-1-3de9e8af7cbd@marliere.net>
Message-ID: <b7726526-0b0a-4d3d-bf05-b1065d361cc2@linaro.org>

On 11/02/2024 16:57, Ricardo B. Marliere wrote:
> Since commit d492cc2573a0 ("driver core: device.h: make struct bus_type
> a const *"), the driver core can properly handle constant struct
> bus_type, move the s3c6410_subsys variable to be a constant structure as
> well, placing it into read-only memory which can not be modified at
> runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
> ---

I just noticed you sent quite the same change for the same subarch.
Please perform changes all at once. Squashed.

Best regards,
Krzysztof



From francesco at dolcini.it  Sun Feb 11 23:58:20 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Mon, 12 Feb 2024 08:58:20 +0100
Subject: [PATCH v3] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <b27ea51f-ad29-4c8a-8f33-f51640f0c013@ti.com>
References: <20240207091100.4001428-1-u-kumar1@ti.com>
 <20240211155459.GA4443@francesco-nb>
 <b27ea51f-ad29-4c8a-8f33-f51640f0c013@ti.com>
Message-ID: <ZcnPnMEknPjtwJtz@gaggiata.pivistrello.it>

On Mon, Feb 12, 2024 at 10:06:30AM +0530, Kumar, Udit wrote:
> 
> On 2/11/2024 9:24 PM, Francesco Dolcini wrote:
> > On Wed, Feb 07, 2024 at 02:41:00PM +0530, Udit Kumar wrote:
> > > Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
> > > 
> > > [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> > > Section Clocks for NAVSS0_CPTS_0 Device,
> > > clock id 12-15 not present.
> > > 
> > > Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
> > no empty lines in between tags and only tags at the end of the commit
> > message, this [0] reference needs to be before or moved to a `Link:` tag,
> > whatever works best for you.
> will below works ?

No, it does not fullfil the expectation to have only tags at the end.

> [0]https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> Section Clocks for NAVSS0_CPTS_0 Device,
> clock id 12-15 not present
> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically
> probing clocks")


From krzysztof.kozlowski at linaro.org  Mon Feb 12 00:00:58 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 09:00:58 +0100
Subject: [PATCH v2] ARM: s3c64xx: make s3c6410_subsys const
In-Reply-To: <20240211-bus_cleanup-arm-v2-1-3de9e8af7cbd@marliere.net>
References: <20240211-bus_cleanup-arm-v2-1-3de9e8af7cbd@marliere.net>
Message-ID: <170772485844.8549.14056972492264035636.b4-ty@linaro.org>


On Sun, 11 Feb 2024 12:57:09 -0300, Ricardo B. Marliere wrote:
> Since commit d492cc2573a0 ("driver core: device.h: make struct bus_type
> a const *"), the driver core can properly handle constant struct
> bus_type, move the s3c6410_subsys variable to be a constant structure as
> well, placing it into read-only memory which can not be modified at
> runtime.
> 
> 
> [...]

Applied, thanks!

[1/1] ARM: s3c64xx: make s3c6410_subsys const
      https://git.kernel.org/krzk/linux/c/a3891621d4a0783ae178d6f2845517e3dd571dd4

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From danishanwar at ti.com  Mon Feb 12 00:06:53 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Mon, 12 Feb 2024 13:36:53 +0530
Subject: [PATCH v3 3/3] arm64: dts: ti: k3-am642-evm: add overlay for
 icssg1 2nd port
In-Reply-To: <33e62844-a148-4374-aba8-481dc7799e15@kernel.org>
References: <20240122113045.1711818-1-danishanwar@ti.com>
 <20240122113045.1711818-4-danishanwar@ti.com>
 <33e62844-a148-4374-aba8-481dc7799e15@kernel.org>
Message-ID: <1a29102b-b3b6-4aee-96b2-5169fefeecb3@ti.com>

Hi Roger,

On 02/02/24 5:56 pm, Roger Quadros wrote:
> 
> 
> On 22/01/2024 13:30, MD Danish Anwar wrote:
>> The am642-evm doesn't allow to enable 2 x CPSW3g ports and 2 x ICSSG1 ports
>> all together, so base k3-am642-evm.dts enables by default 2 x CPSW3g ports
>> and 1 x ICSSG1 ports, but it also possible to support 1 x CPSW3g ports and
>> 2 x ICSSG1 ports configuration.
> 
> "it is also possible"
> 
> OK so there can only be 3 ethernet ports on this board. There is no "ethernet3" alias.
> 
>>
>> This patch adds overlay to support 1 x CPSW3g ports and 2 x ICSSG1 ports
>> configuration:
>> - Add label name 'mdio_mux_1' for 'mdio-mux-1' node so that the node
>>   'mdio-mux-1' can be disabled in the overlay using the label name.
>> - disable 2nd CPSW3g port
>> - update CPSW3g pinmuxes to not use RGMII2
>> - disable mdio-mux-1 and define mdio-mux-2 to route ICSSG1 MDIO to the
>>   shared DP83869 PHY
>> - add and enable ICSSG1 RGMII2 pinmuxes
>> - enable ICSSG1 MII1 port
>>
>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>> ---
>>  arch/arm64/boot/dts/ti/Makefile               |  5 ++
>>  .../dts/ti/k3-am642-evm-icssg1-dualemac.dtso  | 75 +++++++++++++++++++
>>  arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  2 +-
>>  3 files changed, 81 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>>
>> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
>> index 52c1dc910308..320b2fae5730 100644
>> --- a/arch/arm64/boot/dts/ti/Makefile
>> +++ b/arch/arm64/boot/dts/ti/Makefile
>> @@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
>>  dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
>>  dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>>  dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
>> +dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac.dtbo
>>  
>>  # Boards with AM65x SoC
>>  k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
>> @@ -105,6 +106,8 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
>>  	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>>  k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
>>  	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
>> +k3-am642-evm-icssg1-dualemac-dtbs := \
>> +	k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
>>  k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
>>  	k3-j721e-evm-pcie0-ep.dtbo
>>  k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
>> @@ -120,6 +123,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
>>  	k3-am62a7-sk-csi2-ov5640.dtb \
>>  	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
>>  	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
>> +	k3-am642-evm-icssg1-dualemac.dtb \
>>  	k3-j721e-evm-pcie0-ep.dtb \
>>  	k3-j721s2-evm-pcie1-ep.dtb
>>  
>> @@ -129,6 +133,7 @@ DTC_FLAGS_k3-am625-sk += -@
>>  DTC_FLAGS_k3-am62-lp-sk += -@
>>  DTC_FLAGS_k3-am62a7-sk += -@
>>  DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
>> +DTC_FLAGS_k3-am642-evm += -@
>>  DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
>>  DTC_FLAGS_k3-j721e-common-proc-board += -@
>>  DTC_FLAGS_k3-j721s2-common-proc-board += -@
>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>> new file mode 100644
>> index 000000000000..b2b1a6252e73
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
>> @@ -0,0 +1,75 @@
>> +// SPDX-License-Identifier: GPL-2.0
> 
> Don't you need to use updated licensing header like in the series [1]
> 
> [1] https://lore.kernel.org/all/20240110140903.4090946-1-nm at ti.com/
> 
>> +/**
>> + * DT overlay for enabling 2nd ICSSG1 port on AM642 EVM
>> + *
>> + * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
>> + */
>> +
>> +/dts-v1/;
>> +/plugin/;
>> +
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include "k3-pinctrl.h"
>> +
>> +&{/} {
> 
> You need to fixup alias for ethernet1 to icssg1_emac1?
> 
>> +	mdio-mux-2 {
> 
> this should be mdio-mux at 0 ?
> 
>> +		compatible = "mdio-mux-multiplexer";
>> +		mux-controls = <&mdio_mux>;
>> +		mdio-parent-bus = <&icssg1_mdio>;
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		mdio at 0 {
>> +			reg = <0x0>;
>> +			#address-cells = <1>;
>> +			#size-cells = <0>;
>> +
>> +			icssg1_phy2: ethernet-phy at 3 {
>> +				reg = <3>;
>> +				tx-internal-delay-ps = <250>;
>> +				rx-internal-delay-ps = <2000>;
>> +			};
>> +		};
>> +	};
>> +};
>> +

<snip>

>> +};
>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> index c08b0223be52..6ae43c12419f 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> @@ -200,7 +200,7 @@ mdio_mux: mux-controller {
>>  		mux-gpios = <&exp1 12 GPIO_ACTIVE_HIGH>;
>>  	};
>>  
>> -	mdio-mux-1 {
>> +	mdio_mux_1: mdio-mux-1 {
> 
> mdio_mux_1: mdio-mux at 1
> 

Changing this from mdio-mux-1 to mdio-mux at 1 is giving me erorr in DTBS_CHECK

/home/danish/workspace/linux-next/arch/arm64/boot/dts/ti/k3-am642-evm.dtb:
/: mdio-mux at 1: 'anyOf' conditional failed, one must be fixed:
	'reg' is a required property
	'ranges' is a required property
	from schema $id: http://devicetree.org/schemas/root-node.yaml#

The documentation of mdio-mux-multiplexer [1] also has example section
with node name as -1 instead of @1. I don't think node should be renamed
to mdio-mux at 1.

I hadn't done DTBS_CHECK earlier have already made this change in v4
[2]. I will revert back this change and keep the nodes as mdio-mux-1 and
mdio-mux-2 in v5. Let me know if it's OK with you.

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/net/mdio-mux-multiplexer.yaml#n34
[2] https://lore.kernel.org/all/20240205090546.4000446-4-danishanwar at ti.com/

>>  		compatible = "mdio-mux-multiplexer";
>>  		mux-controls = <&mdio_mux>;
>>  		mdio-parent-bus = <&cpsw3g_mdio>;
> 

-- 
Thanks and Regards,
Danish


From krzysztof.kozlowski at linaro.org  Mon Feb 12 00:34:24 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 09:34:24 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit,hd44780: drop redundant GPIO node
Message-ID: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>

Examples of other nodes, like GPIO controller, are redundant and not
really needed in device bindings.

Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../devicetree/bindings/auxdisplay/hit,hd44780.yaml    | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
index 406a922a714e..73d07f2cb303 100644
--- a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
@@ -99,17 +99,7 @@ examples:
     };
   - |
     #include <dt-bindings/gpio/gpio.h>
-    i2c {
-            #address-cells = <1>;
-            #size-cells = <0>;
 
-            pcf8574: pcf8574 at 27 {
-                    compatible = "nxp,pcf8574";
-                    reg = <0x27>;
-                    gpio-controller;
-                    #gpio-cells = <2>;
-            };
-    };
     hd44780 {
             compatible = "hit,hd44780";
             display-height-chars = <2>;
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Mon Feb 12 00:34:25 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 09:34:25 +0100
Subject: [PATCH 2/3] dt-bindings: auxdisplay: adjust example indentation and use generic node names
In-Reply-To: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240212083426.26757-2-krzysztof.kozlowski@linaro.org>

The example DTS should be indented with two or four (preferred) spaces,
as mentioned in Writing Schema document.  While re-indenting, change the
node names to somehow generic names, as expected by Devicetree
specification.

Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../auxdisplay/arm,versatile-lcd.yaml         |  4 +-
 .../bindings/auxdisplay/hit,hd44780.yaml      | 44 ++++++++--------
 .../bindings/auxdisplay/holtek,ht16k33.yaml   | 50 +++++++++----------
 .../bindings/auxdisplay/img,ascii-lcd.yaml    |  4 +-
 4 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml b/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml
index 5d02bd032a85..439f7b811a94 100644
--- a/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml
@@ -39,6 +39,6 @@ additionalProperties: false
 examples:
   - |
     lcd at 10008000 {
-            compatible = "arm,versatile-lcd";
-            reg = <0x10008000 0x1000>;
+        compatible = "arm,versatile-lcd";
+        reg = <0x10008000 0x1000>;
     };
diff --git a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
index 73d07f2cb303..1c7fd29bbcc7 100644
--- a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
@@ -84,32 +84,32 @@ additionalProperties: false
 examples:
   - |
     #include <dt-bindings/gpio/gpio.h>
-    auxdisplay {
-            compatible = "hit,hd44780";
+    display-controller {
+        compatible = "hit,hd44780";
 
-            data-gpios = <&hc595 0 GPIO_ACTIVE_HIGH>,
-                         <&hc595 1 GPIO_ACTIVE_HIGH>,
-                         <&hc595 2 GPIO_ACTIVE_HIGH>,
-                         <&hc595 3 GPIO_ACTIVE_HIGH>;
-            enable-gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
-            rs-gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
+        data-gpios = <&hc595 0 GPIO_ACTIVE_HIGH>,
+                     <&hc595 1 GPIO_ACTIVE_HIGH>,
+                     <&hc595 2 GPIO_ACTIVE_HIGH>,
+                     <&hc595 3 GPIO_ACTIVE_HIGH>;
+        enable-gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
+        rs-gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
 
-            display-height-chars = <2>;
-            display-width-chars = <16>;
+        display-height-chars = <2>;
+        display-width-chars = <16>;
     };
   - |
     #include <dt-bindings/gpio/gpio.h>
 
-    hd44780 {
-            compatible = "hit,hd44780";
-            display-height-chars = <2>;
-            display-width-chars = <16>;
-            data-gpios = <&pcf8574 4 0>,
-                         <&pcf8574 5 0>,
-                         <&pcf8574 6 0>,
-                         <&pcf8574 7 0>;
-            enable-gpios = <&pcf8574 2 0>;
-            rs-gpios = <&pcf8574 0 0>;
-            rw-gpios = <&pcf8574 1 0>;
-            backlight-gpios = <&pcf8574 3 0>;
+    display-controller {
+        compatible = "hit,hd44780";
+        display-height-chars = <2>;
+        display-width-chars = <16>;
+        data-gpios = <&pcf8574 4 0>,
+                     <&pcf8574 5 0>,
+                     <&pcf8574 6 0>,
+                     <&pcf8574 7 0>;
+        enable-gpios = <&pcf8574 2 0>;
+        rs-gpios = <&pcf8574 0 0>;
+        rw-gpios = <&pcf8574 1 0>;
+        backlight-gpios = <&pcf8574 3 0>;
     };
diff --git a/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml b/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
index be95f6b97b41..b90eec2077b4 100644
--- a/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
@@ -74,31 +74,31 @@ examples:
     #include <dt-bindings/input/input.h>
     #include <dt-bindings/leds/common.h>
     i2c {
-            #address-cells = <1>;
-            #size-cells = <0>;
+        #address-cells = <1>;
+        #size-cells = <0>;
 
-            ht16k33: ht16k33 at 70 {
-                    compatible = "holtek,ht16k33";
-                    reg = <0x70>;
-                    refresh-rate-hz = <20>;
-                    interrupt-parent = <&gpio4>;
-                    interrupts = <5 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>;
-                    debounce-delay-ms = <50>;
-                    linux,keymap = <MATRIX_KEY(2, 0, KEY_F6)>,
-                                   <MATRIX_KEY(3, 0, KEY_F8)>,
-                                   <MATRIX_KEY(4, 0, KEY_F10)>,
-                                   <MATRIX_KEY(5, 0, KEY_F4)>,
-                                   <MATRIX_KEY(6, 0, KEY_F2)>,
-                                   <MATRIX_KEY(2, 1, KEY_F5)>,
-                                   <MATRIX_KEY(3, 1, KEY_F7)>,
-                                   <MATRIX_KEY(4, 1, KEY_F9)>,
-                                   <MATRIX_KEY(5, 1, KEY_F3)>,
-                                   <MATRIX_KEY(6, 1, KEY_F1)>;
+        display-controller at 70 {
+            compatible = "holtek,ht16k33";
+            reg = <0x70>;
+            refresh-rate-hz = <20>;
+            interrupt-parent = <&gpio4>;
+            interrupts = <5 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>;
+            debounce-delay-ms = <50>;
+            linux,keymap = <MATRIX_KEY(2, 0, KEY_F6)>,
+                           <MATRIX_KEY(3, 0, KEY_F8)>,
+                           <MATRIX_KEY(4, 0, KEY_F10)>,
+                           <MATRIX_KEY(5, 0, KEY_F4)>,
+                           <MATRIX_KEY(6, 0, KEY_F2)>,
+                           <MATRIX_KEY(2, 1, KEY_F5)>,
+                           <MATRIX_KEY(3, 1, KEY_F7)>,
+                           <MATRIX_KEY(4, 1, KEY_F9)>,
+                           <MATRIX_KEY(5, 1, KEY_F3)>,
+                           <MATRIX_KEY(6, 1, KEY_F1)>;
 
-                    led {
-                            color = <LED_COLOR_ID_RED>;
-                            function = LED_FUNCTION_BACKLIGHT;
-                            linux,default-trigger = "backlight";
-                    };
+            led {
+                color = <LED_COLOR_ID_RED>;
+                function = LED_FUNCTION_BACKLIGHT;
+                linux,default-trigger = "backlight";
             };
-      };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/auxdisplay/img,ascii-lcd.yaml b/Documentation/devicetree/bindings/auxdisplay/img,ascii-lcd.yaml
index 1899b23de7d1..55e9831b3f67 100644
--- a/Documentation/devicetree/bindings/auxdisplay/img,ascii-lcd.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/img,ascii-lcd.yaml
@@ -50,6 +50,6 @@ additionalProperties: false
 examples:
   - |
     lcd: lcd at 17fff000 {
-            compatible = "img,boston-lcd";
-            reg = <0x17fff000 0x8>;
+        compatible = "img,boston-lcd";
+        reg = <0x17fff000 0x8>;
     };
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Mon Feb 12 00:34:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 09:34:26 +0100
Subject: [PATCH 3/3] dt-bindings: auxdisplay: hit,hd44780: use defines for GPIO flags
In-Reply-To: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240212083426.26757-3-krzysztof.kozlowski@linaro.org>

Improve example DTS readability by using known defines for GPIO flags.

Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../bindings/auxdisplay/hit,hd44780.yaml         | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
index 1c7fd29bbcc7..869ae0f6cf5d 100644
--- a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
@@ -104,12 +104,12 @@ examples:
         compatible = "hit,hd44780";
         display-height-chars = <2>;
         display-width-chars = <16>;
-        data-gpios = <&pcf8574 4 0>,
-                     <&pcf8574 5 0>,
-                     <&pcf8574 6 0>,
-                     <&pcf8574 7 0>;
-        enable-gpios = <&pcf8574 2 0>;
-        rs-gpios = <&pcf8574 0 0>;
-        rw-gpios = <&pcf8574 1 0>;
-        backlight-gpios = <&pcf8574 3 0>;
+        data-gpios = <&pcf8574 4 GPIO_ACTIVE_HIGH>,
+                     <&pcf8574 5 GPIO_ACTIVE_HIGH>,
+                     <&pcf8574 6 GPIO_ACTIVE_HIGH>,
+                     <&pcf8574 7 GPIO_ACTIVE_HIGH>;
+        enable-gpios = <&pcf8574 2 GPIO_ACTIVE_HIGH>;
+        rs-gpios = <&pcf8574 0 GPIO_ACTIVE_HIGH>;
+        rw-gpios = <&pcf8574 1 GPIO_ACTIVE_HIGH>;
+        backlight-gpios = <&pcf8574 3 GPIO_ACTIVE_HIGH>;
     };
-- 
2.34.1



From geert at linux-m68k.org  Mon Feb 12 00:41:50 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 12 Feb 2024 09:41:50 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit,hd44780: drop redundant
 GPIO node
In-Reply-To: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>

Hi Krzysztof,

CC Ralf

On Mon, Feb 12, 2024 at 9:34?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
> Examples of other nodes, like GPIO controller, are redundant and not
> really needed in device bindings.
>
> Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Thanks for your patch!

> --- a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
> +++ b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
> @@ -99,17 +99,7 @@ examples:
>      };
>    - |
>      #include <dt-bindings/gpio/gpio.h>
> -    i2c {
> -            #address-cells = <1>;
> -            #size-cells = <0>;
>
> -            pcf8574: pcf8574 at 27 {
> -                    compatible = "nxp,pcf8574";
> -                    reg = <0x27>;
> -                    gpio-controller;
> -                    #gpio-cells = <2>;
> -            };
> -    };

This part was added delberately in commit c784e46c8445635a ("auxdisplay:
Add I2C gpio expander example"), to aid makers who are not DT experts.
Note that there are no other examples of this popular wiring scheme
in upstream DTS.

>      hd44780 {
>              compatible = "hit,hd44780";
>              display-height-chars = <2>;

If you do want to insist on removing the i2c GPIO expander part,
I think this node should be removed too, as it is almost identical
to the first example.

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 m-chawdhry at ti.com  Mon Feb 12 00:44:34 2024
From: m-chawdhry at ti.com (Manorit Chawdhry)
Date: Mon, 12 Feb 2024 14:14:34 +0530
Subject: [PATCH v2 0/3] arm64: dts: ti: Introduce J722S SoC and EVM
In-Reply-To: <20240206100608.127702-1-vaishnav.a@ti.com>
References: <20240206100608.127702-1-vaishnav.a@ti.com>
Message-ID: <20240212084434.fygiqv2gtovjlq3d@uda0497581>

Hi Vaishnav,

On 15:36-20240206, Vaishnav Achath wrote:
> This series adds basic support for J722S family of SoCs. Also add
> J722S EVM support with basic peripheral like MMC and UART.
> 
> TRM: https://www.ti.com/lit/zip/sprujb3
> EVM Schematics: https://www.ti.com/lit/zip/sprr495
> 
> Bootlog (6.8.0-rc3-next-20240206):
> https://gist.github.com/vaishnavachath/23d859925277df9ccd628190e7c23371
> 
> Changelog:
> V1->V2:
>   * Address feedback from Nishanth to reuse from AM62P5 dtsi.
>   * Remove bootph-all from root nodes.
>   * Change License to GPL-2.0-only OR MIT as followed for other
>     K3 files.
> 
> Vaishnav Achath (3):
>   dt-bindings: arm: ti: Add bindings for J722S SoCs
>   arm64: dts: ti: Introduce J722S family of SoCs
>   arm64: dts: ti: Add support for TI J722S Evaluation Module
> 

For the series, 

Reviewed-by: Manorit Chawdhry <m-chawdhry at ti.com>

Regards,
Manorit

>  .../devicetree/bindings/arm/ti/k3.yaml        |   6 +
>  arch/arm64/boot/dts/ti/Makefile               |   3 +
>  arch/arm64/boot/dts/ti/k3-j722s-evm.dts       | 251 ++++++++++++++++++
>  arch/arm64/boot/dts/ti/k3-j722s.dtsi          |  89 +++++++
>  arch/arm64/boot/dts/ti/k3-pinctrl.h           |   3 +
>  5 files changed, 352 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/ti/k3-j722s-evm.dts
>  create mode 100644 arch/arm64/boot/dts/ti/k3-j722s.dtsi
> 
> -- 
> 2.34.1
> 


From angelogioacchino.delregno at collabora.com  Mon Feb 12 00:45:31 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 12 Feb 2024 09:45:31 +0100
Subject: [PATCH] mtd: rawnand: Prefer struct_size over open coded
 arithmetic
In-Reply-To: <20240210161619.12656-1-erick.archer@gmx.com>
References: <20240210161619.12656-1-erick.archer@gmx.com>
Message-ID: <5cd419e6-2585-4f9e-b814-b928ebdb18f2@collabora.com>

Il 10/02/24 17:16, Erick Archer ha scritto:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> As the "chip" variable is a pointer to "struct mtk_nfc_nand_chip" and
> this structure ends in a flexible array:
> 
> struct mtk_nfc_nand_chip {
> 	[...]
> 	u8 sels[] __counted_by(nsels);
> };
> 
> the preferred way in the kernel is to use the struct_size() helper to
> do the arithmetic instead of the argument "size + count * size" in the
> devm_kzalloc() function.
> 
> This way, the code is more readable and more safer.

This way, the code is more readable and safer.

Apart from that,
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> 
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
> Link: https://github.com/KSPP/linux/issues/160 [2]
> Signed-off-by: Erick Archer <erick.archer at gmx.com>
> ---
>   drivers/mtd/nand/raw/mtk_nand.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
> index 60198e33d2d5..17477bb2d48f 100644
> --- a/drivers/mtd/nand/raw/mtk_nand.c
> +++ b/drivers/mtd/nand/raw/mtk_nand.c
> @@ -1356,7 +1356,7 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
>   		return -EINVAL;
>   	}
> 
> -	chip = devm_kzalloc(dev, sizeof(*chip) + nsels * sizeof(u8),
> +	chip = devm_kzalloc(dev, struct_size(chip, sels, nsels),
>   			    GFP_KERNEL);
>   	if (!chip)
>   		return -ENOMEM;
> --
> 2.25.1
> 




From angelogioacchino.delregno at collabora.com  Mon Feb 12 00:46:43 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 12 Feb 2024 09:46:43 +0100
Subject: [PATCH v2] mtd: rawnand: Prefer struct_size over open coded
 arithmetic
In-Reply-To: <20240211091633.4545-1-erick.archer@gmx.com>
References: <20240211091633.4545-1-erick.archer@gmx.com>
Message-ID: <d7bbca9f-466a-4595-b02d-703dd22c3386@collabora.com>

Il 11/02/24 10:16, Erick Archer ha scritto:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> As the "chip" variable is a pointer to "struct mtk_nfc_nand_chip" and
> this structure ends in a flexible array:
> 
> struct mtk_nfc_nand_chip {
> 	[...]
> 	u8 sels[] __counted_by(nsels);
> };
> 
> the preferred way in the kernel is to use the struct_size() helper to
> do the arithmetic instead of the argument "size + count * size" in the
> devm_kzalloc() function.
> 
> This way, the code is more readable and safer.
> 
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
> Link: https://github.com/KSPP/linux/issues/160 [2]
> Reviewed-by: Gustavo A. R. Silva <gustavoars at kernel.org>
> Signed-off-by: Erick Archer <erick.archer at gmx.com>

Just noticed that there was a v2 already addressing the commit description issue.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Feb 12 00:49:21 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 12 Feb 2024 09:49:21 +0100
Subject: [PATCH] iommu/mtk_iommu: Use devm_kcalloc() instead of
 devm_kzalloc()
In-Reply-To: <20240211182250.12656-1-erick.archer@gmx.com>
References: <20240211182250.12656-1-erick.archer@gmx.com>
Message-ID: <25e10072-30eb-4272-8a89-2c5240d53a1c@collabora.com>

Il 11/02/24 19:22, Erick Archer ha scritto:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> Here the multiplication is obviously safe because MTK_PROTECT_PA_ALIGN
> is defined as a literal value of 256 or 128.
> 
> For the "mtk_iommu.c" file: 256
> For the "mtk_iommu_v1.c" file: 128
> 
> However, using devm_kcalloc() is more appropriate [2] and improves
> readability. This patch has no effect on runtime behavior.
> 
> Link: https://github.com/KSPP/linux/issues/162 [1]
> Link: https://www.kernel.org/doc/html/next/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [2]
> Signed-off-by: Erick Archer <erick.archer at gmx.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/iommu/mtk_iommu.c    | 2 +-
>   drivers/iommu/mtk_iommu_v1.c | 4 ++--
>   2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 7abe9e85a570..9aae6eb604b1 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -1264,7 +1264,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_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN, GFP_KERNEL);
>   	if (!protect)
>   		return -ENOMEM;
>   	data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index 25b41222abae..45cd845d153f 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -621,8 +621,8 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev)
>   	data->dev = dev;
> 
>   	/* Protect memory. HW will access here while translation fault.*/
> -	protect = devm_kzalloc(dev, MTK_PROTECT_PA_ALIGN * 2,
> -			GFP_KERNEL | GFP_DMA);
> +	protect = devm_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN,
> +			       GFP_KERNEL | GFP_DMA);
>   	if (!protect)
>   		return -ENOMEM;
>   	data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
> --
> 2.25.1
> 




From angelogioacchino.delregno at collabora.com  Mon Feb 12 00:51:02 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 12 Feb 2024 09:51:02 +0100
Subject: [PATCH v4] dt-bindings: net: wireless: mt76: add interrupts
 description for MT7986
In-Reply-To: <20231221032648.641-1-chui-hao.chiu@mediatek.com>
References: <20231221032648.641-1-chui-hao.chiu@mediatek.com>
Message-ID: <c3488bc9-f55f-478a-b8fc-274f40fb0818@collabora.com>

Il 21/12/23 04:26, Peter Chiu ha scritto:
> The mt7986 can support four interrupts to distribute the interrupts
> to different CPUs.
> 
> Signed-off-by: Peter Chiu <chui-hao.chiu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Feb 12 00:53:54 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 12 Feb 2024 09:53:54 +0100
Subject: [PATCH V2] dt-bindings: thermal: mediatek,thermal: document
 AUXADC 32k clock
In-Reply-To: <ddec28a5-8d65-4e52-bb3c-9587acf7bca1@gmail.com>
References: <20240209055203.17144-1-zajec5@gmail.com>
 <17d143aa-576e-4d67-a0ea-b79f3518b81c@collabora.com>
 <ddec28a5-8d65-4e52-bb3c-9587acf7bca1@gmail.com>
Message-ID: <cd1350d0-6333-4519-a811-8413080ac92d@collabora.com>

Il 12/02/24 07:11, Rafa? Mi?ecki ha scritto:
> On 9.02.2024 10:13, AngeloGioacchino Del Regno wrote:
>> Il 09/02/24 06:52, Rafa? Mi?ecki ha scritto:
>>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>>
>>> SoCs MT7981 and MT7986 include a newer thermal block (V3) that requires
>>> enabling one more clock called AUXADC 32k. Require it in binding.
>>>
>>> Cc: Daniel Golle <daniel at makrotopia.org>
>>> Cc: Sam Shih <sam.shih at mediatek.com>
>>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>>
>> So, I've made some research on this matter.. and this is a NACK.
> 
> Well, I can only thank you for the research.
> 
> Let's drop this patch. I'll sort out the rest later.

Thank you for bringing that up - this was necessary to clarify this and
to actually make both of us aware of the mistake in the device trees that
we have for those SoCs.

Take your time, btw, you're doing a great job.

Cheers,
Angelo


From vigneshr at ti.com  Mon Feb 12 00:52:36 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Mon, 12 Feb 2024 14:22:36 +0530
Subject: [PATCH 0/3] arm64: ti: k3-am62a: Add display support
In-Reply-To: <20240201125452.1920623-1-a-bhatia1@ti.com>
References: <20240201125452.1920623-1-a-bhatia1@ti.com>
Message-ID: <170772794559.2674561.13954046137471686164.b4-ty@ti.com>

Hi Aradhya Bhatia,

On Thu, 01 Feb 2024 18:24:49 +0530, Aradhya Bhatia wrote:
> This patch series adds DT nodes for Display SubSystem (DSS) and other
> peripherals required to enable the HDMI audio and video on the
> AM62A7-SK EVM. An HDMI monitor can be connected to the platform for the
> audio-video outputs.
> 
> Regards
> Aradhya
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/3] arm64: dts: ti: k3-am62a-main: Add node for Display SubSystem (DSS)
      commit: 3618811657b31090da08a0c4bcd9941102b5456f
[2/3] arm64: dts: ti: k3-am62a7-sk: Add HDMI support
      commit: 396ca2fc736b0b3c6f738408e9a3e82d86b62d49
[3/3] arm64: dts: ti: Makefile: Add HDMI audio check for AM62A7-SK
      commit: cff6dd01a68fe9a8aaab724ef4e21f37eff609e9

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From mripard at kernel.org  Mon Feb 12 01:55:32 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 10:55:32 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB
 property
In-Reply-To: <20240209203046.GA996172@toolbox>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <niqn7eql5neyfp5ficdfisdpmlwrprovqn5g7lgcfwoe74ds23@7fr4yv2miqe7>
 <20240209203046.GA996172@toolbox>
Message-ID: <uplclresnokchsgutsd27ihv4422sob77reobw6ygx3c3cqnti@hjmrhut7l5r5>

On Fri, Feb 09, 2024 at 09:30:46PM +0100, Sebastian Wick wrote:
> On Fri, Feb 02, 2024 at 04:49:04PM +0100, Maxime Ripard wrote:
> > Hi Sebastian,
> > 
> > On Mon, Jan 15, 2024 at 03:33:08PM +0100, Sebastian Wick wrote:
> > > >  /**
> > > >   * DOC: HDMI connector properties
> > > >   *
> > > > + * Broadcast RGB
> > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > + *      Infoframes will be generated according to that value.
> > > > + *
> > > > + *      The value of this property can be one of the following:
> > > > + *
> > > > + *      Automatic:
> > > > + *              RGB Range is selected automatically based on the mode
> > > > + *              according to the HDMI specifications.
> > > > + *
> > > > + *      Full:
> > > > + *              Full RGB Range is forced.
> > > > + *
> > > > + *      Limited 16:235:
> > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > + *              this works for any number of bits-per-component.
> > > > + *
> > > > + *      Drivers can set up this property by calling
> > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > + *
> > > 
> > > This is a good time to document this in more detail. There might be two
> > > different things being affected:
> > > 
> > > 1. The signalling (InfoFrame/SDP/...)
> > > 2. The color pipeline processing
> > > 
> > > All values of Broadcast RGB always affect the color pipeline processing
> > > such that a full-range input to the CRTC is converted to either full- or
> > > limited-range, depending on what the monitor is supposed to accept.
> > > 
> > > When automatic is selected, does that mean that there is no signalling,
> > > or that the signalling matches what the monitor is supposed to accept
> > > according to the spec? Also, is this really HDMI specific?
> > > 
> > > When full or limited is selected and the monitor doesn't support the
> > > signalling, what happens?
> > 
> > Leaving the YCbCr vs RGB discussion aside, would this be better ?
> 
> Yes, it is. Thanks.

Great, it'll be in the next version.

> We do have to resolve the YCbCr vs RGB issue though.
> 
> >  * Broadcast RGB (HDMI specific)
> >  *      Indicates the Quantization Range (Full vs Limited) used. The color
> >  *      processing pipeline will be adjusted to match the value of the
> 
> Ah, another thing no note here is that the CRTC as configured by user
> space must always produce full range pixels.

Added too

Thanks
-------------- 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/20240212/e6915a83/attachment.sig>

From b-kapoor at ti.com  Mon Feb 12 01:59:02 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 15:29:02 +0530
Subject: [PATCH 1/4] arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for wkup_uart0 and mcu_uart0
In-Reply-To: <20240212095905.1057298-1-b-kapoor@ti.com>
References: <20240212095905.1057298-1-b-kapoor@ti.com>
Message-ID: <20240212095905.1057298-2-b-kapoor@ti.com>

WKUP_PADCONFIG registers for wkup_uart0 and mcu_uart0 lies
under wkup_pmx2 for J7200. Thus, modify pinmux for both
of them.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 .../boot/dts/ti/k3-j7200-common-proc-board.dts  | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
index 1d8bddcae90e..160580a0584a 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -119,24 +119,25 @@ transceiver3: can-phy3 {
 };
 
 &wkup_pmx0 {
+};
+
+&wkup_pmx2 {
 	mcu_uart0_pins_default: mcu-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0xf4, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
-			J721E_WKUP_IOPAD(0xf0, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
-			J721E_WKUP_IOPAD(0xf8, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
-			J721E_WKUP_IOPAD(0xfc, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+			J721E_WKUP_IOPAD(0x90, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
+			J721E_WKUP_IOPAD(0x94, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+			J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
+			J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
 		>;
 	};
 
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0xb0, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
-			J721E_WKUP_IOPAD(0xb4, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
+			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
+			J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
 		>;
 	};
-};
 
-&wkup_pmx2 {
 	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
 		pinctrl-single,pins = <
 			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
-- 
2.34.1



From b-kapoor at ti.com  Mon Feb 12 01:59:03 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 15:29:03 +0530
Subject: [PATCH 2/4] arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency from mcu_uart0
In-Reply-To: <20240212095905.1057298-1-b-kapoor@ti.com>
References: <20240212095905.1057298-1-b-kapoor@ti.com>
Message-ID: <20240212095905.1057298-3-b-kapoor@ti.com>

Clock-frequency property is already present in mcu_uart0 node of the
k3-j7200-mcu-wakeup.dtsi file. Thus, remove redundant clock-frequency
property from mcu_uart0 node.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
index 160580a0584a..6593c5da82c0 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -273,7 +273,6 @@ &mcu_uart0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_uart0_pins_default>;
-	clock-frequency = <96000000>;
 };
 
 &main_uart0 {
-- 
2.34.1



From b-kapoor at ti.com  Mon Feb 12 01:59:01 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 15:29:01 +0530
Subject: [PATCH 0/4] arm64: dts: ti: Modify pinmux for wkup_uart0 and mcu_uart0
Message-ID: <20240212095905.1057298-1-b-kapoor@ti.com>

WKUP_PADCONFIG registers for wkup_uart0 and mcu_uart0 lies under
wkup_pmx2 for J7200. Thus, modify pinmux for both of them. Also,
remove the redundant clock-frequency property from mcu_uart0 node.

Only Tx and Rx Signal lines for wkup_uart0 are brought out on
J721S2 Common Proc Board and J784S4 EVM, but CTS and RTS signal lines
are not brought out. Thus, remove pinmux for CTS and RTS signal lines
for wkup_uart0 in J721S2 and J784S4.

Bhavya Kapoor (4):
  arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for
    wkup_uart0 and mcu_uart0
  arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency
    from mcu_uart0
  arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and
    RTS in wkup_uart0
  arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in
    wkup_uart0

 .../boot/dts/ti/k3-j7200-common-proc-board.dts | 18 +++++++++---------
 .../dts/ti/k3-j721s2-common-proc-board.dts     |  2 --
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts       |  2 --
 3 files changed, 9 insertions(+), 13 deletions(-)

-- 
2.34.1



From b-kapoor at ti.com  Mon Feb 12 01:59:05 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 15:29:05 +0530
Subject: [PATCH 4/4] arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in wkup_uart0
In-Reply-To: <20240212095905.1057298-1-b-kapoor@ti.com>
References: <20240212095905.1057298-1-b-kapoor@ti.com>
Message-ID: <20240212095905.1057298-5-b-kapoor@ti.com>

Only Tx and Rx Signal lines for wkup_uart0 are brought out on
the J784S4 EVM from SoC, but CTS and RTS signal lines are not
brought on the EVM. Thus, remove pinmux for CTS and RTS signal
lines for wkup_uart0 in J784S4.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
index 57e7cb8ea2b8..9f16642ccd5f 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -336,8 +336,6 @@ &wkup_pmx2 {
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
-			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-			J721S2_WKUP_IOPAD(0x074, PIN_INPUT, 0) /* (L36) WKUP_GPIO0_7.WKUP_UART0_RTSn */
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_INPUT, 0) /* (K34) WKUP_UART0_TXD */
 		>;
-- 
2.34.1



From b-kapoor at ti.com  Mon Feb 12 01:59:04 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 15:29:04 +0530
Subject: [PATCH 3/4] arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and RTS in wkup_uart0
In-Reply-To: <20240212095905.1057298-1-b-kapoor@ti.com>
References: <20240212095905.1057298-1-b-kapoor@ti.com>
Message-ID: <20240212095905.1057298-4-b-kapoor@ti.com>

Only Tx and Rx Signal lines for wkup_uart0 are brought out on
the Common Proc Board through SoM, but CTS and RTS signal lines
are not brought on the board. Thus, remove pinmux for CTS and RTS
signal lines for wkup_uart0 in J721S2.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
index 361365bb5523..6371cb1c1fe7 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -190,8 +190,6 @@ J721S2_IOPAD(0x038, PIN_OUTPUT, 0) /* (AB28) MCASP0_ACLKX.MCAN5_TX */
 &wkup_pmx2 {
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (E25) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-			J721S2_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (F28) WKUP_GPIO0_7.WKUP_UART0_RTSn */
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */
 		>;
-- 
2.34.1



From mripard at kernel.org  Mon Feb 12 02:01:07 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 11:01:07 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add
 Broadcast RGB property
In-Reply-To: <20240209203435.GB996172@toolbox>
References: <20231207-kms-hdmi-connector-state-v5-0-6538e19d634d@kernel.org>
 <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
Message-ID: <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>

On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > Hi,
> > > > > > 
> > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > >  /**
> > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > >   *
> > > > > > > > > + * Broadcast RGB
> > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > + *
> > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > + *
> > > > > > > > > + *      Automatic:
> > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > + *
> > > > > > > > > + *      Full:
> > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > + *
> > > > > > > > > + *      Limited 16:235:
> > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > + *
> > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > + *
> > > > > > > > 
> > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > different things being affected:
> > > > > > > > 
> > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > 2. The color pipeline processing
> > > > > > > > 
> > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > 
> > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > 
> > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > signalling, what happens?
> > > > > > > 
> > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > YCbCr?
> > > > > > 
> > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > vc4 will follow the value of the property.
> > > > > 
> > > > > The property is literally called "Broadcast *RGB*".
> > > > > That should explain why it's only affecting RGB.
> > > > 
> > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > to make names inconsistent too, that's fine and not an argument in
> > > > itself.
> > > > 
> > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > to enable it.
> > > > 
> > > > vc4 supports it.
> > > 
> > > Someone implemented it incorrectly then.
> > 
> > Incorrectly according to what documentation / specification? I'm sorry,
> > but I find it super ironic that i915 gets to do its own thing, not
> > document any of it, and when people try to clean things up they get told
> > that we got it all wrong.
> 
> FWIW, this was an i915 property and if another driver uses the same
> property name it must have the same behavior. Yes, it isn't standardized
> and yes, it's not documented (hence this effort here) but it's still on
> vc4 to make the property compatible.

How is it not compatible? It's a superset of what i915 provides, but
it's strictly compatible with it.

I would argue that i915 is the broken one since userspace could force a
full range output, but since the driver takes the YUV vs RGB decision
itself and only supports limited range for YUV, the driver would
effectively ignore that user-space property, without the user-space
being able to tell it was ignored in the first place.

> Trying to make the property handle YCbCr is very much in the "let's try
> to fix the property" territory that I want to avoid, so I'm in favor of
> adjusting vc4.

Breaking the ABI in the process. For something that is explicitly
supported by the spec, the driver, and the hardware. On a property that
never said it wasn't meant to be used that way, and with semantics based
on a driver that never provided a way to check those restrictions in the
first place.

And it's not like i915 is going to use that code anyway.

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/20240212/d96b2f9b/attachment.sig>

From ckeepax at opensource.cirrus.com  Mon Feb 12 02:02:17 2024
From: ckeepax at opensource.cirrus.com (Charles Keepax)
Date: Mon, 12 Feb 2024 10:02:17 +0000
Subject: [PATCH] clk: constify the of_phandle_args argument of
 of_clk_provider
In-Reply-To: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
References: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
Message-ID: <ZcnsqaIftZXcNaUA@ediswmail9.ad.cirrus.com>

On Thu, Feb 08, 2024 at 05:37:10PM +0100, Krzysztof Kozlowski wrote:
> None of the implementations of the get() and get_hw() callbacks of
> "struct of_clk_provider" modify the contents of received of_phandle_args
> pointer.  They treat it as read-only variable used to find the clock to
> return.  Make obvious that implementations are not supposed to modify
> the of_phandle_args, by making it a pointer to const.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>  drivers/clk/clk-lochnagar.c                   |  2 +-

For the Lochnagar bits:

Reviewed-by: Charles Keepax <ckeepax at opensource.cirrus.com>

Thanks,
Charles


From angelogioacchino.delregno at collabora.com  Mon Feb 12 02:15:37 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 12 Feb 2024 11:15:37 +0100
Subject: [PATCH v2 2/2] usb: mtu3: Add MT8195 MTU3 ip-sleep wakeup support
In-Reply-To: <0f96aac2ee16c31808f22853fdf746678f5284e8.camel@mediatek.com>
References: <20240122111809.148546-1-angelogioacchino.delregno@collabora.com>
 <20240122111809.148546-2-angelogioacchino.delregno@collabora.com>
 <0f96aac2ee16c31808f22853fdf746678f5284e8.camel@mediatek.com>
Message-ID: <6ccaba64-4bbe-4710-9fee-eaf31c0485b8@collabora.com>

Il 04/02/24 07:03, Chunfeng Yun (???) ha scritto:
> On Mon, 2024-01-22 at 12:18 +0100, AngeloGioacchino Del Regno wrote:
>> Add support for the ip-sleep wakeup functionality on the three MTU3
>> controllers found on the MT8195 SoC.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <
>> angelogioacchino.delregno at collabora.com>
>> ---
>>
>> Changes in v2:
>>   - Dropped unused definition for WC0_IS_EN_P1_95
>>
>>   drivers/usb/mtu3/mtu3_host.c | 30 ++++++++++++++++++++++++++++++
>>   1 file changed, 30 insertions(+)
>>
>> diff --git a/drivers/usb/mtu3/mtu3_host.c
>> b/drivers/usb/mtu3/mtu3_host.c
>> index 9f2be22af844..7c657ea2dabd 100644
>> --- a/drivers/usb/mtu3/mtu3_host.c
>> +++ b/drivers/usb/mtu3/mtu3_host.c
>> @@ -34,6 +34,18 @@
>>   #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 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)
>> @@ -44,6 +56,9 @@ enum ssusb_uwk_vers {
>>   	SSUSB_UWK_V2,
>>   	SSUSB_UWK_V1_1 = 101,	/* specific revision 1.01 */
>>   	SSUSB_UWK_V1_2,		/* specific revision 1.02 */
>> +	SSUSB_UWK_V1_3,		/* mt8195 IP0 */
>> +	SSUSB_UWK_V1_5 = 105,	/* mt8195 IP2 */
>> +	SSUSB_UWK_V1_6,		/* mt8195 IP3 */
>>   };
>>   
>>   /*
>> @@ -70,6 +85,21 @@ static void ssusb_wakeup_ip_sleep_set(struct
>> ssusb_mtk *ssusb, bool enable)
>>   		msk = WC0_SSUSB0_CDEN | WC0_IS_SPM_EN;
>>   		val = enable ? msk : 0;
>>   		break;
>> +	case SSUSB_UWK_V1_3:
>> +		reg = ssusb->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_5:
>> +		reg = ssusb->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 = ssusb->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 = ssusb->uwk_reg_base + PERI_SSUSB_SPM_CTRL;
>>   		msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN;
> 
> which project will use ip-sleep wakeup for mt8195? only use device
> mode?
> 
> As I know, when use upstream code to support dual-role mode on mt8195,
> there is a bug caused by hw limitation;
> 
> 

This is required because:
  1. The device tree nodes for MT8195 were wrong (now they're correct), as in,
     there are three MTU3 controllers that must be described, as the device tree
     provides a description of the hardware, not a partial description of whatever
     one machine wants to use; and
  2. When the description of the hardware in DT is correct, even if Chromebooks are
     declaring dr_mode = "host", the IP sleep must come from MTU3 - otherwise there
     will be issues when trying to enter system sleep (as the system will be woken
     up immediately after trying to go to suspend); and
  3. Upstream does support the Genio 1200 EVK, and I'm also introducing a new board
     that is similar to that (Radxa NIO12L).

Besides, which bug are you talking about?

At least on Chromebooks, everything seems to be working just fine; maybe that's
because, on Cherry, dr_mode is forced to host.

Regards,
Angelo


From andre.draszik at linaro.org  Mon Feb 12 02:17:48 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Mon, 12 Feb 2024 10:17:48 +0000
Subject: [PATCH] arm64: dts: exynos: gs101: add stable i2c aliases for
 gs101-oriole
In-Reply-To: <170737972037.52344.9107022607101399076.b4-ty@linaro.org>
References: <20240130233700.2287442-1-andre.draszik@linaro.org>
	 <170737972037.52344.9107022607101399076.b4-ty@linaro.org>
Message-ID: <5972b6a4ae8669e2a9e872278b740b182217906b.camel@linaro.org>

Hi Krzysztof,

On Thu, 2024-02-08 at 09:08 +0100, Krzysztof Kozlowski wrote:
> 
> On Tue, 30 Jan 2024 23:37:00 +0000, Andr? Draszik wrote:
> > Now that we have more than i2c interface, add aliases to ensure
> > deterministic bus number assignment.
> > 
> > So as to keep compatibility with existing Pixel userspace builds, use
> > the same bus numbers for hsi2c_8 and hsi2c_12 as the downstream
> > drivers with the intention to eventually add all the earlier busses as
> > well.
> > 
> > [...]
> 
> Applied, thanks!
> 
> [1/1] arm64: dts: exynos: gs101: add stable i2c aliases for gs101-oriole
> ????? https://git.kernel.org/krzk/linux/c/72ccd925dcbd2ad6935a4874679b6cf5b3de7156

Is it too late to ask for this patch to be dropped please? It appears
downstream has just changed all their aliases on Friday, whereas the
point of this patch was to keep things aligned.

I won't post anything similar until we start integrating with Android/AOSP
at some point in the future.


Thanks,
Andre'



From krzysztof.kozlowski at linaro.org  Mon Feb 12 02:23:02 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 11:23:02 +0100
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
Message-ID: <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>

On 08/02/2024 11:43, Lee Jones wrote:
> On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
>> Convert the atmel,hlcdc binding to DT schema format.
>>
>> Align clocks and clock-names properties to clearly indicate that the LCD
>> controller expects lvds_pll_clk when interfaced with the lvds display. This
>> alignment with the specific hardware requirements ensures accurate device tree
>> configuration for systems utilizing the HLCDC IP.
>>
>> [...]
> 
> Applied, thanks!
> 
> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
>       commit: cb946db1335b599ece363d33966bf653ed0fa58a
> 

Next is still failing.

Dharma,
You must explain and clearly mark dependencies between patches.

Lee,
Can you pick up two previous patches as well?

Best regards,
Krzysztof



From kvalo at kernel.org  Mon Feb 12 02:24:34 2024
From: kvalo at kernel.org (Kalle Valo)
Date: Mon, 12 Feb 2024 12:24:34 +0200
Subject: [PATCH v4] dt-bindings: net: wireless: mt76: add interrupts
 description for MT7986
In-Reply-To: <03d80cad-b72b-44d7-b726-cd8e3d4f81a9@gmail.com>
 (=?utf-8?Q?=22Rafa=C5=82=09Mi=C5=82ecki=22's?= message of "Mon, 12 Feb 2024
 08:20:56 +0100")
References: <20231221032648.641-1-chui-hao.chiu@mediatek.com>
	<03d80cad-b72b-44d7-b726-cd8e3d4f81a9@gmail.com>
Message-ID: <87o7cmou8t.fsf@kernel.org>

Rafa? Mi?ecki <zajec5 at gmail.com> writes:

> On 21.12.2023 04:26, Peter Chiu wrote:
>> The mt7986 can support four interrupts to distribute the interrupts
>> to different CPUs.
>
> Can we have this patch picked up, please? Felix? Kalle?

Felix has applied this to this tree:

https://github.com/nbd168/wireless/commit/26b98d08fda9ebef33c5eb3e1a6a14be64358caf

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


From david at redhat.com  Mon Feb 12 02:26:12 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 11:26:12 +0100
Subject: [PATCH v7 0/4] kvm: arm64: allow the VM to select DEVICE_* and
 NORMAL_NC for IO memory
In-Reply-To: <20240211174705.31992-1-ankita@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
Message-ID: <aa6c1708-d6ac-46f7-b7ab-e97a273a90c2@redhat.com>

On 11.02.24 18:47, ankita at nvidia.com wrote:
> From: Ankit Agrawal <ankita at nvidia.com>
> 

Hi,

> Currently, KVM for ARM64 maps at stage 2 memory that is considered device
> with DEVICE_nGnRE memory attributes; this setting overrides (per
> ARM architecture [1]) any device MMIO mapping present at stage 1,
> resulting in a set-up whereby a guest operating system cannot
> determine device MMIO mapping memory attributes on its own but
> it is always overridden by the KVM stage 2 default.
> 
> This set-up does not allow guest operating systems to select device
> memory attributes independently from KVM stage-2 mappings
> (refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
> which turns out to be an issue in that guest operating systems
> (e.g. Linux) may request to map devices MMIO regions with memory
> attributes that guarantee better performance (e.g. gathering
> attribute - that for some devices can generate larger PCIe memory
> writes TLPs) and specific operations (e.g. unaligned transactions)
> such as the NormalNC memory type.
> 
> The default device stage 2 mapping was chosen in KVM for ARM64 since
> it was considered safer (i.e. it would not allow guests to trigger
> uncontained failures ultimately crashing the machine) but this
> turned out to be asynchronous (SError) defeating the purpose.
> 
> For these reasons, relax the KVM stage 2 device memory attributes
> from DEVICE_nGnRE to Normal-NC.
> 
> Generalizing to other devices may be problematic, however. E.g.
> GICv2 VCPU interface, which is effectively a shared peripheral, can
> allow a guest to affect another guest's interrupt distribution. Hence
> limit the change to VFIO PCI as caution. This is achieved by
> making the VFIO PCI core module set a flag that is tested by KVM
> to activate the code. This could be extended to other devices in
> the future once that is deemed safe.

I still have to digest some of the stuff I learned about this issue, 
please bear with me :)

(1) PCI BARs might contain mixtures of RAM and MMIO, the exact 
locations/semantics within a BAR are only really known to the actual 
device driver.

We must not unconditionally map PFNs "the wrong way", because it can 
have undesired side effects. Side effects might include 
read-speculation, that can be very problematic with MMIO regions.

The safe way (for the host) is DEVICE_nGnRE. But that is actually 
problematic for performance (where we want WC?) and unaligned accesses 
(where we want NC?).

We can trigger both cases right now inside VMs, where we want the device 
driver to actually make the decision.


(2) For a VM, that device driver lives inside the VM, for DPDK and 
friends, it lives in user space. They have this information.

We only focus here on optimizing (fixing?) the mapping for VMs, DPDK is 
out of the picture. So we want to allow the VM to achieve a WC/NC 
mapping by using a relaxed (NC) mapping in stage-1. Whatever is set in 
stage-2 wins.


(3) vfio knows whether using WC (and NC?) could be problematic, and must 
forbid it, if that is the case. There are cases where we could otherwise 
cause harm (bring down the host?). We must keep mapping the memory as 
DEVICE_nGnRE when in doubt.


Now, what the new mmap() flag does is tell the world "using the wrong 
mapping type cannot bring down the host", and KVM uses that to use a 
different mapping type (NC) in stage-1 as setup by vfio in the user 
space page tables.

I was trying to find ways of avoiding a mmap() flag and was hoping that 
we could just use a PTE bit that does not have semantics in VM_PFNMAP 
mappings. Unfortunately, arm64 does not support uffd-wp, which I had in 
mind, so it's not that easy.


Further, I was wondering if there would be a way to let DPDK similarly 
benefit, because it looks like we are happily ignoring that (I was told 
they apply some hacks to work around that).


In essence, user space knows how it will consume that memory: QEMU wants 
to mmap() it only to get it into stage-1 and not access it via the user 
page tables. DPDK wants to mmap() it to actually access it from user space.


So I am curious, is the following problematic, and why:

(a) User space tells VFIO which parts of a BAR it would like to have 
mapped differently. For QEMU, this would mean, requesting a NC mapping 
for the whole BAR. For DPDK, it could mean requesting different types 
for parts of a BAR.

(b) VFIO decides if it is safe to use a relaxed mapping. If in doubt, it 
falls back to existing (legacy) handling -- DEVICE_nGnRE.

(c) KVM simply uses the existing mapping type instead of diverging from 
the one in the user space mapping.


That would mean, that we would map NC already in QEMU. I wonder if that 
could be a problem with read speculation, even if QEMU never really 
accesses that mmap'ed region.

Something like that would of course require user space changes. Handling 
it without such changes (ignoring DPDK of course) would require some 
information exchange between KVM and vfio, like the mmap flag proposed.

-- 
Cheers,

David / dhildenb



From patchwork-bot+netdevbpf at kernel.org  Mon Feb 12 02:30:26 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Mon, 12 Feb 2024 10:30:26 +0000
Subject: [PATCH net-next v4] net: stmmac: dwmac-qcom-ethqos: Enable TBS on all
 queues but 0
In-Reply-To: <20240208231145.2732931-1-quic_abchauha@quicinc.com>
References: <20240208231145.2732931-1-quic_abchauha@quicinc.com>
Message-ID: <170773382640.15535.14931143276870991018.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by David S. Miller <davem at davemloft.net>:

On Thu,  8 Feb 2024 15:11:45 -0800 you wrote:
> TSO and TBS cannot co-exist. TBS requires special descriptor to be
> allocated at bootup. Initialising Tx queues at probe to support
> TSO and TBS can help in allocating those resources at bootup.
> 
> TX queues with TBS can support etf qdisc hw offload.
> 
> This is similar to the patch raised by NXP
> commit 3b12ec8f618e ("net: stmmac: dwmac-imx: set TSO/TBS TX queues default settings")
> 
> [...]

Here is the summary with links:
  - [net-next,v4] net: stmmac: dwmac-qcom-ethqos: Enable TBS on all queues but 0
    https://git.kernel.org/netdev/net-next/c/0918c1dcd55c

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From b-kapoor at ti.com  Mon Feb 12 02:35:08 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 16:05:08 +0530
Subject: [PATCH 0/4] arm64: dts: ti: Modify pinmux for wkup_uart0 and
 mcu_uart0
In-Reply-To: <20240212095905.1057298-1-b-kapoor@ti.com>
References: <20240212095905.1057298-1-b-kapoor@ti.com>
Message-ID: <ab894372-8212-4a29-8167-b872105db81c@ti.com>

This should have been a v2, please ignore this . I will resend.

Thanks

On 12/02/24 3:29 pm, Bhavya Kapoor wrote:
> WKUP_PADCONFIG registers for wkup_uart0 and mcu_uart0 lies under
> wkup_pmx2 for J7200. Thus, modify pinmux for both of them. Also,
> remove the redundant clock-frequency property from mcu_uart0 node.
>
> Only Tx and Rx Signal lines for wkup_uart0 are brought out on
> J721S2 Common Proc Board and J784S4 EVM, but CTS and RTS signal lines
> are not brought out. Thus, remove pinmux for CTS and RTS signal lines
> for wkup_uart0 in J721S2 and J784S4.
>
> Bhavya Kapoor (4):
>    arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for
>      wkup_uart0 and mcu_uart0
>    arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency
>      from mcu_uart0
>    arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and
>      RTS in wkup_uart0
>    arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in
>      wkup_uart0
>
>   .../boot/dts/ti/k3-j7200-common-proc-board.dts | 18 +++++++++---------
>   .../dts/ti/k3-j721s2-common-proc-board.dts     |  2 --
>   arch/arm64/boot/dts/ti/k3-j784s4-evm.dts       |  2 --
>   3 files changed, 9 insertions(+), 13 deletions(-)
>


From neil.armstrong at linaro.org  Mon Feb 12 02:37:30 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 12 Feb 2024 11:37:30 +0100
Subject: [PATCH 1/5] dt-bindings: display/msm/gmu: Document Adreno 750 GMU
In-Reply-To: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
Message-ID: <20240212-topic-sm8650-gpu-v1-1-708a40b747b5@linaro.org>

Document the Adreno 750 GMU found on the SM8650 platform.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 Documentation/devicetree/bindings/display/msm/gmu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml b/Documentation/devicetree/bindings/display/msm/gmu.yaml
index 4e1c25b42908..b3837368a260 100644
--- a/Documentation/devicetree/bindings/display/msm/gmu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml
@@ -224,6 +224,7 @@ allOf:
             enum:
               - qcom,adreno-gmu-730.1
               - qcom,adreno-gmu-740.1
+              - qcom,adreno-gmu-750.1
     then:
       properties:
         reg:

-- 
2.34.1



From neil.armstrong at linaro.org  Mon Feb 12 02:37:29 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 12 Feb 2024 11:37:29 +0100
Subject: [PATCH 0/5] drm/msm: Add support for the A750 GPU found on the
 SM8650 platform
Message-ID: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>

Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
doesn't have an HWCFG block but a separate register set.

The missing registers are added in the a6xx.xml.h file that would
require a subsequent sync and the non-existent hwcfg is handled
in a6xx_set_hwcg().

The A750 GPU info are added under the adreno_is_a750() macro and
the ADRENO_7XX_GEN3 family id.

This adds:
- the GMU and SMMU bindings
- DRM driver changes
- DT nodes

Dependencies: None

Tested using Mesa's !26934 Merge Request [0] on the SM8650-QRD
and with kmscube & vkcube to test basic rendering.

[0] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26934

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
Neil Armstrong (5):
      dt-bindings: display/msm/gmu: Document Adreno 750 GMU
      dt-bindings: arm-smmu: Document SM8650 GPU SMMU
      drm: msm: add support for A750 GPU
      arm64: dts: qcom: sm8650: add GPU nodes
      arm64: dts: qcom: sm8650-qrd: enable GPU

 .../devicetree/bindings/display/msm/gmu.yaml       |   1 +
 .../devicetree/bindings/iommu/arm,smmu.yaml        |   7 +-
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts            |   8 +
 arch/arm64/boot/dts/qcom/sm8650.dtsi               | 169 +++++++++++++++++++++
 drivers/gpu/drm/msm/adreno/a6xx.xml.h              |   8 +
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c              |   2 +
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c              |  29 +++-
 drivers/gpu/drm/msm/adreno/adreno_device.c         |  14 ++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h            |   9 +-
 9 files changed, 241 insertions(+), 6 deletions(-)
---
base-commit: 84baf172e2fa30d6d6d0fb8ed076b47e836b74f1
change-id: 20240208-topic-sm8650-gpu-489d5e2c2b17

Best regards,
-- 
Neil Armstrong <neil.armstrong at linaro.org>



From neil.armstrong at linaro.org  Mon Feb 12 02:37:31 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 12 Feb 2024 11:37:31 +0100
Subject: [PATCH 2/5] dt-bindings: arm-smmu: Document SM8650 GPU SMMU
In-Reply-To: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
Message-ID: <20240212-topic-sm8650-gpu-v1-2-708a40b747b5@linaro.org>

Document the GPU SMMU found on the SM8650 platform.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index a4042ae24770..3ad5c850f3bf 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -93,6 +93,7 @@ properties:
               - qcom,sm8350-smmu-500
               - qcom,sm8450-smmu-500
               - qcom,sm8550-smmu-500
+              - qcom,sm8650-smmu-500
           - const: qcom,adreno-smmu
           - const: qcom,smmu-500
           - const: arm,mmu-500
@@ -508,7 +509,10 @@ allOf:
   - if:
       properties:
         compatible:
-          const: qcom,sm8550-smmu-500
+          contains:
+            enum:
+              - qcom,sm8550-smmu-500
+              - qcom,sm8650-smmu-500
     then:
       properties:
         clock-names:
@@ -544,7 +548,6 @@ allOf:
               - qcom,sdx65-smmu-500
               - qcom,sm6350-smmu-500
               - qcom,sm6375-smmu-500
-              - qcom,sm8650-smmu-500
               - qcom,x1e80100-smmu-500
     then:
       properties:

-- 
2.34.1



From neil.armstrong at linaro.org  Mon Feb 12 02:37:32 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 12 Feb 2024 11:37:32 +0100
Subject: [PATCH 3/5] drm: msm: add support for A750 GPU
In-Reply-To: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
Message-ID: <20240212-topic-sm8650-gpu-v1-3-708a40b747b5@linaro.org>

Add support for the A750 GPU found on the SM8650 platform

Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
doesn't have an HWCFG block but a separate register set.

The missing registers are added in the a6xx.xml.h file that would
require a subsequent sync and the non-existent hwcfg is handled
in a6xx_set_hwcg().

The A750 GPU info are added under the adreno_is_a750() macro and
the ADRENO_7XX_GEN3 family id.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/gpu/drm/msm/adreno/a6xx.xml.h      |  8 ++++++++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c      |  2 ++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c      | 29 ++++++++++++++++++++++++++---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++++++++++++++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h    |  9 ++++++++-
 5 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
index 863b5e3b0e67..c4db4e0c0819 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
@@ -1725,6 +1725,8 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00
 
 #define REG_A6XX_RBBM_BLOCK_SW_RESET_CMD2			0x00000046
 
+#define REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL				0x000000ad
+
 #define REG_A6XX_RBBM_CLOCK_CNTL				0x000000ae
 
 #define REG_A6XX_RBBM_CLOCK_CNTL_SP0				0x000000b0
@@ -1939,12 +1941,18 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00
 
 #define REG_A6XX_RBBM_CLOCK_HYST_HLSQ				0x0000011d
 
+#define REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD			0x0000011e
+
+#define REG_A7XX_RBBM_CGC_P2S_TRIG_CMD				0x0000011f
+
 #define REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE			0x00000120
 
 #define REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE			0x00000121
 
 #define REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE			0x00000122
 
+#define REG_A7XX_RBBM_CGC_P2S_STATUS				0x00000122
+
 #define REG_A7XX_RBBM_CLOCK_HYST2_VFD				0x0000012f
 
 #define REG_A6XX_RBBM_LPAC_GBIF_CLIENT_QOS_CNTL			0x000005ff
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 8c4900444b2c..325881d8ff08 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -842,6 +842,8 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
 		 */
 		if (adreno_is_a740(adreno_gpu))
 			chipid_min = 2;
+		else if (adreno_is_a750(adreno_gpu))
+			chipid_min = 9;
 		else
 			return -EINVAL;
 
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c0bc924cd302..472991584053 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -958,10 +958,11 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
 	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
 	const struct adreno_reglist *reg;
+	bool skip_programming = !(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu));
 	unsigned int i;
 	u32 val, clock_cntl_on, cgc_mode;
 
-	if (!adreno_gpu->info->hwcg)
+	if (skip_programming)
 		return;
 
 	if (adreno_is_a630(adreno_gpu))
@@ -982,6 +983,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 			  state ? 0x5555 : 0);
 	}
 
+	if (!adreno_gpu->info->hwcg) {
+		gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
+		gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
+
+		if (state) {
+			gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
+
+			if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
+					     val & BIT(0), 1, 10)) {
+				dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
+				return;
+			}
+
+			gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
+		}
+
+		return;
+	}
+
 	val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
 
 	/* Don't re-program the registers if they are already correct */
@@ -1239,7 +1259,9 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu)
 		count = ARRAY_SIZE(a660_protect);
 		count_max = 48;
 		BUILD_BUG_ON(ARRAY_SIZE(a660_protect) > 48);
-	} else if (adreno_is_a730(adreno_gpu) || adreno_is_a740(adreno_gpu)) {
+	} else if (adreno_is_a730(adreno_gpu) ||
+		   adreno_is_a740(adreno_gpu) ||
+		   adreno_is_a750(adreno_gpu)) {
 		regs = a730_protect;
 		count = ARRAY_SIZE(a730_protect);
 		count_max = 48;
@@ -2880,7 +2902,8 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
 
 	/* gpu->info only gets assigned in adreno_gpu_init() */
 	is_a7xx = config->info->family == ADRENO_7XX_GEN1 ||
-		  config->info->family == ADRENO_7XX_GEN2;
+		  config->info->family == ADRENO_7XX_GEN2 ||
+		  config->info->family == ADRENO_7XX_GEN3;
 
 	a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 2ce7d7b1690d..e2582c91d7e7 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -522,6 +522,20 @@ static const struct adreno_info gpulist[] = {
 		.zapfw = "a740_zap.mdt",
 		.hwcg = a740_hwcg,
 		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */
+		.family = ADRENO_7XX_GEN3,
+		.fw = {
+			[ADRENO_FW_SQE] = "gen70900_sqe.fw",
+			[ADRENO_FW_GMU] = "gmu_gen70900.bin",
+		},
+		.gmem = 3 * SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "gen70900_zap.mbn",
+		.address_space_size = SZ_16G,
 	},
 };
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index bc14df96feb0..744fa18067f8 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -48,6 +48,7 @@ enum adreno_family {
 	ADRENO_6XX_GEN4,  /* a660 family */
 	ADRENO_7XX_GEN1,  /* a730 family */
 	ADRENO_7XX_GEN2,  /* a740 family */
+	ADRENO_7XX_GEN3,  /* a750 family */
 };
 
 #define ADRENO_QUIRK_TWO_PASS_USE_WFI		BIT(0)
@@ -423,12 +424,18 @@ static inline int adreno_is_a740(struct adreno_gpu *gpu)
 	return gpu->info->chip_ids[0] == 0x43050a01;
 }
 
+static inline int adreno_is_a750(struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x43051401;
+}
+
 /* Placeholder to make future diffs smaller */
 static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
 {
 	if (WARN_ON_ONCE(!gpu->info))
 		return false;
-	return gpu->info->family == ADRENO_7XX_GEN2;
+	return gpu->info->family == ADRENO_7XX_GEN2 ||
+	       gpu->info->family == ADRENO_7XX_GEN3;
 }
 
 static inline int adreno_is_a7xx(struct adreno_gpu *gpu)

-- 
2.34.1



From neil.armstrong at linaro.org  Mon Feb 12 02:37:33 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 12 Feb 2024 11:37:33 +0100
Subject: [PATCH 4/5] arm64: dts: qcom: sm8650: add GPU nodes
In-Reply-To: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
Message-ID: <20240212-topic-sm8650-gpu-v1-4-708a40b747b5@linaro.org>

Add GPU nodes for the SM8650 platform.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/boot/dts/qcom/sm8650.dtsi | 169 +++++++++++++++++++++++++++++++++++
 1 file changed, 169 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
index c455ca4e6475..f6f9e603fb2f 100644
--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -2582,6 +2582,131 @@ tcsr: clock-controller at 1fc0000 {
 			#reset-cells = <1>;
 		};
 
+		gpu: gpu at 3d00000 {
+			compatible = "qcom,adreno-43051401", "qcom,adreno";
+			reg = <0x0 0x03d00000 0x0 0x40000>,
+			      <0x0 0x03d9e000 0x0 0x1000>,
+			      <0x0 0x03d61000 0x0 0x800>;
+			reg-names = "kgsl_3d0_reg_memory",
+				    "cx_mem",
+				    "cx_dbgc";
+
+			interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+
+			iommus = <&adreno_smmu 0 0x0>,
+				 <&adreno_smmu 1 0x0>;
+
+			operating-points-v2 = <&gpu_opp_table>;
+
+			interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>;
+			interconnect-names = "gfx-mem";
+
+			qcom,gmu = <&gmu>;
+
+			status = "disabled";
+
+			zap-shader {
+				memory-region = <&gpu_micro_code_mem>;
+			};
+
+			/* Speedbin needs more work on A740+, keep only lower freqs */
+			gpu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-680000000 {
+					opp-hz = /bits/ 64 <680000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+				};
+
+				opp-629000000 {
+					opp-hz = /bits/ 64 <629000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+				};
+
+				opp-578000000 {
+					opp-hz = /bits/ 64 <578000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+				};
+
+				opp-500000000 {
+					opp-hz = /bits/ 64 <500000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+				};
+
+				opp-422000000 {
+					opp-hz = /bits/ 64 <422000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+				};
+
+				opp-366000000 {
+					opp-hz = /bits/ 64 <366000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+				};
+
+				opp-310000000 {
+					opp-hz = /bits/ 64 <310000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+				};
+
+				opp-231000000 {
+					opp-hz = /bits/ 64 <231000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+				};
+			};
+		};
+
+		gmu: gmu at 3d6a000 {
+			compatible = "qcom,adreno-gmu-750.1", "qcom,adreno-gmu";
+			reg = <0x0 0x03d6a000 0x0 0x35000>,
+			      <0x0 0x03d50000 0x0 0x10000>,
+			      <0x0 0x0b280000 0x0 0x10000>;
+			reg-names = "gmu", "rscc", "gmu_pdc";
+
+			interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hfi", "gmu";
+
+			clocks = <&gpucc GPU_CC_AHB_CLK>,
+				 <&gpucc GPU_CC_CX_GMU_CLK>,
+				 <&gpucc GPU_CC_CXO_CLK>,
+				 <&gcc GCC_DDRSS_GPU_AXI_CLK>,
+				 <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gpucc GPU_CC_HUB_CX_INT_CLK>,
+				 <&gpucc GPU_CC_DEMET_CLK>;
+			clock-names = "ahb",
+				      "gmu",
+				      "cxo",
+				      "axi",
+				      "memnoc",
+				      "hub",
+				      "demet";
+
+			power-domains = <&gpucc GPU_CX_GDSC>,
+					<&gpucc GPU_GX_GDSC>;
+			power-domain-names = "cx",
+					     "gx";
+
+			iommus = <&adreno_smmu 5 0x0>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			operating-points-v2 = <&gmu_opp_table>;
+
+			gmu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-625000000 {
+					opp-hz = /bits/ 64 <625000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+				};
+
+				opp-260000000 {
+					opp-hz = /bits/ 64 <260000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+				};
+			};
+		};
+
 		gpucc: clock-controller at 3d90000 {
 			compatible = "qcom,sm8650-gpucc";
 			reg = <0 0x03d90000 0 0xa000>;
@@ -2595,6 +2720,50 @@ gpucc: clock-controller at 3d90000 {
 			#power-domain-cells = <1>;
 		};
 
+		adreno_smmu: iommu at 3da0000 {
+			compatible = "qcom,sm8650-smmu-500", "qcom,adreno-smmu",
+				     "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x03da0000 0x0 0x40000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <1>;
+			interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 659 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 661 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 664 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 668 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 699 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+				 <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+				 <&gpucc GPU_CC_AHB_CLK>;
+			clock-names = "hlos",
+				      "bus",
+				      "iface",
+				      "ahb";
+			power-domains = <&gpucc GPU_CX_GDSC>;
+			dma-coherent;
+		};
+
 		ipa: ipa at 3f40000 {
 			compatible = "qcom,sm8650-ipa", "qcom,sm8550-ipa";
 

-- 
2.34.1



From neil.armstrong at linaro.org  Mon Feb 12 02:37:34 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 12 Feb 2024 11:37:34 +0100
Subject: [PATCH 5/5] arm64: dts: qcom: sm8650-qrd: enable GPU
In-Reply-To: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
Message-ID: <20240212-topic-sm8650-gpu-v1-5-708a40b747b5@linaro.org>

Add path of the GPU firmware for the SM8650-QRD board

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
index 8515498553bf..7151f3dc67c4 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
@@ -525,6 +525,14 @@ &ipa {
 	status = "okay";
 };
 
+&gpu {
+	status = "okay";
+
+	zap-shader {
+		firmware-name = "qcom/sm8650/gen70900_zap.mbn";
+	};
+};
+
 &mdss {
 	status = "okay";
 };

-- 
2.34.1



From geert at linux-m68k.org  Mon Feb 12 02:38:51 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 12 Feb 2024 11:38:51 +0100
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth`` property
In-Reply-To: <0ac8d573-6486-458d-afb9-090b5f8d4a21@linaro.org>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
 <20240208135045.3728927-2-tudor.ambarus@linaro.org> <20240208-grating-legwarmer-0a04cfb04d61@spud>
 <c2b08463-cb13-4e9b-8797-8ebcf1047f66@linaro.org> <20240209-chest-sleet-a119fc3d4243@spud>
 <0ac8d573-6486-458d-afb9-090b5f8d4a21@linaro.org>
Message-ID: <CAMuHMdXEKecx-wQCSzqmRr6af2AUOnoFhfD2JLx28n8OYnvzGw@mail.gmail.com>

Hi Tudor,

On Fri, Feb 9, 2024 at 5:55?PM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
> On 2/9/24 16:21, Conor Dooley wrote:
> > On Fri, Feb 09, 2024 at 01:56:56PM +0000, Tudor Ambarus wrote:
> >> On 2/8/24 18:24, Conor Dooley wrote:
> >>> On Thu, Feb 08, 2024 at 01:50:34PM +0000, Tudor Ambarus wrote:
> >>>> There are instances of the same IP that are configured by the integrator
> >>>> with different FIFO depths. Introduce the fifo-depth property to allow
> >>>> such nodes to specify their FIFO depth.
> >>>>
> >>>> We haven't seen SPI IPs with different FIFO depths for RX and TX, thus
> >>>> introduce a single property.
> >>>
> >>> Some citation attached to this would be nice. "We haven't seen" offers
> >>> no detail as to what IPs that allow this sort of configuration of FIFO
> >>> size that you have actually checked.
> >>>
> >>> I went and checked our IP that we use in FPGA fabric, which has a
> >>> configurable fifo depth. It only has a single knob for both RX and TX
> >>> FIFOs. The Xilinx xps spi core also has configurable FIFOs, but again RX
> >>> and TX sizes are tied there. At least that's a sample size of three.
> >>>
> >>> One of our guys is working on support for the IP I just mentioned and
> >>> would be defining a vendor property for this, so
> >>> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> >>>
> >>
> >> Thanks, Conor. I had in mind that SPI has a shift register and it's
> >> improbable to have different FIFO depths for RX and TX.
> >
> > IDK, but I've learned to expect the unexpectable, especially when it
> > comes to the IPs intended for use in FPGAs.
> >
> >> At least I don't
> >> see how it would work, I guess it will use the minimum depth between the
> >> two?
> >
> > I'm not really sure how it would work other than that in the general
> > case, but some use case specific configuration could work, but I do
> > agree that it is
> >
> >> I grepped by "fifo" in the spi bindings and I now see that renesas is
> >> using dedicated properties for RX and TX, but I think that there too the
> >> FIFOs have the same depths. Looking into drivers/spi/spi-sh-msiof.c I
> >> see that the of_device_id.data contains 64 bytes FIFOs for RX and TX,
> >> regardless of the compatible.
> >>
> >> Geert, any idea if the FIFO depths can differ for RX and TX in
> >> spi-sh-msiof.c?

See my other email
https://lore.kernel.org/all/CAMuHMdU_Hx9PLmHf2Xm1KKTy_OF-TeCv7SzmA5CZWz+PLkbAGA at mail.gmail.com

Note that at one point we did have 64/256 in the driver, but that was
changed in commit fe78d0b7691c0274 ("spi: sh-msiof: Fix FIFO size to
64 word from 256 word").  Diving into the discussion around that patch,
there seem to be two factors at play:
  1. Actual FIFO size,
  2. Maximum transfer size per block
     (up to 2 blocks on R-Car, up to 4 blocks on SH(-Mobile)).
As the driver supports only a single block, it should be limited to
64 on R-Car Gen2/3.  R-Car Gen4 claims to have widened the register
bit field for the maximum transfer size per block, so 256 might be
possible there...

> >> Anyway, even if there are such imbalanced architectures, I guess we can
> >> consider them when/if they appear? (add rx/tx-fifo-depth dt properties)
> >
> > I think so.
> >
> >> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
> >> Override the default TX fifo size.  Unit is words.  Ignored if 0.
> >> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
> >> renesas,rx-fifo-size:
> >> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
> >> Override the default RX fifo size.  Unit is words.  Ignored if 0.
> >
> > These renesas ones seemed interesting at first glance due to these
> > comments, but what's missed by grep the is "deprecated" marking on
> > these. They seem to have been replaced by soc-specific compatibles.
>
> In the driver the renesas,{rx,tx}-fifo-size properties still have the
> highest priority:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git/tree/drivers/spi/spi-sh-msiof.c#n1350
>
> Maybe something for Geert, as I see he was the one marking these
> properties as deprecated. I guess he forgot to update the driver.
>
> Anyway, I think we shall be fine, even if we don't hear from Geert.

The renesas,{rx,tx}-fifo-size properties date back to the early days
of DT an ARM, when it was assumed that slightly different versions of
IP cores could be handled well using a single common compatible value,
and properties describing the (few) differences.  The pitfall here
is the "few differences": too many times people discovered later that
there were more differences, needing more properties, and complicating
backwards-compatibility.

Hence the handling of different FIFO sizes was moved to the driver based
on compatible values, and the renesas,{rx,tx}-fifo-size properties were
deprecated.  See commit beb74bb0875579c4 ("spi: sh-msiof: Add support
for R-Car H2 and M2"), which shows that there were more changes
needed than the anticipated FIFO sizes.  And more were added later,
see later additions to sh_msiof_chipdata.

So unless it is meant for a configurable synthesizable IP core, where
this is a documented parameter of the IP core, I advise against
specifying the FIFO size(s) in DT.

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  Mon Feb 12 02:41:43 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 12 Feb 2024 11:41:43 +0100
Subject: [PATCH v1 02/18] thermal: Add new structures and
 thermal_zone_device_register()
In-Reply-To: <CAJZ5v0iYNPB2v7ZCynEOvWy+gz4DQUhuoJ8e7F1MXz13m_d7rw@mail.gmail.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
 <20240130111250.185718-3-angelogioacchino.delregno@collabora.com>
 <CAJZ5v0jzaGpK8LnsFDtjuPoURrwrUgM1Z2QfZhK_FUzDeK3wcw@mail.gmail.com>
 <e4359d2c-e686-4a97-9d21-d10908e9df61@moroto.mountain>
 <CAJZ5v0iYNPB2v7ZCynEOvWy+gz4DQUhuoJ8e7F1MXz13m_d7rw@mail.gmail.com>
Message-ID: <45422a32-de34-4de1-bcd3-5580386f27f8@collabora.com>

Il 02/02/24 18:13, Rafael J. Wysocki ha scritto:
> On Fri, Feb 2, 2024 at 9:47?AM Dan Carpenter <dan.carpenter at linaro.org> wrote:
>>
>> On Thu, Feb 01, 2024 at 08:24:15PM +0100, Rafael J. Wysocki wrote:
>>> On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
>>>> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
>>>> index 65d8f92a9a0d..7a540b746703 100644
>>>> --- a/include/linux/thermal.h
>>>> +++ b/include/linux/thermal.h
>>>> @@ -149,7 +149,8 @@ struct thermal_cooling_device {
>>>>                          passive trip point.
>>>>    * @need_update:       if equals 1, thermal_zone_device_update needs to be invoked.
>>>>    * @ops:       operations this &thermal_zone_device supports
>>>> - * @tzp:       thermal zone parameters
>>>> + * @tzp:               Thermal zone parameters
>>>> + * @tgp:               Thermal zone governor parameters
>>>>    * @governor:  pointer to the governor for this thermal zone
>>>>    * @governor_data:     private pointer for governor data
>>>>    * @thermal_instances: list of &struct thermal_instance of this thermal zone
>>>> @@ -184,7 +185,8 @@ struct thermal_zone_device {
>>>>          int prev_high_trip;
>>>>          atomic_t need_update;
>>>>          struct thermal_zone_device_ops *ops;
>>>> -       struct thermal_zone_params *tzp;
>>>> +       struct thermal_zone_platform_params *tzp;
>>>> +       struct thermal_governor_params *tgp;
>>>
>>> I agree with doing a split here, but I'm not sure about moving items
>>> from the arg list to struct thermal_zone_platform_params (as mentioned
>>> above).
>>>
>>> Also the naming is quite inconsistent.  IMO it would be better to call
>>> the first pointer "tzpp", rename struct thermal_governor_params to
>>> struct thermal_zone_governor_params and call the second pointer
>>> "tzgp".
>>>
>>
>> The names "tzgp" and "tzpp" look almost identical at first glance.
>> Could we increase the hamming distance somehow?
> 
> Good point.
> 
> They may as well be gov_params and platform_params AFAIAC.

I'm more for gov_params and zone_params, as the thermal_zone_platform_params is
supposed to get renamed to struct thermal_zone_params in part 2.

Anything against that?

Cheers,
Angelo


From konrad.dybcio at linaro.org  Mon Feb 12 02:42:46 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 12 Feb 2024 11:42:46 +0100
Subject: [PATCH 1/5] dt-bindings: display/msm/gmu: Document Adreno 750 GMU
In-Reply-To: <20240212-topic-sm8650-gpu-v1-1-708a40b747b5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
 <20240212-topic-sm8650-gpu-v1-1-708a40b747b5@linaro.org>
Message-ID: <1a7d7283-1437-46f5-8983-bd551f5a9801@linaro.org>

On 12.02.2024 11:37, Neil Armstrong wrote:
> Document the Adreno 750 GMU found on the SM8650 platform.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>

Konrad


From b-kapoor at ti.com  Mon Feb 12 02:44:13 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 16:14:13 +0530
Subject: [RESEND PATCH v2 0/4] arm64: dts: ti: Modify pinmux for wkup_uart0 and mcu_uart0
Message-ID: <20240212104417.1058993-1-b-kapoor@ti.com>

WKUP_PADCONFIG registers for wkup_uart0 and mcu_uart0 lies under
wkup_pmx2 for J7200. Thus, modify pinmux for both of them. Also,
remove the redundant clock-frequency property from mcu_uart0 node.

Only Tx and Rx Signal lines for wkup_uart0 are brought out on
J721S2 Common Proc Board and J784S4 EVM, but CTS and RTS signal lines
are not brought out. Thus, remove pinmux for CTS and RTS signal lines
for wkup_uart0 in J721S2 and J784S4.

v1 Link : https://lore.kernel.org/all/20240208110602.931573-1-b-kapoor at ti.com/

Changelog v1->v2:
 - Divided Pinmux and clock frequency patch(1/3) for J7200 into 2 patches
 - Change commit message to include wkup_uart0 for referring to the instance

Rebased to 20240212

Bhavya Kapoor (4):
  arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for
    wkup_uart0 and mcu_uart0
  arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency
    from mcu_uart0
  arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and
    RTS in wkup_uart0
  arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in
    wkup_uart0

 .../boot/dts/ti/k3-j7200-common-proc-board.dts | 18 +++++++++---------
 .../dts/ti/k3-j721s2-common-proc-board.dts     |  2 --
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts       |  2 --
 3 files changed, 9 insertions(+), 13 deletions(-)

-- 
2.34.1



From b-kapoor at ti.com  Mon Feb 12 02:44:14 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 16:14:14 +0530
Subject: [RESEND PATCH v2 1/4] arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for wkup_uart0 and mcu_uart0
In-Reply-To: <20240212104417.1058993-1-b-kapoor@ti.com>
References: <20240212104417.1058993-1-b-kapoor@ti.com>
Message-ID: <20240212104417.1058993-2-b-kapoor@ti.com>

WKUP_PADCONFIG registers for wkup_uart0 and mcu_uart0 lies
under wkup_pmx2 for J7200. Thus, modify pinmux for both
of them.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 .../boot/dts/ti/k3-j7200-common-proc-board.dts  | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
index 1d8bddcae90e..160580a0584a 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -119,24 +119,25 @@ transceiver3: can-phy3 {
 };
 
 &wkup_pmx0 {
+};
+
+&wkup_pmx2 {
 	mcu_uart0_pins_default: mcu-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0xf4, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
-			J721E_WKUP_IOPAD(0xf0, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
-			J721E_WKUP_IOPAD(0xf8, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
-			J721E_WKUP_IOPAD(0xfc, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+			J721E_WKUP_IOPAD(0x90, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
+			J721E_WKUP_IOPAD(0x94, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+			J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
+			J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
 		>;
 	};
 
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0xb0, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
-			J721E_WKUP_IOPAD(0xb4, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
+			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
+			J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
 		>;
 	};
-};
 
-&wkup_pmx2 {
 	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
 		pinctrl-single,pins = <
 			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
-- 
2.34.1



From b-kapoor at ti.com  Mon Feb 12 02:44:15 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 16:14:15 +0530
Subject: [RESEND PATCH v2 2/4] arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency from mcu_uart0
In-Reply-To: <20240212104417.1058993-1-b-kapoor@ti.com>
References: <20240212104417.1058993-1-b-kapoor@ti.com>
Message-ID: <20240212104417.1058993-3-b-kapoor@ti.com>

Clock-frequency property is already present in mcu_uart0 node of the
k3-j7200-mcu-wakeup.dtsi file. Thus, remove redundant clock-frequency
property from mcu_uart0 node.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
index 160580a0584a..6593c5da82c0 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -273,7 +273,6 @@ &mcu_uart0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_uart0_pins_default>;
-	clock-frequency = <96000000>;
 };
 
 &main_uart0 {
-- 
2.34.1



From b-kapoor at ti.com  Mon Feb 12 02:44:16 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 16:14:16 +0530
Subject: [RESEND PATCH v2 3/4] arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and RTS in wkup_uart0
In-Reply-To: <20240212104417.1058993-1-b-kapoor@ti.com>
References: <20240212104417.1058993-1-b-kapoor@ti.com>
Message-ID: <20240212104417.1058993-4-b-kapoor@ti.com>

Only Tx and Rx Signal lines for wkup_uart0 are brought out on
the Common Proc Board through SoM, but CTS and RTS signal lines
are not brought on the board. Thus, remove pinmux for CTS and RTS
signal lines for wkup_uart0 in J721S2.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
index 361365bb5523..6371cb1c1fe7 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -190,8 +190,6 @@ J721S2_IOPAD(0x038, PIN_OUTPUT, 0) /* (AB28) MCASP0_ACLKX.MCAN5_TX */
 &wkup_pmx2 {
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (E25) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-			J721S2_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (F28) WKUP_GPIO0_7.WKUP_UART0_RTSn */
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */
 		>;
-- 
2.34.1



From b-kapoor at ti.com  Mon Feb 12 02:44:17 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Mon, 12 Feb 2024 16:14:17 +0530
Subject: [RESEND PATCH v2 4/4] arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in wkup_uart0
In-Reply-To: <20240212104417.1058993-1-b-kapoor@ti.com>
References: <20240212104417.1058993-1-b-kapoor@ti.com>
Message-ID: <20240212104417.1058993-5-b-kapoor@ti.com>

Only Tx and Rx Signal lines for wkup_uart0 are brought out on
the J784S4 EVM from SoC, but CTS and RTS signal lines are not
brought on the EVM. Thus, remove pinmux for CTS and RTS signal
lines for wkup_uart0 in J784S4.

Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
index 57e7cb8ea2b8..9f16642ccd5f 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -336,8 +336,6 @@ &wkup_pmx2 {
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
-			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-			J721S2_WKUP_IOPAD(0x074, PIN_INPUT, 0) /* (L36) WKUP_GPIO0_7.WKUP_UART0_RTSn */
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_INPUT, 0) /* (K34) WKUP_UART0_TXD */
 		>;
-- 
2.34.1



From gregkh at linuxfoundation.org  Mon Feb 12 02:45:45 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 12 Feb 2024 11:45:45 +0100
Subject: [PATCH 0/2] ARM: struct bus_type cleanup
In-Reply-To: <20240211-bus_cleanup-rmk-v1-0-65668e578d55@marliere.net>
References: <20240211-bus_cleanup-rmk-v1-0-65668e578d55@marliere.net>
Message-ID: <2024021241-cussed-suds-ffff@gregkh>

On Sun, Feb 11, 2024 at 12:45:06PM -0300, Ricardo B. Marliere wrote:
> This series is part of an effort to cleanup the users of the driver
> core, as can be seen in many recent patches authored by Greg across the
> tree (e.g. [1]).
> 
> ---
> [1]: https://lore.kernel.org/lkml/?q=f%3Agregkh%40linuxfoundation.org+s%3A%22make%22+and+s%3A%22const%22
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
> 

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From gregkh at linuxfoundation.org  Mon Feb 12 02:46:02 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 12 Feb 2024 11:46:02 +0100
Subject: [PATCH 0/2] firmware: struct bus_type cleanup
In-Reply-To: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
References: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
Message-ID: <2024021257-anchovy-enlighten-7a2a@gregkh>

On Sun, Feb 11, 2024 at 12:51:28PM -0300, Ricardo B. Marliere wrote:
> This series is part of an effort to cleanup the users of the driver
> core, as can be seen in many recent patches authored by Greg across the
> tree (e.g. [1]).
> 
> ---
> [1]: https://lore.kernel.org/lkml/?q=f%3Agregkh%40linuxfoundation.org+s%3A%22make%22+and+s%3A%22const%22
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From konrad.dybcio at linaro.org  Mon Feb 12 02:46:15 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 12 Feb 2024 11:46:15 +0100
Subject: [PATCH 3/5] drm: msm: add support for A750 GPU
In-Reply-To: <20240212-topic-sm8650-gpu-v1-3-708a40b747b5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
 <20240212-topic-sm8650-gpu-v1-3-708a40b747b5@linaro.org>
Message-ID: <b5d76a25-045a-4acd-ad20-d28855b40222@linaro.org>

On 12.02.2024 11:37, Neil Armstrong wrote:
> Add support for the A750 GPU found on the SM8650 platform
> 
> Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
> doesn't have an HWCFG block but a separate register set.
> 
> The missing registers are added in the a6xx.xml.h file that would
> require a subsequent sync and the non-existent hwcfg is handled
> in a6xx_set_hwcg().

These should also be submitted to mesa to make sure the next header sync
doesn't wipe them

[...]

> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -958,10 +958,11 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>  	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>  	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
>  	const struct adreno_reglist *reg;
> +	bool skip_programming = !(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu));

is_a750?

>  	unsigned int i;
>  	u32 val, clock_cntl_on, cgc_mode;
>  
> -	if (!adreno_gpu->info->hwcg)
> +	if (skip_programming)
>  		return;
>  
>  	if (adreno_is_a630(adreno_gpu))
> @@ -982,6 +983,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>  			  state ? 0x5555 : 0);
>  	}
>  
> +	if (!adreno_gpu->info->hwcg) {

I don't think this block of code is reachable now, no?

Maybe remove the skip_programming and if_a750 here?

> +		gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
> +		gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
> +
> +		if (state) {
> +			gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
> +
> +			if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
> +					     val & BIT(0), 1, 10)) {

We should define that bit name (the err suggests it's
REG_A7XX_RBBM_GCC_P2S_STATUS_TXDONE or so)

[...]

> +static inline int adreno_is_a750(struct adreno_gpu *gpu)
> +{
> +	return gpu->info->chip_ids[0] == 0x43051401;
> +}
> +
>  /* Placeholder to make future diffs smaller */

Please also remove this comment now that it's invalid

Konrad


From jszhang at kernel.org  Mon Feb 12 02:34:36 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Mon, 12 Feb 2024 18:34:36 +0800
Subject: [PATCH v3 1/2] dt-bindings: arm: sunxi: Add Sipeed Longan Module
 3H and Longan Pi 3H
In-Reply-To: <7ee6df91-76fa-44e8-ab81-fd4b63b58ce9@linaro.org>
References: <20240211081739.395-1-jszhang@kernel.org>
 <20240211081739.395-2-jszhang@kernel.org>
 <7ee6df91-76fa-44e8-ab81-fd4b63b58ce9@linaro.org>
Message-ID: <Zcn0POS-4BFGlRm9@xhacker>

On Sun, Feb 11, 2024 at 05:29:32PM +0100, Krzysztof Kozlowski wrote:
> On 11/02/2024 09:17, Jisheng Zhang wrote:
> > Add name & compatible for the Sipeed Longan Module 3H and Longan PI 3H
> > board.
> > 
> > Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> > Reviewed-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> 
> This is a friendly reminder during the review process.

Oops, I forgot to add Conor's ack...
> 
> It looks like you received a tag and forgot to add it.
> 
> If you do not know the process, here is a short explanation:
> Please add Acked-by/Reviewed-by/Tested-by tags when posting new
> versions, under or above your Signed-off-by tag. Tag is "received", when
> provided in a message replied to you on the mailing list. Tools like b4
> can help here. However, there's no need to repost patches *only* to add
> the tags. The upstream maintainer will do that for tags received on the
> version they apply.

IIRC, the b4 can only help on the latest version. If I missed the ack
in v3, the ack tag will be lost. So how to handle this case? repost or
Conor gave an ack to v3 again?

Thanks for your information.
> 
> https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577
> 
> If a tag was not added on purpose, please state why and what changed.
> Best regards,
> Krzysztof
> 


From konrad.dybcio at linaro.org  Mon Feb 12 02:50:14 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 12 Feb 2024 11:50:14 +0100
Subject: [PATCH 4/5] arm64: dts: qcom: sm8650: add GPU nodes
In-Reply-To: <20240212-topic-sm8650-gpu-v1-4-708a40b747b5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
 <20240212-topic-sm8650-gpu-v1-4-708a40b747b5@linaro.org>
Message-ID: <70caf0d0-28f5-48b9-b10e-5541488dd982@linaro.org>

On 12.02.2024 11:37, Neil Armstrong wrote:
> Add GPU nodes for the SM8650 platform.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/sm8650.dtsi | 169 +++++++++++++++++++++++++++++++++++
>  1 file changed, 169 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
> index c455ca4e6475..f6f9e603fb2f 100644
> --- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
> @@ -2582,6 +2582,131 @@ tcsr: clock-controller at 1fc0000 {
>  			#reset-cells = <1>;
>  		};
>  
> +		gpu: gpu at 3d00000 {
> +			compatible = "qcom,adreno-43051401", "qcom,adreno";
> +			reg = <0x0 0x03d00000 0x0 0x40000>,
> +			      <0x0 0x03d9e000 0x0 0x1000>,
> +			      <0x0 0x03d61000 0x0 0x800>;
> +			reg-names = "kgsl_3d0_reg_memory",
> +				    "cx_mem",
> +				    "cx_dbgc";
> +
> +			interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
> +
> +			iommus = <&adreno_smmu 0 0x0>,
> +				 <&adreno_smmu 1 0x0>;
> +
> +			operating-points-v2 = <&gpu_opp_table>;
> +
> +			interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>;
> +			interconnect-names = "gfx-mem";

ICC should be unnecessary

Konrad


From konrad.dybcio at linaro.org  Mon Feb 12 02:50:31 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 12 Feb 2024 11:50:31 +0100
Subject: [PATCH 5/5] arm64: dts: qcom: sm8650-qrd: enable GPU
In-Reply-To: <20240212-topic-sm8650-gpu-v1-5-708a40b747b5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
 <20240212-topic-sm8650-gpu-v1-5-708a40b747b5@linaro.org>
Message-ID: <8c1c8528-76c3-4f6e-8208-4dd5e45dd39e@linaro.org>

On 12.02.2024 11:37, Neil Armstrong wrote:
> Add path of the GPU firmware for the SM8650-QRD board
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>

Konrad


From rhi at pengutronix.de  Mon Feb 12 03:07:06 2024
From: rhi at pengutronix.de (Roland Hieber)
Date: Mon, 12 Feb 2024 12:07:06 +0100
Subject: MXSFB error: -ENODEV: Cannot connect bridge
In-Reply-To: <34yzygh3mbwpqr2re7nxmhyxy3s7qmqy4vhxvoyxnoguktriur@z66m7gvpqlia>
References: <34yzygh3mbwpqr2re7nxmhyxy3s7qmqy4vhxvoyxnoguktriur@z66m7gvpqlia>
Message-ID: <20240212110706.ibrreoj2wgzhltyw@pengutronix.de>

On Thu, Feb 08, 2024 at 12:58:02PM -0300, Hiago De Franco wrote:
> Hello all,
> 
> while doing some tests with kernel v6.8-rc3 and Colibri iMX7D, we
> noticed the following error:
> 
> [    0.432547] mxsfb 30730000.lcdif: error -ENODEV: Cannot connect bridge
> 
> This was introduced by commit edbbae7fba495284f72f05768696572691231558
> ("ARM: dts: imx7: add MIPI-DSI support"). This patch is routing the
> lcdif to the mipi_dsi_in_lcdif endpoint, however we do not have the DSI
> pins available in our edge connector. Instead, we use the parallel RGB
> LCD interface directly with, as example, an external LVDS transmitter:
> 
> &lcdif {
> ...
> 	status = "disabled";
> 
> 	port {
> 		lcdif_out: endpoint {
> 			remote-endpoint = <&lcd_panel_in>;
> 		};
> 	};
> };
> 
> By applying the following patch, the issue is gone and the LVDS works
> again:
> 
> diff --git a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
> index ebf7befcc11e..9c81c6baa2d3 100644
> --- a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
> +++ b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
> @@ -834,16 +834,6 @@ lcdif: lcdif at 30730000 {
>  					<&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>;
>  				clock-names = "pix", "axi";
>  				status = "disabled";
> -
> -				port {
> -					#address-cells = <1>;
> -					#size-cells = <0>;
> -
> -					lcdif_out_mipi_dsi: endpoint at 0 {
> -						reg = <0>;
> -						remote-endpoint = <&mipi_dsi_in_lcdif>;
> -					};
> -				};
>  			};
>  
>  			mipi_csi: mipi-csi at 30750000 {
> @@ -895,22 +885,6 @@ mipi_dsi: dsi at 30760000 {
>  				samsung,esc-clock-frequency = <20000000>;
>  				samsung,pll-clock-frequency = <24000000>;
>  				status = "disabled";
> -
> -				ports {
> -					#address-cells = <1>;
> -					#size-cells = <0>;
> -
> -					port at 0 {
> -						reg = <0>;
> -						#address-cells = <1>;
> -						#size-cells = <0>;
> -
> -						mipi_dsi_in_lcdif: endpoint at 0 {
> -							reg = <0>;
> -							remote-endpoint = <&lcdif_out_mipi_dsi>;
> -						};
> -					};
> -				};
>  			};
>  		};
> 
> I would like to know your opinion about this patch before sending it,
> does it makes sense for you? I understand that routing to endpoint
> should be done in the SoM device tree, so we are free to rout other
> endpoint without issues.

As far as I understood, the LCDIF -> DSI connection is always present in
the SoC. Can you overwrite the routing in your dts like this:?

    &lcdif_out_mipi_dsi {
        remote-endpoint = <&lcd_panel_in>;
    };

I'm not sure what is the best default solution here for imx7s.dtsi. Also
the labels don't work out in that case, this could be improved.

Regards,
 
 - Roland

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


From ulf.hansson at linaro.org  Mon Feb 12 03:17:03 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 12 Feb 2024 12:17:03 +0100
Subject: [PATCH 0/6] mfd: tmio: simplify header and move to platform_data
In-Reply-To: <20240209132837.GJ689448@google.com>
References: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
 <CAPDyKFpmfgwJ5dJFmORhg1tBewzhB_jrWikpX=b23r-joN91SA@mail.gmail.com> <20240209132837.GJ689448@google.com>
Message-ID: <CAPDyKFpho16DU7OorMgXDqiyfFfgM_tWu+DZZOHd0gbjtBw_Cg@mail.gmail.com>

On Fri, 9 Feb 2024 at 14:28, Lee Jones <lee at kernel.org> wrote:
>
> On Fri, 09 Feb 2024, Ulf Hansson wrote:
>
> > On Fri, 9 Feb 2024 at 02:59, Wolfram Sang
> > <wsa+renesas at sang-engineering.com> wrote:
> > >
> > > The MFD parts of the TMIO have been removed by Arnd, so that only the
> > > SD/MMC related functionality is left. Remove the outdated remains in the
> > > public header file and then move it to platform_data as the data is now
> > > specific for the SD/MMC part.
> > >
> > > Based on 6.8-rc3, build bot is happy. Branch is here:
> > >
> > > git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/sdhi/tmio-simplification
> > >
> > > I'd suggest this goes via the MFD tree, so the series would need acks
> > > from the MMC and SH maintainers. Is that okay with everyone?
> >
> > Wouldn't it be better to funnel this via the mmc tree? In that way, we
> > can easily avoid conflicts with additional renesas-mmc driver changes
> > that we have in pipe.
>
> You could say the same about changes SH, MFD and Platform Data have in
> the pipe.
>
> > Or perhaps there are other changes that make the mfd tree preferred?
>
> MFD is usually preferred since the parent device usually lives there and
> we are well accustomed to merging multi-subsystem related sets.
>
> It doesn't really matter how this is merged.  The only stipulation is
> that whoever applies the set does so on a succinct, immutable, tagged
> branch and sends out a pull-request for everyone else to pull from.

You are right.

Although, in this particular case I thought it could make better sense
to use the mmc tree, because 1) we are only removing a header file
from mfd and 2) I know we have other renesas-mmc changes in the pipe
for the next release. The point is, I wanted us to avoid the need for
using an immutable branch. But nevermind.

>
> If you want to do that, there are no complains from me.

Well, it sounds like we may need the flexibility with the immutable
branch, so I suggest we do the usual thing with the mfd tree.

Please add my ack for the mmc related changes.

[...]

Kind regards
Uffe


From krzysztof.kozlowski at linaro.org  Mon Feb 12 03:18:35 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 12:18:35 +0100
Subject: [PATCH] arm64: dts: exynos: gs101: add stable i2c aliases for
 gs101-oriole
In-Reply-To: <5972b6a4ae8669e2a9e872278b740b182217906b.camel@linaro.org>
References: <20240130233700.2287442-1-andre.draszik@linaro.org>
 <170737972037.52344.9107022607101399076.b4-ty@linaro.org>
 <5972b6a4ae8669e2a9e872278b740b182217906b.camel@linaro.org>
Message-ID: <dce39e15-32a8-482c-8751-af4a133f82d2@linaro.org>

On 12/02/2024 11:17, Andr? Draszik wrote:
> Hi Krzysztof,
> 
> On Thu, 2024-02-08 at 09:08 +0100, Krzysztof Kozlowski wrote:
>>
>> On Tue, 30 Jan 2024 23:37:00 +0000, Andr? Draszik wrote:
>>> Now that we have more than i2c interface, add aliases to ensure
>>> deterministic bus number assignment.
>>>
>>> So as to keep compatibility with existing Pixel userspace builds, use
>>> the same bus numbers for hsi2c_8 and hsi2c_12 as the downstream
>>> drivers with the intention to eventually add all the earlier busses as
>>> well.
>>>
>>> [...]
>>
>> Applied, thanks!
>>
>> [1/1] arm64: dts: exynos: gs101: add stable i2c aliases for gs101-oriole
>> ????? https://git.kernel.org/krzk/linux/c/72ccd925dcbd2ad6935a4874679b6cf5b3de7156
> 
> Is it too late to ask for this patch to be dropped please? It appears
> downstream has just changed all their aliases on Friday, whereas the
> point of this patch was to keep things aligned.
> 
> I won't post anything similar until we start integrating with Android/AOSP
> at some point in the future.

I can drop it, but the actual problem is that what if downstream keeps
changing aliases? They can do it... The aliases are not there to match
with downstream, but to have stable interface matching SCHEMATICS.

Best regards,
Krzysztof



From arnd at kernel.org  Mon Feb 12 03:19:04 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 12 Feb 2024 12:19:04 +0100
Subject: [PATCH] i2c: pasemi: split driver into two separate modules
Message-ID: <20240212111933.963985-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

On powerpc, it is possible to compile test both the new apple (arm) and
old pasemi (powerpc) drivers for the i2c hardware at the same time,
which leads to a warning about linking the same object file twice:

scripts/Makefile.build:244: drivers/i2c/busses/Makefile: i2c-pasemi-core.o is added to multiple modules: i2c-apple i2c-pasemi

Rework the driver to have an explicit helper module, letting Kbuild
take care of whether this should be built-in or a loadable driver.

Fixes: 9bc5f4f660ff ("i2c: pasemi: Split pci driver to its own file")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/i2c/busses/Makefile          | 6 ++----
 drivers/i2c/busses/i2c-pasemi-core.c | 6 ++++++
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 3757b9391e60..aa0ee8ecd6f2 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -90,10 +90,8 @@ obj-$(CONFIG_I2C_NPCM)		+= i2c-npcm7xx.o
 obj-$(CONFIG_I2C_OCORES)	+= i2c-ocores.o
 obj-$(CONFIG_I2C_OMAP)		+= i2c-omap.o
 obj-$(CONFIG_I2C_OWL)		+= i2c-owl.o
-i2c-pasemi-objs := i2c-pasemi-core.o i2c-pasemi-pci.o
-obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi.o
-i2c-apple-objs := i2c-pasemi-core.o i2c-pasemi-platform.o
-obj-$(CONFIG_I2C_APPLE)	+= i2c-apple.o
+obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi-core.o i2c-pasemi-pci.o
+obj-$(CONFIG_I2C_APPLE)		+= i2c-pasemi-core.o i2c-pasemi-platform.o
 obj-$(CONFIG_I2C_PCA_PLATFORM)	+= i2c-pca-platform.o
 obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
 obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o
diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
index 7d54a9f34c74..bd8becbdeeb2 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -369,6 +369,7 @@ int pasemi_i2c_common_probe(struct pasemi_smbus *smbus)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(pasemi_i2c_common_probe);
 
 irqreturn_t pasemi_irq_handler(int irq, void *dev_id)
 {
@@ -378,3 +379,8 @@ irqreturn_t pasemi_irq_handler(int irq, void *dev_id)
 	complete(&smbus->irq_completion);
 	return IRQ_HANDLED;
 }
+EXPORT_SYMBOL_GPL(pasemi_irq_handler);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Olof Johansson <olof at lixom.net>");
+MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver");
-- 
2.39.2



From suzuki.poulose at arm.com  Mon Feb 12 03:23:35 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 12 Feb 2024 11:23:35 +0000
Subject: [PATCH] coresight: etm4x: Set skip_power_up in etm4_init_arch_data function
In-Reply-To: <20240131105423.9519-1-quic_jinlmao@quicinc.com>
References: <20240131105423.9519-1-quic_jinlmao@quicinc.com>
Message-ID: <170773625002.2157180.12446966066185707431.b4-ty@arm.com>

On Wed, 31 Jan 2024 02:54:19 -0800, Mao Jinlong wrote:
> skip_power_up is used in etm4_init_arch_data when set lpoverride. So
> need to set the value of it before calling using it.
> 
> 

Applied, thanks!

[1/1] coresight: etm4x: Set skip_power_up in etm4_init_arch_data function
      https://git.kernel.org/coresight/c/1bbe0a247e5d

Best regards,
-- 
Suzuki K Poulose <suzuki.poulose at arm.com>


From suzuki.poulose at arm.com  Mon Feb 12 03:25:29 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 12 Feb 2024 11:25:29 +0000
Subject: [PATCH v7 00/10] Add support to configure TPDM CMB subunit
In-Reply-To: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <170773624998.2157180.11126865505279178953.b4-ty@arm.com>

On Sun, 4 Feb 2024 13:30:31 +0800, Tao Zhang wrote:
> Introduction of TPDM CMB(Continuous Multi Bit) subunit
> CMB subunit is responsible for creating a dataset element, and is also
> optionally responsible for packing it to fit multiple elements on a
> single ATB transfer if possible in the configuration. The TPDM Core
> Datapath requests timestamps be stored by the TPDA and then delivering
> ATB sized data (depending on ATB width and element size, this could
> be smaller or larger than a dataset element) to the ATB Mast FSM.
> The CMB makes trace elements in two modes. In ?continuous? mode, every
> valid data cycle creates an element. In ?trace on change? mode, when
> valid data changes on the bus, a trace element is created. In
> continuous mode, all cycles where this condition is true create trace
> elements. In trace on change mode, a data element is only when the
> previously sampled input is different from the current sampled input.
> 
> [...]

Applied, thanks!

[01/10] coresight-tpdm: Optimize the store function of tpdm simple dataset
        https://git.kernel.org/coresight/c/9f0ea8e8344b
[02/10] coresight-tpdm: Optimize the useage of tpdm_has_dsb_dataset
        https://git.kernel.org/coresight/c/f021801c418e
[03/10] dt-bindings: arm: qcom,coresight-tpdm: Add support for CMB element size
        https://git.kernel.org/coresight/c/4ed57f75898c
[04/10] coresight-tpdm: Add CMB dataset support
        https://git.kernel.org/coresight/c/a1705ffcce52
[05/10] coresight-tpda: Add support to configure CMB element
        https://git.kernel.org/coresight/c/e6d7f5252f73
[06/10] coresight-tpdm: Add support to configure CMB
        https://git.kernel.org/coresight/c/2d9ab11c262e
[07/10] coresight-tpdm: Add pattern registers support for CMB
        https://git.kernel.org/coresight/c/53d4a017a524
[08/10] coresight-tpdm: Add timestamp control register support for the CMB
        https://git.kernel.org/coresight/c/dc6ce57e2aa0
[09/10] dt-bindings: arm: qcom,coresight-tpdm: Add support for TPDM CMB MSR register
        https://git.kernel.org/coresight/c/19bfaff38457
[10/10] coresight-tpdm: Add msr register support for CMB
        https://git.kernel.org/coresight/c/8e8804145a46

Best regards,
-- 
Suzuki K Poulose <suzuki.poulose at arm.com>


From arnd at kernel.org  Mon Feb 12 03:25:27 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 12 Feb 2024 12:25:27 +0100
Subject: [PATCH] soc: fsl: dpio: fix kcalloc() argument order
Message-ID: <20240212112545.1244685-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

A previous bugfix added a call to kcalloc(), which starting in gcc-14
causes a harmless warning about the argument order:

drivers/soc/fsl/dpio/dpio-service.c: In function 'dpaa2_io_service_enqueue_multiple_desc_fq':
drivers/soc/fsl/dpio/dpio-service.c:526:29: error: 'kcalloc' sizes specified with 'sizeof' in the earlier argument and not in the later argument [-Werror=calloc-transposed-args]
  526 |         ed = kcalloc(sizeof(struct qbman_eq_desc), 32, GFP_KERNEL);
      |                             ^~~~~~
drivers/soc/fsl/dpio/dpio-service.c:526:29: note: earlier argument should specify number of elements, later size of each element

Since the two are only multiplied, the order does not change the
behavior, so just fix it now to shut up the compiler warning.

Fixes: 5c4a5999b245 ("soc: fsl: dpio: avoid stack usage warning")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/soc/fsl/dpio/dpio-service.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/fsl/dpio/dpio-service.c b/drivers/soc/fsl/dpio/dpio-service.c
index 1d2b27e3ea63..b811446e0fa5 100644
--- a/drivers/soc/fsl/dpio/dpio-service.c
+++ b/drivers/soc/fsl/dpio/dpio-service.c
@@ -523,7 +523,7 @@ int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d,
 	struct qbman_eq_desc *ed;
 	int i, ret;
 
-	ed = kcalloc(sizeof(struct qbman_eq_desc), 32, GFP_KERNEL);
+	ed = kcalloc(32, sizeof(struct qbman_eq_desc), GFP_KERNEL);
 	if (!ed)
 		return -ENOMEM;
 
-- 
2.39.2



From krzysztof.kozlowski at linaro.org  Mon Feb 12 03:25:48 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 12:25:48 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit,hd44780: drop redundant
 GPIO node
In-Reply-To: <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
Message-ID: <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>

On 12/02/2024 09:41, Geert Uytterhoeven wrote:
> Thanks for your patch!
> 
>> --- a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
>> +++ b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
>> @@ -99,17 +99,7 @@ examples:
>>      };
>>    - |
>>      #include <dt-bindings/gpio/gpio.h>
>> -    i2c {
>> -            #address-cells = <1>;
>> -            #size-cells = <0>;
>>
>> -            pcf8574: pcf8574 at 27 {
>> -                    compatible = "nxp,pcf8574";
>> -                    reg = <0x27>;
>> -                    gpio-controller;
>> -                    #gpio-cells = <2>;
>> -            };
>> -    };
> 
> This part was added delberately in commit c784e46c8445635a ("auxdisplay:
> Add I2C gpio expander example"), to aid makers who are not DT experts.
> Note that there are no other examples of this popular wiring scheme
> in upstream DTS.

Hm, I don't understand how exactly it helps. The GPIO expander has its
own example and as you pointed below, this is basically the same code,
except rw and backlight GPIOs.


> 
>>      hd44780 {
>>              compatible = "hit,hd44780";
>>              display-height-chars = <2>;
> 
> If you do want to insist on removing the i2c GPIO expander part,
> I think this node should be removed too, as it is almost identical
> to the first example.
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 

Best regards,
Krzysztof



From suzuki.poulose at arm.com  Mon Feb 12 03:27:11 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 12 Feb 2024 11:27:11 +0000
Subject: [PATCH v3 0/4] coresight: Make current W=1 warnings default
In-Reply-To: <20231123120459.287578-1-james.clark@arm.com>
References: <20231123120459.287578-1-james.clark@arm.com>
Message-ID: <170773625002.2157180.1032311578975893182.b4-ty@arm.com>

On Thu, 23 Nov 2023 12:04:55 +0000, James Clark wrote:
> Changes since v2:
> 
>   * Split code and Makefile changes
>   * Add a fix for a comment warning in etm3x
>   * Add some sparse checker fixes in coresight-cfg-afdo.c
>   * Fix the 0 instead of NULL warnings reported by kernel test robot
> 
> [...]

Now moved to coresight next branch, thanks!

[1/4] coresight: Fix uninitialized struct warnings
      https://git.kernel.org/coresight/c/8a519235c3c3
[2/4] coresight: etm3x: Fix build warning
      https://git.kernel.org/coresight/c/54daf07e6332
[3/4] coresight: Fix undeclared variable warnings from sparse checker
      https://git.kernel.org/coresight/c/a7195f3f9383
[4/4] coresight: Make current W=1 warnings default
      https://git.kernel.org/coresight/c/d999c7dd5279

Best regards,
-- 
Suzuki K Poulose <suzuki.poulose at arm.com>


From suzuki.poulose at arm.com  Mon Feb 12 03:27:51 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 12 Feb 2024 11:27:51 +0000
Subject: [PATCH v2 00/12] coresight: Separate sysfs and Perf usage and some other cleanups
In-Reply-To: <20240129154050.569566-1-james.clark@arm.com>
References: <20240129154050.569566-1-james.clark@arm.com>
Message-ID: <170773625002.2157180.12698644436434425979.b4-ty@arm.com>

On Mon, 29 Jan 2024 15:40:31 +0000, James Clark wrote:
> Changes since V1:
> 
>   * Clarify further "the selected sink" in _coresight_build_path()
>   * Move etm4x's mode to coresight device which was missing from V1
>   * Use explicit initialisers in coresight_dev_type
>   * Create functions for handling mode changes
> 
> [...]

Applied, thanks!

[01/12] coresight: Fix issue where a source device's helpers aren't disabled
        https://git.kernel.org/coresight/c/f68bbe4dcfa3
[02/12] coresight: Make language around "activated" sinks consistent
        https://git.kernel.org/coresight/c/a0fef3f05cf3
[03/12] coresight: Remove ops callback checks
        https://git.kernel.org/coresight/c/a11ebe138b8d
[04/12] coresight: Move mode to struct coresight_device
        https://git.kernel.org/coresight/c/9cae77cf23e3
[05/12] coresight: Remove the 'enable' field.
        https://git.kernel.org/coresight/c/d5e83f97eb56
[06/12] coresight: Move all sysfs code to sysfs file
        https://git.kernel.org/coresight/c/1f5149c7751c
[07/12] coresight: Remove atomic type from refcnt
        https://git.kernel.org/coresight/c/4545b38ef004
[08/12] coresight: Remove unused stubs
        https://git.kernel.org/coresight/c/053ad9ad1d13
[09/12] coresight: Add explicit member initializers to coresight_dev_type
        https://git.kernel.org/coresight/c/812265e26ed3
[10/12] coresight: Add helper for atomically taking the device
        https://git.kernel.org/coresight/c/d724f65218b9
[11/12] coresight: Add a helper for getting csdev->mode
        https://git.kernel.org/coresight/c/c95c2733e5fe
[12/12] coresight: Add helper for setting csdev->mode
        https://git.kernel.org/coresight/c/bcaabb95f0c9

Best regards,
-- 
Suzuki K Poulose <suzuki.poulose at arm.com>


From andre.draszik at linaro.org  Mon Feb 12 03:30:50 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Mon, 12 Feb 2024 11:30:50 +0000
Subject: [PATCH] arm64: dts: exynos: gs101: add stable i2c aliases for
 gs101-oriole
In-Reply-To: <dce39e15-32a8-482c-8751-af4a133f82d2@linaro.org>
References: <20240130233700.2287442-1-andre.draszik@linaro.org>
	 <170737972037.52344.9107022607101399076.b4-ty@linaro.org>
	 <5972b6a4ae8669e2a9e872278b740b182217906b.camel@linaro.org>
	 <dce39e15-32a8-482c-8751-af4a133f82d2@linaro.org>
Message-ID: <c16c1f18a8c6f33a608618d4ccf7d8c8dbb6f88b.camel@linaro.org>

On Mon, 2024-02-12 at 12:18 +0100, Krzysztof Kozlowski wrote:
> I can drop it, but the actual problem is that what if downstream keeps
> changing aliases? They can do it...

We won't care at that stage, downstream should have no reason to divert from
upstream for numbering at some point in the future.

>  The aliases are not there to match
> with downstream, but to have stable interface matching SCHEMATICS.

Except the schematics don't refer to the i2c busses by number.

Cheers,
Andre'



From suzuki.poulose at arm.com  Mon Feb 12 03:30:44 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 12 Feb 2024 11:30:44 +0000
Subject: [PATCH] coresight: make coresight_bustype const
In-Reply-To: <2024010531-tinfoil-avert-4a57@gregkh>
References: <2024010531-tinfoil-avert-4a57@gregkh>
Message-ID: <170773625003.2157180.18291020574566263083.b4-ty@arm.com>

On Fri, 5 Jan 2024 13:33:32 +0100, Greg Kroah-Hartman wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the coresight_bustype variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> 

Moved to next, thanks!

[1/1] coresight: make coresight_bustype const
      https://git.kernel.org/coresight/c/dd95255d44c0

Best regards,
-- 
Suzuki K Poulose <suzuki.poulose at arm.com>


From ricardo at marliere.net  Mon Feb 12 03:35:14 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Mon, 12 Feb 2024 08:35:14 -0300
Subject: [PATCH v2] ARM: s3c64xx: make s3c6410_subsys const
In-Reply-To: <b7726526-0b0a-4d3d-bf05-b1065d361cc2@linaro.org>
References: <20240211-bus_cleanup-arm-v2-1-3de9e8af7cbd@marliere.net>
 <b7726526-0b0a-4d3d-bf05-b1065d361cc2@linaro.org>
Message-ID: <2ezdr4px2tfzpn7ut63wdtmcb2roid4d6kpl654wwmfvkemhpq@k5hpjz74q4ho>

Hi Krzysztof,

On 12 Feb 08:31, Krzysztof Kozlowski wrote:
> On 11/02/2024 16:57, Ricardo B. Marliere wrote:
> > Since commit d492cc2573a0 ("driver core: device.h: make struct bus_type
> > a const *"), the driver core can properly handle constant struct
> > bus_type, move the s3c6410_subsys variable to be a constant structure as
> > well, placing it into read-only memory which can not be modified at
> > runtime.
> > 
> > Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> > Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> > Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
> > ---
> 
> I just noticed you sent quite the same change for the same subarch.
> Please perform changes all at once. Squashed.

Yes, sorry about that. The reason for this is that I initially started
splitting up this commit into proper submissions:

https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git/commit/?h=bus_cleanup&id=26105f537f0c60eacfeb430abd2e05d7ddcdd8aa

And only after that I started grepping the tree for the other users.

> 
> Best regards,
> Krzysztof
> 


From krzysztof.kozlowski at linaro.org  Mon Feb 12 03:40:02 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 12:40:02 +0100
Subject: [PATCH] arm64: dts: exynos: gs101: add stable i2c aliases for
 gs101-oriole
In-Reply-To: <c16c1f18a8c6f33a608618d4ccf7d8c8dbb6f88b.camel@linaro.org>
References: <20240130233700.2287442-1-andre.draszik@linaro.org>
 <170737972037.52344.9107022607101399076.b4-ty@linaro.org>
 <5972b6a4ae8669e2a9e872278b740b182217906b.camel@linaro.org>
 <dce39e15-32a8-482c-8751-af4a133f82d2@linaro.org>
 <c16c1f18a8c6f33a608618d4ccf7d8c8dbb6f88b.camel@linaro.org>
Message-ID: <67a6564a-00bb-461d-b7eb-ca169df6d251@linaro.org>

On 12/02/2024 12:30, Andr? Draszik wrote:
> On Mon, 2024-02-12 at 12:18 +0100, Krzysztof Kozlowski wrote:
>> I can drop it, but the actual problem is that what if downstream keeps
>> changing aliases? They can do it...
> 
> We won't care at that stage, downstream should have no reason to divert from
> upstream for numbering at some point in the future.

What do you mean by "no reason"? The reason is they can do whatever they
want. Some project leader says: "I want this" and they will do it. They
won't care about our upstream choice at all.

And then what, you change it again?

If downstream was caring, then they could pick as well aliases which we
already committed.

To remind: the downstream was released 3 years ago! So the downstream
DTS is long past "beta" phase and should be considered stable. If they
keep changing the aliases after three years, then they can keep doing it
for next 20 years.

Best regards,
Krzysztof



From andre.draszik at linaro.org  Mon Feb 12 03:52:58 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Mon, 12 Feb 2024 11:52:58 +0000
Subject: [PATCH] arm64: dts: exynos: gs101: add stable i2c aliases for
 gs101-oriole
In-Reply-To: <67a6564a-00bb-461d-b7eb-ca169df6d251@linaro.org>
References: <20240130233700.2287442-1-andre.draszik@linaro.org>
	 <170737972037.52344.9107022607101399076.b4-ty@linaro.org>
	 <5972b6a4ae8669e2a9e872278b740b182217906b.camel@linaro.org>
	 <dce39e15-32a8-482c-8751-af4a133f82d2@linaro.org>
	 <c16c1f18a8c6f33a608618d4ccf7d8c8dbb6f88b.camel@linaro.org>
	 <67a6564a-00bb-461d-b7eb-ca169df6d251@linaro.org>
Message-ID: <0ad3082c50e21a74de41ca9908bd53b72e1f1a9c.camel@linaro.org>

On Mon, 2024-02-12 at 12:40 +0100, Krzysztof Kozlowski wrote:
> On 12/02/2024 12:30, Andr? Draszik wrote:
> > On Mon, 2024-02-12 at 12:18 +0100, Krzysztof Kozlowski wrote:
> > > I can drop it, but the actual problem is that what if downstream keeps
> > > changing aliases? They can do it...
> > 
> > We won't care at that stage, downstream should have no reason to divert from
> > upstream for numbering at some point in the future.
> 
> What do you mean by "no reason"? The reason is they can do whatever they
> want. Some project leader says: "I want this" and they will do it. They
> won't care about our upstream choice at all.
> 
> And then what, you change it again?

As I said above, we won't care if downstream changes again at that stage, so
no, I wouldn't plan on changing again.


Cheers,
Andre'



From rafael at kernel.org  Mon Feb 12 03:57:00 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Mon, 12 Feb 2024 12:57:00 +0100
Subject: [PATCH v1 02/18] thermal: Add new structures and thermal_zone_device_register()
In-Reply-To: <45422a32-de34-4de1-bcd3-5580386f27f8@collabora.com>
References: <20240130111250.185718-1-angelogioacchino.delregno@collabora.com>
 <20240130111250.185718-3-angelogioacchino.delregno@collabora.com>
 <CAJZ5v0jzaGpK8LnsFDtjuPoURrwrUgM1Z2QfZhK_FUzDeK3wcw@mail.gmail.com>
 <e4359d2c-e686-4a97-9d21-d10908e9df61@moroto.mountain> <CAJZ5v0iYNPB2v7ZCynEOvWy+gz4DQUhuoJ8e7F1MXz13m_d7rw@mail.gmail.com>
 <45422a32-de34-4de1-bcd3-5580386f27f8@collabora.com>
Message-ID: <CAJZ5v0jyeGMKxks9bYneUbm-zWpW8u9ARXCmqY5c=TMswgFuQA@mail.gmail.com>

On Mon, Feb 12, 2024 at 11:41?AM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Il 02/02/24 18:13, Rafael J. Wysocki ha scritto:
> > On Fri, Feb 2, 2024 at 9:47?AM Dan Carpenter <dan.carpenter at linaro.org> wrote:
> >>
> >> On Thu, Feb 01, 2024 at 08:24:15PM +0100, Rafael J. Wysocki wrote:
> >>> On Tue, Jan 30, 2024 at 12:13?PM AngeloGioacchino Del Regno
> >>>> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> >>>> index 65d8f92a9a0d..7a540b746703 100644
> >>>> --- a/include/linux/thermal.h
> >>>> +++ b/include/linux/thermal.h
> >>>> @@ -149,7 +149,8 @@ struct thermal_cooling_device {
> >>>>                          passive trip point.
> >>>>    * @need_update:       if equals 1, thermal_zone_device_update needs to be invoked.
> >>>>    * @ops:       operations this &thermal_zone_device supports
> >>>> - * @tzp:       thermal zone parameters
> >>>> + * @tzp:               Thermal zone parameters
> >>>> + * @tgp:               Thermal zone governor parameters
> >>>>    * @governor:  pointer to the governor for this thermal zone
> >>>>    * @governor_data:     private pointer for governor data
> >>>>    * @thermal_instances: list of &struct thermal_instance of this thermal zone
> >>>> @@ -184,7 +185,8 @@ struct thermal_zone_device {
> >>>>          int prev_high_trip;
> >>>>          atomic_t need_update;
> >>>>          struct thermal_zone_device_ops *ops;
> >>>> -       struct thermal_zone_params *tzp;
> >>>> +       struct thermal_zone_platform_params *tzp;
> >>>> +       struct thermal_governor_params *tgp;
> >>>
> >>> I agree with doing a split here, but I'm not sure about moving items
> >>> from the arg list to struct thermal_zone_platform_params (as mentioned
> >>> above).
> >>>
> >>> Also the naming is quite inconsistent.  IMO it would be better to call
> >>> the first pointer "tzpp", rename struct thermal_governor_params to
> >>> struct thermal_zone_governor_params and call the second pointer
> >>> "tzgp".
> >>>
> >>
> >> The names "tzgp" and "tzpp" look almost identical at first glance.
> >> Could we increase the hamming distance somehow?
> >
> > Good point.
> >
> > They may as well be gov_params and platform_params AFAIAC.
>
> I'm more for gov_params and zone_params, as the thermal_zone_platform_params is
> supposed to get renamed to struct thermal_zone_params in part 2.
>
> Anything against that?

Nope, sounds good!


From rsc at runtux.com  Mon Feb 12 03:58:39 2024
From: rsc at runtux.com (Ralf Schlatterbeck)
Date: Mon, 12 Feb 2024 12:58:39 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop
 redundant GPIO node
In-Reply-To: <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
Message-ID: <20240212115837.efz73yxinkysdmgh@runtux.com>

On Mon, Feb 12, 2024 at 12:25:48PM +0100, Krzysztof Kozlowski wrote:
> 
> Hm, I don't understand how exactly it helps. The GPIO expander has its
> own example and as you pointed below, this is basically the same code,
> except rw and backlight GPIOs.

The hd44780 is a display that is very often used.
By people (like me some time ago) not familiar with the nice io expander
implementation in Linux. The consequence of that is that you'll find
several out-of-tree implementations for this display with i2c out in the
wild. So my thought of documenting this (again) at that location is to
make it easier for people with a hd44780 with the standard i2c interface
to see how it is done in Linux.

So I really think it helps. It would have helped me :-)

Ralf
-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   www.runtux.com
Reichergasse 131, A-3411 Weidling       email: office at runtux.com


From mark.rutland at arm.com  Mon Feb 12 04:00:23 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 12 Feb 2024 12:00:23 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <20240202080756.1453939-20-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
Message-ID: <ZcoIVypNwOPIX30w@FVFF77S0Q05N>

Hi Ryan,

Overall this looks pretty good; I have a bunch of minor comments below, and a
bigger question on the way ptep_get_lockless() works.

On Fri, Feb 02, 2024 at 08:07:50AM +0000, Ryan Roberts wrote:
> With the ptep API sufficiently refactored, we can now introduce a new
> "contpte" API layer, which transparently manages the PTE_CONT bit for
> user mappings.
> 
> In this initial implementation, only suitable batches of PTEs, set via
> set_ptes(), are mapped with the PTE_CONT bit. Any subsequent
> modification of individual PTEs will cause an "unfold" operation to
> repaint the contpte block as individual PTEs before performing the
> requested operation. While, a modification of a single PTE could cause
> the block of PTEs to which it belongs to become eligible for "folding"
> into a contpte entry, "folding" is not performed in this initial
> implementation due to the costs of checking the requirements are met.
> Due to this, contpte mappings will degrade back to normal pte mappings
> over time if/when protections are changed. This will be solved in a
> future patch.
> 
> Since a contpte block only has a single access and dirty bit, the
> semantic here changes slightly; when getting a pte (e.g. ptep_get())
> that is part of a contpte mapping, the access and dirty information are
> pulled from the block (so all ptes in the block return the same
> access/dirty info). When changing the access/dirty info on a pte (e.g.
> ptep_set_access_flags()) that is part of a contpte mapping, this change
> will affect the whole contpte block. This is works fine in practice
> since we guarantee that only a single folio is mapped by a contpte
> block, and the core-mm tracks access/dirty information per folio.
> 
> In order for the public functions, which used to be pure inline, to
> continue to be callable by modules, export all the contpte_* symbols
> that are now called by those public inline functions.
> 
> The feature is enabled/disabled with the ARM64_CONTPTE Kconfig parameter
> at build time. It defaults to enabled as long as its dependency,
> TRANSPARENT_HUGEPAGE is also enabled. The core-mm depends upon
> TRANSPARENT_HUGEPAGE to be able to allocate large folios, so if its not
> enabled, then there is no chance of meeting the physical contiguity
> requirement for contpte mappings.
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>  arch/arm64/Kconfig               |   9 +
>  arch/arm64/include/asm/pgtable.h | 161 ++++++++++++++++++
>  arch/arm64/mm/Makefile           |   1 +
>  arch/arm64/mm/contpte.c          | 283 +++++++++++++++++++++++++++++++
>  4 files changed, 454 insertions(+)
>  create mode 100644 arch/arm64/mm/contpte.c
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index d86d7f4758b5..1442e8ed95b6 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -2230,6 +2230,15 @@ config UNWIND_PATCH_PAC_INTO_SCS
>  	select UNWIND_TABLES
>  	select DYNAMIC_SCS
>  
> +config ARM64_CONTPTE
> +	bool "Contiguous PTE mappings for user memory" if EXPERT
> +	depends on TRANSPARENT_HUGEPAGE
> +	default y
> +	help
> +	  When enabled, user mappings are configured using the PTE contiguous
> +	  bit, for any mappings that meet the size and alignment requirements.
> +	  This reduces TLB pressure and improves performance.
> +
>  endmenu # "Kernel Features"
>  
>  menu "Boot options"
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 7dc6b68ee516..34892a95403d 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -133,6 +133,10 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>   */
>  #define pte_valid_not_user(pte) \
>  	((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN))
> +/*
> + * Returns true if the pte is valid and has the contiguous bit set.
> + */
> +#define pte_valid_cont(pte)	(pte_valid(pte) && pte_cont(pte))
>  /*
>   * Could the pte be present in the TLB? We must check mm_tlb_flush_pending
>   * so that we don't erroneously return false for pages that have been
> @@ -1135,6 +1139,161 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
>  #define vmemmap_update_pte vmemmap_update_pte
>  #endif
>  
> +#ifdef CONFIG_ARM64_CONTPTE
> +
> +/*
> + * The contpte APIs are used to transparently manage the contiguous bit in ptes
> + * where it is possible and makes sense to do so. The PTE_CONT bit is considered
> + * a private implementation detail of the public ptep API (see below).
> + */
> +extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, pte_t pte);
> +extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
> +extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
> +extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, pte_t pte, unsigned int nr);
> +extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep);
> +extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep);
> +extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep,
> +				pte_t entry, int dirty);
> +
> +static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
> +					pte_t *ptep, pte_t pte)
> +{
> +	if (unlikely(pte_valid_cont(pte)))
> +		__contpte_try_unfold(mm, addr, ptep, pte);
> +}
> +
> +/*
> + * The below functions constitute the public API that arm64 presents to the
> + * core-mm to manipulate PTE entries within their page tables (or at least this
> + * is the subset of the API that arm64 needs to implement). These public
> + * versions will automatically and transparently apply the contiguous bit where
> + * it makes sense to do so. Therefore any users that are contig-aware (e.g.
> + * hugetlb, kernel mapper) should NOT use these APIs, but instead use the
> + * private versions, which are prefixed with double underscore. All of these
> + * APIs except for ptep_get_lockless() are expected to be called with the PTL
> + * held.
> + */
> +
> +#define ptep_get ptep_get
> +static inline pte_t ptep_get(pte_t *ptep)
> +{
> +	pte_t pte = __ptep_get(ptep);
> +
> +	if (likely(!pte_valid_cont(pte)))
> +		return pte;
> +
> +	return contpte_ptep_get(ptep, pte);
> +}
> +
> +#define ptep_get_lockless ptep_get_lockless
> +static inline pte_t ptep_get_lockless(pte_t *ptep)
> +{
> +	pte_t pte = __ptep_get(ptep);
> +
> +	if (likely(!pte_valid_cont(pte)))
> +		return pte;
> +
> +	return contpte_ptep_get_lockless(ptep);
> +}
> +
> +static inline void set_pte(pte_t *ptep, pte_t pte)
> +{
> +	/*
> +	 * We don't have the mm or vaddr so cannot unfold contig entries (since
> +	 * it requires tlb maintenance). set_pte() is not used in core code, so
> +	 * this should never even be called. Regardless do our best to service
> +	 * any call and emit a warning if there is any attempt to set a pte on
> +	 * top of an existing contig range.
> +	 */
> +	pte_t orig_pte = __ptep_get(ptep);
> +
> +	WARN_ON_ONCE(pte_valid_cont(orig_pte));
> +	__set_pte(ptep, pte_mknoncont(pte));
> +}
> +
> +#define set_ptes set_ptes
> +static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, pte_t pte, unsigned int nr)
> +{
> +	pte = pte_mknoncont(pte);

Why do we have to clear the contiguous bit here? Is that for the same reason as
set_pte(), or do we expect callers to legitimately call this with the
contiguous bit set in 'pte'?

I think you explained this to me in-person, and IIRC we don't expect callers to
go set the bit themselves, but since it 'leaks' out to them via __ptep_get() we
have to clear it here to defer the decision of whether to set/clear it when
modifying entries. It would be nice if we could have a description of why/when
we need to clear this, e.g. in the 'public API' comment block above.

> +
> +	if (likely(nr == 1)) {
> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +		__set_ptes(mm, addr, ptep, pte, 1);
> +	} else {
> +		contpte_set_ptes(mm, addr, ptep, pte, nr);
> +	}
> +}
> +
> +static inline void pte_clear(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep)
> +{
> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +	__pte_clear(mm, addr, ptep);
> +}
> +
> +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
> +static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep)
> +{
> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +	return __ptep_get_and_clear(mm, addr, ptep);
> +}
> +
> +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
> +static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep)
> +{
> +	pte_t orig_pte = __ptep_get(ptep);
> +
> +	if (likely(!pte_valid_cont(orig_pte)))
> +		return __ptep_test_and_clear_young(vma, addr, ptep);
> +
> +	return contpte_ptep_test_and_clear_young(vma, addr, ptep);
> +}
> +
> +#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
> +static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep)
> +{
> +	pte_t orig_pte = __ptep_get(ptep);
> +
> +	if (likely(!pte_valid_cont(orig_pte)))
> +		return __ptep_clear_flush_young(vma, addr, ptep);
> +
> +	return contpte_ptep_clear_flush_young(vma, addr, ptep);
> +}
> +
> +#define __HAVE_ARCH_PTEP_SET_WRPROTECT
> +static inline void ptep_set_wrprotect(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep)
> +{
> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +	__ptep_set_wrprotect(mm, addr, ptep);
> +}
> +
> +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
> +static inline int ptep_set_access_flags(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep,
> +				pte_t entry, int dirty)
> +{
> +	pte_t orig_pte = __ptep_get(ptep);
> +
> +	entry = pte_mknoncont(entry);
> +
> +	if (likely(!pte_valid_cont(orig_pte)))
> +		return __ptep_set_access_flags(vma, addr, ptep, entry, dirty);
> +
> +	return contpte_ptep_set_access_flags(vma, addr, ptep, entry, dirty);
> +}
> +
> +#else /* CONFIG_ARM64_CONTPTE */
> +
>  #define ptep_get				__ptep_get
>  #define set_pte					__set_pte
>  #define set_ptes				__set_ptes
> @@ -1150,6 +1309,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
>  #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
>  #define ptep_set_access_flags			__ptep_set_access_flags
>  
> +#endif /* CONFIG_ARM64_CONTPTE */
> +
>  #endif /* !__ASSEMBLY__ */
>  
>  #endif /* __ASM_PGTABLE_H */
> diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
> index dbd1bc95967d..60454256945b 100644
> --- a/arch/arm64/mm/Makefile
> +++ b/arch/arm64/mm/Makefile
> @@ -3,6 +3,7 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
>  				   cache.o copypage.o flush.o \
>  				   ioremap.o mmap.o pgd.o mmu.o \
>  				   context.o proc.o pageattr.o fixmap.o
> +obj-$(CONFIG_ARM64_CONTPTE)	+= contpte.o
>  obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
>  obj-$(CONFIG_PTDUMP_CORE)	+= ptdump.o
>  obj-$(CONFIG_PTDUMP_DEBUGFS)	+= ptdump_debugfs.o
> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
> new file mode 100644
> index 000000000000..bfb50e6b44c7
> --- /dev/null
> +++ b/arch/arm64/mm/contpte.c
> @@ -0,0 +1,283 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2023 ARM Ltd.
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/export.h>
> +#include <asm/tlbflush.h>
> +
> +static inline bool mm_is_user(struct mm_struct *mm)
> +{
> +	/*
> +	 * Don't attempt to apply the contig bit to kernel mappings, because
> +	 * dynamically adding/removing the contig bit can cause page faults.
> +	 * These racing faults are ok for user space, since they get serialized
> +	 * on the PTL. But kernel mappings can't tolerate faults.
> +	 */
> +	return mm != &init_mm;
> +}

We also have the efi_mm as a non-user mm, though I don't think we manipulate
that while it is live, and I'm not sure if that needs any special handling.

> +static inline pte_t *contpte_align_down(pte_t *ptep)
> +{
> +	return (pte_t *)(ALIGN_DOWN((unsigned long)ptep >> 3, CONT_PTES) << 3);

I think this can be:

static inline pte_t *contpte_align_down(pte_t *ptep)
{
	return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
}

> +
> +static void contpte_convert(struct mm_struct *mm, unsigned long addr,
> +			    pte_t *ptep, pte_t pte)
> +{
> +	struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0);
> +	unsigned long start_addr;
> +	pte_t *start_ptep;
> +	int i;
> +
> +	start_ptep = ptep = contpte_align_down(ptep);
> +	start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> +	pte = pfn_pte(ALIGN_DOWN(pte_pfn(pte), CONT_PTES), pte_pgprot(pte));
> +
> +	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) {
> +		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
> +
> +		if (pte_dirty(ptent))
> +			pte = pte_mkdirty(pte);
> +
> +		if (pte_young(ptent))
> +			pte = pte_mkyoung(pte);
> +	}

Not a big deal either way, but I wonder if it makes more sense to accumulate
the 'ptent' dirty/young values, then modify 'pte' once, i.e.

	bool dirty = false, young = false;

	for (...) {
		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
		dirty |= pte_dirty(ptent);
		young |= pte_young(ptent);
	}

	if (dirty)
		pte_mkdirty(pte);
	if (young)
		pte_mkyoung(pte);

I suspect that might generate slightly better code, but I'm also happy with the
current form if people thnk that's more legible (I have no strong feelings
either way).

> +
> +	__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
> +
> +	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
> +}
> +
> +void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
> +			pte_t *ptep, pte_t pte)
> +{
> +	/*
> +	 * We have already checked that the ptes are contiguous in
> +	 * contpte_try_unfold(), so just check that the mm is user space.
> +	 */
> +
> +	if (!mm_is_user(mm))
> +		return;

Nit: normally we don't put a line gap between a comment block and the
associated block of code.

> +
> +	pte = pte_mknoncont(pte);
> +	contpte_convert(mm, addr, ptep, pte);
> +}
> +EXPORT_SYMBOL(__contpte_try_unfold);
> +
> +pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
> +{
> +	/*
> +	 * Gather access/dirty bits, which may be populated in any of the ptes
> +	 * of the contig range. We are guarranteed to be holding the PTL, so any
> +	 * contiguous range cannot be unfolded or otherwise modified under our
> +	 * feet.
> +	 */

Nit: s/guarranteed/guaranteed/

> +
> +	pte_t pte;
> +	int i;
> +
> +	ptep = contpte_align_down(ptep);
> +
> +	for (i = 0; i < CONT_PTES; i++, ptep++) {
> +		pte = __ptep_get(ptep);
> +
> +		if (pte_dirty(pte))
> +			orig_pte = pte_mkdirty(orig_pte);
> +
> +		if (pte_young(pte))
> +			orig_pte = pte_mkyoung(orig_pte);
> +	}
> +
> +	return orig_pte;
> +}
> +EXPORT_SYMBOL(contpte_ptep_get);
> +
> +pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
> +{
> +	/*
> +	 * Gather access/dirty bits, which may be populated in any of the ptes
> +	 * of the contig range. We may not be holding the PTL, so any contiguous
> +	 * range may be unfolded/modified/refolded under our feet. Therefore we
> +	 * ensure we read a _consistent_ contpte range by checking that all ptes
> +	 * in the range are valid and have CONT_PTE set, that all pfns are
> +	 * contiguous and that all pgprots are the same (ignoring access/dirty).
> +	 * If we find a pte that is not consistent, then we must be racing with
> +	 * an update so start again. If the target pte does not have CONT_PTE
> +	 * set then that is considered consistent on its own because it is not
> +	 * part of a contpte range.
> +	 */
> +
> +	pgprot_t orig_prot;
> +	unsigned long pfn;
> +	pte_t orig_pte;
> +	pgprot_t prot;
> +	pte_t *ptep;
> +	pte_t pte;
> +	int i;
> +
> +retry:
> +	orig_pte = __ptep_get(orig_ptep);
> +
> +	if (!pte_valid_cont(orig_pte))
> +		return orig_pte;
> +
> +	orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
> +	ptep = contpte_align_down(orig_ptep);
> +	pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
> +
> +	for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
> +		pte = __ptep_get(ptep);
> +		prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
> +
> +		if (!pte_valid_cont(pte) ||
> +		   pte_pfn(pte) != pfn ||
> +		   pgprot_val(prot) != pgprot_val(orig_prot))
> +			goto retry;
> +
> +		if (pte_dirty(pte))
> +			orig_pte = pte_mkdirty(orig_pte);
> +
> +		if (pte_young(pte))
> +			orig_pte = pte_mkyoung(orig_pte);
> +	}
> +
> +	return orig_pte;
> +}
> +EXPORT_SYMBOL(contpte_ptep_get_lockless);

I'm struggling to convince myself that this is safe in general, as it really
depends on how the caller will use this value. Which caller(s) actually care
about the access/dirty bits, given those could change at any time anyway?

I took a quick scan, and AFAICT:

* For perf_get_pgtable_size(), we only care about whether the entry is valid
  and has the contig bit set. We could clean that up with a new interface, e.g.
  something like a new ptep_get_size_lockless().

* For gup_pte_range(), I'm not sure we actually need the access/dirty bits when
  we look at the pte to start with, since we only care where we can logically
  write to the page at that point.

  I see that we later follow up with:

    with pte_val(pte) != pte_val(ptep_get(ptep)))

  ... is that why we need ptep_get_lockless() to accumulate the access/dirty
  bits? So that shape of lockless-try...locked-compare sequence works?

* For huge_pte_alloc(), arm64 doesn't select CONFIG_ARCH_WANT_GENERAL_HUGETLB,
  so this doesn' seem to matter.

* For __collapse_huge_page_swapin(), we only care if the pte is a swap pte,
  which means the pte isn't valid, and we'll return the orig_pte as-is anyway.

* For pte_range_none() the access/dirty bits don't matter.

* For handle_pte_fault() I think we have the same shape of
  lockless-try...locked-compare sequence as for gup_pte_range(), where we don't
  care about the acess/dirty bits before we reach the locked compare step.

* For ptdump_pte_entry() I think it's arguable that we should continue to
  report the access/dirty bits separately for each PTE, as we have done until
  now, to give an accurate representation of the contents of the translation
  tables.

* For swap_vma_readahead() and unuse_pte_range() we only care if the PTE is a
  swap entry, the access/dirty bits don't matter.

So AFAICT this only really matters for gup_pte_range() and handle_pte_fault(),
and IIUC that's only so that the locklessly-loaded pte value can be compared
with a subsequently locked-loaded entry (for which the access/dirty bits will
be accumulated). Have I understood that correctly?

If so, I wonder if we could instead do that comparison modulo the access/dirty
bits, and leave ptep_get_lockless() only reading a single entry?

Thanks,
Mark.

> +void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
> +					pte_t *ptep, pte_t pte, unsigned int nr)
> +{
> +	unsigned long next;
> +	unsigned long end;
> +	unsigned long pfn;
> +	pgprot_t prot;
> +
> +	/*
> +	 * The set_ptes() spec guarantees that when nr > 1, the initial state of
> +	 * all ptes is not-present. Therefore we never need to unfold or
> +	 * otherwise invalidate a range before we set the new ptes.
> +	 * contpte_set_ptes() should never be called for nr < 2.
> +	 */
> +	VM_WARN_ON(nr == 1);
> +
> +	if (!mm_is_user(mm))
> +		return __set_ptes(mm, addr, ptep, pte, nr);
> +
> +	end = addr + (nr << PAGE_SHIFT);
> +	pfn = pte_pfn(pte);
> +	prot = pte_pgprot(pte);
> +
> +	do {
> +		next = pte_cont_addr_end(addr, end);
> +		nr = (next - addr) >> PAGE_SHIFT;
> +		pte = pfn_pte(pfn, prot);
> +
> +		if (((addr | next | (pfn << PAGE_SHIFT)) & ~CONT_PTE_MASK) == 0)
> +			pte = pte_mkcont(pte);
> +		else
> +			pte = pte_mknoncont(pte);
> +
> +		__set_ptes(mm, addr, ptep, pte, nr);
> +
> +		addr = next;
> +		ptep += nr;
> +		pfn += nr;
> +
> +	} while (addr != end);
> +}
> +EXPORT_SYMBOL(contpte_set_ptes);
> +
> +int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
> +					unsigned long addr, pte_t *ptep)
> +{
> +	/*
> +	 * ptep_clear_flush_young() technically requires us to clear the access
> +	 * flag for a _single_ pte. However, the core-mm code actually tracks
> +	 * access/dirty per folio, not per page. And since we only create a
> +	 * contig range when the range is covered by a single folio, we can get
> +	 * away with clearing young for the whole contig range here, so we avoid
> +	 * having to unfold.
> +	 */
> +
> +	int young = 0;
> +	int i;
> +
> +	ptep = contpte_align_down(ptep);
> +	addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> +
> +	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
> +		young |= __ptep_test_and_clear_young(vma, addr, ptep);
> +
> +	return young;
> +}
> +EXPORT_SYMBOL(contpte_ptep_test_and_clear_young);
> +
> +int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
> +					unsigned long addr, pte_t *ptep)
> +{
> +	int young;
> +
> +	young = contpte_ptep_test_and_clear_young(vma, addr, ptep);
> +
> +	if (young) {
> +		/*
> +		 * See comment in __ptep_clear_flush_young(); same rationale for
> +		 * eliding the trailing DSB applies here.
> +		 */
> +		addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> +		__flush_tlb_range_nosync(vma, addr, addr + CONT_PTE_SIZE,
> +					 PAGE_SIZE, true, 3);
> +	}
> +
> +	return young;
> +}
> +EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
> +
> +int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
> +					unsigned long addr, pte_t *ptep,
> +					pte_t entry, int dirty)
> +{
> +	unsigned long start_addr;
> +	pte_t orig_pte;
> +	int i;
> +
> +	/*
> +	 * Gather the access/dirty bits for the contiguous range. If nothing has
> +	 * changed, its a noop.
> +	 */
> +	orig_pte = pte_mknoncont(ptep_get(ptep));
> +	if (pte_val(orig_pte) == pte_val(entry))
> +		return 0;
> +
> +	/*
> +	 * We can fix up access/dirty bits without having to unfold the contig
> +	 * range. But if the write bit is changing, we must unfold.
> +	 */
> +	if (pte_write(orig_pte) == pte_write(entry)) {
> +		/*
> +		 * For HW access management, we technically only need to update
> +		 * the flag on a single pte in the range. But for SW access
> +		 * management, we need to update all the ptes to prevent extra
> +		 * faults. Avoid per-page tlb flush in __ptep_set_access_flags()
> +		 * and instead flush the whole range at the end.
> +		 */
> +		ptep = contpte_align_down(ptep);
> +		start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> +
> +		for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
> +			__ptep_set_access_flags(vma, addr, ptep, entry, 0);
> +
> +		if (dirty)
> +			__flush_tlb_range(vma, start_addr, addr,
> +							PAGE_SIZE, true, 3);
> +	} else {
> +		__contpte_try_unfold(vma->vm_mm, addr, ptep, orig_pte);
> +		__ptep_set_access_flags(vma, addr, ptep, entry, dirty);
> +	}
> +
> +	return 1;
> +}
> +EXPORT_SYMBOL(contpte_ptep_set_access_flags);
> -- 
> 2.25.1
> 


From tudor.ambarus at linaro.org  Mon Feb 12 04:01:54 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 12:01:54 +0000
Subject: [PATCH 01/12] spi: dt-bindings: introduce the ``fifo-depth``
 property
In-Reply-To: <CAMuHMdXEKecx-wQCSzqmRr6af2AUOnoFhfD2JLx28n8OYnvzGw@mail.gmail.com>
References: <20240208135045.3728927-1-tudor.ambarus@linaro.org>
 <20240208135045.3728927-2-tudor.ambarus@linaro.org>
 <20240208-grating-legwarmer-0a04cfb04d61@spud>
 <c2b08463-cb13-4e9b-8797-8ebcf1047f66@linaro.org>
 <20240209-chest-sleet-a119fc3d4243@spud>
 <0ac8d573-6486-458d-afb9-090b5f8d4a21@linaro.org>
 <CAMuHMdXEKecx-wQCSzqmRr6af2AUOnoFhfD2JLx28n8OYnvzGw@mail.gmail.com>
Message-ID: <b7051bea-8197-4338-a089-5e5fff540ac5@linaro.org>



On 2/12/24 10:38, Geert Uytterhoeven wrote:
> Hi Tudor,

Hi, Geert!

> 
> On Fri, Feb 9, 2024 at 5:55?PM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>> On 2/9/24 16:21, Conor Dooley wrote:
>>> On Fri, Feb 09, 2024 at 01:56:56PM +0000, Tudor Ambarus wrote:
>>>> On 2/8/24 18:24, Conor Dooley wrote:
>>>>> On Thu, Feb 08, 2024 at 01:50:34PM +0000, Tudor Ambarus wrote:
>>>>>> There are instances of the same IP that are configured by the integrator
>>>>>> with different FIFO depths. Introduce the fifo-depth property to allow
>>>>>> such nodes to specify their FIFO depth.
>>>>>>
>>>>>> We haven't seen SPI IPs with different FIFO depths for RX and TX, thus
>>>>>> introduce a single property.
>>>>>
>>>>> Some citation attached to this would be nice. "We haven't seen" offers
>>>>> no detail as to what IPs that allow this sort of configuration of FIFO
>>>>> size that you have actually checked.
>>>>>
>>>>> I went and checked our IP that we use in FPGA fabric, which has a
>>>>> configurable fifo depth. It only has a single knob for both RX and TX
>>>>> FIFOs. The Xilinx xps spi core also has configurable FIFOs, but again RX
>>>>> and TX sizes are tied there. At least that's a sample size of three.
>>>>>
>>>>> One of our guys is working on support for the IP I just mentioned and
>>>>> would be defining a vendor property for this, so
>>>>> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
>>>>>
>>>>
>>>> Thanks, Conor. I had in mind that SPI has a shift register and it's
>>>> improbable to have different FIFO depths for RX and TX.
>>>
>>> IDK, but I've learned to expect the unexpectable, especially when it
>>> comes to the IPs intended for use in FPGAs.
>>>
>>>> At least I don't
>>>> see how it would work, I guess it will use the minimum depth between the
>>>> two?
>>>
>>> I'm not really sure how it would work other than that in the general
>>> case, but some use case specific configuration could work, but I do
>>> agree that it is
>>>
>>>> I grepped by "fifo" in the spi bindings and I now see that renesas is
>>>> using dedicated properties for RX and TX, but I think that there too the
>>>> FIFOs have the same depths. Looking into drivers/spi/spi-sh-msiof.c I
>>>> see that the of_device_id.data contains 64 bytes FIFOs for RX and TX,
>>>> regardless of the compatible.
>>>>
>>>> Geert, any idea if the FIFO depths can differ for RX and TX in
>>>> spi-sh-msiof.c?
> 
> See my other email
> https://lore.kernel.org/all/CAMuHMdU_Hx9PLmHf2Xm1KKTy_OF-TeCv7SzmA5CZWz+PLkbAGA at mail.gmail.com
> 

I saw the response, thanks again!

> Note that at one point we did have 64/256 in the driver, but that was
> changed in commit fe78d0b7691c0274 ("spi: sh-msiof: Fix FIFO size to
> 64 word from 256 word").  Diving into the discussion around that patch,
> there seem to be two factors at play:
>   1. Actual FIFO size,
>   2. Maximum transfer size per block
>      (up to 2 blocks on R-Car, up to 4 blocks on SH(-Mobile)).
> As the driver supports only a single block, it should be limited to
> 64 on R-Car Gen2/3.  R-Car Gen4 claims to have widened the register
> bit field for the maximum transfer size per block, so 256 might be
> possible there...

Got it.

> 
>>>> Anyway, even if there are such imbalanced architectures, I guess we can
>>>> consider them when/if they appear? (add rx/tx-fifo-depth dt properties)
>>>
>>> I think so.
>>>
>>>> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
>>>> Override the default TX fifo size.  Unit is words.  Ignored if 0.
>>>> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
>>>> renesas,rx-fifo-size:
>>>> Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml:
>>>> Override the default RX fifo size.  Unit is words.  Ignored if 0.
>>>
>>> These renesas ones seemed interesting at first glance due to these
>>> comments, but what's missed by grep the is "deprecated" marking on
>>> these. They seem to have been replaced by soc-specific compatibles.
>>
>> In the driver the renesas,{rx,tx}-fifo-size properties still have the
>> highest priority:
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git/tree/drivers/spi/spi-sh-msiof.c#n1350
>>
>> Maybe something for Geert, as I see he was the one marking these
>> properties as deprecated. I guess he forgot to update the driver.
>>
>> Anyway, I think we shall be fine, even if we don't hear from Geert.
> 
> The renesas,{rx,tx}-fifo-size properties date back to the early days
> of DT an ARM, when it was assumed that slightly different versions of
> IP cores could be handled well using a single common compatible value,
> and properties describing the (few) differences.  The pitfall here
> is the "few differences": too many times people discovered later that
> there were more differences, needing more properties, and complicating
> backwards-compatibility.
> 
> Hence the handling of different FIFO sizes was moved to the driver based
> on compatible values, and the renesas,{rx,tx}-fifo-size properties were
> deprecated.  See commit beb74bb0875579c4 ("spi: sh-msiof: Add support
> for R-Car H2 and M2"), which shows that there were more changes
> needed than the anticipated FIFO sizes.  And more were added later,
> see later additions to sh_msiof_chipdata.
> 
> So unless it is meant for a configurable synthesizable IP core, where
> this is a documented parameter of the IP core, I advise against
> specifying the FIFO size(s) in DT.
> 

I guess I get it now. You marked those properties as deprecated so that
users stop using them and rely on the driver based compatible values,
but at the same time you allowed the devicetree properties to have a
higher priority than the driver based compatible values in case one
really wants/needs to use the dt properties. I don't have a preference
here, I guess it's fine.

Thanks for the explanations!
ta


From james.clark at arm.com  Mon Feb 12 04:02:55 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 12 Feb 2024 12:02:55 +0000
Subject: [PATCH V4 00/11] coresight: Move remaining AMBA ACPI devices into
 platform driver
In-Reply-To: <20240123054608.1790189-1-anshuman.khandual@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
Message-ID: <60499829-a5fa-54e6-42e3-bd48f25a65dc@arm.com>



On 23/01/2024 05:45, Anshuman Khandual wrote:
> This moves remaining AMBA ACPI devices into respective platform drivers for
> enabling ACPI based power management support. This series applies on kernel
> v6.8-rc1 release. This series has been built, and boot tested on a DT based
> coresight platform. Although this still requires some more testing on ACPI
> based coresight platforms.
> 
> https://git.gitlab.arm.com/linux-arm/linux-anshuman.git (amba_other_acpi_migration_v4)
> 
> Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: James Clark <james.clark at arm.com>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: linux-acpi at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: coresight at lists.linaro.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> 

Reviewed-by: James Clark <james.clark at arm.com>

> Changes in V4:
> 
> - Fixed PM imbalance in etm4_probe() error path with pm_runtime_disable()
> - Restored back the pm_runtime_disable() on platform probe error paths
>   in replicator, funnel, catu, tpiu, tmc and stm devices
> - Dropped dev_caps argument from __tmc_probe()
> - Changed xxxx_platform_remove() for platform_driver->remove_new() callback
> 
> Changes in V3:
> 
> https://lore.kernel.org/all/20231208053939.42901-1-anshuman.khandual at arm.com/
> 
> - Split coresight_init_driver/remove_driver() helpers into a separate patch
> - Added 'drvdata->pclk' comments in replicator, funnel, tpiu, tmc, and stm devices
> - Updated funnel, and replicator drivers to use these new helpers
> - Check for drvdata instead of drvdata->pclk in suspend and resume paths in catu,
>   tmc and debug devices
> - Added patch to extract device name from AMBA pid based table lookup for stm
> - Added patch to extract device properties from AMBA pid based table look for tmc
> - Dropped pm_runtime_put() from common __probe() functions
> - Handled pm_runtime_put() in AMBA driver in success path
> - Handled pm_runtime_put() in platform driver in both success and error paths
> 
> Changes in V2:
> 
> https://lore.kernel.org/all/20231201062053.1268492-1-anshuman.khandual at arm.com/
> 
> - Dropped redundant devm_ioremap_resource() hunk from tmc_platform_probe()
> - Defined coresight_[init|remove]_driver() for both AMBA/platform drivers
> - Changed catu, tmc, tpiu, stm and debug coresight drivers to use the new
>   helpers avoiding build issues arising from module_amba_driver(), and
>   module_platform_driver() being on the same file
> 
> Changes in V1:
> 
> https://lore.kernel.org/all/20231027072943.3418997-1-anshuman.khandual at arm.com/
> 
> - Replaced all IS_ERR() instances with IS_ERR_OR_NULL() as per Suzuki
> 
> Changes in RFC:
> 
> https://lore.kernel.org/all/20230921042040.1334641-1-anshuman.khandual at arm.com/
> 
> Anshuman Khandual (11):
>   coresight: etm4x: Fix unbalanced pm_runtime_enable()
>   coresight: stm: Extract device name from AMBA pid based table lookup
>   coresight: tmc: Extract device properties from AMBA pid based table lookup
>   coresight: Add helpers registering/removing both AMBA and platform drivers
>   coresight: replicator: Move ACPI support from AMBA driver to platform driver
>   coresight: funnel: Move ACPI support from AMBA driver to platform driver
>   coresight: catu: Move ACPI support from AMBA driver to platform driver
>   coresight: tpiu: Move ACPI support from AMBA driver to platform driver
>   coresight: tmc: Move ACPI support from AMBA driver to platform driver
>   coresight: stm: Move ACPI support from AMBA driver to platform driver
>   coresight: debug: Move ACPI support from AMBA driver to platform driver
> 
>  drivers/acpi/arm64/amba.c                     |   8 -
>  drivers/hwtracing/coresight/coresight-catu.c  | 142 +++++++++++++---
>  drivers/hwtracing/coresight/coresight-catu.h  |   1 +
>  drivers/hwtracing/coresight/coresight-core.c  |  29 ++++
>  .../hwtracing/coresight/coresight-cpu-debug.c | 141 ++++++++++++++--
>  .../coresight/coresight-etm4x-core.c          |   3 +
>  .../hwtracing/coresight/coresight-funnel.c    |  86 +++++-----
>  drivers/hwtracing/coresight/coresight-priv.h  |  10 ++
>  .../coresight/coresight-replicator.c          |  81 ++++-----
>  drivers/hwtracing/coresight/coresight-stm.c   | 117 +++++++++++--
>  .../hwtracing/coresight/coresight-tmc-core.c  | 158 +++++++++++++++---
>  drivers/hwtracing/coresight/coresight-tmc.h   |   2 +
>  drivers/hwtracing/coresight/coresight-tpiu.c  | 102 +++++++++--
>  include/linux/coresight.h                     |   7 +
>  14 files changed, 726 insertions(+), 161 deletions(-)
> 


From david at redhat.com  Mon Feb 12 04:03:02 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 13:03:02 +0100
Subject: [PATCH v5 01/25] mm: Clarify the spec for set_ptes()
In-Reply-To: <20240202080756.1453939-2-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-2-ryan.roberts@arm.com>
Message-ID: <739e29cd-a0a7-4e76-826e-6fd4968ba4e0@redhat.com>

On 02.02.24 09:07, Ryan Roberts wrote:
> set_ptes() spec implies that it can only be used to set a present pte
> because it interprets the PFN field to increment it. However,
> set_pte_at() has been implemented on top of set_ptes() since set_ptes()
> was introduced, and set_pte_at() allows setting a pte to a not-present
> state. So clarify the spec to state that when nr==1, new state of pte
> may be present or not present. When nr>1, new state of all ptes must be
> present.
> 
> While we are at it, tighten the spec to set requirements around the
> initial state of ptes; when nr==1 it may be either present or
> not-present. But when nr>1 all ptes must initially be not-present. All
> set_ptes() callsites already conform to this requirement. Stating it
> explicitly is useful because it allows for a simplification to the
> upcoming arm64 contpte implementation.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>   include/linux/pgtable.h | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index f0feae7f89fb..5e7eaf8f2b97 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -229,6 +229,10 @@ static inline pte_t pte_next_pfn(pte_t pte)
>    * @pte: Page table entry for the first page.
>    * @nr: Number of pages to map.
>    *
> + * When nr==1, initial state of pte may be present or not present, and new state
> + * may be present or not present. When nr>1, initial state of all ptes must be
> + * not present, and new state must be present.
> + *
>    * May be overridden by the architecture, or the architecture can define
>    * set_pte() and PFN_PTE_SHIFT.
>    *

Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From vaishnav.a at ti.com  Mon Feb 12 04:03:54 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Mon, 12 Feb 2024 17:33:54 +0530
Subject: [PATCH 1/4] arm64: dts: ti: k3-am62p: Fix memory ranges for DMSS
In-Reply-To: <20240201-am62p_csi-v1-1-c83bb9eaeb49@ti.com>
References: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
 <20240201-am62p_csi-v1-1-c83bb9eaeb49@ti.com>
Message-ID: <994c6ff1-96ed-4dde-94a1-43f6cab2a005@ti.com>

Hi Jai,

Thanks for the patch.

On 01/02/24 18:37, Jai Luthra wrote:
> The INTR module for DMASS1 (CSI specific DMASS) is outside the currently
> available ranges, as it starts at 0x4e400000. So fix the ranges property
> to enable programming the interrupts correctly.
> 
> Fixes: 29075cc09f43 ("arm64: dts: ti: Introduce AM62P5 family of SoCs")
> Signed-off-by: Jai Luthra <j-luthra at ti.com>
> ---
>   arch/arm64/boot/dts/ti/k3-am62p.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
> index 84ffe7b9dcaf..4f22b5d9fb9f 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
> @@ -71,7 +71,7 @@ cbass_main: bus at f0000 {
>   			 <0x00 0x43600000 0x00 0x43600000 0x00 0x00010000>, /* SA3 sproxy data */
>   			 <0x00 0x44043000 0x00 0x44043000 0x00 0x00000fe0>, /* TI SCI DEBUG */
>   			 <0x00 0x44860000 0x00 0x44860000 0x00 0x00040000>, /* SA3 sproxy config */
> -			 <0x00 0x48000000 0x00 0x48000000 0x00 0x06400000>, /* DMSS */
> +			 <0x00 0x48000000 0x00 0x48000000 0x00 0x06408000>, /* DMSS */

Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>

>   			 <0x00 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS0 DAT1 */
>   			 <0x00 0x70000000 0x00 0x70000000 0x00 0x00010000>, /* OCSRAM */
>   			 <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */
> 


From vaishnav.a at ti.com  Mon Feb 12 04:05:03 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Mon, 12 Feb 2024 17:35:03 +0530
Subject: [PATCH 2/4] arm64: dts: ti: k3-am62p: Add DMASS1 for CSI
In-Reply-To: <20240201-am62p_csi-v1-2-c83bb9eaeb49@ti.com>
References: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
 <20240201-am62p_csi-v1-2-c83bb9eaeb49@ti.com>
Message-ID: <7e5cbf78-7668-4fc2-90b9-27d0d4b857e3@ti.com>



On 01/02/24 18:37, Jai Luthra wrote:
> On AM62P, CSI-RX uses a dedicated BCDMA instance (DMASS1) for
> transferring captured camera frames to DDR, so enable it.
> 
> Signed-off-by: Jai Luthra <j-luthra at ti.com>
> ---
>   arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 37 +++++++++++++++++++++++++++++++
>   1 file changed, 37 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> index 4c51bae06b57..57ec4ef334e4 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> @@ -158,6 +158,43 @@ main_pktdma: dma-controller at 485c0000 {
>   		};
>   	};
>   
> +	dmss_csi: bus at 4e000000 {
> +		compatible = "simple-bus";
> +		ranges = <0x00 0x4e000000 0x00 0x4e000000 0x00 0x408000>;
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		dma-ranges;
> +		ti,sci-dev-id = <198>;
> +
> +		inta_main_dmss_csi: interrupt-controller at 4e400000 {
> +			compatible = "ti,sci-inta";
> +			reg = <0x00 0x4e400000 0x00 0x8000>;
> +			#interrupt-cells = <0>;
> +			interrupt-controller;
> +			interrupt-parent = <&gic500>;
> +			msi-controller;
> +			power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
> +			ti,sci = <&dmsc>;
> +			ti,sci-dev-id = <200>;
> +			ti,interrupt-ranges = <0 237 8>;
> +			ti,unmapped-event-sources = <&main_bcdma_csi>;
> +		};
> +
> +		main_bcdma_csi: dma-controller at 4e230000 {
> +			compatible = "ti,am62a-dmss-bcdma-csirx";
> +			reg = <0x00 0x4e230000 0x00 0x100>,
> +			      <0x00 0x4e180000 0x00 0x8000>,
> +			      <0x00 0x4e100000 0x00 0x10000>;
> +			reg-names = "gcfg", "rchanrt", "ringrt";
> +			#dma-cells = <3>;
> +			msi-parent = <&inta_main_dmss_csi>;
> +			power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
> +			ti,sci = <&dmsc>;
> +			ti,sci-dev-id = <199>;
> +			ti,sci-rm-range-rchan = <0x21>;
> +		};
> +	};

Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>

> +
>   	dmsc: system-controller at 44043000 {
>   		compatible = "ti,k2g-sci";
>   		ti,host-id = <12>;
> 


From vaishnav.a at ti.com  Mon Feb 12 04:06:34 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Mon, 12 Feb 2024 17:36:34 +0530
Subject: [PATCH 3/4] arm64: dts: ti: k3-am62p: Add nodes for CSI-RX
In-Reply-To: <20240201-am62p_csi-v1-3-c83bb9eaeb49@ti.com>
References: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
 <20240201-am62p_csi-v1-3-c83bb9eaeb49@ti.com>
Message-ID: <a64d7c6b-8c22-47c3-a60f-e9dc39026fe0@ti.com>



On 01/02/24 18:37, Jai Luthra wrote:
> AM62P supports image capture via the MIPI CSI-2 protocol, it uses three
> IPs to achieve this: Cadence DPHY, Cadence CSI-RX, and TI's pixelgrabber
> wrapper on top. Enable all of these IPs in the devicetree.
> 

Add nodes and keep them disabled sounds more apt here as you are keeping 
all of these disabled.

> Signed-off-by: Jai Luthra <j-luthra at ti.com>
> ---
>   arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 61 +++++++++++++++++++++++++++++++
>   1 file changed, 61 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> index 57ec4ef334e4..fdd835a04327 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
> @@ -928,4 +928,65 @@ mcasp2: audio-controller at 2b20000 {
>   		power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
>   		status = "disabled";
>   	};
> +
> +	ti_csi2rx0: ticsi2rx at 30102000 {
> +		compatible = "ti,j721e-csi2rx-shim";
> +		reg = <0x00 0x30102000 0x00 0x1000>;
> +		ranges;
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		dmas = <&main_bcdma_csi 0 0x5000 0>;
> +		dma-names = "rx0";
> +		power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
> +
> +		cdns_csi2rx0: csi-bridge at 30101000 {
> +			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
> +			reg = <0x00 0x30101000 0x00 0x1000>;
> +			clocks = <&k3_clks 182 0>, <&k3_clks 182 3>, <&k3_clks 182 0>,
> +				<&k3_clks 182 0>, <&k3_clks 182 4>, <&k3_clks 182 4>;
> +			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
> +				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
> +			phys = <&dphy0>;
> +			phy-names = "dphy";
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				csi0_port0: port at 0 {
> +					reg = <0>;
> +					status = "disabled";
> +				};
> +
> +				csi0_port1: port at 1 {
> +					reg = <1>;
> +					status = "disabled";
> +				};
> +
> +				csi0_port2: port at 2 {
> +					reg = <2>;
> +					status = "disabled";
> +				};
> +
> +				csi0_port3: port at 3 {
> +					reg = <3>;
> +					status = "disabled";
> +				};
> +
> +				csi0_port4: port at 4 {
> +					reg = <4>;
> +					status = "disabled";
> +				};
> +			};
> +		};
> +	};
> +
> +	dphy0: phy at 30110000 {
> +		compatible = "cdns,dphy-rx";
> +		reg = <0x00 0x30110000 0x00 0x1100>;
> +		#phy-cells = <0>;
> +		power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
> +	};

Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>

>   };
> 


From lkp at intel.com  Mon Feb 12 04:06:03 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 12 Feb 2024 20:06:03 +0800
Subject: [PATCH v3 13/19] power: reset: msm-poweroff: Use
 devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240208170410.67975-14-afd@ti.com>
Message-ID: <ZcoJq8o/ZeJEQjis@rli9-mobl>

Hi Andrew,

kernel test robot noticed the following build warnings:

[auto build test WARNING on sre-power-supply/for-next]
[also build test WARNING on mani-mhi/mhi-next soc/for-next linus/master v6.8-rc4 next-20240209]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrew-Davis/power-reset-atc260x-poweroff-Use-devm_register_sys_off_handler-RESTART/20240209-011655
base:   https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git for-next
patch link:    https://lore.kernel.org/r/20240208170410.67975-14-afd%40ti.com
patch subject: [PATCH v3 13/19] power: reset: msm-poweroff: Use devm_register_sys_off_handler(RESTART)
:::::: branch date: 4 days ago
:::::: commit date: 4 days ago
config: arm64-randconfig-r131-20240211 (https://download.01.org/0day-ci/archive/20240212/202402121342.7WgNqBu9-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20240212/202402121342.7WgNqBu9-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/r/202402121342.7WgNqBu9-lkp at intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/power/reset/msm-poweroff.c:18:41: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected void [noderef] __iomem *msm_ps_hold @@     got void *cb_data @@
   drivers/power/reset/msm-poweroff.c:18:41: sparse:     expected void [noderef] __iomem *msm_ps_hold
   drivers/power/reset/msm-poweroff.c:18:41: sparse:     got void *cb_data
>> drivers/power/reset/msm-poweroff.c:33:61: sparse: sparse: incorrect type in argument 5 (different address spaces) @@     expected void *cb_data @@     got void [noderef] __iomem *msm_ps_hold @@
   drivers/power/reset/msm-poweroff.c:33:61: sparse:     expected void *cb_data
   drivers/power/reset/msm-poweroff.c:33:61: sparse:     got void [noderef] __iomem *msm_ps_hold
   drivers/power/reset/msm-poweroff.c:37:39: sparse: sparse: incorrect type in argument 5 (different address spaces) @@     expected void *cb_data @@     got void [noderef] __iomem *msm_ps_hold @@
   drivers/power/reset/msm-poweroff.c:37:39: sparse:     expected void *cb_data
   drivers/power/reset/msm-poweroff.c:37:39: sparse:     got void [noderef] __iomem *msm_ps_hold

vim +18 drivers/power/reset/msm-poweroff.c

78be3176c4335b Abhimanyu Kapur 2013-07-30  15  
bc460fab0b719d Andrew Davis    2024-02-08  16  static int do_msm_poweroff(struct sys_off_data *data)
78be3176c4335b Abhimanyu Kapur 2013-07-30  17  {
bc460fab0b719d Andrew Davis    2024-02-08 @18  	void __iomem *msm_ps_hold = data->cb_data;
bc460fab0b719d Andrew Davis    2024-02-08  19  
78be3176c4335b Abhimanyu Kapur 2013-07-30  20  	writel(0, msm_ps_hold);
78be3176c4335b Abhimanyu Kapur 2013-07-30  21  	mdelay(10000);
18a702e0de9879 Pramod Gurav    2014-09-25  22  
18a702e0de9879 Pramod Gurav    2014-09-25  23  	return NOTIFY_DONE;
78be3176c4335b Abhimanyu Kapur 2013-07-30  24  }
78be3176c4335b Abhimanyu Kapur 2013-07-30  25  
78be3176c4335b Abhimanyu Kapur 2013-07-30  26  static int msm_restart_probe(struct platform_device *pdev)
78be3176c4335b Abhimanyu Kapur 2013-07-30  27  {
bc460fab0b719d Andrew Davis    2024-02-08  28  	void __iomem *msm_ps_hold = devm_platform_ioremap_resource(pdev, 0);
78be3176c4335b Abhimanyu Kapur 2013-07-30  29  	if (IS_ERR(msm_ps_hold))
78be3176c4335b Abhimanyu Kapur 2013-07-30  30  		return PTR_ERR(msm_ps_hold);
78be3176c4335b Abhimanyu Kapur 2013-07-30  31  
bc460fab0b719d Andrew Davis    2024-02-08  32  	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
bc460fab0b719d Andrew Davis    2024-02-08 @33  				      128, do_msm_poweroff, msm_ps_hold);
18a702e0de9879 Pramod Gurav    2014-09-25  34  
521ef776c49589 Andrew Davis    2024-02-08  35  	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
521ef776c49589 Andrew Davis    2024-02-08  36  				      SYS_OFF_PRIO_DEFAULT, do_msm_poweroff,
521ef776c49589 Andrew Davis    2024-02-08  37  				      msm_ps_hold);
18a702e0de9879 Pramod Gurav    2014-09-25  38  
78be3176c4335b Abhimanyu Kapur 2013-07-30  39  	return 0;
78be3176c4335b Abhimanyu Kapur 2013-07-30  40  }
78be3176c4335b Abhimanyu Kapur 2013-07-30  41  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki



From vaishnav.a at ti.com  Mon Feb 12 04:07:41 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Mon, 12 Feb 2024 17:37:41 +0530
Subject: [PATCH 4/4] arm64: dts: ti: Enable overlays for SK-AM62P
In-Reply-To: <20240201-am62p_csi-v1-4-c83bb9eaeb49@ti.com>
References: <20240201-am62p_csi-v1-0-c83bb9eaeb49@ti.com>
 <20240201-am62p_csi-v1-4-c83bb9eaeb49@ti.com>
Message-ID: <b473f88b-ae6d-49fd-8ba8-2f3e27b6e536@ti.com>



On 01/02/24 18:37, Jai Luthra wrote:
> Enable symbols so that overlays can be applied on the base DTB for
> SK-AM62P.
> 
> Also compile-test known-to-work camera sensor overlays for OV5640 and
> IMX219.
> 
> Signed-off-by: Jai Luthra <j-luthra at ti.com>
> ---
>   arch/arm64/boot/dts/ti/Makefile | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
> index 52c1dc910308..80733ed747a2 100644
> --- a/arch/arm64/boot/dts/ti/Makefile
> +++ b/arch/arm64/boot/dts/ti/Makefile
> @@ -101,6 +101,12 @@ k3-am62a7-sk-csi2-ov5640-dtbs := k3-am62a7-sk.dtb \
>   	k3-am62x-sk-csi2-ov5640.dtbo
>   k3-am62a7-sk-csi2-tevi-ov5640-dtbs := k3-am62a7-sk.dtb \
>   	k3-am62x-sk-csi2-tevi-ov5640.dtbo
> +k3-am62p5-sk-csi2-imx219-dtbs := k3-am62p5-sk.dtb \
> +	k3-am62x-sk-csi2-imx219.dtbo
> +k3-am62p5-sk-csi2-ov5640-dtbs := k3-am62p5-sk.dtb \
> +	k3-am62x-sk-csi2-ov5640.dtbo
> +k3-am62p5-sk-csi2-tevi-ov5640-dtbs := k3-am62p5-sk.dtb \
> +	k3-am62x-sk-csi2-tevi-ov5640.dtbo
>   k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
>   	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
>   k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
> @@ -118,6 +124,9 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
>   	k3-am62-lp-sk-hdmi-audio.dtb \
>   	k3-am62a7-sk-csi2-imx219.dtb \
>   	k3-am62a7-sk-csi2-ov5640.dtb \
> +	k3-am62p5-sk-csi2-imx219.dtb \
> +	k3-am62p5-sk-csi2-ov5640.dtb \
> +	k3-am62p5-sk-csi2-tevi-ov5640.dtb \
>   	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
>   	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
>   	k3-j721e-evm-pcie0-ep.dtb \
> @@ -128,6 +137,7 @@ DTC_FLAGS_k3-am625-beagleplay += -@
>   DTC_FLAGS_k3-am625-sk += -@
>   DTC_FLAGS_k3-am62-lp-sk += -@
>   DTC_FLAGS_k3-am62a7-sk += -@
> +DTC_FLAGS_k3-am62p5-sk += -@

Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>

>   DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
>   DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
>   DTC_FLAGS_k3-j721e-common-proc-board += -@
> 


From krzysztof.kozlowski at linaro.org  Mon Feb 12 04:07:54 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 13:07:54 +0100
Subject: [PATCH] arm64: dts: exynos: gs101: add stable i2c aliases for
 gs101-oriole
In-Reply-To: <0ad3082c50e21a74de41ca9908bd53b72e1f1a9c.camel@linaro.org>
References: <20240130233700.2287442-1-andre.draszik@linaro.org>
 <170737972037.52344.9107022607101399076.b4-ty@linaro.org>
 <5972b6a4ae8669e2a9e872278b740b182217906b.camel@linaro.org>
 <dce39e15-32a8-482c-8751-af4a133f82d2@linaro.org>
 <c16c1f18a8c6f33a608618d4ccf7d8c8dbb6f88b.camel@linaro.org>
 <67a6564a-00bb-461d-b7eb-ca169df6d251@linaro.org>
 <0ad3082c50e21a74de41ca9908bd53b72e1f1a9c.camel@linaro.org>
Message-ID: <b6ec1d0e-e35c-4917-871b-049efcb2ea22@linaro.org>

On 12/02/2024 12:52, Andr? Draszik wrote:
> On Mon, 2024-02-12 at 12:40 +0100, Krzysztof Kozlowski wrote:
>> On 12/02/2024 12:30, Andr? Draszik wrote:
>>> On Mon, 2024-02-12 at 12:18 +0100, Krzysztof Kozlowski wrote:
>>>> I can drop it, but the actual problem is that what if downstream keeps
>>>> changing aliases? They can do it...
>>>
>>> We won't care at that stage, downstream should have no reason to divert from
>>> upstream for numbering at some point in the future.
>>
>> What do you mean by "no reason"? The reason is they can do whatever they
>> want. Some project leader says: "I want this" and they will do it. They
>> won't care about our upstream choice at all.
>>
>> And then what, you change it again?
> 
> As I said above, we won't care if downstream changes again at that stage, so
> no, I wouldn't plan on changing again.

Then I am lost. What stage are you thinking? What differs between now
and let's say 1 month for the GS101 which was released more than three
years ago?

BTW, the aliases I see in downstream DTS (gs101-usi.dtsi) - since
beginning up to Android 14 are:

                hsi2c8 = &hsi2c_8;
                hsi2c9 = &hsi2c_9;
                hsi2c10 = &hsi2c_10;
                hsi2c11 = &hsi2c_11;
                hsi2c12 = &hsi2c_12;

They were set like this in 2020 and never changed afterwards.

Best regards,
Krzysztof



From wsa+renesas at sang-engineering.com  Mon Feb 12 04:12:46 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Mon, 12 Feb 2024 13:12:46 +0100
Subject: [PATCH 0/6] mfd: tmio: simplify header and move to platform_data
In-Reply-To: <CAPDyKFpho16DU7OorMgXDqiyfFfgM_tWu+DZZOHd0gbjtBw_Cg@mail.gmail.com>
References: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
 <CAPDyKFpmfgwJ5dJFmORhg1tBewzhB_jrWikpX=b23r-joN91SA@mail.gmail.com>
 <20240209132837.GJ689448@google.com>
 <CAPDyKFpho16DU7OorMgXDqiyfFfgM_tWu+DZZOHd0gbjtBw_Cg@mail.gmail.com>
Message-ID: <ZcoLPnA8TEAgBk8O@shikoro>

Hi Lee, Ulf,

> Please add my ack for the mmc related changes.

I prepared v2 of the series: rebased to rc4, acks added, capitalized
first letter... waiting for buildbot now before resending.

Thanks,

   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/20240212/30e604c4/attachment.sig>

From suzuki.poulose at arm.com  Mon Feb 12 04:13:00 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 12 Feb 2024 12:13:00 +0000
Subject: [PATCH V4 03/11] coresight: tmc: Extract device properties from
 AMBA pid based table lookup
In-Reply-To: <20240123054608.1790189-4-anshuman.khandual@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-4-anshuman.khandual@arm.com>
Message-ID: <44597c9a-79bd-40f8-87a7-b53582132583@arm.com>

On 23/01/2024 05:46, Anshuman Khandual wrote:
> This extracts device properties from AMBA pid based table lookup. This also
> defers tmc_etr_setup_caps() after the coresight device has been initialized
> so that PID value can be read.
> 
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: James Clark <james.clark 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>
> ---
>   .../hwtracing/coresight/coresight-tmc-core.c  | 19 +++++++++++++------
>   1 file changed, 13 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index 7ec5365e2b64..e71db3099a29 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -370,16 +370,24 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
>   	return (auth & TMC_AUTH_NSID_MASK) == 0x3;
>   }
>   
> +#define TMC_AMBA_MASK 0xfffff
> +
> +static const struct amba_id tmc_ids[];
> +
>   /* Detect and initialise the capabilities of a TMC ETR */
> -static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
> +static int tmc_etr_setup_caps(struct device *parent, u32 devid)
>   {
>   	int rc;
> -	u32 dma_mask = 0;
> +	u32 tmc_pid, dma_mask = 0;
>   	struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
> +	void *dev_caps;
>   
>   	if (!tmc_etr_has_non_secure_access(drvdata))
>   		return -EACCES;
>   
> +	tmc_pid = coresight_get_pid(&drvdata->csdev->access) & TMC_AMBA_MASK;
> +	dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid);
> +
>   	/* Set the unadvertised capabilities */
>   	tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
>   
> @@ -497,10 +505,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>   		desc.type = CORESIGHT_DEV_TYPE_SINK;
>   		desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
>   		desc.ops = &tmc_etr_cs_ops;
> -		ret = tmc_etr_setup_caps(dev, devid,
> -					 coresight_get_uci_data(id));
> -		if (ret)
> -			goto out;
>   		idr_init(&drvdata->idr);
>   		mutex_init(&drvdata->idr_mutex);
>   		dev_list = &etr_devs;
> @@ -539,6 +543,9 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>   		goto out;
>   	}
>   
> +	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
> +		ret = tmc_etr_setup_caps(dev, devid);
> +

With this change, we silently accept an ETR that may only have "SECURE" 
access only and crash later while we try to enable tracing. You could
pass in the "access" (which is already in 'desc.access' in the original
call site and deal with it ?

Suzuki



>   	drvdata->miscdev.name = desc.name;
>   	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
>   	drvdata->miscdev.fops = &tmc_fops;



From rogerq at kernel.org  Mon Feb 12 04:13:56 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 12 Feb 2024 14:13:56 +0200
Subject: [PATCH v1] arm64: dts: ti: k3-am62-main: disable usb lpm
In-Reply-To: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
References: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
Message-ID: <2629cd30-23aa-4f03-8452-ae13297fd6b6@kernel.org>

Hi Andrejs,

On 09/02/2024 15:02, Andrejs Cainikovs wrote:
> From: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
> 
> AM62 USB works with some devices, while failing to operate with others.

Could you please share which devices failed to work for you?

> 
> [  560.189822] xhci-hcd xhci-hcd.4.auto: xHCI Host Controller
> [  560.195631] xhci-hcd xhci-hcd.4.auto: new USB bus registered, assigned bus number 2
> [  574.388509] xhci-hcd xhci-hcd.4.auto: can't setup: -110
> [  574.393814] xhci-hcd xhci-hcd.4.auto: USB bus 2 deregistered
> [  574.399544] xhci-hcd: probe of xhci-hcd.4.auto failed with error -110
> 
> This seems to be related to LPM (Link Power Management), and disabling it
> turns USB into reliable working state.
> 
> As per AM62 reference manual:
> 
>> 4.8.2.1 USB2SS Unsupported Features
>>
>> The following features are not supported on this family of devices:
>> ...
>> - USB 2.0 ECN: Link Power Management (LPM)
>> ...
> 
> Fixes: 2240f96cf3cd ("arm64: dts: ti: k3-am62-main: Add support for USB")
> Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
> ---
>  arch/arm64/boot/dts/ti/k3-am62-main.dtsi | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> index 464b7565d085..c49fbce5cb70 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> @@ -640,6 +640,8 @@ usb0: usb at 31000000 {
>  			interrupt-names = "host", "peripheral";
>  			maximum-speed = "high-speed";
>  			dr_mode = "otg";
> +			snps,usb2-gadget-lpm-disable;
> +			snps,usb2-lpm-disable;
>  		};
>  	};
>  
> @@ -663,6 +665,8 @@ usb1: usb at 31100000 {
>  			interrupt-names = "host", "peripheral";
>  			maximum-speed = "high-speed";
>  			dr_mode = "otg";
> +			snps,usb2-gadget-lpm-disable;
> +			snps,usb2-lpm-disable;
>  		};
>  	};
>  

Instead of this could you please check if this series fixes the issue for you?
https://lore.kernel.org/all/20240205141221.56076-1-rogerq at kernel.org/

-- 
cheers,
-roger


From david at redhat.com  Mon Feb 12 04:14:23 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 13:14:23 +0100
Subject: [PATCH v5 03/25] mm: Make pte_next_pfn() a wrapper around
 pte_advance_pfn()
In-Reply-To: <20240202080756.1453939-4-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-4-ryan.roberts@arm.com>
Message-ID: <c269c2e0-afca-4ff0-8ffd-9049fb52c905@redhat.com>

On 02.02.24 09:07, Ryan Roberts wrote:
> The goal is to be able to advance a PTE by an arbitrary number of PFNs.
> So introduce a new API that takes a nr param.
> 
> We are going to remove pte_next_pfn() and replace it with
> pte_advance_pfn(). As a first step, implement pte_next_pfn() as a
> wrapper around pte_advance_pfn() so that we can incrementally switch the
> architectures over. Once all arches are moved over, we will change all
> the core-mm callers to call pte_advance_pfn() directly and remove the
> wrapper.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>   include/linux/pgtable.h | 8 +++++++-
>   1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 5e7eaf8f2b97..815d92dcb96b 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -214,9 +214,15 @@ static inline int pmd_dirty(pmd_t pmd)
>   
>   
>   #ifndef pte_next_pfn
> +#ifndef pte_advance_pfn
> +static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
> +{
> +	return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
> +}
> +#endif
>   static inline pte_t pte_next_pfn(pte_t pte)
>   {
> -	return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
> +	return pte_advance_pfn(pte, 1);
>   }
>   #endif
>   

I do wonder if we simply want to leave pte_next_pfn() around? Especially 
patch #4, #6 don't really benefit from the change? So are the other 
set_ptes() implementations.

That is, only convert all pte_next_pfn()->pte_advance_pfn(), and leave a
pte_next_pfn() macro in place.

Any downsides to that? This patch here would become:

#ifndef pte_advance_pfn
static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
{
	return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
}
#endif

#ifndef pte_next_pfn
#define pte_next_pfn(pte) pte_advance_pfn(pte, 1)
#endif

As you convert the three arches, make them define pte_advance_pfn and 
udnefine pte_next_pfn. in the end, you can drop the #ifdef around 
pte_next_pfn here.

-- 
Cheers,

David / dhildenb



From andriy.shevchenko at linux.intel.com  Mon Feb 12 04:14:34 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Mon, 12 Feb 2024 14:14:34 +0200
Subject: [PATCH 2/3] dt-bindings: auxdisplay: adjust example indentation
 and use generic node names
In-Reply-To: <20240212083426.26757-2-krzysztof.kozlowski@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <20240212083426.26757-2-krzysztof.kozlowski@linaro.org>
Message-ID: <ZcoLqjBnif7ZZ7-j@smile.fi.intel.com>

On Mon, Feb 12, 2024 at 09:34:25AM +0100, Krzysztof Kozlowski wrote:
> The example DTS should be indented with two or four (preferred) spaces,
> as mentioned in Writing Schema document.  While re-indenting, change the
> node names to somehow generic names, as expected by Devicetree
> specification.

Thank you, it's helpful!
Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>

-- 
With Best Regards,
Andy Shevchenko




From andriy.shevchenko at linux.intel.com  Mon Feb 12 04:15:04 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Mon, 12 Feb 2024 14:15:04 +0200
Subject: [PATCH 3/3] dt-bindings: auxdisplay: hit,hd44780: use defines
 for GPIO flags
In-Reply-To: <20240212083426.26757-3-krzysztof.kozlowski@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <20240212083426.26757-3-krzysztof.kozlowski@linaro.org>
Message-ID: <ZcoLyAI-RuaN5X6H@smile.fi.intel.com>

On Mon, Feb 12, 2024 at 09:34:26AM +0100, Krzysztof Kozlowski wrote:
> Improve example DTS readability by using known defines for GPIO flags.

Yes, it's better this way.
Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>

-- 
With Best Regards,
Andy Shevchenko




From zajec5 at gmail.com  Mon Feb 12 04:16:19 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 12 Feb 2024 13:16:19 +0100
Subject: [PATCH REBASED 1/2] arm64: dts: mediatek: mt7986: reorder properties
Message-ID: <20240212121620.15035-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Use order described as preferred in DTS Coding Style. Mostly just move
"compatible", "reg" and "ranges" properties. In two nodes also move
vendor-prefixed props down.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 67 ++++++++++++-----------
 1 file changed, 34 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index d974739eae1c..eba5e27a1bbe 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -27,34 +27,34 @@ cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		cpu0: cpu at 0 {
-			device_type = "cpu";
 			compatible = "arm,cortex-a53";
-			enable-method = "psci";
 			reg = <0x0>;
+			device_type = "cpu";
+			enable-method = "psci";
 			#cooling-cells = <2>;
 		};
 
 		cpu1: cpu at 1 {
-			device_type = "cpu";
 			compatible = "arm,cortex-a53";
-			enable-method = "psci";
 			reg = <0x1>;
+			device_type = "cpu";
+			enable-method = "psci";
 			#cooling-cells = <2>;
 		};
 
 		cpu2: cpu at 2 {
-			device_type = "cpu";
 			compatible = "arm,cortex-a53";
-			enable-method = "psci";
 			reg = <0x2>;
+			device_type = "cpu";
+			enable-method = "psci";
 			#cooling-cells = <2>;
 		};
 
 		cpu3: cpu at 3 {
-			device_type = "cpu";
-			enable-method = "psci";
 			compatible = "arm,cortex-a53";
 			reg = <0x3>;
+			device_type = "cpu";
+			enable-method = "psci";
 			#cooling-cells = <2>;
 		};
 	};
@@ -131,22 +131,22 @@ timer {
 	};
 
 	soc {
-		#address-cells = <2>;
-		#size-cells = <2>;
 		compatible = "simple-bus";
 		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
 
 		gic: interrupt-controller at c000000 {
 			compatible = "arm,gic-v3";
-			#interrupt-cells = <3>;
-			interrupt-parent = <&gic>;
-			interrupt-controller;
 			reg = <0 0x0c000000 0 0x10000>,  /* GICD */
 			      <0 0x0c080000 0 0x80000>,  /* GICR */
 			      <0 0x0c400000 0 0x2000>,   /* GICC */
 			      <0 0x0c410000 0 0x1000>,   /* GICH */
 			      <0 0x0c420000 0 0x2000>;   /* GICV */
+			interrupt-parent = <&gic>;
 			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
 		};
 
 		infracfg: infracfg at 10001000 {
@@ -310,9 +310,9 @@ i2c0: i2c at 11008000 {
 
 		spi0: spi at 1100a000 {
 			compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
+			reg = <0 0x1100a000 0 0x100>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <0 0x1100a000 0 0x100>;
 			interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&topckgen CLK_TOP_MPLL_D2>,
 				 <&topckgen CLK_TOP_SPI_SEL>,
@@ -324,9 +324,9 @@ spi0: spi at 1100a000 {
 
 		spi1: spi at 1100b000 {
 			compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
+			reg = <0 0x1100b000 0 0x100>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <0 0x1100b000 0 0x100>;
 			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&topckgen CLK_TOP_MPLL_D2>,
 				 <&topckgen CLK_TOP_SPIM_MST_SEL>,
@@ -388,7 +388,6 @@ mmc0: mmc at 11230000 {
 		};
 
 		thermal: thermal at 1100c800 {
-			#thermal-sensor-cells = <1>;
 			compatible = "mediatek,mt7986-thermal";
 			reg = <0 0x1100c800 0 0x800>;
 			interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
@@ -396,30 +395,30 @@ thermal: thermal at 1100c800 {
 				 <&infracfg CLK_INFRA_ADC_26M_CK>,
 				 <&infracfg CLK_INFRA_ADC_FRC_CK>;
 			clock-names = "therm", "auxadc", "adc_32k";
-			mediatek,auxadc = <&auxadc>;
-			mediatek,apmixedsys = <&apmixedsys>;
 			nvmem-cells = <&thermal_calibration>;
 			nvmem-cell-names = "calibration-data";
+			#thermal-sensor-cells = <1>;
+			mediatek,auxadc = <&auxadc>;
+			mediatek,apmixedsys = <&apmixedsys>;
 		};
 
 		pcie: pcie at 11280000 {
 			compatible = "mediatek,mt7986-pcie",
 				     "mediatek,mt8192-pcie";
+			reg = <0x00 0x11280000 0x00 0x4000>;
+			reg-names = "pcie-mac";
+			ranges = <0x82000000 0x00 0x20000000 0x00
+				  0x20000000 0x00 0x10000000>;
 			device_type = "pci";
 			#address-cells = <3>;
 			#size-cells = <2>;
-			reg = <0x00 0x11280000 0x00 0x4000>;
-			reg-names = "pcie-mac";
 			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
 			bus-range = <0x00 0xff>;
-			ranges = <0x82000000 0x00 0x20000000 0x00
-				  0x20000000 0x00 0x10000000>;
 			clocks = <&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
 				 <&infracfg CLK_INFRA_IPCIE_CK>,
 				 <&infracfg CLK_INFRA_IPCIER_CK>,
 				 <&infracfg CLK_INFRA_IPCIEB_CK>;
 			clock-names = "pl_250m", "tl_26m", "peri_26m", "top_133m";
-			status = "disabled";
 
 			phys = <&pcie_port PHY_TYPE_PCIE>;
 			phy-names = "pcie-phy";
@@ -430,6 +429,8 @@ pcie: pcie at 11280000 {
 					<0 0 0 2 &pcie_intc 1>,
 					<0 0 0 3 &pcie_intc 2>,
 					<0 0 0 4 &pcie_intc 3>;
+			status = "disabled";
+
 			pcie_intc: interrupt-controller {
 				#address-cells = <0>;
 				#interrupt-cells = <1>;
@@ -440,9 +441,9 @@ pcie_intc: interrupt-controller {
 		pcie_phy: t-phy {
 			compatible = "mediatek,mt7986-tphy",
 				     "mediatek,generic-tphy-v2";
+			ranges;
 			#address-cells = <2>;
 			#size-cells = <2>;
-			ranges;
 			status = "disabled";
 
 			pcie_port: pcie-phy at 11c00000 {
@@ -467,9 +468,9 @@ thermal_calibration: calib at 274 {
 		usb_phy: t-phy at 11e10000 {
 			compatible = "mediatek,mt7986-tphy",
 				     "mediatek,generic-tphy-v2";
+			ranges = <0 0 0x11e10000 0x1700>;
 			#address-cells = <1>;
 			#size-cells = <1>;
-			ranges = <0 0 0x11e10000 0x1700>;
 			status = "disabled";
 
 			u2port0: usb-phy at 0 {
@@ -497,11 +498,11 @@ u2port1: usb-phy at 1000 {
 		};
 
 		ethsys: syscon at 15000000 {
-			 #address-cells = <1>;
-			 #size-cells = <1>;
 			 compatible = "mediatek,mt7986-ethsys",
 				      "syscon";
 			 reg = <0 0x15000000 0 0x1000>;
+			 #address-cells = <1>;
+			 #size-cells = <1>;
 			 #clock-cells = <1>;
 			 #reset-cells = <1>;
 		};
@@ -578,26 +579,26 @@ eth: ethernet at 15100000 {
 					  <&topckgen CLK_TOP_SGM_325M_SEL>;
 			assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
 						 <&apmixedsys CLK_APMIXED_SGMPLL>;
+			#reset-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			mediatek,ethsys = <&ethsys>;
 			mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
 			mediatek,wed-pcie = <&wed_pcie>;
 			mediatek,wed = <&wed0>, <&wed1>;
-			#reset-cells = <1>;
-			#address-cells = <1>;
-			#size-cells = <0>;
 			status = "disabled";
 		};
 
 		wifi: wifi at 18000000 {
 			compatible = "mediatek,mt7986-wmac";
+			reg = <0 0x18000000 0 0x1000000>,
+			      <0 0x10003000 0 0x1000>,
+			      <0 0x11d10000 0 0x1000>;
 			resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>;
 			reset-names = "consys";
 			clocks = <&topckgen CLK_TOP_CONN_MCUSYS_SEL>,
 				 <&topckgen CLK_TOP_AP2CNN_HOST_SEL>;
 			clock-names = "mcu", "ap2conn";
-			reg = <0 0x18000000 0 0x1000000>,
-			      <0 0x10003000 0 0x1000>,
-			      <0 0x11d10000 0 0x1000>;
 			interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.35.3



From zajec5 at gmail.com  Mon Feb 12 04:16:20 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 12 Feb 2024 13:16:20 +0100
Subject: [PATCH REBASED 2/2] arm64: dts: mediatek: mt7986: reorder nodes
In-Reply-To: <20240212121620.15035-1-zajec5@gmail.com>
References: <20240212121620.15035-1-zajec5@gmail.com>
Message-ID: <20240212121620.15035-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Use order described as preferred in DTS Coding Style:
1. Sort bus nodes by unit address
2. Use alpha-numerical order for the rest

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 116 +++++++++++-----------
 1 file changed, 58 insertions(+), 58 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index eba5e27a1bbe..b3f416b9a7a4 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -16,13 +16,6 @@ / {
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	clk40m: oscillator-40m {
-		compatible = "fixed-clock";
-		clock-frequency = <40000000>;
-		#clock-cells = <0>;
-		clock-output-names = "clkxtal";
-	};
-
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -59,6 +52,13 @@ cpu3: cpu at 3 {
 		};
 	};
 
+	clk40m: oscillator-40m {
+		compatible = "fixed-clock";
+		clock-frequency = <40000000>;
+		#clock-cells = <0>;
+		clock-output-names = "clkxtal";
+	};
+
 	psci {
 		compatible = "arm,psci-0.2";
 		method = "smc";
@@ -121,15 +121,6 @@ wo_boot: wo-boot at 15194000 {
 
 	};
 
-	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>;
-	};
-
 	soc {
 		compatible = "simple-bus";
 		ranges;
@@ -203,6 +194,19 @@ pio: pinctrl at 1001f000 {
 			#interrupt-cells = <2>;
 		};
 
+		pwm: pwm at 10048000 {
+			compatible = "mediatek,mt7986-pwm";
+			reg = <0 0x10048000 0 0x1000>;
+			#pwm-cells = <2>;
+			interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&topckgen CLK_TOP_PWM_SEL>,
+				 <&infracfg CLK_INFRA_PWM_STA>,
+				 <&infracfg CLK_INFRA_PWM1_CK>,
+				 <&infracfg CLK_INFRA_PWM2_CK>;
+			clock-names = "top", "main", "pwm1", "pwm2";
+			status = "disabled";
+		};
+
 		sgmiisys0: syscon at 10060000 {
 			compatible = "mediatek,mt7986-sgmiisys_0",
 				     "syscon";
@@ -240,19 +244,6 @@ crypto: crypto at 10320000 {
 			status = "disabled";
 		};
 
-		pwm: pwm at 10048000 {
-			compatible = "mediatek,mt7986-pwm";
-			reg = <0 0x10048000 0 0x1000>;
-			#pwm-cells = <2>;
-			interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&topckgen CLK_TOP_PWM_SEL>,
-				 <&infracfg CLK_INFRA_PWM_STA>,
-				 <&infracfg CLK_INFRA_PWM1_CK>,
-				 <&infracfg CLK_INFRA_PWM2_CK>;
-			clock-names = "top", "main", "pwm1", "pwm2";
-			status = "disabled";
-		};
-
 		uart0: serial at 11002000 {
 			compatible = "mediatek,mt7986-uart",
 				     "mediatek,mt6577-uart";
@@ -336,6 +327,21 @@ spi1: spi at 1100b000 {
 			status = "disabled";
 		};
 
+		thermal: thermal at 1100c800 {
+			compatible = "mediatek,mt7986-thermal";
+			reg = <0 0x1100c800 0 0x800>;
+			interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_THERM_CK>,
+				 <&infracfg CLK_INFRA_ADC_26M_CK>,
+				 <&infracfg CLK_INFRA_ADC_FRC_CK>;
+			clock-names = "therm", "auxadc", "adc_32k";
+			nvmem-cells = <&thermal_calibration>;
+			nvmem-cell-names = "calibration-data";
+			#thermal-sensor-cells = <1>;
+			mediatek,auxadc = <&auxadc>;
+			mediatek,apmixedsys = <&apmixedsys>;
+		};
+
 		auxadc: adc at 1100d000 {
 			compatible = "mediatek,mt7986-auxadc";
 			reg = <0 0x1100d000 0 0x1000>;
@@ -387,21 +393,6 @@ mmc0: mmc at 11230000 {
 			status = "disabled";
 		};
 
-		thermal: thermal at 1100c800 {
-			compatible = "mediatek,mt7986-thermal";
-			reg = <0 0x1100c800 0 0x800>;
-			interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&infracfg CLK_INFRA_THERM_CK>,
-				 <&infracfg CLK_INFRA_ADC_26M_CK>,
-				 <&infracfg CLK_INFRA_ADC_FRC_CK>;
-			clock-names = "therm", "auxadc", "adc_32k";
-			nvmem-cells = <&thermal_calibration>;
-			nvmem-cell-names = "calibration-data";
-			#thermal-sensor-cells = <1>;
-			mediatek,auxadc = <&auxadc>;
-			mediatek,apmixedsys = <&apmixedsys>;
-		};
-
 		pcie: pcie at 11280000 {
 			compatible = "mediatek,mt7986-pcie",
 				     "mediatek,mt8192-pcie";
@@ -533,20 +524,6 @@ wed1: wed at 15011000 {
 			mediatek,wo-ccif = <&wo_ccif1>;
 		};
 
-		wo_ccif0: syscon at 151a5000 {
-			compatible = "mediatek,mt7986-wo-ccif", "syscon";
-			reg = <0 0x151a5000 0 0x1000>;
-			interrupt-parent = <&gic>;
-			interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
-		};
-
-		wo_ccif1: syscon at 151ad000 {
-			compatible = "mediatek,mt7986-wo-ccif", "syscon";
-			reg = <0 0x151ad000 0 0x1000>;
-			interrupt-parent = <&gic>;
-			interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
-		};
-
 		eth: ethernet at 15100000 {
 			compatible = "mediatek,mt7986-eth";
 			reg = <0 0x15100000 0 0x80000>;
@@ -589,6 +566,20 @@ eth: ethernet at 15100000 {
 			status = "disabled";
 		};
 
+		wo_ccif0: syscon at 151a5000 {
+			compatible = "mediatek,mt7986-wo-ccif", "syscon";
+			reg = <0 0x151a5000 0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		wo_ccif1: syscon at 151ad000 {
+			compatible = "mediatek,mt7986-wo-ccif", "syscon";
+			reg = <0 0x151ad000 0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
 		wifi: wifi at 18000000 {
 			compatible = "mediatek,mt7986-wmac";
 			reg = <0 0x18000000 0 0x1000000>,
@@ -646,4 +637,13 @@ cpu_trip_active_low: active-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>;
+	};
 };
-- 
2.35.3



From kurt at linutronix.de  Mon Feb 12 04:17:37 2024
From: kurt at linutronix.de (Kurt Kanzenbach)
Date: Mon, 12 Feb 2024 13:17:37 +0100
Subject: [PATCH net-next] net: stmmac: Simplify mtl IRQ status checking
In-Reply-To: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>
References: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>
Message-ID: <87il2t98ri.fsf@kurt.kurt.home>

On Thu Feb 08 2024, Kurt Kanzenbach wrote:
> Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO overflow
> interrupts") disabled the RX FIFO overflow interrupts. However, it left the
> status variable around, but never checks it.
>
> As stmmac_host_mtl_irq_status() returns only 0 now, the code can be
> simplified.
>
> Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>

Hi Jakub,

why did this got marked as Changes Requested. What changes have to be
made?

Thanks,
Kurt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 861 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240212/15a6d49f/attachment-0001.sig>

From anup at brainfault.org  Mon Feb 12 04:23:58 2024
From: anup at brainfault.org (Anup Patel)
Date: Mon, 12 Feb 2024 17:53:58 +0530
Subject: [PATCH v5 00/12] RISCV: Add kvm Sstc timer selftests
In-Reply-To: <cover.1705916069.git.haibo1.xu@intel.com>
References: <cover.1705916069.git.haibo1.xu@intel.com>
Message-ID: <CAAhSdy2wFzk0h5MiM5y9Fij0HyWake=7vNuV1MExUxkEtMWShw@mail.gmail.com>

On Mon, Jan 22, 2024 at 3:15?PM Haibo Xu <haibo1.xu at intel.com> wrote:
>
> The RISC-V arch_timer selftests is used to validate Sstc timer
> functionality in a guest, which sets up periodic timer interrupts
> and check the basic interrupt status upon its receipt.
>
> This KVM selftests was ported from aarch64 arch_timer and tested
> with Linux v6.7-rc8 on a Qemu riscv64 virt machine.
>
> ---
> Changed since v4:
>   * Rebased to Linux 6.7-rc8
>   * Added new patch(2/12) to clean up the data type in struct test_args
>   * Re-ordered patch(11/11) in v4 to patch(3/12)
>   * Changed the timer_err_margin_us type from int to uint32_t
>
> Haibo Xu (11):
>   KVM: arm64: selftests: Data type cleanup for arch_timer test
>   KVM: arm64: selftests: Enable tuning of error margin in arch_timer
>     test
>   KVM: arm64: selftests: Split arch_timer test code
>   KVM: selftests: Add CONFIG_64BIT definition for the build
>   tools: riscv: Add header file csr.h
>   tools: riscv: Add header file vdso/processor.h
>   KVM: riscv: selftests: Switch to use macro from csr.h
>   KVM: riscv: selftests: Add exception handling support
>   KVM: riscv: selftests: Add guest helper to get vcpu id
>   KVM: riscv: selftests: Change vcpu_has_ext to a common function
>   KVM: riscv: selftests: Add sstc timer test
>
> Paolo Bonzini (1):
>   selftests/kvm: Fix issues with $(SPLIT_TESTS)

Rebased on Linux-6.8-rc4 and queued this series for Linux-6.9

Thanks,
Anup

>
>  tools/arch/riscv/include/asm/csr.h            | 541 ++++++++++++++++++
>  tools/arch/riscv/include/asm/vdso/processor.h |  32 ++
>  tools/testing/selftests/kvm/Makefile          |  27 +-
>  .../selftests/kvm/aarch64/arch_timer.c        | 295 +---------
>  tools/testing/selftests/kvm/arch_timer.c      | 259 +++++++++
>  .../selftests/kvm/include/aarch64/processor.h |   4 -
>  .../selftests/kvm/include/kvm_util_base.h     |   9 +
>  .../selftests/kvm/include/riscv/arch_timer.h  |  71 +++
>  .../selftests/kvm/include/riscv/processor.h   |  65 ++-
>  .../testing/selftests/kvm/include/test_util.h |   2 +
>  .../selftests/kvm/include/timer_test.h        |  45 ++
>  .../selftests/kvm/lib/riscv/handlers.S        | 101 ++++
>  .../selftests/kvm/lib/riscv/processor.c       |  87 +++
>  .../testing/selftests/kvm/riscv/arch_timer.c  | 111 ++++
>  .../selftests/kvm/riscv/get-reg-list.c        |  11 +-
>  15 files changed, 1353 insertions(+), 307 deletions(-)
>  create mode 100644 tools/arch/riscv/include/asm/csr.h
>  create mode 100644 tools/arch/riscv/include/asm/vdso/processor.h
>  create mode 100644 tools/testing/selftests/kvm/arch_timer.c
>  create mode 100644 tools/testing/selftests/kvm/include/riscv/arch_timer.h
>  create mode 100644 tools/testing/selftests/kvm/include/timer_test.h
>  create mode 100644 tools/testing/selftests/kvm/lib/riscv/handlers.S
>  create mode 100644 tools/testing/selftests/kvm/riscv/arch_timer.c
>
> --
> 2.34.1
>


From quic_riteshk at quicinc.com  Mon Feb 12 04:28:29 2024
From: quic_riteshk at quicinc.com (Ritesh Kumar)
Date: Mon, 12 Feb 2024 17:58:29 +0530
Subject: [PATCH 2/2] arm64: dts: qcom: qcm6490-idp: add display and panel
In-Reply-To: <9d1c684f-51ac-4d9c-a189-940ff65e0cab@linaro.org>
References: <20240116094935.9988-1-quic_riteshk@quicinc.com>
 <20240116094935.9988-3-quic_riteshk@quicinc.com>
 <20a8efd1-e243-434e-8f75-aa786ac8014f@linaro.org>
 <CAA8EJpqQVuS+yqXQ2y5sNQrRVg7tcQAJ3ywsEjg+O=7TkUZWLQ@mail.gmail.com>
 <99a9a562-9f6f-411c-be1c-0a28fc2524dd@quicinc.com>
 <CAA8EJppj+cDnw7p4yANvF0FmEhX3+L5xUq8w3TeevAGhcpo1Yg@mail.gmail.com>
 <9d1c684f-51ac-4d9c-a189-940ff65e0cab@linaro.org>
Message-ID: <7932ccbb-3b41-49e2-bb88-9c2633002a0d@quicinc.com>


On 1/23/2024 11:34 PM, Konrad Dybcio wrote:
>
>
> On 1/23/24 16:12, Dmitry Baryshkov wrote:
>> On Tue, 23 Jan 2024 at 15:43, Ritesh Kumar <quic_riteshk at quicinc.com> 
>> wrote:
>>>
>>>
>>> On 1/16/2024 6:27 PM, Dmitry Baryshkov wrote:
>>>
>>>> On Tue, 16 Jan 2024 at 14:06, Konrad Dybcio 
>>>> <konrad.dybcio at linaro.org> wrote:
>>>>>
>>>>>
>>>>> On 1/16/24 10:49, Ritesh Kumar wrote:
>>>>>> Enable Display Subsystem with Novatek NT36672E Panel
>>>>>> on qcm6490 idp platform.
>>>>>>
>>>>>> Signed-off-by: Ritesh Kumar <quic_riteshk at quicinc.com>
>>>>>> ---
>>>>>> ??? arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 100 
>>>>>> +++++++++++++++++++++++
>>>>>> ??? 1 file changed, 100 insertions(+)
>>>>>>
>>>>>> diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts 
>>>>>> b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
>>>>>> index 2a6e4907c5ee..efa5252130a1 100644
>>>>>> --- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
>>>>>> +++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
>>>>>> @@ -9,6 +9,7 @@
>>>>>> ??? #define PM7250B_SID 8
>>>>>> ??? #define PM7250B_SID1 9
>>>>>>
>>>>>> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
>>>>>> ??? #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
>>>>>> ??? #include "sc7280.dtsi"
>>>>>> ??? #include "pm7250b.dtsi"
>>>>>> @@ -38,6 +39,25 @@
>>>>>> ??????????????? stdout-path = "serial0:115200n8";
>>>>>> ??????? };
>>>>>>
>>>>>> +???? lcd_disp_bias: lcd-disp-bias-regulator {
>>>>>> +???????????? compatible = "regulator-fixed";
>>>>>> +???????????? regulator-name = "lcd_disp_bias";
>>>>>> +???????????? regulator-min-microvolt = <5500000>;
>>>>>> +???????????? regulator-max-microvolt = <5500000>;
>>>>>> +???????????? gpio = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
>>>>>> +???????????? enable-active-high;
>>>>>> +???????????? pinctrl-names = "default";
>>>>>> +???????????? pinctrl-0 = <&lcd_disp_bias_en>;
>>>>> property-n
>>>>> property-names
>>>>>
>>>>> all throughout the patch
>>>
>>> Thanks, I will update in the new version.
>>>
>>>>>> +&gpu {
>>>>>> +???? status = "disabled";
>>>>>> +};
>>>>> Hm.. generally we disable the GPU in the SoC DT, but that doesn't
>>>>> seem to have happened here..
>>>>>
>>>>> Thinking about it more, is disabling it here necessary? Does it
>>>>> not fail gracefully?
>>>> Missed this.
>>>>
>>>> I'd say, I don't see a reason to disable it at all. The GPU should be
>>>> working on sc7280 / qcm4290.
>>>
>>> With GPU device node enabled, adreno_bind failure is seen as the
>>> "speed_bin" was not populated on QCM6490 target which leads to display
>>> bind failure.
>>
>> Excuse me please. The GPU node for sc7280 already has speed_bin, which
>> points to qfprom + 0x1e9, bits 5 to 9.
>>
>> Do you mean that qcm6490 uses different speed bin location? Or
>> different values for the speed bins?
>>
>>> Spoke with GPU team and on QCM6490 board, only CPU rendering is
>>> supported for now and there is no plan to enable GPU rendering in near
>>> future.
>>
>> This sounds like having the feature disabled for no particular reason.
>> Both the kernel and Mesa have supported the Adreno 635 for quite a
>> while.
>
> 643 [1], [2]
>
>>
>>> In this regard, what do you suggest
>>>
>>> 1) Disable GPU in QCM6490 DT (as per the current patch)
>>> 2) Disable GPU in the SoC DT, but enable it in other platform DTs. 
>>> (This
>>> will prompt change in all the dt's and we don't have all the devices to
>>> test)
>>
>> The second option definitely follows what is present on other platforms.
>>
>>> Please let me know your views on it.
>>
>> Please enable the GPU instead.
>
> +1
>
> Konrad
>
> [1] 
> https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25408/diffs?commit_id=b1e851d66c3a3e53f1a464023f675f3f6cbd3503
> [2] 
> https://patches.linaro.org/project/linux-arm-msm/cover/20230926-topic-a643-v1-0-7af6937ac0a3 at linaro.org/

Thanks for the help. After applying missing patches from series 
https://patches.linaro.org/project/linux-arm-msm/cover/20230926-topic-a643-v1-0-7af6937ac0a3 at linaro.org/
in my local build, GPU is working fine. GPU disablement change is not 
needed. I will send new version of patch removing GPU part and 
addressing other review comments.

Thanks,
Ritesh


From cristian.marussi at arm.com  Mon Feb 12 04:32:24 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:24 +0000
Subject: [PATCH 02/11] firmware: arm_scmi: Add a common helper to check if a message is supported
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-3-cristian.marussi@arm.com>

A common helper is provided to check if a specific protocol message is
supported or not.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c    | 34 +++++++++++++++++++++++++++
 drivers/firmware/arm_scmi/protocols.h |  4 ++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 3ea64b22cf0d..4a64ad5c21ee 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1754,10 +1754,44 @@ static void scmi_common_fastchannel_db_ring(struct scmi_fc_db_info *db)
 #endif
 }
 
+/**
+ * scmi_protocol_msg_check  - Check protocol message attributes
+ *
+ * @ph: A reference to the protocol handle.
+ * @message_id: The ID of the message to check.
+ * @attributes: A parameter to optionally return the retrieved message
+ *		attributes, in case of Success.
+ *
+ * An helper to check protocol message attributes for a specific protocol
+ * and message pair.
+ *
+ * Return: 0 on SUCCESS
+ */
+static int scmi_protocol_msg_check(const struct scmi_protocol_handle *ph,
+				   u32 message_id, u32 *attributes)
+{
+	int ret;
+	struct scmi_xfer *t;
+
+	ret = xfer_get_init(ph, PROTOCOL_MESSAGE_ATTRIBUTES,
+			    sizeof(__le32), 0, &t);
+	if (ret)
+		return ret;
+
+	put_unaligned_le32(message_id, t->tx.buf);
+	ret = do_xfer(ph, t);
+	if (!ret && attributes)
+		*attributes = get_unaligned_le32(t->rx.buf);
+	xfer_put(ph, t);
+
+	return ret;
+}
+
 static const struct scmi_proto_helpers_ops helpers_ops = {
 	.extended_name_get = scmi_common_extended_name_get,
 	.iter_response_init = scmi_iterator_init,
 	.iter_response_run = scmi_iterator_run,
+	.protocol_msg_check = scmi_protocol_msg_check,
 	.fastchannel_init = scmi_common_fastchannel_init,
 	.fastchannel_db_ring = scmi_common_fastchannel_db_ring,
 };
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index e683c26f24eb..26a3edd49fea 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -251,6 +251,8 @@ struct scmi_fc_info {
  *			provided in @ops.
  * @iter_response_run: A common helper to trigger the run of a previously
  *		       initialized iterator.
+ * @protocol_msg_check: A common helper to check is a specific protocol message
+ *			is supported.
  * @fastchannel_init: A common helper used to initialize FC descriptors by
  *		      gathering FC descriptions from the SCMI platform server.
  * @fastchannel_db_ring: A common helper to ring a FC doorbell.
@@ -264,6 +266,8 @@ struct scmi_proto_helpers_ops {
 				    unsigned int max_resources, u8 msg_id,
 				    size_t tx_size, void *priv);
 	int (*iter_response_run)(void *iter);
+	int (*protocol_msg_check)(const struct scmi_protocol_handle *ph,
+				  u32 message_id, u32 *attributes);
 	void (*fastchannel_init)(const struct scmi_protocol_handle *ph,
 				 u8 describe_id, u32 message_id,
 				 u32 valid_size, u32 domain,
-- 
2.43.0



From cristian.marussi at arm.com  Mon Feb 12 04:32:22 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:22 +0000
Subject: [PATCH 00/11] Add SCMI core checks for notification support.
Message-ID: <20240212123233.1230090-1-cristian.marussi@arm.com>

Hi,

this small series adds a new logic into the SCMI core to implicitly check
for notification support when some SCMI driver attempts to register for
notifications.

Till now, trying to register a notifier for an unsuppported notification
returned an error and this behaviour generated unneeded message exchanges:
the only way to avoid this was to lookup in advance the specific protocol
and resources available in order to avoid registering at all any notifier
where not supported.

Anyway, not all protocols currently expose the related notification info
to lookup and, moreover, no check was performed anywhere to verify if the
specific notification enable/disable command was supported at all (almost
all of these notification enable commands are optional).

Last but not least, this kind of support checks could and should be handled
transparently by the SCMI core.

With this series each protocol can optionally provide an event_ops
callcback that will be invoked by the core to lookup if the specific
command and event/resource notification is supported on the running
platform; the SCMI core then, at initialization time, will use such
callbacks to take care to collect such info and mark unsupported
events/resources.

Later on, when an SCMI driver attempts to register a notifier for a
specific event/resources, it will fail and return an error to the caller
if the requested notification was not supported.

The end-result is that the SCMI driver user will fail to register a
notifier if the related command or resource is not supported (like before),
BUT without the need of exchanging any message NOR the need to actively
lookup if the specified notification is supported.

The last two patches in the series, instead, take care to extend the Perf
notification report to provide the pre-calculated frequencies corresponding
to the level or index carried by the specific notification report.
These latter 2 patches are indeed only slighly related to this series at
large but are provided here for ease of access.

Based on sudeep/for-next/scmi/updates on top of commit

7dd3d11f4dac ("clk: scmi: Add support for forbidden clock state controls")

Thanks,
Cristian

---

Cristian Marussi (11):
  firmware: arm_scmi: Check for notification support
  firmware: arm_scmi: Add a common helper to check if a message is
    supported
  firmware: arm_scmi: Implement Perf .is_notify_supported callback
  firmware: arm_scmi: Implement Power .is_notify_supported callback
  firmware: arm_scmi: Implement SysPower .is_notify_supported callback
  firmware: arm_scmi: Implement Clock .is_notify_supported callback
  firmware: arm_scmi: Implement Sensor .is_notify_supported callback
  firmware: arm_scmi: Implement Reset .is_notify_supported callback
  firmware: arm_scmi: Implement Powercap .is_notify_supported callback
  firmware: arm_scmi: Use opps_by_lvl to store opps
  firmware: arm_scmi: Report frequencies in Perf notifications

 drivers/firmware/arm_scmi/clock.c     |  47 ++++++++-
 drivers/firmware/arm_scmi/driver.c    |  34 ++++++
 drivers/firmware/arm_scmi/notify.c    |  17 ++-
 drivers/firmware/arm_scmi/notify.h    |   4 +
 drivers/firmware/arm_scmi/perf.c      | 144 +++++++++++++++++++++++---
 drivers/firmware/arm_scmi/power.c     |  30 +++++-
 drivers/firmware/arm_scmi/powercap.c  |  45 +++++++-
 drivers/firmware/arm_scmi/protocols.h |   4 +
 drivers/firmware/arm_scmi/reset.c     |  37 +++++--
 drivers/firmware/arm_scmi/sensors.c   |  37 ++++++-
 drivers/firmware/arm_scmi/system.c    |  16 +++
 include/linux/scmi_protocol.h         |   3 +
 12 files changed, 383 insertions(+), 35 deletions(-)

-- 
2.43.0




From cristian.marussi at arm.com  Mon Feb 12 04:32:23 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:23 +0000
Subject: [PATCH 01/11] firmware: arm_scmi: Check for notification support
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-2-cristian.marussi@arm.com>

When registering protocol events, use the optional .is_notify_supported
callback provided by the protocol to check if that specific notification
type is available for that particular resource on the running system,
marking it as unsupported otherwise.

Then, when a notification enable request is received, return an error if
it was previously marked as unsuppported, so avoiding to send a needless
notification enable command and check the returned value for failure.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/notify.c | 17 ++++++++++++++++-
 drivers/firmware/arm_scmi/notify.h |  4 ++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c
index 0efd20cd9d69..27c52531194d 100644
--- a/drivers/firmware/arm_scmi/notify.c
+++ b/drivers/firmware/arm_scmi/notify.c
@@ -99,6 +99,7 @@
 #define PROTO_ID_MASK		GENMASK(31, 24)
 #define EVT_ID_MASK		GENMASK(23, 16)
 #define SRC_ID_MASK		GENMASK(15, 0)
+#define NOTIF_UNSUPP		-1
 
 /*
  * Builds an unsigned 32bit key from the given input tuple to be used
@@ -788,6 +789,7 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
 
 	pd->ph = ph;
 	for (i = 0; i < ee->num_events; i++, evt++) {
+		int id;
 		struct scmi_registered_event *r_evt;
 
 		r_evt = devm_kzalloc(ni->handle->dev, sizeof(*r_evt),
@@ -809,6 +811,11 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
 		if (!r_evt->report)
 			return -ENOMEM;
 
+		for (id = 0; id < r_evt->num_sources; id++)
+			if (ee->ops->is_notify_supported &&
+			    !ee->ops->is_notify_supported(ph, r_evt->evt->id, id))
+				refcount_set(&r_evt->sources[id], NOTIF_UNSUPP);
+
 		pd->registered_events[i] = r_evt;
 		/* Ensure events are updated */
 		smp_wmb();
@@ -1166,7 +1173,13 @@ static inline int __scmi_enable_evt(struct scmi_registered_event *r_evt,
 			int ret = 0;
 
 			sid = &r_evt->sources[src_id];
-			if (refcount_read(sid) == 0) {
+			if (refcount_read(sid) == NOTIF_UNSUPP) {
+				dev_dbg(r_evt->proto->ph->dev,
+					"Notification NOT supported - proto_id:%d  evt_id:%d  src_id:%d",
+					r_evt->proto->id, r_evt->evt->id,
+					src_id);
+				ret = -EOPNOTSUPP;
+			} else if (refcount_read(sid) == 0) {
 				ret = REVT_NOTIFY_ENABLE(r_evt, r_evt->evt->id,
 							 src_id);
 				if (!ret)
@@ -1179,6 +1192,8 @@ static inline int __scmi_enable_evt(struct scmi_registered_event *r_evt,
 	} else {
 		for (; num_sources; src_id++, num_sources--) {
 			sid = &r_evt->sources[src_id];
+			if (refcount_read(sid) == NOTIF_UNSUPP)
+				continue;
 			if (refcount_dec_and_test(sid))
 				REVT_NOTIFY_DISABLE(r_evt,
 						    r_evt->evt->id, src_id);
diff --git a/drivers/firmware/arm_scmi/notify.h b/drivers/firmware/arm_scmi/notify.h
index 4e9b627edfef..76758a736cf4 100644
--- a/drivers/firmware/arm_scmi/notify.h
+++ b/drivers/firmware/arm_scmi/notify.h
@@ -35,6 +35,8 @@ struct scmi_protocol_handle;
 
 /**
  * struct scmi_event_ops  - Protocol helpers called by the notification core.
+ * @is_notify_supported: Return 0 if the specified notification for the
+ *			 specified resource (src_id) is supported.
  * @get_num_sources: Returns the number of possible events' sources for this
  *		     protocol
  * @set_notify_enabled: Enable/disable the required evt_id/src_id notifications
@@ -50,6 +52,8 @@ struct scmi_protocol_handle;
  *	    process context.
  */
 struct scmi_event_ops {
+	bool (*is_notify_supported)(const struct scmi_protocol_handle *ph,
+				    u8 evt_id, u32 src_id);
 	int (*get_num_sources)(const struct scmi_protocol_handle *ph);
 	int (*set_notify_enabled)(const struct scmi_protocol_handle *ph,
 				  u8 evt_id, u32 src_id, bool enabled);
-- 
2.43.0



From cristian.marussi at arm.com  Mon Feb 12 04:32:25 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:25 +0000
Subject: [PATCH 03/11] firmware: arm_scmi: Implement Perf .is_notify_supported callback
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-4-cristian.marussi@arm.com>

Add a preliminary check to verify if Perf-related notify enable commands
are supported at all by the running platform, and then provide the callback
needed to allow the core SCMI notification subsytem to fine-grain check if
a specific resource domain supports notifications.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/perf.c | 45 +++++++++++++++++++++++++++++---
 1 file changed, 42 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index 9e7b1ee94940..2627ace5b07f 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -182,6 +182,8 @@ struct scmi_perf_info {
 	enum scmi_power_scale power_scale;
 	u64 stats_addr;
 	u32 stats_size;
+	bool notify_lvl_cmd;
+	bool notify_lim_cmd;
 	struct perf_dom_info *dom_info;
 };
 
@@ -222,6 +224,15 @@ static int scmi_perf_attributes_get(const struct scmi_protocol_handle *ph,
 	}
 
 	ph->xops->xfer_put(ph, t);
+
+	if (!ret) {
+		if (!ph->hops->protocol_msg_check(ph, PERF_NOTIFY_LEVEL, NULL))
+			pi->notify_lvl_cmd = true;
+
+		if (!ph->hops->protocol_msg_check(ph, PERF_NOTIFY_LIMITS, NULL))
+			pi->notify_lim_cmd = true;
+	}
+
 	return ret;
 }
 
@@ -239,6 +250,7 @@ static void scmi_perf_xa_destroy(void *data)
 static int
 scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
 				struct perf_dom_info *dom_info,
+				bool notify_lim_cmd, bool notify_lvl_cmd,
 				u32 version)
 {
 	int ret;
@@ -260,8 +272,12 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
 
 		dom_info->set_limits = SUPPORTS_SET_LIMITS(flags);
 		dom_info->info.set_perf = SUPPORTS_SET_PERF_LVL(flags);
-		dom_info->perf_limit_notify = SUPPORTS_PERF_LIMIT_NOTIFY(flags);
-		dom_info->perf_level_notify = SUPPORTS_PERF_LEVEL_NOTIFY(flags);
+		if (notify_lim_cmd)
+			dom_info->perf_limit_notify =
+				SUPPORTS_PERF_LIMIT_NOTIFY(flags);
+		if (notify_lvl_cmd)
+			dom_info->perf_level_notify =
+				SUPPORTS_PERF_LEVEL_NOTIFY(flags);
 		dom_info->perf_fastchannels = SUPPORTS_PERF_FASTCHANNELS(flags);
 		if (PROTOCOL_REV_MAJOR(version) >= 0x4)
 			dom_info->level_indexing_mode =
@@ -993,6 +1009,27 @@ static const struct scmi_perf_proto_ops perf_proto_ops = {
 	.power_scale_get = scmi_power_scale_get,
 };
 
+static bool scmi_perf_notify_supported(const struct scmi_protocol_handle *ph,
+				       u8 evt_id, u32 src_id)
+{
+	bool supported;
+	struct perf_dom_info *dom;
+
+	if (evt_id >= ARRAY_SIZE(evt_2_cmd))
+		return false;
+
+	dom = scmi_perf_domain_lookup(ph, src_id);
+	if (IS_ERR(dom))
+		return false;
+
+	if (evt_id == SCMI_EVENT_PERFORMANCE_LIMITS_CHANGED)
+		supported = dom->perf_limit_notify;
+	else
+		supported = dom->perf_level_notify;
+
+	return supported;
+}
+
 static int scmi_perf_set_notify_enabled(const struct scmi_protocol_handle *ph,
 					u8 evt_id, u32 src_id, bool enable)
 {
@@ -1082,6 +1119,7 @@ static const struct scmi_event perf_events[] = {
 };
 
 static const struct scmi_event_ops perf_event_ops = {
+	.is_notify_supported = scmi_perf_notify_supported,
 	.get_num_sources = scmi_perf_get_num_sources,
 	.set_notify_enabled = scmi_perf_set_notify_enabled,
 	.fill_custom_report = scmi_perf_fill_custom_report,
@@ -1126,7 +1164,8 @@ static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph)
 		struct perf_dom_info *dom = pinfo->dom_info + domain;
 
 		dom->id = domain;
-		scmi_perf_domain_attributes_get(ph, dom, version);
+		scmi_perf_domain_attributes_get(ph, dom, pinfo->notify_lim_cmd,
+						pinfo->notify_lvl_cmd, version);
 		scmi_perf_describe_levels_get(ph, dom, version);
 
 		if (dom->perf_fastchannels)
-- 
2.43.0



From cristian.marussi at arm.com  Mon Feb 12 04:32:26 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:26 +0000
Subject: [PATCH 04/11] firmware: arm_scmi: Implement Power .is_notify_supported callback
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-5-cristian.marussi@arm.com>

Add a preliminary check to verify if Power-related notify enable commands
are supported at all by the running platform, and then provide the callback
needed to allow the core SCMI notification subsytem to fine-grain check if
a specific resource domain supports notifications.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/power.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/arm_scmi/power.c b/drivers/firmware/arm_scmi/power.c
index c2e6b9b4d941..49666bd1d8ac 100644
--- a/drivers/firmware/arm_scmi/power.c
+++ b/drivers/firmware/arm_scmi/power.c
@@ -68,6 +68,7 @@ struct power_dom_info {
 
 struct scmi_power_info {
 	u32 version;
+	bool notify_state_change_cmd;
 	int num_domains;
 	u64 stats_addr;
 	u32 stats_size;
@@ -97,13 +98,18 @@ static int scmi_power_attributes_get(const struct scmi_protocol_handle *ph,
 	}
 
 	ph->xops->xfer_put(ph, t);
+
+	if (!ret)
+		if (!ph->hops->protocol_msg_check(ph, POWER_STATE_NOTIFY, NULL))
+			pi->notify_state_change_cmd = true;
+
 	return ret;
 }
 
 static int
 scmi_power_domain_attributes_get(const struct scmi_protocol_handle *ph,
 				 u32 domain, struct power_dom_info *dom_info,
-				 u32 version)
+				 u32 version, bool notify_state_change_cmd)
 {
 	int ret;
 	u32 flags;
@@ -122,7 +128,9 @@ scmi_power_domain_attributes_get(const struct scmi_protocol_handle *ph,
 	if (!ret) {
 		flags = le32_to_cpu(attr->flags);
 
-		dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags);
+		if (notify_state_change_cmd)
+			dom_info->state_set_notify =
+				SUPPORTS_STATE_SET_NOTIFY(flags);
 		dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags);
 		dom_info->state_set_sync = SUPPORTS_STATE_SET_SYNC(flags);
 		strscpy(dom_info->name, attr->name, SCMI_SHORT_NAME_MAX_SIZE);
@@ -231,6 +239,20 @@ static int scmi_power_request_notify(const struct scmi_protocol_handle *ph,
 	return ret;
 }
 
+static bool scmi_power_notify_supported(const struct scmi_protocol_handle *ph,
+					u8 evt_id, u32 src_id)
+{
+	struct power_dom_info *dom;
+	struct scmi_power_info *pinfo = ph->get_priv(ph);
+
+	if (evt_id != SCMI_EVENT_POWER_STATE_CHANGED ||
+	    src_id >= pinfo->num_domains)
+		return false;
+
+	dom = pinfo->dom_info + src_id;
+	return dom->state_set_notify;
+}
+
 static int scmi_power_set_notify_enabled(const struct scmi_protocol_handle *ph,
 					 u8 evt_id, u32 src_id, bool enable)
 {
@@ -285,6 +307,7 @@ static const struct scmi_event power_events[] = {
 };
 
 static const struct scmi_event_ops power_event_ops = {
+	.is_notify_supported = scmi_power_notify_supported,
 	.get_num_sources = scmi_power_get_num_sources,
 	.set_notify_enabled = scmi_power_set_notify_enabled,
 	.fill_custom_report = scmi_power_fill_custom_report,
@@ -326,7 +349,8 @@ static int scmi_power_protocol_init(const struct scmi_protocol_handle *ph)
 	for (domain = 0; domain < pinfo->num_domains; domain++) {
 		struct power_dom_info *dom = pinfo->dom_info + domain;
 
-		scmi_power_domain_attributes_get(ph, domain, dom, version);
+		scmi_power_domain_attributes_get(ph, domain, dom, version,
+						 pinfo->notify_state_change_cmd);
 	}
 
 	pinfo->version = version;
-- 
2.43.0



From cristian.marussi at arm.com  Mon Feb 12 04:32:27 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:27 +0000
Subject: [PATCH 05/11] firmware: arm_scmi: Implement SysPower .is_notify_supported callback
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-6-cristian.marussi@arm.com>

Add a preliminary check to verify if SysPower-related notify enable
commands are supported at all by the running platform, and then provide the
callback needed to allow the core SCMI notification subsytem to fine-grain
check if a specific resource domain supports notifications.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/system.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/firmware/arm_scmi/system.c b/drivers/firmware/arm_scmi/system.c
index 1621da97bcbb..b6358c155f7f 100644
--- a/drivers/firmware/arm_scmi/system.c
+++ b/drivers/firmware/arm_scmi/system.c
@@ -36,8 +36,20 @@ struct scmi_system_power_state_notifier_payld {
 struct scmi_system_info {
 	u32 version;
 	bool graceful_timeout_supported;
+	bool power_state_notify_cmd;
 };
 
+static bool scmi_system_notify_supported(const struct scmi_protocol_handle *ph,
+					 u8 evt_id, u32 src_id)
+{
+	struct scmi_system_info *pinfo = ph->get_priv(ph);
+
+	if (evt_id != SCMI_EVENT_SYSTEM_POWER_STATE_NOTIFIER)
+		return false;
+
+	return pinfo->power_state_notify_cmd;
+}
+
 static int scmi_system_request_notify(const struct scmi_protocol_handle *ph,
 				      bool enable)
 {
@@ -114,6 +126,7 @@ static const struct scmi_event system_events[] = {
 };
 
 static const struct scmi_event_ops system_event_ops = {
+	.is_notify_supported = scmi_system_notify_supported,
 	.set_notify_enabled = scmi_system_set_notify_enabled,
 	.fill_custom_report = scmi_system_fill_custom_report,
 };
@@ -147,6 +160,9 @@ static int scmi_system_protocol_init(const struct scmi_protocol_handle *ph)
 	if (PROTOCOL_REV_MAJOR(pinfo->version) >= 0x2)
 		pinfo->graceful_timeout_supported = true;
 
+	if (!ph->hops->protocol_msg_check(ph, SYSTEM_POWER_STATE_NOTIFY, NULL))
+		pinfo->power_state_notify_cmd = true;
+
 	return ph->set_priv(ph, pinfo, version);
 }
 
-- 
2.43.0



From cristian.marussi at arm.com  Mon Feb 12 04:32:28 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:28 +0000
Subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock .is_notify_supported callback
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-7-cristian.marussi@arm.com>

Add a preliminary check to verify if Clock-related notify enable commands
are supported at all by the running platform, and then provide the callback
needed to allow the core SCMI notification subsytem to fine-grain check if
a specific resource domain supports notifications.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/clock.c | 47 ++++++++++++++++++++++++++++---
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 959e48aba1b5..85eda5db40ba 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -158,6 +158,8 @@ struct clock_info {
 	u32 version;
 	int num_clocks;
 	int max_async_req;
+	bool notify_rate_changed_cmd;
+	bool notify_rate_change_requested_cmd;
 	atomic_t cur_async_req;
 	struct scmi_clock_info *clk;
 	int (*clock_config_set)(const struct scmi_protocol_handle *ph,
@@ -204,6 +206,17 @@ scmi_clock_protocol_attributes_get(const struct scmi_protocol_handle *ph,
 	}
 
 	ph->xops->xfer_put(ph, t);
+
+	if (!ret) {
+		if (!ph->hops->protocol_msg_check(ph, CLOCK_RATE_NOTIFY, NULL))
+			ci->notify_rate_changed_cmd = true;
+
+		if (!ph->hops->protocol_msg_check(ph,
+						  CLOCK_RATE_CHANGE_REQUESTED_NOTIFY,
+						  NULL))
+			ci->notify_rate_change_requested_cmd = true;
+	}
+
 	return ret;
 }
 
@@ -329,13 +342,14 @@ scmi_clock_get_permissions(const struct scmi_protocol_handle *ph, u32 clk_id,
 }
 
 static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph,
-				     u32 clk_id, struct scmi_clock_info *clk,
+				     u32 clk_id, struct clock_info *cinfo,
 				     u32 version)
 {
 	int ret;
 	u32 attributes;
 	struct scmi_xfer *t;
 	struct scmi_msg_resp_clock_attributes *attr;
+	struct scmi_clock_info *clk = cinfo->clk + clk_id;
 
 	ret = ph->xops->xfer_get_init(ph, CLOCK_ATTRIBUTES,
 				      sizeof(clk_id), sizeof(*attr), &t);
@@ -368,9 +382,11 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph,
 						    NULL, clk->name,
 						    SCMI_MAX_STR_SIZE);
 
-		if (SUPPORTS_RATE_CHANGED_NOTIF(attributes))
+		if (cinfo->notify_rate_changed_cmd &&
+		    SUPPORTS_RATE_CHANGED_NOTIF(attributes))
 			clk->rate_changed_notifications = true;
-		if (SUPPORTS_RATE_CHANGE_REQUESTED_NOTIF(attributes))
+		if (cinfo->notify_rate_change_requested_cmd &&
+		    SUPPORTS_RATE_CHANGE_REQUESTED_NOTIF(attributes))
 			clk->rate_change_requested_notifications = true;
 		if (SUPPORTS_PARENT_CLOCK(attributes))
 			scmi_clock_possible_parents(ph, clk_id, clk);
@@ -896,6 +912,28 @@ static const struct scmi_clk_proto_ops clk_proto_ops = {
 	.parent_get = scmi_clock_get_parent,
 };
 
+static bool scmi_clk_notify_supported(const struct scmi_protocol_handle *ph,
+				      u8 evt_id, u32 src_id)
+{
+	bool supported;
+	struct scmi_clock_info *clk;
+	struct clock_info *ci = ph->get_priv(ph);
+
+	if (evt_id >= ARRAY_SIZE(evt_2_cmd))
+		return false;
+
+	clk = scmi_clock_domain_lookup(ci, src_id);
+	if (IS_ERR(clk))
+		return false;
+
+	if (evt_id == SCMI_EVENT_CLOCK_RATE_CHANGED)
+		supported = clk->rate_changed_notifications;
+	else
+		supported = clk->rate_change_requested_notifications;
+
+	return supported;
+}
+
 static int scmi_clk_rate_notify(const struct scmi_protocol_handle *ph,
 				u32 clk_id, int message_id, bool enable)
 {
@@ -980,6 +1018,7 @@ static const struct scmi_event clk_events[] = {
 };
 
 static const struct scmi_event_ops clk_event_ops = {
+	.is_notify_supported = scmi_clk_notify_supported,
 	.get_num_sources = scmi_clk_get_num_sources,
 	.set_notify_enabled = scmi_clk_set_notify_enabled,
 	.fill_custom_report = scmi_clk_fill_custom_report,
@@ -1021,7 +1060,7 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
 	for (clkid = 0; clkid < cinfo->num_clocks; clkid++) {
 		struct scmi_clock_info *clk = cinfo->clk + clkid;
 
-		ret = scmi_clock_attributes_get(ph, clkid, clk, version);
+		ret = scmi_clock_attributes_get(ph, clkid, cinfo, version);
 		if (!ret)
 			scmi_clock_describe_rates_get(ph, clkid, clk);
 	}
-- 
2.43.0



From cristian.marussi at arm.com  Mon Feb 12 04:32:29 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:29 +0000
Subject: [PATCH 07/11] firmware: arm_scmi: Implement Sensor .is_notify_supported callback
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-8-cristian.marussi@arm.com>

Add a preliminary check to verify if Sensor-related notify enable commands
are supported at all by the running platform, and then provide the callback
needed to allow the core SCMI notification subsytem to fine-grain check if
a specific resource domain supports notifications.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/sensors.c | 37 ++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c
index 311149965370..7fc5535ca34c 100644
--- a/drivers/firmware/arm_scmi/sensors.c
+++ b/drivers/firmware/arm_scmi/sensors.c
@@ -215,6 +215,8 @@ struct scmi_sensor_update_notify_payld {
 
 struct sensors_info {
 	u32 version;
+	bool notify_trip_point_cmd;
+	bool notify_continuos_update_cmd;
 	int num_sensors;
 	int max_requests;
 	u64 reg_addr;
@@ -246,6 +248,18 @@ static int scmi_sensor_attributes_get(const struct scmi_protocol_handle *ph,
 	}
 
 	ph->xops->xfer_put(ph, t);
+
+	if (!ret) {
+		if (!ph->hops->protocol_msg_check(ph,
+						  SENSOR_TRIP_POINT_NOTIFY, NULL))
+			si->notify_trip_point_cmd = true;
+
+		if (!ph->hops->protocol_msg_check(ph,
+						  SENSOR_CONTINUOUS_UPDATE_NOTIFY,
+						  NULL))
+			si->notify_continuos_update_cmd = true;
+	}
+
 	return ret;
 }
 
@@ -594,7 +608,8 @@ iter_sens_descr_process_response(const struct scmi_protocol_handle *ph,
 	 * Such bitfields are assumed to be zeroed on non
 	 * relevant fw versions...assuming fw not buggy !
 	 */
-	s->update = SUPPORTS_UPDATE_NOTIFY(attrl);
+	if (si->notify_continuos_update_cmd)
+		s->update = SUPPORTS_UPDATE_NOTIFY(attrl);
 	s->timestamped = SUPPORTS_TIMESTAMP(attrl);
 	if (s->timestamped)
 		s->tstamp_scale = S32_EXT(SENSOR_TSTAMP_EXP(attrl));
@@ -988,6 +1003,25 @@ static const struct scmi_sensor_proto_ops sensor_proto_ops = {
 	.config_set = scmi_sensor_config_set,
 };
 
+static bool scmi_sensor_notify_supported(const struct scmi_protocol_handle *ph,
+					 u8 evt_id, u32 src_id)
+{
+	bool supported = false;
+	const struct scmi_sensor_info *s;
+	struct sensors_info *sinfo = ph->get_priv(ph);
+
+	s = scmi_sensor_info_get(ph, src_id);
+	if (!s)
+		return false;
+
+	if (evt_id == SCMI_EVENT_SENSOR_TRIP_POINT_EVENT)
+		supported = sinfo->notify_trip_point_cmd;
+	else if (evt_id == SCMI_EVENT_SENSOR_UPDATE)
+		supported = s->update;
+
+	return supported;
+}
+
 static int scmi_sensor_set_notify_enabled(const struct scmi_protocol_handle *ph,
 					  u8 evt_id, u32 src_id, bool enable)
 {
@@ -1099,6 +1133,7 @@ static const struct scmi_event sensor_events[] = {
 };
 
 static const struct scmi_event_ops sensor_event_ops = {
+	.is_notify_supported = scmi_sensor_notify_supported,
 	.get_num_sources = scmi_sensor_get_num_sources,
 	.set_notify_enabled = scmi_sensor_set_notify_enabled,
 	.fill_custom_report = scmi_sensor_fill_custom_report,
-- 
2.43.0



From cristian.marussi at arm.com  Mon Feb 12 04:32:30 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:30 +0000
Subject: [PATCH 08/11] firmware: arm_scmi: Implement Reset .is_notify_supported callback
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-9-cristian.marussi@arm.com>

Add a preliminary check to verify if Reset-related notify enable commands
are supported at all by the running platform, and then provide the callback
needed to allow the core SCMI notification subsytem to fine-grain check if
a specific resource domain supports notifications.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/reset.c | 37 ++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c
index 19970d9f9e36..1b318316535e 100644
--- a/drivers/firmware/arm_scmi/reset.c
+++ b/drivers/firmware/arm_scmi/reset.c
@@ -67,6 +67,7 @@ struct reset_dom_info {
 struct scmi_reset_info {
 	u32 version;
 	int num_domains;
+	bool notify_reset_cmd;
 	struct reset_dom_info *dom_info;
 };
 
@@ -89,18 +90,24 @@ static int scmi_reset_attributes_get(const struct scmi_protocol_handle *ph,
 	}
 
 	ph->xops->xfer_put(ph, t);
+
+	if (!ret)
+		if (!ph->hops->protocol_msg_check(ph, RESET_NOTIFY, NULL))
+			pi->notify_reset_cmd = true;
+
 	return ret;
 }
 
 static int
 scmi_reset_domain_attributes_get(const struct scmi_protocol_handle *ph,
-				 u32 domain, struct reset_dom_info *dom_info,
-				 u32 version)
+				 struct scmi_reset_info *pinfo,
+				 u32 domain, u32 version)
 {
 	int ret;
 	u32 attributes;
 	struct scmi_xfer *t;
 	struct scmi_msg_resp_reset_domain_attributes *attr;
+	struct reset_dom_info *dom_info = pinfo->dom_info + domain;
 
 	ret = ph->xops->xfer_get_init(ph, RESET_DOMAIN_ATTRIBUTES,
 				      sizeof(domain), sizeof(*attr), &t);
@@ -115,7 +122,9 @@ scmi_reset_domain_attributes_get(const struct scmi_protocol_handle *ph,
 		attributes = le32_to_cpu(attr->attributes);
 
 		dom_info->async_reset = SUPPORTS_ASYNC_RESET(attributes);
-		dom_info->reset_notify = SUPPORTS_NOTIFY_RESET(attributes);
+		if (pinfo->notify_reset_cmd)
+			dom_info->reset_notify =
+				SUPPORTS_NOTIFY_RESET(attributes);
 		dom_info->latency_us = le32_to_cpu(attr->latency);
 		if (dom_info->latency_us == U32_MAX)
 			dom_info->latency_us = 0;
@@ -226,6 +235,20 @@ static const struct scmi_reset_proto_ops reset_proto_ops = {
 	.deassert = scmi_reset_domain_deassert,
 };
 
+static bool scmi_reset_notify_supported(const struct scmi_protocol_handle *ph,
+					u8 evt_id, u32 src_id)
+{
+	struct reset_dom_info *dom;
+	struct scmi_reset_info *pi = ph->get_priv(ph);
+
+	if (evt_id != SCMI_EVENT_RESET_ISSUED || src_id >= pi->num_domains)
+		return false;
+
+	dom = pi->dom_info + src_id;
+
+	return dom->reset_notify;
+}
+
 static int scmi_reset_notify(const struct scmi_protocol_handle *ph,
 			     u32 domain_id, bool enable)
 {
@@ -301,6 +324,7 @@ static const struct scmi_event reset_events[] = {
 };
 
 static const struct scmi_event_ops reset_event_ops = {
+	.is_notify_supported = scmi_reset_notify_supported,
 	.get_num_sources = scmi_reset_get_num_sources,
 	.set_notify_enabled = scmi_reset_set_notify_enabled,
 	.fill_custom_report = scmi_reset_fill_custom_report,
@@ -339,11 +363,8 @@ static int scmi_reset_protocol_init(const struct scmi_protocol_handle *ph)
 	if (!pinfo->dom_info)
 		return -ENOMEM;
 
-	for (domain = 0; domain < pinfo->num_domains; domain++) {
-		struct reset_dom_info *dom = pinfo->dom_info + domain;
-
-		scmi_reset_domain_attributes_get(ph, domain, dom, version);
-	}
+	for (domain = 0; domain < pinfo->num_domains; domain++)
+		scmi_reset_domain_attributes_get(ph, pinfo, domain, version);
 
 	pinfo->version = version;
 	return ph->set_priv(ph, pinfo, version);
-- 
2.43.0



From cristian.marussi at arm.com  Mon Feb 12 04:32:31 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:31 +0000
Subject: [PATCH 09/11] firmware: arm_scmi: Implement Powercap .is_notify_supported callback
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-10-cristian.marussi@arm.com>

Add a preliminary check to verify if Powercap-related notify enable
commands are supported at all by the running platform, and then provide the
callback needed to allow the core SCMI notification subsytem to fine-grain
check if a specific resource domain supports notifications.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/powercap.c | 45 +++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/arm_scmi/powercap.c b/drivers/firmware/arm_scmi/powercap.c
index a4c6cd4716fe..aae91f47303e 100644
--- a/drivers/firmware/arm_scmi/powercap.c
+++ b/drivers/firmware/arm_scmi/powercap.c
@@ -124,6 +124,8 @@ struct scmi_powercap_state {
 struct powercap_info {
 	u32 version;
 	int num_domains;
+	bool notify_cap_cmd;
+	bool notify_measurements_cmd;
 	struct scmi_powercap_state *states;
 	struct scmi_powercap_info *powercaps;
 };
@@ -157,6 +159,18 @@ scmi_powercap_attributes_get(const struct scmi_protocol_handle *ph,
 	}
 
 	ph->xops->xfer_put(ph, t);
+
+	if (!ret) {
+		if (!ph->hops->protocol_msg_check(ph,
+						  POWERCAP_CAP_NOTIFY, NULL))
+			pi->notify_cap_cmd = true;
+
+		if (!ph->hops->protocol_msg_check(ph,
+						  POWERCAP_MEASUREMENTS_NOTIFY,
+						  NULL))
+			pi->notify_measurements_cmd = true;
+	}
+
 	return ret;
 }
 
@@ -200,10 +214,12 @@ scmi_powercap_domain_attributes_get(const struct scmi_protocol_handle *ph,
 		flags = le32_to_cpu(resp->attributes);
 
 		dom_info->id = domain;
-		dom_info->notify_powercap_cap_change =
-			SUPPORTS_POWERCAP_CAP_CHANGE_NOTIFY(flags);
-		dom_info->notify_powercap_measurement_change =
-			SUPPORTS_POWERCAP_MEASUREMENTS_CHANGE_NOTIFY(flags);
+		if (pinfo->notify_cap_cmd)
+			dom_info->notify_powercap_cap_change =
+				SUPPORTS_POWERCAP_CAP_CHANGE_NOTIFY(flags);
+		if (pinfo->notify_measurements_cmd)
+			dom_info->notify_powercap_measurement_change =
+				SUPPORTS_POWERCAP_MEASUREMENTS_CHANGE_NOTIFY(flags);
 		dom_info->async_powercap_cap_set =
 			SUPPORTS_ASYNC_POWERCAP_CAP_SET(flags);
 		dom_info->powercap_cap_config =
@@ -788,6 +804,26 @@ static int scmi_powercap_notify(const struct scmi_protocol_handle *ph,
 	return ret;
 }
 
+static bool
+scmi_powercap_notify_supported(const struct scmi_protocol_handle *ph,
+			       u8 evt_id, u32 src_id)
+{
+	bool supported;
+	const struct scmi_powercap_info *dom_info;
+	struct powercap_info *pi = ph->get_priv(ph);
+
+	if (evt_id >= ARRAY_SIZE(evt_2_cmd) || src_id >= pi->num_domains)
+		return false;
+
+	dom_info = pi->powercaps + src_id;
+	if (evt_id == SCMI_EVENT_POWERCAP_CAP_CHANGED)
+		supported = dom_info->notify_powercap_cap_change;
+	else if (evt_id == SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED)
+		supported = dom_info->notify_powercap_measurement_change;
+
+	return supported;
+}
+
 static int
 scmi_powercap_set_notify_enabled(const struct scmi_protocol_handle *ph,
 				 u8 evt_id, u32 src_id, bool enable)
@@ -904,6 +940,7 @@ static const struct scmi_event powercap_events[] = {
 };
 
 static const struct scmi_event_ops powercap_event_ops = {
+	.is_notify_supported = scmi_powercap_notify_supported,
 	.get_num_sources = scmi_powercap_get_num_sources,
 	.set_notify_enabled = scmi_powercap_set_notify_enabled,
 	.fill_custom_report = scmi_powercap_fill_custom_report,
-- 
2.43.0



From cristian.marussi at arm.com  Mon Feb 12 04:32:32 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:32 +0000
Subject: [PATCH 10/11] firmware: arm_scmi: Use opps_by_lvl to store opps
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-11-cristian.marussi@arm.com>

Store all the discovered OPPs into the XArray opps_by_lvl even when
level_indexing mode is not used, since it comes handy to easily retrieve
OPPs by level.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/perf.c | 30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index 2627ace5b07f..e20d137a92f6 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -326,9 +326,9 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
 					    dom_info->id, NULL, dom_info->info.name,
 					    SCMI_MAX_STR_SIZE);
 
+	xa_init(&dom_info->opps_by_lvl);
 	if (dom_info->level_indexing_mode) {
 		xa_init(&dom_info->opps_by_idx);
-		xa_init(&dom_info->opps_by_lvl);
 		hash_init(dom_info->opps_by_freq);
 	}
 
@@ -371,13 +371,21 @@ static int iter_perf_levels_update_state(struct scmi_iterator_state *st,
 }
 
 static inline void
-process_response_opp(struct scmi_opp *opp, unsigned int loop_idx,
+process_response_opp(struct device *dev, struct perf_dom_info *dom,
+		     struct scmi_opp *opp, unsigned int loop_idx,
 		     const struct scmi_msg_resp_perf_describe_levels *r)
 {
+	int ret;
+
 	opp->perf = le32_to_cpu(r->opp[loop_idx].perf_val);
 	opp->power = le32_to_cpu(r->opp[loop_idx].power);
 	opp->trans_latency_us =
 		le16_to_cpu(r->opp[loop_idx].transition_latency_us);
+
+	ret = xa_insert(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL);
+	if (ret)
+		dev_warn(dev, "Failed to add opps_by_lvl at %d - ret:%d\n",
+			 opp->perf, ret);
 }
 
 static inline void
@@ -385,16 +393,21 @@ process_response_opp_v4(struct device *dev, struct perf_dom_info *dom,
 			struct scmi_opp *opp, unsigned int loop_idx,
 			const struct scmi_msg_resp_perf_describe_levels_v4 *r)
 {
+	int ret;
+
 	opp->perf = le32_to_cpu(r->opp[loop_idx].perf_val);
 	opp->power = le32_to_cpu(r->opp[loop_idx].power);
 	opp->trans_latency_us =
 		le16_to_cpu(r->opp[loop_idx].transition_latency_us);
 
+	ret = xa_insert(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL);
+	if (ret)
+		dev_warn(dev, "Failed to add opps_by_lvl at %d - ret:%d\n",
+			 opp->perf, ret);
+
 	/* Note that PERF v4 reports always five 32-bit words */
 	opp->indicative_freq = le32_to_cpu(r->opp[loop_idx].indicative_freq);
 	if (dom->level_indexing_mode) {
-		int ret;
-
 		opp->level_index = le32_to_cpu(r->opp[loop_idx].level_index);
 
 		ret = xa_insert(&dom->opps_by_idx, opp->level_index, opp,
@@ -404,12 +417,6 @@ process_response_opp_v4(struct device *dev, struct perf_dom_info *dom,
 				 "Failed to add opps_by_idx at %d - ret:%d\n",
 				 opp->level_index, ret);
 
-		ret = xa_insert(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL);
-		if (ret)
-			dev_warn(dev,
-				 "Failed to add opps_by_lvl at %d - ret:%d\n",
-				 opp->perf, ret);
-
 		hash_add(dom->opps_by_freq, &opp->hash, opp->indicative_freq);
 	}
 }
@@ -424,7 +431,8 @@ iter_perf_levels_process_response(const struct scmi_protocol_handle *ph,
 
 	opp = &p->perf_dom->opp[st->desc_index + st->loop_idx];
 	if (PROTOCOL_REV_MAJOR(p->version) <= 0x3)
-		process_response_opp(opp, st->loop_idx, response);
+		process_response_opp(ph->dev, p->perf_dom, opp, st->loop_idx,
+				     response);
 	else
 		process_response_opp_v4(ph->dev, p->perf_dom, opp, st->loop_idx,
 					response);
-- 
2.43.0



From cristian.marussi at arm.com  Mon Feb 12 04:32:33 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:32:33 +0000
Subject: [PATCH 11/11] firmware: arm_scmi: Report frequencies in Perf notifications
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <20240212123233.1230090-12-cristian.marussi@arm.com>

Extend the Perf notification report to include pre-calculated frequencies
corresponding to the reported limits/levels event; such frequencies are
properly computed based on the stored known OPPs information taking into
consideration if the current operating mode is level indexed or not.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/perf.c | 69 ++++++++++++++++++++++++++++++++
 include/linux/scmi_protocol.h    |  3 ++
 2 files changed, 72 insertions(+)

diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index e20d137a92f6..981e327e63e3 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -1055,18 +1055,47 @@ static int scmi_perf_set_notify_enabled(const struct scmi_protocol_handle *ph,
 	return ret;
 }
 
+static int
+scmi_perf_xlate_opp_to_freq(struct perf_dom_info *dom,
+			    unsigned int index, unsigned long *freq)
+{
+	struct scmi_opp *opp;
+
+	if (!dom || !freq)
+		return -EINVAL;
+
+	if (!dom->level_indexing_mode) {
+		opp = xa_load(&dom->opps_by_lvl, index);
+		if (!opp)
+			return -ENODEV;
+
+		*freq = opp->perf * dom->mult_factor;
+	} else {
+		opp = xa_load(&dom->opps_by_idx, index);
+		if (!opp)
+			return -ENODEV;
+
+		*freq = opp->indicative_freq * dom->mult_factor;
+	}
+
+	return 0;
+}
+
 static void *scmi_perf_fill_custom_report(const struct scmi_protocol_handle *ph,
 					  u8 evt_id, ktime_t timestamp,
 					  const void *payld, size_t payld_sz,
 					  void *report, u32 *src_id)
 {
+	int ret;
 	void *rep = NULL;
+	struct perf_dom_info *dom;
 
 	switch (evt_id) {
 	case SCMI_EVENT_PERFORMANCE_LIMITS_CHANGED:
 	{
 		const struct scmi_perf_limits_notify_payld *p = payld;
 		struct scmi_perf_limits_report *r = report;
+		unsigned long freq_min, freq_max;
 
 		if (sizeof(*p) != payld_sz)
 			break;
@@ -1076,14 +1105,36 @@ static void *scmi_perf_fill_custom_report(const struct scmi_protocol_handle *ph,
 		r->domain_id = le32_to_cpu(p->domain_id);
 		r->range_max = le32_to_cpu(p->range_max);
 		r->range_min = le32_to_cpu(p->range_min);
+		/* Check if the reported domain exist at all */
+		dom = scmi_perf_domain_lookup(ph, r->domain_id);
+		if (IS_ERR(dom))
+			break;
+		/*
+		 * Event will be reported from this point on...
+		 * ...even if, later, xlated frequencies were not retrieved.
+		 */
 		*src_id = r->domain_id;
 		rep = r;
+
+		ret = scmi_perf_xlate_opp_to_freq(dom, r->range_max, &freq_max);
+		if (ret)
+			break;
+
+		ret = scmi_perf_xlate_opp_to_freq(dom, r->range_min, &freq_min);
+		if (ret)
+			break;
+
+		/* Report translated freqs ONLY if both available */
+		r->range_max_freq = freq_max;
+		r->range_min_freq = freq_min;
+
 		break;
 	}
 	case SCMI_EVENT_PERFORMANCE_LEVEL_CHANGED:
 	{
 		const struct scmi_perf_level_notify_payld *p = payld;
 		struct scmi_perf_level_report *r = report;
+		unsigned long freq;
 
 		if (sizeof(*p) != payld_sz)
 			break;
@@ -1091,9 +1142,27 @@ static void *scmi_perf_fill_custom_report(const struct scmi_protocol_handle *ph,
 		r->timestamp = timestamp;
 		r->agent_id = le32_to_cpu(p->agent_id);
 		r->domain_id = le32_to_cpu(p->domain_id);
+		/* Report translated freqs ONLY if available */
 		r->performance_level = le32_to_cpu(p->performance_level);
+		/* Check if the reported domain exist at all */
+		dom = scmi_perf_domain_lookup(ph, r->domain_id);
+		if (IS_ERR(dom))
+			break;
+		/*
+		 * Event will be reported from this point on...
+		 * ...even if, later, xlated frequencies were not retrieved.
+		 */
 		*src_id = r->domain_id;
 		rep = r;
+
+		/* Report translated freqs ONLY if available */
+		ret = scmi_perf_xlate_opp_to_freq(dom, r->performance_level,
+						  &freq);
+		if (ret)
+			break;
+
+		r->performance_level_freq = freq;
+
 		break;
 	}
 	default:
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 0cc40af5519a..9b9351e07a11 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -956,6 +956,8 @@ struct scmi_perf_limits_report {
 	unsigned int	domain_id;
 	unsigned int	range_max;
 	unsigned int	range_min;
+	unsigned long	range_max_freq;
+	unsigned long	range_min_freq;
 };
 
 struct scmi_perf_level_report {
@@ -963,6 +965,7 @@ struct scmi_perf_level_report {
 	unsigned int	agent_id;
 	unsigned int	domain_id;
 	unsigned int	performance_level;
+	unsigned long	performance_level_freq;
 };
 
 struct scmi_sensor_trip_point_report {
-- 
2.43.0



From andre.draszik at linaro.org  Mon Feb 12 04:38:14 2024
From: andre.draszik at linaro.org (=?ISO-8859-1?Q?Andr=E9?= Draszik)
Date: Mon, 12 Feb 2024 12:38:14 +0000
Subject: [PATCH] arm64: dts: exynos: gs101: add stable i2c aliases for
 gs101-oriole
In-Reply-To: <b6ec1d0e-e35c-4917-871b-049efcb2ea22@linaro.org>
References: <20240130233700.2287442-1-andre.draszik@linaro.org>
	 <170737972037.52344.9107022607101399076.b4-ty@linaro.org>
	 <5972b6a4ae8669e2a9e872278b740b182217906b.camel@linaro.org>
	 <dce39e15-32a8-482c-8751-af4a133f82d2@linaro.org>
	 <c16c1f18a8c6f33a608618d4ccf7d8c8dbb6f88b.camel@linaro.org>
	 <67a6564a-00bb-461d-b7eb-ca169df6d251@linaro.org>
	 <0ad3082c50e21a74de41ca9908bd53b72e1f1a9c.camel@linaro.org>
	 <b6ec1d0e-e35c-4917-871b-049efcb2ea22@linaro.org>
Message-ID: <fbd335e81928c1c3cd63ee44514cf95a23dafb6f.camel@linaro.org>

On Mon, 2024-02-12 at 13:07 +0100, Krzysztof Kozlowski wrote:
> On 12/02/2024 12:52, Andr? Draszik wrote:
> > As I said above, we won't care if downstream changes again at that stage, so
> > no, I wouldn't plan on changing again.
> 
> Then I am lost. What stage are you thinking? What differs between now
> and let's say 1 month for the GS101 which was released more than three
> years ago?

The idea was to make the initial transition to using upstream easier,
hence we added the same aliases as downstream (at the time).
Given the transition is not happening right now, we might as well hold
off with the aliases and add them later, with whatever downstream will
be using at that time.

If in the future somebody downstream decides 'I want this' (changed again),
why should upstream care at that stage?

Again, this patch was just trying to make initial transition easier, do you
have a better recommendation?

> BTW, the aliases I see in downstream DTS (gs101-usi.dtsi) - since
> beginning up to Android 14 are:
> 
> ??????????????? hsi2c8 = &hsi2c_8;
> ??????????????? hsi2c9 = &hsi2c_9;
> ??????????????? hsi2c10 = &hsi2c_10;
> ??????????????? hsi2c11 = &hsi2c_11;
> ??????????????? hsi2c12 = &hsi2c_12;
> 
> They were set like this in 2020 and never changed afterwards.

Those were incorrect and didn't actually work as intended, here's a
better place to look:

https://android.googlesource.com/kernel/google-modules/raviole-device/+log/refs/heads/android-gs-raviole-mainline
and
https://android.googlesource.com/kernel/google-modules/raviole-device/+/9864593c894da90cd8b631ab57f15c25f4e11465%5E%21/


Cheers,
Andre'



From angelogioacchino.delregno at collabora.com  Mon Feb 12 04:38:28 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 12 Feb 2024 13:38:28 +0100
Subject: [PATCH REBASED 1/2] arm64: dts: mediatek: mt7986: reorder properties
In-Reply-To: <20240212121620.15035-1-zajec5@gmail.com>
References: <20240212121620.15035-1-zajec5@gmail.com>
Message-ID: <170774149167.16640.16616243802900743288.b4-ty@collabora.com>

On Mon, 12 Feb 2024 13:16:19 +0100, Rafa? Mi?ecki wrote:
> Use order described as preferred in DTS Coding Style. Mostly just move
> "compatible", "reg" and "ranges" properties. In two nodes also move
> vendor-prefixed props down.
> 
> 

Applied to v6.8-next/dts64, thanks!

[1/2] arm64: dts: mediatek: mt7986: reorder properties
      https://git.kernel.org/mediatek/c/7eb133c9
[2/2] arm64: dts: mediatek: mt7986: reorder nodes
      https://git.kernel.org/mediatek/c/3f79e8f3

Cheers,
Angelo



From angelogioacchino.delregno at collabora.com  Mon Feb 12 04:42:50 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 12 Feb 2024 13:42:50 +0100
Subject: [PATCH] arm64: dts: mediatek: mt7622: add missing "device_type" to memory nodes
In-Reply-To: <20240122132357.31264-1-zajec5@gmail.com>
References: <20240122132357.31264-1-zajec5@gmail.com>
Message-ID: <170774176471.19382.17605326667599843858.b4-ty@collabora.com>

On Mon, 22 Jan 2024 14:23:57 +0100, Rafa? Mi?ecki wrote:
> This fixes:
> arch/arm64/boot/dts/mediatek/mt7622-rfb1.dtb: /: memory at 40000000: 'device_type' is a required property
>         from schema $id: http://devicetree.org/schemas/memory.yaml#
> arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dtb: /: memory at 40000000: 'device_type' is a required property
>         from schema $id: http://devicetree.org/schemas/memory.yaml#
> 
> 
> [...]

Applied to v6.8-next/dts64, thanks!

[1/1] arm64: dts: mediatek: mt7622: add missing "device_type" to memory nodes
      https://git.kernel.org/mediatek/c/99d100e0

Cheers,
Angelo



From david at redhat.com  Mon Feb 12 04:44:28 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 13:44:28 +0100
Subject: [PATCH v5 18/25] arm64/mm: Split __flush_tlb_range() to elide
 trailing DSB
In-Reply-To: <20240202080756.1453939-19-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-19-ryan.roberts@arm.com>
Message-ID: <9e1d793a-02c9-4dbb-a6d4-1e1c0c42638c@redhat.com>

On 02.02.24 09:07, Ryan Roberts wrote:
> Split __flush_tlb_range() into __flush_tlb_range_nosync() +
> __flush_tlb_range(), in the same way as the existing flush_tlb_page()
> arrangement. This allows calling __flush_tlb_range_nosync() to elide the
> trailing DSB. Forthcoming "contpte" code will take advantage of this
> when clearing the young bit from a contiguous range of ptes.
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>   arch/arm64/include/asm/tlbflush.h | 13 +++++++++++--
>   1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
> index 79e932a1bdf8..50a765917327 100644
> --- a/arch/arm64/include/asm/tlbflush.h
> +++ b/arch/arm64/include/asm/tlbflush.h
> @@ -422,7 +422,7 @@ do {									\
>   #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \
>   	__flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false, kvm_lpa2_is_enabled());
>   
> -static inline void __flush_tlb_range(struct vm_area_struct *vma,
> +static inline void __flush_tlb_range_nosync(struct vm_area_struct *vma,
>   				     unsigned long start, unsigned long end,
>   				     unsigned long stride, bool last_level,
>   				     int tlb_level)
> @@ -456,10 +456,19 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
>   		__flush_tlb_range_op(vae1is, start, pages, stride, asid,
>   				     tlb_level, true, lpa2_is_enabled());
>   
> -	dsb(ish);
>   	mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
>   }
>   
> +static inline void __flush_tlb_range(struct vm_area_struct *vma,
> +				     unsigned long start, unsigned long end,
> +				     unsigned long stride, bool last_level,
> +				     int tlb_level)
> +{
> +	__flush_tlb_range_nosync(vma, start, end, stride,
> +				 last_level, tlb_level);
> +	dsb(ish);
> +}
> +
>   static inline void flush_tlb_range(struct vm_area_struct *vma,
>   				   unsigned long start, unsigned long end)
>   {

You're now calling dsb() after 
mmu_notifier_arch_invalidate_secondary_tlbs().


In flush_tlb_mm(), we have the order

	dsb(ish);	
	mmu_notifier_arch_invalidate_secondary_tlbs()

In flush_tlb_page(), we have the effective order:

	mmu_notifier_arch_invalidate_secondary_tlbs()
	dsb(ish);

In flush_tlb_range(), we used to have the order:

	dsb(ish);
	mmu_notifier_arch_invalidate_secondary_tlbs();


So I *suspect* having that DSB before 
mmu_notifier_arch_invalidate_secondary_tlbs() is fine. Hopefully, 
nothing in there relies on that placement.

Maybe wort spelling out in the patch description

Reviewed-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From cristian.marussi at arm.com  Mon Feb 12 04:44:42 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 12 Feb 2024 12:44:42 +0000
Subject: [PATCH V2 1/4] firmware: arm_scmi: Add perf_notify_support
 interface
In-Reply-To: <20240131112854.24euh6c6xgljsj6c@bogus>
References: <20240117104116.2055349-1-quic_sibis@quicinc.com>
 <20240117104116.2055349-2-quic_sibis@quicinc.com>
 <ZbfJN1c9viiLhO1L@pluto>
 <ZbfhdqBBpjyf3IRI@pluto>
 <20240131112854.24euh6c6xgljsj6c@bogus>
Message-ID: <ZcoSuv7qwexbXy-9@pluto>

On Wed, Jan 31, 2024 at 11:28:54AM +0000, Sudeep Holla wrote:
> On Mon, Jan 29, 2024 at 05:33:42PM +0000, Cristian Marussi wrote:

Hi Sibi,

> > On Mon, Jan 29, 2024 at 03:50:20PM +0000, Cristian Marussi wrote:
> > > On Wed, Jan 17, 2024 at 04:11:13PM +0530, Sibi Sankar wrote:
> > > > Add a new perf_notify_support interface to the existing perf_ops to export
> > > > info regarding limit/level change notification support.
> > > > 
> > > 
> > > Hi Sibi,
> > > 
> > > as I mentioned previously, in order not to add a needless stream of SCMI
> > > Perf accessors I posted this:
> > > 
> > > https://lore.kernel.org/linux-arm-kernel/20240129151002.1215333-1-cristian.marussi at arm.com/T/#u
> > > 
> > > to expose all the Perf domains infos via the usual info_get(), similarly
> > > to how other SCMI protocols do already.
> > > 
> > > I think that reworking this series on that, you can certainly drop this patch and just
> > > check the _notify booleans on the retrieved domain info.
> > 
> > Sorry, but hold on with this change, I will probably post an updated version
> > my patch above.
> > 
> 
> As discussed in private, I would prefer to avoid exposing all the internals
> to the users of SCMI perf. At the same time may we can do better if we can
> check the availability of notification as part of notification enablement
> from the SCMI driver, I need to think the details yet.
> 

as previously mentioned, after speaking with Sudeep, I posted a new
series at [1], that aims to solve your problem with registering
notifications and looking up reported Perf frequencies in a new way.

Using the changes at [1] you should be able to:

- register your notifier without caring to check if the notification
  is supported, since the SCMI core will take care of checking that and
  report an error if not supported, without sending any unneeded
  attempted notification enable message  (so you can drop 1/4 in this
  series)

- retrieve the pre-calculated OPPs frequencies from the new extended
  Perf notifications reports no matter if the system if operating in
  level_indexing_mode or not. (so you can drop 2/4 in this series)

Thanks,
Cristian

[1]: https://lore.kernel.org/linux-arm-kernel/20240212123233.1230090-1-cristian.marussi at arm.com/T/#ma68cefd753e34ba3e1f2d4392e978026a87e1bf8



From m.szyprowski at samsung.com  Mon Feb 12 04:48:35 2024
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Mon, 12 Feb 2024 13:48:35 +0100
Subject: [PATCH v4 06/10] arm64: cpufeature: Detect HCR_EL2.NV1 being
 RES0
In-Reply-To: <20240122181344.258974-7-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
	<20240122181344.258974-7-maz@kernel.org>
	<CGME20240212124837eucas1p231da54bb0ff8d46d38c6c7e627e50172@eucas1p2.samsung.com>
Message-ID: <e3cc70fb-16d9-4e4e-aa35-f0eb2baaf166@samsung.com>

Dead All,

On 22.01.2024 19:13, Marc Zyngier wrote:
> A variant of FEAT_E2H0 not being implemented exists in the form of
> HCR_EL2.E2H being RES1 *and* HCR_EL2.NV1 being RES0 (indicating that
> only VHE is supported on the host and nested guests).
>
> Add the necessary infrastructure for this new CPU capability.
>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---

This patch landed recently in linux-next as commit da9af5071b25 ("arm64: 
cpufeature: Detect HCR_EL2.NV1 being RES0"). I found that it causes a 
following regression in the CPU hot-plug operation:

# for i in /sys/devices/system/cpu/cpu[1-9]; do echo 1 >$i/online; done
------------[ cut here ]------------
kernel BUG at arch/arm64/kernel/cpufeature.c:1468!
Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP
Modules linked in: dw_hdmi_cec dw_hdmi_i2s_audio crct10dif_ce 
snd_soc_simple_card rockchip_saradc industrialio_triggered_buffer 
hantro_vpu kfifo_buf snd_soc_simple_card_utils rockchip_thermal 
phy_rockchip_naneng_combphy display_connector gpio_ir_recv v4l2_vp9 
v4l2_h264 v4l2_mem2mem dwmac_rk videobuf2_dma_contig stmmac_platform 
videobuf2_memops videobuf2_v4l2 stmmac rockchipdrm videodev 
snd_soc_rockchip_i2s_tdm snd_soc_rk817 pcs_xpcs panfrost rtc_rk808 
rk805_pwrkey analogix_dp rk817_charger spi_rockchip_sfc dw_mipi_dsi 
videobuf2_common dw_hdmi drm_shmem_helper mc gpu_sched 
drm_display_helper ahci_dwc ip_tables x_tables ipv6
CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.8.0-rc1+ #14563
Hardware name: Hardkernel ODROID-M1 (DT)
pstate: 800001c9 (Nzcv dAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : __read_sysreg_by_encoding+0x38c/0x390
lr : read_scoped_sysreg+0x4c/0x70
...
Call trace:
 ?__read_sysreg_by_encoding+0x38c/0x390
 ?read_scoped_sysreg+0x4c/0x70
 ?has_nv1+0x18/0x48
 ?verify_local_cpu_caps+0x54/0x124
 ?check_local_cpu_capabilities+0x28/0x208
 ?secondary_start_kernel+0xb0/0x154
 ?__secondary_switched+0xb8/0xbc
Code: d53802f3 17ffff3b d5380253 17ffff39 (d4210000)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Attempted to kill the idle task!
SMP: stopping secondary CPUs
Kernel Offset: disabled
CPU features: 0x1,80000000,80050295,2100721b
Memory Limit: none
---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---

It looks that some additional checks are needed for the CPU hot-plug case.

>   arch/arm64/kernel/cpufeature.c | 12 ++++++++++++
>   arch/arm64/tools/cpucaps       |  1 +
>   2 files changed, 13 insertions(+)
>
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index ad3753fbdcb1..91249d20883b 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1794,6 +1794,11 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
>   	return !meltdown_safe;
>   }
>   
> +static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
> +{
> +	return !has_cpuid_feature(entry, scope);
> +}
> +
>   #if defined(ID_AA64MMFR0_EL1_TGRAN_LPA2) && defined(ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2)
>   static bool has_lpa2_at_stage1(u64 mmfr0)
>   {
> @@ -2794,6 +2799,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>   		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
>   		.matches = has_lpa2,
>   	},
> +	{
> +		.desc = "NV1",
> +		.capability = ARM64_HAS_HCR_NV1,
> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> +		.matches = has_nv1,
> +		ARM64_CPUID_FIELDS_NEG(ID_AA64MMFR4_EL1, E2H0, NI_NV1)
> +	},
>   	{},
>   };
>   
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index b912b1409fc0..65090dd34641 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -35,6 +35,7 @@ HAS_GENERIC_AUTH_IMP_DEF
>   HAS_GIC_CPUIF_SYSREGS
>   HAS_GIC_PRIO_MASKING
>   HAS_GIC_PRIO_RELAXED_SYNC
> +HAS_HCR_NV1
>   HAS_HCX
>   HAS_LDAPR
>   HAS_LPA2

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From francesco at dolcini.it  Mon Feb 12 04:54:02 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Mon, 12 Feb 2024 13:54:02 +0100
Subject: [PATCH v1] arm64: dts: ti: k3-am62-main: disable usb lpm
In-Reply-To: <2629cd30-23aa-4f03-8452-ae13297fd6b6@kernel.org>
References: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
 <2629cd30-23aa-4f03-8452-ae13297fd6b6@kernel.org>
Message-ID: <20240212125402.GA5043@francesco-nb>

Hello Roger,

On Mon, Feb 12, 2024 at 02:13:56PM +0200, Roger Quadros wrote:
> On 09/02/2024 15:02, Andrejs Cainikovs wrote:
> > diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> > index 464b7565d085..c49fbce5cb70 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> > @@ -663,6 +665,8 @@ usb1: usb at 31100000 {
> >  			interrupt-names = "host", "peripheral";
> >  			maximum-speed = "high-speed";
> >  			dr_mode = "otg";
> > +			snps,usb2-gadget-lpm-disable;
> > +			snps,usb2-lpm-disable;
> 
> Instead of this could you please check if this series fixes the issue for you?
> https://lore.kernel.org/all/20240205141221.56076-1-rogerq at kernel.org/

Isn't this change correct despite whatever the test results on that
change are going to be? The manual is pretty adamant on LPM not being
supported by the AM62 SoC.

Francesco



From jgg at nvidia.com  Mon Feb 12 04:56:54 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Mon, 12 Feb 2024 08:56:54 -0400
Subject: [PATCH v7 0/4] kvm: arm64: allow the VM to select DEVICE_* and
 NORMAL_NC for IO memory
In-Reply-To: <aa6c1708-d6ac-46f7-b7ab-e97a273a90c2@redhat.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
 <aa6c1708-d6ac-46f7-b7ab-e97a273a90c2@redhat.com>
Message-ID: <20240212125654.GV10476@nvidia.com>

On Mon, Feb 12, 2024 at 11:26:12AM +0100, David Hildenbrand wrote:

> I still have to digest some of the stuff I learned about this issue, please
> bear with me :)
> 
> (1) PCI BARs might contain mixtures of RAM and MMIO, the exact
> locations/semantics within a BAR are only really known to the actual device
> driver.

Nit: Not RAM and MMIO but different kinds of MMIO that have different
access patterns. The conclusion is correct.

> We must not unconditionally map PFNs "the wrong way", because it can have
> undesired side effects. Side effects might include read-speculation, that
> can be very problematic with MMIO regions.

It is worse that some hand wavey "side effect". If you map memory with
NORMAL_NC (ie for write combining) then writel() doesn't work
correctly at all.

The memory must be mapped according to which kernel APIs the actual
driver in the VM will use. writel() vs __iowrite64_copy().

> We can trigger both cases right now inside VMs, where we want the device
> driver to actually make the decision.

Yes
 
> (2) For a VM, that device driver lives inside the VM, for DPDK and friends,
> it lives in user space. They have this information.

Yes
 
> We only focus here on optimizing (fixing?) the mapping for VMs, DPDK is out
> of the picture.

DPDK will be solved through some VFIO ioctl, we know how to do it,
just nobody has cared enough to do it.

> So we want to allow the VM to achieve a WC/NC mapping by using a
> relaxed (NC) mapping in stage-1. Whatever is set in stage-2 wins.

Yes
 
> 
> (3) vfio knows whether using WC (and NC?) could be problematic, and must
> forbid it, if that is the case. There are cases where we could otherwise
> cause harm (bring down the host?). We must keep mapping the memory as
> DEVICE_nGnRE when in doubt.

Yes, there is an unspecific fear that on ARM platforms using NORMAL_NC
in the wrong way can trigger a catastrophic error and kill the
host. There is no way to know if the platform has this bug, so the
agreement was to be conservative and only allow it for vfio-pci, based
on some specific details of how PCI has to be implemented and ARM
guidance on PCI integration..

> Now, what the new mmap() flag does is tell the world "using the wrong
> mapping type cannot bring down the host", and KVM uses that to use a
> different mapping type (NC) in stage-1 as setup by vfio in the user space
> page tables.

The inverse meaning, we assume VMAs with the flag can bring down the
host, but yes.

> I was trying to find ways of avoiding a mmap() flag and was hoping that we
> could just use a PTE bit that does not have semantics in VM_PFNMAP mappings.
> Unfortunately, arm64 does not support uffd-wp, which I had in mind, so it's
> not that easy.

Seems like a waste of a valuable PTE bit to me.

> Further, I was wondering if there would be a way to let DPDK similarly
> benefit, because it looks like we are happily ignoring that (I was told they
> apply some hacks to work around that).

dpdk doesn't need the VMA bit, we know how to solve it with vfio
ioctls, it is very straightforward. dpdk just does a ioctl & mmap and
VFIO will create a vma with pgprote_writecombine(). Completely
trivial, the only nasty bit is fitting this into the VFIO uAPI.

> (a) User space tells VFIO which parts of a BAR it would like to have mapped
> differently. For QEMU, this would mean, requesting a NC mapping for the
> whole BAR. For DPDK, it could mean requesting different types for parts of a
> BAR.

We don't want to have have the memory mapped as NC in qemu. As I said
above if it is mapped NC then writel() doesn't work. We can't have
conflicting mappings that go toward NC when the right answer is
DEVICE. 

writel() on NC will malfunction.

__iowrite64_copy() on DEVICE will be functionally correct but slower.

The S2 mapping that KVM creates is special because it doesn't actually
map it once the VM kernel gets started. The VM kernel always supplies
a S1 table that sets the correct type.

So if qemu has DEVICE, the S2 has NC and the VM's S1 has DEVICE then
the mapping is realiably made to be DEVICE. The hidden S2 doesn't
cause a problem.

> That would mean, that we would map NC already in QEMU. I wonder if that
> could be a problem with read speculation, even if QEMU never really accesses
> that mmap'ed region.

Also correct.

Further, qemu may need to do emulation for MMIO in various cases and
the qemu logic for this requires a DEVICE mapping or the emulation
will malfunction.

Using NC in qemu is off the table.

Jason


From ryan.roberts at arm.com  Mon Feb 12 04:59:57 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 12:59:57 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
Message-ID: <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>

On 12/02/2024 12:00, Mark Rutland wrote:
> Hi Ryan,
> 
> Overall this looks pretty good; I have a bunch of minor comments below, and a
> bigger question on the way ptep_get_lockless() works.

OK great - thanks for the review. Let's see if I can answer them all...

> 
> On Fri, Feb 02, 2024 at 08:07:50AM +0000, Ryan Roberts wrote:
>> With the ptep API sufficiently refactored, we can now introduce a new
>> "contpte" API layer, which transparently manages the PTE_CONT bit for
>> user mappings.
>>
>> In this initial implementation, only suitable batches of PTEs, set via
>> set_ptes(), are mapped with the PTE_CONT bit. Any subsequent
>> modification of individual PTEs will cause an "unfold" operation to
>> repaint the contpte block as individual PTEs before performing the
>> requested operation. While, a modification of a single PTE could cause
>> the block of PTEs to which it belongs to become eligible for "folding"
>> into a contpte entry, "folding" is not performed in this initial
>> implementation due to the costs of checking the requirements are met.
>> Due to this, contpte mappings will degrade back to normal pte mappings
>> over time if/when protections are changed. This will be solved in a
>> future patch.
>>
>> Since a contpte block only has a single access and dirty bit, the
>> semantic here changes slightly; when getting a pte (e.g. ptep_get())
>> that is part of a contpte mapping, the access and dirty information are
>> pulled from the block (so all ptes in the block return the same
>> access/dirty info). When changing the access/dirty info on a pte (e.g.
>> ptep_set_access_flags()) that is part of a contpte mapping, this change
>> will affect the whole contpte block. This is works fine in practice
>> since we guarantee that only a single folio is mapped by a contpte
>> block, and the core-mm tracks access/dirty information per folio.
>>
>> In order for the public functions, which used to be pure inline, to
>> continue to be callable by modules, export all the contpte_* symbols
>> that are now called by those public inline functions.
>>
>> The feature is enabled/disabled with the ARM64_CONTPTE Kconfig parameter
>> at build time. It defaults to enabled as long as its dependency,
>> TRANSPARENT_HUGEPAGE is also enabled. The core-mm depends upon
>> TRANSPARENT_HUGEPAGE to be able to allocate large folios, so if its not
>> enabled, then there is no chance of meeting the physical contiguity
>> requirement for contpte mappings.
>>
>> Tested-by: John Hubbard <jhubbard at nvidia.com>
>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>> ---
>>  arch/arm64/Kconfig               |   9 +
>>  arch/arm64/include/asm/pgtable.h | 161 ++++++++++++++++++
>>  arch/arm64/mm/Makefile           |   1 +
>>  arch/arm64/mm/contpte.c          | 283 +++++++++++++++++++++++++++++++
>>  4 files changed, 454 insertions(+)
>>  create mode 100644 arch/arm64/mm/contpte.c
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index d86d7f4758b5..1442e8ed95b6 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -2230,6 +2230,15 @@ config UNWIND_PATCH_PAC_INTO_SCS
>>  	select UNWIND_TABLES
>>  	select DYNAMIC_SCS
>>  
>> +config ARM64_CONTPTE
>> +	bool "Contiguous PTE mappings for user memory" if EXPERT
>> +	depends on TRANSPARENT_HUGEPAGE
>> +	default y
>> +	help
>> +	  When enabled, user mappings are configured using the PTE contiguous
>> +	  bit, for any mappings that meet the size and alignment requirements.
>> +	  This reduces TLB pressure and improves performance.
>> +
>>  endmenu # "Kernel Features"
>>  
>>  menu "Boot options"
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index 7dc6b68ee516..34892a95403d 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -133,6 +133,10 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>>   */
>>  #define pte_valid_not_user(pte) \
>>  	((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN))
>> +/*
>> + * Returns true if the pte is valid and has the contiguous bit set.
>> + */
>> +#define pte_valid_cont(pte)	(pte_valid(pte) && pte_cont(pte))
>>  /*
>>   * Could the pte be present in the TLB? We must check mm_tlb_flush_pending
>>   * so that we don't erroneously return false for pages that have been
>> @@ -1135,6 +1139,161 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
>>  #define vmemmap_update_pte vmemmap_update_pte
>>  #endif
>>  
>> +#ifdef CONFIG_ARM64_CONTPTE
>> +
>> +/*
>> + * The contpte APIs are used to transparently manage the contiguous bit in ptes
>> + * where it is possible and makes sense to do so. The PTE_CONT bit is considered
>> + * a private implementation detail of the public ptep API (see below).
>> + */
>> +extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>> +				pte_t *ptep, pte_t pte);
>> +extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
>> +extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
>> +extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
>> +				pte_t *ptep, pte_t pte, unsigned int nr);
>> +extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>> +				unsigned long addr, pte_t *ptep);
>> +extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>> +				unsigned long addr, pte_t *ptep);
>> +extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>> +				unsigned long addr, pte_t *ptep,
>> +				pte_t entry, int dirty);
>> +
>> +static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>> +					pte_t *ptep, pte_t pte)
>> +{
>> +	if (unlikely(pte_valid_cont(pte)))
>> +		__contpte_try_unfold(mm, addr, ptep, pte);
>> +}
>> +
>> +/*
>> + * The below functions constitute the public API that arm64 presents to the
>> + * core-mm to manipulate PTE entries within their page tables (or at least this
>> + * is the subset of the API that arm64 needs to implement). These public
>> + * versions will automatically and transparently apply the contiguous bit where
>> + * it makes sense to do so. Therefore any users that are contig-aware (e.g.
>> + * hugetlb, kernel mapper) should NOT use these APIs, but instead use the
>> + * private versions, which are prefixed with double underscore. All of these
>> + * APIs except for ptep_get_lockless() are expected to be called with the PTL
>> + * held.
>> + */
>> +
>> +#define ptep_get ptep_get
>> +static inline pte_t ptep_get(pte_t *ptep)
>> +{
>> +	pte_t pte = __ptep_get(ptep);
>> +
>> +	if (likely(!pte_valid_cont(pte)))
>> +		return pte;
>> +
>> +	return contpte_ptep_get(ptep, pte);
>> +}
>> +
>> +#define ptep_get_lockless ptep_get_lockless
>> +static inline pte_t ptep_get_lockless(pte_t *ptep)
>> +{
>> +	pte_t pte = __ptep_get(ptep);
>> +
>> +	if (likely(!pte_valid_cont(pte)))
>> +		return pte;
>> +
>> +	return contpte_ptep_get_lockless(ptep);
>> +}
>> +
>> +static inline void set_pte(pte_t *ptep, pte_t pte)
>> +{
>> +	/*
>> +	 * We don't have the mm or vaddr so cannot unfold contig entries (since
>> +	 * it requires tlb maintenance). set_pte() is not used in core code, so
>> +	 * this should never even be called. Regardless do our best to service
>> +	 * any call and emit a warning if there is any attempt to set a pte on
>> +	 * top of an existing contig range.
>> +	 */
>> +	pte_t orig_pte = __ptep_get(ptep);
>> +
>> +	WARN_ON_ONCE(pte_valid_cont(orig_pte));
>> +	__set_pte(ptep, pte_mknoncont(pte));
>> +}
>> +
>> +#define set_ptes set_ptes
>> +static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
>> +				pte_t *ptep, pte_t pte, unsigned int nr)
>> +{
>> +	pte = pte_mknoncont(pte);
> 
> Why do we have to clear the contiguous bit here? Is that for the same reason as
> set_pte(), or do we expect callers to legitimately call this with the
> contiguous bit set in 'pte'?
> 
> I think you explained this to me in-person, and IIRC we don't expect callers to
> go set the bit themselves, but since it 'leaks' out to them via __ptep_get() we
> have to clear it here to defer the decision of whether to set/clear it when
> modifying entries. It would be nice if we could have a description of why/when
> we need to clear this, e.g. in the 'public API' comment block above.

Yes, I think you've got it, but just to ram home the point: The PTE_CONT bit is
private to the architecture code and is never set directly by core code. If the
public API ever receives a pte that happens to have the PTE_CONT bit set, it
would be bad news if we then accidentally set that in the pgtable.

Ideally, we would just uncondidtionally clear the bit before a getter returns
the pte (e.g. ptep_get(), ptep_get_lockless(), ptep_get_and_clear(), ...). That
way, the code code is guarranteed never to see a pte with the PTE_CONT bit set
and can therefore never accidentally pass such a pte into a setter function.
However, there is existing functionality that relies on being able to get a pte,
then pass it to pte_leaf_size(), and arch function that checks the PTE_CONT bit
to determine how big the leaf is. This is used in perf_get_pgtable_size().

So to allow perf_get_pgtable_size() to continue to see the "real" page size, I
decided to allow PTE_CONT to leak through the getters and instead
unconditionally clear the bit when a pte is passed to any of the setters.

I'll add a (slightly less verbose) comment as you suggest.

> 
>> +
>> +	if (likely(nr == 1)) {
>> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>> +		__set_ptes(mm, addr, ptep, pte, 1);
>> +	} else {
>> +		contpte_set_ptes(mm, addr, ptep, pte, nr);
>> +	}
>> +}
>> +
>> +static inline void pte_clear(struct mm_struct *mm,
>> +				unsigned long addr, pte_t *ptep)
>> +{
>> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>> +	__pte_clear(mm, addr, ptep);
>> +}
>> +
>> +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
>> +static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
>> +				unsigned long addr, pte_t *ptep)
>> +{
>> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>> +	return __ptep_get_and_clear(mm, addr, ptep);
>> +}
>> +
>> +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
>> +static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
>> +				unsigned long addr, pte_t *ptep)
>> +{
>> +	pte_t orig_pte = __ptep_get(ptep);
>> +
>> +	if (likely(!pte_valid_cont(orig_pte)))
>> +		return __ptep_test_and_clear_young(vma, addr, ptep);
>> +
>> +	return contpte_ptep_test_and_clear_young(vma, addr, ptep);
>> +}
>> +
>> +#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
>> +static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
>> +				unsigned long addr, pte_t *ptep)
>> +{
>> +	pte_t orig_pte = __ptep_get(ptep);
>> +
>> +	if (likely(!pte_valid_cont(orig_pte)))
>> +		return __ptep_clear_flush_young(vma, addr, ptep);
>> +
>> +	return contpte_ptep_clear_flush_young(vma, addr, ptep);
>> +}
>> +
>> +#define __HAVE_ARCH_PTEP_SET_WRPROTECT
>> +static inline void ptep_set_wrprotect(struct mm_struct *mm,
>> +				unsigned long addr, pte_t *ptep)
>> +{
>> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>> +	__ptep_set_wrprotect(mm, addr, ptep);
>> +}
>> +
>> +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
>> +static inline int ptep_set_access_flags(struct vm_area_struct *vma,
>> +				unsigned long addr, pte_t *ptep,
>> +				pte_t entry, int dirty)
>> +{
>> +	pte_t orig_pte = __ptep_get(ptep);
>> +
>> +	entry = pte_mknoncont(entry);
>> +
>> +	if (likely(!pte_valid_cont(orig_pte)))
>> +		return __ptep_set_access_flags(vma, addr, ptep, entry, dirty);
>> +
>> +	return contpte_ptep_set_access_flags(vma, addr, ptep, entry, dirty);
>> +}
>> +
>> +#else /* CONFIG_ARM64_CONTPTE */
>> +
>>  #define ptep_get				__ptep_get
>>  #define set_pte					__set_pte
>>  #define set_ptes				__set_ptes
>> @@ -1150,6 +1309,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
>>  #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
>>  #define ptep_set_access_flags			__ptep_set_access_flags
>>  
>> +#endif /* CONFIG_ARM64_CONTPTE */
>> +
>>  #endif /* !__ASSEMBLY__ */
>>  
>>  #endif /* __ASM_PGTABLE_H */
>> diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
>> index dbd1bc95967d..60454256945b 100644
>> --- a/arch/arm64/mm/Makefile
>> +++ b/arch/arm64/mm/Makefile
>> @@ -3,6 +3,7 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
>>  				   cache.o copypage.o flush.o \
>>  				   ioremap.o mmap.o pgd.o mmu.o \
>>  				   context.o proc.o pageattr.o fixmap.o
>> +obj-$(CONFIG_ARM64_CONTPTE)	+= contpte.o
>>  obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
>>  obj-$(CONFIG_PTDUMP_CORE)	+= ptdump.o
>>  obj-$(CONFIG_PTDUMP_DEBUGFS)	+= ptdump_debugfs.o
>> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
>> new file mode 100644
>> index 000000000000..bfb50e6b44c7
>> --- /dev/null
>> +++ b/arch/arm64/mm/contpte.c
>> @@ -0,0 +1,283 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (C) 2023 ARM Ltd.
>> + */
>> +
>> +#include <linux/mm.h>
>> +#include <linux/export.h>
>> +#include <asm/tlbflush.h>
>> +
>> +static inline bool mm_is_user(struct mm_struct *mm)
>> +{
>> +	/*
>> +	 * Don't attempt to apply the contig bit to kernel mappings, because
>> +	 * dynamically adding/removing the contig bit can cause page faults.
>> +	 * These racing faults are ok for user space, since they get serialized
>> +	 * on the PTL. But kernel mappings can't tolerate faults.
>> +	 */
>> +	return mm != &init_mm;
>> +}
> 
> We also have the efi_mm as a non-user mm, though I don't think we manipulate
> that while it is live, and I'm not sure if that needs any special handling.

Well we never need this function in the hot (order-0 folio) path, so I think I
could add a check for efi_mm here with performance implication. It's probably
safest to explicitly exclude it? What do you think?

> 
>> +static inline pte_t *contpte_align_down(pte_t *ptep)
>> +{
>> +	return (pte_t *)(ALIGN_DOWN((unsigned long)ptep >> 3, CONT_PTES) << 3);
> 
> I think this can be:
> 
> static inline pte_t *contpte_align_down(pte_t *ptep)
> {
> 	return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
> }

Yep - that's much less ugly - thanks!

> 
>> +
>> +static void contpte_convert(struct mm_struct *mm, unsigned long addr,
>> +			    pte_t *ptep, pte_t pte)
>> +{
>> +	struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0);
>> +	unsigned long start_addr;
>> +	pte_t *start_ptep;
>> +	int i;
>> +
>> +	start_ptep = ptep = contpte_align_down(ptep);
>> +	start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
>> +	pte = pfn_pte(ALIGN_DOWN(pte_pfn(pte), CONT_PTES), pte_pgprot(pte));
>> +
>> +	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) {
>> +		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
>> +
>> +		if (pte_dirty(ptent))
>> +			pte = pte_mkdirty(pte);
>> +
>> +		if (pte_young(ptent))
>> +			pte = pte_mkyoung(pte);
>> +	}
> 
> Not a big deal either way, but I wonder if it makes more sense to accumulate
> the 'ptent' dirty/young values, then modify 'pte' once, i.e.
> 
> 	bool dirty = false, young = false;
> 
> 	for (...) {
> 		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
> 		dirty |= pte_dirty(ptent);
> 		young |= pte_young(ptent);
> 	}
> 
> 	if (dirty)
> 		pte_mkdirty(pte);
> 	if (young)
> 		pte_mkyoung(pte);
> 
> I suspect that might generate slightly better code, but I'm also happy with the
> current form if people thnk that's more legible (I have no strong feelings
> either way).

I kept it this way, because its the same pattern used in arm64's hugetlbpage.c.
We also had the same comment against David's batching patches recently, and he
opted to stick with the former version:

https://lore.kernel.org/linux-mm/d83309fa-4daa-430f-ae52-4e72162bca9a at redhat.com/

So I'm inclined to leave it as is, since you're not insisting :)

> 
>> +
>> +	__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
>> +
>> +	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
>> +}
>> +
>> +void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>> +			pte_t *ptep, pte_t pte)
>> +{
>> +	/*
>> +	 * We have already checked that the ptes are contiguous in
>> +	 * contpte_try_unfold(), so just check that the mm is user space.
>> +	 */
>> +
>> +	if (!mm_is_user(mm))
>> +		return;
> 
> Nit: normally we don't put a line gap between a comment block and the
> associated block of code.

ACK, I'll fix in next version.

> 
>> +
>> +	pte = pte_mknoncont(pte);
>> +	contpte_convert(mm, addr, ptep, pte);
>> +}
>> +EXPORT_SYMBOL(__contpte_try_unfold);
>> +
>> +pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
>> +{
>> +	/*
>> +	 * Gather access/dirty bits, which may be populated in any of the ptes
>> +	 * of the contig range. We are guarranteed to be holding the PTL, so any
>> +	 * contiguous range cannot be unfolded or otherwise modified under our
>> +	 * feet.
>> +	 */
> 
> Nit: s/guarranteed/guaranteed/

ACK, I'll fix in next version.

> 
>> +
>> +	pte_t pte;
>> +	int i;
>> +
>> +	ptep = contpte_align_down(ptep);
>> +
>> +	for (i = 0; i < CONT_PTES; i++, ptep++) {
>> +		pte = __ptep_get(ptep);
>> +
>> +		if (pte_dirty(pte))
>> +			orig_pte = pte_mkdirty(orig_pte);
>> +
>> +		if (pte_young(pte))
>> +			orig_pte = pte_mkyoung(orig_pte);
>> +	}
>> +
>> +	return orig_pte;
>> +}
>> +EXPORT_SYMBOL(contpte_ptep_get);
>> +
>> +pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
>> +{
>> +	/*
>> +	 * Gather access/dirty bits, which may be populated in any of the ptes
>> +	 * of the contig range. We may not be holding the PTL, so any contiguous
>> +	 * range may be unfolded/modified/refolded under our feet. Therefore we
>> +	 * ensure we read a _consistent_ contpte range by checking that all ptes
>> +	 * in the range are valid and have CONT_PTE set, that all pfns are
>> +	 * contiguous and that all pgprots are the same (ignoring access/dirty).
>> +	 * If we find a pte that is not consistent, then we must be racing with
>> +	 * an update so start again. If the target pte does not have CONT_PTE
>> +	 * set then that is considered consistent on its own because it is not
>> +	 * part of a contpte range.
>> +	 */
>> +
>> +	pgprot_t orig_prot;
>> +	unsigned long pfn;
>> +	pte_t orig_pte;
>> +	pgprot_t prot;
>> +	pte_t *ptep;
>> +	pte_t pte;
>> +	int i;
>> +
>> +retry:
>> +	orig_pte = __ptep_get(orig_ptep);
>> +
>> +	if (!pte_valid_cont(orig_pte))
>> +		return orig_pte;
>> +
>> +	orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
>> +	ptep = contpte_align_down(orig_ptep);
>> +	pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
>> +
>> +	for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
>> +		pte = __ptep_get(ptep);
>> +		prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
>> +
>> +		if (!pte_valid_cont(pte) ||
>> +		   pte_pfn(pte) != pfn ||
>> +		   pgprot_val(prot) != pgprot_val(orig_prot))
>> +			goto retry;
>> +
>> +		if (pte_dirty(pte))
>> +			orig_pte = pte_mkdirty(orig_pte);
>> +
>> +		if (pte_young(pte))
>> +			orig_pte = pte_mkyoung(orig_pte);
>> +	}
>> +
>> +	return orig_pte;
>> +}
>> +EXPORT_SYMBOL(contpte_ptep_get_lockless);
> 
> I'm struggling to convince myself that this is safe in general, as it really
> depends on how the caller will use this value. Which caller(s) actually care
> about the access/dirty bits, given those could change at any time anyway?

I think your points below are valid, and agree we should try to make this work
without needing access/dirty if possible. But can you elaborate on why you don't
think it's safe?

> 
> I took a quick scan, and AFAICT:

Thanks for enumerating these; Saves me from having to refresh my memory :)

> 
> * For perf_get_pgtable_size(), we only care about whether the entry is valid
>   and has the contig bit set. We could clean that up with a new interface, e.g.
>   something like a new ptep_get_size_lockless().
> 
> * For gup_pte_range(), I'm not sure we actually need the access/dirty bits when
>   we look at the pte to start with, since we only care where we can logically
>   write to the page at that point.
> 
>   I see that we later follow up with:
> 
>     with pte_val(pte) != pte_val(ptep_get(ptep)))
> 
>   ... is that why we need ptep_get_lockless() to accumulate the access/dirty
>   bits? So that shape of lockless-try...locked-compare sequence works?
> 
> * For huge_pte_alloc(), arm64 doesn't select CONFIG_ARCH_WANT_GENERAL_HUGETLB,
>   so this doesn' seem to matter.
> 
> * For __collapse_huge_page_swapin(), we only care if the pte is a swap pte,
>   which means the pte isn't valid, and we'll return the orig_pte as-is anyway.
> 
> * For pte_range_none() the access/dirty bits don't matter.
> 
> * For handle_pte_fault() I think we have the same shape of
>   lockless-try...locked-compare sequence as for gup_pte_range(), where we don't
>   care about the acess/dirty bits before we reach the locked compare step.
> 
> * For ptdump_pte_entry() I think it's arguable that we should continue to
>   report the access/dirty bits separately for each PTE, as we have done until
>   now, to give an accurate representation of the contents of the translation
>   tables.
> 
> * For swap_vma_readahead() and unuse_pte_range() we only care if the PTE is a
>   swap entry, the access/dirty bits don't matter.
> 
> So AFAICT this only really matters for gup_pte_range() and handle_pte_fault(),
> and IIUC that's only so that the locklessly-loaded pte value can be compared
> with a subsequently locked-loaded entry (for which the access/dirty bits will
> be accumulated). Have I understood that correctly?

Yes, I agree with what you are saying. My approach was to try to implement the
existing APIs accurately though, the argument being that it reduces the chances
of getting it wrong. But if you think the implementation is unsafe, then I guess
it blows that out of the water...

> 
> If so, I wonder if we could instead do that comparison modulo the access/dirty
> bits, 

I think that would work - but will need to think a bit more on it.

> and leave ptep_get_lockless() only reading a single entry?

I think we will need to do something a bit less fragile. ptep_get() does collect
the access/dirty bits so its confusing if ptep_get_lockless() doesn't IMHO. So
we will likely want to rename the function and make its documentation explicit
that it does not return those bits.

ptep_get_lockless_noyoungdirty()? yuk... Any ideas?

Of course if I could convince you the current implementation is safe, I might be
able to sidestep this optimization until a later date?

Thanks,
Ryan


> 
> Thanks,
> Mark.
> 
>> +void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
>> +					pte_t *ptep, pte_t pte, unsigned int nr)
>> +{
>> +	unsigned long next;
>> +	unsigned long end;
>> +	unsigned long pfn;
>> +	pgprot_t prot;
>> +
>> +	/*
>> +	 * The set_ptes() spec guarantees that when nr > 1, the initial state of
>> +	 * all ptes is not-present. Therefore we never need to unfold or
>> +	 * otherwise invalidate a range before we set the new ptes.
>> +	 * contpte_set_ptes() should never be called for nr < 2.
>> +	 */
>> +	VM_WARN_ON(nr == 1);
>> +
>> +	if (!mm_is_user(mm))
>> +		return __set_ptes(mm, addr, ptep, pte, nr);
>> +
>> +	end = addr + (nr << PAGE_SHIFT);
>> +	pfn = pte_pfn(pte);
>> +	prot = pte_pgprot(pte);
>> +
>> +	do {
>> +		next = pte_cont_addr_end(addr, end);
>> +		nr = (next - addr) >> PAGE_SHIFT;
>> +		pte = pfn_pte(pfn, prot);
>> +
>> +		if (((addr | next | (pfn << PAGE_SHIFT)) & ~CONT_PTE_MASK) == 0)
>> +			pte = pte_mkcont(pte);
>> +		else
>> +			pte = pte_mknoncont(pte);
>> +
>> +		__set_ptes(mm, addr, ptep, pte, nr);
>> +
>> +		addr = next;
>> +		ptep += nr;
>> +		pfn += nr;
>> +
>> +	} while (addr != end);
>> +}
>> +EXPORT_SYMBOL(contpte_set_ptes);
>> +
>> +int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>> +					unsigned long addr, pte_t *ptep)
>> +{
>> +	/*
>> +	 * ptep_clear_flush_young() technically requires us to clear the access
>> +	 * flag for a _single_ pte. However, the core-mm code actually tracks
>> +	 * access/dirty per folio, not per page. And since we only create a
>> +	 * contig range when the range is covered by a single folio, we can get
>> +	 * away with clearing young for the whole contig range here, so we avoid
>> +	 * having to unfold.
>> +	 */
>> +
>> +	int young = 0;
>> +	int i;
>> +
>> +	ptep = contpte_align_down(ptep);
>> +	addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
>> +
>> +	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
>> +		young |= __ptep_test_and_clear_young(vma, addr, ptep);
>> +
>> +	return young;
>> +}
>> +EXPORT_SYMBOL(contpte_ptep_test_and_clear_young);
>> +
>> +int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>> +					unsigned long addr, pte_t *ptep)
>> +{
>> +	int young;
>> +
>> +	young = contpte_ptep_test_and_clear_young(vma, addr, ptep);
>> +
>> +	if (young) {
>> +		/*
>> +		 * See comment in __ptep_clear_flush_young(); same rationale for
>> +		 * eliding the trailing DSB applies here.
>> +		 */
>> +		addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
>> +		__flush_tlb_range_nosync(vma, addr, addr + CONT_PTE_SIZE,
>> +					 PAGE_SIZE, true, 3);
>> +	}
>> +
>> +	return young;
>> +}
>> +EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
>> +
>> +int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>> +					unsigned long addr, pte_t *ptep,
>> +					pte_t entry, int dirty)
>> +{
>> +	unsigned long start_addr;
>> +	pte_t orig_pte;
>> +	int i;
>> +
>> +	/*
>> +	 * Gather the access/dirty bits for the contiguous range. If nothing has
>> +	 * changed, its a noop.
>> +	 */
>> +	orig_pte = pte_mknoncont(ptep_get(ptep));
>> +	if (pte_val(orig_pte) == pte_val(entry))
>> +		return 0;
>> +
>> +	/*
>> +	 * We can fix up access/dirty bits without having to unfold the contig
>> +	 * range. But if the write bit is changing, we must unfold.
>> +	 */
>> +	if (pte_write(orig_pte) == pte_write(entry)) {
>> +		/*
>> +		 * For HW access management, we technically only need to update
>> +		 * the flag on a single pte in the range. But for SW access
>> +		 * management, we need to update all the ptes to prevent extra
>> +		 * faults. Avoid per-page tlb flush in __ptep_set_access_flags()
>> +		 * and instead flush the whole range at the end.
>> +		 */
>> +		ptep = contpte_align_down(ptep);
>> +		start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
>> +
>> +		for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
>> +			__ptep_set_access_flags(vma, addr, ptep, entry, 0);
>> +
>> +		if (dirty)
>> +			__flush_tlb_range(vma, start_addr, addr,
>> +							PAGE_SIZE, true, 3);
>> +	} else {
>> +		__contpte_try_unfold(vma->vm_mm, addr, ptep, orig_pte);
>> +		__ptep_set_access_flags(vma, addr, ptep, entry, dirty);
>> +	}
>> +
>> +	return 1;
>> +}
>> +EXPORT_SYMBOL(contpte_ptep_set_access_flags);
>> -- 
>> 2.25.1
>>



From ryan.roberts at arm.com  Mon Feb 12 05:05:51 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 13:05:51 +0000
Subject: [PATCH v5 18/25] arm64/mm: Split __flush_tlb_range() to elide
 trailing DSB
In-Reply-To: <9e1d793a-02c9-4dbb-a6d4-1e1c0c42638c@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-19-ryan.roberts@arm.com>
 <9e1d793a-02c9-4dbb-a6d4-1e1c0c42638c@redhat.com>
Message-ID: <1ef4c737-0926-424c-9698-794c23370b74@arm.com>

On 12/02/2024 12:44, David Hildenbrand wrote:
> On 02.02.24 09:07, Ryan Roberts wrote:
>> Split __flush_tlb_range() into __flush_tlb_range_nosync() +
>> __flush_tlb_range(), in the same way as the existing flush_tlb_page()
>> arrangement. This allows calling __flush_tlb_range_nosync() to elide the
>> trailing DSB. Forthcoming "contpte" code will take advantage of this
>> when clearing the young bit from a contiguous range of ptes.
>>
>> Tested-by: John Hubbard <jhubbard at nvidia.com>
>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>> ---
>> ? arch/arm64/include/asm/tlbflush.h | 13 +++++++++++--
>> ? 1 file changed, 11 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/tlbflush.h
>> b/arch/arm64/include/asm/tlbflush.h
>> index 79e932a1bdf8..50a765917327 100644
>> --- a/arch/arm64/include/asm/tlbflush.h
>> +++ b/arch/arm64/include/asm/tlbflush.h
>> @@ -422,7 +422,7 @@ do {??????????????????????????????????? \
>> ? #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \
>> ????? __flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false,
>> kvm_lpa2_is_enabled());
>> ? -static inline void __flush_tlb_range(struct vm_area_struct *vma,
>> +static inline void __flush_tlb_range_nosync(struct vm_area_struct *vma,
>> ?????????????????????? unsigned long start, unsigned long end,
>> ?????????????????????? unsigned long stride, bool last_level,
>> ?????????????????????? int tlb_level)
>> @@ -456,10 +456,19 @@ static inline void __flush_tlb_range(struct
>> vm_area_struct *vma,
>> ????????? __flush_tlb_range_op(vae1is, start, pages, stride, asid,
>> ?????????????????????? tlb_level, true, lpa2_is_enabled());
>> ? -??? dsb(ish);
>> ????? mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
>> ? }
>> ? +static inline void __flush_tlb_range(struct vm_area_struct *vma,
>> +???????????????????? unsigned long start, unsigned long end,
>> +???????????????????? unsigned long stride, bool last_level,
>> +???????????????????? int tlb_level)
>> +{
>> +??? __flush_tlb_range_nosync(vma, start, end, stride,
>> +???????????????? last_level, tlb_level);
>> +??? dsb(ish);
>> +}
>> +
>> ? static inline void flush_tlb_range(struct vm_area_struct *vma,
>> ???????????????????? unsigned long start, unsigned long end)
>> ? {
> 
> You're now calling dsb() after mmu_notifier_arch_invalidate_secondary_tlbs().
> 
> 
> In flush_tlb_mm(), we have the order
> 
> ????dsb(ish);???
> ????mmu_notifier_arch_invalidate_secondary_tlbs()
> 
> In flush_tlb_page(), we have the effective order:
> 
> ????mmu_notifier_arch_invalidate_secondary_tlbs()
> ????dsb(ish);
> 
> In flush_tlb_range(), we used to have the order:
> 
> ????dsb(ish);
> ????mmu_notifier_arch_invalidate_secondary_tlbs();
> 
> 
> So I *suspect* having that DSB before
> mmu_notifier_arch_invalidate_secondary_tlbs() is fine. Hopefully, nothing in
> there relies on that placement.

Will spotted this against v3. My argument was that I was following the existing
pattern in flush_tlb_page(). Apparently that is not correct and needs changing,
but the conclusion was to leave my change as is for now, since it is consistent
and change them at a later date together.

https://lore.kernel.org/linux-arm-kernel/123a58b0-2ea6-4da3-9719-98ca55c8095e at arm.com/



> 
> Maybe wort spelling out in the patch description
> 
> Reviewed-by: David Hildenbrand <david at redhat.com>
> 

Thanks!




From david at redhat.com  Mon Feb 12 05:06:35 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 14:06:35 +0100
Subject: [PATCH v7 0/4] kvm: arm64: allow the VM to select DEVICE_* and
 NORMAL_NC for IO memory
In-Reply-To: <20240212125654.GV10476@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
 <aa6c1708-d6ac-46f7-b7ab-e97a273a90c2@redhat.com>
 <20240212125654.GV10476@nvidia.com>
Message-ID: <30493284-53f6-4172-a9e1-cb9052acced4@redhat.com>

Hi Jason,

Thanks for all the details (some might be valuable to document in more 
detail, but I'm not that experienced with all of the mapping types on 
arm64, so it might "just be me").

> It is worse that some hand wavey "side effect". If you map memory with
> NORMAL_NC (ie for write combining) then writel() doesn't work
> correctly at all.
> 
> The memory must be mapped according to which kernel APIs the actual
> driver in the VM will use. writel() vs __iowrite64_copy().
> 
>> We can trigger both cases right now inside VMs, where we want the device
>> driver to actually make the decision.
> 
> Yes
>   
>> (2) For a VM, that device driver lives inside the VM, for DPDK and friends,
>> it lives in user space. They have this information.
> 
> Yes
>   
>> We only focus here on optimizing (fixing?) the mapping for VMs, DPDK is out
>> of the picture.
> 
> DPDK will be solved through some VFIO ioctl, we know how to do it,
> just nobody has cared enough to do it.

Good!

> 
>> So we want to allow the VM to achieve a WC/NC mapping by using a
>> relaxed (NC) mapping in stage-1. Whatever is set in stage-2 wins.
> 
> Yes
>   
>>
>> (3) vfio knows whether using WC (and NC?) could be problematic, and must
>> forbid it, if that is the case. There are cases where we could otherwise
>> cause harm (bring down the host?). We must keep mapping the memory as
>> DEVICE_nGnRE when in doubt.
> 
> Yes, there is an unspecific fear that on ARM platforms using NORMAL_NC
> in the wrong way can trigger a catastrophic error and kill the
> host. There is no way to know if the platform has this bug, so the
> agreement was to be conservative and only allow it for vfio-pci, based
> on some specific details of how PCI has to be implemented and ARM
> guidance on PCI integration..
> 
>> Now, what the new mmap() flag does is tell the world "using the wrong
>> mapping type cannot bring down the host", and KVM uses that to use a
>> different mapping type (NC) in stage-1 as setup by vfio in the user space
>> page tables.
> 
> The inverse meaning, we assume VMAs with the flag can bring down the
> host, but yes.

Got it, will have a closer look at the patch soon.

> 
>> I was trying to find ways of avoiding a mmap() flag and was hoping that we
>> could just use a PTE bit that does not have semantics in VM_PFNMAP mappings.
>> Unfortunately, arm64 does not support uffd-wp, which I had in mind, so it's
>> not that easy.
> 
> Seems like a waste of a valuable PTE bit to me.

It would rather have been "it's already unused there, so let's reuse 
it". But there was no such low-hanging gruit.

> 
>> Further, I was wondering if there would be a way to let DPDK similarly
>> benefit, because it looks like we are happily ignoring that (I was told they
>> apply some hacks to work around that).
> 
> dpdk doesn't need the VMA bit, we know how to solve it with vfio
> ioctls, it is very straightforward. dpdk just does a ioctl & mmap and
> VFIO will create a vma with pgprote_writecombine(). Completely
> trivial, the only nasty bit is fitting this into the VFIO uAPI.

That's what I thought.

> 
>> (a) User space tells VFIO which parts of a BAR it would like to have mapped
>> differently. For QEMU, this would mean, requesting a NC mapping for the
>> whole BAR. For DPDK, it could mean requesting different types for parts of a
>> BAR.
> 
> We don't want to have have the memory mapped as NC in qemu. As I said
> above if it is mapped NC then writel() doesn't work. We can't have
> conflicting mappings that go toward NC when the right answer is
> DEVICE.

I was wondering who would trigger that, but as I read below it could be 
MMIO emulation.

> 
> writel() on NC will malfunction.
> 
> __iowrite64_copy() on DEVICE will be functionally correct but slower.
> 
> The S2 mapping that KVM creates is special because it doesn't actually
> map it once the VM kernel gets started. The VM kernel always supplies
> a S1 table that sets the correct type.
> 
> So if qemu has DEVICE, the S2 has NC and the VM's S1 has DEVICE then
> the mapping is realiably made to be DEVICE. The hidden S2 doesn't
> cause a problem.
> 
>> That would mean, that we would map NC already in QEMU. I wonder if that
>> could be a problem with read speculation, even if QEMU never really accesses
>> that mmap'ed region.
> 
> Also correct.
> 
> Further, qemu may need to do emulation for MMIO in various cases and
> the qemu logic for this requires a DEVICE mapping or the emulation
> will malfunction.
> 
> Using NC in qemu is off the table.

Good, thanks for the details, all makes sense to me.

-- 
Cheers,

David / dhildenb



From david at redhat.com  Mon Feb 12 05:13:04 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 14:13:04 +0100
Subject: [PATCH v7 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <20240211174705.31992-3-ankita@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
 <20240211174705.31992-3-ankita@nvidia.com>
Message-ID: <165363ba-d6cc-47a7-ab2a-d3a27a42f739@redhat.com>

On 11.02.24 18:47, ankita at nvidia.com wrote:
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> Generalizing S2 setting from DEVICE_nGnRE to NormalNc for non PCI
> devices may be problematic. E.g. GICv2 vCPU interface, which is
> effectively a shared peripheral, can allow a guest to affect another
> guest's interrupt distribution. The issue may be solved by limiting
> the relaxation to mappings that have a user VMA. Still there is
> insufficient information and uncertainity in the behavior of

s/uncertainity/uncertainty/

> non PCI drivers.
> 
> Add a new flag VM_ALLOW_ANY_UNCACHED to indicate KVM that the device
> is WC capable and these S2 changes can be extended to it. KVM can use
> this flag to activate the code.
> 

MM people will stumble only over this commit at some point, looking for 
details. It might make sense to add a bit more details on the underlying 
problem (user space tables vs. stage-1 vs. stage-2) and why we want to 
have a different mapping in user space compared to stage-1.

Then, describe that the VMA flag was found to be the simplest and 
cleanest way to communicate this information from VFIO to KVM.

> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> ---
>   include/linux/mm.h | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
> 
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index f5a97dec5169..59576e56c58b 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -391,6 +391,20 @@ extern unsigned int kobjsize(const void *objp);
>   # define VM_UFFD_MINOR		VM_NONE
>   #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
>   
> +/*
> + * This flag is used to connect VFIO to arch specific KVM code. It
> + * indicates that the memory under this VMA is safe for use with any
> + * non-cachable memory type inside KVM. Some VFIO devices, on some
> + * platforms, are thought to be unsafe and can cause machine crashes
> + * if KVM does not lock down the memory type.
> + */
> +#ifdef CONFIG_64BIT
> +#define VM_ALLOW_ANY_UNCACHED_BIT	39
> +#define VM_ALLOW_ANY_UNCACHED		BIT(VM_ALLOW_ANY_UNCACHED_BIT)
> +#else
> +#define VM_ALLOW_ANY_UNCACHED		VM_NONE
> +#endif
> +
>   /* Bits set in the VMA until the stack is in its final location */
>   #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
>   

It's not perfect (very VFIO <-> KVM specific right now, VMA flags feel a 
bit wrong), but it certainly easier and cleaner than any alternatives I 
could think of.

Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From mripard at kernel.org  Mon Feb 12 05:12:43 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:43 +0100
Subject: [PATCH v6 00/36] drm/connector: Create HDMI Connector
 infrastructure
Message-ID: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>

Hi,

Here's a series that creates some extra infrastructure specifically
targeted at HDMI controllers.

The idea behind this series came from a recent discussion on IRC during
which we discussed infoframes generation of i915 vs everything else.

Infoframes generation code still requires some decent boilerplate, with
each driver doing some variation of it.

In parallel, while working on vc4, we ended up converting a lot of i915
logic (mostly around format / bpc selection, and scrambler setup) to
apply on top of a driver that relies only on helpers.

While currently sitting in the vc4 driver, none of that logic actually
relies on any driver or hardware-specific behaviour.

The only missing piece to make it shareable are a bunch of extra
variables stored in a state (current bpc, format, RGB range selection,
etc.).

The initial implementation was relying on some generic subclass of
drm_connector to address HDMI connectors, with a bunch of helpers that
will take care of all the "HDMI Spec" related code. Scrambler setup is
missing at the moment but can easily be plugged in.

The feedback was that creating a connector subclass like was done for
writeback would prevent the adoption of those helpers since it couldn't
be used in all situations (like when the connector driver can implement
multiple output) and required more churn to cast between the
drm_connector and its subclass. The decision was thus to provide a set
of helper and to store the required variables in drm_connector and
drm_connector_state. This what has been implemented now.

Hans Verkuil also expressed interest in implementing a mechanism in v4l2
to retrieve infoframes from HDMI receiver and implementing a tool to
decode (and eventually check) infoframes. His current work on
edid-decode to enable that based on that series can be found here:
https://git.linuxtv.org/hverkuil/edid-decode.git/log/?h=hverkuil

And some more context here:
https://lore.kernel.org/dri-devel/50db7366-cd3d-4675-aaad-b857202234de at xs4all.nl/

This series thus leverages the infoframe generation code to expose it
through debugfs.

I also used the occasion to unit-test everything but the infoframe
generation, which can come later once I get a proper understanding of
what the infoframe are supposed to look like. This required to add some
extra kunit helpers and infrastructure to have multiple EDIDs and allow
each test to run with a particular set of capabilities.

This entire series has been tested on a Pi4, passes all its unittests
(125 new tests), and has only been build-tested for sunxi and rockchip.

Let me know what you think,
Maxime

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
Changes in v6:
- Rebased on top of current next
- Split the tests into separate patches
- Improve the Broadcast RGB documentation
- Link to v5: https://lore.kernel.org/r/20231207-kms-hdmi-connector-state-v5-0-6538e19d634d at kernel.org

Changes in v5:
- Dropped the connector init arg checking patch, and the related kunit
  tests
- Dropped HDMI Vendor infoframes in rockchip inno_hdmi
- Fixed the build warnings
- Link to v4: https://lore.kernel.org/r/20231128-kms-hdmi-connector-state-v4-0-c7602158306e at kernel.org

Changes in v4:
- Create unit tests for everything but infoframes
- Fix a number of bugs identified by the unit tests
- Rename DRM (Dynamic Range and Mastering) infoframe file to HDR_DRM
- Drop RFC status
- Link to v3: https://lore.kernel.org/r/20231031-kms-hdmi-connector-state-v3-0-328b0fae43a7 at kernel.org

Changes in v3:
- Made sure the series work on the RaspberryPi4
- Handle YUV420 in the char clock rate computation
- Use the maximum bpc value the connector allows at reset
- Expose the RGB Limited vs Full Range value in the connector state
  instead of through a helper
- Fix Broadcast RGB documentation
- Add more debug logging
- Small fixes here and there
- Link to v2: https://lore.kernel.org/r/20230920-kms-hdmi-connector-state-v2-0-17932daddd7d at kernel.org

Changes in v2:
- Change from a subclass to a set of helpers for drm_connector and
  drm_connector state
- Don't assume that all drivers support RGB, YUV420 and YUV422 but make
  them provide a bitfield instead.
- Don't assume that all drivers support the Broadcast RGB property but
  make them call the registration helper.
- Document the Broacast RGB property
- Convert the inno_hdmi and sun4i_hdmi driver.
- Link to v1: https://lore.kernel.org/r/20230814-kms-hdmi-connector-state-v1-0-048054df3654 at kernel.org

---
Maxime Ripard (36):
      drm/tests: helpers: Include missing drm_drv header
      drm/tests: helpers: Add atomic helpers
      drm/tests: Add helper to create mock plane
      drm/tests: Add helper to create mock crtc
      drm/tests: connector: Add tests for drmm_connector_init
      drm/connector: Introduce an HDMI connector initialization function
      drm/tests: connector: Add tests for drmm_connector_hdmi_init
      drm/connector: hdmi: Create an HDMI sub-state
      drm/connector: hdmi: Add Broadcast RGB property
      drm/tests: Add tests for Broadcast RGB property
      drm/connector: hdmi: Add RGB Quantization Range to the connector state
      drm/tests: Add RGB Quantization tests
      drm/connector: hdmi: Add output BPC to the connector state
      drm/tests: Add output bpc tests
      drm/connector: hdmi: Add support for output format
      drm/tests: Add output formats tests
      drm/connector: hdmi: Add HDMI compute clock helper
      drm/tests: Add HDMI TDMS character rate tests
      drm/connector: hdmi: Calculate TMDS character rate
      drm/tests: Add TDMS character rate connector state tests
      drm/connector: hdmi: Add custom hook to filter TMDS character rate
      drm/tests: Add HDMI connector rate filter hook tests
      drm/connector: hdmi: Compute bpc and format automatically
      drm/tests: Add HDMI connector bpc and format tests
      drm/connector: hdmi: Add Infoframes generation
      drm/tests: Add infoframes test
      drm/connector: hdmi: Create Infoframe DebugFS entries
      drm/vc4: hdmi: Switch to HDMI connector
      drm/vc4: tests: Remove vc4_dummy_plane structure
      drm/vc4: tests: Convert to plane creation helper
      drm/rockchip: inno_hdmi: Switch to HDMI connector
      drm/sun4i: hdmi: Convert encoder to atomic
      drm/sun4i: hdmi: Move mode_set into enable
      drm/sun4i: hdmi: Switch to container_of_const
      drm/sun4i: hdmi: Consolidate atomic_check and mode_valid
      drm/sun4i: hdmi: Switch to HDMI connector

 Documentation/gpu/kms-properties.csv               |    1 -
 drivers/gpu/drm/Kconfig                            |    1 +
 drivers/gpu/drm/drm_atomic.c                       |   11 +
 drivers/gpu/drm/drm_atomic_state_helper.c          |  659 ++++++++
 drivers/gpu/drm/drm_atomic_uapi.c                  |    4 +
 drivers/gpu/drm/drm_connector.c                    |  264 +++
 drivers/gpu/drm/drm_debugfs.c                      |  110 ++
 drivers/gpu/drm/rockchip/inno_hdmi.c               |  123 +-
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c             |  203 ++-
 drivers/gpu/drm/tests/Makefile                     |    1 +
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 1728 ++++++++++++++++++++
 drivers/gpu/drm/tests/drm_connector_test.c         | 1227 +++++++++++++-
 drivers/gpu/drm/tests/drm_kunit_edid.h             |  482 ++++++
 drivers/gpu/drm/tests/drm_kunit_helpers.c          |  150 ++
 drivers/gpu/drm/vc4/tests/vc4_mock.c               |    6 +-
 drivers/gpu/drm/vc4/tests/vc4_mock.h               |    9 +-
 drivers/gpu/drm/vc4/tests/vc4_mock_plane.c         |   44 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c                     |  638 +-------
 drivers/gpu/drm/vc4/vc4_hdmi.h                     |   44 +-
 drivers/gpu/drm/vc4/vc4_hdmi_phy.c                 |    6 +-
 include/drm/drm_atomic_state_helper.h              |   12 +
 include/drm/drm_connector.h                        |  257 +++
 include/drm/drm_kunit_helpers.h                    |   23 +
 23 files changed, 5186 insertions(+), 817 deletions(-)
---
base-commit: ae00c445390b349e070a64dc62f08aa878db7248
change-id: 20230814-kms-hdmi-connector-state-616787e67927

Best regards,
-- 
Maxime Ripard <mripard at kernel.org>



From mripard at kernel.org  Mon Feb 12 05:12:44 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:44 +0100
Subject: [PATCH v6 01/36] drm/tests: helpers: Include missing drm_drv
 header
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-1-f4bcdc979e6f@kernel.org>

We have a few functions declared in our kunit helpers header, some of
them dereferencing the struct drm_driver.

However, we don't include the drm_drv.h header file defining that
structure, leading to compilation errors if we don't include both
headers.

Fixes: d98780310719 ("drm/tests: helpers: Allow to pass a custom drm_driver")
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 include/drm/drm_kunit_helpers.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
index ba483c87f0e7..3ae19892229d 100644
--- a/include/drm/drm_kunit_helpers.h
+++ b/include/drm/drm_kunit_helpers.h
@@ -3,6 +3,8 @@
 #ifndef DRM_KUNIT_HELPERS_H_
 #define DRM_KUNIT_HELPERS_H_
 
+#include <drm/drm_drv.h>
+
 #include <linux/device.h>
 
 #include <kunit/test.h>

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:45 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:45 +0100
Subject: [PATCH v6 02/36] drm/tests: helpers: Add atomic helpers
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-2-f4bcdc979e6f@kernel.org>

The mock device we were creating was missing any of the driver-wide
helpers. That was fine before since we weren't testing the atomic state
path, but we're going to start, so let's use the default
implementations.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_kunit_helpers.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index ca4f8e4c5d5d..4fb11b938bc1 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_kunit_helpers.h>
 #include <drm/drm_managed.h>
@@ -14,6 +15,8 @@
 #define KUNIT_DEVICE_NAME	"drm-kunit-mock-device"
 
 static const struct drm_mode_config_funcs drm_mode_config_funcs = {
+	.atomic_check	= drm_atomic_helper_check,
+	.atomic_commit	= drm_atomic_helper_commit,
 };
 
 /**

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:46 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:46 +0100
Subject: [PATCH v6 03/36] drm/tests: Add helper to create mock plane
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-3-f4bcdc979e6f@kernel.org>

We're going to need a full-blown, functional, KMS device to test more
components of the atomic modesetting infrastructure.

Let's add a new helper to create a dumb, mocked, primary plane. By
default, it will create a linear XRGB8888 plane, using the default
helpers.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_kunit_helpers.c | 85 +++++++++++++++++++++++++++++++
 include/drm/drm_kunit_helpers.h           | 11 ++++
 2 files changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index 4fb11b938bc1..32dc8354641a 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -3,6 +3,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_drv.h>
+#include <drm/drm_fourcc.h>
 #include <drm/drm_kunit_helpers.h>
 #include <drm/drm_managed.h>
 
@@ -164,5 +165,89 @@ drm_kunit_helper_atomic_state_alloc(struct kunit *test,
 }
 EXPORT_SYMBOL_GPL(drm_kunit_helper_atomic_state_alloc);
 
+static const uint32_t default_plane_formats[] = {
+	DRM_FORMAT_XRGB8888,
+};
+
+static const uint64_t default_plane_modifiers[] = {
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID
+};
+
+static const struct drm_plane_helper_funcs default_plane_helper_funcs = {
+};
+
+static const struct drm_plane_funcs default_plane_funcs = {
+	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
+	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
+	.reset			= drm_atomic_helper_plane_reset,
+};
+
+/**
+ * drm_kunit_helper_create_primary_plane - Creates a mock primary plane for a KUnit test
+ * @test: The test context object
+ * @drm: The device to alloc the plane for
+ * @funcs: Callbacks for the new plane. Optional.
+ * @helper_funcs: Helpers callbacks for the new plane. Optional.
+ * @formats: array of supported formats (DRM_FORMAT\_\*). Optional.
+ * @num_formats: number of elements in @formats
+ * @modifiers: array of struct drm_format modifiers terminated by
+ *             DRM_FORMAT_MOD_INVALID. Optional.
+ *
+ * This allocates and initializes a mock struct &drm_plane meant to be
+ * part of a mock device for a KUnit test.
+ *
+ * Resources will be cleaned up automatically.
+ *
+ * @funcs will default to the default helpers implementations.
+ * @helper_funcs will default to an empty implementation. @formats will
+ * default to XRGB8888 only. @modifiers will default to a linear
+ * modifier only.
+ *
+ * Returns:
+ * A pointer to the new plane, or an ERR_PTR() otherwise.
+ */
+struct drm_plane *
+drm_kunit_helper_create_primary_plane(struct kunit *test,
+				      struct drm_device *drm,
+				      const struct drm_plane_funcs *funcs,
+				      const struct drm_plane_helper_funcs *helper_funcs,
+				      const uint32_t *formats,
+				      unsigned int num_formats,
+				      const uint64_t *modifiers)
+{
+	struct drm_plane *plane;
+
+	if (!funcs)
+		funcs = &default_plane_funcs;
+
+	if (!helper_funcs)
+		helper_funcs = &default_plane_helper_funcs;
+
+	if (!formats || !num_formats) {
+		formats = default_plane_formats;
+		num_formats = ARRAY_SIZE(default_plane_formats);
+	}
+
+	if (!modifiers)
+		modifiers = default_plane_modifiers;
+
+	plane = __drmm_universal_plane_alloc(drm,
+					     sizeof(struct drm_plane), 0,
+					     0,
+					     funcs,
+					     formats,
+					     num_formats,
+					     default_plane_modifiers,
+					     DRM_PLANE_TYPE_PRIMARY,
+					     NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
+
+	drm_plane_helper_add(plane, helper_funcs);
+
+	return plane;
+}
+EXPORT_SYMBOL_GPL(drm_kunit_helper_create_primary_plane);
+
 MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");
 MODULE_LICENSE("GPL");
diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
index 3ae19892229d..38667d624aa8 100644
--- a/include/drm/drm_kunit_helpers.h
+++ b/include/drm/drm_kunit_helpers.h
@@ -10,6 +10,8 @@
 #include <kunit/test.h>
 
 struct drm_device;
+struct drm_plane_funcs;
+struct drm_plane_helper_funcs;
 struct kunit;
 
 struct device *drm_kunit_helper_alloc_device(struct kunit *test);
@@ -99,4 +101,13 @@ drm_kunit_helper_atomic_state_alloc(struct kunit *test,
 				    struct drm_device *drm,
 				    struct drm_modeset_acquire_ctx *ctx);
 
+struct drm_plane *
+drm_kunit_helper_create_primary_plane(struct kunit *test,
+				      struct drm_device *drm,
+				      const struct drm_plane_funcs *funcs,
+				      const struct drm_plane_helper_funcs *helper_funcs,
+				      const uint32_t *formats,
+				      unsigned int num_formats,
+				      const uint64_t *modifiers);
+
 #endif // DRM_KUNIT_HELPERS_H_

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:47 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:47 +0100
Subject: [PATCH v6 04/36] drm/tests: Add helper to create mock crtc
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-4-f4bcdc979e6f@kernel.org>

We're going to need a full-blown, functional, KMS device to test more
components of the atomic modesetting infrastructure.

Let's add a new helper to create a dumb, mocked, CRTC. By default it
will create a CRTC relying only on the default helpers, but drivers are
free to deviate from that.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_kunit_helpers.c | 62 +++++++++++++++++++++++++++++++
 include/drm/drm_kunit_helpers.h           | 10 +++++
 2 files changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index 32dc8354641a..d5317d13d3fc 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -249,5 +249,67 @@ drm_kunit_helper_create_primary_plane(struct kunit *test,
 }
 EXPORT_SYMBOL_GPL(drm_kunit_helper_create_primary_plane);
 
+static const struct drm_crtc_helper_funcs default_crtc_helper_funcs = {
+};
+
+static const struct drm_crtc_funcs default_crtc_funcs = {
+	.atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.reset                  = drm_atomic_helper_crtc_reset,
+};
+
+/**
+ * drm_kunit_helper_create_crtc - Creates a mock CRTC for a KUnit test
+ * @test: The test context object
+ * @drm: The device to alloc the plane for
+ * @primary: Primary plane for CRTC
+ * @cursor: Cursor plane for CRTC. Optional.
+ * @funcs: Callbacks for the new plane. Optional.
+ * @helper_funcs: Helpers callbacks for the new plane. Optional.
+ *
+ * This allocates and initializes a mock struct &drm_crtc meant to be
+ * part of a mock device for a KUnit test.
+ *
+ * Resources will be cleaned up automatically.
+ *
+ * @funcs will default to the default helpers implementations.
+ * @helper_funcs will default to an empty implementation.
+ *
+ * Returns:
+ * A pointer to the new CRTC, or an ERR_PTR() otherwise.
+ */
+struct drm_crtc *
+drm_kunit_helper_create_crtc(struct kunit *test,
+			     struct drm_device *drm,
+			     struct drm_plane *primary,
+			     struct drm_plane *cursor,
+			     const struct drm_crtc_funcs *funcs,
+			     const struct drm_crtc_helper_funcs *helper_funcs)
+{
+	struct drm_crtc *crtc;
+	int ret;
+
+	if (!funcs)
+		funcs = &default_crtc_funcs;
+
+	if (!helper_funcs)
+		helper_funcs = &default_crtc_helper_funcs;
+
+	crtc = drmm_kzalloc(drm, sizeof(*crtc), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, crtc);
+
+	ret = drmm_crtc_init_with_planes(drm, crtc,
+					 primary,
+					 cursor,
+					 funcs,
+					 NULL);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	drm_crtc_helper_add(crtc, helper_funcs);
+
+	return crtc;
+}
+EXPORT_SYMBOL_GPL(drm_kunit_helper_create_crtc);
+
 MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");
 MODULE_LICENSE("GPL");
diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
index 38667d624aa8..6e99627edf45 100644
--- a/include/drm/drm_kunit_helpers.h
+++ b/include/drm/drm_kunit_helpers.h
@@ -9,6 +9,8 @@
 
 #include <kunit/test.h>
 
+struct drm_crtc_funcs;
+struct drm_crtc_helper_funcs;
 struct drm_device;
 struct drm_plane_funcs;
 struct drm_plane_helper_funcs;
@@ -110,4 +112,12 @@ drm_kunit_helper_create_primary_plane(struct kunit *test,
 				      unsigned int num_formats,
 				      const uint64_t *modifiers);
 
+struct drm_crtc *
+drm_kunit_helper_create_crtc(struct kunit *test,
+			     struct drm_device *drm,
+			     struct drm_plane *primary,
+			     struct drm_plane *cursor,
+			     const struct drm_crtc_funcs *funcs,
+			     const struct drm_crtc_helper_funcs *helper_funcs);
+
 #endif // DRM_KUNIT_HELPERS_H_

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:48 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:48 +0100
Subject: [PATCH v6 05/36] drm/tests: connector: Add tests for
 drmm_connector_init
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-5-f4bcdc979e6f@kernel.org>

drmm_connector_init is the preferred function to initialize a
drm_connector structure. Let's add a bunch of unit tests for it.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_connector_test.c | 170 ++++++++++++++++++++++++++++-
 1 file changed, 169 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index c66aa2dc8d9d..a268847be8d1 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -3,10 +3,175 @@
  * Kunit test for drm_modes functions
  */
 
+#include <linux/i2c.h>
+
+#include <drm/drm_atomic_state_helper.h>
 #include <drm/drm_connector.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_kunit_helpers.h>
 
 #include <kunit/test.h>
 
+struct drm_connector_init_priv {
+	struct drm_device drm;
+	struct drm_connector connector;
+	struct i2c_adapter ddc;
+};
+
+static const struct drm_connector_funcs dummy_funcs = {
+	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
+	.reset			= drm_atomic_helper_connector_reset,
+};
+
+static int dummy_ddc_xfer(struct i2c_adapter *adapter,
+			  struct i2c_msg *msgs, int num)
+{
+	return num;
+}
+
+static u32 dummy_ddc_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm dummy_ddc_algorithm = {
+	.master_xfer = dummy_ddc_xfer,
+	.functionality = dummy_ddc_func,
+};
+
+static void i2c_del_adapter_wrapper(void *ptr)
+{
+	struct i2c_adapter *adap = ptr;
+
+	i2c_del_adapter(adap);
+}
+
+static int drm_test_connector_init(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv;
+	struct device *dev;
+	int ret;
+
+	dev = drm_kunit_helper_alloc_device(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+	priv = drm_kunit_helper_alloc_drm_device(test, dev,
+						 struct drm_connector_init_priv, drm,
+						 DRIVER_MODESET | DRIVER_ATOMIC);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+
+	strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name));
+	priv->ddc.owner = THIS_MODULE;
+	priv->ddc.algo = &dummy_ddc_algorithm;
+	priv->ddc.dev.parent = dev;
+
+	ret = i2c_add_adapter(&priv->ddc);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	test->priv = priv;
+	return 0;
+}
+
+/*
+ * Test that the registration of a bog standard connector works as
+ * expected and doesn't report any error.
+ */
+static void drm_test_drmm_connector_init(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_init(&priv->drm, &priv->connector,
+				  &dummy_funcs,
+				  DRM_MODE_CONNECTOR_HDMIA,
+				  &priv->ddc);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector without a DDC adapter
+ * doesn't report any error.
+ */
+static void drm_test_drmm_connector_init_null_ddc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_init(&priv->drm, &priv->connector,
+				  &dummy_funcs,
+				  DRM_MODE_CONNECTOR_HDMIA,
+				  NULL);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector succeeds for all possible
+ * connector types.
+ */
+static void drm_test_drmm_connector_init_type_valid(struct kunit *test)
+{
+       struct drm_connector_init_priv *priv = test->priv;
+       unsigned int connector_type = *(unsigned int *)test->param_value;
+       int ret;
+
+       ret = drmm_connector_init(&priv->drm, &priv->connector,
+				 &dummy_funcs,
+				 connector_type,
+				 &priv->ddc);
+       KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static const unsigned int drm_connector_init_type_valid_tests[] = {
+	DRM_MODE_CONNECTOR_Unknown,
+	DRM_MODE_CONNECTOR_VGA,
+	DRM_MODE_CONNECTOR_DVII,
+	DRM_MODE_CONNECTOR_DVID,
+	DRM_MODE_CONNECTOR_DVIA,
+	DRM_MODE_CONNECTOR_Composite,
+	DRM_MODE_CONNECTOR_SVIDEO,
+	DRM_MODE_CONNECTOR_LVDS,
+	DRM_MODE_CONNECTOR_Component,
+	DRM_MODE_CONNECTOR_9PinDIN,
+	DRM_MODE_CONNECTOR_DisplayPort,
+	DRM_MODE_CONNECTOR_HDMIA,
+	DRM_MODE_CONNECTOR_HDMIB,
+	DRM_MODE_CONNECTOR_TV,
+	DRM_MODE_CONNECTOR_eDP,
+	DRM_MODE_CONNECTOR_VIRTUAL,
+	DRM_MODE_CONNECTOR_DSI,
+	DRM_MODE_CONNECTOR_DPI,
+	DRM_MODE_CONNECTOR_WRITEBACK,
+	DRM_MODE_CONNECTOR_SPI,
+	DRM_MODE_CONNECTOR_USB,
+};
+
+static void drm_connector_init_type_desc(const unsigned int *type, char *desc)
+{
+	sprintf(desc, "%s", drm_get_connector_type_name(*type));
+}
+
+KUNIT_ARRAY_PARAM(drm_connector_init_type_valid,
+		  drm_connector_init_type_valid_tests,
+		  drm_connector_init_type_desc);
+
+static struct kunit_case drmm_connector_init_tests[] = {
+	KUNIT_CASE(drm_test_drmm_connector_init),
+	KUNIT_CASE(drm_test_drmm_connector_init_null_ddc),
+	KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid,
+			 drm_connector_init_type_valid_gen_params),
+	{ }
+};
+
+static struct kunit_suite drmm_connector_init_test_suite = {
+	.name = "drmm_connector_init",
+	.init = drm_test_connector_init,
+	.test_cases = drmm_connector_init_tests,
+};
+
 struct drm_get_tv_mode_from_name_test {
 	const char *name;
 	enum drm_connector_tv_mode expected_mode;
@@ -70,7 +235,10 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
 	.test_cases = drm_get_tv_mode_from_name_tests,
 };
 
-kunit_test_suite(drm_get_tv_mode_from_name_test_suite);
+kunit_test_suites(
+	&drmm_connector_init_test_suite,
+	&drm_get_tv_mode_from_name_test_suite
+);
 
 MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");
 MODULE_LICENSE("GPL");

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:49 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:49 +0100
Subject: [PATCH v6 06/36] drm/connector: Introduce an HDMI connector
 initialization function
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-6-f4bcdc979e6f@kernel.org>

A lot of the various HDMI drivers duplicate some logic that depends on
the HDMI spec itself and not really a particular hardware
implementation.

Output BPC or format selection, infoframe generation are good examples
of such areas.

This creates a lot of boilerplate, with a lot of variations, which makes
it hard for userspace to rely on, and makes it difficult to get it right
for drivers.

In the next patches, we'll add a lot of infrastructure around the
drm_connector and drm_connector_state structures, which will allow to
abstract away the duplicated logic. This infrastructure comes with a few
requirements though, and thus we need a new initialization function.

Hopefully, this will make drivers simpler to handle, and their behaviour
more consistent.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_connector.c | 39 +++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     |  5 +++++
 2 files changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b0516505f7ae..d9961cce8245 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -452,6 +452,45 @@ int drmm_connector_init(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drmm_connector_init);
 
+/**
+ * drmm_connector_hdmi_init - Init a preallocated HDMI connector
+ * @dev: DRM device
+ * @connector: A pointer to the HDMI connector to init
+ * @funcs: callbacks for this connector
+ * @connector_type: user visible type of the connector
+ * @ddc: optional pointer to the associated ddc adapter
+ *
+ * Initialises a preallocated HDMI connector. Connectors can be
+ * subclassed as part of driver connector objects.
+ *
+ * Cleanup is automatically handled with a call to
+ * drm_connector_cleanup() in a DRM-managed action.
+ *
+ * The connector structure should be allocated with drmm_kzalloc().
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_connector_hdmi_init(struct drm_device *dev,
+			     struct drm_connector *connector,
+			     const struct drm_connector_funcs *funcs,
+			     int connector_type,
+			     struct i2c_adapter *ddc)
+{
+	int ret;
+
+	if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+	      connector_type == DRM_MODE_CONNECTOR_HDMIB))
+		return -EINVAL;
+
+	ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(drmm_connector_hdmi_init);
+
 /**
  * drm_connector_attach_edid_property - attach edid property.
  * @connector: the connector
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index fe88d7fc6b8f..4491c4c2fb6e 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1904,6 +1904,11 @@ int drmm_connector_init(struct drm_device *dev,
 			const struct drm_connector_funcs *funcs,
 			int connector_type,
 			struct i2c_adapter *ddc);
+int drmm_connector_hdmi_init(struct drm_device *dev,
+			     struct drm_connector *connector,
+			     const struct drm_connector_funcs *funcs,
+			     int connector_type,
+			     struct i2c_adapter *ddc);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);
 void drm_connector_unregister(struct drm_connector *connector);

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:52 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:52 +0100
Subject: [PATCH v6 09/36] drm/connector: hdmi: Add Broadcast RGB property
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-9-f4bcdc979e6f@kernel.org>

The i915 driver has a property to force the RGB range of an HDMI output.
The vc4 driver then implemented the same property with the same
semantics. KWin has support for it, and a PR for mutter is also there to
support it.

Both drivers implementing the same property with the same semantics,
plus the userspace having support for it, is proof enough that it's
pretty much a de-facto standard now and we can provide helpers for it.

Let's plumb it into the newly created HDMI connector.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 Documentation/gpu/kms-properties.csv      |  1 -
 drivers/gpu/drm/drm_atomic.c              |  5 ++
 drivers/gpu/drm/drm_atomic_state_helper.c | 17 +++++++
 drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
 drivers/gpu/drm/drm_connector.c           | 85 +++++++++++++++++++++++++++++++
 include/drm/drm_connector.h               | 36 +++++++++++++
 6 files changed, 147 insertions(+), 1 deletion(-)

diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv
index 0f9590834829..caef14c532d4 100644
--- a/Documentation/gpu/kms-properties.csv
+++ b/Documentation/gpu/kms-properties.csv
@@ -17,7 +17,6 @@ Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,De
 ,Virtual GPU,?suggested X?,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an X offset for a connector
 ,,?suggested Y?,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an Y offset for a connector
 ,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" }",Connector,TDB
-i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normally in the range 0..1.0 are remapped to the range 16/255..235/255."
 ,,?audio?,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD
 ,SDVO-TV,?mode?,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD
 ,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index a91737adf8e7..93831850ffcd 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1143,6 +1143,11 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 	drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc);
 	drm_printf(p, "\tcolorspace=%s\n", drm_get_colorspace_name(state->colorspace));
 
+	if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)
+		drm_printf(p, "\tbroadcast_rgb=%s\n",
+			   drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb));
+
 	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
 		if (state->writeback_job && state->writeback_job->fb)
 			drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id);
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 7ad1dffe66d9..d93bc7f5faee 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -584,6 +584,7 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
 void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
 					      struct drm_connector_state *new_state)
 {
+	new_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
 
@@ -651,6 +652,22 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
 int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 					   struct drm_atomic_state *state)
 {
+	struct drm_connector_state *old_state =
+		drm_atomic_get_old_connector_state(state, connector);
+	struct drm_connector_state *new_state =
+		drm_atomic_get_new_connector_state(state, connector);
+
+	if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb) {
+		struct drm_crtc *crtc = new_state->crtc;
+		struct drm_crtc_state *crtc_state;
+
+		crtc_state = drm_atomic_get_crtc_state(state, crtc);
+		if (IS_ERR(crtc_state))
+			return PTR_ERR(crtc_state);
+
+		crtc_state->mode_changed = true;
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 29d4940188d4..2b415b4ed506 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -776,6 +776,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 		state->max_requested_bpc = val;
 	} else if (property == connector->privacy_screen_sw_state_property) {
 		state->privacy_screen_sw_state = val;
+	} else if (property == connector->broadcast_rgb_property) {
+		state->hdmi.broadcast_rgb = val;
 	} else if (connector->funcs->atomic_set_property) {
 		return connector->funcs->atomic_set_property(connector,
 				state, property, val);
@@ -859,6 +861,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->max_requested_bpc;
 	} else if (property == connector->privacy_screen_sw_state_property) {
 		*val = state->privacy_screen_sw_state;
+	} else if (property == connector->broadcast_rgb_property) {
+		*val = state->hdmi.broadcast_rgb;
 	} else if (connector->funcs->atomic_get_property) {
 		return connector->funcs->atomic_get_property(connector,
 				state, property, val);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index d9961cce8245..53abf213a045 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1183,6 +1183,29 @@ static const u32 dp_colorspaces =
 	BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) |
 	BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);
 
+static const struct drm_prop_enum_list broadcast_rgb_names[] = {
+	{ DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic" },
+	{ DRM_HDMI_BROADCAST_RGB_FULL, "Full" },
+	{ DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" },
+};
+
+/*
+ * drm_hdmi_connector_get_broadcast_rgb_name - Return a string for HDMI connector RGB broadcast selection
+ * @broadcast_rgb: Broadcast RGB selection to compute name of
+ *
+ * Returns: the name of the Broadcast RGB selection, or NULL if the type
+ * is not valid.
+ */
+const char *
+drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb)
+{
+	if (broadcast_rgb > DRM_HDMI_BROADCAST_RGB_LIMITED)
+		return NULL;
+
+	return broadcast_rgb_names[broadcast_rgb].name;
+}
+EXPORT_SYMBOL(drm_hdmi_connector_get_broadcast_rgb_name);
+
 /**
  * DOC: standard connector properties
  *
@@ -1655,6 +1678,35 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
 /**
  * DOC: HDMI connector properties
  *
+ * Broadcast RGB (HDMI specific)
+ *      Indicates the Quantization Range (Full vs Limited) used. The color
+ *      processing pipeline will be adjusted to match the value of the
+ *      property, and the Infoframes will be generated and sent accordingly.
+ *
+ *      The CRTC attached to the connector must be configured by user-space to
+ *      always produce full-range pixels.
+ *
+ *      The value of this property can be one of the following:
+ *
+ *      Automatic:
+ *              The quantization range is selected automatically based on the
+ *              mode according to the HDMI specifications (HDMI 1.4b - Section
+ *              6.6 - Video Quantization Ranges).
+ *
+ *      Full:
+ *              Full quantization range is forced.
+ *
+ *      Limited 16:235:
+ *              Limited quantization range is forced. Unlike the name suggests,
+ *              this works for any number of bits-per-component.
+ *
+ *      Property values other than Automatic can result in colors being off (if
+ *      limited is selected but the display expects full), or a black screen
+ *      (if full is selected but the display expects limited).
+ *
+ *      Drivers can set up this property by calling
+ *      drm_connector_attach_broadcast_rgb_property().
+ *
  * content type (HDMI specific):
  *	Indicates content type setting to be used in HDMI infoframes to indicate
  *	content type for the external device, so that it adjusts its display
@@ -2517,6 +2569,39 @@ int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *conn
 }
 EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property);
 
+/**
+ * drm_connector_attach_broadcast_rgb_property - attach "Broadcast RGB" property
+ * @connector: connector to attach the property on.
+ *
+ * This is used to add support for forcing the RGB range on a connector
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_property *prop;
+
+	prop = connector->broadcast_rgb_property;
+	if (!prop) {
+		prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
+						"Broadcast RGB",
+						broadcast_rgb_names,
+						ARRAY_SIZE(broadcast_rgb_names));
+		if (!prop)
+			return -EINVAL;
+
+		connector->broadcast_rgb_property = prop;
+	}
+
+	drm_object_attach_property(&connector->base, prop,
+				   DRM_HDMI_BROADCAST_RGB_AUTO);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_broadcast_rgb_property);
+
 /**
  * drm_connector_attach_colorspace_property - attach "Colorspace" property
  * @connector: connector to attach the property on.
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 000a2a156619..3867a4c01b78 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -368,6 +368,30 @@ enum drm_panel_orientation {
 	DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
 };
 
+/**
+ * enum drm_hdmi_broadcast_rgb - Broadcast RGB Selection for an HDMI @drm_connector
+ */
+enum drm_hdmi_broadcast_rgb {
+	/**
+	 * @DRM_HDMI_BROADCAST_RGB_AUTO: The RGB range is selected
+	 * automatically based on the mode.
+	 */
+	DRM_HDMI_BROADCAST_RGB_AUTO,
+
+	/**
+	 * @DRM_HDMI_BROADCAST_RGB_FULL: Full range RGB is forced.
+	 */
+	DRM_HDMI_BROADCAST_RGB_FULL,
+
+	/**
+	 * @DRM_HDMI_BROADCAST_RGB_LIMITED: Limited range RGB is forced.
+	 */
+	DRM_HDMI_BROADCAST_RGB_LIMITED,
+};
+
+const char *
+drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb);
+
 /**
  * struct drm_monitor_range_info - Panel's Monitor range in EDID for
  * &drm_display_info
@@ -1037,6 +1061,11 @@ struct drm_connector_state {
 	 * @drm_atomic_helper_connector_hdmi_check().
 	 */
 	struct {
+		/**
+		 * @broadcast_rgb: Connector property to pass the
+		 * Broadcast RGB selection value.
+		 */
+		enum drm_hdmi_broadcast_rgb broadcast_rgb;
 	} hdmi;
 };
 
@@ -1706,6 +1735,12 @@ struct drm_connector {
 	 */
 	struct drm_property *privacy_screen_hw_state_property;
 
+	/**
+	 * @broadcast_rgb_property: Connector property to set the
+	 * Broadcast RGB selection to output with.
+	 */
+	struct drm_property *broadcast_rgb_property;
+
 #define DRM_CONNECTOR_POLL_HPD (1 << 0)
 #define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
 #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
@@ -2026,6 +2061,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
 					       u32 scaling_mode_mask);
 int drm_connector_attach_vrr_capable_property(
 		struct drm_connector *connector);
+int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector);
 int drm_connector_attach_colorspace_property(struct drm_connector *connector);
 int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector);
 bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state,

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:50 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:50 +0100
Subject: [PATCH v6 07/36] drm/tests: connector: Add tests for
 drmm_connector_hdmi_init
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-7-f4bcdc979e6f@kernel.org>

We just introduced a new initialization function for our connectors, so
let's build a kunit test suite for it as well.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_connector_test.c | 123 +++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index a268847be8d1..8f070cacab3b 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -172,6 +172,128 @@ static struct kunit_suite drmm_connector_init_test_suite = {
 	.test_cases = drmm_connector_init_tests,
 };
 
+/*
+ * Test that the registration of a bog standard connector works as
+ * expected and doesn't report any error.
+ */
+static void drm_test_connector_hdmi_init_valid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector without a DDC adapter
+ * doesn't report any error.
+ */
+static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       NULL);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector with an HDMI
+ * connector type succeeds.
+ */
+static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	unsigned int connector_type = *(unsigned int *)test->param_value;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       connector_type,
+				       &priv->ddc);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = {
+	DRM_MODE_CONNECTOR_HDMIA,
+	DRM_MODE_CONNECTOR_HDMIB,
+};
+
+static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc)
+{
+	sprintf(desc, "%s", drm_get_connector_type_name(*type));
+}
+
+KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid,
+		  drm_connector_hdmi_init_type_valid_tests,
+		  drm_connector_hdmi_init_type_desc);
+
+/*
+ * Test that the registration of an HDMI connector with an !HDMI
+ * connector type fails.
+ */
+static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	unsigned int connector_type = *(unsigned int *)test->param_value;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       connector_type,
+				       &priv->ddc);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = {
+	DRM_MODE_CONNECTOR_Unknown,
+	DRM_MODE_CONNECTOR_VGA,
+	DRM_MODE_CONNECTOR_DVII,
+	DRM_MODE_CONNECTOR_DVID,
+	DRM_MODE_CONNECTOR_DVIA,
+	DRM_MODE_CONNECTOR_Composite,
+	DRM_MODE_CONNECTOR_SVIDEO,
+	DRM_MODE_CONNECTOR_LVDS,
+	DRM_MODE_CONNECTOR_Component,
+	DRM_MODE_CONNECTOR_9PinDIN,
+	DRM_MODE_CONNECTOR_DisplayPort,
+	DRM_MODE_CONNECTOR_TV,
+	DRM_MODE_CONNECTOR_eDP,
+	DRM_MODE_CONNECTOR_VIRTUAL,
+	DRM_MODE_CONNECTOR_DSI,
+	DRM_MODE_CONNECTOR_DPI,
+	DRM_MODE_CONNECTOR_WRITEBACK,
+	DRM_MODE_CONNECTOR_SPI,
+	DRM_MODE_CONNECTOR_USB,
+};
+
+KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
+		  drm_connector_hdmi_init_type_invalid_tests,
+		  drm_connector_hdmi_init_type_desc);
+
+static struct kunit_case drmm_connector_hdmi_init_tests[] = {
+	KUNIT_CASE(drm_test_connector_hdmi_init_valid),
+	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
+	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
+			 drm_connector_hdmi_init_type_valid_gen_params),
+	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,
+			 drm_connector_hdmi_init_type_invalid_gen_params),
+	{ }
+};
+
+static struct kunit_suite drmm_connector_hdmi_init_test_suite = {
+	.name = "drmm_connector_hdmi_init",
+	.init = drm_test_connector_init,
+	.test_cases = drmm_connector_hdmi_init_tests,
+};
+
 struct drm_get_tv_mode_from_name_test {
 	const char *name;
 	enum drm_connector_tv_mode expected_mode;
@@ -236,6 +358,7 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
 };
 
 kunit_test_suites(
+	&drmm_connector_hdmi_init_test_suite,
 	&drmm_connector_init_test_suite,
 	&drm_get_tv_mode_from_name_test_suite
 );

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:53 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:53 +0100
Subject: [PATCH v6 10/36] drm/tests: Add tests for Broadcast RGB property
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-10-f4bcdc979e6f@kernel.org>

This had a bunch of kunit tests to make sure our code to handle the
Broadcast RGB property behaves properly.

This requires bringing a bit of infrastructure to create mock HDMI
connectors, with custom EDIDs.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/Makefile                     |   1 +
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 376 +++++++++++++++++++++
 drivers/gpu/drm/tests/drm_connector_test.c         | 117 ++++++-
 drivers/gpu/drm/tests/drm_kunit_edid.h             | 106 ++++++
 4 files changed, 599 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile
index d6183b3d7688..b29ddfd90596 100644
--- a/drivers/gpu/drm/tests/Makefile
+++ b/drivers/gpu/drm/tests/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST_HELPERS) += \
 	drm_kunit_helpers.o
 
 obj-$(CONFIG_DRM_KUNIT_TEST) += \
+	drm_atomic_state_helper_test.o \
 	drm_buddy_test.o \
 	drm_cmdline_parser_test.o \
 	drm_connector_test.o \
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
new file mode 100644
index 000000000000..21e6f796ee13
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Kunit test for drm_atomic_state_helper functions
+ */
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_atomic_uapi.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_kunit_helpers.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_probe_helper.h>
+
+#include <drm/drm_print.h>
+#include "../drm_crtc_internal.h"
+
+#include <kunit/test.h>
+
+#include "drm_kunit_edid.h"
+
+struct drm_atomic_helper_connector_hdmi_priv {
+	struct drm_device drm;
+	struct drm_plane *plane;
+	struct drm_crtc *crtc;
+	struct drm_encoder encoder;
+	struct drm_connector connector;
+
+	const char *current_edid;
+	size_t current_edid_len;
+};
+
+#define connector_to_priv(c) \
+	container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector)
+
+static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector)
+{
+	struct drm_device *drm = connector->dev;
+	struct drm_display_mode *mode, *preferred;
+
+	mutex_lock(&drm->mode_config.mutex);
+	preferred = list_first_entry(&connector->modes, struct drm_display_mode, head);
+	list_for_each_entry(mode, &connector->modes, head)
+		if (mode->type & DRM_MODE_TYPE_PREFERRED)
+			preferred = mode;
+	mutex_unlock(&drm->mode_config.mutex);
+
+	return preferred;
+}
+
+static int light_up_connector(struct kunit *test,
+			      struct drm_device *drm,
+			      struct drm_crtc *crtc,
+			      struct drm_connector *connector,
+			      struct drm_display_mode *mode,
+			      struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_atomic_state *state;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc_state *crtc_state;
+	int ret;
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, connector);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+	ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	crtc_state->enable = true;
+	crtc_state->active = true;
+
+	ret = drm_atomic_commit(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	return 0;
+}
+
+static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
+			      const char *edid, size_t edid_len)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv =
+		connector_to_priv(connector);
+	struct drm_device *drm = connector->dev;
+	int ret;
+
+	priv->current_edid = edid;
+	priv->current_edid_len = edid_len;
+
+	mutex_lock(&drm->mode_config.mutex);
+	ret = connector->funcs->fill_modes(connector, 4096, 4096);
+	mutex_unlock(&drm->mode_config.mutex);
+	KUNIT_ASSERT_GT(test, ret, 0);
+
+	return 0;
+}
+
+static int dummy_connector_get_modes(struct drm_connector *connector)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv =
+		connector_to_priv(connector);
+	const struct drm_edid *edid;
+	unsigned int num_modes;
+
+	edid = drm_edid_alloc(priv->current_edid, priv->current_edid_len);
+	if (!edid)
+		return -EINVAL;
+
+	drm_edid_connector_update(connector, edid);
+	num_modes = drm_edid_connector_add_modes(connector);
+
+	drm_edid_free(edid);
+
+	return num_modes;
+}
+
+static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = {
+	.atomic_check	= drm_atomic_helper_connector_hdmi_check,
+	.get_modes	= dummy_connector_get_modes,
+};
+
+static void dummy_hdmi_connector_reset(struct drm_connector *connector)
+{
+	drm_atomic_helper_connector_reset(connector);
+	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
+}
+
+static const struct drm_connector_funcs dummy_connector_funcs = {
+	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
+	.fill_modes		= drm_helper_probe_single_connector_modes,
+	.reset			= dummy_hdmi_connector_reset,
+};
+
+static
+struct drm_atomic_helper_connector_hdmi_priv *
+drm_atomic_helper_connector_hdmi_init(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector *conn;
+	struct drm_encoder *enc;
+	struct drm_device *drm;
+	struct device *dev;
+	int ret;
+
+	dev = drm_kunit_helper_alloc_device(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+	priv = drm_kunit_helper_alloc_drm_device(test, dev,
+						 struct drm_atomic_helper_connector_hdmi_priv, drm,
+						 DRIVER_MODESET | DRIVER_ATOMIC);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+	test->priv = priv;
+
+	drm = &priv->drm;
+	priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
+							    NULL,
+							    NULL,
+							    NULL, 0,
+							    NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->plane);
+
+	priv->crtc = drm_kunit_helper_create_crtc(test, drm,
+						  priv->plane, NULL,
+						  NULL,
+						  NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->crtc);
+
+	enc = &priv->encoder;
+	ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	enc->possible_crtcs = drm_crtc_mask(priv->crtc);
+
+	conn = &priv->connector;
+	ret = drmm_connector_hdmi_init(drm, conn,
+				       &dummy_connector_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       NULL);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	drm_connector_helper_add(conn, &dummy_connector_helper_funcs);
+	drm_connector_attach_encoder(conn, enc);
+
+	drm_mode_config_reset(drm);
+
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	return priv;
+}
+
+/*
+ * Test that if we change the RGB quantization property to a different
+ * value, we trigger a mode change on the connector's CRTC, which will
+ * in turn disable/enable the connector.
+ */
+static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector_state *new_conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	conn = &priv->connector;
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	new_conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+	KUNIT_ASSERT_NE(test,
+			old_conn_state->hdmi.broadcast_rgb,
+			new_conn_state->hdmi.broadcast_rgb);
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+	KUNIT_EXPECT_EQ(test, new_conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_FULL);
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+	KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
+}
+
+/*
+ * Test that if we set the RGB quantization property to the same value,
+ * we don't trigger a mode change on the connector's CRTC and leave the
+ * connector unaffected.
+ */
+static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector_state *new_conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	conn = &priv->connector;
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	new_conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state->hdmi.broadcast_rgb = old_conn_state->hdmi.broadcast_rgb;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	KUNIT_EXPECT_EQ(test,
+			old_conn_state->hdmi.broadcast_rgb,
+			new_conn_state->hdmi.broadcast_rgb);
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
+}
+
+static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
+	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
+	{ }
+};
+
+static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = {
+	.name		= "drm_atomic_helper_connector_hdmi_check",
+	.test_cases	= drm_atomic_helper_connector_hdmi_check_tests,
+};
+
+/*
+ * Test that the value of the Broadcast RGB property out of reset is set
+ * to auto.
+ */
+static void drm_test_check_broadcast_rgb_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO);
+}
+
+static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
+	KUNIT_CASE(drm_test_check_broadcast_rgb_value),
+	{ }
+};
+
+static struct kunit_suite drm_atomic_helper_connector_hdmi_reset_test_suite = {
+	.name		= "drm_atomic_helper_connector_hdmi_reset",
+	.test_cases 	= drm_atomic_helper_connector_hdmi_reset_tests,
+};
+
+kunit_test_suites(
+	&drm_atomic_helper_connector_hdmi_check_test_suite,
+	&drm_atomic_helper_connector_hdmi_reset_test_suite,
+);
+
+MODULE_AUTHOR("Maxime Ripard <mripard at kernel.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 8f070cacab3b..41d33dea30af 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -12,6 +12,8 @@
 
 #include <kunit/test.h>
 
+#include "../drm_crtc_internal.h"
+
 struct drm_connector_init_priv {
 	struct drm_device drm;
 	struct drm_connector connector;
@@ -357,10 +359,123 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
 	.test_cases = drm_get_tv_mode_from_name_tests,
 };
 
+struct drm_hdmi_connector_get_broadcast_rgb_name_test {
+	unsigned int kind;
+	const char *expected_name;
+};
+
+#define BROADCAST_RGB_TEST(_kind, _name)	\
+	{					\
+		.kind = _kind,			\
+		.expected_name = _name,		\
+	}
+
+static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test)
+{
+	const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params =
+		test->param_value;
+
+	KUNIT_EXPECT_STREQ(test,
+			   drm_hdmi_connector_get_broadcast_rgb_name(params->kind),
+			   params->expected_name);
+}
+
+static const
+struct drm_hdmi_connector_get_broadcast_rgb_name_test
+drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = {
+	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"),
+	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"),
+	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"),
+};
+
+static void
+drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t,
+						     char *desc)
+{
+	sprintf(desc, "%s", t->expected_name);
+}
+
+KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid,
+		  drm_hdmi_connector_get_broadcast_rgb_name_valid_tests,
+		  drm_hdmi_connector_get_broadcast_rgb_name_valid_desc);
+
+static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test)
+{
+	KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3));
+};
+
+static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = {
+	KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name,
+			 drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params),
+	KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid),
+	{ }
+};
+
+static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = {
+	.name = "drm_hdmi_connector_get_broadcast_rgb_name",
+	.test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests,
+};
+
+static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	struct drm_connector *connector = &priv->connector;
+	struct drm_property *prop;
+	int ret;
+
+	ret = drmm_connector_init(&priv->drm, connector,
+				  &dummy_funcs,
+				  DRM_MODE_CONNECTOR_HDMIA,
+				  &priv->ddc);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = drm_connector_attach_broadcast_rgb_property(connector);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	prop = connector->broadcast_rgb_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	struct drm_connector *connector = &priv->connector;
+	struct drm_property *prop;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	ret = drm_connector_attach_broadcast_rgb_property(connector);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	prop = connector->broadcast_rgb_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = {
+	KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property),
+	KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector),
+	{ }
+};
+
+static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = {
+	.name = "drm_connector_attach_broadcast_rgb_property",
+	.init = drm_test_connector_init,
+	.test_cases = drm_connector_attach_broadcast_rgb_property_tests,
+};
+
 kunit_test_suites(
 	&drmm_connector_hdmi_init_test_suite,
 	&drmm_connector_init_test_suite,
-	&drm_get_tv_mode_from_name_test_suite
+	&drm_connector_attach_broadcast_rgb_property_test_suite,
+	&drm_get_tv_mode_from_name_test_suite,
+	&drm_hdmi_connector_get_broadcast_rgb_name_test_suite
 );
 
 MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");
diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h
new file mode 100644
index 000000000000..2bba316de064
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_kunit_edid.h
@@ -0,0 +1,106 @@
+#ifndef DRM_KUNIT_EDID_H_
+#define DRM_KUNIT_EDID_H_
+
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92
+ *
+ * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c
+ * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ *   EDID Structure Version & Revision: 1.3
+ *   Vendor & Product Identification:
+ *     Manufacturer: LNX
+ *     Model: 42
+ *     Made in: 2023
+ *   Basic Display Parameters & Features:
+ *     Digital display
+ *     DFP 1.x compatible TMDS
+ *     Maximum image size: 160 cm x 90 cm
+ *     Gamma: 2.20
+ *     Monochrome or grayscale display
+ *     First detailed timing is the preferred timing
+ *   Color Characteristics:
+ *     Red  : 0.0000, 0.0000
+ *     Green: 0.0000, 0.0000
+ *     Blue : 0.0000, 0.0000
+ *     White: 0.0000, 0.0000
+ *   Established Timings I & II:
+ *     DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
+ *   Standard Timings: none
+ *   Detailed Timing Descriptors:
+ *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (1600 mm x 900 mm)
+ *                  Hfront   88 Hsync  44 Hback  148 Hpol P
+ *                  Vfront    4 Vsync   5 Vback   36 Vpol P
+ *     Display Product Name: 'Test EDID'
+ *     Display Range Limits:
+ *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ *     Dummy Descriptor:
+ *   Extension blocks: 1
+ * Checksum: 0x92
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ *   Revision: 3
+ *   Underscans IT Video Formats by default
+ *   Native detailed modes: 1
+ *   Colorimetry Data Block:
+ *     sRGB
+ *   Video Data Block:
+ *     VIC  16:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz
+ *   Video Capability Data Block:
+ *     YCbCr quantization: No Data
+ *     RGB quantization: Selectable (via AVI Q)
+ *     PT scan behavior: No Data
+ *     IT scan behavior: Always Underscanned
+ *     CE scan behavior: Always Underscanned
+ *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ *     Source physical address: 1.2.3.4
+ *     Maximum TMDS clock: 200 MHz
+ *     Extended HDMI video details:
+ * Checksum: 0xd0  Unused space in Extension Block: 100 bytes
+ */
+const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+  0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+  0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+  0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81,
+  0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c,
+  0x00, 0x12, 0x34, 0x00, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xd0
+};
+
+#endif // DRM_KUNIT_EDID_H_

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:54 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:54 +0100
Subject: [PATCH v6 11/36] drm/connector: hdmi: Add RGB Quantization Range
 to the connector state
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-11-f4bcdc979e6f@kernel.org>

HDMI controller drivers will need to figure out the RGB range they need
to configure based on a mode and property values. Let's expose that in
the HDMI connector state so drivers can just use that value.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic.c              |  4 ++-
 drivers/gpu/drm/drm_atomic_state_helper.c | 44 +++++++++++++++++++++++++++++++
 include/drm/drm_connector.h               |  6 +++++
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 93831850ffcd..0c283964cee0 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1144,9 +1144,11 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 	drm_printf(p, "\tcolorspace=%s\n", drm_get_colorspace_name(state->colorspace));
 
 	if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
-	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)
+	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
 		drm_printf(p, "\tbroadcast_rgb=%s\n",
 			   drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb));
+		drm_printf(p, "\tis_full_range=%c\n", state->hdmi.is_full_range ? 'y' : 'n');
+	}
 
 	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
 		if (state->writeback_job && state->writeback_job->fb)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index d93bc7f5faee..08db9956840b 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -31,6 +31,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_device.h>
+#include <drm/drm_edid.h>
 #include <drm/drm_framebuffer.h>
 #include <drm/drm_plane.h>
 #include <drm/drm_print.h>
@@ -637,6 +638,47 @@ int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
 
+static const struct drm_display_mode *
+connector_state_get_mode(const struct drm_connector_state *conn_state)
+{
+	struct drm_atomic_state *state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+
+	state = conn_state->state;
+	if (!state)
+		return NULL;
+
+	crtc = conn_state->crtc;
+	if (!crtc)
+		return NULL;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	if (!crtc_state)
+		return NULL;
+
+	return &crtc_state->mode;
+}
+
+static bool hdmi_is_full_range(const struct drm_connector *connector,
+			       const struct drm_connector_state *state)
+{
+	const struct drm_display_info *display = &connector->display_info;
+	const struct drm_display_mode *mode =
+		connector_state_get_mode(state);
+
+	if (state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_FULL)
+		return true;
+
+	if (state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED)
+		return false;
+
+	if (!display->is_hdmi)
+		return true;
+
+	return drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL ? true : false;
+}
+
 /**
  * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
  * @connector: DRM Connector
@@ -657,6 +699,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 	struct drm_connector_state *new_state =
 		drm_atomic_get_new_connector_state(state, connector);
 
+	new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state);
+
 	if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb) {
 		struct drm_crtc *crtc = new_state->crtc;
 		struct drm_crtc_state *crtc_state;
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 3867a4c01b78..76eecd449fb8 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1066,6 +1066,12 @@ struct drm_connector_state {
 		 * Broadcast RGB selection value.
 		 */
 		enum drm_hdmi_broadcast_rgb broadcast_rgb;
+
+		/**
+		 * @is_full_range: Is the output supposed to use a full
+		 * RGB Quantization Range or not?
+		 */
+		bool is_full_range;
 	} hdmi;
 };
 

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:55 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:55 +0100
Subject: [PATCH v6 12/36] drm/tests: Add RGB Quantization tests
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-12-f4bcdc979e6f@kernel.org>

The previous commit added the infrastructure to the connector state to
track what RGB Quantization should be used in a given state for an HDMI
connector.

Let's add some kunit tests to make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 335 +++++++++++++++++++++
 1 file changed, 335 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 21e6f796ee13..7750c3d214a4 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -328,7 +328,342 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes
 	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 }
 
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to auto with a mode that isn't the
+ * VIC-1 mode, we will get a limited RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_AUTO);
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to auto with a VIC-1 mode, we will get
+ * a full RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *mode;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_AUTO);
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to full with a mode that isn't the
+ * VIC-1 mode, we will get a full RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_FULL);
+
+	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to full with a VIC-1 mode, we will get
+ * a full RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *mode;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_FULL);
+
+	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to limited with a mode that isn't the
+ * VIC-1 mode, we will get a limited RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_LIMITED);
+
+	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to limited with a VIC-1 mode, we will
+ * get a limited RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *mode;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_LIMITED);
+
+	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
+	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
 	{ }

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:57 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:57 +0100
Subject: [PATCH v6 14/36] drm/tests: Add output bpc tests
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-14-f4bcdc979e6f@kernel.org>

Now that we're tracking the output bpc count in the connector state,
let's add a few tests to make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 203 +++++++++++++++++++++
 drivers/gpu/drm/tests/drm_connector_test.c         | 138 ++++++++++++++
 2 files changed, 341 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 64ba1f6256ba..a1b0e6914cf8 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -659,6 +659,138 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te
 	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
 }
 
+/*
+ * Test that if we change the maximum bpc property to a different value,
+ * we trigger a mode change on the connector's CRTC, which will in turn
+ * disable/enable the connector.
+ */
+static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector_state *new_conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	conn = &priv->connector;
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	new_conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state->hdmi.output_bpc = 8;
+
+	KUNIT_ASSERT_NE(test,
+			old_conn_state->hdmi.output_bpc,
+			new_conn_state->hdmi.output_bpc);
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	KUNIT_ASSERT_NE(test,
+			old_conn_state->hdmi.output_bpc,
+			new_conn_state->hdmi.output_bpc);
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+	KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
+}
+
+/*
+ * Test that if we set the output bpc property to the same value, we
+ * don't trigger a mode change on the connector's CRTC and leave the
+ * connector unaffected.
+ */
+static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector_state *new_conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	conn = &priv->connector;
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	new_conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			new_conn_state->hdmi.output_bpc,
+			old_conn_state->hdmi.output_bpc);
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	KUNIT_EXPECT_EQ(test,
+			old_conn_state->hdmi.output_bpc,
+			new_conn_state->hdmi.output_bpc);
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
@@ -668,6 +800,8 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
+	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
+	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
 	{ }
 };
 
@@ -694,8 +828,77 @@ static void drm_test_check_broadcast_rgb_value(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO);
 }
 
+/*
+ * Test that if the connector was initialised with a maximum bpc of 8,
+ * the value of the max_bpc and max_requested_bpc properties out of
+ * reset are also set to 8, and output_bpc is set to 0 and will be
+ * filled at atomic_check time.
+ */
+static void drm_test_check_bpc_8_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
+}
+
+/*
+ * Test that if the connector was initialised with a maximum bpc of 10,
+ * the value of the max_bpc and max_requested_bpc properties out of
+ * reset are also set to 10, and output_bpc is set to 0 and will be
+ * filled at atomic_check time.
+ */
+static void drm_test_check_bpc_10_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 10);
+	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 10);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
+}
+
+/*
+ * Test that if the connector was initialised with a maximum bpc of 12,
+ * the value of the max_bpc and max_requested_bpc properties out of
+ * reset are also set to 12, and output_bpc is set to 0 and will be
+ * filled at atomic_check time.
+ */
+static void drm_test_check_bpc_12_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test, 12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 12);
+	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 12);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_value),
+	KUNIT_CASE(drm_test_check_bpc_8_value),
+	KUNIT_CASE(drm_test_check_bpc_10_value),
+	KUNIT_CASE(drm_test_check_bpc_12_value),
 	{ }
 };
 
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 96b19a5954b4..fef7d53d34d4 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -208,6 +208,139 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
+/*
+ * Test that the registration of a connector with an invalid maximum bpc
+ * count fails.
+ */
+static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       9);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a null maximum bpc
+ * count fails.
+ */
+static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       0);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a maximum bpc count of
+ * 8 succeeds, registers the max bpc property, but doesn't register the
+ * HDR output metadata one.
+ */
+static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	struct drm_connector *connector = &priv->connector;
+	struct drm_property *prop;
+	uint64_t val;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	prop = connector->max_bpc_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+
+	ret = drm_object_property_get_value(&connector->base, prop, &val);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, val, 8);
+
+	prop = priv->drm.mode_config.hdr_output_metadata_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+/*
+ * Test that the registration of a connector with a maximum bpc count of
+ * 10 succeeds and registers the max bpc and HDR output metadata
+ * properties.
+ */
+static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	struct drm_connector *connector = &priv->connector;
+	struct drm_property *prop;
+	uint64_t val;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       10);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	prop = connector->max_bpc_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+
+	ret = drm_object_property_get_value(&connector->base, prop, &val);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, val, 10);
+
+	prop = priv->drm.mode_config.hdr_output_metadata_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+/*
+ * Test that the registration of a connector with a maximum bpc count of
+ * 12 succeeds and registers the max bpc and HDR output metadata
+ * properties.
+ */
+static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	struct drm_connector *connector = &priv->connector;
+	struct drm_property *prop;
+	uint64_t val;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       12);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	prop = connector->max_bpc_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+
+	ret = drm_object_property_get_value(&connector->base, prop, &val);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, val, 12);
+
+	prop = priv->drm.mode_config.hdr_output_metadata_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
 /*
  * Test that the registration of an HDMI connector with an HDMI
  * connector type succeeds.
@@ -286,6 +419,11 @@ KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
 
 static struct kunit_case drmm_connector_hdmi_init_tests[] = {
 	KUNIT_CASE(drm_test_connector_hdmi_init_valid),
+	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8),
+	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10),
+	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12),
+	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid),
+	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null),
 	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
 			 drm_connector_hdmi_init_type_valid_gen_params),

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:56 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:56 +0100
Subject: [PATCH v6 13/36] drm/connector: hdmi: Add output BPC to the
 connector state
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-13-f4bcdc979e6f@kernel.org>

We'll add automatic selection of the output BPC in a following patch,
but let's add it to the HDMI connector state already.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic.c                       |  1 +
 drivers/gpu/drm/drm_atomic_state_helper.c          |  7 ++++++-
 drivers/gpu/drm/drm_connector.c                    | 20 +++++++++++++++++-
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 24 ++++++++++++----------
 drivers/gpu/drm/tests/drm_connector_test.c         | 15 +++++++++-----
 include/drm/drm_connector.h                        | 13 +++++++++++-
 6 files changed, 61 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 0c283964cee0..5fcdab90c793 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1148,6 +1148,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 		drm_printf(p, "\tbroadcast_rgb=%s\n",
 			   drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb));
 		drm_printf(p, "\tis_full_range=%c\n", state->hdmi.is_full_range ? 'y' : 'n');
+		drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
 	}
 
 	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 08db9956840b..2025d053e54f 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -585,6 +585,10 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
 void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
 					      struct drm_connector_state *new_state)
 {
+	unsigned int max_bpc = connector->max_bpc;
+
+	new_state->max_bpc = max_bpc;
+	new_state->max_requested_bpc = max_bpc;
 	new_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
@@ -701,7 +705,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 
 	new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state);
 
-	if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb) {
+	if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb ||
+	    old_state->hdmi.output_bpc != new_state->hdmi.output_bpc) {
 		struct drm_crtc *crtc = new_state->crtc;
 		struct drm_crtc_state *crtc_state;
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 53abf213a045..ca39fd027e20 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -459,6 +459,7 @@ EXPORT_SYMBOL(drmm_connector_init);
  * @funcs: callbacks for this connector
  * @connector_type: user visible type of the connector
  * @ddc: optional pointer to the associated ddc adapter
+ * @max_bpc: Maximum bits per char the HDMI connector supports
  *
  * Initialises a preallocated HDMI connector. Connectors can be
  * subclassed as part of driver connector objects.
@@ -475,7 +476,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
 			     const struct drm_connector_funcs *funcs,
 			     int connector_type,
-			     struct i2c_adapter *ddc)
+			     struct i2c_adapter *ddc,
+			     unsigned int max_bpc)
 {
 	int ret;
 
@@ -483,10 +485,26 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 	      connector_type == DRM_MODE_CONNECTOR_HDMIB))
 		return -EINVAL;
 
+	if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12))
+		return -EINVAL;
+
 	ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);
 	if (ret)
 		return ret;
 
+	/*
+	 * drm_connector_attach_max_bpc_property() requires the
+	 * connector to have a state.
+	 */
+	if (connector->funcs->reset)
+		connector->funcs->reset(connector);
+
+	drm_connector_attach_max_bpc_property(connector, 8, max_bpc);
+	connector->max_bpc = max_bpc;
+
+	if (max_bpc > 8)
+		drm_connector_attach_hdr_output_metadata_property(connector);
+
 	return 0;
 }
 EXPORT_SYMBOL(drmm_connector_hdmi_init);
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 7750c3d214a4..64ba1f6256ba 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -146,7 +146,8 @@ static const struct drm_connector_funcs dummy_connector_funcs = {
 
 static
 struct drm_atomic_helper_connector_hdmi_priv *
-drm_atomic_helper_connector_hdmi_init(struct kunit *test)
+drm_atomic_helper_connector_hdmi_init(struct kunit *test,
+				      unsigned int max_bpc)
 {
 	struct drm_atomic_helper_connector_hdmi_priv *priv;
 	struct drm_connector *conn;
@@ -188,7 +189,8 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test)
 	ret = drmm_connector_hdmi_init(drm, conn,
 				       &dummy_connector_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
-				       NULL);
+				       NULL,
+				       max_bpc);
 	KUNIT_ASSERT_EQ(test, ret, 0);
 
 	drm_connector_helper_add(conn, &dummy_connector_helper_funcs);
@@ -223,7 +225,7 @@ static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test);
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
@@ -284,7 +286,7 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test);
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
@@ -345,7 +347,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test);
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -399,7 +401,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test);
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -452,7 +454,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test);
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -508,7 +510,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test);
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -563,7 +565,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test);
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -619,7 +621,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test);
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -684,7 +686,7 @@ static void drm_test_check_broadcast_rgb_value(struct kunit *test)
 	struct drm_connector_state *conn_state;
 	struct drm_connector *conn;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test);
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 41d33dea30af..96b19a5954b4 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -186,7 +186,8 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test)
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
-				       &priv->ddc);
+				       &priv->ddc,
+				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
@@ -202,7 +203,8 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
-				       NULL);
+				       NULL,
+				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
@@ -219,7 +221,8 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
 				       connector_type,
-				       &priv->ddc);
+				       &priv->ddc,
+				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
@@ -250,7 +253,8 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
 				       connector_type,
-				       &priv->ddc);
+				       &priv->ddc,
+				       8);
 	KUNIT_EXPECT_LT(test, ret, 0);
 }
 
@@ -447,7 +451,8 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
-				       &priv->ddc);
+				       &priv->ddc,
+				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
 	ret = drm_connector_attach_broadcast_rgb_property(connector);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 76eecd449fb8..1b1b6aed04ee 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1072,6 +1072,11 @@ struct drm_connector_state {
 		 * RGB Quantization Range or not?
 		 */
 		bool is_full_range;
+
+		/**
+		 * @output_bpc: Bits per color channel to output.
+		 */
+		unsigned int output_bpc;
 	} hdmi;
 };
 
@@ -1717,6 +1722,11 @@ struct drm_connector {
 	 */
 	struct drm_property_blob *path_blob_ptr;
 
+	/**
+	 * @max_bpc: Maximum bits per color channel the connector supports.
+	 */
+	unsigned int max_bpc;
+
 	/**
 	 * @max_bpc_property: Default connector property for the max bpc to be
 	 * driven out of the connector.
@@ -1956,7 +1966,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
 			     const struct drm_connector_funcs *funcs,
 			     int connector_type,
-			     struct i2c_adapter *ddc);
+			     struct i2c_adapter *ddc,
+			     unsigned int max_bpc);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);
 void drm_connector_unregister(struct drm_connector *connector);

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:59 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:59 +0100
Subject: [PATCH v6 16/36] drm/tests: Add output formats tests
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-16-f4bcdc979e6f@kernel.org>

Now that we track the HDMI output format as part of the connector state,
let's add a few tests to make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 32 +++++++
 drivers/gpu/drm/tests/drm_connector_test.c         | 99 +++++++++++++++++++++-
 2 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index a5cba3e63f99..4e2ec436987b 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -824,6 +824,15 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
+	/*
+	 * TODO: We should have tests to check that a change in the
+	 * format triggers a CRTC mode change just like we do for the
+	 * RGB Quantization and BPC.
+	 *
+	 * However, we don't have any way to control which format gets
+	 * picked up aside from changing the BPC or mode which would
+	 * already trigger a mode change.
+	 */
 	{ }
 };
 
@@ -924,11 +933,34 @@ static void drm_test_check_bpc_12_value(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
 }
 
+/*
+ * Test that the value of the output format property out of reset is set
+ * to RGB, even if the driver supports more than that.
+ */
+static void drm_test_check_format_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_value),
 	KUNIT_CASE(drm_test_check_bpc_8_value),
 	KUNIT_CASE(drm_test_check_bpc_10_value),
 	KUNIT_CASE(drm_test_check_bpc_12_value),
+	KUNIT_CASE(drm_test_check_format_value),
 	{ }
 };
 
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 9c5ce7e81d01..fa6fe8084107 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -348,6 +348,42 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
 }
 
+/*
+ * Test that the registration of an HDMI connector with no supported
+ * format fails.
+ */
+static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       0,
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector not listing RGB as a
+ * supported format fails.
+ */
+static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_YUV422),
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
 /*
  * Test that the registration of an HDMI connector with an HDMI
  * connector type succeeds.
@@ -433,6 +469,8 @@ static struct kunit_case drmm_connector_hdmi_init_tests[] = {
 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12),
 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid),
 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null),
+	KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty),
+	KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb),
 	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
 			 drm_connector_hdmi_init_type_valid_gen_params),
@@ -567,6 +605,64 @@ static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite =
 	.test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests,
 };
 
+struct drm_hdmi_connector_get_output_format_name_test {
+	unsigned int kind;
+	const char *expected_name;
+};
+
+#define OUTPUT_FORMAT_TEST(_kind, _name)	\
+	{					\
+		.kind = _kind,			\
+		.expected_name = _name,		\
+	}
+
+static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test)
+{
+	const struct drm_hdmi_connector_get_output_format_name_test *params =
+		test->param_value;
+
+	KUNIT_EXPECT_STREQ(test,
+			   drm_hdmi_connector_get_output_format_name(params->kind),
+			   params->expected_name);
+}
+
+static const
+struct drm_hdmi_connector_get_output_format_name_test
+drm_hdmi_connector_get_output_format_name_valid_tests[] = {
+	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"),
+	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"),
+	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"),
+	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"),
+};
+
+static void
+drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t,
+						     char *desc)
+{
+	sprintf(desc, "%s", t->expected_name);
+}
+
+KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid,
+		  drm_hdmi_connector_get_output_format_name_valid_tests,
+		  drm_hdmi_connector_get_output_format_name_valid_desc);
+
+static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test)
+{
+	KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4));
+};
+
+static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = {
+	KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name,
+			 drm_hdmi_connector_get_output_format_name_valid_gen_params),
+	KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid),
+	{ }
+};
+
+static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = {
+	.name = "drm_hdmi_connector_get_output_format_name",
+	.test_cases = drm_hdmi_connector_get_output_format_name_tests,
+};
+
 static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test)
 {
 	struct drm_connector_init_priv *priv = test->priv;
@@ -628,7 +724,8 @@ kunit_test_suites(
 	&drmm_connector_init_test_suite,
 	&drm_connector_attach_broadcast_rgb_property_test_suite,
 	&drm_get_tv_mode_from_name_test_suite,
-	&drm_hdmi_connector_get_broadcast_rgb_name_test_suite
+	&drm_hdmi_connector_get_broadcast_rgb_name_test_suite,
+	&drm_hdmi_connector_get_output_format_name_test_suite
 );
 
 MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:58 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:58 +0100
Subject: [PATCH v6 15/36] drm/connector: hdmi: Add support for output
 format
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-15-f4bcdc979e6f@kernel.org>

Just like BPC, we'll add support for automatic selection of the output
format for HDMI connectors.

Let's add the needed defaults and fields for now.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic.c                       |  2 +
 drivers/gpu/drm/drm_atomic_state_helper.c          |  3 +-
 drivers/gpu/drm/drm_connector.c                    | 31 ++++++++++++
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 58 ++++++++++++++++------
 drivers/gpu/drm/tests/drm_connector_test.c         | 10 ++++
 include/drm/drm_connector.h                        | 19 +++++++
 6 files changed, 108 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5fcdab90c793..47fd2a7ca9e1 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1149,6 +1149,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 			   drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb));
 		drm_printf(p, "\tis_full_range=%c\n", state->hdmi.is_full_range ? 'y' : 'n');
 		drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
+		drm_printf(p, "\toutput_format=%s\n",
+			   drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
 	}
 
 	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 2025d053e54f..34aee5232974 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -706,7 +706,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 	new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state);
 
 	if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb ||
-	    old_state->hdmi.output_bpc != new_state->hdmi.output_bpc) {
+	    old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
+	    old_state->hdmi.output_format != new_state->hdmi.output_format) {
 		struct drm_crtc *crtc = new_state->crtc;
 		struct drm_crtc_state *crtc_state;
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index ca39fd027e20..b895bea667f7 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -459,6 +459,7 @@ EXPORT_SYMBOL(drmm_connector_init);
  * @funcs: callbacks for this connector
  * @connector_type: user visible type of the connector
  * @ddc: optional pointer to the associated ddc adapter
+ * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats
  * @max_bpc: Maximum bits per char the HDMI connector supports
  *
  * Initialises a preallocated HDMI connector. Connectors can be
@@ -477,6 +478,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     const struct drm_connector_funcs *funcs,
 			     int connector_type,
 			     struct i2c_adapter *ddc,
+			     unsigned long supported_formats,
 			     unsigned int max_bpc)
 {
 	int ret;
@@ -485,6 +487,9 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 	      connector_type == DRM_MODE_CONNECTOR_HDMIB))
 		return -EINVAL;
 
+	if (!supported_formats || !(supported_formats & BIT(HDMI_COLORSPACE_RGB)))
+		return -EINVAL;
+
 	if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12))
 		return -EINVAL;
 
@@ -492,6 +497,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 	if (ret)
 		return ret;
 
+	connector->hdmi.supported_formats = supported_formats;
+
 	/*
 	 * drm_connector_attach_max_bpc_property() requires the
 	 * connector to have a state.
@@ -1224,6 +1231,30 @@ drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_
 }
 EXPORT_SYMBOL(drm_hdmi_connector_get_broadcast_rgb_name);
 
+static const char * const output_format_str[] = {
+	[HDMI_COLORSPACE_RGB]		= "RGB",
+	[HDMI_COLORSPACE_YUV420]	= "YUV 4:2:0",
+	[HDMI_COLORSPACE_YUV422]	= "YUV 4:2:2",
+	[HDMI_COLORSPACE_YUV444]	= "YUV 4:4:4",
+};
+
+/*
+ * drm_hdmi_connector_get_output_format_name() - Return a string for HDMI connector output format
+ * @fmt: Output format to compute name of
+ *
+ * Returns: the name of the output format, or NULL if the type is not
+ * valid.
+ */
+const char *
+drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt)
+{
+	if (fmt >= ARRAY_SIZE(output_format_str))
+		return NULL;
+
+	return output_format_str[fmt];
+}
+EXPORT_SYMBOL(drm_hdmi_connector_get_output_format_name);
+
 /**
  * DOC: standard connector properties
  *
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index a1b0e6914cf8..a5cba3e63f99 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -147,6 +147,7 @@ static const struct drm_connector_funcs dummy_connector_funcs = {
 static
 struct drm_atomic_helper_connector_hdmi_priv *
 drm_atomic_helper_connector_hdmi_init(struct kunit *test,
+				      unsigned int formats,
 				      unsigned int max_bpc)
 {
 	struct drm_atomic_helper_connector_hdmi_priv *priv;
@@ -190,6 +191,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test,
 				       &dummy_connector_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       NULL,
+				       formats,
 				       max_bpc);
 	KUNIT_ASSERT_EQ(test, ret, 0);
 
@@ -225,7 +227,9 @@ static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
@@ -286,7 +290,9 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
@@ -347,7 +353,9 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -401,7 +409,9 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -454,7 +464,9 @@ static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -510,7 +522,9 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -565,7 +579,9 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -621,7 +637,9 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -678,7 +696,9 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     10);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
@@ -745,7 +765,9 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     10);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
@@ -820,7 +842,9 @@ static void drm_test_check_broadcast_rgb_value(struct kunit *test)
 	struct drm_connector_state *conn_state;
 	struct drm_connector *conn;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -840,7 +864,9 @@ static void drm_test_check_bpc_8_value(struct kunit *test)
 	struct drm_connector_state *conn_state;
 	struct drm_connector *conn;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -862,7 +888,9 @@ static void drm_test_check_bpc_10_value(struct kunit *test)
 	struct drm_connector_state *conn_state;
 	struct drm_connector *conn;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     10);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -884,7 +912,9 @@ static void drm_test_check_bpc_12_value(struct kunit *test)
 	struct drm_connector_state *conn_state;
 	struct drm_connector *conn;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 12);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     12);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index fef7d53d34d4..9c5ce7e81d01 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -187,6 +187,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
@@ -204,6 +205,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       NULL,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
@@ -221,6 +223,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       9);
 	KUNIT_EXPECT_LT(test, ret, 0);
 }
@@ -238,6 +241,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       0);
 	KUNIT_EXPECT_LT(test, ret, 0);
 }
@@ -259,6 +263,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
@@ -292,6 +297,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       10);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
@@ -325,6 +331,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       12);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
@@ -355,6 +362,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
 				       &dummy_funcs,
 				       connector_type,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
@@ -387,6 +395,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
 				       &dummy_funcs,
 				       connector_type,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_LT(test, ret, 0);
 }
@@ -590,6 +599,7 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 1b1b6aed04ee..74db5ce47e01 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -391,6 +391,8 @@ enum drm_hdmi_broadcast_rgb {
 
 const char *
 drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb);
+const char *
+drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt);
 
 /**
  * struct drm_monitor_range_info - Panel's Monitor range in EDID for
@@ -1077,6 +1079,11 @@ struct drm_connector_state {
 		 * @output_bpc: Bits per color channel to output.
 		 */
 		unsigned int output_bpc;
+
+		/**
+		 * @output_format: Pixel format to output in.
+		 */
+		enum hdmi_colorspace output_format;
 	} hdmi;
 };
 
@@ -1944,6 +1951,17 @@ struct drm_connector {
 
 	/** @hdr_sink_metadata: HDR Metadata Information read from sink */
 	struct hdr_sink_metadata hdr_sink_metadata;
+
+	/**
+	 * @hdmi: HDMI-related variable and properties.
+	 */
+	struct {
+		/**
+		 * @supported_formats: Bitmask of @hdmi_colorspace
+		 * supported by the controller.
+		 */
+		unsigned long supported_formats;
+	} hdmi;
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -1967,6 +1985,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     const struct drm_connector_funcs *funcs,
 			     int connector_type,
 			     struct i2c_adapter *ddc,
+			     unsigned long supported_formats,
 			     unsigned int max_bpc);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:00 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:00 +0100
Subject: [PATCH v6 17/36] drm/connector: hdmi: Add HDMI compute clock
 helper
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-17-f4bcdc979e6f@kernel.org>

A lot of HDMI drivers have some variation of the formula to calculate
the TMDS character rate from a mode, but few of them actually take all
parameters into account.

Let's create a helper to provide that rate taking all parameters into
account.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_connector.c | 71 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     |  5 +++
 2 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b895bea667f7..332477c6a987 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2982,6 +2982,77 @@ void drm_connector_update_privacy_screen(const struct drm_connector_state *conne
 }
 EXPORT_SYMBOL(drm_connector_update_privacy_screen);
 
+/**
+ * drm_connector_hdmi_compute_mode_clock() - Computes the TMDS Character Rate
+ * @mode: Display mode to compute the clock for
+ * @bpc: Bits per character
+ * @fmt: Output Pixel Format used
+ *
+ * Returns the TMDS Character Rate for a given mode, bpc count and output format.
+ *
+ * RETURNS:
+ * The TMDS Character Rate, in Hertz, or 0 on error.
+ */
+unsigned long long
+drm_connector_hdmi_compute_mode_clock(const struct drm_display_mode *mode,
+				      unsigned int bpc,
+				      enum hdmi_colorspace fmt)
+{
+	unsigned long long clock = mode->clock * 1000ULL;
+	unsigned int vic = drm_match_cea_mode(mode);
+
+	/*
+	 * CTA-861-G Spec, section 5.4 - Color Coding and Quantization
+	 * mandates that VIC 1 always uses 8 bpc.
+	 */
+	if (vic == 1 && bpc != 8)
+		return 0;
+
+	/*
+	 * HDMI 2.0 Spec, section 7.1 - YCbCr 4:2:0 Pixel Encoding
+	 * specifies that YUV420 encoding is only available for those
+	 * VICs.
+	 */
+	if (fmt == HDMI_COLORSPACE_YUV420 &&
+	    !(vic == 96 || vic == 97 || vic == 101 ||
+	      vic == 102 || vic == 106 || vic == 107))
+		return 0;
+
+	if (fmt == HDMI_COLORSPACE_YUV422) {
+		/*
+		 * HDMI 1.4b Spec, section 6.2.3 - Pixel Encoding Requirements
+		 * specifies that YUV422 is 36-bit only.
+		 */
+		if (bpc != 12)
+			return 0;
+
+		/*
+		 * HDMI 1.0 Spec, section 6.5 - Pixel Encoding
+		 * specifies that YUV422 requires two 12-bits components per
+		 * pixel clock, which is equivalent in our calculation to three
+		 * 8-bits components
+		 */
+		bpc = 8;
+	}
+
+	/*
+	 * HDMI 2.0 Spec, Section 7.1 - YCbCr 4:2:0 Pixel Encoding
+	 * specifies that YUV420 encoding is carried at a TMDS Character Rate
+	 * equal to half the pixel clock rate.
+	 */
+	if (fmt == HDMI_COLORSPACE_YUV420)
+		clock = clock / 2;
+
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		clock = clock * 2;
+
+	clock = clock * bpc;
+	do_div(clock, 8);
+
+	return clock;
+}
+EXPORT_SYMBOL(drm_connector_hdmi_compute_mode_clock);
+
 int drm_connector_set_obj_prop(struct drm_mode_object *obj,
 				    struct drm_property *property,
 				    uint64_t value)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 74db5ce47e01..0cc5a8732664 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -38,6 +38,7 @@ struct drm_connector_helper_funcs;
 struct drm_modeset_acquire_ctx;
 struct drm_device;
 struct drm_crtc;
+struct drm_display_mode;
 struct drm_encoder;
 struct drm_panel;
 struct drm_property;
@@ -2136,6 +2137,10 @@ void drm_connector_attach_privacy_screen_properties(struct drm_connector *conn);
 void drm_connector_attach_privacy_screen_provider(
 	struct drm_connector *connector, struct drm_privacy_screen *priv);
 void drm_connector_update_privacy_screen(const struct drm_connector_state *connector_state);
+unsigned long long
+drm_connector_hdmi_compute_mode_clock(const struct drm_display_mode *mode,
+				      unsigned int bpc,
+				      enum hdmi_colorspace fmt);
 
 /**
  * struct drm_tile_group - Tile group metadata

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:02 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:02 +0100
Subject: [PATCH v6 19/36] drm/connector: hdmi: Calculate TMDS character
 rate
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-19-f4bcdc979e6f@kernel.org>

Most HDMI drivers have some code to calculate the TMDS character rate,
usually to adjust an internal clock to match what the mode requires.

Since the TMDS character rates mostly depends on the resolution, whether
we need to repeat pixels or not, the bpc count and the format, we can
now derive it from the HDMI connector state that stores all those infos
and remove the duplication from drivers.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic.c                       |  1 +
 drivers/gpu/drm/drm_atomic_state_helper.c          | 44 ++++++++++++++++++++++
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  3 ++
 include/drm/drm_connector.h                        |  5 +++
 4 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 47fd2a7ca9e1..ec6c6beda5c9 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1151,6 +1151,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 		drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
 		drm_printf(p, "\toutput_format=%s\n",
 			   drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
+		drm_printf(p, "\ttmds_char_rate=%llu\n", state->hdmi.tmds_char_rate);
 	}
 
 	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 34aee5232974..ac77d47a0ce3 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -683,6 +683,41 @@ static bool hdmi_is_full_range(const struct drm_connector *connector,
 	return drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL ? true : false;
 }
 
+static enum drm_mode_status
+hdmi_clock_valid(const struct drm_connector *connector,
+		 const struct drm_display_mode *mode,
+		 unsigned long long clock)
+{
+	const struct drm_display_info *info = &connector->display_info;
+
+	if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static int
+hdmi_compute_clock(const struct drm_connector *connector,
+		   struct drm_connector_state *state,
+		   const struct drm_display_mode *mode,
+		   unsigned int bpc, enum hdmi_colorspace fmt)
+{
+	enum drm_mode_status status;
+	unsigned long long clock;
+
+	clock = drm_connector_hdmi_compute_mode_clock(mode, bpc, fmt);
+	if (!clock)
+		return -EINVAL;
+
+	status = hdmi_clock_valid(connector, mode, clock);
+	if (status != MODE_OK)
+		return -EINVAL;
+
+	state->hdmi.tmds_char_rate = clock;
+
+	return 0;
+}
+
 /**
  * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
  * @connector: DRM Connector
@@ -702,9 +737,18 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 		drm_atomic_get_old_connector_state(state, connector);
 	struct drm_connector_state *new_state =
 		drm_atomic_get_new_connector_state(state, connector);
+	const struct drm_display_mode *mode =
+		connector_state_get_mode(new_state);
+	int ret;
 
 	new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state);
 
+	ret = hdmi_compute_clock(connector, new_state, mode,
+				 new_state->hdmi.output_bpc,
+				 new_state->hdmi.output_format);
+	if (ret)
+		return ret;
+
 	if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb ||
 	    old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
 	    old_state->hdmi.output_format != new_state->hdmi.output_format) {
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 4e2ec436987b..d3f35600a9f9 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -70,6 +70,9 @@ static int light_up_connector(struct kunit *test,
 	conn_state = drm_atomic_get_connector_state(state, connector);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 
+	conn_state->hdmi.output_bpc = connector->max_bpc;
+	conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB;
+
 	ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 0cc5a8732664..59016d9c17f5 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1085,6 +1085,11 @@ struct drm_connector_state {
 		 * @output_format: Pixel format to output in.
 		 */
 		enum hdmi_colorspace output_format;
+
+		/**
+		 * @tmds_char_rate: TMDS Character Rate, in Hz.
+		 */
+		unsigned long long tmds_char_rate;
 	} hdmi;
 };
 

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:01 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:01 +0100
Subject: [PATCH v6 18/36] drm/tests: Add HDMI TDMS character rate tests
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-18-f4bcdc979e6f@kernel.org>

The previous patch added an helper to compute the TMDS character rate on
an HDMI connector. Let's add a few tests to make sure it works as
expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_connector_test.c | 323 +++++++++++++++++++++++++++++
 1 file changed, 323 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index fa6fe8084107..0a838924a546 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -8,7 +8,9 @@
 #include <drm/drm_atomic_state_helper.h>
 #include <drm/drm_connector.h>
 #include <drm/drm_drv.h>
+#include <drm/drm_edid.h>
 #include <drm/drm_kunit_helpers.h>
+#include <drm/drm_modes.h>
 
 #include <kunit/test.h>
 
@@ -719,10 +721,331 @@ static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite
 	.test_cases = drm_connector_attach_broadcast_rgb_property_tests,
 };
 
+/*
+ * Test that for a given mode, with 8bpc and an RGB output the TMDS
+ * character rate is equal to the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate);
+}
+
+/*
+ * Test that for a given mode, with 10bpc and an RGB output the TMDS
+ * character rate is equal to 1.25 times the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate);
+}
+
+/*
+ * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS
+ * character rate computation fails.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a given mode, with 12bpc and an RGB output the TMDS
+ * character rate is equal to 1.5 times the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate);
+}
+
+/*
+ * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS
+ * character rate computation fails.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a mode with the pixel repetition flag, the TMDS
+ * character rate is indeed double the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_double(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 6);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate);
+}
+
+/*
+ * Test that the TMDS character rate computation for the VIC modes
+ * explicitly listed in the spec as supporting YUV420 succeed and return
+ * half the mode pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned long long rate;
+	unsigned int vic = *(unsigned int *)test->param_value;
+
+	mode = drm_display_mode_from_cea_vic(drm, vic);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate);
+}
+
+static const unsigned int drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = {
+	96, 97, 101, 102, 106, 107,
+};
+
+static void drm_connector_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc)
+{
+	sprintf(desc, "VIC %u", *vic);
+}
+
+KUNIT_ARRAY_PARAM(drm_connector_hdmi_compute_mode_clock_yuv420_valid,
+		  drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests,
+		  drm_connector_hdmi_compute_mode_clock_yuv420_vic_desc);
+
+/*
+ * Test that trying to compute the TMDS char rate with the YUV420 format
+ * for a mode that doesn't support the YUV420 encoding returns an error.
+ *
+ * TODO: We should probably test this with all the VIC but the
+ * explicitly supported ones. Since the list of VIC is quite long and
+ * not linear, the best way to support it at the moment would be to
+ * create a custom gen_params function that would only return valid
+ * VICs. At the moment, that function expects to get a pointer back
+ * however, and compilers don't really like casting between integer and
+ * pointers.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_invalid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, 42);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420);
+	KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a given mode listed supporting it and an YUV420 output
+ * with 10bpc, the TMDS character rate is equal to 0.625 times the mode
+ * pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned int vic =
+		drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, vic);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420);
+	KUNIT_ASSERT_GT(test, rate, 0);
+
+	KUNIT_EXPECT_EQ(test, mode->clock * 625, rate);
+}
+
+/*
+ * Test that for a given mode listed supporting it and an YUV420 output
+ * with 12bpc, the TMDS character rate is equal to 0.75 times the mode
+ * pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned int vic =
+		drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, vic);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420);
+	KUNIT_ASSERT_GT(test, rate, 0);
+
+	KUNIT_EXPECT_EQ(test, mode->clock * 750, rate);
+}
+
+/*
+ * Test that for a given mode, the computation of the TMDS character
+ * rate with 8bpc and a YUV422 output fails.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422);
+	KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a given mode, the computation of the TMDS character
+ * rate with 10bpc and a YUV422 output fails.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422);
+	KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a given mode, the computation of the TMDS character
+ * rate with 12bpc and a YUV422 output succeeds and returns a rate equal
+ * to the mode pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
+}
+
+static struct kunit_case drm_connector_hdmi_compute_mode_clock_tests[] = {
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb),
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc),
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc_vic_1),
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc),
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc_vic_1),
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_double),
+	KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid,
+			 drm_connector_hdmi_compute_mode_clock_yuv420_valid_gen_params),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_invalid),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc),
+	{ }
+};
+
+static struct kunit_suite drm_connector_hdmi_compute_mode_clock_test_suite = {
+	.name = "drm_test_connector_hdmi_compute_mode_clock",
+	.init = drm_test_connector_init,
+	.test_cases = drm_connector_hdmi_compute_mode_clock_tests,
+};
+
 kunit_test_suites(
 	&drmm_connector_hdmi_init_test_suite,
 	&drmm_connector_init_test_suite,
 	&drm_connector_attach_broadcast_rgb_property_test_suite,
+	&drm_connector_hdmi_compute_mode_clock_test_suite,
 	&drm_get_tv_mode_from_name_test_suite,
 	&drm_hdmi_connector_get_broadcast_rgb_name_test_suite,
 	&drm_hdmi_connector_get_output_format_name_test_suite

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:12:51 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:12:51 +0100
Subject: [PATCH v6 08/36] drm/connector: hdmi: Create an HDMI sub-state
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-8-f4bcdc979e6f@kernel.org>

The next features we will need to share across drivers will need to
store some parameters for drivers to use, such as the selected output
format.

Let's create a new connector sub-state dedicated to HDMI controllers,
that will eventually store everything we need.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c | 35 +++++++++++++++++++++++++++++++
 include/drm/drm_atomic_state_helper.h     |  4 ++++
 include/drm/drm_connector.h               |  7 +++++++
 3 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 519228eb1095..7ad1dffe66d9 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -571,6 +571,22 @@ void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
 
+/**
+ * __drm_atomic_helper_connector_hdmi_reset() - Initializes all HDMI @drm_connector_state resources
+ * @connector: DRM connector
+ * @new_state: connector state to reset
+ *
+ * Initializes all HDMI resources from a @drm_connector_state without
+ * actually allocating it. This is useful for HDMI drivers, in
+ * combination with __drm_atomic_helper_connector_reset() or
+ * drm_atomic_helper_connector_reset().
+ */
+void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
+					      struct drm_connector_state *new_state)
+{
+}
+EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
+
 /**
  * drm_atomic_helper_connector_tv_check - Validate an analog TV connector state
  * @connector: DRM Connector
@@ -620,6 +636,25 @@ int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
 
+/**
+ * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
+ * @connector: DRM Connector
+ * @state: the DRM State object
+ *
+ * Provides a default connector state check handler for HDMI connectors.
+ * Checks that a desired connector update is valid, and updates various
+ * fields of derived state.
+ *
+ * RETURNS:
+ * Zero on success, or an errno code otherwise.
+ */
+int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
+					   struct drm_atomic_state *state)
+{
+	return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
+
 /**
  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
  * @connector: connector object
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index b9740edb2658..d59d2b3aef9a 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -71,7 +71,11 @@ void __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_
 void __drm_atomic_helper_connector_reset(struct drm_connector *connector,
 					 struct drm_connector_state *conn_state);
 void drm_atomic_helper_connector_reset(struct drm_connector *connector);
+void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
+					      struct drm_connector_state *new_state);
 void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector);
+int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
+					   struct drm_atomic_state *state);
 int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
 					 struct drm_atomic_state *state);
 void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 4491c4c2fb6e..000a2a156619 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1031,6 +1031,13 @@ struct drm_connector_state {
 	 * DRM blob property for HDR output metadata
 	 */
 	struct drm_property_blob *hdr_output_metadata;
+
+	/**
+	 * @hdmi: HDMI-related variable and properties. Filled by
+	 * @drm_atomic_helper_connector_hdmi_check().
+	 */
+	struct {
+	} hdmi;
 };
 
 /**

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:04 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:04 +0100
Subject: [PATCH v6 21/36] drm/connector: hdmi: Add custom hook to filter
 TMDS character rate
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-21-f4bcdc979e6f@kernel.org>

Most of the HDMI controllers have an upper TMDS character rate limit
they can't exceed. On "embedded"-grade display controllers, it will
typically be lower than what high-grade monitors can provide these days,
so drivers will filter the TMDS character rate based on the controller
capabilities.

To make that easier to handle for drivers, let's provide an optional
hook to be implemented by drivers so they can tell the HDMI controller
helpers if a given TMDS character rate is reachable for them or not.

This will then be useful to figure out the best format and bpc count for
a given mode.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c          |  9 +++++++
 drivers/gpu/drm/drm_connector.c                    |  4 +++
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  4 +++
 drivers/gpu/drm/tests/drm_connector_test.c         | 15 +++++++++++
 include/drm/drm_connector.h                        | 30 ++++++++++++++++++++++
 5 files changed, 62 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index ac77d47a0ce3..3a965c4aa59b 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -688,11 +688,20 @@ hdmi_clock_valid(const struct drm_connector *connector,
 		 const struct drm_display_mode *mode,
 		 unsigned long long clock)
 {
+	const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
 	const struct drm_display_info *info = &connector->display_info;
 
 	if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000)
 		return MODE_CLOCK_HIGH;
 
+	if (funcs && funcs->tmds_char_rate_valid) {
+		enum drm_mode_status status;
+
+		status = funcs->tmds_char_rate_valid(connector, mode, clock);
+		if (status != MODE_OK)
+			return status;
+	}
+
 	return MODE_OK;
 }
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 332477c6a987..a4466a79421e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -457,6 +457,7 @@ EXPORT_SYMBOL(drmm_connector_init);
  * @dev: DRM device
  * @connector: A pointer to the HDMI connector to init
  * @funcs: callbacks for this connector
+ * @hdmi_funcs: HDMI-related callbacks for this connector
  * @connector_type: user visible type of the connector
  * @ddc: optional pointer to the associated ddc adapter
  * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats
@@ -476,6 +477,7 @@ EXPORT_SYMBOL(drmm_connector_init);
 int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
 			     const struct drm_connector_funcs *funcs,
+			     const struct drm_connector_hdmi_funcs *hdmi_funcs,
 			     int connector_type,
 			     struct i2c_adapter *ddc,
 			     unsigned long supported_formats,
@@ -512,6 +514,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 	if (max_bpc > 8)
 		drm_connector_attach_hdr_output_metadata_property(connector);
 
+	connector->hdmi.funcs = hdmi_funcs;
+
 	return 0;
 }
 EXPORT_SYMBOL(drmm_connector_hdmi_init);
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index d76fafb91025..a43bbfc2c2d0 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -110,6 +110,9 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto
 	return 0;
 }
 
+static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
+};
+
 static int dummy_connector_get_modes(struct drm_connector *connector)
 {
 	struct drm_atomic_helper_connector_hdmi_priv *priv =
@@ -192,6 +195,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test,
 	conn = &priv->connector;
 	ret = drmm_connector_hdmi_init(drm, conn,
 				       &dummy_connector_funcs,
+				       &dummy_connector_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       NULL,
 				       formats,
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 0a838924a546..6a3651b08c81 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -22,6 +22,9 @@ struct drm_connector_init_priv {
 	struct i2c_adapter ddc;
 };
 
+static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = {
+};
+
 static const struct drm_connector_funcs dummy_funcs = {
 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
 	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
@@ -187,6 +190,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -205,6 +209,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       NULL,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -223,6 +228,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -241,6 +247,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -263,6 +270,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -297,6 +305,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -331,6 +340,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -361,6 +371,7 @@ static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       0,
@@ -379,6 +390,7 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_YUV422),
@@ -398,6 +410,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       connector_type,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -431,6 +444,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       connector_type,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -695,6 +709,7 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 59016d9c17f5..3eaf4d54364d 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1093,6 +1093,30 @@ struct drm_connector_state {
 	} hdmi;
 };
 
+/**
+ * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
+ */
+struct drm_connector_hdmi_funcs {
+	/**
+	 * @tmds_char_rate_valid:
+	 *
+	 * This callback is invoked at atomic_check time to figure out
+	 * whether a particular TMDS character rate is supported by the
+	 * driver.
+	 *
+	 * The @tmds_char_rate_valid callback is optional.
+	 *
+	 * Returns:
+	 *
+	 * Either &drm_mode_status.MODE_OK or one of the failure reasons
+	 * in &enum drm_mode_status.
+	 */
+	enum drm_mode_status
+	(*tmds_char_rate_valid)(const struct drm_connector *connector,
+				const struct drm_display_mode *mode,
+				unsigned long long tmds_rate);
+};
+
 /**
  * struct drm_connector_funcs - control connectors on a given device
  *
@@ -1967,6 +1991,11 @@ struct drm_connector {
 		 * supported by the controller.
 		 */
 		unsigned long supported_formats;
+
+		/**
+		 * @funcs: HDMI connector Control Functions
+		 */
+		const struct drm_connector_hdmi_funcs *funcs;
 	} hdmi;
 };
 
@@ -1989,6 +2018,7 @@ int drmm_connector_init(struct drm_device *dev,
 int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
 			     const struct drm_connector_funcs *funcs,
+			     const struct drm_connector_hdmi_funcs *hdmi_funcs,
 			     int connector_type,
 			     struct i2c_adapter *ddc,
 			     unsigned long supported_formats,

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:05 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:05 +0100
Subject: [PATCH v6 22/36] drm/tests: Add HDMI connector rate filter hook
 tests
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-22-f4bcdc979e6f@kernel.org>

The previous patch adds a new hook for HDMI connectors to filter out
configurations based on the TMDS character rate. Let's add some tests to
make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 65 ++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index a43bbfc2c2d0..e7dbdd4a4e7f 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -113,6 +113,18 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto
 static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
 };
 
+static enum drm_mode_status
+reject_connector_tmds_char_rate_valid(const struct drm_connector *connector,
+				       const struct drm_display_mode *mode,
+				       unsigned long long tmds_rate)
+{
+	return MODE_BAD;
+}
+
+static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = {
+	.tmds_char_rate_valid	= reject_connector_tmds_char_rate_valid,
+};
+
 static int dummy_connector_get_modes(struct drm_connector *connector)
 {
 	struct drm_atomic_helper_connector_hdmi_priv *priv =
@@ -960,6 +972,58 @@ static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500);
 }
 
+/*
+ * Test that if we filter a rate through our hook, it's indeed rejected
+ * by the whole atomic_check logic.
+ *
+ * We do so by first doing a commit on the pipeline to make sure that it
+ * works, change the HDMI helpers pointer, and then try the same commit
+ * again to see if it fails as it should.
+ */
+static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	conn = &priv->connector;
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	/* You shouldn't be doing that at home. */
+	conn->hdmi.funcs = &reject_connector_hdmi_funcs;
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+	crtc_state->connectors_changed = true;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
@@ -969,6 +1033,7 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
+	KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:06 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:06 +0100
Subject: [PATCH v6 23/36] drm/connector: hdmi: Compute bpc and format
 automatically
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-23-f4bcdc979e6f@kernel.org>

Now that we have all the infrastructure needed, we can add some code
that will, for a given connector state and mode, compute the best output
format and bpc.

The algorithm is equivalent to the one already found in i915 and vc4.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c          | 183 ++++++++++++++++++++-
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  25 ++-
 2 files changed, 196 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 3a965c4aa59b..67fb9dd2e41e 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -683,6 +683,96 @@ static bool hdmi_is_full_range(const struct drm_connector *connector,
 	return drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL ? true : false;
 }
 
+static bool
+sink_supports_format_bpc(const struct drm_connector *connector,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode,
+			 unsigned int format, unsigned int bpc)
+{
+	struct drm_device *dev = connector->dev;
+	u8 vic = drm_match_cea_mode(mode);
+
+	if (vic == 1 && bpc != 8) {
+		drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
+		return false;
+	}
+
+	if (!info->is_hdmi &&
+	    (format != HDMI_COLORSPACE_RGB || bpc != 8)) {
+		drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
+		return false;
+	}
+
+	if (!(connector->hdmi.supported_formats & BIT(format))) {
+		drm_dbg(dev, "%s format unsupported by the connector.\n",
+			drm_hdmi_connector_get_output_format_name(format));
+		return false;
+	}
+
+	switch (format) {
+	case HDMI_COLORSPACE_RGB:
+		drm_dbg(dev, "RGB Format, checking the constraints.\n");
+
+		if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
+			return false;
+
+		if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {
+			drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
+			return false;
+		}
+
+		if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {
+			drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
+			return false;
+		}
+
+		drm_dbg(dev, "RGB format supported in that configuration.\n");
+
+		return true;
+
+	case HDMI_COLORSPACE_YUV422:
+		drm_dbg(dev, "YUV422 format, checking the constraints.\n");
+
+		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
+			drm_dbg(dev, "Sink doesn't support YUV422.\n");
+			return false;
+		}
+
+		if (bpc != 12) {
+			drm_dbg(dev, "YUV422 only supports 12 bpc.\n");
+			return false;
+		}
+
+		drm_dbg(dev, "YUV422 format supported in that configuration.\n");
+
+		return true;
+
+	case HDMI_COLORSPACE_YUV444:
+		drm_dbg(dev, "YUV444 format, checking the constraints.\n");
+
+		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {
+			drm_dbg(dev, "Sink doesn't support YUV444.\n");
+			return false;
+		}
+
+		if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_30)) {
+			drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
+			return false;
+		}
+
+		if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_36)) {
+			drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
+			return false;
+		}
+
+		drm_dbg(dev, "YUV444 format supported in that configuration.\n");
+
+		return true;
+	}
+
+	return false;
+}
+
 static enum drm_mode_status
 hdmi_clock_valid(const struct drm_connector *connector,
 		 const struct drm_display_mode *mode,
@@ -727,6 +817,95 @@ hdmi_compute_clock(const struct drm_connector *connector,
 	return 0;
 }
 
+static bool
+hdmi_try_format_bpc(const struct drm_connector *connector,
+		    struct drm_connector_state *state,
+		    const struct drm_display_mode *mode,
+		    unsigned int bpc, enum hdmi_colorspace fmt)
+{
+	const struct drm_display_info *info = &connector->display_info;
+	struct drm_device *dev = connector->dev;
+	int ret;
+
+	drm_dbg(dev, "Trying %s output format\n",
+		drm_hdmi_connector_get_output_format_name(fmt));
+
+	if (!sink_supports_format_bpc(connector, info, mode, fmt, bpc)) {
+		drm_dbg(dev, "%s output format not supported with %u bpc\n",
+			drm_hdmi_connector_get_output_format_name(fmt), bpc);
+		return false;
+	}
+
+	ret = hdmi_compute_clock(connector, state, mode, bpc, fmt);
+	if (ret) {
+		drm_dbg(dev, "Couldn't compute clock for %s output format and %u bpc\n",
+			drm_hdmi_connector_get_output_format_name(fmt), bpc);
+		return false;
+	}
+
+	drm_dbg(dev, "%s output format supported with %u (TMDS char rate: %llu Hz)\n",
+		drm_hdmi_connector_get_output_format_name(fmt), bpc, state->hdmi.tmds_char_rate);
+
+	return true;
+}
+
+static int
+hdmi_compute_format(const struct drm_connector *connector,
+		    struct drm_connector_state *state,
+		    const struct drm_display_mode *mode,
+		    unsigned int bpc)
+{
+	struct drm_device *dev = connector->dev;
+
+	if (hdmi_try_format_bpc(connector, state, mode, bpc, HDMI_COLORSPACE_RGB)) {
+		state->hdmi.output_format = HDMI_COLORSPACE_RGB;
+		return 0;
+	}
+
+	if (hdmi_try_format_bpc(connector, state, mode, bpc, HDMI_COLORSPACE_YUV422)) {
+		state->hdmi.output_format = HDMI_COLORSPACE_YUV422;
+		return 0;
+	}
+
+	drm_dbg(dev, "Failed. No Format Supported for that bpc count.\n");
+
+	return -EINVAL;
+}
+
+static int
+hdmi_compute_config(const struct drm_connector *connector,
+		    struct drm_connector_state *state,
+		    const struct drm_display_mode *mode)
+{
+	struct drm_device *dev = connector->dev;
+	unsigned int max_bpc = clamp_t(unsigned int,
+				       state->max_bpc,
+				       8, connector->max_bpc);
+	unsigned int bpc;
+	int ret;
+
+	for (bpc = max_bpc; bpc >= 8; bpc -= 2) {
+		drm_dbg(dev, "Trying with a %d bpc output\n", bpc);
+
+		ret = hdmi_compute_format(connector, state, mode, bpc);
+		if (ret)
+			continue;
+
+		state->hdmi.output_bpc = bpc;
+
+		drm_dbg(dev,
+			"Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n",
+			mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
+			state->hdmi.output_bpc,
+			drm_hdmi_connector_get_output_format_name(state->hdmi.output_format),
+			state->hdmi.tmds_char_rate);
+
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 /**
  * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
  * @connector: DRM Connector
@@ -752,9 +931,7 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 
 	new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state);
 
-	ret = hdmi_compute_clock(connector, new_state, mode,
-				 new_state->hdmi.output_bpc,
-				 new_state->hdmi.output_format);
+	ret = hdmi_compute_config(connector, new_state, mode);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index e7dbdd4a4e7f..262d974341c0 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -70,9 +70,6 @@ static int light_up_connector(struct kunit *test,
 	conn_state = drm_atomic_get_connector_state(state, connector);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 
-	conn_state->hdmi.output_bpc = connector->max_bpc;
-	conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB;
-
 	ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
@@ -720,10 +717,15 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
 						     10);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 
-	conn = &priv->connector;
 	preferred = find_preferred_mode(conn);
 	KUNIT_ASSERT_NOT_NULL(test, preferred);
 
@@ -741,11 +743,11 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
 
-	new_conn_state->hdmi.output_bpc = 8;
+	new_conn_state->max_requested_bpc = 8;
 
 	KUNIT_ASSERT_NE(test,
-			old_conn_state->hdmi.output_bpc,
-			new_conn_state->hdmi.output_bpc);
+			old_conn_state->max_requested_bpc,
+			new_conn_state->max_requested_bpc);
 
 	ret = drm_atomic_check_only(state);
 	KUNIT_ASSERT_EQ(test, ret, 0);
@@ -789,10 +791,15 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 						     10);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 
-	conn = &priv->connector;
 	preferred = find_preferred_mode(conn);
 	KUNIT_ASSERT_NOT_NULL(test, preferred);
 
@@ -1167,7 +1174,7 @@ static void drm_test_check_format_value(struct kunit *test)
 
 	conn = &priv->connector;
 	conn_state = conn->state;
-	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 0);
 }
 
 /*

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:03 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:03 +0100
Subject: [PATCH v6 20/36] drm/tests: Add TDMS character rate connector
 state tests
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-20-f4bcdc979e6f@kernel.org>

The previous patch stores in the connector state the expected TMDS
character rate matching the configuration of the HDMI connector. Let's
add a few tests to make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 166 ++++++++++++++++
 drivers/gpu/drm/tests/drm_kunit_edid.h             | 216 +++++++++++++++++++++
 2 files changed, 382 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index d3f35600a9f9..d76fafb91025 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -816,6 +816,146 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 }
 
+/*
+ * Test that when doing a commit which would use RGB 8bpc, the TMDS
+ * clock rate stored in the connector state is equal to the mode clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8);
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000);
+}
+
+/*
+ * Test that when doing a commit which would use RGB 10bpc, the TMDS
+ * clock rate stored in the connector state is equal to 1.25 times the
+ * mode pixel clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     10);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10);
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
+}
+
+/*
+ * Test that when doing a commit which would use RGB 12bpc, the TMDS
+ * clock rate stored in the connector state is equal to 1.5 times the
+ * mode pixel clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12);
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
@@ -827,6 +967,9 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
+	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
+	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
+	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
 	/*
 	 * TODO: We should have tests to check that a change in the
 	 * format triggers a CRTC mode change just like we do for the
@@ -958,12 +1101,35 @@ static void drm_test_check_format_value(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
 }
 
+/*
+ * Test that the value of the output format property out of reset is set
+ * to 0, and will be computed at atomic_check time.
+ */
+static void drm_test_check_tmds_char_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, 0);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_value),
 	KUNIT_CASE(drm_test_check_bpc_8_value),
 	KUNIT_CASE(drm_test_check_bpc_10_value),
 	KUNIT_CASE(drm_test_check_bpc_12_value),
 	KUNIT_CASE(drm_test_check_format_value),
+	KUNIT_CASE(drm_test_check_tmds_char_value),
 	{ }
 };
 
diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h
index 2bba316de064..24f3377ef0f0 100644
--- a/drivers/gpu/drm/tests/drm_kunit_edid.h
+++ b/drivers/gpu/drm/tests/drm_kunit_edid.h
@@ -103,4 +103,220 @@ const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {
   0x00, 0x00, 0x00, 0xd0
 };
 
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 1a 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 7a
+ *
+ * 02 03 1b b1 e3 05 00 20 41 10 e2 00 ca 6d 03 0c
+ * 00 12 34 78 28 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a8
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ *   EDID Structure Version & Revision: 1.3
+ *   Vendor & Product Identification:
+ *     Manufacturer: LNX
+ *     Model: 42
+ *     Made in: 2023
+ *   Basic Display Parameters & Features:
+ *     Digital display
+ *     DFP 1.x compatible TMDS
+ *     Maximum image size: 160 cm x 90 cm
+ *     Gamma: 2.20
+ *     Undefined display color type
+ *     First detailed timing is the preferred timing
+ *   Color Characteristics:
+ *     Red  : 0.0000, 0.0000
+ *     Green: 0.0000, 0.0000
+ *     Blue : 0.0000, 0.0000
+ *     White: 0.0000, 0.0000
+ *   Established Timings I & II:
+ *     DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
+ *   Standard Timings: none
+ *   Detailed Timing Descriptors:
+ *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (1600 mm x 900 mm)
+ *                  Hfront   88 Hsync  44 Hback  148 Hpol P
+ *                  Vfront    4 Vsync   5 Vback   36 Vpol P
+ *     Display Product Name: 'Test EDID'
+ *     Display Range Limits:
+ *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ *     Dummy Descriptor:
+ *   Extension blocks: 1
+ * Checksum: 0x7a
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ *   Revision: 3
+ *   Underscans IT Video Formats by default
+ *   Supports YCbCr 4:4:4
+ *   Supports YCbCr 4:2:2
+ *   Native detailed modes: 1
+ *   Colorimetry Data Block:
+ *     sRGB
+ *   Video Data Block:
+ *     VIC  16:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz
+ *   Video Capability Data Block:
+ *     YCbCr quantization: Selectable (via AVI YQ)
+ *     RGB quantization: Selectable (via AVI Q)
+ *     PT scan behavior: No Data
+ *     IT scan behavior: Always Underscanned
+ *     CE scan behavior: Always Underscanned
+ *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ *     Source physical address: 1.2.3.4
+ *     DC_48bit
+ *     DC_36bit
+ *     DC_30bit
+ *     DC_Y444
+ *     Maximum TMDS clock: 200 MHz
+ *     Extended HDMI video details:
+ * Checksum: 0xa8  Unused space in Extension Block: 100 bytes
+ */
+const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz[] = {
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+  0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+  0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+  0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+  0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7a, 0x02, 0x03, 0x1b, 0xb1,
+  0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x6d, 0x03, 0x0c,
+  0x00, 0x12, 0x34, 0x78, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xa8
+};
+
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 0a 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 8a
+ *
+ * 02 03 1b b1 e3 05 00 20 41 10 e2 00 ca 6d 03 0c
+ * 00 12 34 78 44 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8c
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ *   EDID Structure Version & Revision: 1.3
+ *   Vendor & Product Identification:
+ *     Manufacturer: LNX
+ *     Model: 42
+ *     Made in: 2023
+ *   Basic Display Parameters & Features:
+ *     Digital display
+ *     DFP 1.x compatible TMDS
+ *     Maximum image size: 160 cm x 90 cm
+ *     Gamma: 2.20
+ *     RGB color display
+ *     First detailed timing is the preferred timing
+ *   Color Characteristics:
+ *     Red  : 0.0000, 0.0000
+ *     Green: 0.0000, 0.0000
+ *     Blue : 0.0000, 0.0000
+ *     White: 0.0000, 0.0000
+ *   Established Timings I & II:
+ *     DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
+ *   Standard Timings: none
+ *   Detailed Timing Descriptors:
+ *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (1600 mm x 900 mm)
+ *                  Hfront   88 Hsync  44 Hback  148 Hpol P
+ *                  Vfront    4 Vsync   5 Vback   36 Vpol P
+ *     Display Product Name: 'Test EDID'
+ *     Display Range Limits:
+ *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ *     Dummy Descriptor:
+ *   Extension blocks: 1
+ * Checksum: 0x8a
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ *   Revision: 3
+ *   Underscans IT Video Formats by default
+ *   Supports YCbCr 4:4:4
+ *   Supports YCbCr 4:2:2
+ *   Native detailed modes: 1
+ *   Colorimetry Data Block:
+ *     sRGB
+ *   Video Data Block:
+ *     VIC  16:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz
+ *   Video Capability Data Block:
+ *     YCbCr quantization: Selectable (via AVI YQ)
+ *     RGB quantization: Selectable (via AVI Q)
+ *     PT scan behavior: No Data
+ *     IT scan behavior: Always Underscanned
+ *     CE scan behavior: Always Underscanned
+ *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ *     Source physical address: 1.2.3.4
+ *     DC_48bit
+ *     DC_36bit
+ *     DC_30bit
+ *     DC_Y444
+ *     Maximum TMDS clock: 340 MHz
+ *     Extended HDMI video details:
+ * Checksum: 0x8c  Unused space in Extension Block: 100 bytes
+ */
+const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz[] = {
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+  0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+  0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+  0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+  0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8a, 0x02, 0x03, 0x1b, 0xb1,
+  0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x6d, 0x03, 0x0c,
+  0x00, 0x12, 0x34, 0x78, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x8c
+};
+
 #endif // DRM_KUNIT_EDID_H_

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:07 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:07 +0100
Subject: [PATCH v6 24/36] drm/tests: Add HDMI connector bpc and format
 tests
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-24-f4bcdc979e6f@kernel.org>

The previous patch added the bpc and format an HDMI connector needs to
be set up with for a given connector state.

Let's add a few tests to make sure it works as expected.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 504 +++++++++++++++++++++
 drivers/gpu/drm/tests/drm_kunit_edid.h             | 160 +++++++
 2 files changed, 664 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 262d974341c0..860e34b00fee 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -839,6 +839,56 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 }
 
+/*
+ * Test that if we have an HDMI connector but a !HDMI display, we always
+ * output RGB with 8 bpc.
+ */
+static void drm_test_check_output_bpc_dvi(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_dvi_1080p,
+				 ARRAY_SIZE(test_edid_dvi_1080p));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_FALSE(test, info->is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
 /*
  * Test that when doing a commit which would use RGB 8bpc, the TMDS
  * clock rate stored in the connector state is equal to the mode clock
@@ -1031,6 +1081,452 @@ static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
 	KUNIT_EXPECT_LT(test, ret, 0);
 }
 
+/*
+ * Test that if:
+ * - We have an HDMI connector supporting RGB only
+ * - The chosen mode has a TMDS character rate higher than the display
+ *   supports in RGB/12bpc
+ * - The chosen mode has a TMDS character rate lower than the display
+ *   supports in RGB/10bpc.
+ *
+ * Then we will pick the latter, and the computed TMDS character rate
+ * will be equal to 1.25 times the mode pixel clock.
+ */
+static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
+}
+
+/*
+ * Test that if:
+ * - We have an HDMI connector supporting both RGB and YUV422 and up to
+ *   12 bpc
+ * - The chosen mode has a TMDS character rate higher than the display
+ *   supports in RGB/12bpc
+ * - The chosen mode has a TMDS character rate lower than the display
+ *   supports in YUV422/12bpc.
+ *
+ * Then we will pick the latter, and the computed TMDS character rate
+ * will be equal to the mode pixel clock.
+ */
+static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 12);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV422);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000);
+}
+
+/*
+ * Test that if a driver and screen supports RGB and YUV formats, and we
+ * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could
+ * have had a higher bpc.
+ */
+static void drm_test_check_output_bpc_format_vic_1(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	/*
+	 * NOTE: We can't use drm_connector_hdmi_compute_mode_clock()
+	 * here because we're trying to get the rate of an invalid
+	 * configuration.
+	 *
+	 * Thus, we have to calculate the rate by hand.
+	 */
+	rate = mode->clock * 1500;
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a driver supports only RGB but the screen also supports
+ * YUV formats, we only end up with an RGB format.
+ */
+static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	/*
+	 * We're making sure that YUV422 would be the preferred option
+	 * here: we're always favouring higher bpc, we can't have RGB
+	 * because the TMDS character rate exceeds the maximum supported
+	 * by the display, and YUV422 works for that display.
+	 *
+	 * But since the driver only supports RGB, we should fallback to
+	 * a lower bpc with RGB.
+	 */
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a screen supports only RGB but the driver also supports
+ * YUV formats, we only end up with an RGB format.
+ */
+static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	/*
+	 * We're making sure that YUV422 would be the preferred option
+	 * here: we're always favouring higher bpc, we can't have RGB
+	 * because the TMDS character rate exceeds the maximum supported
+	 * by the display, and YUV422 works for that display.
+	 *
+	 * But since the display only supports RGB, we should fallback to
+	 * a lower bpc with RGB.
+	 */
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a display supports higher bpc but the driver only
+ * supports 8 bpc, we only end up with 8 bpc even if we could have had a
+ * higher bpc.
+ */
+static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	/*
+	 * We're making sure that we have headroom on the TMDS character
+	 * clock to actually use 12bpc.
+	 */
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a driver supports higher bpc but the display only
+ * supports 8 bpc, we only end up with 8 bpc even if we could have had a
+ * higher bpc.
+ */
+static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_max_340mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	/*
+	 * We're making sure that we have headroom on the TMDS character
+	 * clock to actually use 12bpc.
+	 */
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
@@ -1041,8 +1537,16 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
 	KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
+	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback),
+	KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
+	KUNIT_CASE(drm_test_check_output_bpc_dvi),
+	KUNIT_CASE(drm_test_check_output_bpc_format_vic_1),
+	KUNIT_CASE(drm_test_check_output_bpc_format_display_8bpc_only),
+	KUNIT_CASE(drm_test_check_output_bpc_format_display_rgb_only),
+	KUNIT_CASE(drm_test_check_output_bpc_format_driver_8bpc_only),
+	KUNIT_CASE(drm_test_check_output_bpc_format_driver_rgb_only),
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h
index 24f3377ef0f0..3e3527c58c31 100644
--- a/drivers/gpu/drm/tests/drm_kunit_edid.h
+++ b/drivers/gpu/drm/tests/drm_kunit_edid.h
@@ -1,6 +1,64 @@
 #ifndef DRM_KUNIT_EDID_H_
 #define DRM_KUNIT_EDID_H_
 
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 0a 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ab
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ *   EDID Structure Version & Revision: 1.3
+ *   Vendor & Product Identification:
+ *     Manufacturer: LNX
+ *     Model: 42
+ *     Made in: 2023
+ *   Basic Display Parameters & Features:
+ *     Digital display
+ *     DFP 1.x compatible TMDS
+ *     Maximum image size: 160 cm x 90 cm
+ *     Gamma: 2.20
+ *     RGB color display
+ *     First detailed timing is the preferred timing
+ *   Color Characteristics:
+ *     Red  : 0.0000, 0.0000
+ *     Green: 0.0000, 0.0000
+ *     Blue : 0.0000, 0.0000
+ *     White: 0.0000, 0.0000
+ *   Established Timings I & II: none
+ *   Standard Timings: none
+ *   Detailed Timing Descriptors:
+ *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (1600 mm x 900 mm)
+ *                  Hfront   88 Hsync  44 Hback  148 Hpol P
+ *                  Vfront    4 Vsync   5 Vback   36 Vpol P
+ *     Display Product Name: 'Test EDID'
+ *     Display Range Limits:
+ *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ *     Dummy Descriptor:
+ * Checksum: 0xab
+ */
+const unsigned char test_edid_dvi_1080p[] = {
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+  0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+  0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+  0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+  0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab
+};
+
 /*
  * edid-decode (hex):
  *
@@ -103,6 +161,108 @@ const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {
   0x00, 0x00, 0x00, 0xd0
 };
 
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92
+ *
+ * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c
+ * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ *   EDID Structure Version & Revision: 1.3
+ *   Vendor & Product Identification:
+ *     Manufacturer: LNX
+ *     Model: 42
+ *     Made in: 2023
+ *   Basic Display Parameters & Features:
+ *     Digital display
+ *     DFP 1.x compatible TMDS
+ *     Maximum image size: 160 cm x 90 cm
+ *     Gamma: 2.20
+ *     Monochrome or grayscale display
+ *     First detailed timing is the preferred timing
+ *   Color Characteristics:
+ *     Red  : 0.0000, 0.0000
+ *     Green: 0.0000, 0.0000
+ *     Blue : 0.0000, 0.0000
+ *     White: 0.0000, 0.0000
+ *   Established Timings I & II:
+ *     DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
+ *   Standard Timings: none
+ *   Detailed Timing Descriptors:
+ *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (1600 mm x 900 mm)
+ *                  Hfront   88 Hsync  44 Hback  148 Hpol P
+ *                  Vfront    4 Vsync   5 Vback   36 Vpol P
+ *     Display Product Name: 'Test EDID'
+ *     Display Range Limits:
+ *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ *     Dummy Descriptor:
+ *   Extension blocks: 1
+ * Checksum: 0x92
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ *   Revision: 3
+ *   Underscans IT Video Formats by default
+ *   Native detailed modes: 1
+ *   Colorimetry Data Block:
+ *     sRGB
+ *   Video Data Block:
+ *     VIC  16:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz
+ *   Video Capability Data Block:
+ *     YCbCr quantization: No Data
+ *     RGB quantization: Selectable (via AVI Q)
+ *     PT scan behavior: No Data
+ *     IT scan behavior: Always Underscanned
+ *     CE scan behavior: Always Underscanned
+ *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ *     Source physical address: 1.2.3.4
+ *     Maximum TMDS clock: 340 MHz
+ *     Extended HDMI video details:
+ * Checksum: 0xd0  Unused space in Extension Block: 100 bytes
+ */
+const unsigned char test_edid_hdmi_1080p_rgb_max_340mhz[] = {
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+  0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+  0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+  0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81,
+  0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c,
+  0x00, 0x12, 0x34, 0x00, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xd0
+};
+
 /*
  * edid-decode (hex):
  *

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:09 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:09 +0100
Subject: [PATCH v6 26/36] drm/tests: Add infoframes test
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-26-f4bcdc979e6f@kernel.org>

The previous patch added the generation of the infoframes matching an
HDMI connector state. Let's add a few tests to make sure it works as
expected.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_connector_test.c | 219 +++++++++++++++++++++++++++++
 1 file changed, 219 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index b9c80d282380..07066b704b36 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -219,6 +219,217 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
+/*
+ * Test that the registration of an HDMI connector with a NULL vendor
+ * fails.
+ */
+static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       NULL, "Product",
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector with a NULL product
+ * fails.
+ */
+static void drm_test_connector_hdmi_init_null_product(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", NULL,
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a valid, shorter than
+ * the max length, product name succeeds, and is stored padded with 0.
+ */
+static void drm_test_connector_hdmi_init_product_valid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
+		'P', 'r', 'o', 'd',
+	};
+	const char *product_name = "Prod";
+	int ret;
+
+	KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", product_name,
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_MEMEQ(test,
+			   priv->connector.hdmi.product,
+			   expected_product,
+			   sizeof(priv->connector.hdmi.product));
+}
+
+/*
+ * Test that the registration of a connector with a valid, at max
+ * length, product name succeeds, and is stored padded without any
+ * trailing \0.
+ */
+static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
+		'P', 'r', 'o', 'd', 'u', 'c', 't',
+		'P', 'r', 'o', 'd', 'u', 'c', 't',
+		'P', 'r',
+	};
+	const char *product_name = "ProductProductPr";
+	int ret;
+
+	KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", product_name,
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_MEMEQ(test,
+			   priv->connector.hdmi.product,
+			   expected_product,
+			   sizeof(priv->connector.hdmi.product));
+}
+
+/*
+ * Test that the registration of a connector with a product name larger
+ * than the maximum length fails.
+ */
+static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const char *product_name = "ProductProductProduct";
+	int ret;
+
+	KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", product_name,
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a vendor name smaller
+ * than the maximum length succeeds, and is stored padded with zeros.
+ */
+static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
+		'V', 'e', 'n', 'd',
+	};
+	const char *vendor_name = "Vend";
+	int ret;
+
+	KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       vendor_name, "Product",
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_MEMEQ(test,
+			   priv->connector.hdmi.vendor,
+			   expected_vendor,
+			   sizeof(priv->connector.hdmi.vendor));
+}
+
+/*
+ * Test that the registration of a connector with a vendor name at the
+ * maximum length succeeds, and is stored padded without the trailing
+ * zero.
+ */
+static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
+		'V', 'e', 'n', 'd', 'o', 'r',
+		'V', 'e',
+	};
+	const char *vendor_name = "VendorVe";
+	int ret;
+
+	KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       vendor_name, "Product",
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_MEMEQ(test,
+			   priv->connector.hdmi.vendor,
+			   expected_vendor,
+			   sizeof(priv->connector.hdmi.vendor));
+}
+
+/*
+ * Test that the registration of a connector with a vendor name larger
+ * than the maximum length fails.
+ */
+static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const char *vendor_name = "VendorVendor";
+	int ret;
+
+	KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       vendor_name, "Product",
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
 /*
  * Test that the registration of a connector with an invalid maximum bpc
  * count fails.
@@ -499,6 +710,14 @@ static struct kunit_case drmm_connector_hdmi_init_tests[] = {
 	KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty),
 	KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb),
 	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
+	KUNIT_CASE(drm_test_connector_hdmi_init_null_product),
+	KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor),
+	KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact),
+	KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long),
+	KUNIT_CASE(drm_test_connector_hdmi_init_product_valid),
+	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact),
+	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long),
+	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid),
 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
 			 drm_connector_hdmi_init_type_valid_gen_params),
 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:08 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:08 +0100
Subject: [PATCH v6 25/36] drm/connector: hdmi: Add Infoframes generation
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-25-f4bcdc979e6f@kernel.org>

Infoframes in KMS is usually handled by a bunch of low-level helpers
that require quite some boilerplate for drivers. This leads to
discrepancies with how drivers generate them, and which are actually
sent.

Now that we have everything needed to generate them in the HDMI
connector state, we can generate them in our common logic so that
drivers can simply reuse what we precomputed.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/Kconfig                            |   1 +
 drivers/gpu/drm/drm_atomic_state_helper.c          | 327 +++++++++++++++++++++
 drivers/gpu/drm/drm_connector.c                    |  16 +
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |   1 +
 drivers/gpu/drm/tests/drm_connector_test.c         |  12 +
 include/drm/drm_atomic_state_helper.h              |   8 +
 include/drm/drm_connector.h                        | 133 +++++++++
 7 files changed, 498 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 872edb47bb53..ad9c467e20ce 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -99,6 +99,7 @@ config DRM_KUNIT_TEST
 config DRM_KMS_HELPER
 	tristate
 	depends on DRM
+	select DRM_DISPLAY_HDMI_HELPER
 	help
 	  CRTC helpers for KMS drivers.
 
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 67fb9dd2e41e..82650ba46a4a 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -38,6 +38,8 @@
 #include <drm/drm_vblank.h>
 #include <drm/drm_writeback.h>
 
+#include <drm/display/drm_hdmi_helper.h>
+
 #include <linux/slab.h>
 #include <linux/dma-fence.h>
 
@@ -906,6 +908,142 @@ hdmi_compute_config(const struct drm_connector *connector,
 	return -EINVAL;
 }
 
+static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
+				       struct drm_connector_state *state)
+{
+	const struct drm_display_mode *mode =
+		connector_state_get_mode(state);
+	struct drm_connector_hdmi_infoframe *infoframe =
+		&state->hdmi.infoframes.avi;
+	struct hdmi_avi_infoframe *frame =
+		&infoframe->data.avi;
+	bool is_full_range = state->hdmi.is_full_range;
+	enum hdmi_quantization_range rgb_quant_range =
+		is_full_range ? HDMI_QUANTIZATION_RANGE_FULL : HDMI_QUANTIZATION_RANGE_LIMITED;
+	int ret;
+
+	ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode);
+	if (ret)
+		return ret;
+
+	frame->colorspace = state->hdmi.output_format;
+
+	drm_hdmi_avi_infoframe_quant_range(frame, connector, mode, rgb_quant_range);
+	drm_hdmi_avi_infoframe_colorimetry(frame, state);
+	drm_hdmi_avi_infoframe_bars(frame, state);
+
+	infoframe->set = true;
+
+	return 0;
+}
+
+static int hdmi_generate_spd_infoframe(const struct drm_connector *connector,
+				       struct drm_connector_state *state)
+{
+	struct drm_connector_hdmi_infoframe *infoframe =
+		&state->hdmi.infoframes.spd;
+	struct hdmi_spd_infoframe *frame =
+		&infoframe->data.spd;
+	int ret;
+
+	ret = hdmi_spd_infoframe_init(frame,
+				      connector->hdmi.vendor,
+				      connector->hdmi.product);
+	if (ret)
+		return ret;
+
+	frame->sdi = HDMI_SPD_SDI_PC;
+
+	infoframe->set = true;
+
+	return 0;
+}
+
+static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector,
+				       struct drm_connector_state *state)
+{
+	struct drm_connector_hdmi_infoframe *infoframe =
+		&state->hdmi.infoframes.hdr_drm;
+	struct hdmi_drm_infoframe *frame =
+		&infoframe->data.drm;
+	int ret;
+
+	if (connector->max_bpc < 10)
+		return 0;
+
+	if (!state->hdr_output_metadata)
+		return 0;
+
+	ret = drm_hdmi_infoframe_set_hdr_metadata(frame, state);
+	if (ret)
+		return ret;
+
+	infoframe->set = true;
+
+	return 0;
+}
+
+static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector *connector,
+					       struct drm_connector_state *state)
+{
+	const struct drm_display_mode *mode =
+		connector_state_get_mode(state);
+	struct drm_connector_hdmi_infoframe *infoframe =
+		&state->hdmi.infoframes.hdmi;
+	struct hdmi_vendor_infoframe *frame =
+		&infoframe->data.vendor.hdmi;
+	int ret;
+
+	ret = drm_hdmi_vendor_infoframe_from_display_mode(frame, connector, mode);
+	if (ret) {
+		if (ret == -EINVAL)
+			return 0;
+
+		return ret;
+	}
+
+	infoframe->set = true;
+
+	return 0;
+}
+
+static int
+hdmi_generate_infoframes(const struct drm_connector *connector,
+			 struct drm_connector_state *state)
+{
+	const struct drm_display_info *info = &connector->display_info;
+	int ret;
+
+	if (!info->is_hdmi)
+		return 0;
+
+	if (!info->has_hdmi_infoframe)
+		return 0;
+
+	ret = hdmi_generate_avi_infoframe(connector, state);
+	if (ret)
+		return ret;
+
+	ret = hdmi_generate_spd_infoframe(connector, state);
+	if (ret)
+		return ret;
+
+	/*
+	 * Audio Infoframes will be generated by ALSA, and updated by
+	 * drm_atomic_helper_connector_hdmi_update_audio_infoframe().
+	 */
+
+	ret = hdmi_generate_hdr_infoframe(connector, state);
+	if (ret)
+		return ret;
+
+	ret = hdmi_generate_hdmi_vendor_infoframe(connector, state);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 /**
  * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
  * @connector: DRM Connector
@@ -935,6 +1073,10 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 	if (ret)
 		return ret;
 
+	ret = hdmi_generate_infoframes(connector, new_state);
+	if (ret)
+		return ret;
+
 	if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb ||
 	    old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
 	    old_state->hdmi.output_format != new_state->hdmi.output_format) {
@@ -952,6 +1094,191 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
 
+#define HDMI_MAX_INFOFRAME_SIZE		29
+
+static int clear_device_infoframe(struct drm_connector *connector,
+				  enum hdmi_infoframe_type type)
+{
+	const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
+
+	if (!funcs || !funcs->clear_infoframe)
+		return 0;
+
+	return funcs->clear_infoframe(connector, type);
+}
+
+static int clear_infoframe(struct drm_connector *connector,
+			   struct drm_connector_hdmi_infoframe *conn_frame,
+			   struct drm_connector_hdmi_infoframe *old_frame)
+{
+	int ret;
+
+	ret = clear_device_infoframe(connector, old_frame->data.any.type);
+	if (ret)
+		return ret;
+
+	memset(old_frame, 0, sizeof(*old_frame));
+
+	return 0;
+}
+
+static int write_device_infoframe(struct drm_connector *connector,
+				  union hdmi_infoframe *frame)
+{
+	const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
+	u8 buffer[HDMI_MAX_INFOFRAME_SIZE];
+	int len;
+
+	if (!funcs || !funcs->write_infoframe)
+		return -ENOSYS;
+
+	len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer));
+	if (len < 0)
+		return len;
+
+	return funcs->write_infoframe(connector, frame->any.type, buffer, len);
+}
+
+static int write_infoframe(struct drm_connector *connector,
+			   struct drm_connector_hdmi_infoframe *conn_frame,
+			   struct drm_connector_hdmi_infoframe *new_frame)
+{
+	int ret;
+
+	ret = write_device_infoframe(connector, &new_frame->data);
+	if (ret)
+		return ret;
+
+	if (conn_frame)
+		memcpy(conn_frame, new_frame, sizeof(*conn_frame));
+
+	return 0;
+}
+
+static int write_or_clear_infoframe(struct drm_connector *connector,
+				    struct drm_connector_hdmi_infoframe *conn_frame,
+				    struct drm_connector_hdmi_infoframe *old_frame,
+				    struct drm_connector_hdmi_infoframe *new_frame)
+{
+	if (new_frame->set)
+		return write_infoframe(connector, conn_frame, new_frame);
+
+	if (old_frame->set && !new_frame->set)
+		return clear_infoframe(connector, conn_frame, old_frame);
+
+	return 0;
+}
+
+#define UPDATE_INFOFRAME(c, os, ns, i)				\
+	write_or_clear_infoframe(c,				\
+				 &(c)->hdmi.infoframes.i,	\
+				 &(os)->hdmi.infoframes.i,	\
+				 &(ns)->hdmi.infoframes.i)
+
+/**
+ * drm_atomic_helper_connector_hdmi_update_infoframes - Update the Infoframes
+ * @connector: A pointer to the HDMI connector
+ * @state: The HDMI connector state to generate the infoframe from
+ *
+ * This function is meant for HDMI connector drivers to write their
+ * infoframes. It will typically be used in a
+ * @drm_connector_helper_funcs.atomic_enable implementation.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
+						       struct drm_atomic_state *state)
+{
+	struct drm_connector_state *old_state =
+		drm_atomic_get_old_connector_state(state, connector);
+	struct drm_connector_state *new_state =
+		drm_atomic_get_new_connector_state(state, connector);
+	struct drm_display_info *info = &connector->display_info;
+	int ret;
+
+	if (!info->is_hdmi)
+		return 0;
+
+	if (!info->has_hdmi_infoframe)
+		return 0;
+
+	mutex_lock(&connector->hdmi.infoframes.lock);
+
+	ret = UPDATE_INFOFRAME(connector, old_state, new_state, avi);
+	if (ret)
+		goto out;
+
+	if (connector->hdmi.infoframes.audio.set) {
+		ret = write_infoframe(connector,
+				      NULL,
+				      &connector->hdmi.infoframes.audio);
+		if (ret)
+			goto out;
+	}
+
+	ret = UPDATE_INFOFRAME(connector, old_state, new_state, hdr_drm);
+	if (ret)
+		goto out;
+
+	ret = UPDATE_INFOFRAME(connector, old_state, new_state, spd);
+	if (ret)
+		goto out;
+
+	ret = UPDATE_INFOFRAME(connector, old_state, new_state, hdmi);
+	if (ret)
+		goto out;
+
+out:
+	mutex_unlock(&connector->hdmi.infoframes.lock);
+	return ret;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_infoframes);
+
+#undef UPDATE_INFOFRAME
+#undef UPDATE_INFOFRAME_TOGGLE
+
+/**
+ * drm_atomic_helper_connector_hdmi_update_audio_infoframe - Update the Audio Infoframe
+ * @connector: A pointer to the HDMI connector
+ * @frame: A pointer to the audio infoframe to write
+ *
+ * This function is meant for HDMI connector drivers to update their
+ * audio infoframe. It will typically be used in one of the ALSA hooks
+ * (most likely prepare).
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int
+drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector,
+							struct hdmi_audio_infoframe *frame)
+{
+	struct drm_connector_hdmi_infoframe infoframe = {};
+	struct drm_display_info *info = &connector->display_info;
+	int ret;
+
+	if (!info->is_hdmi)
+		return 0;
+
+	if (!info->has_hdmi_infoframe)
+		return 0;
+
+	memcpy(&infoframe.data, frame, sizeof(infoframe.data));
+	infoframe.set = true;
+
+	mutex_lock(&connector->hdmi.infoframes.lock);
+
+	ret = write_infoframe(connector,
+			      &connector->hdmi.infoframes.audio,
+			      &infoframe);
+
+	mutex_unlock(&connector->hdmi.infoframes.lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe);
+
 /**
  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
  * @connector: connector object
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index a4466a79421e..7941df99bf85 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -456,6 +456,8 @@ EXPORT_SYMBOL(drmm_connector_init);
  * drmm_connector_hdmi_init - Init a preallocated HDMI connector
  * @dev: DRM device
  * @connector: A pointer to the HDMI connector to init
+ * @vendor: HDMI Controller Vendor name
+ * @product: HDMI Controller Product name
  * @funcs: callbacks for this connector
  * @hdmi_funcs: HDMI-related callbacks for this connector
  * @connector_type: user visible type of the connector
@@ -476,6 +478,7 @@ EXPORT_SYMBOL(drmm_connector_init);
  */
 int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
+			     const char *vendor, const char *product,
 			     const struct drm_connector_funcs *funcs,
 			     const struct drm_connector_hdmi_funcs *hdmi_funcs,
 			     int connector_type,
@@ -485,6 +488,13 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 {
 	int ret;
 
+	if (!vendor || !product)
+		return -EINVAL;
+
+	if ((strlen(vendor) > DRM_CONNECTOR_HDMI_VENDOR_LEN) ||
+	    (strlen(product) > DRM_CONNECTOR_HDMI_PRODUCT_LEN))
+		return -EINVAL;
+
 	if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||
 	      connector_type == DRM_MODE_CONNECTOR_HDMIB))
 		return -EINVAL;
@@ -500,6 +510,12 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 		return ret;
 
 	connector->hdmi.supported_formats = supported_formats;
+	strtomem_pad(connector->hdmi.vendor, vendor, 0);
+	strtomem_pad(connector->hdmi.product, product, 0);
+
+	ret = drmm_mutex_init(dev, &connector->hdmi.infoframes.lock);
+	if (ret)
+		return ret;
 
 	/*
 	 * drm_connector_attach_max_bpc_property() requires the
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 860e34b00fee..1eaa83af9dd0 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -203,6 +203,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test,
 
 	conn = &priv->connector;
 	ret = drmm_connector_hdmi_init(drm, conn,
+				       "Vendor", "Product",
 				       &dummy_connector_funcs,
 				       &dummy_connector_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 6a3651b08c81..b9c80d282380 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -189,6 +189,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -208,6 +209,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -227,6 +229,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -246,6 +249,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -269,6 +273,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -304,6 +309,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -339,6 +345,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -370,6 +377,7 @@ static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -389,6 +397,7 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -409,6 +418,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       connector_type,
@@ -443,6 +453,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       connector_type,
@@ -708,6 +719,7 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index d59d2b3aef9a..22f083968aa8 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -40,6 +40,8 @@ struct drm_private_state;
 struct drm_modeset_acquire_ctx;
 struct drm_device;
 
+struct hdmi_audio_infoframe;
+
 void __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *state,
 					  struct drm_crtc *crtc);
 void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
@@ -88,6 +90,12 @@ void
 __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state);
 void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
 					  struct drm_connector_state *state);
+
+int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector,
+							    struct hdmi_audio_infoframe *frame);
+int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
+						       struct drm_atomic_state *state);
+
 void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
 						     struct drm_private_state *state);
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 3eaf4d54364d..5964ef283022 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -914,6 +914,21 @@ struct drm_tv_connector_state {
 	unsigned int hue;
 };
 
+/**
+ * struct drm_connector_hdmi_infoframe - HDMI Infoframe container
+ */
+struct drm_connector_hdmi_infoframe {
+	/**
+	 * @data: HDMI Infoframe structure
+	 */
+	union hdmi_infoframe data;
+
+	/**
+	 * @set: Is the content of @data valid?
+	 */
+	bool set;
+};
+
 /**
  * struct drm_connector_state - mutable connector state
  */
@@ -1070,6 +1085,35 @@ struct drm_connector_state {
 		 */
 		enum drm_hdmi_broadcast_rgb broadcast_rgb;
 
+		/**
+		 * @infoframes: HDMI Infoframes matching that state
+		 */
+		struct {
+			/**
+			 * @avi: AVI Infoframes structure matching our
+			 * state.
+			 */
+			struct drm_connector_hdmi_infoframe avi;
+
+			/**
+			 * @hdr_drm: DRM (Dynamic Range and Mastering)
+			 * Infoframes structure matching our state.
+			 */
+			struct drm_connector_hdmi_infoframe hdr_drm;
+
+			/**
+			 * @spd: SPD Infoframes structure matching our
+			 * state.
+			 */
+			struct drm_connector_hdmi_infoframe spd;
+
+			/**
+			 * @vendor: HDMI Vendor Infoframes structure
+			 * matching our state.
+			 */
+			struct drm_connector_hdmi_infoframe hdmi;
+		} infoframes;
+
 		/**
 		 * @is_full_range: Is the output supposed to use a full
 		 * RGB Quantization Range or not?
@@ -1115,6 +1159,41 @@ struct drm_connector_hdmi_funcs {
 	(*tmds_char_rate_valid)(const struct drm_connector *connector,
 				const struct drm_display_mode *mode,
 				unsigned long long tmds_rate);
+
+	/**
+	 * @clear_infoframe:
+	 *
+	 * This callback is invoked through
+	 * @drm_atomic_helper_hdmi_connector_update_infoframes during a
+	 * commit to clear the infoframes into the hardware. It will be
+	 * called multiple times, once for every disabled infoframe
+	 * type.
+	 *
+	 * The @clear_infoframe callback is optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*clear_infoframe)(struct drm_connector *connector,
+			       enum hdmi_infoframe_type type);
+
+	/**
+	 * @write_infoframe:
+	 *
+	 * This callback is invoked through
+	 * @drm_atomic_helper_hdmi_connector_update_infoframes during a
+	 * commit to program the infoframes into the hardware. It will
+	 * be called multiple times, once for every updated infoframe
+	 * type.
+	 *
+	 * The @write_infoframe callback is mandatory.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*write_infoframe)(struct drm_connector *connector,
+			       enum hdmi_infoframe_type type,
+			       const u8 *buffer, size_t len);
 };
 
 /**
@@ -1986,6 +2065,18 @@ struct drm_connector {
 	 * @hdmi: HDMI-related variable and properties.
 	 */
 	struct {
+#define DRM_CONNECTOR_HDMI_VENDOR_LEN	8
+		/**
+		 * @vendor: HDMI Controller Vendor Name
+		 */
+		unsigned char vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] __nonstring;
+
+#define DRM_CONNECTOR_HDMI_PRODUCT_LEN	16
+		/**
+		 * @product: HDMI Controller Product Name
+		 */
+		unsigned char product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] __nonstring;
+
 		/**
 		 * @supported_formats: Bitmask of @hdmi_colorspace
 		 * supported by the controller.
@@ -1996,6 +2087,47 @@ struct drm_connector {
 		 * @funcs: HDMI connector Control Functions
 		 */
 		const struct drm_connector_hdmi_funcs *funcs;
+
+		/**
+		 * @infoframes: Current Infoframes output by the connector
+		 */
+		struct {
+			/**
+			 * @lock: Mutex protecting against concurrent access to
+			 * the infoframes, most notably between KMS and ALSA.
+			 */
+			struct mutex lock;
+
+			/**
+			 * @audio: Current Audio Infoframes structure. Protected
+			 * by @lock.
+			 */
+			struct drm_connector_hdmi_infoframe audio;
+
+			/**
+			 * @avi: Current AVI Infoframes structure. Protected by
+			 * @lock.
+			 */
+			struct drm_connector_hdmi_infoframe avi;
+
+			/**
+			 * @hdr_drm: Current DRM (Dynamic Range and Mastering)
+			 * Infoframes structure. Protected by @lock.
+			 */
+			struct drm_connector_hdmi_infoframe hdr_drm;
+
+			/**
+			 * @spd: Current SPD Infoframes structure. Protected by
+			 * @lock.
+			 */
+			struct drm_connector_hdmi_infoframe spd;
+
+			/**
+			 * @vendor: Current HDMI Vendor Infoframes structure.
+			 * Protected by @lock.
+			 */
+			struct drm_connector_hdmi_infoframe hdmi;
+		} infoframes;
 	} hdmi;
 };
 
@@ -2017,6 +2149,7 @@ int drmm_connector_init(struct drm_device *dev,
 			struct i2c_adapter *ddc);
 int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
+			     const char *vendor, const char *product,
 			     const struct drm_connector_funcs *funcs,
 			     const struct drm_connector_hdmi_funcs *hdmi_funcs,
 			     int connector_type,

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:10 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:10 +0100
Subject: [PATCH v6 27/36] drm/connector: hdmi: Create Infoframe DebugFS
 entries
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-27-f4bcdc979e6f@kernel.org>

There has been some discussions recently about the infoframes sent by
drivers and if they were properly generated.

In parallel, there's been some interest in creating an infoframe-decode
tool similar to edid-decode.

Both would be much easier if we were to expose the infoframes programmed
in the hardware. It won't be perfect since we have no guarantee that
it's actually what goes through the wire, but it's the best we can do.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_debugfs.c | 110 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 08fcefd804bc..160389f3d84b 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -520,6 +520,114 @@ static const struct file_operations drm_connector_fops = {
 	.write = connector_write
 };
 
+struct debugfs_wrapper {
+	struct drm_connector *connector;
+	struct drm_connector_hdmi_infoframe *frame;
+};
+
+#define HDMI_MAX_INFOFRAME_SIZE		29
+
+static ssize_t
+infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos)
+{
+	const struct debugfs_wrapper *wrapper = filp->private_data;
+	struct drm_connector *connector = wrapper->connector;
+	struct drm_connector_hdmi_infoframe *infoframe = wrapper->frame;
+	union hdmi_infoframe *frame = &infoframe->data;
+	u8 buf[HDMI_MAX_INFOFRAME_SIZE];
+	ssize_t len = 0;
+
+	mutex_lock(&connector->hdmi.infoframes.lock);
+
+	if (!infoframe->set)
+		goto out;
+
+	len = hdmi_infoframe_pack(frame, buf, sizeof(buf));
+	if (len < 0)
+		goto out;
+
+	len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+
+out:
+	mutex_unlock(&connector->hdmi.infoframes.lock);
+	return len;
+}
+
+static const struct file_operations infoframe_fops = {
+	.owner   = THIS_MODULE,
+	.open    = simple_open,
+	.read    = infoframe_read,
+};
+
+static int create_hdmi_infoframe_file(struct drm_connector *connector,
+				      struct dentry *parent,
+				      const char *filename,
+				      struct drm_connector_hdmi_infoframe *frame)
+{
+	struct drm_device *dev = connector->dev;
+	struct debugfs_wrapper *wrapper;
+	struct dentry *file;
+
+	wrapper = drmm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
+	if (!wrapper)
+		return -ENOMEM;
+
+	wrapper->connector = connector;
+	wrapper->frame = frame;
+
+	file = debugfs_create_file(filename, 0400, parent, wrapper, &infoframe_fops);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	return 0;
+}
+
+#define CREATE_HDMI_INFOFRAME_FILE(c, p, i)		\
+	create_hdmi_infoframe_file(c, p, #i, &(c)->hdmi.infoframes.i)
+
+static int create_hdmi_infoframe_files(struct drm_connector *connector,
+				       struct dentry *parent)
+{
+	int ret;
+
+	ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, audio);
+	if (ret)
+		return ret;
+
+	ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, avi);
+	if (ret)
+		return ret;
+
+	ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, hdr_drm);
+	if (ret)
+		return ret;
+
+	ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, spd);
+	if (ret)
+		return ret;
+
+	ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, hdmi);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void hdmi_debugfs_add(struct drm_connector *connector)
+{
+	struct dentry *dir;
+
+	if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+	      connector->connector_type == DRM_MODE_CONNECTOR_HDMIB))
+		return;
+
+	dir = debugfs_create_dir("infoframes", connector->debugfs_entry);
+	if (IS_ERR(dir))
+		return;
+
+	create_hdmi_infoframe_files(connector, dir);
+}
+
 void drm_debugfs_connector_add(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
@@ -547,6 +655,8 @@ void drm_debugfs_connector_add(struct drm_connector *connector)
 	debugfs_create_file("output_bpc", 0444, root, connector,
 			    &output_bpc_fops);
 
+	hdmi_debugfs_add(connector);
+
 	if (connector->funcs->debugfs_init)
 		connector->funcs->debugfs_init(connector, root);
 }

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:12 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:12 +0100
Subject: [PATCH v6 29/36] drm/vc4: tests: Remove vc4_dummy_plane structure
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-29-f4bcdc979e6f@kernel.org>

The vc4_dummy_plane structure is an exact equivalent to vc4_plane, so we
don't need it.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/vc4/tests/vc4_mock.c       |  6 ++----
 drivers/gpu/drm/vc4/tests/vc4_mock.h       |  9 ++-------
 drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 14 +++++---------
 3 files changed, 9 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.c b/drivers/gpu/drm/vc4/tests/vc4_mock.c
index becb3dbaa548..0731a7d85d7a 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock.c
@@ -109,16 +109,14 @@ static const struct vc4_mock_desc vc5_mock =
 static int __build_one_pipe(struct kunit *test, struct drm_device *drm,
 			    const struct vc4_mock_pipe_desc *pipe)
 {
-	struct vc4_dummy_plane *dummy_plane;
 	struct drm_plane *plane;
 	struct vc4_dummy_crtc *dummy_crtc;
 	struct drm_crtc *crtc;
 	unsigned int i;
 
-	dummy_plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
+	plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
 
-	plane = &dummy_plane->plane.base;
 	dummy_crtc = vc4_mock_pv(test, drm, plane, pipe->data);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc);
 
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.h b/drivers/gpu/drm/vc4/tests/vc4_mock.h
index 2d0b339bd9f3..002b6218960c 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock.h
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock.h
@@ -21,13 +21,8 @@ struct drm_crtc *vc4_find_crtc_for_encoder(struct kunit *test,
 	return NULL;
 }
 
-struct vc4_dummy_plane {
-	struct vc4_plane plane;
-};
-
-struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
-					struct drm_device *drm,
-					enum drm_plane_type type);
+struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
+				  enum drm_plane_type type);
 
 struct vc4_dummy_crtc {
 	struct vc4_crtc crtc;
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
index 62b18f5f41db..973f5f929097 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
@@ -22,15 +22,12 @@ static const uint32_t vc4_dummy_plane_formats[] = {
 	DRM_FORMAT_XRGB8888,
 };
 
-struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
-					struct drm_device *drm,
-					enum drm_plane_type type)
+struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
+				  enum drm_plane_type type)
 {
-	struct vc4_dummy_plane *dummy_plane;
 	struct drm_plane *plane;
 
-	dummy_plane = drmm_universal_plane_alloc(drm,
-						 struct vc4_dummy_plane, plane.base,
+	plane = __drmm_universal_plane_alloc(drm, sizeof(struct drm_plane), 0,
 						 0,
 						 &vc4_dummy_plane_funcs,
 						 vc4_dummy_plane_formats,
@@ -38,10 +35,9 @@ struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
 						 NULL,
 						 DRM_PLANE_TYPE_PRIMARY,
 						 NULL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
 
-	plane = &dummy_plane->plane.base;
 	drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs);
 
-	return dummy_plane;
+	return plane;
 }

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:14 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:14 +0100
Subject: [PATCH v6 31/36] drm/rockchip: inno_hdmi: Switch to HDMI connector
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-31-f4bcdc979e6f@kernel.org>

The new HDMI connector infrastructure allows to remove some boilerplate,
especially to generate infoframes. Let's switch to it.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/rockchip/inno_hdmi.c | 123 ++++++++++++-----------------------
 1 file changed, 42 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 1d2261643743..d59947679042 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -67,9 +67,7 @@ struct inno_hdmi {
 
 struct inno_hdmi_connector_state {
 	struct drm_connector_state	base;
-	unsigned int			enc_out_format;
 	unsigned int			colorimetry;
-	bool				rgb_limited_range;
 };
 
 static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
@@ -257,26 +255,29 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
 	inno_hdmi_standby(hdmi);
 }
 
-static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
-				    enum hdmi_infoframe_type type)
+static int inno_hdmi_disable_frame(struct drm_connector *connector,
+				   enum hdmi_infoframe_type type)
 {
-	struct drm_connector *connector = &hdmi->connector;
+	struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
 
 	if (type != HDMI_INFOFRAME_TYPE_AVI) {
 		drm_err(connector->dev,
 			"Unsupported infoframe type: %u\n", type);
-		return;
+		return 0;
 	}
 
 	hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
+
+	return 0;
 }
 
-static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
-				  union hdmi_infoframe *frame, enum hdmi_infoframe_type type)
+static int inno_hdmi_upload_frame(struct drm_connector *connector,
+				  enum hdmi_infoframe_type type,
+				  const u8 *buffer, size_t len)
 {
-	struct drm_connector *connector = &hdmi->connector;
+	struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
 	u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
-	ssize_t rc, i;
+	ssize_t i;
 
 	if (type != HDMI_INFOFRAME_TYPE_AVI) {
 		drm_err(connector->dev,
@@ -284,59 +285,19 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
 		return 0;
 	}
 
-	inno_hdmi_disable_frame(hdmi, type);
+	inno_hdmi_disable_frame(connector, type);
 
-	rc = hdmi_infoframe_pack(frame, packed_frame,
-				 sizeof(packed_frame));
-	if (rc < 0)
-		return rc;
-
-	for (i = 0; i < rc; i++)
+	for (i = 0; i < len; i++)
 		hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
 			    packed_frame[i]);
 
 	return 0;
 }
 
-static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
-				      struct drm_display_mode *mode)
-{
-	struct drm_connector *connector = &hdmi->connector;
-	struct drm_connector_state *conn_state = connector->state;
-	struct inno_hdmi_connector_state *inno_conn_state =
-					to_inno_hdmi_conn_state(conn_state);
-	union hdmi_infoframe frame;
-	int rc;
-
-	rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
-						      &hdmi->connector,
-						      mode);
-	if (rc) {
-		inno_hdmi_disable_frame(hdmi, HDMI_INFOFRAME_TYPE_AVI);
-		return rc;
-	}
-
-	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444)
-		frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
-	else if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV422)
-		frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
-	else
-		frame.avi.colorspace = HDMI_COLORSPACE_RGB;
-
-	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
-		drm_hdmi_avi_infoframe_quant_range(&frame.avi,
-						   connector, mode,
-						   inno_conn_state->rgb_limited_range ?
-						   HDMI_QUANTIZATION_RANGE_LIMITED :
-						   HDMI_QUANTIZATION_RANGE_FULL);
-	} else {
-		frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
-		frame.avi.ycc_quantization_range =
-			HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
-	}
-
-	return inno_hdmi_upload_frame(hdmi, &frame, HDMI_INFOFRAME_TYPE_AVI);
-}
+static const struct drm_connector_hdmi_funcs inno_hdmi_hdmi_connector_funcs = {
+	.clear_infoframe	= inno_hdmi_disable_frame,
+	.write_infoframe	= inno_hdmi_upload_frame,
+};
 
 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
 {
@@ -361,8 +322,8 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
 		v_VIDEO_INPUT_CSP(0);
 	hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
 
-	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
-		if (inno_conn_state->rgb_limited_range) {
+	if (conn_state->hdmi.output_format == HDMI_COLORSPACE_RGB) {
+		if (!conn_state->hdmi.is_full_range) {
 			csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
 			auto_csc = AUTO_CSC_DISABLE;
 			c0_c2_change = C0_C2_CHANGE_DISABLE;
@@ -380,14 +341,14 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
 		}
 	} else {
 		if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
-			if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
+			if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) {
 				csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
 				auto_csc = AUTO_CSC_DISABLE;
 				c0_c2_change = C0_C2_CHANGE_DISABLE;
 				csc_enable = v_CSC_ENABLE;
 			}
 		} else {
-			if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
+			if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) {
 				csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
 				auto_csc = AUTO_CSC_DISABLE;
 				c0_c2_change = C0_C2_CHANGE_DISABLE;
@@ -462,10 +423,12 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
 }
 
 static int inno_hdmi_setup(struct inno_hdmi *hdmi,
-			   struct drm_display_mode *mode)
+			   struct drm_crtc_state *new_crtc_state,
+			   struct drm_connector_state *new_conn_state)
 {
-	struct drm_display_info *display = &hdmi->connector.display_info;
-	unsigned long mpixelclock = mode->clock * 1000;
+	struct drm_connector *connector = &hdmi->connector;
+	struct drm_display_info *display = &connector->display_info;
+	struct drm_display_mode *mode = &new_crtc_state->adjusted_mode;
 
 	/* Mute video and audio output */
 	hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
@@ -479,8 +442,8 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
 
 	inno_hdmi_config_video_csc(hdmi);
 
-	if (display->is_hdmi)
-		inno_hdmi_config_video_avi(hdmi, mode);
+	drm_atomic_helper_connector_hdmi_update_infoframes(connector,
+							   new_conn_state->state);
 
 	/*
 	 * When IP controller have configured to an accurate video
@@ -488,13 +451,13 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
 	 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
 	 * clock rate, and reconfigure the DDC clock.
 	 */
-	inno_hdmi_i2c_init(hdmi, mpixelclock);
+	inno_hdmi_i2c_init(hdmi, new_conn_state->hdmi.tmds_char_rate);
 
 	/* Unmute video and audio output */
 	hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
 		  v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
 
-	inno_hdmi_power_up(hdmi, mpixelclock);
+	inno_hdmi_power_up(hdmi, new_conn_state->hdmi.tmds_char_rate);
 
 	return 0;
 }
@@ -546,7 +509,7 @@ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
 	if (WARN_ON(!crtc_state))
 		return;
 
-	inno_hdmi_setup(hdmi, &crtc_state->adjusted_mode);
+	inno_hdmi_setup(hdmi, crtc_state, conn_state);
 }
 
 static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
@@ -563,7 +526,6 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 			       struct drm_connector_state *conn_state)
 {
 	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
-	struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
 	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 	u8 vic = drm_match_cea_mode(mode);
 	struct inno_hdmi_connector_state *inno_conn_state =
@@ -580,12 +542,7 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 	else
 		inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
 
-	inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
-	inno_conn_state->rgb_limited_range =
-		drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED;
-
-	return  inno_hdmi_display_mode_valid(hdmi,
-				&crtc_state->adjusted_mode) == MODE_OK ? 0 : -EINVAL;
+	return 0;
 }
 
 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
@@ -662,10 +619,9 @@ static void inno_hdmi_connector_reset(struct drm_connector *connector)
 		return;
 
 	__drm_atomic_helper_connector_reset(connector, &inno_conn_state->base);
+	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
 
 	inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
-	inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
-	inno_conn_state->rgb_limited_range = false;
 }
 
 static struct drm_connector_state *
@@ -698,6 +654,7 @@ static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
 };
 
 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
+	.atomic_check = drm_atomic_helper_connector_hdmi_check,
 	.get_modes = inno_hdmi_connector_get_modes,
 	.mode_valid = inno_hdmi_connector_mode_valid,
 };
@@ -725,10 +682,14 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &inno_hdmi_connector_helper_funcs);
-	drm_connector_init_with_ddc(drm, &hdmi->connector,
-				    &inno_hdmi_connector_funcs,
-				    DRM_MODE_CONNECTOR_HDMIA,
-				    hdmi->ddc);
+	drmm_connector_hdmi_init(drm, &hdmi->connector,
+				 "Rockchip", "Inno HDMI",
+				 &inno_hdmi_connector_funcs,
+				 &inno_hdmi_hdmi_connector_funcs,
+				 DRM_MODE_CONNECTOR_HDMIA,
+				 hdmi->ddc,
+				 BIT(HDMI_COLORSPACE_RGB),
+				 8);
 
 	drm_connector_attach_encoder(&hdmi->connector, encoder);
 

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:11 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:11 +0100
Subject: [PATCH v6 28/36] drm/vc4: hdmi: Switch to HDMI connector
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-28-f4bcdc979e6f@kernel.org>

The new HDMI connector infrastructure allows us to remove a lot of
boilerplate, so let's switch to it.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c     | 638 +++++--------------------------------
 drivers/gpu/drm/vc4/vc4_hdmi.h     |  44 +--
 drivers/gpu/drm/vc4/vc4_hdmi_phy.c |   6 +-
 3 files changed, 86 insertions(+), 602 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 34f807ed1c31..1f489cbe0c90 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -110,25 +110,6 @@
 
 #define HDMI_14_MAX_TMDS_CLK   (340 * 1000 * 1000)
 
-static const char * const output_format_str[] = {
-	[VC4_HDMI_OUTPUT_RGB]		= "RGB",
-	[VC4_HDMI_OUTPUT_YUV420]	= "YUV 4:2:0",
-	[VC4_HDMI_OUTPUT_YUV422]	= "YUV 4:2:2",
-	[VC4_HDMI_OUTPUT_YUV444]	= "YUV 4:4:4",
-};
-
-static const char *vc4_hdmi_output_fmt_str(enum vc4_hdmi_output_format fmt)
-{
-	if (fmt >= ARRAY_SIZE(output_format_str))
-		return "invalid";
-
-	return output_format_str[fmt];
-}
-
-static unsigned long long
-vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode,
-				    unsigned int bpc, enum vc4_hdmi_output_format fmt);
-
 static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi)
 {
 	struct drm_display_info *display = &vc4_hdmi->connector.display_info;
@@ -147,28 +128,13 @@ static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi)
 
 static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode,
 					   unsigned int bpc,
-					   enum vc4_hdmi_output_format fmt)
+					   enum hdmi_colorspace fmt)
 {
-	unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt);
+	unsigned long long clock = drm_connector_hdmi_compute_mode_clock(mode, bpc, fmt);
 
 	return clock > HDMI_14_MAX_TMDS_CLK;
 }
 
-static bool vc4_hdmi_is_full_range(struct vc4_hdmi *vc4_hdmi,
-				   struct vc4_hdmi_connector_state *vc4_state)
-{
-	const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
-	struct drm_display_info *display = &vc4_hdmi->connector.display_info;
-
-	if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_LIMITED)
-		return false;
-	else if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_FULL)
-		return true;
-
-	return !display->is_hdmi ||
-		drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL;
-}
-
 static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
 {
 	struct drm_debugfs_entry *entry = m->private;
@@ -520,7 +486,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
 		const struct drm_display_mode *mode;
 
 		list_for_each_entry(mode, &connector->probed_modes, head) {
-			if (vc4_hdmi_mode_needs_scrambling(mode, 8, VC4_HDMI_OUTPUT_RGB)) {
+			if (vc4_hdmi_mode_needs_scrambling(mode, 8, HDMI_COLORSPACE_RGB)) {
 				drm_warn_once(drm, "The core clock cannot reach frequencies high enough to support 4k @ 60Hz.");
 				drm_warn_once(drm, "Please change your config.txt file to add hdmi_enable_4kp60.");
 			}
@@ -535,12 +501,8 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
 {
 	struct drm_connector_state *old_state =
 		drm_atomic_get_old_connector_state(state, connector);
-	struct vc4_hdmi_connector_state *old_vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(old_state);
 	struct drm_connector_state *new_state =
 		drm_atomic_get_new_connector_state(state, connector);
-	struct vc4_hdmi_connector_state *new_vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(new_state);
 	struct drm_crtc *crtc = new_state->crtc;
 
 	if (!crtc)
@@ -572,9 +534,7 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
 			return ret;
 	}
 
-	if (old_state->colorspace != new_state->colorspace ||
-	    old_vc4_state->broadcast_rgb != new_vc4_state->broadcast_rgb ||
-	    !drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) {
+	if (old_state->colorspace != new_state->colorspace) {
 		struct drm_crtc_state *crtc_state;
 
 		crtc_state = drm_atomic_get_crtc_state(state, crtc);
@@ -584,112 +544,21 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
 		crtc_state->mode_changed = true;
 	}
 
-	return 0;
-}
-
-static int vc4_hdmi_connector_get_property(struct drm_connector *connector,
-					   const struct drm_connector_state *state,
-					   struct drm_property *property,
-					   uint64_t *val)
-{
-	struct drm_device *drm = connector->dev;
-	struct vc4_hdmi *vc4_hdmi =
-		connector_to_vc4_hdmi(connector);
-	const struct vc4_hdmi_connector_state *vc4_conn_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
-
-	if (property == vc4_hdmi->broadcast_rgb_property) {
-		*val = vc4_conn_state->broadcast_rgb;
-	} else {
-		drm_dbg(drm, "Unknown property [PROP:%d:%s]\n",
-			property->base.id, property->name);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int vc4_hdmi_connector_set_property(struct drm_connector *connector,
-					   struct drm_connector_state *state,
-					   struct drm_property *property,
-					   uint64_t val)
-{
-	struct drm_device *drm = connector->dev;
-	struct vc4_hdmi *vc4_hdmi =
-		connector_to_vc4_hdmi(connector);
-	struct vc4_hdmi_connector_state *vc4_conn_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
-
-	if (property == vc4_hdmi->broadcast_rgb_property) {
-		vc4_conn_state->broadcast_rgb = val;
-		return 0;
-	}
-
-	drm_dbg(drm, "Unknown property [PROP:%d:%s]\n",
-		property->base.id, property->name);
-	return -EINVAL;
+	return drm_atomic_helper_connector_hdmi_check(connector, state);
 }
 
 static void vc4_hdmi_connector_reset(struct drm_connector *connector)
 {
-	struct vc4_hdmi_connector_state *old_state =
-		conn_state_to_vc4_hdmi_conn_state(connector->state);
-	struct vc4_hdmi_connector_state *new_state =
-		kzalloc(sizeof(*new_state), GFP_KERNEL);
-
-	if (connector->state)
-		__drm_atomic_helper_connector_destroy_state(connector->state);
-
-	kfree(old_state);
-	__drm_atomic_helper_connector_reset(connector, &new_state->base);
-
-	if (!new_state)
-		return;
-
-	new_state->base.max_bpc = 8;
-	new_state->base.max_requested_bpc = 8;
-	new_state->output_format = VC4_HDMI_OUTPUT_RGB;
-	new_state->broadcast_rgb = VC4_HDMI_BROADCAST_RGB_AUTO;
+	drm_atomic_helper_connector_reset(connector);
+	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
 	drm_atomic_helper_connector_tv_margins_reset(connector);
 }
 
-static struct drm_connector_state *
-vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
-{
-	struct drm_connector_state *conn_state = connector->state;
-	struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state);
-	struct vc4_hdmi_connector_state *new_state;
-
-	new_state = kzalloc(sizeof(*new_state), GFP_KERNEL);
-	if (!new_state)
-		return NULL;
-
-	new_state->tmds_char_rate = vc4_state->tmds_char_rate;
-	new_state->output_bpc = vc4_state->output_bpc;
-	new_state->output_format = vc4_state->output_format;
-	new_state->broadcast_rgb = vc4_state->broadcast_rgb;
-	__drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
-
-	return &new_state->base;
-}
-
-static void vc4_hdmi_connector_destroy_state(struct drm_connector *connector,
-					     struct drm_connector_state *state)
-{
-	struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
-
-	__drm_atomic_helper_connector_destroy_state(state);
-	kfree(vc4_state);
-}
-
 static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.reset = vc4_hdmi_connector_reset,
-	.atomic_duplicate_state = vc4_hdmi_connector_duplicate_state,
-	.atomic_destroy_state = vc4_hdmi_connector_destroy_state,
-	.atomic_get_property = vc4_hdmi_connector_get_property,
-	.atomic_set_property = vc4_hdmi_connector_set_property,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
@@ -698,32 +567,7 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
 	.atomic_check = vc4_hdmi_connector_atomic_check,
 };
 
-static const struct drm_prop_enum_list broadcast_rgb_names[] = {
-	{ VC4_HDMI_BROADCAST_RGB_AUTO, "Automatic" },
-	{ VC4_HDMI_BROADCAST_RGB_FULL, "Full" },
-	{ VC4_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" },
-};
-
-static void
-vc4_hdmi_attach_broadcast_rgb_property(struct drm_device *dev,
-				       struct vc4_hdmi *vc4_hdmi)
-{
-	struct drm_property *prop = vc4_hdmi->broadcast_rgb_property;
-
-	if (!prop) {
-		prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
-						"Broadcast RGB",
-						broadcast_rgb_names,
-						ARRAY_SIZE(broadcast_rgb_names));
-		if (!prop)
-			return;
-
-		vc4_hdmi->broadcast_rgb_property = prop;
-	}
-
-	drm_object_attach_property(&vc4_hdmi->connector.base, prop,
-				   VC4_HDMI_BROADCAST_RGB_AUTO);
-}
+static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs;
 
 static int vc4_hdmi_connector_init(struct drm_device *dev,
 				   struct vc4_hdmi *vc4_hdmi)
@@ -732,10 +576,16 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
 	struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
 	int ret;
 
-	ret = drmm_connector_init(dev, connector,
-				  &vc4_hdmi_connector_funcs,
-				  DRM_MODE_CONNECTOR_HDMIA,
-				  vc4_hdmi->ddc);
+	ret = drmm_connector_hdmi_init(dev, connector,
+				       "Broadcom", "Videocore",
+				       &vc4_hdmi_connector_funcs,
+				       &vc4_hdmi_hdmi_connector_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       vc4_hdmi->ddc,
+				       BIT(HDMI_COLORSPACE_RGB) |
+				       BIT(HDMI_COLORSPACE_YUV422) |
+				       BIT(HDMI_COLORSPACE_YUV444),
+				       12);
 	if (ret)
 		return ret;
 
@@ -759,7 +609,6 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
 
 	drm_connector_attach_colorspace_property(connector);
 	drm_connector_attach_tv_margin_properties(connector);
-	drm_connector_attach_max_bpc_property(connector, 8, 12);
 
 	connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
 			     DRM_CONNECTOR_POLL_DISCONNECT);
@@ -768,21 +617,19 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
 	connector->doublescan_allowed = 0;
 	connector->stereo_allowed = 1;
 
-	if (vc4_hdmi->variant->supports_hdr)
-		drm_connector_attach_hdr_output_metadata_property(connector);
-
-	vc4_hdmi_attach_broadcast_rgb_property(dev, vc4_hdmi);
+	ret = drm_connector_attach_broadcast_rgb_property(connector);
+	if (ret)
+		return ret;
 
 	drm_connector_attach_encoder(connector, encoder);
 
 	return 0;
 }
 
-static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
+static int vc4_hdmi_stop_packet(struct vc4_hdmi *vc4_hdmi,
 				enum hdmi_infoframe_type type,
 				bool poll)
 {
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	u32 packet_id = type - 0x80;
 	unsigned long flags;
@@ -806,12 +653,13 @@ static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
 	return ret;
 }
 
-static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
-				     union hdmi_infoframe *frame)
+static int vc4_hdmi_write_infoframe(struct drm_connector *connector,
+				    enum hdmi_infoframe_type type,
+				    const u8 *infoframe, size_t len)
 {
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct drm_device *drm = vc4_hdmi->connector.dev;
-	u32 packet_id = frame->any.type - 0x80;
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
+	struct drm_device *drm = connector->dev;
+	u32 packet_id = type - 0x80;
 	const struct vc4_hdmi_register *ram_packet_start =
 		&vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START];
 	u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id;
@@ -821,22 +669,25 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
 						       ram_packet_start->reg);
 	uint8_t buffer[VC4_HDMI_PACKET_STRIDE] = {};
 	unsigned long flags;
-	ssize_t len, i;
+	ssize_t i;
 	int ret;
 	int idx;
 
 	if (!drm_dev_enter(drm, &idx))
-		return;
+		return 0;
+
+	if (len > sizeof(buffer)) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(buffer, infoframe, len);
 
 	WARN_ONCE(!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
 		    VC4_HDMI_RAM_PACKET_ENABLE),
 		  "Packet RAM has to be on to store the packet.");
 
-	len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer));
-	if (len < 0)
-		goto out;
-
-	ret = vc4_hdmi_stop_packet(encoder, frame->any.type, true);
+	ret = vc4_hdmi_stop_packet(vc4_hdmi, type, true);
 	if (ret) {
 		DRM_ERROR("Failed to wait for infoframe to go idle: %d\n", ret);
 		goto out;
@@ -878,130 +729,7 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
 
 out:
 	drm_dev_exit(idx);
-}
-
-static void vc4_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame,
-					      enum vc4_hdmi_output_format fmt)
-{
-	switch (fmt) {
-	case VC4_HDMI_OUTPUT_RGB:
-		frame->colorspace = HDMI_COLORSPACE_RGB;
-		break;
-
-	case VC4_HDMI_OUTPUT_YUV420:
-		frame->colorspace = HDMI_COLORSPACE_YUV420;
-		break;
-
-	case VC4_HDMI_OUTPUT_YUV422:
-		frame->colorspace = HDMI_COLORSPACE_YUV422;
-		break;
-
-	case VC4_HDMI_OUTPUT_YUV444:
-		frame->colorspace = HDMI_COLORSPACE_YUV444;
-		break;
-
-	default:
-		break;
-	}
-}
-
-static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
-{
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct drm_connector *connector = &vc4_hdmi->connector;
-	struct drm_connector_state *cstate = connector->state;
-	struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(cstate);
-	const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
-	union hdmi_infoframe frame;
-	int ret;
-
-	lockdep_assert_held(&vc4_hdmi->mutex);
-
-	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
-						       connector, mode);
-	if (ret < 0) {
-		DRM_ERROR("couldn't fill AVI infoframe\n");
-		return;
-	}
-
-	drm_hdmi_avi_infoframe_quant_range(&frame.avi,
-					   connector, mode,
-					   vc4_hdmi_is_full_range(vc4_hdmi, vc4_state) ?
-					   HDMI_QUANTIZATION_RANGE_FULL :
-					   HDMI_QUANTIZATION_RANGE_LIMITED);
-	drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate);
-	vc4_hdmi_avi_infoframe_colorspace(&frame.avi, vc4_state->output_format);
-	drm_hdmi_avi_infoframe_bars(&frame.avi, cstate);
-
-	vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
-{
-	union hdmi_infoframe frame;
-	int ret;
-
-	ret = hdmi_spd_infoframe_init(&frame.spd, "Broadcom", "Videocore");
-	if (ret < 0) {
-		DRM_ERROR("couldn't fill SPD infoframe\n");
-		return;
-	}
-
-	frame.spd.sdi = HDMI_SPD_SDI_PC;
-
-	vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder)
-{
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct hdmi_audio_infoframe *audio = &vc4_hdmi->audio.infoframe;
-	union hdmi_infoframe frame;
-
-	memcpy(&frame.audio, audio, sizeof(*audio));
-
-	if (vc4_hdmi->packet_ram_enabled)
-		vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_hdr_infoframe(struct drm_encoder *encoder)
-{
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct drm_connector *connector = &vc4_hdmi->connector;
-	struct drm_connector_state *conn_state = connector->state;
-	union hdmi_infoframe frame;
-
-	lockdep_assert_held(&vc4_hdmi->mutex);
-
-	if (!vc4_hdmi->variant->supports_hdr)
-		return;
-
-	if (!conn_state->hdr_output_metadata)
-		return;
-
-	if (drm_hdmi_infoframe_set_hdr_metadata(&frame.drm, conn_state))
-		return;
-
-	vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder)
-{
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-
-	lockdep_assert_held(&vc4_hdmi->mutex);
-
-	vc4_hdmi_set_avi_infoframe(encoder);
-	vc4_hdmi_set_spd_infoframe(encoder);
-	/*
-	 * If audio was streaming, then we need to reenabled the audio
-	 * infoframe here during encoder_enable.
-	 */
-	if (vc4_hdmi->audio.streaming)
-		vc4_hdmi_set_audio_infoframe(encoder);
-
-	vc4_hdmi_set_hdr_infoframe(encoder);
+	return ret;
 }
 
 #define SCRAMBLING_POLLING_DELAY_MS	1000
@@ -1170,9 +898,8 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 			       struct drm_connector_state *state,
 			       const struct drm_display_mode *mode)
 {
-	struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
+	bool is_lim_range = !state->hdmi.is_full_range;
 	unsigned long flags;
 	u32 csc_ctl;
 	int idx;
@@ -1185,7 +912,7 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 	csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
 				VC4_HD_CSC_CTL_ORDER);
 
-	if (!vc4_hdmi_is_full_range(vc4_hdmi, vc4_state)) {
+	if (is_lim_range) {
 		/* CEA VICs other than #1 requre limited range RGB
 		 * output unless overridden by an AVI infoframe.
 		 * Apply a colorspace conversion to squash 0-255 down
@@ -1408,9 +1135,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 			       const struct drm_display_mode *mode)
 {
 	struct drm_device *drm = vc4_hdmi->connector.dev;
-	struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
-	unsigned int lim_range = vc4_hdmi_is_full_range(vc4_hdmi, vc4_state) ? 0 : 1;
+	unsigned int lim_range = state->hdmi.is_full_range ? 0 : 1;
 	unsigned long flags;
 	const u16 (*csc)[4];
 	u32 if_cfg = 0;
@@ -1425,14 +1150,14 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 
 	spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 
-	switch (vc4_state->output_format) {
-	case VC4_HDMI_OUTPUT_YUV444:
+	switch (state->hdmi.output_format) {
+	case HDMI_COLORSPACE_YUV444:
 		csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range);
 
 		vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, csc);
 		break;
 
-	case VC4_HDMI_OUTPUT_YUV422:
+	case HDMI_COLORSPACE_YUV422:
 		csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range);
 
 		csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD,
@@ -1449,7 +1174,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 		vc5_hdmi_set_csc_coeffs(vc4_hdmi, csc);
 		break;
 
-	case VC4_HDMI_OUTPUT_RGB:
+	case HDMI_COLORSPACE_RGB:
 		if_xbar = 0x354021;
 
 		vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_rgb[lim_range]);
@@ -1538,8 +1263,6 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
 				 const struct drm_display_mode *mode)
 {
 	struct drm_device *drm = vc4_hdmi->connector.dev;
-	const struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
 	bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
 	bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
 	bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
@@ -1591,7 +1314,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
 	HDMI_WRITE(HDMI_VERTB0, vertb_even);
 	HDMI_WRITE(HDMI_VERTB1, vertb);
 
-	switch (vc4_state->output_bpc) {
+	switch (state->hdmi.output_bpc) {
 	case 12:
 		gcp = 6;
 		break;
@@ -1608,7 +1331,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
 	 * YCC422 is always 36-bit and not considered deep colour so
 	 * doesn't signal in GCP.
 	 */
-	if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) {
+	if (state->hdmi.output_format == HDMI_COLORSPACE_YUV422) {
 		gcp = 0;
 	}
 
@@ -1692,10 +1415,8 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
 	struct drm_connector *connector = &vc4_hdmi->connector;
 	struct drm_connector_state *conn_state =
 		drm_atomic_get_new_connector_state(state, connector);
-	struct vc4_hdmi_connector_state *vc4_conn_state =
-		conn_state_to_vc4_hdmi_conn_state(conn_state);
 	const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
-	unsigned long tmds_char_rate = vc4_conn_state->tmds_char_rate;
+	unsigned long tmds_char_rate = conn_state->hdmi.tmds_char_rate;
 	unsigned long bvb_rate, hsm_rate;
 	unsigned long flags;
 	int ret;
@@ -1772,7 +1493,7 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
 	}
 
 	if (vc4_hdmi->variant->phy_init)
-		vc4_hdmi->variant->phy_init(vc4_hdmi, vc4_conn_state);
+		vc4_hdmi->variant->phy_init(vc4_hdmi, conn_state);
 
 	spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 
@@ -1837,7 +1558,8 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
 					      struct drm_atomic_state *state)
 {
 	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct drm_device *drm = vc4_hdmi->connector.dev;
+	struct drm_connector *connector = &vc4_hdmi->connector;
+	struct drm_device *drm = connector->dev;
 	const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
 	struct drm_display_info *display = &vc4_hdmi->connector.display_info;
 	bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
@@ -1903,7 +1625,7 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
 		spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 		vc4_hdmi->packet_ram_enabled = true;
 
-		vc4_hdmi_set_infoframes(encoder);
+		drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
 	}
 
 	vc4_hdmi_recenter_fifo(vc4_hdmi);
@@ -1920,108 +1642,21 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
 					     struct drm_connector_state *conn_state)
 {
 	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(conn_state);
 
 	mutex_lock(&vc4_hdmi->mutex);
 	drm_mode_copy(&vc4_hdmi->saved_adjusted_mode,
 		      &crtc_state->adjusted_mode);
-	vc4_hdmi->output_bpc = vc4_state->output_bpc;
-	vc4_hdmi->output_format = vc4_state->output_format;
+	vc4_hdmi->output_bpc = conn_state->hdmi.output_bpc;
+	vc4_hdmi->output_format = conn_state->hdmi.output_format;
 	mutex_unlock(&vc4_hdmi->mutex);
 }
 
-static bool
-vc4_hdmi_sink_supports_format_bpc(const struct vc4_hdmi *vc4_hdmi,
-				  const struct drm_display_info *info,
-				  const struct drm_display_mode *mode,
-				  unsigned int format, unsigned int bpc)
-{
-	struct drm_device *dev = vc4_hdmi->connector.dev;
-	u8 vic = drm_match_cea_mode(mode);
-
-	if (vic == 1 && bpc != 8) {
-		drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
-		return false;
-	}
-
-	if (!info->is_hdmi &&
-	    (format != VC4_HDMI_OUTPUT_RGB || bpc != 8)) {
-		drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
-		return false;
-	}
-
-	switch (format) {
-	case VC4_HDMI_OUTPUT_RGB:
-		drm_dbg(dev, "RGB Format, checking the constraints.\n");
-
-		if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
-			return false;
-
-		if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {
-			drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
-			return false;
-		}
-
-		if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {
-			drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
-			return false;
-		}
-
-		drm_dbg(dev, "RGB format supported in that configuration.\n");
-
-		return true;
-
-	case VC4_HDMI_OUTPUT_YUV422:
-		drm_dbg(dev, "YUV422 format, checking the constraints.\n");
-
-		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
-			drm_dbg(dev, "Sink doesn't support YUV422.\n");
-			return false;
-		}
-
-		if (bpc != 12) {
-			drm_dbg(dev, "YUV422 only supports 12 bpc.\n");
-			return false;
-		}
-
-		drm_dbg(dev, "YUV422 format supported in that configuration.\n");
-
-		return true;
-
-	case VC4_HDMI_OUTPUT_YUV444:
-		drm_dbg(dev, "YUV444 format, checking the constraints.\n");
-
-		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {
-			drm_dbg(dev, "Sink doesn't support YUV444.\n");
-			return false;
-		}
-
-		if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_30)) {
-			drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
-			return false;
-		}
-
-		if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_36)) {
-			drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
-			return false;
-		}
-
-		drm_dbg(dev, "YUV444 format supported in that configuration.\n");
-
-		return true;
-	}
-
-	return false;
-}
-
 static enum drm_mode_status
-vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
-			     const struct drm_display_mode *mode,
-			     unsigned long long clock)
+vc4_hdmi_connector_clock_valid(const struct drm_connector *connector,
+			       const struct drm_display_mode *mode,
+			       unsigned long long clock)
 {
-	const struct drm_connector *connector = &vc4_hdmi->connector;
-	const struct drm_display_info *info = &connector->display_info;
+	const struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
 
 	if (clock > vc4_hdmi->variant->max_pixel_clock)
@@ -2036,125 +1671,13 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
 	    drm_mode_vrefresh(mode) >= 50)
 		return MODE_CLOCK_HIGH;
 
-	if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
-		return MODE_CLOCK_HIGH;
-
 	return MODE_OK;
 }
 
-static unsigned long long
-vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode,
-				    unsigned int bpc,
-				    enum vc4_hdmi_output_format fmt)
-{
-	unsigned long long clock = mode->clock * 1000ULL;
-
-	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
-		clock = clock * 2;
-
-	if (fmt == VC4_HDMI_OUTPUT_YUV422)
-		bpc = 8;
-
-	clock = clock * bpc;
-	do_div(clock, 8);
-
-	return clock;
-}
-
-static int
-vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi,
-			       struct vc4_hdmi_connector_state *vc4_state,
-			       const struct drm_display_mode *mode,
-			       unsigned int bpc, unsigned int fmt)
-{
-	unsigned long long clock;
-
-	clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt);
-	if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, clock) != MODE_OK)
-		return -EINVAL;
-
-	vc4_state->tmds_char_rate = clock;
-
-	return 0;
-}
-
-static int
-vc4_hdmi_encoder_compute_format(const struct vc4_hdmi *vc4_hdmi,
-				struct vc4_hdmi_connector_state *vc4_state,
-				const struct drm_display_mode *mode,
-				unsigned int bpc)
-{
-	struct drm_device *dev = vc4_hdmi->connector.dev;
-	const struct drm_connector *connector = &vc4_hdmi->connector;
-	const struct drm_display_info *info = &connector->display_info;
-	unsigned int format;
-
-	drm_dbg(dev, "Trying with an RGB output\n");
-
-	format = VC4_HDMI_OUTPUT_RGB;
-	if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) {
-		int ret;
-
-		ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state,
-						     mode, bpc, format);
-		if (!ret) {
-			vc4_state->output_format = format;
-			return 0;
-		}
-	}
-
-	drm_dbg(dev, "Failed, Trying with an YUV422 output\n");
-
-	format = VC4_HDMI_OUTPUT_YUV422;
-	if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) {
-		int ret;
-
-		ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state,
-						     mode, bpc, format);
-		if (!ret) {
-			vc4_state->output_format = format;
-			return 0;
-		}
-	}
-
-	drm_dbg(dev, "Failed. No Format Supported for that bpc count.\n");
-
-	return -EINVAL;
-}
-
-static int
-vc4_hdmi_encoder_compute_config(const struct vc4_hdmi *vc4_hdmi,
-				struct vc4_hdmi_connector_state *vc4_state,
-				const struct drm_display_mode *mode)
-{
-	struct drm_device *dev = vc4_hdmi->connector.dev;
-	struct drm_connector_state *conn_state = &vc4_state->base;
-	unsigned int max_bpc = clamp_t(unsigned int, conn_state->max_bpc, 8, 12);
-	unsigned int bpc;
-	int ret;
-
-	for (bpc = max_bpc; bpc >= 8; bpc -= 2) {
-		drm_dbg(dev, "Trying with a %d bpc output\n", bpc);
-
-		ret = vc4_hdmi_encoder_compute_format(vc4_hdmi, vc4_state,
-						      mode, bpc);
-		if (ret)
-			continue;
-
-		vc4_state->output_bpc = bpc;
-
-		drm_dbg(dev,
-			"Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n",
-			mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
-			vc4_state->output_bpc,
-			vc4_hdmi_output_fmt_str(vc4_state->output_format),
-			vc4_state->tmds_char_rate);
-
-		break;
-	}
-
-	return ret;
-}
+static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs = {
+	.tmds_char_rate_valid	= vc4_hdmi_connector_clock_valid,
+	.write_infoframe	= vc4_hdmi_write_infoframe,
+};
 
 #define WIFI_2_4GHz_CH1_MIN_FREQ	2400000000ULL
 #define WIFI_2_4GHz_CH1_MAX_FREQ	2422000000ULL
@@ -2164,16 +1687,9 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 					 struct drm_connector_state *conn_state)
 {
 	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct drm_connector *connector = &vc4_hdmi->connector;
-	struct drm_connector_state *old_conn_state =
-		drm_atomic_get_old_connector_state(conn_state->state, connector);
-	struct vc4_hdmi_connector_state *old_vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(old_conn_state);
-	struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state);
 	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 	unsigned long long tmds_char_rate = mode->clock * 1000;
 	unsigned long long tmds_bit_rate;
-	int ret;
 
 	if (vc4_hdmi->variant->unsupported_odd_h_timings) {
 		if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
@@ -2209,15 +1725,6 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 		tmds_char_rate = mode->clock * 1000;
 	}
 
-	ret = vc4_hdmi_encoder_compute_config(vc4_hdmi, vc4_state, mode);
-	if (ret)
-		return ret;
-
-	/* vc4_hdmi_encoder_compute_config may have changed output_bpc and/or output_format */
-	if (vc4_state->output_bpc != old_vc4_state->output_bpc ||
-	    vc4_state->output_format != old_vc4_state->output_format)
-		crtc_state->mode_changed = true;
-
 	return 0;
 }
 
@@ -2226,6 +1733,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
 			    const struct drm_display_mode *mode)
 {
 	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
+	unsigned long long rate;
 
 	if (vc4_hdmi->variant->unsupported_odd_h_timings &&
 	    !(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
@@ -2233,7 +1741,8 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
 	     (mode->hsync_end % 2) || (mode->htotal % 2)))
 		return MODE_H_ILLEGAL;
 
-	return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, mode->clock * 1000);
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+	return vc4_hdmi_connector_clock_valid(&vc4_hdmi->connector, mode, rate);
 }
 
 static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
@@ -2425,7 +1934,6 @@ static int vc4_hdmi_audio_startup(struct device *dev, void *data)
 
 static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 {
-	struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
 	struct device *dev = &vc4_hdmi->pdev->dev;
 	unsigned long flags;
 	int ret;
@@ -2433,7 +1941,7 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 	lockdep_assert_held(&vc4_hdmi->mutex);
 
 	vc4_hdmi->audio.streaming = false;
-	ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO, false);
+	ret = vc4_hdmi_stop_packet(vc4_hdmi, HDMI_INFOFRAME_TYPE_AUDIO, false);
 	if (ret)
 		dev_err(dev, "Failed to stop audio infoframe: %d\n", ret);
 
@@ -2524,7 +2032,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
 {
 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
-	struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
+	struct drm_connector *connector = &vc4_hdmi->connector;
 	unsigned int sample_rate = params->sample_rate;
 	unsigned int channels = params->channels;
 	unsigned long flags;
@@ -2601,8 +2109,10 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
 
 	spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 
-	memcpy(&vc4_hdmi->audio.infoframe, &params->cea, sizeof(params->cea));
-	vc4_hdmi_set_audio_infoframe(encoder);
+	ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector,
+								      &params->cea);
+	if (ret)
+		goto out_dev_exit;
 
 out_dev_exit:
 	drm_dev_exit(idx);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 934d5d61485a..b37f1d2c3fe5 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -10,7 +10,6 @@
 
 struct vc4_hdmi;
 struct vc4_hdmi_register;
-struct vc4_hdmi_connector_state;
 
 enum vc4_hdmi_phy_channel {
 	PHY_LANE_0 = 0,
@@ -76,7 +75,7 @@ struct vc4_hdmi_variant {
 
 	/* Callback to initialize the PHY according to the connector state */
 	void (*phy_init)(struct vc4_hdmi *vc4_hdmi,
-			 struct vc4_hdmi_connector_state *vc4_conn_state);
+			 struct drm_connector_state *conn_state);
 
 	/* Callback to disable the PHY */
 	void (*phy_disable)(struct vc4_hdmi *vc4_hdmi);
@@ -110,19 +109,6 @@ struct vc4_hdmi_audio {
 	bool streaming;
 };
 
-enum vc4_hdmi_output_format {
-	VC4_HDMI_OUTPUT_RGB,
-	VC4_HDMI_OUTPUT_YUV422,
-	VC4_HDMI_OUTPUT_YUV444,
-	VC4_HDMI_OUTPUT_YUV420,
-};
-
-enum vc4_hdmi_broadcast_rgb {
-	VC4_HDMI_BROADCAST_RGB_AUTO,
-	VC4_HDMI_BROADCAST_RGB_FULL,
-	VC4_HDMI_BROADCAST_RGB_LIMITED,
-};
-
 /* General HDMI hardware state. */
 struct vc4_hdmi {
 	struct vc4_hdmi_audio audio;
@@ -135,8 +121,6 @@ struct vc4_hdmi {
 
 	struct delayed_work scrambling_work;
 
-	struct drm_property *broadcast_rgb_property;
-
 	struct i2c_adapter *ddc;
 	void __iomem *hdmicore_regs;
 	void __iomem *hd_regs;
@@ -218,16 +202,17 @@ struct vc4_hdmi {
 	bool scdc_enabled;
 
 	/**
-	 * @output_bpc: Copy of @vc4_connector_state.output_bpc for use
-	 * outside of KMS hooks. Protected by @mutex.
+	 * @output_bpc: Copy of @drm_connector_state.hdmi.output_bpc for
+	 * use outside of KMS hooks. Protected by @mutex.
 	 */
 	unsigned int output_bpc;
 
 	/**
-	 * @output_format: Copy of @vc4_connector_state.output_format
-	 * for use outside of KMS hooks. Protected by @mutex.
+	 * @output_format: Copy of
+	 * @drm_connector_state.hdmi.output_format for use outside of
+	 * KMS hooks. Protected by @mutex.
 	 */
-	enum vc4_hdmi_output_format output_format;
+	enum hdmi_colorspace output_format;
 };
 
 #define connector_to_vc4_hdmi(_connector)				\
@@ -240,25 +225,14 @@ encoder_to_vc4_hdmi(struct drm_encoder *encoder)
 	return container_of_const(_encoder, struct vc4_hdmi, encoder);
 }
 
-struct vc4_hdmi_connector_state {
-	struct drm_connector_state	base;
-	unsigned long long		tmds_char_rate;
-	unsigned int 			output_bpc;
-	enum vc4_hdmi_output_format	output_format;
-	enum vc4_hdmi_broadcast_rgb	broadcast_rgb;
-};
-
-#define conn_state_to_vc4_hdmi_conn_state(_state)			\
-	container_of_const(_state, struct vc4_hdmi_connector_state, base)
-
 void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
-		       struct vc4_hdmi_connector_state *vc4_conn_state);
+		       struct drm_connector_state *conn_state);
 void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
 void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
 void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
 
 void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
-		       struct vc4_hdmi_connector_state *vc4_conn_state);
+		       struct drm_connector_state *conn_state);
 void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
 void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
 void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
index ec24999bf96d..1f5507fc7a03 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
@@ -128,7 +128,7 @@
 #define OSCILLATOR_FREQUENCY	54000000
 
 void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
-		       struct vc4_hdmi_connector_state *conn_state)
+		       struct drm_connector_state *conn_state)
 {
 	unsigned long flags;
 
@@ -361,11 +361,11 @@ static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi)
 }
 
 void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
-		       struct vc4_hdmi_connector_state *conn_state)
+		       struct drm_connector_state *conn_state)
 {
 	const struct phy_lane_settings *chan0_settings, *chan1_settings, *chan2_settings, *clock_settings;
 	const struct vc4_hdmi_variant *variant = vc4_hdmi->variant;
-	unsigned long long pixel_freq = conn_state->tmds_char_rate;
+	unsigned long long pixel_freq = conn_state->hdmi.tmds_char_rate;
 	unsigned long long vco_freq;
 	unsigned char word_sel;
 	unsigned long flags;

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:13 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:13 +0100
Subject: [PATCH v6 30/36] drm/vc4: tests: Convert to plane creation helper
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-30-f4bcdc979e6f@kernel.org>

Now that we have a plane create helper for kunit mocked drivers, let's
convert to it in vc4.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 34 +++++++-----------------------
 1 file changed, 8 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
index 973f5f929097..14357db82238 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
@@ -1,43 +1,25 @@
 // SPDX-License-Identifier: GPL-2.0
 
-#include <drm/drm_atomic_state_helper.h>
-#include <drm/drm_fourcc.h>
-#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_kunit_helpers.h>
 #include <drm/drm_plane.h>
 
 #include <kunit/test.h>
 
 #include "vc4_mock.h"
 
-static const struct drm_plane_helper_funcs vc4_dummy_plane_helper_funcs = {
-};
-
-static const struct drm_plane_funcs vc4_dummy_plane_funcs = {
-	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
-	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
-	.reset			= drm_atomic_helper_plane_reset,
-};
-
-static const uint32_t vc4_dummy_plane_formats[] = {
-	DRM_FORMAT_XRGB8888,
-};
-
 struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
 				  enum drm_plane_type type)
 {
 	struct drm_plane *plane;
 
-	plane = __drmm_universal_plane_alloc(drm, sizeof(struct drm_plane), 0,
-						 0,
-						 &vc4_dummy_plane_funcs,
-						 vc4_dummy_plane_formats,
-						 ARRAY_SIZE(vc4_dummy_plane_formats),
-						 NULL,
-						 DRM_PLANE_TYPE_PRIMARY,
-						 NULL);
+	KUNIT_ASSERT_EQ(test, type, DRM_PLANE_TYPE_PRIMARY);
+
+	plane = drm_kunit_helper_create_primary_plane(test, drm,
+						      NULL,
+						      NULL,
+						      NULL, 0,
+						      NULL);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
 
-	drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs);
-
 	return plane;
 }

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:15 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:15 +0100
Subject: [PATCH v6 32/36] drm/sun4i: hdmi: Convert encoder to atomic
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-32-f4bcdc979e6f@kernel.org>

The sun4i_hdmi driver still uses the non-atomic variants of the encoder
hooks, so let's convert to their atomic equivalents.

Acked-by: Sui Jingfeng <sui.jingfeng at linux.dev>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 152375f3de2e..799a26215cc2 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -82,7 +82,8 @@ static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder,
 	return 0;
 }
 
-static void sun4i_hdmi_disable(struct drm_encoder *encoder)
+static void sun4i_hdmi_disable(struct drm_encoder *encoder,
+			       struct drm_atomic_state *state)
 {
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
 	u32 val;
@@ -96,7 +97,8 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder)
 	clk_disable_unprepare(hdmi->tmds_clk);
 }
 
-static void sun4i_hdmi_enable(struct drm_encoder *encoder)
+static void sun4i_hdmi_enable(struct drm_encoder *encoder,
+			      struct drm_atomic_state *state)
 {
 	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
@@ -120,9 +122,10 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder)
 }
 
 static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
+				struct drm_crtc_state *crtc_state,
+				struct drm_connector_state *conn_state)
 {
+	const struct drm_display_mode *mode = &crtc_state->mode;
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
 	unsigned int x, y;
 	u32 val;
@@ -201,9 +204,9 @@ static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
 
 static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
 	.atomic_check	= sun4i_hdmi_atomic_check,
-	.disable	= sun4i_hdmi_disable,
-	.enable		= sun4i_hdmi_enable,
-	.mode_set	= sun4i_hdmi_mode_set,
+	.atomic_disable	= sun4i_hdmi_disable,
+	.atomic_enable	= sun4i_hdmi_enable,
+	.atomic_mode_set	= sun4i_hdmi_mode_set,
 	.mode_valid	= sun4i_hdmi_mode_valid,
 };
 

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:16 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:16 +0100
Subject: [PATCH v6 33/36] drm/sun4i: hdmi: Move mode_set into enable
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-33-f4bcdc979e6f@kernel.org>

We're not doing anything special in atomic_mode_set so we can simply
merge it into atomic_enable.

Acked-by: Sui Jingfeng <sui.jingfeng at linux.dev>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 38 +++++++++++++---------------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 799a26215cc2..bae69d696765 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -103,33 +103,11 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
 	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
 	struct drm_display_info *display = &hdmi->connector.display_info;
+	unsigned int x, y;
 	u32 val = 0;
 
 	DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
 
-	clk_prepare_enable(hdmi->tmds_clk);
-
-	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
-	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
-	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
-	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
-
-	val = SUN4I_HDMI_VID_CTRL_ENABLE;
-	if (display->is_hdmi)
-		val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE;
-
-	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
-}
-
-static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
-				struct drm_crtc_state *crtc_state,
-				struct drm_connector_state *conn_state)
-{
-	const struct drm_display_mode *mode = &crtc_state->mode;
-	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
-	unsigned int x, y;
-	u32 val;
-
 	clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
 	clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
 
@@ -181,6 +159,19 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
 		val |= SUN4I_HDMI_VID_TIMING_POL_VSYNC;
 
 	writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG);
+
+	clk_prepare_enable(hdmi->tmds_clk);
+
+	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
+	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
+	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
+	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
+
+	val = SUN4I_HDMI_VID_CTRL_ENABLE;
+	if (display->is_hdmi)
+		val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE;
+
+	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
 }
 
 static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
@@ -206,7 +197,6 @@ static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
 	.atomic_check	= sun4i_hdmi_atomic_check,
 	.atomic_disable	= sun4i_hdmi_disable,
 	.atomic_enable	= sun4i_hdmi_enable,
-	.atomic_mode_set	= sun4i_hdmi_mode_set,
 	.mode_valid	= sun4i_hdmi_mode_valid,
 };
 

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:17 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:17 +0100
Subject: [PATCH v6 34/36] drm/sun4i: hdmi: Switch to container_of_const
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-34-f4bcdc979e6f@kernel.org>

container_of_const() allows to preserve the pointer constness and is
thus more flexible than inline functions.

Let's switch all our instances of container_of() to container_of_const().

Reviewed-by: Sui Jingfeng <sui.jingfeng at linux.dev>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index bae69d696765..c276d984da6b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -30,19 +30,11 @@
 #include "sun4i_drv.h"
 #include "sun4i_hdmi.h"
 
-static inline struct sun4i_hdmi *
-drm_encoder_to_sun4i_hdmi(struct drm_encoder *encoder)
-{
-	return container_of(encoder, struct sun4i_hdmi,
-			    encoder);
-}
+#define drm_encoder_to_sun4i_hdmi(e)		\
+	container_of_const(e, struct sun4i_hdmi, encoder)
 
-static inline struct sun4i_hdmi *
-drm_connector_to_sun4i_hdmi(struct drm_connector *connector)
-{
-	return container_of(connector, struct sun4i_hdmi,
-			    connector);
-}
+#define drm_connector_to_sun4i_hdmi(c)		\
+	container_of_const(c, struct sun4i_hdmi, connector)
 
 static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
 					   struct drm_display_mode *mode)

-- 
2.43.0



From mripard at kernel.org  Mon Feb 12 05:13:18 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:18 +0100
Subject: [PATCH v6 35/36] drm/sun4i: hdmi: Consolidate atomic_check and
 mode_valid
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-35-f4bcdc979e6f@kernel.org>

atomic_check and mode_valid do not check for the same things which can
lead to surprising result if the userspace commits a mode that didn't go
through mode_valid. Let's merge the two implementations into a function
called by both.

Acked-by: Sui Jingfeng <sui.jingfeng at linux.dev>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 74 +++++++++++++++++++++-------------
 1 file changed, 47 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index c276d984da6b..b7cf369b1906 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -62,18 +62,6 @@ static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
 	return 0;
 }
 
-static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder,
-				   struct drm_crtc_state *crtc_state,
-				   struct drm_connector_state *conn_state)
-{
-	struct drm_display_mode *mode = &crtc_state->mode;
-
-	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
-		return -EINVAL;
-
-	return 0;
-}
-
 static void sun4i_hdmi_disable(struct drm_encoder *encoder,
 			       struct drm_atomic_state *state)
 {
@@ -166,31 +154,61 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
 	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
 }
 
-static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
-					const struct drm_display_mode *mode)
+static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
+	.atomic_disable	= sun4i_hdmi_disable,
+	.atomic_enable	= sun4i_hdmi_enable,
+};
+
+static enum drm_mode_status
+sun4i_hdmi_connector_clock_valid(const struct drm_connector *connector,
+				 const struct drm_display_mode *mode,
+				 unsigned long long clock)
 {
-	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
-	unsigned long rate = mode->clock * 1000;
-	unsigned long diff = rate / 200; /* +-0.5% allowed by HDMI spec */
+	const struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
+	unsigned long diff = clock / 200; /* +-0.5% allowed by HDMI spec */
 	long rounded_rate;
 
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		return MODE_BAD;
+
 	/* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */
-	if (rate > 165000000)
+	if (clock > 165000000)
 		return MODE_CLOCK_HIGH;
-	rounded_rate = clk_round_rate(hdmi->tmds_clk, rate);
+
+	rounded_rate = clk_round_rate(hdmi->tmds_clk, clock);
 	if (rounded_rate > 0 &&
-	    max_t(unsigned long, rounded_rate, rate) -
-	    min_t(unsigned long, rounded_rate, rate) < diff)
+	    max_t(unsigned long, rounded_rate, clock) -
+	    min_t(unsigned long, rounded_rate, clock) < diff)
 		return MODE_OK;
+
 	return MODE_NOCLOCK;
 }
 
-static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
-	.atomic_check	= sun4i_hdmi_atomic_check,
-	.atomic_disable	= sun4i_hdmi_disable,
-	.atomic_enable	= sun4i_hdmi_enable,
-	.mode_valid	= sun4i_hdmi_mode_valid,
-};
+static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector,
+					     struct drm_atomic_state *state)
+{
+	struct drm_connector_state *conn_state =
+		drm_atomic_get_new_connector_state(state, connector);
+	struct drm_crtc *crtc = conn_state->crtc;
+	struct drm_crtc_state *crtc_state = crtc->state;
+	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+	enum drm_mode_status status;
+
+	status = sun4i_hdmi_connector_clock_valid(connector, mode,
+						  mode->clock * 1000);
+	if (status != MODE_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static enum drm_mode_status
+sun4i_hdmi_connector_mode_valid(struct drm_connector *connector,
+				struct drm_display_mode *mode)
+{
+	return sun4i_hdmi_connector_clock_valid(connector, mode,
+						mode->clock * 1000);
+}
 
 static int sun4i_hdmi_get_modes(struct drm_connector *connector)
 {
@@ -236,6 +254,8 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev)
 }
 
 static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = {
+	.atomic_check	= sun4i_hdmi_connector_atomic_check,
+	.mode_valid	= sun4i_hdmi_connector_mode_valid,
 	.get_modes	= sun4i_hdmi_get_modes,
 };
 

-- 
2.43.0



From david at redhat.com  Mon Feb 12 05:15:02 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 14:15:02 +0100
Subject: [PATCH v5 18/25] arm64/mm: Split __flush_tlb_range() to elide
 trailing DSB
In-Reply-To: <1ef4c737-0926-424c-9698-794c23370b74@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-19-ryan.roberts@arm.com>
 <9e1d793a-02c9-4dbb-a6d4-1e1c0c42638c@redhat.com>
 <1ef4c737-0926-424c-9698-794c23370b74@arm.com>
Message-ID: <608feac1-8cd6-48c2-87ab-688fb9c0bda4@redhat.com>

On 12.02.24 14:05, Ryan Roberts wrote:
> On 12/02/2024 12:44, David Hildenbrand wrote:
>> On 02.02.24 09:07, Ryan Roberts wrote:
>>> Split __flush_tlb_range() into __flush_tlb_range_nosync() +
>>> __flush_tlb_range(), in the same way as the existing flush_tlb_page()
>>> arrangement. This allows calling __flush_tlb_range_nosync() to elide the
>>> trailing DSB. Forthcoming "contpte" code will take advantage of this
>>> when clearing the young bit from a contiguous range of ptes.
>>>
>>> Tested-by: John Hubbard <jhubbard at nvidia.com>
>>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>>> ---
>>>  ? arch/arm64/include/asm/tlbflush.h | 13 +++++++++++--
>>>  ? 1 file changed, 11 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/tlbflush.h
>>> b/arch/arm64/include/asm/tlbflush.h
>>> index 79e932a1bdf8..50a765917327 100644
>>> --- a/arch/arm64/include/asm/tlbflush.h
>>> +++ b/arch/arm64/include/asm/tlbflush.h
>>> @@ -422,7 +422,7 @@ do {??????????????????????????????????? \
>>>  ? #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \
>>>  ????? __flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false,
>>> kvm_lpa2_is_enabled());
>>>  ? -static inline void __flush_tlb_range(struct vm_area_struct *vma,
>>> +static inline void __flush_tlb_range_nosync(struct vm_area_struct *vma,
>>>  ?????????????????????? unsigned long start, unsigned long end,
>>>  ?????????????????????? unsigned long stride, bool last_level,
>>>  ?????????????????????? int tlb_level)
>>> @@ -456,10 +456,19 @@ static inline void __flush_tlb_range(struct
>>> vm_area_struct *vma,
>>>  ????????? __flush_tlb_range_op(vae1is, start, pages, stride, asid,
>>>  ?????????????????????? tlb_level, true, lpa2_is_enabled());
>>>  ? -??? dsb(ish);
>>>  ????? mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
>>>  ? }
>>>  ? +static inline void __flush_tlb_range(struct vm_area_struct *vma,
>>> +???????????????????? unsigned long start, unsigned long end,
>>> +???????????????????? unsigned long stride, bool last_level,
>>> +???????????????????? int tlb_level)
>>> +{
>>> +??? __flush_tlb_range_nosync(vma, start, end, stride,
>>> +???????????????? last_level, tlb_level);
>>> +??? dsb(ish);
>>> +}
>>> +
>>>  ? static inline void flush_tlb_range(struct vm_area_struct *vma,
>>>  ???????????????????? unsigned long start, unsigned long end)
>>>  ? {
>>
>> You're now calling dsb() after mmu_notifier_arch_invalidate_secondary_tlbs().
>>
>>
>> In flush_tlb_mm(), we have the order
>>
>>  ????dsb(ish);
>>  ????mmu_notifier_arch_invalidate_secondary_tlbs()
>>
>> In flush_tlb_page(), we have the effective order:
>>
>>  ????mmu_notifier_arch_invalidate_secondary_tlbs()
>>  ????dsb(ish);
>>
>> In flush_tlb_range(), we used to have the order:
>>
>>  ????dsb(ish);
>>  ????mmu_notifier_arch_invalidate_secondary_tlbs();
>>
>>
>> So I *suspect* having that DSB before
>> mmu_notifier_arch_invalidate_secondary_tlbs() is fine. Hopefully, nothing in
>> there relies on that placement.
> 
> Will spotted this against v3. My argument was that I was following the existing
> pattern in flush_tlb_page(). Apparently that is not correct and needs changing,
> but the conclusion was to leave my change as is for now, since it is consistent
> and change them at a later date together.

Good, I think you should add a few words to the patch description 
("ordering might be incorrect, but is in-line with __flush_tlb_page()"; 
will be resolved separately).

-- 
Cheers,

David / dhildenb



From mripard at kernel.org  Mon Feb 12 05:13:19 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 14:13:19 +0100
Subject: [PATCH v6 36/36] drm/sun4i: hdmi: Switch to HDMI connector
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
Message-ID: <20240212-kms-hdmi-connector-state-v6-36-f4bcdc979e6f@kernel.org>

The new HDMI connector infrastructure allows to remove some boilerplate,
especially to generate infoframes. Let's switch to it.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 80 ++++++++++++++++++++++------------
 1 file changed, 51 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index b7cf369b1906..8a9106a39f23 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -36,30 +36,24 @@
 #define drm_connector_to_sun4i_hdmi(c)		\
 	container_of_const(c, struct sun4i_hdmi, connector)
 
-static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
-					   struct drm_display_mode *mode)
+static int sun4i_hdmi_write_infoframe(struct drm_connector *connector,
+				      enum hdmi_infoframe_type type,
+				      const u8 *buffer, size_t len)
 {
-	struct hdmi_avi_infoframe frame;
-	u8 buffer[17];
-	int i, ret;
+	struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
+	int i;
 
-	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
-						       &hdmi->connector, mode);
-	if (ret < 0) {
-		DRM_ERROR("Failed to get infoframes from mode\n");
-		return ret;
+	if (type != HDMI_INFOFRAME_TYPE_AVI) {
+		drm_err(connector->dev,
+			"Unsupported infoframe type: %u\n", type);
+		return 0;
 	}
 
-	ret = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
-	if (ret < 0) {
-		DRM_ERROR("Failed to pack infoframes\n");
-		return ret;
-	}
-
-	for (i = 0; i < sizeof(buffer); i++)
+	for (i = 0; i < len; i++)
 		writeb(buffer[i], hdmi->base + SUN4I_HDMI_AVI_INFOFRAME_REG(i));
 
 	return 0;
+
 }
 
 static void sun4i_hdmi_disable(struct drm_encoder *encoder,
@@ -82,14 +76,18 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
 {
 	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
-	struct drm_display_info *display = &hdmi->connector.display_info;
+	struct drm_connector *connector = &hdmi->connector;
+	struct drm_display_info *display = &connector->display_info;
+	struct drm_connector_state *conn_state =
+		drm_atomic_get_new_connector_state(state, connector);
+	unsigned long long tmds_rate = conn_state->hdmi.tmds_char_rate;
 	unsigned int x, y;
 	u32 val = 0;
 
 	DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
 
-	clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
-	clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
+	clk_set_rate(hdmi->mod_clk, tmds_rate);
+	clk_set_rate(hdmi->tmds_clk, tmds_rate);
 
 	/* Set input sync enable */
 	writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC,
@@ -142,7 +140,8 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
 
 	clk_prepare_enable(hdmi->tmds_clk);
 
-	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
+	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
+
 	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
 	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
 	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
@@ -195,7 +194,7 @@ static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector,
 	enum drm_mode_status status;
 
 	status = sun4i_hdmi_connector_clock_valid(connector, mode,
-						  mode->clock * 1000);
+						  conn_state->hdmi.tmds_char_rate);
 	if (status != MODE_OK)
 		return -EINVAL;
 
@@ -206,8 +205,11 @@ static enum drm_mode_status
 sun4i_hdmi_connector_mode_valid(struct drm_connector *connector,
 				struct drm_display_mode *mode)
 {
-	return sun4i_hdmi_connector_clock_valid(connector, mode,
-						mode->clock * 1000);
+	unsigned long long rate =
+		drm_connector_hdmi_compute_mode_clock(mode, 8,
+						      HDMI_COLORSPACE_RGB);
+
+	return sun4i_hdmi_connector_clock_valid(connector, mode, rate);
 }
 
 static int sun4i_hdmi_get_modes(struct drm_connector *connector)
@@ -253,6 +255,11 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev)
 	return ddc;
 }
 
+static const struct drm_connector_hdmi_funcs sun4i_hdmi_hdmi_connector_funcs = {
+	.tmds_char_rate_valid	= sun4i_hdmi_connector_clock_valid,
+	.write_infoframe	= sun4i_hdmi_write_infoframe,
+};
+
 static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = {
 	.atomic_check	= sun4i_hdmi_connector_atomic_check,
 	.mode_valid	= sun4i_hdmi_connector_mode_valid,
@@ -274,11 +281,17 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	return connector_status_connected;
 }
 
+static void sun4i_hdmi_connector_reset(struct drm_connector *connector)
+{
+	drm_atomic_helper_connector_reset(connector);
+	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
+}
+
 static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
 	.detect			= sun4i_hdmi_connector_detect,
 	.fill_modes		= drm_helper_probe_single_connector_modes,
 	.destroy		= drm_connector_cleanup,
-	.reset			= drm_atomic_helper_connector_reset,
+	.reset			= sun4i_hdmi_connector_reset,
 	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
 };
@@ -637,10 +650,19 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &sun4i_hdmi_connector_helper_funcs);
-	ret = drm_connector_init_with_ddc(drm, &hdmi->connector,
-					  &sun4i_hdmi_connector_funcs,
-					  DRM_MODE_CONNECTOR_HDMIA,
-					  hdmi->ddc_i2c);
+	ret = drmm_connector_hdmi_init(drm, &hdmi->connector,
+				       /*
+					* NOTE: Those are likely to be
+					* wrong, but I couldn't find the
+					* actual ones in the BSP.
+					*/
+				       "AW", "HDMI",
+				       &sun4i_hdmi_connector_funcs,
+				       &sun4i_hdmi_hdmi_connector_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       hdmi->ddc_i2c,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
 	if (ret) {
 		dev_err(dev,
 			"Couldn't initialise the HDMI connector\n");

-- 
2.43.0



From robh at kernel.org  Mon Feb 12 05:16:31 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 12 Feb 2024 07:16:31 -0600
Subject: [PATCH v1 02/14] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240210012114.489102-3-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-3-sre@kernel.org>
Message-ID: <20240212131631.GA13910-robh@kernel.org>

On Sat, Feb 10, 2024 at 02:18:06AM +0100, Sebastian Reichel wrote:
> Convert the i.MX  Wireless External Interface Module binding to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../devicetree/bindings/bus/fsl,imx-weim.yaml | 225 ++++++++++++++++++
>  .../devicetree/bindings/bus/imx-weim.txt      | 117 ---------
>  2 files changed, 225 insertions(+), 117 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
>  delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
> 
> diff --git a/Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml b/Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
> new file mode 100644
> index 000000000000..3d27bdaef304
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/bus/fsl,imx-weim.yaml
> @@ -0,0 +1,225 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/bus/fsl,imx-weim.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: i.MX Wireless External Interface Module (WEIM)
> +
> +maintainers:
> +  - Shawn Guo <shawnguo at kernel.org>
> +  - Sascha Hauer <s.hauer at pengutronix.de>
> +
> +description:
> +  The term "wireless" does not imply that the WEIM is literally an interface
> +  without wires. It simply means that this module was originally designed for
> +  wireless and mobile applications that use low-power technology. The actual
> +  devices are instantiated from the child nodes of a WEIM node.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - enum:
> +          - fsl,imx1-weim
> +          - fsl,imx27-weim
> +          - fsl,imx50-weim
> +          - fsl,imx51-weim
> +          - fsl,imx6q-weim
> +      - items:
> +          - enum:
> +              - fsl,imx31-weim
> +              - fsl,imx35-weim
> +          - const: fsl,imx27-weim
> +      - items:
> +          - enum:
> +              - fsl,imx6sx-weim
> +              - fsl,imx6ul-weim
> +          - const: fsl,imx6q-weim
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  '#address-cells':
> +    const: 2
> +
> +  '#size-cells':
> +    const: 1
> +
> +  ranges: true
> +
> +  fsl,weim-cs-gpr:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: |
> +      Phandle to the system General Purpose Register controller that contains
> +      WEIM CS GPR register, e.g. IOMUXC_GPR1 on i.MX6Q. IOMUXC_GPR1[11:0]
> +      should be set up as one of the following 4 possible values depending on
> +      the CS space configuration.
> +
> +      IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
> +      ---------------------------------------------
> +              05          128M     0M     0M     0M
> +              033          64M    64M     0M     0M
> +              0113         64M    32M    32M     0M
> +              01111        32M    32M    32M    32M
> +
> +      In case that the property is absent, the reset value or what bootloader
> +      sets up in IOMUXC_GPR1[11:0] will be used.
> +
> +  fsl,burst-clk-enable:
> +    type: boolean
> +    description:
> +      The presence of this property indicates that the weim bus should operate
> +      in Burst Clock Mode.
> +
> +  fsl,continuous-burst-clk:
> +    type: boolean
> +    description:
> +      Make Burst Clock to output continuous clock. Without this option Burst
> +      Clock will output clock only when necessary.
> +
> +patternProperties:
> +  "^.*@[0-7],[0-9a-f]+$":
> +    description: Devices attached to chip selects are represented as subnodes.
> +    type: object
> +    additionalProperties: true
> +    properties:
> +      fsl,weim-cs-timing:
> +        $ref: /schemas/types.yaml#/definitions/uint32-array
> +        description:
> +          Timing values for the child node.
> +    required:
> +      - fsl,weim-cs-timing

This needs to go in its own schema doc and then added to 
memory-controllers/mc-peripheral-props.yaml

We should probably also move this binding to memory-controllers/


> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          not:
> +            contains:
> +              enum:
> +                - fsl,imx50-weim
> +                - fsl,imx6q-weim
> +    then:
> +      properties:
> +        fsl,weim-cs-gpr: false
> +        fsl,burst-clk-enable: false
> +  - if:
> +      properties:
> +        fsl,burst-clk-enable: false
> +    then:
> +      properties:
> +        fsl,continuous-burst-clk: false
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: fsl,imx1-weim
> +    then:
> +      patternProperties:
> +        "^.*@[0-7],[0-9a-f]+$":
> +          properties:
> +            fsl,weim-cs-timing:
> +              items:
> +                items:
> +                  - description: CSxU
> +                  - description: CSxL
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - fsl,imx27-weim
> +              - fsl,imx31-weim
> +              - fsl,imx35-weim
> +    then:
> +      patternProperties:
> +        "^.*@[0-7],[0-9a-f]+$":
> +          properties:
> +            fsl,weim-cs-timing:
> +              items:
> +                items:
> +                  - description: CSCRxU
> +                  - description: CSCRxL
> +                  - description: CSCRxA
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - fsl,imx50-weim
> +              - fsl,imx51-weim
> +              - fsl,imx6q-weim
> +              - fsl,imx6sx-weim
> +              - fsl,imx6ul-weim
> +    then:
> +      patternProperties:
> +        "^.*@[0-7],[0-9a-f]+$":
> +          properties:
> +            fsl,weim-cs-timing:
> +              items:
> +                items:
> +                  - description: CSxGCR1
> +                  - description: CSxGCR2
> +                  - description: CSxRCR1
> +                  - description: CSxRCR2
> +                  - description: CSxWCR1
> +                  - description: CSxWCR2
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - '#address-cells'
> +  - '#size-cells'
> +  - ranges
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    weim at 21b8000 {

bus or external-bus

> +        compatible = "fsl,imx6q-weim";
> +        reg = <0x021b8000 0x4000>;
> +        clocks = <&clks 196>;
> +        #address-cells = <2>;
> +        #size-cells = <1>;
> +        ranges = <0 0 0x08000000 0x08000000>;
> +        fsl,weim-cs-gpr = <&gpr>;
> +
> +        nor at 0,0 {
> +            compatible = "cfi-flash";
> +            reg = <0 0 0x02000000>;
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +            bank-width = <2>;
> +            fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
> +            0x0000c000 0x1404a38e 0x00000000>;
> +        };
> +    };
> +  - |
> +    weim at 21b8000 {
> +        compatible = "fsl,imx6q-weim";
> +        reg = <0x021b8000 0x4000>;
> +        clocks = <&clks 196>;
> +        #address-cells = <2>;
> +        #size-cells = <1>;
> +        ranges = <0 0 0x08000000 0x02000000
> +                  1 0 0x0a000000 0x02000000
> +                  2 0 0x0c000000 0x02000000
> +                  3 0 0x0e000000 0x02000000>;
> +        fsl,weim-cs-gpr = <&gpr>;
> +
> +        acme at 0,0 {
> +            compatible = "acme,whatever";

Real bindings only please.

> +            reg = <0 0 0x100>, <0 0x400000 0x800>,
> +                  <1 0x400000 0x800>;
> +            fsl,weim-cs-timing = <0x024400b1 0x00001010 0x20081100
> +                                  0x00000000 0xa0000240 0x00000000>;
> +        };
> +    };


From david at redhat.com  Mon Feb 12 05:16:30 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 14:16:30 +0100
Subject: [PATCH v7 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240211174705.31992-5-ankita@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
 <20240211174705.31992-5-ankita@nvidia.com>
Message-ID: <6ab142f0-bf66-4611-915d-938d58a277d3@redhat.com>

On 11.02.24 18:47, ankita at nvidia.com wrote:
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> The code to map the MMIO in S2 as NormalNC is enabled when conveyed
> that the device is WC safe using a new flag VM_ALLOW_ANY_UNCACHED.
> 
> Make vfio-pci set the VM_ALLOW_ANY_UNCACHED flag.
> 
> This could be extended to other devices in the future once that
> is deemed safe.

Maybe add some more details how one could make a decision whether it 
would be safe (either here or in patch #2).

> 
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Acked-by: Jason Gunthorpe <jgg at nvidia.com>
> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> ---
>   drivers/vfio/pci/vfio_pci_core.c | 6 +++++-
>   1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 1cbc990d42e0..eba2146202f9 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -1862,8 +1862,12 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
>   	/*
>   	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
>   	 * change vm_flags within the fault handler.  Set them now.
> +	 *
> +	 * Set an additional flag VM_ALLOW_ANY_UNCACHED to convey kvm that
> +	 * the device is wc safe.
>   	 */
> -	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
> +	vm_flags_set(vma, VM_ALLOW_ANY_UNCACHED | VM_IO | VM_PFNMAP |
> +			VM_DONTEXPAND | VM_DONTDUMP);
>   	vma->vm_ops = &vfio_pci_mmap_ops;
>   
>   	return 0;

Reviewed-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From krzysztof.kozlowski at linaro.org  Mon Feb 12 05:20:50 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 14:20:50 +0100
Subject: [PATCH] arm64: dts: exynos: gs101: add stable i2c aliases for
 gs101-oriole
In-Reply-To: <fbd335e81928c1c3cd63ee44514cf95a23dafb6f.camel@linaro.org>
References: <20240130233700.2287442-1-andre.draszik@linaro.org>
 <170737972037.52344.9107022607101399076.b4-ty@linaro.org>
 <5972b6a4ae8669e2a9e872278b740b182217906b.camel@linaro.org>
 <dce39e15-32a8-482c-8751-af4a133f82d2@linaro.org>
 <c16c1f18a8c6f33a608618d4ccf7d8c8dbb6f88b.camel@linaro.org>
 <67a6564a-00bb-461d-b7eb-ca169df6d251@linaro.org>
 <0ad3082c50e21a74de41ca9908bd53b72e1f1a9c.camel@linaro.org>
 <b6ec1d0e-e35c-4917-871b-049efcb2ea22@linaro.org>
 <fbd335e81928c1c3cd63ee44514cf95a23dafb6f.camel@linaro.org>
Message-ID: <38ba0c8c-8d82-4bff-bf80-ce30ba04c5ef@linaro.org>

On 12/02/2024 13:38, Andr? Draszik wrote:
> On Mon, 2024-02-12 at 13:07 +0100, Krzysztof Kozlowski wrote:
>> On 12/02/2024 12:52, Andr? Draszik wrote:
>>> As I said above, we won't care if downstream changes again at that stage, so
>>> no, I wouldn't plan on changing again.
>>
>> Then I am lost. What stage are you thinking? What differs between now
>> and let's say 1 month for the GS101 which was released more than three
>> years ago?
> 
> The idea was to make the initial transition to using upstream easier,
> hence we added the same aliases as downstream (at the time).
> Given the transition is not happening right now, we might as well hold
> off with the aliases and add them later, with whatever downstream will
> be using at that time.

Hm ok, I just did not understand what are the criteria of choosing point
in time when you take the aliases from dowstream.

> 
> If in the future somebody downstream decides 'I want this' (changed again),
> why should upstream care at that stage?
> 
> Again, this patch was just trying to make initial transition easier, do you
> have a better recommendation?
> 
>> BTW, the aliases I see in downstream DTS (gs101-usi.dtsi) - since
>> beginning up to Android 14 are:
>>
>> ??????????????? hsi2c8 = &hsi2c_8;
>> ??????????????? hsi2c9 = &hsi2c_9;
>> ??????????????? hsi2c10 = &hsi2c_10;
>> ??????????????? hsi2c11 = &hsi2c_11;
>> ??????????????? hsi2c12 = &hsi2c_12;
>>
>> They were set like this in 2020 and never changed afterwards.
> 
> Those were incorrect and didn't actually work as intended, here's a
> better place to look:
> 
> https://android.googlesource.com/kernel/google-modules/raviole-device/+log/refs/heads/android-gs-raviole-mainline
> and
> https://android.googlesource.com/kernel/google-modules/raviole-device/+/9864593c894da90cd8b631ab57f15c25f4e11465%5E%21/

Thanks, so it's like Qualcomm - DTS separate from the kernel, although
here a bit confusing because partially overlapping.


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Mon Feb 12 05:22:43 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 14:22:43 +0100
Subject: [PATCH] arm64: dts: exynos: gs101: add stable i2c aliases for
 gs101-oriole
In-Reply-To: <20240130233700.2287442-1-andre.draszik@linaro.org>
References: <20240130233700.2287442-1-andre.draszik@linaro.org>
Message-ID: <27b85493-62d6-49b2-a6a8-c656c534d697@linaro.org>

On 31/01/2024 00:37, Andr? Draszik wrote:
> Now that we have more than i2c interface, add aliases to ensure
> deterministic bus number assignment.
> 
> So as to keep compatibility with existing Pixel userspace builds, use
> the same bus numbers for hsi2c_8 and hsi2c_12 as the downstream
> drivers with the intention to eventually add all the earlier busses as
> well.
> 
> Suggested-by: Will McVicker <willmcvicker at google.com>
> Signed-off-by: Andr? Draszik <andre.draszik at linaro.org>
> 
> ---
> Note, this patch should only be applied after series
> "[PATCH v3 0/7] gs101 oriole: peripheral block 1 (peric1) and i2c12 support"
> https://lore.kernel.org/all/20240129174703.1175426-1-andre.draszik at linaro.org/

Dropped on request.

Best regards,
Krzysztof



From ryan.roberts at arm.com  Mon Feb 12 05:27:00 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 13:27:00 +0000
Subject: [PATCH v5 18/25] arm64/mm: Split __flush_tlb_range() to elide
 trailing DSB
In-Reply-To: <608feac1-8cd6-48c2-87ab-688fb9c0bda4@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-19-ryan.roberts@arm.com>
 <9e1d793a-02c9-4dbb-a6d4-1e1c0c42638c@redhat.com>
 <1ef4c737-0926-424c-9698-794c23370b74@arm.com>
 <608feac1-8cd6-48c2-87ab-688fb9c0bda4@redhat.com>
Message-ID: <e19ba38c-8935-47be-be2a-1920b09034c8@arm.com>

On 12/02/2024 13:15, David Hildenbrand wrote:
> On 12.02.24 14:05, Ryan Roberts wrote:
>> On 12/02/2024 12:44, David Hildenbrand wrote:
>>> On 02.02.24 09:07, Ryan Roberts wrote:
>>>> Split __flush_tlb_range() into __flush_tlb_range_nosync() +
>>>> __flush_tlb_range(), in the same way as the existing flush_tlb_page()
>>>> arrangement. This allows calling __flush_tlb_range_nosync() to elide the
>>>> trailing DSB. Forthcoming "contpte" code will take advantage of this
>>>> when clearing the young bit from a contiguous range of ptes.
>>>>
>>>> Tested-by: John Hubbard <jhubbard at nvidia.com>
>>>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>>>> ---
>>>> ?? arch/arm64/include/asm/tlbflush.h | 13 +++++++++++--
>>>> ?? 1 file changed, 11 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/include/asm/tlbflush.h
>>>> b/arch/arm64/include/asm/tlbflush.h
>>>> index 79e932a1bdf8..50a765917327 100644
>>>> --- a/arch/arm64/include/asm/tlbflush.h
>>>> +++ b/arch/arm64/include/asm/tlbflush.h
>>>> @@ -422,7 +422,7 @@ do {??????????????????????????????????? \
>>>> ?? #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \
>>>> ?????? __flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false,
>>>> kvm_lpa2_is_enabled());
>>>> ?? -static inline void __flush_tlb_range(struct vm_area_struct *vma,
>>>> +static inline void __flush_tlb_range_nosync(struct vm_area_struct *vma,
>>>> ??????????????????????? unsigned long start, unsigned long end,
>>>> ??????????????????????? unsigned long stride, bool last_level,
>>>> ??????????????????????? int tlb_level)
>>>> @@ -456,10 +456,19 @@ static inline void __flush_tlb_range(struct
>>>> vm_area_struct *vma,
>>>> ?????????? __flush_tlb_range_op(vae1is, start, pages, stride, asid,
>>>> ??????????????????????? tlb_level, true, lpa2_is_enabled());
>>>> ?? -??? dsb(ish);
>>>> ?????? mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
>>>> ?? }
>>>> ?? +static inline void __flush_tlb_range(struct vm_area_struct *vma,
>>>> +???????????????????? unsigned long start, unsigned long end,
>>>> +???????????????????? unsigned long stride, bool last_level,
>>>> +???????????????????? int tlb_level)
>>>> +{
>>>> +??? __flush_tlb_range_nosync(vma, start, end, stride,
>>>> +???????????????? last_level, tlb_level);
>>>> +??? dsb(ish);
>>>> +}
>>>> +
>>>> ?? static inline void flush_tlb_range(struct vm_area_struct *vma,
>>>> ????????????????????? unsigned long start, unsigned long end)
>>>> ?? {
>>>
>>> You're now calling dsb() after mmu_notifier_arch_invalidate_secondary_tlbs().
>>>
>>>
>>> In flush_tlb_mm(), we have the order
>>>
>>> ?????dsb(ish);
>>> ?????mmu_notifier_arch_invalidate_secondary_tlbs()
>>>
>>> In flush_tlb_page(), we have the effective order:
>>>
>>> ?????mmu_notifier_arch_invalidate_secondary_tlbs()
>>> ?????dsb(ish);
>>>
>>> In flush_tlb_range(), we used to have the order:
>>>
>>> ?????dsb(ish);
>>> ?????mmu_notifier_arch_invalidate_secondary_tlbs();
>>>
>>>
>>> So I *suspect* having that DSB before
>>> mmu_notifier_arch_invalidate_secondary_tlbs() is fine. Hopefully, nothing in
>>> there relies on that placement.
>>
>> Will spotted this against v3. My argument was that I was following the existing
>> pattern in flush_tlb_page(). Apparently that is not correct and needs changing,
>> but the conclusion was to leave my change as is for now, since it is consistent
>> and change them at a later date together.
> 
> Good, I think you should add a few words to the patch description ("ordering
> might be incorrect, but is in-line with __flush_tlb_page()"; will be resolved
> separately).
> 

ACK, will do. Thanks!



From dmitry.baryshkov at linaro.org  Mon Feb 12 05:27:34 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 12 Feb 2024 15:27:34 +0200
Subject: [PATCH 2/2] arm64: dts: qcom: qcm6490-idp: add display and panel
In-Reply-To: <7932ccbb-3b41-49e2-bb88-9c2633002a0d@quicinc.com>
References: <20240116094935.9988-1-quic_riteshk@quicinc.com>
 <20240116094935.9988-3-quic_riteshk@quicinc.com> <20a8efd1-e243-434e-8f75-aa786ac8014f@linaro.org>
 <CAA8EJpqQVuS+yqXQ2y5sNQrRVg7tcQAJ3ywsEjg+O=7TkUZWLQ@mail.gmail.com>
 <99a9a562-9f6f-411c-be1c-0a28fc2524dd@quicinc.com> <CAA8EJppj+cDnw7p4yANvF0FmEhX3+L5xUq8w3TeevAGhcpo1Yg@mail.gmail.com>
 <9d1c684f-51ac-4d9c-a189-940ff65e0cab@linaro.org> <7932ccbb-3b41-49e2-bb88-9c2633002a0d@quicinc.com>
Message-ID: <CAA8EJppdJqBz=+2Lq4XEXptPoudHS_N7Qs0cjJ9bx2EZwP07dw@mail.gmail.com>

On Mon, 12 Feb 2024 at 14:28, Ritesh Kumar <quic_riteshk at quicinc.com> wrote:
>
>
> On 1/23/2024 11:34 PM, Konrad Dybcio wrote:
> >
> >
> > On 1/23/24 16:12, Dmitry Baryshkov wrote:
> >> On Tue, 23 Jan 2024 at 15:43, Ritesh Kumar <quic_riteshk at quicinc.com>
> >> wrote:
> >>>
> >>>
> >>> On 1/16/2024 6:27 PM, Dmitry Baryshkov wrote:
> >>>
> >>>> On Tue, 16 Jan 2024 at 14:06, Konrad Dybcio
> >>>> <konrad.dybcio at linaro.org> wrote:
> >>>>>
> >>>>>
> >>>>> On 1/16/24 10:49, Ritesh Kumar wrote:
> >>>>>> Enable Display Subsystem with Novatek NT36672E Panel
> >>>>>> on qcm6490 idp platform.
> >>>>>>
> >>>>>> Signed-off-by: Ritesh Kumar <quic_riteshk at quicinc.com>
> >>>>>> ---
> >>>>>>     arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 100
> >>>>>> +++++++++++++++++++++++
> >>>>>>     1 file changed, 100 insertions(+)
> >>>>>>
> >>>>>> diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
> >>>>>> b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
> >>>>>> index 2a6e4907c5ee..efa5252130a1 100644
> >>>>>> --- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
> >>>>>> +++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
> >>>>>> @@ -9,6 +9,7 @@
> >>>>>>     #define PM7250B_SID 8
> >>>>>>     #define PM7250B_SID1 9
> >>>>>>
> >>>>>> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
> >>>>>>     #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
> >>>>>>     #include "sc7280.dtsi"
> >>>>>>     #include "pm7250b.dtsi"
> >>>>>> @@ -38,6 +39,25 @@
> >>>>>>                 stdout-path = "serial0:115200n8";
> >>>>>>         };
> >>>>>>
> >>>>>> +     lcd_disp_bias: lcd-disp-bias-regulator {
> >>>>>> +             compatible = "regulator-fixed";
> >>>>>> +             regulator-name = "lcd_disp_bias";
> >>>>>> +             regulator-min-microvolt = <5500000>;
> >>>>>> +             regulator-max-microvolt = <5500000>;
> >>>>>> +             gpio = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
> >>>>>> +             enable-active-high;
> >>>>>> +             pinctrl-names = "default";
> >>>>>> +             pinctrl-0 = <&lcd_disp_bias_en>;
> >>>>> property-n
> >>>>> property-names
> >>>>>
> >>>>> all throughout the patch
> >>>
> >>> Thanks, I will update in the new version.
> >>>
> >>>>>> +&gpu {
> >>>>>> +     status = "disabled";
> >>>>>> +};
> >>>>> Hm.. generally we disable the GPU in the SoC DT, but that doesn't
> >>>>> seem to have happened here..
> >>>>>
> >>>>> Thinking about it more, is disabling it here necessary? Does it
> >>>>> not fail gracefully?
> >>>> Missed this.
> >>>>
> >>>> I'd say, I don't see a reason to disable it at all. The GPU should be
> >>>> working on sc7280 / qcm4290.
> >>>
> >>> With GPU device node enabled, adreno_bind failure is seen as the
> >>> "speed_bin" was not populated on QCM6490 target which leads to display
> >>> bind failure.
> >>
> >> Excuse me please. The GPU node for sc7280 already has speed_bin, which
> >> points to qfprom + 0x1e9, bits 5 to 9.
> >>
> >> Do you mean that qcm6490 uses different speed bin location? Or
> >> different values for the speed bins?
> >>
> >>> Spoke with GPU team and on QCM6490 board, only CPU rendering is
> >>> supported for now and there is no plan to enable GPU rendering in near
> >>> future.
> >>
> >> This sounds like having the feature disabled for no particular reason.
> >> Both the kernel and Mesa have supported the Adreno 635 for quite a
> >> while.
> >
> > 643 [1], [2]
> >
> >>
> >>> In this regard, what do you suggest
> >>>
> >>> 1) Disable GPU in QCM6490 DT (as per the current patch)
> >>> 2) Disable GPU in the SoC DT, but enable it in other platform DTs.
> >>> (This
> >>> will prompt change in all the dt's and we don't have all the devices to
> >>> test)
> >>
> >> The second option definitely follows what is present on other platforms.
> >>
> >>> Please let me know your views on it.
> >>
> >> Please enable the GPU instead.
> >
> > +1
> >
> > Konrad
> >
> > [1]
> > https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25408/diffs?commit_id=b1e851d66c3a3e53f1a464023f675f3f6cbd3503
> > [2]
> > https://patches.linaro.org/project/linux-arm-msm/cover/20230926-topic-a643-v1-0-7af6937ac0a3 at linaro.org/
>
> Thanks for the help. After applying missing patches from series
> https://patches.linaro.org/project/linux-arm-msm/cover/20230926-topic-a643-v1-0-7af6937ac0a3 at linaro.org/
> in my local build, GPU is working fine. GPU disablement change is not
> needed. I will send new version of patch removing GPU part and
> addressing other review comments.

Thank you!

-- 
With best wishes
Dmitry


From frank at oltmanns.dev  Mon Feb 12 05:29:14 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 12 Feb 2024 14:29:14 +0100
Subject: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher
 clock rate
In-Reply-To: <87sf1zxb0s.fsf@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-5-96a46a2d8c9b@oltmanns.dev>
 <poua4bzyciiwt65sqjf2whqfdumvoe4h3bkjpf64px2vwgumrf@sai73byg2iju>
 <87sf1zxb0s.fsf@oltmanns.dev>
Message-ID: <87o7clyfo5.fsf@oltmanns.dev>


On 2024-02-11 at 16:42:43 +0100, Frank Oltmanns <frank at oltmanns.dev> wrote:
> On 2024-02-08 at 20:05:08 +0100, Maxime Ripard <mripard at kernel.org> wrote:
>> [[PGP Signed Part:Undecided]]
>> Hi Frank,
>>
>> On Mon, Feb 05, 2024 at 04:22:28PM +0100, Frank Oltmanns wrote:
>>> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
>>> The SOC requires pll-mipi to run at more than 500 MHz.
>>>
>>> This is the relevant clock tree:
>>>  pll-mipi
>>>     tcon0
>>>        tcon-data-clock
>>>
>>> tcon-data-clock has to run at 1/4 the DSI per-lane bit rate. The XBD599
>>> has 24 bpp and 4 lanes. Therefore, the resulting requested
>>> tcon-data-clock rate is:
>>>     crtc_clock * 1000 * (24 / 4) / 4
>>>
>>> tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it requests a
>>> parent rate of
>>>     4 * (crtc_clock * 1000 * (24 / 4) / 4)
>>>
>>> Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate of pll-mipi.
>>>
>>> pll-mipi's constraint to run at 500MHz or higher forces us to have a
>>> crtc_clock >= 83333 kHz if we want a 60 Hz vertical refresh rate.
>>>
>>> Change [hv]sync_(start|end) so that we reach a clock rate of 83502 kHz
>>> so that it is high enough to align with pll-pipi limits.
>>>
>>> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
>>
>> That commit log is great, but it's kind of off-topic. It's a panel
>> driver, it can be used on any MIPI-DSI controller, the only relevant
>> information there should be the panel timings required in the datasheet.
>>
>> The PLL setup is something for the MIPI-DSI driver to adjust, not for
>> the panel to care for.
>>
>
> I absolutely agree. It even was the reason for my submission of a
> sunxi-ng patch series last year that was accepted, to make pll-mipi more
> flexible. :)
>
> The only remaining option I currently see for adjusting the sunxi-ng
> driver to further accomodate the panel, is trying to use a higher
> divisor than 4 for calculating tcon-data-clock from tcon0. I remember
> reading a discussion about this, but as far as I remember that proposal
> was rejected (by you, IIRC).
>
> While I appreciate other suggestion as well, I'll look into options for
> using a different divisor than 4.

I tried the following:
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -391,7 +391,7 @@ static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon,
         * dclk is required to run at 1/4 the DSI per-lane bit rate.
         */
        tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
-       tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
+       tcon->dclk_max_div = 127;
        clk_set_rate(tcon->dclk, mode->crtc_clock * 1000 * (bpp / lanes)
                                                  / SUN6I_DSI_TCON_DIV);

On the pinephone, this selects a divisor of 6 resulting in a 25% frame
drop. I.e., unless I'm missing something using a divisor other than 4 is
not an option. This also matches your report from 2019: "Well, it's also
breaking another panel." [1]

I can currently see the following options:

a. Drive PLL-MIPI outside spec and panel within spec (current situation,
   but missing a small patch [2] that fixes the crtc_clock and nothing
   else) and live with the fact that some pinephones will run
   unreliably.

b. Drive PLL-MIPI and panel within spec and shove data into the panel at
   a too high rate (i.e., apply the rest of this series but not this
   specific patch). This seems to mostly work, but hasn't seen any long
   term testing. Short term testing showed that this approach results in
   a slight but noticable unsmooth scrolling behavior.

c. Drive PLL-MIPI within spec and panel outside spec (i.e., apply a
   future version of the whole series). This has been tested for over a
   month on three devices that I know of. There are no reports of panels
   not working with the suggested parameters.

All options require additional work on the GPU rate which is currently
being discussed in a parallel thread of this series. Unless somebody
comes up with a better idea, I will pause working on fixing PLL-MIPI and
focus on the GPU instead. While I doubt it, maybe fixing the GPU is
sufficient and continuing to drive PLL-MIPI outside spec proves to be
ok.

[1]: https://lore.kernel.org/all/20190828130341.s5z76wejulwdgxlc at flea/
[2]: https://lore.kernel.org/all/20230219114553.288057-2-frank at oltmanns.dev/

Best regards,
  Frank

>
> Best regards,
>   Frank
>
>>
>> Maxime
>>
>> [[End of PGP Signed Part]]


From dmitry.baryshkov at linaro.org  Mon Feb 12 05:32:12 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 12 Feb 2024 15:32:12 +0200
Subject: [PATCH 5/5] arm64: dts: qcom: sm8650-qrd: enable GPU
In-Reply-To: <20240212-topic-sm8650-gpu-v1-5-708a40b747b5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org> <20240212-topic-sm8650-gpu-v1-5-708a40b747b5@linaro.org>
Message-ID: <CAA8EJpryCXUxs69ockt0TN4LOuBB-4dZkLYHUZyN1Uq0isMjYg@mail.gmail.com>

On Mon, 12 Feb 2024 at 12:37, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>
> Add path of the GPU firmware for the SM8650-QRD board
>
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/sm8650-qrd.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
> index 8515498553bf..7151f3dc67c4 100644
> --- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
> +++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
> @@ -525,6 +525,14 @@ &ipa {
>         status = "okay";
>  };
>
> +&gpu {
> +       status = "okay";
> +
> +       zap-shader {
> +               firmware-name = "qcom/sm8650/gen70900_zap.mbn";

But why? For sm8450 / sm8550 we had "a730_zap.mbn" and "a740_zap.mbn"

> +       };
> +};
> +
>  &mdss {
>         status = "okay";
>  };
>
> --
> 2.34.1
>


-- 
With best wishes
Dmitry


From quic_mojha at quicinc.com  Mon Feb 12 05:34:03 2024
From: quic_mojha at quicinc.com (Mukesh Ojha)
Date: Mon, 12 Feb 2024 19:04:03 +0530
Subject: [PATCH v8 08/10] pstore/ram: Add dynamic ramoops region support
 through commandline
In-Reply-To: <20240131110837.14218-9-quic_mojha@quicinc.com>
References: <20240131110837.14218-1-quic_mojha@quicinc.com>
 <20240131110837.14218-9-quic_mojha@quicinc.com>
Message-ID: <45b5a4d3-b79f-aa66-67e9-2a57bbfb938e@quicinc.com>

Hi @Kees/@Tony/@Guilherme,

Wanted to get your early feedback, especially on 8th and 9th patch.
please suggest.

-Mukesh

On 1/31/2024 4:38 PM, Mukesh Ojha wrote:
> The reserved memory region for ramoops is assumed to be at a fixed
> and known location when read from the devicetree. This may not be
> required for something like Qualcomm's minidump which is interested
> in knowing addresses of ramoops region but it does not put hard
> requirement of address being fixed as most of its SoC does not
> support warm reset and does not use pstorefs at all instead it has
> firmware way of collecting ramoops region if it gets to know the
> address and register it with apss minidump table which is sitting
> in shared memory region in DDR and firmware will have access to
> these table during reset and collects it on crash of SoC.
> 
> So, add the support of reserving ramoops region to be dynamically
> allocated early during boot if it is request through command line
> via 'dyn_ramoops_size=<size>' and fill up reserved resource structure
> and export the structure, so that it can be read by ramoops driver.
> 
> Signed-off-by: Mukesh Ojha <quic_mojha at quicinc.com>
> ---
>   Documentation/admin-guide/ramoops.rst | 23 +++++++++-
>   fs/pstore/Kconfig                     | 15 ++++++
>   fs/pstore/ram.c                       | 66 +++++++++++++++++++++++++--
>   include/linux/pstore_ram.h            |  5 ++
>   init/main.c                           |  3 ++
>   5 files changed, 108 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/admin-guide/ramoops.rst b/Documentation/admin-guide/ramoops.rst
> index e9f85142182d..6de61002f9e9 100644
> --- a/Documentation/admin-guide/ramoops.rst
> +++ b/Documentation/admin-guide/ramoops.rst
> @@ -33,6 +33,13 @@ memory are implementation defined, and won't work on many ARMs such as omaps.
>   Setting ``mem_type=2`` attempts to treat the memory region as normal memory,
>   which enables full cache on it. This can improve the performance.
>   
> +Ramoops supports its memory to be allocated dynamically during early boot
> +for plaforms that do not have support for warm boot i.e., no assurance
> +that Ram content will be preserved across boot and for these platforms
> +giving static Ramoops memory is not necessary as it has separate backend
> +mechanism to retrieve ramoops content on system failure. More about
> +how to enable Dynamic ramoops in ``Setting the parameters`` A.b section.
> +
>   The memory area is divided into ``record_size`` chunks (also rounded down to
>   power of two) and each kmesg dump writes a ``record_size`` chunk of
>   information.
> @@ -59,7 +66,7 @@ Setting the parameters
>   
>   Setting the ramoops parameters can be done in several different manners:
>   
> - A. Use the module parameters (which have the names of the variables described
> + A.a  Use the module parameters (which have the names of the variables described
>    as before). For quick debugging, you can also reserve parts of memory during
>    boot and then use the reserved memory for ramoops. For example, assuming a
>    machine with > 128 MB of memory, the following kernel command line will tell
> @@ -68,6 +75,20 @@ Setting the ramoops parameters can be done in several different manners:
>   
>   	mem=128M ramoops.mem_address=0x8000000 ramoops.ecc=1
>   
> + A.b  Ramoops memory can be also be dynamically reserved by Kernel and in such
> + scenario ``mem_address`` i.e., Ramoops base address can be anywhere in the RAM
> + instead of being fixed and predefined. A separate command line option
> + ``dyn_ramoops_size=<size>`` and kernel config CONFIG_PSTORE_DYNAMIC_RAMOOPS
> + are provided to facilitate Dynamic Ramoops memory reservation during early boot.
> + The command line option and the config should only be used in the presence of
> + separate backend which knows how to recover Dynamic Ramoops region otherwise
> + regular ramoops functionality will be impacted.
> + ``mem_size`` should not be used if Dynamic Ramoops support is requested and if
> + both are given ``mem_size`` value is overwritten with ``dyn_ramoops_size`` value
> + i.e., Dynamic Ramoops takes precedence::
> +
> +	dyn_ramoops_size=2M ramoops.console_size=2097152
> +
>    B. Use Device Tree bindings, as described in
>    ``Documentation/devicetree/bindings/reserved-memory/ramoops.yaml``.
>    For example::
> diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
> index 3acc38600cd1..b8bdbd2f0e73 100644
> --- a/fs/pstore/Kconfig
> +++ b/fs/pstore/Kconfig
> @@ -81,6 +81,21 @@ config PSTORE_RAM
>   
>   	  For more information, see Documentation/admin-guide/ramoops.rst.
>   
> +config PSTORE_DYNAMIC_RAMOOPS
> +	bool "Reserve ramoops region dynamically"
> +	select PSTORE_RAM
> +	help
> +	  This enables the dynamic reservation of ramoops region for a special case
> +	  where there is no need to access the logs from pstorefs on next boot;
> +	  instead there is separate backend mechanism like minidump present which has
> +	  awareness about the dynamic ramoops region and can recover the logs. This is
> +	  enabled via command line parameter dyn_ramoops_size=<size> and should not be
> +	  used in absence of separate backend which knows how to recover this dynamic
> +	  region.
> +
> +	  Note whenever this config is selected ramoops driver will be built statically
> +	  into kernel.
> +
>   config PSTORE_ZONE
>   	tristate
>   	depends on PSTORE
> diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
> index 88b34fdbf759..1faf0835700b 100644
> --- a/fs/pstore/ram.c
> +++ b/fs/pstore/ram.c
> @@ -20,6 +20,7 @@
>   #include <linux/compiler.h>
>   #include <linux/of.h>
>   #include <linux/of_address.h>
> +#include <linux/memblock.h>
>   #include <linux/mm.h>
>   
>   #include "internal.h"
> @@ -103,6 +104,59 @@ struct ramoops_context {
>   };
>   
>   static struct platform_device *dummy;
> +static struct resource dyn_ramoops_res = {
> +	.name  = "ramoops",
> +	.start = 0,
> +	.end   = 0,
> +	.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
> +	.desc  = IORES_DESC_NONE,
> +};
> +static int dyn_ramoops_size;
> +
> +#ifdef CONFIG_PSTORE_DYNAMIC_RAMOOPS
> +static int __init parse_dyn_ramoops_size(char *p)
> +{
> +	char *tmp;
> +
> +	dyn_ramoops_size = memparse(p, &tmp);
> +	if (p == tmp) {
> +		pr_err("ramoops: memory size expected\n");
> +		dyn_ramoops_size = 0;
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +early_param("dyn_ramoops_size", parse_dyn_ramoops_size);
> +
> +/*
> + * setup_dynamic_ramoops() - Reserve memory for dynamic ramoops
> + *
> + * Enables dynamic reserve memory support for ramoops through
> + * command line.
> + */
> +void __init setup_dynamic_ramoops(void)
> +{
> +	unsigned long long ramoops_base;
> +	unsigned long long ramoops_size;
> +
> +	if (!dyn_ramoops_size)
> +		return;
> +
> +	ramoops_base = memblock_phys_alloc_range(dyn_ramoops_size, SMP_CACHE_BYTES,
> +						 0, MEMBLOCK_ALLOC_NOLEAKTRACE);
> +	if (!ramoops_base) {
> +		pr_err("cannot allocate ramoops dynamic memory (size:0x%llx).\n",
> +			ramoops_size);
> +		dyn_ramoops_size = 0;
> +		return;
> +	}
> +
> +	dyn_ramoops_res.start = ramoops_base;
> +	dyn_ramoops_res.end = ramoops_base + dyn_ramoops_size - 1;
> +	insert_resource(&iomem_resource, &dyn_ramoops_res);
> +}
> +#endif
>   
>   static int ramoops_pstore_open(struct pstore_info *psi)
>   {
> @@ -915,13 +969,19 @@ static void __init ramoops_register_dummy(void)
>   
>   	/*
>   	 * Prepare a dummy platform data structure to carry the module
> -	 * parameters. If mem_size isn't set, then there are no module
> -	 * parameters, and we can skip this.
> +	 * parameters.
> +	 *
> +	 * dyn_ramoops_size takes precedence over mem_size if it is
> +	 * enabled and valid.
>   	 */
> -	if (!mem_size)
> +	if (!dyn_ramoops_size && !mem_size)
>   		return;
>   
>   	pr_info("using module parameters\n");
> +	if (dyn_ramoops_size) {
> +		mem_size = dyn_ramoops_size;
> +		mem_address = dyn_ramoops_res.start;
> +	}
>   
>   	memset(&pdata, 0, sizeof(pdata));
>   	pdata.mem_size = mem_size;
> diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h
> index 9d65ff94e216..1efff7a38333 100644
> --- a/include/linux/pstore_ram.h
> +++ b/include/linux/pstore_ram.h
> @@ -39,4 +39,9 @@ struct ramoops_platform_data {
>   	struct persistent_ram_ecc_info ecc_info;
>   };
>   
> +#ifdef CONFIG_PSTORE_DYNAMIC_RAMOOPS
> +void __init setup_dynamic_ramoops(void);
> +#else
> +static inline void __init setup_dynamic_ramoops(void) {}
> +#endif
>   #endif
> diff --git a/init/main.c b/init/main.c
> index ef3ce41b8fc5..3d74241bcb2b 100644
> --- a/init/main.c
> +++ b/init/main.c
> @@ -99,6 +99,8 @@
>   #include <linux/init_syscalls.h>
>   #include <linux/stackdepot.h>
>   #include <linux/randomize_kstack.h>
> +#include <linux/moduleloader.h>
> +#include <linux/pstore_ram.h>
>   #include <net/net_namespace.h>
>   
>   #include <asm/io.h>
> @@ -890,6 +892,7 @@ void start_kernel(void)
>   	pr_notice("%s", linux_banner);
>   	early_security_init();
>   	setup_arch(&command_line);
> +	setup_dynamic_ramoops();
>   	setup_boot_config();
>   	setup_command_line(command_line);
>   	setup_nr_cpu_ids();


From neil.armstrong at linaro.org  Mon Feb 12 05:36:08 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 12 Feb 2024 14:36:08 +0100
Subject: [PATCH 5/5] arm64: dts: qcom: sm8650-qrd: enable GPU
In-Reply-To: <CAA8EJpryCXUxs69ockt0TN4LOuBB-4dZkLYHUZyN1Uq0isMjYg@mail.gmail.com>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
 <20240212-topic-sm8650-gpu-v1-5-708a40b747b5@linaro.org>
 <CAA8EJpryCXUxs69ockt0TN4LOuBB-4dZkLYHUZyN1Uq0isMjYg@mail.gmail.com>
Message-ID: <fff6f6e1-ca2d-4f15-b891-d9b52de8a72f@linaro.org>

Hi,

On 12/02/2024 14:32, Dmitry Baryshkov wrote:
> On Mon, 12 Feb 2024 at 12:37, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>>
>> Add path of the GPU firmware for the SM8650-QRD board
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
>> ---
>>   arch/arm64/boot/dts/qcom/sm8650-qrd.dts | 8 ++++++++
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
>> index 8515498553bf..7151f3dc67c4 100644
>> --- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
>> +++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
>> @@ -525,6 +525,14 @@ &ipa {
>>          status = "okay";
>>   };
>>
>> +&gpu {
>> +       status = "okay";
>> +
>> +       zap-shader {
>> +               firmware-name = "qcom/sm8650/gen70900_zap.mbn";
> 
> But why? For sm8450 / sm8550 we had "a730_zap.mbn" and "a740_zap.mbn"

No idea why, this is the vendor's fw name, it uses the chipid (2 for sm8550, 9 for sm8650) instead of the commercial name like the seq file (gen70900_sqe.fw).

Neil

> 
>> +       };
>> +};
>> +
>>   &mdss {
>>          status = "okay";
>>   };
>>
>> --
>> 2.34.1
>>
> 
> 



From krzysztof.kozlowski at linaro.org  Mon Feb 12 05:38:27 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 14:38:27 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop redundant
 GPIO node
In-Reply-To: <20240212115837.efz73yxinkysdmgh@runtux.com>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
 <20240212115837.efz73yxinkysdmgh@runtux.com>
Message-ID: <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>

On 12/02/2024 12:58, Ralf Schlatterbeck wrote:
> On Mon, Feb 12, 2024 at 12:25:48PM +0100, Krzysztof Kozlowski wrote:
>>
>> Hm, I don't understand how exactly it helps. The GPIO expander has its
>> own example and as you pointed below, this is basically the same code,
>> except rw and backlight GPIOs.
> 
> The hd44780 is a display that is very often used.
> By people (like me some time ago) not familiar with the nice io expander
> implementation in Linux. The consequence of that is that you'll find
> several out-of-tree implementations for this display with i2c out in the
> wild. So my thought of documenting this (again) at that location is to
> make it easier for people with a hd44780 with the standard i2c interface
> to see how it is done in Linux.

GPIO expanders and their usage is nothing specific to this device -
other devices also might benefit of them. Or the SoCs which have enough
of GPIOs... I really do not understand why do we need expander here and
how does it help

Anyway, binding examples should not be collection of unrelated
solutions, because then we should accept for each device schema several
other variations and combinations.

Best regards,
Krzysztof



From andriy.shevchenko at linux.intel.com  Mon Feb 12 05:39:17 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Mon, 12 Feb 2024 15:39:17 +0200
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit,hd44780: drop redundant
 GPIO node
In-Reply-To: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
Message-ID: <ZcofhWb8stiddmru@smile.fi.intel.com>

On Mon, Feb 12, 2024 at 09:34:24AM +0100, Krzysztof Kozlowski wrote:
> Examples of other nodes, like GPIO controller, are redundant and not
> really needed in device bindings.

...

> -    i2c {
> -            #address-cells = <1>;
> -            #size-cells = <0>;
>  
> -            pcf8574: pcf8574 at 27 {
> -                    compatible = "nxp,pcf8574";
> -                    reg = <0x27>;
> -                    gpio-controller;
> -                    #gpio-cells = <2>;
> -            };
> -    };

In patch 3 you updated the lines that have lost their sense due to this one.
And I agree with others, please leave this example in place.

-- 
With Best Regards,
Andy Shevchenko




From robh at kernel.org  Mon Feb 12 05:41:19 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 12 Feb 2024 07:41:19 -0600
Subject: [PATCH v1 03/14] dt-bindings: sound: fsl,imx-asrc: convert to
 YAML
In-Reply-To: <20240210012114.489102-4-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-4-sre@kernel.org>
Message-ID: <20240212134119.GA37175-robh@kernel.org>

On Sat, Feb 10, 2024 at 02:18:07AM +0100, Sebastian Reichel wrote:
> Convert the i.MX ASRC DT binding to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../devicetree/bindings/sound/fsl,asrc.txt    |  80 ---------
>  .../bindings/sound/fsl,imx-asrc.yaml          | 159 ++++++++++++++++++
>  2 files changed, 159 insertions(+), 80 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/sound/fsl,asrc.txt
>  create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml


> diff --git a/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml
> new file mode 100644
> index 000000000000..bc1607ecf345
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml
> @@ -0,0 +1,159 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/fsl,imx-asrc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale Asynchronous Sample Rate Converter (ASRC) Controller
> +
> +description:
> +  The Asynchronous Sample Rate Converter (ASRC) converts the sampling rate of
> +  a signal associated with an input clock into a signal associated with a
> +  different output clock. The driver currently works as a Front End of DPCM
> +  with other Back Ends Audio controller such as ESAI, SSI and SAI. It has
> +  three pairs to support three substreams within totally 10 channels.
> +
> +maintainers:
> +  - Shawn Guo <shawnguo at kernel.org>
> +  - Sascha Hauer <s.hauer at pengutronix.de>
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - enum:
> +          - fsl,imx35-asrc
> +          - fsl,imx53-asrc
> +          - fsl,imx8qm-asrc
> +          - fsl,imx8qxp-asrc
> +      - items:
> +          - enum:
> +              - fsl,imx6sx-asrc
> +              - fsl,imx6ul-asrc
> +          - const: fsl,imx53-asrc
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  dmas:
> +    maxItems: 6
> +
> +  dma-names:
> +    items:
> +      - const: rxa
> +      - const: rxb
> +      - const: rxc
> +      - const: txa
> +      - const: txb
> +      - const: txc
> +
> +  clocks:
> +    maxItems: 19
> +
> +  clock-names:
> +    items:
> +      - const: mem
> +      - const: ipg
> +      - const: asrck_0
> +      - const: asrck_1
> +      - const: asrck_2
> +      - const: asrck_3
> +      - const: asrck_4
> +      - const: asrck_5
> +      - const: asrck_6
> +      - const: asrck_7
> +      - const: asrck_8
> +      - const: asrck_9
> +      - const: asrck_a
> +      - const: asrck_b
> +      - const: asrck_c
> +      - const: asrck_d
> +      - const: asrck_e
> +      - const: asrck_f
> +      - const: spba
> +
> +  fsl,asrc-rate:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: The mutual sample rate used by DPCM Back Ends
> +
> +  fsl,asrc-width:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: The mutual sample width used by DPCM Back Ends

Constraints?

> +
> +  fsl,asrc-clk-map:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines clock map used in driver
> +      <0> - select the map for asrc0 in imx8qm/imx8qxp
> +      <1> - select the map for asrc1 in imx8qm/imx8qxp

Looks like constraints.

> +
> +  big-endian:
> +    type: boolean
> +    description:
> +      If this property is absent, the little endian mode will be in use as
> +      default. Otherwise, the big endian mode will be in use for all the
> +      device registers.
> +
> +  fsl,asrc-format:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines a mutual sample format used by DPCM Back Ends, which can
> +      replace the fsl,asrc-width. The value is 2 (S16_LE), or 6 (S24_LE).

Looks like constraints.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - dmas
> +  - dma-names
> +  - clocks
> +  - clock-names
> +  - fsl,asrc-rate
> +  - fsl,asrc-width
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - fsl,imx8qm-asrc
> +              - fsl,imx8qxp-asrc
> +    then:
> +      required:
> +        - fsl,asrc-clk-map
> +    else:
> +      properties:
> +        fsl,asrc-clk-map: false
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/clock/imx6qdl-clock.h>
> +    asrc: asrc at 2034000 {
> +        compatible = "fsl,imx53-asrc";
> +        reg = <0x02034000 0x4000>;
> +        interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
> +        clocks = <&clks IMX6QDL_CLK_ASRC_IPG>,
> +                 <&clks IMX6QDL_CLK_ASRC_MEM>, <&clks 0>,
> +                 <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
> +                 <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
> +                 <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
> +                 <&clks IMX6QDL_CLK_ASRC>, <&clks 0>, <&clks 0>,
> +                 <&clks IMX6QDL_CLK_SPBA>;
> +        clock-names = "mem", "ipg", "asrck_0",
> +                "asrck_1", "asrck_2", "asrck_3", "asrck_4",
> +                "asrck_5", "asrck_6", "asrck_7", "asrck_8",
> +                "asrck_9", "asrck_a", "asrck_b", "asrck_c",
> +                "asrck_d", "asrck_e", "asrck_f", "spba";
> +        dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
> +               <&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
> +        dma-names = "rxa", "rxb", "rxc",
> +                    "txa", "txb", "txc";
> +        fsl,asrc-rate  = <48000>;
> +        fsl,asrc-width = <16>;
> +    };
> -- 
> 2.43.0
> 


From david at redhat.com  Mon Feb 12 05:43:35 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 14:43:35 +0100
Subject: [PATCH v5 22/25] mm: Add pte_batch_hint() to reduce scanning in
 folio_pte_batch()
In-Reply-To: <20240202080756.1453939-23-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-23-ryan.roberts@arm.com>
Message-ID: <6d452a1a-1edc-4e97-8b39-99dc48315bb8@redhat.com>

On 02.02.24 09:07, Ryan Roberts wrote:
> Some architectures (e.g. arm64) can tell from looking at a pte, if some
> follow-on ptes also map contiguous physical memory with the same pgprot.
> (for arm64, these are contpte mappings).
> 
> Take advantage of this knowledge to optimize folio_pte_batch() so that
> it can skip these ptes when scanning to create a batch. By default, if
> an arch does not opt-in, folio_pte_batch() returns a compile-time 1, so
> the changes are optimized out and the behaviour is as before.
> 
> arm64 will opt-in to providing this hint in the next patch, which will
> greatly reduce the cost of ptep_get() when scanning a range of contptes.
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>   include/linux/pgtable.h | 18 ++++++++++++++++++
>   mm/memory.c             | 20 +++++++++++++-------
>   2 files changed, 31 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 50f32cccbd92..cba31f177d27 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -212,6 +212,24 @@ static inline int pmd_dirty(pmd_t pmd)
>   #define arch_flush_lazy_mmu_mode()	do {} while (0)
>   #endif
>   
> +#ifndef pte_batch_hint
> +/**
> + * pte_batch_hint - Number of pages that can be added to batch without scanning.
> + * @ptep: Page table pointer for the entry.
> + * @pte: Page table entry.
> + *
> + * Some architectures know that a set of contiguous ptes all map the same
> + * contiguous memory with the same permissions. In this case, it can provide a
> + * hint to aid pte batching without the core code needing to scan every pte.

I think we might want to document here the expectation regarding
dirty/accessed bits. folio_pte_batch() will ignore dirty bits only with
FPB_IGNORE_DIRTY. But especially for arm64, it makes sense to ignore them
always when batching, because the dirty bit may target any pte part of the
cont-pte group either way.

Maybe something like:

"
An architecture implementation may only ignore the PTE accessed and dirty bits.
Further, it may only ignore the dirty bit if that bit is already not
maintained with precision per PTE inside the hinted batch, and ptep_get()
would already have to collect it from various PTEs.
"

I think there are some more details to it, but I'm hoping something along
the lines above is sufficient.


> +
>   #ifndef pte_advance_pfn
>   static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>   {
> diff --git a/mm/memory.c b/mm/memory.c
> index 65fbe4f886c1..902665b27702 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -988,16 +988,21 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
>   {
>   	unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio);
>   	const pte_t *end_ptep = start_ptep + max_nr;
> -	pte_t expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, 1), flags);
> -	pte_t *ptep = start_ptep + 1;
> +	pte_t expected_pte = __pte_batch_clear_ignored(pte, flags);
> +	pte_t *ptep = start_ptep;
>   	bool writable;
> +	int nr;
>   
>   	if (any_writable)
>   		*any_writable = false;
>   
>   	VM_WARN_ON_FOLIO(!pte_present(pte), folio);
>   
> -	while (ptep != end_ptep) {
> +	nr = pte_batch_hint(ptep, pte);
> +	expected_pte = pte_advance_pfn(expected_pte, nr);
> +	ptep += nr;
> +

*Maybe* it's easier to get when initializing expected_pte+ptep only once.

Like:

[...]
pte_t expected_pte, *ptep;
[...]

nr = pte_batch_hint(start_ptep, pte);
expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, nr), flags);
ptep = start_ptep + nr;

> +	while (ptep < end_ptep) {
>   		pte = ptep_get(ptep);
>   		if (any_writable)
>   			writable = !!pte_write(pte);
> @@ -1011,17 +1016,18 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
>   		 * corner cases the next PFN might fall into a different
>   		 * folio.
>   		 */
> -		if (pte_pfn(pte) == folio_end_pfn)
> +		if (pte_pfn(pte) >= folio_end_pfn)
>   			break;
>   
>   		if (any_writable)
>   			*any_writable |= writable;
>   
> -		expected_pte = pte_advance_pfn(expected_pte, 1);
> -		ptep++;
> +		nr = pte_batch_hint(ptep, pte);
> +		expected_pte = pte_advance_pfn(expected_pte, nr);
> +		ptep += nr;
>   	}
>   
> -	return ptep - start_ptep;
> +	return min(ptep - start_ptep, max_nr);
>   }

Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From andriy.shevchenko at linux.intel.com  Mon Feb 12 05:43:51 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Mon, 12 Feb 2024 15:43:51 +0200
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop
 redundant GPIO node
In-Reply-To: <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
 <20240212115837.efz73yxinkysdmgh@runtux.com>
 <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
Message-ID: <Zcogl6tqbMdQldKA@smile.fi.intel.com>

On Mon, Feb 12, 2024 at 02:38:27PM +0100, Krzysztof Kozlowski wrote:
> On 12/02/2024 12:58, Ralf Schlatterbeck wrote:

...

> Anyway, binding examples should not be collection of unrelated
> solutions, because then we should accept for each device schema several
> other variations and combinations.

Is this documented?

In any case, you would need to amend your series one way or another.

-- 
With Best Regards,
Andy Shevchenko




From schwab at suse.de  Mon Feb 12 05:46:29 2024
From: schwab at suse.de (Andreas Schwab)
Date: Mon, 12 Feb 2024 14:46:29 +0100
Subject: 6.7 regression: platform 4809c000.mmc: deferred probe pending
Message-ID: <mvmcyt13idm.fsf@suse.de>

I'm getting these messages on the PandaBoard since 6.7:

[   29.285522][  T156] platform 4809c000.mmc: deferred probe pending
[   29.291748][  T156] platform 4a0ab000.usb_otg_hs: deferred probe pending
[   29.298522][  T156] platform 58005000.encoder: deferred probe pending
[   29.305053][  T156] platform 58006000.encoder: deferred probe pending
[   29.305145][  T156] i2c 0-004b: deferred probe pending
[   29.316772][  T156] platform 40132000.target-module: deferred probe pending
[   37.382110][  T156] pbias_mmc_omap4: disabling

As a result, the SD card is not found.
Any idea what's going on here?

-- 
Andreas Schwab, SUSE Labs, schwab at suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


From david at redhat.com  Mon Feb 12 05:46:29 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 14:46:29 +0100
Subject: [PATCH v5 23/25] arm64/mm: Implement pte_batch_hint()
In-Reply-To: <20240202080756.1453939-24-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-24-ryan.roberts@arm.com>
Message-ID: <40889617-0820-473e-86ed-04eca6489169@redhat.com>

On 02.02.24 09:07, Ryan Roberts wrote:
> When core code iterates over a range of ptes and calls ptep_get() for
> each of them, if the range happens to cover contpte mappings, the number
> of pte reads becomes amplified by a factor of the number of PTEs in a
> contpte block. This is because for each call to ptep_get(), the
> implementation must read all of the ptes in the contpte block to which
> it belongs to gather the access and dirty bits.
> 
> This causes a hotspot for fork(), as well as operations that unmap
> memory such as munmap(), exit and madvise(MADV_DONTNEED). Fortunately we
> can fix this by implementing pte_batch_hint() which allows their
> iterators to skip getting the contpte tail ptes when gathering the batch
> of ptes to operate on. This results in the number of PTE reads returning
> to 1 per pte.
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>   arch/arm64/include/asm/pgtable.h | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index ad04adb7b87f..353ea67b5d75 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -1220,6 +1220,15 @@ static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>   		__contpte_try_unfold(mm, addr, ptep, pte);
>   }
>   
> +#define pte_batch_hint pte_batch_hint
> +static inline unsigned int pte_batch_hint(pte_t *ptep, pte_t pte)
> +{
> +	if (!pte_valid_cont(pte))
> +		return 1;
> +
> +	return CONT_PTES - (((unsigned long)ptep >> 3) & (CONT_PTES - 1));
> +}
> +
>   /*
>    * The below functions constitute the public API that arm64 presents to the
>    * core-mm to manipulate PTE entries within their page tables (or at least this


Reviewed-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From avromanov at salutedevices.com  Mon Feb 12 05:50:48 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:48 +0300
Subject: [PATCH v4 00/20] Support more Amlogic SoC families in crypto driver
Message-ID: <20240212135108.549755-1-avromanov@salutedevices.com>

Hello!

This patchset expand the funcionality of the Amlogic
crypto driver by adding support for more SoC families:
AXG, G12A, G12B, SM1, A1, S4.

Also specify and enable crypto node in device tree
for reference Amlogic devices.

Tested on AXG, G12A/B, SM1, A1 and S4 devices via
custom tests [1] and tcrypt module.

---

Changes V1 -> V2 [2]:

- Rebased over linux-next.
- Adjusted device tree bindings description.
- A1 and S4 dts use their own compatible, which is a G12 fallback.

Changes V2 -> V3 [3]:

- Fix errors in dt-bindings and device tree.
- Add new field in platform data, which determines
whether clock controller should be used for crypto IP.
- Place back MODULE_DEVICE_TABLE.
- Correct commit messages.

Changes V3 -> V4 [4]:

- Update dt-bindings as per Krzysztof Kozlowski comments.
- Fix bisection: get rid of compiler errors in some patches.

Links:
  - [1] https://gist.github.com/mRrvz/3fb8943a7487ab7b943ec140706995e7
  - [2] https://lore.kernel.org/all/20240110201216.18016-1-avromanov at salutedevices.com/
  - [3] https://lore.kernel.org/all/20240123165831.970023-1-avromanov at salutedevices.com/
  - [4] https://lore.kernel.org/all/20240205155521.1795552-1-avromanov at salutedevices.com/

Alexey Romanov (20):
  drivers: crypto: meson: don't hardcode IRQ count
  drviers: crypto: meson: add platform data
  drivers: crypto: meson: make CLK controller optional
  drivers: crypto: meson: add MMIO helpers
  drivers: crypto: meson: move get_engine_number()
  drivers: crypto: meson: drop status field from meson_flow
  drivers: crypto: meson: move algs definition and cipher API to
    cipher.c
  drivers: crypto: meson: cleanup defines
  drivers: crypto: meson: process more than MAXDESCS descriptors
  drivers: crypto: meson: avoid kzalloc in engine thread
  drivers: crypto: meson: introduce hasher
  drivers: crypto: meson: add support for AES-CTR
  drivers: crypto: meson: use fallback for 192-bit keys
  drivers: crypto: meson: add support for G12-series
  drivers: crypto: meson: add support for AXG-series
  dt-bindings: crypto: meson: support new SoC's
  arch: arm64: dts: meson: a1: add crypto node
  arch: arm64: dts: meson: s4: add crypto node
  arch: arm64: dts: meson: g12: add crypto node
  arch: arm64: dts: meson: axg: add crypto node

 .../bindings/crypto/amlogic,gxl-crypto.yaml   |  43 +-
 arch/arm64/boot/dts/amlogic/meson-a1.dtsi     |   7 +
 arch/arm64/boot/dts/amlogic/meson-axg.dtsi    |   6 +
 .../boot/dts/amlogic/meson-g12-common.dtsi    |   6 +
 arch/arm64/boot/dts/amlogic/meson-s4.dtsi     |   6 +
 drivers/crypto/amlogic/Makefile               |   2 +-
 drivers/crypto/amlogic/amlogic-gxl-cipher.c   | 602 ++++++++++++------
 drivers/crypto/amlogic/amlogic-gxl-core.c     | 290 +++++----
 drivers/crypto/amlogic/amlogic-gxl-hasher.c   | 452 +++++++++++++
 drivers/crypto/amlogic/amlogic-gxl.h          | 117 +++-
 10 files changed, 1183 insertions(+), 348 deletions(-)
 create mode 100644 drivers/crypto/amlogic/amlogic-gxl-hasher.c

-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:52 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:52 +0300
Subject: [PATCH v4 04/20] drivers: crypto: meson: add MMIO helpers
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-5-avromanov@salutedevices.com>

Add MMIO access helpers: meson_dma_start() and meson_dma_ready().

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c |  2 +-
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 24 ++++++++++++++++-----
 drivers/crypto/amlogic/amlogic-gxl.h        |  2 ++
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 7eff3ae7356f..1fe916b0a138 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)
 
 	reinit_completion(&mc->chanlist[flow].complete);
 	mc->chanlist[flow].status = 0;
-	writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
+	meson_dma_start(mc, flow);
 	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
 						  msecs_to_jiffies(500));
 	if (mc->chanlist[flow].status == 0) {
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 54113c524ec5..372c30f72072 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -23,18 +23,32 @@
 
 #include "amlogic-gxl.h"
 
+void meson_dma_start(struct meson_dev *mc, int flow)
+{
+	u32 offset = (mc->pdata->descs_reg + flow) << 2;
+
+	writel(mc->chanlist[flow].t_phy | 2, mc->base + offset);
+}
+
+static bool meson_dma_ready(struct meson_dev *mc, int flow)
+{
+	u32 offset = (mc->pdata->status_reg + flow) << 2;
+	u32 data = readl(mc->base + offset);
+
+	if (data)
+		writel_relaxed(0xF, mc->base + offset);
+
+	return data;
+}
+
 static irqreturn_t meson_irq_handler(int irq, void *data)
 {
 	struct meson_dev *mc = (struct meson_dev *)data;
 	int flow;
-	u32 p;
 
 	for (flow = 0; flow < mc->flow_cnt; flow++) {
 		if (mc->chanlist[flow].irq == irq) {
-			p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
-			if (p) {
-				writel_relaxed(0xF, mc->base +
-					      ((mc->pdata->status_reg + flow) << 2));
+			if (meson_dma_ready(mc, flow)) {
 				mc->chanlist[flow].status = 1;
 				complete(&mc->chanlist[flow].complete);
 				return IRQ_HANDLED;
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index a36b9bac63a0..59fc6a67e0a9 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -163,6 +163,8 @@ struct meson_alg_template {
 #endif
 };
 
+void meson_dma_start(struct meson_dev *mc, int flow);
+
 int meson_enqueue(struct crypto_async_request *areq, u32 type);
 
 int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:50 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:50 +0300
Subject: [PATCH v4 02/20] drviers: crypto: meson: add platform data
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-3-avromanov@salutedevices.com>

To support other Amlogic SoC's we have to
use platform data: descriptors and status registers
offsets are individual for each SoC series.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c |  2 +-
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 32 +++++++++++++++------
 drivers/crypto/amlogic/amlogic-gxl.h        | 11 +++++++
 3 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index b19032f92415..7eff3ae7356f 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)
 
 	reinit_completion(&mc->chanlist[flow].complete);
 	mc->chanlist[flow].status = 0;
-	writel(mc->chanlist[flow].t_phy | 2, mc->base + (flow << 2));
+	writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
 	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
 						  msecs_to_jiffies(500));
 	if (mc->chanlist[flow].status == 0) {
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 35ec64df5b3a..4d1b1d5b7a54 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
 #include "amlogic-gxl.h"
@@ -30,9 +31,10 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
 
 	for (flow = 0; flow < mc->flow_cnt; flow++) {
 		if (mc->chanlist[flow].irq == irq) {
-			p = readl(mc->base + ((0x04 + flow) << 2));
+			p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
 			if (p) {
-				writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
+				writel_relaxed(0xF, mc->base +
+					      ((mc->pdata->status_reg + flow) << 2));
 				mc->chanlist[flow].status = 1;
 				complete(&mc->chanlist[flow].complete);
 				return IRQ_HANDLED;
@@ -245,15 +247,35 @@ static void meson_unregister_algs(struct meson_dev *mc)
 	}
 }
 
+static const struct meson_pdata meson_gxl_pdata = {
+	.descs_reg = 0x0,
+	.status_reg = 0x4,
+};
+
+static const struct of_device_id meson_crypto_of_match_table[] = {
+	{
+		.compatible = "amlogic,gxl-crypto",
+		.data = &meson_gxl_pdata,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
+
 static int meson_crypto_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *match;
 	struct meson_dev *mc;
 	int err;
 
+	match = of_match_device(meson_crypto_of_match_table, &pdev->dev);
+	if (!match)
+		return -EINVAL;
+
 	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
 	if (!mc)
 		return -ENOMEM;
 
+	mc->pdata = match->data;
 	mc->dev = &pdev->dev;
 	platform_set_drvdata(pdev, mc);
 
@@ -319,12 +341,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
 	clk_disable_unprepare(mc->busclk);
 }
 
-static const struct of_device_id meson_crypto_of_match_table[] = {
-	{ .compatible = "amlogic,gxl-crypto", },
-	{}
-};
-MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
-
 static struct platform_driver meson_crypto_driver = {
 	.probe		 = meson_crypto_probe,
 	.remove_new	 = meson_crypto_remove,
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 79177cfa8b88..9ad75da214ff 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -78,6 +78,16 @@ struct meson_flow {
 #endif
 };
 
+/*
+ * struct meson_pdata - SoC series dependent data.
+ * @reg_descs:	offset to descriptors register
+ * @reg_status:	offset to status register
+ */
+struct meson_pdata {
+	u32 descs_reg;
+	u32 status_reg;
+};
+
 /*
  * struct meson_dev - main container for all this driver information
  * @base:	base address of amlogic-crypto
@@ -93,6 +103,7 @@ struct meson_dev {
 	void __iomem *base;
 	struct clk *busclk;
 	struct device *dev;
+	const struct meson_pdata *pdata;
 	struct meson_flow *chanlist;
 	atomic_t flow;
 	int flow_cnt;
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:49 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:49 +0300
Subject: [PATCH v4 01/20] drivers: crypto: meson: don't hardcode IRQ count
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-2-avromanov@salutedevices.com>

IRQ count is no longer hardcoded, and make it part of
struct meson_flow. We need this for extend driver support for
other Amlogic SoC's.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c |  2 +-
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 47 ++++++++++++---------
 drivers/crypto/amlogic/amlogic-gxl.h        |  8 ++--
 3 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 29048da6f50a..b19032f92415 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -19,7 +19,7 @@
 
 static int get_engine_number(struct meson_dev *mc)
 {
-	return atomic_inc_return(&mc->flow) % MAXFLOW;
+	return atomic_inc_return(&mc->flow) % mc->flow_cnt;
 }
 
 static bool meson_cipher_need_fallback(struct skcipher_request *areq)
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f54ab0d0b1e8..35ec64df5b3a 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -28,8 +28,8 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
 	int flow;
 	u32 p;
 
-	for (flow = 0; flow < MAXFLOW; flow++) {
-		if (mc->irqs[flow] == irq) {
+	for (flow = 0; flow < mc->flow_cnt; flow++) {
+		if (mc->chanlist[flow].irq == irq) {
 			p = readl(mc->base + ((0x04 + flow) << 2));
 			if (p) {
 				writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
@@ -110,7 +110,7 @@ static int meson_debugfs_show(struct seq_file *seq, void *v)
 	struct meson_dev *mc __maybe_unused = seq->private;
 	int i;
 
-	for (i = 0; i < MAXFLOW; i++)
+	for (i = 0; i < mc->flow_cnt; i++)
 		seq_printf(seq, "Channel %d: nreq %lu\n", i,
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
 			   mc->chanlist[i].stat_req);
@@ -153,14 +153,32 @@ static void meson_free_chanlist(struct meson_dev *mc, int i)
  */
 static int meson_allocate_chanlist(struct meson_dev *mc)
 {
+	struct platform_device *pdev = to_platform_device(mc->dev);
 	int i, err;
 
-	mc->chanlist = devm_kcalloc(mc->dev, MAXFLOW,
+	mc->flow_cnt = platform_irq_count(pdev);
+	if (mc->flow_cnt <= 0) {
+		dev_err(mc->dev, "No IRQs defined\n");
+		return -ENODEV;
+	}
+
+	mc->chanlist = devm_kcalloc(mc->dev, mc->flow_cnt,
 				    sizeof(struct meson_flow), GFP_KERNEL);
 	if (!mc->chanlist)
 		return -ENOMEM;
 
-	for (i = 0; i < MAXFLOW; i++) {
+	for (i = 0; i < mc->flow_cnt; i++) {
+		mc->chanlist[i].irq = platform_get_irq(pdev, i);
+		if (mc->chanlist[i].irq < 0)
+			return mc->chanlist[i].irq;
+
+		err = devm_request_irq(mc->dev, mc->chanlist[i].irq,
+				       meson_irq_handler, 0, "aml-crypto", mc);
+		if (err < 0) {
+			dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
+			return err;
+		}
+
 		init_completion(&mc->chanlist[i].complete);
 
 		mc->chanlist[i].engine = crypto_engine_alloc_init(mc->dev, true);
@@ -230,7 +248,7 @@ static void meson_unregister_algs(struct meson_dev *mc)
 static int meson_crypto_probe(struct platform_device *pdev)
 {
 	struct meson_dev *mc;
-	int err, i;
+	int err;
 
 	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
 	if (!mc)
@@ -252,19 +270,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	for (i = 0; i < MAXFLOW; i++) {
-		mc->irqs[i] = platform_get_irq(pdev, i);
-		if (mc->irqs[i] < 0)
-			return mc->irqs[i];
-
-		err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0,
-				       "gxl-crypto", mc);
-		if (err < 0) {
-			dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
-			return err;
-		}
-	}
-
 	err = clk_prepare_enable(mc->busclk);
 	if (err != 0) {
 		dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
@@ -294,7 +299,7 @@ static int meson_crypto_probe(struct platform_device *pdev)
 error_alg:
 	meson_unregister_algs(mc);
 error_flow:
-	meson_free_chanlist(mc, MAXFLOW - 1);
+	meson_free_chanlist(mc, mc->flow_cnt - 1);
 	clk_disable_unprepare(mc->busclk);
 	return err;
 }
@@ -309,7 +314,7 @@ static void meson_crypto_remove(struct platform_device *pdev)
 
 	meson_unregister_algs(mc);
 
-	meson_free_chanlist(mc, MAXFLOW - 1);
+	meson_free_chanlist(mc, mc->flow_cnt - 1);
 
 	clk_disable_unprepare(mc->busclk);
 }
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 1013a666c932..79177cfa8b88 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -22,8 +22,6 @@
 #define MESON_OPMODE_ECB 0
 #define MESON_OPMODE_CBC 1
 
-#define MAXFLOW 2
-
 #define MAXDESC 64
 
 #define DESC_LAST BIT(18)
@@ -62,6 +60,7 @@ struct meson_desc {
  * @keylen:	keylen for this flow operation
  * @complete:	completion for the current task on this flow
  * @status:	set to 1 by interrupt if task is done
+ * @irq:	IRQ number for amlogic-crypto
  * @t_phy:	Physical address of task
  * @tl:		pointer to the current ce_task for this flow
  * @stat_req:	number of request done by this flow
@@ -70,6 +69,7 @@ struct meson_flow {
 	struct crypto_engine *engine;
 	struct completion complete;
 	int status;
+	int irq;
 	unsigned int keylen;
 	dma_addr_t t_phy;
 	struct meson_desc *tl;
@@ -85,7 +85,7 @@ struct meson_flow {
  * @dev:	the platform device
  * @chanlist:	array of all flow
  * @flow:	flow to use in next request
- * @irqs:	IRQ numbers for amlogic-crypto
+ * @flow_cnt:	flow count for amlogic-crypto
  * @dbgfs_dir:	Debugfs dentry for statistic directory
  * @dbgfs_stats: Debugfs dentry for statistic counters
  */
@@ -95,7 +95,7 @@ struct meson_dev {
 	struct device *dev;
 	struct meson_flow *chanlist;
 	atomic_t flow;
-	int irqs[MAXFLOW];
+	int flow_cnt;
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
 	struct dentry *dbgfs_dir;
 #endif
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:54 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:54 +0300
Subject: [PATCH v4 06/20] drivers: crypto: meson: drop status field from meson_flow
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-7-avromanov@salutedevices.com>

This field is used only to check for timeout. But there is more
convenient way to achive the same goal.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 13 +++++++++----
 drivers/crypto/amlogic/amlogic-gxl-core.c   |  1 -
 drivers/crypto/amlogic/amlogic-gxl.h        |  2 --
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 18e9e2d39b1f..dc0b100c5de2 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -219,13 +219,18 @@ static int meson_cipher(struct skcipher_request *areq)
 	}
 
 	reinit_completion(&mc->chanlist[flow].complete);
-	mc->chanlist[flow].status = 0;
 	meson_dma_start(mc, flow);
-	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
-						  msecs_to_jiffies(500));
-	if (mc->chanlist[flow].status == 0) {
+
+	err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
+							msecs_to_jiffies(500));
+	if (err == 0) {
 		dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
 		err = -EINVAL;
+	} else if (err < 0) {
+		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
+	} else {
+		/* No error */
+		err = 0;
 	}
 
 	dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 51291fdcf8b6..f7c60ebffbc3 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -54,7 +54,6 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
 	for (flow = 0; flow < mc->flow_cnt; flow++) {
 		if (mc->chanlist[flow].irq == irq) {
 			if (meson_dma_ready(mc, flow)) {
-				mc->chanlist[flow].status = 1;
 				complete(&mc->chanlist[flow].complete);
 				return IRQ_HANDLED;
 			}
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 5f5e3115fcdf..e27908992ae3 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -59,7 +59,6 @@ struct meson_desc {
  * @engine:	ptr to the crypto_engine for this flow
  * @keylen:	keylen for this flow operation
  * @complete:	completion for the current task on this flow
- * @status:	set to 1 by interrupt if task is done
  * @irq:	IRQ number for amlogic-crypto
  * @t_phy:	Physical address of task
  * @tl:		pointer to the current ce_task for this flow
@@ -68,7 +67,6 @@ struct meson_desc {
 struct meson_flow {
 	struct crypto_engine *engine;
 	struct completion complete;
-	int status;
 	int irq;
 	unsigned int keylen;
 	dma_addr_t t_phy;
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:51 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:51 +0300
Subject: [PATCH v4 03/20] drivers: crypto: meson: make CLK controller optional
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-4-avromanov@salutedevices.com>

Amlogic crypto IP doesn't take a clock input on some
SoCs: AXG / A1 / S4 / G12. So make it optional.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-core.c | 21 ++++++++-------------
 drivers/crypto/amlogic/amlogic-gxl.h      |  2 ++
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 4d1b1d5b7a54..54113c524ec5 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -250,6 +250,7 @@ static void meson_unregister_algs(struct meson_dev *mc)
 static const struct meson_pdata meson_gxl_pdata = {
 	.descs_reg = 0x0,
 	.status_reg = 0x4,
+	.need_clk = true,
 };
 
 static const struct of_device_id meson_crypto_of_match_table[] = {
@@ -285,17 +286,14 @@ static int meson_crypto_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Cannot request MMIO err=%d\n", err);
 		return err;
 	}
-	mc->busclk = devm_clk_get(&pdev->dev, "blkmv");
-	if (IS_ERR(mc->busclk)) {
-		err = PTR_ERR(mc->busclk);
-		dev_err(&pdev->dev, "Cannot get core clock err=%d\n", err);
-		return err;
-	}
 
-	err = clk_prepare_enable(mc->busclk);
-	if (err != 0) {
-		dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
-		return err;
+	if (mc->pdata->need_clk) {
+		mc->busclk = devm_clk_get_enabled(&pdev->dev, "blkmv");
+		if (IS_ERR(mc->busclk)) {
+			err = PTR_ERR(mc->busclk);
+			dev_err(&pdev->dev, "Cannot get and enable core clock err=%d\n", err);
+			return err;
+		}
 	}
 
 	err = meson_allocate_chanlist(mc);
@@ -322,7 +320,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
 	meson_unregister_algs(mc);
 error_flow:
 	meson_free_chanlist(mc, mc->flow_cnt - 1);
-	clk_disable_unprepare(mc->busclk);
 	return err;
 }
 
@@ -337,8 +334,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
 	meson_unregister_algs(mc);
 
 	meson_free_chanlist(mc, mc->flow_cnt - 1);
-
-	clk_disable_unprepare(mc->busclk);
 }
 
 static struct platform_driver meson_crypto_driver = {
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 9ad75da214ff..a36b9bac63a0 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -82,10 +82,12 @@ struct meson_flow {
  * struct meson_pdata - SoC series dependent data.
  * @reg_descs:	offset to descriptors register
  * @reg_status:	offset to status register
+ * @need_clk:	clock input is needed
  */
 struct meson_pdata {
 	u32 descs_reg;
 	u32 status_reg;
+	bool need_clk;
 };
 
 /*
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:53 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:53 +0300
Subject: [PATCH v4 05/20] drivers: crypto: meson: move get_engine_number()
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-6-avromanov@salutedevices.com>

Move get_engine_number() function from cipher.c to core.c

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 9 ++-------
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 5 +++++
 drivers/crypto/amlogic/amlogic-gxl.h        | 2 ++
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 1fe916b0a138..18e9e2d39b1f 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -17,11 +17,6 @@
 #include <crypto/internal/skcipher.h>
 #include "amlogic-gxl.h"
 
-static int get_engine_number(struct meson_dev *mc)
-{
-	return atomic_inc_return(&mc->flow) % mc->flow_cnt;
-}
-
 static bool meson_cipher_need_fallback(struct skcipher_request *areq)
 {
 	struct scatterlist *src_sg = areq->src;
@@ -282,7 +277,7 @@ int meson_skdecrypt(struct skcipher_request *areq)
 	rctx->op_dir = MESON_DECRYPT;
 	if (meson_cipher_need_fallback(areq))
 		return meson_cipher_do_fallback(areq);
-	e = get_engine_number(op->mc);
+	e = meson_get_engine_number(op->mc);
 	engine = op->mc->chanlist[e].engine;
 	rctx->flow = e;
 
@@ -300,7 +295,7 @@ int meson_skencrypt(struct skcipher_request *areq)
 	rctx->op_dir = MESON_ENCRYPT;
 	if (meson_cipher_need_fallback(areq))
 		return meson_cipher_do_fallback(areq);
-	e = get_engine_number(op->mc);
+	e = meson_get_engine_number(op->mc);
 	engine = op->mc->chanlist[e].engine;
 	rctx->flow = e;
 
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 372c30f72072..51291fdcf8b6 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -23,6 +23,11 @@
 
 #include "amlogic-gxl.h"
 
+int meson_get_engine_number(struct meson_dev *mc)
+{
+	return atomic_inc_return(&mc->flow) % mc->flow_cnt;
+}
+
 void meson_dma_start(struct meson_dev *mc, int flow)
 {
 	u32 offset = (mc->pdata->descs_reg + flow) << 2;
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 59fc6a67e0a9..5f5e3115fcdf 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -163,6 +163,8 @@ struct meson_alg_template {
 #endif
 };
 
+int meson_get_engine_number(struct meson_dev *mc);
+
 void meson_dma_start(struct meson_dev *mc, int flow);
 
 int meson_enqueue(struct crypto_async_request *areq, u32 type);
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:55 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:55 +0300
Subject: [PATCH v4 07/20] drivers: crypto: meson: move algs definition and cipher API to cipher.c
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-8-avromanov@salutedevices.com>

Because that is proper place for them. In particular,
it takes less of exported symbol between compiling entities.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c |  98 +++++++++++++++--
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 110 ++++----------------
 drivers/crypto/amlogic/amlogic-gxl.h        |  14 +--
 3 files changed, 119 insertions(+), 103 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index dc0b100c5de2..bc3092a8a2c2 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -271,7 +271,7 @@ int meson_handle_cipher_request(struct crypto_engine *engine, void *areq)
 	return 0;
 }
 
-int meson_skdecrypt(struct skcipher_request *areq)
+static int meson_skdecrypt(struct skcipher_request *areq)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
 	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
@@ -289,7 +289,7 @@ int meson_skdecrypt(struct skcipher_request *areq)
 	return crypto_transfer_skcipher_request_to_engine(engine, areq);
 }
 
-int meson_skencrypt(struct skcipher_request *areq)
+static int meson_skencrypt(struct skcipher_request *areq)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
 	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
@@ -307,7 +307,7 @@ int meson_skencrypt(struct skcipher_request *areq)
 	return crypto_transfer_skcipher_request_to_engine(engine, areq);
 }
 
-int meson_cipher_init(struct crypto_tfm *tfm)
+static int meson_cipher_init(struct crypto_tfm *tfm)
 {
 	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 	struct meson_alg_template *algt;
@@ -333,7 +333,7 @@ int meson_cipher_init(struct crypto_tfm *tfm)
 	return 0;
 }
 
-void meson_cipher_exit(struct crypto_tfm *tfm)
+static void meson_cipher_exit(struct crypto_tfm *tfm)
 {
 	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 
@@ -341,8 +341,8 @@ void meson_cipher_exit(struct crypto_tfm *tfm)
 	crypto_free_skcipher(op->fallback_tfm);
 }
 
-int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
-		     unsigned int keylen)
+static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
+			    unsigned int keylen)
 {
 	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
 	struct meson_dev *mc = op->mc;
@@ -369,3 +369,89 @@ int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 
 	return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
 }
+
+static struct meson_alg_template algs[] = {
+{
+	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+	.blockmode = MESON_OPMODE_CBC,
+	.alg.skcipher.base = {
+		.base = {
+			.cra_name = "cbc(aes)",
+			.cra_driver_name = "cbc-aes-gxl",
+			.cra_priority = 400,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+				CRYPTO_ALG_NEED_FALLBACK,
+			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
+			.cra_module = THIS_MODULE,
+			.cra_alignmask = 0xf,
+			.cra_init = meson_cipher_init,
+			.cra_exit = meson_cipher_exit,
+		},
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.ivsize		= AES_BLOCK_SIZE,
+		.setkey		= meson_aes_setkey,
+		.encrypt	= meson_skencrypt,
+		.decrypt	= meson_skdecrypt,
+	},
+	.alg.skcipher.op = {
+		.do_one_request = meson_handle_cipher_request,
+	},
+},
+{
+	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+	.blockmode = MESON_OPMODE_ECB,
+	.alg.skcipher.base = {
+		.base = {
+			.cra_name = "ecb(aes)",
+			.cra_driver_name = "ecb-aes-gxl",
+			.cra_priority = 400,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+				CRYPTO_ALG_NEED_FALLBACK,
+			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
+			.cra_module = THIS_MODULE,
+			.cra_alignmask = 0xf,
+			.cra_init = meson_cipher_init,
+			.cra_exit = meson_cipher_exit,
+		},
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.setkey		= meson_aes_setkey,
+		.encrypt	= meson_skencrypt,
+		.decrypt	= meson_skdecrypt,
+	},
+	.alg.skcipher.op = {
+		.do_one_request = meson_handle_cipher_request,
+	},
+},
+};
+
+int meson_cipher_register(struct meson_dev *mc)
+{
+	return meson_register_algs(mc, algs, ARRAY_SIZE(algs));
+}
+
+void meson_cipher_unregister(struct meson_dev *mc)
+{
+	meson_unregister_algs(mc, algs, ARRAY_SIZE(algs));
+}
+
+void meson_cipher_debugfs_show(struct seq_file *seq, void *v)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(algs); i++) {
+		seq_printf(seq, "%s %s %lu %lu\n",
+			   algs[i].alg.skcipher.base.base.cra_driver_name,
+			   algs[i].alg.skcipher.base.base.cra_name,
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+			   algs[i].stat_req, algs[i].stat_fb);
+#else
+			   0ul, 0ul);
+#endif
+	}
+}
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f7c60ebffbc3..22ff2768b5e5 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -65,66 +65,6 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static struct meson_alg_template mc_algs[] = {
-{
-	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-	.blockmode = MESON_OPMODE_CBC,
-	.alg.skcipher.base = {
-		.base = {
-			.cra_name = "cbc(aes)",
-			.cra_driver_name = "cbc-aes-gxl",
-			.cra_priority = 400,
-			.cra_blocksize = AES_BLOCK_SIZE,
-			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
-				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
-				CRYPTO_ALG_NEED_FALLBACK,
-			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
-			.cra_module = THIS_MODULE,
-			.cra_alignmask = 0xf,
-			.cra_init = meson_cipher_init,
-			.cra_exit = meson_cipher_exit,
-		},
-		.min_keysize	= AES_MIN_KEY_SIZE,
-		.max_keysize	= AES_MAX_KEY_SIZE,
-		.ivsize		= AES_BLOCK_SIZE,
-		.setkey		= meson_aes_setkey,
-		.encrypt	= meson_skencrypt,
-		.decrypt	= meson_skdecrypt,
-	},
-	.alg.skcipher.op = {
-		.do_one_request = meson_handle_cipher_request,
-	},
-},
-{
-	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-	.blockmode = MESON_OPMODE_ECB,
-	.alg.skcipher.base = {
-		.base = {
-			.cra_name = "ecb(aes)",
-			.cra_driver_name = "ecb-aes-gxl",
-			.cra_priority = 400,
-			.cra_blocksize = AES_BLOCK_SIZE,
-			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
-				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
-				CRYPTO_ALG_NEED_FALLBACK,
-			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
-			.cra_module = THIS_MODULE,
-			.cra_alignmask = 0xf,
-			.cra_init = meson_cipher_init,
-			.cra_exit = meson_cipher_exit,
-		},
-		.min_keysize	= AES_MIN_KEY_SIZE,
-		.max_keysize	= AES_MAX_KEY_SIZE,
-		.setkey		= meson_aes_setkey,
-		.encrypt	= meson_skencrypt,
-		.decrypt	= meson_skdecrypt,
-	},
-	.alg.skcipher.op = {
-		.do_one_request = meson_handle_cipher_request,
-	},
-},
-};
-
 static int meson_debugfs_show(struct seq_file *seq, void *v)
 {
 	struct meson_dev *mc __maybe_unused = seq->private;
@@ -138,20 +78,8 @@ static int meson_debugfs_show(struct seq_file *seq, void *v)
 			   0ul);
 #endif
 
-	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
-		switch (mc_algs[i].type) {
-		case CRYPTO_ALG_TYPE_SKCIPHER:
-			seq_printf(seq, "%s %s %lu %lu\n",
-				   mc_algs[i].alg.skcipher.base.base.cra_driver_name,
-				   mc_algs[i].alg.skcipher.base.base.cra_name,
-#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
-				   mc_algs[i].stat_req, mc_algs[i].stat_fb);
-#else
-				   0ul, 0ul);
-#endif
-			break;
-		}
-	}
+	meson_cipher_debugfs_show(seq, v);
+
 	return 0;
 }
 DEFINE_SHOW_ATTRIBUTE(meson_debugfs);
@@ -228,38 +156,40 @@ static int meson_allocate_chanlist(struct meson_dev *mc)
 	return err;
 }
 
-static int meson_register_algs(struct meson_dev *mc)
+int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+			unsigned int count)
 {
 	int err, i;
 
-	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
-		mc_algs[i].mc = mc;
-		switch (mc_algs[i].type) {
+	for (i = 0; i < count; i++) {
+		switch (algs[i].type) {
 		case CRYPTO_ALG_TYPE_SKCIPHER:
-			err = crypto_engine_register_skcipher(&mc_algs[i].alg.skcipher);
+			err = crypto_engine_register_skcipher(&algs[i].alg.skcipher);
 			if (err) {
 				dev_err(mc->dev, "Fail to register %s\n",
-					mc_algs[i].alg.skcipher.base.base.cra_name);
-				mc_algs[i].mc = NULL;
+					algs[i].alg.skcipher.base.base.cra_name);
+				meson_unregister_algs(mc, algs, count);
 				return err;
 			}
 			break;
 		}
+		algs[i].mc = mc;
 	}
 
 	return 0;
 }
 
-static void meson_unregister_algs(struct meson_dev *mc)
+void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+			   unsigned int count)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
-		if (!mc_algs[i].mc)
+	for (i = 0; i < count; i++) {
+		if (!algs[i].mc)
 			continue;
-		switch (mc_algs[i].type) {
+		switch (algs[i].type) {
 		case CRYPTO_ALG_TYPE_SKCIPHER:
-			crypto_engine_unregister_skcipher(&mc_algs[i].alg.skcipher);
+			crypto_engine_unregister_skcipher(&algs[i].alg.skcipher);
 			break;
 		}
 	}
@@ -318,9 +248,9 @@ static int meson_crypto_probe(struct platform_device *pdev)
 	if (err)
 		goto error_flow;
 
-	err = meson_register_algs(mc);
+	err = meson_cipher_register(mc);
 	if (err)
-		goto error_alg;
+		goto error_flow;
 
 	if (IS_ENABLED(CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG)) {
 		struct dentry *dbgfs_dir;
@@ -334,8 +264,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
 	}
 
 	return 0;
-error_alg:
-	meson_unregister_algs(mc);
 error_flow:
 	meson_free_chanlist(mc, mc->flow_cnt - 1);
 	return err;
@@ -349,7 +277,7 @@ static void meson_crypto_remove(struct platform_device *pdev)
 	debugfs_remove_recursive(mc->dbgfs_dir);
 #endif
 
-	meson_unregister_algs(mc);
+	meson_cipher_unregister(mc);
 
 	meson_free_chanlist(mc, mc->flow_cnt - 1);
 }
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index e27908992ae3..0a03e8144977 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -167,10 +167,12 @@ void meson_dma_start(struct meson_dev *mc, int flow);
 
 int meson_enqueue(struct crypto_async_request *areq, u32 type);
 
-int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
-		     unsigned int keylen);
-int meson_cipher_init(struct crypto_tfm *tfm);
-void meson_cipher_exit(struct crypto_tfm *tfm);
-int meson_skdecrypt(struct skcipher_request *areq);
-int meson_skencrypt(struct skcipher_request *areq);
+int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+			unsigned int count);
+void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+			   unsigned int count);
+
+int meson_cipher_register(struct meson_dev *mc);
+void meson_cipher_unregister(struct meson_dev *mc);
+void meson_cipher_debugfs_show(struct seq_file *seq, void *v);
 int meson_handle_cipher_request(struct crypto_engine *engine, void *areq);
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:56 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:56 +0300
Subject: [PATCH v4 08/20] drivers: crypto: meson: cleanup defines
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-9-avromanov@salutedevices.com>

It is bad to use hardcoded values directly in the code.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 24 ++++++++++-----------
 drivers/crypto/amlogic/amlogic-gxl.h        | 16 ++++++++------
 2 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index bc3092a8a2c2..c662c4b86e97 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -141,8 +141,8 @@ static int meson_cipher(struct skcipher_request *areq)
 						 ivsize, 0);
 		}
 	}
-	if (keyivlen == 24)
-		keyivlen = 32;
+	if (keyivlen == AES_KEYSIZE_192)
+		keyivlen = AES_MAX_KEY_SIZE;
 
 	phykeyiv = dma_map_single(mc->dev, bkeyiv, keyivlen,
 				  DMA_TO_DEVICE);
@@ -161,7 +161,7 @@ static int meson_cipher(struct skcipher_request *areq)
 		todo = min(keyivlen - eat, 16u);
 		desc->t_src = cpu_to_le32(phykeyiv + i * 16);
 		desc->t_dst = cpu_to_le32(i * 16);
-		v = (MODE_KEY << 20) | DESC_OWN | 16;
+		v = DESC_MODE_KEY | DESC_OWN | 16;
 		desc->t_status = cpu_to_le32(v);
 
 		eat += todo;
@@ -205,7 +205,7 @@ static int meson_cipher(struct skcipher_request *areq)
 		desc->t_src = cpu_to_le32(sg_dma_address(src_sg));
 		desc->t_dst = cpu_to_le32(sg_dma_address(dst_sg));
 		todo = min(len, sg_dma_len(src_sg));
-		v = (op->keymode << 20) | DESC_OWN | todo | (algt->blockmode << 26);
+		v = op->keymode | DESC_OWN | todo | algt->blockmode;
 		if (rctx->op_dir)
 			v |= DESC_ENCRYPTION;
 		len -= todo;
@@ -348,14 +348,14 @@ static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 	struct meson_dev *mc = op->mc;
 
 	switch (keylen) {
-	case 128 / 8:
-		op->keymode = MODE_AES_128;
+	case AES_KEYSIZE_128:
+		op->keymode = DESC_MODE_AES_128;
 		break;
-	case 192 / 8:
-		op->keymode = MODE_AES_192;
+	case AES_KEYSIZE_192:
+		op->keymode = DESC_MODE_AES_192;
 		break;
-	case 256 / 8:
-		op->keymode = MODE_AES_256;
+	case AES_KEYSIZE_256:
+		op->keymode = DESC_MODE_AES_256;
 		break;
 	default:
 		dev_dbg(mc->dev, "ERROR: Invalid keylen %u\n", keylen);
@@ -373,7 +373,7 @@ static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 static struct meson_alg_template algs[] = {
 {
 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-	.blockmode = MESON_OPMODE_CBC,
+	.blockmode = DESC_OPMODE_CBC,
 	.alg.skcipher.base = {
 		.base = {
 			.cra_name = "cbc(aes)",
@@ -402,7 +402,7 @@ static struct meson_alg_template algs[] = {
 },
 {
 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
-	.blockmode = MESON_OPMODE_ECB,
+	.blockmode = DESC_OPMODE_ECB,
 	.alg.skcipher.base = {
 		.base = {
 			.cra_name = "ecb(aes)",
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 0a03e8144977..a0d83c82906d 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -11,19 +11,21 @@
 #include <linux/crypto.h>
 #include <linux/scatterlist.h>
 
-#define MODE_KEY 1
-#define MODE_AES_128 0x8
-#define MODE_AES_192 0x9
-#define MODE_AES_256 0xa
-
 #define MESON_DECRYPT 0
 #define MESON_ENCRYPT 1
 
-#define MESON_OPMODE_ECB 0
-#define MESON_OPMODE_CBC 1
+#define DESC_MODE_KEY (0x1 << 20)
+#define DESC_MODE_AES_128 (0x8 << 20)
+#define DESC_MODE_AES_192 (0x9 << 20)
+#define DESC_MODE_AES_256 (0xa << 20)
 
 #define MAXDESC 64
 
+#define DESC_OPMODE_ECB (0 << 26)
+#define DESC_OPMODE_CBC (1 << 26)
+
+#define DESC_MAXLEN ((1 << 17) - 1)
+
 #define DESC_LAST BIT(18)
 #define DESC_ENCRYPTION BIT(28)
 #define DESC_OWN BIT(31)
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:57 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:57 +0300
Subject: [PATCH v4 09/20] drivers: crypto: meson: process more than MAXDESCS descriptors
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-10-avromanov@salutedevices.com>

1. The old alhorithm was not designed to process a large
amount of memory, and therefore gave incorrect results.

2. Not all Amlogic SoC's use 3 KEY/IV descriptors.
Add keyiv descriptors count parameter to platform data.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 443 ++++++++++++--------
 drivers/crypto/amlogic/amlogic-gxl-core.c   |   1 +
 drivers/crypto/amlogic/amlogic-gxl.h        |   2 +
 3 files changed, 281 insertions(+), 165 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index c662c4b86e97..c1b3569a614a 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -17,35 +17,41 @@
 #include <crypto/internal/skcipher.h>
 #include "amlogic-gxl.h"
 
-static bool meson_cipher_need_fallback(struct skcipher_request *areq)
+static bool meson_cipher_need_fallback_sg(struct skcipher_request *areq,
+					  struct scatterlist *sg)
 {
-	struct scatterlist *src_sg = areq->src;
-	struct scatterlist *dst_sg = areq->dst;
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+	unsigned int blocksize = crypto_skcipher_blocksize(tfm);
+	unsigned int cryptlen = areq->cryptlen;
+
+	while (cryptlen) {
+		unsigned int len = min(cryptlen, sg->length);
+
+		if (!IS_ALIGNED(sg->offset, sizeof(u32)))
+			return true;
+		if (len % blocksize != 0)
+			return true;
+
+		cryptlen -= len;
+		sg = sg_next(sg);
+	}
+
+	return false;
+}
 
+static bool meson_cipher_need_fallback(struct skcipher_request *areq)
+{
 	if (areq->cryptlen == 0)
 		return true;
 
-	if (sg_nents(src_sg) != sg_nents(dst_sg))
+	if (meson_cipher_need_fallback_sg(areq, areq->src))
 		return true;
 
-	/* KEY/IV descriptors use 3 desc */
-	if (sg_nents(src_sg) > MAXDESC - 3 || sg_nents(dst_sg) > MAXDESC - 3)
-		return true;
+	if (areq->dst == areq->src)
+		return false;
 
-	while (src_sg && dst_sg) {
-		if ((src_sg->length % 16) != 0)
-			return true;
-		if ((dst_sg->length % 16) != 0)
-			return true;
-		if (src_sg->length != dst_sg->length)
-			return true;
-		if (!IS_ALIGNED(src_sg->offset, sizeof(u32)))
-			return true;
-		if (!IS_ALIGNED(dst_sg->offset, sizeof(u32)))
-			return true;
-		src_sg = sg_next(src_sg);
-		dst_sg = sg_next(dst_sg);
-	}
+	if (meson_cipher_need_fallback_sg(areq, areq->dst))
+		return true;
 
 	return false;
 }
@@ -76,6 +82,212 @@ static int meson_cipher_do_fallback(struct skcipher_request *areq)
 	return err;
 }
 
+struct cipher_ctx {
+	struct {
+		dma_addr_t addr;
+		unsigned int len;
+	} keyiv;
+
+	struct skcipher_request *areq;
+	struct scatterlist *src_sg;
+	struct scatterlist *dst_sg;
+	void *bkeyiv;
+
+	unsigned int src_offset;
+	unsigned int dst_offset;
+	unsigned int cryptlen;
+	unsigned int tloffset;
+};
+
+static int meson_map_scatterlist(struct skcipher_request *areq, struct meson_dev *mc)
+{
+	int nr_sgs, nr_sgd;
+
+	if (areq->src == areq->dst) {
+		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
+							DMA_BIDIRECTIONAL);
+		if (!nr_sgs) {
+			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
+			return -EINVAL;
+		}
+	} else {
+		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
+							DMA_TO_DEVICE);
+		if (!nr_sgs) {
+			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
+			return -EINVAL;
+		}
+
+		nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
+							DMA_FROM_DEVICE);
+		if (!nr_sgd) {
+			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void meson_unmap_scatterlist(struct skcipher_request *areq, struct meson_dev *mc)
+{
+	if (areq->src == areq->dst) {
+		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL);
+	} else {
+		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
+		dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE);
+	}
+}
+
+static void meson_setup_keyiv_descs(struct cipher_ctx *ctx)
+{
+	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
+	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+	struct meson_alg_template *algt = container_of(alg,
+		struct meson_alg_template, alg.skcipher.base);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+	struct meson_dev *mc = op->mc;
+	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+	unsigned int blockmode = algt->blockmode;
+	int i;
+
+	if (ctx->tloffset)
+		return;
+
+	if (blockmode == DESC_OPMODE_CBC) {
+		memcpy(ctx->bkeyiv + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
+		ctx->keyiv.len = AES_MAX_KEY_SIZE + ivsize;
+		dma_sync_single_for_device(mc->dev, ctx->keyiv.addr,
+					   ctx->keyiv.len, DMA_TO_DEVICE);
+	}
+
+	for (i = 0; i < mc->pdata->setup_desc_cnt; i++) {
+		struct meson_desc *desc =
+			&mc->chanlist[rctx->flow].tl[ctx->tloffset];
+		int offset = i * 16;
+
+		desc->t_src = cpu_to_le32(ctx->keyiv.addr + offset);
+		desc->t_dst = cpu_to_le32(offset);
+		desc->t_status = cpu_to_le32(DESC_OWN | DESC_MODE_KEY | ctx->keyiv.len);
+
+		ctx->tloffset++;
+	}
+}
+
+static bool meson_setup_data_descs(struct cipher_ctx *ctx)
+{
+	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+	struct meson_alg_template *algt = container_of(alg,
+						       struct meson_alg_template,
+						       alg.skcipher.base);
+	struct meson_dev *mc = op->mc;
+	struct meson_desc *desc = &mc->chanlist[rctx->flow].tl[ctx->tloffset];
+	unsigned int blocksize = crypto_skcipher_blocksize(tfm);
+	unsigned int blockmode = algt->blockmode;
+	unsigned int maxlen = rounddown(DESC_MAXLEN, blocksize);
+	unsigned int todo;
+	u32 v;
+
+	ctx->tloffset++;
+
+	todo = min(ctx->cryptlen, maxlen);
+	todo = min(todo, ctx->cryptlen);
+	todo = min(todo, sg_dma_len(ctx->src_sg) - ctx->src_offset);
+	todo = min(todo, sg_dma_len(ctx->dst_sg) - ctx->dst_offset);
+
+	desc->t_src = cpu_to_le32(sg_dma_address(ctx->src_sg) + ctx->src_offset);
+	desc->t_dst = cpu_to_le32(sg_dma_address(ctx->dst_sg) + ctx->dst_offset);
+
+	ctx->cryptlen -= todo;
+	ctx->src_offset += todo;
+	ctx->dst_offset += todo;
+
+	v = DESC_OWN | blockmode | op->keymode | todo;
+	if (rctx->op_dir == MESON_ENCRYPT)
+		v |= DESC_ENCRYPTION;
+
+	if (!ctx->cryptlen || ctx->tloffset == MAXDESC)
+		v |= DESC_LAST;
+
+	desc->t_status = cpu_to_le32(v);
+
+	return v & DESC_LAST;
+}
+
+static int meson_kick_hardware(struct cipher_ctx *ctx)
+{
+	struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+	struct meson_alg_template *algt = container_of(alg,
+						       struct meson_alg_template,
+						       alg.skcipher.base);
+	struct meson_dev *mc = op->mc;
+	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+	unsigned int blockmode = algt->blockmode;
+	enum dma_data_direction new_iv_dir;
+	dma_addr_t new_iv_phys;
+	void *new_iv;
+	int err;
+
+	if (blockmode == DESC_OPMODE_CBC) {
+		struct scatterlist *sg;
+		unsigned int offset;
+
+		if (rctx->op_dir == MESON_ENCRYPT) {
+			sg = ctx->dst_sg;
+			offset = ctx->dst_offset;
+			new_iv_dir = DMA_FROM_DEVICE;
+		} else {
+			sg = ctx->src_sg;
+			offset = ctx->src_offset;
+			new_iv_dir = DMA_TO_DEVICE;
+		}
+
+		if (ctx->areq->src == ctx->areq->dst)
+			new_iv_dir = DMA_BIDIRECTIONAL;
+
+		offset -= ivsize;
+		new_iv = sg_virt(sg) + offset;
+		new_iv_phys = sg_dma_address(sg) + offset;
+	}
+
+	if (blockmode == DESC_OPMODE_CBC &&
+		rctx->op_dir == MESON_DECRYPT) {
+		dma_sync_single_for_cpu(mc->dev, new_iv_phys,
+					ivsize, new_iv_dir);
+		memcpy(ctx->areq->iv, new_iv, ivsize);
+	}
+
+	reinit_completion(&mc->chanlist[rctx->flow].complete);
+	meson_dma_start(mc, rctx->flow);
+	err = wait_for_completion_interruptible_timeout(
+			&mc->chanlist[rctx->flow].complete, msecs_to_jiffies(500));
+	if (err == 0) {
+		dev_err(mc->dev, "DMA timeout for flow %d\n", rctx->flow);
+		return -EINVAL;
+	} else if (err < 0) {
+		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
+		return err;
+	}
+
+	if (blockmode == DESC_OPMODE_CBC &&
+		rctx->op_dir == MESON_ENCRYPT) {
+		dma_sync_single_for_cpu(mc->dev, new_iv_phys,
+					ivsize, new_iv_dir);
+		memcpy(ctx->areq->iv, new_iv, ivsize);
+	}
+
+	ctx->tloffset = 0;
+
+	return 0;
+}
+
 static int meson_cipher(struct skcipher_request *areq)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
@@ -84,176 +296,77 @@ static int meson_cipher(struct skcipher_request *areq)
 	struct meson_dev *mc = op->mc;
 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
 	struct meson_alg_template *algt;
-	int flow = rctx->flow;
-	unsigned int todo, eat, len;
-	struct scatterlist *src_sg = areq->src;
-	struct scatterlist *dst_sg = areq->dst;
-	struct meson_desc *desc;
-	int nr_sgs, nr_sgd;
-	int i, err = 0;
-	unsigned int keyivlen, ivsize, offset, tloffset;
-	dma_addr_t phykeyiv;
-	void *backup_iv = NULL, *bkeyiv;
-	u32 v;
-
-	algt = container_of(alg, struct meson_alg_template, alg.skcipher.base);
+	struct cipher_ctx ctx = {
+		.areq = areq,
+		.src_offset = 0,
+		.dst_offset = 0,
+		.src_sg = areq->src,
+		.dst_sg = areq->dst,
+		.cryptlen = areq->cryptlen,
+	};
+	int err;
 
-	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u flow=%d\n", __func__,
+	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u ctx.flow=%d\n", __func__,
 		crypto_tfm_alg_name(areq->base.tfm),
 		areq->cryptlen,
 		rctx->op_dir, crypto_skcipher_ivsize(tfm),
-		op->keylen, flow);
+		op->keylen, rctx->flow);
+
+	algt = container_of(alg, struct meson_alg_template, alg.skcipher.base);
 
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
 	algt->stat_req++;
-	mc->chanlist[flow].stat_req++;
+	mc->chanlist[rctx->flow].stat_req++;
 #endif
 
-	/*
-	 * The hardware expect a list of meson_desc structures.
-	 * The 2 first structures store key
-	 * The third stores IV
-	 */
-	bkeyiv = kzalloc(48, GFP_KERNEL | GFP_DMA);
-	if (!bkeyiv)
+	ctx.bkeyiv = kzalloc(48, GFP_KERNEL | GFP_DMA);
+	if (!ctx.bkeyiv)
 		return -ENOMEM;
 
-	memcpy(bkeyiv, op->key, op->keylen);
-	keyivlen = op->keylen;
+	memcpy(ctx.bkeyiv, op->key, op->keylen);
+	ctx.keyiv.len = op->keylen;
+	if (ctx.keyiv.len == AES_KEYSIZE_192)
+		ctx.keyiv.len = AES_MAX_KEY_SIZE;
 
-	ivsize = crypto_skcipher_ivsize(tfm);
-	if (areq->iv && ivsize > 0) {
-		if (ivsize > areq->cryptlen) {
-			dev_err(mc->dev, "invalid ivsize=%d vs len=%d\n", ivsize, areq->cryptlen);
-			err = -EINVAL;
-			goto theend;
-		}
-		memcpy(bkeyiv + 32, areq->iv, ivsize);
-		keyivlen = 48;
-		if (rctx->op_dir == MESON_DECRYPT) {
-			backup_iv = kzalloc(ivsize, GFP_KERNEL);
-			if (!backup_iv) {
-				err = -ENOMEM;
-				goto theend;
-			}
-			offset = areq->cryptlen - ivsize;
-			scatterwalk_map_and_copy(backup_iv, areq->src, offset,
-						 ivsize, 0);
-		}
-	}
-	if (keyivlen == AES_KEYSIZE_192)
-		keyivlen = AES_MAX_KEY_SIZE;
-
-	phykeyiv = dma_map_single(mc->dev, bkeyiv, keyivlen,
+	ctx.keyiv.addr = dma_map_single(mc->dev, ctx.bkeyiv, ctx.keyiv.len,
 				  DMA_TO_DEVICE);
-	err = dma_mapping_error(mc->dev, phykeyiv);
+	err = dma_mapping_error(mc->dev, ctx.keyiv.addr);
 	if (err) {
 		dev_err(mc->dev, "Cannot DMA MAP KEY IV\n");
 		goto theend;
 	}
 
-	tloffset = 0;
-	eat = 0;
-	i = 0;
-	while (keyivlen > eat) {
-		desc = &mc->chanlist[flow].tl[tloffset];
-		memset(desc, 0, sizeof(struct meson_desc));
-		todo = min(keyivlen - eat, 16u);
-		desc->t_src = cpu_to_le32(phykeyiv + i * 16);
-		desc->t_dst = cpu_to_le32(i * 16);
-		v = DESC_MODE_KEY | DESC_OWN | 16;
-		desc->t_status = cpu_to_le32(v);
-
-		eat += todo;
-		i++;
-		tloffset++;
-	}
-
-	if (areq->src == areq->dst) {
-		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
-				    DMA_BIDIRECTIONAL);
-		if (!nr_sgs) {
-			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
-			err = -EINVAL;
-			goto theend;
-		}
-		nr_sgd = nr_sgs;
-	} else {
-		nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
-				    DMA_TO_DEVICE);
-		if (!nr_sgs || nr_sgs > MAXDESC - 3) {
-			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
-			err = -EINVAL;
-			goto theend;
-		}
-		nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
-				    DMA_FROM_DEVICE);
-		if (!nr_sgd || nr_sgd > MAXDESC - 3) {
-			dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
-			err = -EINVAL;
-			goto theend;
-		}
-	}
-
-	src_sg = areq->src;
-	dst_sg = areq->dst;
-	len = areq->cryptlen;
-	while (src_sg) {
-		desc = &mc->chanlist[flow].tl[tloffset];
-		memset(desc, 0, sizeof(struct meson_desc));
-
-		desc->t_src = cpu_to_le32(sg_dma_address(src_sg));
-		desc->t_dst = cpu_to_le32(sg_dma_address(dst_sg));
-		todo = min(len, sg_dma_len(src_sg));
-		v = op->keymode | DESC_OWN | todo | algt->blockmode;
-		if (rctx->op_dir)
-			v |= DESC_ENCRYPTION;
-		len -= todo;
-
-		if (!sg_next(src_sg))
-			v |= DESC_LAST;
-		desc->t_status = cpu_to_le32(v);
-		tloffset++;
-		src_sg = sg_next(src_sg);
-		dst_sg = sg_next(dst_sg);
-	}
+	err = meson_map_scatterlist(areq, mc);
+	if (err)
+		goto theend;
 
-	reinit_completion(&mc->chanlist[flow].complete);
-	meson_dma_start(mc, flow);
+	ctx.tloffset = 0;
 
-	err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
-							msecs_to_jiffies(500));
-	if (err == 0) {
-		dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
-		err = -EINVAL;
-	} else if (err < 0) {
-		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
-	} else {
-		/* No error */
-		err = 0;
-	}
+	while (ctx.cryptlen) {
+		meson_setup_keyiv_descs(&ctx);
 
-	dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
+		if (meson_setup_data_descs(&ctx)) {
+			err = meson_kick_hardware(&ctx);
+			if (err)
+				break;
+		}
 
-	if (areq->src == areq->dst) {
-		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL);
-	} else {
-		dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
-		dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE);
-	}
+		if (ctx.src_offset == sg_dma_len(ctx.src_sg)) {
+			ctx.src_offset = 0;
+			ctx.src_sg = sg_next(ctx.src_sg);
+		}
 
-	if (areq->iv && ivsize > 0) {
-		if (rctx->op_dir == MESON_DECRYPT) {
-			memcpy(areq->iv, backup_iv, ivsize);
-		} else {
-			scatterwalk_map_and_copy(areq->iv, areq->dst,
-						 areq->cryptlen - ivsize,
-						 ivsize, 0);
+		if (ctx.dst_offset == sg_dma_len(ctx.dst_sg)) {
+			ctx.dst_offset = 0;
+			ctx.dst_sg = sg_next(ctx.dst_sg);
 		}
 	}
+
+	dma_unmap_single(mc->dev, ctx.keyiv.addr, ctx.keyiv.len, DMA_TO_DEVICE);
+	meson_unmap_scatterlist(areq, mc);
+
 theend:
-	kfree_sensitive(bkeyiv);
-	kfree_sensitive(backup_iv);
+	kfree_sensitive(ctx.bkeyiv);
 
 	return err;
 }
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 22ff2768b5e5..f93e14f5717d 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -199,6 +199,7 @@ static const struct meson_pdata meson_gxl_pdata = {
 	.descs_reg = 0x0,
 	.status_reg = 0x4,
 	.need_clk = true,
+	.setup_desc_cnt = 3,
 };
 
 static const struct of_device_id meson_crypto_of_match_table[] = {
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index a0d83c82906d..eb2f8cd72b65 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -83,11 +83,13 @@ struct meson_flow {
  * @reg_descs:	offset to descriptors register
  * @reg_status:	offset to status register
  * @need_clk:	clock input is needed
+ * @setup_desc_cnt:	number of setup descriptor to configure.
  */
 struct meson_pdata {
 	u32 descs_reg;
 	u32 status_reg;
 	bool need_clk;
+	u32 setup_desc_cnt;
 };
 
 /*
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:58 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:58 +0300
Subject: [PATCH v4 10/20] drivers: crypto: meson: avoid kzalloc in engine thread
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-11-avromanov@salutedevices.com>

It makes no sense to allocate memory via kzalloc, we
can use static buffer, speedup data processing and
don't think about kfree() calls.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 26 ++++++++-------------
 drivers/crypto/amlogic/amlogic-gxl.h        |  6 ++---
 2 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index c1b3569a614a..3f42b2cc568d 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -91,7 +91,6 @@ struct cipher_ctx {
 	struct skcipher_request *areq;
 	struct scatterlist *src_sg;
 	struct scatterlist *dst_sg;
-	void *bkeyiv;
 
 	unsigned int src_offset;
 	unsigned int dst_offset;
@@ -156,8 +155,7 @@ static void meson_setup_keyiv_descs(struct cipher_ctx *ctx)
 		return;
 
 	if (blockmode == DESC_OPMODE_CBC) {
-		memcpy(ctx->bkeyiv + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
-		ctx->keyiv.len = AES_MAX_KEY_SIZE + ivsize;
+		memcpy(op->keyiv + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
 		dma_sync_single_for_device(mc->dev, ctx->keyiv.addr,
 					   ctx->keyiv.len, DMA_TO_DEVICE);
 	}
@@ -304,6 +302,7 @@ static int meson_cipher(struct skcipher_request *areq)
 		.dst_sg = areq->dst,
 		.cryptlen = areq->cryptlen,
 	};
+	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
 	int err;
 
 	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u ctx.flow=%d\n", __func__,
@@ -319,16 +318,16 @@ static int meson_cipher(struct skcipher_request *areq)
 	mc->chanlist[rctx->flow].stat_req++;
 #endif
 
-	ctx.bkeyiv = kzalloc(48, GFP_KERNEL | GFP_DMA);
-	if (!ctx.bkeyiv)
-		return -ENOMEM;
-
-	memcpy(ctx.bkeyiv, op->key, op->keylen);
 	ctx.keyiv.len = op->keylen;
 	if (ctx.keyiv.len == AES_KEYSIZE_192)
 		ctx.keyiv.len = AES_MAX_KEY_SIZE;
 
-	ctx.keyiv.addr = dma_map_single(mc->dev, ctx.bkeyiv, ctx.keyiv.len,
+	if (algt->blockmode == DESC_OPMODE_CBC) {
+		memcpy(op->keyiv + AES_MAX_KEY_SIZE, areq->iv, ivsize);
+		ctx.keyiv.len = AES_MAX_KEY_SIZE + ivsize;
+	}
+
+	ctx.keyiv.addr = dma_map_single(mc->dev, op->keyiv, ctx.keyiv.len,
 				  DMA_TO_DEVICE);
 	err = dma_mapping_error(mc->dev, ctx.keyiv.addr);
 	if (err) {
@@ -366,8 +365,6 @@ static int meson_cipher(struct skcipher_request *areq)
 	meson_unmap_scatterlist(areq, mc);
 
 theend:
-	kfree_sensitive(ctx.bkeyiv);
-
 	return err;
 }
 
@@ -450,7 +447,6 @@ static void meson_cipher_exit(struct crypto_tfm *tfm)
 {
 	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 
-	kfree_sensitive(op->key);
 	crypto_free_skcipher(op->fallback_tfm);
 }
 
@@ -474,11 +470,9 @@ static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 		dev_dbg(mc->dev, "ERROR: Invalid keylen %u\n", keylen);
 		return -EINVAL;
 	}
-	kfree_sensitive(op->key);
+
+	memcpy(op->keyiv, key, keylen);
 	op->keylen = keylen;
-	op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
-	if (!op->key)
-		return -ENOMEM;
 
 	return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
 }
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index eb2f8cd72b65..e1453dd2e9f4 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -129,15 +129,15 @@ struct meson_cipher_req_ctx {
 
 /*
  * struct meson_cipher_tfm_ctx - context for a skcipher TFM
- * @key:		pointer to key data
+ * @keyiv:		key data
  * @keylen:		len of the key
  * @keymode:		The keymode(type and size of key) associated with this TFM
  * @mc:			pointer to the private data of driver handling this TFM
  * @fallback_tfm:	pointer to the fallback TFM
  */
 struct meson_cipher_tfm_ctx {
-	u32 *key;
-	u32 keylen;
+	u8 keyiv[AES_MAX_KEY_SIZE + AES_BLOCK_SIZE] ____cacheline_aligned;
+	u32 keylen ____cacheline_aligned;
 	u32 keymode;
 	struct meson_dev *mc;
 	struct crypto_skcipher *fallback_tfm;
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:51:02 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:51:02 +0300
Subject: [PATCH v4 14/20] drivers: crypto: meson: add support for G12-series
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-15-avromanov@salutedevices.com>

This platform data also can be used for A1 and S4 as fallback.
Tested via tcrypt module and with custom tests.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-core.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 429c3474028b..2ffe5994b353 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -218,11 +218,31 @@ static const struct meson_pdata meson_gxl_pdata = {
 	.support_192bit_key = true,
 };
 
+static const struct meson_pdata meson_g12a_pdata = {
+	.descs_reg = 0x0,
+	.status_reg = 0x8,
+	.need_clk = false,
+	.setup_desc_cnt = 1,
+	.support_192bit_key = false,
+};
+
 static const struct of_device_id meson_crypto_of_match_table[] = {
 	{
 		.compatible = "amlogic,gxl-crypto",
 		.data = &meson_gxl_pdata,
 	},
+	{
+		.compatible = "amlogic,g12a-crypto",
+		.data = &meson_g12a_pdata,
+	},
+	{
+		.compatible = "amlogic,a1-crypto",
+		.data = &meson_g12a_pdata,
+	},
+	{
+		.compatible = "amlogic,s4-crypto",
+		.data = &meson_g12a_pdata,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:51:06 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:51:06 +0300
Subject: [PATCH v4 18/20] arch: arm64: dts: meson: s4: add crypto node
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-19-avromanov@salutedevices.com>

This patch adds a crypto node declaration for Amlogic S4-series.
With the Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 arch/arm64/boot/dts/amlogic/meson-s4.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
index ce90b35686a2..dc05e2c5da3b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -339,6 +339,12 @@ mux {
 
 			};
 
+			crypto: crypto at 440400 {
+				compatible = "amlogic,s4-crypto", "amlogic,g12a-crypto";
+				reg = <0x0 0x440400 0x0 0x48>;
+				interrupts = <GIC_SPI 24 IRQ_TYPE_EDGE_RISING>;
+			};
+
 			gpio_intc: interrupt-controller at 4080 {
 				compatible = "amlogic,meson-s4-gpio-intc",
 					     "amlogic,meson-gpio-intc";
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:51:04 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:51:04 +0300
Subject: [PATCH v4 16/20] dt-bindings: crypto: meson: support new SoC's
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-17-avromanov@salutedevices.com>

Now crypto module available at G12A/G12B/S4/A1/SM1/AXG.

1. Add new compatibles:
  - amlogic,g12a-crypto
  - amlogic,s4-crypto (uses g12a-crypto as fallback)
  - amlogic,a1-crypto (uses g12a-crypto as fallback)
  - amlogic,axg-crypto

2. All SoC's, exclude GXL, doesn't take a clock input for
Crypto IP. Make it required only for amlogic,gxl-crypto.

3. All SoC's, exclude GXL, uses only one interrupt flow
for Crypto IP.

4. Add power-domains in schema.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 .../bindings/crypto/amlogic,gxl-crypto.yaml   | 43 ++++++++++++++++---
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
index 948e11ebe4ee..41f0153d58c8 100644
--- a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
+++ b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
@@ -11,20 +11,30 @@ maintainers:
 
 properties:
   compatible:
-    items:
-      - const: amlogic,gxl-crypto
+    oneOf:
+      - items:
+          - enum:
+              - amlogic,a1-crypto
+              - amlogic,s4-crypto
+          - const: amlogic,g12a-crypto
+      - enum:
+          - amlogic,gxl-crypto
+          - amlogic,axg-crypto
+          - amlogic,g12a-crypto
 
   reg:
     maxItems: 1
 
   interrupts:
-    items:
-      - description: Interrupt for flow 0
-      - description: Interrupt for flow 1
+    minItems: 1
+    maxItems: 2
 
   clocks:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
   clock-names:
     const: blkmv
 
@@ -32,8 +42,27 @@ required:
   - compatible
   - reg
   - interrupts
-  - clocks
-  - clock-names
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: amlogic,gxl-crypto
+    then:
+      required:
+        - clocks
+        - clock-names
+      properties:
+        interrupts:
+          items:
+            - description: Interrupt for flow 0
+            - description: Interrupt for flow 1
+    else:
+      properties:
+        interrupts:
+          items:
+            - description: Interrupt for flow 0
 
 additionalProperties: false
 
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:51:05 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:51:05 +0300
Subject: [PATCH v4 17/20] arch: arm64: dts: meson: a1: add crypto node
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-18-avromanov@salutedevices.com>

This patch adds a crypto node declaration. With the
Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
index b9fd69112535..6d11e38ca3c0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
@@ -653,6 +653,13 @@ sd_emmc: sd at 10000 {
 				power-domains = <&pwrc PWRC_SD_EMMC_ID>;
 				status = "disabled";
 			};
+
+			crypto: crypto at 6000 {
+				compatible = "amlogic,a1-crypto", "amlogic,g12a-crypto";
+				reg = <0x0 0x6000 0x0 0x48>;
+				interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>;
+				power-domains = <&pwrc PWRC_DMA_ID>;
+			};
 		};
 
 		usb: usb at fe004400 {
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:51:07 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:51:07 +0300
Subject: [PATCH v4 19/20] arch: arm64: dts: meson: g12: add crypto node
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-20-avromanov@salutedevices.com>

This patch adds a crypto node declaration for Amlogic G12-series.
With the Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.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 ff68b911b729..f6d7047a579c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1709,6 +1709,12 @@ internal_ephy: ethernet-phy at 8 {
 					};
 				};
 			};
+
+			crypto: crypto at 3e000 {
+				compatible = "amlogic,g12a-crypto";
+				reg = <0x0 0x3e000 0x0 0x48>;
+				interrupts = <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>;
+			};
 		};
 
 		aobus: bus at ff800000 {
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:51:00 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:51:00 +0300
Subject: [PATCH v4 12/20] drivers: crypto: meson: add support for AES-CTR
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-13-avromanov@salutedevices.com>

This patch adds support for AES-CTR algorithm.
Tested via tcrypt and custom tests.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 44 +++++++++++++++++++--
 drivers/crypto/amlogic/amlogic-gxl.h        |  1 +
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 3f42b2cc568d..828109f4a1c3 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -154,7 +154,7 @@ static void meson_setup_keyiv_descs(struct cipher_ctx *ctx)
 	if (ctx->tloffset)
 		return;
 
-	if (blockmode == DESC_OPMODE_CBC) {
+	if (blockmode == DESC_OPMODE_CBC || blockmode == DESC_OPMODE_CTR) {
 		memcpy(op->keyiv + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
 		dma_sync_single_for_device(mc->dev, ctx->keyiv.addr,
 					   ctx->keyiv.len, DMA_TO_DEVICE);
@@ -186,6 +186,7 @@ static bool meson_setup_data_descs(struct cipher_ctx *ctx)
 	struct meson_desc *desc = &mc->chanlist[rctx->flow].tl[ctx->tloffset];
 	unsigned int blocksize = crypto_skcipher_blocksize(tfm);
 	unsigned int blockmode = algt->blockmode;
+	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
 	unsigned int maxlen = rounddown(DESC_MAXLEN, blocksize);
 	unsigned int todo;
 	u32 v;
@@ -204,8 +205,15 @@ static bool meson_setup_data_descs(struct cipher_ctx *ctx)
 	ctx->src_offset += todo;
 	ctx->dst_offset += todo;
 
+	if (blockmode == DESC_OPMODE_CTR) {
+		unsigned int nblocks = todo / blocksize;
+
+		while (nblocks--)
+			crypto_inc(ctx->areq->iv, ivsize);
+	}
+
 	v = DESC_OWN | blockmode | op->keymode | todo;
-	if (rctx->op_dir == MESON_ENCRYPT)
+	if (rctx->op_dir == MESON_ENCRYPT || blockmode == DESC_OPMODE_CTR)
 		v |= DESC_ENCRYPTION;
 
 	if (!ctx->cryptlen || ctx->tloffset == MAXDESC)
@@ -322,7 +330,8 @@ static int meson_cipher(struct skcipher_request *areq)
 	if (ctx.keyiv.len == AES_KEYSIZE_192)
 		ctx.keyiv.len = AES_MAX_KEY_SIZE;
 
-	if (algt->blockmode == DESC_OPMODE_CBC) {
+	if (algt->blockmode == DESC_OPMODE_CBC ||
+		algt->blockmode == DESC_OPMODE_CTR) {
 		memcpy(op->keyiv + AES_MAX_KEY_SIZE, areq->iv, ivsize);
 		ctx.keyiv.len = AES_MAX_KEY_SIZE + ivsize;
 	}
@@ -535,6 +544,35 @@ static struct meson_alg_template algs[] = {
 		.do_one_request = meson_handle_cipher_request,
 	},
 },
+{
+	.type = CRYPTO_ALG_TYPE_SKCIPHER,
+	.blockmode = DESC_OPMODE_CTR,
+	.alg.skcipher.base = {
+		.base = {
+			.cra_name = "ctr(aes)",
+			.cra_driver_name = "ctr-aes-gxl",
+			.cra_priority = 400,
+			.cra_blocksize = AES_BLOCK_SIZE,
+			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+				CRYPTO_ALG_NEED_FALLBACK,
+			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
+			.cra_module = THIS_MODULE,
+			.cra_alignmask = 0xf,
+			.cra_init = meson_cipher_init,
+			.cra_exit = meson_cipher_exit,
+		},
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.ivsize		= AES_BLOCK_SIZE,
+		.setkey		= meson_aes_setkey,
+		.encrypt	= meson_skencrypt,
+		.decrypt	= meson_skdecrypt,
+	},
+	.alg.skcipher.op = {
+		.do_one_request = meson_handle_cipher_request,
+	},
+},
 };
 
 int meson_cipher_register(struct meson_dev *mc)
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index a07b4f6b3bcc..7f6d91e7b365 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -24,6 +24,7 @@
 
 #define DESC_OPMODE_ECB (0 << 26)
 #define DESC_OPMODE_CBC (1 << 26)
+#define DESC_OPMODE_CTR (2 << 26)
 #define DESC_OPMODE_SHA (0 << 26)
 
 #define DESC_MAXLEN ((1 << 17) - 1)
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:50:59 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:50:59 +0300
Subject: [PATCH v4 11/20] drivers: crypto: meson: introduce hasher
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-12-avromanov@salutedevices.com>

Introduce support for SHA1/SHA224/SHA256 hash algos.
Tested via tcrypt and custom tests.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/Makefile             |   2 +-
 drivers/crypto/amlogic/amlogic-gxl-core.c   |  24 +-
 drivers/crypto/amlogic/amlogic-gxl-hasher.c | 452 ++++++++++++++++++++
 drivers/crypto/amlogic/amlogic-gxl.h        |  49 +++
 4 files changed, 525 insertions(+), 2 deletions(-)
 create mode 100644 drivers/crypto/amlogic/amlogic-gxl-hasher.c

diff --git a/drivers/crypto/amlogic/Makefile b/drivers/crypto/amlogic/Makefile
index 39057e62c13e..4b6b388b7880 100644
--- a/drivers/crypto/amlogic/Makefile
+++ b/drivers/crypto/amlogic/Makefile
@@ -1,2 +1,2 @@
 obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic-gxl-crypto.o
-amlogic-gxl-crypto-y := amlogic-gxl-core.o amlogic-gxl-cipher.o
+amlogic-gxl-crypto-y := amlogic-gxl-core.o amlogic-gxl-cipher.o amlogic-gxl-hasher.o
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f93e14f5717d..f3b5e004b3a5 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -20,6 +20,9 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/internal/hash.h>
+#include <linux/dma-mapping.h>
 
 #include "amlogic-gxl.h"
 
@@ -172,6 +175,15 @@ int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
 				return err;
 			}
 			break;
+		case CRYPTO_ALG_TYPE_AHASH:
+			err = crypto_engine_register_ahash(&algs[i].alg.ahash);
+			if (err) {
+				dev_err(mc->dev, "Fail to register %s\n",
+					algs[i].alg.ahash.base.halg.base.cra_name);
+				meson_unregister_algs(mc, algs, count);
+				return err;
+			}
+			break;
 		}
 		algs[i].mc = mc;
 	}
@@ -191,6 +203,9 @@ void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs
 		case CRYPTO_ALG_TYPE_SKCIPHER:
 			crypto_engine_unregister_skcipher(&algs[i].alg.skcipher);
 			break;
+		case CRYPTO_ALG_TYPE_AHASH:
+			crypto_engine_unregister_ahash(&algs[i].alg.ahash);
+			break;
 		}
 	}
 }
@@ -258,13 +273,20 @@ static int meson_crypto_probe(struct platform_device *pdev)
 
 		dbgfs_dir = debugfs_create_dir("gxl-crypto", NULL);
 		debugfs_create_file("stats", 0444, dbgfs_dir, mc, &meson_debugfs_fops);
-
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
 		mc->dbgfs_dir = dbgfs_dir;
 #endif
 	}
 
+	err = meson_hasher_register(mc);
+	if (err)
+		goto error_hasher;
+
 	return 0;
+
+error_hasher:
+	meson_cipher_unregister(mc);
+
 error_flow:
 	meson_free_chanlist(mc, mc->flow_cnt - 1);
 	return err;
diff --git a/drivers/crypto/amlogic/amlogic-gxl-hasher.c b/drivers/crypto/amlogic/amlogic-gxl-hasher.c
new file mode 100644
index 000000000000..04f85cd4d97f
--- /dev/null
+++ b/drivers/crypto/amlogic/amlogic-gxl-hasher.c
@@ -0,0 +1,452 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hardware asynchronous hasher for Amlogic SoC's.
+ *
+ * Copyright (c) 2023, SaluteDevices. All Rights Reserved.
+ *
+ * Author: Alexey Romanov <avromanov at salutedevices.com>
+ */
+
+#include <linux/crypto.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <crypto/internal/hash.h>
+#include <crypto/sha1.h>
+#include <crypto/sha2.h>
+
+#include "amlogic-gxl.h"
+
+static int meson_sha_init(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+
+	memset(rctx, 0, sizeof(struct meson_hasher_req_ctx));
+
+	rctx->flow = meson_get_engine_number(tctx->mc);
+	rctx->begin_req = true;
+
+	return 0;
+}
+
+static int meson_sha_update(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct crypto_engine *engine = tctx->mc->chanlist[rctx->flow].engine;
+
+	return crypto_transfer_hash_request_to_engine(engine, req);
+}
+
+static int meson_sha_final(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct crypto_engine *engine = tctx->mc->chanlist[rctx->flow].engine;
+
+	rctx->final_req = true;
+
+	return crypto_transfer_hash_request_to_engine(engine, req);
+}
+
+static int meson_hasher_req_map(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_dev *mc = tctx->mc;
+	int ret;
+
+	if (!req->nbytes)
+		return 0;
+
+	ret = dma_map_sg(mc->dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
+	if (!ret) {
+		dev_err(mc->dev, "Cannot DMA MAP request data\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void meson_hasher_req_unmap(struct ahash_request *req)
+{
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_dev *mc = tctx->mc;
+
+	if (!req->nbytes)
+		return;
+
+	dma_unmap_sg(mc->dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
+}
+
+struct hasher_ctx {
+	struct crypto_async_request *areq;
+
+	unsigned int tloffset;
+	unsigned int nbytes;
+	unsigned int todo;
+
+	dma_addr_t state_addr;
+	dma_addr_t src_addr;
+	unsigned int src_offset;
+	struct scatterlist *src_sg;
+};
+
+static bool meson_final(struct hasher_ctx *ctx)
+{
+	struct ahash_request *req = ahash_request_cast(ctx->areq);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+
+	return !ctx->nbytes && rctx->final_req;
+}
+
+static int meson_fill_partial_buffer(struct hasher_ctx *ctx, unsigned int len)
+{
+	struct ahash_request *req = ahash_request_cast(ctx->areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct meson_dev *mc = tctx->mc;
+	unsigned int blocksize = crypto_ahash_blocksize(tfm);
+	unsigned int copy;
+
+	if (len) {
+		copy = min(blocksize - rctx->partial_size, len);
+		memcpy(rctx->partial + rctx->partial_size,
+				sg_virt(ctx->src_sg) + ctx->src_offset, copy);
+
+		rctx->partial_size += copy;
+		ctx->nbytes -= copy;
+		ctx->src_offset += copy;
+	}
+
+	if (rctx->partial_size == blocksize || meson_final(ctx)) {
+		rctx->partial_addr = dma_map_single(mc->dev,
+						   rctx->partial,
+						   rctx->partial_size,
+						   DMA_TO_DEVICE);
+		if (dma_mapping_error(mc->dev, rctx->partial_addr)) {
+			dev_err(mc->dev, "Cannot DMA MAP SHA partial buffer\n");
+			return -ENOMEM;
+		}
+
+		rctx->partial_mapped = true;
+		ctx->todo = rctx->partial_size;
+		ctx->src_addr = rctx->partial_addr;
+	}
+
+	return 0;
+}
+
+static unsigned int meson_setup_data_descs(struct hasher_ctx *ctx)
+{
+	struct ahash_request *req = ahash_request_cast(ctx->areq);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_dev *mc = tctx->mc;
+	struct meson_flow *flow = &mc->chanlist[rctx->flow];
+	struct hash_alg_common *alg = crypto_hash_alg_common(tfm);
+	struct meson_alg_template *algt = container_of(alg,
+		struct meson_alg_template, alg.ahash.base.halg);
+	struct meson_desc *desc = &flow->tl[ctx->tloffset];
+	u32 v;
+
+	ctx->tloffset++;
+
+	v = DESC_OWN | DESC_ENCRYPTION | DESC_OPMODE_SHA |
+	    ctx->todo | algt->blockmode;
+	if (rctx->begin_req) {
+		rctx->begin_req = false;
+		v |= DESC_BEGIN;
+	}
+
+	if (!ctx->nbytes && rctx->final_req) {
+		rctx->final_req = false;
+		v |= DESC_END;
+	}
+
+	if (!ctx->nbytes || ctx->tloffset == MAXDESC || rctx->partial_mapped)
+		v |= DESC_LAST;
+
+	desc->t_src = cpu_to_le32(ctx->src_addr);
+	desc->t_dst = cpu_to_le32(ctx->state_addr);
+	desc->t_status = cpu_to_le32(v);
+
+	return v & DESC_LAST;
+}
+
+static int meson_kick_hardware(struct hasher_ctx *ctx)
+{
+	struct ahash_request *req = ahash_request_cast(ctx->areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_dev *mc = tctx->mc;
+	struct meson_flow *flow = &mc->chanlist[rctx->flow];
+	int ret;
+
+	reinit_completion(&flow->complete);
+	meson_dma_start(mc, rctx->flow);
+
+	ret = wait_for_completion_timeout(&flow->complete,
+					  msecs_to_jiffies(500));
+	if (ret == 0) {
+		dev_err(mc->dev, "DMA timeout for flow %d\n", rctx->flow);
+		return -EINVAL;
+	} else if (ret < 0) {
+		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", ret);
+		return ret;
+	}
+
+	if (rctx->partial_mapped) {
+		dma_unmap_single(mc->dev, rctx->partial_addr,
+				 rctx->partial_size,
+				 DMA_TO_DEVICE);
+		rctx->partial_size = 0;
+		rctx->partial_mapped = false;
+	}
+
+	ctx->tloffset = 0;
+
+	return 0;
+}
+
+static void meson_setup_state_descs(struct hasher_ctx *ctx)
+{
+	struct ahash_request *req = ahash_request_cast(ctx->areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_dev *mc = tctx->mc;
+	struct meson_desc *desc;
+	int i;
+
+	if (ctx->tloffset || rctx->begin_req)
+		return;
+
+	for (i = 0; i < mc->pdata->setup_desc_cnt; i++) {
+		int offset = i * 16;
+
+		desc = &mc->chanlist[rctx->flow].tl[ctx->tloffset];
+		desc->t_src = cpu_to_le32(ctx->state_addr + offset);
+		desc->t_dst = cpu_to_le32(offset);
+		desc->t_status = cpu_to_le32(MESON_SHA_BUFFER_SIZE |
+					     DESC_MODE_KEY | DESC_OWN);
+
+		ctx->tloffset++;
+	}
+}
+
+static int meson_hasher_do_one_request(struct crypto_engine *engine, void *areq)
+{
+	struct ahash_request *req = ahash_request_cast(areq);
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+	struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+	struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+	struct meson_dev *mc = tctx->mc;
+	struct hasher_ctx ctx = {
+		.tloffset = 0,
+		.src_offset = 0,
+		.nbytes = req->nbytes,
+		.src_sg = req->src,
+		.areq = areq,
+	};
+	unsigned int blocksize = crypto_ahash_blocksize(tfm);
+	unsigned int digest_size = crypto_ahash_digestsize(tfm);
+	bool final_req = rctx->final_req;
+	int ret;
+
+	ctx.state_addr = dma_map_single(mc->dev, rctx->state,
+			   sizeof(rctx->state), DMA_BIDIRECTIONAL);
+	ret = dma_mapping_error(mc->dev, ctx.state_addr);
+	if (ret) {
+		dev_err(mc->dev, "Cannot DMA MAP SHA state buffer");
+		goto fail_map_single;
+	}
+
+	ret = meson_hasher_req_map(req);
+	if (ret)
+		goto fail_map_req;
+
+	for (;;) {
+		unsigned int len = ctx.src_sg ?
+			min(sg_dma_len(ctx.src_sg) - ctx.src_offset, ctx.nbytes) : 0;
+
+		ctx.src_addr = 0;
+		ctx.todo = 0;
+
+		if (!rctx->final_req && !ctx.nbytes)
+			break;
+
+		meson_setup_state_descs(&ctx);
+
+		if (rctx->partial_size && rctx->partial_size < blocksize) {
+			ret = meson_fill_partial_buffer(&ctx, len);
+			if (ret)
+				goto fail;
+		} else if (len && len < blocksize) {
+			memcpy(rctx->partial, sg_virt(ctx.src_sg) + ctx.src_offset, len);
+
+			rctx->partial_size = len;
+			ctx.nbytes -= len;
+			ctx.src_offset += len;
+		} else if (len) {
+			ctx.src_addr = sg_dma_address(ctx.src_sg) + ctx.src_offset;
+			ctx.todo = min(rounddown(DESC_MAXLEN, blocksize),
+					rounddown(len, blocksize));
+			ctx.nbytes -= ctx.todo;
+			ctx.src_offset += ctx.todo;
+		}
+
+		if (ctx.src_sg && ctx.src_offset == sg_dma_len(ctx.src_sg)) {
+			ctx.src_offset = 0;
+			ctx.src_sg = sg_next(ctx.src_sg);
+		}
+
+		if (!ctx.todo && ctx.nbytes)
+			continue;
+
+		if (!ctx.todo && !rctx->final_req && !ctx.tloffset)
+			continue;
+
+		if (meson_setup_data_descs(&ctx)) {
+			ret = meson_kick_hardware(&ctx);
+			if (ret)
+				goto fail;
+		}
+	}
+
+fail:
+	meson_hasher_req_unmap(req);
+
+fail_map_req:
+	dma_unmap_single(mc->dev, ctx.state_addr, sizeof(rctx->state),
+			 DMA_BIDIRECTIONAL);
+
+fail_map_single:
+	if (final_req && ret == 0)
+		memcpy(req->result, rctx->state, digest_size);
+
+	local_bh_disable();
+	crypto_finalize_hash_request(engine, req, ret);
+	local_bh_enable();
+
+	return ret;
+}
+
+static int meson_hasher_init(struct crypto_tfm *tfm)
+{
+	struct meson_hasher_tfm_ctx *tctx = crypto_tfm_ctx(tfm);
+	struct crypto_ahash *atfm = __crypto_ahash_cast(tfm);
+	struct hash_alg_common *alg = crypto_hash_alg_common(atfm);
+	struct meson_alg_template *algt = container_of(alg,
+		struct meson_alg_template, alg.ahash.base.halg);
+
+	crypto_ahash_set_reqsize(atfm, crypto_ahash_statesize(atfm));
+
+	memset(tctx, 0, sizeof(struct meson_hasher_tfm_ctx));
+
+	tctx->mc = algt->mc;
+
+	return 0;
+}
+
+static struct meson_alg_template mc_algs[] = {
+{
+	.type = CRYPTO_ALG_TYPE_AHASH,
+	.blockmode = DESC_MODE_SHA1,
+	.alg.ahash.base = {
+		.halg = {
+			.base = {
+				.cra_name = "sha1",
+				.cra_driver_name = "sha1-gxl",
+				.cra_priority = 400,
+				.cra_blocksize = SHA1_BLOCK_SIZE,
+				.cra_flags = CRYPTO_ALG_ASYNC,
+				.cra_ctxsize = sizeof(struct meson_hasher_tfm_ctx),
+				.cra_module = THIS_MODULE,
+				.cra_alignmask = 0,
+				.cra_init = meson_hasher_init,
+			},
+			.digestsize = SHA1_DIGEST_SIZE,
+			.statesize = sizeof(struct meson_hasher_req_ctx),
+		},
+		.init = meson_sha_init,
+		.update = meson_sha_update,
+		.final = meson_sha_final,
+	},
+	.alg.ahash.op = {
+		.do_one_request = meson_hasher_do_one_request,
+	},
+},
+{
+	.type = CRYPTO_ALG_TYPE_AHASH,
+	.blockmode = DESC_MODE_SHA224,
+	.alg.ahash.base = {
+		.halg = {
+			.base = {
+				.cra_name = "sha224",
+				.cra_driver_name = "sha224-gxl",
+				.cra_priority = 400,
+				.cra_blocksize = SHA224_BLOCK_SIZE,
+				.cra_flags = CRYPTO_ALG_ASYNC,
+				.cra_ctxsize = sizeof(struct meson_hasher_tfm_ctx),
+				.cra_module = THIS_MODULE,
+				.cra_alignmask = 0,
+				.cra_init = meson_hasher_init,
+			},
+			.digestsize = SHA224_DIGEST_SIZE,
+			.statesize = sizeof(struct meson_hasher_req_ctx),
+		},
+		.init = meson_sha_init,
+		.update = meson_sha_update,
+		.final = meson_sha_final,
+	},
+	.alg.ahash.op = {
+		.do_one_request = meson_hasher_do_one_request,
+	},
+},
+{
+	.type = CRYPTO_ALG_TYPE_AHASH,
+	.blockmode = DESC_MODE_SHA256,
+	.alg.ahash.base = {
+		.halg = {
+			.base = {
+				.cra_name = "sha256",
+				.cra_driver_name = "sha256-gxl",
+				.cra_priority = 400,
+				.cra_blocksize = SHA256_BLOCK_SIZE,
+				.cra_flags = CRYPTO_ALG_ASYNC,
+				.cra_ctxsize = sizeof(struct meson_hasher_tfm_ctx),
+				.cra_module = THIS_MODULE,
+				.cra_alignmask = 0,
+				.cra_init = meson_hasher_init,
+			},
+			.digestsize = SHA256_DIGEST_SIZE,
+			.statesize = sizeof(struct meson_hasher_req_ctx),
+		},
+		.init = meson_sha_init,
+		.update = meson_sha_update,
+		.final = meson_sha_final,
+	},
+	.alg.ahash.op = {
+		.do_one_request = meson_hasher_do_one_request,
+	},
+},
+};
+
+int meson_hasher_register(struct meson_dev *mc)
+{
+	return meson_register_algs(mc, mc_algs, ARRAY_SIZE(mc_algs));
+}
+
+void meson_hasher_unregister(struct meson_dev *mc)
+{
+	meson_unregister_algs(mc, mc_algs, ARRAY_SIZE(mc_algs));
+}
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index e1453dd2e9f4..a07b4f6b3bcc 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -5,6 +5,7 @@
  * Copyright (C) 2018-2019 Corentin LABBE <clabbe at baylibre.com>
  */
 #include <crypto/aes.h>
+#include <crypto/sha2.h>
 #include <crypto/engine.h>
 #include <crypto/skcipher.h>
 #include <linux/debugfs.h>
@@ -23,13 +24,25 @@
 
 #define DESC_OPMODE_ECB (0 << 26)
 #define DESC_OPMODE_CBC (1 << 26)
+#define DESC_OPMODE_SHA (0 << 26)
 
 #define DESC_MAXLEN ((1 << 17) - 1)
 
+#define DESC_MODE_SHA1   (0x5 << 20)
+#define DESC_MODE_SHA224 (0x7 << 20)
+#define DESC_MODE_SHA256 (0x6 << 20)
+
 #define DESC_LAST BIT(18)
+#define DESC_BEGIN BIT(24)
+#define DESC_END BIT(25)
 #define DESC_ENCRYPTION BIT(28)
 #define DESC_OWN BIT(31)
 
+#define MESON_SHA_BUFFER_SIZE (SHA256_DIGEST_SIZE + 16)
+
+#define MESON_SHA_BEGIN BIT(1)
+#define MESON_SHA_FINAL BIT(2)
+
 /*
  * struct meson_desc - Descriptor for DMA operations
  * Note that without datasheet, some are unknown
@@ -143,6 +156,38 @@ struct meson_cipher_tfm_ctx {
 	struct crypto_skcipher *fallback_tfm;
 };
 
+/*
+ * struct meson_hasher_req_ctx - context for a hasher request
+ * @state:		state data
+ * @partial:		partial buffer data. Contains sent data which
+ *			size < blocksize
+ * @partial_size:	size of the partial buffer
+ * @partial_addr:	physical address of partial buffer
+ * @partial_mapped:	indicates is partial buffer currently mapped or not
+ * @flags:		request flags (for example, is this final req or not)
+ * @flow:		the flow to use for this request
+ */
+struct meson_hasher_req_ctx {
+	u8 state[SHA256_DIGEST_SIZE + 16] ____cacheline_aligned;
+	u8 partial[SHA256_BLOCK_SIZE] ____cacheline_aligned;
+	unsigned int partial_size ____cacheline_aligned;
+	dma_addr_t partial_addr;
+	bool partial_mapped;
+
+	bool begin_req;
+	bool final_req;
+	int flow;
+};
+
+/*
+ * struct meson_hasher_tfm_ctx - context for a hasher TFM
+ * @enginectx:		crypto_engine used by this TFM
+ * @mc:			pointer to the private data of driver handling this TFM
+ */
+struct meson_hasher_tfm_ctx {
+	struct meson_dev *mc;
+};
+
 /*
  * struct meson_alg_template - crypto_alg template
  * @type:		the CRYPTO_ALG_TYPE for this template
@@ -157,6 +202,7 @@ struct meson_alg_template {
 	u32 blockmode;
 	union {
 		struct skcipher_engine_alg skcipher;
+		struct ahash_engine_alg ahash;
 	} alg;
 	struct meson_dev *mc;
 #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
@@ -180,3 +226,6 @@ int meson_cipher_register(struct meson_dev *mc);
 void meson_cipher_unregister(struct meson_dev *mc);
 void meson_cipher_debugfs_show(struct seq_file *seq, void *v);
 int meson_handle_cipher_request(struct crypto_engine *engine, void *areq);
+
+int meson_hasher_register(struct meson_dev *mc);
+void meson_hasher_unregister(struct meson_dev *mc);
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:51:01 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:51:01 +0300
Subject: [PATCH v4 13/20] drivers: crypto: meson: use fallback for 192-bit keys
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-14-avromanov@salutedevices.com>

Unforunately, not all Amlogic SoC's have a 192-bit key
support for AES algo. In this case, use fallback.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c | 7 +++++++
 drivers/crypto/amlogic/amlogic-gxl-core.c   | 1 +
 drivers/crypto/amlogic/amlogic-gxl.h        | 2 ++
 3 files changed, 10 insertions(+)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 828109f4a1c3..da593130553e 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -41,6 +41,13 @@ static bool meson_cipher_need_fallback_sg(struct skcipher_request *areq,
 
 static bool meson_cipher_need_fallback(struct skcipher_request *areq)
 {
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+	struct meson_dev *mc = op->mc;
+
+	if (op->keymode == DESC_MODE_AES_192 && !mc->pdata->support_192bit_key)
+		return true;
+
 	if (areq->cryptlen == 0)
 		return true;
 
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f3b5e004b3a5..429c3474028b 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -215,6 +215,7 @@ static const struct meson_pdata meson_gxl_pdata = {
 	.status_reg = 0x4,
 	.need_clk = true,
 	.setup_desc_cnt = 3,
+	.support_192bit_key = true,
 };
 
 static const struct of_device_id meson_crypto_of_match_table[] = {
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 7f6d91e7b365..2d2777a25453 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -98,12 +98,14 @@ struct meson_flow {
  * @reg_status:	offset to status register
  * @need_clk:	clock input is needed
  * @setup_desc_cnt:	number of setup descriptor to configure.
+ * @support_192bit_key:	indicates whether platform support AES 192-bit key
  */
 struct meson_pdata {
 	u32 descs_reg;
 	u32 status_reg;
 	bool need_clk;
 	u32 setup_desc_cnt;
+	bool support_192bit_key;
 };
 
 /*
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:51:03 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:51:03 +0300
Subject: [PATCH v4 15/20] drivers: crypto: meson: add support for AXG-series
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-16-avromanov@salutedevices.com>

Tested via tcrypt module and with custom tests.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 drivers/crypto/amlogic/amlogic-gxl-core.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 2ffe5994b353..536ad438f713 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -226,6 +226,14 @@ static const struct meson_pdata meson_g12a_pdata = {
 	.support_192bit_key = false,
 };
 
+static const struct meson_pdata meson_axg_pdata = {
+	.descs_reg = 0x0,
+	.status_reg = 0x8,
+	.need_clk = false,
+	.setup_desc_cnt = 3,
+	.support_192bit_key = true,
+};
+
 static const struct of_device_id meson_crypto_of_match_table[] = {
 	{
 		.compatible = "amlogic,gxl-crypto",
@@ -243,6 +251,10 @@ static const struct of_device_id meson_crypto_of_match_table[] = {
 		.compatible = "amlogic,s4-crypto",
 		.data = &meson_g12a_pdata,
 	},
+	{
+		.compatible = "amlogic,axg-crypto",
+		.data = &meson_axg_pdata,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
-- 
2.34.1



From avromanov at salutedevices.com  Mon Feb 12 05:51:08 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Mon, 12 Feb 2024 16:51:08 +0300
Subject: [PATCH v4 20/20] arch: arm64: dts: meson: axg: add crypto node
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <20240212135108.549755-21-avromanov@salutedevices.com>

This patch adds a crypto node declaration. With the
Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
---
 arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 6d12b760b90f..b19be72abdd6 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -294,6 +294,12 @@ ethmac: ethernet at ff3f0000 {
 			status = "disabled";
 		};
 
+		crypto: crypto at ff63e000 {
+			compatible = "amlogic,axg-crypto";
+			reg = <0x0 0xff63e000 0x0 0x48>;
+			interrupts = <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>;
+		};
+
 		pcie_phy: phy at ff644000 {
 			compatible = "amlogic,axg-pcie-phy";
 			reg = <0x0 0xff644000 0x0 0x1c>;
-- 
2.34.1



From david at redhat.com  Mon Feb 12 05:54:27 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 14:54:27 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
Message-ID: <a91cfe1c-289e-4828-8cfc-be34eb69a71b@redhat.com>

>> If so, I wonder if we could instead do that comparison modulo the access/dirty
>> bits,
> 
> I think that would work - but will need to think a bit more on it.
> 
>> and leave ptep_get_lockless() only reading a single entry?
> 
> I think we will need to do something a bit less fragile. ptep_get() does collect
> the access/dirty bits so its confusing if ptep_get_lockless() doesn't IMHO. So
> we will likely want to rename the function and make its documentation explicit
> that it does not return those bits.
> 
> ptep_get_lockless_noyoungdirty()? yuk... Any ideas?
> 
> Of course if I could convince you the current implementation is safe, I might be
> able to sidestep this optimization until a later date?

As discussed (and pointed out abive), there might be quite some 
callsites where we don't really care about uptodate accessed/dirty bits 
-- where ptep_get() is used nowadays.

One way to approach that I had in mind was having an explicit interface:

ptep_get()
ptep_get_uptodate()
ptep_get_lockless()
ptep_get_lockless_uptodate()

Especially the last one might not be needed.

Futher, "uptodate" might not be the best choice because of 
PageUptodate() and friends. But it's better than 
"youngdirty"/"noyoungdirty" IMHO.

Of course, any such changes require care and are better done one step at 
at time separately.

-- 
Cheers,

David / dhildenb



From neil.armstrong at linaro.org  Mon Feb 12 05:55:21 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 12 Feb 2024 14:55:21 +0100
Subject: [PATCH 4/5] arm64: dts: qcom: sm8650: add GPU nodes
In-Reply-To: <70caf0d0-28f5-48b9-b10e-5541488dd982@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
 <20240212-topic-sm8650-gpu-v1-4-708a40b747b5@linaro.org>
 <70caf0d0-28f5-48b9-b10e-5541488dd982@linaro.org>
Message-ID: <575f4d10-6022-4e9f-9b0e-221ea2d20fc6@linaro.org>

On 12/02/2024 11:50, Konrad Dybcio wrote:
> On 12.02.2024 11:37, Neil Armstrong wrote:
>> Add GPU nodes for the SM8650 platform.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
>> ---
>>   arch/arm64/boot/dts/qcom/sm8650.dtsi | 169 +++++++++++++++++++++++++++++++++++
>>   1 file changed, 169 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
>> index c455ca4e6475..f6f9e603fb2f 100644
>> --- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
>> @@ -2582,6 +2582,131 @@ tcsr: clock-controller at 1fc0000 {
>>   			#reset-cells = <1>;
>>   		};
>>   
>> +		gpu: gpu at 3d00000 {
>> +			compatible = "qcom,adreno-43051401", "qcom,adreno";
>> +			reg = <0x0 0x03d00000 0x0 0x40000>,
>> +			      <0x0 0x03d9e000 0x0 0x1000>,
>> +			      <0x0 0x03d61000 0x0 0x800>;
>> +			reg-names = "kgsl_3d0_reg_memory",
>> +				    "cx_mem",
>> +				    "cx_dbgc";
>> +
>> +			interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
>> +
>> +			iommus = <&adreno_smmu 0 0x0>,
>> +				 <&adreno_smmu 1 0x0>;
>> +
>> +			operating-points-v2 = <&gpu_opp_table>;
>> +
>> +			interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>;
>> +			interconnect-names = "gfx-mem";
> 
> ICC should be unnecessary

Ack I'll remove

Neil

> 
> Konrad



From krzysztof.kozlowski at linaro.org  Mon Feb 12 05:56:43 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 14:56:43 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit,hd44780: drop redundant
 GPIO node
In-Reply-To: <ZcofhWb8stiddmru@smile.fi.intel.com>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <ZcofhWb8stiddmru@smile.fi.intel.com>
Message-ID: <906db6a6-48ba-41e5-be23-1dea0ecf96ee@linaro.org>

On 12/02/2024 14:39, Andy Shevchenko wrote:
> On Mon, Feb 12, 2024 at 09:34:24AM +0100, Krzysztof Kozlowski wrote:
>> Examples of other nodes, like GPIO controller, are redundant and not
>> really needed in device bindings.
> 
> ...
> 
>> -    i2c {
>> -            #address-cells = <1>;
>> -            #size-cells = <0>;
>>  
>> -            pcf8574: pcf8574 at 27 {
>> -                    compatible = "nxp,pcf8574";
>> -                    reg = <0x27>;
>> -                    gpio-controller;
>> -                    #gpio-cells = <2>;
>> -            };
>> -    };
> 
> In patch 3 you updated the lines that have lost their sense due to this one.

How did they lose it?


> And I agree with others, please leave this example in place.

What for? Why this binding is special and 99% of others do not need GPIO
expander in the example?

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Mon Feb 12 05:59:02 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 14:59:02 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop redundant
 GPIO node
In-Reply-To: <Zcogl6tqbMdQldKA@smile.fi.intel.com>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
 <20240212115837.efz73yxinkysdmgh@runtux.com>
 <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
 <Zcogl6tqbMdQldKA@smile.fi.intel.com>
Message-ID: <d603a588-d312-486e-b6c9-647a6b90580c@linaro.org>

On 12/02/2024 14:43, Andy Shevchenko wrote:
> On Mon, Feb 12, 2024 at 02:38:27PM +0100, Krzysztof Kozlowski wrote:
>> On 12/02/2024 12:58, Ralf Schlatterbeck wrote:
> 
> ...
> 
>> Anyway, binding examples should not be collection of unrelated
>> solutions, because then we should accept for each device schema several
>> other variations and combinations.
> 
> Is this documented?

Yes, writing schema says what the example is. We repeated it multiple
times on multiple reviews, we made multiple commits multiple times and I
briefly mentioned it also in my talks.

Best regards,
Krzysztof



From maz at kernel.org  Mon Feb 12 06:00:47 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 12 Feb 2024 14:00:47 +0000
Subject: [PATCH v4 06/10] arm64: cpufeature: Detect HCR_EL2.NV1 being RES0
In-Reply-To: <e3cc70fb-16d9-4e4e-aa35-f0eb2baaf166@samsung.com>
References: <20240122181344.258974-1-maz@kernel.org>
	<20240122181344.258974-7-maz@kernel.org>
	<CGME20240212124837eucas1p231da54bb0ff8d46d38c6c7e627e50172@eucas1p2.samsung.com>
	<e3cc70fb-16d9-4e4e-aa35-f0eb2baaf166@samsung.com>
Message-ID: <86eddh6auo.wl-maz@kernel.org>

On Mon, 12 Feb 2024 12:48:35 +0000,
Marek Szyprowski <m.szyprowski at samsung.com> wrote:
> 
> Dead All,
> 
> On 22.01.2024 19:13, Marc Zyngier wrote:
> > A variant of FEAT_E2H0 not being implemented exists in the form of
> > HCR_EL2.E2H being RES1 *and* HCR_EL2.NV1 being RES0 (indicating that
> > only VHE is supported on the host and nested guests).
> >
> > Add the necessary infrastructure for this new CPU capability.
> >
> > Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> 
> This patch landed recently in linux-next as commit da9af5071b25 ("arm64: 
> cpufeature: Detect HCR_EL2.NV1 being RES0"). I found that it causes a 
> following regression in the CPU hot-plug operation:
> 
> # for i in /sys/devices/system/cpu/cpu[1-9]; do echo 1 >$i/online; done
> ------------[ cut here ]------------
> kernel BUG at arch/arm64/kernel/cpufeature.c:1468!
> Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP
> Modules linked in: dw_hdmi_cec dw_hdmi_i2s_audio crct10dif_ce 
> snd_soc_simple_card rockchip_saradc industrialio_triggered_buffer 
> hantro_vpu kfifo_buf snd_soc_simple_card_utils rockchip_thermal 
> phy_rockchip_naneng_combphy display_connector gpio_ir_recv v4l2_vp9 
> v4l2_h264 v4l2_mem2mem dwmac_rk videobuf2_dma_contig stmmac_platform 
> videobuf2_memops videobuf2_v4l2 stmmac rockchipdrm videodev 
> snd_soc_rockchip_i2s_tdm snd_soc_rk817 pcs_xpcs panfrost rtc_rk808 
> rk805_pwrkey analogix_dp rk817_charger spi_rockchip_sfc dw_mipi_dsi 
> videobuf2_common dw_hdmi drm_shmem_helper mc gpu_sched 
> drm_display_helper ahci_dwc ip_tables x_tables ipv6
> CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.8.0-rc1+ #14563
> Hardware name: Hardkernel ODROID-M1 (DT)
> pstate: 800001c9 (Nzcv dAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : __read_sysreg_by_encoding+0x38c/0x390
> lr : read_scoped_sysreg+0x4c/0x70
> ...
> Call trace:
>  ?__read_sysreg_by_encoding+0x38c/0x390
>  ?read_scoped_sysreg+0x4c/0x70
>  ?has_nv1+0x18/0x48
>  ?verify_local_cpu_caps+0x54/0x124
>  ?check_local_cpu_capabilities+0x28/0x208
>  ?secondary_start_kernel+0xb0/0x154
>  ?__secondary_switched+0xb8/0xbc
> Code: d53802f3 17ffff3b d5380253 17ffff39 (d4210000)
> ---[ end trace 0000000000000000 ]---
> Kernel panic - not syncing: Attempted to kill the idle task!
> SMP: stopping secondary CPUs
> Kernel Offset: disabled
> CPU features: 0x1,80000000,80050295,2100721b
> Memory Limit: none
> ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---
> 
> It looks that some additional checks are needed for the CPU hot-plug case.

Nah, that's much simpler.

I simply missed a spot where ID_AA64MMFR4_EL1 must be handled (it is
getting annoying that we have more than a single place where these
"read all the ID registers" are handled).

Can you please give the following a go? If that works for you (it does
for me here), I'll post an actual fix (plus another fix for another
buglet I just noticed).

Thanks,

	M.

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0f29ac43c7a2..2f8958f27e9e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1456,6 +1456,7 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
 	read_sysreg_case(SYS_ID_AA64MMFR1_EL1);
 	read_sysreg_case(SYS_ID_AA64MMFR2_EL1);
 	read_sysreg_case(SYS_ID_AA64MMFR3_EL1);
+	read_sysreg_case(SYS_ID_AA64MMFR4_EL1);
 	read_sysreg_case(SYS_ID_AA64ISAR0_EL1);
 	read_sysreg_case(SYS_ID_AA64ISAR1_EL1);
 	read_sysreg_case(SYS_ID_AA64ISAR2_EL1);

-- 
Without deviation from the norm, progress is not possible.


From tudor.ambarus at linaro.org  Mon Feb 12 06:03:19 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:19 +0000
Subject: [PATCH v2 00/12] spi: s3c64xx: remove OF alias ID dependency
Message-ID: <20240212140331.915498-1-tudor.ambarus@linaro.org>

The driver was wrong as it assumed that the alias values in devicetree
have a particular meaning in identifying instances. This immediately
breaks when there is a dtb file that does not use the same alias values,
e.g. because it only needs some of the SPI ports.

Tested gs101 SPI with spi-loopback-test, all went fine. I updated
exynos850 as it uses the same USI.SPI_VERSION as gs101. Maybe Sam can
test exynos850, if not, we can drop that patch (12/12).

v2:
- update bindings to consider the asymmetric case where the RX FIFO
  depth can differ from the TX FIFO depth
- update commit message in patch 11/12 to describe the GS101 change
  (I was wrongly mentioning exynos 850). 


Tudor Ambarus (12):
  spi: dt-bindings: introduce FIFO depth properties
  spi: s3c64xx: define a magic value
  spi: s3c64xx: allow full FIFO masks
  spi: s3c64xx: determine the fifo depth only once
  spi: s3c64xx: retrieve the FIFO depth from the device tree
  spi: s3c64xx: allow FIFO depth to be determined from the compatible
  spi: s3c64xx: let the SPI core determine the bus number
  spi: s3c64xx: introduce s3c64xx_spi_set_port_id()
  spi: s3c64xx: get rid of the OF alias ID dependency
  spi: s3c64xx: deprecate fifo_lvl_mask, rx_lvl_offset and port_id
  spi: s3c64xx: switch gs101 to new port config data
  spi: s3c64xx: switch exynos850 to new port config data

 .../bindings/spi/spi-controller.yaml          |  27 ++++
 drivers/spi/spi-s3c64xx.c                     | 142 ++++++++++++++----
 2 files changed, 138 insertions(+), 31 deletions(-)

-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:20 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:20 +0000
Subject: [PATCH v2 01/12] spi: dt-bindings: introduce FIFO depth properties
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-2-tudor.ambarus@linaro.org>

There are SPI IPs that can be configured by the integrator with a
specific FIFO depth depending on the system's capabilities. For example,
the samsung USI SPI IP can be configured by the integrator with a TX/RX
FIFO from 8 byte to 256 bytes.

Introduce the ``fifo-depth`` property for such instances of IPs where the
same FIFO depth is used for both RX and TX. Introduce ``rx-fifo-depth``
and ``tx-fifo-depth`` properties for cases where the RX FIFO depth is
different from the TX FIFO depth.

Make the dedicated RX/TX properties dependent on each other and mutual
exclusive with the other.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 .../bindings/spi/spi-controller.yaml          | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml
index 524f6fe8c27b..add39884d226 100644
--- a/Documentation/devicetree/bindings/spi/spi-controller.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml
@@ -69,6 +69,21 @@ properties:
          Should be generally avoided and be replaced by
          spi-cs-high + ACTIVE_HIGH.
 
+  fifo-depth:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Size of the RX and TX data FIFOs in bytes.
+
+  rx-fifo-depth:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Size of the RX data FIFO in bytes.
+
+  tx-fifo-depth:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Size of the TX data FIFO in bytes.
+
   num-cs:
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
@@ -116,6 +131,10 @@ patternProperties:
       - compatible
       - reg
 
+dependencies:
+  rx-fifo-depth: [ tx-fifo-depth ]
+  tx-fifo-depth: [ rx-fifo-depth ]
+
 allOf:
   - if:
       not:
@@ -129,6 +148,14 @@ allOf:
       properties:
         "#address-cells":
           const: 0
+  - not:
+        required:
+          - fifo-depth
+          - rx-fifo-depth
+  - not:
+        required:
+          - fifo-depth
+          - tx-fifo-depth
 
 additionalProperties: true
 
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:21 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:21 +0000
Subject: [PATCH v2 02/12] spi: s3c64xx: define a magic value
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-3-tudor.ambarus@linaro.org>

Define a magic value, it will be used in the next patch as well.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 6f29dca68491..6ff3b25b6feb 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -78,6 +78,7 @@
 #define S3C64XX_SPI_INT_RX_FIFORDY_EN		(1<<1)
 #define S3C64XX_SPI_INT_TX_FIFORDY_EN		(1<<0)
 
+#define S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT	6
 #define S3C64XX_SPI_ST_RX_OVERRUN_ERR		(1<<5)
 #define S3C64XX_SPI_ST_RX_UNDERRUN_ERR		(1<<4)
 #define S3C64XX_SPI_ST_TX_OVERRUN_ERR		(1<<3)
@@ -108,7 +109,8 @@
 #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
 #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \
 				(1 << (i)->port_conf->tx_st_done)) ? 1 : 0)
-#define TX_FIFO_LVL(v, i) (((v) >> 6) & FIFO_LVL_MASK(i))
+#define TX_FIFO_LVL(v, i) (((v) >> S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT) &	\
+			   FIFO_LVL_MASK(i))
 #define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \
 					FIFO_LVL_MASK(i))
 #define FIFO_DEPTH(i) ((FIFO_LVL_MASK(i) >> 1) + 1)
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:22 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:22 +0000
Subject: [PATCH v2 03/12] spi: s3c64xx: allow full FIFO masks
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-4-tudor.ambarus@linaro.org>

The driver is wrong because is using partial register field masks for the
SPI_STATUS.{RX, TX}_FIFO_LVL register fields.

We see s3c64xx_spi_port_config.fifo_lvl_mask with different values for
different instances of the same IP. Take s5pv210_spi_port_config for
example, it defines:
	.fifo_lvl_mask  = { 0x1ff, 0x7F },

fifo_lvl_mask is used to determine the FIFO depth of the instance of the
IP. In this case, the integrator uses a 256 bytes FIFO for the first SPI
instance of the IP, and a 64 bytes FIFO for the second instance. While
the first mask reflects the SPI_STATUS.{RX, TX}_FIFO_LVL register
fields, the second one is two bits short. Using partial field masks is
misleading and can hide problems of the driver's logic.

Allow platforms to specify the full FIFO mask, regardless of the FIFO
depth.

Introduce {rx, tx}_fifomask to represent the SPI_STATUS.{RX, TX}_FIFO_LVL
register fields. It's a shifted mask defining the field's length and
position. We'll be able to deprecate the use of @rx_lvl_offset, as the
shift value can be determined from the mask. The existing compatibles
shall start using {rx, tx}_fifomask so that they use the full field mask
and to avoid shifting the mask to position, and then shifting it back to
zero in the {TX, RX}_FIFO_LVL macros.

@rx_lvl_offset will be deprecated in a further patch, after we have the
infrastructure to deprecate @fifo_lvl_mask as well.

No functional change intended.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 40 +++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 6ff3b25b6feb..338ca3f03ea5 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -3,6 +3,7 @@
 // Copyright (c) 2009 Samsung Electronics Co., Ltd.
 //      Jaswinder Singh <jassi.brar at samsung.com>
 
+#include <linux/bitops.h>
 #include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
@@ -109,10 +110,10 @@
 #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
 #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \
 				(1 << (i)->port_conf->tx_st_done)) ? 1 : 0)
-#define TX_FIFO_LVL(v, i) (((v) >> S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT) &	\
-			   FIFO_LVL_MASK(i))
-#define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \
-					FIFO_LVL_MASK(i))
+#define TX_FIFO_LVL(v, sdd)	(((v) & (sdd)->tx_fifomask) >>		\
+				 __ffs((sdd)->tx_fifomask))
+#define RX_FIFO_LVL(v, sdd)	(((v) & (sdd)->rx_fifomask) >>		\
+				 __ffs((sdd)->rx_fifomask))
 #define FIFO_DEPTH(i) ((FIFO_LVL_MASK(i) >> 1) + 1)
 
 #define S3C64XX_SPI_MAX_TRAILCNT	0x3ff
@@ -136,6 +137,10 @@ struct s3c64xx_spi_dma_data {
  * struct s3c64xx_spi_port_config - SPI Controller hardware info
  * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
  * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
+ * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
+ * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
  * @tx_st_done: Bit offset of TX_DONE bit in SPI_STATUS regiter.
  * @clk_div: Internal clock divider
  * @quirks: Bitmask of known quirks
@@ -154,6 +159,8 @@ struct s3c64xx_spi_dma_data {
 struct s3c64xx_spi_port_config {
 	int	fifo_lvl_mask[MAX_SPI_PORTS];
 	int	rx_lvl_offset;
+	u32	rx_fifomask;
+	u32	tx_fifomask;
 	int	tx_st_done;
 	int	quirks;
 	int	clk_div;
@@ -184,6 +191,10 @@ struct s3c64xx_spi_port_config {
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
  * @port_conf: Local SPI port configuration data
  * @port_id: Port identification number
+ * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
+ * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
  */
 struct s3c64xx_spi_driver_data {
 	void __iomem                    *regs;
@@ -203,6 +214,8 @@ struct s3c64xx_spi_driver_data {
 	struct s3c64xx_spi_dma_data	tx_dma;
 	const struct s3c64xx_spi_port_config	*port_conf;
 	unsigned int			port_id;
+	u32				rx_fifomask;
+	u32				tx_fifomask;
 };
 
 static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd)
@@ -1183,6 +1196,23 @@ static inline const struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
 	return (const struct s3c64xx_spi_port_config *)platform_get_device_id(pdev)->driver_data;
 }
 
+static void s3c64xx_spi_set_fifomask(struct s3c64xx_spi_driver_data *sdd)
+{
+	const struct s3c64xx_spi_port_config *port_conf = sdd->port_conf;
+
+	if (port_conf->rx_fifomask)
+		sdd->rx_fifomask = port_conf->rx_fifomask;
+	else
+		sdd->rx_fifomask = FIFO_LVL_MASK(sdd) <<
+			port_conf->rx_lvl_offset;
+
+	if (port_conf->tx_fifomask)
+		sdd->tx_fifomask = port_conf->tx_fifomask;
+	else
+		sdd->tx_fifomask = FIFO_LVL_MASK(sdd) <<
+			S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT;
+}
+
 static int s3c64xx_spi_probe(struct platform_device *pdev)
 {
 	struct resource	*mem_res;
@@ -1231,6 +1261,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
+	s3c64xx_spi_set_fifomask(sdd);
+
 	sdd->cur_bpw = 8;
 
 	sdd->tx_dma.direction = DMA_MEM_TO_DEV;
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:23 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:23 +0000
Subject: [PATCH v2 04/12] spi: s3c64xx: determine the fifo depth only once
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-5-tudor.ambarus@linaro.org>

Determine the FIFO depth only once, at probe time.
``sdd->fifo_depth`` can be set later on with the FIFO depth
specified in the device tree.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 338ca3f03ea5..72572e23cde5 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -191,6 +191,7 @@ struct s3c64xx_spi_port_config {
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
  * @port_conf: Local SPI port configuration data
  * @port_id: Port identification number
+ * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
  * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
@@ -214,6 +215,7 @@ struct s3c64xx_spi_driver_data {
 	struct s3c64xx_spi_dma_data	tx_dma;
 	const struct s3c64xx_spi_port_config	*port_conf;
 	unsigned int			port_id;
+	unsigned int			fifo_depth;
 	u32				rx_fifomask;
 	u32				tx_fifomask;
 };
@@ -424,7 +426,7 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
 	struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
 
 	if (sdd->rx_dma.ch && sdd->tx_dma.ch)
-		return xfer->len > FIFO_DEPTH(sdd);
+		return xfer->len > sdd->fifo_depth;
 
 	return false;
 }
@@ -548,7 +550,7 @@ static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,
 	void __iomem *regs = sdd->regs;
 	unsigned long val = 1;
 	u32 status;
-	u32 max_fifo = FIFO_DEPTH(sdd);
+	u32 max_fifo = sdd->fifo_depth;
 
 	if (timeout_ms)
 		val = msecs_to_loops(timeout_ms);
@@ -655,7 +657,7 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
 	 * For any size less than the fifo size the below code is
 	 * executed atleast once.
 	 */
-	loops = xfer->len / FIFO_DEPTH(sdd);
+	loops = xfer->len / sdd->fifo_depth;
 	buf = xfer->rx_buf;
 	do {
 		/* wait for data to be received in the fifo */
@@ -792,7 +794,7 @@ static int s3c64xx_spi_transfer_one(struct spi_controller *host,
 				    struct spi_transfer *xfer)
 {
 	struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
-	const unsigned int fifo_len = FIFO_DEPTH(sdd);
+	const unsigned int fifo_len = sdd->fifo_depth;
 	const void *tx_buf = NULL;
 	void *rx_buf = NULL;
 	int target_len = 0, origin_len = 0;
@@ -1261,6 +1263,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
+	sdd->fifo_depth = FIFO_DEPTH(sdd);
+
 	s3c64xx_spi_set_fifomask(sdd);
 
 	sdd->cur_bpw = 8;
@@ -1352,7 +1356,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Targets attached\n",
 					sdd->port_id, host->num_chipselect);
 	dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\n",
-					mem_res, FIFO_DEPTH(sdd));
+		mem_res, sdd->fifo_depth);
 
 	pm_runtime_mark_last_busy(&pdev->dev);
 	pm_runtime_put_autosuspend(&pdev->dev);
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:24 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:24 +0000
Subject: [PATCH v2 05/12] spi: s3c64xx: retrieve the FIFO depth from the device tree
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-6-tudor.ambarus@linaro.org>

There are SoCs that configure different FIFO depths for their instances
of the SPI IP. See the fifo_lvl_mask defined for exynos4_spi_port_config
for example:
        .fifo_lvl_mask  = { 0x1ff, 0x7F, 0x7F },
The first instance of the IP is configured with 256 bytes FIFOs, whereas
the last two are configured with 64 bytes FIFOs.

Instead of mangling with the .fifo_lvl_mask and its dependency of the DT
alias ID, allow such SoCs to determine the FIFO depth via the
``fifo-depth`` DT property.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 72572e23cde5..b1c63f75021d 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1263,7 +1263,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
-	sdd->fifo_depth = FIFO_DEPTH(sdd);
+	if (of_property_read_u32(pdev->dev.of_node, "fifo-depth",
+				 &sdd->fifo_depth))
+		sdd->fifo_depth = FIFO_DEPTH(sdd);
 
 	s3c64xx_spi_set_fifomask(sdd);
 
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:25 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:25 +0000
Subject: [PATCH v2 06/12] spi: s3c64xx: allow FIFO depth to be determined from the compatible
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-7-tudor.ambarus@linaro.org>

There are SoCs that use the same FIFO depth for all the instances of the
SPI IP. See the fifo_lvl_mask defined for gs101 for example:
    .fifo_lvl_mask  = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
                        0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},

Instead of specifying the FIFO depth with the same value for all 16
nodes in this case, allow such SoCs to infer the FIFO depth from the
compatible. There are other SoCs than can benefit of this, see:
{gs101, fsd, exynos850, s3c641, s3c2443}_spi_port_config.

The FIFO depth inferred from the compatible has a higher precedence than
the one that might be specified via device tree, the driver shall know
better.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index b1c63f75021d..68f95c04d092 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -137,6 +137,7 @@ struct s3c64xx_spi_dma_data {
  * struct s3c64xx_spi_port_config - SPI Controller hardware info
  * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
  * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
+ * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
  * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
@@ -159,6 +160,7 @@ struct s3c64xx_spi_dma_data {
 struct s3c64xx_spi_port_config {
 	int	fifo_lvl_mask[MAX_SPI_PORTS];
 	int	rx_lvl_offset;
+	unsigned int fifo_depth;
 	u32	rx_fifomask;
 	u32	tx_fifomask;
 	int	tx_st_done;
@@ -1263,8 +1265,10 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
-	if (of_property_read_u32(pdev->dev.of_node, "fifo-depth",
-				 &sdd->fifo_depth))
+	if (sdd->port_conf->fifo_depth)
+		sdd->fifo_depth = sdd->port_conf->fifo_depth;
+	else if (of_property_read_u32(pdev->dev.of_node, "fifo-depth",
+				      &sdd->fifo_depth))
 		sdd->fifo_depth = FIFO_DEPTH(sdd);
 
 	s3c64xx_spi_set_fifomask(sdd);
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:26 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:26 +0000
Subject: [PATCH v2 07/12] spi: s3c64xx: let the SPI core determine the bus number
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-8-tudor.ambarus@linaro.org>

Let the core determine the bus number, either by getting the alias ID
(as the driver forces now), or by allocating a dynamic bus number when
the alias is absent. Prepare the driver to allow dt aliases to be
absent.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 68f95c04d092..ac47755beb02 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1279,7 +1279,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	sdd->rx_dma.direction = DMA_DEV_TO_MEM;
 
 	host->dev.of_node = pdev->dev.of_node;
-	host->bus_num = sdd->port_id;
+	host->bus_num = -1;
 	host->setup = s3c64xx_spi_setup;
 	host->cleanup = s3c64xx_spi_cleanup;
 	host->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
@@ -1360,7 +1360,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	}
 
 	dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Targets attached\n",
-					sdd->port_id, host->num_chipselect);
+		host->bus_num, host->num_chipselect);
 	dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\n",
 		mem_res, sdd->fifo_depth);
 
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:27 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:27 +0000
Subject: [PATCH v2 08/12] spi: s3c64xx: introduce s3c64xx_spi_set_port_id()
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-9-tudor.ambarus@linaro.org>

Prepare driver to get rid of the of alias ID dependency. Split the
port_id logic into a dedicated method.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index ac47755beb02..40de325bd094 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1200,6 +1200,27 @@ static inline const struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
 	return (const struct s3c64xx_spi_port_config *)platform_get_device_id(pdev)->driver_data;
 }
 
+static int s3c64xx_spi_set_port_id(struct platform_device *pdev,
+				   struct s3c64xx_spi_driver_data *sdd)
+{
+	int ret;
+
+	if (pdev->dev.of_node) {
+		ret = of_alias_get_id(pdev->dev.of_node, "spi");
+		if (ret < 0)
+			return dev_err_probe(&pdev->dev, ret,
+					     "Failed to get alias id\n");
+		sdd->port_id = ret;
+	} else {
+		if (pdev->id < 0)
+			return dev_err_probe(&pdev->dev, -EINVAL,
+					     "Negative platform ID is not allowed\n");
+		sdd->port_id = pdev->id;
+	}
+
+	return 0;
+}
+
 static void s3c64xx_spi_set_fifomask(struct s3c64xx_spi_driver_data *sdd)
 {
 	const struct s3c64xx_spi_port_config *port_conf = sdd->port_conf;
@@ -1252,18 +1273,10 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	sdd->host = host;
 	sdd->cntrlr_info = sci;
 	sdd->pdev = pdev;
-	if (pdev->dev.of_node) {
-		ret = of_alias_get_id(pdev->dev.of_node, "spi");
-		if (ret < 0)
-			return dev_err_probe(&pdev->dev, ret,
-					     "Failed to get alias id\n");
-		sdd->port_id = ret;
-	} else {
-		if (pdev->id < 0)
-			return dev_err_probe(&pdev->dev, -EINVAL,
-					     "Negative platform ID is not allowed\n");
-		sdd->port_id = pdev->id;
-	}
+
+	ret = s3c64xx_spi_set_port_id(pdev, sdd);
+	if (ret)
+		return ret;
 
 	if (sdd->port_conf->fifo_depth)
 		sdd->fifo_depth = sdd->port_conf->fifo_depth;
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:28 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:28 +0000
Subject: [PATCH v2 09/12] spi: s3c64xx: get rid of the OF alias ID dependency
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-10-tudor.ambarus@linaro.org>

Compatibles that set ``port_conf->{rx, tx}_fifomask`` are now safe to
get rid of the OF alias ID dependency. Let the driver probe even without
the alias for these.

With this we also protect the FIFO_LVL_MASK calls from
s3c64xx_spi_set_fifomask().

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 40de325bd094..d2d1c9767145 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1203,8 +1203,12 @@ static inline const struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
 static int s3c64xx_spi_set_port_id(struct platform_device *pdev,
 				   struct s3c64xx_spi_driver_data *sdd)
 {
+	const struct s3c64xx_spi_port_config *port_conf = sdd->port_conf;
 	int ret;
 
+	if (port_conf->rx_fifomask && port_conf->tx_fifomask)
+		return 0;
+
 	if (pdev->dev.of_node) {
 		ret = of_alias_get_id(pdev->dev.of_node, "spi");
 		if (ret < 0)
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:29 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:29 +0000
Subject: [PATCH v2 10/12] spi: s3c64xx: deprecate fifo_lvl_mask, rx_lvl_offset and port_id
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-11-tudor.ambarus@linaro.org>

Deprecate fifo_lvl_mask, rx_lvl_offset and port_id. One shall use
{rx, tx}_fifomask instead. Add messages to each port configuration.

Suggested-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index d2d1c9767145..128f4a7c4bd9 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -135,8 +135,8 @@ struct s3c64xx_spi_dma_data {
 
 /**
  * struct s3c64xx_spi_port_config - SPI Controller hardware info
- * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
- * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
+ * @fifo_lvl_mask: [DEPRECATED] use @{rx, tx}_fifomask instead.
+ * @rx_lvl_offset: [DEPRECATED] use @{rx,tx}_fifomask instead.
  * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
@@ -192,7 +192,7 @@ struct s3c64xx_spi_port_config {
  * @rx_dma: Local receive DMA data (e.g. chan and direction)
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
  * @port_conf: Local SPI port configuration data
- * @port_id: Port identification number
+ * @port_id: [DEPRECATED] use @{rx,tx}_fifomask instead.
  * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
@@ -1508,7 +1508,9 @@ static const struct dev_pm_ops s3c64xx_spi_pm = {
 };
 
 static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 13,
 	.tx_st_done	= 21,
 	.clk_div	= 2,
@@ -1516,14 +1518,18 @@ static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config s3c6410_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7F },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 13,
 	.tx_st_done	= 21,
 	.clk_div	= 2,
 };
 
 static const struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7F },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1531,7 +1537,9 @@ static const struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos4_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7F, 0x7F },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1541,7 +1549,9 @@ static const struct s3c64xx_spi_port_config exynos4_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos7_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7F, 0x7F, 0x7F, 0x7F, 0x1ff},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1551,7 +1561,9 @@ static const struct s3c64xx_spi_port_config exynos7_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1562,7 +1574,9 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos850_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
@@ -1573,8 +1587,10 @@ static const struct s3c64xx_spi_port_config exynos850_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynosautov9_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff, 0x7f,
 			    0x7f, 0x7f, 0x7f, 0x7f},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
@@ -1586,7 +1602,9 @@ static const struct s3c64xx_spi_port_config exynosautov9_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1597,8 +1615,10 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
 			    0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:30 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:30 +0000
Subject: [PATCH v2 11/12] spi: s3c64xx: switch gs101 to new port config data
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-12-tudor.ambarus@linaro.org>

Drop the fifo_lvl_mask and rx_lvl_offset and switch to the new port
config data.

Advantages of the change:
- drop dependency on the OF alias ID.
- FIFO depth is inferred from the compatible. GS101 integrates 16 SPI
  IPs, all with 64 bytes FIFO depths.
- use full mask for SPI_STATUS.{RX, TX}_FIFO_LVL fields. Using partial
  masks is misleading and can hide problems of the driver logic.

S3C64XX_SPI_ST_TX_FIFO_RDY_V2 was defined based on the USI's
SPI_VERSION.USI_IP_VERSION register field, which has value 2 at reset.

MAX_SPI_PORTS is updated to reflect the maximum number of ports for the
rest of the compatibles.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 128f4a7c4bd9..784786407d2e 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -20,7 +20,7 @@
 #include <linux/spi/spi.h>
 #include <linux/types.h>
 
-#define MAX_SPI_PORTS		16
+#define MAX_SPI_PORTS		12
 #define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1)
 #define AUTOSUSPEND_TIMEOUT	2000
 
@@ -79,6 +79,8 @@
 #define S3C64XX_SPI_INT_RX_FIFORDY_EN		(1<<1)
 #define S3C64XX_SPI_INT_TX_FIFORDY_EN		(1<<0)
 
+#define S3C64XX_SPI_ST_RX_FIFO_RDY_V2		GENMASK(23, 15)
+#define S3C64XX_SPI_ST_TX_FIFO_RDY_V2		GENMASK(14, 6)
 #define S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT	6
 #define S3C64XX_SPI_ST_RX_OVERRUN_ERR		(1<<5)
 #define S3C64XX_SPI_ST_RX_UNDERRUN_ERR		(1<<4)
@@ -1615,11 +1617,9 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
-	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
-	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-			    0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
-	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
-	.rx_lvl_offset	= 15,
+	.fifo_depth	= 64,
+	.rx_fifomask	= S3C64XX_SPI_ST_RX_FIFO_RDY_V2,
+	.tx_fifomask	= S3C64XX_SPI_ST_TX_FIFO_RDY_V2,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
 	.high_speed	= true,
-- 
2.43.0.687.g38aa6559b0-goog



From tudor.ambarus at linaro.org  Mon Feb 12 06:03:31 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 12 Feb 2024 14:03:31 +0000
Subject: [PATCH v2 12/12] spi: s3c64xx: switch exynos850 to new port config data
In-Reply-To: <20240212140331.915498-1-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
Message-ID: <20240212140331.915498-13-tudor.ambarus@linaro.org>

Exynos850 has the same version of USI SPI (v2.1) as GS101.
Drop the fifo_lvl_mask and rx_lvl_offset and switch to the new port
config data.

Backward compatibility with DT is not broken because when alises are
set:
- the SPI core will set the bus number according to the alias ID
- the FIFO depth is always the same size for exynos850 (64 bytes) no
  matter the alias ID number.

Advantages of the change:
- drop dependency on the OF alias ID.
- FIFO depth is inferred from the compatible. Exynos850 integrates 3 SPI
  IPs, all with 64 bytes FIFO depths.
- use full mask for SPI_STATUS.{RX, TX}_FIFO_LVL fields. Using partial
  masks is misleading and can hide problems of the driver logic.

Just compiled tested.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 784786407d2e..9fcbe040cb2f 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1576,10 +1576,9 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos850_spi_port_config = {
-	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
-	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f },
-	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
-	.rx_lvl_offset	= 15,
+	.fifo_depth	= 64,
+	.rx_fifomask	= S3C64XX_SPI_ST_RX_FIFO_RDY_V2,
+	.tx_fifomask	= S3C64XX_SPI_ST_TX_FIFO_RDY_V2,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
 	.high_speed	= true,
-- 
2.43.0.687.g38aa6559b0-goog



From andriy.shevchenko at linux.intel.com  Mon Feb 12 06:04:09 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Mon, 12 Feb 2024 16:04:09 +0200
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop
 redundant GPIO node
In-Reply-To: <d603a588-d312-486e-b6c9-647a6b90580c@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
 <20240212115837.efz73yxinkysdmgh@runtux.com>
 <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
 <Zcogl6tqbMdQldKA@smile.fi.intel.com>
 <d603a588-d312-486e-b6c9-647a6b90580c@linaro.org>
Message-ID: <ZcolWdCeLf0nDPdY@smile.fi.intel.com>

On Mon, Feb 12, 2024 at 02:59:02PM +0100, Krzysztof Kozlowski wrote:
> On 12/02/2024 14:43, Andy Shevchenko wrote:
> > On Mon, Feb 12, 2024 at 02:38:27PM +0100, Krzysztof Kozlowski wrote:
> >> On 12/02/2024 12:58, Ralf Schlatterbeck wrote:

...

> >> Anyway, binding examples should not be collection of unrelated
> >> solutions, because then we should accept for each device schema several
> >> other variations and combinations.
> > 
> > Is this documented?
> 
> Yes, writing schema says what the example is. We repeated it multiple
> times on multiple reviews, we made multiple commits multiple times and I
> briefly mentioned it also in my talks.

Good to know, thanks!

-- 
With Best Regards,
Andy Shevchenko




From robh at kernel.org  Mon Feb 12 06:08:24 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 12 Feb 2024 08:08:24 -0600
Subject: [PATCH v2] dt-bindings: interrupt-controller: Convert Atmel AIC
 to json-schema
In-Reply-To: <20240209100122.61335-1-dharma.b@microchip.com>
References: <20240209100122.61335-1-dharma.b@microchip.com>
Message-ID: <20240212140824.GA107736-robh@kernel.org>

On Fri, Feb 09, 2024 at 03:31:22PM +0530, Dharma Balasubiramani wrote:
> Convert the Atmel AIC binding document to DT schema format using
> json-schema.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> ---
> Changelog
> v1 -> v2
> - Drop the '|' as there is no formatting to preserve.
> - Remove unnecessary marketing statement from description.
> - Drop the description for interrupts and reg, it's obvious.
> - Put reg after compatible.
> - Drop comment in example.
> - Drop the example of device that is wired to an AIC as it's(dma) binding is
>   not yet available.
> ---
>  .../interrupt-controller/atmel,aic.txt        | 43 -----------
>  .../interrupt-controller/atmel,aic.yaml       | 74 +++++++++++++++++++
>  2 files changed, 74 insertions(+), 43 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
> deleted file mode 100644
> index 7079d44bf3ba..000000000000
> --- a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
> +++ /dev/null
> @@ -1,43 +0,0 @@
> -* Advanced Interrupt Controller (AIC)
> -
> -Required properties:
> -- compatible: Should be:
> -    - "atmel,<chip>-aic" where  <chip> can be "at91rm9200", "sama5d2",
> -      "sama5d3" or "sama5d4"
> -    - "microchip,<chip>-aic" where <chip> can be "sam9x60"
> -
> -- interrupt-controller: Identifies the node as an interrupt controller.
> -- #interrupt-cells: The number of cells to define the interrupts. It should be 3.
> -  The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet).
> -  The second cell is used to specify flags:
> -    bits[3:0] trigger type and level flags:
> -      1 = low-to-high edge triggered.
> -      2 = high-to-low edge triggered.
> -      4 = active high level-sensitive.
> -      8 = active low level-sensitive.
> -      Valid combinations are 1, 2, 3, 4, 8.
> -      Default flag for internal sources should be set to 4 (active high).
> -  The third cell is used to specify the irq priority from 0 (lowest) to 7
> -  (highest).
> -- reg: Should contain AIC registers location and length
> -- atmel,external-irqs: u32 array of external irqs.
> -
> -Examples:
> -	/*
> -	 * AIC
> -	 */
> -	aic: interrupt-controller at fffff000 {
> -		compatible = "atmel,at91rm9200-aic";
> -		interrupt-controller;
> -		#interrupt-cells = <3>;
> -		reg = <0xfffff000 0x200>;
> -	};
> -
> -	/*
> -	 * An interrupt generating device that is wired to an AIC.
> -	 */
> -	dma: dma-controller at ffffec00 {
> -		compatible = "atmel,at91sam9g45-dma";
> -		reg = <0xffffec00 0x200>;
> -		interrupts = <21 4 5>;
> -	};
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
> new file mode 100644
> index 000000000000..df81115a8b7f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
> @@ -0,0 +1,74 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interrupt-controller/atmel,aic.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Advanced Interrupt Controller (AIC)
> +
> +maintainers:
> +  - Nicolas Ferre <nicolas.ferre at microchip.com>
> +  - Dharma balasubiramani <dharma.b at microchip.com>
> +
> +description:
> +  The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
> +  maskable, vectored interrupt controller providing handling of up to one
> +  hundred and twenty-eight interrupt sources.
> +
> +allOf:
> +  - $ref: /schemas/interrupt-controller.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - atmel,at91rm9200-aic
> +      - atmel,sama5d2-aic
> +      - atmel,sama5d3-aic
> +      - atmel,sama5d4-aic
> +      - microchip,sam9x60-aic
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupt-controller: true
> +
> +  "#interrupt-cells":
> +    const: 3
> +    description: |
> +      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
> +      The 2nd cell specifies flags:
> +        bits[3:0] trigger type and level flags:
> +          1 = low-to-high edge triggered.
> +          2 = high-to-low edge triggered.
> +          4 = active high level-sensitive.
> +          8 = active low level-sensitive.
> +        Valid combinations: 1, 2, 3, 4, 8.
> +        Default for internal sources: 4 (active high).
> +      The 3rd cell specifies irq priority from 0 (lowest) to 7 (highest).
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  atmel,external-irqs:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description: u32 array of external irqs.

Constraints on the array size and/or entry values?

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupt-controller
> +  - "#interrupt-cells"
> +  - atmel,external-irqs
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    interrupt-controller at fffff000 {
> +      compatible = "atmel,at91rm9200-aic";
> +      interrupt-controller;
> +      #interrupt-cells = <3>;
> +      reg = <0xfffff000 0x200>;
> +      atmel,external-irqs = <31>;
> +    };
> +...
> 
> base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
> -- 
> 2.25.1
> 


From zajec5 at gmail.com  Mon Feb 12 06:08:39 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 12 Feb 2024 15:08:39 +0100
Subject: [PATCH] dt-bindings: vendor-prefixes: add smartrg
Message-ID: <20240212140839.27150-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

SmartRG described itself as a CPE manufacturer and produced few home
network devices (e.g. wireless routers). Their SmartRG SR400ac router
(smartrg,sr400ac) is covered by in-Linux DT binding and DTS file.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 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 bf6d8261725b..80a7c07401ed 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1305,6 +1305,8 @@ patternProperties:
     description: Skyworks Solutions, Inc.
   "^smartlabs,.*":
     description: SmartLabs LLC
+  "^smartrg,.*":
+    description: SmartRG, Inc.
   "^smi,.*":
     description: Silicon Motion Technology Corporation
   "^smsc,.*":
-- 
2.35.3



From andriy.shevchenko at linux.intel.com  Mon Feb 12 06:09:18 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Mon, 12 Feb 2024 16:09:18 +0200
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit,hd44780: drop redundant
 GPIO node
In-Reply-To: <906db6a6-48ba-41e5-be23-1dea0ecf96ee@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <ZcofhWb8stiddmru@smile.fi.intel.com>
 <906db6a6-48ba-41e5-be23-1dea0ecf96ee@linaro.org>
Message-ID: <Zcomjp9oH9VfO3NA@smile.fi.intel.com>

On Mon, Feb 12, 2024 at 02:56:43PM +0100, Krzysztof Kozlowski wrote:
> On 12/02/2024 14:39, Andy Shevchenko wrote:
> > On Mon, Feb 12, 2024 at 09:34:24AM +0100, Krzysztof Kozlowski wrote:

...

> >> -    i2c {
> >> -            #address-cells = <1>;
> >> -            #size-cells = <0>;
> >>  
> >> -            pcf8574: pcf8574 at 27 {
> >> -                    compatible = "nxp,pcf8574";
> >> -                    reg = <0x27>;
> >> -                    gpio-controller;
> >> -                    #gpio-cells = <2>;
> >> -            };
> >> -    };
> > 
> > In patch 3 you updated the lines that have lost their sense due to this one.
> 
> How did they lose it?

Now they are referring to the non-existed node in the example. OTOH, there is
already hc595 case...

The Q here (as you pointed out that it's better to name nodes in generic way),
how these names are okay with the schema (hc595, pcf8574) as being referred to?

...

> > And I agree with others, please leave this example in place.
> 
> What for? Why this binding is special and 99% of others do not need GPIO
> expander in the example?

Some people already tried to explain you their point of view, but I see that:
- the unrelated nodes in the schemas are not welcome (as per your talks
  and documentation);
- the current file has other references that have no existing node in the
  example;
- you are DT maintainer, so I believe you know this better.

With this, I'm almost (see above question though) satisfied with the series.

-- 
With Best Regards,
Andy Shevchenko




From ryan.roberts at arm.com  Mon Feb 12 06:10:55 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 14:10:55 +0000
Subject: [PATCH v5 03/25] mm: Make pte_next_pfn() a wrapper around
 pte_advance_pfn()
In-Reply-To: <c269c2e0-afca-4ff0-8ffd-9049fb52c905@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-4-ryan.roberts@arm.com>
 <c269c2e0-afca-4ff0-8ffd-9049fb52c905@redhat.com>
Message-ID: <cdf4e537-5b0d-45ba-8094-527127c791a6@arm.com>

On 12/02/2024 12:14, David Hildenbrand wrote:
> On 02.02.24 09:07, Ryan Roberts wrote:
>> The goal is to be able to advance a PTE by an arbitrary number of PFNs.
>> So introduce a new API that takes a nr param.
>>
>> We are going to remove pte_next_pfn() and replace it with
>> pte_advance_pfn(). As a first step, implement pte_next_pfn() as a
>> wrapper around pte_advance_pfn() so that we can incrementally switch the
>> architectures over. Once all arches are moved over, we will change all
>> the core-mm callers to call pte_advance_pfn() directly and remove the
>> wrapper.
>>
>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>> ---
>> ? include/linux/pgtable.h | 8 +++++++-
>> ? 1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>> index 5e7eaf8f2b97..815d92dcb96b 100644
>> --- a/include/linux/pgtable.h
>> +++ b/include/linux/pgtable.h
>> @@ -214,9 +214,15 @@ static inline int pmd_dirty(pmd_t pmd)
>> ? ? ? #ifndef pte_next_pfn
>> +#ifndef pte_advance_pfn
>> +static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>> +{
>> +??? return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
>> +}
>> +#endif
>> ? static inline pte_t pte_next_pfn(pte_t pte)
>> ? {
>> -??? return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
>> +??? return pte_advance_pfn(pte, 1);
>> ? }
>> ? #endif
>> ? 
> 
> I do wonder if we simply want to leave pte_next_pfn() around? Especially patch
> #4, #6 don't really benefit from the change? So are the other set_ptes()
> implementations.
> 
> That is, only convert all pte_next_pfn()->pte_advance_pfn(), and leave a
> pte_next_pfn() macro in place.
> 
> Any downsides to that? 

The downside is just having multiple functions that effectively do the same
thing. Personally I think its cleaner and easier to understand the code with
just one generic function which we pass 1 to it where we only want to advance by
1. In the end, there are only a couple of places where pte_advance_pfn(1) is
used, so doesn't really seem valuable to me to maintain a specialization.

Unless you feel strongly that we need to keep pte_next_pfn() then I'd prefer to
leave it as I've done in this series.

> This patch here would become:
> 
> #ifndef pte_advance_pfn
> static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
> {
> ????return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
> }
> #endif
> 
> #ifndef pte_next_pfn
> #define pte_next_pfn(pte) pte_advance_pfn(pte, 1)
> #endif
> 
> As you convert the three arches, make them define pte_advance_pfn and udnefine
> pte_next_pfn. in the end, you can drop the #ifdef around pte_next_pfn here.
> 



From david at redhat.com  Mon Feb 12 06:19:14 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 15:19:14 +0100
Subject: [PATCH] mm/hugetlb: Move page order check inside
 hugetlb_cma_reserve()
In-Reply-To: <20240209054221.1403364-1-anshuman.khandual@arm.com>
References: <20240209054221.1403364-1-anshuman.khandual@arm.com>
Message-ID: <b73948f3-560c-4b5e-b638-6f3055dee758@redhat.com>

On 09.02.24 06:42, Anshuman Khandual wrote:
> All platforms could benefit from page order check against MAX_PAGE_ORDER
> before allocating a CMA area for gigantic hugetlb pages. Let's move this
> check from individual platforms to generic hugetlb.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Michael Ellerman <mpe at ellerman.id.au>
> Cc: Nicholas Piggin <npiggin at gmail.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linuxppc-dev at lists.ozlabs.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 v6.8-rc3
>   
>   arch/arm64/mm/hugetlbpage.c   | 7 -------
>   arch/powerpc/mm/hugetlbpage.c | 4 +---
>   mm/hugetlb.c                  | 7 +++++++
>   3 files changed, 8 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 8116ac599f80..6720ec8d50e7 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -45,13 +45,6 @@ void __init arm64_hugetlb_cma_reserve(void)
>   	else
>   		order = CONT_PMD_SHIFT - PAGE_SHIFT;
>   
> -	/*
> -	 * HugeTLB CMA reservation is required for gigantic
> -	 * huge pages which could not be allocated via the
> -	 * page allocator. Just warn if there is any change
> -	 * breaking this assumption.
> -	 */
> -	WARN_ON(order <= MAX_PAGE_ORDER);
>   	hugetlb_cma_reserve(order);
>   }
>   #endif /* CONFIG_CMA */
> diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
> index 0a540b37aab6..16557d008eef 100644
> --- a/arch/powerpc/mm/hugetlbpage.c
> +++ b/arch/powerpc/mm/hugetlbpage.c
> @@ -614,8 +614,6 @@ void __init gigantic_hugetlb_cma_reserve(void)
>   		 */
>   		order = mmu_psize_to_shift(MMU_PAGE_16G) - PAGE_SHIFT;
>   
> -	if (order) {
> -		VM_WARN_ON(order <= MAX_PAGE_ORDER);
> +	if (order)
>   		hugetlb_cma_reserve(order);
> -	}
>   }
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index cf9c9b2906ea..345b3524df35 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -7699,6 +7699,13 @@ void __init hugetlb_cma_reserve(int order)
>   	bool node_specific_cma_alloc = false;
>   	int nid;
>   
> +	/*
> +	 * HugeTLB CMA reservation is required for gigantic
> +	 * huge pages which could not be allocated via the
> +	 * page allocator. Just warn if there is any change
> +	 * breaking this assumption.
> +	 */
> +	VM_WARN_ON(order <= MAX_PAGE_ORDER);
>   	cma_reserve_called = true;
>   
>   	if (!hugetlb_cma_size)

Reviewed-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From krzysztof.kozlowski at linaro.org  Mon Feb 12 06:20:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 15:20:26 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit,hd44780: drop redundant
 GPIO node
In-Reply-To: <Zcomjp9oH9VfO3NA@smile.fi.intel.com>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <ZcofhWb8stiddmru@smile.fi.intel.com>
 <906db6a6-48ba-41e5-be23-1dea0ecf96ee@linaro.org>
 <Zcomjp9oH9VfO3NA@smile.fi.intel.com>
Message-ID: <b836cf9d-dc71-4835-b45f-1092aafa1dfd@linaro.org>

On 12/02/2024 15:09, Andy Shevchenko wrote:
> On Mon, Feb 12, 2024 at 02:56:43PM +0100, Krzysztof Kozlowski wrote:
>> On 12/02/2024 14:39, Andy Shevchenko wrote:
>>> On Mon, Feb 12, 2024 at 09:34:24AM +0100, Krzysztof Kozlowski wrote:
> 
> ...
> 
>>>> -    i2c {
>>>> -            #address-cells = <1>;
>>>> -            #size-cells = <0>;
>>>>  
>>>> -            pcf8574: pcf8574 at 27 {
>>>> -                    compatible = "nxp,pcf8574";
>>>> -                    reg = <0x27>;
>>>> -                    gpio-controller;
>>>> -                    #gpio-cells = <2>;
>>>> -            };
>>>> -    };
>>>
>>> In patch 3 you updated the lines that have lost their sense due to this one.
>>
>> How did they lose it?
> 
> Now they are referring to the non-existed node in the example. OTOH, there is
> already hc595 case...

All of the bindings examples do it. It's expected.

> 
> The Q here (as you pointed out that it's better to name nodes in generic way),
> how these names are okay with the schema (hc595, pcf8574) as being referred to?

They are not OK, although I don't see the name "hc595". There is phandle
to the hc595 label, but that's fine. Not a node name.

Best regards,
Krzysztof



From m.szyprowski at samsung.com  Mon Feb 12 06:21:46 2024
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Mon, 12 Feb 2024 15:21:46 +0100
Subject: [PATCH v4 06/10] arm64: cpufeature: Detect HCR_EL2.NV1 being
 RES0
In-Reply-To: <86eddh6auo.wl-maz@kernel.org>
References: <20240122181344.258974-1-maz@kernel.org>
	<20240122181344.258974-7-maz@kernel.org>
	<CGME20240212124837eucas1p231da54bb0ff8d46d38c6c7e627e50172@eucas1p2.samsung.com>
	<e3cc70fb-16d9-4e4e-aa35-f0eb2baaf166@samsung.com>
	<86eddh6auo.wl-maz@kernel.org>
Message-ID: <21e55530-7d66-4aff-a78d-4bffd55310d1@samsung.com>

On 12.02.2024 15:00, Marc Zyngier wrote:
> On Mon, 12 Feb 2024 12:48:35 +0000,
> Marek Szyprowski <m.szyprowski at samsung.com> wrote:
>> On 22.01.2024 19:13, Marc Zyngier wrote:
>>> A variant of FEAT_E2H0 not being implemented exists in the form of
>>> HCR_EL2.E2H being RES1 *and* HCR_EL2.NV1 being RES0 (indicating that
>>> only VHE is supported on the host and nested guests).
>>>
>>> Add the necessary infrastructure for this new CPU capability.
>>>
>>> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
>>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>>> ---
>> This patch landed recently in linux-next as commit da9af5071b25 ("arm64:
>> cpufeature: Detect HCR_EL2.NV1 being RES0"). I found that it causes a
>> following regression in the CPU hot-plug operation:
>>
>> # for i in /sys/devices/system/cpu/cpu[1-9]; do echo 1 >$i/online; done
>> ------------[ cut here ]------------
>> kernel BUG at arch/arm64/kernel/cpufeature.c:1468!
>> Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP
>> Modules linked in: dw_hdmi_cec dw_hdmi_i2s_audio crct10dif_ce
>> snd_soc_simple_card rockchip_saradc industrialio_triggered_buffer
>> hantro_vpu kfifo_buf snd_soc_simple_card_utils rockchip_thermal
>> phy_rockchip_naneng_combphy display_connector gpio_ir_recv v4l2_vp9
>> v4l2_h264 v4l2_mem2mem dwmac_rk videobuf2_dma_contig stmmac_platform
>> videobuf2_memops videobuf2_v4l2 stmmac rockchipdrm videodev
>> snd_soc_rockchip_i2s_tdm snd_soc_rk817 pcs_xpcs panfrost rtc_rk808
>> rk805_pwrkey analogix_dp rk817_charger spi_rockchip_sfc dw_mipi_dsi
>> videobuf2_common dw_hdmi drm_shmem_helper mc gpu_sched
>> drm_display_helper ahci_dwc ip_tables x_tables ipv6
>> CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.8.0-rc1+ #14563
>> Hardware name: Hardkernel ODROID-M1 (DT)
>> pstate: 800001c9 (Nzcv dAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>> pc : __read_sysreg_by_encoding+0x38c/0x390
>> lr : read_scoped_sysreg+0x4c/0x70
>> ...
>> Call trace:
>>   ?__read_sysreg_by_encoding+0x38c/0x390
>>   ?read_scoped_sysreg+0x4c/0x70
>>   ?has_nv1+0x18/0x48
>>   ?verify_local_cpu_caps+0x54/0x124
>>   ?check_local_cpu_capabilities+0x28/0x208
>>   ?secondary_start_kernel+0xb0/0x154
>>   ?__secondary_switched+0xb8/0xbc
>> Code: d53802f3 17ffff3b d5380253 17ffff39 (d4210000)
>> ---[ end trace 0000000000000000 ]---
>> Kernel panic - not syncing: Attempted to kill the idle task!
>> SMP: stopping secondary CPUs
>> Kernel Offset: disabled
>> CPU features: 0x1,80000000,80050295,2100721b
>> Memory Limit: none
>> ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---
>>
>> It looks that some additional checks are needed for the CPU hot-plug case.
> Nah, that's much simpler.
>
> I simply missed a spot where ID_AA64MMFR4_EL1 must be handled (it is
> getting annoying that we have more than a single place where these
> "read all the ID registers" are handled).
>
> Can you please give the following a go? If that works for you (it does
> for me here), I'll post an actual fix (plus another fix for another
> buglet I just noticed).

Works fine now.

Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
> Thanks,
>
> 	M.
>
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 0f29ac43c7a2..2f8958f27e9e 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1456,6 +1456,7 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
>   	read_sysreg_case(SYS_ID_AA64MMFR1_EL1);
>   	read_sysreg_case(SYS_ID_AA64MMFR2_EL1);
>   	read_sysreg_case(SYS_ID_AA64MMFR3_EL1);
> +	read_sysreg_case(SYS_ID_AA64MMFR4_EL1);
>   	read_sysreg_case(SYS_ID_AA64ISAR0_EL1);
>   	read_sysreg_case(SYS_ID_AA64ISAR1_EL1);
>   	read_sysreg_case(SYS_ID_AA64ISAR2_EL1);
>
Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From krzysztof.kozlowski at linaro.org  Mon Feb 12 06:22:46 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 12 Feb 2024 15:22:46 +0100
Subject: [PATCH] dt-bindings: vendor-prefixes: add smartrg
In-Reply-To: <20240212140839.27150-1-zajec5@gmail.com>
References: <20240212140839.27150-1-zajec5@gmail.com>
Message-ID: <945a884f-926f-4a30-8c68-725a52a97833@linaro.org>

On 12/02/2024 15:08, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> SmartRG described itself as a CPE manufacturer and produced few home
> network devices (e.g. wireless routers). Their SmartRG SR400ac router
> (smartrg,sr400ac) is covered by in-Linux DT binding and DTS file.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From david at redhat.com  Mon Feb 12 06:29:00 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 15:29:00 +0100
Subject: [PATCH v5 03/25] mm: Make pte_next_pfn() a wrapper around
 pte_advance_pfn()
In-Reply-To: <cdf4e537-5b0d-45ba-8094-527127c791a6@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-4-ryan.roberts@arm.com>
 <c269c2e0-afca-4ff0-8ffd-9049fb52c905@redhat.com>
 <cdf4e537-5b0d-45ba-8094-527127c791a6@arm.com>
Message-ID: <828d2573-b5fe-43b3-b955-944c05bcdb60@redhat.com>

On 12.02.24 15:10, Ryan Roberts wrote:
> On 12/02/2024 12:14, David Hildenbrand wrote:
>> On 02.02.24 09:07, Ryan Roberts wrote:
>>> The goal is to be able to advance a PTE by an arbitrary number of PFNs.
>>> So introduce a new API that takes a nr param.
>>>
>>> We are going to remove pte_next_pfn() and replace it with
>>> pte_advance_pfn(). As a first step, implement pte_next_pfn() as a
>>> wrapper around pte_advance_pfn() so that we can incrementally switch the
>>> architectures over. Once all arches are moved over, we will change all
>>> the core-mm callers to call pte_advance_pfn() directly and remove the
>>> wrapper.
>>>
>>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>>> ---
>>>  ? include/linux/pgtable.h | 8 +++++++-
>>>  ? 1 file changed, 7 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>>> index 5e7eaf8f2b97..815d92dcb96b 100644
>>> --- a/include/linux/pgtable.h
>>> +++ b/include/linux/pgtable.h
>>> @@ -214,9 +214,15 @@ static inline int pmd_dirty(pmd_t pmd)
>>>  ? ? ? #ifndef pte_next_pfn
>>> +#ifndef pte_advance_pfn
>>> +static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>>> +{
>>> +??? return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
>>> +}
>>> +#endif
>>>  ? static inline pte_t pte_next_pfn(pte_t pte)
>>>  ? {
>>> -??? return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
>>> +??? return pte_advance_pfn(pte, 1);
>>>  ? }
>>>  ? #endif
>>>    
>>
>> I do wonder if we simply want to leave pte_next_pfn() around? Especially patch
>> #4, #6 don't really benefit from the change? So are the other set_ptes()
>> implementations.
>>
>> That is, only convert all pte_next_pfn()->pte_advance_pfn(), and leave a
>> pte_next_pfn() macro in place.
>>
>> Any downsides to that?
> 
> The downside is just having multiple functions that effectively do the same
> thing. Personally I think its cleaner and easier to understand the code with
> just one generic function which we pass 1 to it where we only want to advance by
> 1. In the end, there are only a couple of places where pte_advance_pfn(1) is
> used, so doesn't really seem valuable to me to maintain a specialization.

Well, not really functions, just a macro. Like we have set_pte_at() 
translating to set_ptes().

Arguably, we have more callers of set_pte_at().

"Easier to understand", I don't know. :)

> 
> Unless you feel strongly that we need to keep pte_next_pfn() then I'd prefer to
> leave it as I've done in this series.

Well, it makes you patch set shorter and there is less code churn.

So personally, I'd just leave pte_next_pfn() in there. But whatever you 
prefer, not the end of the world.

-- 
Cheers,

David / dhildenb



From andriy.shevchenko at linux.intel.com  Mon Feb 12 06:31:49 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Mon, 12 Feb 2024 16:31:49 +0200
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit,hd44780: drop redundant
 GPIO node
In-Reply-To: <b836cf9d-dc71-4835-b45f-1092aafa1dfd@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <ZcofhWb8stiddmru@smile.fi.intel.com>
 <906db6a6-48ba-41e5-be23-1dea0ecf96ee@linaro.org>
 <Zcomjp9oH9VfO3NA@smile.fi.intel.com>
 <b836cf9d-dc71-4835-b45f-1092aafa1dfd@linaro.org>
Message-ID: <Zcor1RYVMh3-V-wL@smile.fi.intel.com>

On Mon, Feb 12, 2024 at 03:20:26PM +0100, Krzysztof Kozlowski wrote:
> On 12/02/2024 15:09, Andy Shevchenko wrote:
> > On Mon, Feb 12, 2024 at 02:56:43PM +0100, Krzysztof Kozlowski wrote:
> >> On 12/02/2024 14:39, Andy Shevchenko wrote:
> >>> On Mon, Feb 12, 2024 at 09:34:24AM +0100, Krzysztof Kozlowski wrote:

...

> >>>> -    i2c {
> >>>> -            #address-cells = <1>;
> >>>> -            #size-cells = <0>;
> >>>>  
> >>>> -            pcf8574: pcf8574 at 27 {
> >>>> -                    compatible = "nxp,pcf8574";
> >>>> -                    reg = <0x27>;
> >>>> -                    gpio-controller;
> >>>> -                    #gpio-cells = <2>;
> >>>> -            };
> >>>> -    };
> >>>
> >>> In patch 3 you updated the lines that have lost their sense due to this one.
> >>
> >> How did they lose it?
> > 
> > Now they are referring to the non-existed node in the example. OTOH, there is
> > already hc595 case...
> 
> All of the bindings examples do it. It's expected.
> 
> > 
> > The Q here (as you pointed out that it's better to name nodes in generic way),
> > how these names are okay with the schema (hc595, pcf8574) as being referred to?
> 
> They are not OK, although I don't see the name "hc595". There is phandle
> to the hc595 label, but that's fine. Not a node name.

Ah, okay, so it's a semantic difference. Thank you for your patience and elaboration!

-- 
With Best Regards,
Andy Shevchenko




From rsc at runtux.com  Mon Feb 12 06:39:58 2024
From: rsc at runtux.com (Ralf Schlatterbeck)
Date: Mon, 12 Feb 2024 15:39:58 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop
 redundant GPIO node
In-Reply-To: <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
 <20240212115837.efz73yxinkysdmgh@runtux.com>
 <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
Message-ID: <20240212143957.gaxxz3nt7pxhlmqh@runtux.com>

On Mon, Feb 12, 2024 at 02:38:27PM +0100, Krzysztof Kozlowski wrote:
> On 12/02/2024 12:58, Ralf Schlatterbeck wrote:
> 
> GPIO expanders and their usage is nothing specific to this device -
> other devices also might benefit of them. Or the SoCs which have enough
> of GPIOs... I really do not understand why do we need expander here and
> how does it help

Can we then at least link the I/O Expander example to the docs of that
display?
I've documented my experience here:
https://blog.runtux.com/posts/2021/01/06/

And at the time there were two out-of-tree implementations.

Note that I think that redundancy in code is bad.
Not so for documentation.

Thanks + kind regards
Ralf
-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   www.runtux.com
Reichergasse 131, A-3411 Weidling       email: office at runtux.com


From ryan.roberts at arm.com  Mon Feb 12 06:45:00 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 14:45:00 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <a91cfe1c-289e-4828-8cfc-be34eb69a71b@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <a91cfe1c-289e-4828-8cfc-be34eb69a71b@redhat.com>
Message-ID: <502a3ea7-fd86-4314-8292-c7999eda92eb@arm.com>

On 12/02/2024 13:54, David Hildenbrand wrote:
>>> If so, I wonder if we could instead do that comparison modulo the access/dirty
>>> bits,
>>
>> I think that would work - but will need to think a bit more on it.
>>
>>> and leave ptep_get_lockless() only reading a single entry?
>>
>> I think we will need to do something a bit less fragile. ptep_get() does collect
>> the access/dirty bits so its confusing if ptep_get_lockless() doesn't IMHO. So
>> we will likely want to rename the function and make its documentation explicit
>> that it does not return those bits.
>>
>> ptep_get_lockless_noyoungdirty()? yuk... Any ideas?
>>
>> Of course if I could convince you the current implementation is safe, I might be
>> able to sidestep this optimization until a later date?
> 
> As discussed (and pointed out abive), there might be quite some callsites where
> we don't really care about uptodate accessed/dirty bits -- where ptep_get() is
> used nowadays.
> 
> One way to approach that I had in mind was having an explicit interface:
> 
> ptep_get()
> ptep_get_uptodate()
> ptep_get_lockless()
> ptep_get_lockless_uptodate()

Yes, I like the direction of this. I guess we anticipate that call sites
requiring the "_uptodate" variant will be the minority so it makes sense to use
the current names for the "_not_uptodate" variants? But to do a slow migration,
it might be better/safer to have the weaker variant use the new name - that
would allow us to downgrade one at a time?

> 
> Especially the last one might not be needed.
I've done a scan through the code and agree with Mark's original conclusions.
Additionally, huge_pte_alloc() (which isn't used for arm64) doesn't rely on
access/dirty info. So I think I could migrate everything to the weaker variant
fairly easily.

> 
> Futher, "uptodate" might not be the best choice because of PageUptodate() and
> friends. But it's better than "youngdirty"/"noyoungdirty" IMHO.

Certainly agree with "noyoungdirty" being a horrible name. How about "_sync" /
"_nosync"?

> 
> Of course, any such changes require care and are better done one step at at time
> separately.
> 

So I propose to introduce ptep_get_lockless_nosync() (name up for discussion)
and migrate all users to it, as part of this series. This will side-step Mark's
correctness concerns. We can add ptep_get_nosync() later and migrate slowly.

Shout if you think this is a bad plan.

Thanks,
Ryan




From robh at kernel.org  Mon Feb 12 06:45:16 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 12 Feb 2024 08:45:16 -0600
Subject: [PATCH V3 0/3] dt-bindings: arm: mediatek: convert
 MT7622-related bindings to the json-schema
In-Reply-To: <20240211213925.18348-1-zajec5@gmail.com>
References: <20240211213925.18348-1-zajec5@gmail.com>
Message-ID: <20240212144516.GA301127-robh@kernel.org>

On Sun, Feb 11, 2024 at 10:39:22PM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> There are more MediaTek bindings to convert but for now I focused on
> those used by MT7622.
> 
> V2: Move bindings to /clock/
>     Use clock-controller@ nodenames
>     Drop incorrectly specified "syscon"
> 
> V3: Update titles of all 3 bindings
>     Simplify HIFSYS compatbile (drop "items:")
> 
> Rafa? Mi?ecki (3):
>   dt-bindings: arm: mediatek: convert hifsys to the json-schema clock
>   dt-bindings: arm: mediatek: convert PCIESYS to the json-schema clock
>   dt-bindings: arm: mediatek: convert SSUSBSYS to the json-schema clock

dt-bindings: clock: mediatek: ...

>  .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
>  .../arm/mediatek/mediatek,pciesys.txt         | 25 ----------
>  .../arm/mediatek/mediatek,ssusbsys.txt        | 25 ----------
>  .../clock/mediatek,mt2701-hifsys.yaml         | 50 +++++++++++++++++++
>  .../clock/mediatek,mt7622-pciesys.yaml        | 45 +++++++++++++++++
>  .../clock/mediatek,mt7622-ssusbsys.yaml       | 45 +++++++++++++++++
>  6 files changed, 140 insertions(+), 76 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
>  delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
>  delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
>  create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml
>  create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml

Presumably Stephen should take these, but you Cc'ed the timekeeping 
maintainers rather than the clock maintainers. Please use 
get_maintainer.pl.

Rob


From neil.armstrong at linaro.org  Mon Feb 12 06:45:56 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 12 Feb 2024 15:45:56 +0100
Subject: [PATCH 3/5] drm: msm: add support for A750 GPU
In-Reply-To: <b5d76a25-045a-4acd-ad20-d28855b40222@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
 <20240212-topic-sm8650-gpu-v1-3-708a40b747b5@linaro.org>
 <b5d76a25-045a-4acd-ad20-d28855b40222@linaro.org>
Message-ID: <bcad544c-7ca2-4b4f-805b-4ccaedbd091c@linaro.org>

On 12/02/2024 11:46, Konrad Dybcio wrote:
> On 12.02.2024 11:37, Neil Armstrong wrote:
>> Add support for the A750 GPU found on the SM8650 platform
>>
>> Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
>> doesn't have an HWCFG block but a separate register set.
>>
>> The missing registers are added in the a6xx.xml.h file that would
>> require a subsequent sync and the non-existent hwcfg is handled
>> in a6xx_set_hwcg().
> 
> These should also be submitted to mesa to make sure the next header sync
> doesn't wipe them

Ack submitting them right now: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27576

> 
> [...]
> 
>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> @@ -958,10 +958,11 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>   	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>>   	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
>>   	const struct adreno_reglist *reg;
>> +	bool skip_programming = !(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu));
> 
> is_a750?

OK right, I was thinking of the next gpu which will probably also miss an hwcfg

> 
>>   	unsigned int i;
>>   	u32 val, clock_cntl_on, cgc_mode;
>>   
>> -	if (!adreno_gpu->info->hwcg)
>> +	if (skip_programming)
>>   		return;
>>   
>>   	if (adreno_is_a630(adreno_gpu))
>> @@ -982,6 +983,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>   			  state ? 0x5555 : 0);
>>   	}
>>   
>> +	if (!adreno_gpu->info->hwcg) {
> 
> I don't think this block of code is reachable now, no?

It is because we didn't skip when adreno_is_a7xx(adreno_gpu)

> 
> Maybe remove the skip_programming and if_a750 here?
This would require:
 >> -	if (!adreno_gpu->info->hwcg || )
 >> +	if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))

and:

 >> +	if (adreno_is_a750(adreno_gpu)) {

But if the next gpu also doesn't have an hwcfg, we will need to use
the current design...

I just tried with:
====================><===============================
@@ -961,7 +961,7 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
         unsigned int i;
         u32 val, clock_cntl_on, cgc_mode;

-       if (!adreno_gpu->info->hwcg)
+       if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
                 return;

         if (adreno_is_a630(adreno_gpu))
@@ -982,6 +982,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
                           state ? 0x5555 : 0);
         }

+       if (adreno_is_a750(adreno_gpu)) {
+               gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
+               gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
+
+               if (state) {
+                       gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
+
+                       if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
+                                            val & A7XX_RBBM_CGC_P2S_STATUS_TXDONE, 1, 10)) {
+                               dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
+                               return;
+                       }
+
+                       gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
+               }
+
+               return;
+       }
+
         val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);

         /* Don't re-program the registers if they are already correct */
====================><===============================

And it works fine, does it work it for you ?

> 
>> +		gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
>> +		gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
>> +
>> +		if (state) {
>> +			gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
>> +
>> +			if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
>> +					     val & BIT(0), 1, 10)) {
> 
> We should define that bit name (the err suggests it's
> REG_A7XX_RBBM_GCC_P2S_STATUS_TXDONE or so)
> 
> [...]
> 
>> +static inline int adreno_is_a750(struct adreno_gpu *gpu)
>> +{
>> +	return gpu->info->chip_ids[0] == 0x43051401;
>> +}
>> +
>>   /* Placeholder to make future diffs smaller */
> 
> Please also remove this comment now that it's invalid

Ack

> 
> Konrad

Thanks,
Neil



From maz at kernel.org  Mon Feb 12 06:47:36 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 12 Feb 2024 14:47:36 +0000
Subject: [PATCH 2/2] arm64: cpufeatures: Only check for NV1 if NV is present
In-Reply-To: <20240212144736.1933112-1-maz@kernel.org>
References: <20240212144736.1933112-1-maz@kernel.org>
Message-ID: <20240212144736.1933112-3-maz@kernel.org>

We handle ID_AA64MMFR4_EL1.E2H0 being 0 as NV1 being present.
However, this is only true if FEAT_NV is implemented.

Add the required check to has_nv1(), avoiding spuriously advertising
NV1 on HW that doesn't have NV at all.

Fixes: da9af5071b25 ("arm64: cpufeature: Detect HCR_EL2.NV1 being RES0")
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 2f8958f27e9e..3421b684d340 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1812,8 +1812,9 @@ static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
 		{}
 	};
 
-	return !(has_cpuid_feature(entry, scope) ||
-		 is_midr_in_range_list(read_cpuid_id(), nv1_ni_list));
+	return (this_cpu_has_cap(ARM64_HAS_NESTED_VIRT) &&
+		!(has_cpuid_feature(entry, scope) ||
+		  is_midr_in_range_list(read_cpuid_id(), nv1_ni_list)));
 }
 
 #if defined(ID_AA64MMFR0_EL1_TGRAN_LPA2) && defined(ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2)
-- 
2.39.2



From maz at kernel.org  Mon Feb 12 06:47:34 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 12 Feb 2024 14:47:34 +0000
Subject: [PATCH 0/2] ARM64: Fixes for FEAT_E2H0 handling
Message-ID: <20240212144736.1933112-1-maz@kernel.org>

As the FEAT_E2H0 handling series has made it to -next, some of its
shortcomings are becoming apparent:

- A missing ID register in __read_sysreg_by_encoding() is causing CPU
  hotplug to explode (reported by Marek)

- NV1 is getting advertised on HW that doesn't have FEAT_NV, which is
  fairly harmless, but still annoying

These fixes should directly apply on the feat_e2h0 branch that Oliver
has pushed to kvmarm/next.

Marc Zyngier (2):
  arm64: cpufeatures: Add missing ID_AA64MMFR4_EL1 to
    __read_sysreg_by_encoding()
  arm64: cpufeatures: Only check for NV1 if NV is present

 arch/arm64/kernel/cpufeature.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

-- 
2.39.2



From maz at kernel.org  Mon Feb 12 06:47:35 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 12 Feb 2024 14:47:35 +0000
Subject: [PATCH 1/2] arm64: cpufeatures: Add missing ID_AA64MMFR4_EL1 to __read_sysreg_by_encoding()
In-Reply-To: <20240212144736.1933112-1-maz@kernel.org>
References: <20240212144736.1933112-1-maz@kernel.org>
Message-ID: <20240212144736.1933112-2-maz@kernel.org>

When triggering a CPU hotplug scenario, we reparse the CPU feature
with SCOPE_LOCAL_CPU, for which we use __read_sysreg_by_encoding()
to get the HW value for this CPU.

As it turns out, we're missing the handling for ID_AA64MMFR4_EL1,
and trigger a BUG(). Funnily enough, Marek isn't completely happy
about that.

Add the damn register to the list.

Fixes: 805bb61f8279 ("arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling")
Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0f29ac43c7a2..2f8958f27e9e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1456,6 +1456,7 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
 	read_sysreg_case(SYS_ID_AA64MMFR1_EL1);
 	read_sysreg_case(SYS_ID_AA64MMFR2_EL1);
 	read_sysreg_case(SYS_ID_AA64MMFR3_EL1);
+	read_sysreg_case(SYS_ID_AA64MMFR4_EL1);
 	read_sysreg_case(SYS_ID_AA64ISAR0_EL1);
 	read_sysreg_case(SYS_ID_AA64ISAR1_EL1);
 	read_sysreg_case(SYS_ID_AA64ISAR2_EL1);
-- 
2.39.2



From nfraprado at collabora.com  Mon Feb 12 06:50:04 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 12 Feb 2024 09:50:04 -0500
Subject: [PATCH v4 0/4] Allow coreboot modules to autoload and enable cbmem
 in the arm64 defconfig
Message-ID: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>

This series adds the missing pieces to the coreboot bus and the module
alias generation to allow coreboot modules to be automatically loaded
when matching devices are detected.

The configs for cbmem coreboot entries are then enabled in the arm64
defconfig, as modules, to allow reading logs from coreboot on arm64
Chromebooks, which is useful for debugging the boot process.

Changes in v4:
- Added driver_data to device_id struct
- Link to v3: https://lore.kernel.org/r/20240117-coreboot-mod-defconfig-v3-0-049565a27bba at collabora.com

Changes in v3:
- Merged all "add to module device table" commits into a single commit
  which also changes the coreboot_driver struct to contain an id table
  and avoid unused variable warnings for the id tables.

Changes in v2:
- Added commits for vpd, memconsole and framebuffer drivers to add them
  to the module device table

---
N?colas F. R. A. Prado (4):
      firmware: coreboot: Generate modalias uevent for devices
      firmware: coreboot: Generate aliases for coreboot modules
      firmware: coreboot: Replace tag with id table in driver struct
      arm64: defconfig: Enable support for cbmem entries in the coreboot table

 arch/arm64/configs/defconfig                   |  3 +++
 drivers/firmware/google/cbmem.c                |  8 +++++++-
 drivers/firmware/google/coreboot_table.c       | 20 +++++++++++++++++++-
 drivers/firmware/google/coreboot_table.h       |  3 ++-
 drivers/firmware/google/framebuffer-coreboot.c |  8 +++++++-
 drivers/firmware/google/memconsole-coreboot.c  |  8 +++++++-
 drivers/firmware/google/vpd.c                  |  8 +++++++-
 include/linux/mod_devicetable.h                | 10 ++++++++++
 scripts/mod/devicetable-offsets.c              |  3 +++
 scripts/mod/file2alias.c                       | 10 ++++++++++
 10 files changed, 75 insertions(+), 6 deletions(-)
---
base-commit: 0f067394dd3b2af3263339cf7183bdb6ee0ac1f8
change-id: 20240117-coreboot-mod-defconfig-826b01e242d9

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From nfraprado at collabora.com  Mon Feb 12 06:50:05 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 12 Feb 2024 09:50:05 -0500
Subject: [PATCH v4 1/4] firmware: coreboot: Generate modalias uevent for
 devices
In-Reply-To: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
References: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
Message-ID: <20240212-coreboot-mod-defconfig-v4-1-d14172676f6d@collabora.com>

Generate a modalias uevent for devices in the coreboot bus to allow
userspace to automatically load the corresponding modules.

Acked-by: Brian Norris <briannorris at chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Brian Norris <briannorris at chromium.org>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 drivers/firmware/google/coreboot_table.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
index 2a4469bf1b81..c1b9a9e8e8ed 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -53,11 +53,20 @@ static void coreboot_bus_remove(struct device *dev)
 		driver->remove(device);
 }
 
+static int coreboot_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)
+{
+	struct coreboot_device *device = CB_DEV(dev);
+	u32 tag = device->entry.tag;
+
+	return add_uevent_var(env, "MODALIAS=coreboot:t%08X", tag);
+}
+
 static struct bus_type coreboot_bus_type = {
 	.name		= "coreboot",
 	.match		= coreboot_bus_match,
 	.probe		= coreboot_bus_probe,
 	.remove		= coreboot_bus_remove,
+	.uevent		= coreboot_bus_uevent,
 };
 
 static void coreboot_device_release(struct device *dev)

-- 
2.43.0



From nfraprado at collabora.com  Mon Feb 12 06:50:06 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 12 Feb 2024 09:50:06 -0500
Subject: [PATCH v4 2/4] firmware: coreboot: Generate aliases for coreboot
 modules
In-Reply-To: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
References: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
Message-ID: <20240212-coreboot-mod-defconfig-v4-2-d14172676f6d@collabora.com>

Generate aliases for coreboot modules to allow automatic module probing.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Brian Norris <briannorris at chromium.org>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 include/linux/mod_devicetable.h   | 10 ++++++++++
 scripts/mod/devicetable-offsets.c |  3 +++
 scripts/mod/file2alias.c          | 10 ++++++++++
 3 files changed, 23 insertions(+)

diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index f458469c5ce5..7a9a07ea451b 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -960,4 +960,14 @@ struct vchiq_device_id {
 	char name[32];
 };
 
+/**
+ * struct coreboot_device_id - Identifies a coreboot table entry
+ * @tag: tag ID
+ * @driver_data: driver specific data
+ */
+struct coreboot_device_id {
+	__u32 tag;
+	kernel_ulong_t driver_data;
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index e91a3c38143b..518200813d4e 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -274,5 +274,8 @@ int main(void)
 	DEVID(vchiq_device_id);
 	DEVID_FIELD(vchiq_device_id, name);
 
+	DEVID(coreboot_device_id);
+	DEVID_FIELD(coreboot_device_id, tag);
+
 	return 0;
 }
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 4829680a0a6d..5d1c61fa5a55 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1494,6 +1494,15 @@ static int do_vchiq_entry(const char *filename, void *symval, char *alias)
 	return 1;
 }
 
+/* Looks like: coreboot:tN */
+static int do_coreboot_entry(const char *filename, void *symval, char *alias)
+{
+	DEF_FIELD(symval, coreboot_device_id, tag);
+	sprintf(alias, "coreboot:t%08X", tag);
+
+	return 1;
+}
+
 /* Does namelen bytes of name exactly match the symbol? */
 static bool sym_is(const char *name, unsigned namelen, const char *symbol)
 {
@@ -1575,6 +1584,7 @@ static const struct devtable devtable[] = {
 	{"ishtp", SIZE_ishtp_device_id, do_ishtp_entry},
 	{"cdx", SIZE_cdx_device_id, do_cdx_entry},
 	{"vchiq", SIZE_vchiq_device_id, do_vchiq_entry},
+	{"coreboot", SIZE_coreboot_device_id, do_coreboot_entry},
 };
 
 /* Create MODULE_ALIAS() statements.

-- 
2.43.0



From nfraprado at collabora.com  Mon Feb 12 06:50:07 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 12 Feb 2024 09:50:07 -0500
Subject: [PATCH v4 3/4] firmware: coreboot: Replace tag with id table in
 driver struct
In-Reply-To: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
References: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
Message-ID: <20240212-coreboot-mod-defconfig-v4-3-d14172676f6d@collabora.com>

Switch the plain 'tag' field in struct coreboot_driver for the newly
created coreboot_device_id struct, which also contains a tag field and
has the benefit of allowing modalias generation, and update all coreboot
drivers accordingly.

While at it, also add the id table for each driver to the module device
table to allow automatically loading the module.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Brian Norris <briannorris at chromium.org>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 drivers/firmware/google/cbmem.c                |  8 +++++++-
 drivers/firmware/google/coreboot_table.c       | 11 ++++++++++-
 drivers/firmware/google/coreboot_table.h       |  3 ++-
 drivers/firmware/google/framebuffer-coreboot.c |  8 +++++++-
 drivers/firmware/google/memconsole-coreboot.c  |  8 +++++++-
 drivers/firmware/google/vpd.c                  |  8 +++++++-
 6 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/google/cbmem.c b/drivers/firmware/google/cbmem.c
index 88e587ba1e0d..c2bffdc352a3 100644
--- a/drivers/firmware/google/cbmem.c
+++ b/drivers/firmware/google/cbmem.c
@@ -114,6 +114,12 @@ static int cbmem_entry_probe(struct coreboot_device *dev)
 	return 0;
 }
 
+static const struct coreboot_device_id cbmem_ids[] = {
+	{ .tag = LB_TAG_CBMEM_ENTRY },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(coreboot, cbmem_ids);
+
 static struct coreboot_driver cbmem_entry_driver = {
 	.probe = cbmem_entry_probe,
 	.drv = {
@@ -121,7 +127,7 @@ static struct coreboot_driver cbmem_entry_driver = {
 		.owner = THIS_MODULE,
 		.dev_groups = dev_groups,
 	},
-	.tag = LB_TAG_CBMEM_ENTRY,
+	.id_table = cbmem_ids,
 };
 module_coreboot_driver(cbmem_entry_driver);
 
diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
index c1b9a9e8e8ed..33971cf33112 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -28,8 +28,17 @@ static int coreboot_bus_match(struct device *dev, struct device_driver *drv)
 {
 	struct coreboot_device *device = CB_DEV(dev);
 	struct coreboot_driver *driver = CB_DRV(drv);
+	const struct coreboot_device_id *id;
 
-	return device->entry.tag == driver->tag;
+	if (!driver->id_table)
+		return 0;
+
+	for (id = driver->id_table; id->tag; id++) {
+		if (device->entry.tag == id->tag)
+			return 1;
+	}
+
+	return 0;
 }
 
 static int coreboot_bus_probe(struct device *dev)
diff --git a/drivers/firmware/google/coreboot_table.h b/drivers/firmware/google/coreboot_table.h
index d814dca33a08..86427989c57f 100644
--- a/drivers/firmware/google/coreboot_table.h
+++ b/drivers/firmware/google/coreboot_table.h
@@ -13,6 +13,7 @@
 #define __COREBOOT_TABLE_H
 
 #include <linux/device.h>
+#include <linux/mod_devicetable.h>
 
 /* Coreboot table header structure */
 struct coreboot_table_header {
@@ -93,7 +94,7 @@ struct coreboot_driver {
 	int (*probe)(struct coreboot_device *);
 	void (*remove)(struct coreboot_device *);
 	struct device_driver drv;
-	u32 tag;
+	const struct coreboot_device_id *id_table;
 };
 
 /* Register a driver that uses the data from a coreboot table. */
diff --git a/drivers/firmware/google/framebuffer-coreboot.c b/drivers/firmware/google/framebuffer-coreboot.c
index 5c84bbebfef8..07c458bf64ec 100644
--- a/drivers/firmware/google/framebuffer-coreboot.c
+++ b/drivers/firmware/google/framebuffer-coreboot.c
@@ -80,13 +80,19 @@ static void framebuffer_remove(struct coreboot_device *dev)
 	platform_device_unregister(pdev);
 }
 
+static const struct coreboot_device_id framebuffer_ids[] = {
+	{ .tag = CB_TAG_FRAMEBUFFER },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(coreboot, framebuffer_ids);
+
 static struct coreboot_driver framebuffer_driver = {
 	.probe = framebuffer_probe,
 	.remove = framebuffer_remove,
 	.drv = {
 		.name = "framebuffer",
 	},
-	.tag = CB_TAG_FRAMEBUFFER,
+	.id_table = framebuffer_ids,
 };
 module_coreboot_driver(framebuffer_driver);
 
diff --git a/drivers/firmware/google/memconsole-coreboot.c b/drivers/firmware/google/memconsole-coreboot.c
index 74b5286518ee..24c97a70aa80 100644
--- a/drivers/firmware/google/memconsole-coreboot.c
+++ b/drivers/firmware/google/memconsole-coreboot.c
@@ -96,13 +96,19 @@ static void memconsole_remove(struct coreboot_device *dev)
 	memconsole_exit();
 }
 
+static const struct coreboot_device_id memconsole_ids[] = {
+	{ .tag = CB_TAG_CBMEM_CONSOLE },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(coreboot, memconsole_ids);
+
 static struct coreboot_driver memconsole_driver = {
 	.probe = memconsole_probe,
 	.remove = memconsole_remove,
 	.drv = {
 		.name = "memconsole",
 	},
-	.tag = CB_TAG_CBMEM_CONSOLE,
+	.id_table = memconsole_ids,
 };
 module_coreboot_driver(memconsole_driver);
 
diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c
index ee6e08c0592b..8e4216714b29 100644
--- a/drivers/firmware/google/vpd.c
+++ b/drivers/firmware/google/vpd.c
@@ -306,13 +306,19 @@ static void vpd_remove(struct coreboot_device *dev)
 	kobject_put(vpd_kobj);
 }
 
+static const struct coreboot_device_id vpd_ids[] = {
+	{ .tag = CB_TAG_VPD },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(coreboot, vpd_ids);
+
 static struct coreboot_driver vpd_driver = {
 	.probe = vpd_probe,
 	.remove = vpd_remove,
 	.drv = {
 		.name = "vpd",
 	},
-	.tag = CB_TAG_VPD,
+	.id_table = vpd_ids,
 };
 module_coreboot_driver(vpd_driver);
 

-- 
2.43.0



From nfraprado at collabora.com  Mon Feb 12 06:50:08 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 12 Feb 2024 09:50:08 -0500
Subject: [PATCH v4 4/4] arm64: defconfig: Enable support for cbmem entries
 in the coreboot table
In-Reply-To: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
References: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
Message-ID: <20240212-coreboot-mod-defconfig-v4-4-d14172676f6d@collabora.com>

Enable the cbmem driver and dependencies in order to support reading
cbmem entries from the coreboot table, which are used to store logs from
coreboot on arm64 Chromebooks, and provide useful information for
debugging the boot process on those devices.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Brian Norris <briannorris at chromium.org>
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 361c31b5d064..49121133f045 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -255,6 +255,9 @@ CONFIG_INTEL_STRATIX10_RSU=m
 CONFIG_MTK_ADSP_IPC=m
 CONFIG_QCOM_QSEECOM=y
 CONFIG_QCOM_QSEECOM_UEFISECAPP=y
+CONFIG_GOOGLE_FIRMWARE=y
+CONFIG_GOOGLE_CBMEM=m
+CONFIG_GOOGLE_COREBOOT_TABLE=m
 CONFIG_EFI_CAPSULE_LOADER=y
 CONFIG_IMX_SCU=y
 CONFIG_IMX_SCU_PD=y

-- 
2.43.0



From ryan.roberts at arm.com  Mon Feb 12 07:00:58 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 15:00:58 +0000
Subject: [PATCH v5 22/25] mm: Add pte_batch_hint() to reduce scanning in
 folio_pte_batch()
In-Reply-To: <6d452a1a-1edc-4e97-8b39-99dc48315bb8@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-23-ryan.roberts@arm.com>
 <6d452a1a-1edc-4e97-8b39-99dc48315bb8@redhat.com>
Message-ID: <13c6dc7b-7cc5-4cd1-8d6b-4574c4386076@arm.com>

On 12/02/2024 13:43, David Hildenbrand wrote:
> On 02.02.24 09:07, Ryan Roberts wrote:
>> Some architectures (e.g. arm64) can tell from looking at a pte, if some
>> follow-on ptes also map contiguous physical memory with the same pgprot.
>> (for arm64, these are contpte mappings).
>>
>> Take advantage of this knowledge to optimize folio_pte_batch() so that
>> it can skip these ptes when scanning to create a batch. By default, if
>> an arch does not opt-in, folio_pte_batch() returns a compile-time 1, so
>> the changes are optimized out and the behaviour is as before.
>>
>> arm64 will opt-in to providing this hint in the next patch, which will
>> greatly reduce the cost of ptep_get() when scanning a range of contptes.
>>
>> Tested-by: John Hubbard <jhubbard at nvidia.com>
>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>> ---
>> ? include/linux/pgtable.h | 18 ++++++++++++++++++
>> ? mm/memory.c???????????? | 20 +++++++++++++-------
>> ? 2 files changed, 31 insertions(+), 7 deletions(-)
>>
>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>> index 50f32cccbd92..cba31f177d27 100644
>> --- a/include/linux/pgtable.h
>> +++ b/include/linux/pgtable.h
>> @@ -212,6 +212,24 @@ static inline int pmd_dirty(pmd_t pmd)
>> ? #define arch_flush_lazy_mmu_mode()??? do {} while (0)
>> ? #endif
>> ? +#ifndef pte_batch_hint
>> +/**
>> + * pte_batch_hint - Number of pages that can be added to batch without scanning.
>> + * @ptep: Page table pointer for the entry.
>> + * @pte: Page table entry.
>> + *
>> + * Some architectures know that a set of contiguous ptes all map the same
>> + * contiguous memory with the same permissions. In this case, it can provide a
>> + * hint to aid pte batching without the core code needing to scan every pte.
> 
> I think we might want to document here the expectation regarding
> dirty/accessed bits. folio_pte_batch() will ignore dirty bits only with
> FPB_IGNORE_DIRTY. But especially for arm64, it makes sense to ignore them
> always when batching, because the dirty bit may target any pte part of the
> cont-pte group either way.
> 
> Maybe something like:
> 
> "
> An architecture implementation may only ignore the PTE accessed and dirty bits.
> Further, it may only ignore the dirty bit if that bit is already not
> maintained with precision per PTE inside the hinted batch, and ptep_get()
> would already have to collect it from various PTEs.
> "

Yep, sounds good. I'll add it in next version.

> 
> I think there are some more details to it, but I'm hoping something along
> the lines above is sufficient.
> 
> 
>> +
>> ? #ifndef pte_advance_pfn
>> ? static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>> ? {
>> diff --git a/mm/memory.c b/mm/memory.c
>> index 65fbe4f886c1..902665b27702 100644
>> --- a/mm/memory.c
>> +++ b/mm/memory.c
>> @@ -988,16 +988,21 @@ static inline int folio_pte_batch(struct folio *folio,
>> unsigned long addr,
>> ? {
>> ????? unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio);
>> ????? const pte_t *end_ptep = start_ptep + max_nr;
>> -??? pte_t expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, 1),
>> flags);
>> -??? pte_t *ptep = start_ptep + 1;
>> +??? pte_t expected_pte = __pte_batch_clear_ignored(pte, flags);
>> +??? pte_t *ptep = start_ptep;
>> ????? bool writable;
>> +??? int nr;
>> ? ????? if (any_writable)
>> ????????? *any_writable = false;
>> ? ????? VM_WARN_ON_FOLIO(!pte_present(pte), folio);
>> ? -??? while (ptep != end_ptep) {
>> +??? nr = pte_batch_hint(ptep, pte);
>> +??? expected_pte = pte_advance_pfn(expected_pte, nr);
>> +??? ptep += nr;
>> +
> 
> *Maybe* it's easier to get when initializing expected_pte+ptep only once.
> 
> Like:
> 
> [...]
> pte_t expected_pte, *ptep;
> [...]
> 
> nr = pte_batch_hint(start_ptep, pte);
> expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, nr), flags);
> ptep = start_ptep + nr;

Yeah that works for me. Will change for next version.

> 
>> +??? while (ptep < end_ptep) {
>> ????????? pte = ptep_get(ptep);
>> ????????? if (any_writable)
>> ????????????? writable = !!pte_write(pte);
>> @@ -1011,17 +1016,18 @@ static inline int folio_pte_batch(struct folio *folio,
>> unsigned long addr,
>> ?????????? * corner cases the next PFN might fall into a different
>> ?????????? * folio.
>> ?????????? */
>> -??????? if (pte_pfn(pte) == folio_end_pfn)
>> +??????? if (pte_pfn(pte) >= folio_end_pfn)
>> ????????????? break;
>> ? ????????? if (any_writable)
>> ????????????? *any_writable |= writable;
>> ? -??????? expected_pte = pte_advance_pfn(expected_pte, 1);
>> -??????? ptep++;
>> +??????? nr = pte_batch_hint(ptep, pte);
>> +??????? expected_pte = pte_advance_pfn(expected_pte, nr);
>> +??????? ptep += nr;
>> ????? }
>> ? -??? return ptep - start_ptep;
>> +??? return min(ptep - start_ptep, max_nr);
>> ? }
> 
> Acked-by: David Hildenbrand <david at redhat.com>

Thanks!

> 



From neil.armstrong at linaro.org  Mon Feb 12 07:02:49 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 16:02:49 +0100
Subject: [PATCH v1 2/2] arm64: dts: amlogic: axg: initialize default SoC
 capacitance
In-Reply-To: <20240209212816.11187-3-ddrokosov@salutedevices.com>
References: <20240209212816.11187-1-ddrokosov@salutedevices.com>
 <20240209212816.11187-3-ddrokosov@salutedevices.com>
Message-ID: <34ee9676-567f-4c07-83b0-f3b8b1e08db9@linaro.org>

On 09/02/2024 22:28, Dmitry Rokosov wrote:
> The capacitance value is required for the usage of the cpufreq cooling
> device and power_allocator thermal governor in the appropriate energy
> model.
> 
> It helps to compute the power estimated by the SoC at the appropriate
> frequency. If it is the frequency of an existing OPP, or at the
> frequency of the first OPP above the requested value otherwise.
> 
> The power is estimated as P = C * V^2 * f, with C being the SoC's
> capacitance and V and f respectively representing the voltage and
> frequency of the OPP.
> 
> Since AXG SoC doesn't have SCMI protocol support, we need to initialize
> capacitance using the 'dynamic-power-coefficient' DT entry. Its value is
> retrieved from the vendor kernel, and it gives us the following
> freq2power mapping:
>      +-----------+--------+
>      | frequency,| power, |
>      |    MHz    |   uW   |
>      +-----------+--------+
>      |     100   |  10354 |
>      +-----------+--------+
>      |     250   |  27104 |
>      +-----------+--------+
>      |     500   |  55447 |
>      +-----------+--------+
>      |     667   |  77327 |
>      +-----------+--------+
>      |    1000   | 129024 |
>      +-----------+--------+
>      |    1200   | 164656 |
>      +-----------+--------+
>      |    1296   | 192489 |
>      +-----------+--------+
>      |    1416   | 239870 |
>      +-----------+--------+
> 
> Signed-off-by: Dmitry Rokosov <ddrokosov at salutedevices.com>
> ---
>   arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> index ea96fef328e8..6d12b760b90f 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> @@ -74,6 +74,7 @@ cpu0: cpu at 0 {
>   			enable-method = "psci";
>   			next-level-cache = <&l2>;
>   			clocks = <&scpi_dvfs 0>;
> +			dynamic-power-coefficient = <140>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -84,6 +85,7 @@ cpu1: cpu at 1 {
>   			enable-method = "psci";
>   			next-level-cache = <&l2>;
>   			clocks = <&scpi_dvfs 0>;
> +			dynamic-power-coefficient = <140>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -94,6 +96,7 @@ cpu2: cpu at 2 {
>   			enable-method = "psci";
>   			next-level-cache = <&l2>;
>   			clocks = <&scpi_dvfs 0>;
> +			dynamic-power-coefficient = <140>;
>   			#cooling-cells = <2>;
>   		};
>   
> @@ -104,6 +107,7 @@ cpu3: cpu at 3 {
>   			enable-method = "psci";
>   			next-level-cache = <&l2>;
>   			clocks = <&scpi_dvfs 0>;
> +			dynamic-power-coefficient = <140>;
>   			#cooling-cells = <2>;
>   		};
>   

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 12 07:02:59 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 16:02:59 +0100
Subject: [PATCH v1 1/2] arm64: dts: amlogic: axg: move cpu cooling-cells
 to common dtsi
In-Reply-To: <20240209212816.11187-2-ddrokosov@salutedevices.com>
References: <20240209212816.11187-1-ddrokosov@salutedevices.com>
 <20240209212816.11187-2-ddrokosov@salutedevices.com>
Message-ID: <ceb6a93d-39e0-4d12-b2bf-d27acab83a28@linaro.org>

On 09/02/2024 22:28, Dmitry Rokosov wrote:
> The CPU cooling-cells property should be located in the meson-axg common
> dtsi, as it is required for all AXG-based boards with DVFS.
> 
> Signed-off-by: Dmitry Rokosov <ddrokosov at salutedevices.com>
> ---
>   .../amlogic/meson-axg-jethome-jethub-j1xx.dtsi   | 16 ----------------
>   arch/arm64/boot/dts/amlogic/meson-axg.dtsi       |  4 ++++
>   2 files changed, 4 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
> index db605f3a22b4..55802fb03a46 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
> @@ -332,19 +332,3 @@ &gpio {
>   		"", "", "", "", "", // 80 - 84
>   		"", ""; // 85-86
>   };
> -
> -&cpu0 {
> -	#cooling-cells = <2>;
> -};
> -
> -&cpu1 {
> -	#cooling-cells = <2>;
> -};
> -
> -&cpu2 {
> -	#cooling-cells = <2>;
> -};
> -
> -&cpu3 {
> -	#cooling-cells = <2>;
> -};
> diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> index 7e5ac9db93f8..ea96fef328e8 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> @@ -74,6 +74,7 @@ cpu0: cpu at 0 {
>   			enable-method = "psci";
>   			next-level-cache = <&l2>;
>   			clocks = <&scpi_dvfs 0>;
> +			#cooling-cells = <2>;
>   		};
>   
>   		cpu1: cpu at 1 {
> @@ -83,6 +84,7 @@ cpu1: cpu at 1 {
>   			enable-method = "psci";
>   			next-level-cache = <&l2>;
>   			clocks = <&scpi_dvfs 0>;
> +			#cooling-cells = <2>;
>   		};
>   
>   		cpu2: cpu at 2 {
> @@ -92,6 +94,7 @@ cpu2: cpu at 2 {
>   			enable-method = "psci";
>   			next-level-cache = <&l2>;
>   			clocks = <&scpi_dvfs 0>;
> +			#cooling-cells = <2>;
>   		};
>   
>   		cpu3: cpu at 3 {
> @@ -101,6 +104,7 @@ cpu3: cpu at 3 {
>   			enable-method = "psci";
>   			next-level-cache = <&l2>;
>   			clocks = <&scpi_dvfs 0>;
> +			#cooling-cells = <2>;
>   		};
>   
>   		l2: l2-cache0 {

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 12 07:03:10 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 12 Feb 2024 16:03:10 +0100
Subject: [PATCH] arm64: dts: amlogic: t7: minor whitespace cleanup
In-Reply-To: <20240208105252.128940-1-krzysztof.kozlowski@linaro.org>
References: <20240208105252.128940-1-krzysztof.kozlowski@linaro.org>
Message-ID: <7aade7aa-68eb-4585-94c1-6bec11ff296d@linaro.org>

On 08/02/2024 11:52, Krzysztof Kozlowski wrote:
> The DTS code coding style expects exactly one space before '{'
> character.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>   arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index a03c7667d2b6..ad1cac42e9d8 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -54,7 +54,7 @@ cpu100: cpu at 100 {
>   			enable-method = "psci";
>   		};
>   
> -		cpu101: cpu at 101{
> +		cpu101: cpu at 101 {
>   			device_type = "cpu";
>   			compatible = "arm,cortex-a53";
>   			reg = <0x0 0x101>;

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From jstephan at baylibre.com  Mon Feb 12 07:07:03 2024
From: jstephan at baylibre.com (Julien Stephan)
Date: Mon, 12 Feb 2024 16:07:03 +0100
Subject: [PATCH v4 3/5] media: platform: mediatek: isp_30: add mediatek
 ISP3.0 sensor interface
In-Reply-To: <3c2bee40-3792-409c-b42f-f8b013ff641c@collabora.com>
References: <20240110141443.364655-1-jstephan@baylibre.com>
 <20240110141443.364655-4-jstephan@baylibre.com> <3c2bee40-3792-409c-b42f-f8b013ff641c@collabora.com>
Message-ID: <CAEHHSvaUSJTTQpUD0eX3dFw7rohRm6Z=_RO0Sknn9JxfH603UQ@mail.gmail.com>

Hi Angelo,

Thank you for your comments. Few questions below.

Cheers
Julien

Le jeu. 11 janv. 2024 ? 13:04, AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> a ?crit :
 .. snip ..
>
> > +             .code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8,
> > +             .flags = MTK_SENINF_FORMAT_JPEG,
> > +     },
> > +     /* Keep the input-only formats last. */
>
> Your comment doesn't make me understand why input-only formats shall be
> placed last - and makes me think that having two arrays (one for both
> and one for input only) would be easier and less error prone, other than
> making you able to drop the MTK_SENINF_FORMAT_INPUT_ONLY flag entirely.
>

Not sure I agree with you on this... If I want to split into two I
will have to duplicate
the whole mtk_seninf_formats[] which is quite big because the first 26
formats are
for both input and source pad. Moreover it will introduce some check on the pad
before choosing the correct format structure..  or maybe I am missing
your point?

> > +     {
> > +             .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
> > +             .flags = MTK_SENINF_FORMAT_DPCM | MTK_SENINF_FORMAT_INPUT_ONLY,
> > +     }, {
> > +             .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
> > +             .flags = MTK_SENINF_FORMAT_DPCM | MTK_SENINF_FORMAT_INPUT_ONLY,
> > +     }, {
> > +             .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
> > +             .flags = MTK_SENINF_FORMAT_DPCM | MTK_SENINF_FORMAT_INPUT_ONLY,
> > +     }, {
> > +             .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
> > +             .flags = MTK_SENINF_FORMAT_DPCM | MTK_SENINF_FORMAT_INPUT_ONLY,
> > +     }
> > +};
> > +
> > +static const struct mtk_seninf_format_info *mtk_seninf_format_info(u32 code)
> > +{
> > +     unsigned int i;
> > +
> > +     for (i = 0; i < ARRAY_SIZE(mtk_seninf_formats); ++i) {
> > +             if (mtk_seninf_formats[i].code == code)
> > +                     return &mtk_seninf_formats[i];
> > +     }
> > +
> > +     return NULL;
> > +}
> > +
>
> ..snip..
>
> > +
> > +static void mtk_seninf_input_setup_csi2(struct mtk_seninf_input *input,
> > +                                     struct v4l2_subdev_state *state)
> > +{
> > +     const struct mtk_seninf_format_info *fmtinfo;
> > +     const struct v4l2_mbus_framefmt *format;
> > +     unsigned int num_data_lanes = input->bus.num_data_lanes;
> > +     unsigned int val = 0;
> > +
> > +     format = v4l2_subdev_state_get_stream_format(state, input->pad, 0);
> > +     fmtinfo = mtk_seninf_format_info(format->code);
> > +
> > +     /* Configure timestamp */
> > +     writel(SENINF_TIMESTAMP_STEP, input->base + SENINF_TG1_TM_STP);
> > +
> > +     /* HQ */
> > +     writel(0x0, input->base + SENINF_TG1_PH_CNT);
>
> Zero means:
>   - Sensor master clock: ISP_CLK
>   - Sensor clock polarity: Rising edge
>   - Sensor reset deasserted
>   - Sensor powered up
>   - Pixel clock inversion disabled
>   - Sensor master clock polarity disabled
>   - Phase counter disabled
>
> > +     writel(0x10001, input->base + SENINF_TG1_SEN_CK);
>
> Unroll this one... this is the TG1 sensor clock divider.
>
> CLKFL GENMASK(5, 0)
> CLKRS GENMASK(13, 8)
> CLKCNT GENMASK(21,16)
>
> Like this, I don't get what you're trying to set, because you're using a fixed
> sensor clock rate, meaning that only a handful of camera sensors will be usable.
>
> Is this 8Mhz? 16? 24? what? :-)
>
> Two hints:
>   - sensor_clk = clk_get_rate(isp_clk) / (tg1_sen_ck_clkcnt + 1);
>   - int mtk_seninf_set_sensor_clk(u8 rate_mhz);
>
> Please :-)
>
> > +
> > +     /* First Enable Sensor interface and select pad (0x1a04_0200) */
> > +     mtk_seninf_input_update(input, SENINF_CTRL, SENINF_EN, 1);
> > +     mtk_seninf_input_update(input, SENINF_CTRL, PAD2CAM_DATA_SEL, SENINF_PAD_10BIT);
> > +     mtk_seninf_input_update(input, SENINF_CTRL, SENINF_SRC_SEL, 0);
> > +     mtk_seninf_input_update(input, SENINF_CTRL_EXT, SENINF_CSI2_IP_EN, 1);
> > +     mtk_seninf_input_update(input, SENINF_CTRL_EXT, SENINF_NCSI2_IP_EN, 0);
> > +
> > +     /* DPCM Enable */
> > +     if (fmtinfo->flags & MTK_SENINF_FORMAT_DPCM)
> > +             val = SENINF_CSI2_DPCM_DI_2A_DPCM_EN;
> > +     else
> > +             val = SENINF_CSI2_DPCM_DI_30_DPCM_EN;
> > +     writel(val, input->base + SENINF_CSI2_DPCM);
> > +
> > +     /* Settle delay */
> > +     mtk_seninf_input_update(input, SENINF_CSI2_LNRD_TIMING,
> > +                             DATA_SETTLE_PARAMETER, SENINF_SETTLE_DELAY);
> > +
> > +     /* HQ */
> > +     writel(0x10, input->base + SENINF_CSI2_LNRC_FSM);
>
> As far as I know, SENINF_CSI2_LNRC_FSM is a read-only register: this write will do
> exactly nothing...
>
> > +
> > +     /* CSI2 control */
> > +     val = readl(input->base + SENINF_CSI2_CTL)
> > +         | (FIELD_PREP(SENINF_CSI2_CTL_ED_SEL, DATA_HEADER_ORDER_DI_WCL_WCH)
> > +         | SENINF_CSI2_CTL_CLOCK_LANE_EN | (BIT(num_data_lanes) - 1));
> > +     writel(val, input->base + SENINF_CSI2_CTL);
> > +
> > +     mtk_seninf_input_update(input, SENINF_CSI2_RESYNC_MERGE_CTL,
> > +                             BYPASS_LANE_RESYNC, 0);
>
> 93 columns: fits in one line (not only this one!).
>
> > +     mtk_seninf_input_update(input, SENINF_CSI2_RESYNC_MERGE_CTL, CDPHY_SEL, 0);
> > +     mtk_seninf_input_update(input, SENINF_CSI2_RESYNC_MERGE_CTL,
> > +                             CPHY_LANE_RESYNC_CNT, 3);
> > +     mtk_seninf_input_update(input, SENINF_CSI2_MODE, CSR_CSI2_MODE, 0);
> > +     mtk_seninf_input_update(input, SENINF_CSI2_MODE, CSR_CSI2_HEADER_LEN, 0);
> > +     mtk_seninf_input_update(input, SENINF_CSI2_DPHY_SYNC, SYNC_SEQ_MASK_0, 0xff00);
> > +     mtk_seninf_input_update(input, SENINF_CSI2_DPHY_SYNC, SYNC_SEQ_PAT_0, 0x001d);
> > +
> > +     mtk_seninf_input_update(input, SENINF_CSI2_CTL, CLOCK_HS_OPTION, 0);
> > +     mtk_seninf_input_update(input, SENINF_CSI2_CTL, HSRX_DET_EN, 0);
> > +     mtk_seninf_input_update(input, SENINF_CSI2_CTL, HS_TRAIL_EN, 1);
> > +     mtk_seninf_input_update(input, SENINF_CSI2_HS_TRAIL, HS_TRAIL_PARAMETER,
> > +                             SENINF_HS_TRAIL_PARAMETER);
> > +
> > +     /* Set debug port to output packet number */
> > +     mtk_seninf_input_update(input, SENINF_CSI2_DGB_SEL, DEBUG_EN, 1);
> > +     mtk_seninf_input_update(input, SENINF_CSI2_DGB_SEL, DEBUG_SEL, 0x1a);
> > +
> > +     /* HQ */
> > +     writel(0xfffffffe, input->base + SENINF_CSI2_SPARE0);
>
> I have no idea what this SPARE0 does, but I think that this is something that you
> want to get from platform_data, as I guess this would be different on various SoCs?
>
> > +
> > +     /* Enable CSI2 IRQ mask */
> > +     /* Turn on all interrupt */
> > +     writel(0xffffffff, input->base + SENINF_CSI2_INT_EN);
> > +     /* Write clear CSI2 IRQ */
> > +     writel(0xffffffff, input->base + SENINF_CSI2_INT_STATUS);
> > +     /* Enable CSI2 Extend IRQ mask */
>
> You missed:
>         writel(0xffffffff, input->base + SENINF_CSI2_INT_EN_EXT);
>
> P.S.: #define SENINF_CSI2_INT_EN_EXT 0x0b10
>
>
> > +     /* Turn on all interrupt */
>
> /* Reset the CSI2 to commit changes */ <-- makes more sense, doesn't it?
>
> > +     mtk_seninf_input_update(input, SENINF_CTRL, CSI2_SW_RST, 1);
> > +     udelay(1);
> > +     mtk_seninf_input_update(input, SENINF_CTRL, CSI2_SW_RST, 0);
> > +}
> > +
> > +static void mtk_seninf_mux_setup(struct mtk_seninf_mux *mux,
> > +                              struct mtk_seninf_input *input,
> > +                              struct v4l2_subdev_state *state)
> > +{
> > +     const struct mtk_seninf_format_info *fmtinfo;
> > +     const struct v4l2_mbus_framefmt *format;
> > +     unsigned int pix_sel_ext;
> > +     unsigned int pix_sel;
> > +     unsigned int hs_pol = 0;
> > +     unsigned int vs_pol = 0;
> > +     unsigned int val;
> > +     u32 rst_mask;
> > +
> > +     format = v4l2_subdev_state_get_stream_format(state, input->pad, 0);
> > +     fmtinfo = mtk_seninf_format_info(format->code);
> > +
> > +     /* Enable mux */
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_MUX_EN, 1);
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_SRC_SEL, SENINF_MIPI_SENSOR);
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL_EXT, SENINF_SRC_SEL_EXT, SENINF_NORMAL_MODEL);
> > +
> > +     pix_sel_ext = 0;
> > +     pix_sel = 1;
>
>
>         pixels_per_cycle = 1;
>         bus_width = pixels_per_cycle >> 1;
>
> because:  0 == 1pix/cyc, 1 == 2pix/cyc, 2 == 4pix/cyc, 3 == 8pix... etc
> ...but the width of this register depends on the SoC, so you also want to set
> constraints to the bus width on a per-soc basis (platform data again, or at
> least leave a comment here).>
>         mtk_seninf_mux_update(....  PIX_SEL_EXT, bus_width);
>         mtk_seninf_mux_update(....  PIX_SEL, bus_width);
>

Again, not sure to get your point here. PIX_SEL_EXT and PIX_SEL are 1 bit each
and according to the datasheet 1pix/cycle is 0 in PIX_SEL_EXT and 0 in PIX_SEL,
2 pix/cycles is 0 in PIX_SEL_EXT and 1 in PIX_SEL
and 4 pix/cycle is 1 in PIX_SEL_EXT and 0 in PIX_SEL


> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL_EXT, SENINF_PIX_SEL_EXT, pix_sel_ext);
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_PIX_SEL, pix_sel);
> > +
> > +     if (fmtinfo->flags & MTK_SENINF_FORMAT_JPEG) {
> > +             mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FULL_WR_EN, 0);
> > +             mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FLUSH_EN,
> > +                                   FIFO_FLUSH_EN_JPEG_2_PIXEL_MODE);
> > +             mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_PUSH_EN,
> > +                             FIFO_PUSH_EN_JPEG_2_PIXEL_MODE);
> > +     } else {
> > +             mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FULL_WR_EN, 2);
> > +             mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FLUSH_EN,
> > +                                  FIFO_FLUSH_EN_NORMAL_MODE);
> > +             mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_PUSH_EN,
> > +                             FIFO_PUSH_EN_NORMAL_MODE);
> > +     }
> > +
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_HSYNC_POL, hs_pol);
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_VSYNC_POL, vs_pol);
> > +
> > +     val = mtk_seninf_mux_read(mux, SENINF_MUX_CTRL);
> > +     rst_mask = SENINF_MUX_CTRL_SENINF_IRQ_SW_RST | SENINF_MUX_CTRL_SENINF_MUX_SW_RST;
> > +
> > +     mtk_seninf_mux_write(mux, SENINF_MUX_CTRL, val | rst_mask);
>
> Are you sure that you don't need any wait between assertion and deassertion of RST?
> Looks strange, but I don't really know then.
>
> > +     mtk_seninf_mux_write(mux, SENINF_MUX_CTRL, val & ~rst_mask);
> > +
> > +     /* HQ */
> > +     mtk_seninf_mux_write(mux, SENINF_MUX_SPARE, 0xc2000);
>
> val = SENINF_FIFO_FULL_SEL;
>
> /* SPARE field meaning is unknown */
> val |= 0xc0000;
>
>         mtk_seninf_mux_write(mux, SENINF_MUX_SPARE, val);
>
> > +}
> > +
> > +static void mtk_seninf_top_mux_setup(struct mtk_seninf *priv,
> > +                                  enum mtk_seninf_id seninf_id,
> > +                                  struct mtk_seninf_mux *mux)
> > +{
> > +     unsigned int val;
> > +
> > +     /*
> > +      * Use the top mux (from SENINF input to MUX) to configure routing, and
> > +      * hardcode a 1:1 mapping from the MUX instances to the SENINF outputs.
> > +      */
> > +     val = readl(priv->base + SENINF_TOP_MUX_CTRL)
> > +             & ~(0xf << (mux->mux_id * 4));
> > +     val |= (seninf_id & 0xf) << (mux->mux_id * 4);
> > +     writel(val, priv->base + SENINF_TOP_MUX_CTRL);
> > +
> > +     writel(0x76541010, priv->base + SENINF_TOP_CAM_MUX_CTRL);
>
> Each four bits of TOP_CAM_MUX_CTRL selects between seninf1 to seninf8 muxes, and
> TOP_MUX_CTRL is laid out in the very same way.
>
> This means that if you're calculating a value for TOP_MUX_CTRL, you can do exactly
> the same for TOP_CAM_MUX_CTRL.
>
> > +}
> > +
> > +static void seninf_enable_test_pattern(struct mtk_seninf *priv,
> > +                                    struct v4l2_subdev_state *state)
> > +{
> > +     struct mtk_seninf_input *input = &priv->inputs[CSI_PORT_0];
> > +     struct mtk_seninf_mux *mux = &priv->muxes[0];
> > +     const struct mtk_seninf_format_info *fmtinfo;
> > +     const struct v4l2_mbus_framefmt *format;
> > +     unsigned int val;
> > +     unsigned int pix_sel_ext;
> > +     unsigned int pix_sel;
> > +     unsigned int hs_pol = 0;
> > +     unsigned int vs_pol = 0;
> > +     unsigned int seninf = 0;
> > +     unsigned int tm_size = 0;
> > +     unsigned int mux_id = mux->mux_id;
> > +
> > +     format = v4l2_subdev_state_get_stream_format(state, priv->conf->nb_inputs, 0);
> > +     fmtinfo = mtk_seninf_format_info(format->code);
> > +
> > +     mtk_seninf_update(priv, SENINF_TOP_CTRL, MUX_LP_MODE, 0);
> > +
> > +     mtk_seninf_update(priv, SENINF_TOP_CTRL, SENINF_PCLK_EN, 1);
> > +     mtk_seninf_update(priv, SENINF_TOP_CTRL, SENINF2_PCLK_EN, 1);
> > +
> > +     mtk_seninf_input_update(input, SENINF_CTRL, SENINF_EN, 1);
> > +     mtk_seninf_input_update(input, SENINF_CTRL, SENINF_SRC_SEL, 1);
> > +     mtk_seninf_input_update(input, SENINF_CTRL_EXT,
> > +                             SENINF_TESTMDL_IP_EN, 1);
> > +
> > +     mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_EN, 1);
> > +     mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_PAT, 0xc);
> > +     mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_VSYNC, 4);
> > +     mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_DUMMYPXL, 0x28);
> > +
> > +     if (fmtinfo->flags & MTK_SENINF_FORMAT_BAYER)
> > +             mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_FMT, 0x0);
> > +     else
> > +             mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_FMT, 0x1);
> > +
> > +     tm_size = FIELD_PREP(SENINF_TG1_TM_SIZE_TM_LINE, format->height + 8);
> > +     switch (format->code) {
> > +     case MEDIA_BUS_FMT_UYVY8_1X16:
> > +     case MEDIA_BUS_FMT_VYUY8_1X16:
> > +     case MEDIA_BUS_FMT_YUYV8_1X16:
> > +     case MEDIA_BUS_FMT_YVYU8_1X16:
> > +             tm_size |= FIELD_PREP(SENINF_TG1_TM_SIZE_TM_PXL, format->width * 2);
> > +             break;
> > +     default:
> > +             tm_size |= FIELD_PREP(SENINF_TG1_TM_SIZE_TM_PXL, format->width);
> > +             break;
> > +     }
> > +     writel(tm_size, input->base + SENINF_TG1_TM_SIZE);
> > +
> > +     writel(TEST_MODEL_CLK_DIVIDED_CNT, input->base + SENINF_TG1_TM_CLK);
> > +     writel(TIME_STAMP_DIVIDER, input->base + SENINF_TG1_TM_STP);
> > +
> > +     /* Set top mux */
> > +     val = (readl(priv->base + SENINF_TOP_MUX_CTRL) & (~(0xf << (mux_id * 4)))) |
> > +             ((seninf & 0xf) << (mux_id * 4));
> > +     writel(val, priv->base + SENINF_TOP_MUX_CTRL);
>
> This is duplicated, and it is the same that you have in mtk_seninf_top_mux_setup()
>
> > +
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_MUX_EN, 1);
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL_EXT,
> > +                           SENINF_SRC_SEL_EXT, SENINF_TEST_MODEL);
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_SRC_SEL, 1);
> > +
> > +     pix_sel_ext = 0;
> > +     pix_sel = 1;
> > +
>
> This is in mtk_seninf_mux_setup(), but if you apply my suggestion, it won't be in
> there anymore, so you'll call a function here to set the right value :-)
>
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL_EXT,
> > +                           SENINF_PIX_SEL_EXT, pix_sel_ext);
> > +
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_PIX_SEL, pix_sel);
> > +
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_PUSH_EN, 0x1f);
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FLUSH_EN, 0x1b);
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FULL_WR_EN, 2);
> > +
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_HSYNC_POL, hs_pol);
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_VSYNC_POL, vs_pol);
> > +     mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_HSYNC_MASK, 1);
> > +
> > +     mtk_seninf_mux_write(mux, SENINF_MUX_INTEN,
> > +                          SENINF_IRQ_CLR_SEL | SENINF_ALL_ERR_IRQ_EN);
> > +
> > +     mtk_seninf_mux_write(mux, SENINF_MUX_CTRL,
> > +                          mtk_seninf_mux_read(mux, SENINF_MUX_CTRL) |
> > +                          SENINF_MUX_CTRL_SENINF_IRQ_SW_RST |
> > +                          SENINF_MUX_CTRL_SENINF_MUX_SW_RST);
> > +     udelay(1);
> > +     mtk_seninf_mux_write(mux, SENINF_MUX_CTRL,
> > +                          mtk_seninf_mux_read(mux, SENINF_MUX_CTRL) &
> > +                          ~(SENINF_MUX_CTRL_SENINF_IRQ_SW_RST |
> > +                            SENINF_MUX_CTRL_SENINF_MUX_SW_RST));
> > +
> > +     //check this
> > +     writel(0x76540010, priv->base + SENINF_TOP_CAM_MUX_CTRL);
> > +
> > +     dev_dbg(priv->dev, "%s: OK\n", __func__);
> > +}
> > +
>
> Cheers,
> Angelo
>


From robh at kernel.org  Mon Feb 12 07:09:19 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 12 Feb 2024 09:09:19 -0600
Subject: [PATCH 1/5] dt-bindings: firmware: add i.MX SCMI Extension
 protocol
In-Reply-To: <20240202-imx95-bbm-misc-v1-1-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
 <20240202-imx95-bbm-misc-v1-1-3cb743020933@nxp.com>
Message-ID: <20240212150919.GA322668-robh@kernel.org>

On Fri, Feb 02, 2024 at 02:34:39PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add i.MX SCMI Extension protocol BBM and MISC binding.

No idea what BBM and MISC are.

> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  .../devicetree/bindings/firmware/nxp,scmi.yaml     | 64 ++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/firmware/nxp,scmi.yaml b/Documentation/devicetree/bindings/firmware/nxp,scmi.yaml
> new file mode 100644
> index 000000000000..00d6361bbbea
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/firmware/nxp,scmi.yaml
> @@ -0,0 +1,64 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2024 NXP
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/firmware/nxp,scmi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: i.MX System Control and Management Interface (SCMI) Protocol Extension
> +
> +maintainers:
> +  - Peng Fan <peng.fan at nxp.com>
> +
> +allOf:
> +  - $ref: arm,scmi.yaml#
> +
> +properties:
> +  protocol at 11:

Wrong unit-address?

> +    $ref: 'arm,scmi.yaml#/$defs/protocol-node'
> +    unevaluatedProperties: false

Description of what this protocol is needed.

> +
> +    properties:
> +      reg:
> +        const: 0x81
> +
> +  protocol at 13:
> +    $ref: 'arm,scmi.yaml#/$defs/protocol-node'
> +    unevaluatedProperties: false
> +
> +    properties:
> +      reg:
> +        const: 0x84
> +
> +      wakeup-sources:

Is this somehow generic?

> +        description: each entry consists of 2 integers and represents the source and edge

What does 'edge' mean in this context?

> +        items:
> +          items:
> +            - description: the wakeup source
> +            - description: the wakeup edge

Constraints?

> +        $ref: /schemas/types.yaml#/definitions/uint32-matrix
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    firmware {
> +        scmi {


Need a compatible here so this actually gets tested.

> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            protocol at 81 {
> +              reg = <0x81>;
> +            };
> +
> +            protocol at 84 {
> +              reg = <0x84>;
> +              wakeup-sources = <6 1
> +                                7 1
> +                                8 1
> +                                9 1
> +                                10 1>;

<> around each entry. e.g. "<6 1>"

> +            };
> +         };
> +    };
> +...
> 
> -- 
> 2.37.1
> 


From kuba at kernel.org  Mon Feb 12 07:12:16 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 12 Feb 2024 07:12:16 -0800
Subject: [PATCH net-next] net: stmmac: Simplify mtl IRQ status checking
In-Reply-To: <87il2t98ri.fsf@kurt.kurt.home>
References: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>
	<87il2t98ri.fsf@kurt.kurt.home>
Message-ID: <20240212071216.21e36c5c@kernel.org>

On Mon, 12 Feb 2024 13:17:37 +0100 Kurt Kanzenbach wrote:
> On Thu Feb 08 2024, Kurt Kanzenbach wrote:
> > Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO overflow
> > interrupts") disabled the RX FIFO overflow interrupts. However, it left the
> > status variable around, but never checks it.
> >
> > As stmmac_host_mtl_irq_status() returns only 0 now, the code can be
> > simplified.
> >
> > Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>  
> 
> why did this got marked as Changes Requested. What changes have to be
> made?

Sorry, restored!


From michal.vokac at ysoft.com  Mon Feb 12 07:23:41 2024
From: michal.vokac at ysoft.com (=?UTF-8?q?Michal=20Vok=C3=A1=C4=8D?=)
Date: Mon, 12 Feb 2024 16:23:41 +0100
Subject: [PATCH 1/2] ARM: dts: imx6dl-yapp4: Fix the QCA switch register address
Message-ID: <1707751422-31517-1-git-send-email-michal.vokac@ysoft.com>

The switch address in the node name is in hex while the address in the reg
property is decimal which is wrong. Fix that and write the reg address
as a hexadecimal number.

Fixes: 15b43e497ffd ("ARM: dts: imx6dl-yapp4: Use correct pseudo PHY address for the switch")
Signed-off-by: Michal Vok?? <michal.vokac at ysoft.com>
---
 arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
index cfb0fc924b42..5763f8253d51 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
@@ -143,7 +143,7 @@
 
 		switch at 10 {
 			compatible = "qca,qca8334";
-			reg = <10>;
+			reg = <0x10>;
 			reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
 
 			switch_ports: ports {
-- 
2.1.4



From michal.vokac at ysoft.com  Mon Feb 12 07:23:42 2024
From: michal.vokac at ysoft.com (=?UTF-8?q?Michal=20Vok=C3=A1=C4=8D?=)
Date: Mon, 12 Feb 2024 16:23:42 +0100
Subject: [PATCH 2/2] ARM: dts: imx6dl-yapp4: Move the internal switch PHYs under the switch node
In-Reply-To: <1707751422-31517-1-git-send-email-michal.vokac@ysoft.com>
References: <1707751422-31517-1-git-send-email-michal.vokac@ysoft.com>
Message-ID: <1707751422-31517-2-git-send-email-michal.vokac@ysoft.com>

We identified that the PHYs actually do not work since commit 7da7b84fee58
("ARM: dts: imx6dl-yapp4: Move phy reset into switch node") as
a coincidence of several circumstances.

The reset signal is kept asserted by a pull-down resistor on the board
unless it is deasserted by GPIO from the SoC. This is to keep the switch
dead until it is configured properly by the kernel and user space.

Prior to the referenced commit the switch was reset by the FEC driver
and the reset GPIO was actively deasserted. The mdio-bus was scanned
and the attached switch and its PHYs were found and configured.

With the referenced commit the switch is reset by the qca8k driver.
Because of another bug in the qca8k driver, functionality of the reset
pin depends on its pre-kernel configuration. See commit c44fc98f0a8f
("net: dsa: qca8k: fix illegal usage of GPIO")

The problem did not appear until we removed support for the switch
and configuration of its reset pin from the bootloader.

To fix that, properly describe the internal mdio-bus configuration of
the qca8334 switch. The PHYs are internal to the switch and sit on its
internal mdio-bus.

Fixes: 7da7b84fee58 ("ARM: dts: imx6dl-yapp4: Move phy reset into switch node")
Signed-off-by: Michal Vok?? <michal.vokac at ysoft.com>
---
 arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi | 23 ++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
index 5763f8253d51..eec1f9092572 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
@@ -133,14 +133,6 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		phy_port2: phy at 1 {
-			reg = <1>;
-		};
-
-		phy_port3: phy at 2 {
-			reg = <2>;
-		};
-
 		switch at 10 {
 			compatible = "qca,qca8334";
 			reg = <0x10>;
@@ -165,15 +157,30 @@
 				eth2: port at 2 {
 					reg = <2>;
 					label = "eth2";
+					phy-mode = "internal";
 					phy-handle = <&phy_port2>;
 				};
 
 				eth1: port at 3 {
 					reg = <3>;
 					label = "eth1";
+					phy-mode = "internal";
 					phy-handle = <&phy_port3>;
 				};
 			};
+
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				phy_port2: ethernet-phy at 1 {
+					reg = <1>;
+				};
+
+				phy_port3: ethernet-phy at 2 {
+					reg = <2>;
+				};
+			};
 		};
 	};
 };
-- 
2.1.4



From geert at linux-m68k.org  Mon Feb 12 07:24:46 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 12 Feb 2024 16:24:46 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop redundant
 GPIO node
In-Reply-To: <20240212143957.gaxxz3nt7pxhlmqh@runtux.com>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org> <20240212115837.efz73yxinkysdmgh@runtux.com>
 <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org> <20240212143957.gaxxz3nt7pxhlmqh@runtux.com>
Message-ID: <CAMuHMdVzQb=0ZkPMWjcXzYrUjPGm_KzbtgfPN7icZzi3whPbiA@mail.gmail.com>

Hi Ralf,

On Mon, Feb 12, 2024 at 3:40?PM Ralf Schlatterbeck <rsc at runtux.com> wrote:
> On Mon, Feb 12, 2024 at 02:38:27PM +0100, Krzysztof Kozlowski wrote:
> > On 12/02/2024 12:58, Ralf Schlatterbeck wrote:
> > GPIO expanders and their usage is nothing specific to this device -
> > other devices also might benefit of them. Or the SoCs which have enough
> > of GPIOs... I really do not understand why do we need expander here and
> > how does it help
>
> Can we then at least link the I/O Expander example to the docs of that
> display?
> I've documented my experience here:
> https://blog.runtux.com/posts/2021/01/06/

Any chance you can update the DT overlays to use sugar syntax instead
of raw fragments, target{,-path} properties, and __overlay__ subnodes?

You can find examples in my DT overlay collection, e.g.
https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/commit/?h=topic/renesas-overlays&id=3a41e34a2dd902c7bf74d11254a56190787252b6

> And at the time there were two out-of-tree implementations.

Only two? ;-)

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 david at redhat.com  Mon Feb 12 07:26:13 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 16:26:13 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <502a3ea7-fd86-4314-8292-c7999eda92eb@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <a91cfe1c-289e-4828-8cfc-be34eb69a71b@redhat.com>
 <502a3ea7-fd86-4314-8292-c7999eda92eb@arm.com>
Message-ID: <427ba87a-7dd0-4f3e-861f-fe6946b7cd97@redhat.com>

On 12.02.24 15:45, Ryan Roberts wrote:
> On 12/02/2024 13:54, David Hildenbrand wrote:
>>>> If so, I wonder if we could instead do that comparison modulo the access/dirty
>>>> bits,
>>>
>>> I think that would work - but will need to think a bit more on it.
>>>
>>>> and leave ptep_get_lockless() only reading a single entry?
>>>
>>> I think we will need to do something a bit less fragile. ptep_get() does collect
>>> the access/dirty bits so its confusing if ptep_get_lockless() doesn't IMHO. So
>>> we will likely want to rename the function and make its documentation explicit
>>> that it does not return those bits.
>>>
>>> ptep_get_lockless_noyoungdirty()? yuk... Any ideas?
>>>
>>> Of course if I could convince you the current implementation is safe, I might be
>>> able to sidestep this optimization until a later date?
>>
>> As discussed (and pointed out abive), there might be quite some callsites where
>> we don't really care about uptodate accessed/dirty bits -- where ptep_get() is
>> used nowadays.
>>
>> One way to approach that I had in mind was having an explicit interface:
>>
>> ptep_get()
>> ptep_get_uptodate()
>> ptep_get_lockless()
>> ptep_get_lockless_uptodate()
> 
> Yes, I like the direction of this. I guess we anticipate that call sites
> requiring the "_uptodate" variant will be the minority so it makes sense to use
> the current names for the "_not_uptodate" variants? But to do a slow migration,
> it might be better/safer to have the weaker variant use the new name - that
> would allow us to downgrade one at a time?

Yes, I was primarily struggling with names. Likely it makes sense to 
either have two completely new function names, or use the new name only 
for the "faster but less precise" variant.

> 
>>
>> Especially the last one might not be needed.
> I've done a scan through the code and agree with Mark's original conclusions.
> Additionally, huge_pte_alloc() (which isn't used for arm64) doesn't rely on
> access/dirty info. So I think I could migrate everything to the weaker variant
> fairly easily.
> 
>>
>> Futher, "uptodate" might not be the best choice because of PageUptodate() and
>> friends. But it's better than "youngdirty"/"noyoungdirty" IMHO.
> 
> Certainly agree with "noyoungdirty" being a horrible name. How about "_sync" /
> "_nosync"?

I could live with

ptep_get_sync()
ptep_get_nosync()

with proper documentation :)

I don't think we use "_sync" / "_nosync" in the context of pte 
operations yet.

Well, there seems to be "__arm_v7s_pte_sync" in iommu code, bit at least 
in core code nothing jumped at me.

-- 
Cheers,

David / dhildenb



From ryan.roberts at arm.com  Mon Feb 12 07:30:47 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 15:30:47 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
Message-ID: <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>

On 12/02/2024 12:59, Ryan Roberts wrote:
> On 12/02/2024 12:00, Mark Rutland wrote:
>> Hi Ryan,
>>
>> Overall this looks pretty good; I have a bunch of minor comments below, and a
>> bigger question on the way ptep_get_lockless() works.
> 
> OK great - thanks for the review. Let's see if I can answer them all...
> 
>>
>> On Fri, Feb 02, 2024 at 08:07:50AM +0000, Ryan Roberts wrote:
>>> With the ptep API sufficiently refactored, we can now introduce a new
>>> "contpte" API layer, which transparently manages the PTE_CONT bit for
>>> user mappings.
>>>
>>> In this initial implementation, only suitable batches of PTEs, set via
>>> set_ptes(), are mapped with the PTE_CONT bit. Any subsequent
>>> modification of individual PTEs will cause an "unfold" operation to
>>> repaint the contpte block as individual PTEs before performing the
>>> requested operation. While, a modification of a single PTE could cause
>>> the block of PTEs to which it belongs to become eligible for "folding"
>>> into a contpte entry, "folding" is not performed in this initial
>>> implementation due to the costs of checking the requirements are met.
>>> Due to this, contpte mappings will degrade back to normal pte mappings
>>> over time if/when protections are changed. This will be solved in a
>>> future patch.
>>>
>>> Since a contpte block only has a single access and dirty bit, the
>>> semantic here changes slightly; when getting a pte (e.g. ptep_get())
>>> that is part of a contpte mapping, the access and dirty information are
>>> pulled from the block (so all ptes in the block return the same
>>> access/dirty info). When changing the access/dirty info on a pte (e.g.
>>> ptep_set_access_flags()) that is part of a contpte mapping, this change
>>> will affect the whole contpte block. This is works fine in practice
>>> since we guarantee that only a single folio is mapped by a contpte
>>> block, and the core-mm tracks access/dirty information per folio.
>>>
>>> In order for the public functions, which used to be pure inline, to
>>> continue to be callable by modules, export all the contpte_* symbols
>>> that are now called by those public inline functions.
>>>
>>> The feature is enabled/disabled with the ARM64_CONTPTE Kconfig parameter
>>> at build time. It defaults to enabled as long as its dependency,
>>> TRANSPARENT_HUGEPAGE is also enabled. The core-mm depends upon
>>> TRANSPARENT_HUGEPAGE to be able to allocate large folios, so if its not
>>> enabled, then there is no chance of meeting the physical contiguity
>>> requirement for contpte mappings.
>>>
>>> Tested-by: John Hubbard <jhubbard at nvidia.com>
>>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>>> ---
>>>  arch/arm64/Kconfig               |   9 +
>>>  arch/arm64/include/asm/pgtable.h | 161 ++++++++++++++++++
>>>  arch/arm64/mm/Makefile           |   1 +
>>>  arch/arm64/mm/contpte.c          | 283 +++++++++++++++++++++++++++++++
>>>  4 files changed, 454 insertions(+)
>>>  create mode 100644 arch/arm64/mm/contpte.c
>>>
>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>> index d86d7f4758b5..1442e8ed95b6 100644
>>> --- a/arch/arm64/Kconfig
>>> +++ b/arch/arm64/Kconfig
>>> @@ -2230,6 +2230,15 @@ config UNWIND_PATCH_PAC_INTO_SCS
>>>  	select UNWIND_TABLES
>>>  	select DYNAMIC_SCS
>>>  
>>> +config ARM64_CONTPTE
>>> +	bool "Contiguous PTE mappings for user memory" if EXPERT
>>> +	depends on TRANSPARENT_HUGEPAGE
>>> +	default y
>>> +	help
>>> +	  When enabled, user mappings are configured using the PTE contiguous
>>> +	  bit, for any mappings that meet the size and alignment requirements.
>>> +	  This reduces TLB pressure and improves performance.
>>> +
>>>  endmenu # "Kernel Features"
>>>  
>>>  menu "Boot options"
>>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>>> index 7dc6b68ee516..34892a95403d 100644
>>> --- a/arch/arm64/include/asm/pgtable.h
>>> +++ b/arch/arm64/include/asm/pgtable.h
>>> @@ -133,6 +133,10 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>>>   */
>>>  #define pte_valid_not_user(pte) \
>>>  	((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN))
>>> +/*
>>> + * Returns true if the pte is valid and has the contiguous bit set.
>>> + */
>>> +#define pte_valid_cont(pte)	(pte_valid(pte) && pte_cont(pte))
>>>  /*
>>>   * Could the pte be present in the TLB? We must check mm_tlb_flush_pending
>>>   * so that we don't erroneously return false for pages that have been
>>> @@ -1135,6 +1139,161 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
>>>  #define vmemmap_update_pte vmemmap_update_pte
>>>  #endif
>>>  
>>> +#ifdef CONFIG_ARM64_CONTPTE
>>> +
>>> +/*
>>> + * The contpte APIs are used to transparently manage the contiguous bit in ptes
>>> + * where it is possible and makes sense to do so. The PTE_CONT bit is considered
>>> + * a private implementation detail of the public ptep API (see below).
>>> + */
>>> +extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>>> +				pte_t *ptep, pte_t pte);
>>> +extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
>>> +extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
>>> +extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
>>> +				pte_t *ptep, pte_t pte, unsigned int nr);
>>> +extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>>> +				unsigned long addr, pte_t *ptep);
>>> +extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>>> +				unsigned long addr, pte_t *ptep);
>>> +extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>>> +				unsigned long addr, pte_t *ptep,
>>> +				pte_t entry, int dirty);
>>> +
>>> +static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>>> +					pte_t *ptep, pte_t pte)
>>> +{
>>> +	if (unlikely(pte_valid_cont(pte)))
>>> +		__contpte_try_unfold(mm, addr, ptep, pte);
>>> +}
>>> +
>>> +/*
>>> + * The below functions constitute the public API that arm64 presents to the
>>> + * core-mm to manipulate PTE entries within their page tables (or at least this
>>> + * is the subset of the API that arm64 needs to implement). These public
>>> + * versions will automatically and transparently apply the contiguous bit where
>>> + * it makes sense to do so. Therefore any users that are contig-aware (e.g.
>>> + * hugetlb, kernel mapper) should NOT use these APIs, but instead use the
>>> + * private versions, which are prefixed with double underscore. All of these
>>> + * APIs except for ptep_get_lockless() are expected to be called with the PTL
>>> + * held.
>>> + */
>>> +
>>> +#define ptep_get ptep_get
>>> +static inline pte_t ptep_get(pte_t *ptep)
>>> +{
>>> +	pte_t pte = __ptep_get(ptep);
>>> +
>>> +	if (likely(!pte_valid_cont(pte)))
>>> +		return pte;
>>> +
>>> +	return contpte_ptep_get(ptep, pte);
>>> +}
>>> +
>>> +#define ptep_get_lockless ptep_get_lockless
>>> +static inline pte_t ptep_get_lockless(pte_t *ptep)
>>> +{
>>> +	pte_t pte = __ptep_get(ptep);
>>> +
>>> +	if (likely(!pte_valid_cont(pte)))
>>> +		return pte;
>>> +
>>> +	return contpte_ptep_get_lockless(ptep);
>>> +}
>>> +
>>> +static inline void set_pte(pte_t *ptep, pte_t pte)
>>> +{
>>> +	/*
>>> +	 * We don't have the mm or vaddr so cannot unfold contig entries (since
>>> +	 * it requires tlb maintenance). set_pte() is not used in core code, so
>>> +	 * this should never even be called. Regardless do our best to service
>>> +	 * any call and emit a warning if there is any attempt to set a pte on
>>> +	 * top of an existing contig range.
>>> +	 */
>>> +	pte_t orig_pte = __ptep_get(ptep);
>>> +
>>> +	WARN_ON_ONCE(pte_valid_cont(orig_pte));
>>> +	__set_pte(ptep, pte_mknoncont(pte));
>>> +}
>>> +
>>> +#define set_ptes set_ptes
>>> +static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
>>> +				pte_t *ptep, pte_t pte, unsigned int nr)
>>> +{
>>> +	pte = pte_mknoncont(pte);
>>
>> Why do we have to clear the contiguous bit here? Is that for the same reason as
>> set_pte(), or do we expect callers to legitimately call this with the
>> contiguous bit set in 'pte'?
>>
>> I think you explained this to me in-person, and IIRC we don't expect callers to
>> go set the bit themselves, but since it 'leaks' out to them via __ptep_get() we
>> have to clear it here to defer the decision of whether to set/clear it when
>> modifying entries. It would be nice if we could have a description of why/when
>> we need to clear this, e.g. in the 'public API' comment block above.
> 
> Yes, I think you've got it, but just to ram home the point: The PTE_CONT bit is
> private to the architecture code and is never set directly by core code. If the
> public API ever receives a pte that happens to have the PTE_CONT bit set, it
> would be bad news if we then accidentally set that in the pgtable.
> 
> Ideally, we would just uncondidtionally clear the bit before a getter returns
> the pte (e.g. ptep_get(), ptep_get_lockless(), ptep_get_and_clear(), ...). That
> way, the code code is guarranteed never to see a pte with the PTE_CONT bit set
> and can therefore never accidentally pass such a pte into a setter function.
> However, there is existing functionality that relies on being able to get a pte,
> then pass it to pte_leaf_size(), and arch function that checks the PTE_CONT bit
> to determine how big the leaf is. This is used in perf_get_pgtable_size().
> 
> So to allow perf_get_pgtable_size() to continue to see the "real" page size, I
> decided to allow PTE_CONT to leak through the getters and instead
> unconditionally clear the bit when a pte is passed to any of the setters.
> 
> I'll add a (slightly less verbose) comment as you suggest.
> 
>>
>>> +
>>> +	if (likely(nr == 1)) {
>>> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>>> +		__set_ptes(mm, addr, ptep, pte, 1);
>>> +	} else {
>>> +		contpte_set_ptes(mm, addr, ptep, pte, nr);
>>> +	}
>>> +}
>>> +
>>> +static inline void pte_clear(struct mm_struct *mm,
>>> +				unsigned long addr, pte_t *ptep)
>>> +{
>>> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>>> +	__pte_clear(mm, addr, ptep);
>>> +}
>>> +
>>> +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
>>> +static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
>>> +				unsigned long addr, pte_t *ptep)
>>> +{
>>> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>>> +	return __ptep_get_and_clear(mm, addr, ptep);
>>> +}
>>> +
>>> +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
>>> +static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
>>> +				unsigned long addr, pte_t *ptep)
>>> +{
>>> +	pte_t orig_pte = __ptep_get(ptep);
>>> +
>>> +	if (likely(!pte_valid_cont(orig_pte)))
>>> +		return __ptep_test_and_clear_young(vma, addr, ptep);
>>> +
>>> +	return contpte_ptep_test_and_clear_young(vma, addr, ptep);
>>> +}
>>> +
>>> +#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
>>> +static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
>>> +				unsigned long addr, pte_t *ptep)
>>> +{
>>> +	pte_t orig_pte = __ptep_get(ptep);
>>> +
>>> +	if (likely(!pte_valid_cont(orig_pte)))
>>> +		return __ptep_clear_flush_young(vma, addr, ptep);
>>> +
>>> +	return contpte_ptep_clear_flush_young(vma, addr, ptep);
>>> +}
>>> +
>>> +#define __HAVE_ARCH_PTEP_SET_WRPROTECT
>>> +static inline void ptep_set_wrprotect(struct mm_struct *mm,
>>> +				unsigned long addr, pte_t *ptep)
>>> +{
>>> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>>> +	__ptep_set_wrprotect(mm, addr, ptep);
>>> +}
>>> +
>>> +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
>>> +static inline int ptep_set_access_flags(struct vm_area_struct *vma,
>>> +				unsigned long addr, pte_t *ptep,
>>> +				pte_t entry, int dirty)
>>> +{
>>> +	pte_t orig_pte = __ptep_get(ptep);
>>> +
>>> +	entry = pte_mknoncont(entry);
>>> +
>>> +	if (likely(!pte_valid_cont(orig_pte)))
>>> +		return __ptep_set_access_flags(vma, addr, ptep, entry, dirty);
>>> +
>>> +	return contpte_ptep_set_access_flags(vma, addr, ptep, entry, dirty);
>>> +}
>>> +
>>> +#else /* CONFIG_ARM64_CONTPTE */
>>> +
>>>  #define ptep_get				__ptep_get
>>>  #define set_pte					__set_pte
>>>  #define set_ptes				__set_ptes
>>> @@ -1150,6 +1309,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
>>>  #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
>>>  #define ptep_set_access_flags			__ptep_set_access_flags
>>>  
>>> +#endif /* CONFIG_ARM64_CONTPTE */
>>> +
>>>  #endif /* !__ASSEMBLY__ */
>>>  
>>>  #endif /* __ASM_PGTABLE_H */
>>> diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
>>> index dbd1bc95967d..60454256945b 100644
>>> --- a/arch/arm64/mm/Makefile
>>> +++ b/arch/arm64/mm/Makefile
>>> @@ -3,6 +3,7 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
>>>  				   cache.o copypage.o flush.o \
>>>  				   ioremap.o mmap.o pgd.o mmu.o \
>>>  				   context.o proc.o pageattr.o fixmap.o
>>> +obj-$(CONFIG_ARM64_CONTPTE)	+= contpte.o
>>>  obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
>>>  obj-$(CONFIG_PTDUMP_CORE)	+= ptdump.o
>>>  obj-$(CONFIG_PTDUMP_DEBUGFS)	+= ptdump_debugfs.o
>>> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
>>> new file mode 100644
>>> index 000000000000..bfb50e6b44c7
>>> --- /dev/null
>>> +++ b/arch/arm64/mm/contpte.c
>>> @@ -0,0 +1,283 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Copyright (C) 2023 ARM Ltd.
>>> + */
>>> +
>>> +#include <linux/mm.h>
>>> +#include <linux/export.h>
>>> +#include <asm/tlbflush.h>
>>> +
>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>> +{
>>> +	/*
>>> +	 * Don't attempt to apply the contig bit to kernel mappings, because
>>> +	 * dynamically adding/removing the contig bit can cause page faults.
>>> +	 * These racing faults are ok for user space, since they get serialized
>>> +	 * on the PTL. But kernel mappings can't tolerate faults.
>>> +	 */
>>> +	return mm != &init_mm;
>>> +}
>>
>> We also have the efi_mm as a non-user mm, though I don't think we manipulate
>> that while it is live, and I'm not sure if that needs any special handling.
> 
> Well we never need this function in the hot (order-0 folio) path, so I think I
> could add a check for efi_mm here with performance implication. It's probably
> safest to explicitly exclude it? What do you think?

Oops: This should have read "I think I could add a check for efi_mm here
*without* performance implication"

> 
>>
>>> +static inline pte_t *contpte_align_down(pte_t *ptep)
>>> +{
>>> +	return (pte_t *)(ALIGN_DOWN((unsigned long)ptep >> 3, CONT_PTES) << 3);
>>
>> I think this can be:
>>
>> static inline pte_t *contpte_align_down(pte_t *ptep)
>> {
>> 	return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
>> }
> 
> Yep - that's much less ugly - thanks!
> 
>>
>>> +
>>> +static void contpte_convert(struct mm_struct *mm, unsigned long addr,
>>> +			    pte_t *ptep, pte_t pte)
>>> +{
>>> +	struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0);
>>> +	unsigned long start_addr;
>>> +	pte_t *start_ptep;
>>> +	int i;
>>> +
>>> +	start_ptep = ptep = contpte_align_down(ptep);
>>> +	start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
>>> +	pte = pfn_pte(ALIGN_DOWN(pte_pfn(pte), CONT_PTES), pte_pgprot(pte));
>>> +
>>> +	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) {
>>> +		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
>>> +
>>> +		if (pte_dirty(ptent))
>>> +			pte = pte_mkdirty(pte);
>>> +
>>> +		if (pte_young(ptent))
>>> +			pte = pte_mkyoung(pte);
>>> +	}
>>
>> Not a big deal either way, but I wonder if it makes more sense to accumulate
>> the 'ptent' dirty/young values, then modify 'pte' once, i.e.
>>
>> 	bool dirty = false, young = false;
>>
>> 	for (...) {
>> 		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
>> 		dirty |= pte_dirty(ptent);
>> 		young |= pte_young(ptent);
>> 	}
>>
>> 	if (dirty)
>> 		pte_mkdirty(pte);
>> 	if (young)
>> 		pte_mkyoung(pte);
>>
>> I suspect that might generate slightly better code, but I'm also happy with the
>> current form if people thnk that's more legible (I have no strong feelings
>> either way).
> 
> I kept it this way, because its the same pattern used in arm64's hugetlbpage.c.
> We also had the same comment against David's batching patches recently, and he
> opted to stick with the former version:
> 
> https://lore.kernel.org/linux-mm/d83309fa-4daa-430f-ae52-4e72162bca9a at redhat.com/
> 
> So I'm inclined to leave it as is, since you're not insisting :)
> 
>>
>>> +
>>> +	__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
>>> +
>>> +	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
>>> +}
>>> +
>>> +void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>>> +			pte_t *ptep, pte_t pte)
>>> +{
>>> +	/*
>>> +	 * We have already checked that the ptes are contiguous in
>>> +	 * contpte_try_unfold(), so just check that the mm is user space.
>>> +	 */
>>> +
>>> +	if (!mm_is_user(mm))
>>> +		return;
>>
>> Nit: normally we don't put a line gap between a comment block and the
>> associated block of code.
> 
> ACK, I'll fix in next version.

Just to clarify this, I've got a few instances in this file where I have a
comment that applies to the function as a whole, and in those cases the comment
is the first thing in the body of the function, and there's a blank line between
the end of the comment and the first statement. This is intended to be one of
those comments, although since the function is pretty small, I can see how it
also could look like it applies to the immediately proceeding statements too.

What is the normal policy for such comments? I'd rather leave this alone since
it aligns with how all the others are done in the file. Or should I just remove
the blank line for all instances?


> 
>>
>>> +
>>> +	pte = pte_mknoncont(pte);
>>> +	contpte_convert(mm, addr, ptep, pte);
>>> +}
>>> +EXPORT_SYMBOL(__contpte_try_unfold);
>>> +
>>> +pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
>>> +{
>>> +	/*
>>> +	 * Gather access/dirty bits, which may be populated in any of the ptes
>>> +	 * of the contig range. We are guarranteed to be holding the PTL, so any
>>> +	 * contiguous range cannot be unfolded or otherwise modified under our
>>> +	 * feet.
>>> +	 */
>>
>> Nit: s/guarranteed/guaranteed/
> 
> ACK, I'll fix in next version.
> 
>>
>>> +
>>> +	pte_t pte;
>>> +	int i;
>>> +
>>> +	ptep = contpte_align_down(ptep);
>>> +
>>> +	for (i = 0; i < CONT_PTES; i++, ptep++) {
>>> +		pte = __ptep_get(ptep);
>>> +
>>> +		if (pte_dirty(pte))
>>> +			orig_pte = pte_mkdirty(orig_pte);
>>> +
>>> +		if (pte_young(pte))
>>> +			orig_pte = pte_mkyoung(orig_pte);
>>> +	}
>>> +
>>> +	return orig_pte;
>>> +}
>>> +EXPORT_SYMBOL(contpte_ptep_get);
>>> +
>>> +pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
>>> +{
>>> +	/*
>>> +	 * Gather access/dirty bits, which may be populated in any of the ptes
>>> +	 * of the contig range. We may not be holding the PTL, so any contiguous
>>> +	 * range may be unfolded/modified/refolded under our feet. Therefore we
>>> +	 * ensure we read a _consistent_ contpte range by checking that all ptes
>>> +	 * in the range are valid and have CONT_PTE set, that all pfns are
>>> +	 * contiguous and that all pgprots are the same (ignoring access/dirty).
>>> +	 * If we find a pte that is not consistent, then we must be racing with
>>> +	 * an update so start again. If the target pte does not have CONT_PTE
>>> +	 * set then that is considered consistent on its own because it is not
>>> +	 * part of a contpte range.
>>> +	 */
>>> +
>>> +	pgprot_t orig_prot;
>>> +	unsigned long pfn;
>>> +	pte_t orig_pte;
>>> +	pgprot_t prot;
>>> +	pte_t *ptep;
>>> +	pte_t pte;
>>> +	int i;
>>> +
>>> +retry:
>>> +	orig_pte = __ptep_get(orig_ptep);
>>> +
>>> +	if (!pte_valid_cont(orig_pte))
>>> +		return orig_pte;
>>> +
>>> +	orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
>>> +	ptep = contpte_align_down(orig_ptep);
>>> +	pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
>>> +
>>> +	for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
>>> +		pte = __ptep_get(ptep);
>>> +		prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
>>> +
>>> +		if (!pte_valid_cont(pte) ||
>>> +		   pte_pfn(pte) != pfn ||
>>> +		   pgprot_val(prot) != pgprot_val(orig_prot))
>>> +			goto retry;
>>> +
>>> +		if (pte_dirty(pte))
>>> +			orig_pte = pte_mkdirty(orig_pte);
>>> +
>>> +		if (pte_young(pte))
>>> +			orig_pte = pte_mkyoung(orig_pte);
>>> +	}
>>> +
>>> +	return orig_pte;
>>> +}
>>> +EXPORT_SYMBOL(contpte_ptep_get_lockless);
>>
>> I'm struggling to convince myself that this is safe in general, as it really
>> depends on how the caller will use this value. Which caller(s) actually care
>> about the access/dirty bits, given those could change at any time anyway?
> 
> I think your points below are valid, and agree we should try to make this work
> without needing access/dirty if possible. But can you elaborate on why you don't
> think it's safe?
> 
>>
>> I took a quick scan, and AFAICT:
> 
> Thanks for enumerating these; Saves me from having to refresh my memory :)
> 
>>
>> * For perf_get_pgtable_size(), we only care about whether the entry is valid
>>   and has the contig bit set. We could clean that up with a new interface, e.g.
>>   something like a new ptep_get_size_lockless().
>>
>> * For gup_pte_range(), I'm not sure we actually need the access/dirty bits when
>>   we look at the pte to start with, since we only care where we can logically
>>   write to the page at that point.
>>
>>   I see that we later follow up with:
>>
>>     with pte_val(pte) != pte_val(ptep_get(ptep)))
>>
>>   ... is that why we need ptep_get_lockless() to accumulate the access/dirty
>>   bits? So that shape of lockless-try...locked-compare sequence works?
>>
>> * For huge_pte_alloc(), arm64 doesn't select CONFIG_ARCH_WANT_GENERAL_HUGETLB,
>>   so this doesn' seem to matter.
>>
>> * For __collapse_huge_page_swapin(), we only care if the pte is a swap pte,
>>   which means the pte isn't valid, and we'll return the orig_pte as-is anyway.
>>
>> * For pte_range_none() the access/dirty bits don't matter.
>>
>> * For handle_pte_fault() I think we have the same shape of
>>   lockless-try...locked-compare sequence as for gup_pte_range(), where we don't
>>   care about the acess/dirty bits before we reach the locked compare step.
>>
>> * For ptdump_pte_entry() I think it's arguable that we should continue to
>>   report the access/dirty bits separately for each PTE, as we have done until
>>   now, to give an accurate representation of the contents of the translation
>>   tables.
>>
>> * For swap_vma_readahead() and unuse_pte_range() we only care if the PTE is a
>>   swap entry, the access/dirty bits don't matter.
>>
>> So AFAICT this only really matters for gup_pte_range() and handle_pte_fault(),
>> and IIUC that's only so that the locklessly-loaded pte value can be compared
>> with a subsequently locked-loaded entry (for which the access/dirty bits will
>> be accumulated). Have I understood that correctly?
> 
> Yes, I agree with what you are saying. My approach was to try to implement the
> existing APIs accurately though, the argument being that it reduces the chances
> of getting it wrong. But if you think the implementation is unsafe, then I guess
> it blows that out of the water...
> 
>>
>> If so, I wonder if we could instead do that comparison modulo the access/dirty
>> bits, 
> 
> I think that would work - but will need to think a bit more on it.
> 
>> and leave ptep_get_lockless() only reading a single entry?
> 
> I think we will need to do something a bit less fragile. ptep_get() does collect
> the access/dirty bits so its confusing if ptep_get_lockless() doesn't IMHO. So
> we will likely want to rename the function and make its documentation explicit
> that it does not return those bits.
> 
> ptep_get_lockless_noyoungdirty()? yuk... Any ideas?
> 
> Of course if I could convince you the current implementation is safe, I might be
> able to sidestep this optimization until a later date?
> 
> Thanks,
> Ryan
> 
> 
>>
>> Thanks,
>> Mark.
>>
>>> +void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
>>> +					pte_t *ptep, pte_t pte, unsigned int nr)
>>> +{
>>> +	unsigned long next;
>>> +	unsigned long end;
>>> +	unsigned long pfn;
>>> +	pgprot_t prot;
>>> +
>>> +	/*
>>> +	 * The set_ptes() spec guarantees that when nr > 1, the initial state of
>>> +	 * all ptes is not-present. Therefore we never need to unfold or
>>> +	 * otherwise invalidate a range before we set the new ptes.
>>> +	 * contpte_set_ptes() should never be called for nr < 2.
>>> +	 */
>>> +	VM_WARN_ON(nr == 1);
>>> +
>>> +	if (!mm_is_user(mm))
>>> +		return __set_ptes(mm, addr, ptep, pte, nr);
>>> +
>>> +	end = addr + (nr << PAGE_SHIFT);
>>> +	pfn = pte_pfn(pte);
>>> +	prot = pte_pgprot(pte);
>>> +
>>> +	do {
>>> +		next = pte_cont_addr_end(addr, end);
>>> +		nr = (next - addr) >> PAGE_SHIFT;
>>> +		pte = pfn_pte(pfn, prot);
>>> +
>>> +		if (((addr | next | (pfn << PAGE_SHIFT)) & ~CONT_PTE_MASK) == 0)
>>> +			pte = pte_mkcont(pte);
>>> +		else
>>> +			pte = pte_mknoncont(pte);
>>> +
>>> +		__set_ptes(mm, addr, ptep, pte, nr);
>>> +
>>> +		addr = next;
>>> +		ptep += nr;
>>> +		pfn += nr;
>>> +
>>> +	} while (addr != end);
>>> +}
>>> +EXPORT_SYMBOL(contpte_set_ptes);
>>> +
>>> +int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>>> +					unsigned long addr, pte_t *ptep)
>>> +{
>>> +	/*
>>> +	 * ptep_clear_flush_young() technically requires us to clear the access
>>> +	 * flag for a _single_ pte. However, the core-mm code actually tracks
>>> +	 * access/dirty per folio, not per page. And since we only create a
>>> +	 * contig range when the range is covered by a single folio, we can get
>>> +	 * away with clearing young for the whole contig range here, so we avoid
>>> +	 * having to unfold.
>>> +	 */
>>> +
>>> +	int young = 0;
>>> +	int i;
>>> +
>>> +	ptep = contpte_align_down(ptep);
>>> +	addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
>>> +
>>> +	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
>>> +		young |= __ptep_test_and_clear_young(vma, addr, ptep);
>>> +
>>> +	return young;
>>> +}
>>> +EXPORT_SYMBOL(contpte_ptep_test_and_clear_young);
>>> +
>>> +int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>>> +					unsigned long addr, pte_t *ptep)
>>> +{
>>> +	int young;
>>> +
>>> +	young = contpte_ptep_test_and_clear_young(vma, addr, ptep);
>>> +
>>> +	if (young) {
>>> +		/*
>>> +		 * See comment in __ptep_clear_flush_young(); same rationale for
>>> +		 * eliding the trailing DSB applies here.
>>> +		 */
>>> +		addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
>>> +		__flush_tlb_range_nosync(vma, addr, addr + CONT_PTE_SIZE,
>>> +					 PAGE_SIZE, true, 3);
>>> +	}
>>> +
>>> +	return young;
>>> +}
>>> +EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
>>> +
>>> +int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>>> +					unsigned long addr, pte_t *ptep,
>>> +					pte_t entry, int dirty)
>>> +{
>>> +	unsigned long start_addr;
>>> +	pte_t orig_pte;
>>> +	int i;
>>> +
>>> +	/*
>>> +	 * Gather the access/dirty bits for the contiguous range. If nothing has
>>> +	 * changed, its a noop.
>>> +	 */
>>> +	orig_pte = pte_mknoncont(ptep_get(ptep));
>>> +	if (pte_val(orig_pte) == pte_val(entry))
>>> +		return 0;
>>> +
>>> +	/*
>>> +	 * We can fix up access/dirty bits without having to unfold the contig
>>> +	 * range. But if the write bit is changing, we must unfold.
>>> +	 */
>>> +	if (pte_write(orig_pte) == pte_write(entry)) {
>>> +		/*
>>> +		 * For HW access management, we technically only need to update
>>> +		 * the flag on a single pte in the range. But for SW access
>>> +		 * management, we need to update all the ptes to prevent extra
>>> +		 * faults. Avoid per-page tlb flush in __ptep_set_access_flags()
>>> +		 * and instead flush the whole range at the end.
>>> +		 */
>>> +		ptep = contpte_align_down(ptep);
>>> +		start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
>>> +
>>> +		for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
>>> +			__ptep_set_access_flags(vma, addr, ptep, entry, 0);
>>> +
>>> +		if (dirty)
>>> +			__flush_tlb_range(vma, start_addr, addr,
>>> +							PAGE_SIZE, true, 3);
>>> +	} else {
>>> +		__contpte_try_unfold(vma->vm_mm, addr, ptep, orig_pte);
>>> +		__ptep_set_access_flags(vma, addr, ptep, entry, dirty);
>>> +	}
>>> +
>>> +	return 1;
>>> +}
>>> +EXPORT_SYMBOL(contpte_ptep_set_access_flags);
>>> -- 
>>> 2.25.1
>>>
> 



From ryan.roberts at arm.com  Mon Feb 12 07:34:43 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 15:34:43 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <427ba87a-7dd0-4f3e-861f-fe6946b7cd97@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <a91cfe1c-289e-4828-8cfc-be34eb69a71b@redhat.com>
 <502a3ea7-fd86-4314-8292-c7999eda92eb@arm.com>
 <427ba87a-7dd0-4f3e-861f-fe6946b7cd97@redhat.com>
Message-ID: <abe814c9-71f3-4d7d-bdc8-9dd930d6f0b2@arm.com>

On 12/02/2024 15:26, David Hildenbrand wrote:
> On 12.02.24 15:45, Ryan Roberts wrote:
>> On 12/02/2024 13:54, David Hildenbrand wrote:
>>>>> If so, I wonder if we could instead do that comparison modulo the access/dirty
>>>>> bits,
>>>>
>>>> I think that would work - but will need to think a bit more on it.
>>>>
>>>>> and leave ptep_get_lockless() only reading a single entry?
>>>>
>>>> I think we will need to do something a bit less fragile. ptep_get() does
>>>> collect
>>>> the access/dirty bits so its confusing if ptep_get_lockless() doesn't IMHO. So
>>>> we will likely want to rename the function and make its documentation explicit
>>>> that it does not return those bits.
>>>>
>>>> ptep_get_lockless_noyoungdirty()? yuk... Any ideas?
>>>>
>>>> Of course if I could convince you the current implementation is safe, I
>>>> might be
>>>> able to sidestep this optimization until a later date?
>>>
>>> As discussed (and pointed out abive), there might be quite some callsites where
>>> we don't really care about uptodate accessed/dirty bits -- where ptep_get() is
>>> used nowadays.
>>>
>>> One way to approach that I had in mind was having an explicit interface:
>>>
>>> ptep_get()
>>> ptep_get_uptodate()
>>> ptep_get_lockless()
>>> ptep_get_lockless_uptodate()
>>
>> Yes, I like the direction of this. I guess we anticipate that call sites
>> requiring the "_uptodate" variant will be the minority so it makes sense to use
>> the current names for the "_not_uptodate" variants? But to do a slow migration,
>> it might be better/safer to have the weaker variant use the new name - that
>> would allow us to downgrade one at a time?
> 
> Yes, I was primarily struggling with names. Likely it makes sense to either have
> two completely new function names, or use the new name only for the "faster but
> less precise" variant.
> 
>>
>>>
>>> Especially the last one might not be needed.
>> I've done a scan through the code and agree with Mark's original conclusions.
>> Additionally, huge_pte_alloc() (which isn't used for arm64) doesn't rely on
>> access/dirty info. So I think I could migrate everything to the weaker variant
>> fairly easily.
>>
>>>
>>> Futher, "uptodate" might not be the best choice because of PageUptodate() and
>>> friends. But it's better than "youngdirty"/"noyoungdirty" IMHO.
>>
>> Certainly agree with "noyoungdirty" being a horrible name. How about "_sync" /
>> "_nosync"?
> 
> I could live with
> 
> ptep_get_sync()
> ptep_get_nosync()
> 
> with proper documentation :)

but could you live with:

ptep_get()
ptep_get_nosync()
ptep_get_lockless_nosync()

?

So leave the "slower, more precise" version with the existing name.

> 
> I don't think we use "_sync" / "_nosync" in the context of pte operations yet.
> 
> Well, there seems to be "__arm_v7s_pte_sync" in iommu code, bit at least in core
> code nothing jumped at me.
> 



From robh at kernel.org  Mon Feb 12 07:36:00 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 12 Feb 2024 09:36:00 -0600
Subject: [PATCH v2 01/12] spi: dt-bindings: introduce FIFO depth
 properties
In-Reply-To: <20240212140331.915498-2-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
 <20240212140331.915498-2-tudor.ambarus@linaro.org>
Message-ID: <170775215967.605422.1424850912641172864.robh@kernel.org>


On Mon, 12 Feb 2024 14:03:20 +0000, Tudor Ambarus wrote:
> There are SPI IPs that can be configured by the integrator with a
> specific FIFO depth depending on the system's capabilities. For example,
> the samsung USI SPI IP can be configured by the integrator with a TX/RX
> FIFO from 8 byte to 256 bytes.
> 
> Introduce the ``fifo-depth`` property for such instances of IPs where the
> same FIFO depth is used for both RX and TX. Introduce ``rx-fifo-depth``
> and ``tx-fifo-depth`` properties for cases where the RX FIFO depth is
> different from the TX FIFO depth.
> 
> Make the dedicated RX/TX properties dependent on each other and mutual
> exclusive with the other.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  .../bindings/spi/spi-controller.yaml          | 27 +++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 

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/spi/spi-controller.yaml:152:9: [warning] wrong indentation: expected 6 but found 8 (indentation)
./Documentation/devicetree/bindings/spi/spi-controller.yaml:156:9: [warning] wrong indentation: expected 6 but found 8 (indentation)

dtschema/dtc warnings/errors:

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240212140331.915498-2-tudor.ambarus at linaro.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From shiftee at posteo.net  Mon Feb 12 07:43:19 2024
From: shiftee at posteo.net (Mark O'Donovan)
Date: Mon, 12 Feb 2024 15:43:19 +0000
Subject: [PATCH] net: stmmac: xgmac: fix initializer element is not constant error
Message-ID: <20240212154319.907447-1-shiftee@posteo.net>

GCC prior to 8.x gives an "initializer element is not constant"
error for the uses of dpp_tx_err in dwxgmac3_dma_dpp_errors.
Newer compilers accept either version.

More info here:
https://lore.kernel.org/all/20240103-fix-bq24190_charger-vbus_desc-non-const-v1-1-115ddf798c70 at kernel.org

Signed-off-by: Mark O'Donovan <shiftee at posteo.net>
---
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index 323c57f03c93..c02c035b81c0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -830,8 +830,8 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
 	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
 };
 
-static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
-static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
+#define dpp_rx_err "Read Rx Descriptor Parity checker Error"
+#define dpp_tx_err "Read Tx Descriptor Parity checker Error"
 static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
 	{ true, "TDPES0", dpp_tx_err },
 	{ true, "TDPES1", dpp_tx_err },

base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de
-- 
2.39.2



From ryan.roberts at arm.com  Mon Feb 12 07:47:44 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 15:47:44 +0000
Subject: [PATCH v5 22/25] mm: Add pte_batch_hint() to reduce scanning in
 folio_pte_batch()
In-Reply-To: <6d452a1a-1edc-4e97-8b39-99dc48315bb8@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-23-ryan.roberts@arm.com>
 <6d452a1a-1edc-4e97-8b39-99dc48315bb8@redhat.com>
Message-ID: <82c59a7f-328e-4521-8855-ccacc3dc4ce5@arm.com>

On 12/02/2024 13:43, David Hildenbrand wrote:
> On 02.02.24 09:07, Ryan Roberts wrote:
>> Some architectures (e.g. arm64) can tell from looking at a pte, if some
>> follow-on ptes also map contiguous physical memory with the same pgprot.
>> (for arm64, these are contpte mappings).
>>
>> Take advantage of this knowledge to optimize folio_pte_batch() so that
>> it can skip these ptes when scanning to create a batch. By default, if
>> an arch does not opt-in, folio_pte_batch() returns a compile-time 1, so
>> the changes are optimized out and the behaviour is as before.
>>
>> arm64 will opt-in to providing this hint in the next patch, which will
>> greatly reduce the cost of ptep_get() when scanning a range of contptes.
>>
>> Tested-by: John Hubbard <jhubbard at nvidia.com>
>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>> ---
>> ? include/linux/pgtable.h | 18 ++++++++++++++++++
>> ? mm/memory.c???????????? | 20 +++++++++++++-------
>> ? 2 files changed, 31 insertions(+), 7 deletions(-)
>>
>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>> index 50f32cccbd92..cba31f177d27 100644
>> --- a/include/linux/pgtable.h
>> +++ b/include/linux/pgtable.h
>> @@ -212,6 +212,24 @@ static inline int pmd_dirty(pmd_t pmd)
>> ? #define arch_flush_lazy_mmu_mode()??? do {} while (0)
>> ? #endif
>> ? +#ifndef pte_batch_hint
>> +/**
>> + * pte_batch_hint - Number of pages that can be added to batch without scanning.
>> + * @ptep: Page table pointer for the entry.
>> + * @pte: Page table entry.
>> + *
>> + * Some architectures know that a set of contiguous ptes all map the same
>> + * contiguous memory with the same permissions. In this case, it can provide a
>> + * hint to aid pte batching without the core code needing to scan every pte.
> 
> I think we might want to document here the expectation regarding
> dirty/accessed bits. folio_pte_batch() will ignore dirty bits only with
> FPB_IGNORE_DIRTY. But especially for arm64, it makes sense to ignore them
> always when batching, because the dirty bit may target any pte part of the
> cont-pte group either way.
> 
> Maybe something like:
> 
> "
> An architecture implementation may only ignore the PTE accessed and dirty bits.
> Further, it may only ignore the dirty bit if that bit is already not
> maintained with precision per PTE inside the hinted batch, and ptep_get()
> would already have to collect it from various PTEs.
> "

I'm proposing to simplify this to:

"
An architecture implementation may ignore the PTE accessed state. Further, the
dirty state must apply atomically to all the PTEs described by the hint.
"

Which I think more accurately describes the requirement. Shout if you disagree.

> 
> I think there are some more details to it, but I'm hoping something along
> the lines above is sufficient.
> 
> 
>> +
>> ? #ifndef pte_advance_pfn
>> ? static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>> ? {
>> diff --git a/mm/memory.c b/mm/memory.c
>> index 65fbe4f886c1..902665b27702 100644
>> --- a/mm/memory.c
>> +++ b/mm/memory.c
>> @@ -988,16 +988,21 @@ static inline int folio_pte_batch(struct folio *folio,
>> unsigned long addr,
>> ? {
>> ????? unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio);
>> ????? const pte_t *end_ptep = start_ptep + max_nr;
>> -??? pte_t expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, 1),
>> flags);
>> -??? pte_t *ptep = start_ptep + 1;
>> +??? pte_t expected_pte = __pte_batch_clear_ignored(pte, flags);
>> +??? pte_t *ptep = start_ptep;
>> ????? bool writable;
>> +??? int nr;
>> ? ????? if (any_writable)
>> ????????? *any_writable = false;
>> ? ????? VM_WARN_ON_FOLIO(!pte_present(pte), folio);
>> ? -??? while (ptep != end_ptep) {
>> +??? nr = pte_batch_hint(ptep, pte);
>> +??? expected_pte = pte_advance_pfn(expected_pte, nr);
>> +??? ptep += nr;
>> +
> 
> *Maybe* it's easier to get when initializing expected_pte+ptep only once.
> 
> Like:
> 
> [...]
> pte_t expected_pte, *ptep;
> [...]
> 
> nr = pte_batch_hint(start_ptep, pte);
> expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, nr), flags);
> ptep = start_ptep + nr;
> 
>> +??? while (ptep < end_ptep) {
>> ????????? pte = ptep_get(ptep);
>> ????????? if (any_writable)
>> ????????????? writable = !!pte_write(pte);
>> @@ -1011,17 +1016,18 @@ static inline int folio_pte_batch(struct folio *folio,
>> unsigned long addr,
>> ?????????? * corner cases the next PFN might fall into a different
>> ?????????? * folio.
>> ?????????? */
>> -??????? if (pte_pfn(pte) == folio_end_pfn)
>> +??????? if (pte_pfn(pte) >= folio_end_pfn)
>> ????????????? break;
>> ? ????????? if (any_writable)
>> ????????????? *any_writable |= writable;
>> ? -??????? expected_pte = pte_advance_pfn(expected_pte, 1);
>> -??????? ptep++;
>> +??????? nr = pte_batch_hint(ptep, pte);
>> +??????? expected_pte = pte_advance_pfn(expected_pte, nr);
>> +??????? ptep += nr;
>> ????? }
>> ? -??? return ptep - start_ptep;
>> +??? return min(ptep - start_ptep, max_nr);
>> ? }
> 
> Acked-by: David Hildenbrand <david at redhat.com>
> 



From ville.syrjala at linux.intel.com  Mon Feb 12 07:49:33 2024
From: ville.syrjala at linux.intel.com (Ville =?iso-8859-1?Q?Syrj=E4l=E4?=)
Date: Mon, 12 Feb 2024 17:49:33 +0200
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add
 Broadcast RGB property
In-Reply-To: <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
References: <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox>
 <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
Message-ID: <Zco-DQaXqae7B1jt@intel.com>

On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > Hi,
> > > > > > > 
> > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > >  /**
> > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > >   *
> > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > + *
> > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > + *
> > > > > > > > > > + *      Automatic:
> > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > + *
> > > > > > > > > > + *      Full:
> > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > + *
> > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > + *
> > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > + *
> > > > > > > > > 
> > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > different things being affected:
> > > > > > > > > 
> > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > 2. The color pipeline processing
> > > > > > > > > 
> > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > 
> > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > 
> > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > signalling, what happens?
> > > > > > > > 
> > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > YCbCr?
> > > > > > > 
> > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > vc4 will follow the value of the property.
> > > > > > 
> > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > That should explain why it's only affecting RGB.
> > > > > 
> > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > itself.
> > > > > 
> > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > to enable it.
> > > > > 
> > > > > vc4 supports it.
> > > > 
> > > > Someone implemented it incorrectly then.
> > > 
> > > Incorrectly according to what documentation / specification? I'm sorry,
> > > but I find it super ironic that i915 gets to do its own thing, not
> > > document any of it, and when people try to clean things up they get told
> > > that we got it all wrong.
> > 
> > FWIW, this was an i915 property and if another driver uses the same
> > property name it must have the same behavior. Yes, it isn't standardized
> > and yes, it's not documented (hence this effort here) but it's still on
> > vc4 to make the property compatible.
> 
> How is it not compatible? It's a superset of what i915 provides, but
> it's strictly compatible with it.

No it is not. Eg. what happens if you set the thing to full range for
RGB (which you must on many broken monitors), and then the kernel
automagically switches to YCbCr (for whatever reason) but the monitor
doesn't support full range YCbCr? Answer: you get crap output.

> 
> I would argue that i915 is the broken one since userspace could force a
> full range output, but since the driver takes the YUV vs RGB decision
> itself and only supports limited range for YUV, the driver would
> effectively ignore that user-space property, without the user-space
> being able to tell it was ignored in the first place.
> 
> > Trying to make the property handle YCbCr is very much in the "let's try
> > to fix the property" territory that I want to avoid, so I'm in favor of
> > adjusting vc4.
> 
> Breaking the ABI in the process. For something that is explicitly
> supported by the spec, the driver, and the hardware. On a property that
> never said it wasn't meant to be used that way, and with semantics based
> on a driver that never provided a way to check those restrictions in the
> first place.
> 
> And it's not like i915 is going to use that code anyway.
> 
> Maxime



-- 
Ville Syrj?l?
Intel


From matthias.bgg at gmail.com  Mon Feb 12 07:50:12 2024
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Mon, 12 Feb 2024 16:50:12 +0100
Subject: [PATCH] iommu/mtk_iommu: Use devm_kcalloc() instead of
 devm_kzalloc()
In-Reply-To: <20240211182250.12656-1-erick.archer@gmx.com>
References: <20240211182250.12656-1-erick.archer@gmx.com>
Message-ID: <826077f1-dc96-49be-961b-e9cfbed1fef5@gmail.com>



On 11/02/2024 19:22, Erick Archer wrote:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> Here the multiplication is obviously safe because MTK_PROTECT_PA_ALIGN
> is defined as a literal value of 256 or 128.
> 
> For the "mtk_iommu.c" file: 256
> For the "mtk_iommu_v1.c" file: 128
> 
> However, using devm_kcalloc() is more appropriate [2] and improves
> readability. This patch has no effect on runtime behavior.
> 
> Link: https://github.com/KSPP/linux/issues/162 [1]
> Link: https://www.kernel.org/doc/html/next/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [2]
> Signed-off-by: Erick Archer <erick.archer at gmx.com>

Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

> ---
>   drivers/iommu/mtk_iommu.c    | 2 +-
>   drivers/iommu/mtk_iommu_v1.c | 4 ++--
>   2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 7abe9e85a570..9aae6eb604b1 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -1264,7 +1264,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_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN, GFP_KERNEL);
>   	if (!protect)
>   		return -ENOMEM;
>   	data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index 25b41222abae..45cd845d153f 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -621,8 +621,8 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev)
>   	data->dev = dev;
> 
>   	/* Protect memory. HW will access here while translation fault.*/
> -	protect = devm_kzalloc(dev, MTK_PROTECT_PA_ALIGN * 2,
> -			GFP_KERNEL | GFP_DMA);
> +	protect = devm_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN,
> +			       GFP_KERNEL | GFP_DMA);
>   	if (!protect)
>   		return -ENOMEM;
>   	data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
> --
> 2.25.1
> 


From matthias.bgg at gmail.com  Mon Feb 12 07:50:51 2024
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Mon, 12 Feb 2024 16:50:51 +0100
Subject: [PATCH v2] mtd: rawnand: Prefer struct_size over open coded
 arithmetic
In-Reply-To: <20240211091633.4545-1-erick.archer@gmx.com>
References: <20240211091633.4545-1-erick.archer@gmx.com>
Message-ID: <f5ea54f4-9176-4fde-89bf-71b1771e47c3@gmail.com>



On 11/02/2024 10:16, Erick Archer wrote:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> As the "chip" variable is a pointer to "struct mtk_nfc_nand_chip" and
> this structure ends in a flexible array:
> 
> struct mtk_nfc_nand_chip {
> 	[...]
> 	u8 sels[] __counted_by(nsels);
> };
> 
> the preferred way in the kernel is to use the struct_size() helper to
> do the arithmetic instead of the argument "size + count * size" in the
> devm_kzalloc() function.
> 
> This way, the code is more readable and safer.
> 
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
> Link: https://github.com/KSPP/linux/issues/160 [2]
> Reviewed-by: Gustavo A. R. Silva <gustavoars at kernel.org>
> Signed-off-by: Erick Archer <erick.archer at gmx.com>

Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

> ---
> Changes in v2:
> - Add the "Reviewed-by:" tag.
> - Fix a spelling error in the commit message. Change "more safer" for
>    "safer" (Uwe Kleine-K?nig)
> ---
>   drivers/mtd/nand/raw/mtk_nand.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
> index 60198e33d2d5..17477bb2d48f 100644
> --- a/drivers/mtd/nand/raw/mtk_nand.c
> +++ b/drivers/mtd/nand/raw/mtk_nand.c
> @@ -1356,7 +1356,7 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
>   		return -EINVAL;
>   	}
> 
> -	chip = devm_kzalloc(dev, sizeof(*chip) + nsels * sizeof(u8),
> +	chip = devm_kzalloc(dev, struct_size(chip, sels, nsels),
>   			    GFP_KERNEL);
>   	if (!chip)
>   		return -ENOMEM;
> --
> 2.25.1
> 


From mwalle at kernel.org  Mon Feb 12 08:02:31 2024
From: mwalle at kernel.org (Michael Walle)
Date: Mon, 12 Feb 2024 17:02:31 +0100
Subject: [PATCH v2 3/3] arm64: dts: ti: Add support for TI J722S
 Evaluation Module
In-Reply-To: <20240206100608.127702-4-vaishnav.a@ti.com>
References: <20240206100608.127702-1-vaishnav.a@ti.com>
 <20240206100608.127702-4-vaishnav.a@ti.com>
Message-ID: <CZ386ITQ83KH.1KNOV5MXLXPBF@kernel.org>

Hi,

On Tue Feb 6, 2024 at 11:06 AM CET, Vaishnav Achath wrote:
> +# Boards with J722s SoC
> +dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb

I'm a bit confused by your names. What are the new/correct ones now?
Some seem to use the amXX names and some the jXX ones. I've read [1]
and it appears it was suggested to use the am67 names for the device
trees. Esp. because there is already, am62, am64, am65, am68 and
am69 in as names for the device trees.

The TRM you've linked in the cover letter doesn't shed much light
either. It just lists both.

-michael

[1] https://lore.kernel.org/all/81f90d13-da10-4a68-a0e7-95212f40b3e8 at ti.com/            
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 252 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240212/4bbd1b74/attachment-0001.sig>

From andrew at lunn.ch  Mon Feb 12 08:08:58 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 12 Feb 2024 17:08:58 +0100
Subject: [PATCH 1/2] ARM: dts: imx6dl-yapp4: Fix the QCA switch register
 address
In-Reply-To: <1707751422-31517-1-git-send-email-michal.vokac@ysoft.com>
References: <1707751422-31517-1-git-send-email-michal.vokac@ysoft.com>
Message-ID: <c5dad8e7-c486-4dd9-bfb5-bdfa2ddc18b3@lunn.ch>

On Mon, Feb 12, 2024 at 04:23:41PM +0100, Michal Vok?? wrote:
> The switch address in the node name is in hex while the address in the reg
> property is decimal which is wrong. Fix that and write the reg address
> as a hexadecimal number.

This feels the wrong way around. The reg value is used by the kernel,
where as the node name is not. If the reg value was wrong, the switch
would not be found. If this file was tested, why did somebody not
notice the switch was missing?

Do you have the hardware? Can you confirm is really does not work
without this patch? Was 15b43e497ffd never actually tested?

Thanks
	Andrew

> 
> Fixes: 15b43e497ffd ("ARM: dts: imx6dl-yapp4: Use correct pseudo PHY address for the switch")
> Signed-off-by: Michal Vok?? <michal.vokac at ysoft.com>
> ---
>  arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
> index cfb0fc924b42..5763f8253d51 100644
> --- a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
> +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
> @@ -143,7 +143,7 @@
>  
>  		switch at 10 {
>  			compatible = "qca,qca8334";
> -			reg = <10>;
> +			reg = <0x10>;
>  			reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
>  
>  			switch_ports: ports {
> -- 
> 2.1.4
> 


From rafael at kernel.org  Mon Feb 12 08:09:34 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Mon, 12 Feb 2024 17:09:34 +0100
Subject: [PATCH v2] fix overflow in idle exit_latency
In-Reply-To: <e23ebdd8-7fbe-435b-a850-0ef18a51b020@collabora.com>
References: <20231219031444.91752-1-bo.ye@mediatek.com> <e23ebdd8-7fbe-435b-a850-0ef18a51b020@collabora.com>
Message-ID: <CAJZ5v0h=OKnY85EF9Mg1irsSbnea+P9oAQAdQURqjn+6_5s2PQ@mail.gmail.com>

On Tue, Dec 19, 2023 at 11:56?AM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Il 19/12/23 04:14, Bo Ye ha scritto:
> > From: C Cheng <C.Cheng at mediatek.com>
> >
> > In detail:
> >
> > In C language, when you perform a multiplication operation, if
> > both operands are of int type, the multiplication operation is
> > performed on the int type, and then the result is converted to
> > the target type. This means that if the product of int type
> > multiplication exceeds the range that int type can represent,
> >   an overflow will occur even if you store the result in a
> > variable of int64_t type.
> >
> > For a multiplication of two int values, it is better to use
> > mul_u32_u32() rather than s->exit_latency_ns = s->exit_latency *
> > NSEC_PER_USEC to avoid potential overflow happenning.
> >
> > Signed-off-by: C Cheng <C.Cheng at mediatek.com>
> > Signed-off-by: Bo Ye <bo.ye at mediatek.com>
>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Applied as 6.9 material under a different subject (cpuidle: Avoid
potential overflow in integer multiplication), thanks!


From afd at ti.com  Mon Feb 12 08:13:14 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:13:14 -0600
Subject: [PATCH v3 18/19] power: reset: syscon-poweroff: Move device data
 into a struct
In-Reply-To: <glaiaikudbtuahnwnqoduretcnmrpb7lg2gerlnntcltrjfcko@4vgjb4v66rad>
References: <20240208170410.67975-1-afd@ti.com>
 <20240208170410.67975-19-afd@ti.com>
 <glaiaikudbtuahnwnqoduretcnmrpb7lg2gerlnntcltrjfcko@4vgjb4v66rad>
Message-ID: <961cb55f-1725-4e3e-9704-c0e7cb9e4e7c@ti.com>

On 2/11/24 5:52 PM, Sebastian Reichel wrote:
> Hi Andrew,
> 
> On Thu, Feb 08, 2024 at 11:04:09AM -0600, Andrew Davis wrote:
>> Currently all these device data elements are top level global variables.
>> Move these into a struct. This will be used in the next patch when
>> the global variable usage is removed. Doing this in two steps makes
>> the patches easier to read.
>>
>> Signed-off-by: Andrew Davis <afd at ti.com>
>> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> ---
>>   drivers/power/reset/syscon-poweroff.c | 36 +++++++++++++++------------
>>   1 file changed, 20 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
>> index 1b2ce7734260c..4899a019256e8 100644
>> --- a/drivers/power/reset/syscon-poweroff.c
>> +++ b/drivers/power/reset/syscon-poweroff.c
>> @@ -15,15 +15,19 @@
>>   #include <linux/pm.h>
>>   #include <linux/regmap.h>
>>   
>> -static struct regmap *map;
>> -static u32 offset;
>> -static u32 value;
>> -static u32 mask;
>> +struct syscon_poweroff_data {
>> +	struct regmap *map;
>> +	u32 offset;
>> +	u32 value;
>> +	u32 mask;
>> +};
>> +
>> +static struct syscon_poweroff_data *data;
> 
> This patch is broken without the follow-up patch, since data is
> never allocated. You need to move the memory allocation from the
> next patch to this one.

Ah, yes, seems I meant to make this struct point to a definition
not just a declaration. But just moving the allocation to this
patch seems to make this easier too, will do that, v4 on the way.

Thanks,
Andrew

> 
> Greetings,
> 
> -- Sebastian


From david at redhat.com  Mon Feb 12 08:24:15 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 17:24:15 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <abe814c9-71f3-4d7d-bdc8-9dd930d6f0b2@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <a91cfe1c-289e-4828-8cfc-be34eb69a71b@redhat.com>
 <502a3ea7-fd86-4314-8292-c7999eda92eb@arm.com>
 <427ba87a-7dd0-4f3e-861f-fe6946b7cd97@redhat.com>
 <abe814c9-71f3-4d7d-bdc8-9dd930d6f0b2@arm.com>
Message-ID: <55a1e0ef-14b3-4311-b2aa-a6add76fa2ed@redhat.com>

On 12.02.24 16:34, Ryan Roberts wrote:
> On 12/02/2024 15:26, David Hildenbrand wrote:
>> On 12.02.24 15:45, Ryan Roberts wrote:
>>> On 12/02/2024 13:54, David Hildenbrand wrote:
>>>>>> If so, I wonder if we could instead do that comparison modulo the access/dirty
>>>>>> bits,
>>>>>
>>>>> I think that would work - but will need to think a bit more on it.
>>>>>
>>>>>> and leave ptep_get_lockless() only reading a single entry?
>>>>>
>>>>> I think we will need to do something a bit less fragile. ptep_get() does
>>>>> collect
>>>>> the access/dirty bits so its confusing if ptep_get_lockless() doesn't IMHO. So
>>>>> we will likely want to rename the function and make its documentation explicit
>>>>> that it does not return those bits.
>>>>>
>>>>> ptep_get_lockless_noyoungdirty()? yuk... Any ideas?
>>>>>
>>>>> Of course if I could convince you the current implementation is safe, I
>>>>> might be
>>>>> able to sidestep this optimization until a later date?
>>>>
>>>> As discussed (and pointed out abive), there might be quite some callsites where
>>>> we don't really care about uptodate accessed/dirty bits -- where ptep_get() is
>>>> used nowadays.
>>>>
>>>> One way to approach that I had in mind was having an explicit interface:
>>>>
>>>> ptep_get()
>>>> ptep_get_uptodate()
>>>> ptep_get_lockless()
>>>> ptep_get_lockless_uptodate()
>>>
>>> Yes, I like the direction of this. I guess we anticipate that call sites
>>> requiring the "_uptodate" variant will be the minority so it makes sense to use
>>> the current names for the "_not_uptodate" variants? But to do a slow migration,
>>> it might be better/safer to have the weaker variant use the new name - that
>>> would allow us to downgrade one at a time?
>>
>> Yes, I was primarily struggling with names. Likely it makes sense to either have
>> two completely new function names, or use the new name only for the "faster but
>> less precise" variant.
>>
>>>
>>>>
>>>> Especially the last one might not be needed.
>>> I've done a scan through the code and agree with Mark's original conclusions.
>>> Additionally, huge_pte_alloc() (which isn't used for arm64) doesn't rely on
>>> access/dirty info. So I think I could migrate everything to the weaker variant
>>> fairly easily.
>>>
>>>>
>>>> Futher, "uptodate" might not be the best choice because of PageUptodate() and
>>>> friends. But it's better than "youngdirty"/"noyoungdirty" IMHO.
>>>
>>> Certainly agree with "noyoungdirty" being a horrible name. How about "_sync" /
>>> "_nosync"?
>>
>> I could live with
>>
>> ptep_get_sync()
>> ptep_get_nosync()
>>
>> with proper documentation :)
> 
> but could you live with:
> 
> ptep_get()
> ptep_get_nosync()
> ptep_get_lockless_nosync()
> 
> ?
> 
> So leave the "slower, more precise" version with the existing name.

Sure.

-- 
Cheers,

David / dhildenb



From david at redhat.com  Mon Feb 12 08:27:59 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 12 Feb 2024 17:27:59 +0100
Subject: [PATCH v5 22/25] mm: Add pte_batch_hint() to reduce scanning in
 folio_pte_batch()
In-Reply-To: <82c59a7f-328e-4521-8855-ccacc3dc4ce5@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-23-ryan.roberts@arm.com>
 <6d452a1a-1edc-4e97-8b39-99dc48315bb8@redhat.com>
 <82c59a7f-328e-4521-8855-ccacc3dc4ce5@arm.com>
Message-ID: <cc6cd016-0d91-428d-8041-329d5400978e@redhat.com>

On 12.02.24 16:47, Ryan Roberts wrote:
> On 12/02/2024 13:43, David Hildenbrand wrote:
>> On 02.02.24 09:07, Ryan Roberts wrote:
>>> Some architectures (e.g. arm64) can tell from looking at a pte, if some
>>> follow-on ptes also map contiguous physical memory with the same pgprot.
>>> (for arm64, these are contpte mappings).
>>>
>>> Take advantage of this knowledge to optimize folio_pte_batch() so that
>>> it can skip these ptes when scanning to create a batch. By default, if
>>> an arch does not opt-in, folio_pte_batch() returns a compile-time 1, so
>>> the changes are optimized out and the behaviour is as before.
>>>
>>> arm64 will opt-in to providing this hint in the next patch, which will
>>> greatly reduce the cost of ptep_get() when scanning a range of contptes.
>>>
>>> Tested-by: John Hubbard <jhubbard at nvidia.com>
>>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>>> ---
>>>  ? include/linux/pgtable.h | 18 ++++++++++++++++++
>>>  ? mm/memory.c???????????? | 20 +++++++++++++-------
>>>  ? 2 files changed, 31 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>>> index 50f32cccbd92..cba31f177d27 100644
>>> --- a/include/linux/pgtable.h
>>> +++ b/include/linux/pgtable.h
>>> @@ -212,6 +212,24 @@ static inline int pmd_dirty(pmd_t pmd)
>>>  ? #define arch_flush_lazy_mmu_mode()??? do {} while (0)
>>>  ? #endif
>>>  ? +#ifndef pte_batch_hint
>>> +/**
>>> + * pte_batch_hint - Number of pages that can be added to batch without scanning.
>>> + * @ptep: Page table pointer for the entry.
>>> + * @pte: Page table entry.
>>> + *
>>> + * Some architectures know that a set of contiguous ptes all map the same
>>> + * contiguous memory with the same permissions. In this case, it can provide a
>>> + * hint to aid pte batching without the core code needing to scan every pte.
>>
>> I think we might want to document here the expectation regarding
>> dirty/accessed bits. folio_pte_batch() will ignore dirty bits only with
>> FPB_IGNORE_DIRTY. But especially for arm64, it makes sense to ignore them
>> always when batching, because the dirty bit may target any pte part of the
>> cont-pte group either way.
>>
>> Maybe something like:
>>
>> "
>> An architecture implementation may only ignore the PTE accessed and dirty bits.
>> Further, it may only ignore the dirty bit if that bit is already not
>> maintained with precision per PTE inside the hinted batch, and ptep_get()
>> would already have to collect it from various PTEs.
>> "
> 
> I'm proposing to simplify this to:
> 
> "
> An architecture implementation may ignore the PTE accessed state. Further, the
> dirty state must apply atomically to all the PTEs described by the hint.
> "
> 
> Which I think more accurately describes the requirement. Shout if you disagree.

I'm not 100% sure if the "must apply atomically" is clear without all of 
the cont-pte details and ptep_get(). But I fail to describe it in a 
better way.

It's all better compared to what we had before, so LGTM :)

-- 
Cheers,

David / dhildenb



From afd at ti.com  Mon Feb 12 08:28:15 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:15 -0600
Subject: [PATCH v4 03/19] power: reset: xgene-reboot: Use devm_platform_ioremap_resource() helper
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-4-afd@ti.com>

Use device life-cycle managed ioremap function to simplify probe and
exit paths.

While here add __iomem to the returned pointer to fix a sparse warning.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/xgene-reboot.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
index c2e5a99940d37..6b545a83d8889 100644
--- a/drivers/power/reset/xgene-reboot.c
+++ b/drivers/power/reset/xgene-reboot.c
@@ -22,7 +22,7 @@
 
 struct xgene_reboot_context {
 	struct device *dev;
-	void *csr;
+	void __iomem *csr;
 	u32 mask;
 	struct notifier_block restart_handler;
 };
@@ -54,7 +54,7 @@ static int xgene_reboot_probe(struct platform_device *pdev)
 	if (!ctx)
 		return -ENOMEM;
 
-	ctx->csr = of_iomap(dev->of_node, 0);
+	ctx->csr = devm_platform_ioremap_resource(pdev, 0);
 	if (!ctx->csr) {
 		dev_err(dev, "can not map resource\n");
 		return -ENODEV;
@@ -67,10 +67,8 @@ static int xgene_reboot_probe(struct platform_device *pdev)
 	ctx->restart_handler.notifier_call = xgene_restart_handler;
 	ctx->restart_handler.priority = 128;
 	err = register_restart_handler(&ctx->restart_handler);
-	if (err) {
-		iounmap(ctx->csr);
+	if (err)
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
-	}
 
 	return err;
 }
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:12 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:12 -0600
Subject: [PATCH v4 00/19] Remove pm_power_off use in drivers/power/reset
Message-ID: <20240212162831.67838-1-afd@ti.com>

Hello all,

Use of pm_power_off is considered legacy and should be replaced with
register_sys_off*(). Same for register_restart_handler(). Do this
for the drivers/power/reset subsystem for all trivial cases.

Thanks,
Andrew

Changes for v4:
 - Fix sparse warning in [12/19] and [13/19]
 - Move data allocate from [19/19] to [18/19]
 - Add review tags in patches [7/19] and [11/19]
 - Rebase on v6.8-rc4

Changes for v3:
 - Use dev_err_probe() in patch [11/19]
 - Add review tags in patches [18/19] and [19/19]

Changes for v2:
 - Fix sparse warning in 7/19 and 10/19
 - Add new patch fixing an already existing sparse warning (3/19)
 - Rebase on v6.8-rc3

Andrew Davis (19):
  power: reset: atc260x-poweroff: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: atc260x-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: xgene-reboot: Use devm_platform_ioremap_resource()
    helper
  power: reset: xgene-reboot: Use devm_register_sys_off_handler(RESTART)
  power: reset: tps65086-restart: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: tps65086-restart: Remove unneeded device data struct
  power: reset: brcm-kona-reset: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: axxia-reset: Use devm_register_sys_off_handler(RESTART)
  power: reset: rmobile-reset: Use devm_platform_ioremap_resource()
    helper
  power: reset: rmobile-reset: Use
    devm_register_sys_off_handler(RESTART)
  power: reset: mt6323-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: msm-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: msm-poweroff: Use devm_register_sys_off_handler(RESTART)
  power: reset: regulator-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: as3722-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: gemini-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: restart-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)
  power: reset: syscon-poweroff: Move device data into a struct
  power: reset: syscon-poweroff: Use
    devm_register_sys_off_handler(POWER_OFF)

 drivers/power/reset/as3722-poweroff.c    | 30 ++++-------
 drivers/power/reset/atc260x-poweroff.c   | 55 ++++++++------------
 drivers/power/reset/axxia-reset.c        | 16 +++---
 drivers/power/reset/brcm-kona-reset.c    | 11 ++--
 drivers/power/reset/gemini-poweroff.c    | 16 +++---
 drivers/power/reset/msm-poweroff.c       | 21 +++-----
 drivers/power/reset/mt6323-poweroff.c    | 26 +++++-----
 drivers/power/reset/regulator-poweroff.c | 36 +++++--------
 drivers/power/reset/restart-poweroff.c   | 25 +++------
 drivers/power/reset/rmobile-reset.c      | 35 ++++---------
 drivers/power/reset/syscon-poweroff.c    | 66 ++++++++++++------------
 drivers/power/reset/tps65086-restart.c   | 58 ++++-----------------
 drivers/power/reset/xgene-reboot.c       | 21 +++-----
 13 files changed, 150 insertions(+), 266 deletions(-)

-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:18 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:18 -0600
Subject: [PATCH v4 06/19] power: reset: tps65086-restart: Remove unneeded device data struct
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-7-afd@ti.com>

We only need one member of the struct tps65086_restart, pass that
tps65086_restart_notify() directly. Remove that struct and its
allocation.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/tps65086-restart.c | 35 ++++++--------------------
 1 file changed, 8 insertions(+), 27 deletions(-)

diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c
index 82d7a761a0385..6976dbcac74fa 100644
--- a/drivers/power/reset/tps65086-restart.c
+++ b/drivers/power/reset/tps65086-restart.c
@@ -9,19 +9,14 @@
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
 
-struct tps65086_restart {
-	struct device *dev;
-};
-
 static int tps65086_restart_notify(struct sys_off_data *data)
 {
-	struct tps65086_restart *tps65086_restart = data->cb_data;
-	struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent);
+	struct tps65086 *tps65086 = data->cb_data;
 	int ret;
 
 	ret = regmap_write(tps65086->regmap, TPS65086_FORCESHUTDN, 1);
 	if (ret) {
-		dev_err(tps65086_restart->dev, "%s: error writing to tps65086 pmic: %d\n",
+		dev_err(tps65086->dev, "%s: error writing to tps65086 pmic: %d\n",
 			__func__, ret);
 		return NOTIFY_DONE;
 	}
@@ -36,27 +31,13 @@ static int tps65086_restart_notify(struct sys_off_data *data)
 
 static int tps65086_restart_probe(struct platform_device *pdev)
 {
-	struct tps65086_restart *tps65086_restart;
-	int ret;
-
-	tps65086_restart = devm_kzalloc(&pdev->dev, sizeof(*tps65086_restart), GFP_KERNEL);
-	if (!tps65086_restart)
-		return -ENOMEM;
-
-	tps65086_restart->dev = &pdev->dev;
-
-	ret = devm_register_sys_off_handler(&pdev->dev,
-					    SYS_OFF_MODE_RESTART,
-					    SYS_OFF_PRIO_HIGH,
-					    tps65086_restart_notify,
-					    tps65086_restart);
-	if (ret) {
-		dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
-			__func__, ret);
-		return -ENODEV;
-	}
+	struct tps65086 *tps65086 = dev_get_drvdata(pdev->dev.parent);
 
-	return 0;
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_RESTART,
+					     SYS_OFF_PRIO_HIGH,
+					     tps65086_restart_notify,
+					     tps65086);
 }
 
 static const struct platform_device_id tps65086_restart_id_table[] = {
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:14 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:14 -0600
Subject: [PATCH v4 02/19] power: reset: atc260x-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-3-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/atc260x-poweroff.c | 38 ++++++++++----------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/drivers/power/reset/atc260x-poweroff.c b/drivers/power/reset/atc260x-poweroff.c
index ce2748d3282c3..e3e4621ccb1dd 100644
--- a/drivers/power/reset/atc260x-poweroff.c
+++ b/drivers/power/reset/atc260x-poweroff.c
@@ -19,9 +19,6 @@ struct atc260x_pwrc {
 	int (*do_poweroff)(const struct atc260x_pwrc *pwrc, bool restart);
 };
 
-/* Global variable needed only for pm_power_off */
-static struct atc260x_pwrc *atc260x_pwrc_data;
-
 static int atc2603c_do_poweroff(const struct atc260x_pwrc *pwrc, bool restart)
 {
 	int ret, deep_sleep = 0;
@@ -164,11 +161,15 @@ static int atc2609a_init(const struct atc260x_pwrc *pwrc)
 	return ret;
 }
 
-static void atc260x_pwrc_pm_handler(void)
+static int atc260x_pwrc_pm_handler(struct sys_off_data *data)
 {
-	atc260x_pwrc_data->do_poweroff(atc260x_pwrc_data, false);
+	struct atc260x_pwrc *pwrc = data->cb_data;
+
+	pwrc->do_poweroff(pwrc, false);
 
 	WARN_ONCE(1, "Unable to power off system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int atc260x_pwrc_restart_handler(struct sys_off_data *data)
@@ -211,14 +212,14 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	platform_set_drvdata(pdev, priv);
-
-	if (!pm_power_off) {
-		atc260x_pwrc_data = priv;
-		pm_power_off = atc260x_pwrc_pm_handler;
-	} else {
-		dev_warn(priv->dev, "Poweroff callback already assigned\n");
-	}
+	ret = devm_register_sys_off_handler(priv->dev,
+					    SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    atc260x_pwrc_pm_handler,
+					    priv);
+	if (ret)
+		dev_err(priv->dev, "failed to register power-off handler: %d\n",
+			ret);
 
 	ret = devm_register_sys_off_handler(priv->dev,
 					    SYS_OFF_MODE_RESTART,
@@ -232,19 +233,8 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static void atc260x_pwrc_remove(struct platform_device *pdev)
-{
-	struct atc260x_pwrc *priv = platform_get_drvdata(pdev);
-
-	if (atc260x_pwrc_data == priv) {
-		pm_power_off = NULL;
-		atc260x_pwrc_data = NULL;
-	}
-}
-
 static struct platform_driver atc260x_pwrc_driver = {
 	.probe = atc260x_pwrc_probe,
-	.remove_new = atc260x_pwrc_remove,
 	.driver = {
 		.name = "atc260x-pwrc",
 	},
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:16 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:16 -0600
Subject: [PATCH v4 04/19] power: reset: xgene-reboot: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-5-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/xgene-reboot.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
index 6b545a83d8889..867162dfe7eae 100644
--- a/drivers/power/reset/xgene-reboot.c
+++ b/drivers/power/reset/xgene-reboot.c
@@ -24,15 +24,11 @@ struct xgene_reboot_context {
 	struct device *dev;
 	void __iomem *csr;
 	u32 mask;
-	struct notifier_block restart_handler;
 };
 
-static int xgene_restart_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int xgene_restart_handler(struct sys_off_data *data)
 {
-	struct xgene_reboot_context *ctx =
-		container_of(this, struct xgene_reboot_context,
-			     restart_handler);
+	struct xgene_reboot_context *ctx = data->cb_data;
 
 	/* Issue the reboot */
 	writel(ctx->mask, ctx->csr);
@@ -64,9 +60,8 @@ static int xgene_reboot_probe(struct platform_device *pdev)
 		ctx->mask = 0xFFFFFFFF;
 
 	ctx->dev = dev;
-	ctx->restart_handler.notifier_call = xgene_restart_handler;
-	ctx->restart_handler.priority = 128;
-	err = register_restart_handler(&ctx->restart_handler);
+	err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, 128,
+					    xgene_restart_handler, ctx);
 	if (err)
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
 
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:17 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:17 -0600
Subject: [PATCH v4 05/19] power: reset: tps65086-restart: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-6-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/tps65086-restart.c | 35 ++++++--------------------
 1 file changed, 7 insertions(+), 28 deletions(-)

diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c
index ee8e9f4b837ea..82d7a761a0385 100644
--- a/drivers/power/reset/tps65086-restart.c
+++ b/drivers/power/reset/tps65086-restart.c
@@ -10,15 +10,12 @@
 #include <linux/reboot.h>
 
 struct tps65086_restart {
-	struct notifier_block handler;
 	struct device *dev;
 };
 
-static int tps65086_restart_notify(struct notifier_block *this,
-				   unsigned long mode, void *cmd)
+static int tps65086_restart_notify(struct sys_off_data *data)
 {
-	struct tps65086_restart *tps65086_restart =
-		container_of(this, struct tps65086_restart, handler);
+	struct tps65086_restart *tps65086_restart = data->cb_data;
 	struct tps65086 *tps65086 = dev_get_drvdata(tps65086_restart->dev->parent);
 	int ret;
 
@@ -46,13 +43,13 @@ static int tps65086_restart_probe(struct platform_device *pdev)
 	if (!tps65086_restart)
 		return -ENOMEM;
 
-	platform_set_drvdata(pdev, tps65086_restart);
-
-	tps65086_restart->handler.notifier_call = tps65086_restart_notify;
-	tps65086_restart->handler.priority = 192;
 	tps65086_restart->dev = &pdev->dev;
 
-	ret = register_restart_handler(&tps65086_restart->handler);
+	ret = devm_register_sys_off_handler(&pdev->dev,
+					    SYS_OFF_MODE_RESTART,
+					    SYS_OFF_PRIO_HIGH,
+					    tps65086_restart_notify,
+					    tps65086_restart);
 	if (ret) {
 		dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
 			__func__, ret);
@@ -62,23 +59,6 @@ static int tps65086_restart_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static void tps65086_restart_remove(struct platform_device *pdev)
-{
-	struct tps65086_restart *tps65086_restart = platform_get_drvdata(pdev);
-	int ret;
-
-	ret = unregister_restart_handler(&tps65086_restart->handler);
-	if (ret) {
-		/*
-		 * tps65086_restart_probe() registered the restart handler. So
-		 * unregistering should work fine. Checking the error code
-		 * shouldn't be needed, still doing it for completeness.
-		 */
-		dev_err(&pdev->dev, "%s: cannot unregister restart handler: %d\n",
-			__func__, ret);
-	}
-}
-
 static const struct platform_device_id tps65086_restart_id_table[] = {
 	{ "tps65086-reset", },
 	{ /* sentinel */ }
@@ -90,7 +70,6 @@ static struct platform_driver tps65086_restart_driver = {
 		.name = "tps65086-restart",
 	},
 	.probe = tps65086_restart_probe,
-	.remove_new = tps65086_restart_remove,
 	.id_table = tps65086_restart_id_table,
 };
 module_platform_driver(tps65086_restart_driver);
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:21 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:21 -0600
Subject: [PATCH v4 09/19] power: reset: rmobile-reset: Use devm_platform_ioremap_resource() helper
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-10-afd@ti.com>

Use device life-cycle managed ioremap function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/rmobile-reset.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c
index 5df9b41c68c79..29c17ed2d4de9 100644
--- a/drivers/power/reset/rmobile-reset.c
+++ b/drivers/power/reset/rmobile-reset.c
@@ -41,28 +41,23 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 {
 	int error;
 
-	sysc_base2 = of_iomap(pdev->dev.of_node, 1);
-	if (!sysc_base2)
-		return -ENODEV;
+	sysc_base2 = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(sysc_base2))
+		return PTR_ERR(sysc_base2);
 
 	error = register_restart_handler(&rmobile_reset_nb);
 	if (error) {
 		dev_err(&pdev->dev,
 			"cannot register restart handler (err=%d)\n", error);
-		goto fail_unmap;
+		return error;
 	}
 
 	return 0;
-
-fail_unmap:
-	iounmap(sysc_base2);
-	return error;
 }
 
 static void rmobile_reset_remove(struct platform_device *pdev)
 {
 	unregister_restart_handler(&rmobile_reset_nb);
-	iounmap(sysc_base2);
 }
 
 static const struct of_device_id rmobile_reset_of_match[] = {
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:13 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:13 -0600
Subject: [PATCH v4 01/19] power: reset: atc260x-poweroff: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-2-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/atc260x-poweroff.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/power/reset/atc260x-poweroff.c b/drivers/power/reset/atc260x-poweroff.c
index b4aa50e9685e1..ce2748d3282c3 100644
--- a/drivers/power/reset/atc260x-poweroff.c
+++ b/drivers/power/reset/atc260x-poweroff.c
@@ -16,7 +16,6 @@
 struct atc260x_pwrc {
 	struct device *dev;
 	struct regmap *regmap;
-	struct notifier_block restart_nb;
 	int (*do_poweroff)(const struct atc260x_pwrc *pwrc, bool restart);
 };
 
@@ -172,11 +171,9 @@ static void atc260x_pwrc_pm_handler(void)
 	WARN_ONCE(1, "Unable to power off system\n");
 }
 
-static int atc260x_pwrc_restart_handler(struct notifier_block *nb,
-					unsigned long mode, void *cmd)
+static int atc260x_pwrc_restart_handler(struct sys_off_data *data)
 {
-	struct atc260x_pwrc *pwrc = container_of(nb, struct atc260x_pwrc,
-						 restart_nb);
+	struct atc260x_pwrc *pwrc = data->cb_data;
 	pwrc->do_poweroff(pwrc, true);
 
 	return NOTIFY_DONE;
@@ -194,8 +191,6 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 
 	priv->dev = &pdev->dev;
 	priv->regmap = atc260x->regmap;
-	priv->restart_nb.notifier_call = atc260x_pwrc_restart_handler;
-	priv->restart_nb.priority = 192;
 
 	switch (atc260x->ic_type) {
 	case ATC2603C:
@@ -225,7 +220,11 @@ static int atc260x_pwrc_probe(struct platform_device *pdev)
 		dev_warn(priv->dev, "Poweroff callback already assigned\n");
 	}
 
-	ret = register_restart_handler(&priv->restart_nb);
+	ret = devm_register_sys_off_handler(priv->dev,
+					    SYS_OFF_MODE_RESTART,
+					    SYS_OFF_PRIO_HIGH,
+					    atc260x_pwrc_restart_handler,
+					    priv);
 	if (ret)
 		dev_err(priv->dev, "failed to register restart handler: %d\n",
 			ret);
@@ -241,8 +240,6 @@ static void atc260x_pwrc_remove(struct platform_device *pdev)
 		pm_power_off = NULL;
 		atc260x_pwrc_data = NULL;
 	}
-
-	unregister_restart_handler(&priv->restart_nb);
 }
 
 static struct platform_driver atc260x_pwrc_driver = {
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:20 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:20 -0600
Subject: [PATCH v4 08/19] power: reset: axxia-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-9-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/axxia-reset.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/power/reset/axxia-reset.c b/drivers/power/reset/axxia-reset.c
index 24946766760c3..797bf6773860e 100644
--- a/drivers/power/reset/axxia-reset.c
+++ b/drivers/power/reset/axxia-reset.c
@@ -26,11 +26,10 @@
 #define SC_EFUSE_INT_STATUS	0x180c
 #define   EFUSE_READ_DONE	(1<<31)
 
-static struct regmap *syscon;
-
-static int axxia_restart_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int axxia_restart_handler(struct sys_off_data *data)
 {
+	struct regmap *syscon = data->cb_data;
+
 	/* Access Key (0xab) */
 	regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab);
 	/* Select internal boot from 0xffff0000 */
@@ -44,14 +43,10 @@ static int axxia_restart_handler(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block axxia_restart_nb = {
-	.notifier_call = axxia_restart_handler,
-	.priority = 128,
-};
-
 static int axxia_reset_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct regmap *syscon;
 	int err;
 
 	syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
@@ -60,7 +55,8 @@ static int axxia_reset_probe(struct platform_device *pdev)
 		return PTR_ERR(syscon);
 	}
 
-	err = register_restart_handler(&axxia_restart_nb);
+	err = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+					    128, axxia_restart_handler, syscon);
 	if (err)
 		dev_err(dev, "cannot register restart handler (err=%d)\n", err);
 
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:26 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:26 -0600
Subject: [PATCH v4 14/19] power: reset: regulator-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-15-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/regulator-poweroff.c | 36 +++++++++---------------
 1 file changed, 13 insertions(+), 23 deletions(-)

diff --git a/drivers/power/reset/regulator-poweroff.c b/drivers/power/reset/regulator-poweroff.c
index 15160809c423a..fed4978e38580 100644
--- a/drivers/power/reset/regulator-poweroff.c
+++ b/drivers/power/reset/regulator-poweroff.c
@@ -13,18 +13,15 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+#include <linux/reboot.h>
 #include <linux/regulator/consumer.h>
 
 #define TIMEOUT_MS 3000
 
-/*
- * Hold configuration here, cannot be more than one instance of the driver
- * since pm_power_off itself is global.
- */
-static struct regulator *cpu_regulator;
-
-static void regulator_poweroff_do_poweroff(void)
+static int regulator_poweroff_do_poweroff(struct sys_off_data *data)
 {
+	struct regulator *cpu_regulator = data->cb_data;
+
 	if (cpu_regulator && regulator_is_enabled(cpu_regulator))
 		regulator_force_disable(cpu_regulator);
 
@@ -32,30 +29,24 @@ static void regulator_poweroff_do_poweroff(void)
 	mdelay(TIMEOUT_MS);
 
 	WARN_ON(1);
+
+	return NOTIFY_DONE;
 }
 
 static int regulator_poweroff_probe(struct platform_device *pdev)
 {
-	/* If a pm_power_off function has already been added, leave it alone */
-	if (pm_power_off != NULL) {
-		dev_err(&pdev->dev,
-			"%s: pm_power_off function already registered\n",
-			__func__);
-		return -EBUSY;
-	}
+	struct regulator *cpu_regulator;
 
 	cpu_regulator = devm_regulator_get(&pdev->dev, "cpu");
 	if (IS_ERR(cpu_regulator))
 		return PTR_ERR(cpu_regulator);
 
-	pm_power_off = &regulator_poweroff_do_poweroff;
-	return 0;
-}
-
-static void regulator_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &regulator_poweroff_do_poweroff)
-		pm_power_off = NULL;
+	/* Set this handler to low priority to not override an existing handler */
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_LOW,
+					     regulator_poweroff_do_poweroff,
+					     cpu_regulator);
 }
 
 static const struct of_device_id of_regulator_poweroff_match[] = {
@@ -66,7 +57,6 @@ MODULE_DEVICE_TABLE(of, of_regulator_poweroff_match);
 
 static struct platform_driver regulator_poweroff_driver = {
 	.probe = regulator_poweroff_probe,
-	.remove_new = regulator_poweroff_remove,
 	.driver = {
 		.name = "poweroff-regulator",
 		.of_match_table = of_regulator_poweroff_match,
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:22 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:22 -0600
Subject: [PATCH v4 10/19] power: reset: rmobile-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-11-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/rmobile-reset.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c
index 29c17ed2d4de9..80265608c18e0 100644
--- a/drivers/power/reset/rmobile-reset.c
+++ b/drivers/power/reset/rmobile-reset.c
@@ -21,22 +21,14 @@
 
 static void __iomem *sysc_base2;
 
-static int rmobile_reset_handler(struct notifier_block *this,
-				 unsigned long mode, void *cmd)
+static int rmobile_reset_handler(struct sys_off_data *data)
 {
-	pr_debug("%s %lu\n", __func__, mode);
-
 	/* Let's assume we have acquired the HPB semaphore */
 	writel(RESCNT2_PRES, sysc_base2 + RESCNT2);
 
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block rmobile_reset_nb = {
-	.notifier_call = rmobile_reset_handler,
-	.priority = 192,
-};
-
 static int rmobile_reset_probe(struct platform_device *pdev)
 {
 	int error;
@@ -45,7 +37,11 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 	if (IS_ERR(sysc_base2))
 		return PTR_ERR(sysc_base2);
 
-	error = register_restart_handler(&rmobile_reset_nb);
+	error = devm_register_sys_off_handler(&pdev->dev,
+					      SYS_OFF_MODE_RESTART,
+					      SYS_OFF_PRIO_HIGH,
+					      rmobile_reset_handler,
+					      NULL);
 	if (error) {
 		dev_err(&pdev->dev,
 			"cannot register restart handler (err=%d)\n", error);
@@ -55,11 +51,6 @@ static int rmobile_reset_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static void rmobile_reset_remove(struct platform_device *pdev)
-{
-	unregister_restart_handler(&rmobile_reset_nb);
-}
-
 static const struct of_device_id rmobile_reset_of_match[] = {
 	{ .compatible = "renesas,sysc-rmobile", },
 	{ /* sentinel */ }
@@ -68,7 +59,6 @@ MODULE_DEVICE_TABLE(of, rmobile_reset_of_match);
 
 static struct platform_driver rmobile_reset_driver = {
 	.probe = rmobile_reset_probe,
-	.remove_new = rmobile_reset_remove,
 	.driver = {
 		.name = "rmobile_reset",
 		.of_match_table = rmobile_reset_of_match,
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:28 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:28 -0600
Subject: [PATCH v4 16/19] power: reset: gemini-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-17-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/gemini-poweroff.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/power/reset/gemini-poweroff.c b/drivers/power/reset/gemini-poweroff.c
index d309b610142ce..06d6992dec892 100644
--- a/drivers/power/reset/gemini-poweroff.c
+++ b/drivers/power/reset/gemini-poweroff.c
@@ -70,12 +70,9 @@ static irqreturn_t gemini_powerbutton_interrupt(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-/* This callback needs this static local as it has void as argument */
-static struct gemini_powercon *gpw_poweroff;
-
-static void gemini_poweroff(void)
+static int gemini_poweroff(struct sys_off_data *data)
 {
-	struct gemini_powercon *gpw = gpw_poweroff;
+	struct gemini_powercon *gpw = data->cb_data;
 	u32 val;
 
 	dev_crit(gpw->dev, "Gemini power off\n");
@@ -86,6 +83,8 @@ static void gemini_poweroff(void)
 	val &= ~GEMINI_CTRL_ENABLE;
 	val |= GEMINI_CTRL_SHUTDOWN;
 	writel(val, gpw->base + GEMINI_PWC_CTRLREG);
+
+	return NOTIFY_DONE;
 }
 
 static int gemini_poweroff_probe(struct platform_device *pdev)
@@ -148,8 +147,11 @@ static int gemini_poweroff_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	pm_power_off = gemini_poweroff;
-	gpw_poweroff = gpw;
+	ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    gemini_poweroff, gpw);
+	if (ret)
+		return ret;
 
 	dev_info(dev, "Gemini poweroff driver registered\n");
 
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:25 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:25 -0600
Subject: [PATCH v4 13/19] power: reset: msm-poweroff: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-14-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/msm-poweroff.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index 3bf0ea06c4853..c7eb6dc8e90ae 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -14,23 +14,11 @@
 #include <linux/pm.h>
 
 static void __iomem *msm_ps_hold;
-static int deassert_pshold(struct notifier_block *nb, unsigned long action,
-			   void *data)
-{
-	writel(0, msm_ps_hold);
-	mdelay(10000);
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block restart_nb = {
-	.notifier_call = deassert_pshold,
-	.priority = 128,
-};
 
 static int do_msm_poweroff(struct sys_off_data *data)
 {
-	deassert_pshold(&restart_nb, 0, NULL);
+	writel(0, msm_ps_hold);
+	mdelay(10000);
 
 	return NOTIFY_DONE;
 }
@@ -41,7 +29,8 @@ static int msm_restart_probe(struct platform_device *pdev)
 	if (IS_ERR(msm_ps_hold))
 		return PTR_ERR(msm_ps_hold);
 
-	register_restart_handler(&restart_nb);
+	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+				      128, do_msm_poweroff, NULL);
 
 	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
 				      SYS_OFF_PRIO_DEFAULT, do_msm_poweroff,
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:27 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:27 -0600
Subject: [PATCH v4 15/19] power: reset: as3722-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-16-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/as3722-poweroff.c | 30 ++++++++++-----------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/power/reset/as3722-poweroff.c b/drivers/power/reset/as3722-poweroff.c
index ab3350ce2d621..bb26fa6fa67ca 100644
--- a/drivers/power/reset/as3722-poweroff.c
+++ b/drivers/power/reset/as3722-poweroff.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/slab.h>
 
 struct as3722_poweroff {
@@ -18,22 +19,18 @@ struct as3722_poweroff {
 	struct as3722 *as3722;
 };
 
-static struct as3722_poweroff *as3722_pm_poweroff;
-
-static void as3722_pm_power_off(void)
+static int as3722_pm_power_off(struct sys_off_data *data)
 {
+	struct as3722_poweroff *as3722_pm_poweroff = data->cb_data;
 	int ret;
 
-	if (!as3722_pm_poweroff) {
-		pr_err("AS3722 poweroff is not initialised\n");
-		return;
-	}
-
 	ret = as3722_update_bits(as3722_pm_poweroff->as3722,
 		AS3722_RESET_CONTROL_REG, AS3722_POWER_OFF, AS3722_POWER_OFF);
 	if (ret < 0)
 		dev_err(as3722_pm_poweroff->dev,
 			"RESET_CONTROL_REG update failed, %d\n", ret);
+
+	return NOTIFY_DONE;
 }
 
 static int as3722_poweroff_probe(struct platform_device *pdev)
@@ -54,18 +51,14 @@ static int as3722_poweroff_probe(struct platform_device *pdev)
 
 	as3722_poweroff->as3722 = dev_get_drvdata(pdev->dev.parent);
 	as3722_poweroff->dev = &pdev->dev;
-	as3722_pm_poweroff = as3722_poweroff;
-	if (!pm_power_off)
-		pm_power_off = as3722_pm_power_off;
 
-	return 0;
-}
+	return devm_register_sys_off_handler(as3722_poweroff->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_DEFAULT,
+					     as3722_pm_power_off,
+					     as3722_poweroff);
 
-static void as3722_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == as3722_pm_power_off)
-		pm_power_off = NULL;
-	as3722_pm_poweroff = NULL;
+	return 0;
 }
 
 static struct platform_driver as3722_poweroff_driver = {
@@ -73,7 +66,6 @@ static struct platform_driver as3722_poweroff_driver = {
 		.name = "as3722-power-off",
 	},
 	.probe = as3722_poweroff_probe,
-	.remove_new = as3722_poweroff_remove,
 };
 
 module_platform_driver(as3722_poweroff_driver);
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:31 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:31 -0600
Subject: [PATCH v4 19/19] power: reset: syscon-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-20-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

This also makes our data struct per-device and not global, which allows
for more than one instance of this device.

Signed-off-by: Andrew Davis <afd at ti.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/power/reset/syscon-poweroff.c | 30 ++++++++++-----------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
index 19c8da997b4c8..203936f4c544f 100644
--- a/drivers/power/reset/syscon-poweroff.c
+++ b/drivers/power/reset/syscon-poweroff.c
@@ -13,6 +13,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+#include <linux/reboot.h>
 #include <linux/regmap.h>
 
 struct syscon_poweroff_data {
@@ -22,21 +23,24 @@ struct syscon_poweroff_data {
 	u32 mask;
 };
 
-static struct syscon_poweroff_data *data;
-
-static void syscon_poweroff(void)
+static int syscon_poweroff(struct sys_off_data *off_data)
 {
+	struct syscon_poweroff_data *data = off_data->cb_data;
+
 	/* Issue the poweroff */
 	regmap_update_bits(data->map, data->offset, data->mask, data->value);
 
 	mdelay(1000);
 
 	pr_emerg("Unable to poweroff system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int syscon_poweroff_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct syscon_poweroff_data *data;
 	int mask_err, value_err;
 
 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
@@ -73,21 +77,10 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 		data->mask = 0xFFFFFFFF;
 	}
 
-	if (pm_power_off) {
-		dev_err(dev, "pm_power_off already claimed for %ps",
-			pm_power_off);
-		return -EBUSY;
-	}
-
-	pm_power_off = syscon_poweroff;
-
-	return 0;
-}
-
-static void syscon_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == syscon_poweroff)
-		pm_power_off = NULL;
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_DEFAULT,
+					     syscon_poweroff, data);
 }
 
 static const struct of_device_id syscon_poweroff_of_match[] = {
@@ -97,7 +90,6 @@ static const struct of_device_id syscon_poweroff_of_match[] = {
 
 static struct platform_driver syscon_poweroff_driver = {
 	.probe = syscon_poweroff_probe,
-	.remove_new = syscon_poweroff_remove,
 	.driver = {
 		.name = "syscon-poweroff",
 		.of_match_table = syscon_poweroff_of_match,
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:24 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:24 -0600
Subject: [PATCH v4 12/19] power: reset: msm-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-13-afd@ti.com>

Use this helper to register sys_off handler. Drivers should move away from
setting pm_power_off directly as it only allows for one handler. The new
way allows for trying multiple if the first one doesn't work.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/msm-poweroff.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index d96d248a6e25b..3bf0ea06c4853 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -28,9 +28,11 @@ static struct notifier_block restart_nb = {
 	.priority = 128,
 };
 
-static void do_msm_poweroff(void)
+static int do_msm_poweroff(struct sys_off_data *data)
 {
 	deassert_pshold(&restart_nb, 0, NULL);
+
+	return NOTIFY_DONE;
 }
 
 static int msm_restart_probe(struct platform_device *pdev)
@@ -41,7 +43,9 @@ static int msm_restart_probe(struct platform_device *pdev)
 
 	register_restart_handler(&restart_nb);
 
-	pm_power_off = do_msm_poweroff;
+	devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_POWER_OFF,
+				      SYS_OFF_PRIO_DEFAULT, do_msm_poweroff,
+				      NULL);
 
 	return 0;
 }
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:19 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:19 -0600
Subject: [PATCH v4 07/19] power: reset: brcm-kona-reset: Use devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-8-afd@ti.com>

Use device life-cycle managed register function to simplify probe.

Signed-off-by: Andrew Davis <afd at ti.com>
Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
---
 drivers/power/reset/brcm-kona-reset.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/power/reset/brcm-kona-reset.c b/drivers/power/reset/brcm-kona-reset.c
index d05728b1db097..ee3f1bb976530 100644
--- a/drivers/power/reset/brcm-kona-reset.c
+++ b/drivers/power/reset/brcm-kona-reset.c
@@ -15,8 +15,7 @@
 
 static void __iomem *kona_reset_base;
 
-static int kona_reset_handler(struct notifier_block *this,
-				unsigned long mode, void *cmd)
+static int kona_reset_handler(struct sys_off_data *data)
 {
 	/*
 	 * A soft reset is triggered by writing a 0 to bit 0 of the soft reset
@@ -31,18 +30,14 @@ static int kona_reset_handler(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block kona_reset_nb = {
-	.notifier_call = kona_reset_handler,
-	.priority = 128,
-};
-
 static int kona_reset_probe(struct platform_device *pdev)
 {
 	kona_reset_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(kona_reset_base))
 		return PTR_ERR(kona_reset_base);
 
-	return register_restart_handler(&kona_reset_nb);
+	return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+					     128, kona_reset_handler, NULL);
 }
 
 static const struct of_device_id of_match[] = {
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:29 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:29 -0600
Subject: [PATCH v4 17/19] power: reset: restart-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-18-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
---
 drivers/power/reset/restart-poweroff.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
index f4d6004793d3a..fcd588f9ae9d3 100644
--- a/drivers/power/reset/restart-poweroff.c
+++ b/drivers/power/reset/restart-poweroff.c
@@ -14,29 +14,21 @@
 #include <linux/module.h>
 #include <linux/reboot.h>
 
-static void restart_poweroff_do_poweroff(void)
+static int restart_poweroff_do_poweroff(struct sys_off_data *data)
 {
 	reboot_mode = REBOOT_HARD;
 	machine_restart(NULL);
+	return NOTIFY_DONE;
 }
 
 static int restart_poweroff_probe(struct platform_device *pdev)
 {
-	/* If a pm_power_off function has already been added, leave it alone */
-	if (pm_power_off != NULL) {
-		dev_err(&pdev->dev,
-			"pm_power_off function already registered");
-		return -EBUSY;
-	}
-
-	pm_power_off = &restart_poweroff_do_poweroff;
-	return 0;
-}
-
-static void restart_poweroff_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &restart_poweroff_do_poweroff)
-		pm_power_off = NULL;
+	/* Set this handler to low priority to not override an existing handler */
+	return devm_register_sys_off_handler(&pdev->dev,
+					     SYS_OFF_MODE_POWER_OFF,
+					     SYS_OFF_PRIO_LOW,
+					     restart_poweroff_do_poweroff,
+					     NULL);
 }
 
 static const struct of_device_id of_restart_poweroff_match[] = {
@@ -47,7 +39,6 @@ MODULE_DEVICE_TABLE(of, of_restart_poweroff_match);
 
 static struct platform_driver restart_poweroff_driver = {
 	.probe = restart_poweroff_probe,
-	.remove_new = restart_poweroff_remove,
 	.driver = {
 		.name = "poweroff-restart",
 		.of_match_table = of_restart_poweroff_match,
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:30 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:30 -0600
Subject: [PATCH v4 18/19] power: reset: syscon-poweroff: Move device data into a struct
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-19-afd@ti.com>

Currently all these device data elements are top level global variables.
Move these into a struct. This will be used in the next patch when
the global variable usage is removed. Doing this in two steps makes
the patches easier to read.

Signed-off-by: Andrew Davis <afd at ti.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/power/reset/syscon-poweroff.c | 40 ++++++++++++++++-----------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
index 1b2ce7734260c..19c8da997b4c8 100644
--- a/drivers/power/reset/syscon-poweroff.c
+++ b/drivers/power/reset/syscon-poweroff.c
@@ -15,15 +15,19 @@
 #include <linux/pm.h>
 #include <linux/regmap.h>
 
-static struct regmap *map;
-static u32 offset;
-static u32 value;
-static u32 mask;
+struct syscon_poweroff_data {
+	struct regmap *map;
+	u32 offset;
+	u32 value;
+	u32 mask;
+};
+
+static struct syscon_poweroff_data *data;
 
 static void syscon_poweroff(void)
 {
 	/* Issue the poweroff */
-	regmap_update_bits(map, offset, mask, value);
+	regmap_update_bits(data->map, data->offset, data->mask, data->value);
 
 	mdelay(1000);
 
@@ -35,22 +39,26 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	int mask_err, value_err;
 
-	map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
-	if (IS_ERR(map)) {
-		map = syscon_node_to_regmap(dev->parent->of_node);
-		if (IS_ERR(map)) {
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->map = syscon_regmap_lookup_by_phandle(dev->of_node, "regmap");
+	if (IS_ERR(data->map)) {
+		data->map = syscon_node_to_regmap(dev->parent->of_node);
+		if (IS_ERR(data->map)) {
 			dev_err(dev, "unable to get syscon");
-			return PTR_ERR(map);
+			return PTR_ERR(data->map);
 		}
 	}
 
-	if (of_property_read_u32(dev->of_node, "offset", &offset)) {
+	if (of_property_read_u32(dev->of_node, "offset", &data->offset)) {
 		dev_err(dev, "unable to read 'offset'");
 		return -EINVAL;
 	}
 
-	value_err = of_property_read_u32(dev->of_node, "value", &value);
-	mask_err = of_property_read_u32(dev->of_node, "mask", &mask);
+	value_err = of_property_read_u32(dev->of_node, "value", &data->value);
+	mask_err = of_property_read_u32(dev->of_node, "mask", &data->mask);
 	if (value_err && mask_err) {
 		dev_err(dev, "unable to read 'value' and 'mask'");
 		return -EINVAL;
@@ -58,11 +66,11 @@ static int syscon_poweroff_probe(struct platform_device *pdev)
 
 	if (value_err) {
 		/* support old binding */
-		value = mask;
-		mask = 0xFFFFFFFF;
+		data->value = data->mask;
+		data->mask = 0xFFFFFFFF;
 	} else if (mask_err) {
 		/* support value without mask*/
-		mask = 0xFFFFFFFF;
+		data->mask = 0xFFFFFFFF;
 	}
 
 	if (pm_power_off) {
-- 
2.39.2



From afd at ti.com  Mon Feb 12 08:28:23 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:28:23 -0600
Subject: [PATCH v4 11/19] power: reset: mt6323-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <20240212162831.67838-12-afd@ti.com>

Use device life-cycle managed register function to simplify probe and
exit paths.

Signed-off-by: Andrew Davis <afd at ti.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/power/reset/mt6323-poweroff.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c
index 57a63c0ab7fb7..c663347547f97 100644
--- a/drivers/power/reset/mt6323-poweroff.c
+++ b/drivers/power/reset/mt6323-poweroff.c
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/mfd/mt6397/core.h>
 #include <linux/mfd/mt6397/rtc.h>
+#include <linux/reboot.h>
 
 struct mt6323_pwrc {
 	struct device *dev;
@@ -21,11 +22,9 @@ struct mt6323_pwrc {
 	u32 base;
 };
 
-static struct mt6323_pwrc *mt_pwrc;
-
-static void mt6323_do_pwroff(void)
+static int mt6323_do_pwroff(struct sys_off_data *data)
 {
-	struct mt6323_pwrc *pwrc = mt_pwrc;
+	struct mt6323_pwrc *pwrc = data->cb_data;
 	unsigned int val;
 	int ret;
 
@@ -44,6 +43,8 @@ static void mt6323_do_pwroff(void)
 	mdelay(1000);
 
 	WARN_ONCE(1, "Unable to power off system\n");
+
+	return NOTIFY_DONE;
 }
 
 static int mt6323_pwrc_probe(struct platform_device *pdev)
@@ -51,6 +52,7 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
 	struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
 	struct mt6323_pwrc *pwrc;
 	struct resource *res;
+	int ret;
 
 	pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
 	if (!pwrc)
@@ -63,19 +65,18 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
 	pwrc->base = res->start;
 	pwrc->regmap = mt6397_chip->regmap;
 	pwrc->dev = &pdev->dev;
-	mt_pwrc = pwrc;
 
-	pm_power_off = &mt6323_do_pwroff;
+	ret = devm_register_sys_off_handler(pwrc->dev,
+					    SYS_OFF_MODE_POWER_OFF,
+					    SYS_OFF_PRIO_DEFAULT,
+					    mt6323_do_pwroff,
+					    pwrc);
+	if (ret)
+		return dev_err_probe(pwrc->dev, ret, "failed to register power-off handler\n");
 
 	return 0;
 }
 
-static void mt6323_pwrc_remove(struct platform_device *pdev)
-{
-	if (pm_power_off == &mt6323_do_pwroff)
-		pm_power_off = NULL;
-}
-
 static const struct of_device_id mt6323_pwrc_dt_match[] = {
 	{ .compatible = "mediatek,mt6323-pwrc" },
 	{},
@@ -84,7 +85,6 @@ MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match);
 
 static struct platform_driver mt6323_pwrc_driver = {
 	.probe          = mt6323_pwrc_probe,
-	.remove_new     = mt6323_pwrc_remove,
 	.driver         = {
 		.name   = "mt6323-pwrc",
 		.of_match_table = mt6323_pwrc_dt_match,
-- 
2.39.2



From hverkuil at xs4all.nl  Mon Feb 12 08:39:03 2024
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Mon, 12 Feb 2024 17:39:03 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB property
In-Reply-To: <Zco-DQaXqae7B1jt@intel.com>
References: <20231207-kms-hdmi-connector-state-v5-8-6538e19d634d@kernel.org>
 <20240115143308.GA159345@toolbox> <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
Message-ID: <0b3e31e6-34ae-46e3-a43d-bc4895542d8a@xs4all.nl>

On 12/02/2024 16:49, Ville Syrj?l? wrote:
> On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
>> On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
>>> On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
>>>> On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
>>>>> On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
>>>>>> On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
>>>>>>> On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
>>>>>>>>>>>  /**
>>>>>>>>>>>   * DOC: HDMI connector properties
>>>>>>>>>>>   *
>>>>>>>>>>> + * Broadcast RGB
>>>>>>>>>>> + *      Indicates the RGB Quantization Range (Full vs Limited) used.
>>>>>>>>>>> + *      Infoframes will be generated according to that value.
>>>>>>>>>>> + *
>>>>>>>>>>> + *      The value of this property can be one of the following:
>>>>>>>>>>> + *
>>>>>>>>>>> + *      Automatic:
>>>>>>>>>>> + *              RGB Range is selected automatically based on the mode
>>>>>>>>>>> + *              according to the HDMI specifications.
>>>>>>>>>>> + *
>>>>>>>>>>> + *      Full:
>>>>>>>>>>> + *              Full RGB Range is forced.
>>>>>>>>>>> + *
>>>>>>>>>>> + *      Limited 16:235:
>>>>>>>>>>> + *              Limited RGB Range is forced. Unlike the name suggests,
>>>>>>>>>>> + *              this works for any number of bits-per-component.
>>>>>>>>>>> + *
>>>>>>>>>>> + *      Drivers can set up this property by calling
>>>>>>>>>>> + *      drm_connector_attach_broadcast_rgb_property().
>>>>>>>>>>> + *
>>>>>>>>>>
>>>>>>>>>> This is a good time to document this in more detail. There might be two
>>>>>>>>>> different things being affected:
>>>>>>>>>>
>>>>>>>>>> 1. The signalling (InfoFrame/SDP/...)
>>>>>>>>>> 2. The color pipeline processing
>>>>>>>>>>
>>>>>>>>>> All values of Broadcast RGB always affect the color pipeline processing
>>>>>>>>>> such that a full-range input to the CRTC is converted to either full- or
>>>>>>>>>> limited-range, depending on what the monitor is supposed to accept.
>>>>>>>>>>
>>>>>>>>>> When automatic is selected, does that mean that there is no signalling,
>>>>>>>>>> or that the signalling matches what the monitor is supposed to accept
>>>>>>>>>> according to the spec? Also, is this really HDMI specific?
>>>>>>>>>>
>>>>>>>>>> When full or limited is selected and the monitor doesn't support the
>>>>>>>>>> signalling, what happens?
>>>>>>>>>
>>>>>>>>> Forgot to mention: user-space still has no control over RGB vs YCbCr on
>>>>>>>>> the cable, so is this only affecting RGB? If not, how does it affect
>>>>>>>>> YCbCr?
>>>>>>>>
>>>>>>>> So I dug a bit into both the i915 and vc4 drivers, and it looks like if
>>>>>>>> we're using a YCbCr format, i915 will always use a limited range while
>>>>>>>> vc4 will follow the value of the property.
>>>>>>>
>>>>>>> The property is literally called "Broadcast *RGB*".
>>>>>>> That should explain why it's only affecting RGB.
>>>>>>
>>>>>> Right. And the limited range option is called "Limited 16:235" despite
>>>>>> being usable on bpc > 8 bits. Naming errors occurs, and history happens
>>>>>> to make names inconsistent too, that's fine and not an argument in
>>>>>> itself.
>>>>>>
>>>>>>> Full range YCbCr is a much rarer beast so we've never bothered
>>>>>>> to enable it.
>>>>>>
>>>>>> vc4 supports it.
>>>>>
>>>>> Someone implemented it incorrectly then.
>>>>
>>>> Incorrectly according to what documentation / specification? I'm sorry,
>>>> but I find it super ironic that i915 gets to do its own thing, not
>>>> document any of it, and when people try to clean things up they get told
>>>> that we got it all wrong.
>>>
>>> FWIW, this was an i915 property and if another driver uses the same
>>> property name it must have the same behavior. Yes, it isn't standardized
>>> and yes, it's not documented (hence this effort here) but it's still on
>>> vc4 to make the property compatible.
>>
>> How is it not compatible? It's a superset of what i915 provides, but
>> it's strictly compatible with it.
> 
> No it is not. Eg. what happens if you set the thing to full range for
> RGB (which you must on many broken monitors), and then the kernel
> automagically switches to YCbCr (for whatever reason) but the monitor
> doesn't support full range YCbCr? Answer: you get crap output.

The Broadcast RGB setting is really specific to RGB output. That's where
you need it, since due to messed up standards in the past it is common to
have to override this.

For YCbCr it is not needed since it is always limited range in practice.
If there is ever a need to support full range YCbCr, then a new "Broadcast YCbCr"
setting should be created.

The only place were you see full range YCbCr being used is in combination with
JPEG codecs, since JPEG uses full range YCbCr. But it does not normally occur
on video output interfaces.

Regards,

	Hans

> 
>>
>> I would argue that i915 is the broken one since userspace could force a
>> full range output, but since the driver takes the YUV vs RGB decision
>> itself and only supports limited range for YUV, the driver would
>> effectively ignore that user-space property, without the user-space
>> being able to tell it was ignored in the first place.
>>
>>> Trying to make the property handle YCbCr is very much in the "let's try
>>> to fix the property" territory that I want to avoid, so I'm in favor of
>>> adjusting vc4.
>>
>> Breaking the ABI in the process. For something that is explicitly
>> supported by the spec, the driver, and the hardware. On a property that
>> never said it wasn't meant to be used that way, and with semantics based
>> on a driver that never provided a way to check those restrictions in the
>> first place.
>>
>> And it's not like i915 is going to use that code anyway.
>>
>> Maxime
> 
> 
> 



From josua at solid-run.com  Mon Feb 12 08:39:35 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 12 Feb 2024 16:39:35 +0000
Subject: [PATCH v5 0/5] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
In-Reply-To: <359993c5-3387-443c-8cef-30ee7ad1f521@ti.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
 <359993c5-3387-443c-8cef-30ee7ad1f521@ti.com>
Message-ID: <b918364e-cfca-4342-acc2-2b51bad75596@solid-run.com>

Hi Vignesh,

Am 12.02.24 um 05:10 schrieb Vignesh Raghavendra:
> Hi Josua,
>
> On 11/02/24 20:37, Josua Mayer wrote:
>> This series adds DT bindings and dts descriptions for SolidRun AM642
>> based SoM and Hummingboard EVB.
>>
>> Additionally a commit from downstream vendor kernel are included,
>> enhancing support for pru based ethernet.
>> I wasn't sure how to properly annotate it in commit description /
>> signed-off area ...:
>>
>> 1. add description for "Industrial Ethernet Peripherals" (IEP) to am64
>>    https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/commit/arch/arm64/boot/dts/ti/k3-am64-main.dtsi?h=ti-linux-6.1.y-cicd&id=5afb73d82a014b59462162d960b350b8c58e5ae6
>>    IEP is already supported in-tree by a driver, and used in
>>    k3-am65-main.dtsi.
>>
>> Unfortunately dtbs_check reported many problems, I put some remarks:
>>
>> - 'mux-controller' does not match any of the regexes
>>   The expectation seems to be that a mux-controller at minimum has an
>>   address, something to put behind an @. However this is a gpio mux, not
>>   sure how to name it better.
>>
> I don't see this warning locally. Are you using updated dt-schema?
pip3 install dtschema --upgrade
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: dtschema in ~/.local/lib/python3.11/site-packages (2023.11)

Re-Tested on 6.8-rc1

> reg
> is not necessary gpio-mux as per gpio-mux.yaml
The error is not about reg property, it is about the node name:

mux-controller {
??? compatible = "gpio-mux";
??? ...
};

? DTC_CHK arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb
.../arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb: syscon at 43000000: 'mux-controller' does not match any of the regexes: '^chipid@[0-9a-f]+$', '^clock-controller@[0-9a-f]+$', '^mux-controller@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pinctrl-[0-9]+'
?????? from schema $id: http://devicetree.org/schemas/mfd/ti,j721e-system-controller.yaml#
>
>> - unevaluated properties: interrupts, interrupt-parent
>>   sensors and flash yaml are missing interrupt descriptions, but these
>>   parts definitely have an interrupt signal in this solidrun board.
>>
> Please add them to appropriate schema as necessary
Okay.
Looks like it is only two:
.../arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb: humidity-sensor at 41: 'interrupt-parent', 'interrupts' do not match any of the regexes: 'pinctrl-[0-9]+'
???????from schema $id: http://devicetree.org/schemas/iio/humidity/ti,hdc2010.yaml#
.../arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb: flash at 0: Unevaluated properties are not allowed ('interrupt-parent', 'interrupts' were unexpected)
???????from schema $id: http://devicetree.org/schemas/mtd/jedec,spi-nor.yaml#
>
>> - wrong names for pinctrl nodes
>>   Other TI DTSs consistently end with *-pins-default. Should a different
>>   naming convention be used?
>>
> No, pinctrl nodes need to end in -pins. All TI boards have been updated
> to new schema [0] and sysconfig tool on dev.ti.com/sysconfig generates
> appropriately. Please fix
Okay, will do ...
>
>
>> - cdns,phy-type required property
>>   inherited from k3-am64-main.dtsi
>>   there is a PHY_NONE value in dt-bindings/phy/phy.h,
>>   but not allowed in phy-cadence-torrent.yaml
>>
> Sorry, I didnt get what's the issue wrt cdns,phy-type ?
There were two issues, but they both disappeared as per 6.8-rc1 :)
>
>
> Note, I really don't want to accept patches that add new dtbs_check
> issues especially for nodes that already have YAML bindings. Please
> update the .yaml files as necessary.
I have succeeded locally getting rid of all but one, the node name of mux-controller mentioned above.
Will include yaml patches in next version.
>
> [0]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a49568115143435390f20965902809471b6f830c
>
>

From romain.gantois at bootlin.com  Mon Feb 12 08:42:08 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Mon, 12 Feb 2024 17:42:08 +0100
Subject: [PATCH net-next v3 1/7] net: phylink: add PHY_F_RXC_ALWAYS_ON to
 PHY dev flags
In-Reply-To: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
References: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
Message-ID: <20240212-rxc_bugfix-v3-1-e9f2eb6b3b05@bootlin.com>

From: Russell King <linux at armlinux.org.uk>

Some MAC controllers (e.g. stmmac) require their connected PHY to
continuously provide a receive clock signal. This can cause issues in two
cases:

  1. The clock signal hasn't been started yet by the time the MAC driver
     initializes its hardware. This can make the initialization fail, as in
      the case of the rzn1 GMAC1 driver.
  2. The clock signal is cut during a power saving event. By the time the
     MAC is brought back up, the clock signal is still not active since
     phylink_start hasn't been called yet. This brings us back to case 1.

If a PHY driver reads this flag, it should ensure that the receive clock
signal is started as soon as possible, and that it isn't brought down when
the PHY goes into suspend.

Signed-off-by: Russell King <linux at armlinux.org.uk>
[rgantois: commit log]
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/phy/phylink.c | 10 +++++++++-
 include/linux/phy.h       |  1 +
 include/linux/phylink.h   |  4 ++++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 503fd7c40523..2bb583543dea 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1923,6 +1923,8 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
 static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,
 			      phy_interface_t interface)
 {
+	u32 flags = 0;
+
 	if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED ||
 		    (pl->cfg_link_an_mode == MLO_AN_INBAND &&
 		     phy_interface_mode_is_8023z(interface) && !pl->sfp_bus)))
@@ -1931,7 +1933,10 @@ static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,
 	if (pl->phydev)
 		return -EBUSY;
 
-	return phy_attach_direct(pl->netdev, phy, 0, interface);
+	if (pl->config->mac_requires_rxc)
+		flags |= PHY_F_RXC_ALWAYS_ON;
+
+	return phy_attach_direct(pl->netdev, phy, flags, interface);
 }
 
 /**
@@ -2034,6 +2039,9 @@ int phylink_fwnode_phy_connect(struct phylink *pl,
 		pl->link_config.interface = pl->link_interface;
 	}
 
+	if (pl->config->mac_requires_rxc)
+		flags |= PHY_F_RXC_ALWAYS_ON;
+
 	ret = phy_attach_direct(pl->netdev, phy_dev, flags,
 				pl->link_interface);
 	phy_device_free(phy_dev);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 2249cdb5957a..1fef852634bd 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -771,6 +771,7 @@ struct phy_device {
 
 /* Generic phy_device::dev_flags */
 #define PHY_F_NO_IRQ		0x80000000
+#define PHY_F_RXC_ALWAYS_ON	0x40000000
 
 static inline struct phy_device *to_phy_device(const struct device *dev)
 {
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 6ba411732a0d..019993e5f570 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -138,6 +138,9 @@ enum phylink_op_type {
  * @poll_fixed_state: if true, starts link_poll,
  *		      if MAC link is at %MLO_AN_FIXED mode.
  * @mac_managed_pm: if true, indicate the MAC driver is responsible for PHY PM.
+ * @mac_requires_rxc: if true, the MAC always requires a receive clock from PHY.
+ *                    The PHY driver should start the clock signal as soon as
+ *                    possible and avoid stopping it during suspend events.
  * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND
  * @get_fixed_state: callback to execute to determine the fixed link state,
  *		     if MAC link is at %MLO_AN_FIXED mode.
@@ -150,6 +153,7 @@ struct phylink_config {
 	enum phylink_op_type type;
 	bool poll_fixed_state;
 	bool mac_managed_pm;
+	bool mac_requires_rxc;
 	bool ovr_an_inband;
 	void (*get_fixed_state)(struct phylink_config *config,
 				struct phylink_link_state *state);

-- 
2.43.0



From romain.gantois at bootlin.com  Mon Feb 12 08:42:07 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Mon, 12 Feb 2024 17:42:07 +0100
Subject: [PATCH net-next v3 0/7] Fix missing PHY-to-MAC RX clock
Message-ID: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>

Hello everyone,

This is version three of my series that addresses the issue with some MAC/PHY
combinations.

Notable changes in v3:
  - Removed the "interface" argument from pcs_init().
  - Added a kernel doc for pcs_init().

Notable changes in v2:
  - Introduced a pcs op for initializing hardware required for MAC
    initialization, instead of using phylink_validate() for this purpose.
  - Refactored stmmac to use a generic PCS reference in mac_device_info
    instead of a model-specific field.

There is an issue with some stmmac/PHY combinations that has been reported
some time ago in a couple of different series:

Clark Wang's report:
https://lore.kernel.org/all/20230202081559.3553637-1-xiaoning.wang at nxp.com/
Cl?ment L?ger's report:
https://lore.kernel.org/linux-arm-kernel/20230116103926.276869-4-clement.leger at bootlin.com/

Stmmac controllers require an RX clock signal from the MII bus to perform
their hardware initialization successfully. This causes issues with some
PHY/PCS devices. If these devices do not bring the clock signal up before
the MAC driver initializes its hardware, then said initialization will
fail. This can happen at probe time or when the system wakes up from a
suspended state.

This series introduces new flags for phy_device and phylink_pcs. These
flags allow MAC drivers to signal to PHY/PCS drivers that the RX clock
signal should be enabled as soon as possible, and that it should always
stay enabled.

I have included specific uses of these flags that fix the RZN1 GMAC1 stmmac
driver that I am currently working on and that is not yet upstream. I have
also included changes to the at803x PHY driver that should fix the issue
that Clark Wang was having.

Clark, could you please confirm that this series fixes your issue with the
at803x PHY?

Best Regards,

Romain

Romain Gantois (2):
  net: phy: add rxc_always_on flag to phylink_pcs
  net: pcs: rzn1-miic: Init RX clock early if MAC requires it

Russell King (3):
  net: phy: add PHY_F_RXC_ALWAYS_ON to PHY dev flags
  net: stmmac: Signal to PHY/PCS drivers to keep RX clock on
  net: phy: at803x: Avoid hibernating if MAC requires RX clock

 .../net/ethernet/stmicro/stmmac/stmmac_main.c  |  5 +++++
 drivers/net/pcs/pcs-rzn1-miic.c                | 18 +++++++++++++-----
 drivers/net/phy/at803x.c                       |  3 ++-
 drivers/net/phy/phylink.c                      | 13 ++++++++++++-
 include/linux/phy.h                            |  1 +
 include/linux/phylink.h                        |  9 +++++++++
 6 files changed, 42 insertions(+), 7 deletions(-)

--
2.43.0

---
- Link to v2: https://lore.kernel.org/r/20240130-rxc_bugfix-v2-0-5e6c3168e5f0 at bootlin.com

---
Maxime Chevallier (1):
      net: stmmac: don't rely on lynx_pcs presence to check for a PHY

Romain Gantois (4):
      net: phylink: add rxc_always_on flag to phylink_pcs
      net: stmmac: Support a generic PCS field in mac_device_info
      net: stmmac: Signal to PHY/PCS drivers to keep RX clock on
      net: pcs: rzn1-miic: Init RX clock early if MAC requires it

Russell King (2):
      net: phylink: add PHY_F_RXC_ALWAYS_ON to PHY dev flags
      net: phy: qcom: at803x: Avoid hibernating if MAC requires RX clock

 drivers/net/ethernet/stmicro/stmmac/common.h       |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  8 ++---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 15 ++++----
 drivers/net/pcs/pcs-rzn1-miic.c                    | 27 ++++++++++++++
 drivers/net/phy/phylink.c                          | 24 ++++++++++++-
 drivers/net/phy/qcom/at803x.c                      |  3 +-
 include/linux/phy.h                                |  1 +
 include/linux/phylink.h                            | 42 ++++++++++++++++++++++
 8 files changed, 109 insertions(+), 13 deletions(-)
---
base-commit: 0f37666d87d2dea42ec21776c3d562b7cbd71612
change-id: 20240126-rxc_bugfix-d47b3b1a374f

Best regards,
-- 
Romain Gantois <romain.gantois at bootlin.com>



From romain.gantois at bootlin.com  Mon Feb 12 08:42:11 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Mon, 12 Feb 2024 17:42:11 +0100
Subject: [PATCH net-next v3 4/7] net: stmmac: Support a generic PCS field
 in mac_device_info
In-Reply-To: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
References: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
Message-ID: <20240212-rxc_bugfix-v3-4-e9f2eb6b3b05@bootlin.com>

Global stmmac support for early initialization of PCS devices requires a
generic PCS reference that can be passed to phylink_pcs_pre_init().
Currently, the mac_device_info struct contains only one PCS field, which is
specific to the Lynx model.

As PCS models are hardware-specific, it is more appropriate to have a
generic PCS field in the mac_device_info struct.

Refactor the lynx_pcs field into a generic phylink_pcs field.

Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h        | 2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 8 ++++----
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c   | 5 +----
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index a6fefe675ef1..f55cf09f0783 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -593,7 +593,7 @@ struct mac_device_info {
 	const struct stmmac_mmc_ops *mmc;
 	const struct stmmac_est_ops *est;
 	struct dw_xpcs *xpcs;
-	struct phylink_pcs *lynx_pcs; /* Lynx external PCS */
+	struct phylink_pcs *phylink_pcs;
 	struct mii_regs mii;	/* MII register Addresses */
 	struct mac_link link;
 	void __iomem *pcsr;     /* vpointer to device CSRs */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 68f85e4605cb..12b4a80ea3aa 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -479,9 +479,9 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
 			goto err_dvr_remove;
 		}
 
-		stpriv->hw->lynx_pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
-		if (IS_ERR(stpriv->hw->lynx_pcs)) {
-			ret = PTR_ERR(stpriv->hw->lynx_pcs);
+		stpriv->hw->phylink_pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
+		if (IS_ERR(stpriv->hw->phylink_pcs)) {
+			ret = PTR_ERR(stpriv->hw->phylink_pcs);
 			goto err_dvr_remove;
 		}
 	}
@@ -498,7 +498,7 @@ static void socfpga_dwmac_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct stmmac_priv *priv = netdev_priv(ndev);
-	struct phylink_pcs *pcs = priv->hw->lynx_pcs;
+	struct phylink_pcs *pcs = priv->hw->phylink_pcs;
 
 	stmmac_pltfr_remove(pdev);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 47cd8666af43..ec4f6377b5ee 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -944,10 +944,7 @@ static struct phylink_pcs *stmmac_mac_select_pcs(struct phylink_config *config,
 	if (priv->hw->xpcs)
 		return &priv->hw->xpcs->pcs;
 
-	if (priv->hw->lynx_pcs)
-		return priv->hw->lynx_pcs;
-
-	return NULL;
+	return priv->hw->phylink_pcs;
 }
 
 static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,

-- 
2.43.0



From romain.gantois at bootlin.com  Mon Feb 12 08:42:10 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Mon, 12 Feb 2024 17:42:10 +0100
Subject: [PATCH net-next v3 3/7] net: stmmac: don't rely on lynx_pcs
 presence to check for a PHY
In-Reply-To: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
References: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
Message-ID: <20240212-rxc_bugfix-v3-3-e9f2eb6b3b05@bootlin.com>

From: Maxime Chevallier <maxime.chevallier at bootlin.com>

When initializing attached PHYs, there are some cases where we don't expect
any PHY to be connected. The logic uses conditions based on various local
PCS configuration, but also calls-in phylink_expects_phy() via
stmmac_init_phy(), which is enough to ensure we don't try to initialize a
PHY when using a Lynx PCS, as long as we have the phy_interface set to a
802.3z mode and are using inband negociation.

Drop the lynx check, making the stmmac generic code more pcs_lynx-agnostic.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
[rgantois: commit log]
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9159d93ceb03..47cd8666af43 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3959,8 +3959,7 @@ static int __stmmac_open(struct net_device *dev,
 	if (priv->hw->pcs != STMMAC_PCS_TBI &&
 	    priv->hw->pcs != STMMAC_PCS_RTBI &&
 	    (!priv->hw->xpcs ||
-	     xpcs_get_an_mode(priv->hw->xpcs, mode) != DW_AN_C73) &&
-	    !priv->hw->lynx_pcs) {
+	     xpcs_get_an_mode(priv->hw->xpcs, mode) != DW_AN_C73)) {
 		ret = stmmac_init_phy(dev);
 		if (ret) {
 			netdev_err(priv->dev,

-- 
2.43.0



From romain.gantois at bootlin.com  Mon Feb 12 08:42:09 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Mon, 12 Feb 2024 17:42:09 +0100
Subject: [PATCH net-next v3 2/7] net: phylink: add rxc_always_on flag to
 phylink_pcs
In-Reply-To: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
References: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
Message-ID: <20240212-rxc_bugfix-v3-2-e9f2eb6b3b05@bootlin.com>

Some MAC drivers (e.g. stmmac) require a continuous receive clock signal to
be generated by a PCS that is handled by a standalone PCS driver.

Such a PCS driver does not have access to a PHY device, thus cannot check
the PHY_F_RXC_ALWAYS_ON flag. They cannot check max_requires_rxc in the
phylink config either, since it is a private member. Therefore, a new flag
is needed to signal to the PCS that it should keep the RX clock signal up
at all times.

Suggested-by: Russell King <linux at armlinux.org.uk>
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/phy/phylink.c | 14 ++++++++++++++
 include/linux/phylink.h   | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 2bb583543dea..dad7462996ab 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1042,6 +1042,20 @@ static void phylink_pcs_poll_start(struct phylink *pl)
 		mod_timer(&pl->link_poll, jiffies + HZ);
 }
 
+int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs)
+{
+	int ret = 0;
+
+	/* Signal to PCS driver that MAC requires RX clock for init */
+	if (pl->config->mac_requires_rxc)
+		pcs->rxc_always_on = true;
+
+	if (pcs->ops->pcs_pre_init)
+		ret = pcs->ops->pcs_pre_init(pcs);
+
+	return ret;
+}
+
 static void phylink_mac_config(struct phylink *pl,
 			       const struct phylink_link_state *state)
 {
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 019993e5f570..f6ef5bc82179 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -396,6 +396,10 @@ struct phylink_pcs_ops;
  * @phylink: pointer to &struct phylink_config
  * @neg_mode: provide PCS neg mode via "mode" argument
  * @poll: poll the PCS for link changes
+ * @rxc_always_on: The MAC driver requires the reference clock
+ *                 to always be on. Standalone PCS drivers which
+ *                 do not have access to a PHY device can check
+ *                 this instead of PHY_F_RXC_ALWAYS_ON.
  *
  * This structure is designed to be embedded within the PCS private data,
  * and will be passed between phylink and the PCS.
@@ -408,6 +412,7 @@ struct phylink_pcs {
 	struct phylink *phylink;
 	bool neg_mode;
 	bool poll;
+	bool rxc_always_on;
 };
 
 /**
@@ -422,6 +427,8 @@ struct phylink_pcs {
  * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
  * @pcs_link_up: program the PCS for the resolved link configuration
  *               (where necessary).
+ * @pcs_pre_init: configure PCS components necessary for MAC hardware
+ *                initialization e.g. RX clock for stmmac.
  */
 struct phylink_pcs_ops {
 	int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
@@ -441,6 +448,7 @@ struct phylink_pcs_ops {
 	void (*pcs_an_restart)(struct phylink_pcs *pcs);
 	void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode,
 			    phy_interface_t interface, int speed, int duplex);
+	int (*pcs_pre_init)(struct phylink_pcs *pcs);
 };
 
 #if 0 /* For kernel-doc purposes only. */
@@ -549,6 +557,34 @@ void pcs_an_restart(struct phylink_pcs *pcs);
  */
 void pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
 		 phy_interface_t interface, int speed, int duplex);
+
+/**
+ * pcs_pre_init() - Configure PCS components necessary for MAC initialization
+ * @pcs: a pointer to a &struct phylink_pcs.
+ *
+ * This function can be called by MAC drivers through the
+ * phylink_pcs_pre_init() wrapper, before their hardware is initialized. It
+ * should not be called after the link is brought up, as reconfiguring the PCS
+ * at this point could break the link.
+ *
+ * Some MAC devices require specific hardware initialization to be performed by
+ * their associated PCS device before they can properly initialize their own
+ * hardware. An example of this is the initialization of stmmac controllers,
+ * which requires an active REF_CLK signal to be provided by the PHY/PCS.
+ *
+ * By calling phylink_pcs_pre_init(), MAC drivers can ensure that the PCS is
+ * setup in a way that allows for successful hardware initialization.
+ *
+ * The specific configuration performed by pcs_pre_init() is dependent on the
+ * model of PCS and the requirements of the MAC device attached to it. PCS
+ * driver authors should consider whether their target device is to be used in
+ * conjunction with a MAC device whose driver calls phylink_pcs_pre_init(). MAC
+ * driver authors should document their requirements for the PCS
+ * pre-initialization.
+ *
+ */
+int pcs_config(struct phylink_pcs *pcs);
+
 #endif
 
 struct phylink *phylink_create(struct phylink_config *,
@@ -568,6 +604,8 @@ void phylink_disconnect_phy(struct phylink *);
 void phylink_mac_change(struct phylink *, bool up);
 void phylink_pcs_change(struct phylink_pcs *, bool up);
 
+int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs);
+
 void phylink_start(struct phylink *);
 void phylink_stop(struct phylink *);
 

-- 
2.43.0



From romain.gantois at bootlin.com  Mon Feb 12 08:42:13 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Mon, 12 Feb 2024 17:42:13 +0100
Subject: [PATCH net-next v3 6/7] net: phy: qcom: at803x: Avoid hibernating
 if MAC requires RX clock
In-Reply-To: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
References: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
Message-ID: <20240212-rxc_bugfix-v3-6-e9f2eb6b3b05@bootlin.com>

From: Russell King <linux at armlinux.org.uk>

Stmmac controllers connected to an at803x PHY cannot resume properly after
suspend when WoL is enabled. This happens because the MAC requires an RX
clock generated by the PHY to initialize its hardware properly. But the RX
clock is cut when the PHY suspends and isn't brought up until the MAC
driver resumes the phylink.

Prevent the at803x PHY driver from going into suspend if the attached MAC
driver always requires an RX clock signal.

Reported-by: Clark Wang <xiaoning.wang at nxp.com>
Link: https://lore.kernel.org/all/20230202081559.3553637-1-xiaoning.wang at nxp.com/
Signed-off-by: Russell King <linux at armlinux.org.uk>
[rgantois: commit log]
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/phy/qcom/at803x.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/qcom/at803x.c b/drivers/net/phy/qcom/at803x.c
index 4717c59d51d0..2a221b81cf37 100644
--- a/drivers/net/phy/qcom/at803x.c
+++ b/drivers/net/phy/qcom/at803x.c
@@ -426,7 +426,8 @@ static int at803x_hibernation_mode_config(struct phy_device *phydev)
 	/* The default after hardware reset is hibernation mode enabled. After
 	 * software reset, the value is retained.
 	 */
-	if (!(priv->flags & AT803X_DISABLE_HIBERNATION_MODE))
+	if (!(priv->flags & AT803X_DISABLE_HIBERNATION_MODE) &&
+	    !(phydev->dev_flags & PHY_F_RXC_ALWAYS_ON))
 		return 0;
 
 	return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,

-- 
2.43.0



From romain.gantois at bootlin.com  Mon Feb 12 08:42:14 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Mon, 12 Feb 2024 17:42:14 +0100
Subject: [PATCH net-next v3 7/7] net: pcs: rzn1-miic: Init RX clock early
 if MAC requires it
In-Reply-To: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
References: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
Message-ID: <20240212-rxc_bugfix-v3-7-e9f2eb6b3b05@bootlin.com>

The GMAC1 controller in the RZN1 IP requires the RX MII clock signal to be
started before it initializes its own hardware, thus before it calls
phylink_start.

Check the rxc_always_on pcs flag and enable the clock signal during the
link validation phase.

Reported-by: Cl?ment L?ger <clement.leger at bootlin.com>
Link: https://lore.kernel.org/linux-arm-kernel/20230116103926.276869-4-clement.leger at bootlin.com/
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/pcs/pcs-rzn1-miic.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c
index d93f84fbb1fd..b0d9736c678e 100644
--- a/drivers/net/pcs/pcs-rzn1-miic.c
+++ b/drivers/net/pcs/pcs-rzn1-miic.c
@@ -279,10 +279,37 @@ static int miic_validate(struct phylink_pcs *pcs, unsigned long *supported,
 	return -EINVAL;
 }
 
+static int miic_pre_init(struct phylink_pcs *pcs)
+{
+	struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs);
+	struct miic *miic = miic_port->miic;
+	u32 val;
+
+	/* Start RX clock if required */
+	if (pcs->rxc_always_on) {
+		/* In MII through mode, the clock signals will be driven by the
+		 * external PHY, which might not be initialized yet. Set RMII
+		 * as default mode to ensure that a reference clock signal is
+		 * generated.
+		 */
+		miic_port->interface = PHY_INTERFACE_MODE_RMII;
+
+		val = FIELD_PREP(MIIC_CONVCTRL_CONV_MODE, CONV_MODE_RMII);
+		miic_reg_rmw(miic, MIIC_CONVCTRL(miic_port->port),
+			     MIIC_CONVCTRL_CONV_MODE,
+			     val);
+
+		miic_converter_enable(miic, miic_port->port, 1);
+	}
+
+	return 0;
+}
+
 static const struct phylink_pcs_ops miic_phylink_ops = {
 	.pcs_validate = miic_validate,
 	.pcs_config = miic_config,
 	.pcs_link_up = miic_link_up,
+	.pcs_pre_init = miic_pre_init,
 };
 
 struct phylink_pcs *miic_create(struct device *dev, struct device_node *np)

-- 
2.43.0



From romain.gantois at bootlin.com  Mon Feb 12 08:42:12 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Mon, 12 Feb 2024 17:42:12 +0100
Subject: [PATCH net-next v3 5/7] net: stmmac: Signal to PHY/PCS drivers to
 keep RX clock on
In-Reply-To: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
References: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
Message-ID: <20240212-rxc_bugfix-v3-5-e9f2eb6b3b05@bootlin.com>

There is a reocurring issue with stmmac controllers where the MAC fails to
initialize its hardware if an RX clock signal isn't provided on the MAC/PHY
link.

This causes issues when PHY or PCS devices either go into suspend while
cutting the RX clock or do not bring the clock signal up early enough for
the MAC to initialize successfully.

Set the mac_requires_rxc flag in the stmmac phylink config so that PHY/PCS
drivers know to keep the RX clock up at all times.

Reported-by: Clark Wang <xiaoning.wang at nxp.com>
Link: https://lore.kernel.org/all/20230202081559.3553637-1-xiaoning.wang at nxp.com/
Reported-by: Cl?ment L?ger <clement.leger at bootlin.com>
Link: https://lore.kernel.org/linux-arm-kernel/20230116103926.276869-4-clement.leger at bootlin.com/
Suggested-by: Russell King <linux at armlinux.org.uk>
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ec4f6377b5ee..caf71a502ff2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1218,6 +1218,9 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 	priv->phylink_config.type = PHYLINK_NETDEV;
 	priv->phylink_config.mac_managed_pm = true;
 
+	/* Stmmac always requires an RX clock for hardware initialization */
+	priv->phylink_config.mac_requires_rxc = true;
+
 	mdio_bus_data = priv->plat->mdio_bus_data;
 	if (mdio_bus_data)
 		priv->phylink_config.ovr_an_inband =
@@ -3407,6 +3410,10 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
 	u32 chan;
 	int ret;
 
+	/* Make sure RX clock is enabled */
+	if (priv->hw->phylink_pcs)
+		phylink_pcs_pre_init(priv->phylink, priv->hw->phylink_pcs);
+
 	/* DMA initialization and SW reset */
 	ret = stmmac_init_dma_engine(priv);
 	if (ret < 0) {

-- 
2.43.0



From ldearquer at gmail.com  Mon Feb 12 08:44:43 2024
From: ldearquer at gmail.com (Luis de Arquer)
Date: Mon, 12 Feb 2024 17:44:43 +0100
Subject: [PATCH v2 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>
References: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
	 <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>
Message-ID: <61af7b121b23fe8ed06df5348692f862b9b125bf.camel@gmail.com>

Hi Cristian,

On Mon, 2024-02-05 at 13:24 +0200, Cristian Ciocaltea wrote:
> +
> +static bool hdptx_phy_clk_pll_calc(unsigned int data_rate,
> +				   struct ropll_config *cfg)
> +{
> +	const unsigned int fout = data_rate / 2, fref = 24000;
> +	unsigned long k = 0, lc, k_sub, lc_sub;
> +	unsigned int fvco, sdc;
> +	u32 mdiv, sdiv, n = 8;
> +
> +	for (sdiv = 16; sdiv >= 1; sdiv--) {
> +		if (sdiv % 2 && sdiv != 1)
> +			continue;
> +
> +		fvco = fout * sdiv;
> +
> +		if (fvco < 2000000 || fvco > 4000000)
> +			continue;
> +

What about adding a check to data_rate, maybe like

if (fout > 0x0FFFFFFF)
	return false;

or similar, before the for loop, to keep the multiplication safe?

Right now it would be redundant, given that data_rate was, at some
point, encoded in 28 bits within bus_width. But can prevent future pain,
especially after changing to phy_configure_opts_hdmi.

Luis


From Dave.Martin at arm.com  Mon Feb 12 08:50:49 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Mon, 12 Feb 2024 16:50:49 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
Message-ID: <ZcpMabqH+VZv6RCZ@e133344.arm.com>

On Sat, Feb 03, 2024 at 12:16:49PM +0000, Mark Brown wrote:
> Doug Anderson observed that ChromeOS crashes are being reported which
> include failing allocations of order 7 during core dumps due to ptrace
> allocating storage for regsets:
> 
>   chrome: page allocation failure: order:7,
>           mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
>           nodemask=(null),cpuset=urgent,mems_allowed=0
>    ...
>   regset_get_alloc+0x1c/0x28
>   elf_core_dump+0x3d8/0xd8c
>   do_coredump+0xeb8/0x1378
> 
> with further investigation showing that this is:
> 
>    [   66.957385] DOUG: Allocating 279584 bytes
> 
> which is the maximum size of the SVE regset. As Doug observes it is not
> entirely surprising that such a large allocation of contiguous memory might
> fail on a long running system.
> 
> The SVE regset is currently sized to hold SVE registers with a VQ of
> SVE_VQ_MAX which is 512, substantially more than the architectural maximum
> of 16 which we might see even in a system emulating the limits of the
> architecture. Since we don't expose the size we tell the regset core
> externally let's define ARCH_SVE_VQ_MAX with the actual architectural
> maximum and use that for the regset, we'll still overallocate most of the
> time but much less so which will be helpful even if the core is fixed to
> not require contiguous allocations.
> 
> We could also teach the ptrace core about runtime discoverable regset sizes
> but that would be a more invasive change and this is being observed in
> practical systems.
> 
> Reported-by: Doug Anderson <dianders at chromium.org>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> We should probably also use the actual architectural limit for the
> bitmasks we use in the VL enumeration code, though that's both a little
> bit more involved and less immediately a problem.
> ---
>  arch/arm64/include/asm/fpsimd.h | 10 +++++-----
>  arch/arm64/kernel/ptrace.c      |  3 ++-
>  2 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index 50e5f25d3024..cf5f31181bc8 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -62,12 +62,12 @@ static inline void cpacr_restore(unsigned long cpacr)
>   * When we defined the maximum SVE vector length we defined the ABI so
>   * that the maximum vector length included all the reserved for future
>   * expansion bits in ZCR rather than those just currently defined by
> - * the architecture. While SME follows a similar pattern the fact that
> - * it includes a square matrix means that any allocations that attempt
> - * to cover the maximum potential vector length (such as happen with
> - * the regset used for ptrace) end up being extremely large. Define
> - * the much lower actual limit for use in such situations.
> + * the architecture.  Using this length to allocate worst size buffers
> + * results in excessively large allocations, and this effect is even
> + * more pronounced for SME due to ZA.  Define more suitable VLs for
> + * these situations.
>   */
> +#define ARCH_SVE_VQ_MAX 16
>  #define SME_VQ_MAX	16
>  
>  struct task_struct;
> diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
> index dc6cf0e37194..e3bef38fc2e2 100644
> --- a/arch/arm64/kernel/ptrace.c
> +++ b/arch/arm64/kernel/ptrace.c
> @@ -1500,7 +1500,8 @@ static const struct user_regset aarch64_regsets[] = {
>  #ifdef CONFIG_ARM64_SVE
>  	[REGSET_SVE] = { /* Scalable Vector Extension */
>  		.core_note_type = NT_ARM_SVE,
> -		.n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE),
> +		.n = DIV_ROUND_UP(SVE_PT_SIZE(ARCH_SVE_VQ_MAX,
> +					      SVE_PT_REGS_SVE),
>  				  SVE_VQ_BYTES),

Do we need an actual check somewhere that we don't bust this limit?

Since ZCR_ELx_LEN_MASK was changed from 0x1ff to 0xf, it looks like the
kernel itself will not generate an overlarge VL, although it feels a bit
like this guarantee arrives by accident.
Could ARCH_SVE_VQ_MAX be based on ZCR_ELx_LEN_MASK instead?

Userspace could specify vl > sve_vl_from_vq(ARCH_SVE_VQ_MAX) in
PTRACE_SETREGSET; I'm not sure exactly what happens there.

(The original 0x1ff value of ZCR_ELx_LEN_MASK was based on more than
just hope, but it does seem appropriate to restrict it now so that it
matches the formal architecture, as per commit f171f9e4097d
("arm64/fp: Make SVE and SME length register definition match
architecture") )

[...]

Cheers
---Dave


From mripard at kernel.org  Mon Feb 12 08:53:48 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 17:53:48 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add
 Broadcast RGB property
In-Reply-To: <Zco-DQaXqae7B1jt@intel.com>
References: <20240115143308.GA159345@toolbox>
 <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
Message-ID: <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>

On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > Hi,
> > > > > > > > 
> > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > >  /**
> > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > >   *
> > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > + *
> > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > + *
> > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > + *
> > > > > > > > > > > + *      Full:
> > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > + *
> > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > + *
> > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > + *
> > > > > > > > > > 
> > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > different things being affected:
> > > > > > > > > > 
> > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > 
> > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > 
> > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > 
> > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > signalling, what happens?
> > > > > > > > > 
> > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > YCbCr?
> > > > > > > > 
> > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > vc4 will follow the value of the property.
> > > > > > > 
> > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > That should explain why it's only affecting RGB.
> > > > > > 
> > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > itself.
> > > > > > 
> > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > to enable it.
> > > > > > 
> > > > > > vc4 supports it.
> > > > > 
> > > > > Someone implemented it incorrectly then.
> > > > 
> > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > document any of it, and when people try to clean things up they get told
> > > > that we got it all wrong.
> > > 
> > > FWIW, this was an i915 property and if another driver uses the same
> > > property name it must have the same behavior. Yes, it isn't standardized
> > > and yes, it's not documented (hence this effort here) but it's still on
> > > vc4 to make the property compatible.
> > 
> > How is it not compatible? It's a superset of what i915 provides, but
> > it's strictly compatible with it.
> 
> No it is not.

The property is compatible with i915 interpretation of it, whether you
like it or not. And that's what Sebastian was referring to.

> Eg. what happens if you set the thing to full range for RGB (which you
> must on many broken monitors), and then the kernel automagically
> switches to YCbCr (for whatever reason) but the monitor doesn't
> support full range YCbCr? Answer: you get crap output.

And that part is just moving goalposts.

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/20240212/5525b51c/attachment.sig>

From Dave.Martin at arm.com  Mon Feb 12 08:54:47 2024
From: Dave.Martin at arm.com (Dave Martin)
Date: Mon, 12 Feb 2024 16:54:47 +0000
Subject: [PATCH v2] arm64/sve: Document that __SVE_VQ_MAX is much larger
 than needed
In-Reply-To: <20240209-arm64-sve-vl-max-comment-v2-1-111b283469ee@kernel.org>
References: <20240209-arm64-sve-vl-max-comment-v2-1-111b283469ee@kernel.org>
Message-ID: <ZcpNV9wws5poOY8w@e133344.arm.com>

On Fri, Feb 09, 2024 at 04:53:36PM +0000, Mark Brown wrote:
> __SVE_VQ_MAX is defined without comment as 512 but the actual
> architectural maximum is 16, a substantial difference which might not
> be obvious to readers especially given the several different units used
> for specifying vector sizes in various contexts and the fact that it's
> often used via macros.  In an effort to minimise surprises for users who
> might assume the value is the architectural maximum and use it to do
> things like size allocations add a comment noting the difference, and
> add a note for SVE_VQ_MAX to aid discoverability.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> Changes in v2:
> - Use new wording mostly provided by Dave Martin.
> - Reference __SVE_VQ_MAX comment near SVE_VQ_MAX define.
> - Link to v1: https://lore.kernel.org/r/20240206-arm64-sve-vl-max-comment-v1-1-dddf16414412 at kernel.org
> ---
>  arch/arm64/include/uapi/asm/sve_context.h | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/arch/arm64/include/uapi/asm/sve_context.h b/arch/arm64/include/uapi/asm/sve_context.h
> index 754ab751b523..72aefc081061 100644
> --- a/arch/arm64/include/uapi/asm/sve_context.h
> +++ b/arch/arm64/include/uapi/asm/sve_context.h
> @@ -13,6 +13,17 @@
>  
>  #define __SVE_VQ_BYTES		16	/* number of bytes per quadword */
>  
> +/*
> + * Yes, __SVE_VQ_MAX is 512 QUADWORDS.
> + *
> + * To help ensure forward portability, this is much larger than the
> + * current maximum value defined by the SVE architecture.  While arrays
> + * or static allocations can be sized based on this value, watch out!
> + * It will waste a surprisingly large amount of memory.
> + *
> + * Dynamic sizing based on the actual runtime vector length is likely to
> + * be preferable for most purposes.
> + */
>  #define __SVE_VQ_MIN		1
>  #define __SVE_VQ_MAX		512

Acked-by: Dave Martin <Dave.Martin at arm.com>

[...]


From afd at ti.com  Mon Feb 12 08:58:58 2024
From: afd at ti.com (Andrew Davis)
Date: Mon, 12 Feb 2024 10:58:58 -0600
Subject: [PATCH v5 0/5] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
In-Reply-To: <b918364e-cfca-4342-acc2-2b51bad75596@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
 <359993c5-3387-443c-8cef-30ee7ad1f521@ti.com>
 <b918364e-cfca-4342-acc2-2b51bad75596@solid-run.com>
Message-ID: <faaca11f-508e-450c-83f2-1aa03734b7cd@ti.com>

On 2/12/24 10:39 AM, Josua Mayer wrote:
> Hi Vignesh,
> 
> Am 12.02.24 um 05:10 schrieb Vignesh Raghavendra:
>> Hi Josua,
>>
>> On 11/02/24 20:37, Josua Mayer wrote:
>>> This series adds DT bindings and dts descriptions for SolidRun AM642
>>> based SoM and Hummingboard EVB.
>>>
>>> Additionally a commit from downstream vendor kernel are included,
>>> enhancing support for pru based ethernet.
>>> I wasn't sure how to properly annotate it in commit description /
>>> signed-off area ...:
>>>
>>> 1. add description for "Industrial Ethernet Peripherals" (IEP) to am64
>>>     https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/commit/arch/arm64/boot/dts/ti/k3-am64-main.dtsi?h=ti-linux-6.1.y-cicd&id=5afb73d82a014b59462162d960b350b8c58e5ae6
>>>     IEP is already supported in-tree by a driver, and used in
>>>     k3-am65-main.dtsi.
>>>
>>> Unfortunately dtbs_check reported many problems, I put some remarks:
>>>
>>> - 'mux-controller' does not match any of the regexes
>>>    The expectation seems to be that a mux-controller at minimum has an
>>>    address, something to put behind an @. However this is a gpio mux, not
>>>    sure how to name it better.
>>>
>> I don't see this warning locally. Are you using updated dt-schema?
> pip3 install dtschema --upgrade
> Defaulting to user installation because normal site-packages is not writeable
> Requirement already satisfied: dtschema in ~/.local/lib/python3.11/site-packages (2023.11)
> 
> Re-Tested on 6.8-rc1
> 
>> reg
>> is not necessary gpio-mux as per gpio-mux.yaml
> The error is not about reg property, it is about the node name:
> 
> mux-controller {
>  ??? compatible = "gpio-mux";
>  ??? ...
> };
> 
>  ? DTC_CHK arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb
> .../arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb: syscon at 43000000: 'mux-controller' does not match any of the regexes: '^chipid@[0-9a-f]+$', '^clock-controller@[0-9a-f]+$', '^mux-controller@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pinctrl-[0-9]+'
>  ?????? from schema $id: http://devicetree.org/schemas/mfd/ti,j721e-system-controller.yaml#

This is an existing issue that we are working to fix. Nothing you
can do about it, all boards that include k3-am64-main.dtsi
will have this warning currently.

Andrew

>>
>>> - unevaluated properties: interrupts, interrupt-parent
>>>    sensors and flash yaml are missing interrupt descriptions, but these
>>>    parts definitely have an interrupt signal in this solidrun board.
>>>
>> Please add them to appropriate schema as necessary
> Okay.
> Looks like it is only two:
> .../arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb: humidity-sensor at 41: 'interrupt-parent', 'interrupts' do not match any of the regexes: 'pinctrl-[0-9]+'
>  ???????from schema $id: http://devicetree.org/schemas/iio/humidity/ti,hdc2010.yaml#
> .../arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb: flash at 0: Unevaluated properties are not allowed ('interrupt-parent', 'interrupts' were unexpected)
>  ???????from schema $id: http://devicetree.org/schemas/mtd/jedec,spi-nor.yaml#
>>
>>> - wrong names for pinctrl nodes
>>>    Other TI DTSs consistently end with *-pins-default. Should a different
>>>    naming convention be used?
>>>
>> No, pinctrl nodes need to end in -pins. All TI boards have been updated
>> to new schema [0] and sysconfig tool on dev.ti.com/sysconfig generates
>> appropriately. Please fix
> Okay, will do ...
>>
>>
>>> - cdns,phy-type required property
>>>    inherited from k3-am64-main.dtsi
>>>    there is a PHY_NONE value in dt-bindings/phy/phy.h,
>>>    but not allowed in phy-cadence-torrent.yaml
>>>
>> Sorry, I didnt get what's the issue wrt cdns,phy-type ?
> There were two issues, but they both disappeared as per 6.8-rc1 :)
>>
>>
>> Note, I really don't want to accept patches that add new dtbs_check
>> issues especially for nodes that already have YAML bindings. Please
>> update the .yaml files as necessary.
> I have succeeded locally getting rid of all but one, the node name of mux-controller mentioned above.
> Will include yaml patches in next version.
>>
>> [0]
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a49568115143435390f20965902809471b6f830c
>>
>>


From mripard at kernel.org  Mon Feb 12 09:00:21 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 12 Feb 2024 18:00:21 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB
 property
In-Reply-To: <0b3e31e6-34ae-46e3-a43d-bc4895542d8a@xs4all.nl>
References: <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <0b3e31e6-34ae-46e3-a43d-bc4895542d8a@xs4all.nl>
Message-ID: <tb6yqictmlpwokeihyyh4wxabrp6xs3zgvfpxjeulkmoxloysa@caqtn5fyc7cs>

On Mon, Feb 12, 2024 at 05:39:03PM +0100, Hans Verkuil wrote:
> On 12/02/2024 16:49, Ville Syrj?l? wrote:
> > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> >> On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> >>> On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> >>>> On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> >>>>> On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> >>>>>> On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> >>>>>>> On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> >>>>>>>> Hi,
> >>>>>>>>
> >>>>>>>> On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> >>>>>>>>>>>  /**
> >>>>>>>>>>>   * DOC: HDMI connector properties
> >>>>>>>>>>>   *
> >>>>>>>>>>> + * Broadcast RGB
> >>>>>>>>>>> + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> >>>>>>>>>>> + *      Infoframes will be generated according to that value.
> >>>>>>>>>>> + *
> >>>>>>>>>>> + *      The value of this property can be one of the following:
> >>>>>>>>>>> + *
> >>>>>>>>>>> + *      Automatic:
> >>>>>>>>>>> + *              RGB Range is selected automatically based on the mode
> >>>>>>>>>>> + *              according to the HDMI specifications.
> >>>>>>>>>>> + *
> >>>>>>>>>>> + *      Full:
> >>>>>>>>>>> + *              Full RGB Range is forced.
> >>>>>>>>>>> + *
> >>>>>>>>>>> + *      Limited 16:235:
> >>>>>>>>>>> + *              Limited RGB Range is forced. Unlike the name suggests,
> >>>>>>>>>>> + *              this works for any number of bits-per-component.
> >>>>>>>>>>> + *
> >>>>>>>>>>> + *      Drivers can set up this property by calling
> >>>>>>>>>>> + *      drm_connector_attach_broadcast_rgb_property().
> >>>>>>>>>>> + *
> >>>>>>>>>>
> >>>>>>>>>> This is a good time to document this in more detail. There might be two
> >>>>>>>>>> different things being affected:
> >>>>>>>>>>
> >>>>>>>>>> 1. The signalling (InfoFrame/SDP/...)
> >>>>>>>>>> 2. The color pipeline processing
> >>>>>>>>>>
> >>>>>>>>>> All values of Broadcast RGB always affect the color pipeline processing
> >>>>>>>>>> such that a full-range input to the CRTC is converted to either full- or
> >>>>>>>>>> limited-range, depending on what the monitor is supposed to accept.
> >>>>>>>>>>
> >>>>>>>>>> When automatic is selected, does that mean that there is no signalling,
> >>>>>>>>>> or that the signalling matches what the monitor is supposed to accept
> >>>>>>>>>> according to the spec? Also, is this really HDMI specific?
> >>>>>>>>>>
> >>>>>>>>>> When full or limited is selected and the monitor doesn't support the
> >>>>>>>>>> signalling, what happens?
> >>>>>>>>>
> >>>>>>>>> Forgot to mention: user-space still has no control over RGB vs YCbCr on
> >>>>>>>>> the cable, so is this only affecting RGB? If not, how does it affect
> >>>>>>>>> YCbCr?
> >>>>>>>>
> >>>>>>>> So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> >>>>>>>> we're using a YCbCr format, i915 will always use a limited range while
> >>>>>>>> vc4 will follow the value of the property.
> >>>>>>>
> >>>>>>> The property is literally called "Broadcast *RGB*".
> >>>>>>> That should explain why it's only affecting RGB.
> >>>>>>
> >>>>>> Right. And the limited range option is called "Limited 16:235" despite
> >>>>>> being usable on bpc > 8 bits. Naming errors occurs, and history happens
> >>>>>> to make names inconsistent too, that's fine and not an argument in
> >>>>>> itself.
> >>>>>>
> >>>>>>> Full range YCbCr is a much rarer beast so we've never bothered
> >>>>>>> to enable it.
> >>>>>>
> >>>>>> vc4 supports it.
> >>>>>
> >>>>> Someone implemented it incorrectly then.
> >>>>
> >>>> Incorrectly according to what documentation / specification? I'm sorry,
> >>>> but I find it super ironic that i915 gets to do its own thing, not
> >>>> document any of it, and when people try to clean things up they get told
> >>>> that we got it all wrong.
> >>>
> >>> FWIW, this was an i915 property and if another driver uses the same
> >>> property name it must have the same behavior. Yes, it isn't standardized
> >>> and yes, it's not documented (hence this effort here) but it's still on
> >>> vc4 to make the property compatible.
> >>
> >> How is it not compatible? It's a superset of what i915 provides, but
> >> it's strictly compatible with it.
> > 
> > No it is not. Eg. what happens if you set the thing to full range for
> > RGB (which you must on many broken monitors), and then the kernel
> > automagically switches to YCbCr (for whatever reason) but the monitor
> > doesn't support full range YCbCr? Answer: you get crap output.
> 
> The Broadcast RGB setting is really specific to RGB output. That's where
> you need it, since due to messed up standards in the past it is common to
> have to override this.
> 
> For YCbCr it is not needed since it is always limited range in practice.
> If there is ever a need to support full range YCbCr, then a new "Broadcast YCbCr"
> setting should be created.

We can't implement that, really. The userspace has no way to tell if RGB
or YUV is going to be used, so it wouldn't have an idea of what property
it needs to set.

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/20240212/09ec96c0/attachment.sig>

From neil.armstrong at linaro.org  Mon Feb 12 09:04:27 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:04:27 +0100
Subject: [PATCH v4 00/20] Support more Amlogic SoC families in crypto
 driver
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <6e7c9f54-1a75-46fd-867b-ce952417a903@linaro.org>

Hi,

On 12/02/2024 14:50, Alexey Romanov wrote:
> Hello!
> 
> This patchset expand the funcionality of the Amlogic
> crypto driver by adding support for more SoC families:
> AXG, G12A, G12B, SM1, A1, S4.
> 
> Also specify and enable crypto node in device tree
> for reference Amlogic devices.
> 
> Tested on AXG, G12A/B, SM1, A1 and S4 devices via
> custom tests [1] and tcrypt module.
> 
> ---
> 
> Changes V1 -> V2 [2]:
> 
> - Rebased over linux-next.
> - Adjusted device tree bindings description.
> - A1 and S4 dts use their own compatible, which is a G12 fallback.
> 
> Changes V2 -> V3 [3]:
> 
> - Fix errors in dt-bindings and device tree.
> - Add new field in platform data, which determines
> whether clock controller should be used for crypto IP.
> - Place back MODULE_DEVICE_TABLE.
> - Correct commit messages.
> 
> Changes V3 -> V4 [4]:
> 
> - Update dt-bindings as per Krzysztof Kozlowski comments.
> - Fix bisection: get rid of compiler errors in some patches.
> 
> Links:
>    - [1] https://gist.github.com/mRrvz/3fb8943a7487ab7b943ec140706995e7
>    - [2] https://lore.kernel.org/all/20240110201216.18016-1-avromanov at salutedevices.com/
>    - [3] https://lore.kernel.org/all/20240123165831.970023-1-avromanov at salutedevices.com/
>    - [4] https://lore.kernel.org/all/20240205155521.1795552-1-avromanov at salutedevices.com/
> 
> Alexey Romanov (20):
>    drivers: crypto: meson: don't hardcode IRQ count
>    drviers: crypto: meson: add platform data
>    drivers: crypto: meson: make CLK controller optional
>    drivers: crypto: meson: add MMIO helpers
>    drivers: crypto: meson: move get_engine_number()
>    drivers: crypto: meson: drop status field from meson_flow
>    drivers: crypto: meson: move algs definition and cipher API to
>      cipher.c
>    drivers: crypto: meson: cleanup defines
>    drivers: crypto: meson: process more than MAXDESCS descriptors
>    drivers: crypto: meson: avoid kzalloc in engine thread
>    drivers: crypto: meson: introduce hasher
>    drivers: crypto: meson: add support for AES-CTR
>    drivers: crypto: meson: use fallback for 192-bit keys
>    drivers: crypto: meson: add support for G12-series
>    drivers: crypto: meson: add support for AXG-series
>    dt-bindings: crypto: meson: support new SoC's
>    arch: arm64: dts: meson: a1: add crypto node
>    arch: arm64: dts: meson: s4: add crypto node
>    arch: arm64: dts: meson: g12: add crypto node
>    arch: arm64: dts: meson: axg: add crypto node
> 
>   .../bindings/crypto/amlogic,gxl-crypto.yaml   |  43 +-
>   arch/arm64/boot/dts/amlogic/meson-a1.dtsi     |   7 +
>   arch/arm64/boot/dts/amlogic/meson-axg.dtsi    |   6 +
>   .../boot/dts/amlogic/meson-g12-common.dtsi    |   6 +
>   arch/arm64/boot/dts/amlogic/meson-s4.dtsi     |   6 +
>   drivers/crypto/amlogic/Makefile               |   2 +-
>   drivers/crypto/amlogic/amlogic-gxl-cipher.c   | 602 ++++++++++++------
>   drivers/crypto/amlogic/amlogic-gxl-core.c     | 290 +++++----
>   drivers/crypto/amlogic/amlogic-gxl-hasher.c   | 452 +++++++++++++
>   drivers/crypto/amlogic/amlogic-gxl.h          | 117 +++-
>   10 files changed, 1183 insertions(+), 348 deletions(-)
>   create mode 100644 drivers/crypto/amlogic/amlogic-gxl-hasher.c
> 

The overall looks fine, I'll wait for further comments on the code,
but the DT looks ok and I didn't find any issues code building
or DT bindings check.

Neil


From neil.armstrong at linaro.org  Mon Feb 12 09:04:33 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:04:33 +0100
Subject: [PATCH v4 17/20] arch: arm64: dts: meson: a1: add crypto node
In-Reply-To: <20240212135108.549755-18-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-18-avromanov@salutedevices.com>
Message-ID: <847b368f-3f71-4391-85f0-e00eca24a922@linaro.org>

On 12/02/2024 14:51, Alexey Romanov wrote:
> This patch adds a crypto node declaration. With the
> Amlogic crypto driver we can use HW implementation
> of SHA1/224/256 and AES algo.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 7 +++++++
>   1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> index b9fd69112535..6d11e38ca3c0 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> @@ -653,6 +653,13 @@ sd_emmc: sd at 10000 {
>   				power-domains = <&pwrc PWRC_SD_EMMC_ID>;
>   				status = "disabled";
>   			};
> +
> +			crypto: crypto at 6000 {
> +				compatible = "amlogic,a1-crypto", "amlogic,g12a-crypto";
> +				reg = <0x0 0x6000 0x0 0x48>;
> +				interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>;
> +				power-domains = <&pwrc PWRC_DMA_ID>;
> +			};
>   		};
>   
>   		usb: usb at fe004400 {

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 12 09:04:40 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:04:40 +0100
Subject: [PATCH v4 18/20] arch: arm64: dts: meson: s4: add crypto node
In-Reply-To: <20240212135108.549755-19-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-19-avromanov@salutedevices.com>
Message-ID: <e490c717-338e-4b43-a9b2-17d5358c4dd1@linaro.org>

On 12/02/2024 14:51, Alexey Romanov wrote:
> This patch adds a crypto node declaration for Amlogic S4-series.
> With the Amlogic crypto driver we can use HW implementation
> of SHA1/224/256 and AES algo.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   arch/arm64/boot/dts/amlogic/meson-s4.dtsi | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
> index ce90b35686a2..dc05e2c5da3b 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
> @@ -339,6 +339,12 @@ mux {
>   
>   			};
>   
> +			crypto: crypto at 440400 {
> +				compatible = "amlogic,s4-crypto", "amlogic,g12a-crypto";
> +				reg = <0x0 0x440400 0x0 0x48>;
> +				interrupts = <GIC_SPI 24 IRQ_TYPE_EDGE_RISING>;
> +			};
> +
>   			gpio_intc: interrupt-controller at 4080 {
>   				compatible = "amlogic,meson-s4-gpio-intc",
>   					     "amlogic,meson-gpio-intc";

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 12 09:04:45 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:04:45 +0100
Subject: [PATCH v4 19/20] arch: arm64: dts: meson: g12: add crypto node
In-Reply-To: <20240212135108.549755-20-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-20-avromanov@salutedevices.com>
Message-ID: <1d19de25-362b-4983-98ee-c1aa6d2c5cc0@linaro.org>

On 12/02/2024 14:51, Alexey Romanov wrote:
> This patch adds a crypto node declaration for Amlogic G12-series.
> With the Amlogic crypto driver we can use HW implementation
> of SHA1/224/256 and AES algo.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.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 ff68b911b729..f6d7047a579c 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> @@ -1709,6 +1709,12 @@ internal_ephy: ethernet-phy at 8 {
>   					};
>   				};
>   			};
> +
> +			crypto: crypto at 3e000 {
> +				compatible = "amlogic,g12a-crypto";
> +				reg = <0x0 0x3e000 0x0 0x48>;
> +				interrupts = <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>;
> +			};
>   		};
>   
>   		aobus: bus at ff800000 {

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 12 09:04:51 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:04:51 +0100
Subject: [PATCH v4 20/20] arch: arm64: dts: meson: axg: add crypto node
In-Reply-To: <20240212135108.549755-21-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-21-avromanov@salutedevices.com>
Message-ID: <ecf86b35-a53a-4570-8ef1-377759422dcf@linaro.org>

On 12/02/2024 14:51, Alexey Romanov wrote:
> This patch adds a crypto node declaration. With the
> Amlogic crypto driver we can use HW implementation
> of SHA1/224/256 and AES algo.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> index 6d12b760b90f..b19be72abdd6 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> @@ -294,6 +294,12 @@ ethmac: ethernet at ff3f0000 {
>   			status = "disabled";
>   		};
>   
> +		crypto: crypto at ff63e000 {
> +			compatible = "amlogic,axg-crypto";
> +			reg = <0x0 0xff63e000 0x0 0x48>;
> +			interrupts = <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>;
> +		};
> +
>   		pcie_phy: phy at ff644000 {
>   			compatible = "amlogic,axg-pcie-phy";
>   			reg = <0x0 0xff644000 0x0 0x1c>;

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From alex.williamson at redhat.com  Mon Feb 12 09:05:02 2024
From: alex.williamson at redhat.com (Alex Williamson)
Date: Mon, 12 Feb 2024 10:05:02 -0700
Subject: [PATCH v7 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240211174705.31992-5-ankita@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
	<20240211174705.31992-5-ankita@nvidia.com>
Message-ID: <20240212100502.2b5009e4.alex.williamson@redhat.com>

On Sun, 11 Feb 2024 23:17:05 +0530
<ankita at nvidia.com> wrote:

> From: Ankit Agrawal <ankita at nvidia.com>
> 
> The code to map the MMIO in S2 as NormalNC is enabled when conveyed
> that the device is WC safe using a new flag VM_ALLOW_ANY_UNCACHED.
> 
> Make vfio-pci set the VM_ALLOW_ANY_UNCACHED flag.
> 
> This could be extended to other devices in the future once that
> is deemed safe.
> 
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Acked-by: Jason Gunthorpe <jgg at nvidia.com>
> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> ---
>  drivers/vfio/pci/vfio_pci_core.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 1cbc990d42e0..eba2146202f9 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -1862,8 +1862,12 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
>  	/*
>  	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
>  	 * change vm_flags within the fault handler.  Set them now.
> +	 *
> +	 * Set an additional flag VM_ALLOW_ANY_UNCACHED to convey kvm that
> +	 * the device is wc safe.
>  	 */

That's a pretty superficial comment.  Check that this is accurate, but
maybe something like:

	The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64,
	allowing stage 2 device mapping attributes to use Normal-NC
	rather than DEVICE_nGnRE, which allows guest mappings
	supporting combining attributes (WC).  This attribute has
	potential risks with the GICv2 VCPU interface, but is expected
	to be safe for vfio-pci use cases.

And specifically, I think these other devices that may be problematic
as described in the cover letter is a warning against use for
vfio-platform, is that correct?

Thanks,
Alex

> -	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
> +	vm_flags_set(vma, VM_ALLOW_ANY_UNCACHED | VM_IO | VM_PFNMAP |
> +			VM_DONTEXPAND | VM_DONTDUMP);
>  	vma->vm_ops = &vfio_pci_mmap_ops;
>  
>  	return 0;



From sebastian.wick at redhat.com  Mon Feb 12 09:06:18 2024
From: sebastian.wick at redhat.com (Sebastian Wick)
Date: Mon, 12 Feb 2024 18:06:18 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add
 Broadcast RGB property
In-Reply-To: <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
References: <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
Message-ID: <20240212170618.GA1372043@toolbox>

On Mon, Feb 12, 2024 at 05:53:48PM +0100, Maxime Ripard wrote:
> On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > > Hi,
> > > > > > > > > 
> > > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > > >  /**
> > > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > > >   *
> > > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > > + *
> > > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > > + *
> > > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > > + *
> > > > > > > > > > > > + *      Full:
> > > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > > + *
> > > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > > + *
> > > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > > + *
> > > > > > > > > > > 
> > > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > > different things being affected:
> > > > > > > > > > > 
> > > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > > 
> > > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > > 
> > > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > > 
> > > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > > signalling, what happens?
> > > > > > > > > > 
> > > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > > YCbCr?
> > > > > > > > > 
> > > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > > vc4 will follow the value of the property.
> > > > > > > > 
> > > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > > That should explain why it's only affecting RGB.
> > > > > > > 
> > > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > > itself.
> > > > > > > 
> > > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > > to enable it.
> > > > > > > 
> > > > > > > vc4 supports it.
> > > > > > 
> > > > > > Someone implemented it incorrectly then.
> > > > > 
> > > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > > document any of it, and when people try to clean things up they get told
> > > > > that we got it all wrong.
> > > > 
> > > > FWIW, this was an i915 property and if another driver uses the same
> > > > property name it must have the same behavior. Yes, it isn't standardized
> > > > and yes, it's not documented (hence this effort here) but it's still on
> > > > vc4 to make the property compatible.
> > > 
> > > How is it not compatible? It's a superset of what i915 provides, but
> > > it's strictly compatible with it.
> > 
> > No it is not.
> 
> The property is compatible with i915 interpretation of it, whether you
> like it or not. And that's what Sebastian was referring to.
> 
> > Eg. what happens if you set the thing to full range for RGB (which you
> > must on many broken monitors), and then the kernel automagically
> > switches to YCbCr (for whatever reason) but the monitor doesn't
> > support full range YCbCr? Answer: you get crap output.
> 
> And that part is just moving goalposts.

But it's really not. The Broadcast RGB property kind of works from a
user space perspective because it's a workaround for broken sinks. If a
sink expects limited range we can force full range. If this however
affects YCbCr modes as well, then this isn't a workaround for broken RGB
range anymore because it now breaks YCbCr.

Sorry, but vc4 just has to change.

And again: let's please stop trying to improve the property.

> 
> Maxime




From neil.armstrong at linaro.org  Mon Feb 12 09:08:44 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:08:44 +0100
Subject: [PATCH v4 02/20] drviers: crypto: meson: add platform data
In-Reply-To: <20240212135108.549755-3-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-3-avromanov@salutedevices.com>
Message-ID: <233ca2ec-ba1d-403f-b1d6-ba1b2c856e7f@linaro.org>

On 12/02/2024 14:50, Alexey Romanov wrote:
> To support other Amlogic SoC's we have to
> use platform data: descriptors and status registers
> offsets are individual for each SoC series.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   drivers/crypto/amlogic/amlogic-gxl-cipher.c |  2 +-
>   drivers/crypto/amlogic/amlogic-gxl-core.c   | 32 +++++++++++++++------
>   drivers/crypto/amlogic/amlogic-gxl.h        | 11 +++++++
>   3 files changed, 36 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index b19032f92415..7eff3ae7356f 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)
>   
>   	reinit_completion(&mc->chanlist[flow].complete);
>   	mc->chanlist[flow].status = 0;
> -	writel(mc->chanlist[flow].t_phy | 2, mc->base + (flow << 2));
> +	writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
>   	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
>   						  msecs_to_jiffies(500));
>   	if (mc->chanlist[flow].status == 0) {
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 35ec64df5b3a..4d1b1d5b7a54 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -18,6 +18,7 @@
>   #include <linux/kernel.h>
>   #include <linux/module.h>
>   #include <linux/of.h>
> +#include <linux/of_device.h>
>   #include <linux/platform_device.h>
>   
>   #include "amlogic-gxl.h"
> @@ -30,9 +31,10 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
>   
>   	for (flow = 0; flow < mc->flow_cnt; flow++) {
>   		if (mc->chanlist[flow].irq == irq) {
> -			p = readl(mc->base + ((0x04 + flow) << 2));
> +			p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
>   			if (p) {
> -				writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
> +				writel_relaxed(0xF, mc->base +
> +					      ((mc->pdata->status_reg + flow) << 2));
>   				mc->chanlist[flow].status = 1;
>   				complete(&mc->chanlist[flow].complete);
>   				return IRQ_HANDLED;
> @@ -245,15 +247,35 @@ static void meson_unregister_algs(struct meson_dev *mc)
>   	}
>   }
>   
> +static const struct meson_pdata meson_gxl_pdata = {
> +	.descs_reg = 0x0,
> +	.status_reg = 0x4,
> +};
> +
> +static const struct of_device_id meson_crypto_of_match_table[] = {
> +	{
> +		.compatible = "amlogic,gxl-crypto",
> +		.data = &meson_gxl_pdata,
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
> +
>   static int meson_crypto_probe(struct platform_device *pdev)
>   {
> +	const struct of_device_id *match;
>   	struct meson_dev *mc;
>   	int err;
>   
> +	match = of_match_device(meson_crypto_of_match_table, &pdev->dev);
> +	if (!match)
> +		return -EINVAL;
> +
>   	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
>   	if (!mc)
>   		return -ENOMEM;
>   
> +	mc->pdata = match->data;
>   	mc->dev = &pdev->dev;
>   	platform_set_drvdata(pdev, mc);
>   
> @@ -319,12 +341,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
>   	clk_disable_unprepare(mc->busclk);
>   }
>   
> -static const struct of_device_id meson_crypto_of_match_table[] = {
> -	{ .compatible = "amlogic,gxl-crypto", },
> -	{}
> -};
> -MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
> -

Please leave the struct at this place, and use of_device_get_match_data() instead.

>   static struct platform_driver meson_crypto_driver = {
>   	.probe		 = meson_crypto_probe,
>   	.remove_new	 = meson_crypto_remove,
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index 79177cfa8b88..9ad75da214ff 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -78,6 +78,16 @@ struct meson_flow {
>   #endif
>   };
>   
> +/*
> + * struct meson_pdata - SoC series dependent data.
> + * @reg_descs:	offset to descriptors register
> + * @reg_status:	offset to status register
> + */
> +struct meson_pdata {
> +	u32 descs_reg;
> +	u32 status_reg;
> +};
> +
>   /*
>    * struct meson_dev - main container for all this driver information
>    * @base:	base address of amlogic-crypto
> @@ -93,6 +103,7 @@ struct meson_dev {
>   	void __iomem *base;
>   	struct clk *busclk;
>   	struct device *dev;
> +	const struct meson_pdata *pdata;
>   	struct meson_flow *chanlist;
>   	atomic_t flow;
>   	int flow_cnt;



From broonie at kernel.org  Mon Feb 12 09:09:24 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 12 Feb 2024 17:09:24 +0000
Subject: [PATCH] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <ZcpMabqH+VZv6RCZ@e133344.arm.com>
References: <20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org>
 <ZcpMabqH+VZv6RCZ@e133344.arm.com>
Message-ID: <b0858303-8289-4371-be62-27da98d57020@sirena.org.uk>

On Mon, Feb 12, 2024 at 04:50:49PM +0000, Dave Martin wrote:
> On Sat, Feb 03, 2024 at 12:16:49PM +0000, Mark Brown wrote:

> > -		.n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE),
> > +		.n = DIV_ROUND_UP(SVE_PT_SIZE(ARCH_SVE_VQ_MAX,
> > +					      SVE_PT_REGS_SVE),
> >  				  SVE_VQ_BYTES),

> Do we need an actual check somewhere that we don't bust this limit?

...

> Userspace could specify vl > sve_vl_from_vq(ARCH_SVE_VQ_MAX) in
> PTRACE_SETREGSET; I'm not sure exactly what happens there.

We already have validation against the actual enumerated limits for the
system by virtue of setting the vector length to whatever is specified
so we'll limit any overly large vector length down to something we can
actually support and then reject an attempt to supply register data if
we changed the VL from what the user specified.

> Since ZCR_ELx_LEN_MASK was changed from 0x1ff to 0xf, it looks like the
> kernel itself will not generate an overlarge VL, although it feels a bit
> like this guarantee arrives by accident.
> Could ARCH_SVE_VQ_MAX be based on ZCR_ELx_LEN_MASK instead?

I guess.
-------------- 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/20240212/7e5a0ab2/attachment.sig>

From neil.armstrong at linaro.org  Mon Feb 12 09:10:44 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:10:44 +0100
Subject: [PATCH v4 03/20] drivers: crypto: meson: make CLK controller
 optional
In-Reply-To: <20240212135108.549755-4-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-4-avromanov@salutedevices.com>
Message-ID: <0ccbe65c-4a68-472e-8de0-79e88691d364@linaro.org>

On 12/02/2024 14:50, Alexey Romanov wrote:
> Amlogic crypto IP doesn't take a clock input on some
> SoCs: AXG / A1 / S4 / G12. So make it optional.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   drivers/crypto/amlogic/amlogic-gxl-core.c | 21 ++++++++-------------
>   drivers/crypto/amlogic/amlogic-gxl.h      |  2 ++
>   2 files changed, 10 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 4d1b1d5b7a54..54113c524ec5 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -250,6 +250,7 @@ static void meson_unregister_algs(struct meson_dev *mc)
>   static const struct meson_pdata meson_gxl_pdata = {
>   	.descs_reg = 0x0,
>   	.status_reg = 0x4,
> +	.need_clk = true,
>   };
>   
>   static const struct of_device_id meson_crypto_of_match_table[] = {
> @@ -285,17 +286,14 @@ static int meson_crypto_probe(struct platform_device *pdev)
>   		dev_err(&pdev->dev, "Cannot request MMIO err=%d\n", err);
>   		return err;
>   	}
> -	mc->busclk = devm_clk_get(&pdev->dev, "blkmv");
> -	if (IS_ERR(mc->busclk)) {
> -		err = PTR_ERR(mc->busclk);
> -		dev_err(&pdev->dev, "Cannot get core clock err=%d\n", err);
> -		return err;
> -	}
>   
> -	err = clk_prepare_enable(mc->busclk);
> -	if (err != 0) {
> -		dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
> -		return err;
> +	if (mc->pdata->need_clk) {
> +		mc->busclk = devm_clk_get_enabled(&pdev->dev, "blkmv");
> +		if (IS_ERR(mc->busclk)) {
> +			err = PTR_ERR(mc->busclk);
> +			dev_err(&pdev->dev, "Cannot get and enable core clock err=%d\n", err);
> +			return err;
> +		}
>   	}
>   
>   	err = meson_allocate_chanlist(mc);
> @@ -322,7 +320,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
>   	meson_unregister_algs(mc);
>   error_flow:
>   	meson_free_chanlist(mc, mc->flow_cnt - 1);
> -	clk_disable_unprepare(mc->busclk);
>   	return err;
>   }
>   
> @@ -337,8 +334,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
>   	meson_unregister_algs(mc);
>   
>   	meson_free_chanlist(mc, mc->flow_cnt - 1);
> -
> -	clk_disable_unprepare(mc->busclk);
>   }
>   
>   static struct platform_driver meson_crypto_driver = {
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index 9ad75da214ff..a36b9bac63a0 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -82,10 +82,12 @@ struct meson_flow {
>    * struct meson_pdata - SoC series dependent data.
>    * @reg_descs:	offset to descriptors register
>    * @reg_status:	offset to status register
> + * @need_clk:	clock input is needed
>    */
>   struct meson_pdata {
>   	u32 descs_reg;
>   	u32 status_reg;
> +	bool need_clk;
>   };
>   
>   /*

You may use devm_clk_get_optional_enabled() instead, bindings will ensure
clock is provided when needed.

With this you can also drop the clk_disable_unprepare() in meson_crypto_remove().

Neil



From neil.armstrong at linaro.org  Mon Feb 12 09:11:20 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:11:20 +0100
Subject: [PATCH v4 04/20] drivers: crypto: meson: add MMIO helpers
In-Reply-To: <20240212135108.549755-5-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-5-avromanov@salutedevices.com>
Message-ID: <6cbbf8ff-8e8b-4b37-846c-a9d4084f3f2d@linaro.org>

On 12/02/2024 14:50, Alexey Romanov wrote:
> Add MMIO access helpers: meson_dma_start() and meson_dma_ready().
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   drivers/crypto/amlogic/amlogic-gxl-cipher.c |  2 +-
>   drivers/crypto/amlogic/amlogic-gxl-core.c   | 24 ++++++++++++++++-----
>   drivers/crypto/amlogic/amlogic-gxl.h        |  2 ++
>   3 files changed, 22 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index 7eff3ae7356f..1fe916b0a138 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)
>   
>   	reinit_completion(&mc->chanlist[flow].complete);
>   	mc->chanlist[flow].status = 0;
> -	writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
> +	meson_dma_start(mc, flow);
>   	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
>   						  msecs_to_jiffies(500));
>   	if (mc->chanlist[flow].status == 0) {
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 54113c524ec5..372c30f72072 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -23,18 +23,32 @@
>   
>   #include "amlogic-gxl.h"
>   
> +void meson_dma_start(struct meson_dev *mc, int flow)
> +{
> +	u32 offset = (mc->pdata->descs_reg + flow) << 2;
> +
> +	writel(mc->chanlist[flow].t_phy | 2, mc->base + offset);
> +}
> +
> +static bool meson_dma_ready(struct meson_dev *mc, int flow)
> +{
> +	u32 offset = (mc->pdata->status_reg + flow) << 2;
> +	u32 data = readl(mc->base + offset);
> +
> +	if (data)
> +		writel_relaxed(0xF, mc->base + offset);
> +
> +	return data;
> +}
> +
>   static irqreturn_t meson_irq_handler(int irq, void *data)
>   {
>   	struct meson_dev *mc = (struct meson_dev *)data;
>   	int flow;
> -	u32 p;
>   
>   	for (flow = 0; flow < mc->flow_cnt; flow++) {
>   		if (mc->chanlist[flow].irq == irq) {
> -			p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
> -			if (p) {
> -				writel_relaxed(0xF, mc->base +
> -					      ((mc->pdata->status_reg + flow) << 2));
> +			if (meson_dma_ready(mc, flow)) {
>   				mc->chanlist[flow].status = 1;
>   				complete(&mc->chanlist[flow].complete);
>   				return IRQ_HANDLED;
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index a36b9bac63a0..59fc6a67e0a9 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -163,6 +163,8 @@ struct meson_alg_template {
>   #endif
>   };
>   
> +void meson_dma_start(struct meson_dev *mc, int flow);
> +
>   int meson_enqueue(struct crypto_async_request *areq, u32 type);
>   
>   int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 12 09:11:45 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:11:45 +0100
Subject: [PATCH v4 05/20] drivers: crypto: meson: move get_engine_number()
In-Reply-To: <20240212135108.549755-6-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-6-avromanov@salutedevices.com>
Message-ID: <3c0b7daf-29f9-4569-9aa3-fe8f381de821@linaro.org>

On 12/02/2024 14:50, Alexey Romanov wrote:
> Move get_engine_number() function from cipher.c to core.c
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   drivers/crypto/amlogic/amlogic-gxl-cipher.c | 9 ++-------
>   drivers/crypto/amlogic/amlogic-gxl-core.c   | 5 +++++
>   drivers/crypto/amlogic/amlogic-gxl.h        | 2 ++
>   3 files changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index 1fe916b0a138..18e9e2d39b1f 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -17,11 +17,6 @@
>   #include <crypto/internal/skcipher.h>
>   #include "amlogic-gxl.h"
>   
> -static int get_engine_number(struct meson_dev *mc)
> -{
> -	return atomic_inc_return(&mc->flow) % mc->flow_cnt;
> -}
> -
>   static bool meson_cipher_need_fallback(struct skcipher_request *areq)
>   {
>   	struct scatterlist *src_sg = areq->src;
> @@ -282,7 +277,7 @@ int meson_skdecrypt(struct skcipher_request *areq)
>   	rctx->op_dir = MESON_DECRYPT;
>   	if (meson_cipher_need_fallback(areq))
>   		return meson_cipher_do_fallback(areq);
> -	e = get_engine_number(op->mc);
> +	e = meson_get_engine_number(op->mc);
>   	engine = op->mc->chanlist[e].engine;
>   	rctx->flow = e;
>   
> @@ -300,7 +295,7 @@ int meson_skencrypt(struct skcipher_request *areq)
>   	rctx->op_dir = MESON_ENCRYPT;
>   	if (meson_cipher_need_fallback(areq))
>   		return meson_cipher_do_fallback(areq);
> -	e = get_engine_number(op->mc);
> +	e = meson_get_engine_number(op->mc);
>   	engine = op->mc->chanlist[e].engine;
>   	rctx->flow = e;
>   
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 372c30f72072..51291fdcf8b6 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -23,6 +23,11 @@
>   
>   #include "amlogic-gxl.h"
>   
> +int meson_get_engine_number(struct meson_dev *mc)
> +{
> +	return atomic_inc_return(&mc->flow) % mc->flow_cnt;
> +}
> +
>   void meson_dma_start(struct meson_dev *mc, int flow)
>   {
>   	u32 offset = (mc->pdata->descs_reg + flow) << 2;
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index 59fc6a67e0a9..5f5e3115fcdf 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -163,6 +163,8 @@ struct meson_alg_template {
>   #endif
>   };
>   
> +int meson_get_engine_number(struct meson_dev *mc);
> +
>   void meson_dma_start(struct meson_dev *mc, int flow);
>   
>   int meson_enqueue(struct crypto_async_request *areq, u32 type);

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 12 09:12:02 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:12:02 +0100
Subject: [PATCH v4 06/20] drivers: crypto: meson: drop status field from
 meson_flow
In-Reply-To: <20240212135108.549755-7-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-7-avromanov@salutedevices.com>
Message-ID: <e4f025d1-267d-4c80-b211-bdadfc31d2b1@linaro.org>

On 12/02/2024 14:50, Alexey Romanov wrote:
> This field is used only to check for timeout. But there is more
> convenient way to achive the same goal.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   drivers/crypto/amlogic/amlogic-gxl-cipher.c | 13 +++++++++----
>   drivers/crypto/amlogic/amlogic-gxl-core.c   |  1 -
>   drivers/crypto/amlogic/amlogic-gxl.h        |  2 --
>   3 files changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index 18e9e2d39b1f..dc0b100c5de2 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -219,13 +219,18 @@ static int meson_cipher(struct skcipher_request *areq)
>   	}
>   
>   	reinit_completion(&mc->chanlist[flow].complete);
> -	mc->chanlist[flow].status = 0;
>   	meson_dma_start(mc, flow);
> -	wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
> -						  msecs_to_jiffies(500));
> -	if (mc->chanlist[flow].status == 0) {
> +
> +	err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
> +							msecs_to_jiffies(500));
> +	if (err == 0) {
>   		dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
>   		err = -EINVAL;
> +	} else if (err < 0) {
> +		dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
> +	} else {
> +		/* No error */
> +		err = 0;
>   	}
>   
>   	dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 51291fdcf8b6..f7c60ebffbc3 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -54,7 +54,6 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
>   	for (flow = 0; flow < mc->flow_cnt; flow++) {
>   		if (mc->chanlist[flow].irq == irq) {
>   			if (meson_dma_ready(mc, flow)) {
> -				mc->chanlist[flow].status = 1;
>   				complete(&mc->chanlist[flow].complete);
>   				return IRQ_HANDLED;
>   			}
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index 5f5e3115fcdf..e27908992ae3 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -59,7 +59,6 @@ struct meson_desc {
>    * @engine:	ptr to the crypto_engine for this flow
>    * @keylen:	keylen for this flow operation
>    * @complete:	completion for the current task on this flow
> - * @status:	set to 1 by interrupt if task is done
>    * @irq:	IRQ number for amlogic-crypto
>    * @t_phy:	Physical address of task
>    * @tl:		pointer to the current ce_task for this flow
> @@ -68,7 +67,6 @@ struct meson_desc {
>   struct meson_flow {
>   	struct crypto_engine *engine;
>   	struct completion complete;
> -	int status;
>   	int irq;
>   	unsigned int keylen;
>   	dma_addr_t t_phy;

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 12 09:12:25 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:12:25 +0100
Subject: [PATCH v4 07/20] drivers: crypto: meson: move algs definition and
 cipher API to cipher.c
In-Reply-To: <20240212135108.549755-8-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-8-avromanov@salutedevices.com>
Message-ID: <09b4656d-a16c-4ae9-b1be-4320e093b974@linaro.org>

On 12/02/2024 14:50, Alexey Romanov wrote:
> Because that is proper place for them. In particular,
> it takes less of exported symbol between compiling entities.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   drivers/crypto/amlogic/amlogic-gxl-cipher.c |  98 +++++++++++++++--
>   drivers/crypto/amlogic/amlogic-gxl-core.c   | 110 ++++----------------
>   drivers/crypto/amlogic/amlogic-gxl.h        |  14 +--
>   3 files changed, 119 insertions(+), 103 deletions(-)
> 
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index dc0b100c5de2..bc3092a8a2c2 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -271,7 +271,7 @@ int meson_handle_cipher_request(struct crypto_engine *engine, void *areq)
>   	return 0;
>   }
>   
> -int meson_skdecrypt(struct skcipher_request *areq)
> +static int meson_skdecrypt(struct skcipher_request *areq)
>   {
>   	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
>   	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
> @@ -289,7 +289,7 @@ int meson_skdecrypt(struct skcipher_request *areq)
>   	return crypto_transfer_skcipher_request_to_engine(engine, areq);
>   }
>   
> -int meson_skencrypt(struct skcipher_request *areq)
> +static int meson_skencrypt(struct skcipher_request *areq)
>   {
>   	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
>   	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
> @@ -307,7 +307,7 @@ int meson_skencrypt(struct skcipher_request *areq)
>   	return crypto_transfer_skcipher_request_to_engine(engine, areq);
>   }
>   
> -int meson_cipher_init(struct crypto_tfm *tfm)
> +static int meson_cipher_init(struct crypto_tfm *tfm)
>   {
>   	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
>   	struct meson_alg_template *algt;
> @@ -333,7 +333,7 @@ int meson_cipher_init(struct crypto_tfm *tfm)
>   	return 0;
>   }
>   
> -void meson_cipher_exit(struct crypto_tfm *tfm)
> +static void meson_cipher_exit(struct crypto_tfm *tfm)
>   {
>   	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
>   
> @@ -341,8 +341,8 @@ void meson_cipher_exit(struct crypto_tfm *tfm)
>   	crypto_free_skcipher(op->fallback_tfm);
>   }
>   
> -int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
> -		     unsigned int keylen)
> +static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
> +			    unsigned int keylen)
>   {
>   	struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
>   	struct meson_dev *mc = op->mc;
> @@ -369,3 +369,89 @@ int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
>   
>   	return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
>   }
> +
> +static struct meson_alg_template algs[] = {
> +{
> +	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> +	.blockmode = MESON_OPMODE_CBC,
> +	.alg.skcipher.base = {
> +		.base = {
> +			.cra_name = "cbc(aes)",
> +			.cra_driver_name = "cbc-aes-gxl",
> +			.cra_priority = 400,
> +			.cra_blocksize = AES_BLOCK_SIZE,
> +			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
> +				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
> +				CRYPTO_ALG_NEED_FALLBACK,
> +			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
> +			.cra_module = THIS_MODULE,
> +			.cra_alignmask = 0xf,
> +			.cra_init = meson_cipher_init,
> +			.cra_exit = meson_cipher_exit,
> +		},
> +		.min_keysize	= AES_MIN_KEY_SIZE,
> +		.max_keysize	= AES_MAX_KEY_SIZE,
> +		.ivsize		= AES_BLOCK_SIZE,
> +		.setkey		= meson_aes_setkey,
> +		.encrypt	= meson_skencrypt,
> +		.decrypt	= meson_skdecrypt,
> +	},
> +	.alg.skcipher.op = {
> +		.do_one_request = meson_handle_cipher_request,
> +	},
> +},
> +{
> +	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> +	.blockmode = MESON_OPMODE_ECB,
> +	.alg.skcipher.base = {
> +		.base = {
> +			.cra_name = "ecb(aes)",
> +			.cra_driver_name = "ecb-aes-gxl",
> +			.cra_priority = 400,
> +			.cra_blocksize = AES_BLOCK_SIZE,
> +			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
> +				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
> +				CRYPTO_ALG_NEED_FALLBACK,
> +			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
> +			.cra_module = THIS_MODULE,
> +			.cra_alignmask = 0xf,
> +			.cra_init = meson_cipher_init,
> +			.cra_exit = meson_cipher_exit,
> +		},
> +		.min_keysize	= AES_MIN_KEY_SIZE,
> +		.max_keysize	= AES_MAX_KEY_SIZE,
> +		.setkey		= meson_aes_setkey,
> +		.encrypt	= meson_skencrypt,
> +		.decrypt	= meson_skdecrypt,
> +	},
> +	.alg.skcipher.op = {
> +		.do_one_request = meson_handle_cipher_request,
> +	},
> +},
> +};
> +
> +int meson_cipher_register(struct meson_dev *mc)
> +{
> +	return meson_register_algs(mc, algs, ARRAY_SIZE(algs));
> +}
> +
> +void meson_cipher_unregister(struct meson_dev *mc)
> +{
> +	meson_unregister_algs(mc, algs, ARRAY_SIZE(algs));
> +}
> +
> +void meson_cipher_debugfs_show(struct seq_file *seq, void *v)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(algs); i++) {
> +		seq_printf(seq, "%s %s %lu %lu\n",
> +			   algs[i].alg.skcipher.base.base.cra_driver_name,
> +			   algs[i].alg.skcipher.base.base.cra_name,
> +#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
> +			   algs[i].stat_req, algs[i].stat_fb);
> +#else
> +			   0ul, 0ul);
> +#endif
> +	}
> +}
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index f7c60ebffbc3..22ff2768b5e5 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -65,66 +65,6 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
>   	return IRQ_HANDLED;
>   }
>   
> -static struct meson_alg_template mc_algs[] = {
> -{
> -	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -	.blockmode = MESON_OPMODE_CBC,
> -	.alg.skcipher.base = {
> -		.base = {
> -			.cra_name = "cbc(aes)",
> -			.cra_driver_name = "cbc-aes-gxl",
> -			.cra_priority = 400,
> -			.cra_blocksize = AES_BLOCK_SIZE,
> -			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
> -				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
> -				CRYPTO_ALG_NEED_FALLBACK,
> -			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
> -			.cra_module = THIS_MODULE,
> -			.cra_alignmask = 0xf,
> -			.cra_init = meson_cipher_init,
> -			.cra_exit = meson_cipher_exit,
> -		},
> -		.min_keysize	= AES_MIN_KEY_SIZE,
> -		.max_keysize	= AES_MAX_KEY_SIZE,
> -		.ivsize		= AES_BLOCK_SIZE,
> -		.setkey		= meson_aes_setkey,
> -		.encrypt	= meson_skencrypt,
> -		.decrypt	= meson_skdecrypt,
> -	},
> -	.alg.skcipher.op = {
> -		.do_one_request = meson_handle_cipher_request,
> -	},
> -},
> -{
> -	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -	.blockmode = MESON_OPMODE_ECB,
> -	.alg.skcipher.base = {
> -		.base = {
> -			.cra_name = "ecb(aes)",
> -			.cra_driver_name = "ecb-aes-gxl",
> -			.cra_priority = 400,
> -			.cra_blocksize = AES_BLOCK_SIZE,
> -			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
> -				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
> -				CRYPTO_ALG_NEED_FALLBACK,
> -			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
> -			.cra_module = THIS_MODULE,
> -			.cra_alignmask = 0xf,
> -			.cra_init = meson_cipher_init,
> -			.cra_exit = meson_cipher_exit,
> -		},
> -		.min_keysize	= AES_MIN_KEY_SIZE,
> -		.max_keysize	= AES_MAX_KEY_SIZE,
> -		.setkey		= meson_aes_setkey,
> -		.encrypt	= meson_skencrypt,
> -		.decrypt	= meson_skdecrypt,
> -	},
> -	.alg.skcipher.op = {
> -		.do_one_request = meson_handle_cipher_request,
> -	},
> -},
> -};
> -
>   static int meson_debugfs_show(struct seq_file *seq, void *v)
>   {
>   	struct meson_dev *mc __maybe_unused = seq->private;
> @@ -138,20 +78,8 @@ static int meson_debugfs_show(struct seq_file *seq, void *v)
>   			   0ul);
>   #endif
>   
> -	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
> -		switch (mc_algs[i].type) {
> -		case CRYPTO_ALG_TYPE_SKCIPHER:
> -			seq_printf(seq, "%s %s %lu %lu\n",
> -				   mc_algs[i].alg.skcipher.base.base.cra_driver_name,
> -				   mc_algs[i].alg.skcipher.base.base.cra_name,
> -#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
> -				   mc_algs[i].stat_req, mc_algs[i].stat_fb);
> -#else
> -				   0ul, 0ul);
> -#endif
> -			break;
> -		}
> -	}
> +	meson_cipher_debugfs_show(seq, v);
> +
>   	return 0;
>   }
>   DEFINE_SHOW_ATTRIBUTE(meson_debugfs);
> @@ -228,38 +156,40 @@ static int meson_allocate_chanlist(struct meson_dev *mc)
>   	return err;
>   }
>   
> -static int meson_register_algs(struct meson_dev *mc)
> +int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
> +			unsigned int count)
>   {
>   	int err, i;
>   
> -	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
> -		mc_algs[i].mc = mc;
> -		switch (mc_algs[i].type) {
> +	for (i = 0; i < count; i++) {
> +		switch (algs[i].type) {
>   		case CRYPTO_ALG_TYPE_SKCIPHER:
> -			err = crypto_engine_register_skcipher(&mc_algs[i].alg.skcipher);
> +			err = crypto_engine_register_skcipher(&algs[i].alg.skcipher);
>   			if (err) {
>   				dev_err(mc->dev, "Fail to register %s\n",
> -					mc_algs[i].alg.skcipher.base.base.cra_name);
> -				mc_algs[i].mc = NULL;
> +					algs[i].alg.skcipher.base.base.cra_name);
> +				meson_unregister_algs(mc, algs, count);
>   				return err;
>   			}
>   			break;
>   		}
> +		algs[i].mc = mc;
>   	}
>   
>   	return 0;
>   }
>   
> -static void meson_unregister_algs(struct meson_dev *mc)
> +void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs,
> +			   unsigned int count)
>   {
>   	int i;
>   
> -	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
> -		if (!mc_algs[i].mc)
> +	for (i = 0; i < count; i++) {
> +		if (!algs[i].mc)
>   			continue;
> -		switch (mc_algs[i].type) {
> +		switch (algs[i].type) {
>   		case CRYPTO_ALG_TYPE_SKCIPHER:
> -			crypto_engine_unregister_skcipher(&mc_algs[i].alg.skcipher);
> +			crypto_engine_unregister_skcipher(&algs[i].alg.skcipher);
>   			break;
>   		}
>   	}
> @@ -318,9 +248,9 @@ static int meson_crypto_probe(struct platform_device *pdev)
>   	if (err)
>   		goto error_flow;
>   
> -	err = meson_register_algs(mc);
> +	err = meson_cipher_register(mc);
>   	if (err)
> -		goto error_alg;
> +		goto error_flow;
>   
>   	if (IS_ENABLED(CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG)) {
>   		struct dentry *dbgfs_dir;
> @@ -334,8 +264,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
>   	}
>   
>   	return 0;
> -error_alg:
> -	meson_unregister_algs(mc);
>   error_flow:
>   	meson_free_chanlist(mc, mc->flow_cnt - 1);
>   	return err;
> @@ -349,7 +277,7 @@ static void meson_crypto_remove(struct platform_device *pdev)
>   	debugfs_remove_recursive(mc->dbgfs_dir);
>   #endif
>   
> -	meson_unregister_algs(mc);
> +	meson_cipher_unregister(mc);
>   
>   	meson_free_chanlist(mc, mc->flow_cnt - 1);
>   }
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index e27908992ae3..0a03e8144977 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -167,10 +167,12 @@ void meson_dma_start(struct meson_dev *mc, int flow);
>   
>   int meson_enqueue(struct crypto_async_request *areq, u32 type);
>   
> -int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
> -		     unsigned int keylen);
> -int meson_cipher_init(struct crypto_tfm *tfm);
> -void meson_cipher_exit(struct crypto_tfm *tfm);
> -int meson_skdecrypt(struct skcipher_request *areq);
> -int meson_skencrypt(struct skcipher_request *areq);
> +int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
> +			unsigned int count);
> +void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs,
> +			   unsigned int count);
> +
> +int meson_cipher_register(struct meson_dev *mc);
> +void meson_cipher_unregister(struct meson_dev *mc);
> +void meson_cipher_debugfs_show(struct seq_file *seq, void *v);
>   int meson_handle_cipher_request(struct crypto_engine *engine, void *areq);

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 12 09:14:38 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:14:38 +0100
Subject: [PATCH v4 08/20] drivers: crypto: meson: cleanup defines
In-Reply-To: <20240212135108.549755-9-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-9-avromanov@salutedevices.com>
Message-ID: <82b074b3-6ae1-4e00-8648-8dd938d6e334@linaro.org>

On 12/02/2024 14:50, Alexey Romanov wrote:
> It is bad to use hardcoded values directly in the code.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   drivers/crypto/amlogic/amlogic-gxl-cipher.c | 24 ++++++++++-----------
>   drivers/crypto/amlogic/amlogic-gxl.h        | 16 ++++++++------
>   2 files changed, 21 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index bc3092a8a2c2..c662c4b86e97 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -141,8 +141,8 @@ static int meson_cipher(struct skcipher_request *areq)
>   						 ivsize, 0);
>   		}
>   	}
> -	if (keyivlen == 24)
> -		keyivlen = 32;
> +	if (keyivlen == AES_KEYSIZE_192)
> +		keyivlen = AES_MAX_KEY_SIZE;
>   
>   	phykeyiv = dma_map_single(mc->dev, bkeyiv, keyivlen,
>   				  DMA_TO_DEVICE);
> @@ -161,7 +161,7 @@ static int meson_cipher(struct skcipher_request *areq)
>   		todo = min(keyivlen - eat, 16u);
>   		desc->t_src = cpu_to_le32(phykeyiv + i * 16);
>   		desc->t_dst = cpu_to_le32(i * 16);
> -		v = (MODE_KEY << 20) | DESC_OWN | 16;
> +		v = DESC_MODE_KEY | DESC_OWN | 16;
>   		desc->t_status = cpu_to_le32(v);
>   
>   		eat += todo;
> @@ -205,7 +205,7 @@ static int meson_cipher(struct skcipher_request *areq)
>   		desc->t_src = cpu_to_le32(sg_dma_address(src_sg));
>   		desc->t_dst = cpu_to_le32(sg_dma_address(dst_sg));
>   		todo = min(len, sg_dma_len(src_sg));
> -		v = (op->keymode << 20) | DESC_OWN | todo | (algt->blockmode << 26);
> +		v = op->keymode | DESC_OWN | todo | algt->blockmode;
>   		if (rctx->op_dir)
>   			v |= DESC_ENCRYPTION;
>   		len -= todo;
> @@ -348,14 +348,14 @@ static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
>   	struct meson_dev *mc = op->mc;
>   
>   	switch (keylen) {
> -	case 128 / 8:
> -		op->keymode = MODE_AES_128;
> +	case AES_KEYSIZE_128:
> +		op->keymode = DESC_MODE_AES_128;
>   		break;
> -	case 192 / 8:
> -		op->keymode = MODE_AES_192;
> +	case AES_KEYSIZE_192:
> +		op->keymode = DESC_MODE_AES_192;
>   		break;
> -	case 256 / 8:
> -		op->keymode = MODE_AES_256;
> +	case AES_KEYSIZE_256:
> +		op->keymode = DESC_MODE_AES_256;
>   		break;
>   	default:
>   		dev_dbg(mc->dev, "ERROR: Invalid keylen %u\n", keylen);
> @@ -373,7 +373,7 @@ static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
>   static struct meson_alg_template algs[] = {
>   {
>   	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -	.blockmode = MESON_OPMODE_CBC,
> +	.blockmode = DESC_OPMODE_CBC,
>   	.alg.skcipher.base = {
>   		.base = {
>   			.cra_name = "cbc(aes)",
> @@ -402,7 +402,7 @@ static struct meson_alg_template algs[] = {
>   },
>   {
>   	.type = CRYPTO_ALG_TYPE_SKCIPHER,
> -	.blockmode = MESON_OPMODE_ECB,
> +	.blockmode = DESC_OPMODE_ECB,
>   	.alg.skcipher.base = {
>   		.base = {
>   			.cra_name = "ecb(aes)",
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index 0a03e8144977..a0d83c82906d 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -11,19 +11,21 @@
>   #include <linux/crypto.h>
>   #include <linux/scatterlist.h>
>   
> -#define MODE_KEY 1
> -#define MODE_AES_128 0x8
> -#define MODE_AES_192 0x9
> -#define MODE_AES_256 0xa
> -
>   #define MESON_DECRYPT 0
>   #define MESON_ENCRYPT 1
>   
> -#define MESON_OPMODE_ECB 0
> -#define MESON_OPMODE_CBC 1
> +#define DESC_MODE_KEY (0x1 << 20)
> +#define DESC_MODE_AES_128 (0x8 << 20)
> +#define DESC_MODE_AES_192 (0x9 << 20)
> +#define DESC_MODE_AES_256 (0xa << 20)


>   
>   #define MAXDESC 64
>   
> +#define DESC_OPMODE_ECB (0 << 26)
> +#define DESC_OPMODE_CBC (1 << 26)
> +
> +#define DESC_MAXLEN ((1 << 17) - 1)

GENMASK(16, 0) ?

> +
>   #define DESC_LAST BIT(18)
>   #define DESC_ENCRYPTION BIT(28)
>   #define DESC_OWN BIT(31)

Anyway:
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 12 09:15:42 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 12 Feb 2024 18:15:42 +0100
Subject: [PATCH v4 10/20] drivers: crypto: meson: avoid kzalloc in engine
 thread
In-Reply-To: <20240212135108.549755-11-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-11-avromanov@salutedevices.com>
Message-ID: <92397728-d763-402d-b3e6-f4edd6f71740@linaro.org>

On 12/02/2024 14:50, Alexey Romanov wrote:
> It makes no sense to allocate memory via kzalloc, we
> can use static buffer, speedup data processing and
> don't think about kfree() calls.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>   drivers/crypto/amlogic/amlogic-gxl-cipher.c | 26 ++++++++-------------
>   drivers/crypto/amlogic/amlogic-gxl.h        |  6 ++---
>   2 files changed, 13 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index c1b3569a614a..3f42b2cc568d 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -91,7 +91,6 @@ struct cipher_ctx {
>   	struct skcipher_request *areq;
>   	struct scatterlist *src_sg;
>   	struct scatterlist *dst_sg;
> -	void *bkeyiv;
>   
>   	unsigned int src_offset;
>   	unsigned int dst_offset;
> @@ -156,8 +155,7 @@ static void meson_setup_keyiv_descs(struct cipher_ctx *ctx)
>   		return;
>   
>   	if (blockmode == DESC_OPMODE_CBC) {
> -		memcpy(ctx->bkeyiv + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
> -		ctx->keyiv.len = AES_MAX_KEY_SIZE + ivsize;
> +		memcpy(op->keyiv + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
>   		dma_sync_single_for_device(mc->dev, ctx->keyiv.addr,
>   					   ctx->keyiv.len, DMA_TO_DEVICE);
>   	}
> @@ -304,6 +302,7 @@ static int meson_cipher(struct skcipher_request *areq)
>   		.dst_sg = areq->dst,
>   		.cryptlen = areq->cryptlen,
>   	};
> +	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
>   	int err;
>   
>   	dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u ctx.flow=%d\n", __func__,
> @@ -319,16 +318,16 @@ static int meson_cipher(struct skcipher_request *areq)
>   	mc->chanlist[rctx->flow].stat_req++;
>   #endif
>   
> -	ctx.bkeyiv = kzalloc(48, GFP_KERNEL | GFP_DMA);
> -	if (!ctx.bkeyiv)
> -		return -ENOMEM;
> -
> -	memcpy(ctx.bkeyiv, op->key, op->keylen);
>   	ctx.keyiv.len = op->keylen;
>   	if (ctx.keyiv.len == AES_KEYSIZE_192)
>   		ctx.keyiv.len = AES_MAX_KEY_SIZE;
>   
> -	ctx.keyiv.addr = dma_map_single(mc->dev, ctx.bkeyiv, ctx.keyiv.len,
> +	if (algt->blockmode == DESC_OPMODE_CBC) {
> +		memcpy(op->keyiv + AES_MAX_KEY_SIZE, areq->iv, ivsize);
> +		ctx.keyiv.len = AES_MAX_KEY_SIZE + ivsize;
> +	}
> +
> +	ctx.keyiv.addr = dma_map_single(mc->dev, op->keyiv, ctx.keyiv.len,
>   				  DMA_TO_DEVICE);
>   	err = dma_mapping_error(mc->dev, ctx.keyiv.addr);
>   	if (err) {
> @@ -366,8 +365,6 @@ static int meson_cipher(struct skcipher_request *areq)
>   	meson_unmap_scatterlist(areq, mc);
>   
>   theend:
> -	kfree_sensitive(ctx.bkeyiv);
> -
>   	return err;
>   }
>   
> @@ -450,7 +447,6 @@ static void meson_cipher_exit(struct crypto_tfm *tfm)
>   {
>   	struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
>   
> -	kfree_sensitive(op->key);
>   	crypto_free_skcipher(op->fallback_tfm);
>   }
>   
> @@ -474,11 +470,9 @@ static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
>   		dev_dbg(mc->dev, "ERROR: Invalid keylen %u\n", keylen);
>   		return -EINVAL;
>   	}
> -	kfree_sensitive(op->key);
> +
> +	memcpy(op->keyiv, key, keylen);
>   	op->keylen = keylen;
> -	op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
> -	if (!op->key)
> -		return -ENOMEM;
>   
>   	return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
>   }
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index eb2f8cd72b65..e1453dd2e9f4 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -129,15 +129,15 @@ struct meson_cipher_req_ctx {
>   
>   /*
>    * struct meson_cipher_tfm_ctx - context for a skcipher TFM
> - * @key:		pointer to key data
> + * @keyiv:		key data
>    * @keylen:		len of the key
>    * @keymode:		The keymode(type and size of key) associated with this TFM
>    * @mc:			pointer to the private data of driver handling this TFM
>    * @fallback_tfm:	pointer to the fallback TFM
>    */
>   struct meson_cipher_tfm_ctx {
> -	u32 *key;
> -	u32 keylen;
> +	u8 keyiv[AES_MAX_KEY_SIZE + AES_BLOCK_SIZE] ____cacheline_aligned;
> +	u32 keylen ____cacheline_aligned;
>   	u32 keymode;
>   	struct meson_dev *mc;
>   	struct crypto_skcipher *fallback_tfm;

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From jgg at nvidia.com  Mon Feb 12 09:20:01 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Mon, 12 Feb 2024 13:20:01 -0400
Subject: [PATCH v7 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240212100502.2b5009e4.alex.williamson@redhat.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
 <20240211174705.31992-5-ankita@nvidia.com>
 <20240212100502.2b5009e4.alex.williamson@redhat.com>
Message-ID: <20240212172001.GE4048826@nvidia.com>

On Mon, Feb 12, 2024 at 10:05:02AM -0700, Alex Williamson wrote:

> > --- a/drivers/vfio/pci/vfio_pci_core.c
> > +++ b/drivers/vfio/pci/vfio_pci_core.c
> > @@ -1862,8 +1862,12 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
> >  	/*
> >  	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
> >  	 * change vm_flags within the fault handler.  Set them now.
> > +	 *
> > +	 * Set an additional flag VM_ALLOW_ANY_UNCACHED to convey kvm that
> > +	 * the device is wc safe.
> >  	 */
> 
> That's a pretty superficial comment.  Check that this is accurate, but
> maybe something like:
> 
> 	The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64,
> 	allowing stage 2 device mapping attributes to use Normal-NC
               ^^^^ 

> 	rather than DEVICE_nGnRE, which allows guest mappings
> 	supporting combining attributes (WC).  This attribute has
> 	potential risks with the GICv2 VCPU interface, but is expected
> 	to be safe for vfio-pci use cases.

Sure, if you want to elaborate more

  The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64,
  allowing KVM stage 2 device mapping attributes to use Normal-NC
  rather than DEVICE_nGnRE, which allows guest mappings
  supporting combining attributes (WC). ARM does not architecturally
  guarentee this is safe, and indeed some MMIO regions like the GICv2
  VCPU interface can trigger uncontained faults if Normal-NC is used.

  Even worse we expect there are platforms where even DEVICE_nGnRE can
  allow uncontained faults in conercases. Unfortunately existing ARM
  IP requires platform integration to take responsibility to prevent
  this.

  To safely use VFIO in KVM the platform must guarantee full safety
  in the guest where no action taken against a MMIO mapping can
  trigger an uncontainer failure. We belive that most VFIO PCI
  platforms support this for both mapping types, at least in common
  flows, based on some expectations of how PCI IP is integrated. This
  can be enabled more broadly, for instance into vfio-platform
  drivers, but only after the platform vendor completes auditing for
  safety.
 
> And specifically, I think these other devices that may be problematic
> as described in the cover letter is a warning against use for
> vfio-platform, is that correct?

Maybe more like "we have a general consensus that vfio-pci is likely
safe due to how PCI IP is typically integrated, but it is much less
obvious for other VFIO bus types. As there is no known WC user for
vfio-platform drivers be conservative and do not enable it."

Jason


From alex.williamson at redhat.com  Mon Feb 12 09:27:18 2024
From: alex.williamson at redhat.com (Alex Williamson)
Date: Mon, 12 Feb 2024 10:27:18 -0700
Subject: [PATCH v7 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240212172001.GE4048826@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
	<20240211174705.31992-5-ankita@nvidia.com>
	<20240212100502.2b5009e4.alex.williamson@redhat.com>
	<20240212172001.GE4048826@nvidia.com>
Message-ID: <20240212102718.07543659.alex.williamson@redhat.com>

On Mon, 12 Feb 2024 13:20:01 -0400
Jason Gunthorpe <jgg at nvidia.com> wrote:

> On Mon, Feb 12, 2024 at 10:05:02AM -0700, Alex Williamson wrote:
> 
> > > --- a/drivers/vfio/pci/vfio_pci_core.c
> > > +++ b/drivers/vfio/pci/vfio_pci_core.c
> > > @@ -1862,8 +1862,12 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
> > >  	/*
> > >  	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
> > >  	 * change vm_flags within the fault handler.  Set them now.
> > > +	 *
> > > +	 * Set an additional flag VM_ALLOW_ANY_UNCACHED to convey kvm that
> > > +	 * the device is wc safe.
> > >  	 */  
> > 
> > That's a pretty superficial comment.  Check that this is accurate, but
> > maybe something like:
> > 
> > 	The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64,
> > 	allowing stage 2 device mapping attributes to use Normal-NC  
>                ^^^^ 
> 
> > 	rather than DEVICE_nGnRE, which allows guest mappings
> > 	supporting combining attributes (WC).  This attribute has
> > 	potential risks with the GICv2 VCPU interface, but is expected
> > 	to be safe for vfio-pci use cases.  
> 
> Sure, if you want to elaborate more
> 
>   The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64,
>   allowing KVM stage 2 device mapping attributes to use Normal-NC
>   rather than DEVICE_nGnRE, which allows guest mappings
>   supporting combining attributes (WC). ARM does not architecturally
>   guarentee this is safe, and indeed some MMIO regions like the GICv2
>   VCPU interface can trigger uncontained faults if Normal-NC is used.
> 
>   Even worse we expect there are platforms where even DEVICE_nGnRE can
>   allow uncontained faults in conercases. Unfortunately existing ARM
                                ^^^^^^^^^^

*corner cases


>   IP requires platform integration to take responsibility to prevent
>   this.
> 
>   To safely use VFIO in KVM the platform must guarantee full safety
>   in the guest where no action taken against a MMIO mapping can
>   trigger an uncontainer failure. We belive that most VFIO PCI
>   platforms support this for both mapping types, at least in common
>   flows, based on some expectations of how PCI IP is integrated. This
>   can be enabled more broadly, for instance into vfio-platform
>   drivers, but only after the platform vendor completes auditing for
>   safety.

I like it, please incorporate into the next version.
  
> > And specifically, I think these other devices that may be problematic
> > as described in the cover letter is a warning against use for
> > vfio-platform, is that correct?  
> 
> Maybe more like "we have a general consensus that vfio-pci is likely
> safe due to how PCI IP is typically integrated, but it is much less
> obvious for other VFIO bus types. As there is no known WC user for
> vfio-platform drivers be conservative and do not enable it."

Ok.  Thanks for the clarification.

Alex



From quic_pbrahma at quicinc.com  Mon Feb 12 09:29:50 2024
From: quic_pbrahma at quicinc.com (Pratyush Brahma)
Date: Mon, 12 Feb 2024 22:59:50 +0530
Subject: [PATCH v4 03/10] iommu/arm-smmu-qcom: Add support for TBUs
In-Reply-To: <20240201210529.7728-4-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-4-quic_c_gdjako@quicinc.com>
Message-ID: <13da9cd9-218d-4b3f-98f8-62edcd91a23e@quicinc.com>

Hi

The following patch would introduce a use-after-free bug which was found 
during KASAN testing on qcm6490 with the patch.

diff 
<https://lore.kernel.org/all/20240201210529.7728-4-quic_c_gdjako at quicinc.com/#iZ2e.:20240201210529.7728-4-quic_c_gdjako::40quicinc.com:1drivers:iommu:arm:arm-smmu:arm-smmu-qcom.c> 
--git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index 
8b04ece00420..ca806644e6eb 100644 --- 
a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -1,12 +1,14 @@   // SPDX-License-Identifier: GPL-2.0-only
  /*
   * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved    */
  
  #include <linux/acpi.h>
  #include <linux/adreno-smmu-priv.h>
  #include <linux/delay.h>
  #include <linux/of_device.h>
+#include <linux/of_platform.h>   #include <linux/firmware/qcom/qcom_scm.h>
  
  #include "arm-smmu.h"
@@ -446,6 +448,7 @@ static struct arm_smmu_device 
*qcom_smmu_create(struct arm_smmu_device *smmu,   	const struct device_node *np = smmu->dev->of_node;
  	const struct arm_smmu_impl *impl;
  	struct qcom_smmu *qsmmu;
+ int ret;   
  	if (!data)
  		return ERR_PTR(-EINVAL);
@@ -469,6 +472,12 @@ static struct arm_smmu_device 
*qcom_smmu_create(struct arm_smmu_device *smmu,   	qsmmu->smmu.impl = impl;
  	qsmmu->cfg = data->cfg;
  
+ INIT_LIST_HEAD(&qsmmu->tbu_list); + mutex_init(&qsmmu->tbu_list_lock); 
+ ret = devm_of_platform_populate(smmu->dev); // smmu has been freed by 
devm_krealloc() above but is being accessed here again later. This 
causes use-after-free bug. + if (ret) + return ERR_PTR(ret); +   	return &qsmmu->smmu;
  }

Can it be done like below?
  	qsmmu->smmu.impl = impl;
  	qsmmu->cfg = data->cfg;
  
+ INIT_LIST_HEAD(&qsmmu->tbu_list); + mutex_init(&qsmmu->tbu_list_lock); 
+ ret = devm_of_platform_populate(qsmmu->smmu.dev);// Using the struct 
to which smmu was copied instead of freed ptr. Thanks, Pratyush



From jm at ti.com  Mon Feb 12 09:31:36 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 11:31:36 -0600
Subject: [PATCH v1 0/9] Fix MMC properties on Sitara devices
In-Reply-To: <20240211154411.GA3360@francesco-nb>
References: <20240207225526.3953230-1-jm@ti.com>
 <20240211154411.GA3360@francesco-nb>
Message-ID: <22af7436-8833-4049-bdbb-f79bb3314ee8@ti.com>

Hi Francesco,

On 2/11/24 9:44 AM, Francesco Dolcini wrote:
> Hello Judith and TI folks,
> 
> On Wed, Feb 07, 2024 at 04:55:17PM -0600, Judith Mendez wrote:
>> This patch series aims to add or fix MMC properties:
>> OTAPDLY/ITAPDLY.
>>
>> The DLL properties ti,trm-icp and ti,driver-strength-ohm
>> should also be updated since only AM64x and AM62p devices
>> have a DLL to enable, so remove these properties when not
>> applicable.
> 
> Do you have any reference regarding this change? TI reference manual or
> anything like that?

I believe there is no specific documentation that states outright that
these device tree properties are not applicable for devices like AM62x.

There are a few hints in the device datasheet and TRM, if the MMC PHY
has a DLL to enable, DLL properties should show in both docs.

Also, you can read the MMC bindings doc description:
https://github.com/torvalds/linux/blob/master/Documentation/devicetree
/bindings/mmc/sdhci-am654.yaml#L179

> 
> No change needed in sdhci_am654.c? It seems that `drv_strength` is written
> to some register unconditionally, is it ok to do so?


Actually, we only write this value to the register if there is a DLL
to enable. If we have this property in device tree for devices like
AM62x and AM62ax, this property is ignored in the driver. So I am
removing this property from device tree as part of the effort to
clean up MMC nodes in device tree.

> 
> Do this change implies that there is no way to configure the drive
> strength on such SoCs and MMC/SD trace impedance must be the nominal
> 50ohm?

We do not support changing drive strength for these devices. My 
understanding is that the drive strength should default to about
40 ohms, which should be good enough for any eMMC operating mode.

~ Judith

> 
> Thanks,
> Francesco
> 



From conor at kernel.org  Mon Feb 12 09:34:16 2024
From: conor at kernel.org (Conor Dooley)
Date: Mon, 12 Feb 2024 17:34:16 +0000
Subject: [PATCH v3 1/2] dt-bindings: arm: sunxi: Add Sipeed Longan Module
 3H and Longan Pi 3H
In-Reply-To: <Zcn0POS-4BFGlRm9@xhacker>
References: <20240211081739.395-1-jszhang@kernel.org>
 <20240211081739.395-2-jszhang@kernel.org>
 <7ee6df91-76fa-44e8-ab81-fd4b63b58ce9@linaro.org>
 <Zcn0POS-4BFGlRm9@xhacker>
Message-ID: <20240212-stowaway-cartel-3aee8992cbd3@spud>

On Mon, Feb 12, 2024 at 06:34:36PM +0800, Jisheng Zhang wrote:
> On Sun, Feb 11, 2024 at 05:29:32PM +0100, Krzysztof Kozlowski wrote:
> > On 11/02/2024 09:17, Jisheng Zhang wrote:
> > > Add name & compatible for the Sipeed Longan Module 3H and Longan PI 3H
> > > board.
> > > 
> > > Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> > > Reviewed-by: Andre Przywara <andre.przywara at arm.com>
> > > ---
> > 
> > This is a friendly reminder during the review process.
> 
> Oops, I forgot to add Conor's ack...
> > 
> > It looks like you received a tag and forgot to add it.
> > 
> > If you do not know the process, here is a short explanation:
> > Please add Acked-by/Reviewed-by/Tested-by tags when posting new
> > versions, under or above your Signed-off-by tag. Tag is "received", when
> > provided in a message replied to you on the mailing list. Tools like b4
> > can help here. However, there's no need to repost patches *only* to add
> > the tags. The upstream maintainer will do that for tags received on the
> > version they apply.
> 
> IIRC, the b4 can only help on the latest version. If I missed the ack
> in v3, the ack tag will be lost. So how to handle this case? repost or
> Conor gave an ack to v3 again?

I think what the form letter means is that b4 could've been used to
update the tags before you sent out this version.

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Thanks,
Conor.
-------------- 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/20240212/a7f643fd/attachment-0001.sig>

From josua at solid-run.com  Mon Feb 12 09:38:07 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 12 Feb 2024 18:38:07 +0100
Subject: [PATCH v6 0/7] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
Message-ID: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>

This series adds DT bindings and dts descriptions for SolidRun AM642
based SoM and Hummingboard EVB.

Additionally a commit from downstream vendor kernel are included,
enhancing support for pru based ethernet.
I wasn't sure how to properly annotate it in commit description /
signed-off area ...:

1. add description for "Industrial Ethernet Peripherals" (IEP) to am64
   https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/commit/arch/arm64/boot/dts/ti/k3-am64-main.dtsi?h=ti-linux-6.1.y-cicd&id=5afb73d82a014b59462162d960b350b8c58e5ae6
   IEP is already supported in-tree by a driver, and used in
   k3-am65-main.dtsi.

Unfortunately dtbs_check still reports one problem:

- 'mux-controller' does not match any of the regexes
  The expectation seems to be that a mux-controller at minimum has an
  address, something to put behind an @, e.g. "mux-controller at 7".
  However this mux is not on a bus, it is just a gpio-mux,
  not sure how to name it better.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
Changes in v6:
- renamed pinctrl nodes to *-default-pins
  (reported by Vignesh Raghavendra <vigneshr at ti.com>)
  (dropped Reviewed-by: Andrew Davis <afd at ti.com>)
- removed tabs from pinctrl comments to shorten lines
- updated humidity sensor yaml with interrupts property
- updated spi-nor flash yaml with interrupts property
- Link to v5: https://lore.kernel.org/r/20240211-add-am64-som-v5-0-790ed7121249 at solid-run.com

Changes in v5:
- abracon,abx80x.yaml:
  - reworded 'compatible' description
  - removed $ref to interrupts.yaml
  - nested example in fake i2c
  - changed maintainer to rtc list
  (reported by Conor Dooley <conor at kernel.org>)
- patch 4/5 dts:
  - re-added status properties for sdhci nodes
    k3-am64-main.dtsi has been changed in-tree since v1
    such that sdhci nodes are explicitly status disabled now.
  - picked up reviewed-by
  (reported by Andrew Davis <afd at ti.com>)
- Link to v4: https://lore.kernel.org/r/20240202-add-am64-som-v4-0-5f8b12af5e71 at solid-run.com

Changes in v4:
- abracon,abx80x.yaml: fixed dtc error in example irq reference
- Link to v3: https://lore.kernel.org/r/20240202-add-am64-som-v3-0-2f44023d50e9 at solid-run.com

Changes in v3:
- removed lots more status properties, double-checked against soc dtsi
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
  (reported by Andrew Davis <afd at ti.com>)
- removed intentionally-disabled pcie node from dts
- rewrote yaml bindings to use enum instead of anyof+const+description
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
- abracon yaml
  - added missing maintainer
  - added diode type property type
  - added example
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>)
  - added reference to /schemas/interrupts.yaml#
- use generic name for pru ethernet controller node
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>)
- removed unnamed dmas from pru ethernet controller node
- moved pcie/usb3 features to dtb overlays
- Link to v2: https://lore.kernel.org/r/20240112-add-am64-som-v2-0-1385246c428c at solid-run.com

Changes in v2:
- reordered patchset to drop separate patch adding iep handle to som
- moved dtbs_check warnings to cover letter
- converted abracon abx80x rtc bindings to yaml
- updated dts:
  - remove unnecessary status properties
  - changed non-generic node names
  - use color property for led descriptions,
    they have no default function on evaluation board
  - drop earlycon bootargs from chosen node
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
- converted charger node to comment, part not assembled, has no bindings
- picked up acked-by on board bindings patch
- Link to v1: https://lore.kernel.org/r/20240103-add-am64-som-v1-0-dda1f9227aef at solid-run.com

---
Josua Mayer (6):
      dt-bindings: arm: ti: Add bindings for SolidRun AM642 HummingBoard-T
      dt-bindings: rtc: abx80x: convert to yaml
      dt-bindings: iio: humidity: hdc20x0: add optional interrupts property
      dt-bindings: mtd: spi-nor: add optional interrupts property
      arm64: dts: add description for solidrun am642 som and evaluation board
      arm64: dts: ti: hummingboard-t: add overlays for m.2 pci-e and usb-3

Suman Anna (1):
      arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes

 Documentation/devicetree/bindings/arm/ti/k3.yaml   |   7 +
 .../bindings/iio/humidity/ti,hdc2010.yaml          |   3 +
 .../devicetree/bindings/mtd/jedec,spi-nor.yaml     |   3 +
 .../devicetree/bindings/rtc/abracon,abx80x.txt     |  31 --
 .../devicetree/bindings/rtc/abracon,abx80x.yaml    |  79 +++
 arch/arm64/boot/dts/ti/Makefile                    |   7 +
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi           |  24 +
 .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  |  45 ++
 .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  |  44 ++
 arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 594 +++++++++++++++++++++
 11 files changed, 1098 insertions(+), 31 deletions(-)
---
base-commit: 83d0ff463b50d2395e05339a34e35d14ba82043f
change-id: 20240101-add-am64-som-51a1ca47edf3

Sincerely,
-- 
Josua Mayer <josua at solid-run.com>



From josua at solid-run.com  Mon Feb 12 09:38:09 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 12 Feb 2024 18:38:09 +0100
Subject: [PATCH v6 2/7] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
Message-ID: <20240212-add-am64-som-v6-2-b59edb2bc8c3@solid-run.com>

Convert the abracon abx80x rtc text bindings to dt-schema format.

In addition to the text description reference generic interrupts
properties and add an example.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ---------
 .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 79 ++++++++++++++++++++++
 2 files changed, 79 insertions(+), 31 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
deleted file mode 100644
index 2405e35a1bc0..000000000000
--- a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-Abracon ABX80X I2C ultra low power RTC/Alarm chip
-
-The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
-ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
-is the superset of ab180x.
-
-Required properties:
-
- - "compatible": should one of:
-        "abracon,abx80x"
-        "abracon,ab0801"
-        "abracon,ab0803"
-        "abracon,ab0804"
-        "abracon,ab0805"
-        "abracon,ab1801"
-        "abracon,ab1803"
-        "abracon,ab1804"
-        "abracon,ab1805"
-        "microcrystal,rv1805"
-	Using "abracon,abx80x" will enable chip autodetection.
- - "reg": I2C bus address of the device
-
-Optional properties:
-
-The abx804 and abx805 have a trickle charger that is able to charge the
-connected battery or supercap. Both the following properties have to be defined
-and valid to enable charging:
-
- - "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
- - "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
-                          resistor, the other values are in kOhm.
diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
new file mode 100644
index 000000000000..58dbbca27deb
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Abracon ABX80X I2C ultra low power RTC/Alarm chip
+
+maintainers:
+  - linux-rtc at vger.kernel.org
+
+allOf:
+  - $ref: rtc.yaml#
+
+properties:
+  compatible:
+    description:
+      The wildcard 'abracon,abx80x' may be used to support a mix
+      of different abracon rtc`s. In this case the driver
+      must perform auto-detection from ID register.
+    enum:
+      - abracon,abx80x
+      - abracon,ab0801
+      - abracon,ab0803
+      - abracon,ab0804
+      - abracon,ab0805
+      - abracon,ab1801
+      - abracon,ab1803
+      - abracon,ab1804
+      - abracon,ab1805
+      - microcrystal,rv1805
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  abracon,tc-diode:
+    description:
+      Trickle-charge diode type.
+      Required to enable charging backup battery.
+
+      Supported are 'standard' diodes with a 0.6V drop
+      and 'schottky' diodes with a 0.3V drop.
+    $ref: /schemas/types.yaml#/definitions/string
+    enum:
+      - standard
+      - schottky
+
+  abracon,tc-resistor:
+    description:
+      Trickle-charge resistor value in kOhm.
+      Required to enable charging backup battery.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 3, 6, 11]
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        rtc at 69 {
+            compatible = "abracon,abx80x";
+            reg = <0x69>;
+            abracon,tc-diode = "schottky";
+            abracon,tc-resistor = <3>;
+            interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
+        };
+    };

-- 
2.35.3



From josua at solid-run.com  Mon Feb 12 09:38:10 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 12 Feb 2024 18:38:10 +0100
Subject: [PATCH v6 3/7] dt-bindings: iio: humidity: hdc20x0: add optional
 interrupts property
In-Reply-To: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
Message-ID: <20240212-add-am64-som-v6-3-b59edb2bc8c3@solid-run.com>

HDC2010 and HDC2080 humidity sensors both have an interrupt / data-ready
signal which can be used for signaling to the host.

Add binding for "interrupts" property so that boards wiring this signal
may describe the connection.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml b/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml
index 79e75a8675cb..e3eca8917517 100644
--- a/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml
+++ b/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml
@@ -27,6 +27,9 @@ properties:
   reg:
     maxItems: 1
 
+  interrupts:
+    maxItems: 1
+
 required:
   - compatible
   - reg

-- 
2.35.3



From josua at solid-run.com  Mon Feb 12 09:38:11 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 12 Feb 2024 18:38:11 +0100
Subject: [PATCH v6 4/7] dt-bindings: mtd: spi-nor: add optional interrupts
 property
In-Reply-To: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
Message-ID: <20240212-add-am64-som-v6-4-b59edb2bc8c3@solid-run.com>

Some spi flash memories have an interrupt signal which can be used for
signalling on-chip events such as busy status or ecc errors to the host.

Add binding for "interrupts" property so that boards wiring this signal
may describe the connection.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
index 58f0cea160ef..6e3afb42926e 100644
--- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
+++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
@@ -52,6 +52,9 @@ properties:
     minItems: 1
     maxItems: 2
 
+  interrupts:
+    maxItems: 1
+
   m25p,fast-read:
     type: boolean
     description:

-- 
2.35.3



From josua at solid-run.com  Mon Feb 12 09:38:08 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 12 Feb 2024 18:38:08 +0100
Subject: [PATCH v6 1/7] dt-bindings: arm: ti: Add bindings for SolidRun
 AM642 HummingBoard-T
In-Reply-To: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
Message-ID: <20240212-add-am64-som-v6-1-b59edb2bc8c3@solid-run.com>

Add bindings for SolidRun AM642 HummingBoard-T Board, which is the
evaluation board for SolidRun AM642 SoM.

Signed-off-by: Josua Mayer <josua at solid-run.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/ti/k3.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
index c6506bccfe88..0233a8b0b6fc 100644
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -87,6 +87,13 @@ properties:
           - const: tq,am642-tqma6442l
           - const: ti,am642
 
+      - description: K3 AM642 SoC SolidRun SoM based boards
+        items:
+          - enum:
+              - solidrun,am642-hummingboard-t
+          - const: solidrun,am642-sr-som
+          - const: ti,am642
+
       - description: K3 AM654 SoC
         items:
           - enum:

-- 
2.35.3



From josua at solid-run.com  Mon Feb 12 09:38:13 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 12 Feb 2024 18:38:13 +0100
Subject: [PATCH v6 6/7] arm64: dts: add description for solidrun am642 som
 and evaluation board
In-Reply-To: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
Message-ID: <20240212-add-am64-som-v6-6-b59edb2bc8c3@solid-run.com>

Add description for the SolidRun AM642 SoM, and HummingBoard-T
evaluation board.

The SoM features:
- 1x cpsw ethernet with phy
- 2x pru ethernet with phy
- eMMC
- spi flash (assembly option)

Additionally microSD and usb-2.0 otg are included in the SoM
description as they are supported boot sources for the SOC boot-rom.

The Carrier provides:
- 3x RJ45 connector
- 2x M.2 connector
- USB-2.0 Hub
- USB-A Connector
- LEDs
- 2x CAN transceiver
- 1x RS485 transceiver
- sensors

The M.2 connectors support either USB-3.1 or PCI-E depending on status
of a mux. By default the mux is switched off.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/Makefile                    |   1 +
 arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 594 +++++++++++++++++++++
 3 files changed, 887 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..bd73ce06acba 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -38,6 +38,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-hdmi-audio.dtbo
 
 # Boards with AM64x SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
new file mode 100644
index 000000000000..234d76e4e944
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * DTS for SolidRun AM642 HummingBoard-T,
+ * running on Cortex A53.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-am642.dtsi"
+#include "k3-am642-sr-som.dtsi"
+
+/ {
+	model = "SolidRun AM642 HummingBoard-T";
+	compatible = "solidrun,am642-hummingboard-t", "solidrun,am642-sr-som", "ti,am642";
+
+	aliases {
+		serial5 = &main_uart3;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&leds_default_pins>;
+
+		/* D24 */
+		led1: led-1 {
+			label = "led1";
+			gpios = <&main_gpio0 29 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		/* D25 */
+		led2: led-2 {
+			label = "led2";
+			gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		/* D26 */
+		led3: led-3 {
+			label = "led3";
+			gpios = <&main_gpio0 33 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+	};
+
+	regulator-m2-3v3 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&regulator_pcie_3v3_default_pins>;
+		regulator-name = "m2-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&main_gpio1 17 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	regulator-vpp-1v8 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&regulator_vpp_1v8_default_pins>;
+		regulator-name = "vpp-1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		gpio = <&main_gpio1 78 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	serdes_mux: mux-controller {
+		compatible = "gpio-mux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&serdes_mux_default_pins>;
+		#mux-control-cells = <0>;
+		/*
+		 * Mux has 2 IOs:
+		 * - select: 0 = USB-3 (M2); 1 = PCIE (M1)
+		 * - shutdown: 0 = active; 1 = disabled (high impedance)
+		 */
+		mux-gpios = <&main_gpio1 40 GPIO_ACTIVE_HIGH>, <&main_gpio1 41 GPIO_ACTIVE_HIGH>;
+		/* default disabled */
+		idle-state = <2>;
+	};
+};
+
+&main_gpio0 {
+	m2-reset-hog {
+		gpio-hog;
+		gpios = <12 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m2-reset";
+	};
+
+	m1-m2-w-disable1-hog {
+		gpio-hog;
+		gpios = <32 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m1-m2-pcie-w-disable1";
+	};
+
+	m1-m2-w-disable2-hog {
+		gpio-hog;
+		gpios = <34 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m1-m2-pcie-w-disable2";
+	};
+};
+
+&main_gpio1 {
+	m1-pcie-clkreq0-hog {
+		gpio-hog;
+		gpios = <11 GPIO_ACTIVE_LOW>;
+		input;
+		line-name = "m1-pcie-clkreq0";
+	};
+
+	m2-pcie-clkreq-hog {
+		gpio-hog;
+		gpios = <35 GPIO_ACTIVE_LOW>;
+		input;
+		line-name = "m2-pcie-clkreq";
+	};
+};
+
+&main_i2c0 {
+	pinctrl-0 = <&main_i2c0_default_pins>, <&main_i2c0_int_default_pins>;
+
+	humidity-sensor at 41 {
+		compatible = "ti,hdc2010";
+		reg = <0x41>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+	light-sensor at 44 {
+		compatible = "ti,opt3001";
+		reg = <0x44>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+	/* charger at 6a */
+};
+
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_default_pins>;
+	status = "okay";
+
+	rtc at 69 {
+		compatible = "abracon,abx80x";
+		reg = <0x69>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtc_int_default_pins>;
+		abracon,tc-diode = "schottky";
+		abracon,tc-resistor = <3>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
+
+&main_mcan0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan0_default_pins>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <8000000>;
+	};
+};
+
+&main_mcan1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan1_default_pins>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <8000000>;
+	};
+};
+
+&main_pmx0 {
+	leds_default_pins: leds-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0074, PIN_OUTPUT, 7) /* GPMC0_AD14.GPIO0_29 */
+			AM64X_IOPAD(0x0078, PIN_OUTPUT, 7) /* GPMC0_AD15.GPIO0_30 */
+			AM64X_IOPAD(0x0088, PIN_OUTPUT, 7) /* GPMC0_OEn_REn.GPIO0_33 */
+		>;
+	};
+
+	main_i2c0_int_default_pins: main-i2c0-int-default-pins {
+		pinctrl-single,pins = <
+			/* external pull-up on Carrier */
+			AM64X_IOPAD(0x0098, PIN_INPUT, 7) /* GPMC0_WAIT0.GPIO0_37 */
+		>;
+	};
+
+	main_i2c1_default_pins: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x0268, PIN_INPUT, 0) /* I2C1_SCL.I2C1_SCL */
+			AM64X_IOPAD(0x026c, PIN_INPUT, 0) /* I2C1_SDA.I2C1_SDA */
+		>;
+	};
+
+	main_mcan0_default_pins: main-mcan0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0254, PIN_INPUT, 0) /* MCAN0_RX.MCAN0_RX */
+			AM64X_IOPAD(0x0250, PIN_OUTPUT, 0) /* MCAN0_TX.MCAN0_TX */
+		>;
+	};
+
+	main_mcan1_default_pins: main-mcan1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x025c, PIN_INPUT, 0) /* MCAN1_RX.MCAN1_RX */
+			AM64X_IOPAD(0x0258, PIN_OUTPUT, 0) /* MCAN1_TX.MCAN1_TX */
+		>;
+	};
+
+	main_uart3_default_pins: main-uart3-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x016c, PIN_INPUT, 10) /* PRG0_PRU0_GPO3.UART3_CTSn */
+			AM64X_IOPAD(0x0170, PIN_OUTPUT, 10) /* PRG0_PRU0_GPO4.UART3_TXD */
+			AM64X_IOPAD(0x0174, PIN_OUTPUT, 10) /* PRG0_PRU0_GPO5.UART3_RTSn */
+			AM64X_IOPAD(0x01ac, PIN_INPUT, 10) /* PRG0_PRU0_GPO19.UART3_RXD */
+		>;
+	};
+
+	pcie0_default_pins: pcie0-default-pins {
+		pinctrl-single,pins = <
+			/* connector M2 RESET */
+			AM64X_IOPAD(0x0030, PIN_OUTPUT, 7) /* OSPI0_CSn1.GPIO0_12 */
+			/* connectors M1 & M2 W_DISABLE1 */
+			AM64X_IOPAD(0x0084, PIN_OUTPUT, 7) /* GPMC0_ADVN_ALE.GPIO0_32 */
+			/* connectors M1 & M2 W_DISABLE2 */
+			AM64X_IOPAD(0x008c, PIN_OUTPUT, 7) /* GPMC0_WEN.GPIO0_34 */
+			/* connectors M1 & M2 PERST0 (PCI Reset) */
+			AM64X_IOPAD(0x019c, PIN_OUTPUT, 7) /* PRG0_PRU0_GPO15.GPIO1_15 */
+			/* connector M1 CLKREQ0 */
+			AM64X_IOPAD(0x018c, PIN_INPUT, 7) /* PRG0_PRU0_GPO11.GPIO1_11 */
+			/* connector M2 CLKREQ0 */
+			AM64X_IOPAD(0x01ec, PIN_INPUT, 7) /* PRG0_PRU1_GPO15.GPIO1_35 */
+		>;
+	};
+
+	regulator_pcie_3v3_default_pins: regulator-pcie-3v3-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01a4, PIN_OUTPUT, 7) /* PRG0_PRU0_GPO17.GPIO1_17 */
+		>;
+	};
+
+	regulator_vpp_1v8_default_pins: regulator-vpp-1v8-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x029c, PIN_OUTPUT, 7) /* MMC1_SDWP.GPIO1_78 */
+		>;
+	};
+
+	rtc_int_default_pins: rtc-int-default-pins {
+		pinctrl-single,pins = <
+			/* external pull-up on Carrier */
+			AM64X_IOPAD(0x00b4, PIN_INPUT, 7) /* GPMC0_CSn3.GPIO0_44 */
+		>;
+	};
+
+	serdes_mux_default_pins: serdes-mux-default-pins {
+		pinctrl-single,pins = <
+			/* SEL, 10k pull-down on carrier, 2.2k pullup on SoM */
+			AM64X_IOPAD(0x0200, PIN_OUTPUT, 7) /* PRG0_MDIO0_MDIO.GPIO1_40 */
+			/* EN */
+			AM64X_IOPAD(0x0204, PIN_OUTPUT, 7) /* PRG0_MDIO0_MDC.GPIO1_41 */
+		>;
+	};
+};
+
+&main_uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart3_default_pins>;
+	uart-has-rtscts;
+	rs485-rts-active-low;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+&usb0 {
+	dr_mode = "host";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
new file mode 100644
index 000000000000..c19d0b8bbf0f
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
@@ -0,0 +1,594 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ */
+
+#include <dt-bindings/net/ti-dp83869.h>
+
+/ {
+	model = "SolidRun AM642 SoM";
+	compatible = "solidrun,am642-sr-som", "ti,am642";
+
+	aliases {
+		ethernet0 = &cpsw_port1;
+		ethernet1 = &icssg1_emac0;
+		ethernet2 = &icssg1_emac1;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		serial2 = &main_uart0;
+	};
+
+	chosen {
+		/* SoC default UART console */
+		stdout-path = "serial2:115200n8";
+	};
+
+	/* PRU Ethernet Controller */
+	ethernet {
+		compatible = "ti,am642-icssg-prueth";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pru_rgmii1_default_pins>, <&pru_rgmii2_default_pins>;
+
+		sram = <&oc_sram>;
+		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
+		firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
+
+		/* configure internal pinmux for mii mode */
+		ti,pruss-gp-mux-sel = <2>, <2>, <2>, <2>, <2>, <2>;
+
+		ti,mii-g-rt = <&icssg1_mii_g_rt>;
+		ti,mii-rt = <&icssg1_mii_rt>;
+		ti,iep = <&icssg1_iep0>, <&icssg1_iep1>;
+
+		/*
+		 * Configure icssg interrupt controller to map pru-internal
+		 * interrupts 8/9 via channels 0/1 to host interrupts 0/1.
+		 *
+		 * For details see interrupt controller documentation:
+		 * Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
+		 */
+		interrupt-parent = <&icssg1_intc>;
+		interrupts = <24 0 2>, <25 1 3>;
+		interrupt-names = "tx_ts0", "tx_ts1";
+
+		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
+		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
+		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
+		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+			    "rx0", "rx1";
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			icssg1_emac0: port at 0 {
+				reg = <0>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4110>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				phy-handle = <&ethernet_phy2>;
+				phy-mode = "rgmii-id";
+			};
+
+			icssg1_emac1: port at 1 {
+				reg = <1>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4114>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				phy-handle = <&ethernet_phy1>;
+				phy-mode = "rgmii-id";
+			};
+		};
+	};
+
+	/* DDR16SS0:
+	 * - Bank 1 @ 0x080000000-0x0FFFFFFFF: max. 2GB in 32-bit address space
+	 * - Bank 2 @ 0x880000000-0x9FFFFFFFF: max. 6GB in 64-bit address space
+	 */
+	memory at 80000000 {
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+		      <0x00000008 0x80000000 0x00000001 0x80000000>;
+		device_type = "memory";
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		secure_ddr: optee at 9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+			no-map;
+		};
+
+		main_r5fss0_core0_dma_memory_region: r5f-dma-memory at a0000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_memory_region: r5f-memory at a0100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_dma_memory_region: r5f-dma-memory at a1000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_memory_region: r5f-memory at a1100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_dma_memory_region: r5f-dma-memory at a2000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_memory_region: r5f-memory at a2100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_dma_memory_region: r5f-dma-memory at a3000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_memory_region: r5f-memory at a3100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3100000 0x00 0xf00000>;
+			no-map;
+		};
+	};
+
+	vdd_mmc0: regulator-vdd-mmc0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd-mmc0";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&cpsw3g {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_default_pins>;
+};
+
+&cpsw3g_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio0_default_pins>;
+	status = "okay";
+
+	ethernet_phy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy0_default_pins>;
+		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 84 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+};
+
+&cpsw_port1 {
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy0>;
+};
+
+&cpsw_port2 {
+	status = "disabled";
+};
+
+&icssg1_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pru1_mdio0_default_pins>;
+	status = "okay";
+
+	ethernet_phy1: ethernet-phy at 3 {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy1_default_pins>;
+		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 20 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+
+	ethernet_phy2: ethernet-phy at f {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <0xf>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy2_default_pins>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 52 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+};
+
+&mailbox0_cluster2 {
+	status = "okay";
+
+	mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+
+	mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+		ti,mbox-rx = <2 0 2>;
+		ti,mbox-tx = <3 0 2>;
+	};
+};
+
+&mailbox0_cluster4 {
+	status = "okay";
+
+	mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+
+	mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+		ti,mbox-rx = <2 0 2>;
+		ti,mbox-tx = <3 0 2>;
+	};
+};
+
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_default_pins>;
+	status = "okay";
+
+	som_eeprom: eeprom at 50 {
+		compatible = "atmel,24c01";
+		reg = <0x50>;
+		pagesize = <8>;
+	};
+};
+
+&main_pmx0 {
+	/* hog global functions */
+	pinctrl-names = "default";
+	pinctrl-0 = <&ethernet_phy_default_pins>;
+
+	ethernet_phy_default_pins: ethernet-phy-default-pins {
+		pinctrl-single,pins = <
+			/* interrupt / power-down, external pull-up on SoM */
+			AM64X_IOPAD(0x0278, PIN_INPUT, 7) /* EXTINTn.GPIO1_70 */
+		>;
+	};
+
+	ethernet_phy0_default_pins: ethernet-phy0-default-pins {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x0154, PIN_OUTPUT, 7) /* PRG1_PRU1_GPO19.GPIO0_84 */
+			/* reference clock */
+			AM64X_IOPAD(0x0274, PIN_OUTPUT, 5) /* EXT_REFCLK1.CLKOUT0 */
+		>;
+	};
+
+	ethernet_phy1_default_pins: ethernet-phy1-default-pins {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x0150, PIN_OUTPUT, 7) /* PRG1_PRU1_GPO18.GPIO0_20 */
+			/* led0, external pull-down on SoM */
+			AM64X_IOPAD(0x0128, PIN_INPUT, 7) /* PRG1_PRU1_GPO8.GPIO0_73 */
+			/* led1/rxer */
+			AM64X_IOPAD(0x011c, PIN_INPUT, 7) /* PRG1_PRU1_GPO5.GPIO0_70 */
+		>;
+	};
+
+	ethernet_phy2_default_pins: ethernet-phy2-default-pins {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x00d4, PIN_OUTPUT, 7) /* PRG1_PRU0_GPO7.GPIO0_52 */
+			/* led0, external pull-down on SoM */
+			AM64X_IOPAD(0x00d8, PIN_INPUT, 7) /* PRG1_PRU0_GPO8.GPIO0_53 */
+			/* led1/rxer */
+			AM64X_IOPAD(0x00cc, PIN_INPUT, 7) /* PRG1_PRU0_GPO5.GPIO0_50 */
+		>;
+	};
+
+	main_i2c0_default_pins: main-i2c0-default-pins {
+		pinctrl-single,pins = <
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x0260, PIN_INPUT, 0) /* I2C0_SCL.I2C0_SCL */
+			AM64X_IOPAD(0x0264, PIN_INPUT, 0) /* I2C0_SDA.I2C0_SDA */
+		>;
+	};
+
+	/*
+	 * main_mmc0_default_pins: main-mmc0-default-pins
+	 *
+	 * MMC0_CMD: no padconfig
+	 * MMC0_CLK: no padconfig, external pull-up on SoM
+	 * MMC0_DAT0: no padconfig
+	 * MMC0_DAT1: no padconfig
+	 * MMC0_DAT2: no padconfig
+	 * MMC0_DAT3: no padconfig
+	 * MMC0_DAT4: no padconfig
+	 * MMC0_DAT5: no padconfig
+	 * MMC0_DAT6: no padconfig
+	 * MMC0_DAT7: no padconfig
+	 * MMC0_DS: no padconfig, external pull-down on SoM
+	 */
+
+	main_mmc1_default_pins: main-mmc1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0294, PIN_INPUT_PULLUP, 0) /* (J19) MMC1_CMD */
+			AM64X_IOPAD(0x028c, PIN_INPUT, 0) /* MMC1_CLK.MMC1_CLK */
+			AM64X_IOPAD(0x0288, PIN_INPUT_PULLUP, 0) /* MMC1_DAT0.MMC1_DAT0 */
+			AM64X_IOPAD(0x0284, PIN_INPUT_PULLUP, 0) /* MMC1_DAT1.MMC1_DAT1 */
+			AM64X_IOPAD(0x0280, PIN_INPUT_PULLUP, 0) /* MMC1_DAT2.MMC1_DAT2 */
+			AM64X_IOPAD(0x027c, PIN_INPUT_PULLUP, 0) /* MMC1_DAT3.MMC1_DAT3 */
+			/* external pull-down on SoM & Carrier */
+			AM64X_IOPAD(0x0298, PIN_INPUT_PULLUP, 0) /* MMC1_SDCD.MMC1_SDCD */
+			AM64X_IOPAD(0x0290, PIN_INPUT, 0) /* MMC1_CLKLB: clock loopback */
+		>;
+	};
+
+	main_uart0_default_pins: main-uart0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0230, PIN_INPUT, 0) /* UART0_RXD.UART0_RXD */
+			AM64X_IOPAD(0x0234, PIN_OUTPUT, 0) /* UART0_TXD.UART0_TXD */
+		>;
+	};
+
+	mdio0_default_pins: mdio0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01fc, PIN_OUTPUT, 4) /* PRG0_PRU1_GPO19.MDIO0_MDC */
+			AM64X_IOPAD(0x01f8, PIN_INPUT, 4) /* PRG0_PRU1_GPO18.MDIO0_MDIO */
+		>;
+	};
+
+	ospi0_default_pins: ospi0-default-pins {
+		pinctrl-single,pins = <
+			/* external pull-down on SoM */
+			AM64X_IOPAD(0x0000, PIN_OUTPUT, 0) /* OSPI0_CLK.OSPI0_CLK */
+			AM64X_IOPAD(0x0008, PIN_OUTPUT, 0) /* OSPI0_DQS.OSPI0_DQS */
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x002c, PIN_OUTPUT, 0) /* OSPI0_CSn0.OSPI0_CSn0 */
+			AM64X_IOPAD(0x000c, PIN_INPUT, 0) /* OSPI0_D0.OSPI0_D0 */
+			AM64X_IOPAD(0x0010, PIN_INPUT, 0) /* OSPI0_D1.OSPI0_D1 */
+			AM64X_IOPAD(0x0014, PIN_INPUT, 0) /* OSPI0_D2.OSPI0_D2 */
+			AM64X_IOPAD(0x0018, PIN_INPUT, 0) /* OSPI0_D3.OSPI0_D3 */
+			AM64X_IOPAD(0x001c, PIN_INPUT, 0) /* OSPI0_D4.OSPI0_D4 */
+			AM64X_IOPAD(0x0020, PIN_INPUT, 0) /* OSPI0_D5.OSPI0_D5 */
+			AM64X_IOPAD(0x0024, PIN_INPUT, 0) /* OSPI0_D6.OSPI0_D6 */
+			AM64X_IOPAD(0x0028, PIN_INPUT, 0) /* OSPI0_D7.OSPI0_D7 */
+		>;
+	};
+
+	ospi0_flash0_default_pins: ospi0-flash0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0034, PIN_OUTPUT, 7) /* OSPI0_CSn2.GPIO0_13 */
+			AM64X_IOPAD(0x0038, PIN_INPUT, 7) /* OSPI0_CSn3.GPIO0_14 */
+		>;
+	};
+
+	pru1_mdio0_default_pins: pru1-mdio0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0) /* PRG1_MDIO0_MDC.PRG1_MDIO0_MDC */
+			AM64X_IOPAD(0x0158, PIN_INPUT, 0) /* PRG1_MDIO0_MDIO.PRG1_MDIO0_MDIO */
+		>;
+	};
+
+	pru_rgmii1_default_pins: pru-rgmii1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x00b8, PIN_INPUT, 2) /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
+			AM64X_IOPAD(0x00bc, PIN_INPUT, 2) /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
+			AM64X_IOPAD(0x00c0, PIN_INPUT, 2) /* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
+			AM64X_IOPAD(0x00c4, PIN_INPUT, 2) /* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
+			AM64X_IOPAD(0x00d0, PIN_INPUT, 2) /* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
+			AM64X_IOPAD(0x00c8, PIN_INPUT, 2) /* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
+			AM64X_IOPAD(0x00e4, PIN_OUTPUT, 2) /* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
+			AM64X_IOPAD(0x00e8, PIN_OUTPUT, 2) /* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
+			AM64X_IOPAD(0x00ec, PIN_OUTPUT, 2) /* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
+			AM64X_IOPAD(0x00f0, PIN_OUTPUT, 2) /* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
+			AM64X_IOPAD(0x00f8, PIN_INPUT, 2) /* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
+			AM64X_IOPAD(0x00f4, PIN_OUTPUT, 2) /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
+		>;
+	};
+
+	pru_rgmii2_default_pins: pru-rgmii2-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0108, PIN_INPUT, 2) /* PRG1_PRU1_GPO0.RGMII2_RD0 */
+			AM64X_IOPAD(0x010c, PIN_INPUT, 2) /* PRG1_PRU1_GPO1.RGMII2_RD1 */
+			AM64X_IOPAD(0x0110, PIN_INPUT, 2) /* PRG1_PRU1_GPO2.RGMII2_RD2 */
+			AM64X_IOPAD(0x0114, PIN_INPUT, 2) /* PRG1_PRU1_GPO3.RGMII2_RD3 */
+			AM64X_IOPAD(0x0120, PIN_INPUT, 2) /* PRG1_PRU1_GPO6.RGMII2_RXC */
+			AM64X_IOPAD(0x0118, PIN_INPUT, 2) /* PRG1_PRU1_GPO4.RGMII2_RX_CTL */
+			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO11.RGMII2_TD0 */
+			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO12.RGMII2_TD1 */
+			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO13.RGMII2_TD2 */
+			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO14.RGMII2_TD3 */
+			AM64X_IOPAD(0x0148, PIN_INPUT, 2) /* PRG1_PRU1_GPO16.RGMII2_TXC */
+			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO15.RGMII2_TX_CTL */
+		>;
+	};
+
+	rgmii1_default_pins: rgmii1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01cc, PIN_INPUT, 4) /* PRG0_PRU1_GPO7.RGMII1_RD0 */
+			AM64X_IOPAD(0x01d4, PIN_INPUT, 4) /* PRG0_PRU1_GPO9.RGMII1_RD1 */
+			AM64X_IOPAD(0x01d8, PIN_INPUT, 4) /* PRG0_PRU1_GPO10.RGMII1_RD2 */
+			AM64X_IOPAD(0x01f4, PIN_INPUT, 4) /* PRG0_PRU1_GPO17.RGMII1_RD3 */
+			AM64X_IOPAD(0x0188, PIN_INPUT, 4) /* PRG0_PRU0_GPO10.RGMII1_RXC */
+			AM64X_IOPAD(0x0184, PIN_INPUT, 4) /* PRG0_PRU0_GPO9.RGMII1_RX_CTL */
+			AM64X_IOPAD(0x0124, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO7.RGMII1_TD0 */
+			AM64X_IOPAD(0x012c, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO9.RGMII1_TD1 */
+			AM64X_IOPAD(0x0130, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO10.RGMII1_TD2 */
+			AM64X_IOPAD(0x014c, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO17.RGMII1_TD3 */
+			AM64X_IOPAD(0x00e0, PIN_INPUT, 4) /* PRG1_PRU0_GPO10.RGMII1_TXC */
+			AM64X_IOPAD(0x00dc, PIN_OUTPUT, 4) /* PRG1_PRU0_GPO9.RGMII1_TX_CTL */
+		>;
+	};
+
+	usb0_default_pins: usb0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0) /* USB0_DRVVBUS.USB0_DRVVBUS */
+		>;
+	};
+};
+
+&main_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core0>;
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0_core1 {
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core1>;
+	memory-region = <&main_r5fss0_core1_dma_memory_region>,
+			<&main_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss1_core0 {
+	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core0>;
+	memory-region = <&main_r5fss1_core0_dma_memory_region>,
+			<&main_r5fss1_core0_memory_region>;
+};
+
+&main_r5fss1_core1 {
+	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core1>;
+	memory-region = <&main_r5fss1_core1_dma_memory_region>,
+			<&main_r5fss1_core1_memory_region>;
+};
+
+/* SoC default UART console */
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_default_pins>;
+	status = "okay";
+};
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_default_pins>;
+	num-cs = <1>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ospi0_flash0_default_pins>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <200000000>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
+		cdns,read-delay = <0>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&main_gpio0 13 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&sdhci0 {
+	/* mmc0 pins have no padconfig */
+	bus-width = <8>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+	non-removable;
+	cap-mmc-hw-reset;
+	no-sd;
+	/*
+	 * MMC controller supports switching between 1.8V and 3.3V signalling.
+	 * However MMC0 (unlike MMC1) does not integrate an LDO.
+	 * Explicitly link a regulator node for indicating to the driver which
+	 * voltages are actually usable.
+	 */
+	vqmmc-supply = <&vdd_mmc0>;
+	status = "okay";
+};
+
+/*
+ * microSD is on carrier - however since SoC can boot from it,
+ * configure it just in case.
+ */
+&sdhci1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_default_pins>;
+	bus-width = <4>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+	status = "okay";
+};
+
+/*
+ * USB settings are a carrier choice - however since SoC can boot from it,
+ * configure as USB-2.0 OTG here, keeping USB-3 serdes disabled.
+ */
+&usb0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_default_pins>;
+	dr_mode = "otg";
+	maximum-speed = "high-speed";
+};
+
+&usbss0 {
+	ti,vbus-divider;
+	ti,usb2-only;
+};

-- 
2.35.3



From josua at solid-run.com  Mon Feb 12 09:38:12 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 12 Feb 2024 18:38:12 +0100
Subject: [PATCH v6 5/7] arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
In-Reply-To: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
Message-ID: <20240212-add-am64-som-v6-5-b59edb2bc8c3@solid-run.com>

From: Suman Anna <s-anna at ti.com>

The ICSSG IP on AM64x SoCs have two Industrial Ethernet Peripherals (IEPs)
to manage/generate Industrial Ethernet functions such as time stamping.
Each IEP sub-module is sourced from an internal clock mux that can be
derived from either of the IP instance's ICSSG_IEP_GCLK or from another
internal ICSSG CORE_CLK mux. Add both the IEP nodes for both the ICSSG
instances. The IEP clock is currently configured to be derived
indirectly from the ICSSG_ICLK running at 250 MHz.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
Signed-off-by: Suman Anna <s-anna at ti.com>
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index e348114f42e0..9d2dad8ae8df 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -1244,6 +1244,18 @@ icssg0_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg0_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
+		icssg0_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
 		icssg0_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
@@ -1385,6 +1397,18 @@ icssg1_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg1_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
+		icssg1_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
 		icssg1_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;

-- 
2.35.3



From josua at solid-run.com  Mon Feb 12 09:38:14 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 12 Feb 2024 18:38:14 +0100
Subject: [PATCH v6 7/7] arm64: dts: ti: hummingboard-t: add overlays for
 m.2 pci-e and usb-3
In-Reply-To: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
Message-ID: <20240212-add-am64-som-v6-7-b59edb2bc8c3@solid-run.com>

HummingBoard-T features two M.2 connectors labeled "M1" and "M2".
The single SerDes lane of the SoC can be routed to either M1 pci-e
signals, or M2 usb-3 signals by a gpio-controlled mux.

Add overlays for each configuration.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/Makefile                    |  6 +++
 .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  | 45 ++++++++++++++++++++++
 .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  | 44 +++++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index bd73ce06acba..cd12720638c7 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -37,8 +37,14 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-imx219.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-hdmi-audio.dtbo
 
 # Boards with AM64x SoC
+k3-am642-hummingboard-t-pcie-dtbs := \
+	k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-pcie.dtbo
+k3-am642-hummingboard-t-usb3-dtbs := \
+	k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-usb3.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-pcie.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-usb3.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
new file mode 100644
index 000000000000..bd9a5caf20da
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable PCI-E.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&pcie0_rc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_default_pins>;
+	reset-gpios = <&main_gpio1 15 GPIO_ACTIVE_HIGH>;
+	phys = <&serdes0_link>;
+	phy-names = "pcie-phy";
+	num-lanes = <1>;
+	status = "okay";
+};
+
+&serdes0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	serdes0_link: phy at 0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		cdns,phy-type = <PHY_TYPE_PCIE>;
+		#phy-cells = <0>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes_ln_ctrl {
+	idle-states = <AM64_SERDES0_LANE0_PCIE0>;
+};
+
+&serdes_mux {
+	idle-state = <1>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
new file mode 100644
index 000000000000..ffcc3bd3c7bc
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable USB-3.1.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&serdes0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	serdes0_link: phy at 0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		cdns,phy-type = <PHY_TYPE_USB3>;
+		#phy-cells = <0>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes_ln_ctrl {
+	idle-states = <AM64_SERDES0_LANE0_USB>;
+};
+
+&serdes_mux {
+	idle-state = <0>;
+};
+
+&usbss0 {
+	/delete-property/ ti,usb2-only;
+};
+
+&usb0 {
+	maximum-speed = "super-speed";
+	phys = <&serdes0_link>;
+	phy-names = "cdns3,usb3-phy";
+};

-- 
2.35.3



From maxime.chevallier at bootlin.com  Mon Feb 12 09:53:32 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Mon, 12 Feb 2024 18:53:32 +0100
Subject: [PATCH net-next v3 7/7] net: pcs: rzn1-miic: Init RX clock
 early if MAC requires it
In-Reply-To: <20240212-rxc_bugfix-v3-7-e9f2eb6b3b05@bootlin.com>
References: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com>
	<20240212-rxc_bugfix-v3-7-e9f2eb6b3b05@bootlin.com>
Message-ID: <20240212185332.2ebf2935@device-28.home>

Hi Romain,

On Mon, 12 Feb 2024 17:42:14 +0100
Romain Gantois <romain.gantois at bootlin.com> wrote:

> The GMAC1 controller in the RZN1 IP requires the RX MII clock signal to be
> started before it initializes its own hardware, thus before it calls
> phylink_start.
> 
> Check the rxc_always_on pcs flag and enable the clock signal during the
> link validation phase.

It looks like this commit log doesn't match the content of the commit.

> Reported-by: Cl?ment L?ger <clement.leger at bootlin.com>
> Link: https://lore.kernel.org/linux-arm-kernel/20230116103926.276869-4-clement.leger at bootlin.com/
> Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
> ---
>  drivers/net/pcs/pcs-rzn1-miic.c | 27 +++++++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c
> index d93f84fbb1fd..b0d9736c678e 100644
> --- a/drivers/net/pcs/pcs-rzn1-miic.c
> +++ b/drivers/net/pcs/pcs-rzn1-miic.c
> @@ -279,10 +279,37 @@ static int miic_validate(struct phylink_pcs *pcs, unsigned long *supported,
>  	return -EINVAL;
>  }
>  
> +static int miic_pre_init(struct phylink_pcs *pcs)
> +{
> +	struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs);
> +	struct miic *miic = miic_port->miic;
> +	u32 val;
> +
> +	/* Start RX clock if required */
> +	if (pcs->rxc_always_on) {
> +		/* In MII through mode, the clock signals will be driven by the
> +		 * external PHY, which might not be initialized yet. Set RMII
> +		 * as default mode to ensure that a reference clock signal is
> +		 * generated.
> +		 */
> +		miic_port->interface = PHY_INTERFACE_MODE_RMII;

There's this check in miic_config :

	if (interface != miic_port->interface) {
		val |= FIELD_PREP(MIIC_CONVCTRL_CONV_SPEED, speed);
		mask |= MIIC_CONVCTRL_CONV_SPEED;
		miic_port->interface = interface;
	}

As you set the interface to RMII and set the CONV_MODE below without
really looking at the speed, is there any risk of a mismatch between
the configured mode and the speed ?

Thanks,

Maxime


From oliver.upton at linux.dev  Mon Feb 12 10:05:42 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 18:05:42 +0000
Subject: [PATCH 0/2] ARM64: Fixes for FEAT_E2H0 handling
In-Reply-To: <20240212144736.1933112-1-maz@kernel.org>
References: <20240212144736.1933112-1-maz@kernel.org>
Message-ID: <170776111436.2280274.3289030811512349732.b4-ty@linux.dev>

On Mon, 12 Feb 2024 14:47:34 +0000, Marc Zyngier wrote:
> As the FEAT_E2H0 handling series has made it to -next, some of its
> shortcomings are becoming apparent:
> 
> - A missing ID register in __read_sysreg_by_encoding() is causing CPU
>   hotplug to explode (reported by Marek)
> 
> - NV1 is getting advertised on HW that doesn't have FEAT_NV, which is
>   fairly harmless, but still annoying
> 
> [...]

Applied to kvmarm/next, thanks!

[1/2] arm64: cpufeatures: Add missing ID_AA64MMFR4_EL1 to __read_sysreg_by_encoding()
      https://git.kernel.org/kvmarm/kvmarm/c/87b8cf2387c5
[2/2] arm64: cpufeatures: Only check for NV1 if NV is present
      https://git.kernel.org/kvmarm/kvmarm/c/3673d01a2f55

--
Best,
Oliver


From wahrenst at gmx.net  Mon Feb 12 10:28:36 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon, 12 Feb 2024 19:28:36 +0100
Subject: [PATCH v1 14/14] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <20240210012114.489102-15-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-15-sre@kernel.org>
Message-ID: <c38e7c68-e725-4174-aa0a-0594a55c8d56@gmx.net>

Hi Sebastian,

Am 10.02.24 um 02:18 schrieb Sebastian Reichel:
> Add UNI-T UTi260b thermal camera board.
>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>   arch/arm/boot/dts/nxp/imx/Makefile            |   1 +
>   arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts | 564 ++++++++++++++++++
>   2 files changed, 565 insertions(+)
>   create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
>
> diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile
> index a724d1a7a9a0..47350cf3ddeb 100644
> --- a/arch/arm/boot/dts/nxp/imx/Makefile
> +++ b/arch/arm/boot/dts/nxp/imx/Makefile
> @@ -349,6 +349,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
>   	imx6ull-tarragon-slavext.dtb \
>   	imx6ull-tqma6ull2-mba6ulx.dtb \
>   	imx6ull-tqma6ull2l-mba6ulx.dtb \
> +	imx6ull-uti260b.dtb \
>   	imx6ulz-14x14-evk.dtb \
>   	imx6ulz-bsh-smm-m2.dtb
>   dtb-$(CONFIG_SOC_IMX7D) += \
> diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
> new file mode 100644
> index 000000000000..336727895fa4
> --- /dev/null
> +++ b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
> @@ -0,0 +1,564 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +// Copyright (C) 2022 Sebastian Reichel <sre at kernel.org>
2024 ?
> +
> +/dts-v1/;
> +#include "imx6ull.dtsi"
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/clock/imx6ul-clock.h>
> +
> +/ {
> +	model = "UNI-T UTi260B Thermal Camera";
> +	compatible = "uni-t,imx6ull-uti260b", "fsl,imx6ull";
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	memory at 80000000 {
> +		device_type = "memory";
> +		reg = <0x80000000 0x20000000>;
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&mux_led_ctrl>;
> +
> +		led {
> +			label = "led";
The label property is deprecated, please use color and function instead.
> +			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +		};
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&mux_gpio_keys>;
> +		autorepeat;
> +
> +		up-key {
> +			label = "Up";
> +			gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_UP>;
> +		};
> +
> +		down-key {
> +			label = "Down";
> +			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_DOWN>;
> +		};
> +
> +		left-key {
> +			label = "Left";
> +			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_LEFT>;
> +		};
> +
> +		right-key {
> +			label = "Right";
> +			gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_RIGHT>;
> +		};
> +
> +		ok-key {
> +			label = "Ok";
> +			gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_ENTER>;
> +		};
> +
> +		return-key {
> +			label = "Return";
> +			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_ESC>;
> +		};
> +
> +		play-key {
> +			label = "Media";
> +			gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_MEDIA>;
> +		};
> +
> +		trigger-key {
> +			label = "Trigger";
> +			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
> +			linux,code = <BTN_TRIGGER>;
> +		};
> +
> +		power-key {
> +			label = "Power";
> +			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_POWER>;
> +		};
> +
> +		light-key {
> +			label = "Light";
> +			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_LIGHTS_TOGGLE>;
> +		};
> +	};
> +
> +	panel_backlight: backlight {
> +		compatible = "pwm-backlight";
> +		brightness-levels = <0 4 8 16 32 64 128 255>;
> +		default-brightness-level = <6>;
> +		enable-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&mux_backlight_enable>;
> +		power-supply = <&reg_vsd>;
> +		pwms = <&pwm1 0 50000 0>;
> +	};
> +
> +	reg_vsd: regulator-vsd {
i think the node name should be just "regulator"
> +		compatible = "regulator-fixed";
> +		regulator-name = "VSD_3V3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +	};
> +
> +	reg_vref: regulator-vref-4v2 {
dito
> +		compatible = "regulator-fixed";
> +		regulator-name = "VREF_4V2";
> +		regulator-min-microvolt = <4200000>;
> +		regulator-max-microvolt = <4200000>;
> +	};
> +
> +	tp5000: charger {
> +		compatible = "gpio-charger";
> +		charger-type = "usb-sdp";
> +		gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&mux_charger_stat1>;
> +	};
> +
> +	battery: battery {
> +		compatible = "simple-battery";
> +		/* generic 26650 battery */
> +		device-chemistry = "lithium-ion";
> +		charge-full-design-microamp-hours = <5000000>;
> +		voltage-max-design-microvolt = <4200000>;
> +		voltage-min-design-microvolt = <3300000>;
> +	};
> +
> +	fuel-gauge {
> +		compatible = "adc-battery";
> +		charged-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
> +		io-channel-names = "voltage";
> +		io-channels = <&adc1 7>;
> +		monitored-battery = <&battery>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&mux_charger_stat2>;
> +		power-supplies = <&tp5000>;
> +	};
> +
> +	poweroff {
> +		compatible = "gpio-poweroff";
> +		gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&mux_poweroff>;
> +	};
> +};
> +
> +&gpio1 {
> +	ir-reset-hog {
> +		gpio-hog;
> +		gpios = <3 GPIO_ACTIVE_LOW>;
> +		line-name = "ir-reset-gpio";
> +		output-low;
> +		pinctrl-0 = <&mux_ir_reset>;
Doesn't this miss pinctrl-names = "default" ?
> +	};
> +};
> +
> +&gpio2 {
> +	/* configuring this to output-high results in poweroff */
> +	power-en-hog {
> +		gpio-hog;
> +		gpios = <6 GPIO_ACTIVE_HIGH>;
> +		line-name = "power-en-gpio";
> +		output-low;
> +		pinctrl-0 = <&mux_poweroff2>;
> +	};
> +};
> +
> +&ecspi3 {
> +	cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mux_spi3>, <&mux_spi3_cs>;
> +	status = "okay";
> +
> +	panel at 0 {
> +		compatible = "inanbo,t28cp45tn89-v17";
> +		reg = <0>;
> +		backlight = <&panel_backlight>;
> +		power-supply = <&reg_vsd>;
> +		spi-cpha;
> +		spi-cpol;
> +		spi-max-frequency = <100000>;
This seems slow to me. Is this a limitation of the display?
> +		spi-rx-bus-width = <0>;
> +
> +		port {
> +			panel_in: endpoint {
> +				remote-endpoint = <&display_out>;
> +			};
> +		};
> +	};
> +};
> +
> +&uart1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mux_uart>;
> +	status = "okay";
> +};
> +
> +&pwm1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mux_pwm>;
> +	status = "okay";
> +};
> +
> +&i2c1 {
> +	clock-frequency = <100000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mux_i2c1>;
> +	status = "okay";
> +
> +	camera at 21 {
> +		compatible = "galaxycore,gc0308";
> +		reg = <0x21>;
> +		clocks = <&clks IMX6UL_CLK_CSI>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&mux_gc0308>;
> +		powerdown-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
> +		reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
> +		vdd28-supply = <&reg_vsd>;
> +
> +		port {
> +			gc0308_to_parallel: endpoint {
> +				remote-endpoint = <&parallel_from_gc0308>;
> +				bus-width = <8>;
> +				data-shift = <2>; /* lines 9:2 are used */
> +				hsync-active = <1>; /* active high */
> +				vsync-active = <1>; /* active high */
> +				data-active = <1>; /* active high */
> +				pclk-sample = <1>; /* sample on rising edge */
> +			};
> +		};
> +	};
> +};
> +
> +&csi {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mux_csi>;
> +
> +	port {
> +		parallel_from_gc0308: endpoint {
> +			remote-endpoint = <&gc0308_to_parallel>;
> +		};
> +	};
> +};
> +
> +&i2c2 {
> +	clock-frequency = <100000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mux_i2c2>;
> +	status = "okay";
> +
> +	rtc at 51 {
> +		compatible = "nxp,pcf8563";
> +		reg = <0x51>;
> +	};
> +};
> +
> +&lcdif {
> +	assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;
> +	assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mux_lcd_data>, <&mux_lcd_ctrl>;
> +	status = "okay";
> +
> +	port {
> +		display_out: endpoint {
> +			remote-endpoint = <&panel_in>;
> +		};
> +	};
> +};
> +
> +&usdhc1 {
Would be nice to place a comment above this, which mentions the intended
use case: eMMC, SD card, ...
> +	cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
> +	keep-power-in-suspend;
> +	no-1-8-v;
> +	pinctrl-names = "default", "state_100mhz", "state_200mhz";
> +	pinctrl-0 = <&mux_sdhc1>, <&mux_sdhc1_cd>;
> +	pinctrl-1 = <&mux_sdhc1_100mhz>, <&mux_sdhc1_cd>;
> +	pinctrl-2 = <&mux_sdhc1_200mhz>, <&mux_sdhc1_cd>;
> +	wakeup-source;
> +	vmmc-supply = <&reg_vsd>;
> +	status = "okay";
> +};
> +
> +&usdhc2 {
dito

Best regards
> +	keep-power-in-suspend;
> +	no-1-8-v;
> +	non-removable;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mux_sdhc2>;
> +	wakeup-source;
> +	status = "okay";
> +};
> +
> +&wdog1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mux_wdog>;
> +};
> +
> +&adc1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mux_adc>;
> +	vref-supply = <&reg_vref>;
> +	#io-channel-cells = <1>;
> +	status = "okay";
> +};
> +
>


From cristian.ciocaltea at collabora.com  Mon Feb 12 10:36:03 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 12 Feb 2024 20:36:03 +0200
Subject: [PATCH v2 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <61af7b121b23fe8ed06df5348692f862b9b125bf.camel@gmail.com>
References: <20240205-phy-hdptx-v2-0-a7150814c047@collabora.com>
 <20240205-phy-hdptx-v2-2-a7150814c047@collabora.com>
 <61af7b121b23fe8ed06df5348692f862b9b125bf.camel@gmail.com>
Message-ID: <4efca2ec-b078-4421-8956-e3add15d8f62@collabora.com>

Hi Luis,

On 2/12/24 18:44, Luis de Arquer wrote:
> Hi Cristian,
> 
> On Mon, 2024-02-05 at 13:24 +0200, Cristian Ciocaltea wrote:
>> +
>> +static bool hdptx_phy_clk_pll_calc(unsigned int data_rate,
>> +				   struct ropll_config *cfg)
>> +{
>> +	const unsigned int fout = data_rate / 2, fref = 24000;
>> +	unsigned long k = 0, lc, k_sub, lc_sub;
>> +	unsigned int fvco, sdc;
>> +	u32 mdiv, sdiv, n = 8;
>> +
>> +	for (sdiv = 16; sdiv >= 1; sdiv--) {
>> +		if (sdiv % 2 && sdiv != 1)
>> +			continue;
>> +
>> +		fvco = fout * sdiv;
>> +
>> +		if (fvco < 2000000 || fvco > 4000000)
>> +			continue;
>> +
> 
> What about adding a check to data_rate, maybe like
> 
> if (fout > 0x0FFFFFFF)
> 	return false;
> 
> or similar, before the for loop, to keep the multiplication safe?
> 
> Right now it would be redundant, given that data_rate was, at some
> point, encoded in 28 bits within bus_width. But can prevent future pain,
> especially after changing to phy_configure_opts_hdmi.

Indeed, it makes sense to do the check, thanks for the heads up!
I was almost ready to submit v3, so this arrived just in time. :-)

Regards,
Cristian


From cristian.ciocaltea at collabora.com  Mon Feb 12 10:52:28 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 12 Feb 2024 20:52:28 +0200
Subject: [PATCH v3 0/2] Add support for RK3588 HDMI/eDP Combo PHY
Message-ID: <20240212-phy-hdptx-v3-0-2cde680cd024@collabora.com>

Add driver and bindings to add initial support the Rockchip HDMI/eDP TX
Combo PHY found on RK3588 SoC.

The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
and eDP links.

Please note that currently only the TMDS related functionality has been
implemented.  This has been tested on Radxa ROCK 5B and Rockchip EVB1
boards.

Changes in v3:
- Collected R-b & T-b tags from Heiko
- Converted all *_REG() args to lowercase (Vinod)
- Dropped unnecessary register read/write wrappers (Vinod)
- Added rate overflow check in hdptx_phy_clk_pll_calc() (Luis)
- Link to v2:
  https://lore.kernel.org/r/20240205-phy-hdptx-v2-0-a7150814c047 at collabora.com

Changes in v2:
- Rebased series onto next-20240129
- Removed patch 'dt-bindings: soc: rockchip: Add rk3588 hdptxphy syscon'
  already applied by Heiko
- For consistency with SoC TRM, replaced all references to DP with eDP
- Updated PHY schema per Krzysztof's review; also collected his R-b tag
- Dropped FRL, EARC and 10-bit color depth functionality until the HDMI
  configuration options become available in PHY API
- Squashed lots of regmap_write operations via regmap_multi_reg_write
  (Sebastian)
- Introduced parametrized {CMN|SB|LNTOP|LANE}_REG() macros to replace
  the long list of register defines
- Optimized handling of the config arrays by using ARRAY_SIZE() (Sascha)
- Link to v1:
  https://lore.kernel.org/r/20240119193806.1030214-1-cristian.ciocaltea at collabora.com

---
Cristian Ciocaltea (2):
      dt-bindings: phy: Add Rockchip HDMI/eDP Combo PHY schema
      phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver

 .../bindings/phy/rockchip,rk3588-hdptx-phy.yaml    |   91 ++
 drivers/phy/rockchip/Kconfig                       |    8 +
 drivers/phy/rockchip/Makefile                      |    1 +
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c  | 1028 ++++++++++++++++++++
 4 files changed, 1128 insertions(+)
---
base-commit: 596764183be8ebb13352b281a442a1f1151c9b06
change-id: 20240128-phy-hdptx-8a98ab60d18e



From cristian.ciocaltea at collabora.com  Mon Feb 12 10:52:29 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 12 Feb 2024 20:52:29 +0200
Subject: [PATCH v3 1/2] dt-bindings: phy: Add Rockchip HDMI/eDP Combo PHY
 schema
In-Reply-To: <20240212-phy-hdptx-v3-0-2cde680cd024@collabora.com>
References: <20240212-phy-hdptx-v3-0-2cde680cd024@collabora.com>
Message-ID: <20240212-phy-hdptx-v3-1-2cde680cd024@collabora.com>

Add dt-binding schema for the HDMI/eDP Transmitter Combo PHY found on
Rockchip RK3588 SoC.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 .../bindings/phy/rockchip,rk3588-hdptx-phy.yaml    | 91 ++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml
new file mode 100644
index 000000000000..54e822c715f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml
@@ -0,0 +1,91 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/rockchip,rk3588-hdptx-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC HDMI/eDP Transmitter Combo PHY
+
+maintainers:
+  - Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3588-hdptx-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Reference clock
+      - description: APB clock
+
+  clock-names:
+    items:
+      - const: ref
+      - const: apb
+
+  "#phy-cells":
+    const: 0
+
+  resets:
+    items:
+      - description: PHY reset line
+      - description: APB reset line
+      - description: INIT reset line
+      - description: CMN reset line
+      - description: LANE reset line
+      - description: ROPLL reset line
+      - description: LCPLL reset line
+
+  reset-names:
+    items:
+      - const: phy
+      - const: apb
+      - const: init
+      - const: cmn
+      - const: lane
+      - const: ropll
+      - const: lcpll
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: Some PHY related data is accessed through GRF regs.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+  - resets
+  - reset-names
+  - rockchip,grf
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
+    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      phy at fed60000 {
+        compatible = "rockchip,rk3588-hdptx-phy";
+        reg = <0x0 0xfed60000 0x0 0x2000>;
+        clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
+        clock-names = "ref", "apb";
+        #phy-cells = <0>;
+        resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
+                 <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
+                 <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
+                 <&cru SRST_HDPTX0_LCPLL>;
+        reset-names = "phy", "apb", "init", "cmn", "lane", "ropll", "lcpll";
+        rockchip,grf = <&hdptxphy_grf>;
+      };
+    };

-- 
2.43.0



From cristian.ciocaltea at collabora.com  Mon Feb 12 10:52:30 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 12 Feb 2024 20:52:30 +0200
Subject: [PATCH v3 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <20240212-phy-hdptx-v3-0-2cde680cd024@collabora.com>
References: <20240212-phy-hdptx-v3-0-2cde680cd024@collabora.com>
Message-ID: <20240212-phy-hdptx-v3-2-2cde680cd024@collabora.com>

Add driver for the HDMI/eDP TX Combo PHY found on Rockchip RK3588 SoC.

The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
and eDP links.  The maximum data rate is 12Gbps (FRL), while the minimum
is 250Mbps (TMDS).

Only the TMDS link is currently supported.

Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
Tested-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/Kconfig                      |    8 +
 drivers/phy/rockchip/Makefile                     |    1 +
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 1028 +++++++++++++++++++++
 3 files changed, 1037 insertions(+)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 94360fc96a6f..a34f67bb7e61 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -83,6 +83,14 @@ config PHY_ROCKCHIP_PCIE
 	help
 	  Enable this to support the Rockchip PCIe PHY.
 
+config PHY_ROCKCHIP_SAMSUNG_HDPTX
+	tristate "Rockchip Samsung HDMI/eDP Combo PHY driver"
+	depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
+	select GENERIC_PHY
+	help
+	  Enable this to support the Rockchip HDMI/eDP Combo PHY
+	  with Samsung IP block.
+
 config PHY_ROCKCHIP_SNPS_PCIE3
 	tristate "Rockchip Snps PCIe3 PHY Driver"
 	depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
index 7eab129230d1..3d911304e654 100644
--- a/drivers/phy/rockchip/Makefile
+++ b/drivers/phy/rockchip/Makefile
@@ -8,6 +8,7 @@ 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_SAMSUNG_HDPTX)	+= phy-rockchip-samsung-hdptx.o
 obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3)	+= phy-rockchip-snps-pcie3.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-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
new file mode 100644
index 000000000000..a2b3bd799aa8
--- /dev/null
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -0,0 +1,1028 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2024 Collabora Ltd.
+ *
+ * Author: Algea Cao <algea.cao at rock-chips.com>
+ * Author: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/rational.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#define GRF_HDPTX_CON0			0x00
+#define HDPTX_I_PLL_EN			BIT(7)
+#define HDPTX_I_BIAS_EN			BIT(6)
+#define HDPTX_I_BGR_EN			BIT(5)
+#define GRF_HDPTX_STATUS		0x80
+#define HDPTX_O_PLL_LOCK_DONE		BIT(3)
+#define HDPTX_O_PHY_CLK_RDY		BIT(2)
+#define HDPTX_O_PHY_RDY			BIT(1)
+#define HDPTX_O_SB_RDY			BIT(0)
+
+#define HDTPX_REG(_n, _min, _max)				\
+	(							\
+		BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) +	\
+		BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) +	\
+		((0x##_n) * 4)					\
+	)
+
+#define CMN_REG(n)			HDTPX_REG(n, 0000, 00a7)
+#define SB_REG(n)			HDTPX_REG(n, 0100, 0129)
+#define LNTOP_REG(n)			HDTPX_REG(n, 0200, 0229)
+#define LANE_REG(n)			HDTPX_REG(n, 0300, 062d)
+
+/* CMN_REG(0008) */
+#define LCPLL_EN_MASK			BIT(6)
+#define LCPLL_LCVCO_MODE_EN_MASK	BIT(4)
+/* CMN_REG(001e) */
+#define LCPLL_PI_EN_MASK		BIT(5)
+#define LCPLL_100M_CLK_EN_MASK		BIT(0)
+/* CMN_REG(0025) */
+#define LCPLL_PMS_IQDIV_RSTN		BIT(4)
+/* CMN_REG(0028) */
+#define LCPLL_SDC_FRAC_EN		BIT(2)
+#define LCPLL_SDC_FRAC_RSTN		BIT(0)
+/* CMN_REG(002d) */
+#define LCPLL_SDC_N_MASK		GENMASK(3, 1)
+/* CMN_REG(002e) */
+#define LCPLL_SDC_NUMBERATOR_MASK	GENMASK(5, 0)
+/* CMN_REG(002f) */
+#define LCPLL_SDC_DENOMINATOR_MASK	GENMASK(7, 2)
+#define LCPLL_SDC_NDIV_RSTN		BIT(0)
+/* CMN_REG(003d) */
+#define ROPLL_LCVCO_EN			BIT(4)
+/* CMN_REG(004e) */
+#define ROPLL_PI_EN			BIT(5)
+/* CMN_REG(005c) */
+#define ROPLL_PMS_IQDIV_RSTN		BIT(5)
+/* CMN_REG(005e) */
+#define ROPLL_SDM_EN_MASK		BIT(6)
+#define ROPLL_SDM_FRAC_EN_RBR		BIT(3)
+#define ROPLL_SDM_FRAC_EN_HBR		BIT(2)
+#define ROPLL_SDM_FRAC_EN_HBR2		BIT(1)
+#define ROPLL_SDM_FRAC_EN_HBR3		BIT(0)
+/* CMN_REG(0064) */
+#define ROPLL_SDM_NUM_SIGN_RBR_MASK	BIT(3)
+/* CMN_REG(0069) */
+#define ROPLL_SDC_N_RBR_MASK		GENMASK(2, 0)
+/* CMN_REG(0074) */
+#define ROPLL_SDC_NDIV_RSTN		BIT(2)
+#define ROPLL_SSC_EN			BIT(0)
+/* CMN_REG(0081) */
+#define OVRD_PLL_CD_CLK_EN		BIT(8)
+#define PLL_CD_HSCLK_EAST_EN		BIT(0)
+/* CMN_REG(0086) */
+#define PLL_PCG_POSTDIV_SEL_MASK	GENMASK(7, 4)
+#define PLL_PCG_CLK_SEL_MASK		GENMASK(3, 1)
+#define PLL_PCG_CLK_EN			BIT(0)
+/* CMN_REG(0087) */
+#define PLL_FRL_MODE_EN			BIT(3)
+#define PLL_TX_HS_CLK_EN		BIT(2)
+/* CMN_REG(0089) */
+#define LCPLL_ALONE_MODE		BIT(1)
+/* CMN_REG(0097) */
+#define DIG_CLK_SEL			BIT(1)
+#define ROPLL_REF			BIT(1)
+#define LCPLL_REF			0
+/* CMN_REG(0099) */
+#define CMN_ROPLL_ALONE_MODE		BIT(2)
+#define ROPLL_ALONE_MODE		BIT(2)
+/* CMN_REG(009a) */
+#define HS_SPEED_SEL			BIT(0)
+#define DIV_10_CLOCK			BIT(0)
+/* CMN_REG(009b) */
+#define IS_SPEED_SEL			BIT(4)
+#define LINK_SYMBOL_CLOCK		BIT(4)
+#define LINK_SYMBOL_CLOCK1_2		0
+
+/* SB_REG(0102) */
+#define OVRD_SB_RXTERM_EN_MASK		BIT(5)
+#define SB_RXTERM_EN_MASK		BIT(4)
+#define ANA_SB_RXTERM_OFFSP_MASK	GENMASK(3, 0)
+/* SB_REG(0103) */
+#define ANA_SB_RXTERM_OFFSN_MASK	GENMASK(6, 3)
+#define OVRD_SB_RX_RESCAL_DONE_MASK	BIT(1)
+#define SB_RX_RESCAL_DONE_MASK		BIT(0)
+/* SB_REG(0104) */
+#define OVRD_SB_EN_MASK			BIT(5)
+#define SB_EN_MASK			BIT(4)
+/* SB_REG(0105) */
+#define OVRD_SB_EARC_CMDC_EN_MASK	BIT(6)
+#define SB_EARC_CMDC_EN_MASK		BIT(5)
+#define ANA_SB_TX_HLVL_PROG_MASK	GENMASK(2, 0)
+/* SB_REG(0106) */
+#define ANA_SB_TX_LLVL_PROG_MASK	GENMASK(6, 4)
+/* SB_REG(0109) */
+#define ANA_SB_DMRX_AFC_DIV_RATIO_MASK	GENMASK(2, 0)
+/* SB_REG(010f) */
+#define OVRD_SB_VREG_EN_MASK		BIT(7)
+#define SB_VREG_EN_MASK			BIT(6)
+#define OVRD_SB_VREG_LPF_BYPASS_MASK	BIT(5)
+#define SB_VREG_LPF_BYPASS_MASK		BIT(4)
+#define ANA_SB_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
+/* SB_REG(0110) */
+#define ANA_SB_VREG_REF_SEL_MASK	BIT(0)
+/* SB_REG(0113) */
+#define SB_RX_RCAL_OPT_CODE_MASK	GENMASK(5, 4)
+#define SB_RX_RTERM_CTRL_MASK		GENMASK(3, 0)
+/* SB_REG(0114) */
+#define SB_TG_SB_EN_DELAY_TIME_MASK	GENMASK(5, 3)
+#define SB_TG_RXTERM_EN_DELAY_TIME_MASK	GENMASK(2, 0)
+/* SB_REG(0115) */
+#define SB_READY_DELAY_TIME_MASK	GENMASK(5, 3)
+#define SB_TG_OSC_EN_DELAY_TIME_MASK	GENMASK(2, 0)
+/* SB_REG(0116) */
+#define AFC_RSTN_DELAY_TIME_MASK	GENMASK(6, 4)
+/* SB_REG(0117) */
+#define FAST_PULSE_TIME_MASK		GENMASK(3, 0)
+/* SB_REG(011b) */
+#define SB_EARC_SIG_DET_BYPASS_MASK	BIT(4)
+#define SB_AFC_TOL_MASK			GENMASK(3, 0)
+/* SB_REG(011f) */
+#define SB_PWM_AFC_CTRL_MASK		GENMASK(7, 2)
+#define SB_RCAL_RSTN_MASK		BIT(1)
+/* SB_REG(0120) */
+#define SB_EARC_EN_MASK			BIT(1)
+#define SB_EARC_AFC_EN_MASK		BIT(2)
+/* SB_REG(0123) */
+#define OVRD_SB_READY_MASK		BIT(5)
+#define SB_READY_MASK			BIT(4)
+
+/* LNTOP_REG(0200) */
+#define PROTOCOL_SEL			BIT(2)
+#define HDMI_MODE			BIT(2)
+#define HDMI_TMDS_FRL_SEL		BIT(1)
+/* LNTOP_REG(0206) */
+#define DATA_BUS_SEL			BIT(0)
+#define DATA_BUS_36_40			BIT(0)
+/* LNTOP_REG(0207) */
+#define LANE_EN				0xf
+#define ALL_LANE_EN			0xf
+
+/* LANE_REG(0312) */
+#define LN0_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN0_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN0_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN0_TX_SER_RATE_SEL_HBR3	BIT(2)
+/* LANE_REG(0412) */
+#define LN1_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN1_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN1_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN1_TX_SER_RATE_SEL_HBR3	BIT(2)
+/* LANE_REG(0512) */
+#define LN2_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN2_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN2_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN2_TX_SER_RATE_SEL_HBR3	BIT(2)
+/* LANE_REG(0612) */
+#define LN3_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN3_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN3_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN3_TX_SER_RATE_SEL_HBR3	BIT(2)
+
+struct lcpll_config {
+	u32 bit_rate;
+	u8 lcvco_mode_en;
+	u8 pi_en;
+	u8 clk_en_100m;
+	u8 pms_mdiv;
+	u8 pms_mdiv_afc;
+	u8 pms_pdiv;
+	u8 pms_refdiv;
+	u8 pms_sdiv;
+	u8 pi_cdiv_rstn;
+	u8 pi_cdiv_sel;
+	u8 sdm_en;
+	u8 sdm_rstn;
+	u8 sdc_frac_en;
+	u8 sdc_rstn;
+	u8 sdm_deno;
+	u8 sdm_num_sign;
+	u8 sdm_num;
+	u8 sdc_n;
+	u8 sdc_n2;
+	u8 sdc_num;
+	u8 sdc_deno;
+	u8 sdc_ndiv_rstn;
+	u8 ssc_en;
+	u8 ssc_fm_dev;
+	u8 ssc_fm_freq;
+	u8 ssc_clk_div_sel;
+	u8 cd_tx_ser_rate_sel;
+};
+
+struct ropll_config {
+	u32 bit_rate;
+	u8 pms_mdiv;
+	u8 pms_mdiv_afc;
+	u8 pms_pdiv;
+	u8 pms_refdiv;
+	u8 pms_sdiv;
+	u8 pms_iqdiv_rstn;
+	u8 ref_clk_sel;
+	u8 sdm_en;
+	u8 sdm_rstn;
+	u8 sdc_frac_en;
+	u8 sdc_rstn;
+	u8 sdm_clk_div;
+	u8 sdm_deno;
+	u8 sdm_num_sign;
+	u8 sdm_num;
+	u8 sdc_n;
+	u8 sdc_num;
+	u8 sdc_deno;
+	u8 sdc_ndiv_rstn;
+	u8 ssc_en;
+	u8 ssc_fm_dev;
+	u8 ssc_fm_freq;
+	u8 ssc_clk_div_sel;
+	u8 ana_cpp_ctrl;
+	u8 ana_lpf_c_sel;
+	u8 cd_tx_ser_rate_sel;
+};
+
+enum rockchip_hdptx_reset {
+	RST_PHY = 0,
+	RST_APB,
+	RST_INIT,
+	RST_CMN,
+	RST_LANE,
+	RST_ROPLL,
+	RST_LCPLL,
+	RST_MAX
+};
+
+struct rockchip_hdptx_phy {
+	struct device *dev;
+	struct regmap *regmap;
+	struct regmap *grf;
+
+	struct phy *phy;
+	struct phy_config *phy_cfg;
+	struct clk_bulk_data *clks;
+	int nr_clks;
+	struct reset_control_bulk_data rsts[RST_MAX];
+};
+
+static const struct ropll_config ropll_tmds_cfg[] = {
+	{ 5940000, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 3712500, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 2970000, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1620000, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1856250, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1540000, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1485000, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5,
+	  0x10, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1462500, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1190000, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1065000, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1080000, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 855000, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 835000, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 928125, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 742500, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 650000, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 337500, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5,
+	  1, 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 400000, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 270000, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 251750, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+};
+
+static const struct reg_sequence hdtpx_common_cmn_init_seq[] = {
+	REG_SEQ0(CMN_REG(0009), 0x0c),
+	REG_SEQ0(CMN_REG(000a), 0x83),
+	REG_SEQ0(CMN_REG(000b), 0x06),
+	REG_SEQ0(CMN_REG(000c), 0x20),
+	REG_SEQ0(CMN_REG(000d), 0xb8),
+	REG_SEQ0(CMN_REG(000e), 0x0f),
+	REG_SEQ0(CMN_REG(000f), 0x0f),
+	REG_SEQ0(CMN_REG(0010), 0x04),
+	REG_SEQ0(CMN_REG(0011), 0x00),
+	REG_SEQ0(CMN_REG(0012), 0x26),
+	REG_SEQ0(CMN_REG(0013), 0x22),
+	REG_SEQ0(CMN_REG(0014), 0x24),
+	REG_SEQ0(CMN_REG(0015), 0x77),
+	REG_SEQ0(CMN_REG(0016), 0x08),
+	REG_SEQ0(CMN_REG(0017), 0x00),
+	REG_SEQ0(CMN_REG(0018), 0x04),
+	REG_SEQ0(CMN_REG(0019), 0x48),
+	REG_SEQ0(CMN_REG(001a), 0x01),
+	REG_SEQ0(CMN_REG(001b), 0x00),
+	REG_SEQ0(CMN_REG(001c), 0x01),
+	REG_SEQ0(CMN_REG(001d), 0x64),
+	REG_SEQ0(CMN_REG(001f), 0x00),
+	REG_SEQ0(CMN_REG(0026), 0x53),
+	REG_SEQ0(CMN_REG(0029), 0x01),
+	REG_SEQ0(CMN_REG(0030), 0x00),
+	REG_SEQ0(CMN_REG(0031), 0x20),
+	REG_SEQ0(CMN_REG(0032), 0x30),
+	REG_SEQ0(CMN_REG(0033), 0x0b),
+	REG_SEQ0(CMN_REG(0034), 0x23),
+	REG_SEQ0(CMN_REG(0035), 0x00),
+	REG_SEQ0(CMN_REG(0038), 0x00),
+	REG_SEQ0(CMN_REG(0039), 0x00),
+	REG_SEQ0(CMN_REG(003a), 0x00),
+	REG_SEQ0(CMN_REG(003b), 0x00),
+	REG_SEQ0(CMN_REG(003c), 0x80),
+	REG_SEQ0(CMN_REG(003e), 0x0c),
+	REG_SEQ0(CMN_REG(003f), 0x83),
+	REG_SEQ0(CMN_REG(0040), 0x06),
+	REG_SEQ0(CMN_REG(0041), 0x20),
+	REG_SEQ0(CMN_REG(0042), 0xb8),
+	REG_SEQ0(CMN_REG(0043), 0x00),
+	REG_SEQ0(CMN_REG(0044), 0x46),
+	REG_SEQ0(CMN_REG(0045), 0x24),
+	REG_SEQ0(CMN_REG(0046), 0xff),
+	REG_SEQ0(CMN_REG(0047), 0x00),
+	REG_SEQ0(CMN_REG(0048), 0x44),
+	REG_SEQ0(CMN_REG(0049), 0xfa),
+	REG_SEQ0(CMN_REG(004a), 0x08),
+	REG_SEQ0(CMN_REG(004b), 0x00),
+	REG_SEQ0(CMN_REG(004c), 0x01),
+	REG_SEQ0(CMN_REG(004d), 0x64),
+	REG_SEQ0(CMN_REG(004e), 0x14),
+	REG_SEQ0(CMN_REG(004f), 0x00),
+	REG_SEQ0(CMN_REG(0050), 0x00),
+	REG_SEQ0(CMN_REG(005d), 0x0c),
+	REG_SEQ0(CMN_REG(005f), 0x01),
+	REG_SEQ0(CMN_REG(006b), 0x04),
+	REG_SEQ0(CMN_REG(0073), 0x30),
+	REG_SEQ0(CMN_REG(0074), 0x00),
+	REG_SEQ0(CMN_REG(0075), 0x20),
+	REG_SEQ0(CMN_REG(0076), 0x30),
+	REG_SEQ0(CMN_REG(0077), 0x08),
+	REG_SEQ0(CMN_REG(0078), 0x0c),
+	REG_SEQ0(CMN_REG(0079), 0x00),
+	REG_SEQ0(CMN_REG(007b), 0x00),
+	REG_SEQ0(CMN_REG(007c), 0x00),
+	REG_SEQ0(CMN_REG(007d), 0x00),
+	REG_SEQ0(CMN_REG(007e), 0x00),
+	REG_SEQ0(CMN_REG(007f), 0x00),
+	REG_SEQ0(CMN_REG(0080), 0x00),
+	REG_SEQ0(CMN_REG(0081), 0x09),
+	REG_SEQ0(CMN_REG(0082), 0x04),
+	REG_SEQ0(CMN_REG(0083), 0x24),
+	REG_SEQ0(CMN_REG(0084), 0x20),
+	REG_SEQ0(CMN_REG(0085), 0x03),
+	REG_SEQ0(CMN_REG(0086), 0x01),
+	REG_SEQ0(CMN_REG(0087), 0x0c),
+	REG_SEQ0(CMN_REG(008a), 0x55),
+	REG_SEQ0(CMN_REG(008b), 0x25),
+	REG_SEQ0(CMN_REG(008c), 0x2c),
+	REG_SEQ0(CMN_REG(008d), 0x22),
+	REG_SEQ0(CMN_REG(008e), 0x14),
+	REG_SEQ0(CMN_REG(008f), 0x20),
+	REG_SEQ0(CMN_REG(0090), 0x00),
+	REG_SEQ0(CMN_REG(0091), 0x00),
+	REG_SEQ0(CMN_REG(0092), 0x00),
+	REG_SEQ0(CMN_REG(0093), 0x00),
+	REG_SEQ0(CMN_REG(009a), 0x11),
+	REG_SEQ0(CMN_REG(009b), 0x10),
+};
+
+static const struct reg_sequence hdtpx_tmds_cmn_init_seq[] = {
+	REG_SEQ0(CMN_REG(0008), 0x00),
+	REG_SEQ0(CMN_REG(0011), 0x01),
+	REG_SEQ0(CMN_REG(0017), 0x20),
+	REG_SEQ0(CMN_REG(001e), 0x14),
+	REG_SEQ0(CMN_REG(0020), 0x00),
+	REG_SEQ0(CMN_REG(0021), 0x00),
+	REG_SEQ0(CMN_REG(0022), 0x11),
+	REG_SEQ0(CMN_REG(0023), 0x00),
+	REG_SEQ0(CMN_REG(0024), 0x00),
+	REG_SEQ0(CMN_REG(0025), 0x53),
+	REG_SEQ0(CMN_REG(0026), 0x00),
+	REG_SEQ0(CMN_REG(0027), 0x00),
+	REG_SEQ0(CMN_REG(0028), 0x01),
+	REG_SEQ0(CMN_REG(002a), 0x00),
+	REG_SEQ0(CMN_REG(002b), 0x00),
+	REG_SEQ0(CMN_REG(002c), 0x00),
+	REG_SEQ0(CMN_REG(002d), 0x00),
+	REG_SEQ0(CMN_REG(002e), 0x04),
+	REG_SEQ0(CMN_REG(002f), 0x00),
+	REG_SEQ0(CMN_REG(0030), 0x20),
+	REG_SEQ0(CMN_REG(0031), 0x30),
+	REG_SEQ0(CMN_REG(0032), 0x0b),
+	REG_SEQ0(CMN_REG(0033), 0x23),
+	REG_SEQ0(CMN_REG(0034), 0x00),
+	REG_SEQ0(CMN_REG(003d), 0x40),
+	REG_SEQ0(CMN_REG(0042), 0x78),
+	REG_SEQ0(CMN_REG(004e), 0x34),
+	REG_SEQ0(CMN_REG(005c), 0x25),
+	REG_SEQ0(CMN_REG(005e), 0x4f),
+	REG_SEQ0(CMN_REG(0074), 0x04),
+	REG_SEQ0(CMN_REG(0081), 0x01),
+	REG_SEQ0(CMN_REG(0087), 0x04),
+	REG_SEQ0(CMN_REG(0089), 0x00),
+	REG_SEQ0(CMN_REG(0095), 0x00),
+	REG_SEQ0(CMN_REG(0097), 0x02),
+	REG_SEQ0(CMN_REG(0099), 0x04),
+	REG_SEQ0(CMN_REG(009b), 0x00),
+};
+
+static const struct reg_sequence hdtpx_common_sb_init_seq[] = {
+	REG_SEQ0(SB_REG(0114), 0x00),
+	REG_SEQ0(SB_REG(0115), 0x00),
+	REG_SEQ0(SB_REG(0116), 0x00),
+	REG_SEQ0(SB_REG(0117), 0x00),
+};
+
+static const struct reg_sequence hdtpx_tmds_lntop_highbr_seq[] = {
+	REG_SEQ0(LNTOP_REG(0201), 0x00),
+	REG_SEQ0(LNTOP_REG(0202), 0x00),
+	REG_SEQ0(LNTOP_REG(0203), 0x0f),
+	REG_SEQ0(LNTOP_REG(0204), 0xff),
+	REG_SEQ0(LNTOP_REG(0205), 0xff),
+};
+
+static const struct reg_sequence hdtpx_tmds_lntop_lowbr_seq[] = {
+	REG_SEQ0(LNTOP_REG(0201), 0x07),
+	REG_SEQ0(LNTOP_REG(0202), 0xc1),
+	REG_SEQ0(LNTOP_REG(0203), 0xf0),
+	REG_SEQ0(LNTOP_REG(0204), 0x7c),
+	REG_SEQ0(LNTOP_REG(0205), 0x1f),
+};
+
+static const struct reg_sequence hdtpx_common_lane_init_seq[] = {
+	REG_SEQ0(LANE_REG(0303), 0x0c),
+	REG_SEQ0(LANE_REG(0307), 0x20),
+	REG_SEQ0(LANE_REG(030a), 0x17),
+	REG_SEQ0(LANE_REG(030b), 0x77),
+	REG_SEQ0(LANE_REG(030c), 0x77),
+	REG_SEQ0(LANE_REG(030d), 0x77),
+	REG_SEQ0(LANE_REG(030e), 0x38),
+	REG_SEQ0(LANE_REG(0310), 0x03),
+	REG_SEQ0(LANE_REG(0311), 0x0f),
+	REG_SEQ0(LANE_REG(0316), 0x02),
+	REG_SEQ0(LANE_REG(031b), 0x01),
+	REG_SEQ0(LANE_REG(031f), 0x15),
+	REG_SEQ0(LANE_REG(0320), 0xa0),
+	REG_SEQ0(LANE_REG(0403), 0x0c),
+	REG_SEQ0(LANE_REG(0407), 0x20),
+	REG_SEQ0(LANE_REG(040a), 0x17),
+	REG_SEQ0(LANE_REG(040b), 0x77),
+	REG_SEQ0(LANE_REG(040c), 0x77),
+	REG_SEQ0(LANE_REG(040d), 0x77),
+	REG_SEQ0(LANE_REG(040e), 0x38),
+	REG_SEQ0(LANE_REG(0410), 0x03),
+	REG_SEQ0(LANE_REG(0411), 0x0f),
+	REG_SEQ0(LANE_REG(0416), 0x02),
+	REG_SEQ0(LANE_REG(041b), 0x01),
+	REG_SEQ0(LANE_REG(041f), 0x15),
+	REG_SEQ0(LANE_REG(0420), 0xa0),
+	REG_SEQ0(LANE_REG(0503), 0x0c),
+	REG_SEQ0(LANE_REG(0507), 0x20),
+	REG_SEQ0(LANE_REG(050a), 0x17),
+	REG_SEQ0(LANE_REG(050b), 0x77),
+	REG_SEQ0(LANE_REG(050c), 0x77),
+	REG_SEQ0(LANE_REG(050d), 0x77),
+	REG_SEQ0(LANE_REG(050e), 0x38),
+	REG_SEQ0(LANE_REG(0510), 0x03),
+	REG_SEQ0(LANE_REG(0511), 0x0f),
+	REG_SEQ0(LANE_REG(0516), 0x02),
+	REG_SEQ0(LANE_REG(051b), 0x01),
+	REG_SEQ0(LANE_REG(051f), 0x15),
+	REG_SEQ0(LANE_REG(0520), 0xa0),
+	REG_SEQ0(LANE_REG(0603), 0x0c),
+	REG_SEQ0(LANE_REG(0607), 0x20),
+	REG_SEQ0(LANE_REG(060a), 0x17),
+	REG_SEQ0(LANE_REG(060b), 0x77),
+	REG_SEQ0(LANE_REG(060c), 0x77),
+	REG_SEQ0(LANE_REG(060d), 0x77),
+	REG_SEQ0(LANE_REG(060e), 0x38),
+	REG_SEQ0(LANE_REG(0610), 0x03),
+	REG_SEQ0(LANE_REG(0611), 0x0f),
+	REG_SEQ0(LANE_REG(0616), 0x02),
+	REG_SEQ0(LANE_REG(061b), 0x01),
+	REG_SEQ0(LANE_REG(061f), 0x15),
+	REG_SEQ0(LANE_REG(0620), 0xa0),
+};
+
+static const struct reg_sequence hdtpx_tmds_lane_init_seq[] = {
+	REG_SEQ0(LANE_REG(0312), 0x00),
+	REG_SEQ0(LANE_REG(031e), 0x00),
+	REG_SEQ0(LANE_REG(0412), 0x00),
+	REG_SEQ0(LANE_REG(041e), 0x00),
+	REG_SEQ0(LANE_REG(0512), 0x00),
+	REG_SEQ0(LANE_REG(051e), 0x00),
+	REG_SEQ0(LANE_REG(0612), 0x00),
+	REG_SEQ0(LANE_REG(061e), 0x08),
+	REG_SEQ0(LANE_REG(0303), 0x2f),
+	REG_SEQ0(LANE_REG(0403), 0x2f),
+	REG_SEQ0(LANE_REG(0503), 0x2f),
+	REG_SEQ0(LANE_REG(0603), 0x2f),
+	REG_SEQ0(LANE_REG(0305), 0x03),
+	REG_SEQ0(LANE_REG(0405), 0x03),
+	REG_SEQ0(LANE_REG(0505), 0x03),
+	REG_SEQ0(LANE_REG(0605), 0x03),
+	REG_SEQ0(LANE_REG(0306), 0x1c),
+	REG_SEQ0(LANE_REG(0406), 0x1c),
+	REG_SEQ0(LANE_REG(0506), 0x1c),
+	REG_SEQ0(LANE_REG(0606), 0x1c),
+};
+
+static bool rockchip_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case 0x0000 ... 0x029c:
+	case 0x0400 ... 0x04a4:
+	case 0x0800 ... 0x08a4:
+	case 0x0c00 ... 0x0cb4:
+	case 0x1000 ... 0x10b4:
+	case 0x1400 ... 0x14b4:
+	case 0x1800 ... 0x18b4:
+		return true;
+	}
+
+	return false;
+}
+
+static const struct regmap_config rockchip_hdptx_phy_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.writeable_reg = rockchip_hdptx_phy_is_rw_reg,
+	.readable_reg = rockchip_hdptx_phy_is_rw_reg,
+	.fast_io = true,
+	.max_register = 0x18b4,
+};
+
+#define hdptx_multi_reg_write(hdptx, seq) \
+	regmap_multi_reg_write((hdptx)->regmap, seq, ARRAY_SIZE(seq))
+
+static void hdptx_pre_power_up(struct rockchip_hdptx_phy *hdptx)
+{
+	u32 val;
+
+	reset_control_assert(hdptx->rsts[RST_APB].rstc);
+	usleep_range(20, 25);
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+
+	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
+
+	val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+}
+
+static int hdptx_post_enable_lane(struct rockchip_hdptx_phy *hdptx)
+{
+	u32 val;
+	int ret;
+
+	reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
+
+	val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
+	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
+				       (val & HDPTX_O_PHY_RDY) &&
+				       (val & HDPTX_O_PLL_LOCK_DONE),
+				       100, 5000);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get PHY lane lock: %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(hdptx->dev, "PHY lane locked\n");
+
+	return 0;
+}
+
+static int hdptx_post_enable_pll(struct rockchip_hdptx_phy *hdptx)
+{
+	u32 val;
+	int ret;
+
+	val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
+	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+
+	usleep_range(10, 15);
+	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
+
+	usleep_range(10, 15);
+	val = HDPTX_I_PLL_EN << 16 | HDPTX_I_PLL_EN;
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+
+	usleep_range(10, 15);
+	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
+				       val & HDPTX_O_PHY_CLK_RDY, 20, 400);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get PHY clk ready: %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(hdptx->dev, "PHY clk ready\n");
+
+	return 0;
+}
+
+static void hdptx_phy_disable(struct rockchip_hdptx_phy *hdptx)
+{
+	u32 val;
+
+	/* reset phy and apb, or phy locked flag may keep 1 */
+	reset_control_assert(hdptx->rsts[RST_PHY].rstc);
+	usleep_range(20, 30);
+	reset_control_deassert(hdptx->rsts[RST_PHY].rstc);
+
+	reset_control_assert(hdptx->rsts[RST_APB].rstc);
+	usleep_range(20, 30);
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+
+	regmap_write(hdptx->regmap, LANE_REG(0300), 0x82);
+	regmap_write(hdptx->regmap, SB_REG(010f), 0xc1);
+	regmap_write(hdptx->regmap, SB_REG(0110), 0x1);
+	regmap_write(hdptx->regmap, LANE_REG(0301), 0x80);
+	regmap_write(hdptx->regmap, LANE_REG(0401), 0x80);
+	regmap_write(hdptx->regmap, LANE_REG(0501), 0x80);
+	regmap_write(hdptx->regmap, LANE_REG(0601), 0x80);
+
+	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
+
+	val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+}
+
+static bool hdptx_phy_clk_pll_calc(unsigned int data_rate,
+				   struct ropll_config *cfg)
+{
+	const unsigned int fout = data_rate / 2, fref = 24000;
+	unsigned long k = 0, lc, k_sub, lc_sub;
+	unsigned int fvco, sdc;
+	u32 mdiv, sdiv, n = 8;
+
+	if (fout > 0xfffffff)
+		return false;
+
+	for (sdiv = 16; sdiv >= 1; sdiv--) {
+		if (sdiv % 2 && sdiv != 1)
+			continue;
+
+		fvco = fout * sdiv;
+
+		if (fvco < 2000000 || fvco > 4000000)
+			continue;
+
+		mdiv = DIV_ROUND_UP(fvco, fref);
+		if (mdiv < 20 || mdiv > 255)
+			continue;
+
+		if (fref * mdiv - fvco) {
+			for (sdc = 264000; sdc <= 750000; sdc += fref)
+				if (sdc * n > fref * mdiv)
+					break;
+
+			if (sdc > 750000)
+				continue;
+
+			rational_best_approximation(fref * mdiv - fvco,
+						    sdc / 16,
+						    GENMASK(6, 0),
+						    GENMASK(7, 0),
+						    &k, &lc);
+
+			rational_best_approximation(sdc * n - fref * mdiv,
+						    sdc,
+						    GENMASK(6, 0),
+						    GENMASK(7, 0),
+						    &k_sub, &lc_sub);
+		}
+
+		break;
+	}
+
+	if (sdiv < 1)
+		return false;
+
+	if (cfg) {
+		cfg->pms_mdiv = mdiv;
+		cfg->pms_mdiv_afc = mdiv;
+		cfg->pms_pdiv = 1;
+		cfg->pms_refdiv = 1;
+		cfg->pms_sdiv = sdiv - 1;
+
+		cfg->sdm_en = k > 0 ? 1 : 0;
+		if (cfg->sdm_en) {
+			cfg->sdm_deno = lc;
+			cfg->sdm_num_sign = 1;
+			cfg->sdm_num = k;
+			cfg->sdc_n = n - 3;
+			cfg->sdc_num = k_sub;
+			cfg->sdc_deno = lc_sub;
+		}
+	}
+
+	return true;
+}
+
+static int hdptx_ropll_tmds_cmn_config(struct rockchip_hdptx_phy *hdptx,
+				       unsigned int rate)
+{
+	const struct ropll_config *cfg = NULL;
+	struct ropll_config rc = {0};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
+		if (rate == ropll_tmds_cfg[i].bit_rate) {
+			cfg = &ropll_tmds_cfg[i];
+			break;
+		}
+
+	if (!cfg) {
+		if (hdptx_phy_clk_pll_calc(rate, &rc)) {
+			cfg = &rc;
+		} else {
+			dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	dev_dbg(hdptx->dev, "mdiv=%u, sdiv=%u, sdm_en=%u, k_sign=%u, k=%u, lc=%u\n",
+		cfg->pms_mdiv, cfg->pms_sdiv + 1, cfg->sdm_en,
+		cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno);
+
+	hdptx_pre_power_up(hdptx);
+
+	reset_control_assert(hdptx->rsts[RST_ROPLL].rstc);
+	usleep_range(20, 30);
+	reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc);
+
+	hdptx_multi_reg_write(hdptx, hdtpx_common_cmn_init_seq);
+	hdptx_multi_reg_write(hdptx, hdtpx_tmds_cmn_init_seq);
+
+	regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv);
+	regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc);
+	regmap_write(hdptx->regmap, CMN_REG(0059),
+		     (cfg->pms_pdiv << 4) | cfg->pms_refdiv);
+	regmap_write(hdptx->regmap, CMN_REG(005a), cfg->pms_sdiv << 4);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK,
+			   FIELD_PREP(ROPLL_SDM_EN_MASK, cfg->sdm_en));
+	if (!cfg->sdm_en)
+		regmap_update_bits(hdptx->regmap, CMN_REG(005e), 0xf, 0);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0064), ROPLL_SDM_NUM_SIGN_RBR_MASK,
+			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, cfg->sdm_num_sign));
+
+	regmap_write(hdptx->regmap, CMN_REG(0060), cfg->sdm_deno);
+	regmap_write(hdptx->regmap, CMN_REG(0065), cfg->sdm_num);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,
+			   FIELD_PREP(ROPLL_SDC_N_RBR_MASK, cfg->sdc_n));
+
+	regmap_write(hdptx->regmap, CMN_REG(006c), cfg->sdc_num);
+	regmap_write(hdptx->regmap, CMN_REG(0070), cfg->sdc_deno);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,
+			   FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN,
+			   PLL_PCG_CLK_EN);
+
+	return hdptx_post_enable_pll(hdptx);
+}
+
+static int hdptx_ropll_tmds_mode_config(struct rockchip_hdptx_phy *hdptx,
+					unsigned int rate)
+{
+	u32 val;
+	int ret;
+
+	ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
+	if (ret)
+		return ret;
+
+	if (!(val & HDPTX_O_PLL_LOCK_DONE)) {
+		ret = hdptx_ropll_tmds_cmn_config(hdptx, rate);
+		if (ret)
+			return ret;
+	}
+
+	hdptx_multi_reg_write(hdptx, hdtpx_common_sb_init_seq);
+
+	regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
+
+	if (rate >= 3400000) {
+		/* For 1/40 bitrate clk */
+		hdptx_multi_reg_write(hdptx, hdtpx_tmds_lntop_highbr_seq);
+	} else {
+		/* For 1/10 bitrate clk */
+		hdptx_multi_reg_write(hdptx, hdtpx_tmds_lntop_lowbr_seq);
+	}
+
+	regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07);
+	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
+
+	hdptx_multi_reg_write(hdptx, hdtpx_common_lane_init_seq);
+	hdptx_multi_reg_write(hdptx, hdtpx_tmds_lane_init_seq);
+
+	return hdptx_post_enable_lane(hdptx);
+}
+
+static int rockchip_hdptx_phy_power_on(struct phy *phy)
+{
+	struct rockchip_hdptx_phy *hdptx = phy_get_drvdata(phy);
+	int ret, bus_width = phy_get_bus_width(hdptx->phy);
+	/*
+	 * FIXME: Temporary workaround to pass pixel_clk_rate
+	 * from the HDMI bridge driver until phy_configure_opts_hdmi
+	 * becomes available in the PHY API.
+	 */
+	unsigned int rate = bus_width & 0xfffffff;
+
+	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
+		__func__, bus_width, rate);
+
+	ret = pm_runtime_resume_and_get(hdptx->dev);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to resume phy: %d\n", ret);
+		return ret;
+	}
+
+	ret = hdptx_ropll_tmds_mode_config(hdptx, rate);
+	if (ret)
+		pm_runtime_put(hdptx->dev);
+
+	return ret;
+}
+
+static int rockchip_hdptx_phy_power_off(struct phy *phy)
+{
+	struct rockchip_hdptx_phy *hdptx = phy_get_drvdata(phy);
+	u32 val;
+	int ret;
+
+	ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
+	if (ret == 0 && (val & HDPTX_O_PLL_LOCK_DONE))
+		hdptx_phy_disable(hdptx);
+
+	pm_runtime_put(hdptx->dev);
+
+	return ret;
+}
+
+static const struct phy_ops rockchip_hdptx_phy_ops = {
+	.power_on  = rockchip_hdptx_phy_power_on,
+	.power_off = rockchip_hdptx_phy_power_off,
+	.owner	   = THIS_MODULE,
+};
+
+static int rockchip_hdptx_phy_runtime_suspend(struct device *dev)
+{
+	struct rockchip_hdptx_phy *hdptx = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(hdptx->nr_clks, hdptx->clks);
+
+	return 0;
+}
+
+static int rockchip_hdptx_phy_runtime_resume(struct device *dev)
+{
+	struct rockchip_hdptx_phy *hdptx = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(hdptx->nr_clks, hdptx->clks);
+	if (ret)
+		dev_err(hdptx->dev, "Failed to enable clocks: %d\n", ret);
+
+	return ret;
+}
+
+static int rockchip_hdptx_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rockchip_hdptx_phy *hdptx;
+	struct phy_provider *phy_provider;
+	void __iomem *regs;
+	int ret;
+
+	hdptx = devm_kzalloc(dev, sizeof(*hdptx), GFP_KERNEL);
+	if (!hdptx)
+		return -ENOMEM;
+
+	hdptx->dev = dev;
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return dev_err_probe(dev, PTR_ERR(regs),
+				     "Failed to ioremap resource\n");
+
+	ret = devm_clk_bulk_get_all(dev, &hdptx->clks);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to get clocks\n");
+	if (ret == 0)
+		return dev_err_probe(dev, -EINVAL, "Missing clocks\n");
+
+	hdptx->nr_clks = ret;
+
+	hdptx->regmap = devm_regmap_init_mmio(dev, regs,
+					      &rockchip_hdptx_phy_regmap_config);
+	if (IS_ERR(hdptx->regmap))
+		return dev_err_probe(dev, PTR_ERR(hdptx->regmap),
+				     "Failed to init regmap\n");
+
+	hdptx->rsts[RST_PHY].id = "phy";
+	hdptx->rsts[RST_APB].id = "apb";
+	hdptx->rsts[RST_INIT].id = "init";
+	hdptx->rsts[RST_CMN].id = "cmn";
+	hdptx->rsts[RST_LANE].id = "lane";
+	hdptx->rsts[RST_ROPLL].id = "ropll";
+	hdptx->rsts[RST_LCPLL].id = "lcpll";
+
+	ret = devm_reset_control_bulk_get_exclusive(dev, RST_MAX, hdptx->rsts);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to get resets\n");
+
+	hdptx->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+						     "rockchip,grf");
+	if (IS_ERR(hdptx->grf))
+		return dev_err_probe(dev, PTR_ERR(hdptx->grf),
+				     "Could not get GRF syscon\n");
+
+	hdptx->phy = devm_phy_create(dev, NULL, &rockchip_hdptx_phy_ops);
+	if (IS_ERR(hdptx->phy))
+		return dev_err_probe(dev, PTR_ERR(hdptx->phy),
+				     "Failed to create HDMI PHY\n");
+
+	platform_set_drvdata(pdev, hdptx);
+	phy_set_drvdata(hdptx->phy, hdptx);
+	phy_set_bus_width(hdptx->phy, 8);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider))
+		return dev_err_probe(dev, PTR_ERR(phy_provider),
+				     "Failed to register PHY provider\n");
+
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
+
+	return 0;
+}
+
+static const struct dev_pm_ops rockchip_hdptx_phy_pm_ops = {
+	RUNTIME_PM_OPS(rockchip_hdptx_phy_runtime_suspend,
+		       rockchip_hdptx_phy_runtime_resume, NULL)
+};
+
+static const struct of_device_id rockchip_hdptx_phy_of_match[] = {
+	{ .compatible = "rockchip,rk3588-hdptx-phy", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, rockchip_hdptx_phy_of_match);
+
+static struct platform_driver rockchip_hdptx_phy_driver = {
+	.probe  = rockchip_hdptx_phy_probe,
+	.driver = {
+		.name = "rockchip-hdptx-phy",
+		.pm = &rockchip_hdptx_phy_pm_ops,
+		.of_match_table = rockchip_hdptx_phy_of_match,
+	},
+};
+module_platform_driver(rockchip_hdptx_phy_driver);
+
+MODULE_AUTHOR("Algea Cao <algea.cao at rock-chips.com>");
+MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea at collabora.com>");
+MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver");
+MODULE_LICENSE("GPL");

-- 
2.43.0



From namhyung at kernel.org  Mon Feb 12 11:11:21 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Mon, 12 Feb 2024 11:11:21 -0800
Subject: [PATCH v5] perf stat: Support per-cluster aggregation
In-Reply-To: <20240208024026.2691-1-yangyicong@huawei.com>
References: <20240208024026.2691-1-yangyicong@huawei.com>
Message-ID: <170776504994.3461281.10666322368252974000.b4-ty@kernel.org>

On Thu, 8 Feb 2024 10:40:26 +0800, Yicong Yang wrote:
> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> Some platforms have 'cluster' topology and CPUs in the cluster will
> share resources like L3 Cache Tag (for HiSilicon Kunpeng SoC) or L2
> cache (for Intel Jacobsville). Currently parsing and building cluster
> topology have been supported since [1].
> 
> [...]

Applied to perf-tools-next, thanks!

Best regards,
-- 
Namhyung Kim <namhyung at kernel.org>


From robin.murphy at arm.com  Mon Feb 12 11:12:20 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 12 Feb 2024 19:12:20 +0000
Subject: [PATCH v4 01/10] dt-bindings: iommu: Add Translation Buffer Unit
 bindings
In-Reply-To: <20240202211749.GA1467077-robh@kernel.org>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
 <20240201210529.7728-2-quic_c_gdjako@quicinc.com>
 <20240202211749.GA1467077-robh@kernel.org>
Message-ID: <680f9ba7-1f32-4365-abd1-771b8c78e844@arm.com>

On 2024-02-02 9:17 pm, Rob Herring wrote:
> On Thu, Feb 01, 2024 at 01:05:20PM -0800, Georgi Djakov wrote:
>> Add common bindings for the TBUs to describe their properties. The
>> TBUs are modelled as child devices of the IOMMU and each of them is
>> described with their compatible, reg and stream-id-range properties.
>> There could be other implementation specific properties to describe
>> any resources like clocks, regulators, power-domains, interconnects
>> that would be needed for TBU operation. Such properties will be
>> documented in a separate vendor-specific TBU schema.
>>
>> Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
>> ---
>>   .../devicetree/bindings/iommu/arm,smmu.yaml   | 14 ++++++++++
>>   .../devicetree/bindings/iommu/tbu-common.yaml | 28 +++++++++++++++++++
>>   2 files changed, 42 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/iommu/tbu-common.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
>> index a4042ae24770..ba3237023b39 100644
>> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
>> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
>> @@ -235,6 +235,20 @@ properties:
>>         enabled for any given device.
>>       $ref: /schemas/types.yaml#/definitions/phandle
>>   
>> +  '#address-cells':
>> +    enum: [ 1, 2 ]
>> +
>> +  '#size-cells':
>> +    enum: [ 1, 2 ]
>> +
>> +  ranges: true
>> +
>> +patternProperties:
>> +  "^tbu@[0-9a-f]+$":
>> +    description: TBU child nodes
>> +    type: object
>> +    $ref: tbu-common.yaml#
> 
>         additionalProperties: false
> 
> 
> However, that's going to break with the extra QCom properties. In
> json-schema, you can't have 2 schemas and extend the properties of
> their child nodes. The validator doesn't "see" the child node schemas at
> the same time. You are going to have to move QCom SMMU to its own schema
> and remove it from arm,smmu.yaml.

Although this common binding is pretty pointless - sorry I missed the 
previous discussion, but these TBU registers are on obscure debugging 
feature of Qualcomm's own invention and definitely not generic. The 
internal topology of the unmodified Arm MMU-500 implementation isn't 
software-visible at all without getting into its own integration and 
debug registers (and maybe to a lesser extent the PMU), and even then 
everything is proxied through the TCU via an internal AXI stream 
interconnect, so there aren't really any TBU-owned resources which would 
warrant describing as such in DT. If anything, the way this binding is 
defined as an MMIO bus with "ranges" would actively *prevent* being able 
to describe the standard hardware this way, since the internal debug 
stuff all wants to refer to TBUs by numerical index.

Conversely, given that the Qualcomm TBU registers seem to be describing 
their own entirely independent resources and inheriting nothing from the 
parent node, I'm not sure it's necessarily worth all the bother of 
describing and supporting them them as children at all, when they could 
just as well be standalone nodes with a phandle to associate an SMMU 
instance.

Thanks,
Robin.


From wahrenst at gmx.net  Mon Feb 12 11:20:35 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Mon, 12 Feb 2024 20:20:35 +0100
Subject: [PATCH v1 07/14] dt-bindings: lcdif: Do not require power-domains
 for i.MX6ULL
In-Reply-To: <20240210012114.489102-8-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-8-sre@kernel.org>
Message-ID: <a8b55331-a8c3-457e-83e0-2aa361ed23c6@gmx.net>

Hi Sebastian,

Am 10.02.24 um 02:18 schrieb Sebastian Reichel:
> i.MX6UL(L) uses "fsl,imx6sx-lcdif" as fallback compatible string,
> but has only very lightweight DISPLAY power domain. Its DISPLAY
> power domain is not supported by the binding / Linux kernel at
> the moment. Since the current setup is working, let's remove the
> power-domain from being required for that platform to fix the warning
> printed by CHECK_DTBS=y.
i'm not sure this is a good idea. In case i.MX6UL(L) is different from
i.MX6SX here, then it should have a different compatible.

Regards


From will at kernel.org  Mon Feb 12 11:30:52 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 12 Feb 2024 19:30:52 +0000
Subject: [RFC PATCH] KVM: arm64: Fix double-free following kvm_pgtable_stage2_free_unlinked()
Message-ID: <20240212193052.27765-1-will@kernel.org>

kvm_pgtable_stage2_free_unlinked() does the final put_page() on the
root page of the sub-tree before returning, so remove the additional
put_page() invocations in the callers.

Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oliver.upton at linux.dev>
Cc: Ricardo Koller <ricarkol at google.com>
Signed-off-by: Will Deacon <will at kernel.org>
---

Hi folks,

Sending this as an RFC as I only spotted it from code inspection and I'm
surprised others aren't seeing fireworks if it's a genuine bug. I also
couldn't come up with a sensible Fixes tag, as all of:

 e7c05540c694b ("KVM: arm64: Add helper for creating unlinked stage2 subtrees")
 8f5a3eb7513fc ("KVM: arm64: Add kvm_pgtable_stage2_split()")
 f6a27d6dc51b2 ("KVM: arm64: Drop last page ref in kvm_pgtable_stage2_free_removed()")

are actually ok in isolation. Hrm. Please tell me I'm wrong?

 arch/arm64/kvm/hyp/pgtable.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index c651df904fe3..ab9d05fcf98b 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -1419,7 +1419,6 @@ kvm_pte_t *kvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt,
 				 level + 1);
 	if (ret) {
 		kvm_pgtable_stage2_free_unlinked(mm_ops, pgtable, level);
-		mm_ops->put_page(pgtable);
 		return ERR_PTR(ret);
 	}
 
@@ -1502,7 +1501,6 @@ static int stage2_split_walker(const struct kvm_pgtable_visit_ctx *ctx,
 
 	if (!stage2_try_break_pte(ctx, mmu)) {
 		kvm_pgtable_stage2_free_unlinked(mm_ops, childp, level);
-		mm_ops->put_page(childp);
 		return -EAGAIN;
 	}
 
-- 
2.43.0.687.g38aa6559b0-goog



From alexandre.belloni at bootlin.com  Mon Feb 12 12:06:36 2024
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Mon, 12 Feb 2024 21:06:36 +0100
Subject: [PATCH v6 2/7] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <20240212-add-am64-som-v6-2-b59edb2bc8c3@solid-run.com>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
 <20240212-add-am64-som-v6-2-b59edb2bc8c3@solid-run.com>
Message-ID: <2024021220055301ade3d4@mail.local>

On 12/02/2024 18:38:09+0100, Josua Mayer wrote:
> Convert the abracon abx80x rtc text bindings to dt-schema format.
> 
> In addition to the text description reference generic interrupts
> properties and add an example.
> 
> Signed-off-by: Josua Mayer <josua at solid-run.com>

Did something change since v6? If not, why didn't you collect the
reviewed-by tag?

> ---
>  .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ---------
>  .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 79 ++++++++++++++++++++++
>  2 files changed, 79 insertions(+), 31 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
> deleted file mode 100644
> index 2405e35a1bc0..000000000000
> --- a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -Abracon ABX80X I2C ultra low power RTC/Alarm chip
> -
> -The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
> -ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
> -is the superset of ab180x.
> -
> -Required properties:
> -
> - - "compatible": should one of:
> -        "abracon,abx80x"
> -        "abracon,ab0801"
> -        "abracon,ab0803"
> -        "abracon,ab0804"
> -        "abracon,ab0805"
> -        "abracon,ab1801"
> -        "abracon,ab1803"
> -        "abracon,ab1804"
> -        "abracon,ab1805"
> -        "microcrystal,rv1805"
> -	Using "abracon,abx80x" will enable chip autodetection.
> - - "reg": I2C bus address of the device
> -
> -Optional properties:
> -
> -The abx804 and abx805 have a trickle charger that is able to charge the
> -connected battery or supercap. Both the following properties have to be defined
> -and valid to enable charging:
> -
> - - "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
> - - "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
> -                          resistor, the other values are in kOhm.
> diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
> new file mode 100644
> index 000000000000..58dbbca27deb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
> @@ -0,0 +1,79 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Abracon ABX80X I2C ultra low power RTC/Alarm chip
> +
> +maintainers:
> +  - linux-rtc at vger.kernel.org
> +
> +allOf:
> +  - $ref: rtc.yaml#
> +
> +properties:
> +  compatible:
> +    description:
> +      The wildcard 'abracon,abx80x' may be used to support a mix
> +      of different abracon rtc`s. In this case the driver
> +      must perform auto-detection from ID register.
> +    enum:
> +      - abracon,abx80x
> +      - abracon,ab0801
> +      - abracon,ab0803
> +      - abracon,ab0804
> +      - abracon,ab0805
> +      - abracon,ab1801
> +      - abracon,ab1803
> +      - abracon,ab1804
> +      - abracon,ab1805
> +      - microcrystal,rv1805
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  abracon,tc-diode:
> +    description:
> +      Trickle-charge diode type.
> +      Required to enable charging backup battery.
> +
> +      Supported are 'standard' diodes with a 0.6V drop
> +      and 'schottky' diodes with a 0.3V drop.
> +    $ref: /schemas/types.yaml#/definitions/string
> +    enum:
> +      - standard
> +      - schottky
> +
> +  abracon,tc-resistor:
> +    description:
> +      Trickle-charge resistor value in kOhm.
> +      Required to enable charging backup battery.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [0, 3, 6, 11]
> +
> +required:
> +  - compatible
> +  - reg
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        rtc at 69 {
> +            compatible = "abracon,abx80x";
> +            reg = <0x69>;
> +            abracon,tc-diode = "schottky";
> +            abracon,tc-resistor = <3>;
> +            interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
> +        };
> +    };
> 
> -- 
> 2.35.3
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From oliver.upton at linux.dev  Mon Feb 12 12:14:37 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 20:14:37 +0000
Subject: [RFC PATCH] KVM: arm64: Fix double-free following
 kvm_pgtable_stage2_free_unlinked()
In-Reply-To: <20240212193052.27765-1-will@kernel.org>
References: <20240212193052.27765-1-will@kernel.org>
Message-ID: <Zcp8LcvsZiZVkNKe@linux.dev>

On Mon, Feb 12, 2024 at 07:30:52PM +0000, Will Deacon wrote:
> kvm_pgtable_stage2_free_unlinked() does the final put_page() on the
> root page of the sub-tree before returning, so remove the additional
> put_page() invocations in the callers.
> 
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oliver.upton at linux.dev>
> Cc: Ricardo Koller <ricarkol at google.com>
> Signed-off-by: Will Deacon <will at kernel.org>
> ---
> 
> Hi folks,
> 
> Sending this as an RFC as I only spotted it from code inspection and I'm
> surprised others aren't seeing fireworks if it's a genuine bug. I also
> couldn't come up with a sensible Fixes tag, as all of:
> 
>  e7c05540c694b ("KVM: arm64: Add helper for creating unlinked stage2 subtrees")
>  8f5a3eb7513fc ("KVM: arm64: Add kvm_pgtable_stage2_split()")
>  f6a27d6dc51b2 ("KVM: arm64: Drop last page ref in kvm_pgtable_stage2_free_removed()")
> 
> are actually ok in isolation. Hrm. Please tell me I'm wrong?
> 
>  arch/arm64/kvm/hyp/pgtable.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index c651df904fe3..ab9d05fcf98b 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -1419,7 +1419,6 @@ kvm_pte_t *kvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt,
>  				 level + 1);
>  	if (ret) {
>  		kvm_pgtable_stage2_free_unlinked(mm_ops, pgtable, level);
> -		mm_ops->put_page(pgtable);
>  		return ERR_PTR(ret);
>  	}

AFAICT, this entire branch is effectively dead code, unless there's a
KVM bug lurking behind the page table walk. The sub-tree isn't visible
to other software or hardware walkers yet, so none of the PTE races
could cause this to pop.

So while this is very obviously a bug, it might be pure luck that folks
haven't seen smoke here. Perhaps while fixing the bug we should take the
opportunity to promote the condition to WARN_ON_ONCE().

> @@ -1502,7 +1501,6 @@ static int stage2_split_walker(const struct kvm_pgtable_visit_ctx *ctx,
>  
>  	if (!stage2_try_break_pte(ctx, mmu)) {
>  		kvm_pgtable_stage2_free_unlinked(mm_ops, childp, level);
> -		mm_ops->put_page(childp);
>  		return -EAGAIN;
>  	}

This, on the other hand, seems possible. There exists a race where an
old block PTE could have the AF set on it and the underlying cmpxchg()
could fail. There shouldn't be a race with any software walkers, as we
hold the MMU lock for write here.

-- 
Thanks,
Oliver


From oliver.upton at linux.dev  Mon Feb 12 12:19:10 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 20:19:10 +0000
Subject: [RFC PATCH] KVM: arm64: Fix double-free following
 kvm_pgtable_stage2_free_unlinked()
In-Reply-To: <Zcp8LcvsZiZVkNKe@linux.dev>
References: <20240212193052.27765-1-will@kernel.org>
 <Zcp8LcvsZiZVkNKe@linux.dev>
Message-ID: <Zcp9PiPCWKKn0Tkd@linux.dev>

On Mon, Feb 12, 2024 at 08:14:41PM +0000, Oliver Upton wrote:
> On Mon, Feb 12, 2024 at 07:30:52PM +0000, Will Deacon wrote:
> > kvm_pgtable_stage2_free_unlinked() does the final put_page() on the
> > root page of the sub-tree before returning, so remove the additional
> > put_page() invocations in the callers.
> > 
> > Cc: Marc Zyngier <maz at kernel.org>
> > Cc: Oliver Upton <oliver.upton at linux.dev>
> > Cc: Ricardo Koller <ricarkol at google.com>
> > Signed-off-by: Will Deacon <will at kernel.org>
> > ---
> > 
> > Hi folks,
> > 
> > Sending this as an RFC as I only spotted it from code inspection and I'm
> > surprised others aren't seeing fireworks if it's a genuine bug. I also
> > couldn't come up with a sensible Fixes tag, as all of:
> > 
> >  e7c05540c694b ("KVM: arm64: Add helper for creating unlinked stage2 subtrees")
> >  8f5a3eb7513fc ("KVM: arm64: Add kvm_pgtable_stage2_split()")
> >  f6a27d6dc51b2 ("KVM: arm64: Drop last page ref in kvm_pgtable_stage2_free_removed()")
> > 
> > are actually ok in isolation. Hrm. Please tell me I'm wrong?
> > 
> >  arch/arm64/kvm/hyp/pgtable.c | 2 --
> >  1 file changed, 2 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> > index c651df904fe3..ab9d05fcf98b 100644
> > --- a/arch/arm64/kvm/hyp/pgtable.c
> > +++ b/arch/arm64/kvm/hyp/pgtable.c
> > @@ -1419,7 +1419,6 @@ kvm_pte_t *kvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt,
> >  				 level + 1);
> >  	if (ret) {
> >  		kvm_pgtable_stage2_free_unlinked(mm_ops, pgtable, level);
> > -		mm_ops->put_page(pgtable);
> >  		return ERR_PTR(ret);
> >  	}
> 
> AFAICT, this entire branch is effectively dead code, unless there's a
> KVM bug lurking behind the page table walk. The sub-tree isn't visible
> to other software or hardware walkers yet, so none of the PTE races
> could cause this to pop.
> 
> So while this is very obviously a bug, it might be pure luck that folks
> haven't seen smoke here. Perhaps while fixing the bug we should take the
> opportunity to promote the condition to WARN_ON_ONCE().
> 
> > @@ -1502,7 +1501,6 @@ static int stage2_split_walker(const struct kvm_pgtable_visit_ctx *ctx,
> >  
> >  	if (!stage2_try_break_pte(ctx, mmu)) {
> >  		kvm_pgtable_stage2_free_unlinked(mm_ops, childp, level);
> > -		mm_ops->put_page(childp);
> >  		return -EAGAIN;
> >  	}
> 
> This, on the other hand, seems possible. There exists a race where an
> old block PTE could have the AF set on it and the underlying cmpxchg()
> could fail.

That is to say, a race with a *HW* update to the PTE that sets AF.

> There shouldn't be a race with any software walkers, as we
> hold the MMU lock for write here.
> 
> -- 
> Thanks,
> Oliver

-- 
Thanks,
Oliver


From oliver.upton at linux.dev  Mon Feb 12 12:24:36 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 20:24:36 +0000
Subject: [PATCH v7 0/4] kvm: arm64: allow the VM to select DEVICE_* and
 NORMAL_NC for IO memory
In-Reply-To: <20240211174705.31992-1-ankita@nvidia.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
Message-ID: <Zcp-hIlV-ZEu0Jou@linux.dev>

On Sun, Feb 11, 2024 at 11:17:01PM +0530, ankita at nvidia.com wrote:
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> Currently, KVM for ARM64 maps at stage 2 memory that is considered device
> with DEVICE_nGnRE memory attributes; this setting overrides (per
> ARM architecture [1]) any device MMIO mapping present at stage 1,
> resulting in a set-up whereby a guest operating system cannot
> determine device MMIO mapping memory attributes on its own but
> it is always overridden by the KVM stage 2 default.
> 
> This set-up does not allow guest operating systems to select device
> memory attributes independently from KVM stage-2 mappings
> (refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
> which turns out to be an issue in that guest operating systems
> (e.g. Linux) may request to map devices MMIO regions with memory
> attributes that guarantee better performance (e.g. gathering
> attribute - that for some devices can generate larger PCIe memory
> writes TLPs) and specific operations (e.g. unaligned transactions)
> such as the NormalNC memory type.
> 
> The default device stage 2 mapping was chosen in KVM for ARM64 since
> it was considered safer (i.e. it would not allow guests to trigger
> uncontained failures ultimately crashing the machine) but this
> turned out to be asynchronous (SError) defeating the purpose.
> 
> For these reasons, relax the KVM stage 2 device memory attributes
> from DEVICE_nGnRE to Normal-NC.

Hi Ankit,

Thanks for being responsive in respinning the series according to the
feedback. I think we're pretty close here, but it'd be good to address
the comment / changelog feedback as well.

Can you respin this once more? Hopefully we can get this stuff soaking
in -next thereafter.

-- 
Thanks,
Oliver


From robin.murphy at arm.com  Mon Feb 12 12:25:53 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 12 Feb 2024 20:25:53 +0000
Subject: [PATCH v4 01/10] dt-bindings: iommu: Add Translation Buffer Unit
 bindings
In-Reply-To: <20240201210529.7728-2-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-1-quic_c_gdjako@quicinc.com>
 <20240201210529.7728-2-quic_c_gdjako@quicinc.com>
Message-ID: <cfc87678-0445-42e6-9fc1-b22ef25566ff@arm.com>

On 2024-02-01 9:05 pm, Georgi Djakov wrote:
> Add common bindings for the TBUs to describe their properties. The
> TBUs are modelled as child devices of the IOMMU and each of them is
> described with their compatible, reg and stream-id-range properties.
> There could be other implementation specific properties to describe
> any resources like clocks, regulators, power-domains, interconnects
> that would be needed for TBU operation. Such properties will be
> documented in a separate vendor-specific TBU schema.
> 
> Signed-off-by: Georgi Djakov <quic_c_gdjako at quicinc.com>
> ---
>   .../devicetree/bindings/iommu/arm,smmu.yaml   | 14 ++++++++++
>   .../devicetree/bindings/iommu/tbu-common.yaml | 28 +++++++++++++++++++
>   2 files changed, 42 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/iommu/tbu-common.yaml
> 
> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> index a4042ae24770..ba3237023b39 100644
> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> @@ -235,6 +235,20 @@ properties:
>         enabled for any given device.
>       $ref: /schemas/types.yaml#/definitions/phandle
>   
> +  '#address-cells':
> +    enum: [ 1, 2 ]
> +
> +  '#size-cells':
> +    enum: [ 1, 2 ]
> +
> +  ranges: true
> +
> +patternProperties:
> +  "^tbu@[0-9a-f]+$":
> +    description: TBU child nodes
> +    type: object
> +    $ref: tbu-common.yaml#
> +
>   required:
>     - compatible
>     - reg
> diff --git a/Documentation/devicetree/bindings/iommu/tbu-common.yaml b/Documentation/devicetree/bindings/iommu/tbu-common.yaml
> new file mode 100644
> index 000000000000..3e95b356e572
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iommu/tbu-common.yaml
> @@ -0,0 +1,28 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iommu/tbu-common.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Translation Buffer Unit (TBU) common properties
> +
> +maintainers:
> +  - Georgi Djakov <quic_c_gdjako at quicinc.com>
> +
> +description:
> +  The SMMU implements a TBU for system masters. It consists if a
> +  Translation Lookaside Buffer (TLB) that caches page tables.
> +
> +properties:
> +  reg:
> +    maxItems: 1
> +
> +  stream-id-range:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description: Stream ID range (address and size) that is assigned by the TBU
> +    items:
> +      minItems: 2
> +      maxItems: 2

Actually, even this doesn't work - for the 15-bit StreamID config, 
there's no guarantee that the devices behind each TBU will use a single 
contiguous StreamID range. Conversely, for any other config the 
StreamIDs are already uniquely associated with a TBU by their top 5 
bits, so the "size" doesn't matter.

Thanks,
Robin.

> +
> +additionalProperties: true
> +...


From ryan.roberts at arm.com  Mon Feb 12 12:38:59 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 20:38:59 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
Message-ID: <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>

[...]

>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>> +{
>>>> +	/*
>>>> +	 * Don't attempt to apply the contig bit to kernel mappings, because
>>>> +	 * dynamically adding/removing the contig bit can cause page faults.
>>>> +	 * These racing faults are ok for user space, since they get serialized
>>>> +	 * on the PTL. But kernel mappings can't tolerate faults.
>>>> +	 */
>>>> +	return mm != &init_mm;
>>>> +}
>>>
>>> We also have the efi_mm as a non-user mm, though I don't think we manipulate
>>> that while it is live, and I'm not sure if that needs any special handling.
>>
>> Well we never need this function in the hot (order-0 folio) path, so I think I
>> could add a check for efi_mm here with performance implication. It's probably
>> safest to explicitly exclude it? What do you think?
> 
> Oops: This should have read "I think I could add a check for efi_mm here
> *without* performance implication"

It turns out that efi_mm is only defined when CONFIG_EFI is enabled. I can do this:

return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);

Is that acceptable? This is my preference, but nothing else outside of efi
references this symbol currently.

Or perhaps I can convince myself that its safe to treat efi_mm like userspace.
There are a couple of things that need to be garanteed for it to be safe:

  - The PFNs of present ptes either need to have an associated struct page or
    need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
    pte_mkdevmap())

  - Live mappings must either be static (no changes that could cause fold/unfold
    while live) or the system must be able to tolerate a temporary fault

Mark suggests efi_mm is not manipulated while live, so that meets the latter
requirement, but I'm not sure about the former?

Thanks,
Ryan



From oliver.upton at linux.dev  Mon Feb 12 12:40:08 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 20:40:08 +0000
Subject: [PATCH v3 00/26] KVM/arm64: VM configuration enforcement
In-Reply-To: <20240205103431.1104133-1-maz@kernel.org>
References: <20240205103431.1104133-1-maz@kernel.org>
Message-ID: <ZcqCKJOb2TeujGYV@linux.dev>

Hey Marc,

On Mon, Feb 05, 2024 at 10:34:05AM +0000, Marc Zyngier wrote:
> This is the third version of this configurationm enforcement series
> after some heroic reviewing from Joey (again) and Suzuki. Many thanks
> to both.
> 
> I think I have taken most of the feedback into account, but please
> shout if I have ignored something.

Want to make sure intentions are abundantly clear on this series, as
there's been a decent amount of attention from folks on managing VM
features.

At the very least I plan on taking the first two patches for 6.9 so we
have the groundwork to enable new feature work. I'd like to get more
eyes on the tail end of the series. I'm going to catch up on the work I
need to do for this merge window (including posting my own crap!) then
come back to reviewing this afterwards.

-- 
Thanks,
Oliver


From gustavo at embeddedor.com  Mon Feb 12 12:41:11 2024
From: gustavo at embeddedor.com (Gustavo A. R. Silva)
Date: Mon, 12 Feb 2024 14:41:11 -0600
Subject: [PATCH] iommu/mtk_iommu: Use devm_kcalloc() instead of
 devm_kzalloc()
In-Reply-To: <20240211182250.12656-1-erick.archer@gmx.com>
References: <20240211182250.12656-1-erick.archer@gmx.com>
Message-ID: <0f3213d3-9010-45d5-8852-f0ab3ffc8f8b@embeddedor.com>



On 2/11/24 12:22, Erick Archer wrote:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> Here the multiplication is obviously safe because MTK_PROTECT_PA_ALIGN
> is defined as a literal value of 256 or 128.
> 
> For the "mtk_iommu.c" file: 256
> For the "mtk_iommu_v1.c" file: 128
> 
> However, using devm_kcalloc() is more appropriate [2] and improves
> readability. This patch has no effect on runtime behavior.
> 
> Link: https://github.com/KSPP/linux/issues/162 [1]
> Link: https://www.kernel.org/doc/html/next/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [2]
> Signed-off-by: Erick Archer <erick.archer at gmx.com>

LGTM:

Reviewed-by: Gustavo A. R. Silva <gustavoars at kernel.org>

Thanks!
-- 
Gustavo

> ---
>   drivers/iommu/mtk_iommu.c    | 2 +-
>   drivers/iommu/mtk_iommu_v1.c | 4 ++--
>   2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 7abe9e85a570..9aae6eb604b1 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -1264,7 +1264,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_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN, GFP_KERNEL);
>   	if (!protect)
>   		return -ENOMEM;
>   	data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index 25b41222abae..45cd845d153f 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -621,8 +621,8 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev)
>   	data->dev = dev;
> 
>   	/* Protect memory. HW will access here while translation fault.*/
> -	protect = devm_kzalloc(dev, MTK_PROTECT_PA_ALIGN * 2,
> -			GFP_KERNEL | GFP_DMA);
> +	protect = devm_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN,
> +			       GFP_KERNEL | GFP_DMA);
>   	if (!protect)
>   		return -ENOMEM;
>   	data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
> --
> 2.25.1
> 
> 


From jernej.skrabec at gmail.com  Mon Feb 12 12:47:01 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 12 Feb 2024 21:47:01 +0100
Subject: [PATCH v3 2/2] arm64: dts: allwinner: h616: Add Sipeed Longan SoM 3H and
 Pi 3H board support
In-Reply-To: <20240211081739.395-3-jszhang@kernel.org>
References: <20240211081739.395-1-jszhang@kernel.org>
 <20240211081739.395-3-jszhang@kernel.org>
Message-ID: <2596781.Lt9SDvczpP@jernej-laptop>

Dne nedelja, 11. februar 2024 ob 09:17:39 CET je Jisheng Zhang napisal(a):
> The Sipeed Longan SoM 3H is a system on module based on the Allwinner
> H618 SoC. The SoM features:
> 
> - Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
> - 2/4 GiB LPDDR4 DRAM SoMs
> - AXP313a PMIC
> - eMMC
> 
> The Sipeed Longan PI 3H is a development board based on the above SoM.
> The board features:
> - Longan SoM 3H
> - Raspberry-Pi-1 compatible GPIO header
> - 2 USB 2.0 host port
> - 1 USB 2.0 type C port (power supply + OTG)
> - MicroSD slot
> - 1Gbps Ethernet port (via RTL8211 PHY)
> - HDMI port
> - WiFi/BT chip
> 
> Add the devicetree file describing the currently supported features,
> namely PMIC, LEDs, UART, SD card, eMMC, USB and Ethernet.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From oliver.upton at linux.dev  Mon Feb 12 12:50:27 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 20:50:27 +0000
Subject: [PATCH] KVM: selftests: Fix GUEST_PRINTF() format warnings in
 ARM code
In-Reply-To: <20240202234603.366925-1-seanjc@google.com>
References: <20240202234603.366925-1-seanjc@google.com>
Message-ID: <ZcqEk16eBKovb-hb@linux.dev>

+cc Anup

FYI -- this patch is touching the arch_timer code. I did a test merge
with kvm_riscv_queue and there weren't any conflicts, but in case that
changes this patch will appear on kvm-arm64/misc in my tree.

-- 
Thanks,
Oliver

On Fri, Feb 02, 2024 at 03:46:03PM -0800, Sean Christopherson wrote:
> Fix a pile of -Wformat warnings in the KVM ARM selftests code, almost all
> of which are benign "long" versus "long long" issues (selftests are 64-bit
> only, and the guest printf code treats "ll" the same as "l").  The code
> itself isn't problematic, but the warnings make it impossible to build ARM
> selftests with -Werror, which does detect real issues from time to time.
> 
> Opportunistically have GUEST_ASSERT_BITMAP_REG() interpret set_expected,
> which is a bool, as an unsigned decimal value, i.e. have it print '0' or
> '1' instead of '0x0' or '0x1'.
> 
> Signed-off-by: Sean Christopherson <seanjc at google.com>


From oliver.upton at linux.dev  Mon Feb 12 12:52:54 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 20:52:54 +0000
Subject: [PATCH v1] KVM: arm64: print Hyp mode
In-Reply-To: <20240209103719.3813599-1-joey.gouly@arm.com>
References: <20240209103719.3813599-1-joey.gouly@arm.com>
Message-ID: <170777114722.3090079.7229054370901472042.b4-ty@linux.dev>

On Fri, 9 Feb 2024 10:37:19 +0000, Joey Gouly wrote:
> Print which of the hyp modes is being used (hVHE, nVHE).
> 
> 

Applied to kvmarm/next, thanks!

[1/1] KVM: arm64: print Hyp mode
      https://git.kernel.org/kvmarm/kvmarm/c/1f3ca7023fe6

--
Best,
Oliver


From oliver.upton at linux.dev  Mon Feb 12 12:55:02 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 20:55:02 +0000
Subject: [PATCH] KVM: selftests: Fix GUEST_PRINTF() format warnings in
 ARM code
In-Reply-To: <ZcqEk16eBKovb-hb@linux.dev>
References: <20240202234603.366925-1-seanjc@google.com>
 <ZcqEk16eBKovb-hb@linux.dev>
Message-ID: <ZcqFpn9y4eHfkRJX@linux.dev>

Dammit, forgot to actually CC Anup. I'll blame jet lag.

On Mon, Feb 12, 2024 at 08:50:38PM +0000, Oliver Upton wrote:
> +cc Anup
> 
> FYI -- this patch is touching the arch_timer code. I did a test merge
> with kvm_riscv_queue and there weren't any conflicts, but in case that
> changes this patch will appear on kvm-arm64/misc in my tree.
> 
> -- 
> Thanks,
> Oliver
> 
> On Fri, Feb 02, 2024 at 03:46:03PM -0800, Sean Christopherson wrote:
> > Fix a pile of -Wformat warnings in the KVM ARM selftests code, almost all
> > of which are benign "long" versus "long long" issues (selftests are 64-bit
> > only, and the guest printf code treats "ll" the same as "l").  The code
> > itself isn't problematic, but the warnings make it impossible to build ARM
> > selftests with -Werror, which does detect real issues from time to time.
> > 
> > Opportunistically have GUEST_ASSERT_BITMAP_REG() interpret set_expected,
> > which is a bool, as an unsigned decimal value, i.e. have it print '0' or
> > '1' instead of '0x0' or '0x1'.
> > 
> > Signed-off-by: Sean Christopherson <seanjc at google.com>

-- 
Thanks,
Oliver


From oliver.upton at linux.dev  Mon Feb 12 12:55:38 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 20:55:38 +0000
Subject: [PATCH v1 0/2] small kern_hyp_va() cleanups
In-Reply-To: <20240208105422.3444159-1-joey.gouly@arm.com>
References: <20240208105422.3444159-1-joey.gouly@arm.com>
Message-ID: <170777114722.3090079.17787047168330760031.b4-ty@linux.dev>

On Thu, 8 Feb 2024 10:54:20 +0000, Joey Gouly wrote:
> I wanted to add some comments to __kern_hyp_va(), since I was recently trying
> to understand it, and I think it could be helpful for someone looking at it in
> the future.
> 
> The second patch removes the assembly macro version, since it is unused. Maybe
> (out-of-tree) pkvm uses it or it's just worth keeping around in case someone
> needs it in the future. So if that patch isn't applied it's not too important.
> 
> [...]

Applied to kvmarm/next, thanks!

[1/2] KVM: arm64: add comments to __kern_hyp_va
      https://git.kernel.org/kvmarm/kvmarm/c/d198e2668e24
[2/2] KVM: arm64: removed unused kern_hyp_va asm macro
      https://git.kernel.org/kvmarm/kvmarm/c/a02395d0f3bf

--
Best,
Oliver


From oliver.upton at linux.dev  Mon Feb 12 12:56:08 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 20:56:08 +0000
Subject: [PATCH] KVM: selftests: Fix GUEST_PRINTF() format warnings in ARM code
In-Reply-To: <20240202234603.366925-1-seanjc@google.com>
References: <20240202234603.366925-1-seanjc@google.com>
Message-ID: <170777114723.3090079.16291479870607585815.b4-ty@linux.dev>

On Fri, 2 Feb 2024 15:46:03 -0800, Sean Christopherson wrote:
> Fix a pile of -Wformat warnings in the KVM ARM selftests code, almost all
> of which are benign "long" versus "long long" issues (selftests are 64-bit
> only, and the guest printf code treats "ll" the same as "l").  The code
> itself isn't problematic, but the warnings make it impossible to build ARM
> selftests with -Werror, which does detect real issues from time to time.
> 
> Opportunistically have GUEST_ASSERT_BITMAP_REG() interpret set_expected,
> which is a bool, as an unsigned decimal value, i.e. have it print '0' or
> '1' instead of '0x0' or '0x1'.
> 
> [...]

Applied to kvmarm/next, thanks!

[1/1] KVM: selftests: Fix GUEST_PRINTF() format warnings in ARM code
      https://git.kernel.org/kvmarm/kvmarm/c/06fdd894b473

--
Best,
Oliver


From jernej.skrabec at gmail.com  Mon Feb 12 13:12:04 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 12 Feb 2024 22:12:04 +0100
Subject: [PATCH v3 0/2] arm64: dts: allwinner: h618: Add Sipeed Longan SoM 3H and
 Pi 3H board
In-Reply-To: <20240211081739.395-1-jszhang@kernel.org>
References: <20240211081739.395-1-jszhang@kernel.org>
Message-ID: <2183605.Mh6RI2rZIc@jernej-laptop>

Dne nedelja, 11. februar 2024 ob 09:17:37 CET je Jisheng Zhang napisal(a):
> Add Sipeed Longan SoM 3H and Longan Pi 3H board support.
> 
> The Sipeed Longan SoM 3H is a system on module based on the Allwinner
> H618 SoC. The SoM features:
> 
> - Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
> - 2/4 GiB LPDDR4 DRAM SoMs
> - AXP313a PMIC
> - eMMC
> 
> The Sipeed Longan PI 3H is a development board based on the above SoM.
> The board features:
> - Longan SoM 3H
> - Raspberry-Pi-1 compatible GPIO header
> - 2 USB 2.0 host port
> - 1 USB 2.0 type C port (power supply + OTG)
> - MicroSD slot
> - 1Gbps Ethernet port (via RTL8211 PHY)
> - HDMI port
> - WiFi/BT chip

Merged, thanks!

Best regards,
Jernej

> 
> Since v2:
>   - collect Reviewed-by tag
>   - add vin-supply property to reg_vcc3v3
>   - fix reg_vcc3v3 voltage value
>   - remove "interrupt-parent" and "interrupts" properties from axp313
>     node
> 
> Since v1:
>   - Use const rather than enum for "sipeed,longan-pi-3h" dt-binding
>   - remove dts-v1, model and compatible from SoM dtsi
>   - add interrupt related properties to axp313 dt node
>   - use "vcc-1v8-pll" and "vcc-3v3-io" as regulator name
>   - add dt node for board's discrete 5V->3.3V regulator and use it for
>     eth\tfcard 3.3v supply
>   - add usb2_vbus-supply property
> 
> 
> Jisheng Zhang (2):
>   dt-bindings: arm: sunxi: Add Sipeed Longan Module 3H and Longan Pi 3H
>   arm64: dts: allwinner: h616: Add Sipeed Longan SoM 3H and Pi 3H board
>     support
> 
>  .../devicetree/bindings/arm/sunxi.yaml        |   6 +
>  arch/arm64/boot/dts/allwinner/Makefile        |   1 +
>  .../sun50i-h618-longan-module-3h.dtsi         |  75 +++++++++
>  .../dts/allwinner/sun50i-h618-longanpi-3h.dts | 144 ++++++++++++++++++
>  4 files changed, 226 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
> 
> 






From nfraprado at collabora.com  Mon Feb 12 13:32:44 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Mon, 12 Feb 2024 16:32:44 -0500
Subject: [PATCH] arm64: dts: mediatek: mt8186: Add missing clocks to ssusb
 power domains
Message-ID: <20240212-mt8186-ssusb-domain-clk-fix-v1-1-26cb98746aa3@collabora.com>

The ssusb power domains currently don't list any clocks, despite
depending on some, and thus rely on the bootloader leaving the required
clocks on in order to work.

When booting with the upstream arm64 defconfig, the power domain
controller will defer probe until modules have loaded since it has an
indirect dependency on CONFIG_MTK_CMDQ, which is configured as a module.
However at the point where modules are loaded, unused clocks are also
disabled, causing the ssusb domains to fail to be enabled and
consequently the controller to fail probe:

mtk-power-controller 10006000.syscon:power-controller: /soc/syscon at 10006000/power-controller/power-domain at 4: failed to power on domain: -110
mtk-power-controller: probe of 10006000.syscon:power-controller failed with error -110

Add the missing clocks to the ssusb power domains so the power
controller can boot without relying on bootloader state.

Fixes: d9e43c1e7a38 ("arm64: dts: mt8186: Add power domains controller")
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8186.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
index adaf5e57fac5..02f33ec3cbd3 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
@@ -931,11 +931,19 @@ power-domain at MT8186_POWER_DOMAIN_CSIRX_TOP {
 
 				power-domain at MT8186_POWER_DOMAIN_SSUSB {
 					reg = <MT8186_POWER_DOMAIN_SSUSB>;
+					clocks = <&topckgen CLK_TOP_USB_TOP>,
+						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>,
+						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_XHCI>;
+					clock-names = "sys_ck", "ref_ck", "xhci_ck";
 					#power-domain-cells = <0>;
 				};
 
 				power-domain at MT8186_POWER_DOMAIN_SSUSB_P1 {
 					reg = <MT8186_POWER_DOMAIN_SSUSB_P1>;
+					clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>,
+						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>,
+						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_XHCI>;
+					clock-names = "sys_ck", "ref_ck", "xhci_ck";
 					#power-domain-cells = <0>;
 				};
 

---
base-commit: 2ae0a045e6814c8c1d676d6153c605a65746aa29
change-id: 20240212-mt8186-ssusb-domain-clk-fix-a691eec834fd

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From ryan.roberts at arm.com  Mon Feb 12 13:34:53 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 12 Feb 2024 21:34:53 +0000
Subject: [PATCH v5 03/25] mm: Make pte_next_pfn() a wrapper around
 pte_advance_pfn()
In-Reply-To: <828d2573-b5fe-43b3-b955-944c05bcdb60@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-4-ryan.roberts@arm.com>
 <c269c2e0-afca-4ff0-8ffd-9049fb52c905@redhat.com>
 <cdf4e537-5b0d-45ba-8094-527127c791a6@arm.com>
 <828d2573-b5fe-43b3-b955-944c05bcdb60@redhat.com>
Message-ID: <3bc05163-2671-4239-ae5a-b9207fdca459@arm.com>

On 12/02/2024 14:29, David Hildenbrand wrote:
> On 12.02.24 15:10, Ryan Roberts wrote:
>> On 12/02/2024 12:14, David Hildenbrand wrote:
>>> On 02.02.24 09:07, Ryan Roberts wrote:
>>>> The goal is to be able to advance a PTE by an arbitrary number of PFNs.
>>>> So introduce a new API that takes a nr param.
>>>>
>>>> We are going to remove pte_next_pfn() and replace it with
>>>> pte_advance_pfn(). As a first step, implement pte_next_pfn() as a
>>>> wrapper around pte_advance_pfn() so that we can incrementally switch the
>>>> architectures over. Once all arches are moved over, we will change all
>>>> the core-mm callers to call pte_advance_pfn() directly and remove the
>>>> wrapper.
>>>>
>>>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>>>> ---
>>>> ?? include/linux/pgtable.h | 8 +++++++-
>>>> ?? 1 file changed, 7 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>>>> index 5e7eaf8f2b97..815d92dcb96b 100644
>>>> --- a/include/linux/pgtable.h
>>>> +++ b/include/linux/pgtable.h
>>>> @@ -214,9 +214,15 @@ static inline int pmd_dirty(pmd_t pmd)
>>>> ?? ? ? #ifndef pte_next_pfn
>>>> +#ifndef pte_advance_pfn
>>>> +static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>>>> +{
>>>> +??? return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
>>>> +}
>>>> +#endif
>>>> ?? static inline pte_t pte_next_pfn(pte_t pte)
>>>> ?? {
>>>> -??? return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
>>>> +??? return pte_advance_pfn(pte, 1);
>>>> ?? }
>>>> ?? #endif
>>>> ?? 
>>>
>>> I do wonder if we simply want to leave pte_next_pfn() around? Especially patch
>>> #4, #6 don't really benefit from the change? So are the other set_ptes()
>>> implementations.
>>>
>>> That is, only convert all pte_next_pfn()->pte_advance_pfn(), and leave a
>>> pte_next_pfn() macro in place.
>>>
>>> Any downsides to that?
>>
>> The downside is just having multiple functions that effectively do the same
>> thing. Personally I think its cleaner and easier to understand the code with
>> just one generic function which we pass 1 to it where we only want to advance by
>> 1. In the end, there are only a couple of places where pte_advance_pfn(1) is
>> used, so doesn't really seem valuable to me to maintain a specialization.
> 
> Well, not really functions, just a macro. Like we have set_pte_at() translating
> to set_ptes().
> 
> Arguably, we have more callers of set_pte_at().
> 
> "Easier to understand", I don't know. :)
> 
>>
>> Unless you feel strongly that we need to keep pte_next_pfn() then I'd prefer to
>> leave it as I've done in this series.
> 
> Well, it makes you patch set shorter and there is less code churn.
> 
> So personally, I'd just leave pte_next_pfn() in there. But whatever you prefer,
> not the end of the world.

I thought about this a bit more and remembered that I'm the apprentice so I've
changed it as you suggested.



From nfraprado at collabora.com  Mon Feb 12 13:53:45 2024
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Mon, 12 Feb 2024 16:53:45 -0500
Subject: [PATCH] arm64: dts: mediatek: mt8186: Add missing clocks to
 ssusb power domains
In-Reply-To: <20240212-mt8186-ssusb-domain-clk-fix-v1-1-26cb98746aa3@collabora.com>
References: <20240212-mt8186-ssusb-domain-clk-fix-v1-1-26cb98746aa3@collabora.com>
Message-ID: <985e1a4f-c538-4a9d-be58-2c688aa7350c@notapiano>

On Mon, Feb 12, 2024 at 04:32:44PM -0500, N?colas F. R. A. Prado wrote:
> The ssusb power domains currently don't list any clocks, despite
> depending on some, and thus rely on the bootloader leaving the required
> clocks on in order to work.
> 
> When booting with the upstream arm64 defconfig, the power domain
> controller will defer probe until modules have loaded since it has an
> indirect dependency on CONFIG_MTK_CMDQ, which is configured as a module.
> However at the point where modules are loaded, unused clocks are also
> disabled, causing the ssusb domains to fail to be enabled and
> consequently the controller to fail probe:
> 
> mtk-power-controller 10006000.syscon:power-controller: /soc/syscon at 10006000/power-controller/power-domain at 4: failed to power on domain: -110
> mtk-power-controller: probe of 10006000.syscon:power-controller failed with error -110
> 
> Add the missing clocks to the ssusb power domains so the power
> controller can boot without relying on bootloader state.
> 
> Fixes: d9e43c1e7a38 ("arm64: dts: mt8186: Add power domains controller")
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> ---
>  arch/arm64/boot/dts/mediatek/mt8186.dtsi | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
> index adaf5e57fac5..02f33ec3cbd3 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
> @@ -931,11 +931,19 @@ power-domain at MT8186_POWER_DOMAIN_CSIRX_TOP {
>  
>  				power-domain at MT8186_POWER_DOMAIN_SSUSB {
>  					reg = <MT8186_POWER_DOMAIN_SSUSB>;
> +					clocks = <&topckgen CLK_TOP_USB_TOP>,
> +						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>,
> +						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_XHCI>;
> +					clock-names = "sys_ck", "ref_ck", "xhci_ck";
>  					#power-domain-cells = <0>;
>  				};
>  
>  				power-domain at MT8186_POWER_DOMAIN_SSUSB_P1 {
>  					reg = <MT8186_POWER_DOMAIN_SSUSB_P1>;
> +					clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>,
> +						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>,
> +						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_XHCI>;
> +					clock-names = "sys_ck", "ref_ck", "xhci_ck";

I forgot to mention this here, but the XHCI clock wasn't needed to get the power
domains to work per se, but leaving it out caused issues when probing the mtu3
devices:
<3>[   15.431506] mtu3 11201000.usb: clks of sts1 are not stable!
<3>[   15.443965] mtu3 11201000.usb: device enable failed -110
<3>[   15.454306] mtu3 11201000.usb: mtu3 hw init failed:-110
<3>[   15.463865] mtu3 11201000.usb: failed to initialize gadget
<4>[   15.477890] mtu3: probe of 11201000.usb failed with error -110

<3>[   15.514603] mtu3 11281000.usb: clks of sts1 are not stable!
<3>[   15.525239] mtu3 11281000.usb: device enable failed -110
<3>[   15.614174] mtu3 11281000.usb: mtu3 hw init failed:-110
<3>[   15.619647] mtu3 11281000.usb: failed to initialize gadget
<4>[   15.630623] mtu3: probe of 11281000.usb failed with error -110

Not sure if this issue should be handled separately (maybe the mtu3 device
should enable the XHCI clock?), but I opted to include the clock here to get
boot working for this device at once.

Thanks,
N?colas


From robh at kernel.org  Mon Feb 12 14:35:01 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 12 Feb 2024 16:35:01 -0600
Subject: [PATCH 1/1] arm64: dts: freescale: tqma9352: Update I2C eeprom
 compatible
In-Reply-To: <20240110100526.478771-1-alexander.stein@ew.tq-group.com>
References: <20240110100526.478771-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240212223501.GA2674720-robh@kernel.org>

On Wed, Jan 10, 2024 at 11:05:26AM +0100, Alexander Stein wrote:
> Now that there is a dedicated compatible for the idendification page use
> that instead. This also allows the removal the size and pagesize
> properties.

This commit message fails to answer Why? 

And fails to mention the ABI break.

> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> ---
>  arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
> index f6e422dc2663e..9d2328c185c90 100644
> --- a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
> @@ -122,10 +122,8 @@ eeprom1: eeprom at 57 {
>  
>  	/* protectable identification memory (part of M24C64-D @57) */
>  	eeprom at 5f {
> -		compatible = "st,24c64", "atmel,24c64";
> +		compatible = "atmel,24c64d-wl";

This compatible is not documented. Please add it to schema.

>  		reg = <0x5f>;
> -		size = <32>;
> -		pagesize = <32>;
>  		vcc-supply = <&reg_v3v3>;
>  	};
>  
> -- 
> 2.34.1
> 


From cristian.ciocaltea at collabora.com  Mon Feb 12 14:48:26 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 13 Feb 2024 00:48:26 +0200
Subject: [PATCH v4 01/19] power: reset: atc260x-poweroff: Use
 devm_register_sys_off_handler(RESTART)
In-Reply-To: <20240212162831.67838-2-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
 <20240212162831.67838-2-afd@ti.com>
Message-ID: <ad65ab14-4e23-43ec-aed8-6bfc59dddb51@collabora.com>

On 2024/02/12, Andrew Davis wrote:
> Use device life-cycle managed register function to simplify probe and
> exit paths.
>
> Signed-off-by: Andrew Davis <afd at ti.com>

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>


From cristian.ciocaltea at collabora.com  Mon Feb 12 14:54:50 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 13 Feb 2024 00:54:50 +0200
Subject: [PATCH v4 02/19] power: reset: atc260x-poweroff: Use
 devm_register_sys_off_handler(POWER_OFF)
In-Reply-To: <20240212162831.67838-3-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
 <20240212162831.67838-3-afd@ti.com>
Message-ID: <088b7b48-075f-4e68-9675-38c0e1f4a560@collabora.com>

On 2024/02/12, Andrew Davis wrote:
> Use device life-cycle managed register function to simplify probe and
> exit paths.
>
> Signed-off-by: Andrew Davis <afd at ti.com>

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>


From sre at kernel.org  Mon Feb 12 15:00:15 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 00:00:15 +0100
Subject: [PATCH v1 14/14] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <c38e7c68-e725-4174-aa0a-0594a55c8d56@gmx.net>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-15-sre@kernel.org>
 <c38e7c68-e725-4174-aa0a-0594a55c8d56@gmx.net>
Message-ID: <56eb2fnpmaya5rwfk5jvluvsidokzpoujeatihgrbxlytbzx5x@ozco7pbgkugp>

Hi Stefan,

On Mon, Feb 12, 2024 at 07:28:36PM +0100, Stefan Wahren wrote:
> > +	reg_vsd: regulator-vsd {
> i think the node name should be just "regulator"
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "VSD_3V3";
> > +		regulator-min-microvolt = <3300000>;
> > +		regulator-max-microvolt = <3300000>;
> > +	};
> > +
> > +	reg_vref: regulator-vref-4v2 {
> dito

The nodename must be unique. So just "regulator" does not work. In
the past this was sometimes solved by adding something like @0,
which is part of the nodename. But that is not ok, since there is no
reg property.

> > +&ecspi3 {
> > +	cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&mux_spi3>, <&mux_spi3_cs>;
> > +	status = "okay";
> > +
> > +	panel at 0 {
> > +		compatible = "inanbo,t28cp45tn89-v17";
> > +		reg = <0>;
> > +		backlight = <&panel_backlight>;
> > +		power-supply = <&reg_vsd>;
> > +		spi-cpha;
> > +		spi-cpol;
> > +		spi-max-frequency = <100000>;
>
> This seems slow to me. Is this a limitation of the display?

I just used something slow, which should definitely work. I will try
to increase to 1MHz. Note, that the display is not driven via SPI.
SPI is just used for the configuration.

Thanks for the review,

-- Sebastian


From lkp at intel.com  Mon Feb 12 15:00:06 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 13 Feb 2024 07:00:06 +0800
Subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock
 .is_notify_supported callback
In-Reply-To: <20240212123233.1230090-7-cristian.marussi@arm.com>
References: <20240212123233.1230090-7-cristian.marussi@arm.com>
Message-ID: <202402130607.H0A5KJ1C-lkp@intel.com>

Hi Cristian,

kernel test robot noticed the following build errors:

[auto build test ERROR on soc/for-next]
[also build test ERROR on linus/master v6.8-rc4 next-20240212]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Cristian-Marussi/firmware-arm_scmi-Check-for-notification-support/20240212-203727
base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
patch link:    https://lore.kernel.org/r/20240212123233.1230090-7-cristian.marussi%40arm.com
patch subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock .is_notify_supported callback
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20240213/202402130607.H0A5KJ1C-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240213/202402130607.H0A5KJ1C-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402130607.H0A5KJ1C-lkp at intel.com/

All error/warnings (new ones prefixed by >>):

   drivers/firmware/arm_scmi/clock.c: In function 'scmi_clk_notify_supported':
>> drivers/firmware/arm_scmi/clock.c:853:15: error: implicit declaration of function 'scmi_clock_domain_lookup' [-Werror=implicit-function-declaration]
     853 |         clk = scmi_clock_domain_lookup(ci, src_id);
         |               ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/firmware/arm_scmi/clock.c:853:13: warning: assignment to 'struct scmi_clock_info *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     853 |         clk = scmi_clock_domain_lookup(ci, src_id);
         |             ^
   cc1: some warnings being treated as errors


vim +/scmi_clock_domain_lookup +853 drivers/firmware/arm_scmi/clock.c

   842	
   843	static bool scmi_clk_notify_supported(const struct scmi_protocol_handle *ph,
   844					      u8 evt_id, u32 src_id)
   845	{
   846		bool supported;
   847		struct scmi_clock_info *clk;
   848		struct clock_info *ci = ph->get_priv(ph);
   849	
   850		if (evt_id >= ARRAY_SIZE(evt_2_cmd))
   851			return false;
   852	
 > 853		clk = scmi_clock_domain_lookup(ci, src_id);
   854		if (IS_ERR(clk))
   855			return false;
   856	
   857		if (evt_id == SCMI_EVENT_CLOCK_RATE_CHANGED)
   858			supported = clk->rate_changed_notifications;
   859		else
   860			supported = clk->rate_change_requested_notifications;
   861	
   862		return supported;
   863	}
   864	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From sre at kernel.org  Mon Feb 12 15:10:55 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 00:10:55 +0100
Subject: [PATCH v1 07/14] dt-bindings: lcdif: Do not require
 power-domains for i.MX6ULL
In-Reply-To: <a8b55331-a8c3-457e-83e0-2aa361ed23c6@gmx.net>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-8-sre@kernel.org>
 <a8b55331-a8c3-457e-83e0-2aa361ed23c6@gmx.net>
Message-ID: <khwsxrpj5fgxl7ukiur2tdyy7a6d6h6zryc5z2h7o6f7k3b32p@cjqsmdbocfpe>

Hi Stefan,

On Mon, Feb 12, 2024 at 08:20:35PM +0100, Stefan Wahren wrote:
> Am 10.02.24 um 02:18 schrieb Sebastian Reichel:
> > i.MX6UL(L) uses "fsl,imx6sx-lcdif" as fallback compatible string,
> > but has only very lightweight DISPLAY power domain. Its DISPLAY
> > power domain is not supported by the binding / Linux kernel at
> > the moment. Since the current setup is working, let's remove the
> > power-domain from being required for that platform to fix the warning
> > printed by CHECK_DTBS=y.
> i'm not sure this is a good idea. In case i.MX6UL(L) is different from
> i.MX6SX here, then it should have a different compatible.

It already has. The i.MX6UL(L) compatible looks like this:

compatible = "fsl,imx6ul-lcdif", "fsl,imx6sx-lcdif"

So the i.MX6SX one is just a fallback compatible. But the current
requirement for power-domains affects i.MX6UL(L), since it says
the compatible only needs to contain "fsl,imx6sx-lcdif" somewhere
to make power-domains mandatory.

Note, that the kernel driver does not use "fsl,imx6ul-lcdif", so
the hardware itself is indeed compatible.

-- Sebastian


From dmitry.baryshkov at linaro.org  Mon Feb 12 15:18:24 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 13 Feb 2024 01:18:24 +0200
Subject: [PATCH v2 5/5] iommu/arm-smmu: Convert to domain_alloc_paging()
In-Reply-To: <20240209222349.GA923780@nvidia.com>
References: <5-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com>
 <20240209200538.917366-1-dmitry.baryshkov@linaro.org> <20240209222349.GA923780@nvidia.com>
Message-ID: <CAA8EJpqdc3nQmTaWYY4VDE7ChV0NjMgBK7Q0rDRTyKZoWtbreA@mail.gmail.com>

On Sat, 10 Feb 2024 at 00:23, Jason Gunthorpe <jgg at nvidia.com> wrote:
>
> On Fri, Feb 09, 2024 at 10:05:38PM +0200, Dmitry Baryshkov wrote:
> > On Tue, 17 Oct 2023 Jason Gunthorpe <jgg at nvidia.com> wrote:
> > > Now that the BLOCKED and IDENTITY behaviors are managed with their own
> > > domains change to the domain_alloc_paging() op.
> > >
> > > The check for using_legacy_binding is now redundant,
> > > arm_smmu_def_domain_type() always returns IOMMU_DOMAIN_IDENTITY for this
> > > mode, so the core code will never attempt to create a DMA domain in the
> > > first place.
> > >
> > > Since commit a4fdd9762272 ("iommu: Use flush queue capability") the core
> > > code only passes in IDENTITY/BLOCKED/UNMANAGED/DMA domain types. It will
> > > not pass in IDENTITY or BLOCKED if the global statics exist, so the test
> > > for DMA is also redundant now too.
> > >
> > > Call arm_smmu_init_domain_context() early if a dev is available.
> > >
> > > Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> > > ---
> > >  drivers/iommu/arm/arm-smmu/arm-smmu.c | 21 +++++++++++++++------
> > >  1 file changed, 15 insertions(+), 6 deletions(-)
> >
> > For some reason this patch breaks booting of the APQ8096 Dragonboard820c
> > (qcom/apq8096-db820c.dts). Dispbling display subsystem (mdss) and venus
> > devices makes the board boot in most of the cases. Most frequently the
> > last parts of the log loog in a following way:
>
> It is surprising we tested this patch on some tegra systems with this
> iommu and didn't hit anything..
>
> The only real functional thing this changes is to move the domain
> initialization up in time, potentially a lot in time in some
> cases. That function does alot of things including touching HW so
> possibly there is some surprising interaction with something else.
>
> So, I would expect this to not WARN_ON and to make it work the same as
> before the patch:
>
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -875,7 +875,9 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
>         mutex_init(&smmu_domain->init_mutex);
>         spin_lock_init(&smmu_domain->cb_lock);
>
> -       if (dev) {
> +       WARN_ON(using_legacy_binding);
> +
> +/*     if (dev) {
>                 struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
>
>                 if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> @@ -883,7 +885,7 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
>                         return NULL;
>                 }
>         }
> -
> +*/
>         return &smmu_domain->domain;
>  }

With the full device tree, this crashed during the IOMMU probe, no warnings:

[   15.343477] bam-dma-engine 644000.dma-controller: num-channels
unspecified in dt
[   15.343675] bam-dma-engine 644000.dma-controller: num-ees unspecified in dt
[   15.394653] msm_serial 7570000.serial: msm_serial: detected port #2
[   15.395170] msm_serial 7570000.serial: uartclk = 19200000
[   15.401983] 7570000.serial: ttyMSM2 at MMIO 0x7570000 (irq = 37,
base_baud = 1200000) is a MSM
[   15.407549] serial serial0: tty port ttyMSM2 registered
[   15.421567] Bluetooth: hci0: setting up ROME/QCA6390
[   15.421728] arm-smmu b40000.iommu: probing hardware configuration...
[   15.425866] arm-smmu b40000.iommu: SMMUv2 with:
[   15.432153] arm-smmu b40000.iommu: stage 1 translation
[   15.436407] arm-smmu b40000.iommu: address translation ops
[   15.441580] arm-smmu b40000.iommu: non-coherent table walk
[   15.447136] arm-smmu b40000.iommu: (IDR0.CTTW overridden by FW configuration)
[   15.452750] arm-smmu b40000.iommu: stream matching with 2 register groups
[   15.460038] arm-smmu b40000.iommu: 2 context banks (0 stage-2 only)
[   15.466908] arm-smmu b40000.iommu: Supported page sizes: 0x63315000
[   15.473367] arm-smmu b40000.iommu: Stage-1: 48-bit VA -> 36-bit IPA
[   15.481638] arm-smmu b40000.iommu: preserved 0 boot mappings
[   15.491783] arm-smmu d00000.iommu: probing hardware configuration...
[   15.491955] arm-smmu d00000.iommu: SMMUv2 with:
[
Format: Log Type - Time(microsec) - Message - Optional Info
Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.XF.1.0-00301


>
> Then I'd ask you to remove the comment and do:
>
> @@ -878,7 +878,9 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
>         if (dev) {
>                 struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
>
> +               WARN_ON(true);
>                 if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> +                       printk("Allocation failure in arm_smmu_domain_alloc_paging()\n");
>                         kfree(smmu_domain);
>                         return NULL;
>                 }
>
>
> And then we may get a clue from the backtraces it generates. I only
> saw one iommu group reported in your log so I'd expect one trace?

With the full device tree, same result:

[   12.319303] bam-dma-engine 644000.dma-controller: num-channels
unspecified in dt
[   12.319502] bam-dma-engine 644000.dma-controller: num-ees unspecified in dt
[   12.370379] msm_serial 7570000.serial: msm_serial: detected port #2
[   12.370895] msm_serial 7570000.serial: uartclk = 19200000
[   12.377773] 7570000.serial: ttyMSM2 at MMIO 0x7570000 (irq = 37,
base_baud = 1200000) is a MSM
[   12.383228] serial serial0: tty port ttyMSM2 registered
[   12.397263] arm-smmu b40000.iommu: probing hardware configuration...
[   12.397441] arm-smmu b40000.iommu: SMMUv2 with:
[   12.398072] Bluetooth: hci0: setting up ROME/QCA6390
[   12.402779] arm-smmu b40000.iommu: stage 1 translation
[   12.402817] arm-smmu b40000.iommu: address translation ops
[   12.402832] arm-smmu b40000.iommu: non-coherent table walk
[   12.402848] arm-smmu b40000.iommu: (IDR0.CTTW overridden by FW configuration)
[   12.402881] arm-smmu b40000.iommu: stream matching with 2 register groups
[   12.402943] arm-smmu b40000.iommu: 2 context banks (0 stage-2 only)
[   12.402987] arm-smmu b40000.iommu: Supported page sizes: 0x63315000
[   12.403004] arm-smmu b40000.iommu: Stage-1: 48-bit VA -> 36-bit IPA
[   12.404941] arm-smmu b40000.iommu: preserved 0 boot mappings
[   12.467015] arm-smmu d00000.iommu: probing hardware configuration...
[   12.467318] arm-smmu d0
Format: Log Type - Time(microsec) - Message - Optional Info
Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.XF.1.0-00301

Even with disabling display-subsystem and venus, it crashes at the
same place, I don't seem to be able to get past it anymore.

-- 
With best wishes
Dmitry


From lkp at intel.com  Mon Feb 12 15:20:24 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 13 Feb 2024 07:20:24 +0800
Subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock
 .is_notify_supported callback
In-Reply-To: <20240212123233.1230090-7-cristian.marussi@arm.com>
References: <20240212123233.1230090-7-cristian.marussi@arm.com>
Message-ID: <202402130758.vkfAqrx0-lkp@intel.com>

Hi Cristian,

kernel test robot noticed the following build warnings:

[auto build test WARNING on soc/for-next]
[also build test WARNING on linus/master v6.8-rc4 next-20240212]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Cristian-Marussi/firmware-arm_scmi-Check-for-notification-support/20240212-203727
base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
patch link:    https://lore.kernel.org/r/20240212123233.1230090-7-cristian.marussi%40arm.com
patch subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock .is_notify_supported callback
config: arm-defconfig (https://download.01.org/0day-ci/archive/20240213/202402130758.vkfAqrx0-lkp at intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project.git f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240213/202402130758.vkfAqrx0-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402130758.vkfAqrx0-lkp at intel.com/

All warnings (new ones prefixed by >>):

   drivers/firmware/arm_scmi/clock.c:853:8: error: implicit declaration of function 'scmi_clock_domain_lookup' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
           clk = scmi_clock_domain_lookup(ci, src_id);
                 ^
>> drivers/firmware/arm_scmi/clock.c:853:6: warning: incompatible integer to pointer conversion assigning to 'struct scmi_clock_info *' from 'int' [-Wint-conversion]
           clk = scmi_clock_domain_lookup(ci, src_id);
               ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 warning and 1 error generated.


vim +853 drivers/firmware/arm_scmi/clock.c

   842	
   843	static bool scmi_clk_notify_supported(const struct scmi_protocol_handle *ph,
   844					      u8 evt_id, u32 src_id)
   845	{
   846		bool supported;
   847		struct scmi_clock_info *clk;
   848		struct clock_info *ci = ph->get_priv(ph);
   849	
   850		if (evt_id >= ARRAY_SIZE(evt_2_cmd))
   851			return false;
   852	
 > 853		clk = scmi_clock_domain_lookup(ci, src_id);
   854		if (IS_ERR(clk))
   855			return false;
   856	
   857		if (evt_id == SCMI_EVENT_CLOCK_RATE_CHANGED)
   858			supported = clk->rate_changed_notifications;
   859		else
   860			supported = clk->rate_change_requested_notifications;
   861	
   862		return supported;
   863	}
   864	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From sre at kernel.org  Mon Feb 12 15:22:57 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 00:22:57 +0100
Subject: [PATCH v1 02/14] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240212131631.GA13910-robh@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-3-sre@kernel.org>
 <20240212131631.GA13910-robh@kernel.org>
Message-ID: <rbhozhrww74j2hkhx5fcqc7edi6zlnjt6fg3onfn4jqumxem27@kaxyyrbbfplw>

Hi Rob,

On Mon, Feb 12, 2024 at 07:16:31AM -0600, Rob Herring wrote:
> [...]
> > +examples:
> > +  - |
> > +    weim at 21b8000 {
> 
> bus or external-bus

I used "memory-controller", which is what the other bindings in
memory-controller use.

-- Sebastian


From dlechner at baylibre.com  Mon Feb 12 15:26:40 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 12 Feb 2024 17:26:40 -0600
Subject: [PATCH 0/5] spi: add support for pre-cooking messages
Message-ID: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>

This is a follow-up to [1] where it was suggested to break down the
proposed SPI offload support into smaller series.

This takes on the first suggested task of introducing an API to
"pre-cook" SPI messages. This idea was first discussed extensively in
2013 [2][3] and revisited more briefly 2022 [4].

The goal here is to be able to improve performance (higher throughput,
and reduced CPU usage) by allowing peripheral drivers that use the
same struct spi_message repeatedly to "pre-cook" the message once to
avoid repeating the same validation, and possibly other operations each
time the message is sent.

This series includes __spi_validate() and the automatic splitting of
xfers in the optimizations. Another frequently suggested optimization
is doing DMA mapping only once. This is not included in this series, but
can be added later (preferably by someone with a real use case for it).

To show how this all works and get some real-world measurements, this
series includes the core changes, optimization of a SPI controller
driver, and optimization of an ADC driver. This test case was only able
to take advantage of the single validation optimization, since it didn't
require splitting transfers. With these changes, CPU usage of the
threaded interrupt handler, which calls spi_sync(), was reduced from
83% to 73% while at the same time the sample rate (frequency of SPI
xfers) was increased from 20kHz to 25kHz.

Finally, there has been quite a bit of discussion on the naming of the
API already. The most natural suggestion of spi_message_[un]prepare()
conflicts with the existing prepare_message controller callback which
does something a bit different. I've so far stuck with [un]optimize()
from [3], but am not partial to it. Maybe [un]cook() would makes more
sense to people? Or maybe we could rename the existing prepare_message
callback to free up the name?

[1]: https://lore.kernel.org/linux-spi/20240109-axi-spi-engine-series-3-v1-1-e42c6a986580 at baylibre.com/T/
[2]: https://lore.kernel.org/linux-spi/E81F4810-48DD-41EE-B110-D0D848B8A510 at martin.sperl.org/T/
[3]: https://lore.kernel.org/linux-spi/39DEC004-10A1-47EF-9D77-276188D2580C at martin.sperl.org/T/
[4]: https://lore.kernel.org/linux-spi/20220525163946.48ea40c9 at erd992/T/

---
David Lechner (5):
      spi: add spi_optimize_message() APIs
      spi: move splitting transfers to spi_optimize_message()
      spi: stm32: move splitting transfers to optimize_message
      spi: axi-spi-engine: move message compile to optimize_message
      iio: adc: ad7380: use spi_optimize_message()

 drivers/iio/adc/ad7380.c         |  52 ++++++--
 drivers/spi/spi-axi-spi-engine.c |  40 +++----
 drivers/spi/spi-stm32.c          |  28 +++--
 drivers/spi/spi.c                | 253 ++++++++++++++++++++++++++++++++-------
 include/linux/spi/spi.h          |  19 +++
 5 files changed, 305 insertions(+), 87 deletions(-)
---
base-commit: 5111fd347aee731964993fc021e428f8cf46a076
prerequisite-patch-id: 844c06b6caf25a2724e130dfa7999dc90dd26fde
change-id: 20240208-mainline-spi-precook-message-189b2f08ba7f


From dlechner at baylibre.com  Mon Feb 12 15:26:41 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 12 Feb 2024 17:26:41 -0600
Subject: [PATCH 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
Message-ID: <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com>

This adds a new spi_optimize_message() function that can be used to
optimize SPI messages that are used more than once. Peripheral drivers
that use the same message multiple times can use this API to perform SPI
message validation and controller-specific optimizations once and then
reuse the message while avoiding the overhead of revalidating the
message on each spi_(a)sync() call.

Internally, the SPI core will also call this function for each message
if the peripheral driver did not explicitly call it. This is done to so
that controller drivers don't have to have multiple code paths for
optimized and non-optimized messages.

A hook is provided for controller drivers to perform controller-specific
optimizations.

Suggested-by: Martin Sperl <kernel at martin.sperl.org>
Link: https://lore.kernel.org/linux-spi/39DEC004-10A1-47EF-9D77-276188D2580C at martin.sperl.org/
Signed-off-by: David Lechner <dlechner at baylibre.com>
---
 drivers/spi/spi.c       | 145 ++++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/spi/spi.h |  19 +++++++
 2 files changed, 160 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c2b10e2c75f0..5bac215d7009 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -2106,6 +2106,41 @@ struct spi_message *spi_get_next_queued_message(struct spi_controller *ctlr)
 }
 EXPORT_SYMBOL_GPL(spi_get_next_queued_message);
 
+/**
+ * __spi_unoptimize_message - shared implementation of spi_unoptimize_message()
+ *                            and spi_maybe_unoptimize_message()
+ * @msg: the message to unoptimize
+ *
+ * Periperhal drivers should use spi_unoptimize_message() and callers inside
+ * core should use spi_maybe_unoptimize_message() rather than calling this
+ * function directly.
+ *
+ * It is not valid to call this on a message that is not currently optimized.
+ */
+static void __spi_unoptimize_message(struct spi_message *msg)
+{
+	struct spi_controller *ctlr = msg->spi->controller;
+
+	if (ctlr->unoptimize_message)
+		ctlr->unoptimize_message(msg);
+
+	msg->optimized = false;
+	msg->opt_state = NULL;
+}
+
+/**
+ * spi_maybe_unoptimize_message - unoptimize msg not managed by a peripheral
+ * @msg: the message to unoptimize
+ *
+ * This function is used to unoptimize a message if and only if it was
+ * optimized by the core (via spi_maybe_optimize_message()).
+ */
+static void spi_maybe_unoptimize_message(struct spi_message *msg)
+{
+	if (!msg->pre_optimized && msg->optimized)
+		__spi_unoptimize_message(msg);
+}
+
 /**
  * spi_finalize_current_message() - the current message is complete
  * @ctlr: the controller to return the message to
@@ -2153,6 +2188,8 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
 
 	mesg->prepared = false;
 
+	spi_maybe_unoptimize_message(mesg);
+
 	WRITE_ONCE(ctlr->cur_msg_incomplete, false);
 	smp_mb(); /* See __spi_pump_transfer_message()... */
 	if (READ_ONCE(ctlr->cur_msg_need_completion))
@@ -4194,6 +4231,99 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
 	return 0;
 }
 
+/**
+ * __spi_optimize_message - shared implementation for spi_optimize_message()
+ *                          and spi_maybe_optimize_message()
+ * @spi: the device that will be used for the message
+ * @msg: the message to optimize
+ * @pre_optimized: whether the message is considered pre-optimized or not
+ *
+ * Peripheral drivers will call spi_optimize_message() and the spi core will
+ * call spi_maybe_optimize_message() instead of calling this directly.
+ *
+ * It is not valid to call this on a message that has already been optimized.
+ *
+ * Return: zero on success, else a negative error code
+ */
+static int __spi_optimize_message(struct spi_device *spi,
+				  struct spi_message *msg,
+				  bool pre_optimized)
+{
+	struct spi_controller *ctlr = spi->controller;
+	int ret;
+
+	ret = __spi_validate(spi, msg);
+	if (ret)
+		return ret;
+
+	if (ctlr->optimize_message) {
+		ret = ctlr->optimize_message(msg);
+		if (ret)
+			return ret;
+	}
+
+	msg->pre_optimized = pre_optimized;
+	msg->optimized = true;
+
+	return 0;
+}
+
+/**
+ * spi_maybe_optimize_message - optimize message if it isn't already pre-optimized
+ * @spi: the device that will be used for the message
+ * @msg: the message to optimize
+ * Return: zero on success, else a negative error code
+ */
+static int spi_maybe_optimize_message(struct spi_device *spi,
+				      struct spi_message *msg)
+{
+	if (msg->pre_optimized)
+		return 0;
+
+	return __spi_optimize_message(spi, msg, false);
+}
+
+/**
+ * spi_optimize_message - do any one-time validation and setup for a SPI message
+ * @spi: the device that will be used for the message
+ * @msg: the message to optimize
+ *
+ * Peripheral drivers that reuse the same message repeatedly may call this to
+ * perform as much message prep as possible once, rather than repeating it each
+ * time a message transfer is performed to improve throughput and reduce CPU
+ * usage.
+ *
+ * Once a message has been optimized, it cannot be modified with the exception
+ * of updating the contents of any xfer->tx_buf (the pointer can't be changed,
+ * only the data in the memory it points to).
+ *
+ * Calls to this function must be balanced with calls to spi_unoptimize_message()
+ * to avoid leaking resources.
+ *
+ * Context: can sleep
+ * Return: zero on success, else a negative error code
+ */
+int spi_optimize_message(struct spi_device *spi, struct spi_message *msg)
+{
+	return __spi_optimize_message(spi, msg, true);
+}
+EXPORT_SYMBOL_GPL(spi_optimize_message);
+
+/**
+ * spi_unoptimize_message - releases any resources allocated by spi_optimize_message()
+ * @msg: the message to unoptimize
+ *
+ * Calls to this function must be balanced with calls to spi_optimize_message().
+ *
+ * Context: can sleep
+ */
+void spi_unoptimize_message(struct spi_message *msg)
+{
+	__spi_unoptimize_message(msg);
+	msg->pre_optimized = false;
+}
+EXPORT_SYMBOL_GPL(spi_unoptimize_message);
+
 static int __spi_async(struct spi_device *spi, struct spi_message *message)
 {
 	struct spi_controller *ctlr = spi->controller;
@@ -4258,8 +4388,8 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
 	int ret;
 	unsigned long flags;
 
-	ret = __spi_validate(spi, message);
-	if (ret != 0)
+	ret = spi_maybe_optimize_message(spi, message);
+	if (ret)
 		return ret;
 
 	spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags);
@@ -4271,6 +4401,8 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
 
 	spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags);
 
+	spi_maybe_unoptimize_message(message);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(spi_async);
@@ -4331,10 +4463,15 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message)
 		return -ESHUTDOWN;
 	}
 
-	status = __spi_validate(spi, message);
-	if (status != 0)
+	status = spi_maybe_optimize_message(spi, message);
+	if (status)
 		return status;
 
+	/*
+	 * NB: all return paths after this point must ensure that
+	 * spi_finalize_current_message() is called to avoid leaking resources.
+	 */
+
 	SPI_STATISTICS_INCREMENT_FIELD(ctlr->pcpu_statistics, spi_sync);
 	SPI_STATISTICS_INCREMENT_FIELD(spi->pcpu_statistics, spi_sync);
 
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 2b8e2746769a..f7a269f4956b 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -475,6 +475,8 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
  *
  * @set_cs: set the logic level of the chip select line.  May be called
  *          from interrupt context.
+ * @optimize_message: optimize the message for reuse
+ * @unoptimize_message: release resources allocated by optimize_message
  * @prepare_message: set up the controller to transfer a single message,
  *                   for example doing DMA mapping.  Called from threaded
  *                   context.
@@ -715,6 +717,8 @@ struct spi_controller {
 	struct completion               xfer_completion;
 	size_t				max_dma_len;
 
+	int (*optimize_message)(struct spi_message *msg);
+	int (*unoptimize_message)(struct spi_message *msg);
 	int (*prepare_transfer_hardware)(struct spi_controller *ctlr);
 	int (*transfer_one_message)(struct spi_controller *ctlr,
 				    struct spi_message *mesg);
@@ -1111,6 +1115,7 @@ struct spi_transfer {
  * @spi: SPI device to which the transaction is queued
  * @is_dma_mapped: if true, the caller provided both DMA and CPU virtual
  *	addresses for each transfer buffer
+ * @optimized: spi_optimize_message was called for the this message
  * @prepared: spi_prepare_message was called for the this message
  * @status: zero for success, else negative errno
  * @complete: called to report transaction completions
@@ -1120,6 +1125,7 @@ struct spi_transfer {
  *	successful segments
  * @queue: for use by whichever driver currently owns the message
  * @state: for use by whichever driver currently owns the message
+ * @opt_state: for use by whichever driver currently owns the message
  * @resources: for resource management when the SPI message is processed
  *
  * A @spi_message is used to execute an atomic sequence of data transfers,
@@ -1143,6 +1149,11 @@ struct spi_message {
 
 	unsigned		is_dma_mapped:1;
 
+	/* spi_optimize_message() was called for this message */
+	bool			pre_optimized;
+	/* __spi_optimize_message() was called for this message */
+	bool			optimized;
+
 	/* spi_prepare_message() was called for this message */
 	bool			prepared;
 
@@ -1172,6 +1183,11 @@ struct spi_message {
 	 */
 	struct list_head	queue;
 	void			*state;
+	/*
+	 * Optional state for use by controller driver between calls to
+	 * spi_optimize_message() and spi_unoptimize_message().
+	 */
+	void			*opt_state;
 
 	/* List of spi_res resources when the SPI message is processed */
 	struct list_head        resources;
@@ -1255,6 +1271,9 @@ static inline void spi_message_free(struct spi_message *m)
 	kfree(m);
 }
 
+extern int spi_optimize_message(struct spi_device *spi, struct spi_message *msg);
+extern void spi_unoptimize_message(struct spi_message *msg);
+
 extern int spi_setup(struct spi_device *spi);
 extern int spi_async(struct spi_device *spi, struct spi_message *message);
 extern int spi_slave_abort(struct spi_device *spi);

-- 
2.43.0



From dlechner at baylibre.com  Mon Feb 12 15:26:42 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 12 Feb 2024 17:26:42 -0600
Subject: [PATCH 2/5] spi: move splitting transfers to spi_optimize_message()
In-Reply-To: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
Message-ID: <20240212-mainline-spi-precook-message-v1-2-a2373cd72d36@baylibre.com>

Splitting transfers is an expensive operation so we can potentially
optimize it by doing it only once per optimization of the message
instead of repeating each time the message is transferred.

The transfer splitting functions are currently the only user of
spi_res_alloc() so spi_res_release() can be safely moved at this time
from spi_finalize_current_message() to spi_unoptimize_message().

The doc comments of the public functions for splitting transfers are
also updated so that callers will know when it is safe to call them
to ensure proper resource management.

Signed-off-by: David Lechner <dlechner at baylibre.com>
---
 drivers/spi/spi.c | 110 +++++++++++++++++++++++++++++++++---------------------
 1 file changed, 68 insertions(+), 42 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 5bac215d7009..8a21fa5bd4b9 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1747,38 +1747,6 @@ static int __spi_pump_transfer_message(struct spi_controller *ctlr,
 
 	trace_spi_message_start(msg);
 
-	/*
-	 * If an SPI controller does not support toggling the CS line on each
-	 * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO
-	 * for the CS line, we can emulate the CS-per-word hardware function by
-	 * splitting transfers into one-word transfers and ensuring that
-	 * cs_change is set for each transfer.
-	 */
-	if ((msg->spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
-					       spi_is_csgpiod(msg->spi))) {
-		ret = spi_split_transfers_maxwords(ctlr, msg, 1);
-		if (ret) {
-			msg->status = ret;
-			spi_finalize_current_message(ctlr);
-			return ret;
-		}
-
-		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
-			/* Don't change cs_change on the last entry in the list */
-			if (list_is_last(&xfer->transfer_list, &msg->transfers))
-				break;
-			xfer->cs_change = 1;
-		}
-	} else {
-		ret = spi_split_transfers_maxsize(ctlr, msg,
-						  spi_max_transfer_size(msg->spi));
-		if (ret) {
-			msg->status = ret;
-			spi_finalize_current_message(ctlr);
-			return ret;
-		}
-	}
-
 	if (ctlr->prepare_message) {
 		ret = ctlr->prepare_message(ctlr, msg);
 		if (ret) {
@@ -2124,6 +2092,8 @@ static void __spi_unoptimize_message(struct spi_message *msg)
 	if (ctlr->unoptimize_message)
 		ctlr->unoptimize_message(msg);
 
+	spi_res_release(ctlr, msg);
+
 	msg->optimized = false;
 	msg->opt_state = NULL;
 }
@@ -2169,15 +2139,6 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
 
 	spi_unmap_msg(ctlr, mesg);
 
-	/*
-	 * In the prepare_messages callback the SPI bus has the opportunity
-	 * to split a transfer to smaller chunks.
-	 *
-	 * Release the split transfers here since spi_map_msg() is done on
-	 * the split transfers.
-	 */
-	spi_res_release(ctlr, mesg);
-
 	if (mesg->prepared && ctlr->unprepare_message) {
 		ret = ctlr->unprepare_message(ctlr, mesg);
 		if (ret) {
@@ -3819,6 +3780,10 @@ static int __spi_split_transfer_maxsize(struct spi_controller *ctlr,
  * @msg:   the @spi_message to transform
  * @maxsize:  the maximum when to apply this
  *
+ * This function allocates resources that are automatically freed during the
+ * spi message unoptimize phase so this function should only be called from
+ * optimize_message callbacks.
+ *
  * Return: status of transformation
  */
 int spi_split_transfers_maxsize(struct spi_controller *ctlr,
@@ -3857,6 +3822,10 @@ EXPORT_SYMBOL_GPL(spi_split_transfers_maxsize);
  * @msg:      the @spi_message to transform
  * @maxwords: the number of words to limit each transfer to
  *
+ * This function allocates resources that are automatically freed during the
+ * spi message unoptimize phase so this function should only be called from
+ * optimize_message callbacks.
+ *
  * Return: status of transformation
  */
 int spi_split_transfers_maxwords(struct spi_controller *ctlr,
@@ -4231,6 +4200,57 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
 	return 0;
 }
 
+/**
+ * spi_split_transfers - generic handling of transfer splitting
+ * @msg: the message to split
+ *
+ * Under certain conditions, a SPI controller may not support arbitrary
+ * transfer sizes or other features required by a peripheral. This function
+ * will split the transfers in the message into smaller transfers that are
+ * supported by the controller.
+ *
+ * Controllers with special requirements not covered here can also split
+ * transfers in the optimize_message() callback.
+ *
+ * Context: can sleep
+ * Return: zero on success, else a negative error code
+ */
+static int spi_split_transfers(struct spi_message *msg)
+{
+	struct spi_controller *ctlr = msg->spi->controller;
+	struct spi_transfer *xfer;
+	int ret;
+
+	/*
+	 * If an SPI controller does not support toggling the CS line on each
+	 * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO
+	 * for the CS line, we can emulate the CS-per-word hardware function by
+	 * splitting transfers into one-word transfers and ensuring that
+	 * cs_change is set for each transfer.
+	 */
+	if ((msg->spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
+					       spi_is_csgpiod(msg->spi))) {
+		ret = spi_split_transfers_maxwords(ctlr, msg, 1);
+		if (ret)
+			return ret;
+
+		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+			/* Don't change cs_change on the last entry in the list */
+			if (list_is_last(&xfer->transfer_list, &msg->transfers))
+				break;
+
+			xfer->cs_change = 1;
+		}
+	} else {
+		ret = spi_split_transfers_maxsize(ctlr, msg,
+						  spi_max_transfer_size(msg->spi));
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 /**
  * __spi_optimize_message - shared implementation for spi_optimize_message()
  *                          and spi_maybe_optimize_message()
@@ -4256,10 +4276,16 @@ static int __spi_optimize_message(struct spi_device *spi,
 	if (ret)
 		return ret;
 
+	ret = spi_split_transfers(msg);
+	if (ret)
+		return ret;
+
 	if (ctlr->optimize_message) {
 		ret = ctlr->optimize_message(msg);
-		if (ret)
+		if (ret) {
+			spi_res_release(ctlr, msg);
 			return ret;
+		}
 	}
 
 	msg->pre_optimized = pre_optimized;

-- 
2.43.0



From dlechner at baylibre.com  Mon Feb 12 15:26:43 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 12 Feb 2024 17:26:43 -0600
Subject: [PATCH 3/5] spi: stm32: move splitting transfers to optimize_message
In-Reply-To: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
Message-ID: <20240212-mainline-spi-precook-message-v1-3-a2373cd72d36@baylibre.com>

Since splitting transfers was moved to spi_optimize_message() in the
core SPI code, we now need to use the optimize_message callback in the
STM32 SPI driver to ensure that the operation is only performed once
when spi_optimize_message() is used by peripheral drivers explicitly.

Signed-off-by: David Lechner <dlechner at baylibre.com>
---
 drivers/spi/spi-stm32.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index c32e57bb38bd..e4e7ddb7524a 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -1118,6 +1118,21 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int stm32_spi_optimize_message(struct spi_message *msg)
+{
+	struct spi_controller *ctrl = msg->spi->controller;
+	struct stm32_spi *spi = spi_controller_get_devdata(ctrl);
+
+	/* On STM32H7, messages should not exceed a maximum size set
+	 * later via the set_number_of_data function. In order to
+	 * ensure that, split large messages into several messages
+	 */
+	if (spi->cfg->set_number_of_data)
+		return spi_split_transfers_maxwords(ctrl, msg, spi->t_size_max);
+
+	return 0;
+}
+
 /**
  * stm32_spi_prepare_msg - set up the controller to transfer a single message
  * @ctrl: controller interface
@@ -1163,18 +1178,6 @@ static int stm32_spi_prepare_msg(struct spi_controller *ctrl,
 		!!(spi_dev->mode & SPI_LSB_FIRST),
 		!!(spi_dev->mode & SPI_CS_HIGH));
 
-	/* On STM32H7, messages should not exceed a maximum size setted
-	 * afterward via the set_number_of_data function. In order to
-	 * ensure that, split large messages into several messages
-	 */
-	if (spi->cfg->set_number_of_data) {
-		int ret;
-
-		ret = spi_split_transfers_maxwords(ctrl, msg, spi->t_size_max);
-		if (ret)
-			return ret;
-	}
-
 	spin_lock_irqsave(&spi->lock, flags);
 
 	/* CPOL, CPHA and LSB FIRST bits have common register */
@@ -2180,6 +2183,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
 	ctrl->max_speed_hz = spi->clk_rate / spi->cfg->baud_rate_div_min;
 	ctrl->min_speed_hz = spi->clk_rate / spi->cfg->baud_rate_div_max;
 	ctrl->use_gpio_descriptors = true;
+	ctrl->optimize_message = stm32_spi_optimize_message;
 	ctrl->prepare_message = stm32_spi_prepare_msg;
 	ctrl->transfer_one = stm32_spi_transfer_one;
 	ctrl->unprepare_message = stm32_spi_unprepare_msg;

-- 
2.43.0



From dlechner at baylibre.com  Mon Feb 12 15:26:44 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 12 Feb 2024 17:26:44 -0600
Subject: [PATCH 4/5] spi: axi-spi-engine: move message compile to optimize_message
In-Reply-To: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
Message-ID: <20240212-mainline-spi-precook-message-v1-4-a2373cd72d36@baylibre.com>

In the AXI SPI Engine driver, compiling the message is an expensive
operation. Previously, it was done per message transfer in the
prepare_message hook. This patch moves the message compile to the
optimize_message hook so that it is only done once per message in
cases where the peripheral driver calls spi_optimize_message().

This can be a significant performance improvement for some peripherals.
For example, the ad7380 driver saw a 13% improvement in throughput
when using the AXI SPI Engine driver with this patch.

Since we now need two message states, one for the optimization stage
that doesn't change for the lifetime of the message and one that is
reset on each transfer for managing the current transfer state, the old
msg->state is split into msg->opt_state and spi_engine->msg_state. The
latter is included in the driver struct now since there is only one
current message at a time that can ever use it and it is in a hot path
so avoiding allocating a new one on each message transfer saves a few
cpu cycles and lets us get rid of the prepare_message callback.

Signed-off-by: David Lechner <dlechner at baylibre.com>
---
 drivers/spi/spi-axi-spi-engine.c | 40 +++++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c
index ca66d202f0e2..6177c1a8d56e 100644
--- a/drivers/spi/spi-axi-spi-engine.c
+++ b/drivers/spi/spi-axi-spi-engine.c
@@ -109,6 +109,7 @@ struct spi_engine {
 	spinlock_t lock;
 
 	void __iomem *base;
+	struct spi_engine_message_state msg_state;
 	struct completion msg_complete;
 	unsigned int int_enable;
 };
@@ -499,17 +500,11 @@ static irqreturn_t spi_engine_irq(int irq, void *devid)
 	return IRQ_HANDLED;
 }
 
-static int spi_engine_prepare_message(struct spi_controller *host,
-				      struct spi_message *msg)
+static int spi_engine_optimize_message(struct spi_message *msg)
 {
 	struct spi_engine_program p_dry, *p;
-	struct spi_engine_message_state *st;
 	size_t size;
 
-	st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (!st)
-		return -ENOMEM;
-
 	spi_engine_precompile_message(msg);
 
 	p_dry.length = 0;
@@ -517,31 +512,22 @@ static int spi_engine_prepare_message(struct spi_controller *host,
 
 	size = sizeof(*p->instructions) * (p_dry.length + 1);
 	p = kzalloc(sizeof(*p) + size, GFP_KERNEL);
-	if (!p) {
-		kfree(st);
+	if (!p)
 		return -ENOMEM;
-	}
 
 	spi_engine_compile_message(msg, false, p);
 
 	spi_engine_program_add_cmd(p, false, SPI_ENGINE_CMD_SYNC(
 						AXI_SPI_ENGINE_CUR_MSG_SYNC_ID));
 
-	st->p = p;
-	st->cmd_buf = p->instructions;
-	st->cmd_length = p->length;
-	msg->state = st;
+	msg->opt_state = p;
 
 	return 0;
 }
 
-static int spi_engine_unprepare_message(struct spi_controller *host,
-					struct spi_message *msg)
+static int spi_engine_unoptimize_message(struct spi_message *msg)
 {
-	struct spi_engine_message_state *st = msg->state;
-
-	kfree(st->p);
-	kfree(st);
+	kfree(msg->opt_state);
 
 	return 0;
 }
@@ -550,10 +536,18 @@ static int spi_engine_transfer_one_message(struct spi_controller *host,
 	struct spi_message *msg)
 {
 	struct spi_engine *spi_engine = spi_controller_get_devdata(host);
-	struct spi_engine_message_state *st = msg->state;
+	struct spi_engine_message_state *st = &spi_engine->msg_state;
+	struct spi_engine_program *p = msg->opt_state;
 	unsigned int int_enable = 0;
 	unsigned long flags;
 
+	/* reinitialize message state for this transfer */
+	memset(st, 0, sizeof(*st));
+	st->p = p;
+	st->cmd_buf = p->instructions;
+	st->cmd_length = p->length;
+	msg->state = st;
+
 	reinit_completion(&spi_engine->msg_complete);
 
 	spin_lock_irqsave(&spi_engine->lock, flags);
@@ -658,8 +652,8 @@ static int spi_engine_probe(struct platform_device *pdev)
 	host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
 	host->max_speed_hz = clk_get_rate(spi_engine->ref_clk) / 2;
 	host->transfer_one_message = spi_engine_transfer_one_message;
-	host->prepare_message = spi_engine_prepare_message;
-	host->unprepare_message = spi_engine_unprepare_message;
+	host->optimize_message = spi_engine_optimize_message;
+	host->unoptimize_message = spi_engine_unoptimize_message;
 	host->num_chipselect = 8;
 
 	if (host->max_speed_hz == 0)

-- 
2.43.0



From dlechner at baylibre.com  Mon Feb 12 15:26:45 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 12 Feb 2024 17:26:45 -0600
Subject: [PATCH 5/5] iio: adc: ad7380: use spi_optimize_message()
In-Reply-To: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
Message-ID: <20240212-mainline-spi-precook-message-v1-5-a2373cd72d36@baylibre.com>

This modifies the ad7380 ADC driver to use spi_optimize_message() to
optimize the SPI message for the buffered read operation. Since buffered
reads reuse the same SPI message for each read, this can improve
performance by reducing the overhead of setting up some parts the SPI
message in each spi_sync() call.

Signed-off-by: David Lechner <dlechner at baylibre.com>
---
 drivers/iio/adc/ad7380.c | 52 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 45 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
index abd746aef868..5c5d2642a474 100644
--- a/drivers/iio/adc/ad7380.c
+++ b/drivers/iio/adc/ad7380.c
@@ -133,6 +133,7 @@ struct ad7380_state {
 	struct spi_device *spi;
 	struct regulator *vref;
 	struct regmap *regmap;
+	struct spi_message *msg;
 	/*
 	 * DMA (thus cache coherency maintenance) requires the
 	 * transfer buffers to live in their own cache lines.
@@ -231,19 +232,55 @@ static int ad7380_debugfs_reg_access(struct iio_dev *indio_dev, u32 reg,
 	return ret;
 }
 
+static int ad7380_buffer_preenable(struct iio_dev *indio_dev)
+{
+	struct ad7380_state *st = iio_priv(indio_dev);
+	struct spi_transfer *xfer;
+	int ret;
+
+	st->msg = spi_message_alloc(1, GFP_KERNEL);
+	if (!st->msg)
+		return -ENOMEM;
+
+	xfer = list_first_entry(&st->msg->transfers, struct spi_transfer,
+				transfer_list);
+
+	xfer->bits_per_word = st->chip_info->channels[0].scan_type.realbits;
+	xfer->len = 4;
+	xfer->rx_buf = st->scan_data.raw;
+
+	ret = spi_optimize_message(st->spi, st->msg);
+	if (ret) {
+		spi_message_free(st->msg);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ad7380_buffer_postdisable(struct iio_dev *indio_dev)
+{
+	struct ad7380_state *st = iio_priv(indio_dev);
+
+	spi_unoptimize_message(st->msg);
+	spi_message_free(st->msg);
+
+	return 0;
+}
+
+static const struct iio_buffer_setup_ops ad7380_buffer_setup_ops = {
+	.preenable = ad7380_buffer_preenable,
+	.postdisable = ad7380_buffer_postdisable,
+};
+
 static irqreturn_t ad7380_trigger_handler(int irq, void *p)
 {
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->indio_dev;
 	struct ad7380_state *st = iio_priv(indio_dev);
-	struct spi_transfer xfer = {
-		.bits_per_word = st->chip_info->channels[0].scan_type.realbits,
-		.len = 4,
-		.rx_buf = st->scan_data.raw,
-	};
 	int ret;
 
-	ret = spi_sync_transfer(st->spi, &xfer, 1);
+	ret = spi_sync(st->spi, st->msg);
 	if (ret)
 		goto out;
 
@@ -420,7 +457,8 @@ static int ad7380_probe(struct spi_device *spi)
 
 	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
 					      iio_pollfunc_store_time,
-					      ad7380_trigger_handler, NULL);
+					      ad7380_trigger_handler,
+					      &ad7380_buffer_setup_ops);
 	if (ret)
 		return ret;
 

-- 
2.43.0



From eahariha at linux.microsoft.com  Mon Feb 12 15:29:06 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Mon, 12 Feb 2024 23:29:06 +0000
Subject: [PATCH] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM Neoverse N2 errata
Message-ID: <20240212232909.2276378-1-eahariha@linux.microsoft.com>

Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft
implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore
suffers from all the same errata.

CC: Mark Rutland <mark.rutland at arm.com>
CC: Marc Zyngier <maz at kernel.org>
CC: Anshuman Khandual <anshuman.khandual at arm.com>
CC: stable at vger.kernel.org # 5.15+
Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>
---
 Documentation/arch/arm64/silicon-errata.rst | 7 +++++++
 arch/arm64/include/asm/cputype.h            | 4 ++++
 arch/arm64/kernel/cpu_errata.c              | 3 +++
 3 files changed, 14 insertions(+)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index e8c2ce1f9df6..45a7f4932fe0 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -243,3 +243,10 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ASR            | ASR8601         | #8601001        | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
++----------------+-----------------+-----------------+-----------------------------+
+| Microsoft      | Azure Cobalt 100| #2139208        | ARM64_ERRATUM_2139208       |
++----------------+-----------------+-----------------+-----------------------------+
+| Microsoft      | Azure Cobalt 100| #2067961        | ARM64_ERRATUM_2067961       |
++----------------+-----------------+-----------------+-----------------------------+
+| Microsoft      | Azure Cobalt 100| #2253138        | ARM64_ERRATUM_2253138       |
++----------------+-----------------+-----------------+-----------------------------+
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 7c7493cb571f..a632a7514e55 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -61,6 +61,7 @@
 #define ARM_CPU_IMP_HISI		0x48
 #define ARM_CPU_IMP_APPLE		0x61
 #define ARM_CPU_IMP_AMPERE		0xC0
+#define ARM_CPU_IMP_MICROSOFT		0x6D
 
 #define ARM_CPU_PART_AEM_V8		0xD0F
 #define ARM_CPU_PART_FOUNDATION		0xD00
@@ -135,6 +136,8 @@
 
 #define AMPERE_CPU_PART_AMPERE1		0xAC3
 
+#define MSFT_CPU_PART_AZURE_COBALT_100	0xD49 /* Based on r0p0 of ARM Neoverse N2 */
+
 #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
 #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
 #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
@@ -193,6 +196,7 @@
 #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)
 #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
 #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
+#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MSFT_CPU_PART_AZURE_COBALT_100)
 
 /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
 #define MIDR_FUJITSU_ERRATUM_010001		MIDR_FUJITSU_A64FX
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 967c7c7a4e7d..76b8dd37092a 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -374,6 +374,7 @@ static const struct midr_range erratum_1463225[] = {
 static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
 #ifdef CONFIG_ARM64_ERRATUM_2139208
 	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_2119858
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
@@ -387,6 +388,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
 static const struct midr_range tsb_flush_fail_cpus[] = {
 #ifdef CONFIG_ARM64_ERRATUM_2067961
 	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_2054223
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
@@ -399,6 +401,7 @@ static const struct midr_range tsb_flush_fail_cpus[] = {
 static struct midr_range trbe_write_out_of_range_cpus[] = {
 #ifdef CONFIG_ARM64_ERRATUM_2253138
 	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_2224489
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
-- 
2.34.1



From jbx6244 at gmail.com  Mon Feb 12 15:29:32 2024
From: jbx6244 at gmail.com (Johan Jonker)
Date: Tue, 13 Feb 2024 00:29:32 +0100
Subject: [PATCH v3 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <20240212-phy-hdptx-v3-2-2cde680cd024@collabora.com>
References: <20240212-phy-hdptx-v3-0-2cde680cd024@collabora.com>
 <20240212-phy-hdptx-v3-2-2cde680cd024@collabora.com>
Message-ID: <b89552bf-cb04-42b1-94ac-5529205b3be1@gmail.com>



On 2/12/24 19:52, Cristian Ciocaltea wrote:
> Add driver for the HDMI/eDP TX Combo PHY found on Rockchip RK3588 SoC.
> 
> The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
> and eDP links.  The maximum data rate is 12Gbps (FRL), while the minimum
> is 250Mbps (TMDS).
> 
> Only the TMDS link is currently supported.
> 
> Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
> Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
> Tested-by: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---

For Linux FTRACE filters it is needed that all functions in a driver start with the same function prefix.
Currently there's a mix of hdtpx_* and rockchip_*
Maybe use rk_hdtpx_* ??? similar to for example rk_nfc_* in rockchip-nand-controller.c

Johan



From oliver.upton at linux.dev  Mon Feb 12 15:44:19 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 12 Feb 2024 15:44:19 -0800
Subject: [PATCH] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM
 Neoverse N2 errata
In-Reply-To: <20240212232909.2276378-1-eahariha@linux.microsoft.com>
References: <20240212232909.2276378-1-eahariha@linux.microsoft.com>
Message-ID: <ZcqtUxhqUbYoRH-G@linux.dev>

Hi Easwar,

On Mon, Feb 12, 2024 at 11:29:06PM +0000, Easwar Hariharan wrote:
> Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft
> implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore
> suffers from all the same errata.

Can you comment at all on where one might find this MIDR? That is, does
your hypervisor report the native MIDR of the implementation or does it
repaint it as an Arm Neoverse N2 (0x410FD490)?

> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 7c7493cb571f..a632a7514e55 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -61,6 +61,7 @@
>  #define ARM_CPU_IMP_HISI		0x48
>  #define ARM_CPU_IMP_APPLE		0x61
>  #define ARM_CPU_IMP_AMPERE		0xC0
> +#define ARM_CPU_IMP_MICROSOFT		0x6D
>  
>  #define ARM_CPU_PART_AEM_V8		0xD0F
>  #define ARM_CPU_PART_FOUNDATION		0xD00
> @@ -135,6 +136,8 @@
>  
>  #define AMPERE_CPU_PART_AMPERE1		0xAC3
>  
> +#define MSFT_CPU_PART_AZURE_COBALT_100	0xD49 /* Based on r0p0 of ARM Neoverse N2 */
> +
>  #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
>  #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
>  #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
> @@ -193,6 +196,7 @@
>  #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)
>  #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
>  #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
> +#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MSFT_CPU_PART_AZURE_COBALT_100)

nitpick: consistently use the abbreviated 'MSFT' for all the definitions
you're adding.

-- 
Thanks,
Oliver


From sashal at kernel.org  Mon Feb 12 16:17:43 2024
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 12 Feb 2024 19:17:43 -0500
Subject: [PATCH AUTOSEL 6.7 37/58] scsi: ufs: core: Fix shift issue in ufshcd_clear_cmd()
In-Reply-To: <20240213001837.668862-1-sashal@kernel.org>
References: <20240213001837.668862-1-sashal@kernel.org>
Message-ID: <20240213001837.668862-37-sashal@kernel.org>

From: Alice Chao <alice.chao at mediatek.com>

[ Upstream commit b513d30d59bb383a6a5d6b533afcab2cee99a8f8 ]

When task_tag >= 32 (in MCQ mode) and sizeof(unsigned int) == 4, 1U <<
task_tag will out of bounds for a u32 mask. Fix this up to prevent
SHIFT_ISSUE (bitwise shifts that are out of bounds for their data type).

[name:debug_monitors&]Unexpected kernel BRK exception at EL1
[name:traps&]Internal error: BRK handler: 00000000f2005514 [#1] PREEMPT SMP
[name:mediatek_cpufreq_hw&]cpufreq stop DVFS log done
[name:mrdump&]Kernel Offset: 0x1ba5800000 from 0xffffffc008000000
[name:mrdump&]PHYS_OFFSET: 0x80000000
[name:mrdump&]pstate: 22400005 (nzCv daif +PAN -UAO)
[name:mrdump&]pc : [0xffffffdbaf52bb2c] ufshcd_clear_cmd+0x280/0x288
[name:mrdump&]lr : [0xffffffdbaf52a774] ufshcd_wait_for_dev_cmd+0x3e4/0x82c
[name:mrdump&]sp : ffffffc0081471b0
<snip>
Workqueue: ufs_eh_wq_0 ufshcd_err_handler
Call trace:
 dump_backtrace+0xf8/0x144
 show_stack+0x18/0x24
 dump_stack_lvl+0x78/0x9c
 dump_stack+0x18/0x44
 mrdump_common_die+0x254/0x480 [mrdump]
 ipanic_die+0x20/0x30 [mrdump]
 notify_die+0x15c/0x204
 die+0x10c/0x5f8
 arm64_notify_die+0x74/0x13c
 do_debug_exception+0x164/0x26c
 el1_dbg+0x64/0x80
 el1h_64_sync_handler+0x3c/0x90
 el1h_64_sync+0x68/0x6c
 ufshcd_clear_cmd+0x280/0x288
 ufshcd_wait_for_dev_cmd+0x3e4/0x82c
 ufshcd_exec_dev_cmd+0x5bc/0x9ac
 ufshcd_verify_dev_init+0x84/0x1c8
 ufshcd_probe_hba+0x724/0x1ce0
 ufshcd_host_reset_and_restore+0x260/0x574
 ufshcd_reset_and_restore+0x138/0xbd0
 ufshcd_err_handler+0x1218/0x2f28
 process_one_work+0x5fc/0x1140
 worker_thread+0x7d8/0xe20
 kthread+0x25c/0x468
 ret_from_fork+0x10/0x20

Signed-off-by: Alice Chao <alice.chao at mediatek.com>
Link: https://lore.kernel.org/r/20240205104905.24929-1-alice.chao at mediatek.com
Reviewed-by: Stanley Jhu <chu.stanley at gmail.com>
Reviewed-by: Bart Van Assche <bvanassche at acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/ufs/core/ufshcd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 1f8d86b9c4fa..6f7cfecacd27 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -3045,7 +3045,7 @@ bool ufshcd_cmd_inflight(struct scsi_cmnd *cmd)
  */
 static int ufshcd_clear_cmd(struct ufs_hba *hba, u32 task_tag)
 {
-	u32 mask = 1U << task_tag;
+	u32 mask;
 	unsigned long flags;
 	int err;
 
@@ -3063,6 +3063,8 @@ static int ufshcd_clear_cmd(struct ufs_hba *hba, u32 task_tag)
 		return 0;
 	}
 
+	mask = 1U << task_tag;
+
 	/* clear outstanding transaction before retry */
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	ufshcd_utrl_clear(hba, mask);
-- 
2.43.0



From jgg at nvidia.com  Mon Feb 12 16:19:34 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Mon, 12 Feb 2024 20:19:34 -0400
Subject: [PATCH v2 5/5] iommu/arm-smmu: Convert to domain_alloc_paging()
In-Reply-To: <CAA8EJpqdc3nQmTaWYY4VDE7ChV0NjMgBK7Q0rDRTyKZoWtbreA@mail.gmail.com>
References: <5-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com>
 <20240209200538.917366-1-dmitry.baryshkov@linaro.org>
 <20240209222349.GA923780@nvidia.com>
 <CAA8EJpqdc3nQmTaWYY4VDE7ChV0NjMgBK7Q0rDRTyKZoWtbreA@mail.gmail.com>
Message-ID: <20240213001934.GF4048826@nvidia.com>

On Tue, Feb 13, 2024 at 01:18:24AM +0200, Dmitry Baryshkov wrote:
> > > For some reason this patch breaks booting of the APQ8096 Dragonboard820c
> > > (qcom/apq8096-db820c.dts). Dispbling display subsystem (mdss) and venus
> > > devices makes the board boot in most of the cases. Most frequently the
> > > last parts of the log loog in a following way:
> >
> > It is surprising we tested this patch on some tegra systems with this
> > iommu and didn't hit anything..
> >
> > The only real functional thing this changes is to move the domain
> > initialization up in time, potentially a lot in time in some
> > cases. That function does alot of things including touching HW so
> > possibly there is some surprising interaction with something else.
> >
> > So, I would expect this to not WARN_ON and to make it work the same as
> > before the patch:
> >
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > @@ -875,7 +875,9 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
> >         mutex_init(&smmu_domain->init_mutex);
> >         spin_lock_init(&smmu_domain->cb_lock);
> >
> > -       if (dev) {
> > +       WARN_ON(using_legacy_binding);
> > +
> > +/*     if (dev) {
> >                 struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> >
> >                 if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> > @@ -883,7 +885,7 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
> >                         return NULL;
> >                 }
> >         }
> > -
> > +*/
> >         return &smmu_domain->domain;
> >  }
> 
> With the full device tree, this crashed during the IOMMU probe, no warnings:

The above reverts nearly all the functional elements of the patch you
said caused the problem, are you certain of your bisection?

> > And then we may get a clue from the backtraces it generates. I only
> > saw one iommu group reported in your log so I'd expect one trace?
> 
> With the full device tree, same result:

This adds basically an unconditional WARN_ON on all the probe paths,
and nothing printed? That is even more surprising.

Those two together suggest that arm_smmu_domain_alloc_paging() isn't
even being called. But the caller is:

	if (alloc_type == IOMMU_DOMAIN_IDENTITY && ops->identity_domain)
		return ops->identity_domain;
	else if (alloc_type == IOMMU_DOMAIN_BLOCKED && ops->blocked_domain)
		return ops->blocked_domain;
	else if (type & __IOMMU_DOMAIN_PAGING && ops->domain_alloc_paging)
		domain = ops->domain_alloc_paging(dev);
	else if (ops->domain_alloc)
		domain = ops->domain_alloc(alloc_type);
	else
		return ERR_PTR(-EOPNOTSUPP);

Which, suggest that alloc_type is somehow garbage for your system? I
don't see how that can happen, but this patch will also cause a
garbage type to be rejected by the core code.

Does this reveal anything for you?

@@ -2118,6 +2118,7 @@ static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops,
        struct iommu_domain *domain;
        unsigned int alloc_type = type & IOMMU_DOMAIN_ALLOC_FLAGS;
 
+       WARN(true, " __iommu_domain_alloc %u %u", alloc_type, type);
        if (alloc_type == IOMMU_DOMAIN_IDENTITY && ops->identity_domain)
                return ops->identity_domain;
        else if (alloc_type == IOMMU_DOMAIN_BLOCKED && ops->blocked_domain)
@@ -2126,8 +2127,10 @@ static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops,
                domain = ops->domain_alloc_paging(dev);
        else if (ops->domain_alloc)
                domain = ops->domain_alloc(alloc_type);
-       else
+       else {
+               printk("Returning failure from __iommu_domain_alloc()\n");
                return ERR_PTR(-EOPNOTSUPP);
+       }
 
        /*
         * Many domain_alloc ops now return ERR_PTR, make things easier for the

It must print, something is wrong with the debugging process if this
doesn't generate back traces :\

Jason


From sashal at kernel.org  Mon Feb 12 16:20:08 2024
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 12 Feb 2024 19:20:08 -0500
Subject: [PATCH AUTOSEL 6.6 31/51] scsi: ufs: core: Fix shift issue in ufshcd_clear_cmd()
In-Reply-To: <20240213002052.670571-1-sashal@kernel.org>
References: <20240213002052.670571-1-sashal@kernel.org>
Message-ID: <20240213002052.670571-31-sashal@kernel.org>

From: Alice Chao <alice.chao at mediatek.com>

[ Upstream commit b513d30d59bb383a6a5d6b533afcab2cee99a8f8 ]

When task_tag >= 32 (in MCQ mode) and sizeof(unsigned int) == 4, 1U <<
task_tag will out of bounds for a u32 mask. Fix this up to prevent
SHIFT_ISSUE (bitwise shifts that are out of bounds for their data type).

[name:debug_monitors&]Unexpected kernel BRK exception at EL1
[name:traps&]Internal error: BRK handler: 00000000f2005514 [#1] PREEMPT SMP
[name:mediatek_cpufreq_hw&]cpufreq stop DVFS log done
[name:mrdump&]Kernel Offset: 0x1ba5800000 from 0xffffffc008000000
[name:mrdump&]PHYS_OFFSET: 0x80000000
[name:mrdump&]pstate: 22400005 (nzCv daif +PAN -UAO)
[name:mrdump&]pc : [0xffffffdbaf52bb2c] ufshcd_clear_cmd+0x280/0x288
[name:mrdump&]lr : [0xffffffdbaf52a774] ufshcd_wait_for_dev_cmd+0x3e4/0x82c
[name:mrdump&]sp : ffffffc0081471b0
<snip>
Workqueue: ufs_eh_wq_0 ufshcd_err_handler
Call trace:
 dump_backtrace+0xf8/0x144
 show_stack+0x18/0x24
 dump_stack_lvl+0x78/0x9c
 dump_stack+0x18/0x44
 mrdump_common_die+0x254/0x480 [mrdump]
 ipanic_die+0x20/0x30 [mrdump]
 notify_die+0x15c/0x204
 die+0x10c/0x5f8
 arm64_notify_die+0x74/0x13c
 do_debug_exception+0x164/0x26c
 el1_dbg+0x64/0x80
 el1h_64_sync_handler+0x3c/0x90
 el1h_64_sync+0x68/0x6c
 ufshcd_clear_cmd+0x280/0x288
 ufshcd_wait_for_dev_cmd+0x3e4/0x82c
 ufshcd_exec_dev_cmd+0x5bc/0x9ac
 ufshcd_verify_dev_init+0x84/0x1c8
 ufshcd_probe_hba+0x724/0x1ce0
 ufshcd_host_reset_and_restore+0x260/0x574
 ufshcd_reset_and_restore+0x138/0xbd0
 ufshcd_err_handler+0x1218/0x2f28
 process_one_work+0x5fc/0x1140
 worker_thread+0x7d8/0xe20
 kthread+0x25c/0x468
 ret_from_fork+0x10/0x20

Signed-off-by: Alice Chao <alice.chao at mediatek.com>
Link: https://lore.kernel.org/r/20240205104905.24929-1-alice.chao at mediatek.com
Reviewed-by: Stanley Jhu <chu.stanley at gmail.com>
Reviewed-by: Bart Van Assche <bvanassche at acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/ufs/core/ufshcd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 44e0437bd19d..f6c83dcff8a8 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -2949,7 +2949,7 @@ bool ufshcd_cmd_inflight(struct scsi_cmnd *cmd)
  */
 static int ufshcd_clear_cmd(struct ufs_hba *hba, u32 task_tag)
 {
-	u32 mask = 1U << task_tag;
+	u32 mask;
 	unsigned long flags;
 	int err;
 
@@ -2967,6 +2967,8 @@ static int ufshcd_clear_cmd(struct ufs_hba *hba, u32 task_tag)
 		return 0;
 	}
 
+	mask = 1U << task_tag;
+
 	/* clear outstanding transaction before retry */
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	ufshcd_utrl_clear(hba, mask);
-- 
2.43.0



From kuba at kernel.org  Mon Feb 12 16:22:44 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 12 Feb 2024 16:22:44 -0800
Subject: [PATCH net-next v3] net: ethernet: mtk_eth_soc: ppe: add
 support for multiple PPEs
In-Reply-To: <20240210135620.28368-1-eladwf@gmail.com>
References: <Zcdtb-eyvxzX9yPe@makrotopia.org>
	<20240210135620.28368-1-eladwf@gmail.com>
Message-ID: <20240212162244.3c011072@kernel.org>

On Sat, 10 Feb 2024 15:56:07 +0200 Elad Yifee wrote:
> Add the missing pieces to allow multiple PPEs units, one for each GMAC.
> mtk_gdm_config has been modified to work on targted mac ID,
> the inner loop moved outside of the function to allow unrelated
> operations like setting the MAC's PPE index.

> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> index a6e91573f8da..5d5cf73a5d5a 100644
> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> @@ -2010,6 +2010,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
>  	struct mtk_rx_dma_v2 *rxd, trxd;
>  	int done = 0, bytes = 0;
>  	dma_addr_t dma_addr = DMA_MAPPING_ERROR;
> +	u8 ppe_index = 0;

Please don't use u8 for basic on-stack variables unless it matches some
HW field which is 8b.

> @@ -3358,6 +3350,8 @@ static int mtk_open(struct net_device *dev)
>  	struct mtk_mac *mac = netdev_priv(dev);
>  	struct mtk_eth *eth = mac->hw;
>  	int i, err;
> +	struct mtk_mac *target_mac;
> +	const u8 ppe_num = mtk_get_ppe_num(eth);

nit: Please order variable decl lines longest to shortest.
If the order breaks init, you should move the init to the body.

It's a bit unclear what the difference between ppe_num, num_ppe and
ppe_index, id and ppe_idx are. It'd be good to increase the naming
consistency.

> @@ -1311,6 +1313,7 @@ struct mtk_eth {
>  struct mtk_mac {
>  	int				id;
>  	phy_interface_t			interface;
> +	u8			ppe_idx;

this looks misaligned

>  	int				speed;
>  	struct device_node		*of_node;
>  	struct phylink			*phylink;

When you repost please do not reply in the same thread.
Start a new one. 

https://www.kernel.org/doc/html/next/process/maintainer-netdev.html#resending-after-review

-- 
pw-bot: cr


From jm at ti.com  Mon Feb 12 16:24:11 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 18:24:11 -0600
Subject: [PATCH v2 4/9] arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
In-Reply-To: <20240213002416.1560357-1-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
Message-ID: <20240213002416.1560357-5-jm@ti.com>

Update MMC0/MMC1 OTAP/ITAP values according to the datasheet
[0], refer to Table 7-68 for MMC0 and Table 7-77 for MMC1.

[0] https://www.ti.com/lit/ds/symlink/am6442.pdf

Fixes: 8abae9389bdb ("arm64: dts: ti: Add support for AM642 SoC")
Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index ddd382a0d735..9bfa0a969bfc 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -633,6 +633,9 @@ sdhci0: mmc at fa10000 {
 		ti,otap-del-sel-mmc-hs = <0x0>;
 		ti,otap-del-sel-ddr52 = <0x6>;
 		ti,otap-del-sel-hs200 = <0x7>;
+		ti,itap-del-sel-legacy = <0x10>;
+		ti,itap-del-sel-mmc-hs = <0xa>;
+		ti,itap-del-sel-ddr52 = <0x3>;
 		status = "disabled";
 	};
 
@@ -645,12 +648,16 @@ sdhci1: mmc at fa00000 {
 		clock-names = "clk_ahb", "clk_xin";
 		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
-		ti,otap-del-sel-sd-hs = <0xf>;
+		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
 		ti,otap-del-sel-sdr25 = <0xf>;
 		ti,otap-del-sel-sdr50 = <0xc>;
 		ti,otap-del-sel-sdr104 = <0x6>;
 		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		ti,clkbuf-sel = <0x7>;
 		status = "disabled";
 	};
-- 
2.43.0



From jm at ti.com  Mon Feb 12 16:24:12 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 18:24:12 -0600
Subject: [PATCH v2 5/9] arm64: dts: ti: k3-am62p: Add ITAP/OTAP values for MMC
In-Reply-To: <20240213002416.1560357-1-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
Message-ID: <20240213002416.1560357-6-jm@ti.com>

Add OTAP/ITAP values to enable HS400 timing for MMC0 and
SDR104 timing for MMC1/MMC2. Remove no-1-8-v property to
enable the highest speed mode possible.

Update MMC OTAP/ITAP values according to the datasheet
[0], refer to Table 7-79 for MMC0 and Table 7-97 for MMC1/MMC2.

[0] https://www.ti.com/lit/ds/symlink/am62p.pdf

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 44 +++++++++++++++++++++--
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts   |  1 -
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index ef1c982a90d8..e43530beb79f 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -534,7 +534,21 @@ sdhci0: mmc at fa10000 {
 		clock-names = "clk_ahb", "clk_xin";
 		assigned-clocks = <&k3_clks 57 2>;
 		assigned-clock-parents = <&k3_clks 57 4>;
-		ti,otap-del-sel-legacy = <0x0>;
+		bus-width = <8>;
+		mmc-ddr-1_8v;
+		mmc-hs200-1_8v;
+		mmc-hs400-1_8v;
+		ti,clkbuf-sel = <0x7>;
+		ti,strobe-sel = <0x77>;
+		ti,trm-icp = <0x8>;
+		ti,otap-del-sel-legacy = <0x1>;
+		ti,otap-del-sel-mmc-hs = <0x1>;
+		ti,otap-del-sel-ddr52 = <0x6>;
+		ti,otap-del-sel-hs200 = <0x8>;
+		ti,otap-del-sel-hs400 = <0x5>;
+		ti,itap-del-sel-legacy = <0x10>;
+		ti,itap-del-sel-mmc-hs = <0xa>;
+		ti,itap-del-sel-ddr52 = <0x3>;
 		status = "disabled";
 	};
 
@@ -545,7 +559,19 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,otap-del-sel-legacy = <0x8>;
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		status = "disabled";
 	};
 
@@ -556,7 +582,19 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,otap-del-sel-legacy = <0x8>;
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		status = "disabled";
 	};
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 95a0146279b1..8c73587b0b62 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -424,7 +424,6 @@ &sdhci1 {
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
-	no-1-8-v;
 	bootph-all;
 };
 
-- 
2.43.0



From jm at ti.com  Mon Feb 12 16:24:16 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 18:24:16 -0600
Subject: [PATCH v2 9/9] arm64: dts: ti: k3-am6*: Add bootph-all property in MMC node
In-Reply-To: <20240213002416.1560357-1-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
Message-ID: <20240213002416.1560357-10-jm@ti.com>

Add missing bootph-all property for AM62p MMC0 and AM64x
MMC0 nodes.

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 1 +
 arch/arm64/boot/dts/ti/k3-am642-evm.dts | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 5c9b73726ebd..e86f34e835c1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -413,6 +413,7 @@ &sdhci0 {
 	status = "okay";
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
+	bootph-all;
 };
 
 &sdhci1 {
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 83f2b00726b5..fcadfb7a353c 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -497,6 +497,7 @@ &sdhci0 {
 	non-removable;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
+	bootph-all;
 };
 
 /* SD/MMC */
-- 
2.43.0



From jm at ti.com  Mon Feb 12 16:24:13 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 18:24:13 -0600
Subject: [PATCH v2 6/9] arm64: dts: ti: k3-am6*: Remove DLL properties for soft PHYs
In-Reply-To: <20240213002416.1560357-1-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
Message-ID: <20240213002416.1560357-7-jm@ti.com>

Remove DLL properties which are not applicable for soft PHYs
since these PHYs do not have a DLL to enable.

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi              | 3 ---
 arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi       | 1 -
 arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi     | 1 -
 arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi        | 1 -
 arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi       | 1 -
 arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi            | 2 --
 arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts        | 3 ---
 arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts | 1 -
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi             | 1 -
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts               | 1 -
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts               | 1 -
 arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi        | 2 --
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi              | 1 -
 arch/arm64/boot/dts/ti/k3-am642-evm.dts               | 1 -
 arch/arm64/boot/dts/ti/k3-am642-sk.dts                | 1 -
 15 files changed, 21 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index fe0cc4a9a501..79ed5cbbbda1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -561,7 +561,6 @@ sdhci0: mmc at fa10000 {
 		assigned-clock-parents = <&k3_clks 57 8>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
-		ti,trm-icp = <0x2>;
 		bus-width = <8>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
@@ -580,7 +579,6 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
@@ -604,7 +602,6 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
index 3372a256c90f..43488cc8bcb1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
@@ -317,7 +317,6 @@ serial_flash: flash at 0 {
 &sdhci0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc0_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	non-removable;
 	status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
index bf6d27e70bc4..6c4cec8728e4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
@@ -185,7 +185,6 @@ &ospi0 {
 
 /* Verdin SD_1 */
 &sdhci1 {
-	ti,driver-strength-ohm = <33>;
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
index 680071688dcb..be62648e7818 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
@@ -206,7 +206,6 @@ &ospi0 {
 
 /* Verdin SD_1 */
 &sdhci1 {
-	ti,driver-strength-ohm = <33>;
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
index a6808b10c7b2..4768ef42c4fc 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
@@ -26,7 +26,6 @@ &sdhci2 {
 	mmc-pwrseq = <&wifi_pwrseq>;
 	non-removable;
 	ti,fails-without-test-cd;
-	ti,driver-strength-ohm = <50>;
 	vmmc-supply = <&reg_3v3>;
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
index 6a06724b6d16..d68310444bcb 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
@@ -1407,7 +1407,6 @@ &sdhci0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdhci0>;
 	non-removable;
-	ti,driver-strength-ohm = <50>;
 	status = "okay";
 };
 
@@ -1416,7 +1415,6 @@ &sdhci1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdhci1>;
 	disable-wp;
-	ti,driver-strength-ohm = <50>;
 	vmmc-supply = <&reg_sdhc1_vmmc>;
 	vqmmc-supply = <&reg_sdhc1_vqmmc>;
 	status = "disabled";
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
index 3b4246ce49de..bb6a5837bcb3 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -819,7 +819,6 @@ &sdhci0 {
 	bootph-all;
 	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	status = "okay";
 };
@@ -832,7 +831,6 @@ &sdhci1 {
 
 	vmmc-supply = <&vdd_3v3_sd>;
 	vqmmc-supply = <&vdd_sd_dv>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
 	cd-debounce-delay-ms = <100>;
@@ -849,7 +847,6 @@ &sdhci2 {
 	ti,fails-without-test-cd;
 	cap-power-off-card;
 	keep-power-in-suspend;
-	ti,driver-strength-ohm = <50>;
 	assigned-clocks = <&k3_clks 157 158>;
 	assigned-clock-parents = <&k3_clks 157 160>;
 	#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
index 5c31f0453def..a83a90497857 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
@@ -334,7 +334,6 @@ &sdhci1 {
 	vqmmc-supply = <&vddshv5_sdio>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	no-1-8-v;
 	status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 6806288ec227..f283777d54b4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -561,7 +561,6 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index c99b2e90f76d..f241637a5642 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -582,7 +582,6 @@ &sdhci1 {
 	vmmc-supply = <&vdd_mmc1>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 8c73587b0b62..5c9b73726ebd 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -422,7 +422,6 @@ &sdhci1 {
 	vqmmc-supply = <&vddshv_sdio>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	bootph-all;
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
index 6dd496cd459a..3c45782ab2b7 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -411,7 +411,6 @@ &sdhci0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc0_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
@@ -421,7 +420,6 @@ &sdhci1 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index 9bfa0a969bfc..a29847735c6e 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -646,7 +646,6 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 5c546ae76d3e..f308076d608a 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -508,7 +508,6 @@ &sdhci1 {
 	pinctrl-names = "default";
 	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index cce04e188ff6..b286eaa02ada 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -471,7 +471,6 @@ &sdhci1 {
 	pinctrl-names = "default";
 	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
-- 
2.43.0



From jm at ti.com  Mon Feb 12 16:24:07 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 18:24:07 -0600
Subject: [PATCH v2 0/9] Fix MMC properties on Sitara devices
Message-ID: <20240213002416.1560357-1-jm@ti.com>

This patch series aims to update MMC nodes for TI 
K3 Sitara devices.

The series introduces MMC0 and MMC2 nodes and enables
eMMC for AM62ax platform.

Also introduce fixes for MMC ITAP/OTAP values for AM64x
platform according to device datasheet [0], and add ITAP/
OTAP values for AM62p to enable the highest timing possible
for MMC0 and MMC1, according to device datasheet [1].

The DLL properties ti,trm-icp and ti,driver-strength-ohm
should be removed for devices with soft PHYs since drive
strength cannot be changed, so remove these properties when
not applicable. Since this fix touches non-TI boards and
therefore cannot be tested, all tested-by's are welcome.

Also include a few fixes for ti,clkbuf-sel, bus-width,
and bootph-all device tree properties in MMC nodes.

This series was tested on:
- AM62a SK
- AM62x SK
- AM62p SK
- AM64x GP EVM
- AM64x SK EVM
- Beagleplay

[0] https://www.ti.com/lit/ds/symlink/am6442.pdf
[1] https://www.ti.com/lit/ds/symlink/am62p.pdf

Judith Mendez (7):
  arm64: dts: ti: k3-am62a-main: Add sdhci2 instance
  arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
  arm64: dts: ti: k3-am62p: Add ITAP/OTAP values for MMC
  arm64: dts: ti: k3-am6*: Remove DLL properties for soft PHYs
  arm64: dts: ti: k3-am6*: Fix ti,clkbuf-sel property in MMC nodes
  arm64: dts: ti: k3-am6*: Fix bus-width property in MMC nodes
  arm64: dts: ti: k3-am6*: Add bootph-all property in MMC node

Nitin Yadav (2):
  arm64: dts: ti: k3-am62a-main: Add sdhci0 instance
  arm64: dts: ti: k3-am62a7-sk: Enable eMMC support

 arch/arm64/boot/dts/ti/k3-am62-main.dtsi      | 12 +++--
 .../boot/dts/ti/k3-am62-phycore-som.dtsi      |  1 -
 .../boot/dts/ti/k3-am62-verdin-dahlia.dtsi    |  1 -
 .../arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi |  1 -
 .../boot/dts/ti/k3-am62-verdin-wifi.dtsi      |  1 -
 arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi    |  2 -
 .../arm64/boot/dts/ti/k3-am625-beagleplay.dts |  4 --
 .../dts/ti/k3-am625-phyboard-lyra-rdk.dts     |  1 -
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi     | 45 ++++++++++++++++++-
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts       | 27 ++++++++++-
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi     | 44 ++++++++++++++++--
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts       |  3 +-
 .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi |  2 -
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi      | 15 +++++--
 arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  4 +-
 arch/arm64/boot/dts/ti/k3-am642-sk.dts        |  2 -
 16 files changed, 129 insertions(+), 36 deletions(-)


base-commit: 1e6bbc5185bcd113c8d2f7aa0a02f588a6bdbe5d
-- 
2.43.0



From jm at ti.com  Mon Feb 12 16:24:15 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 18:24:15 -0600
Subject: [PATCH v2 8/9] arm64: dts: ti: k3-am6*: Fix bus-width property in MMC nodes
In-Reply-To: <20240213002416.1560357-1-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
Message-ID: <20240213002416.1560357-9-jm@ti.com>

Move bus-width property to *main.dtsi, above the OTAP/ITAP
delay values. While there is no error with where it is
currently at, it is easier to read the MMC node if the
bus-width property is located above the OTAP/ITAP delay
values consistently across MMC nodes.

Add missing bus-width for MMC2 in k3-am62-main.

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi       | 5 +++--
 arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 1 -
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi      | 2 +-
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi       | 2 ++
 arch/arm64/boot/dts/ti/k3-am642-evm.dts        | 2 --
 arch/arm64/boot/dts/ti/k3-am642-sk.dts         | 1 -
 6 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 410b390ce5d5..55420eb1c620 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -559,9 +559,9 @@ sdhci0: mmc at fa10000 {
 		clock-names = "clk_ahb", "clk_xin";
 		assigned-clocks = <&k3_clks 57 6>;
 		assigned-clock-parents = <&k3_clks 57 8>;
+		bus-width = <8>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
-		bus-width = <8>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-mmc-hs = <0x0>;
@@ -579,6 +579,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
@@ -591,7 +592,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x1>;
 		ti,itap-del-sel-sdr12 = <0xa>;
 		ti,itap-del-sel-sdr25 = <0x1>;
-		bus-width = <4>;
 		status = "disabled";
 	};
 
@@ -602,6 +602,7 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
index bb6a5837bcb3..a34e0df2ab86 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -842,7 +842,6 @@ &sdhci2 {
 	vmmc-supply = <&wlan_en>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&wifi_pins_default>, <&wifi_32k_clk>;
-	bus-width = <4>;
 	non-removable;
 	ti,fails-without-test-cd;
 	cap-power-off-card;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index ddb76cd66f88..253c1857eedf 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -561,6 +561,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
@@ -573,7 +574,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x0>;
 		ti,itap-del-sel-sdr12 = <0x0>;
 		ti,itap-del-sel-sdr25 = <0x0>;
-		bus-width = <4>;
 		no-1-8-v;
 		status = "disabled";
 	};
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index bea05be7cb48..bc9c9ff993e6 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -626,6 +626,7 @@ sdhci0: mmc at fa10000 {
 		power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 57 0>, <&k3_clks 57 1>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <8>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
 		ti,clkbuf-sel = <0x7>;
@@ -647,6 +648,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index f308076d608a..83f2b00726b5 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -494,7 +494,6 @@ eeprom at 0 {
 /* eMMC */
 &sdhci0 {
 	status = "okay";
-	bus-width = <8>;
 	non-removable;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
@@ -506,7 +505,6 @@ &sdhci1 {
 	status = "okay";
 	vmmc-supply = <&vdd_mmc1>;
 	pinctrl-names = "default";
-	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	disable-wp;
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index b286eaa02ada..67cd41bf806e 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -469,7 +469,6 @@ &sdhci1 {
 	status = "okay";
 	vmmc-supply = <&vdd_mmc1>;
 	pinctrl-names = "default";
-	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	disable-wp;
 };
-- 
2.43.0



From jm at ti.com  Mon Feb 12 16:24:09 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 18:24:09 -0600
Subject: [PATCH v2 2/9] arm64: dts: ti: k3-am62a-main: Add sdhci2 instance
In-Reply-To: <20240213002416.1560357-1-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
Message-ID: <20240213002416.1560357-3-jm@ti.com>

Add sdhci2 DT node in k3-am62a-main for mmc2. Add otap/itap
values according to the datasheet[0], Refer to Table 7-97.

[0] https://www.ti.com/lit/ds/symlink/am62a3.pdf

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 24 +++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index ce5f278235a4..6806288ec227 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -579,6 +579,30 @@ sdhci1: mmc at fa00000 {
 		status = "disabled";
 	};
 
+	sdhci2: mmc at fa20000 {
+		compatible = "ti,am62-sdhci";
+		reg = <0x00 0xfa20000 0x00 0x260>, <0x00 0xfa28000 0x00 0x134>;
+		interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
+		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
+		no-1-8-v;
+		status = "disabled";
+	};
+
 	usbss0: dwc3-usb at f900000 {
 		compatible = "ti,am62-usb";
 		reg = <0x00 0x0f900000 0x00 0x800>;
-- 
2.43.0



From jm at ti.com  Mon Feb 12 16:24:08 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 18:24:08 -0600
Subject: [PATCH v2 1/9] arm64: dts: ti: k3-am62a-main: Add sdhci0 instance
In-Reply-To: <20240213002416.1560357-1-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
Message-ID: <20240213002416.1560357-2-jm@ti.com>

From: Nitin Yadav <n-yadav at ti.com>

Add sdhci0 DT node in k3-am62a-main for eMMC support. Add otap/itap
values according to the datasheet[0], refer to Table 7-79.

[0] https://www.ti.com/lit/ds/symlink/am62a3.pdf

Signed-off-by: Nitin Yadav <n-yadav at ti.com>
Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 972971159a62..ce5f278235a4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -536,6 +536,24 @@ main_gpio1: gpio at 601000 {
 		status = "disabled";
 	};
 
+	sdhci0: mmc at fa10000 {
+		compatible = "ti,am62-sdhci";
+		reg = <0x00 0xfa10000 0x00 0x260>, <0x00 0xfa18000 0x00 0x134>;
+		interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 57 5>, <&k3_clks 57 6>;
+		clock-names = "clk_ahb", "clk_xin";
+		assigned-clocks = <&k3_clks 57 6>;
+		assigned-clock-parents = <&k3_clks 57 8>;
+		bus-width = <8>;
+		mmc-hs200-1_8v;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-mmc-hs = <0x0>;
+		ti,otap-del-sel-hs200 = <0x6>;
+		status = "disabled";
+	};
+
 	sdhci1: mmc at fa00000 {
 		compatible = "ti,am62-sdhci";
 		reg = <0x00 0xfa00000 0x00 0x260>, <0x00 0xfa08000 0x00 0x134>;
-- 
2.43.0



From jm at ti.com  Mon Feb 12 16:24:10 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 18:24:10 -0600
Subject: [PATCH v2 3/9] arm64: dts: ti: k3-am62a7-sk: Enable eMMC support
In-Reply-To: <20240213002416.1560357-1-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
Message-ID: <20240213002416.1560357-4-jm@ti.com>

From: Nitin Yadav <n-yadav at ti.com>

Add support for 32GB eMMC card on AM62A7 SK. Includes adding mmc0
pins settings. Add mmc0 alias for sdhci0 in k3-am62a7-sk.dts.

Signed-off-by: Nitin Yadav <n-yadav at ti.com>
Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts | 26 +++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index f5ae91bf1bdb..c99b2e90f76d 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -20,6 +20,7 @@ aliases {
 		serial0 = &wkup_uart0;
 		serial2 = &main_uart0;
 		serial3 = &main_uart1;
+		mmc0 = &sdhci0;
 		mmc1 = &sdhci1;
 	};
 
@@ -263,6 +264,22 @@ AM62AX_IOPAD(0x0b4, PIN_INPUT_PULLUP, 1) /* (K24) GPMC0_CSn3.I2C2_SDA */
 		>;
 	};
 
+	main_mmc0_pins_default: main-mmc0-default-pins {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */
+			AM62AX_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLKLB */
+			AM62AX_IOPAD(0x21c, PIN_INPUT, 0) /* (AB1) MMC0_CLK */
+			AM62AX_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */
+			AM62AX_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */
+			AM62AX_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */
+			AM62AX_IOPAD(0x208, PIN_INPUT_PULLUP, 0) /* (Y4) MMC0_DAT3 */
+			AM62AX_IOPAD(0x204, PIN_INPUT_PULLUP, 0) /* (AB2) MMC0_DAT4 */
+			AM62AX_IOPAD(0x200, PIN_INPUT_PULLUP, 0) /* (AC1) MMC0_DAT5 */
+			AM62AX_IOPAD(0x1fc, PIN_INPUT_PULLUP, 0) /* (AD2) MMC0_DAT6 */
+			AM62AX_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		pinctrl-single,pins = <
 			AM62AX_IOPAD(0x23c, PIN_INPUT, 0) /* (A21) MMC1_CMD */
@@ -550,6 +567,15 @@ &main_i2c2 {
 	clock-frequency = <400000>;
 };
 
+&sdhci0 {
+	/* eMMC */
+	status = "okay";
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc0_pins_default>;
+	disable-wp;
+};
+
 &sdhci1 {
 	/* SD/MMC */
 	status = "okay";
-- 
2.43.0



From jm at ti.com  Mon Feb 12 16:24:14 2024
From: jm at ti.com (Judith Mendez)
Date: Mon, 12 Feb 2024 18:24:14 -0600
Subject: [PATCH v2 7/9] arm64: dts: ti: k3-am6*: Fix ti,clkbuf-sel property in MMC nodes
In-Reply-To: <20240213002416.1560357-1-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
Message-ID: <20240213002416.1560357-8-jm@ti.com>

Move ti,clkbuf-sel property above the OTAP/ITAP delay values.
While there is no error with where it is currently at, it is
easier to read the MMC node if ti,clkbuf-sel is located above
the OTAP/ITAP delay values consistently across MMC nodes.

Add missing ti,clkbuf-sel for MMC0 in k3-am64-main.

Signed-off-by: Judith Mendez <jm at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi  | 4 ++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 2 +-
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi  | 3 ++-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 79ed5cbbbda1..410b390ce5d5 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -579,6 +579,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
@@ -590,7 +591,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x1>;
 		ti,itap-del-sel-sdr12 = <0xa>;
 		ti,itap-del-sel-sdr25 = <0x1>;
-		ti,clkbuf-sel = <0x7>;
 		bus-width = <4>;
 		status = "disabled";
 	};
@@ -602,6 +602,7 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
@@ -613,7 +614,6 @@ sdhci2: mmc at fa20000 {
 		ti,itap-del-sel-sd-hs = <0xa>;
 		ti,itap-del-sel-sdr12 = <0xa>;
 		ti,itap-del-sel-sdr25 = <0x1>;
-		ti,clkbuf-sel = <0x7>;
 		status = "disabled";
 	};
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index f283777d54b4..ddb76cd66f88 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -561,6 +561,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
@@ -572,7 +573,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x0>;
 		ti,itap-del-sel-sdr12 = <0x0>;
 		ti,itap-del-sel-sdr25 = <0x0>;
-		ti,clkbuf-sel = <0x7>;
 		bus-width = <4>;
 		no-1-8-v;
 		status = "disabled";
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index a29847735c6e..bea05be7cb48 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -628,6 +628,7 @@ sdhci0: mmc at fa10000 {
 		clock-names = "clk_ahb", "clk_xin";
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
+		ti,clkbuf-sel = <0x7>;
 		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-mmc-hs = <0x0>;
@@ -646,6 +647,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
@@ -657,7 +659,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x0>;
 		ti,itap-del-sel-sdr12 = <0x0>;
 		ti,itap-del-sel-sdr25 = <0x0>;
-		ti,clkbuf-sel = <0x7>;
 		status = "disabled";
 	};
 
-- 
2.43.0



From oliver.upton at linux.dev  Mon Feb 12 16:42:42 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 13 Feb 2024 00:42:42 +0000
Subject: [PATCH v5 4/4] KVM: arm64: Initialize the ptdump parser with
 stage-2 attributes
In-Reply-To: <20240207144832.1017815-6-sebastianene@google.com>
References: <20240207144832.1017815-2-sebastianene@google.com>
 <20240207144832.1017815-6-sebastianene@google.com>
Message-ID: <Zcq7AoII8qLWwjsu@linux.dev>

On Wed, Feb 07, 2024 at 02:48:33PM +0000, Sebastian Ene wrote:
> Define a set of attributes used by the ptdump parser to display the
> properties of a guest memory region covered by a pagetable descriptor.
> Build a description of the pagetable levels and initialize the parser
> with this configuration.
> 
> Signed-off-by: Sebastian Ene <sebastianene at google.com>
> ---
>  arch/arm64/kvm/ptdump.c | 156 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 156 insertions(+)
> 
> diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> index a4e984da8aa7..60725d46f17b 100644
> --- a/arch/arm64/kvm/ptdump.c
> +++ b/arch/arm64/kvm/ptdump.c
> @@ -14,6 +14,69 @@
>  #include <kvm_ptdump.h>
>  
>  
> +#define ADDR_MARKER_LEN		(2)
> +#define MARKER_MSG_LEN		(32)
> +
> +static const struct prot_bits stage2_pte_bits[] = {
> +	{
> +		.mask	= PTE_VALID,
> +		.val	= PTE_VALID,
> +		.set	= " ",
> +		.clear	= "F",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
> +		.set	= "XN",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> +		.set	= "R",
> +		.clear	= " ",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> +		.set	= "W",
> +		.clear	= " ",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> +		.set	= "AF",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PTE_NG,
> +		.val	= PTE_NG,
> +		.set	= "FnXS",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PTE_CONT | PTE_VALID,
> +		.val	= PTE_CONT | PTE_VALID,
> +		.set	= "CON",
> +		.clear	= "   ",
> +	}, {
> +		.mask	= PTE_TABLE_BIT,
> +		.val	= PTE_TABLE_BIT,
> +		.set	= "   ",
> +		.clear	= "BLK",

<snip>

> +	}, {
> +		.mask	= KVM_PGTABLE_PROT_SW0,
> +		.val	= KVM_PGTABLE_PROT_SW0,
> +		.set	= "SW0", /* PKVM_PAGE_SHARED_OWNED */
> +	}, {
> +		.mask   = KVM_PGTABLE_PROT_SW1,
> +		.val	= KVM_PGTABLE_PROT_SW1,
> +		.set	= "SW1", /* PKVM_PAGE_SHARED_BORROWED */
> +	}, {
> +		.mask	= KVM_PGTABLE_PROT_SW2,
> +		.val	= KVM_PGTABLE_PROT_SW2,
> +		.set	= "SW2",
> +	}, {
> +		.mask   = KVM_PGTABLE_PROT_SW3,
> +		.val	= KVM_PGTABLE_PROT_SW3,
> +		.set	= "SW3",
> +	},

</snip>

These bits are never set in a 'normal' stage-2 PTE, does it make sense
to carry descriptors for them here? In contexts where the SW bits are
used it might be more useful if the ptdump used the specific meaning of
the bit (e.g. OWNED, BORROWED, etc) instead of the generic SW%d.

That can all wait for when the pKVM bits come into play though.

> +};
> +
>  static int kvm_ptdump_guest_open(struct inode *inode, struct file *file);
>  static int kvm_ptdump_guest_show(struct seq_file *m, void *);
>  
> @@ -52,6 +115,94 @@ static int kvm_ptdump_show_common(struct seq_file *m,
>  	return kvm_pgtable_walk(pgtable, 0, BIT(pgtable->ia_bits), &walker);
>  }
>  
> +static void kvm_ptdump_build_levels(struct pg_level *level, u32 start_lvl)
> +{
> +	static const char * const level_names[] = {"PGD", "PUD", "PMD", "PTE"};
> +	u32 i = 0;
> +	u64 mask_lvl = 0;

nit: _lvl adds nothing to this, and actually confused me for a sec as
to whether the mask changed per level.

> +	if (start_lvl > 2) {
> +		pr_err("invalid start_lvl %u\n", start_lvl);
> +		return;
> +	}

Can't we get something like -EINVAL out here and fail initialization?
Otherwise breadcrumbs like this pr_err() are hard to connect to a
specific failure.

> +	for (i = 0; i < ARRAY_SIZE(stage2_pte_bits); i++)
> +		mask_lvl |= stage2_pte_bits[i].mask;
> +
> +	for (i = start_lvl; i <= KVM_PGTABLE_LAST_LEVEL; i++) {
> +		level[i].name = level_names[i];
> +		level[i].num = ARRAY_SIZE(stage2_pte_bits);
> +		level[i].bits = stage2_pte_bits;
> +		level[i].mask = mask_lvl;
> +	}
> +
> +	if (start_lvl > 0)
> +		level[start_lvl].name = level_names[0];
> +}
> +
> +static int kvm_ptdump_parser_init(struct pg_state *st,
> +				  struct kvm_pgtable *pgtable,
> +				  struct seq_file *m)
> +{
> +	struct addr_marker *ipa_addr_marker;
> +	char *marker_msg;
> +	struct pg_level *level_descr;
> +	struct ptdump_range *range;
> +
> +	ipa_addr_marker = kzalloc(sizeof(struct addr_marker) * ADDR_MARKER_LEN,
> +				  GFP_KERNEL_ACCOUNT);
> +	if (!ipa_addr_marker)
> +		return -ENOMEM;
> +
> +	marker_msg = kzalloc(MARKER_MSG_LEN, GFP_KERNEL_ACCOUNT);
> +	if (!marker_msg)
> +		goto free_with_marker;
> +
> +	level_descr = kzalloc(sizeof(struct pg_level) * (KVM_PGTABLE_LAST_LEVEL + 1),
> +			      GFP_KERNEL_ACCOUNT);
> +	if (!level_descr)
> +		goto free_with_msg;
> +
> +	range = kzalloc(sizeof(struct ptdump_range) * ADDR_MARKER_LEN,
> +			GFP_KERNEL_ACCOUNT);
> +	if (!range)
> +		goto free_with_level;
> +
> +	kvm_ptdump_build_levels(level_descr, pgtable->start_level);
> +
> +	snprintf(marker_msg, MARKER_MSG_LEN, "IPA bits %2u start lvl %1d",
> +		 pgtable->ia_bits, pgtable->start_level);
> +
> +	ipa_addr_marker[0].name = marker_msg;

Is the dynamic name worth the added complexity? I see nothing wrong with
exposing additional debugfs files for simple attributes like the IPA
range and page table levels.

I know it isn't *that* much, just looking for every opportunity to
simplify further.

> +	ipa_addr_marker[1].start_address = BIT(pgtable->ia_bits);
> +	range[0].end = BIT(pgtable->ia_bits);
> +
> +	st->seq = m;
> +	st->marker = ipa_addr_marker;
> +	st->level = -1,
> +	st->pg_level = level_descr,
> +	st->ptdump.range = range;
> +	return 0;
> +
> +free_with_level:
> +	kfree(level_descr);
> +free_with_msg:
> +	kfree(marker_msg);
> +free_with_marker:
> +	kfree(ipa_addr_marker);
> +	return -ENOMEM;
> +}
> +
> +static void kvm_ptdump_parser_teardown(struct pg_state *st)
> +{
> +	const struct addr_marker *ipa_addr_marker = st->marker;
> +
> +	kfree(ipa_addr_marker[0].name);
> +	kfree(ipa_addr_marker);
> +	kfree(st->pg_level);
> +	kfree(st->ptdump.range);
> +}
> +
>  static int kvm_ptdump_guest_show(struct seq_file *m, void *)
>  {
>  	struct kvm *guest_kvm = m->private;
> @@ -59,10 +210,15 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *)
>  	struct pg_state parser_state = {0};
>  	int ret;
>  
> +	ret = kvm_ptdump_parser_init(&parser_state, mmu->pgt, m);
> +	if (ret)
> +		return ret;
> +

Can this be done at open(), or am I missing something?

>  	write_lock(&guest_kvm->mmu_lock);
>  	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
>  	write_unlock(&guest_kvm->mmu_lock);
>  
> +	kvm_ptdump_parser_teardown(&parser_state);

Same question here, can this happen at close()? I guess you'll need a
struct to encapsulate pg_state and a pointer to the VM at least.

Actually, come to think of it, if you embed all of the data you need for
the walker into a structure you can just do a single allocation for it
upfront.

-- 
Thanks,
Oliver


From nmorrisson at phytec.com  Mon Feb 12 16:52:48 2024
From: nmorrisson at phytec.com (Nathan Morrisson)
Date: Mon, 12 Feb 2024 16:52:48 -0800
Subject: [PATCH v3] arm64: dts: ti: am62-phyboard-lyra: Add overlay to enable a GPIO fan
Message-ID: <20240213005248.1027842-1-nmorrisson@phytec.com>

The phyBOARD-Lyra has a GPIO fan header. This overlay enables the fan
header and sets the fan to turn on at 65C.

Signed-off-by: Nathan Morrisson <nmorrisson at phytec.com>
Reviewed-by: Wadim Egorov <w.egorov at phytec.de>
---
v3:
- Remove fan status okay

v2:
- Change overlay name from k3-am62-... to k3-am62x-...
- Add compile time test

 arch/arm64/boot/dts/ti/Makefile               |  3 ++
 .../ti/k3-am62x-phyboard-lyra-gpio-fan.dtso   | 50 +++++++++++++++++++
 2 files changed, 53 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..bfeb496d5039 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -22,6 +22,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dahlia.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-mallow.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am62x-phyboard-lyra-gpio-fan.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
 
 # Boards with AM62Ax SoC
@@ -87,6 +88,8 @@ k3-am625-beagleplay-csi2-ov5640-dtbs := k3-am625-beagleplay.dtb \
 	k3-am625-beagleplay-csi2-ov5640.dtbo
 k3-am625-beagleplay-csi2-tevi-ov5640-dtbs := k3-am625-beagleplay.dtb \
 	k3-am625-beagleplay-csi2-tevi-ov5640.dtbo
+k3-am625-phyboard-lyra-gpio-fan-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
+	k3-am62x-phyboard-lyra-gpio-fan.dtbo
 k3-am625-sk-csi2-imx219-dtbs := k3-am625-sk.dtb \
 	k3-am62x-sk-csi2-imx219.dtbo
 k3-am625-sk-csi2-ov5640-dtbs := k3-am625-sk.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso
new file mode 100644
index 000000000000..f0b2fd4165a7
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2024 PHYTEC America LLC
+ * Author: Garrett Giordano <ggiordano at phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	fan: gpio-fan {
+		compatible = "gpio-fan";
+		gpio-fan,speed-map = <0 0 8600 1>;
+		gpios = <&main_gpio0 40 GPIO_ACTIVE_LOW>;
+		#cooling-cells = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_fan_pins_default>;
+	};
+};
+
+&main_pmx0 {
+	gpio_fan_pins_default: gpio-fan-default-pins {
+		pinctrl-single,pins = <
+			AM62X_IOPAD(0x0a4, PIN_OUTPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
+		>;
+	};
+};
+
+&thermal_zones {
+	main0_thermal: main0-thermal {
+		trips {
+			main0_thermal_trip0: main0-thermal-trip {
+				temperature = <65000>;  /* millicelsius */
+				hysteresis = <2000>;    /* millicelsius */
+				type = "active";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&main0_thermal_trip0>;
+				cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+};
-- 
2.25.1



From oliver.upton at linux.dev  Mon Feb 12 16:56:20 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 13 Feb 2024 00:56:20 +0000
Subject: [PATCH v5 3/4] KVM: arm64: Register ptdump with debugfs on guest
 creation
In-Reply-To: <20240207144832.1017815-5-sebastianene@google.com>
References: <20240207144832.1017815-2-sebastianene@google.com>
 <20240207144832.1017815-5-sebastianene@google.com>
Message-ID: <Zcq-NGa-Gd9rVVgF@linux.dev>

On Wed, Feb 07, 2024 at 02:48:32PM +0000, Sebastian Ene wrote:
> While arch/*/mem/ptdump handles the kernel pagetable dumping code,
> introduce KVM/ptdump which shows the guest stage-2 pagetables. The
> separation is necessary because most of the definitions from the
> stage-2 pagetable reside in the KVM path and we will be invoking
> functionality **specific** to KVM.
> 
> When a guest is created, register a new file entry under the guest
> debugfs dir which allows userspace to show the contents of the guest
> stage-2 pagetables when accessed.
> 
> Signed-off-by: Sebastian Ene <sebastianene at google.com>
> ---
>  arch/arm64/kvm/Kconfig      | 13 ++++++
>  arch/arm64/kvm/Makefile     |  1 +
>  arch/arm64/kvm/debug.c      |  7 ++++
>  arch/arm64/kvm/kvm_ptdump.h | 20 ++++++++++
>  arch/arm64/kvm/ptdump.c     | 79 +++++++++++++++++++++++++++++++++++++
>  5 files changed, 120 insertions(+)
>  create mode 100644 arch/arm64/kvm/kvm_ptdump.h
>  create mode 100644 arch/arm64/kvm/ptdump.c
> 
> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> index 6c3c8ca73e7f..28097dd72174 100644
> --- a/arch/arm64/kvm/Kconfig
> +++ b/arch/arm64/kvm/Kconfig
> @@ -68,4 +68,17 @@ config PROTECTED_NVHE_STACKTRACE
>  
>  	  If unsure, or not using protected nVHE (pKVM), say N.
>  
> +config PTDUMP_STAGE2_DEBUGFS
> +       bool "Present the stage-2 pagetables to debugfs"
> +       depends on PTDUMP_DEBUGFS && KVM
> +       default n
> +       help
> +         Say Y here if you want to show the stage-2 kernel pagetables
> +         layout in a debugfs file. This information is only useful for kernel developers
> +         who are working in architecture specific areas of the kernel.
> +         It is probably not a good idea to enable this feature in a production
> +         kernel.
> +
> +         If in doubt, say N.
> +
>  endif # VIRTUALIZATION
> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> index c0c050e53157..190eac17538c 100644
> --- a/arch/arm64/kvm/Makefile
> +++ b/arch/arm64/kvm/Makefile
> @@ -23,6 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
>  	 vgic/vgic-its.o vgic/vgic-debug.o
>  
>  kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
> +kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
>  
>  always-y := hyp_constants.h hyp-constants.s
>  
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index 8725291cb00a..aef52836cd90 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -14,6 +14,8 @@
>  #include <asm/kvm_arm.h>
>  #include <asm/kvm_emulate.h>
>  
> +#include <kvm_ptdump.h>
> +
>  #include "trace.h"
>  
>  /* These are the bits of MDSCR_EL1 we may manipulate */
> @@ -342,3 +344,8 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
>  	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
>  	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
>  }
> +
> +int kvm_arch_create_vm_debugfs(struct kvm *kvm)
> +{
> +	return kvm_ptdump_guest_register(kvm);
> +}
> diff --git a/arch/arm64/kvm/kvm_ptdump.h b/arch/arm64/kvm/kvm_ptdump.h
> new file mode 100644
> index 000000000000..a7c00a28481b
> --- /dev/null
> +++ b/arch/arm64/kvm/kvm_ptdump.h
> @@ -0,0 +1,20 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) Google, 2023
> + * Author: Sebastian Ene <sebastianene at google.com>
> + */
> +
> +#ifndef __KVM_PTDUMP_H
> +#define __KVM_PTDUMP_H
> +
> +#include <linux/kvm_host.h>
> +#include <asm/ptdump.h>
> +
> +
> +#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
> +int kvm_ptdump_guest_register(struct kvm *kvm);
> +#else
> +static inline int kvm_ptdump_guest_register(struct kvm *kvm) { return 0; }
> +#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
> +
> +#endif /* __KVM_PTDUMP_H */
> diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> new file mode 100644
> index 000000000000..a4e984da8aa7
> --- /dev/null
> +++ b/arch/arm64/kvm/ptdump.c
> @@ -0,0 +1,79 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +//
> +// Debug helper used to dump the stage-2 pagetables of the system and their
> +// associated permissions.
> +//
> +// Copyright (C) Google, 2023
> +// Author: Sebastian Ene <sebastianene at google.com>

Same comment as last time about ... the comment :)

Should be of the form

/*
 *
 */

> +#include <linux/debugfs.h>
> +#include <linux/kvm_host.h>
> +#include <linux/seq_file.h>
> +
> +#include <asm/kvm_pkvm.h>

is this needed?

> +#include <kvm_ptdump.h>
> +
> +
> +static int kvm_ptdump_guest_open(struct inode *inode, struct file *file);
> +static int kvm_ptdump_guest_show(struct seq_file *m, void *);

can you structure the file in a way to avoid forward declarations?

> +static const struct file_operations kvm_ptdump_guest_fops = {
> +	.open		= kvm_ptdump_guest_open,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +	.release	= single_release,
> +};
> +
> +static int kvm_ptdump_guest_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, kvm_ptdump_guest_show, inode->i_private);
> +}
> +

Shouldn't we take a reference on the KVM struct at open to avoid UAF?

	struct kvm *kvm = inode->i_private;

	if (!kvm_get_kvm_safe(kvm))
		return -ENOENT;

Then you can do a put on it at close().

> +static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
> +			      enum kvm_pgtable_walk_flags visit)
> +{
> +	struct pg_state *st = ctx->arg;
> +	struct ptdump_state *pt_st = &st->ptdump;
> +
> +	note_page(pt_st, ctx->addr, ctx->level, ctx->old);
> +	return 0;
> +}
> +
> +static int kvm_ptdump_show_common(struct seq_file *m,
> +				  struct kvm_pgtable *pgtable,
> +				  struct pg_state *parser_state)
> +{
> +	struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker) {
> +		.cb     = kvm_ptdump_visitor,
> +		.arg	= parser_state,
> +		.flags	= KVM_PGTABLE_WALK_LEAF,
> +	};
> +
> +	return kvm_pgtable_walk(pgtable, 0, BIT(pgtable->ia_bits), &walker);
> +}
> +
> +static int kvm_ptdump_guest_show(struct seq_file *m, void *)
> +{
> +	struct kvm *guest_kvm = m->private;
> +	struct kvm_s2_mmu *mmu = &guest_kvm->arch.mmu;
> +	struct pg_state parser_state = {0};
> +	int ret;
> +
> +	write_lock(&guest_kvm->mmu_lock);
> +	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
> +	write_unlock(&guest_kvm->mmu_lock);
> +
> +	return ret;
> +}
> +
> +int kvm_ptdump_guest_register(struct kvm *kvm)
> +{
> +	struct dentry *parent;
> +
> +	parent = debugfs_create_file("stage2_page_tables", 0400,
> +				     kvm->debugfs_dentry, kvm,
> +				     &kvm_ptdump_guest_fops);
> +	if (IS_ERR(parent))
> +		return PTR_ERR(parent);

This makes the otherwise benign debugfs failure into something fatal for
VM creation, no?

>From the documentation on debugfs_create_file():

 * NOTE: it's expected that most callers should _ignore_ the errors returned
 * by this function. Other debugfs functions handle the fact that the "dentry"
 * passed to them could be an error and they don't crash in that case.
 * Drivers should generally work fine even if debugfs fails to init anyway.

The fact that kvm_arch_create_vm_debugfs() has a return value is a bit
of an anti-pattern to begin with.

-- 
Thanks,
Oliver


From sre at kernel.org  Mon Feb 12 17:00:53 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:53 +0100
Subject: [PATCH v2 04/17] dt-bindings: input: touchscreen: fsl,imx6ul-tsc convert to YAML
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-5-sre@kernel.org>

Convert the i.MX6UL touchscreen DT binding to YAML.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../input/touchscreen/fsl,imx6ul-tsc.yaml     | 97 +++++++++++++++++++
 .../bindings/input/touchscreen/imx6ul_tsc.txt | 38 --------
 2 files changed, 97 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
 delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml b/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
new file mode 100644
index 000000000000..678756ad0f92
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/fsl,imx6ul-tsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX6UL Touch Controller
+
+maintainers:
+  - Haibo Chen <haibo.chen at nxp.com>
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+properties:
+  compatible:
+    const: fsl,imx6ul-tsc
+
+  reg:
+    items:
+      - description: touch controller address
+      - description: ADC2 address
+
+  interrupts:
+    items:
+      - description: touch controller address
+      - description: ADC2 address
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: tsc
+      - const: adc
+
+  xnur-gpios:
+    maxItems: 1
+    description:
+      The X- gpio this controller connect to. This xnur-gpio returns to
+      low once the finger leave the touch screen (The last touch event
+      the touch controller capture).
+
+  measure-delay-time:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      The value of measure delay time. Before X-axis or Y-axis measurement,
+      the screen need some time before even potential distribution ready.
+    default: 0xffff
+    minimum: 0
+    maximum: 0xffffff
+
+  pre-charge-time:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      The touch screen need some time to precharge.
+    default: 0xfff
+    minimum: 0
+    maximum: 0xffffffff
+
+  touchscreen-average-samples:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: Number of data samples which are averaged for each read.
+    enum: [ 1, 4, 8, 16, 32 ]
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - xnur-gpios
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/imx6ul-clock.h>
+    #include <dt-bindings/gpio/gpio.h>
+    touchscreen at 2040000 {
+        compatible = "fsl,imx6ul-tsc";
+        reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
+        interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX6UL_CLK_IPG>,
+                 <&clks IMX6UL_CLK_ADC2>;
+        clock-names = "tsc", "adc";
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_tsc>;
+        xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+        measure-delay-time = <0xfff>;
+        pre-charge-time = <0xffff>;
+        touchscreen-average-samples = <32>;
+    };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
deleted file mode 100644
index 164915004424..000000000000
--- a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-* Freescale i.MX6UL Touch Controller
-
-Required properties:
-- compatible: must be "fsl,imx6ul-tsc".
-- reg: this touch controller address and the ADC2 address.
-- interrupts: the interrupt of this touch controller and ADC2.
-- clocks: the root clock of touch controller and ADC2.
-- clock-names; must be "tsc" and "adc".
-- xnur-gpio: the X- gpio this controller connect to.
-  This xnur-gpio returns to low once the finger leave the touch screen (The
-  last touch event the touch controller capture).
-
-Optional properties:
-- measure-delay-time: the value of measure delay time.
-  Before X-axis or Y-axis measurement, the screen need some time before
-  even potential distribution ready.
-  This value depends on the touch screen.
-- pre-charge-time: the touch screen need some time to precharge.
-  This value depends on the touch screen.
-- touchscreen-average-samples: Number of data samples which are averaged for
-  each read. Valid values are 1, 4, 8, 16 and 32.
-
-Example:
-	tsc: tsc at 2040000 {
-		compatible = "fsl,imx6ul-tsc";
-		reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
-		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clks IMX6UL_CLK_IPG>,
-			 <&clks IMX6UL_CLK_ADC2>;
-		clock-names = "tsc", "adc";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_tsc>;
-		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
-		measure-delay-time = <0xfff>;
-		pre-charge-time = <0xffff>;
-		touchscreen-average-samples = <32>;
-	};
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:00:49 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:49 +0100
Subject: [PATCH v2 00/17] UNI-T UTi260B support
Message-ID: <20240213010347.1075251-1-sre@kernel.org>

Hi,

This adds adds support for the UNI-T UTi260B thermal camera, which is based
on i.MX6ULL. Patches 1-14 clean up all warnings reported by CHECK_DTBS for
i.MX6ULL (i.e. for an empty board). They are not specific to the UTi260B and
in fact that machine has most of the IP handled by these patches marked as
disabled. Then patches 15+16 introduce the vendor and board compatible DT
bindings. Finally the last patches adds support for the thermal camera itself.

The DT is based on reverse engineered information. More information about
the device can be found in this presentation from Embedded Recipes 2023:

 * https://embedded-recipes.org/2023/wp-content/uploads/2023/10/Running-FOSS-on-a-Thermal-Camera-Sebastian-Reichel-compressed.pdf
 * https://www.youtube.com/watch?v=uvObsCG-Cqo

I also prepared a branch with these patches (and a minimal kernel config)
and published it here:

https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/log/?h=uti260b-v2

Changes since PATCHv1:
 * https://lore.kernel.org/all/20240210012114.489102-1-sre at kernel.org/
  - uni-t,imx6ull-uti260b -> uni-t,uti260b
  - add Acked-by for uni-t vendor prefix
  - add Acked-by for HDMI audio index fix
  - add Acked-by for LCDIF power-domain requirement drop
  - anatop DT binding: Fixed indentation in example
  - anatop DT binding: Described IRQs
  - touchscreen DT binding: change tsc@ to touchscreen@ in example
  - touchscreen DT binding: change xnur-gpio to xnur-gpios
  - weim DT binding: drop acme,whatever example
  - weim DT binding: use flash@ instead of nor@
  - weim DT binding: update weim.txt reference in arcx,anybus-controller.txt
  - weim DT binding: switch to memory-controller binding
  - fsl,imx-asrc DT binding: fix ASoC patch subject prefix
  - fsl,imx-asrc DT binding: add constraints
  - add new patch fixing xnur-gpio(s) in all i.MX6UL board DT files
  - add new patch fixing touchscreen nodename in i.MX6UL SoC DT file
  - add new patch fixing weim nodename in all i.MX SoC DT files
  - device DTS: use color/functions for the led
  - device DTS: increase SPI speed
  - device DTS: add comment for SD / eMMC node

Unadressed feedback from PATCHv1:
  - anatop phandle vs parent: technically it makes sense to just use the
    parent, but this driver is only used by i.MX6. The current code makes
	use of the phandle, so we cannot drop it because of backwards
	compatibility. So I don't see a point in deprecating this property.
  - touchscreen binding: I kept measure-delay-time and pre-charge-time
    values in hex, since that is being used everywhere and the unit
	is unknown. The values are directly written into HW registers and
	the i.MX6UL TRM does not provide any hints about the unit. I do not
	have an i.MX6UL device with a touchsreen, so I cannot test either.
  - regulator name in DT: I did not rename the regulators to just
    "regulator", since the nodename must be unique.

Greetings,

-- Sebastian

Sebastian Reichel (17):
  dt-bindings: pinctrl: fsl,imx6ul-pinctrl: convert to YAML
  dt-bindings: bus: imx-weim: convert to YAML
  ASoC: dt-bindings: fsl,imx-asrc: convert to YAML
  dt-bindings: input: touchscreen: fsl,imx6ul-tsc convert to YAML
  dt-bindings: soc: imx: fsl,imx-anatop: add binding
  dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add imx6
  dt-bindings: lcdif: Do not require power-domains for i.MX6ULL
  dt-bindings: fsl-imx-sdma: fix HDMI audio index
  ARM: dts: imx6ull: fix pinctrl node name
  ARM: dts: imx6ul: Remove fsl,anatop from usbotg1
  ARM: dts: imx6ul: add missing #thermal-sensor-cells
  ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
  ARM: dts: nxp: imx6ul: fix touchscreen node name
  ARM: dts: nxp: imx: fix weim node name
  dt-bindings: vendor-prefixes: add UNI-T
  dt-bindings: arm: add UNI-T UTi260b
  ARM: dts: imx6ull-uti260b: Add board

 .../devicetree/bindings/arm/fsl.yaml          |   1 +
 .../devicetree/bindings/bus/imx-weim.txt      | 117 ----
 .../bindings/display/fsl,lcdif.yaml           |   8 +-
 .../devicetree/bindings/dma/fsl,imx-sdma.yaml |   3 +-
 .../input/touchscreen/fsl,imx6ul-tsc.yaml     |  97 +++
 .../bindings/input/touchscreen/imx6ul_tsc.txt |  38 --
 .../fsl/fsl,imx-weim-peripherals.yaml         |  36 ++
 .../memory-controllers/fsl/fsl,imx-weim.yaml  | 201 ++++++
 .../mc-peripheral-props.yaml                  |   1 +
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt   |  37 --
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.yaml  | 116 ++++
 .../bindings/soc/imx/fsl,imx-anatop.yaml      | 128 ++++
 .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml  |  18 +-
 .../devicetree/bindings/sound/fsl,asrc.txt    |  80 ---
 .../bindings/sound/fsl,imx-asrc.yaml          | 162 +++++
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm/boot/dts/nxp/imx/Makefile            |   1 +
 arch/arm/boot/dts/nxp/imx/imx1.dtsi           |   2 +-
 arch/arm/boot/dts/nxp/imx/imx27.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx31.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx35.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx51.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi        |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6sl.dtsi         |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6sx.dtsi         |   2 +-
 .../boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi    |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts     |   2 +-
 .../nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi    |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi         |   6 +-
 .../boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi   |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts | 572 ++++++++++++++++++
 arch/arm/boot/dts/nxp/imx/imx6ull.dtsi        |   2 +-
 .../fieldbus/arcx,anybus-controller.txt       |   2 +-
 33 files changed, 1360 insertions(+), 292 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
 delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
 delete mode 100644 Documentation/devicetree/bindings/sound/fsl,asrc.txt
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts

-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:00:52 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:52 +0100
Subject: [PATCH v2 03/17] ASoC: dt-bindings: fsl,imx-asrc: convert to YAML
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-4-sre@kernel.org>

Convert the i.MX ASRC DT binding to YAML.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../devicetree/bindings/sound/fsl,asrc.txt    |  80 ---------
 .../bindings/sound/fsl,imx-asrc.yaml          | 162 ++++++++++++++++++
 2 files changed, 162 insertions(+), 80 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/sound/fsl,asrc.txt
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
deleted file mode 100644
index 998b4c8a7f78..000000000000
--- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-Freescale Asynchronous Sample Rate Converter (ASRC) Controller
-
-The Asynchronous Sample Rate Converter (ASRC) converts the sampling rate of a
-signal associated with an input clock into a signal associated with a different
-output clock. The driver currently works as a Front End of DPCM with other Back
-Ends Audio controller such as ESAI, SSI and SAI. It has three pairs to support
-three substreams within totally 10 channels.
-
-Required properties:
-
-  - compatible		: Compatible list, should contain one of the following
-			  compatibles:
-			  "fsl,imx35-asrc",
-			  "fsl,imx53-asrc",
-			  "fsl,imx8qm-asrc",
-			  "fsl,imx8qxp-asrc",
-
-  - reg			: Offset and length of the register set for the device.
-
-  - interrupts		: Contains the spdif interrupt.
-
-  - dmas		: Generic dma devicetree binding as described in
-			  Documentation/devicetree/bindings/dma/dma.txt.
-
-  - dma-names		: Contains "rxa", "rxb", "rxc", "txa", "txb" and "txc".
-
-  - clocks		: Contains an entry for each entry in clock-names.
-
-  - clock-names		: Contains the following entries
-	"mem"		  Peripheral access clock to access registers.
-	"ipg"		  Peripheral clock to driver module.
-	"asrck_<0-f>"	  Clock sources for input and output clock.
-	"spba"		  The spba clock is required when ASRC is placed as a
-			  bus slave of the Shared Peripheral Bus and when two
-			  or more bus masters (CPU, DMA or DSP) try to access
-			  it. This property is optional depending on the SoC
-			  design.
-
-   - fsl,asrc-rate	: Defines a mutual sample rate used by DPCM Back Ends.
-
-   - fsl,asrc-width	: Defines a mutual sample width used by DPCM Back Ends.
-
-   - fsl,asrc-clk-map   : Defines clock map used in driver. which is required
-			  by imx8qm/imx8qxp platform
-			  <0> - select the map for asrc0 in imx8qm/imx8qxp
-			  <1> - select the map for asrc1 in imx8qm/imx8qxp
-
-Optional properties:
-
-   - big-endian		: If this property is absent, the little endian mode
-			  will be in use as default. Otherwise, the big endian
-			  mode will be in use for all the device registers.
-
-   - fsl,asrc-format	: Defines a mutual sample format used by DPCM Back
-			  Ends, which can replace the fsl,asrc-width.
-			  The value is 2 (S16_LE), or 6 (S24_LE).
-
-Example:
-
-asrc: asrc at 2034000 {
-	compatible = "fsl,imx53-asrc";
-	reg = <0x02034000 0x4000>;
-	interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
-	clocks = <&clks 107>, <&clks 107>, <&clks 0>,
-	       <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
-	       <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
-	       <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
-	       <&clks 107>, <&clks 0>, <&clks 0>;
-	clock-names = "mem", "ipg", "asrck0",
-		"asrck_1", "asrck_2", "asrck_3", "asrck_4",
-		"asrck_5", "asrck_6", "asrck_7", "asrck_8",
-		"asrck_9", "asrck_a", "asrck_b", "asrck_c",
-		"asrck_d", "asrck_e", "asrck_f";
-	dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
-	     <&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
-	dma-names = "rxa", "rxb", "rxc",
-		"txa", "txb", "txc";
-	fsl,asrc-rate  = <48000>;
-	fsl,asrc-width = <16>;
-};
diff --git a/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml
new file mode 100644
index 000000000000..bfef2fcb75b1
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml
@@ -0,0 +1,162 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,imx-asrc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale Asynchronous Sample Rate Converter (ASRC) Controller
+
+description:
+  The Asynchronous Sample Rate Converter (ASRC) converts the sampling rate of
+  a signal associated with an input clock into a signal associated with a
+  different output clock. The driver currently works as a Front End of DPCM
+  with other Back Ends Audio controller such as ESAI, SSI and SAI. It has
+  three pairs to support three substreams within totally 10 channels.
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - fsl,imx35-asrc
+          - fsl,imx53-asrc
+          - fsl,imx8qm-asrc
+          - fsl,imx8qxp-asrc
+      - items:
+          - enum:
+              - fsl,imx6sx-asrc
+              - fsl,imx6ul-asrc
+          - const: fsl,imx53-asrc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  dmas:
+    maxItems: 6
+
+  dma-names:
+    items:
+      - const: rxa
+      - const: rxb
+      - const: rxc
+      - const: txa
+      - const: txb
+      - const: txc
+
+  clocks:
+    maxItems: 19
+
+  clock-names:
+    items:
+      - const: mem
+      - const: ipg
+      - const: asrck_0
+      - const: asrck_1
+      - const: asrck_2
+      - const: asrck_3
+      - const: asrck_4
+      - const: asrck_5
+      - const: asrck_6
+      - const: asrck_7
+      - const: asrck_8
+      - const: asrck_9
+      - const: asrck_a
+      - const: asrck_b
+      - const: asrck_c
+      - const: asrck_d
+      - const: asrck_e
+      - const: asrck_f
+      - const: spba
+
+  fsl,asrc-rate:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: The mutual sample rate used by DPCM Back Ends
+
+  fsl,asrc-width:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: The mutual sample width used by DPCM Back Ends
+    enum: [16, 24]
+
+  fsl,asrc-clk-map:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines clock map used in driver
+      <0> - select the map for asrc0 in imx8qm/imx8qxp
+      <1> - select the map for asrc1 in imx8qm/imx8qxp
+    enum: [0, 1]
+
+  big-endian:
+    type: boolean
+    description:
+      If this property is absent, the little endian mode will be in use as
+      default. Otherwise, the big endian mode will be in use for all the
+      device registers.
+
+  fsl,asrc-format:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines a mutual sample format used by DPCM Back Ends, which can
+      replace the fsl,asrc-width. The value is 2 (S16_LE), or 6 (S24_LE).
+    enum: [2, 6]
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - dmas
+  - dma-names
+  - clocks
+  - clock-names
+  - fsl,asrc-rate
+  - fsl,asrc-width
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx8qm-asrc
+              - fsl,imx8qxp-asrc
+    then:
+      required:
+        - fsl,asrc-clk-map
+    else:
+      properties:
+        fsl,asrc-clk-map: false
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/imx6qdl-clock.h>
+    asrc: asrc at 2034000 {
+        compatible = "fsl,imx53-asrc";
+        reg = <0x02034000 0x4000>;
+        interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX6QDL_CLK_ASRC_IPG>,
+                 <&clks IMX6QDL_CLK_ASRC_MEM>, <&clks 0>,
+                 <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+                 <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+                 <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
+                 <&clks IMX6QDL_CLK_ASRC>, <&clks 0>, <&clks 0>,
+                 <&clks IMX6QDL_CLK_SPBA>;
+        clock-names = "mem", "ipg", "asrck_0",
+                "asrck_1", "asrck_2", "asrck_3", "asrck_4",
+                "asrck_5", "asrck_6", "asrck_7", "asrck_8",
+                "asrck_9", "asrck_a", "asrck_b", "asrck_c",
+                "asrck_d", "asrck_e", "asrck_f", "spba";
+        dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
+               <&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
+        dma-names = "rxa", "rxb", "rxc",
+                    "txa", "txb", "txc";
+        fsl,asrc-rate  = <48000>;
+        fsl,asrc-width = <16>;
+    };
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:00:51 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:51 +0100
Subject: [PATCH v2 02/17] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-3-sre@kernel.org>

Convert the i.MX  Wireless External Interface Module binding to YAML.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../devicetree/bindings/bus/imx-weim.txt      | 117 ----------
 .../fsl/fsl,imx-weim-peripherals.yaml         |  36 ++++
 .../memory-controllers/fsl/fsl,imx-weim.yaml  | 201 ++++++++++++++++++
 .../mc-peripheral-props.yaml                  |   1 +
 .../fieldbus/arcx,anybus-controller.txt       |   2 +-
 5 files changed, 239 insertions(+), 118 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml

diff --git a/Documentation/devicetree/bindings/bus/imx-weim.txt b/Documentation/devicetree/bindings/bus/imx-weim.txt
deleted file mode 100644
index e7f502070d77..000000000000
--- a/Documentation/devicetree/bindings/bus/imx-weim.txt
+++ /dev/null
@@ -1,117 +0,0 @@
-Device tree bindings for i.MX Wireless External Interface Module (WEIM)
-
-The term "wireless" does not imply that the WEIM is literally an interface
-without wires. It simply means that this module was originally designed for
-wireless and mobile applications that use low-power technology.
-
-The actual devices are instantiated from the child nodes of a WEIM node.
-
-Required properties:
-
- - compatible:		Should contain one of the following:
-			  "fsl,imx1-weim"
-			  "fsl,imx27-weim"
-			  "fsl,imx51-weim"
-			  "fsl,imx50-weim"
-			  "fsl,imx6q-weim"
- - reg:			A resource specifier for the register space
-			(see the example below)
- - clocks:		the clock, see the example below.
- - #address-cells:	Must be set to 2 to allow memory address translation
- - #size-cells:		Must be set to 1 to allow CS address passing
- - ranges:		Must be set up to reflect the memory layout with four
-			integer values for each chip-select line in use:
-
-			   <cs-number> 0 <physical address of mapping> <size>
-
-Optional properties:
-
- - fsl,weim-cs-gpr:	For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
-			devices, it should be the phandle to the system General
-			Purpose Register controller that contains WEIM CS GPR
-			register, e.g. IOMUXC_GPR1 on i.MX6Q.  IOMUXC_GPR1[11:0]
-			should be set up as one of the following 4 possible
-			values depending on the CS space configuration.
-
-			IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
-			---------------------------------------------
-				05	    128M     0M     0M     0M
-				033          64M    64M     0M     0M
-				0113         64M    32M    32M     0M
-				01111        32M    32M    32M    32M
-
-			In case that the property is absent, the reset value or
-			what bootloader sets up in IOMUXC_GPR1[11:0] will be
-			used.
-
- - fsl,burst-clk-enable	For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
-			devices, the presence of this property indicates that
-			the weim bus should operate in Burst Clock Mode.
-
- - fsl,continuous-burst-clk	Make Burst Clock to output continuous clock.
-			Without this option Burst Clock will output clock
-			only when necessary. This takes effect only if
-			"fsl,burst-clk-enable" is set.
-
-Timing property for child nodes. It is mandatory, not optional.
-
- - fsl,weim-cs-timing:	The timing array, contains timing values for the
-			child node. We get the CS indexes from the address
-			ranges in the child node's "reg" property.
-			The number of registers depends on the selected chip:
-			For i.MX1, i.MX21 ("fsl,imx1-weim") there are two
-			registers: CSxU, CSxL.
-			For i.MX25, i.MX27, i.MX31 and i.MX35 ("fsl,imx27-weim")
-			there are three registers: CSCRxU, CSCRxL, CSCRxA.
-			For i.MX50, i.MX53 ("fsl,imx50-weim"),
-			i.MX51 ("fsl,imx51-weim") and i.MX6Q ("fsl,imx6q-weim")
-			there are six registers: CSxGCR1, CSxGCR2, CSxRCR1,
-			CSxRCR2, CSxWCR1, CSxWCR2.
-
-Example for an imx6q-sabreauto board, the NOR flash connected to the WEIM:
-
-	weim: weim at 21b8000 {
-		compatible = "fsl,imx6q-weim";
-		reg = <0x021b8000 0x4000>;
-		clocks = <&clks 196>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x08000000>;
-		fsl,weim-cs-gpr = <&gpr>;
-
-		nor at 0,0 {
-			compatible = "cfi-flash";
-			reg = <0 0 0x02000000>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			bank-width = <2>;
-			fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
-					0x0000c000 0x1404a38e 0x00000000>;
-		};
-	};
-
-Example for an imx6q-based board, a multi-chipselect device connected to WEIM:
-
-In this case, both chip select 0 and 1 will be configured with the same timing
-array values.
-
-	weim: weim at 21b8000 {
-		compatible = "fsl,imx6q-weim";
-		reg = <0x021b8000 0x4000>;
-		clocks = <&clks 196>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x02000000
-			  1 0 0x0a000000 0x02000000
-			  2 0 0x0c000000 0x02000000
-			  3 0 0x0e000000 0x02000000>;
-		fsl,weim-cs-gpr = <&gpr>;
-
-		acme at 0 {
-			compatible = "acme,whatever";
-			reg = <0 0 0x100>, <0 0x400000 0x800>,
-				<1 0x400000 0x800>;
-			fsl,weim-cs-timing = <0x024400b1 0x00001010 0x20081100
-				0x00000000 0xa0000240 0x00000000>;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
new file mode 100644
index 000000000000..86d7e5011107
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX WEIM Bus Peripheral Nodes
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+description:
+  This binding is meant for the child nodes of the WEIM node. The node
+  represents any device connected to the WEIM bus. It may be a Flash chip,
+  RAM chip or Ethernet controller, etc. These properties are meant for
+  configuring the WEIM settings/timings and will accompany the bindings
+  supported by the respective device.
+
+properties:
+  reg: true
+
+  fsl,weim-cs-timing:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Timing values for the child node.
+    minItems: 2
+    maxItems: 6
+
+required:
+  - compatible
+  - reg
+  - fsl,weim-cs-timing
+
+# the WEIM child will have its own native properties
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
new file mode 100644
index 000000000000..a2c96da683bf
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
@@ -0,0 +1,201 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,imx-weim.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX Wireless External Interface Module (WEIM)
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+description:
+  The term "wireless" does not imply that the WEIM is literally an interface
+  without wires. It simply means that this module was originally designed for
+  wireless and mobile applications that use low-power technology. The actual
+  devices are instantiated from the child nodes of a WEIM node.
+
+properties:
+  $nodename:
+    pattern: "^memory-controller@[0-9a-f]+$"
+
+  compatible:
+    oneOf:
+      - enum:
+          - fsl,imx1-weim
+          - fsl,imx27-weim
+          - fsl,imx50-weim
+          - fsl,imx51-weim
+          - fsl,imx6q-weim
+      - items:
+          - enum:
+              - fsl,imx31-weim
+              - fsl,imx35-weim
+          - const: fsl,imx27-weim
+      - items:
+          - enum:
+              - fsl,imx6sx-weim
+              - fsl,imx6ul-weim
+          - const: fsl,imx6q-weim
+
+  '#address-cells':
+    const: 2
+
+  '#size-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  ranges: true
+
+  fsl,weim-cs-gpr:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Phandle to the system General Purpose Register controller that contains
+      WEIM CS GPR register, e.g. IOMUXC_GPR1 on i.MX6Q. IOMUXC_GPR1[11:0]
+      should be set up as one of the following 4 possible values depending on
+      the CS space configuration.
+
+      IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
+      ---------------------------------------------
+              05          128M     0M     0M     0M
+              033          64M    64M     0M     0M
+              0113         64M    32M    32M     0M
+              01111        32M    32M    32M    32M
+
+      In case that the property is absent, the reset value or what bootloader
+      sets up in IOMUXC_GPR1[11:0] will be used.
+
+  fsl,burst-clk-enable:
+    type: boolean
+    description:
+      The presence of this property indicates that the weim bus should operate
+      in Burst Clock Mode.
+
+  fsl,continuous-burst-clk:
+    type: boolean
+    description:
+      Make Burst Clock to output continuous clock. Without this option Burst
+      Clock will output clock only when necessary.
+
+patternProperties:
+  "^.*@[0-7],[0-9a-f]+$":
+    type: object
+    description: Devices attached to chip selects are represented as subnodes.
+    $ref: fsl,imx-weim-peripherals.yaml
+    additionalProperties: true
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#address-cells'
+  - '#size-cells'
+  - ranges
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          not:
+            contains:
+              enum:
+                - fsl,imx50-weim
+                - fsl,imx6q-weim
+    then:
+      properties:
+        fsl,weim-cs-gpr: false
+        fsl,burst-clk-enable: false
+  - if:
+      properties:
+        fsl,burst-clk-enable: false
+    then:
+      properties:
+        fsl,continuous-burst-clk: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx1-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSxU
+                  - description: CSxL
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx27-weim
+              - fsl,imx31-weim
+              - fsl,imx35-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSCRxU
+                  - description: CSCRxL
+                  - description: CSCRxA
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx50-weim
+              - fsl,imx51-weim
+              - fsl,imx6q-weim
+              - fsl,imx6sx-weim
+              - fsl,imx6ul-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSxGCR1
+                  - description: CSxGCR2
+                  - description: CSxRCR1
+                  - description: CSxRCR2
+                  - description: CSxWCR1
+                  - description: CSxWCR2
+
+additionalProperties: false
+
+examples:
+  - |
+    memory-controller at 21b8000 {
+        compatible = "fsl,imx6q-weim";
+        reg = <0x021b8000 0x4000>;
+        clocks = <&clks 196>;
+        #address-cells = <2>;
+        #size-cells = <1>;
+        ranges = <0 0 0x08000000 0x08000000>;
+        fsl,weim-cs-gpr = <&gpr>;
+
+        flash at 0,0 {
+            compatible = "cfi-flash";
+            reg = <0 0 0x02000000>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            bank-width = <2>;
+            fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
+                                  0x0000c000 0x1404a38e 0x00000000>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml b/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml
index 8d9dae15ade0..00deeb09f87d 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml
@@ -37,5 +37,6 @@ allOf:
   - $ref: ingenic,nemc-peripherals.yaml#
   - $ref: intel,ixp4xx-expansion-peripheral-props.yaml#
   - $ref: ti,gpmc-child.yaml#
+  - $ref: fsl/fsl,imx-weim-peripherals.yaml
 
 additionalProperties: true
diff --git a/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt b/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt
index b1f9474f36d5..f34a95611645 100644
--- a/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt
+++ b/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt
@@ -48,7 +48,7 @@ Example of usage:
 -----------------
 
 This example places the bridge on top of the i.MX WEIM parallel bus, see:
-Documentation/devicetree/bindings/bus/imx-weim.txt
+Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
 
 &weim {
 	controller at 0,0 {
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:00:50 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:50 +0100
Subject: [PATCH v2 01/17] dt-bindings: pinctrl: fsl,imx6ul-pinctrl: convert to YAML
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-2-sre@kernel.org>

Convert i.MX6UL pinctrl bindings to YAML.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt   |  37 ------
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.yaml  | 116 ++++++++++++++++++
 2 files changed, 116 insertions(+), 37 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
deleted file mode 100644
index 7ca4f6118d9a..000000000000
--- a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-* Freescale i.MX6 UltraLite IOMUX Controller
-
-Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
-and usage.
-
-Required properties:
-- compatible: "fsl,imx6ul-iomuxc" for main IOMUX controller or
-  "fsl,imx6ull-iomuxc-snvs" for i.MX 6ULL's SNVS IOMUX controller.
-- fsl,pins: each entry consists of 6 integers and represents the mux and config
-  setting for one pin.  The first 5 integers <mux_reg conf_reg input_reg mux_val
-  input_val> are specified using a PIN_FUNC_ID macro, which can be found in
-  imx6ul-pinfunc.h under device tree source folder.  The last integer CONFIG is
-  the pad setting value like pull-up on this pin.  Please refer to i.MX6 UltraLite
-  Reference Manual for detailed CONFIG settings.
-
-CONFIG bits definition:
-PAD_CTL_HYS                     (1 << 16)
-PAD_CTL_PUS_100K_DOWN           (0 << 14)
-PAD_CTL_PUS_47K_UP              (1 << 14)
-PAD_CTL_PUS_100K_UP             (2 << 14)
-PAD_CTL_PUS_22K_UP              (3 << 14)
-PAD_CTL_PUE                     (1 << 13)
-PAD_CTL_PKE                     (1 << 12)
-PAD_CTL_ODE                     (1 << 11)
-PAD_CTL_SPEED_LOW               (0 << 6)
-PAD_CTL_SPEED_MED               (1 << 6)
-PAD_CTL_SPEED_HIGH              (3 << 6)
-PAD_CTL_DSE_DISABLE             (0 << 3)
-PAD_CTL_DSE_260ohm              (1 << 3)
-PAD_CTL_DSE_130ohm              (2 << 3)
-PAD_CTL_DSE_87ohm               (3 << 3)
-PAD_CTL_DSE_65ohm               (4 << 3)
-PAD_CTL_DSE_52ohm               (5 << 3)
-PAD_CTL_DSE_43ohm               (6 << 3)
-PAD_CTL_DSE_37ohm               (7 << 3)
-PAD_CTL_SRE_FAST                (1 << 0)
-PAD_CTL_SRE_SLOW                (0 << 0)
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
new file mode 100644
index 000000000000..906b264a9e3c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
@@ -0,0 +1,116 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/fsl,imx6ul-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale IMX6UL IOMUX Controller
+
+maintainers:
+  - Dong Aisheng <aisheng.dong at nxp.com>
+
+description:
+  Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
+  for common binding part and usage.
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx6ul-iomuxc
+      - fsl,imx6ull-iomuxc-snvs
+
+  reg:
+    maxItems: 1
+
+# Client device subnode's properties
+patternProperties:
+  'grp$':
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+
+    properties:
+      fsl,pins:
+        description:
+          each entry consists of 6 integers and represents the mux and config
+          setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
+          mux_val input_val> are specified using a PIN_FUNC_ID macro, which can
+          be found in <arch/arm/boot/dts/imx6ul-pinfunc.h>. The last integer
+          CONFIG is the pad setting value like pull-up on this pin. Please
+          refer to i.MX6UL Reference Manual for detailed CONFIG settings.
+        $ref: /schemas/types.yaml#/definitions/uint32-matrix
+        items:
+          items:
+            - description: |
+                "mux_reg" indicates the offset of mux register.
+            - description: |
+                "conf_reg" indicates the offset of pad configuration register.
+            - description: |
+                "input_reg" indicates the offset of select input register.
+            - description: |
+                "mux_val" indicates the mux value to be applied.
+            - description: |
+                "input_val" indicates the select input value to be applied.
+            - description: |
+                "pad_setting" indicates the pad configuration value to be applied:
+                  PAD_CTL_HYS                     (1 << 16)
+                  PAD_CTL_PUS_100K_DOWN           (0 << 14)
+                  PAD_CTL_PUS_47K_UP              (1 << 14)
+                  PAD_CTL_PUS_100K_UP             (2 << 14)
+                  PAD_CTL_PUS_22K_UP              (3 << 14)
+                  PAD_CTL_PUE                     (1 << 13)
+                  PAD_CTL_PKE                     (1 << 12)
+                  PAD_CTL_ODE                     (1 << 11)
+                  PAD_CTL_SPEED_LOW               (0 << 6)
+                  PAD_CTL_SPEED_MED               (1 << 6)
+                  PAD_CTL_SPEED_HIGH              (3 << 6)
+                  PAD_CTL_DSE_DISABLE             (0 << 3)
+                  PAD_CTL_DSE_260ohm              (1 << 3)
+                  PAD_CTL_DSE_130ohm              (2 << 3)
+                  PAD_CTL_DSE_87ohm               (3 << 3)
+                  PAD_CTL_DSE_65ohm               (4 << 3)
+                  PAD_CTL_DSE_52ohm               (5 << 3)
+                  PAD_CTL_DSE_43ohm               (6 << 3)
+                  PAD_CTL_DSE_37ohm               (7 << 3)
+                  PAD_CTL_SRE_FAST                (1 << 0)
+                  PAD_CTL_SRE_SLOW                (0 << 0)
+
+    required:
+      - fsl,pins
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    iomuxc: pinctrl at 20e0000 {
+      compatible = "fsl,imx6ul-iomuxc";
+      reg = <0x020e0000 0x4000>;
+
+      mux_uart: uartgrp {
+        fsl,pins = <
+          0x0084 0x0310 0x0000 0 0 0x1b0b1
+          0x0088 0x0314 0x0624 0 3 0x1b0b1
+        >;
+      };
+    };
+  - |
+    iomuxc_snvs: pinctrl at 2290000 {
+      compatible = "fsl,imx6ull-iomuxc-snvs";
+      reg = <0x02290000 0x4000>;
+
+      pinctrl_snvs_usbc_det: snvsusbcdetgrp {
+        fsl,pins = <
+          0x0010 0x0054 0x0000 0x5 0x0 0x130b0
+        >;
+      };
+    };
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:00:58 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:58 +0100
Subject: [PATCH v2 09/17] ARM: dts: imx6ull: fix pinctrl node name
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-10-sre@kernel.org>

pinctrl node name must be either pinctrl or pinmux.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ull.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
index 2bccd45e9fc2..8a1776067ecc 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
@@ -75,7 +75,7 @@ rngb: rng at 2284000 {
 				clocks = <&clks IMX6UL_CLK_DUMMY>;
 			};
 
-			iomuxc_snvs: iomuxc-snvs at 2290000 {
+			iomuxc_snvs: pinctrl at 2290000 {
 				compatible = "fsl,imx6ull-iomuxc-snvs";
 				reg = <0x02290000 0x4000>;
 			};
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:00:56 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:56 +0100
Subject: [PATCH v2 07/17] dt-bindings: lcdif: Do not require power-domains for i.MX6ULL
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-8-sre@kernel.org>

i.MX6UL(L) uses "fsl,imx6sx-lcdif" as fallback compatible string,
but has only very lightweight DISPLAY power domain. Its DISPLAY
power domain is not supported by the binding / Linux kernel at
the moment. Since the current setup is working, let's remove the
power-domain from being required for that platform to fix the warning
printed by CHECK_DTBS=y.

Fixes: f62678a77d58 ("dt-bindings: mxsfb: Document i.MX8M/i.MX6SX/i.MX6SL power-domains property")
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/display/fsl,lcdif.yaml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
index 1c2be8d6f633..0681fc49aa1b 100644
--- a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
+++ b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
@@ -120,13 +120,19 @@ allOf:
           maxItems: 1
         clock-names:
           maxItems: 1
+  - if:
+      properties:
+        compatible:
+          const: fsl,imx6sx-lcdif
+    then:
+      required:
+        - power-domains
   - if:
       properties:
         compatible:
           contains:
             enum:
               - fsl,imx6sl-lcdif
-              - fsl,imx6sx-lcdif
               - fsl,imx8mm-lcdif
               - fsl,imx8mn-lcdif
               - fsl,imx8mp-lcdif
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:01:02 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:01:02 +0100
Subject: [PATCH v2 13/17] ARM: dts: nxp: imx6ul: fix touchscreen node name
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-14-sre@kernel.org>

The nodename for a touchscreen should be touchscreen
instead of tsc.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index 45b7605ac381..8aa365f837ca 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -370,7 +370,7 @@ asrc: asrc at 2034000 {
 				};
 			};
 
-			tsc: tsc at 2040000 {
+			tsc: touchscreen at 2040000 {
 				compatible = "fsl,imx6ul-tsc";
 				reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
 				interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:01:03 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:01:03 +0100
Subject: [PATCH v2 14/17] ARM: dts: nxp: imx: fix weim node name
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-15-sre@kernel.org>

Fix WEIM node name in all i.MX SoC DT files.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx1.dtsi    | 2 +-
 arch/arm/boot/dts/nxp/imx/imx27.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx31.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx35.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx51.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6sl.dtsi  | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6sx.dtsi  | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi  | 2 +-
 9 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx1.dtsi b/arch/arm/boot/dts/nxp/imx/imx1.dtsi
index 1ac10965fdfd..389ecb1ebf8f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx1.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx1.dtsi
@@ -251,7 +251,7 @@ gpio4: gpio at 21c300 {
 			};
 		};
 
-		weim: weim at 220000 {
+		weim: memory-controller at 220000 {
 			#address-cells = <2>;
 			#size-cells = <1>;
 			compatible = "fsl,imx1-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx27.dtsi b/arch/arm/boot/dts/nxp/imx/imx27.dtsi
index ec472695c71e..ec3ccc8f4095 100644
--- a/arch/arm/boot/dts/nxp/imx/imx27.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx27.dtsi
@@ -568,7 +568,7 @@ nfc: nand-controller at d8000000 {
 			status = "disabled";
 		};
 
-		weim: weim at d8002000 {
+		weim: memory-controller at d8002000 {
 			#address-cells = <2>;
 			#size-cells = <1>;
 			compatible = "fsl,imx27-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx31.dtsi b/arch/arm/boot/dts/nxp/imx/imx31.dtsi
index e1ae7c175f7d..00006c90d9a7 100644
--- a/arch/arm/boot/dts/nxp/imx/imx31.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx31.dtsi
@@ -352,7 +352,7 @@ nfc: nand at b8000000 {
 				status = "disabled";
 			};
 
-			weim: weim at b8002000 {
+			weim: memory-controller at b8002000 {
 				compatible = "fsl,imx31-weim", "fsl,imx27-weim";
 				reg = <0xb8002000 0x1000>;
 				clocks = <&clks 56>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx35.dtsi b/arch/arm/boot/dts/nxp/imx/imx35.dtsi
index 2d20e5541acc..442dc15677b8 100644
--- a/arch/arm/boot/dts/nxp/imx/imx35.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx35.dtsi
@@ -374,7 +374,7 @@ nfc: nand at bb000000 {
 				status = "disabled";
 			};
 
-			weim: weim at b8002000 {
+			weim: memory-controller at b8002000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				clocks = <&clks 0>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx51.dtsi b/arch/arm/boot/dts/nxp/imx/imx51.dtsi
index c96d6311dfa7..4efce49022e4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx51.dtsi
@@ -578,7 +578,7 @@ m4if: m4if at 83fd8000 {
 				reg = <0x83fd8000 0x1000>;
 			};
 
-			weim: weim at 83fda000 {
+			weim: memory-controller at 83fda000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx51-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
index 81142c523fa8..8431b8a994f4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
@@ -1158,7 +1158,7 @@ mmdc1: memory-controller at 21b4000 { /* MMDC1 */
 				status = "disabled";
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx6q-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
index 28111efb19a6..6aa61235e39e 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
@@ -949,7 +949,7 @@ rngb: rngb at 21b4000 {
 				clocks = <&clks IMX6SL_CLK_DUMMY>;
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				reg = <0x021b8000 0x4000>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
index df3a375f0a3e..0de359d62a47 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
@@ -1107,7 +1107,7 @@ fec2: ethernet at 21b4000 {
 				status = "disabled";
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx6sx-weim", "fsl,imx6q-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index 8aa365f837ca..aeb7e07fd309 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -975,7 +975,7 @@ memory-controller at 21b0000 {
 				clocks = <&clks IMX6UL_CLK_MMDC_P0_IPG>;
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx6ul-weim", "fsl,imx6q-weim";
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:01:01 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:01:01 +0100
Subject: [PATCH v2 12/17] ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-13-sre@kernel.org>

Replace all "xnur-gpio" with "xnur-gpios" in the
i.MX6UL(L) Touchscreen node.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi          | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts                | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi         | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
index 2ac40d69425b..f10f0525490b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
@@ -321,7 +321,7 @@ &snvs_pwrkey {
 &tsc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_tsc>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 	measure-delay-time = <0xffff>;
 	pre-charge-time = <0xfff>;
 	status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts b/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
index 875ae699c5cb..2ca18f3dad0a 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
@@ -203,7 +203,7 @@ &pwm8 {
 &tsc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_tsc>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 };
 
 &sai2 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
index 18cac19aa9b0..af337f18a266 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
@@ -156,7 +156,7 @@ &snvs_pwrkey {
 &tsc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_tsc>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 	measure-delay-time = <0xffff>;
 	pre-charge-time = <0xffff>;
 	status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
index 830b5a5064f2..6d2163250b5d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
@@ -273,7 +273,7 @@ &tsc {
 	pinctrl-names = "default";
 	pre-charge-time = <0xfff>;
 	touchscreen-average-samples = <32>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 };
 
 /* DHCOM UART1 */
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:00:59 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:59 +0100
Subject: [PATCH v2 10/17] ARM: dts: imx6ul: Remove fsl,anatop from usbotg1
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-11-sre@kernel.org>

fsl,anatop should only be added to the usbphy nodes.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index a27a7554c2e7..9eb4eee0c272 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -855,7 +855,6 @@ usbotg1: usb at 2184000 {
 				clocks = <&clks IMX6UL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
-				fsl,anatop = <&anatop>;
 				ahb-burst-config = <0x0>;
 				tx-burst-size-dword = <0x10>;
 				rx-burst-size-dword = <0x10>;
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:01:00 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:01:00 +0100
Subject: [PATCH v2 11/17] ARM: dts: imx6ul: add missing #thermal-sensor-cells
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-12-sre@kernel.org>

Fix the following warning found via CHECK_DTBS:

tempmon: '#thermal-sensor-cells' is a required property

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index 9eb4eee0c272..45b7605ac381 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -638,6 +638,7 @@ tempmon: tempmon {
 					nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
 					nvmem-cell-names = "calib", "temp_grade";
 					clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+					#thermal-sensor-cells = <0>;
 				};
 			};
 
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:01:05 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:01:05 +0100
Subject: [PATCH v2 16/17] dt-bindings: arm: add UNI-T UTi260b
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-17-sre@kernel.org>

Add compatible value for i.MX6ULL based UNI-T
UTi260b thermal camera.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 228dcc5c7d6f..7b65f9c9c1a5 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -708,6 +708,7 @@ properties:
               - toradex,colibri-imx6ull      # Colibri iMX6ULL Modules
               - toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module
               - toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Modules
+              - uni-t,uti260b             # UNI-T UTi260B Thermal Camera
           - const: fsl,imx6ull
 
       - description: i.MX6ULL Armadeus Systems OPOS6ULDev Board
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:00:57 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:57 +0100
Subject: [PATCH v2 08/17] dt-bindings: fsl-imx-sdma: fix HDMI audio index
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-9-sre@kernel.org>

HDMI Audio has been added to the DT binding documentation with an
incorrect index. DT and the driver use index 26. This happened,
because the binding is missing MULTI_SAI type, which is using
index 25.

Reported-by: Michael Yackavage <michaely at ips-yes.com>
Fixes: 7bdbd87d4008 ("dt-bindings: fsl-imx-sdma: Convert imx sdma to DT schema")
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml b/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
index b95dd8db5a30..37135fa024f9 100644
--- a/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
+++ b/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
@@ -92,7 +92,8 @@ properties:
               description: needs firmware more than ver 2
           - Shared ASRC: 23
           - SAI: 24
-          - HDMI Audio: 25
+          - Multi SAI: 25
+          - HDMI Audio: 26
 
        The third cell: transfer priority ID
          enum:
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:00:54 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:54 +0100
Subject: [PATCH v2 05/17] dt-bindings: soc: imx: fsl,imx-anatop: add binding
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-6-sre@kernel.org>

Add missing binding for i.MX anatop syscon.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/soc/imx/fsl,imx-anatop.yaml      | 128 ++++++++++++++++++
 1 file changed, 128 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
new file mode 100644
index 000000000000..5a59e3470510
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
@@ -0,0 +1,128 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/imx/fsl,imx-anatop.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ANATOP register
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - fsl,imx6sl-anatop
+              - fsl,imx6sll-anatop
+              - fsl,imx6sx-anatop
+              - fsl,imx6ul-anatop
+              - fsl,imx7d-anatop
+          - const: fsl,imx6q-anatop
+          - const: syscon
+          - const: simple-mfd
+      - items:
+          - const: fsl,imx6q-anatop
+          - const: syscon
+          - const: simple-mfd
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Temperature sensor event
+      - description: Brown-out event on either of the support regulators
+      - description: Brown-out event on either the core, gpu or soc regulators
+
+  tempmon:
+    type: object
+    unevaluatedProperties: false
+    $ref: /schemas/thermal/imx-thermal.yaml
+
+patternProperties:
+  "regulator-((3p0)|(vddcore)|(vddsoc))$":
+    type: object
+    unevaluatedProperties: false
+    $ref: /schemas/regulator/anatop-regulator.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx6ul-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    anatop: anatop at 20c8000 {
+        compatible = "fsl,imx6ul-anatop", "fsl,imx6q-anatop",
+                     "syscon", "simple-mfd";
+        reg = <0x020c8000 0x1000>;
+        interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+
+        reg_3p0: regulator-3p0 {
+            compatible = "fsl,anatop-regulator";
+            regulator-name = "vdd3p0";
+            regulator-min-microvolt = <2625000>;
+            regulator-max-microvolt = <3400000>;
+            anatop-reg-offset = <0x120>;
+            anatop-vol-bit-shift = <8>;
+            anatop-vol-bit-width = <5>;
+            anatop-min-bit-val = <0>;
+            anatop-min-voltage = <2625000>;
+            anatop-max-voltage = <3400000>;
+            anatop-enable-bit = <0>;
+        };
+
+        reg_arm: regulator-vddcore {
+            compatible = "fsl,anatop-regulator";
+            regulator-name = "cpu";
+            regulator-min-microvolt = <725000>;
+            regulator-max-microvolt = <1450000>;
+            regulator-always-on;
+            anatop-reg-offset = <0x140>;
+            anatop-vol-bit-shift = <0>;
+            anatop-vol-bit-width = <5>;
+            anatop-delay-reg-offset = <0x170>;
+            anatop-delay-bit-shift = <24>;
+            anatop-delay-bit-width = <2>;
+            anatop-min-bit-val = <1>;
+            anatop-min-voltage = <725000>;
+            anatop-max-voltage = <1450000>;
+        };
+
+        reg_soc: regulator-vddsoc {
+            compatible = "fsl,anatop-regulator";
+            regulator-name = "vddsoc";
+            regulator-min-microvolt = <725000>;
+            regulator-max-microvolt = <1450000>;
+            regulator-always-on;
+            anatop-reg-offset = <0x140>;
+            anatop-vol-bit-shift = <18>;
+            anatop-vol-bit-width = <5>;
+            anatop-delay-reg-offset = <0x170>;
+            anatop-delay-bit-shift = <28>;
+            anatop-delay-bit-width = <2>;
+            anatop-min-bit-val = <1>;
+            anatop-min-voltage = <725000>;
+            anatop-max-voltage = <1450000>;
+        };
+
+        tempmon: tempmon {
+            compatible = "fsl,imx6ul-tempmon", "fsl,imx6sx-tempmon";
+            interrupt-parent = <&gpc>;
+            interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+            fsl,tempmon = <&anatop>;
+            nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
+            nvmem-cell-names = "calib", "temp_grade";
+            clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+            #thermal-sensor-cells = <0>;
+        };
+    };
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:00:55 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:00:55 +0100
Subject: [PATCH v2 06/17] dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add imx6
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-7-sre@kernel.org>

Add compatibles used by different i.MX6 variants to the i.MX IOMUX
Controller GPR binding.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml   | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
index 1da1b758b4ae..8451cb4dd87c 100644
--- a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
@@ -17,7 +17,23 @@ properties:
   compatible:
     oneOf:
       - items:
-          - const: fsl,imx8mq-iomuxc-gpr
+          - enum:
+              - fsl,imx6q-iomuxc-gpr
+              - fsl,imx8mq-iomuxc-gpr
+          - const: syscon
+          - const: simple-mfd
+      - items:
+          - enum:
+              - fsl,imx6sl-iomuxc-gpr
+              - fsl,imx6sll-iomuxc-gpr
+              - fsl,imx6ul-iomuxc-gpr
+          - const: fsl,imx6q-iomuxc-gpr
+          - const: syscon
+      - items:
+          - enum:
+              - fsl,imx6sx-iomuxc-gpr
+              - fsl,imx7d-iomuxc-gpr
+          - const: fsl,imx6q-iomuxc-gpr
           - const: syscon
           - const: simple-mfd
       - items:
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:01:04 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:01:04 +0100
Subject: [PATCH v2 15/17] dt-bindings: vendor-prefixes: add UNI-T
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-16-sre@kernel.org>

Uni-Trend Technology is a manufacturer of measurement
and testing tools.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre 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 1a0dc04f1db4..e945e76696c2 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1484,6 +1484,8 @@ patternProperties:
     description: Ufi Space Co., Ltd.
   "^ugoos,.*":
     description: Ugoos Industrial Co., Ltd.
+  "^uni-t,.*":
+    description: Uni-Trend Technology (China) Co., Ltd.
   "^uniwest,.*":
     description: United Western Technologies Corp (UniWest)
   "^upisemi,.*":
-- 
2.43.0



From sre at kernel.org  Mon Feb 12 17:01:06 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:01:06 +0100
Subject: [PATCH v2 17/17] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <20240213010347.1075251-18-sre@kernel.org>

Add UNI-T UTi260b thermal camera board.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/Makefile            |   1 +
 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts | 572 ++++++++++++++++++
 2 files changed, 573 insertions(+)
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts

diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile
index a724d1a7a9a0..47350cf3ddeb 100644
--- a/arch/arm/boot/dts/nxp/imx/Makefile
+++ b/arch/arm/boot/dts/nxp/imx/Makefile
@@ -349,6 +349,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
 	imx6ull-tarragon-slavext.dtb \
 	imx6ull-tqma6ull2-mba6ulx.dtb \
 	imx6ull-tqma6ull2l-mba6ulx.dtb \
+	imx6ull-uti260b.dtb \
 	imx6ulz-14x14-evk.dtb \
 	imx6ulz-bsh-smm-m2.dtb
 dtb-$(CONFIG_SOC_IMX7D) += \
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
new file mode 100644
index 000000000000..2c0972145c79
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
@@ -0,0 +1,572 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright (C) 2022-2024 Sebastian Reichel <sre at kernel.org>
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/clock/imx6ul-clock.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "UNI-T UTi260B Thermal Camera";
+	compatible = "uni-t,uti260b", "fsl,imx6ull";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_led_ctrl>;
+
+		led {
+			color = <LED_COLOR_ID_WHITE>;
+			function = LED_FUNCTION_FLASH;
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_gpio_keys>;
+		autorepeat;
+
+		up-key {
+			label = "Up";
+			gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_UP>;
+		};
+
+		down-key {
+			label = "Down";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_DOWN>;
+		};
+
+		left-key {
+			label = "Left";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_LEFT>;
+		};
+
+		right-key {
+			label = "Right";
+			gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RIGHT>;
+		};
+
+		ok-key {
+			label = "Ok";
+			gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_ENTER>;
+		};
+
+		return-key {
+			label = "Return";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_ESC>;
+		};
+
+		play-key {
+			label = "Media";
+			gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_MEDIA>;
+		};
+
+		trigger-key {
+			label = "Trigger";
+			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_TRIGGER>;
+		};
+
+		power-key {
+			label = "Power";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+
+		light-key {
+			label = "Light";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_LIGHTS_TOGGLE>;
+		};
+	};
+
+	panel_backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+		enable-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_backlight_enable>;
+		power-supply = <&reg_vsd>;
+		pwms = <&pwm1 0 50000 0>;
+	};
+
+	reg_vsd: regulator-vsd {
+		compatible = "regulator-fixed";
+		regulator-name = "VSD_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_vref: regulator-vref-4v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "VREF_4V2";
+		regulator-min-microvolt = <4200000>;
+		regulator-max-microvolt = <4200000>;
+	};
+
+	tp5000: charger {
+		compatible = "gpio-charger";
+		charger-type = "usb-sdp";
+		gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_charger_stat1>;
+	};
+
+	battery: battery {
+		compatible = "simple-battery";
+		/* generic 26650 battery */
+		device-chemistry = "lithium-ion";
+		charge-full-design-microamp-hours = <5000000>;
+		voltage-max-design-microvolt = <4200000>;
+		voltage-min-design-microvolt = <3300000>;
+	};
+
+	fuel-gauge {
+		compatible = "adc-battery";
+		charged-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		io-channel-names = "voltage";
+		io-channels = <&adc1 7>;
+		monitored-battery = <&battery>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_charger_stat2>;
+		power-supplies = <&tp5000>;
+	};
+
+	poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_poweroff>;
+	};
+};
+
+&gpio1 {
+	ir-reset-hog {
+		gpio-hog;
+		gpios = <3 GPIO_ACTIVE_LOW>;
+		line-name = "ir-reset-gpio";
+		output-low;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_ir_reset>;
+	};
+};
+
+&gpio2 {
+	/* configuring this to output-high results in poweroff */
+	power-en-hog {
+		gpio-hog;
+		gpios = <6 GPIO_ACTIVE_HIGH>;
+		line-name = "power-en-gpio";
+		output-low;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_poweroff2>;
+	};
+};
+
+&ecspi3 {
+	cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_spi3>, <&mux_spi3_cs>;
+	status = "okay";
+
+	panel at 0 {
+		compatible = "inanbo,t28cp45tn89-v17";
+		reg = <0>;
+		backlight = <&panel_backlight>;
+		power-supply = <&reg_vsd>;
+		spi-cpha;
+		spi-cpol;
+		spi-max-frequency = <1000000>;
+		spi-rx-bus-width = <0>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&display_out>;
+			};
+		};
+	};
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_uart>;
+	status = "okay";
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_pwm>;
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_i2c1>;
+	status = "okay";
+
+	camera at 21 {
+		compatible = "galaxycore,gc0308";
+		reg = <0x21>;
+		clocks = <&clks IMX6UL_CLK_CSI>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_gc0308>;
+		powerdown-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+		vdd28-supply = <&reg_vsd>;
+
+		port {
+			gc0308_to_parallel: endpoint {
+				remote-endpoint = <&parallel_from_gc0308>;
+				bus-width = <8>;
+				data-shift = <2>; /* lines 9:2 are used */
+				hsync-active = <1>; /* active high */
+				vsync-active = <1>; /* active high */
+				data-active = <1>; /* active high */
+				pclk-sample = <1>; /* sample on rising edge */
+			};
+		};
+	};
+};
+
+&csi {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_csi>;
+
+	port {
+		parallel_from_gc0308: endpoint {
+			remote-endpoint = <&gc0308_to_parallel>;
+		};
+	};
+};
+
+&i2c2 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_i2c2>;
+	status = "okay";
+
+	rtc at 51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&lcdif {
+	assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_lcd_data>, <&mux_lcd_ctrl>;
+	status = "okay";
+
+	port {
+		display_out: endpoint {
+			remote-endpoint = <&panel_in>;
+		};
+	};
+};
+
+&usdhc1 {
+	/* MicroSD */
+	cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+	keep-power-in-suspend;
+	no-1-8-v;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&mux_sdhc1>, <&mux_sdhc1_cd>;
+	pinctrl-1 = <&mux_sdhc1_100mhz>, <&mux_sdhc1_cd>;
+	pinctrl-2 = <&mux_sdhc1_200mhz>, <&mux_sdhc1_cd>;
+	wakeup-source;
+	vmmc-supply = <&reg_vsd>;
+	status = "okay";
+};
+
+&usdhc2 {
+	/* eMMC */
+	keep-power-in-suspend;
+	no-1-8-v;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_sdhc2>;
+	wakeup-source;
+	status = "okay";
+};
+
+&wdog1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_wdog>;
+};
+
+&adc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_adc>;
+	vref-supply = <&reg_vref>;
+	#io-channel-cells = <1>;
+	status = "okay";
+};
+
+&usbotg1 {
+	/* USB-C connector */
+	disable-over-current;
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbotg2 {
+	/* thermal sensor */
+	disable-over-current;
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy1 {
+	fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+	fsl,tx-d-cal = <106>;
+};
+
+&iomuxc {
+	mux_ir_reset: irresetgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03		0x3008
+		>;
+	};
+
+	mux_poweroff: poweroffgrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04		0x3008
+		>;
+	};
+
+	mux_poweroff2: poweroff2grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06		0x3008
+		>;
+	};
+
+	mux_charger_stat1: charger1grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01		0x3008
+		>;
+	};
+
+	mux_charger_stat2: charger2grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO02__GPIO1_IO02		0x3008
+		>;
+	};
+
+	mux_wdog: wdoggrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY		0x30b0
+		>;
+	};
+
+	mux_sdhc1_cd: sdhc1-cd-grp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_RTS_B__GPIO1_IO19		0x17059
+		>;
+	};
+
+	mux_sdhc1: sdhc1grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x17059
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x10071
+			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
+		>;
+	};
+
+	mux_sdhc1_100mhz: sdhc1-100mhz-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x170b9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x170b9
+			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
+		>;
+	};
+
+	mux_sdhc1_200mhz: sdhc1-200mhz-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x170f9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x170f9
+			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
+		>;
+	};
+
+	mux_sdhc2: sdhc2grp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_RE_B__USDHC2_CLK			0x10069
+			MX6UL_PAD_NAND_WE_B__USDHC2_CMD			0x17059
+			MX6UL_PAD_NAND_DATA00__USDHC2_DATA0		0x17059
+			MX6UL_PAD_NAND_DATA01__USDHC2_DATA1		0x17059
+			MX6UL_PAD_NAND_DATA02__USDHC2_DATA2		0x17059
+			MX6UL_PAD_NAND_DATA03__USDHC2_DATA3		0x17059
+			MX6UL_PAD_NAND_DATA04__USDHC2_DATA4		0x17059
+			MX6UL_PAD_NAND_DATA05__USDHC2_DATA5		0x17059
+			MX6UL_PAD_NAND_DATA06__USDHC2_DATA6		0x17059
+			MX6UL_PAD_NAND_DATA07__USDHC2_DATA7		0x17059
+		>;
+	};
+
+	mux_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6UL_PAD_UART4_TX_DATA__I2C1_SCL		0x4001b8b0
+			MX6UL_PAD_UART4_RX_DATA__I2C1_SDA		0x4001b8b0
+		>;
+	};
+
+	mux_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6UL_PAD_UART5_TX_DATA__I2C2_SCL		0x4001f8a8
+			MX6UL_PAD_UART5_RX_DATA__I2C2_SDA		0x4001f8a8
+		>;
+	};
+
+	mux_uart: uartgrp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX		0x1b0b1
+			MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX		0x1b0b1
+		>;
+	};
+
+	mux_gpio_keys: gpiokeygrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11		0x3008
+			MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12		0x3008
+			MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13		0x3008
+			MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10		0x3008
+			MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09		0x3008
+			MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15		0x3008
+			MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08		0x3008
+			MX6UL_PAD_ENET2_TX_CLK__GPIO2_IO14		0x3008
+			MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03		0x3008
+			MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01		0x3008
+		>;
+	};
+
+	mux_led_ctrl: ledctrlgrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02		0x3008
+		>;
+	};
+
+	mux_adc: adcgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO07__GPIO1_IO07		0xb0
+		>;
+	};
+
+	mux_pwm: pwm1grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO08__PWM1_OUT			0x110b0
+		>;
+	};
+
+	mux_backlight_enable: blenablegrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO09__GPIO1_IO09		0x3008
+		>;
+	};
+
+	mux_lcd_data: lcdifdatgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA00__LCDIF_DATA00		0x79
+			MX6UL_PAD_LCD_DATA01__LCDIF_DATA01		0x79
+			MX6UL_PAD_LCD_DATA02__LCDIF_DATA02		0x79
+			MX6UL_PAD_LCD_DATA03__LCDIF_DATA03		0x79
+			MX6UL_PAD_LCD_DATA04__LCDIF_DATA04		0x79
+			MX6UL_PAD_LCD_DATA05__LCDIF_DATA05		0x79
+			MX6UL_PAD_LCD_DATA06__LCDIF_DATA06		0x79
+			MX6UL_PAD_LCD_DATA07__LCDIF_DATA07		0x79
+			MX6UL_PAD_LCD_DATA08__LCDIF_DATA08		0x79
+			MX6UL_PAD_LCD_DATA09__LCDIF_DATA09		0x79
+			MX6UL_PAD_LCD_DATA10__LCDIF_DATA10		0x79
+			MX6UL_PAD_LCD_DATA11__LCDIF_DATA11		0x79
+			MX6UL_PAD_LCD_DATA12__LCDIF_DATA12		0x79
+			MX6UL_PAD_LCD_DATA13__LCDIF_DATA13		0x79
+			MX6UL_PAD_LCD_DATA14__LCDIF_DATA14		0x79
+			MX6UL_PAD_LCD_DATA15__LCDIF_DATA15		0x79
+			MX6UL_PAD_LCD_DATA16__LCDIF_DATA16		0x79
+			MX6UL_PAD_LCD_DATA17__LCDIF_DATA17		0x79
+		>;
+	};
+
+	mux_lcd_ctrl: lcdifctrlgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_CLK__LCDIF_CLK			0x79
+			MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE		0x79
+			MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC		0x79
+			MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC		0x79
+		>;
+	};
+
+	mux_csi: csi1grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK		0x1b088
+			MX6UL_PAD_CSI_VSYNC__CSI_VSYNC			0x1b088
+			MX6UL_PAD_CSI_HSYNC__CSI_HSYNC			0x1b088
+			MX6UL_PAD_CSI_DATA00__CSI_DATA02		0x1b088
+			MX6UL_PAD_CSI_DATA01__CSI_DATA03		0x1b088
+			MX6UL_PAD_CSI_DATA02__CSI_DATA04		0x1b088
+			MX6UL_PAD_CSI_DATA03__CSI_DATA05		0x1b088
+			MX6UL_PAD_CSI_DATA04__CSI_DATA06		0x1b088
+			MX6UL_PAD_CSI_DATA05__CSI_DATA07		0x1b088
+			MX6UL_PAD_CSI_DATA06__CSI_DATA08		0x1b088
+			MX6UL_PAD_CSI_DATA07__CSI_DATA09		0x1b088
+		>;
+	};
+
+	mux_gc0308: gc0308grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_MCLK__CSI_MCLK			0x1e038
+			MX6UL_PAD_GPIO1_IO05__GPIO1_IO05		0x1b088
+			MX6UL_PAD_GPIO1_IO06__GPIO1_IO06		0x1b088
+		>;
+	};
+
+
+	mux_spi3: ecspi3grp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI		0x100b1
+			MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK		0x100b1
+		>;
+	};
+
+	mux_spi3_cs: ecspi3_csgrp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20		0x3008
+		>;
+	};
+};
-- 
2.43.0



From kuba at kernel.org  Mon Feb 12 17:30:15 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 12 Feb 2024 17:30:15 -0800
Subject: [PATCH net-next v4] net: stmmac: dwmac-qcom-ethqos: Add support
 for 2.5G SGMII
In-Reply-To: <20240208111714.11456-1-quic_snehshah@quicinc.com>
References: <20240208111714.11456-1-quic_snehshah@quicinc.com>
Message-ID: <20240212173015.0341f0ee@kernel.org>

On Thu,  8 Feb 2024 16:47:14 +0530 Sneh Shah wrote:
> Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000
> mode for 1G/100M/10M speed.
> Added changes to configure serdes phy and mac based on link speed.
> Changing serdes phy speed involves multiple register writes for
> serdes block. To avoid redundant write operations only update serdes
> phy when new speed is different.

Sounds like 2 separate changes in one patch, please split the
optimization of not writing the registers multiple times and
the 2.5G support.

> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> index 31631e3f89d0..6bbdbb7bef44 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> @@ -106,6 +106,7 @@ struct qcom_ethqos {
>  	struct clk *link_clk;
>  	struct phy *serdes_phy;
>  	unsigned int speed;
> +	int serdes_speed;

Why signed if speed itself is unsigned?

>  	/* Enable and restart the Auto-Negotiation */
>  	if (ane)
>  		value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN;
> +	else
> +		value &= ~GMAC_AN_CTRL_ANE;

That looks unrelated. Either a separate patch or please explain in the
commit msg why.
-- 
pw-bot: cr


From sebastian.reichel at collabora.com  Mon Feb 12 17:30:25 2024
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Tue, 13 Feb 2024 02:30:25 +0100
Subject: [PATCH v4 00/19] Remove pm_power_off use in
 drivers/power/reset
In-Reply-To: <20240212162831.67838-1-afd@ti.com>
References: <20240212162831.67838-1-afd@ti.com>
Message-ID: <170778782561.1080348.15486414819584613989.b4-ty@collabora.com>


On Mon, 12 Feb 2024 10:28:12 -0600, Andrew Davis wrote:
> Use of pm_power_off is considered legacy and should be replaced with
> register_sys_off*(). Same for register_restart_handler(). Do this
> for the drivers/power/reset subsystem for all trivial cases.
> 
> Thanks,
> Andrew
> 
> [...]

Applied, thanks!

[01/19] power: reset: atc260x-poweroff: Use devm_register_sys_off_handler(RESTART)
        commit: f22e835028902b01915f584d2912cc25a397c84e
[02/19] power: reset: atc260x-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
        commit: ab1439b05168dc73539e78d8b3100a0336a83bca
[03/19] power: reset: xgene-reboot: Use devm_platform_ioremap_resource() helper
        commit: 7ddfd33c6ee58ee915d09177a7dbac2c5be7b536
[04/19] power: reset: xgene-reboot: Use devm_register_sys_off_handler(RESTART)
        commit: 6af1ee028537be0a43ce939eb8f5321096208667
[05/19] power: reset: tps65086-restart: Use devm_register_sys_off_handler(RESTART)
        commit: e68b71812ebf385317c5bcf82674c109806be452
[06/19] power: reset: tps65086-restart: Remove unneeded device data struct
        commit: 11d2642e14ad022de13f261370ccddd33693c045
[07/19] power: reset: brcm-kona-reset: Use devm_register_sys_off_handler(RESTART)
        commit: 45079f206e635a08cba395a08dd3fd7629dbb24d
[08/19] power: reset: axxia-reset: Use devm_register_sys_off_handler(RESTART)
        commit: ad8d7b8002a1d3a673f2d6f110b378d137f61037
[09/19] power: reset: rmobile-reset: Use devm_platform_ioremap_resource() helper
        commit: 0867276eb12230a5e94ec2b28eba718e76b77eb1
[10/19] power: reset: rmobile-reset: Use devm_register_sys_off_handler(RESTART)
        commit: ba1188ea8be80a7bc091073792d404ab54b187b1
[11/19] power: reset: mt6323-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
        commit: 6ab9137719a719f39e000aa62887ae25e1194815
[12/19] power: reset: msm-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
        commit: b5711ff9171325261a7d6406b3c2b3c7752b6b8a
[13/19] power: reset: msm-poweroff: Use devm_register_sys_off_handler(RESTART)
        commit: 00ae86ebf893e0c89a7af6bfd270259e3ded93d1
[14/19] power: reset: regulator-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
        commit: 77b61173c2d0ff42e5d609dc1fad137f1229f03b
[15/19] power: reset: as3722-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
        commit: 348fde771ce7f5219a73750bd7a0d4c4497b1223
[16/19] power: reset: gemini-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
        commit: b6475c3f81c13d6d69113f69a668c96af3a5af51
[17/19] power: reset: restart-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
        commit: c3ede0b6f7dd345d8986cb69b861cadb9976782f
[18/19] power: reset: syscon-poweroff: Move device data into a struct
        commit: ffa212831289f15a92fe295a371157290619bb8f
[19/19] power: reset: syscon-poweroff: Use devm_register_sys_off_handler(POWER_OFF)
        commit: 14c5678720bdee7c5b582839a8dbcffd0c50de5c

Best regards,
-- 
Sebastian Reichel <sebastian.reichel at collabora.com>



From patchwork-bot+netdevbpf at kernel.org  Mon Feb 12 17:40:26 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Tue, 13 Feb 2024 01:40:26 +0000
Subject: [PATCH net] net: stmmac: xgmac: use #define for string constants
In-Reply-To: <20240208-xgmac-const-v1-1-e69a1eeabfc8@kernel.org>
References: <20240208-xgmac-const-v1-1-e69a1eeabfc8@kernel.org>
Message-ID: <170778842609.15795.7467205079881432963.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Thu, 08 Feb 2024 09:48:27 +0000 you wrote:
> The cited commit introduces and uses the string constants dpp_tx_err and
> dpp_rx_err. These are assigned to constant fields of the array
> dwxgmac3_error_desc.
> 
> It has been reported that on GCC 6 and 7.5.0 this results in warnings
> such as:
> 
> [...]

Here is the summary with links:
  - [net] net: stmmac: xgmac: use #define for string constants
    https://git.kernel.org/netdev/net/c/1692b9775e74

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From zev at bewilderbeest.net  Mon Feb 12 17:51:36 2024
From: zev at bewilderbeest.net (Zev Weiss)
Date: Mon, 12 Feb 2024 17:51:36 -0800
Subject: [PATCH] ARM: dts: aspeed: asrock: Add BIOS SPI flash chips
Message-ID: <20240213015138.12452-2-zev@bewilderbeest.net>

On e3c246d4i, e3c256d4i, romed8hm3, and spc621d8hm3 the host firmware
flash is accessible to the BMC via the AST2500 SPI1 interface with an
external GPIO-controlled mux switching the flash chip between the host
and the BMC.

The default state of the mux GPIO leaves it connected to the host, so
the BMC's attempt to bind a driver to it during its boot sequence will
fail, but a write to a sysfs 'bind' file after toggling the mux GPIO
(along with whatever other preparatory steps are required) can later
allow it to be attached and accessed by the BMC.  It's not an ideal
arrangement, but in the absence of DT overlays or any other
alternative it is at least a functional one, if somewhat clumsily so.

Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
---

Note that this patch is based on Joel's for-next tree, since the
e3c256d4i and spc621d8hm3 device-trees haven't been merged in mainline
yet.

 .../boot/dts/aspeed/aspeed-bmc-asrock-e3c246d4i.dts  | 12 ++++++++++++
 .../boot/dts/aspeed/aspeed-bmc-asrock-e3c256d4i.dts  | 12 ++++++++++++
 .../boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts  | 12 ++++++++++++
 .../dts/aspeed/aspeed-bmc-asrock-spc621d8hm3.dts     | 12 ++++++++++++
 4 files changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c246d4i.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c246d4i.dts
index c4b2efbfdf56..557ce20e305d 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c246d4i.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c246d4i.dts
@@ -68,6 +68,18 @@ flash at 0 {
 	};
 };
 
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1_default>;
+	flash at 0 {
+		status = "okay";
+		label = "bios";
+		m25p,fast-read;
+		spi-max-frequency = <25000000>; /* 25 MHz */
+	};
+};
+
 &uart5 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c256d4i.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c256d4i.dts
index 263fcc8106ff..bf752ff8204f 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c256d4i.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-e3c256d4i.dts
@@ -69,6 +69,18 @@ flash at 0 {
 	};
 };
 
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1_default>;
+	flash at 0 {
+		status = "okay";
+		label = "bios";
+		m25p,fast-read;
+		spi-max-frequency = <25000000>; /* 25 MHz */
+	};
+};
+
 &uart1 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
index 4554abf0c7cd..8dff2cbf042b 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
@@ -56,6 +56,18 @@ flash at 0 {
 	};
 };
 
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1_default>;
+	flash at 0 {
+		status = "okay";
+		label = "bios";
+		m25p,fast-read;
+		spi-max-frequency = <33000000>; /* 33 MHz */
+	};
+};
+
 &uart5 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-spc621d8hm3.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-spc621d8hm3.dts
index 555485871e7a..54b40776c7e3 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-spc621d8hm3.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-spc621d8hm3.dts
@@ -66,6 +66,18 @@ flash at 0 {
 	};
 };
 
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1_default>;
+	flash at 0 {
+		status = "okay";
+		label = "bios";
+		m25p,fast-read;
+		spi-max-frequency = <17000000>; /* 17 MHz */
+	};
+};
+
 &uart5 {
 	status = "okay";
 };
-- 
2.43.0



From ankita at nvidia.com  Mon Feb 12 17:59:45 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Tue, 13 Feb 2024 01:59:45 +0000
Subject: [PATCH v7 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240212102718.07543659.alex.williamson@redhat.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
	<20240211174705.31992-5-ankita@nvidia.com>
	<20240212100502.2b5009e4.alex.williamson@redhat.com>
	<20240212172001.GE4048826@nvidia.com>
 <20240212102718.07543659.alex.williamson@redhat.com>
Message-ID: <SA1PR12MB7199C6C925FD78EE3827BF6BB04F2@SA1PR12MB7199.namprd12.prod.outlook.com>

>>?? IP requires platform integration to take responsibility to prevent
>>?? this.
>>
>>?? To safely use VFIO in KVM the platform must guarantee full safety
>>?? in the guest where no action taken against a MMIO mapping can
>>?? trigger an uncontainer failure. We belive that most VFIO PCI
>>?? platforms support this for both mapping types, at least in common
>>?? flows, based on some expectations of how PCI IP is integrated. This
>>?? can be enabled more broadly, for instance into vfio-platform
>>?? drivers, but only after the platform vendor completes auditing for
>>?? safety.
>
> I like it, please incorporate into the next version.

Yes, will fix the typos and add it.


From ankita at nvidia.com  Mon Feb 12 18:29:52 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Tue, 13 Feb 2024 02:29:52 +0000
Subject: [PATCH v7 0/4] kvm: arm64: allow the VM to select DEVICE_* and
 NORMAL_NC for IO memory
In-Reply-To: <Zcp-hIlV-ZEu0Jou@linux.dev>
References: <20240211174705.31992-1-ankita@nvidia.com>
 <Zcp-hIlV-ZEu0Jou@linux.dev>
Message-ID: <SA1PR12MB7199B4F962B580A484BCAFCEB04F2@SA1PR12MB7199.namprd12.prod.outlook.com>

>>
>> The default device stage 2 mapping was chosen in KVM for ARM64 since
>> it was considered safer (i.e. it would not allow guests to trigger
>> uncontained failures ultimately crashing the machine) but this
>> turned out to be asynchronous (SError) defeating the purpose.
>>
>> For these reasons, relax the KVM stage 2 device memory attributes
>> from DEVICE_nGnRE to Normal-NC.
>
> Hi Ankit,
>
> Thanks for being responsive in respinning the series according to the
> feedback. I think we're pretty close here, but it'd be good to address
> the comment / changelog feedback as well.
>
> Can you respin this once more? Hopefully we can get this stuff soaking
> in -next thereafter.

Hi Oliver, yes I am planning to refresh it in the next few days after
incorporating the comments.

From lkp at intel.com  Mon Feb 12 18:58:23 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 13 Feb 2024 10:58:23 +0800
Subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock
 .is_notify_supported callback
In-Reply-To: <20240212123233.1230090-7-cristian.marussi@arm.com>
References: <20240212123233.1230090-7-cristian.marussi@arm.com>
Message-ID: <202402131047.2NVZWHma-lkp@intel.com>

Hi Cristian,

kernel test robot noticed the following build errors:

[auto build test ERROR on soc/for-next]
[also build test ERROR on linus/master v6.8-rc4 next-20240212]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Cristian-Marussi/firmware-arm_scmi-Check-for-notification-support/20240212-203727
base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
patch link:    https://lore.kernel.org/r/20240212123233.1230090-7-cristian.marussi%40arm.com
patch subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock .is_notify_supported callback
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20240213/202402131047.2NVZWHma-lkp at intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project c08b90c50bcac9f3f563c79491c8dbcbe7c3b574)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240213/202402131047.2NVZWHma-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402131047.2NVZWHma-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/firmware/arm_scmi/clock.c:853:8: error: call to undeclared function 'scmi_clock_domain_lookup'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     853 |         clk = scmi_clock_domain_lookup(ci, src_id);
         |               ^
>> drivers/firmware/arm_scmi/clock.c:853:6: error: incompatible integer to pointer conversion assigning to 'struct scmi_clock_info *' from 'int' [-Wint-conversion]
     853 |         clk = scmi_clock_domain_lookup(ci, src_id);
         |             ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   2 errors generated.


vim +/scmi_clock_domain_lookup +853 drivers/firmware/arm_scmi/clock.c

   842	
   843	static bool scmi_clk_notify_supported(const struct scmi_protocol_handle *ph,
   844					      u8 evt_id, u32 src_id)
   845	{
   846		bool supported;
   847		struct scmi_clock_info *clk;
   848		struct clock_info *ci = ph->get_priv(ph);
   849	
   850		if (evt_id >= ARRAY_SIZE(evt_2_cmd))
   851			return false;
   852	
 > 853		clk = scmi_clock_domain_lookup(ci, src_id);
   854		if (IS_ERR(clk))
   855			return false;
   856	
   857		if (evt_id == SCMI_EVENT_CLOCK_RATE_CHANGED)
   858			supported = clk->rate_changed_notifications;
   859		else
   860			supported = clk->rate_change_requested_notifications;
   861	
   862		return supported;
   863	}
   864	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From anshuman.khandual at arm.com  Mon Feb 12 19:13:39 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 13 Feb 2024 08:43:39 +0530
Subject: [PATCH V4 03/11] coresight: tmc: Extract device properties from
 AMBA pid based table lookup
In-Reply-To: <44597c9a-79bd-40f8-87a7-b53582132583@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-4-anshuman.khandual@arm.com>
 <44597c9a-79bd-40f8-87a7-b53582132583@arm.com>
Message-ID: <0c65f3b0-a879-444c-b0a4-4af485e72166@arm.com>



On 2/12/24 17:43, Suzuki K Poulose wrote:
> On 23/01/2024 05:46, Anshuman Khandual wrote:
>> This extracts device properties from AMBA pid based table lookup. This also
>> defers tmc_etr_setup_caps() after the coresight device has been initialized
>> so that PID value can be read.
>>
>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Cc: Mike Leach <mike.leach at linaro.org>
>> Cc: James Clark <james.clark 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>
>> ---
>> ? .../hwtracing/coresight/coresight-tmc-core.c? | 19 +++++++++++++------
>> ? 1 file changed, 13 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
>> index 7ec5365e2b64..e71db3099a29 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
>> @@ -370,16 +370,24 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
>> ????? return (auth & TMC_AUTH_NSID_MASK) == 0x3;
>> ? }
>> ? +#define TMC_AMBA_MASK 0xfffff
>> +
>> +static const struct amba_id tmc_ids[];
>> +
>> ? /* Detect and initialise the capabilities of a TMC ETR */
>> -static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
>> +static int tmc_etr_setup_caps(struct device *parent, u32 devid)
>> ? {
>> ????? int rc;
>> -??? u32 dma_mask = 0;
>> +??? u32 tmc_pid, dma_mask = 0;
>> ????? struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
>> +??? void *dev_caps;
>> ? ????? if (!tmc_etr_has_non_secure_access(drvdata))
>> ????????? return -EACCES;
>> ? +??? tmc_pid = coresight_get_pid(&drvdata->csdev->access) & TMC_AMBA_MASK;
>> +??? dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid);
>> +
>> ????? /* Set the unadvertised capabilities */
>> ????? tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
>> ? @@ -497,10 +505,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>> ????????? desc.type = CORESIGHT_DEV_TYPE_SINK;
>> ????????? desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
>> ????????? desc.ops = &tmc_etr_cs_ops;
>> -??????? ret = tmc_etr_setup_caps(dev, devid,
>> -???????????????????? coresight_get_uci_data(id));
>> -??????? if (ret)
>> -??????????? goto out;
>> ????????? idr_init(&drvdata->idr);
>> ????????? mutex_init(&drvdata->idr_mutex);
>> ????????? dev_list = &etr_devs;
>> @@ -539,6 +543,9 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>> ????????? goto out;
>> ????? }
>> ? +??? if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
>> +??????? ret = tmc_etr_setup_caps(dev, devid);
>> +
> 
> With this change, we silently accept an ETR that may only have "SECURE" access only and crash later while we try to enable tracing. You could
> pass in the "access" (which is already in 'desc.access' in the original
> call site and deal with it ?

Just wondering, if something like the following will help ? A failed tmc_etr_setup_caps()
because of failed tmc_etr_has_non_secure_access(), will unregister the coresight device
before returning.

--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -538,8 +538,13 @@ static int __tmc_probe(struct device *dev, struct resource *res)
                goto out;
        }
 
-       if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
+       if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
                ret = tmc_etr_setup_caps(dev, devid);
+               if (ret) {
+                       coresight_unregister(drvdata->csdev);
+                       goto out;
+               }
+       }
 
        drvdata->miscdev.name = desc.name;
        drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;


From robh at kernel.org  Mon Feb 12 19:38:20 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 12 Feb 2024 21:38:20 -0600
Subject: [PATCH v2 02/17] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240213010347.1075251-3-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-3-sre@kernel.org>
Message-ID: <170779549979.3767632.14798050917184496330.robh@kernel.org>


On Tue, 13 Feb 2024 02:00:51 +0100, Sebastian Reichel wrote:
> Convert the i.MX  Wireless External Interface Module binding to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../devicetree/bindings/bus/imx-weim.txt      | 117 ----------
>  .../fsl/fsl,imx-weim-peripherals.yaml         |  36 ++++
>  .../memory-controllers/fsl/fsl,imx-weim.yaml  | 201 ++++++++++++++++++
>  .../mc-peripheral-props.yaml                  |   1 +
>  .../fieldbus/arcx,anybus-controller.txt       |   2 +-
>  5 files changed, 239 insertions(+), 118 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.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/dt-review-ci/linux/Documentation/devicetree/bindings/bus/socionext,uniphier-system-bus.example.dtb: serial at 5,200000: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/serial/8250.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-bus-controller.example.dtb: flash at 0,0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/mtd/mtd-physmap.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-bus-controller.example.dtb: serial at 1,0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/serial/8250.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/intel,ixp4xx-expansion-bus-controller.example.dtb: serial at 1,0: Unevaluated properties are not allowed ('intel,ixp4xx-eb-byte-access', 'intel,ixp4xx-eb-cycle-type', 'intel,ixp4xx-eb-t3', 'intel,ixp4xx-eb-write-enable' were unexpected)
	from schema $id: http://devicetree.org/schemas/serial/8250.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ifc.example.dtb: flash at 0,0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/mtd/mtd-physmap.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/ingenic,nemc.example.dtb: memory-controller at 13410000: ethernet at 6: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/memory-controllers/ingenic,nemc.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/ingenic,nemc.example.dtb: ethernet at 6: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/net/davicom,dm9000.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/ingenic,nemc.example.dtb: ethernet at 6: Unevaluated properties are not allowed ('ingenic,nemc-tAH', 'ingenic,nemc-tAS', 'ingenic,nemc-tAW', 'ingenic,nemc-tBP', 'ingenic,nemc-tSTRV' were unexpected)
	from schema $id: http://devicetree.org/schemas/net/davicom,dm9000.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.example.dtb: memory-controller at 58002000: psram at 0,0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/memory-controllers/st,stm32-fmc2-ebi.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.example.dtb: memory-controller at 58002000: nand-controller at 4,0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/memory-controllers/st,stm32-fmc2-ebi.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.example.dtb: psram at 0,0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/mtd/mtd-physmap.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/watchdog/maxim,max63xx.example.dtb: watchdog at 50000000: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/watchdog/maxim,max63xx.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/serial/serial.example.dtb: serial at 1234: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/serial/8250.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/serial/8250.example.dtb: serial at 80230000: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/serial/8250.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/serial/8250.example.dtb: serial at 49042000: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/serial/8250.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/serial/8250.example.dtb: serial at 1e787000: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/serial/8250.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/net/davicom,dm9000.example.dtb: ethernet at a8000000: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/net/davicom,dm9000.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/net/micrel,ks8851.example.dtb: ethernet at 1,0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/net/micrel,ks8851.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mtd/ti,am654-hbmc.example.dtb: memory-controller at 47034000: flash at 0,0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/mtd/ti,am654-hbmc.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mtd/ti,am654-hbmc.example.dtb: flash at 0,0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/mtd/mtd-physmap.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mtd/mtd-physmap.example.dtb: flash at ff000000: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/mtd/mtd-physmap.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mtd/mtd-physmap.example.dtb: flash at 0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/mtd/mtd-physmap.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mtd/mtd-physmap.example.dtb: sram at 2,0: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/mtd/mtd-physmap.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mtd/mtd-physmap.example.dtb: flash at 20000000: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/mtd/mtd-physmap.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mtd/ingenic,nand.example.dtb: memory-controller at 13410000: nand-controller at 1: 'fsl,weim-cs-timing' is a required property
	from schema $id: http://devicetree.org/schemas/memory-controllers/ingenic,nemc.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240213010347.1075251-3-sre at kernel.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From ankita at nvidia.com  Mon Feb 12 19:41:47 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Tue, 13 Feb 2024 03:41:47 +0000
Subject: [PATCH v7 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <165363ba-d6cc-47a7-ab2a-d3a27a42f739@redhat.com>
References: <20240211174705.31992-1-ankita@nvidia.com>
 <20240211174705.31992-3-ankita@nvidia.com>
 <165363ba-d6cc-47a7-ab2a-d3a27a42f739@redhat.com>
Message-ID: <SA1PR12MB7199CEFA3E0920120BFC2BBEB04F2@SA1PR12MB7199.namprd12.prod.outlook.com>

>> insufficient information and uncertainity in the behavior of
>
> s/uncertainity/uncertainty/

Ack.

>> non PCI drivers.
>>
>> Add a new flag VM_ALLOW_ANY_UNCACHED to indicate KVM that the device
>> is WC capable and these S2 changes can be extended to it. KVM can use
>> this flag to activate the code.
>>
>
> MM people will stumble only over this commit at some point, looking for
> details. It might make sense to add a bit more details on the underlying
> problem (user space tables vs. stage-1 vs. stage-2) and why we want to
> have a different mapping in user space compared to stage-1.
>
> Then, describe that the VMA flag was found to be the simplest and
> cleanest way to communicate this information from VFIO to KVM.

Okay, I'll work on the commit message and describe in more details in
the next version.

>> +/*
>> + * This flag is used to connect VFIO to arch specific KVM code. It
>> + * indicates that the memory under this VMA is safe for use with any
>> + * non-cachable memory type inside KVM. Some VFIO devices, on some
>> + * platforms, are thought to be unsafe and can cause machine crashes
>> + * if KVM does not lock down the memory type.
>> + */
>> +#ifdef CONFIG_64BIT
>> +#define VM_ALLOW_ANY_UNCACHED_BIT??? 39
>> +#define VM_ALLOW_ANY_UNCACHED??????????????? BIT(VM_ALLOW_ANY_UNCACHED_BIT)
>> +#else
>> +#define VM_ALLOW_ANY_UNCACHED??????????????? VM_NONE
>> +#endif
>> +
>>?? /* Bits set in the VMA until the stack is in its final location */
>>?? #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
>>
>
> It's not perfect (very VFIO <-> KVM specific right now, VMA flags feel a
> bit wrong), but it certainly easier and cleaner than any alternatives I
> could think of.
>
> Acked-by: David Hildenbrand <david at redhat.com>

Thanks! FWIW, it was found the cleanest way to restrict the changes to vfio-pci.

From Dharma.B at microchip.com  Mon Feb 12 20:23:36 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Tue, 13 Feb 2024 04:23:36 +0000
Subject: [PATCH v2] dt-bindings: interrupt-controller: Convert Atmel AIC
 to json-schema
In-Reply-To: <20240212140824.GA107736-robh@kernel.org>
References: <20240209100122.61335-1-dharma.b@microchip.com>
 <20240212140824.GA107736-robh@kernel.org>
Message-ID: <003d61c9-b914-4e1c-b3f8-1140ea640039@microchip.com>

Hi Rob,

On 12/02/24 7:38 pm, Rob Herring wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Fri, Feb 09, 2024 at 03:31:22PM +0530, Dharma Balasubiramani wrote:
>> Convert the Atmel AIC binding document to DT schema format using
>> json-schema.
>>
>> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
>> ---
>> Changelog
>> v1 -> v2
>> - Drop the '|' as there is no formatting to preserve.
>> - Remove unnecessary marketing statement from description.
>> - Drop the description for interrupts and reg, it's obvious.
>> - Put reg after compatible.
>> - Drop comment in example.
>> - Drop the example of device that is wired to an AIC as it's(dma) binding is
>>    not yet available.
>> ---
>>   .../interrupt-controller/atmel,aic.txt        | 43 -----------
>>   .../interrupt-controller/atmel,aic.yaml       | 74 +++++++++++++++++++
>>   2 files changed, 74 insertions(+), 43 deletions(-)
>>   delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
>>   create mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
>> deleted file mode 100644
>> index 7079d44bf3ba..000000000000
>> --- a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
>> +++ /dev/null
>> @@ -1,43 +0,0 @@
>> -* Advanced Interrupt Controller (AIC)
>> -
>> -Required properties:
>> -- compatible: Should be:
>> -    - "atmel,<chip>-aic" where  <chip> can be "at91rm9200", "sama5d2",
>> -      "sama5d3" or "sama5d4"
>> -    - "microchip,<chip>-aic" where <chip> can be "sam9x60"
>> -
>> -- interrupt-controller: Identifies the node as an interrupt controller.
>> -- #interrupt-cells: The number of cells to define the interrupts. It should be 3.
>> -  The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet).
>> -  The second cell is used to specify flags:
>> -    bits[3:0] trigger type and level flags:
>> -      1 = low-to-high edge triggered.
>> -      2 = high-to-low edge triggered.
>> -      4 = active high level-sensitive.
>> -      8 = active low level-sensitive.
>> -      Valid combinations are 1, 2, 3, 4, 8.
>> -      Default flag for internal sources should be set to 4 (active high).
>> -  The third cell is used to specify the irq priority from 0 (lowest) to 7
>> -  (highest).
>> -- reg: Should contain AIC registers location and length
>> -- atmel,external-irqs: u32 array of external irqs.
>> -
>> -Examples:
>> -     /*
>> -      * AIC
>> -      */
>> -     aic: interrupt-controller at fffff000 {
>> -             compatible = "atmel,at91rm9200-aic";
>> -             interrupt-controller;
>> -             #interrupt-cells = <3>;
>> -             reg = <0xfffff000 0x200>;
>> -     };
>> -
>> -     /*
>> -      * An interrupt generating device that is wired to an AIC.
>> -      */
>> -     dma: dma-controller at ffffec00 {
>> -             compatible = "atmel,at91sam9g45-dma";
>> -             reg = <0xffffec00 0x200>;
>> -             interrupts = <21 4 5>;
>> -     };
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
>> new file mode 100644
>> index 000000000000..df81115a8b7f
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
>> @@ -0,0 +1,74 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/interrupt-controller/atmel,aic.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Advanced Interrupt Controller (AIC)
>> +
>> +maintainers:
>> +  - Nicolas Ferre <nicolas.ferre at microchip.com>
>> +  - Dharma balasubiramani <dharma.b at microchip.com>
>> +
>> +description:
>> +  The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
>> +  maskable, vectored interrupt controller providing handling of up to one
>> +  hundred and twenty-eight interrupt sources.
>> +
>> +allOf:
>> +  - $ref: /schemas/interrupt-controller.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - atmel,at91rm9200-aic
>> +      - atmel,sama5d2-aic
>> +      - atmel,sama5d3-aic
>> +      - atmel,sama5d4-aic
>> +      - microchip,sam9x60-aic
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  interrupt-controller: true
>> +
>> +  "#interrupt-cells":
>> +    const: 3
>> +    description: |
>> +      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
>> +      The 2nd cell specifies flags:
>> +        bits[3:0] trigger type and level flags:
>> +          1 = low-to-high edge triggered.
>> +          2 = high-to-low edge triggered.
>> +          4 = active high level-sensitive.
>> +          8 = active low level-sensitive.
>> +        Valid combinations: 1, 2, 3, 4, 8.
>> +        Default for internal sources: 4 (active high).
>> +      The 3rd cell specifies irq priority from 0 (lowest) to 7 (highest).
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  atmel,external-irqs:
>> +    $ref: /schemas/types.yaml#/definitions/uint32-array
>> +    description: u32 array of external irqs.
> 
> Constraints on the array size and/or entry values?

The hardware's support for external IRQs may differ, which is why a u32 
array is utilized. This choice is based on the fact that IRQ numbers are 
commonly expressed as integers, and a 32-bit unsigned integer provides a 
standardized size capable of representing a broad range of numbers. This 
size is more than adequate for accommodating IRQ numbering.


> 
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - interrupt-controller
>> +  - "#interrupt-cells"
>> +  - atmel,external-irqs
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    interrupt-controller at fffff000 {
>> +      compatible = "atmel,at91rm9200-aic";
>> +      interrupt-controller;
>> +      #interrupt-cells = <3>;
>> +      reg = <0xfffff000 0x200>;
>> +      atmel,external-irqs = <31>;
>> +    };
>> +...
>>
>> base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
>> --
>> 2.25.1
>>

-- 
With Best Regards,
Dharma B.


From rdunlap at infradead.org  Mon Feb 12 21:02:58 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Mon, 12 Feb 2024 21:02:58 -0800
Subject: [PATCH v2] rtc: mt6397: select IRQ_DOMAIN instead of depending on it
Message-ID: <20240213050258.6167-1-rdunlap@infradead.org>

IRQ_DOMAIN is a hidden (not user visible) symbol. Users cannot set
it directly thru "make *config", so drivers should select it instead
of depending on it if they need it.
Relying on it being set for a dependency is risky.

Consistently using "select" or "depends on" can also help reduce
Kconfig circular dependency issues.

Therefore, change the use of "depends on" for IRQ_DOMAIN to
"select" for RTC_DRV_MT6397.

Fixes: 04d3ba70a3c9 ("rtc: mt6397: add IRQ domain dependency")
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Eddie Huang <eddie.huang at mediatek.com>
Cc: Sean Wang <sean.wang at mediatek.com>
Cc: Matthias Brugger <matthias.bgg at gmail.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-mediatek at lists.infradead.org
Cc: Alessandro Zummo <a.zummo at towertech.it>
Cc: Alexandre Belloni <alexandre.belloni at bootlin.com>
Cc: linux-rtc at vger.kernel.org
Cc: Marc Zyngier <maz at kernel.org>
Cc: Philipp Zabel <p.zabel at pengutronix.de>
Cc: Peter Rosin <peda at axentia.se>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
---
v2: add Rev-by: from AngeloGioacchino

 drivers/rtc/Kconfig |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff -- a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1858,7 +1858,8 @@ config RTC_DRV_MT2712
 
 config RTC_DRV_MT6397
 	tristate "MediaTek PMIC based RTC"
-	depends on MFD_MT6397 || (COMPILE_TEST && IRQ_DOMAIN)
+	depends on MFD_MT6397 || COMPILE_TEST
+	select IRQ_DOMAIN
 	help
 	  This selects the MediaTek(R) RTC driver. RTC is part of MediaTek
 	  MT6397 PMIC. You should enable MT6397 PMIC MFD before select


From w.egorov at phytec.de  Mon Feb 12 21:07:28 2024
From: w.egorov at phytec.de (Wadim Egorov)
Date: Tue, 13 Feb 2024 06:07:28 +0100
Subject: [PATCH v2 8/9] arm64: dts: ti: k3-am6*: Fix bus-width property in
 MMC nodes
In-Reply-To: <20240213002416.1560357-9-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
 <20240213002416.1560357-9-jm@ti.com>
Message-ID: <c6ad3a3e-330c-40cd-8e25-fd259fd1e398@phytec.de>

Hi Judith,

Am 13.02.24 um 01:24 schrieb Judith Mendez:
> Move bus-width property to *main.dtsi, above the OTAP/ITAP
> delay values. While there is no error with where it is
> currently at, it is easier to read the MMC node if the
> bus-width property is located above the OTAP/ITAP delay
> values consistently across MMC nodes.
>
> Add missing bus-width for MMC2 in k3-am62-main.
>
> Signed-off-by: Judith Mendez <jm at ti.com>
> ---
>   arch/arm64/boot/dts/ti/k3-am62-main.dtsi       | 5 +++--
>   arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 1 -
>   arch/arm64/boot/dts/ti/k3-am62a-main.dtsi      | 2 +-
>   arch/arm64/boot/dts/ti/k3-am64-main.dtsi       | 2 ++
>   arch/arm64/boot/dts/ti/k3-am642-evm.dts        | 2 --
>   arch/arm64/boot/dts/ti/k3-am642-sk.dts         | 1 -

I think you missed to update all non TI boards.

Regards,
Wadim

>   6 files changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> index 410b390ce5d5..55420eb1c620 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> @@ -559,9 +559,9 @@ sdhci0: mmc at fa10000 {
>   		clock-names = "clk_ahb", "clk_xin";
>   		assigned-clocks = <&k3_clks 57 6>;
>   		assigned-clock-parents = <&k3_clks 57 8>;
> +		bus-width = <8>;
>   		mmc-ddr-1_8v;
>   		mmc-hs200-1_8v;
> -		bus-width = <8>;
>   		ti,clkbuf-sel = <0x7>;
>   		ti,otap-del-sel-legacy = <0x0>;
>   		ti,otap-del-sel-mmc-hs = <0x0>;
> @@ -579,6 +579,7 @@ sdhci1: mmc at fa00000 {
>   		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>   		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
>   		clock-names = "clk_ahb", "clk_xin";
> +		bus-width = <4>;
>   		ti,clkbuf-sel = <0x7>;
>   		ti,otap-del-sel-legacy = <0x8>;
>   		ti,otap-del-sel-sd-hs = <0x0>;
> @@ -591,7 +592,6 @@ sdhci1: mmc at fa00000 {
>   		ti,itap-del-sel-sd-hs = <0x1>;
>   		ti,itap-del-sel-sdr12 = <0xa>;
>   		ti,itap-del-sel-sdr25 = <0x1>;
> -		bus-width = <4>;
>   		status = "disabled";
>   	};
>   
> @@ -602,6 +602,7 @@ sdhci2: mmc at fa20000 {
>   		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
>   		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
>   		clock-names = "clk_ahb", "clk_xin";
> +		bus-width = <4>;
>   		ti,clkbuf-sel = <0x7>;
>   		ti,otap-del-sel-legacy = <0x8>;
>   		ti,otap-del-sel-sd-hs = <0x0>;
> diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
> index bb6a5837bcb3..a34e0df2ab86 100644
> --- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
> @@ -842,7 +842,6 @@ &sdhci2 {
>   	vmmc-supply = <&wlan_en>;
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&wifi_pins_default>, <&wifi_32k_clk>;
> -	bus-width = <4>;
>   	non-removable;
>   	ti,fails-without-test-cd;
>   	cap-power-off-card;
> diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> index ddb76cd66f88..253c1857eedf 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> @@ -561,6 +561,7 @@ sdhci1: mmc at fa00000 {
>   		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>   		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
>   		clock-names = "clk_ahb", "clk_xin";
> +		bus-width = <4>;
>   		ti,clkbuf-sel = <0x7>;
>   		ti,otap-del-sel-legacy = <0x0>;
>   		ti,otap-del-sel-sd-hs = <0x0>;
> @@ -573,7 +574,6 @@ sdhci1: mmc at fa00000 {
>   		ti,itap-del-sel-sd-hs = <0x0>;
>   		ti,itap-del-sel-sdr12 = <0x0>;
>   		ti,itap-del-sel-sdr25 = <0x0>;
> -		bus-width = <4>;
>   		no-1-8-v;
>   		status = "disabled";
>   	};
> diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
> index bea05be7cb48..bc9c9ff993e6 100644
> --- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
> @@ -626,6 +626,7 @@ sdhci0: mmc at fa10000 {
>   		power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
>   		clocks = <&k3_clks 57 0>, <&k3_clks 57 1>;
>   		clock-names = "clk_ahb", "clk_xin";
> +		bus-width = <8>;
>   		mmc-ddr-1_8v;
>   		mmc-hs200-1_8v;
>   		ti,clkbuf-sel = <0x7>;
> @@ -647,6 +648,7 @@ sdhci1: mmc at fa00000 {
>   		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>   		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
>   		clock-names = "clk_ahb", "clk_xin";
> +		bus-width = <4>;
>   		ti,clkbuf-sel = <0x7>;
>   		ti,otap-del-sel-legacy = <0x0>;
>   		ti,otap-del-sel-sd-hs = <0x0>;
> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> index f308076d608a..83f2b00726b5 100644
> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> @@ -494,7 +494,6 @@ eeprom at 0 {
>   /* eMMC */
>   &sdhci0 {
>   	status = "okay";
> -	bus-width = <8>;
>   	non-removable;
>   	ti,driver-strength-ohm = <50>;
>   	disable-wp;
> @@ -506,7 +505,6 @@ &sdhci1 {
>   	status = "okay";
>   	vmmc-supply = <&vdd_mmc1>;
>   	pinctrl-names = "default";
> -	bus-width = <4>;
>   	pinctrl-0 = <&main_mmc1_pins_default>;
>   	disable-wp;
>   };
> diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
> index b286eaa02ada..67cd41bf806e 100644
> --- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
> @@ -469,7 +469,6 @@ &sdhci1 {
>   	status = "okay";
>   	vmmc-supply = <&vdd_mmc1>;
>   	pinctrl-names = "default";
> -	bus-width = <4>;
>   	pinctrl-0 = <&main_mmc1_pins_default>;
>   	disable-wp;
>   };


From w.egorov at phytec.de  Mon Feb 12 21:26:27 2024
From: w.egorov at phytec.de (Wadim Egorov)
Date: Tue, 13 Feb 2024 06:26:27 +0100
Subject: [PATCH v2 6/9] arm64: dts: ti: k3-am6*: Remove DLL properties for
 soft PHYs
In-Reply-To: <20240213002416.1560357-7-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
 <20240213002416.1560357-7-jm@ti.com>
Message-ID: <5f9fd69e-d3f6-4293-8746-06173f24e521@phytec.de>

Hi Judith,

Am 13.02.24 um 01:24 schrieb Judith Mendez:
> Remove DLL properties which are not applicable for soft PHYs
> since these PHYs do not have a DLL to enable.
>
> Signed-off-by: Judith Mendez <jm at ti.com>
> ---
>   arch/arm64/boot/dts/ti/k3-am62-main.dtsi              | 3 ---
>   arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi       | 1 -
>   arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi     | 1 -
>   arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi        | 1 -
>   arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi       | 1 -
>   arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi            | 2 --
>   arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts        | 3 ---
>   arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts | 1 -
>   arch/arm64/boot/dts/ti/k3-am62a-main.dtsi             | 1 -
>   arch/arm64/boot/dts/ti/k3-am62a7-sk.dts               | 1 -
>   arch/arm64/boot/dts/ti/k3-am62p5-sk.dts               | 1 -
>   arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi        | 2 --
>   arch/arm64/boot/dts/ti/k3-am64-main.dtsi              | 1 -
>   arch/arm64/boot/dts/ti/k3-am642-evm.dts               | 1 -
>   arch/arm64/boot/dts/ti/k3-am642-sk.dts                | 1 -

what about sdhci1 node updates on
 ? - k3-am642-phyboard-electra-rdk.dts
 ? - k3-am642-tqma64xxl-mbax4xxl.dts

Also does this apply only for am64 and sdhci1 (and not sdhci0)?
In your v1 you are describing that only AM64x and AM62p devices have a 
DLL to update the drive strength.
Trying to understand why only one of the interfaces gets updated.

Regards,
Wadim

>   15 files changed, 21 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> index fe0cc4a9a501..79ed5cbbbda1 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> @@ -561,7 +561,6 @@ sdhci0: mmc at fa10000 {
>   		assigned-clock-parents = <&k3_clks 57 8>;
>   		mmc-ddr-1_8v;
>   		mmc-hs200-1_8v;
> -		ti,trm-icp = <0x2>;
>   		bus-width = <8>;
>   		ti,clkbuf-sel = <0x7>;
>   		ti,otap-del-sel-legacy = <0x0>;
> @@ -580,7 +579,6 @@ sdhci1: mmc at fa00000 {
>   		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>   		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
>   		clock-names = "clk_ahb", "clk_xin";
> -		ti,trm-icp = <0x2>;
>   		ti,otap-del-sel-legacy = <0x8>;
>   		ti,otap-del-sel-sd-hs = <0x0>;
>   		ti,otap-del-sel-sdr12 = <0x0>;
> @@ -604,7 +602,6 @@ sdhci2: mmc at fa20000 {
>   		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
>   		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
>   		clock-names = "clk_ahb", "clk_xin";
> -		ti,trm-icp = <0x2>;
>   		ti,otap-del-sel-legacy = <0x8>;
>   		ti,otap-del-sel-sd-hs = <0x0>;
>   		ti,otap-del-sel-sdr12 = <0x0>;
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
> index 3372a256c90f..43488cc8bcb1 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
> @@ -317,7 +317,6 @@ serial_flash: flash at 0 {
>   &sdhci0 {
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&main_mmc0_pins_default>;
> -	ti,driver-strength-ohm = <50>;
>   	disable-wp;
>   	non-removable;
>   	status = "okay";
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
> index bf6d27e70bc4..6c4cec8728e4 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
> @@ -185,7 +185,6 @@ &ospi0 {
>   
>   /* Verdin SD_1 */
>   &sdhci1 {
> -	ti,driver-strength-ohm = <33>;
>   	status = "okay";
>   };
>   
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
> index 680071688dcb..be62648e7818 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
> @@ -206,7 +206,6 @@ &ospi0 {
>   
>   /* Verdin SD_1 */
>   &sdhci1 {
> -	ti,driver-strength-ohm = <33>;
>   	status = "okay";
>   };
>   
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
> index a6808b10c7b2..4768ef42c4fc 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
> @@ -26,7 +26,6 @@ &sdhci2 {
>   	mmc-pwrseq = <&wifi_pwrseq>;
>   	non-removable;
>   	ti,fails-without-test-cd;
> -	ti,driver-strength-ohm = <50>;
>   	vmmc-supply = <&reg_3v3>;
>   	status = "okay";
>   };
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
> index 6a06724b6d16..d68310444bcb 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
> @@ -1407,7 +1407,6 @@ &sdhci0 {
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&pinctrl_sdhci0>;
>   	non-removable;
> -	ti,driver-strength-ohm = <50>;
>   	status = "okay";
>   };
>   
> @@ -1416,7 +1415,6 @@ &sdhci1 {
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&pinctrl_sdhci1>;
>   	disable-wp;
> -	ti,driver-strength-ohm = <50>;
>   	vmmc-supply = <&reg_sdhc1_vmmc>;
>   	vqmmc-supply = <&reg_sdhc1_vqmmc>;
>   	status = "disabled";
> diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
> index 3b4246ce49de..bb6a5837bcb3 100644
> --- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
> @@ -819,7 +819,6 @@ &sdhci0 {
>   	bootph-all;
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&emmc_pins_default>;
> -	ti,driver-strength-ohm = <50>;
>   	disable-wp;
>   	status = "okay";
>   };
> @@ -832,7 +831,6 @@ &sdhci1 {
>   
>   	vmmc-supply = <&vdd_3v3_sd>;
>   	vqmmc-supply = <&vdd_sd_dv>;
> -	ti,driver-strength-ohm = <50>;
>   	disable-wp;
>   	cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
>   	cd-debounce-delay-ms = <100>;
> @@ -849,7 +847,6 @@ &sdhci2 {
>   	ti,fails-without-test-cd;
>   	cap-power-off-card;
>   	keep-power-in-suspend;
> -	ti,driver-strength-ohm = <50>;
>   	assigned-clocks = <&k3_clks 157 158>;
>   	assigned-clock-parents = <&k3_clks 157 160>;
>   	#address-cells = <1>;
> diff --git a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
> index 5c31f0453def..a83a90497857 100644
> --- a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
> @@ -334,7 +334,6 @@ &sdhci1 {
>   	vqmmc-supply = <&vddshv5_sdio>;
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&main_mmc1_pins_default>;
> -	ti,driver-strength-ohm = <50>;
>   	disable-wp;
>   	no-1-8-v;
>   	status = "okay";
> diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> index 6806288ec227..f283777d54b4 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> @@ -561,7 +561,6 @@ sdhci1: mmc at fa00000 {
>   		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>   		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
>   		clock-names = "clk_ahb", "clk_xin";
> -		ti,trm-icp = <0x2>;
>   		ti,otap-del-sel-legacy = <0x0>;
>   		ti,otap-del-sel-sd-hs = <0x0>;
>   		ti,otap-del-sel-sdr12 = <0xf>;
> diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
> index c99b2e90f76d..f241637a5642 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
> @@ -582,7 +582,6 @@ &sdhci1 {
>   	vmmc-supply = <&vdd_mmc1>;
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&main_mmc1_pins_default>;
> -	ti,driver-strength-ohm = <50>;
>   	disable-wp;
>   };
>   
> diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
> index 8c73587b0b62..5c9b73726ebd 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
> @@ -422,7 +422,6 @@ &sdhci1 {
>   	vqmmc-supply = <&vddshv_sdio>;
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&main_mmc1_pins_default>;
> -	ti,driver-strength-ohm = <50>;
>   	disable-wp;
>   	bootph-all;
>   };
> diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
> index 6dd496cd459a..3c45782ab2b7 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
> @@ -411,7 +411,6 @@ &sdhci0 {
>   	status = "okay";
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&main_mmc0_pins_default>;
> -	ti,driver-strength-ohm = <50>;
>   	disable-wp;
>   };
>   
> @@ -421,7 +420,6 @@ &sdhci1 {
>   	status = "okay";
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&main_mmc1_pins_default>;
> -	ti,driver-strength-ohm = <50>;
>   	disable-wp;
>   };
>   
> diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
> index 9bfa0a969bfc..a29847735c6e 100644
> --- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
> @@ -646,7 +646,6 @@ sdhci1: mmc at fa00000 {
>   		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>   		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
>   		clock-names = "clk_ahb", "clk_xin";
> -		ti,trm-icp = <0x2>;
>   		ti,otap-del-sel-legacy = <0x0>;
>   		ti,otap-del-sel-sd-hs = <0x0>;
>   		ti,otap-del-sel-sdr12 = <0xf>;
> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> index 5c546ae76d3e..f308076d608a 100644
> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
> @@ -508,7 +508,6 @@ &sdhci1 {
>   	pinctrl-names = "default";
>   	bus-width = <4>;
>   	pinctrl-0 = <&main_mmc1_pins_default>;
> -	ti,driver-strength-ohm = <50>;
>   	disable-wp;
>   };
>   
> diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
> index cce04e188ff6..b286eaa02ada 100644
> --- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
> @@ -471,7 +471,6 @@ &sdhci1 {
>   	pinctrl-names = "default";
>   	bus-width = <4>;
>   	pinctrl-0 = <&main_mmc1_pins_default>;
> -	ti,driver-strength-ohm = <50>;
>   	disable-wp;
>   };
>   


From zajec5 at gmail.com  Mon Feb 12 21:37:37 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 13 Feb 2024 06:37:37 +0100
Subject: [PATCH 1/3] arm64: dts: mediatek: mt7986: drop invalid properties from ethsys
Message-ID: <20240213053739.14387-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Mediatek ethsys controller / syscon binding doesn't allow any subnodes
so "#address-cells" and "#size-cells" are redundant (actually:
disallowed).

This fixes:
arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: syscon at 15000000: '#address-cells', '#size-cells' do not match any of the regexes: 'pinctrl-[0-9]+'
        from schema $id: http://devicetree.org/schemas/clock/mediatek,ethsys.yaml#

Fixes: 1f9986b258c2 ("arm64: dts: mediatek: add clock support for mt7986a")
Cc: Sam Shih <sam.shih at mediatek.com>
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index b3f416b9a7a4..228e02954e85 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -492,8 +492,6 @@ ethsys: syscon at 15000000 {
 			 compatible = "mediatek,mt7986-ethsys",
 				      "syscon";
 			 reg = <0 0x15000000 0 0x1000>;
-			 #address-cells = <1>;
-			 #size-cells = <1>;
 			 #clock-cells = <1>;
 			 #reset-cells = <1>;
 		};
-- 
2.35.3



From zajec5 at gmail.com  Mon Feb 12 21:37:38 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 13 Feb 2024 06:37:38 +0100
Subject: [PATCH 2/3] arm64: dts: mediatek: mt7986: drop "#reset-cells" from Ethernet controller
In-Reply-To: <20240213053739.14387-1-zajec5@gmail.com>
References: <20240213053739.14387-1-zajec5@gmail.com>
Message-ID: <20240213053739.14387-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Ethernet block doesn't include or act as a reset controller.
Documentation also doesn't document "#reset-cells" for it.

This fixes:
arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: ethernet at 15100000: Unevaluated properties are not allowed ('#reset-cells' was unexpected)
        from schema $id: http://devicetree.org/schemas/net/mediatek,net.yaml#

Fixes: 082ff36bd5c0 ("arm64: dts: mediatek: mt7986: introduce ethernet nodes")
Cc: Lorenzo Bianconi <lorenzo at kernel.org>
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index 228e02954e85..f3a2a89fada4 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -554,7 +554,6 @@ eth: ethernet at 15100000 {
 					  <&topckgen CLK_TOP_SGM_325M_SEL>;
 			assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
 						 <&apmixedsys CLK_APMIXED_SGMPLL>;
-			#reset-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			mediatek,ethsys = <&ethsys>;
-- 
2.35.3



From zajec5 at gmail.com  Mon Feb 12 21:37:39 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 13 Feb 2024 06:37:39 +0100
Subject: [PATCH 3/3] arm64: dts: mediatek: mt7986: drop invalid thermal block clock
In-Reply-To: <20240213053739.14387-1-zajec5@gmail.com>
References: <20240213053739.14387-1-zajec5@gmail.com>
Message-ID: <20240213053739.14387-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Thermal block uses only two clocks. Its binding doesn't document or
allow "adc_32k". Also Linux driver doesn't support it.

It has been additionally verified by Angelo by his detailed research on
MT7981 / MT7986 clocks (thanks!).

This fixes:
arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: thermal at 1100c800: clocks: [[4, 27], [4, 44], [4, 45]] is too long
        from schema $id: http://devicetree.org/schemas/thermal/mediatek,thermal.yaml#
arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: thermal at 1100c800: clock-names: ['therm', 'auxadc', 'adc_32k'] is too long
        from schema $id: http://devicetree.org/schemas/thermal/mediatek,thermal.yaml#

Fixes: 0a9615d58d04 ("arm64: dts: mt7986: add thermal and efuse")
Cc: Daniel Golle <daniel at makrotopia.org>
Link: https://lore.kernel.org/linux-devicetree/17d143aa-576e-4d67-a0ea-b79f3518b81c at collabora.com/
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index f3a2a89fada4..559990dcd1d1 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -332,9 +332,8 @@ thermal: thermal at 1100c800 {
 			reg = <0 0x1100c800 0 0x800>;
 			interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&infracfg CLK_INFRA_THERM_CK>,
-				 <&infracfg CLK_INFRA_ADC_26M_CK>,
-				 <&infracfg CLK_INFRA_ADC_FRC_CK>;
-			clock-names = "therm", "auxadc", "adc_32k";
+				 <&infracfg CLK_INFRA_ADC_26M_CK>;
+			clock-names = "therm", "auxadc";
 			nvmem-cells = <&thermal_calibration>;
 			nvmem-cell-names = "calibration-data";
 			#thermal-sensor-cells = <1>;
-- 
2.35.3



From quic_sibis at quicinc.com  Mon Feb 12 21:40:22 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 13 Feb 2024 11:10:22 +0530
Subject: [PATCH V2 1/4] firmware: arm_scmi: Add perf_notify_support
 interface
In-Reply-To: <ZcoSuv7qwexbXy-9@pluto>
References: <20240117104116.2055349-1-quic_sibis@quicinc.com>
 <20240117104116.2055349-2-quic_sibis@quicinc.com> <ZbfJN1c9viiLhO1L@pluto>
 <ZbfhdqBBpjyf3IRI@pluto> <20240131112854.24euh6c6xgljsj6c@bogus>
 <ZcoSuv7qwexbXy-9@pluto>
Message-ID: <d0b47ead-0e39-a303-66bf-43d7e3bd3fd6@quicinc.com>



On 2/12/24 18:14, Cristian Marussi wrote:
> On Wed, Jan 31, 2024 at 11:28:54AM +0000, Sudeep Holla wrote:
>> On Mon, Jan 29, 2024 at 05:33:42PM +0000, Cristian Marussi wrote:
> 
> Hi Sibi,
> 
>>> On Mon, Jan 29, 2024 at 03:50:20PM +0000, Cristian Marussi wrote:
>>>> On Wed, Jan 17, 2024 at 04:11:13PM +0530, Sibi Sankar wrote:
>>>>> Add a new perf_notify_support interface to the existing perf_ops to export
>>>>> info regarding limit/level change notification support.
>>>>>
>>>>
>>>> Hi Sibi,
>>>>
>>>> as I mentioned previously, in order not to add a needless stream of SCMI
>>>> Perf accessors I posted this:
>>>>
>>>> https://lore.kernel.org/linux-arm-kernel/20240129151002.1215333-1-cristian.marussi at arm.com/T/#u
>>>>
>>>> to expose all the Perf domains infos via the usual info_get(), similarly
>>>> to how other SCMI protocols do already.
>>>>
>>>> I think that reworking this series on that, you can certainly drop this patch and just
>>>> check the _notify booleans on the retrieved domain info.
>>>
>>> Sorry, but hold on with this change, I will probably post an updated version
>>> my patch above.
>>>
>>
>> As discussed in private, I would prefer to avoid exposing all the internals
>> to the users of SCMI perf. At the same time may we can do better if we can
>> check the availability of notification as part of notification enablement
>> from the SCMI driver, I need to think the details yet.
>>
> 
> as previously mentioned, after speaking with Sudeep, I posted a new
> series at [1], that aims to solve your problem with registering
> notifications and looking up reported Perf frequencies in a new way.
> 
> Using the changes at [1] you should be able to:
> 
> - register your notifier without caring to check if the notification
>    is supported, since the SCMI core will take care of checking that and
>    report an error if not supported, without sending any unneeded
>    attempted notification enable message  (so you can drop 1/4 in this
>    series)
> 
> - retrieve the pre-calculated OPPs frequencies from the new extended
>    Perf notifications reports no matter if the system if operating in
>    level_indexing_mode or not. (so you can drop 2/4 in this series)

Christian/Sudeep,

Thanks a lot for spending time on this and simplifying the series.

Will re-spin the series with your recommendations.

-Sibi

> 
> Thanks,
> Cristian
> 
> [1]: https://lore.kernel.org/linux-arm-kernel/20240212123233.1230090-1-cristian.marussi at arm.com/T/#ma68cefd753e34ba3e1f2d4392e978026a87e1bf8
> 


From quic_sibis at quicinc.com  Mon Feb 12 21:42:17 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 13 Feb 2024 11:12:17 +0530
Subject: [PATCH V2 4/4] cpufreq: scmi: Register for limit change
 notifications
In-Reply-To: <ZbfLdvi_sePXiVmM@pluto>
References: <20240117104116.2055349-1-quic_sibis@quicinc.com>
 <20240117104116.2055349-5-quic_sibis@quicinc.com> <ZbfLdvi_sePXiVmM@pluto>
Message-ID: <849d8cd7-ca74-e9ed-851b-01addde05f1b@quicinc.com>



On 1/29/24 21:29, Cristian Marussi wrote:
> On Wed, Jan 17, 2024 at 04:11:16PM +0530, Sibi Sankar wrote:
>> Register for limit change notifications if supported with the help of
>> perf_notify_support interface and determine the throttled frequency
>> using the perf_freq_xlate to apply HW pressure.
>>

Christian,

Thanks for taking time to review the series.

>> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
>> ---
>>
>> v2:
>> * Export cpufreq_update_pressure and use it directly [Lukasz]
>>
>>   drivers/cpufreq/scmi-cpufreq.c | 42 +++++++++++++++++++++++++++++++++-
>>   1 file changed, 41 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
>> index 4ee23f4ebf4a..e0aa85764451 100644
>> --- a/drivers/cpufreq/scmi-cpufreq.c
>> +++ b/drivers/cpufreq/scmi-cpufreq.c
>> @@ -25,9 +25,13 @@ struct scmi_data {
>>   	int domain_id;
>>   	int nr_opp;
>>   	struct device *cpu_dev;
>> +	struct cpufreq_policy *policy;
>>   	cpumask_var_t opp_shared_cpus;
>> +	struct notifier_block limit_notify_nb;
>>   };
>>   
>> +const struct scmi_handle *handle;
>> +static struct scmi_device *scmi_dev;
>>   static struct scmi_protocol_handle *ph;
>>   static const struct scmi_perf_proto_ops *perf_ops;
>>   
>> @@ -144,6 +148,22 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
>>   	return 0;
>>   }
>>   
>> +static int scmi_limit_notify_cb(struct notifier_block *nb, unsigned long event, void *data)
>> +{
>> +	unsigned long freq_hz;
>> +	struct scmi_perf_limits_report *limit_notify = data;
>> +	struct scmi_data *priv = container_of(nb, struct scmi_data, limit_notify_nb);
>> +	struct cpufreq_policy *policy = priv->policy;
>> +
>> +	if (perf_ops->perf_freq_xlate(ph, priv->domain_id, limit_notify->range_max, &freq_hz))
>> +		return NOTIFY_OK;
>> +
>> +	policy->max = freq_hz / HZ_PER_KHZ;
>> +	cpufreq_update_pressure(policy);
>> +
>> +	return NOTIFY_OK;
>> +}
>> +
>>   static int scmi_cpufreq_init(struct cpufreq_policy *policy)
>>   {
>>   	int ret, nr_opp, domain;
>> @@ -151,6 +171,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
>>   	struct device *cpu_dev;
>>   	struct scmi_data *priv;
>>   	struct cpufreq_frequency_table *freq_table;
>> +	struct scmi_perf_notify_info info = {};
>>   
>>   	cpu_dev = get_cpu_device(policy->cpu);
>>   	if (!cpu_dev) {
>> @@ -250,6 +271,25 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
>>   	policy->fast_switch_possible =
>>   		perf_ops->fast_switch_possible(ph, domain);
>>   
>> +	ret = perf_ops->perf_notify_support(ph, domain, &info);
>> +	if (ret)
>> +		dev_warn(cpu_dev, "failed to get supported notifications: %d\n", ret);
>> +
>> +	if (info.perf_limit_notify) {
>> +		priv->limit_notify_nb.notifier_call = scmi_limit_notify_cb;
>> +		ret = handle->notify_ops->devm_event_notifier_register(scmi_dev, SCMI_PROTOCOL_PERF,
>> +							SCMI_EVENT_PERFORMANCE_LIMITS_CHANGED,
>> +							&domain,
>> +							&priv->limit_notify_nb);
>> +		if (ret) {
>> +			dev_err(cpu_dev, "Error in registering limit change notifier for domain %d\n",
>> +				domain);
>> +			return ret;
>> +		}
> 
> Is there a reason to fail completely here if it was not possible to register
> the notifier ? (even though expected to succeed given perf_limit_notify
> was true...)
> 
> Maybe a big fat warn that the system perf could be degraded, but
> carrying on ?
> 
> Or maybe you have in mind a good reason to fail like you did, so please
> explain in that case in a comment.

ack a warn should suffice here

-Sibi

> 
> Thanks,
> Cristian


From quic_sibis at quicinc.com  Mon Feb 12 21:46:03 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 13 Feb 2024 11:16:03 +0530
Subject: [PATCH V2 4/4] cpufreq: scmi: Register for limit change
 notifications
In-Reply-To: <512d7296-2706-4779-b475-fbf2d208e282@arm.com>
References: <20240117104116.2055349-1-quic_sibis@quicinc.com>
 <20240117104116.2055349-5-quic_sibis@quicinc.com>
 <512d7296-2706-4779-b475-fbf2d208e282@arm.com>
Message-ID: <145277d6-ddb5-6dd6-c534-d92ea2d1ff28@quicinc.com>



On 1/31/24 19:59, Pierre Gondois wrote:
> Hello Sibi,
> 
> On 1/17/24 11:41, Sibi Sankar wrote:
>> Register for limit change notifications if supported with the help of
>> perf_notify_support interface and determine the throttled frequency
>> using the perf_freq_xlate to apply HW pressure.
>>

Hey Pierre,

Thanks for taking time to review the series.

>> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
>> ---
>>
>> v2:
>> * Export cpufreq_update_pressure and use it directly [Lukasz]
>>
>> ? drivers/cpufreq/scmi-cpufreq.c | 42 +++++++++++++++++++++++++++++++++-
>> ? 1 file changed, 41 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/cpufreq/scmi-cpufreq.c 
>> b/drivers/cpufreq/scmi-cpufreq.c
>> index 4ee23f4ebf4a..e0aa85764451 100644
>> --- a/drivers/cpufreq/scmi-cpufreq.c
>> +++ b/drivers/cpufreq/scmi-cpufreq.c
>> @@ -25,9 +25,13 @@ struct scmi_data {
>> ????? int domain_id;
>> ????? int nr_opp;
>> ????? struct device *cpu_dev;
>> +??? struct cpufreq_policy *policy;
>> ????? cpumask_var_t opp_shared_cpus;
>> +??? struct notifier_block limit_notify_nb;
>> ? };
>> +const struct scmi_handle *handle;
>> +static struct scmi_device *scmi_dev;
>> ? static struct scmi_protocol_handle *ph;
>> ? static const struct scmi_perf_proto_ops *perf_ops;
>> @@ -144,6 +148,22 @@ scmi_get_cpu_power(struct device *cpu_dev, 
>> unsigned long *power,
>> ????? return 0;
>> ? }
>> +static int scmi_limit_notify_cb(struct notifier_block *nb, unsigned 
>> long event, void *data)
>> +{
>> +??? unsigned long freq_hz;
>> +??? struct scmi_perf_limits_report *limit_notify = data;
>> +??? struct scmi_data *priv = container_of(nb, struct scmi_data, 
>> limit_notify_nb);
>> +??? struct cpufreq_policy *policy = priv->policy;
>> +
>> +??? if (perf_ops->perf_freq_xlate(ph, priv->domain_id, 
>> limit_notify->range_max, &freq_hz))
>> +??????? return NOTIFY_OK;
>> +
>> +??? policy->max = freq_hz / HZ_PER_KHZ;
> 
> Maybe 'policy->max' should be checked. The limits received by SCMI is 
> blindly
> trusted. This might be ok, but could also lead to some inconsistency.
> 
> The scmi_cpufreq_driver's verify() callback could be used.

ack, will fix this in the next re-spin.

> 
> ---
> 
> I think there might also be corner cases where the SCP might advertise
> the maximum boosted frequency as the max limit, but boosting might not
> be enabled on the kernel side.
> So I think this should be checked when setting 'policy->max',

ack

-Sibi
> 
> Regards,
> Pierre
> 
[...]
>> ????? if (!handle)


From vigneshr at ti.com  Mon Feb 12 22:09:37 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 13 Feb 2024 11:39:37 +0530
Subject: [PATCH v5 0/5] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
In-Reply-To: <b918364e-cfca-4342-acc2-2b51bad75596@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
 <359993c5-3387-443c-8cef-30ee7ad1f521@ti.com>
 <b918364e-cfca-4342-acc2-2b51bad75596@solid-run.com>
Message-ID: <57d24319-eabb-48d6-b5a0-cab333c9cc68@ti.com>



On 12/02/24 22:09, Josua Mayer wrote:
> Hi Vignesh,
> 
> Am 12.02.24 um 05:10 schrieb Vignesh Raghavendra:
>> Hi Josua,
>>
>> On 11/02/24 20:37, Josua Mayer wrote:
>>> This series adds DT bindings and dts descriptions for SolidRun AM642
>>> based SoM and Hummingboard EVB.
>>>
>>> Additionally a commit from downstream vendor kernel are included,
>>> enhancing support for pru based ethernet.
>>> I wasn't sure how to properly annotate it in commit description /
>>> signed-off area ...:
>>>
>>> 1. add description for "Industrial Ethernet Peripherals" (IEP) to am64
>>>    https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/commit/arch/arm64/boot/dts/ti/k3-am64-main.dtsi?h=ti-linux-6.1.y-cicd&id=5afb73d82a014b59462162d960b350b8c58e5ae6
>>>    IEP is already supported in-tree by a driver, and used in
>>>    k3-am65-main.dtsi.
>>>
>>> Unfortunately dtbs_check reported many problems, I put some remarks:
>>>
>>> - 'mux-controller' does not match any of the regexes
>>>   The expectation seems to be that a mux-controller at minimum has an
>>>   address, something to put behind an @. However this is a gpio mux, not
>>>   sure how to name it better.
>>>
>> I don't see this warning locally. Are you using updated dt-schema?
> pip3 install dtschema --upgrade
> Defaulting to user installation because normal site-packages is not writeable
> Requirement already satisfied: dtschema in ~/.local/lib/python3.11/site-packages (2023.11)
> 
> Re-Tested on 6.8-rc1
> 
>> reg
>> is not necessary gpio-mux as per gpio-mux.yaml
> The error is not about reg property, it is about the node name:
> 
> mux-controller {
> ??? compatible = "gpio-mux";
> ??? ...
> };
> 
> ? DTC_CHK arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb
> .../arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb: syscon at 43000000: 'mux-controller' does not match any of the regexes: '^chipid@[0-9a-f]+$', '^clock-controller@[0-9a-f]+$', '^mux-controller@[0-9a-f]+$', 'phy@[0-9a-f]+$', 'pinctrl-[0-9]+'
> ?????? from schema $id: http://devicetree.org/schemas/mfd/ti,j721e-system-controller.yaml#

This warning exists not because of gpio-mux but because of SoC level
(k3-am64-main.dtsi) dtsi issue. There is a separate series to fix the
same. So this should be okay to ignore for now.


>>
>>> - unevaluated properties: interrupts, interrupt-parent
>>>   sensors and flash yaml are missing interrupt descriptions, but these
>>>   parts definitely have an interrupt signal in this solidrun board.
>>>
>> Please add them to appropriate schema as necessary
> Okay.
> Looks like it is only two:

> .../arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb: humidity-sensor at 41: 'interrupt-parent', 'interrupts' do not match any of the regexes: 'pinctrl-[0-9]+'
> ???????from schema $id: http://devicetree.org/schemas/iio/humidity/ti,hdc2010.yaml#
> .../arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dtb: flash at 0: Unevaluated properties are not allowed ('interrupt-parent', 'interrupts' were unexpected)
> ???????from schema $id: http://devicetree.org/schemas/mtd/jedec,spi-nor.yaml#

Yup, thanks!


you could post a cut down version of the dts with all the problematic
nodes removed until yaml updates are merged, so as to get the basic
support in.


>>
>>> - wrong names for pinctrl nodes
>>>   Other TI DTSs consistently end with *-pins-default. Should a different
>>>   naming convention be used?
>>>
>> No, pinctrl nodes need to end in -pins. All TI boards have been updated
>> to new schema [0] and sysconfig tool on dev.ti.com/sysconfig generates
>> appropriately. Please fix
> Okay, will do ...
>>
>>
>>> - cdns,phy-type required property
>>>   inherited from k3-am64-main.dtsi
>>>   there is a PHY_NONE value in dt-bindings/phy/phy.h,
>>>   but not allowed in phy-cadence-torrent.yaml
>>>
>> Sorry, I didnt get what's the issue wrt cdns,phy-type ?
> There were two issues, but they both disappeared as per 6.8-rc1 :)
>>

That's nice!


-- 
Regards
Vignesh


From vigneshr at ti.com  Mon Feb 12 22:12:31 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 13 Feb 2024 11:42:31 +0530
Subject: [PATCH v5 0/5] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
In-Reply-To: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
Message-ID: <8aa96c66-d054-4b33-8972-f9faf2e84482@ti.com>

Hi

[...]

On 11/02/24 20:37, Josua Mayer wrote:
> ---
> Josua Mayer (4):
>       dt-bindings: arm: ti: Add bindings for SolidRun AM642 HummingBoard-T


>       dt-bindings: rtc: abx80x: convert to yaml

2/5 needs to go via RTC subsystem tree. Could you split it out into its
own series when you respin

Rest will go via TI K3 arch tree.


>       arm64: dts: add description for solidrun am642 som and evaluation board
>       arm64: dts: ti: hummingboard-t: add overlays for m.2 pci-e and usb-3
> 
> Suman Anna (1):
>       arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
> 
>  Documentation/devicetree/bindings/arm/ti/k3.yaml   |   7 +
>  .../devicetree/bindings/rtc/abracon,abx80x.txt     |  31 --
>  .../devicetree/bindings/rtc/abracon,abx80x.yaml    |  79 +++
>  arch/arm64/boot/dts/ti/Makefile                    |   7 +
>  arch/arm64/boot/dts/ti/k3-am64-main.dtsi           |  24 +
>  .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  |  45 ++
>  .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  |  44 ++
>  arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
>  arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 594 +++++++++++++++++++++
>  9 files changed, 1092 insertions(+), 31 deletions(-)
> ---
> base-commit: 798d1ee1675be84d5c7eb639480aab33f2c8791e
> change-id: 20240101-add-am64-som-51a1ca47edf3
> 
> Sincerely,

-- 
Regards
Vignesh


From s-vadapalli at ti.com  Mon Feb 12 22:13:17 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Tue, 13 Feb 2024 11:43:17 +0530
Subject: [PATCH v3] dt-bindings: PCI: ti,j721e-pci-host: Add support for
 J722S SoC
In-Reply-To: <20240124-unmatched-plating-019a3055cf5e@spud>
References: <20240124122936.816142-1-s-vadapalli@ti.com>
 <20240124-unmatched-plating-019a3055cf5e@spud>
Message-ID: <619dd947-a3da-49ee-9bee-8b21c7e7ca1a@ti.com>



On 24/01/24 21:40, Conor Dooley wrote:
> On Wed, Jan 24, 2024 at 05:59:36PM +0530, Siddharth Vadapalli wrote:
>> TI's J722S SoC has one instance of a Gen3 Single-Lane PCIe controller.
>> The controller on J722S SoC is similar to the one present on TI's AM64
>> SoC, with the difference being that the controller on AM64 SoC supports
>> up to Gen2 link speed while the one on J722S SoC supports Gen3 link speed.
>>
>> Update the bindings with a new compatible for J722S SoC.
>>
>> Technical Reference Manual of J722S SoC: https://www.ti.com/lit/zip/sprujb3
>>
>> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
> 
> Acked-by: Conor Dooley <conor.dooley at microchip.com>

Bjorn, Rob,

Could you please merge this patch? This patch applies cleanly on the latest
linux-next tagged next-20240213.

> 
> Cheers,
> Conor.
> 
>> ---
>>
>> Hello,
>>
>> This patch is based on linux-next tagged next-20240124.
>>
>> v2:
>> https://lore.kernel.org/r/20240122064457.664542-1-s-vadapalli at ti.com/
>> Changes since v2:
>> - Added fallback compatible for "ti,j722s-pcie-host" as
>>   "ti,j721e-pcie-host" based on Conor's suggestion at:
>>   https://lore.kernel.org/r/20240122-getting-drippy-bb22a0634092 at spud/#t
>>
>> v1:
>> https://lore.kernel.org/r/20240117102526.557006-1-s-vadapalli at ti.com/
>> Changes since v1:
>> - Dropped patches 1/3 and 2/3 of the v1 series as discussed in the v1
>>   thread.
>> - Updated patch 3/3 which is the v1 for this patch by dropping the checks
>>   for the "num-lanes" property and "max-link-speed" property since the PCI
>>   driver already validates the "num-lanes" property.
>>
>> Regards,
>> Siddharth.
>>
>>  Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
>> index b7a534cef24d..ac69deeaf1ee 100644
>> --- a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
>> +++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
>> @@ -23,6 +23,10 @@ properties:
>>          items:
>>            - const: ti,j7200-pcie-host
>>            - const: ti,j721e-pcie-host
>> +      - description: PCIe controller in J722S
>> +        items:
>> +          - const: ti,j722s-pcie-host
>> +          - const: ti,j721e-pcie-host
>>  
>>    reg:
>>      maxItems: 4
>> -- 
>> 2.34.1
>>

-- 
Regards,
Siddharth.


From zajec5 at gmail.com  Mon Feb 12 22:14:59 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 13 Feb 2024 07:14:59 +0100
Subject: [PATCH] arm64: dts: mediatek: mt7986: prefix BPI-R3 cooling maps with "map-"
Message-ID: <20240213061459.17917-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This fixes:
arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: thermal-zones: cpu-thermal:cooling-maps: 'cpu-active-high', 'cpu-active-low', 'cpu-active-med' do not match any of the regexes: '^map[-a-zA-Z0-9]*$', 'pinctrl-[0-9]+'
        from schema $id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#

Fixes: c26f779a2295 ("arm64: dts: mt7986: add pwm-fan and cooling-maps to BPI-R3 dts")
Cc: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
index e04b1c0c0ebb..ed79ad1ae871 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
@@ -146,19 +146,19 @@ sfp2: sfp-2 {
 
 &cpu_thermal {
 	cooling-maps {
-		cpu-active-high {
+		map-cpu-active-high {
 			/* active: set fan to cooling level 2 */
 			cooling-device = <&fan 2 2>;
 			trip = <&cpu_trip_active_high>;
 		};
 
-		cpu-active-med {
+		map-cpu-active-med {
 			/* active: set fan to cooling level 1 */
 			cooling-device = <&fan 1 1>;
 			trip = <&cpu_trip_active_med>;
 		};
 
-		cpu-active-low {
+		map-cpu-active-low {
 			/* active: set fan to cooling level 0 */
 			cooling-device = <&fan 0 0>;
 			trip = <&cpu_trip_active_low>;
-- 
2.35.3



From quic_pbrahma at quicinc.com  Mon Feb 12 22:26:08 2024
From: quic_pbrahma at quicinc.com (Pratyush Brahma)
Date: Tue, 13 Feb 2024 11:56:08 +0530
Subject: [PATCH 1/1] iommu/arm-smmu-qcom: Fix use-after-free issue in qcom_smmu_create()
In-Reply-To: <20240201210529.7728-4-quic_c_gdjako@quicinc.com>
References: <20240201210529.7728-4-quic_c_gdjako@quicinc.com>
Message-ID: <20240213062608.13018-1-quic_pbrahma@quicinc.com>

Currently, during arm smmu probe, struct arm_smmu_device pointer
is allocated. The pointer is reallocated to a new struct qcom_smmu in
qcom_smmu_create() with devm_krealloc() which frees the smmu device
after copying the data into the new pointer.

The freed pointer is then passed again in devm_of_platform_populate()
inside qcom_smmu_create() which causes a use-after-free issue.

Fix the use-after-free issue by reassigning the old pointer to
the new pointer where the struct was copied by devm_krealloc().

Signed-off-by: Pratyush Brahma <quic_pbrahma at quicinc.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index ed5ed5da7740..49eaeed6a91c 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -710,6 +710,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
 	qsmmu = devm_krealloc(smmu->dev, smmu, sizeof(*qsmmu), GFP_KERNEL);
 	if (!qsmmu)
 		return ERR_PTR(-ENOMEM);
+	smmu = &qsmmu->smmu;
 
 	qsmmu->smmu.impl = impl;
 	qsmmu->data = data;
@@ -719,7 +720,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
 	if (ret)
 		return ERR_PTR(ret);
 
-	return &qsmmu->smmu;
+	return smmu;
 }
 
 /* Implementation Defined Register Space 0 register offsets */
-- 
2.17.1



From zajec5 at gmail.com  Mon Feb 12 22:39:19 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 13 Feb 2024 07:39:19 +0100
Subject: [PATCH] dt-bindings: dma: convert MediaTek High-Speed controller to the json-schema
Message-ID: <20240213063919.20196-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Adjusted "reg" in example
2. Added includes to example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../bindings/dma/mediatek,mt7622-hsdma.yaml   | 63 +++++++++++++++++++
 .../devicetree/bindings/dma/mtk-hsdma.txt     | 33 ----------
 2 files changed, 63 insertions(+), 33 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mediatek,mt7622-hsdma.yaml
 delete mode 100644 Documentation/devicetree/bindings/dma/mtk-hsdma.txt

diff --git a/Documentation/devicetree/bindings/dma/mediatek,mt7622-hsdma.yaml b/Documentation/devicetree/bindings/dma/mediatek,mt7622-hsdma.yaml
new file mode 100644
index 000000000000..3f1e120e40a3
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mediatek,mt7622-hsdma.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/mediatek,mt7622-hsdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek High-Speed DMA Controller
+
+maintainers:
+  - Sean Wang <sean.wang at mediatek.com>
+
+allOf:
+  - $ref: dma-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7622-hsdma
+      - mediatek,mt7623-hsdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: hsdma
+
+  power-domains:
+    maxItems: 1
+
+  "#dma-cells":
+    description: Channel number
+    const: 1
+
+required:
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - power-domains
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt2701-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/mt2701-power.h>
+
+    dma-controller at 1b007000 {
+        compatible = "mediatek,mt7623-hsdma";
+        reg = <0x1b007000 0x1000>;
+        interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_LOW>;
+        clocks = <&ethsys CLK_ETHSYS_HSDMA>;
+        clock-names = "hsdma";
+        power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
+        #dma-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/dma/mtk-hsdma.txt b/Documentation/devicetree/bindings/dma/mtk-hsdma.txt
deleted file mode 100644
index 4bb317359dc6..000000000000
--- a/Documentation/devicetree/bindings/dma/mtk-hsdma.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-MediaTek High-Speed DMA Controller
-==================================
-
-This device follows the generic DMA bindings defined in dma/dma.txt.
-
-Required properties:
-
-- compatible:	Must be one of
-		  "mediatek,mt7622-hsdma": for MT7622 SoC
-		  "mediatek,mt7623-hsdma": for MT7623 SoC
-- reg:		Should contain the register's base address and length.
-- interrupts:	Should contain a reference to the interrupt used by this
-		device.
-- clocks:	Should be the clock specifiers corresponding to the entry in
-		clock-names property.
-- clock-names:	Should contain "hsdma" entries.
-- power-domains: Phandle to the power domain that the device is part of
-- #dma-cells: 	The length of the DMA specifier, must be <1>. This one cell
-		in dmas property of a client device represents the channel
-		number.
-Example:
-
-        hsdma: dma-controller at 1b007000 {
-		compatible = "mediatek,mt7623-hsdma";
-		reg = <0 0x1b007000 0 0x1000>;
-		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_LOW>;
-		clocks = <&ethsys CLK_ETHSYS_HSDMA>;
-		clock-names = "hsdma";
-		power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
-		#dma-cells = <1>;
-	};
-
-DMA clients must use the format described in dma/dma.txt file.
-- 
2.35.3



From clabbe.montjoie at gmail.com  Mon Feb 12 23:21:12 2024
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 13 Feb 2024 08:21:12 +0100
Subject: [PATCH v4 00/20] Support more Amlogic SoC families in crypto
 driver
In-Reply-To: <20240212135108.549755-1-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
Message-ID: <ZcsYaPIUrBSg8iXu@Red>

Le Mon, Feb 12, 2024 at 04:50:48PM +0300, Alexey Romanov a ?crit :
> Hello!
> 
> This patchset expand the funcionality of the Amlogic
> crypto driver by adding support for more SoC families:
> AXG, G12A, G12B, SM1, A1, S4.
> 
> Also specify and enable crypto node in device tree
> for reference Amlogic devices.
> 
> Tested on AXG, G12A/B, SM1, A1 and S4 devices via
> custom tests [1] and tcrypt module.
> 
> ---
> 

I started to test on Lepotato board and added patchs up to  "drivers: crypto: meson: process more than MAXDESCS descriptors"
booting lead to:
[   18.559922] gxl-crypto c883e000.crypto: will run requests pump with realtime priority
[   18.562492] gxl-crypto c883e000.crypto: will run requests pump with realtime priority
[   18.570328] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
[   18.581135] Mem abort info:
[   18.581354]   ESR = 0x0000000096000006
[   18.585138]   EC = 0x25: DABT (current EL), IL = 32 bits
[   18.593005]   SET = 0, FnV = 0
[   18.593334]   EA = 0, S1PTW = 0
[   18.597329]   FSC = 0x06: level 2 translation fault
[   18.604250] Data abort info:
[   18.604282]   ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
[   18.612243]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[   18.614552]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[   18.624249] user pgtable: 4k pages, 48-bit VAs, pgdp=000000007b8ab000
[   18.626196] [0000000000000028] pgd=080000007b8ac003, p4d=080000007b8ac003, pud=080000007b8ad003, pmd=0000000000000000
[   18.640426] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
[   18.642929] Modules linked in: of_mdio fixed_phy fwnode_mdio sm4_ce(-) sm4 meson_rng meson_canvas libphy rng_core meson_gxbb_wdt watchdog amlogic_gxl_crypto(+) ghash_generic gcm xctr xts cts essiv authenc cmac xcbc ccm
[   18.662164] CPU: 3 PID: 264 Comm: cryptomgr_test Not tainted 6.8.0-rc1-00052-gf70f2b0814a0 #11
[   18.670698] Hardware name: Libre Computer AML-S905X-CC (DT)
[   18.676220] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   18.683118] pc : meson_get_engine_number+0x2c/0x50 [amlogic_gxl_crypto]
[   18.689674] lr : meson_skencrypt+0x38/0x8c [amlogic_gxl_crypto]
[   18.695539] sp : ffff800081393790
[   18.698816] x29: ffff800081393790 x28: 0000000000000400 x27: ffff800080874a80
[   18.705888] x26: ffff800081393830 x25: ffff800081393bd8 x24: ffff000001aaa000
[   18.712961] x23: 0000000000000001 x22: 0000000000000000 x21: ffff0000011b1c50
[   18.720033] x20: ffff00007bac8248 x19: ffff0000011b1c00 x18: ffffffffffffffff
[   18.727105] x17: 00000000000001a4 x16: ffff800078edc1f0 x15: ffff8000813938e0
[   18.734178] x14: ffff800101393bd7 x13: 0000000000000000 x12: 0000000000000000
[   18.741250] x11: 000000000000021c x10: fffffffff81213e0 x9 : 00000000000730d5
[   18.748323] x8 : ffff0000011b1ca8 x7 : fefefefefefefefe x6 : fffffc000007a302
[   18.755395] x5 : ffff800078eb4148 x4 : 0000000000000000 x3 : 0000000000000028
[   18.762468] x2 : ffff000001aaa040 x1 : 0000000000000000 x0 : 0000000000000000
[   18.769541] Call trace:
[   18.771956]  meson_get_engine_number+0x2c/0x50 [amlogic_gxl_crypto]
[   18.778167]  crypto_skcipher_encrypt+0xe0/0x124
[   18.782651]  test_skcipher_vec_cfg+0x2a8/0x6b0
[   18.787050]  test_skcipher_vec+0x80/0x1c4
[   18.791017]  alg_test_skcipher+0xbc/0x1fc
[   18.794985]  alg_test+0x140/0x628
[   18.798262]  cryptomgr_test+0x24/0x44
[   18.801885]  kthread+0x110/0x114
[   18.805076]  ret_from_fork+0x10/0x20
[   18.808617] Code: 1b008440 d65f03c0 9100a003 f9800071 (885f7c61) 
[   18.814651] ---[ end trace 0000000000000000 ]---
[   18.862270] meson8b-dwmac c9410000.ethernet: IRQ eth_wake_irq not found
[   18.863897] meson8b-dwmac c9410000.ethernet: IRQ eth_lpi not found
[   18.870349] meson8b-dwmac c9410000.ethernet: PTP uses main clock
[   18.880548] meson8b-dwmac c9410000.ethernet: User ID: 0x11, Synopsys ID: 0x37
[   18.882403] meson8b-dwmac c9410000.ethernet: 	DWMAC1000
[   18.887926] meson8b-dwmac c9410000.ethernet: DMA HW capability register supported
[   18.895215] meson8b-dwmac c9410000.ethernet: RX Checksum Offload Engine supported
[   18.902627] meson8b-dwmac c9410000.ethernet: COE Type 2
[   18.907756] meson8b-dwmac c9410000.ethernet: TX Checksum insertion supported
[   18.914750] meson8b-dwmac c9410000.ethernet: Wake-Up On Lan supported
[   18.921246] meson8b-dwmac c9410000.ethernet: Normal descriptors
[   18.927017] meson8b-dwmac c9410000.ethernet: Ring mode enabled
[   18.932782] meson8b-dwmac c9410000.ethernet: Enable RX Mitigation via HW Watchdog Timer


From zajec5 at gmail.com  Mon Feb 12 23:47:47 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 13 Feb 2024 08:47:47 +0100
Subject: [PATCH] dt-bindings: ata: convert MediaTek controller to the json-schema
Message-ID: <20240213074747.26151-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../devicetree/bindings/ata/ahci-mtk.txt      | 51 ----------
 .../bindings/ata/mediatek,mtk-ahci.yaml       | 98 +++++++++++++++++++
 2 files changed, 98 insertions(+), 51 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/ata/ahci-mtk.txt
 create mode 100644 Documentation/devicetree/bindings/ata/mediatek,mtk-ahci.yaml

diff --git a/Documentation/devicetree/bindings/ata/ahci-mtk.txt b/Documentation/devicetree/bindings/ata/ahci-mtk.txt
deleted file mode 100644
index d2aa696b161b..000000000000
--- a/Documentation/devicetree/bindings/ata/ahci-mtk.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-MediaTek Serial ATA controller
-
-Required properties:
- - compatible	   : Must be "mediatek,<chip>-ahci", "mediatek,mtk-ahci".
-		     When using "mediatek,mtk-ahci" compatible strings, you
-		     need SoC specific ones in addition, one of:
-		     - "mediatek,mt7622-ahci"
- - reg		   : Physical base addresses and length of register sets.
- - interrupts	   : Interrupt associated with the SATA device.
- - interrupt-names : Associated name must be: "hostc".
- - clocks	   : A list of phandle and clock specifier pairs, one for each
-		     entry in clock-names.
- - clock-names	   : Associated names must be: "ahb", "axi", "asic", "rbc", "pm".
- - phys		   : A phandle and PHY specifier pair for the PHY port.
- - phy-names	   : Associated name must be: "sata-phy".
- - ports-implemented : See ./ahci-platform.txt for details.
-
-Optional properties:
- - power-domains   : A phandle and power domain specifier pair to the power
-		     domain which is responsible for collapsing and restoring
-		     power to the peripheral.
- - resets	   : Must contain an entry for each entry in reset-names.
-		     See ../reset/reset.txt for details.
- - reset-names	   : Associated names must be: "axi", "sw", "reg".
- - mediatek,phy-mode : A phandle to the system controller, used to enable
-		       SATA function.
-
-Example:
-
-	sata: sata at 1a200000 {
-		compatible = "mediatek,mt7622-ahci",
-			     "mediatek,mtk-ahci";
-		reg = <0 0x1a200000 0 0x1100>;
-		interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "hostc";
-		clocks = <&pciesys CLK_SATA_AHB_EN>,
-			 <&pciesys CLK_SATA_AXI_EN>,
-			 <&pciesys CLK_SATA_ASIC_EN>,
-			 <&pciesys CLK_SATA_RBC_EN>,
-			 <&pciesys CLK_SATA_PM_EN>;
-		clock-names = "ahb", "axi", "asic", "rbc", "pm";
-		phys = <&u3port1 PHY_TYPE_SATA>;
-		phy-names = "sata-phy";
-		ports-implemented = <0x1>;
-		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
-		resets = <&pciesys MT7622_SATA_AXI_BUS_RST>,
-			 <&pciesys MT7622_SATA_PHY_SW_RST>,
-			 <&pciesys MT7622_SATA_PHY_REG_RST>;
-		reset-names = "axi", "sw", "reg";
-		mediatek,phy-mode = <&pciesys>;
-	};
diff --git a/Documentation/devicetree/bindings/ata/mediatek,mtk-ahci.yaml b/Documentation/devicetree/bindings/ata/mediatek,mtk-ahci.yaml
new file mode 100644
index 000000000000..a34bd2e9c352
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/mediatek,mtk-ahci.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ata/mediatek,mtk-ahci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Serial ATA controller
+
+maintainers:
+  - Ryder Lee <ryder.lee at mediatek.com>
+
+allOf:
+  - $ref: ahci-common.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt7622-ahci
+      - const: mediatek,mtk-ahci
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-names:
+    const: hostc
+
+  clocks:
+    maxItems: 5
+
+  clock-names:
+    items:
+      - const: ahb
+      - const: axi
+      - const: asic
+      - const: rbc
+      - const: pm
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 3
+
+  reset-names:
+    items:
+      - const: axi
+      - const: sw
+      - const: reg
+
+  mediatek,phy-mode:
+    description: System controller phandle, used to enable SATA function
+    $ref: /schemas/types.yaml#/definitions/phandle
+
+required:
+  - reg
+  - interrupts
+  - interrupt-names
+  - clocks
+  - clock-names
+  - phys
+  - phy-names
+  - ports-implemented
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt7622-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/phy/phy.h>
+    #include <dt-bindings/power/mt7622-power.h>
+    #include <dt-bindings/reset/mt7622-reset.h>
+
+    sata at 1a200000 {
+        compatible = "mediatek,mt7622-ahci", "mediatek,mtk-ahci";
+        reg = <0x1a200000 0x1100>;
+        interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "hostc";
+        clocks = <&pciesys CLK_SATA_AHB_EN>,
+                 <&pciesys CLK_SATA_AXI_EN>,
+                 <&pciesys CLK_SATA_ASIC_EN>,
+                 <&pciesys CLK_SATA_RBC_EN>,
+                 <&pciesys CLK_SATA_PM_EN>;
+        clock-names = "ahb", "axi", "asic", "rbc", "pm";
+        phys = <&u3port1 PHY_TYPE_SATA>;
+        phy-names = "sata-phy";
+        ports-implemented = <0x1>;
+        power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
+        resets = <&pciesys MT7622_SATA_AXI_BUS_RST>,
+                 <&pciesys MT7622_SATA_PHY_SW_RST>,
+                 <&pciesys MT7622_SATA_PHY_REG_RST>;
+        reset-names = "axi", "sw", "reg";
+        mediatek,phy-mode = <&pciesys>;
+    };
-- 
2.35.3



From dmitry.baryshkov at linaro.org  Mon Feb 12 23:51:58 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 13 Feb 2024 09:51:58 +0200
Subject: [PATCH v2 5/5] iommu/arm-smmu: Convert to domain_alloc_paging()
In-Reply-To: <20240209222349.GA923780@nvidia.com>
References: <5-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com>
 <20240209200538.917366-1-dmitry.baryshkov@linaro.org> <20240209222349.GA923780@nvidia.com>
Message-ID: <CAA8EJpp1wuMgawaUPnQWnhz1k023n8Q-k0_sO6P9p7ixntrCJQ@mail.gmail.com>

On Sat, 10 Feb 2024 at 00:23, Jason Gunthorpe <jgg at nvidia.com> wrote:
>
> On Fri, Feb 09, 2024 at 10:05:38PM +0200, Dmitry Baryshkov wrote:
> > On Tue, 17 Oct 2023 Jason Gunthorpe <jgg at nvidia.com> wrote:
> > > Now that the BLOCKED and IDENTITY behaviors are managed with their own
> > > domains change to the domain_alloc_paging() op.
> > >
> > > The check for using_legacy_binding is now redundant,
> > > arm_smmu_def_domain_type() always returns IOMMU_DOMAIN_IDENTITY for this
> > > mode, so the core code will never attempt to create a DMA domain in the
> > > first place.
> > >
> > > Since commit a4fdd9762272 ("iommu: Use flush queue capability") the core
> > > code only passes in IDENTITY/BLOCKED/UNMANAGED/DMA domain types. It will
> > > not pass in IDENTITY or BLOCKED if the global statics exist, so the test
> > > for DMA is also redundant now too.
> > >
> > > Call arm_smmu_init_domain_context() early if a dev is available.
> > >
> > > Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> > > ---
> > >  drivers/iommu/arm/arm-smmu/arm-smmu.c | 21 +++++++++++++++------
> > >  1 file changed, 15 insertions(+), 6 deletions(-)
> >
> > For some reason this patch breaks booting of the APQ8096 Dragonboard820c
> > (qcom/apq8096-db820c.dts). Dispbling display subsystem (mdss) and venus
> > devices makes the board boot in most of the cases. Most frequently the
> > last parts of the log loog in a following way:
>
> It is surprising we tested this patch on some tegra systems with this
> iommu and didn't hit anything..
>
> The only real functional thing this changes is to move the domain
> initialization up in time, potentially a lot in time in some
> cases. That function does alot of things including touching HW so
> possibly there is some surprising interaction with something else.

I should not be debugging strange platforms at 1 a.m. I forgot that
there was another patch to revert. So after reverting the MPM patch,
I'm getting the following results:

>
> So, I would expect this to not WARN_ON and to make it work the same as
> before the patch:

No warnings, the platform now boots up to the point of actually
bringing up the venus device:


[   11.906514] ath10k_pci 0000:01:00.0: qca6174 hw3.2 target
0x05030000 chip_id 0x00340aff sub 0000:0000
[   11.907119] ath10k_pci 0000:01:00.0: kconfig debug 1 debugfs 0
tracing 0 dfs 0 testmode 0
[   11.915881] ath10k_pci 0000:01:00.0: firmware ver
WLAN.RM.4.4.1-00288- api 6 features wowlan,ignore-otp,mfp crc32
bf907c7c
[   11.979972] Console: switching to colour frame buffer device 320x90
[   11.990756] ath10k_pci 0000:01:00.0: board_file api 2 bmi_id 0:1
crc32 d2863f91
[   12.060834] msm_mdp 901000.display-controller: [drm] fb0: msmdrmfb
frame buffer device
[   12.096203] qcom-pcie 608000.pcie: Phy link never came up
[   12.103785] qcom-pcie 608000.pcie: PCI host bridge to bus 0001:00
[   12.103970] qcom-venus c00000.video-codec: Adding to iommu group 3

Format: Log Type - Time(microsec) - Message - Optional Info
Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.XF.1.0-00301
S - IMAGE_VARIANT_STRING=M8996LAB
S - OEM_IMAGE_VERSION_STRING=crm-ubuntu68
S - Boot Interface: UFS

>
> Then I'd ask you to remove the comment and do:
>
> @@ -878,7 +878,9 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
>         if (dev) {
>                 struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
>
> +               WARN_ON(true);
>                 if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> +                       printk("Allocation failure in arm_smmu_domain_alloc_paging()\n");
>                         kfree(smmu_domain);
>                         return NULL;
>                 }
>
>
> And then we may get a clue from the backtraces it generates. I only
> saw one iommu group reported in your log so I'd expect one trace?

I added dev_info + mdelays() around the arm_smmu_init_domain_context()
and I can see that it crashes within that function.

[   29.819624] qcom-venus c00000.video-codec: Adding to iommu group 1
[   29.833181] ------------[ cut here ]------------
[   29.839198] WARNING: CPU: 1 PID: 35 at
drivers/iommu/arm/arm-smmu/arm-smmu.c:883
arm_smmu_domain_alloc_paging+0x80/0x174
[   29.843980] Modules linked in:
[   29.854824] CPU: 1 PID: 35 Comm: kworker/u18:0 Tainted: G     U
        6.8.0-rc3-next-20240208-05495-g20708c29957d-dirty #1739
[   29.857694] Hardware name: Qualcomm Technologies, Inc. DB820c (DT)
[   29.869410] Workqueue: events_unbound deferred_probe_work_func
[   29.875658] pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   29.881474] pc : arm_smmu_domain_alloc_paging+0x80/0x174
[   29.888331] lr : arm_smmu_domain_alloc_paging+0x68/0x174
[   29.893885] sp : ffff8000830338c0
[   29.899179] x29: ffff8000830338c0 x28: 0000000000000000 x27: ffff800081e72000
[   29.902396] x26: ffff00008034ee48 x25: ffff000080b24810 x24: 0000000000000000
[   29.909513] x23: ffff800081e73000 x22: ffff000080b24810 x21: ffff800082e23258
[   29.916633] x20: ffff00008389a700 x19: ffff00008034f600 x18: ffffffffffffffff
[   29.918788] usb 1-1: new high-speed USB device number 2 using xhci-hcd
[   29.923746] x17: 0000000c0000000b x16: 0000000900000008 x15: 0000000000000000
[   29.923765] x14: 000000000000b0af x13: 0000000000000000 x12: 0000000000000166
[   29.923783] x11: 0000000000000001 x10: 0000000000001410 x9 : 0000000000000000
[   29.923801] x8 : ffff00008034f800 x7 : 0000000000000000 x6 : 0000000000000000
[   29.923819] x5 : 0000000000000000 x4 : 0000000000000002 x3 : 0000000000000000
[   29.923837] x2 : ffff800082e23290 x1 : dead4ead00000000 x0 : 0000000000000000
[   29.923855] Call trace:
[   29.923861]  arm_smmu_domain_alloc_paging+0x80/0x174
[   29.923872]  __iommu_domain_alloc+0xcc/0xf4
[   29.923884]  iommu_setup_default_domain+0x294/0x554
[   29.938567] Bluetooth: hci0: Frame reassembly failed (-84)
[   29.944494]  __iommu_probe_device+0x418/0x43c
[   29.944508]  iommu_probe_device+0x3c/0x80
[   29.944519]  of_iommu_configure+0x124/0x1b4
[   29.944529]  of_dma_configure_id+0x170/0x2f4
[   29.969874] mmc0: new ultra high speed SDR104 SDHC card at address 5048
[   29.972966]  platform_dma_configure+0xa8/0xb4
[   29.972983]  really_probe+0x70/0x2ac
[   29.972992]  __driver_probe_device+0x78/0x12c
[   29.973001]  driver_probe_device+0xd8/0x160
[   29.973010]  __device_attach_driver+0xb8/0x138
[   29.973019]  bus_for_each_drv+0x80/0xdc
[   29.973027]  __device_attach+0x9c/0x188
[   29.973037]  device_initial_probe+0x14/0x20
[   29.973046]  bus_probe_device+0xac/0xb0
[   29.973055]  deferred_probe_work_func+0x8c/0xc8
[   29.973064]  process_one_work+0x210/0x5e4
[   29.983596] mmcblk0: mmc0:5048 SD32G 28.8 GiB
[   29.987546]  worker_thread+0x1bc/0x38c
[   29.987558]  kthread+0x120/0x124
[   29.987568]  ret_from_fork+0x10/0x20
[   29.987579] irq event stamp: 109977
[   29.987584] hardirqs last  enabled at (109977):
[<ffff800080fbbc48>] _raw_spin_unlock_irqrestore+0x6c/0x70
[   29.987600] hardirqs last disabled at (109976):
[<ffff800080fbb0a8>] _raw_spin_lock_irqsave+0x84/0x88
[   29.987610] softirqs last  enabled at (109966):
[<ffff800080090680>] __do_softirq+0x498/0x4e0
[   29.987619] softirqs last disabled at (109961):
[<ffff800080096184>] ____do_softirq+0x10/0x1c
[   30.006747]  mmcblk0: p1
[   30.010291] ---[ end trace 0000000000000000 ]---
[   30.018630] remoteproc remoteproc1: remote processor
9300000.remoteproc is now up
[   30.024525] qcom-pcie 600000.pcie: iATU: unroll F, 32 ob, 8 ib,
align 4K, limit 4G
[   30.044747] qcom,apr remoteproc1:smd-edge.apr_audio_svc.-1.-1:
Adding APR/GPR dev: aprsvc:service:4:3
[   30.046118] qcom-pcie 600000.pcie: Invalid eDMA IRQs found
[   30.051718] qcom,apr remoteproc1:smd-edge.apr_audio_svc.-1.-1:
Adding APR/GPR dev: aprsvc:service:4:4
[   30.066435] Bluetooth: hci0: QCA Downloading qca/nvm_00440302.bin
[   30.130736] hub 1-1:1.0: USB hub found
[   30.150390] qcom-pcie 600000.pcie: PCIe Gen.1 x1 link up
[   30.156394] hub 1-1:1.0: 4 ports detected
[   30.161837] qcom-pcie 600000.pcie: PCI host bridge to bus 0000:00
[   30.189583] pci_bus 0000:00: root bus resource [bus 00-ff]
[   30.195652] pci_bus 0000:00: root bus resource [io  0x0000-0xfffff]
[   30.201035] pci_bus 0000:00: root bus resource [mem 0x0c300000-0x0cffffff]
[   30.205424] Bluetooth: hci0: QCA setup on UART is completed
[   30.207262] pci 0000:00:00.0: [17cb:0104] type 01 class 0x060400
PCIe Root Port
[   30.214380] usb 2-1: new SuperSpeed USB device number 2 using xhci-hcd
[   30.219636] qcom-venus c00000.video-codec: Allocating domain
[   30.221503] pci 0000:00:00.0: BAR 0 [mem 0x00000000-0x00000fff]
[   30.221680] pci 0000:00:00.0: PCI bridge to [bus 01-ff]
[   30.221772] pci 0000:00:00.0:   bridge window [io  0x0000-0x0fff]
[   30.221832] pci 0000:00:00.0:   bridge window [mem 0x00000000-0x000fffff]
[   30.221945] pci 0000:00:00.0:   bridge window [mem
0x00000000-0x000fffff 64bit pref]
[   30.222617] pci 0000:00:00.0: PME# supported from D0 D3hot
[   30.273673] hub 2-1:1.0: USB hub found
[   30.276567] hub 2-1:1.0: 4 ports detected

Format: Log Type - Time(microsec) - Message - Optional Info
Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.XF.1.0-00301
S - IMAGE_VARIANT_STRING=M8996LAB
S - OEM_IMAGE_VERSION_STRING=crm-ubuntu68
S - Boot Interface: UFS

I traced this further, it crashes during arm_smmu_write_context_bank().



--
With best wishes
Dmitry


From quic_sibis at quicinc.com  Tue Feb 13 00:03:18 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 13 Feb 2024 13:33:18 +0530
Subject: [PATCH 2/3] firmware: arm_scmi: Add support for marking certain
 frequencies as boost
In-Reply-To: <20240131160848.662dhaoiov3trt4i@bogus>
References: <20240117110443.2060704-1-quic_sibis@quicinc.com>
 <20240117110443.2060704-3-quic_sibis@quicinc.com>
 <e3abe1ab-064f-4a6a-a91d-fe8c91574600@arm.com>
 <20240131160848.662dhaoiov3trt4i@bogus>
Message-ID: <64fdfa4d-f7ec-a5eb-bfbc-ee35d9cd4722@quicinc.com>



On 1/31/24 21:38, Sudeep Holla wrote:
> On Wed, Jan 31, 2024 at 03:29:43PM +0100, Pierre Gondois wrote:
>> Hello Sibi,
>>
>> On 1/17/24 12:04, Sibi Sankar wrote:
>>> All opps above the sustained level/frequency are treated as boost, so mark
>>> them accordingly.
>>>

Sudeep/Pierre,

Thanks for taking time to review the series.

>>> Suggested-by: Sudeep Holla <sudeep.holla at arm.com>
>>> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
>>> ---
>>>    drivers/firmware/arm_scmi/perf.c | 11 ++++++++++-
>>>    1 file changed, 10 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
>>> index e286f04ee6e3..d3fb8c804b3d 100644
>>> --- a/drivers/firmware/arm_scmi/perf.c
>>> +++ b/drivers/firmware/arm_scmi/perf.c
>>> @@ -811,7 +811,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>>>    				     struct device *dev, u32 domain)
>>>    {
>>>    	int idx, ret;
>>> -	unsigned long freq;
>>> +	unsigned long freq, sustained_freq;
>>>    	struct dev_pm_opp_data data = {};
>>>    	struct perf_dom_info *dom;
>>> @@ -819,12 +819,21 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>>>    	if (IS_ERR(dom))
>>>    		return PTR_ERR(dom);
>>> +	if (!dom->level_indexing_mode)
>>> +		sustained_freq = dom->sustained_perf_level * dom->mult_factor;
>>> +	else
>>> +		sustained_freq = dom->sustained_freq_khz * dom->mult_factor;
>>> +
>>>    	for (idx = 0; idx < dom->opp_count; idx++) {
>>>    		if (!dom->level_indexing_mode)
>>>    			freq = dom->opp[idx].perf * dom->mult_factor;
>>>    		else
>>>    			freq = dom->opp[idx].indicative_freq * dom->mult_factor;
>>> +		/* All opps above the sustained level/frequency are treated as boost */
>>> +		if (sustained_freq && freq > sustained_freq)
>>
>> It seems the sustained_freq is not optional since SCMI v1.0,
>> is it necessary to check that (sustained_freq != 0) ?
>>
> 
> Technically correct, we don't have to. But since day 1, we checked and
> handled 0 for perf_level specifically to avoid division by zero. I am
> just worried if there are any platforms in the wild with these values as
> 0. We can start without the check and add it if someone complains perhaps ?

sure will drop the check in the re-spin.

-Sibi

> 


From s-vadapalli at ti.com  Tue Feb 13 00:03:48 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Tue, 13 Feb 2024 13:33:48 +0530
Subject: [PATCH v5] arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in serdes_ln_ctrl
Message-ID: <20240213080348.248916-1-s-vadapalli@ti.com>

From: Chintan Vankar <c-vankar at ti.com>

Change offset in mux-reg-masks property for serdes_ln_ctrl node
since reg-mux property is used in compatible.

Fixes: 2765149273f4 ("mux: mmio: use reg property when parent device is not a syscon")
Signed-off-by: Chintan Vankar <c-vankar at ti.com>
Acked-by: Andrew Davis <afd at ti.com>
Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---
Hello,

This patch is based on linux-next tagged next-20240213.
The v4 of this patch is a part of the series at:
https://lore.kernel.org/r/20240131101441.1362409-1-c-vankar at ti.com/

Since the v4 series mentioned above has open comments on the other
patches in the series, this patch is being posted separately to unblock
other dependent series which rely on the fix implemented by this patch.

Changes since v4:
- Rebased patch on linux-next tagged next-20240213.

Regards,
Siddharth.

 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
index 3cb964982792..3b7f0eca977b 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -52,12 +52,12 @@ serdes_ln_ctrl: mux-controller at 4080 {
 			compatible = "reg-mux";
 			reg = <0x00004080 0x30>;
 			#mux-control-cells = <1>;
-			mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
-					<0x4088 0x3>, <0x408c 0x3>, /* SERDES0 lane2/3 select */
-					<0x4090 0x3>, <0x4094 0x3>, /* SERDES1 lane0/1 select */
-					<0x4098 0x3>, <0x409c 0x3>, /* SERDES1 lane2/3 select */
-					<0x40a0 0x3>, <0x40a4 0x3>, /* SERDES2 lane0/1 select */
-					<0x40a8 0x3>, <0x40ac 0x3>; /* SERDES2 lane2/3 select */
+			mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */
+					<0x8 0x3>, <0xc 0x3>, /* SERDES0 lane2/3 select */
+					<0x10 0x3>, <0x14 0x3>, /* SERDES1 lane0/1 select */
+					<0x18 0x3>, <0x1c 0x3>, /* SERDES1 lane2/3 select */
+					<0x20 0x3>, <0x24 0x3>, /* SERDES2 lane0/1 select */
+					<0x28 0x3>, <0x2c 0x3>; /* SERDES2 lane2/3 select */
 			idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>,
 				      <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
 				      <J784S4_SERDES0_LANE2_IP3_UNUSED>,
-- 
2.34.1



From dmitry.baryshkov at linaro.org  Tue Feb 13 00:06:51 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 13 Feb 2024 10:06:51 +0200
Subject: [PATCH 1/1] iommu/arm-smmu-qcom: Fix use-after-free issue in qcom_smmu_create()
In-Reply-To: <20240213062608.13018-1-quic_pbrahma@quicinc.com>
References: <20240201210529.7728-4-quic_c_gdjako@quicinc.com> <20240213062608.13018-1-quic_pbrahma@quicinc.com>
Message-ID: <CAA8EJpoh-m_fzt9WcUXOkTxVZRQMDf-WrgqqoM0C_-qzjgDm1w@mail.gmail.com>

On Tue, 13 Feb 2024 at 08:27, Pratyush Brahma <quic_pbrahma at quicinc.com> wrote:
>
> Currently, during arm smmu probe, struct arm_smmu_device pointer
> is allocated. The pointer is reallocated to a new struct qcom_smmu in
> qcom_smmu_create() with devm_krealloc() which frees the smmu device
> after copying the data into the new pointer.
>
> The freed pointer is then passed again in devm_of_platform_populate()
> inside qcom_smmu_create() which causes a use-after-free issue.
>
> Fix the use-after-free issue by reassigning the old pointer to
> the new pointer where the struct was copied by devm_krealloc().
>
> Signed-off-by: Pratyush Brahma <quic_pbrahma at quicinc.com>

Missing Fixes tag.

> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index ed5ed5da7740..49eaeed6a91c 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -710,6 +710,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
>         qsmmu = devm_krealloc(smmu->dev, smmu, sizeof(*qsmmu), GFP_KERNEL);
>         if (!qsmmu)
>                 return ERR_PTR(-ENOMEM);
> +       smmu = &qsmmu->smmu;
>
>         qsmmu->smmu.impl = impl;
>         qsmmu->data = data;
> @@ -719,7 +720,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
>         if (ret)
>                 return ERR_PTR(ret);

What is the tree that you have been developing this against? I don't
see this part of the code in the linux-next.

>
> -       return &qsmmu->smmu;
> +       return smmu;
>  }
>
>  /* Implementation Defined Register Space 0 register offsets */
> --
> 2.17.1
>
>


-- 
With best wishes
Dmitry


From francesco at dolcini.it  Tue Feb 13 00:15:43 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Tue, 13 Feb 2024 09:15:43 +0100
Subject: [PATCH v2 6/9] arm64: dts: ti: k3-am6*: Remove DLL properties
 for soft PHYs
In-Reply-To: <20240213002416.1560357-7-jm@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
 <20240213002416.1560357-7-jm@ti.com>
Message-ID: <20240213081543.GA3810@francesco-nb>

Judith, you asked for tests, but if this property does nothing
on AM62 there is no much to test, these changes will just have zero
effect given your explanation.

On Mon, Feb 12, 2024 at 06:24:13PM -0600, Judith Mendez wrote:
> Remove DLL properties which are not applicable for soft PHYs
> since these PHYs do not have a DLL to enable.
> 
> Signed-off-by: Judith Mendez <jm at ti.com>

Acked-by: Francesco Dolcini <francesco.dolcini at toradex.com> # Verdin AM62



From tudor.ambarus at linaro.org  Tue Feb 13 00:16:11 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Tue, 13 Feb 2024 10:16:11 +0200
Subject: [PATCH v2 01/12] spi: dt-bindings: introduce FIFO depth
 properties
In-Reply-To: <170775215967.605422.1424850912641172864.robh@kernel.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
 <20240212140331.915498-2-tudor.ambarus@linaro.org>
 <170775215967.605422.1424850912641172864.robh@kernel.org>
Message-ID: <1d6e104d-6833-48c5-b95d-8f10617cd5c5@linaro.org>



On 12.02.2024 17:36, Rob Herring wrote:
> 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/spi/spi-controller.yaml:152:9: 
> [warning] wrong indentation: expected 6 but found 8 (indentation)
> ./Documentation/devicetree/bindings/spi/spi-controller.yaml:156:9: 
> [warning] wrong indentation: expected 6 but found 8 (indentation)
> 
> dtschema/dtc warnings/errors:

oh, the horror, I missed these. I'll re-check and resend.

Thanks,
ta


From quic_pbrahma at quicinc.com  Tue Feb 13 00:17:39 2024
From: quic_pbrahma at quicinc.com (Pratyush Brahma)
Date: Tue, 13 Feb 2024 13:47:39 +0530
Subject: [PATCH 1/1] iommu/arm-smmu-qcom: Fix use-after-free issue in
 qcom_smmu_create()
In-Reply-To: <CAA8EJpoh-m_fzt9WcUXOkTxVZRQMDf-WrgqqoM0C_-qzjgDm1w@mail.gmail.com>
References: <20240201210529.7728-4-quic_c_gdjako@quicinc.com>
 <20240213062608.13018-1-quic_pbrahma@quicinc.com>
 <CAA8EJpoh-m_fzt9WcUXOkTxVZRQMDf-WrgqqoM0C_-qzjgDm1w@mail.gmail.com>
Message-ID: <ccb6b2a2-040b-46cc-9b72-2e4bd4c75565@quicinc.com>


On 2/13/2024 1:36 PM, Dmitry Baryshkov wrote:
> On Tue, 13 Feb 2024 at 08:27, Pratyush Brahma <quic_pbrahma at quicinc.com> wrote:
>> Currently, during arm smmu probe, struct arm_smmu_device pointer
>> is allocated. The pointer is reallocated to a new struct qcom_smmu in
>> qcom_smmu_create() with devm_krealloc() which frees the smmu device
>> after copying the data into the new pointer.
>>
>> The freed pointer is then passed again in devm_of_platform_populate()
>> inside qcom_smmu_create() which causes a use-after-free issue.
>>
>> Fix the use-after-free issue by reassigning the old pointer to
>> the new pointer where the struct was copied by devm_krealloc().
>>
>> Signed-off-by: Pratyush Brahma <quic_pbrahma at quicinc.com>
> Missing Fixes tag.
Haven't added as the patchset in-reply-to hasn't been merged to 
linux-next. Please refer my next reply.
>
>> ---
>>   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> index ed5ed5da7740..49eaeed6a91c 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> @@ -710,6 +710,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
>>          qsmmu = devm_krealloc(smmu->dev, smmu, sizeof(*qsmmu), GFP_KERNEL);
>>          if (!qsmmu)
>>                  return ERR_PTR(-ENOMEM);
>> +       smmu = &qsmmu->smmu;
>>
>>          qsmmu->smmu.impl = impl;
>>          qsmmu->data = data;
>> @@ -719,7 +720,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
>>          if (ret)
>>                  return ERR_PTR(ret);
> What is the tree that you have been developing this against? I don't
> see this part of the code in the linux-next.
This is in reply to the patchset at: 
https://lore.kernel.org/all/20240201210529.7728-4-quic_c_gdjako at quicinc.com
The aforementioned patchset introduces this bug. This is a suggested fix 
to the bug.
>> -       return &qsmmu->smmu;
>> +       return smmu;
>>   }
>>
>>   /* Implementation Defined Register Space 0 register offsets */
>> --
>> 2.17.1
>>
>>
Thanks,
Pratyush


From aakarsh.jain at samsung.com  Mon Feb 12 20:57:33 2024
From: aakarsh.jain at samsung.com (Aakarsh Jain)
Date: Tue, 13 Feb 2024 10:27:33 +0530
Subject: [Patch v2] dt-bindings: media: s5p-mfc: Remove s5p-mfc.txt binding
References: <CGME20240213045739epcas5p49f28920efda3cb80351b1fcae580b21e@epcas5p4.samsung.com>
Message-ID: <20240213045733.63876-1-aakarsh.jain@samsung.com>

commit "538af6e5856b" which convert s5p-mfc bindings to
json-schema is already merged. Remove "s5p-mfc.txt" file.

Fixes: 538af6e5856b ("dt-bindings: media: s5p-mfc: convert
bindings to json-schema")
Signed-off-by: Aakarsh Jain <aakarsh.jain at samsung.com>
---
changelog:
v1->v2
Add Fixes tag suggested by Krzysztof
 Documentation/devicetree/bindings/media/s5p-mfc.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/media/s5p-mfc.txt

diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt b/Documentation/devicetree/bindings/media/s5p-mfc.txt
deleted file mode 100644
index e69de29bb2d1..000000000000
-- 
2.17.1



From francesco at dolcini.it  Tue Feb 13 00:19:53 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Tue, 13 Feb 2024 09:19:53 +0100
Subject: [PATCH v2 8/9] arm64: dts: ti: k3-am6*: Fix bus-width property
 in MMC nodes
In-Reply-To: <c6ad3a3e-330c-40cd-8e25-fd259fd1e398@phytec.de>
References: <20240213002416.1560357-1-jm@ti.com>
 <20240213002416.1560357-9-jm@ti.com>
 <c6ad3a3e-330c-40cd-8e25-fd259fd1e398@phytec.de>
Message-ID: <20240213081953.GB3810@francesco-nb>

On Tue, Feb 13, 2024 at 06:07:28AM +0100, Wadim Egorov wrote:
> Hi Judith,
> 
> Am 13.02.24 um 01:24 schrieb Judith Mendez:
> > Move bus-width property to *main.dtsi, above the OTAP/ITAP
> > delay values. While there is no error with where it is
> > currently at, it is easier to read the MMC node if the
> > bus-width property is located above the OTAP/ITAP delay
> > values consistently across MMC nodes.
> > 
> > Add missing bus-width for MMC2 in k3-am62-main.
> > 
> > Signed-off-by: Judith Mendez <jm at ti.com>
> > ---
> >   arch/arm64/boot/dts/ti/k3-am62-main.dtsi       | 5 +++--
> >   arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 1 -
> >   arch/arm64/boot/dts/ti/k3-am62a-main.dtsi      | 2 +-
> >   arch/arm64/boot/dts/ti/k3-am64-main.dtsi       | 2 ++
> >   arch/arm64/boot/dts/ti/k3-am642-evm.dts        | 2 --
> >   arch/arm64/boot/dts/ti/k3-am642-sk.dts         | 1 -
> 
> I think you missed to update all non TI boards.

Not sure which boards are you referring to.

I would not change the verdin-am62 boards, the bus-width there is
consistent with the schematics, it's just correct and in the right place
IMO.

Francesco



From krzysztof.kozlowski at linaro.org  Tue Feb 13 00:26:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 13 Feb 2024 09:26:38 +0100
Subject: [Patch v2] dt-bindings: media: s5p-mfc: Remove s5p-mfc.txt
 binding
In-Reply-To: <20240213045733.63876-1-aakarsh.jain@samsung.com>
References: <CGME20240213045739epcas5p49f28920efda3cb80351b1fcae580b21e@epcas5p4.samsung.com>
 <20240213045733.63876-1-aakarsh.jain@samsung.com>
Message-ID: <feab0ab8-9c34-41f4-a013-e66e0c74048b@linaro.org>

On 13/02/2024 05:57, Aakarsh Jain wrote:
> commit "538af6e5856b" which convert s5p-mfc bindings to

Nothing improved here, that's still not correct commit reference. Drop
the quotes and look at submitting patches how this is supposed to be
done. It's explicitly documented.


> json-schema is already merged. Remove "s5p-mfc.txt" file.
> 
> Fixes: 538af6e5856b ("dt-bindings: media: s5p-mfc: convert
> bindings to json-schema")

Don't break tags.

> Signed-off-by: Aakarsh Jain <aakarsh.jain at samsung.com>
> ---
> changelog:

> index e69de29bb2d1..000000000000

Best regards,
Krzysztof



From u-kumar1 at ti.com  Tue Feb 13 00:26:40 2024
From: u-kumar1 at ti.com (Udit Kumar)
Date: Tue, 13 Feb 2024 13:56:40 +0530
Subject: [PATCH v4] clk: keystone: sci-clk: Adding support for non contiguous clocks
Message-ID: <20240213082640.457316-1-u-kumar1@ti.com>

Most of clocks and their parents are defined in contiguous range,
But in few cases, there is gap in clock numbers[0].
Driver assumes clocks to be in contiguous range, and add their clock
ids incrementally.

New firmware started returning error while calling get_freq and is_on
API for non-available clock ids.

In this fix, driver checks and adds only valid clock ids.

[0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
Section Clocks for NAVSS0_CPTS_0 Device, clock id 12-15 not present.

Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
---
Changelog
Changes in v4
- Added only incremental chanegs as per v3 discussion
- Updated commit message
- v3 was Reviewed-by, Dropping Reviewed-by as logic is changed
Link to v3
https://lore.kernel.org/all/20240207091100.4001428-1-u-kumar1 at ti.com/ 

Changes in v3
- instead of get_freq, is_auto API is used to check validilty of clock
- Address comments of v2, to have preindex increment
Link to v2 https://lore.kernel.org/all/20240206104357.3803517-1-u-kumar1 at ti.com/

Changes in v2
- Updated commit message
- Simplified logic for valid clock id
link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/


P.S
Firmawre returns total num_parents count including non available ids.
For above device id NAVSS0_CPTS_0, number of parents clocks are 16
i.e from id 2 to 17. But out of these ids few are not valid.
So driver adds only valid clock ids out ot total.

Original logs
https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
Line 2630 for error

Logs with fix v4
https://gist.github.com/uditkumarti/f25482a5e18e918010b790cffb39f572
Line 2640


 drivers/clk/keystone/sci-clk.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 35fe197dd303..eb2ef44869b2 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -516,6 +516,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
 	struct sci_clk *sci_clk, *prev;
 	int num_clks = 0;
 	int num_parents;
+	bool state;
 	int clk_id;
 	const char * const clk_names[] = {
 		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
@@ -586,6 +587,15 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
 				clk_id = args.args[1] + 1;
 
 				while (num_parents--) {
+					/* Check if this clock id is valid */
+					ret = provider->ops->is_auto(provider->sci,
+						sci_clk->dev_id, clk_id, &state);
+
+					if (ret) {
+						clk_id++;
+						continue;
+					}
+
 					sci_clk = devm_kzalloc(dev,
 							       sizeof(*sci_clk),
 							       GFP_KERNEL);
-- 
2.34.1



From quic_sibis at quicinc.com  Tue Feb 13 00:30:07 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 13 Feb 2024 14:00:07 +0530
Subject: [PATCH 2/3] firmware: arm_scmi: Add support for marking certain
 frequencies as boost
In-Reply-To: <20240131112507.fu355wnolbsoiqxn@bogus>
References: <20240117110443.2060704-1-quic_sibis@quicinc.com>
 <20240117110443.2060704-3-quic_sibis@quicinc.com>
 <20240131112507.fu355wnolbsoiqxn@bogus>
Message-ID: <b57c6699-92f8-192c-34b6-97c04cd18fb4@quicinc.com>



On 1/31/24 16:55, Sudeep Holla wrote:
> On Wed, Jan 17, 2024 at 04:34:42PM +0530, Sibi Sankar wrote:
>> All opps above the sustained level/frequency are treated as boost, so mark
>> them accordingly.
>>
>> Suggested-by: Sudeep Holla <sudeep.holla at arm.com>
>> Signed-off-by: Sibi Sankar <quic_sibis at quicinc.com>
>> ---
>>   drivers/firmware/arm_scmi/perf.c | 11 ++++++++++-
>>   1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
>> index e286f04ee6e3..d3fb8c804b3d 100644
>> --- a/drivers/firmware/arm_scmi/perf.c
>> +++ b/drivers/firmware/arm_scmi/perf.c
>> @@ -811,7 +811,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>>   				     struct device *dev, u32 domain)
>>   {
>>   	int idx, ret;
>> -	unsigned long freq;
>> +	unsigned long freq, sustained_freq;
>>   	struct dev_pm_opp_data data = {};
>>   	struct perf_dom_info *dom;
>>   
>> @@ -819,12 +819,21 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>>   	if (IS_ERR(dom))
>>   		return PTR_ERR(dom);
>>   
>> +	if (!dom->level_indexing_mode)
>> +		sustained_freq = dom->sustained_perf_level * dom->mult_factor;
>> +	else
>> +		sustained_freq = dom->sustained_freq_khz * dom->mult_factor;
>> +
> 
> Can't we just use dom->sustained_freq_khz * 1000UL in both the cases ?

sure, I retained sustained_perf_level because I wasn't sure how the
sustained_perf_level would be populated in systems not using level
indexing mode.

> 
> Other than that this series looks good to me but it would be good to
> explain how you would use this. Since it is enabled by default, do you
> plan to disable boost at time and when ? If it is for thermal reasons,
> why your other series handling thermal and limits notification from the
> firmware not sufficient.

Boost frequencies defined in X1E are achievable by only one CPU in a
cluster i.e. either the other CPUs in the same cluster should be in low
power mode or offline. So it's mostly for book keeping i.e. we wouldn't
to intimate incorrectly that the CPUs are running at max possible
frequency when it's actually running at a lower frequency.

-Sibi

> 


From quic_sibis at quicinc.com  Tue Feb 13 00:35:35 2024
From: quic_sibis at quicinc.com (Sibi Sankar)
Date: Tue, 13 Feb 2024 14:05:35 +0530
Subject: [PATCH 0/3] cpufreq: scmi: Add boost frequency support
In-Reply-To: <e968092a-dc2b-4351-9489-acf874bbc7b6@arm.com>
References: <20240117110443.2060704-1-quic_sibis@quicinc.com>
 <20240123060827.a3vszziftj6pszt3@vireshk-i7> <Za-RtBrSxI-j4Jdx@bogus>
 <e968092a-dc2b-4351-9489-acf874bbc7b6@arm.com>
Message-ID: <01b3d0ed-3fd3-86c6-7b0f-48d34a5d9ba8@quicinc.com>



On 1/31/24 20:37, Dietmar Eggemann wrote:
> On 23/01/2024 11:15, Sudeep Holla wrote:
>> On Tue, Jan 23, 2024 at 11:38:27AM +0530, Viresh Kumar wrote:
>>> On 17-01-24, 16:34, Sibi Sankar wrote:
>>>> This series adds provision to mark dynamic opps as boost capable and adds
>>>> boost frequency support to the scmi cpufreq driver.
>>>>
>>>> Depends on:
>>>> HW pressure v4: https://patchwork.kernel.org/project/linux-arm-msm/cover/20240109164655.626085-1-vincent.guittot at linaro.org/
>>>> scmi notification v2: https://patchwork.kernel.org/project/linux-arm-msm/cover/20240117104116.2055349-1-quic_sibis at quicinc.com/
>>>>
>>>> Sibi Sankar (3):
>>>>    OPP: Extend dev_pm_opp_data with turbo support
>>>>    firmware: arm_scmi: Add support for marking certain frequencies as
>>>>      boost
>>>>    cpufreq: scmi: Enable boost support
>>>
>>> Sudeep, please lemme know if you are okay with the changes. Will apply
>>> them.
>>
>> I was planning to look at it once Lukasz/Dietmar confirm that this concept
>> doesn't change anything fundamental in the way EAS related changes work
>> today. I know I suggested the change as that seem to be right way to do
>> but I haven't analysed if this has any negative impact on the existing
>> features as this change will impact all the existing platform with OPPs
>> above sustained performance/frequency advertised from the SCMI platform
>> firmware.
> 
> I was mostly concerned about the settings for the CPU frequency
> invariance implementation in [drivers/base/arch_topology.c]:
> 
> #define arch_scale_freq_capacity topology_get_freq_scale
> 
> But per_cpu(capacity_freq_ref, cpu) is still set to
> 'policy->cpuinfo.max_freq' in init_cpu_capacity_callback()
> which stays the same.
> 
> With some extra debugging I get the following on Juno-r0 [L b b L L L]:
> 
> root at juno:~# dmesg -w | grep -i "freq\|boost\|noti\|OPP\|cap"
> 
> [    1.768414] arm-scmi firmware:scmi: SCMI Notifications - Core Enabled.
> [    1.793084] [1][LITTLE_CPU]:: Registered OPP[0] 450000000
> [    1.798624] [1][LITTLE_CPU]:: Registered OPP[1] 575000000
> [    1.804131] [1][LITTLE_CPU]:: Registered OPP[2] 700000000
> [    1.809552] scmi_dvfs_device_opps_add() sustained_freq=700000000 freq=775000000
> [    1.816971] [1][LITTLE_CPU]:: Registered OPP[3] 775000000
> [    1.822392] scmi_dvfs_device_opps_add() sustained_freq=700000000 freq=850000000
> [    1.829800] [1][LITTLE_CPU]:: Registered OPP[4] 850000000
> [    1.835268] enabled boost: 0
> [    1.838173] init_cpu_capacity_callback() cpu=0 max_freq=850000
> [    1.844032] init_cpu_capacity_callback() cpu=3 max_freq=850000
> [    1.849886] init_cpu_capacity_callback() cpu=4 max_freq=850000
> [    1.855743] init_cpu_capacity_callback() cpu=5 max_freq=850000
> [    1.866324] cpufreq_update_pressure() cpu=0 cpufreq_pressure=0
> [    1.872178] cpufreq_update_pressure() cpu=3 cpufreq_pressure=0
> [    1.878026] cpufreq_update_pressure() cpu=4 cpufreq_pressure=0
> [    1.883874] cpufreq_update_pressure() cpu=5 cpufreq_pressure=0
> [    1.890633] [0][BIG_CPU]:: Registered OPP[0] 450000000
> [    1.895892] [0][BIG_CPU]:: Registered OPP[1] 625000000
> [    1.901129] [0][BIG_CPU]:: Registered OPP[2] 800000000
> [    1.906286] scmi_dvfs_device_opps_add() sustained_freq=800000000 freq=950000000
> [    1.906381] [0][BIG_CPU]:: Registered OPP[3] 950000000
> [    1.917377] scmi_dvfs_device_opps_add() sustained_freq=800000000 freq=1100000000
> [    1.917468] [0][BIG_CPU]:: Registered OPP[4] 1100000000
> [    1.939237] enabled boost: 0
> [    1.942134] init_cpu_capacity_callback() cpu=1 max_freq=1100000
> [    1.948078] init_cpu_capacity_callback() cpu=2 max_freq=1100000
> [    1.959003] cpufreq_update_pressure() cpu=1 cpufreq_pressure=0
> [    1.964853] cpufreq_update_pressure() cpu=2 cpufreq_pressure=0
> 
> root at juno:/sys/devices/system/cpu/cpufreq# cat boost policy*/boost
> 1
> 0
> 0
> 
> root at juno:/sys/devices/system/cpu/cpufreq# cat policy*/scaling_available_frequencies policy*/scaling_boost_frequencies
> 450000 575000 700000
> 450000 625000 800000
> 775000 850000
> 950000 1100000
> 
> If I disable system-wide boost I see the correct influence on
> 'cpufreq_pressure':
> 
> root at juno:/sys/devices/system/cpu/cpufreq# echo 0 > boost
> 
> [  439.466682] cpufreq_update_pressure() cpu=1 cpufreq_pressure=280
> [  439.472797] cpufreq_update_pressure() cpu=2 cpufreq_pressure=280
> [  439.478889] cpufreq_update_pressure() cpu=0 cpufreq_pressure=79
> [  439.484852] cpufreq_update_pressure() cpu=3 cpufreq_pressure=79
> [  439.490843] cpufreq_update_pressure() cpu=4 cpufreq_pressure=79
> [  439.499621] cpufreq_update_pressure() cpu=5 cpufreq_pressure=79
> 
> reflecting the max frequency change from '1100000 to 800000' on CPU1,2
> and from '850000 to 700000' on CPU0,3-5.
> 
> root at juno:/sys/devices/system/cpu/cpufreq# echo 1 > boost
> 
> [ 2722.693113] cpufreq_update_pressure() cpu=1 cpufreq_pressure=0
> [ 2722.699041] cpufreq_update_pressure() cpu=2 cpufreq_pressure=0
> [ 2722.704962] cpufreq_update_pressure() cpu=0 cpufreq_pressure=0
> [ 2722.710842] cpufreq_update_pressure() cpu=3 cpufreq_pressure=0
> [ 2722.719644] cpufreq_update_pressure() cpu=4 cpufreq_pressure=0
> [ 2722.728224] cpufreq_update_pressure() cpu=5 cpufreq_pressure=0
> 
> What doesn't work for me is to disable boost per policy:
> 
> root at juno:/sys/devices/system/cpu/cpufreq# echo 1 > boost
> root at juno:/sys/devices/system/cpu/cpufreq# echo 0 > policy0/boost
> root at juno:/sys/devices/system/cpu/cpufreq# echo 0 > policy1/boost
> 
> Here I don't see 'cpufreq_pressure' changes.
> 
> BTW, what's the use case you have in mind for this feature? Is it to cap
> high OPPs for CPUs in a certain CPUfreq policy?

Yeah, that's exactly the use case for X1E. Boost frequencies defined in
the SoC are achievable by only one CPU in a cluster i.e. either the
other CPUs in the same cluster should be in low power mode or offline.
So it's mostly for book keeping i.e. we wouldn't to intimate incorrectly
that the CPUs are running at max possible frequency when it's actually
running at a lower frequency.

-Sibi

> 
> 


From ville.syrjala at linux.intel.com  Tue Feb 13 00:38:56 2024
From: ville.syrjala at linux.intel.com (Ville =?iso-8859-1?Q?Syrj=E4l=E4?=)
Date: Tue, 13 Feb 2024 10:38:56 +0200
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add
 Broadcast RGB property
In-Reply-To: <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
References: <20240115143720.GA160656@toolbox>
 <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
Message-ID: <ZcsqoPCJDjA5PJUF@intel.com>

On Mon, Feb 12, 2024 at 05:53:48PM +0100, Maxime Ripard wrote:
> On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > > Hi,
> > > > > > > > > 
> > > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > > >  /**
> > > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > > >   *
> > > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > > + *
> > > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > > + *
> > > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > > + *
> > > > > > > > > > > > + *      Full:
> > > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > > + *
> > > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > > + *
> > > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > > + *
> > > > > > > > > > > 
> > > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > > different things being affected:
> > > > > > > > > > > 
> > > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > > 
> > > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > > 
> > > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > > 
> > > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > > signalling, what happens?
> > > > > > > > > > 
> > > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > > YCbCr?
> > > > > > > > > 
> > > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > > vc4 will follow the value of the property.
> > > > > > > > 
> > > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > > That should explain why it's only affecting RGB.
> > > > > > > 
> > > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > > itself.
> > > > > > > 
> > > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > > to enable it.
> > > > > > > 
> > > > > > > vc4 supports it.
> > > > > > 
> > > > > > Someone implemented it incorrectly then.
> > > > > 
> > > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > > document any of it, and when people try to clean things up they get told
> > > > > that we got it all wrong.
> > > > 
> > > > FWIW, this was an i915 property and if another driver uses the same
> > > > property name it must have the same behavior. Yes, it isn't standardized
> > > > and yes, it's not documented (hence this effort here) but it's still on
> > > > vc4 to make the property compatible.
> > > 
> > > How is it not compatible? It's a superset of what i915 provides, but
> > > it's strictly compatible with it.
> > 
> > No it is not.
> 
> The property is compatible with i915 interpretation of it, whether you
> like it or not. And that's what Sebastian was referring to.
> 
> > Eg. what happens if you set the thing to full range for RGB (which you
> > must on many broken monitors), and then the kernel automagically
> > switches to YCbCr (for whatever reason) but the monitor doesn't
> > support full range YCbCr? Answer: you get crap output.
> 
> And that part is just moving goalposts.

No. Allowing users to get correct colors with broken displays
is the sole reason why this property even exists.

-- 
Ville Syrj?l?
Intel


From linus.walleij at linaro.org  Tue Feb 13 00:44:23 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 13 Feb 2024 09:44:23 +0100
Subject: [PATCH v1 09/14] ARM: dts: imx6ull: fix pinctrl node name
In-Reply-To: <20240210012114.489102-10-sre@kernel.org>
References: <20240210012114.489102-1-sre@kernel.org> <20240210012114.489102-10-sre@kernel.org>
Message-ID: <CACRpkdaem7xe9PRu9U5ivaQYegB67E0W-SLrHe6abY8+Uuztqw@mail.gmail.com>

On Sat, Feb 10, 2024 at 2:21?AM Sebastian Reichel <sre at kernel.org> wrote:

> pinctrl node name must be either pinctrl or pinmux.
>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Tue Feb 13 00:46:51 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 13 Feb 2024 09:46:51 +0100
Subject: [PATCH v2 01/17] dt-bindings: pinctrl: fsl,imx6ul-pinctrl:
 convert to YAML
In-Reply-To: <20240213010347.1075251-2-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org> <20240213010347.1075251-2-sre@kernel.org>
Message-ID: <CACRpkdZ1VwU1xpf8Fe7qNn-WEfUGsNjWD3jFK0+5LxgxNtu+gA@mail.gmail.com>

On Tue, Feb 13, 2024 at 2:03?AM Sebastian Reichel <sre at kernel.org> wrote:

> Convert i.MX6UL pinctrl bindings to YAML.
>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From neil.armstrong at linaro.org  Tue Feb 13 00:47:03 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 13 Feb 2024 09:47:03 +0100
Subject: [PATCH v1] arch: arm64: dts: meson: a1: add assigned-clocks
 for usb node
In-Reply-To: <20240124130623.3471236-1-avromanov@salutedevices.com>
References: <20240124130623.3471236-1-avromanov@salutedevices.com>
Message-ID: <170781402367.1503948.783057553743938971.b4-ty@linaro.org>

Hi,

On Wed, 24 Jan 2024 16:06:23 +0300, Alexey Romanov wrote:
> To ensure proper functionality of USB, it is necessary to use
> the rate of 64000000 for CLKID_USB_BUS. For instance, adb may
> not function correctly without this setting. This information
> has been derived from the vendor SDK.
> 
> 

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v6.9/arm64-dt)

[1/1] arch: arm64: dts: meson: a1: add assigned-clocks for usb node
      https://git.kernel.org/amlogic/c/d1159418fbd5880d3285f4797d3f11eeaf6d0d42

These changes has been applied on the intermediate git tree [1].

The v6.9/arm64-dt branch will then be sent via a formal Pull Request to the Linux SoC maintainers
for inclusion in their intermediate git branches in order to be sent to Linus during
the next merge window, or sooner if it's a set of fixes.

In the cases of fixes, those will be merged in the current release candidate
kernel and as soon they appear on the Linux master branch they will be
backported to the previous Stable and Long-Stable kernels [2].

The intermediate git branches are merged daily in the linux-next tree [3],
people are encouraged testing these pre-release kernels and report issues on the
relevant mailing-lists.

If problems are discovered on those changes, please submit a signed-off-by revert
patch followed by a corrective changeset.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git
[2] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
[3] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git

-- 
Neil



From neil.armstrong at linaro.org  Tue Feb 13 00:47:04 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 13 Feb 2024 09:47:04 +0100
Subject: [PATCH v1 0/2] meson-axg: properly setup CPU power management
In-Reply-To: <20240209212816.11187-1-ddrokosov@salutedevices.com>
References: <20240209212816.11187-1-ddrokosov@salutedevices.com>
Message-ID: <170781402460.1503948.8383837524449723560.b4-ty@linaro.org>

Hi,

On Sat, 10 Feb 2024 00:28:04 +0300, Dmitry Rokosov wrote:
> The Meson AXG leverages the SCPI ARM protocol for the management of CPU
> power, thermal, and frequency. This series addresses several issues that
> have impacted the functionality of the power_allocator thermal governor
> and cpufreq cooling devices.
> 
> Dmitry Rokosov (2):
>   arm64: dts: amlogic: axg: move cpu cooling-cells to common dtsi
>   arm64: dts: amlogic: axg: initialize default SoC capacitance
> 
> [...]

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v6.9/arm64-dt)

[1/2] arm64: dts: amlogic: axg: move cpu cooling-cells to common dtsi
      https://git.kernel.org/amlogic/c/7c3215fe05fe3b8faacc03245cc922c4b98075d7
[2/2] arm64: dts: amlogic: axg: initialize default SoC capacitance
      https://git.kernel.org/amlogic/c/a06d4fdec1ce800188bec15c0219d6774dd145f8

These changes has been applied on the intermediate git tree [1].

The v6.9/arm64-dt branch will then be sent via a formal Pull Request to the Linux SoC maintainers
for inclusion in their intermediate git branches in order to be sent to Linus during
the next merge window, or sooner if it's a set of fixes.

In the cases of fixes, those will be merged in the current release candidate
kernel and as soon they appear on the Linux master branch they will be
backported to the previous Stable and Long-Stable kernels [2].

The intermediate git branches are merged daily in the linux-next tree [3],
people are encouraged testing these pre-release kernels and report issues on the
relevant mailing-lists.

If problems are discovered on those changes, please submit a signed-off-by revert
patch followed by a corrective changeset.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git
[2] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
[3] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git

-- 
Neil



From neil.armstrong at linaro.org  Tue Feb 13 00:47:05 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 13 Feb 2024 09:47:05 +0100
Subject: [PATCH] arm64: dts: amlogic: t7: minor whitespace cleanup
In-Reply-To: <20240208105252.128940-1-krzysztof.kozlowski@linaro.org>
References: <20240208105252.128940-1-krzysztof.kozlowski@linaro.org>
Message-ID: <170781402554.1503948.12321560831974589557.b4-ty@linaro.org>

Hi,

On Thu, 08 Feb 2024 11:52:52 +0100, Krzysztof Kozlowski wrote:
> The DTS code coding style expects exactly one space before '{'
> character.
> 
> 

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v6.9/arm64-dt)

[1/1] arm64: dts: amlogic: t7: minor whitespace cleanup
      https://git.kernel.org/amlogic/c/9225771676d14673acd225a48eaa49ef3998af41

These changes has been applied on the intermediate git tree [1].

The v6.9/arm64-dt branch will then be sent via a formal Pull Request to the Linux SoC maintainers
for inclusion in their intermediate git branches in order to be sent to Linus during
the next merge window, or sooner if it's a set of fixes.

In the cases of fixes, those will be merged in the current release candidate
kernel and as soon they appear on the Linux master branch they will be
backported to the previous Stable and Long-Stable kernels [2].

The intermediate git branches are merged daily in the linux-next tree [3],
people are encouraged testing these pre-release kernels and report issues on the
relevant mailing-lists.

If problems are discovered on those changes, please submit a signed-off-by revert
patch followed by a corrective changeset.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git
[2] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
[3] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git

-- 
Neil



From linus.walleij at linaro.org  Tue Feb 13 00:47:54 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 13 Feb 2024 09:47:54 +0100
Subject: [PATCH v2 09/17] ARM: dts: imx6ull: fix pinctrl node name
In-Reply-To: <20240213010347.1075251-10-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org> <20240213010347.1075251-10-sre@kernel.org>
Message-ID: <CACRpkdZqmfiY5B6y0kSSanF6cw1_jU-BZ5dC8YEp0Oz+78yqQw@mail.gmail.com>

On Tue, Feb 13, 2024 at 2:03?AM Sebastian Reichel <sre at kernel.org> wrote:

> pinctrl node name must be either pinctrl or pinmux.
>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From cristian.marussi at arm.com  Tue Feb 13 00:49:51 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 13 Feb 2024 08:49:51 +0000
Subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock
 .is_notify_supported callback
In-Reply-To: <202402131047.2NVZWHma-lkp@intel.com>
References: <20240212123233.1230090-7-cristian.marussi@arm.com>
 <202402131047.2NVZWHma-lkp@intel.com>
Message-ID: <ZcstL8tRVKIUFoBr@pluto>

On Tue, Feb 13, 2024 at 10:58:23AM +0800, kernel test robot wrote:
> Hi Cristian,
> 
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on soc/for-next]
> [also build test ERROR on linus/master v6.8-rc4 next-20240212]
> [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#_base_tree_information]
> 

Hi,

this series, as stated in the cover-letter, is based off the current tip of

	sudeep/for-next/scmi/updates

and particularly needs commit:

	9c5bc650031e firmware: arm_scmi: Rework clock domain info lookups

from there, since it contains the missing scmi_clock_domain_lookup().

Not_sure/dont_known if there is any way to convey this "based-on-branch"
info to your/any CI at the moment.

Thanks,
Cristian

> url:    https://github.com/intel-lab-lkp/linux/commits/Cristian-Marussi/firmware-arm_scmi-Check-for-notification-support/20240212-203727
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
> patch link:    https://lore.kernel.org/r/20240212123233.1230090-7-cristian.marussi%40arm.com
> patch subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock .is_notify_supported callback
> config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20240213/202402131047.2NVZWHma-lkp at intel.com/config)
> compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project c08b90c50bcac9f3f563c79491c8dbcbe7c3b574)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240213/202402131047.2NVZWHma-lkp at intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp at intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202402131047.2NVZWHma-lkp at intel.com/
> 
> All errors (new ones prefixed by >>):
> 
> >> drivers/firmware/arm_scmi/clock.c:853:8: error: call to undeclared function 'scmi_clock_domain_lookup'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
>      853 |         clk = scmi_clock_domain_lookup(ci, src_id);
>          |               ^
> >> drivers/firmware/arm_scmi/clock.c:853:6: error: incompatible integer to pointer conversion assigning to 'struct scmi_clock_info *' from 'int' [-Wint-conversion]
>      853 |         clk = scmi_clock_domain_lookup(ci, src_id);
>          |             ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    2 errors generated.
> 
> 
> vim +/scmi_clock_domain_lookup +853 drivers/firmware/arm_scmi/clock.c
> 
>    842	
>    843	static bool scmi_clk_notify_supported(const struct scmi_protocol_handle *ph,
>    844					      u8 evt_id, u32 src_id)
>    845	{
>    846		bool supported;
>    847		struct scmi_clock_info *clk;
>    848		struct clock_info *ci = ph->get_priv(ph);
>    849	
>    850		if (evt_id >= ARRAY_SIZE(evt_2_cmd))
>    851			return false;
>    852	
>  > 853		clk = scmi_clock_domain_lookup(ci, src_id);
>    854		if (IS_ERR(clk))
>    855			return false;
>    856	
>    857		if (evt_id == SCMI_EVENT_CLOCK_RATE_CHANGED)
>    858			supported = clk->rate_changed_notifications;
>    859		else
>    860			supported = clk->rate_change_requested_notifications;
>    861	
>    862		return supported;
>    863	}
>    864	
> 
> -- 
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki


From piotr.firek at financialflows.pl  Tue Feb 13 00:50:12 2024
From: piotr.firek at financialflows.pl (Piotr Firek)
Date: Tue, 13 Feb 2024 08:50:12 GMT
Subject: =?UTF-8?Q?Prosz=C4=99_o_kontakt?=
Message-ID: <20240213074501-0.1.2n.8i4i.0.hosrpy8mk8@financialflows.pl>

Dzie? dobry,

Czy jest mo?liwo?? nawi?zania wsp??pracy z Pa?stwem?

Z ch?ci? porozmawiam z osob? zajmuj?c? si? dzia?aniami zwi?zanymi ze sprzeda??.

Pomagamy skutecznie pozyskiwa? nowych klient?w.

Zapraszam do kontaktu.


Pozdrawiam
Piotr Firek


From wahrenst at gmx.net  Tue Feb 13 00:52:36 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Tue, 13 Feb 2024 09:52:36 +0100
Subject: [PATCH v1 14/14] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <56eb2fnpmaya5rwfk5jvluvsidokzpoujeatihgrbxlytbzx5x@ozco7pbgkugp>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-15-sre@kernel.org>
 <c38e7c68-e725-4174-aa0a-0594a55c8d56@gmx.net>
 <56eb2fnpmaya5rwfk5jvluvsidokzpoujeatihgrbxlytbzx5x@ozco7pbgkugp>
Message-ID: <bb7eccc2-a821-4326-b071-2f8a89038dd7@gmx.net>

>>> +&ecspi3 {
>>> +	cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&mux_spi3>, <&mux_spi3_cs>;
>>> +	status = "okay";
>>> +
>>> +	panel at 0 {
>>> +		compatible = "inanbo,t28cp45tn89-v17";
>>> +		reg = <0>;
>>> +		backlight = <&panel_backlight>;
>>> +		power-supply = <&reg_vsd>;
>>> +		spi-cpha;
>>> +		spi-cpol;
>>> +		spi-max-frequency = <100000>;
>> This seems slow to me. Is this a limitation of the display?
> I just used something slow, which should definitely work. I will try
> to increase to 1MHz. Note, that the display is not driven via SPI.
> SPI is just used for the configuration.
Thanks for clarification. Yes, 1 MHz would be better.
>
> Thanks for the review,
>
> -- Sebastian



From tony at atomide.com  Tue Feb 13 00:56:19 2024
From: tony at atomide.com (Tony Lindgren)
Date: Tue, 13 Feb 2024 10:56:19 +0200
Subject: [PATCH] arm64: dts: ti: k3-am62-wakeup: Configure ti-sysc for
 wkup_uart0
In-Reply-To: <e28a4f16-f9a8-499a-a6a3-7acef0e0aa10@ti.com>
References: <20230912111215.18415-1-tony@atomide.com>
 <170368552643.1332094.7883858507182654481.b4-ty@ti.com>
 <e28a4f16-f9a8-499a-a6a3-7acef0e0aa10@ti.com>
Message-ID: <20240213085619.GF52537@atomide.com>

* Raghavendra, Vignesh <vigneshr at ti.com> [231227 15:22]:
> 
> 
> On 12/27/2023 7:29 PM, Vignesh Raghavendra wrote:
> > 
> > On Tue, 12 Sep 2023 14:12:15 +0300, Tony Lindgren wrote:
> >> The devices in the wkup domain are capable of waking up the system from
> >> suspend. We can configure the wkup domain devices in a generic way using
> >> the ti-sysc interconnect target module driver like we have done with the
> >> earlier TI SoCs.
> >>
> >> As ti-sysc manages the SYSCONFIG related registers independent of the
> >> child hardware device, the wake-up configuration is also set even if
> >> wkup_uart0 is reserved by sysfw.
> >>
> >> [...]
> > 
> > Applied, thanks!
> > 
> > [1/1] arm64: dts: ti: k3-am62-wakeup: Configure ti-sysc for wkup_uart0
> >       commit: 86224524b52a8efba26f920736d08c8bfdd22d87
> > 
> 
> 
> Please ignore above. I meant to pick v4. Sorry for the noise!

So we need to add ti,no-reset-on-init as noted by Markus. As I'm not
seeing this in Linux next, I'll send out v5 patch. If you need an
incremental fix I can do that too naturally.

Regards,

Tony


From mihai.sain at microchip.com  Tue Feb 13 00:56:11 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 10:56:11 +0200
Subject: [PATCH 0/3] Add initial support for Microchip SAMA7G54 Curiosity board
Message-ID: <20240213085614.26804-1-mihai.sain@microchip.com>

This patch series adds initial support for Microchip SAMA7G54 Curiosity board.

Mihai Sain (3):
  dt-bindings: ARM: at91: Document Microchip SAMA7G54 Curiosity
  ARM: dts: microchip: sama7g5: Add flexcom 10 node
  ARM: dts: microchip: sama7g54_curiosity: Add initial device tree of the board

 .../devicetree/bindings/arm/atmel-at91.yaml   |   6 +
 arch/arm/boot/dts/microchip/Makefile          |   4 +-
 .../dts/microchip/at91-sama7g54_curiosity.dts | 491 ++++++++++++++++++
 arch/arm/boot/dts/microchip/sama7g5.dtsi      |  26 +
 4 files changed, 526 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts

-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 00:56:12 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 10:56:12 +0200
Subject: [PATCH 1/3] dt-bindings: ARM: at91: Document Microchip SAMA7G54 Curiosity
In-Reply-To: <20240213085614.26804-1-mihai.sain@microchip.com>
References: <20240213085614.26804-1-mihai.sain@microchip.com>
Message-ID: <20240213085614.26804-2-mihai.sain@microchip.com>

Document device tree binding of the Microchip SAMA7G54 Curiosity board.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index 89d75fbb1de4..82f37328cc69 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -179,6 +179,12 @@ properties:
           - const: microchip,sama7g5
           - const: microchip,sama7
 
+      - description: Microchip SAMA7G54 Curiosity Board
+        items:
+          - const: microchip,sama7g54-curiosity
+          - const: microchip,sama7g5
+          - const: microchip,sama7
+
       - description: Microchip LAN9662 Evaluation Boards.
         items:
           - enum:
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 00:56:13 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 10:56:13 +0200
Subject: [PATCH 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <20240213085614.26804-1-mihai.sain@microchip.com>
References: <20240213085614.26804-1-mihai.sain@microchip.com>
Message-ID: <20240213085614.26804-3-mihai.sain@microchip.com>

Add flexcom 10 node for usage on the SAMA7G54 Curiosity board.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/sama7g5.dtsi | 26 ++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
index 269e0a3ca269..c90e404e8ed9 100644
--- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
+++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
@@ -958,6 +958,32 @@ i2c9: i2c at 600 {
 			};
 		};
 
+		flx10: flexcom at e2820000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe2820000 0x200>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe2820000 0x800>;
+			status = "disabled";
+
+			i2c10: i2c at 600 {
+				compatible = "microchip,sama7g5-i2c", "microchip,sam9x60-i2c";
+				reg = <0x600 0x200>;
+				interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
+				atmel,fifo-size = <32>;
+				dmas = <&dma0 AT91_XDMAC_DT_PERID(25)>,
+					<&dma0 AT91_XDMAC_DT_PERID(26)>;
+				dma-names = "rx", "tx";
+				atmel,use-dma-rx;
+				atmel,use-dma-tx;
+				status = "disabled";
+			};
+		};
+
 		flx11: flexcom at e2824000 {
 			compatible = "atmel,sama5d2-flexcom";
 			reg = <0xe2824000 0x200>;
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 00:56:14 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 10:56:14 +0200
Subject: [PATCH 3/3] ARM: dts: microchip: sama7g54_curiosity: Add initial device tree of the board
In-Reply-To: <20240213085614.26804-1-mihai.sain@microchip.com>
References: <20240213085614.26804-1-mihai.sain@microchip.com>
Message-ID: <20240213085614.26804-4-mihai.sain@microchip.com>

Add initial device tree of the SAMA7G54 Curiosity board.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/Makefile          |   4 +-
 .../dts/microchip/at91-sama7g54_curiosity.dts | 491 ++++++++++++++++++
 2 files changed, 494 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts

diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
index efde9546c8f4..29b2a788748f 100644
--- a/arch/arm/boot/dts/microchip/Makefile
+++ b/arch/arm/boot/dts/microchip/Makefile
@@ -12,6 +12,7 @@ DTC_FLAGS_at91-sama5d3_eds := -@
 DTC_FLAGS_at91-sama5d3_xplained := -@
 DTC_FLAGS_at91-sama5d4_xplained := -@
 DTC_FLAGS_at91-sama7g5ek := -@
+DTC_FLAGS_at91-sama7g54_curiosity := -@
 dtb-$(CONFIG_SOC_AT91RM9200) += \
 	at91rm9200ek.dtb \
 	mpa1600.dtb
@@ -87,7 +88,8 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
 	at91-sama5d4ek.dtb \
 	at91-vinco.dtb
 dtb-$(CONFIG_SOC_SAMA7G5) += \
-	at91-sama7g5ek.dtb
+	at91-sama7g5ek.dtb \
+	at91-sama7g54_curiosity.dtb
 
 dtb-$(CONFIG_SOC_LAN966) += \
 	lan966x-kontron-kswitch-d10-mmt-6g-2gs.dtb \
diff --git a/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
new file mode 100644
index 000000000000..c2955a170658
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sama7g54_curiosity.dts - Device Tree file for SAMA7G54 Curiosity Board
+ *
+ * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Mihai Sain <mihai.sain at microchip.com>
+ *
+ */
+/dts-v1/;
+#include "sama7g5-pinfunc.h"
+#include "sama7g5.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/pinctrl/at91.h>
+
+/ {
+	model = "Microchip SAMA7G54 Curiosity";
+	compatible = "microchip,sama7g54-curiosity", "microchip,sama7g5", "microchip,sama7";
+
+	chosen {
+		bootargs = "console=ttyS0,115200 root=/dev/mmcblk1p2 rw rootwait";
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		serial0 = &uart3;
+		i2c0 = &i2c10;
+	};
+
+	clocks {
+		slow_xtal {
+			clock-frequency = <32768>;
+		};
+
+		main_xtal {
+			clock-frequency = <24000000>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_key_gpio_default>;
+
+		button-user {
+			label = "user-button";
+			gpios = <&pioA PIN_PD19 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_PROG1>;
+			wakeup-source;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_led_gpio_default>;
+		status = "okay";
+
+		led-red {
+			label = "red";
+			gpios = <&pioA PIN_PD13 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		led-green {
+			label = "green";
+			gpios = <&pioA PIN_PD14 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		led-blue {
+			label = "blue";
+			gpios = <&pioA PIN_PB15 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x10000000>; // 256 MiB DDR3L-1066 16-bit
+	};
+};
+
+&adc {
+	vddana-supply = <&vddout25>;
+	vref-supply = <&vddout25>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_mikrobus1_an_default &pinctrl_mikrobus2_an_default>;
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vddcpu>;
+};
+
+&dma0 {
+	status = "okay";
+};
+
+&dma1 {
+	status = "okay";
+};
+
+&dma2 {
+	status = "okay";
+};
+
+&ebi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_nand_default>;
+	status = "okay";
+
+	nand_controller: nand-controller {
+		status = "okay";
+
+		nand at 3 {
+			reg = <0x3 0x0 0x800000>;
+			atmel,rb = <0>;
+			nand-bus-width = <8>;
+			nand-ecc-mode = "hw";
+			nand-ecc-strength = <8>;
+			nand-ecc-step-size = <512>;
+			nand-on-flash-bbt;
+			label = "nand";
+			status = "okay";
+
+			partitions {
+				compatible = "fixed-partitions";
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				at91bootstrap at 0 {
+					label = "nand: at91bootstrap";
+					reg = <0x0 0x40000>;
+				};
+
+				bootloader at 40000 {
+					label = "nand: u-boot";
+					reg = <0x40000 0x100000>;
+				};
+
+				bootloaderenv at 140000 {
+					label = "nand: u-boot env";
+					reg = <0x140000 0x40000>;
+				};
+
+				dtb at 180000 {
+					label = "nand: device tree";
+					reg = <0x180000 0x80000>;
+				};
+
+				kernel at 200000 {
+					label = "nand: kernel";
+					reg = <0x200000 0x600000>;
+				};
+
+				rootfs at 800000 {
+					label = "nand: rootfs";
+					reg = <0x800000 0x1f800000>;
+				};
+			};
+		};
+	};
+};
+
+&flx3 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+	status = "okay";
+
+	uart3: serial at 200 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flx3_default>;
+		status = "okay";
+	};
+};
+
+&flx10 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
+	status = "okay";
+
+	i2c10: i2c at 600 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flx10_default>;
+		i2c-analog-filter;
+		i2c-digital-filter;
+		i2c-digital-filter-width-ns = <35>;
+		status = "okay";
+
+		adc at 1f {
+			compatible = "microchip,pac1934";
+			reg = <0x1f>;
+		};
+
+		eeprom at 51 {
+			compatible = "atmel,24c02";
+			reg = <0x51>;
+			pagesize = <16>;
+			size = <256>;
+			status = "okay";
+		};
+
+		mcp16502 at 5b {
+			compatible = "microchip,mcp16502";
+			reg = <0x5b>;
+			status = "okay";
+
+			regulators {
+				vdd_3v3: VDD_IO {
+					regulator-name = "VDD_IO";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-microvolt = <3300000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+						regulator-mode = <4>;
+					};
+				};
+
+				vddioddr: VDD_DDR {
+					regulator-name = "VDD_DDR";
+					regulator-min-microvolt = <1350000>;
+					regulator-max-microvolt = <1350000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-microvolt = <1350000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-on-in-suspend;
+						regulator-suspend-microvolt = <1350000>;
+						regulator-mode = <4>;
+					};
+				};
+
+				vddcore: VDD_CORE {
+					regulator-name = "VDD_CORE";
+					regulator-min-microvolt = <1150000>;
+					regulator-max-microvolt = <1150000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-voltage = <1150000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+						regulator-mode = <4>;
+					};
+				};
+
+				vddcpu: VDD_OTHER {
+					regulator-name = "VDD_OTHER";
+					regulator-min-microvolt = <1050000>;
+					regulator-max-microvolt = <1250000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-ramp-delay = <3125>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-voltage = <1050000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+						regulator-mode = <4>;
+					};
+				};
+
+				vldo1: LDO1 {
+					regulator-name = "LDO1";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-suspend-voltage = <1800000>;
+						regulator-on-in-suspend;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+					};
+				};
+
+				vldo2: LDO2 {
+					regulator-name = "LDO2";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-suspend-voltage = <3300000>;
+						regulator-on-in-suspend;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+					};
+				};
+			};
+		};
+	};
+};
+
+&qspi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi1_default>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-max-frequency = <100000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+		m25p,fast-read;
+		status = "okay";
+	};
+};
+
+&pioA {
+	pinctrl_flx3_default: flx3-default {
+		pinmux = <PIN_PD16__FLEXCOM3_IO0>,
+			 <PIN_PD17__FLEXCOM3_IO1>;
+		bias-pull-up;
+	};
+
+	pinctrl_flx10_default: flx10-default {
+		pinmux = <PIN_PC30__FLEXCOM10_IO0>,
+			 <PIN_PC31__FLEXCOM10_IO1>;
+		bias-pull-up;
+	};
+
+	pinctrl_key_gpio_default: key-gpio-default {
+		pinmux = <PIN_PD19__GPIO>;
+		bias-pull-up;
+	};
+
+	pinctrl_led_gpio_default: led-gpio-default {
+		pinmux = <PIN_PD13__GPIO>,
+			 <PIN_PD14__GPIO>,
+			 <PIN_PB15__GPIO>;
+		bias-pull-up;
+	};
+
+	pinctrl_mikrobus1_an_default: mikrobus1-an-default {
+		pinmux = <PIN_PC15__GPIO>;
+		bias-disable;
+	};
+
+	pinctrl_mikrobus2_an_default: mikrobus2-an-default {
+		pinmux = <PIN_PC13__GPIO>;
+		bias-disable;
+	};
+
+	pinctrl_nand_default: nand-default {
+		pinmux = <PIN_PD9__D0>,
+			 <PIN_PD10__D1>,
+			 <PIN_PD11__D2>,
+			 <PIN_PC21__D3>,
+			 <PIN_PC22__D4>,
+			 <PIN_PC23__D5>,
+			 <PIN_PC24__D6>,
+			 <PIN_PD2__D7>,
+			 <PIN_PD3__NANDRDY>,
+			 <PIN_PD4__NCS3_NANDCS>,
+			 <PIN_PD5__NWE_NWR0_NANDWE>,
+			 <PIN_PD6__NRD_NANDOE>,
+			 <PIN_PD7__A21_NANDALE>,
+			 <PIN_PD8__A22_NANDCLE>;
+		bias-disable;
+		slew-rate = <0>;
+	};
+
+	pinctrl_qspi1_default: qspi1-default {
+		pinmux = <PIN_PB22__QSPI1_IO3>,
+			 <PIN_PB23__QSPI1_IO2>,
+			 <PIN_PB24__QSPI1_IO1>,
+			 <PIN_PB25__QSPI1_IO0>,
+			 <PIN_PB26__QSPI1_CS>,
+			 <PIN_PB27__QSPI1_SCK>;
+		bias-pull-up;
+		slew-rate = <0>;
+	};
+
+	pinctrl_sdmmc0_default: sdmmc0-default {
+		pinmux = <PIN_PA0__SDMMC0_CK>,
+			 <PIN_PA1__SDMMC0_CMD>,
+			 <PIN_PA2__SDMMC0_RSTN>,
+			 <PIN_PA3__SDMMC0_DAT0>,
+			 <PIN_PA4__SDMMC0_DAT1>,
+			 <PIN_PA5__SDMMC0_DAT2>,
+			 <PIN_PA6__SDMMC0_DAT3>;
+		bias-pull-up;
+		slew-rate = <0>;
+	};
+
+	pinctrl_sdmmc1_default: sdmmc1-default {
+		pinmux = <PIN_PB29__SDMMC1_CMD>,
+			 <PIN_PB30__SDMMC1_CK>,
+			 <PIN_PB31__SDMMC1_DAT0>,
+			 <PIN_PC0__SDMMC1_DAT1>,
+			 <PIN_PC1__SDMMC1_DAT2>,
+			 <PIN_PC2__SDMMC1_DAT3>,
+			 <PIN_PC4__SDMMC1_CD>;
+		bias-pull-up;
+		slew-rate = <0>;
+	};
+};
+
+&rtt {
+	atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
+};
+
+// M.2 slot for wireless card
+&sdmmc0 {
+	bus-width = <4>;
+	cd-gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	sdhci-caps-mask = <0x0 0x00200000>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc0_default>;
+	status = "okay";
+};
+
+// micro SD socket
+&sdmmc1 {
+	bus-width = <4>;
+	disable-wp;
+	sdhci-caps-mask = <0x0 0x00200000>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc1_default>;
+	status = "okay";
+};
+
+&shdwc {
+	debounce-delay-us = <976>;
+	status = "okay";
+
+	input at 0 {
+		reg = <0>;
+	};
+};
+
+&tcb0 {
+	timer0: timer at 0 {
+		compatible = "atmel,tcb-timer";
+		reg = <0>;
+	};
+
+	timer1: timer at 1 {
+		compatible = "atmel,tcb-timer";
+		reg = <1>;
+	};
+};
+
+&trng {
+	status = "okay";
+};
+
+&vddout25 {
+	vin-supply = <&vdd_3v3>;
+	status = "okay";
+};
-- 
2.43.0



From cristian.marussi at arm.com  Tue Feb 13 00:57:18 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 13 Feb 2024 08:57:18 +0000
Subject: [PATCH 1/2] firmware: arm_ffa: Make ffa_bus_type const
In-Reply-To: <20240211-bus_cleanup-firmware2-v1-1-1851c92c7be7@marliere.net>
References: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
 <20240211-bus_cleanup-firmware2-v1-1-1851c92c7be7@marliere.net>
Message-ID: <Zcsu7nj1MPzrES2x@pluto>

On Sun, Feb 11, 2024 at 12:51:29PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the ffa_bus_type variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>

Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>

Thanks,
Cristian

> ---
>  drivers/firmware/arm_ffa/bus.c | 2 +-
>  include/linux/arm_ffa.h        | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
> index 1c7940ba5539..2f557e90f2eb 100644
> --- a/drivers/firmware/arm_ffa/bus.c
> +++ b/drivers/firmware/arm_ffa/bus.c
> @@ -105,7 +105,7 @@ static struct attribute *ffa_device_attributes_attrs[] = {
>  };
>  ATTRIBUTE_GROUPS(ffa_device_attributes);
>  
> -struct bus_type ffa_bus_type = {
> +const struct bus_type ffa_bus_type = {
>  	.name		= "arm_ffa",
>  	.match		= ffa_device_match,
>  	.probe		= ffa_device_probe,
> diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
> index 3d0fde57ba90..c906f666ff5d 100644
> --- a/include/linux/arm_ffa.h
> +++ b/include/linux/arm_ffa.h
> @@ -209,7 +209,7 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev) { return false; }
>  #define module_ffa_driver(__ffa_driver)	\
>  	module_driver(__ffa_driver, ffa_register, ffa_unregister)
>  
> -extern struct bus_type ffa_bus_type;
> +extern const struct bus_type ffa_bus_type;
>  
>  /* FFA transport related */
>  struct ffa_partition_info {
> 
> -- 
> 2.43.0
> 


From wahrenst at gmx.net  Tue Feb 13 00:57:20 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Tue, 13 Feb 2024 09:57:20 +0100
Subject: [PATCH v1 07/14] dt-bindings: lcdif: Do not require power-domains
 for i.MX6ULL
In-Reply-To: <khwsxrpj5fgxl7ukiur2tdyy7a6d6h6zryc5z2h7o6f7k3b32p@cjqsmdbocfpe>
References: <20240210012114.489102-1-sre@kernel.org>
 <20240210012114.489102-8-sre@kernel.org>
 <a8b55331-a8c3-457e-83e0-2aa361ed23c6@gmx.net>
 <khwsxrpj5fgxl7ukiur2tdyy7a6d6h6zryc5z2h7o6f7k3b32p@cjqsmdbocfpe>
Message-ID: <d50150e4-79d7-4f1c-b221-a0503e6a0899@gmx.net>

Hi Sebastian,

Am 13.02.24 um 00:10 schrieb Sebastian Reichel:
> Hi Stefan,
>
> On Mon, Feb 12, 2024 at 08:20:35PM +0100, Stefan Wahren wrote:
>> Am 10.02.24 um 02:18 schrieb Sebastian Reichel:
>>> i.MX6UL(L) uses "fsl,imx6sx-lcdif" as fallback compatible string,
>>> but has only very lightweight DISPLAY power domain. Its DISPLAY
>>> power domain is not supported by the binding / Linux kernel at
>>> the moment. Since the current setup is working, let's remove the
>>> power-domain from being required for that platform to fix the warning
>>> printed by CHECK_DTBS=y.
>> i'm not sure this is a good idea. In case i.MX6UL(L) is different from
>> i.MX6SX here, then it should have a different compatible.
> It already has. The i.MX6UL(L) compatible looks like this:
>
> compatible = "fsl,imx6ul-lcdif", "fsl,imx6sx-lcdif"
>
> So the i.MX6SX one is just a fallback compatible. But the current
> requirement for power-domains affects i.MX6UL(L), since it says
> the compatible only needs to contain "fsl,imx6sx-lcdif" somewhere
> to make power-domains mandatory.
thanks, i misunderstood the commit message. I thought this was a
i.MX6UL(L) specific issue and the i.MX6SX is slightly different. In the
past the fallback compatible was sometimes abused.

So everything makes sense now.
> Note, that the kernel driver does not use "fsl,imx6ul-lcdif", so
> the hardware itself is indeed compatible.
>
> -- Sebastian
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From cristian.marussi at arm.com  Tue Feb 13 00:57:52 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 13 Feb 2024 08:57:52 +0000
Subject: [PATCH 2/2] firmware: arm_scmi: make scmi_bus_type const
In-Reply-To: <20240211-bus_cleanup-firmware2-v1-2-1851c92c7be7@marliere.net>
References: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
 <20240211-bus_cleanup-firmware2-v1-2-1851c92c7be7@marliere.net>
Message-ID: <ZcsvEOAmhUNC2lT2@pluto>

On Sun, Feb 11, 2024 at 12:51:30PM -0300, Ricardo B. Marliere wrote:
> Now that the driver core can properly handle constant struct bus_type,
> move the scmi_bus_type variable to be a constant structure as well,
> placing it into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
> ---

Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>

Thanks,
Cristian

>  drivers/firmware/arm_scmi/bus.c    | 2 +-
>  drivers/firmware/arm_scmi/common.h | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
> index c15928b8c5cc..609a6496c1d4 100644
> --- a/drivers/firmware/arm_scmi/bus.c
> +++ b/drivers/firmware/arm_scmi/bus.c
> @@ -263,7 +263,7 @@ static void scmi_dev_remove(struct device *dev)
>  		scmi_drv->remove(scmi_dev);
>  }
>  
> -struct bus_type scmi_bus_type = {
> +const struct bus_type scmi_bus_type = {
>  	.name =	"scmi_protocol",
>  	.match = scmi_dev_match,
>  	.probe = scmi_dev_probe,
> diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
> index 00b165d1f502..6affbfdd1dec 100644
> --- a/drivers/firmware/arm_scmi/common.h
> +++ b/drivers/firmware/arm_scmi/common.h
> @@ -141,7 +141,7 @@ scmi_revision_area_get(const struct scmi_protocol_handle *ph);
>  void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
>  				     u8 *prot_imp);
>  
> -extern struct bus_type scmi_bus_type;
> +extern const struct bus_type scmi_bus_type;
>  
>  #define SCMI_BUS_NOTIFY_DEVICE_REQUEST		0
>  #define SCMI_BUS_NOTIFY_DEVICE_UNREQUEST	1
> 
> -- 
> 2.43.0
> 


From w.egorov at phytec.de  Tue Feb 13 01:05:46 2024
From: w.egorov at phytec.de (Wadim Egorov)
Date: Tue, 13 Feb 2024 10:05:46 +0100
Subject: [PATCH v2 8/9] arm64: dts: ti: k3-am6*: Fix bus-width property in
 MMC nodes
In-Reply-To: <20240213081953.GB3810@francesco-nb>
References: <20240213002416.1560357-1-jm@ti.com>
 <20240213002416.1560357-9-jm@ti.com>
 <c6ad3a3e-330c-40cd-8e25-fd259fd1e398@phytec.de>
 <20240213081953.GB3810@francesco-nb>
Message-ID: <0d8d8b85-1208-4021-b1f8-1c1c593ddbfe@phytec.de>


Am 13.02.24 um 09:19 schrieb Francesco Dolcini:
> On Tue, Feb 13, 2024 at 06:07:28AM +0100, Wadim Egorov wrote:
>> Hi Judith,
>>
>> Am 13.02.24 um 01:24 schrieb Judith Mendez:
>>> Move bus-width property to *main.dtsi, above the OTAP/ITAP
>>> delay values. While there is no error with where it is
>>> currently at, it is easier to read the MMC node if the
>>> bus-width property is located above the OTAP/ITAP delay
>>> values consistently across MMC nodes.
>>>
>>> Add missing bus-width for MMC2 in k3-am62-main.
>>>
>>> Signed-off-by: Judith Mendez <jm at ti.com>
>>> ---
>>>    arch/arm64/boot/dts/ti/k3-am62-main.dtsi       | 5 +++--
>>>    arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 1 -
>>>    arch/arm64/boot/dts/ti/k3-am62a-main.dtsi      | 2 +-
>>>    arch/arm64/boot/dts/ti/k3-am64-main.dtsi       | 2 ++
>>>    arch/arm64/boot/dts/ti/k3-am642-evm.dts        | 2 --
>>>    arch/arm64/boot/dts/ti/k3-am642-sk.dts         | 1 -
>> I think you missed to update all non TI boards.
> Not sure which boards are you referring to.
>
> I would not change the verdin-am62 boards, the bus-width there is
> consistent with the schematics, it's just correct and in the right place
> IMO.

Ah, yes. Agree.


>
> Francesco
>


From rsc at runtux.com  Tue Feb 13 01:07:52 2024
From: rsc at runtux.com (Ralf Schlatterbeck)
Date: Tue, 13 Feb 2024 10:07:52 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop
 redundant GPIO node
In-Reply-To: <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
 <20240212115837.efz73yxinkysdmgh@runtux.com>
 <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
Message-ID: <20240213090752.5g7cnzkaqrfdqi4p@runtux.com>

On Mon, Feb 12, 2024 at 02:38:27PM +0100, Krzysztof Kozlowski wrote:
> On 12/02/2024 12:58, Ralf Schlatterbeck wrote:
> > On Mon, Feb 12, 2024 at 12:25:48PM +0100, Krzysztof Kozlowski wrote:
> >>
> >> Hm, I don't understand how exactly it helps. The GPIO expander has its
> >> own example and as you pointed below, this is basically the same code,
> >> except rw and backlight GPIOs.
> > 
> > The hd44780 is a display that is very often used.
> 
> GPIO expanders and their usage is nothing specific to this device -
> other devices also might benefit of them. Or the SoCs which have enough
> of GPIOs... I really do not understand why do we need expander here and
> how does it help

The hd44780 is most often sold together with that specific I/O expander.
The idea was to help people with that combination how to get their
device working.

> Anyway, binding examples should not be collection of unrelated
> solutions, because then we should accept for each device schema several
> other variations and combinations.

The solutions in that case are not unrelated because they document the
most-often-used hw combo.

I also didn't find any documentation of how to actually *use* the
pcf8575 I/O expander. Even
Documentation/devicetree/bindings/gpio/nxp,pcf8575.yaml
has only docs on how to instantiate the device on the i2c bus but not
how then to use the I/Os of the chip for something else.

So I'd ask again to not remove that piece of useful documentation.

And to get somehow philosophic:
I think that docs should be didactic, not optimized to the least
redundancy.

Thanks and kind regards,
Ralf
-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   www.runtux.com
Reichergasse 131, A-3411 Weidling       email: office at runtux.com


From angelogioacchino.delregno at collabora.com  Tue Feb 13 01:09:05 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 13 Feb 2024 10:09:05 +0100
Subject: [PATCH] arm64: dts: mediatek: mt8186: Add missing clocks to ssusb
 power domains
In-Reply-To: <985e1a4f-c538-4a9d-be58-2c688aa7350c@notapiano>
References: <20240212-mt8186-ssusb-domain-clk-fix-v1-1-26cb98746aa3@collabora.com>
 <985e1a4f-c538-4a9d-be58-2c688aa7350c@notapiano>
Message-ID: <6429a878-af3c-4182-b65f-60e1c0afccc5@collabora.com>

Il 12/02/24 22:53, N?colas F. R. A. Prado ha scritto:
> On Mon, Feb 12, 2024 at 04:32:44PM -0500, N?colas F. R. A. Prado wrote:
>> The ssusb power domains currently don't list any clocks, despite
>> depending on some, and thus rely on the bootloader leaving the required
>> clocks on in order to work.
>>
>> When booting with the upstream arm64 defconfig, the power domain
>> controller will defer probe until modules have loaded since it has an
>> indirect dependency on CONFIG_MTK_CMDQ, which is configured as a module.
>> However at the point where modules are loaded, unused clocks are also
>> disabled, causing the ssusb domains to fail to be enabled and
>> consequently the controller to fail probe:
>>
>> mtk-power-controller 10006000.syscon:power-controller: /soc/syscon at 10006000/power-controller/power-domain at 4: failed to power on domain: -110
>> mtk-power-controller: probe of 10006000.syscon:power-controller failed with error -110
>>
>> Add the missing clocks to the ssusb power domains so the power
>> controller can boot without relying on bootloader state.
>>
>> Fixes: d9e43c1e7a38 ("arm64: dts: mt8186: Add power domains controller")
>> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
>> ---
>>   arch/arm64/boot/dts/mediatek/mt8186.dtsi | 8 ++++++++
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
>> index adaf5e57fac5..02f33ec3cbd3 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi
>> +++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
>> @@ -931,11 +931,19 @@ power-domain at MT8186_POWER_DOMAIN_CSIRX_TOP {
>>   
>>   				power-domain at MT8186_POWER_DOMAIN_SSUSB {
>>   					reg = <MT8186_POWER_DOMAIN_SSUSB>;
>> +					clocks = <&topckgen CLK_TOP_USB_TOP>,
>> +						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>,
>> +						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_XHCI>;
>> +					clock-names = "sys_ck", "ref_ck", "xhci_ck";
>>   					#power-domain-cells = <0>;
>>   				};
>>   
>>   				power-domain at MT8186_POWER_DOMAIN_SSUSB_P1 {
>>   					reg = <MT8186_POWER_DOMAIN_SSUSB_P1>;
>> +					clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>,
>> +						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>,
>> +						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_XHCI>;
>> +					clock-names = "sys_ck", "ref_ck", "xhci_ck";
> 
> I forgot to mention this here, but the XHCI clock wasn't needed to get the power
> domains to work per se, but leaving it out caused issues when probing the mtu3
> devices:
> <3>[   15.431506] mtu3 11201000.usb: clks of sts1 are not stable!
> <3>[   15.443965] mtu3 11201000.usb: device enable failed -110
> <3>[   15.454306] mtu3 11201000.usb: mtu3 hw init failed:-110
> <3>[   15.463865] mtu3 11201000.usb: failed to initialize gadget
> <4>[   15.477890] mtu3: probe of 11201000.usb failed with error -110
> 
> <3>[   15.514603] mtu3 11281000.usb: clks of sts1 are not stable!
> <3>[   15.525239] mtu3 11281000.usb: device enable failed -110
> <3>[   15.614174] mtu3 11281000.usb: mtu3 hw init failed:-110
> <3>[   15.619647] mtu3 11281000.usb: failed to initialize gadget
> <4>[   15.630623] mtu3: probe of 11281000.usb failed with error -110
> 
> Not sure if this issue should be handled separately (maybe the mtu3 device
> should enable the XHCI clock?), but I opted to include the clock here to get
> boot working for this device at once.
> 

Hey Nicolas,
As you just said: having the XHCI clock in the power domain is wrong :-)

Almost comically, the MTU3 binding already supports having a XHCI clock
named "xhci_ck" after "dma_ck"... so the solution is to add the TOP_XHCI
clock in the mtu3 node and that's it. Do not remove it from the children.

mtu3-node-at-somewhere {
		clocks = <&topckgen CLK_TOP_USB_TOP>,
			 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>,
			 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_HCLK>,
			 <&infracfg_ao CLK_INFRA_AO_ICUSB>,
			 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_XHCI>;
		clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
}

Waiting for a v2...

Cheers,
Angelo


From angelogioacchino.delregno at collabora.com  Tue Feb 13 01:11:30 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 13 Feb 2024 10:11:30 +0100
Subject: [PATCH 3/3] arm64: dts: mediatek: mt7986: drop invalid thermal
 block clock
In-Reply-To: <20240213053739.14387-3-zajec5@gmail.com>
References: <20240213053739.14387-1-zajec5@gmail.com>
 <20240213053739.14387-3-zajec5@gmail.com>
Message-ID: <a99af719-4b2c-4c38-830e-b49a89971cb1@collabora.com>

Il 13/02/24 06:37, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Thermal block uses only two clocks. Its binding doesn't document or
> allow "adc_32k". Also Linux driver doesn't support it.
> 
> It has been additionally verified by Angelo by his detailed research on
> MT7981 / MT7986 clocks (thanks!).
> 
> This fixes:
> arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: thermal at 1100c800: clocks: [[4, 27], [4, 44], [4, 45]] is too long
>          from schema $id: http://devicetree.org/schemas/thermal/mediatek,thermal.yaml#
> arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: thermal at 1100c800: clock-names: ['therm', 'auxadc', 'adc_32k'] is too long
>          from schema $id: http://devicetree.org/schemas/thermal/mediatek,thermal.yaml#
> 
> Fixes: 0a9615d58d04 ("arm64: dts: mt7986: add thermal and efuse")
> Cc: Daniel Golle <daniel at makrotopia.org>
> Link: https://lore.kernel.org/linux-devicetree/17d143aa-576e-4d67-a0ea-b79f3518b81c at collabora.com/
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Feb 13 01:11:33 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 13 Feb 2024 10:11:33 +0100
Subject: [PATCH 1/3] arm64: dts: mediatek: mt7986: drop invalid properties
 from ethsys
In-Reply-To: <20240213053739.14387-1-zajec5@gmail.com>
References: <20240213053739.14387-1-zajec5@gmail.com>
Message-ID: <af0bda0a-2c8c-49ea-8e62-b6674b671a2f@collabora.com>

Il 13/02/24 06:37, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Mediatek ethsys controller / syscon binding doesn't allow any subnodes
> so "#address-cells" and "#size-cells" are redundant (actually:
> disallowed).
> 
> This fixes:
> arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: syscon at 15000000: '#address-cells', '#size-cells' do not match any of the regexes: 'pinctrl-[0-9]+'
>          from schema $id: http://devicetree.org/schemas/clock/mediatek,ethsys.yaml#
> 
> Fixes: 1f9986b258c2 ("arm64: dts: mediatek: add clock support for mt7986a")
> Cc: Sam Shih <sam.shih at mediatek.com>
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Feb 13 01:11:31 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 13 Feb 2024 10:11:31 +0100
Subject: [PATCH 2/3] arm64: dts: mediatek: mt7986: drop "#reset-cells"
 from Ethernet controller
In-Reply-To: <20240213053739.14387-2-zajec5@gmail.com>
References: <20240213053739.14387-1-zajec5@gmail.com>
 <20240213053739.14387-2-zajec5@gmail.com>
Message-ID: <ff6d841f-6eb8-449c-91cd-63e4958bf4eb@collabora.com>

Il 13/02/24 06:37, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Ethernet block doesn't include or act as a reset controller.
> Documentation also doesn't document "#reset-cells" for it.
> 
> This fixes:
> arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: ethernet at 15100000: Unevaluated properties are not allowed ('#reset-cells' was unexpected)
>          from schema $id: http://devicetree.org/schemas/net/mediatek,net.yaml#
> 
> Fixes: 082ff36bd5c0 ("arm64: dts: mediatek: mt7986: introduce ethernet nodes")
> Cc: Lorenzo Bianconi <lorenzo at kernel.org>
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Feb 13 01:12:46 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 13 Feb 2024 10:12:46 +0100
Subject: [PATCH] arm64: dts: mediatek: mt7986: prefix BPI-R3 cooling maps
 with "map-"
In-Reply-To: <20240213061459.17917-1-zajec5@gmail.com>
References: <20240213061459.17917-1-zajec5@gmail.com>
Message-ID: <3df28f8e-4efa-4fa6-b529-daba04969ede@collabora.com>

Il 13/02/24 07:14, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This fixes:
> arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: thermal-zones: cpu-thermal:cooling-maps: 'cpu-active-high', 'cpu-active-low', 'cpu-active-med' do not match any of the regexes: '^map[-a-zA-Z0-9]*$', 'pinctrl-[0-9]+'
>          from schema $id: http://devicetree.org/schemas/thermal/thermal-zones.yaml#
> 
> Fixes: c26f779a2295 ("arm64: dts: mt7986: add pwm-fan and cooling-maps to BPI-R3 dts")
> Cc: Daniel Golle <daniel at makrotopia.org>
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From peda at axentia.se  Tue Feb 13 01:19:09 2024
From: peda at axentia.se (Peter Rosin)
Date: Tue, 13 Feb 2024 10:19:09 +0100
Subject: [PATCH v5] arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in
 serdes_ln_ctrl
In-Reply-To: <20240213080348.248916-1-s-vadapalli@ti.com>
References: <20240213080348.248916-1-s-vadapalli@ti.com>
Message-ID: <1be60db1-f292-1074-5898-801380e1fb22@axentia.se>

Hi!

2024-02-13 at 09:03, Siddharth Vadapalli wrote:
> From: Chintan Vankar <c-vankar at ti.com>
> 
> Change offset in mux-reg-masks property for serdes_ln_ctrl node
> since reg-mux property is used in compatible.
> 
> Fixes: 2765149273f4 ("mux: mmio: use reg property when parent device is not a syscon")
> Signed-off-by: Chintan Vankar <c-vankar at ti.com>
> Acked-by: Andrew Davis <afd at ti.com>
> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
> ---
> Hello,
> 
> This patch is based on linux-next tagged next-20240213.
> The v4 of this patch is a part of the series at:
> https://lore.kernel.org/r/20240131101441.1362409-1-c-vankar at ti.com/
> 
> Since the v4 series mentioned above has open comments on the other
> patches in the series, this patch is being posted separately to unblock
> other dependent series which rely on the fix implemented by this patch.
> 
> Changes since v4:
> - Rebased patch on linux-next tagged next-20240213.
> 
> Regards,
> Siddharth.
> 
>  arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> index 3cb964982792..3b7f0eca977b 100644
> --- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> @@ -52,12 +52,12 @@ serdes_ln_ctrl: mux-controller at 4080 {
>  			compatible = "reg-mux";
>  			reg = <0x00004080 0x30>;
>  			#mux-control-cells = <1>;
> -			mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
> -					<0x4088 0x3>, <0x408c 0x3>, /* SERDES0 lane2/3 select */
> -					<0x4090 0x3>, <0x4094 0x3>, /* SERDES1 lane0/1 select */
> -					<0x4098 0x3>, <0x409c 0x3>, /* SERDES1 lane2/3 select */
> -					<0x40a0 0x3>, <0x40a4 0x3>, /* SERDES2 lane0/1 select */
> -					<0x40a8 0x3>, <0x40ac 0x3>; /* SERDES2 lane2/3 select */
> +			mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */
> +					<0x8 0x3>, <0xc 0x3>, /* SERDES0 lane2/3 select */
> +					<0x10 0x3>, <0x14 0x3>, /* SERDES1 lane0/1 select */
> +					<0x18 0x3>, <0x1c 0x3>, /* SERDES1 lane2/3 select */
> +					<0x20 0x3>, <0x24 0x3>, /* SERDES2 lane0/1 select */
> +					<0x28 0x3>, <0x2c 0x3>; /* SERDES2 lane2/3 select */
>  			idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>,
>  				      <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
>  				      <J784S4_SERDES0_LANE2_IP3_UNUSED>,

Ouch. I suspect there is a similar problem in
arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi:


	fss: bus at 47000000 {
		compatible = "simple-bus";
		reg = <0x0 0x47000000 0x0 0x100>;
		#address-cells = <2>;
		#size-cells = <2>;
		ranges;

		hbmc_mux: mux-controller at 47000004 {
			compatible = "reg-mux";
			reg = <0x00 0x47000004 0x00 0x2>;
			#mux-control-cells = <1>;
-			mux-reg-masks = <0x4 0x2>; /* HBMC select */
+			mux-reg-masks = <0x0 0x2>; /* HBMC select */
		};

Who knows what non-upstreamed devices and devicetrees are affected?
I guess we need to revert 2765149273f4 ("mux: mmio: use reg property
when parent device is not a syscon") unless someone sees a sane way
to fix this.

Cheers,
Peter


From u.kleine-koenig at pengutronix.de  Tue Feb 13 01:28:36 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Tue, 13 Feb 2024 10:28:36 +0100
Subject: [PATCH] ARM: Don't mention the full path of the source directory in mach-types.h
Message-ID: <20240213092835.754462-2-u.kleine-koenig@pengutronix.de>

To make package building reproducible independent of the location of the
source tree, the absolute path of this source tree must not be mentioned
in the built artifact. So strip $abs_srctree from FILENAME in the
output.

This fixes a warning issued by Yocto:
	WARNING: linux-lxatac-6.7-r0 do_package_qa: QA Issue: File /usr/src/debug/linux-lxatac/6.7-r0/arch/arm/include/generated/asm/mach-types.h in package linux-lxatac-src contains reference to TMPDIR

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 arch/arm/tools/gen-mach-types | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm/tools/gen-mach-types b/arch/arm/tools/gen-mach-types
index cbe1c33bb871..9592ceb8a102 100644
--- a/arch/arm/tools/gen-mach-types
+++ b/arch/arm/tools/gen-mach-types
@@ -21,10 +21,21 @@ NF == 3 {
 	  num[nr] = ""; nr++
 	}
 
+# prepend a \ to all special chars in a regexp
+function quote(s) {
+	return gensub("[][\\^$.|()*+?{}]", "\\\\&", "g", s)
+}
+
+# Strip the absolute path of the source tree from the parameter
+# to make the result independent of where the source is located.
+function relsrcfile(fn) {
+	sub("^" quote(ENVIRON["abs_srctree"]) "/", "", fn)
+	return fn
+}
 
 END	{
 	  printf("/*\n");
-	  printf(" * This was automagically generated from %s!\n", FILENAME);
+	  printf(" * This was automagically generated from %s!\n", relsrcfile(FILENAME));
 	  printf(" * Do NOT edit\n");
 	  printf(" */\n\n");
 	  printf("#ifndef __ASM_ARM_MACH_TYPE_H\n");
-- 
2.43.0



From patchwork-bot+netdevbpf at kernel.org  Tue Feb 13 01:30:26 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Tue, 13 Feb 2024 09:30:26 +0000
Subject: [PATCH net-next] net: stmmac: Simplify mtl IRQ status checking
In-Reply-To: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>
References: <20240208-stmmac_irq-v1-1-8bab236026d4@linutronix.de>
Message-ID: <170781662679.26596.16174122173623372072.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni at redhat.com>:

On Thu, 08 Feb 2024 11:35:25 +0100 you wrote:
> Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO overflow
> interrupts") disabled the RX FIFO overflow interrupts. However, it left the
> status variable around, but never checks it.
> 
> As stmmac_host_mtl_irq_status() returns only 0 now, the code can be
> simplified.
> 
> [...]

Here is the summary with links:
  - [net-next] net: stmmac: Simplify mtl IRQ status checking
    https://git.kernel.org/netdev/net-next/c/6256fbfd651c

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From noname.nuno at gmail.com  Tue Feb 13 01:51:15 2024
From: noname.nuno at gmail.com (Nuno =?ISO-8859-1?Q?S=E1?=)
Date: Tue, 13 Feb 2024 10:51:15 +0100
Subject: [PATCH 5/5] iio: adc: ad7380: use spi_optimize_message()
In-Reply-To: <20240212-mainline-spi-precook-message-v1-5-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
	 <20240212-mainline-spi-precook-message-v1-5-a2373cd72d36@baylibre.com>
Message-ID: <c06dfa1ecf88b07ef467ad7c08667d0cab400613.camel@gmail.com>

On Mon, 2024-02-12 at 17:26 -0600, David Lechner wrote:
> This modifies the ad7380 ADC driver to use spi_optimize_message() to
> optimize the SPI message for the buffered read operation. Since buffered
> reads reuse the same SPI message for each read, this can improve
> performance by reducing the overhead of setting up some parts the SPI
> message in each spi_sync() call.
> 
> Signed-off-by: David Lechner <dlechner at baylibre.com>
> ---
> ?drivers/iio/adc/ad7380.c | 52 +++++++++++++++++++++++++++++++++++++++++------
> -
> ?1 file changed, 45 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
> index abd746aef868..5c5d2642a474 100644
> --- a/drivers/iio/adc/ad7380.c
> +++ b/drivers/iio/adc/ad7380.c
> @@ -133,6 +133,7 @@ struct ad7380_state {
> ?	struct spi_device *spi;
> ?	struct regulator *vref;
> ?	struct regmap *regmap;
> +	struct spi_message *msg;
> ?	/*
> ?	 * DMA (thus cache coherency maintenance) requires the
> ?	 * transfer buffers to live in their own cache lines.
> @@ -231,19 +232,55 @@ static int ad7380_debugfs_reg_access(struct iio_dev
> *indio_dev, u32 reg,
> ?	return ret;
> ?}
> ?
> +static int ad7380_buffer_preenable(struct iio_dev *indio_dev)
> +{
> +	struct ad7380_state *st = iio_priv(indio_dev);
> +	struct spi_transfer *xfer;
> +	int ret;
> +
> +	st->msg = spi_message_alloc(1, GFP_KERNEL);
> +	if (!st->msg)
> +		return -ENOMEM;
> +
> +	xfer = list_first_entry(&st->msg->transfers, struct spi_transfer,
> +				transfer_list);
> +
> +	xfer->bits_per_word = st->chip_info->channels[0].scan_type.realbits;
> +	xfer->len = 4;
> +	xfer->rx_buf = st->scan_data.raw;
> +
> +	ret = spi_optimize_message(st->spi, st->msg);
> +	if (ret) {
> +		spi_message_free(st->msg);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int ad7380_buffer_postdisable(struct iio_dev *indio_dev)
> +{
> +	struct ad7380_state *st = iio_priv(indio_dev);
> +
> +	spi_unoptimize_message(st->msg);
> +	spi_message_free(st->msg);
> +
> +	return 0;
> +}
> +

Not such a big deal but unless I'm missing something we could have the
spi_message (+ the transfer) statically allocated in struct ad7380_state and do
the optimize only once at probe (naturally with proper devm action for
unoptimize). Then we would not need to this for every buffer enable + disable. I
know in terms of performance it won't matter but it would be less code I guess.

Am I missing something?

- Nuno S?



From noname.nuno at gmail.com  Tue Feb 13 01:53:56 2024
From: noname.nuno at gmail.com (Nuno =?ISO-8859-1?Q?S=E1?=)
Date: Tue, 13 Feb 2024 10:53:56 +0100
Subject: [PATCH 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
	 <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com>
Message-ID: <92e7e0acf6d8746a07729924982acbfea777c468.camel@gmail.com>

On Mon, 2024-02-12 at 17:26 -0600, David Lechner wrote:
> This adds a new spi_optimize_message() function that can be used to
> optimize SPI messages that are used more than once. Peripheral drivers
> that use the same message multiple times can use this API to perform SPI
> message validation and controller-specific optimizations once and then
> reuse the message while avoiding the overhead of revalidating the
> message on each spi_(a)sync() call.
> 
> Internally, the SPI core will also call this function for each message
> if the peripheral driver did not explicitly call it. This is done to so
> that controller drivers don't have to have multiple code paths for
> optimized and non-optimized messages.
> 
> A hook is provided for controller drivers to perform controller-specific
> optimizations.
> 
> Suggested-by: Martin Sperl <kernel at martin.sperl.org>
> Link:
> https://lore.kernel.org/linux-spi/39DEC004-10A1-47EF-9D77-276188D2580C at martin.sperl.org/
> Signed-off-by: David Lechner <dlechner at baylibre.com>
> ---
> ?drivers/spi/spi.c?????? | 145 ++++++++++++++++++++++++++++++++++++++++++++++-
> -
> ?include/linux/spi/spi.h |? 19 +++++++
> ?2 files changed, 160 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index c2b10e2c75f0..5bac215d7009 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -2106,6 +2106,41 @@ struct spi_message *spi_get_next_queued_message(struct
> spi_controller *ctlr)
> ?}
> ?EXPORT_SYMBOL_GPL(spi_get_next_queued_message);
> ?
> +/**
> + * __spi_unoptimize_message - shared implementation of
> spi_unoptimize_message()
> + *??????????????????????????? and spi_maybe_unoptimize_message()
> + * @msg: the message to unoptimize
> + *
> + * Periperhal drivers should use spi_unoptimize_message() and callers inside
> + * core should use spi_maybe_unoptimize_message() rather than calling this
> + * function directly.
> + *
> + * It is not valid to call this on a message that is not currently optimized.
> + */
> +static void __spi_unoptimize_message(struct spi_message *msg)
> +{
> +	struct spi_controller *ctlr = msg->spi->controller;
> +
> +	if (ctlr->unoptimize_message)
> +		ctlr->unoptimize_message(msg);
> +
> +	msg->optimized = false;
> +	msg->opt_state = NULL;
> +}
> +
> +/**
> + * spi_maybe_unoptimize_message - unoptimize msg not managed by a peripheral
> + * @msg: the message to unoptimize
> + *
> + * This function is used to unoptimize a message if and only if it was
> + * optimized by the core (via spi_maybe_optimize_message()).
> + */
> +static void spi_maybe_unoptimize_message(struct spi_message *msg)
> +{
> +	if (!msg->pre_optimized && msg->optimized)
> +		__spi_unoptimize_message(msg);
> +}
> +
> ?/**
> ? * spi_finalize_current_message() - the current message is complete
> ? * @ctlr: the controller to return the message to
> @@ -2153,6 +2188,8 @@ void spi_finalize_current_message(struct spi_controller
> *ctlr)
> ?
> ?	mesg->prepared = false;
> ?
> +	spi_maybe_unoptimize_message(mesg);
> +
> ?	WRITE_ONCE(ctlr->cur_msg_incomplete, false);
> ?	smp_mb(); /* See __spi_pump_transfer_message()... */
> ?	if (READ_ONCE(ctlr->cur_msg_need_completion))
> @@ -4194,6 +4231,99 @@ static int __spi_validate(struct spi_device *spi,
> struct spi_message *message)
> ?	return 0;
> ?}
> ?
> +/**
> + * __spi_optimize_message - shared implementation for spi_optimize_message()
> + *????????????????????????? and spi_maybe_optimize_message()
> + * @spi: the device that will be used for the message
> + * @msg: the message to optimize
> + * @pre_optimized: whether the message is considered pre-optimized or not
> + *
> + * Peripheral drivers will call spi_optimize_message() and the spi core will
> + * call spi_maybe_optimize_message() instead of calling this directly.
> + *
> + * It is not valid to call this on a message that has already been optimized.
> + *
> + * Return: zero on success, else a negative error code
> + */
> +static int __spi_optimize_message(struct spi_device *spi,
> +				? struct spi_message *msg,
> +				? bool pre_optimized)
> +{
> +	struct spi_controller *ctlr = spi->controller;
> +	int ret;
> +
> +	ret = __spi_validate(spi, msg);
> +	if (ret)
> +		return ret;
> +
> +	if (ctlr->optimize_message) {
> +		ret = ctlr->optimize_message(msg);
> +		if (ret)
> +			return ret;
> +	}

Not really sure what are the spi core guarantees or what controllers should be
expecting but I'll still ask :). Do we need to care about locking in here?
Mainly on the controller callback? For spi device related data I guess it's up
to the peripheral driver not to do anything weird or to properly protect the spi
message?

- Nuno S?



From arnd at arndb.de  Tue Feb 13 01:50:35 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 13 Feb 2024 10:50:35 +0100
Subject: [PATCH v7 08/10] coresight-tpdm: Add timestamp control register support
 for the CMB
In-Reply-To: <1707024641-22460-9-git-send-email-quic_taozha@quicinc.com>
References: <1707024641-22460-1-git-send-email-quic_taozha@quicinc.com>
 <1707024641-22460-9-git-send-email-quic_taozha@quicinc.com>
Message-ID: <7723c9f1-fda7-4dc9-bb5a-e12d4908becf@app.fastmail.com>

On Sun, Feb 4, 2024, at 06:30, Tao Zhang wrote:

> @@ -910,7 +1014,7 @@ static struct attribute *tpdm_dsb_patt_attrs[] = {
>  	DSB_PATT_MASK_ATTR(5),
>  	DSB_PATT_MASK_ATTR(6),
>  	DSB_PATT_MASK_ATTR(7),
> -	&dev_attr_enable_ts.attr,
> +	DSB_PATT_ENABLE_TS,
>  	&dev_attr_set_type.attr,
>  	NULL,
>  };
> @@ -964,6 +1068,7 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
>  	CMB_PATT_ATTR(1),
>  	CMB_PATT_MASK_ATTR(0),
>  	CMB_PATT_MASK_ATTR(1),
> +	CMB_PATT_ENABLE_TS,
>  	NULL,
>  };
> 
> @@ -158,6 +175,10 @@
>  		tpdm_simple_dataset_rw(tpmr##nr,		\
>  		DSB_PATT_MASK, nr)
> 
> +#define DSB_PATT_ENABLE_TS					\
> +		tpdm_patt_enable_ts(enable_ts,			\
> +		DSB_PATT)
> +
>  #define DSB_MSR_ATTR(nr)					\
>  		tpdm_simple_dataset_rw(msr##nr,			\
>  		DSB_MSR, nr)

This is causing build failures in linux-next now:

drivers/hwtracing/coresight/coresight-tpdm.c:1055:2: error: missing field 'idx' initializer [-Werror,-Wmissing-field-initializers]
 1055 |         DSB_PATT_ENABLE_TS,
      |         ^
drivers/hwtracing/coresight/coresight-tpdm.h:184:3: note: expanded from macro 'DSB_PATT_ENABLE_TS'
  184 |                 tpdm_patt_enable_ts(enable_ts,                  \
      |                 ^
drivers/hwtracing/coresight/coresight-tpdm.h:156:5: note: expanded from macro 'tpdm_patt_enable_ts'
  156 |            }                                                    \
      |            ^
drivers/hwtracing/coresight/coresight-tpdm.c:1109:2: error: missing field 'idx' initializer [-Werror,-Wmissing-field-initializers]
 1109 |         CMB_PATT_ENABLE_TS,
      |         ^
drivers/hwtracing/coresight/coresight-tpdm.h:208:3: note: expanded from macro 'CMB_PATT_ENABLE_TS'
  208 |                 tpdm_patt_enable_ts(enable_ts,                  \
      |                 ^
drivers/hwtracing/coresight/coresight-tpdm.h:156:5: note: expanded from macro 'tpdm_patt_enable_ts'
  156 |            }                                                    \
      |            ^

Not sure what is going on, so I reverted your patch locally
for my test setup.
Can you send a fix to make it build again?

      Arnd


From lkp at intel.com  Tue Feb 13 01:52:12 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 13 Feb 2024 17:52:12 +0800
Subject: [PATCH v2 2/3] Subject: [PATCH] drm/mediatek/dp: Add HDCP2.x
 feature for DisplayPort
In-Reply-To: <20240205055055.25340-3-mac.shen@mediatek.com>
References: <20240205055055.25340-3-mac.shen@mediatek.com>
Message-ID: <202402131731.OMfzWywy-lkp@intel.com>

Hi mac.shen,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on pza/reset/next linus/master v6.8-rc4 next-20240213]
[cannot apply to pza/imx-drm/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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/mac-shen/Subject-PATCH-drm-mediatek-dp-Add-tee-client-application-for-HDCP-feature/20240205-163727
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:    https://lore.kernel.org/r/20240205055055.25340-3-mac.shen%40mediatek.com
patch subject: [PATCH v2 2/3] Subject: [PATCH] drm/mediatek/dp: Add HDCP2.x feature for DisplayPort
config: arm-randconfig-001-20240213 (https://download.01.org/0day-ci/archive/20240213/202402131731.OMfzWywy-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240213/202402131731.OMfzWywy-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402131731.OMfzWywy-lkp at intel.com/

All errors (new ones prefixed by >>):

   arm-linux-gnueabi-ld: drivers/gpu/drm/mediatek/mtk_dp.o: in function `mtk_dp_get_system_time':
>> mtk_dp.c:(.text+0x41c0): undefined reference to `__aeabi_uldivmod'
>> arm-linux-gnueabi-ld: mtk_dp.c:(.text+0x41ce): undefined reference to `__aeabi_uldivmod'
   arm-linux-gnueabi-ld: drivers/gpu/drm/mediatek/mtk_dp.o: in function `mtk_dp_get_time_diff':
   mtk_dp.c:(.text+0x41ea): undefined reference to `__aeabi_uldivmod'
   arm-linux-gnueabi-ld: mtk_dp.c:(.text+0x41f8): undefined reference to `__aeabi_uldivmod'

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From david at redhat.com  Tue Feb 13 01:54:52 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 13 Feb 2024 10:54:52 +0100
Subject: [PATCH v5 03/25] mm: Make pte_next_pfn() a wrapper around
 pte_advance_pfn()
In-Reply-To: <3bc05163-2671-4239-ae5a-b9207fdca459@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-4-ryan.roberts@arm.com>
 <c269c2e0-afca-4ff0-8ffd-9049fb52c905@redhat.com>
 <cdf4e537-5b0d-45ba-8094-527127c791a6@arm.com>
 <828d2573-b5fe-43b3-b955-944c05bcdb60@redhat.com>
 <3bc05163-2671-4239-ae5a-b9207fdca459@arm.com>
Message-ID: <940939b2-e36c-4d11-b48f-49f633f0c4fa@redhat.com>

On 12.02.24 22:34, Ryan Roberts wrote:
> On 12/02/2024 14:29, David Hildenbrand wrote:
>> On 12.02.24 15:10, Ryan Roberts wrote:
>>> On 12/02/2024 12:14, David Hildenbrand wrote:
>>>> On 02.02.24 09:07, Ryan Roberts wrote:
>>>>> The goal is to be able to advance a PTE by an arbitrary number of PFNs.
>>>>> So introduce a new API that takes a nr param.
>>>>>
>>>>> We are going to remove pte_next_pfn() and replace it with
>>>>> pte_advance_pfn(). As a first step, implement pte_next_pfn() as a
>>>>> wrapper around pte_advance_pfn() so that we can incrementally switch the
>>>>> architectures over. Once all arches are moved over, we will change all
>>>>> the core-mm callers to call pte_advance_pfn() directly and remove the
>>>>> wrapper.
>>>>>
>>>>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>>>>> ---
>>>>>  ?? include/linux/pgtable.h | 8 +++++++-
>>>>>  ?? 1 file changed, 7 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>>>>> index 5e7eaf8f2b97..815d92dcb96b 100644
>>>>> --- a/include/linux/pgtable.h
>>>>> +++ b/include/linux/pgtable.h
>>>>> @@ -214,9 +214,15 @@ static inline int pmd_dirty(pmd_t pmd)
>>>>>  ?? ? ? #ifndef pte_next_pfn
>>>>> +#ifndef pte_advance_pfn
>>>>> +static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>>>>> +{
>>>>> +??? return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
>>>>> +}
>>>>> +#endif
>>>>>  ?? static inline pte_t pte_next_pfn(pte_t pte)
>>>>>  ?? {
>>>>> -??? return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
>>>>> +??? return pte_advance_pfn(pte, 1);
>>>>>  ?? }
>>>>>  ?? #endif
>>>>>     
>>>>
>>>> I do wonder if we simply want to leave pte_next_pfn() around? Especially patch
>>>> #4, #6 don't really benefit from the change? So are the other set_ptes()
>>>> implementations.
>>>>
>>>> That is, only convert all pte_next_pfn()->pte_advance_pfn(), and leave a
>>>> pte_next_pfn() macro in place.
>>>>
>>>> Any downsides to that?
>>>
>>> The downside is just having multiple functions that effectively do the same
>>> thing. Personally I think its cleaner and easier to understand the code with
>>> just one generic function which we pass 1 to it where we only want to advance by
>>> 1. In the end, there are only a couple of places where pte_advance_pfn(1) is
>>> used, so doesn't really seem valuable to me to maintain a specialization.
>>
>> Well, not really functions, just a macro. Like we have set_pte_at() translating
>> to set_ptes().
>>
>> Arguably, we have more callers of set_pte_at().
>>
>> "Easier to understand", I don't know. :)
>>
>>>
>>> Unless you feel strongly that we need to keep pte_next_pfn() then I'd prefer to
>>> leave it as I've done in this series.
>>
>> Well, it makes you patch set shorter and there is less code churn.
>>
>> So personally, I'd just leave pte_next_pfn() in there. But whatever you prefer,
>> not the end of the world.
> 
> I thought about this a bit more and remembered that I'm the apprentice so I've
> changed it as you suggested.

Oh, I say stupid things all the time. Please push back if you disagree. :)

[shrinking a patch set if possible and reasonable is often a good idea]

-- 
Cheers,

David / dhildenb



From quic_kbajaj at quicinc.com  Tue Feb 13 01:54:59 2024
From: quic_kbajaj at quicinc.com (Komal Bajaj)
Date: Tue, 13 Feb 2024 15:24:59 +0530
Subject: [PATCH v2] arm64: defconfig: Enable GCC and interconnect for QDU1000/QRU1000
Message-ID: <20240213095459.18402-1-quic_kbajaj@quicinc.com>

Add the QDU1000/QRU1000 GCC and interconnect drivers as built-in.
These are necessary for the Qualcomm QDU1000/QRU1000 platform to boot
to shell.

Signed-off-by: Komal Bajaj <quic_kbajaj at quicinc.com>
Acked-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
Changes in v2:
- Rebased on top of 6.8-rc4
- Collected acked by tag
- Link to v1: https://lore.kernel.org/all/20230822132333.17580-1-quic_kbajaj at quicinc.com/
---
 arch/arm64/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e6cf3e5d63c3..f121716cd883 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1265,6 +1265,7 @@ CONFIG_MSM_MMCC_8998=m
 CONFIG_QCM_GCC_2290=y
 CONFIG_QCM_DISPCC_2290=m
 CONFIG_QCS_GCC_404=y
+CONFIG_QDU_GCC_1000=y
 CONFIG_SC_CAMCC_8280XP=m
 CONFIG_SC_DISPCC_8280XP=m
 CONFIG_SA_GCC_8775P=y
@@ -1552,6 +1553,7 @@ CONFIG_INTERCONNECT_QCOM_MSM8996=m
 CONFIG_INTERCONNECT_QCOM_OSM_L3=m
 CONFIG_INTERCONNECT_QCOM_QCM2290=m
 CONFIG_INTERCONNECT_QCOM_QCS404=m
+CONFIG_INTERCONNECT_QCOM_QDU1000=y
 CONFIG_INTERCONNECT_QCOM_SA8775P=y
 CONFIG_INTERCONNECT_QCOM_SC7180=y
 CONFIG_INTERCONNECT_QCOM_SC7280=y
--
2.42.0



From richard at sigma-star.at  Tue Feb 13 01:59:56 2024
From: richard at sigma-star.at (Richard Weinberger)
Date: Tue, 13 Feb 2024 10:59:56 +0100
Subject: [PATCH v5 0/6] DCP as trusted keys backend
In-Reply-To: <7AED262F-9387-446D-B11A-C549C02542F9@sigma-star.at>
References: <20231215110639.45522-1-david@sigma-star.at> <7AED262F-9387-446D-B11A-C549C02542F9@sigma-star.at>
Message-ID: <47439997.XUcTiDjVJD@somecomputer>

Am Montag, 5. Februar 2024, 09:39:07 CET schrieb David Gstir:
> Hi,
> 
> > On 15.12.2023, at 12:06, David Gstir <david at sigma-star.at> wrote:
> > 
> > This is a revival of the previous patch set submitted by Richard Weinberger:
> > https://lore.kernel.org/linux-integrity/20210614201620.30451-1-richard at nod.at/
> > 
> > v4 is here:
> > https://lore.kernel.org/keyrings/20231024162024.51260-1-david at sigma-star.at/
> > 
> > v4 -> v5:
> > - Make Kconfig for trust source check scalable as suggested by Jarkko Sakkinen
> > - Add Acked-By from Herbert Xu to patch #1 - thanks!
> > v3 -> v4:
> > - Split changes on MAINTAINERS and documentation into dedicated patches
> > - Use more concise wording in commit messages as suggested by Jarkko Sakkinen
> > v2 -> v3:
> > - Addressed review comments from Jarkko Sakkinen
> > v1 -> v2:
> > - Revive and rebase to latest version
> > - Include review comments from Ahmad Fatoum
> > 
> > The Data CoProcessor (DCP) is an IP core built into many NXP SoCs such
> > as i.mx6ull.
> > 
> > Similar to the CAAM engine used in more powerful SoCs, DCP can AES-
> > encrypt/decrypt user data using a unique, never-disclosed,
> > device-specific key. Unlike CAAM though, it cannot directly wrap and
> > unwrap blobs in hardware. As DCP offers only the bare minimum feature
> > set and a blob mechanism needs aid from software. A blob in this case
> > is a piece of sensitive data (e.g. a key) that is encrypted and
> > authenticated using the device-specific key so that unwrapping can only
> > be done on the hardware where the blob was wrapped.
> > 
> > This patch series adds a DCP based, trusted-key backend and is similar
> > in spirit to the one by Ahmad Fatoum [0] that does the same for CAAM.
> > It is of interest for similar use cases as the CAAM patch set, but for
> > lower end devices, where CAAM is not available.
> > 
> > Because constructing and parsing the blob has to happen in software,
> > we needed to decide on a blob format and chose the following:
> > 
> > struct dcp_blob_fmt {
> > __u8 fmt_version;
> > __u8 blob_key[AES_KEYSIZE_128];
> > __u8 nonce[AES_KEYSIZE_128];
> > __le32 payload_len;
> > __u8 payload[];
> > } __packed;
> > 
> > The `fmt_version` is currently 1.
> > 
> > The encrypted key is stored in the payload area. It is AES-128-GCM
> > encrypted using `blob_key` and `nonce`, GCM auth tag is attached at
> > the end of the payload (`payload_len` does not include the size of
> > the auth tag).
> > 
> > The `blob_key` itself is encrypted in AES-128-ECB mode by DCP using
> > the OTP or UNIQUE device key. A new `blob_key` and `nonce` are generated
> > randomly, when sealing/exporting the DCP blob.
> > 
> > This patchset was tested with dm-crypt on an i.MX6ULL board.
> > 
> > [0] https://lore.kernel.org/keyrings/20220513145705.2080323-1-a.fatoum at pengutronix.de/
> > 
> > David Gstir (6):
> >  crypto: mxs-dcp: Add support for hardware-bound keys
> >  KEYS: trusted: improve scalability of trust source config
> >  KEYS: trusted: Introduce NXP DCP-backed trusted keys
> >  MAINTAINERS: add entry for DCP-based trusted keys
> >  docs: document DCP-backed trusted keys kernel params
> >  docs: trusted-encrypted: add DCP as new trust source
> > 
> > .../admin-guide/kernel-parameters.txt         |  13 +
> > .../security/keys/trusted-encrypted.rst       |  85 +++++
> > MAINTAINERS                                   |   9 +
> > drivers/crypto/mxs-dcp.c                      | 104 +++++-
> > include/keys/trusted_dcp.h                    |  11 +
> > include/soc/fsl/dcp.h                         |  17 +
> > security/keys/trusted-keys/Kconfig            |  18 +-
> > security/keys/trusted-keys/Makefile           |   2 +
> > security/keys/trusted-keys/trusted_core.c     |   6 +-
> > security/keys/trusted-keys/trusted_dcp.c      | 311 ++++++++++++++++++
> > 10 files changed, 562 insertions(+), 14 deletions(-)
> > create mode 100644 include/keys/trusted_dcp.h
> > create mode 100644 include/soc/fsl/dcp.h
> > create mode 100644 security/keys/trusted-keys/trusted_dcp.c
> 
> Jarkko, Mimi, David do you need anything from my side for these patches to get them merged?

Friendly ping also from my side. :-)

Thanks,
//richard

-- 
?????sigma star gmbh | Eduard-Bodem-Gasse 6, 6020 Innsbruck, AUT
UID/VAT Nr: ATU 66964118 | FN: 374287y




From david at redhat.com  Tue Feb 13 02:01:09 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 13 Feb 2024 11:01:09 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
Message-ID: <39ee7f6b-082e-4bab-98e1-dc2130131160@redhat.com>

On 12.02.24 21:38, Ryan Roberts wrote:
> [...]
> 
>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>> +{
>>>>> +	/*
>>>>> +	 * Don't attempt to apply the contig bit to kernel mappings, because
>>>>> +	 * dynamically adding/removing the contig bit can cause page faults.
>>>>> +	 * These racing faults are ok for user space, since they get serialized
>>>>> +	 * on the PTL. But kernel mappings can't tolerate faults.
>>>>> +	 */
>>>>> +	return mm != &init_mm;
>>>>> +}
>>>>
>>>> We also have the efi_mm as a non-user mm, though I don't think we manipulate
>>>> that while it is live, and I'm not sure if that needs any special handling.
>>>
>>> Well we never need this function in the hot (order-0 folio) path, so I think I
>>> could add a check for efi_mm here with performance implication. It's probably
>>> safest to explicitly exclude it? What do you think?
>>
>> Oops: This should have read "I think I could add a check for efi_mm here
>> *without* performance implication"
> 
> It turns out that efi_mm is only defined when CONFIG_EFI is enabled. I can do this:
> 
> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);

Please use all the lines you need ;)

if (IS_ENABLED(CONFIG_EFI) && unlikely(mm == &efi_mm))
	return false;
return mm != &init_mm;

> 
> Is that acceptable? This is my preference, but nothing else outside of efi
> references this symbol currently.

We could also mark MMs in some way to be special.

return mm->is_user;

Then it's easy to extend.

-- 
Cheers,

David / dhildenb



From arnd at kernel.org  Tue Feb 13 02:00:09 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 13 Feb 2024 11:00:09 +0100
Subject: [PATCH] mtd: rawnand: lpc32xx_mlc: fix irq handler prototype
Message-ID: <20240213100146.455811-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

clang-16 warns about mismatched function prototypes:

drivers/mtd/nand/raw/lpc32xx_mlc.c:783:29: error: cast from 'irqreturn_t (*)(int, struct lpc32xx_nand_host *)' (aka 'enum irqreturn (*)(int, struct lpc32xx_nand_host *)') to 'irq_handler_t' (aka 'enum irqreturn (*)(int, void *)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]

Change the interrupt handler to the normal way of just passing
a void* pointer and converting it inside the function..

Fixes: 70f7cb78ec53 ("mtd: add LPC32xx MLC NAND driver")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/mtd/nand/raw/lpc32xx_mlc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c
index 488fd452611a..677fcb03f9be 100644
--- a/drivers/mtd/nand/raw/lpc32xx_mlc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c
@@ -303,8 +303,9 @@ static int lpc32xx_nand_device_ready(struct nand_chip *nand_chip)
 	return 0;
 }
 
-static irqreturn_t lpc3xxx_nand_irq(int irq, struct lpc32xx_nand_host *host)
+static irqreturn_t lpc3xxx_nand_irq(int irq, void *data)
 {
+	struct lpc32xx_nand_host *host = data;
 	uint8_t sr;
 
 	/* Clear interrupt flag by reading status */
@@ -780,7 +781,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
 		goto release_dma_chan;
 	}
 
-	if (request_irq(host->irq, (irq_handler_t)&lpc3xxx_nand_irq,
+	if (request_irq(host->irq, &lpc3xxx_nand_irq,
 			IRQF_TRIGGER_HIGH, DRV_NAME, host)) {
 		dev_err(&pdev->dev, "Error requesting NAND IRQ\n");
 		res = -ENXIO;
-- 
2.39.2



From maz at kernel.org  Tue Feb 13 02:12:03 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 13 Feb 2024 10:12:03 +0000
Subject: [PATCH 0/3] GICv3 ITS fixes for 6.8
Message-ID: <20240213101206.2137483-1-maz@kernel.org>

Here's a small collection of patches that I posted separately in the
past, but that are all more or less related, so it makes sense to
repost them as a series.

It would be good to have them in 6.8, given that at least one of them
fixes a pretty bad regression, and the others can lead to
unpredictable behaviours.

Marc Zyngier (3):
  irqchip/gic-v3-its: Handle non-coherent GICv4 redistributors
  irqchip/gic-v3-its: Restore quirk probing for ACPI-based systems
  irqchip/gic-v3-its: Fix GICv4.1 VPE affinity update

 drivers/irqchip/irq-gic-v3-its.c | 62 ++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 22 deletions(-)

-- 
2.39.2



From maz at kernel.org  Tue Feb 13 02:12:04 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 13 Feb 2024 10:12:04 +0000
Subject: [PATCH 1/3] irqchip/gic-v3-its: Handle non-coherent GICv4 redistributors
In-Reply-To: <20240213101206.2137483-1-maz@kernel.org>
References: <20240213101206.2137483-1-maz@kernel.org>
Message-ID: <20240213101206.2137483-2-maz@kernel.org>

Although the GICv3 code base has gained some handling of systems
failing to handle the shareability attributes, the GICv4 side of
things has been firmly ignored.

This is unfortunate, as the new recent addition of the
"dma-noncoherent" is supposed to apply to all of the GICR tables,
and not just the ones that are common to v3 and v4.

Add some checks to handle the VPROPBASE/VPENDBASE shareability
and cacheability attributes in the same way we deal with the
other GICR_BASE registers, wrapping the flag check in a helper
for improved readability.

Note that this has been found by inspection only, as I don't
have access to HW that suffers from this particular issue.

Fixes: 3a0fff0fb6a3 ("irqchip/gic-v3: Enable non-coherent redistributors/ITSes DT probing")
Reviewed-by: Lorenzo Pieralisi <lpieralisi at kernel.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-gic-v3-its.c | 37 +++++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index d097001c1e3e..fec1b58470df 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -207,6 +207,11 @@ static bool require_its_list_vmovp(struct its_vm *vm, struct its_node *its)
 	return (gic_rdists->has_rvpeid || vm->vlpi_count[its->list_nr]);
 }
 
+static bool rdists_support_shareable(void)
+{
+	return !(gic_rdists->flags & RDIST_FLAGS_FORCE_NON_SHAREABLE);
+}
+
 static u16 get_its_list(struct its_vm *vm)
 {
 	struct its_node *its;
@@ -2710,10 +2715,12 @@ static u64 inherit_vpe_l1_table_from_its(void)
 			break;
 		}
 		val |= FIELD_PREP(GICR_VPROPBASER_4_1_ADDR, addr >> 12);
-		val |= FIELD_PREP(GICR_VPROPBASER_SHAREABILITY_MASK,
-				  FIELD_GET(GITS_BASER_SHAREABILITY_MASK, baser));
-		val |= FIELD_PREP(GICR_VPROPBASER_INNER_CACHEABILITY_MASK,
-				  FIELD_GET(GITS_BASER_INNER_CACHEABILITY_MASK, baser));
+		if (rdists_support_shareable()) {
+			val |= FIELD_PREP(GICR_VPROPBASER_SHAREABILITY_MASK,
+					  FIELD_GET(GITS_BASER_SHAREABILITY_MASK, baser));
+			val |= FIELD_PREP(GICR_VPROPBASER_INNER_CACHEABILITY_MASK,
+					  FIELD_GET(GITS_BASER_INNER_CACHEABILITY_MASK, baser));
+		}
 		val |= FIELD_PREP(GICR_VPROPBASER_4_1_SIZE, GITS_BASER_NR_PAGES(baser) - 1);
 
 		return val;
@@ -2936,8 +2943,10 @@ static int allocate_vpe_l1_table(void)
 	WARN_ON(!IS_ALIGNED(pa, psz));
 
 	val |= FIELD_PREP(GICR_VPROPBASER_4_1_ADDR, pa >> 12);
-	val |= GICR_VPROPBASER_RaWb;
-	val |= GICR_VPROPBASER_InnerShareable;
+	if (rdists_support_shareable()) {
+		val |= GICR_VPROPBASER_RaWb;
+		val |= GICR_VPROPBASER_InnerShareable;
+	}
 	val |= GICR_VPROPBASER_4_1_Z;
 	val |= GICR_VPROPBASER_4_1_VALID;
 
@@ -3126,7 +3135,7 @@ static void its_cpu_init_lpis(void)
 	gicr_write_propbaser(val, rbase + GICR_PROPBASER);
 	tmp = gicr_read_propbaser(rbase + GICR_PROPBASER);
 
-	if (gic_rdists->flags & RDIST_FLAGS_FORCE_NON_SHAREABLE)
+	if (!rdists_support_shareable())
 		tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK;
 
 	if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
@@ -3153,7 +3162,7 @@ static void its_cpu_init_lpis(void)
 	gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
 	tmp = gicr_read_pendbaser(rbase + GICR_PENDBASER);
 
-	if (gic_rdists->flags & RDIST_FLAGS_FORCE_NON_SHAREABLE)
+	if (!rdists_support_shareable())
 		tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK;
 
 	if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
@@ -3880,14 +3889,18 @@ static void its_vpe_schedule(struct its_vpe *vpe)
 	val  = virt_to_phys(page_address(vpe->its_vm->vprop_page)) &
 		GENMASK_ULL(51, 12);
 	val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
-	val |= GICR_VPROPBASER_RaWb;
-	val |= GICR_VPROPBASER_InnerShareable;
+	if (rdists_support_shareable()) {
+		val |= GICR_VPROPBASER_RaWb;
+		val |= GICR_VPROPBASER_InnerShareable;
+	}
 	gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
 
 	val  = virt_to_phys(page_address(vpe->vpt_page)) &
 		GENMASK_ULL(51, 16);
-	val |= GICR_VPENDBASER_RaWaWb;
-	val |= GICR_VPENDBASER_InnerShareable;
+	if (rdists_support_shareable()) {
+		val |= GICR_VPENDBASER_RaWaWb;
+		val |= GICR_VPENDBASER_InnerShareable;
+	}
 	/*
 	 * There is no good way of finding out if the pending table is
 	 * empty as we can race against the doorbell interrupt very
-- 
2.39.2



From maz at kernel.org  Tue Feb 13 02:12:06 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 13 Feb 2024 10:12:06 +0000
Subject: [PATCH 3/3] irqchip/gic-v3-its: Fix GICv4.1 VPE affinity update
In-Reply-To: <20240213101206.2137483-1-maz@kernel.org>
References: <20240213101206.2137483-1-maz@kernel.org>
Message-ID: <20240213101206.2137483-4-maz@kernel.org>

When updating the affinity of a VPE, we currently skip the VMOVP
command if the two CPUs are part of the same VPE affinity.

But this is wrong, as the doorbell corresponding to this VPE
is still delivered on the 'old' CPU, which screws up the balancing.
Furthermore, offlining that 'old' CPU results in doorbell interrupts
generated for this VPE being discarded.

The harsh reality is that we cannot easily elide VMOVP when
a set_affinity request occurs. It needs to be obeyed, and if
an optimisation is to be made, it is at the point where the affinity
change request is made (such as in KVM).

Drop the VMOVP elision altogether, and only use the vpe_table_mask
to try and stay within the same ITS affinity group if at all possible.

Fixes: dd3f050a216e (irqchip/gic-v4.1: Implement the v4.1 flavour of VMOVP)
Reported-by: Kunkun Jiang <jiangkunkun at huawei.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Cc: stable at vger.kernel.org
---
 drivers/irqchip/irq-gic-v3-its.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 250b4562f308..53abd4779914 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -3826,8 +3826,9 @@ static int its_vpe_set_affinity(struct irq_data *d,
 				bool force)
 {
 	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
-	int from, cpu = cpumask_first(mask_val);
+	struct cpumask common, *table_mask;
 	unsigned long flags;
+	int from, cpu;
 
 	/*
 	 * Changing affinity is mega expensive, so let's be as lazy as
@@ -3843,19 +3844,22 @@ static int its_vpe_set_affinity(struct irq_data *d,
 	 * taken on any vLPI handling path that evaluates vpe->col_idx.
 	 */
 	from = vpe_to_cpuid_lock(vpe, &flags);
-	if (from == cpu)
-		goto out;
-
-	vpe->col_idx = cpu;
+	table_mask = gic_data_rdist_cpu(from)->vpe_table_mask;
 
 	/*
-	 * GICv4.1 allows us to skip VMOVP if moving to a cpu whose RD
-	 * is sharing its VPE table with the current one.
+	 * If we are offered another CPU in the same GICv4.1 ITS
+	 * affinity, pick this one. Otherwise, any CPU will do.
 	 */
-	if (gic_data_rdist_cpu(cpu)->vpe_table_mask &&
-	    cpumask_test_cpu(from, gic_data_rdist_cpu(cpu)->vpe_table_mask))
+	if (table_mask && cpumask_and(&common, mask_val, table_mask))
+		cpu = cpumask_test_cpu(from, &common) ? from : cpumask_first(&common);
+	else
+		cpu = cpumask_first(mask_val);
+
+	if (from == cpu)
 		goto out;
 
+	vpe->col_idx = cpu;
+
 	its_send_vmovp(vpe);
 	its_vpe_db_proxy_move(vpe, from, cpu);
 
-- 
2.39.2



From maz at kernel.org  Tue Feb 13 02:12:05 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 13 Feb 2024 10:12:05 +0000
Subject: [PATCH 2/3] irqchip/gic-v3-its: Restore quirk probing for ACPI-based systems
In-Reply-To: <20240213101206.2137483-1-maz@kernel.org>
References: <20240213101206.2137483-1-maz@kernel.org>
Message-ID: <20240213101206.2137483-3-maz@kernel.org>

While refactoring the way the ITSs are probed, the handling of
quirks applicable to ACPI-based platforms was lost. As a result,
systems such as HIP07 lose their GICv4 functionnality, and some
other may even fail to boot, unless they are configured to boot
with DT.

Move the enabling of quirks into its_probe_one(), making it
common to all firmware implementations.

Fixes: 9585a495ac93 ("irqchip/gic-v3-its: Split allocation from initialisation of its_node")
Reviewed-by: Lorenzo Pieralisi <lpieralisi at kernel.org>
Reviewed-by: Zenghui Yu <yuzenghui at huawei.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Cc: stable at vger.kernel.org
---
 drivers/irqchip/irq-gic-v3-its.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index fec1b58470df..250b4562f308 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -5091,6 +5091,8 @@ static int __init its_probe_one(struct its_node *its)
 	u32 ctlr;
 	int err;
 
+	its_enable_quirks(its);
+
 	if (is_v4(its)) {
 		if (!(its->typer & GITS_TYPER_VMOVP)) {
 			err = its_compute_its_list_map(its);
@@ -5442,7 +5444,6 @@ static int __init its_of_probe(struct device_node *node)
 		if (!its)
 			return -ENOMEM;
 
-		its_enable_quirks(its);
 		err = its_probe_one(its);
 		if (err)  {
 			its_node_destroy(its);
-- 
2.39.2



From arnd at kernel.org  Tue Feb 13 02:11:38 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 13 Feb 2024 11:11:38 +0100
Subject: [PATCH] ASoC: meson: add helpers for clk_disable_unprepare
Message-ID: <20240213101220.459641-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Casting between incompatible function types causes a warning with clang-16
because it breaks control flow integrity (KCFI) rules:

sound/soc/meson/aiu.c:243:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
  243 |                                        (void(*)(void *))clk_disable_unprepare,
      |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/device.h:406:34: note: expanded from macro 'devm_add_action_or_reset'
  406 |         __devm_add_action_or_reset(dev, action, data, #action)
      |                                         ^~~~~~
sound/soc/meson/t9015.c:274:4: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
  274 |                         (void(*)(void *))clk_disable_unprepare,
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/device.h:406:34: note: expanded from macro 'devm_add_action_or_reset'
  406 |         __devm_add_action_or_reset(dev, action, data, #action)
      |                                         ^~~~~~

These two meson drivers cast clk_disable_unprepare() into a different type
in order to have it automatically called from the driver relase. Add
trivial helpers to do the same using correct types.

Fixes: 33901f5b9b16 ("ASoC: meson: add t9015 internal DAC driver")
Fixes: 6ae9ca9ce986 ("ASoC: meson: aiu: add i2s and spdif support")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 sound/soc/meson/aiu.c   | 9 ++++++---
 sound/soc/meson/t9015.c | 9 ++++++---
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c
index 7109b81cc3d0..211f360df284 100644
--- a/sound/soc/meson/aiu.c
+++ b/sound/soc/meson/aiu.c
@@ -209,6 +209,11 @@ static const char * const aiu_spdif_ids[] = {
 	[MCLK]	= "spdif_mclk_sel"
 };
 
+static void aiu_clk_disable(void *clk)
+{
+	clk_disable_unprepare(clk);
+}
+
 static int aiu_clk_get(struct device *dev)
 {
 	struct aiu *aiu = dev_get_drvdata(dev);
@@ -239,9 +244,7 @@ static int aiu_clk_get(struct device *dev)
 		return ret;
 	}
 
-	ret = devm_add_action_or_reset(dev,
-				       (void(*)(void *))clk_disable_unprepare,
-				       aiu->pclk);
+	ret = devm_add_action_or_reset(dev, aiu_clk_disable, aiu->pclk);
 	if (ret)
 		dev_err(dev, "failed to add reset action on pclk");
 
diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c
index 9c6b4dac6893..e0f9a603a5e9 100644
--- a/sound/soc/meson/t9015.c
+++ b/sound/soc/meson/t9015.c
@@ -243,6 +243,11 @@ static const struct regmap_config t9015_regmap_config = {
 	.max_register		= POWER_CFG,
 };
 
+static void t9015_clk_disable(void *clk)
+{
+	clk_disable_unprepare(clk);
+}
+
 static int t9015_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -270,9 +275,7 @@ static int t9015_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = devm_add_action_or_reset(dev,
-			(void(*)(void *))clk_disable_unprepare,
-			priv->pclk);
+	ret = devm_add_action_or_reset(dev, t9015_clk_disable, priv->pclk);
 	if (ret)
 		return ret;
 
-- 
2.39.2



From arnd at kernel.org  Tue Feb 13 02:13:44 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 13 Feb 2024 11:13:44 +0100
Subject: [PATCH] ARM: crypto: fix function cast warnings
Message-ID: <20240213101356.460376-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

clang-16 warns about casting between incompatible function types:

arch/arm/crypto/sha256_glue.c:37:5: error: cast from 'void (*)(u32 *, const void *, unsigned int)' (aka 'void (*)(unsigned int *, const void *, unsigned int)') to 'sha256_block_fn *' (aka 'void (*)(struct sha256_state *, const unsigned char *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
   37 |                                 (sha256_block_fn *)sha256_block_data_order);
      |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm/crypto/sha512-glue.c:34:3: error: cast from 'void (*)(u64 *, const u8 *, int)' (aka 'void (*)(unsigned long long *, const unsigned char *, int)') to 'sha512_block_fn *' (aka 'void (*)(struct sha512_state *, const unsigned char *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
   34 |                 (sha512_block_fn *)sha512_block_data_order);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Rework the sha256/sha512 code to instead go through a trivial helper
function to preserve the calling conventions.

Fixes: c80ae7ca3726 ("crypto: arm/sha512 - accelerated SHA-512 using ARM generic ASM and NEON")
Fixes: b59e2ae3690c ("crypto: arm/sha256 - move SHA-224/256 ASM/NEON implementation to base layer")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/crypto/sha256_glue.c | 18 ++++++++++--------
 arch/arm/crypto/sha512-glue.c | 11 ++++++++---
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/arch/arm/crypto/sha256_glue.c b/arch/arm/crypto/sha256_glue.c
index 433ee4ddce6c..d80448d96ab3 100644
--- a/arch/arm/crypto/sha256_glue.c
+++ b/arch/arm/crypto/sha256_glue.c
@@ -27,29 +27,31 @@
 asmlinkage void sha256_block_data_order(u32 *digest, const void *data,
 					unsigned int num_blks);
 
-int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
-			     unsigned int len)
+static void sha256_block_data_order_wrapper(struct sha256_state *sst, u8 const *src, int blocks)
 {
 	/* make sure casting to sha256_block_fn() is safe */
 	BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
 
-	return sha256_base_do_update(desc, data, len,
-				(sha256_block_fn *)sha256_block_data_order);
+	return sha256_block_data_order((u32 *)sst, src, blocks);
+}
+
+int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
+			     unsigned int len)
+{
+	return sha256_base_do_update(desc, data, len, sha256_block_data_order_wrapper);
 }
 EXPORT_SYMBOL(crypto_sha256_arm_update);
 
 static int crypto_sha256_arm_final(struct shash_desc *desc, u8 *out)
 {
-	sha256_base_do_finalize(desc,
-				(sha256_block_fn *)sha256_block_data_order);
+	sha256_base_do_finalize(desc, sha256_block_data_order_wrapper);
 	return sha256_base_finish(desc, out);
 }
 
 int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data,
 			    unsigned int len, u8 *out)
 {
-	sha256_base_do_update(desc, data, len,
-			      (sha256_block_fn *)sha256_block_data_order);
+	sha256_base_do_update(desc, data, len, sha256_block_data_order_wrapper);
 	return crypto_sha256_arm_final(desc, out);
 }
 EXPORT_SYMBOL(crypto_sha256_arm_finup);
diff --git a/arch/arm/crypto/sha512-glue.c b/arch/arm/crypto/sha512-glue.c
index 0635a65aa488..1b2c9c0c8a5f 100644
--- a/arch/arm/crypto/sha512-glue.c
+++ b/arch/arm/crypto/sha512-glue.c
@@ -27,17 +27,22 @@ MODULE_ALIAS_CRYPTO("sha512-arm");
 
 asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks);
 
+static void sha512_block_data_order_wrapper(struct sha512_state *sst, u8 const *src, int blocks)
+{
+	return sha512_block_data_order((u64 *)sst, src, blocks);
+}
+
 int sha512_arm_update(struct shash_desc *desc, const u8 *data,
 		      unsigned int len)
 {
 	return sha512_base_do_update(desc, data, len,
-		(sha512_block_fn *)sha512_block_data_order);
+		sha512_block_data_order_wrapper);
 }
 
 static int sha512_arm_final(struct shash_desc *desc, u8 *out)
 {
 	sha512_base_do_finalize(desc,
-		(sha512_block_fn *)sha512_block_data_order);
+		sha512_block_data_order_wrapper);
 	return sha512_base_finish(desc, out);
 }
 
@@ -45,7 +50,7 @@ int sha512_arm_finup(struct shash_desc *desc, const u8 *data,
 		     unsigned int len, u8 *out)
 {
 	sha512_base_do_update(desc, data, len,
-		(sha512_block_fn *)sha512_block_data_order);
+		sha512_block_data_order_wrapper);
 	return sha512_arm_final(desc, out);
 }
 
-- 
2.39.2



From arnd at kernel.org  Tue Feb 13 02:15:47 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 13 Feb 2024 11:15:47 +0100
Subject: [PATCH] nvmem: meson-efuse: fix function pointer type mismatch
Message-ID: <20240213101607.460930-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

clang-16 warns about casting functions to incompatible types, as is done
here to call clk_disable_unprepare:

drivers/nvmem/meson-efuse.c:78:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
   78 |                                        (void(*)(void *))clk_disable_unprepare,

Address this with a trivial helper function that adjusts the return code.

Fixes: 611fbca1c861 ("nvmem: meson-efuse: add peripheral clock")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/nvmem/meson-efuse.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
index b922df99f9bc..3b9e31d7d073 100644
--- a/drivers/nvmem/meson-efuse.c
+++ b/drivers/nvmem/meson-efuse.c
@@ -38,6 +38,11 @@ static const struct of_device_id meson_efuse_match[] = {
 };
 MODULE_DEVICE_TABLE(of, meson_efuse_match);
 
+static void meson_efuse_clk_disable(void *clk)
+{
+	clk_disable_unprepare(clk);
+}
+
 static int meson_efuse_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -74,9 +79,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = devm_add_action_or_reset(dev,
-				       (void(*)(void *))clk_disable_unprepare,
-				       clk);
+	ret = devm_add_action_or_reset(dev, meson_efuse_clk_disable, clk);
 	if (ret) {
 		dev_err(dev, "failed to add disable callback");
 		return ret;
-- 
2.39.2



From robin.murphy at arm.com  Tue Feb 13 02:20:25 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 13 Feb 2024 10:20:25 +0000
Subject: [PATCH v2 5/5] iommu/arm-smmu: Convert to domain_alloc_paging()
In-Reply-To: <CAA8EJpp1wuMgawaUPnQWnhz1k023n8Q-k0_sO6P9p7ixntrCJQ@mail.gmail.com>
References: <5-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com>
 <20240209200538.917366-1-dmitry.baryshkov@linaro.org>
 <20240209222349.GA923780@nvidia.com>
 <CAA8EJpp1wuMgawaUPnQWnhz1k023n8Q-k0_sO6P9p7ixntrCJQ@mail.gmail.com>
Message-ID: <6511a289-fee6-4d08-9e01-695bd38d4ad6@arm.com>

On 2024-02-13 7:51 am, Dmitry Baryshkov wrote:
> On Sat, 10 Feb 2024 at 00:23, Jason Gunthorpe <jgg at nvidia.com> wrote:
>>
>> On Fri, Feb 09, 2024 at 10:05:38PM +0200, Dmitry Baryshkov wrote:
>>> On Tue, 17 Oct 2023 Jason Gunthorpe <jgg at nvidia.com> wrote:
>>>> Now that the BLOCKED and IDENTITY behaviors are managed with their own
>>>> domains change to the domain_alloc_paging() op.
>>>>
>>>> The check for using_legacy_binding is now redundant,
>>>> arm_smmu_def_domain_type() always returns IOMMU_DOMAIN_IDENTITY for this
>>>> mode, so the core code will never attempt to create a DMA domain in the
>>>> first place.
>>>>
>>>> Since commit a4fdd9762272 ("iommu: Use flush queue capability") the core
>>>> code only passes in IDENTITY/BLOCKED/UNMANAGED/DMA domain types. It will
>>>> not pass in IDENTITY or BLOCKED if the global statics exist, so the test
>>>> for DMA is also redundant now too.
>>>>
>>>> Call arm_smmu_init_domain_context() early if a dev is available.
>>>>
>>>> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
>>>> ---
>>>>   drivers/iommu/arm/arm-smmu/arm-smmu.c | 21 +++++++++++++++------
>>>>   1 file changed, 15 insertions(+), 6 deletions(-)
>>>
>>> For some reason this patch breaks booting of the APQ8096 Dragonboard820c
>>> (qcom/apq8096-db820c.dts). Dispbling display subsystem (mdss) and venus
>>> devices makes the board boot in most of the cases. Most frequently the
>>> last parts of the log loog in a following way:
>>
>> It is surprising we tested this patch on some tegra systems with this
>> iommu and didn't hit anything..
>>
>> The only real functional thing this changes is to move the domain
>> initialization up in time, potentially a lot in time in some
>> cases. That function does alot of things including touching HW so
>> possibly there is some surprising interaction with something else.
> 
> I should not be debugging strange platforms at 1 a.m. I forgot that
> there was another patch to revert. So after reverting the MPM patch,
> I'm getting the following results:
> 
>>
>> So, I would expect this to not WARN_ON and to make it work the same as
>> before the patch:
> 
> No warnings, the platform now boots up to the point of actually
> bringing up the venus device:
> 
> 
> [   11.906514] ath10k_pci 0000:01:00.0: qca6174 hw3.2 target
> 0x05030000 chip_id 0x00340aff sub 0000:0000
> [   11.907119] ath10k_pci 0000:01:00.0: kconfig debug 1 debugfs 0
> tracing 0 dfs 0 testmode 0
> [   11.915881] ath10k_pci 0000:01:00.0: firmware ver
> WLAN.RM.4.4.1-00288- api 6 features wowlan,ignore-otp,mfp crc32
> bf907c7c
> [   11.979972] Console: switching to colour frame buffer device 320x90
> [   11.990756] ath10k_pci 0000:01:00.0: board_file api 2 bmi_id 0:1
> crc32 d2863f91
> [   12.060834] msm_mdp 901000.display-controller: [drm] fb0: msmdrmfb
> frame buffer device
> [   12.096203] qcom-pcie 608000.pcie: Phy link never came up
> [   12.103785] qcom-pcie 608000.pcie: PCI host bridge to bus 0001:00
> [   12.103970] qcom-venus c00000.video-codec: Adding to iommu group 3
> 
> Format: Log Type - Time(microsec) - Message - Optional Info
> Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
> S - QC_IMAGE_VERSION_STRING=BOOT.XF.1.0-00301
> S - IMAGE_VARIANT_STRING=M8996LAB
> S - OEM_IMAGE_VERSION_STRING=crm-ubuntu68
> S - Boot Interface: UFS
> 
>>
>> Then I'd ask you to remove the comment and do:
>>
>> @@ -878,7 +878,9 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
>>          if (dev) {
>>                  struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
>>
>> +               WARN_ON(true);
>>                  if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
>> +                       printk("Allocation failure in arm_smmu_domain_alloc_paging()\n");
>>                          kfree(smmu_domain);
>>                          return NULL;
>>                  }
>>
>>
>> And then we may get a clue from the backtraces it generates. I only
>> saw one iommu group reported in your log so I'd expect one trace?
> 
> I added dev_info + mdelays() around the arm_smmu_init_domain_context()
> and I can see that it crashes within that function.

Yeah, this is totally broken. We can't just call the unmodified 
arm_smmu_init_domain_context() at domain allocation because half of what 
it's doing belongs to the attach operation. We should not be allocating 
context banks, IRQs, etc. for a not-yet-attached domain, and we 
certainly shouldn't be touching hardware there outside of RPM.

Thanks,
Robin.

> 
> [   29.819624] qcom-venus c00000.video-codec: Adding to iommu group 1
> [   29.833181] ------------[ cut here ]------------
> [   29.839198] WARNING: CPU: 1 PID: 35 at
> drivers/iommu/arm/arm-smmu/arm-smmu.c:883
> arm_smmu_domain_alloc_paging+0x80/0x174
> [   29.843980] Modules linked in:
> [   29.854824] CPU: 1 PID: 35 Comm: kworker/u18:0 Tainted: G     U
>          6.8.0-rc3-next-20240208-05495-g20708c29957d-dirty #1739
> [   29.857694] Hardware name: Qualcomm Technologies, Inc. DB820c (DT)
> [   29.869410] Workqueue: events_unbound deferred_probe_work_func
> [   29.875658] pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [   29.881474] pc : arm_smmu_domain_alloc_paging+0x80/0x174
> [   29.888331] lr : arm_smmu_domain_alloc_paging+0x68/0x174
> [   29.893885] sp : ffff8000830338c0
> [   29.899179] x29: ffff8000830338c0 x28: 0000000000000000 x27: ffff800081e72000
> [   29.902396] x26: ffff00008034ee48 x25: ffff000080b24810 x24: 0000000000000000
> [   29.909513] x23: ffff800081e73000 x22: ffff000080b24810 x21: ffff800082e23258
> [   29.916633] x20: ffff00008389a700 x19: ffff00008034f600 x18: ffffffffffffffff
> [   29.918788] usb 1-1: new high-speed USB device number 2 using xhci-hcd
> [   29.923746] x17: 0000000c0000000b x16: 0000000900000008 x15: 0000000000000000
> [   29.923765] x14: 000000000000b0af x13: 0000000000000000 x12: 0000000000000166
> [   29.923783] x11: 0000000000000001 x10: 0000000000001410 x9 : 0000000000000000
> [   29.923801] x8 : ffff00008034f800 x7 : 0000000000000000 x6 : 0000000000000000
> [   29.923819] x5 : 0000000000000000 x4 : 0000000000000002 x3 : 0000000000000000
> [   29.923837] x2 : ffff800082e23290 x1 : dead4ead00000000 x0 : 0000000000000000
> [   29.923855] Call trace:
> [   29.923861]  arm_smmu_domain_alloc_paging+0x80/0x174
> [   29.923872]  __iommu_domain_alloc+0xcc/0xf4
> [   29.923884]  iommu_setup_default_domain+0x294/0x554
> [   29.938567] Bluetooth: hci0: Frame reassembly failed (-84)
> [   29.944494]  __iommu_probe_device+0x418/0x43c
> [   29.944508]  iommu_probe_device+0x3c/0x80
> [   29.944519]  of_iommu_configure+0x124/0x1b4
> [   29.944529]  of_dma_configure_id+0x170/0x2f4
> [   29.969874] mmc0: new ultra high speed SDR104 SDHC card at address 5048
> [   29.972966]  platform_dma_configure+0xa8/0xb4
> [   29.972983]  really_probe+0x70/0x2ac
> [   29.972992]  __driver_probe_device+0x78/0x12c
> [   29.973001]  driver_probe_device+0xd8/0x160
> [   29.973010]  __device_attach_driver+0xb8/0x138
> [   29.973019]  bus_for_each_drv+0x80/0xdc
> [   29.973027]  __device_attach+0x9c/0x188
> [   29.973037]  device_initial_probe+0x14/0x20
> [   29.973046]  bus_probe_device+0xac/0xb0
> [   29.973055]  deferred_probe_work_func+0x8c/0xc8
> [   29.973064]  process_one_work+0x210/0x5e4
> [   29.983596] mmcblk0: mmc0:5048 SD32G 28.8 GiB
> [   29.987546]  worker_thread+0x1bc/0x38c
> [   29.987558]  kthread+0x120/0x124
> [   29.987568]  ret_from_fork+0x10/0x20
> [   29.987579] irq event stamp: 109977
> [   29.987584] hardirqs last  enabled at (109977):
> [<ffff800080fbbc48>] _raw_spin_unlock_irqrestore+0x6c/0x70
> [   29.987600] hardirqs last disabled at (109976):
> [<ffff800080fbb0a8>] _raw_spin_lock_irqsave+0x84/0x88
> [   29.987610] softirqs last  enabled at (109966):
> [<ffff800080090680>] __do_softirq+0x498/0x4e0
> [   29.987619] softirqs last disabled at (109961):
> [<ffff800080096184>] ____do_softirq+0x10/0x1c
> [   30.006747]  mmcblk0: p1
> [   30.010291] ---[ end trace 0000000000000000 ]---
> [   30.018630] remoteproc remoteproc1: remote processor
> 9300000.remoteproc is now up
> [   30.024525] qcom-pcie 600000.pcie: iATU: unroll F, 32 ob, 8 ib,
> align 4K, limit 4G
> [   30.044747] qcom,apr remoteproc1:smd-edge.apr_audio_svc.-1.-1:
> Adding APR/GPR dev: aprsvc:service:4:3
> [   30.046118] qcom-pcie 600000.pcie: Invalid eDMA IRQs found
> [   30.051718] qcom,apr remoteproc1:smd-edge.apr_audio_svc.-1.-1:
> Adding APR/GPR dev: aprsvc:service:4:4
> [   30.066435] Bluetooth: hci0: QCA Downloading qca/nvm_00440302.bin
> [   30.130736] hub 1-1:1.0: USB hub found
> [   30.150390] qcom-pcie 600000.pcie: PCIe Gen.1 x1 link up
> [   30.156394] hub 1-1:1.0: 4 ports detected
> [   30.161837] qcom-pcie 600000.pcie: PCI host bridge to bus 0000:00
> [   30.189583] pci_bus 0000:00: root bus resource [bus 00-ff]
> [   30.195652] pci_bus 0000:00: root bus resource [io  0x0000-0xfffff]
> [   30.201035] pci_bus 0000:00: root bus resource [mem 0x0c300000-0x0cffffff]
> [   30.205424] Bluetooth: hci0: QCA setup on UART is completed
> [   30.207262] pci 0000:00:00.0: [17cb:0104] type 01 class 0x060400
> PCIe Root Port
> [   30.214380] usb 2-1: new SuperSpeed USB device number 2 using xhci-hcd
> [   30.219636] qcom-venus c00000.video-codec: Allocating domain
> [   30.221503] pci 0000:00:00.0: BAR 0 [mem 0x00000000-0x00000fff]
> [   30.221680] pci 0000:00:00.0: PCI bridge to [bus 01-ff]
> [   30.221772] pci 0000:00:00.0:   bridge window [io  0x0000-0x0fff]
> [   30.221832] pci 0000:00:00.0:   bridge window [mem 0x00000000-0x000fffff]
> [   30.221945] pci 0000:00:00.0:   bridge window [mem
> 0x00000000-0x000fffff 64bit pref]
> [   30.222617] pci 0000:00:00.0: PME# supported from D0 D3hot
> [   30.273673] hub 2-1:1.0: USB hub found
> [   30.276567] hub 2-1:1.0: 4 ports detected
> 
> Format: Log Type - Time(microsec) - Message - Optional Info
> Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
> S - QC_IMAGE_VERSION_STRING=BOOT.XF.1.0-00301
> S - IMAGE_VARIANT_STRING=M8996LAB
> S - OEM_IMAGE_VERSION_STRING=crm-ubuntu68
> S - Boot Interface: UFS
> 
> I traced this further, it crashes during arm_smmu_write_context_bank().
> 
> 
> 
> --
> With best wishes
> Dmitry


From suzuki.poulose at arm.com  Tue Feb 13 02:22:39 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 13 Feb 2024 10:22:39 +0000
Subject: [PATCH v7 08/10] coresight-tpdm: Add timestamp control register support for the CMB
In-Reply-To: <7723c9f1-fda7-4dc9-bb5a-e12d4908becf@app.fastmail.com>
References: <7723c9f1-fda7-4dc9-bb5a-e12d4908becf@app.fastmail.com>
Message-ID: <20240213102239.2229731-1-suzuki.poulose@arm.com>

n 13/02/2024 09:50, Arnd Bergmann wrote:
> On Sun, Feb 4, 2024, at 06:30, Tao Zhang wrote:
> 
>> @@ -910,7 +1014,7 @@ static struct attribute *tpdm_dsb_patt_attrs[] = {
>>   	DSB_PATT_MASK_ATTR(5),
>>   	DSB_PATT_MASK_ATTR(6),
>>   	DSB_PATT_MASK_ATTR(7),
>> -	&dev_attr_enable_ts.attr,
>> +	DSB_PATT_ENABLE_TS,
>>   	&dev_attr_set_type.attr,
>>   	NULL,
>>   };
>> @@ -964,6 +1068,7 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
>>   	CMB_PATT_ATTR(1),
>>   	CMB_PATT_MASK_ATTR(0),
>>   	CMB_PATT_MASK_ATTR(1),
>> +	CMB_PATT_ENABLE_TS,
>>   	NULL,
>>   };
>>
>> @@ -158,6 +175,10 @@
>>   		tpdm_simple_dataset_rw(tpmr##nr,		\
>>   		DSB_PATT_MASK, nr)
>>
>> +#define DSB_PATT_ENABLE_TS					\
>> +		tpdm_patt_enable_ts(enable_ts,			\
>> +		DSB_PATT)
>> +
>>   #define DSB_MSR_ATTR(nr)					\
>>   		tpdm_simple_dataset_rw(msr##nr,			\
>>   		DSB_MSR, nr)
> 
> This is causing build failures in linux-next now:
> 
> drivers/hwtracing/coresight/coresight-tpdm.c:1055:2: error: missing field 'idx' initializer [-Werror,-Wmissing-field-initializers]
>   1055 |         DSB_PATT_ENABLE_TS,
>        |         ^
> drivers/hwtracing/coresight/coresight-tpdm.h:184:3: note: expanded from macro 'DSB_PATT_ENABLE_TS'
>    184 |                 tpdm_patt_enable_ts(enable_ts,                  \
>        |                 ^
> drivers/hwtracing/coresight/coresight-tpdm.h:156:5: note: expanded from macro 'tpdm_patt_enable_ts'
>    156 |            }                                                    \
>        |            ^
> drivers/hwtracing/coresight/coresight-tpdm.c:1109:2: error: missing field 'idx' initializer [-Werror,-Wmissing-field-initializers]
>   1109 |         CMB_PATT_ENABLE_TS,
>        |         ^
> drivers/hwtracing/coresight/coresight-tpdm.h:208:3: note: expanded from macro 'CMB_PATT_ENABLE_TS'
>    208 |                 tpdm_patt_enable_ts(enable_ts,                  \
>        |                 ^
> drivers/hwtracing/coresight/coresight-tpdm.h:156:5: note: expanded from macro 'tpdm_patt_enable_ts'
>    156 |            }                                                    \
>        |            ^
> 
> Not sure what is going on, so I reverted your patch locally
> for my test setup.
> Can you send a fix to make it build again?

The idx field is not used for the {DSB,CMB}_PATT_ENABLE_TS attributes and
as such the macros do not set it. May be something like this fixes the problem ?
But any uninitiliased fields must be set to 0 implicitly ?

--->8---
coresight: tpdm: Fix build break due to uninitialised field

{CMB/DSB}_PATT_ENABLE_TS attributes do not use an index field.
But some compilers complain for uninitialised "index" field in
the struct tpdm_dataset_attribute:

drivers/hwtracing/coresight/coresight-tpdm.c:1055:2: error: missing field 'idx' initializer [-Werror,-Wmissing-field-initializers]
 1055 |         DSB_PATT_ENABLE_TS,
      |         ^
drivers/hwtracing/coresight/coresight-tpdm.h:184:3: note: expanded from macro 'DSB_PATT_ENABLE_TS'
  184 |                 tpdm_patt_enable_ts(enable_ts,                  \
      |                 ^
drivers/hwtracing/coresight/coresight-tpdm.h:156:5: note: expanded from macro 'tpdm_patt_enable_ts'
  156 |            }                                                    \
      |            ^
drivers/hwtracing/coresight/coresight-tpdm.c:1109:2: error: missing field 'idx' initializer [-Werror,-Wmissing-field-initializers]
 1109 |         CMB_PATT_ENABLE_TS,
      |         ^
drivers/hwtracing/coresight/coresight-tpdm.h:208:3: note: expanded from macro 'CMB_PATT_ENABLE_TS'
  208 |                 tpdm_patt_enable_ts(enable_ts,                  \
      |                 ^
drivers/hwtracing/coresight/coresight-tpdm.h:156:5: note: expanded from macro 'tpdm_patt_enable_ts'
  156 |            }                                                    \
      |            ^

Reported-by: Arnd Bergmann <arnd at arndb.de>
Cc: Tao Zhang <quic_taozha at quicinc.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
---
 drivers/hwtracing/coresight/coresight-tpdm.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index f3a8f56d0fe7..e08d212642e3 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -153,6 +153,7 @@
 		__ATTR(name, 0644, enable_ts_show,		\
 		enable_ts_store),		\
 		mem,						\
+		0,						\
 	   }							\
 	})[0].attr.attr)
 
-- 
2.34.1



From prabhakar.csengg at gmail.com  Tue Feb 13 02:22:57 2024
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Tue, 13 Feb 2024 10:22:57 +0000
Subject: [PATCH] dt-bindings: timer: renesas: ostm: Document RZ/Five SoC
In-Reply-To: <20231115212908.33131-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20231115212908.33131-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <CA+V-a8tN-qn8zuimte=-riahJBWGgGi8i5botNfWqdWwJ7w-4g@mail.gmail.com>

Hi Daniel,

On Wed, Nov 15, 2023 at 9:29?PM Prabhakar <prabhakar.csengg at gmail.com> wrote:
>
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
>
> The OSTM block on the RZ/Five SoC is identical to one found on the RZ/G2UL
> SoC. "renesas,r9a07g043-ostm" compatible string will be used on the RZ/Five
> SoC so to make this clear and to keep this file consistent, update the
> comment to include RZ/Five SoC.
>
> No driver changes are required as generic compatible string "renesas,ostm"
> will be used as a fallback on RZ/Five SoC.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
>  Documentation/devicetree/bindings/timer/renesas,ostm.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
Gentle ping!

Cheers,
Prabhakar

> diff --git a/Documentation/devicetree/bindings/timer/renesas,ostm.yaml b/Documentation/devicetree/bindings/timer/renesas,ostm.yaml
> index 7207929e5cd6..8b06a681764e 100644
> --- a/Documentation/devicetree/bindings/timer/renesas,ostm.yaml
> +++ b/Documentation/devicetree/bindings/timer/renesas,ostm.yaml
> @@ -23,7 +23,7 @@ properties:
>        - enum:
>            - renesas,r7s72100-ostm  # RZ/A1H
>            - renesas,r7s9210-ostm   # RZ/A2M
> -          - renesas,r9a07g043-ostm # RZ/G2UL
> +          - renesas,r9a07g043-ostm # RZ/G2UL and RZ/Five
>            - renesas,r9a07g044-ostm # RZ/G2{L,LC}
>            - renesas,r9a07g054-ostm # RZ/V2L
>        - const: renesas,ostm        # Generic
> --
> 2.34.1
>


From neil.armstrong at linaro.org  Tue Feb 13 02:26:59 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 13 Feb 2024 11:26:59 +0100
Subject: [PATCH] ASoC: meson: add helpers for clk_disable_unprepare
In-Reply-To: <20240213101220.459641-1-arnd@kernel.org>
References: <20240213101220.459641-1-arnd@kernel.org>
Message-ID: <01bdaec0-c926-4dbb-884d-2215981299ab@linaro.org>

On 13/02/2024 11:11, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> Casting between incompatible function types causes a warning with clang-16
> because it breaks control flow integrity (KCFI) rules:
> 
> sound/soc/meson/aiu.c:243:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>    243 |                                        (void(*)(void *))clk_disable_unprepare,
>        |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/device.h:406:34: note: expanded from macro 'devm_add_action_or_reset'
>    406 |         __devm_add_action_or_reset(dev, action, data, #action)
>        |                                         ^~~~~~
> sound/soc/meson/t9015.c:274:4: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>    274 |                         (void(*)(void *))clk_disable_unprepare,
>        |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/device.h:406:34: note: expanded from macro 'devm_add_action_or_reset'
>    406 |         __devm_add_action_or_reset(dev, action, data, #action)
>        |                                         ^~~~~~
> 
> These two meson drivers cast clk_disable_unprepare() into a different type
> in order to have it automatically called from the driver relase. Add
> trivial helpers to do the same using correct types.
> 
> Fixes: 33901f5b9b16 ("ASoC: meson: add t9015 internal DAC driver")
> Fixes: 6ae9ca9ce986 ("ASoC: meson: aiu: add i2s and spdif support")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> ---
>   sound/soc/meson/aiu.c   | 9 ++++++---
>   sound/soc/meson/t9015.c | 9 ++++++---
>   2 files changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c
> index 7109b81cc3d0..211f360df284 100644
> --- a/sound/soc/meson/aiu.c
> +++ b/sound/soc/meson/aiu.c
> @@ -209,6 +209,11 @@ static const char * const aiu_spdif_ids[] = {
>   	[MCLK]	= "spdif_mclk_sel"
>   };
>   
> +static void aiu_clk_disable(void *clk)
> +{
> +	clk_disable_unprepare(clk);
> +}
> +
>   static int aiu_clk_get(struct device *dev)
>   {
>   	struct aiu *aiu = dev_get_drvdata(dev);
> @@ -239,9 +244,7 @@ static int aiu_clk_get(struct device *dev)
>   		return ret;
>   	}
>   
> -	ret = devm_add_action_or_reset(dev,
> -				       (void(*)(void *))clk_disable_unprepare,
> -				       aiu->pclk);
> +	ret = devm_add_action_or_reset(dev, aiu_clk_disable, aiu->pclk);
>   	if (ret)
>   		dev_err(dev, "failed to add reset action on pclk");
>   
> diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c
> index 9c6b4dac6893..e0f9a603a5e9 100644
> --- a/sound/soc/meson/t9015.c
> +++ b/sound/soc/meson/t9015.c
> @@ -243,6 +243,11 @@ static const struct regmap_config t9015_regmap_config = {
>   	.max_register		= POWER_CFG,
>   };
>   
> +static void t9015_clk_disable(void *clk)
> +{
> +	clk_disable_unprepare(clk);
> +}
> +
>   static int t9015_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
> @@ -270,9 +275,7 @@ static int t9015_probe(struct platform_device *pdev)
>   		return ret;
>   	}
>   
> -	ret = devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			priv->pclk);
> +	ret = devm_add_action_or_reset(dev, t9015_clk_disable, priv->pclk);
>   	if (ret)
>   		return ret;
>   

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Tue Feb 13 02:27:06 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 13 Feb 2024 11:27:06 +0100
Subject: [PATCH] nvmem: meson-efuse: fix function pointer type mismatch
In-Reply-To: <20240213101607.460930-1-arnd@kernel.org>
References: <20240213101607.460930-1-arnd@kernel.org>
Message-ID: <19dc040e-e023-4a17-a6bb-8aca156088d0@linaro.org>

On 13/02/2024 11:15, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> clang-16 warns about casting functions to incompatible types, as is done
> here to call clk_disable_unprepare:
> 
> drivers/nvmem/meson-efuse.c:78:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>     78 |                                        (void(*)(void *))clk_disable_unprepare,
> 
> Address this with a trivial helper function that adjusts the return code.
> 
> Fixes: 611fbca1c861 ("nvmem: meson-efuse: add peripheral clock")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> ---
>   drivers/nvmem/meson-efuse.c | 9 ++++++---
>   1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
> index b922df99f9bc..3b9e31d7d073 100644
> --- a/drivers/nvmem/meson-efuse.c
> +++ b/drivers/nvmem/meson-efuse.c
> @@ -38,6 +38,11 @@ static const struct of_device_id meson_efuse_match[] = {
>   };
>   MODULE_DEVICE_TABLE(of, meson_efuse_match);
>   
> +static void meson_efuse_clk_disable(void *clk)
> +{
> +	clk_disable_unprepare(clk);
> +}
> +
>   static int meson_efuse_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
> @@ -74,9 +79,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
>   		return ret;
>   	}
>   
> -	ret = devm_add_action_or_reset(dev,
> -				       (void(*)(void *))clk_disable_unprepare,
> -				       clk);
> +	ret = devm_add_action_or_reset(dev, meson_efuse_clk_disable, clk);
>   	if (ret) {
>   		dev_err(dev, "failed to add disable callback");
>   		return ret;

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From quic_pbrahma at quicinc.com  Tue Feb 13 02:28:53 2024
From: quic_pbrahma at quicinc.com (Pratyush Brahma)
Date: Tue, 13 Feb 2024 15:58:53 +0530
Subject: [PATCH v1 08/10] iommu/arm-smmu-qcom: Merge table from
 arm-smmu-qcom-debug into match data
In-Reply-To: <20221114170635.1406534-9-dmitry.baryshkov@linaro.org>
References: <20221114170635.1406534-9-dmitry.baryshkov@linaro.org>
Message-ID: <a61a3561-0dde-472b-b8a5-451703f6d8ee@quicinc.com>

Hi

Patch [1] introduces a use after free bug in the function 
"qcom_smmu_create()" in file: drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
wherein devm_krealloc() frees the old pointer marked by "smmu" but it is 
still being accessed later in qcom_smmu_impl_data() in the same function 
as:

qsmmu->cfg = qcom_smmu_impl_data(smmu);

The current patchset [2] implicitly fixes this issue as it doesn't 
access the freed ptr in the line:

qsmmu->cfg = data->cfg;

Hence, can this patchset[2] be propagated to branches where patchset[1] 
has been propagated already? The bug is currently present in all branches
that have patchset[1] but do not have patchset[2].

RFC:

This bug would be reintroduced if patchset [3] is accepted. This makes 
the path prone to such errors as it relies on the
developer's understanding on the internal implementation of devm_krealloc().

Hence, a better fix IMO, would be to remove the confusion around the 
freed "smmu" ptr in the following way:

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 549ae4dba3a6..6dd142ce75d1 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -463,11 +463,12 @@ static struct arm_smmu_device 
*qcom_smmu_create(struct arm_smmu_device *smmu,
 ??????? qsmmu = devm_krealloc(smmu->dev, smmu, sizeof(*qsmmu), GFP_KERNEL);
 ??????? if (!qsmmu)
 ??????????????? return ERR_PTR(-ENOMEM);
+?????? smmu = &qsmmu->smmu;

 ??????? qsmmu->smmu.impl = impl;
 ??????? qsmmu->cfg = data->cfg;

-?????? return &qsmmu->smmu;
+?????? return smmu;
 ?}

This is similar to the patch[4] which I've sent in-reply-to patch[3]. 
Will send a formal patch if you think this approach is better.

Please let me know your thoughts.

Thanks,
Pratyush


[1] 
https://lore.kernel.org/all/20220708094230.4349-1-quic_saipraka at quicinc.com/
[2] 
https://lore.kernel.org/all/20221114170635.1406534-9-dmitry.baryshkov at linaro.org/
[3] 
https://lore.kernel.org/all/20240201210529.7728-4-quic_c_gdjako at quicinc.com/
[4] 
https://lore.kernel.org/all/20240213062608.13018-1-quic_pbrahma at quicinc.com/


From suzuki.poulose at arm.com  Tue Feb 13 02:32:02 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 13 Feb 2024 10:32:02 +0000
Subject: [PATCH V4 03/11] coresight: tmc: Extract device properties from
 AMBA pid based table lookup
In-Reply-To: <0c65f3b0-a879-444c-b0a4-4af485e72166@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-4-anshuman.khandual@arm.com>
 <44597c9a-79bd-40f8-87a7-b53582132583@arm.com>
 <0c65f3b0-a879-444c-b0a4-4af485e72166@arm.com>
Message-ID: <39c01eae-049b-4f5b-b86e-4af22c8246c1@arm.com>

On 13/02/2024 03:13, Anshuman Khandual wrote:
> 
> 
> On 2/12/24 17:43, Suzuki K Poulose wrote:
>> On 23/01/2024 05:46, Anshuman Khandual wrote:
>>> This extracts device properties from AMBA pid based table lookup. This also
>>> defers tmc_etr_setup_caps() after the coresight device has been initialized
>>> so that PID value can be read.
>>>
>>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>>> Cc: Mike Leach <mike.leach at linaro.org>
>>> Cc: James Clark <james.clark 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>
>>> ---
>>>  ? .../hwtracing/coresight/coresight-tmc-core.c? | 19 +++++++++++++------
>>>  ? 1 file changed, 13 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
>>> index 7ec5365e2b64..e71db3099a29 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
>>> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
>>> @@ -370,16 +370,24 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
>>>  ????? return (auth & TMC_AUTH_NSID_MASK) == 0x3;
>>>  ? }
>>>  ? +#define TMC_AMBA_MASK 0xfffff
>>> +
>>> +static const struct amba_id tmc_ids[];
>>> +
>>>  ? /* Detect and initialise the capabilities of a TMC ETR */
>>> -static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
>>> +static int tmc_etr_setup_caps(struct device *parent, u32 devid)
>>>  ? {
>>>  ????? int rc;
>>> -??? u32 dma_mask = 0;
>>> +??? u32 tmc_pid, dma_mask = 0;
>>>  ????? struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
>>> +??? void *dev_caps;
>>>  ? ????? if (!tmc_etr_has_non_secure_access(drvdata))
>>>  ????????? return -EACCES;
>>>  ? +??? tmc_pid = coresight_get_pid(&drvdata->csdev->access) & TMC_AMBA_MASK;
>>> +??? dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid);
>>> +
>>>  ????? /* Set the unadvertised capabilities */
>>>  ????? tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
>>>  ? @@ -497,10 +505,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>>  ????????? desc.type = CORESIGHT_DEV_TYPE_SINK;
>>>  ????????? desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
>>>  ????????? desc.ops = &tmc_etr_cs_ops;
>>> -??????? ret = tmc_etr_setup_caps(dev, devid,
>>> -???????????????????? coresight_get_uci_data(id));
>>> -??????? if (ret)
>>> -??????????? goto out;
>>>  ????????? idr_init(&drvdata->idr);
>>>  ????????? mutex_init(&drvdata->idr_mutex);
>>>  ????????? dev_list = &etr_devs;
>>> @@ -539,6 +543,9 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>>  ????????? goto out;
>>>  ????? }
>>>  ? +??? if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
>>> +??????? ret = tmc_etr_setup_caps(dev, devid);
>>> +
>>
>> With this change, we silently accept an ETR that may only have "SECURE" access only and crash later while we try to enable tracing. You could
>> pass in the "access" (which is already in 'desc.access' in the original
>> call site and deal with it ?
> 
> Just wondering, if something like the following will help ? A failed tmc_etr_setup_caps()
> because of failed tmc_etr_has_non_secure_access(), will unregister the coresight device
> before returning.
> 
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -538,8 +538,13 @@ static int __tmc_probe(struct device *dev, struct resource *res)
>                  goto out;
>          }
>   
> -       if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
> +       if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
>                  ret = tmc_etr_setup_caps(dev, devid);
> +               if (ret) {
> +                       coresight_unregister(drvdata->csdev);
> +                       goto out;
> +               }
> +       }

Why do we move the tmc_etr_setup_caps() in the first place ? We could 
retain where that was and pass "desc.access" parameter rather than 
registering the csdev and then relying csdev->access ?

Suzuki

>   
>          drvdata->miscdev.name = desc.name;
>          drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;



From mkl at pengutronix.de  Tue Feb 13 02:22:49 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 13 Feb 2024 11:22:49 +0100
Subject: [PATCH RESEND v7 0/3] can: xilinx_can: Add ECC feature support
In-Reply-To: <1705059453-29099-1-git-send-email-srinivas.goud@amd.com>
References: <1705059453-29099-1-git-send-email-srinivas.goud@amd.com>
Message-ID: <20240213-evasion-crevice-3faa375c1666-mkl@pengutronix.de>

On 12.01.2024 17:07:30, Srinivas Goud wrote:
> Add ECC feature support to Tx and Rx FIFOs for Xilinx CAN Controller.
> ECC is an IP configuration option where counter registers are added in
> IP for 1bit/2bit ECC errors count and reset.
> Also driver reports 1bit/2bit ECC errors for FIFOs based on ECC error
> interrupts.
> 
> Add xlnx,has-ecc optional property for Xilinx AXI CAN controller
> to support ECC if the ECC block is enabled in the HW.
> 
> Add ethtool stats interface for getting all the ECC errors information.
> 
> There is no public documentation for it available.

Lately I was using ethtool based stats, too and figured out, there's no
need for a spinlock, you can use a struct u64_stats_sync,
u64_stats_update_begin(), u64_stats_update_end(), and
u64_stats_fetch_retry() instead. These are no-ops on 64 bit systems and
sequential locks on 32 bit systems.

I'll send a v8.

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
-------------- 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/20240213/91130579/attachment.sig>

From mkl at pengutronix.de  Tue Feb 13 02:36:43 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 13 Feb 2024 11:36:43 +0100
Subject: [PATCH v8 1/3] dt-bindings: can: xilinx_can: Add 'xlnx,has-ecc'
 optional property
In-Reply-To: <20240213-xilinx_ecc-v8-0-8d75f8b80771@pengutronix.de>
References: <20240213-xilinx_ecc-v8-0-8d75f8b80771@pengutronix.de>
Message-ID: <20240213-xilinx_ecc-v8-1-8d75f8b80771@pengutronix.de>

From: Srinivas Goud <srinivas.goud at amd.com>

ECC feature added to CAN TX_OL, TX_TL and RX FIFOs of Xilinx AXI CAN
Controller.

ECC is an IP configuration option where counter registers are added in
IP for 1bit/2bit ECC errors.

'xlnx,has-ecc' is an optional property and added to Xilinx AXI CAN
Controller node if ECC block enabled in the HW

Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Srinivas Goud <srinivas.goud at amd.com>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 Documentation/devicetree/bindings/net/can/xilinx,can.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/can/xilinx,can.yaml b/Documentation/devicetree/bindings/net/can/xilinx,can.yaml
index 64d57c343e6f..8d4e5af6fd6c 100644
--- a/Documentation/devicetree/bindings/net/can/xilinx,can.yaml
+++ b/Documentation/devicetree/bindings/net/can/xilinx,can.yaml
@@ -49,6 +49,10 @@ properties:
   resets:
     maxItems: 1
 
+  xlnx,has-ecc:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description: CAN TX_OL, TX_TL and RX FIFOs have ECC support(AXI CAN)
+
 required:
   - compatible
   - reg
@@ -137,6 +141,7 @@ examples:
         interrupts = <GIC_SPI 59 IRQ_TYPE_EDGE_RISING>;
         tx-fifo-depth = <0x40>;
         rx-fifo-depth = <0x40>;
+        xlnx,has-ecc;
     };
 
   - |

-- 
2.43.0




From mkl at pengutronix.de  Tue Feb 13 02:36:45 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 13 Feb 2024 11:36:45 +0100
Subject: [PATCH v8 3/3] can: xilinx_can: Add ethtool stats interface for
 ECC errors
In-Reply-To: <20240213-xilinx_ecc-v8-0-8d75f8b80771@pengutronix.de>
References: <20240213-xilinx_ecc-v8-0-8d75f8b80771@pengutronix.de>
Message-ID: <20240213-xilinx_ecc-v8-3-8d75f8b80771@pengutronix.de>

From: Srinivas Goud <srinivas.goud at amd.com>

Add ethtool stats interface for reading FIFO 1bit/2bit ECC errors
information.

Signed-off-by: Srinivas Goud <srinivas.goud at amd.com>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 drivers/net/can/xilinx_can.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index af2af4eade3c..fae0120473f8 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -228,6 +228,7 @@ struct xcan_devtype_data {
  * @transceiver:		Optional pointer to associated CAN transceiver
  * @rstc:			Pointer to reset control
  * @ecc_enable:			ECC enable flag
+ * @syncp:			synchronization for ECC error stats
  * @ecc_rx_2_bit_errors:	RXFIFO 2bit ECC count
  * @ecc_rx_1_bit_errors:	RXFIFO 1bit ECC count
  * @ecc_txol_2_bit_errors:	TXOLFIFO 2bit ECC count
@@ -254,6 +255,7 @@ struct xcan_priv {
 	struct phy *transceiver;
 	struct reset_control *rstc;
 	bool ecc_enable;
+	struct u64_stats_sync syncp;
 	u64_stats_t ecc_rx_2_bit_errors;
 	u64_stats_t ecc_rx_1_bit_errors;
 	u64_stats_t ecc_txol_2_bit_errors;
@@ -347,6 +349,24 @@ static const struct can_tdc_const xcan_tdc_const_canfd2 = {
 	.tdcf_max = 0,
 };
 
+enum xcan_stats_type {
+	XCAN_ECC_RX_2_BIT_ERRORS,
+	XCAN_ECC_RX_1_BIT_ERRORS,
+	XCAN_ECC_TXOL_2_BIT_ERRORS,
+	XCAN_ECC_TXOL_1_BIT_ERRORS,
+	XCAN_ECC_TXTL_2_BIT_ERRORS,
+	XCAN_ECC_TXTL_1_BIT_ERRORS,
+};
+
+static const char xcan_priv_flags_strings[][ETH_GSTRING_LEN] = {
+	[XCAN_ECC_RX_2_BIT_ERRORS] = "ecc_rx_2_bit_errors",
+	[XCAN_ECC_RX_1_BIT_ERRORS] = "ecc_rx_1_bit_errors",
+	[XCAN_ECC_TXOL_2_BIT_ERRORS] = "ecc_txol_2_bit_errors",
+	[XCAN_ECC_TXOL_1_BIT_ERRORS] = "ecc_txol_1_bit_errors",
+	[XCAN_ECC_TXTL_2_BIT_ERRORS] = "ecc_txtl_2_bit_errors",
+	[XCAN_ECC_TXTL_1_BIT_ERRORS] = "ecc_txtl_1_bit_errors",
+};
+
 /**
  * xcan_write_reg_le - Write a value to the device register little endian
  * @priv:	Driver private data structure
@@ -1182,6 +1202,8 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
 		priv->write_reg(priv, XCAN_ECC_CFG_OFFSET, XCAN_ECC_CFG_REECRX_MASK |
 				XCAN_ECC_CFG_REECTXOL_MASK | XCAN_ECC_CFG_REECTXTL_MASK);
 
+		u64_stats_update_begin(&priv->syncp);
+
 		if (isr & XCAN_IXR_E2BERX_MASK) {
 			u64_stats_add(&priv->ecc_rx_2_bit_errors,
 				      FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_rx_ecc));
@@ -1211,6 +1233,8 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
 			u64_stats_add(&priv->ecc_txtl_1_bit_errors,
 				      FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_txtl_ecc));
 		}
+
+		u64_stats_update_end(&priv->syncp);
 	}
 
 	if (cf.can_id) {
@@ -1637,6 +1661,43 @@ static int xcan_get_auto_tdcv(const struct net_device *ndev, u32 *tdcv)
 	return 0;
 }
 
+static void xcan_get_strings(struct net_device *ndev, u32 stringset, u8 *buf)
+{
+	switch (stringset) {
+	case ETH_SS_STATS:
+		memcpy(buf, &xcan_priv_flags_strings,
+		       sizeof(xcan_priv_flags_strings));
+	}
+}
+
+static int xcan_get_sset_count(struct net_device *netdev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return ARRAY_SIZE(xcan_priv_flags_strings);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void xcan_get_ethtool_stats(struct net_device *ndev,
+				   struct ethtool_stats *stats, u64 *data)
+{
+	struct xcan_priv *priv = netdev_priv(ndev);
+	unsigned int start;
+
+	do {
+		start = u64_stats_fetch_begin(&priv->syncp);
+
+		data[XCAN_ECC_RX_2_BIT_ERRORS] = u64_stats_read(&priv->ecc_rx_2_bit_errors);
+		data[XCAN_ECC_RX_1_BIT_ERRORS] = u64_stats_read(&priv->ecc_rx_1_bit_errors);
+		data[XCAN_ECC_TXOL_2_BIT_ERRORS] = u64_stats_read(&priv->ecc_txol_2_bit_errors);
+		data[XCAN_ECC_TXOL_1_BIT_ERRORS] = u64_stats_read(&priv->ecc_txol_1_bit_errors);
+		data[XCAN_ECC_TXTL_2_BIT_ERRORS] = u64_stats_read(&priv->ecc_txtl_2_bit_errors);
+		data[XCAN_ECC_TXTL_1_BIT_ERRORS] = u64_stats_read(&priv->ecc_txtl_1_bit_errors);
+	} while (u64_stats_fetch_retry(&priv->syncp, start));
+}
+
 static const struct net_device_ops xcan_netdev_ops = {
 	.ndo_open	= xcan_open,
 	.ndo_stop	= xcan_close,
@@ -1646,6 +1707,9 @@ static const struct net_device_ops xcan_netdev_ops = {
 
 static const struct ethtool_ops xcan_ethtool_ops = {
 	.get_ts_info = ethtool_op_get_ts_info,
+	.get_strings = xcan_get_strings,
+	.get_sset_count = xcan_get_sset_count,
+	.get_ethtool_stats = xcan_get_ethtool_stats,
 };
 
 /**

-- 
2.43.0




From mkl at pengutronix.de  Tue Feb 13 02:36:42 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 13 Feb 2024 11:36:42 +0100
Subject: [PATCH v8 0/3] Add ECC feature support to Tx and Rx FIFOs for
 Xilinx CAN Controller.
Message-ID: <20240213-xilinx_ecc-v8-0-8d75f8b80771@pengutronix.de>

ECC is an IP configuration option where counter registers are added in
IP for 1bit/2bit ECC errors count and reset.

Also driver reports 1bit/2bit ECC errors for FIFOs based on ECC error
interrupts.

Add xlnx,has-ecc optional property for Xilinx AXI CAN controller
to support ECC if the ECC block is enabled in the HW.

Add ethtool stats interface for getting all the ECC errors information.

There is no public documentation for it available.

Changes in v8:
- Use u64_stats_sync instead of spinlock
- Renamed stats strings: use "_" instead of "-"
- Renamed stats strings: add "_errors" trailer
- Renamed stats variables similar to stats strings

Changes in v7:
- Update with spinlock only for stats counters

Changes in v6:
- Update commit description

Changes in v5:
- Fix review comments
- Change the sequence of updates the stats
- Add get_strings and get_sset_count stats interface
- Use u64 stats helper function

Changes in v4:
- Fix DT binding check warning
- Update xlnx,has-ecc property description

Changes in v3:
- Update mailing list
- Update commit description

Changes in v2:
- Address review comments
- Add ethtool stats interface
- Update commit description

---
Srinivas Goud (3):
      dt-bindings: can: xilinx_can: Add 'xlnx,has-ecc' optional property
      can: xilinx_can: Add ECC support
      can: xilinx_can: Add ethtool stats interface for ECC errors

 .../devicetree/bindings/net/can/xilinx,can.yaml    |   5 +
 drivers/net/can/xilinx_can.c                       | 169 ++++++++++++++++++++-
 2 files changed, 170 insertions(+), 4 deletions(-)
---
base-commit: a3522a2edb3faf8cb98d38c2a99f5967beef24e2
change-id: 20240213-xilinx_ecc-8310f5556010

Best regards,
-- 
Marc Kleine-Budde <mkl at pengutronix.de>




From mkl at pengutronix.de  Tue Feb 13 02:36:44 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 13 Feb 2024 11:36:44 +0100
Subject: [PATCH v8 2/3] can: xilinx_can: Add ECC support
In-Reply-To: <20240213-xilinx_ecc-v8-0-8d75f8b80771@pengutronix.de>
References: <20240213-xilinx_ecc-v8-0-8d75f8b80771@pengutronix.de>
Message-ID: <20240213-xilinx_ecc-v8-2-8d75f8b80771@pengutronix.de>

From: Srinivas Goud <srinivas.goud at amd.com>

Add ECC support for Xilinx CAN Controller, so this driver reports
1bit/2bit ECC errors for FIFO's based on ECC error interrupt. ECC
feature for Xilinx CAN Controller selected through 'xlnx,has-ecc' DT
property

Signed-off-by: Srinivas Goud <srinivas.goud at amd.com>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 drivers/net/can/xilinx_can.c | 105 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 101 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index 3722eaa84234..af2af4eade3c 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -31,6 +31,7 @@
 #include <linux/phy/phy.h>
 #include <linux/pm_runtime.h>
 #include <linux/reset.h>
+#include <linux/u64_stats_sync.h>
 
 #define DRIVER_NAME	"xilinx_can"
 
@@ -58,6 +59,13 @@ enum xcan_reg {
 					  */
 	XCAN_F_BTR_OFFSET	= 0x08C, /* Data Phase Bit Timing */
 	XCAN_TRR_OFFSET		= 0x0090, /* TX Buffer Ready Request */
+
+	/* only on AXI CAN cores */
+	XCAN_ECC_CFG_OFFSET	= 0xC8, /* ECC Configuration */
+	XCAN_TXTLFIFO_ECC_OFFSET	= 0xCC, /* TXTL FIFO ECC error counter */
+	XCAN_TXOLFIFO_ECC_OFFSET	= 0xD0, /* TXOL FIFO ECC error counter */
+	XCAN_RXFIFO_ECC_OFFSET	= 0xD4, /* RX FIFO ECC error counter */
+
 	XCAN_AFR_EXT_OFFSET	= 0x00E0, /* Acceptance Filter */
 	XCAN_FSR_OFFSET		= 0x00E8, /* RX FIFO Status */
 	XCAN_TXMSG_BASE_OFFSET	= 0x0100, /* TX Message Space */
@@ -124,6 +132,18 @@ enum xcan_reg {
 #define XCAN_IXR_TXFLL_MASK		0x00000004 /* Tx FIFO Full intr */
 #define XCAN_IXR_TXOK_MASK		0x00000002 /* TX successful intr */
 #define XCAN_IXR_ARBLST_MASK		0x00000001 /* Arbitration lost intr */
+#define XCAN_IXR_E2BERX_MASK		BIT(23) /* RX FIFO two bit ECC error */
+#define XCAN_IXR_E1BERX_MASK		BIT(22) /* RX FIFO one bit ECC error */
+#define XCAN_IXR_E2BETXOL_MASK		BIT(21) /* TXOL FIFO two bit ECC error */
+#define XCAN_IXR_E1BETXOL_MASK		BIT(20) /* TXOL FIFO One bit ECC error */
+#define XCAN_IXR_E2BETXTL_MASK		BIT(19) /* TXTL FIFO Two bit ECC error */
+#define XCAN_IXR_E1BETXTL_MASK		BIT(18) /* TXTL FIFO One bit ECC error */
+#define XCAN_IXR_ECC_MASK		(XCAN_IXR_E2BERX_MASK | \
+					XCAN_IXR_E1BERX_MASK | \
+					XCAN_IXR_E2BETXOL_MASK | \
+					XCAN_IXR_E1BETXOL_MASK | \
+					XCAN_IXR_E2BETXTL_MASK | \
+					XCAN_IXR_E1BETXTL_MASK)
 #define XCAN_IDR_ID1_MASK		0xFFE00000 /* Standard msg identifier */
 #define XCAN_IDR_SRR_MASK		0x00100000 /* Substitute remote TXreq */
 #define XCAN_IDR_IDE_MASK		0x00080000 /* Identifier extension */
@@ -137,6 +157,11 @@ enum xcan_reg {
 #define XCAN_2_FSR_RI_MASK		0x0000003F /* RX Read Index */
 #define XCAN_DLCR_EDL_MASK		0x08000000 /* EDL Mask in DLC */
 #define XCAN_DLCR_BRS_MASK		0x04000000 /* BRS Mask in DLC */
+#define XCAN_ECC_CFG_REECRX_MASK	BIT(2) /* Reset RX FIFO ECC error counters */
+#define XCAN_ECC_CFG_REECTXOL_MASK	BIT(1) /* Reset TXOL FIFO ECC error counters */
+#define XCAN_ECC_CFG_REECTXTL_MASK	BIT(0) /* Reset TXTL FIFO ECC error counters */
+#define XCAN_ECC_1BIT_CNT_MASK		GENMASK(15, 0) /* FIFO ECC 1bit count mask */
+#define XCAN_ECC_2BIT_CNT_MASK		GENMASK(31, 16) /* FIFO ECC 2bit count mask */
 
 /* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */
 #define XCAN_BRPR_TDC_ENABLE		BIT(16) /* Transmitter Delay Compensation (TDC) Enable */
@@ -202,6 +227,13 @@ struct xcan_devtype_data {
  * @devtype:			Device type specific constants
  * @transceiver:		Optional pointer to associated CAN transceiver
  * @rstc:			Pointer to reset control
+ * @ecc_enable:			ECC enable flag
+ * @ecc_rx_2_bit_errors:	RXFIFO 2bit ECC count
+ * @ecc_rx_1_bit_errors:	RXFIFO 1bit ECC count
+ * @ecc_txol_2_bit_errors:	TXOLFIFO 2bit ECC count
+ * @ecc_txol_1_bit_errors:	TXOLFIFO 1bit ECC count
+ * @ecc_txtl_2_bit_errors:	TXTLFIFO 2bit ECC count
+ * @ecc_txtl_1_bit_errors:	TXTLFIFO 1bit ECC count
  */
 struct xcan_priv {
 	struct can_priv can;
@@ -221,6 +253,13 @@ struct xcan_priv {
 	struct xcan_devtype_data devtype;
 	struct phy *transceiver;
 	struct reset_control *rstc;
+	bool ecc_enable;
+	u64_stats_t ecc_rx_2_bit_errors;
+	u64_stats_t ecc_rx_1_bit_errors;
+	u64_stats_t ecc_txol_2_bit_errors;
+	u64_stats_t ecc_txol_1_bit_errors;
+	u64_stats_t ecc_txtl_2_bit_errors;
+	u64_stats_t ecc_txtl_1_bit_errors;
 };
 
 /* CAN Bittiming constants as per Xilinx CAN specs */
@@ -523,6 +562,9 @@ static int xcan_chip_start(struct net_device *ndev)
 		XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
 		XCAN_IXR_ARBLST_MASK | xcan_rx_int_mask(priv);
 
+	if (priv->ecc_enable)
+		ier |= XCAN_IXR_ECC_MASK;
+
 	if (priv->devtype.flags & XCAN_FLAG_RXMNF)
 		ier |= XCAN_IXR_RXMNF_MASK;
 
@@ -1127,6 +1169,50 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
 		priv->can.can_stats.bus_error++;
 	}
 
+	if (priv->ecc_enable && isr & XCAN_IXR_ECC_MASK) {
+		u32 reg_rx_ecc, reg_txol_ecc, reg_txtl_ecc;
+
+		reg_rx_ecc = priv->read_reg(priv, XCAN_RXFIFO_ECC_OFFSET);
+		reg_txol_ecc = priv->read_reg(priv, XCAN_TXOLFIFO_ECC_OFFSET);
+		reg_txtl_ecc = priv->read_reg(priv, XCAN_TXTLFIFO_ECC_OFFSET);
+
+		/* The counter reaches its maximum at 0xffff and does not overflow.
+		 * Accept the small race window between reading and resetting ECC counters.
+		 */
+		priv->write_reg(priv, XCAN_ECC_CFG_OFFSET, XCAN_ECC_CFG_REECRX_MASK |
+				XCAN_ECC_CFG_REECTXOL_MASK | XCAN_ECC_CFG_REECTXTL_MASK);
+
+		if (isr & XCAN_IXR_E2BERX_MASK) {
+			u64_stats_add(&priv->ecc_rx_2_bit_errors,
+				      FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_rx_ecc));
+		}
+
+		if (isr & XCAN_IXR_E1BERX_MASK) {
+			u64_stats_add(&priv->ecc_rx_1_bit_errors,
+				      FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_rx_ecc));
+		}
+
+		if (isr & XCAN_IXR_E2BETXOL_MASK) {
+			u64_stats_add(&priv->ecc_txol_2_bit_errors,
+				      FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_txol_ecc));
+		}
+
+		if (isr & XCAN_IXR_E1BETXOL_MASK) {
+			u64_stats_add(&priv->ecc_txol_1_bit_errors,
+				      FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_txol_ecc));
+		}
+
+		if (isr & XCAN_IXR_E2BETXTL_MASK) {
+			u64_stats_add(&priv->ecc_txtl_2_bit_errors,
+				      FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_txtl_ecc));
+		}
+
+		if (isr & XCAN_IXR_E1BETXTL_MASK) {
+			u64_stats_add(&priv->ecc_txtl_1_bit_errors,
+				      FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_txtl_ecc));
+		}
+	}
+
 	if (cf.can_id) {
 		struct can_frame *skb_cf;
 		struct sk_buff *skb = alloc_can_err_skb(ndev, &skb_cf);
@@ -1354,8 +1440,8 @@ static irqreturn_t xcan_interrupt(int irq, void *dev_id)
 {
 	struct net_device *ndev = (struct net_device *)dev_id;
 	struct xcan_priv *priv = netdev_priv(ndev);
+	u32 isr_errors, mask;
 	u32 isr, ier;
-	u32 isr_errors;
 	u32 rx_int_mask = xcan_rx_int_mask(priv);
 
 	/* Get the interrupt status from Xilinx CAN */
@@ -1374,10 +1460,15 @@ static irqreturn_t xcan_interrupt(int irq, void *dev_id)
 	if (isr & XCAN_IXR_TXOK_MASK)
 		xcan_tx_interrupt(ndev, isr);
 
+	mask = XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
+		XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK |
+		XCAN_IXR_RXMNF_MASK;
+
+	if (priv->ecc_enable)
+		mask |= XCAN_IXR_ECC_MASK;
+
 	/* Check for the type of error interrupt and Processing it */
-	isr_errors = isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
-			    XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK |
-			    XCAN_IXR_RXMNF_MASK);
+	isr_errors = isr & mask;
 	if (isr_errors) {
 		priv->write_reg(priv, XCAN_ICR_OFFSET, isr_errors);
 		xcan_err_interrupt(ndev, isr);
@@ -1793,6 +1884,7 @@ static int xcan_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	priv = netdev_priv(ndev);
+	priv->ecc_enable = of_property_read_bool(pdev->dev.of_node, "xlnx,has-ecc");
 	priv->dev = &pdev->dev;
 	priv->can.bittiming_const = devtype->bittiming_const;
 	priv->can.do_set_mode = xcan_do_set_mode;
@@ -1909,6 +2001,11 @@ static int xcan_probe(struct platform_device *pdev)
 		   priv->reg_base, ndev->irq, priv->can.clock.freq,
 		   hw_tx_max, priv->tx_max);
 
+	if (priv->ecc_enable) {
+		/* Reset FIFO ECC counters */
+		priv->write_reg(priv, XCAN_ECC_CFG_OFFSET, XCAN_ECC_CFG_REECRX_MASK |
+			XCAN_ECC_CFG_REECTXOL_MASK | XCAN_ECC_CFG_REECTXTL_MASK);
+	}
 	return 0;
 
 err_disableclks:

-- 
2.43.0




From lpieralisi at kernel.org  Tue Feb 13 02:38:43 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Tue, 13 Feb 2024 11:38:43 +0100
Subject: [PATCH v9 16/16] PCI: imx6: Add iMX95 Endpoint (EP) support
In-Reply-To: <20240119171122.3057511-17-Frank.Li@nxp.com>
References: <20240119171122.3057511-1-Frank.Li@nxp.com>
 <20240119171122.3057511-17-Frank.Li@nxp.com>
Message-ID: <ZctGs2d9ccnmYysL@lpieralisi>

[+Christoph, Robin - just checking with you if the DMA mask handling is
what you expect from drivers, don't want to merge code that breaks your
expectations]

On Fri, Jan 19, 2024 at 12:11:22PM -0500, Frank Li wrote:
> Add iMX95 EP support and add 64bit address support. Internal bus bridge for
> PCI support 64bit dma address in iMX95. Hence, call
> dma_set_mask_and_coherent() to set 64 bit DMA mask.
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> 
> Notes:
>     Change from v8 to v9
>     - update fixme comments
>     - update BAR1 comments
>     - Add mani's review tag
>     Change from v7 to v8
>     - Update commit message
>     - Using Fixme
>     - Update clks_cnts by ARRAY_SIZE
>     
>     Change from v4 to v7
>     - none
>     Change from v3 to v4
>     - change align to 4k for imx95
>     Change from v1 to v3
>     - new patches at v3
> 
>  drivers/pci/controller/dwc/pci-imx6.c | 47 +++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index bbaa45c08323b..7889318f6555a 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -75,6 +75,7 @@ enum imx6_pcie_variants {
>  	IMX8MQ_EP,
>  	IMX8MM_EP,
>  	IMX8MP_EP,
> +	IMX95_EP,
>  };
>  
>  #define IMX6_PCIE_FLAG_IMX6_PHY			BIT(0)
> @@ -84,6 +85,7 @@ enum imx6_pcie_variants {
>  #define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
>  #define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
>  #define IMX6_PCIE_FLAG_HAS_SERDES		BIT(6)
> +#define IMX6_PCIE_FLAG_SUPPORT_64BIT		BIT(7)
>  
>  #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
>  
> @@ -616,6 +618,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
>  		break;
>  	case IMX7D:
>  	case IMX95:
> +	case IMX95_EP:
>  		break;
>  	case IMX8MM:
>  	case IMX8MM_EP:
> @@ -1050,6 +1053,23 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
>  	.align = SZ_64K,
>  };
>  
> +/*
> + * BAR#	| Default BAR enable	| Default BAR Type	| Default BAR Size	| BAR Sizing Scheme
> + * ================================================================================================
> + * BAR0	| Enable		| 64-bit		| 1 MB			| Programmable Size
> + * BAR1	| Disable		| 32-bit		| 64 KB			| Fixed Size
> + *        BAR1 should be disabled if BAR0 is 64bit.
> + * BAR2	| Enable		| 32-bit		| 1 MB			| Programmable Size
> + * BAR3	| Enable		| 32-bit		| 64 KB			| Programmable Size
> + * BAR4	| Enable		| 32-bit		| 1M			| Programmable Size
> + * BAR5	| Enable		| 32-bit		| 64 KB			| Programmable Size
> + */
> +static const struct pci_epc_features imx95_pcie_epc_features = {
> +	.msi_capable = true,
> +	.bar_fixed_size[1] = SZ_64K,
> +	.align = SZ_4K,
> +};
> +
>  static const struct pci_epc_features*
>  imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
>  {
> @@ -1092,6 +1112,15 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
>  
>  	pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset;
>  
> +	/*
> +	 * FIXME: Ideally, dbi2 base address should come from DT. But since only IMX95 is defining
> +	 * "dbi2" in DT, "dbi_base2" is set to NULL here for that platform alone so that the DWC
> +	 * core code can fetch that from DT. But once all platform DTs were fixed, this and the
> +	 * above "dbi_base2" setting should be removed.
> +	 */
> +	if (imx6_pcie->drvdata->variant == IMX95_EP)
> +		pci->dbi_base2 = NULL;
> +
>  	ret = dw_pcie_ep_init(ep);
>  	if (ret) {
>  		dev_err(dev, "failed to initialize endpoint\n");
> @@ -1345,6 +1374,9 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>  					     "unable to find iomuxc registers\n");
>  	}
>  
> +	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_SUPPORT_64BIT))
> +		dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
> +
>  	/* Grab PCIe PHY Tx Settings */
>  	if (of_property_read_u32(node, "fsl,tx-deemph-gen1",
>  				 &imx6_pcie->tx_deemph_gen1))
> @@ -1563,6 +1595,20 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>  		.epc_features = &imx8m_pcie_epc_features,
>  	},
> +	[IMX95_EP] = {
> +		.variant = IMX95_EP,
> +		.flags = IMX6_PCIE_FLAG_HAS_SERDES |
> +			 IMX6_PCIE_FLAG_SUPPORT_64BIT,
> +		.clk_names = imx8mq_clks,
> +		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> +		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> +		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
> +		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
> +		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> +		.init_phy = imx95_pcie_init_phy,
> +		.epc_features = &imx95_pcie_epc_features,
> +		.mode = DW_PCIE_EP_TYPE,
> +	},
>  };
>  
>  static const struct of_device_id imx6_pcie_of_match[] = {
> @@ -1577,6 +1623,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
>  	{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
>  	{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
>  	{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
> +	{ .compatible = "fsl,imx95-pcie-ep", .data = &drvdata[IMX95_EP], },
>  	{},
>  };
>  
> -- 
> 2.34.1
> 


From jbrunet at baylibre.com  Tue Feb 13 02:36:28 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Tue, 13 Feb 2024 11:36:28 +0100
Subject: [PATCH] ASoC: meson: add helpers for clk_disable_unprepare
In-Reply-To: <20240213101220.459641-1-arnd@kernel.org>
References: <20240213101220.459641-1-arnd@kernel.org>
Message-ID: <1jbk8kk5pk.fsf@starbuckisacylon.baylibre.com>


On Tue 13 Feb 2024 at 11:11, Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> Casting between incompatible function types causes a warning with clang-16
> because it breaks control flow integrity (KCFI) rules:
>
> sound/soc/meson/aiu.c:243:12: error: cast from 'void (*)(struct clk *)' to
> 'void (*)(void *)' converts to incompatible function type
> [-Werror,-Wcast-function-type-strict]
>   243 |                                        (void(*)(void *))clk_disable_unprepare,
>       |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/device.h:406:34: note: expanded from macro 'devm_add_action_or_reset'
>   406 |         __devm_add_action_or_reset(dev, action, data, #action)
>       |                                         ^~~~~~
> sound/soc/meson/t9015.c:274:4: error: cast from 'void (*)(struct clk *)' to
> 'void (*)(void *)' converts to incompatible function type
> [-Werror,-Wcast-function-type-strict]
>   274 |                         (void(*)(void *))clk_disable_unprepare,
>       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/device.h:406:34: note: expanded from macro 'devm_add_action_or_reset'
>   406 |         __devm_add_action_or_reset(dev, action, data, #action)
>       |                                         ^~~~~~
>
> These two meson drivers cast clk_disable_unprepare() into a different type
> in order to have it automatically called from the driver relase. Add
> trivial helpers to do the same using correct types.
>
> Fixes: 33901f5b9b16 ("ASoC: meson: add t9015 internal DAC driver")
> Fixes: 6ae9ca9ce986 ("ASoC: meson: aiu: add i2s and spdif support")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> ---
>  sound/soc/meson/aiu.c   | 9 ++++++---
>  sound/soc/meson/t9015.c | 9 ++++++---
>  2 files changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c
> index 7109b81cc3d0..211f360df284 100644
> --- a/sound/soc/meson/aiu.c
> +++ b/sound/soc/meson/aiu.c
> @@ -209,6 +209,11 @@ static const char * const aiu_spdif_ids[] = {
>  	[MCLK]	= "spdif_mclk_sel"
>  };
>  
> +static void aiu_clk_disable(void *clk)
> +{
> +	clk_disable_unprepare(clk);
> +}
> +
>  static int aiu_clk_get(struct device *dev)
>  {
>  	struct aiu *aiu = dev_get_drvdata(dev);
> @@ -239,9 +244,7 @@ static int aiu_clk_get(struct device *dev)
>  		return ret;
>  	}
>  
> -	ret = devm_add_action_or_reset(dev,
> -				       (void(*)(void *))clk_disable_unprepare,
> -				       aiu->pclk);
> +	ret = devm_add_action_or_reset(dev, aiu_clk_disable, aiu->pclk);

Hi Arnd,

This probably pre-dates the introduction of devm_clk_get_enabled()
It would probably be better to use that instead of duplicating helper
functions which do the same thing.

If for any reason it is not possible, a common helper in clk.h would
preferable I think.

>  	if (ret)
>  		dev_err(dev, "failed to add reset action on pclk");
>  
> diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c
> index 9c6b4dac6893..e0f9a603a5e9 100644
> --- a/sound/soc/meson/t9015.c
> +++ b/sound/soc/meson/t9015.c
> @@ -243,6 +243,11 @@ static const struct regmap_config t9015_regmap_config = {
>  	.max_register		= POWER_CFG,
>  };
>  
> +static void t9015_clk_disable(void *clk)
> +{
> +	clk_disable_unprepare(clk);
> +}
> +
>  static int t9015_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -270,9 +275,7 @@ static int t9015_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> -	ret = devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			priv->pclk);
> +	ret = devm_add_action_or_reset(dev, t9015_clk_disable, priv->pclk);
>  	if (ret)
>  		return ret;


-- 
Jerome


From arnd at arndb.de  Tue Feb 13 02:45:21 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 13 Feb 2024 11:45:21 +0100
Subject: [PATCH v7 08/10] coresight-tpdm: Add timestamp control register support
 for the CMB
In-Reply-To: <20240213102239.2229731-1-suzuki.poulose@arm.com>
References: <7723c9f1-fda7-4dc9-bb5a-e12d4908becf@app.fastmail.com>
 <20240213102239.2229731-1-suzuki.poulose@arm.com>
Message-ID: <f95cf482-0ef8-43b5-81e0-f1901d8f85d5@app.fastmail.com>

On Tue, Feb 13, 2024, at 11:22, Suzuki K Poulose wrote:

> coresight: tpdm: Fix build break due to uninitialised field
>
> {CMB/DSB}_PATT_ENABLE_TS attributes do not use an index field.
> But some compilers complain for uninitialised "index" field in
> the struct tpdm_dataset_attribute:
>
...
>
> Reported-by: Arnd Bergmann <arnd at arndb.de>
> Cc: Tao Zhang <quic_taozha at quicinc.com>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>

Works fine here with this, thanks for the fix!

Acked-by: Arnd Bergmann <arnd at arndb.de>

I had actually missed that this is a warning option that
is normally disabled even at W=1 level, but it does get
added by drivers/hwtracing/coresight/Makefile setting
-Wextra again because that comes after the
-Wno-missing-field-initializers from scripts/Makefile.extrawarn.

    Arnd


From quic_riteshk at quicinc.com  Tue Feb 13 02:47:52 2024
From: quic_riteshk at quicinc.com (Ritesh Kumar)
Date: Tue, 13 Feb 2024 16:17:52 +0530
Subject: [PATCH v2 0/2] add display and panel on qcm6490 idp
Message-ID: <20240213104754.8195-1-quic_riteshk@quicinc.com>

Build the Novatek NT36672E DSI Panel driver as module and enable
display subsystem on Qualcomm qcm6490 idp board.

---
This series depends on following series:
1. https://lore.kernel.org/all/20231222073135.2512313-1-quic_uchheda at quicinc.com/
   (arm64: dts: qcom: qcm6490-idp: Add support for PM7250B PMIC)
2. https://lore.kernel.org/all/20240108095902.22725-1-quic_riteshk at quicinc.com/
   (Add support for Novatek NT36672E LCD DSI panel)
3. https://lore.kernel.org/all/20240116071803.5264-1-quic_riteshk at quicinc.com/t/#u
   (drm/panel: novatek-nt36672e: Include <linux/of.h>)

v2: Fixed review comments from Dmitry and Konrad
      - moved pinctrl-names after pinctrl-0 property.
      - removed gpu disablement change after validating gpu.
      - updated commit text.
    Rebased the patch
      - rebased the patch to resolve conflicts.
---

Ritesh Kumar (2):
  arm64: defconfig: enable Novatek NT36672E DSI Panel driver
  arm64: dts: qcom: qcm6490-idp: add display and panel

 arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 92 ++++++++++++++++++++++++
 arch/arm64/configs/defconfig             |  1 +
 2 files changed, 93 insertions(+)

-- 
2.17.1



From quic_riteshk at quicinc.com  Tue Feb 13 02:47:53 2024
From: quic_riteshk at quicinc.com (Ritesh Kumar)
Date: Tue, 13 Feb 2024 16:17:53 +0530
Subject: [PATCH v2 1/2] arm64: defconfig: enable Novatek NT36672E DSI Panel driver
In-Reply-To: <20240213104754.8195-1-quic_riteshk@quicinc.com>
References: <20240213104754.8195-1-quic_riteshk@quicinc.com>
Message-ID: <20240213104754.8195-2-quic_riteshk@quicinc.com>

Build the Novatek NT36672E DSI Panel driver as module
because it is used on Qualcomm qcm6490 idp board.

Signed-off-by: Ritesh Kumar <quic_riteshk at quicinc.com>

---
v2: Fixed review comment from Dmitry
      - updated commit text.
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f44b3abf3cef..9bd5bfe386fa 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -862,6 +862,7 @@ CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_PANEL_EDP=m
 CONFIG_DRM_PANEL_ILITEK_ILI9882T=m
 CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
+CONFIG_DRM_PANEL_NOVATEK_NT36672E=m
 CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
 CONFIG_DRM_PANEL_SITRONIX_ST7703=m
 CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
-- 
2.17.1



From quic_riteshk at quicinc.com  Tue Feb 13 02:47:54 2024
From: quic_riteshk at quicinc.com (Ritesh Kumar)
Date: Tue, 13 Feb 2024 16:17:54 +0530
Subject: [PATCH v2 2/2] arm64: dts: qcom: qcm6490-idp: add display and panel
In-Reply-To: <20240213104754.8195-1-quic_riteshk@quicinc.com>
References: <20240213104754.8195-1-quic_riteshk@quicinc.com>
Message-ID: <20240213104754.8195-3-quic_riteshk@quicinc.com>

Enable Display Subsystem with Novatek NT36672E Panel
on qcm6490 idp platform.

Signed-off-by: Ritesh Kumar <quic_riteshk at quicinc.com>

---
v2: Fixed review comments from Dmitry and Konrad
      - moved pinctrl-names after pinctrl-0 property.
      - removed gpu disablement change after validating gpu.
    Rebased the patch
      - rebased the patch to resolve conflicts.
---
 arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 92 ++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
index 502a5a383bde..0054b2a8d6c7 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
+++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
@@ -10,6 +10,7 @@
 #define PM7250B_SID1 9
 
 #include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 #include "sc7280.dtsi"
 #include "pm7250b.dtsi"
@@ -39,6 +40,25 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	lcd_disp_bias: lcd-disp-bias-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "lcd_disp_bias";
+		regulator-min-microvolt = <5500000>;
+		regulator-max-microvolt = <5500000>;
+		gpio = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		pinctrl-0 = <&lcd_disp_bias_en>;
+		pinctrl-names = "default";
+	};
+
+	pm8350c_pwm_backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pm8350c_pwm 3 65535>;
+		enable-gpios = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&pmic_lcd_bl_en>;
+		pinctrl-names = "default";
+	};
+
 	reserved-memory {
 		xbl_mem: xbl at 80700000 {
 			reg = <0x0 0x80700000 0x0 0x100000>;
@@ -421,7 +441,79 @@
 	};
 };
 
+&mdss {
+	status = "okay";
+};
+
+&mdss_dsi {
+	vdda-supply = <&vreg_l6b_1p2>;
+	status = "okay";
+
+	panel at 0 {
+		compatible = "novatek,nt36672e";
+		reg = <0>;
+
+		reset-gpios = <&tlmm 44 GPIO_ACTIVE_HIGH>;
+
+		vddi-supply = <&vreg_l8c_1p62>;
+		avdd-supply = <&lcd_disp_bias>;
+		avee-supply = <&lcd_disp_bias>;
+
+		backlight = <&pm8350c_pwm_backlight>;
+
+		port {
+			panel0_in: endpoint {
+				remote-endpoint = <&mdss_dsi0_out>;
+			};
+		};
+	};
+};
+
+&mdss_dsi0_out {
+	remote-endpoint = <&panel0_in>;
+	data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi_phy {
+	vdds-supply = <&vreg_l10c_0p88>;
+	status = "okay";
+};
+
+&pm7250b_gpios {
+	lcd_disp_bias_en: lcd-disp-bias-en-state {
+		pins = "gpio2";
+		function = "func1";
+		bias-disable;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+		input-disable;
+		output-enable;
+		power-source = <0>;
+	};
+};
+
+&pm8350c_gpios {
+	pmic_lcd_bl_en: pmic-lcd-bl-en-state {
+		pins = "gpio7";
+		function = "normal";
+		bias-disable;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+		output-low;
+		power-source = <0>;
+	};
+
+	pmic_lcd_bl_pwm: pmic-lcd-bl-pwm-state {
+		pins = "gpio8";
+		function = "func1";
+		bias-disable;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+		output-low;
+		power-source = <0>;
+	};
+};
+
 &pm8350c_pwm {
+	pinctrl-0 = <&pmic_lcd_bl_pwm>;
+	pinctrl-names = "default";
 	status = "okay";
 
 	multi-led {
-- 
2.17.1



From arnd at arndb.de  Tue Feb 13 02:52:50 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 13 Feb 2024 11:52:50 +0100
Subject: [PATCH] ASoC: meson: add helpers for clk_disable_unprepare
In-Reply-To: <1jbk8kk5pk.fsf@starbuckisacylon.baylibre.com>
References: <20240213101220.459641-1-arnd@kernel.org>
 <1jbk8kk5pk.fsf@starbuckisacylon.baylibre.com>
Message-ID: <c61d7daf-1b13-4ff8-aeae-7dcd8dd02131@app.fastmail.com>

On Tue, Feb 13, 2024, at 11:36, Jerome Brunet wrote:
> On Tue 13 Feb 2024 at 11:11, Arnd Bergmann <arnd at kernel.org> wrote:

> This probably pre-dates the introduction of devm_clk_get_enabled()
> It would probably be better to use that instead of duplicating helper
> functions which do the same thing.

Ah, I had not thought of that interface either, so you are probably
right that this is the best way to do it.
Can you send a replacement patch then and add my Reported-by?

I also sent the same patch for drivers/nvmem/meson-efuse.c, which
I guess will also need the same treatment. I also checked and saw
that all three files already had this code in linux-6.0 when
devm_clk_get_enabled() got added.

> If for any reason it is not possible, a common helper in clk.h would
> preferable I think.

I can't think of anything that prevents us from using
devm_clk_get_enabled() here.

    Arnd


From dmitry.baryshkov at linaro.org  Tue Feb 13 02:53:55 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 13 Feb 2024 12:53:55 +0200
Subject: [PATCH v2 2/2] arm64: dts: qcom: qcm6490-idp: add display and panel
In-Reply-To: <20240213104754.8195-3-quic_riteshk@quicinc.com>
References: <20240213104754.8195-1-quic_riteshk@quicinc.com> <20240213104754.8195-3-quic_riteshk@quicinc.com>
Message-ID: <CAA8EJprztE0Cwc=+vxxXk=wKmyMU_TCtLPcY29RHO4-+nWFQEw@mail.gmail.com>

On Tue, 13 Feb 2024 at 12:48, Ritesh Kumar <quic_riteshk at quicinc.com> wrote:
>
> Enable Display Subsystem with Novatek NT36672E Panel
> on qcm6490 idp platform.
>
> Signed-off-by: Ritesh Kumar <quic_riteshk at quicinc.com>
>
> ---
> v2: Fixed review comments from Dmitry and Konrad
>       - moved pinctrl-names after pinctrl-0 property.
>       - removed gpu disablement change after validating gpu.
>     Rebased the patch
>       - rebased the patch to resolve conflicts.
> ---
>  arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 92 ++++++++++++++++++++++++
>  1 file changed, 92 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
> index 502a5a383bde..0054b2a8d6c7 100644
> --- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
> +++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
> @@ -10,6 +10,7 @@
>  #define PM7250B_SID1 9
>
>  #include <dt-bindings/leds/common.h>
> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
>  #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
>  #include "sc7280.dtsi"
>  #include "pm7250b.dtsi"
> @@ -39,6 +40,25 @@
>                 stdout-path = "serial0:115200n8";
>         };
>
> +       lcd_disp_bias: lcd-disp-bias-regulator {

regualtor-lcd-disp-bias, please. This will allow grouping regulators together.

> +               compatible = "regulator-fixed";
> +               regulator-name = "lcd_disp_bias";
> +               regulator-min-microvolt = <5500000>;
> +               regulator-max-microvolt = <5500000>;
> +               gpio = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
> +               enable-active-high;
> +               pinctrl-0 = <&lcd_disp_bias_en>;
> +               pinctrl-names = "default";
> +       };
> +
> +       pm8350c_pwm_backlight: backlight {

This node isn't in the sort order.

> +               compatible = "pwm-backlight";
> +               pwms = <&pm8350c_pwm 3 65535>;
> +               enable-gpios = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
> +               pinctrl-0 = <&pmic_lcd_bl_en>;
> +               pinctrl-names = "default";
> +       };
> +
>         reserved-memory {
>                 xbl_mem: xbl at 80700000 {
>                         reg = <0x0 0x80700000 0x0 0x100000>;
> @@ -421,7 +441,79 @@
>         };
>  };
>
> +&mdss {
> +       status = "okay";
> +};
> +
> +&mdss_dsi {
> +       vdda-supply = <&vreg_l6b_1p2>;
> +       status = "okay";
> +
> +       panel at 0 {
> +               compatible = "novatek,nt36672e";
> +               reg = <0>;
> +
> +               reset-gpios = <&tlmm 44 GPIO_ACTIVE_HIGH>;
> +
> +               vddi-supply = <&vreg_l8c_1p62>;
> +               avdd-supply = <&lcd_disp_bias>;
> +               avee-supply = <&lcd_disp_bias>;
> +
> +               backlight = <&pm8350c_pwm_backlight>;
> +
> +               port {
> +                       panel0_in: endpoint {
> +                               remote-endpoint = <&mdss_dsi0_out>;
> +                       };
> +               };
> +       };
> +};
> +
> +&mdss_dsi0_out {
> +       remote-endpoint = <&panel0_in>;
> +       data-lanes = <0 1 2 3>;
> +};
> +
> +&mdss_dsi_phy {
> +       vdds-supply = <&vreg_l10c_0p88>;
> +       status = "okay";
> +};
> +
> +&pm7250b_gpios {
> +       lcd_disp_bias_en: lcd-disp-bias-en-state {
> +               pins = "gpio2";
> +               function = "func1";
> +               bias-disable;
> +               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
> +               input-disable;
> +               output-enable;
> +               power-source = <0>;
> +       };
> +};
> +
> +&pm8350c_gpios {
> +       pmic_lcd_bl_en: pmic-lcd-bl-en-state {
> +               pins = "gpio7";
> +               function = "normal";
> +               bias-disable;
> +               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
> +               output-low;
> +               power-source = <0>;
> +       };
> +
> +       pmic_lcd_bl_pwm: pmic-lcd-bl-pwm-state {
> +               pins = "gpio8";
> +               function = "func1";
> +               bias-disable;
> +               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
> +               output-low;
> +               power-source = <0>;
> +       };
> +};
> +
>  &pm8350c_pwm {
> +       pinctrl-0 = <&pmic_lcd_bl_pwm>;
> +       pinctrl-names = "default";
>         status = "okay";
>
>         multi-led {
> --
> 2.17.1
>


-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Tue Feb 13 02:54:24 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 13 Feb 2024 12:54:24 +0200
Subject: [PATCH v2 1/2] arm64: defconfig: enable Novatek NT36672E DSI
 Panel driver
In-Reply-To: <20240213104754.8195-2-quic_riteshk@quicinc.com>
References: <20240213104754.8195-1-quic_riteshk@quicinc.com> <20240213104754.8195-2-quic_riteshk@quicinc.com>
Message-ID: <CAA8EJpq0AnPgcP_zWw2hOYKeZ7uvuf9f=Z6=af5H4BCE7TC-Dg@mail.gmail.com>

On Tue, 13 Feb 2024 at 12:48, Ritesh Kumar <quic_riteshk at quicinc.com> wrote:
>
> Build the Novatek NT36672E DSI Panel driver as module
> because it is used on Qualcomm qcm6490 idp board.
>
> Signed-off-by: Ritesh Kumar <quic_riteshk at quicinc.com>

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

>
> ---
> v2: Fixed review comment from Dmitry
>       - updated commit text.
> ---
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)


-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Tue Feb 13 02:55:38 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 13 Feb 2024 12:55:38 +0200
Subject: [PATCH v2 5/5] iommu/arm-smmu: Convert to domain_alloc_paging()
In-Reply-To: <6511a289-fee6-4d08-9e01-695bd38d4ad6@arm.com>
References: <5-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com>
 <20240209200538.917366-1-dmitry.baryshkov@linaro.org> <20240209222349.GA923780@nvidia.com>
 <CAA8EJpp1wuMgawaUPnQWnhz1k023n8Q-k0_sO6P9p7ixntrCJQ@mail.gmail.com> <6511a289-fee6-4d08-9e01-695bd38d4ad6@arm.com>
Message-ID: <CAA8EJpqtUnGXMPQO4F0JXQDv0oJKFYjuhf4hSBe2tY1ebWFjRA@mail.gmail.com>

On Tue, 13 Feb 2024 at 12:20, Robin Murphy <robin.murphy at arm.com> wrote:
>
> On 2024-02-13 7:51 am, Dmitry Baryshkov wrote:
> > On Sat, 10 Feb 2024 at 00:23, Jason Gunthorpe <jgg at nvidia.com> wrote:
> >>
> >> On Fri, Feb 09, 2024 at 10:05:38PM +0200, Dmitry Baryshkov wrote:
> >>> On Tue, 17 Oct 2023 Jason Gunthorpe <jgg at nvidia.com> wrote:
> >>>> Now that the BLOCKED and IDENTITY behaviors are managed with their own
> >>>> domains change to the domain_alloc_paging() op.
> >>>>
> >>>> The check for using_legacy_binding is now redundant,
> >>>> arm_smmu_def_domain_type() always returns IOMMU_DOMAIN_IDENTITY for this
> >>>> mode, so the core code will never attempt to create a DMA domain in the
> >>>> first place.
> >>>>
> >>>> Since commit a4fdd9762272 ("iommu: Use flush queue capability") the core
> >>>> code only passes in IDENTITY/BLOCKED/UNMANAGED/DMA domain types. It will
> >>>> not pass in IDENTITY or BLOCKED if the global statics exist, so the test
> >>>> for DMA is also redundant now too.
> >>>>
> >>>> Call arm_smmu_init_domain_context() early if a dev is available.
> >>>>
> >>>> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> >>>> ---
> >>>>   drivers/iommu/arm/arm-smmu/arm-smmu.c | 21 +++++++++++++++------
> >>>>   1 file changed, 15 insertions(+), 6 deletions(-)
> >>>
> >>> For some reason this patch breaks booting of the APQ8096 Dragonboard820c
> >>> (qcom/apq8096-db820c.dts). Dispbling display subsystem (mdss) and venus
> >>> devices makes the board boot in most of the cases. Most frequently the
> >>> last parts of the log loog in a following way:
> >>
> >> It is surprising we tested this patch on some tegra systems with this
> >> iommu and didn't hit anything..
> >>
> >> The only real functional thing this changes is to move the domain
> >> initialization up in time, potentially a lot in time in some
> >> cases. That function does alot of things including touching HW so
> >> possibly there is some surprising interaction with something else.
> >
> > I should not be debugging strange platforms at 1 a.m. I forgot that
> > there was another patch to revert. So after reverting the MPM patch,
> > I'm getting the following results:
> >
> >>
> >> So, I would expect this to not WARN_ON and to make it work the same as
> >> before the patch:
> >
> > No warnings, the platform now boots up to the point of actually
> > bringing up the venus device:
> >
> >
> > [   11.906514] ath10k_pci 0000:01:00.0: qca6174 hw3.2 target
> > 0x05030000 chip_id 0x00340aff sub 0000:0000
> > [   11.907119] ath10k_pci 0000:01:00.0: kconfig debug 1 debugfs 0
> > tracing 0 dfs 0 testmode 0
> > [   11.915881] ath10k_pci 0000:01:00.0: firmware ver
> > WLAN.RM.4.4.1-00288- api 6 features wowlan,ignore-otp,mfp crc32
> > bf907c7c
> > [   11.979972] Console: switching to colour frame buffer device 320x90
> > [   11.990756] ath10k_pci 0000:01:00.0: board_file api 2 bmi_id 0:1
> > crc32 d2863f91
> > [   12.060834] msm_mdp 901000.display-controller: [drm] fb0: msmdrmfb
> > frame buffer device
> > [   12.096203] qcom-pcie 608000.pcie: Phy link never came up
> > [   12.103785] qcom-pcie 608000.pcie: PCI host bridge to bus 0001:00
> > [   12.103970] qcom-venus c00000.video-codec: Adding to iommu group 3
> >
> > Format: Log Type - Time(microsec) - Message - Optional Info
> > Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
> > S - QC_IMAGE_VERSION_STRING=BOOT.XF.1.0-00301
> > S - IMAGE_VARIANT_STRING=M8996LAB
> > S - OEM_IMAGE_VERSION_STRING=crm-ubuntu68
> > S - Boot Interface: UFS
> >
> >>
> >> Then I'd ask you to remove the comment and do:
> >>
> >> @@ -878,7 +878,9 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
> >>          if (dev) {
> >>                  struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> >>
> >> +               WARN_ON(true);
> >>                  if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> >> +                       printk("Allocation failure in arm_smmu_domain_alloc_paging()\n");
> >>                          kfree(smmu_domain);
> >>                          return NULL;
> >>                  }
> >>
> >>
> >> And then we may get a clue from the backtraces it generates. I only
> >> saw one iommu group reported in your log so I'd expect one trace?
> >
> > I added dev_info + mdelays() around the arm_smmu_init_domain_context()
> > and I can see that it crashes within that function.
>
> Yeah, this is totally broken. We can't just call the unmodified
> arm_smmu_init_domain_context() at domain allocation because half of what
> it's doing belongs to the attach operation. We should not be allocating
> context banks, IRQs, etc. for a not-yet-attached domain, and we
> certainly shouldn't be touching hardware there outside of RPM.

Should I send a revert?

>
> Thanks,
> Robin.



-- 
With best wishes
Dmitry


From lpieralisi at kernel.org  Tue Feb 13 02:57:55 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Tue, 13 Feb 2024 11:57:55 +0100
Subject: [PATCH v9 07/16] PCI: imx6: Simplify configure_type() by using
 mode_off and mode_mask
In-Reply-To: <20240119171122.3057511-8-Frank.Li@nxp.com>
References: <20240119171122.3057511-1-Frank.Li@nxp.com>
 <20240119171122.3057511-8-Frank.Li@nxp.com>
Message-ID: <ZctLM7xLf7L3CJrr@lpieralisi>

On Fri, Jan 19, 2024 at 12:11:13PM -0500, Frank Li wrote:
> Add drvdata::mode_off and drvdata::mode_mask to simplify
> imx6_pcie_configure_type() logic.
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> 
> Notes:
>     Chagne from v8 to v9
>     - add Manivannan's review tag
>     Change from v7 to v8
>     - replace simple with simplify
>     - remove reduntant comments about FILED_PREP
>     Change from v3 to v7
>     - none
>     Change from v2 to v3
>     - none
>     Change from v1 to v2
>     - use ffs() to fixe build error.
>     
>     Change from v2 to v3
>     - none
>     Change from v1 to v2
>     - use ffs() to fixe build error.
> 
>  drivers/pci/controller/dwc/pci-imx6.c | 59 ++++++++++++++++++---------
>  1 file changed, 39 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index d19fcb54fde0d..8df07b71c93e5 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -68,6 +68,7 @@ enum imx6_pcie_variants {
>  
>  #define IMX6_PCIE_MAX_CLKS       6
>  
> +#define IMX6_PCIE_MAX_INSTANCES			2
>  struct imx6_pcie_drvdata {
>  	enum imx6_pcie_variants variant;
>  	enum dw_pcie_device_mode mode;
> @@ -78,6 +79,8 @@ struct imx6_pcie_drvdata {
>  	const u32 clks_cnt;
>  	const u32 ltssm_off;
>  	const u32 ltssm_mask;
> +	const u32 mode_off[IMX6_PCIE_MAX_INSTANCES];
> +	const u32 mode_mask[IMX6_PCIE_MAX_INSTANCES];
>  };
>  
>  struct imx6_pcie {
> @@ -174,32 +177,24 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
>  
>  static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
>  {
> -	unsigned int mask, val, mode;
> +	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
> +	unsigned int mask, val, mode, id;
>  
> -	if (imx6_pcie->drvdata->mode == DW_PCIE_EP_TYPE)
> +	if (drvdata->mode == DW_PCIE_EP_TYPE)
>  		mode = PCI_EXP_TYPE_ENDPOINT;
>  	else
>  		mode = PCI_EXP_TYPE_ROOT_PORT;
>  
> -	switch (imx6_pcie->drvdata->variant) {
> -	case IMX8MQ:
> -	case IMX8MQ_EP:
> -		if (imx6_pcie->controller_id == 1) {
> -			mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE;
> -			val  = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
> -					  mode);
> -		} else {
> -			mask = IMX6Q_GPR12_DEVICE_TYPE;
> -			val  = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode);
> -		}
> -		break;
> -	default:
> -		mask = IMX6Q_GPR12_DEVICE_TYPE;
> -		val  = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode);
> -		break;
> -	}
> +	id = imx6_pcie->controller_id;
> +
> +	/* If mode_mask[id] is zero, means each controller have its individual gpr */
> +	if (!drvdata->mode_mask[id])
> +		id = 0;

I don't understand what this means. If the mode mask for id is == 0, we
are falling back to mode_mask and mode_off for controller ID 0 ? Is that
what this code is supposed to do ? If so the comment makes no sense to
me.

Lorenzo

> +
> +	mask = drvdata->mode_mask[id];
> +	val = mode << (ffs(mask) - 1);
>  
> -	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, mask, val);
> +	regmap_update_bits(imx6_pcie->iomuxc_gpr, drvdata->mode_off[id], mask, val);
>  }
>  
>  static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, bool exp_val)
> @@ -1385,6 +1380,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.clks_cnt = ARRAY_SIZE(imx6q_clks),
>  		.ltssm_off = IOMUXC_GPR12,
>  		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
> +		.mode_off[0] = IOMUXC_GPR12,
> +		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>  	},
>  	[IMX6SX] = {
>  		.variant = IMX6SX,
> @@ -1396,6 +1393,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.clks_cnt = ARRAY_SIZE(imx6sx_clks),
>  		.ltssm_off = IOMUXC_GPR12,
>  		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
> +		.mode_off[0] = IOMUXC_GPR12,
> +		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>  	},
>  	[IMX6QP] = {
>  		.variant = IMX6QP,
> @@ -1408,6 +1407,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.clks_cnt = ARRAY_SIZE(imx6q_clks),
>  		.ltssm_off = IOMUXC_GPR12,
>  		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
> +		.mode_off[0] = IOMUXC_GPR12,
> +		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>  	},
>  	[IMX7D] = {
>  		.variant = IMX7D,
> @@ -1417,6 +1418,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.gpr = "fsl,imx7d-iomuxc-gpr",
>  		.clk_names = imx6q_clks,
>  		.clks_cnt = ARRAY_SIZE(imx6q_clks),
> +		.mode_off[0] = IOMUXC_GPR12,
> +		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>  	},
>  	[IMX8MQ] = {
>  		.variant = IMX8MQ,
> @@ -1425,6 +1428,10 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.gpr = "fsl,imx8mq-iomuxc-gpr",
>  		.clk_names = imx8mq_clks,
>  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> +		.mode_off[0] = IOMUXC_GPR12,
> +		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
> +		.mode_off[1] = IOMUXC_GPR12,
> +		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
>  	},
>  	[IMX8MM] = {
>  		.variant = IMX8MM,
> @@ -1434,6 +1441,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.gpr = "fsl,imx8mm-iomuxc-gpr",
>  		.clk_names = imx8mm_clks,
>  		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
> +		.mode_off[0] = IOMUXC_GPR12,
> +		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>  	},
>  	[IMX8MP] = {
>  		.variant = IMX8MP,
> @@ -1443,6 +1452,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.gpr = "fsl,imx8mp-iomuxc-gpr",
>  		.clk_names = imx8mm_clks,
>  		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
> +		.mode_off[0] = IOMUXC_GPR12,
> +		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>  	},
>  	[IMX8MQ_EP] = {
>  		.variant = IMX8MQ_EP,
> @@ -1452,6 +1463,10 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.gpr = "fsl,imx8mq-iomuxc-gpr",
>  		.clk_names = imx8mq_clks,
>  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> +		.mode_off[0] = IOMUXC_GPR12,
> +		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
> +		.mode_off[1] = IOMUXC_GPR12,
> +		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
>  	},
>  	[IMX8MM_EP] = {
>  		.variant = IMX8MM_EP,
> @@ -1460,6 +1475,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.gpr = "fsl,imx8mm-iomuxc-gpr",
>  		.clk_names = imx8mm_clks,
>  		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
> +		.mode_off[0] = IOMUXC_GPR12,
> +		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>  	},
>  	[IMX8MP_EP] = {
>  		.variant = IMX8MP_EP,
> @@ -1468,6 +1485,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.gpr = "fsl,imx8mp-iomuxc-gpr",
>  		.clk_names = imx8mm_clks,
>  		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
> +		.mode_off[0] = IOMUXC_GPR12,
> +		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>  	},
>  };
>  
> -- 
> 2.34.1
> 


From mkl at pengutronix.de  Tue Feb 13 03:00:24 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 13 Feb 2024 12:00:24 +0100
Subject: [PATCH RESEND v7 0/3] can: xilinx_can: Add ECC feature support
In-Reply-To: <20240213-evasion-crevice-3faa375c1666-mkl@pengutronix.de>
References: <1705059453-29099-1-git-send-email-srinivas.goud@amd.com>
 <20240213-evasion-crevice-3faa375c1666-mkl@pengutronix.de>
Message-ID: <20240213-reactor-vertebrae-af419800fcdc-mkl@pengutronix.de>

On 13.02.2024 11:22:49, Marc Kleine-Budde wrote:
> On 12.01.2024 17:07:30, Srinivas Goud wrote:
> > Add ECC feature support to Tx and Rx FIFOs for Xilinx CAN Controller.
> > ECC is an IP configuration option where counter registers are added in
> > IP for 1bit/2bit ECC errors count and reset.
> > Also driver reports 1bit/2bit ECC errors for FIFOs based on ECC error
> > interrupts.
> > 
> > Add xlnx,has-ecc optional property for Xilinx AXI CAN controller
> > to support ECC if the ECC block is enabled in the HW.
> > 
> > Add ethtool stats interface for getting all the ECC errors information.
> > 
> > There is no public documentation for it available.
> 
> Lately I was using ethtool based stats, too and figured out, there's no
> need for a spinlock, you can use a struct u64_stats_sync,
> u64_stats_update_begin(), u64_stats_update_end(), and
> u64_stats_fetch_retry() instead. These are no-ops on 64 bit systems and
> sequential locks on 32 bit systems.
> 
> I'll send a v8.

https://lore.kernel.org/all/20240213-xilinx_ecc-v8-0-8d75f8b80771 at pengutronix.de/

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
-------------- 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/20240213/fe101ce4/attachment.sig>

From suzuki.poulose at arm.com  Tue Feb 13 03:01:12 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 13 Feb 2024 11:01:12 +0000
Subject: [PATCH v7 08/10] coresight-tpdm: Add timestamp control register
 support for the CMB
In-Reply-To: <f95cf482-0ef8-43b5-81e0-f1901d8f85d5@app.fastmail.com>
References: <7723c9f1-fda7-4dc9-bb5a-e12d4908becf@app.fastmail.com>
 <20240213102239.2229731-1-suzuki.poulose@arm.com>
 <f95cf482-0ef8-43b5-81e0-f1901d8f85d5@app.fastmail.com>
Message-ID: <a5a51333-ba84-4725-9dc2-a6689aad36fc@arm.com>

On 13/02/2024 10:45, Arnd Bergmann wrote:
> On Tue, Feb 13, 2024, at 11:22, Suzuki K Poulose wrote:
> 
>> coresight: tpdm: Fix build break due to uninitialised field
>>
>> {CMB/DSB}_PATT_ENABLE_TS attributes do not use an index field.
>> But some compilers complain for uninitialised "index" field in
>> the struct tpdm_dataset_attribute:
>>
> ...
>>
>> Reported-by: Arnd Bergmann <arnd at arndb.de>
>> Cc: Tao Zhang <quic_taozha at quicinc.com>
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> 
> Works fine here with this, thanks for the fix!
> 
> Acked-by: Arnd Bergmann <arnd at arndb.de>
> 
> I had actually missed that this is a warning option that
> is normally disabled even at W=1 level, but it does get
> added by drivers/hwtracing/coresight/Makefile setting
> -Wextra again because that comes after the
> -Wno-missing-field-initializers from scripts/Makefile.extrawarn.
> 
>      Arnd


Thanks, I will queue this.

Suzuki


From suzuki.poulose at arm.com  Tue Feb 13 03:04:22 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 13 Feb 2024 11:04:22 +0000
Subject: [PATCH v7 08/10] coresight-tpdm: Add timestamp control register
 support for the CMB
In-Reply-To: <f95cf482-0ef8-43b5-81e0-f1901d8f85d5@app.fastmail.com>
References: <7723c9f1-fda7-4dc9-bb5a-e12d4908becf@app.fastmail.com>
 <20240213102239.2229731-1-suzuki.poulose@arm.com>
 <f95cf482-0ef8-43b5-81e0-f1901d8f85d5@app.fastmail.com>
Message-ID: <f62c70b6-c674-462f-847f-e0d5f80e1442@arm.com>

On 13/02/2024 10:45, Arnd Bergmann wrote:
> On Tue, Feb 13, 2024, at 11:22, Suzuki K Poulose wrote:
> 
>> coresight: tpdm: Fix build break due to uninitialised field
>>
>> {CMB/DSB}_PATT_ENABLE_TS attributes do not use an index field.
>> But some compilers complain for uninitialised "index" field in
>> the struct tpdm_dataset_attribute:
>>
> ...
>>
>> Reported-by: Arnd Bergmann <arnd at arndb.de>
>> Cc: Tao Zhang <quic_taozha at quicinc.com>
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> 
> Works fine here with this, thanks for the fix!
> 
> Acked-by: Arnd Bergmann <arnd at arndb.de>
> 
> I had actually missed that this is a warning option that
> is normally disabled even at W=1 level, but it does get
> added by drivers/hwtracing/coresight/Makefile setting
> -Wextra again because that comes after the
> -Wno-missing-field-initializers from scripts/Makefile.extrawarn.
> 
>      Arnd


Thanks for verifying, I have queued this.

https://git.kernel.org/coresight/c/c099fdd218a0

Suzuki


From dmitry.baryshkov at linaro.org  Tue Feb 13 03:10:22 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 13 Feb 2024 13:10:22 +0200
Subject: [PATCH v1 08/10] iommu/arm-smmu-qcom: Merge table from
 arm-smmu-qcom-debug into match data
In-Reply-To: <a61a3561-0dde-472b-b8a5-451703f6d8ee@quicinc.com>
References: <20221114170635.1406534-9-dmitry.baryshkov@linaro.org> <a61a3561-0dde-472b-b8a5-451703f6d8ee@quicinc.com>
Message-ID: <CAA8EJpoJUZDUxpA1+LJTEVRaMQJrpZ7iU9_dZ3uQvzPKE_UUfg@mail.gmail.com>

On Tue, 13 Feb 2024 at 12:29, Pratyush Brahma <quic_pbrahma at quicinc.com> wrote:
>
> Hi
>
> Patch [1] introduces a use after free bug in the function
> "qcom_smmu_create()" in file: drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> wherein devm_krealloc() frees the old pointer marked by "smmu" but it is
> still being accessed later in qcom_smmu_impl_data() in the same function
> as:
>
> qsmmu->cfg = qcom_smmu_impl_data(smmu);
>
> The current patchset [2] implicitly fixes this issue as it doesn't
> access the freed ptr in the line:
>
> qsmmu->cfg = data->cfg;
>
> Hence, can this patchset[2] be propagated to branches where patchset[1]
> has been propagated already? The bug is currently present in all branches
> that have patchset[1] but do not have patchset[2].
>
> RFC:
>
> This bug would be reintroduced if patchset [3] is accepted. This makes
> the path prone to such errors as it relies on the
> developer's understanding on the internal implementation of devm_krealloc().

realloc is a basic function. Not understanding it is a significant
problem for the developer.

> Hence, a better fix IMO, would be to remove the confusion around the
> freed "smmu" ptr in the following way:

Could you please post a proper patch, which can be reviewed and
accepted or declined?

>
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 549ae4dba3a6..6dd142ce75d1 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -463,11 +463,12 @@ static struct arm_smmu_device
> *qcom_smmu_create(struct arm_smmu_device *smmu,
>          qsmmu = devm_krealloc(smmu->dev, smmu, sizeof(*qsmmu), GFP_KERNEL);
>          if (!qsmmu)
>                  return ERR_PTR(-ENOMEM);
> +       smmu = &qsmmu->smmu;
>
>          qsmmu->smmu.impl = impl;
>          qsmmu->cfg = data->cfg;
>
> -       return &qsmmu->smmu;
> +       return smmu;
>   }
>
> This is similar to the patch[4] which I've sent in-reply-to patch[3].
> Will send a formal patch if you think this approach is better.
>
> Please let me know your thoughts.

None of the other implementations does this. If you are going to fix
qcom implementation, please fix all implementations. However a better
option might be to change arm-smmu to remove devm_krealloc() usage at
all.



--
With best wishes
Dmitry


From maz at kernel.org  Tue Feb 13 03:12:34 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 13 Feb 2024 11:12:34 +0000
Subject: [RFC PATCH] KVM: arm64: Fix double-free following kvm_pgtable_stage2_free_unlinked()
In-Reply-To: <Zcp8LcvsZiZVkNKe@linux.dev>
References: <20240212193052.27765-1-will@kernel.org>
	<Zcp8LcvsZiZVkNKe@linux.dev>
Message-ID: <86cyt062jh.wl-maz@kernel.org>

On Mon, 12 Feb 2024 20:14:37 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Mon, Feb 12, 2024 at 07:30:52PM +0000, Will Deacon wrote:
> > kvm_pgtable_stage2_free_unlinked() does the final put_page() on the
> > root page of the sub-tree before returning, so remove the additional
> > put_page() invocations in the callers.
> > 
> > Cc: Marc Zyngier <maz at kernel.org>
> > Cc: Oliver Upton <oliver.upton at linux.dev>
> > Cc: Ricardo Koller <ricarkol at google.com>
> > Signed-off-by: Will Deacon <will at kernel.org>
> > ---
> > 
> > Hi folks,
> > 
> > Sending this as an RFC as I only spotted it from code inspection and I'm
> > surprised others aren't seeing fireworks if it's a genuine bug. I also
> > couldn't come up with a sensible Fixes tag, as all of:
> > 
> >  e7c05540c694b ("KVM: arm64: Add helper for creating unlinked stage2 subtrees")
> >  8f5a3eb7513fc ("KVM: arm64: Add kvm_pgtable_stage2_split()")
> >  f6a27d6dc51b2 ("KVM: arm64: Drop last page ref in kvm_pgtable_stage2_free_removed()")

I'd blame it on the last commit, as we really ought to have it if we
have the others.

> >
> > are actually ok in isolation. Hrm. Please tell me I'm wrong?
> > 
> >  arch/arm64/kvm/hyp/pgtable.c | 2 --
> >  1 file changed, 2 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> > index c651df904fe3..ab9d05fcf98b 100644
> > --- a/arch/arm64/kvm/hyp/pgtable.c
> > +++ b/arch/arm64/kvm/hyp/pgtable.c
> > @@ -1419,7 +1419,6 @@ kvm_pte_t *kvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt,
> >  				 level + 1);
> >  	if (ret) {
> >  		kvm_pgtable_stage2_free_unlinked(mm_ops, pgtable, level);
> > -		mm_ops->put_page(pgtable);
> >  		return ERR_PTR(ret);
> >  	}
> 
> AFAICT, this entire branch is effectively dead code, unless there's a
> KVM bug lurking behind the page table walk. The sub-tree isn't visible
> to other software or hardware walkers yet, so none of the PTE races
> could cause this to pop.
> 
> So while this is very obviously a bug, it might be pure luck that folks
> haven't seen smoke here. Perhaps while fixing the bug we should take the
> opportunity to promote the condition to WARN_ON_ONCE().

Can't you construct a case where an allocation fails during the walk
(memcache empty), and we end up on this exact path?

> 
> > @@ -1502,7 +1501,6 @@ static int stage2_split_walker(const struct kvm_pgtable_visit_ctx *ctx,
> >  
> >  	if (!stage2_try_break_pte(ctx, mmu)) {
> >  		kvm_pgtable_stage2_free_unlinked(mm_ops, childp, level);
> > -		mm_ops->put_page(childp);
> >  		return -EAGAIN;
> >  	}
> 
> This, on the other hand, seems possible. There exists a race where an
> old block PTE could have the AF set on it and the underlying cmpxchg()
> could fail. There shouldn't be a race with any software walkers, as we
> hold the MMU lock for write here.

AF update is indeed a likely candidate.

In any case, this patch looks good to me as it is, and we can always
have a separate tweak to adjust the severity of the first case as
required. Unless anyone objects, I'd like to queue it shortly.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From m.szyprowski at samsung.com  Tue Feb 13 03:14:37 2024
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Tue, 13 Feb 2024 12:14:37 +0100
Subject: [PATCH 2/2] arm64: cpufeatures: Only check for NV1 if NV is
 present
In-Reply-To: <20240212144736.1933112-3-maz@kernel.org>
References: <20240212144736.1933112-1-maz@kernel.org>
	<CGME20240212144758eucas1p1345ba6f2000c10a4b33f8575f0a8d22b@eucas1p1.samsung.com>
	<20240212144736.1933112-3-maz@kernel.org>
Message-ID: <5b2d8fee-9d0f-48f7-b9ec-b86e95387a61@samsung.com>

Hi

On 12.02.2024 15:47, Marc Zyngier wrote:
> We handle ID_AA64MMFR4_EL1.E2H0 being 0 as NV1 being present.
> However, this is only true if FEAT_NV is implemented.
>
> Add the required check to has_nv1(), avoiding spuriously advertising
> NV1 on HW that doesn't have NV at all.
>
> Fixes: da9af5071b25 ("arm64: cpufeature: Detect HCR_EL2.NV1 being RES0")
> Signed-off-by: Marc Zyngier <maz at kernel.org>

This patch in turn introduces the following warning during boot 
(observed on today's linux-next):

CPU: All CPU(s) started at EL2
CPU features: detected: 32-bit EL0 Support
CPU features: detected: 32-bit EL1 Support
CPU features: detected: CRC32 instructions
------------[ cut here ]------------
WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/cpufeature.c:3369 
this_cpu_has_cap+0x18/0x70
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc4-next-20240213 #8014
Hardware name: Khadas VIM3 (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : this_cpu_has_cap+0x18/0x70
lr : has_nv1+0x24/0xcc
...
Call trace:
 ?this_cpu_has_cap+0x18/0x70
 ?update_cpu_capabilities+0x50/0x134
 ?setup_system_features+0x30/0x120
 ?smp_cpus_done+0x48/0xb4
 ?smp_init+0x7c/0x8c
 ?kernel_init_freeable+0x18c/0x4e4
 ?kernel_init+0x20/0x1d8
 ?ret_from_fork+0x10/0x20
irq event stamp: 2846
hardirqs last? enabled at (2845): [<ffff80008012cf5c>] 
console_unlock+0x164/0x190
hardirqs last disabled at (2846): [<ffff80008123a078>] el1_dbg+0x24/0x8c
softirqs last? enabled at (2842): [<ffff800080010a60>] 
__do_softirq+0x4a0/0x4e8
softirqs last disabled at (2827): [<ffff8000800169b0>] 
____do_softirq+0x10/0x1c
---[ end trace 0000000000000000 ]---
alternatives: applying system-wide alternatives


> ---
>   arch/arm64/kernel/cpufeature.c | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 2f8958f27e9e..3421b684d340 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1812,8 +1812,9 @@ static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
>   		{}
>   	};
>   
> -	return !(has_cpuid_feature(entry, scope) ||
> -		 is_midr_in_range_list(read_cpuid_id(), nv1_ni_list));
> +	return (this_cpu_has_cap(ARM64_HAS_NESTED_VIRT) &&
> +		!(has_cpuid_feature(entry, scope) ||
> +		  is_midr_in_range_list(read_cpuid_id(), nv1_ni_list)));
>   }
>   
>   #if defined(ID_AA64MMFR0_EL1_TGRAN_LPA2) && defined(ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2)

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From will at kernel.org  Tue Feb 13 03:16:23 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 13 Feb 2024 11:16:23 +0000
Subject: [PATCH v2 5/5] iommu/arm-smmu: Convert to domain_alloc_paging()
In-Reply-To: <CAA8EJpqtUnGXMPQO4F0JXQDv0oJKFYjuhf4hSBe2tY1ebWFjRA@mail.gmail.com>
References: <5-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com>
 <20240209200538.917366-1-dmitry.baryshkov@linaro.org>
 <20240209222349.GA923780@nvidia.com>
 <CAA8EJpp1wuMgawaUPnQWnhz1k023n8Q-k0_sO6P9p7ixntrCJQ@mail.gmail.com>
 <6511a289-fee6-4d08-9e01-695bd38d4ad6@arm.com>
 <CAA8EJpqtUnGXMPQO4F0JXQDv0oJKFYjuhf4hSBe2tY1ebWFjRA@mail.gmail.com>
Message-ID: <20240213111623.GA28517@willie-the-truck>

On Tue, Feb 13, 2024 at 12:55:38PM +0200, Dmitry Baryshkov wrote:
> On Tue, 13 Feb 2024 at 12:20, Robin Murphy <robin.murphy at arm.com> wrote:
> > On 2024-02-13 7:51 am, Dmitry Baryshkov wrote:
> > > On Sat, 10 Feb 2024 at 00:23, Jason Gunthorpe <jgg at nvidia.com> wrote:
> > >> And then we may get a clue from the backtraces it generates. I only
> > >> saw one iommu group reported in your log so I'd expect one trace?
> > >
> > > I added dev_info + mdelays() around the arm_smmu_init_domain_context()
> > > and I can see that it crashes within that function.
> >
> > Yeah, this is totally broken. We can't just call the unmodified
> > arm_smmu_init_domain_context() at domain allocation because half of what
> > it's doing belongs to the attach operation. We should not be allocating
> > context banks, IRQs, etc. for a not-yet-attached domain, and we
> > certainly shouldn't be touching hardware there outside of RPM.
> 
> Should I send a revert?

If reverting the patch fixes the issue for you, then yes please!

Hopefully you can help Jason test a reworked verson for the future, as
it's evident that Tegra doesn't tickle the power management side of things
in the same way.

Will


From will at kernel.org  Tue Feb 13 03:20:15 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 13 Feb 2024 11:20:15 +0000
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240208142729.GH10476@nvidia.com>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
 <20240208125846.GA23290@willie-the-truck>
 <20240208142729.GH10476@nvidia.com>
Message-ID: <20240213112015.GB28517@willie-the-truck>

Hi Jason,

On Thu, Feb 08, 2024 at 10:27:29AM -0400, Jason Gunthorpe wrote:
> On Thu, Feb 08, 2024 at 12:58:47PM +0000, Will Deacon wrote:
> > On Fri, Feb 02, 2024 at 10:28:05AM -0400, Jason Gunthorpe wrote:
> > > If the SMMU is configured to use a two level CD table then
> > > arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
> > > GFP_KERNEL. Due to recent changes this is being done under a spinlock to
> > > iterate over the device list - thus it will trigger a sleeping while
> > > atomic warning:
> > > 
> > >   arm_smmu_sva_set_dev_pasid()
> > >     mutex_lock(&sva_lock);
> > >     __arm_smmu_sva_bind()
> > >      arm_smmu_mmu_notifier_get()
> > >       spin_lock_irqsave()
> > >       arm_smmu_write_ctx_desc()
> > > 	arm_smmu_get_cd_ptr()
> > >          arm_smmu_alloc_cd_leaf_table()
> > > 	  dmam_alloc_coherent(GFP_KERNEL)
> > > 
> > > This is a 64K high order allocation and really should not be done
> > > atomically.
> > > 
> > > The proper answer is to sequence CD programming in a way that does not
> > > require the device list or a spinlock. Part two of my lager series does
> > > this and already solves this bug.
> > > 
> > > In the mean time we can solve the functional issue by preallocating the CD
> > > entry outside any locking. CD leafs are effectively never freed so this
> > > guarantees the arm_smmu_write_ctx_desc() inside the lock will not take the
> > > allocation path.
> > > 
> > > Fixes: 24503148c545 ("iommu/arm-smmu-v3: Refactor write_ctx_desc")
> > > Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> > > Closes: https://lore.kernel.org/all/4e25d161-0cf8-4050-9aa3-dfa21cd63e56 at moroto.mountain/
> > > Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> > > ---
> > >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 5 +++++
> > >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c     | 2 +-
> > >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h     | 2 ++
> > >  3 files changed, 8 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> > > index 05722121f00e70..068d60732e6481 100644
> > > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> > > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> > > @@ -588,6 +588,11 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
> > >  {
> > >  	int ret = 0;
> > >  	struct mm_struct *mm = domain->mm;
> > > +	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> > > +
> > > +	/* Preallocate the required leafs outside locks */
> > > +	if (!arm_smmu_get_cd_ptr(master, id))
> > > +		return -ENOMEM;
> > 
> > What guarantees that all the masters in the domain share the same l2 CD
> > table?
> 
> Nothing, in fact they don't.
> 
> However, a multi-master RID domain is something that doesn't fully
> work with SVA today. This code is functionally/security wrong to
> install the PASID into all the masters that share the RID domain.
> 
> In practice that doesn't happen because the iommu group size when
> PASID is enabled is restricted to 1 and the DMA API is the thing that
> has created a unique per-group domain to be able to turn SVA on at
> all.
> 
> So, the RID domain's list has one master entry that is the same as the
> set_dev_pasid's master.
> 
> Which is why this patch works, it prealloctes the only master that
> matters for the only configuration where SVA works and is used today.
> 
> iommufd could violate these assumptions which is part of why I'm
> fixing all of this in preparation to enable PASID support for all
> drivers in iommufd.

Damn, all the surrounding rework has really left this poor code in a bit
of a state. Could you please respin your fix, but with an additional change
to arm_smmu_mmu_notifier_get() so that it returns an error if there is
more than one device in the domain, with some of the above in a comment?

Cheers,

Will


From francesco at dolcini.it  Tue Feb 13 03:21:46 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Tue, 13 Feb 2024 12:21:46 +0100
Subject: Regression, i.MX7 boot failure, Linux v6.1.77
Message-ID: <20240213112146.GA5874@francesco-nb>

Hello Sasha,
kernel v6.1.77 introduces a regression, with a boot failure, on i.MX7,
with commit db30f469ae8b ("ARM: dts: imx7s: Fix nand-controller #size-cells").

The issue is known [1][2], changing `#size-cells = <0>` is formally
correct, but do not play well with the firmware that are deployed on
those embedded devices, leading to a boot failure.

A mitigation was implemented in the Linux kernel,
commit 84549c816dc3 ("mtd: parsers: ofpart: add workaround for #size-cells 0")
that was merged into v6.3, the firmware was also fixed, however existing
device using old firmware will not boot anymore if updating to a newer
kernel.

I would ask you to drop such a patch from any stable patches queue and
not backport it to any older kernel.

To fix v6.1.y I see two options:
 - backport 84549c816dc3
 - revert db30f469ae8b

What do you prefer? Should I send myself a patch?

[1] https://lore.kernel.org/all/Y4dgBTGNWpM6SQXI at francesco-nb.int.toradex.com/
[2] https://lore.kernel.org/all/20221202071900.1143950-1-francesco at dolcini.it/

Francesco



From tony at atomide.com  Tue Feb 13 03:25:08 2024
From: tony at atomide.com (Tony Lindgren)
Date: Tue, 13 Feb 2024 13:25:08 +0200
Subject: [PATCH v5 1/1] arm64: dts: ti: k3-am62-wakeup: Configure ti-sysc for wkup_uart0
Message-ID: <20240213112510.6334-1-tony@atomide.com>

The devices in the wkup domain are capable of waking up the system from
suspend. We can configure the wkup domain devices in a generic way using
the ti-sysc interconnect target module driver like we have done with the
earlier TI SoCs.

As ti-sysc manages the SYSCONFIG related registers independent of the
child hardware device, the wake-up configuration is also set even if
wkup_uart0 is reserved by sysfw.

The wkup_uart0 device has interconnect target module register mapping like
dra7 wkup uart. There is a 1 MB interconnect target range with one uart IP
block in the target module. The power domain and clock affects the whole
interconnect target module.

Note we change the functional clock name to follow the ti-sysc binding
and use "fck" instead of "fclk".

Also note that we need to disable the target module reset as noted by
Markus. Otherwise the sysfw using wkup_uart0 can get confused on some
devices leading to boot time issues such as mbox timeouts.

Tested-by: Dhruva Gole <d-gole at ti.com>
Reviewed-by: Kevin Hilman <khilman at baylibre.com>
Tested-by: Markus Schneider-Pargmann <msp at baylibre.com>
Signed-off-by: Tony Lindgren <tony at atomide.com>
---
Changes since v4:

- Add ti,no-reset-on-init as noted by Markus

Changes since v3:

- Use the first reg for the target module node name to avoid a
  make W=1 dtbs warning as noted by Nishanth

Changes since v2:

- Fix node name for 8250 IP, it's at offset 0 from the target module

- Added Kevin's Reviewed-by from v2 as the node name change is mostly
  cosmetic

Changes since v1:

- Added Tested-by from Dhruva
---
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi | 34 ++++++++++++++++++----
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -5,6 +5,8 @@
  * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
  */
 
+#include <dt-bindings/bus/ti-sysc.h>
+
 &cbass_wakeup {
 	wkup_conf: syscon at 43000000 {
 		bootph-all;
@@ -21,14 +23,34 @@ chipid: chipid at 14 {
 		};
 	};
 
-	wkup_uart0: serial at 2b300000 {
-		compatible = "ti,am64-uart", "ti,am654-uart";
-		reg = <0x00 0x2b300000 0x00 0x100>;
-		interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+	target-module at 2b300050 {
+		compatible = "ti,sysc-omap2", "ti,sysc";
+		reg = <0 0x2b300050 0 0x4>,
+		      <0 0x2b300054 0 0x4>,
+		      <0 0x2b300058 0 0x4>;
+		reg-names = "rev", "sysc", "syss";
+		ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+				 SYSC_OMAP2_SOFTRESET |
+				 SYSC_OMAP2_AUTOIDLE)>;
+		ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+				<SYSC_IDLE_NO>,
+				<SYSC_IDLE_SMART>,
+				<SYSC_IDLE_SMART_WKUP>;
+		ti,syss-mask = <1>;
+		ti,no-reset-on-init;
 		power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 114 0>;
-		clock-names = "fclk";
-		status = "disabled";
+		clock-names = "fck";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0 0x2b300000 0x100000>;
+
+		wkup_uart0: serial at 0 {
+			compatible = "ti,am64-uart", "ti,am654-uart";
+			reg = <0 0x100>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
 	};
 
 	wkup_i2c0: i2c at 2b200000 {
-- 
2.43.1


From dmitry.baryshkov at linaro.org  Tue Feb 13 03:31:56 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 13 Feb 2024 13:31:56 +0200
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
Message-ID: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>

This reverts commit 9b3febc3a3da ("iommu/arm-smmu: Convert to
domain_alloc_paging()"). It breaks Qualcomm MSM8996 platform. Calling
arm_smmu_write_context_bank() from new codepath results in the platform
being reset because of the unclocked hardware access.

Fixes: 9b3febc3a3da ("iommu/arm-smmu: Convert to domain_alloc_paging()")
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 68b6bc5e7c71..6317aaf7b3ab 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -859,10 +859,14 @@ static void arm_smmu_destroy_domain_context(struct arm_smmu_domain *smmu_domain)
 	arm_smmu_rpm_put(smmu);
 }
 
-static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
+static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 {
 	struct arm_smmu_domain *smmu_domain;
 
+	if (type != IOMMU_DOMAIN_UNMANAGED) {
+		if (using_legacy_binding || type != IOMMU_DOMAIN_DMA)
+			return NULL;
+	}
 	/*
 	 * Allocate the domain and initialise some of its data structures.
 	 * We can't really do anything meaningful until we've added a
@@ -875,15 +879,6 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
 	mutex_init(&smmu_domain->init_mutex);
 	spin_lock_init(&smmu_domain->cb_lock);
 
-	if (dev) {
-		struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
-
-		if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
-			kfree(smmu_domain);
-			return NULL;
-		}
-	}
-
 	return &smmu_domain->domain;
 }
 
@@ -1600,7 +1595,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.identity_domain	= &arm_smmu_identity_domain,
 	.blocked_domain		= &arm_smmu_blocked_domain,
 	.capable		= arm_smmu_capable,
-	.domain_alloc_paging	= arm_smmu_domain_alloc_paging,
+	.domain_alloc		= arm_smmu_domain_alloc,
 	.probe_device		= arm_smmu_probe_device,
 	.release_device		= arm_smmu_release_device,
 	.probe_finalize		= arm_smmu_probe_finalize,

---
base-commit: 46d4e2eb58e14c8935fa0e27d16d4c62ef82849a
change-id: 20240213-iommu-revert-domain-alloc-fa729e537df5

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



From rogerq at kernel.org  Tue Feb 13 03:34:12 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 13 Feb 2024 13:34:12 +0200
Subject: [PATCH v1] arm64: dts: ti: k3-am62-main: disable usb lpm
In-Reply-To: <20240212125402.GA5043@francesco-nb>
References: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
 <2629cd30-23aa-4f03-8452-ae13297fd6b6@kernel.org>
 <20240212125402.GA5043@francesco-nb>
Message-ID: <4adb0a74-4789-4b9d-b970-1cd94602c27c@kernel.org>



On 12/02/2024 14:54, Francesco Dolcini wrote:
> Hello Roger,
> 
> On Mon, Feb 12, 2024 at 02:13:56PM +0200, Roger Quadros wrote:
>> On 09/02/2024 15:02, Andrejs Cainikovs wrote:
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>>> index 464b7565d085..c49fbce5cb70 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>>> @@ -663,6 +665,8 @@ usb1: usb at 31100000 {
>>>  			interrupt-names = "host", "peripheral";
>>>  			maximum-speed = "high-speed";
>>>  			dr_mode = "otg";
>>> +			snps,usb2-gadget-lpm-disable;
>>> +			snps,usb2-lpm-disable;
>>
>> Instead of this could you please check if this series fixes the issue for you?
>> https://lore.kernel.org/all/20240205141221.56076-1-rogerq at kernel.org/
> 
> Isn't this change correct despite whatever the test results on that
> change are going to be? The manual is pretty adamant on LPM not being
> supported by the AM62 SoC.
> 

You are right. We should have this in regardless.

-- 
cheers,
-roger


From robin.murphy at arm.com  Tue Feb 13 03:36:51 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 13 Feb 2024 11:36:51 +0000
Subject: [PATCH 1/1] iommu/arm-smmu-qcom: Fix use-after-free issue in
 qcom_smmu_create()
In-Reply-To: <ccb6b2a2-040b-46cc-9b72-2e4bd4c75565@quicinc.com>
References: <20240201210529.7728-4-quic_c_gdjako@quicinc.com>
 <20240213062608.13018-1-quic_pbrahma@quicinc.com>
 <CAA8EJpoh-m_fzt9WcUXOkTxVZRQMDf-WrgqqoM0C_-qzjgDm1w@mail.gmail.com>
 <ccb6b2a2-040b-46cc-9b72-2e4bd4c75565@quicinc.com>
Message-ID: <edfe34ca-06d4-46c8-81a2-f713ab74d769@arm.com>

On 2024-02-13 8:17 am, Pratyush Brahma wrote:
> 
> On 2/13/2024 1:36 PM, Dmitry Baryshkov wrote:
>> On Tue, 13 Feb 2024 at 08:27, Pratyush Brahma 
>> <quic_pbrahma at quicinc.com> wrote:
>>> Currently, during arm smmu probe, struct arm_smmu_device pointer
>>> is allocated. The pointer is reallocated to a new struct qcom_smmu in
>>> qcom_smmu_create() with devm_krealloc() which frees the smmu device
>>> after copying the data into the new pointer.
>>>
>>> The freed pointer is then passed again in devm_of_platform_populate()
>>> inside qcom_smmu_create() which causes a use-after-free issue.
>>>
>>> Fix the use-after-free issue by reassigning the old pointer to
>>> the new pointer where the struct was copied by devm_krealloc().
>>>
>>> Signed-off-by: Pratyush Brahma <quic_pbrahma at quicinc.com>
>> Missing Fixes tag.
> Haven't added as the patchset in-reply-to hasn't been merged to 
> linux-next. Please refer my next reply.
>>
>>> ---
>>> ? drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 3 ++-
>>> ? 1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
>>> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>> index ed5ed5da7740..49eaeed6a91c 100644
>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>>> @@ -710,6 +710,7 @@ static struct arm_smmu_device 
>>> *qcom_smmu_create(struct arm_smmu_device *smmu,
>>> ???????? qsmmu = devm_krealloc(smmu->dev, smmu, sizeof(*qsmmu), 
>>> GFP_KERNEL);
>>> ???????? if (!qsmmu)
>>> ???????????????? return ERR_PTR(-ENOMEM);
>>> +?????? smmu = &qsmmu->smmu;
>>>
>>> ???????? qsmmu->smmu.impl = impl;
>>> ???????? qsmmu->data = data;
>>> @@ -719,7 +720,7 @@ static struct arm_smmu_device 
>>> *qcom_smmu_create(struct arm_smmu_device *smmu,
>>> ???????? if (ret)
>>> ???????????????? return ERR_PTR(ret);
>> What is the tree that you have been developing this against? I don't
>> see this part of the code in the linux-next.
> This is in reply to the patchset at: 
> https://lore.kernel.org/all/20240201210529.7728-4-quic_c_gdjako at quicinc.com
> The aforementioned patchset introduces this bug. This is a suggested fix 
> to the bug.

Unless you are the 0-day bot, please just point out bugs in under-review 
patches via regular review comments rather than sending patches for 
unmerged patches.

There is nothing to fix in mainline, and as I commented on the binding 
patch I'm not sure I agree with the fundamental premise for touching 
qcom_smmu_create() in this series at all.

Thanks,
Robin.

>>> -?????? return &qsmmu->smmu;
>>> +?????? return smmu;
>>> ? }
>>>
>>> ? /* Implementation Defined Register Space 0 register offsets */
>>> -- 
>>> 2.17.1
>>>
>>>
> Thanks,
> Pratyush


From robin.murphy at arm.com  Tue Feb 13 03:38:08 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 13 Feb 2024 11:38:08 +0000
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
In-Reply-To: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
References: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
Message-ID: <02a590bd-6379-455a-8184-d631ae88e63a@arm.com>

On 2024-02-13 11:31 am, Dmitry Baryshkov wrote:
> This reverts commit 9b3febc3a3da ("iommu/arm-smmu: Convert to
> domain_alloc_paging()"). It breaks Qualcomm MSM8996 platform. Calling
> arm_smmu_write_context_bank() from new codepath results in the platform
> being reset because of the unclocked hardware access.

Acked-by: Robin Murphy <robin.murphy at arm.com>

> Fixes: 9b3febc3a3da ("iommu/arm-smmu: Convert to domain_alloc_paging()")
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>   drivers/iommu/arm/arm-smmu/arm-smmu.c | 17 ++++++-----------
>   1 file changed, 6 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index 68b6bc5e7c71..6317aaf7b3ab 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -859,10 +859,14 @@ static void arm_smmu_destroy_domain_context(struct arm_smmu_domain *smmu_domain)
>   	arm_smmu_rpm_put(smmu);
>   }
>   
> -static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
> +static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
>   {
>   	struct arm_smmu_domain *smmu_domain;
>   
> +	if (type != IOMMU_DOMAIN_UNMANAGED) {
> +		if (using_legacy_binding || type != IOMMU_DOMAIN_DMA)
> +			return NULL;
> +	}
>   	/*
>   	 * Allocate the domain and initialise some of its data structures.
>   	 * We can't really do anything meaningful until we've added a
> @@ -875,15 +879,6 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
>   	mutex_init(&smmu_domain->init_mutex);
>   	spin_lock_init(&smmu_domain->cb_lock);
>   
> -	if (dev) {
> -		struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> -
> -		if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> -			kfree(smmu_domain);
> -			return NULL;
> -		}
> -	}
> -
>   	return &smmu_domain->domain;
>   }
>   
> @@ -1600,7 +1595,7 @@ static struct iommu_ops arm_smmu_ops = {
>   	.identity_domain	= &arm_smmu_identity_domain,
>   	.blocked_domain		= &arm_smmu_blocked_domain,
>   	.capable		= arm_smmu_capable,
> -	.domain_alloc_paging	= arm_smmu_domain_alloc_paging,
> +	.domain_alloc		= arm_smmu_domain_alloc,
>   	.probe_device		= arm_smmu_probe_device,
>   	.release_device		= arm_smmu_release_device,
>   	.probe_finalize		= arm_smmu_probe_finalize,
> 
> ---
> base-commit: 46d4e2eb58e14c8935fa0e27d16d4c62ef82849a
> change-id: 20240213-iommu-revert-domain-alloc-fa729e537df5
> 
> Best regards,


From lpieralisi at kernel.org  Tue Feb 13 03:41:10 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Tue, 13 Feb 2024 12:41:10 +0100
Subject: [PATCH v10 03/14] PCI: imx6: Simplify reset handling by using by
 using *_FLAG_HAS_*_RESET
In-Reply-To: <20240205173335.1120469-4-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <20240205173335.1120469-4-Frank.Li@nxp.com>
Message-ID: <ZctVVjjHYVczweta@lpieralisi>

On Mon, Feb 05, 2024 at 12:33:24PM -0500, Frank Li wrote:
> Refactors the reset handling logic in the imx6 PCI driver by adding
> IMX6_PCIE_FLAG_HAS_*_RESET bitmask define for drvdata::flags.
> 
> The drvdata::flags and a bitmask ensures a cleaner and more scalable
> switch-case structure for handling reset.
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> 
> Notes:
>     Change from v4 to v5:
>     - Add Mani's Reviewed-by tag
>     - Fixed MQ_EP's flags
>     
>     Chagne from v3 to v4:
>     - none
>     Change from v2 to v3:
>     - add Philipp's Reviewed-by tag
>     Change from v1 to v2:
>     - remove condition check before reset_control_(de)assert() because it is
>       none ops if a NULL pointer pass down.
>     - still keep condition check at probe to help identify dts file mismatch
>       problem.
>     
>     Change from v1 to v2:
>     - remove condition check before reset_control_(de)assert() because it is
>       none ops if a NULL pointer pass down.
>     - still keep condition check at probe to help identify dts file mismatch
>       problem.
> 
>  drivers/pci/controller/dwc/pci-imx6.c | 105 ++++++++++----------------
>  1 file changed, 39 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 59f117f855c26..a1653b58051b7 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -61,6 +61,8 @@ enum imx6_pcie_variants {
>  #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
>  #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
>  #define IMX6_PCIE_FLAG_HAS_PHYDRV			BIT(3)
> +#define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
> +#define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
>  
>  #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
>  
> @@ -661,18 +663,10 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
>  
>  static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
>  {
> +	reset_control_assert(imx6_pcie->pciephy_reset);
> +	reset_control_assert(imx6_pcie->apps_reset);
> +
>  	switch (imx6_pcie->drvdata->variant) {
> -	case IMX7D:
> -	case IMX8MQ:
> -	case IMX8MQ_EP:
> -		reset_control_assert(imx6_pcie->pciephy_reset);
> -		fallthrough;
> -	case IMX8MM:
> -	case IMX8MM_EP:
> -	case IMX8MP:
> -	case IMX8MP_EP:
> -		reset_control_assert(imx6_pcie->apps_reset);
> -		break;
>  	case IMX6SX:
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
>  				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
> @@ -693,6 +687,8 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
>  				   IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
>  		break;
> +	default:
> +		break;
>  	}
>  
>  	/* Some boards don't have PCIe reset GPIO. */
> @@ -706,14 +702,10 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
>  	struct dw_pcie *pci = imx6_pcie->pci;
>  	struct device *dev = pci->dev;
>  
> +	reset_control_deassert(imx6_pcie->pciephy_reset);
> +
>  	switch (imx6_pcie->drvdata->variant) {
> -	case IMX8MQ:
> -	case IMX8MQ_EP:
> -		reset_control_deassert(imx6_pcie->pciephy_reset);
> -		break;
>  	case IMX7D:
> -		reset_control_deassert(imx6_pcie->pciephy_reset);
> -
>  		/* Workaround for ERR010728, failure of PCI-e PLL VCO to
>  		 * oscillate, especially when cold.  This turns off "Duty-cycle
>  		 * Corrector" and other mysterious undocumented things.
> @@ -745,11 +737,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
>  
>  		usleep_range(200, 500);
>  		break;
> -	case IMX6Q:		/* Nothing to do */
> -	case IMX8MM:
> -	case IMX8MM_EP:
> -	case IMX8MP:
> -	case IMX8MP_EP:
> +	default:
>  		break;
>  	}
>  
> @@ -796,16 +784,11 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
>  				   IMX6Q_GPR12_PCIE_CTL_2,
>  				   IMX6Q_GPR12_PCIE_CTL_2);
>  		break;
> -	case IMX7D:
> -	case IMX8MQ:
> -	case IMX8MQ_EP:
> -	case IMX8MM:
> -	case IMX8MM_EP:
> -	case IMX8MP:
> -	case IMX8MP_EP:
> -		reset_control_deassert(imx6_pcie->apps_reset);
> +	default:
>  		break;
>  	}
> +
> +	reset_control_deassert(imx6_pcie->apps_reset);

You rely on the fact that passing NULL is a no-op on platforms where
this wasn't called before (valid question for other hunks in this commit),
correct ?

Just checking, it does not make things much cleaner but I am not opposed to
this change.

Thanks,
Lorenzo

>  }
>  
>  static void imx6_pcie_ltssm_disable(struct device *dev)
> @@ -819,16 +802,11 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
>  				   IMX6Q_GPR12_PCIE_CTL_2, 0);
>  		break;
> -	case IMX7D:
> -	case IMX8MQ:
> -	case IMX8MQ_EP:
> -	case IMX8MM:
> -	case IMX8MM_EP:
> -	case IMX8MP:
> -	case IMX8MP_EP:
> -		reset_control_assert(imx6_pcie->apps_reset);
> +	default:
>  		break;
>  	}
> +
> +	reset_control_assert(imx6_pcie->apps_reset);
>  }
>  
>  static int imx6_pcie_start_link(struct dw_pcie *pci)
> @@ -1287,38 +1265,26 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>  					     "failed to get pcie phy\n");
>  	}
>  
> +	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_APP_RESET)) {
> +		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev, "apps");
> +		if (IS_ERR(imx6_pcie->apps_reset))
> +			return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
> +					     "failed to get pcie apps reset control\n");
> +	}
> +
> +	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_PHY_RESET)) {
> +		imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, "pciephy");
> +		if (IS_ERR(imx6_pcie->pciephy_reset))
> +			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pciephy_reset),
> +					     "Failed to get PCIEPHY reset control\n");
> +	}
> +
>  	switch (imx6_pcie->drvdata->variant) {
>  	case IMX8MQ:
>  	case IMX8MQ_EP:
>  	case IMX7D:
>  		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
>  			imx6_pcie->controller_id = 1;
> -
> -		imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev,
> -									    "pciephy");
> -		if (IS_ERR(imx6_pcie->pciephy_reset)) {
> -			dev_err(dev, "Failed to get PCIEPHY reset control\n");
> -			return PTR_ERR(imx6_pcie->pciephy_reset);
> -		}
> -
> -		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
> -									 "apps");
> -		if (IS_ERR(imx6_pcie->apps_reset)) {
> -			dev_err(dev, "Failed to get PCIE APPS reset control\n");
> -			return PTR_ERR(imx6_pcie->apps_reset);
> -		}
> -		break;
> -	case IMX8MM:
> -	case IMX8MM_EP:
> -	case IMX8MP:
> -	case IMX8MP_EP:
> -		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
> -									 "apps");
> -		if (IS_ERR(imx6_pcie->apps_reset))
> -			return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
> -					     "failed to get pcie apps reset control\n");
> -
> -		break;
>  	default:
>  		break;
>  	}
> @@ -1448,13 +1414,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  	},
>  	[IMX7D] = {
>  		.variant = IMX7D,
> -		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
> +		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
> +			 IMX6_PCIE_FLAG_HAS_APP_RESET |
> +			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
>  		.gpr = "fsl,imx7d-iomuxc-gpr",
>  		.clk_names = imx6q_clks,
>  		.clks_cnt = ARRAY_SIZE(imx6q_clks),
>  	},
>  	[IMX8MQ] = {
>  		.variant = IMX8MQ,
> +		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
> +			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
>  		.gpr = "fsl,imx8mq-iomuxc-gpr",
>  		.clk_names = imx8mq_clks,
>  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> @@ -1471,13 +1441,16 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  	[IMX8MP] = {
>  		.variant = IMX8MP,
>  		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
> -			 IMX6_PCIE_FLAG_HAS_PHYDRV,
> +			 IMX6_PCIE_FLAG_HAS_PHYDRV |
> +			 IMX6_PCIE_FLAG_HAS_APP_RESET,
>  		.gpr = "fsl,imx8mp-iomuxc-gpr",
>  		.clk_names = imx8mm_clks,
>  		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
>  	},
>  	[IMX8MQ_EP] = {
>  		.variant = IMX8MQ_EP,
> +		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
> +			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
>  		.mode = DW_PCIE_EP_TYPE,
>  		.gpr = "fsl,imx8mq-iomuxc-gpr",
>  		.clk_names = imx8mq_clks,
> -- 
> 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 jbrunet at baylibre.com  Tue Feb 13 03:09:52 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Tue, 13 Feb 2024 12:09:52 +0100
Subject: [PATCH] ASoC: meson: add helpers for clk_disable_unprepare
In-Reply-To: <c61d7daf-1b13-4ff8-aeae-7dcd8dd02131@app.fastmail.com>
References: <20240213101220.459641-1-arnd@kernel.org>
 <1jbk8kk5pk.fsf@starbuckisacylon.baylibre.com>
 <c61d7daf-1b13-4ff8-aeae-7dcd8dd02131@app.fastmail.com>
Message-ID: <1j7cj8k2se.fsf@starbuckisacylon.baylibre.com>


On Tue 13 Feb 2024 at 11:52, "Arnd Bergmann" <arnd at arndb.de> wrote:

> On Tue, Feb 13, 2024, at 11:36, Jerome Brunet wrote:
>> On Tue 13 Feb 2024 at 11:11, Arnd Bergmann <arnd at kernel.org> wrote:
>
>> This probably pre-dates the introduction of devm_clk_get_enabled()
>> It would probably be better to use that instead of duplicating helper
>> functions which do the same thing.
>
> Ah, I had not thought of that interface either, so you are probably
> right that this is the best way to do it.
> Can you send a replacement patch then and add my Reported-by?

Sure.

How may I reproduce the problem ?
Just tried with 'Debian clang version 16.0.6 (19)', no warning.

I suppose I need to add something ?

>
> I also sent the same patch for drivers/nvmem/meson-efuse.c, which
> I guess will also need the same treatment. I also checked and saw
> that all three files already had this code in linux-6.0 when
> devm_clk_get_enabled() got added.
>
>> If for any reason it is not possible, a common helper in clk.h would
>> preferable I think.
>
> I can't think of anything that prevents us from using
> devm_clk_get_enabled() here.
>
>     Arnd


-- 
Jerome


From francesco at dolcini.it  Tue Feb 13 03:43:28 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Tue, 13 Feb 2024 12:43:28 +0100
Subject: [PATCH v1] arm64: dts: ti: k3-am62-main: disable usb lpm
In-Reply-To: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
References: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
Message-ID: <20240213114328.GA6727@francesco-nb>

On Fri, Feb 09, 2024 at 02:02:12PM +0100, Andrejs Cainikovs wrote:
> From: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
> 
> AM62 USB works with some devices, while failing to operate with others.
> 
> [  560.189822] xhci-hcd xhci-hcd.4.auto: xHCI Host Controller
> [  560.195631] xhci-hcd xhci-hcd.4.auto: new USB bus registered, assigned bus number 2
> [  574.388509] xhci-hcd xhci-hcd.4.auto: can't setup: -110
> [  574.393814] xhci-hcd xhci-hcd.4.auto: USB bus 2 deregistered
> [  574.399544] xhci-hcd: probe of xhci-hcd.4.auto failed with error -110
> 
> This seems to be related to LPM (Link Power Management), and disabling it
> turns USB into reliable working state.
> 
> As per AM62 reference manual:
> 
> > 4.8.2.1 USB2SS Unsupported Features
> >
> > The following features are not supported on this family of devices:
> > ...
> > - USB 2.0 ECN: Link Power Management (LPM)
> > ...
> 
> Fixes: 2240f96cf3cd ("arm64: dts: ti: k3-am62-main: Add support for USB")
> Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>

Reviewed-by: Francesco Dolcini <francesco.dolcini at toradex.com>

Francesco



From gregkh at linuxfoundation.org  Tue Feb 13 03:44:48 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 13 Feb 2024 12:44:48 +0100
Subject: Regression, i.MX7 boot failure, Linux v6.1.77
In-Reply-To: <20240213112146.GA5874@francesco-nb>
References: <20240213112146.GA5874@francesco-nb>
Message-ID: <2024021300-traverse-anyplace-7910@gregkh>

On Tue, Feb 13, 2024 at 12:21:46PM +0100, Francesco Dolcini wrote:
> Hello Sasha,
> kernel v6.1.77 introduces a regression, with a boot failure, on i.MX7,
> with commit db30f469ae8b ("ARM: dts: imx7s: Fix nand-controller #size-cells").
> 
> The issue is known [1][2], changing `#size-cells = <0>` is formally
> correct, but do not play well with the firmware that are deployed on
> those embedded devices, leading to a boot failure.
> 
> A mitigation was implemented in the Linux kernel,
> commit 84549c816dc3 ("mtd: parsers: ofpart: add workaround for #size-cells 0")
> that was merged into v6.3, the firmware was also fixed, however existing
> device using old firmware will not boot anymore if updating to a newer
> kernel.
> 
> I would ask you to drop such a patch from any stable patches queue and
> not backport it to any older kernel.
> 
> To fix v6.1.y I see two options:
>  - backport 84549c816dc3
>  - revert db30f469ae8b
> 
> What do you prefer? Should I send myself a patch?

Backport would be best, that way we are in sync with newer releases.

I'll go queue it up now, thanks.

greg k-h


From jgg at nvidia.com  Tue Feb 13 03:54:23 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 07:54:23 -0400
Subject: [PATCH v2 5/5] iommu/arm-smmu: Convert to domain_alloc_paging()
In-Reply-To: <20240213111623.GA28517@willie-the-truck>
References: <5-v2-c86cc8c2230e+160bb-smmu_newapi_jgg@nvidia.com>
 <20240209200538.917366-1-dmitry.baryshkov@linaro.org>
 <20240209222349.GA923780@nvidia.com>
 <CAA8EJpp1wuMgawaUPnQWnhz1k023n8Q-k0_sO6P9p7ixntrCJQ@mail.gmail.com>
 <6511a289-fee6-4d08-9e01-695bd38d4ad6@arm.com>
 <CAA8EJpqtUnGXMPQO4F0JXQDv0oJKFYjuhf4hSBe2tY1ebWFjRA@mail.gmail.com>
 <20240213111623.GA28517@willie-the-truck>
Message-ID: <20240213115423.GG4048826@nvidia.com>

On Tue, Feb 13, 2024 at 11:16:23AM +0000, Will Deacon wrote:
> On Tue, Feb 13, 2024 at 12:55:38PM +0200, Dmitry Baryshkov wrote:
> > On Tue, 13 Feb 2024 at 12:20, Robin Murphy <robin.murphy at arm.com> wrote:
> > > On 2024-02-13 7:51 am, Dmitry Baryshkov wrote:
> > > > On Sat, 10 Feb 2024 at 00:23, Jason Gunthorpe <jgg at nvidia.com> wrote:
> > > >> And then we may get a clue from the backtraces it generates. I only
> > > >> saw one iommu group reported in your log so I'd expect one trace?
> > > >
> > > > I added dev_info + mdelays() around the arm_smmu_init_domain_context()
> > > > and I can see that it crashes within that function.
> > >
> > > Yeah, this is totally broken. We can't just call the unmodified
> > > arm_smmu_init_domain_context() at domain allocation because half of what
> > > it's doing belongs to the attach operation. We should not be allocating
> > > context banks, IRQs, etc. for a not-yet-attached domain, and we
> > > certainly shouldn't be touching hardware there outside of RPM.
> > 
> > Should I send a revert?
> 
> If reverting the patch fixes the issue for you, then yes please!

Not the whole thing though, just remove the 'if (dev)' like you
tested, thanks.

If you want I will send it

> Hopefully you can help Jason test a reworked verson for the future, as
> it's evident that Tegra doesn't tickle the power management side of things
> in the same way.

It can stay, as long as it uses the alloc_domain_paging() that is
enough for the core code to move forward.

I included it only because we were able to test it, most of the other
drivers I did not try to move their "finalize".

Jason


From krzysztof.kozlowski at linaro.org  Tue Feb 13 03:54:52 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 13 Feb 2024 12:54:52 +0100
Subject: [PATCH] dt-bindings: ata: convert MediaTek controller to the
 json-schema
In-Reply-To: <20240213074747.26151-1-zajec5@gmail.com>
References: <20240213074747.26151-1-zajec5@gmail.com>
Message-ID: <272705aa-a942-4676-8010-d001e336b26e@linaro.org>

On 13/02/2024 08:47, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  .../devicetree/bindings/ata/ahci-mtk.txt      | 51 ----------
>  .../bindings/ata/mediatek,mtk-ahci.yaml       | 98 +++++++++++++++++++
>  2 files changed, 98 insertions(+), 51 deletions(-)


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From mark.rutland at arm.com  Tue Feb 13 04:02:49 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 13 Feb 2024 12:02:49 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
Message-ID: <ZctaaeVFF8TpjA8Z@FVFF77S0Q05N.cambridge.arm.com>

On Mon, Feb 12, 2024 at 12:59:57PM +0000, Ryan Roberts wrote:
> On 12/02/2024 12:00, Mark Rutland wrote:
> > Hi Ryan,

[...]

> >> +static inline void set_pte(pte_t *ptep, pte_t pte)
> >> +{
> >> +	/*
> >> +	 * We don't have the mm or vaddr so cannot unfold contig entries (since
> >> +	 * it requires tlb maintenance). set_pte() is not used in core code, so
> >> +	 * this should never even be called. Regardless do our best to service
> >> +	 * any call and emit a warning if there is any attempt to set a pte on
> >> +	 * top of an existing contig range.
> >> +	 */
> >> +	pte_t orig_pte = __ptep_get(ptep);
> >> +
> >> +	WARN_ON_ONCE(pte_valid_cont(orig_pte));
> >> +	__set_pte(ptep, pte_mknoncont(pte));
> >> +}
> >> +
> >> +#define set_ptes set_ptes
> >> +static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
> >> +				pte_t *ptep, pte_t pte, unsigned int nr)
> >> +{
> >> +	pte = pte_mknoncont(pte);
> > 
> > Why do we have to clear the contiguous bit here? Is that for the same reason as
> > set_pte(), or do we expect callers to legitimately call this with the
> > contiguous bit set in 'pte'?
> > 
> > I think you explained this to me in-person, and IIRC we don't expect callers to
> > go set the bit themselves, but since it 'leaks' out to them via __ptep_get() we
> > have to clear it here to defer the decision of whether to set/clear it when
> > modifying entries. It would be nice if we could have a description of why/when
> > we need to clear this, e.g. in the 'public API' comment block above.
> 
> Yes, I think you've got it, but just to ram home the point: The PTE_CONT bit is
> private to the architecture code and is never set directly by core code. If the
> public API ever receives a pte that happens to have the PTE_CONT bit set, it
> would be bad news if we then accidentally set that in the pgtable.
> 
> Ideally, we would just uncondidtionally clear the bit before a getter returns
> the pte (e.g. ptep_get(), ptep_get_lockless(), ptep_get_and_clear(), ...). That
> way, the code code is guarranteed never to see a pte with the PTE_CONT bit set
> and can therefore never accidentally pass such a pte into a setter function.
> However, there is existing functionality that relies on being able to get a pte,
> then pass it to pte_leaf_size(), and arch function that checks the PTE_CONT bit
> to determine how big the leaf is. This is used in perf_get_pgtable_size().
> 
> So to allow perf_get_pgtable_size() to continue to see the "real" page size, I
> decided to allow PTE_CONT to leak through the getters and instead
> unconditionally clear the bit when a pte is passed to any of the setters.
> 
> I'll add a (slightly less verbose) comment as you suggest.

Great, thanks!

[...]

> >> +static inline bool mm_is_user(struct mm_struct *mm)
> >> +{
> >> +	/*
> >> +	 * Don't attempt to apply the contig bit to kernel mappings, because
> >> +	 * dynamically adding/removing the contig bit can cause page faults.
> >> +	 * These racing faults are ok for user space, since they get serialized
> >> +	 * on the PTL. But kernel mappings can't tolerate faults.
> >> +	 */
> >> +	return mm != &init_mm;
> >> +}
> > 
> > We also have the efi_mm as a non-user mm, though I don't think we manipulate
> > that while it is live, and I'm not sure if that needs any special handling.
> 
> Well we never need this function in the hot (order-0 folio) path, so I think I
> could add a check for efi_mm here with performance implication. It's probably
> safest to explicitly exclude it? What do you think?

That sounds ok to me.

Otherwise, if we (somehow) know that we avoid calling this at all with an EFI
mm (e.g. because of the way we construct that), I'd be happy with a comment.

Probably best to Cc Ard for whatever we do here.

> >> +static inline pte_t *contpte_align_down(pte_t *ptep)
> >> +{
> >> +	return (pte_t *)(ALIGN_DOWN((unsigned long)ptep >> 3, CONT_PTES) << 3);
> > 
> > I think this can be:
> > 
> > static inline pte_t *contpte_align_down(pte_t *ptep)
> > {
> > 	return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
> > }
> 
> Yep - that's much less ugly - thanks!
> 
> > 
> >> +
> >> +static void contpte_convert(struct mm_struct *mm, unsigned long addr,
> >> +			    pte_t *ptep, pte_t pte)
> >> +{
> >> +	struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0);
> >> +	unsigned long start_addr;
> >> +	pte_t *start_ptep;
> >> +	int i;
> >> +
> >> +	start_ptep = ptep = contpte_align_down(ptep);
> >> +	start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> >> +	pte = pfn_pte(ALIGN_DOWN(pte_pfn(pte), CONT_PTES), pte_pgprot(pte));
> >> +
> >> +	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) {
> >> +		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
> >> +
> >> +		if (pte_dirty(ptent))
> >> +			pte = pte_mkdirty(pte);
> >> +
> >> +		if (pte_young(ptent))
> >> +			pte = pte_mkyoung(pte);
> >> +	}
> > 
> > Not a big deal either way, but I wonder if it makes more sense to accumulate
> > the 'ptent' dirty/young values, then modify 'pte' once, i.e.
> > 
> > 	bool dirty = false, young = false;
> > 
> > 	for (...) {
> > 		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
> > 		dirty |= pte_dirty(ptent);
> > 		young |= pte_young(ptent);
> > 	}
> > 
> > 	if (dirty)
> > 		pte_mkdirty(pte);
> > 	if (young)
> > 		pte_mkyoung(pte);
> > 
> > I suspect that might generate slightly better code, but I'm also happy with the
> > current form if people thnk that's more legible (I have no strong feelings
> > either way).
> 
> I kept it this way, because its the same pattern used in arm64's hugetlbpage.c.
> We also had the same comment against David's batching patches recently, and he
> opted to stick with the former version:
> 
> https://lore.kernel.org/linux-mm/d83309fa-4daa-430f-ae52-4e72162bca9a at redhat.com/
> 
> So I'm inclined to leave it as is, since you're not insisting :)

That rationale is reasonable, and I'm fine with this as-is.

[...]

> >> +pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
> >> +{
> >> +	/*
> >> +	 * Gather access/dirty bits, which may be populated in any of the ptes
> >> +	 * of the contig range. We may not be holding the PTL, so any contiguous
> >> +	 * range may be unfolded/modified/refolded under our feet. Therefore we
> >> +	 * ensure we read a _consistent_ contpte range by checking that all ptes
> >> +	 * in the range are valid and have CONT_PTE set, that all pfns are
> >> +	 * contiguous and that all pgprots are the same (ignoring access/dirty).
> >> +	 * If we find a pte that is not consistent, then we must be racing with
> >> +	 * an update so start again. If the target pte does not have CONT_PTE
> >> +	 * set then that is considered consistent on its own because it is not
> >> +	 * part of a contpte range.
> >> +	 */
> >> +
> >> +	pgprot_t orig_prot;
> >> +	unsigned long pfn;
> >> +	pte_t orig_pte;
> >> +	pgprot_t prot;
> >> +	pte_t *ptep;
> >> +	pte_t pte;
> >> +	int i;
> >> +
> >> +retry:
> >> +	orig_pte = __ptep_get(orig_ptep);
> >> +
> >> +	if (!pte_valid_cont(orig_pte))
> >> +		return orig_pte;
> >> +
> >> +	orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
> >> +	ptep = contpte_align_down(orig_ptep);
> >> +	pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
> >> +
> >> +	for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
> >> +		pte = __ptep_get(ptep);
> >> +		prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
> >> +
> >> +		if (!pte_valid_cont(pte) ||
> >> +		   pte_pfn(pte) != pfn ||
> >> +		   pgprot_val(prot) != pgprot_val(orig_prot))
> >> +			goto retry;
> >> +
> >> +		if (pte_dirty(pte))
> >> +			orig_pte = pte_mkdirty(orig_pte);
> >> +
> >> +		if (pte_young(pte))
> >> +			orig_pte = pte_mkyoung(orig_pte);
> >> +	}
> >> +
> >> +	return orig_pte;
> >> +}
> >> +EXPORT_SYMBOL(contpte_ptep_get_lockless);
> > 
> > I'm struggling to convince myself that this is safe in general, as it really
> > depends on how the caller will use this value. Which caller(s) actually care
> > about the access/dirty bits, given those could change at any time anyway?
> 
> I think your points below are valid, and agree we should try to make this work
> without needing access/dirty if possible. But can you elaborate on why you don't
> think it's safe?

Having mulled this over, I think it is safe as-is, and I was being overly
cautious.

I had a general fear of potential problems stemming from the fact that (a) the
accumulation of access/dirty bits isn't atomic and (b) the loop is unbounded.
>From looking at how this is used today, I think (a) is essentially the same as
reading a stale non-contiguous entry, and I'm being overly cautious there. For
(b), I think that's largely a performance concern and the would only retry
indefinitely in the presence of mis-programmed entries or consistent racing
with a writer under heavy contention.

I think it's still desirable to avoid the accumulation in most cases (to avoid
redundant work and to minimize the potential for unbounded retries), but I'm
happy with that being a follow-up improvement.

> > I took a quick scan, and AFAICT:
> 
> Thanks for enumerating these; Saves me from having to refresh my memory :)
> > 
> > * For perf_get_pgtable_size(), we only care about whether the entry is valid
> >   and has the contig bit set. We could clean that up with a new interface, e.g.
> >   something like a new ptep_get_size_lockless().
> > 
> > * For gup_pte_range(), I'm not sure we actually need the access/dirty bits when
> >   we look at the pte to start with, since we only care where we can logically
> >   write to the page at that point.
> > 
> >   I see that we later follow up with:
> > 
> >     with pte_val(pte) != pte_val(ptep_get(ptep)))
> > 
> >   ... is that why we need ptep_get_lockless() to accumulate the access/dirty
> >   bits? So that shape of lockless-try...locked-compare sequence works?
> > 
> > * For huge_pte_alloc(), arm64 doesn't select CONFIG_ARCH_WANT_GENERAL_HUGETLB,
> >   so this doesn' seem to matter.
> > 
> > * For __collapse_huge_page_swapin(), we only care if the pte is a swap pte,
> >   which means the pte isn't valid, and we'll return the orig_pte as-is anyway.
> > 
> > * For pte_range_none() the access/dirty bits don't matter.
> > 
> > * For handle_pte_fault() I think we have the same shape of
> >   lockless-try...locked-compare sequence as for gup_pte_range(), where we don't
> >   care about the acess/dirty bits before we reach the locked compare step.
> > 
> > * For ptdump_pte_entry() I think it's arguable that we should continue to
> >   report the access/dirty bits separately for each PTE, as we have done until
> >   now, to give an accurate representation of the contents of the translation
> >   tables.
> > 
> > * For swap_vma_readahead() and unuse_pte_range() we only care if the PTE is a
> >   swap entry, the access/dirty bits don't matter.
> > 
> > So AFAICT this only really matters for gup_pte_range() and handle_pte_fault(),
> > and IIUC that's only so that the locklessly-loaded pte value can be compared
> > with a subsequently locked-loaded entry (for which the access/dirty bits will
> > be accumulated). Have I understood that correctly?
> 
> Yes, I agree with what you are saying. My approach was to try to implement the
> existing APIs accurately though, the argument being that it reduces the chances
> of getting it wrong. But if you think the implementation is unsafe, then I guess
> it blows that out of the water...

I think your approach makes sense, and as above I'm happy to defer the API
changes/additions to avoid the accumulation of access/dirty bits.

> > If so, I wonder if we could instead do that comparison modulo the access/dirty
> > bits, 
> 
> I think that would work - but will need to think a bit more on it.
> 
> > and leave ptep_get_lockless() only reading a single entry?
> 
> I think we will need to do something a bit less fragile. ptep_get() does collect
> the access/dirty bits so its confusing if ptep_get_lockless() doesn't IMHO. So
> we will likely want to rename the function and make its documentation explicit
> that it does not return those bits.
> 
> ptep_get_lockless_noyoungdirty()? yuk... Any ideas?
> 
> Of course if I could convince you the current implementation is safe, I might be
> able to sidestep this optimization until a later date?

Yep. :)

Mark.


From ryan.roberts at arm.com  Tue Feb 13 04:06:22 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 12:06:22 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
Message-ID: <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>

On 12/02/2024 20:38, Ryan Roberts wrote:
> [...]
> 
>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>> +{
>>>>> +	/*
>>>>> +	 * Don't attempt to apply the contig bit to kernel mappings, because
>>>>> +	 * dynamically adding/removing the contig bit can cause page faults.
>>>>> +	 * These racing faults are ok for user space, since they get serialized
>>>>> +	 * on the PTL. But kernel mappings can't tolerate faults.
>>>>> +	 */
>>>>> +	return mm != &init_mm;
>>>>> +}
>>>>
>>>> We also have the efi_mm as a non-user mm, though I don't think we manipulate
>>>> that while it is live, and I'm not sure if that needs any special handling.
>>>
>>> Well we never need this function in the hot (order-0 folio) path, so I think I
>>> could add a check for efi_mm here with performance implication. It's probably
>>> safest to explicitly exclude it? What do you think?
>>
>> Oops: This should have read "I think I could add a check for efi_mm here
>> *without* performance implication"
> 
> It turns out that efi_mm is only defined when CONFIG_EFI is enabled. I can do this:
> 
> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
> 
> Is that acceptable? This is my preference, but nothing else outside of efi
> references this symbol currently.
> 
> Or perhaps I can convince myself that its safe to treat efi_mm like userspace.
> There are a couple of things that need to be garanteed for it to be safe:
> 
>   - The PFNs of present ptes either need to have an associated struct page or
>     need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
>     pte_mkdevmap())
> 
>   - Live mappings must either be static (no changes that could cause fold/unfold
>     while live) or the system must be able to tolerate a temporary fault
> 
> Mark suggests efi_mm is not manipulated while live, so that meets the latter
> requirement, but I'm not sure about the former?

I've gone through all the efi code, and conclude that, as Mark suggests, the
mappings are indeed static. And additionally, the ptes are populated using only
the _private_ ptep API, so there is no issue here. As just discussed with Mark,
my prefereence is to not make any changes to code, and just add a comment
describing why efi_mm is safe.

Details:

* Registered with ptdump
    * ptep_get_lockless()
* efi_create_mapping -> create_pgd_mapping ? -> init_pte:
    * __ptep_get()
    * __set_pte()
* efi_memattr_apply_permissions -> efi_set_mapping_permissions ? -> set_permissions
    * __ptep_get()
    * __set_pte()

Thanks,
Ryan

> 
> Thanks,
> Ryan
> 



From herbert at gondor.apana.org.au  Tue Feb 13 04:09:21 2024
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Tue, 13 Feb 2024 20:09:21 +0800
Subject: [PATCH] ARM: crypto: fix function cast warnings
In-Reply-To: <20240213101356.460376-1-arnd@kernel.org>
References: <20240213101356.460376-1-arnd@kernel.org>
Message-ID: <Zctb8QOtMuIfMvDT@gondor.apana.org.au>

On Tue, Feb 13, 2024 at 11:13:44AM +0100, Arnd Bergmann wrote:
>
> Rework the sha256/sha512 code to instead go through a trivial helper
> function to preserve the calling conventions.

Why not just change the assembly function prototype?

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 will at kernel.org  Tue Feb 13 04:12:01 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 13 Feb 2024 12:12:01 +0000
Subject: [RFC PATCH] KVM: arm64: Fix double-free following
 kvm_pgtable_stage2_free_unlinked()
In-Reply-To: <86cyt062jh.wl-maz@kernel.org>
References: <20240212193052.27765-1-will@kernel.org>
 <Zcp8LcvsZiZVkNKe@linux.dev>
 <86cyt062jh.wl-maz@kernel.org>
Message-ID: <20240213121201.GA28682@willie-the-truck>

On Tue, Feb 13, 2024 at 11:12:34AM +0000, Marc Zyngier wrote:
> On Mon, 12 Feb 2024 20:14:37 +0000,
> Oliver Upton <oliver.upton at linux.dev> wrote:
> > On Mon, Feb 12, 2024 at 07:30:52PM +0000, Will Deacon wrote:
> > > Sending this as an RFC as I only spotted it from code inspection and I'm
> > > surprised others aren't seeing fireworks if it's a genuine bug. I also
> > > couldn't come up with a sensible Fixes tag, as all of:
> > > 
> > >  e7c05540c694b ("KVM: arm64: Add helper for creating unlinked stage2 subtrees")
> > >  8f5a3eb7513fc ("KVM: arm64: Add kvm_pgtable_stage2_split()")
> > >  f6a27d6dc51b2 ("KVM: arm64: Drop last page ref in kvm_pgtable_stage2_free_removed()")
> 
> I'd blame it on the last commit, as we really ought to have it if we
> have the others.

Yes, that's probably the best approach if you're adding a Fixes tag.

> > > @@ -1502,7 +1501,6 @@ static int stage2_split_walker(const struct kvm_pgtable_visit_ctx *ctx,
> > >  
> > >  	if (!stage2_try_break_pte(ctx, mmu)) {
> > >  		kvm_pgtable_stage2_free_unlinked(mm_ops, childp, level);
> > > -		mm_ops->put_page(childp);
> > >  		return -EAGAIN;
> > >  	}
> > 
> > This, on the other hand, seems possible. There exists a race where an
> > old block PTE could have the AF set on it and the underlying cmpxchg()
> > could fail. There shouldn't be a race with any software walkers, as we
> > hold the MMU lock for write here.
> 
> AF update is indeed a likely candidate.
> 
> In any case, this patch looks good to me as it is, and we can always
> have a separate tweak to adjust the severity of the first case as
> required. Unless anyone objects, I'd like to queue it shortly.

Fine by me! Even though I found it by inspection, I have taken the patch
for a spin to check that I (somehow) didn't break something else.

Will


From krzysztof.kozlowski at linaro.org  Tue Feb 13 04:12:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 13 Feb 2024 13:12:26 +0100
Subject: [PATCH 1/3] dt-bindings: ARM: at91: Document Microchip SAMA7G54
 Curiosity
In-Reply-To: <20240213085614.26804-2-mihai.sain@microchip.com>
References: <20240213085614.26804-1-mihai.sain@microchip.com>
 <20240213085614.26804-2-mihai.sain@microchip.com>
Message-ID: <9ff75d56-73b4-42b2-bcc4-6888b247fc0c@linaro.org>

On 13/02/2024 09:56, Mihai Sain wrote:
> Document device tree binding of the Microchip SAMA7G54 Curiosity board.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From jgg at ziepe.ca  Tue Feb 13 04:12:57 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 08:12:57 -0400
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
In-Reply-To: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
References: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
Message-ID: <20240213121257.GI765010@ziepe.ca>

On Tue, Feb 13, 2024 at 01:31:56PM +0200, Dmitry Baryshkov wrote:
> This reverts commit 9b3febc3a3da ("iommu/arm-smmu: Convert to
> domain_alloc_paging()"). It breaks Qualcomm MSM8996 platform. Calling
> arm_smmu_write_context_bank() from new codepath results in the platform
> being reset because of the unclocked hardware access.
> 
> Fixes: 9b3febc3a3da ("iommu/arm-smmu: Convert to domain_alloc_paging()")
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu.c | 17 ++++++-----------
>  1 file changed, 6 insertions(+), 11 deletions(-)

Please no, as I said in the other email the only thing that should be
reverted is this:

> @@ -875,15 +879,6 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
>  	mutex_init(&smmu_domain->init_mutex);
>  	spin_lock_init(&smmu_domain->cb_lock);
>  
> -	if (dev) {
> -		struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> -
> -		if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> -			kfree(smmu_domain);
> -			return NULL;
> -		}
> -	}
> -
>  	return &smmu_domain->domain;
>  }

Everything else is fine, you already tested with that arrangement.

Jason


From krzysztof.kozlowski at linaro.org  Tue Feb 13 04:16:37 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 13 Feb 2024 13:16:37 +0100
Subject: [PATCH 3/3] ARM: dts: microchip: sama7g54_curiosity: Add initial
 device tree of the board
In-Reply-To: <20240213085614.26804-4-mihai.sain@microchip.com>
References: <20240213085614.26804-1-mihai.sain@microchip.com>
 <20240213085614.26804-4-mihai.sain@microchip.com>
Message-ID: <1895b682-288c-4645-bc8e-2e4c364e7de1@linaro.org>

On 13/02/2024 09:56, Mihai Sain wrote:
> Add initial device tree of the SAMA7G54 Curiosity board.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/Makefile          |   4 +-
>  .../dts/microchip/at91-sama7g54_curiosity.dts | 491 ++++++++++++++++++
>  2 files changed, 494 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
> 
> diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
> index efde9546c8f4..29b2a788748f 100644
> --- a/arch/arm/boot/dts/microchip/Makefile
> +++ b/arch/arm/boot/dts/microchip/Makefile
> @@ -12,6 +12,7 @@ DTC_FLAGS_at91-sama5d3_eds := -@
>  DTC_FLAGS_at91-sama5d3_xplained := -@
>  DTC_FLAGS_at91-sama5d4_xplained := -@
>  DTC_FLAGS_at91-sama7g5ek := -@
> +DTC_FLAGS_at91-sama7g54_curiosity := -@
>  dtb-$(CONFIG_SOC_AT91RM9200) += \
>  	at91rm9200ek.dtb \
>  	mpa1600.dtb
> @@ -87,7 +88,8 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
>  	at91-sama5d4ek.dtb \
>  	at91-vinco.dtb
>  dtb-$(CONFIG_SOC_SAMA7G5) += \
> -	at91-sama7g5ek.dtb
> +	at91-sama7g5ek.dtb \
> +	at91-sama7g54_curiosity.dtb
>  
>  dtb-$(CONFIG_SOC_LAN966) += \
>  	lan966x-kontron-kswitch-d10-mmt-6g-2gs.dtb \
> diff --git a/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
> new file mode 100644
> index 000000000000..c2955a170658
> --- /dev/null
> +++ b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
> @@ -0,0 +1,491 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * at91-sama7g54_curiosity.dts - Device Tree file for SAMA7G54 Curiosity Board
> + *
> + * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
> + *
> + * Author: Mihai Sain <mihai.sain at microchip.com>
> + *
> + */
> +/dts-v1/;
> +#include "sama7g5-pinfunc.h"
> +#include "sama7g5.dtsi"
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/mfd/atmel-flexcom.h>
> +#include <dt-bindings/pinctrl/at91.h>
> +
> +/ {
> +	model = "Microchip SAMA7G54 Curiosity";
> +	compatible = "microchip,sama7g54-curiosity", "microchip,sama7g5", "microchip,sama7";
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200 root=/dev/mmcblk1p2 rw rootwait";

What if user wants root from other place? What if mmc number changes,
which is actually happening all the time (hint: use partuuid)? Drop
root, it's not that helpful.

You also do not need console, so drop entire bootargs.


> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	aliases {
> +		serial0 = &uart3;
> +		i2c0 = &i2c10;
> +	};
> +
> +	clocks {
> +		slow_xtal {

No underscores in node names. Generic node names, so at least generic
prefix or suffix. Anyway you should override your properties via
phandle/label style.


> +			clock-frequency = <32768>;
> +		};
> +
> +		main_xtal {
> +			clock-frequency = <24000000>;
> +		};
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_key_gpio_default>;
> +
> +		button-user {
> +			label = "user-button";
> +			gpios = <&pioA PIN_PD19 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_PROG1>;
> +			wakeup-source;
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_led_gpio_default>;
> +		status = "okay";

Why do you need it? Was it disabled anywhere?

> +
> +		led-red {
> +			label = "red";

Use color and function instead.

> +			gpios = <&pioA PIN_PD13 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +		};
> +
> +		led-green {
> +			label = "green";

Use color and function instead.

> +			gpios = <&pioA PIN_PD14 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +		};
> +
> +		led-blue {
> +			label = "blue";

Use color and function instead.

> +			gpios = <&pioA PIN_PB15 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "heartbeat";
> +		};
> +	};
> +
> +	memory at 60000000 {
> +		device_type = "memory";
> +		reg = <0x60000000 0x10000000>; // 256 MiB DDR3L-1066 16-bit
> +	};
> +};
> +
> +&adc {
> +	vddana-supply = <&vddout25>;
> +	vref-supply = <&vddout25>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_mikrobus1_an_default &pinctrl_mikrobus2_an_default>;
> +	status = "okay";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&vddcpu>;
> +};
> +
> +&dma0 {
> +	status = "okay";
> +};
> +
> +&dma1 {
> +	status = "okay";
> +};
> +
> +&dma2 {
> +	status = "okay";
> +};
> +
> +&ebi {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_nand_default>;
> +	status = "okay";
> +
> +	nand_controller: nand-controller {
> +		status = "okay";
> +
> +		nand at 3 {
> +			reg = <0x3 0x0 0x800000>;
> +			atmel,rb = <0>;
> +			nand-bus-width = <8>;
> +			nand-ecc-mode = "hw";
> +			nand-ecc-strength = <8>;
> +			nand-ecc-step-size = <512>;
> +			nand-on-flash-bbt;
> +			label = "nand";
> +			status = "okay";

Was it disabled anywhere?

> +
> +			partitions {
> +				compatible = "fixed-partitions";
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +
> +				at91bootstrap at 0 {
> +					label = "nand: at91bootstrap";
> +					reg = <0x0 0x40000>;
> +				};
> +
> +				bootloader at 40000 {
> +					label = "nand: u-boot";
> +					reg = <0x40000 0x100000>;
> +				};
> +
> +				bootloaderenv at 140000 {
> +					label = "nand: u-boot env";
> +					reg = <0x140000 0x40000>;
> +				};
> +
> +				dtb at 180000 {
> +					label = "nand: device tree";
> +					reg = <0x180000 0x80000>;
> +				};
> +
> +				kernel at 200000 {
> +					label = "nand: kernel";
> +					reg = <0x200000 0x600000>;
> +				};
> +
> +				rootfs at 800000 {
> +					label = "nand: rootfs";
> +					reg = <0x800000 0x1f800000>;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&flx3 {
> +	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
> +	status = "okay";
> +
> +	uart3: serial at 200 {
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_flx3_default>;
> +		status = "okay";
> +	};
> +};
> +
> +&flx10 {
> +	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
> +	status = "okay";
> +
> +	i2c10: i2c at 600 {
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_flx10_default>;
> +		i2c-analog-filter;
> +		i2c-digital-filter;
> +		i2c-digital-filter-width-ns = <35>;
> +		status = "okay";
> +
> +		adc at 1f {
> +			compatible = "microchip,pac1934";
> +			reg = <0x1f>;
> +		};
> +
> +		eeprom at 51 {
> +			compatible = "atmel,24c02";
> +			reg = <0x51>;
> +			pagesize = <16>;
> +			size = <256>;
> +			status = "okay";

Was it disabled anywhere?

> +		};
> +
> +		mcp16502 at 5b {

Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation


> +			compatible = "microchip,mcp16502";
> +			reg = <0x5b>;
> +			status = "okay";

Was it disabled anywhere?

> +
> +			regulators {
> +				vdd_3v3: VDD_IO {
> +					regulator-name = "VDD_IO";
> +					regulator-min-microvolt = <3300000>;
> +					regulator-max-microvolt = <3300000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-microvolt = <3300000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vddioddr: VDD_DDR {
> +					regulator-name = "VDD_DDR";
> +					regulator-min-microvolt = <1350000>;
> +					regulator-max-microvolt = <1350000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-microvolt = <1350000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-on-in-suspend;
> +						regulator-suspend-microvolt = <1350000>;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vddcore: VDD_CORE {
> +					regulator-name = "VDD_CORE";
> +					regulator-min-microvolt = <1150000>;
> +					regulator-max-microvolt = <1150000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-voltage = <1150000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vddcpu: VDD_OTHER {
> +					regulator-name = "VDD_OTHER";
> +					regulator-min-microvolt = <1050000>;
> +					regulator-max-microvolt = <1250000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-ramp-delay = <3125>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-voltage = <1050000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vldo1: LDO1 {
> +					regulator-name = "LDO1";
> +					regulator-min-microvolt = <1800000>;
> +					regulator-max-microvolt = <1800000>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-suspend-voltage = <1800000>;
> +						regulator-on-in-suspend;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +					};
> +				};
> +
> +				vldo2: LDO2 {
> +					regulator-name = "LDO2";
> +					regulator-min-microvolt = <3300000>;
> +					regulator-max-microvolt = <3300000>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-suspend-voltage = <3300000>;
> +						regulator-on-in-suspend;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +					};
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&qspi1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_qspi1_default>;
> +	status = "okay";
> +
> +	flash at 0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0x0>;
> +		spi-max-frequency = <100000000>;
> +		spi-tx-bus-width = <4>;
> +		spi-rx-bus-width = <4>;
> +		m25p,fast-read;
> +		status = "okay";

Was it disabled anywhere?



Best regards,
Krzysztof



From jgg at nvidia.com  Tue Feb 13 04:18:50 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 08:18:50 -0400
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240213112015.GB28517@willie-the-truck>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
 <20240208125846.GA23290@willie-the-truck>
 <20240208142729.GH10476@nvidia.com>
 <20240213112015.GB28517@willie-the-truck>
Message-ID: <20240213121850.GH4048826@nvidia.com>

On Tue, Feb 13, 2024 at 11:20:15AM +0000, Will Deacon wrote:

> Damn, all the surrounding rework has really left this poor code in a bit
> of a state. 

That's one way to describe it. There is a reason it took me so many
patches to align this to the new core APIs :(

> Could you please respin your fix, but with an additional change
> to arm_smmu_mmu_notifier_get() so that it returns an error if there is
> more than one device in the domain, with some of the above in a comment?

Adding a check is not a comprehensive solution, there are still ways
userspace can attack this code with iommufd's coming PASID support. It
certainly doesn't belong in this patch which should be backported.

I can summarize some of these details in a comment for this patch.

Jason


From david at redhat.com  Tue Feb 13 04:19:08 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 13 Feb 2024 13:19:08 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
 <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
Message-ID: <41499621-482f-455b-9f68-b43ea8052557@redhat.com>

On 13.02.24 13:06, Ryan Roberts wrote:
> On 12/02/2024 20:38, Ryan Roberts wrote:
>> [...]
>>
>>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>>> +{
>>>>>> +	/*
>>>>>> +	 * Don't attempt to apply the contig bit to kernel mappings, because
>>>>>> +	 * dynamically adding/removing the contig bit can cause page faults.
>>>>>> +	 * These racing faults are ok for user space, since they get serialized
>>>>>> +	 * on the PTL. But kernel mappings can't tolerate faults.
>>>>>> +	 */
>>>>>> +	return mm != &init_mm;
>>>>>> +}
>>>>>
>>>>> We also have the efi_mm as a non-user mm, though I don't think we manipulate
>>>>> that while it is live, and I'm not sure if that needs any special handling.
>>>>
>>>> Well we never need this function in the hot (order-0 folio) path, so I think I
>>>> could add a check for efi_mm here with performance implication. It's probably
>>>> safest to explicitly exclude it? What do you think?
>>>
>>> Oops: This should have read "I think I could add a check for efi_mm here
>>> *without* performance implication"
>>
>> It turns out that efi_mm is only defined when CONFIG_EFI is enabled. I can do this:
>>
>> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
>>
>> Is that acceptable? This is my preference, but nothing else outside of efi
>> references this symbol currently.
>>
>> Or perhaps I can convince myself that its safe to treat efi_mm like userspace.
>> There are a couple of things that need to be garanteed for it to be safe:
>>
>>    - The PFNs of present ptes either need to have an associated struct page or
>>      need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
>>      pte_mkdevmap())
>>
>>    - Live mappings must either be static (no changes that could cause fold/unfold
>>      while live) or the system must be able to tolerate a temporary fault
>>
>> Mark suggests efi_mm is not manipulated while live, so that meets the latter
>> requirement, but I'm not sure about the former?
> 
> I've gone through all the efi code, and conclude that, as Mark suggests, the
> mappings are indeed static. And additionally, the ptes are populated using only
> the _private_ ptep API, so there is no issue here. As just discussed with Mark,
> my prefereence is to not make any changes to code, and just add a comment
> describing why efi_mm is safe.
> 
> Details:
> 
> * Registered with ptdump
>      * ptep_get_lockless()
> * efi_create_mapping -> create_pgd_mapping ? -> init_pte:
>      * __ptep_get()
>      * __set_pte()
> * efi_memattr_apply_permissions -> efi_set_mapping_permissions ? -> set_permissions
>      * __ptep_get()
>      * __set_pte()

Sound good. We could add some VM_WARN_ON if we ever get the efi_mm via 
the "official" APIs.

-- 
Cheers,

David / dhildenb



From horatiu.vultur at microchip.com  Tue Feb 13 04:17:05 2024
From: horatiu.vultur at microchip.com (Horatiu Vultur)
Date: Tue, 13 Feb 2024 13:17:05 +0100
Subject: [PATCH net-next] net: sparx5: Add spinlock for frame transmission from CPU
Message-ID: <20240213121705.4070598-1-horatiu.vultur@microchip.com>

Both registers used when doing manual injection or fdma injection are
shared between all the net devices of the switch. It was noticed that
when having two process which each of them trying to inject frames on
different ethernet ports, that the HW started to behave strange, by
sending out more frames then expected. When doing fdma injection it is
required to set the frame in the DCB and then make sure that the next
pointer of the last DCB is invalid. But because there is no locks for
this, then easily this pointer between the DCB can be broken and then it
would create a loop of DCBs. And that means that the HW will
continuously transmit these frames in a loop. Until the SW will break
this loop.
Therefore to fix this issue, add a spin lock for when accessing the
registers for manual or fdma injection.

Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_main.c   | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_main.h   | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_packet.c | 2 ++
 3 files changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index d1f7fc8b1b71a..3c066b62e6894 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -757,6 +757,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, sparx5);
 	sparx5->pdev = pdev;
 	sparx5->dev = &pdev->dev;
+	spin_lock_init(&sparx5->tx_lock);
 
 	/* Do switch core reset if available */
 	reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index 6f565c0c0c3dc..316fed5f27355 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -280,6 +280,7 @@ struct sparx5 {
 	int xtr_irq;
 	/* Frame DMA */
 	int fdma_irq;
+	spinlock_t tx_lock; /* lock for frame transmission */
 	struct sparx5_rx rx;
 	struct sparx5_tx tx;
 	/* PTP */
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
index 6db6ac6a3bbc2..ac7e1cffbcecf 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
@@ -244,10 +244,12 @@ netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	skb_tx_timestamp(skb);
+	spin_lock(&sparx5->tx_lock);
 	if (sparx5->fdma_irq > 0)
 		ret = sparx5_fdma_xmit(sparx5, ifh, skb);
 	else
 		ret = sparx5_inject(sparx5, ifh, skb, dev);
+	spin_unlock(&sparx5->tx_lock);
 
 	if (ret == -EBUSY)
 		goto busy;
-- 
2.34.1



From will at kernel.org  Tue Feb 13 04:19:34 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 13 Feb 2024 12:19:34 +0000
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
In-Reply-To: <20240213121257.GI765010@ziepe.ca>
References: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
 <20240213121257.GI765010@ziepe.ca>
Message-ID: <20240213121934.GA28726@willie-the-truck>

On Tue, Feb 13, 2024 at 08:12:57AM -0400, Jason Gunthorpe wrote:
> On Tue, Feb 13, 2024 at 01:31:56PM +0200, Dmitry Baryshkov wrote:
> > This reverts commit 9b3febc3a3da ("iommu/arm-smmu: Convert to
> > domain_alloc_paging()"). It breaks Qualcomm MSM8996 platform. Calling
> > arm_smmu_write_context_bank() from new codepath results in the platform
> > being reset because of the unclocked hardware access.
> > 
> > Fixes: 9b3febc3a3da ("iommu/arm-smmu: Convert to domain_alloc_paging()")
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> >  drivers/iommu/arm/arm-smmu/arm-smmu.c | 17 ++++++-----------
> >  1 file changed, 6 insertions(+), 11 deletions(-)
> 
> Please no, as I said in the other email the only thing that should be
> reverted is this:
> 
> > @@ -875,15 +879,6 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
> >  	mutex_init(&smmu_domain->init_mutex);
> >  	spin_lock_init(&smmu_domain->cb_lock);
> >  
> > -	if (dev) {
> > -		struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> > -
> > -		if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> > -			kfree(smmu_domain);
> > -			return NULL;
> > -		}
> > -	}
> > -
> >  	return &smmu_domain->domain;
> >  }
> 
> Everything else is fine, you already tested with that arrangement.

Partial reverts are a recipe for confusion, so I'll take this and if you'd
like to bring back some of the hunks, please can you send a patch on top
that does that?

Cheers,

Will


From krzysztof.kozlowski at linaro.org  Tue Feb 13 04:19:59 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 13 Feb 2024 13:19:59 +0100
Subject: [PATCH v2 16/17] dt-bindings: arm: add UNI-T UTi260b
In-Reply-To: <20240213010347.1075251-17-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-17-sre@kernel.org>
Message-ID: <0d94b8a4-0bfa-4f1f-bd58-6a59c408b7f2@linaro.org>

On 13/02/2024 02:01, Sebastian Reichel wrote:
> Add compatible value for i.MX6ULL based UNI-T
> UTi260b thermal camera.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From michal.vokac at ysoft.com  Tue Feb 13 04:20:44 2024
From: michal.vokac at ysoft.com (=?UTF-8?B?TWljaGFsIFZva8OhxI0=?=)
Date: Tue, 13 Feb 2024 13:20:44 +0100
Subject: [PATCH 1/2] ARM: dts: imx6dl-yapp4: Fix the QCA switch register
 address
In-Reply-To: <c5dad8e7-c486-4dd9-bfb5-bdfa2ddc18b3@lunn.ch>
References: <1707751422-31517-1-git-send-email-michal.vokac@ysoft.com>
 <c5dad8e7-c486-4dd9-bfb5-bdfa2ddc18b3@lunn.ch>
Message-ID: <db282aa5-2db3-49b9-a7dd-86e94226aa7b@ysoft.com>

On 12. 02. 24 17:08, Andrew Lunn wrote:
> On Mon, Feb 12, 2024 at 04:23:41PM +0100, Michal Vok?? wrote:
>> The switch address in the node name is in hex while the address in the reg
>> property is decimal which is wrong. Fix that and write the reg address
>> as a hexadecimal number.
> 
> This feels the wrong way around. The reg value is used by the kernel,
> where as the node name is not. If the reg value was wrong, the switch
> would not be found. If this file was tested, why did somebody not
> notice the switch was missing?
> 
> Do you have the hardware? Can you confirm is really does not work
> without this patch? Was 15b43e497ffd never actually tested?
Yes, I have bunch of these boards all around my desk - we manufacture
them. I am pretty sure I tested all the patches I have ever sent to
the mailing list regarding these boards.

The fact is that the switch actually works regardless of the reg value.
It worked prior to the 15b43e497ffd commit with address 0, it worked
later on with the reg value 10 and it works now with reg value 0x10.

While dealing with the broken reset gpio [1] I just noticed that in
the 15b43e497ffd commit I made a typo and the node name address value
and reg address value differ so I wanted to put that in order.

I?barely remember that my motivation for creating the 15b43e497ffd
commit was that I saw similar change on the mailing list or in the git
log for the other boards using the QCA8K switch. So I "fixed" that
on our board as well.

Now when I was looking for some references I found that there is an
other board in mainline with similarly wrong setting:

arch/arm/boot/dts/qcom/qcom-ipq8064-rb3011.dts

                 switch1: switch at 14 {
                         compatible = "qca,qca8337";

                         dsa,member = <1 0>;

                         pinctrl-0 = <&sw1_reset_pin>;
                         pinctrl-names = "default";

                         reset-gpios = <&qcom_pinmux 17 GPIO_ACTIVE_LOW>;
                         reg = <0x10>;

I admit that my understanding of the MDIO bus and addressing of
the connected external/internal devices is pretty limited. I have no
answer to why it works like that but as you brought up your questions
I would actually like to know as well.

Thank you!
Michal

+Cc: Jonathan McDowell
[1] https://patchwork.kernel.org/project/netdevbpf/patch/1706266175-3408-1-git-send-email-michal.vokac at ysoft.com/


From krzysztof.kozlowski at linaro.org  Tue Feb 13 04:23:52 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 13 Feb 2024 13:23:52 +0100
Subject: [PATCH v2 03/17] ASoC: dt-bindings: fsl,imx-asrc: convert to YAML
In-Reply-To: <20240213010347.1075251-4-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-4-sre@kernel.org>
Message-ID: <7edacc5f-ee3e-456a-93bf-cd4324c03720@linaro.org>

On 13/02/2024 02:00, Sebastian Reichel wrote:
> Convert the i.MX ASRC DT binding to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../devicetree/bindings/sound/fsl,asrc.txt    |  80 ---------
>  .../bindings/sound/fsl,imx-asrc.yaml          | 162 ++++++++++++++++++
>  2 files changed, 162 insertions(+), 80 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/sound/fsl,asrc.txt
>  create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 13 04:27:09 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 13 Feb 2024 13:27:09 +0100
Subject: [PATCH v2 05/17] dt-bindings: soc: imx: fsl,imx-anatop: add
 binding
In-Reply-To: <20240213010347.1075251-6-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-6-sre@kernel.org>
Message-ID: <eaf37a1e-58e2-4cc7-85f9-8cb81537b3b9@linaro.org>

On 13/02/2024 02:00, Sebastian Reichel wrote:
> Add missing binding for i.MX anatop syscon.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../bindings/soc/imx/fsl,imx-anatop.yaml      | 128 ++++++++++++++++++
>  1 file changed, 128 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
> 
> diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
> new file mode 100644
> index 000000000000..5a59e3470510
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
> @@ -0,0 +1,128 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/soc/imx/fsl,imx-anatop.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ANATOP register
> +
> +maintainers:
> +  - Shawn Guo <shawnguo at kernel.org>
> +  - Sascha Hauer <s.hauer at pengutronix.de>
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - enum:
> +              - fsl,imx6sl-anatop
> +              - fsl,imx6sll-anatop
> +              - fsl,imx6sx-anatop
> +              - fsl,imx6ul-anatop
> +              - fsl,imx7d-anatop
> +          - const: fsl,imx6q-anatop
> +          - const: syscon
> +          - const: simple-mfd
> +      - items:
> +          - const: fsl,imx6q-anatop
> +          - const: syscon
> +          - const: simple-mfd
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    items:
> +      - description: Temperature sensor event
> +      - description: Brown-out event on either of the support regulators
> +      - description: Brown-out event on either the core, gpu or soc regulators
> +
> +  tempmon:
> +    type: object
> +    unevaluatedProperties: false
> +    $ref: /schemas/thermal/imx-thermal.yaml

So you just ignored my comment? I did not receive any response from you
on this.

Best regards,
Krzysztof



From ulf.hansson at linaro.org  Tue Feb 13 04:33:08 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 13 Feb 2024 13:33:08 +0100
Subject: [PATCH] pmdomain: arm: Fix NULL dereference on scmi_perf_domain removal
In-Reply-To: <20240125191756.868860-1-cristian.marussi@arm.com>
References: <20240125191756.868860-1-cristian.marussi@arm.com>
Message-ID: <CAPDyKFq=35C6CdbsXmkVSgJ=JyxjMM70tfcWURGMntf6h_u0eA@mail.gmail.com>

On Thu, 25 Jan 2024 at 20:18, Cristian Marussi <cristian.marussi at arm.com> wrote:
>
> On unloading of the scmi_perf_domain module got the below splat, when in
> the DT provided to the system under test the '#power-domain-cells' property
> was missing.
> Indeed, this particular setup causes the probe to bail out early without
> giving any error, so that, then, the removal code is run on unload, but
> without all the expected initialized structures in place.
>
> Add a check and bail out early on remove too.
>
> Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
> Mem abort info:
>    ESR = 0x0000000096000004
>    EC = 0x25: DABT (current EL), IL = 32 bits
>    SET = 0, FnV = 0
>    EA = 0, S1PTW = 0
>    FSC = 0x04: level 0 translation fault
>  Data abort info:
>    ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
>    CM = 0, WnR = 0, TnD = 0, TagAccess = 0
>    GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
>  user pgtable: 4k pages, 48-bit VAs, pgdp=00000001076e5000
>  [0000000000000008] pgd=0000000000000000, p4d=0000000000000000
>  Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
>  Modules linked in: scmi_perf_domain(-) scmi_module scmi_core
>  CPU: 0 PID: 231 Comm: rmmod Not tainted 6.7.0-00084-gb4b1f27d3b83-dirty #15
>  Hardware name: linux,dummy-virt (DT)
>  pstate: 61400005 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
>  pc : scmi_perf_domain_remove+0x28/0x70 [scmi_perf_domain]
>  lr : scmi_perf_domain_remove+0x28/0x70 [scmi_perf_domain]
>  sp : ffff80008393bc10
>  x29: ffff80008393bc10 x28: ffff0000875a8000 x27: 0000000000000000
>  x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
>  x23: ffff00008030c090 x22: ffff00008032d490 x21: ffff80007b287050
>  x20: 0000000000000000 x19: ffff00008032d410 x18: 0000000000000000
>  x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>  x14: 8ba0696d05013a2f x13: 0000000000000000 x12: 0000000000000002
>  x11: 0101010101010101 x10: ffff00008510cff8 x9 : ffff800080a6797c
>  x8 : 0101010101010101 x7 : 7f7f7f7f7f7f7f7f x6 : fefefeff6364626d
>  x5 : 8080808000000000 x4 : 0000000000000020 x3 : 00000000553a3dc1
>  x2 : ffff0000875a8000 x1 : ffff0000875a8000 x0 : ffff800082ffa048
>  Call trace:
>   scmi_perf_domain_remove+0x28/0x70 [scmi_perf_domain]
>   scmi_dev_remove+0x28/0x40 [scmi_core]
>   device_remove+0x54/0x90
>   device_release_driver_internal+0x1dc/0x240
>   driver_detach+0x58/0xa8
>   bus_remove_driver+0x78/0x108
>   driver_unregister+0x38/0x70
>   scmi_driver_unregister+0x28/0x180 [scmi_core]
>   scmi_perf_domain_driver_exit+0x18/0xb78 [scmi_perf_domain]
>   __arm64_sys_delete_module+0x1a8/0x2c0
>   invoke_syscall+0x50/0x128
>   el0_svc_common.constprop.0+0x48/0xf0
>   do_el0_svc+0x24/0x38
>   el0_svc+0x34/0xb8
>   el0t_64_sync_handler+0x100/0x130
>   el0t_64_sync+0x190/0x198
>  Code: a90153f3 f9403c14 f9414800 955f8a05 (b9400a80)
>  ---[ end trace 0000000000000000 ]---
>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: Ulf Hansson <ulf.hansson at linaro.org>
> Fixes: 2af23ceb8624 ("pmdomain: arm: Add the SCMI performance domain")
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>

Applied for fixes - and by amending the commit message a bit,
according to suggestions from Sudeep, thanks!

Kind regards
Uffe


> ---
> I suppose the probe does NOT bail out with an error because this DT config has
> to be supported, right ?
> ---
>  drivers/pmdomain/arm/scmi_perf_domain.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/pmdomain/arm/scmi_perf_domain.c b/drivers/pmdomain/arm/scmi_perf_domain.c
> index 709bbc448fad..d7ef46ccd9b8 100644
> --- a/drivers/pmdomain/arm/scmi_perf_domain.c
> +++ b/drivers/pmdomain/arm/scmi_perf_domain.c
> @@ -159,6 +159,9 @@ static void scmi_perf_domain_remove(struct scmi_device *sdev)
>         struct genpd_onecell_data *scmi_pd_data = dev_get_drvdata(dev);
>         int i;
>
> +       if (!scmi_pd_data)
> +               return;
> +
>         of_genpd_del_provider(dev->of_node);
>
>         for (i = 0; i < scmi_pd_data->num_domains; i++)
> --
> 2.43.0
>


From ulf.hansson at linaro.org  Tue Feb 13 04:33:18 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 13 Feb 2024 13:33:18 +0100
Subject: [PATCH 1/2] pmdomain: constify of_phandle_args in xlate
In-Reply-To: <20240208202822.631449-1-krzysztof.kozlowski@linaro.org>
References: <20240208202822.631449-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CAPDyKFr8rTEaJkQtvZwEsHiYz77hUGb7CvBw9oGfBOzxcWWV3g@mail.gmail.com>

On Thu, 8 Feb 2024 at 21:28, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> The xlate callbacks are supposed to translate of_phandle_args to proper
> provider without modifying the of_phandle_args.  Make the argument
> pointer to const for code safety and readability.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/pmdomain/core.c                     | 4 ++--
>  drivers/pmdomain/imx/scu-pd.c               | 2 +-
>  drivers/pmdomain/tegra/powergate-bpmp.c     | 2 +-
>  drivers/pmdomain/ti/ti_sci_pm_domains.c     | 2 +-
>  drivers/pmdomain/xilinx/zynqmp-pm-domains.c | 2 +-
>  include/linux/pm_domain.h                   | 2 +-
>  6 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> index 46331e71108a..ea4b29475206 100644
> --- a/drivers/pmdomain/core.c
> +++ b/drivers/pmdomain/core.c
> @@ -2266,7 +2266,7 @@ static DEFINE_MUTEX(of_genpd_mutex);
>   * to be a valid pointer to struct generic_pm_domain.
>   */
>  static struct generic_pm_domain *genpd_xlate_simple(
> -                                       struct of_phandle_args *genpdspec,
> +                                       const struct of_phandle_args *genpdspec,
>                                         void *data)
>  {
>         return data;
> @@ -2283,7 +2283,7 @@ static struct generic_pm_domain *genpd_xlate_simple(
>   * the genpd_onecell_data struct when registering the provider.
>   */
>  static struct generic_pm_domain *genpd_xlate_onecell(
> -                                       struct of_phandle_args *genpdspec,
> +                                       const struct of_phandle_args *genpdspec,
>                                         void *data)
>  {
>         struct genpd_onecell_data *genpd_data = data;
> diff --git a/drivers/pmdomain/imx/scu-pd.c b/drivers/pmdomain/imx/scu-pd.c
> index 891c1d925a9d..05841b0bf7f3 100644
> --- a/drivers/pmdomain/imx/scu-pd.c
> +++ b/drivers/pmdomain/imx/scu-pd.c
> @@ -393,7 +393,7 @@ static int imx_sc_pd_power_off(struct generic_pm_domain *domain)
>         return imx_sc_pd_power(domain, false);
>  }
>
> -static struct generic_pm_domain *imx_scu_pd_xlate(struct of_phandle_args *spec,
> +static struct generic_pm_domain *imx_scu_pd_xlate(const struct of_phandle_args *spec,
>                                                   void *data)
>  {
>         struct generic_pm_domain *domain = ERR_PTR(-ENOENT);
> diff --git a/drivers/pmdomain/tegra/powergate-bpmp.c b/drivers/pmdomain/tegra/powergate-bpmp.c
> index 179ed895c279..b0138ca9f851 100644
> --- a/drivers/pmdomain/tegra/powergate-bpmp.c
> +++ b/drivers/pmdomain/tegra/powergate-bpmp.c
> @@ -305,7 +305,7 @@ static void tegra_bpmp_remove_powergates(struct tegra_bpmp *bpmp)
>  }
>
>  static struct generic_pm_domain *
> -tegra_powergate_xlate(struct of_phandle_args *spec, void *data)
> +tegra_powergate_xlate(const struct of_phandle_args *spec, void *data)
>  {
>         struct generic_pm_domain *domain = ERR_PTR(-ENOENT);
>         struct genpd_onecell_data *genpd = data;
> diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c
> index c091d569ecd5..9dddf227a3a6 100644
> --- a/drivers/pmdomain/ti/ti_sci_pm_domains.c
> +++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c
> @@ -85,7 +85,7 @@ static int ti_sci_pd_power_on(struct generic_pm_domain *domain)
>   * @data: genpd core data for all the powerdomains on the device
>   */
>  static struct generic_pm_domain *ti_sci_pd_xlate(
> -                                       struct of_phandle_args *genpdspec,
> +                                       const struct of_phandle_args *genpdspec,
>                                         void *data)
>  {
>         struct genpd_onecell_data *genpd_data = data;
> diff --git a/drivers/pmdomain/xilinx/zynqmp-pm-domains.c b/drivers/pmdomain/xilinx/zynqmp-pm-domains.c
> index 6fd514286d82..0b5831e5ba1b 100644
> --- a/drivers/pmdomain/xilinx/zynqmp-pm-domains.c
> +++ b/drivers/pmdomain/xilinx/zynqmp-pm-domains.c
> @@ -210,7 +210,7 @@ static void zynqmp_gpd_detach_dev(struct generic_pm_domain *domain,
>  }
>
>  static struct generic_pm_domain *zynqmp_gpd_xlate
> -                               (struct of_phandle_args *genpdspec, void *data)
> +                               (const struct of_phandle_args *genpdspec, void *data)
>  {
>         struct genpd_onecell_data *genpd_data = data;
>         unsigned int i, idx = genpdspec->args[0];
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index fb91770ba4ba..1a391ef1b6f8 100644
> --- a/include/linux/pm_domain.h
> +++ b/include/linux/pm_domain.h
> @@ -349,7 +349,7 @@ static inline void dev_pm_genpd_resume(struct device *dev) {}
>  /* OF PM domain providers */
>  struct of_device_id;
>
> -typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args,
> +typedef struct generic_pm_domain *(*genpd_xlate_t)(const struct of_phandle_args *args,
>                                                    void *data);
>
>  struct genpd_onecell_data {
> --
> 2.34.1
>


From ulf.hansson at linaro.org  Tue Feb 13 04:33:21 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 13 Feb 2024 13:33:21 +0100
Subject: [PATCH 2/2] pmdomain: constify of_phandle_args in add device and subdomain
In-Reply-To: <20240208202822.631449-2-krzysztof.kozlowski@linaro.org>
References: <20240208202822.631449-1-krzysztof.kozlowski@linaro.org> <20240208202822.631449-2-krzysztof.kozlowski@linaro.org>
Message-ID: <CAPDyKFpAnrhVWnt-qy3ysT1EGgEB7h6UvoSa6w=faQXqyk+nsA@mail.gmail.com>

On Thu, 8 Feb 2024 at 21:28, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> Pointer to of_phandle_args is not modified by of_genpd_add_device() and
> of_genpd_add_subdomain(), so it can be made pointer to const for code
> safety and readability.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/pmdomain/core.c   | 12 ++++++------
>  include/linux/pm_domain.h | 20 ++++++++++----------
>  2 files changed, 16 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> index ea4b29475206..4215ffd9b11c 100644
> --- a/drivers/pmdomain/core.c
> +++ b/drivers/pmdomain/core.c
> @@ -2526,7 +2526,7 @@ EXPORT_SYMBOL_GPL(of_genpd_del_provider);
>   * on failure.
>   */
>  static struct generic_pm_domain *genpd_get_from_provider(
> -                                       struct of_phandle_args *genpdspec)
> +                                       const struct of_phandle_args *genpdspec)
>  {
>         struct generic_pm_domain *genpd = ERR_PTR(-ENOENT);
>         struct of_genpd_provider *provider;
> @@ -2557,7 +2557,7 @@ static struct generic_pm_domain *genpd_get_from_provider(
>   * Looks-up an I/O PM domain based upon phandle args provided and adds
>   * the device to the PM domain. Returns a negative error code on failure.
>   */
> -int of_genpd_add_device(struct of_phandle_args *genpdspec, struct device *dev)
> +int of_genpd_add_device(const struct of_phandle_args *genpdspec, struct device *dev)
>  {
>         struct generic_pm_domain *genpd;
>         int ret;
> @@ -2591,8 +2591,8 @@ EXPORT_SYMBOL_GPL(of_genpd_add_device);
>   * provided and adds the subdomain to the parent PM domain. Returns a
>   * negative error code on failure.
>   */
> -int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
> -                          struct of_phandle_args *subdomain_spec)
> +int of_genpd_add_subdomain(const struct of_phandle_args *parent_spec,
> +                          const struct of_phandle_args *subdomain_spec)
>  {
>         struct generic_pm_domain *parent, *subdomain;
>         int ret;
> @@ -2629,8 +2629,8 @@ EXPORT_SYMBOL_GPL(of_genpd_add_subdomain);
>   * provided and removes the subdomain from the parent PM domain. Returns a
>   * negative error code on failure.
>   */
> -int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
> -                             struct of_phandle_args *subdomain_spec)
> +int of_genpd_remove_subdomain(const struct of_phandle_args *parent_spec,
> +                             const struct of_phandle_args *subdomain_spec)
>  {
>         struct generic_pm_domain *parent, *subdomain;
>         int ret;
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 1a391ef1b6f8..772d3280d35f 100644
> --- a/include/linux/pm_domain.h
> +++ b/include/linux/pm_domain.h
> @@ -364,11 +364,11 @@ int of_genpd_add_provider_simple(struct device_node *np,
>  int of_genpd_add_provider_onecell(struct device_node *np,
>                                   struct genpd_onecell_data *data);
>  void of_genpd_del_provider(struct device_node *np);
> -int of_genpd_add_device(struct of_phandle_args *args, struct device *dev);
> -int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
> -                          struct of_phandle_args *subdomain_spec);
> -int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
> -                             struct of_phandle_args *subdomain_spec);
> +int of_genpd_add_device(const struct of_phandle_args *args, struct device *dev);
> +int of_genpd_add_subdomain(const struct of_phandle_args *parent_spec,
> +                          const struct of_phandle_args *subdomain_spec);
> +int of_genpd_remove_subdomain(const struct of_phandle_args *parent_spec,
> +                             const struct of_phandle_args *subdomain_spec);
>  struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
>  int of_genpd_parse_idle_states(struct device_node *dn,
>                                struct genpd_power_state **states, int *n);
> @@ -393,20 +393,20 @@ static inline int of_genpd_add_provider_onecell(struct device_node *np,
>
>  static inline void of_genpd_del_provider(struct device_node *np) {}
>
> -static inline int of_genpd_add_device(struct of_phandle_args *args,
> +static inline int of_genpd_add_device(const struct of_phandle_args *args,
>                                       struct device *dev)
>  {
>         return -ENODEV;
>  }
>
> -static inline int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
> -                                        struct of_phandle_args *subdomain_spec)
> +static inline int of_genpd_add_subdomain(const struct of_phandle_args *parent_spec,
> +                                        const struct of_phandle_args *subdomain_spec)
>  {
>         return -ENODEV;
>  }
>
> -static inline int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
> -                                       struct of_phandle_args *subdomain_spec)
> +static inline int of_genpd_remove_subdomain(const struct of_phandle_args *parent_spec,
> +                                           const struct of_phandle_args *subdomain_spec)
>  {
>         return -ENODEV;
>  }
> --
> 2.34.1
>


From arnd at arndb.de  Tue Feb 13 04:45:19 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 13 Feb 2024 13:45:19 +0100
Subject: [PATCH] ASoC: meson: add helpers for clk_disable_unprepare
In-Reply-To: <1j7cj8k2se.fsf@starbuckisacylon.baylibre.com>
References: <20240213101220.459641-1-arnd@kernel.org>
 <1jbk8kk5pk.fsf@starbuckisacylon.baylibre.com>
 <c61d7daf-1b13-4ff8-aeae-7dcd8dd02131@app.fastmail.com>
 <1j7cj8k2se.fsf@starbuckisacylon.baylibre.com>
Message-ID: <bcd477f9-8619-4121-83ce-fa8ba05a36aa@app.fastmail.com>

On Tue, Feb 13, 2024, at 12:09, Jerome Brunet wrote:
> On Tue 13 Feb 2024 at 11:52, "Arnd Bergmann" <arnd at arndb.de> wrote:
>
>> On Tue, Feb 13, 2024, at 11:36, Jerome Brunet wrote:
>>> On Tue 13 Feb 2024 at 11:11, Arnd Bergmann <arnd at kernel.org> wrote:
>>
>>> This probably pre-dates the introduction of devm_clk_get_enabled()
>>> It would probably be better to use that instead of duplicating helper
>>> functions which do the same thing.
>>
>> Ah, I had not thought of that interface either, so you are probably
>> right that this is the best way to do it.
>> Can you send a replacement patch then and add my Reported-by?
>
> Sure.
>
> How may I reproduce the problem ?
> Just tried with 'Debian clang version 16.0.6 (19)', no warning.
>
> I suppose I need to add something ?

The warning is currently only enabled at W=1 level until
we have fixed all the existing diagnostic output. I have
sent the other ones today, but for now, please test with
'make W=1'.

     Arnd


From jgg at ziepe.ca  Tue Feb 13 04:53:03 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 08:53:03 -0400
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
In-Reply-To: <20240213121934.GA28726@willie-the-truck>
References: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
 <20240213121257.GI765010@ziepe.ca>
 <20240213121934.GA28726@willie-the-truck>
Message-ID: <20240213125303.GJ765010@ziepe.ca>

On Tue, Feb 13, 2024 at 12:19:34PM +0000, Will Deacon wrote:
> > > @@ -875,15 +879,6 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
> > >  	mutex_init(&smmu_domain->init_mutex);
> > >  	spin_lock_init(&smmu_domain->cb_lock);
> > >  
> > > -	if (dev) {
> > > -		struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> > > -
> > > -		if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> > > -			kfree(smmu_domain);
> > > -			return NULL;
> > > -		}
> > > -	}
> > > -
> > >  	return &smmu_domain->domain;
> > >  }
> > 
> > Everything else is fine, you already tested with that arrangement.
> 
> Partial reverts are a recipe for confusion, so I'll take this and if you'd
> like to bring back some of the hunks, please can you send a patch on top
> that does that?

The typical kernel standard is to fix bugs in patches and only reach
for a wholesale revert if the community is struggling with bug
fixing. Dmitry already tested removing that hunk, Robin explained the
issue, we understand the bug fix is to remove the
arm_smmu_init_domain_context() call. Nothing justifies a full scale
revert.

I'll send another patch if you want, but it seems like a waste of all
our time.

Jason


From will at kernel.org  Tue Feb 13 04:54:56 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 13 Feb 2024 12:54:56 +0000
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240213121850.GH4048826@nvidia.com>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
 <20240208125846.GA23290@willie-the-truck>
 <20240208142729.GH10476@nvidia.com>
 <20240213112015.GB28517@willie-the-truck>
 <20240213121850.GH4048826@nvidia.com>
Message-ID: <20240213125456.GA28844@willie-the-truck>

Hi Jason,

On Tue, Feb 13, 2024 at 08:18:50AM -0400, Jason Gunthorpe wrote:
> On Tue, Feb 13, 2024 at 11:20:15AM +0000, Will Deacon wrote:
> 
> > Damn, all the surrounding rework has really left this poor code in a bit
> > of a state. 
> 
> That's one way to describe it. There is a reason it took me so many
> patches to align this to the new core APIs :(
> 
> > Could you please respin your fix, but with an additional change
> > to arm_smmu_mmu_notifier_get() so that it returns an error if there is
> > more than one device in the domain, with some of the above in a comment?
> 
> Adding a check is not a comprehensive solution, there are still ways
> userspace can attack this code with iommufd's coming PASID support. It
> certainly doesn't belong in this patch which should be backported.

Ok, then how about avoiding the allocation entirely once the lock is held?
Untested diff below, but you'd call arm_smmu_init_cd_table() from
arm_smmu_sva_set_dev_pasid(). I'd just like to make sure we really do
avoid allocating from atomic context if we end up with a multi-master
domain.

> I can summarize some of these details in a comment for this patch.

Alternatively, we can just revert the offending commits if we're not able
to agree on a simple fix for now. I'd prefer to avoid that though.

Will

--->8

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 0ffb1cf17e0b..8ca92639b13a 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1019,7 +1019,10 @@ static void arm_smmu_write_cd_l1_desc(__le64 *dst,
        WRITE_ONCE(*dst, cpu_to_le64(val));
 }
 
-static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
+static __le64 *
+__arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid,
+                     int (*cd_alloc)(struct arm_smmu_device *,
+                                     struct arm_smmu_l1_ctx_desc *))
 {
        __le64 *l1ptr;
        unsigned int idx;
@@ -1033,7 +1036,7 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
        idx = ssid >> CTXDESC_SPLIT;
        l1_desc = &cd_table->l1_desc[idx];
        if (!l1_desc->l2ptr) {
-               if (arm_smmu_alloc_cd_leaf_table(smmu, l1_desc))
+               if (!cd_alloc || cd_alloc(smmu, l1_desc))
                        return NULL;
 
                l1ptr = cd_table->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
@@ -1045,6 +1048,19 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
        return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS;
 }
 
+static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
+{
+       return __arm_smmu_get_cd_ptr(master, ssid, NULL);
+}
+
+int arm_smmu_init_cd_table(struct arm_smmu_master *master, u32 ssid)
+{
+       if (!__arm_smmu_get_cd_ptr(master, ssid, arm_smmu_alloc_cd_leaf_table))
+               return -ENOMEM;
+
+       return 0;
+}
+
 int arm_smmu_write_ctx_desc(struct arm_smmu_master *master, int ssid,
                            struct arm_smmu_ctx_desc *cd)
 {



From srinivas.kandagatla at linaro.org  Tue Feb 13 04:59:51 2024
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 13 Feb 2024 12:59:51 +0000
Subject: [PATCH V4 0/4] Add ZynqMP efuse access support
In-Reply-To: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
References: <20240202113843.17999-1-praveen.teja.kundanala@amd.com>
Message-ID: <170782919184.32030.17868326404218700363.b4-ty@linaro.org>


On Fri, 02 Feb 2024 17:08:39 +0530, Praveen Teja Kundanala wrote:
>  - Add ZynqMP efuse firmware API for efuse access
>  - zynqmp_nvmem_probe cleanup
>  - Add support to read/write ZynqMP efuse memory
> 
> The first patch depends on
> https://lore.kernel.org/linux-arm-kernel/20231004094116.27128-2-jay.buddhabhatti at amd.com/
> 
> [...]

Applied, thanks!

[1/4] firmware: xilinx: Add ZynqMP efuse access API
      commit: 88f70b7f94747e8e52930a57d6d11d1bd83224c4
[2/4] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
      commit: 71e2473b51515f61c4edd50aa8e841526a2963ae
[3/4] nvmem: zynqmp_nvmem: Add support to access efuse
      commit: fcb1413edbd8b3da53081735b1b1585cbce0e23e
[4/4] MAINTAINERS: Add maintainers for ZynqMP NVMEM driver
      commit: 81ef75cac58fe75554a01db5f34b9c093241c05d

Best regards,
-- 
Srinivas Kandagatla <srinivas.kandagatla at linaro.org>



From will at kernel.org  Tue Feb 13 04:59:52 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 13 Feb 2024 12:59:52 +0000
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
In-Reply-To: <20240213125303.GJ765010@ziepe.ca>
References: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
 <20240213121257.GI765010@ziepe.ca>
 <20240213121934.GA28726@willie-the-truck>
 <20240213125303.GJ765010@ziepe.ca>
Message-ID: <20240213125951.GB28844@willie-the-truck>

On Tue, Feb 13, 2024 at 08:53:03AM -0400, Jason Gunthorpe wrote:
> On Tue, Feb 13, 2024 at 12:19:34PM +0000, Will Deacon wrote:
> > > > @@ -875,15 +879,6 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
> > > >  	mutex_init(&smmu_domain->init_mutex);
> > > >  	spin_lock_init(&smmu_domain->cb_lock);
> > > >  
> > > > -	if (dev) {
> > > > -		struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> > > > -
> > > > -		if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> > > > -			kfree(smmu_domain);
> > > > -			return NULL;
> > > > -		}
> > > > -	}
> > > > -
> > > >  	return &smmu_domain->domain;
> > > >  }
> > > 
> > > Everything else is fine, you already tested with that arrangement.
> > 
> > Partial reverts are a recipe for confusion, so I'll take this and if you'd
> > like to bring back some of the hunks, please can you send a patch on top
> > that does that?
> 
> The typical kernel standard is to fix bugs in patches and only reach
> for a wholesale revert if the community is struggling with bug
> fixing. Dmitry already tested removing that hunk, Robin explained the
> issue, we understand the bug fix is to remove the
> arm_smmu_init_domain_context() call. Nothing justifies a full scale
> revert.

I can't say I'm aware of any consensus for how to handle this, to be
completely honest with you. I just personally see a lot of benefit in
reverting to a known-good state, especially when the revert has been
posted by the bug reporter. Then we can add stuff on top of that known
good state without having to worry about any other problems that we're
yet to uncover. Doesn't really sound controversial...

> I'll send another patch if you want, but it seems like a waste of all
> our time.

It's a bug fix, of course it's a waste of time! We're talking minutes
though, right?

Will


From zajec5 at gmail.com  Tue Feb 13 05:00:43 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 13 Feb 2024 14:00:43 +0100
Subject: [PATCH 1/2] dt-bindings: usb: mtk-xhci: add compatible for MT7988
Message-ID: <20240213130044.1976-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

MT7988 SoC contains two on-SoC XHCI controllers. Add proper binding.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
index 924fd3d748a8..ef3143f4b794 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
@@ -29,6 +29,7 @@ properties:
           - mediatek,mt7623-xhci
           - mediatek,mt7629-xhci
           - mediatek,mt7986-xhci
+          - mediatek,mt7988-xhci
           - mediatek,mt8173-xhci
           - mediatek,mt8183-xhci
           - mediatek,mt8186-xhci
-- 
2.35.3



From zajec5 at gmail.com  Tue Feb 13 05:00:44 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 13 Feb 2024 14:00:44 +0100
Subject: [PATCH 2/2] arm64: dts: mediatek: mt7988: add XHCI controllers
In-Reply-To: <20240213130044.1976-1-zajec5@gmail.com>
References: <20240213130044.1976-1-zajec5@gmail.com>
Message-ID: <20240213130044.1976-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Add bindings of two on-SoC XHCI controllers.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 32 ++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index bba97de4fb44..3eb5396dea22 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0-only OR MIT
 
+#include <dt-bindings/clock/mediatek,mt7988-clk.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
 
 / {
 	compatible = "mediatek,mt7988a";
@@ -78,7 +80,7 @@ gic: interrupt-controller at c000000 {
 			#interrupt-cells = <3>;
 		};
 
-		clock-controller at 10001000 {
+		infracfg: clock-controller at 10001000 {
 			compatible = "mediatek,mt7988-infracfg", "syscon";
 			reg = <0 0x10001000 0 0x1000>;
 			#clock-cells = <1>;
@@ -103,6 +105,34 @@ clock-controller at 1001e000 {
 			#clock-cells = <1>;
 		};
 
+		usb at 11190000 {
+			compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
+			reg = <0 0x11190000 0 0x2e00>,
+			      <0 0x11193e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_USB_SYS>,
+				 <&infracfg CLK_INFRA_USB_REF>,
+				 <&infracfg CLK_INFRA_66M_USB_HCK>,
+				 <&infracfg CLK_INFRA_133M_USB_HCK>,
+				 <&infracfg CLK_INFRA_USB_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
+		};
+
+		usb at 11200000 {
+			compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
+			reg = <0 0x11200000 0 0x2e00>,
+			      <0 0x11203e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_USB_SYS_CK_P1>,
+				 <&infracfg CLK_INFRA_USB_CK_P1>,
+				 <&infracfg CLK_INFRA_66M_USB_HCK_CK_P1>,
+				 <&infracfg CLK_INFRA_133M_USB_HCK_CK_P1>,
+				 <&infracfg CLK_INFRA_USB_XHCI_CK_P1>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
+		};
+
 		clock-controller at 11f40000 {
 			compatible = "mediatek,mt7988-xfi-pll";
 			reg = <0 0x11f40000 0 0x1000>;
-- 
2.35.3



From daniel.lezcano at linaro.org  Tue Feb 13 05:03:39 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Tue, 13 Feb 2024 14:03:39 +0100
Subject: [PATCH] dt-bindings: timer: renesas: ostm: Document RZ/Five SoC
In-Reply-To: <CA+V-a8tN-qn8zuimte=-riahJBWGgGi8i5botNfWqdWwJ7w-4g@mail.gmail.com>
References: <20231115212908.33131-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <CA+V-a8tN-qn8zuimte=-riahJBWGgGi8i5botNfWqdWwJ7w-4g@mail.gmail.com>
Message-ID: <6092ee3a-4a28-488b-97fe-538e619f8983@linaro.org>

On 13/02/2024 11:22, Lad, Prabhakar wrote:
> Hi Daniel,
> 
> On Wed, Nov 15, 2023 at 9:29?PM Prabhakar <prabhakar.csengg at gmail.com> wrote:
>>
>> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
>>
>> The OSTM block on the RZ/Five SoC is identical to one found on the RZ/G2UL
>> SoC. "renesas,r9a07g043-ostm" compatible string will be used on the RZ/Five
>> SoC so to make this clear and to keep this file consistent, update the
>> comment to include RZ/Five SoC.
>>
>> No driver changes are required as generic compatible string "renesas,ostm"
>> will be used as a fallback on RZ/Five SoC.
>>
>> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
>> ---
>>   Documentation/devicetree/bindings/timer/renesas,ostm.yaml | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
> Gentle ping!

Applied, thanks for the head up

-- 
<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 ryan.roberts at arm.com  Tue Feb 13 05:03:53 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 13:03:53 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <ZctaaeVFF8TpjA8Z@FVFF77S0Q05N.cambridge.arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <ZctaaeVFF8TpjA8Z@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <d2ca1de5-d833-4806-a5a2-75410e1f731a@arm.com>

On 13/02/2024 12:02, Mark Rutland wrote:
> On Mon, Feb 12, 2024 at 12:59:57PM +0000, Ryan Roberts wrote:
>> On 12/02/2024 12:00, Mark Rutland wrote:
>>> Hi Ryan,
> 
> [...]
> 
>>>> +static inline void set_pte(pte_t *ptep, pte_t pte)
>>>> +{
>>>> +	/*
>>>> +	 * We don't have the mm or vaddr so cannot unfold contig entries (since
>>>> +	 * it requires tlb maintenance). set_pte() is not used in core code, so
>>>> +	 * this should never even be called. Regardless do our best to service
>>>> +	 * any call and emit a warning if there is any attempt to set a pte on
>>>> +	 * top of an existing contig range.
>>>> +	 */
>>>> +	pte_t orig_pte = __ptep_get(ptep);
>>>> +
>>>> +	WARN_ON_ONCE(pte_valid_cont(orig_pte));
>>>> +	__set_pte(ptep, pte_mknoncont(pte));
>>>> +}
>>>> +
>>>> +#define set_ptes set_ptes
>>>> +static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
>>>> +				pte_t *ptep, pte_t pte, unsigned int nr)
>>>> +{
>>>> +	pte = pte_mknoncont(pte);
>>>
>>> Why do we have to clear the contiguous bit here? Is that for the same reason as
>>> set_pte(), or do we expect callers to legitimately call this with the
>>> contiguous bit set in 'pte'?
>>>
>>> I think you explained this to me in-person, and IIRC we don't expect callers to
>>> go set the bit themselves, but since it 'leaks' out to them via __ptep_get() we
>>> have to clear it here to defer the decision of whether to set/clear it when
>>> modifying entries. It would be nice if we could have a description of why/when
>>> we need to clear this, e.g. in the 'public API' comment block above.
>>
>> Yes, I think you've got it, but just to ram home the point: The PTE_CONT bit is
>> private to the architecture code and is never set directly by core code. If the
>> public API ever receives a pte that happens to have the PTE_CONT bit set, it
>> would be bad news if we then accidentally set that in the pgtable.
>>
>> Ideally, we would just uncondidtionally clear the bit before a getter returns
>> the pte (e.g. ptep_get(), ptep_get_lockless(), ptep_get_and_clear(), ...). That
>> way, the code code is guarranteed never to see a pte with the PTE_CONT bit set
>> and can therefore never accidentally pass such a pte into a setter function.
>> However, there is existing functionality that relies on being able to get a pte,
>> then pass it to pte_leaf_size(), and arch function that checks the PTE_CONT bit
>> to determine how big the leaf is. This is used in perf_get_pgtable_size().
>>
>> So to allow perf_get_pgtable_size() to continue to see the "real" page size, I
>> decided to allow PTE_CONT to leak through the getters and instead
>> unconditionally clear the bit when a pte is passed to any of the setters.
>>
>> I'll add a (slightly less verbose) comment as you suggest.
> 
> Great, thanks!
> 
> [...]
> 
>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>> +{
>>>> +	/*
>>>> +	 * Don't attempt to apply the contig bit to kernel mappings, because
>>>> +	 * dynamically adding/removing the contig bit can cause page faults.
>>>> +	 * These racing faults are ok for user space, since they get serialized
>>>> +	 * on the PTL. But kernel mappings can't tolerate faults.
>>>> +	 */
>>>> +	return mm != &init_mm;
>>>> +}
>>>
>>> We also have the efi_mm as a non-user mm, though I don't think we manipulate
>>> that while it is live, and I'm not sure if that needs any special handling.
>>
>> Well we never need this function in the hot (order-0 folio) path, so I think I
>> could add a check for efi_mm here with performance implication. It's probably
>> safest to explicitly exclude it? What do you think?
> 
> That sounds ok to me.
> 
> Otherwise, if we (somehow) know that we avoid calling this at all with an EFI
> mm (e.g. because of the way we construct that), I'd be happy with a comment.

We crossed streams - as per my other email, I'm confident that this is safe so
will just add a comment.

> 
> Probably best to Cc Ard for whatever we do here.

Ard is already on CC.

> 
>>>> +static inline pte_t *contpte_align_down(pte_t *ptep)
>>>> +{
>>>> +	return (pte_t *)(ALIGN_DOWN((unsigned long)ptep >> 3, CONT_PTES) << 3);
>>>
>>> I think this can be:
>>>
>>> static inline pte_t *contpte_align_down(pte_t *ptep)
>>> {
>>> 	return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
>>> }
>>
>> Yep - that's much less ugly - thanks!
>>
>>>
>>>> +
>>>> +static void contpte_convert(struct mm_struct *mm, unsigned long addr,
>>>> +			    pte_t *ptep, pte_t pte)
>>>> +{
>>>> +	struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0);
>>>> +	unsigned long start_addr;
>>>> +	pte_t *start_ptep;
>>>> +	int i;
>>>> +
>>>> +	start_ptep = ptep = contpte_align_down(ptep);
>>>> +	start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
>>>> +	pte = pfn_pte(ALIGN_DOWN(pte_pfn(pte), CONT_PTES), pte_pgprot(pte));
>>>> +
>>>> +	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) {
>>>> +		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
>>>> +
>>>> +		if (pte_dirty(ptent))
>>>> +			pte = pte_mkdirty(pte);
>>>> +
>>>> +		if (pte_young(ptent))
>>>> +			pte = pte_mkyoung(pte);
>>>> +	}
>>>
>>> Not a big deal either way, but I wonder if it makes more sense to accumulate
>>> the 'ptent' dirty/young values, then modify 'pte' once, i.e.
>>>
>>> 	bool dirty = false, young = false;
>>>
>>> 	for (...) {
>>> 		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
>>> 		dirty |= pte_dirty(ptent);
>>> 		young |= pte_young(ptent);
>>> 	}
>>>
>>> 	if (dirty)
>>> 		pte_mkdirty(pte);
>>> 	if (young)
>>> 		pte_mkyoung(pte);
>>>
>>> I suspect that might generate slightly better code, but I'm also happy with the
>>> current form if people thnk that's more legible (I have no strong feelings
>>> either way).
>>
>> I kept it this way, because its the same pattern used in arm64's hugetlbpage.c.
>> We also had the same comment against David's batching patches recently, and he
>> opted to stick with the former version:
>>
>> https://lore.kernel.org/linux-mm/d83309fa-4daa-430f-ae52-4e72162bca9a at redhat.com/
>>
>> So I'm inclined to leave it as is, since you're not insisting :)
> 
> That rationale is reasonable, and I'm fine with this as-is.
> 
> [...]
> 
>>>> +pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
>>>> +{
>>>> +	/*
>>>> +	 * Gather access/dirty bits, which may be populated in any of the ptes
>>>> +	 * of the contig range. We may not be holding the PTL, so any contiguous
>>>> +	 * range may be unfolded/modified/refolded under our feet. Therefore we
>>>> +	 * ensure we read a _consistent_ contpte range by checking that all ptes
>>>> +	 * in the range are valid and have CONT_PTE set, that all pfns are
>>>> +	 * contiguous and that all pgprots are the same (ignoring access/dirty).
>>>> +	 * If we find a pte that is not consistent, then we must be racing with
>>>> +	 * an update so start again. If the target pte does not have CONT_PTE
>>>> +	 * set then that is considered consistent on its own because it is not
>>>> +	 * part of a contpte range.
>>>> +	 */
>>>> +
>>>> +	pgprot_t orig_prot;
>>>> +	unsigned long pfn;
>>>> +	pte_t orig_pte;
>>>> +	pgprot_t prot;
>>>> +	pte_t *ptep;
>>>> +	pte_t pte;
>>>> +	int i;
>>>> +
>>>> +retry:
>>>> +	orig_pte = __ptep_get(orig_ptep);
>>>> +
>>>> +	if (!pte_valid_cont(orig_pte))
>>>> +		return orig_pte;
>>>> +
>>>> +	orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
>>>> +	ptep = contpte_align_down(orig_ptep);
>>>> +	pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
>>>> +
>>>> +	for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
>>>> +		pte = __ptep_get(ptep);
>>>> +		prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
>>>> +
>>>> +		if (!pte_valid_cont(pte) ||
>>>> +		   pte_pfn(pte) != pfn ||
>>>> +		   pgprot_val(prot) != pgprot_val(orig_prot))
>>>> +			goto retry;
>>>> +
>>>> +		if (pte_dirty(pte))
>>>> +			orig_pte = pte_mkdirty(orig_pte);
>>>> +
>>>> +		if (pte_young(pte))
>>>> +			orig_pte = pte_mkyoung(orig_pte);
>>>> +	}
>>>> +
>>>> +	return orig_pte;
>>>> +}
>>>> +EXPORT_SYMBOL(contpte_ptep_get_lockless);
>>>
>>> I'm struggling to convince myself that this is safe in general, as it really
>>> depends on how the caller will use this value. Which caller(s) actually care
>>> about the access/dirty bits, given those could change at any time anyway?
>>
>> I think your points below are valid, and agree we should try to make this work
>> without needing access/dirty if possible. But can you elaborate on why you don't
>> think it's safe?
> 
> Having mulled this over, I think it is safe as-is, and I was being overly
> cautious.
> 
> I had a general fear of potential problems stemming from the fact that (a) the
> accumulation of access/dirty bits isn't atomic and (b) the loop is unbounded.
> From looking at how this is used today, I think (a) is essentially the same as
> reading a stale non-contiguous entry, and I'm being overly cautious there. For
> (b), I think that's largely a performance concern and the would only retry
> indefinitely in the presence of mis-programmed entries or consistent racing
> with a writer under heavy contention.
> 
> I think it's still desirable to avoid the accumulation in most cases (to avoid
> redundant work and to minimize the potential for unbounded retries), but I'm
> happy with that being a follow-up improvement.

Great! I'll do the conversion to ptep_get_lockless_nosync() as a follow up series.

> 
>>> I took a quick scan, and AFAICT:
>>
>> Thanks for enumerating these; Saves me from having to refresh my memory :)
>>>
>>> * For perf_get_pgtable_size(), we only care about whether the entry is valid
>>>   and has the contig bit set. We could clean that up with a new interface, e.g.
>>>   something like a new ptep_get_size_lockless().
>>>
>>> * For gup_pte_range(), I'm not sure we actually need the access/dirty bits when
>>>   we look at the pte to start with, since we only care where we can logically
>>>   write to the page at that point.
>>>
>>>   I see that we later follow up with:
>>>
>>>     with pte_val(pte) != pte_val(ptep_get(ptep)))
>>>
>>>   ... is that why we need ptep_get_lockless() to accumulate the access/dirty
>>>   bits? So that shape of lockless-try...locked-compare sequence works?
>>>
>>> * For huge_pte_alloc(), arm64 doesn't select CONFIG_ARCH_WANT_GENERAL_HUGETLB,
>>>   so this doesn' seem to matter.
>>>
>>> * For __collapse_huge_page_swapin(), we only care if the pte is a swap pte,
>>>   which means the pte isn't valid, and we'll return the orig_pte as-is anyway.
>>>
>>> * For pte_range_none() the access/dirty bits don't matter.
>>>
>>> * For handle_pte_fault() I think we have the same shape of
>>>   lockless-try...locked-compare sequence as for gup_pte_range(), where we don't
>>>   care about the acess/dirty bits before we reach the locked compare step.
>>>
>>> * For ptdump_pte_entry() I think it's arguable that we should continue to
>>>   report the access/dirty bits separately for each PTE, as we have done until
>>>   now, to give an accurate representation of the contents of the translation
>>>   tables.
>>>
>>> * For swap_vma_readahead() and unuse_pte_range() we only care if the PTE is a
>>>   swap entry, the access/dirty bits don't matter.
>>>
>>> So AFAICT this only really matters for gup_pte_range() and handle_pte_fault(),
>>> and IIUC that's only so that the locklessly-loaded pte value can be compared
>>> with a subsequently locked-loaded entry (for which the access/dirty bits will
>>> be accumulated). Have I understood that correctly?
>>
>> Yes, I agree with what you are saying. My approach was to try to implement the
>> existing APIs accurately though, the argument being that it reduces the chances
>> of getting it wrong. But if you think the implementation is unsafe, then I guess
>> it blows that out of the water...
> 
> I think your approach makes sense, and as above I'm happy to defer the API
> changes/additions to avoid the accumulation of access/dirty bits.
> 
>>> If so, I wonder if we could instead do that comparison modulo the access/dirty
>>> bits, 
>>
>> I think that would work - but will need to think a bit more on it.
>>
>>> and leave ptep_get_lockless() only reading a single entry?
>>
>> I think we will need to do something a bit less fragile. ptep_get() does collect
>> the access/dirty bits so its confusing if ptep_get_lockless() doesn't IMHO. So
>> we will likely want to rename the function and make its documentation explicit
>> that it does not return those bits.
>>
>> ptep_get_lockless_noyoungdirty()? yuk... Any ideas?
>>
>> Of course if I could convince you the current implementation is safe, I might be
>> able to sidestep this optimization until a later date?
> 
> Yep. :)
> 
> Mark.



From ryan.roberts at arm.com  Tue Feb 13 05:06:34 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 13:06:34 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <41499621-482f-455b-9f68-b43ea8052557@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
 <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com>
Message-ID: <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>

On 13/02/2024 12:19, David Hildenbrand wrote:
> On 13.02.24 13:06, Ryan Roberts wrote:
>> On 12/02/2024 20:38, Ryan Roberts wrote:
>>> [...]
>>>
>>>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>>>> +{
>>>>>>> +??? /*
>>>>>>> +???? * Don't attempt to apply the contig bit to kernel mappings, because
>>>>>>> +???? * dynamically adding/removing the contig bit can cause page faults.
>>>>>>> +???? * These racing faults are ok for user space, since they get serialized
>>>>>>> +???? * on the PTL. But kernel mappings can't tolerate faults.
>>>>>>> +???? */
>>>>>>> +??? return mm != &init_mm;
>>>>>>> +}
>>>>>>
>>>>>> We also have the efi_mm as a non-user mm, though I don't think we manipulate
>>>>>> that while it is live, and I'm not sure if that needs any special handling.
>>>>>
>>>>> Well we never need this function in the hot (order-0 folio) path, so I think I
>>>>> could add a check for efi_mm here with performance implication. It's probably
>>>>> safest to explicitly exclude it? What do you think?
>>>>
>>>> Oops: This should have read "I think I could add a check for efi_mm here
>>>> *without* performance implication"
>>>
>>> It turns out that efi_mm is only defined when CONFIG_EFI is enabled. I can do
>>> this:
>>>
>>> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
>>>
>>> Is that acceptable? This is my preference, but nothing else outside of efi
>>> references this symbol currently.
>>>
>>> Or perhaps I can convince myself that its safe to treat efi_mm like userspace.
>>> There are a couple of things that need to be garanteed for it to be safe:
>>>
>>> ?? - The PFNs of present ptes either need to have an associated struct page or
>>> ???? need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
>>> ???? pte_mkdevmap())
>>>
>>> ?? - Live mappings must either be static (no changes that could cause
>>> fold/unfold
>>> ???? while live) or the system must be able to tolerate a temporary fault
>>>
>>> Mark suggests efi_mm is not manipulated while live, so that meets the latter
>>> requirement, but I'm not sure about the former?
>>
>> I've gone through all the efi code, and conclude that, as Mark suggests, the
>> mappings are indeed static. And additionally, the ptes are populated using only
>> the _private_ ptep API, so there is no issue here. As just discussed with Mark,
>> my prefereence is to not make any changes to code, and just add a comment
>> describing why efi_mm is safe.
>>
>> Details:
>>
>> * Registered with ptdump
>> ???? * ptep_get_lockless()
>> * efi_create_mapping -> create_pgd_mapping ? -> init_pte:
>> ???? * __ptep_get()
>> ???? * __set_pte()
>> * efi_memattr_apply_permissions -> efi_set_mapping_permissions ? ->
>> set_permissions
>> ???? * __ptep_get()
>> ???? * __set_pte()
> 
> Sound good. We could add some VM_WARN_ON if we ever get the efi_mm via the
> "official" APIs.

We could, but that would lead to the same linkage issue, which I'm trying to
avoid in the first place:

VM_WARN_ON(IS_ENABLED(CONFIG_EFI) && mm == efi_mm);

This creates new source code dependencies, which I would rather avoid if possible.



From srinivas.kandagatla at linaro.org  Tue Feb 13 05:07:20 2024
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 13 Feb 2024 13:07:20 +0000
Subject: [PATCH 3/3] nvmem: mtk-efuse: Drop NVMEM device name
In-Reply-To: <20240130095656.3712469-4-wenst@chromium.org>
References: <20240130095656.3712469-1-wenst@chromium.org>
 <20240130095656.3712469-4-wenst@chromium.org>
Message-ID: <92d4d421-54a8-4a41-8b47-61ae39b55ebb@linaro.org>



On 30/01/2024 09:56, Chen-Yu Tsai wrote:
> The MT8183 has not one but two efuse devices. The static name and ID
> causes the second efuse device to fail to probe, due to duplicate sysfs
> entries.

have you considered using NVMEM_DEVID_AUTO?

--srini
> 
> With the rework of the mtk-socinfo driver, lookup by name is no longer
> necessary. The custom name can simply be dropped.
> 
> Fixes: 4e6102d60d88 ("nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>   drivers/nvmem/mtk-efuse.c | 1 -
>   1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/nvmem/mtk-efuse.c b/drivers/nvmem/mtk-efuse.c
> index f5bebcecf9bd..9caf04667341 100644
> --- a/drivers/nvmem/mtk-efuse.c
> +++ b/drivers/nvmem/mtk-efuse.c
> @@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platform_device *pdev)
>   	econfig.size = resource_size(res);
>   	econfig.priv = priv;
>   	econfig.dev = dev;
> -	econfig.name = "mtk-efuse";
>   	if (pdata->uses_post_processing)
>   		econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
>   	nvmem = devm_nvmem_register(dev, &econfig);


From andrew at lunn.ch  Tue Feb 13 05:10:42 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 13 Feb 2024 14:10:42 +0100
Subject: [PATCH 1/2] ARM: dts: imx6dl-yapp4: Fix the QCA switch register
 address
In-Reply-To: <db282aa5-2db3-49b9-a7dd-86e94226aa7b@ysoft.com>
References: <1707751422-31517-1-git-send-email-michal.vokac@ysoft.com>
 <c5dad8e7-c486-4dd9-bfb5-bdfa2ddc18b3@lunn.ch>
 <db282aa5-2db3-49b9-a7dd-86e94226aa7b@ysoft.com>
Message-ID: <e00ed8cb-f73d-48a6-9999-f5acd5a202a0@lunn.ch>

On Tue, Feb 13, 2024 at 01:20:44PM +0100, Michal Vok?? wrote:
> On 12. 02. 24 17:08, Andrew Lunn wrote:
> > On Mon, Feb 12, 2024 at 04:23:41PM +0100, Michal Vok?? wrote:
> > > The switch address in the node name is in hex while the address in the reg
> > > property is decimal which is wrong. Fix that and write the reg address
> > > as a hexadecimal number.
> > 
> > This feels the wrong way around. The reg value is used by the kernel,
> > where as the node name is not. If the reg value was wrong, the switch
> > would not be found. If this file was tested, why did somebody not
> > notice the switch was missing?
> > 
> > Do you have the hardware? Can you confirm is really does not work
> > without this patch? Was 15b43e497ffd never actually tested?
> Yes, I have bunch of these boards all around my desk - we manufacture
> them. I am pretty sure I tested all the patches I have ever sent to
> the mailing list regarding these boards.
> 
> The fact is that the switch actually works regardless of the reg value.
> It worked prior to the 15b43e497ffd commit with address 0, it worked
> later on with the reg value 10 and it works now with reg value 0x10.

Ah, so that is the missing piece of information from the commit
message. That the reg value does not actually matter. Hence it is safe
to change it.

Please reword the commit message.

> I admit that my understanding of the MDIO bus and addressing of
> the connected external/internal devices is pretty limited. I have no
> answer to why it works like that but as you brought up your questions
> I would actually like to know as well.

My guess is, the switch assumes it has full access to all the
addresses on the bus. It probably uses a subset, but that subset is
hard coded. But the MDIO DT binding requires a valid reg value, so
something has to be used.

There are some devices which use a single address on the bus. The
mv88e6xxx can be strapped into such a mode, so you can have multiple
switches on the bus. The reg value is then used. But you can also
strap it so it takes over the whole bus, and uses #num_ports + 3
addresses on the bus, and those addresses are hard coded in the
silicon, so the reg value is ignored.

    Andrew

---
pw-bot: cr


From david at redhat.com  Tue Feb 13 05:13:26 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 13 Feb 2024 14:13:26 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
 <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com>
 <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
Message-ID: <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com>

On 13.02.24 14:06, Ryan Roberts wrote:
> On 13/02/2024 12:19, David Hildenbrand wrote:
>> On 13.02.24 13:06, Ryan Roberts wrote:
>>> On 12/02/2024 20:38, Ryan Roberts wrote:
>>>> [...]
>>>>
>>>>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>>>>> +{
>>>>>>>> +??? /*
>>>>>>>> +???? * Don't attempt to apply the contig bit to kernel mappings, because
>>>>>>>> +???? * dynamically adding/removing the contig bit can cause page faults.
>>>>>>>> +???? * These racing faults are ok for user space, since they get serialized
>>>>>>>> +???? * on the PTL. But kernel mappings can't tolerate faults.
>>>>>>>> +???? */
>>>>>>>> +??? return mm != &init_mm;
>>>>>>>> +}
>>>>>>>
>>>>>>> We also have the efi_mm as a non-user mm, though I don't think we manipulate
>>>>>>> that while it is live, and I'm not sure if that needs any special handling.
>>>>>>
>>>>>> Well we never need this function in the hot (order-0 folio) path, so I think I
>>>>>> could add a check for efi_mm here with performance implication. It's probably
>>>>>> safest to explicitly exclude it? What do you think?
>>>>>
>>>>> Oops: This should have read "I think I could add a check for efi_mm here
>>>>> *without* performance implication"
>>>>
>>>> It turns out that efi_mm is only defined when CONFIG_EFI is enabled. I can do
>>>> this:
>>>>
>>>> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
>>>>
>>>> Is that acceptable? This is my preference, but nothing else outside of efi
>>>> references this symbol currently.
>>>>
>>>> Or perhaps I can convince myself that its safe to treat efi_mm like userspace.
>>>> There are a couple of things that need to be garanteed for it to be safe:
>>>>
>>>>  ?? - The PFNs of present ptes either need to have an associated struct page or
>>>>  ???? need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
>>>>  ???? pte_mkdevmap())
>>>>
>>>>  ?? - Live mappings must either be static (no changes that could cause
>>>> fold/unfold
>>>>  ???? while live) or the system must be able to tolerate a temporary fault
>>>>
>>>> Mark suggests efi_mm is not manipulated while live, so that meets the latter
>>>> requirement, but I'm not sure about the former?
>>>
>>> I've gone through all the efi code, and conclude that, as Mark suggests, the
>>> mappings are indeed static. And additionally, the ptes are populated using only
>>> the _private_ ptep API, so there is no issue here. As just discussed with Mark,
>>> my prefereence is to not make any changes to code, and just add a comment
>>> describing why efi_mm is safe.
>>>
>>> Details:
>>>
>>> * Registered with ptdump
>>>  ???? * ptep_get_lockless()
>>> * efi_create_mapping -> create_pgd_mapping ? -> init_pte:
>>>  ???? * __ptep_get()
>>>  ???? * __set_pte()
>>> * efi_memattr_apply_permissions -> efi_set_mapping_permissions ? ->
>>> set_permissions
>>>  ???? * __ptep_get()
>>>  ???? * __set_pte()
>>
>> Sound good. We could add some VM_WARN_ON if we ever get the efi_mm via the
>> "official" APIs.
> 
> We could, but that would lead to the same linkage issue, which I'm trying to
> avoid in the first place:
> 
> VM_WARN_ON(IS_ENABLED(CONFIG_EFI) && mm == efi_mm);
> 
> This creates new source code dependencies, which I would rather avoid if possible.

Just a thought, you could have a is_efi_mm() function that abstracts all that.

diff --git a/include/linux/efi.h b/include/linux/efi.h
index c74f47711f0b..152f5fa66a2a 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -692,6 +692,15 @@ extern struct efi {
  
  extern struct mm_struct efi_mm;
  
+static inline void is_efi_mm(struct mm_struct *mm)
+{
+#ifdef CONFIG_EFI
+       return mm == &efi_mm;
+#else
+       return false;
+#endif
+}
+
  static inline int
  efi_guidcmp (efi_guid_t left, efi_guid_t right)
  {


-- 
Cheers,

David / dhildenb



From robh at kernel.org  Tue Feb 13 05:14:05 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 07:14:05 -0600
Subject: [PATCH v2 01/12] spi: dt-bindings: introduce FIFO depth
 properties
In-Reply-To: <20240212140331.915498-2-tudor.ambarus@linaro.org>
References: <20240212140331.915498-1-tudor.ambarus@linaro.org>
 <20240212140331.915498-2-tudor.ambarus@linaro.org>
Message-ID: <20240213131405.GA1047438-robh@kernel.org>

On Mon, Feb 12, 2024 at 02:03:20PM +0000, Tudor Ambarus wrote:
> There are SPI IPs that can be configured by the integrator with a
> specific FIFO depth depending on the system's capabilities. For example,
> the samsung USI SPI IP can be configured by the integrator with a TX/RX
> FIFO from 8 byte to 256 bytes.
> 
> Introduce the ``fifo-depth`` property for such instances of IPs where the
> same FIFO depth is used for both RX and TX. Introduce ``rx-fifo-depth``
> and ``tx-fifo-depth`` properties for cases where the RX FIFO depth is
> different from the TX FIFO depth.
> 
> Make the dedicated RX/TX properties dependent on each other and mutual
> exclusive with the other.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  .../bindings/spi/spi-controller.yaml          | 27 +++++++++++++++++++
>  1 file changed, 27 insertions(+)

With the indentation fixed,

Reviewed-by: Rob Herring <robh at kernel.org>


From will at kernel.org  Tue Feb 13 05:19:52 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 13 Feb 2024 13:19:52 +0000
Subject: [PATCH] iommu/arm-smmu-qcom: Add X1E80100 MDSS compatible
In-Reply-To: <20240131-x1e80100-iommu-arm-smmu-qcom-v1-1-c1240419c718@linaro.org>
References: <20240131-x1e80100-iommu-arm-smmu-qcom-v1-1-c1240419c718@linaro.org>
Message-ID: <20240213131952.GB28926@willie-the-truck>

On Wed, Jan 31, 2024 at 02:35:16PM +0200, Abel Vesa wrote:
> Add the X1E80100 MDSS compatible to clients compatible list, as it also
> needs the workarounds.
> 
> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 8b04ece00420..5c7cfc51b57c 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -260,6 +260,7 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
>  	{ .compatible = "qcom,sm6375-mdss" },
>  	{ .compatible = "qcom,sm8150-mdss" },
>  	{ .compatible = "qcom,sm8250-mdss" },
> +	{ .compatible = "qcom,x1e80100-mdss" },

I think this needs adding to the bindings Documentation first.

Will


From ryan.roberts at arm.com  Tue Feb 13 05:20:55 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 13:20:55 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
 <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com>
 <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
 <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com>
Message-ID: <dce5f80d-942f-439c-a549-5290666464ca@arm.com>

On 13/02/2024 13:13, David Hildenbrand wrote:
> On 13.02.24 14:06, Ryan Roberts wrote:
>> On 13/02/2024 12:19, David Hildenbrand wrote:
>>> On 13.02.24 13:06, Ryan Roberts wrote:
>>>> On 12/02/2024 20:38, Ryan Roberts wrote:
>>>>> [...]
>>>>>
>>>>>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>>>>>> +{
>>>>>>>>> +??? /*
>>>>>>>>> +???? * Don't attempt to apply the contig bit to kernel mappings, because
>>>>>>>>> +???? * dynamically adding/removing the contig bit can cause page faults.
>>>>>>>>> +???? * These racing faults are ok for user space, since they get
>>>>>>>>> serialized
>>>>>>>>> +???? * on the PTL. But kernel mappings can't tolerate faults.
>>>>>>>>> +???? */
>>>>>>>>> +??? return mm != &init_mm;
>>>>>>>>> +}
>>>>>>>>
>>>>>>>> We also have the efi_mm as a non-user mm, though I don't think we
>>>>>>>> manipulate
>>>>>>>> that while it is live, and I'm not sure if that needs any special handling.
>>>>>>>
>>>>>>> Well we never need this function in the hot (order-0 folio) path, so I
>>>>>>> think I
>>>>>>> could add a check for efi_mm here with performance implication. It's
>>>>>>> probably
>>>>>>> safest to explicitly exclude it? What do you think?
>>>>>>
>>>>>> Oops: This should have read "I think I could add a check for efi_mm here
>>>>>> *without* performance implication"
>>>>>
>>>>> It turns out that efi_mm is only defined when CONFIG_EFI is enabled. I can do
>>>>> this:
>>>>>
>>>>> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
>>>>>
>>>>> Is that acceptable? This is my preference, but nothing else outside of efi
>>>>> references this symbol currently.
>>>>>
>>>>> Or perhaps I can convince myself that its safe to treat efi_mm like userspace.
>>>>> There are a couple of things that need to be garanteed for it to be safe:
>>>>>
>>>>> ??? - The PFNs of present ptes either need to have an associated struct
>>>>> page or
>>>>> ????? need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
>>>>> ????? pte_mkdevmap())
>>>>>
>>>>> ??? - Live mappings must either be static (no changes that could cause
>>>>> fold/unfold
>>>>> ????? while live) or the system must be able to tolerate a temporary fault
>>>>>
>>>>> Mark suggests efi_mm is not manipulated while live, so that meets the latter
>>>>> requirement, but I'm not sure about the former?
>>>>
>>>> I've gone through all the efi code, and conclude that, as Mark suggests, the
>>>> mappings are indeed static. And additionally, the ptes are populated using only
>>>> the _private_ ptep API, so there is no issue here. As just discussed with Mark,
>>>> my prefereence is to not make any changes to code, and just add a comment
>>>> describing why efi_mm is safe.
>>>>
>>>> Details:
>>>>
>>>> * Registered with ptdump
>>>> ????? * ptep_get_lockless()
>>>> * efi_create_mapping -> create_pgd_mapping ? -> init_pte:
>>>> ????? * __ptep_get()
>>>> ????? * __set_pte()
>>>> * efi_memattr_apply_permissions -> efi_set_mapping_permissions ? ->
>>>> set_permissions
>>>> ????? * __ptep_get()
>>>> ????? * __set_pte()
>>>
>>> Sound good. We could add some VM_WARN_ON if we ever get the efi_mm via the
>>> "official" APIs.
>>
>> We could, but that would lead to the same linkage issue, which I'm trying to
>> avoid in the first place:
>>
>> VM_WARN_ON(IS_ENABLED(CONFIG_EFI) && mm == efi_mm);
>>
>> This creates new source code dependencies, which I would rather avoid if
>> possible.
> 
> Just a thought, you could have a is_efi_mm() function that abstracts all that.
> 
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index c74f47711f0b..152f5fa66a2a 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -692,6 +692,15 @@ extern struct efi {
> ?
> ?extern struct mm_struct efi_mm;
> ?
> +static inline void is_efi_mm(struct mm_struct *mm)
> +{
> +#ifdef CONFIG_EFI
> +?????? return mm == &efi_mm;
> +#else
> +?????? return false;
> +#endif
> +}
> +
> ?static inline int
> ?efi_guidcmp (efi_guid_t left, efi_guid_t right)
> ?{
> 
> 

That would definitely work, but in that case, I might as well just check for it
in mm_is_user() (and personally I would change the name to mm_is_efi()):


static inline bool mm_is_user(struct mm_struct *mm)
{
	return mm != &init_mm && !mm_is_efi(mm);
}

Any objections?



From david at redhat.com  Tue Feb 13 05:22:46 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 13 Feb 2024 14:22:46 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <dce5f80d-942f-439c-a549-5290666464ca@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
 <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com>
 <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
 <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com>
 <dce5f80d-942f-439c-a549-5290666464ca@arm.com>
Message-ID: <e89a3d11-fe73-4717-b0d6-55cc4fbe16cf@redhat.com>

On 13.02.24 14:20, Ryan Roberts wrote:
> On 13/02/2024 13:13, David Hildenbrand wrote:
>> On 13.02.24 14:06, Ryan Roberts wrote:
>>> On 13/02/2024 12:19, David Hildenbrand wrote:
>>>> On 13.02.24 13:06, Ryan Roberts wrote:
>>>>> On 12/02/2024 20:38, Ryan Roberts wrote:
>>>>>> [...]
>>>>>>
>>>>>>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>>>>>>> +{
>>>>>>>>>> +??? /*
>>>>>>>>>> +???? * Don't attempt to apply the contig bit to kernel mappings, because
>>>>>>>>>> +???? * dynamically adding/removing the contig bit can cause page faults.
>>>>>>>>>> +???? * These racing faults are ok for user space, since they get
>>>>>>>>>> serialized
>>>>>>>>>> +???? * on the PTL. But kernel mappings can't tolerate faults.
>>>>>>>>>> +???? */
>>>>>>>>>> +??? return mm != &init_mm;
>>>>>>>>>> +}
>>>>>>>>>
>>>>>>>>> We also have the efi_mm as a non-user mm, though I don't think we
>>>>>>>>> manipulate
>>>>>>>>> that while it is live, and I'm not sure if that needs any special handling.
>>>>>>>>
>>>>>>>> Well we never need this function in the hot (order-0 folio) path, so I
>>>>>>>> think I
>>>>>>>> could add a check for efi_mm here with performance implication. It's
>>>>>>>> probably
>>>>>>>> safest to explicitly exclude it? What do you think?
>>>>>>>
>>>>>>> Oops: This should have read "I think I could add a check for efi_mm here
>>>>>>> *without* performance implication"
>>>>>>
>>>>>> It turns out that efi_mm is only defined when CONFIG_EFI is enabled. I can do
>>>>>> this:
>>>>>>
>>>>>> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
>>>>>>
>>>>>> Is that acceptable? This is my preference, but nothing else outside of efi
>>>>>> references this symbol currently.
>>>>>>
>>>>>> Or perhaps I can convince myself that its safe to treat efi_mm like userspace.
>>>>>> There are a couple of things that need to be garanteed for it to be safe:
>>>>>>
>>>>>>  ??? - The PFNs of present ptes either need to have an associated struct
>>>>>> page or
>>>>>>  ????? need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
>>>>>>  ????? pte_mkdevmap())
>>>>>>
>>>>>>  ??? - Live mappings must either be static (no changes that could cause
>>>>>> fold/unfold
>>>>>>  ????? while live) or the system must be able to tolerate a temporary fault
>>>>>>
>>>>>> Mark suggests efi_mm is not manipulated while live, so that meets the latter
>>>>>> requirement, but I'm not sure about the former?
>>>>>
>>>>> I've gone through all the efi code, and conclude that, as Mark suggests, the
>>>>> mappings are indeed static. And additionally, the ptes are populated using only
>>>>> the _private_ ptep API, so there is no issue here. As just discussed with Mark,
>>>>> my prefereence is to not make any changes to code, and just add a comment
>>>>> describing why efi_mm is safe.
>>>>>
>>>>> Details:
>>>>>
>>>>> * Registered with ptdump
>>>>>  ????? * ptep_get_lockless()
>>>>> * efi_create_mapping -> create_pgd_mapping ? -> init_pte:
>>>>>  ????? * __ptep_get()
>>>>>  ????? * __set_pte()
>>>>> * efi_memattr_apply_permissions -> efi_set_mapping_permissions ? ->
>>>>> set_permissions
>>>>>  ????? * __ptep_get()
>>>>>  ????? * __set_pte()
>>>>
>>>> Sound good. We could add some VM_WARN_ON if we ever get the efi_mm via the
>>>> "official" APIs.
>>>
>>> We could, but that would lead to the same linkage issue, which I'm trying to
>>> avoid in the first place:
>>>
>>> VM_WARN_ON(IS_ENABLED(CONFIG_EFI) && mm == efi_mm);
>>>
>>> This creates new source code dependencies, which I would rather avoid if
>>> possible.
>>
>> Just a thought, you could have a is_efi_mm() function that abstracts all that.
>>
>> diff --git a/include/linux/efi.h b/include/linux/efi.h
>> index c74f47711f0b..152f5fa66a2a 100644
>> --- a/include/linux/efi.h
>> +++ b/include/linux/efi.h
>> @@ -692,6 +692,15 @@ extern struct efi {
>>   
>>  ?extern struct mm_struct efi_mm;
>>   
>> +static inline void is_efi_mm(struct mm_struct *mm)
>> +{
>> +#ifdef CONFIG_EFI
>> +?????? return mm == &efi_mm;
>> +#else
>> +?????? return false;
>> +#endif
>> +}
>> +
>>  ?static inline int
>>  ?efi_guidcmp (efi_guid_t left, efi_guid_t right)
>>  ?{
>>
>>
> 
> That would definitely work, but in that case, I might as well just check for it
> in mm_is_user() (and personally I would change the name to mm_is_efi()):
> 
> 
> static inline bool mm_is_user(struct mm_struct *mm)
> {
> 	return mm != &init_mm && !mm_is_efi(mm);
> }
> 
> Any objections?
> 

Nope :) Maybe slap in an "unlikely()", because efi_mm *is* unlikely to 
show up.

-- 
Cheers,

David / dhildenb



From robin.murphy at arm.com  Tue Feb 13 05:23:45 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 13 Feb 2024 13:23:45 +0000
Subject: [PATCH v9 16/16] PCI: imx6: Add iMX95 Endpoint (EP) support
In-Reply-To: <ZctGs2d9ccnmYysL@lpieralisi>
References: <20240119171122.3057511-1-Frank.Li@nxp.com>
 <20240119171122.3057511-17-Frank.Li@nxp.com> <ZctGs2d9ccnmYysL@lpieralisi>
Message-ID: <f1b8c49b-0d13-4a3e-9696-75a370ac0e59@arm.com>

On 13/02/2024 10:38 am, Lorenzo Pieralisi wrote:
> [+Christoph, Robin - just checking with you if the DMA mask handling is
> what you expect from drivers, don't want to merge code that breaks your
> expectations]

I don't really understand how all the endpoint stuff fits together, but 
my hunch would be that setting the DMA masks in imx6_add_pcie_ep() might 
be more sensible, unless perhaps there's an implied intent to account 
for eDMA channels in root complex mode as well (and so assuming that 
eDMA and endpoint mode play nicely together sharing the same platform 
device) - as we've discussed before across various threads, setting DMA 
masks for a host bridge itself doesn't really make sense (and hence it 
leaves the gap where we can get away with co-opting them for the MSI 
address hack); it's any additional DMA-initiating functionality within a 
root complex which should own that responsibility.

FWIW it looks like the equivalent change for Layerscape *is* specific to 
endpoint mode, but I don't know how relevant that is to i.MX given that 
they're unrelated hardware configurations.

Thanks,
Robin.

> On Fri, Jan 19, 2024 at 12:11:22PM -0500, Frank Li wrote:
>> Add iMX95 EP support and add 64bit address support. Internal bus bridge for
>> PCI support 64bit dma address in iMX95. Hence, call
>> dma_set_mask_and_coherent() to set 64 bit DMA mask.
>>
>> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
>> Signed-off-by: Frank Li <Frank.Li at nxp.com>
>> ---
>>
>> Notes:
>>      Change from v8 to v9
>>      - update fixme comments
>>      - update BAR1 comments
>>      - Add mani's review tag
>>      Change from v7 to v8
>>      - Update commit message
>>      - Using Fixme
>>      - Update clks_cnts by ARRAY_SIZE
>>      
>>      Change from v4 to v7
>>      - none
>>      Change from v3 to v4
>>      - change align to 4k for imx95
>>      Change from v1 to v3
>>      - new patches at v3
>>
>>   drivers/pci/controller/dwc/pci-imx6.c | 47 +++++++++++++++++++++++++++
>>   1 file changed, 47 insertions(+)
>>
>> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
>> index bbaa45c08323b..7889318f6555a 100644
>> --- a/drivers/pci/controller/dwc/pci-imx6.c
>> +++ b/drivers/pci/controller/dwc/pci-imx6.c
>> @@ -75,6 +75,7 @@ enum imx6_pcie_variants {
>>   	IMX8MQ_EP,
>>   	IMX8MM_EP,
>>   	IMX8MP_EP,
>> +	IMX95_EP,
>>   };
>>   
>>   #define IMX6_PCIE_FLAG_IMX6_PHY			BIT(0)
>> @@ -84,6 +85,7 @@ enum imx6_pcie_variants {
>>   #define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
>>   #define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
>>   #define IMX6_PCIE_FLAG_HAS_SERDES		BIT(6)
>> +#define IMX6_PCIE_FLAG_SUPPORT_64BIT		BIT(7)
>>   
>>   #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
>>   
>> @@ -616,6 +618,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
>>   		break;
>>   	case IMX7D:
>>   	case IMX95:
>> +	case IMX95_EP:
>>   		break;
>>   	case IMX8MM:
>>   	case IMX8MM_EP:
>> @@ -1050,6 +1053,23 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
>>   	.align = SZ_64K,
>>   };
>>   
>> +/*
>> + * BAR#	| Default BAR enable	| Default BAR Type	| Default BAR Size	| BAR Sizing Scheme
>> + * ================================================================================================
>> + * BAR0	| Enable		| 64-bit		| 1 MB			| Programmable Size
>> + * BAR1	| Disable		| 32-bit		| 64 KB			| Fixed Size
>> + *        BAR1 should be disabled if BAR0 is 64bit.
>> + * BAR2	| Enable		| 32-bit		| 1 MB			| Programmable Size
>> + * BAR3	| Enable		| 32-bit		| 64 KB			| Programmable Size
>> + * BAR4	| Enable		| 32-bit		| 1M			| Programmable Size
>> + * BAR5	| Enable		| 32-bit		| 64 KB			| Programmable Size
>> + */
>> +static const struct pci_epc_features imx95_pcie_epc_features = {
>> +	.msi_capable = true,
>> +	.bar_fixed_size[1] = SZ_64K,
>> +	.align = SZ_4K,
>> +};
>> +
>>   static const struct pci_epc_features*
>>   imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
>>   {
>> @@ -1092,6 +1112,15 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
>>   
>>   	pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset;
>>   
>> +	/*
>> +	 * FIXME: Ideally, dbi2 base address should come from DT. But since only IMX95 is defining
>> +	 * "dbi2" in DT, "dbi_base2" is set to NULL here for that platform alone so that the DWC
>> +	 * core code can fetch that from DT. But once all platform DTs were fixed, this and the
>> +	 * above "dbi_base2" setting should be removed.
>> +	 */
>> +	if (imx6_pcie->drvdata->variant == IMX95_EP)
>> +		pci->dbi_base2 = NULL;
>> +
>>   	ret = dw_pcie_ep_init(ep);
>>   	if (ret) {
>>   		dev_err(dev, "failed to initialize endpoint\n");
>> @@ -1345,6 +1374,9 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>>   					     "unable to find iomuxc registers\n");
>>   	}
>>   
>> +	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_SUPPORT_64BIT))
>> +		dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
>> +
>>   	/* Grab PCIe PHY Tx Settings */
>>   	if (of_property_read_u32(node, "fsl,tx-deemph-gen1",
>>   				 &imx6_pcie->tx_deemph_gen1))
>> @@ -1563,6 +1595,20 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>>   		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>>   		.epc_features = &imx8m_pcie_epc_features,
>>   	},
>> +	[IMX95_EP] = {
>> +		.variant = IMX95_EP,
>> +		.flags = IMX6_PCIE_FLAG_HAS_SERDES |
>> +			 IMX6_PCIE_FLAG_SUPPORT_64BIT,
>> +		.clk_names = imx8mq_clks,
>> +		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
>> +		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
>> +		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
>> +		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
>> +		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
>> +		.init_phy = imx95_pcie_init_phy,
>> +		.epc_features = &imx95_pcie_epc_features,
>> +		.mode = DW_PCIE_EP_TYPE,
>> +	},
>>   };
>>   
>>   static const struct of_device_id imx6_pcie_of_match[] = {
>> @@ -1577,6 +1623,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
>>   	{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
>>   	{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
>>   	{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
>> +	{ .compatible = "fsl,imx95-pcie-ep", .data = &drvdata[IMX95_EP], },
>>   	{},
>>   };
>>   
>> -- 
>> 2.34.1
>>


From ryan.roberts at arm.com  Tue Feb 13 05:24:35 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 13:24:35 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <e89a3d11-fe73-4717-b0d6-55cc4fbe16cf@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
 <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com>
 <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
 <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com>
 <dce5f80d-942f-439c-a549-5290666464ca@arm.com>
 <e89a3d11-fe73-4717-b0d6-55cc4fbe16cf@redhat.com>
Message-ID: <b9f7636e-61eb-40bc-bab3-2caaa5f39c57@arm.com>

On 13/02/2024 13:22, David Hildenbrand wrote:
> On 13.02.24 14:20, Ryan Roberts wrote:
>> On 13/02/2024 13:13, David Hildenbrand wrote:
>>> On 13.02.24 14:06, Ryan Roberts wrote:
>>>> On 13/02/2024 12:19, David Hildenbrand wrote:
>>>>> On 13.02.24 13:06, Ryan Roberts wrote:
>>>>>> On 12/02/2024 20:38, Ryan Roberts wrote:
>>>>>>> [...]
>>>>>>>
>>>>>>>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>>>>>>>> +{
>>>>>>>>>>> +??? /*
>>>>>>>>>>> +???? * Don't attempt to apply the contig bit to kernel mappings,
>>>>>>>>>>> because
>>>>>>>>>>> +???? * dynamically adding/removing the contig bit can cause page
>>>>>>>>>>> faults.
>>>>>>>>>>> +???? * These racing faults are ok for user space, since they get
>>>>>>>>>>> serialized
>>>>>>>>>>> +???? * on the PTL. But kernel mappings can't tolerate faults.
>>>>>>>>>>> +???? */
>>>>>>>>>>> +??? return mm != &init_mm;
>>>>>>>>>>> +}
>>>>>>>>>>
>>>>>>>>>> We also have the efi_mm as a non-user mm, though I don't think we
>>>>>>>>>> manipulate
>>>>>>>>>> that while it is live, and I'm not sure if that needs any special
>>>>>>>>>> handling.
>>>>>>>>>
>>>>>>>>> Well we never need this function in the hot (order-0 folio) path, so I
>>>>>>>>> think I
>>>>>>>>> could add a check for efi_mm here with performance implication. It's
>>>>>>>>> probably
>>>>>>>>> safest to explicitly exclude it? What do you think?
>>>>>>>>
>>>>>>>> Oops: This should have read "I think I could add a check for efi_mm here
>>>>>>>> *without* performance implication"
>>>>>>>
>>>>>>> It turns out that efi_mm is only defined when CONFIG_EFI is enabled. I
>>>>>>> can do
>>>>>>> this:
>>>>>>>
>>>>>>> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
>>>>>>>
>>>>>>> Is that acceptable? This is my preference, but nothing else outside of efi
>>>>>>> references this symbol currently.
>>>>>>>
>>>>>>> Or perhaps I can convince myself that its safe to treat efi_mm like
>>>>>>> userspace.
>>>>>>> There are a couple of things that need to be garanteed for it to be safe:
>>>>>>>
>>>>>>> ???? - The PFNs of present ptes either need to have an associated struct
>>>>>>> page or
>>>>>>> ?????? need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
>>>>>>> ?????? pte_mkdevmap())
>>>>>>>
>>>>>>> ???? - Live mappings must either be static (no changes that could cause
>>>>>>> fold/unfold
>>>>>>> ?????? while live) or the system must be able to tolerate a temporary fault
>>>>>>>
>>>>>>> Mark suggests efi_mm is not manipulated while live, so that meets the latter
>>>>>>> requirement, but I'm not sure about the former?
>>>>>>
>>>>>> I've gone through all the efi code, and conclude that, as Mark suggests, the
>>>>>> mappings are indeed static. And additionally, the ptes are populated using
>>>>>> only
>>>>>> the _private_ ptep API, so there is no issue here. As just discussed with
>>>>>> Mark,
>>>>>> my prefereence is to not make any changes to code, and just add a comment
>>>>>> describing why efi_mm is safe.
>>>>>>
>>>>>> Details:
>>>>>>
>>>>>> * Registered with ptdump
>>>>>> ?????? * ptep_get_lockless()
>>>>>> * efi_create_mapping -> create_pgd_mapping ? -> init_pte:
>>>>>> ?????? * __ptep_get()
>>>>>> ?????? * __set_pte()
>>>>>> * efi_memattr_apply_permissions -> efi_set_mapping_permissions ? ->
>>>>>> set_permissions
>>>>>> ?????? * __ptep_get()
>>>>>> ?????? * __set_pte()
>>>>>
>>>>> Sound good. We could add some VM_WARN_ON if we ever get the efi_mm via the
>>>>> "official" APIs.
>>>>
>>>> We could, but that would lead to the same linkage issue, which I'm trying to
>>>> avoid in the first place:
>>>>
>>>> VM_WARN_ON(IS_ENABLED(CONFIG_EFI) && mm == efi_mm);
>>>>
>>>> This creates new source code dependencies, which I would rather avoid if
>>>> possible.
>>>
>>> Just a thought, you could have a is_efi_mm() function that abstracts all that.
>>>
>>> diff --git a/include/linux/efi.h b/include/linux/efi.h
>>> index c74f47711f0b..152f5fa66a2a 100644
>>> --- a/include/linux/efi.h
>>> +++ b/include/linux/efi.h
>>> @@ -692,6 +692,15 @@ extern struct efi {
>>> ? ??extern struct mm_struct efi_mm;
>>> ? +static inline void is_efi_mm(struct mm_struct *mm)
>>> +{
>>> +#ifdef CONFIG_EFI
>>> +?????? return mm == &efi_mm;
>>> +#else
>>> +?????? return false;
>>> +#endif
>>> +}
>>> +
>>> ??static inline int
>>> ??efi_guidcmp (efi_guid_t left, efi_guid_t right)
>>> ??{
>>>
>>>
>>
>> That would definitely work, but in that case, I might as well just check for it
>> in mm_is_user() (and personally I would change the name to mm_is_efi()):
>>
>>
>> static inline bool mm_is_user(struct mm_struct *mm)
>> {
>> ????return mm != &init_mm && !mm_is_efi(mm);
>> }
>>
>> Any objections?
>>
> 
> Nope :) Maybe slap in an "unlikely()", because efi_mm *is* unlikely to show up.

Deal

> 



From robh at kernel.org  Tue Feb 13 05:26:54 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 07:26:54 -0600
Subject: [PATCH v2 02/17] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240213010347.1075251-3-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-3-sre@kernel.org>
Message-ID: <20240213132654.GA1051154-robh@kernel.org>

On Tue, Feb 13, 2024 at 02:00:51AM +0100, Sebastian Reichel wrote:
> Convert the i.MX  Wireless External Interface Module binding to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../devicetree/bindings/bus/imx-weim.txt      | 117 ----------
>  .../fsl/fsl,imx-weim-peripherals.yaml         |  36 ++++
>  .../memory-controllers/fsl/fsl,imx-weim.yaml  | 201 ++++++++++++++++++
>  .../mc-peripheral-props.yaml                  |   1 +
>  .../fieldbus/arcx,anybus-controller.txt       |   2 +-
>  5 files changed, 239 insertions(+), 118 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml


> diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
> new file mode 100644
> index 000000000000..86d7e5011107
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
> @@ -0,0 +1,36 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: i.MX WEIM Bus Peripheral Nodes
> +
> +maintainers:
> +  - Shawn Guo <shawnguo at kernel.org>
> +  - Sascha Hauer <s.hauer at pengutronix.de>
> +
> +description:
> +  This binding is meant for the child nodes of the WEIM node. The node
> +  represents any device connected to the WEIM bus. It may be a Flash chip,
> +  RAM chip or Ethernet controller, etc. These properties are meant for
> +  configuring the WEIM settings/timings and will accompany the bindings
> +  supported by the respective device.
> +
> +properties:
> +  reg: true
> +
> +  fsl,weim-cs-timing:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      Timing values for the child node.
> +    minItems: 2
> +    maxItems: 6
> +
> +required:
> +  - compatible
> +  - reg
> +  - fsl,weim-cs-timing

This should be marked required in fsl,imx-weim.yaml instead to fix the 
errors.

Really, the other required ones should be in mc-peripheral-props.yaml as 
it applies to everyone.

> +
> +# the WEIM child will have its own native properties
> +additionalProperties: true


From smostafa at google.com  Tue Feb 13 05:30:12 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Tue, 13 Feb 2024 13:30:12 +0000
Subject: [PATCH v4 06/16] iommu/arm-smmu-v3: Hold arm_smmu_asid_lock
 during all of attach_dev
In-Reply-To: <20240201132443.GP1455070@nvidia.com>
References: <0-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <6-v4-c93b774edcc4+42d2b-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZbuLeWDvhhufT7Pa@google.com>
 <20240201132443.GP1455070@nvidia.com>
Message-ID: <Zctu5HOJOPaTNBt-@google.com>

On Thu, Feb 01, 2024 at 09:24:43AM -0400, Jason Gunthorpe wrote:
> On Thu, Feb 01, 2024 at 12:15:53PM +0000, Mostafa Saleh wrote:
> > Hi Jason,
> > 
> > On Thu, Jan 25, 2024 at 07:57:16PM -0400, Jason Gunthorpe wrote:
> > > The BTM support wants to be able to change the ASID of any smmu_domain.
> > > When it goes to do this it holds the arm_smmu_asid_lock and iterates over
> > > the target domain's devices list.
> > > 
> > > During attach of a S1 domain we must ensure that the devices list and
> > > CD are in sync, otherwise we could miss CD updates or a parallel CD update
> > > could push an out of date CD.
> > > 
> > > This is pretty complicated, and almost works today because
> > > arm_smmu_detach_dev() removes the master from the linked list before
> > > working on the CD entries, preventing parallel update of the CD.
> > > 
> > > However, it does have an issue where the CD can remain programed while the
> > > domain appears to be unattached. arm_smmu_share_asid() will then not clear
> > > any CD entriess and install its own CD entry with the same ASID
> > > concurrently. This creates a small race window where the IOMMU can see two
> > > ASIDs pointing to different translations.
> > 
> > I don?t see the race condition.
> > 
> > The current flow is as follows,
> > For SVA, if the asid was used by domain_x, it will do:
> > 
> > lock(arm_smmu_asid_lock)
> > Alloc new asid and set cd->asid.
> > lock(domain_x->devices_lock)
> > Write new CD with the new asid
> > unlock(domain_x->devices_lock)
> > unlock(arm_smmu_asid_lock)
> > 
> > For attach_dev (domain_y), if the device was attached to domain_z
> > //Detach old domain
> > lock(domain_z->devices_lock)
> > Remove master from old domain
> > unlock(domain_z->devices_lock)
> 
> At this moment all locks are dropped and the RID's CD entry continues
> to use the ASID.
> 
> The racing BTM flow now runs and will do your above:
> 
> arm_smmu_mmu_notifier_get()
>  arm_smmu_alloc_shared_cd()
>   arm_smmu_share_asid():
>     arm_smmu_update_ctx_desc_devices() <<- Does nothing due to list_del above
>     arm_smmu_tlb_inv_asid() <<-- Woops, we are invalidating an ASID that is still in a CD!
>  arm_smmu_write_ctx_desc() <<-- Install a new translation on a PASID's CD
> 
> Now the HW can observe two installed CDs using the same ASID but they
> point to different translations. This is illegal.
> 
> > Clear CD
> 
> Now we remove the RID CD, but it is too late, the PASID CD is already
> installed.
> 
> ASID/VMID lifecycle must be strictly contained to ensure the cache
> remains coherent:
> 
> 1. All programmed STE/CDs using the ASID/VMID must always point to the
>    same translation
> 
> 2. All references to a ASID/VMID must be removed from their STE/CDs
>    before the ASID is flushed
> 
> 3. The ASID/VMID must be flushed before it is assigned to a STE/CD
>    with a new translation.
> 
> We solve this by requiring that the arm_smmu_asid_lock must be held
> such that the smmu_domains->devices list AND the actual content of the
> CD tables are always observed to be consistent.
> 
> Jason

I see, thanks a lot for the detailed explanation.?
Maybe this can be added to the change log, so it?s documented somewhere.

Also, I guess this is mainly theoretical, as it requires the detached device to
issue DMA while being detached?

Thanks,
Mostafa


From jgg at nvidia.com  Tue Feb 13 05:30:45 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 09:30:45 -0400
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240213125456.GA28844@willie-the-truck>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
 <20240208125846.GA23290@willie-the-truck>
 <20240208142729.GH10476@nvidia.com>
 <20240213112015.GB28517@willie-the-truck>
 <20240213121850.GH4048826@nvidia.com>
 <20240213125456.GA28844@willie-the-truck>
Message-ID: <20240213133045.GA989297@nvidia.com>

On Tue, Feb 13, 2024 at 12:54:56PM +0000, Will Deacon wrote:
> > Adding a check is not a comprehensive solution, there are still ways
> > userspace can attack this code with iommufd's coming PASID support. It
> > certainly doesn't belong in this patch which should be backported.
> 
> Ok, then how about avoiding the allocation entirely once the lock is
> held?

We need to allocate because we can't assume anything already made the
CD leaf present. Do you mean to do this additionally to this patch?

There are several places where a noalloc CD behavior would be useful,
I'd be fine to add that as part of this patch to protect the loop.

> > I can summarize some of these details in a comment for this patch.
>
> Alternatively, we can just revert the offending commits if we're not able
> to agree on a simple fix for now. I'd prefer to avoid that though.

I feel we are not aligned here. We are trying to get the driver to
work properly with iommufd and expose all the HW features. This has
been fixed comprehensively and well-reviewed patches have been on the
list for 7 months now. We want to move forward, not revert things.

Jason


From ardb at kernel.org  Tue Feb 13 05:33:34 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 13 Feb 2024 14:33:34 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <dce5f80d-942f-439c-a549-5290666464ca@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com> <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com> <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com> <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com> <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
 <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com> <dce5f80d-942f-439c-a549-5290666464ca@arm.com>
Message-ID: <CAMj1kXEVf1m4hVXORc6t9ytAOb75KZLcW-OJ6999VaKbkVdQ3A@mail.gmail.com>

On Tue, 13 Feb 2024 at 14:21, Ryan Roberts <ryan.roberts at arm.com> wrote:
>
> On 13/02/2024 13:13, David Hildenbrand wrote:
> > On 13.02.24 14:06, Ryan Roberts wrote:
> >> On 13/02/2024 12:19, David Hildenbrand wrote:
> >>> On 13.02.24 13:06, Ryan Roberts wrote:
> >>>> On 12/02/2024 20:38, Ryan Roberts wrote:
> >>>>> [...]
> >>>>>
> >>>>>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
> >>>>>>>>> +{
> >>>>>>>>> +    /*
> >>>>>>>>> +     * Don't attempt to apply the contig bit to kernel mappings, because
> >>>>>>>>> +     * dynamically adding/removing the contig bit can cause page faults.
> >>>>>>>>> +     * These racing faults are ok for user space, since they get
> >>>>>>>>> serialized
> >>>>>>>>> +     * on the PTL. But kernel mappings can't tolerate faults.
> >>>>>>>>> +     */
> >>>>>>>>> +    return mm != &init_mm;
> >>>>>>>>> +}
> >>>>>>>>
> >>>>>>>> We also have the efi_mm as a non-user mm, though I don't think we
> >>>>>>>> manipulate
> >>>>>>>> that while it is live, and I'm not sure if that needs any special handling.
> >>>>>>>
> >>>>>>> Well we never need this function in the hot (order-0 folio) path, so I
> >>>>>>> think I
> >>>>>>> could add a check for efi_mm here with performance implication. It's
> >>>>>>> probably
> >>>>>>> safest to explicitly exclude it? What do you think?
> >>>>>>
> >>>>>> Oops: This should have read "I think I could add a check for efi_mm here
> >>>>>> *without* performance implication"
> >>>>>
> >>>>> It turns out that efi_mm is only defined when CONFIG_EFI is enabled. I can do
> >>>>> this:
> >>>>>
> >>>>> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
> >>>>>
> >>>>> Is that acceptable? This is my preference, but nothing else outside of efi
> >>>>> references this symbol currently.
> >>>>>
> >>>>> Or perhaps I can convince myself that its safe to treat efi_mm like userspace.
> >>>>> There are a couple of things that need to be garanteed for it to be safe:
> >>>>>
> >>>>>     - The PFNs of present ptes either need to have an associated struct
> >>>>> page or
> >>>>>       need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
> >>>>>       pte_mkdevmap())
> >>>>>
> >>>>>     - Live mappings must either be static (no changes that could cause
> >>>>> fold/unfold
> >>>>>       while live) or the system must be able to tolerate a temporary fault
> >>>>>
> >>>>> Mark suggests efi_mm is not manipulated while live, so that meets the latter
> >>>>> requirement, but I'm not sure about the former?
> >>>>
> >>>> I've gone through all the efi code, and conclude that, as Mark suggests, the
> >>>> mappings are indeed static. And additionally, the ptes are populated using only
> >>>> the _private_ ptep API, so there is no issue here. As just discussed with Mark,
> >>>> my prefereence is to not make any changes to code, and just add a comment
> >>>> describing why efi_mm is safe.
> >>>>
> >>>> Details:
> >>>>
> >>>> * Registered with ptdump
> >>>>       * ptep_get_lockless()
> >>>> * efi_create_mapping -> create_pgd_mapping ? -> init_pte:
> >>>>       * __ptep_get()
> >>>>       * __set_pte()
> >>>> * efi_memattr_apply_permissions -> efi_set_mapping_permissions ? ->
> >>>> set_permissions
> >>>>       * __ptep_get()
> >>>>       * __set_pte()
> >>>
> >>> Sound good. We could add some VM_WARN_ON if we ever get the efi_mm via the
> >>> "official" APIs.
> >>
> >> We could, but that would lead to the same linkage issue, which I'm trying to
> >> avoid in the first place:
> >>
> >> VM_WARN_ON(IS_ENABLED(CONFIG_EFI) && mm == efi_mm);
> >>
> >> This creates new source code dependencies, which I would rather avoid if
> >> possible.
> >
> > Just a thought, you could have a is_efi_mm() function that abstracts all that.
> >
> > diff --git a/include/linux/efi.h b/include/linux/efi.h
> > index c74f47711f0b..152f5fa66a2a 100644
> > --- a/include/linux/efi.h
> > +++ b/include/linux/efi.h
> > @@ -692,6 +692,15 @@ extern struct efi {
> >
> >  extern struct mm_struct efi_mm;
> >
> > +static inline void is_efi_mm(struct mm_struct *mm)
> > +{
> > +#ifdef CONFIG_EFI
> > +       return mm == &efi_mm;
> > +#else
> > +       return false;
> > +#endif
> > +}
> > +
> >  static inline int
> >  efi_guidcmp (efi_guid_t left, efi_guid_t right)
> >  {
> >
> >
>
> That would definitely work, but in that case, I might as well just check for it
> in mm_is_user() (and personally I would change the name to mm_is_efi()):
>
>
> static inline bool mm_is_user(struct mm_struct *mm)
> {
>         return mm != &init_mm && !mm_is_efi(mm);
> }
>
> Any objections?
>

Any reason not to use IS_ENABLED(CONFIG_EFI) in the above? The extern
declaration is visible to the compiler, and any references should
disappear before the linker could notice that efi_mm does not exist.

In any case, feel free to add

Acked-by: Ard Biesheuvel <ardb at kernel.org>

when you roll a patch based on the above, with or without IS_ENABLED().

And as you concluded, efi_mm is indeed set in stone once the runtime
regions described by the firmware have been mapped, although this may
happen in two passes depending on how the runtime regions are
described. But by the time user MMs might exist, efi_mm should
effectively be immutable.


From robh at kernel.org  Tue Feb 13 05:39:40 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 07:39:40 -0600
Subject: [PATCH] dt-bindings: vendor-prefixes: add smartrg
In-Reply-To: <20240212140839.27150-1-zajec5@gmail.com>
References: <20240212140839.27150-1-zajec5@gmail.com>
Message-ID: <170783157961.1082071.9686592830997462350.robh@kernel.org>


On Mon, 12 Feb 2024 15:08:39 +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> SmartRG described itself as a CPE manufacturer and produced few home
> network devices (e.g. wireless routers). Their SmartRG SR400ac router
> (smartrg,sr400ac) is covered by in-Linux DT binding and DTS file.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Applied, thanks!



From david at redhat.com  Tue Feb 13 05:45:32 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 13 Feb 2024 14:45:32 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <CAMj1kXEVf1m4hVXORc6t9ytAOb75KZLcW-OJ6999VaKbkVdQ3A@mail.gmail.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
 <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com>
 <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
 <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com>
 <dce5f80d-942f-439c-a549-5290666464ca@arm.com>
 <CAMj1kXEVf1m4hVXORc6t9ytAOb75KZLcW-OJ6999VaKbkVdQ3A@mail.gmail.com>
Message-ID: <64b872bd-4b12-4dbd-b043-1ad11aeaa19a@redhat.com>

On 13.02.24 14:33, Ard Biesheuvel wrote:
> On Tue, 13 Feb 2024 at 14:21, Ryan Roberts <ryan.roberts at arm.com> wrote:
>>
>> On 13/02/2024 13:13, David Hildenbrand wrote:
>>> On 13.02.24 14:06, Ryan Roberts wrote:
>>>> On 13/02/2024 12:19, David Hildenbrand wrote:
>>>>> On 13.02.24 13:06, Ryan Roberts wrote:
>>>>>> On 12/02/2024 20:38, Ryan Roberts wrote:
>>>>>>> [...]
>>>>>>>
>>>>>>>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>>>>>>>> +{
>>>>>>>>>>> +    /*
>>>>>>>>>>> +     * Don't attempt to apply the contig bit to kernel mappings, because
>>>>>>>>>>> +     * dynamically adding/removing the contig bit can cause page faults.
>>>>>>>>>>> +     * These racing faults are ok for user space, since they get
>>>>>>>>>>> serialized
>>>>>>>>>>> +     * on the PTL. But kernel mappings can't tolerate faults.
>>>>>>>>>>> +     */
>>>>>>>>>>> +    return mm != &init_mm;
>>>>>>>>>>> +}
>>>>>>>>>>
>>>>>>>>>> We also have the efi_mm as a non-user mm, though I don't think we
>>>>>>>>>> manipulate
>>>>>>>>>> that while it is live, and I'm not sure if that needs any special handling.
>>>>>>>>>
>>>>>>>>> Well we never need this function in the hot (order-0 folio) path, so I
>>>>>>>>> think I
>>>>>>>>> could add a check for efi_mm here with performance implication. It's
>>>>>>>>> probably
>>>>>>>>> safest to explicitly exclude it? What do you think?
>>>>>>>>
>>>>>>>> Oops: This should have read "I think I could add a check for efi_mm here
>>>>>>>> *without* performance implication"
>>>>>>>
>>>>>>> It turns out that efi_mm is only defined when CONFIG_EFI is enabled I can do
>>>>>>> this:
>>>>>>>
>>>>>>> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
>>>>>>>
>>>>>>> Is that acceptable? This is my preference, but nothing else outside of efi
>>>>>>> references this symbol currently.
>>>>>>>
>>>>>>> Or perhaps I can convince myself that its safe to treat efi_mm like userspace.
>>>>>>> There are a couple of things that need to be garanteed for it to be safe:
>>>>>>>
>>>>>>>      - The PFNs of present ptes either need to have an associated struct
>>>>>>> page or
>>>>>>>        need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
>>>>>>>        pte_mkdevmap())
>>>>>>>
>>>>>>>      - Live mappings must either be static (no changes that could cause
>>>>>>> fold/unfold
>>>>>>>        while live) or the system must be able to tolerate a temporary fault
>>>>>>>
>>>>>>> Mark suggests efi_mm is not manipulated while live, so that meets the latter
>>>>>>> requirement, but I'm not sure about the former?
>>>>>>
>>>>>> I've gone through all the efi code, and conclude that, as Mark suggests, the
>>>>>> mappings are indeed static. And additionally, the ptes are populated using only
>>>>>> the _private_ ptep API, so there is no issue here. As just discussed with Mark,
>>>>>> my prefereence is to not make any changes to code, and just add a comment
>>>>>> describing why efi_mm is safe.
>>>>>>
>>>>>> Details:
>>>>>>
>>>>>> * Registered with ptdump
>>>>>>        * ptep_get_lockless()
>>>>>> * efi_create_mapping -> create_pgd_mapping ? -> init_pte:
>>>>>>        * __ptep_get()
>>>>>>        * __set_pte()
>>>>>> * efi_memattr_apply_permissions -> efi_set_mapping_permissions ? ->
>>>>>> set_permissions
>>>>>>        * __ptep_get()
>>>>>>        * __set_pte()
>>>>>
>>>>> Sound good. We could add some VM_WARN_ON if we ever get the efi_mm via the
>>>>> "official" APIs.
>>>>
>>>> We could, but that would lead to the same linkage issue, which I'm trying to
>>>> avoid in the first place:
>>>>
>>>> VM_WARN_ON(IS_ENABLED(CONFIG_EFI) && mm == efi_mm);
>>>>
>>>> This creates new source code dependencies, which I would rather avoid if
>>>> possible.
>>>
>>> Just a thought, you could have a is_efi_mm() function that abstracts all that.
>>>
>>> diff --git a/include/linux/efi.h b/include/linux/efi.h
>>> index c74f47711f0b..152f5fa66a2a 100644
>>> --- a/include/linux/efi.h
>>> +++ b/include/linux/efi.h
>>> @@ -692,6 +692,15 @@ extern struct efi {
>>>
>>>   extern struct mm_struct efi_mm;
>>>
>>> +static inline void is_efi_mm(struct mm_struct *mm)
>>> +{
>>> +#ifdef CONFIG_EFI
>>> +       return mm == &efi_mm;
>>> +#else
>>> +       return false;
>>> +#endif
>>> +}
>>> +
>>>   static inline int
>>>   efi_guidcmp (efi_guid_t left, efi_guid_t right)
>>>   {
>>>
>>>
>>
>> That would definitely work, but in that case, I might as well just check for it
>> in mm_is_user() (and personally I would change the name to mm_is_efi()):
>>
>>
>> static inline bool mm_is_user(struct mm_struct *mm)
>> {
>>          return mm != &init_mm && !mm_is_efi(mm);
>> }
>>
>> Any objections?
>>
> 
> Any reason not to use IS_ENABLED(CONFIG_EFI) in the above? The extern
> declaration is visible to the compiler, and any references should
> disappear before the linker could notice that efi_mm does not exist.
> 

Sure, as long as the linker is happy why not. I'll let Ryan mess with 
that :)

> In any case, feel free to add
> 
> Acked-by: Ard Biesheuvel <ardb at kernel.org>

Thanks for the review.

-- 
Cheers,

David / dhildenb



From will at kernel.org  Tue Feb 13 05:47:14 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 13 Feb 2024 13:47:14 +0000
Subject: [PATCH v9 4/5] iommu/arm-smmu: add ACTLR data and support for
 SM8550
In-Reply-To: <20240123144543.9405-5-quic_bibekkum@quicinc.com>
References: <20240123144543.9405-1-quic_bibekkum@quicinc.com>
 <20240123144543.9405-5-quic_bibekkum@quicinc.com>
Message-ID: <20240213134714.GC28926@willie-the-truck>

On Tue, Jan 23, 2024 at 08:15:42PM +0530, Bibek Kumar Patro wrote:
> Add ACTLR data table for SM8550 along with support for
> same including SM8550 specific implementation operations.
> 
> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 90 ++++++++++++++++++++++
>  1 file changed, 90 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 6004c6d9a7b2..db15b1eade97 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -23,6 +23,86 @@
> 
>  #define CPRE			(1 << 1)
>  #define CMTLB			(1 << 0)
> +#define PREFETCH_SHIFT		8
> +#define PREFETCH_DEFAULT	0
> +#define PREFETCH_SHALLOW	(1 << PREFETCH_SHIFT)
> +#define PREFETCH_MODERATE	(2 << PREFETCH_SHIFT)
> +#define PREFETCH_DEEP		(3 << PREFETCH_SHIFT)
> +#define PREFETCH_SWITCH_GFX	(5 << 3)
> +
> +static const struct actlr_config sm8550_apps_actlr_cfg[] = {
> +	{ 0x18a0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
> +	{ 0x18e0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
> +	{ 0x0800, 0x0020, PREFETCH_DEFAULT | CMTLB },
> +	{ 0x1800, 0x00c0, PREFETCH_DEFAULT | CMTLB },
> +	{ 0x1820, 0x0000, PREFETCH_DEFAULT | CMTLB },
> +	{ 0x1860, 0x0000, PREFETCH_DEFAULT | CMTLB },
> +	{ 0x0c01, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> +	{ 0x0c02, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> +	{ 0x0c03, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> +	{ 0x0c04, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> +	{ 0x0c05, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> +	{ 0x0c06, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },

[...]

Isn't this effectively hard-coding the topology of the SoC in the driver?
Wouldn't it better describing higher-level prefetch properties in the DT
nodes corresponding to the upstream devices?

Looking back at the prior revisions of this series, it seems like others
were in favour of this approach, so if that's the general consensus, then
so be it. But is this _really_ what we want in the SMMU driver? It would
be good to have an Ack from Robin and a DT maintainer on this mechanism.

It just all feels a bit like a step back into the bad old world of
platform data to me, where we end up trying to maintain a bunch of random
constants that supposedly make things faster for somebody :/

Will


From jgg at ziepe.ca  Tue Feb 13 05:47:26 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 09:47:26 -0400
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
In-Reply-To: <20240213125951.GB28844@willie-the-truck>
References: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
 <20240213121257.GI765010@ziepe.ca>
 <20240213121934.GA28726@willie-the-truck>
 <20240213125303.GJ765010@ziepe.ca>
 <20240213125951.GB28844@willie-the-truck>
Message-ID: <20240213134726.GK765010@ziepe.ca>

On Tue, Feb 13, 2024 at 12:59:52PM +0000, Will Deacon wrote:
> > The typical kernel standard is to fix bugs in patches and only reach
> > for a wholesale revert if the community is struggling with bug
> > fixing. Dmitry already tested removing that hunk, Robin explained the
> > issue, we understand the bug fix is to remove the
> > arm_smmu_init_domain_context() call. Nothing justifies a full scale
> > revert.
> 
> I can't say I'm aware of any consensus for how to handle this, to be
> completely honest with you. 

Well, I work in a lot of subsystems and this is a surprise to me and
not something I've seen before. Fix the bug, move forward. Reverts are
a cultural admission of failure. I use threats of a revert as a hammer
to encourage people to pay attention to the bugs. I hardly ever
actually revert things. What does reverting their code say to my
submitters???

> > I'll send another patch if you want, but it seems like a waste of all
> > our time.
> 
> It's a bug fix, of course it's a waste of time! We're talking minutes
> though, right?

It becomes hard for maintainers to juggle the tress since you have to
send the revert to -rc and the fix on top of the rc to next. Again, I
will send the patch, just discussing.

Jason


From arnd at kernel.org  Tue Feb 13 05:49:46 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 13 Feb 2024 14:49:46 +0100
Subject: [PATCH] [v2] ARM: crypto: fix function cast warnings
Message-ID: <20240213135000.3400052-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

clang-16 warns about casting between incompatible function types:

arch/arm/crypto/sha256_glue.c:37:5: error: cast from 'void (*)(u32 *, const void *, unsigned int)' (aka 'void (*)(unsigned int *, const void *, unsigned int)') to 'sha256_block_fn *' (aka 'void (*)(struct sha256_state *, const unsigned char *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
   37 |                                 (sha256_block_fn *)sha256_block_data_order);
      |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm/crypto/sha512-glue.c:34:3: error: cast from 'void (*)(u64 *, const u8 *, int)' (aka 'void (*)(unsigned long long *, const unsigned char *, int)') to 'sha512_block_fn *' (aka 'void (*)(struct sha512_state *, const unsigned char *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
   34 |                 (sha512_block_fn *)sha512_block_data_order);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Fix the prototypes for the assembler functions to match the typedef.
The code already relies on the digest being the first part of the
state structure, so there is no change in behavior.

Fixes: c80ae7ca3726 ("crypto: arm/sha512 - accelerated SHA-512 using ARM generic ASM and NEON")
Fixes: b59e2ae3690c ("crypto: arm/sha256 - move SHA-224/256 ASM/NEON implementation to base layer")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
v2: rewrite change as suggested by Herbert Xu.
---
 arch/arm/crypto/sha256_glue.c | 13 +++++--------
 arch/arm/crypto/sha512-glue.c | 12 +++++-------
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/arch/arm/crypto/sha256_glue.c b/arch/arm/crypto/sha256_glue.c
index 433ee4ddce6c..f85933fdec75 100644
--- a/arch/arm/crypto/sha256_glue.c
+++ b/arch/arm/crypto/sha256_glue.c
@@ -24,8 +24,8 @@
 
 #include "sha256_glue.h"
 
-asmlinkage void sha256_block_data_order(u32 *digest, const void *data,
-					unsigned int num_blks);
+asmlinkage void sha256_block_data_order(struct sha256_state *state,
+					const u8 *data, int num_blks);
 
 int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
 			     unsigned int len)
@@ -33,23 +33,20 @@ int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
 	/* make sure casting to sha256_block_fn() is safe */
 	BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
 
-	return sha256_base_do_update(desc, data, len,
-				(sha256_block_fn *)sha256_block_data_order);
+	return sha256_base_do_update(desc, data, len, sha256_block_data_order);
 }
 EXPORT_SYMBOL(crypto_sha256_arm_update);
 
 static int crypto_sha256_arm_final(struct shash_desc *desc, u8 *out)
 {
-	sha256_base_do_finalize(desc,
-				(sha256_block_fn *)sha256_block_data_order);
+	sha256_base_do_finalize(desc, sha256_block_data_order);
 	return sha256_base_finish(desc, out);
 }
 
 int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data,
 			    unsigned int len, u8 *out)
 {
-	sha256_base_do_update(desc, data, len,
-			      (sha256_block_fn *)sha256_block_data_order);
+	sha256_base_do_update(desc, data, len, sha256_block_data_order);
 	return crypto_sha256_arm_final(desc, out);
 }
 EXPORT_SYMBOL(crypto_sha256_arm_finup);
diff --git a/arch/arm/crypto/sha512-glue.c b/arch/arm/crypto/sha512-glue.c
index 0635a65aa488..1be5bd498af3 100644
--- a/arch/arm/crypto/sha512-glue.c
+++ b/arch/arm/crypto/sha512-glue.c
@@ -25,27 +25,25 @@ MODULE_ALIAS_CRYPTO("sha512");
 MODULE_ALIAS_CRYPTO("sha384-arm");
 MODULE_ALIAS_CRYPTO("sha512-arm");
 
-asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks);
+asmlinkage void sha512_block_data_order(struct sha512_state *state,
+					u8 const *src, int blocks);
 
 int sha512_arm_update(struct shash_desc *desc, const u8 *data,
 		      unsigned int len)
 {
-	return sha512_base_do_update(desc, data, len,
-		(sha512_block_fn *)sha512_block_data_order);
+	return sha512_base_do_update(desc, data, len, sha512_block_data_order);
 }
 
 static int sha512_arm_final(struct shash_desc *desc, u8 *out)
 {
-	sha512_base_do_finalize(desc,
-		(sha512_block_fn *)sha512_block_data_order);
+	sha512_base_do_finalize(desc, sha512_block_data_order);
 	return sha512_base_finish(desc, out);
 }
 
 int sha512_arm_finup(struct shash_desc *desc, const u8 *data,
 		     unsigned int len, u8 *out)
 {
-	sha512_base_do_update(desc, data, len,
-		(sha512_block_fn *)sha512_block_data_order);
+	sha512_base_do_update(desc, data, len, sha512_block_data_order);
 	return sha512_arm_final(desc, out);
 }
 
-- 
2.39.2



From arnd at arndb.de  Tue Feb 13 05:50:15 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 13 Feb 2024 14:50:15 +0100
Subject: [PATCH] ARM: crypto: fix function cast warnings
In-Reply-To: <Zctb8QOtMuIfMvDT@gondor.apana.org.au>
References: <20240213101356.460376-1-arnd@kernel.org>
 <Zctb8QOtMuIfMvDT@gondor.apana.org.au>
Message-ID: <3370c551-f24d-4d00-999a-99c229d693a9@app.fastmail.com>

On Tue, Feb 13, 2024, at 13:09, Herbert Xu wrote:
> On Tue, Feb 13, 2024 at 11:13:44AM +0100, Arnd Bergmann wrote:
>>
>> Rework the sha256/sha512 code to instead go through a trivial helper
>> function to preserve the calling conventions.
>
> Why not just change the assembly function prototype?

Good idea, sent v2 now.

    Arnd


From festevam at gmail.com  Tue Feb 13 05:53:05 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 13 Feb 2024 10:53:05 -0300
Subject: [PATCH v2 12/17] ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
In-Reply-To: <20240213010347.1075251-13-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org> <20240213010347.1075251-13-sre@kernel.org>
Message-ID: <CAOMZO5BUzaqHEvd877te_Tgiaz+QvWrvLC_oKg+mRPzmL26pDw@mail.gmail.com>

On Mon, Feb 12, 2024 at 10:03?PM Sebastian Reichel <sre at kernel.org> wrote:
>
> Replace all "xnur-gpio" with "xnur-gpios" in the
> i.MX6UL(L) Touchscreen node.

Please explain the reason for doing this.


From ardb at kernel.org  Tue Feb 13 05:56:21 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 13 Feb 2024 14:56:21 +0100
Subject: [PATCH] [v2] ARM: crypto: fix function cast warnings
In-Reply-To: <20240213135000.3400052-1-arnd@kernel.org>
References: <20240213135000.3400052-1-arnd@kernel.org>
Message-ID: <CAMj1kXH9fDXp0u7kRGVbom_EWhob-VAu67gpWYacUMx-N-p+Fg@mail.gmail.com>

On Tue, 13 Feb 2024 at 14:50, Arnd Bergmann <arnd at kernel.org> wrote:
>
> From: Arnd Bergmann <arnd at arndb.de>
>
> clang-16 warns about casting between incompatible function types:
>
> arch/arm/crypto/sha256_glue.c:37:5: error: cast from 'void (*)(u32 *, const void *, unsigned int)' (aka 'void (*)(unsigned int *, const void *, unsigned int)') to 'sha256_block_fn *' (aka 'void (*)(struct sha256_state *, const unsigned char *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>    37 |                                 (sha256_block_fn *)sha256_block_data_order);
>       |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> arch/arm/crypto/sha512-glue.c:34:3: error: cast from 'void (*)(u64 *, const u8 *, int)' (aka 'void (*)(unsigned long long *, const unsigned char *, int)') to 'sha512_block_fn *' (aka 'void (*)(struct sha512_state *, const unsigned char *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>    34 |                 (sha512_block_fn *)sha512_block_data_order);
>       |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> Fix the prototypes for the assembler functions to match the typedef.
> The code already relies on the digest being the first part of the
> state structure, so there is no change in behavior.
>
> Fixes: c80ae7ca3726 ("crypto: arm/sha512 - accelerated SHA-512 using ARM generic ASM and NEON")
> Fixes: b59e2ae3690c ("crypto: arm/sha256 - move SHA-224/256 ASM/NEON implementation to base layer")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> ---
> v2: rewrite change as suggested by Herbert Xu.
> ---
>  arch/arm/crypto/sha256_glue.c | 13 +++++--------
>  arch/arm/crypto/sha512-glue.c | 12 +++++-------
>  2 files changed, 10 insertions(+), 15 deletions(-)
>

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>

> diff --git a/arch/arm/crypto/sha256_glue.c b/arch/arm/crypto/sha256_glue.c
> index 433ee4ddce6c..f85933fdec75 100644
> --- a/arch/arm/crypto/sha256_glue.c
> +++ b/arch/arm/crypto/sha256_glue.c
> @@ -24,8 +24,8 @@
>
>  #include "sha256_glue.h"
>
> -asmlinkage void sha256_block_data_order(u32 *digest, const void *data,
> -                                       unsigned int num_blks);
> +asmlinkage void sha256_block_data_order(struct sha256_state *state,
> +                                       const u8 *data, int num_blks);
>
>  int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
>                              unsigned int len)
> @@ -33,23 +33,20 @@ int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
>         /* make sure casting to sha256_block_fn() is safe */
>         BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
>
> -       return sha256_base_do_update(desc, data, len,
> -                               (sha256_block_fn *)sha256_block_data_order);
> +       return sha256_base_do_update(desc, data, len, sha256_block_data_order);
>  }
>  EXPORT_SYMBOL(crypto_sha256_arm_update);
>
>  static int crypto_sha256_arm_final(struct shash_desc *desc, u8 *out)
>  {
> -       sha256_base_do_finalize(desc,
> -                               (sha256_block_fn *)sha256_block_data_order);
> +       sha256_base_do_finalize(desc, sha256_block_data_order);
>         return sha256_base_finish(desc, out);
>  }
>
>  int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data,
>                             unsigned int len, u8 *out)
>  {
> -       sha256_base_do_update(desc, data, len,
> -                             (sha256_block_fn *)sha256_block_data_order);
> +       sha256_base_do_update(desc, data, len, sha256_block_data_order);
>         return crypto_sha256_arm_final(desc, out);
>  }
>  EXPORT_SYMBOL(crypto_sha256_arm_finup);
> diff --git a/arch/arm/crypto/sha512-glue.c b/arch/arm/crypto/sha512-glue.c
> index 0635a65aa488..1be5bd498af3 100644
> --- a/arch/arm/crypto/sha512-glue.c
> +++ b/arch/arm/crypto/sha512-glue.c
> @@ -25,27 +25,25 @@ MODULE_ALIAS_CRYPTO("sha512");
>  MODULE_ALIAS_CRYPTO("sha384-arm");
>  MODULE_ALIAS_CRYPTO("sha512-arm");
>
> -asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks);
> +asmlinkage void sha512_block_data_order(struct sha512_state *state,
> +                                       u8 const *src, int blocks);
>
>  int sha512_arm_update(struct shash_desc *desc, const u8 *data,
>                       unsigned int len)
>  {
> -       return sha512_base_do_update(desc, data, len,
> -               (sha512_block_fn *)sha512_block_data_order);
> +       return sha512_base_do_update(desc, data, len, sha512_block_data_order);
>  }
>
>  static int sha512_arm_final(struct shash_desc *desc, u8 *out)
>  {
> -       sha512_base_do_finalize(desc,
> -               (sha512_block_fn *)sha512_block_data_order);
> +       sha512_base_do_finalize(desc, sha512_block_data_order);
>         return sha512_base_finish(desc, out);
>  }
>
>  int sha512_arm_finup(struct shash_desc *desc, const u8 *data,
>                      unsigned int len, u8 *out)
>  {
> -       sha512_base_do_update(desc, data, len,
> -               (sha512_block_fn *)sha512_block_data_order);
> +       sha512_base_do_update(desc, data, len, sha512_block_data_order);
>         return sha512_arm_final(desc, out);
>  }
>
> --
> 2.39.2
>


From will at kernel.org  Tue Feb 13 05:56:28 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 13 Feb 2024 13:56:28 +0000
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240213133045.GA989297@nvidia.com>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
 <20240208125846.GA23290@willie-the-truck>
 <20240208142729.GH10476@nvidia.com>
 <20240213112015.GB28517@willie-the-truck>
 <20240213121850.GH4048826@nvidia.com>
 <20240213125456.GA28844@willie-the-truck>
 <20240213133045.GA989297@nvidia.com>
Message-ID: <20240213135627.GD28926@willie-the-truck>

On Tue, Feb 13, 2024 at 09:30:45AM -0400, Jason Gunthorpe wrote:
> On Tue, Feb 13, 2024 at 12:54:56PM +0000, Will Deacon wrote:
> > > Adding a check is not a comprehensive solution, there are still ways
> > > userspace can attack this code with iommufd's coming PASID support. It
> > > certainly doesn't belong in this patch which should be backported.
> > 
> > Ok, then how about avoiding the allocation entirely once the lock is
> > held?
> 
> We need to allocate because we can't assume anything already made the
> CD leaf present. Do you mean to do this additionally to this patch?

Yes, that's why I said "you'd call arm_smmu_init_cd_table() from
arm_smmu_sva_set_dev_pasid()" in the part of my reply that you trimmed.
The diff is just trying to explain an alternative approach, rather than
meant as a wholesale replacment to your patch. Crucially, it does _not_
allocate with the spinlock held.

I can write it as a full patch if you prefer (and I'll need your help to
test it), but I was really hoping to continue the discussion so you could
spin a v2.

> > > I can summarize some of these details in a comment for this patch.
> >
> > Alternatively, we can just revert the offending commits if we're not able
> > to agree on a simple fix for now. I'd prefer to avoid that though.
> 
> I feel we are not aligned here. We are trying to get the driver to
> work properly with iommufd and expose all the HW features. This has
> been fixed comprehensively and well-reviewed patches have been on the
> list for 7 months now. We want to move forward, not revert things.

I appreciate the effort you're putting in, but this specific patch is
fixing a regression so let's stabilise the base before we continue to
build on top of it.

Will


From eauger at redhat.com  Tue Feb 13 05:59:31 2024
From: eauger at redhat.com (Eric Auger)
Date: Tue, 13 Feb 2024 14:59:31 +0100
Subject: [PATCH v1 2/4] KVM: arm64: Document
 KVM_ARM_GET_REG_WRITABLE_MASKS
In-Reply-To: <20230919175017.538312-3-jingzhangos@google.com>
References: <20230919175017.538312-1-jingzhangos@google.com>
 <20230919175017.538312-3-jingzhangos@google.com>
Message-ID: <82b72bd2-c079-40c3-90b8-30174f2a8fe0@redhat.com>

Hi,

On 9/19/23 19:50, Jing Zhang wrote:
> Add some basic documentation on how to get feature ID register writable
> masks from userspace.
> 
> Signed-off-by: Jing Zhang <jingzhangos at google.com>
> ---
>  Documentation/virt/kvm/api.rst | 42 ++++++++++++++++++++++++++++++++++
>  1 file changed, 42 insertions(+)
> 
> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> index 21a7578142a1..2defb5e198ce 100644
> --- a/Documentation/virt/kvm/api.rst
> +++ b/Documentation/virt/kvm/api.rst
> @@ -6070,6 +6070,48 @@ writes to the CNTVCT_EL0 and CNTPCT_EL0 registers using the SET_ONE_REG
>  interface. No error will be returned, but the resulting offset will not be
>  applied.
>  
> +4.139 KVM_ARM_GET_REG_WRITABLE_MASKS
> +-------------------------------------------
> +
> +:Capability: KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES
> +:Architectures: arm64
> +:Type: vm ioctl
> +:Parameters: struct reg_mask_range (in/out)
> +:Returns: 0 on success, < 0 on error
> +
> +
> +::
> +
> +        #define ARM64_FEATURE_ID_SPACE_SIZE	(3 * 8 * 8)
> +        #define ARM64_FEATURE_ID_RANGE_IDREGS	BIT(0)
> +
> +        struct reg_mask_range {
> +                __u64 addr;             /* Pointer to mask array */
> +                __u32 range;            /* Requested range */
> +                __u32 reserved[13];
> +        };
> +
> +This ioctl copies the writable masks for Feature ID registers to userspace.
> +The Feature ID space is defined as the AArch64 System register space with
> +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}.
when attempting a migration between Ampere Altra and ThunderXv2 the
first hurdle is to handle a failure when writing ICC_CTLR_EL1
(3.0.12.12.4) on dest. This reg is outside of the scope of the above
single range (BIT(0)).

This may be questionable if we want to migrate between those types of
machines but the goal is to exercise different scenarios to have a
gloval view of the problems.

This reg exposes some RO capabilities such as ExtRange, A3V, SEIS,
IDBits, ...
So to get the migration going further I would need to tweek this on the
source - for instance I guess SEIS could be reset despite the host HW
cap - without making too much trouble.

What would you recommend, adding a new range? But I guess we need to
design ranges carefully otherwise we may be quickly limited by the
number of flag bits.

Any suggestion?

Thanks

Eric
> +
> +The mask array pointed to by ``addr`` is indexed by the macro
> +``ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2)``, allowing userspace
> +to know what bits can be changed for the system register described by ``op0,
> +op1, crn, crm, op2``.
> +
> +The ``range`` field describes the requested range of registers. The valid
> +ranges can be retrieved by checking the return value of
> +KVM_CAP_CHECK_EXTENSION_VM for the KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES
> +capability, which will return a bitmask of the supported ranges. Each bit
> +set in the return value represents a possible value for the ``range``
> +field.  At the time of writing, only bit 0 is returned set by the
> +capability, meaning that only the value ``ARM64_FEATURE_ID_RANGE_IDREGS``
> +is valid for ``range``.
> +
> +The ``reserved[13]`` array is reserved for future use and should be 0, or
> +KVM may return an error.
> +
>  5. The kvm_run structure
>  ========================
>  



From jgg at nvidia.com  Tue Feb 13 06:00:33 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 10:00:33 -0400
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240213135627.GD28926@willie-the-truck>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
 <20240208125846.GA23290@willie-the-truck>
 <20240208142729.GH10476@nvidia.com>
 <20240213112015.GB28517@willie-the-truck>
 <20240213121850.GH4048826@nvidia.com>
 <20240213125456.GA28844@willie-the-truck>
 <20240213133045.GA989297@nvidia.com>
 <20240213135627.GD28926@willie-the-truck>
Message-ID: <20240213140033.GB989297@nvidia.com>

On Tue, Feb 13, 2024 at 01:56:28PM +0000, Will Deacon wrote:

> I can write it as a full patch if you prefer (and I'll need your help to
> test it), but I was really hoping to continue the discussion so you could
> spin a v2.

No worries, I'll take care of it, just need to understand what we have
agreed.

Jason


From ryan.roberts at arm.com  Tue Feb 13 06:02:01 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 14:02:01 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <64b872bd-4b12-4dbd-b043-1ad11aeaa19a@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
 <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com>
 <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
 <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com>
 <dce5f80d-942f-439c-a549-5290666464ca@arm.com>
 <CAMj1kXEVf1m4hVXORc6t9ytAOb75KZLcW-OJ6999VaKbkVdQ3A@mail.gmail.com>
 <64b872bd-4b12-4dbd-b043-1ad11aeaa19a@redhat.com>
Message-ID: <3de2130b-9f0f-4a11-ac06-7bf814de641c@arm.com>

On 13/02/2024 13:45, David Hildenbrand wrote:
> On 13.02.24 14:33, Ard Biesheuvel wrote:
>> On Tue, 13 Feb 2024 at 14:21, Ryan Roberts <ryan.roberts at arm.com> wrote:
>>>
>>> On 13/02/2024 13:13, David Hildenbrand wrote:
>>>> On 13.02.24 14:06, Ryan Roberts wrote:
>>>>> On 13/02/2024 12:19, David Hildenbrand wrote:
>>>>>> On 13.02.24 13:06, Ryan Roberts wrote:
>>>>>>> On 12/02/2024 20:38, Ryan Roberts wrote:
>>>>>>>> [...]
>>>>>>>>
>>>>>>>>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>>>>>>>>> +{
>>>>>>>>>>>> +??? /*
>>>>>>>>>>>> +???? * Don't attempt to apply the contig bit to kernel mappings,
>>>>>>>>>>>> because
>>>>>>>>>>>> +???? * dynamically adding/removing the contig bit can cause page
>>>>>>>>>>>> faults.
>>>>>>>>>>>> +???? * These racing faults are ok for user space, since they get
>>>>>>>>>>>> serialized
>>>>>>>>>>>> +???? * on the PTL. But kernel mappings can't tolerate faults.
>>>>>>>>>>>> +???? */
>>>>>>>>>>>> +??? return mm != &init_mm;
>>>>>>>>>>>> +}
>>>>>>>>>>>
>>>>>>>>>>> We also have the efi_mm as a non-user mm, though I don't think we
>>>>>>>>>>> manipulate
>>>>>>>>>>> that while it is live, and I'm not sure if that needs any special
>>>>>>>>>>> handling.
>>>>>>>>>>
>>>>>>>>>> Well we never need this function in the hot (order-0 folio) path, so I
>>>>>>>>>> think I
>>>>>>>>>> could add a check for efi_mm here with performance implication. It's
>>>>>>>>>> probably
>>>>>>>>>> safest to explicitly exclude it? What do you think?
>>>>>>>>>
>>>>>>>>> Oops: This should have read "I think I could add a check for efi_mm here
>>>>>>>>> *without* performance implication"
>>>>>>>>
>>>>>>>> It turns out that efi_mm is only defined when CONFIG_EFI is enabled I
>>>>>>>> can do
>>>>>>>> this:
>>>>>>>>
>>>>>>>> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
>>>>>>>>
>>>>>>>> Is that acceptable? This is my preference, but nothing else outside of efi
>>>>>>>> references this symbol currently.
>>>>>>>>
>>>>>>>> Or perhaps I can convince myself that its safe to treat efi_mm like
>>>>>>>> userspace.
>>>>>>>> There are a couple of things that need to be garanteed for it to be safe:
>>>>>>>>
>>>>>>>> ???? - The PFNs of present ptes either need to have an associated struct
>>>>>>>> page or
>>>>>>>> ?????? need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
>>>>>>>> ?????? pte_mkdevmap())
>>>>>>>>
>>>>>>>> ???? - Live mappings must either be static (no changes that could cause
>>>>>>>> fold/unfold
>>>>>>>> ?????? while live) or the system must be able to tolerate a temporary fault
>>>>>>>>
>>>>>>>> Mark suggests efi_mm is not manipulated while live, so that meets the
>>>>>>>> latter
>>>>>>>> requirement, but I'm not sure about the former?
>>>>>>>
>>>>>>> I've gone through all the efi code, and conclude that, as Mark suggests, the
>>>>>>> mappings are indeed static. And additionally, the ptes are populated
>>>>>>> using only
>>>>>>> the _private_ ptep API, so there is no issue here. As just discussed with
>>>>>>> Mark,
>>>>>>> my prefereence is to not make any changes to code, and just add a comment
>>>>>>> describing why efi_mm is safe.
>>>>>>>
>>>>>>> Details:
>>>>>>>
>>>>>>> * Registered with ptdump
>>>>>>> ?????? * ptep_get_lockless()
>>>>>>> * efi_create_mapping -> create_pgd_mapping ? -> init_pte:
>>>>>>> ?????? * __ptep_get()
>>>>>>> ?????? * __set_pte()
>>>>>>> * efi_memattr_apply_permissions -> efi_set_mapping_permissions ? ->
>>>>>>> set_permissions
>>>>>>> ?????? * __ptep_get()
>>>>>>> ?????? * __set_pte()
>>>>>>
>>>>>> Sound good. We could add some VM_WARN_ON if we ever get the efi_mm via the
>>>>>> "official" APIs.
>>>>>
>>>>> We could, but that would lead to the same linkage issue, which I'm trying to
>>>>> avoid in the first place:
>>>>>
>>>>> VM_WARN_ON(IS_ENABLED(CONFIG_EFI) && mm == efi_mm);
>>>>>
>>>>> This creates new source code dependencies, which I would rather avoid if
>>>>> possible.
>>>>
>>>> Just a thought, you could have a is_efi_mm() function that abstracts all that.
>>>>
>>>> diff --git a/include/linux/efi.h b/include/linux/efi.h
>>>> index c74f47711f0b..152f5fa66a2a 100644
>>>> --- a/include/linux/efi.h
>>>> +++ b/include/linux/efi.h
>>>> @@ -692,6 +692,15 @@ extern struct efi {
>>>>
>>>> ? extern struct mm_struct efi_mm;
>>>>
>>>> +static inline void is_efi_mm(struct mm_struct *mm)
>>>> +{
>>>> +#ifdef CONFIG_EFI
>>>> +?????? return mm == &efi_mm;
>>>> +#else
>>>> +?????? return false;
>>>> +#endif
>>>> +}
>>>> +
>>>> ? static inline int
>>>> ? efi_guidcmp (efi_guid_t left, efi_guid_t right)
>>>> ? {
>>>>
>>>>
>>>
>>> That would definitely work, but in that case, I might as well just check for it
>>> in mm_is_user() (and personally I would change the name to mm_is_efi()):
>>>
>>>
>>> static inline bool mm_is_user(struct mm_struct *mm)
>>> {
>>> ???????? return mm != &init_mm && !mm_is_efi(mm);
>>> }
>>>
>>> Any objections?
>>>
>>
>> Any reason not to use IS_ENABLED(CONFIG_EFI) in the above? The extern
>> declaration is visible to the compiler, and any references should
>> disappear before the linker could notice that efi_mm does not exist.
>>
> 
> Sure, as long as the linker is happy why not. I'll let Ryan mess with that :)

I'm not sure if you are suggesting dropping the mm_is_efi() helper and just use
IS_ENABLED(CONFIG_EFI) in mm_is_user() to guard efi_mm, or if you are suggesting
using IS_ENABLED(CONFIG_EFI) in mm_is_efi() instead of the ifdefery?

The former was what I did initially; It works great, but I didn't like that I
was introducing a new code dependecy between efi and arm64 (nothing else outside
of efi references efi_mm).

So then concluded that it is safe to not worry about efi_mm (thanks for your
confirmation). But then David wanted a VM_WARN check, which reintroduces the
code dependency. So he suggested the mm_is_efi() helper to hide that... This is
all starting to feel circular...

Since I've jsut updated the code to do it David's way, I propose leaving it as
is since nobody has strong feelings.

> 
>> In any case, feel free to add
>>
>> Acked-by: Ard Biesheuvel <ardb at kernel.org>

Great thanks!

> 
> Thanks for the review.
> 



From mripard at kernel.org  Tue Feb 13 06:04:05 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 13 Feb 2024 15:04:05 +0100
Subject: [RFC PATCH 2/3] drm/tidss: Add support for display sharing
In-Reply-To: <88018f5f-a7db-7278-e5c3-bb1dbf0e3f14@ti.com>
References: <20240116134142.2092483-1-devarsht@ti.com>
 <20240116134142.2092483-3-devarsht@ti.com>
 <vgfzhamtiwkpdyk5ndagsb63subclinotoe6tsi3wu6z7454ec@igxfzjc5gyqm>
 <88018f5f-a7db-7278-e5c3-bb1dbf0e3f14@ti.com>
Message-ID: <qiqrhpqtnox47wj6az7t3fjp4vc6k32fw42tp5slqggrhe6utb@i7lkpaf3v3od>

Hi Devarsh,

On Thu, Feb 08, 2024 at 06:26:17PM +0530, Devarsh Thakkar wrote:
> Hi Maxime,
> 
> Thanks a lot for checking on this.
> 
> On 26/01/24 17:45, Maxime Ripard wrote:
> > Hi,
> > 
> > Thanks a lot for working on that.
> > 
> > On Tue, Jan 16, 2024 at 07:11:41PM +0530, Devarsh Thakkar wrote:
> >> Display subsystem present in TI Keystone family of devices supports sharing
> >> of display between multiple hosts as it provides separate register space
> >> (common* region) for each host to programming display controller and also a
> >> unique interrupt line for each host.
> >>
> >> This adds support for display sharing, by allowing partitioning of
> >> resources either at video port level or at video plane level as
> >> described below :
> >>
> >> 1) Linux can own (i.e have write access) completely one or more of video
> >> ports along with corresponding resources (viz. overlay managers,
> >> video planes) used by Linux in context of those video ports.
> >> Even if Linux is owning
> >> these video ports it can still share this video port with a remote core
> >> which can own one or more video planes associated with this video port.
> >>
> >> 2) Linux owns one or more of the video planes with video port
> >> (along with corresponding overlay manager) associated with these planes
> >> being owned and controlled by a remote core. Linux still has read-only
> >> access to the associated video port and overlay managers so that it can
> >> parse the settings made by remote core.
> > 
> > So, just to make sure we're on the same page. 1) means Linux drives the
> > whole display engine, but can lend planes to the R5? How does that work,
> > is Linux aware of the workload being there (plane size, format, etc) ?
> > 
> 
> Well, there is no dynamic procedure being followed for lending. The
> partitioning scheme is decided and known before hand, and the remote
> core firmware updated and compiled accordingly, and similarly the
> device-tree overlay for Linux is also updated with partitioning
> information before bootup.
> 
> What would happen here is that Linux will know before-hand this
> partitioning information via device-tree properties and won't enumerate
> the plane owned by RTOS, but it will enumerate the rest of the display
> components and initialize the DSS, after which user can load the DSS
> firmware on remote core and this firmware will only have control of
> plane as it was compiled with that configuration.

Right. If the RTOS is in control of a single plane, how it is expected
to deal with Linux shutting the CRTC down, or enforcing a configuration
that isn't compatible with what the RTOS expects (like a plane with a
higher zpos masking its plane), what is the mechanism to reconcile it?

> > And 2) would mean that the display engine is under the R5 control and
> > Linux only gets to fill the plane and let the firmware know of what it
> > wants?
> > 
> 
> Here too the partitioning information is pre-decided and remote core
> firmware and device-tree overlay for Linux updated accordingly. But in
> this case as remote core firmware owns the display (minus the plane
> owned by Linux) it is started and initialized during the bootloader
> phase itself where it initializes the DSS and starts rendering using the
> plane owned by it and Linux just latches to the DSS without
> re-initializing it, with write access only to the plane that is owned by
> Linux. You can refer [1] for more details on this.
>
> > If so, do we even need the tidss driver in the second case? We could
> > just write a fwkms driver of some sorts that could be used by multiple
> > implementations of the same "defer to firmware" logic.
> > 
> 
> This feature of static partitioning of DSS resources is specific to DSS7
> hardware (which is controlled by tidss driver) which supports dedicated
> register space and interrupt line for each of the hosts [0], so that
> multiple hosts can drive the display controller simultaneously as  per
> the desired static partitioning of resources, and so I don't think a
> separate driver is required here and tidss seems the right place to
> support this, where using this device-tree approach different resource
> partitioning schemas can be achieved as described here [1]. This was
> also aligned with Tomi too where we discussed that tidss is the right
> place to support this as we are simply leveraging the DSS hardware
> capabilities of static partitioning here.

If the only thing tidss does in the "owned by RTOS" is forwarding KMS
atomic states to the RTOS, then I'm still not sure why we need to
involve tidss at all.

It's not just about interrupts, it's also about how your arbitrate
between what Linux wants and what the RTOS wants. Like if the RTOS still
wants to output something but Linux wants to disable it, how do you
reconcile the two?

You have to have something that reconciles both, and typically for
firmware-based setup this will be the firmware's job.

That's very similar to what the RaspberryPi did with fkms, and I believe
that having a generic KMS-on-remoteproc driver when the firmware has
control over the display is the path forward.

> >> For both the cases, the resources used in context of processing core
> >> running Linux along with ownership information are exposed by user as
> >> part of device-tree blob and driver uses an updated feature list tailored
> >> for this shared mode accordingly. The driver also auto-populates
> >> matching overlay managers and output types from shared video
> >> port list provided in device-tree blob.
> >> In dispc_feature struct remove const access specfier for output_type
> >> array as it is required to be updated dynamically in run-time for shared
> >> mode.
> > 
> > I'm also not entirely sure that the device tree is the right path there.
> > Surely the firmware capabilities will evolve over time, while the device
> > tree won't. Is there some way to make it discoverable at probe time by
> > the driver?
>
> I think the main highlight of the sharing feature is the hardware
> capability where each host is provided separate irq and register space
> to program display for their display context independently

Wait, what do you mean by display context here?

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/20240213/e7240bc5/attachment-0001.sig>

From david at redhat.com  Tue Feb 13 06:05:14 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 13 Feb 2024 15:05:14 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <3de2130b-9f0f-4a11-ac06-7bf814de641c@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
 <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com>
 <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
 <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com>
 <dce5f80d-942f-439c-a549-5290666464ca@arm.com>
 <CAMj1kXEVf1m4hVXORc6t9ytAOb75KZLcW-OJ6999VaKbkVdQ3A@mail.gmail.com>
 <64b872bd-4b12-4dbd-b043-1ad11aeaa19a@redhat.com>
 <3de2130b-9f0f-4a11-ac06-7bf814de641c@arm.com>
Message-ID: <f93e5552-5e46-4f49-918a-21b63156eb32@redhat.com>

On 13.02.24 15:02, Ryan Roberts wrote:
> On 13/02/2024 13:45, David Hildenbrand wrote:
>> On 13.02.24 14:33, Ard Biesheuvel wrote:
>>> On Tue, 13 Feb 2024 at 14:21, Ryan Roberts <ryan.roberts at arm.com> wrote:
>>>>
>>>> On 13/02/2024 13:13, David Hildenbrand wrote:
>>>>> On 13.02.24 14:06, Ryan Roberts wrote:
>>>>>> On 13/02/2024 12:19, David Hildenbrand wrote:
>>>>>>> On 13.02.24 13:06, Ryan Roberts wrote:
>>>>>>>> On 12/02/2024 20:38, Ryan Roberts wrote:
>>>>>>>>> [...]
>>>>>>>>>
>>>>>>>>>>>>> +static inline bool mm_is_user(struct mm_struct *mm)
>>>>>>>>>>>>> +{
>>>>>>>>>>>>> +??? /*
>>>>>>>>>>>>> +???? * Don't attempt to apply the contig bit to kernel mappings,
>>>>>>>>>>>>> because
>>>>>>>>>>>>> +???? * dynamically adding/removing the contig bit can cause page
>>>>>>>>>>>>> faults.
>>>>>>>>>>>>> +???? * These racing faults are ok for user space, since they get
>>>>>>>>>>>>> serialized
>>>>>>>>>>>>> +???? * on the PTL. But kernel mappings can't tolerate faults.
>>>>>>>>>>>>> +???? */
>>>>>>>>>>>>> +??? return mm != &init_mm;
>>>>>>>>>>>>> +}
>>>>>>>>>>>>
>>>>>>>>>>>> We also have the efi_mm as a non-user mm, though I don't think we
>>>>>>>>>>>> manipulate
>>>>>>>>>>>> that while it is live, and I'm not sure if that needs any special
>>>>>>>>>>>> handling.
>>>>>>>>>>>
>>>>>>>>>>> Well we never need this function in the hot (order-0 folio) path, so I
>>>>>>>>>>> think I
>>>>>>>>>>> could add a check for efi_mm here with performance implication. It's
>>>>>>>>>>> probably
>>>>>>>>>>> safest to explicitly exclude it? What do you think?
>>>>>>>>>>
>>>>>>>>>> Oops: This should have read "I think I could add a check for efi_mm here
>>>>>>>>>> *without* performance implication"
>>>>>>>>>
>>>>>>>>> It turns out that efi_mm is only defined when CONFIG_EFI is enabled I
>>>>>>>>> can do
>>>>>>>>> this:
>>>>>>>>>
>>>>>>>>> return mm != &init_mm && (!IS_ENABLED(CONFIG_EFI) || mm != &efi_mm);
>>>>>>>>>
>>>>>>>>> Is that acceptable? This is my preference, but nothing else outside of efi
>>>>>>>>> references this symbol currently.
>>>>>>>>>
>>>>>>>>> Or perhaps I can convince myself that its safe to treat efi_mm like
>>>>>>>>> userspace.
>>>>>>>>> There are a couple of things that need to be garanteed for it to be safe:
>>>>>>>>>
>>>>>>>>>  ???? - The PFNs of present ptes either need to have an associated struct
>>>>>>>>> page or
>>>>>>>>>  ?????? need to have the PTE_SPECIAL bit set (either pte_mkspecial() or
>>>>>>>>>  ?????? pte_mkdevmap())
>>>>>>>>>
>>>>>>>>>  ???? - Live mappings must either be static (no changes that could cause
>>>>>>>>> fold/unfold
>>>>>>>>>  ?????? while live) or the system must be able to tolerate a temporary fault
>>>>>>>>>
>>>>>>>>> Mark suggests efi_mm is not manipulated while live, so that meets the
>>>>>>>>> latter
>>>>>>>>> requirement, but I'm not sure about the former?
>>>>>>>>
>>>>>>>> I've gone through all the efi code, and conclude that, as Mark suggests, the
>>>>>>>> mappings are indeed static. And additionally, the ptes are populated
>>>>>>>> using only
>>>>>>>> the _private_ ptep API, so there is no issue here. As just discussed with
>>>>>>>> Mark,
>>>>>>>> my prefereence is to not make any changes to code, and just add a comment
>>>>>>>> describing why efi_mm is safe.
>>>>>>>>
>>>>>>>> Details:
>>>>>>>>
>>>>>>>> * Registered with ptdump
>>>>>>>>  ?????? * ptep_get_lockless()
>>>>>>>> * efi_create_mapping -> create_pgd_mapping ? -> init_pte:
>>>>>>>>  ?????? * __ptep_get()
>>>>>>>>  ?????? * __set_pte()
>>>>>>>> * efi_memattr_apply_permissions -> efi_set_mapping_permissions ? ->
>>>>>>>> set_permissions
>>>>>>>>  ?????? * __ptep_get()
>>>>>>>>  ?????? * __set_pte()
>>>>>>>
>>>>>>> Sound good. We could add some VM_WARN_ON if we ever get the efi_mm via the
>>>>>>> "official" APIs.
>>>>>>
>>>>>> We could, but that would lead to the same linkage issue, which I'm trying to
>>>>>> avoid in the first place:
>>>>>>
>>>>>> VM_WARN_ON(IS_ENABLED(CONFIG_EFI) && mm == efi_mm);
>>>>>>
>>>>>> This creates new source code dependencies, which I would rather avoid if
>>>>>> possible.
>>>>>
>>>>> Just a thought, you could have a is_efi_mm() function that abstracts all that.
>>>>>
>>>>> diff --git a/include/linux/efi.h b/include/linux/efi.h
>>>>> index c74f47711f0b..152f5fa66a2a 100644
>>>>> --- a/include/linux/efi.h
>>>>> +++ b/include/linux/efi.h
>>>>> @@ -692,6 +692,15 @@ extern struct efi {
>>>>>
>>>>>  ? extern struct mm_struct efi_mm;
>>>>>
>>>>> +static inline void is_efi_mm(struct mm_struct *mm)
>>>>> +{
>>>>> +#ifdef CONFIG_EFI
>>>>> +?????? return mm == &efi_mm;
>>>>> +#else
>>>>> +?????? return false;
>>>>> +#endif
>>>>> +}
>>>>> +
>>>>>  ? static inline int
>>>>>  ? efi_guidcmp (efi_guid_t left, efi_guid_t right)
>>>>>  ? {
>>>>>
>>>>>
>>>>
>>>> That would definitely work, but in that case, I might as well just check for it
>>>> in mm_is_user() (and personally I would change the name to mm_is_efi()):
>>>>
>>>>
>>>> static inline bool mm_is_user(struct mm_struct *mm)
>>>> {
>>>>  ???????? return mm != &init_mm && !mm_is_efi(mm);
>>>> }
>>>>
>>>> Any objections?
>>>>
>>>
>>> Any reason not to use IS_ENABLED(CONFIG_EFI) in the above? The extern
>>> declaration is visible to the compiler, and any references should
>>> disappear before the linker could notice that efi_mm does not exist.
>>>
>>
>> Sure, as long as the linker is happy why not. I'll let Ryan mess with that :)
> 
> I'm not sure if you are suggesting dropping the mm_is_efi() helper and just use
> IS_ENABLED(CONFIG_EFI) in mm_is_user() to guard efi_mm, or if you are suggesting
> using IS_ENABLED(CONFIG_EFI) in mm_is_efi() instead of the ifdefery?
> 
> The former was what I did initially; It works great, but I didn't like that I
> was introducing a new code dependecy between efi and arm64 (nothing else outside
> of efi references efi_mm).
> 
> So then concluded that it is safe to not worry about efi_mm (thanks for your
> confirmation). But then David wanted a VM_WARN check, which reintroduces the
> code dependency. So he suggested the mm_is_efi() helper to hide that... This is
> all starting to feel circular...

I think Ard meant that inside mm_is_efi(), we could avoid the #ifdef and 
simply use IS_ENABLED().

-- 
Cheers,

David / dhildenb



From will at kernel.org  Tue Feb 13 06:09:00 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 13 Feb 2024 14:09:00 +0000
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
In-Reply-To: <20240213134726.GK765010@ziepe.ca>
References: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
 <20240213121257.GI765010@ziepe.ca>
 <20240213121934.GA28726@willie-the-truck>
 <20240213125303.GJ765010@ziepe.ca>
 <20240213125951.GB28844@willie-the-truck>
 <20240213134726.GK765010@ziepe.ca>
Message-ID: <20240213140900.GE28926@willie-the-truck>

Hey Jason,

On Tue, Feb 13, 2024 at 09:47:26AM -0400, Jason Gunthorpe wrote:
> On Tue, Feb 13, 2024 at 12:59:52PM +0000, Will Deacon wrote:
> > > The typical kernel standard is to fix bugs in patches and only reach
> > > for a wholesale revert if the community is struggling with bug
> > > fixing. Dmitry already tested removing that hunk, Robin explained the
> > > issue, we understand the bug fix is to remove the
> > > arm_smmu_init_domain_context() call. Nothing justifies a full scale
> > > revert.
> > 
> > I can't say I'm aware of any consensus for how to handle this, to be
> > completely honest with you. 
> 
> Well, I work in a lot of subsystems and this is a surprise to me and
> not something I've seen before. Fix the bug, move forward. Reverts are
> a cultural admission of failure. I use threats of a revert as a hammer
> to encourage people to pay attention to the bugs. I hardly ever
> actually revert things. What does reverting their code say to my
> submitters???

Huh. I guess I'm lucky never to have worked in a environment where that
is the case. In fact, my experience is quite the opposite: revert first
so that things get back to a working state and the developer/submitter
has some breathing room to rework the broken code. It's actually fairly
blameless if you get it right and when you have a half-functional CI it's
pretty much a necessity. Anyway, I digress...

So if you see me appearing to be heavy-handed with reverts when dealing
with regressions, it's really nothing tactical. Rather, it's purely
about keeping the driver in a known functional state.

> > > I'll send another patch if you want, but it seems like a waste of all
> > > our time.
> > 
> > It's a bug fix, of course it's a waste of time! We're talking minutes
> > though, right?
> 
> It becomes hard for maintainers to juggle the tress since you have to
> send the revert to -rc and the fix on top of the rc to next. Again, I
> will send the patch, just discussing.

I've never had any difficulty managing that, so I think we'll be ok.
Worst case, I can merge my fixes queue into my next queue.

Will


From ardb at kernel.org  Tue Feb 13 06:08:39 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 13 Feb 2024 15:08:39 +0100
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <f93e5552-5e46-4f49-918a-21b63156eb32@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com> <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com> <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com> <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com> <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
 <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com> <dce5f80d-942f-439c-a549-5290666464ca@arm.com>
 <CAMj1kXEVf1m4hVXORc6t9ytAOb75KZLcW-OJ6999VaKbkVdQ3A@mail.gmail.com>
 <64b872bd-4b12-4dbd-b043-1ad11aeaa19a@redhat.com> <3de2130b-9f0f-4a11-ac06-7bf814de641c@arm.com>
 <f93e5552-5e46-4f49-918a-21b63156eb32@redhat.com>
Message-ID: <CAMj1kXEK6wiHkO9sJ5h6D3L88dR=2UndEqGeQjv=TftZ3PnN9w@mail.gmail.com>

On Tue, 13 Feb 2024 at 15:05, David Hildenbrand <david at redhat.com> wrote:
>
> On 13.02.24 15:02, Ryan Roberts wrote:
> > On 13/02/2024 13:45, David Hildenbrand wrote:
> >> On 13.02.24 14:33, Ard Biesheuvel wrote:
> >>> On Tue, 13 Feb 2024 at 14:21, Ryan Roberts <ryan.roberts at arm.com> wrote:
> >>>>
> >>>> On 13/02/2024 13:13, David Hildenbrand wrote:
...
> >>>>> Just a thought, you could have a is_efi_mm() function that abstracts all that.
> >>>>>
> >>>>> diff --git a/include/linux/efi.h b/include/linux/efi.h
> >>>>> index c74f47711f0b..152f5fa66a2a 100644
> >>>>> --- a/include/linux/efi.h
> >>>>> +++ b/include/linux/efi.h
> >>>>> @@ -692,6 +692,15 @@ extern struct efi {
> >>>>>
> >>>>>    extern struct mm_struct efi_mm;
> >>>>>
> >>>>> +static inline void is_efi_mm(struct mm_struct *mm)
> >>>>> +{
> >>>>> +#ifdef CONFIG_EFI
> >>>>> +       return mm == &efi_mm;
> >>>>> +#else
> >>>>> +       return false;
> >>>>> +#endif
> >>>>> +}
> >>>>> +
> >>>>>    static inline int
> >>>>>    efi_guidcmp (efi_guid_t left, efi_guid_t right)
> >>>>>    {
> >>>>>
> >>>>>
> >>>>
> >>>> That would definitely work, but in that case, I might as well just check for it
> >>>> in mm_is_user() (and personally I would change the name to mm_is_efi()):
> >>>>
> >>>>
> >>>> static inline bool mm_is_user(struct mm_struct *mm)
> >>>> {
> >>>>           return mm != &init_mm && !mm_is_efi(mm);
> >>>> }
> >>>>
> >>>> Any objections?
> >>>>
> >>>
> >>> Any reason not to use IS_ENABLED(CONFIG_EFI) in the above? The extern
> >>> declaration is visible to the compiler, and any references should
> >>> disappear before the linker could notice that efi_mm does not exist.
> >>>
> >>
> >> Sure, as long as the linker is happy why not. I'll let Ryan mess with that :)
> >
> > I'm not sure if you are suggesting dropping the mm_is_efi() helper and just use
> > IS_ENABLED(CONFIG_EFI) in mm_is_user() to guard efi_mm, or if you are suggesting
> > using IS_ENABLED(CONFIG_EFI) in mm_is_efi() instead of the ifdefery?
> >
> > The former was what I did initially; It works great, but I didn't like that I
> > was introducing a new code dependecy between efi and arm64 (nothing else outside
> > of efi references efi_mm).
> >
> > So then concluded that it is safe to not worry about efi_mm (thanks for your
> > confirmation). But then David wanted a VM_WARN check, which reintroduces the
> > code dependency. So he suggested the mm_is_efi() helper to hide that... This is
> > all starting to feel circular...
>
> I think Ard meant that inside mm_is_efi(), we could avoid the #ifdef and
> simply use IS_ENABLED().
>

Yes.

static inline void mm_is_efi(struct mm_struct *mm)
{
    return IS_ENABLED(CONFIG_EFI) && mm == &efi_mm;
}


From wenst at chromium.org  Tue Feb 13 06:13:17 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 13 Feb 2024 22:13:17 +0800
Subject: [PATCH 3/3] nvmem: mtk-efuse: Drop NVMEM device name
In-Reply-To: <92d4d421-54a8-4a41-8b47-61ae39b55ebb@linaro.org>
References: <20240130095656.3712469-1-wenst@chromium.org> <20240130095656.3712469-4-wenst@chromium.org>
 <92d4d421-54a8-4a41-8b47-61ae39b55ebb@linaro.org>
Message-ID: <CAGXv+5Ej1cEiNegMEf9GOMYTiabiBU1DpfC7QkQAsHEjuNPCxA@mail.gmail.com>

On Tue, Feb 13, 2024 at 9:07?PM Srinivas Kandagatla
<srinivas.kandagatla at linaro.org> wrote:
>
>
>
> On 30/01/2024 09:56, Chen-Yu Tsai wrote:
> > The MT8183 has not one but two efuse devices. The static name and ID
> > causes the second efuse device to fail to probe, due to duplicate sysfs
> > entries.
>
> have you considered using NVMEM_DEVID_AUTO?

Yes, that was considered and what is actually implemented downstream.

However, since the reason for using a custom name no longer exists, it
seems simpler to just revert to the previous behavior, which is to let
the nvmem core deal with naming.


ChenYu

> --srini
> >
> > With the rework of the mtk-socinfo driver, lookup by name is no longer
> > necessary. The custom name can simply be dropped.
> >
> > Fixes: 4e6102d60d88 ("nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse")
> > Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> > ---
> >   drivers/nvmem/mtk-efuse.c | 1 -
> >   1 file changed, 1 deletion(-)
> >
> > diff --git a/drivers/nvmem/mtk-efuse.c b/drivers/nvmem/mtk-efuse.c
> > index f5bebcecf9bd..9caf04667341 100644
> > --- a/drivers/nvmem/mtk-efuse.c
> > +++ b/drivers/nvmem/mtk-efuse.c
> > @@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platform_device *pdev)
> >       econfig.size = resource_size(res);
> >       econfig.priv = priv;
> >       econfig.dev = dev;
> > -     econfig.name = "mtk-efuse";
> >       if (pdata->uses_post_processing)
> >               econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
> >       nvmem = devm_nvmem_register(dev, &econfig);


From michal.vokac at ysoft.com  Tue Feb 13 06:14:36 2024
From: michal.vokac at ysoft.com (=?UTF-8?B?TWljaGFsIFZva8OhxI0=?=)
Date: Tue, 13 Feb 2024 15:14:36 +0100
Subject: [PATCH 1/2] ARM: dts: imx6dl-yapp4: Fix the QCA switch register
 address
In-Reply-To: <e00ed8cb-f73d-48a6-9999-f5acd5a202a0@lunn.ch>
References: <1707751422-31517-1-git-send-email-michal.vokac@ysoft.com>
 <c5dad8e7-c486-4dd9-bfb5-bdfa2ddc18b3@lunn.ch>
 <db282aa5-2db3-49b9-a7dd-86e94226aa7b@ysoft.com>
 <e00ed8cb-f73d-48a6-9999-f5acd5a202a0@lunn.ch>
Message-ID: <f3b75b82-2ff4-491c-8abf-1ba86171260d@ysoft.com>

On 13. 02. 24 14:10, Andrew Lunn wrote:
> On Tue, Feb 13, 2024 at 01:20:44PM +0100, Michal Vok?? wrote:
>> On 12. 02. 24 17:08, Andrew Lunn wrote:
>>> On Mon, Feb 12, 2024 at 04:23:41PM +0100, Michal Vok?? wrote:
>> The fact is that the switch actually works regardless of the reg value.
>> It worked prior to the 15b43e497ffd commit with address 0, it worked
>> later on with the reg value 10 and it works now with reg value 0x10.
> 
> Ah, so that is the missing piece of information from the commit
> message. That the reg value does not actually matter. Hence it is safe
> to change it.
> 
> Please reword the commit message.

OK, I will do so.

>> I admit that my understanding of the MDIO bus and addressing of
>> the connected external/internal devices is pretty limited. I have no
>> answer to why it works like that but as you brought up your questions
>> I would actually like to know as well.
> 
> My guess is, the switch assumes it has full access to all the
> addresses on the bus. It probably uses a subset, but that subset is
> hard coded. But the MDIO DT binding requires a valid reg value, so
> something has to be used.

That makes sense. The problem is that the MDIO?access and addressing
of the QCA8K switch is not well documented in the datasheet.

> There are some devices which use a single address on the bus. The
> mv88e6xxx can be strapped into such a mode, so you can have multiple
> switches on the bus. The reg value is then used. But you can also
> strap it so it takes over the whole bus, and uses #num_ports + 3
> addresses on the bus, and those addresses are hard coded in the
> silicon, so the reg value is ignored.

Ah, yes I am actually aware of that feature on the mv88e6xxx. We use
it on newer board revisions. AFAIK the switch is by default strapped
to the single chip addressing mode by internal pull-ups.

Thank you very much for shedding some light to that topic!

Michal


From shradha.t at samsung.com  Tue Feb 13 05:27:49 2024
From: shradha.t at samsung.com (Shradha Todi)
Date: Tue, 13 Feb 2024 18:57:49 +0530
Subject: [PATCH v5 0/2] Add helper function to get and enable all bulk
 clocks
References: <CGME20240213132759epcas5p4896fd9d0b1af7762ff98ae9e586492dc@epcas5p4.samsung.com>
Message-ID: <20240213132751.46813-1-shradha.t@samsung.com>

Create a managed API wrapper to get all the bulk clocks and enable them
as it is a very common practice in many drivers. The second patch uses
this API to adapt to clk_bulk_* APIs in the exynos driver.
v1:
 - https://lore.kernel.org/lkml/20231009062216.6729-1-shradha.t at samsung.com/
v2:
 - https://lore.kernel.org/lkml/20231115065621.27014-1-shradha.t at samsung.com/
 - Addressed Manivannan's comments to improve patch
v3:
 - https://lore.kernel.org/all/20240110110115.56270-1-shradha.t at samsung.com/
 - Took Marek's suggestion to make a common bulk clk wrapper and use it in
   the exynos driver
v4:
 - https://lore.kernel.org/all/20240124103838.32478-1-shradha.t at samsung.com/
 - Addressed Alim and Manivannan's comments
 - Changed enabled->enable and disabled->disable in function name
 - Remove num_clks out parameter as it is not required by user
 - Removed exit callback and used function name directly in release
v5:
 - Rephrased comments for better readability

Shradha Todi (2):
  clk: Provide managed helper to get and enable bulk clocks
  PCI: exynos: Adapt to clk_bulk_* APIs

 drivers/clk/clk-devres.c                | 40 ++++++++++++++++++
 drivers/pci/controller/dwc/pci-exynos.c | 54 ++-----------------------
 include/linux/clk.h                     | 23 +++++++++++
 3 files changed, 67 insertions(+), 50 deletions(-)

-- 
2.17.1



From shradha.t at samsung.com  Tue Feb 13 05:27:50 2024
From: shradha.t at samsung.com (Shradha Todi)
Date: Tue, 13 Feb 2024 18:57:50 +0530
Subject: [PATCH v5 1/2] clk: Provide managed helper to get and enable bulk
 clocks
In-Reply-To: <20240213132751.46813-1-shradha.t@samsung.com>
References: <20240213132751.46813-1-shradha.t@samsung.com>
	<CGME20240213132806epcas5p43e394aea91c61797a8cc3a901e0cf574@epcas5p4.samsung.com>
Message-ID: <20240213132751.46813-2-shradha.t@samsung.com>

Provide a managed devm_clk_bulk* wrapper to get and enable all
bulk clocks in order to simplify drivers that keeps all clocks
enabled for the time of driver operation.

Suggested-by: Marek Szyprowski <m.szyprowski at samsung.com>
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/clk/clk-devres.c | 40 ++++++++++++++++++++++++++++++++++++++++
 include/linux/clk.h      | 23 +++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 4fb4fd4b06bd..cbbd2cc339c3 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -182,6 +182,46 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all);
 
+static void devm_clk_bulk_release_all_enable(struct device *dev, void *res)
+{
+	struct clk_bulk_devres *devres = res;
+
+	clk_bulk_disable_unprepare(devres->num_clks, devres->clks);
+	clk_bulk_put_all(devres->num_clks, devres->clks);
+}
+
+int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
+					      struct clk_bulk_data **clks)
+{
+	struct clk_bulk_devres *devres;
+	int ret;
+
+	devres = devres_alloc(devm_clk_bulk_release_all_enable,
+			      sizeof(*devres), GFP_KERNEL);
+	if (!devres)
+		return -ENOMEM;
+
+	ret = clk_bulk_get_all(dev, &devres->clks);
+	if (ret > 0) {
+		*clks = devres->clks;
+		devres->num_clks = ret;
+	} else {
+		devres_free(devres);
+		return ret;
+	}
+
+	ret = clk_bulk_prepare_enable(devres->num_clks, *clks);
+	if (!ret) {
+		devres_add(dev, devres);
+	} else {
+		clk_bulk_put_all(devres->num_clks, devres->clks);
+		devres_free(devres);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enable);
+
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
 	struct clk **c = res;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1ef013324237..85a9330d5a5a 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -438,6 +438,22 @@ int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks,
 int __must_check devm_clk_bulk_get_all(struct device *dev,
 				       struct clk_bulk_data **clks);
 
+/**
+ * devm_clk_bulk_get_all_enable - Get and enable all clocks of the consumer (managed)
+ * @dev: device for clock "consumer"
+ * @clks: pointer to the clk_bulk_data table of consumer
+ *
+ * Returns success (0) or negative errno.
+ *
+ * This helper function allows drivers to get all clocks of the
+ * consumer and enables them in one operation with management.
+ * The clks will automatically be disabled and freed when the device
+ * is unbound.
+ */
+
+int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
+					      struct clk_bulk_data **clks);
+
 /**
  * devm_clk_get - lookup and obtain a managed reference to a clock producer.
  * @dev: device for clock "consumer"
@@ -960,6 +976,13 @@ static inline int __must_check devm_clk_bulk_get_all(struct device *dev,
 	return 0;
 }
 
+static inline int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
+						struct clk_bulk_data **clks)
+{
+
+	return 0;
+}
+
 static inline struct clk *devm_get_clk_from_child(struct device *dev,
 				struct device_node *np, const char *con_id)
 {
-- 
2.17.1



From shradha.t at samsung.com  Tue Feb 13 05:27:51 2024
From: shradha.t at samsung.com (Shradha Todi)
Date: Tue, 13 Feb 2024 18:57:51 +0530
Subject: [PATCH v5 2/2] PCI: exynos: Adapt to clk_bulk_* APIs
In-Reply-To: <20240213132751.46813-1-shradha.t@samsung.com>
References: <20240213132751.46813-1-shradha.t@samsung.com>
	<CGME20240213132810epcas5p22316ffa73fd9b86923f3f741c3a9101e@epcas5p2.samsung.com>
Message-ID: <20240213132751.46813-3-shradha.t@samsung.com>

There is no need to hardcode the clock info in the driver as driver can
rely on the devicetree to supply the clocks required for the functioning
of the peripheral. Get rid of the static clock info and obtain the
platform supplied clocks. All the clocks supplied is obtained and enabled
using the devm_clk_bulk_get_all_enable() API.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/pci/controller/dwc/pci-exynos.c | 54 ++-----------------------
 1 file changed, 4 insertions(+), 50 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index ec5611005566..3234eb5be1fb 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -54,43 +54,11 @@
 struct exynos_pcie {
 	struct dw_pcie			pci;
 	void __iomem			*elbi_base;
-	struct clk			*clk;
-	struct clk			*bus_clk;
+	struct clk_bulk_data		*clks;
 	struct phy			*phy;
 	struct regulator_bulk_data	supplies[2];
 };
 
-static int exynos_pcie_init_clk_resources(struct exynos_pcie *ep)
-{
-	struct device *dev = ep->pci.dev;
-	int ret;
-
-	ret = clk_prepare_enable(ep->clk);
-	if (ret) {
-		dev_err(dev, "cannot enable pcie rc clock");
-		return ret;
-	}
-
-	ret = clk_prepare_enable(ep->bus_clk);
-	if (ret) {
-		dev_err(dev, "cannot enable pcie bus clock");
-		goto err_bus_clk;
-	}
-
-	return 0;
-
-err_bus_clk:
-	clk_disable_unprepare(ep->clk);
-
-	return ret;
-}
-
-static void exynos_pcie_deinit_clk_resources(struct exynos_pcie *ep)
-{
-	clk_disable_unprepare(ep->bus_clk);
-	clk_disable_unprepare(ep->clk);
-}
-
 static void exynos_pcie_writel(void __iomem *base, u32 val, u32 reg)
 {
 	writel(val, base + reg);
@@ -332,17 +300,9 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 	if (IS_ERR(ep->elbi_base))
 		return PTR_ERR(ep->elbi_base);
 
-	ep->clk = devm_clk_get(dev, "pcie");
-	if (IS_ERR(ep->clk)) {
-		dev_err(dev, "Failed to get pcie rc clock\n");
-		return PTR_ERR(ep->clk);
-	}
-
-	ep->bus_clk = devm_clk_get(dev, "pcie_bus");
-	if (IS_ERR(ep->bus_clk)) {
-		dev_err(dev, "Failed to get pcie bus clock\n");
-		return PTR_ERR(ep->bus_clk);
-	}
+	ret = devm_clk_bulk_get_all_enable(dev, &ep->clks);
+	if (ret < 0)
+		return ret;
 
 	ep->supplies[0].supply = "vdd18";
 	ep->supplies[1].supply = "vdd10";
@@ -351,10 +311,6 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = exynos_pcie_init_clk_resources(ep);
-	if (ret)
-		return ret;
-
 	ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies);
 	if (ret)
 		return ret;
@@ -369,7 +325,6 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 
 fail_probe:
 	phy_exit(ep->phy);
-	exynos_pcie_deinit_clk_resources(ep);
 	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
 
 	return ret;
@@ -383,7 +338,6 @@ static int __exit exynos_pcie_remove(struct platform_device *pdev)
 	exynos_pcie_assert_core_reset(ep);
 	phy_power_off(ep->phy);
 	phy_exit(ep->phy);
-	exynos_pcie_deinit_clk_resources(ep);
 	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
 
 	return 0;
-- 
2.17.1



From ryan.roberts at arm.com  Tue Feb 13 06:21:07 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 14:21:07 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <CAMj1kXEK6wiHkO9sJ5h6D3L88dR=2UndEqGeQjv=TftZ3PnN9w@mail.gmail.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <aa232591-e0c8-422d-a641-fa555914c5f0@arm.com>
 <64395ae4-3a7d-45dd-8f1d-ea6b232829c5@arm.com>
 <d6ce951f-f83b-4a5a-a814-311f2d8b01e4@arm.com>
 <41499621-482f-455b-9f68-b43ea8052557@redhat.com>
 <1d302d7a-50ab-4ab4-b049-75ed4a71a87d@arm.com>
 <99e2a92c-f2a2-4e1e-8ce2-08caae2cb7e4@redhat.com>
 <dce5f80d-942f-439c-a549-5290666464ca@arm.com>
 <CAMj1kXEVf1m4hVXORc6t9ytAOb75KZLcW-OJ6999VaKbkVdQ3A@mail.gmail.com>
 <64b872bd-4b12-4dbd-b043-1ad11aeaa19a@redhat.com>
 <3de2130b-9f0f-4a11-ac06-7bf814de641c@arm.com>
 <f93e5552-5e46-4f49-918a-21b63156eb32@redhat.com>
 <CAMj1kXEK6wiHkO9sJ5h6D3L88dR=2UndEqGeQjv=TftZ3PnN9w@mail.gmail.com>
Message-ID: <ed91f6c5-1ed2-4fb3-b5a4-0a720721e3f6@arm.com>

On 13/02/2024 14:08, Ard Biesheuvel wrote:
> On Tue, 13 Feb 2024 at 15:05, David Hildenbrand <david at redhat.com> wrote:
>>
>> On 13.02.24 15:02, Ryan Roberts wrote:
>>> On 13/02/2024 13:45, David Hildenbrand wrote:
>>>> On 13.02.24 14:33, Ard Biesheuvel wrote:
>>>>> On Tue, 13 Feb 2024 at 14:21, Ryan Roberts <ryan.roberts at arm.com> wrote:
>>>>>>
>>>>>> On 13/02/2024 13:13, David Hildenbrand wrote:
> ...
>>>>>>> Just a thought, you could have a is_efi_mm() function that abstracts all that.
>>>>>>>
>>>>>>> diff --git a/include/linux/efi.h b/include/linux/efi.h
>>>>>>> index c74f47711f0b..152f5fa66a2a 100644
>>>>>>> --- a/include/linux/efi.h
>>>>>>> +++ b/include/linux/efi.h
>>>>>>> @@ -692,6 +692,15 @@ extern struct efi {
>>>>>>>
>>>>>>>    extern struct mm_struct efi_mm;
>>>>>>>
>>>>>>> +static inline void is_efi_mm(struct mm_struct *mm)
>>>>>>> +{
>>>>>>> +#ifdef CONFIG_EFI
>>>>>>> +       return mm == &efi_mm;
>>>>>>> +#else
>>>>>>> +       return false;
>>>>>>> +#endif
>>>>>>> +}
>>>>>>> +
>>>>>>>    static inline int
>>>>>>>    efi_guidcmp (efi_guid_t left, efi_guid_t right)
>>>>>>>    {
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> That would definitely work, but in that case, I might as well just check for it
>>>>>> in mm_is_user() (and personally I would change the name to mm_is_efi()):
>>>>>>
>>>>>>
>>>>>> static inline bool mm_is_user(struct mm_struct *mm)
>>>>>> {
>>>>>>           return mm != &init_mm && !mm_is_efi(mm);
>>>>>> }
>>>>>>
>>>>>> Any objections?
>>>>>>
>>>>>
>>>>> Any reason not to use IS_ENABLED(CONFIG_EFI) in the above? The extern
>>>>> declaration is visible to the compiler, and any references should
>>>>> disappear before the linker could notice that efi_mm does not exist.
>>>>>
>>>>
>>>> Sure, as long as the linker is happy why not. I'll let Ryan mess with that :)
>>>
>>> I'm not sure if you are suggesting dropping the mm_is_efi() helper and just use
>>> IS_ENABLED(CONFIG_EFI) in mm_is_user() to guard efi_mm, or if you are suggesting
>>> using IS_ENABLED(CONFIG_EFI) in mm_is_efi() instead of the ifdefery?
>>>
>>> The former was what I did initially; It works great, but I didn't like that I
>>> was introducing a new code dependecy between efi and arm64 (nothing else outside
>>> of efi references efi_mm).
>>>
>>> So then concluded that it is safe to not worry about efi_mm (thanks for your
>>> confirmation). But then David wanted a VM_WARN check, which reintroduces the
>>> code dependency. So he suggested the mm_is_efi() helper to hide that... This is
>>> all starting to feel circular...
>>
>> I think Ard meant that inside mm_is_efi(), we could avoid the #ifdef and
>> simply use IS_ENABLED().
>>
> 
> Yes.
> 
> static inline void mm_is_efi(struct mm_struct *mm)
> {
>     return IS_ENABLED(CONFIG_EFI) && mm == &efi_mm;
> }

Ahh, got it. Yes, I'll do it like this. Thanks!



From maz at kernel.org  Tue Feb 13 06:21:48 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 13 Feb 2024 14:21:48 +0000
Subject: [PATCH 2/2] arm64: cpufeatures: Only check for NV1 if NV is present
In-Reply-To: <5b2d8fee-9d0f-48f7-b9ec-b86e95387a61@samsung.com>
References: <20240212144736.1933112-1-maz@kernel.org>
	<CGME20240212144758eucas1p1345ba6f2000c10a4b33f8575f0a8d22b@eucas1p1.samsung.com>
	<20240212144736.1933112-3-maz@kernel.org>
	<5b2d8fee-9d0f-48f7-b9ec-b86e95387a61@samsung.com>
Message-ID: <86bk8k5ts3.wl-maz@kernel.org>

On Tue, 13 Feb 2024 11:14:37 +0000,
Marek Szyprowski <m.szyprowski at samsung.com> wrote:
> 
> Hi
> 
> On 12.02.2024 15:47, Marc Zyngier wrote:
> > We handle ID_AA64MMFR4_EL1.E2H0 being 0 as NV1 being present.
> > However, this is only true if FEAT_NV is implemented.
> >
> > Add the required check to has_nv1(), avoiding spuriously advertising
> > NV1 on HW that doesn't have NV at all.
> >
> > Fixes: da9af5071b25 ("arm64: cpufeature: Detect HCR_EL2.NV1 being RES0")
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> 
> This patch in turn introduces the following warning during boot 
> (observed on today's linux-next):
> 
> CPU: All CPU(s) started at EL2
> CPU features: detected: 32-bit EL0 Support
> CPU features: detected: 32-bit EL1 Support
> CPU features: detected: CRC32 instructions
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/cpufeature.c:3369 
> this_cpu_has_cap+0x18/0x70
> Modules linked in:
> CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc4-next-20240213 #8014
> Hardware name: Khadas VIM3 (DT)
> pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : this_cpu_has_cap+0x18/0x70
> lr : has_nv1+0x24/0xcc
> ...
> Call trace:
>  ?this_cpu_has_cap+0x18/0x70
>  ?update_cpu_capabilities+0x50/0x134
>  ?setup_system_features+0x30/0x120
>  ?smp_cpus_done+0x48/0xb4
>  ?smp_init+0x7c/0x8c
>  ?kernel_init_freeable+0x18c/0x4e4
>  ?kernel_init+0x20/0x1d8
>  ?ret_from_fork+0x10/0x20
> irq event stamp: 2846
> hardirqs last? enabled at (2845): [<ffff80008012cf5c>] 
> console_unlock+0x164/0x190
> hardirqs last disabled at (2846): [<ffff80008123a078>] el1_dbg+0x24/0x8c
> softirqs last? enabled at (2842): [<ffff800080010a60>] 
> __do_softirq+0x4a0/0x4e8
> softirqs last disabled at (2827): [<ffff8000800169b0>] 
> ____do_softirq+0x10/0x1c
> ---[ end trace 0000000000000000 ]---
> alternatives: applying system-wide alternatives

This is nothing short of embarrassing. It looks like I somehow managed
to drop CONFIG_PREEMPT from my test config, making it impossible to
identify these issues. Apologies for that.

The following patch fixes it for me. Could you please give it a go?

Thanks,

	M.

From cd75279d3b6c387c13972b61c486a203d9652e97 Mon Sep 17 00:00:00 2001
From: Marc Zyngier <maz at kernel.org>
Date: Tue, 13 Feb 2024 13:37:57 +0000
Subject: [PATCH] arm64: cpufeatures: Fix FEAT_NV check when checking for
 FEAT_NV1

Using this_cpu_has_cap() has the potential to go wrong when
used system-wide on a preemptible kernel. Instead, use the
__system_matches_cap() helper when checking for FEAT_NV in the
FEAT_NV1 probing helper.

Fixes: 3673d01a2f55 ("arm64: cpufeatures: Only check for NV1 if NV is present")
Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 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 3421b684d340..f309fd542c20 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1812,7 +1812,7 @@ static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
 		{}
 	};
 
-	return (this_cpu_has_cap(ARM64_HAS_NESTED_VIRT) &&
+	return (__system_matches_cap(ARM64_HAS_NESTED_VIRT) &&
 		!(has_cpuid_feature(entry, scope) ||
 		  is_midr_in_range_list(read_cpuid_id(), nv1_ni_list)));
 }
-- 
2.39.2


-- 
Without deviation from the norm, progress is not possible.


From jbrunet at baylibre.com  Tue Feb 13 06:28:28 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Tue, 13 Feb 2024 15:28:28 +0100
Subject: [PATCH v2] nvmem: meson-efuse: fix function pointer type mismatch
Message-ID: <20240213142831.3069049-1-jbrunet@baylibre.com>

clang-16 warns about casting functions to incompatible types, as is done
here to call clk_disable_unprepare:

drivers/nvmem/meson-efuse.c:78:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
   78 |                                        (void(*)(void *))clk_disable_unprepare,

The pattern of getting, enabling and setting a disable callback for a
clock can be replaced with devm_clk_get_enabled(), which also fixes
this warning.

Fixes: 611fbca1c861 ("nvmem: meson-efuse: add peripheral clock")
Reported-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 drivers/nvmem/meson-efuse.c | 25 +++----------------------
 1 file changed, 3 insertions(+), 22 deletions(-)

diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
index b922df99f9bc..33678d0af2c2 100644
--- a/drivers/nvmem/meson-efuse.c
+++ b/drivers/nvmem/meson-efuse.c
@@ -47,7 +47,6 @@ static int meson_efuse_probe(struct platform_device *pdev)
 	struct nvmem_config *econfig;
 	struct clk *clk;
 	unsigned int size;
-	int ret;
 
 	sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
 	if (!sm_np) {
@@ -60,27 +59,9 @@ static int meson_efuse_probe(struct platform_device *pdev)
 	if (!fw)
 		return -EPROBE_DEFER;
 
-	clk = devm_clk_get(dev, NULL);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "failed to get efuse gate");
-		return ret;
-	}
-
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		dev_err(dev, "failed to enable gate");
-		return ret;
-	}
-
-	ret = devm_add_action_or_reset(dev,
-				       (void(*)(void *))clk_disable_unprepare,
-				       clk);
-	if (ret) {
-		dev_err(dev, "failed to add disable callback");
-		return ret;
-	}
+	clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(clk))
+		return dev_err_probe(dev, PTR_ERR(clk), "failed to get efuse gate");
 
 	if (meson_sm_call(fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
 		dev_err(dev, "failed to get max user");
-- 
2.43.0



From jszhang at kernel.org  Tue Feb 13 06:16:08 2024
From: jszhang at kernel.org (Jisheng Zhang)
Date: Tue, 13 Feb 2024 22:16:08 +0800
Subject: [PATCH net v3] net: stmmac: protect updates of 64-bit statistics
 counters
In-Reply-To: <ea1567d9-ce66-45e6-8168-ac40a47d1821@roeck-us.net>
References: <20240203190927.19669-1-petr@tesarici.cz>
 <ea1567d9-ce66-45e6-8168-ac40a47d1821@roeck-us.net>
Message-ID: <Zct5qJcZw0YKx54r@xhacker>

On Sun, Feb 11, 2024 at 08:30:21PM -0800, Guenter Roeck wrote:
> Hi,
> 
> On Sat, Feb 03, 2024 at 08:09:27PM +0100, Petr Tesarik wrote:
> > As explained by a comment in <linux/u64_stats_sync.h>, write side of struct
> > u64_stats_sync must ensure mutual exclusion, or one seqcount update could
> > be lost on 32-bit platforms, thus blocking readers forever. Such lockups
> > have been observed in real world after stmmac_xmit() on one CPU raced with
> > stmmac_napi_poll_tx() on another CPU.
> > 
> > To fix the issue without introducing a new lock, split the statics into
> > three parts:
> > 
> > 1. fields updated only under the tx queue lock,
> > 2. fields updated only during NAPI poll,
> > 3. fields updated only from interrupt context,
> > 
> > Updates to fields in the first two groups are already serialized through
> > other locks. It is sufficient to split the existing struct u64_stats_sync
> > so that each group has its own.
> > 
> > Note that tx_set_ic_bit is updated from both contexts. Split this counter
> > so that each context gets its own, and calculate their sum to get the total
> > value in stmmac_get_ethtool_stats().
> > 
> > For the third group, multiple interrupts may be processed by different CPUs
> > at the same time, but interrupts on the same CPU will not nest. Move fields
> > from this group to a newly created per-cpu struct stmmac_pcpu_stats.
> > 
> > Fixes: 133466c3bbe1 ("net: stmmac: use per-queue 64 bit statistics where necessary")
> > Link: https://lore.kernel.org/netdev/Za173PhviYg-1qIn at torres.zugschlus.de/t/
> > Cc: stable at vger.kernel.org
> > Signed-off-by: Petr Tesarik <petr at tesarici.cz>
> 
> This patch results in a lockdep splat. Backtrace and bisect results attached.
> 
> Guenter
> 
> ---
> [   33.736728] ================================
> [   33.736805] WARNING: inconsistent lock state
> [   33.736953] 6.8.0-rc4 #1 Tainted: G                 N
> [   33.737080] --------------------------------
> [   33.737155] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
> [   33.737309] kworker/0:2/39 [HC1[1]:SC0[2]:HE0:SE0] takes:
> [   33.737459] ef792074 (&syncp->seq#2){?...}-{0:0}, at: sun8i_dwmac_dma_interrupt+0x9c/0x28c
> [   33.738206] {HARDIRQ-ON-W} state was registered at:
> [   33.738318]   lock_acquire+0x11c/0x368
> [   33.738431]   __u64_stats_update_begin+0x104/0x1ac
> [   33.738525]   stmmac_xmit+0x4d0/0xc58

interesting lockdep splat...
stmmac_xmit() operates on txq_stats->q_syncp, while the
sun8i_dwmac_dma_interrupt() operates on pcpu's priv->xstats.pcpu_stats
they are different syncp. so how does lockdep splat happen.

> [   33.738605]   dev_hard_start_xmit+0xc4/0x2a0
> [   33.738689]   sch_direct_xmit+0xf8/0x30c
> [   33.738763]   __dev_queue_xmit+0x400/0xcc4
> [   33.738831]   ip6_finish_output2+0x254/0xafc
> [   33.738903]   mld_sendpack+0x260/0x5b0
> [   33.738969]   mld_ifc_work+0x274/0x588
> [   33.739032]   process_one_work+0x230/0x604
> [   33.739101]   worker_thread+0x1dc/0x494
> [   33.739165]   kthread+0x100/0x120
> [   33.739225]   ret_from_fork+0x14/0x28
> [   33.739302] irq event stamp: 3553
> [   33.739371] hardirqs last  enabled at (3552): [<c03e884c>] __call_rcu_common.constprop.0+0x1a4/0x6b4
> [   33.739515] hardirqs last disabled at (3553): [<c0300bd4>] __irq_svc+0x54/0xb8
> [   33.739638] softirqs last  enabled at (3542): [<c1254a60>] neigh_resolve_output+0x1fc/0x254
> [   33.739795] softirqs last disabled at (3546): [<c1243798>] __dev_queue_xmit+0x48/0xcc4
> [   33.739919]
> [   33.739919] other info that might help us debug this:
> [   33.740021]  Possible unsafe locking scenario:
> [   33.740021]
> [   33.740111]        CPU0
> [   33.740158]        ----
> [   33.740204]   lock(&syncp->seq#2);
> [   33.740314]   <Interrupt>
> [   33.740363]     lock(&syncp->seq#2);
> [   33.740511]
> [   33.740511]  *** DEADLOCK ***
> [   33.740511]
> [   33.740665] 8 locks held by kworker/0:2/39:
> [   33.740761]  #0: c4bfb2a8 ((wq_completion)mld){+.+.}-{0:0}, at: process_one_work+0x168/0x604
> [   33.741025]  #1: f0909f20 ((work_completion)(&(&idev->mc_ifc_work)->work)){+.+.}-{0:0}, at: process_one_work+0x168/0x604
> [   33.741230]  #2: c328baac (&idev->mc_lock){+.+.}-{3:3}, at: mld_ifc_work+0x24/0x588
> [   33.741387]  #3: c2191488 (rcu_read_lock){....}-{1:2}, at: mld_sendpack+0x0/0x5b0
> [   33.741553]  #4: c2191488 (rcu_read_lock){....}-{1:2}, at: ip6_finish_output2+0x174/0xafc
> [   33.741716]  #5: c219149c (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x48/0xcc4
> [   33.741877]  #6: c4d3a974 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: __dev_queue_xmit+0x334/0xcc4
> [   33.742070]  #7: c49e5050 (_xmit_ETHER#2){+...}-{2:2}, at: sch_direct_xmit+0x158/0x30c
> [   33.742250]
> [   33.742250] stack backtrace:
> [   33.742426] CPU: 0 PID: 39 Comm: kworker/0:2 Tainted: G                 N 6.8.0-rc4 #1
> [   33.742578] Hardware name: Allwinner sun8i Family
> [   33.742776] Workqueue: mld mld_ifc_work
> [   33.742998]  unwind_backtrace from show_stack+0x10/0x14
> [   33.743119]  show_stack from dump_stack_lvl+0x68/0x90
> [   33.743232]  dump_stack_lvl from mark_lock.part.0+0xbd8/0x12d8
> [   33.743345]  mark_lock.part.0 from __lock_acquire+0xad4/0x224c
> [   33.743458]  __lock_acquire from lock_acquire+0x11c/0x368
> [   33.743564]  lock_acquire from __u64_stats_update_begin+0x104/0x1ac
> [   33.743683]  __u64_stats_update_begin from sun8i_dwmac_dma_interrupt+0x9c/0x28c
> [   33.743805]  sun8i_dwmac_dma_interrupt from stmmac_napi_check+0x40/0x1c8
> [   33.743917]  stmmac_napi_check from stmmac_interrupt+0xa4/0x154
> [   33.744020]  stmmac_interrupt from __handle_irq_event_percpu+0xcc/0x2ec
> [   33.744134]  __handle_irq_event_percpu from handle_irq_event+0x38/0x80
> [   33.744243]  handle_irq_event from handle_fasteoi_irq+0x9c/0x1c4
> [   33.744346]  handle_fasteoi_irq from generic_handle_domain_irq+0x28/0x38
> [   33.744459]  generic_handle_domain_irq from gic_handle_irq+0x98/0xcc
> [   33.744567]  gic_handle_irq from generic_handle_arch_irq+0x34/0x44
> [   33.744673]  generic_handle_arch_irq from call_with_stack+0x18/0x20
> [   33.744831]  call_with_stack from __irq_svc+0x9c/0xb8
> [   33.745018] Exception stack(0xf0909c00 to 0xf0909c48)
> [   33.745221] 9c00: f0ab0000 c49e506c 0000005a 00000000 c0000006 f0ab0014 0000005a c0f5da68
> [   33.745387] 9c20: c35bd810 c4b50000 c4b50000 c365d300 00000000 f0909c50 c0f70a70 c0f70a74
> [   33.745574] 9c40: 60000013 ffffffff
> [   33.745668]  __irq_svc from sun8i_dwmac_enable_dma_transmission+0x20/0x24
> [   33.745809]  sun8i_dwmac_enable_dma_transmission from stmmac_xmit+0x790/0xc58
> [   33.745975]  stmmac_xmit from dev_hard_start_xmit+0xc4/0x2a0
> [   33.746100]  dev_hard_start_xmit from sch_direct_xmit+0xf8/0x30c
> [   33.746220]  sch_direct_xmit from __dev_queue_xmit+0x400/0xcc4
> [   33.746350]  __dev_queue_xmit from ip6_finish_output2+0x254/0xafc
> [   33.746462]  ip6_finish_output2 from mld_sendpack+0x260/0x5b0
> [   33.746568]  mld_sendpack from mld_ifc_work+0x274/0x588
> [   33.746670]  mld_ifc_work from process_one_work+0x230/0x604
> [   33.746793]  process_one_work from worker_thread+0x1dc/0x494
> [   33.746906]  worker_thread from kthread+0x100/0x120
> [   33.746994]  kthread from ret_from_fork+0x14/0x28
> [   33.747076] Exception stack(0xf0909fb0 to 0xf0909ff8)
> [   33.747165] 9fa0:                                     00000000 00000000 00000000 00000000
> [   33.747303] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [   33.747433] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> 
> ---
> # bad: [841c35169323cd833294798e58b9bf63fa4fa1de] Linux 6.8-rc4
> # good: [54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478] Linux 6.8-rc3
> git bisect start 'HEAD' 'v6.8-rc3'
> # bad: [c76b766ec50d3d43e2dacea53a733b285f4b730d] Merge tag 'drm-fixes-2024-02-09' of git://anongit.freedesktop.org/drm/drm
> git bisect bad c76b766ec50d3d43e2dacea53a733b285f4b730d
> # bad: [63e4b9d693e0f8c28359c7ea81e1ee510864c37b] Merge tag 'nf-24-02-08' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
> git bisect bad 63e4b9d693e0f8c28359c7ea81e1ee510864c37b
> # bad: [75428f537d7cae33c7e4dd726144074f78622c09] net: intel: fix old compiler regressions
> git bisect bad 75428f537d7cae33c7e4dd726144074f78622c09
> # good: [1a1c13303ff6d64e6f718dc8aa614e580ca8d9b4] nfp: flower: prevent re-adding mac index for bonded port
> git bisect good 1a1c13303ff6d64e6f718dc8aa614e580ca8d9b4
> # good: [3871aa01e1a779d866fa9dfdd5a836f342f4eb87] tipc: Check the bearer type before calling tipc_udp_nl_bearer_add()
> git bisect good 3871aa01e1a779d866fa9dfdd5a836f342f4eb87
> # good: [58086721b7781c3e35b19c9b78c8f5a791070ba3] devlink: avoid potential loop in devlink_rel_nested_in_notify_work()
> git bisect good 58086721b7781c3e35b19c9b78c8f5a791070ba3
> # bad: [38cc3c6dcc09dc3a1800b5ec22aef643ca11eab8] net: stmmac: protect updates of 64-bit statistics counters
> git bisect bad 38cc3c6dcc09dc3a1800b5ec22aef643ca11eab8
> # good: [cb88cb53badb8aeb3955ad6ce80b07b598e310b8] ppp_async: limit MRU to 64K
> git bisect good cb88cb53badb8aeb3955ad6ce80b07b598e310b8
> # first bad commit: [38cc3c6dcc09dc3a1800b5ec22aef643ca11eab8] net: stmmac: protect updates of 64-bit statistics counters


From krzysztof.kozlowski at linaro.org  Tue Feb 13 06:32:17 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 13 Feb 2024 15:32:17 +0100
Subject: [PATCH] arm64: dts: amlogic: replace underscores in node names
Message-ID: <20240213143217.336341-1-krzysztof.kozlowski@linaro.org>

Underscores should not be used in node names (dtc with W=2 warns about
them), so replace them with hyphens.

Cc: Marc Gonzalez <mgonzalez at freebox.fr>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../arm64/boot/dts/amlogic/meson-a1-ad402.dts |  2 +-
 .../meson-axg-jethome-jethub-j1xx.dtsi        | 14 ++++++-------
 .../arm64/boot/dts/amlogic/meson-axg-s400.dts | 16 +++++++--------
 .../dts/amlogic/meson-g12a-radxa-zero.dts     | 12 +++++------
 .../boot/dts/amlogic/meson-g12a-sei510.dts    | 14 ++++++-------
 .../boot/dts/amlogic/meson-g12a-u200.dts      | 16 +++++++--------
 .../boot/dts/amlogic/meson-g12a-x96-max.dts   | 14 ++++++-------
 .../dts/amlogic/meson-g12b-odroid-n2.dtsi     |  2 +-
 .../boot/dts/amlogic/meson-g12b-odroid.dtsi   | 20 +++++++++----------
 .../boot/dts/amlogic/meson-g12b-w400.dtsi     | 10 +++++-----
 .../dts/amlogic/meson-gx-libretech-pc.dtsi    | 12 +++++------
 .../boot/dts/amlogic/meson-gx-p23x-q20x.dtsi  |  8 ++++----
 .../dts/amlogic/meson-gxbb-nexbox-a95x.dts    |  6 +++---
 .../boot/dts/amlogic/meson-gxbb-odroidc2.dts  |  8 ++++----
 .../boot/dts/amlogic/meson-gxbb-p200.dts      |  4 ++--
 .../boot/dts/amlogic/meson-gxbb-p20x.dtsi     |  6 +++---
 .../boot/dts/amlogic/meson-gxbb-vega-s95.dtsi |  8 ++++----
 .../boot/dts/amlogic/meson-gxbb-wetek.dtsi    |  8 ++++----
 .../amlogic/meson-gxl-s805x-libretech-ac.dts  |  8 ++++----
 .../boot/dts/amlogic/meson-gxl-s805x-p241.dts |  8 ++++----
 .../meson-gxl-s905w-jethome-jethub-j80.dts    |  8 ++++----
 .../meson-gxl-s905x-hwacom-amazetv.dts        |  6 +++---
 .../meson-gxl-s905x-libretech-cc-v2.dts       | 12 +++++------
 .../amlogic/meson-gxl-s905x-libretech-cc.dts  |  6 +++---
 .../amlogic/meson-gxl-s905x-nexbox-a95x.dts   |  6 +++---
 .../dts/amlogic/meson-gxl-s905x-p212.dtsi     |  8 ++++----
 .../dts/amlogic/meson-gxm-khadas-vim2.dts     |  8 ++++----
 .../amlogic/meson-gxm-s912-libretech-pc.dts   |  2 +-
 .../boot/dts/amlogic/meson-khadas-vim3.dtsi   | 16 +++++++--------
 .../amlogic/meson-libretech-cottonwood.dtsi   |  6 +++---
 .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 10 +++++-----
 .../boot/dts/amlogic/meson-sm1-bananapi.dtsi  | 14 ++++++-------
 .../boot/dts/amlogic/meson-sm1-odroid-hc4.dts |  4 ++--
 .../boot/dts/amlogic/meson-sm1-odroid.dtsi    | 20 +++++++++----------
 .../boot/dts/amlogic/meson-sm1-sei610.dts     | 12 +++++------
 35 files changed, 167 insertions(+), 167 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts b/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
index 1c20516fa653..4bc30af05848 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
@@ -106,7 +106,7 @@ &spifc {
 	pinctrl-0 = <&spifc_pins>;
 	pinctrl-names = "default";
 
-	spi_nand at 0 {
+	flash at 0 {
 		compatible = "spi-nand";
 		status = "okay";
 		reg = <0>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
index db605f3a22b4..a53e1fe9ac1e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
@@ -35,7 +35,7 @@ emmc_pwrseq: emmc-pwrseq {
 		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -44,7 +44,7 @@ vcc_3v3: regulator-vcc_3v3 {
 		regulator-always-on;
 	};
 
-	vcc_5v: regulator-vcc_5v {
+	vcc_5v: regulator-vcc-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC5V";
 		regulator-min-microvolt = <5000000>;
@@ -52,7 +52,7 @@ vcc_5v: regulator-vcc_5v {
 		regulator-always-on;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -61,7 +61,7 @@ vddao_3v3: regulator-vddao_3v3 {
 		regulator-always-on;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
@@ -70,7 +70,7 @@ vddio_ao18: regulator-vddio_ao18 {
 		regulator-always-on;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <3300000>;
@@ -79,7 +79,7 @@ vddio_boot: regulator-vddio_boot {
 		regulator-always-on;
 	};
 
-	vccq_1v8: regulator-vccq_1v8 {
+	vccq_1v8: regulator-vccq-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCCQ_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -88,7 +88,7 @@ vccq_1v8: regulator-vccq_1v8 {
 		regulator-always-on;
 	};
 
-	usb_pwr: regulator-usb_pwr {
+	usb_pwr: regulator-usb-pwr {
 		compatible = "regulator-fixed";
 		regulator-name = "USB_PWR";
 		regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
index c8905663bc75..7ed526f45175 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
@@ -12,7 +12,7 @@ / {
 	compatible = "amlogic,s400", "amlogic,a113d", "amlogic,meson-axg";
 	model = "Amlogic Meson AXG S400 Development Board";
 
-	adc_keys {
+	keys {
 		compatible = "adc-keys";
 		io-channels = <&saradc 0>;
 		io-channel-names = "buttons";
@@ -111,7 +111,7 @@ memory at 0 {
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
 
-	main_12v: regulator-main_12v {
+	main_12v: regulator-main-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "12V";
 		regulator-min-microvolt = <12000000>;
@@ -119,7 +119,7 @@ main_12v: regulator-main_12v {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -128,7 +128,7 @@ vcc_3v3: regulator-vcc_3v3 {
 		regulator-always-on;
 	};
 
-	vcc_5v: regulator-vcc_5v {
+	vcc_5v: regulator-vcc-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC5V";
 		regulator-min-microvolt = <5000000>;
@@ -139,7 +139,7 @@ vcc_5v: regulator-vcc_5v {
 		enable-active-high;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -148,7 +148,7 @@ vddao_3v3: regulator-vddao_3v3 {
 		regulator-always-on;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
@@ -157,7 +157,7 @@ vddio_ao18: regulator-vddio_ao18 {
 		regulator-always-on;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
@@ -166,7 +166,7 @@ vddio_boot: regulator-vddio_boot {
 		regulator-always-on;
 	};
 
-	usb_pwr: regulator-usb_pwr {
+	usb_pwr: regulator-usb-pwr {
 		compatible = "regulator-fixed";
 		regulator-name = "USB_PWR";
 		regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
index fcd7e1d8e16f..15b9bc280706 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
@@ -60,7 +60,7 @@ sdio_pwrseq: sdio-pwrseq {
 		clock-names = "ext_clock";
 	};
 
-	ao_5v: regulator-ao_5v {
+	ao_5v: regulator-ao-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "AO_5V";
 		regulator-min-microvolt = <5000000>;
@@ -68,7 +68,7 @@ ao_5v: regulator-ao_5v {
 		regulator-always-on;
 	};
 
-	vcc_1v8: regulator-vcc_1v8 {
+	vcc_1v8: regulator-vcc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -77,7 +77,7 @@ vcc_1v8: regulator-vcc_1v8 {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -86,7 +86,7 @@ vcc_3v3: regulator-vcc_3v3 {
 		regulator-always-on;
 	};
 
-	hdmi_pw: regulator-hdmi_pw {
+	hdmi_pw: regulator-hdmi-pw {
 		compatible = "regulator-fixed";
 		regulator-name = "HDMI_PW";
 		regulator-min-microvolt = <5000000>;
@@ -95,7 +95,7 @@ hdmi_pw: regulator-hdmi_pw {
 		regulator-always-on;
 	};
 
-	vddao_1v8: regulator-vddao_1v8 {
+	vddao_1v8: regulator-vddao-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -104,7 +104,7 @@ vddao_1v8: regulator-vddao_1v8 {
 		regulator-always-on;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
index 4c4550dd4711..61cb8135a392 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
@@ -15,7 +15,7 @@ / {
 	compatible = "seirobotics,sei510", "amlogic,g12a";
 	model = "SEI Robotics SEI510";
 
-	adc_keys {
+	keys {
 		compatible = "adc-keys";
 		io-channels = <&saradc 0>;
 		io-channel-names = "buttons";
@@ -83,7 +83,7 @@ memory at 0 {
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
 
-	ao_5v: regulator-ao_5v {
+	ao_5v: regulator-ao-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "AO_5V";
 		regulator-min-microvolt = <5000000>;
@@ -92,7 +92,7 @@ ao_5v: regulator-ao_5v {
 		regulator-always-on;
 	};
 
-	dc_in: regulator-dc_in {
+	dc_in: regulator-dc-in {
 		compatible = "regulator-fixed";
 		regulator-name = "DC_IN";
 		regulator-min-microvolt = <5000000>;
@@ -100,7 +100,7 @@ dc_in: regulator-dc_in {
 		regulator-always-on;
 	};
 
-	emmc_1v8: regulator-emmc_1v8 {
+	emmc_1v8: regulator-emmc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "EMMC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -109,7 +109,7 @@ emmc_1v8: regulator-emmc_1v8 {
 		regulator-always-on;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -118,7 +118,7 @@ vddao_3v3: regulator-vddao_3v3 {
 		regulator-always-on;
 	};
 
-	vddao_3v3_t: regultor-vddao_3v3_t {
+	vddao_3v3_t: regulator-vddao-3v3-t {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3_T";
 		regulator-min-microvolt = <3300000>;
@@ -147,7 +147,7 @@ vddcpu: regulator-vddcpu {
 		regulator-always-on;
 	};
 
-	vddio_ao1v8: regulator-vddio_ao1v8 {
+	vddio_ao1v8: regulator-vddio-ao1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO1V8";
 		regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
index 8355ddd7e9ae..3da7922d83f1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
@@ -75,7 +75,7 @@ memory at 0 {
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
 
-	flash_1v8: regulator-flash_1v8 {
+	flash_1v8: regulator-flash-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "FLASH_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -84,7 +84,7 @@ flash_1v8: regulator-flash_1v8 {
 		regulator-always-on;
 	};
 
-	main_12v: regulator-main_12v {
+	main_12v: regulator-main-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "12V";
 		regulator-min-microvolt = <12000000>;
@@ -92,7 +92,7 @@ main_12v: regulator-main_12v {
 		regulator-always-on;
 	};
 
-	usb_pwr_en: regulator-usb_pwr_en {
+	usb_pwr_en: regulator-usb-pwr-en {
 		compatible = "regulator-fixed";
 		regulator-name = "USB_PWR_EN";
 		regulator-min-microvolt = <5000000>;
@@ -103,7 +103,7 @@ usb_pwr_en: regulator-usb_pwr_en {
 		enable-active-high;
 	};
 
-	vcc_1v8: regulator-vcc_1v8 {
+	vcc_1v8: regulator-vcc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -112,7 +112,7 @@ vcc_1v8: regulator-vcc_1v8 {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -122,7 +122,7 @@ vcc_3v3: regulator-vcc_3v3 {
 		/* FIXME: actually controlled by VDDCPU_B_EN */
 	};
 
-	vcc_5v: regulator-vcc_5v {
+	vcc_5v: regulator-vcc-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_5V";
 		regulator-min-microvolt = <5000000>;
@@ -133,7 +133,7 @@ vcc_5v: regulator-vcc_5v {
 		enable-active-high;
 	};
 
-	vddao_1v8: regulator-vddao_1v8 {
+	vddao_1v8: regulator-vddao-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -142,7 +142,7 @@ vddao_1v8: regulator-vddao_1v8 {
 		regulator-always-on;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
index 9b55982b6a6b..05c7a1e3f1b7 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
@@ -66,7 +66,7 @@ sdio_pwrseq: sdio-pwrseq {
 		clock-names = "ext_clock";
 	};
 
-	flash_1v8: regulator-flash_1v8 {
+	flash_1v8: regulator-flash-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "FLASH_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -75,7 +75,7 @@ flash_1v8: regulator-flash_1v8 {
 		regulator-always-on;
 	};
 
-	dc_in: regulator-dc_in {
+	dc_in: regulator-dc-in {
 		compatible = "regulator-fixed";
 		regulator-name = "DC_IN";
 		regulator-min-microvolt = <5000000>;
@@ -83,7 +83,7 @@ dc_in: regulator-dc_in {
 		regulator-always-on;
 	};
 
-	vcc_1v8: regulator-vcc_1v8 {
+	vcc_1v8: regulator-vcc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -92,7 +92,7 @@ vcc_1v8: regulator-vcc_1v8 {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -102,7 +102,7 @@ vcc_3v3: regulator-vcc_3v3 {
 		/* FIXME: actually controlled by VDDCPU_B_EN */
 	};
 
-	vcc_5v: regulator-vcc_5v {
+	vcc_5v: regulator-vcc-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_5V";
 		regulator-min-microvolt = <5000000>;
@@ -112,7 +112,7 @@ vcc_5v: regulator-vcc_5v {
 		gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
 	};
 
-	vddao_1v8: regulator-vddao_1v8 {
+	vddao_1v8: regulator-vddao-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -121,7 +121,7 @@ vddao_1v8: regulator-vddao_1v8 {
 		regulator-always-on;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
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 91c9769fda20..d80dd9a3da31 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
@@ -19,7 +19,7 @@ dio2133: audio-amplifier-0 {
 		status = "okay";
 	};
 
-	hub_5v: regulator-hub_5v {
+	hub_5v: regulator-hub-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "HUB_5V";
 		regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi
index 9e12a34b2840..09d959aefb18 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi
@@ -48,7 +48,7 @@ led-blue {
 		};
 	};
 
-	tflash_vdd: regulator-tflash_vdd {
+	tflash_vdd: regulator-tflash-vdd {
 		compatible = "regulator-fixed";
 
 		regulator-name = "TFLASH_VDD";
@@ -60,7 +60,7 @@ tflash_vdd: regulator-tflash_vdd {
 		regulator-always-on;
 	};
 
-	tf_io: gpio-regulator-tf_io {
+	tf_io: gpio-regulator-tf-io {
 		compatible = "regulator-gpio";
 
 		regulator-name = "TF_IO";
@@ -74,7 +74,7 @@ tf_io: gpio-regulator-tf_io {
 			 <1800000 1>;
 	};
 
-	flash_1v8: regulator-flash_1v8 {
+	flash_1v8: regulator-flash-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "FLASH_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -83,7 +83,7 @@ flash_1v8: regulator-flash_1v8 {
 		regulator-always-on;
 	};
 
-	main_12v: regulator-main_12v {
+	main_12v: regulator-main-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "12V";
 		regulator-min-microvolt = <12000000>;
@@ -91,7 +91,7 @@ main_12v: regulator-main_12v {
 		regulator-always-on;
 	};
 
-	usb_pwr_en: regulator-usb_pwr_en {
+	usb_pwr_en: regulator-usb-pwr-en {
 		compatible = "regulator-fixed";
 		regulator-name = "USB_PWR_EN";
 		regulator-min-microvolt = <5000000>;
@@ -103,7 +103,7 @@ usb_pwr_en: regulator-usb_pwr_en {
 		enable-active-high;
 	};
 
-	vcc_5v: regulator-vcc_5v {
+	vcc_5v: regulator-vcc-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "5V";
 		regulator-min-microvolt = <5000000>;
@@ -114,7 +114,7 @@ vcc_5v: regulator-vcc_5v {
 		enable-active-high;
 	};
 
-	vcc_1v8: regulator-vcc_1v8 {
+	vcc_1v8: regulator-vcc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -123,7 +123,7 @@ vcc_1v8: regulator-vcc_1v8 {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -171,7 +171,7 @@ vddcpu_b: regulator-vddcpu-b {
 		regulator-always-on;
 	};
 
-	vddao_1v8: regulator-vddao_1v8 {
+	vddao_1v8: regulator-vddao-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -180,7 +180,7 @@ vddao_1v8: regulator-vddao_1v8 {
 		regulator-always-on;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi
index ac8b7178257e..4cb6930ffb19 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi
@@ -39,7 +39,7 @@ sdio_pwrseq: sdio-pwrseq {
 		clock-names = "ext_clock";
 	};
 
-	flash_1v8: regulator-flash_1v8 {
+	flash_1v8: regulator-flash-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "FLASH_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -48,7 +48,7 @@ flash_1v8: regulator-flash_1v8 {
 		regulator-always-on;
 	};
 
-	main_12v: regulator-main_12v {
+	main_12v: regulator-main-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "12V";
 		regulator-min-microvolt = <12000000>;
@@ -56,7 +56,7 @@ main_12v: regulator-main_12v {
 		regulator-always-on;
 	};
 
-	vcc_5v: regulator-vcc_5v {
+	vcc_5v: regulator-vcc-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_5V";
 		regulator-min-microvolt = <5000000>;
@@ -67,7 +67,7 @@ vcc_5v: regulator-vcc_5v {
 		enable-active-high;
 	};
 
-	vcc_1v8: regulator-vcc_1v8 {
+	vcc_1v8: regulator-vcc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -76,7 +76,7 @@ vcc_1v8: regulator-vcc_1v8 {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
index 5e7b9273b062..efd662a452e8 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
@@ -84,7 +84,7 @@ memory at 0 {
 		reg = <0x0 0x0 0x0 0x80000000>;
 	};
 
-	ao_5v: regulator-ao_5v {
+	ao_5v: regulator-ao-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "AO_5V";
 		regulator-min-microvolt = <5000000>;
@@ -93,7 +93,7 @@ ao_5v: regulator-ao_5v {
 		regulator-always-on;
 	};
 
-	dc_in: regulator-dc_in {
+	dc_in: regulator-dc-in {
 		compatible = "regulator-fixed";
 		regulator-name = "DC_IN";
 		regulator-min-microvolt = <5000000>;
@@ -120,7 +120,7 @@ led-blue {
 		};
 	};
 
-	vcc_card: regulator-vcc_card {
+	vcc_card: regulator-vcc-card {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_CARD";
 		regulator-min-microvolt = <3300000>;
@@ -141,7 +141,7 @@ vcc5v: regulator-vcc5v {
 		gpio = <&gpio GPIOH_3 GPIO_OPEN_DRAIN>;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
@@ -150,7 +150,7 @@ vddio_ao18: regulator-vddio_ao18 {
 		regulator-always-on;
 	};
 
-	vddio_ao3v3: regulator-vddio_ao3v3 {
+	vddio_ao3v3: regulator-vddio-ao3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO3V3";
 		regulator-min-microvolt = <3300000>;
@@ -159,7 +159,7 @@ vddio_ao3v3: regulator-vddio_ao3v3 {
 		regulator-always-on;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
index e59c3c92b1e7..08d6b69ba469 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
@@ -50,28 +50,28 @@ hdmi_5v: regulator-hdmi-5v {
 		regulator-always-on;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
index 4aab1ab705b4..cca129ce2c58 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
@@ -78,21 +78,21 @@ vddio_card: gpio-regulator {
 			 <3300000 1>;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index e6d2de7c45a9..c431986e6a33 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -67,7 +67,7 @@ p5v0: regulator-p5v0 {
 		regulator-always-on;
 	};
 
-	hdmi_p5v0: regulator-hdmi_p5v0 {
+	hdmi_p5v0: regulator-hdmi-p5v0 {
 		compatible = "regulator-fixed";
 		regulator-name = "HDMI_P5V0";
 		regulator-min-microvolt = <5000000>;
@@ -76,7 +76,7 @@ hdmi_p5v0: regulator-hdmi_p5v0 {
 		vin-supply = <&p5v0>;
 	};
 
-	tflash_vdd: regulator-tflash_vdd {
+	tflash_vdd: regulator-tflash-vdd {
 		compatible = "regulator-fixed";
 
 		regulator-name = "TFLASH_VDD";
@@ -92,7 +92,7 @@ tflash_vdd: regulator-tflash_vdd {
 		vin-supply = <&vddio_ao3v3>;
 	};
 
-	tf_io: gpio-regulator-tf_io {
+	tf_io: gpio-regulator-tf-io {
 		compatible = "regulator-gpio";
 
 		regulator-name = "TF_IO";
@@ -148,7 +148,7 @@ vddio_ao3v3: regulator-vddio-ao3v3 {
 		vin-supply = <&p5v0>;
 	};
 
-	ddr3_1v5: regulator-ddr3_1v5 {
+	ddr3_1v5: regulator-ddr3-1v5 {
 		compatible = "regulator-fixed";
 		regulator-name = "DDR3_1V5";
 		regulator-min-microvolt = <1500000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
index 591455c50e88..7f94716876d3 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
@@ -21,14 +21,14 @@ spdif_dit: audio-codec-0 {
 		sound-name-prefix = "DIT";
 	};
 
-	avdd18_usb_adc: regulator-avdd18_usb_adc {
+	avdd18_usb_adc: regulator-avdd18-usb-adc {
 		compatible = "regulator-fixed";
 		regulator-name = "AVDD18_USB_ADC";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	adc_keys {
+	keys {
 		compatible = "adc-keys";
 		io-channels = <&saradc 0>;
 		io-channel-names = "buttons";
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index e803a466fe4e..52d57773a77f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -53,21 +53,21 @@ vddio_card: gpio-regulator {
 		regulator-settling-time-down-us = <150000>;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
index 74df32534231..255e93a0b36d 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
@@ -47,28 +47,28 @@ usb_pwr: regulator-usb-pwrs {
 		enable-active-high;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
index 94dafb955301..deb295227189 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
@@ -49,21 +49,21 @@ usb_pwr: regulator-usb-pwrs {
 		enable-active-high;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
@@ -71,7 +71,7 @@ vddio_ao18: regulator-vddio_ao18 {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
index a29b49f051ae..90ef9c17d80b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
@@ -42,7 +42,7 @@ cvbs_connector_in: endpoint {
 		};
 	};
 
-	dc_5v: regulator-dc_5v {
+	dc_5v: regulator-dc-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "DC_5V";
 		regulator-min-microvolt = <5000000>;
@@ -89,7 +89,7 @@ vcck: regulator-vcck {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -98,7 +98,7 @@ vcc_3v3: regulator-vcc_3v3 {
 		regulator-always-on;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
@@ -107,7 +107,7 @@ vddio_ao18: regulator-vddio_ao18 {
 		regulator-always-on;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
index c0d6eb55100a..08a4718219b1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
@@ -64,28 +64,28 @@ memory at 0 {
 		reg = <0x0 0x0 0x0 0x20000000>;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts
index a18d6d241a5a..2b94b6e5285e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts
@@ -37,28 +37,28 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
index c8d74e61dec1..89fe5110f7a2 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
@@ -42,21 +42,21 @@ vddio_card: gpio-regulator {
 			 <3300000 1>;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts
index 2825db91e462..63b20860067c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts
@@ -67,7 +67,7 @@ memory at 0 {
 		reg = <0x0 0x0 0x0 0x80000000>;
 	};
 
-	ao_5v: regulator-ao_5v {
+	ao_5v: regulator-ao-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "AO_5V";
 		regulator-min-microvolt = <5000000>;
@@ -76,7 +76,7 @@ ao_5v: regulator-ao_5v {
 		regulator-always-on;
 	};
 
-	dc_in: regulator-dc_in {
+	dc_in: regulator-dc-in {
 		compatible = "regulator-fixed";
 		regulator-name = "DC_IN";
 		regulator-min-microvolt = <5000000>;
@@ -93,7 +93,7 @@ vcck: regulator-vcck {
 		regulator-always-on;
 	};
 
-	vcc_card: regulator-vcc_card {
+	vcc_card: regulator-vcc-card {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_CARD";
 		regulator-min-microvolt = <3300000>;
@@ -114,7 +114,7 @@ vcc5v: regulator-vcc5v {
 		gpio = <&gpio GPIOH_3 GPIO_OPEN_DRAIN>;
 	};
 
-	vddio_ao3v3: regulator-vddio_ao3v3 {
+	vddio_ao3v3: regulator-vddio-ao3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO3V3";
 		regulator-min-microvolt = <3300000>;
@@ -139,7 +139,7 @@ vddio_card: regulator-vddio-card {
 		regulator-settling-time-down-us = <50000>;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
@@ -148,7 +148,7 @@ vddio_ao18: regulator-vddio_ao18 {
 		regulator-always-on;
 	};
 
-	vcc_1v8: regulator-vcc_1v8 {
+	vcc_1v8: regulator-vcc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC 1V8";
 		regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
index 27093e6ac9e2..8b26c9661be1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
@@ -93,7 +93,7 @@ hdmi_5v: regulator-hdmi-5v {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -117,7 +117,7 @@ vcc_card: regulator-vcc-card {
 		regulator-settling-time-down-us = <50000>;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
@@ -125,7 +125,7 @@ vddio_ao18: regulator-vddio_ao18 {
 	};
 
 	/* This is provided by LDOs on the eMMC daugther card */
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
index f1acca5c4434..c79f9f2099bf 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
@@ -42,21 +42,21 @@ vddio_card: gpio-regulator {
 			 <3300000 1>;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
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 a150cc0e18ff..7e7dc87ede2d 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
@@ -39,28 +39,28 @@ hdmi_5v: regulator-hdmi-5v {
 		regulator-always-on;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
index 860f307494c5..07e7c3bedea0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
@@ -112,28 +112,28 @@ hdmi_5v: regulator-hdmi-5v {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddio_boot: regulator-vddio_boot {
+	vddio_boot: regulator-vddio-boot {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_BOOT";
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <1800000>;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts
index 4eda9f634c42..a66f19851ac9 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts
@@ -14,7 +14,7 @@ / {
 		     "amlogic,meson-gxm";
 	model = "Libre Computer AML-S912-PC";
 
-	typec2_vbus: regulator-typec2_vbus {
+	typec2_vbus: regulator-typec2-vbus {
 		compatible = "regulator-fixed";
 		regulator-name = "TYPEC2_VBUS";
 		regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
index 514a6dd4b124..e78cc9b577a0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
@@ -80,7 +80,7 @@ sdio_pwrseq: sdio-pwrseq {
 		clock-names = "ext_clock";
 	};
 
-	dc_in: regulator-dc_in {
+	dc_in: regulator-dc-in {
 		compatible = "regulator-fixed";
 		regulator-name = "DC_IN";
 		regulator-min-microvolt = <5000000>;
@@ -88,7 +88,7 @@ dc_in: regulator-dc_in {
 		regulator-always-on;
 	};
 
-	vcc_5v: regulator-vcc_5v {
+	vcc_5v: regulator-vcc-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_5V";
 		regulator-min-microvolt = <5000000>;
@@ -99,7 +99,7 @@ vcc_5v: regulator-vcc_5v {
 		enable-active-high;
 	};
 
-	vcc_1v8: regulator-vcc_1v8 {
+	vcc_1v8: regulator-vcc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -108,7 +108,7 @@ vcc_1v8: regulator-vcc_1v8 {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -118,7 +118,7 @@ vcc_3v3: regulator-vcc_3v3 {
 		/* FIXME: actually controlled by VDDCPU_B_EN */
 	};
 
-	vddao_1v8: regulator-vddao_1v8 {
+	vddao_1v8: regulator-vddao-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO1V8";
 		regulator-min-microvolt = <1800000>;
@@ -127,7 +127,7 @@ vddao_1v8: regulator-vddao_1v8 {
 		regulator-always-on;
 	};
 
-	emmc_1v8: regulator-emmc_1v8 {
+	emmc_1v8: regulator-emmc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "EMMC_AO1V8";
 		regulator-min-microvolt = <1800000>;
@@ -136,7 +136,7 @@ emmc_1v8: regulator-emmc_1v8 {
 		regulator-always-on;
 	};
 
-	vsys_3v3: regulator-vsys_3v3 {
+	vsys_3v3: regulator-vsys-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VSYS_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -145,7 +145,7 @@ vsys_3v3: regulator-vsys_3v3 {
 		regulator-always-on;
 	};
 
-	usb_pwr: regulator-usb_pwr {
+	usb_pwr: regulator-usb-pwr {
 		compatible = "regulator-fixed";
 		regulator-name = "USB_PWR";
 		regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi b/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
index 35e8f5bae990..082b72703cdf 100644
--- a/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
@@ -150,7 +150,7 @@ vcc_5v: regulator-vcc-5v {
 		gpio-open-drain;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -171,7 +171,7 @@ vddcpu_b: regulator-vddcpu-b {
 		pwm-dutycycle-range = <100 0>;
 	};
 
-	vddio_ao18: regulator-vddio_ao18 {
+	vddio_ao18: regulator-vddio-ao18 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO18";
 		regulator-min-microvolt = <1800000>;
@@ -180,7 +180,7 @@ vddio_ao18: regulator-vddio_ao18 {
 		vin-supply = <&vddao_3v3>;
 	};
 
-	vddio_c: regulator-vddio_c {
+	vddio_c: regulator-vddio-c {
 		compatible = "regulator-gpio";
 		regulator-name = "VDDIO_C";
 		regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
index 46a34731f7e2..d1fa8b8bf795 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
@@ -54,7 +54,7 @@ memory at 0 {
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
 
-	ao_5v: regulator-ao_5v {
+	ao_5v: regulator-ao-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "AO_5V";
 		regulator-min-microvolt = <5000000>;
@@ -63,7 +63,7 @@ ao_5v: regulator-ao_5v {
 		regulator-always-on;
 	};
 
-	dc_in: regulator-dc_in {
+	dc_in: regulator-dc-in {
 		compatible = "regulator-fixed";
 		regulator-name = "DC_IN";
 		regulator-min-microvolt = <5000000>;
@@ -71,7 +71,7 @@ dc_in: regulator-dc_in {
 		regulator-always-on;
 	};
 
-	emmc_1v8: regulator-emmc_1v8 {
+	emmc_1v8: regulator-emmc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "EMMC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -80,7 +80,7 @@ emmc_1v8: regulator-emmc_1v8 {
 		regulator-always-on;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -105,7 +105,7 @@ vddcpu: regulator-vddcpu {
 		regulator-always-on;
 	};
 
-	vddio_ao1v8: regulator-vddio_ao1v8 {
+	vddio_ao1v8: regulator-vddio-ao1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO1V8";
 		regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi
index 62404743e62d..81dce862902a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi
@@ -82,7 +82,7 @@ memory at 0 {
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
 
-	emmc_1v8: regulator-emmc_1v8 {
+	emmc_1v8: regulator-emmc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "EMMC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -91,7 +91,7 @@ emmc_1v8: regulator-emmc_1v8 {
 		regulator-always-on;
 	};
 
-	dc_in: regulator-dc_in {
+	dc_in: regulator-dc-in {
 		compatible = "regulator-fixed";
 		regulator-name = "DC_IN";
 		regulator-min-microvolt = <5000000>;
@@ -99,7 +99,7 @@ dc_in: regulator-dc_in {
 		regulator-always-on;
 	};
 
-	vddio_c: regulator-vddio_c {
+	vddio_c: regulator-vddio-c {
 		compatible = "regulator-gpio";
 		regulator-name = "VDDIO_C";
 		regulator-min-microvolt = <1800000>;
@@ -116,7 +116,7 @@ vddio_c: regulator-vddio_c {
 			 <3300000 1>;
 	};
 
-	tflash_vdd: regulator-tflash_vdd {
+	tflash_vdd: regulator-tflash-vdd {
 		compatible = "regulator-fixed";
 		regulator-name = "TFLASH_VDD";
 		regulator-min-microvolt = <3300000>;
@@ -127,7 +127,7 @@ tflash_vdd: regulator-tflash_vdd {
 		regulator-always-on;
 	};
 
-	vddao_1v8: regulator-vddao_1v8 {
+	vddao_1v8: regulator-vddao-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -136,7 +136,7 @@ vddao_1v8: regulator-vddao_1v8 {
 		regulator-always-on;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -165,7 +165,7 @@ vddcpu: regulator-vddcpu {
 	};
 
 	/* USB Hub Power Enable */
-	vl_pwr_en: regulator-vl_pwr_en {
+	vl_pwr_en: regulator-vl-pwr-en {
 		compatible = "regulator-fixed";
 		regulator-name = "VL_PWR_EN";
 		regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts
index 846a2d6c20e5..0170139b8d32 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts
@@ -43,7 +43,7 @@ led-red {
 	};
 
 	/* Powers the SATA Disk 0 regulator, which is enabled when a disk load is detected */
-	p12v_0: regulator-p12v_0 {
+	p12v_0: regulator-p12v-0 {
 		compatible = "regulator-fixed";
 		regulator-name = "P12V_0";
 		regulator-min-microvolt = <12000000>;
@@ -56,7 +56,7 @@ p12v_0: regulator-p12v_0 {
 	};
 
 	/* Powers the SATA Disk 1 regulator, which is enabled when a disk load is detected */
-	p12v_1: regulator-p12v_1 {
+	p12v_1: regulator-p12v-1 {
 		compatible = "regulator-fixed";
 		regulator-name = "P12V_1";
 		regulator-min-microvolt = <12000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index 1db2327bbd13..951eb8e3f0c0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -28,7 +28,7 @@ emmc_pwrseq: emmc-pwrseq {
 		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
 	};
 
-	tflash_vdd: regulator-tflash_vdd {
+	tflash_vdd: regulator-tflash-vdd {
 		compatible = "regulator-fixed";
 
 		regulator-name = "TFLASH_VDD";
@@ -40,7 +40,7 @@ tflash_vdd: regulator-tflash_vdd {
 		regulator-always-on;
 	};
 
-	tf_io: gpio-regulator-tf_io {
+	tf_io: gpio-regulator-tf-io {
 		compatible = "regulator-gpio";
 
 		regulator-name = "TF_IO";
@@ -59,7 +59,7 @@ tf_io: gpio-regulator-tf_io {
 			 <1800000 1>;
 	};
 
-	flash_1v8: regulator-flash_1v8 {
+	flash_1v8: regulator-flash-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "FLASH_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -68,7 +68,7 @@ flash_1v8: regulator-flash_1v8 {
 		regulator-always-on;
 	};
 
-	main_12v: regulator-main_12v {
+	main_12v: regulator-main-12v {
 		compatible = "regulator-fixed";
 		regulator-name = "12V";
 		regulator-min-microvolt = <12000000>;
@@ -76,7 +76,7 @@ main_12v: regulator-main_12v {
 		regulator-always-on;
 	};
 
-	vcc_5v: regulator-vcc_5v {
+	vcc_5v: regulator-vcc-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "5V";
 		regulator-min-microvolt = <5000000>;
@@ -87,7 +87,7 @@ vcc_5v: regulator-vcc_5v {
 		enable-active-high;
 	};
 
-	vcc_1v8: regulator-vcc_1v8 {
+	vcc_1v8: regulator-vcc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -96,7 +96,7 @@ vcc_1v8: regulator-vcc_1v8 {
 		regulator-always-on;
 	};
 
-	vcc_3v3: regulator-vcc_3v3 {
+	vcc_3v3: regulator-vcc-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VCC_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -125,7 +125,7 @@ vddcpu: regulator-vddcpu {
 		regulator-always-on;
 	};
 
-	usb_pwr_en: regulator-usb_pwr_en {
+	usb_pwr_en: regulator-usb-pwr-en {
 		compatible = "regulator-fixed";
 		regulator-name = "USB_PWR_EN";
 		regulator-min-microvolt = <5000000>;
@@ -137,7 +137,7 @@ usb_pwr_en: regulator-usb_pwr_en {
 		enable-active-high;
 	};
 
-	vddao_1v8: regulator-vddao_1v8 {
+	vddao_1v8: regulator-vddao-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -146,7 +146,7 @@ vddao_1v8: regulator-vddao_1v8 {
 		regulator-always-on;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
index 109932068dbe..3581e14cbf18 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
@@ -127,7 +127,7 @@ memory at 0 {
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
 
-	ao_5v: regulator-ao_5v {
+	ao_5v: regulator-ao-5v {
 		compatible = "regulator-fixed";
 		regulator-name = "AO_5V";
 		regulator-min-microvolt = <5000000>;
@@ -136,7 +136,7 @@ ao_5v: regulator-ao_5v {
 		regulator-always-on;
 	};
 
-	dc_in: regulator-dc_in {
+	dc_in: regulator-dc-in {
 		compatible = "regulator-fixed";
 		regulator-name = "DC_IN";
 		regulator-min-microvolt = <5000000>;
@@ -144,7 +144,7 @@ dc_in: regulator-dc_in {
 		regulator-always-on;
 	};
 
-	emmc_1v8: regulator-emmc_1v8 {
+	emmc_1v8: regulator-emmc-1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "EMMC_1V8";
 		regulator-min-microvolt = <1800000>;
@@ -153,7 +153,7 @@ emmc_1v8: regulator-emmc_1v8 {
 		regulator-always-on;
 	};
 
-	vddao_3v3: regulator-vddao_3v3 {
+	vddao_3v3: regulator-vddao-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3";
 		regulator-min-microvolt = <3300000>;
@@ -163,7 +163,7 @@ vddao_3v3: regulator-vddao_3v3 {
 	};
 
 	/* Used by Tuner, RGB Led & IR Emitter LED array */
-	vddao_3v3_t: regulator-vddao_3v3_t {
+	vddao_3v3_t: regulator-vddao-3v3-t {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDAO_3V3_T";
 		regulator-min-microvolt = <3300000>;
@@ -192,7 +192,7 @@ vddcpu: regulator-vddcpu {
 		regulator-always-on;
 	};
 
-	vddio_ao1v8: regulator-vddio_ao1v8 {
+	vddio_ao1v8: regulator-vddio-ao1v8 {
 		compatible = "regulator-fixed";
 		regulator-name = "VDDIO_AO1V8";
 		regulator-min-microvolt = <1800000>;
-- 
2.34.1



From manojkiran.eda at gmail.com  Tue Feb 13 06:36:08 2024
From: manojkiran.eda at gmail.com (Manojkiran Eda)
Date: Tue, 13 Feb 2024 20:06:08 +0530
Subject: [PATCH] Add eSPI device driver (flash channel)
Message-ID: <20240213-espi_driver-v1-1-92741c812843@gmail.com>

This patch adds the driver support for the eSPI controller of
Aspeed 5/6th generation SoCs. This controller is a slave device
communicating with a master over Enhanced Serial Peripheral
Interface (eSPI).

eSPI supports 4 channels, namely peripheral, virtual wire,
out-of-band, and flash, and operates at max frequency of 66MHz.

But at the moment, this patch set only supports the flash channel.

Signed-off-by: Manojkiran Eda <manojkiran.eda at gmail.com>
---
Hello everyone,

I'm presenting a revised version of the eSPI device driver patch series found at the following link:

https://lore.kernel.org/openbmc/20220516005412.4844-1-chiawei_wang at aspeedtech.com/ 

This update addresses the issues identified during the review process.

While the previous patch series attempted to incorporate support for all four different channels of eSPI,
this new series focuses on upstreaming the flash channel initially, ensuring that all review comments are
duly addressed, before progressing further.

Results:

Successfully conducted a flash update via eSPI.

Note:

This marks my inaugural endeavor in contributing code to the kernel subsystem. I kindly request reviewers
to incorporate as many details as possible in the review comments.
---
 .../devicetree/bindings/soc/aspeed/espi.yaml       | 125 ++++++
 arch/arm/boot/dts/aspeed/aspeed-g6.dtsi            |  16 +-
 drivers/mtd/mtdcore.c                              |   2 +-
 drivers/soc/aspeed/Kconfig                         |  10 +
 drivers/soc/aspeed/Makefile                        |   3 +
 drivers/soc/aspeed/aspeed-espi-ctrl.c              | 197 +++++++++
 drivers/soc/aspeed/aspeed-espi-ctrl.h              | 169 ++++++++
 drivers/soc/aspeed/aspeed-espi-flash.c             | 466 +++++++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-flash.h             |  45 ++
 include/uapi/linux/espi/aspeed-espi-ioc.h          | 103 +++++
 10 files changed, 1134 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/aspeed/espi.yaml b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
new file mode 100644
index 000000000000..6521a351d18d
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
@@ -0,0 +1,125 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# # Copyright (c) 2021 Aspeed Technology Inc.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/soc/aspeed/espi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Aspeed eSPI Controller
+
+maintainers:
+  - Manojkiran Eda <manojkiran.eda at gmail.com>
+  - Patrick Rudolph <patrick.rudolph at 9elements.com>
+  - Chia-Wei Wang <chiawei_wang at aspeedtech.com>
+  - Ryan Chen <ryan_chen at aspeedtech.com>
+
+description:
+  Aspeed eSPI controller implements a slave side eSPI endpoint device
+  supporting the four eSPI channels, namely peripheral, virtual wire,
+  out-of-band, and flash.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - aspeed,ast2500-espi
+          - aspeed,ast2600-espi
+      - const: simple-mfd
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^espi-ctrl@[0-9a-f]+$":
+    type: object
+
+    description: Control of the four basic eSPI channels
+
+    properties:
+      compatible:
+        items:
+          - enum:
+              - aspeed,ast2500-espi-ctrl
+              - aspeed,ast2600-espi-ctrl
+
+      interrupts:
+        maxItems: 1
+
+      clocks:
+        maxItems: 1
+
+      flash,dma-mode:
+        type: boolean
+        description: Enable DMA support for eSPI flash channel
+
+      flash,safs-mode:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [ 0, 1, 2 ]
+        default: 0
+        description: Slave-Attached-Sharing-Flash mode, 0->Mix, 1->SW, 2->HW
+
+    required:
+      - compatible
+      - interrupts
+      - clocks
+
+  "^espi-mmbi@[0-9a-f]+$":
+    type: object
+
+    description: Control of the PCH-BMC data exchange over eSPI peripheral memory cycle
+
+    properties:
+      compatible:
+        const: aspeed,ast2600-espi-mmbi
+
+      interrupts:
+        maxItems: 1
+
+    required:
+      - compatible
+      - interrupts
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/ast2600-clock.h>
+
+    espi: espi at 1e6ee000 {
+        compatible = "aspeed,ast2600-espi", "simple-mfd", "syscon";
+        reg = <0x1e6ee000 0x1000>;
+
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0x0 0x1e6ee000 0x1000>;
+
+        espi_ctrl: espi-ctrl at 0 {
+            compatible = "aspeed,ast2600-espi-ctrl";
+            reg = <0x0 0x800>;
+            interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
+        };
+
+        espi_mmbi: espi-mmbi at 800 {
+            compatible = "aspeed,ast2600-espi-mmbi";
+            reg = <0x800 0x50>;
+            interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+        };
+    };
diff --git a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
index c4d1faade8be..08d7a2689086 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
@@ -453,7 +453,21 @@ video: video at 1e700000 {
 				interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
 				status = "disabled";
 			};
-
+			espi: espi at 1e6ee000 {
+				compatible = "aspeed,ast2600-espi", "simple-mfd", "syscon";
+				reg = <0x1e6ee000 0x1000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1e6ee000 0x1000>;
+				espi_ctrl: espi-ctrl at 0 {
+						compatible = "aspeed,ast2600-espi-ctrl";
+						reg = <0x0 0x800>,<0x0 0x4000000>;
+						reg-names = "espi_ctrl","espi_flash";
+						interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+						clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
+						status = "disabled";
+						};
+			};
 			gpio0: gpio at 1e780000 {
 				#gpio-cells = <2>;
 				gpio-controller;
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index e451b28840d5..cc51c9fb2c1e 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -2560,7 +2560,7 @@ static void __exit cleanup_mtd(void)
 	idr_destroy(&mtd_idr);
 }
 
-module_init(init_mtd);
+subsys_initcall(init_mtd);
 module_exit(cleanup_mtd);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
index f579ee0b5afa..468f000abc66 100644
--- a/drivers/soc/aspeed/Kconfig
+++ b/drivers/soc/aspeed/Kconfig
@@ -52,6 +52,16 @@ config ASPEED_SOCINFO
 	help
 	  Say yes to support decoding of ASPEED BMC information.
 
+config ASPEED_ESPI
+	bool "ASPEED eSPI slave driver"
+	select REGMAP
+	select MFD_SYSCON
+	default n
+	help
+	  Enable driver support for the Aspeed eSPI engine. The eSPI engine
+	  plays as a slave device in BMC to communicate with the Host over
+	  the eSPI interface.
+
 endmenu
 
 endif
diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile
index b35d74592964..a6e2464a08af 100644
--- a/drivers/soc/aspeed/Makefile
+++ b/drivers/soc/aspeed/Makefile
@@ -4,3 +4,6 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP)		+= aspeed-lpc-snoop.o
 obj-$(CONFIG_ASPEED_UART_ROUTING)	+= aspeed-uart-routing.o
 obj-$(CONFIG_ASPEED_P2A_CTRL)		+= aspeed-p2a-ctrl.o
 obj-$(CONFIG_ASPEED_SOCINFO)		+= aspeed-socinfo.o
+obj-$(CONFIG_ASPEED_ESPI)		    += aspeed-espi-ctrl.o \
+                                       aspeed-espi-flash.o
+
diff --git a/drivers/soc/aspeed/aspeed-espi-ctrl.c b/drivers/soc/aspeed/aspeed-espi-ctrl.c
new file mode 100644
index 000000000000..8fa9efee9210
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ctrl.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 IBM Corporation.
+ */
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+
+#include "aspeed-espi-ctrl.h"
+#include "aspeed-espi-flash.h"
+
+/**
+ * aspeed_espi_ctrl_isr - function to handle various interrupts
+ * @irq: interrupt line
+ * @arg: pointer to access device registers
+ *
+ * Returns IRQ_HANDLED
+ */
+static irqreturn_t aspeed_espi_ctrl_isr(int irq, void *arg)
+{
+	uint32_t sts;
+	struct aspeed_espi_ctrl *espi_ctrl = (struct aspeed_espi_ctrl *)arg;
+
+	regmap_read(espi_ctrl->map, ESPI_INT_STS, &sts);
+
+	if (sts & ESPI_INT_STS_FLASH_BITS) {
+		aspeed_espi_flash_event(sts, espi_ctrl->flash);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS,
+			     sts & ESPI_INT_STS_FLASH_BITS);
+	}
+
+	if (sts & ESPI_INT_STS_HW_RST_DEASSERT) {
+		aspeed_espi_flash_enable(espi_ctrl->flash);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T0, 0x0);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T1, 0x0);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_EN, 0xffffffff);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_T0, 0x1);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_EN, 0x1);
+
+		regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+				   ESPI_INT_EN_HW_RST_DEASSERT,
+				   ESPI_INT_EN_HW_RST_DEASSERT);
+
+		regmap_update_bits(
+			espi_ctrl->map, ESPI_SYSEVT,
+			ESPI_SYSEVT_SLV_BOOT_STS | ESPI_SYSEVT_SLV_BOOT_DONE,
+			ESPI_SYSEVT_SLV_BOOT_STS | ESPI_SYSEVT_SLV_BOOT_DONE);
+
+		regmap_write(espi_ctrl->map, ESPI_INT_STS,
+			     ESPI_INT_STS_HW_RST_DEASSERT);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * aspeed_espi_ctrl_probe - function to probe the platform driver
+ * @pdev: platform device
+ *
+ * Returns 0 on success, -ENOMEM on error
+ */
+static int aspeed_espi_ctrl_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct aspeed_espi_ctrl *espi_ctrl;
+	struct device *dev = &pdev->dev;
+
+	espi_ctrl = devm_kzalloc(dev, sizeof(*espi_ctrl), GFP_KERNEL);
+	if (!espi_ctrl)
+		return -ENOMEM;
+
+	espi_ctrl->model = of_device_get_match_data(dev);
+
+	espi_ctrl->map = syscon_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR(espi_ctrl->map)) {
+		dev_err(dev, "cannot get remap\n");
+		return PTR_ERR(espi_ctrl->map);
+	}
+
+	espi_ctrl->irq = platform_get_irq(pdev, 0);
+	if (espi_ctrl->irq < 0)
+		return espi_ctrl->irq;
+
+	espi_ctrl->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(espi_ctrl->clk)) {
+		dev_err(dev, "cannot get clock\n");
+		return PTR_ERR(espi_ctrl->clk);
+	}
+
+	rc = clk_prepare_enable(espi_ctrl->clk);
+	if (rc) {
+		dev_err(dev, "cannot enable clock\n");
+		return rc;
+	}
+
+	/*
+	 * This takes care of deferred probe , incase the mtd core
+	 * subsystem is not probed yet.
+	 */
+	espi_ctrl->flash = aspeed_espi_flash_alloc(dev, espi_ctrl);
+	if (IS_ERR(espi_ctrl->flash)) {
+		dev_err(dev, "failed to allocate flash channel\n");
+		pr_info("flash alloc failed with return code %ld\n",
+			PTR_ERR(espi_ctrl->flash));
+		return PTR_ERR(espi_ctrl->flash);
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T0, 0x0);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T1, 0x0);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_EN, 0xffffffff);
+
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_T0, 0x1);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_EN, 0x1);
+
+	rc = devm_request_irq(dev, espi_ctrl->irq, aspeed_espi_ctrl_isr, 0,
+			      DEVICE_NAME, espi_ctrl);
+	if (rc) {
+		dev_err(dev, "failed to request IRQ\n");
+		return rc;
+	}
+
+	// clear the interrupt enable register
+	regmap_write(espi_ctrl->map, ESPI_INT_EN_CLR, 0x7fffffff);
+
+	// Disable the interrupts in all channels except flash channel
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_FLASH_BITS | ESPI_INT_EN_HW_RST_DEASSERT,
+			   ESPI_INT_EN_FLASH_BITS |
+				   ESPI_INT_STS_HW_RST_DEASSERT);
+
+	dev_set_drvdata(dev, espi_ctrl);
+
+	dev_info(dev, "module loaded\n");
+
+	return 0;
+}
+
+/**
+ * aspeed_espi_ctrl_remove - Release the driver
+ * @pdev: the platform device
+ *
+ * Returns 0
+ */
+static int aspeed_espi_ctrl_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct aspeed_espi_ctrl *espi_ctrl = dev_get_drvdata(dev);
+
+	aspeed_espi_flash_free(dev, espi_ctrl->flash);
+
+	return 0;
+}
+
+static const struct aspeed_espi_model ast2500_model = {
+	.version = ESPI_AST2500,
+};
+
+static const struct aspeed_espi_model ast2600_model = {
+	.version = ESPI_AST2600,
+};
+
+static const struct of_device_id aspeed_espi_ctrl_of_matches[] = {
+	{ .compatible = "aspeed,ast2500-espi-ctrl", .data = &ast2500_model },
+	{ .compatible = "aspeed,ast2600-espi-ctrl", .data = &ast2600_model },
+	{},
+};
+MODULE_DEVICE_TABLE(of, aspeed_espi_ctrl_of_matches);
+
+static struct platform_driver aspeed_espi_ctrl_driver = {
+	.driver = {
+		.name = DEVICE_NAME,
+		.of_match_table = aspeed_espi_ctrl_of_matches,
+	},
+	.probe = aspeed_espi_ctrl_probe,
+	.remove = aspeed_espi_ctrl_remove,
+};
+
+module_platform_driver(aspeed_espi_ctrl_driver);
+
+MODULE_AUTHOR("Manojkiran Eda <manojkiran.eda at gmail.com>");
+MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph at 9elements.com>");
+MODULE_AUTHOR("Chia-Wei Wang <chiawei_wang at aspeedtech.com>");
+MODULE_AUTHOR("Ryan Chen <ryan_chen at aspeedtech.com>");
+MODULE_DESCRIPTION("Control of Aspeed eSPI Slave Device");
+MODULE_LICENSE("GPL");
diff --git a/drivers/soc/aspeed/aspeed-espi-ctrl.h b/drivers/soc/aspeed/aspeed-espi-ctrl.h
new file mode 100644
index 000000000000..3e20cbebf8b2
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ctrl.h
@@ -0,0 +1,169 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 IBM Corporation.
+ */
+#ifndef _ASPEED_ESPI_CTRL_H_
+#define _ASPEED_ESPI_CTRL_H_
+
+#include <linux/bits.h>
+
+#define DEVICE_NAME "aspeed-espi-ctrl"
+
+/**
+ * enum aspeed_espi_version - Enumeration to capture aspeed versions that this
+ *                            driver supports
+ * @ESPI_AST2500: eSPI for AST2500 Model
+ * @ESPI_AST2600: eSPI for AST2600 Model
+ *
+ * This enumeration captures various aspeed models that this driver supports
+ */
+
+enum aspeed_espi_version {
+	ESPI_AST2500,
+	ESPI_AST2600,
+};
+
+/**
+ * struct aspeed_espi_model - structure to capture version of espi
+ * @version: espi version
+ *
+ * Structure to capture version of eSPI
+ */
+struct aspeed_espi_model {
+	uint32_t version;
+};
+
+/**
+ * struct aspeed_espi_ctrl - structure to group various channels of the driver
+ * @dev: platform device pointer
+ * @map: register map for the device
+ * @clk: clock for the device
+ * @irq: interrupt request
+ * @flash: pointer to flash channel of eSPI
+ * @model: pointer to version of eSPI
+ *
+ * Structure to capture version of eSPI
+ */
+struct aspeed_espi_ctrl {
+	struct device *dev;
+	struct regmap *map;
+	struct clk *clk;
+	int irq;
+	struct aspeed_espi_flash *flash;
+	const struct aspeed_espi_model *model;
+};
+
+/* eSPI register offset */
+#define ESPI_CTRL 0x000
+#define ESPI_CTRL_FLASH_TX_DMA_EN BIT(23)
+#define ESPI_CTRL_FLASH_RX_DMA_EN BIT(22)
+#define ESPI_CTRL_FLASH_SW_MODE_MASK GENMASK(11, 10)
+#define ESPI_CTRL_FLASH_SW_MODE_SHIFT 10
+#define ESPI_CTRL_FLASH_SW_RDY BIT(7)
+
+#define ESPI_STS 0x004
+#define ESPI_CTRL_FLASH_CHAN_RDY BIT(6)
+
+#define ESPI_INT_STS 0x008
+#define ESPI_INT_STS_HW_RST_DEASSERT BIT(31)
+#define ESPI_INT_STS_FLASH_TX_ERR BIT(21)
+#define ESPI_INT_STS_FLASH_TX_ABT BIT(19)
+#define ESPI_INT_STS_FLASH_RX_ABT BIT(15)
+#define ESPI_INT_STS_FLASH_TX_CMPLT BIT(7)
+#define ESPI_INT_STS_FLASH_RX_CMPLT BIT(6)
+#define ESPI_INT_EN 0x00c
+#define ESPI_INT_EN_HW_RST_DEASSERT BIT(31)
+#define ESPI_INT_EN_FLASH_TX_ERR BIT(21)
+#define ESPI_INT_EN_FLASH_TX_ABT BIT(19)
+#define ESPI_INT_EN_FLASH_RX_ABT BIT(15)
+#define ESPI_INT_EN_FLASH_TX_CMPLT BIT(7)
+#define ESPI_INT_EN_FLASH_RX_CMPLT BIT(6)
+#define ESPI_INT_EN_CLR 0x0fc
+#define ESPI_FLASH_RX_DMA 0x060
+#define ESPI_FLASH_RX_CTRL 0x064
+#define ESPI_FLASH_RX_CTRL_PEND_SERV BIT(31)
+#define ESPI_FLASH_RX_CTRL_LEN_MASK GENMASK(23, 12)
+#define ESPI_FLASH_RX_CTRL_LEN_SHIFT 12
+#define ESPI_FLASH_RX_CTRL_TAG_MASK GENMASK(11, 8)
+#define ESPI_FLASH_RX_CTRL_TAG_SHIFT 8
+#define ESPI_FLASH_RX_CTRL_CYC_MASK GENMASK(7, 0)
+#define ESPI_FLASH_RX_CTRL_CYC_SHIFT 0
+#define ESPI_FLASH_RX_PORT 0x068
+#define ESPI_FLASH_TX_DMA 0x070
+#define ESPI_FLASH_TX_CTRL 0x074
+#define ESPI_FLASH_TX_CTRL_TRIGGER BIT(31)
+#define ESPI_FLASH_TX_CTRL_LEN_MASK GENMASK(23, 12)
+#define ESPI_FLASH_TX_CTRL_LEN_SHIFT 12
+#define ESPI_FLASH_TX_CTRL_TAG_MASK GENMASK(11, 8)
+#define ESPI_FLASH_TX_CTRL_TAG_SHIFT 8
+#define ESPI_FLASH_TX_CTRL_CYC_MASK GENMASK(7, 0)
+#define ESPI_FLASH_TX_CTRL_CYC_SHIFT 0
+#define ESPI_FLASH_TX_PORT 0x078
+#define ESPI_CTRL2 0x080
+#define ESPI_CTRL2_MEMCYC_RD_DIS BIT(6)
+#define ESPI_CTRL2_MEMCYC_WR_DIS BIT(4)
+#define ESPI_SYSEVT_INT_EN 0x094
+#define ESPI_SYSEVT 0x098
+#define ESPI_SYSEVT_HOST_RST_ACK BIT(27)
+#define ESPI_SYSEVT_RST_CPU_INIT BIT(26)
+#define ESPI_SYSEVT_SLV_BOOT_STS BIT(23)
+#define ESPI_SYSEVT_NON_FATAL_ERR BIT(22)
+#define ESPI_SYSEVT_FATAL_ERR BIT(21)
+#define ESPI_SYSEVT_SLV_BOOT_DONE BIT(20)
+#define ESPI_SYSEVT_NMI_OUT BIT(10)
+#define ESPI_SYSEVT_SMI_OUT BIT(9)
+#define ESPI_SYSEVT_HOST_RST_WARN BIT(8)
+#define ESPI_SYSEVT_PLTRSTN BIT(5)
+#define ESPI_SYSEVT_SUSPEND BIT(4)
+#define ESPI_SYSEVT_S5_SLEEP BIT(2)
+#define ESPI_SYSEVT_S4_SLEEP BIT(1)
+#define ESPI_SYSEVT_S3_SLEEP BIT(0)
+#define ESPI_GEN_CAP_N_CONF 0x0a0
+#define ESPI_CH0_CAP_N_CONF 0x0a4
+#define ESPI_CH1_CAP_N_CONF 0x0a8
+#define ESPI_CH2_CAP_N_CONF 0x0ac
+#define ESPI_CH3_CAP_N_CONF 0x0b0
+#define ESPI_CH3_CAP_N_CONF_ERASE_MASK GENMASK(4, 2)
+#define ESPI_CH3_CAP_N_CONF_ERASE_SHIFT 2
+#define ESPI_CH3_CAP_N_CONF_ERASE_SIZE_4KB 1
+#define ESPI_CH3_CAP_N_CONF_ERASE_SIZE_64KB 2
+#define ESPI_CH3_CAP_N_CONF_ERASE_SIZE_4KB_64KB 3
+#define ESPI_CH3_CAP_N_CONF_ERASE_SIZE_128KB 4
+#define ESPI_CH3_CAP_N_CONF_ERASE_SIZE_256KB 5
+#define ESPI_CH3_CAP_N_CONF2 0x0b4
+#define ESPI_SYSEVT1_INT_EN 0x100
+#define ESPI_SYSEVT1 0x104
+#define ESPI_SYSEVT1_SUSPEND_ACK BIT(20)
+#define ESPI_SYSEVT1_SUSPEND_WARN BIT(0)
+#define ESPI_SYSEVT_INT_T0 0x110
+#define ESPI_SYSEVT_INT_T1 0x114
+#define ESPI_SYSEVT_INT_T2 0x118
+#define ESPI_SYSEVT_INT_T2_HOST_RST_WARN ESPI_SYSEVT_HOST_RST_WARN
+#define ESPI_SYSEVT_INT_STS 0x11c
+#define ESPI_SYSEVT_INT_STS_NMI_OUT ESPI_SYSEVT_NMI_OUT
+#define ESPI_SYSEVT_INT_STS_SMI_OUT ESPI_SYSEVT_SMI_OUT
+#define ESPI_SYSEVT_INT_STS_HOST_RST_WARN ESPI_SYSEVT_HOST_RST_WARN
+#define ESPI_SYSEVT_INT_STS_PLTRSTN ESPI_SYSEVT_PLTRSTN
+#define ESPI_SYSEVT_INT_STS_SUSPEND ESPI_SYSEVT_SUSPEND
+#define ESPI_SYSEVT_INT_STS_S5_SLEEP ESPI_SYSEVT_INT_S5_SLEEP
+#define ESPI_SYSEVT_INT_STS_S4_SLEEP ESPI_SYSEVT_INT_S4_SLEEP
+#define ESPI_SYSEVT_INT_STS_S3_SLEEP ESPI_SYSEVT_INT_S3_SLEEP
+#define ESPI_SYSEVT1_INT_T0 0x120
+#define ESPI_SYSEVT1_INT_T1 0x124
+#define ESPI_SYSEVT1_INT_T2 0x128
+#define ESPI_SYSEVT1_INT_STS 0x12c
+#define ESPI_SYSEVT1_INT_STS_SUSPEND_WARN ESPI_SYSEVT1_SUSPEND_WARN
+
+/* collect ESPI_INT_STS bits of eSPI channels for convenience */
+#define ESPI_INT_STS_FLASH_BITS                                    \
+	(ESPI_INT_STS_FLASH_TX_ERR | ESPI_INT_STS_FLASH_TX_ABT |   \
+	 ESPI_INT_STS_FLASH_RX_ABT | ESPI_INT_STS_FLASH_TX_CMPLT | \
+	 ESPI_INT_STS_FLASH_RX_CMPLT)
+
+/* collect ESPI_INT_EN bits of eSPI channels for convenience */
+#define ESPI_INT_EN_FLASH_BITS                                   \
+	(ESPI_INT_EN_FLASH_TX_ERR | ESPI_INT_EN_FLASH_TX_ABT |   \
+	 ESPI_INT_EN_FLASH_RX_ABT | ESPI_INT_EN_FLASH_TX_CMPLT | \
+	 ESPI_INT_EN_FLASH_RX_CMPLT)
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-flash.c b/drivers/soc/aspeed/aspeed-espi-flash.c
new file mode 100644
index 000000000000..d3cf5011426e
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-flash.c
@@ -0,0 +1,466 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2023 IBM Corporation
+ */
+#include <linux/fs.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/miscdevice.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+
+#include "linux/espi/aspeed-espi-ioc.h"
+#include "aspeed-espi-ctrl.h"
+#include "aspeed-espi-flash.h"
+
+static long aspeed_espi_flash_rx(uint8_t *cyc, uint16_t *len, uint32_t *addr,
+				 uint8_t *pkt, size_t *pkt_len,
+				 struct aspeed_espi_flash *espi_flash)
+{
+	unsigned long flags;
+	uint32_t reg, rx_pkt_len, addr_be;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+	void *rx_virt_ptr;
+	ulong to;
+	int ret;
+
+	spin_lock_irqsave(&espi_flash->spinlock, flags);
+
+	to = msecs_to_jiffies(100);
+	ret = wait_event_interruptible_lock_irq_timeout(
+		espi_flash->wq, espi_flash->rx_sts, espi_flash->spinlock, to);
+
+	spin_unlock_irqrestore(&espi_flash->spinlock, flags);
+
+	if (ret == -ERESTARTSYS)
+		return -EINTR;
+	else if (!ret)
+		return -ETIMEDOUT;
+	else if (espi_flash->rx_sts & ESPI_INT_STS_FLASH_RX_ABT)
+		return -EFAULT;
+	else
+		ret = 0;
+
+	/* common header (i.e. cycle type, tag, and length) is taken by HW */
+	regmap_read(espi_ctrl->map, ESPI_FLASH_RX_CTRL, &reg);
+	*cyc = (reg & ESPI_FLASH_RX_CTRL_CYC_MASK) >>
+	       ESPI_FLASH_RX_CTRL_CYC_SHIFT;
+	*len = (reg & ESPI_FLASH_RX_CTRL_LEN_MASK) >>
+	       ESPI_FLASH_RX_CTRL_LEN_SHIFT;
+
+	/*
+	 * calculate the length of the rest part of the
+	 * eSPI packet to be read from HW and copied to
+	 * user space.
+	 */
+	switch (*cyc) {
+	case ESPI_FLASH_READ:
+	case ESPI_FLASH_WRITE:
+	case ESPI_FLASH_ERASE:
+		rx_virt_ptr = espi_flash->dma.rx_virt + sizeof(addr_be);
+		rx_pkt_len = (*len) ? *len : ESPI_PLD_LEN_MAX;
+
+		if (addr) {
+			memcpy(&addr_be, espi_flash->dma.rx_virt,
+			       sizeof(addr_be));
+			*addr = ntohl(addr_be);
+		}
+
+		break;
+	case ESPI_FLASH_SUC_CMPLT_D_MIDDLE:
+	case ESPI_FLASH_SUC_CMPLT_D_FIRST:
+	case ESPI_FLASH_SUC_CMPLT_D_LAST:
+	case ESPI_FLASH_SUC_CMPLT_D_ONLY:
+		rx_pkt_len = (*len) ? *len : ESPI_PLD_LEN_MAX;
+		rx_virt_ptr = espi_flash->dma.rx_virt;
+		break;
+	case ESPI_FLASH_SUC_CMPLT:
+	case ESPI_FLASH_UNSUC_CMPLT:
+	case ESPI_FLASH_UNSUC_CMPLT_ONLY:
+		/* No data received */
+		rx_pkt_len = 0;
+		rx_virt_ptr = NULL;
+		break;
+	default:
+		rx_pkt_len = 0;
+		ret = -EFAULT;
+	}
+	if (pkt_len)
+		*pkt_len = rx_pkt_len;
+
+	if (rx_pkt_len && pkt_len && pkt) {
+		if (*pkt_len >= rx_pkt_len)
+			memcpy(pkt, rx_virt_ptr, rx_pkt_len);
+		else
+			ret = -EINVAL;
+	}
+
+	spin_lock_irqsave(&espi_flash->spinlock, flags);
+
+	regmap_write_bits(espi_ctrl->map, ESPI_FLASH_RX_CTRL,
+			  ESPI_FLASH_RX_CTRL_PEND_SERV,
+			  ESPI_FLASH_RX_CTRL_PEND_SERV);
+
+	espi_flash->rx_sts = 0;
+
+	spin_unlock_irqrestore(&espi_flash->spinlock, flags);
+	return ret;
+}
+
+static long
+aspeed_espi_flash_rx_get_completion(struct aspeed_espi_flash *espi_flash)
+{
+	uint8_t cyc;
+	uint16_t len;
+	int ret;
+
+	ret = aspeed_espi_flash_rx(&cyc, &len, NULL, NULL, 0, espi_flash);
+	if (ret)
+		return ret;
+
+	if (cyc != ESPI_FLASH_SUC_CMPLT) {
+		dev_notice("eSPI Rx response was not successful\n");
+		return -EFAULT;
+	}
+	return 0;
+}
+
+static long aspeed_espi_flash_put_tx(uint8_t cyc, uint16_t len, uint32_t addr,
+				     const uint8_t *pkt, size_t pkt_len,
+				     struct aspeed_espi_flash *espi_flash)
+{
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+	unsigned long flags;
+	uint32_t reg, addr_be;
+	ulong to;
+	int ret = 0;
+
+	/* Test if flash channel is ready */
+	regmap_read(espi_ctrl->map, ESPI_STS, &reg);
+	if (!(reg & ESPI_CTRL_FLASH_CHAN_RDY)) {
+		dev_notice("eSPI flash channel not ready\n");
+		return -EIO;
+	}
+
+	/* Test if TX ready */
+	regmap_read(espi_ctrl->map, ESPI_FLASH_TX_CTRL, &reg);
+	if (reg & ESPI_FLASH_TX_CTRL_TRIGGER) {
+		dev_notice("eSPI Tx operation still pending\n");
+		return -EBUSY;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	addr_be = htonl(addr);
+	memcpy(espi_flash->dma.tx_virt, &addr_be, sizeof(addr_be));
+	if (pkt && pkt_len)
+		memcpy(espi_flash->dma.tx_virt + sizeof(addr_be), pkt, pkt_len);
+
+	dma_wmb();
+
+	spin_lock_irqsave(&espi_flash->spinlock, flags);
+	espi_flash->tx_sts = 0;
+	espi_flash->rx_sts = 0;
+
+	reg = ((cyc << ESPI_FLASH_TX_CTRL_CYC_SHIFT) &
+	       ESPI_FLASH_TX_CTRL_CYC_MASK) |
+	      ((len << ESPI_FLASH_TX_CTRL_LEN_SHIFT) &
+	       ESPI_FLASH_TX_CTRL_LEN_MASK) |
+	      ESPI_FLASH_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_FLASH_TX_CTRL, reg);
+
+	to = msecs_to_jiffies(100);
+	ret = wait_event_interruptible_lock_irq_timeout(
+		espi_flash->wq, espi_flash->tx_sts, espi_flash->spinlock, to);
+	if (ret == -ERESTARTSYS)
+		ret = -EINTR;
+	else if (!ret) {
+		dev_notice("eSPI Tx operation not processed within 100msec\n");
+		ret = -ETIMEDOUT;
+	} else if (espi_flash->tx_sts &
+		   (ESPI_INT_STS_FLASH_TX_ERR | ESPI_INT_STS_FLASH_TX_ABT)) {
+		dev_notice("eSPI Tx operation declined by remote\n");
+
+		ret = -EFAULT;
+	} else
+		ret = 0;
+
+	spin_unlock_irqrestore(&espi_flash->spinlock, flags);
+	return ret;
+}
+
+void aspeed_espi_flash_event(uint32_t sts, struct aspeed_espi_flash *espi_flash)
+{
+	unsigned long flags;
+
+	if (!(sts & ESPI_INT_STS_FLASH_BITS))
+		return;
+
+	spin_lock_irqsave(&espi_flash->spinlock, flags);
+	espi_flash->rx_sts |=
+		sts & (ESPI_INT_STS_FLASH_RX_ABT | ESPI_INT_STS_FLASH_RX_CMPLT);
+	espi_flash->tx_sts |=
+		sts & (ESPI_INT_STS_FLASH_TX_ERR | ESPI_INT_STS_FLASH_TX_ABT |
+		       ESPI_INT_STS_FLASH_TX_CMPLT);
+	spin_unlock_irqrestore(&espi_flash->spinlock, flags);
+	wake_up_interruptible(&espi_flash->wq);
+}
+
+static int aspeed_espi_flash_erase(struct mtd_info *mtd,
+				   struct erase_info *instr)
+{
+	struct aspeed_espi_flash *espi_flash = mtd->priv;
+	int ret = 0;
+
+	/* Sanity checks */
+	if ((uint32_t)instr->len % espi_flash->mtd.erasesize)
+		return -EINVAL;
+
+	if ((uint32_t)instr->addr % espi_flash->mtd.erasesize)
+		return -EINVAL;
+
+	mutex_lock(&espi_flash->lock);
+
+	while (instr->len) {
+		ret = aspeed_espi_flash_put_tx(ESPI_FLASH_ERASE,
+					       espi_flash->erase_mask,
+					       instr->addr, NULL, 0,
+					       espi_flash);
+		if (ret)
+			goto unlock_mtx_n_out;
+
+		ret = aspeed_espi_flash_rx_get_completion(espi_flash);
+		if (ret)
+			goto unlock_mtx_n_out;
+
+		instr->len -= espi_flash->mtd.erasesize;
+		instr->addr += espi_flash->mtd.erasesize;
+	}
+
+unlock_mtx_n_out:
+	instr->fail_addr = instr->addr;
+
+	mutex_unlock(&espi_flash->lock);
+	return ret;
+}
+
+static int aspeed_espi_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
+				  size_t *retlen, u_char *buf)
+{
+	struct aspeed_espi_flash *espi_flash = mtd->priv;
+	uint16_t len_pt, len_rx;
+	size_t pkt_len;
+	uint8_t cyc;
+	int ret = 0;
+
+	mutex_lock(&espi_flash->lock);
+
+	while (len) {
+		len_pt = (len > ESPI_PLD_LEN_MIN) ? ESPI_PLD_LEN_MIN : len;
+
+		ret = aspeed_espi_flash_put_tx(ESPI_FLASH_READ, len_pt, from,
+					       NULL, 0, espi_flash);
+		if (ret)
+			goto unlock_mtx_n_out;
+
+		pkt_len = len_pt;
+		len_rx = 0;
+		cyc = 0;
+		ret = aspeed_espi_flash_rx(&cyc, &len_rx, NULL, buf, &pkt_len,
+					   espi_flash);
+		if (ret)
+			goto unlock_mtx_n_out;
+
+		if (cyc != ESPI_FLASH_SUC_CMPLT_D_ONLY) {
+			dev_notice("eSPI Rx response was not successful\n");
+			ret = -EFAULT;
+			goto unlock_mtx_n_out;
+		}
+		if (pkt_len != len_pt) {
+			dev_notice("eSPI Rx response has unexpected data length\n");
+			ret = -ENODATA;
+			goto unlock_mtx_n_out;
+		}
+
+		len -= len_pt;
+		buf += len_pt;
+		from += len_pt;
+		*retlen += len_pt;
+	}
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_flash->lock);
+	return ret;
+}
+
+static int aspeed_espi_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
+				   size_t *retlen, const u_char *buf)
+{
+	struct aspeed_espi_flash *espi_flash = mtd->priv;
+	uint16_t len_pt;
+	int ret = 0;
+
+	mutex_lock(&espi_flash->lock);
+
+	while (len) {
+		len_pt = (len > ESPI_PLD_LEN_MIN) ? ESPI_PLD_LEN_MIN : len;
+
+		ret = aspeed_espi_flash_put_tx(ESPI_FLASH_WRITE, len_pt, to,
+					       buf, len_pt, espi_flash);
+		if (ret)
+			goto unlock_mtx_n_out;
+
+		ret = aspeed_espi_flash_rx_get_completion(espi_flash);
+		if (ret)
+			goto unlock_mtx_n_out;
+
+		len -= len_pt;
+		buf += len_pt;
+		to += len_pt;
+		*retlen += len_pt;
+	}
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_flash->lock);
+	return ret;
+}
+
+void aspeed_espi_flash_enable(struct aspeed_espi_flash *espi_flash)
+{
+	struct aspeed_espi_flash_dma *dma = &espi_flash->dma;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_FLASH_SW_MODE_MASK, 0);
+
+	/* Enable DMA transfers */
+	regmap_write(espi_ctrl->map, ESPI_FLASH_TX_DMA, dma->tx_addr);
+	regmap_write(espi_ctrl->map, ESPI_FLASH_RX_DMA, dma->rx_addr);
+	regmap_update_bits(
+		espi_ctrl->map, ESPI_CTRL,
+		ESPI_CTRL_FLASH_TX_DMA_EN | ESPI_CTRL_FLASH_RX_DMA_EN,
+		ESPI_CTRL_FLASH_TX_DMA_EN | ESPI_CTRL_FLASH_RX_DMA_EN);
+
+	/* Enable interrupts */
+	regmap_write(espi_ctrl->map, ESPI_INT_STS, ESPI_INT_STS_FLASH_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN, ESPI_INT_EN_FLASH_BITS,
+			   ESPI_INT_EN_FLASH_BITS);
+
+	/* Set Flash Channel Software Ready */
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL, ESPI_CTRL_FLASH_SW_RDY,
+			   ESPI_CTRL_FLASH_SW_RDY);
+}
+
+void *aspeed_espi_flash_alloc(struct device *dev,
+			      struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int ret, index;
+	struct aspeed_espi_flash_dma *dma;
+	struct mtd_info *mtd;
+	struct aspeed_espi_flash *espi_flash;
+	struct resource res;
+	u32 reg;
+
+	espi_flash =
+		devm_kzalloc(dev, sizeof(struct aspeed_espi_flash), GFP_KERNEL);
+	if (!espi_flash)
+		return ERR_PTR(-ENOMEM);
+
+	espi_flash->ctrl = espi_ctrl;
+
+	/* Bus lock */
+	mutex_init(&espi_flash->lock);
+
+	init_waitqueue_head(&espi_flash->wq);
+
+	spin_lock_init(&espi_flash->spinlock);
+
+	dma = &espi_flash->dma;
+
+	dma->tx_virt =
+		dma_alloc_coherent(dev, PAGE_SIZE, &dma->tx_addr, GFP_KERNEL);
+	if (!dma->tx_virt) {
+		dev_err(dev, "cannot allocate DMA TX buffer\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	dma->rx_virt =
+		dma_alloc_coherent(dev, PAGE_SIZE, &dma->rx_addr, GFP_KERNEL);
+	if (!dma->rx_virt) {
+		dev_err(dev, "cannot allocate DMA RX buffer\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	index = of_property_match_string(dev->of_node, "reg-names",
+					 "espi_flash");
+	ret = of_address_to_resource(dev->of_node, index, &res);
+	if (ret < 0) {
+		dev_err(dev, "something went wrong\n");
+		return ERR_PTR(-ENODEV);
+	}
+	reg = resource_size(&res);
+	mtd = &espi_flash->mtd;
+	mtd->dev.parent = dev;
+	mtd->size = reg;
+	mtd->flags = MTD_CAP_NORFLASH;
+	mtd->_erase = aspeed_espi_flash_erase;
+	mtd->_read = aspeed_espi_flash_read;
+	mtd->_write = aspeed_espi_flash_write;
+	mtd->type = MTD_NORFLASH;
+	mtd->name = DEVICE_NAME;
+
+	regmap_read(espi_ctrl->map, ESPI_CH3_CAP_N_CONF, &reg);
+	reg = (reg & ESPI_CH3_CAP_N_CONF_ERASE_MASK) >>
+	      ESPI_CH3_CAP_N_CONF_ERASE_SHIFT;
+	espi_flash->erase_mask = reg;
+	switch (reg) {
+	case ESPI_CH3_CAP_N_CONF_ERASE_SIZE_4KB:
+	case ESPI_CH3_CAP_N_CONF_ERASE_SIZE_4KB_64KB:
+		mtd->erasesize = 0x1000;
+		espi_flash->erase_mask = 1;
+		break;
+	case ESPI_CH3_CAP_N_CONF_ERASE_SIZE_64KB:
+		mtd->erasesize = 0x10000;
+		break;
+	case ESPI_CH3_CAP_N_CONF_ERASE_SIZE_128KB:
+		mtd->erasesize = 0x20000;
+		break;
+	case ESPI_CH3_CAP_N_CONF_ERASE_SIZE_256KB:
+		mtd->erasesize = 0x40000;
+		break;
+	default:
+		dev_notice("Unknown erase size %x\n", reg);
+		return ERR_PTR(-ENODEV);
+	}
+
+	mtd->writesize = 1;
+	mtd->owner = THIS_MODULE;
+	mtd->priv = espi_flash;
+
+	ret = mtd_device_register(mtd, NULL, 0);
+	if (ret) {
+		dev_notice("aspeed-espi-mtd: Failed to register mtd device\n");
+		return ERR_PTR(ret);
+	}
+
+	aspeed_espi_flash_enable(espi_flash);
+	return espi_flash;
+}
+
+void aspeed_espi_flash_free(struct device *dev,
+			    struct aspeed_espi_flash *espi_flash)
+{
+	struct aspeed_espi_flash_dma *dma = &espi_flash->dma;
+
+	dma_free_coherent(dev, PAGE_SIZE, dma->tx_virt, dma->tx_addr);
+	dma_free_coherent(dev, PAGE_SIZE, dma->rx_virt, dma->rx_addr);
+
+	mtd_device_unregister(&espi_flash->mtd);
+}
diff --git a/drivers/soc/aspeed/aspeed-espi-flash.h b/drivers/soc/aspeed/aspeed-espi-flash.h
new file mode 100644
index 000000000000..cceadd258c62
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-flash.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 IBM Corporation.
+ */
+#ifndef _ASPEED_ESPI_FLASH_H_
+#define _ASPEED_ESPI_FLASH_H_
+
+#include <linux/mtd/mtd.h>
+
+enum aspeed_espi_flash_safs_mode {
+	SAFS_MODE_MIX,
+	SAFS_MODE_SW,
+	SAFS_MODE_HW,
+	SAFS_MODES,
+};
+
+struct aspeed_espi_flash_dma {
+	void *tx_virt;
+	dma_addr_t tx_addr;
+	void *rx_virt;
+	dma_addr_t rx_addr;
+};
+
+struct aspeed_espi_flash {
+
+	unsigned short		page_offset;	/* offset in flash address */
+	unsigned int		page_size;	   /* of bytes per page */
+	struct mutex			lock;
+	struct aspeed_espi_flash_dma	dma;
+	struct mtd_info			mtd;
+	struct aspeed_espi_ctrl		*ctrl;
+	uint8_t				erase_mask;
+	uint32_t			tx_sts;
+	uint32_t			rx_sts;
+	wait_queue_head_t		wq;
+	spinlock_t			spinlock;
+};
+
+void aspeed_espi_flash_event(uint32_t sts, struct aspeed_espi_flash *espi_flash);
+void aspeed_espi_flash_enable(struct aspeed_espi_flash *espi_flash);
+void *aspeed_espi_flash_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl);
+void aspeed_espi_flash_free(struct device *dev, struct aspeed_espi_flash *espi_flash);
+
+#endif
+
diff --git a/include/uapi/linux/espi/aspeed-espi-ioc.h b/include/uapi/linux/espi/aspeed-espi-ioc.h
new file mode 100644
index 000000000000..fa5751fc7327
--- /dev/null
+++ b/include/uapi/linux/espi/aspeed-espi-ioc.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2024 IBM Corporation.
+ */
+#ifndef _ASPEED_ESPI_IOC_H
+#define _ASPEED_ESPI_IOC_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/*
+ * eSPI cycle type encoding
+ *
+ * Section 5.1 Cycle Types and Packet Format,
+ * Intel eSPI Interface Base Specification, Rev 1.0, Jan. 2016.
+ */
+#define ESPI_FLASH_READ			0x00
+#define ESPI_FLASH_WRITE		0x01
+#define ESPI_FLASH_ERASE		0x02
+#define ESPI_FLASH_SUC_CMPLT		0x06
+#define ESPI_FLASH_SUC_CMPLT_D_MIDDLE	0x09
+#define ESPI_FLASH_SUC_CMPLT_D_FIRST	0x0b
+#define ESPI_FLASH_SUC_CMPLT_D_LAST	0x0d
+#define ESPI_FLASH_SUC_CMPLT_D_ONLY	0x0f
+#define ESPI_FLASH_UNSUC_CMPLT		0x0c
+#define ESPI_FLASH_UNSUC_CMPLT_ONLY	0x0e
+
+/*
+ * eSPI packet format structure
+ *
+ * Section 5.1 Cycle Types and Packet Format,
+ * Intel eSPI Interface Base Specification, Rev 1.0, Jan. 2016.
+ */
+struct espi_comm_hdr {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+};
+
+struct espi_flash_rwe {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint32_t addr_be;
+	uint8_t data[];
+} __packed;
+
+struct espi_flash_cmplt {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t data[];
+} __packed;
+
+struct aspeed_espi_ioc {
+	uint32_t pkt_len;
+	uint8_t *pkt;
+};
+
+/*
+ * we choose the longest header and the max payload size
+ * based on the Intel specification to define the maximum
+ * eSPI packet length
+ */
+#define ESPI_PLD_LEN_MIN	(1UL << 6)
+#define ESPI_PLD_LEN_MAX	(1UL << 12)
+#define ESPI_PKT_LEN_MAX	(sizeof(struct espi_perif_msg) + ESPI_PLD_LEN_MAX)
+
+#define __ASPEED_ESPI_IOCTL_MAGIC	0xb8
+
+/*
+ * The IOCTL-based interface works in the eSPI packet in/out paradigm.
+ *
+ * Only the virtual wire IOCTL is a special case which does not send
+ * or receive an eSPI packet. However, to keep a more consistent use from
+ * userspace, we make all of the four channel drivers serve through the
+ * IOCTL interface.
+ *
+ * For the eSPI packet format, refer to
+ *   Section 5.1 Cycle Types and Packet Format,
+ *   Intel eSPI Interface Base Specification, Rev 1.0, Jan. 2016.
+ *
+ * For the example user apps using these IOCTL, refer to
+ *   https://github.com/AspeedTech-BMC/aspeed_app/tree/master/espi_test
+ */
+
+/*
+ * Flash Channel (CH3)
+ *  - ASPEED_ESPI_FLASH_GET_RX
+ *      Receive an eSPI flash packet
+ *  - ASPEED_ESPI_FLASH_PUT_TX
+ *      Transmit an eSPI flash packet
+ */
+#define ASPEED_ESPI_FLASH_GET_RX	_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x30, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_FLASH_PUT_TX	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x31, struct aspeed_espi_ioc)
+
+#endif
+

---
base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de
change-id: 20240213-espi_driver-5861a64d7dc4

Best regards,
-- 
Manojkiran Eda <manojkiran.eda at gmail.com>



From srinivas.kandagatla at linaro.org  Tue Feb 13 06:36:27 2024
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 13 Feb 2024 14:36:27 +0000
Subject: (subset) [PATCH 0/3] soc: mediatek: mtk-socinfo: Fixes and
 cleanup
In-Reply-To: <20240130095656.3712469-1-wenst@chromium.org>
References: <20240130095656.3712469-1-wenst@chromium.org>
Message-ID: <170783498706.33763.10510416022837379654.b4-ty@linaro.org>


On Tue, 30 Jan 2024 17:56:50 +0800, Chen-Yu Tsai wrote:
> The new mtk-socinfo driver has a double put of the nvmem device used to
> read the socinfo data. While fixing it, I rewrote the read function to
> make better use of the device node and device relationship.
> 
> Patch 1 rewrites the cell read function in the mtk-socinfo so that no
> resource leaks happen, and device lookup is more efficient.
> 
> [...]

Applied, thanks!

[3/3] nvmem: mtk-efuse: Drop NVMEM device name
      commit: eadaa6f9aaf682b1840bf08a8320907de4e32d50

Best regards,
-- 
Srinivas Kandagatla <srinivas.kandagatla at linaro.org>



From jgg at ziepe.ca  Tue Feb 13 06:42:08 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 10:42:08 -0400
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
In-Reply-To: <20240213140900.GE28926@willie-the-truck>
References: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
 <20240213121257.GI765010@ziepe.ca>
 <20240213121934.GA28726@willie-the-truck>
 <20240213125303.GJ765010@ziepe.ca>
 <20240213125951.GB28844@willie-the-truck>
 <20240213134726.GK765010@ziepe.ca>
 <20240213140900.GE28926@willie-the-truck>
Message-ID: <20240213144208.GL765010@ziepe.ca>

On Tue, Feb 13, 2024 at 02:09:00PM +0000, Will Deacon wrote:
> Hey Jason,
> 
> On Tue, Feb 13, 2024 at 09:47:26AM -0400, Jason Gunthorpe wrote:
> > On Tue, Feb 13, 2024 at 12:59:52PM +0000, Will Deacon wrote:
> > > > The typical kernel standard is to fix bugs in patches and only reach
> > > > for a wholesale revert if the community is struggling with bug
> > > > fixing. Dmitry already tested removing that hunk, Robin explained the
> > > > issue, we understand the bug fix is to remove the
> > > > arm_smmu_init_domain_context() call. Nothing justifies a full scale
> > > > revert.
> > > 
> > > I can't say I'm aware of any consensus for how to handle this, to be
> > > completely honest with you. 
> > 
> > Well, I work in a lot of subsystems and this is a surprise to me and
> > not something I've seen before. Fix the bug, move forward. Reverts are
> > a cultural admission of failure. I use threats of a revert as a hammer
> > to encourage people to pay attention to the bugs. I hardly ever
> > actually revert things. What does reverting their code say to my
> > submitters???
> 
> Huh. I guess I'm lucky never to have worked in a environment where that
> is the case. In fact, my experience is quite the opposite: revert first
> so that things get back to a working state and the developer/submitter
> has some breathing room to rework the broken code. It's actually fairly
> blameless if you get it right and when you have a half-functional CI it's
> pretty much a necessity. Anyway, I digress...

Fascinating, I am glad we had this discussion because I was pretty put
off by this talk of revert in this and the other thread. Cultural
differences!

Thanks,
Jason


From abel.vesa at linaro.org  Tue Feb 13 06:41:55 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Tue, 13 Feb 2024 16:41:55 +0200
Subject: [PATCH RFC v2] spmi: pmic-arb: Add support for multiple buses
Message-ID: <20240213-spmi-multi-master-support-v2-1-b3b102326906@linaro.org>

The v7 HW supports currently 2 buses. So register each bus as a separate
spmi controller and adapt all ops to use the bus instead of the
arbitrator. Legacy mode is still supported as long as there is no child
node that represents a bus, instead all nodes are expected to be actual
slave devices.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
Changes in v2:
- Reworked it so that it registers a spmi controller for each bus
  rather than relying on the generic framework to pass on the bus
  (master) id.
- Link to v1: https://lore.kernel.org/r/20240207-spmi-multi-master-support-v1-0-ce57f301c7fd at linaro.org
---
 drivers/spmi/spmi-pmic-arb.c | 950 ++++++++++++++++++++++++++-----------------
 1 file changed, 585 insertions(+), 365 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 9ed1180fe31f..eced35b712b4 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -13,6 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spmi.h>
@@ -94,6 +96,8 @@ enum pmic_arb_channel {
 	PMIC_ARB_CHANNEL_OBS,
 };
 
+#define PMIC_ARB_MAX_BUSES		2
+
 /* Maximum number of support PMIC peripherals */
 #define PMIC_ARB_MAX_PERIPHS		512
 #define PMIC_ARB_MAX_PERIPHS_V7		1024
@@ -125,64 +129,77 @@ struct apid_data {
 	u8		irq_ee;
 };
 
+struct spmi_pmic_arb;
+
 /**
- * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ * struct spmi_pmic_arb_bus - SPMI PMIC Arbiter Bus object
  *
- * @rd_base:		on v1 "core", on v2 "observer" register base off DT.
- * @wr_base:		on v1 "core", on v2 "chnls"    register base off DT.
  * @intr:		address of the SPMI interrupt control registers.
  * @cnfg:		address of the PMIC Arbiter configuration registers.
- * @lock:		lock to synchronize accesses.
- * @channel:		execution environment channel to use for accesses.
- * @irq:		PMIC ARB interrupt.
- * @ee:			the current Execution Environment
- * @bus_instance:	on v7: 0 = primary SPMI bus, 1 = secondary SPMI bus
- * @min_apid:		minimum APID (used for bounding IRQ search)
- * @max_apid:		maximum APID
+ * @domain:		irq domain object for PMIC IRQ domain
+ * @bus_index:	on v7: 0 = primary SPMI bus, 1 = secondary SPMI bus
  * @base_apid:		on v7: minimum APID associated with the particular SPMI
  *			bus instance
  * @apid_count:		on v5 and v7: number of APIDs associated with the
  *			particular SPMI bus instance
  * @mapping_table:	in-memory copy of PPID -> APID mapping table.
- * @domain:		irq domain object for PMIC IRQ domain
- * @spmic:		SPMI controller object
- * @ver_ops:		version dependent operations.
  * @ppid_to_apid:	in-memory copy of PPID -> APID mapping table.
- * @last_apid:		Highest value APID in use
  * @apid_data:		Table of data for all APIDs
+ * @last_apid:		Highest value APID in use
+ * @irq:		PMIC ARB interrupt.
+ */
+struct spmi_pmic_arb_bus {
+	struct spmi_pmic_arb	*pmic_arb;
+	struct irq_domain	*domain;
+	void __iomem		*intr;
+	void __iomem		*cnfg;
+	struct spmi_controller	*spmic;
+	u32			bus_index;
+	u16			base_apid;
+	int			apid_count;
+	u32			*mapping_table;
+	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
+	u16			*ppid_to_apid;
+	u16			last_apid;
+	struct apid_data	*apid_data;
+	u16			min_apid;
+	u16			max_apid;
+	int			irq;
+	u8			id;
+};
+
+/**
+ * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ *
+ * @rd_base:		on v1 "core", on v2 "observer" register base off DT.
+ * @wr_base:		on v1 "core", on v2 "chnls"    register base off DT.
+ * @lock:		lock to synchronize accesses.
+ * @channel:		execution environment channel to use for accesses.
+ * @ee:			the current Execution Environment
+ * @min_apid:		minimum APID (used for bounding IRQ search)
+ * @max_apid:		maximum APID
+ * @ver_ops:		version dependent operations.
  * @max_periphs:	Number of elements in apid_data[]
  */
 struct spmi_pmic_arb {
 	void __iomem		*rd_base;
 	void __iomem		*wr_base;
-	void __iomem		*intr;
-	void __iomem		*cnfg;
 	void __iomem		*core;
 	resource_size_t		core_size;
 	raw_spinlock_t		lock;
 	u8			channel;
-	int			irq;
 	u8			ee;
-	u32			bus_instance;
-	u16			min_apid;
-	u16			max_apid;
-	u16			base_apid;
-	int			apid_count;
-	u32			*mapping_table;
-	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
-	struct irq_domain	*domain;
-	struct spmi_controller	*spmic;
 	const struct pmic_arb_ver_ops *ver_ops;
-	u16			*ppid_to_apid;
-	u16			last_apid;
-	struct apid_data	*apid_data;
 	int			max_periphs;
+	struct spmi_pmic_arb_bus buses[PMIC_ARB_MAX_BUSES];
+	int			buses_available;
 };
 
 /**
  * struct pmic_arb_ver_ops - version dependent functionality.
  *
  * @ver_str:		version string.
+ * @init_apid:		finds the apid base and count
  * @ppid_to_apid:	finds the apid for a given ppid.
  * @non_data_cmd:	on v1 issues an spmi non-data command.
  *			on v2 no HW support, returns -EOPNOTSUPP.
@@ -202,20 +219,22 @@ struct spmi_pmic_arb {
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
-	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
+	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
+	int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index);
+	int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
-	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type);
+	int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+		      enum pmic_arb_channel ch_type);
 	u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
 	int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
 	/* Interrupts controller functionality (offset of PIC registers) */
-	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb *pmic_arb, u8 m,
+	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb_bus *bus, u8 m,
 					  u16 n);
-	void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*acc_enable)(struct spmi_pmic_arb_bus *bus, u16 n);
+	void __iomem *(*irq_status)(struct spmi_pmic_arb_bus *bus, u16 n);
+	void __iomem *(*irq_clear)(struct spmi_pmic_arb_bus *bus, u16 n);
 	u32 (*apid_map_offset)(u16 n);
-	void __iomem *(*apid_owner)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*apid_owner)(struct spmi_pmic_arb_bus *bus, u16 n);
 };
 
 static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -263,13 +282,14 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 				  void __iomem *base, u8 sid, u16 addr,
 				  enum pmic_arb_channel ch_type)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 status = 0;
 	u32 timeout = PMIC_ARB_TIMEOUT_US;
 	u32 offset;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type);
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr, ch_type);
 	if (rc < 0)
 		return rc;
 
@@ -281,21 +301,21 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 
 		if (status & PMIC_ARB_STATUS_DONE) {
 			if (status & PMIC_ARB_STATUS_DENIED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction denied (%#x)\n",
+					__func__, bus->id, sid, addr, status);
 				return -EPERM;
 			}
 
 			if (status & PMIC_ARB_STATUS_FAILURE) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction failed (%#x) reg: 0x%x\n",
+					__func__, bus->id, sid, addr, status, offset);
 				WARN_ON(1);
 				return -EIO;
 			}
 
 			if (status & PMIC_ARB_STATUS_DROPPED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction dropped (%#x)\n",
+					__func__, bus->id, sid, addr, status);
 				return -EIO;
 			}
 
@@ -304,8 +324,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 		udelay(1);
 	}
 
-	dev_err(&ctrl->dev, "%s: %#x %#x: timeout, status %#x\n",
-		__func__, sid, addr, status);
+	dev_err(&ctrl->dev, "%s: %#x %#x %#x: timeout, status %#x\n",
+		__func__, bus->id, sid, addr, status);
 	return -ETIMEDOUT;
 }
 
@@ -313,12 +333,13 @@ static int
 pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[0];
 	unsigned long flags;
 	u32 cmd;
 	int rc;
 	u32 offset;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW);
+	rc = pmic_arb->ver_ops->offset(bus, sid, 0, PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
@@ -354,20 +375,21 @@ static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
 	return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid);
 }
 
-static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 sid,
+static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb_bus *bus, u8 opc, u8 sid,
 				 u16 addr, size_t len, u32 *cmd, u32 *offset)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr,
 				       PMIC_ARB_CHANNEL_OBS);
 	if (rc < 0)
 		return rc;
 
 	*offset = rc;
 	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-		dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+		dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
 			PMIC_ARB_MAX_TRANS_BYTES, len);
 		return  -EINVAL;
 	}
@@ -391,7 +413,8 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      u32 offset, u8 sid, u16 addr, u8 *buf,
 				      size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
@@ -413,12 +436,13 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 			     u16 addr, u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned long flags;
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_read_cmd(bus, opc, sid, addr, len, &cmd,
 				   &offset);
 	if (rc)
 		return rc;
@@ -430,21 +454,22 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 	return rc;
 }
 
-static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc,
+static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb_bus *bus, u8 opc,
 				  u8 sid, u16 addr, size_t len, u32 *cmd,
 				  u32 *offset)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr,
 					PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
 	*offset = rc;
 	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-		dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+		dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
 			PMIC_ARB_MAX_TRANS_BYTES, len);
 		return  -EINVAL;
 	}
@@ -470,7 +495,8 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      u32 offset, u8 sid, u16 addr,
 				      const u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 
 	/* Write data to FIFOs */
@@ -489,12 +515,13 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 			      u16 addr, const u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned long flags;
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_write_cmd(bus, opc, sid, addr, len, &cmd,
 				    &offset);
 	if (rc)
 		return rc;
@@ -510,18 +537,19 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr,
 				 const u8 *buf, const u8 *mask, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 read_cmd, read_offset, write_cmd, write_offset;
 	u8 temp[PMIC_ARB_MAX_TRANS_BYTES];
 	unsigned long flags;
 	int rc, i;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, SPMI_CMD_EXT_READL, sid, addr, len,
+	rc = pmic_arb_fmt_read_cmd(bus, SPMI_CMD_EXT_READL, sid, addr, len,
 				   &read_cmd, &read_offset);
 	if (rc)
 		return rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, SPMI_CMD_EXT_WRITEL, sid, addr,
+	rc = pmic_arb_fmt_write_cmd(bus, SPMI_CMD_EXT_WRITEL, sid, addr,
 				    len, &write_cmd, &write_offset);
 	if (rc)
 		return rc;
@@ -564,25 +592,25 @@ struct spmi_pmic_arb_qpnpint_type {
 static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
 			       size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
+	if (pmic_arb_write_cmd(bus->spmic, SPMI_CMD_EXT_WRITEL, sid,
 			       (per << 8) + reg, buf, len))
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
 }
 
 static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, sid,
+	if (pmic_arb_read_cmd(bus->spmic, SPMI_CMD_EXT_READL, sid,
 			      (per << 8) + reg, buf, len))
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
 }
 
@@ -590,47 +618,49 @@ static int qpnpint_spmi_masked_write(struct irq_data *d, u8 reg,
 				     const void *buf, const void *mask,
 				     size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 	int rc;
 
-	rc = pmic_arb_masked_write(pmic_arb->spmic, sid, (per << 8) + reg, buf,
+	rc = pmic_arb_masked_write(bus->spmic, sid, (per << 8) + reg, buf,
 				   mask, len);
 	if (rc)
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
 				    d->irq, rc);
 	return rc;
 }
 
-static void cleanup_irq(struct spmi_pmic_arb *pmic_arb, u16 apid, int id)
+static void cleanup_irq(struct spmi_pmic_arb_bus *bus, u16 apid, int id)
 {
-	u16 ppid = pmic_arb->apid_data[apid].ppid;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	u16 ppid = bus->apid_data[apid].ppid;
 	u8 sid = ppid >> 8;
 	u8 per = ppid & 0xFF;
 	u8 irq_mask = BIT(id);
 
-	dev_err_ratelimited(&pmic_arb->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
-			__func__, apid, sid, per, id);
-	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	dev_err_ratelimited(&bus->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
+			    __func__, apid, sid, per, id);
+	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(bus, apid));
 }
 
-static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
+static int periph_interrupt(struct spmi_pmic_arb_bus *bus, u16 apid)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned int irq;
 	u32 status, id;
 	int handled = 0;
-	u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF;
-	u8 per = pmic_arb->apid_data[apid].ppid & 0xFF;
+	u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF;
+	u8 per = bus->apid_data[apid].ppid & 0xFF;
 
-	status = readl_relaxed(pmic_arb->ver_ops->irq_status(pmic_arb, apid));
+	status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid));
 	while (status) {
 		id = ffs(status) - 1;
 		status &= ~BIT(id);
-		irq = irq_find_mapping(pmic_arb->domain,
-					spec_to_hwirq(sid, per, id, apid));
+		irq = irq_find_mapping(bus->domain,
+				       spec_to_hwirq(sid, per, id, apid));
 		if (irq == 0) {
-			cleanup_irq(pmic_arb, apid, id);
+			cleanup_irq(bus, apid, id);
 			continue;
 		}
 		generic_handle_irq(irq);
@@ -642,16 +672,17 @@ static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
 
 static void pmic_arb_chained_irq(struct irq_desc *desc)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb_bus *bus = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int first = pmic_arb->min_apid;
-	int last = pmic_arb->max_apid;
+	int first = bus->min_apid;
+	int last = bus->max_apid;
 	/*
 	 * acc_offset will be non-zero for the secondary SPMI bus instance on
 	 * v7 controllers.
 	 */
-	int acc_offset = pmic_arb->base_apid >> 5;
+	int acc_offset = bus->base_apid >> 5;
 	u8 ee = pmic_arb->ee;
 	u32 status, enable, handled = 0;
 	int i, id, apid;
@@ -662,7 +693,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	chained_irq_enter(chip, desc);
 
 	for (i = first >> 5; i <= last >> 5; ++i) {
-		status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i - acc_offset));
+		status = readl_relaxed(ver_ops->owner_acc_status(bus, ee, i - acc_offset));
 		if (status)
 			acc_valid = true;
 
@@ -676,9 +707,9 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 				continue;
 			}
 			enable = readl_relaxed(
-					ver_ops->acc_enable(pmic_arb, apid));
+					ver_ops->acc_enable(bus, apid));
 			if (enable & SPMI_PIC_ACC_ENABLE_BIT)
-				if (periph_interrupt(pmic_arb, apid) != 0)
+				if (periph_interrupt(bus, apid) != 0)
 					handled++;
 		}
 	}
@@ -687,19 +718,19 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	if (!acc_valid) {
 		for (i = first; i <= last; i++) {
 			/* skip if APPS is not irq owner */
-			if (pmic_arb->apid_data[i].irq_ee != pmic_arb->ee)
+			if (bus->apid_data[i].irq_ee != pmic_arb->ee)
 				continue;
 
 			irq_status = readl_relaxed(
-					     ver_ops->irq_status(pmic_arb, i));
+					     ver_ops->irq_status(bus, i));
 			if (irq_status) {
 				enable = readl_relaxed(
-					     ver_ops->acc_enable(pmic_arb, i));
+					     ver_ops->acc_enable(bus, i));
 				if (enable & SPMI_PIC_ACC_ENABLE_BIT) {
-					dev_dbg(&pmic_arb->spmic->dev,
+					dev_dbg(&bus->spmic->dev,
 						"Dispatching IRQ for apid=%d status=%x\n",
 						i, irq_status);
-					if (periph_interrupt(pmic_arb, i) != 0)
+					if (periph_interrupt(bus, i) != 0)
 						handled++;
 				}
 			}
@@ -714,12 +745,13 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 
 static void qpnpint_irq_ack(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 data;
 
-	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(bus, apid));
 
 	data = BIT(irq);
 	qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
@@ -735,14 +767,15 @@ static void qpnpint_irq_mask(struct irq_data *d)
 
 static void qpnpint_irq_unmask(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 buf[2];
 
 	writel_relaxed(SPMI_PIC_ACC_ENABLE_BIT,
-			ver_ops->acc_enable(pmic_arb, apid));
+			ver_ops->acc_enable(bus, apid));
 
 	qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1);
 	if (!(buf[0] & BIT(irq))) {
@@ -799,9 +832,9 @@ static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
 
 static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 
-	return irq_set_irq_wake(pmic_arb->irq, on);
+	return irq_set_irq_wake(bus->irq, on);
 }
 
 static int qpnpint_get_irqchip_state(struct irq_data *d,
@@ -823,17 +856,18 @@ static int qpnpint_get_irqchip_state(struct irq_data *d,
 static int qpnpint_irq_domain_activate(struct irq_domain *domain,
 				       struct irq_data *d, bool reserve)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 periph = hwirq_to_per(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u16 sid = hwirq_to_sid(d->hwirq);
 	u16 irq = hwirq_to_irq(d->hwirq);
 	u8 buf;
 
-	if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
+	if (bus->apid_data[apid].irq_ee != pmic_arb->ee) {
+		dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
 			sid, periph, irq, pmic_arb->ee,
-			pmic_arb->apid_data[apid].irq_ee);
+			bus->apid_data[apid].irq_ee);
 		return -ENODEV;
 	}
 
@@ -860,15 +894,16 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 					unsigned long *out_hwirq,
 					unsigned int *out_type)
 {
-	struct spmi_pmic_arb *pmic_arb = d->host_data;
+	struct spmi_pmic_arb_bus *bus = d->host_data;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 *intspec = fwspec->param;
 	u16 apid, ppid;
 	int rc;
 
-	dev_dbg(&pmic_arb->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
+	dev_dbg(&bus->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
 		intspec[0], intspec[1], intspec[2]);
 
-	if (irq_domain_get_of_node(d) != pmic_arb->spmic->dev.of_node)
+	if (irq_domain_get_of_node(d) != bus->spmic->dev.of_node)
 		return -EINVAL;
 	if (fwspec->param_count != 4)
 		return -EINVAL;
@@ -876,37 +911,38 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 		return -EINVAL;
 
 	ppid = intspec[0] << 8 | intspec[1];
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
 	if (rc < 0) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
-		intspec[0], intspec[1], intspec[2], rc);
+		dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
+			intspec[0], intspec[1], intspec[2], rc);
 		return rc;
 	}
 
 	apid = rc;
 	/* Keep track of {max,min}_apid for bounding search during interrupt */
-	if (apid > pmic_arb->max_apid)
-		pmic_arb->max_apid = apid;
-	if (apid < pmic_arb->min_apid)
-		pmic_arb->min_apid = apid;
+	if (apid > bus->max_apid)
+		bus->max_apid = apid;
+	if (apid < bus->min_apid)
+		bus->min_apid = apid;
 
 	*out_hwirq = spec_to_hwirq(intspec[0], intspec[1], intspec[2], apid);
 	*out_type  = intspec[3] & IRQ_TYPE_SENSE_MASK;
 
-	dev_dbg(&pmic_arb->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
+	dev_dbg(&bus->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
 
 	return 0;
 }
 
 static struct lock_class_key qpnpint_irq_lock_class, qpnpint_irq_request_class;
 
-static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb,
+static void qpnpint_irq_domain_map(struct spmi_pmic_arb_bus *bus,
 				   struct irq_domain *domain, unsigned int virq,
 				   irq_hw_number_t hwirq, unsigned int type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	irq_flow_handler_t handler;
 
-	dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
+	dev_dbg(&bus->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
 		virq, hwirq, type);
 
 	if (type & IRQ_TYPE_EDGE_BOTH)
@@ -925,7 +961,7 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 				    unsigned int virq, unsigned int nr_irqs,
 				    void *data)
 {
-	struct spmi_pmic_arb *pmic_arb = domain->host_data;
+	struct spmi_pmic_arb_bus *bus = domain->host_data;
 	struct irq_fwspec *fwspec = data;
 	irq_hw_number_t hwirq;
 	unsigned int type;
@@ -936,29 +972,75 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 		return ret;
 
 	for (i = 0; i < nr_irqs; i++)
-		qpnpint_irq_domain_map(pmic_arb, domain, virq + i, hwirq + i,
+		qpnpint_irq_domain_map(bus, domain, virq + i, hwirq + i,
 				       type);
 
 	return 0;
 }
 
-static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb_bus *bus)
 {
-	u32 *mapping_table = pmic_arb->mapping_table;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+
+	/*
+	 * Initialize max_apid/min_apid to the opposite bounds, during
+	 * the irq domain translation, we are sure to update these
+	 */
+	bus->max_apid = 0;
+	bus->min_apid = pmic_arb->max_periphs - 1;
+
+	return 0;
+}
+
+static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->wr_base = core;
+	pmic_arb->rd_base = core;
+
+	return 0;
+}
+
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus, int index)
+{
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	u32 *mapping_table;
+
+	if (index) {
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs,
+				     sizeof(*mapping_table), GFP_KERNEL);
+	if (!mapping_table)
+		return -ENOMEM;
+
+	bus->mapping_table = mapping_table;
+
+	return pmic_arb_init_apid_min_max(bus);
+}
+
+static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb_bus *bus, u16 ppid)
+{
+	u32 *mapping_table = bus->mapping_table;
 	int index = 0, i;
 	u16 apid_valid;
 	u16 apid;
 	u32 data;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = bus->ppid_to_apid[ppid];
 	if (apid_valid & PMIC_ARB_APID_VALID) {
 		apid = apid_valid & ~PMIC_ARB_APID_VALID;
 		return apid;
 	}
 
 	for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
-		if (!test_and_set_bit(index, pmic_arb->mapping_table_valid))
-			mapping_table[index] = readl_relaxed(pmic_arb->cnfg +
+		if (!test_and_set_bit(index, bus->mapping_table_valid))
+			mapping_table[index] = readl_relaxed(bus->cnfg +
 						SPMI_MAPPING_TABLE_REG(index));
 
 		data = mapping_table[index];
@@ -968,9 +1050,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				bus->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				bus->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		} else {
@@ -978,9 +1060,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				bus->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				bus->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		}
@@ -990,24 +1072,26 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 }
 
 /* v1 offset per ee */
-static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v1(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return 0x800 + 0x80 * pmic_arb->channel;
 }
 
-static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static u16 pmic_arb_find_apid(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid];
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	struct apid_data *apidd = &bus->apid_data[bus->last_apid];
 	u32 regval, offset;
 	u16 id, apid;
 
-	for (apid = pmic_arb->last_apid; ; apid++, apidd++) {
+	for (apid = bus->last_apid; ; apid++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(apid);
 		if (offset >= pmic_arb->core_size)
 			break;
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus,
 								     apid));
 		apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 		apidd->write_ee = apidd->irq_ee;
@@ -1017,33 +1101,62 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 			continue;
 
 		id = (regval >> 8) & PMIC_ARB_PPID_MASK;
-		pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
+		bus->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
 		apidd->ppid = id;
 		if (id == ppid) {
 			apid |= PMIC_ARB_APID_VALID;
 			break;
 		}
 	}
-	pmic_arb->last_apid = apid & ~PMIC_ARB_APID_VALID;
+	bus->last_apid = apid & ~PMIC_ARB_APID_VALID;
 
 	return apid;
 }
 
-static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+
+	pmic_arb->core = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					   "obsrvr");
+	pmic_arb->rd_base = devm_ioremap(dev, res->start,
+					 resource_size(res));
+	if (IS_ERR(pmic_arb->rd_base))
+		return PTR_ERR(pmic_arb->rd_base);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					   "chnls");
+	pmic_arb->wr_base = devm_ioremap(dev, res->start,
+					 resource_size(res));
+	if (IS_ERR(pmic_arb->wr_base))
+		return PTR_ERR(pmic_arb->wr_base);
+
+	return 0;
+}
+
+static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
 	u16 apid_valid;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = bus->ppid_to_apid[ppid];
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
-		apid_valid = pmic_arb_find_apid(pmic_arb, ppid);
+		apid_valid = pmic_arb_find_apid(bus, ppid);
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
 	return apid_valid & ~PMIC_ARB_APID_VALID;
 }
 
-static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	struct apid_data *apidd;
 	struct apid_data *prev_apidd;
 	u16 i, apid, ppid, apid_max;
@@ -1065,9 +1178,9 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 	 * where N = number of APIDs supported by the primary bus and
 	 *       M = number of APIDs supported by the secondary bus
 	 */
-	apidd = &pmic_arb->apid_data[pmic_arb->base_apid];
-	apid_max = pmic_arb->base_apid + pmic_arb->apid_count;
-	for (i = pmic_arb->base_apid; i < apid_max; i++, apidd++) {
+	apidd = &bus->apid_data[bus->base_apid];
+	apid_max = bus->base_apid + bus->apid_count;
+	for (i = bus->base_apid; i < apid_max; i++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(i);
 		if (offset >= pmic_arb->core_size)
 			break;
@@ -1078,19 +1191,18 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		ppid = (regval >> 8) & PMIC_ARB_PPID_MASK;
 		is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval);
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
-								     i));
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i));
 		apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 
 		apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE;
 
-		valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
-		apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
-		prev_apidd = &pmic_arb->apid_data[apid];
+		valid = bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
+		apid = bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+		prev_apidd = &bus->apid_data[apid];
 
 		if (!valid || apidd->write_ee == pmic_arb->ee) {
 			/* First PPID mapping or one for this EE */
-			pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+			bus->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
 		} else if (valid && is_irq_ee &&
 			   prev_apidd->write_ee == pmic_arb->ee) {
 			/*
@@ -1101,42 +1213,43 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		}
 
 		apidd->ppid = ppid;
-		pmic_arb->last_apid = i;
+		bus->last_apid = i;
 	}
 
 	/* Dump the mapping table for debug purposes. */
-	dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
+	dev_dbg(&bus->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
 	for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) {
-		apid = pmic_arb->ppid_to_apid[ppid];
+		apid = bus->ppid_to_apid[ppid];
 		if (apid & PMIC_ARB_APID_VALID) {
 			apid &= ~PMIC_ARB_APID_VALID;
-			apidd = &pmic_arb->apid_data[apid];
-			dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n",
-			      ppid, apid, apidd->write_ee, apidd->irq_ee);
+			apidd = &bus->apid_data[apid];
+			dev_dbg(&bus->spmic->dev, "%#03X %3u %2u %2u\n",
+				ppid, apid, apidd->write_ee, apidd->irq_ee);
 		}
 	}
 
 	return 0;
 }
 
-static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
+	if (!(bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
-	return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+	return bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
 }
 
 /* v2 offset per ppid and per ee */
-static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	u16 ppid;
 	int rc;
 
 	ppid = sid << 8 | ((addr >> 8) & 0xFF);
-	rc = pmic_arb_ppid_to_apid_v2(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v2(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1144,19 +1257,55 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0x1000 * pmic_arb->ee + 0x8000 * apid;
 }
 
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus, int index)
+{
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	int ret;
+
+	if (index) {
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	bus->base_apid = 0;
+	bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+					   PMIC_ARB_FEATURES_PERIPH_MASK;
+
+	if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+		dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+			bus->base_apid + bus->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_min_max(bus);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(bus);
+	if (ret) {
+		dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v5 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v5(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v5(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1166,8 +1315,8 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
-			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+		if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+			dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
 		}
@@ -1178,19 +1327,75 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return offset;
 }
 
+static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+	int ret = pmic_arb_get_core_resources_v2(pdev, core);
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+
+	return ret;
+}
+
+/*
+ * Only v7 supports 2 bus buses. Each bus will get a different apid count,
+ * read from different registers.
+ */
+static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index)
+{
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	int ret;
+
+	if (index == 0) {
+		bus->base_apid = 0;
+		bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else if (index == 1) {
+		bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						  PMIC_ARB_FEATURES_PERIPH_MASK;
+		bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else {
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
+			bus->id);
+		return -EINVAL;
+	}
+
+	if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+		dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+			bus->base_apid + bus->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_min_max(bus);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(bus);
+	if (ret) {
+		dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v7 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v7(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1200,8 +1405,8 @@ static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x8000 * pmic_arb->ee + 0x20 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
-			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+		if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+			dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
 		}
@@ -1223,104 +1428,110 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x20 * m + 0x4 * n;
+	return bus->intr + 0x20 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x100000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x200000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x10000 * m + 0x4 * n;
+	return bus->intr + 0x10000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x200 + 0x4 * n;
+	return bus->intr + 0x200 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * n;
+	return bus->intr + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x600 + 0x4 * n;
+	return bus->intr + 0x600 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x4 + 0x1000 * n;
+	return bus->intr + 0x4 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0xA00 + 0x4 * n;
+	return bus->intr + 0xA00 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x8 + 0x1000 * n;
+	return bus->intr + 0x8 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x1000 * n;
 }
 
@@ -1340,9 +1551,9 @@ static u32 pmic_arb_apid_map_offset_v7(u16 n)
 }
 
 static void __iomem *
-pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->cnfg + 0x700 + 0x4 * n;
+	return bus->cnfg + 0x700 + 0x4 * n;
 }
 
 /*
@@ -1351,13 +1562,15 @@ pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
  * 0.
  */
 static void __iomem *
-pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->cnfg + 0x4 * (n - pmic_arb->base_apid);
+	return  bus->cnfg + 0x4 * (n - bus->base_apid);
 }
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
+	.get_core_resources	= pmic_arb_get_core_resources_v1,
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v1,
 	.offset			= pmic_arb_offset_v1,
@@ -1372,6 +1585,8 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.ver_str		= "v2",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1386,6 +1601,8 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.ver_str		= "v3",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1400,6 +1617,8 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.ver_str		= "v5",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
+	.init_apid		= pmic_arb_init_apid_v5,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v5,
@@ -1414,6 +1633,8 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.ver_str		= "v7",
+	.get_core_resources	= pmic_arb_get_core_resources_v7,
+	.init_apid		= pmic_arb_init_apid_v7,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v7,
@@ -1433,22 +1654,153 @@ static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
 	.translate = qpnpint_irq_domain_translate,
 };
 
+static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
+				  struct device_node *node,
+				  struct spmi_pmic_arb *pmic_arb)
+{
+	int bus_index = pmic_arb->buses_available;
+	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[bus_index];
+	struct device *dev = &pdev->dev;
+	struct spmi_controller *ctrl;
+	void __iomem *intr;
+	void __iomem *cnfg;
+	int index, ret;
+	u32 irq;
+
+	ctrl = devm_spmi_controller_alloc(dev, sizeof(*ctrl));
+	if (IS_ERR(ctrl))
+		return PTR_ERR(ctrl);
+
+	ctrl->cmd = pmic_arb_cmd;
+	ctrl->read_cmd = pmic_arb_read_cmd;
+	ctrl->write_cmd = pmic_arb_write_cmd;
+
+	bus = spmi_controller_get_drvdata(ctrl);
+	bus->spmic = ctrl;
+
+	bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID,
+					 sizeof(*bus->ppid_to_apid),
+					 GFP_KERNEL);
+	if (!bus->ppid_to_apid)
+		return -ENOMEM;
+
+	bus->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs,
+				      sizeof(*bus->apid_data),
+				      GFP_KERNEL);
+	if (!bus->apid_data)
+		return -ENOMEM;
+
+	/* Optional property for v7: */
+	of_property_read_u32(node, "qcom,bus-id", &bus_index);
+	if (bus_index != pmic_arb->buses_available) {
+		dev_err(dev, "wrong bus-id value");
+		return -EINVAL;
+	}
+
+	index = of_property_match_string(node, "reg-names", "cnfg");
+	if (index < 0) {
+		dev_err(dev, "cnfg reg region missing");
+		return -EINVAL;
+	}
+
+	cnfg = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(cnfg))
+		return PTR_ERR(cnfg);
+
+	index = of_property_match_string(node, "reg-names", "intr");
+	if (index < 0) {
+		dev_err(dev, "intr reg region missing");
+		return -EINVAL;
+	}
+
+	intr = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(intr))
+		return PTR_ERR(intr);
+
+	irq = of_irq_get_byname(node, "periph_irq");
+	if (irq < 0)
+		return irq;
+
+	bus->pmic_arb = pmic_arb;
+	bus->intr = intr;
+	bus->cnfg = cnfg;
+	bus->irq = irq;
+	bus->id = bus_index;
+
+	ret = pmic_arb->ver_ops->init_apid(bus, index);
+	if (ret)
+		return ret;
+
+	dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index);
+
+	bus->domain = irq_domain_add_tree(dev->of_node,
+					  &pmic_arb_irq_domain_ops, bus);
+	if (!bus->domain) {
+		dev_err(&pdev->dev, "unable to create irq_domain\n");
+		return -ENOMEM;
+	}
+
+	irq_set_chained_handler_and_data(bus->irq,
+					 pmic_arb_chained_irq, bus);
+
+	bus->spmic->dev.of_node = node;
+	dev_set_name(&bus->spmic->dev, "spmi-%d", bus_index);
+
+	ret = devm_spmi_controller_add(dev, bus->spmic);
+	if (ret)
+		return ret;
+
+	pmic_arb->buses_available++;
+
+	return 0;
+}
+
+static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb,
+					struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct device_node *child;
+	int ret;
+
+	for_each_available_child_of_node(node, child)
+		if (of_node_name_eq(child, "bus")) {
+			ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb);
+			if (ret)
+				return ret;
+		}
+
+	if (!pmic_arb->buses_available)
+		ret = spmi_pmic_arb_bus_init(pdev, node, pmic_arb);
+
+	return ret;
+}
+
+static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb)
+{
+	int i;
+
+	for (i = 0; i < pmic_arb->buses_available; i++) {
+		struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[i];
+
+		irq_set_chained_handler_and_data(bus->irq,
+						 NULL, NULL);
+		irq_domain_remove(bus->domain);
+	}
+}
+
 static int spmi_pmic_arb_probe(struct platform_device *pdev)
 {
 	struct spmi_pmic_arb *pmic_arb;
-	struct spmi_controller *ctrl;
+	struct device *dev = &pdev->dev;
 	struct resource *res;
 	void __iomem *core;
-	u32 *mapping_table;
 	u32 channel, ee, hw_ver;
 	int err;
 
-	ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*pmic_arb));
-	if (IS_ERR(ctrl))
-		return PTR_ERR(ctrl);
-
-	pmic_arb = spmi_controller_get_drvdata(ctrl);
-	pmic_arb->spmic = ctrl;
+	pmic_arb = devm_kzalloc(dev, sizeof(*pmic_arb), GFP_KERNEL);
+	if (!pmic_arb)
+		return -ENOMEM;
 
 	/*
 	 * Please don't replace this with devm_platform_ioremap_resource() or
@@ -1461,118 +1813,34 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	 * which does not result in a devm_request_mem_region() call.
 	 */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
-	core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
+	core = devm_ioremap(dev, res->start, resource_size(res));
 	if (IS_ERR(core))
 		return PTR_ERR(core);
 
 	pmic_arb->core_size = resource_size(res);
 
-	pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
-					      sizeof(*pmic_arb->ppid_to_apid),
-					      GFP_KERNEL);
-	if (!pmic_arb->ppid_to_apid)
-		return -ENOMEM;
+	platform_set_drvdata(pdev, pmic_arb);
+	raw_spin_lock_init(&pmic_arb->lock);
 
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
-
-	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
+	if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
 		pmic_arb->ver_ops = &pmic_arb_v1;
-		pmic_arb->wr_base = core;
-		pmic_arb->rd_base = core;
-	} else {
-		pmic_arb->core = core;
-
-		if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v2;
-		else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v3;
-		else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v5;
-		else
-			pmic_arb->ver_ops = &pmic_arb_v7;
-
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   "obsrvr");
-		pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start,
-						 resource_size(res));
-		if (IS_ERR(pmic_arb->rd_base))
-			return PTR_ERR(pmic_arb->rd_base);
-
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   "chnls");
-		pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start,
-						 resource_size(res));
-		if (IS_ERR(pmic_arb->wr_base))
-			return PTR_ERR(pmic_arb->wr_base);
-	}
-
-	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
-
-	if (hw_ver >= PMIC_ARB_VERSION_V7_MIN) {
-		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
-		/* Optional property for v7: */
-		of_property_read_u32(pdev->dev.of_node, "qcom,bus-id",
-					&pmic_arb->bus_instance);
-		if (pmic_arb->bus_instance > 1) {
-			dev_err(&pdev->dev, "invalid bus instance (%u) specified\n",
-				pmic_arb->bus_instance);
-			return -EINVAL;
-		}
-
-		if (pmic_arb->bus_instance == 0) {
-			pmic_arb->base_apid = 0;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		} else {
-			pmic_arb->base_apid =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES1) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		}
-
-		if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->base_apid + pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	} else if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		pmic_arb->base_apid = 0;
-		pmic_arb->apid_count = readl_relaxed(core + PMIC_ARB_FEATURES) &
-					PMIC_ARB_FEATURES_PERIPH_MASK;
-
-		if (pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	}
+	else if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v2;
+	else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v3;
+	else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v5;
+	else
+		pmic_arb->ver_ops = &pmic_arb_v7;
 
-	pmic_arb->apid_data = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					   sizeof(*pmic_arb->apid_data),
-					   GFP_KERNEL);
-	if (!pmic_arb->apid_data)
-		return -ENOMEM;
+	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
+	if (err)
+		return err;
 
-	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
+	dev_info(&pdev->dev, "PMIC arbiter version %s (0x%x)\n",
 		 pmic_arb->ver_ops->ver_str, hw_ver);
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
-	pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->intr))
-		return PTR_ERR(pmic_arb->intr);
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
-	pmic_arb->cnfg = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->cnfg))
-		return PTR_ERR(pmic_arb->cnfg);
-
-	pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq");
-	if (pmic_arb->irq < 0)
-		return pmic_arb->irq;
-
 	err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
 	if (err) {
 		dev_err(&pdev->dev, "channel unspecified.\n");
@@ -1597,64 +1865,16 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "invalid EE (%u) specified\n", ee);
 		return -EINVAL;
 	}
-
 	pmic_arb->ee = ee;
-	mapping_table = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					sizeof(*mapping_table), GFP_KERNEL);
-	if (!mapping_table)
-		return -ENOMEM;
-
-	pmic_arb->mapping_table = mapping_table;
-	/* Initialize max_apid/min_apid to the opposite bounds, during
-	 * the irq domain translation, we are sure to update these */
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
-
-	platform_set_drvdata(pdev, ctrl);
-	raw_spin_lock_init(&pmic_arb->lock);
-
-	ctrl->cmd = pmic_arb_cmd;
-	ctrl->read_cmd = pmic_arb_read_cmd;
-	ctrl->write_cmd = pmic_arb_write_cmd;
-
-	if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		err = pmic_arb_read_apid_map_v5(pmic_arb);
-		if (err) {
-			dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n",
-				err);
-			return err;
-		}
-	}
-
-	dev_dbg(&pdev->dev, "adding irq domain\n");
-	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
-					 &pmic_arb_irq_domain_ops, pmic_arb);
-	if (!pmic_arb->domain) {
-		dev_err(&pdev->dev, "unable to create irq_domain\n");
-		return -ENOMEM;
-	}
-
-	irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq,
-					pmic_arb);
-	err = spmi_controller_add(ctrl);
-	if (err)
-		goto err_domain_remove;
 
-	return 0;
-
-err_domain_remove:
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
-	return err;
+	return spmi_pmic_arb_register_buses(pmic_arb, pdev);
 }
 
 static void spmi_pmic_arb_remove(struct platform_device *pdev)
 {
-	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
-	spmi_controller_remove(ctrl);
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	spmi_pmic_arb_deregister_buses(pmic_arb);
 }
 
 static const struct of_device_id spmi_pmic_arb_match_table[] = {

---
base-commit: 445a555e0623387fa9b94e68e61681717e70200a
change-id: 20240207-spmi-multi-master-support-832a704b779b

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>



From ardb at kernel.org  Tue Feb 13 06:42:19 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 13 Feb 2024 15:42:19 +0100
Subject: [PATCH] ARM: iwmmxt: Remove support for PJ4/PJ4B cores
In-Reply-To: <970a39e9-913f-43c9-8f0d-189e0532401d@app.fastmail.com>
References: <20240209110901.4032939-2-ardb+git@google.com> <0bc7c97c-6549-4ae1-9787-4702e7ab737e@app.fastmail.com>
 <Zchwu2OqHLvEIgln@xhacker> <970a39e9-913f-43c9-8f0d-189e0532401d@app.fastmail.com>
Message-ID: <CAMj1kXEvCSPgwfa3oE5bnaaW7v_6ZQj=ceRaO2EOkaU_8dyV9w@mail.gmail.com>

On Sun, 11 Feb 2024 at 11:22, Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Sun, Feb 11, 2024, at 08:01, Jisheng Zhang wrote:
> > On Fri, Feb 09, 2024 at 03:27:02PM +0100, Arnd Bergmann wrote:
> >>
> >> Maybe add a bit about which cores are actually affected by this:
> >>
> >> The PJ4 cores are used in four platforms: armada 370/xp, dove
> >> (cubox, d2plug), mmp2 (xo-1.75) and berlin (chromecast 1).
> >
> > Per berlin2cd.dtsi, chromecast is powered by CA9 ;)
>
> Right, I confused it with the one in the Google TV, had
> not realized these were actually different variants of that
> chip.
>

Thanks all. I'll respin and resend.


From krzysztof.kozlowski at linaro.org  Tue Feb 13 06:46:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 13 Feb 2024 15:46:26 +0100
Subject: [PATCH] arm64: dts: mediatek: replace underscores in node names
Message-ID: <20240213144626.341463-1-krzysztof.kozlowski@linaro.org>

Underscores should not be used in node names (dtc with W=2 warns about
them), so replace them with hyphens.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi              |  2 +-
 arch/arm64/boot/dts/mediatek/mt6797.dtsi               |  8 ++++----
 .../dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso     |  2 +-
 arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts  |  2 +-
 arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi           |  2 +-
 arch/arm64/boot/dts/mediatek/mt8173.dtsi               | 10 +++++-----
 arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts        |  2 +-
 arch/arm64/boot/dts/mediatek/mt8183.dtsi               |  2 +-
 8 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index ed1a9d319415..6d218caa198c 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -261,7 +261,7 @@ pericfg: syscon at 10003000 {
 		#clock-cells = <1>;
 	};
 
-	syscfg_pctl_a: syscfg_pctl_a at 10005000 {
+	syscfg_pctl_a: syscon at 10005000 {
 		compatible = "mediatek,mt2712-pctl-a-syscfg", "syscon";
 		reg = <0 0x10005000 0 0x1000>;
 	};
diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
index c3677d77e0a4..0e9d11b4585b 100644
--- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
@@ -117,7 +117,7 @@ topckgen: topckgen at 10000000 {
 		#clock-cells = <1>;
 	};
 
-	infrasys: infracfg_ao at 10001000 {
+	infrasys: syscon at 10001000 {
 		compatible = "mediatek,mt6797-infracfg", "syscon";
 		reg = <0 0x10001000 0 0x1000>;
 		#clock-cells = <1>;
@@ -452,19 +452,19 @@ mmsys: syscon at 14000000 {
 		#clock-cells = <1>;
 	};
 
-	imgsys: imgsys_config at 15000000  {
+	imgsys: syscon at 15000000  {
 		compatible = "mediatek,mt6797-imgsys", "syscon";
 		reg = <0 0x15000000 0 0x1000>;
 		#clock-cells = <1>;
 	};
 
-	vdecsys: vdec_gcon at 16000000 {
+	vdecsys: syscon at 16000000 {
 		compatible = "mediatek,mt6797-vdecsys", "syscon";
 		reg = <0 0x16000000 0 0x10000>;
 		#clock-cells = <1>;
 	};
 
-	vencsys: venc_gcon at 17000000 {
+	vencsys: syscon at 17000000 {
 		compatible = "mediatek,mt6797-vencsys", "syscon";
 		reg = <0 0x17000000 0 0x1000>;
 		#clock-cells = <1>;
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
index 543c13385d6e..7b97c5c91bd0 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
@@ -15,7 +15,7 @@ fragment at 0 {
 		__overlay__ {
 			#address-cells = <1>;
 			#size-cells = <0>;
-			spi_nand: spi_nand at 0 {
+			spi_nand: flash at 0 {
 				compatible = "spi-nand";
 				reg = <0>;
 				spi-max-frequency = <10000000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
index 256f245ac01d..1c9fc791bdfc 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
@@ -14,7 +14,7 @@ / {
 
 &cpu_thermal {
 	trips {
-		cpu_crit: cpu_crit0 {
+		cpu_crit: cpu-crit0 {
 			temperature = <100000>;
 			type = "critical";
 		};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
index 335aed42dc9e..6d962d437e02 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
@@ -1135,7 +1135,7 @@ rtc: mt6397rtc {
 			compatible = "mediatek,mt6397-rtc";
 		};
 
-		syscfg_pctl_pmic: syscfg_pctl_pmic at c000 {
+		syscfg_pctl_pmic: syscon at c000 {
 			compatible = "mediatek,mt6397-pctl-pmic-syscfg",
 				     "syscon";
 			reg = <0 0x0000c000 0 0x0108>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index fe572a2f8f79..3458be7f7f61 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -222,14 +222,14 @@ CPU_SLEEP_0: cpu-sleep-0 {
 		};
 	};
 
-	pmu_a53 {
+	pmu-a53 {
 		compatible = "arm,cortex-a53-pmu";
 		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_SPI 9 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-affinity = <&cpu0>, <&cpu1>;
 	};
 
-	pmu_a72 {
+	pmu-a72 {
 		compatible = "arm,cortex-a72-pmu";
 		interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_SPI 13 IRQ_TYPE_LEVEL_LOW>;
@@ -286,7 +286,7 @@ target: trip-point1 {
 					type = "passive";
 				};
 
-				cpu_crit: cpu_crit0 {
+				cpu_crit: cpu-crit0 {
 					temperature = <115000>;
 					hysteresis = <2000>;
 					type = "critical";
@@ -318,7 +318,7 @@ reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
 		ranges;
-		vpu_dma_reserved: vpu_dma_mem_region at b7000000 {
+		vpu_dma_reserved: vpu-dma-mem at b7000000 {
 			compatible = "shared-dma-pool";
 			reg = <0 0xb7000000 0 0x500000>;
 			alignment = <0x1000>;
@@ -366,7 +366,7 @@ pericfg: power-controller at 10003000 {
 			#reset-cells = <1>;
 		};
 
-		syscfg_pctl_a: syscfg_pctl_a at 10005000 {
+		syscfg_pctl_a: syscon at 10005000 {
 			compatible = "mediatek,mt8173-pctl-a-syscfg", "syscon";
 			reg = <0 0x10005000 0 0x1000>;
 		};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
index 76449b4cf236..333c516af490 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
@@ -33,7 +33,7 @@ reserved-memory {
 		#size-cells = <2>;
 		ranges;
 
-		scp_mem_reserved: scp_mem_region at 50000000 {
+		scp_mem_reserved: scp-mem at 50000000 {
 			compatible = "shared-dma-pool";
 			reg = <0 0x50000000 0 0x2900000>;
 			no-map;
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index cdc8d86cb432..93dfbf130231 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1964,7 +1964,7 @@ larb4: larb at 17010000 {
 			power-domains = <&spm MT8183_POWER_DOMAIN_VENC>;
 		};
 
-		venc_jpg: venc_jpg at 17030000 {
+		venc_jpg: jpeg-encoder at 17030000 {
 			compatible = "mediatek,mt8183-jpgenc", "mediatek,mtk-jpgenc";
 			reg = <0 0x17030000 0 0x1000>;
 			interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_LOW>;
-- 
2.34.1



From edumazet at google.com  Tue Feb 13 06:51:35 2024
From: edumazet at google.com (Eric Dumazet)
Date: Tue, 13 Feb 2024 15:51:35 +0100
Subject: [PATCH net v3] net: stmmac: protect updates of 64-bit statistics counters
In-Reply-To: <Zct5qJcZw0YKx54r@xhacker>
References: <20240203190927.19669-1-petr@tesarici.cz> <ea1567d9-ce66-45e6-8168-ac40a47d1821@roeck-us.net>
 <Zct5qJcZw0YKx54r@xhacker>
Message-ID: <CANn89i+4tVWezqr=BYZ5AF=9EgV2EPqhdHun=u=ga32CEJ4BXQ@mail.gmail.com>

On Tue, Feb 13, 2024 at 3:29?PM Jisheng Zhang <jszhang at kernel.org> wrote:
>
> On Sun, Feb 11, 2024 at 08:30:21PM -0800, Guenter Roeck wrote:
> > Hi,
> >
> > On Sat, Feb 03, 2024 at 08:09:27PM +0100, Petr Tesarik wrote:
> > > As explained by a comment in <linux/u64_stats_sync.h>, write side of struct
> > > u64_stats_sync must ensure mutual exclusion, or one seqcount update could
> > > be lost on 32-bit platforms, thus blocking readers forever. Such lockups
> > > have been observed in real world after stmmac_xmit() on one CPU raced with
> > > stmmac_napi_poll_tx() on another CPU.
> > >
> > > To fix the issue without introducing a new lock, split the statics into
> > > three parts:
> > >
> > > 1. fields updated only under the tx queue lock,
> > > 2. fields updated only during NAPI poll,
> > > 3. fields updated only from interrupt context,
> > >
> > > Updates to fields in the first two groups are already serialized through
> > > other locks. It is sufficient to split the existing struct u64_stats_sync
> > > so that each group has its own.
> > >
> > > Note that tx_set_ic_bit is updated from both contexts. Split this counter
> > > so that each context gets its own, and calculate their sum to get the total
> > > value in stmmac_get_ethtool_stats().
> > >
> > > For the third group, multiple interrupts may be processed by different CPUs
> > > at the same time, but interrupts on the same CPU will not nest. Move fields
> > > from this group to a newly created per-cpu struct stmmac_pcpu_stats.
> > >
> > > Fixes: 133466c3bbe1 ("net: stmmac: use per-queue 64 bit statistics where necessary")
> > > Link: https://lore.kernel.org/netdev/Za173PhviYg-1qIn at torres.zugschlus.de/t/
> > > Cc: stable at vger.kernel.org
> > > Signed-off-by: Petr Tesarik <petr at tesarici.cz>
> >
> > This patch results in a lockdep splat. Backtrace and bisect results attached.
> >
> > Guenter
> >
> > ---
> > [   33.736728] ================================
> > [   33.736805] WARNING: inconsistent lock state
> > [   33.736953] 6.8.0-rc4 #1 Tainted: G                 N
> > [   33.737080] --------------------------------
> > [   33.737155] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
> > [   33.737309] kworker/0:2/39 [HC1[1]:SC0[2]:HE0:SE0] takes:
> > [   33.737459] ef792074 (&syncp->seq#2){?...}-{0:0}, at: sun8i_dwmac_dma_interrupt+0x9c/0x28c
> > [   33.738206] {HARDIRQ-ON-W} state was registered at:
> > [   33.738318]   lock_acquire+0x11c/0x368
> > [   33.738431]   __u64_stats_update_begin+0x104/0x1ac
> > [   33.738525]   stmmac_xmit+0x4d0/0xc58
>
> interesting lockdep splat...
> stmmac_xmit() operates on txq_stats->q_syncp, while the
> sun8i_dwmac_dma_interrupt() operates on pcpu's priv->xstats.pcpu_stats
> they are different syncp. so how does lockdep splat happen.

Right, I do not see anything obvious yet.


From balint.dobszay at arm.com  Tue Feb 13 06:52:36 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Tue, 13 Feb 2024 15:52:36 +0100
Subject: [PATCH 0/3] TEE driver for Trusted Services
Message-ID: <20240213145239.379875-1-balint.dobszay@arm.com>

This series introduces a TEE driver for Trusted Services [1].

Trusted Services is a TrustedFirmware.org project that provides a
framework for developing and deploying device Root of Trust services in
FF-A [2] Secure Partitions. The project hosts the reference
implementation of Arm Platform Security Architecture [3] for Arm
A-profile devices.

The FF-A Secure Partitions are accessible through the FF-A driver in
Linux. However, the FF-A driver doesn't have a user space interface so
user space clients currently cannot access Trusted Services. The goal of
this TEE driver is to bridge this gap and make Trusted Services
functionality accessible from user space.

Changelog:
RFC[4] -> v1:
  - Add patch for moving pool_op helper functions to the TEE subsystem,
    as suggested by Jens
  - Address comments from Sumit, add patch for documentation

[1] https://www.trustedfirmware.org/projects/trusted-services/
[2] https://developer.arm.com/documentation/den0077/
[3] https://www.arm.com/architecture/security-features/platform-security
[4] https://lore.kernel.org/linux-arm-kernel/20230927152145.111777-1-balint.dobszay at arm.com/


Balint Dobszay (3):
  tee: optee: Move pool_op helper functions
  tee: tstee: Add Trusted Services TEE driver
  Documentation: tee: Add TS-TEE driver

 Documentation/tee/index.rst       |   1 +
 Documentation/tee/ts-tee.rst      |  70 +++++
 drivers/tee/Kconfig               |   1 +
 drivers/tee/Makefile              |   1 +
 drivers/tee/optee/core.c          |  64 ----
 drivers/tee/optee/ffa_abi.c       |   6 +-
 drivers/tee/optee/optee_private.h |  12 -
 drivers/tee/optee/smc_abi.c       |  10 +-
 drivers/tee/tee_shm.c             |  65 ++++
 drivers/tee/tstee/Kconfig         |  11 +
 drivers/tee/tstee/Makefile        |   3 +
 drivers/tee/tstee/core.c          | 501 ++++++++++++++++++++++++++++++
 drivers/tee/tstee/tstee_private.h |  92 ++++++
 include/linux/tee_drv.h           |  11 +
 include/uapi/linux/tee.h          |   1 +
 15 files changed, 765 insertions(+), 84 deletions(-)
 create mode 100644 Documentation/tee/ts-tee.rst
 create mode 100644 drivers/tee/tstee/Kconfig
 create mode 100644 drivers/tee/tstee/Makefile
 create mode 100644 drivers/tee/tstee/core.c
 create mode 100644 drivers/tee/tstee/tstee_private.h

-- 
2.34.1



From maz at kernel.org  Tue Feb 13 06:53:31 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 13 Feb 2024 14:53:31 +0000
Subject: [PATCH v1 2/4] KVM: arm64: Document KVM_ARM_GET_REG_WRITABLE_MASKS
In-Reply-To: <82b72bd2-c079-40c3-90b8-30174f2a8fe0@redhat.com>
References: <20230919175017.538312-1-jingzhangos@google.com>
	<20230919175017.538312-3-jingzhangos@google.com>
	<82b72bd2-c079-40c3-90b8-30174f2a8fe0@redhat.com>
Message-ID: <86a5o45sb8.wl-maz@kernel.org>

Hey Eric,

On Tue, 13 Feb 2024 13:59:31 +0000,
Eric Auger <eauger at redhat.com> wrote:
> 
> Hi,
> 
> On 9/19/23 19:50, Jing Zhang wrote:
> > Add some basic documentation on how to get feature ID register writable
> > masks from userspace.
> > 
> > Signed-off-by: Jing Zhang <jingzhangos at google.com>
> > ---
> >  Documentation/virt/kvm/api.rst | 42 ++++++++++++++++++++++++++++++++++
> >  1 file changed, 42 insertions(+)
> > 
> > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> > index 21a7578142a1..2defb5e198ce 100644
> > --- a/Documentation/virt/kvm/api.rst
> > +++ b/Documentation/virt/kvm/api.rst
> > @@ -6070,6 +6070,48 @@ writes to the CNTVCT_EL0 and CNTPCT_EL0 registers using the SET_ONE_REG
> >  interface. No error will be returned, but the resulting offset will not be
> >  applied.
> >  
> > +4.139 KVM_ARM_GET_REG_WRITABLE_MASKS
> > +-------------------------------------------
> > +
> > +:Capability: KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES
> > +:Architectures: arm64
> > +:Type: vm ioctl
> > +:Parameters: struct reg_mask_range (in/out)
> > +:Returns: 0 on success, < 0 on error
> > +
> > +
> > +::
> > +
> > +        #define ARM64_FEATURE_ID_SPACE_SIZE	(3 * 8 * 8)
> > +        #define ARM64_FEATURE_ID_RANGE_IDREGS	BIT(0)
> > +
> > +        struct reg_mask_range {
> > +                __u64 addr;             /* Pointer to mask array */
> > +                __u32 range;            /* Requested range */
> > +                __u32 reserved[13];
> > +        };
> > +
> > +This ioctl copies the writable masks for Feature ID registers to userspace.
> > +The Feature ID space is defined as the AArch64 System register space with
> > +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}.
> when attempting a migration between Ampere Altra and ThunderXv2 the
> first hurdle is to handle a failure when writing ICC_CTLR_EL1
> (3.0.12.12.4) on dest. This reg is outside of the scope of the above
> single range (BIT(0)).

Indeed. But more importantly, this isn't really an ID register. Plenty
of variable bits in there.

> This may be questionable if we want to migrate between those types of
> machines but the goal is to exercise different scenarios to have a
> gloval view of the problems.

I think this is a valuable experiment, and we should definitely
explore this sort of things (as I cannot see the diversity of ARM
system slowing down any time soon).

> 
> This reg exposes some RO capabilities such as ExtRange, A3V, SEIS,
> IDBits, ...
> So to get the migration going further I would need to tweek this on the
> source - for instance I guess SEIS could be reset despite the host HW
> cap - without making too much trouble.

I'm not sure SEIS is such an easy one: if you promised the guest that
it would never get an SError doing the most stupid things (SEIS=0), it
really shouldn't get one after migration. If you advertised it on the
source HW (Altra), a migration to TX2 would be fine.

The other bits are possible to change depending on the requirements of
the VM (aff3, IDBits), and ExtRange should always be set to 0 (because
our GIC implementation doesn't support EPPI/ESPI).

The really ugly part here is that if you want to affect these bits,
you will need to trap and emulate the access. Not a big deal, but in
the absence of FGT, you will need to handle the full Common trap
group, which is going to slow things down (you will have to trap
ICV_PMR_EL1, for example).

> What would you recommend, adding a new range? But I guess we need to
> design ranges carefully otherwise we may be quickly limited by the
> number of flag bits.

I can see a need to adding a range that would cover non-ID registers
that have RO fields. But we also need to consider the case of EL2
registers that take part in this.

For example, ICV_CTLR_EL1 and ICH_VTR_EL2 and deeply linked, and share
some fields. Without NV, no need to expose HCR_VTR_EL2. With NV, this
register actually drives ICV_CTLR_EL1.

So careful planning is required here, and the impact of this measured.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From balint.dobszay at arm.com  Tue Feb 13 06:52:37 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Tue, 13 Feb 2024 15:52:37 +0100
Subject: [PATCH 1/3] tee: optee: Move pool_op helper functions
In-Reply-To: <20240213145239.379875-1-balint.dobszay@arm.com>
References: <20240213145239.379875-1-balint.dobszay@arm.com>
Message-ID: <20240213145239.379875-2-balint.dobszay@arm.com>

Move the pool alloc and free helper functions from the OP-TEE driver to
the TEE subsystem, since these could be reused in other TEE drivers.
This patch is not supposed to change behavior, it's only reorganizing
the code.

Suggested-by: Jens Wiklander <jens.wiklander at linaro.org>
Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
---
 drivers/tee/optee/core.c          | 64 ------------------------------
 drivers/tee/optee/ffa_abi.c       |  6 +--
 drivers/tee/optee/optee_private.h | 12 ------
 drivers/tee/optee/smc_abi.c       | 10 ++---
 drivers/tee/tee_shm.c             | 65 +++++++++++++++++++++++++++++++
 include/linux/tee_drv.h           | 11 ++++++
 6 files changed, 84 insertions(+), 84 deletions(-)

diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 3aed554bc8d8..9390f21f9902 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -9,7 +9,6 @@
 #include <linux/crash_dump.h>
 #include <linux/errno.h>
 #include <linux/io.h>
-#include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@@ -17,69 +16,6 @@
 #include <linux/types.h>
 #include "optee_private.h"
 
-int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-			       size_t size, size_t align,
-			       int (*shm_register)(struct tee_context *ctx,
-						   struct tee_shm *shm,
-						   struct page **pages,
-						   size_t num_pages,
-						   unsigned long start))
-{
-	size_t nr_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE;
-	struct page **pages;
-	unsigned int i;
-	int rc = 0;
-
-	/*
-	 * Ignore alignment since this is already going to be page aligned
-	 * and there's no need for any larger alignment.
-	 */
-	shm->kaddr = alloc_pages_exact(nr_pages * PAGE_SIZE,
-				       GFP_KERNEL | __GFP_ZERO);
-	if (!shm->kaddr)
-		return -ENOMEM;
-
-	shm->paddr = virt_to_phys(shm->kaddr);
-	shm->size = nr_pages * PAGE_SIZE;
-
-	pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL);
-	if (!pages) {
-		rc = -ENOMEM;
-		goto err;
-	}
-
-	for (i = 0; i < nr_pages; i++)
-		pages[i] = virt_to_page((u8 *)shm->kaddr + i * PAGE_SIZE);
-
-	shm->pages = pages;
-	shm->num_pages = nr_pages;
-
-	if (shm_register) {
-		rc = shm_register(shm->ctx, shm, pages, nr_pages,
-				  (unsigned long)shm->kaddr);
-		if (rc)
-			goto err;
-	}
-
-	return 0;
-err:
-	free_pages_exact(shm->kaddr, shm->size);
-	shm->kaddr = NULL;
-	return rc;
-}
-
-void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-			       int (*shm_unregister)(struct tee_context *ctx,
-						     struct tee_shm *shm))
-{
-	if (shm_unregister)
-		shm_unregister(shm->ctx, shm);
-	free_pages_exact(shm->kaddr, shm->size);
-	shm->kaddr = NULL;
-	kfree(shm->pages);
-	shm->pages = NULL;
-}
-
 static void optee_bus_scan(struct work_struct *work)
 {
 	WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP));
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index ecb5eb079408..ee11918a2b35 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -374,14 +374,14 @@ static int optee_ffa_shm_unregister_supp(struct tee_context *ctx,
 static int pool_ffa_op_alloc(struct tee_shm_pool *pool,
 			     struct tee_shm *shm, size_t size, size_t align)
 {
-	return optee_pool_op_alloc_helper(pool, shm, size, align,
-					  optee_ffa_shm_register);
+	return tee_shm_pool_op_alloc_helper(pool, shm, size, align,
+					    optee_ffa_shm_register);
 }
 
 static void pool_ffa_op_free(struct tee_shm_pool *pool,
 			     struct tee_shm *shm)
 {
-	optee_pool_op_free_helper(pool, shm, optee_ffa_shm_unregister);
+	tee_shm_pool_op_free_helper(pool, shm, optee_ffa_shm_unregister);
 }
 
 static void pool_ffa_op_destroy_pool(struct tee_shm_pool *pool)
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 7a5243c78b55..a153285a1919 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -283,18 +283,6 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
 int optee_enumerate_devices(u32 func);
 void optee_unregister_devices(void);
 
-int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-			       size_t size, size_t align,
-			       int (*shm_register)(struct tee_context *ctx,
-						   struct tee_shm *shm,
-						   struct page **pages,
-						   size_t num_pages,
-						   unsigned long start));
-void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-			       int (*shm_unregister)(struct tee_context *ctx,
-						     struct tee_shm *shm));
-
-
 void optee_remove_common(struct optee *optee);
 int optee_open(struct tee_context *ctx, bool cap_memref_null);
 void optee_release(struct tee_context *ctx);
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
index a37f87087e5c..78f4c8c43790 100644
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -592,19 +592,19 @@ static int pool_op_alloc(struct tee_shm_pool *pool,
 	 * to be registered with OP-TEE.
 	 */
 	if (shm->flags & TEE_SHM_PRIV)
-		return optee_pool_op_alloc_helper(pool, shm, size, align, NULL);
+		return tee_shm_pool_op_alloc_helper(pool, shm, size, align, NULL);
 
-	return optee_pool_op_alloc_helper(pool, shm, size, align,
-					  optee_shm_register);
+	return tee_shm_pool_op_alloc_helper(pool, shm, size, align,
+					    optee_shm_register);
 }
 
 static void pool_op_free(struct tee_shm_pool *pool,
 			 struct tee_shm *shm)
 {
 	if (!(shm->flags & TEE_SHM_PRIV))
-		optee_pool_op_free_helper(pool, shm, optee_shm_unregister);
+		tee_shm_pool_op_free_helper(pool, shm, optee_shm_unregister);
 	else
-		optee_pool_op_free_helper(pool, shm, NULL);
+		tee_shm_pool_op_free_helper(pool, shm, NULL);
 }
 
 static void pool_op_destroy_pool(struct tee_shm_pool *pool)
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c
index 731d9028b67f..641aad92ffe2 100644
--- a/drivers/tee/tee_shm.c
+++ b/drivers/tee/tee_shm.c
@@ -202,6 +202,71 @@ struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size)
 }
 EXPORT_SYMBOL_GPL(tee_shm_alloc_priv_buf);
 
+int tee_shm_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
+				 size_t size, size_t align,
+				 int (*shm_register)(struct tee_context *ctx,
+						     struct tee_shm *shm,
+						     struct page **pages,
+						     size_t num_pages,
+						     unsigned long start))
+{
+	size_t nr_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE;
+	struct page **pages;
+	unsigned int i;
+	int rc = 0;
+
+	/*
+	 * Ignore alignment since this is already going to be page aligned
+	 * and there's no need for any larger alignment.
+	 */
+	shm->kaddr = alloc_pages_exact(nr_pages * PAGE_SIZE,
+				       GFP_KERNEL | __GFP_ZERO);
+	if (!shm->kaddr)
+		return -ENOMEM;
+
+	shm->paddr = virt_to_phys(shm->kaddr);
+	shm->size = nr_pages * PAGE_SIZE;
+
+	pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL);
+	if (!pages) {
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < nr_pages; i++)
+		pages[i] = virt_to_page((u8 *)shm->kaddr + i * PAGE_SIZE);
+
+	shm->pages = pages;
+	shm->num_pages = nr_pages;
+
+	if (shm_register) {
+		rc = shm_register(shm->ctx, shm, pages, nr_pages,
+				  (unsigned long)shm->kaddr);
+		if (rc)
+			goto err;
+	}
+
+	return 0;
+err:
+	free_pages_exact(shm->kaddr, shm->size);
+	shm->kaddr = NULL;
+	return rc;
+}
+EXPORT_SYMBOL_GPL(tee_shm_pool_op_alloc_helper);
+
+void tee_shm_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
+				 int (*shm_unregister)(struct tee_context *ctx,
+						       struct tee_shm *shm))
+{
+	if (shm_unregister)
+		shm_unregister(shm->ctx, shm);
+	free_pages_exact(shm->kaddr, shm->size);
+	shm->kaddr = NULL;
+	kfree(shm->pages);
+	shm->pages = NULL;
+}
+EXPORT_SYMBOL_GPL(tee_shm_pool_op_free_helper);
+
 static struct tee_shm *
 register_shm_helper(struct tee_context *ctx, struct iov_iter *iter, u32 flags,
 		    int id)
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index 911ddf92dcee..4cf402424e71 100644
--- a/include/linux/tee_drv.h
+++ b/include/linux/tee_drv.h
@@ -275,6 +275,17 @@ void *tee_get_drvdata(struct tee_device *teedev);
 struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size);
 struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size);
 
+int tee_shm_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
+				 size_t size, size_t align,
+				 int (*shm_register)(struct tee_context *ctx,
+						     struct tee_shm *shm,
+						     struct page **pages,
+						     size_t num_pages,
+						     unsigned long start));
+void tee_shm_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
+				 int (*shm_unregister)(struct tee_context *ctx,
+						       struct tee_shm *shm));
+
 struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx,
 					    void *addr, size_t length);
 
-- 
2.34.1



From balint.dobszay at arm.com  Tue Feb 13 06:52:38 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Tue, 13 Feb 2024 15:52:38 +0100
Subject: [PATCH 2/3] tee: tstee: Add Trusted Services TEE driver
In-Reply-To: <20240213145239.379875-1-balint.dobszay@arm.com>
References: <20240213145239.379875-1-balint.dobszay@arm.com>
Message-ID: <20240213145239.379875-3-balint.dobszay@arm.com>

The Trusted Services project provides a framework for developing and
deploying device Root of Trust services in FF-A Secure Partitions. The
FF-A SPs are accessible through the FF-A driver, but this doesn't
provide a user space interface. The goal of this TEE driver is to make
Trusted Services SPs accessible for user space clients.

All TS SPs have the same FF-A UUID, it identifies the RPC protocol used
by TS. A TS SP can host one or more services, a service is identified by
its service UUID. The same type of service cannot be present twice in
the same SP. During SP boot each service in an SP is assigned an
interface ID, this is just a short ID to simplify message addressing.
There is 1:1 mapping between TS SPs and TEE devices, i.e. a separate TEE
device is registered for each TS SP. This is required since contrary to
the generic TEE design where memory is shared with the whole TEE
implementation, in case of FF-A, memory is shared with a specific SP. A
user space client has to be able to separately share memory with each SP
based on its endpoint ID.

Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
---
 drivers/tee/Kconfig               |   1 +
 drivers/tee/Makefile              |   1 +
 drivers/tee/tstee/Kconfig         |  11 +
 drivers/tee/tstee/Makefile        |   3 +
 drivers/tee/tstee/core.c          | 501 ++++++++++++++++++++++++++++++
 drivers/tee/tstee/tstee_private.h |  92 ++++++
 include/uapi/linux/tee.h          |   1 +
 7 files changed, 610 insertions(+)
 create mode 100644 drivers/tee/tstee/Kconfig
 create mode 100644 drivers/tee/tstee/Makefile
 create mode 100644 drivers/tee/tstee/core.c
 create mode 100644 drivers/tee/tstee/tstee_private.h

diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig
index 73a147202e88..61b507c18780 100644
--- a/drivers/tee/Kconfig
+++ b/drivers/tee/Kconfig
@@ -15,5 +15,6 @@ if TEE
 
 source "drivers/tee/optee/Kconfig"
 source "drivers/tee/amdtee/Kconfig"
+source "drivers/tee/tstee/Kconfig"
 
 endif
diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
index 68da044afbfa..5488cba30bd2 100644
--- a/drivers/tee/Makefile
+++ b/drivers/tee/Makefile
@@ -5,3 +5,4 @@ tee-objs += tee_shm.o
 tee-objs += tee_shm_pool.o
 obj-$(CONFIG_OPTEE) += optee/
 obj-$(CONFIG_AMDTEE) += amdtee/
+obj-$(CONFIG_ARM_TSTEE) += tstee/
diff --git a/drivers/tee/tstee/Kconfig b/drivers/tee/tstee/Kconfig
new file mode 100644
index 000000000000..d32f91d47398
--- /dev/null
+++ b/drivers/tee/tstee/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config ARM_TSTEE
+	tristate "Arm Trusted Services TEE driver"
+	depends on ARM_FFA_TRANSPORT
+	default n
+	help
+	  The Trusted Services project provides a framework for developing and
+	  deploying device Root of Trust services in FF-A Secure Partitions.
+	  This driver provides an interface to make Trusted Services Secure
+	  Partitions accessible for user space clients, since the FF-A driver
+	  doesn't implement a user space interface directly.
diff --git a/drivers/tee/tstee/Makefile b/drivers/tee/tstee/Makefile
new file mode 100644
index 000000000000..5227020ebd30
--- /dev/null
+++ b/drivers/tee/tstee/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+arm-tstee-objs := core.o
+obj-$(CONFIG_ARM_TSTEE) = arm-tstee.o
diff --git a/drivers/tee/tstee/core.c b/drivers/tee/tstee/core.c
new file mode 100644
index 000000000000..8d6bbe4d03ed
--- /dev/null
+++ b/drivers/tee/tstee/core.c
@@ -0,0 +1,501 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, Arm Limited
+ */
+
+#define DRIVER_NAME "Arm TSTEE"
+#define pr_fmt(fmt) DRIVER_NAME ": " fmt
+
+#include <linux/arm_ffa.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/limits.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/tee_drv.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+
+#include "tstee_private.h"
+
+#define FFA_DIRECT_REQ_ARG_NUM 5
+#define FFA_INVALID_MEM_HANDLE U64_MAX
+
+static void arg_list_to_ffa_data(const u32 *args, struct ffa_send_direct_data *data)
+{
+	data->data0 = args[0];
+	data->data1 = args[1];
+	data->data2 = args[2];
+	data->data3 = args[3];
+	data->data4 = args[4];
+}
+
+static void arg_list_from_ffa_data(const struct ffa_send_direct_data *data, u32 *args)
+{
+	args[0] = lower_32_bits(data->data0);
+	args[1] = lower_32_bits(data->data1);
+	args[2] = lower_32_bits(data->data2);
+	args[3] = lower_32_bits(data->data3);
+	args[4] = lower_32_bits(data->data4);
+}
+
+static void tstee_get_version(struct tee_device *teedev, struct tee_ioctl_version_data *vers)
+{
+	struct tstee *tstee = tee_get_drvdata(teedev);
+	struct tee_ioctl_version_data v = {
+		.impl_id = TEE_IMPL_ID_TSTEE,
+		/* FF-A endpoint ID only uses the lower 16 bits */
+		.impl_caps = lower_16_bits(tstee->ffa_dev->vm_id),
+		.gen_caps = 0,
+	};
+
+	*vers = v;
+}
+
+static int tstee_open(struct tee_context *ctx)
+{
+	struct ts_context_data *ctxdata;
+
+	ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
+	if (!ctxdata)
+		return -ENOMEM;
+
+	mutex_init(&ctxdata->mutex);
+	idr_init(&ctxdata->sess_ids);
+	INIT_LIST_HEAD(&ctxdata->sess_list);
+
+	ctx->data = ctxdata;
+
+	return 0;
+}
+
+static void tstee_release(struct tee_context *ctx)
+{
+	struct ts_context_data *ctxdata = ctx->data;
+	struct ts_session *sess, *sess_tmp;
+
+	if (!ctxdata)
+		return;
+
+	list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list, list_node) {
+		list_del(&sess->list_node);
+		idr_remove(&ctxdata->sess_ids, sess->session_id);
+		kfree(sess);
+	}
+
+	idr_destroy(&ctxdata->sess_ids);
+	mutex_destroy(&ctxdata->mutex);
+
+	kfree(ctxdata);
+	ctx->data = NULL;
+}
+
+static struct ts_session *find_session(struct ts_context_data *ctxdata, u32 session_id)
+{
+	struct ts_session *sess;
+
+	list_for_each_entry(sess, &ctxdata->sess_list, list_node)
+		if (sess->session_id == session_id)
+			return sess;
+
+	return NULL;
+}
+
+static int tstee_open_session(struct tee_context *ctx, struct tee_ioctl_open_session_arg *arg,
+			      struct tee_param *param __always_unused)
+{
+	struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+	struct ffa_device *ffa_dev = tstee->ffa_dev;
+	struct ts_context_data *ctxdata = ctx->data;
+	struct ffa_send_direct_data ffa_data;
+	struct ts_session *sess = NULL;
+	u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+	int sess_id;
+	int rc;
+
+	ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+								  TS_RPC_OP_SERVICE_INFO);
+
+	memcpy((u8 *)(ffa_args + TS_RPC_SERVICE_INFO_UUID0), arg->uuid, UUID_SIZE);
+
+	arg_list_to_ffa_data(ffa_args, &ffa_data);
+	rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+	if (rc)
+		return rc;
+
+	arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+	if (ffa_args[TS_RPC_SERVICE_INFO_RPC_STATUS] != TS_RPC_OK)
+		return -ENODEV;
+
+	if (ffa_args[TS_RPC_SERVICE_INFO_IFACE] > U8_MAX)
+		return -EINVAL;
+
+	sess = kzalloc(sizeof(*sess), GFP_KERNEL);
+	if (!sess)
+		return -ENOMEM;
+
+	sess_id = idr_alloc(&ctxdata->sess_ids, sess, 1, 0, GFP_KERNEL);
+	if (sess_id < 0) {
+		kfree(sess);
+		return sess_id;
+	}
+
+	sess->session_id = sess_id;
+	sess->iface_id = ffa_args[TS_RPC_SERVICE_INFO_IFACE];
+
+	mutex_lock(&ctxdata->mutex);
+	list_add(&sess->list_node, &ctxdata->sess_list);
+	mutex_unlock(&ctxdata->mutex);
+
+	arg->session = sess_id;
+	arg->ret = 0;
+
+	return 0;
+}
+
+static int tstee_close_session(struct tee_context *ctx, u32 session)
+{
+	struct ts_context_data *ctxdata = ctx->data;
+	struct ts_session *sess;
+
+	mutex_lock(&ctxdata->mutex);
+	sess = find_session(ctxdata, session);
+	if (sess)
+		list_del(&sess->list_node);
+
+	mutex_unlock(&ctxdata->mutex);
+
+	if (!sess)
+		return -EINVAL;
+
+	idr_remove(&ctxdata->sess_ids, sess->session_id);
+	kfree(sess);
+
+	return 0;
+}
+
+static int tstee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
+			     struct tee_param *param)
+{
+	struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+	struct ffa_device *ffa_dev = tstee->ffa_dev;
+	struct ts_context_data *ctxdata = ctx->data;
+	struct ffa_send_direct_data ffa_data;
+	struct tee_shm *shm = NULL;
+	struct ts_session *sess;
+	u32 req_len, ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+	int shm_id, rc;
+	u8 iface_id;
+	u64 handle;
+	u16 opcode;
+
+	mutex_lock(&ctxdata->mutex);
+	sess = find_session(ctxdata, arg->session);
+
+	/* Do this while holding the mutex to make sure that the session wasn't closed meanwhile */
+	if (sess)
+		iface_id = sess->iface_id;
+
+	mutex_unlock(&ctxdata->mutex);
+	if (!sess)
+		return -EINVAL;
+
+	opcode = lower_16_bits(arg->func);
+	shm_id = lower_32_bits(param[0].u.value.a);
+	req_len = lower_32_bits(param[0].u.value.b);
+
+	if (shm_id != 0) {
+		shm = tee_shm_get_from_id(ctx, shm_id);
+		if (IS_ERR(shm))
+			return PTR_ERR(shm);
+
+		if (shm->size < req_len) {
+			pr_err("request doesn't fit into shared memory buffer\n");
+			rc = -EINVAL;
+			goto out;
+		}
+
+		handle = shm->sec_world_id;
+	} else {
+		handle = FFA_INVALID_MEM_HANDLE;
+	}
+
+	ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(iface_id, opcode);
+	ffa_args[TS_RPC_SERVICE_MEM_HANDLE_LSW] = lower_32_bits(handle);
+	ffa_args[TS_RPC_SERVICE_MEM_HANDLE_MSW] = upper_32_bits(handle);
+	ffa_args[TS_RPC_SERVICE_REQ_LEN] = req_len;
+	ffa_args[TS_RPC_SERVICE_CLIENT_ID] = 0;
+
+	arg_list_to_ffa_data(ffa_args, &ffa_data);
+	rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+	if (rc)
+		goto out;
+
+	arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+	if (ffa_args[TS_RPC_SERVICE_RPC_STATUS] != TS_RPC_OK) {
+		pr_err("invoke_func rpc status: %d\n", ffa_args[TS_RPC_SERVICE_RPC_STATUS]);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	arg->ret = ffa_args[TS_RPC_SERVICE_STATUS];
+	if (shm && shm->size >= ffa_args[TS_RPC_SERVICE_RESP_LEN])
+		param[0].u.value.a = ffa_args[TS_RPC_SERVICE_RESP_LEN];
+
+out:
+	if (shm)
+		tee_shm_put(shm);
+
+	return rc;
+}
+
+static int tstee_shm_register(struct tee_context *ctx, struct tee_shm *shm, struct page **pages,
+			      size_t num_pages, unsigned long start __always_unused)
+{
+	struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+	struct ffa_device *ffa_dev = tstee->ffa_dev;
+	struct ffa_mem_region_attributes mem_attr = {
+		.receiver = tstee->ffa_dev->vm_id,
+		.attrs = FFA_MEM_RW,
+		.flag = 0,
+	};
+	struct ffa_mem_ops_args mem_args = {
+		.attrs = &mem_attr,
+		.use_txbuf = true,
+		.nattrs = 1,
+		.flags = 0,
+	};
+	struct ffa_send_direct_data ffa_data;
+	struct sg_table sgt;
+	u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+	int rc;
+
+	rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0, num_pages * PAGE_SIZE,
+				       GFP_KERNEL);
+	if (rc)
+		return rc;
+
+	mem_args.sg = sgt.sgl;
+	rc = ffa_dev->ops->mem_ops->memory_share(&mem_args);
+	sg_free_table(&sgt);
+	if (rc)
+		return rc;
+
+	shm->sec_world_id = mem_args.g_handle;
+
+	ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+								  TS_RPC_OP_RETRIEVE_MEM);
+	ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_LSW] = lower_32_bits(shm->sec_world_id);
+	ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_MSW] = upper_32_bits(shm->sec_world_id);
+	ffa_args[TS_RPC_RETRIEVE_MEM_TAG_LSW] = 0;
+	ffa_args[TS_RPC_RETRIEVE_MEM_TAG_MSW] = 0;
+
+	arg_list_to_ffa_data(ffa_args, &ffa_data);
+	rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+	if (rc) {
+		(void)ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
+		return rc;
+	}
+
+	arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+	if (ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS] != TS_RPC_OK) {
+		pr_err("shm_register rpc status: %d\n", ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS]);
+		ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int tstee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
+{
+	struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+	struct ffa_device *ffa_dev = tstee->ffa_dev;
+	struct ffa_send_direct_data ffa_data;
+	u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+	int rc;
+
+	ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+								  TS_RPC_OP_RELINQ_MEM);
+	ffa_args[TS_RPC_RELINQ_MEM_HANDLE_LSW] = lower_32_bits(shm->sec_world_id);
+	ffa_args[TS_RPC_RELINQ_MEM_HANDLE_MSW] = upper_32_bits(shm->sec_world_id);
+
+	arg_list_to_ffa_data(ffa_args, &ffa_data);
+	rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+	if (rc)
+		return rc;
+	arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+	if (ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS] != TS_RPC_OK) {
+		pr_err("shm_unregister rpc status: %d\n", ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS]);
+		return -EINVAL;
+	}
+
+	rc = ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
+
+	return rc;
+}
+
+static const struct tee_driver_ops tstee_ops = {
+	.get_version = tstee_get_version,
+	.open = tstee_open,
+	.release = tstee_release,
+	.open_session = tstee_open_session,
+	.close_session = tstee_close_session,
+	.invoke_func = tstee_invoke_func,
+	.shm_register = tstee_shm_register,
+	.shm_unregister = tstee_shm_unregister,
+};
+
+static const struct tee_desc tstee_desc = {
+	.name = "tstee-clnt",
+	.ops = &tstee_ops,
+	.owner = THIS_MODULE,
+};
+
+static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm, size_t size, size_t align)
+{
+	return tee_shm_pool_op_alloc_helper(pool, shm, size, align, tstee_shm_register);
+}
+
+static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm)
+{
+	tee_shm_pool_op_free_helper(pool, shm, tstee_shm_unregister);
+}
+
+static void pool_op_destroy_pool(struct tee_shm_pool *pool)
+{
+	kfree(pool);
+}
+
+static const struct tee_shm_pool_ops pool_ops = {
+	.alloc = pool_op_alloc,
+	.free = pool_op_free,
+	.destroy_pool = pool_op_destroy_pool,
+};
+
+static struct tee_shm_pool *tstee_create_shm_pool(void)
+{
+	struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+
+	if (!pool)
+		return ERR_PTR(-ENOMEM);
+
+	pool->ops = &pool_ops;
+
+	return pool;
+}
+
+static bool tstee_check_rpc_compatible(struct ffa_device *ffa_dev)
+{
+	struct ffa_send_direct_data ffa_data;
+	u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+
+	ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+								  TS_RPC_OP_GET_VERSION);
+
+	arg_list_to_ffa_data(ffa_args, &ffa_data);
+	if (ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data))
+		return false;
+
+	arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+	return ffa_args[TS_RPC_GET_VERSION_RESP] == TS_RPC_PROTOCOL_VERSION;
+}
+
+static void tstee_deinit_common(struct tstee *tstee)
+{
+	tee_device_unregister(tstee->teedev);
+	if (tstee->pool)
+		tee_shm_pool_free(tstee->pool);
+
+	kfree(tstee);
+}
+
+static int tstee_probe(struct ffa_device *ffa_dev)
+{
+	struct tstee *tstee;
+	int rc;
+
+	ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev);
+
+	if (!tstee_check_rpc_compatible(ffa_dev))
+		return -EINVAL;
+
+	tstee = kzalloc(sizeof(*tstee), GFP_KERNEL);
+	if (!tstee)
+		return -ENOMEM;
+
+	tstee->ffa_dev = ffa_dev;
+
+	tstee->pool = tstee_create_shm_pool();
+	if (IS_ERR(tstee->pool)) {
+		rc = PTR_ERR(tstee->pool);
+		tstee->pool = NULL;
+		goto err;
+	}
+
+	tstee->teedev = tee_device_alloc(&tstee_desc, NULL, tstee->pool, tstee);
+	if (IS_ERR(tstee->teedev)) {
+		rc = PTR_ERR(tstee->teedev);
+		tstee->teedev = NULL;
+		goto err;
+	}
+
+	rc = tee_device_register(tstee->teedev);
+	if (rc)
+		goto err;
+
+	ffa_dev_set_drvdata(ffa_dev, tstee);
+
+	pr_info("driver initialized for endpoint 0x%x\n", ffa_dev->vm_id);
+
+	return 0;
+
+err:
+	tstee_deinit_common(tstee);
+	return rc;
+}
+
+static void tstee_remove(struct ffa_device *ffa_dev)
+{
+	tstee_deinit_common(ffa_dev->dev.driver_data);
+}
+
+static const struct ffa_device_id tstee_device_ids[] = {
+	/* TS RPC protocol UUID: bdcd76d7-825e-4751-963b-86d4f84943ac */
+	{ TS_RPC_UUID },
+	{}
+};
+
+static struct ffa_driver tstee_driver = {
+	.name = "arm_tstee",
+	.probe = tstee_probe,
+	.remove = tstee_remove,
+	.id_table = tstee_device_ids,
+};
+
+static int __init mod_init(void)
+{
+	return ffa_register(&tstee_driver);
+}
+module_init(mod_init)
+
+static void __exit mod_exit(void)
+{
+	ffa_unregister(&tstee_driver);
+}
+module_exit(mod_exit)
+
+MODULE_ALIAS("arm-tstee");
+MODULE_AUTHOR("Balint Dobszay <balint.dobszay at arm.com>");
+MODULE_DESCRIPTION("Arm Trusted Services TEE driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tee/tstee/tstee_private.h b/drivers/tee/tstee/tstee_private.h
new file mode 100644
index 000000000000..81eeda220a5c
--- /dev/null
+++ b/drivers/tee/tstee/tstee_private.h
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023, Arm Limited
+ */
+
+#ifndef TSTEE_PRIVATE_H
+#define TSTEE_PRIVATE_H
+
+#include <linux/arm_ffa.h>
+#include <linux/bitops.h>
+#include <linux/idr.h>
+#include <linux/tee_drv.h>
+#include <linux/types.h>
+#include <linux/uuid.h>
+
+/* UUID of this protocol */
+#define TS_RPC_UUID UUID_INIT(0xbdcd76d7, 0x825e, 0x4751, \
+			      0x96, 0x3b, 0x86, 0xd4, 0xf8, 0x49, 0x43, 0xac)
+
+/* Protocol version*/
+#define TS_RPC_PROTOCOL_VERSION		(1)
+
+/* Status codes */
+#define TS_RPC_OK			(0)
+
+/* RPC control register */
+#define TS_RPC_CTRL_REG			(0)
+#define OPCODE_MASK			GENMASK(15, 0)
+#define IFACE_ID_MASK			GENMASK(23, 16)
+#define TS_RPC_CTRL_OPCODE(x)		((u16)(FIELD_GET(OPCODE_MASK, (x))))
+#define TS_RPC_CTRL_IFACE_ID(x)		((u8)(FIELD_GET(IFACE_ID_MASK, (x))))
+#define TS_RPC_CTRL_PACK_IFACE_OPCODE(i, o)	\
+	(FIELD_PREP(IFACE_ID_MASK, (i)) | FIELD_PREP(OPCODE_MASK, (o)))
+#define TS_RPC_CTRL_SAP_RC		BIT(30)
+#define TS_RPC_CTRL_SAP_ERR		BIT(31)
+
+/* Interface ID for RPC management operations */
+#define TS_RPC_MGMT_IFACE_ID		(0xff)
+
+/* Management calls */
+#define TS_RPC_OP_GET_VERSION		(0x0000)
+#define TS_RPC_GET_VERSION_RESP		(1)
+
+#define TS_RPC_OP_RETRIEVE_MEM		(0x0001)
+#define TS_RPC_RETRIEVE_MEM_HANDLE_LSW	(1)
+#define TS_RPC_RETRIEVE_MEM_HANDLE_MSW	(2)
+#define TS_RPC_RETRIEVE_MEM_TAG_LSW	(3)
+#define TS_RPC_RETRIEVE_MEM_TAG_MSW	(4)
+#define TS_RPC_RETRIEVE_MEM_RPC_STATUS	(1)
+
+#define TS_RPC_OP_RELINQ_MEM		(0x0002)
+#define TS_RPC_RELINQ_MEM_HANDLE_LSW	(1)
+#define TS_RPC_RELINQ_MEM_HANDLE_MSW	(2)
+#define TS_RPC_RELINQ_MEM_RPC_STATUS	(1)
+
+#define TS_RPC_OP_SERVICE_INFO		(0x0003)
+#define TS_RPC_SERVICE_INFO_UUID0	(1)
+#define TS_RPC_SERVICE_INFO_UUID1	(2)
+#define TS_RPC_SERVICE_INFO_UUID2	(3)
+#define TS_RPC_SERVICE_INFO_UUID3	(4)
+#define TS_RPC_SERVICE_INFO_RPC_STATUS	(1)
+#define TS_RPC_SERVICE_INFO_IFACE	(2)
+
+/* Service call */
+#define TS_RPC_SERVICE_MEM_HANDLE_LSW	(1)
+#define TS_RPC_SERVICE_MEM_HANDLE_MSW	(2)
+#define TS_RPC_SERVICE_REQ_LEN		(3)
+#define TS_RPC_SERVICE_CLIENT_ID	(4)
+#define TS_RPC_SERVICE_RPC_STATUS	(1)
+#define TS_RPC_SERVICE_STATUS		(2)
+#define TS_RPC_SERVICE_RESP_LEN		(3)
+
+struct tstee {
+	struct ffa_device *ffa_dev;
+	struct tee_device *teedev;
+	struct tee_shm_pool *pool;
+};
+
+struct ts_session {
+	struct list_head list_node;
+	u32 session_id;
+	u8 iface_id;
+};
+
+struct ts_context_data {
+	struct list_head sess_list;
+	struct idr sess_ids;
+	/* Serializes access to this struct */
+	struct mutex mutex;
+};
+
+#endif /* TSTEE_PRIVATE_H */
diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
index 23e57164693c..d0430bee8292 100644
--- a/include/uapi/linux/tee.h
+++ b/include/uapi/linux/tee.h
@@ -56,6 +56,7 @@
  */
 #define TEE_IMPL_ID_OPTEE	1
 #define TEE_IMPL_ID_AMDTEE	2
+#define TEE_IMPL_ID_TSTEE	3
 
 /*
  * OP-TEE specific capabilities
-- 
2.34.1



From balint.dobszay at arm.com  Tue Feb 13 06:52:39 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Tue, 13 Feb 2024 15:52:39 +0100
Subject: [PATCH 3/3] Documentation: tee: Add TS-TEE driver
In-Reply-To: <20240213145239.379875-1-balint.dobszay@arm.com>
References: <20240213145239.379875-1-balint.dobszay@arm.com>
Message-ID: <20240213145239.379875-4-balint.dobszay@arm.com>

Add documentation for the Trusted Services TEE driver.

Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
---
 Documentation/tee/index.rst  |  1 +
 Documentation/tee/ts-tee.rst | 70 ++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 Documentation/tee/ts-tee.rst

diff --git a/Documentation/tee/index.rst b/Documentation/tee/index.rst
index a23bd08847e5..4be6e69d7837 100644
--- a/Documentation/tee/index.rst
+++ b/Documentation/tee/index.rst
@@ -10,6 +10,7 @@ TEE Subsystem
    tee
    op-tee
    amd-tee
+   ts-tee
 
 .. only::  subproject and html
 
diff --git a/Documentation/tee/ts-tee.rst b/Documentation/tee/ts-tee.rst
new file mode 100644
index 000000000000..e121ebbbfab7
--- /dev/null
+++ b/Documentation/tee/ts-tee.rst
@@ -0,0 +1,70 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================================
+TS-TEE (Trusted Services project)
+=================================
+
+This driver provides access to secure services implemented by Trusted Services.
+
+Trusted Services [1] is a TrustedFirmware.org project that provides a framework
+for developing and deploying device Root of Trust services in FF-A [2] S-EL0
+Secure Partitions. The project hosts the reference implementation of the Arm
+Platform Security Architecture [3] for Arm A-profile devices.
+
+The FF-A Secure Partitions (SP) are accessible through the FF-A driver [4] which
+provides the low level communication for this driver. On top of that the Trusted
+Services RPC protocol is used [5]. To use the driver from user space a reference
+implementation is provided at [6], which is part of the Trusted Services client
+library called libts [7].
+
+All Trusted Services (TS) SPs have the same FF-A UUID, it identifies the TS RPC
+protocol. A TS SP can host one or more services (e.g. PSA Crypto, PSA ITS, etc).
+A service is identified by its service UUID, the same type of service cannot be
+present twice in the same SP. During SP boot each service in the SP is assigned
+an "interface ID", this is just a short ID to simplify message addressing.
+
+The generic TEE design is to share memory at once with the TEE implementation,
+which can then be reused to communicate with multiple TAs. However, in case of
+FF-A, memory sharing works on an endpoint level, i.e. memory is shared with a
+specific SP. User space has to be able to separately share memory with each SP
+based on its endpoint ID, therefore a separate TEE device is registered for each
+discovered TS SP. Opening the SP corresponds to opening the TEE device and
+creating a TEE context. A TS SP hosts one or more services, opening a service
+corresponds to opening a session in the given tee_context.
+
+Overview of a system with Trusted Services components::
+
+   User space                  Kernel space                   Secure world
+   ~~~~~~~~~~                  ~~~~~~~~~~~~                   ~~~~~~~~~~~~
+   +--------+                                               +-------------+
+   | Client |                                               | Trusted     |
+   +--------+                                               | Services SP |
+      /\                                                    +-------------+
+      ||                                                          /\
+      ||                                                          ||
+      ||                                                          ||
+      \/                                                          \/
+   +-------+                +----------+--------+           +-------------+
+   | libts |                |  TEE     | TS-TEE |           |  FF-A SPMC  |
+   |       |                |  subsys  | driver |           |   + SPMD    |
+   +-------+----------------+----+-----+--------+-----------+-------------+
+   |      Generic TEE API        |     |  FF-A  |     TS RPC protocol     |
+   |      IOCTL (TEE_IOC_*)      |     | driver |        over FF-A        |
+   +-----------------------------+     +--------+-------------------------+
+
+References
+==========
+
+[1] https://www.trustedfirmware.org/projects/trusted-services/
+
+[2] https://developer.arm.com/documentation/den0077/
+
+[3] https://www.arm.com/architecture/security-features/platform-security
+
+[4] drivers/firmware/arm_ffa/
+
+[5] https://trusted-services.readthedocs.io/en/v1.0.0/developer/service-access-protocols.html#abi
+
+[6] https://git.trustedfirmware.org/TS/trusted-services.git/tree/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c?h=v1.0.0
+
+[7] https://git.trustedfirmware.org/TS/trusted-services.git/tree/deployments/libts/arm-linux/CMakeLists.txt?h=v1.0.0
-- 
2.34.1



From suzuki.poulose at arm.com  Tue Feb 13 06:54:32 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 13 Feb 2024 14:54:32 +0000
Subject: [PATCH 2/2] arm64: cpufeatures: Only check for NV1 if NV is
 present
In-Reply-To: <86bk8k5ts3.wl-maz@kernel.org>
References: <20240212144736.1933112-1-maz@kernel.org>
 <CGME20240212144758eucas1p1345ba6f2000c10a4b33f8575f0a8d22b@eucas1p1.samsung.com>
 <20240212144736.1933112-3-maz@kernel.org>
 <5b2d8fee-9d0f-48f7-b9ec-b86e95387a61@samsung.com>
 <86bk8k5ts3.wl-maz@kernel.org>
Message-ID: <0593516b-2419-49b7-83aa-fe189ffad0c2@arm.com>

On 13/02/2024 14:21, Marc Zyngier wrote:
> On Tue, 13 Feb 2024 11:14:37 +0000,
> Marek Szyprowski <m.szyprowski at samsung.com> wrote:
>>
>> Hi
>>
>> On 12.02.2024 15:47, Marc Zyngier wrote:
>>> We handle ID_AA64MMFR4_EL1.E2H0 being 0 as NV1 being present.
>>> However, this is only true if FEAT_NV is implemented.
>>>
>>> Add the required check to has_nv1(), avoiding spuriously advertising
>>> NV1 on HW that doesn't have NV at all.
>>>
>>> Fixes: da9af5071b25 ("arm64: cpufeature: Detect HCR_EL2.NV1 being RES0")
>>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>>
>> This patch in turn introduces the following warning during boot
>> (observed on today's linux-next):
>>
>> CPU: All CPU(s) started at EL2
>> CPU features: detected: 32-bit EL0 Support
>> CPU features: detected: 32-bit EL1 Support
>> CPU features: detected: CRC32 instructions
>> ------------[ cut here ]------------
>> WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/cpufeature.c:3369
>> this_cpu_has_cap+0x18/0x70
>> Modules linked in:
>> CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc4-next-20240213 #8014
>> Hardware name: Khadas VIM3 (DT)
>> pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>> pc : this_cpu_has_cap+0x18/0x70
>> lr : has_nv1+0x24/0xcc
>> ...
>> Call trace:
>>   ?this_cpu_has_cap+0x18/0x70
>>   ?update_cpu_capabilities+0x50/0x134
>>   ?setup_system_features+0x30/0x120
>>   ?smp_cpus_done+0x48/0xb4
>>   ?smp_init+0x7c/0x8c
>>   ?kernel_init_freeable+0x18c/0x4e4
>>   ?kernel_init+0x20/0x1d8
>>   ?ret_from_fork+0x10/0x20
>> irq event stamp: 2846
>> hardirqs last? enabled at (2845): [<ffff80008012cf5c>]
>> console_unlock+0x164/0x190
>> hardirqs last disabled at (2846): [<ffff80008123a078>] el1_dbg+0x24/0x8c
>> softirqs last? enabled at (2842): [<ffff800080010a60>]
>> __do_softirq+0x4a0/0x4e8
>> softirqs last disabled at (2827): [<ffff8000800169b0>]
>> ____do_softirq+0x10/0x1c
>> ---[ end trace 0000000000000000 ]---
>> alternatives: applying system-wide alternatives
> 
> This is nothing short of embarrassing. It looks like I somehow managed
> to drop CONFIG_PREEMPT from my test config, making it impossible to
> identify these issues. Apologies for that.
> 
> The following patch fixes it for me. Could you please give it a go?
> 
> Thanks,
> 
> 	M.
> 
>  From cd75279d3b6c387c13972b61c486a203d9652e97 Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <maz at kernel.org>
> Date: Tue, 13 Feb 2024 13:37:57 +0000
> Subject: [PATCH] arm64: cpufeatures: Fix FEAT_NV check when checking for
>   FEAT_NV1
> 
> Using this_cpu_has_cap() has the potential to go wrong when
> used system-wide on a preemptible kernel. Instead, use the
> __system_matches_cap() helper when checking for FEAT_NV in the
> FEAT_NV1 probing helper.
> 
> Fixes: 3673d01a2f55 ("arm64: cpufeatures: Only check for NV1 if NV is present")
> Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   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 3421b684d340..f309fd542c20 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1812,7 +1812,7 @@ static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
>   		{}
>   	};
>   
> -	return (this_cpu_has_cap(ARM64_HAS_NESTED_VIRT) &&
> +	return (__system_matches_cap(ARM64_HAS_NESTED_VIRT) &&

Even though this change now uses SYSTEM scope for NESTED_VIRT, that is 
the correct choice. Ideally, we should use the scope that was passed 
into "has_v1", but as we have seen SCOPE_LOCAL is not safe. SYSTEM
schope works fine as both NV1 and NESTED_VIRT are SYSTEM scope. The only 
time we run them SCOPE_LOCAL is for hotplugged in CPUs, at which point 
the SYSTEM wide caps are finalized and will use the right value.

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>



>   		!(has_cpuid_feature(entry, scope) ||
>   		  is_midr_in_range_list(read_cpuid_id(), nv1_ni_list)));
>   }



From neil.armstrong at linaro.org  Tue Feb 13 06:55:56 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 13 Feb 2024 15:55:56 +0100
Subject: [PATCH RFC v2] spmi: pmic-arb: Add support for multiple buses
In-Reply-To: <20240213-spmi-multi-master-support-v2-1-b3b102326906@linaro.org>
References: <20240213-spmi-multi-master-support-v2-1-b3b102326906@linaro.org>
Message-ID: <3fcb9f16-61f8-4544-a319-20496d5eb106@linaro.org>

On 13/02/2024 15:41, Abel Vesa wrote:
> The v7 HW supports currently 2 buses. So register each bus as a separate
> spmi controller and adapt all ops to use the bus instead of the
> arbitrator. Legacy mode is still supported as long as there is no child
> node that represents a bus, instead all nodes are expected to be actual
> slave devices.
> 
> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> ---
> Changes in v2:
> - Reworked it so that it registers a spmi controller for each bus
>    rather than relying on the generic framework to pass on the bus
>    (master) id.

Thanks, I think this is better.

> - Link to v1: https://lore.kernel.org/r/20240207-spmi-multi-master-support-v1-0-ce57f301c7fd at linaro.org
> ---
>   drivers/spmi/spmi-pmic-arb.c | 950 ++++++++++++++++++++++++++-----------------
>   1 file changed, 585 insertions(+), 365 deletions(-)
> 
> diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> index 9ed1180fe31f..eced35b712b4 100644
> --- a/drivers/spmi/spmi-pmic-arb.c
> +++ b/drivers/spmi/spmi-pmic-arb.c

<snip>


> +static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
> +				  struct device_node *node,
> +				  struct spmi_pmic_arb *pmic_arb)
> +{
> +	int bus_index = pmic_arb->buses_available;
> +	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[bus_index];
> +	struct device *dev = &pdev->dev;
> +	struct spmi_controller *ctrl;
> +	void __iomem *intr;
> +	void __iomem *cnfg;
> +	int index, ret;
> +	u32 irq;
> +
> +	ctrl = devm_spmi_controller_alloc(dev, sizeof(*ctrl));
> +	if (IS_ERR(ctrl))
> +		return PTR_ERR(ctrl);
> +
> +	ctrl->cmd = pmic_arb_cmd;
> +	ctrl->read_cmd = pmic_arb_read_cmd;
> +	ctrl->write_cmd = pmic_arb_write_cmd;
> +
> +	bus = spmi_controller_get_drvdata(ctrl);
> +	bus->spmic = ctrl;
> +
> +	bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID,
> +					 sizeof(*bus->ppid_to_apid),
> +					 GFP_KERNEL);
> +	if (!bus->ppid_to_apid)
> +		return -ENOMEM;
> +
> +	bus->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs,
> +				      sizeof(*bus->apid_data),
> +				      GFP_KERNEL);
> +	if (!bus->apid_data)
> +		return -ENOMEM;
> +
> +	/* Optional property for v7: */
> +	of_property_read_u32(node, "qcom,bus-id", &bus_index);

Not sure what bindings you plan to use, but this should be the reg property.

> +	if (bus_index != pmic_arb->buses_available) {
> +		dev_err(dev, "wrong bus-id value");
> +		return -EINVAL;
> +	}
> +
> +	index = of_property_match_string(node, "reg-names", "cnfg");
> +	if (index < 0) {
> +		dev_err(dev, "cnfg reg region missing");
> +		return -EINVAL;
> +	}
> +
> +	cnfg = devm_of_iomap(dev, node, index, NULL);
> +	if (IS_ERR(cnfg))
> +		return PTR_ERR(cnfg);
> +
> +	index = of_property_match_string(node, "reg-names", "intr");
> +	if (index < 0) {
> +		dev_err(dev, "intr reg region missing");
> +		return -EINVAL;
> +	}
> +
> +	intr = devm_of_iomap(dev, node, index, NULL);
> +	if (IS_ERR(intr))
> +		return PTR_ERR(intr);
> +
> +	irq = of_irq_get_byname(node, "periph_irq");
> +	if (irq < 0)
> +		return irq;
> +
> +	bus->pmic_arb = pmic_arb;
> +	bus->intr = intr;
> +	bus->cnfg = cnfg;
> +	bus->irq = irq;
> +	bus->id = bus_index;
> +
> +	ret = pmic_arb->ver_ops->init_apid(bus, index);
> +	if (ret)
> +		return ret;
> +
> +	dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index);
> +
> +	bus->domain = irq_domain_add_tree(dev->of_node,
> +					  &pmic_arb_irq_domain_ops, bus);
> +	if (!bus->domain) {
> +		dev_err(&pdev->dev, "unable to create irq_domain\n");
> +		return -ENOMEM;
> +	}
> +
> +	irq_set_chained_handler_and_data(bus->irq,
> +					 pmic_arb_chained_irq, bus);
> +
> +	bus->spmic->dev.of_node = node;
> +	dev_set_name(&bus->spmic->dev, "spmi-%d", bus_index);
> +
> +	ret = devm_spmi_controller_add(dev, bus->spmic);
> +	if (ret)
> +		return ret;
> +
> +	pmic_arb->buses_available++;
> +
> +	return 0;
> +}
> +
> +static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb,
> +					struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *node = dev->of_node;
> +	struct device_node *child;
> +	int ret;
> +
> +	for_each_available_child_of_node(node, child)
> +		if (of_node_name_eq(child, "bus")) {

It seems you use "bus" subnodes, it seems you should also submit a new
bindings scheme for v7 controllers with subnodes

> +			ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb);
> +			if (ret)
> +				return ret;
> +		}
> +
> +	if (!pmic_arb->buses_available)
> +		ret = spmi_pmic_arb_bus_init(pdev, node, pmic_arb);
> +
> +	return ret;
> +}
> +
> +static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb)
> +{
> +	int i;
> +
> +	for (i = 0; i < pmic_arb->buses_available; i++) {
> +		struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[i];
> +
> +		irq_set_chained_handler_and_data(bus->irq,
> +						 NULL, NULL);
> +		irq_domain_remove(bus->domain);
> +	}
> +}
> +

<snip>

Overall the patch is __huge__, could you split it ? Like move the bus handling
then add the multi-bus support in separate patches ?

But first please add new bindings first so we know what you expect from DT.

Thanks,
Neil

> 
> ---
> base-commit: 445a555e0623387fa9b94e68e61681717e70200a
> change-id: 20240207-spmi-multi-master-support-832a704b779b
> 
> Best regards,



From mihai.sain at microchip.com  Tue Feb 13 06:55:34 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 16:55:34 +0200
Subject: [PATCH v4 0/8] Add power-supply properties for sdmmc nodes on Microchip boards
Message-ID: <20240213145542.23207-1-mihai.sain@microchip.com>

This patch series adds power-supply properties for sdmmc nodes on Microchip boards.

Changes in v4:
--------------

* Simplify the commit description for each board to have a better understanding.

Changes in v3:
--------------

* Update the commit description for each board in order to wrap the line at max 75 columns.

Changes in v2:
--------------

* Update the commit description for each board.
* The goal is to keep the vqmmc at 3V3 in order to use the sd high-speed mode.

Mihai Sain (8):
  ARM: dts: microchip: sam9x60_curiosity: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sam9x60ek: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sama5d27_som1_ek: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sama5d27_wlsom1: Add power-supply property for sdmmc1 node
  ARM: dts: microchip: sama5d27_wlsom1_ek: Add power-supply property for sdmmc0 node
  ARM: dts: microchip: sama5d29_curiosity: Add power-supply properties for sdmmc nodes
  ARM: dts: microchip: sama5d2_icp: Add power-supply property for sdmmc0 node
  ARM: dts: microchip: sama5d2_xplained: Add power-supply property for sdmmc0 node

 arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts  | 4 ++++
 arch/arm/boot/dts/microchip/at91-sam9x60ek.dts          | 4 ++++
 arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts   | 4 ++++
 arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi   | 2 ++
 arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts | 2 ++
 arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts | 4 ++++
 arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts        | 2 ++
 arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts   | 2 ++
 8 files changed, 24 insertions(+)

-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 06:55:36 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 16:55:36 +0200
Subject: [PATCH v4 2/8] ARM: dts: microchip: sam9x60ek: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240213145542.23207-1-mihai.sain@microchip.com>
References: <20240213145542.23207-1-mihai.sain@microchip.com>
Message-ID: <20240213145542.23207-3-mihai.sain@microchip.com>

In order to use the sd high-speed mode, keep vqmmc at 3V3.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sam9x60ek.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts b/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
index f3cbb675cea4..b19a0956dc97 100644
--- a/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
+++ b/arch/arm/boot/dts/microchip/at91-sam9x60ek.dts
@@ -560,6 +560,8 @@ &sdmmc0 {
 	status = "okay";
 	cd-gpios = <&pioA 23 GPIO_ACTIVE_LOW>;
 	disable-wp;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 };
 
 &sdmmc1 {
@@ -568,6 +570,8 @@ &sdmmc1 {
 	pinctrl-0 = <&pinctrl_sdmmc1_default>;
 	no-1-8-v;
 	non-removable;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 	status = "disabled"; /* Conflict with flx4. */
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 06:55:37 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 16:55:37 +0200
Subject: [PATCH v4 3/8] ARM: dts: microchip: sama5d27_som1_ek: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240213145542.23207-1-mihai.sain@microchip.com>
References: <20240213145542.23207-1-mihai.sain@microchip.com>
Message-ID: <20240213145542.23207-4-mihai.sain@microchip.com>

In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts b/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
index f3ffb8f01d8a..255ee0640133 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
@@ -56,6 +56,8 @@ sdmmc0: sdio-host at a0000000 {
 			bus-width = <8>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_sdmmc0_default>;
+			vmmc-supply = <&vddin_3v3>;
+			vqmmc-supply = <&vddin_3v3>;
 			status = "okay";
 		};
 
@@ -63,6 +65,8 @@ sdmmc1: sdio-host at b0000000 {
 			bus-width = <4>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_sdmmc1_default>;
+			vmmc-supply = <&vddin_3v3>;
+			vqmmc-supply = <&vddin_3v3>;
 			status = "okay";
 		};
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 06:55:38 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 16:55:38 +0200
Subject: [PATCH v4 4/8] ARM: dts: microchip: sama5d27_wlsom1: Add power-supply property for sdmmc1 node
In-Reply-To: <20240213145542.23207-1-mihai.sain@microchip.com>
References: <20240213145542.23207-1-mihai.sain@microchip.com>
Message-ID: <20240213145542.23207-5-mihai.sain@microchip.com>

In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.
Add vmmc-supply and vqmmc-supply properties to sdmmc1 node.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi
index 4617805c7748..96819ea24cbd 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi
+++ b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1.dtsi
@@ -368,6 +368,8 @@ &sdmmc1 {
 	no-1-8-v;
 	non-removable;
 	bus-width = <4>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 
 	wilc: wifi at 0 {
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 06:55:41 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 16:55:41 +0200
Subject: [PATCH v4 7/8] ARM: dts: microchip: sama5d2_icp: Add power-supply property for sdmmc0 node
In-Reply-To: <20240213145542.23207-1-mihai.sain@microchip.com>
References: <20240213145542.23207-1-mihai.sain@microchip.com>
Message-ID: <20240213145542.23207-8-mihai.sain@microchip.com>

In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.
Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts b/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts
index 999adeca6f33..adcb3240e5f5 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d2_icp.dts
@@ -712,6 +712,8 @@ &sdmmc0 {
 	bus-width = <4>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
+	vmmc-supply = <&vdd_io_reg>;	// 3.3V
+	vqmmc-supply = <&vdd_io_reg>;	// 3.3V
 	status = "okay";
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 06:55:42 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 16:55:42 +0200
Subject: [PATCH v4 8/8] ARM: dts: microchip: sama5d2_xplained: Add power-supply property for sdmmc0 node
In-Reply-To: <20240213145542.23207-1-mihai.sain@microchip.com>
References: <20240213145542.23207-1-mihai.sain@microchip.com>
Message-ID: <20240213145542.23207-9-mihai.sain@microchip.com>

In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.
Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
index 6680031387e8..9b7e56790a5a 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
@@ -67,6 +67,8 @@ sdmmc0: sdio-host at a0000000 {
 			pinctrl-0 = <&pinctrl_sdmmc0_default>;
 			non-removable;
 			mmc-ddr-3_3v;
+			vmmc-supply = <&vdd_3v3_reg>;
+			vqmmc-supply = <&vdd_3v3_reg>;
 			status = "okay";
 		};
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 06:55:39 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 16:55:39 +0200
Subject: [PATCH v4 5/8] ARM: dts: microchip: sama5d27_wlsom1_ek: Add power-supply property for sdmmc0 node
In-Reply-To: <20240213145542.23207-1-mihai.sain@microchip.com>
References: <20240213145542.23207-1-mihai.sain@microchip.com>
Message-ID: <20240213145542.23207-6-mihai.sain@microchip.com>

In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.
Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
index 15239834d886..7b36e1970bb7 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
@@ -199,6 +199,8 @@ &sdmmc0 {
 	bus-width = <4>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 06:55:40 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 16:55:40 +0200
Subject: [PATCH v4 6/8] ARM: dts: microchip: sama5d29_curiosity: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240213145542.23207-1-mihai.sain@microchip.com>
References: <20240213145542.23207-1-mihai.sain@microchip.com>
Message-ID: <20240213145542.23207-7-mihai.sain@microchip.com>

In order to avoid the issues from the tuning procedure required by
the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
index 6b02b7bcfd49..4a86597d089a 100644
--- a/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
+++ b/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
@@ -504,6 +504,8 @@ &sdmmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
 	disable-wp;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 };
 
@@ -512,6 +514,8 @@ &sdmmc1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc1_default>;
 	disable-wp;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
 	status = "okay";
 };
 
-- 
2.43.0



From mihai.sain at microchip.com  Tue Feb 13 06:55:35 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Tue, 13 Feb 2024 16:55:35 +0200
Subject: [PATCH v4 1/8] ARM: dts: microchip: sam9x60_curiosity: Add power-supply properties for sdmmc nodes
In-Reply-To: <20240213145542.23207-1-mihai.sain@microchip.com>
References: <20240213145542.23207-1-mihai.sain@microchip.com>
Message-ID: <20240213145542.23207-2-mihai.sain@microchip.com>

In order to use the sd high-speed mode, keep vqmmc at 3V3.
Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
index c6fbdd29019f..457c54dde0b7 100644
--- a/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
+++ b/arch/arm/boot/dts/microchip/at91-sam9x60_curiosity.dts
@@ -452,6 +452,8 @@ &sdmmc0 {
 	pinctrl-0 = <&pinctrl_sdmmc0_default &pinctrl_sdmmc0_cd>;
 	cd-gpios = <&pioA 25 GPIO_ACTIVE_LOW>;
 	disable-wp;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 	status = "okay";
 };
 
@@ -460,6 +462,8 @@ &sdmmc1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc1_default>;
 	disable-wp;
+	vmmc-supply = <&vdd1_3v3>;
+	vqmmc-supply = <&vdd1_3v3>;
 	status = "okay";
 };
 
-- 
2.43.0



From arnd at arndb.de  Tue Feb 13 06:59:39 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 13 Feb 2024 15:59:39 +0100
Subject: [PATCH v2] nvmem: meson-efuse: fix function pointer type mismatch
In-Reply-To: <20240213142831.3069049-1-jbrunet@baylibre.com>
References: <20240213142831.3069049-1-jbrunet@baylibre.com>
Message-ID: <5448aaaa-3784-49c5-bc42-c5cd1e953949@app.fastmail.com>

On Tue, Feb 13, 2024, at 15:28, Jerome Brunet wrote:
> clang-16 warns about casting functions to incompatible types, as is done
> here to call clk_disable_unprepare:
>
> drivers/nvmem/meson-efuse.c:78:12: error: cast from 'void (*)(struct 
> clk *)' to 'void (*)(void *)' converts to incompatible function type 
> [-Werror,-Wcast-function-type-strict]
>    78 |                                        (void(*)(void 
> *))clk_disable_unprepare,
>
> The pattern of getting, enabling and setting a disable callback for a
> clock can be replaced with devm_clk_get_enabled(), which also fixes
> this warning.
>
> Fixes: 611fbca1c861 ("nvmem: meson-efuse: add peripheral clock")
> Reported-by: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>

Perfect, much nicer than my version.

Acked-by: Arnd Bergmann <arnd at arndb.de>


From nfraprado at collabora.com  Tue Feb 13 07:02:36 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Tue, 13 Feb 2024 10:02:36 -0500
Subject: [PATCH v2 0/2] arm64: dts: mediatek: mt8186: Fixes for ssusb hang
 using defconfig
Message-ID: <20240213-mt8186-ssusb-domain-clk-fix-v2-0-1f981d35f3fd@collabora.com>

Two fixes in ssusb components (the power domain and usb controller) to
allow them to successfully probe and the mt8186 to boot using the
upstream defconfig.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
Changes in v2:
- Moved the XHCI clock from the power domain to the mtu3 node and to a
  separate commit
- Link to v1: https://lore.kernel.org/r/20240212-mt8186-ssusb-domain-clk-fix-v1-1-26cb98746aa3 at collabora.com

---
N?colas F. R. A. Prado (2):
      arm64: dts: mediatek: mt8186: Add missing clocks to ssusb power domains
      arm64: dts: mediatek: mt8186: Add missing xhci clock to usb controllers

 arch/arm64/boot/dts/mediatek/mt8186.dtsi | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
---
base-commit: 2ae0a045e6814c8c1d676d6153c605a65746aa29
change-id: 20240212-mt8186-ssusb-domain-clk-fix-a691eec834fd

Best regards,
-- 
N?colas F. R. A. Prado <nfraprado at collabora.com>



From nfraprado at collabora.com  Tue Feb 13 07:02:37 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Tue, 13 Feb 2024 10:02:37 -0500
Subject: [PATCH v2 1/2] arm64: dts: mediatek: mt8186: Add missing clocks to
 ssusb power domains
In-Reply-To: <20240213-mt8186-ssusb-domain-clk-fix-v2-0-1f981d35f3fd@collabora.com>
References: <20240213-mt8186-ssusb-domain-clk-fix-v2-0-1f981d35f3fd@collabora.com>
Message-ID: <20240213-mt8186-ssusb-domain-clk-fix-v2-1-1f981d35f3fd@collabora.com>

The ssusb power domains currently don't list any clocks, despite
depending on some, and thus rely on the bootloader leaving the required
clocks on in order to work.

When booting with the upstream arm64 defconfig, the power domain
controller will defer probe until modules have loaded since it has an
indirect dependency on CONFIG_MTK_CMDQ, which is configured as a module.
However at the point where modules are loaded, unused clocks are also
disabled, causing the ssusb domains to fail to be enabled and
consequently the controller to fail probe:

mtk-power-controller 10006000.syscon:power-controller: /soc/syscon at 10006000/power-controller/power-domain at 4: failed to power on domain: -110
mtk-power-controller: probe of 10006000.syscon:power-controller failed with error -110

Add the missing clocks for the ssusb power domains so that they can
successfully probe without relying on the bootloader state.

Fixes: d9e43c1e7a38 ("arm64: dts: mt8186: Add power domains controller")
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8186.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
index adaf5e57fac5..e0e5721d6b53 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
@@ -931,11 +931,17 @@ power-domain at MT8186_POWER_DOMAIN_CSIRX_TOP {
 
 				power-domain at MT8186_POWER_DOMAIN_SSUSB {
 					reg = <MT8186_POWER_DOMAIN_SSUSB>;
+					clocks = <&topckgen CLK_TOP_USB_TOP>,
+						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>;
+					clock-names = "sys_ck", "ref_ck";
 					#power-domain-cells = <0>;
 				};
 
 				power-domain at MT8186_POWER_DOMAIN_SSUSB_P1 {
 					reg = <MT8186_POWER_DOMAIN_SSUSB_P1>;
+					clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>,
+						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>;
+					clock-names = "sys_ck", "ref_ck";
 					#power-domain-cells = <0>;
 				};
 

-- 
2.43.0



From nfraprado at collabora.com  Tue Feb 13 07:02:38 2024
From: nfraprado at collabora.com (=?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?=)
Date: Tue, 13 Feb 2024 10:02:38 -0500
Subject: [PATCH v2 2/2] arm64: dts: mediatek: mt8186: Add missing xhci
 clock to usb controllers
In-Reply-To: <20240213-mt8186-ssusb-domain-clk-fix-v2-0-1f981d35f3fd@collabora.com>
References: <20240213-mt8186-ssusb-domain-clk-fix-v2-0-1f981d35f3fd@collabora.com>
Message-ID: <20240213-mt8186-ssusb-domain-clk-fix-v2-2-1f981d35f3fd@collabora.com>

The mtu3 usb controllers don't list the xhci clock, though they require
it, and thus rely on the bootloader leaving it on in order to work.

When booting with the upstream arm64 defconfig, the usb controllers will
defer probe until modules have loaded since they have an indirect
dependency on CONFIG_MTK_CMDQ, which is configured as a module. However
at the point where modules are loaded, unused clocks are also disabled,
causing the usb controllers to probe without the xhci clock enabled and
fail to probe:

mtu3 11201000.usb: clks of sts1 are not stable!
mtu3 11201000.usb: device enable failed -110
mtu3 11201000.usb: mtu3 hw init failed:-110
mtu3 11201000.usb: failed to initialize gadget
mtu3: probe of 11201000.usb failed with error -110

(and same for the one at 11281000)

Add the missing clock for the usb controllers so that they can
successfully probe without relying on the bootloader state.

Fixes: f6c3e61c5486 ("arm64: dts: mediatek: mt8186: Add MTU3 nodes")
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8186.dtsi | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
index e0e5721d6b53..8c55b7225cf6 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
@@ -1536,8 +1536,9 @@ ssusb0: usb at 11201000 {
 			clocks = <&topckgen CLK_TOP_USB_TOP>,
 				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>,
 				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_HCLK>,
-				 <&infracfg_ao CLK_INFRA_AO_ICUSB>;
-			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck";
+				 <&infracfg_ao CLK_INFRA_AO_ICUSB>,
+				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
 			interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH 0>;
 			phys = <&u2port0 PHY_TYPE_USB2>;
 			power-domains = <&spm MT8186_POWER_DOMAIN_SSUSB>;
@@ -1601,8 +1602,9 @@ ssusb1: usb at 11281000 {
 			clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>,
 				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>,
 				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_HCLK>,
-				 <&clk26m>;
-			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck";
+				 <&clk26m>,
+				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
 			interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH 0>;
 			phys = <&u2port1 PHY_TYPE_USB2>, <&u3port1 PHY_TYPE_USB3>;
 			power-domains = <&spm MT8186_POWER_DOMAIN_SSUSB_P1>;

-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:19 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:19 +0100
Subject: [PATCH net-next v7 02/13] net: sfp: pass the phy_device when disconnecting an sfp module's PHY
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-3-maxime.chevallier@bootlin.com>

Pass the phy_device as a parameter to the sfp upstream .disconnect_phy
operation. This is preparatory work to help track phy devices across
a net_device's link.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---

V7: No changes
V6: Moved an incorrectly added hunk from the previous series to patch 0003
V5: No changes
V4: No changes
V3: No changes

 drivers/net/phy/phylink.c | 3 ++-
 drivers/net/phy/sfp-bus.c | 4 ++--
 include/linux/sfp.h       | 2 +-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index ed0b4ccaa6a6..a816391add12 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -3385,7 +3385,8 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
 	return ret;
 }
 
-static void phylink_sfp_disconnect_phy(void *upstream)
+static void phylink_sfp_disconnect_phy(void *upstream,
+				       struct phy_device *phydev)
 {
 	phylink_disconnect_phy(upstream);
 }
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index db39dec7f247..e05013aeecc3 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -486,7 +486,7 @@ static void sfp_unregister_bus(struct sfp_bus *bus)
 			bus->socket_ops->stop(bus->sfp);
 		bus->socket_ops->detach(bus->sfp);
 		if (bus->phydev && ops && ops->disconnect_phy)
-			ops->disconnect_phy(bus->upstream);
+			ops->disconnect_phy(bus->upstream, bus->phydev);
 	}
 	bus->registered = false;
 }
@@ -742,7 +742,7 @@ void sfp_remove_phy(struct sfp_bus *bus)
 	const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
 
 	if (ops && ops->disconnect_phy)
-		ops->disconnect_phy(bus->upstream);
+		ops->disconnect_phy(bus->upstream, bus->phydev);
 	bus->phydev = NULL;
 }
 EXPORT_SYMBOL_GPL(sfp_remove_phy);
diff --git a/include/linux/sfp.h b/include/linux/sfp.h
index 9346cd44814d..0573e53b0c11 100644
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -544,7 +544,7 @@ struct sfp_upstream_ops {
 	void (*link_down)(void *priv);
 	void (*link_up)(void *priv);
 	int (*connect_phy)(void *priv, struct phy_device *);
-	void (*disconnect_phy)(void *priv);
+	void (*disconnect_phy)(void *priv, struct phy_device *);
 };
 
 #if IS_ENABLED(CONFIG_SFP)
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:17 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:17 +0100
Subject: [PATCH net-next v7 00/13] Introduce PHY listing and link_topology tracking
Message-ID: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>

Hello everyone,

This is V7 for the link topology addition, allowing to track all PHYs
that are linked to netdevices.

The main change in V7 is the protection of the main internal API
entrypoints (link_topo_init/cleanup, link_topo_add/del_phy) by
IS_REACHABLE(CONFIG_PHYLIB).

That's restrictive, but it looks difficult to do otherwise while still keep the
data structure opaque and not add dependency clutter with PHYLIB.

As you can tell, I'm unsure about this, so please don't hesitate to
comment on that part :)

The other changes are very minor, the only one is a call to netdev_put
in the .done() netlink callback.

As a remainder, here's what the PHY listings would look like :
 - eth0 has a 88x3310 acting as media converter, and an SFP module with
   an embedded 88e1111 PHY
 - eth2 has a 88e1510 PHY

# ethtool --show-phys *

PHY for eth0:
PHY index: 1
Driver name: mv88x3310
PHY device name: f212a600.mdio-mii:00
Downstream SFP bus name: sfp-eth0
PHY id: 0
Upstream type: MAC

PHY for eth0:
PHY index: 2
Driver name: Marvell 88E1111
PHY device name: i2c:sfp-eth0:16
PHY id: 21040322
Upstream type: PHY
Upstream PHY index: 1
Upstream SFP name: sfp-eth0

PHY for eth2:
PHY index: 1
Driver name: Marvell 88E1510
PHY device name: f212a200.mdio-mii:00
PHY id: 21040593
Upstream type: MAC

Ethtool patches : https://github.com/minimaxwell/ethtool/tree/link-topo-v6

Link to V6: https://lore.kernel.org/netdev/20240126183851.2081418-1-maxime.chevallier at bootlin.com/
Link to V5: https://lore.kernel.org/netdev/20231221180047.1924733-1-maxime.chevallier at bootlin.com/
Link to V4: https://lore.kernel.org/netdev/20231215171237.1152563-1-maxime.chevallier at bootlin.com/
Link to V3: https://lore.kernel.org/netdev/20231201163704.1306431-1-maxime.chevallier at bootlin.com/
Link to V2: https://lore.kernel.org/netdev/20231117162323.626979-1-maxime.chevallier at bootlin.com/
Link to V1: https://lore.kernel.org/netdev/20230907092407.647139-1-maxime.chevallier at bootlin.com/

Maxime Chevallier (13):
  net: phy: Introduce ethernet link topology representation
  net: sfp: pass the phy_device when disconnecting an sfp module's PHY
  net: phy: add helpers to handle sfp phy connect/disconnect
  net: sfp: Add helper to return the SFP bus name
  net: ethtool: Allow passing a phy index for some commands
  netlink: specs: add phy-index as a header parameter
  net: ethtool: Introduce a command to list PHYs on an interface
  netlink: specs: add ethnl PHY_GET command set
  net: ethtool: plca: Target the command to the requested PHY
  net: ethtool: pse-pd: Target the command to the requested PHY
  net: ethtool: cable-test: Target the command to the requested PHY
  net: ethtool: strset: Allow querying phy stats by index
  Documentation: networking: document phy_link_topology

 Documentation/netlink/specs/ethtool.yaml      |  62 ++++
 Documentation/networking/ethtool-netlink.rst  |  46 +++
 Documentation/networking/index.rst            |   1 +
 .../networking/phy-link-topology.rst          | 121 +++++++
 MAINTAINERS                                   |   2 +
 drivers/net/phy/Makefile                      |   2 +-
 drivers/net/phy/at803x.c                      |   2 +
 drivers/net/phy/marvell-88x2222.c             |   2 +
 drivers/net/phy/marvell.c                     |   2 +
 drivers/net/phy/marvell10g.c                  |   2 +
 drivers/net/phy/phy_device.c                  |  55 ++++
 drivers/net/phy/phy_link_topology.c           | 105 +++++++
 drivers/net/phy/phylink.c                     |   3 +-
 drivers/net/phy/sfp-bus.c                     |  15 +-
 include/linux/netdevice.h                     |   4 +-
 include/linux/phy.h                           |   6 +
 include/linux/phy_link_topology.h             |  72 +++++
 include/linux/phy_link_topology_core.h        |  25 ++
 include/linux/sfp.h                           |   8 +-
 include/uapi/linux/ethtool.h                  |  16 +
 include/uapi/linux/ethtool_netlink.h          |  21 ++
 net/core/dev.c                                |   9 +
 net/ethtool/Makefile                          |   2 +-
 net/ethtool/cabletest.c                       |  16 +-
 net/ethtool/netlink.c                         |  53 +++-
 net/ethtool/netlink.h                         |  10 +
 net/ethtool/phy.c                             | 297 ++++++++++++++++++
 net/ethtool/plca.c                            |  19 +-
 net/ethtool/pse-pd.c                          |  13 +-
 net/ethtool/strset.c                          |  17 +-
 30 files changed, 965 insertions(+), 43 deletions(-)
 create mode 100644 Documentation/networking/phy-link-topology.rst
 create mode 100644 drivers/net/phy/phy_link_topology.c
 create mode 100644 include/linux/phy_link_topology.h
 create mode 100644 include/linux/phy_link_topology_core.h
 create mode 100644 net/ethtool/phy.c

-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:20 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:20 +0100
Subject: [PATCH net-next v7 03/13] net: phy: add helpers to handle sfp phy connect/disconnect
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-4-maxime.chevallier@bootlin.com>

There are a few PHY drivers that can handle SFP modules through their
sfp_upstream_ops. Introduce Phylib helpers to keep track of connected
SFP PHYs in a netdevice's namespace, by adding the SFP PHY to the
upstream PHY's netdev's namespace.

By doing so, these SFP PHYs can be enumerated and exposed to users,
which will be able to use their capabilities.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---

V7: No changes
V6: Moved phy_get_link_topology() definition to this patch
V5: No Changes
V4: Rebased the at803x part with the newer version on net-next
V3: Renaming
V2: Renaming

 drivers/net/phy/at803x.c          |  2 ++
 drivers/net/phy/marvell-88x2222.c |  2 ++
 drivers/net/phy/marvell.c         |  2 ++
 drivers/net/phy/marvell10g.c      |  2 ++
 drivers/net/phy/phy_device.c      | 48 +++++++++++++++++++++++++++++++
 include/linux/phy.h               |  2 ++
 6 files changed, 58 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index a62442a55774..2f50170738f3 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -1475,6 +1475,8 @@ static const struct sfp_upstream_ops at8031_sfp_ops = {
 	.attach = phy_sfp_attach,
 	.detach = phy_sfp_detach,
 	.module_insert = at8031_sfp_insert,
+	.connect_phy = phy_sfp_connect_phy,
+	.disconnect_phy = phy_sfp_disconnect_phy,
 };
 
 static int at8031_parse_dt(struct phy_device *phydev)
diff --git a/drivers/net/phy/marvell-88x2222.c b/drivers/net/phy/marvell-88x2222.c
index e3aa30dad2e6..3f77bbc7e04f 100644
--- a/drivers/net/phy/marvell-88x2222.c
+++ b/drivers/net/phy/marvell-88x2222.c
@@ -555,6 +555,8 @@ static const struct sfp_upstream_ops sfp_phy_ops = {
 	.link_down = mv2222_sfp_link_down,
 	.attach = phy_sfp_attach,
 	.detach = phy_sfp_detach,
+	.connect_phy = phy_sfp_connect_phy,
+	.disconnect_phy = phy_sfp_disconnect_phy,
 };
 
 static int mv2222_probe(struct phy_device *phydev)
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index eba652a4c1d8..674e29bce2cc 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -3254,6 +3254,8 @@ static const struct sfp_upstream_ops m88e1510_sfp_ops = {
 	.module_remove = m88e1510_sfp_remove,
 	.attach = phy_sfp_attach,
 	.detach = phy_sfp_detach,
+	.connect_phy = phy_sfp_connect_phy,
+	.disconnect_phy = phy_sfp_disconnect_phy,
 };
 
 static int m88e1510_probe(struct phy_device *phydev)
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index ad43e280930c..6642eb642d4b 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -503,6 +503,8 @@ static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
 static const struct sfp_upstream_ops mv3310_sfp_ops = {
 	.attach = phy_sfp_attach,
 	.detach = phy_sfp_detach,
+	.connect_phy = phy_sfp_connect_phy,
+	.disconnect_phy = phy_sfp_disconnect_phy,
 	.module_insert = mv3310_sfp_insert,
 };
 
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 9385a4ee9380..436c7b62d5be 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -266,6 +266,14 @@ static void phy_mdio_device_remove(struct mdio_device *mdiodev)
 
 static struct phy_driver genphy_driver;
 
+static struct phy_link_topology *phy_get_link_topology(struct phy_device *phydev)
+{
+	if (phydev->attached_dev)
+		return phydev->attached_dev->link_topo;
+
+	return NULL;
+}
+
 static LIST_HEAD(phy_fixup_list);
 static DEFINE_MUTEX(phy_fixup_lock);
 
@@ -1355,6 +1363,46 @@ phy_standalone_show(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RO(phy_standalone);
 
+/**
+ * phy_sfp_connect_phy - Connect the SFP module's PHY to the upstream PHY
+ * @upstream: pointer to the upstream phy device
+ * @phy: pointer to the SFP module's phy device
+ *
+ * This helper allows keeping track of PHY devices on the link. It adds the
+ * SFP module's phy to the phy namespace of the upstream phy
+ */
+int phy_sfp_connect_phy(void *upstream, struct phy_device *phy)
+{
+	struct phy_device *phydev = upstream;
+	struct phy_link_topology *topo = phy_get_link_topology(phydev);
+
+	if (topo)
+		return phy_link_topo_add_phy(topo, phy, PHY_UPSTREAM_PHY, phydev);
+
+	return 0;
+}
+EXPORT_SYMBOL(phy_sfp_connect_phy);
+
+/**
+ * phy_sfp_disconnect_phy - Disconnect the SFP module's PHY from the upstream PHY
+ * @upstream: pointer to the upstream phy device
+ * @phy: pointer to the SFP module's phy device
+ *
+ * This helper allows keeping track of PHY devices on the link. It removes the
+ * SFP module's phy to the phy namespace of the upstream phy. As the module phy
+ * will be destroyed, re-inserting the same module will add a new phy with a
+ * new index.
+ */
+void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy)
+{
+	struct phy_device *phydev = upstream;
+	struct phy_link_topology *topo = phy_get_link_topology(phydev);
+
+	if (topo)
+		phy_link_topo_del_phy(topo, phy);
+}
+EXPORT_SYMBOL(phy_sfp_disconnect_phy);
+
 /**
  * phy_sfp_attach - attach the SFP bus to the PHY upstream network device
  * @upstream: pointer to the phy device
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 78647b5e0c13..3637bdfc1166 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1725,6 +1725,8 @@ int phy_suspend(struct phy_device *phydev);
 int phy_resume(struct phy_device *phydev);
 int __phy_resume(struct phy_device *phydev);
 int phy_loopback(struct phy_device *phydev, bool enable);
+int phy_sfp_connect_phy(void *upstream, struct phy_device *phy);
+void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy);
 void phy_sfp_attach(void *upstream, struct sfp_bus *bus);
 void phy_sfp_detach(void *upstream, struct sfp_bus *bus);
 int phy_sfp_probe(struct phy_device *phydev,
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:21 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:21 +0100
Subject: [PATCH net-next v7 04/13] net: sfp: Add helper to return the SFP bus name
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-5-maxime.chevallier@bootlin.com>

Knowing the bus name is helpful when we want to expose the link topology
to userspace, add a helper to return the SFP bus name.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
---

V7: - No changes
V6: - No changes
V5: - Added Andrew's R-b
V4: - No changes
V3: - Added RTNL assert
    - Made the stub inline
V2: New patch

 drivers/net/phy/sfp-bus.c | 11 +++++++++++
 include/linux/sfp.h       |  6 ++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index e05013aeecc3..413021619afe 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -859,3 +859,14 @@ void sfp_unregister_socket(struct sfp_bus *bus)
 	sfp_bus_put(bus);
 }
 EXPORT_SYMBOL_GPL(sfp_unregister_socket);
+
+const char *sfp_get_name(struct sfp_bus *bus)
+{
+	ASSERT_RTNL();
+
+	if (bus->sfp_dev)
+		return dev_name(bus->sfp_dev);
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(sfp_get_name);
diff --git a/include/linux/sfp.h b/include/linux/sfp.h
index 0573e53b0c11..55c0ab17c9e2 100644
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -570,6 +570,7 @@ struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode);
 int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
 			 const struct sfp_upstream_ops *ops);
 void sfp_bus_del_upstream(struct sfp_bus *bus);
+const char *sfp_get_name(struct sfp_bus *bus);
 #else
 static inline int sfp_parse_port(struct sfp_bus *bus,
 				 const struct sfp_eeprom_id *id,
@@ -648,6 +649,11 @@ static inline int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
 static inline void sfp_bus_del_upstream(struct sfp_bus *bus)
 {
 }
+
+static inline const char *sfp_get_name(struct sfp_bus *bus)
+{
+	return NULL;
+}
 #endif
 
 #endif
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:18 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:18 +0100
Subject: [PATCH net-next v7 01/13] net: phy: Introduce ethernet link topology representation
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-2-maxime.chevallier@bootlin.com>

Link topologies containing multiple network PHYs attached to the same
net_device can be found when using a PHY as a media converter for use
with an SFP connector, on which an SFP transceiver containing a PHY can
be used.

With the current model, the transceiver's PHY can't be used for
operations such as cable testing, timestamping, macsec offload, etc.

The reason being that most of the logic for these configuration, coming
from either ethtool netlink or ioctls tend to use netdev->phydev, which
in multi-phy systems will reference the PHY closest to the MAC.

Introduce a numbering scheme allowing to enumerate PHY devices that
belong to any netdev, which can in turn allow userspace to take more
precise decisions with regard to each PHY's configuration.

The numbering is maintained per-netdev, in a phy_device_list.
The numbering works similarly to a netdevice's ifindex, with
identifiers that are only recycled once INT_MAX has been reached.

This prevents races that could occur between PHY listing and SFP
transceiver removal/insertion.

The identifiers are assigned at phy_attach time, as the numbering
depends on the netdevice the phy is attached to. The PHY index can be
re-used for PHYs that are persistent.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V7: - Protected the phy_link_topo helpers/stubs with IS_REACHABLE
V6: - Made link_topo a pointer
    - Reworked the init/cleanup sequence
    - Added phy_index recycling if possible
V5: - Dropped the ASSERT_RTNL()
    - Made the phy_link_topo_get_phy inline
V4: - Moved the phy_link_topo_init() code to an inline header function
    - Made the code build without phylib

V3: - Renamed to phy_link_topology
    - Added assertions for RTNL
    - Various cleanups of leftover, unused test code
    - Made the PHY index u32

 MAINTAINERS                            |   2 +
 drivers/net/phy/Makefile               |   2 +-
 drivers/net/phy/phy_device.c           |   7 ++
 drivers/net/phy/phy_link_topology.c    | 105 +++++++++++++++++++++++++
 include/linux/netdevice.h              |   4 +-
 include/linux/phy.h                    |   4 +
 include/linux/phy_link_topology.h      |  72 +++++++++++++++++
 include/linux/phy_link_topology_core.h |  25 ++++++
 include/uapi/linux/ethtool.h           |  16 ++++
 net/core/dev.c                         |   9 +++
 10 files changed, 244 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/phy/phy_link_topology.c
 create mode 100644 include/linux/phy_link_topology.h
 create mode 100644 include/linux/phy_link_topology_core.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 960512bec428..03403f38aaf9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7938,6 +7938,8 @@ F:	include/linux/mii.h
 F:	include/linux/of_net.h
 F:	include/linux/phy.h
 F:	include/linux/phy_fixed.h
+F:	include/linux/phy_link_topology.h
+F:	include/linux/phy_link_topology_core.h
 F:	include/linux/phylib_stubs.h
 F:	include/linux/platform_data/mdio-bcm-unimac.h
 F:	include/linux/platform_data/mdio-gpio.h
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 6097afd44392..f218954fd7a8 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -2,7 +2,7 @@
 # Makefile for Linux PHY drivers
 
 libphy-y			:= phy.o phy-c45.o phy-core.o phy_device.o \
-				   linkmode.o
+				   linkmode.o phy_link_topology.o
 mdio-bus-y			+= mdio_bus.o mdio_device.o
 
 ifdef CONFIG_MDIO_DEVICE
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 3611ea64875e..9385a4ee9380 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -29,6 +29,7 @@
 #include <linux/phy.h>
 #include <linux/phylib_stubs.h>
 #include <linux/phy_led_triggers.h>
+#include <linux/phy_link_topology.h>
 #include <linux/pse-pd/pse.h>
 #include <linux/property.h>
 #include <linux/rtnetlink.h>
@@ -1491,6 +1492,11 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 
 		if (phydev->sfp_bus_attached)
 			dev->sfp_bus = phydev->sfp_bus;
+
+		err = phy_link_topo_add_phy(dev->link_topo, phydev,
+					    PHY_UPSTREAM_MAC, dev);
+		if (err)
+			goto error;
 	}
 
 	/* Some Ethernet drivers try to connect to a PHY device before
@@ -1820,6 +1826,7 @@ void phy_detach(struct phy_device *phydev)
 	if (dev) {
 		phydev->attached_dev->phydev = NULL;
 		phydev->attached_dev = NULL;
+		phy_link_topo_del_phy(dev->link_topo, phydev);
 	}
 	phydev->phylink = NULL;
 
diff --git a/drivers/net/phy/phy_link_topology.c b/drivers/net/phy/phy_link_topology.c
new file mode 100644
index 000000000000..985941c5c558
--- /dev/null
+++ b/drivers/net/phy/phy_link_topology.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Infrastructure to handle all PHY devices connected to a given netdev,
+ * either directly or indirectly attached.
+ *
+ * Copyright (c) 2023 Maxime Chevallier<maxime.chevallier at bootlin.com>
+ */
+
+#include <linux/phy_link_topology.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/rtnetlink.h>
+#include <linux/xarray.h>
+
+struct phy_link_topology *phy_link_topo_create(struct net_device *dev)
+{
+	struct phy_link_topology *topo;
+
+	topo = kzalloc(sizeof(*topo), GFP_KERNEL);
+	if (!topo)
+		return ERR_PTR(-ENOMEM);
+
+	xa_init_flags(&topo->phys, XA_FLAGS_ALLOC1);
+	topo->next_phy_index = 1;
+
+	return topo;
+}
+
+void phy_link_topo_destroy(struct phy_link_topology *topo)
+{
+	if (!topo)
+		return;
+
+	xa_destroy(&topo->phys);
+	kfree(topo);
+}
+
+int phy_link_topo_add_phy(struct phy_link_topology *topo,
+			  struct phy_device *phy,
+			  enum phy_upstream upt, void *upstream)
+{
+	struct phy_device_node *pdn;
+	int ret;
+
+	pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
+	if (!pdn)
+		return -ENOMEM;
+
+	pdn->phy = phy;
+	switch (upt) {
+	case PHY_UPSTREAM_MAC:
+		pdn->upstream.netdev = (struct net_device *)upstream;
+		if (phy_on_sfp(phy))
+			pdn->parent_sfp_bus = pdn->upstream.netdev->sfp_bus;
+		break;
+	case PHY_UPSTREAM_PHY:
+		pdn->upstream.phydev = (struct phy_device *)upstream;
+		if (phy_on_sfp(phy))
+			pdn->parent_sfp_bus = pdn->upstream.phydev->sfp_bus;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+	pdn->upstream_type = upt;
+
+	/* Attempt to re-use a previously allocated phy_index */
+	if (phy->phyindex) {
+		ret = xa_insert(&topo->phys, phy->phyindex, pdn, GFP_KERNEL);
+
+		/* Errors could be either -ENOMEM or -EBUSY. If the phy has an
+		 * index, and there's another entry at the same index, this is
+		 * unexpected and we still error-out
+		 */
+		if (ret)
+			goto err;
+		return 0;
+	}
+
+	ret = xa_alloc_cyclic(&topo->phys, &phy->phyindex, pdn, xa_limit_32b,
+			      &topo->next_phy_index, GFP_KERNEL);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	kfree(pdn);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(phy_link_topo_add_phy);
+
+void phy_link_topo_del_phy(struct phy_link_topology *topo,
+			   struct phy_device *phy)
+{
+	struct phy_device_node *pdn = xa_erase(&topo->phys, phy->phyindex);
+
+	/* We delete the PHY from the topology, however we don't re-set the
+	 * phy->phyindex field. If the PHY isn't gone, we can re-assign it the
+	 * same index next time it's added back to the topology
+	 */
+
+	kfree(pdn);
+}
+EXPORT_SYMBOL_GPL(phy_link_topo_del_phy);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 118c40258d07..eef604c4df81 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -40,7 +40,6 @@
 #include <net/dcbnl.h>
 #endif
 #include <net/netprio_cgroup.h>
-
 #include <linux/netdev_features.h>
 #include <linux/neighbour.h>
 #include <uapi/linux/netdevice.h>
@@ -52,6 +51,7 @@
 #include <net/net_trackers.h>
 #include <net/net_debug.h>
 #include <net/dropreason-core.h>
+#include <linux/phy_link_topology_core.h>
 
 struct netpoll_info;
 struct device;
@@ -2047,6 +2047,7 @@ enum netdev_stat_type {
  *	@fcoe_ddp_xid:	Max exchange id for FCoE LRO by ddp
  *
  *	@priomap:	XXX: need comments on this one
+ *	@link_topo:	Physical link topology tracking attached PHYs
  *	@phydev:	Physical device may attach itself
  *			for hardware timestamping
  *	@sfp_bus:	attached &struct sfp_bus structure.
@@ -2441,6 +2442,7 @@ struct net_device {
 #if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
 	struct netprio_map __rcu *priomap;
 #endif
+	struct phy_link_topology	*link_topo;
 	struct phy_device	*phydev;
 	struct sfp_bus		*sfp_bus;
 	struct lock_class_key	*qdisc_tx_busylock;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 684efaeca07c..78647b5e0c13 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -544,6 +544,9 @@ struct macsec_ops;
  * @drv: Pointer to the driver for this PHY instance
  * @devlink: Create a link between phy dev and mac dev, if the external phy
  *           used by current mac interface is managed by another mac interface.
+ * @phyindex: Unique id across the phy's parent tree of phys to address the PHY
+ *	      from userspace, similar to ifindex. A zero index means the PHY
+ *	      wasn't assigned an id yet.
  * @phy_id: UID for this device found during discovery
  * @c45_ids: 802.3-c45 Device Identifiers if is_c45.
  * @is_c45:  Set to true if this PHY uses clause 45 addressing.
@@ -642,6 +645,7 @@ struct phy_device {
 
 	struct device_link *devlink;
 
+	u32 phyindex;
 	u32 phy_id;
 
 	struct phy_c45_device_ids c45_ids;
diff --git a/include/linux/phy_link_topology.h b/include/linux/phy_link_topology.h
new file mode 100644
index 000000000000..6b79feb607e7
--- /dev/null
+++ b/include/linux/phy_link_topology.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PHY device list allow maintaining a list of PHY devices that are
+ * part of a netdevice's link topology. PHYs can for example be chained,
+ * as is the case when using a PHY that exposes an SFP module, on which an
+ * SFP transceiver that embeds a PHY is connected.
+ *
+ * This list can then be used by userspace to leverage individual PHY
+ * capabilities.
+ */
+#ifndef __PHY_LINK_TOPOLOGY_H
+#define __PHY_LINK_TOPOLOGY_H
+
+#include <linux/ethtool.h>
+#include <linux/phy_link_topology_core.h>
+
+struct xarray;
+struct phy_device;
+struct net_device;
+struct sfp_bus;
+
+struct phy_device_node {
+	enum phy_upstream upstream_type;
+
+	union {
+		struct net_device	*netdev;
+		struct phy_device	*phydev;
+	} upstream;
+
+	struct sfp_bus *parent_sfp_bus;
+
+	struct phy_device *phy;
+};
+
+struct phy_link_topology {
+	struct xarray phys;
+	u32 next_phy_index;
+};
+
+static inline struct phy_device *
+phy_link_topo_get_phy(struct phy_link_topology *topo, u32 phyindex)
+{
+	struct phy_device_node *pdn = xa_load(&topo->phys, phyindex);
+
+	if (pdn)
+		return pdn->phy;
+
+	return NULL;
+}
+
+#if IS_REACHABLE(CONFIG_PHYLIB)
+int phy_link_topo_add_phy(struct phy_link_topology *topo,
+			  struct phy_device *phy,
+			  enum phy_upstream upt, void *upstream);
+
+void phy_link_topo_del_phy(struct phy_link_topology *lt, struct phy_device *phy);
+
+#else
+static inline int phy_link_topo_add_phy(struct phy_link_topology *topo,
+					struct phy_device *phy,
+					enum phy_upstream upt, void *upstream)
+{
+	return 0;
+}
+
+static inline void phy_link_topo_del_phy(struct phy_link_topology *topo,
+					 struct phy_device *phy)
+{
+}
+#endif
+
+#endif /* __PHY_LINK_TOPOLOGY_H */
diff --git a/include/linux/phy_link_topology_core.h b/include/linux/phy_link_topology_core.h
new file mode 100644
index 000000000000..0a6479055745
--- /dev/null
+++ b/include/linux/phy_link_topology_core.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PHY_LINK_TOPOLOGY_CORE_H
+#define __PHY_LINK_TOPOLOGY_CORE_H
+
+struct phy_link_topology;
+
+#if IS_REACHABLE(CONFIG_PHYLIB)
+
+struct phy_link_topology *phy_link_topo_create(struct net_device *dev);
+void phy_link_topo_destroy(struct phy_link_topology *topo);
+
+#else
+
+static inline struct phy_link_topology *phy_link_topo_create(struct net_device *dev)
+{
+	return NULL;
+}
+
+static inline void phy_link_topo_destroy(struct phy_link_topology *topo)
+{
+}
+
+#endif
+
+#endif /* __PHY_LINK_TOPOLOGY_CORE_H */
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 06ef6b78b7de..01ba529dbb6d 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -2220,4 +2220,20 @@ struct ethtool_link_settings {
 	 * __u32 map_lp_advertising[link_mode_masks_nwords];
 	 */
 };
+
+/**
+ * enum phy_upstream - Represents the upstream component a given PHY device
+ * is connected to, as in what is on the other end of the MII bus. Most PHYs
+ * will be attached to an Ethernet MAC controller, but in some cases, there's
+ * an intermediate PHY used as a media-converter, which will driver another
+ * MII interface as its output.
+ * @PHY_UPSTREAM_MAC: Upstream component is a MAC (a switch port,
+ *		      or ethernet controller)
+ * @PHY_UPSTREAM_PHY: Upstream component is a PHY (likely a media converter)
+ */
+enum phy_upstream {
+	PHY_UPSTREAM_MAC,
+	PHY_UPSTREAM_PHY,
+};
+
 #endif /* _UAPI_LINUX_ETHTOOL_H */
diff --git a/net/core/dev.c b/net/core/dev.c
index cb2dab0feee0..0fed31da523a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -153,6 +153,7 @@
 #include <linux/prandom.h>
 #include <linux/once_lite.h>
 #include <net/netdev_rx_queue.h>
+#include <linux/phy_link_topology_core.h>
 
 #include "dev.h"
 #include "net-sysfs.h"
@@ -10875,6 +10876,12 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 #ifdef CONFIG_NET_SCHED
 	hash_init(dev->qdisc_hash);
 #endif
+	dev->link_topo = phy_link_topo_create(dev);
+	if (IS_ERR(dev->link_topo)) {
+		dev->link_topo = NULL;
+		goto free_all;
+	}
+
 	dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM;
 	setup(dev);
 
@@ -10963,6 +10970,8 @@ void free_netdev(struct net_device *dev)
 	free_percpu(dev->xdp_bulkq);
 	dev->xdp_bulkq = NULL;
 
+	phy_link_topo_destroy(dev->link_topo);
+
 	/*  Compatibility with error handling in drivers */
 	if (dev->reg_state == NETREG_UNINITIALIZED) {
 		netdev_freemem(dev);
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:22 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:22 +0100
Subject: [PATCH net-next v7 05/13] net: ethtool: Allow passing a phy index for some commands
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-6-maxime.chevallier@bootlin.com>

Some netlink commands are target towards ethernet PHYs, to control some
of their features. As there's several such commands, add the ability to
pass a PHY index in the ethnl request, which will populate the generic
ethnl_req_info with the relevant phydev when the command targets a PHY.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
---
V7: - No changes
V6: - Added dedicated policies when passing a PHY index
    - Dropped Andrew's R-b as there were changes
V5: - Added Andrew's R-b
    - Fix a typo reported by Simon
V4: - No Changes
V3: - Fixed the documentation
V2: - New patch


 Documentation/networking/ethtool-netlink.rst |  7 ++++
 include/uapi/linux/ethtool_netlink.h         |  1 +
 net/ethtool/netlink.c                        | 44 +++++++++++++++++++-
 net/ethtool/netlink.h                        |  5 +++
 4 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index d583d9abf2f8..3ca6c21e74af 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -57,6 +57,7 @@ Structure of this header is
   ``ETHTOOL_A_HEADER_DEV_INDEX``  u32     device ifindex
   ``ETHTOOL_A_HEADER_DEV_NAME``   string  device name
   ``ETHTOOL_A_HEADER_FLAGS``      u32     flags common for all requests
+  ``ETHTOOL_A_HEADER_PHY_INDEX``  u32     phy device index
   ==============================  ======  =============================
 
 ``ETHTOOL_A_HEADER_DEV_INDEX`` and ``ETHTOOL_A_HEADER_DEV_NAME`` identify the
@@ -81,6 +82,12 @@ the behaviour is backward compatible, i.e. requests from old clients not aware
 of the flag should be interpreted the way the client expects. A client must
 not set flags it does not understand.
 
+``ETHTOOL_A_HEADER_PHY_INDEX`` identify the ethernet PHY the message relates to.
+As there are numerous commands that are related to PHY configuration, and because
+we can have more than one PHY on the link, the PHY index can be passed in the
+request for the commands that needs it. It is however not mandatory, and if it
+is not passed for commands that target a PHY, the net_device.phydev pointer
+is used, as a fallback that keeps the legacy behaviour.
 
 Bit sets
 ========
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 3f89074aa06c..422e8cfdd98c 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -133,6 +133,7 @@ enum {
 	ETHTOOL_A_HEADER_DEV_INDEX,		/* u32 */
 	ETHTOOL_A_HEADER_DEV_NAME,		/* string */
 	ETHTOOL_A_HEADER_FLAGS,			/* u32 - ETHTOOL_FLAG_* */
+	ETHTOOL_A_HEADER_PHY_INDEX,		/* u32 */
 
 	/* add new constants above here */
 	__ETHTOOL_A_HEADER_CNT,
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index fe3553f60bf3..5a9beb09e5d4 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -4,6 +4,7 @@
 #include <linux/ethtool_netlink.h>
 #include <linux/pm_runtime.h>
 #include "netlink.h"
+#include <linux/phy_link_topology.h>
 
 static struct genl_family ethtool_genl_family;
 
@@ -30,6 +31,24 @@ const struct nla_policy ethnl_header_policy_stats[] = {
 							  ETHTOOL_FLAGS_STATS),
 };
 
+const struct nla_policy ethnl_header_policy_phy[] = {
+	[ETHTOOL_A_HEADER_DEV_INDEX]	= { .type = NLA_U32 },
+	[ETHTOOL_A_HEADER_DEV_NAME]	= { .type = NLA_NUL_STRING,
+					    .len = ALTIFNAMSIZ - 1 },
+	[ETHTOOL_A_HEADER_FLAGS]	= NLA_POLICY_MASK(NLA_U32,
+							  ETHTOOL_FLAGS_BASIC),
+	[ETHTOOL_A_HEADER_PHY_INDEX]		= NLA_POLICY_MIN(NLA_U32, 1),
+};
+
+const struct nla_policy ethnl_header_policy_phy_stats[] = {
+	[ETHTOOL_A_HEADER_DEV_INDEX]	= { .type = NLA_U32 },
+	[ETHTOOL_A_HEADER_DEV_NAME]	= { .type = NLA_NUL_STRING,
+					    .len = ALTIFNAMSIZ - 1 },
+	[ETHTOOL_A_HEADER_FLAGS]	= NLA_POLICY_MASK(NLA_U32,
+							  ETHTOOL_FLAGS_STATS),
+	[ETHTOOL_A_HEADER_PHY_INDEX]		= NLA_POLICY_MIN(NLA_U32, 1),
+};
+
 int ethnl_ops_begin(struct net_device *dev)
 {
 	int ret;
@@ -89,8 +108,9 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
 			       const struct nlattr *header, struct net *net,
 			       struct netlink_ext_ack *extack, bool require_dev)
 {
-	struct nlattr *tb[ARRAY_SIZE(ethnl_header_policy)];
+	struct nlattr *tb[ARRAY_SIZE(ethnl_header_policy_phy)];
 	const struct nlattr *devname_attr;
+	struct phy_device *phydev = NULL;
 	struct net_device *dev = NULL;
 	u32 flags = 0;
 	int ret;
@@ -104,7 +124,7 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
 	/* No validation here, command policy should have a nested policy set
 	 * for the header, therefore validation should have already been done.
 	 */
-	ret = nla_parse_nested(tb, ARRAY_SIZE(ethnl_header_policy) - 1, header,
+	ret = nla_parse_nested(tb, ARRAY_SIZE(ethnl_header_policy_phy) - 1, header,
 			       NULL, extack);
 	if (ret < 0)
 		return ret;
@@ -145,6 +165,26 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
 		return -EINVAL;
 	}
 
+	if (dev) {
+		if (tb[ETHTOOL_A_HEADER_PHY_INDEX]) {
+			u32 phy_index = nla_get_u32(tb[ETHTOOL_A_HEADER_PHY_INDEX]);
+
+			phydev = phy_link_topo_get_phy(dev->link_topo,
+						       phy_index);
+			if (!phydev) {
+				NL_SET_ERR_MSG_ATTR(extack, header,
+						    "no phy matches phy index");
+				return -EINVAL;
+			}
+		} else {
+			/* If we need a PHY but no phy index is specified, fallback
+			 * to dev->phydev
+			 */
+			phydev = dev->phydev;
+		}
+	}
+
+	req_info->phydev = phydev;
 	req_info->dev = dev;
 	req_info->flags = flags;
 	return 0;
diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
index 9a333a8d04c1..d57a890b5d9e 100644
--- a/net/ethtool/netlink.h
+++ b/net/ethtool/netlink.h
@@ -250,6 +250,7 @@ static inline unsigned int ethnl_reply_header_size(void)
  * @dev:   network device the request is for (may be null)
  * @dev_tracker: refcount tracker for @dev reference
  * @flags: request flags common for all request types
+ * @phydev: phy_device connected to @dev this request is for (may be null)
  *
  * This is a common base for request specific structures holding data from
  * parsed userspace request. These always embed struct ethnl_req_info at
@@ -259,6 +260,7 @@ struct ethnl_req_info {
 	struct net_device	*dev;
 	netdevice_tracker	dev_tracker;
 	u32			flags;
+	struct phy_device	*phydev;
 };
 
 static inline void ethnl_parse_header_dev_put(struct ethnl_req_info *req_info)
@@ -395,9 +397,12 @@ extern const struct ethnl_request_ops ethnl_rss_request_ops;
 extern const struct ethnl_request_ops ethnl_plca_cfg_request_ops;
 extern const struct ethnl_request_ops ethnl_plca_status_request_ops;
 extern const struct ethnl_request_ops ethnl_mm_request_ops;
+extern const struct ethnl_request_ops ethnl_phy_request_ops;
 
 extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];
 extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];
+extern const struct nla_policy ethnl_header_policy_phy[ETHTOOL_A_HEADER_PHY_INDEX + 1];
+extern const struct nla_policy ethnl_header_policy_phy_stats[ETHTOOL_A_HEADER_PHY_INDEX + 1];
 extern const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_COUNTS_ONLY + 1];
 extern const struct nla_policy ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_HEADER + 1];
 extern const struct nla_policy ethnl_linkinfo_set_policy[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL + 1];
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:23 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:23 +0100
Subject: [PATCH net-next v7 06/13] netlink: specs: add phy-index as a header parameter
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-7-maxime.chevallier@bootlin.com>

Update the spec to take the newly introduced phy-index as a generic
request parameter.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
---
V7: No changes
V6: No changes
V5: Added Andrew's R-b
V4: Ditch the ethtool-user generated code
V3: New patch

 Documentation/netlink/specs/ethtool.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 197208f419dc..bb6e1dc6d1c5 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -30,6 +30,9 @@ attribute-sets:
       -
         name: flags
         type: u32
+      -
+        name: phy-index
+        type: u32
 
   -
     name: bitset-bit
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:25 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:25 +0100
Subject: [PATCH net-next v7 08/13] netlink: specs: add ethnl PHY_GET command set
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-9-maxime.chevallier@bootlin.com>

The PHY_GET command, supporting both DUMP and GET operations, is used to
retrieve the list of PHYs connected to a netdevice, and get topology
information to know where exactly it sits on the physical link.

Add the netlink specs corresponding to that command.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---

V7: No changes
V6: Updated the spec according to the new attributes
V5: No changes
V4: Remove the ethtool-user generated code
V3: New patch

 Documentation/netlink/specs/ethtool.yaml | 59 ++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index bb6e1dc6d1c5..e98d78fbc2f3 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -16,6 +16,11 @@ definitions:
     name: stringset
     type: enum
     entries: []
+  -
+    name: phy-upstream-type
+    enum-name:
+    type: enum
+    entries: [ mac, phy ]
 
 attribute-sets:
   -
@@ -945,6 +950,38 @@ attribute-sets:
       -
         name: burst-tmr
         type: u32
+  -
+    name: phy
+    attributes:
+      -
+        name: header
+        type: nest
+        nested-attributes: header
+      -
+        name: index
+        type: u32
+      -
+        name: drvname
+        type: string
+      -
+        name: name
+        type: string
+      -
+        name: upstream-type
+        type: u32
+        enum: phy-upstream-type
+      -
+        name: upstream-phy-index
+        type: u32
+      -
+        name: upstream-sfp-name
+        type: string
+      -
+        name: downstream-sfp-name
+        type: string
+      -
+        name: id
+        type: u32
 
 operations:
   enum-model: directional
@@ -1696,3 +1733,25 @@ operations:
       name: mm-ntf
       doc: Notification for change in MAC Merge configuration.
       notify: mm-get
+    -
+      name: phy-get
+      doc: Get PHY devices attached to an interface
+
+      attribute-set: phy
+
+      do: &phy-get-op
+        request:
+          attributes:
+            - header
+        reply:
+          attributes:
+            - header
+            - index
+            - drvname
+            - name
+            - upstream-type
+            - upstream-phy-index
+            - upstream-sfp-name
+            - downstream-sfp-name
+            - id
+      dump: *phy-get-op
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:26 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:26 +0100
Subject: [PATCH net-next v7 09/13] net: ethtool: plca: Target the command to the requested PHY
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-10-maxime.chevallier@bootlin.com>

PLCA is a PHY-specific command. Instead of targeting the command
towards dev->phydev, use the request to pick the targeted PHY.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---

V7: No changes
V6: Use dedicated policy
V5: Added Andrew's R-b
V4: No changes
V3: No changes
V2: New patch

 net/ethtool/plca.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/net/ethtool/plca.c b/net/ethtool/plca.c
index b1e2e3b5027f..43b31a4a164e 100644
--- a/net/ethtool/plca.c
+++ b/net/ethtool/plca.c
@@ -25,7 +25,7 @@ struct plca_reply_data {
 
 const struct nla_policy ethnl_plca_get_cfg_policy[] = {
 	[ETHTOOL_A_PLCA_HEADER]		=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 };
 
 static void plca_update_sint(int *dst, struct nlattr **tb, u32 attrid,
@@ -61,7 +61,7 @@ static int plca_get_cfg_prepare_data(const struct ethnl_req_info *req_base,
 	int ret;
 
 	// check that the PHY device is available and connected
-	if (!dev->phydev) {
+	if (!req_base->phydev) {
 		ret = -EOPNOTSUPP;
 		goto out;
 	}
@@ -80,7 +80,7 @@ static int plca_get_cfg_prepare_data(const struct ethnl_req_info *req_base,
 	memset(&data->plca_cfg, 0xff,
 	       sizeof_field(struct plca_reply_data, plca_cfg));
 
-	ret = ops->get_plca_cfg(dev->phydev, &data->plca_cfg);
+	ret = ops->get_plca_cfg(req_base->phydev, &data->plca_cfg);
 	ethnl_ops_complete(dev);
 
 out:
@@ -129,7 +129,7 @@ static int plca_get_cfg_fill_reply(struct sk_buff *skb,
 
 const struct nla_policy ethnl_plca_set_cfg_policy[] = {
 	[ETHTOOL_A_PLCA_HEADER]		=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 	[ETHTOOL_A_PLCA_ENABLED]	= NLA_POLICY_MAX(NLA_U8, 1),
 	[ETHTOOL_A_PLCA_NODE_ID]	= NLA_POLICY_MAX(NLA_U32, 255),
 	[ETHTOOL_A_PLCA_NODE_CNT]	= NLA_POLICY_RANGE(NLA_U32, 1, 255),
@@ -141,7 +141,6 @@ const struct nla_policy ethnl_plca_set_cfg_policy[] = {
 static int
 ethnl_set_plca(struct ethnl_req_info *req_info, struct genl_info *info)
 {
-	struct net_device *dev = req_info->dev;
 	const struct ethtool_phy_ops *ops;
 	struct nlattr **tb = info->attrs;
 	struct phy_plca_cfg plca_cfg;
@@ -149,7 +148,7 @@ ethnl_set_plca(struct ethnl_req_info *req_info, struct genl_info *info)
 	int ret;
 
 	// check that the PHY device is available and connected
-	if (!dev->phydev)
+	if (!req_info->phydev)
 		return -EOPNOTSUPP;
 
 	ops = ethtool_phy_ops;
@@ -168,7 +167,7 @@ ethnl_set_plca(struct ethnl_req_info *req_info, struct genl_info *info)
 	if (!mod)
 		return 0;
 
-	ret = ops->set_plca_cfg(dev->phydev, &plca_cfg, info->extack);
+	ret = ops->set_plca_cfg(req_info->phydev, &plca_cfg, info->extack);
 	return ret < 0 ? ret : 1;
 }
 
@@ -191,7 +190,7 @@ const struct ethnl_request_ops ethnl_plca_cfg_request_ops = {
 
 const struct nla_policy ethnl_plca_get_status_policy[] = {
 	[ETHTOOL_A_PLCA_HEADER]		=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 };
 
 static int plca_get_status_prepare_data(const struct ethnl_req_info *req_base,
@@ -204,7 +203,7 @@ static int plca_get_status_prepare_data(const struct ethnl_req_info *req_base,
 	int ret;
 
 	// check that the PHY device is available and connected
-	if (!dev->phydev) {
+	if (!req_base->phydev) {
 		ret = -EOPNOTSUPP;
 		goto out;
 	}
@@ -223,7 +222,7 @@ static int plca_get_status_prepare_data(const struct ethnl_req_info *req_base,
 	memset(&data->plca_st, 0xff,
 	       sizeof_field(struct plca_reply_data, plca_st));
 
-	ret = ops->get_plca_status(dev->phydev, &data->plca_st);
+	ret = ops->get_plca_status(req_base->phydev, &data->plca_st);
 	ethnl_ops_complete(dev);
 out:
 	return ret;
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:24 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:24 +0100
Subject: [PATCH net-next v7 07/13] net: ethtool: Introduce a command to list PHYs on an interface
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-8-maxime.chevallier@bootlin.com>

As we have the ability to track the PHYs connected to a net_device
through the link_topology, we can expose this list to userspace. This
allows userspace to use these identifiers for phy-specific commands and
take the decision of which PHY to target by knowing the link topology.

Add PHY_GET and PHY_DUMP, which can be a filtered DUMP operation to list
devices on only one interface.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---

V7: - Moved the netdev release into the .done() call for filtered DUMP
      requests
V6: - Removed un-needed nest
    - Fixed the DUMP code
    - Fixed the documentation formatting
V5: - Fixed xmas tree
    - Fixed uninitialized return variable (Simon)
V4: - Fixed errors when not having SFP enabled, resulting in null names
      being passed as parameters to strlen.
V3: - Fixed the documentation
    - Fixed the DUMP implementation
V2: New patch

 Documentation/networking/ethtool-netlink.rst |  39 +++
 include/uapi/linux/ethtool_netlink.h         |  20 ++
 net/ethtool/Makefile                         |   2 +-
 net/ethtool/netlink.c                        |   9 +
 net/ethtool/netlink.h                        |   5 +
 net/ethtool/phy.c                            | 297 +++++++++++++++++++
 6 files changed, 371 insertions(+), 1 deletion(-)
 create mode 100644 net/ethtool/phy.c

diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index 3ca6c21e74af..e498c3b0b28f 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -2011,6 +2011,44 @@ The attributes are propagated to the driver through the following structure:
 .. kernel-doc:: include/linux/ethtool.h
     :identifiers: ethtool_mm_cfg
 
+PHY_GET
+=======
+
+Retrieve information about a given Ethernet PHY sitting on the link. As there
+can be more than one PHY, the DUMP operation can be used to list the PHYs
+present on a given interface, by passing an interface index or name in
+the dump request
+
+Request contents:
+
+  ====================================  ======  ==========================
+  ``ETHTOOL_A_PHY_HEADER``              nested  request header
+  ====================================  ======  ==========================
+
+Kernel response contents:
+
+  ===================================== ======  ===============================
+  ``ETHTOOL_A_PHY_HEADER``              nested  request header
+  ``ETHTOOL_A_PHY_INDEX``               u32     the phy's unique index, that can
+                                                be used for phy-specific
+                                                requests
+  ``ETHTOOL_A_PHY_DRVNAME``             string  the phy driver name
+  ``ETHTOOL_A_PHY_NAME``                string  the phy device name
+  ``ETHTOOL_A_PHY_UPSTREAM_TYPE``       u32     the type of device this phy is
+                                                connected to
+  ``ETHTOOL_A_PHY_UPSTREAM_INDEX``      u32     the PHY index of the upstream
+                                                PHY
+  ``ETHTOOL_A_PHY_UPSTREAM_SFP_NAME``   string  if this PHY is connected to
+                                                it's parent PHY through an SFP
+                                                bus, the name of this sfp bus
+  ``ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME`` string  if the phy controls an sfp bus,
+                                                the name of the sfp bus
+  ``ETHTOOL_A_PHY_ID``                  u32     the phy id if the phy is C22
+  ===================================== ======  ===============================
+
+When ``ETHTOOL_A_PHY_UPSTREAM_TYPE`` is PHY_UPSTREAM_PHY, the PHY's parent is
+another PHY.
+
 Request translation
 ===================
 
@@ -2117,4 +2155,5 @@ are netlink only.
   n/a                                 ``ETHTOOL_MSG_PLCA_GET_STATUS``
   n/a                                 ``ETHTOOL_MSG_MM_GET``
   n/a                                 ``ETHTOOL_MSG_MM_SET``
+  n/a                                 ``ETHTOOL_MSG_PHY_GET``
   =================================== =====================================
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 422e8cfdd98c..f7a13e93ecb7 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -57,6 +57,7 @@ enum {
 	ETHTOOL_MSG_PLCA_GET_STATUS,
 	ETHTOOL_MSG_MM_GET,
 	ETHTOOL_MSG_MM_SET,
+	ETHTOOL_MSG_PHY_GET,
 
 	/* add new constants above here */
 	__ETHTOOL_MSG_USER_CNT,
@@ -109,6 +110,8 @@ enum {
 	ETHTOOL_MSG_PLCA_NTF,
 	ETHTOOL_MSG_MM_GET_REPLY,
 	ETHTOOL_MSG_MM_NTF,
+	ETHTOOL_MSG_PHY_GET_REPLY,
+	ETHTOOL_MSG_PHY_NTF,
 
 	/* add new constants above here */
 	__ETHTOOL_MSG_KERNEL_CNT,
@@ -977,6 +980,23 @@ enum {
 	ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_CNT - 1)
 };
 
+enum {
+	ETHTOOL_A_PHY_UNSPEC,
+	ETHTOOL_A_PHY_HEADER,			/* nest - _A_HEADER_* */
+	ETHTOOL_A_PHY_INDEX,			/* u32 */
+	ETHTOOL_A_PHY_DRVNAME,			/* string */
+	ETHTOOL_A_PHY_NAME,			/* string */
+	ETHTOOL_A_PHY_UPSTREAM_TYPE,		/* u32 */
+	ETHTOOL_A_PHY_UPSTREAM_INDEX,		/* u32 */
+	ETHTOOL_A_PHY_UPSTREAM_SFP_NAME,	/* string */
+	ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME,	/* string */
+	ETHTOOL_A_PHY_ID,			/* u32 */
+
+	/* add new constants above here */
+	__ETHTOOL_A_PHY_CNT,
+	ETHTOOL_A_PHY_MAX = (__ETHTOOL_A_PHY_CNT - 1)
+};
+
 /* generic netlink info */
 #define ETHTOOL_GENL_NAME "ethtool"
 #define ETHTOOL_GENL_VERSION 1
diff --git a/net/ethtool/Makefile b/net/ethtool/Makefile
index 504f954a1b28..0ccd0e9afd3f 100644
--- a/net/ethtool/Makefile
+++ b/net/ethtool/Makefile
@@ -8,4 +8,4 @@ ethtool_nl-y	:= netlink.o bitset.o strset.o linkinfo.o linkmodes.o rss.o \
 		   linkstate.o debug.o wol.o features.o privflags.o rings.o \
 		   channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \
 		   tunnels.o fec.o eeprom.o stats.o phc_vclocks.o mm.o \
-		   module.o pse-pd.o plca.o mm.o
+		   module.o pse-pd.o plca.o mm.o phy.o
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index 5a9beb09e5d4..6334e8ce95f7 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -1169,6 +1169,15 @@ static const struct genl_ops ethtool_genl_ops[] = {
 		.policy = ethnl_mm_set_policy,
 		.maxattr = ARRAY_SIZE(ethnl_mm_set_policy) - 1,
 	},
+	{
+		.cmd	= ETHTOOL_MSG_PHY_GET,
+		.doit	= ethnl_phy_doit,
+		.start	= ethnl_phy_start,
+		.dumpit	= ethnl_phy_dumpit,
+		.done	= ethnl_phy_done,
+		.policy = ethnl_phy_get_policy,
+		.maxattr = ARRAY_SIZE(ethnl_phy_get_policy) - 1,
+	},
 };
 
 static const struct genl_multicast_group ethtool_nl_mcgrps[] = {
diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
index d57a890b5d9e..0e71b53bdb1c 100644
--- a/net/ethtool/netlink.h
+++ b/net/ethtool/netlink.h
@@ -446,6 +446,7 @@ extern const struct nla_policy ethnl_plca_set_cfg_policy[ETHTOOL_A_PLCA_MAX + 1]
 extern const struct nla_policy ethnl_plca_get_status_policy[ETHTOOL_A_PLCA_HEADER + 1];
 extern const struct nla_policy ethnl_mm_get_policy[ETHTOOL_A_MM_HEADER + 1];
 extern const struct nla_policy ethnl_mm_set_policy[ETHTOOL_A_MM_MAX + 1];
+extern const struct nla_policy ethnl_phy_get_policy[ETHTOOL_A_PHY_HEADER + 1];
 
 int ethnl_set_features(struct sk_buff *skb, struct genl_info *info);
 int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);
@@ -453,6 +454,10 @@ int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info);
 int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info);
 int ethnl_tunnel_info_start(struct netlink_callback *cb);
 int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
+int ethnl_phy_start(struct netlink_callback *cb);
+int ethnl_phy_doit(struct sk_buff *skb, struct genl_info *info);
+int ethnl_phy_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
+int ethnl_phy_done(struct netlink_callback *cb);
 
 extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN];
 extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN];
diff --git a/net/ethtool/phy.c b/net/ethtool/phy.c
new file mode 100644
index 000000000000..fb73bf51c683
--- /dev/null
+++ b/net/ethtool/phy.c
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2023 Bootlin
+ *
+ */
+#include "common.h"
+#include "netlink.h"
+
+#include <linux/phy.h>
+#include <linux/phy_link_topology.h>
+#include <linux/sfp.h>
+
+struct phy_req_info {
+	struct ethnl_req_info		base;
+	struct phy_device_node		pdn;
+};
+
+#define PHY_REQINFO(__req_base) \
+	container_of(__req_base, struct phy_req_info, base)
+
+const struct nla_policy ethnl_phy_get_policy[ETHTOOL_A_PHY_HEADER + 1] = {
+	[ETHTOOL_A_PHY_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
+};
+
+/* Caller holds rtnl */
+static ssize_t
+ethnl_phy_reply_size(const struct ethnl_req_info *req_base,
+		     struct netlink_ext_ack *extack)
+{
+	struct phy_req_info *req_info = PHY_REQINFO(req_base);
+	struct phy_device_node *pdn = &req_info->pdn;
+	struct phy_device *phydev = pdn->phy;
+	size_t size = 0;
+
+	ASSERT_RTNL();
+
+	/* ETHTOOL_A_PHY_INDEX */
+	size += nla_total_size(sizeof(u32));
+
+	/* ETHTOOL_A_DRVNAME */
+	if (phydev->drv)
+		size += nla_total_size(strlen(phydev->drv->name) + 1);
+
+	/* ETHTOOL_A_NAME */
+	size += nla_total_size(strlen(dev_name(&phydev->mdio.dev)) + 1);
+
+	/* ETHTOOL_A_PHY_UPSTREAM_TYPE */
+	size += nla_total_size(sizeof(u32));
+
+	/* ETHTOOL_A_PHY_ID */
+	size += nla_total_size(sizeof(u32));
+
+	if (phy_on_sfp(phydev)) {
+		const char *upstream_sfp_name = sfp_get_name(pdn->parent_sfp_bus);
+
+		/* ETHTOOL_A_PHY_UPSTREAM_SFP_NAME */
+		if (upstream_sfp_name)
+			size += nla_total_size(strlen(upstream_sfp_name) + 1);
+
+		/* ETHTOOL_A_PHY_UPSTREAM_INDEX */
+		size += nla_total_size(sizeof(u32));
+	}
+
+	/* ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME */
+	if (phydev->sfp_bus) {
+		const char *sfp_name = sfp_get_name(phydev->sfp_bus);
+
+		if (sfp_name)
+			size += nla_total_size(strlen(sfp_name) + 1);
+	}
+
+	return size;
+}
+
+static int
+ethnl_phy_fill_reply(const struct ethnl_req_info *req_base, struct sk_buff *skb)
+{
+	struct phy_req_info *req_info = PHY_REQINFO(req_base);
+	struct phy_device_node *pdn = &req_info->pdn;
+	struct phy_device *phydev = pdn->phy;
+	enum phy_upstream ptype;
+
+	ptype = pdn->upstream_type;
+
+	if (nla_put_u32(skb, ETHTOOL_A_PHY_INDEX, phydev->phyindex) ||
+	    nla_put_string(skb, ETHTOOL_A_PHY_NAME, dev_name(&phydev->mdio.dev)) ||
+	    nla_put_u32(skb, ETHTOOL_A_PHY_UPSTREAM_TYPE, ptype) ||
+	    nla_put_u32(skb, ETHTOOL_A_PHY_ID, phydev->phy_id))
+		return -EMSGSIZE;
+
+	if (phydev->drv && nla_put_string(skb, ETHTOOL_A_PHY_DRVNAME, phydev->drv->name))
+		return -EMSGSIZE;
+
+	if (ptype == PHY_UPSTREAM_PHY) {
+		struct phy_device *upstream = pdn->upstream.phydev;
+		const char *sfp_upstream_name;
+
+		/* Parent index */
+		if (nla_put_u32(skb, ETHTOOL_A_PHY_UPSTREAM_INDEX, upstream->phyindex))
+			return -EMSGSIZE;
+
+		if (pdn->parent_sfp_bus) {
+			sfp_upstream_name = sfp_get_name(pdn->parent_sfp_bus);
+			if (sfp_upstream_name && nla_put_string(skb,
+								ETHTOOL_A_PHY_UPSTREAM_SFP_NAME,
+								sfp_upstream_name))
+				return -EMSGSIZE;
+		}
+	}
+
+	if (phydev->sfp_bus) {
+		const char *sfp_name = sfp_get_name(phydev->sfp_bus);
+
+		if (sfp_name &&
+		    nla_put_string(skb, ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME,
+				   sfp_name))
+			return -EMSGSIZE;
+	}
+
+	return 0;
+}
+
+static int ethnl_phy_parse_request(struct ethnl_req_info *req_base,
+				   struct nlattr **tb)
+{
+	struct phy_link_topology *topo = req_base->dev->link_topo;
+	struct phy_req_info *req_info = PHY_REQINFO(req_base);
+	struct phy_device_node *pdn;
+
+	if (!req_base->phydev)
+		return 0;
+
+	pdn = xa_load(&topo->phys, req_base->phydev->phyindex);
+	memcpy(&req_info->pdn, pdn, sizeof(*pdn));
+
+	return 0;
+}
+
+int ethnl_phy_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct phy_req_info req_info = {};
+	struct nlattr **tb = info->attrs;
+	struct sk_buff *rskb;
+	void *reply_payload;
+	int reply_len;
+	int ret;
+
+	ret = ethnl_parse_header_dev_get(&req_info.base,
+					 tb[ETHTOOL_A_PHY_HEADER],
+					 genl_info_net(info), info->extack,
+					 true);
+	if (ret < 0)
+		return ret;
+
+	rtnl_lock();
+
+	ret = ethnl_phy_parse_request(&req_info.base, tb);
+	if (ret < 0)
+		goto err_unlock_rtnl;
+
+	/* No PHY, return early */
+	if (!req_info.pdn.phy)
+		goto err_unlock_rtnl;
+
+	ret = ethnl_phy_reply_size(&req_info.base, info->extack);
+	if (ret < 0)
+		goto err_unlock_rtnl;
+	reply_len = ret + ethnl_reply_header_size();
+
+	rskb = ethnl_reply_init(reply_len, req_info.base.dev,
+				ETHTOOL_MSG_PHY_GET_REPLY,
+				ETHTOOL_A_PHY_HEADER,
+				info, &reply_payload);
+	if (!rskb) {
+		ret = -ENOMEM;
+		goto err_unlock_rtnl;
+	}
+
+	ret = ethnl_phy_fill_reply(&req_info.base, rskb);
+	if (ret)
+		goto err_free_msg;
+
+	rtnl_unlock();
+	ethnl_parse_header_dev_put(&req_info.base);
+	genlmsg_end(rskb, reply_payload);
+
+	return genlmsg_reply(rskb, info);
+
+err_free_msg:
+	nlmsg_free(rskb);
+err_unlock_rtnl:
+	rtnl_unlock();
+	ethnl_parse_header_dev_put(&req_info.base);
+	return ret;
+}
+
+struct ethnl_phy_dump_ctx {
+	struct phy_req_info	*phy_req_info;
+	unsigned long ifindex;
+	unsigned long phy_index;
+};
+
+int ethnl_phy_start(struct netlink_callback *cb)
+{
+	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
+	struct ethnl_phy_dump_ctx *ctx = (void *)cb->ctx;
+	struct nlattr **tb = info->info.attrs;
+	int ret;
+
+	BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
+
+	ctx->phy_req_info = kzalloc(sizeof(*ctx->phy_req_info), GFP_KERNEL);
+	if (!ctx->phy_req_info)
+		return -ENOMEM;
+
+	ret = ethnl_parse_header_dev_get(&ctx->phy_req_info->base,
+					 tb[ETHTOOL_A_PHY_HEADER],
+					 sock_net(cb->skb->sk), cb->extack,
+					 false);
+	ctx->ifindex = 0;
+	ctx->phy_index = 0;
+	return ret;
+}
+
+int ethnl_phy_done(struct netlink_callback *cb)
+{
+	struct ethnl_phy_dump_ctx *ctx = (void *)cb->ctx;
+
+	ethnl_parse_header_dev_put(&ctx->phy_req_info->base);
+	kfree(ctx->phy_req_info);
+
+	return 0;
+}
+
+static int ethnl_phy_dump_one_dev(struct sk_buff *skb, struct net_device *dev,
+				  struct netlink_callback *cb)
+{
+	struct ethnl_phy_dump_ctx *ctx = (void *)cb->ctx;
+	struct phy_req_info *pri = ctx->phy_req_info;
+	struct phy_device_node *pdn;
+	int ret = 0;
+	void *ehdr;
+
+	pri->base.dev = dev;
+
+	xa_for_each_start(&dev->link_topo->phys, ctx->phy_index, pdn, ctx->phy_index) {
+		ehdr = ethnl_dump_put(skb, cb,
+				      ETHTOOL_MSG_PHY_GET_REPLY);
+		if (!ehdr) {
+			ret = -EMSGSIZE;
+			break;
+		}
+
+		ret = ethnl_fill_reply_header(skb, dev,
+					      ETHTOOL_A_PHY_HEADER);
+		if (ret < 0) {
+			genlmsg_cancel(skb, ehdr);
+			break;
+		}
+
+		memcpy(&pri->pdn, pdn, sizeof(*pdn));
+		ret = ethnl_phy_fill_reply(&pri->base, skb);
+
+		genlmsg_end(skb, ehdr);
+	}
+
+	return ret;
+}
+
+int ethnl_phy_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct ethnl_phy_dump_ctx *ctx = (void *)cb->ctx;
+	struct net *net = sock_net(skb->sk);
+	struct net_device *dev;
+	int ret = 0;
+
+	rtnl_lock();
+
+	if (ctx->phy_req_info->base.dev) {
+		ret = ethnl_phy_dump_one_dev(skb, ctx->phy_req_info->base.dev, cb);
+	} else {
+		for_each_netdev_dump(net, dev, ctx->ifindex) {
+			ret = ethnl_phy_dump_one_dev(skb, dev, cb);
+			if (ret)
+				break;
+
+			ctx->phy_index = 0;
+		}
+	}
+	rtnl_unlock();
+
+	if (ret == -EMSGSIZE && skb->len)
+		return skb->len;
+
+	return ret;
+}
+
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:28 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:28 +0100
Subject: [PATCH net-next v7 11/13] net: ethtool: cable-test: Target the command to the requested PHY
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-12-maxime.chevallier@bootlin.com>

Cable testing is a PHY-specific command. Instead of targeting the command
towards dev->phydev, use the request to pick the targeted PHY.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V7: No changes
V6: Use dedicated policy
V5: Added Andrew's R-b
V4: No changes
V3: No changes
V2: New patch

 net/ethtool/cabletest.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/net/ethtool/cabletest.c b/net/ethtool/cabletest.c
index 06a151165c31..536800bbc379 100644
--- a/net/ethtool/cabletest.c
+++ b/net/ethtool/cabletest.c
@@ -13,7 +13,7 @@
 
 const struct nla_policy ethnl_cable_test_act_policy[] = {
 	[ETHTOOL_A_CABLE_TEST_HEADER]		=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 };
 
 static int ethnl_cable_test_started(struct phy_device *phydev, u8 cmd)
@@ -69,7 +69,7 @@ int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info)
 		return ret;
 
 	dev = req_info.dev;
-	if (!dev->phydev) {
+	if (!req_info.phydev) {
 		ret = -EOPNOTSUPP;
 		goto out_dev_put;
 	}
@@ -85,12 +85,12 @@ int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info)
 	if (ret < 0)
 		goto out_rtnl;
 
-	ret = ops->start_cable_test(dev->phydev, info->extack);
+	ret = ops->start_cable_test(req_info.phydev, info->extack);
 
 	ethnl_ops_complete(dev);
 
 	if (!ret)
-		ethnl_cable_test_started(dev->phydev,
+		ethnl_cable_test_started(req_info.phydev,
 					 ETHTOOL_MSG_CABLE_TEST_NTF);
 
 out_rtnl:
@@ -220,7 +220,7 @@ static const struct nla_policy cable_test_tdr_act_cfg_policy[] = {
 
 const struct nla_policy ethnl_cable_test_tdr_act_policy[] = {
 	[ETHTOOL_A_CABLE_TEST_TDR_HEADER]	=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 	[ETHTOOL_A_CABLE_TEST_TDR_CFG]		= { .type = NLA_NESTED },
 };
 
@@ -321,7 +321,7 @@ int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info)
 		return ret;
 
 	dev = req_info.dev;
-	if (!dev->phydev) {
+	if (!req_info.phydev) {
 		ret = -EOPNOTSUPP;
 		goto out_dev_put;
 	}
@@ -342,12 +342,12 @@ int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info)
 	if (ret < 0)
 		goto out_rtnl;
 
-	ret = ops->start_cable_test_tdr(dev->phydev, info->extack, &cfg);
+	ret = ops->start_cable_test_tdr(req_info.phydev, info->extack, &cfg);
 
 	ethnl_ops_complete(dev);
 
 	if (!ret)
-		ethnl_cable_test_started(dev->phydev,
+		ethnl_cable_test_started(req_info.phydev,
 					 ETHTOOL_MSG_CABLE_TEST_TDR_NTF);
 
 out_rtnl:
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:30 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:30 +0100
Subject: [PATCH net-next v7 13/13] Documentation: networking: document phy_link_topology
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-14-maxime.chevallier@bootlin.com>

The newly introduced phy_link_topology tracks all ethernet PHYs that are
attached to a netdevice. Document the base principle, internal and
external APIs. As the phy_link_topology is expected to be extended, this
documentation will hold any further improvements and additions made
relative to topology handling.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V7: No changes
V6: No changes
V5: Fixed a lot of typos
V4: No changes
V3: New patch

 Documentation/networking/index.rst            |   1 +
 .../networking/phy-link-topology.rst          | 121 ++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100644 Documentation/networking/phy-link-topology.rst

diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst
index 69f3d6dcd9fd..a2c45a75a4a6 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -88,6 +88,7 @@ Contents:
    operstates
    packet_mmap
    phonet
+   phy-link-topology
    pktgen
    plip
    ppp_generic
diff --git a/Documentation/networking/phy-link-topology.rst b/Documentation/networking/phy-link-topology.rst
new file mode 100644
index 000000000000..1fd8e904ef4b
--- /dev/null
+++ b/Documentation/networking/phy-link-topology.rst
@@ -0,0 +1,121 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+PHY link topology
+=================
+
+Overview
+========
+
+The PHY link topology representation in the networking stack aims at representing
+the hardware layout for any given Ethernet link.
+
+An Ethernet Interface from userspace's point of view is nothing but a
+:c:type:`struct net_device <net_device>`, which exposes configuration options
+through the legacy ioctls and the ethool netlink commands. The base assumption
+when designing these configuration channels were that the link looked
+something like this ::
+
+  +-----------------------+        +----------+      +--------------+
+  | Ethernet Controller / |        | Ethernet |      | Connector /  |
+  |       MAC             | ------ |   PHY    | ---- |    Port      | ---... to LP
+  +-----------------------+        +----------+      +--------------+
+  struct net_device               struct phy_device
+
+Commands that needs to configure the PHY will go through the net_device.phydev
+field to reach the PHY and perform the relevant configuration.
+
+This assumption falls apart in more complex topologies that can arise when,
+for example, using SFP transceivers (although that's not the only specific case).
+
+Here, we have 2 basic scenarios. Either the MAC is able to output a serialized
+interface, that can directly be fed to an SFP cage, such as SGMII, 1000BaseX,
+10GBaseR, etc.
+
+The link topology then looks like this (when an SFP module is inserted) ::
+
+  +-----+  SGMII  +------------+
+  | MAC | ------- | SFP Module |
+  +-----+         +------------+
+
+Knowing that some modules embed a PHY, the actual link is more like ::
+
+  +-----+  SGMII   +--------------+
+  | MAC | -------- | PHY (on SFP) |
+  +-----+          +--------------+
+
+In this case, the SFP PHY is handled by phylib, and registered by phylink through
+its SFP upstream ops.
+
+Now some Ethernet controllers aren't able to output a serialized interface, so
+we can't directly connect them to an SFP cage. However, some PHYs can be used
+as media-converters, to translate the non-serialized MAC MII interface to a
+serialized MII interface fed to the SFP ::
+
+  +-----+  RGMII  +-----------------------+  SGMII  +--------------+
+  | MAC | ------- | PHY (media converter) | ------- | PHY (on SFP) |
+  +-----+         +-----------------------+         +--------------+
+
+This is where the model of having a single net_device.phydev pointer shows its
+limitations, as we now have 2 PHYs on the link.
+
+The phy_link topology framework aims at providing a way to keep track of every
+PHY on the link, for use by both kernel drivers and subsystems, but also to
+report the topology to userspace, allowing to target individual PHYs in configuration
+commands.
+
+API
+===
+
+The :c:type:`struct phy_link_topology <phy_link_topology>` is a per-netdevice
+resource, that gets initialized at netdevice creation. Once it's initialized,
+it is then possible to register PHYs to the topology through :
+
+:c:func:`phy_link_topo_add_phy`
+
+Besides registering the PHY to the topology, this call will also assign a unique
+index to the PHY, which can then be reported to userspace to refer to this PHY
+(akin to the ifindex). This index is a u32, ranging from 1 to U32_MAX. The value
+0 is reserved to indicate the PHY doesn't belong to any topology yet.
+
+The PHY can then be removed from the topology through
+
+:c:func:`phy_link_topo_del_phy`
+
+These function are already hooked into the phylib subsystem, so all PHYs that
+are linked to a net_device through :c:func:`phy_attach_direct` will automatically
+join the netdev's topology.
+
+PHYs that are on a SFP module will also be automatically registered IF the SFP
+upstream is phylink (so, no media-converter).
+
+PHY drivers that can be used as SFP upstream need to call :c:func:`phy_sfp_attach_phy`
+and :c:func:`phy_sfp_detach_phy`, which can be used as a
+.attach_phy / .detach_phy implementation for the
+:c:type:`struct sfp_upstream_ops <sfp_upstream_ops>`.
+
+UAPI
+====
+
+There exist a set of netlink commands to query the link topology from userspace,
+see ``Documentation/networking/ethtool-netlink.rst``.
+
+The whole point of having a topology representation is to assign the phyindex
+field in :c:type:`struct phy_device <phy_device>`. This index is reported to
+userspace using the ``ETHTOOL_MSG_PHY_GET`` ethtnl command. Performing a DUMP operation
+will result in all PHYs from all net_device being listed. The DUMP command
+accepts either a ``ETHTOOL_A_HEADER_DEV_INDEX`` or ``ETHTOOL_A_HEADER_DEV_NAME``
+to be passed in the request to filter the DUMP to a single net_device.
+
+The retrieved index can then be passed as a request parameter using the
+``ETHTOOL_A_HEADER_PHY_INDEX`` field in the following ethnl commands :
+
+* ``ETHTOOL_MSG_STRSET_GET`` to get the stats string set from a given PHY
+* ``ETHTOOL_MSG_CABLE_TEST_ACT`` and ``ETHTOOL_MSG_CABLE_TEST_ACT``, to perform
+  cable testing on a given PHY on the link (most likely the outermost PHY)
+* ``ETHTOOL_MSG_PSE_SET`` and ``ETHTOOL_MSG_PSE_GET`` for PHY-controlled PoE and PSE settings
+* ``ETHTOOL_MSG_PLCA_GET_CFG``, ``ETHTOOL_MSG_PLCA_SET_CFG`` and ``ETHTOOL_MSG_PLCA_GET_STATUS``
+  to set the PLCA (Physical Layer Collision Avoidance) parameters
+
+Note that the PHY index can be passed to other requests, which will silently
+ignore it if present and irrelevant.
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:27 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:27 +0100
Subject: [PATCH net-next v7 10/13] net: ethtool: pse-pd: Target the command to the requested PHY
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-11-maxime.chevallier@bootlin.com>

PSE and PD configuration is a PHY-specific command. Instead of targeting
the command towards dev->phydev, use the request to pick the targeted
PHY device.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---

V7: No changes
V6: Use dedicated policy
V5: Added-back an incorrectly removed check
V4: No changes
V3: No changes
V2: New patch

 net/ethtool/pse-pd.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index cc478af77111..be50d79122c4 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -28,15 +28,13 @@ struct pse_reply_data {
 /* PSE_GET */
 
 const struct nla_policy ethnl_pse_get_policy[ETHTOOL_A_PSE_HEADER + 1] = {
-	[ETHTOOL_A_PSE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
+	[ETHTOOL_A_PSE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy_phy),
 };
 
-static int pse_get_pse_attributes(struct net_device *dev,
+static int pse_get_pse_attributes(struct phy_device *phydev,
 				  struct netlink_ext_ack *extack,
 				  struct pse_reply_data *data)
 {
-	struct phy_device *phydev = dev->phydev;
-
 	if (!phydev) {
 		NL_SET_ERR_MSG(extack, "No PHY is attached");
 		return -EOPNOTSUPP;
@@ -64,7 +62,7 @@ static int pse_prepare_data(const struct ethnl_req_info *req_base,
 	if (ret < 0)
 		return ret;
 
-	ret = pse_get_pse_attributes(dev, info->extack, data);
+	ret = pse_get_pse_attributes(req_base->phydev, info->extack, data);
 
 	ethnl_ops_complete(dev);
 
@@ -109,7 +107,7 @@ static int pse_fill_reply(struct sk_buff *skb,
 /* PSE_SET */
 
 const struct nla_policy ethnl_pse_set_policy[ETHTOOL_A_PSE_MAX + 1] = {
-	[ETHTOOL_A_PSE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
+	[ETHTOOL_A_PSE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy_phy),
 	[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] =
 		NLA_POLICY_RANGE(NLA_U32, ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED,
 				 ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED),
@@ -124,7 +122,6 @@ ethnl_set_pse_validate(struct ethnl_req_info *req_info, struct genl_info *info)
 static int
 ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info)
 {
-	struct net_device *dev = req_info->dev;
 	struct pse_control_config config = {};
 	struct nlattr **tb = info->attrs;
 	struct phy_device *phydev;
@@ -132,7 +129,7 @@ ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info)
 	/* this values are already validated by the ethnl_pse_set_policy */
 	config.admin_cotrol = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]);
 
-	phydev = dev->phydev;
+	phydev = req_info->phydev;
 	if (!phydev) {
 		NL_SET_ERR_MSG(info->extack, "No PHY is attached");
 		return -EOPNOTSUPP;
-- 
2.43.0



From maxime.chevallier at bootlin.com  Tue Feb 13 07:04:29 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 13 Feb 2024 16:04:29 +0100
Subject: [PATCH net-next v7 12/13] net: ethtool: strset: Allow querying phy stats by index
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240213150431.1796171-13-maxime.chevallier@bootlin.com>

The ETH_SS_PHY_STATS command gets PHY statistics. Use the phydev pointer
from the ethnl request to allow query phy stats from each PHY on the
link.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V7: No changes
V6: Use dedicated policy
V5: Added Andrew's R-b
V4: No changes
V3: No changes
V2: New patch
 net/ethtool/strset.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/net/ethtool/strset.c b/net/ethtool/strset.c
index c678b484a079..edc826407564 100644
--- a/net/ethtool/strset.c
+++ b/net/ethtool/strset.c
@@ -126,7 +126,7 @@ struct strset_reply_data {
 
 const struct nla_policy ethnl_strset_get_policy[] = {
 	[ETHTOOL_A_STRSET_HEADER]	=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 	[ETHTOOL_A_STRSET_STRINGSETS]	= { .type = NLA_NESTED },
 	[ETHTOOL_A_STRSET_COUNTS_ONLY]	= { .type = NLA_FLAG },
 };
@@ -233,17 +233,18 @@ static void strset_cleanup_data(struct ethnl_reply_data *reply_base)
 }
 
 static int strset_prepare_set(struct strset_info *info, struct net_device *dev,
-			      unsigned int id, bool counts_only)
+			      struct phy_device *phydev, unsigned int id,
+			      bool counts_only)
 {
 	const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
 	const struct ethtool_ops *ops = dev->ethtool_ops;
 	void *strings;
 	int count, ret;
 
-	if (id == ETH_SS_PHY_STATS && dev->phydev &&
+	if (id == ETH_SS_PHY_STATS && phydev &&
 	    !ops->get_ethtool_phy_stats && phy_ops &&
 	    phy_ops->get_sset_count)
-		ret = phy_ops->get_sset_count(dev->phydev);
+		ret = phy_ops->get_sset_count(phydev);
 	else if (ops->get_sset_count && ops->get_strings)
 		ret = ops->get_sset_count(dev, id);
 	else
@@ -258,10 +259,10 @@ static int strset_prepare_set(struct strset_info *info, struct net_device *dev,
 		strings = kcalloc(count, ETH_GSTRING_LEN, GFP_KERNEL);
 		if (!strings)
 			return -ENOMEM;
-		if (id == ETH_SS_PHY_STATS && dev->phydev &&
+		if (id == ETH_SS_PHY_STATS && phydev &&
 		    !ops->get_ethtool_phy_stats && phy_ops &&
 		    phy_ops->get_strings)
-			phy_ops->get_strings(dev->phydev, strings);
+			phy_ops->get_strings(phydev, strings);
 		else
 			ops->get_strings(dev, id, strings);
 		info->strings = strings;
@@ -305,8 +306,8 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,
 		    !data->sets[i].per_dev)
 			continue;
 
-		ret = strset_prepare_set(&data->sets[i], dev, i,
-					 req_info->counts_only);
+		ret = strset_prepare_set(&data->sets[i], dev, req_base->phydev,
+					 i, req_info->counts_only);
 		if (ret < 0)
 			goto err_ops;
 	}
-- 
2.43.0



From Frank.li at nxp.com  Tue Feb 13 07:20:07 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 13 Feb 2024 10:20:07 -0500
Subject: [PATCH v10 03/14] PCI: imx6: Simplify reset handling by using by
 using *_FLAG_HAS_*_RESET
In-Reply-To: <ZctVVjjHYVczweta@lpieralisi>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <20240205173335.1120469-4-Frank.Li@nxp.com>
 <ZctVVjjHYVczweta@lpieralisi>
Message-ID: <ZcuIp3qlEYCePr8Y@lizhi-Precision-Tower-5810>

On Tue, Feb 13, 2024 at 12:41:10PM +0100, Lorenzo Pieralisi wrote:
> On Mon, Feb 05, 2024 at 12:33:24PM -0500, Frank Li wrote:
> > Refactors the reset handling logic in the imx6 PCI driver by adding
> > IMX6_PCIE_FLAG_HAS_*_RESET bitmask define for drvdata::flags.
> > 
> > The drvdata::flags and a bitmask ensures a cleaner and more scalable
> > switch-case structure for handling reset.
> > 
> > Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > 
> > Notes:
> >     Change from v4 to v5:
> >     - Add Mani's Reviewed-by tag
> >     - Fixed MQ_EP's flags
> >     
> >     Chagne from v3 to v4:
> >     - none
> >     Change from v2 to v3:
> >     - add Philipp's Reviewed-by tag
> >     Change from v1 to v2:
> >     - remove condition check before reset_control_(de)assert() because it is
> >       none ops if a NULL pointer pass down.
> >     - still keep condition check at probe to help identify dts file mismatch
> >       problem.
> >     
> >     Change from v1 to v2:
> >     - remove condition check before reset_control_(de)assert() because it is
> >       none ops if a NULL pointer pass down.
> >     - still keep condition check at probe to help identify dts file mismatch
> >       problem.
> > 
> >  drivers/pci/controller/dwc/pci-imx6.c | 105 ++++++++++----------------
> >  1 file changed, 39 insertions(+), 66 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> > index 59f117f855c26..a1653b58051b7 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -61,6 +61,8 @@ enum imx6_pcie_variants {
> >  #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
> >  #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
> >  #define IMX6_PCIE_FLAG_HAS_PHYDRV			BIT(3)
> > +#define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
> > +#define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
> >  
> >  #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
> >  
> > @@ -661,18 +663,10 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
> >  
> >  static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
> >  {
> > +	reset_control_assert(imx6_pcie->pciephy_reset);
> > +	reset_control_assert(imx6_pcie->apps_reset);
> > +
> >  	switch (imx6_pcie->drvdata->variant) {
> > -	case IMX7D:
> > -	case IMX8MQ:
> > -	case IMX8MQ_EP:
> > -		reset_control_assert(imx6_pcie->pciephy_reset);
> > -		fallthrough;
> > -	case IMX8MM:
> > -	case IMX8MM_EP:
> > -	case IMX8MP:
> > -	case IMX8MP_EP:
> > -		reset_control_assert(imx6_pcie->apps_reset);
> > -		break;
> >  	case IMX6SX:
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
> >  				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
> > @@ -693,6 +687,8 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> >  				   IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
> >  		break;
> > +	default:
> > +		break;
> >  	}
> >  
> >  	/* Some boards don't have PCIe reset GPIO. */
> > @@ -706,14 +702,10 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
> >  	struct dw_pcie *pci = imx6_pcie->pci;
> >  	struct device *dev = pci->dev;
> >  
> > +	reset_control_deassert(imx6_pcie->pciephy_reset);
> > +
> >  	switch (imx6_pcie->drvdata->variant) {
> > -	case IMX8MQ:
> > -	case IMX8MQ_EP:
> > -		reset_control_deassert(imx6_pcie->pciephy_reset);
> > -		break;
> >  	case IMX7D:
> > -		reset_control_deassert(imx6_pcie->pciephy_reset);
> > -
> >  		/* Workaround for ERR010728, failure of PCI-e PLL VCO to
> >  		 * oscillate, especially when cold.  This turns off "Duty-cycle
> >  		 * Corrector" and other mysterious undocumented things.
> > @@ -745,11 +737,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
> >  
> >  		usleep_range(200, 500);
> >  		break;
> > -	case IMX6Q:		/* Nothing to do */
> > -	case IMX8MM:
> > -	case IMX8MM_EP:
> > -	case IMX8MP:
> > -	case IMX8MP_EP:
> > +	default:
> >  		break;
> >  	}
> >  
> > @@ -796,16 +784,11 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
> >  				   IMX6Q_GPR12_PCIE_CTL_2,
> >  				   IMX6Q_GPR12_PCIE_CTL_2);
> >  		break;
> > -	case IMX7D:
> > -	case IMX8MQ:
> > -	case IMX8MQ_EP:
> > -	case IMX8MM:
> > -	case IMX8MM_EP:
> > -	case IMX8MP:
> > -	case IMX8MP_EP:
> > -		reset_control_deassert(imx6_pcie->apps_reset);
> > +	default:
> >  		break;
> >  	}
> > +
> > +	reset_control_deassert(imx6_pcie->apps_reset);
> 
> You rely on the fact that passing NULL is a no-op on platforms where
> this wasn't called before (valid question for other hunks in this commit),
> correct ?
> 

Thank you take time to review it. 
Yes, it follow Philipp's suggestion. Remove conditional check at v2.

Frank

> Just checking, it does not make things much cleaner but I am not opposed to
> this change.
> 
> Thanks,
> Lorenzo
> 
> >  }
> >  
> >  static void imx6_pcie_ltssm_disable(struct device *dev)
> > @@ -819,16 +802,11 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
> >  				   IMX6Q_GPR12_PCIE_CTL_2, 0);
> >  		break;
> > -	case IMX7D:
> > -	case IMX8MQ:
> > -	case IMX8MQ_EP:
> > -	case IMX8MM:
> > -	case IMX8MM_EP:
> > -	case IMX8MP:
> > -	case IMX8MP_EP:
> > -		reset_control_assert(imx6_pcie->apps_reset);
> > +	default:
> >  		break;
> >  	}
> > +
> > +	reset_control_assert(imx6_pcie->apps_reset);
> >  }
> >  
> >  static int imx6_pcie_start_link(struct dw_pcie *pci)
> > @@ -1287,38 +1265,26 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> >  					     "failed to get pcie phy\n");
> >  	}
> >  
> > +	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_APP_RESET)) {
> > +		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev, "apps");
> > +		if (IS_ERR(imx6_pcie->apps_reset))
> > +			return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
> > +					     "failed to get pcie apps reset control\n");
> > +	}
> > +
> > +	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_PHY_RESET)) {
> > +		imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, "pciephy");
> > +		if (IS_ERR(imx6_pcie->pciephy_reset))
> > +			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pciephy_reset),
> > +					     "Failed to get PCIEPHY reset control\n");
> > +	}
> > +
> >  	switch (imx6_pcie->drvdata->variant) {
> >  	case IMX8MQ:
> >  	case IMX8MQ_EP:
> >  	case IMX7D:
> >  		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> >  			imx6_pcie->controller_id = 1;
> > -
> > -		imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev,
> > -									    "pciephy");
> > -		if (IS_ERR(imx6_pcie->pciephy_reset)) {
> > -			dev_err(dev, "Failed to get PCIEPHY reset control\n");
> > -			return PTR_ERR(imx6_pcie->pciephy_reset);
> > -		}
> > -
> > -		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
> > -									 "apps");
> > -		if (IS_ERR(imx6_pcie->apps_reset)) {
> > -			dev_err(dev, "Failed to get PCIE APPS reset control\n");
> > -			return PTR_ERR(imx6_pcie->apps_reset);
> > -		}
> > -		break;
> > -	case IMX8MM:
> > -	case IMX8MM_EP:
> > -	case IMX8MP:
> > -	case IMX8MP_EP:
> > -		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
> > -									 "apps");
> > -		if (IS_ERR(imx6_pcie->apps_reset))
> > -			return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
> > -					     "failed to get pcie apps reset control\n");
> > -
> > -		break;
> >  	default:
> >  		break;
> >  	}
> > @@ -1448,13 +1414,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
> >  	},
> >  	[IMX7D] = {
> >  		.variant = IMX7D,
> > -		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
> > +		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
> > +			 IMX6_PCIE_FLAG_HAS_APP_RESET |
> > +			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
> >  		.gpr = "fsl,imx7d-iomuxc-gpr",
> >  		.clk_names = imx6q_clks,
> >  		.clks_cnt = ARRAY_SIZE(imx6q_clks),
> >  	},
> >  	[IMX8MQ] = {
> >  		.variant = IMX8MQ,
> > +		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
> > +			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
> >  		.gpr = "fsl,imx8mq-iomuxc-gpr",
> >  		.clk_names = imx8mq_clks,
> >  		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> > @@ -1471,13 +1441,16 @@ static const struct imx6_pcie_drvdata drvdata[] = {
> >  	[IMX8MP] = {
> >  		.variant = IMX8MP,
> >  		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
> > -			 IMX6_PCIE_FLAG_HAS_PHYDRV,
> > +			 IMX6_PCIE_FLAG_HAS_PHYDRV |
> > +			 IMX6_PCIE_FLAG_HAS_APP_RESET,
> >  		.gpr = "fsl,imx8mp-iomuxc-gpr",
> >  		.clk_names = imx8mm_clks,
> >  		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
> >  	},
> >  	[IMX8MQ_EP] = {
> >  		.variant = IMX8MQ_EP,
> > +		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
> > +			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
> >  		.mode = DW_PCIE_EP_TYPE,
> >  		.gpr = "fsl,imx8mq-iomuxc-gpr",
> >  		.clk_names = imx8mq_clks,
> > -- 
> > 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 linux at roeck-us.net  Tue Feb 13 07:26:40 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Tue, 13 Feb 2024 07:26:40 -0800
Subject: [PATCH net v3] net: stmmac: protect updates of 64-bit statistics
 counters
In-Reply-To: <CANn89i+4tVWezqr=BYZ5AF=9EgV2EPqhdHun=u=ga32CEJ4BXQ@mail.gmail.com>
References: <20240203190927.19669-1-petr@tesarici.cz>
 <ea1567d9-ce66-45e6-8168-ac40a47d1821@roeck-us.net>
 <Zct5qJcZw0YKx54r@xhacker>
 <CANn89i+4tVWezqr=BYZ5AF=9EgV2EPqhdHun=u=ga32CEJ4BXQ@mail.gmail.com>
Message-ID: <20d94512-c4f2-49f7-ac97-846dc24a6730@roeck-us.net>

On Tue, Feb 13, 2024 at 03:51:35PM +0100, Eric Dumazet wrote:
> On Tue, Feb 13, 2024 at 3:29?PM Jisheng Zhang <jszhang at kernel.org> wrote:
> >
> > On Sun, Feb 11, 2024 at 08:30:21PM -0800, Guenter Roeck wrote:
> > > Hi,
> > >
> > > On Sat, Feb 03, 2024 at 08:09:27PM +0100, Petr Tesarik wrote:
> > > > As explained by a comment in <linux/u64_stats_sync.h>, write side of struct
> > > > u64_stats_sync must ensure mutual exclusion, or one seqcount update could
> > > > be lost on 32-bit platforms, thus blocking readers forever. Such lockups
> > > > have been observed in real world after stmmac_xmit() on one CPU raced with
> > > > stmmac_napi_poll_tx() on another CPU.
> > > >
> > > > To fix the issue without introducing a new lock, split the statics into
> > > > three parts:
> > > >
> > > > 1. fields updated only under the tx queue lock,
> > > > 2. fields updated only during NAPI poll,
> > > > 3. fields updated only from interrupt context,
> > > >
> > > > Updates to fields in the first two groups are already serialized through
> > > > other locks. It is sufficient to split the existing struct u64_stats_sync
> > > > so that each group has its own.
> > > >
> > > > Note that tx_set_ic_bit is updated from both contexts. Split this counter
> > > > so that each context gets its own, and calculate their sum to get the total
> > > > value in stmmac_get_ethtool_stats().
> > > >
> > > > For the third group, multiple interrupts may be processed by different CPUs
> > > > at the same time, but interrupts on the same CPU will not nest. Move fields
> > > > from this group to a newly created per-cpu struct stmmac_pcpu_stats.
> > > >
> > > > Fixes: 133466c3bbe1 ("net: stmmac: use per-queue 64 bit statistics where necessary")
> > > > Link: https://lore.kernel.org/netdev/Za173PhviYg-1qIn at torres.zugschlus.de/t/
> > > > Cc: stable at vger.kernel.org
> > > > Signed-off-by: Petr Tesarik <petr at tesarici.cz>
> > >
> > > This patch results in a lockdep splat. Backtrace and bisect results attached.
> > >
> > > Guenter
> > >
> > > ---
> > > [   33.736728] ================================
> > > [   33.736805] WARNING: inconsistent lock state
> > > [   33.736953] 6.8.0-rc4 #1 Tainted: G                 N
> > > [   33.737080] --------------------------------
> > > [   33.737155] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
> > > [   33.737309] kworker/0:2/39 [HC1[1]:SC0[2]:HE0:SE0] takes:
> > > [   33.737459] ef792074 (&syncp->seq#2){?...}-{0:0}, at: sun8i_dwmac_dma_interrupt+0x9c/0x28c
> > > [   33.738206] {HARDIRQ-ON-W} state was registered at:
> > > [   33.738318]   lock_acquire+0x11c/0x368
> > > [   33.738431]   __u64_stats_update_begin+0x104/0x1ac
> > > [   33.738525]   stmmac_xmit+0x4d0/0xc58
> >
> > interesting lockdep splat...
> > stmmac_xmit() operates on txq_stats->q_syncp, while the
> > sun8i_dwmac_dma_interrupt() operates on pcpu's priv->xstats.pcpu_stats
> > they are different syncp. so how does lockdep splat happen.
> 
> Right, I do not see anything obvious yet.

Wild guess: I think it maybe saying that due to

	inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.

the critical code may somehow be interrupted and, while handling the
interrupt, try to acquire the same lock again.

Guenter


From dlechner at baylibre.com  Tue Feb 13 07:27:58 2024
From: dlechner at baylibre.com (David Lechner)
Date: Tue, 13 Feb 2024 09:27:58 -0600
Subject: [PATCH 5/5] iio: adc: ad7380: use spi_optimize_message()
In-Reply-To: <c06dfa1ecf88b07ef467ad7c08667d0cab400613.camel@gmail.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
 <20240212-mainline-spi-precook-message-v1-5-a2373cd72d36@baylibre.com> <c06dfa1ecf88b07ef467ad7c08667d0cab400613.camel@gmail.com>
Message-ID: <CAMknhBEU=iMzpE_P0KePL4cZZktBOGHRXaEox5a7XcVjXDT+Dg@mail.gmail.com>

On Tue, Feb 13, 2024 at 3:47?AM Nuno S? <noname.nuno at gmail.com> wrote:
>
> On Mon, 2024-02-12 at 17:26 -0600, David Lechner wrote:
> > This modifies the ad7380 ADC driver to use spi_optimize_message() to
> > optimize the SPI message for the buffered read operation. Since buffered
> > reads reuse the same SPI message for each read, this can improve
> > performance by reducing the overhead of setting up some parts the SPI
> > message in each spi_sync() call.
> >
> > Signed-off-by: David Lechner <dlechner at baylibre.com>
> > ---
> >  drivers/iio/adc/ad7380.c | 52 +++++++++++++++++++++++++++++++++++++++++------
> > -
> >  1 file changed, 45 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
> > index abd746aef868..5c5d2642a474 100644
> > --- a/drivers/iio/adc/ad7380.c
> > +++ b/drivers/iio/adc/ad7380.c
> > @@ -133,6 +133,7 @@ struct ad7380_state {
> >       struct spi_device *spi;
> >       struct regulator *vref;
> >       struct regmap *regmap;
> > +     struct spi_message *msg;
> >       /*
> >        * DMA (thus cache coherency maintenance) requires the
> >        * transfer buffers to live in their own cache lines.
> > @@ -231,19 +232,55 @@ static int ad7380_debugfs_reg_access(struct iio_dev
> > *indio_dev, u32 reg,
> >       return ret;
> >  }
> >
> > +static int ad7380_buffer_preenable(struct iio_dev *indio_dev)
> > +{
> > +     struct ad7380_state *st = iio_priv(indio_dev);
> > +     struct spi_transfer *xfer;
> > +     int ret;
> > +
> > +     st->msg = spi_message_alloc(1, GFP_KERNEL);
> > +     if (!st->msg)
> > +             return -ENOMEM;
> > +
> > +     xfer = list_first_entry(&st->msg->transfers, struct spi_transfer,
> > +                             transfer_list);
> > +
> > +     xfer->bits_per_word = st->chip_info->channels[0].scan_type.realbits;
> > +     xfer->len = 4;
> > +     xfer->rx_buf = st->scan_data.raw;
> > +
> > +     ret = spi_optimize_message(st->spi, st->msg);
> > +     if (ret) {
> > +             spi_message_free(st->msg);
> > +             return ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int ad7380_buffer_postdisable(struct iio_dev *indio_dev)
> > +{
> > +     struct ad7380_state *st = iio_priv(indio_dev);
> > +
> > +     spi_unoptimize_message(st->msg);
> > +     spi_message_free(st->msg);
> > +
> > +     return 0;
> > +}
> > +
>
> Not such a big deal but unless I'm missing something we could have the
> spi_message (+ the transfer) statically allocated in struct ad7380_state and do
> the optimize only once at probe (naturally with proper devm action for
> unoptimize). Then we would not need to this for every buffer enable + disable. I
> know in terms of performance it won't matter but it would be less code I guess.
>
> Am I missing something?

No, your understanding is correct for the current state of everything
in this series. So, we could do as you suggest, but I have a feeling
that future additions to this driver might require that it gets
changed back this way eventually.


From ryan.roberts at arm.com  Tue Feb 13 07:29:24 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 15:29:24 +0000
Subject: [PATCH v5 19/25] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <55a1e0ef-14b3-4311-b2aa-a6add76fa2ed@redhat.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-20-ryan.roberts@arm.com>
 <ZcoIVypNwOPIX30w@FVFF77S0Q05N>
 <c899f252-dbf3-4e7b-8342-b5a5180486cd@arm.com>
 <a91cfe1c-289e-4828-8cfc-be34eb69a71b@redhat.com>
 <502a3ea7-fd86-4314-8292-c7999eda92eb@arm.com>
 <427ba87a-7dd0-4f3e-861f-fe6946b7cd97@redhat.com>
 <abe814c9-71f3-4d7d-bdc8-9dd930d6f0b2@arm.com>
 <55a1e0ef-14b3-4311-b2aa-a6add76fa2ed@redhat.com>
Message-ID: <b5d26583-386b-41b4-83d1-30500e6837a9@arm.com>

On 12/02/2024 16:24, David Hildenbrand wrote:
> On 12.02.24 16:34, Ryan Roberts wrote:
>> On 12/02/2024 15:26, David Hildenbrand wrote:
>>> On 12.02.24 15:45, Ryan Roberts wrote:
>>>> On 12/02/2024 13:54, David Hildenbrand wrote:
>>>>>>> If so, I wonder if we could instead do that comparison modulo the
>>>>>>> access/dirty
>>>>>>> bits,
>>>>>>
>>>>>> I think that would work - but will need to think a bit more on it.
>>>>>>
>>>>>>> and leave ptep_get_lockless() only reading a single entry?
>>>>>>
>>>>>> I think we will need to do something a bit less fragile. ptep_get() does
>>>>>> collect
>>>>>> the access/dirty bits so its confusing if ptep_get_lockless() doesn't
>>>>>> IMHO. So
>>>>>> we will likely want to rename the function and make its documentation
>>>>>> explicit
>>>>>> that it does not return those bits.
>>>>>>
>>>>>> ptep_get_lockless_noyoungdirty()? yuk... Any ideas?
>>>>>>
>>>>>> Of course if I could convince you the current implementation is safe, I
>>>>>> might be
>>>>>> able to sidestep this optimization until a later date?
>>>>>
>>>>> As discussed (and pointed out abive), there might be quite some callsites
>>>>> where
>>>>> we don't really care about uptodate accessed/dirty bits -- where ptep_get() is
>>>>> used nowadays.
>>>>>
>>>>> One way to approach that I had in mind was having an explicit interface:
>>>>>
>>>>> ptep_get()
>>>>> ptep_get_uptodate()
>>>>> ptep_get_lockless()
>>>>> ptep_get_lockless_uptodate()
>>>>
>>>> Yes, I like the direction of this. I guess we anticipate that call sites
>>>> requiring the "_uptodate" variant will be the minority so it makes sense to use
>>>> the current names for the "_not_uptodate" variants? But to do a slow migration,
>>>> it might be better/safer to have the weaker variant use the new name - that
>>>> would allow us to downgrade one at a time?
>>>
>>> Yes, I was primarily struggling with names. Likely it makes sense to either have
>>> two completely new function names, or use the new name only for the "faster but
>>> less precise" variant.
>>>
>>>>
>>>>>
>>>>> Especially the last one might not be needed.
>>>> I've done a scan through the code and agree with Mark's original conclusions.
>>>> Additionally, huge_pte_alloc() (which isn't used for arm64) doesn't rely on
>>>> access/dirty info. So I think I could migrate everything to the weaker variant
>>>> fairly easily.
>>>>
>>>>>
>>>>> Futher, "uptodate" might not be the best choice because of PageUptodate() and
>>>>> friends. But it's better than "youngdirty"/"noyoungdirty" IMHO.
>>>>
>>>> Certainly agree with "noyoungdirty" being a horrible name. How about "_sync" /
>>>> "_nosync"?
>>>
>>> I could live with
>>>
>>> ptep_get_sync()
>>> ptep_get_nosync()
>>>
>>> with proper documentation :)
>>
>> but could you live with:
>>
>> ptep_get()
>> ptep_get_nosync()
>> ptep_get_lockless_nosync()
>>
>> ?
>>
>> So leave the "slower, more precise" version with the existing name.
> 
> Sure.
> 

I'm just implementing this (as a separate RFC), and had an alternative idea for
naming/semantics:

ptep_get()
ptep_get_norecency()
ptep_get_lockless()
ptep_get_lockless_norecency()

The "_norecency" versions explicitly clear the access/dirty bits. This is useful
for the "compare to original pte to check we are not racing" pattern:

pte = ptep_get_lockless_norecency(ptep)
...
<lock>
if (!pte_same(pte, ptep_get_norecency(ptep)))
	// RACE!
...
<unlock>

With the "_nosync" semantic, the access/dirty bits may or may not be set, so the
user has to explicitly clear them to do the comparison. (although I considered a
pte_same_nosync() that would clear the bits for you - but that name is pretty naff).

Although the _norecency semantic requires always explicitly clearing the bits,
so may be infinitesimally slower, it gives a very clear expectation that the
access/dirty bits are always clear and I think that's conveyed well in the name too.

Thoughts?



From lpieralisi at kernel.org  Tue Feb 13 07:31:22 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Tue, 13 Feb 2024 16:31:22 +0100
Subject: [PATCH v10 01/14] PCI: imx6: Simplify clock handling by using
 clk_bulk*() function
In-Reply-To: <20240205173335.1120469-2-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <20240205173335.1120469-2-Frank.Li@nxp.com>
Message-ID: <ZcuLSkvPuyMXsQeD@lpieralisi>

On Mon, Feb 05, 2024 at 12:33:22PM -0500, Frank Li wrote:
> Refector the clock handling logic. Add 'clk_names' define in drvdata. Use
> clk_bulk*() api simplify the code.
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> 
> Notes:
>     Change from v9 to v10
>     - fixed missed delete a case, which need failthrough to next one.
>     Change from v8 to v9
>     - change clks names
>     - Add Manivannan's review tag
>     
>     Change from v7 to v8
>     - update comment message
>     - using ARRAY_SIZE to count clk_names.
>     Change from v6 to v7
>     - none
>     Change from v4 to v5
>     - update commit message
>     - direct using clk name list, instead of macro
>     - still keep caculate clk list count because sizeof return pre allocated
>     array size.
>     
>     Change from v3 to v4
>     - using clk_bulk_*() API
>     Change from v1 to v3
>     - none
>     
>     Change from v4 to v5
>     - update commit message
>     - direct using clk name list, instead of macro
>     - still keep caculate clk list count because sizeof return pre allocated
>     array size.
>     
>     Change from v3 to v4
>     - using clk_bulk_*() API
>     Change from v1 to v3
>     - none
>     
>     Change from v8 to v9
>     - change clks names
>     - Add Manivannan's review tag
>     
>     Change from v7 to v8
>     - update comment message
>     - using ARRAY_SIZE to count clk_names.
>     Change from v6 to v7
>     - none
>     Change from v4 to v5
>     - update commit message
>     - direct using clk name list, instead of macro
>     - still keep caculate clk list count because sizeof return pre allocated
>     array size.
>     
>     Change from v3 to v4
>     - using clk_bulk_*() API
>     Change from v1 to v3
>     - none
>     
>     Change from v4 to v5
>     - update commit message
>     - direct using clk name list, instead of macro
>     - still keep caculate clk list count because sizeof return pre allocated
>     array size.
>     
>     Change from v3 to v4
>     - using clk_bulk_*() API
>     Change from v1 to v3
>     - none
> 
>  drivers/pci/controller/dwc/pci-imx6.c | 138 ++++++++++----------------
>  1 file changed, 50 insertions(+), 88 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 74703362aeec7..82854e94c5621 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -61,12 +61,16 @@ enum imx6_pcie_variants {
>  #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
>  #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
>  
> +#define IMX6_PCIE_MAX_CLKS       6
> +
>  struct imx6_pcie_drvdata {
>  	enum imx6_pcie_variants variant;
>  	enum dw_pcie_device_mode mode;
>  	u32 flags;
>  	int dbi_length;
>  	const char *gpr;
> +	const char * const *clk_names;
> +	const u32 clks_cnt;
>  };
>  
>  struct imx6_pcie {
> @@ -74,11 +78,7 @@ struct imx6_pcie {
>  	int			reset_gpio;
>  	bool			gpio_active_high;
>  	bool			link_is_up;
> -	struct clk		*pcie_bus;
> -	struct clk		*pcie_phy;
> -	struct clk		*pcie_inbound_axi;
> -	struct clk		*pcie;
> -	struct clk		*pcie_aux;
> +	struct clk_bulk_data	clks[IMX6_PCIE_MAX_CLKS];

Why can't you allocate this dynamically ?

>  	struct regmap		*iomuxc_gpr;
>  	u16			msi_ctrl;
>  	u32			controller_id;
> @@ -407,13 +407,18 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
>  
>  static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
>  {
> -	unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy);
> +	unsigned long phy_rate = 0;
>  	int mult, div;
>  	u16 val;
> +	int i;
>  
>  	if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY))
>  		return 0;
>  
> +	for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
> +		if (strncmp(imx6_pcie->clks[i].id, "pcie_phy", 8) == 0)
> +			phy_rate = clk_get_rate(imx6_pcie->clks[i].clk);
> +
>  	switch (phy_rate) {
>  	case 125000000:
>  		/*
> @@ -550,19 +555,11 @@ static int imx6_pcie_attach_pd(struct device *dev)
>  
>  static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
>  {
> -	struct dw_pcie *pci = imx6_pcie->pci;
> -	struct device *dev = pci->dev;
>  	unsigned int offset;
>  	int ret = 0;
>  
>  	switch (imx6_pcie->drvdata->variant) {
>  	case IMX6SX:
> -		ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
> -		if (ret) {
> -			dev_err(dev, "unable to enable pcie_axi clock\n");
> -			break;
> -		}
> -
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
>  				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
>  		break;
> @@ -589,12 +586,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
>  	case IMX8MQ_EP:
>  	case IMX8MP:
>  	case IMX8MP_EP:
> -		ret = clk_prepare_enable(imx6_pcie->pcie_aux);
> -		if (ret) {
> -			dev_err(dev, "unable to enable pcie_aux clock\n");
> -			break;
> -		}
> -
>  		offset = imx6_pcie_grp_offset(imx6_pcie);
>  		/*
>  		 * Set the over ride low and enabled
> @@ -615,9 +606,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
>  static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
>  {
>  	switch (imx6_pcie->drvdata->variant) {
> -	case IMX6SX:
> -		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
> -		break;
>  	case IMX6QP:
>  	case IMX6Q:
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> @@ -631,14 +619,6 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
>  				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
>  				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
>  		break;
> -	case IMX8MM:
> -	case IMX8MM_EP:
> -	case IMX8MQ:
> -	case IMX8MQ_EP:
> -	case IMX8MP:
> -	case IMX8MP_EP:
> -		clk_disable_unprepare(imx6_pcie->pcie_aux);
> -		break;
>  	default:
>  		break;
>  	}
> @@ -650,23 +630,9 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
>  	struct device *dev = pci->dev;
>  	int ret;
>  
> -	ret = clk_prepare_enable(imx6_pcie->pcie_phy);
> -	if (ret) {
> -		dev_err(dev, "unable to enable pcie_phy clock\n");
> +	ret = clk_bulk_prepare_enable(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
> +	if (ret)
>  		return ret;
> -	}
> -
> -	ret = clk_prepare_enable(imx6_pcie->pcie_bus);
> -	if (ret) {
> -		dev_err(dev, "unable to enable pcie_bus clock\n");
> -		goto err_pcie_bus;
> -	}
> -
> -	ret = clk_prepare_enable(imx6_pcie->pcie);
> -	if (ret) {
> -		dev_err(dev, "unable to enable pcie clock\n");
> -		goto err_pcie;
> -	}
>  
>  	ret = imx6_pcie_enable_ref_clk(imx6_pcie);
>  	if (ret) {
> @@ -679,11 +645,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
>  	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);
> +	clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
>  
>  	return ret;
>  }
> @@ -691,9 +653,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
>  static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
>  {
>  	imx6_pcie_disable_ref_clk(imx6_pcie);
> -	clk_disable_unprepare(imx6_pcie->pcie);
> -	clk_disable_unprepare(imx6_pcie->pcie_bus);
> -	clk_disable_unprepare(imx6_pcie->pcie_phy);
> +	clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
>  }
>  
>  static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
> @@ -1252,6 +1212,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>  	struct device_node *node = dev->of_node;
>  	int ret;
>  	u16 val;
> +	int i;
>  
>  	imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
>  	if (!imx6_pcie)
> @@ -1305,32 +1266,20 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>  		return imx6_pcie->reset_gpio;
>  	}
>  
> -	/* Fetch clocks */
> -	imx6_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus");
> -	if (IS_ERR(imx6_pcie->pcie_bus))
> -		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_bus),
> -				     "pcie_bus clock source missing or invalid\n");
> +	if (imx6_pcie->drvdata->clks_cnt >= IMX6_PCIE_MAX_CLKS)
> +		return dev_err_probe(dev, -ENOMEM, "clks_cnt is too big\n");

Same question as above, this should not fail if the clks array is
dynamically allocated according to imx6_pcie->drvdata->clks_cnt.

Lorenzo

>  
> -	imx6_pcie->pcie = devm_clk_get(dev, "pcie");
> -	if (IS_ERR(imx6_pcie->pcie))
> -		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie),
> -				     "pcie clock source missing or invalid\n");
> +	for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
> +		imx6_pcie->clks[i].id = imx6_pcie->drvdata->clk_names[i];
> +
> +	/* Fetch clocks */
> +	ret = devm_clk_bulk_get(dev, imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
> +	if (ret)
> +		return ret;
>  
>  	switch (imx6_pcie->drvdata->variant) {
> -	case IMX6SX:
> -		imx6_pcie->pcie_inbound_axi = devm_clk_get(dev,
> -							   "pcie_inbound_axi");
> -		if (IS_ERR(imx6_pcie->pcie_inbound_axi))
> -			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_inbound_axi),
> -					     "pcie_inbound_axi clock missing or invalid\n");
> -		break;
>  	case IMX8MQ:
>  	case IMX8MQ_EP:
> -		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
> -		if (IS_ERR(imx6_pcie->pcie_aux))
> -			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
> -					     "pcie_aux clock source missing or invalid\n");
> -		fallthrough;
>  	case IMX7D:
>  		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
>  			imx6_pcie->controller_id = 1;
> @@ -1353,10 +1302,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>  	case IMX8MM_EP:
>  	case IMX8MP:
>  	case IMX8MP_EP:
> -		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
> -		if (IS_ERR(imx6_pcie->pcie_aux))
> -			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
> -					     "pcie_aux clock source missing or invalid\n");
>  		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
>  									 "apps");
>  		if (IS_ERR(imx6_pcie->apps_reset))
> @@ -1372,14 +1317,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>  	default:
>  		break;
>  	}
> -	/* Don't fetch the pcie_phy clock, if it has abstract PHY driver */
> -	if (imx6_pcie->phy == NULL) {
> -		imx6_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy");
> -		if (IS_ERR(imx6_pcie->pcie_phy))
> -			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_phy),
> -					     "pcie_phy clock source missing or invalid\n");
> -	}
> -
>  
>  	/* Grab turnoff reset */
>  	imx6_pcie->turnoff_reset = devm_reset_control_get_optional_exclusive(dev, "turnoff");
> @@ -1470,6 +1407,11 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
>  	imx6_pcie_assert_core_reset(imx6_pcie);
>  }
>  
> +static const char * const imx6q_clks[] = {"pcie_bus", "pcie", "pcie_phy"};
> +static const char * const imx8mm_clks[] = {"pcie_bus", "pcie", "pcie_aux"};
> +static const char * const imx8mq_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_aux"};
> +static const char * const imx6sx_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_inbound_axi"};
> +
>  static const struct imx6_pcie_drvdata drvdata[] = {
>  	[IMX6Q] = {
>  		.variant = IMX6Q,
> @@ -1477,6 +1419,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
>  		.dbi_length = 0x200,
>  		.gpr = "fsl,imx6q-iomuxc-gpr",
> +		.clk_names = imx6q_clks,
> +		.clks_cnt = ARRAY_SIZE(imx6q_clks),
>  	},
>  	[IMX6SX] = {
>  		.variant = IMX6SX,
> @@ -1484,6 +1428,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE |
>  			 IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
>  		.gpr = "fsl,imx6q-iomuxc-gpr",
> +		.clk_names = imx6sx_clks,
> +		.clks_cnt = ARRAY_SIZE(imx6sx_clks),
>  	},
>  	[IMX6QP] = {
>  		.variant = IMX6QP,
> @@ -1492,40 +1438,56 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  			 IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
>  		.dbi_length = 0x200,
>  		.gpr = "fsl,imx6q-iomuxc-gpr",
> +		.clk_names = imx6q_clks,
> +		.clks_cnt = ARRAY_SIZE(imx6q_clks),
>  	},
>  	[IMX7D] = {
>  		.variant = IMX7D,
>  		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
>  		.gpr = "fsl,imx7d-iomuxc-gpr",
> +		.clk_names = imx6q_clks,
> +		.clks_cnt = ARRAY_SIZE(imx6q_clks),
>  	},
>  	[IMX8MQ] = {
>  		.variant = IMX8MQ,
>  		.gpr = "fsl,imx8mq-iomuxc-gpr",
> +		.clk_names = imx8mq_clks,
> +		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
>  	},
>  	[IMX8MM] = {
>  		.variant = IMX8MM,
>  		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
>  		.gpr = "fsl,imx8mm-iomuxc-gpr",
> +		.clk_names = imx8mm_clks,
> +		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
>  	},
>  	[IMX8MP] = {
>  		.variant = IMX8MP,
>  		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
>  		.gpr = "fsl,imx8mp-iomuxc-gpr",
> +		.clk_names = imx8mm_clks,
> +		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
>  	},
>  	[IMX8MQ_EP] = {
>  		.variant = IMX8MQ_EP,
>  		.mode = DW_PCIE_EP_TYPE,
>  		.gpr = "fsl,imx8mq-iomuxc-gpr",
> +		.clk_names = imx8mq_clks,
> +		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
>  	},
>  	[IMX8MM_EP] = {
>  		.variant = IMX8MM_EP,
>  		.mode = DW_PCIE_EP_TYPE,
>  		.gpr = "fsl,imx8mm-iomuxc-gpr",
> +		.clk_names = imx8mm_clks,
> +		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
>  	},
>  	[IMX8MP_EP] = {
>  		.variant = IMX8MP_EP,
>  		.mode = DW_PCIE_EP_TYPE,
>  		.gpr = "fsl,imx8mp-iomuxc-gpr",
> +		.clk_names = imx8mm_clks,
> +		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
>  	},
>  };
>  
> -- 
> 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 broonie at kernel.org  Tue Feb 13 07:32:44 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 15:32:44 +0000
Subject: [PATCH 0/2] arm64/fp: Initialise all bits in vector control
 registers to known values
Message-ID: <20240213-arm64-fp-init-vec-cr-v1-0-7e7c2d584f26@kernel.org>

We currently do read/modify/write sequences whenever we update fields in
ZCR_EL1 and SMCR_EL1 so fields we are not explicitly handling will not
be initialised to known values, fix this.  The EL2 registers are already
fully configured.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
Mark Brown (2):
      arm64/sve: Ensure that all fields in ZCR_EL1 are set to known values
      arm64/sme: Ensure that all fields in SMCR_EL1 are set to known values

 arch/arm64/kernel/fpsimd.c | 5 +++++
 1 file changed, 5 insertions(+)
---
base-commit: 54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478
change-id: 20240212-arm64-fp-init-vec-cr-018449327500

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From broonie at kernel.org  Tue Feb 13 07:32:45 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 15:32:45 +0000
Subject: [PATCH 1/2] arm64/sve: Ensure that all fields in ZCR_EL1 are set
 to known values
In-Reply-To: <20240213-arm64-fp-init-vec-cr-v1-0-7e7c2d584f26@kernel.org>
References: <20240213-arm64-fp-init-vec-cr-v1-0-7e7c2d584f26@kernel.org>
Message-ID: <20240213-arm64-fp-init-vec-cr-v1-1-7e7c2d584f26@kernel.org>

At present nothing in our CPU initialisation code ever sets unknown fields
in ZCR_EL1 to known values, all updates to ZCR_EL1 are read/modify/write
sequences for LEN. All the unknown fields are RES0, explicitly initialise
them as such to avoid future surprises.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a5dc6f764195..cc3c9ad877a8 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1134,6 +1134,8 @@ void cpu_enable_sve(const struct arm64_cpu_capabilities *__always_unused p)
 {
 	write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_ZEN_EL1EN, CPACR_EL1);
 	isb();
+
+	write_sysreg_s(0, SYS_ZCR_EL1);
 }
 
 void __init sve_setup(void)

-- 
2.30.2



From broonie at kernel.org  Tue Feb 13 07:32:46 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 15:32:46 +0000
Subject: [PATCH 2/2] arm64/sme: Ensure that all fields in SMCR_EL1 are set
 to known values
In-Reply-To: <20240213-arm64-fp-init-vec-cr-v1-0-7e7c2d584f26@kernel.org>
References: <20240213-arm64-fp-init-vec-cr-v1-0-7e7c2d584f26@kernel.org>
Message-ID: <20240213-arm64-fp-init-vec-cr-v1-2-7e7c2d584f26@kernel.org>

At present nothing in our CPU initialisation code ever sets unknown fields
in SMCR_EL1 to known values, all updates to SMCR_EL1 are read/modify/write
sequences. All the unknown fields are RES0, explicitly initialise them as
such to avoid future surprises.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index cc3c9ad877a8..f96907b813fa 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1247,6 +1247,9 @@ void cpu_enable_sme(const struct arm64_cpu_capabilities *__always_unused p)
 	write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_SMEN_EL1EN, CPACR_EL1);
 	isb();
 
+	/* Ensure all bits in SMCR are set to known values */
+	write_sysreg_s(0, SYS_SMCR_EL1);
+
 	/* Allow EL0 to access TPIDR2 */
 	write_sysreg(read_sysreg(SCTLR_EL1) | SCTLR_ELx_ENTP2, SCTLR_EL1);
 	isb();

-- 
2.30.2



From Frank.li at nxp.com  Tue Feb 13 07:35:50 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 13 Feb 2024 10:35:50 -0500
Subject: [PATCH v9 16/16] PCI: imx6: Add iMX95 Endpoint (EP) support
In-Reply-To: <f1b8c49b-0d13-4a3e-9696-75a370ac0e59@arm.com>
References: <20240119171122.3057511-1-Frank.Li@nxp.com>
 <20240119171122.3057511-17-Frank.Li@nxp.com>
 <ZctGs2d9ccnmYysL@lpieralisi>
 <f1b8c49b-0d13-4a3e-9696-75a370ac0e59@arm.com>
Message-ID: <ZcuMVv931r97iWm/@lizhi-Precision-Tower-5810>

On Tue, Feb 13, 2024 at 01:23:45PM +0000, Robin Murphy wrote:
> On 13/02/2024 10:38 am, Lorenzo Pieralisi wrote:
> > [+Christoph, Robin - just checking with you if the DMA mask handling is
> > what you expect from drivers, don't want to merge code that breaks your
> > expectations]
> 
> I don't really understand how all the endpoint stuff fits together, but my
> hunch would be that setting the DMA masks in imx6_add_pcie_ep() might be
> more sensible, unless perhaps there's an implied intent to account for eDMA

pci_epc_mem_alloc_addr() ioremap PCIe EP side outbound memory. Without it
it will be mapped to lower 4G space / SWIOTLB. Generally, outbound is quite
big in some chips, such imx95, (4GB). So it need set dmamask to make sure
it can be mapped to > 4G space.

> channels in root complex mode as well (and so assuming that eDMA and
> endpoint mode play nicely together sharing the same platform device) - as

There are eDMA in host side, but still not find a usecase yet. So it is not
enabled yet. I just need add flags IMX6_PCIE_FLAG_SUPPORT_64BIT in imx95
host if needs.

Anyways, if you like, I can move it into imx6_add_pcie_ep() at next
version.

Frank

> we've discussed before across various threads, setting DMA masks for a host
> bridge itself doesn't really make sense (and hence it leaves the gap where
> we can get away with co-opting them for the MSI address hack); it's any
> additional DMA-initiating functionality within a root complex which should
> own that responsibility.
> 
> FWIW it looks like the equivalent change for Layerscape *is* specific to
> endpoint mode, but I don't know how relevant that is to i.MX given that
> they're unrelated hardware configurations.

Previous i.MX PCI outbound space < 4G space. And only have 32bit address
access in system bus. So needn't set DMA mask. i.MX95 change it and PCIe
part is inheriate from layerscape.

Frank
> 
> Thanks,
> Robin.
> 
> > On Fri, Jan 19, 2024 at 12:11:22PM -0500, Frank Li wrote:
> > > Add iMX95 EP support and add 64bit address support. Internal bus bridge for
> > > PCI support 64bit dma address in iMX95. Hence, call
> > > dma_set_mask_and_coherent() to set 64 bit DMA mask.
> > > 
> > > Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > > ---
> > > 
> > > Notes:
> > >      Change from v8 to v9
> > >      - update fixme comments
> > >      - update BAR1 comments
> > >      - Add mani's review tag
> > >      Change from v7 to v8
> > >      - Update commit message
> > >      - Using Fixme
> > >      - Update clks_cnts by ARRAY_SIZE
> > >      Change from v4 to v7
> > >      - none
> > >      Change from v3 to v4
> > >      - change align to 4k for imx95
> > >      Change from v1 to v3
> > >      - new patches at v3
> > > 
> > >   drivers/pci/controller/dwc/pci-imx6.c | 47 +++++++++++++++++++++++++++
> > >   1 file changed, 47 insertions(+)
> > > 
> > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> > > index bbaa45c08323b..7889318f6555a 100644
> > > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > > @@ -75,6 +75,7 @@ enum imx6_pcie_variants {
> > >   	IMX8MQ_EP,
> > >   	IMX8MM_EP,
> > >   	IMX8MP_EP,
> > > +	IMX95_EP,
> > >   };
> > >   #define IMX6_PCIE_FLAG_IMX6_PHY			BIT(0)
> > > @@ -84,6 +85,7 @@ enum imx6_pcie_variants {
> > >   #define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
> > >   #define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
> > >   #define IMX6_PCIE_FLAG_HAS_SERDES		BIT(6)
> > > +#define IMX6_PCIE_FLAG_SUPPORT_64BIT		BIT(7)
> > >   #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
> > > @@ -616,6 +618,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
> > >   		break;
> > >   	case IMX7D:
> > >   	case IMX95:
> > > +	case IMX95_EP:
> > >   		break;
> > >   	case IMX8MM:
> > >   	case IMX8MM_EP:
> > > @@ -1050,6 +1053,23 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
> > >   	.align = SZ_64K,
> > >   };
> > > +/*
> > > + * BAR#	| Default BAR enable	| Default BAR Type	| Default BAR Size	| BAR Sizing Scheme
> > > + * ================================================================================================
> > > + * BAR0	| Enable		| 64-bit		| 1 MB			| Programmable Size
> > > + * BAR1	| Disable		| 32-bit		| 64 KB			| Fixed Size
> > > + *        BAR1 should be disabled if BAR0 is 64bit.
> > > + * BAR2	| Enable		| 32-bit		| 1 MB			| Programmable Size
> > > + * BAR3	| Enable		| 32-bit		| 64 KB			| Programmable Size
> > > + * BAR4	| Enable		| 32-bit		| 1M			| Programmable Size
> > > + * BAR5	| Enable		| 32-bit		| 64 KB			| Programmable Size
> > > + */
> > > +static const struct pci_epc_features imx95_pcie_epc_features = {
> > > +	.msi_capable = true,
> > > +	.bar_fixed_size[1] = SZ_64K,
> > > +	.align = SZ_4K,
> > > +};
> > > +
> > >   static const struct pci_epc_features*
> > >   imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
> > >   {
> > > @@ -1092,6 +1112,15 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
> > >   	pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset;
> > > +	/*
> > > +	 * FIXME: Ideally, dbi2 base address should come from DT. But since only IMX95 is defining
> > > +	 * "dbi2" in DT, "dbi_base2" is set to NULL here for that platform alone so that the DWC
> > > +	 * core code can fetch that from DT. But once all platform DTs were fixed, this and the
> > > +	 * above "dbi_base2" setting should be removed.
> > > +	 */
> > > +	if (imx6_pcie->drvdata->variant == IMX95_EP)
> > > +		pci->dbi_base2 = NULL;
> > > +
> > >   	ret = dw_pcie_ep_init(ep);
> > >   	if (ret) {
> > >   		dev_err(dev, "failed to initialize endpoint\n");
> > > @@ -1345,6 +1374,9 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> > >   					     "unable to find iomuxc registers\n");
> > >   	}
> > > +	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_SUPPORT_64BIT))
> > > +		dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
> > > +
> > >   	/* Grab PCIe PHY Tx Settings */
> > >   	if (of_property_read_u32(node, "fsl,tx-deemph-gen1",
> > >   				 &imx6_pcie->tx_deemph_gen1))
> > > @@ -1563,6 +1595,20 @@ static const struct imx6_pcie_drvdata drvdata[] = {
> > >   		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
> > >   		.epc_features = &imx8m_pcie_epc_features,
> > >   	},
> > > +	[IMX95_EP] = {
> > > +		.variant = IMX95_EP,
> > > +		.flags = IMX6_PCIE_FLAG_HAS_SERDES |
> > > +			 IMX6_PCIE_FLAG_SUPPORT_64BIT,
> > > +		.clk_names = imx8mq_clks,
> > > +		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> > > +		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> > > +		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
> > > +		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
> > > +		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> > > +		.init_phy = imx95_pcie_init_phy,
> > > +		.epc_features = &imx95_pcie_epc_features,
> > > +		.mode = DW_PCIE_EP_TYPE,
> > > +	},
> > >   };
> > >   static const struct of_device_id imx6_pcie_of_match[] = {
> > > @@ -1577,6 +1623,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
> > >   	{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
> > >   	{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
> > >   	{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
> > > +	{ .compatible = "fsl,imx95-pcie-ep", .data = &drvdata[IMX95_EP], },
> > >   	{},
> > >   };
> > > -- 
> > > 2.34.1
> > > 


From smostafa at google.com  Tue Feb 13 07:37:43 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Tue, 13 Feb 2024 15:37:43 +0000
Subject: [PATCH v5 03/17] iommu/arm-smmu-v3: Move
 arm_smmu_rmr_install_bypass_ste()
In-Reply-To: <3-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <3-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <ZcuMx0w6MDWpkLne@google.com>

Hi Jason,

On Tue, Feb 06, 2024 at 11:12:40AM -0400, Jason Gunthorpe wrote:
> Logically arm_smmu_init_strtab() is the function that allocates and
> populates the stream table with the initial value of the STEs. After this
> function returns the stream table should be fully ready.
> 
> arm_smmu_rmr_install_bypass_ste() adjusts the initial stream table to force
> any SIDs that the FW says have IOMMU_RESV_DIRECT to use bypass. This
> ensures there is no disruption to the identity mapping during boot.
> 
> Put arm_smmu_rmr_install_bypass_ste() into arm_smmu_init_strtab(), it
> already executes immediately after arm_smmu_init_strtab().
> 
> No functional change intended.

I think arm_smmu_init_strtab is quite low level to abstract FW configuration in it.
For example in KVM[1] we'd re-use a big part of this driver and rely on similar
low-level functions. But no strong opinion.

[1] https://lore.kernel.org/kvmarm/20230201125328.2186498-1-jean-philippe at linaro.org/


Thanks,
Mostafa

> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Moritz Fischer <moritzf at google.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> 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 6123e5ad95822c..2ab36dcf7c61f5 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -101,6 +101,8 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
>  	{ 0, NULL},
>  };
>  
> +static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu);
> +
>  static void parse_driver_options(struct arm_smmu_device *smmu)
>  {
>  	int i = 0;
> @@ -3256,6 +3258,7 @@ static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
>  	cfg->strtab_base_cfg = reg;
>  
>  	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents);
> +
>  	return 0;
>  }
>  
> @@ -3279,6 +3282,8 @@ static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
>  
>  	ida_init(&smmu->vmid_map);
>  
> +	/* Check for RMRs and install bypass STEs if any */
> +	arm_smmu_rmr_install_bypass_ste(smmu);
>  	return 0;
>  }
>  
> @@ -4073,9 +4078,6 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
>  	/* Record our private device structure */
>  	platform_set_drvdata(pdev, smmu);
>  
> -	/* Check for RMRs and install bypass STEs if any */
> -	arm_smmu_rmr_install_bypass_ste(smmu);
> -
>  	/* Reset the device */
>  	ret = arm_smmu_device_reset(smmu, bypass);
>  	if (ret)
> -- 
> 2.43.0
> 


From abel.vesa at linaro.org  Tue Feb 13 07:38:16 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Tue, 13 Feb 2024 17:38:16 +0200
Subject: [PATCH RFC v2] spmi: pmic-arb: Add support for multiple buses
In-Reply-To: <3fcb9f16-61f8-4544-a319-20496d5eb106@linaro.org>
References: <20240213-spmi-multi-master-support-v2-1-b3b102326906@linaro.org>
 <3fcb9f16-61f8-4544-a319-20496d5eb106@linaro.org>
Message-ID: <ZcuM6ChFFN6pIlrf@linaro.org>

On 24-02-13 15:55:56, Neil Armstrong wrote:
> On 13/02/2024 15:41, Abel Vesa wrote:
> > The v7 HW supports currently 2 buses. So register each bus as a separate
> > spmi controller and adapt all ops to use the bus instead of the
> > arbitrator. Legacy mode is still supported as long as there is no child
> > node that represents a bus, instead all nodes are expected to be actual
> > slave devices.
> > 
> > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > ---
> > Changes in v2:
> > - Reworked it so that it registers a spmi controller for each bus
> >    rather than relying on the generic framework to pass on the bus
> >    (master) id.
> 
> Thanks, I think this is better.
> 
> > - Link to v1: https://lore.kernel.org/r/20240207-spmi-multi-master-support-v1-0-ce57f301c7fd at linaro.org
> > ---
> >   drivers/spmi/spmi-pmic-arb.c | 950 ++++++++++++++++++++++++++-----------------
> >   1 file changed, 585 insertions(+), 365 deletions(-)
> > 
> > diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> > index 9ed1180fe31f..eced35b712b4 100644
> > --- a/drivers/spmi/spmi-pmic-arb.c
> > +++ b/drivers/spmi/spmi-pmic-arb.c
> 
> <snip>
> 
> 
> > +static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
> > +				  struct device_node *node,
> > +				  struct spmi_pmic_arb *pmic_arb)
> > +{
> > +	int bus_index = pmic_arb->buses_available;
> > +	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[bus_index];
> > +	struct device *dev = &pdev->dev;
> > +	struct spmi_controller *ctrl;
> > +	void __iomem *intr;
> > +	void __iomem *cnfg;
> > +	int index, ret;
> > +	u32 irq;
> > +
> > +	ctrl = devm_spmi_controller_alloc(dev, sizeof(*ctrl));
> > +	if (IS_ERR(ctrl))
> > +		return PTR_ERR(ctrl);
> > +
> > +	ctrl->cmd = pmic_arb_cmd;
> > +	ctrl->read_cmd = pmic_arb_read_cmd;
> > +	ctrl->write_cmd = pmic_arb_write_cmd;
> > +
> > +	bus = spmi_controller_get_drvdata(ctrl);
> > +	bus->spmic = ctrl;
> > +
> > +	bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID,
> > +					 sizeof(*bus->ppid_to_apid),
> > +					 GFP_KERNEL);
> > +	if (!bus->ppid_to_apid)
> > +		return -ENOMEM;
> > +
> > +	bus->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs,
> > +				      sizeof(*bus->apid_data),
> > +				      GFP_KERNEL);
> > +	if (!bus->apid_data)
> > +		return -ENOMEM;
> > +
> > +	/* Optional property for v7: */
> > +	of_property_read_u32(node, "qcom,bus-id", &bus_index);
> 
> Not sure what bindings you plan to use, but this should be the reg property.
> 

This is already part of the old bindings (and implementation) and it's
only used for cases where some platforms would have two separate DT
nodes (one for each bus, v7 only) as it would specify which bus id it
is.

None of the upstream platforms use the qcom,bus-id with any other value
than 0, currently.

TBH, I think it should be dropped entirely.

Also, just realized that if any platforms is using two separate
controller nodes for each bus, this new approach will break the second
instance as it will expect the qcom,bus-id value to still be 0.

> > +	if (bus_index != pmic_arb->buses_available) {
> > +		dev_err(dev, "wrong bus-id value");
> > +		return -EINVAL;
> > +	}
> > +
> > +	index = of_property_match_string(node, "reg-names", "cnfg");
> > +	if (index < 0) {
> > +		dev_err(dev, "cnfg reg region missing");
> > +		return -EINVAL;
> > +	}
> > +
> > +	cnfg = devm_of_iomap(dev, node, index, NULL);
> > +	if (IS_ERR(cnfg))
> > +		return PTR_ERR(cnfg);
> > +
> > +	index = of_property_match_string(node, "reg-names", "intr");
> > +	if (index < 0) {
> > +		dev_err(dev, "intr reg region missing");
> > +		return -EINVAL;
> > +	}
> > +
> > +	intr = devm_of_iomap(dev, node, index, NULL);
> > +	if (IS_ERR(intr))
> > +		return PTR_ERR(intr);
> > +
> > +	irq = of_irq_get_byname(node, "periph_irq");
> > +	if (irq < 0)
> > +		return irq;
> > +
> > +	bus->pmic_arb = pmic_arb;
> > +	bus->intr = intr;
> > +	bus->cnfg = cnfg;
> > +	bus->irq = irq;
> > +	bus->id = bus_index;
> > +
> > +	ret = pmic_arb->ver_ops->init_apid(bus, index);
> > +	if (ret)
> > +		return ret;
> > +
> > +	dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index);
> > +
> > +	bus->domain = irq_domain_add_tree(dev->of_node,
> > +					  &pmic_arb_irq_domain_ops, bus);
> > +	if (!bus->domain) {
> > +		dev_err(&pdev->dev, "unable to create irq_domain\n");
> > +		return -ENOMEM;
> > +	}
> > +
> > +	irq_set_chained_handler_and_data(bus->irq,
> > +					 pmic_arb_chained_irq, bus);
> > +
> > +	bus->spmic->dev.of_node = node;
> > +	dev_set_name(&bus->spmic->dev, "spmi-%d", bus_index);
> > +
> > +	ret = devm_spmi_controller_add(dev, bus->spmic);
> > +	if (ret)
> > +		return ret;
> > +
> > +	pmic_arb->buses_available++;
> > +
> > +	return 0;
> > +}
> > +
> > +static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb,
> > +					struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct device_node *node = dev->of_node;
> > +	struct device_node *child;
> > +	int ret;
> > +
> > +	for_each_available_child_of_node(node, child)
> > +		if (of_node_name_eq(child, "bus")) {
> 
> It seems you use "bus" subnodes, it seems you should also submit a new
> bindings scheme for v7 controllers with subnodes

Yep, will do that.

> 
> > +			ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb);
> > +			if (ret)
> > +				return ret;
> > +		}
> > +
> > +	if (!pmic_arb->buses_available)
> > +		ret = spmi_pmic_arb_bus_init(pdev, node, pmic_arb);
> > +
> > +	return ret;
> > +}
> > +
> > +static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < pmic_arb->buses_available; i++) {
> > +		struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[i];
> > +
> > +		irq_set_chained_handler_and_data(bus->irq,
> > +						 NULL, NULL);
> > +		irq_domain_remove(bus->domain);
> > +	}
> > +}
> > +
> 
> <snip>
> 
> Overall the patch is __huge__, could you split it ? Like move the bus handling
> then add the multi-bus support in separate patches ?

Sure thing.

> 
> But first please add new bindings first so we know what you expect from DT.

Yep, will add another example to the existing bindings schema.

> 
> Thanks,
> Neil
> 
> > 
> > ---
> > base-commit: 445a555e0623387fa9b94e68e61681717e70200a
> > change-id: 20240207-spmi-multi-master-support-832a704b779b
> > 
> > Best regards,
> 


From dlechner at baylibre.com  Tue Feb 13 07:38:29 2024
From: dlechner at baylibre.com (David Lechner)
Date: Tue, 13 Feb 2024 09:38:29 -0600
Subject: [PATCH 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <92e7e0acf6d8746a07729924982acbfea777c468.camel@gmail.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
 <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com> <92e7e0acf6d8746a07729924982acbfea777c468.camel@gmail.com>
Message-ID: <CAMknhBG0LY+xiaK6qXcRj5_UAnTUAk0h36qO1qYWYR-MN5ajzA@mail.gmail.com>

On Tue, Feb 13, 2024 at 3:50?AM Nuno S? <noname.nuno at gmail.com> wrote:
>
> On Mon, 2024-02-12 at 17:26 -0600, David Lechner wrote:
> > This adds a new spi_optimize_message() function that can be used to
> > optimize SPI messages that are used more than once. Peripheral drivers
> > that use the same message multiple times can use this API to perform SPI
> > message validation and controller-specific optimizations once and then
> > reuse the message while avoiding the overhead of revalidating the
> > message on each spi_(a)sync() call.
> >
> > Internally, the SPI core will also call this function for each message
> > if the peripheral driver did not explicitly call it. This is done to so
> > that controller drivers don't have to have multiple code paths for
> > optimized and non-optimized messages.
> >
> > A hook is provided for controller drivers to perform controller-specific
> > optimizations.
> >
> > Suggested-by: Martin Sperl <kernel at martin.sperl.org>
> > Link:
> > https://lore.kernel.org/linux-spi/39DEC004-10A1-47EF-9D77-276188D2580C at martin.sperl.org/
> > Signed-off-by: David Lechner <dlechner at baylibre.com>
> > ---
> >  drivers/spi/spi.c       | 145 ++++++++++++++++++++++++++++++++++++++++++++++-
> > -
> >  include/linux/spi/spi.h |  19 +++++++
> >  2 files changed, 160 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> > index c2b10e2c75f0..5bac215d7009 100644
> > --- a/drivers/spi/spi.c
> > +++ b/drivers/spi/spi.c
> > @@ -2106,6 +2106,41 @@ struct spi_message *spi_get_next_queued_message(struct
> > spi_controller *ctlr)
> >  }
> >  EXPORT_SYMBOL_GPL(spi_get_next_queued_message);
> >
> > +/**
> > + * __spi_unoptimize_message - shared implementation of
> > spi_unoptimize_message()
> > + *                            and spi_maybe_unoptimize_message()
> > + * @msg: the message to unoptimize
> > + *
> > + * Periperhal drivers should use spi_unoptimize_message() and callers inside
> > + * core should use spi_maybe_unoptimize_message() rather than calling this
> > + * function directly.
> > + *
> > + * It is not valid to call this on a message that is not currently optimized.
> > + */
> > +static void __spi_unoptimize_message(struct spi_message *msg)
> > +{
> > +     struct spi_controller *ctlr = msg->spi->controller;
> > +
> > +     if (ctlr->unoptimize_message)
> > +             ctlr->unoptimize_message(msg);
> > +
> > +     msg->optimized = false;
> > +     msg->opt_state = NULL;
> > +}
> > +
> > +/**
> > + * spi_maybe_unoptimize_message - unoptimize msg not managed by a peripheral
> > + * @msg: the message to unoptimize
> > + *
> > + * This function is used to unoptimize a message if and only if it was
> > + * optimized by the core (via spi_maybe_optimize_message()).
> > + */
> > +static void spi_maybe_unoptimize_message(struct spi_message *msg)
> > +{
> > +     if (!msg->pre_optimized && msg->optimized)
> > +             __spi_unoptimize_message(msg);
> > +}
> > +
> >  /**
> >   * spi_finalize_current_message() - the current message is complete
> >   * @ctlr: the controller to return the message to
> > @@ -2153,6 +2188,8 @@ void spi_finalize_current_message(struct spi_controller
> > *ctlr)
> >
> >       mesg->prepared = false;
> >
> > +     spi_maybe_unoptimize_message(mesg);
> > +
> >       WRITE_ONCE(ctlr->cur_msg_incomplete, false);
> >       smp_mb(); /* See __spi_pump_transfer_message()... */
> >       if (READ_ONCE(ctlr->cur_msg_need_completion))
> > @@ -4194,6 +4231,99 @@ static int __spi_validate(struct spi_device *spi,
> > struct spi_message *message)
> >       return 0;
> >  }
> >
> > +/**
> > + * __spi_optimize_message - shared implementation for spi_optimize_message()
> > + *                          and spi_maybe_optimize_message()
> > + * @spi: the device that will be used for the message
> > + * @msg: the message to optimize
> > + * @pre_optimized: whether the message is considered pre-optimized or not
> > + *
> > + * Peripheral drivers will call spi_optimize_message() and the spi core will
> > + * call spi_maybe_optimize_message() instead of calling this directly.
> > + *
> > + * It is not valid to call this on a message that has already been optimized.
> > + *
> > + * Return: zero on success, else a negative error code
> > + */
> > +static int __spi_optimize_message(struct spi_device *spi,
> > +                               struct spi_message *msg,
> > +                               bool pre_optimized)
> > +{
> > +     struct spi_controller *ctlr = spi->controller;
> > +     int ret;
> > +
> > +     ret = __spi_validate(spi, msg);
> > +     if (ret)
> > +             return ret;
> > +
> > +     if (ctlr->optimize_message) {
> > +             ret = ctlr->optimize_message(msg);
> > +             if (ret)
> > +                     return ret;
> > +     }
>
> Not really sure what are the spi core guarantees or what controllers should be
> expecting but I'll still ask :). Do we need to care about locking in here?
> Mainly on the controller callback? For spi device related data I guess it's up
> to the peripheral driver not to do anything weird or to properly protect the spi
> message?
>

Currently, it is expected that this operates only on the message
struct and doesn't poke any hardware so no locking is currently
required. And, yes, it is up to peripheral drivers that opt in to
pre-optimization to follow the rules of not touching the message while
it is in the optimized state. For peripheral drivers that don't call
spi_optimized_message(), nothing has really changed.


From smostafa at google.com  Tue Feb 13 07:38:57 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Tue, 13 Feb 2024 15:38:57 +0000
Subject: [PATCH v5 06/17] iommu/arm-smmu-v3: Hold arm_smmu_asid_lock
 during all of attach_dev
In-Reply-To: <6-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <6-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <ZcuNESWmrC9jZ9lM@google.com>

Hi Jason,

On Tue, Feb 06, 2024 at 11:12:43AM -0400, Jason Gunthorpe wrote:
> The BTM support wants to be able to change the ASID of any smmu_domain.
> When it goes to do this it holds the arm_smmu_asid_lock and iterates over
> the target domain's devices list.
> 
> During attach of a S1 domain we must ensure that the devices list and
> CD are in sync, otherwise we could miss CD updates or a parallel CD update
> could push an out of date CD.
> 
> This is pretty complicated, and almost works today because
> arm_smmu_detach_dev() removes the master from the linked list before
> working on the CD entries, preventing parallel update of the CD.
> 
> However, it does have an issue where the CD can remain programed while the
> domain appears to be unattached. arm_smmu_share_asid() will then not clear
> any CD entriess and install its own CD entry with the same ASID
> concurrently. This creates a small race window where the IOMMU can see two
> ASIDs pointing to different translations.
> 
> Solve this by wrapping most of the attach flow in the
> arm_smmu_asid_lock. This locks more than strictly needed to prepare for
> the next patch which will reorganize the order of the linked list, STE and
> CD changes.
> 
> Move arm_smmu_detach_dev() till after we have initialized the domain so
> the lock can be held for less time.
>

This seems a bit theoretical to me also it requires mis-programming as the master
will issue DMA in detach, but as this is not a hot path, I don?t think overlocking
will is a problem.

Reviewed-by: Mostafa Saleh <smostafa at google.com>

> Reviewed-by: Michael Shavit <mshavit at google.com>
> Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Moritz Fischer <moritzf at google.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 22 ++++++++++++---------
>  1 file changed, 13 insertions(+), 9 deletions(-)
> 
> 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 417b2c877ff311..1229545ae6db4e 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2639,8 +2639,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  		return -EBUSY;
>  	}
>  
> -	arm_smmu_detach_dev(master);
> -
>  	mutex_lock(&smmu_domain->init_mutex);
>  
>  	if (!smmu_domain->smmu) {
> @@ -2655,6 +2653,16 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  	if (ret)
>  		return ret;
>  
> +	/*
> +	 * Prevent arm_smmu_share_asid() from trying to change the ASID
> +	 * of either the old or new domain while we are working on it.
> +	 * This allows the STE and the smmu_domain->devices list to
> +	 * be inconsistent during this routine.
> +	 */
> +	mutex_lock(&arm_smmu_asid_lock);
> +
> +	arm_smmu_detach_dev(master);
> +
>  	master->domain = smmu_domain;
>  
>  	/*
> @@ -2680,13 +2688,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  			}
>  		}
>  
> -		/*
> -		 * Prevent SVA from concurrently modifying the CD or writing to
> -		 * the CD entry
> -		 */
> -		mutex_lock(&arm_smmu_asid_lock);
>  		ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, &smmu_domain->cd);
> -		mutex_unlock(&arm_smmu_asid_lock);
>  		if (ret) {
>  			master->domain = NULL;
>  			goto out_list_del;
> @@ -2696,13 +2698,15 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  	arm_smmu_install_ste_for_dev(master);
>  
>  	arm_smmu_enable_ats(master);
> -	return 0;
> +	goto out_unlock;
>  
>  out_list_del:
>  	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
>  	list_del(&master->domain_head);
>  	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
>  
> +out_unlock:
> +	mutex_unlock(&arm_smmu_asid_lock);
>  	return ret;
>  }
>  
> -- 
> 2.43.0
> 


From arnaud.pouliquen at foss.st.com  Tue Feb 13 07:38:11 2024
From: arnaud.pouliquen at foss.st.com (Arnaud POULIQUEN)
Date: Tue, 13 Feb 2024 16:38:11 +0100
Subject: [PATCH v2 2/4] dt-bindings: remoteproc: Add compatibility for TEE
 support
In-Reply-To: <20240130175112.GA2040002-robh@kernel.org>
References: <20240118100433.3984196-1-arnaud.pouliquen@foss.st.com>
 <20240118100433.3984196-3-arnaud.pouliquen@foss.st.com>
 <20240130175112.GA2040002-robh@kernel.org>
Message-ID: <32b5b04b-c644-43d0-b190-4200f0e92979@foss.st.com>

Hello Rob,

On 1/30/24 18:51, Rob Herring wrote:
> On Thu, Jan 18, 2024 at 11:04:31AM +0100, Arnaud Pouliquen wrote:
>> The "st,stm32mp1-m4-tee" compatible is utilized in a system configuration
>> where the Cortex-M4 firmware is loaded by the Trusted execution Environment
>> (TEE).
>> For instance, this compatible is used in both the Linux and OP-TEE
>> device-tree:
>> - In OP-TEE, a node is defined in the device tree with the
>>   st,stm32mp1-m4-tee to support signed remoteproc firmware.
>>   Based on DT properties, OP-TEE authenticates, loads, starts, and stops
>>   the firmware.
>> - On Linux, when the compatibility is set, the Cortex-M resets should not
>>   be declared in the device tree.
>>
>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
>> ---
>> V1 to V2 updates
>> - update "st,stm32mp1-m4" compatible description to generalize
>> - remove the 'reset-names' requirement in one conditional branch, as the
>>   property is already part of the condition test.
>> ---
>>  .../bindings/remoteproc/st,stm32-rproc.yaml   | 52 +++++++++++++++----
>>  1 file changed, 43 insertions(+), 9 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
>> index 370af61d8f28..6af821b15736 100644
>> --- a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
>> +++ b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
>> @@ -16,7 +16,12 @@ maintainers:
>>  
>>  properties:
>>    compatible:
>> -    const: st,stm32mp1-m4
>> +    enum:
>> +      - st,stm32mp1-m4
>> +      - st,stm32mp1-m4-tee
>> +    description:
>> +      Use "st,stm32mp1-m4" for the Cortex-M4 coprocessor management by non-secure context
>> +      Use "st,stm32mp1-m4-tee" for the Cortex-M4 coprocessor management by secure context
>>  
>>    reg:
>>      description:
>> @@ -142,21 +147,40 @@ properties:
>>  required:
>>    - compatible
>>    - reg
>> -  - resets
>>  
>>  allOf:
>>    - if:
>>        properties:
>> -        reset-names:
>> -          not:
>> -            contains:
>> -              const: hold_boot
>> +        compatible:
>> +          contains:
>> +            const: st,stm32mp1-m4
>> +    then:
>> +      if:
>> +        properties:
>> +          reset-names:
>> +            not:
>> +              contains:
>> +                const: hold_boot
> 
> Note that this is true when 'reset-names' is not present. If that is not 
> desired, then you need 'required: [reset-names]'. Not really a new issue 
> though.
> 

Yes that corresponds to my expectation, for compatibility with legacy DT.
If the hold_boot reset was not used, reset-names was not mandatory
I will add the 'required: [reset-names]' in the else

Thanks,
Arnaud

>> +      then:
>> +        required:
>> +          - st,syscfg-holdboot
>> +          - resets
>> +      else:
>> +        properties:
>> +          st,syscfg-holdboot: false
>> +        required:
>> +          - resets
> 
> 'resets' is always required within the outer 'then' schema, so you can 
> move this up a level.
> 
>> +
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: st,stm32mp1-m4-tee
>>      then:
>> -      required:
>> -        - st,syscfg-holdboot
>> -    else:
>>        properties:
>>          st,syscfg-holdboot: false
>> +        reset-names: false
>> +        resets: false
>>  
>>  additionalProperties: false
>>  
>> @@ -188,5 +212,15 @@ examples:
>>        st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>;
>>        st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>;
>>      };
>> +  - |
>> +    #include <dt-bindings/reset/stm32mp1-resets.h>
>> +    m4 at 10000000 {
>> +      compatible = "st,stm32mp1-m4-tee";
>> +      reg = <0x10000000 0x40000>,
>> +            <0x30000000 0x40000>,
>> +            <0x38000000 0x10000>;
>> +      st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>;
>> +      st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>;
>> +    };
>>  
>>  ...
>> -- 
>> 2.25.1
>>


From robh at kernel.org  Tue Feb 13 07:40:13 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 09:40:13 -0600
Subject: [PATCH] Add eSPI device driver (flash channel)
In-Reply-To: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
References: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
Message-ID: <170783881259.1420281.1418000696740064343.robh@kernel.org>


On Tue, 13 Feb 2024 20:06:08 +0530, Manojkiran Eda wrote:
> This patch adds the driver support for the eSPI controller of
> Aspeed 5/6th generation SoCs. This controller is a slave device
> communicating with a master over Enhanced Serial Peripheral
> Interface (eSPI).
> 
> eSPI supports 4 channels, namely peripheral, virtual wire,
> out-of-band, and flash, and operates at max frequency of 66MHz.
> 
> But at the moment, this patch set only supports the flash channel.
> 
> Signed-off-by: Manojkiran Eda <manojkiran.eda at gmail.com>
> ---
> Hello everyone,
> 
> I'm presenting a revised version of the eSPI device driver patch series found at the following link:
> 
> https://lore.kernel.org/openbmc/20220516005412.4844-1-chiawei_wang at aspeedtech.com/
> 
> This update addresses the issues identified during the review process.
> 
> While the previous patch series attempted to incorporate support for all four different channels of eSPI,
> this new series focuses on upstreaming the flash channel initially, ensuring that all review comments are
> duly addressed, before progressing further.
> 
> Results:
> 
> Successfully conducted a flash update via eSPI.
> 
> Note:
> 
> This marks my inaugural endeavor in contributing code to the kernel subsystem. I kindly request reviewers
> to incorporate as many details as possible in the review comments.
> ---
>  .../devicetree/bindings/soc/aspeed/espi.yaml       | 125 ++++++
>  arch/arm/boot/dts/aspeed/aspeed-g6.dtsi            |  16 +-
>  drivers/mtd/mtdcore.c                              |   2 +-
>  drivers/soc/aspeed/Kconfig                         |  10 +
>  drivers/soc/aspeed/Makefile                        |   3 +
>  drivers/soc/aspeed/aspeed-espi-ctrl.c              | 197 +++++++++
>  drivers/soc/aspeed/aspeed-espi-ctrl.h              | 169 ++++++++
>  drivers/soc/aspeed/aspeed-espi-flash.c             | 466 +++++++++++++++++++++
>  drivers/soc/aspeed/aspeed-espi-flash.h             |  45 ++
>  include/uapi/linux/espi/aspeed-espi-ioc.h          | 103 +++++
>  10 files changed, 1134 insertions(+), 2 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:
./Documentation/devicetree/bindings/soc/aspeed/espi.yaml:5:6: [error] string value is redundantly quoted with any quotes (quoted-strings)
./Documentation/devicetree/bindings/soc/aspeed/espi.yaml:6:10: [error] string value is redundantly quoted with any quotes (quoted-strings)

dtschema/dtc warnings/errors:

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240213-espi_driver-v1-1-92741c812843 at gmail.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From smostafa at google.com  Tue Feb 13 07:40:34 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Tue, 13 Feb 2024 15:40:34 +0000
Subject: [PATCH v5 08/17] iommu/arm-smmu-v3: Do not change the STE twice
 during arm_smmu_attach_dev()
In-Reply-To: <8-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <8-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <ZcuNcka3q3nUOpFM@google.com>

Hi Jason,

On Tue, Feb 06, 2024 at 11:12:45AM -0400, Jason Gunthorpe wrote:
> This was needed because the STE code required the STE to be in
> ABORT/BYPASS inorder to program a cdtable or S2 STE. Now that the STE code
> can automatically handle all transitions we can remove this step
> from the attach_dev flow.
> 
> A few small bugs exist because of this:
> 
> 1) If the core code does BLOCKED -> UNMANAGED with disable_bypass=false
>    then there will be a moment where the STE points at BYPASS. Since
>    this can be done by VFIO/IOMMUFD it is a small security race.
> 
> 2) If the core code does IDENTITY -> DMA then any IOMMU_RESV_DIRECT
>    regions will temporarily become BLOCKED. We'd like drivers to
>    work in a way that allows IOMMU_RESV_DIRECT to be continuously
>    functional during these transitions.
> 
> Make arm_smmu_release_device() put the STE back to the correct
> ABORT/BYPASS setting. Fix a bug where a IOMMU_RESV_DIRECT was ignored on
> this path.
> 
> As noted before the reordering of the linked list/STE/CD changes is OK
> against concurrent arm_smmu_share_asid() because of the
> arm_smmu_asid_lock.
> 
> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Moritz Fischer <moritzf at google.com>
> Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> 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 1138e868c4d73e..340f3dc82c9ce0 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2562,7 +2562,6 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
>  static void arm_smmu_detach_dev(struct arm_smmu_master *master)
>  {
>  	unsigned long flags;
> -	struct arm_smmu_ste target;
>  	struct arm_smmu_domain *smmu_domain = master->domain;
>  
>  	if (!smmu_domain)
> @@ -2576,11 +2575,6 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
>  
>  	master->domain = NULL;
>  	master->ats_enabled = false;
> -	if (disable_bypass)
> -		arm_smmu_make_abort_ste(&target);
> -	else
> -		arm_smmu_make_bypass_ste(&target);
> -	arm_smmu_install_ste_for_dev(master, &target);
>  	/*
>  	 * Clearing the CD entry isn't strictly required to detach the domain
>  	 * since the table is uninstalled anyway, but it helps avoid confusion
> @@ -2928,9 +2922,18 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
>  static void arm_smmu_release_device(struct device *dev)
>  {
>  	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> +	struct arm_smmu_ste target;
>  
>  	if (WARN_ON(arm_smmu_master_sva_enabled(master)))
>  		iopf_queue_remove_device(master->smmu->evtq.iopf, dev);
> +
> +	/* Put the STE back to what arm_smmu_init_strtab() sets */
> +	if (disable_bypass && !dev->iommu->require_direct)
> +		arm_smmu_make_abort_ste(&target);
> +	else
> +		arm_smmu_make_bypass_ste(&target);
> +	arm_smmu_install_ste_for_dev(master, &target);
> +
>  	arm_smmu_detach_dev(master);
>  	arm_smmu_disable_pasid(master);
>  	arm_smmu_remove_master(master);
> -- 
> 2.43.0
> 
I am still reviewing patch-1 and the hitless machinery (also I think -or hope-
this can be simplified), with the assumption that
arm_smmu_install_ste_for_dev()/arm_smmu_write_ste() will do the right thing,
that good looks good to me.

However, as it changes the current behavior of the driver where disable_bypass
used to override require_direct, I am not sure if this would break any existing setups.


Thanks,
Mostafa


From smostafa at google.com  Tue Feb 13 07:42:53 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Tue, 13 Feb 2024 15:42:53 +0000
Subject: [PATCH v5 09/17] iommu/arm-smmu-v3: Put writing the context
 descriptor in the right order
In-Reply-To: <9-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <9-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <ZcuN_YZBzxJ2wvAg@google.com>

Hi Jason,

On Tue, Feb 06, 2024 at 11:12:46AM -0400, Jason Gunthorpe wrote:
> Get closer to the IOMMU API ideal that changes between domains can be
> hitless. The ordering for the CD table entry is not entirely clean from
> this perspective.
> 
> When switching away from a STE with a CD table programmed in it we should
> write the new STE first, then clear any old data in the CD entry.
> 
> If we are programming a CD table for the first time to a STE then the CD
> entry should be programmed before the STE is loaded.
> 
> If we are replacing a CD table entry when the STE already points at the CD
> entry then we just need to do the make/break sequence.
> 
> Lift this code out of arm_smmu_detach_dev() so it can all be sequenced
> properly. The only other caller is arm_smmu_release_device() and it is
> going to free the cdtable anyhow, so it doesn't matter what is in it.
> 
> Reviewed-by: Michael Shavit <mshavit at google.com>
> Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Moritz Fischer <moritzf at google.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29 ++++++++++++++-------
>  1 file changed, 20 insertions(+), 9 deletions(-)
> 
> 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 340f3dc82c9ce0..2a6ac0af932c54 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2575,14 +2575,6 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
>  
>  	master->domain = NULL;
>  	master->ats_enabled = false;
> -	/*
> -	 * Clearing the CD entry isn't strictly required to detach the domain
> -	 * since the table is uninstalled anyway, but it helps avoid confusion
> -	 * in the call to arm_smmu_write_ctx_desc on the next attach (which
> -	 * expects the entry to be empty).
> -	 */
> -	if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 && master->cd_table.cdtab)
> -		arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, NULL);
>  }
>  
>  static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
> @@ -2659,6 +2651,17 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  				master->domain = NULL;
>  				goto out_list_del;
>  			}
> +		} else {
> +			/*
> +			 * arm_smmu_write_ctx_desc() relies on the entry being
> +			 * invalid to work, clear any existing entry.
> +			 */
> +			ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
> +						      NULL);
> +			if (ret) {
> +				master->domain = NULL;
> +				goto out_list_del;
> +			}

Instead of having duplicate
           if (ret) {
               master->domain = NULL;
               goto out_list_del;
           }

In the if and the else, we can just move it outside.

>  		}
>  
>  		ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, &smmu_domain->cd);
> @@ -2668,15 +2671,23 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  		}
>  
>  		arm_smmu_make_cdtable_ste(&target, master);
> +		arm_smmu_install_ste_for_dev(master, &target);
>  		break;
>  	case ARM_SMMU_DOMAIN_S2:
>  		arm_smmu_make_s2_domain_ste(&target, master, smmu_domain);
> +		arm_smmu_install_ste_for_dev(master, &target);
> +		if (master->cd_table.cdtab)
> +			arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
> +						      NULL);
>  		break;
>  	case ARM_SMMU_DOMAIN_BYPASS:
>  		arm_smmu_make_bypass_ste(&target);
> +		arm_smmu_install_ste_for_dev(master, &target);
> +		if (master->cd_table.cdtab)
> +			arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
> +						      NULL);
>  		break;
>  	}
This invalidates the CD while the STE is in bypass/S2 which is a new behavior
to the driver, I don?t see anything from the user manual about this, so I
believe that is fine.

Reviewed-by: Mostafa Saleh <smostafa at google.com>

> -	arm_smmu_install_ste_for_dev(master, &target);
>  
>  	arm_smmu_enable_ats(master);
>  	goto out_unlock;
> -- 
> 2.43.0
>

Thanks,
Mostafa


From smostafa at google.com  Tue Feb 13 07:43:40 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Tue, 13 Feb 2024 15:43:40 +0000
Subject: [PATCH v5 10/17] iommu/arm-smmu-v3: Pass smmu_domain to
 arm_enable/disable_ats()
In-Reply-To: <10-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <10-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <ZcuOLGOqArUzUOfv@google.com>

On Tue, Feb 06, 2024 at 11:12:47AM -0400, Jason Gunthorpe wrote:
> The caller already has the domain, just pass it in. A following patch will
> remove master->domain.
> 
> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Moritz Fischer <moritzf at google.com>
> Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)
> 
> 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 2a6ac0af932c54..133f13f33df124 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2474,12 +2474,12 @@ static bool arm_smmu_ats_supported(struct arm_smmu_master *master)
>  	return dev_is_pci(dev) && pci_ats_supported(to_pci_dev(dev));
>  }
>  
> -static void arm_smmu_enable_ats(struct arm_smmu_master *master)
> +static void arm_smmu_enable_ats(struct arm_smmu_master *master,
> +				struct arm_smmu_domain *smmu_domain)
>  {
>  	size_t stu;
>  	struct pci_dev *pdev;
>  	struct arm_smmu_device *smmu = master->smmu;
> -	struct arm_smmu_domain *smmu_domain = master->domain;
>  
>  	/* Don't enable ATS at the endpoint if it's not enabled in the STE */
>  	if (!master->ats_enabled)
> @@ -2495,10 +2495,9 @@ static void arm_smmu_enable_ats(struct arm_smmu_master *master)
>  		dev_err(master->dev, "Failed to enable ATS (STU %zu)\n", stu);
>  }
>  
> -static void arm_smmu_disable_ats(struct arm_smmu_master *master)
> +static void arm_smmu_disable_ats(struct arm_smmu_master *master,
> +				 struct arm_smmu_domain *smmu_domain)
>  {
> -	struct arm_smmu_domain *smmu_domain = master->domain;
> -
>  	if (!master->ats_enabled)
>  		return;
>  
> @@ -2567,7 +2566,7 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
>  	if (!smmu_domain)
>  		return;
>  
> -	arm_smmu_disable_ats(master);
> +	arm_smmu_disable_ats(master, smmu_domain);
>  
>  	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
>  	list_del(&master->domain_head);
> @@ -2689,7 +2688,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  		break;
>  	}
>  
> -	arm_smmu_enable_ats(master);
> +	arm_smmu_enable_ats(master, smmu_domain);
>  	goto out_unlock;
>  
>  out_list_del:
> -- 
> 2.43.0
>

Reviewed-by: Mostafa Saleh <smostafa at google.com>

Thanks,
Mostafa


From smostafa at google.com  Tue Feb 13 07:45:34 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Tue, 13 Feb 2024 15:45:34 +0000
Subject: [PATCH v5 11/17] iommu/arm-smmu-v3: Remove
 arm_smmu_master->domain
In-Reply-To: <11-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <11-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <ZcuOnnrWN3ZxJY8x@google.com>

Hi Jason,

On Tue, Feb 06, 2024 at 11:12:48AM -0400, Jason Gunthorpe wrote:
> Introducing global statics which are of type struct iommu_domain, not
> struct arm_smmu_domain makes it difficult to retain
> arm_smmu_master->domain, as it can no longer point to an IDENTITY or
> BLOCKED domain.
> 
> The only place that uses the value is arm_smmu_detach_dev(). Change things
> to work like other drivers and call iommu_get_domain_for_dev() to obtain
> the current domain.
> 
> The master->domain is subtly protecting the domain_head against being
> unused, change the domain_head to be INIT'd when the master is not
> attached to a domain instead of garbage/zero.

I don't this the problem here, neither the reason for initialising the
domain_head, can you please clarify the issue?

> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Moritz Fischer <moritzf at google.com>
> Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 ++++++++-------------
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  1 -
>  2 files changed, 10 insertions(+), 17 deletions(-)
> 
> 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 133f13f33df124..a98707cd1efccb 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2560,19 +2560,20 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
>  
>  static void arm_smmu_detach_dev(struct arm_smmu_master *master)
>  {
> +	struct iommu_domain *domain = iommu_get_domain_for_dev(master->dev);
> +	struct arm_smmu_domain *smmu_domain;
>  	unsigned long flags;
> -	struct arm_smmu_domain *smmu_domain = master->domain;
>  
> -	if (!smmu_domain)
> +	if (!domain)
>  		return;
>  
> +	smmu_domain = to_smmu_domain(domain);
>  	arm_smmu_disable_ats(master, smmu_domain);
>  
>  	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> -	list_del(&master->domain_head);
> +	list_del_init(&master->domain_head);
>  	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
>  
> -	master->domain = NULL;
>  	master->ats_enabled = false;
>  }
>  
> @@ -2626,8 +2627,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  
>  	arm_smmu_detach_dev(master);
>  
> -	master->domain = smmu_domain;
> -
>  	/*
>  	 * The SMMU does not support enabling ATS with bypass. When the STE is
>  	 * in bypass (STE.Config[2:0] == 0b100), ATS Translation Requests and
> @@ -2646,10 +2645,8 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  	case ARM_SMMU_DOMAIN_S1:
>  		if (!master->cd_table.cdtab) {
>  			ret = arm_smmu_alloc_cd_tables(master);
> -			if (ret) {
> -				master->domain = NULL;
> +			if (ret)
>  				goto out_list_del;
> -			}
>  		} else {
>  			/*
>  			 * arm_smmu_write_ctx_desc() relies on the entry being
> @@ -2657,17 +2654,13 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  			 */
>  			ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
>  						      NULL);
> -			if (ret) {
> -				master->domain = NULL;
> +			if (ret)
>  				goto out_list_del;
> -			}
>  		}
>  
>  		ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, &smmu_domain->cd);
> -		if (ret) {
> -			master->domain = NULL;
> +		if (ret)
>  			goto out_list_del;
> -		}
>  
>  		arm_smmu_make_cdtable_ste(&target, master);
>  		arm_smmu_install_ste_for_dev(master, &target);
> @@ -2693,7 +2686,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  
>  out_list_del:
>  	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> -	list_del(&master->domain_head);
> +	list_del_init(&master->domain_head);
>  	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
>  
>  out_unlock:
> @@ -2894,6 +2887,7 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
>  	master->dev = dev;
>  	master->smmu = smmu;
>  	INIT_LIST_HEAD(&master->bonds);
> +	INIT_LIST_HEAD(&master->domain_head);
>  	dev_iommu_priv_set(dev, master);
>  
>  	ret = arm_smmu_insert_master(smmu, master);
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index cbf4b57719b7b9..587f99701ad30f 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -696,7 +696,6 @@ struct arm_smmu_stream {
>  struct arm_smmu_master {
>  	struct arm_smmu_device		*smmu;
>  	struct device			*dev;
> -	struct arm_smmu_domain		*domain;
>  	struct list_head		domain_head;
>  	struct arm_smmu_stream		*streams;
>  	/* Locked by the iommu core using the group mutex */
> -- 
> 2.43.0
>
Thanks,
Mostafa


From arnaud.pouliquen at foss.st.com  Tue Feb 13 07:47:30 2024
From: arnaud.pouliquen at foss.st.com (Arnaud POULIQUEN)
Date: Tue, 13 Feb 2024 16:47:30 +0100
Subject: [Linux-stm32] [PATCH v2 4/4] remoteproc: stm32: Add support of an
 OP-TEE TA to load the firmware
In-Reply-To: <36c0368b-94f3-40bd-9273-33ab2c9bf913@foss.st.com>
References: <20240118100433.3984196-1-arnaud.pouliquen@foss.st.com>
 <20240118100433.3984196-5-arnaud.pouliquen@foss.st.com>
 <ZbPnsJm67G10+HQ3@p14s> <7ec6c9e8-9267-4e7c-81a4-abcdb2ab4239@foss.st.com>
 <ZbqW5YfDmEWG4G1X@p14s> <8ede77bb-0fbc-4de2-b51b-67674744b551@foss.st.com>
 <ZbvAmxHscnbUQGOD@p14s> <a52e00c5-fb60-4a9e-85ff-0f9649850f48@foss.st.com>
 <Zb1IPlnbMp9Utu2y@p14s> <36c0368b-94f3-40bd-9273-33ab2c9bf913@foss.st.com>
Message-ID: <bdac5637-767e-4310-9ecd-fad5490e9b3c@foss.st.com>

Hello Mathieu,

On 2/5/24 10:13, Arnaud POULIQUEN wrote:
> 
> 
> On 2/2/24 20:53, Mathieu Poirier wrote:
>> On Thu, Feb 01, 2024 at 07:33:35PM +0100, Arnaud POULIQUEN wrote:
>>>
>>>
>>> On 2/1/24 17:02, Mathieu Poirier wrote:
>>>> On Thu, Feb 01, 2024 at 04:06:37PM +0100, Arnaud POULIQUEN wrote:
>>>>> hello Mathieu,
>>>>>
>>>>> On 1/31/24 19:52, Mathieu Poirier wrote:
>>>>>> On Tue, Jan 30, 2024 at 10:13:48AM +0100, Arnaud POULIQUEN wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 1/26/24 18:11, Mathieu Poirier wrote:
>>>>>>>> On Thu, Jan 18, 2024 at 11:04:33AM +0100, Arnaud Pouliquen wrote:
>>>>>>>>> The new TEE remoteproc device is used to manage remote firmware in a
>>>>>>>>> secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
>>>>>>>>> introduced to delegate the loading of the firmware to the trusted
>>>>>>>>> execution context. In such cases, the firmware should be signed and
>>>>>>>>> adhere to the image format defined by the TEE.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
>>>>>>>>> ---
>>>>>>>>> V1 to V2 update:
>>>>>>>>> - remove the select "TEE_REMOTEPROC" in STM32_RPROC config as detected by
>>>>>>>>>   the kernel test robot:
>>>>>>>>>      WARNING: unmet direct dependencies detected for TEE_REMOTEPROC
>>>>>>>>>      Depends on [n]: REMOTEPROC [=y] && OPTEE [=n]
>>>>>>>>>      Selected by [y]:
>>>>>>>>>      - STM32_RPROC [=y] && (ARCH_STM32 || COMPILE_TEST [=y]) && REMOTEPROC [=y]
>>>>>>>>> - Fix initialized trproc variable in  stm32_rproc_probe
>>>>>>>>> ---
>>>>>>>>>  drivers/remoteproc/stm32_rproc.c | 149 +++++++++++++++++++++++++++++--
>>>>>>>>>  1 file changed, 144 insertions(+), 5 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
>>>>>>>>> index fcc0001e2657..cf6a21bac945 100644
>>>>>>>>> --- a/drivers/remoteproc/stm32_rproc.c
>>>>>>>>> +++ b/drivers/remoteproc/stm32_rproc.c
>>>>>>>>> @@ -20,6 +20,7 @@
>>>>>>>>>  #include <linux/remoteproc.h>
>>>>>>>>>  #include <linux/reset.h>
>>>>>>>>>  #include <linux/slab.h>
>>>>>>>>> +#include <linux/tee_remoteproc.h>
>>>>>>>>>  #include <linux/workqueue.h>
>>>>>>>>>  
>>>>>>>>>  #include "remoteproc_internal.h"
>>>>>>>>> @@ -49,6 +50,9 @@
>>>>>>>>>  #define M4_STATE_STANDBY	4
>>>>>>>>>  #define M4_STATE_CRASH		5
>>>>>>>>>  
>>>>>>>>> +/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
>>>>>>>>> +#define STM32_MP1_M4_PROC_ID    0
>>>>>>>>> +
>>>>>>>>>  struct stm32_syscon {
>>>>>>>>>  	struct regmap *map;
>>>>>>>>>  	u32 reg;
>>>>>>>>> @@ -90,6 +94,8 @@ struct stm32_rproc {
>>>>>>>>>  	struct stm32_mbox mb[MBOX_NB_MBX];
>>>>>>>>>  	struct workqueue_struct *workqueue;
>>>>>>>>>  	bool hold_boot_smc;
>>>>>>>>> +	bool fw_loaded;
>>>>>>>>> +	struct tee_rproc *trproc;
>>>>>>>>>  	void __iomem *rsc_va;
>>>>>>>>>  };
>>>>>>>>>  
>>>>>>>>> @@ -257,6 +263,91 @@ static int stm32_rproc_release(struct rproc *rproc)
>>>>>>>>>  	return err;
>>>>>>>>>  }
>>>>>>>>>  
>>>>>>>>> +static int stm32_rproc_tee_elf_sanity_check(struct rproc *rproc,
>>>>>>>>> +					    const struct firmware *fw)
>>>>>>>>> +{
>>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>>> +	unsigned int ret = 0;
>>>>>>>>> +
>>>>>>>>> +	if (rproc->state == RPROC_DETACHED)
>>>>>>>>> +		return 0;
>>>>>>>>> +
>>>>>>>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
>>>>>>>>> +	if (!ret)
>>>>>>>>> +		ddata->fw_loaded = true;
>>>>>>>>> +
>>>>>>>>> +	return ret;
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>> +static int stm32_rproc_tee_elf_load(struct rproc *rproc,
>>>>>>>>> +				    const struct firmware *fw)
>>>>>>>>> +{
>>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>>> +	unsigned int ret;
>>>>>>>>> +
>>>>>>>>> +	/*
>>>>>>>>> +	 * This function can be called by remote proc for recovery
>>>>>>>>> +	 * without the sanity check. In this case we need to load the firmware
>>>>>>>>> +	 * else nothing done here as the firmware has been preloaded for the
>>>>>>>>> +	 * sanity check to be able to parse it for the resource table.
>>>>>>>>> +	 */
>>>>>>>>
>>>>>>>> This comment is very confusing - please consider refactoring.  
>>>>>>>>
>>>>>>>>> +	if (ddata->fw_loaded)
>>>>>>>>> +		return 0;
>>>>>>>>> +
>>>>>>>>
>>>>>>>> I'm not sure about keeping a flag to indicate the status of the loaded firmware.
>>>>>>>> It is not done for the non-secure method, I don't see why it would be needed for
>>>>>>>> the secure one.
>>>>>>>>
>>>>>>>
>>>>>>> The difference is on the sanity check.
>>>>>>> - in rproc_elf_sanity_check we  parse the elf file to verify that it is
>>>>>>> valid.
>>>>>>> - in stm32_rproc_tee_elf_sanity_check we have to do the same, that means to
>>>>>>> authenticate it. the authentication is done during the load.
>>>>>>>
>>>>>>> So this flag is used to avoid to reload it twice time.
>>>>>>> refactoring the comment should help to understand this flag
>>>>>>>
>>>>>>>
>>>>>>> An alternative would be to bypass the sanity check. But this lead to same
>>>>>>> limitation.
>>>>>>> Before loading the firmware in remoteproc_core, we call rproc_parse_fw() that is
>>>>>>> used to get the resource table address. To get it from tee we need to
>>>>>>> authenticate the firmware so load it...
>>>>>>>
>>>>>>
>>>>>> I spent a long time thinking about this patchset.  Looking at the code as it
>>>>>> is now, request_firmware() in rproc_boot() is called even when the TEE is
>>>>>> responsible for loading the firmware.  There should be some conditional code
>>>>>> that calls either request_firmware() or tee_rproc_load_fw().  The latter should
>>>>>> also be renamed to tee_rproc_request_firmware() to avoid confusion.
>>>>>
>>>>>
>>>>> The request_firmware() call is needed in both cases to get the image from the
>>>>> filesystem. The tee_rproc_load_fw() gets, as input, the struct firmware provided
>>>>> by request_firmware().
>>>>
>>>> The cover letter clearly state the secure side is responsible for loading the
>>>> firmware image but here you're telling me it has to be loaded twice.  This is
>>>> very confusing.
>>>
>>> Concerning the call of request_firmware()
>>>
>>> By "both cases" I would say that the call of request_firmware() is needed in
>>> both modes:
>>> - the ELF firmware is parsed and loaded by linux (legacy)
>>> - the binary firmware is parsed and loaded by OP-TEE.
>>>
>>> The Op-TEE is not able to get the firmware image from the file system.
>>>
>>>
>>> Concerning the call of tee_rproc_load_fw twice time
>>>
>>> There are 2 use cases:
>>>
>>> - First boot of the remote processor:
>>>
>>>   1) The Linux rproc gets the binary firmware image from the file system by
>>>      calling  request_firmware(). A copy is stored in memory.
>>
>> Right.  And I think tee_rproc_load_fw() should be called right after
>> request_firmware() if rproc::tee_rproc_interface is valid.  At that point the TEE
>> app may or may not do the firmware authentication, that is application specific.

FYI, I am close to completing V3 for my series. However, I am facing an issue
with rproc_load_segments() that requires the implementation of ops->load on start.
Therefore, just inserting a tee_rproc_load_fw() call is not possible.

Due to this constraint, I did not find a solution that matches your
recommendations. Nevertheless, I will propose another solution in my V3, trying
to take into account as many of your comments/requests as possible, including
updating of the remoteproc_core.c to simplify the sequence.


Regards,
Arnaud


>>
>>>   2) the linux performs a sanity check on the firmware calling
>>>      rproc_fw_sanity_check()
>>> 	=> from OP-TEE point of view this means to autenticate the firmware
>>> 	=> let consider in this exemple that we bypass this step
>>>            (ops->sanity_check = NULL)
>>
>> Ok
>>
>>> 		
>>>   3) the linux rproc call rproc_parse_fw() to get the resource table
>>> 	=> From OP-TEE point of view the resource table is available only when
>>>            the firmware is loaded
>>
>> Right, and it should have been loaded already.  If it is not then the TEE should
>> return an error.
>>
>>> 	=> We need to call tee_rproc_load_fw() to be able then to get the
>>>            address of the resource table.
>>
>> See my comment above - at this point the TEE should already have the firmware.
>> As such the only thing left is to get the address of the resource table, which
>> you already do in rproc_tee_get_rsc_table().  The upper part of that function
>> should be spun off in a new static function to deal with the TEE API, something
>> like _rproc_tee_get_rsc_table().  The new function should also be called in
>> tee_rproc_get_loaded_rsc_table() rather than keeping a cache value in
>> trproc->rsc_va.
>>
>>>   4) The Linux rproc calls rproc_handle_resources() to parse the resource table.
>>>   5) The linux rproc calls rproc_start()
>>> 	- load the firrmware calling rproc_load_segments()
>>> 		=> we don't want to call tee_rproc_load_fw() it a second time
>>
>> And that is fine if the TEE app has already placed the program segments in
>> memory.
>>
>>> 	- start the firmware calling ops->start()
>>>
>>> - Reboot on crash recovery using rproc_boot_recovery()
>>>
>>>   1)  The Linux rproc gets the binary firmware image from the file system by
>>>      calling request_firmware(). A copy is stored in memory.
>>>   5) The linux rproc calls rproc_start()
>>> 	- load the firrmware calling rproc_load_segments()
>>> 		=> we have to call tee_rproc_load_fw() to reload the firmware
>>
>> Loading the firmware in the TEE should be done right after request_firmware()
>> has been called, the same way it is done in the boot path.  If there isn't a
>> need to reload the TEE firmware than the TEE application should ignore the
>> request.
> 
> I need to prototype to verify this proposal.
> I will come back with a V3.

> 
> Thank you for the advice and review!
> 
> Regard,
> Arnaud
> 
>>
>>> 	- start the firmware calling ops->start()
>>>
>>> In first use case we have to load the firmware on rproc_parse_fw(), in second
>>> usecase on rproc_load_segments().
>>>
>>> This is the point I have tried to solve with the ddata->fw_loaded variable.
>>>
>>>>
>>>> I'm also confused as to why stm32_rproc_tee_elf_sanity_check() is calling
>>>> tee_rproc_load_fw().  There should be one call to load the firmware and another
>>>> to perform a sanity check on it.  If the sanity check is done at load time by
>>>> the secure world then ops::sanity_check() is NULL.
>>>
>>> Sure, make sense to remove the sanity_check ops
>>>
>>> Thanks,
>>> Arnaud
>>>
>>>>
>>>> Most of what this patchset does makes sense, but some of it needs to be moved
>>>> around.  
>>>>
>>>> Thanks,
>>>> Mathieu
>>>>
>>>>>
>>>>> If we want to integrate in remoteproc_core the solution could probably have to
>>>>> create the equivalent of the rproc_fw_boot() to load the firmware with an
>>>>> external method. Here is an example based on a new rproc_ops ( not tested)
>>>>>
>>>>> + static int rproc_fw_ext_boot(struct rproc *rproc, const struct firmware *fw)
>>>>> + {
>>>>> + 	struct device *dev = &rproc->dev;
>>>>> + 	const char *name = rproc->firmware;
>>>>> + 	int ret;
>>>>> +
>>>>> +
>>>>> + 	dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size);
>>>>> + 	
>>>>> + 	/* ops to load and start the remoteprocessor */
>>>>> + 	ret = rproc->ops->boot(rproc, fw);
>>>>> + 	if (ret)
>>>>> + 		return ret;
>>>>> +
>>>>> + 	/*
>>>>> + 	 * if enabling an IOMMU isn't relevant for this rproc, this is
>>>>> + 	 * just a nop
>>>>> + 	 */
>>>>> + 	ret = rproc_enable_iommu(rproc);
>>>>> + 	if (ret) {
>>>>> + 		dev_err(dev, "can't enable iommu: %d\n", ret);
>>>>> + 		return ret;
>>>>> + 	}
>>>>> +
>>>>> + 	/* Prepare rproc for firmware loading if needed */
>>>>> + 	ret = rproc_prepare_device(rproc);
>>>>> + 	if (ret) {
>>>>> + 		dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
>>>>> + 		goto disable_iommu;
>>>>> + 	}
>>>>> +
>>>>> + 	ret = rproc_set_rsc_table(rproc);
>>>>> + 	if (ret) {
>>>>> + 		dev_err(dev, "can't load resource table: %d\n", ret);
>>>>> + 		goto unprepare_device;
>>>>> + 	}
>>>>> +
>>>>> +
>>>>> + 	/* reset max_notifyid */
>>>>> + 	rproc->max_notifyid = -1;
>>>>> +
>>>>> + 	/* reset handled vdev */
>>>>> + 	rproc->nb_vdev = 0;
>>>>> +
>>>>> + 	/* handle fw resources which are required to boot rproc */
>>>>> + 	ret = rproc_handle_resources(rproc, rproc_loading_handlers);
>>>>> + 	if (ret) {
>>>>> + 		dev_err(dev, "Failed to process resources: %d\n", ret);
>>>>> + 		goto clean_up_resources;
>>>>> + 	}
>>>>> +
>>>>> + 	/* Allocate carveout resources associated to rproc */
>>>>> + 	ret = rproc_alloc_registered_carveouts(rproc);
>>>>> + 	if (ret) {
>>>>> + 		dev_err(dev, "Failed to allocate associated carveouts: %d\n",
>>>>> + 			ret);
>>>>> + 		goto clean_up_resources;
>>>>> + 	}
>>>>> +
>>>>> + 	return 0;
>>>>> +
>>>>> + clean_up_resources:
>>>>> + 	rproc_resource_cleanup(rproc);
>>>>> + unprepare_rproc:
>>>>> + 	/* release HW resources if needed */
>>>>> + 	rproc_unprepare_device(rproc);
>>>>> + disable_iommu:
>>>>> + 	rproc_disable_iommu(rproc);
>>>>> + 	return ret;
>>>>> + }
>>>>>
>>>>>
>>>>> int rproc_boot(struct rproc *rproc)
>>>>> {
>>>>> [...]
>>>>>
>>>>> - 		ret = rproc_fw_boot(rproc, firmware_p);
>>>>> + 		if(rproc->ops->boot)
>>>>> + 			ret = rproc_fw_ext_boot(rproc, firmware_p);
>>>>> + 		else
>>>>> + 			ret = rproc_fw_boot(rproc, firmware_p);
>>>>>
>>>>> Another advantage of this solution is that it opens the framework to other
>>>>> formats. For instance it could be a way to support dtb format requested in [RFC]
>>>>> Passing device-tree to remoteproc [1].
>>>>>
>>>>> [1]
>>>>> https://lore.kernel.org/linux-remoteproc/f67cd822-4e29-71f2-7c42-e11dbaa6cd8c at kalrayinc.com/T/#t
>>>>>
>>>>> Thanks,
>>>>> Arnaud
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>>> I touched on that before but please rename rproc_tee_get_rsc_table() to
>>>>>> rproc_tee_elf_load_rsc_table().  I also suggest to introduce a new function,
>>>>>> rproc_tee_get_loaded_rsc_table() that would be called from
>>>>>> rproc_tee_elf_load_rsc_table().  That way we don't need trproc->rsc_va.  
>>>>>>
>>>>>> I also think tee_rproc should be renamed to "rproc_tee_interface" and folded
>>>>>> under struct rproc.  
>>>>>>
>>>>>> With the above most of the problems with the current implementation should
>>>>>> naturally go away.
>>>>>>
>>>>>> Thanks,
>>>>>> Mathieu
>>>>>>
>>>>>>>
>>>>>>>>> +	ret = tee_rproc_load_fw(ddata->trproc, fw);
>>>>>>>>> +	if (ret)
>>>>>>>>> +		return ret;
>>>>>>>>> +	ddata->fw_loaded = true;
>>>>>>>>> +
>>>>>>>>> +	/* Update the resource table parameters. */
>>>>>>>>> +	if (rproc_tee_get_rsc_table(ddata->trproc)) {
>>>>>>>>> +		/* No resource table: reset the related fields. */
>>>>>>>>> +		rproc->cached_table = NULL;
>>>>>>>>> +		rproc->table_ptr = NULL;
>>>>>>>>> +		rproc->table_sz = 0;
>>>>>>>>> +	}
>>>>>>>>> +
>>>>>>>>> +	return 0;
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>> +static struct resource_table *
>>>>>>>>> +stm32_rproc_tee_elf_find_loaded_rsc_table(struct rproc *rproc,
>>>>>>>>> +					  const struct firmware *fw)
>>>>>>>>> +{
>>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>>> +
>>>>>>>>> +	return tee_rproc_get_loaded_rsc_table(ddata->trproc);
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>> +static int stm32_rproc_tee_start(struct rproc *rproc)
>>>>>>>>> +{
>>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>>> +
>>>>>>>>> +	return tee_rproc_start(ddata->trproc);
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>> +static int stm32_rproc_tee_attach(struct rproc *rproc)
>>>>>>>>> +{
>>>>>>>>> +	/* Nothing to do, remote proc already started by the secured context. */
>>>>>>>>> +	return 0;
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>> +static int stm32_rproc_tee_stop(struct rproc *rproc)
>>>>>>>>> +{
>>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>>> +	int err;
>>>>>>>>> +
>>>>>>>>> +	stm32_rproc_request_shutdown(rproc);
>>>>>>>>> +
>>>>>>>>> +	err = tee_rproc_stop(ddata->trproc);
>>>>>>>>> +	if (err)
>>>>>>>>> +		return err;
>>>>>>>>> +
>>>>>>>>> +	ddata->fw_loaded = false;
>>>>>>>>> +
>>>>>>>>> +	return stm32_rproc_release(rproc);
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>>  static int stm32_rproc_prepare(struct rproc *rproc)
>>>>>>>>>  {
>>>>>>>>>  	struct device *dev = rproc->dev.parent;
>>>>>>>>> @@ -319,7 +410,14 @@ static int stm32_rproc_prepare(struct rproc *rproc)
>>>>>>>>>  
>>>>>>>>>  static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
>>>>>>>>>  {
>>>>>>>>> -	if (rproc_elf_load_rsc_table(rproc, fw))
>>>>>>>>> +	struct stm32_rproc *ddata = rproc->priv;
>>>>>>>>> +	int ret;
>>>>>>>>> +
>>>>>>>>> +	if (ddata->trproc)
>>>>>>>>> +		ret = rproc_tee_get_rsc_table(ddata->trproc);
>>>>>>>>> +	else
>>>>>>>>> +		ret = rproc_elf_load_rsc_table(rproc, fw);
>>>>>>>>> +	if (ret)
>>>>>>>>>  		dev_warn(&rproc->dev, "no resource table found for this firmware\n");
>>>>>>>>>  
>>>>>>>>>  	return 0;
>>>>>>>>> @@ -693,8 +791,22 @@ static const struct rproc_ops st_rproc_ops = {
>>>>>>>>>  	.get_boot_addr	= rproc_elf_get_boot_addr,
>>>>>>>>>  };
>>>>>>>>>  
>>>>>>>>> +static const struct rproc_ops st_rproc_tee_ops = {
>>>>>>>>> +	.prepare	= stm32_rproc_prepare,
>>>>>>>>> +	.start		= stm32_rproc_tee_start,
>>>>>>>>> +	.stop		= stm32_rproc_tee_stop,
>>>>>>>>> +	.attach		= stm32_rproc_tee_attach,
>>>>>>>>> +	.kick		= stm32_rproc_kick,
>>>>>>>>> +	.parse_fw	= stm32_rproc_parse_fw,
>>>>>>>>> +	.find_loaded_rsc_table = stm32_rproc_tee_elf_find_loaded_rsc_table,
>>>>>>>>> +	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
>>>>>>>>> +	.sanity_check	= stm32_rproc_tee_elf_sanity_check,
>>>>>>>>> +	.load		= stm32_rproc_tee_elf_load,
>>>>>>>>> +};
>>>>>>>>> +
>>>>>>>>>  static const struct of_device_id stm32_rproc_match[] = {
>>>>>>>>> -	{ .compatible = "st,stm32mp1-m4" },
>>>>>>>>> +	{.compatible = "st,stm32mp1-m4",},
>>>>>>>>> +	{.compatible = "st,stm32mp1-m4-tee",},
>>>>>>>>>  	{},
>>>>>>>>>  };
>>>>>>>>>  MODULE_DEVICE_TABLE(of, stm32_rproc_match);
>>>>>>>>> @@ -853,6 +965,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>>>>>>  	struct device *dev = &pdev->dev;
>>>>>>>>>  	struct stm32_rproc *ddata;
>>>>>>>>>  	struct device_node *np = dev->of_node;
>>>>>>>>> +	struct tee_rproc *trproc = NULL;
>>>>>>>>>  	struct rproc *rproc;
>>>>>>>>>  	unsigned int state;
>>>>>>>>>  	int ret;
>>>>>>>>> @@ -861,11 +974,31 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>>>>>>  	if (ret)
>>>>>>>>>  		return ret;
>>>>>>>>>  
>>>>>>>>> -	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
>>>>>>>>> -	if (!rproc)
>>>>>>>>> -		return -ENOMEM;
>>>>>>>>> +	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
>>>>>>>>> +		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
>>>>>>>>> +		if (IS_ERR(trproc)) {
>>>>>>>>> +			dev_err_probe(dev, PTR_ERR(trproc),
>>>>>>>>> +				      "signed firmware not supported by TEE\n");
>>>>>>>>> +			return PTR_ERR(trproc);
>>>>>>>>> +		}
>>>>>>>>> +		/*
>>>>>>>>> +		 * Delegate the firmware management to the secure context.
>>>>>>>>> +		 * The firmware loaded has to be signed.
>>>>>>>>> +		 */
>>>>>>>>> +		dev_info(dev, "Support of signed firmware only\n");
>>>>>>>>
>>>>>>>> Not sure what this adds.  Please remove.
>>>>>>>
>>>>>>> This is used to inform the user that only a signed firmware can be loaded, not
>>>>>>> an ELF file.
>>>>>>> I have a patch in my pipe to provide the supported format in the debugfs. In a
>>>>>>> first step, I can suppress this message and we can revisit the issue when I push
>>>>>>> the debugfs proposal.
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Arnaud
>>>>>>>
>>>>>>>>
>>>>>>>>> +	}
>>>>>>>>> +	rproc = rproc_alloc(dev, np->name,
>>>>>>>>> +			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
>>>>>>>>> +			    NULL, sizeof(*ddata));
>>>>>>>>> +	if (!rproc) {
>>>>>>>>> +		ret = -ENOMEM;
>>>>>>>>> +		goto free_tee;
>>>>>>>>> +	}
>>>>>>>>>  
>>>>>>>>>  	ddata = rproc->priv;
>>>>>>>>> +	ddata->trproc = trproc;
>>>>>>>>> +	if (trproc)
>>>>>>>>> +		trproc->rproc = rproc;
>>>>>>>>>  
>>>>>>>>>  	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
>>>>>>>>>  
>>>>>>>>> @@ -916,6 +1049,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>>>>>>>>  		device_init_wakeup(dev, false);
>>>>>>>>>  	}
>>>>>>>>>  	rproc_free(rproc);
>>>>>>>>> +free_tee:
>>>>>>>>> +	if (trproc)
>>>>>>>>> +		tee_rproc_unregister(trproc);
>>>>>>>>> +
>>>>>>>>>  	return ret;
>>>>>>>>>  }
>>>>>>>>>  
>>>>>>>>> @@ -937,6 +1074,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
>>>>>>>>>  		device_init_wakeup(dev, false);
>>>>>>>>>  	}
>>>>>>>>>  	rproc_free(rproc);
>>>>>>>>> +	if (ddata->trproc)
>>>>>>>>> +		tee_rproc_unregister(ddata->trproc);
>>>>>>>>>  }
>>>>>>>>>  
>>>>>>>>>  static int stm32_rproc_suspend(struct device *dev)
>>>>>>>>> -- 
>>>>>>>>> 2.25.1
>>>>>>>>>
> _______________________________________________
> Linux-stm32 mailing list
> Linux-stm32 at st-md-mailman.stormreply.com
> https://st-md-mailman.stormreply.com/mailman/listinfo/linux-stm32


From thierry.reding at gmail.com  Tue Feb 13 07:51:34 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Tue, 13 Feb 2024 16:51:34 +0100
Subject: [PATCH net-next v2 3/3] net: stmmac: Configure AXI on Tegra234
 MGBE
In-Reply-To: <uzzzxx3mv6yoslijhhzdzyossvcvi52jgbulza54uqh2wrm5kd@ddd5o56b2dhu>
References: <20240202-stmmac-axi-config-v2-0-64eab2bab17b@nvidia.com>
 <20240202-stmmac-axi-config-v2-3-64eab2bab17b@nvidia.com>
 <uzzzxx3mv6yoslijhhzdzyossvcvi52jgbulza54uqh2wrm5kd@ddd5o56b2dhu>
Message-ID: <CZ42KOP6ECUC.EEIHWA147NV9@gmail.com>

On Mon Feb 5, 2024 at 1:44 AM CET, Serge Semin wrote:
> On Fri, Feb 02, 2024 at 12:53:35PM +0100, Thierry Reding wrote:
> > From: Thierry Reding <treding at nvidia.com>
> > 
> > Allow the device to use bursts and increase the maximum number of
> > outstanding requests to improve performance. Measurements show an
> > increase in throughput of around 5x on a 1 Gbps link.
> > 
> > Signed-off-by: Thierry Reding <treding at nvidia.com>
> > ---
> >  drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> > index bab57d1675df..b6bfa48f279d 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> > @@ -199,6 +199,12 @@ static void mgbe_uphy_lane_bringup_serdes_down(struct net_device *ndev, void *mg
> >  	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
> >  }
> >  
> > +static const struct stmmac_axi tegra234_mgbe_axi = {
> > +	.axi_wr_osr_lmt = 63,
> > +	.axi_rd_osr_lmt = 63,
> > +	.axi_blen = { 256, },
> > +};
> > +
> >  static int tegra_mgbe_probe(struct platform_device *pdev)
> >  {
> >  	struct plat_stmmacenet_data *plat;
> > @@ -284,6 +290,9 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
> >  	if (err < 0)
> >  		goto disable_clks;
> >  
> > +	/* setup default AXI configuration */
> > +	res.axi = &tegra234_mgbe_axi;
> > +
> >  	plat = devm_stmmac_probe_config_dt(pdev, &res);
> >  	if (IS_ERR(plat)) {
> >  		err = PTR_ERR(plat);
>
> The entire series can be converted to just a few lines of change:

Sorry for the delay, I missed this reply.

>  	plat = devm_stmmac_probe_config_dt(pdev, res.mac);
>  	if (IS_ERR(plat)) {
>  		err = PTR_ERR(plat);
>  		goto disable_clks;
>  	}
> +
> +	if (IS_ERR_OR_NULL(plat->axi)) {
> +		plat->axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
> +		if (!plat->axi) {
> +			ret = -ENOMEM;
> +			goto disable_clks;
> +		}
> +	} /* else memset plat->axi with zeros if you wish */
> +
> +	plat->axi->axi_wr_osr_lmt = 63;
> +	plat->axi->axi_rd_osr_lmt = 63;
> +	plat->axi->axi_blen[0] = 256;
>  
>  	plat->has_xgmac = 1;
>  	plat->flags |= STMMAC_FLAG_TSO_EN;
>  	plat->pmt = 1;
>
> Please don't overcomplicate the already overcomplicated driver with a
> functionality which can be reached by the default one. In this case
> the easiest way is to let the generic code work and then
> override/replace/fix/etc the retrieved values. Thus there won't be
> need in adding the redundant functionality and keep the generic
> DT-platform code a bit simpler to read.

I'm not sure I understand how this is overcomplicating things. The code
is pretty much unchanged, except that the AXI configuration can now have
driver-specified defaults before the DT is parsed. Perhaps I need to add
comments to make that a bit clearer?

While your version is certainly simpler it has the drawback that it no
longer allows the platform defaults to be overridden in device tree. I
would prefer if the defaults can be derived from the compatible string
but if need be for those defaults to still be overridable from device
tree.

Thierry
-------------- 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/20240213/e3bc984f/attachment-0001.sig>

From jm at ti.com  Tue Feb 13 07:52:33 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 09:52:33 -0600
Subject: [PATCH v2 6/9] arm64: dts: ti: k3-am6*: Remove DLL properties for
 soft PHYs
In-Reply-To: <5f9fd69e-d3f6-4293-8746-06173f24e521@phytec.de>
References: <20240213002416.1560357-1-jm@ti.com>
 <20240213002416.1560357-7-jm@ti.com>
 <5f9fd69e-d3f6-4293-8746-06173f24e521@phytec.de>
Message-ID: <e805b72a-17a2-4a54-bb90-dab44a551711@ti.com>

Hi Wadim,

On 2/12/24 11:26 PM, Wadim Egorov wrote:
> Hi Judith,
> 
> Am 13.02.24 um 01:24 schrieb Judith Mendez:
>> Remove DLL properties which are not applicable for soft PHYs
>> since these PHYs do not have a DLL to enable.
>>
>> Signed-off-by: Judith Mendez <jm at ti.com>
>> ---
>> ? arch/arm64/boot/dts/ti/k3-am62-main.dtsi????????????? | 3 ---
>> ? arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi?????? | 1 -
>> ? arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi???? | 1 -
>> ? arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi??????? | 1 -
>> ? arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi?????? | 1 -
>> ? arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi??????????? | 2 --
>> ? arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts??????? | 3 ---
>> ? arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts | 1 -
>> ? arch/arm64/boot/dts/ti/k3-am62a-main.dtsi???????????? | 1 -
>> ? arch/arm64/boot/dts/ti/k3-am62a7-sk.dts?????????????? | 1 -
>> ? arch/arm64/boot/dts/ti/k3-am62p5-sk.dts?????????????? | 1 -
>> ? arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi??????? | 2 --
>> ? arch/arm64/boot/dts/ti/k3-am64-main.dtsi????????????? | 1 -
>> ? arch/arm64/boot/dts/ti/k3-am642-evm.dts?????????????? | 1 -
>> ? arch/arm64/boot/dts/ti/k3-am642-sk.dts??????????????? | 1 -
> 
> what about sdhci1 node updates on
>  ? - k3-am642-phyboard-electra-rdk.dts
>  ? - k3-am642-tqma64xxl-mbax4xxl.dts
> 

The same patch applies for this boards.

> Also does this apply only for am64 and sdhci1 (and not sdhci0)?
> In your v1 you are describing that only AM64x and AM62p devices have a 
> DLL to update the drive strength.
> Trying to understand why only one of the interfaces gets updated.

This patch only applies for AM64x sdhci1 node, since sdhci1
is a soft PHY and does not have a DLL.

~ Judith

> 
> Regards,
> Wadim
> 
>> ? 15 files changed, 21 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi 
>> b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>> index fe0cc4a9a501..79ed5cbbbda1 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>> @@ -561,7 +561,6 @@ sdhci0: mmc at fa10000 {
>> ????????? assigned-clock-parents = <&k3_clks 57 8>;
>> ????????? mmc-ddr-1_8v;
>> ????????? mmc-hs200-1_8v;
>> -??????? ti,trm-icp = <0x2>;
>> ????????? bus-width = <8>;
>> ????????? ti,clkbuf-sel = <0x7>;
>> ????????? ti,otap-del-sel-legacy = <0x0>;
>> @@ -580,7 +579,6 @@ sdhci1: mmc at fa00000 {
>> ????????? power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>> ????????? clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
>> ????????? clock-names = "clk_ahb", "clk_xin";
>> -??????? ti,trm-icp = <0x2>;
>> ????????? ti,otap-del-sel-legacy = <0x8>;
>> ????????? ti,otap-del-sel-sd-hs = <0x0>;
>> ????????? ti,otap-del-sel-sdr12 = <0x0>;
>> @@ -604,7 +602,6 @@ sdhci2: mmc at fa20000 {
>> ????????? power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
>> ????????? clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
>> ????????? clock-names = "clk_ahb", "clk_xin";
>> -??????? ti,trm-icp = <0x2>;
>> ????????? ti,otap-del-sel-legacy = <0x8>;
>> ????????? ti,otap-del-sel-sd-hs = <0x0>;
>> ????????? ti,otap-del-sel-sdr12 = <0x0>;
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi 
>> b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
>> index 3372a256c90f..43488cc8bcb1 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
>> @@ -317,7 +317,6 @@ serial_flash: flash at 0 {
>> ? &sdhci0 {
>> ????? pinctrl-names = "default";
>> ????? pinctrl-0 = <&main_mmc0_pins_default>;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? disable-wp;
>> ????? non-removable;
>> ????? status = "okay";
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi 
>> b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
>> index bf6d27e70bc4..6c4cec8728e4 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
>> @@ -185,7 +185,6 @@ &ospi0 {
>> ? /* Verdin SD_1 */
>> ? &sdhci1 {
>> -??? ti,driver-strength-ohm = <33>;
>> ????? status = "okay";
>> ? };
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi 
>> b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
>> index 680071688dcb..be62648e7818 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
>> @@ -206,7 +206,6 @@ &ospi0 {
>> ? /* Verdin SD_1 */
>> ? &sdhci1 {
>> -??? ti,driver-strength-ohm = <33>;
>> ????? status = "okay";
>> ? };
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi 
>> b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
>> index a6808b10c7b2..4768ef42c4fc 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
>> @@ -26,7 +26,6 @@ &sdhci2 {
>> ????? mmc-pwrseq = <&wifi_pwrseq>;
>> ????? non-removable;
>> ????? ti,fails-without-test-cd;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? vmmc-supply = <&reg_3v3>;
>> ????? status = "okay";
>> ? };
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi 
>> b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
>> index 6a06724b6d16..d68310444bcb 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
>> @@ -1407,7 +1407,6 @@ &sdhci0 {
>> ????? pinctrl-names = "default";
>> ????? pinctrl-0 = <&pinctrl_sdhci0>;
>> ????? non-removable;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? status = "okay";
>> ? };
>> @@ -1416,7 +1415,6 @@ &sdhci1 {
>> ????? pinctrl-names = "default";
>> ????? pinctrl-0 = <&pinctrl_sdhci1>;
>> ????? disable-wp;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? vmmc-supply = <&reg_sdhc1_vmmc>;
>> ????? vqmmc-supply = <&reg_sdhc1_vqmmc>;
>> ????? status = "disabled";
>> diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts 
>> b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
>> index 3b4246ce49de..bb6a5837bcb3 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
>> @@ -819,7 +819,6 @@ &sdhci0 {
>> ????? bootph-all;
>> ????? pinctrl-names = "default";
>> ????? pinctrl-0 = <&emmc_pins_default>;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? disable-wp;
>> ????? status = "okay";
>> ? };
>> @@ -832,7 +831,6 @@ &sdhci1 {
>> ????? vmmc-supply = <&vdd_3v3_sd>;
>> ????? vqmmc-supply = <&vdd_sd_dv>;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? disable-wp;
>> ????? cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
>> ????? cd-debounce-delay-ms = <100>;
>> @@ -849,7 +847,6 @@ &sdhci2 {
>> ????? ti,fails-without-test-cd;
>> ????? cap-power-off-card;
>> ????? keep-power-in-suspend;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? assigned-clocks = <&k3_clks 157 158>;
>> ????? assigned-clock-parents = <&k3_clks 157 160>;
>> ????? #address-cells = <1>;
>> diff --git a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts 
>> b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
>> index 5c31f0453def..a83a90497857 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
>> @@ -334,7 +334,6 @@ &sdhci1 {
>> ????? vqmmc-supply = <&vddshv5_sdio>;
>> ????? pinctrl-names = "default";
>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? disable-wp;
>> ????? no-1-8-v;
>> ????? status = "okay";
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi 
>> b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
>> index 6806288ec227..f283777d54b4 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
>> @@ -561,7 +561,6 @@ sdhci1: mmc at fa00000 {
>> ????????? power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>> ????????? clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
>> ????????? clock-names = "clk_ahb", "clk_xin";
>> -??????? ti,trm-icp = <0x2>;
>> ????????? ti,otap-del-sel-legacy = <0x0>;
>> ????????? ti,otap-del-sel-sd-hs = <0x0>;
>> ????????? ti,otap-del-sel-sdr12 = <0xf>;
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts 
>> b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
>> index c99b2e90f76d..f241637a5642 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
>> @@ -582,7 +582,6 @@ &sdhci1 {
>> ????? vmmc-supply = <&vdd_mmc1>;
>> ????? pinctrl-names = "default";
>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? disable-wp;
>> ? };
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts 
>> b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>> index 8c73587b0b62..5c9b73726ebd 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>> @@ -422,7 +422,6 @@ &sdhci1 {
>> ????? vqmmc-supply = <&vddshv_sdio>;
>> ????? pinctrl-names = "default";
>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? disable-wp;
>> ????? bootph-all;
>> ? };
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi 
>> b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
>> index 6dd496cd459a..3c45782ab2b7 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
>> @@ -411,7 +411,6 @@ &sdhci0 {
>> ????? status = "okay";
>> ????? pinctrl-names = "default";
>> ????? pinctrl-0 = <&main_mmc0_pins_default>;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? disable-wp;
>> ? };
>> @@ -421,7 +420,6 @@ &sdhci1 {
>> ????? status = "okay";
>> ????? pinctrl-names = "default";
>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? disable-wp;
>> ? };
>> diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi 
>> b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
>> index 9bfa0a969bfc..a29847735c6e 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
>> @@ -646,7 +646,6 @@ sdhci1: mmc at fa00000 {
>> ????????? power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>> ????????? clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
>> ????????? clock-names = "clk_ahb", "clk_xin";
>> -??????? ti,trm-icp = <0x2>;
>> ????????? ti,otap-del-sel-legacy = <0x0>;
>> ????????? ti,otap-del-sel-sd-hs = <0x0>;
>> ????????? ti,otap-del-sel-sdr12 = <0xf>;
>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts 
>> b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> index 5c546ae76d3e..f308076d608a 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>> @@ -508,7 +508,6 @@ &sdhci1 {
>> ????? pinctrl-names = "default";
>> ????? bus-width = <4>;
>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? disable-wp;
>> ? };
>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts 
>> b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
>> index cce04e188ff6..b286eaa02ada 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
>> @@ -471,7 +471,6 @@ &sdhci1 {
>> ????? pinctrl-names = "default";
>> ????? bus-width = <4>;
>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>> -??? ti,driver-strength-ohm = <50>;
>> ????? disable-wp;
>> ? };



From edumazet at google.com  Tue Feb 13 07:52:52 2024
From: edumazet at google.com (Eric Dumazet)
Date: Tue, 13 Feb 2024 16:52:52 +0100
Subject: [PATCH net v3] net: stmmac: protect updates of 64-bit statistics counters
In-Reply-To: <20d94512-c4f2-49f7-ac97-846dc24a6730@roeck-us.net>
References: <20240203190927.19669-1-petr@tesarici.cz> <ea1567d9-ce66-45e6-8168-ac40a47d1821@roeck-us.net>
 <Zct5qJcZw0YKx54r@xhacker> <CANn89i+4tVWezqr=BYZ5AF=9EgV2EPqhdHun=u=ga32CEJ4BXQ@mail.gmail.com>
 <20d94512-c4f2-49f7-ac97-846dc24a6730@roeck-us.net>
Message-ID: <CANn89iL1piwsbsBx4Z=kySUfmPa9LbZn-SNthgA+W6NEnojgSQ@mail.gmail.com>

On Tue, Feb 13, 2024 at 4:26?PM Guenter Roeck <linux at roeck-us.net> wrote:
>
> On Tue, Feb 13, 2024 at 03:51:35PM +0100, Eric Dumazet wrote:
> > On Tue, Feb 13, 2024 at 3:29?PM Jisheng Zhang <jszhang at kernel.org> wrote:
> > >
> > > On Sun, Feb 11, 2024 at 08:30:21PM -0800, Guenter Roeck wrote:
> > > > Hi,
> > > >
> > > > On Sat, Feb 03, 2024 at 08:09:27PM +0100, Petr Tesarik wrote:
> > > > > As explained by a comment in <linux/u64_stats_sync.h>, write side of struct
> > > > > u64_stats_sync must ensure mutual exclusion, or one seqcount update could
> > > > > be lost on 32-bit platforms, thus blocking readers forever. Such lockups
> > > > > have been observed in real world after stmmac_xmit() on one CPU raced with
> > > > > stmmac_napi_poll_tx() on another CPU.
> > > > >
> > > > > To fix the issue without introducing a new lock, split the statics into
> > > > > three parts:
> > > > >
> > > > > 1. fields updated only under the tx queue lock,
> > > > > 2. fields updated only during NAPI poll,
> > > > > 3. fields updated only from interrupt context,
> > > > >
> > > > > Updates to fields in the first two groups are already serialized through
> > > > > other locks. It is sufficient to split the existing struct u64_stats_sync
> > > > > so that each group has its own.
> > > > >
> > > > > Note that tx_set_ic_bit is updated from both contexts. Split this counter
> > > > > so that each context gets its own, and calculate their sum to get the total
> > > > > value in stmmac_get_ethtool_stats().
> > > > >
> > > > > For the third group, multiple interrupts may be processed by different CPUs
> > > > > at the same time, but interrupts on the same CPU will not nest. Move fields
> > > > > from this group to a newly created per-cpu struct stmmac_pcpu_stats.
> > > > >
> > > > > Fixes: 133466c3bbe1 ("net: stmmac: use per-queue 64 bit statistics where necessary")
> > > > > Link: https://lore.kernel.org/netdev/Za173PhviYg-1qIn at torres.zugschlus.de/t/
> > > > > Cc: stable at vger.kernel.org
> > > > > Signed-off-by: Petr Tesarik <petr at tesarici.cz>
> > > >
> > > > This patch results in a lockdep splat. Backtrace and bisect results attached.
> > > >
> > > > Guenter
> > > >
> > > > ---
> > > > [   33.736728] ================================
> > > > [   33.736805] WARNING: inconsistent lock state
> > > > [   33.736953] 6.8.0-rc4 #1 Tainted: G                 N
> > > > [   33.737080] --------------------------------
> > > > [   33.737155] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
> > > > [   33.737309] kworker/0:2/39 [HC1[1]:SC0[2]:HE0:SE0] takes:
> > > > [   33.737459] ef792074 (&syncp->seq#2){?...}-{0:0}, at: sun8i_dwmac_dma_interrupt+0x9c/0x28c
> > > > [   33.738206] {HARDIRQ-ON-W} state was registered at:
> > > > [   33.738318]   lock_acquire+0x11c/0x368
> > > > [   33.738431]   __u64_stats_update_begin+0x104/0x1ac
> > > > [   33.738525]   stmmac_xmit+0x4d0/0xc58
> > >
> > > interesting lockdep splat...
> > > stmmac_xmit() operates on txq_stats->q_syncp, while the
> > > sun8i_dwmac_dma_interrupt() operates on pcpu's priv->xstats.pcpu_stats
> > > they are different syncp. so how does lockdep splat happen.
> >
> > Right, I do not see anything obvious yet.
>
> Wild guess: I think it maybe saying that due to
>
>         inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
>
> the critical code may somehow be interrupted and, while handling the
> interrupt, try to acquire the same lock again.

This should not happen, the 'syncp' are different. They have different
lockdep classes.

One is exclusively used from hard irq context.

The second one only used from BH context.


From francesco at dolcini.it  Tue Feb 13 07:56:22 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Tue, 13 Feb 2024 16:56:22 +0100
Subject: [PATCH v1] arm64: dts: ti: verdin-am62: Set VDD CORE minimum voltage to 0.75V
Message-ID: <20240213155622.18309-1-francesco@dolcini.it>

From: Francesco Dolcini <francesco.dolcini at toradex.com>

Set VDD_CORE minimum voltage to 0.75V, TI AM62 can run at either 0.75V
or 0.85V depending on the actual speed grade and on the maximum
configured speed (1.4GHz frequency requires 0.85V).

The actual value is programmed into the PMIC EEPROM during manufacturing
(according to the SOC speed grade) and this ensure that both the voltage
values are valid and therefore the OS will not overwrite the value
programmed into the PMIC.

Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
---
 arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
index 6a06724b6d16..4129566172a2 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
@@ -1118,7 +1118,7 @@ reg_vdd_core: buck1 {
 				regulator-always-on;
 				regulator-boot-on;
 				regulator-max-microvolt = <850000>;
-				regulator-min-microvolt = <850000>;
+				regulator-min-microvolt = <750000>;
 				regulator-name = "+VDD_CORE (PMIC BUCK1)";
 			};
 
-- 
2.39.2



From Frank.li at nxp.com  Tue Feb 13 07:58:01 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 13 Feb 2024 10:58:01 -0500
Subject: [PATCH v10 01/14] PCI: imx6: Simplify clock handling by using
 clk_bulk*() function
In-Reply-To: <ZcuLSkvPuyMXsQeD@lpieralisi>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <20240205173335.1120469-2-Frank.Li@nxp.com>
 <ZcuLSkvPuyMXsQeD@lpieralisi>
Message-ID: <ZcuRiQ0brp2SfmNU@lizhi-Precision-Tower-5810>

On Tue, Feb 13, 2024 at 04:31:22PM +0100, Lorenzo Pieralisi wrote:
> On Mon, Feb 05, 2024 at 12:33:22PM -0500, Frank Li wrote:
> > Refector the clock handling logic. Add 'clk_names' define in drvdata. Use
> > clk_bulk*() api simplify the code.
> > 
> > Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > 
> > Notes:
> >     Change from v9 to v10
> >     - fixed missed delete a case, which need failthrough to next one.
> >     Change from v8 to v9
> >     - change clks names
> >     - Add Manivannan's review tag
> >     
> >     Change from v7 to v8
> >     - update comment message
> >     - using ARRAY_SIZE to count clk_names.
> >     Change from v6 to v7
> >     - none
> >     Change from v4 to v5
> >     - update commit message
> >     - direct using clk name list, instead of macro
> >     - still keep caculate clk list count because sizeof return pre allocated
> >     array size.
> >     
> >     Change from v3 to v4
> >     - using clk_bulk_*() API
> >     Change from v1 to v3
> >     - none
> >     
> >     Change from v4 to v5
> >     - update commit message
> >     - direct using clk name list, instead of macro
> >     - still keep caculate clk list count because sizeof return pre allocated
> >     array size.
> >     
> >     Change from v3 to v4
> >     - using clk_bulk_*() API
> >     Change from v1 to v3
> >     - none
> >     
> >     Change from v8 to v9
> >     - change clks names
> >     - Add Manivannan's review tag
> >     
> >     Change from v7 to v8
> >     - update comment message
> >     - using ARRAY_SIZE to count clk_names.
> >     Change from v6 to v7
> >     - none
> >     Change from v4 to v5
> >     - update commit message
> >     - direct using clk name list, instead of macro
> >     - still keep caculate clk list count because sizeof return pre allocated
> >     array size.
> >     
> >     Change from v3 to v4
> >     - using clk_bulk_*() API
> >     Change from v1 to v3
> >     - none
> >     
> >     Change from v4 to v5
> >     - update commit message
> >     - direct using clk name list, instead of macro
> >     - still keep caculate clk list count because sizeof return pre allocated
> >     array size.
> >     
> >     Change from v3 to v4
> >     - using clk_bulk_*() API
> >     Change from v1 to v3
> >     - none
> > 
> >  drivers/pci/controller/dwc/pci-imx6.c | 138 ++++++++++----------------
> >  1 file changed, 50 insertions(+), 88 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> > index 74703362aeec7..82854e94c5621 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -61,12 +61,16 @@ enum imx6_pcie_variants {
> >  #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
> >  #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
> >  
> > +#define IMX6_PCIE_MAX_CLKS       6
> > +
> >  struct imx6_pcie_drvdata {
> >  	enum imx6_pcie_variants variant;
> >  	enum dw_pcie_device_mode mode;
> >  	u32 flags;
> >  	int dbi_length;
> >  	const char *gpr;
> > +	const char * const *clk_names;
> > +	const u32 clks_cnt;
> >  };
> >  
> >  struct imx6_pcie {
> > @@ -74,11 +78,7 @@ struct imx6_pcie {
> >  	int			reset_gpio;
> >  	bool			gpio_active_high;
> >  	bool			link_is_up;
> > -	struct clk		*pcie_bus;
> > -	struct clk		*pcie_phy;
> > -	struct clk		*pcie_inbound_axi;
> > -	struct clk		*pcie;
> > -	struct clk		*pcie_aux;
> > +	struct clk_bulk_data	clks[IMX6_PCIE_MAX_CLKS];
> 
> Why can't you allocate this dynamically ?

Engineer choose. clk_bulk_data is small data struct, two pointers (16byte
in 64bit system). clks in imx is 3-4, Over half already used(compared 6).
waste case only wast 48byte.
 
Dynamically allocate can't save much memory, there are some extra manage
meta data for dynamical memory, which may bigger than 48byte.

Frank

> 
> >  	struct regmap		*iomuxc_gpr;
> >  	u16			msi_ctrl;
> >  	u32			controller_id;
> > @@ -407,13 +407,18 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
> >  
> >  static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
> >  {
> > -	unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy);
> > +	unsigned long phy_rate = 0;
> >  	int mult, div;
> >  	u16 val;
> > +	int i;
> >  
> >  	if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY))
> >  		return 0;
> >  
> > +	for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
> > +		if (strncmp(imx6_pcie->clks[i].id, "pcie_phy", 8) == 0)
> > +			phy_rate = clk_get_rate(imx6_pcie->clks[i].clk);
> > +
> >  	switch (phy_rate) {
> >  	case 125000000:
> >  		/*
> > @@ -550,19 +555,11 @@ static int imx6_pcie_attach_pd(struct device *dev)
> >  
> >  static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
> >  {
> > -	struct dw_pcie *pci = imx6_pcie->pci;
> > -	struct device *dev = pci->dev;
> >  	unsigned int offset;
> >  	int ret = 0;
> >  
> >  	switch (imx6_pcie->drvdata->variant) {
> >  	case IMX6SX:
> > -		ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
> > -		if (ret) {
> > -			dev_err(dev, "unable to enable pcie_axi clock\n");
> > -			break;
> > -		}
> > -
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
> >  				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
> >  		break;
> > @@ -589,12 +586,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
> >  	case IMX8MQ_EP:
> >  	case IMX8MP:
> >  	case IMX8MP_EP:
> > -		ret = clk_prepare_enable(imx6_pcie->pcie_aux);
> > -		if (ret) {
> > -			dev_err(dev, "unable to enable pcie_aux clock\n");
> > -			break;
> > -		}
> > -
> >  		offset = imx6_pcie_grp_offset(imx6_pcie);
> >  		/*
> >  		 * Set the over ride low and enabled
> > @@ -615,9 +606,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
> >  static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
> >  {
> >  	switch (imx6_pcie->drvdata->variant) {
> > -	case IMX6SX:
> > -		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
> > -		break;
> >  	case IMX6QP:
> >  	case IMX6Q:
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> > @@ -631,14 +619,6 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
> >  				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
> >  				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
> >  		break;
> > -	case IMX8MM:
> > -	case IMX8MM_EP:
> > -	case IMX8MQ:
> > -	case IMX8MQ_EP:
> > -	case IMX8MP:
> > -	case IMX8MP_EP:
> > -		clk_disable_unprepare(imx6_pcie->pcie_aux);
> > -		break;
> >  	default:
> >  		break;
> >  	}
> > @@ -650,23 +630,9 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
> >  	struct device *dev = pci->dev;
> >  	int ret;
> >  
> > -	ret = clk_prepare_enable(imx6_pcie->pcie_phy);
> > -	if (ret) {
> > -		dev_err(dev, "unable to enable pcie_phy clock\n");
> > +	ret = clk_bulk_prepare_enable(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
> > +	if (ret)
> >  		return ret;
> > -	}
> > -
> > -	ret = clk_prepare_enable(imx6_pcie->pcie_bus);
> > -	if (ret) {
> > -		dev_err(dev, "unable to enable pcie_bus clock\n");
> > -		goto err_pcie_bus;
> > -	}
> > -
> > -	ret = clk_prepare_enable(imx6_pcie->pcie);
> > -	if (ret) {
> > -		dev_err(dev, "unable to enable pcie clock\n");
> > -		goto err_pcie;
> > -	}
> >  
> >  	ret = imx6_pcie_enable_ref_clk(imx6_pcie);
> >  	if (ret) {
> > @@ -679,11 +645,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
> >  	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);
> > +	clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
> >  
> >  	return ret;
> >  }
> > @@ -691,9 +653,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
> >  static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
> >  {
> >  	imx6_pcie_disable_ref_clk(imx6_pcie);
> > -	clk_disable_unprepare(imx6_pcie->pcie);
> > -	clk_disable_unprepare(imx6_pcie->pcie_bus);
> > -	clk_disable_unprepare(imx6_pcie->pcie_phy);
> > +	clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
> >  }
> >  
> >  static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
> > @@ -1252,6 +1212,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> >  	struct device_node *node = dev->of_node;
> >  	int ret;
> >  	u16 val;
> > +	int i;
> >  
> >  	imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
> >  	if (!imx6_pcie)
> > @@ -1305,32 +1266,20 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> >  		return imx6_pcie->reset_gpio;
> >  	}
> >  
> > -	/* Fetch clocks */
> > -	imx6_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus");
> > -	if (IS_ERR(imx6_pcie->pcie_bus))
> > -		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_bus),
> > -				     "pcie_bus clock source missing or invalid\n");
> > +	if (imx6_pcie->drvdata->clks_cnt >= IMX6_PCIE_MAX_CLKS)
> > +		return dev_err_probe(dev, -ENOMEM, "clks_cnt is too big\n");
> 
> Same question as above, this should not fail if the clks array is
> dynamically allocated according to imx6_pcie->drvdata->clks_cnt.

Devm_kzalloc also may return NULL. Still need check. This safe check only
meanful when add new platform. imx6_pcie->drvdata->clks_cnt is static data.

It should never failure at running time. But, devm_kzalloc may failure
at run time.

It is not big deal. It's most likely personal tast. For small static data,
I perfer use static memory.

Frank

> 
> Lorenzo
> 
> >  
> > -	imx6_pcie->pcie = devm_clk_get(dev, "pcie");
> > -	if (IS_ERR(imx6_pcie->pcie))
> > -		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie),
> > -				     "pcie clock source missing or invalid\n");
> > +	for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
> > +		imx6_pcie->clks[i].id = imx6_pcie->drvdata->clk_names[i];
> > +
> > +	/* Fetch clocks */
> > +	ret = devm_clk_bulk_get(dev, imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
> > +	if (ret)
> > +		return ret;
> >  
> >  	switch (imx6_pcie->drvdata->variant) {
> > -	case IMX6SX:
> > -		imx6_pcie->pcie_inbound_axi = devm_clk_get(dev,
> > -							   "pcie_inbound_axi");
> > -		if (IS_ERR(imx6_pcie->pcie_inbound_axi))
> > -			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_inbound_axi),
> > -					     "pcie_inbound_axi clock missing or invalid\n");
> > -		break;
> >  	case IMX8MQ:
> >  	case IMX8MQ_EP:
> > -		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
> > -		if (IS_ERR(imx6_pcie->pcie_aux))
> > -			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
> > -					     "pcie_aux clock source missing or invalid\n");
> > -		fallthrough;
> >  	case IMX7D:
> >  		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
> >  			imx6_pcie->controller_id = 1;
> > @@ -1353,10 +1302,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> >  	case IMX8MM_EP:
> >  	case IMX8MP:
> >  	case IMX8MP_EP:
> > -		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
> > -		if (IS_ERR(imx6_pcie->pcie_aux))
> > -			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
> > -					     "pcie_aux clock source missing or invalid\n");
> >  		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
> >  									 "apps");
> >  		if (IS_ERR(imx6_pcie->apps_reset))
> > @@ -1372,14 +1317,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> >  	default:
> >  		break;
> >  	}
> > -	/* Don't fetch the pcie_phy clock, if it has abstract PHY driver */
> > -	if (imx6_pcie->phy == NULL) {
> > -		imx6_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy");
> > -		if (IS_ERR(imx6_pcie->pcie_phy))
> > -			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_phy),
> > -					     "pcie_phy clock source missing or invalid\n");
> > -	}
> > -
> >  
> >  	/* Grab turnoff reset */
> >  	imx6_pcie->turnoff_reset = devm_reset_control_get_optional_exclusive(dev, "turnoff");
> > @@ -1470,6 +1407,11 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
> >  	imx6_pcie_assert_core_reset(imx6_pcie);
> >  }
> >  
> > +static const char * const imx6q_clks[] = {"pcie_bus", "pcie", "pcie_phy"};
> > +static const char * const imx8mm_clks[] = {"pcie_bus", "pcie", "pcie_aux"};
> > +static const char * const imx8mq_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_aux"};
> > +static const char * const imx6sx_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_inbound_axi"};
> > +
> >  static const struct imx6_pcie_drvdata drvdata[] = {
> >  	[IMX6Q] = {
> >  		.variant = IMX6Q,
> > @@ -1477,6 +1419,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
> >  			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
> >  		.dbi_length = 0x200,
> >  		.gpr = "fsl,imx6q-iomuxc-gpr",
> > +		.clk_names = imx6q_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx6q_clks),
> >  	},
> >  	[IMX6SX] = {
> >  		.variant = IMX6SX,
> > @@ -1484,6 +1428,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
> >  			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE |
> >  			 IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
> >  		.gpr = "fsl,imx6q-iomuxc-gpr",
> > +		.clk_names = imx6sx_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx6sx_clks),
> >  	},
> >  	[IMX6QP] = {
> >  		.variant = IMX6QP,
> > @@ -1492,40 +1438,56 @@ static const struct imx6_pcie_drvdata drvdata[] = {
> >  			 IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
> >  		.dbi_length = 0x200,
> >  		.gpr = "fsl,imx6q-iomuxc-gpr",
> > +		.clk_names = imx6q_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx6q_clks),
> >  	},
> >  	[IMX7D] = {
> >  		.variant = IMX7D,
> >  		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
> >  		.gpr = "fsl,imx7d-iomuxc-gpr",
> > +		.clk_names = imx6q_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx6q_clks),
> >  	},
> >  	[IMX8MQ] = {
> >  		.variant = IMX8MQ,
> >  		.gpr = "fsl,imx8mq-iomuxc-gpr",
> > +		.clk_names = imx8mq_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> >  	},
> >  	[IMX8MM] = {
> >  		.variant = IMX8MM,
> >  		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
> >  		.gpr = "fsl,imx8mm-iomuxc-gpr",
> > +		.clk_names = imx8mm_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
> >  	},
> >  	[IMX8MP] = {
> >  		.variant = IMX8MP,
> >  		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
> >  		.gpr = "fsl,imx8mp-iomuxc-gpr",
> > +		.clk_names = imx8mm_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
> >  	},
> >  	[IMX8MQ_EP] = {
> >  		.variant = IMX8MQ_EP,
> >  		.mode = DW_PCIE_EP_TYPE,
> >  		.gpr = "fsl,imx8mq-iomuxc-gpr",
> > +		.clk_names = imx8mq_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> >  	},
> >  	[IMX8MM_EP] = {
> >  		.variant = IMX8MM_EP,
> >  		.mode = DW_PCIE_EP_TYPE,
> >  		.gpr = "fsl,imx8mm-iomuxc-gpr",
> > +		.clk_names = imx8mm_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
> >  	},
> >  	[IMX8MP_EP] = {
> >  		.variant = IMX8MP_EP,
> >  		.mode = DW_PCIE_EP_TYPE,
> >  		.gpr = "fsl,imx8mp-iomuxc-gpr",
> > +		.clk_names = imx8mm_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
> >  	},
> >  };
> >  
> > -- 
> > 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 noname.nuno at gmail.com  Tue Feb 13 08:08:19 2024
From: noname.nuno at gmail.com (Nuno =?ISO-8859-1?Q?S=E1?=)
Date: Tue, 13 Feb 2024 17:08:19 +0100
Subject: [PATCH 5/5] iio: adc: ad7380: use spi_optimize_message()
In-Reply-To: <CAMknhBEU=iMzpE_P0KePL4cZZktBOGHRXaEox5a7XcVjXDT+Dg@mail.gmail.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
	 <20240212-mainline-spi-precook-message-v1-5-a2373cd72d36@baylibre.com>
	 <c06dfa1ecf88b07ef467ad7c08667d0cab400613.camel@gmail.com>
	 <CAMknhBEU=iMzpE_P0KePL4cZZktBOGHRXaEox5a7XcVjXDT+Dg@mail.gmail.com>
Message-ID: <e03968102b92b3711808eb532685bc9e05fc3c8d.camel@gmail.com>

On Tue, 2024-02-13 at 09:27 -0600, David Lechner wrote:
> On Tue, Feb 13, 2024 at 3:47?AM Nuno S? <noname.nuno at gmail.com> wrote:
> > 
> > On Mon, 2024-02-12 at 17:26 -0600, David Lechner wrote:
> > > This modifies the ad7380 ADC driver to use spi_optimize_message() to
> > > optimize the SPI message for the buffered read operation. Since buffered
> > > reads reuse the same SPI message for each read, this can improve
> > > performance by reducing the overhead of setting up some parts the SPI
> > > message in each spi_sync() call.
> > > 
> > > Signed-off-by: David Lechner <dlechner at baylibre.com>
> > > ---
> > > ?drivers/iio/adc/ad7380.c | 52 +++++++++++++++++++++++++++++++++++++++++--
> > > ----
> > > -
> > > ?1 file changed, 45 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
> > > index abd746aef868..5c5d2642a474 100644
> > > --- a/drivers/iio/adc/ad7380.c
> > > +++ b/drivers/iio/adc/ad7380.c
> > > @@ -133,6 +133,7 @@ struct ad7380_state {
> > > ????? struct spi_device *spi;
> > > ????? struct regulator *vref;
> > > ????? struct regmap *regmap;
> > > +???? struct spi_message *msg;
> > > ????? /*
> > > ?????? * DMA (thus cache coherency maintenance) requires the
> > > ?????? * transfer buffers to live in their own cache lines.
> > > @@ -231,19 +232,55 @@ static int ad7380_debugfs_reg_access(struct iio_dev
> > > *indio_dev, u32 reg,
> > > ????? return ret;
> > > ?}
> > > 
> > > +static int ad7380_buffer_preenable(struct iio_dev *indio_dev)
> > > +{
> > > +???? struct ad7380_state *st = iio_priv(indio_dev);
> > > +???? struct spi_transfer *xfer;
> > > +???? int ret;
> > > +
> > > +???? st->msg = spi_message_alloc(1, GFP_KERNEL);
> > > +???? if (!st->msg)
> > > +???????????? return -ENOMEM;
> > > +
> > > +???? xfer = list_first_entry(&st->msg->transfers, struct spi_transfer,
> > > +???????????????????????????? transfer_list);
> > > +
> > > +???? xfer->bits_per_word = st->chip_info->channels[0].scan_type.realbits;
> > > +???? xfer->len = 4;
> > > +???? xfer->rx_buf = st->scan_data.raw;
> > > +
> > > +???? ret = spi_optimize_message(st->spi, st->msg);
> > > +???? if (ret) {
> > > +???????????? spi_message_free(st->msg);
> > > +???????????? return ret;
> > > +???? }
> > > +
> > > +???? return 0;
> > > +}
> > > +
> > > +static int ad7380_buffer_postdisable(struct iio_dev *indio_dev)
> > > +{
> > > +???? struct ad7380_state *st = iio_priv(indio_dev);
> > > +
> > > +???? spi_unoptimize_message(st->msg);
> > > +???? spi_message_free(st->msg);
> > > +
> > > +???? return 0;
> > > +}
> > > +
> > 
> > Not such a big deal but unless I'm missing something we could have the
> > spi_message (+ the transfer) statically allocated in struct ad7380_state and
> > do
> > the optimize only once at probe (naturally with proper devm action for
> > unoptimize). Then we would not need to this for every buffer enable +
> > disable. I
> > know in terms of performance it won't matter but it would be less code I
> > guess.
> > 
> > Am I missing something?
> 
> No, your understanding is correct for the current state of everything
> in this series. So, we could do as you suggest, but I have a feeling
> that future additions to this driver might require that it gets
> changed back this way eventually.

Hmm, not really sure about that as chip_info stuff is always our friend :). And
I'm anyways of the opinion of keeping things simpler and start to evolve when
really needed (because often we never really need to evolve). But bah, as I
said... this is really not a big deal.

- Nuno S?


From quic_jinlmao at quicinc.com  Tue Feb 13 08:05:17 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Tue, 13 Feb 2024 08:05:17 -0800
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename qcom,dsb-element-size
In-Reply-To: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
Message-ID: <20240213160521.15925-2-quic_jinlmao@quicinc.com>

Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
bit.

Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml          | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
index d0647ffaed71..62188c51ceb5 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
@@ -44,7 +44,7 @@ properties:
     minItems: 1
     maxItems: 2
 
-  qcom,dsb-element-size:
+  qcom,dsb-element-bits:
     description:
       Specifies the DSB(Discrete Single Bit) element size supported by
       the monitor. The associated aggregator will read this size before it
@@ -111,7 +111,7 @@ examples:
       compatible = "qcom,coresight-tpdm", "arm,primecell";
       reg = <0x0684c000 0x1000>;
 
-      qcom,dsb-element-size = /bits/ 8 <32>;
+      qcom,dsb-element-bits = <32>;
       qcom,dsb-msrs-num = <16>;
 
       clocks = <&aoss_qmp>;
-- 
2.41.0



From quic_jinlmao at quicinc.com  Tue Feb 13 08:05:16 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Tue, 13 Feb 2024 08:05:16 -0800
Subject: [PATCH v1 0/2] coresight: tpdm: Change qcom,dsb-element-size to qcom,dsb-elem-bits
Message-ID: <20240213160521.15925-1-quic_jinlmao@quicinc.com>

As unit of dsb element size is bit, change qcom,dsb-element-size to
qcom,dsb-elem-bits.

Mao Jinlong (2):
  dt-bindings: arm: qcom,coresight-tpdm: Rename qcom,dsb-element-size
  coresight-tpda: Change qcom,dsb-element-size to qcom,dsb-elem-bits

 .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml          | 4 ++--
 drivers/hwtracing/coresight/coresight-tpda.c                  | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

-- 
2.41.0



From quic_jinlmao at quicinc.com  Tue Feb 13 08:05:18 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Tue, 13 Feb 2024 08:05:18 -0800
Subject: [PATCH v1 2/2] coresight-tpda: Change qcom,dsb-element-size to qcom,dsb-elem-bits
In-Reply-To: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
Message-ID: <20240213160521.15925-3-quic_jinlmao@quicinc.com>

Change qcom,dsb-element-size to qcom,dsb-elem-bits as the unit is bit.

Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpda.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 6863afe7ca94..5d20e10be24b 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -70,7 +70,7 @@ static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
 
 	if (tpdm_has_dsb_dataset(tpdm_data)) {
 		rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
-				"qcom,dsb-element-size", &drvdata->dsb_esize);
+				"qcom,dsb-element-bits", &drvdata->dsb_esize);
 	}
 	if (tpdm_has_cmb_dataset(tpdm_data)) {
 		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
-- 
2.41.0



From mbland at motorola.com  Tue Feb 13 08:05:45 2024
From: mbland at motorola.com (Maxwell Bland)
Date: Tue, 13 Feb 2024 10:05:45 -0600
Subject: [PATCH] arm64: allow post-init vmalloc PXNTable
Message-ID: <CAP5Mv+ydhk=Ob4b40ZahGMgT-5+-VEHxtmA=-LkJiEOOU+K6hw@mail.gmail.com>

Apologies if this is a duplicate mail, it will be the last one. Moto's SMTP
server sucks!!

Ensures that PXNTable can be set on all table descriptors allocated
through vmalloc. Normally, PXNTable is set only during initial memory
mapping and does not apply thereafter, making it possible for attackers
to target post-init allocated writable PTEs as a staging region for
injection of their code into the kernel. Presently it is not possible to
efficiently prevent these attacks as VMALLOC_END overlaps with _text,
e.g.:

VMALLOC_START ffff800080000000 VMALLOC_END fffffbfff0000000
_text         ffffb6c0c1400000 _end        ffffb6c0c3e40000

Setting VMALLOC_END to _text in init would resolve this issue with the
caveat of a sizeable reduction in the size of available vmalloc memory
due to requirements on aslr randomness. However, there are circumstances
where this trade-off is necessary: in particular, hypervisor-level
security monitors where 1) the microarchitecture contains race
conditions on PTE level updates or 2) a per-PTE update verifier comes at
a significant hit to performance.

Because the address of _text is aslr-sensitive and this patch associates
this value with VMALLOC_END, we remove the use of VMALLOC_END in a print
statement in mm/percpu.c. However, only the format string is updated in
crash_core.c, since we are dead at that point regardless. VMALLOC_END is
updated in kernel/setup.c to associate the feature closely with aslr and
region allocation code.

Signed-off-by: Maxwell Bland <mbland at motorola.com>
---
 arch/arm64/Kconfig                   | 13 +++++++++++++
 arch/arm64/include/asm/pgtable.h     |  6 ++++++
 arch/arm64/include/asm/vmalloc-pxn.h | 10 ++++++++++
 arch/arm64/kernel/crash_core.c       |  2 +-
 arch/arm64/kernel/setup.c            |  9 +++++++++
 mm/percpu.c                          |  4 ++--
 6 files changed, 41 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm64/include/asm/vmalloc-pxn.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aa7c1d435139..5f1e75d70e14 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2165,6 +2165,19 @@ config ARM64_DEBUG_PRIORITY_MASKING
    If unsure, say N
 endif # ARM64_PSEUDO_NMI

+config ARM64_VMALLOC_PXN
+ bool "Ensures table descriptors pointing to kernel data are PXNTable"
+ help
+   Reduces the range of the kernel data vmalloc region to remove any
+   overlap with kernel code, making it possible to enable the PXNTable
+   bit on table descriptors allocated after the kernel's initial memory
+   mapping.
+
+   This increases the performance of security monitors which protect
+   against malicious updates to page table entries.
+
+   If unsure, say N.
+
 config RELOCATABLE
  bool "Build a relocatable kernel image" if EXPERT
  select ARCH_HAS_RELR
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 79ce70fbb751..49f64ea77c81 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -22,7 +22,9 @@
  * and fixed mappings
  */
 #define VMALLOC_START (MODULES_END)
+#ifndef CONFIG_ARM64_VMALLOC_PXN
 #define VMALLOC_END (VMEMMAP_START - SZ_256M)
+#endif

 #define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))

@@ -35,6 +37,10 @@
 #include <linux/sched.h>
 #include <linux/page_table_check.h>

+#ifdef CONFIG_ARM64_VMALLOC_PXN
+#include <asm/vmalloc-pxn.h>
+#endif
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE

diff --git a/arch/arm64/include/asm/vmalloc-pxn.h
b/arch/arm64/include/asm/vmalloc-pxn.h
new file mode 100644
index 000000000000..c8c4f878eb62
--- /dev/null
+++ b/arch/arm64/include/asm/vmalloc-pxn.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARM64_VMALLOC_PXN_H
+#define _ASM_ARM64_VMALLOC_PXN_H
+
+#ifdef CONFIG_ARM64_VMALLOC_PXN
+extern u64 __vmalloc_end __ro_after_init;
+#define VMALLOC_END (__vmalloc_end)
+#endif /* CONFIG_ARM64_VMALLOC_PXN */
+
+#endif /* _ASM_ARM64_VMALLOC_PXN_H */
diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/crash_core.c
index 66cde752cd74..39dccae11a40 100644
--- a/arch/arm64/kernel/crash_core.c
+++ b/arch/arm64/kernel/crash_core.c
@@ -24,7 +24,7 @@ void arch_crash_save_vmcoreinfo(void)
  vmcoreinfo_append_str("NUMBER(MODULES_VADDR)=0x%lx\n", MODULES_VADDR);
  vmcoreinfo_append_str("NUMBER(MODULES_END)=0x%lx\n", MODULES_END);
  vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", VMALLOC_START);
- vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%lx\n", VMALLOC_END);
+ vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%llx\n", VMALLOC_END);
  vmcoreinfo_append_str("NUMBER(VMEMMAP_START)=0x%lx\n", VMEMMAP_START);
  vmcoreinfo_append_str("NUMBER(VMEMMAP_END)=0x%lx\n", VMEMMAP_END);
  vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 42c690bb2d60..b7ccee672743 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -54,6 +54,11 @@
 #include <asm/xen/hypervisor.h>
 #include <asm/mmu_context.h>

+#ifdef CONFIG_ARM64_VMALLOC_PXN
+u64 __vmalloc_end __ro_after_init = VMEMMAP_START - SZ_256M;
+EXPORT_SYMBOL(__vmalloc_end);
+#endif /* CONFIG_ARM64_VMALLOC_PXN */
+
 static int num_standard_resources;
 static struct resource *standard_resources;

@@ -298,6 +303,10 @@ void __init __no_sanitize_address setup_arch(char
**cmdline_p)

  kaslr_init();

+#ifdef CONFIG_ARM64_VMALLOC_PXN
+ __vmalloc_end = ALIGN_DOWN((u64) _text, PMD_SIZE);
+#endif
+
  /*
  * If know now we are going to need KPTI then use non-global
  * mappings from the start, avoiding the cost of rewriting
diff --git a/mm/percpu.c b/mm/percpu.c
index 4e11fc1e6def..a902500ebfa0 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -3128,8 +3128,8 @@ int __init pcpu_embed_first_chunk(size_t
reserved_size, size_t dyn_size,

  /* warn if maximum distance is further than 75% of vmalloc space */
  if (max_distance > VMALLOC_TOTAL * 3 / 4) {
- pr_warn("max_distance=0x%lx too large for vmalloc space 0x%lx\n",
- max_distance, VMALLOC_TOTAL);
+ pr_warn("max_distance=0x%lx too large for vmalloc space\n",
+ max_distance);
 #ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
  /* and fail if we have fallback */
  rc = -EINVAL;

base-commit: 716f4aaa7b48a55c73d632d0657b35342b1fefd7
-- 
2.39.0


From jm at ti.com  Tue Feb 13 08:06:27 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 10:06:27 -0600
Subject: [PATCH v2 6/9] arm64: dts: ti: k3-am6*: Remove DLL properties for
 soft PHYs
In-Reply-To: <e805b72a-17a2-4a54-bb90-dab44a551711@ti.com>
References: <20240213002416.1560357-1-jm@ti.com>
 <20240213002416.1560357-7-jm@ti.com>
 <5f9fd69e-d3f6-4293-8746-06173f24e521@phytec.de>
 <e805b72a-17a2-4a54-bb90-dab44a551711@ti.com>
Message-ID: <ede25bc6-7c9c-4d1f-9233-de4ae14d42eb@ti.com>

Hi Wadim,

On 2/13/24 9:52 AM, Judith Mendez wrote:
> Hi Wadim,
> 
> On 2/12/24 11:26 PM, Wadim Egorov wrote:
>> Hi Judith,
>>
>> Am 13.02.24 um 01:24 schrieb Judith Mendez:
>>> Remove DLL properties which are not applicable for soft PHYs
>>> since these PHYs do not have a DLL to enable.
>>>
>>> Signed-off-by: Judith Mendez <jm at ti.com>
>>> ---
>>> ? arch/arm64/boot/dts/ti/k3-am62-main.dtsi????????????? | 3 ---
>>> ? arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi?????? | 1 -
>>> ? arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi???? | 1 -
>>> ? arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi??????? | 1 -
>>> ? arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi?????? | 1 -
>>> ? arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi??????????? | 2 --
>>> ? arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts??????? | 3 ---
>>> ? arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts | 1 -
>>> ? arch/arm64/boot/dts/ti/k3-am62a-main.dtsi???????????? | 1 -
>>> ? arch/arm64/boot/dts/ti/k3-am62a7-sk.dts?????????????? | 1 -
>>> ? arch/arm64/boot/dts/ti/k3-am62p5-sk.dts?????????????? | 1 -
>>> ? arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi??????? | 2 --
>>> ? arch/arm64/boot/dts/ti/k3-am64-main.dtsi????????????? | 1 -
>>> ? arch/arm64/boot/dts/ti/k3-am642-evm.dts?????????????? | 1 -
>>> ? arch/arm64/boot/dts/ti/k3-am642-sk.dts??????????????? | 1 -
>>
>> what about sdhci1 node updates on
>> ?? - k3-am642-phyboard-electra-rdk.dts
>> ?? - k3-am642-tqma64xxl-mbax4xxl.dts
>>
> 
> The same patch applies for this boards.

I will add for v3.

> 
>> Also does this apply only for am64 and sdhci1 (and not sdhci0)?
>> In your v1 you are describing that only AM64x and AM62p devices have a 
>> DLL to update the drive strength.
>> Trying to understand why only one of the interfaces gets updated.
> 
> This patch only applies for AM64x sdhci1 node, since sdhci1
> is a soft PHY and does not have a DLL.
> 
> ~ Judith
> 
>>
>> Regards,
>> Wadim
>>
>>> ? 15 files changed, 21 deletions(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi 
>>> b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>>> index fe0cc4a9a501..79ed5cbbbda1 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>>> @@ -561,7 +561,6 @@ sdhci0: mmc at fa10000 {
>>> ????????? assigned-clock-parents = <&k3_clks 57 8>;
>>> ????????? mmc-ddr-1_8v;
>>> ????????? mmc-hs200-1_8v;
>>> -??????? ti,trm-icp = <0x2>;
>>> ????????? bus-width = <8>;
>>> ????????? ti,clkbuf-sel = <0x7>;
>>> ????????? ti,otap-del-sel-legacy = <0x0>;
>>> @@ -580,7 +579,6 @@ sdhci1: mmc at fa00000 {
>>> ????????? power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>>> ????????? clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
>>> ????????? clock-names = "clk_ahb", "clk_xin";
>>> -??????? ti,trm-icp = <0x2>;
>>> ????????? ti,otap-del-sel-legacy = <0x8>;
>>> ????????? ti,otap-del-sel-sd-hs = <0x0>;
>>> ????????? ti,otap-del-sel-sdr12 = <0x0>;
>>> @@ -604,7 +602,6 @@ sdhci2: mmc at fa20000 {
>>> ????????? power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
>>> ????????? clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
>>> ????????? clock-names = "clk_ahb", "clk_xin";
>>> -??????? ti,trm-icp = <0x2>;
>>> ????????? ti,otap-del-sel-legacy = <0x8>;
>>> ????????? ti,otap-del-sel-sd-hs = <0x0>;
>>> ????????? ti,otap-del-sel-sdr12 = <0x0>;
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi 
>>> b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
>>> index 3372a256c90f..43488cc8bcb1 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
>>> @@ -317,7 +317,6 @@ serial_flash: flash at 0 {
>>> ? &sdhci0 {
>>> ????? pinctrl-names = "default";
>>> ????? pinctrl-0 = <&main_mmc0_pins_default>;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? disable-wp;
>>> ????? non-removable;
>>> ????? status = "okay";
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi 
>>> b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
>>> index bf6d27e70bc4..6c4cec8728e4 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
>>> @@ -185,7 +185,6 @@ &ospi0 {
>>> ? /* Verdin SD_1 */
>>> ? &sdhci1 {
>>> -??? ti,driver-strength-ohm = <33>;
>>> ????? status = "okay";
>>> ? };
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi 
>>> b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
>>> index 680071688dcb..be62648e7818 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
>>> @@ -206,7 +206,6 @@ &ospi0 {
>>> ? /* Verdin SD_1 */
>>> ? &sdhci1 {
>>> -??? ti,driver-strength-ohm = <33>;
>>> ????? status = "okay";
>>> ? };
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi 
>>> b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
>>> index a6808b10c7b2..4768ef42c4fc 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
>>> @@ -26,7 +26,6 @@ &sdhci2 {
>>> ????? mmc-pwrseq = <&wifi_pwrseq>;
>>> ????? non-removable;
>>> ????? ti,fails-without-test-cd;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? vmmc-supply = <&reg_3v3>;
>>> ????? status = "okay";
>>> ? };
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi 
>>> b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
>>> index 6a06724b6d16..d68310444bcb 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
>>> @@ -1407,7 +1407,6 @@ &sdhci0 {
>>> ????? pinctrl-names = "default";
>>> ????? pinctrl-0 = <&pinctrl_sdhci0>;
>>> ????? non-removable;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? status = "okay";
>>> ? };
>>> @@ -1416,7 +1415,6 @@ &sdhci1 {
>>> ????? pinctrl-names = "default";
>>> ????? pinctrl-0 = <&pinctrl_sdhci1>;
>>> ????? disable-wp;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? vmmc-supply = <&reg_sdhc1_vmmc>;
>>> ????? vqmmc-supply = <&reg_sdhc1_vqmmc>;
>>> ????? status = "disabled";
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts 
>>> b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
>>> index 3b4246ce49de..bb6a5837bcb3 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
>>> +++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
>>> @@ -819,7 +819,6 @@ &sdhci0 {
>>> ????? bootph-all;
>>> ????? pinctrl-names = "default";
>>> ????? pinctrl-0 = <&emmc_pins_default>;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? disable-wp;
>>> ????? status = "okay";
>>> ? };
>>> @@ -832,7 +831,6 @@ &sdhci1 {
>>> ????? vmmc-supply = <&vdd_3v3_sd>;
>>> ????? vqmmc-supply = <&vdd_sd_dv>;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? disable-wp;
>>> ????? cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
>>> ????? cd-debounce-delay-ms = <100>;
>>> @@ -849,7 +847,6 @@ &sdhci2 {
>>> ????? ti,fails-without-test-cd;
>>> ????? cap-power-off-card;
>>> ????? keep-power-in-suspend;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? assigned-clocks = <&k3_clks 157 158>;
>>> ????? assigned-clock-parents = <&k3_clks 157 160>;
>>> ????? #address-cells = <1>;
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts 
>>> b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
>>> index 5c31f0453def..a83a90497857 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
>>> +++ b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
>>> @@ -334,7 +334,6 @@ &sdhci1 {
>>> ????? vqmmc-supply = <&vddshv5_sdio>;
>>> ????? pinctrl-names = "default";
>>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? disable-wp;
>>> ????? no-1-8-v;
>>> ????? status = "okay";
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi 
>>> b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
>>> index 6806288ec227..f283777d54b4 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
>>> @@ -561,7 +561,6 @@ sdhci1: mmc at fa00000 {
>>> ????????? power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>>> ????????? clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
>>> ????????? clock-names = "clk_ahb", "clk_xin";
>>> -??????? ti,trm-icp = <0x2>;
>>> ????????? ti,otap-del-sel-legacy = <0x0>;
>>> ????????? ti,otap-del-sel-sd-hs = <0x0>;
>>> ????????? ti,otap-del-sel-sdr12 = <0xf>;
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts 
>>> b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
>>> index c99b2e90f76d..f241637a5642 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
>>> @@ -582,7 +582,6 @@ &sdhci1 {
>>> ????? vmmc-supply = <&vdd_mmc1>;
>>> ????? pinctrl-names = "default";
>>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? disable-wp;
>>> ? };
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts 
>>> b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>>> index 8c73587b0b62..5c9b73726ebd 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
>>> @@ -422,7 +422,6 @@ &sdhci1 {
>>> ????? vqmmc-supply = <&vddshv_sdio>;
>>> ????? pinctrl-names = "default";
>>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? disable-wp;
>>> ????? bootph-all;
>>> ? };
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi 
>>> b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
>>> index 6dd496cd459a..3c45782ab2b7 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
>>> @@ -411,7 +411,6 @@ &sdhci0 {
>>> ????? status = "okay";
>>> ????? pinctrl-names = "default";
>>> ????? pinctrl-0 = <&main_mmc0_pins_default>;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? disable-wp;
>>> ? };
>>> @@ -421,7 +420,6 @@ &sdhci1 {
>>> ????? status = "okay";
>>> ????? pinctrl-names = "default";
>>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? disable-wp;
>>> ? };
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi 
>>> b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
>>> index 9bfa0a969bfc..a29847735c6e 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
>>> +++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
>>> @@ -646,7 +646,6 @@ sdhci1: mmc at fa00000 {
>>> ????????? power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
>>> ????????? clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
>>> ????????? clock-names = "clk_ahb", "clk_xin";
>>> -??????? ti,trm-icp = <0x2>;
>>> ????????? ti,otap-del-sel-legacy = <0x0>;
>>> ????????? ti,otap-del-sel-sd-hs = <0x0>;
>>> ????????? ti,otap-del-sel-sdr12 = <0xf>;
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts 
>>> b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>>> index 5c546ae76d3e..f308076d608a 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>>> +++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
>>> @@ -508,7 +508,6 @@ &sdhci1 {
>>> ????? pinctrl-names = "default";
>>> ????? bus-width = <4>;
>>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? disable-wp;
>>> ? };
>>> diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts 
>>> b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
>>> index cce04e188ff6..b286eaa02ada 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
>>> +++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
>>> @@ -471,7 +471,6 @@ &sdhci1 {
>>> ????? pinctrl-names = "default";
>>> ????? bus-width = <4>;
>>> ????? pinctrl-0 = <&main_mmc1_pins_default>;
>>> -??? ti,driver-strength-ohm = <50>;
>>> ????? disable-wp;
>>> ? };
> 
> 



From ardb+git at google.com  Tue Feb 13 08:06:53 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Tue, 13 Feb 2024 17:06:53 +0100
Subject: [PATCH v2] ARM: iwmmxt: Remove support for PJ4/PJ4B cores
Message-ID: <20240213160652.1577362-2-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
does not support this combination (its iWMMXt configuration always
implies v5te), and so there is no v6/v7 user space that actually makes
use of this, beyond generic support for things like setjmp() that
preserve/restore the iWMMXt register file using generic LDC/STC
instructions emitted in assembler.  As [0] appears to imply, this logic
is triggered for the init process at boot, and so most user threads will
have a iWMMXt register context associated with it, even though it is
never used.

At this point, it is highly unlikely that such GCC support will ever
materialize (and Clang does not implement support for iWMMXt to begin
with).

This means that advertising iWMMXt support on these cores results in
context switch overhead without any associated benefit, and so it is
better to simply ignore the iWMMXt unit on these systems. So rip out the
support. Doing so also fixes the issue reported in [0] related to UNDEF
handling of co-processor #0/#1 instructions issued from user space
running in Thumb2 mode.

The PJ4 cores are used in four platforms: Armada 370/xp, Dove (Cubox,
d2plug), MMP2 (xo-1.75) and Berlin (Google TV). Out of these, only the
first is still widely used, but that one actually doesn't have iWMMXt
but instead has only VFPV3-D16, and so it is not impacted by this
change.

Cc: Russell King <linux at armlinux.org.uk>
Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Arnd Bergmann <arnd at arndb.de>
Acked-by: Nicolas Pitre <nico at fluxnic.net>
Reviewed-by: Jisheng Zhang <jszhang at kernel.org>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/Kconfig          |   4 +-
 arch/arm/kernel/Makefile  |   2 -
 arch/arm/kernel/iwmmxt.S  |  51 ++------
 arch/arm/kernel/pj4-cp0.c | 135 --------------------
 4 files changed, 15 insertions(+), 177 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0af6709570d1..0d4e316a389e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -503,8 +503,8 @@ source "arch/arm/mm/Kconfig"
 
 config IWMMXT
 	bool "Enable iWMMXt support"
-	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B
-	default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B
+	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
+	default y if PXA27x || PXA3xx || ARCH_MMP
 	help
 	  Enable support for iWMMXt context switching at run time if
 	  running on a CPU that supports it.
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 771264d4726a..ae2f2b2b4e5a 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -75,8 +75,6 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
 obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
-obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o
-obj-$(CONFIG_CPU_PJ4B)		+= pj4-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_regs.o perf_callchain.o
 obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event_xscale.o perf_event_v6.o \
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index a0218c4867b9..4a335d3c5969 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -18,18 +18,6 @@
 #include <asm/assembler.h>
 #include "iwmmxt.h"
 
-#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
-#define PJ4(code...)		code
-#define XSC(code...)
-#elif defined(CONFIG_CPU_MOHAWK) || \
-	defined(CONFIG_CPU_XSC3) || \
-	defined(CONFIG_CPU_XSCALE)
-#define PJ4(code...)
-#define XSC(code...)		code
-#else
-#error "Unsupported iWMMXt architecture"
-#endif
-
 #define MMX_WR0		 	(0x00)
 #define MMX_WR1		 	(0x08)
 #define MMX_WR2		 	(0x10)
@@ -81,17 +69,13 @@ ENDPROC(iwmmxt_undef_handler)
 ENTRY(iwmmxt_task_enable)
 	inc_preempt_count r10, r3
 
-	XSC(mrc	p15, 0, r2, c15, c1, 0)
-	PJ4(mrc p15, 0, r2, c1, c0, 2)
+	mrc	p15, 0, r2, c15, c1, 0
 	@ CP0 and CP1 accessible?
-	XSC(tst	r2, #0x3)
-	PJ4(tst	r2, #0xf)
+	tst	r2, #0x3
 	bne	4f				@ if so no business here
 	@ enable access to CP0 and CP1
-	XSC(orr	r2, r2, #0x3)
-	XSC(mcr	p15, 0, r2, c15, c1, 0)
-	PJ4(orr	r2, r2, #0xf)
-	PJ4(mcr	p15, 0, r2, c1, c0, 2)
+	orr	r2, r2, #0x3
+	mcr	p15, 0, r2, c15, c1, 0
 
 	ldr	r3, =concan_owner
 	ldr	r2, [r0, #S_PC]			@ current task pc value
@@ -218,12 +202,9 @@ ENTRY(iwmmxt_task_disable)
 	bne	1f				@ no: quit
 
 	@ enable access to CP0 and CP1
-	XSC(mrc	p15, 0, r4, c15, c1, 0)
-	XSC(orr	r4, r4, #0x3)
-	XSC(mcr	p15, 0, r4, c15, c1, 0)
-	PJ4(mrc p15, 0, r4, c1, c0, 2)
-	PJ4(orr	r4, r4, #0xf)
-	PJ4(mcr	p15, 0, r4, c1, c0, 2)
+	mrc	p15, 0, r4, c15, c1, 0
+	orr	r4, r4, #0x3
+	mcr	p15, 0, r4, c15, c1, 0
 
 	mov	r0, #0				@ nothing to load
 	str	r0, [r3]			@ no more current owner
@@ -232,10 +213,8 @@ ENTRY(iwmmxt_task_disable)
 	bl	concan_save
 
 	@ disable access to CP0 and CP1
-	XSC(bic	r4, r4, #0x3)
-	XSC(mcr	p15, 0, r4, c15, c1, 0)
-	PJ4(bic	r4, r4, #0xf)
-	PJ4(mcr	p15, 0, r4, c1, c0, 2)
+	bic	r4, r4, #0x3
+	mcr	p15, 0, r4, c15, c1, 0
 
 	mrc	p15, 0, r2, c2, c0, 0
 	mov	r2, r2				@ cpwait
@@ -330,11 +309,9 @@ ENDPROC(iwmmxt_task_restore)
  */
 ENTRY(iwmmxt_task_switch)
 
-	XSC(mrc	p15, 0, r1, c15, c1, 0)
-	PJ4(mrc	p15, 0, r1, c1, c0, 2)
+	mrc	p15, 0, r1, c15, c1, 0
 	@ CP0 and CP1 accessible?
-	XSC(tst	r1, #0x3)
-	PJ4(tst	r1, #0xf)
+	tst	r1, #0x3
 	bne	1f				@ yes: block them for next task
 
 	ldr	r2, =concan_owner
@@ -344,10 +321,8 @@ ENTRY(iwmmxt_task_switch)
 	retne	lr				@ no: leave Concan disabled
 
 1:	@ flip Concan access
-	XSC(eor	r1, r1, #0x3)
-	XSC(mcr	p15, 0, r1, c15, c1, 0)
-	PJ4(eor r1, r1, #0xf)
-	PJ4(mcr	p15, 0, r1, c1, c0, 2)
+	eor	r1, r1, #0x3
+	mcr	p15, 0, r1, c15, c1, 0
 
 	mrc	p15, 0, r1, c2, c0, 0
 	sub	pc, lr, r1, lsr #32		@ cpwait and return
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
deleted file mode 100644
index 4bca8098c4ff..000000000000
--- a/arch/arm/kernel/pj4-cp0.c
+++ /dev/null
@@ -1,135 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/kernel/pj4-cp0.c
- *
- * PJ4 iWMMXt coprocessor context switching and handling
- *
- * Copyright (c) 2010 Marvell International Inc.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <asm/thread_notify.h>
-#include <asm/cputype.h>
-
-static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
-{
-	struct thread_info *thread = t;
-
-	switch (cmd) {
-	case THREAD_NOTIFY_FLUSH:
-		/*
-		 * flush_thread() zeroes thread->fpstate, so no need
-		 * to do anything here.
-		 *
-		 * FALLTHROUGH: Ensure we don't try to overwrite our newly
-		 * initialised state information on the first fault.
-		 */
-
-	case THREAD_NOTIFY_EXIT:
-		iwmmxt_task_release(thread);
-		break;
-
-	case THREAD_NOTIFY_SWITCH:
-		iwmmxt_task_switch(thread);
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block __maybe_unused iwmmxt_notifier_block = {
-	.notifier_call	= iwmmxt_do,
-};
-
-
-static u32 __init pj4_cp_access_read(void)
-{
-	u32 value;
-
-	__asm__ __volatile__ (
-		"mrc	p15, 0, %0, c1, c0, 2\n\t"
-		: "=r" (value));
-	return value;
-}
-
-static void __init pj4_cp_access_write(u32 value)
-{
-	u32 temp;
-
-	__asm__ __volatile__ (
-		"mcr	p15, 0, %1, c1, c0, 2\n\t"
-#ifdef CONFIG_THUMB2_KERNEL
-		"isb\n\t"
-#else
-		"mrc	p15, 0, %0, c1, c0, 2\n\t"
-		"mov	%0, %0\n\t"
-		"sub	pc, pc, #4\n\t"
-#endif
-		: "=r" (temp) : "r" (value));
-}
-
-static int __init pj4_get_iwmmxt_version(void)
-{
-	u32 cp_access, wcid;
-
-	cp_access = pj4_cp_access_read();
-	pj4_cp_access_write(cp_access | 0xf);
-
-	/* check if coprocessor 0 and 1 are available */
-	if ((pj4_cp_access_read() & 0xf) != 0xf) {
-		pj4_cp_access_write(cp_access);
-		return -ENODEV;
-	}
-
-	/* read iWMMXt coprocessor id register p1, c0 */
-	__asm__ __volatile__ ("mrc    p1, 0, %0, c0, c0, 0\n" : "=r" (wcid));
-
-	pj4_cp_access_write(cp_access);
-
-	/* iWMMXt v1 */
-	if ((wcid & 0xffffff00) == 0x56051000)
-		return 1;
-	/* iWMMXt v2 */
-	if ((wcid & 0xffffff00) == 0x56052000)
-		return 2;
-
-	return -EINVAL;
-}
-
-/*
- * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
- * switch code handle iWMMXt context switching.
- */
-static int __init pj4_cp0_init(void)
-{
-	u32 __maybe_unused cp_access;
-	int vers;
-
-	if (!cpu_is_pj4())
-		return 0;
-
-	vers = pj4_get_iwmmxt_version();
-	if (vers < 0)
-		return 0;
-
-#ifndef CONFIG_IWMMXT
-	pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n");
-#else
-	cp_access = pj4_cp_access_read() & ~0xf;
-	pj4_cp_access_write(cp_access);
-
-	pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers);
-	elf_hwcap |= HWCAP_IWMMXT;
-	thread_register_notifier(&iwmmxt_notifier_block);
-	register_iwmmxt_undef_handler();
-#endif
-
-	return 0;
-}
-
-late_initcall(pj4_cp0_init);
-- 
2.43.0.687.g38aa6559b0-goog



From jgg at nvidia.com  Tue Feb 13 08:16:01 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 12:16:01 -0400
Subject: [PATCH v5 03/17] iommu/arm-smmu-v3: Move
 arm_smmu_rmr_install_bypass_ste()
In-Reply-To: <ZcuMx0w6MDWpkLne@google.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <3-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZcuMx0w6MDWpkLne@google.com>
Message-ID: <20240213161601.GB1088888@nvidia.com>

On Tue, Feb 13, 2024 at 03:37:43PM +0000, Mostafa Saleh wrote:
> Hi Jason,
> 
> On Tue, Feb 06, 2024 at 11:12:40AM -0400, Jason Gunthorpe wrote:
> > Logically arm_smmu_init_strtab() is the function that allocates and
> > populates the stream table with the initial value of the STEs. After this
> > function returns the stream table should be fully ready.
> > 
> > arm_smmu_rmr_install_bypass_ste() adjusts the initial stream table to force
> > any SIDs that the FW says have IOMMU_RESV_DIRECT to use bypass. This
> > ensures there is no disruption to the identity mapping during boot.
> > 
> > Put arm_smmu_rmr_install_bypass_ste() into arm_smmu_init_strtab(), it
> > already executes immediately after arm_smmu_init_strtab().
> > 
> > No functional change intended.
> 
> I think arm_smmu_init_strtab is quite low level to abstract FW configuration in it.
> For example in KVM[1] we'd re-use a big part of this driver and rely on similar
> low-level functions. But no strong opinion.

I'm happy to drop this patch, if no strong opinion I will leave it

> [1] https://lore.kernel.org/kvmarm/20230201125328.2186498-1-jean-philippe at linaro.org/

I saw this but I didn't try to figure out too much what it is
doing.. It looks like a new iommu driver that re-uses alot of the
datastructures of SMMU but has a different HW facing API based on
hypercalls?

It seems interesting, but my knee jerk reaction would be that a new
iommu driver proposal needs to implement the new iommu core APIs, not
the old stuff. IMHO, when this progresses past a RFC it needs to come
as a proper submission of just the iommu driver, in the normal way.

I also wonder about the wisdom of sharing so much code. Code sharing
is not unconditionally good if it doesn't have a robust abstraction..

Jason


From robh at kernel.org  Tue Feb 13 08:19:05 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 10:19:05 -0600
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop
 redundant GPIO node
In-Reply-To: <d603a588-d312-486e-b6c9-647a6b90580c@linaro.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
 <20240212115837.efz73yxinkysdmgh@runtux.com>
 <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
 <Zcogl6tqbMdQldKA@smile.fi.intel.com>
 <d603a588-d312-486e-b6c9-647a6b90580c@linaro.org>
Message-ID: <20240213161905.GA1459669-robh@kernel.org>

On Mon, Feb 12, 2024 at 02:59:02PM +0100, Krzysztof Kozlowski wrote:
> On 12/02/2024 14:43, Andy Shevchenko wrote:
> > On Mon, Feb 12, 2024 at 02:38:27PM +0100, Krzysztof Kozlowski wrote:
> >> On 12/02/2024 12:58, Ralf Schlatterbeck wrote:
> > 
> > ...
> > 
> >> Anyway, binding examples should not be collection of unrelated
> >> solutions, because then we should accept for each device schema several
> >> other variations and combinations.
> > 
> > Is this documented?
> 
> Yes, writing schema says what the example is. We repeated it multiple
> times on multiple reviews, we made multiple commits multiple times and I
> briefly mentioned it also in my talks.

While yes, this is the guidance, I think this case has provided enough 
justification to keep it. Let's move on please.

Rob


From jgg at nvidia.com  Tue Feb 13 08:18:58 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 12:18:58 -0400
Subject: [PATCH v5 06/17] iommu/arm-smmu-v3: Hold arm_smmu_asid_lock
 during all of attach_dev
In-Reply-To: <ZcuNESWmrC9jZ9lM@google.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <6-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZcuNESWmrC9jZ9lM@google.com>
Message-ID: <20240213161858.GC1088888@nvidia.com>

On Tue, Feb 13, 2024 at 03:38:57PM +0000, Mostafa Saleh wrote:

> This seems a bit theoretical to me also it requires mis-programming as the master
> will issue DMA in detach

iommufd allows VFIO userspace to do this workload as an attack on the
kernel.

Thanks,
Jason


From lpieralisi at kernel.org  Tue Feb 13 08:20:10 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Tue, 13 Feb 2024 17:20:10 +0100
Subject: [PATCH v10 01/14] PCI: imx6: Simplify clock handling by using
 clk_bulk*() function
In-Reply-To: <ZcuRiQ0brp2SfmNU@lizhi-Precision-Tower-5810>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <20240205173335.1120469-2-Frank.Li@nxp.com>
 <ZcuLSkvPuyMXsQeD@lpieralisi>
 <ZcuRiQ0brp2SfmNU@lizhi-Precision-Tower-5810>
Message-ID: <ZcuWuntrvlkvOVrZ@lpieralisi>

On Tue, Feb 13, 2024 at 10:58:01AM -0500, Frank Li wrote:
> On Tue, Feb 13, 2024 at 04:31:22PM +0100, Lorenzo Pieralisi wrote:
> > On Mon, Feb 05, 2024 at 12:33:22PM -0500, Frank Li wrote:
> > > Refector the clock handling logic. Add 'clk_names' define in drvdata. Use
> > > clk_bulk*() api simplify the code.
> > > 
> > > Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > > ---
> > > 
> > > Notes:
> > >     Change from v9 to v10
> > >     - fixed missed delete a case, which need failthrough to next one.
> > >     Change from v8 to v9
> > >     - change clks names
> > >     - Add Manivannan's review tag
> > >     
> > >     Change from v7 to v8
> > >     - update comment message
> > >     - using ARRAY_SIZE to count clk_names.
> > >     Change from v6 to v7
> > >     - none
> > >     Change from v4 to v5
> > >     - update commit message
> > >     - direct using clk name list, instead of macro
> > >     - still keep caculate clk list count because sizeof return pre allocated
> > >     array size.
> > >     
> > >     Change from v3 to v4
> > >     - using clk_bulk_*() API
> > >     Change from v1 to v3
> > >     - none
> > >     
> > >     Change from v4 to v5
> > >     - update commit message
> > >     - direct using clk name list, instead of macro
> > >     - still keep caculate clk list count because sizeof return pre allocated
> > >     array size.
> > >     
> > >     Change from v3 to v4
> > >     - using clk_bulk_*() API
> > >     Change from v1 to v3
> > >     - none
> > >     
> > >     Change from v8 to v9
> > >     - change clks names
> > >     - Add Manivannan's review tag
> > >     
> > >     Change from v7 to v8
> > >     - update comment message
> > >     - using ARRAY_SIZE to count clk_names.
> > >     Change from v6 to v7
> > >     - none
> > >     Change from v4 to v5
> > >     - update commit message
> > >     - direct using clk name list, instead of macro
> > >     - still keep caculate clk list count because sizeof return pre allocated
> > >     array size.
> > >     
> > >     Change from v3 to v4
> > >     - using clk_bulk_*() API
> > >     Change from v1 to v3
> > >     - none
> > >     
> > >     Change from v4 to v5
> > >     - update commit message
> > >     - direct using clk name list, instead of macro
> > >     - still keep caculate clk list count because sizeof return pre allocated
> > >     array size.
> > >     
> > >     Change from v3 to v4
> > >     - using clk_bulk_*() API
> > >     Change from v1 to v3
> > >     - none
> > > 
> > >  drivers/pci/controller/dwc/pci-imx6.c | 138 ++++++++++----------------
> > >  1 file changed, 50 insertions(+), 88 deletions(-)
> > > 
> > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> > > index 74703362aeec7..82854e94c5621 100644
> > > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > > @@ -61,12 +61,16 @@ enum imx6_pcie_variants {
> > >  #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
> > >  #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
> > >  
> > > +#define IMX6_PCIE_MAX_CLKS       6
> > > +
> > >  struct imx6_pcie_drvdata {
> > >  	enum imx6_pcie_variants variant;
> > >  	enum dw_pcie_device_mode mode;
> > >  	u32 flags;
> > >  	int dbi_length;
> > >  	const char *gpr;
> > > +	const char * const *clk_names;
> > > +	const u32 clks_cnt;
> > >  };
> > >  
> > >  struct imx6_pcie {
> > > @@ -74,11 +78,7 @@ struct imx6_pcie {
> > >  	int			reset_gpio;
> > >  	bool			gpio_active_high;
> > >  	bool			link_is_up;
> > > -	struct clk		*pcie_bus;
> > > -	struct clk		*pcie_phy;
> > > -	struct clk		*pcie_inbound_axi;
> > > -	struct clk		*pcie;
> > > -	struct clk		*pcie_aux;
> > > +	struct clk_bulk_data	clks[IMX6_PCIE_MAX_CLKS];
> > 
> > Why can't you allocate this dynamically ?
> 
> Engineer choose. clk_bulk_data is small data struct, two pointers (16byte
> in 64bit system). clks in imx is 3-4, Over half already used(compared 6).
> waste case only wast 48byte.
>  
> Dynamically allocate can't save much memory, there are some extra manage
> meta data for dynamical memory, which may bigger than 48byte.
> 
> Frank
> 
> > 
> > >  	struct regmap		*iomuxc_gpr;
> > >  	u16			msi_ctrl;
> > >  	u32			controller_id;
> > > @@ -407,13 +407,18 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
> > >  
> > >  static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
> > >  {
> > > -	unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy);
> > > +	unsigned long phy_rate = 0;
> > >  	int mult, div;
> > >  	u16 val;
> > > +	int i;
> > >  
> > >  	if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY))
> > >  		return 0;
> > >  
> > > +	for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
> > > +		if (strncmp(imx6_pcie->clks[i].id, "pcie_phy", 8) == 0)
> > > +			phy_rate = clk_get_rate(imx6_pcie->clks[i].clk);
> > > +
> > >  	switch (phy_rate) {
> > >  	case 125000000:
> > >  		/*
> > > @@ -550,19 +555,11 @@ static int imx6_pcie_attach_pd(struct device *dev)
> > >  
> > >  static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
> > >  {
> > > -	struct dw_pcie *pci = imx6_pcie->pci;
> > > -	struct device *dev = pci->dev;
> > >  	unsigned int offset;
> > >  	int ret = 0;
> > >  
> > >  	switch (imx6_pcie->drvdata->variant) {
> > >  	case IMX6SX:
> > > -		ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
> > > -		if (ret) {
> > > -			dev_err(dev, "unable to enable pcie_axi clock\n");
> > > -			break;
> > > -		}
> > > -
> > >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
> > >  				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
> > >  		break;
> > > @@ -589,12 +586,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
> > >  	case IMX8MQ_EP:
> > >  	case IMX8MP:
> > >  	case IMX8MP_EP:
> > > -		ret = clk_prepare_enable(imx6_pcie->pcie_aux);
> > > -		if (ret) {
> > > -			dev_err(dev, "unable to enable pcie_aux clock\n");
> > > -			break;
> > > -		}
> > > -
> > >  		offset = imx6_pcie_grp_offset(imx6_pcie);
> > >  		/*
> > >  		 * Set the over ride low and enabled
> > > @@ -615,9 +606,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
> > >  static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
> > >  {
> > >  	switch (imx6_pcie->drvdata->variant) {
> > > -	case IMX6SX:
> > > -		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
> > > -		break;
> > >  	case IMX6QP:
> > >  	case IMX6Q:
> > >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> > > @@ -631,14 +619,6 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
> > >  				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
> > >  				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
> > >  		break;
> > > -	case IMX8MM:
> > > -	case IMX8MM_EP:
> > > -	case IMX8MQ:
> > > -	case IMX8MQ_EP:
> > > -	case IMX8MP:
> > > -	case IMX8MP_EP:
> > > -		clk_disable_unprepare(imx6_pcie->pcie_aux);
> > > -		break;
> > >  	default:
> > >  		break;
> > >  	}
> > > @@ -650,23 +630,9 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
> > >  	struct device *dev = pci->dev;
> > >  	int ret;
> > >  
> > > -	ret = clk_prepare_enable(imx6_pcie->pcie_phy);
> > > -	if (ret) {
> > > -		dev_err(dev, "unable to enable pcie_phy clock\n");
> > > +	ret = clk_bulk_prepare_enable(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
> > > +	if (ret)
> > >  		return ret;
> > > -	}
> > > -
> > > -	ret = clk_prepare_enable(imx6_pcie->pcie_bus);
> > > -	if (ret) {
> > > -		dev_err(dev, "unable to enable pcie_bus clock\n");
> > > -		goto err_pcie_bus;
> > > -	}
> > > -
> > > -	ret = clk_prepare_enable(imx6_pcie->pcie);
> > > -	if (ret) {
> > > -		dev_err(dev, "unable to enable pcie clock\n");
> > > -		goto err_pcie;
> > > -	}
> > >  
> > >  	ret = imx6_pcie_enable_ref_clk(imx6_pcie);
> > >  	if (ret) {
> > > @@ -679,11 +645,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
> > >  	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);
> > > +	clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
> > >  
> > >  	return ret;
> > >  }
> > > @@ -691,9 +653,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
> > >  static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
> > >  {
> > >  	imx6_pcie_disable_ref_clk(imx6_pcie);
> > > -	clk_disable_unprepare(imx6_pcie->pcie);
> > > -	clk_disable_unprepare(imx6_pcie->pcie_bus);
> > > -	clk_disable_unprepare(imx6_pcie->pcie_phy);
> > > +	clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
> > >  }
> > >  
> > >  static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
> > > @@ -1252,6 +1212,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> > >  	struct device_node *node = dev->of_node;
> > >  	int ret;
> > >  	u16 val;
> > > +	int i;
> > >  
> > >  	imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
> > >  	if (!imx6_pcie)
> > > @@ -1305,32 +1266,20 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> > >  		return imx6_pcie->reset_gpio;
> > >  	}
> > >  
> > > -	/* Fetch clocks */
> > > -	imx6_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus");
> > > -	if (IS_ERR(imx6_pcie->pcie_bus))
> > > -		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_bus),
> > > -				     "pcie_bus clock source missing or invalid\n");
> > > +	if (imx6_pcie->drvdata->clks_cnt >= IMX6_PCIE_MAX_CLKS)
> > > +		return dev_err_probe(dev, -ENOMEM, "clks_cnt is too big\n");
> > 
> > Same question as above, this should not fail if the clks array is
> > dynamically allocated according to imx6_pcie->drvdata->clks_cnt.
> 
> Devm_kzalloc also may return NULL. Still need check. This safe check only
> meanful when add new platform. imx6_pcie->drvdata->clks_cnt is static data.
> 
> It should never failure at running time. But, devm_kzalloc may failure
> at run time.
> 
> It is not big deal. It's most likely personal tast. For small static data,
> I perfer use static memory.

It is fine to keep the static data (but meanful, tast and perfer aren't
English words, a spell checker would fix them, if I may suggest).

Thanks,
Lorenzo


From daniel.machon at microchip.com  Tue Feb 13 08:22:58 2024
From: daniel.machon at microchip.com (Daniel Machon)
Date: Tue, 13 Feb 2024 16:22:58 +0000
Subject: [PATCH net-next] net: sparx5: Add spinlock for frame
 transmission from CPU
In-Reply-To: <20240213121705.4070598-1-horatiu.vultur@microchip.com>
References: <20240213121705.4070598-1-horatiu.vultur@microchip.com>
Message-ID: <20240213162258.ajicpzeevveajrz6@DEN-DL-M70577>

> Both registers used when doing manual injection or fdma injection are
> shared between all the net devices of the switch. It was noticed that
> when having two process which each of them trying to inject frames on
> different ethernet ports, that the HW started to behave strange, by
> sending out more frames then expected. When doing fdma injection it is
> required to set the frame in the DCB and then make sure that the next
> pointer of the last DCB is invalid. But because there is no locks for
> this, then easily this pointer between the DCB can be broken and then it
> would create a loop of DCBs. And that means that the HW will
> continuously transmit these frames in a loop. Until the SW will break
> this loop.
> Therefore to fix this issue, add a spin lock for when accessing the
> registers for manual or fdma injection.

Reviewed-by: Daniel Machon <daniel.machon at microchip.com>



From jgg at nvidia.com  Tue Feb 13 08:26:17 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 12:26:17 -0400
Subject: [PATCH v5 08/17] iommu/arm-smmu-v3: Do not change the STE twice
 during arm_smmu_attach_dev()
In-Reply-To: <ZcuNcka3q3nUOpFM@google.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <8-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZcuNcka3q3nUOpFM@google.com>
Message-ID: <20240213162617.GD1088888@nvidia.com>

On Tue, Feb 13, 2024 at 03:40:34PM +0000, Mostafa Saleh wrote:
> > @@ -2928,9 +2922,18 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
> >  static void arm_smmu_release_device(struct device *dev)
> >  {
> >  	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> > +	struct arm_smmu_ste target;
> >  
> >  	if (WARN_ON(arm_smmu_master_sva_enabled(master)))
> >  		iopf_queue_remove_device(master->smmu->evtq.iopf, dev);
> > +
> > +	/* Put the STE back to what arm_smmu_init_strtab() sets */
> > +	if (disable_bypass && !dev->iommu->require_direct)
> > +		arm_smmu_make_abort_ste(&target);
> > +	else
> > +		arm_smmu_make_bypass_ste(&target);
> > +	arm_smmu_install_ste_for_dev(master, &target);
> > +
> >  	arm_smmu_detach_dev(master);
> >  	arm_smmu_disable_pasid(master);
> >  	arm_smmu_remove_master(master);

> I am still reviewing patch-1 and the hitless machinery (also I think -or hope-
> this can be simplified), with the assumption that
> arm_smmu_install_ste_for_dev()/arm_smmu_write_ste() will do the right thing,
> that good looks good to me.

I'm interested if you can come up with something. Let me know if you
want to bounce some ideas.

> However, as it changes the current behavior of the driver where
> disable_bypass used to override require_direct, I am not sure if
> this would break any existing setups.

Yes, the commit message explains this. It is a little bug.

require_direct takes precedence when building the initial STE, release
should restore the STE back to how it was before probe.

I don't imagine a case where a system was fine with the STE during
boot but doesn't like that same STE during devuce hot unplug???

Jason


From oliver.upton at linux.dev  Tue Feb 13 08:29:42 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 13 Feb 2024 16:29:42 +0000
Subject: [RFC PATCH] KVM: arm64: Fix double-free following
 kvm_pgtable_stage2_free_unlinked()
In-Reply-To: <86cyt062jh.wl-maz@kernel.org>
References: <20240212193052.27765-1-will@kernel.org>
 <Zcp8LcvsZiZVkNKe@linux.dev>
 <86cyt062jh.wl-maz@kernel.org>
Message-ID: <ZcuY9rdvGaJ66edx@linux.dev>

On Tue, Feb 13, 2024 at 11:12:34AM +0000, Marc Zyngier wrote:
> On Mon, 12 Feb 2024 20:14:37 +0000,
> Oliver Upton <oliver.upton at linux.dev> wrote:
> > 
> > On Mon, Feb 12, 2024 at 07:30:52PM +0000, Will Deacon wrote:
> > > kvm_pgtable_stage2_free_unlinked() does the final put_page() on the
> > > root page of the sub-tree before returning, so remove the additional
> > > put_page() invocations in the callers.
> > > 
> > > Cc: Marc Zyngier <maz at kernel.org>
> > > Cc: Oliver Upton <oliver.upton at linux.dev>
> > > Cc: Ricardo Koller <ricarkol at google.com>
> > > Signed-off-by: Will Deacon <will at kernel.org>
> > > ---
> > > 
> > > Hi folks,
> > > 
> > > Sending this as an RFC as I only spotted it from code inspection and I'm
> > > surprised others aren't seeing fireworks if it's a genuine bug. I also
> > > couldn't come up with a sensible Fixes tag, as all of:
> > > 
> > >  e7c05540c694b ("KVM: arm64: Add helper for creating unlinked stage2 subtrees")
> > >  8f5a3eb7513fc ("KVM: arm64: Add kvm_pgtable_stage2_split()")
> > >  f6a27d6dc51b2 ("KVM: arm64: Drop last page ref in kvm_pgtable_stage2_free_removed()")
> 
> I'd blame it on the last commit, as we really ought to have it if we
> have the others.
> 
> > >
> > > are actually ok in isolation. Hrm. Please tell me I'm wrong?
> > > 
> > >  arch/arm64/kvm/hyp/pgtable.c | 2 --
> > >  1 file changed, 2 deletions(-)
> > > 
> > > diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> > > index c651df904fe3..ab9d05fcf98b 100644
> > > --- a/arch/arm64/kvm/hyp/pgtable.c
> > > +++ b/arch/arm64/kvm/hyp/pgtable.c
> > > @@ -1419,7 +1419,6 @@ kvm_pte_t *kvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt,
> > >  				 level + 1);
> > >  	if (ret) {
> > >  		kvm_pgtable_stage2_free_unlinked(mm_ops, pgtable, level);
> > > -		mm_ops->put_page(pgtable);
> > >  		return ERR_PTR(ret);
> > >  	}
> > 
> > AFAICT, this entire branch is effectively dead code, unless there's a
> > KVM bug lurking behind the page table walk. The sub-tree isn't visible
> > to other software or hardware walkers yet, so none of the PTE races
> > could cause this to pop.
> > 
> > So while this is very obviously a bug, it might be pure luck that folks
> > haven't seen smoke here. Perhaps while fixing the bug we should take the
> > opportunity to promote the condition to WARN_ON_ONCE().
> 
> Can't you construct a case where an allocation fails during the walk
> (memcache empty), and we end up on this exact path?

Possibly, but AFAICT that can only happen if there was a bug in KVM. We
don't start the walk at all if userspace set the split chunk size to 0,
and otherwise we expect it to be at least PMD_SIZE, which will top up
the cache to 1 every pass. stage2_split_walker() will 'do the right
thing' if there aren't enough preallocated pages to get down to level 3.

It really doesn't matter either way, I'm just trying to convince myself
of the reasons why we haven't seen this explode yet :)

> > 
> > > @@ -1502,7 +1501,6 @@ static int stage2_split_walker(const struct kvm_pgtable_visit_ctx *ctx,
> > >  
> > >  	if (!stage2_try_break_pte(ctx, mmu)) {
> > >  		kvm_pgtable_stage2_free_unlinked(mm_ops, childp, level);
> > > -		mm_ops->put_page(childp);
> > >  		return -EAGAIN;
> > >  	}
> > 
> > This, on the other hand, seems possible. There exists a race where an
> > old block PTE could have the AF set on it and the underlying cmpxchg()
> > could fail. There shouldn't be a race with any software walkers, as we
> > hold the MMU lock for write here.
> 
> AF update is indeed a likely candidate.
> 
> In any case, this patch looks good to me as it is, and we can always
> have a separate tweak to adjust the severity of the first case as
> required. Unless anyone objects, I'd like to queue it shortly.

Agreed, happy with the way this looks and should've added:

Reviewed-by: Oliver Upton <oliver.upton at linux.dev>

the first time around.

-- 
Thanks,
Oliver


From robh at kernel.org  Tue Feb 13 08:30:55 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 10:30:55 -0600
Subject: [PATCH] dt-bindings: ufs: samsung,exynos-ufs: Add size
 constraints on "samsung,sysreg"
In-Reply-To: <20240124190733.1554314-1-robh@kernel.org>
References: <20240124190733.1554314-1-robh@kernel.org>
Message-ID: <170784184808.1480991.12030700618297062106.robh@kernel.org>


On Wed, 24 Jan 2024 13:07:33 -0600, Rob Herring wrote:
> The 'phandle-array' type is a bit ambiguous. It can be either just an
> array of phandles or an array of phandles plus args. "samsung,sysreg" is
> the latter and needs to be constrained to a single entry with a phandle and
> offset.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../devicetree/bindings/ufs/samsung,exynos-ufs.yaml      | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 

Applied, thanks!



From mark.rutland at arm.com  Tue Feb 13 08:31:36 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 13 Feb 2024 16:31:36 +0000
Subject: [PATCH v5 20/25] arm64/mm: Implement new wrprotect_ptes() batch
 API
In-Reply-To: <20240202080756.1453939-21-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-21-ryan.roberts@arm.com>
Message-ID: <ZcuZaO8pars3aFtu@FVFF77S0Q05N.cambridge.arm.com>

On Fri, Feb 02, 2024 at 08:07:51AM +0000, Ryan Roberts wrote:
> Optimize the contpte implementation to fix some of the fork performance
> regression introduced by the initial contpte commit. Subsequent patches
> will solve it entirely.
> 
> During fork(), any private memory in the parent must be write-protected.
> Previously this was done 1 PTE at a time. But the core-mm supports
> batched wrprotect via the new wrprotect_ptes() API. So let's implement
> that API and for fully covered contpte mappings, we no longer need to
> unfold the contpte. This has 2 benefits:
> 
>   - reduced unfolding, reduces the number of tlbis that must be issued.
>   - The memory remains contpte-mapped ("folded") in the parent, so it
>     continues to benefit from the more efficient use of the TLB after
>     the fork.
> 
> The optimization to wrprotect a whole contpte block without unfolding is
> possible thanks to the tightening of the Arm ARM in respect to the
> definition and behaviour when 'Misprogramming the Contiguous bit'. See
> section D21194 at https://developer.arm.com/documentation/102105/latest/

Minor nit, but it'd be better to refer to a specific revision of the document,
e.g.

  https://developer.arm.com/documentation/102105/ja-07/

That way people can see the specific version of the text you were referring to
even if that changes later, and it means the link is still useful when D21194
gets merged into the ARM ARM and dropped from the known issues doc.

> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>  arch/arm64/include/asm/pgtable.h | 61 ++++++++++++++++++++++++++------
>  arch/arm64/mm/contpte.c          | 35 ++++++++++++++++++
>  2 files changed, 86 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 34892a95403d..c07f0d563733 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -978,16 +978,12 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
>  }
>  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
>  
> -/*
> - * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
> - * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
> - */
> -static inline void __ptep_set_wrprotect(struct mm_struct *mm,
> -					unsigned long address, pte_t *ptep)
> +static inline void ___ptep_set_wrprotect(struct mm_struct *mm,
> +					unsigned long address, pte_t *ptep,
> +					pte_t pte)
>  {
> -	pte_t old_pte, pte;
> +	pte_t old_pte;
>  
> -	pte = __ptep_get(ptep);
>  	do {
>  		old_pte = pte;
>  		pte = pte_wrprotect(pte);
> @@ -996,6 +992,25 @@ static inline void __ptep_set_wrprotect(struct mm_struct *mm,
>  	} while (pte_val(pte) != pte_val(old_pte));
>  }
>  
> +/*
> + * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
> + * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
> + */
> +static inline void __ptep_set_wrprotect(struct mm_struct *mm,
> +					unsigned long address, pte_t *ptep)
> +{
> +	___ptep_set_wrprotect(mm, address, ptep, __ptep_get(ptep));
> +}
> +
> +static inline void __wrprotect_ptes(struct mm_struct *mm, unsigned long address,
> +				pte_t *ptep, unsigned int nr)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < nr; i++, address += PAGE_SIZE, ptep++)
> +		__ptep_set_wrprotect(mm, address, ptep);
> +}
> +
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  #define __HAVE_ARCH_PMDP_SET_WRPROTECT
>  static inline void pmdp_set_wrprotect(struct mm_struct *mm,
> @@ -1156,6 +1171,8 @@ extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep);
>  extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep);
> +extern void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr);
>  extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep,
>  				pte_t entry, int dirty);
> @@ -1269,12 +1286,35 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
>  	return contpte_ptep_clear_flush_young(vma, addr, ptep);
>  }
>  
> +#define wrprotect_ptes wrprotect_ptes
> +static inline void wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr)
> +{
> +	if (likely(nr == 1)) {
> +		/*
> +		 * Optimization: wrprotect_ptes() can only be called for present
> +		 * ptes so we only need to check contig bit as condition for
> +		 * unfold, and we can remove the contig bit from the pte we read
> +		 * to avoid re-reading. This speeds up fork() which is sensitive
> +		 * for order-0 folios. Equivalent to contpte_try_unfold().
> +		 */
> +		pte_t orig_pte = __ptep_get(ptep);
> +
> +		if (unlikely(pte_cont(orig_pte))) {
> +			__contpte_try_unfold(mm, addr, ptep, orig_pte);
> +			orig_pte = pte_mknoncont(orig_pte);
> +		}
> +		___ptep_set_wrprotect(mm, addr, ptep, orig_pte);
> +	} else {
> +		contpte_wrprotect_ptes(mm, addr, ptep, nr);
> +	}
> +}
> +
>  #define __HAVE_ARCH_PTEP_SET_WRPROTECT
>  static inline void ptep_set_wrprotect(struct mm_struct *mm,
>  				unsigned long addr, pte_t *ptep)
>  {
> -	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> -	__ptep_set_wrprotect(mm, addr, ptep);
> +	wrprotect_ptes(mm, addr, ptep, 1);
>  }
>  
>  #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
> @@ -1306,6 +1346,7 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
>  #define ptep_clear_flush_young			__ptep_clear_flush_young
>  #define __HAVE_ARCH_PTEP_SET_WRPROTECT
>  #define ptep_set_wrprotect			__ptep_set_wrprotect
> +#define wrprotect_ptes				__wrprotect_ptes
>  #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
>  #define ptep_set_access_flags			__ptep_set_access_flags
>  
> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
> index bfb50e6b44c7..c85e64baf03b 100644
> --- a/arch/arm64/mm/contpte.c
> +++ b/arch/arm64/mm/contpte.c
> @@ -23,6 +23,23 @@ static inline pte_t *contpte_align_down(pte_t *ptep)
>  	return (pte_t *)(ALIGN_DOWN((unsigned long)ptep >> 3, CONT_PTES) << 3);
>  }
>  
> +static void contpte_try_unfold_partial(struct mm_struct *mm, unsigned long addr,
> +					pte_t *ptep, unsigned int nr)
> +{
> +	/*
> +	 * Unfold any partially covered contpte block at the beginning and end
> +	 * of the range.
> +	 */
> +
> +	if (ptep != contpte_align_down(ptep) || nr < CONT_PTES)
> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +
> +	if (ptep + nr != contpte_align_down(ptep + nr))
> +		contpte_try_unfold(mm, addr + PAGE_SIZE * (nr - 1),
> +				ptep + nr - 1,
> +				__ptep_get(ptep + nr - 1));

Nit: we should use braces for this 'if' block since it covers multiple lines
(even though the function call is a single statement).

It *might* be worth using temporaries for the last ptep and addr, e.g.

	if (ptep + nr != contpte_align_down(ptep + nr)) {
		unsigned long last_addr = addr + PAGE_SIZE * (nr - 1);
		pte_t *last_ptep = ptep + nr - 1;
		contpte_try_unfold(mm, last_addr, last_ptep,
				   __ptep_get(last_ptep));
	}

... but I'm happy without the temporaries so long as we have braces.

> +}
> +
>  static void contpte_convert(struct mm_struct *mm, unsigned long addr,
>  			    pte_t *ptep, pte_t pte)
>  {
> @@ -236,6 +253,24 @@ int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>  }
>  EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
>  
> +void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
> +					pte_t *ptep, unsigned int nr)
> +{
> +	/*
> +	 * If wrprotecting an entire contig range, we can avoid unfolding. Just
> +	 * set wrprotect and wait for the later mmu_gather flush to invalidate
> +	 * the tlb. Until the flush, the page may or may not be wrprotected.
> +	 * After the flush, it is guarranteed wrprotected. If its a partial

Typo: s/guarranteed/guaranteed/
Typo: s/its/it's/ (or s/its/it is/)

Other than the above this looks good to me.

Mark.

> +	 * range though, we must unfold, because we can't have a case where
> +	 * CONT_PTE is set but wrprotect applies to a subset of the PTEs; this
> +	 * would cause it to continue to be unpredictable after the flush.
> +	 */
> +
> +	contpte_try_unfold_partial(mm, addr, ptep, nr);
> +	__wrprotect_ptes(mm, addr, ptep, nr);
> +}
> +EXPORT_SYMBOL(contpte_wrprotect_ptes);
> +
>  int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>  					unsigned long addr, pte_t *ptep,
>  					pte_t entry, int dirty)
> -- 
> 2.25.1
> 


From brgl at bgdev.pl  Tue Feb 13 08:34:25 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 13 Feb 2024 17:34:25 +0100
Subject: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <CAMRc=MfbcweVTo0-Xqe0aMyWfX14AHqYB+Y-1iK2nY_gOTHaiw@mail.gmail.com>

On Mon, Feb 5, 2024 at 7:28?PM Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>

[snip]

>
> Tested on sm8550 and sa8775p with the Inline Crypto Engine and
> remoteproc.
>

I forgot to mention that I also tested it on db410c where it correctly
reports that:

[    0.107312] qcom_scm firmware:scm: SHM Bridge not supported

and falls back to using non-SHM bridge allocator.

It was also tested on other platforms by other people which is
reflected in Tested-by tags in this series.

Bart


From ryan.roberts at arm.com  Tue Feb 13 08:36:17 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 16:36:17 +0000
Subject: [PATCH v5 20/25] arm64/mm: Implement new wrprotect_ptes() batch
 API
In-Reply-To: <ZcuZaO8pars3aFtu@FVFF77S0Q05N.cambridge.arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-21-ryan.roberts@arm.com>
 <ZcuZaO8pars3aFtu@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <4e748f14-647d-4ce5-a14a-464eefb01581@arm.com>

On 13/02/2024 16:31, Mark Rutland wrote:
> On Fri, Feb 02, 2024 at 08:07:51AM +0000, Ryan Roberts wrote:
>> Optimize the contpte implementation to fix some of the fork performance
>> regression introduced by the initial contpte commit. Subsequent patches
>> will solve it entirely.
>>
>> During fork(), any private memory in the parent must be write-protected.
>> Previously this was done 1 PTE at a time. But the core-mm supports
>> batched wrprotect via the new wrprotect_ptes() API. So let's implement
>> that API and for fully covered contpte mappings, we no longer need to
>> unfold the contpte. This has 2 benefits:
>>
>>   - reduced unfolding, reduces the number of tlbis that must be issued.
>>   - The memory remains contpte-mapped ("folded") in the parent, so it
>>     continues to benefit from the more efficient use of the TLB after
>>     the fork.
>>
>> The optimization to wrprotect a whole contpte block without unfolding is
>> possible thanks to the tightening of the Arm ARM in respect to the
>> definition and behaviour when 'Misprogramming the Contiguous bit'. See
>> section D21194 at https://developer.arm.com/documentation/102105/latest/
> 
> Minor nit, but it'd be better to refer to a specific revision of the document,
> e.g.
> 
>   https://developer.arm.com/documentation/102105/ja-07/
> 
> That way people can see the specific version of the text you were referring to
> even if that changes later, and it means the link is still useful when D21194
> gets merged into the ARM ARM and dropped from the known issues doc.

ACK: will fix

> 
>>
>> Tested-by: John Hubbard <jhubbard at nvidia.com>
>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>> ---
>>  arch/arm64/include/asm/pgtable.h | 61 ++++++++++++++++++++++++++------
>>  arch/arm64/mm/contpte.c          | 35 ++++++++++++++++++
>>  2 files changed, 86 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index 34892a95403d..c07f0d563733 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -978,16 +978,12 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
>>  }
>>  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
>>  
>> -/*
>> - * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
>> - * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
>> - */
>> -static inline void __ptep_set_wrprotect(struct mm_struct *mm,
>> -					unsigned long address, pte_t *ptep)
>> +static inline void ___ptep_set_wrprotect(struct mm_struct *mm,
>> +					unsigned long address, pte_t *ptep,
>> +					pte_t pte)
>>  {
>> -	pte_t old_pte, pte;
>> +	pte_t old_pte;
>>  
>> -	pte = __ptep_get(ptep);
>>  	do {
>>  		old_pte = pte;
>>  		pte = pte_wrprotect(pte);
>> @@ -996,6 +992,25 @@ static inline void __ptep_set_wrprotect(struct mm_struct *mm,
>>  	} while (pte_val(pte) != pte_val(old_pte));
>>  }
>>  
>> +/*
>> + * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
>> + * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
>> + */
>> +static inline void __ptep_set_wrprotect(struct mm_struct *mm,
>> +					unsigned long address, pte_t *ptep)
>> +{
>> +	___ptep_set_wrprotect(mm, address, ptep, __ptep_get(ptep));
>> +}
>> +
>> +static inline void __wrprotect_ptes(struct mm_struct *mm, unsigned long address,
>> +				pte_t *ptep, unsigned int nr)
>> +{
>> +	unsigned int i;
>> +
>> +	for (i = 0; i < nr; i++, address += PAGE_SIZE, ptep++)
>> +		__ptep_set_wrprotect(mm, address, ptep);
>> +}
>> +
>>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>>  #define __HAVE_ARCH_PMDP_SET_WRPROTECT
>>  static inline void pmdp_set_wrprotect(struct mm_struct *mm,
>> @@ -1156,6 +1171,8 @@ extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>>  				unsigned long addr, pte_t *ptep);
>>  extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>>  				unsigned long addr, pte_t *ptep);
>> +extern void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
>> +				pte_t *ptep, unsigned int nr);
>>  extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>>  				unsigned long addr, pte_t *ptep,
>>  				pte_t entry, int dirty);
>> @@ -1269,12 +1286,35 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
>>  	return contpte_ptep_clear_flush_young(vma, addr, ptep);
>>  }
>>  
>> +#define wrprotect_ptes wrprotect_ptes
>> +static inline void wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
>> +				pte_t *ptep, unsigned int nr)
>> +{
>> +	if (likely(nr == 1)) {
>> +		/*
>> +		 * Optimization: wrprotect_ptes() can only be called for present
>> +		 * ptes so we only need to check contig bit as condition for
>> +		 * unfold, and we can remove the contig bit from the pte we read
>> +		 * to avoid re-reading. This speeds up fork() which is sensitive
>> +		 * for order-0 folios. Equivalent to contpte_try_unfold().
>> +		 */
>> +		pte_t orig_pte = __ptep_get(ptep);
>> +
>> +		if (unlikely(pte_cont(orig_pte))) {
>> +			__contpte_try_unfold(mm, addr, ptep, orig_pte);
>> +			orig_pte = pte_mknoncont(orig_pte);
>> +		}
>> +		___ptep_set_wrprotect(mm, addr, ptep, orig_pte);
>> +	} else {
>> +		contpte_wrprotect_ptes(mm, addr, ptep, nr);
>> +	}
>> +}
>> +
>>  #define __HAVE_ARCH_PTEP_SET_WRPROTECT
>>  static inline void ptep_set_wrprotect(struct mm_struct *mm,
>>  				unsigned long addr, pte_t *ptep)
>>  {
>> -	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>> -	__ptep_set_wrprotect(mm, addr, ptep);
>> +	wrprotect_ptes(mm, addr, ptep, 1);
>>  }
>>  
>>  #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
>> @@ -1306,6 +1346,7 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
>>  #define ptep_clear_flush_young			__ptep_clear_flush_young
>>  #define __HAVE_ARCH_PTEP_SET_WRPROTECT
>>  #define ptep_set_wrprotect			__ptep_set_wrprotect
>> +#define wrprotect_ptes				__wrprotect_ptes
>>  #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
>>  #define ptep_set_access_flags			__ptep_set_access_flags
>>  
>> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
>> index bfb50e6b44c7..c85e64baf03b 100644
>> --- a/arch/arm64/mm/contpte.c
>> +++ b/arch/arm64/mm/contpte.c
>> @@ -23,6 +23,23 @@ static inline pte_t *contpte_align_down(pte_t *ptep)
>>  	return (pte_t *)(ALIGN_DOWN((unsigned long)ptep >> 3, CONT_PTES) << 3);
>>  }
>>  
>> +static void contpte_try_unfold_partial(struct mm_struct *mm, unsigned long addr,
>> +					pte_t *ptep, unsigned int nr)
>> +{
>> +	/*
>> +	 * Unfold any partially covered contpte block at the beginning and end
>> +	 * of the range.
>> +	 */
>> +
>> +	if (ptep != contpte_align_down(ptep) || nr < CONT_PTES)
>> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>> +
>> +	if (ptep + nr != contpte_align_down(ptep + nr))
>> +		contpte_try_unfold(mm, addr + PAGE_SIZE * (nr - 1),
>> +				ptep + nr - 1,
>> +				__ptep_get(ptep + nr - 1));
> 
> Nit: we should use braces for this 'if' block since it covers multiple lines
> (even though the function call is a single statement).
> 
> It *might* be worth using temporaries for the last ptep and addr, e.g.
> 
> 	if (ptep + nr != contpte_align_down(ptep + nr)) {
> 		unsigned long last_addr = addr + PAGE_SIZE * (nr - 1);
> 		pte_t *last_ptep = ptep + nr - 1;
> 		contpte_try_unfold(mm, last_addr, last_ptep,
> 				   __ptep_get(last_ptep));
> 	}
> 
> ... but I'm happy without the temporaries so long as we have braces.

ACK will fix and add temporaries.

> 
>> +}
>> +
>>  static void contpte_convert(struct mm_struct *mm, unsigned long addr,
>>  			    pte_t *ptep, pte_t pte)
>>  {
>> @@ -236,6 +253,24 @@ int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>>  }
>>  EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
>>  
>> +void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
>> +					pte_t *ptep, unsigned int nr)
>> +{
>> +	/*
>> +	 * If wrprotecting an entire contig range, we can avoid unfolding. Just
>> +	 * set wrprotect and wait for the later mmu_gather flush to invalidate
>> +	 * the tlb. Until the flush, the page may or may not be wrprotected.
>> +	 * After the flush, it is guarranteed wrprotected. If its a partial
> 
> Typo: s/guarranteed/guaranteed/
> Typo: s/its/it's/ (or s/its/it is/)

ACK: already fixed guaranteed after you pointed out the same typo in earlier
patch. Will fix it's.

> 
> Other than the above this looks good to me.

Great thanks!

> 
> Mark.
> 
>> +	 * range though, we must unfold, because we can't have a case where
>> +	 * CONT_PTE is set but wrprotect applies to a subset of the PTEs; this
>> +	 * would cause it to continue to be unpredictable after the flush.
>> +	 */
>> +
>> +	contpte_try_unfold_partial(mm, addr, ptep, nr);
>> +	__wrprotect_ptes(mm, addr, ptep, nr);
>> +}
>> +EXPORT_SYMBOL(contpte_wrprotect_ptes);
>> +
>>  int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>>  					unsigned long addr, pte_t *ptep,
>>  					pte_t entry, int dirty)
>> -- 
>> 2.25.1
>>



From jgg at nvidia.com  Tue Feb 13 08:37:39 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 12:37:39 -0400
Subject: [PATCH v5 11/17] iommu/arm-smmu-v3: Remove
 arm_smmu_master->domain
In-Reply-To: <ZcuOnnrWN3ZxJY8x@google.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <11-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZcuOnnrWN3ZxJY8x@google.com>
Message-ID: <20240213163739.GE1088888@nvidia.com>

On Tue, Feb 13, 2024 at 03:45:34PM +0000, Mostafa Saleh wrote:
> Hi Jason,
> 
> On Tue, Feb 06, 2024 at 11:12:48AM -0400, Jason Gunthorpe wrote:
> > Introducing global statics which are of type struct iommu_domain, not
> > struct arm_smmu_domain makes it difficult to retain
> > arm_smmu_master->domain, as it can no longer point to an IDENTITY or
> > BLOCKED domain.
> > 
> > The only place that uses the value is arm_smmu_detach_dev(). Change things
> > to work like other drivers and call iommu_get_domain_for_dev() to obtain
> > the current domain.
> > 
> > The master->domain is subtly protecting the domain_head against being
> > unused, change the domain_head to be INIT'd when the master is not
> > attached to a domain instead of garbage/zero.
> 
> I don't this the problem here, neither the reason for initialising the
> domain_head, can you please clarify the issue?

I didn't notice it either. Eric found it:

https://lore.kernel.org/linux-iommu/6fff20dd-46d5-4974-a4a5-fb4e7a59ce44 at redhat.com/

> > @@ -2560,19 +2560,20 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
> >  
> >  static void arm_smmu_detach_dev(struct arm_smmu_master *master)
> >  {
> > +	struct iommu_domain *domain = iommu_get_domain_for_dev(master->dev);
> > +	struct arm_smmu_domain *smmu_domain;
> >  	unsigned long flags;
> > -	struct arm_smmu_domain *smmu_domain = master->domain;

master->domain is NULL here which happens in cases where the current
RID domain is not a PAGING domain.

> > -	if (!smmu_domain)
> > +	if (!domain)
> >  		return;

Which used to early exit

> >  
> > +	smmu_domain = to_smmu_domain(domain);
> >  	arm_smmu_disable_ats(master, smmu_domain);
> >  
> >  	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> > -	list_del(&master->domain_head);
> > +	list_del_init(&master->domain_head);
> >  	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);

But now would cause the list_del() to hit a non-inited list_head and
explode.

Instead we keep the list head init'd and the list_del is a NOP.

Tricky right??

I changed the comment like this:

The master->domain is subtly protecting the master->domain_head against
being unused as only PAGING domains will set master->domain and only
paging domains use the master->domain_head. To make it simple keep the
master->domain_head initialized so that the list_del() logic just does
nothing for non-PAGING domains.

OK?

Jason


From sebastianene at google.com  Tue Feb 13 08:42:27 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Tue, 13 Feb 2024 16:42:27 +0000
Subject: [PATCH v5 3/4] KVM: arm64: Register ptdump with debugfs on guest
 creation
In-Reply-To: <Zcq-NGa-Gd9rVVgF@linux.dev>
References: <20240207144832.1017815-2-sebastianene@google.com>
 <20240207144832.1017815-5-sebastianene@google.com>
 <Zcq-NGa-Gd9rVVgF@linux.dev>
Message-ID: <Zcub87FwaVPkCXQE@google.com>

On Tue, Feb 13, 2024 at 12:56:20AM +0000, Oliver Upton wrote:
> On Wed, Feb 07, 2024 at 02:48:32PM +0000, Sebastian Ene wrote:

Hello Oliver,

> > While arch/*/mem/ptdump handles the kernel pagetable dumping code,
> > introduce KVM/ptdump which shows the guest stage-2 pagetables. The
> > separation is necessary because most of the definitions from the
> > stage-2 pagetable reside in the KVM path and we will be invoking
> > functionality **specific** to KVM.
> > 
> > When a guest is created, register a new file entry under the guest
> > debugfs dir which allows userspace to show the contents of the guest
> > stage-2 pagetables when accessed.
> > 
> > Signed-off-by: Sebastian Ene <sebastianene at google.com>
> > ---
> >  arch/arm64/kvm/Kconfig      | 13 ++++++
> >  arch/arm64/kvm/Makefile     |  1 +
> >  arch/arm64/kvm/debug.c      |  7 ++++
> >  arch/arm64/kvm/kvm_ptdump.h | 20 ++++++++++
> >  arch/arm64/kvm/ptdump.c     | 79 +++++++++++++++++++++++++++++++++++++
> >  5 files changed, 120 insertions(+)
> >  create mode 100644 arch/arm64/kvm/kvm_ptdump.h
> >  create mode 100644 arch/arm64/kvm/ptdump.c
> > 
> > diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> > index 6c3c8ca73e7f..28097dd72174 100644
> > --- a/arch/arm64/kvm/Kconfig
> > +++ b/arch/arm64/kvm/Kconfig
> > @@ -68,4 +68,17 @@ config PROTECTED_NVHE_STACKTRACE
> >  
> >  	  If unsure, or not using protected nVHE (pKVM), say N.
> >  
> > +config PTDUMP_STAGE2_DEBUGFS
> > +       bool "Present the stage-2 pagetables to debugfs"
> > +       depends on PTDUMP_DEBUGFS && KVM
> > +       default n
> > +       help
> > +         Say Y here if you want to show the stage-2 kernel pagetables
> > +         layout in a debugfs file. This information is only useful for kernel developers
> > +         who are working in architecture specific areas of the kernel.
> > +         It is probably not a good idea to enable this feature in a production
> > +         kernel.
> > +
> > +         If in doubt, say N.
> > +
> >  endif # VIRTUALIZATION
> > diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> > index c0c050e53157..190eac17538c 100644
> > --- a/arch/arm64/kvm/Makefile
> > +++ b/arch/arm64/kvm/Makefile
> > @@ -23,6 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
> >  	 vgic/vgic-its.o vgic/vgic-debug.o
> >  
> >  kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
> > +kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
> >  
> >  always-y := hyp_constants.h hyp-constants.s
> >  
> > diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> > index 8725291cb00a..aef52836cd90 100644
> > --- a/arch/arm64/kvm/debug.c
> > +++ b/arch/arm64/kvm/debug.c
> > @@ -14,6 +14,8 @@
> >  #include <asm/kvm_arm.h>
> >  #include <asm/kvm_emulate.h>
> >  
> > +#include <kvm_ptdump.h>
> > +
> >  #include "trace.h"
> >  
> >  /* These are the bits of MDSCR_EL1 we may manipulate */
> > @@ -342,3 +344,8 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
> >  	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
> >  	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
> >  }
> > +
> > +int kvm_arch_create_vm_debugfs(struct kvm *kvm)
> > +{
> > +	return kvm_ptdump_guest_register(kvm);
> > +}
> > diff --git a/arch/arm64/kvm/kvm_ptdump.h b/arch/arm64/kvm/kvm_ptdump.h
> > new file mode 100644
> > index 000000000000..a7c00a28481b
> > --- /dev/null
> > +++ b/arch/arm64/kvm/kvm_ptdump.h
> > @@ -0,0 +1,20 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (C) Google, 2023
> > + * Author: Sebastian Ene <sebastianene at google.com>
> > + */
> > +
> > +#ifndef __KVM_PTDUMP_H
> > +#define __KVM_PTDUMP_H
> > +
> > +#include <linux/kvm_host.h>
> > +#include <asm/ptdump.h>
> > +
> > +
> > +#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
> > +int kvm_ptdump_guest_register(struct kvm *kvm);
> > +#else
> > +static inline int kvm_ptdump_guest_register(struct kvm *kvm) { return 0; }
> > +#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
> > +
> > +#endif /* __KVM_PTDUMP_H */
> > diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> > new file mode 100644
> > index 000000000000..a4e984da8aa7
> > --- /dev/null
> > +++ b/arch/arm64/kvm/ptdump.c
> > @@ -0,0 +1,79 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +//
> > +// Debug helper used to dump the stage-2 pagetables of the system and their
> > +// associated permissions.
> > +//
> > +// Copyright (C) Google, 2023
> > +// Author: Sebastian Ene <sebastianene at google.com>
> 
> Same comment as last time about ... the comment :)
> 
> Should be of the form
> 
> /*
>  *
>  */
> 

I forgot to update this, sorry. Let me fix it.

> > +#include <linux/debugfs.h>
> > +#include <linux/kvm_host.h>
> > +#include <linux/seq_file.h>
> > +
> > +#include <asm/kvm_pkvm.h>
> 
> is this needed?
>

We only need  <asm/kvm_pgtable.h> so I will update this.

> > +#include <kvm_ptdump.h>
> > +
> > +
> > +static int kvm_ptdump_guest_open(struct inode *inode, struct file *file);
> > +static int kvm_ptdump_guest_show(struct seq_file *m, void *);
> 
> can you structure the file in a way to avoid forward declarations?
> 

Sounds good, let me drop those.

> > +static const struct file_operations kvm_ptdump_guest_fops = {
> > +	.open		= kvm_ptdump_guest_open,
> > +	.read		= seq_read,
> > +	.llseek		= seq_lseek,
> > +	.release	= single_release,
> > +};
> > +
> > +static int kvm_ptdump_guest_open(struct inode *inode, struct file *file)
> > +{
> > +	return single_open(file, kvm_ptdump_guest_show, inode->i_private);
> > +}
> > +
> 
> Shouldn't we take a reference on the KVM struct at open to avoid UAF?
> 
> 	struct kvm *kvm = inode->i_private;
> 
> 	if (!kvm_get_kvm_safe(kvm))
> 		return -ENOENT;
> 
> Then you can do a put on it at close().
> 

Thanks, I though that the kvm_destroy_vm_debugfs will keep spinning if
there are opened paths to the debugfs entry, but I guess nothing prevents
that from happening and the kvm struct can be removed behind our back.

> > +static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
> > +			      enum kvm_pgtable_walk_flags visit)
> > +{
> > +	struct pg_state *st = ctx->arg;
> > +	struct ptdump_state *pt_st = &st->ptdump;
> > +
> > +	note_page(pt_st, ctx->addr, ctx->level, ctx->old);
> > +	return 0;
> > +}
> > +
> > +static int kvm_ptdump_show_common(struct seq_file *m,
> > +				  struct kvm_pgtable *pgtable,
> > +				  struct pg_state *parser_state)
> > +{
> > +	struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker) {
> > +		.cb     = kvm_ptdump_visitor,
> > +		.arg	= parser_state,
> > +		.flags	= KVM_PGTABLE_WALK_LEAF,
> > +	};
> > +
> > +	return kvm_pgtable_walk(pgtable, 0, BIT(pgtable->ia_bits), &walker);
> > +}
> > +
> > +static int kvm_ptdump_guest_show(struct seq_file *m, void *)
> > +{
> > +	struct kvm *guest_kvm = m->private;
> > +	struct kvm_s2_mmu *mmu = &guest_kvm->arch.mmu;
> > +	struct pg_state parser_state = {0};
> > +	int ret;
> > +
> > +	write_lock(&guest_kvm->mmu_lock);
> > +	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
> > +	write_unlock(&guest_kvm->mmu_lock);
> > +
> > +	return ret;
> > +}
> > +
> > +int kvm_ptdump_guest_register(struct kvm *kvm)
> > +{
> > +	struct dentry *parent;
> > +
> > +	parent = debugfs_create_file("stage2_page_tables", 0400,
> > +				     kvm->debugfs_dentry, kvm,
> > +				     &kvm_ptdump_guest_fops);
> > +	if (IS_ERR(parent))
> > +		return PTR_ERR(parent);
> 
> This makes the otherwise benign debugfs failure into something fatal for
> VM creation, no?
> 
> From the documentation on debugfs_create_file():
> 
>  * NOTE: it's expected that most callers should _ignore_ the errors returned
>  * by this function. Other debugfs functions handle the fact that the "dentry"
>  * passed to them could be an error and they don't crash in that case.
>  * Drivers should generally work fine even if debugfs fails to init anyway.
> 
> The fact that kvm_arch_create_vm_debugfs() has a return value is a bit
> of an anti-pattern to begin with.
>

Ack, I will ignore the retun code then.

> -- 
> Thanks,
> Oliver

Thanks,
Sebastian


From mark.rutland at arm.com  Tue Feb 13 08:43:11 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 13 Feb 2024 16:43:11 +0000
Subject: [PATCH v5 21/25] arm64/mm: Implement new
 [get_and_]clear_full_ptes() batch APIs
In-Reply-To: <20240202080756.1453939-22-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-22-ryan.roberts@arm.com>
Message-ID: <ZcucHyb1OBG677gx@FVFF77S0Q05N.cambridge.arm.com>

On Fri, Feb 02, 2024 at 08:07:52AM +0000, Ryan Roberts wrote:
> Optimize the contpte implementation to fix some of the
> exit/munmap/dontneed performance regression introduced by the initial
> contpte commit. Subsequent patches will solve it entirely.
> 
> During exit(), munmap() or madvise(MADV_DONTNEED), mappings must be
> cleared. Previously this was done 1 PTE at a time. But the core-mm
> supports batched clear via the new [get_and_]clear_full_ptes() APIs. So
> let's implement those APIs and for fully covered contpte mappings, we no
> longer need to unfold the contpte. This significantly reduces unfolding
> operations, reducing the number of tlbis that must be issued.
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>  arch/arm64/include/asm/pgtable.h | 67 ++++++++++++++++++++++++++++++++
>  arch/arm64/mm/contpte.c          | 17 ++++++++
>  2 files changed, 84 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index c07f0d563733..ad04adb7b87f 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -965,6 +965,37 @@ static inline pte_t __ptep_get_and_clear(struct mm_struct *mm,
>  	return pte;
>  }
>  
> +static inline void __clear_full_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr, int full)
> +{
> +	for (;;) {
> +		__ptep_get_and_clear(mm, addr, ptep);
> +		if (--nr == 0)
> +			break;
> +		ptep++;
> +		addr += PAGE_SIZE;
> +	}
> +}

The loop construct is a bit odd; can't this be:

	while (nr--) {
		__ptep_get_and_clear(mm, addr, ptep);
		ptep++;
		addr += PAGE_SIZE;
	}

... or:

	do {
		__ptep_get_and_clear(mm, addr, ptep);
		ptep++;
		addr += PAGE_SIZE;
	} while (--nr);

... ?

Otherwise, this looks good to me.

Mark.

> +
> +static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep,
> +				unsigned int nr, int full)
> +{
> +	pte_t pte, tmp_pte;
> +
> +	pte = __ptep_get_and_clear(mm, addr, ptep);
> +	while (--nr) {
> +		ptep++;
> +		addr += PAGE_SIZE;
> +		tmp_pte = __ptep_get_and_clear(mm, addr, ptep);
> +		if (pte_dirty(tmp_pte))
> +			pte = pte_mkdirty(pte);
> +		if (pte_young(tmp_pte))
> +			pte = pte_mkyoung(pte);
> +	}
> +	return pte;
> +}
> +
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  #define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
>  static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
> @@ -1167,6 +1198,11 @@ extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
>  extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
>  extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
>  				pte_t *ptep, pte_t pte, unsigned int nr);
> +extern void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr, int full);
> +extern pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep,
> +				unsigned int nr, int full);
>  extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep);
>  extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
> @@ -1254,6 +1290,35 @@ static inline void pte_clear(struct mm_struct *mm,
>  	__pte_clear(mm, addr, ptep);
>  }
>  
> +#define clear_full_ptes clear_full_ptes
> +static inline void clear_full_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr, int full)
> +{
> +	if (likely(nr == 1)) {
> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +		__clear_full_ptes(mm, addr, ptep, nr, full);
> +	} else {
> +		contpte_clear_full_ptes(mm, addr, ptep, nr, full);
> +	}
> +}
> +
> +#define get_and_clear_full_ptes get_and_clear_full_ptes
> +static inline pte_t get_and_clear_full_ptes(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep,
> +				unsigned int nr, int full)
> +{
> +	pte_t pte;
> +
> +	if (likely(nr == 1)) {
> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +		pte = __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
> +	} else {
> +		pte = contpte_get_and_clear_full_ptes(mm, addr, ptep, nr, full);
> +	}
> +
> +	return pte;
> +}
> +
>  #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
>  static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
>  				unsigned long addr, pte_t *ptep)
> @@ -1338,6 +1403,8 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
>  #define set_pte					__set_pte
>  #define set_ptes				__set_ptes
>  #define pte_clear				__pte_clear
> +#define clear_full_ptes				__clear_full_ptes
> +#define get_and_clear_full_ptes			__get_and_clear_full_ptes
>  #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
>  #define ptep_get_and_clear			__ptep_get_and_clear
>  #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
> index c85e64baf03b..80346108450b 100644
> --- a/arch/arm64/mm/contpte.c
> +++ b/arch/arm64/mm/contpte.c
> @@ -207,6 +207,23 @@ void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
>  }
>  EXPORT_SYMBOL(contpte_set_ptes);
>  
> +void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr, int full)
> +{
> +	contpte_try_unfold_partial(mm, addr, ptep, nr);
> +	__clear_full_ptes(mm, addr, ptep, nr, full);
> +}
> +EXPORT_SYMBOL(contpte_clear_full_ptes);
> +
> +pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep,
> +				unsigned int nr, int full)
> +{
> +	contpte_try_unfold_partial(mm, addr, ptep, nr);
> +	return __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
> +}
> +EXPORT_SYMBOL(contpte_get_and_clear_full_ptes);
> +
>  int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>  					unsigned long addr, pte_t *ptep)
>  {
> -- 
> 2.25.1
> 


From andriy.shevchenko at linux.intel.com  Tue Feb 13 08:43:39 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Tue, 13 Feb 2024 18:43:39 +0200
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop
 redundant GPIO node
In-Reply-To: <20240213161905.GA1459669-robh@kernel.org>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
 <20240212115837.efz73yxinkysdmgh@runtux.com>
 <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
 <Zcogl6tqbMdQldKA@smile.fi.intel.com>
 <d603a588-d312-486e-b6c9-647a6b90580c@linaro.org>
 <20240213161905.GA1459669-robh@kernel.org>
Message-ID: <ZcucO8R8ZOtR38jl@smile.fi.intel.com>

On Tue, Feb 13, 2024 at 10:19:05AM -0600, Rob Herring wrote:
> On Mon, Feb 12, 2024 at 02:59:02PM +0100, Krzysztof Kozlowski wrote:
> > On 12/02/2024 14:43, Andy Shevchenko wrote:
> > > On Mon, Feb 12, 2024 at 02:38:27PM +0100, Krzysztof Kozlowski wrote:
> > >> On 12/02/2024 12:58, Ralf Schlatterbeck wrote:

...

> > >> Anyway, binding examples should not be collection of unrelated
> > >> solutions, because then we should accept for each device schema several
> > >> other variations and combinations.
> > > 
> > > Is this documented?
> > 
> > Yes, writing schema says what the example is. We repeated it multiple
> > times on multiple reviews, we made multiple commits multiple times and I
> > briefly mentioned it also in my talks.
> 
> While yes, this is the guidance, I think this case has provided enough
> justification to keep it. Let's move on please.

Thank you, Rob.

Krzysztof, can you send v2, I'll apply it to the tree?

-- 
With Best Regards,
Andy Shevchenko




From smostafa at google.com  Tue Feb 13 08:46:42 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Tue, 13 Feb 2024 16:46:42 +0000
Subject: [PATCH v5 03/17] iommu/arm-smmu-v3: Move
 arm_smmu_rmr_install_bypass_ste()
In-Reply-To: <20240213161601.GB1088888@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <3-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZcuMx0w6MDWpkLne@google.com>
 <20240213161601.GB1088888@nvidia.com>
Message-ID: <Zcuc8g-G4dCxieUl@google.com>

On Tue, Feb 13, 2024 at 12:16:01PM -0400, Jason Gunthorpe wrote:
> On Tue, Feb 13, 2024 at 03:37:43PM +0000, Mostafa Saleh wrote:
> > Hi Jason,
> > 
> > On Tue, Feb 06, 2024 at 11:12:40AM -0400, Jason Gunthorpe wrote:
> > > Logically arm_smmu_init_strtab() is the function that allocates and
> > > populates the stream table with the initial value of the STEs. After this
> > > function returns the stream table should be fully ready.
> > > 
> > > arm_smmu_rmr_install_bypass_ste() adjusts the initial stream table to force
> > > any SIDs that the FW says have IOMMU_RESV_DIRECT to use bypass. This
> > > ensures there is no disruption to the identity mapping during boot.
> > > 
> > > Put arm_smmu_rmr_install_bypass_ste() into arm_smmu_init_strtab(), it
> > > already executes immediately after arm_smmu_init_strtab().
> > > 
> > > No functional change intended.
> > 
> > I think arm_smmu_init_strtab is quite low level to abstract FW configuration in it.
> > For example in KVM[1] we'd re-use a big part of this driver and rely on similar
> > low-level functions. But no strong opinion.
> 
> I'm happy to drop this patch, if no strong opinion I will leave it
> 
> > [1] https://lore.kernel.org/kvmarm/20230201125328.2186498-1-jean-philippe at linaro.org/
> 
> I saw this but I didn't try to figure out too much what it is
> doing.. It looks like a new iommu driver that re-uses alot of the
> datastructures of SMMU but has a different HW facing API based on
> hypercalls?

Yes, this is an implementation for the SMMUv3 driver in EL2 in KVM that is needed
for DMA isolation for Protected KVM(pKVM) as the host is untrusted in this case and
can attack the hypervisor through DMA.

This is similar to the kernel driver but with a bunch of tricks such as page table
allocation, power management and more.

Also we have some plans to extend it to KVM guests, (Initially I was considering
KVM-VFIO device but now with the new iommufd stuff, it might fit in there)

> It seems interesting, but my knee jerk reaction would be that a new
> iommu driver proposal needs to implement the new iommu core APIs, not
> the old stuff. IMHO, when this progresses past a RFC it needs to come
> as a proper submission of just the iommu driver, in the normal way.
> 
> I also wonder about the wisdom of sharing so much code. Code sharing
> is not unconditionally good if it doesn't have a robust abstraction..
>

The idea is that as the hardware is common and most of the dt binding also,
we shouldn?t really reinvent the wheel, so this series moves the common code
for the page-table library to be shared with EL1/EL2 and for HW/FW probe and
init to be shared between the kernel drivers and adds a lot of the infrastructure
for IOMMUs in the hypervisor.

Thanks,
Mostafa


From zajec5 at gmail.com  Tue Feb 13 08:46:32 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 13 Feb 2024 17:46:32 +0100
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible for MT7988
Message-ID: <20240213164633.25447-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

MT7988 has on-SoC controller that can control up to 8 PWMs.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml b/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
index 0fbe8a6469eb..a5c308801619 100644
--- a/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
@@ -24,6 +24,7 @@ properties:
           - mediatek,mt7629-pwm
           - mediatek,mt7981-pwm
           - mediatek,mt7986-pwm
+          - mediatek,mt7988-pwm
           - mediatek,mt8183-pwm
           - mediatek,mt8365-pwm
           - mediatek,mt8516-pwm
-- 
2.35.3



From zajec5 at gmail.com  Tue Feb 13 08:46:33 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 13 Feb 2024 17:46:33 +0100
Subject: [PATCH 2/2] arm64: dts: mediatek: mt7988: add PWM controller
In-Reply-To: <20240213164633.25447-1-zajec5@gmail.com>
References: <20240213164633.25447-1-zajec5@gmail.com>
Message-ID: <20240213164633.25447-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Add binding for on-SoC controller that can control up to 8 PWMs.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
index bba97de4fb44..67007626b5cd 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only OR MIT
 
+#include <dt-bindings/clock/mediatek,mt7988-clk.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
@@ -78,7 +79,7 @@ gic: interrupt-controller at c000000 {
 			#interrupt-cells = <3>;
 		};
 
-		clock-controller at 10001000 {
+		infracfg: clock-controller at 10001000 {
 			compatible = "mediatek,mt7988-infracfg", "syscon";
 			reg = <0 0x10001000 0 0x1000>;
 			#clock-cells = <1>;
@@ -103,6 +104,24 @@ clock-controller at 1001e000 {
 			#clock-cells = <1>;
 		};
 
+		pwm at 10048000 {
+			compatible = "mediatek,mt7988-pwm";
+			reg = <0 0x10048000 0 0x1000>;
+			clocks = <&infracfg CLK_INFRA_66M_PWM_BCK>,
+				 <&infracfg CLK_INFRA_66M_PWM_HCK>,
+				 <&infracfg CLK_INFRA_66M_PWM_CK1>,
+				 <&infracfg CLK_INFRA_66M_PWM_CK2>,
+				 <&infracfg CLK_INFRA_66M_PWM_CK3>,
+				 <&infracfg CLK_INFRA_66M_PWM_CK4>,
+				 <&infracfg CLK_INFRA_66M_PWM_CK5>,
+				 <&infracfg CLK_INFRA_66M_PWM_CK6>,
+				 <&infracfg CLK_INFRA_66M_PWM_CK7>,
+				 <&infracfg CLK_INFRA_66M_PWM_CK8>;
+			clock-names = "top", "main", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6",
+				      "pwm7","pwm8";
+			#pwm-cells = <2>;
+		};
+
 		clock-controller at 11f40000 {
 			compatible = "mediatek,mt7988-xfi-pll";
 			reg = <0 0x11f40000 0 0x1000>;
-- 
2.35.3



From ryan.roberts at arm.com  Tue Feb 13 08:48:50 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 16:48:50 +0000
Subject: [PATCH v5 21/25] arm64/mm: Implement new
 [get_and_]clear_full_ptes() batch APIs
In-Reply-To: <ZcucHyb1OBG677gx@FVFF77S0Q05N.cambridge.arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-22-ryan.roberts@arm.com>
 <ZcucHyb1OBG677gx@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <aaf2bc8e-3fe3-4d41-ab5b-fca99b33c8a4@arm.com>

On 13/02/2024 16:43, Mark Rutland wrote:
> On Fri, Feb 02, 2024 at 08:07:52AM +0000, Ryan Roberts wrote:
>> Optimize the contpte implementation to fix some of the
>> exit/munmap/dontneed performance regression introduced by the initial
>> contpte commit. Subsequent patches will solve it entirely.
>>
>> During exit(), munmap() or madvise(MADV_DONTNEED), mappings must be
>> cleared. Previously this was done 1 PTE at a time. But the core-mm
>> supports batched clear via the new [get_and_]clear_full_ptes() APIs. So
>> let's implement those APIs and for fully covered contpte mappings, we no
>> longer need to unfold the contpte. This significantly reduces unfolding
>> operations, reducing the number of tlbis that must be issued.
>>
>> Tested-by: John Hubbard <jhubbard at nvidia.com>
>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>> ---
>>  arch/arm64/include/asm/pgtable.h | 67 ++++++++++++++++++++++++++++++++
>>  arch/arm64/mm/contpte.c          | 17 ++++++++
>>  2 files changed, 84 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index c07f0d563733..ad04adb7b87f 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -965,6 +965,37 @@ static inline pte_t __ptep_get_and_clear(struct mm_struct *mm,
>>  	return pte;
>>  }
>>  
>> +static inline void __clear_full_ptes(struct mm_struct *mm, unsigned long addr,
>> +				pte_t *ptep, unsigned int nr, int full)
>> +{
>> +	for (;;) {
>> +		__ptep_get_and_clear(mm, addr, ptep);
>> +		if (--nr == 0)
>> +			break;
>> +		ptep++;
>> +		addr += PAGE_SIZE;
>> +	}
>> +}
> 
> The loop construct is a bit odd; can't this be:

I found it a little odd at first, but its avoiding the ptep and addr increments
the last time through the loop. Its the preferred pattern for these functions in
core-mm. See default set_ptes(), wrprotect_ptes(), clear_full_ptes() in
include/linux/pgtable.h.

So I'd prefer to leave it as is so that we match them. What do you think?

> 
> 	while (nr--) {
> 		__ptep_get_and_clear(mm, addr, ptep);
> 		ptep++;
> 		addr += PAGE_SIZE;
> 	}
> 
> ... or:
> 
> 	do {
> 		__ptep_get_and_clear(mm, addr, ptep);
> 		ptep++;
> 		addr += PAGE_SIZE;
> 	} while (--nr);
> 
> ... ?
> 
> Otherwise, this looks good to me.
> 
> Mark.
> 
>> +
>> +static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm,
>> +				unsigned long addr, pte_t *ptep,
>> +				unsigned int nr, int full)
>> +{
>> +	pte_t pte, tmp_pte;
>> +
>> +	pte = __ptep_get_and_clear(mm, addr, ptep);
>> +	while (--nr) {
>> +		ptep++;
>> +		addr += PAGE_SIZE;
>> +		tmp_pte = __ptep_get_and_clear(mm, addr, ptep);
>> +		if (pte_dirty(tmp_pte))
>> +			pte = pte_mkdirty(pte);
>> +		if (pte_young(tmp_pte))
>> +			pte = pte_mkyoung(pte);
>> +	}
>> +	return pte;
>> +}
>> +
>>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>>  #define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
>>  static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
>> @@ -1167,6 +1198,11 @@ extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
>>  extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
>>  extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
>>  				pte_t *ptep, pte_t pte, unsigned int nr);
>> +extern void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
>> +				pte_t *ptep, unsigned int nr, int full);
>> +extern pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
>> +				unsigned long addr, pte_t *ptep,
>> +				unsigned int nr, int full);
>>  extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>>  				unsigned long addr, pte_t *ptep);
>>  extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>> @@ -1254,6 +1290,35 @@ static inline void pte_clear(struct mm_struct *mm,
>>  	__pte_clear(mm, addr, ptep);
>>  }
>>  
>> +#define clear_full_ptes clear_full_ptes
>> +static inline void clear_full_ptes(struct mm_struct *mm, unsigned long addr,
>> +				pte_t *ptep, unsigned int nr, int full)
>> +{
>> +	if (likely(nr == 1)) {
>> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>> +		__clear_full_ptes(mm, addr, ptep, nr, full);
>> +	} else {
>> +		contpte_clear_full_ptes(mm, addr, ptep, nr, full);
>> +	}
>> +}
>> +
>> +#define get_and_clear_full_ptes get_and_clear_full_ptes
>> +static inline pte_t get_and_clear_full_ptes(struct mm_struct *mm,
>> +				unsigned long addr, pte_t *ptep,
>> +				unsigned int nr, int full)
>> +{
>> +	pte_t pte;
>> +
>> +	if (likely(nr == 1)) {
>> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>> +		pte = __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
>> +	} else {
>> +		pte = contpte_get_and_clear_full_ptes(mm, addr, ptep, nr, full);
>> +	}
>> +
>> +	return pte;
>> +}
>> +
>>  #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
>>  static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
>>  				unsigned long addr, pte_t *ptep)
>> @@ -1338,6 +1403,8 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
>>  #define set_pte					__set_pte
>>  #define set_ptes				__set_ptes
>>  #define pte_clear				__pte_clear
>> +#define clear_full_ptes				__clear_full_ptes
>> +#define get_and_clear_full_ptes			__get_and_clear_full_ptes
>>  #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
>>  #define ptep_get_and_clear			__ptep_get_and_clear
>>  #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
>> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
>> index c85e64baf03b..80346108450b 100644
>> --- a/arch/arm64/mm/contpte.c
>> +++ b/arch/arm64/mm/contpte.c
>> @@ -207,6 +207,23 @@ void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
>>  }
>>  EXPORT_SYMBOL(contpte_set_ptes);
>>  
>> +void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
>> +				pte_t *ptep, unsigned int nr, int full)
>> +{
>> +	contpte_try_unfold_partial(mm, addr, ptep, nr);
>> +	__clear_full_ptes(mm, addr, ptep, nr, full);
>> +}
>> +EXPORT_SYMBOL(contpte_clear_full_ptes);
>> +
>> +pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
>> +				unsigned long addr, pte_t *ptep,
>> +				unsigned int nr, int full)
>> +{
>> +	contpte_try_unfold_partial(mm, addr, ptep, nr);
>> +	return __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
>> +}
>> +EXPORT_SYMBOL(contpte_get_and_clear_full_ptes);
>> +
>>  int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>>  					unsigned long addr, pte_t *ptep)
>>  {
>> -- 
>> 2.25.1
>>



From oliver.upton at linux.dev  Tue Feb 13 08:51:12 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 13 Feb 2024 16:51:12 +0000
Subject: [PATCH v5 3/4] KVM: arm64: Register ptdump with debugfs on guest
 creation
In-Reply-To: <Zcub87FwaVPkCXQE@google.com>
References: <20240207144832.1017815-2-sebastianene@google.com>
 <20240207144832.1017815-5-sebastianene@google.com>
 <Zcq-NGa-Gd9rVVgF@linux.dev>
 <Zcub87FwaVPkCXQE@google.com>
Message-ID: <ZcueAGbQISkxaTNR@linux.dev>

On Tue, Feb 13, 2024 at 04:42:27PM +0000, Sebastian Ene wrote:
> On Tue, Feb 13, 2024 at 12:56:20AM +0000, Oliver Upton wrote:
> > On Wed, Feb 07, 2024 at 02:48:32PM +0000, Sebastian Ene wrote:

[...]

> > > +static int kvm_ptdump_guest_open(struct inode *inode, struct file *file)
> > > +{
> > > +	return single_open(file, kvm_ptdump_guest_show, inode->i_private);
> > > +}
> > > +
> > 
> > Shouldn't we take a reference on the KVM struct at open to avoid UAF?
> > 
> > 	struct kvm *kvm = inode->i_private;
> > 
> > 	if (!kvm_get_kvm_safe(kvm))
> > 		return -ENOENT;
> > 
> > Then you can do a put on it at close().
> > 
> 
> Thanks, I though that the kvm_destroy_vm_debugfs will keep spinning if
> there are opened paths to the debugfs entry, but I guess nothing prevents
> that from happening and the kvm struct can be removed behind our back.

kvm_destroy_vm() will get called after the last put() on a kvm struct,
so all debugfs files should be closed too if we're consistent about
this.

-- 
Thanks,
Oliver


From maz at kernel.org  Tue Feb 13 08:52:36 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 13 Feb 2024 16:52:36 +0000
Subject: [RFC PATCH] KVM: arm64: Fix double-free following kvm_pgtable_stage2_free_unlinked()
In-Reply-To: <ZcuY9rdvGaJ66edx@linux.dev>
References: <20240212193052.27765-1-will@kernel.org>
	<Zcp8LcvsZiZVkNKe@linux.dev>
	<86cyt062jh.wl-maz@kernel.org>
	<ZcuY9rdvGaJ66edx@linux.dev>
Message-ID: <868r3o5msr.wl-maz@kernel.org>

On Tue, 13 Feb 2024 16:29:42 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Tue, Feb 13, 2024 at 11:12:34AM +0000, Marc Zyngier wrote:
> > On Mon, 12 Feb 2024 20:14:37 +0000,
> > Oliver Upton <oliver.upton at linux.dev> wrote:
> > > 
> > > On Mon, Feb 12, 2024 at 07:30:52PM +0000, Will Deacon wrote:
> > > > kvm_pgtable_stage2_free_unlinked() does the final put_page() on the
> > > > root page of the sub-tree before returning, so remove the additional
> > > > put_page() invocations in the callers.
> > > > 
> > > > Cc: Marc Zyngier <maz at kernel.org>
> > > > Cc: Oliver Upton <oliver.upton at linux.dev>
> > > > Cc: Ricardo Koller <ricarkol at google.com>
> > > > Signed-off-by: Will Deacon <will at kernel.org>
> > > > ---
> > > > 
> > > > Hi folks,
> > > > 
> > > > Sending this as an RFC as I only spotted it from code inspection and I'm
> > > > surprised others aren't seeing fireworks if it's a genuine bug. I also
> > > > couldn't come up with a sensible Fixes tag, as all of:
> > > > 
> > > >  e7c05540c694b ("KVM: arm64: Add helper for creating unlinked stage2 subtrees")
> > > >  8f5a3eb7513fc ("KVM: arm64: Add kvm_pgtable_stage2_split()")
> > > >  f6a27d6dc51b2 ("KVM: arm64: Drop last page ref in kvm_pgtable_stage2_free_removed()")
> > 
> > I'd blame it on the last commit, as we really ought to have it if we
> > have the others.
> > 
> > > >
> > > > are actually ok in isolation. Hrm. Please tell me I'm wrong?
> > > > 
> > > >  arch/arm64/kvm/hyp/pgtable.c | 2 --
> > > >  1 file changed, 2 deletions(-)
> > > > 
> > > > diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> > > > index c651df904fe3..ab9d05fcf98b 100644
> > > > --- a/arch/arm64/kvm/hyp/pgtable.c
> > > > +++ b/arch/arm64/kvm/hyp/pgtable.c
> > > > @@ -1419,7 +1419,6 @@ kvm_pte_t *kvm_pgtable_stage2_create_unlinked(struct kvm_pgtable *pgt,
> > > >  				 level + 1);
> > > >  	if (ret) {
> > > >  		kvm_pgtable_stage2_free_unlinked(mm_ops, pgtable, level);
> > > > -		mm_ops->put_page(pgtable);
> > > >  		return ERR_PTR(ret);
> > > >  	}
> > > 
> > > AFAICT, this entire branch is effectively dead code, unless there's a
> > > KVM bug lurking behind the page table walk. The sub-tree isn't visible
> > > to other software or hardware walkers yet, so none of the PTE races
> > > could cause this to pop.
> > > 
> > > So while this is very obviously a bug, it might be pure luck that folks
> > > haven't seen smoke here. Perhaps while fixing the bug we should take the
> > > opportunity to promote the condition to WARN_ON_ONCE().
> > 
> > Can't you construct a case where an allocation fails during the walk
> > (memcache empty), and we end up on this exact path?
> 
> Possibly, but AFAICT that can only happen if there was a bug in KVM. We
> don't start the walk at all if userspace set the split chunk size to 0,
> and otherwise we expect it to be at least PMD_SIZE, which will top up
> the cache to 1 every pass. stage2_split_walker() will 'do the right
> thing' if there aren't enough preallocated pages to get down to level 3.
> 
> It really doesn't matter either way, I'm just trying to convince myself
> of the reasons why we haven't seen this explode yet :)

Yeah, that's probably very unlikely to hit given the current
conditions.

> 
> > > 
> > > > @@ -1502,7 +1501,6 @@ static int stage2_split_walker(const struct kvm_pgtable_visit_ctx *ctx,
> > > >  
> > > >  	if (!stage2_try_break_pte(ctx, mmu)) {
> > > >  		kvm_pgtable_stage2_free_unlinked(mm_ops, childp, level);
> > > > -		mm_ops->put_page(childp);
> > > >  		return -EAGAIN;
> > > >  	}
> > > 
> > > This, on the other hand, seems possible. There exists a race where an
> > > old block PTE could have the AF set on it and the underlying cmpxchg()
> > > could fail. There shouldn't be a race with any software walkers, as we
> > > hold the MMU lock for write here.
> > 
> > AF update is indeed a likely candidate.
> > 
> > In any case, this patch looks good to me as it is, and we can always
> > have a separate tweak to adjust the severity of the first case as
> > required. Unless anyone objects, I'd like to queue it shortly.
> 
> Agreed, happy with the way this looks and should've added:
> 
> Reviewed-by: Oliver Upton <oliver.upton at linux.dev>
> 
> the first time around.

Thanks for that. I'll queue that shortly and send (another) PR.

	M.

-- 
Without deviation from the norm, progress is not possible.


From mark.rutland at arm.com  Tue Feb 13 08:53:01 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 13 Feb 2024 16:53:01 +0000
Subject: [PATCH v5 21/25] arm64/mm: Implement new
 [get_and_]clear_full_ptes() batch APIs
In-Reply-To: <aaf2bc8e-3fe3-4d41-ab5b-fca99b33c8a4@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-22-ryan.roberts@arm.com>
 <ZcucHyb1OBG677gx@FVFF77S0Q05N.cambridge.arm.com>
 <aaf2bc8e-3fe3-4d41-ab5b-fca99b33c8a4@arm.com>
Message-ID: <ZcuebesH1pvx4sxl@FVFF77S0Q05N.cambridge.arm.com>

On Tue, Feb 13, 2024 at 04:48:50PM +0000, Ryan Roberts wrote:
> On 13/02/2024 16:43, Mark Rutland wrote:
> > On Fri, Feb 02, 2024 at 08:07:52AM +0000, Ryan Roberts wrote:

> >> +static inline void __clear_full_ptes(struct mm_struct *mm, unsigned long addr,
> >> +				pte_t *ptep, unsigned int nr, int full)
> >> +{
> >> +	for (;;) {
> >> +		__ptep_get_and_clear(mm, addr, ptep);
> >> +		if (--nr == 0)
> >> +			break;
> >> +		ptep++;
> >> +		addr += PAGE_SIZE;
> >> +	}
> >> +}
> > 
> > The loop construct is a bit odd; can't this be:
> 
> I found it a little odd at first, but its avoiding the ptep and addr increments
> the last time through the loop. Its the preferred pattern for these functions in
> core-mm. See default set_ptes(), wrprotect_ptes(), clear_full_ptes() in
> include/linux/pgtable.h.
> 
> So I'd prefer to leave it as is so that we match them. What do you think?

That's fair enough; it I'm happy with it as-is.

Mark.


From mark.rutland at arm.com  Tue Feb 13 08:54:51 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 13 Feb 2024 16:54:51 +0000
Subject: [PATCH v5 23/25] arm64/mm: Implement pte_batch_hint()
In-Reply-To: <20240202080756.1453939-24-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-24-ryan.roberts@arm.com>
Message-ID: <Zcue2_wPJe8lx4_u@FVFF77S0Q05N.cambridge.arm.com>

On Fri, Feb 02, 2024 at 08:07:54AM +0000, Ryan Roberts wrote:
> When core code iterates over a range of ptes and calls ptep_get() for
> each of them, if the range happens to cover contpte mappings, the number
> of pte reads becomes amplified by a factor of the number of PTEs in a
> contpte block. This is because for each call to ptep_get(), the
> implementation must read all of the ptes in the contpte block to which
> it belongs to gather the access and dirty bits.
> 
> This causes a hotspot for fork(), as well as operations that unmap
> memory such as munmap(), exit and madvise(MADV_DONTNEED). Fortunately we
> can fix this by implementing pte_batch_hint() which allows their
> iterators to skip getting the contpte tail ptes when gathering the batch
> of ptes to operate on. This results in the number of PTE reads returning
> to 1 per pte.
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/pgtable.h | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index ad04adb7b87f..353ea67b5d75 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -1220,6 +1220,15 @@ static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>  		__contpte_try_unfold(mm, addr, ptep, pte);
>  }
>  
> +#define pte_batch_hint pte_batch_hint
> +static inline unsigned int pte_batch_hint(pte_t *ptep, pte_t pte)
> +{
> +	if (!pte_valid_cont(pte))
> +		return 1;
> +
> +	return CONT_PTES - (((unsigned long)ptep >> 3) & (CONT_PTES - 1));
> +}
> +
>  /*
>   * The below functions constitute the public API that arm64 presents to the
>   * core-mm to manipulate PTE entries within their page tables (or at least this
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Tue Feb 13 08:55:49 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 13 Feb 2024 16:55:49 +0000
Subject: [PATCH v5 24/25] arm64/mm: __always_inline to improve fork() perf
In-Reply-To: <20240202080756.1453939-25-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-25-ryan.roberts@arm.com>
Message-ID: <ZcufFVa7FJRgrEI1@FVFF77S0Q05N.cambridge.arm.com>

On Fri, Feb 02, 2024 at 08:07:55AM +0000, Ryan Roberts wrote:
> As set_ptes() and wrprotect_ptes() become a bit more complex, the
> compiler may choose not to inline them. But this is critical for fork()
> performance. So mark the functions, along with contpte_try_unfold()
> which is called by them, as __always_inline. This is worth ~1% on the
> fork() microbenchmark with order-0 folios (the common case).
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

I have no strong feelings either way on this, so:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/pgtable.h | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 353ea67b5d75..cdc310880a3b 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -1213,8 +1213,8 @@ extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep,
>  				pte_t entry, int dirty);
>  
> -static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
> -					pte_t *ptep, pte_t pte)
> +static __always_inline void contpte_try_unfold(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep, pte_t pte)
>  {
>  	if (unlikely(pte_valid_cont(pte)))
>  		__contpte_try_unfold(mm, addr, ptep, pte);
> @@ -1279,7 +1279,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
>  }
>  
>  #define set_ptes set_ptes
> -static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
> +static __always_inline void set_ptes(struct mm_struct *mm, unsigned long addr,
>  				pte_t *ptep, pte_t pte, unsigned int nr)
>  {
>  	pte = pte_mknoncont(pte);
> @@ -1361,8 +1361,8 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
>  }
>  
>  #define wrprotect_ptes wrprotect_ptes
> -static inline void wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
> -				pte_t *ptep, unsigned int nr)
> +static __always_inline void wrprotect_ptes(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep, unsigned int nr)
>  {
>  	if (likely(nr == 1)) {
>  		/*
> -- 
> 2.25.1
> 


From gregkh at linuxfoundation.org  Tue Feb 13 08:58:35 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Tue, 13 Feb 2024 17:58:35 +0100
Subject: [PATCH] arm64: allow post-init vmalloc PXNTable
In-Reply-To: <CAP5Mv+ydhk=Ob4b40ZahGMgT-5+-VEHxtmA=-LkJiEOOU+K6hw@mail.gmail.com>
References: <CAP5Mv+ydhk=Ob4b40ZahGMgT-5+-VEHxtmA=-LkJiEOOU+K6hw@mail.gmail.com>
Message-ID: <2024021300-gently-ether-3978@gregkh>

On Tue, Feb 13, 2024 at 10:05:45AM -0600, Maxwell Bland wrote:
> Apologies if this is a duplicate mail, it will be the last one. Moto's SMTP
> server sucks!!

This shouldn't be in the changelog, it needs to go below the --- line.

Also, your patch is corrupted and can not be applied :(

thanks,

greg k-h


From sebastianene at google.com  Tue Feb 13 08:59:01 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Tue, 13 Feb 2024 16:59:01 +0000
Subject: [PATCH v5 4/4] KVM: arm64: Initialize the ptdump parser with
 stage-2 attributes
In-Reply-To: <Zcq7AoII8qLWwjsu@linux.dev>
References: <20240207144832.1017815-2-sebastianene@google.com>
 <20240207144832.1017815-6-sebastianene@google.com>
 <Zcq7AoII8qLWwjsu@linux.dev>
Message-ID: <Zcuf1ZUvwhxBobuG@google.com>

On Tue, Feb 13, 2024 at 12:42:42AM +0000, Oliver Upton wrote:
> On Wed, Feb 07, 2024 at 02:48:33PM +0000, Sebastian Ene wrote:
> > Define a set of attributes used by the ptdump parser to display the
> > properties of a guest memory region covered by a pagetable descriptor.
> > Build a description of the pagetable levels and initialize the parser
> > with this configuration.
> > 
> > Signed-off-by: Sebastian Ene <sebastianene at google.com>
> > ---
> >  arch/arm64/kvm/ptdump.c | 156 ++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 156 insertions(+)
> > 
> > diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> > index a4e984da8aa7..60725d46f17b 100644
> > --- a/arch/arm64/kvm/ptdump.c
> > +++ b/arch/arm64/kvm/ptdump.c
> > @@ -14,6 +14,69 @@
> >  #include <kvm_ptdump.h>
> >  
> >  
> > +#define ADDR_MARKER_LEN		(2)
> > +#define MARKER_MSG_LEN		(32)
> > +
> > +static const struct prot_bits stage2_pte_bits[] = {
> > +	{
> > +		.mask	= PTE_VALID,
> > +		.val	= PTE_VALID,
> > +		.set	= " ",
> > +		.clear	= "F",
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
> > +		.val	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
> > +		.set	= "XN",
> > +		.clear	= "  ",
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> > +		.set	= "R",
> > +		.clear	= " ",
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> > +		.set	= "W",
> > +		.clear	= " ",
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> > +		.set	= "AF",
> > +		.clear	= "  ",
> > +	}, {
> > +		.mask	= PTE_NG,
> > +		.val	= PTE_NG,
> > +		.set	= "FnXS",
> > +		.clear	= "  ",
> > +	}, {
> > +		.mask	= PTE_CONT | PTE_VALID,
> > +		.val	= PTE_CONT | PTE_VALID,
> > +		.set	= "CON",
> > +		.clear	= "   ",
> > +	}, {
> > +		.mask	= PTE_TABLE_BIT,
> > +		.val	= PTE_TABLE_BIT,
> > +		.set	= "   ",
> > +		.clear	= "BLK",
> 
> <snip>
> 
> > +	}, {
> > +		.mask	= KVM_PGTABLE_PROT_SW0,
> > +		.val	= KVM_PGTABLE_PROT_SW0,
> > +		.set	= "SW0", /* PKVM_PAGE_SHARED_OWNED */
> > +	}, {
> > +		.mask   = KVM_PGTABLE_PROT_SW1,
> > +		.val	= KVM_PGTABLE_PROT_SW1,
> > +		.set	= "SW1", /* PKVM_PAGE_SHARED_BORROWED */
> > +	}, {
> > +		.mask	= KVM_PGTABLE_PROT_SW2,
> > +		.val	= KVM_PGTABLE_PROT_SW2,
> > +		.set	= "SW2",
> > +	}, {
> > +		.mask   = KVM_PGTABLE_PROT_SW3,
> > +		.val	= KVM_PGTABLE_PROT_SW3,
> > +		.set	= "SW3",
> > +	},
> 
> </snip>
> 
> These bits are never set in a 'normal' stage-2 PTE, does it make sense
> to carry descriptors for them here? In contexts where the SW bits are
> used it might be more useful if the ptdump used the specific meaning of
> the bit (e.g. OWNED, BORROWED, etc) instead of the generic SW%d.
> 
> That can all wait for when the pKVM bits come into play though.
> 

True, I guess we don't need these bits for now. We can insert them at a
later time when we will have the pKVM support and then we will have to
use their real maning for the state tracking.

> > +};
> > +
> >  static int kvm_ptdump_guest_open(struct inode *inode, struct file *file);
> >  static int kvm_ptdump_guest_show(struct seq_file *m, void *);
> >  
> > @@ -52,6 +115,94 @@ static int kvm_ptdump_show_common(struct seq_file *m,
> >  	return kvm_pgtable_walk(pgtable, 0, BIT(pgtable->ia_bits), &walker);
> >  }
> >  
> > +static void kvm_ptdump_build_levels(struct pg_level *level, u32 start_lvl)
> > +{
> > +	static const char * const level_names[] = {"PGD", "PUD", "PMD", "PTE"};
> > +	u32 i = 0;
> > +	u64 mask_lvl = 0;
> 
> nit: _lvl adds nothing to this, and actually confused me for a sec as
> to whether the mask changed per level.
> 

I will drop it from the name to avoid the confusion.

> > +	if (start_lvl > 2) {
> > +		pr_err("invalid start_lvl %u\n", start_lvl);
> > +		return;
> > +	}
> 
> Can't we get something like -EINVAL out here and fail initialization?
> Otherwise breadcrumbs like this pr_err() are hard to connect to a
> specific failure.
>

Ok, I will add a return code for this function.

> > +	for (i = 0; i < ARRAY_SIZE(stage2_pte_bits); i++)
> > +		mask_lvl |= stage2_pte_bits[i].mask;
> > +
> > +	for (i = start_lvl; i <= KVM_PGTABLE_LAST_LEVEL; i++) {
> > +		level[i].name = level_names[i];
> > +		level[i].num = ARRAY_SIZE(stage2_pte_bits);
> > +		level[i].bits = stage2_pte_bits;
> > +		level[i].mask = mask_lvl;
> > +	}
> > +
> > +	if (start_lvl > 0)
> > +		level[start_lvl].name = level_names[0];
> > +}
> > +
> > +static int kvm_ptdump_parser_init(struct pg_state *st,
> > +				  struct kvm_pgtable *pgtable,
> > +				  struct seq_file *m)
> > +{
> > +	struct addr_marker *ipa_addr_marker;
> > +	char *marker_msg;
> > +	struct pg_level *level_descr;
> > +	struct ptdump_range *range;
> > +
> > +	ipa_addr_marker = kzalloc(sizeof(struct addr_marker) * ADDR_MARKER_LEN,
> > +				  GFP_KERNEL_ACCOUNT);
> > +	if (!ipa_addr_marker)
> > +		return -ENOMEM;
> > +
> > +	marker_msg = kzalloc(MARKER_MSG_LEN, GFP_KERNEL_ACCOUNT);
> > +	if (!marker_msg)
> > +		goto free_with_marker;
> > +
> > +	level_descr = kzalloc(sizeof(struct pg_level) * (KVM_PGTABLE_LAST_LEVEL + 1),
> > +			      GFP_KERNEL_ACCOUNT);
> > +	if (!level_descr)
> > +		goto free_with_msg;
> > +
> > +	range = kzalloc(sizeof(struct ptdump_range) * ADDR_MARKER_LEN,
> > +			GFP_KERNEL_ACCOUNT);
> > +	if (!range)
> > +		goto free_with_level;
> > +
> > +	kvm_ptdump_build_levels(level_descr, pgtable->start_level);
> > +
> > +	snprintf(marker_msg, MARKER_MSG_LEN, "IPA bits %2u start lvl %1d",
> > +		 pgtable->ia_bits, pgtable->start_level);
> > +
> > +	ipa_addr_marker[0].name = marker_msg;
> 
> Is the dynamic name worth the added complexity? I see nothing wrong with
> exposing additional debugfs files for simple attributes like the IPA
> range and page table levels.
> 
> I know it isn't *that* much, just looking for every opportunity to
> simplify further.
> 

We can keep them separate, I have no strong opinion about this. I think
this was Vincent's, original suggestion to have them so I will check with
him as well.

> > +	ipa_addr_marker[1].start_address = BIT(pgtable->ia_bits);
> > +	range[0].end = BIT(pgtable->ia_bits);
> > +
> > +	st->seq = m;
> > +	st->marker = ipa_addr_marker;
> > +	st->level = -1,
> > +	st->pg_level = level_descr,
> > +	st->ptdump.range = range;
> > +	return 0;
> > +
> > +free_with_level:
> > +	kfree(level_descr);
> > +free_with_msg:
> > +	kfree(marker_msg);
> > +free_with_marker:
> > +	kfree(ipa_addr_marker);
> > +	return -ENOMEM;
> > +}
> > +
> > +static void kvm_ptdump_parser_teardown(struct pg_state *st)
> > +{
> > +	const struct addr_marker *ipa_addr_marker = st->marker;
> > +
> > +	kfree(ipa_addr_marker[0].name);
> > +	kfree(ipa_addr_marker);
> > +	kfree(st->pg_level);
> > +	kfree(st->ptdump.range);
> > +}
> > +
> >  static int kvm_ptdump_guest_show(struct seq_file *m, void *)
> >  {
> >  	struct kvm *guest_kvm = m->private;
> > @@ -59,10 +210,15 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *)
> >  	struct pg_state parser_state = {0};
> >  	int ret;
> >  
> > +	ret = kvm_ptdump_parser_init(&parser_state, mmu->pgt, m);
> > +	if (ret)
> > +		return ret;
> > +
> 
> Can this be done at open(), or am I missing something?
> 

I guess we can do this in open() but then we will have to add again that
struct that wraps some ptdump specific state tracking. It seemed a bit cleaner in
this way. What do you think ?

> >  	write_lock(&guest_kvm->mmu_lock);
> >  	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
> >  	write_unlock(&guest_kvm->mmu_lock);
> >  
> > +	kvm_ptdump_parser_teardown(&parser_state);
> 
> Same question here, can this happen at close()? I guess you'll need a
> struct to encapsulate pg_state and a pointer to the VM at least.
>

Right, I tried to avoid using a separate struct as we discussed in v4.

> Actually, come to think of it, if you embed all of the data you need for
> the walker into a structure you can just do a single allocation for it
> upfront.
> 
> -- 
> Thanks,
> Oliver

Thanks for the feedback,
Seb


From smostafa at google.com  Tue Feb 13 09:00:44 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Tue, 13 Feb 2024 17:00:44 +0000
Subject: [PATCH v5 11/17] iommu/arm-smmu-v3: Remove
 arm_smmu_master->domain
In-Reply-To: <20240213163739.GE1088888@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <11-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZcuOnnrWN3ZxJY8x@google.com>
 <20240213163739.GE1088888@nvidia.com>
Message-ID: <ZcugPKDPlx6mOgfg@google.com>

On Tue, Feb 13, 2024 at 12:37:39PM -0400, Jason Gunthorpe wrote:
> On Tue, Feb 13, 2024 at 03:45:34PM +0000, Mostafa Saleh wrote:
> > Hi Jason,
> > 
> > On Tue, Feb 06, 2024 at 11:12:48AM -0400, Jason Gunthorpe wrote:
> > > Introducing global statics which are of type struct iommu_domain, not
> > > struct arm_smmu_domain makes it difficult to retain
> > > arm_smmu_master->domain, as it can no longer point to an IDENTITY or
> > > BLOCKED domain.
> > > 
> > > The only place that uses the value is arm_smmu_detach_dev(). Change things
> > > to work like other drivers and call iommu_get_domain_for_dev() to obtain
> > > the current domain.
> > > 
> > > The master->domain is subtly protecting the domain_head against being
> > > unused, change the domain_head to be INIT'd when the master is not
> > > attached to a domain instead of garbage/zero.
> > 
> > I don't this the problem here, neither the reason for initialising the
> > domain_head, can you please clarify the issue?
> 
> I didn't notice it either. Eric found it:
> 
> https://lore.kernel.org/linux-iommu/6fff20dd-46d5-4974-a4a5-fb4e7a59ce44 at redhat.com/
> 
> > > @@ -2560,19 +2560,20 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
> > >  
> > >  static void arm_smmu_detach_dev(struct arm_smmu_master *master)
> > >  {
> > > +	struct iommu_domain *domain = iommu_get_domain_for_dev(master->dev);
> > > +	struct arm_smmu_domain *smmu_domain;
> > >  	unsigned long flags;
> > > -	struct arm_smmu_domain *smmu_domain = master->domain;
> 
> master->domain is NULL here which happens in cases where the current
> RID domain is not a PAGING domain.
> 
> > > -	if (!smmu_domain)
> > > +	if (!domain)
> > >  		return;
> 
> Which used to early exit
> 
> > >  
> > > +	smmu_domain = to_smmu_domain(domain);
> > >  	arm_smmu_disable_ats(master, smmu_domain);
> > >  
> > >  	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> > > -	list_del(&master->domain_head);
> > > +	list_del_init(&master->domain_head);
> > >  	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
> 
> But now would cause the list_del() to hit a non-inited list_head and
> explode.
> 
> Instead we keep the list head init'd and the list_del is a NOP.
> 
> Tricky right??
> 
> I changed the comment like this:
> 
> The master->domain is subtly protecting the master->domain_head against
> being unused as only PAGING domains will set master->domain and only
> paging domains use the master->domain_head. To make it simple keep the
> master->domain_head initialized so that the list_del() logic just does
> nothing for non-PAGING domains.
> 
> OK?

Ahh, I see, as iommu_get_domain_for_dev() now returns a valid domain.
Thanks for the explanation, that makes sense.

Reviewed-by: Mostafa Saleh <smostafa at google.com>

Thanks,
Mostafa


From rsc at runtux.com  Tue Feb 13 09:06:57 2024
From: rsc at runtux.com (Ralf Schlatterbeck)
Date: Tue, 13 Feb 2024 18:06:57 +0100
Subject: [PATCH v2 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <20240202115330.wxkbfmvd76sy3a6a@runtux.com>
References: <20240202115330.wxkbfmvd76sy3a6a@runtux.com>
Message-ID: <20240213170657.puwlx5pjl3odcs2k@runtux.com>

On Fri, Feb 02, 2024 at 12:53:30PM +0100, Ralf Schlatterbeck wrote:
> There was a change in the mxs-dma engine that uses a new custom flag.
> The change was not applied to the mxs spi driver.
> This results in chipselect being deasserted too early.
> This fixes the chipselect problem by using the new flag in the mxs-spi
> driver.
> 
> Fixes: ceeeb99cd821 ("dmaengine: mxs: rename custom flag")
> Signed-off-by: Ralf Schlatterbeck <rsc at runtux.com>
> ---
> For oscilloscope screenshots and a verbose explanation see my blog post
> at https://blog.runtux.com/posts/2024/02/01/
> History:
> Omit the line break change from patch requested by Marc Kleine-Budde
> <mkl at pengutronix.de>
> 
>  drivers/spi/spi-mxs.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
> index 1bf080339b5a..88cbe4f00cc3 100644
> --- a/drivers/spi/spi-mxs.c
> +++ b/drivers/spi/spi-mxs.c
> @@ -39,6 +39,7 @@
>  #include <linux/spi/spi.h>
>  #include <linux/spi/mxs-spi.h>
>  #include <trace/events/spi.h>
> +#include <linux/dma/mxs-dma.h>
>  
>  #define DRIVER_NAME		"mxs-spi"
>  
> @@ -252,7 +253,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
>  		desc = dmaengine_prep_slave_sg(ssp->dmach,
>  				&dma_xfer[sg_count].sg, 1,
>  				(flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
> -				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +				DMA_PREP_INTERRUPT | MXS_DMA_CTRL_WAIT4END);
>  
>  		if (!desc) {
>  			dev_err(ssp->dev,
> -- 
> 2.20.1
> 
> -- 
> Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
> Open Source Consulting                  www:   www.runtux.com
> Reichergasse 131, A-3411 Weidling       email: office at runtux.com

Any news on this, will it be picked up for the next merge window?

Thanks + kind regards
Ralf Schlatterbeck
-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   www.runtux.com
Reichergasse 131, A-3411 Weidling       email: office at runtux.com


From afd at ti.com  Tue Feb 13 09:08:48 2024
From: afd at ti.com (Andrew Davis)
Date: Tue, 13 Feb 2024 11:08:48 -0600
Subject: [PATCH v5] arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in
 serdes_ln_ctrl
In-Reply-To: <1be60db1-f292-1074-5898-801380e1fb22@axentia.se>
References: <20240213080348.248916-1-s-vadapalli@ti.com>
 <1be60db1-f292-1074-5898-801380e1fb22@axentia.se>
Message-ID: <af73545a-1746-4e14-a3f2-772d72e6ff97@ti.com>

On 2/13/24 3:19 AM, Peter Rosin wrote:
> Hi!
> 
> 2024-02-13 at 09:03, Siddharth Vadapalli wrote:
>> From: Chintan Vankar <c-vankar at ti.com>
>>
>> Change offset in mux-reg-masks property for serdes_ln_ctrl node
>> since reg-mux property is used in compatible.
>>
>> Fixes: 2765149273f4 ("mux: mmio: use reg property when parent device is not a syscon")
>> Signed-off-by: Chintan Vankar <c-vankar at ti.com>
>> Acked-by: Andrew Davis <afd at ti.com>
>> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
>> ---
>> Hello,
>>
>> This patch is based on linux-next tagged next-20240213.
>> The v4 of this patch is a part of the series at:
>> https://lore.kernel.org/r/20240131101441.1362409-1-c-vankar at ti.com/
>>
>> Since the v4 series mentioned above has open comments on the other
>> patches in the series, this patch is being posted separately to unblock
>> other dependent series which rely on the fix implemented by this patch.
>>
>> Changes since v4:
>> - Rebased patch on linux-next tagged next-20240213.
>>
>> Regards,
>> Siddharth.
>>
>>   arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 12 ++++++------
>>   1 file changed, 6 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
>> index 3cb964982792..3b7f0eca977b 100644
>> --- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
>> @@ -52,12 +52,12 @@ serdes_ln_ctrl: mux-controller at 4080 {
>>   			compatible = "reg-mux";
>>   			reg = <0x00004080 0x30>;
>>   			#mux-control-cells = <1>;
>> -			mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
>> -					<0x4088 0x3>, <0x408c 0x3>, /* SERDES0 lane2/3 select */
>> -					<0x4090 0x3>, <0x4094 0x3>, /* SERDES1 lane0/1 select */
>> -					<0x4098 0x3>, <0x409c 0x3>, /* SERDES1 lane2/3 select */
>> -					<0x40a0 0x3>, <0x40a4 0x3>, /* SERDES2 lane0/1 select */
>> -					<0x40a8 0x3>, <0x40ac 0x3>; /* SERDES2 lane2/3 select */
>> +			mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */
>> +					<0x8 0x3>, <0xc 0x3>, /* SERDES0 lane2/3 select */
>> +					<0x10 0x3>, <0x14 0x3>, /* SERDES1 lane0/1 select */
>> +					<0x18 0x3>, <0x1c 0x3>, /* SERDES1 lane2/3 select */
>> +					<0x20 0x3>, <0x24 0x3>, /* SERDES2 lane0/1 select */
>> +					<0x28 0x3>, <0x2c 0x3>; /* SERDES2 lane2/3 select */
>>   			idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>,
>>   				      <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
>>   				      <J784S4_SERDES0_LANE2_IP3_UNUSED>,
> 
> Ouch. I suspect there is a similar problem in
> arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi:
> 
> 
> 	fss: bus at 47000000 {
> 		compatible = "simple-bus";
> 		reg = <0x0 0x47000000 0x0 0x100>;
> 		#address-cells = <2>;
> 		#size-cells = <2>;
> 		ranges;
> 
> 		hbmc_mux: mux-controller at 47000004 {
> 			compatible = "reg-mux";
> 			reg = <0x00 0x47000004 0x00 0x2>;
> 			#mux-control-cells = <1>;
> -			mux-reg-masks = <0x4 0x2>; /* HBMC select */
> +			mux-reg-masks = <0x0 0x2>; /* HBMC select */
> 		};
> 
> Who knows what non-upstreamed devices and devicetrees are affected?
> I guess we need to revert 2765149273f4 ("mux: mmio: use reg property
> when parent device is not a syscon") unless someone sees a sane way
> to fix this.

There are only two in-tree nodes with "reg-mux" with a reg property: the
one this patch fixes, and the hbmc_mux you point out, both in TI devices.
I'd say it is safe to assume we are the only users, and our non-upstreamed
DTs depend on that patch, reverting it would cause more issues for
out-of-tree users than just fixing the two broken nodes above.

Andrew

> 
> Cheers,
> Peter


From oliver.upton at linux.dev  Tue Feb 13 09:10:30 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Tue, 13 Feb 2024 17:10:30 +0000
Subject: [PATCH v5 4/4] KVM: arm64: Initialize the ptdump parser with
 stage-2 attributes
In-Reply-To: <Zcuf1ZUvwhxBobuG@google.com>
References: <20240207144832.1017815-2-sebastianene@google.com>
 <20240207144832.1017815-6-sebastianene@google.com>
 <Zcq7AoII8qLWwjsu@linux.dev>
 <Zcuf1ZUvwhxBobuG@google.com>
Message-ID: <ZcuihokcWA3q-pZS@linux.dev>

On Tue, Feb 13, 2024 at 04:59:01PM +0000, Sebastian Ene wrote:
> On Tue, Feb 13, 2024 at 12:42:42AM +0000, Oliver Upton wrote:
> > On Wed, Feb 07, 2024 at 02:48:33PM +0000, Sebastian Ene wrote:

[...]

> > > +
> > > +	snprintf(marker_msg, MARKER_MSG_LEN, "IPA bits %2u start lvl %1d",
> > > +		 pgtable->ia_bits, pgtable->start_level);
> > > +
> > > +	ipa_addr_marker[0].name = marker_msg;
> > 
> > Is the dynamic name worth the added complexity? I see nothing wrong with
> > exposing additional debugfs files for simple attributes like the IPA
> > range and page table levels.
> > 
> > I know it isn't *that* much, just looking for every opportunity to
> > simplify further.
> > 
> 
> We can keep them separate, I have no strong opinion about this. I think
> this was Vincent's, original suggestion to have them so I will check with
> him as well.

Well, if we get to the place where there's a single struct containing
all of the required data upfront then this becomes less of an issue.
This is useful information still, so let's see if we can go about it the
other way.

> > > +	ret = kvm_ptdump_parser_init(&parser_state, mmu->pgt, m);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > 
> > Can this be done at open(), or am I missing something?
> > 
> 
> I guess we can do this in open() but then we will have to add again that
> struct that wraps some ptdump specific state tracking. It seemed a bit cleaner in
> this way. What do you think ?

Allocating something that looks like an iterator end embedding it in
->private isn't too uncommon.

> > >  	write_lock(&guest_kvm->mmu_lock);
> > >  	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
> > >  	write_unlock(&guest_kvm->mmu_lock);
> > >  
> > > +	kvm_ptdump_parser_teardown(&parser_state);
> > 
> > Same question here, can this happen at close()? I guess you'll need a
> > struct to encapsulate pg_state and a pointer to the VM at least.
> >
> 
> Right, I tried to avoid using a separate struct as we discussed in v4.

Sorry, I hope I didn't confuse you in my prior feedback.

What I had issue with was the multiple layers of function ptr / ops
structs for managing the file interface. I have zero concerns with
organizing the _data_ for the walk this way.

> > Actually, come to think of it, if you embed all of the data you need for
> > the walker into a structure you can just do a single allocation for it
> > upfront.

-- 
Thanks,
Oliver


From mbland at motorola.com  Tue Feb 13 09:16:04 2024
From: mbland at motorola.com (Maxwell Bland)
Date: Tue, 13 Feb 2024 17:16:04 +0000
Subject: [External] Re: [PATCH] arm64: allow post-init vmalloc PXNTable
In-Reply-To: <2024021300-gently-ether-3978@gregkh>
References: <CAP5Mv+ydhk=Ob4b40ZahGMgT-5+-VEHxtmA=-LkJiEOOU+K6hw@mail.gmail.com>
 <2024021300-gently-ether-3978@gregkh>
Message-ID: <SEZPR03MB6786975721BC2C6393731C59B44F2@SEZPR03MB6786.apcprd03.prod.outlook.com>

> This shouldn't be in the changelog, it needs to go below the --- line.

Oh! Thanks!!!

> Also, your patch is corrupted and can not be applied :(

Shoot! Apologies, I just noticed the hard-wrap at 80. I am talking to Moto's IT right now, I will resend patch once I can fix the mail server config.

Maxwell

From festevam at gmail.com  Tue Feb 13 09:22:53 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 13 Feb 2024 14:22:53 -0300
Subject: [PATCH v2 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <20240213170657.puwlx5pjl3odcs2k@runtux.com>
References: <20240202115330.wxkbfmvd76sy3a6a@runtux.com> <20240213170657.puwlx5pjl3odcs2k@runtux.com>
Message-ID: <CAOMZO5CD7+E_BBH+oQ8HUdBeRFZxWW7s2uJgS5eaQAW_Fe4CNg@mail.gmail.com>

Hi Ralf,

On Tue, Feb 13, 2024 at 2:07?PM Ralf Schlatterbeck <rsc at runtux.com> wrote:
>
> On Fri, Feb 02, 2024 at 12:53:30PM +0100, Ralf Schlatterbeck wrote:
> > There was a change in the mxs-dma engine that uses a new custom flag.
> > The change was not applied to the mxs spi driver.
> > This results in chipselect being deasserted too early.
> > This fixes the chipselect problem by using the new flag in the mxs-spi
> > driver.
> >
> > Fixes: ceeeb99cd821 ("dmaengine: mxs: rename custom flag")
> > Signed-off-by: Ralf Schlatterbeck <rsc at runtux.com>
> > ---
> > For oscilloscope screenshots and a verbose explanation see my blog post
> > at https://blog.runtux.com/posts/2024/02/01/

I suggest putting the link to your detailed explanation into the
commit log as this is useful information.

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From Jonathan.Cameron at Huawei.com  Tue Feb 13 09:25:50 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Tue, 13 Feb 2024 17:25:50 +0000
Subject: [PATCH 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
	<20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com>
Message-ID: <20240213172550.000023a7@Huawei.com>

On Mon, 12 Feb 2024 17:26:41 -0600
David Lechner <dlechner at baylibre.com> wrote:

> This adds a new spi_optimize_message() function that can be used to
> optimize SPI messages that are used more than once. Peripheral drivers
> that use the same message multiple times can use this API to perform SPI
> message validation and controller-specific optimizations once and then
> reuse the message while avoiding the overhead of revalidating the
> message on each spi_(a)sync() call.
> 
> Internally, the SPI core will also call this function for each message
> if the peripheral driver did not explicitly call it. This is done to so
> that controller drivers don't have to have multiple code paths for
> optimized and non-optimized messages.
> 
> A hook is provided for controller drivers to perform controller-specific
> optimizations.
> 
> Suggested-by: Martin Sperl <kernel at martin.sperl.org>
> Link: https://lore.kernel.org/linux-spi/39DEC004-10A1-47EF-9D77-276188D2580C at martin.sperl.org/
> Signed-off-by: David Lechner <dlechner at baylibre.com>

A few trivial things inline but looks good to me in general.

I thought about suggesting splitting this into an initial patch that just does
the bits without the controller callbacks. Maybe it would work better that way
with that introduced after the validate and splitting of transfers (so most
of patches 1 and 2) as a patch 3 prior to the stm32 additions?

> ---
>  drivers/spi/spi.c       | 145 ++++++++++++++++++++++++++++++++++++++++++++++--
>  include/linux/spi/spi.h |  19 +++++++
>  2 files changed, 160 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index c2b10e2c75f0..5bac215d7009 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -2106,6 +2106,41 @@ struct spi_message *spi_get_next_queued_message(struct spi_controller *ctlr)
>  }
>  EXPORT_SYMBOL_GPL(spi_get_next_queued_message);
>  
> +/**
> + * __spi_unoptimize_message - shared implementation of spi_unoptimize_message()
> + *                            and spi_maybe_unoptimize_message()
> + * @msg: the message to unoptimize
> + *
> + * Periperhal drivers should use spi_unoptimize_message() and callers inside
> + * core should use spi_maybe_unoptimize_message() rather than calling this
> + * function directly.
> + *
> + * It is not valid to call this on a message that is not currently optimized.
> + */
> +static void __spi_unoptimize_message(struct spi_message *msg)
> +{
> +	struct spi_controller *ctlr = msg->spi->controller;
> +
> +	if (ctlr->unoptimize_message)
> +		ctlr->unoptimize_message(msg);
> +
> +	msg->optimized = false;
> +	msg->opt_state = NULL;
> +}

Seems misbalanced that this doesn't take a pre_optimized flag in but
__spi_optimize does. I'd move handling that to outside the call in both cases.


>  	spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags);
> @@ -4271,6 +4401,8 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
>  
>  	spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags);
>  
> +	spi_maybe_unoptimize_message(message);
> +
>  	return ret;
>  }
>  EXPORT_SYMBOL_GPL(spi_async);
> @@ -4331,10 +4463,15 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message)
>  		return -ESHUTDOWN;
>  	}
>  
> -	status = __spi_validate(spi, message);
> -	if (status != 0)
> +	status = spi_maybe_optimize_message(spi, message);
> +	if (status)
>  		return status;
>  
> +	/*
> +	 * NB: all return paths after this point must ensure that
> +	 * spi_finalize_current_message() is called to avoid leaking resources.

I'm not sure a catch all like that makes sense. Not sufficient to call
the finer grained spi_maybe_unoptimize_message()  ?
> +	 */
> +
>  	SPI_STATISTICS_INCREMENT_FIELD(ctlr->pcpu_statistics, spi_sync);
>  	SPI_STATISTICS_INCREMENT_FIELD(spi->pcpu_statistics, spi_sync);



From f.fainelli at gmail.com  Tue Feb 13 09:26:45 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 13 Feb 2024 09:26:45 -0800
Subject: [PATCH net-next] net: sparx5: Add spinlock for frame transmission
 from CPU
In-Reply-To: <20240213121705.4070598-1-horatiu.vultur@microchip.com>
References: <20240213121705.4070598-1-horatiu.vultur@microchip.com>
Message-ID: <5476743f-3648-4038-97f8-a9df22c0f507@gmail.com>

On 2/13/24 04:17, Horatiu Vultur wrote:
> Both registers used when doing manual injection or fdma injection are
> shared between all the net devices of the switch. It was noticed that
> when having two process which each of them trying to inject frames on
> different ethernet ports, that the HW started to behave strange, by
> sending out more frames then expected. When doing fdma injection it is
> required to set the frame in the DCB and then make sure that the next
> pointer of the last DCB is invalid. But because there is no locks for
> this, then easily this pointer between the DCB can be broken and then it
> would create a loop of DCBs. And that means that the HW will
> continuously transmit these frames in a loop. Until the SW will break
> this loop.
> Therefore to fix this issue, add a spin lock for when accessing the
> registers for manual or fdma injection.
> 
> Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>

Any reason you targeted 'net-next' rather than 'net', as this appears to 
be clearly a bug fix here?
-- 
Florian



From Jonathan.Cameron at Huawei.com  Tue Feb 13 09:28:32 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Tue, 13 Feb 2024 17:28:32 +0000
Subject: [PATCH 5/5] iio: adc: ad7380: use spi_optimize_message()
In-Reply-To: <20240212-mainline-spi-precook-message-v1-5-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
	<20240212-mainline-spi-precook-message-v1-5-a2373cd72d36@baylibre.com>
Message-ID: <20240213172832.00004fab@Huawei.com>

On Mon, 12 Feb 2024 17:26:45 -0600
David Lechner <dlechner at baylibre.com> wrote:

> This modifies the ad7380 ADC driver to use spi_optimize_message() to
> optimize the SPI message for the buffered read operation. Since buffered
> reads reuse the same SPI message for each read, this can improve
> performance by reducing the overhead of setting up some parts the SPI
> message in each spi_sync() call.
> 
> Signed-off-by: David Lechner <dlechner at baylibre.com>
> ---
>  drivers/iio/adc/ad7380.c | 52 +++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 45 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
> index abd746aef868..5c5d2642a474 100644
> --- a/drivers/iio/adc/ad7380.c
> +++ b/drivers/iio/adc/ad7380.c
> @@ -133,6 +133,7 @@ struct ad7380_state {
>  	struct spi_device *spi;
>  	struct regulator *vref;
>  	struct regmap *regmap;
> +	struct spi_message *msg;
>  	/*
>  	 * DMA (thus cache coherency maintenance) requires the
>  	 * transfer buffers to live in their own cache lines.
> @@ -231,19 +232,55 @@ static int ad7380_debugfs_reg_access(struct iio_dev *indio_dev, u32 reg,
>  	return ret;
>  }
>  
> +static int ad7380_buffer_preenable(struct iio_dev *indio_dev)
> +{
> +	struct ad7380_state *st = iio_priv(indio_dev);
> +	struct spi_transfer *xfer;
> +	int ret;
> +
> +	st->msg = spi_message_alloc(1, GFP_KERNEL);

As it only ever has one element, is there a clear advantage over
just embedding the spi_message in the structure rather than
as a separate allocation? You'd need the transfer as well.

	spi_message_init_with_transfers(st->msg, &st->trans, 1);

The transfer is then also available without walking the list (though
obviously you don't walk very far ;).

> +	if (!st->msg)
> +		return -ENOMEM;
> +
> +	xfer = list_first_entry(&st->msg->transfers, struct spi_transfer,
> +				transfer_list);
> +
> +	xfer->bits_per_word = st->chip_info->channels[0].scan_type.realbits;
> +	xfer->len = 4;
> +	xfer->rx_buf = st->scan_data.raw;
> +
> +	ret = spi_optimize_message(st->spi, st->msg);
> +	if (ret) {
> +		spi_message_free(st->msg);
Would avoid freeing explicitly here or later if it was embedded in
struct ad7380_state

Also, this doesn't seem very dynamic in general. Anything stopping this
being done at probe() as a one time thing?

> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int ad7380_buffer_postdisable(struct iio_dev *indio_dev)
> +{
> +	struct ad7380_state *st = iio_priv(indio_dev);
> +
> +	spi_unoptimize_message(st->msg);
> +	spi_message_free(st->msg);
> +
> +	return 0;
> +}
> +
> +static const struct iio_buffer_setup_ops ad7380_buffer_setup_ops = {
> +	.preenable = ad7380_buffer_preenable,
> +	.postdisable = ad7380_buffer_postdisable,
> +};
> +
>  static irqreturn_t ad7380_trigger_handler(int irq, void *p)
>  {
>  	struct iio_poll_func *pf = p;
>  	struct iio_dev *indio_dev = pf->indio_dev;
>  	struct ad7380_state *st = iio_priv(indio_dev);
> -	struct spi_transfer xfer = {
> -		.bits_per_word = st->chip_info->channels[0].scan_type.realbits,
> -		.len = 4,
> -		.rx_buf = st->scan_data.raw,
> -	};
>  	int ret;
>  
> -	ret = spi_sync_transfer(st->spi, &xfer, 1);
> +	ret = spi_sync(st->spi, st->msg);
>  	if (ret)
>  		goto out;
>  
> @@ -420,7 +457,8 @@ static int ad7380_probe(struct spi_device *spi)
>  
>  	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
>  					      iio_pollfunc_store_time,
> -					      ad7380_trigger_handler, NULL);
> +					      ad7380_trigger_handler,
> +					      &ad7380_buffer_setup_ops);
>  	if (ret)
>  		return ret;
>  
> 



From Jonathan.Cameron at Huawei.com  Tue Feb 13 09:31:10 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Tue, 13 Feb 2024 17:31:10 +0000
Subject: [PATCH 5/5] iio: adc: ad7380: use spi_optimize_message()
In-Reply-To: <e03968102b92b3711808eb532685bc9e05fc3c8d.camel@gmail.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
	<20240212-mainline-spi-precook-message-v1-5-a2373cd72d36@baylibre.com>
	<c06dfa1ecf88b07ef467ad7c08667d0cab400613.camel@gmail.com>
	<CAMknhBEU=iMzpE_P0KePL4cZZktBOGHRXaEox5a7XcVjXDT+Dg@mail.gmail.com>
	<e03968102b92b3711808eb532685bc9e05fc3c8d.camel@gmail.com>
Message-ID: <20240213173110.00007855@Huawei.com>

On Tue, 13 Feb 2024 17:08:19 +0100
Nuno S? <noname.nuno at gmail.com> wrote:

> On Tue, 2024-02-13 at 09:27 -0600, David Lechner wrote:
> > On Tue, Feb 13, 2024 at 3:47?AM Nuno S? <noname.nuno at gmail.com> wrote:  
> > > 
> > > On Mon, 2024-02-12 at 17:26 -0600, David Lechner wrote:  
> > > > This modifies the ad7380 ADC driver to use spi_optimize_message() to
> > > > optimize the SPI message for the buffered read operation. Since buffered
> > > > reads reuse the same SPI message for each read, this can improve
> > > > performance by reducing the overhead of setting up some parts the SPI
> > > > message in each spi_sync() call.
> > > > 
> > > > Signed-off-by: David Lechner <dlechner at baylibre.com>
> > > > ---
> > > > ?drivers/iio/adc/ad7380.c | 52 +++++++++++++++++++++++++++++++++++++++++--
> > > > ----
> > > > -
> > > > ?1 file changed, 45 insertions(+), 7 deletions(-)
> > > > 
> > > > diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
> > > > index abd746aef868..5c5d2642a474 100644
> > > > --- a/drivers/iio/adc/ad7380.c
> > > > +++ b/drivers/iio/adc/ad7380.c
> > > > @@ -133,6 +133,7 @@ struct ad7380_state {
> > > > ????? struct spi_device *spi;
> > > > ????? struct regulator *vref;
> > > > ????? struct regmap *regmap;
> > > > +???? struct spi_message *msg;
> > > > ????? /*
> > > > ?????? * DMA (thus cache coherency maintenance) requires the
> > > > ?????? * transfer buffers to live in their own cache lines.
> > > > @@ -231,19 +232,55 @@ static int ad7380_debugfs_reg_access(struct iio_dev
> > > > *indio_dev, u32 reg,
> > > > ????? return ret;
> > > > ?}
> > > > 
> > > > +static int ad7380_buffer_preenable(struct iio_dev *indio_dev)
> > > > +{
> > > > +???? struct ad7380_state *st = iio_priv(indio_dev);
> > > > +???? struct spi_transfer *xfer;
> > > > +???? int ret;
> > > > +
> > > > +???? st->msg = spi_message_alloc(1, GFP_KERNEL);
> > > > +???? if (!st->msg)
> > > > +???????????? return -ENOMEM;
> > > > +
> > > > +???? xfer = list_first_entry(&st->msg->transfers, struct spi_transfer,
> > > > +???????????????????????????? transfer_list);
> > > > +
> > > > +???? xfer->bits_per_word = st->chip_info->channels[0].scan_type.realbits;
> > > > +???? xfer->len = 4;
> > > > +???? xfer->rx_buf = st->scan_data.raw;
> > > > +
> > > > +???? ret = spi_optimize_message(st->spi, st->msg);
> > > > +???? if (ret) {
> > > > +???????????? spi_message_free(st->msg);
> > > > +???????????? return ret;
> > > > +???? }
> > > > +
> > > > +???? return 0;
> > > > +}
> > > > +
> > > > +static int ad7380_buffer_postdisable(struct iio_dev *indio_dev)
> > > > +{
> > > > +???? struct ad7380_state *st = iio_priv(indio_dev);
> > > > +
> > > > +???? spi_unoptimize_message(st->msg);
> > > > +???? spi_message_free(st->msg);
> > > > +
> > > > +???? return 0;
> > > > +}
> > > > +  
> > > 
> > > Not such a big deal but unless I'm missing something we could have the
> > > spi_message (+ the transfer) statically allocated in struct ad7380_state and
> > > do
> > > the optimize only once at probe (naturally with proper devm action for
> > > unoptimize). Then we would not need to this for every buffer enable +
> > > disable. I
> > > know in terms of performance it won't matter but it would be less code I
> > > guess.
> > > 
> > > Am I missing something?  
> > 
> > No, your understanding is correct for the current state of everything
> > in this series. So, we could do as you suggest, but I have a feeling
> > that future additions to this driver might require that it gets
> > changed back this way eventually.  
> 
> Hmm, not really sure about that as chip_info stuff is always our friend :). And
> I'm anyways of the opinion of keeping things simpler and start to evolve when
> really needed (because often we never really need to evolve). But bah, as I
> said... this is really not a big deal.
> 
Oops should have read Nuno's review before replying!

I'd rather we embedded it for now and did the optimization at probe.
Whilst it's a lot of work per transfer it's not enough to worry about delaying
it until preenable().  Easy to make that move and take it dynamic when
driver changes need it.  In meantime, I don't want lots of other drivers
picking up this pattern when they may never need the complexity of
making things more dynamic.

Jonathan

> - Nuno S?
> 



From Jonathan.Cameron at Huawei.com  Tue Feb 13 09:35:45 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Tue, 13 Feb 2024 17:35:45 +0000
Subject: [PATCH 2/5] spi: move splitting transfers to
 spi_optimize_message()
In-Reply-To: <20240212-mainline-spi-precook-message-v1-2-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
	<20240212-mainline-spi-precook-message-v1-2-a2373cd72d36@baylibre.com>
Message-ID: <20240213173545.00006564@Huawei.com>

On Mon, 12 Feb 2024 17:26:42 -0600
David Lechner <dlechner at baylibre.com> wrote:

> Splitting transfers is an expensive operation so we can potentially
> optimize it by doing it only once per optimization of the message
> instead of repeating each time the message is transferred.
> 
> The transfer splitting functions are currently the only user of
> spi_res_alloc() so spi_res_release() can be safely moved at this time
> from spi_finalize_current_message() to spi_unoptimize_message().
> 
> The doc comments of the public functions for splitting transfers are
> also updated so that callers will know when it is safe to call them
> to ensure proper resource management.
> 
> Signed-off-by: David Lechner <dlechner at baylibre.com>
> ---
Trivial thing (which applies equally to the original code).
Otherwise LGTM.
FWIW
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

> +/**
> + * spi_split_transfers - generic handling of transfer splitting
> + * @msg: the message to split
> + *
> + * Under certain conditions, a SPI controller may not support arbitrary
> + * transfer sizes or other features required by a peripheral. This function
> + * will split the transfers in the message into smaller transfers that are
> + * supported by the controller.
> + *
> + * Controllers with special requirements not covered here can also split
> + * transfers in the optimize_message() callback.
> + *
> + * Context: can sleep
> + * Return: zero on success, else a negative error code
> + */
> +static int spi_split_transfers(struct spi_message *msg)
> +{
> +	struct spi_controller *ctlr = msg->spi->controller;
> +	struct spi_transfer *xfer;
> +	int ret;
> +
> +	/*
> +	 * If an SPI controller does not support toggling the CS line on each
> +	 * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO
> +	 * for the CS line, we can emulate the CS-per-word hardware function by
> +	 * splitting transfers into one-word transfers and ensuring that
> +	 * cs_change is set for each transfer.
> +	 */
> +	if ((msg->spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
> +					       spi_is_csgpiod(msg->spi))) {
	if ((msg->spi->mode & SPI_CS_WORD) &&
	    (!(ctlr->mode_bits & SPI_CS_WORD) || spi_is_csgpiod(msg->spi))) {

Seems easier to read to me. I appreciate you are just moving it though so
don't mind that much if you leave it in the original form.



> +		ret = spi_split_transfers_maxwords(ctlr, msg, 1);
> +		if (ret)
> +			return ret;
> +
> +		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
> +			/* Don't change cs_change on the last entry in the list */
> +			if (list_is_last(&xfer->transfer_list, &msg->transfers))
> +				break;
> +
> +			xfer->cs_change = 1;
> +		}
> +	} else {
> +		ret = spi_split_transfers_maxsize(ctlr, msg,
> +						  spi_max_transfer_size(msg->spi));
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}



From mark.rutland at arm.com  Tue Feb 13 09:44:23 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 13 Feb 2024 17:44:23 +0000
Subject: [PATCH v5 25/25] arm64/mm: Automatically fold contpte mappings
In-Reply-To: <20240202080756.1453939-26-ryan.roberts@arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-26-ryan.roberts@arm.com>
Message-ID: <Zcuqd9e359L0SVPC@FVFF77S0Q05N.cambridge.arm.com>

On Fri, Feb 02, 2024 at 08:07:56AM +0000, Ryan Roberts wrote:
> There are situations where a change to a single PTE could cause the
> contpte block in which it resides to become foldable (i.e. could be
> repainted with the contiguous bit). Such situations arise, for example,
> when user space temporarily changes protections, via mprotect, for
> individual pages, such can be the case for certain garbage collectors.
> 
> We would like to detect when such a PTE change occurs. However this can
> be expensive due to the amount of checking required. Therefore only
> perform the checks when an indiviual PTE is modified via mprotect
> (ptep_modify_prot_commit() -> set_pte_at() -> set_ptes(nr=1)) and only
> when we are setting the final PTE in a contpte-aligned block.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>  arch/arm64/include/asm/pgtable.h | 26 +++++++++++++
>  arch/arm64/mm/contpte.c          | 64 ++++++++++++++++++++++++++++++++
>  2 files changed, 90 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index cdc310880a3b..d3357fe4eb89 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -1192,6 +1192,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
>   * where it is possible and makes sense to do so. The PTE_CONT bit is considered
>   * a private implementation detail of the public ptep API (see below).
>   */
> +extern void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, pte_t pte);
>  extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>  				pte_t *ptep, pte_t pte);
>  extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
> @@ -1213,6 +1215,29 @@ extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep,
>  				pte_t entry, int dirty);
>  
> +static __always_inline void contpte_try_fold(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep, pte_t pte)
> +{
> +	/*
> +	 * Only bother trying if both the virtual and physical addresses are
> +	 * aligned and correspond to the last entry in a contig range. The core
> +	 * code mostly modifies ranges from low to high, so this is the likely
> +	 * the last modification in the contig range, so a good time to fold.
> +	 * We can't fold special mappings, because there is no associated folio.
> +	 */
> +
> +	const unsigned long contmask = CONT_PTES - 1;
> +	bool valign = ((addr >> PAGE_SHIFT) & contmask) == contmask;
> +
> +	if (unlikely(valign)) {
> +		bool palign = (pte_pfn(pte) & contmask) == contmask;
> +
> +		if (unlikely(palign &&
> +		    pte_valid(pte) && !pte_cont(pte) && !pte_special(pte)))
> +			__contpte_try_fold(mm, addr, ptep, pte);
> +	}
> +}
> +
>  static __always_inline void contpte_try_unfold(struct mm_struct *mm,
>  				unsigned long addr, pte_t *ptep, pte_t pte)
>  {
> @@ -1287,6 +1312,7 @@ static __always_inline void set_ptes(struct mm_struct *mm, unsigned long addr,
>  	if (likely(nr == 1)) {
>  		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>  		__set_ptes(mm, addr, ptep, pte, 1);
> +		contpte_try_fold(mm, addr, ptep, pte);
>  	} else {
>  		contpte_set_ptes(mm, addr, ptep, pte, nr);
>  	}
> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
> index 80346108450b..2c7dafd0552a 100644
> --- a/arch/arm64/mm/contpte.c
> +++ b/arch/arm64/mm/contpte.c
> @@ -67,6 +67,70 @@ static void contpte_convert(struct mm_struct *mm, unsigned long addr,
>  	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
>  }
>  
> +void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
> +			pte_t *ptep, pte_t pte)
> +{
> +	/*
> +	 * We have already checked that the virtual and pysical addresses are
> +	 * correctly aligned for a contpte mapping in contpte_try_fold() so the
> +	 * remaining checks are to ensure that the contpte range is fully
> +	 * covered by a single folio, and ensure that all the ptes are valid
> +	 * with contiguous PFNs and matching prots. We ignore the state of the
> +	 * access and dirty bits for the purpose of deciding if its a contiguous
> +	 * range; the folding process will generate a single contpte entry which
> +	 * has a single access and dirty bit. Those 2 bits are the logical OR of
> +	 * their respective bits in the constituent pte entries. In order to
> +	 * ensure the contpte range is covered by a single folio, we must
> +	 * recover the folio from the pfn, but special mappings don't have a
> +	 * folio backing them. Fortunately contpte_try_fold() already checked
> +	 * that the pte is not special - we never try to fold special mappings.
> +	 * Note we can't use vm_normal_page() for this since we don't have the
> +	 * vma.
> +	 */
> +
> +	unsigned long folio_saddr, folio_eaddr;
> +	unsigned long cont_saddr, cont_eaddr;
> +	pte_t expected_pte, subpte;
> +	struct folio *folio;
> +	struct page *page;
> +	unsigned long pfn;
> +	pte_t *orig_ptep;
> +	pgprot_t prot;
> +
> +	int i;
> +
> +	if (!mm_is_user(mm))
> +		return;
> +
> +	page = pte_page(pte);
> +	folio = page_folio(page);
> +	folio_saddr = addr - (page - &folio->page) * PAGE_SIZE;
> +	folio_eaddr = folio_saddr + folio_nr_pages(folio) * PAGE_SIZE;
> +	cont_saddr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> +	cont_eaddr = cont_saddr + CONT_PTE_SIZE;

I assume that the 's' in *_sddar is for "start", and the 'e' in *_eaddr is for
"end". Could we use "start" and "end" directly, e.g. folio_start, folio_end?

> +
> +	if (folio_saddr > cont_saddr || folio_eaddr < cont_eaddr)
> +		return;
> +
> +	pfn = pte_pfn(pte) - ((addr - cont_saddr) >> PAGE_SHIFT);

IIUC this should be the same as:

	pfn = ALIGN_DOWN(pte_pfn(pte), NR_CONT_PTES);

... which would align with the way we generate 'cont_saddr' above.

Otherwise, this looks good to me.

Mark.

> +	prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
> +	expected_pte = pfn_pte(pfn, prot);
> +	orig_ptep = ptep;
> +	ptep = contpte_align_down(ptep);
> +
> +	for (i = 0; i < CONT_PTES; i++) {
> +		subpte = pte_mkold(pte_mkclean(__ptep_get(ptep)));
> +		if (!pte_same(subpte, expected_pte))
> +			return;
> +		expected_pte = pte_advance_pfn(expected_pte, 1);
> +		ptep++;
> +	}
> +
> +	pte = pte_mkcont(pte);
> +	contpte_convert(mm, addr, orig_ptep, pte);
> +}
> +EXPORT_SYMBOL(__contpte_try_fold);
> +
>  void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>  			pte_t *ptep, pte_t pte)
>  {
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Tue Feb 13 09:48:30 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 13 Feb 2024 17:48:30 +0000
Subject: [PATCH] arm64: allow post-init vmalloc PXNTable
In-Reply-To: <CAP5Mv+ydhk=Ob4b40ZahGMgT-5+-VEHxtmA=-LkJiEOOU+K6hw@mail.gmail.com>
References: <CAP5Mv+ydhk=Ob4b40ZahGMgT-5+-VEHxtmA=-LkJiEOOU+K6hw@mail.gmail.com>
Message-ID: <ZcurbvkUR-BoGTxu@FVFF77S0Q05N.cambridge.arm.com>

On Tue, Feb 13, 2024 at 10:05:45AM -0600, Maxwell Bland wrote:
> Apologies if this is a duplicate mail, it will be the last one. Moto's SMTP
> server sucks!!
> 
> Ensures that PXNTable can be set on all table descriptors allocated
> through vmalloc. Normally, PXNTable is set only during initial memory
> mapping and does not apply thereafter, making it possible for attackers
> to target post-init allocated writable PTEs as a staging region for
> injection of their code into the kernel. Presently it is not possible to
> efficiently prevent these attacks as VMALLOC_END overlaps with _text,
> e.g.:
> 
> VMALLOC_START ffff800080000000 VMALLOC_END fffffbfff0000000
> _text         ffffb6c0c1400000 _end        ffffb6c0c3e40000
> 
> Setting VMALLOC_END to _text in init would resolve this issue with the
> caveat of a sizeable reduction in the size of available vmalloc memory
> due to requirements on aslr randomness. However, there are circumstances
> where this trade-off is necessary: in particular, hypervisor-level
> security monitors where 1) the microarchitecture contains race
> conditions on PTE level updates or 2) a per-PTE update verifier comes at
> a significant hit to performance.

Which "hypervisor-level security monitors" are you referring to? We don't
support any of those upstream AFAIK.

How much VA space are you potentially throwing away?

How does this work with other allocations of executable memory? e.g. modules,
BPF?

I'm not keen on this as-is.

Mark.

> Because the address of _text is aslr-sensitive and this patch associates
> this value with VMALLOC_END, we remove the use of VMALLOC_END in a print
> statement in mm/percpu.c. However, only the format string is updated in
> crash_core.c, since we are dead at that point regardless. VMALLOC_END is
> updated in kernel/setup.c to associate the feature closely with aslr and
> region allocation code.
> 
> Signed-off-by: Maxwell Bland <mbland at motorola.com>
> ---
>  arch/arm64/Kconfig                   | 13 +++++++++++++
>  arch/arm64/include/asm/pgtable.h     |  6 ++++++
>  arch/arm64/include/asm/vmalloc-pxn.h | 10 ++++++++++
>  arch/arm64/kernel/crash_core.c       |  2 +-
>  arch/arm64/kernel/setup.c            |  9 +++++++++
>  mm/percpu.c                          |  4 ++--
>  6 files changed, 41 insertions(+), 3 deletions(-)
>  create mode 100644 arch/arm64/include/asm/vmalloc-pxn.h
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index aa7c1d435139..5f1e75d70e14 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -2165,6 +2165,19 @@ config ARM64_DEBUG_PRIORITY_MASKING
>     If unsure, say N
>  endif # ARM64_PSEUDO_NMI
> 
> +config ARM64_VMALLOC_PXN
> + bool "Ensures table descriptors pointing to kernel data are PXNTable"
> + help
> +   Reduces the range of the kernel data vmalloc region to remove any
> +   overlap with kernel code, making it possible to enable the PXNTable
> +   bit on table descriptors allocated after the kernel's initial memory
> +   mapping.
> +
> +   This increases the performance of security monitors which protect
> +   against malicious updates to page table entries.
> +
> +   If unsure, say N.
> +
>  config RELOCATABLE
>   bool "Build a relocatable kernel image" if EXPERT
>   select ARCH_HAS_RELR
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 79ce70fbb751..49f64ea77c81 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -22,7 +22,9 @@
>   * and fixed mappings
>   */
>  #define VMALLOC_START (MODULES_END)
> +#ifndef CONFIG_ARM64_VMALLOC_PXN
>  #define VMALLOC_END (VMEMMAP_START - SZ_256M)
> +#endif
> 
>  #define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
> 
> @@ -35,6 +37,10 @@
>  #include <linux/sched.h>
>  #include <linux/page_table_check.h>
> 
> +#ifdef CONFIG_ARM64_VMALLOC_PXN
> +#include <asm/vmalloc-pxn.h>
> +#endif
> +
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
> 
> diff --git a/arch/arm64/include/asm/vmalloc-pxn.h
> b/arch/arm64/include/asm/vmalloc-pxn.h
> new file mode 100644
> index 000000000000..c8c4f878eb62
> --- /dev/null
> +++ b/arch/arm64/include/asm/vmalloc-pxn.h
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_ARM64_VMALLOC_PXN_H
> +#define _ASM_ARM64_VMALLOC_PXN_H
> +
> +#ifdef CONFIG_ARM64_VMALLOC_PXN
> +extern u64 __vmalloc_end __ro_after_init;
> +#define VMALLOC_END (__vmalloc_end)
> +#endif /* CONFIG_ARM64_VMALLOC_PXN */
> +
> +#endif /* _ASM_ARM64_VMALLOC_PXN_H */
> diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/crash_core.c
> index 66cde752cd74..39dccae11a40 100644
> --- a/arch/arm64/kernel/crash_core.c
> +++ b/arch/arm64/kernel/crash_core.c
> @@ -24,7 +24,7 @@ void arch_crash_save_vmcoreinfo(void)
>   vmcoreinfo_append_str("NUMBER(MODULES_VADDR)=0x%lx\n", MODULES_VADDR);
>   vmcoreinfo_append_str("NUMBER(MODULES_END)=0x%lx\n", MODULES_END);
>   vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", VMALLOC_START);
> - vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%lx\n", VMALLOC_END);
> + vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%llx\n", VMALLOC_END);
>   vmcoreinfo_append_str("NUMBER(VMEMMAP_START)=0x%lx\n", VMEMMAP_START);
>   vmcoreinfo_append_str("NUMBER(VMEMMAP_END)=0x%lx\n", VMEMMAP_END);
>   vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 42c690bb2d60..b7ccee672743 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -54,6 +54,11 @@
>  #include <asm/xen/hypervisor.h>
>  #include <asm/mmu_context.h>
> 
> +#ifdef CONFIG_ARM64_VMALLOC_PXN
> +u64 __vmalloc_end __ro_after_init = VMEMMAP_START - SZ_256M;
> +EXPORT_SYMBOL(__vmalloc_end);
> +#endif /* CONFIG_ARM64_VMALLOC_PXN */
> +
>  static int num_standard_resources;
>  static struct resource *standard_resources;
> 
> @@ -298,6 +303,10 @@ void __init __no_sanitize_address setup_arch(char
> **cmdline_p)
> 
>   kaslr_init();
> 
> +#ifdef CONFIG_ARM64_VMALLOC_PXN
> + __vmalloc_end = ALIGN_DOWN((u64) _text, PMD_SIZE);
> +#endif
> +
>   /*
>   * If know now we are going to need KPTI then use non-global
>   * mappings from the start, avoiding the cost of rewriting
> diff --git a/mm/percpu.c b/mm/percpu.c
> index 4e11fc1e6def..a902500ebfa0 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -3128,8 +3128,8 @@ int __init pcpu_embed_first_chunk(size_t
> reserved_size, size_t dyn_size,
> 
>   /* warn if maximum distance is further than 75% of vmalloc space */
>   if (max_distance > VMALLOC_TOTAL * 3 / 4) {
> - pr_warn("max_distance=0x%lx too large for vmalloc space 0x%lx\n",
> - max_distance, VMALLOC_TOTAL);
> + pr_warn("max_distance=0x%lx too large for vmalloc space\n",
> + max_distance);
>  #ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
>   /* and fail if we have fallback */
>   rc = -EINVAL;
> 
> base-commit: 716f4aaa7b48a55c73d632d0657b35342b1fefd7
> -- 
> 2.39.0


From u.kleine-koenig at pengutronix.de  Tue Feb 13 09:48:48 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Tue, 13 Feb 2024 18:48:48 +0100
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible
 for MT7988
In-Reply-To: <20240213164633.25447-1-zajec5@gmail.com>
References: <20240213164633.25447-1-zajec5@gmail.com>
Message-ID: <onnokyq7ciza7i7jzc74cun2khpst5iocuccks2cm433ux3za3@dou4oacrvuxj>

Hello Rafa?,

On Tue, Feb 13, 2024 at 05:46:32PM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7988 has on-SoC controller that can control up to 8 PWMs.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

please make sure that the email address used for sending the patch
matches the Signed-off-by line.

(It depends on the pickyness of the relevant maintainer if that is a
stopper or not.)

Assuming this patch will go in via a mediatek tree:

Acked-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Thanks
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/20240213/acf9e7c6/attachment.sig>

From broonie at kernel.org  Tue Feb 13 09:49:48 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 17:49:48 +0000
Subject: [PATCH v2 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <20240213170657.puwlx5pjl3odcs2k@runtux.com>
References: <20240202115330.wxkbfmvd76sy3a6a@runtux.com>
 <20240213170657.puwlx5pjl3odcs2k@runtux.com>
Message-ID: <ce80f238-1a56-4254-ac1d-5a9249c40b66@sirena.org.uk>

On Tue, Feb 13, 2024 at 06:06:57PM +0100, Ralf Schlatterbeck wrote:
> On Fri, Feb 02, 2024 at 12:53:30PM +0100, Ralf Schlatterbeck wrote:

> > -- 
> > Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
> > Open Source Consulting                  www:   www.runtux.com
> > Reichergasse 131, A-3411 Weidling       email: office at runtux.com

> Any news on this, will it be picked up for the next merge window?

Please don't send content free pings and please allow a reasonable time
for review.  People get busy, go on holiday, attend conferences and so 
on so unless there is some reason for urgency (like critical bug fixes)
please allow at least a couple of weeks for review.  If there have been
review comments then people may be waiting for those to be addressed.

Sending content free pings adds to the mail volume (if they are seen at
all) which is often the problem and since they can't be reviewed
directly if something has gone wrong you'll have to resend the patches
anyway, so sending again is generally a better approach though there are
some other maintainers who like them - if in doubt look at how patches
for the subsystem are normally handled.
-------------- 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/20240213/8105c087/attachment.sig>

From jgg at nvidia.com  Tue Feb 13 09:50:42 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 13 Feb 2024 13:50:42 -0400
Subject: [PATCH v5 09/17] iommu/arm-smmu-v3: Put writing the context
 descriptor in the right order
In-Reply-To: <ZcuN_YZBzxJ2wvAg@google.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <9-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZcuN_YZBzxJ2wvAg@google.com>
Message-ID: <20240213175042.GF1088888@nvidia.com>

On Tue, Feb 13, 2024 at 03:42:53PM +0000, Mostafa Saleh wrote:
> > @@ -2659,6 +2651,17 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
> >  				master->domain = NULL;
> >  				goto out_list_del;
> >  			}
> > +		} else {
> > +			/*
> > +			 * arm_smmu_write_ctx_desc() relies on the entry being
> > +			 * invalid to work, clear any existing entry.
> > +			 */
> > +			ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
> > +						      NULL);
> > +			if (ret) {
> > +				master->domain = NULL;
> > +				goto out_list_del;
> > +			}
> 
> Instead of having duplicate
>            if (ret) {
>                master->domain = NULL;
>                goto out_list_del;
>            }
> 
> In the if and the else, we can just move it outside.

Stylistically I often try to avoid shifting the error path from its
statement, but it is OK either way..

However, part 2 removes the need for error handling here entirely, so
let's leave it.

> > @@ -2668,15 +2671,23 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
> >  		}
> >  
> >  		arm_smmu_make_cdtable_ste(&target, master);
> > +		arm_smmu_install_ste_for_dev(master, &target);
> >  		break;
> >  	case ARM_SMMU_DOMAIN_S2:
> >  		arm_smmu_make_s2_domain_ste(&target, master, smmu_domain);
> > +		arm_smmu_install_ste_for_dev(master, &target);
> > +		if (master->cd_table.cdtab)
> > +			arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
> > +						      NULL);
> >  		break;
> >  	case ARM_SMMU_DOMAIN_BYPASS:
> >  		arm_smmu_make_bypass_ste(&target);
> > +		arm_smmu_install_ste_for_dev(master, &target);
> > +		if (master->cd_table.cdtab)
> > +			arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
> > +						      NULL);
> >  		break;
> >  	}
> This invalidates the CD while the STE is in bypass/S2 which is a new behavior
> to the driver, 

Yes

> I don?t see anything from the user manual about this, so I
> believe that is fine.

Nor do I. Nor can I see any reason why HW would care. We also
invalidate ASID's and VMID's after their tables have been removed from
the STE/CD too.

There are other options here if this is found out to be a trouble but
they are convoluted enough to not do them without a concrete reason.

Thanks,
Jason


From robh+dt at kernel.org  Tue Feb 13 09:52:00 2024
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 17:52:00 +0000
Subject: [PATCH v3 7/7] of: Add KUnit test to confirm DTB is loaded
In-Reply-To: <2185a3cc3152a0b9a94b0c64353bc9a1.sboyd@kernel.org>
References: <20240202195909.3458162-1-sboyd@kernel.org> <20240202195909.3458162-8-sboyd@kernel.org>
 <CABVgOS=A8BQ6HHpBKFqg-N10ckk2XYavaS-MPXvZ0wenrVm=1g@mail.gmail.com>
 <89892ecd6b1b043db58258705c32b02b.sboyd@kernel.org> <CAMuHMdUuP5Ya2gU3V_ET=Ji_+yx+jr7eCch5uDJSqvQN9jJM3g@mail.gmail.com>
 <2185a3cc3152a0b9a94b0c64353bc9a1.sboyd@kernel.org>
Message-ID: <CAL_JsqLrRXdPZ+u9XG960V7sXECBi5Ko7BYdreftYz-O=Hwieg@mail.gmail.com>

On Fri, Feb 9, 2024 at 8:59?PM Stephen Boyd <sboyd at kernel.org> wrote:
>
> Quoting Geert Uytterhoeven (2024-02-05 11:55:29)
> > On Mon, Feb 5, 2024 at 8:19?PM Stephen Boyd <sboyd at kernel.org> wrote:
> > > Quoting David Gow (2024-02-02 20:10:17)
> > > > On Sat, 3 Feb 2024 at 03:59, Stephen Boyd <sboyd at kernel.org> wrote:
> > > > > Add a KUnit test that confirms a DTB has been loaded, i.e. there is a
> > > > > root node, and that the of_have_populated_dt() API works properly.
> > > > >
> > > > > Cc: Rob Herring <robh+dt at kernel.org>
> > > > > Cc: Frank Rowand <frowand.list at gmail.com>
> > > > > Cc: David Gow <davidgow at google.com>
> > > > > Cc: Brendan Higgins <brendan.higgins at linux.dev>
> > > > > Signed-off-by: Stephen Boyd <sboyd at kernel.org>
> > > > > ---
> > > >
> > > > This looks pretty good to me test-wise, though it still fails on m68k.
> > > > (Everything else I tried it on works, though I've definitely not tried
> > > > _every_ architecture.)
> > > >
> > > > aarch64: PASSED
> > > > i386: PASSED
> > > > x86_64: PASSED
> > > > x86_64 KASAN: PASSED
> > > > powerpc64: PASSED
> > > > UML: PASSED
> > > > UML LLVM: PASSED
> > > > m68k: FAILED
> > > > > $ qemu-system-m68k -nodefaults -m 1024 -kernel .kunit-all-m68k/vmlinux -append 'kunit.enable=1 console=hvc0 kunit_shutdown=reboot' -no-reboot -nographic -serial stdio -machine virt
> > > > > [11:55:05] ===================== dtb (2 subtests) =====================
> > > > > [11:55:05] # dtb_root_node_found_by_path: EXPECTATION FAILED at drivers/of/of_test.c:18
> > > > > [11:55:05] Expected np is not null, but is
> > > > > [11:55:05] [FAILED] dtb_root_node_found_by_path
> > > > > [11:55:05] # dtb_root_node_populates_of_root: EXPECTATION FAILED at drivers/of/of_test.c:28
> > > > > [11:55:05] Expected of_root is not null, but is
> > > > > [11:55:05] [FAILED] dtb_root_node_populates_of_root
> > > > > [11:55:05]     # module: of_test
> > > > > [11:55:05] # dtb: pass:0 fail:2 skip:0 total:2
> > > > > [11:55:05] # Totals: pass:0 fail:2 skip:0 total:2
> > > > > [11:55:05] ======================= [FAILED] dtb =======================
> > >
> > > Ah yeah I forgot to mention that. m68k fails because it doesn't call the
> > > unflatten_(and_copy)?_device_tree() function, so we don't populate a
> > > root node on that architecture. One solution would be to make CONFIG_OF
> > > unavailable on m68k. Or we have to make sure DT works on any
> > > architecture. Rob, what do you prefer here?
> >
> > I guess the latter?
> > Alpha, hexagon, parisc, s390, and sparc are also lacking calls
> > to unflatten.*device_tree().
> >
>
> sparc does that on purpose. Perhaps it's simplest to call
> unflatten_device_tree() if of_root is still NULL after setup_arch()
> returns.
>
> ---8<---
> diff --git a/init/main.c b/init/main.c
> index e24b0780fdff..02f5cf8be6c1 100644
> --- a/init/main.c
> +++ b/init/main.c
> @@ -97,6 +97,8 @@
>  #include <linux/jump_label.h>
>  #include <linux/kcsan.h>
>  #include <linux/init_syscalls.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
>  #include <linux/stackdepot.h>
>  #include <linux/randomize_kstack.h>
>  #include <net/net_namespace.h>
> @@ -895,6 +897,8 @@ void start_kernel(void)
>         pr_notice("%s", linux_banner);
>         early_security_init();
>         setup_arch(&command_line);
> +       if (!of_root)

of_root is another thing I'd like to remove direct access to. That
check could be inside unflatten_device_tree().

> +               unflatten_device_tree();

That's back to what Frank had essentially and I wanted to avoid.

I think I'd just disable the tests on the above arches and let them
opt-in. I could be convinced otherwise though.

Rob


From gregkh at linuxfoundation.org  Tue Feb 13 09:30:29 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Tue, 13 Feb 2024 18:30:29 +0100
Subject: [External] Re: [PATCH] arm64: allow post-init vmalloc PXNTable
In-Reply-To: <SEZPR03MB6786975721BC2C6393731C59B44F2@SEZPR03MB6786.apcprd03.prod.outlook.com>
References: <CAP5Mv+ydhk=Ob4b40ZahGMgT-5+-VEHxtmA=-LkJiEOOU+K6hw@mail.gmail.com>
 <2024021300-gently-ether-3978@gregkh>
 <SEZPR03MB6786975721BC2C6393731C59B44F2@SEZPR03MB6786.apcprd03.prod.outlook.com>
Message-ID: <2024021321-scooter-citrus-233c@gregkh>

On Tue, Feb 13, 2024 at 05:16:04PM +0000, Maxwell Bland wrote:
> > This shouldn't be in the changelog, it needs to go below the --- line.
> 
> Oh! Thanks!!!
> 
> > Also, your patch is corrupted and can not be applied :(
> 
> Shoot! Apologies, I just noticed the hard-wrap at 80. I am talking to Moto's IT right now, I will resend patch once I can fix the mail server config.

tabs were also eaten :(


From tanmay.shah at amd.com  Tue Feb 13 09:54:47 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Tue, 13 Feb 2024 09:54:47 -0800
Subject: [PATCH v10 1/4] remoteproc: zynqmp: fix lockstep mode memory region
In-Reply-To: <20240213175450.3097308-1-tanmay.shah@amd.com>
References: <20240213175450.3097308-1-tanmay.shah@amd.com>
Message-ID: <20240213175450.3097308-2-tanmay.shah@amd.com>

In lockstep mode, r5 core0 uses TCM of R5 core1. Following is lockstep
mode memory region as per hardware reference manual.

    |      *TCM*         |   *R5 View* | *Linux view* |
    | R5_0 ATCM (128 KB) | 0x0000_0000 | 0xFFE0_0000  |
    | R5_0 BTCM (128 KB) | 0x0002_0000 | 0xFFE2_0000  |

However, driver shouldn't model it as above because R5 core0 TCM and core1
TCM has different power-domains mapped to it.
Hence, TCM address space in lockstep mode should be modeled as 64KB
regions only where each region has its own power-domain as following:

    |      *TCM*         |   *R5 View* | *Linux view* |
    | R5_0 ATCM0 (64 KB) | 0x0000_0000 | 0xFFE0_0000  |
    | R5_0 BTCM0 (64 KB) | 0x0002_0000 | 0xFFE2_0000  |
    | R5_0 ATCM1 (64 KB) | 0x0001_0000 | 0xFFE1_0000  |
    | R5_0 BTCM1 (64 KB) | 0x0003_0000 | 0xFFE3_0000  |

This makes driver maintanance easy and makes design robust for future
platorms as well.

Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---
 drivers/remoteproc/xlnx_r5_remoteproc.c | 145 ++----------------------
 1 file changed, 12 insertions(+), 133 deletions(-)

diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index 4395edea9a64..42b0384d34f2 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -84,12 +84,12 @@ static const struct mem_bank_data zynqmp_tcm_banks_split[] = {
 	{0xffeb0000UL, 0x20000, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
 };
 
-/* In lockstep mode cluster combines each 64KB TCM and makes 128KB TCM */
+/* In lockstep mode cluster uses each 64KB TCM from second core as well */
 static const struct mem_bank_data zynqmp_tcm_banks_lockstep[] = {
-	{0xffe00000UL, 0x0, 0x20000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 128KB each */
-	{0xffe20000UL, 0x20000, 0x20000UL, PD_R5_0_BTCM, "btcm0"},
-	{0, 0, 0, PD_R5_1_ATCM, ""},
-	{0, 0, 0, PD_R5_1_BTCM, ""},
+	{0xffe00000UL, 0x0, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
+	{0xffe20000UL, 0x20000, 0x10000UL, PD_R5_0_BTCM, "btcm0"},
+	{0xffe10000UL, 0x10000, 0x10000UL, PD_R5_1_ATCM, "atcm1"},
+	{0xffe30000UL, 0x30000, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
 };
 
 /**
@@ -540,14 +540,14 @@ static int tcm_mem_map(struct rproc *rproc,
 }
 
 /*
- * add_tcm_carveout_split_mode()
+ * add_tcm_banks()
  * @rproc: single R5 core's corresponding rproc instance
  *
- * allocate and add remoteproc carveout for TCM memory in split mode
+ * allocate and add remoteproc carveout for TCM memory
  *
  * return 0 on success, otherwise non-zero value on failure
  */
-static int add_tcm_carveout_split_mode(struct rproc *rproc)
+static int add_tcm_banks(struct rproc *rproc)
 {
 	struct rproc_mem_entry *rproc_mem;
 	struct zynqmp_r5_core *r5_core;
@@ -580,10 +580,10 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 					     ZYNQMP_PM_REQUEST_ACK_BLOCKING);
 		if (ret < 0) {
 			dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
-			goto release_tcm_split;
+			goto release_tcm;
 		}
 
-		dev_dbg(dev, "TCM carveout split mode %s addr=%llx, da=0x%x, size=0x%lx",
+		dev_dbg(dev, "TCM carveout %s addr=%llx, da=0x%x, size=0x%lx",
 			bank_name, bank_addr, da, bank_size);
 
 		rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
@@ -593,7 +593,7 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 		if (!rproc_mem) {
 			ret = -ENOMEM;
 			zynqmp_pm_release_node(pm_domain_id);
-			goto release_tcm_split;
+			goto release_tcm;
 		}
 
 		rproc_add_carveout(rproc, rproc_mem);
@@ -601,7 +601,7 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 
 	return 0;
 
-release_tcm_split:
+release_tcm:
 	/* If failed, Turn off all TCM banks turned on before */
 	for (i--; i >= 0; i--) {
 		pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
@@ -610,127 +610,6 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 	return ret;
 }
 
-/*
- * add_tcm_carveout_lockstep_mode()
- * @rproc: single R5 core's corresponding rproc instance
- *
- * allocate and add remoteproc carveout for TCM memory in lockstep mode
- *
- * return 0 on success, otherwise non-zero value on failure
- */
-static int add_tcm_carveout_lockstep_mode(struct rproc *rproc)
-{
-	struct rproc_mem_entry *rproc_mem;
-	struct zynqmp_r5_core *r5_core;
-	int i, num_banks, ret;
-	phys_addr_t bank_addr;
-	size_t bank_size = 0;
-	struct device *dev;
-	u32 pm_domain_id;
-	char *bank_name;
-	u32 da;
-
-	r5_core = rproc->priv;
-	dev = r5_core->dev;
-
-	/* Go through zynqmp banks for r5 node */
-	num_banks = r5_core->tcm_bank_count;
-
-	/*
-	 * In lockstep mode, TCM is contiguous memory block
-	 * However, each TCM block still needs to be enabled individually.
-	 * So, Enable each TCM block individually.
-	 * Although ATCM and BTCM is contiguous memory block, add two separate
-	 * carveouts for both.
-	 */
-	for (i = 0; i < num_banks; i++) {
-		pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
-
-		/* Turn on each TCM bank individually */
-		ret = zynqmp_pm_request_node(pm_domain_id,
-					     ZYNQMP_PM_CAPABILITY_ACCESS, 0,
-					     ZYNQMP_PM_REQUEST_ACK_BLOCKING);
-		if (ret < 0) {
-			dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
-			goto release_tcm_lockstep;
-		}
-
-		bank_size = r5_core->tcm_banks[i]->size;
-		if (bank_size == 0)
-			continue;
-
-		bank_addr = r5_core->tcm_banks[i]->addr;
-		da = r5_core->tcm_banks[i]->da;
-		bank_name = r5_core->tcm_banks[i]->bank_name;
-
-		/* Register TCM address range, TCM map and unmap functions */
-		rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
-						 bank_size, da,
-						 tcm_mem_map, tcm_mem_unmap,
-						 bank_name);
-		if (!rproc_mem) {
-			ret = -ENOMEM;
-			zynqmp_pm_release_node(pm_domain_id);
-			goto release_tcm_lockstep;
-		}
-
-		/* If registration is success, add carveouts */
-		rproc_add_carveout(rproc, rproc_mem);
-
-		dev_dbg(dev, "TCM carveout lockstep mode %s addr=0x%llx, da=0x%x, size=0x%lx",
-			bank_name, bank_addr, da, bank_size);
-	}
-
-	return 0;
-
-release_tcm_lockstep:
-	/* If failed, Turn off all TCM banks turned on before */
-	for (i--; i >= 0; i--) {
-		pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
-		zynqmp_pm_release_node(pm_domain_id);
-	}
-	return ret;
-}
-
-/*
- * add_tcm_banks()
- * @rproc: single R5 core's corresponding rproc instance
- *
- * allocate and add remoteproc carveouts for TCM memory based on cluster mode
- *
- * return 0 on success, otherwise non-zero value on failure
- */
-static int add_tcm_banks(struct rproc *rproc)
-{
-	struct zynqmp_r5_cluster *cluster;
-	struct zynqmp_r5_core *r5_core;
-	struct device *dev;
-
-	r5_core = rproc->priv;
-	if (!r5_core)
-		return -EINVAL;
-
-	dev = r5_core->dev;
-
-	cluster = dev_get_drvdata(dev->parent);
-	if (!cluster) {
-		dev_err(dev->parent, "Invalid driver data\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * In lockstep mode TCM banks are one contiguous memory region of 256Kb
-	 * In split mode, each TCM bank is 64Kb and not contiguous.
-	 * We add memory carveouts accordingly.
-	 */
-	if (cluster->mode == SPLIT_MODE)
-		return add_tcm_carveout_split_mode(rproc);
-	else if (cluster->mode == LOCKSTEP_MODE)
-		return add_tcm_carveout_lockstep_mode(rproc);
-
-	return -EINVAL;
-}
-
 /*
  * zynqmp_r5_parse_fw()
  * @rproc: single R5 core's corresponding rproc instance
-- 
2.25.1



From tanmay.shah at amd.com  Tue Feb 13 09:54:46 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Tue, 13 Feb 2024 09:54:46 -0800
Subject: [PATCH v10 0/4] add zynqmp TCM bindings
Message-ID: <20240213175450.3097308-1-tanmay.shah@amd.com>

Tightly-Coupled Memories(TCMs) are low-latency memory that provides
predictable instruction execution and predictable data load/store
timing. Each Cortex-R5F processor contains exclusive two 64 KB memory
banks on the ATCM and BTCM ports, for a total of 128 KB of memory.
In lockstep mode, both 128KB memory is accessible to the cluster.

As per ZynqMP Ultrascale+ Technical Reference Manual UG1085, following
is address space of TCM memory. The bindings in this patch series
introduces properties to accommodate following address space with
address translation between Linux and Cortex-R5 views.

|     |     |     |
| --- | --- | --- |
|      *Mode*        |   *R5 View* | *Linux view* |  Notes               |
| *Split Mode*       | *start addr*| *start addr* |                      |
| R5_0 ATCM (64 KB)  | 0x0000_0000 | 0xFFE0_0000  |                      |
| R5_0 BTCM (64 KB)  | 0x0002_0000 | 0xFFE2_0000  |                      |
| R5_1 ATCM (64 KB)  | 0x0000_0000 | 0xFFE9_0000  | alias of 0xFFE1_0000 |
| R5_1 BTCM (64 KB)  | 0x0002_0000 | 0xFFEB_0000  | alias of 0xFFE3_0000 |
|  ___               |     ___     |    ___       |                      |
| *Lockstep Mode*    |             |              |                      |
| R5_0 ATCM (128 KB) | 0x0000_0000 | 0xFFE0_0000  |                      |
| R5_0 BTCM (128 KB) | 0x0002_0000 | 0xFFE2_0000  |                      |

References:
UG1085 TCM address space:
https://docs.xilinx.com/r/en-US/ug1085-zynq-ultrascale-trm/Tightly-Coupled-Memory-Address-Map

Changs in v10:
  - Add new patch (1/4) to series that changes hardcode TCM addresses in
    lockstep mode and removes separate handling of TCM in lockstep and
    split mode
  - modify number of "reg", "reg-names" and "power-domains" entries
    based on cluster mode
  - Add extra optional atcm and btcm in "reg" property for lockstep mode
  - Add "reg-names" for extra optional atcm and btcm for lockstep mode
  - Drop previous Ack as bindings has new change
  - Add individual tcm regions via "reg" and "reg-names" for lockstep mode
  - Add each tcm's power-domains in lockstep mode
  - Drop previous Ack as new change in dts patchset
  - Remove redundant changes in driver to handle TCM in lockstep mode

Changes in v9:
  - Fix rproc lockstep dts
  - Introduce new API to request and release core1 TCM power-domains in
    lockstep mode. This will be used during prepare -> add_tcm_banks
    callback to enable TCM in lockstep mode.
  - Parse TCM from device-tree in lockstep mode and split mode in
    uniform way.
  - Fix TCM representation in device-tree in lockstep mode.
  - Fix comments as suggested

Changes in v8:
  - Remove use of pm_domains framework
  - Remove checking of pm_domain_id validation to power on/off tcm
  - Remove spurious change
  - parse power-domains property from device-tree and use EEMI calls
    to power on/off TCM instead of using pm domains framework

Changes in v7:
  - %s/pm_dev1/pm_dev_core0/r
  - %s/pm_dev_link1/pm_dev_core0_link/r
  - %s/pm_dev2/pm_dev_core1/r
  - %s/pm_dev_link2/pm_dev_core1_link/r
  - remove pm_domain_id check to move next patch
  - add comment about how 1st entry in pm domain list is used
  - fix loop when jump to fail_add_pm_domains loop
  - move checking of pm_domain_id from previous patch
  - fix mem_bank_data memory allocation

Changes in v6:
  - Introduce new node entry for r5f cluster split mode dts and
    keep it disabled by default.
  - Keep remoteproc lockstep mode enabled by default to maintian
    back compatibility.
  - Enable split mode only for zcu102 board to demo split mode use
  - Remove spurious change
  - Handle errors in add_pm_domains function
  - Remove redundant code to handle errors from remove_pm_domains
  - Missing . at the end of the commit message
  - remove redundant initialization of variables
  - remove fail_tcm label and relevant code to free memory
    acquired using devm_* API. As this will be freed when device free it
  - add extra check to see if "reg" property is supported or not

Changes in v5:
  - maintain Rob's Ack on bindings patch as no changes in bindings
  - split previous patch into multiple patches
  - Use pm domain framework to turn on/off TCM
  - Add support of parsing TCM information from device-tree
  - maintain backward compatibility with previous bindings without
    TCM information available in device-tree

This patch series continues previous effort to upstream ZynqMP
TCM bindings:
Previous v4 version link:
https://lore.kernel.org/all/20230829181900.2561194-1-tanmay.shah at amd.com/

Previous v3 version link:
https://lore.kernel.org/all/1689964908-22371-1-git-send-email-radhey.shyam.pandey at amd.com/
Radhey Shyam Pandey (1):
  dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings


Radhey Shyam Pandey (1):
  dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings

Tanmay Shah (3):
  remoteproc: zynqmp: fix lockstep mode memory region
  dts: zynqmp: add properties for TCM in remoteproc
  remoteproc: zynqmp: parse TCM from device tree

 .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 +++++++++++--
 .../boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts  |   8 +
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  65 ++++-
 drivers/remoteproc/xlnx_r5_remoteproc.c       | 257 ++++++++----------
 4 files changed, 357 insertions(+), 165 deletions(-)


base-commit: 929654e8f1add50b01d5a56171a31c311b0a739a
-- 
2.25.1



From tanmay.shah at amd.com  Tue Feb 13 09:54:49 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Tue, 13 Feb 2024 09:54:49 -0800
Subject: [PATCH v10 3/4] dts: zynqmp: add properties for TCM in remoteproc
In-Reply-To: <20240213175450.3097308-1-tanmay.shah@amd.com>
References: <20240213175450.3097308-1-tanmay.shah@amd.com>
Message-ID: <20240213175450.3097308-4-tanmay.shah@amd.com>

Add properties as per new bindings in zynqmp remoteproc node
to represent TCM address and size.

This patch also adds alternative remoteproc node to represent
remoteproc cluster in split mode. By default lockstep mode is
enabled and users should disable it before using split mode
dts. Both device-tree nodes can't be used simultaneously one
of them must be disabled. For zcu102-1.0 and zcu102-1.1 board
remoteproc split mode dts node is enabled and lockstep mode
dts is disabled.

Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---

Changes in v10:
  - Add individual tcm regions via "reg" and "reg-names" for lockstep mode
  - Add each tcm's power-domains in lockstep mode
  - Drop previous Ack as new change in this patchset

Changes in v9:
  - fix rproc lockstep dts


 .../boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts  |  8 +++
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 65 +++++++++++++++++--
 2 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
index c8f71a1aec89..495ca94b45db 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
@@ -14,6 +14,14 @@ / {
 	compatible = "xlnx,zynqmp-zcu102-rev1.0", "xlnx,zynqmp-zcu102", "xlnx,zynqmp";
 };
 
+&rproc_split {
+	status = "okay";
+};
+
+&rproc_lockstep {
+	status = "disabled";
+};
+
 &eeprom {
 	#address-cells = <1>;
 	#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index eaba466804bc..c8a7fd0f3a1e 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -248,19 +248,74 @@ fpga_full: fpga-full {
 		ranges;
 	};
 
-	remoteproc {
+	rproc_lockstep: remoteproc at ffe00000 {
 		compatible = "xlnx,zynqmp-r5fss";
 		xlnx,cluster-mode = <1>;
 
-		r5f-0 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+			 <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+			 <0x0 0x10000 0x0 0xffe10000 0x0 0x10000>,
+			 <0x0 0x30000 0x0 0xffe30000 0x0 0x10000>;
+
+		r5f at 0 {
+			compatible = "xlnx,zynqmp-r5f";
+			reg = <0x0 0x0 0x0 0x10000>,
+			      <0x0 0x20000 0x0 0x10000>,
+			      <0x0 0x10000 0x0 0x10000>,
+			      <0x0 0x30000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0", "atcm1", "btcm1";
+			power-domains = <&zynqmp_firmware PD_RPU_0>,
+					<&zynqmp_firmware PD_R5_0_ATCM>,
+					<&zynqmp_firmware PD_R5_0_BTCM>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
+			memory-region = <&rproc_0_fw_image>;
+		};
+
+		r5f at 1 {
+			compatible = "xlnx,zynqmp-r5f";
+			reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_1>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
+			memory-region = <&rproc_1_fw_image>;
+		};
+	};
+
+	rproc_split: remoteproc-split at ffe00000 {
+		status = "disabled";
+		compatible = "xlnx,zynqmp-r5fss";
+		xlnx,cluster-mode = <0>;
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+			 <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+			 <0x1 0x0 0x0 0xffe90000 0x0 0x10000>,
+			 <0x1 0x20000 0x0 0xffeb0000 0x0 0x10000>;
+
+		r5f at 0 {
 			compatible = "xlnx,zynqmp-r5f";
-			power-domains = <&zynqmp_firmware PD_RPU_0>;
+			reg = <0x0 0x0 0x0 0x10000>, <0x0 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_0>,
+					<&zynqmp_firmware PD_R5_0_ATCM>,
+					<&zynqmp_firmware PD_R5_0_BTCM>;
 			memory-region = <&rproc_0_fw_image>;
 		};
 
-		r5f-1 {
+		r5f at 1 {
 			compatible = "xlnx,zynqmp-r5f";
-			power-domains = <&zynqmp_firmware PD_RPU_1>;
+			reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_1>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
 			memory-region = <&rproc_1_fw_image>;
 		};
 	};
-- 
2.25.1



From tanmay.shah at amd.com  Tue Feb 13 09:54:50 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Tue, 13 Feb 2024 09:54:50 -0800
Subject: [PATCH v10 4/4] remoteproc: zynqmp: parse TCM from device tree
In-Reply-To: <20240213175450.3097308-1-tanmay.shah@amd.com>
References: <20240213175450.3097308-1-tanmay.shah@amd.com>
Message-ID: <20240213175450.3097308-5-tanmay.shah@amd.com>

ZynqMP TCM information was fixed in driver. Now ZynqMP TCM information
is available in device-tree. Parse TCM information in driver
as per new bindings.

Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---

Changes in v10:
  - Remove redundant changes to handle TCM in lockstep mode

Changes in v9:
  - Introduce new API to request and release core1 TCM power-domains in
    lockstep mode. This will be used during prepare -> add_tcm_banks
    callback to enable TCM in lockstep mode.
  - Parse TCM from device-tree in lockstep mode and split mode in
    uniform way.
  - Fix TCM representation in device-tree in lockstep mode.

Changes in v8:
  - Remove pm_domains framework
  - Remove checking of pm_domain_id validation to power on/off tcm
  - Remove spurious change
  - parse power-domains property from device-tree and use EEMI calls
    to power on/off TCM instead of using pm domains framework

Changes in v7:
  - move checking of pm_domain_id from previous patch
  - fix mem_bank_data memory allocation

 drivers/remoteproc/xlnx_r5_remoteproc.c | 112 ++++++++++++++++++++++--
 1 file changed, 107 insertions(+), 5 deletions(-)

diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index 42b0384d34f2..49e8eaf83fce 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -74,8 +74,8 @@ struct mbox_info {
 };
 
 /*
- * Hardcoded TCM bank values. This will be removed once TCM bindings are
- * accepted for system-dt specifications and upstreamed in linux kernel
+ * Hardcoded TCM bank values. This will stay in driver to maintain backward
+ * compatibility with device-tree that does not have TCM information.
  */
 static const struct mem_bank_data zynqmp_tcm_banks_split[] = {
 	{0xffe00000UL, 0x0, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
@@ -757,6 +757,103 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)
 	return ERR_PTR(ret);
 }
 
+static int zynqmp_r5_get_tcm_node_from_dt(struct zynqmp_r5_cluster *cluster)
+{
+	int i, j, tcm_bank_count, ret, tcm_pd_idx, pd_count;
+	struct of_phandle_args out_args = {0};
+	struct zynqmp_r5_core *r5_core;
+	struct platform_device *cpdev;
+	struct mem_bank_data *tcm;
+	struct device_node *np;
+	struct resource *res;
+	u64 abs_addr, size;
+	struct device *dev;
+
+	for (i = 0; i < cluster->core_count; i++) {
+		r5_core = cluster->r5_cores[i];
+		dev = r5_core->dev;
+		np = r5_core->np;
+
+		pd_count = of_count_phandle_with_args(np, "power-domains",
+						      "#power-domain-cells");
+
+		if (pd_count <= 0) {
+			dev_err(dev, "invalid power-domains property, %d\n", pd_count);
+			return -EINVAL;
+		}
+
+		/* First entry in power-domains list is for r5 core, rest for TCM. */
+		tcm_bank_count = pd_count - 1;
+
+		if (tcm_bank_count <= 0) {
+			dev_err(dev, "invalid TCM count %d\n", tcm_bank_count);
+			return -EINVAL;
+		}
+
+		r5_core->tcm_banks = devm_kcalloc(dev, tcm_bank_count,
+						  sizeof(struct mem_bank_data *),
+						  GFP_KERNEL);
+		if (!r5_core->tcm_banks)
+			ret = -ENOMEM;
+
+		r5_core->tcm_bank_count = tcm_bank_count;
+		for (j = 0, tcm_pd_idx = 1; j < tcm_bank_count; j++, tcm_pd_idx++) {
+			tcm = devm_kzalloc(dev, sizeof(struct mem_bank_data),
+					   GFP_KERNEL);
+			if (!tcm)
+				return -ENOMEM;
+
+			r5_core->tcm_banks[j] = tcm;
+
+			/* Get power-domains id of TCM. */
+			ret = of_parse_phandle_with_args(np, "power-domains",
+							 "#power-domain-cells",
+							 tcm_pd_idx, &out_args);
+			if (ret) {
+				dev_err(r5_core->dev,
+					"failed to get tcm %d pm domain, ret %d\n",
+					tcm_pd_idx, ret);
+				return ret;
+			}
+			tcm->pm_domain_id = out_args.args[0];
+			of_node_put(out_args.np);
+
+			/* Get TCM address without translation. */
+			ret = of_property_read_reg(np, j, &abs_addr, &size);
+			if (ret) {
+				dev_err(dev, "failed to get reg property\n");
+				return ret;
+			}
+
+			/*
+			 * Remote processor can address only 32 bits
+			 * so convert 64-bits into 32-bits. This will discard
+			 * any unwanted upper 32-bits.
+			 */
+			tcm->da = (u32)abs_addr;
+			tcm->size = (u32)size;
+
+			cpdev = to_platform_device(dev);
+			res = platform_get_resource(cpdev, IORESOURCE_MEM, j);
+			if (!res) {
+				dev_err(dev, "failed to get tcm resource\n");
+				return -EINVAL;
+			}
+
+			tcm->addr = (u32)res->start;
+			tcm->bank_name = (char *)res->name;
+			res = devm_request_mem_region(dev, tcm->addr, tcm->size,
+						      tcm->bank_name);
+			if (!res) {
+				dev_err(dev, "failed to request tcm resource\n");
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
 /**
  * zynqmp_r5_get_tcm_node()
  * Ideally this function should parse tcm node and store information
@@ -835,9 +932,14 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
 	struct zynqmp_r5_core *r5_core;
 	int ret, i;
 
-	ret = zynqmp_r5_get_tcm_node(cluster);
-	if (ret < 0) {
-		dev_err(dev, "can't get tcm node, err %d\n", ret);
+	r5_core = cluster->r5_cores[0];
+	if (of_find_property(r5_core->np, "reg", NULL))
+		ret = zynqmp_r5_get_tcm_node_from_dt(cluster);
+	else
+		ret = zynqmp_r5_get_tcm_node(cluster);
+
+	if (ret) {
+		dev_err(dev, "can't get tcm, err %d\n", ret);
 		return ret;
 	}
 
-- 
2.25.1



From tanmay.shah at amd.com  Tue Feb 13 09:54:48 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Tue, 13 Feb 2024 09:54:48 -0800
Subject: [PATCH v10 2/4] dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings
In-Reply-To: <20240213175450.3097308-1-tanmay.shah@amd.com>
References: <20240213175450.3097308-1-tanmay.shah@amd.com>
Message-ID: <20240213175450.3097308-3-tanmay.shah@amd.com>

From: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>

Introduce bindings for TCM memory address space on AMD-xilinx Zynq
UltraScale+ platform. It will help in defining TCM in device-tree
and make it's access platform agnostic and data-driven.

Tightly-coupled memories(TCMs) are low-latency memory that provides
predictable instruction execution and predictable data load/store
timing. Each Cortex-R5F processor contains two 64-bit wide 64 KB memory
banks on the ATCM and BTCM ports, for a total of 128 KB of memory.

The TCM resources(reg, reg-names and power-domain) are documented for
each TCM in the R5 node. The reg and reg-names are made as required
properties as we don't want to hardcode TCM addresses for future
platforms and for zu+ legacy implementation will ensure that the
old dts w/o reg/reg-names works and stable ABI is maintained.

It also extends the examples for TCM split and lockstep modes.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---

Changes in v10:
  - modify number of "reg", "reg-names" and "power-domains" entries
    based on cluster mode
  - Add extra optional atcm and btcm in "reg" property for lockstep mode
  - Add "reg-names" for extra optional atcm and btcm for lockstep mode
  - Drop previous Ack as bindings has new change

Changes in v9:
  - None
Changes in v8:
  - None
Changes in v7:
  - None
Changes in v6:
  - None
Changes in v5:
  - None

Changes in v4:
  - Use address-cells and size-cells value 2
  - Modify ranges property as per new value of address-cells
    and size-cells
  - Modify child node "reg" property accordingly 
  - Remove previous ack for further review

v4 link: https://lore.kernel.org/all/20230829181900.2561194-2-tanmay.shah at amd.com/

 .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 ++++++++++++++++--
 1 file changed, 170 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml b/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
index 78aac69f1060..2de74307821e 100644
--- a/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
@@ -20,9 +20,21 @@ properties:
   compatible:
     const: xlnx,zynqmp-r5fss
 
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 2
+
+  ranges:
+    description: |
+      Standard ranges definition providing address translations for
+      local R5F TCM address spaces to bus addresses.
+
   xlnx,cluster-mode:
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [0, 1, 2]
+    default: 1
     description: |
       The RPU MPCore can operate in split mode (Dual-processor performance), Safety
       lock-step mode(Both RPU cores execute the same code in lock-step,
@@ -37,7 +49,7 @@ properties:
       2: single cpu mode
 
 patternProperties:
-  "^r5f-[a-f0-9]+$":
+  "^r5f@[0-9a-f]+$":
     type: object
     description: |
       The RPU is located in the Low Power Domain of the Processor Subsystem.
@@ -54,9 +66,6 @@ patternProperties:
       compatible:
         const: xlnx,zynqmp-r5f
 
-      power-domains:
-        maxItems: 1
-
       mboxes:
         minItems: 1
         items:
@@ -101,35 +110,174 @@ patternProperties:
 
     required:
       - compatible
-      - power-domains
 
-    unevaluatedProperties: false
+allOf:
+  - if:
+      properties:
+        xlnx,cluster-mode:
+            enum:
+              - 1
+    then:
+      patternProperties:
+        "^r5f@[0-9a-f]+$":
+          type: object
+
+          properties:
+            reg:
+              minItems: 1
+              items:
+                - description: ATCM internal memory
+                - description: BTCM internal memory
+                - description: extra ATCM memory in lockstep mode
+                - description: extra BTCM memory in lockstep mode
+
+            reg-names:
+              minItems: 1
+              items:
+                - const: atcm0
+                - const: btcm0
+                - const: atcm1
+                - const: btcm1
+
+            power-domains:
+              minItems: 2
+              maxItems: 5
+
+          required:
+            - reg
+            - reg-names
+            - power-domains
+
+    else:
+      patternProperties:
+        "^r5f@[0-9a-f]+$":
+          type: object
+
+          properties:
+            reg:
+              minItems: 1
+              items:
+                - description: ATCM internal memory
+                - description: BTCM internal memory
+
+            reg-names:
+              minItems: 1
+              items:
+                - const: atcm0
+                - const: btcm0
+
+            power-domains:
+              minItems: 2
+              maxItems: 3
+
+          required:
+            - reg
+            - reg-names
+            - power-domains
 
 required:
   - compatible
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
 
 additionalProperties: false
 
 examples:
   - |
-    remoteproc {
-        compatible = "xlnx,zynqmp-r5fss";
-        xlnx,cluster-mode = <1>;
-
-        r5f-0 {
-            compatible = "xlnx,zynqmp-r5f";
-            power-domains = <&zynqmp_firmware 0x7>;
-            memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
-            mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
-            mbox-names = "tx", "rx";
+    #include <dt-bindings/power/xlnx-zynqmp-power.h>
+
+    // Split mode configuration
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        remoteproc at ffe00000 {
+            compatible = "xlnx,zynqmp-r5fss";
+            xlnx,cluster-mode = <0>;
+
+            #address-cells = <2>;
+            #size-cells = <2>;
+            ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+                     <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+                     <0x1 0x0 0x0 0xffe90000 0x0 0x10000>,
+                     <0x1 0x20000 0x0 0xffeb0000 0x0 0x10000>;
+
+            r5f at 0 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x0 0x0 0x0 0x10000>, <0x0 0x20000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0";
+                power-domains = <&zynqmp_firmware PD_RPU_0>,
+                                <&zynqmp_firmware PD_R5_0_ATCM>,
+                                <&zynqmp_firmware PD_R5_0_BTCM>;
+                memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>,
+                                <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
+                mbox-names = "tx", "rx";
+            };
+
+            r5f at 1 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0";
+                power-domains = <&zynqmp_firmware PD_RPU_1>,
+                                <&zynqmp_firmware PD_R5_1_ATCM>,
+                                <&zynqmp_firmware PD_R5_1_BTCM>;
+                memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>,
+                                <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
+                mbox-names = "tx", "rx";
+            };
         };
+    };
+
+  - |
+    //Lockstep configuration
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        remoteproc at ffe00000 {
+            compatible = "xlnx,zynqmp-r5fss";
+            xlnx,cluster-mode = <1>;
+
+            #address-cells = <2>;
+            #size-cells = <2>;
+            ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+                     <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+                     <0x0 0x10000 0x0 0xffe10000 0x0 0x10000>,
+                     <0x0 0x30000 0x0 0xffe30000 0x0 0x10000>;
+
+            r5f at 0 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x0 0x0 0x0 0x10000>,
+                      <0x0 0x20000 0x0 0x10000>,
+                      <0x0 0x10000 0x0 0x10000>,
+                      <0x0 0x30000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0", "atcm1", "btcm1";
+                power-domains = <&zynqmp_firmware PD_RPU_0>,
+                                <&zynqmp_firmware PD_R5_0_ATCM>,
+                                <&zynqmp_firmware PD_R5_0_BTCM>,
+                                <&zynqmp_firmware PD_R5_1_ATCM>,
+                                <&zynqmp_firmware PD_R5_1_BTCM>;
+                memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>,
+                                <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
+                mbox-names = "tx", "rx";
+            };
 
-        r5f-1 {
-            compatible = "xlnx,zynqmp-r5f";
-            power-domains = <&zynqmp_firmware 0x8>;
-            memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
-            mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
-            mbox-names = "tx", "rx";
+            r5f at 1 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0";
+                power-domains = <&zynqmp_firmware PD_RPU_1>,
+                                <&zynqmp_firmware PD_R5_1_ATCM>,
+                                <&zynqmp_firmware PD_R5_1_BTCM>;
+                memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>,
+                                <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
+                mbox-names = "tx", "rx";
+            };
         };
     };
 ...
-- 
2.25.1



From wahrenst at gmx.net  Tue Feb 13 09:50:11 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Tue, 13 Feb 2024 18:50:11 +0100
Subject: [PATCH v2 17/17] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <20240213010347.1075251-18-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-18-sre@kernel.org>
Message-ID: <95d56903-7893-4a12-a451-f1bcc1d5316e@gmx.net>

Am 13.02.24 um 02:01 schrieb Sebastian Reichel:
> Add UNI-T UTi260b thermal camera board.
>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
Reviewed-by: Stefan Wahren <wahrenst at gmx.net>


From broonie at kernel.org  Tue Feb 13 09:55:43 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 17:55:43 +0000
Subject: [PATCH 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <92e7e0acf6d8746a07729924982acbfea777c468.camel@gmail.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
 <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com>
 <92e7e0acf6d8746a07729924982acbfea777c468.camel@gmail.com>
Message-ID: <890cc62c-9ae3-41b7-98a8-2c3245570045@sirena.org.uk>

On Tue, Feb 13, 2024 at 10:53:56AM +0100, Nuno S? wrote:
> On Mon, 2024-02-12 at 17:26 -0600, David Lechner wrote:
> > This adds a new spi_optimize_message() function that can be used to
> > optimize SPI messages that are used more than once. Peripheral drivers
> > that use the same message multiple times can use this API to perform SPI
> > message validation and controller-specific optimizations once and then
> > reuse the message while avoiding the overhead of revalidating the

Please delete unneeded context from mails when replying.  Doing this
makes it much easier to find your reply in the message, helping ensure
it won't be missed by people scrolling through the irrelevant quoted
material.
-------------- 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/20240213/290cb781/attachment-0001.sig>

From linus.walleij at linaro.org  Tue Feb 13 09:57:22 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 13 Feb 2024 18:57:22 +0100
Subject: [PATCH 02/22] gpio: Add ChromeOS EC GPIO driver
In-Reply-To: <20240210070934.2549994-3-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-3-swboyd@chromium.org>
Message-ID: <CACRpkdaxW+2q9=CPpkJZK7tWh5T7smnvqoEhEGezV9TvOw9wqQ@mail.gmail.com>

Hi Stephen,

thanks for your patch!

Overall it looks good I have a few nitpicks

On Sat, Feb 10, 2024 at 8:09?AM Stephen Boyd <swboyd at chromium.org> wrote:

> The ChromeOS embedded controller (EC) supports setting the state of
> GPIOs when the system is unlocked, and getting the state of GPIOs in all
> cases. The GPIOs are on the EC itself, so the EC acts similar to a GPIO
> expander. Add a driver to get and set the GPIOs on the EC through the
> host command interface.
>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: Bartosz Golaszewski <brgl at bgdev.pl>
> Cc: Benson Leung <bleung at chromium.org>
> Cc: Guenter Roeck <groeck at chromium.org>
> Cc: <linux-gpio at vger.kernel.org>
> Cc: <chrome-platform at lists.linux.dev>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
(...)

> +config GPIO_CROS_EC
> +       tristate "ChromeOS EC GPIO support"
> +       depends on CROS_EC
> +       help
> +         GPIO driver for exposing GPIOs on the ChromeOS Embedded
> +         Controller.
> +
> +         This driver can also be built as a module. If so, the module
> +         will be called gpio-cros-ec.

Classified as "MFD Expander" but I honestly don't know anything better.

> +#include <linux/bitops.h>
> +#include <linux/errno.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/init.h>

Do you need init.h?
I guess maybe... I thought module would be enough for this.

> +static int cros_ec_gpio_request(struct gpio_chip *chip, unsigned gpio_pin)
> +{
> +       if (gpio_pin < chip->ngpio)
> +               return 0;
> +
> +       return -EINVAL;
> +}

If this check is needed, it should be in gpiolib I think?

> +#ifdef CONFIG_OF

This ifdef should not be needed these days.

> +static const struct of_device_id cros_ec_gpio_of_match[] = {
> +       { .compatible = "google,cros-ec-gpio" },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, cros_ec_gpio_of_match);
> +#endif
> +
> +static struct platform_driver cros_ec_gpio_driver = {
> +       .probe = cros_ec_gpio_probe,
> +       .driver = {
> +               .name = "cros-ec-gpio",
> +               .of_match_table = of_match_ptr(cros_ec_gpio_of_match),

Nor the of_match_ptr() business.

With these fixed/addressed:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From dan.carpenter at linaro.org  Tue Feb 13 10:05:01 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Tue, 13 Feb 2024 21:05:01 +0300
Subject: [PATCH] drm/imx/dcss: fix resource size calculation
Message-ID: <4914592b-4256-4c9c-bc1d-6dec1e473831@moroto.mountain>

The resource is inclusive of the ->start and ->end addresses so this
calculation is not correct.  It should be "res->end - res->start + 1".
Use the resource_size() to do the calculation.

Fixes: 90393c9b5408 ("drm/imx/dcss: request memory region")
Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>
---
>From static analysis.  Not tested.

 drivers/gpu/drm/imx/dcss/dcss-dev.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.c b/drivers/gpu/drm/imx/dcss/dcss-dev.c
index 597e9b7bd4bf..7fd0c4c14205 100644
--- a/drivers/gpu/drm/imx/dcss/dcss-dev.c
+++ b/drivers/gpu/drm/imx/dcss/dcss-dev.c
@@ -167,7 +167,6 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output)
 	struct resource *res;
 	struct dcss_dev *dcss;
 	const struct dcss_type_data *devtype;
-	resource_size_t res_len;
 
 	devtype = of_device_get_match_data(dev);
 	if (!devtype) {
@@ -181,8 +180,7 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output)
 		return ERR_PTR(-EINVAL);
 	}
 
-	res_len = res->end - res->start;
-	if (!devm_request_mem_region(dev, res->start, res_len, "dcss")) {
+	if (!devm_request_mem_region(dev, res->start, resource_size(res), "dcss")) {
 		dev_err(dev, "cannot request memory region\n");
 		return ERR_PTR(-EBUSY);
 	}
-- 
2.43.0



From ryan.roberts at arm.com  Tue Feb 13 10:05:09 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 13 Feb 2024 18:05:09 +0000
Subject: [PATCH v5 25/25] arm64/mm: Automatically fold contpte mappings
In-Reply-To: <Zcuqd9e359L0SVPC@FVFF77S0Q05N.cambridge.arm.com>
References: <20240202080756.1453939-1-ryan.roberts@arm.com>
 <20240202080756.1453939-26-ryan.roberts@arm.com>
 <Zcuqd9e359L0SVPC@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <5b4ab6d9-1078-4834-91c4-8715c27b861f@arm.com>

On 13/02/2024 17:44, Mark Rutland wrote:
> On Fri, Feb 02, 2024 at 08:07:56AM +0000, Ryan Roberts wrote:
>> There are situations where a change to a single PTE could cause the
>> contpte block in which it resides to become foldable (i.e. could be
>> repainted with the contiguous bit). Such situations arise, for example,
>> when user space temporarily changes protections, via mprotect, for
>> individual pages, such can be the case for certain garbage collectors.
>>
>> We would like to detect when such a PTE change occurs. However this can
>> be expensive due to the amount of checking required. Therefore only
>> perform the checks when an indiviual PTE is modified via mprotect
>> (ptep_modify_prot_commit() -> set_pte_at() -> set_ptes(nr=1)) and only
>> when we are setting the final PTE in a contpte-aligned block.
>>
>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>> ---
>>  arch/arm64/include/asm/pgtable.h | 26 +++++++++++++
>>  arch/arm64/mm/contpte.c          | 64 ++++++++++++++++++++++++++++++++
>>  2 files changed, 90 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index cdc310880a3b..d3357fe4eb89 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -1192,6 +1192,8 @@ void vmemmap_update_pte(unsigned long addr, pte_t *ptep, pte_t pte);
>>   * where it is possible and makes sense to do so. The PTE_CONT bit is considered
>>   * a private implementation detail of the public ptep API (see below).
>>   */
>> +extern void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
>> +				pte_t *ptep, pte_t pte);
>>  extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>>  				pte_t *ptep, pte_t pte);
>>  extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
>> @@ -1213,6 +1215,29 @@ extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>>  				unsigned long addr, pte_t *ptep,
>>  				pte_t entry, int dirty);
>>  
>> +static __always_inline void contpte_try_fold(struct mm_struct *mm,
>> +				unsigned long addr, pte_t *ptep, pte_t pte)
>> +{
>> +	/*
>> +	 * Only bother trying if both the virtual and physical addresses are
>> +	 * aligned and correspond to the last entry in a contig range. The core
>> +	 * code mostly modifies ranges from low to high, so this is the likely
>> +	 * the last modification in the contig range, so a good time to fold.
>> +	 * We can't fold special mappings, because there is no associated folio.
>> +	 */
>> +
>> +	const unsigned long contmask = CONT_PTES - 1;
>> +	bool valign = ((addr >> PAGE_SHIFT) & contmask) == contmask;
>> +
>> +	if (unlikely(valign)) {
>> +		bool palign = (pte_pfn(pte) & contmask) == contmask;
>> +
>> +		if (unlikely(palign &&
>> +		    pte_valid(pte) && !pte_cont(pte) && !pte_special(pte)))
>> +			__contpte_try_fold(mm, addr, ptep, pte);
>> +	}
>> +}
>> +
>>  static __always_inline void contpte_try_unfold(struct mm_struct *mm,
>>  				unsigned long addr, pte_t *ptep, pte_t pte)
>>  {
>> @@ -1287,6 +1312,7 @@ static __always_inline void set_ptes(struct mm_struct *mm, unsigned long addr,
>>  	if (likely(nr == 1)) {
>>  		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>>  		__set_ptes(mm, addr, ptep, pte, 1);
>> +		contpte_try_fold(mm, addr, ptep, pte);
>>  	} else {
>>  		contpte_set_ptes(mm, addr, ptep, pte, nr);
>>  	}
>> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
>> index 80346108450b..2c7dafd0552a 100644
>> --- a/arch/arm64/mm/contpte.c
>> +++ b/arch/arm64/mm/contpte.c
>> @@ -67,6 +67,70 @@ static void contpte_convert(struct mm_struct *mm, unsigned long addr,
>>  	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
>>  }
>>  
>> +void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
>> +			pte_t *ptep, pte_t pte)
>> +{
>> +	/*
>> +	 * We have already checked that the virtual and pysical addresses are
>> +	 * correctly aligned for a contpte mapping in contpte_try_fold() so the
>> +	 * remaining checks are to ensure that the contpte range is fully
>> +	 * covered by a single folio, and ensure that all the ptes are valid
>> +	 * with contiguous PFNs and matching prots. We ignore the state of the
>> +	 * access and dirty bits for the purpose of deciding if its a contiguous
>> +	 * range; the folding process will generate a single contpte entry which
>> +	 * has a single access and dirty bit. Those 2 bits are the logical OR of
>> +	 * their respective bits in the constituent pte entries. In order to
>> +	 * ensure the contpte range is covered by a single folio, we must
>> +	 * recover the folio from the pfn, but special mappings don't have a
>> +	 * folio backing them. Fortunately contpte_try_fold() already checked
>> +	 * that the pte is not special - we never try to fold special mappings.
>> +	 * Note we can't use vm_normal_page() for this since we don't have the
>> +	 * vma.
>> +	 */
>> +
>> +	unsigned long folio_saddr, folio_eaddr;
>> +	unsigned long cont_saddr, cont_eaddr;
>> +	pte_t expected_pte, subpte;
>> +	struct folio *folio;
>> +	struct page *page;
>> +	unsigned long pfn;
>> +	pte_t *orig_ptep;
>> +	pgprot_t prot;
>> +
>> +	int i;
>> +
>> +	if (!mm_is_user(mm))
>> +		return;
>> +
>> +	page = pte_page(pte);
>> +	folio = page_folio(page);
>> +	folio_saddr = addr - (page - &folio->page) * PAGE_SIZE;
>> +	folio_eaddr = folio_saddr + folio_nr_pages(folio) * PAGE_SIZE;
>> +	cont_saddr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
>> +	cont_eaddr = cont_saddr + CONT_PTE_SIZE;
> 
> I assume that the 's' in *_sddar is for "start", and the 'e' in *_eaddr is for
> "end". Could we use "start" and "end" directly, e.g. folio_start, folio_end?

ACK; will fix.

> 
>> +
>> +	if (folio_saddr > cont_saddr || folio_eaddr < cont_eaddr)
>> +		return;
>> +
>> +	pfn = pte_pfn(pte) - ((addr - cont_saddr) >> PAGE_SHIFT);
> 
> IIUC this should be the same as:
> 
> 	pfn = ALIGN_DOWN(pte_pfn(pte), NR_CONT_PTES);
> 
> ... which would align with the way we generate 'cont_saddr' above.

ACK; will fix.

> 
> Otherwise, this looks good to me.

Great thanks!

I'll get these changes done and rebase onto mm-unstable once David's zap
batching series is in, retest and re-post (hopefully in the next couple of days!)

> 
> Mark.
> 
>> +	prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
>> +	expected_pte = pfn_pte(pfn, prot);
>> +	orig_ptep = ptep;
>> +	ptep = contpte_align_down(ptep);
>> +
>> +	for (i = 0; i < CONT_PTES; i++) {
>> +		subpte = pte_mkold(pte_mkclean(__ptep_get(ptep)));
>> +		if (!pte_same(subpte, expected_pte))
>> +			return;
>> +		expected_pte = pte_advance_pfn(expected_pte, 1);
>> +		ptep++;
>> +	}
>> +
>> +	pte = pte_mkcont(pte);
>> +	contpte_convert(mm, addr, orig_ptep, pte);
>> +}
>> +EXPORT_SYMBOL(__contpte_try_fold);
>> +
>>  void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>>  			pte_t *ptep, pte_t pte)
>>  {
>> -- 
>> 2.25.1
>>



From conor at kernel.org  Tue Feb 13 10:18:36 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 13 Feb 2024 18:18:36 +0000
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible
 for MT7988
In-Reply-To: <20240213164633.25447-1-zajec5@gmail.com>
References: <20240213164633.25447-1-zajec5@gmail.com>
Message-ID: <20240213-resource-evaluator-0754cfd5882d@spud>

On Tue, Feb 13, 2024 at 05:46:32PM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7988 has on-SoC controller that can control up to 8 PWMs.

I see a binding and a dts patch, but no driver patch, how come?

Also, what makes this incompatibly different with the other devices in
the binding, like the 8183?

Cheers,
Conor.

> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml b/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
> index 0fbe8a6469eb..a5c308801619 100644
> --- a/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
> +++ b/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
> @@ -24,6 +24,7 @@ properties:
>            - mediatek,mt7629-pwm
>            - mediatek,mt7981-pwm
>            - mediatek,mt7986-pwm
> +          - mediatek,mt7988-pwm
>            - mediatek,mt8183-pwm
>            - mediatek,mt8365-pwm
>            - mediatek,mt8516-pwm
> -- 
> 2.35.3
> 
-------------- 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/20240213/5007d485/attachment-0001.sig>

From robh at kernel.org  Tue Feb 13 10:20:35 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 12:20:35 -0600
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename
 qcom,dsb-element-size
In-Reply-To: <20240213160521.15925-2-quic_jinlmao@quicinc.com>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
 <20240213160521.15925-2-quic_jinlmao@quicinc.com>
Message-ID: <170784843419.1735886.14696780778135755616.robh@kernel.org>


On Tue, 13 Feb 2024 08:05:17 -0800, Mao Jinlong wrote:
> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
> bit.
> 
> Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
> ---
>  .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml          | 4 ++--
>  1 file changed, 2 insertions(+), 2 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/dt-review-ci/linux/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml: properties:qcom,dsb-element-bits: '$ref' should not be valid under {'const': '$ref'}
	hint: Standard unit suffix properties don't need a type $ref
	from schema $id: http://devicetree.org/meta-schemas/core.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.example.dtb: tpdm at 684c000: qcom,dsb-element-bits:0: [0, 0, 0, 32] is too long
	from schema $id: http://devicetree.org/schemas/arm/qcom,coresight-tpdm.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.example.dtb: tpdm at 684c000: qcom,dsb-element-bits:0:0: 0 is not one of [32, 64]
	from schema $id: http://devicetree.org/schemas/arm/qcom,coresight-tpdm.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.example.dtb: tpdm at 684c000: qcom,dsb-element-bits:0: [0, 0, 0, 32] is too long
	from schema $id: http://devicetree.org/schemas/arm/qcom,coresight-tpdm.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.example.dtb: tpdm at 684c000: qcom,dsb-element-bits: size is 8, expected 32
	from schema $id: http://devicetree.org/schemas/property-units.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240213160521.15925-2-quic_jinlmao at quicinc.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From naresh.kamboju at linaro.org  Tue Feb 13 10:21:23 2024
From: naresh.kamboju at linaro.org (Naresh Kamboju)
Date: Tue, 13 Feb 2024 23:51:23 +0530
Subject: WARNING: arch/arm64/kernel/cpufeature.c:3369 this_cpu_has_cap
Message-ID: <CA+G9fYuVJ3DfmOR2GxbVmLqh_d=3y_wTXX-vQOUgp86uX-3oGg@mail.gmail.com>

Following kernel warning notices on all arm64 devices on today's Linux
next-20240213 tag.

Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>

[    0.038524] SMP: Total of 6 processors activated.
[    0.038539] CPU: All CPU(s) started at EL2
[    0.038588] CPU features: detected: 32-bit EL0 Support
[    0.038602] CPU features: detected: 32-bit EL1 Support
[    0.038620] CPU features: detected: CRC32 instructions
[    0.038650] ------------[ cut here ]------------
[    0.038656] WARNING: CPU: 0 PID: 1 at
arch/arm64/kernel/cpufeature.c:3369 this_cpu_has_cap+0x1c/0x70
[    0.038691] Modules linked in:
[    0.038707] CPU: 0 PID: 1 Comm: swapper/0 Not tainted
6.8.0-rc4-next-20240213 #1
[    0.038721] Hardware name: Radxa ROCK Pi 4B (DT)
[    0.038729] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[    0.038744] pc : this_cpu_has_cap+0x1c/0x70
[    0.038761] lr : has_nv1+0x28/0xe8
..
[    0.039008] Call trace:
[    0.039014]  this_cpu_has_cap+0x1c/0x70
[    0.039031]  update_cpu_capabilities+0xd4/0x138
[    0.039048]  setup_system_features+0x38/0x130
[    0.039075]  smp_cpus_done+0x50/0xc8
[    0.039094]  smp_init+0x84/0xa0
[    0.039109]  kernel_init_freeable+0x11c/0x400
[    0.039126]  kernel_init+0x28/0x1f0
[    0.039148]  ret_from_fork+0x10/0x20
[    0.039167] ---[ end trace 0000000000000000 ]---


Links:
 - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240213/testrun/22596318/suite/log-parser-boot/test/check-kernel-exception/log
 - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240213/testrun/22596318/suite/log-parser-boot/tests/

This issue has been addressed in the relevant email thread,
https://lore.kernel.org/all/0593516b-2419-49b7-83aa-fe189ffad0c2 at arm.com/

I will test the corresponding fix patch and get back to you.

--
Linaro LKFT
https://lkft.linaro.org


From broonie at kernel.org  Tue Feb 13 10:24:38 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 18:24:38 +0000
Subject: [PATCH v2] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
Message-ID: <20240213-arm64-sve-ptrace-regset-size-v2-1-c7600ca74b9b@kernel.org>

Doug Anderson observed that ChromeOS crashes are being reported which
include failing allocations of order 7 during core dumps due to ptrace
allocating storage for regsets:

  chrome: page allocation failure: order:7,
          mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
          nodemask=(null),cpuset=urgent,mems_allowed=0
   ...
  regset_get_alloc+0x1c/0x28
  elf_core_dump+0x3d8/0xd8c
  do_coredump+0xeb8/0x1378

with further investigation showing that this is:

   [   66.957385] DOUG: Allocating 279584 bytes

which is the maximum size of the SVE regset. As Doug observes it is not
entirely surprising that such a large allocation of contiguous memory might
fail on a long running system.

The SVE regset is currently sized to hold SVE registers with a VQ of
SVE_VQ_MAX which is 512, substantially more than the architectural maximum
of 16 which we might see even in a system emulating the limits of the
architecture. Since we don't expose the size we tell the regset core
externally let's define ARCH_SVE_VQ_MAX with the actual architectural
maximum and use that for the regset, we'll still overallocate most of the
time but much less so which will be helpful even if the core is fixed to
not require contiguous allocations.

Specify ARCH_SVE_VQ_MAX in terms of the maximum value that can be written
into ZCR_ELx.LEN (where this is set in the hardware). For consistency
update the maximum SME vector length to be specified in the same style
while we are at it.

We could also teach the ptrace core about runtime discoverable regset sizes
but that would be a more invasive change and this is being observed in
practical systems.

Reported-by: Doug Anderson <dianders at chromium.org>
Signed-off-by: Mark Brown <broonie at kernel.org>
---
We should probably also use the actual architectural limit for the
bitmasks we use in the VL enumeration code, though that's both a little
bit more involved and less immediately a problem.
---
Changes in v2:
- Specify the value using the size of the bitfield it goes into.
- Link to v1: https://lore.kernel.org/r/20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e at kernel.org
---
 arch/arm64/include/asm/fpsimd.h | 12 ++++++------
 arch/arm64/kernel/ptrace.c      |  3 ++-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 50e5f25d3024..481d94416d69 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -62,13 +62,13 @@ static inline void cpacr_restore(unsigned long cpacr)
  * When we defined the maximum SVE vector length we defined the ABI so
  * that the maximum vector length included all the reserved for future
  * expansion bits in ZCR rather than those just currently defined by
- * the architecture. While SME follows a similar pattern the fact that
- * it includes a square matrix means that any allocations that attempt
- * to cover the maximum potential vector length (such as happen with
- * the regset used for ptrace) end up being extremely large. Define
- * the much lower actual limit for use in such situations.
+ * the architecture.  Using this length to allocate worst size buffers
+ * results in excessively large allocations, and this effect is even
+ * more pronounced for SME due to ZA.  Define more suitable VLs for
+ * these situations.
  */
-#define SME_VQ_MAX	16
+#define ARCH_SVE_VQ_MAX ((ZCR_ELx_LEN_MASK >> ZCR_ELx_LEN_SHIFT) + 1)
+#define SME_VQ_MAX	((SMCR_ELx_LEN_MASK >> SMCR_ELx_LEN_SHIFT) + 1)
 
 struct task_struct;
 
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index dc6cf0e37194..e3bef38fc2e2 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1500,7 +1500,8 @@ static const struct user_regset aarch64_regsets[] = {
 #ifdef CONFIG_ARM64_SVE
 	[REGSET_SVE] = { /* Scalable Vector Extension */
 		.core_note_type = NT_ARM_SVE,
-		.n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE),
+		.n = DIV_ROUND_UP(SVE_PT_SIZE(ARCH_SVE_VQ_MAX,
+					      SVE_PT_REGS_SVE),
 				  SVE_VQ_BYTES),
 		.size = SVE_VQ_BYTES,
 		.align = SVE_VQ_BYTES,

---
base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
change-id: 20240202-arm64-sve-ptrace-regset-size-21b0928969e1

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From quic_nkela at quicinc.com  Tue Feb 13 10:24:48 2024
From: quic_nkela at quicinc.com (Nikunj Kela)
Date: Tue, 13 Feb 2024 10:24:48 -0800
Subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock
 .is_notify_supported callback
In-Reply-To: <ZcstL8tRVKIUFoBr@pluto>
References: <20240212123233.1230090-7-cristian.marussi@arm.com>
 <202402131047.2NVZWHma-lkp@intel.com> <ZcstL8tRVKIUFoBr@pluto>
Message-ID: <fc28f615-eaaf-459a-96e2-fce104f77fe7@quicinc.com>


On 2/13/2024 12:49 AM, Cristian Marussi wrote:
> On Tue, Feb 13, 2024 at 10:58:23AM +0800, kernel test robot wrote:
>> Hi Cristian,
>>
>> kernel test robot noticed the following build errors:
>>
>> [auto build test ERROR on soc/for-next]
>> [also build test ERROR on linus/master v6.8-rc4 next-20240212]
>> [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#_base_tree_information]
>>
> Hi,
>
> this series, as stated in the cover-letter, is based off the current tip of
>
> 	sudeep/for-next/scmi/updates
>
> and particularly needs commit:
>
> 	9c5bc650031e firmware: arm_scmi: Rework clock domain info lookups
>
> from there, since it contains the missing scmi_clock_domain_lookup().
>
> Not_sure/dont_known if there is any way to convey this "based-on-branch"
> info to your/any CI at the moment.
>
> Thanks,
> Cristian
Maybe add supdeep's tree in MAINTAINERS and use 'base-commit'.
>> url:    https://github.com/intel-lab-lkp/linux/commits/Cristian-Marussi/firmware-arm_scmi-Check-for-notification-support/20240212-203727
>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
>> patch link:    https://lore.kernel.org/r/20240212123233.1230090-7-cristian.marussi%40arm.com
>> patch subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock .is_notify_supported callback
>> config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20240213/202402131047.2NVZWHma-lkp at intel.com/config)
>> compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project c08b90c50bcac9f3f563c79491c8dbcbe7c3b574)
>> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240213/202402131047.2NVZWHma-lkp at intel.com/reproduce)
>>
>> If you fix the issue in a separate patch/commit (i.e. not just a new version of
>> the same patch/commit), kindly add following tags
>> | Reported-by: kernel test robot <lkp at intel.com>
>> | Closes: https://lore.kernel.org/oe-kbuild-all/202402131047.2NVZWHma-lkp at intel.com/
>>
>> All errors (new ones prefixed by >>):
>>
>>>> drivers/firmware/arm_scmi/clock.c:853:8: error: call to undeclared function 'scmi_clock_domain_lookup'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
>>       853 |         clk = scmi_clock_domain_lookup(ci, src_id);
>>           |               ^
>>>> drivers/firmware/arm_scmi/clock.c:853:6: error: incompatible integer to pointer conversion assigning to 'struct scmi_clock_info *' from 'int' [-Wint-conversion]
>>       853 |         clk = scmi_clock_domain_lookup(ci, src_id);
>>           |             ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>     2 errors generated.
>>
>>
>> vim +/scmi_clock_domain_lookup +853 drivers/firmware/arm_scmi/clock.c
>>
>>     842	
>>     843	static bool scmi_clk_notify_supported(const struct scmi_protocol_handle *ph,
>>     844					      u8 evt_id, u32 src_id)
>>     845	{
>>     846		bool supported;
>>     847		struct scmi_clock_info *clk;
>>     848		struct clock_info *ci = ph->get_priv(ph);
>>     849	
>>     850		if (evt_id >= ARRAY_SIZE(evt_2_cmd))
>>     851			return false;
>>     852	
>>   > 853		clk = scmi_clock_domain_lookup(ci, src_id);
>>     854		if (IS_ERR(clk))
>>     855			return false;
>>     856	
>>     857		if (evt_id == SCMI_EVENT_CLOCK_RATE_CHANGED)
>>     858			supported = clk->rate_changed_notifications;
>>     859		else
>>     860			supported = clk->rate_change_requested_notifications;
>>     861	
>>     862		return supported;
>>     863	}
>>     864	
>>
>> -- 
>> 0-DAY CI Kernel Test Service
>> https://github.com/intel/lkp-tests/wiki


From conor at kernel.org  Tue Feb 13 10:27:09 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 13 Feb 2024 18:27:09 +0000
Subject: [PATCH 1/2] dt-bindings: usb: mtk-xhci: add compatible for MT7988
In-Reply-To: <20240213130044.1976-1-zajec5@gmail.com>
References: <20240213130044.1976-1-zajec5@gmail.com>
Message-ID: <20240213-shortlist-unhook-7e7cc4e66c0a@spud>

On Tue, Feb 13, 2024 at 02:00:43PM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7988 SoC contains two on-SoC XHCI controllers. Add proper binding.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.
-------------- 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/20240213/0663150d/attachment.sig>

From broonie at kernel.org  Tue Feb 13 10:31:30 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 18:31:30 +0000
Subject: (subset) [PATCH v2 00/17] UNI-T UTi260B support
In-Reply-To: <20240213010347.1075251-1-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
Message-ID: <170784909076.647645.11591150150653881447.b4-ty@kernel.org>

On Tue, 13 Feb 2024 02:00:49 +0100, Sebastian Reichel wrote:
> This adds adds support for the UNI-T UTi260B thermal camera, which is based
> on i.MX6ULL. Patches 1-14 clean up all warnings reported by CHECK_DTBS for
> i.MX6ULL (i.e. for an empty board). They are not specific to the UTi260B and
> in fact that machine has most of the IP handled by these patches marked as
> disabled. Then patches 15+16 introduce the vendor and board compatible DT
> bindings. Finally the last patches adds support for the thermal camera itself.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[03/17] ASoC: dt-bindings: fsl,imx-asrc: convert to YAML
        commit: 20c0c9b352df1ab7915c827cb1d182bfc32f9f46

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  Tue Feb 13 10:39:49 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 13 Feb 2024 11:39:49 -0700
Subject: [Linux-stm32] [PATCH v2 4/4] remoteproc: stm32: Add support of an
 OP-TEE TA to load the firmware
In-Reply-To: <bdac5637-767e-4310-9ecd-fad5490e9b3c@foss.st.com>
References: <20240118100433.3984196-1-arnaud.pouliquen@foss.st.com>
 <20240118100433.3984196-5-arnaud.pouliquen@foss.st.com> <ZbPnsJm67G10+HQ3@p14s>
 <7ec6c9e8-9267-4e7c-81a4-abcdb2ab4239@foss.st.com> <ZbqW5YfDmEWG4G1X@p14s>
 <8ede77bb-0fbc-4de2-b51b-67674744b551@foss.st.com> <ZbvAmxHscnbUQGOD@p14s>
 <a52e00c5-fb60-4a9e-85ff-0f9649850f48@foss.st.com> <Zb1IPlnbMp9Utu2y@p14s>
 <36c0368b-94f3-40bd-9273-33ab2c9bf913@foss.st.com> <bdac5637-767e-4310-9ecd-fad5490e9b3c@foss.st.com>
Message-ID: <CANLsYkxvkj4Rx6+hA6yGStROY8FDxRdAh2h4SJc+eqECj-Ew9A@mail.gmail.com>

On Tue, 13 Feb 2024 at 08:48, Arnaud POULIQUEN
<arnaud.pouliquen at foss.st.com> wrote:
>
> Hello Mathieu,
>
> On 2/5/24 10:13, Arnaud POULIQUEN wrote:
> >
> >
> > On 2/2/24 20:53, Mathieu Poirier wrote:
> >> On Thu, Feb 01, 2024 at 07:33:35PM +0100, Arnaud POULIQUEN wrote:
> >>>
> >>>
> >>> On 2/1/24 17:02, Mathieu Poirier wrote:
> >>>> On Thu, Feb 01, 2024 at 04:06:37PM +0100, Arnaud POULIQUEN wrote:
> >>>>> hello Mathieu,
> >>>>>
> >>>>> On 1/31/24 19:52, Mathieu Poirier wrote:
> >>>>>> On Tue, Jan 30, 2024 at 10:13:48AM +0100, Arnaud POULIQUEN wrote:
> >>>>>>>
> >>>>>>>
> >>>>>>> On 1/26/24 18:11, Mathieu Poirier wrote:
> >>>>>>>> On Thu, Jan 18, 2024 at 11:04:33AM +0100, Arnaud Pouliquen wrote:
> >>>>>>>>> The new TEE remoteproc device is used to manage remote firmware in a
> >>>>>>>>> secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
> >>>>>>>>> introduced to delegate the loading of the firmware to the trusted
> >>>>>>>>> execution context. In such cases, the firmware should be signed and
> >>>>>>>>> adhere to the image format defined by the TEE.
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
> >>>>>>>>> ---
> >>>>>>>>> V1 to V2 update:
> >>>>>>>>> - remove the select "TEE_REMOTEPROC" in STM32_RPROC config as detected by
> >>>>>>>>>   the kernel test robot:
> >>>>>>>>>      WARNING: unmet direct dependencies detected for TEE_REMOTEPROC
> >>>>>>>>>      Depends on [n]: REMOTEPROC [=y] && OPTEE [=n]
> >>>>>>>>>      Selected by [y]:
> >>>>>>>>>      - STM32_RPROC [=y] && (ARCH_STM32 || COMPILE_TEST [=y]) && REMOTEPROC [=y]
> >>>>>>>>> - Fix initialized trproc variable in  stm32_rproc_probe
> >>>>>>>>> ---
> >>>>>>>>>  drivers/remoteproc/stm32_rproc.c | 149 +++++++++++++++++++++++++++++--
> >>>>>>>>>  1 file changed, 144 insertions(+), 5 deletions(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
> >>>>>>>>> index fcc0001e2657..cf6a21bac945 100644
> >>>>>>>>> --- a/drivers/remoteproc/stm32_rproc.c
> >>>>>>>>> +++ b/drivers/remoteproc/stm32_rproc.c
> >>>>>>>>> @@ -20,6 +20,7 @@
> >>>>>>>>>  #include <linux/remoteproc.h>
> >>>>>>>>>  #include <linux/reset.h>
> >>>>>>>>>  #include <linux/slab.h>
> >>>>>>>>> +#include <linux/tee_remoteproc.h>
> >>>>>>>>>  #include <linux/workqueue.h>
> >>>>>>>>>
> >>>>>>>>>  #include "remoteproc_internal.h"
> >>>>>>>>> @@ -49,6 +50,9 @@
> >>>>>>>>>  #define M4_STATE_STANDBY     4
> >>>>>>>>>  #define M4_STATE_CRASH               5
> >>>>>>>>>
> >>>>>>>>> +/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
> >>>>>>>>> +#define STM32_MP1_M4_PROC_ID    0
> >>>>>>>>> +
> >>>>>>>>>  struct stm32_syscon {
> >>>>>>>>>       struct regmap *map;
> >>>>>>>>>       u32 reg;
> >>>>>>>>> @@ -90,6 +94,8 @@ struct stm32_rproc {
> >>>>>>>>>       struct stm32_mbox mb[MBOX_NB_MBX];
> >>>>>>>>>       struct workqueue_struct *workqueue;
> >>>>>>>>>       bool hold_boot_smc;
> >>>>>>>>> +     bool fw_loaded;
> >>>>>>>>> +     struct tee_rproc *trproc;
> >>>>>>>>>       void __iomem *rsc_va;
> >>>>>>>>>  };
> >>>>>>>>>
> >>>>>>>>> @@ -257,6 +263,91 @@ static int stm32_rproc_release(struct rproc *rproc)
> >>>>>>>>>       return err;
> >>>>>>>>>  }
> >>>>>>>>>
> >>>>>>>>> +static int stm32_rproc_tee_elf_sanity_check(struct rproc *rproc,
> >>>>>>>>> +                                         const struct firmware *fw)
> >>>>>>>>> +{
> >>>>>>>>> +     struct stm32_rproc *ddata = rproc->priv;
> >>>>>>>>> +     unsigned int ret = 0;
> >>>>>>>>> +
> >>>>>>>>> +     if (rproc->state == RPROC_DETACHED)
> >>>>>>>>> +             return 0;
> >>>>>>>>> +
> >>>>>>>>> +     ret = tee_rproc_load_fw(ddata->trproc, fw);
> >>>>>>>>> +     if (!ret)
> >>>>>>>>> +             ddata->fw_loaded = true;
> >>>>>>>>> +
> >>>>>>>>> +     return ret;
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +static int stm32_rproc_tee_elf_load(struct rproc *rproc,
> >>>>>>>>> +                                 const struct firmware *fw)
> >>>>>>>>> +{
> >>>>>>>>> +     struct stm32_rproc *ddata = rproc->priv;
> >>>>>>>>> +     unsigned int ret;
> >>>>>>>>> +
> >>>>>>>>> +     /*
> >>>>>>>>> +      * This function can be called by remote proc for recovery
> >>>>>>>>> +      * without the sanity check. In this case we need to load the firmware
> >>>>>>>>> +      * else nothing done here as the firmware has been preloaded for the
> >>>>>>>>> +      * sanity check to be able to parse it for the resource table.
> >>>>>>>>> +      */
> >>>>>>>>
> >>>>>>>> This comment is very confusing - please consider refactoring.
> >>>>>>>>
> >>>>>>>>> +     if (ddata->fw_loaded)
> >>>>>>>>> +             return 0;
> >>>>>>>>> +
> >>>>>>>>
> >>>>>>>> I'm not sure about keeping a flag to indicate the status of the loaded firmware.
> >>>>>>>> It is not done for the non-secure method, I don't see why it would be needed for
> >>>>>>>> the secure one.
> >>>>>>>>
> >>>>>>>
> >>>>>>> The difference is on the sanity check.
> >>>>>>> - in rproc_elf_sanity_check we  parse the elf file to verify that it is
> >>>>>>> valid.
> >>>>>>> - in stm32_rproc_tee_elf_sanity_check we have to do the same, that means to
> >>>>>>> authenticate it. the authentication is done during the load.
> >>>>>>>
> >>>>>>> So this flag is used to avoid to reload it twice time.
> >>>>>>> refactoring the comment should help to understand this flag
> >>>>>>>
> >>>>>>>
> >>>>>>> An alternative would be to bypass the sanity check. But this lead to same
> >>>>>>> limitation.
> >>>>>>> Before loading the firmware in remoteproc_core, we call rproc_parse_fw() that is
> >>>>>>> used to get the resource table address. To get it from tee we need to
> >>>>>>> authenticate the firmware so load it...
> >>>>>>>
> >>>>>>
> >>>>>> I spent a long time thinking about this patchset.  Looking at the code as it
> >>>>>> is now, request_firmware() in rproc_boot() is called even when the TEE is
> >>>>>> responsible for loading the firmware.  There should be some conditional code
> >>>>>> that calls either request_firmware() or tee_rproc_load_fw().  The latter should
> >>>>>> also be renamed to tee_rproc_request_firmware() to avoid confusion.
> >>>>>
> >>>>>
> >>>>> The request_firmware() call is needed in both cases to get the image from the
> >>>>> filesystem. The tee_rproc_load_fw() gets, as input, the struct firmware provided
> >>>>> by request_firmware().
> >>>>
> >>>> The cover letter clearly state the secure side is responsible for loading the
> >>>> firmware image but here you're telling me it has to be loaded twice.  This is
> >>>> very confusing.
> >>>
> >>> Concerning the call of request_firmware()
> >>>
> >>> By "both cases" I would say that the call of request_firmware() is needed in
> >>> both modes:
> >>> - the ELF firmware is parsed and loaded by linux (legacy)
> >>> - the binary firmware is parsed and loaded by OP-TEE.
> >>>
> >>> The Op-TEE is not able to get the firmware image from the file system.
> >>>
> >>>
> >>> Concerning the call of tee_rproc_load_fw twice time
> >>>
> >>> There are 2 use cases:
> >>>
> >>> - First boot of the remote processor:
> >>>
> >>>   1) The Linux rproc gets the binary firmware image from the file system by
> >>>      calling  request_firmware(). A copy is stored in memory.
> >>
> >> Right.  And I think tee_rproc_load_fw() should be called right after
> >> request_firmware() if rproc::tee_rproc_interface is valid.  At that point the TEE
> >> app may or may not do the firmware authentication, that is application specific.
>
> FYI, I am close to completing V3 for my series. However, I am facing an issue
> with rproc_load_segments() that requires the implementation of ops->load on start.
> Therefore, just inserting a tee_rproc_load_fw() call is not possible.
>
> Due to this constraint, I did not find a solution that matches your
> recommendations. Nevertheless, I will propose another solution in my V3, trying
> to take into account as many of your comments/requests as possible, including
> updating of the remoteproc_core.c to simplify the sequence.
>
>

Thanks for the heads-up, let's see what you come up with.  That said,
please provide as much information as possible on the constraints you
are facing.

> Regards,
> Arnaud
>
>
> >>
> >>>   2) the linux performs a sanity check on the firmware calling
> >>>      rproc_fw_sanity_check()
> >>>     => from OP-TEE point of view this means to autenticate the firmware
> >>>     => let consider in this exemple that we bypass this step
> >>>            (ops->sanity_check = NULL)
> >>
> >> Ok
> >>
> >>>
> >>>   3) the linux rproc call rproc_parse_fw() to get the resource table
> >>>     => From OP-TEE point of view the resource table is available only when
> >>>            the firmware is loaded
> >>
> >> Right, and it should have been loaded already.  If it is not then the TEE should
> >> return an error.
> >>
> >>>     => We need to call tee_rproc_load_fw() to be able then to get the
> >>>            address of the resource table.
> >>
> >> See my comment above - at this point the TEE should already have the firmware.
> >> As such the only thing left is to get the address of the resource table, which
> >> you already do in rproc_tee_get_rsc_table().  The upper part of that function
> >> should be spun off in a new static function to deal with the TEE API, something
> >> like _rproc_tee_get_rsc_table().  The new function should also be called in
> >> tee_rproc_get_loaded_rsc_table() rather than keeping a cache value in
> >> trproc->rsc_va.
> >>
> >>>   4) The Linux rproc calls rproc_handle_resources() to parse the resource table.
> >>>   5) The linux rproc calls rproc_start()
> >>>     - load the firrmware calling rproc_load_segments()
> >>>             => we don't want to call tee_rproc_load_fw() it a second time
> >>
> >> And that is fine if the TEE app has already placed the program segments in
> >> memory.
> >>
> >>>     - start the firmware calling ops->start()
> >>>
> >>> - Reboot on crash recovery using rproc_boot_recovery()
> >>>
> >>>   1)  The Linux rproc gets the binary firmware image from the file system by
> >>>      calling request_firmware(). A copy is stored in memory.
> >>>   5) The linux rproc calls rproc_start()
> >>>     - load the firrmware calling rproc_load_segments()
> >>>             => we have to call tee_rproc_load_fw() to reload the firmware
> >>
> >> Loading the firmware in the TEE should be done right after request_firmware()
> >> has been called, the same way it is done in the boot path.  If there isn't a
> >> need to reload the TEE firmware than the TEE application should ignore the
> >> request.
> >
> > I need to prototype to verify this proposal.
> > I will come back with a V3.
>
> >
> > Thank you for the advice and review!
> >
> > Regard,
> > Arnaud
> >
> >>
> >>>     - start the firmware calling ops->start()
> >>>
> >>> In first use case we have to load the firmware on rproc_parse_fw(), in second
> >>> usecase on rproc_load_segments().
> >>>
> >>> This is the point I have tried to solve with the ddata->fw_loaded variable.
> >>>
> >>>>
> >>>> I'm also confused as to why stm32_rproc_tee_elf_sanity_check() is calling
> >>>> tee_rproc_load_fw().  There should be one call to load the firmware and another
> >>>> to perform a sanity check on it.  If the sanity check is done at load time by
> >>>> the secure world then ops::sanity_check() is NULL.
> >>>
> >>> Sure, make sense to remove the sanity_check ops
> >>>
> >>> Thanks,
> >>> Arnaud
> >>>
> >>>>
> >>>> Most of what this patchset does makes sense, but some of it needs to be moved
> >>>> around.
> >>>>
> >>>> Thanks,
> >>>> Mathieu
> >>>>
> >>>>>
> >>>>> If we want to integrate in remoteproc_core the solution could probably have to
> >>>>> create the equivalent of the rproc_fw_boot() to load the firmware with an
> >>>>> external method. Here is an example based on a new rproc_ops ( not tested)
> >>>>>
> >>>>> + static int rproc_fw_ext_boot(struct rproc *rproc, const struct firmware *fw)
> >>>>> + {
> >>>>> +         struct device *dev = &rproc->dev;
> >>>>> +         const char *name = rproc->firmware;
> >>>>> +         int ret;
> >>>>> +
> >>>>> +
> >>>>> +         dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size);
> >>>>> +
> >>>>> +         /* ops to load and start the remoteprocessor */
> >>>>> +         ret = rproc->ops->boot(rproc, fw);
> >>>>> +         if (ret)
> >>>>> +                 return ret;
> >>>>> +
> >>>>> +         /*
> >>>>> +          * if enabling an IOMMU isn't relevant for this rproc, this is
> >>>>> +          * just a nop
> >>>>> +          */
> >>>>> +         ret = rproc_enable_iommu(rproc);
> >>>>> +         if (ret) {
> >>>>> +                 dev_err(dev, "can't enable iommu: %d\n", ret);
> >>>>> +                 return ret;
> >>>>> +         }
> >>>>> +
> >>>>> +         /* Prepare rproc for firmware loading if needed */
> >>>>> +         ret = rproc_prepare_device(rproc);
> >>>>> +         if (ret) {
> >>>>> +                 dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
> >>>>> +                 goto disable_iommu;
> >>>>> +         }
> >>>>> +
> >>>>> +         ret = rproc_set_rsc_table(rproc);
> >>>>> +         if (ret) {
> >>>>> +                 dev_err(dev, "can't load resource table: %d\n", ret);
> >>>>> +                 goto unprepare_device;
> >>>>> +         }
> >>>>> +
> >>>>> +
> >>>>> +         /* reset max_notifyid */
> >>>>> +         rproc->max_notifyid = -1;
> >>>>> +
> >>>>> +         /* reset handled vdev */
> >>>>> +         rproc->nb_vdev = 0;
> >>>>> +
> >>>>> +         /* handle fw resources which are required to boot rproc */
> >>>>> +         ret = rproc_handle_resources(rproc, rproc_loading_handlers);
> >>>>> +         if (ret) {
> >>>>> +                 dev_err(dev, "Failed to process resources: %d\n", ret);
> >>>>> +                 goto clean_up_resources;
> >>>>> +         }
> >>>>> +
> >>>>> +         /* Allocate carveout resources associated to rproc */
> >>>>> +         ret = rproc_alloc_registered_carveouts(rproc);
> >>>>> +         if (ret) {
> >>>>> +                 dev_err(dev, "Failed to allocate associated carveouts: %d\n",
> >>>>> +                         ret);
> >>>>> +                 goto clean_up_resources;
> >>>>> +         }
> >>>>> +
> >>>>> +         return 0;
> >>>>> +
> >>>>> + clean_up_resources:
> >>>>> +         rproc_resource_cleanup(rproc);
> >>>>> + unprepare_rproc:
> >>>>> +         /* release HW resources if needed */
> >>>>> +         rproc_unprepare_device(rproc);
> >>>>> + disable_iommu:
> >>>>> +         rproc_disable_iommu(rproc);
> >>>>> +         return ret;
> >>>>> + }
> >>>>>
> >>>>>
> >>>>> int rproc_boot(struct rproc *rproc)
> >>>>> {
> >>>>> [...]
> >>>>>
> >>>>> -                 ret = rproc_fw_boot(rproc, firmware_p);
> >>>>> +                 if(rproc->ops->boot)
> >>>>> +                         ret = rproc_fw_ext_boot(rproc, firmware_p);
> >>>>> +                 else
> >>>>> +                         ret = rproc_fw_boot(rproc, firmware_p);
> >>>>>
> >>>>> Another advantage of this solution is that it opens the framework to other
> >>>>> formats. For instance it could be a way to support dtb format requested in [RFC]
> >>>>> Passing device-tree to remoteproc [1].
> >>>>>
> >>>>> [1]
> >>>>> https://lore.kernel.org/linux-remoteproc/f67cd822-4e29-71f2-7c42-e11dbaa6cd8c at kalrayinc.com/T/#t
> >>>>>
> >>>>> Thanks,
> >>>>> Arnaud
> >>>>>
> >>>>>
> >>>>>
> >>>>>>
> >>>>>> I touched on that before but please rename rproc_tee_get_rsc_table() to
> >>>>>> rproc_tee_elf_load_rsc_table().  I also suggest to introduce a new function,
> >>>>>> rproc_tee_get_loaded_rsc_table() that would be called from
> >>>>>> rproc_tee_elf_load_rsc_table().  That way we don't need trproc->rsc_va.
> >>>>>>
> >>>>>> I also think tee_rproc should be renamed to "rproc_tee_interface" and folded
> >>>>>> under struct rproc.
> >>>>>>
> >>>>>> With the above most of the problems with the current implementation should
> >>>>>> naturally go away.
> >>>>>>
> >>>>>> Thanks,
> >>>>>> Mathieu
> >>>>>>
> >>>>>>>
> >>>>>>>>> +     ret = tee_rproc_load_fw(ddata->trproc, fw);
> >>>>>>>>> +     if (ret)
> >>>>>>>>> +             return ret;
> >>>>>>>>> +     ddata->fw_loaded = true;
> >>>>>>>>> +
> >>>>>>>>> +     /* Update the resource table parameters. */
> >>>>>>>>> +     if (rproc_tee_get_rsc_table(ddata->trproc)) {
> >>>>>>>>> +             /* No resource table: reset the related fields. */
> >>>>>>>>> +             rproc->cached_table = NULL;
> >>>>>>>>> +             rproc->table_ptr = NULL;
> >>>>>>>>> +             rproc->table_sz = 0;
> >>>>>>>>> +     }
> >>>>>>>>> +
> >>>>>>>>> +     return 0;
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +static struct resource_table *
> >>>>>>>>> +stm32_rproc_tee_elf_find_loaded_rsc_table(struct rproc *rproc,
> >>>>>>>>> +                                       const struct firmware *fw)
> >>>>>>>>> +{
> >>>>>>>>> +     struct stm32_rproc *ddata = rproc->priv;
> >>>>>>>>> +
> >>>>>>>>> +     return tee_rproc_get_loaded_rsc_table(ddata->trproc);
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +static int stm32_rproc_tee_start(struct rproc *rproc)
> >>>>>>>>> +{
> >>>>>>>>> +     struct stm32_rproc *ddata = rproc->priv;
> >>>>>>>>> +
> >>>>>>>>> +     return tee_rproc_start(ddata->trproc);
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +static int stm32_rproc_tee_attach(struct rproc *rproc)
> >>>>>>>>> +{
> >>>>>>>>> +     /* Nothing to do, remote proc already started by the secured context. */
> >>>>>>>>> +     return 0;
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +static int stm32_rproc_tee_stop(struct rproc *rproc)
> >>>>>>>>> +{
> >>>>>>>>> +     struct stm32_rproc *ddata = rproc->priv;
> >>>>>>>>> +     int err;
> >>>>>>>>> +
> >>>>>>>>> +     stm32_rproc_request_shutdown(rproc);
> >>>>>>>>> +
> >>>>>>>>> +     err = tee_rproc_stop(ddata->trproc);
> >>>>>>>>> +     if (err)
> >>>>>>>>> +             return err;
> >>>>>>>>> +
> >>>>>>>>> +     ddata->fw_loaded = false;
> >>>>>>>>> +
> >>>>>>>>> +     return stm32_rproc_release(rproc);
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>>  static int stm32_rproc_prepare(struct rproc *rproc)
> >>>>>>>>>  {
> >>>>>>>>>       struct device *dev = rproc->dev.parent;
> >>>>>>>>> @@ -319,7 +410,14 @@ static int stm32_rproc_prepare(struct rproc *rproc)
> >>>>>>>>>
> >>>>>>>>>  static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
> >>>>>>>>>  {
> >>>>>>>>> -     if (rproc_elf_load_rsc_table(rproc, fw))
> >>>>>>>>> +     struct stm32_rproc *ddata = rproc->priv;
> >>>>>>>>> +     int ret;
> >>>>>>>>> +
> >>>>>>>>> +     if (ddata->trproc)
> >>>>>>>>> +             ret = rproc_tee_get_rsc_table(ddata->trproc);
> >>>>>>>>> +     else
> >>>>>>>>> +             ret = rproc_elf_load_rsc_table(rproc, fw);
> >>>>>>>>> +     if (ret)
> >>>>>>>>>               dev_warn(&rproc->dev, "no resource table found for this firmware\n");
> >>>>>>>>>
> >>>>>>>>>       return 0;
> >>>>>>>>> @@ -693,8 +791,22 @@ static const struct rproc_ops st_rproc_ops = {
> >>>>>>>>>       .get_boot_addr  = rproc_elf_get_boot_addr,
> >>>>>>>>>  };
> >>>>>>>>>
> >>>>>>>>> +static const struct rproc_ops st_rproc_tee_ops = {
> >>>>>>>>> +     .prepare        = stm32_rproc_prepare,
> >>>>>>>>> +     .start          = stm32_rproc_tee_start,
> >>>>>>>>> +     .stop           = stm32_rproc_tee_stop,
> >>>>>>>>> +     .attach         = stm32_rproc_tee_attach,
> >>>>>>>>> +     .kick           = stm32_rproc_kick,
> >>>>>>>>> +     .parse_fw       = stm32_rproc_parse_fw,
> >>>>>>>>> +     .find_loaded_rsc_table = stm32_rproc_tee_elf_find_loaded_rsc_table,
> >>>>>>>>> +     .get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
> >>>>>>>>> +     .sanity_check   = stm32_rproc_tee_elf_sanity_check,
> >>>>>>>>> +     .load           = stm32_rproc_tee_elf_load,
> >>>>>>>>> +};
> >>>>>>>>> +
> >>>>>>>>>  static const struct of_device_id stm32_rproc_match[] = {
> >>>>>>>>> -     { .compatible = "st,stm32mp1-m4" },
> >>>>>>>>> +     {.compatible = "st,stm32mp1-m4",},
> >>>>>>>>> +     {.compatible = "st,stm32mp1-m4-tee",},
> >>>>>>>>>       {},
> >>>>>>>>>  };
> >>>>>>>>>  MODULE_DEVICE_TABLE(of, stm32_rproc_match);
> >>>>>>>>> @@ -853,6 +965,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>>>>>>>>       struct device *dev = &pdev->dev;
> >>>>>>>>>       struct stm32_rproc *ddata;
> >>>>>>>>>       struct device_node *np = dev->of_node;
> >>>>>>>>> +     struct tee_rproc *trproc = NULL;
> >>>>>>>>>       struct rproc *rproc;
> >>>>>>>>>       unsigned int state;
> >>>>>>>>>       int ret;
> >>>>>>>>> @@ -861,11 +974,31 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>>>>>>>>       if (ret)
> >>>>>>>>>               return ret;
> >>>>>>>>>
> >>>>>>>>> -     rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
> >>>>>>>>> -     if (!rproc)
> >>>>>>>>> -             return -ENOMEM;
> >>>>>>>>> +     if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
> >>>>>>>>> +             trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
> >>>>>>>>> +             if (IS_ERR(trproc)) {
> >>>>>>>>> +                     dev_err_probe(dev, PTR_ERR(trproc),
> >>>>>>>>> +                                   "signed firmware not supported by TEE\n");
> >>>>>>>>> +                     return PTR_ERR(trproc);
> >>>>>>>>> +             }
> >>>>>>>>> +             /*
> >>>>>>>>> +              * Delegate the firmware management to the secure context.
> >>>>>>>>> +              * The firmware loaded has to be signed.
> >>>>>>>>> +              */
> >>>>>>>>> +             dev_info(dev, "Support of signed firmware only\n");
> >>>>>>>>
> >>>>>>>> Not sure what this adds.  Please remove.
> >>>>>>>
> >>>>>>> This is used to inform the user that only a signed firmware can be loaded, not
> >>>>>>> an ELF file.
> >>>>>>> I have a patch in my pipe to provide the supported format in the debugfs. In a
> >>>>>>> first step, I can suppress this message and we can revisit the issue when I push
> >>>>>>> the debugfs proposal.
> >>>>>>>
> >>>>>>> Thanks,
> >>>>>>> Arnaud
> >>>>>>>
> >>>>>>>>
> >>>>>>>>> +     }
> >>>>>>>>> +     rproc = rproc_alloc(dev, np->name,
> >>>>>>>>> +                         trproc ? &st_rproc_tee_ops : &st_rproc_ops,
> >>>>>>>>> +                         NULL, sizeof(*ddata));
> >>>>>>>>> +     if (!rproc) {
> >>>>>>>>> +             ret = -ENOMEM;
> >>>>>>>>> +             goto free_tee;
> >>>>>>>>> +     }
> >>>>>>>>>
> >>>>>>>>>       ddata = rproc->priv;
> >>>>>>>>> +     ddata->trproc = trproc;
> >>>>>>>>> +     if (trproc)
> >>>>>>>>> +             trproc->rproc = rproc;
> >>>>>>>>>
> >>>>>>>>>       rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
> >>>>>>>>>
> >>>>>>>>> @@ -916,6 +1049,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>>>>>>>>               device_init_wakeup(dev, false);
> >>>>>>>>>       }
> >>>>>>>>>       rproc_free(rproc);
> >>>>>>>>> +free_tee:
> >>>>>>>>> +     if (trproc)
> >>>>>>>>> +             tee_rproc_unregister(trproc);
> >>>>>>>>> +
> >>>>>>>>>       return ret;
> >>>>>>>>>  }
> >>>>>>>>>
> >>>>>>>>> @@ -937,6 +1074,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
> >>>>>>>>>               device_init_wakeup(dev, false);
> >>>>>>>>>       }
> >>>>>>>>>       rproc_free(rproc);
> >>>>>>>>> +     if (ddata->trproc)
> >>>>>>>>> +             tee_rproc_unregister(ddata->trproc);
> >>>>>>>>>  }
> >>>>>>>>>
> >>>>>>>>>  static int stm32_rproc_suspend(struct device *dev)
> >>>>>>>>> --
> >>>>>>>>> 2.25.1
> >>>>>>>>>
> > _______________________________________________
> > Linux-stm32 mailing list
> > Linux-stm32 at st-md-mailman.stormreply.com
> > https://st-md-mailman.stormreply.com/mailman/listinfo/linux-stm32


From broonie at kernel.org  Tue Feb 13 10:44:58 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 18:44:58 +0000
Subject: [PATCH v2 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <20240202115330.wxkbfmvd76sy3a6a@runtux.com>
References: <20240202115330.wxkbfmvd76sy3a6a@runtux.com>
Message-ID: <170784989820.681459.6695714509639866106.b4-ty@kernel.org>

On Fri, 02 Feb 2024 12:53:30 +0100, Ralf Schlatterbeck wrote:
> There was a change in the mxs-dma engine that uses a new custom flag.
> The change was not applied to the mxs spi driver.
> This results in chipselect being deasserted too early.
> This fixes the chipselect problem by using the new flag in the mxs-spi
> driver.
> 
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi-mxs: Fix chipselect glitch
      commit: 269e31aecdd0b70f53a05def79480f15cbcc0fd6

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 conor at kernel.org  Tue Feb 13 10:52:01 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 13 Feb 2024 18:52:01 +0000
Subject: [PATCH] dt-bindings: dma: convert MediaTek High-Speed controller
 to the json-schema
In-Reply-To: <20240213063919.20196-1-zajec5@gmail.com>
References: <20240213063919.20196-1-zajec5@gmail.com>
Message-ID: <20240213-dandy-snowflake-1dabe0e88b3a@spud>

On Tue, Feb 13, 2024 at 07:39:19AM +0100, Rafa? Mi?ecki wrote:

> +  "#dma-cells":
> +    description: Channel number

I think you can just remove this description if you end up doing a
resubmission for some reason, but this looks good to me.
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.
-------------- 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/20240213/d618b072/attachment.sig>

From broonie at kernel.org  Tue Feb 13 10:55:00 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 18:55:00 +0000
Subject: [PATCH 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
 <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com>
Message-ID: <54623b74-872a-41dc-992f-71a586d145ec@sirena.org.uk>

On Mon, Feb 12, 2024 at 05:26:41PM -0600, David Lechner wrote:

> This adds a new spi_optimize_message() function that can be used to
> optimize SPI messages that are used more than once. Peripheral drivers
> that use the same message multiple times can use this API to perform SPI
> message validation and controller-specific optimizations once and then
> reuse the message while avoiding the overhead of revalidating the
> message on each spi_(a)sync() call.

This looks basically fine.  Some small comments:

> +/**
> + * __spi_unoptimize_message - shared implementation of spi_unoptimize_message()
> + *                            and spi_maybe_unoptimize_message()
> + * @msg: the message to unoptimize

There's no need for kerneldoc for internal only functions and it can
make the generated documentation a bit confusing for users.  Just skip
the /** for /*.

> +static int __spi_optimize_message(struct spi_device *spi,
> +				  struct spi_message *msg,
> +				  bool pre_optimized)
> +{
> +	struct spi_controller *ctlr = spi->controller;
> +	int ret;
> +
> +	ret = __spi_validate(spi, msg);
> +	if (ret)
> +		return ret;
> +
> +	if (ctlr->optimize_message) {
> +		ret = ctlr->optimize_message(msg);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	msg->pre_optimized = pre_optimized;

It would probably be clearer to name the parameter pre_optimising rather
than pre_optimized, as it is the logic is a bit confusing.  Either that
or some comments.  A similar issue applies on the cleanup path.
-------------- 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/20240213/1680805c/attachment.sig>

From dlechner at baylibre.com  Tue Feb 13 10:59:01 2024
From: dlechner at baylibre.com (David Lechner)
Date: Tue, 13 Feb 2024 12:59:01 -0600
Subject: [PATCH 5/5] iio: adc: ad7380: use spi_optimize_message()
In-Reply-To: <20240213173110.00007855@Huawei.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
 <20240212-mainline-spi-precook-message-v1-5-a2373cd72d36@baylibre.com>
 <c06dfa1ecf88b07ef467ad7c08667d0cab400613.camel@gmail.com>
 <CAMknhBEU=iMzpE_P0KePL4cZZktBOGHRXaEox5a7XcVjXDT+Dg@mail.gmail.com>
 <e03968102b92b3711808eb532685bc9e05fc3c8d.camel@gmail.com> <20240213173110.00007855@Huawei.com>
Message-ID: <CAMknhBFQLvaTcFAt_LqEsDYvMDOwFo3u0xkt7fOsgL0tcmoX6Q@mail.gmail.com>

On Tue, Feb 13, 2024 at 11:31?AM Jonathan Cameron
<Jonathan.Cameron at huawei.com> wrote:
>
> On Tue, 13 Feb 2024 17:08:19 +0100
> Nuno S? <noname.nuno at gmail.com> wrote:
>
> > On Tue, 2024-02-13 at 09:27 -0600, David Lechner wrote:
> > > On Tue, Feb 13, 2024 at 3:47?AM Nuno S? <noname.nuno at gmail.com> wrote:
> > > >

...

> > > > Am I missing something?
> > >
> > > No, your understanding is correct for the current state of everything
> > > in this series. So, we could do as you suggest, but I have a feeling
> > > that future additions to this driver might require that it gets
> > > changed back this way eventually.
> >
> > Hmm, not really sure about that as chip_info stuff is always our friend :). And
> > I'm anyways of the opinion of keeping things simpler and start to evolve when
> > really needed (because often we never really need to evolve). But bah, as I
> > said... this is really not a big deal.
> >
> Oops should have read Nuno's review before replying!
>
> I'd rather we embedded it for now and did the optimization at probe.
> Whilst it's a lot of work per transfer it's not enough to worry about delaying
> it until preenable().  Easy to make that move and take it dynamic when
> driver changes need it.  In meantime, I don't want lots of other drivers
> picking up this pattern when they may never need the complexity of
> making things more dynamic.
>

Noted.


From heiko at sntech.de  Tue Feb 13 11:01:40 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 20:01:40 +0100
Subject: [PATCH v6 31/36] drm/rockchip: inno_hdmi: Switch to HDMI connector
In-Reply-To: <20240212-kms-hdmi-connector-state-v6-31-f4bcdc979e6f@kernel.org>
References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org>
 <20240212-kms-hdmi-connector-state-v6-31-f4bcdc979e6f@kernel.org>
Message-ID: <1852174.atdPhlSkOF@phil>

Am Montag, 12. Februar 2024, 14:13:14 CET schrieb Maxime Ripard:
> The new HDMI connector infrastructure allows to remove some boilerplate,
> especially to generate infoframes. Let's switch to it.
> 
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Acked-by: Heiko Stuebner <heiko at sntech.de>

> ---
>  drivers/gpu/drm/rockchip/inno_hdmi.c | 123 ++++++++++++-----------------------
>  1 file changed, 42 insertions(+), 81 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
> index 1d2261643743..d59947679042 100644
> --- a/drivers/gpu/drm/rockchip/inno_hdmi.c
> +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
> @@ -67,9 +67,7 @@ struct inno_hdmi {
>  
>  struct inno_hdmi_connector_state {
>  	struct drm_connector_state	base;
> -	unsigned int			enc_out_format;
>  	unsigned int			colorimetry;
> -	bool				rgb_limited_range;
>  };
>  
>  static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
> @@ -257,26 +255,29 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
>  	inno_hdmi_standby(hdmi);
>  }
>  
> -static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
> -				    enum hdmi_infoframe_type type)
> +static int inno_hdmi_disable_frame(struct drm_connector *connector,
> +				   enum hdmi_infoframe_type type)
>  {
> -	struct drm_connector *connector = &hdmi->connector;
> +	struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
>  
>  	if (type != HDMI_INFOFRAME_TYPE_AVI) {
>  		drm_err(connector->dev,
>  			"Unsupported infoframe type: %u\n", type);
> -		return;
> +		return 0;
>  	}
>  
>  	hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
> +
> +	return 0;
>  }
>  
> -static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
> -				  union hdmi_infoframe *frame, enum hdmi_infoframe_type type)
> +static int inno_hdmi_upload_frame(struct drm_connector *connector,
> +				  enum hdmi_infoframe_type type,
> +				  const u8 *buffer, size_t len)
>  {
> -	struct drm_connector *connector = &hdmi->connector;
> +	struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
>  	u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
> -	ssize_t rc, i;
> +	ssize_t i;
>  
>  	if (type != HDMI_INFOFRAME_TYPE_AVI) {
>  		drm_err(connector->dev,
> @@ -284,59 +285,19 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
>  		return 0;
>  	}
>  
> -	inno_hdmi_disable_frame(hdmi, type);
> +	inno_hdmi_disable_frame(connector, type);
>  
> -	rc = hdmi_infoframe_pack(frame, packed_frame,
> -				 sizeof(packed_frame));
> -	if (rc < 0)
> -		return rc;
> -
> -	for (i = 0; i < rc; i++)
> +	for (i = 0; i < len; i++)
>  		hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
>  			    packed_frame[i]);
>  
>  	return 0;
>  }
>  
> -static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
> -				      struct drm_display_mode *mode)
> -{
> -	struct drm_connector *connector = &hdmi->connector;
> -	struct drm_connector_state *conn_state = connector->state;
> -	struct inno_hdmi_connector_state *inno_conn_state =
> -					to_inno_hdmi_conn_state(conn_state);
> -	union hdmi_infoframe frame;
> -	int rc;
> -
> -	rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
> -						      &hdmi->connector,
> -						      mode);
> -	if (rc) {
> -		inno_hdmi_disable_frame(hdmi, HDMI_INFOFRAME_TYPE_AVI);
> -		return rc;
> -	}
> -
> -	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444)
> -		frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
> -	else if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV422)
> -		frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
> -	else
> -		frame.avi.colorspace = HDMI_COLORSPACE_RGB;
> -
> -	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
> -		drm_hdmi_avi_infoframe_quant_range(&frame.avi,
> -						   connector, mode,
> -						   inno_conn_state->rgb_limited_range ?
> -						   HDMI_QUANTIZATION_RANGE_LIMITED :
> -						   HDMI_QUANTIZATION_RANGE_FULL);
> -	} else {
> -		frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
> -		frame.avi.ycc_quantization_range =
> -			HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
> -	}
> -
> -	return inno_hdmi_upload_frame(hdmi, &frame, HDMI_INFOFRAME_TYPE_AVI);
> -}
> +static const struct drm_connector_hdmi_funcs inno_hdmi_hdmi_connector_funcs = {
> +	.clear_infoframe	= inno_hdmi_disable_frame,
> +	.write_infoframe	= inno_hdmi_upload_frame,
> +};
>  
>  static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
>  {
> @@ -361,8 +322,8 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
>  		v_VIDEO_INPUT_CSP(0);
>  	hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
>  
> -	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
> -		if (inno_conn_state->rgb_limited_range) {
> +	if (conn_state->hdmi.output_format == HDMI_COLORSPACE_RGB) {
> +		if (!conn_state->hdmi.is_full_range) {
>  			csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
>  			auto_csc = AUTO_CSC_DISABLE;
>  			c0_c2_change = C0_C2_CHANGE_DISABLE;
> @@ -380,14 +341,14 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
>  		}
>  	} else {
>  		if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
> -			if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
> +			if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) {
>  				csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
>  				auto_csc = AUTO_CSC_DISABLE;
>  				c0_c2_change = C0_C2_CHANGE_DISABLE;
>  				csc_enable = v_CSC_ENABLE;
>  			}
>  		} else {
> -			if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
> +			if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) {
>  				csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
>  				auto_csc = AUTO_CSC_DISABLE;
>  				c0_c2_change = C0_C2_CHANGE_DISABLE;
> @@ -462,10 +423,12 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
>  }
>  
>  static int inno_hdmi_setup(struct inno_hdmi *hdmi,
> -			   struct drm_display_mode *mode)
> +			   struct drm_crtc_state *new_crtc_state,
> +			   struct drm_connector_state *new_conn_state)
>  {
> -	struct drm_display_info *display = &hdmi->connector.display_info;
> -	unsigned long mpixelclock = mode->clock * 1000;
> +	struct drm_connector *connector = &hdmi->connector;
> +	struct drm_display_info *display = &connector->display_info;
> +	struct drm_display_mode *mode = &new_crtc_state->adjusted_mode;
>  
>  	/* Mute video and audio output */
>  	hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
> @@ -479,8 +442,8 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
>  
>  	inno_hdmi_config_video_csc(hdmi);
>  
> -	if (display->is_hdmi)
> -		inno_hdmi_config_video_avi(hdmi, mode);
> +	drm_atomic_helper_connector_hdmi_update_infoframes(connector,
> +							   new_conn_state->state);
>  
>  	/*
>  	 * When IP controller have configured to an accurate video
> @@ -488,13 +451,13 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
>  	 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
>  	 * clock rate, and reconfigure the DDC clock.
>  	 */
> -	inno_hdmi_i2c_init(hdmi, mpixelclock);
> +	inno_hdmi_i2c_init(hdmi, new_conn_state->hdmi.tmds_char_rate);
>  
>  	/* Unmute video and audio output */
>  	hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
>  		  v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
>  
> -	inno_hdmi_power_up(hdmi, mpixelclock);
> +	inno_hdmi_power_up(hdmi, new_conn_state->hdmi.tmds_char_rate);
>  
>  	return 0;
>  }
> @@ -546,7 +509,7 @@ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
>  	if (WARN_ON(!crtc_state))
>  		return;
>  
> -	inno_hdmi_setup(hdmi, &crtc_state->adjusted_mode);
> +	inno_hdmi_setup(hdmi, crtc_state, conn_state);
>  }
>  
>  static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
> @@ -563,7 +526,6 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
>  			       struct drm_connector_state *conn_state)
>  {
>  	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
> -	struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
>  	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
>  	u8 vic = drm_match_cea_mode(mode);
>  	struct inno_hdmi_connector_state *inno_conn_state =
> @@ -580,12 +542,7 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
>  	else
>  		inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
>  
> -	inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
> -	inno_conn_state->rgb_limited_range =
> -		drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED;
> -
> -	return  inno_hdmi_display_mode_valid(hdmi,
> -				&crtc_state->adjusted_mode) == MODE_OK ? 0 : -EINVAL;
> +	return 0;
>  }
>  
>  static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
> @@ -662,10 +619,9 @@ static void inno_hdmi_connector_reset(struct drm_connector *connector)
>  		return;
>  
>  	__drm_atomic_helper_connector_reset(connector, &inno_conn_state->base);
> +	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
>  
>  	inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
> -	inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
> -	inno_conn_state->rgb_limited_range = false;
>  }
>  
>  static struct drm_connector_state *
> @@ -698,6 +654,7 @@ static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
>  };
>  
>  static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
> +	.atomic_check = drm_atomic_helper_connector_hdmi_check,
>  	.get_modes = inno_hdmi_connector_get_modes,
>  	.mode_valid = inno_hdmi_connector_mode_valid,
>  };
> @@ -725,10 +682,14 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
>  
>  	drm_connector_helper_add(&hdmi->connector,
>  				 &inno_hdmi_connector_helper_funcs);
> -	drm_connector_init_with_ddc(drm, &hdmi->connector,
> -				    &inno_hdmi_connector_funcs,
> -				    DRM_MODE_CONNECTOR_HDMIA,
> -				    hdmi->ddc);
> +	drmm_connector_hdmi_init(drm, &hdmi->connector,
> +				 "Rockchip", "Inno HDMI",
> +				 &inno_hdmi_connector_funcs,
> +				 &inno_hdmi_hdmi_connector_funcs,
> +				 DRM_MODE_CONNECTOR_HDMIA,
> +				 hdmi->ddc,
> +				 BIT(HDMI_COLORSPACE_RGB),
> +				 8);
>  
>  	drm_connector_attach_encoder(&hdmi->connector, encoder);
>  
> 
> 






From sven at svenpeter.dev  Tue Feb 13 11:13:34 2024
From: sven at svenpeter.dev (Sven Peter)
Date: Tue, 13 Feb 2024 20:13:34 +0100
Subject: [PATCH] i2c: pasemi: split driver into two separate modules
In-Reply-To: <20240212111933.963985-1-arnd@kernel.org>
References: <20240212111933.963985-1-arnd@kernel.org>
Message-ID: <A4AE8C4C-C37E-4026-A3CC-E613754307D6@svenpeter.dev>


> 
> On 12. Feb 2024, at 12:19, Arnd Bergmann <arnd at kernel.org> wrote:
> 
> ?From: Arnd Bergmann <arnd at arndb.de>
> 
> On powerpc, it is possible to compile test both the new apple (arm) and
> old pasemi (powerpc) drivers for the i2c hardware at the same time,
> which leads to a warning about linking the same object file twice:
> 
> scripts/Makefile.build:244: drivers/i2c/busses/Makefile: i2c-pasemi-core.o is added to multiple modules: i2c-apple i2c-pasemi
> 
> Rework the driver to have an explicit helper module, letting Kbuild
> take care of whether this should be built-in or a loadable driver.
> 
> Fixes: 9bc5f4f660ff ("i2c: pasemi: Split pci driver to its own file")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> ---

Reviewed-by: Sven Peter <sven at svenpeter.dev>

thanks, totally forgot about this!


Sven


> drivers/i2c/busses/Makefile          | 6 ++----
> drivers/i2c/busses/i2c-pasemi-core.c | 6 ++++++
> 2 files changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
> index 3757b9391e60..aa0ee8ecd6f2 100644
> --- a/drivers/i2c/busses/Makefile
> +++ b/drivers/i2c/busses/Makefile
> @@ -90,10 +90,8 @@ obj-$(CONFIG_I2C_NPCM)        += i2c-npcm7xx.o
> obj-$(CONFIG_I2C_OCORES)    += i2c-ocores.o
> obj-$(CONFIG_I2C_OMAP)        += i2c-omap.o
> obj-$(CONFIG_I2C_OWL)        += i2c-owl.o
> -i2c-pasemi-objs := i2c-pasemi-core.o i2c-pasemi-pci.o
> -obj-$(CONFIG_I2C_PASEMI)    += i2c-pasemi.o
> -i2c-apple-objs := i2c-pasemi-core.o i2c-pasemi-platform.o
> -obj-$(CONFIG_I2C_APPLE)    += i2c-apple.o
> +obj-$(CONFIG_I2C_PASEMI)    += i2c-pasemi-core.o i2c-pasemi-pci.o
> +obj-$(CONFIG_I2C_APPLE)        += i2c-pasemi-core.o i2c-pasemi-platform.o
> obj-$(CONFIG_I2C_PCA_PLATFORM)    += i2c-pca-platform.o
> obj-$(CONFIG_I2C_PNX)        += i2c-pnx.o
> obj-$(CONFIG_I2C_PXA)        += i2c-pxa.o
> diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
> index 7d54a9f34c74..bd8becbdeeb2 100644
> --- a/drivers/i2c/busses/i2c-pasemi-core.c
> +++ b/drivers/i2c/busses/i2c-pasemi-core.c
> @@ -369,6 +369,7 @@ int pasemi_i2c_common_probe(struct pasemi_smbus *smbus)
> 
>   return 0;
> }
> +EXPORT_SYMBOL_GPL(pasemi_i2c_common_probe);
> 
> irqreturn_t pasemi_irq_handler(int irq, void *dev_id)
> {
> @@ -378,3 +379,8 @@ irqreturn_t pasemi_irq_handler(int irq, void *dev_id)
>   complete(&smbus->irq_completion);
>   return IRQ_HANDLED;
> }
> +EXPORT_SYMBOL_GPL(pasemi_irq_handler);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Olof Johansson <olof at lixom.net>");
> +MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver");
> --
> 2.39.2



From conor at kernel.org  Tue Feb 13 11:13:57 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 13 Feb 2024 19:13:57 +0000
Subject: [PATCH v2] dt-bindings: interrupt-controller: Convert Atmel AIC
 to json-schema
In-Reply-To: <003d61c9-b914-4e1c-b3f8-1140ea640039@microchip.com>
References: <20240209100122.61335-1-dharma.b@microchip.com>
 <20240212140824.GA107736-robh@kernel.org>
 <003d61c9-b914-4e1c-b3f8-1140ea640039@microchip.com>
Message-ID: <20240213-estranged-charger-bf0372f367e0@spud>

On Tue, Feb 13, 2024 at 04:23:36AM +0000, Dharma.B at microchip.com wrote:
> On 12/02/24 7:38 pm, Rob Herring wrote:
> > On Fri, Feb 09, 2024 at 03:31:22PM +0530, Dharma Balasubiramani wrote:
> >> +  atmel,external-irqs:
> >> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> >> +    description: u32 array of external irqs.
> > 
> > Constraints on the array size and/or entry values?
> 
> The hardware's support for external IRQs may differ, which is why a u32 
> array is utilized. This choice is based on the fact that IRQ numbers are 
> commonly expressed as integers, and a 32-bit unsigned integer provides a 
> standardized size capable of representing a broad range of numbers. This 
> size is more than adequate for accommodating IRQ numbering.

I don't think Rob was questioning your use of u32s, but rather the fact
that you do not limit the values at all nor the number of values.
-------------- 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/20240213/9c7c1fe0/attachment.sig>

From mbland at motorola.com  Tue Feb 13 11:15:07 2024
From: mbland at motorola.com (Maxwell Bland)
Date: Tue, 13 Feb 2024 19:15:07 +0000
Subject: [PATCH] arm64: allow post-init vmalloc PXNTable
In-Reply-To: <ZcurbvkUR-BoGTxu@FVFF77S0Q05N.cambridge.arm.com>
References: <CAP5Mv+ydhk=Ob4b40ZahGMgT-5+-VEHxtmA=-LkJiEOOU+K6hw@mail.gmail.com>
 <ZcurbvkUR-BoGTxu@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <SEZPR03MB67865557061A2494B1A1243CB44F2@SEZPR03MB6786.apcprd03.prod.outlook.com>

> From: Mark Rutland <mark.rutland at arm.com> On Tue, Feb 13, 2024 at 10:05:45AM
> -0600, Maxwell Bland wrote:
> > VMALLOC_START ffff800080000000 VMALLOC_END fffffbfff0000000 _text
> > ffffb6c0c1400000 _end        ffffb6c0c3e40000
> >
> > Setting VMALLOC_END to _text in init would resolve this issue with the
> > caveat of a sizeable reduction in the size of available vmalloc memory due
> > to requirements on aslr randomness. However, there are circumstances where
> > this trade-off is necessary: in particular, hypervisor-level security
> > monitors where 1) the microarchitecture contains race conditions on PTE
> > level updates or 2) a per-PTE update verifier comes at a significant hit to
> > performance.
>
> Which "hypervisor-level security monitors" are you referring to?

Right now there are around 4 or 5 different attempts (from what I know: Moto,
Samsung, MediaTek, and Qualcomm) at making page tables immutable and reducing
the kernel threat surface to just dynamically allocated structs, e.g.
file_operations, in ARM, a revival of some of the ideas of:

https://wenboshen.org/publications/papers/tz-rkp-ccs14.pdf

Which are no longer possible to enforce for a number of reasons.  As related to
this patch in particular: the performance hits involved in per-PTE update
verification are huge.

My goal is ultimately to prevent modern exploits like:

https://github.com/chompie1337/s8_2019_2215_poc

which modify dynamically allocated pointers, but trying to protect against these
exploits is disingenuous without first being able to enforce PXN on non-code
pages, i.e. there is a reason we do this in mm initialization, but we need to
enforce or support the enforcement of PXNTable dynamically too.

> We don't support any of those upstream AFAIK.

As is hopefully apparent from the above, though it will help downstream systems,
I do not see this patch as a support issue so much as a legitimate security
feature. There is the matter of deciding which subsystem should be responsible.

The generic vmalloc interface should provide a strong distinction between code
and data allocations, but enforcing this would become the responsibility of each
microarchitecture regardless.

>
> How much VA space are you potentially throwing away?
>

This is rough, I admit. )-: On the order of 70,000 GB, likely more in practice:
it restricts vmalloc to the region before _text. You may be thinking, "that is
ridiculous, c'mon Maxwell", and you would be right, but I was OK with this
trade-off for Moto systems, and was thinking the approach keeps the patch
changes small and simple.

I had a hard time thinking of a better way to do this while avoiding duplication
of vmalloc code into arm64 land. Potentially, though, it would be OK to add an
additional field to the generic vmalloc interface? I may need to reach out for
help here: maybe the solution to the issue will come more readily to those with
more experience.

> How does this work with other allocations of executable memory? e.g.  modules,
> BPF?

It should work.

- arch/arm64/kernel/module.c uses __vmalloc_node_range with module_alloc_base
  and module_alloc_end, bypassing the generic vmalloc_node region, and these
  variables are decided based on a random offset between _text and _end.
- kernel/bpf/core.c uses bpf_jit_alloc_exec to create executable code regions,
  which is a wrapper for module_alloc. In the interpreted BPF case, we do not
  need to worry since the pages storing interpreted code are NX and can be
  marked PXNTable regardless.

> I'm not keen on this as-is.

That's OK, so long as we agree enforcing PXNTable dynamically would be a good
thing. I look forward to your thoughts on the above, and I will go back and
iterate.

Working with IT to fix the email formatting now, so I will hopefully be able to
post a fetchable and runnable version of my initial patch shortly.

From heiko at sntech.de  Tue Feb 13 11:16:16 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 20:16:16 +0100
Subject: [PATCH] arm64: dts: rockchip: set num-cs property for spi on px30
In-Reply-To: <20240119101656.965744-1-heiko@sntech.de>
References: <20240119101656.965744-1-heiko@sntech.de>
Message-ID: <170785172859.3347621.5058867416491288233.b4-ty@sntech.de>

On Fri, 19 Jan 2024 11:16:56 +0100, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> The px30 has two spi controllers with two chip-selects each.
> The num-cs property is specified as the total number of chip
> selects a controllers has and is used since 2020 to find uses
> of chipselects outside that range in the Rockchip spi driver.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: set num-cs property for spi on px30
      commit: 334bf0710c98d391f4067b72f535d6c4c84dfb6f

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Tue Feb 13 11:16:17 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 20:16:17 +0100
Subject: [PATCH v1] arm64: dts: rockchip: rk3328: Drop interrupts property from pwm-rockchip nodes
In-Reply-To: <5551846d-62cd-4b72-94f4-07541e726c37@gmail.com>
References: <5551846d-62cd-4b72-94f4-07541e726c37@gmail.com>
Message-ID: <170785172859.3347621.16554815233925268437.b4-ty@sntech.de>

On Mon, 5 Feb 2024 00:16:43 +0100, Johan Jonker wrote:
> The binding doesn't define interrupts and adding such a definition was
> refused because it's unclear how they should ever be used and the
> relevant registers are outside the PWM range. So drop them fixing
> several dtbs_check warnings.
> 
> 

Applied, thanks!

[1/1] arm64: dts: rockchip: rk3328: Drop interrupts property from pwm-rockchip nodes
      commit: 1bbd894e2ae67faf52632bc9290ff926d9b741ea

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Tue Feb 13 11:16:19 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 20:16:19 +0100
Subject: [PATCH] arm64: dts: rk3588: minor whitespace cleanup
In-Reply-To: <20240208105129.128561-1-krzysztof.kozlowski@linaro.org>
References: <20240208105129.128561-1-krzysztof.kozlowski@linaro.org>
Message-ID: <170785172858.3347621.3639452641350737104.b4-ty@sntech.de>

On Thu, 8 Feb 2024 11:51:29 +0100, Krzysztof Kozlowski wrote:
> The DTS code coding style expects exactly one space before '{'
> character.
> 
> 

Applied, thanks!

[1/1] arm64: dts: rk3588: minor whitespace cleanup
      commit: 00890f5d15f50bd386bf222ddee355cec6c6d53a

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Tue Feb 13 11:16:15 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 20:16:15 +0100
Subject: [PATCH v6 0/2] serial: 8250: Add support for rs485 half/full duplex on puma/ringneck-haikou
In-Reply-To: <20240208-dev-rx-enable-v6-0-39e68e17a339@theobroma-systems.com>
References: <20240208-dev-rx-enable-v6-0-39e68e17a339@theobroma-systems.com>
Message-ID: <170785172857.3347621.5386366884287991661.b4-ty@sntech.de>

On Thu, 08 Feb 2024 16:39:54 +0100, Farouk Bouabid wrote:
> On the boards that we are using (ringneck/puma-haikou) a hardware switch
> can set the rs485 transceiver into half or full duplex mode.
> 
> In half-duplex mode the DE/RE signal of the rs485 transceiver is not
> connected to an RTS signal whose control is already handled in the rs485
> emulation (start/stop callbacks), but rather to a gpio. And since enabling
> the receiver requires setting this gpio active we need to do that in em485
> while receiving and disable it while sending to enable the driver mode.
> 
> [...]

Applied, thanks!

[1/2] arm64: dts: rockchip: rk3399-puma-haikou: add rs485 support on uart2
      commit: 54448f711aa32f176534bbd7b1903cc6d1c8a50d
[2/2] arm64: dts: rockchip: px30-ringneck-haikou: add rs485 support on uart5
      commit: 5963d97aa780619ffb66cf4886c0ca1175ccbd3e

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Tue Feb 13 11:16:18 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 20:16:18 +0100
Subject: [PATCH] arm64: dts: rockchip: rk3588: remove redundant cd-gpios in sdmmc node
In-Reply-To: <20240201034621.1970279-1-kever.yang@rock-chips.com>
References: <20240201034621.1970279-1-kever.yang@rock-chips.com>
Message-ID: <170785172862.3347621.15441860587856403205.b4-ty@sntech.de>

On Thu, 1 Feb 2024 11:46:21 +0800, Kever Yang wrote:
> The sdmmc node already have a "&sdmmc_det" for pinctrl which switch the
> GPIO0A4 to sdmmc detect function, no need to define a separate "cd-gpios".
> 
> RK3588 has force_jtage feature which is enable JTAG function via sdmmc
> pins automatically when there is no SD card insert, this feature will
> need the GPIO0A4 works in sdmmc_det function like other mmc signal instead
> of GPIO function, or else the force_jtag can not auto be disabled when
> SD card insert.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: rk3588: remove redundant cd-gpios in sdmmc node
      commit: d859ad305ed19d9a77d8c8ecd22459b73da36ba6

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From maz at kernel.org  Tue Feb 13 11:18:48 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 13 Feb 2024 19:18:48 +0000
Subject: WARNING: arch/arm64/kernel/cpufeature.c:3369 this_cpu_has_cap
In-Reply-To: <CA+G9fYuVJ3DfmOR2GxbVmLqh_d=3y_wTXX-vQOUgp86uX-3oGg@mail.gmail.com>
References: <CA+G9fYuVJ3DfmOR2GxbVmLqh_d=3y_wTXX-vQOUgp86uX-3oGg@mail.gmail.com>
Message-ID: <87il2sw4tj.wl-maz@kernel.org>

On Tue, 13 Feb 2024 18:21:23 +0000,
Naresh Kamboju <naresh.kamboju at linaro.org> wrote:
> 
> Following kernel warning notices on all arm64 devices on today's Linux
> next-20240213 tag.
> 
> Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>

What is the sense of this tag, and even of this email, for an issue
that has already been reported, as outlined below?

> 
> [    0.038524] SMP: Total of 6 processors activated.
> [    0.038539] CPU: All CPU(s) started at EL2
> [    0.038588] CPU features: detected: 32-bit EL0 Support
> [    0.038602] CPU features: detected: 32-bit EL1 Support
> [    0.038620] CPU features: detected: CRC32 instructions
> [    0.038650] ------------[ cut here ]------------
> [    0.038656] WARNING: CPU: 0 PID: 1 at
> arch/arm64/kernel/cpufeature.c:3369 this_cpu_has_cap+0x1c/0x70
> [    0.038691] Modules linked in:
> [    0.038707] CPU: 0 PID: 1 Comm: swapper/0 Not tainted
> 6.8.0-rc4-next-20240213 #1
> [    0.038721] Hardware name: Radxa ROCK Pi 4B (DT)
> [    0.038729] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [    0.038744] pc : this_cpu_has_cap+0x1c/0x70
> [    0.038761] lr : has_nv1+0x28/0xe8
> ..
> [    0.039008] Call trace:
> [    0.039014]  this_cpu_has_cap+0x1c/0x70
> [    0.039031]  update_cpu_capabilities+0xd4/0x138
> [    0.039048]  setup_system_features+0x38/0x130
> [    0.039075]  smp_cpus_done+0x50/0xc8
> [    0.039094]  smp_init+0x84/0xa0
> [    0.039109]  kernel_init_freeable+0x11c/0x400
> [    0.039126]  kernel_init+0x28/0x1f0
> [    0.039148]  ret_from_fork+0x10/0x20
> [    0.039167] ---[ end trace 0000000000000000 ]---
> 
> 
> Links:
>  - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240213/testrun/22596318/suite/log-parser-boot/test/check-kernel-exception/log
>  - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240213/testrun/22596318/suite/log-parser-boot/tests/
> 
> This issue has been addressed in the relevant email thread,
> https://lore.kernel.org/all/0593516b-2419-49b7-83aa-fe189ffad0c2 at arm.com/

Correct link:

https://lore.kernel.org/all/86bk8k5ts3.wl-maz at kernel.org/

> I will test the corresponding fix patch and get back to you.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From heiko at sntech.de  Tue Feb 13 11:20:01 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 20:20:01 +0100
Subject: (subset) [PATCH v2 1/6] dt-bindings: display: rockchip: rockchip,dw-hdmi: remove port property
In-Reply-To: <a493c65e-7cf9-455f-95d5-8c98cad35710@gmail.com>
References: <a493c65e-7cf9-455f-95d5-8c98cad35710@gmail.com>
Message-ID: <170785199080.3350387.14199175297568955666.b4-ty@sntech.de>

On Wed, 31 Jan 2024 22:14:29 +0100, Johan Jonker wrote:
> The hdmi-connector nodes are now functional and the new way to model
> hdmi ports nodes with both in and output port subnodes. Unfortunately
> with the conversion to YAML the old method with only an input port node
> was used. Later the new method was also added to the binding.
> A binding must be unambiguously, so remove the old port property
> entirely and make port at 0 and port at 1 a requirement as all
> upstream dts files are updated as well and because checking
> deprecated stuff is a bit pointless.
> Update the example to avoid use of the removed property.
> 
> [...]

Applied, thanks!

[1/6] dt-bindings: display: rockchip: rockchip,dw-hdmi: remove port property
      commit: 0d192c4c72ce00ab07a6b27f068607e21f754a46
[2/6] dt-bindings: display: rockchip,dw-hdmi: add power-domains property
      commit: 6b1f93ea345947c94bf3a7a6e668a2acfd310918

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From dlechner at baylibre.com  Tue Feb 13 11:20:31 2024
From: dlechner at baylibre.com (David Lechner)
Date: Tue, 13 Feb 2024 13:20:31 -0600
Subject: [PATCH 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <20240213172550.000023a7@Huawei.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
 <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com> <20240213172550.000023a7@Huawei.com>
Message-ID: <CAMknhBHc5LnaOOYoeCvtDvUcSXzPnHUtkheYMt73Uv5512dJVg@mail.gmail.com>

On Tue, Feb 13, 2024 at 11:25?AM Jonathan Cameron
<Jonathan.Cameron at huawei.com> wrote:
>
>
> I thought about suggesting splitting this into an initial patch that just does
> the bits without the controller callbacks. Maybe it would work better that way
> with that introduced after the validate and splitting of transfers (so most
> of patches 1 and 2) as a patch 3 prior to the stm32 additions?

Unless anyone else feels the same way, I'm inclined to avoid the extra
work of splitting it up.


> > +static void __spi_unoptimize_message(struct spi_message *msg)
> > +{
> > +     struct spi_controller *ctlr = msg->spi->controller;
> > +
> > +     if (ctlr->unoptimize_message)
> > +             ctlr->unoptimize_message(msg);
> > +
> > +     msg->optimized = false;
> > +     msg->opt_state = NULL;
> > +}
>
> Seems misbalanced that this doesn't take a pre_optimized flag in but
> __spi_optimize does. I'd move handling that to outside the call in both cases.
>
>

Agreed.


> > @@ -4331,10 +4463,15 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message)
> >               return -ESHUTDOWN;
> >       }
> >
> > -     status = __spi_validate(spi, message);
> > -     if (status != 0)
> > +     status = spi_maybe_optimize_message(spi, message);
> > +     if (status)
> >               return status;
> >
> > +     /*
> > +      * NB: all return paths after this point must ensure that
> > +      * spi_finalize_current_message() is called to avoid leaking resources.
>
> I'm not sure a catch all like that makes sense. Not sufficient to call
> the finer grained spi_maybe_unoptimize_message()  ?

Hmm... this is my bias from a previous fix showing through. Maybe this
comment doesn't belong in this patch. The short answer to your
question is "it's complicated".


From robh at kernel.org  Tue Feb 13 11:20:52 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 13:20:52 -0600
Subject: [PATCH v10 2/4] dt-bindings: remoteproc: add Tightly Coupled
 Memory (TCM) bindings
In-Reply-To: <20240213175450.3097308-3-tanmay.shah@amd.com>
References: <20240213175450.3097308-1-tanmay.shah@amd.com>
 <20240213175450.3097308-3-tanmay.shah@amd.com>
Message-ID: <170785205177.2155555.1311787541370066483.robh@kernel.org>


On Tue, 13 Feb 2024 09:54:48 -0800, Tanmay Shah wrote:
> From: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
> 
> Introduce bindings for TCM memory address space on AMD-xilinx Zynq
> UltraScale+ platform. It will help in defining TCM in device-tree
> and make it's access platform agnostic and data-driven.
> 
> Tightly-coupled memories(TCMs) are low-latency memory that provides
> predictable instruction execution and predictable data load/store
> timing. Each Cortex-R5F processor contains two 64-bit wide 64 KB memory
> banks on the ATCM and BTCM ports, for a total of 128 KB of memory.
> 
> The TCM resources(reg, reg-names and power-domain) are documented for
> each TCM in the R5 node. The reg and reg-names are made as required
> properties as we don't want to hardcode TCM addresses for future
> platforms and for zu+ legacy implementation will ensure that the
> old dts w/o reg/reg-names works and stable ABI is maintained.
> 
> It also extends the examples for TCM split and lockstep modes.
> 
> Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
> Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
> ---
> 
> Changes in v10:
>   - modify number of "reg", "reg-names" and "power-domains" entries
>     based on cluster mode
>   - Add extra optional atcm and btcm in "reg" property for lockstep mode
>   - Add "reg-names" for extra optional atcm and btcm for lockstep mode
>   - Drop previous Ack as bindings has new change
> 
> Changes in v9:
>   - None
> Changes in v8:
>   - None
> Changes in v7:
>   - None
> Changes in v6:
>   - None
> Changes in v5:
>   - None
> 
> Changes in v4:
>   - Use address-cells and size-cells value 2
>   - Modify ranges property as per new value of address-cells
>     and size-cells
>   - Modify child node "reg" property accordingly
>   - Remove previous ack for further review
> 
> v4 link: https://lore.kernel.org/all/20230829181900.2561194-2-tanmay.shah at amd.com/
> 
>  .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 ++++++++++++++++--
>  1 file changed, 170 insertions(+), 22 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:
./Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml:118:13: [warning] wrong indentation: expected 10 but found 12 (indentation)

dtschema/dtc warnings/errors:

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240213175450.3097308-3-tanmay.shah at amd.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From maz at kernel.org  Tue Feb 13 11:25:16 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 13 Feb 2024 19:25:16 +0000
Subject: [RFC PATCH] KVM: arm64: Fix double-free following kvm_pgtable_stage2_free_unlinked()
In-Reply-To: <20240212193052.27765-1-will@kernel.org>
References: <20240212193052.27765-1-will@kernel.org>
Message-ID: <170785230656.2847941.2376736166184489545.b4-ty@kernel.org>

On Mon, 12 Feb 2024 19:30:52 +0000, Will Deacon wrote:
> kvm_pgtable_stage2_free_unlinked() does the final put_page() on the
> root page of the sub-tree before returning, so remove the additional
> put_page() invocations in the callers.

Applied to fixes, thanks!

[1/1] KVM: arm64: Fix double-free following kvm_pgtable_stage2_free_unlinked()
      commit: c60d847be7b8e69e419e02a2b3d19c2842a3c35d

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From dlechner at baylibre.com  Tue Feb 13 11:26:02 2024
From: dlechner at baylibre.com (David Lechner)
Date: Tue, 13 Feb 2024 13:26:02 -0600
Subject: [PATCH 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <54623b74-872a-41dc-992f-71a586d145ec@sirena.org.uk>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
 <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com> <54623b74-872a-41dc-992f-71a586d145ec@sirena.org.uk>
Message-ID: <CAMknhBGt0EyA_FcpXbmT-PStZqmZ_PUENHbVfgDFOwWcv5gTAw@mail.gmail.com>

On Tue, Feb 13, 2024 at 12:55?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Mon, Feb 12, 2024 at 05:26:41PM -0600, David Lechner wrote:
>
> > +static int __spi_optimize_message(struct spi_device *spi,
> > +                               struct spi_message *msg,
> > +                               bool pre_optimized)
> > +{
> > +     struct spi_controller *ctlr = spi->controller;
> > +     int ret;
> > +
> > +     ret = __spi_validate(spi, msg);
> > +     if (ret)
> > +             return ret;
> > +
> > +     if (ctlr->optimize_message) {
> > +             ret = ctlr->optimize_message(msg);
> > +             if (ret)
> > +                     return ret;
> > +     }
> > +
> > +     msg->pre_optimized = pre_optimized;
>
> It would probably be clearer to name the parameter pre_optimising rather
> than pre_optimized, as it is the logic is a bit confusing.  Either that
> or some comments.  A similar issue applies on the cleanup path.

Per Jonathan's suggestion, I plan to remove the parameter from this
function and handle this flag at the call site instead.


From broonie at kernel.org  Tue Feb 13 11:28:39 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 19:28:39 +0000
Subject: [PATCH 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <CAMknhBGt0EyA_FcpXbmT-PStZqmZ_PUENHbVfgDFOwWcv5gTAw@mail.gmail.com>
References: <20240212-mainline-spi-precook-message-v1-0-a2373cd72d36@baylibre.com>
 <20240212-mainline-spi-precook-message-v1-1-a2373cd72d36@baylibre.com>
 <54623b74-872a-41dc-992f-71a586d145ec@sirena.org.uk>
 <CAMknhBGt0EyA_FcpXbmT-PStZqmZ_PUENHbVfgDFOwWcv5gTAw@mail.gmail.com>
Message-ID: <6900e726-dac7-45c0-a88f-7830c1c7e43f@sirena.org.uk>

On Tue, Feb 13, 2024 at 01:26:02PM -0600, David Lechner wrote:
> On Tue, Feb 13, 2024 at 12:55?PM Mark Brown <broonie at kernel.org> wrote:

> > It would probably be clearer to name the parameter pre_optimising rather
> > than pre_optimized, as it is the logic is a bit confusing.  Either that
> > or some comments.  A similar issue applies on the cleanup path.

> Per Jonathan's suggestion, I plan to remove the parameter from this
> function and handle this flag at the call site instead.

That works 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/20240213/6b001ab4/attachment-0001.sig>

From heiko at sntech.de  Tue Feb 13 11:31:58 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 20:31:58 +0100
Subject: [PATCH] dt-bindings: rockchip: Fix Hardkernel ODROID-M1 board bindings
In-Reply-To: <194a0894-a9f9-4c5e-b304-e7278104d8e7@feathertop.org>
References: <20240115145142.6292-1-lee@kyuhyuk.kr> <47795047.XUcTiDjVJD@diego>
 <194a0894-a9f9-4c5e-b304-e7278104d8e7@feathertop.org>
Message-ID: <2185016.Icojqenx9y@phil>

Hi Tim,

Am Mittwoch, 17. Januar 2024, 11:03:26 CET schrieb Tim Lunn:
> On 1/17/24 06:55, Heiko St?bner wrote:
> > Am Dienstag, 16. Januar 2024, 20:26:05 CET schrieb Rob Herring:
> >> On Tue, Jan 16, 2024 at 09:31:35AM +0100, Heiko St?bner wrote:
> >>> Am Dienstag, 16. Januar 2024, 08:24:44 CET schrieb Krzysztof Kozlowski:
> >>>> On 16/01/2024 03:00, Tim Lunn wrote:
> >>>>> On 1/16/24 01:58, Krzysztof Kozlowski wrote:
> >>>>>> On 15/01/2024 15:51, KyuHyuk Lee wrote:
> >>>>>>> The vendor in ODROID-M1 is hardkernel, but it was incorrectly written
> >>>>>>> as rockchip. Fixed the vendor prefix correctly.
> >>>>>>>
> >>>>>>> Signed-off-by: KyuHyuk Lee <lee at kyuhyuk.kr>
> >>>>>>> ---
> >>>>>>>    Documentation/devicetree/bindings/arm/rockchip.yaml | 2 +-
> >>>>>>>    1 file changed, 1 insertion(+), 1 deletion(-)
> >>>>>> You need to start testing your patches. Your last M1 fails as well in
> >>>>>> multiple places.
> >>>>>>
> >>>>>> It does not look like you tested the DTS against bindings. Please run
> >>>>>> `make dtbs_check W=1` (see
> >>>>>> Documentation/devicetree/bindings/writing-schema.rst or
> >>>>>> https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
> >>>>>> for instructions).
> >>>>>>
> >>>>>> The DTS change will break the users, so would be nice to mention this in
> >>>>>> its commit msg.
> >>>>> I notice there are a couple of other boards that incorrectly use
> >>>>> rockchip as the vendor also:
> >>>>>
> >>>>>             - const: rockchip,rk3399-orangepi
> >>>>>             - const: rockchip,rk3568-bpi-r2pro
> >>>>>
> >>>>> Perhaps these should also be fixed at the same time?
> >>>> What is happening with rockchip boards?
> >>> Copy-paste stuff ... boards using rockchip,boardname instead of
> >>> vendor,boardname for their compatible.
> >>>
> >>> I do remember us noticing this a number of times on some boards
> >>> and requesting fixes, but looks like some slipped through.
> >>>
> >>> So I guess Tim is suggesting changing the compatible, but with boards
> >>> being merged a while ago, this would break backwards compatibility.
> >>> So I guess both the Orange and Banana Pies will need to live with that.
> >> You may get away with it because we generally don't use the names...
> >>
> >> Though there are some discussions to start using them to select dtbs by
> >> bootloaders.
> > Ah, that's good to know (both points) ... so essentially right now would be
> > a good time to do what Tim suggested, before the names get actual usage.
> >
> > @Tim: is that something you'd want to do?
> >
> Sure, I will prepare patches and send them out soon.

As I stumbled upon this patch just now, how is that coming along? :-)

Thanks
Heiko




From mbland at motorola.com  Tue Feb 13 11:35:27 2024
From: mbland at motorola.com (Maxwell Bland)
Date: Tue, 13 Feb 2024 19:35:27 +0000
Subject: [PATCH] arm64: allow post-init vmalloc PXNTable
In-Reply-To: <SEZPR03MB67865557061A2494B1A1243CB44F2@SEZPR03MB6786.apcprd03.prod.outlook.com>
References: <CAP5Mv+ydhk=Ob4b40ZahGMgT-5+-VEHxtmA=-LkJiEOOU+K6hw@mail.gmail.com>
 <ZcurbvkUR-BoGTxu@FVFF77S0Q05N.cambridge.arm.com>
 <SEZPR03MB67865557061A2494B1A1243CB44F2@SEZPR03MB6786.apcprd03.prod.outlook.com>
Message-ID: <SEZPR03MB67864221134F49E9BE3B1FB9B44F2@SEZPR03MB6786.apcprd03.prod.outlook.com>

> -----Original Message-----
> From: Maxwell Bland On Tuesday, February 13, 2024 1:15 PM
> > From: Mark Rutland <mark.rutland at arm.com>
> > How does this work with other allocations of executable memory? e.g.  modules,
> > BPF?
> 
> It should work.
> - kernel/bpf/core.c uses bpf_jit_alloc_exec to create executable code regions,
>   which is a wrapper for module_alloc. In the interpreted BPF case, we do not
>   need to worry since the pages storing interpreted code are NX and can be
>   marked PXNTable regardless.

Correction: I was wrong here. The _weak reference to bpf_jit_alloc_exec is overwritten in
arch/arm64/net/bpf_jit_comp.c  to use a vmalloc call. This would need to be set back to
the generic BPF's use of "module_alloc". I will look into and correct this.


From heiko at sntech.de  Tue Feb 13 11:37:53 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 20:37:53 +0100
Subject: (subset) [PATCH 1/2] arm64: dts: rockchip: rock-pi-e: adjust phy-handle name
In-Reply-To: <20240116204103.29318-1-twoerner@gmail.com>
References: <20240116204103.29318-1-twoerner@gmail.com>
Message-ID: <170785305473.3362031.7094478212374122329.b4-ty@sntech.de>

On Tue, 16 Jan 2024 15:41:01 -0500, Trevor Woerner wrote:
> The rock-pi-e currently comes in 4 board spins, the latest one (v1.21)
> swaps out the Realtek 8211e PHY for an 8211f PHY. Therefore modify the
> phy-handle name to be more generic.
> 
> 

Applied, thanks!

[1/2] arm64: dts: rockchip: rock-pi-e: adjust phy-handle name
      commit: abe3426c8176b2713713e8ba7cbc7cecc5dedd81

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Tue Feb 13 11:37:51 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 20:37:51 +0100
Subject: (subset) [PATCH v2 1/6] dt-bindings: display: rockchip: rockchip,dw-hdmi: remove port property
In-Reply-To: <a493c65e-7cf9-455f-95d5-8c98cad35710@gmail.com>
References: <a493c65e-7cf9-455f-95d5-8c98cad35710@gmail.com>
Message-ID: <170785305473.3362031.5919338158795795118.b4-ty@sntech.de>

On Wed, 31 Jan 2024 22:14:29 +0100, Johan Jonker wrote:
> The hdmi-connector nodes are now functional and the new way to model
> hdmi ports nodes with both in and output port subnodes. Unfortunately
> with the conversion to YAML the old method with only an input port node
> was used. Later the new method was also added to the binding.
> A binding must be unambiguously, so remove the old port property
> entirely and make port at 0 and port at 1 a requirement as all
> upstream dts files are updated as well and because checking
> deprecated stuff is a bit pointless.
> Update the example to avoid use of the removed property.
> 
> [...]

Applied, thanks!

[3/6] ARM: dts: rockchip: fix rk3288 hdmi ports node
      commit: 585e4dc07100a6465b3da8d24e46188064c1c925
[4/6] ARM: dts: rockchip: fix rk322x hdmi ports node
      commit: 15a5ed03000cf61daf87d14628085cb1bc8ae72c
[5/6] arm64: dts: rockchip: fix rk3328 hdmi ports node
      commit: 1d00ba4700d1e0f88ae70d028d2e17e39078fa1c
[6/6] arm64: dts: rockchip: fix rk3399 hdmi ports node
      commit: f051b6ace7ffcc48d6d1017191f167c0a85799f6

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From naresh.kamboju at linaro.org  Tue Feb 13 11:38:01 2024
From: naresh.kamboju at linaro.org (Naresh Kamboju)
Date: Wed, 14 Feb 2024 01:08:01 +0530
Subject: WARNING: arch/arm64/kernel/cpufeature.c:3369 this_cpu_has_cap
In-Reply-To: <87il2sw4tj.wl-maz@kernel.org>
References: <CA+G9fYuVJ3DfmOR2GxbVmLqh_d=3y_wTXX-vQOUgp86uX-3oGg@mail.gmail.com>
 <87il2sw4tj.wl-maz@kernel.org>
Message-ID: <CA+G9fYu-2x48SC6jYzuLVDsYt=FF8-9x9e0Nt0X2gb5G1PvdaA@mail.gmail.com>

On Wed, 14 Feb 2024 at 00:48, Marc Zyngier <maz at kernel.org> wrote:
>
> On Tue, 13 Feb 2024 18:21:23 +0000,
> Naresh Kamboju <naresh.kamboju at linaro.org> wrote:
> >
> > Following kernel warning notices on all arm64 devices on today's Linux
> > next-20240213 tag.
> >
> > Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>
>
> What is the sense of this tag, and even of this email, for an issue
> that has already been reported, as outlined below?

LKFT building and testing Linux next tree and found this warning on
today's Linux next-20240213. However it is been reported by someone
else.

You may ignore the tag.

>
> >
> > [    0.038524] SMP: Total of 6 processors activated.
> > [    0.038539] CPU: All CPU(s) started at EL2
> > [    0.038588] CPU features: detected: 32-bit EL0 Support
> > [    0.038602] CPU features: detected: 32-bit EL1 Support
> > [    0.038620] CPU features: detected: CRC32 instructions
> > [    0.038650] ------------[ cut here ]------------
> > [    0.038656] WARNING: CPU: 0 PID: 1 at
> > arch/arm64/kernel/cpufeature.c:3369 this_cpu_has_cap+0x1c/0x70
...
> >
> > This issue has been addressed in the relevant email thread,
> > https://lore.kernel.org/all/0593516b-2419-49b7-83aa-fe189ffad0c2 at arm.com/

> Correct link:
>
> https://lore.kernel.org/all/86bk8k5ts3.wl-maz at kernel.org/

Thank you.

>
> > I will test the corresponding fix patch and get back to you.

I have tested your patch and the reported issue has been fixed.

- Naresh


From dmitry.baryshkov at linaro.org  Tue Feb 13 11:49:15 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 13 Feb 2024 21:49:15 +0200
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
In-Reply-To: <20240213125951.GB28844@willie-the-truck>
References: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
 <20240213121257.GI765010@ziepe.ca> <20240213121934.GA28726@willie-the-truck>
 <20240213125303.GJ765010@ziepe.ca> <20240213125951.GB28844@willie-the-truck>
Message-ID: <CAA8EJppWpLgX_kfk6O11k0uwyiq507pp_d+QtDogSgJqgiGviw@mail.gmail.com>

On Tue, 13 Feb 2024 at 14:59, Will Deacon <will at kernel.org> wrote:
>
> On Tue, Feb 13, 2024 at 08:53:03AM -0400, Jason Gunthorpe wrote:
> > On Tue, Feb 13, 2024 at 12:19:34PM +0000, Will Deacon wrote:
> > > > > @@ -875,15 +879,6 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
> > > > >         mutex_init(&smmu_domain->init_mutex);
> > > > >         spin_lock_init(&smmu_domain->cb_lock);
> > > > >
> > > > > -       if (dev) {
> > > > > -               struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> > > > > -
> > > > > -               if (arm_smmu_init_domain_context(smmu_domain, cfg->smmu, dev)) {
> > > > > -                       kfree(smmu_domain);
> > > > > -                       return NULL;
> > > > > -               }
> > > > > -       }
> > > > > -
> > > > >         return &smmu_domain->domain;
> > > > >  }
> > > >
> > > > Everything else is fine, you already tested with that arrangement.
> > >
> > > Partial reverts are a recipe for confusion, so I'll take this and if you'd
> > > like to bring back some of the hunks, please can you send a patch on top
> > > that does that?
> >
> > The typical kernel standard is to fix bugs in patches and only reach
> > for a wholesale revert if the community is struggling with bug
> > fixing. Dmitry already tested removing that hunk, Robin explained the
> > issue, we understand the bug fix is to remove the
> > arm_smmu_init_domain_context() call. Nothing justifies a full scale
> > revert.
>
> I can't say I'm aware of any consensus for how to handle this, to be
> completely honest with you. I just personally see a lot of benefit in
> reverting to a known-good state, especially when the revert has been
> posted by the bug reporter. Then we can add stuff on top of that known
> good state without having to worry about any other problems that we're
> yet to uncover. Doesn't really sound controversial...

Well, I'm open to any patch set that ends up fixing the issue. I won't
insist on landing the revert first, it's up to Will and Robin, I'd
say.

If there are any patches for this matter, please Cc me and
linux-arm-msm@, so that we can reply with the Tested-by trailer.

> > I'll send another patch if you want, but it seems like a waste of all
> > our time.
>
> It's a bug fix, of course it's a waste of time! We're talking minutes
> though, right?
>
> Will
-- 
With best wishes
Dmitry


From rsc at runtux.com  Tue Feb 13 12:02:38 2024
From: rsc at runtux.com (Ralf Schlatterbeck)
Date: Tue, 13 Feb 2024 21:02:38 +0100
Subject: [PATCH v2 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <170784989820.681459.6695714509639866106.b4-ty@kernel.org>
References: <20240202115330.wxkbfmvd76sy3a6a@runtux.com>
 <170784989820.681459.6695714509639866106.b4-ty@kernel.org>
Message-ID: <20240213200238.v5q364fwvn62vseb@runtux.com>

On Tue, Feb 13, 2024 at 06:44:58PM +0000, Mark Brown wrote:
> Applied to
> 
>    https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
> 
> Thanks!

Thanks!
Sorry for my impatience.

Ralf
-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   www.runtux.com
Reichergasse 131, A-3411 Weidling       email: office at runtux.com


From rsc at runtux.com  Tue Feb 13 12:02:35 2024
From: rsc at runtux.com (Ralf Schlatterbeck)
Date: Tue, 13 Feb 2024 21:02:35 +0100
Subject: [PATCH v2 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <CAOMZO5CD7+E_BBH+oQ8HUdBeRFZxWW7s2uJgS5eaQAW_Fe4CNg@mail.gmail.com>
References: <20240202115330.wxkbfmvd76sy3a6a@runtux.com>
 <20240213170657.puwlx5pjl3odcs2k@runtux.com>
 <CAOMZO5CD7+E_BBH+oQ8HUdBeRFZxWW7s2uJgS5eaQAW_Fe4CNg@mail.gmail.com>
Message-ID: <20240213200235.htnvyy343qiw3kbv@runtux.com>

On Tue, Feb 13, 2024 at 02:22:53PM -0300, Fabio Estevam wrote:
> 
> On Tue, Feb 13, 2024 at 2:07?PM Ralf Schlatterbeck <rsc at runtux.com> wrote:
> > > ---
> > > For oscilloscope screenshots and a verbose explanation see my blog post
> > > at https://blog.runtux.com/posts/2024/02/01/
> 
> I suggest putting the link to your detailed explanation into the
> commit log as this is useful information.
> 
> Reviewed-by: Fabio Estevam <festevam at gmail.com>

Thanks for the review!

My blog post might go away at some point.
And I think when looking at the original patch (in the Fixes: line) it
is quite obvious that the file in question was overlooked during the
original change. So it was hard to find and I documented it but looking
at it in context should be pretty clear.

Thanks
Ralf
-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   www.runtux.com
Reichergasse 131, A-3411 Weidling       email: office at runtux.com


From heiko at sntech.de  Tue Feb 13 12:02:46 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 21:02:46 +0100
Subject: [GIT PULL] Rockchip dts fixes for 6.8
Message-ID: <2450634.jE0xQCEvom@phil>

Hi Arnd, Kevin, Olof,

please find a below a collection of fixes for the current release 6.8
cycle.

Please pull

Thanks
Heiko


The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.8-rockchip-dtsfixes1

for you to fetch changes up to c22d03a95b0d815cd186302fdd93f74d99f1c914:

  arm64: dts: rockchip: Correct Indiedroid Nova GPIO Names (2024-02-13 20:28:19 +0100)

----------------------------------------------------------------
Some fixes to make devicetrees conform to bindings better (pwm irqs), dt
styling fixes (unneeded jaguar status, whitespaces, Cool Pi regulator
naming) and functionality fixes (px30 spi chipselect number, allowing
rk3588-evb1 to turn off, pcie lane numbers on CoolPi, wrong gpio-names
on Indidroid Nova and some CoolPi sdmmc aliases to match what uboot uses).

----------------------------------------------------------------
Andy Yan (4):
      arm64: dts: rockchip: aliase sdmmc as mmc1 for Cool Pi 4B
      arm64: dts: rockchip: aliase sdmmc as mmc1 for Cool Pi CM5 EVB
      arm64: dts: rockchip: rename vcc5v0_usb30_host regulator for Cool Pi CM5 EVB
      arm64: dts: rockchip: Fix the num-lanes of pcie3x4 on Cool Pi CM5 EVB

Chris Morgan (1):
      arm64: dts: rockchip: Correct Indiedroid Nova GPIO Names

Heiko Stuebner (2):
      arm64: dts: rockchip: drop unneeded status from rk3588-jaguar gpio-leds
      arm64: dts: rockchip: set num-cs property for spi on px30

Johan Jonker (1):
      arm64: dts: rockchip: Drop interrupts property from rk3328 pwm-rockchip node

Krzysztof Kozlowski (1):
      arm64: dts: rockchip: minor rk3588 whitespace cleanup

Sebastian Reichel (1):
      arm64: dts: rockchip: mark system power controller on rk3588-evb1

Uwe Kleine-K?nig (1):
      ARM: dts: rockchip: Drop interrupts property from pwm-rockchip nodes

 arch/arm/boot/dts/rockchip/rv1108.dtsi                   |  8 --------
 arch/arm64/boot/dts/rockchip/px30.dtsi                   |  2 ++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi                 |  1 -
 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts   |  8 +++++---
 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi      |  4 ++--
 arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts         |  1 +
 arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts           |  1 -
 arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts        |  8 ++++----
 arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts       |  4 ++--
 arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 10 +++++-----
 10 files changed, 21 insertions(+), 26 deletions(-)





From festevam at gmail.com  Tue Feb 13 12:04:04 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 13 Feb 2024 17:04:04 -0300
Subject: [PATCH v2 1/1] spi-mxs: Fix chipselect glitch
In-Reply-To: <20240213200235.htnvyy343qiw3kbv@runtux.com>
References: <20240202115330.wxkbfmvd76sy3a6a@runtux.com> <20240213170657.puwlx5pjl3odcs2k@runtux.com>
 <CAOMZO5CD7+E_BBH+oQ8HUdBeRFZxWW7s2uJgS5eaQAW_Fe4CNg@mail.gmail.com> <20240213200235.htnvyy343qiw3kbv@runtux.com>
Message-ID: <CAOMZO5B3zD4rQP8uHMjQ-NRLBnUzis-Ay45tj40J7RFPzAZ=Pg@mail.gmail.com>

On Tue, Feb 13, 2024 at 5:02?PM Ralf Schlatterbeck <rsc at runtux.com> wrote:

> My blog post might go away at some point.
> And I think when looking at the original patch (in the Fixes: line) it
> is quite obvious that the file in question was overlooked during the
> original change. So it was hard to find and I documented it but looking
> at it in context should be pretty clear.

Yes, that's fine. Mark has already applied it, so we are all good.

Thanks for the fix.


From m.szyprowski at samsung.com  Tue Feb 13 12:06:29 2024
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Tue, 13 Feb 2024 21:06:29 +0100
Subject: [PATCH 2/2] arm64: cpufeatures: Only check for NV1 if NV is
 present
In-Reply-To: <86bk8k5ts3.wl-maz@kernel.org>
References: <20240212144736.1933112-1-maz@kernel.org>
	<CGME20240212144758eucas1p1345ba6f2000c10a4b33f8575f0a8d22b@eucas1p1.samsung.com>
	<20240212144736.1933112-3-maz@kernel.org>
	<5b2d8fee-9d0f-48f7-b9ec-b86e95387a61@samsung.com>
	<86bk8k5ts3.wl-maz@kernel.org>
Message-ID: <1c3ad9f8-41ee-4fe0-bd9c-ca1212129cbf@samsung.com>

On 13.02.2024 15:21, Marc Zyngier wrote:
> On Tue, 13 Feb 2024 11:14:37 +0000,
> Marek Szyprowski <m.szyprowski at samsung.com> wrote:
>> On 12.02.2024 15:47, Marc Zyngier wrote:
>>> We handle ID_AA64MMFR4_EL1.E2H0 being 0 as NV1 being present.
>>> However, this is only true if FEAT_NV is implemented.
>>>
>>> Add the required check to has_nv1(), avoiding spuriously advertising
>>> NV1 on HW that doesn't have NV at all.
>>>
>>> Fixes: da9af5071b25 ("arm64: cpufeature: Detect HCR_EL2.NV1 being RES0")
>>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>> This patch in turn introduces the following warning during boot
>> (observed on today's linux-next):
>>
>> CPU: All CPU(s) started at EL2
>> CPU features: detected: 32-bit EL0 Support
>> CPU features: detected: 32-bit EL1 Support
>> CPU features: detected: CRC32 instructions
>> ------------[ cut here ]------------
>> WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/cpufeature.c:3369
>> this_cpu_has_cap+0x18/0x70
>> Modules linked in:
>> CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc4-next-20240213 #8014
>> Hardware name: Khadas VIM3 (DT)
>> pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>> pc : this_cpu_has_cap+0x18/0x70
>> lr : has_nv1+0x24/0xcc
>> ...
>> Call trace:
>>   ?this_cpu_has_cap+0x18/0x70
>>   ?update_cpu_capabilities+0x50/0x134
>>   ?setup_system_features+0x30/0x120
>>   ?smp_cpus_done+0x48/0xb4
>>   ?smp_init+0x7c/0x8c
>>   ?kernel_init_freeable+0x18c/0x4e4
>>   ?kernel_init+0x20/0x1d8
>>   ?ret_from_fork+0x10/0x20
>> irq event stamp: 2846
>> hardirqs last? enabled at (2845): [<ffff80008012cf5c>]
>> console_unlock+0x164/0x190
>> hardirqs last disabled at (2846): [<ffff80008123a078>] el1_dbg+0x24/0x8c
>> softirqs last? enabled at (2842): [<ffff800080010a60>]
>> __do_softirq+0x4a0/0x4e8
>> softirqs last disabled at (2827): [<ffff8000800169b0>]
>> ____do_softirq+0x10/0x1c
>> ---[ end trace 0000000000000000 ]---
>> alternatives: applying system-wide alternatives
> This is nothing short of embarrassing. It looks like I somehow managed
> to drop CONFIG_PREEMPT from my test config, making it impossible to
> identify these issues. Apologies for that.
>
> The following patch fixes it for me. Could you please give it a go?

Works fine for me.

Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>

>  From cd75279d3b6c387c13972b61c486a203d9652e97 Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <maz at kernel.org>
> Date: Tue, 13 Feb 2024 13:37:57 +0000
> Subject: [PATCH] arm64: cpufeatures: Fix FEAT_NV check when checking for
>   FEAT_NV1
>
> Using this_cpu_has_cap() has the potential to go wrong when
> used system-wide on a preemptible kernel. Instead, use the
> __system_matches_cap() helper when checking for FEAT_NV in the
> FEAT_NV1 probing helper.
>
> Fixes: 3673d01a2f55 ("arm64: cpufeatures: Only check for NV1 if NV is present")
> Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   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 3421b684d340..f309fd542c20 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1812,7 +1812,7 @@ static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
>   		{}
>   	};
>   
> -	return (this_cpu_has_cap(ARM64_HAS_NESTED_VIRT) &&
> +	return (__system_matches_cap(ARM64_HAS_NESTED_VIRT) &&
>   		!(has_cpuid_feature(entry, scope) ||
>   		  is_midr_in_range_list(read_cpuid_id(), nv1_ni_list)));
>   }

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From heiko at sntech.de  Tue Feb 13 12:06:49 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 13 Feb 2024 21:06:49 +0100
Subject: [PATCH] drm/rockchip: vop2: add a missing unlock in vop2_crtc_atomic_enable()
In-Reply-To: <20240119190841.1619443-1-harshit.m.mogalapalli@oracle.com>
References: <20240119190841.1619443-1-harshit.m.mogalapalli@oracle.com>
Message-ID: <170785480543.3398384.2668111589921036012.b4-ty@sntech.de>

On Fri, 19 Jan 2024 11:08:40 -0800, Harshit Mogalapalli wrote:
> Unlock before returning on the error path.
> 
> 

Applied, thanks!

[1/1] drm/rockchip: vop2: add a missing unlock in vop2_crtc_atomic_enable()
      commit: b6ddaa63f728d26c12048aed76be99c24f435c41

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From glaubitz at physik.fu-berlin.de  Tue Feb 13 12:52:33 2024
From: glaubitz at physik.fu-berlin.de (John Paul Adrian Glaubitz)
Date: Tue, 13 Feb 2024 21:52:33 +0100
Subject: [PATCH 6/6] mfd: tmio: move header to platform_data
In-Reply-To: <20240209015817.14627-14-wsa+renesas@sang-engineering.com>
References: <20240209015817.14627-8-wsa+renesas@sang-engineering.com>
	 <20240209015817.14627-14-wsa+renesas@sang-engineering.com>
Message-ID: <51eb2eb0845ae986209ba1ecda315dd27519a087.camel@physik.fu-berlin.de>

On Fri, 2024-02-09 at 02:58 +0100, Wolfram Sang wrote:
> All the MFD components are gone from the header meanwhile. Only the MMC
> relevant data is left which makes it a platform_data for the MMC
> controller. Move the header to the now fitting directory.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
> ---
>  MAINTAINERS                                   | 2 +-
>  arch/sh/boards/board-sh7757lcr.c              | 2 +-
>  arch/sh/boards/mach-ap325rxa/setup.c          | 2 +-
>  arch/sh/boards/mach-ecovec24/setup.c          | 2 +-
>  arch/sh/boards/mach-kfr2r09/setup.c           | 2 +-
>  arch/sh/boards/mach-migor/setup.c             | 2 +-
>  arch/sh/boards/mach-se/7724/setup.c           | 2 +-
>  drivers/mmc/host/renesas_sdhi_core.c          | 2 +-
>  drivers/mmc/host/renesas_sdhi_internal_dmac.c | 2 +-
>  drivers/mmc/host/renesas_sdhi_sys_dmac.c      | 2 +-
>  drivers/mmc/host/tmio_mmc_core.c              | 2 +-
>  drivers/mmc/host/uniphier-sd.c                | 2 +-
>  include/linux/{mfd => platform_data}/tmio.h   | 0
>  13 files changed, 12 insertions(+), 12 deletions(-)
>  rename include/linux/{mfd => platform_data}/tmio.h (100%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 960512bec428..c4e20abd177b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -22154,7 +22154,7 @@ L:	linux-renesas-soc at vger.kernel.org
>  S:	Supported
>  F:	drivers/mmc/host/renesas_sdhi*
>  F:	drivers/mmc/host/tmio_mmc*
> -F:	include/linux/mfd/tmio.h
> +F:	include/linux/platform_data/tmio.h
>  
>  TMP401 HARDWARE MONITOR DRIVER
>  M:	Guenter Roeck <linux at roeck-us.net>
> diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
> index f39c8196efdf..4014c042d2a5 100644
> --- a/arch/sh/boards/board-sh7757lcr.c
> +++ b/arch/sh/boards/board-sh7757lcr.c
> @@ -14,9 +14,9 @@
>  #include <linux/spi/spi.h>
>  #include <linux/spi/flash.h>
>  #include <linux/io.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/platform_data/sh_mmcif.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/sh_eth.h>
>  #include <linux/sh_intc.h>
>  #include <linux/usb/renesas_usbhs.h>
> diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
> index 645cccf3da88..bb5004a8ac02 100644
> --- a/arch/sh/boards/mach-ap325rxa/setup.c
> +++ b/arch/sh/boards/mach-ap325rxa/setup.c
> @@ -24,10 +24,10 @@
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
>  #include <linux/memblock.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mtd/physmap.h>
>  #include <linux/mtd/sh_flctl.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/fixed.h>
>  #include <linux/regulator/machine.h>
> diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
> index 30d117f9ad7e..6f13557eecd6 100644
> --- a/arch/sh/boards/mach-ecovec24/setup.c
> +++ b/arch/sh/boards/mach-ecovec24/setup.c
> @@ -17,13 +17,13 @@
>  #include <linux/input/sh_keysc.h>
>  #include <linux/interrupt.h>
>  #include <linux/memblock.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/platform_data/sh_mmcif.h>
>  #include <linux/mtd/physmap.h>
>  #include <linux/gpio.h>
>  #include <linux/gpio/machine.h>
>  #include <linux/platform_data/gpio_backlight.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_data/tsc2007.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/fixed.h>
> diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
> index 6b775eae85c0..70236859919d 100644
> --- a/arch/sh/boards/mach-kfr2r09/setup.c
> +++ b/arch/sh/boards/mach-kfr2r09/setup.c
> @@ -22,10 +22,10 @@
>  #include <linux/input/sh_keysc.h>
>  #include <linux/interrupt.h>
>  #include <linux/memblock.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mtd/physmap.h>
>  #include <linux/platform_data/lv5207lp.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/fixed.h>
>  #include <linux/regulator/machine.h>
> diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
> index 773ee767d0c4..1853e6319a66 100644
> --- a/arch/sh/boards/mach-migor/setup.c
> +++ b/arch/sh/boards/mach-migor/setup.c
> @@ -7,6 +7,7 @@
>  #include <linux/clkdev.h>
>  #include <linux/dma-map-ops.h>
>  #include <linux/init.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/interrupt.h>
>  #include <linux/input.h>
> @@ -14,7 +15,6 @@
>  #include <linux/memblock.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mtd/physmap.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mtd/platnand.h>
>  #include <linux/i2c.h>
>  #include <linux/regulator/fixed.h>
> diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
> index 787ddd3c627a..e500feb91053 100644
> --- a/arch/sh/boards/mach-se/7724/setup.c
> +++ b/arch/sh/boards/mach-se/7724/setup.c
> @@ -21,9 +21,9 @@
>  #include <linux/input/sh_keysc.h>
>  #include <linux/interrupt.h>
>  #include <linux/memblock.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mtd/physmap.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/fixed.h>
>  #include <linux/regulator/machine.h>
> diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
> index c675dec587ef..f84f60139bcf 100644
> --- a/drivers/mmc/host/renesas_sdhi_core.c
> +++ b/drivers/mmc/host/renesas_sdhi_core.c
> @@ -22,13 +22,13 @@
>  #include <linux/delay.h>
>  #include <linux/iopoll.h>
>  #include <linux/kernel.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mmc/mmc.h>
>  #include <linux/mmc/slot-gpio.h>
>  #include <linux/module.h>
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/pinctrl/pinctrl-state.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_domain.h>
>  #include <linux/regulator/consumer.h>
> diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> index 24e1c17908d7..97cd55fec0bf 100644
> --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> @@ -11,12 +11,12 @@
>  #include <linux/device.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/io-64-nonatomic-hi-lo.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/pagemap.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/scatterlist.h>
> diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> index c18581897f8a..68e31c37cce6 100644
> --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> @@ -11,12 +11,12 @@
>  #include <linux/device.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/dmaengine.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/pagemap.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/scatterlist.h>
> diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
> index c39141a5bd23..0c4397b3cffd 100644
> --- a/drivers/mmc/host/tmio_mmc_core.c
> +++ b/drivers/mmc/host/tmio_mmc_core.c
> @@ -31,7 +31,6 @@
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/irq.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/card.h>
>  #include <linux/mmc/host.h>
>  #include <linux/mmc/mmc.h>
> @@ -39,6 +38,7 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/pagemap.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_qos.h>
>  #include <linux/pm_runtime.h>
> diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c
> index 1404989e6151..bd231dbe90ba 100644
> --- a/drivers/mmc/host/uniphier-sd.c
> +++ b/drivers/mmc/host/uniphier-sd.c
> @@ -9,11 +9,11 @@
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/mfd/syscon.h>
> -#include <linux/mfd/tmio.h>
>  #include <linux/mmc/host.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/pinctrl/consumer.h>
> +#include <linux/platform_data/tmio.h>
>  #include <linux/platform_device.h>
>  #include <linux/regmap.h>
>  #include <linux/reset.h>
> diff --git a/include/linux/mfd/tmio.h b/include/linux/platform_data/tmio.h
> similarity index 100%
> rename from include/linux/mfd/tmio.h
> rename to include/linux/platform_data/tmio.h

Acked-by: John Paul Adrian Glaubitz <glaubitz at physik.fu-berlin.de>

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913


From tanmay.shah at amd.com  Tue Feb 13 12:37:49 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Tue, 13 Feb 2024 14:37:49 -0600
Subject: [PATCH v10 2/4] dt-bindings: remoteproc: add Tightly Coupled
 Memory (TCM) bindings
In-Reply-To: <170785205177.2155555.1311787541370066483.robh@kernel.org>
References: <20240213175450.3097308-1-tanmay.shah@amd.com>
 <20240213175450.3097308-3-tanmay.shah@amd.com>
 <170785205177.2155555.1311787541370066483.robh@kernel.org>
Message-ID: <b931a24c-f676-4ddb-bb7c-e7a509d5dd4b@amd.com>

Hello,

Thanks for reviews please find my comments below.

On 2/13/24 1:20 PM, Rob Herring wrote:
> On Tue, 13 Feb 2024 09:54:48 -0800, Tanmay Shah wrote:
> > From: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
> > 
> > Introduce bindings for TCM memory address space on AMD-xilinx Zynq
> > UltraScale+ platform. It will help in defining TCM in device-tree
> > and make it's access platform agnostic and data-driven.
> > 
> > Tightly-coupled memories(TCMs) are low-latency memory that provides
> > predictable instruction execution and predictable data load/store
> > timing. Each Cortex-R5F processor contains two 64-bit wide 64 KB memory
> > banks on the ATCM and BTCM ports, for a total of 128 KB of memory.
> > 
> > The TCM resources(reg, reg-names and power-domain) are documented for
> > each TCM in the R5 node. The reg and reg-names are made as required
> > properties as we don't want to hardcode TCM addresses for future
> > platforms and for zu+ legacy implementation will ensure that the
> > old dts w/o reg/reg-names works and stable ABI is maintained.
> > 
> > It also extends the examples for TCM split and lockstep modes.
> > 
> > Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
> > Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
> > ---
> > 
> > Changes in v10:
> >   - modify number of "reg", "reg-names" and "power-domains" entries
> >     based on cluster mode
> >   - Add extra optional atcm and btcm in "reg" property for lockstep mode
> >   - Add "reg-names" for extra optional atcm and btcm for lockstep mode
> >   - Drop previous Ack as bindings has new change
> > 
> > Changes in v9:
> >   - None
> > Changes in v8:
> >   - None
> > Changes in v7:
> >   - None
> > Changes in v6:
> >   - None
> > Changes in v5:
> >   - None
> > 
> > Changes in v4:
> >   - Use address-cells and size-cells value 2
> >   - Modify ranges property as per new value of address-cells
> >     and size-cells
> >   - Modify child node "reg" property accordingly
> >   - Remove previous ack for further review
> > 
> > v4 link: https://lore.kernel.org/all/20230829181900.2561194-2-tanmay.shah at amd.com/
> > 
> >  .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 ++++++++++++++++--
> >  1 file changed, 170 insertions(+), 22 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:
> ./Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml:118:13: [warning] wrong indentation: expected 10 but found 12 (indentation)
Ack. I will fix this.

However, can I still get reviews on patch itself so if something else needs to be fixed I can fix in next revision as well.

Also, I tried to run yamllint with following command:

make DT_CHECKER_FLAGS=-m dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml O=../build/zynqmp/linux-next/


However, I see following logs without any error on bindings:

? LINT??? Documentation/devicetree/bindings
invalid config: unknown option "required" for rule "quoted-strings"
*xargs: /usr/bin/yamllint: exited with status 255; aborting*
? CHKDT?? Documentation/devicetree/bindings/processed-schema.json
? SCHEMA? Documentation/devicetree/bindings/processed-schema.json
? DTEX??? Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.example.dts
? DTC_CHK Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.example.dtb

I am not sure if my system is missing something but, yamllint tool is failing.

I appreciate if someone can point to quick fix if this is known issue and is already resolved.

Thanks,

Tanmay

> dtschema/dtc warnings/errors:
>
> doc reference errors (make refcheckdocs):
>
> See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240213175450.3097308-3-tanmay.shah at amd.com
>
> The base for the series is generally the latest rc1. A different dependency
> should be noted in *this* patch.
>
> 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 after running the above command yourself. Note
> that DT_SCHEMA_FILES can be set to your schema file to speed up checking
> your schema. However, it must be unset to test all examples with your schema.
>


From dianders at chromium.org  Tue Feb 13 13:04:55 2024
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 13 Feb 2024 13:04:55 -0800
Subject: [PATCH v2] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <20240213-arm64-sve-ptrace-regset-size-v2-1-c7600ca74b9b@kernel.org>
References: <20240213-arm64-sve-ptrace-regset-size-v2-1-c7600ca74b9b@kernel.org>
Message-ID: <CAD=FV=UaLTtjhHdKDj=g6xzcAZjU+9XvQ8GCYyrwq5oWTec1dw@mail.gmail.com>

Hi,

On Tue, Feb 13, 2024 at 10:24?AM Mark Brown <broonie at kernel.org> wrote:
>
> Doug Anderson observed that ChromeOS crashes are being reported which
> include failing allocations of order 7 during core dumps due to ptrace
> allocating storage for regsets:
>
>   chrome: page allocation failure: order:7,
>           mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
>           nodemask=(null),cpuset=urgent,mems_allowed=0
>    ...
>   regset_get_alloc+0x1c/0x28
>   elf_core_dump+0x3d8/0xd8c
>   do_coredump+0xeb8/0x1378
>
> with further investigation showing that this is:
>
>    [   66.957385] DOUG: Allocating 279584 bytes
>
> which is the maximum size of the SVE regset. As Doug observes it is not
> entirely surprising that such a large allocation of contiguous memory might
> fail on a long running system.
>
> The SVE regset is currently sized to hold SVE registers with a VQ of
> SVE_VQ_MAX which is 512, substantially more than the architectural maximum
> of 16 which we might see even in a system emulating the limits of the
> architecture. Since we don't expose the size we tell the regset core
> externally let's define ARCH_SVE_VQ_MAX with the actual architectural
> maximum and use that for the regset, we'll still overallocate most of the
> time but much less so which will be helpful even if the core is fixed to
> not require contiguous allocations.
>
> Specify ARCH_SVE_VQ_MAX in terms of the maximum value that can be written
> into ZCR_ELx.LEN (where this is set in the hardware). For consistency
> update the maximum SME vector length to be specified in the same style
> while we are at it.
>
> We could also teach the ptrace core about runtime discoverable regset sizes
> but that would be a more invasive change and this is being observed in
> practical systems.
>
> Reported-by: Doug Anderson <dianders at chromium.org>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> We should probably also use the actual architectural limit for the
> bitmasks we use in the VL enumeration code, though that's both a little
> bit more involved and less immediately a problem.
> ---
> Changes in v2:
> - Specify the value using the size of the bitfield it goes into.
> - Link to v1: https://lore.kernel.org/r/20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e at kernel.org
> ---
>  arch/arm64/include/asm/fpsimd.h | 12 ++++++------
>  arch/arm64/kernel/ptrace.c      |  3 ++-
>  2 files changed, 8 insertions(+), 7 deletions(-)

FWIW, v2 still works for me from a black box point of view. :-P I ran
the same test I did from v1. Repeating here:

Confirmed that when I send a "quit" signal to Chrome now that the
allocation I see for "core_note_type" NT_ARM_SVE goes down from
279,584 bytes (n=17474) to just 8,768 bytes (n=548).

Tested-by: Douglas Anderson <dianders at chromium.org>


From mbland at debian.lenovo.com  Tue Feb 13 12:18:15 2024
From: mbland at debian.lenovo.com (Maxwell Bland)
Date: Tue, 13 Feb 2024 14:18:15 -0600
Subject: [PATCH] arm64: allow post-init vmalloc PXNTable
In-Reply-To: <2024021321-scooter-citrus-233c@gregkh>
Message-ID: <4TZDhL5C5Hz3p8NW@ilclmmrp02.lenovo.com>

Ensures that PXNTable can be set on all table descriptors allocated
through vmalloc. Normally, PXNTable is set only during initial memory
mapping and does not apply thereafter, making it possible for attackers
to target post-init allocated writable PTEs as a staging region for
injection of their code into the kernel. Presently it is not possible to
efficiently prevent these attacks as VMALLOC_END overlaps with _text,
e.g.:

VMALLOC_START ffff800080000000 VMALLOC_END fffffbfff0000000
_text         ffffb6c0c1400000 _end        ffffb6c0c3e40000

Setting VMALLOC_END to _text in init would resolve this issue with the
caveat of a sizeable reduction in the size of available vmalloc memory
(~70,000 GB) due to requirements on aslr randomness. However, we need to
support the enforcement of PXNTable dynamically for our static
assignment of this flag during mm initialization to be effective.

Because the address of _text is aslr-sensitive and this patch associates
this value with VMALLOC_END, we remove the use of VMALLOC_END in a print
statement in mm/percpu.c. However, only the format string is updated in
crash_core.c, since we are dead at that point regardless. VMALLOC_END is
updated in kernel/setup.c to associate the feature closely with aslr and
region allocation code.

bpf_jit_comp.c must also be remediated to ensure that the module_alloc
rather than vmalloc interface is used, so that regions used for BPF
allocations are appropriately located into the _text region.

Signed-off-by: Maxwell Bland <mbland at motorola.com>
---

This is an attempt to get Moto's SMTP server to send the patch without ruining
the formatting. Based on Mark R.'s comments, though, it sounds like:

1) I need to figure out a way to reduce the reduction in virtual memory.
2) I need to actually enforce PXNTable dynamically, to make it clear this is a
real upstream issue.
3) I need some testing and quantification to make sure this does not ruin BPF
and module allocations.

https://lore.kernel.org/all/ZcurbvkUR-BoGTxu at FVFF77S0Q05N.cambridge.arm.com/

Regardless, here's the original patch on the current Github linux main.

 arch/arm64/Kconfig                   | 13 +++++++++++++
 arch/arm64/include/asm/pgtable.h     |  6 ++++++
 arch/arm64/include/asm/vmalloc-pxn.h |  9 +++++++++
 arch/arm64/kernel/crash_core.c       |  2 +-
 arch/arm64/kernel/setup.c            |  9 +++++++++
 arch/arm64/net/bpf_jit_comp.c        |  5 +++--
 mm/percpu.c                          |  4 ++--
 7 files changed, 43 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm64/include/asm/vmalloc-pxn.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aa7c1d435139..5f1e75d70e14 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2165,6 +2165,19 @@ config ARM64_DEBUG_PRIORITY_MASKING
          If unsure, say N
 endif # ARM64_PSEUDO_NMI

+config ARM64_VMALLOC_PXN
+       bool "Ensures table descriptors pointing to kernel data are PXNTable"
+       help
+         Reduces the range of the kernel data vmalloc region to remove any
+         overlap with kernel code, making it possible to enable the PXNTable
+         bit on table descriptors allocated after the kernel's initial memory
+         mapping.
+
+         This increases the performance of security monitors which protect
+         against malicious updates to page table entries.
+
+         If unsure, say N.
+
 config RELOCATABLE
        bool "Build a relocatable kernel image" if EXPERT
        select ARCH_HAS_RELR
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 79ce70fbb751..49f64ea77c81 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -22,7 +22,9 @@
  *     and fixed mappings
  */
 #define VMALLOC_START          (MODULES_END)
+#ifndef CONFIG_ARM64_VMALLOC_PXN
 #define VMALLOC_END            (VMEMMAP_START - SZ_256M)
+#endif

 #define vmemmap                        ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))

@@ -35,6 +37,10 @@
 #include <linux/sched.h>
 #include <linux/page_table_check.h>

+#ifdef CONFIG_ARM64_VMALLOC_PXN
+#include <asm/vmalloc-pxn.h>
+#endif
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE

diff --git a/arch/arm64/include/asm/vmalloc-pxn.h b/arch/arm64/include/asm/vmalloc-pxn.h
new file mode 100644
index 000000000000..d054427e2804
--- /dev/null
+++ b/arch/arm64/include/asm/vmalloc-pxn.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_ARM64_VMALLOC_PXN_H
+#define _ASM_ARM64_VMALLOC_PXN_H
+
+#ifdef CONFIG_ARM64_VMALLOC_PXN
+extern u64 __vmalloc_end __ro_after_init;
+#define VMALLOC_END (__vmalloc_end)
+#endif /* CONFIG_ARM64_VMALLOC_PXN */
+
+#endif /* _ASM_ARM64_VMALLOC_PXN_H */
diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/crash_core.c
index 66cde752cd74..39dccae11a40 100644
--- a/arch/arm64/kernel/crash_core.c
+++ b/arch/arm64/kernel/crash_core.c
@@ -24,7 +24,7 @@ void arch_crash_save_vmcoreinfo(void)
        vmcoreinfo_append_str("NUMBER(MODULES_VADDR)=0x%lx\n", MODULES_VADDR);
        vmcoreinfo_append_str("NUMBER(MODULES_END)=0x%lx\n", MODULES_END);
        vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", VMALLOC_START);
-       vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%lx\n", VMALLOC_END);
+       vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%llx\n", VMALLOC_END);
        vmcoreinfo_append_str("NUMBER(VMEMMAP_START)=0x%lx\n", VMEMMAP_START);
        vmcoreinfo_append_str("NUMBER(VMEMMAP_END)=0x%lx\n", VMEMMAP_END);
        vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 42c690bb2d60..b7ccee672743 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -54,6 +54,11 @@
 #include <asm/xen/hypervisor.h>
 #include <asm/mmu_context.h>

+#ifdef CONFIG_ARM64_VMALLOC_PXN
+u64 __vmalloc_end __ro_after_init = VMEMMAP_START - SZ_256M;
+EXPORT_SYMBOL(__vmalloc_end);
+#endif /* CONFIG_ARM64_VMALLOC_PXN */
+
 static int num_standard_resources;
 static struct resource *standard_resources;

@@ -298,6 +303,10 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)

        kaslr_init();

+#ifdef CONFIG_ARM64_VMALLOC_PXN
+       __vmalloc_end = ALIGN_DOWN((u64) _text, PMD_SIZE);
+#endif
+
        /*
         * If know now we are going to need KPTI then use non-global
         * mappings from the start, avoiding the cost of rewriting
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 8955da5c47cf..1fe0d637792c 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -11,6 +11,7 @@
 #include <linux/bpf.h>
 #include <linux/filter.h>
 #include <linux/memory.h>
+#include <linux/moduleloader.h>
 #include <linux/printk.h>
 #include <linux/slab.h>

@@ -1690,12 +1691,12 @@ u64 bpf_jit_alloc_exec_limit(void)
 void *bpf_jit_alloc_exec(unsigned long size)
 {
        /* Memory is intended to be executable, reset the pointer tag. */
-       return kasan_reset_tag(vmalloc(size));
+       return kasan_reset_tag(module_alloc(size));
 }

 void bpf_jit_free_exec(void *addr)
 {
-       return vfree(addr);
+       return module_memfree(addr);
 }

 /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */
diff --git a/mm/percpu.c b/mm/percpu.c
index 4e11fc1e6def..a902500ebfa0 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -3128,8 +3128,8 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size,

        /* warn if maximum distance is further than 75% of vmalloc space */
        if (max_distance > VMALLOC_TOTAL * 3 / 4) {
-               pr_warn("max_distance=0x%lx too large for vmalloc space 0x%lx\n",
-                               max_distance, VMALLOC_TOTAL);
+               pr_warn("max_distance=0x%lx too large for vmalloc space\n",
+                               max_distance);
 #ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
                /* and fail if we have fallback */
                rc = -EINVAL;
--
2.39.2



From charles.perry at savoirfairelinux.com  Tue Feb 13 13:40:12 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Tue, 13 Feb 2024 16:40:12 -0500 (EST)
Subject: [PATCH v3 2/5] dt-bindings: fpga: xlnx,fpga-slave-serial:
 rename gpios
In-Reply-To: <69679d9a-02e9-498f-8f5a-7c029059a8c1@linaro.org>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com> <20240207180142.79625-3-charles.perry@savoirfairelinux.com> <69679d9a-02e9-498f-8f5a-7c029059a8c1@linaro.org>
Message-ID: <1139371633.970589.1707860412394.JavaMail.zimbra@savoirfairelinux.com>

On Feb 11, 2024, at 10:39 AM, Krzysztof Kozlowski krzysztof.kozlowski at linaro.org wrote:
> On 07/02/2024 19:01, Charles Perry wrote:
>> By convention, gpio consumer names should not contain underscores
>> (prog_b here) and shouldn't contain active low suffixes (-b here).
>> 
>> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
>> ---
>>  .../bindings/fpga/xlnx,fpga-slave-serial.yaml        | 12 ++++++------
>>  1 file changed, 6 insertions(+), 6 deletions(-)
>> 
>> diff --git a/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml
>> b/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml
>> index 614d86ad825f3..650a4d8792b64 100644
>> --- a/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml
>> +++ b/Documentation/devicetree/bindings/fpga/xlnx,fpga-slave-serial.yaml
>> @@ -36,7 +36,7 @@ properties:
>>    reg:
>>      maxItems: 1
>>  
>> -  prog_b-gpios:
>> +  prog-gpios:
> 
> Please deprecate old property and add allOf excluding the usage of both.
> Driver still parses old property, so we should have it documented.
> 
> https://lore.kernel.org/all/20230118163208.GA117919-robh at kernel.org/
> 
> Best regards,
> Krzysztof

Ok. Thank you for the example.

Regards,
Charles


From rdunlap at infradead.org  Tue Feb 13 13:44:45 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Tue, 13 Feb 2024 13:44:45 -0800
Subject: [PATCH 3/3] Documentation: tee: Add TS-TEE driver
In-Reply-To: <20240213145239.379875-4-balint.dobszay@arm.com>
References: <20240213145239.379875-1-balint.dobszay@arm.com>
 <20240213145239.379875-4-balint.dobszay@arm.com>
Message-ID: <bbb40718-9bfa-4431-a3b0-c09d068fd6cc@infradead.org>

Hi--

On 2/13/24 06:52, Balint Dobszay wrote:
> Add documentation for the Trusted Services TEE driver.
> 
> Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
> ---
>  Documentation/tee/index.rst  |  1 +
>  Documentation/tee/ts-tee.rst | 70 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 71 insertions(+)
>  create mode 100644 Documentation/tee/ts-tee.rst
> 

> diff --git a/Documentation/tee/ts-tee.rst b/Documentation/tee/ts-tee.rst
> new file mode 100644
> index 000000000000..e121ebbbfab7
> --- /dev/null
> +++ b/Documentation/tee/ts-tee.rst
> @@ -0,0 +1,70 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +=================================
> +TS-TEE (Trusted Services project)
> +=================================
> +
> +This driver provides access to secure services implemented by Trusted Services.
> +
> +Trusted Services [1] is a TrustedFirmware.org project that provides a framework
> +for developing and deploying device Root of Trust services in FF-A [2] S-EL0
> +Secure Partitions. The project hosts the reference implementation of the Arm
> +Platform Security Architecture [3] for Arm A-profile devices.
> +
> +The FF-A Secure Partitions (SP) are accessible through the FF-A driver [4] which
> +provides the low level communication for this driver. On top of that the Trusted
> +Services RPC protocol is used [5]. To use the driver from user space a reference
> +implementation is provided at [6], which is part of the Trusted Services client
> +library called libts [7].
> +

Fix run-on sentences:

> +All Trusted Services (TS) SPs have the same FF-A UUID, it identifies the TS RPC

                                                    UUID. It
or
                                                    UUIT; it

> +protocol. A TS SP can host one or more services (e.g. PSA Crypto, PSA ITS, etc).
> +A service is identified by its service UUID, the same type of service cannot be

                                          UUID;

> +present twice in the same SP. During SP boot each service in the SP is assigned
> +an "interface ID", this is just a short ID to simplify message addressing.

      "interface ID." This

> +
> +The generic TEE design is to share memory at once with the TEE implementation,
> +which can then be reused to communicate with multiple TAs. However, in case of

"TA" is not defined.

> +FF-A, memory sharing works on an endpoint level, i.e. memory is shared with a
> +specific SP. User space has to be able to separately share memory with each SP
> +based on its endpoint ID, therefore a separate TEE device is registered for each

                         ID; therefore

> +discovered TS SP. Opening the SP corresponds to opening the TEE device and
> +creating a TEE context. A TS SP hosts one or more services, opening a service

                                                     services. Opening

> +corresponds to opening a session in the given tee_context.
> +
> +Overview of a system with Trusted Services components::
> +
> +   User space                  Kernel space                   Secure world
> +   ~~~~~~~~~~                  ~~~~~~~~~~~~                   ~~~~~~~~~~~~
> +   +--------+                                               +-------------+
> +   | Client |                                               | Trusted     |
> +   +--------+                                               | Services SP |
> +      /\                                                    +-------------+
> +      ||                                                          /\
> +      ||                                                          ||
> +      ||                                                          ||
> +      \/                                                          \/
> +   +-------+                +----------+--------+           +-------------+
> +   | libts |                |  TEE     | TS-TEE |           |  FF-A SPMC  |
> +   |       |                |  subsys  | driver |           |   + SPMD    |
> +   +-------+----------------+----+-----+--------+-----------+-------------+
> +   |      Generic TEE API        |     |  FF-A  |     TS RPC protocol     |
> +   |      IOCTL (TEE_IOC_*)      |     | driver |        over FF-A        |
> +   +-----------------------------+     +--------+-------------------------+
> +
> +References
> +==========
> +
> +[1] https://www.trustedfirmware.org/projects/trusted-services/
> +
> +[2] https://developer.arm.com/documentation/den0077/
> +
> +[3] https://www.arm.com/architecture/security-features/platform-security
> +
> +[4] drivers/firmware/arm_ffa/
> +
> +[5] https://trusted-services.readthedocs.io/en/v1.0.0/developer/service-access-protocols.html#abi
> +
> +[6] https://git.trustedfirmware.org/TS/trusted-services.git/tree/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c?h=v1.0.0
> +
> +[7] https://git.trustedfirmware.org/TS/trusted-services.git/tree/deployments/libts/arm-linux/CMakeLists.txt?h=v1.0.0

-- 
#Randy


From jbrunet at baylibre.com  Tue Feb 13 13:58:02 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Tue, 13 Feb 2024 22:58:02 +0100
Subject: [PATCH v2 0/2] ASoC: meson: aiu: fix function pointer type mismatch
Message-ID: <20240213215807.3326688-1-jbrunet@baylibre.com>

This patchset fixes 2 -Wcast-function-type-strict warning in amlogic
audio drivers with clang 16.

Changes since v1: [0]
* use devm_clk_get_enabled() instead of adding a dedicated helper in each
  driver.
* Split the patch, 1 per fixed commit to make it easier for stable.

[0]: https://lore.kernel.org/lkml/20240213101220.459641-1-arnd at kernel.org/

Jerome Brunet (2):
  ASoC: meson: aiu: fix function pointer type mismatch
  ASoC: meson: t9015: fix function pointer type mismatch

 sound/soc/meson/aiu.c   | 19 ++++---------------
 sound/soc/meson/aiu.h   |  1 -
 sound/soc/meson/t9015.c | 20 ++++----------------
 3 files changed, 8 insertions(+), 32 deletions(-)

-- 
2.43.0



From jbrunet at baylibre.com  Tue Feb 13 13:58:03 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Tue, 13 Feb 2024 22:58:03 +0100
Subject: [PATCH v2 1/2] ASoC: meson: aiu: fix function pointer type mismatch
In-Reply-To: <20240213215807.3326688-1-jbrunet@baylibre.com>
References: <20240213215807.3326688-1-jbrunet@baylibre.com>
Message-ID: <20240213215807.3326688-2-jbrunet@baylibre.com>

clang-16 warns about casting functions to incompatible types, as is done
here to call clk_disable_unprepare:

sound/soc/meson/aiu.c:243:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
  243 |                                        (void(*)(void *))clk_disable_unprepare,

The pattern of getting, enabling and setting a disable callback for a
clock can be replaced with devm_clk_get_enabled(), which also fixes
this warning.

Fixes: 6ae9ca9ce986 ("ASoC: meson: aiu: add i2s and spdif support")
Reported-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 sound/soc/meson/aiu.c | 19 ++++---------------
 sound/soc/meson/aiu.h |  1 -
 2 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c
index 7109b81cc3d0..5d1419ed7a62 100644
--- a/sound/soc/meson/aiu.c
+++ b/sound/soc/meson/aiu.c
@@ -212,11 +212,12 @@ static const char * const aiu_spdif_ids[] = {
 static int aiu_clk_get(struct device *dev)
 {
 	struct aiu *aiu = dev_get_drvdata(dev);
+	struct clk *pclk;
 	int ret;
 
-	aiu->pclk = devm_clk_get(dev, "pclk");
-	if (IS_ERR(aiu->pclk))
-		return dev_err_probe(dev, PTR_ERR(aiu->pclk), "Can't get the aiu pclk\n");
+	pclk = devm_clk_get_enabled(dev, "pclk");
+	if (IS_ERR(pclk))
+		return dev_err_probe(dev, PTR_ERR(pclk), "Can't get the aiu pclk\n");
 
 	aiu->spdif_mclk = devm_clk_get(dev, "spdif_mclk");
 	if (IS_ERR(aiu->spdif_mclk))
@@ -233,18 +234,6 @@ static int aiu_clk_get(struct device *dev)
 	if (ret)
 		return dev_err_probe(dev, ret, "Can't get the spdif clocks\n");
 
-	ret = clk_prepare_enable(aiu->pclk);
-	if (ret) {
-		dev_err(dev, "peripheral clock enable failed\n");
-		return ret;
-	}
-
-	ret = devm_add_action_or_reset(dev,
-				       (void(*)(void *))clk_disable_unprepare,
-				       aiu->pclk);
-	if (ret)
-		dev_err(dev, "failed to add reset action on pclk");
-
 	return ret;
 }
 
diff --git a/sound/soc/meson/aiu.h b/sound/soc/meson/aiu.h
index 393b6c2307e4..0f94c8bf6081 100644
--- a/sound/soc/meson/aiu.h
+++ b/sound/soc/meson/aiu.h
@@ -33,7 +33,6 @@ struct aiu_platform_data {
 };
 
 struct aiu {
-	struct clk *pclk;
 	struct clk *spdif_mclk;
 	struct aiu_interface i2s;
 	struct aiu_interface spdif;
-- 
2.43.0



From jbrunet at baylibre.com  Tue Feb 13 13:58:04 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Tue, 13 Feb 2024 22:58:04 +0100
Subject: [PATCH v2 2/2] ASoC: meson: t9015: fix function pointer type mismatch
In-Reply-To: <20240213215807.3326688-1-jbrunet@baylibre.com>
References: <20240213215807.3326688-1-jbrunet@baylibre.com>
Message-ID: <20240213215807.3326688-3-jbrunet@baylibre.com>

clang-16 warns about casting functions to incompatible types, as is done
here to call clk_disable_unprepare:

sound/soc/meson/t9015.c:274:4: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
  274 |                         (void(*)(void *))clk_disable_unprepare,

The pattern of getting, enabling and setting a disable callback for a
clock can be replaced with devm_clk_get_enabled(), which also fixes
this warning.

Fixes: 33901f5b9b16 ("ASoC: meson: add t9015 internal DAC driver")
Reported-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
---
 sound/soc/meson/t9015.c | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c
index 9c6b4dac6893..571f65788c59 100644
--- a/sound/soc/meson/t9015.c
+++ b/sound/soc/meson/t9015.c
@@ -48,7 +48,6 @@
 #define POWER_CFG	0x10
 
 struct t9015 {
-	struct clk *pclk;
 	struct regulator *avdd;
 };
 
@@ -249,6 +248,7 @@ static int t9015_probe(struct platform_device *pdev)
 	struct t9015 *priv;
 	void __iomem *regs;
 	struct regmap *regmap;
+	struct clk *pclk;
 	int ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -256,26 +256,14 @@ static int t9015_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	platform_set_drvdata(pdev, priv);
 
-	priv->pclk = devm_clk_get(dev, "pclk");
-	if (IS_ERR(priv->pclk))
-		return dev_err_probe(dev, PTR_ERR(priv->pclk), "failed to get core clock\n");
+	pclk = devm_clk_get_enabled(dev, "pclk");
+	if (IS_ERR(pclk))
+		return dev_err_probe(dev, PTR_ERR(pclk), "failed to get core clock\n");
 
 	priv->avdd = devm_regulator_get(dev, "AVDD");
 	if (IS_ERR(priv->avdd))
 		return dev_err_probe(dev, PTR_ERR(priv->avdd), "failed to AVDD\n");
 
-	ret = clk_prepare_enable(priv->pclk);
-	if (ret) {
-		dev_err(dev, "core clock enable failed\n");
-		return ret;
-	}
-
-	ret = devm_add_action_or_reset(dev,
-			(void(*)(void *))clk_disable_unprepare,
-			priv->pclk);
-	if (ret)
-		return ret;
-
 	ret = device_reset(dev);
 	if (ret) {
 		dev_err(dev, "reset failed\n");
-- 
2.43.0



From wsa+renesas at sang-engineering.com  Tue Feb 13 14:02:19 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Tue, 13 Feb 2024 23:02:19 +0100
Subject: [PATCH v2 0/6] mfd: tmio: simplify header and move to platform_data
Message-ID: <20240213220221.2380-8-wsa+renesas@sang-engineering.com>

Changes since v1:

* rebased to rc4
* collected all needed acks (Thanks!)
* capitalized first letter in commit subject

The MFD parts of the TMIO have been removed by Arnd, so that only the
SD/MMC related functionality is left. Remove the outdated remains in the
public header file and then move it to platform_data as the data is now
specific for the SD/MMC part.

Based on 6.8-rc4, build bot is happy. Branch is here:

git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git renesas/sdhi/tmio-simplification

(just missing Adrian's ack for SH which came just now)

We agreed already that this should go in via MFD. Thanks!

All the best!

   Wolfram


Wolfram Sang (6):
  mfd: tmio: Remove obsolete platform_data
  mfd: tmio: Remove obsolete io accessors
  mmc: tmio/sdhi: Fix includes
  mfd: tmio: Update include files
  mfd: tmio: Sanitize comments
  mfd: tmio: Move header to platform_data

 MAINTAINERS                                   |   2 +-
 arch/sh/boards/board-sh7757lcr.c              |   2 +-
 arch/sh/boards/mach-ap325rxa/setup.c          |   2 +-
 arch/sh/boards/mach-ecovec24/setup.c          |   2 +-
 arch/sh/boards/mach-kfr2r09/setup.c           |   2 +-
 arch/sh/boards/mach-migor/setup.c             |   2 +-
 arch/sh/boards/mach-se/7724/setup.c           |   2 +-
 drivers/mmc/host/renesas_sdhi_core.c          |   2 +-
 drivers/mmc/host/renesas_sdhi_internal_dmac.c |   5 +-
 drivers/mmc/host/renesas_sdhi_sys_dmac.c      |   5 +-
 drivers/mmc/host/tmio_mmc_core.c              |   3 +-
 drivers/mmc/host/uniphier-sd.c                |   2 +-
 include/linux/mfd/tmio.h                      | 133 ------------------
 include/linux/platform_data/tmio.h            |  64 +++++++++
 14 files changed, 81 insertions(+), 147 deletions(-)
 delete mode 100644 include/linux/mfd/tmio.h
 create mode 100644 include/linux/platform_data/tmio.h

-- 
2.43.0



From wsa+renesas at sang-engineering.com  Tue Feb 13 14:02:25 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Tue, 13 Feb 2024 23:02:25 +0100
Subject: [PATCH v2 6/6] mfd: tmio: Move header to platform_data
In-Reply-To: <20240213220221.2380-8-wsa+renesas@sang-engineering.com>
References: <20240213220221.2380-8-wsa+renesas@sang-engineering.com>
Message-ID: <20240213220221.2380-14-wsa+renesas@sang-engineering.com>

All the MFD components are gone from the header meanwhile. Only the MMC
relevant data is left which makes it a platform_data for the MMC
controller. Move the header to the now fitting directory.

Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
Acked-by: Lee Jones <lee at kernel.org>
Acked-by: Ulf Hansson <ulf.hansson at linaro.org> # For MMC
Acked-by: John Paul Adrian Glaubitz <glaubitz at physik.fu-berlin.de>
---
 MAINTAINERS                                   | 2 +-
 arch/sh/boards/board-sh7757lcr.c              | 2 +-
 arch/sh/boards/mach-ap325rxa/setup.c          | 2 +-
 arch/sh/boards/mach-ecovec24/setup.c          | 2 +-
 arch/sh/boards/mach-kfr2r09/setup.c           | 2 +-
 arch/sh/boards/mach-migor/setup.c             | 2 +-
 arch/sh/boards/mach-se/7724/setup.c           | 2 +-
 drivers/mmc/host/renesas_sdhi_core.c          | 2 +-
 drivers/mmc/host/renesas_sdhi_internal_dmac.c | 2 +-
 drivers/mmc/host/renesas_sdhi_sys_dmac.c      | 2 +-
 drivers/mmc/host/tmio_mmc_core.c              | 2 +-
 drivers/mmc/host/uniphier-sd.c                | 2 +-
 include/linux/{mfd => platform_data}/tmio.h   | 0
 13 files changed, 12 insertions(+), 12 deletions(-)
 rename include/linux/{mfd => platform_data}/tmio.h (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 73d898383e51..fb672e0bb0c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22153,7 +22153,7 @@ L:	linux-renesas-soc at vger.kernel.org
 S:	Supported
 F:	drivers/mmc/host/renesas_sdhi*
 F:	drivers/mmc/host/tmio_mmc*
-F:	include/linux/mfd/tmio.h
+F:	include/linux/platform_data/tmio.h
 
 TMP401 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux at roeck-us.net>
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
index f39c8196efdf..4014c042d2a5 100644
--- a/arch/sh/boards/board-sh7757lcr.c
+++ b/arch/sh/boards/board-sh7757lcr.c
@@ -14,9 +14,9 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/io.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_data/sh_mmcif.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/sh_eth.h>
 #include <linux/sh_intc.h>
 #include <linux/usb/renesas_usbhs.h>
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 645cccf3da88..bb5004a8ac02 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -24,10 +24,10 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/sh_flctl.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 30d117f9ad7e..6f13557eecd6 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -17,13 +17,13 @@
 #include <linux/input/sh_keysc.h>
 #include <linux/interrupt.h>
 #include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_data/sh_mmcif.h>
 #include <linux/mtd/physmap.h>
 #include <linux/gpio.h>
 #include <linux/gpio/machine.h>
 #include <linux/platform_data/gpio_backlight.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_data/tsc2007.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/fixed.h>
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 6b775eae85c0..70236859919d 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -22,10 +22,10 @@
 #include <linux/input/sh_keysc.h>
 #include <linux/interrupt.h>
 #include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_data/lv5207lp.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 773ee767d0c4..1853e6319a66 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -7,6 +7,7 @@
 #include <linux/clkdev.h>
 #include <linux/dma-map-ops.h>
 #include <linux/init.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
@@ -14,7 +15,6 @@
 #include <linux/memblock.h>
 #include <linux/mmc/host.h>
 #include <linux/mtd/physmap.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mtd/platnand.h>
 #include <linux/i2c.h>
 #include <linux/regulator/fixed.h>
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 787ddd3c627a..e500feb91053 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -21,9 +21,9 @@
 #include <linux/input/sh_keysc.h>
 #include <linux/interrupt.h>
 #include <linux/memblock.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mtd/physmap.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index c675dec587ef..f84f60139bcf 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -22,13 +22,13 @@
 #include <linux/delay.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/slot-gpio.h>
 #include <linux/module.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/pinctrl-state.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/regulator/consumer.h>
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
index 24e1c17908d7..97cd55fec0bf 100644
--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
@@ -11,12 +11,12 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io-64-nonatomic-hi-lo.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pagemap.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
index c18581897f8a..68e31c37cce6 100644
--- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
@@ -11,12 +11,12 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pagemap.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index c39141a5bd23..0c4397b3cffd 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -31,7 +31,6 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
@@ -39,6 +38,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pagemap.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c
index 1404989e6151..bd231dbe90ba 100644
--- a/drivers/mmc/host/uniphier-sd.c
+++ b/drivers/mmc/host/uniphier-sd.c
@@ -9,11 +9,11 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/mfd/syscon.h>
-#include <linux/mfd/tmio.h>
 #include <linux/mmc/host.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pinctrl/consumer.h>
+#include <linux/platform_data/tmio.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
diff --git a/include/linux/mfd/tmio.h b/include/linux/platform_data/tmio.h
similarity index 100%
rename from include/linux/mfd/tmio.h
rename to include/linux/platform_data/tmio.h
-- 
2.43.0



From robh at kernel.org  Tue Feb 13 14:28:08 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 16:28:08 -0600
Subject: [PATCH] Add eSPI device driver (flash channel)
In-Reply-To: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
References: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
Message-ID: <20240213222808.GA2490812-robh@kernel.org>

On Tue, Feb 13, 2024 at 08:06:08PM +0530, Manojkiran Eda wrote:
> This patch adds the driver support for the eSPI controller of
> Aspeed 5/6th generation SoCs. This controller is a slave device
> communicating with a master over Enhanced Serial Peripheral
> Interface (eSPI).
> 
> eSPI supports 4 channels, namely peripheral, virtual wire,
> out-of-band, and flash, and operates at max frequency of 66MHz.
> 
> But at the moment, this patch set only supports the flash channel.

You're not going to need binding changes to add support for those, 
right?

> 
> Signed-off-by: Manojkiran Eda <manojkiran.eda at gmail.com>
> ---
> Hello everyone,
> 
> I'm presenting a revised version of the eSPI device driver patch series found at the following link:
> 
> https://lore.kernel.org/openbmc/20220516005412.4844-1-chiawei_wang at aspeedtech.com/ 
> 
> This update addresses the issues identified during the review process.
> 
> While the previous patch series attempted to incorporate support for all four different channels of eSPI,
> this new series focuses on upstreaming the flash channel initially, ensuring that all review comments are
> duly addressed, before progressing further.
> 
> Results:
> 
> Successfully conducted a flash update via eSPI.
> 
> Note:
> 
> This marks my inaugural endeavor in contributing code to the kernel subsystem. I kindly request reviewers
> to incorporate as many details as possible in the review comments.

Please start with submitting-patches.rst and the DT specific version of 
that.

> ---
>  .../devicetree/bindings/soc/aspeed/espi.yaml       | 125 ++++++

This should be a separate patch. checkpatch.pl will tell you this and 
other things.

Filename should match compatible.

>  arch/arm/boot/dts/aspeed/aspeed-g6.dtsi            |  16 +-

This is another patch.

>  drivers/mtd/mtdcore.c                              |   2 +-

Yet another patch. But really, this one will be rejected most likely 
unless you can justify why it is needed.

>  drivers/soc/aspeed/Kconfig                         |  10 +
>  drivers/soc/aspeed/Makefile                        |   3 +
>  drivers/soc/aspeed/aspeed-espi-ctrl.c              | 197 +++++++++
>  drivers/soc/aspeed/aspeed-espi-ctrl.h              | 169 ++++++++
>  drivers/soc/aspeed/aspeed-espi-flash.c             | 466 +++++++++++++++++++++
>  drivers/soc/aspeed/aspeed-espi-flash.h             |  45 ++
>  include/uapi/linux/espi/aspeed-espi-ioc.h          | 103 +++++

Your own interface to userspace is probably not going to be accepted 
either.

>  10 files changed, 1134 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/soc/aspeed/espi.yaml b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> new file mode 100644
> index 000000000000..6521a351d18d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> @@ -0,0 +1,125 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# # Copyright (c) 2021 Aspeed Technology Inc.

It's 2024 now.

> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/soc/aspeed/espi.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Aspeed eSPI Controller
> +
> +maintainers:
> +  - Manojkiran Eda <manojkiran.eda at gmail.com>
> +  - Patrick Rudolph <patrick.rudolph at 9elements.com>
> +  - Chia-Wei Wang <chiawei_wang at aspeedtech.com>
> +  - Ryan Chen <ryan_chen at aspeedtech.com>
> +
> +description:
> +  Aspeed eSPI controller implements a slave side eSPI endpoint device

s/slave/device/

> +  supporting the four eSPI channels, namely peripheral, virtual wire,
> +  out-of-band, and flash.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - aspeed,ast2500-espi
> +          - aspeed,ast2600-espi
> +      - const: simple-mfd
> +      - const: syscon
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#address-cells":
> +    const: 1
> +
> +  "#size-cells":
> +    const: 1
> +
> +  ranges: true
> +
> +patternProperties:
> +  "^espi-ctrl@[0-9a-f]+$":
> +    type: object

Is this really a separate sub-block? As in could it be reused somewhere 
else or in a different combination of blocks?

> +
> +    description: Control of the four basic eSPI channels
> +
> +    properties:
> +      compatible:
> +        items:
> +          - enum:
> +              - aspeed,ast2500-espi-ctrl
> +              - aspeed,ast2600-espi-ctrl
> +
> +      interrupts:
> +        maxItems: 1
> +
> +      clocks:
> +        maxItems: 1
> +
> +      flash,dma-mode:
> +        type: boolean
> +        description: Enable DMA support for eSPI flash channel
> +
> +      flash,safs-mode:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        enum: [ 0, 1, 2 ]
> +        default: 0
> +        description: Slave-Attached-Sharing-Flash mode, 0->Mix, 1->SW, 2->HW
> +
> +    required:
> +      - compatible
> +      - interrupts
> +      - clocks
> +
> +  "^espi-mmbi@[0-9a-f]+$":
> +    type: object

Is this really a separate sub-block?

> +
> +    description: Control of the PCH-BMC data exchange over eSPI peripheral memory cycle
> +
> +    properties:
> +      compatible:
> +        const: aspeed,ast2600-espi-mmbi
> +
> +      interrupts:
> +        maxItems: 1
> +
> +    required:
> +      - compatible
> +      - interrupts
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#address-cells"
> +  - "#size-cells"
> +  - ranges
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/ast2600-clock.h>
> +
> +    espi: espi at 1e6ee000 {
> +        compatible = "aspeed,ast2600-espi", "simple-mfd", "syscon";
> +        reg = <0x1e6ee000 0x1000>;
> +
> +        #address-cells = <1>;
> +        #size-cells = <1>;
> +        ranges = <0x0 0x1e6ee000 0x1000>;
> +
> +        espi_ctrl: espi-ctrl at 0 {
> +            compatible = "aspeed,ast2600-espi-ctrl";
> +            reg = <0x0 0x800>;
> +            interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
> +            clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
> +        };
> +
> +        espi_mmbi: espi-mmbi at 800 {
> +            compatible = "aspeed,ast2600-espi-mmbi";
> +            reg = <0x800 0x50>;
> +            interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
> +        };
> +    };
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
> index c4d1faade8be..08d7a2689086 100644
> --- a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
> +++ b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
> @@ -453,7 +453,21 @@ video: video at 1e700000 {
>  				interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
>  				status = "disabled";
>  			};
> -
> +			espi: espi at 1e6ee000 {
> +				compatible = "aspeed,ast2600-espi", "simple-mfd", "syscon";
> +				reg = <0x1e6ee000 0x1000>;
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +				ranges = <0x0 0x1e6ee000 0x1000>;
> +				espi_ctrl: espi-ctrl at 0 {
> +						compatible = "aspeed,ast2600-espi-ctrl";
> +						reg = <0x0 0x800>,<0x0 0x4000000>;
> +						reg-names = "espi_ctrl","espi_flash";
> +						interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
> +						clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
> +						status = "disabled";
> +						};

Wrong indentation.

> +			};
>  			gpio0: gpio at 1e780000 {
>  				#gpio-cells = <2>;
>  				gpio-controller;


From robh at kernel.org  Tue Feb 13 14:29:57 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 16:29:57 -0600
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename
 qcom,dsb-element-size
In-Reply-To: <20240213160521.15925-2-quic_jinlmao@quicinc.com>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
 <20240213160521.15925-2-quic_jinlmao@quicinc.com>
Message-ID: <20240213222957.GA2502642-robh@kernel.org>

On Tue, Feb 13, 2024 at 08:05:17AM -0800, Mao Jinlong wrote:
> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
> bit.

That may be, but this is an ABI and you are stuck with it. Unless, you 
can justify why that doesn't matter. (IIRC, this is new, so maybe no 
users yet?)


From robh at kernel.org  Tue Feb 13 14:31:30 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 13 Feb 2024 16:31:30 -0600
Subject: [PATCH v10 2/4] dt-bindings: remoteproc: add Tightly Coupled
 Memory (TCM) bindings
In-Reply-To: <b931a24c-f676-4ddb-bb7c-e7a509d5dd4b@amd.com>
References: <20240213175450.3097308-1-tanmay.shah@amd.com>
 <20240213175450.3097308-3-tanmay.shah@amd.com>
 <170785205177.2155555.1311787541370066483.robh@kernel.org>
 <b931a24c-f676-4ddb-bb7c-e7a509d5dd4b@amd.com>
Message-ID: <20240213223130.GA2504650-robh@kernel.org>

On Tue, Feb 13, 2024 at 02:37:49PM -0600, Tanmay Shah wrote:
> Hello,
> 
> Thanks for reviews please find my comments below.
> 
> On 2/13/24 1:20 PM, Rob Herring wrote:
> > On Tue, 13 Feb 2024 09:54:48 -0800, Tanmay Shah wrote:
> > > From: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
> > > 
> > > Introduce bindings for TCM memory address space on AMD-xilinx Zynq
> > > UltraScale+ platform. It will help in defining TCM in device-tree
> > > and make it's access platform agnostic and data-driven.
> > > 
> > > Tightly-coupled memories(TCMs) are low-latency memory that provides
> > > predictable instruction execution and predictable data load/store
> > > timing. Each Cortex-R5F processor contains two 64-bit wide 64 KB memory
> > > banks on the ATCM and BTCM ports, for a total of 128 KB of memory.
> > > 
> > > The TCM resources(reg, reg-names and power-domain) are documented for
> > > each TCM in the R5 node. The reg and reg-names are made as required
> > > properties as we don't want to hardcode TCM addresses for future
> > > platforms and for zu+ legacy implementation will ensure that the
> > > old dts w/o reg/reg-names works and stable ABI is maintained.
> > > 
> > > It also extends the examples for TCM split and lockstep modes.
> > > 
> > > Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
> > > Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
> > > ---
> > > 
> > > Changes in v10:
> > >   - modify number of "reg", "reg-names" and "power-domains" entries
> > >     based on cluster mode
> > >   - Add extra optional atcm and btcm in "reg" property for lockstep mode
> > >   - Add "reg-names" for extra optional atcm and btcm for lockstep mode
> > >   - Drop previous Ack as bindings has new change
> > > 
> > > Changes in v9:
> > >   - None
> > > Changes in v8:
> > >   - None
> > > Changes in v7:
> > >   - None
> > > Changes in v6:
> > >   - None
> > > Changes in v5:
> > >   - None
> > > 
> > > Changes in v4:
> > >   - Use address-cells and size-cells value 2
> > >   - Modify ranges property as per new value of address-cells
> > >     and size-cells
> > >   - Modify child node "reg" property accordingly
> > >   - Remove previous ack for further review
> > > 
> > > v4 link: https://lore.kernel.org/all/20230829181900.2561194-2-tanmay.shah at amd.com/
> > > 
> > >  .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 ++++++++++++++++--
> > >  1 file changed, 170 insertions(+), 22 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:
> > ./Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml:118:13: [warning] wrong indentation: expected 10 but found 12 (indentation)
> Ack. I will fix this.
> 
> However, can I still get reviews on patch itself so if something else needs to be fixed I can fix in next revision as well.
> 
> Also, I tried to run yamllint with following command:
> 
> make DT_CHECKER_FLAGS=-m dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml O=../build/zynqmp/linux-next/
> 
> 
> However, I see following logs without any error on bindings:
> 
> ? LINT??? Documentation/devicetree/bindings
> invalid config: unknown option "required" for rule "quoted-strings"
> *xargs: /usr/bin/yamllint: exited with status 255; aborting*
> ? CHKDT?? Documentation/devicetree/bindings/processed-schema.json
> ? SCHEMA? Documentation/devicetree/bindings/processed-schema.json
> ? DTEX??? Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.example.dts
> ? DTC_CHK Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.example.dtb
> 
> I am not sure if my system is missing something but, yamllint tool is failing.

"unknown option" means old version of yamllint.

Rob


From ionela.voinescu at arm.com  Tue Feb 13 15:02:49 2024
From: ionela.voinescu at arm.com (Ionela Voinescu)
Date: Tue, 13 Feb 2024 23:02:49 +0000
Subject: [PATCH] cpufreq: CPPC: Resolve the large frequency discrepancy
 from cpuinfo_cur_freq
In-Reply-To: <ZcYEjMO7IhSaLAAF@e129154.nice.arm.com>
References: <9428a1ed-ba4d-1fe6-63e8-11e152bf1f09@huawei.com>
 <lnocwcitdbmgcyhd2dlczgdlhtfw4pfot2br2i3hqscnvr3xgq@nuxlauxum3nr>
 <d0f47e9d-6a58-8b46-89be-b3182abb69f0@huawei.com>
 <ZZwAmqp6hcmMF8aN@arm.com>
 <6505bdcb-5a5f-cba6-483b-75c51414a9c6@huawei.com>
 <ZaaOQzCpBjmW71xf@e129154.nice.arm.com>
 <a84a9749-97a5-a207-dfd3-8322a5a992d9@huawei.com>
 <Zbyi40XtqbqXm0CL@e129154.nice.arm.com>
 <4f66c62e-b089-a125-5a8d-4a98d4181618@huawei.com>
 <ZcYEjMO7IhSaLAAF@e129154.nice.arm.com>
Message-ID: <Zcv1GXN711uI6ykr@arm.com>

Hi,

On Friday 09 Feb 2024 at 11:55:08 (+0100), Beata Michalska wrote:
> On Tue, Feb 06, 2024 at 04:02:15PM +0800, lihuisong (C) wrote:
[..]
> > > > > > 
> > > > > > > Would you be able to test [1] on your platform and usecase?
> > > > > > I has tested it on my platform (CPU number: 64, SMT: off and CPU base
> > > > > > frequency: 2.7GHz).
> > > > > > Accoding to the testing result,
> > > > > > 1> I found that patch [1] and [2] cannot cover the no housekeeping CPUs.
> > > > > > They still have to face the large frequency discrepancy issue my patch
> > > > > > mentioned.
> > > > > > 2> Additionally, the frequency value of all CPUs are almost the same by
> > > > > > using the 'arch_freq_scale' factor way. I'm not sure if it is ok.
> > > > > > 
> > > > > > The patch [1] has been modified silightly as below:
> > > > > > -->
> > > > > > @@ -1756,7 +1756,10 @@ static unsigned int
> > > > > > cpufreq_verify_current_freq(struct cpufreq_policy *policy, b
> > > > > >   ?{
> > > > > >   ??????? unsigned int new_freq;
> > > > > > 
> > > > > > -?????? new_freq = cpufreq_driver->get(policy->cpu);
> > > > > > +?????? new_freq = arch_freq_get_on_cpu(policy->cpu);
> > > > > > +?????? if (!new_freq)
> > > > > > +?????????????? new_freq = cpufreq_driver->get(policy->cpu);
> > > > > > +
> > > > > As pointed out this change will not make it to the next version of the patch.
> > > > > So I'd say you can safely ignore it and assume that arch_freq_get_on_cpu will
> > > > > only be wired for sysfs nodes for scaling_cur_freq/cpuinfo_cur_freq
> > > > > >   ??????? if (!new_freq)
> > > > > >   ??????????????? return 0;
> > > > > > 
> > > > > > And the result is as follows:
> > > > > > *case 1:**No setting the nohz_full and cpufreq use performance governor*
> > > > > > *--> Step1: *read 'cpuinfo_cur_freq' in no pressure
> > > > > >   ? 0: 2699264???? 2: 2699264???? 4: 2699264???? 6: 2699264
> > > > > >   ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2699264
> > > > > >   ?16: 2699264??? 18: 2696628??? 20: 2699264??? 22: 2696628
> > > > > >   ?24: 2699264??? 26: 2696628??? 28: 2699264??? 30: 2696628
> > > > > >   ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
> > > > > >   ?40: 2699264??? 42: 2699264??? 44: 2696628??? 46: 2696628
> > > > > >   ?48: 2696628??? 50: 2699264??? 52: 2699264??? 54: 2696628
> > > > > >   ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
> > > > > >   ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2696628
> > > > > >   ?72: 2699264??? 74: 2696628??? 76: 2696628??? 78: 2699264
> > > > > >   ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
> > > > > >   ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2699264
> > > > > >   ?96: 2696628??? 98: 2699264?? 100: 2699264?? 102: 2696628
> > > > > > 104: 2699264?? 106: 2699264?? 108: 2699264?? 110: 2696628
> > > > > > 112: 2699264?? 114: 2699264?? 116: 2699264?? 118: 2699264
> > > > > > 120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2699264
> > > > > > Note: the frequency of all CPUs are almost the same.
> > > > > Were you expecting smth else ?
> > > > The frequency of each CPU might have a different value.
> > > > All value of all CPUs is the same under high pressure.
> > > > I don't know what the phenomenon is on other platform.
> > > > Do you know who else tested it?
> > > So I might have rushed a bit with my previous comment/question: apologies for
> > > that.
> > > The numbers above: those are on a fairly idle/lightly loaded system right?
> > Yes.
> > > Would you mind having another go with just the arch_freq_get_on_cpu
> > > implementation beign added and dropping the changes in the cpufreq and
> > All my tests are done when cpufreq policy is "performance" and OS isn't on a
> > high load.
> > Reading "scaling_cur_freq" or "scaling_cur_freq" for each physical core on
> > platform
> > 
> > The testing result for "cpuinfo_cur_freq" with your changes on a fairly idle
> > and high loaded system can also be found in this thread.
> > *A: the result with your changes*
> > --> Reading "scaling_cur_freq"
> > ? 0: 2688720???? 2: 2696628???? 4: 2699264???? 6: 2696628
> > ? 8: 2699264??? 10: 2696628??? 12: 2699264??? 14: 2699264
> > ?16: 2699264??? 18: 2696628??? 20: 2696628??? 22: 2696628
> > ?24: 2699264??? 26: 2696628??? 28: 2696628??? 30: 2696628
> > ?32: 2699264??? 34: 2691356??? 36: 2696628??? 38: 2699264
> > ?40: 2699264??? 42: 2696628??? 44: 2696628??? 46: 2699264
> > ?48: 2699264??? 50: 2696628??? 52: 2696628??? 54: 2696628
> > ?56: 2696628??? 58: 2699264??? 60: 2691356??? 62: 2696628
> > ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
> > ?72: 2696628??? 74: 2696628??? 76: 2699264??? 78: 2696628
> > ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
> > ?88: 2625456??? 90: 2696628??? 92: 2699264??? 94: 2696628
> > ?96: 2696628??? 98: 2696628?? 100: 2699264?? 102: 2699264
> > 104: 2699264?? 106: 2696628?? 108: 2699264?? 110: 2696628
> > 112: 2699264?? 114: 2699264?? 116: 2696628?? 118: 2696628
> > 120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2696628
> > -->Reading? "cpuinfo_cur_freq"
> > ? 0: 2696628???? 2: 2696628???? 4: 2699264???? 6: 2688720
> > ? 8: 2699264??? 10: 2700000??? 12: 2696628??? 14: 2698322
> > ?16: 2699264??? 18: 2699264??? 20: 2696628??? 22: 2699264
> > ?24: 2699264??? 26: 2699264??? 28: 2699264??? 30: 2699264
> > ?32: 2699264??? 34: 2693992??? 36: 2696628??? 38: 2696628
> > ?40: 2699264??? 42: 2699264??? 44: 2699264??? 46: 2696628
> > ?48: 2696628??? 50: 2699264??? 52: 2696628??? 54: 2696628
> > ?56: 2699264??? 58: 2699264??? 60: 2696628??? 62: 2699264
> > ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2699264
> > ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2693992
> > ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
> > ?88: 2696628??? 90: 2699264??? 92: 2696628??? 94: 2699264
> > ?96: 2699264??? 98: 2696628?? 100: 2699264?? 102: 2699264
> > 104: 2691356?? 106: 2699264?? 108: 2699264?? 110: 2699264
> > 112: 2699264?? 114: 2696628?? 116: 2699264?? 118: 2699264
> > 120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628
> > 
> > *B: the result without your changes*
> > -->Reading "scaling_cur_freq"
> > ? 0: 2698245???? 2: 2706690???? 4: 2699649???? 6: 2702105
> > ? 8: 2704362??? 10: 2697993??? 12: 2701672??? 14: 2704362
> > ?16: 2701052??? 18: 2701052??? 20: 2694385??? 22: 2699650
> > ?24: 2706802??? 26: 2702389??? 28: 2698299??? 30: 2698299
> > ?32: 2697333??? 34: 2697993??? 36: 2701337??? 38: 2699328
> > ?40: 2700330??? 42: 2700330??? 44: 2698019??? 46: 2697697
> > ?48: 2699659??? 50: 2701700??? 52: 2703401??? 54: 2701700
> > ?56: 2704013??? 58: 2697658??? 60: 2695000??? 62: 2697666
> > ?64: 2697902??? 66: 2701052??? 68: 2698245??? 70: 2695789
> > ?72: 2701315??? 74: 2696655??? 76: 2693666??? 78: 2695317
> > ?80: 2704912??? 82: 2699649??? 84: 2698245??? 86: 2695454
> > ?88: 2697966??? 90: 2697959??? 92: 2699319??? 94: 2700680
> > ?96: 2695317??? 98: 2698996?? 100: 2700000?? 102: 2700334
> > 104: 2701320?? 106: 2695065?? 108: 2700986?? 110: 2703960
> > 112: 2697635?? 114: 2704421?? 116: 2700680?? 118: 2702040
> > 120: 2700334?? 122: 2697993?? 124: 2700334?? 126: 2705351
> > -->Reading "cpuinfo_cur_freq"
> > ? 0: 2696853???? 2: 2695454???? 4: 2699649???? 6: 2706993
> > ? 8: 2706060??? 10: 2704362??? 12: 2704362??? 14: 2697658
> > ?16: 2707719??? 18: 2697192??? 20: 2702456??? 22: 2699650
> > ?24: 2705782??? 26: 2698299??? 28: 2703061??? 30: 2705802
> > ?32: 2700000??? 34: 2700671??? 36: 2701337??? 38: 2697658
> > ?40: 2700330??? 42: 2700330??? 44: 2699672??? 46: 2697697
> > ?48: 2703061??? 50: 2696610??? 52: 2692542??? 54: 2704406
> > ?56: 2695317??? 58: 2699331??? 60: 2698996??? 62: 2702675
> > ?64: 2704912??? 66: 2703859??? 68: 2699649??? 70: 2698596
> > ?72: 2703908??? 74: 2703355??? 76: 2697658??? 78: 2695317
> > ?80: 2702105??? 82: 2707719??? 84: 2702105??? 86: 2699649
> > ?88: 2697966??? 90: 2691525??? 92: 2701700??? 94: 2700680
> > ?96: 2695317??? 98: 2698996?? 100: 2698666?? 102: 2700334
> > 104: 2690429?? 106: 2707590?? 108: 2700986?? 110: 2701320
> > 112: 2696283?? 114: 2692881?? 116: 2697627?? 118: 2704421
> > 120: 2698996?? 122: 2696321?? 124: 2696655?? 126: 2695000
> >
> So in both cases : whether you use arch_freq_get_on_cpu or not
> (so with and without the patch) you get roughly the same frequencies
> on all cores - or am I missing smth from the dump above ?
> And those are reflecting max freq you have provided earlier (?)
> Note that the arch_freq_get_on_cpu will return an average frequency for
> the last tick, so even if your system is roughly idle with your performance
> governor those numbers make sense (some/most of the cores might be idle
> but you will see the last freq the core was running at before going to idle).
> I do not think there is an agreement what should be shown for idle core when
> querying their freq through sysfs. Showing last known freq makes sense, even
> more than waking up core just to try to get one.
> 
> @Ionela: Please jump in if I got things wrong.

Yes, that's how I see things as well. When using the performance
governor, when the CPU is active, the frequency of the CPU should be the
maximum one (unless there has been firmware/hardware capping) and that
would be reflected by cpuinfo_cur_freq, either through the use of the
frequency scale factor (based on the samples on the last tick)  or the
driver's .get() function (having woken up the CPU to sample the
counters).

So the values above look alright to me.

Thanks,
Ionela.

> 
> > > then read 'scaling_cur_freq', doing several reads in some intervals ?
> > It seems that above phenomenon has not a lot to do with reading intervals.
> > > The change has been tested on RD-N2 model (Neoverse N2 ref platform),
> > > it has also been discussed here [1]
> > I doesn't get the testing result on this platform in its thread.
> It might be missing exact numbers but the conclusions should be here [1]
> 
> > > > > > *--> Step 2: *read 'cpuinfo_cur_freq' in the high memory access pressure.
> > > > > >   ? 0: 2696628???? 2: 2696628???? 4: 2696628???? 6: 2696628
> > > > > >   ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2696628
> > > > > >   ?16: 2696628??? 18: 2696628??? 20: 2696628??? 22: 2696628
> > > > > >   ?24: 2696628??? 26: 2696628??? 28: 2696628??? 30: 2696628
> > > > > >   ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
> > > > > >   ?40: 2696628??? 42: 2696628??? 44: 2696628??? 46: 2696628
> > > > > >   ?48: 2696628??? 50: 2696628??? 52: 2696628??? 54: 2696628
> > > > > >   ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
> > > > > >   ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
> > > > > >   ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2696628
> > > > > >   ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
> > > > > >   ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2696628
> > > > > >   ?96: 2696628??? 98: 2696628?? 100: 2696628?? 102: 2696628
> > > > > > 104: 2696628?? 106: 2696628?? 108: 2696628?? 110: 2696628
> > > > > > 112: 2696628?? 114: 2696628?? 116: 2696628?? 118: 2696628
> > > > > > 120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628
> > > > > > 
> > > > > > *Case 2: setting nohz_full and cpufreq use ondemand governor*
> > > > > > There is "isolcpus=1-10,41-50 nohz_full=1-10,41-50 rcu_nocbs=1-10,41-50" in
> > > > > > /proc/cmdline.
> > > > > Right, so if I remember correctly nohz_full implies rcu_nocbs, so no need to
> > > > > set that one.
> > > > > Now, afair, isolcpus will make the selected CPUs to disappear from the
> > > > > schedulers view (no balancing, no migrating), so unless you affine smth
> > > > > explicitly to those CPUs, you will not see much of an activity there.
> > > > Correct.
> > > > > Need to double check though as it has been a while ...
> > > > > > *--> Step 1: *setting ondemand governor to all policy and query
> > > > > > 'cpuinfo_cur_freq' in no pressure case.
> > > > > > And the frequency of CPUs all are about 400MHz.
> > > > > > *--> Step 2:* read 'cpuinfo_cur_freq' in the high memory access pressure.
> > > > > > The high memory access pressure is from the command: "stress-ng -c 64
> > > > > > --cpu-load 100% --taskset 0-63"
> > > > > I'm not entirely convinced that this will affine to isolated cpus, especially
> > > > > that the affinity mask spans all available cpus. If that is the case, no wonder
> > > > > your isolated cpus are getting wasted being idle. But I would have to double
> > > > > check how this is being handled.
> > > > > > The result:
> > > > > >   ?0: 2696628???? 1:? 400000???? 2:? 400000???? 3:? 400909
> > > > > >   ?4:? 400000???? 5:? 400000???? 6:? 400000???? 7:? 400000
> > > > > >   ?8:? 400000???? 9:? 400000??? 10:? 400600??? 11: 2696628
> > > > > > 12: 2696628??? 13: 2696628??? 14: 2696628??? 15: 2696628
> > > > > > 16: 2696628??? 17: 2696628??? 18: 2696628??? 19: 2696628
> > > > > > 20: 2696628??? 21: 2696628??? 22: 2696628??? 23: 2696628
> > > > > > 24: 2696628??? 25: 2696628??? 26: 2696628??? 27: 2696628
> > > > > > 28: 2696628??? 29: 2696628??? 30: 2696628??? 31: 2696628
> > > > > > 32: 2696628??? 33: 2696628??? 34: 2696628??? 35: 2696628
> > > > > > 36: 2696628??? 37: 2696628??? 38: 2696628??? 39: 2696628
> > > > > > 40: 2696628??? 41:? 400000??? 42:? 400000??? 43:? 400000
> > > > > > 44:? 400000??? 45:? 398847??? 46:? 400000??? 47:? 400000
> > > > > > 48:? 400000??? 49:? 400000??? 50:? 400000??? 51: 2696628
> > > > > > 52: 2696628??? 53: 2696628??? 54: 2696628??? 55: 2696628
> > > > > > 56: 2696628??? 57: 2696628??? 58: 2696628??? 59: 2696628
> > > > > > 60: 2696628??? 61: 2696628??? 62: 2696628??? 63: 2699264
> > > > > > 
> > > > > > Note:
> > > > > > (1) The frequency of 1-10 and 41-50 CPUs work on the lowest frequency.
> > > > > >   ???? It turned out that nohz full was already work.
> > > > > >   ???? I guess that stress-ng cannot use the CPU in the range of nohz full.
> > > > > >   ???? Because the CPU frequency will be increased to 2.7G by binding CPU to
> > > > > > other application.
> > > > > > (2) The frequency of the nohz full core is calculated by get() callback
> > > > > > according to ftrace.
> > > > > It is as there is no sched tick on those, and apparently there is nothing
> > > > > running on them either.
> > > > Yes.
> > > > If we select your approach and the above phenomenon is normal,
> > > > the large frequency discrepancy issue can be resolved for CPUs with sched
> > > > tick by the way.
> > > > But the nohz full cores still have to face this issue. So this patch is also
> > > > needed.
> > > > 
> > > Yes, nohz cores full have to be handled by the cpufreq driver.
> > Correct. So we still have to face the issue in this patch and push this
> > patch.
> > Beata, would you please review this patch?
> Just to clarify for my benefit (apologies but I do have to contex switch
> pretty often these days): by reviewing this patch do you mean:
> 1) review your changes (if so I think there are few comments already to be
> addressed, but I can try to have another look)
> 2) review changes for AMU-based arch_freq_get_on_cpu ?
> 
> *note: I will still try to have a look at the non-housekeeping cpus case
> 
> ---
> [1] https://lore.kernel.org/lkml/691d3eb2-cd93-f0fc-a7a4-2a8c0d44262c at nvidia.com/
> ---
> 
> BR
> Beata
> > 
> > 
> > /Huisong
> > > 
> [...]


From broonie at kernel.org  Tue Feb 13 15:06:33 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 23:06:33 +0000
Subject: [PATCH v3 2/2] arm64/sme: Restore SMCR_EL1.EZT0 on exit from
 suspend
In-Reply-To: <20240213-arm64-sme-resume-v3-0-17e05e493471@kernel.org>
References: <20240213-arm64-sme-resume-v3-0-17e05e493471@kernel.org>
Message-ID: <20240213-arm64-sme-resume-v3-2-17e05e493471@kernel.org>

The fields in SMCR_EL1 reset to an architecturally UNKNOWN value. Since we
do not otherwise manage the traps configured in this register at runtime we
need to reconfigure them after a suspend in case nothing else was kind
enough to preserve them for us. Do so for SMCR_EL1.EZT0.

Fixes: d4913eee152d (arm64/sme: Add basic enumeration for SME2)
Reported-by: Jackson Cooper-Driver <Jackson.Cooper-Driver at arm.com>
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 8d2a5824d5d3..7a7c056f0647 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1320,6 +1320,8 @@ void sme_suspend_exit(void)
 
 	if (system_supports_fa64())
 		smcr |= SMCR_ELx_FA64;
+	if (system_supports_sme2())
+		smcr |= SMCR_ELx_EZT0;
 
 	write_sysreg_s(smcr, SYS_SMCR_EL1);
 	write_sysreg_s(0, SYS_SMPRI_EL1);

-- 
2.30.2



From broonie at kernel.org  Tue Feb 13 15:06:32 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 23:06:32 +0000
Subject: [PATCH v3 1/2] arm64/sme: Restore SME registers on exit from
 suspend
In-Reply-To: <20240213-arm64-sme-resume-v3-0-17e05e493471@kernel.org>
References: <20240213-arm64-sme-resume-v3-0-17e05e493471@kernel.org>
Message-ID: <20240213-arm64-sme-resume-v3-1-17e05e493471@kernel.org>

The fields in SMCR_EL1 and SMPRI_EL1 reset to an architecturally UNKNOWN
value. Since we do not otherwise manage the traps configured in this
register at runtime we need to reconfigure them after a suspend in case
nothing else was kind enough to preserve them for us.

The vector length will be restored as part of restoring the SME state for
the next SME using task.

Fixes: a1f4ccd25cc2 (arm64/sme: Provide Kconfig for SME)
Reported-by: Jackson Cooper-Driver <Jackson.Cooper-Driver at arm.com>
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h |  2 ++
 arch/arm64/kernel/fpsimd.c      | 14 ++++++++++++++
 arch/arm64/kernel/suspend.c     |  3 +++
 3 files changed, 19 insertions(+)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 50e5f25d3024..7780d343ef08 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -386,6 +386,7 @@ extern void sme_alloc(struct task_struct *task, bool flush);
 extern unsigned int sme_get_vl(void);
 extern int sme_set_current_vl(unsigned long arg);
 extern int sme_get_current_vl(void);
+extern void sme_suspend_exit(void);
 
 /*
  * Return how many bytes of memory are required to store the full SME
@@ -421,6 +422,7 @@ 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; }
+static inline void sme_suspend_exit(void) { }
 
 static inline size_t sme_state_size(struct task_struct const *task)
 {
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a5dc6f764195..8d2a5824d5d3 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1311,6 +1311,20 @@ void __init sme_setup(void)
 		get_sme_default_vl());
 }
 
+void sme_suspend_exit(void)
+{
+	u64 smcr = 0;
+
+	if (!system_supports_sme())
+		return;
+
+	if (system_supports_fa64())
+		smcr |= SMCR_ELx_FA64;
+
+	write_sysreg_s(smcr, SYS_SMCR_EL1);
+	write_sysreg_s(0, SYS_SMPRI_EL1);
+}
+
 #endif /* CONFIG_ARM64_SME */
 
 static void sve_init_regs(void)
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index eca4d0435211..eaaff94329cd 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -12,6 +12,7 @@
 #include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/exec.h>
+#include <asm/fpsimd.h>
 #include <asm/mte.h>
 #include <asm/memory.h>
 #include <asm/mmu_context.h>
@@ -80,6 +81,8 @@ void notrace __cpu_suspend_exit(void)
 	 */
 	spectre_v4_enable_mitigation(NULL);
 
+	sme_suspend_exit();
+
 	/* Restore additional feature-specific configuration */
 	ptrauth_suspend_exit();
 }

-- 
2.30.2



From broonie at kernel.org  Tue Feb 13 15:06:31 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 13 Feb 2024 23:06:31 +0000
Subject: [PATCH v3 0/2] arm64/sme: Fix handling of traps on resume
Message-ID: <20240213-arm64-sme-resume-v3-0-17e05e493471@kernel.org>

The fast model was recently changed to reset system registers to 0 on
resume, exposing the fact that for SME we do not restore the
configuration of traps for extensions that add state.  Fix this.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
Changes in v3:
- Tweak commit message.
- Link to v2: https://lore.kernel.org/r/20240203-arm64-sme-resume-v2-0-a1fbaddc4425 at kernel.org

Changes in v2:
- Also reinitialise SMPRI_EL1.
- Link to v1: https://lore.kernel.org/r/20240130-arm64-sme-resume-v1-0-0e60ebba18df at kernel.org

---
Mark Brown (2):
      arm64/sme: Restore SME registers on exit from suspend
      arm64/sme: Restore SMCR_EL1.EZT0 on exit from suspend

 arch/arm64/include/asm/fpsimd.h |  2 ++
 arch/arm64/kernel/fpsimd.c      | 16 ++++++++++++++++
 arch/arm64/kernel/suspend.c     |  3 +++
 3 files changed, 21 insertions(+)
---
base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
change-id: 20240129-arm64-sme-resume-3266150292b6

Best regards,
-- 
Mark Brown <broonie at kernel.org>



From dianders at chromium.org  Tue Feb 13 15:24:03 2024
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 13 Feb 2024 15:24:03 -0800
Subject: [PATCH 19/22] arm64: dts: qcom: sc7180: quackingstick: Disable
 instead of delete usb_c1
In-Reply-To: <20240210070934.2549994-20-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-20-swboyd@chromium.org>
Message-ID: <CAD=FV=XxX9wqZdwf9Wtq2=KOKgTr5FhyJJWp8S9W1xFW3cY80Q@mail.gmail.com>

Hi,

On Fri, Feb 9, 2024 at 11:10?PM Stephen Boyd <swboyd at chromium.org> wrote:
>
> It's simpler to reason about things if we disable nodes instead of
> deleting them. Disable the second usb type-c connector node on
> quackingstick instead of deleting it so that we can reason about ports
> more easily.
>
> Cc: <cros-qcom-dts-watchers at chromium.org>
> Cc: Andy Gross <agross at kernel.org>
> Cc: Bjorn Andersson <andersson at kernel.org>
> Cc: Konrad Dybcio <konrad.dybcio at linaro.org>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: <linux-arm-msm at vger.kernel.org>
> Cc: <devicetree at vger.kernel.org>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  .../arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)

Bjorn: happy to see this landed any time to shorten Stephen's series.

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From dianders at chromium.org  Tue Feb 13 15:24:20 2024
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 13 Feb 2024 15:24:20 -0800
Subject: [PATCH 20/22] arm64: dts: qcom: sc7180: pazquel: Add missing
 comment header
In-Reply-To: <20240210070934.2549994-21-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-21-swboyd@chromium.org>
Message-ID: <CAD=FV=XH=yJdEKSmOq50mXw12hsBc0-oWmhnc4h_itGqfoEjfA@mail.gmail.com>

Hi,

On Fri, Feb 9, 2024 at 11:10?PM Stephen Boyd <swboyd at chromium.org> wrote:
>
> We put a header before modifying pinctrl nodes defined in
> sc7180-trogdor.dtsi in every other file. Add one here so we know that
> this section is for pinctrl modifications.
>
> Cc: <cros-qcom-dts-watchers at chromium.org>
> Cc: Andy Gross <agross at kernel.org>
> Cc: Bjorn Andersson <andersson at kernel.org>
> Cc: Konrad Dybcio <konrad.dybcio at linaro.org>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: <linux-arm-msm at vger.kernel.org>
> Cc: <devicetree at vger.kernel.org>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  arch/arm64/boot/dts/qcom/sc7180-trogdor-pazquel.dtsi | 2 ++
>  1 file changed, 2 insertions(+)

Bjorn: happy to see this landed any time to shorten Stephen's series.

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From dianders at chromium.org  Tue Feb 13 15:34:38 2024
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 13 Feb 2024 15:34:38 -0800
Subject: [PATCH 21/22] arm64: dts: qcom: sc7180-trogdor: Make
 clamshell/detachable fragments
In-Reply-To: <20240210070934.2549994-22-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-22-swboyd@chromium.org>
Message-ID: <CAD=FV=WovmtKFiG0OMzpus9=z8UJ+Ev3TrwsVia8pSegvjwUiw@mail.gmail.com>

Hi,

On Fri, Feb 9, 2024 at 11:10?PM Stephen Boyd <swboyd at chromium.org> wrote:
>
> diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
> new file mode 100644
> index 000000000000..bcf3df463f80
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-clamshell.dtsi
> @@ -0,0 +1,9 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Google Trogdor dts framgent for clamshells

s/framgent/fragment


> diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
> new file mode 100644
> index 000000000000..ab0f30288871
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-detachable.dtsi
> @@ -0,0 +1,12 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Google Trogdor dts framgent for detachables

s/framgent/fragment


> + * Copyright 2024 Google LLC.
> + */
> +

Tiny nit: should this file have a comment like "/* This file must be
included after sc7180-trogdor.dtsi */" like the clamshell file?


> diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
> index e9f213d27711..c3fd6760de7a 100644
> --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
> @@ -5,8 +5,7 @@
>   * Copyright 2020 Google LLC.
>   */
>
> -/* This file must be included after sc7180-trogdor.dtsi */
> -#include <arm/cros-ec-keyboard.dtsi>
> +#include "sc7180-trogdor-clamshell.dtsi"

nit: Not that it was terribly consistent before, but in lazor you
remove the "This file must be included after sc7180-trogdor.dtsi"
because (I guess) it moved to the clamshell file. However, in other
dts files you don't remove it. pazquel has the exact same comment and
it's not removed. Pompom has a slight variant of the comment where it
explains the reason (to modify cros_ec) and it's not removed. Could
make it more consistent...


Everything above is either tiny typos or nits, so happy enough with:

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From sre at kernel.org  Tue Feb 13 15:42:38 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Wed, 14 Feb 2024 00:42:38 +0100
Subject: [PATCH v2 05/17] dt-bindings: soc: imx: fsl,imx-anatop: add
 binding
In-Reply-To: <eaf37a1e-58e2-4cc7-85f9-8cb81537b3b9@linaro.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-6-sre@kernel.org>
 <eaf37a1e-58e2-4cc7-85f9-8cb81537b3b9@linaro.org>
Message-ID: <22pec37ketr2pgcqwz4nd5lm55ohv7jvtxw2l7piosbnx3sw7e@gewljn5veatn>

Hi Krzysztof,

On Tue, Feb 13, 2024 at 01:27:09PM +0100, Krzysztof Kozlowski wrote:
> [...]
> > +  tempmon:
> > +    type: object
> > +    unevaluatedProperties: false
> > +    $ref: /schemas/thermal/imx-thermal.yaml
> 
> So you just ignored my comment?
> I did not receive any response from you on this.

I had mentioned it in the cover letter next to the changelog:

Unadressed feedback from PATCHv1:
 - anatop phandle vs parent: technically it makes sense to just use the
   parent, but this driver is only used by i.MX6. The current code makes
   use of the phandle, so we cannot drop it because of backwards
   compatibility. So I don't see a point in deprecating this property.

(reading it again: s/driver/binding/ and s/code/Linux kernel driver/)

Greetings,

-- Sebastian


From sre at kernel.org  Tue Feb 13 15:48:05 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Wed, 14 Feb 2024 00:48:05 +0100
Subject: [PATCH v2 12/17] ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
In-Reply-To: <CAOMZO5BUzaqHEvd877te_Tgiaz+QvWrvLC_oKg+mRPzmL26pDw@mail.gmail.com>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-13-sre@kernel.org>
 <CAOMZO5BUzaqHEvd877te_Tgiaz+QvWrvLC_oKg+mRPzmL26pDw@mail.gmail.com>
Message-ID: <wowv3yiz2xis3fafel4rkedorrh2n3iamfctyvtuwxrvdxroq2@dojgmuotvzml>

Hi,

On Tue, Feb 13, 2024 at 10:53:05AM -0300, Fabio Estevam wrote:
> On Mon, Feb 12, 2024 at 10:03?PM Sebastian Reichel <sre at kernel.org> wrote:
> > Replace all "xnur-gpio" with "xnur-gpios" in the
> > i.MX6UL(L) Touchscreen node.
> 
> Please explain the reason for doing this.

DT binding maintainers asked to use xnur-gpios instead of xnur-gpio
in the DT binding when converting to YAML (the -gpio suffix is
deprecated in favour of -gpios). This updates the DT files to become
compliant. The Linux kernel driver has already been using gpiod API
when it was added to the kernel, so this change is backwards compatible.

I will extend the description from this patch in v3.

-- Sebastian


From jm at ti.com  Tue Feb 13 15:56:53 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 17:56:53 -0600
Subject: [PATCH v3 1/9] arm64: dts: ti: k3-am62a-main: Add sdhci0 instance
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <20240213235701.2438513-2-jm@ti.com>

From: Nitin Yadav <n-yadav at ti.com>

Add sdhci0 DT node in k3-am62a-main for eMMC support. Add otap/itap
values according to the datasheet[0], refer to Table 7-79.

[0] https://www.ti.com/lit/ds/symlink/am62a3.pdf

Signed-off-by: Nitin Yadav <n-yadav at ti.com>
Signed-off-by: Judith Mendez <jm at ti.com>
---
Changes since V3:
- No change
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 972971159a62..ce5f278235a4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -536,6 +536,24 @@ main_gpio1: gpio at 601000 {
 		status = "disabled";
 	};
 
+	sdhci0: mmc at fa10000 {
+		compatible = "ti,am62-sdhci";
+		reg = <0x00 0xfa10000 0x00 0x260>, <0x00 0xfa18000 0x00 0x134>;
+		interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 57 5>, <&k3_clks 57 6>;
+		clock-names = "clk_ahb", "clk_xin";
+		assigned-clocks = <&k3_clks 57 6>;
+		assigned-clock-parents = <&k3_clks 57 8>;
+		bus-width = <8>;
+		mmc-hs200-1_8v;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-mmc-hs = <0x0>;
+		ti,otap-del-sel-hs200 = <0x6>;
+		status = "disabled";
+	};
+
 	sdhci1: mmc at fa00000 {
 		compatible = "ti,am62-sdhci";
 		reg = <0x00 0xfa00000 0x00 0x260>, <0x00 0xfa08000 0x00 0x134>;
-- 
2.43.0



From jm at ti.com  Tue Feb 13 15:56:57 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 17:56:57 -0600
Subject: [PATCH v3 5/9] arm64: dts: ti: k3-am62p: Add ITAP/OTAP values for MMC
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <20240213235701.2438513-6-jm@ti.com>

Add OTAP/ITAP values to enable HS400 timing for MMC0 and
SDR104 timing for MMC1/MMC2. Remove no-1-8-v property to
enable the highest speed mode possible.

Update MMC OTAP/ITAP values according to the datasheet
[0], refer to Table 7-79 for MMC0 and Table 7-97 for MMC1/MMC2.

[0] https://www.ti.com/lit/ds/symlink/am62p.pdf

Signed-off-by: Judith Mendez <jm at ti.com>
---
Changes since V3:
- No change
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 44 +++++++++++++++++++++--
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts   |  1 -
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index ef1c982a90d8..e43530beb79f 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -534,7 +534,21 @@ sdhci0: mmc at fa10000 {
 		clock-names = "clk_ahb", "clk_xin";
 		assigned-clocks = <&k3_clks 57 2>;
 		assigned-clock-parents = <&k3_clks 57 4>;
-		ti,otap-del-sel-legacy = <0x0>;
+		bus-width = <8>;
+		mmc-ddr-1_8v;
+		mmc-hs200-1_8v;
+		mmc-hs400-1_8v;
+		ti,clkbuf-sel = <0x7>;
+		ti,strobe-sel = <0x77>;
+		ti,trm-icp = <0x8>;
+		ti,otap-del-sel-legacy = <0x1>;
+		ti,otap-del-sel-mmc-hs = <0x1>;
+		ti,otap-del-sel-ddr52 = <0x6>;
+		ti,otap-del-sel-hs200 = <0x8>;
+		ti,otap-del-sel-hs400 = <0x5>;
+		ti,itap-del-sel-legacy = <0x10>;
+		ti,itap-del-sel-mmc-hs = <0xa>;
+		ti,itap-del-sel-ddr52 = <0x3>;
 		status = "disabled";
 	};
 
@@ -545,7 +559,19 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,otap-del-sel-legacy = <0x8>;
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		status = "disabled";
 	};
 
@@ -556,7 +582,19 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,otap-del-sel-legacy = <0x8>;
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		status = "disabled";
 	};
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 95a0146279b1..8c73587b0b62 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -424,7 +424,6 @@ &sdhci1 {
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
-	no-1-8-v;
 	bootph-all;
 };
 
-- 
2.43.0



From jm at ti.com  Tue Feb 13 15:56:58 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 17:56:58 -0600
Subject: [PATCH v3 6/9] arm64: dts: ti: k3-am6*: Remove DLL properties for soft PHYs
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <20240213235701.2438513-7-jm@ti.com>

Remove DLL properties which are not applicable for soft PHYs
since these PHYs do not have a DLL to enable.

Acked-by: Francesco Dolcini <francesco.dolcini at toradex.com> # Verdin AM62
Signed-off-by: Judith Mendez <jm at ti.com>
---
Changes since V3:
- Remove ti,driver-strength-ohm property in sdhci1 node for
 k3-am642-tqma64xxl-mbax4xxl and k3-am642-phyboard-electra-rdk board files.
- Add Francesco's Acked-by
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi                 | 3 ---
 arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi          | 1 -
 arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi        | 1 -
 arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi           | 1 -
 arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi          | 1 -
 arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi               | 2 --
 arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts           | 3 ---
 arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts    | 1 -
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi                | 1 -
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts                  | 1 -
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts                  | 1 -
 arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi           | 2 --
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi                 | 1 -
 arch/arm64/boot/dts/ti/k3-am642-evm.dts                  | 1 -
 arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts | 1 -
 arch/arm64/boot/dts/ti/k3-am642-sk.dts                   | 1 -
 arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts   | 1 -
 17 files changed, 23 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index fe0cc4a9a501..79ed5cbbbda1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -561,7 +561,6 @@ sdhci0: mmc at fa10000 {
 		assigned-clock-parents = <&k3_clks 57 8>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
-		ti,trm-icp = <0x2>;
 		bus-width = <8>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
@@ -580,7 +579,6 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
@@ -604,7 +602,6 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
index 3372a256c90f..43488cc8bcb1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
@@ -317,7 +317,6 @@ serial_flash: flash at 0 {
 &sdhci0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc0_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	non-removable;
 	status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
index bf6d27e70bc4..6c4cec8728e4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
@@ -185,7 +185,6 @@ &ospi0 {
 
 /* Verdin SD_1 */
 &sdhci1 {
-	ti,driver-strength-ohm = <33>;
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
index 680071688dcb..be62648e7818 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
@@ -206,7 +206,6 @@ &ospi0 {
 
 /* Verdin SD_1 */
 &sdhci1 {
-	ti,driver-strength-ohm = <33>;
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
index a6808b10c7b2..4768ef42c4fc 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
@@ -26,7 +26,6 @@ &sdhci2 {
 	mmc-pwrseq = <&wifi_pwrseq>;
 	non-removable;
 	ti,fails-without-test-cd;
-	ti,driver-strength-ohm = <50>;
 	vmmc-supply = <&reg_3v3>;
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
index 6a06724b6d16..d68310444bcb 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
@@ -1407,7 +1407,6 @@ &sdhci0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdhci0>;
 	non-removable;
-	ti,driver-strength-ohm = <50>;
 	status = "okay";
 };
 
@@ -1416,7 +1415,6 @@ &sdhci1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdhci1>;
 	disable-wp;
-	ti,driver-strength-ohm = <50>;
 	vmmc-supply = <&reg_sdhc1_vmmc>;
 	vqmmc-supply = <&reg_sdhc1_vqmmc>;
 	status = "disabled";
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
index 3b4246ce49de..bb6a5837bcb3 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -819,7 +819,6 @@ &sdhci0 {
 	bootph-all;
 	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	status = "okay";
 };
@@ -832,7 +831,6 @@ &sdhci1 {
 
 	vmmc-supply = <&vdd_3v3_sd>;
 	vqmmc-supply = <&vdd_sd_dv>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
 	cd-debounce-delay-ms = <100>;
@@ -849,7 +847,6 @@ &sdhci2 {
 	ti,fails-without-test-cd;
 	cap-power-off-card;
 	keep-power-in-suspend;
-	ti,driver-strength-ohm = <50>;
 	assigned-clocks = <&k3_clks 157 158>;
 	assigned-clock-parents = <&k3_clks 157 160>;
 	#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
index 5c31f0453def..a83a90497857 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
@@ -334,7 +334,6 @@ &sdhci1 {
 	vqmmc-supply = <&vddshv5_sdio>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	no-1-8-v;
 	status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 6806288ec227..f283777d54b4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -561,7 +561,6 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index c99b2e90f76d..f241637a5642 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -582,7 +582,6 @@ &sdhci1 {
 	vmmc-supply = <&vdd_mmc1>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 8c73587b0b62..5c9b73726ebd 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -422,7 +422,6 @@ &sdhci1 {
 	vqmmc-supply = <&vddshv_sdio>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	bootph-all;
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
index 6dd496cd459a..3c45782ab2b7 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -411,7 +411,6 @@ &sdhci0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc0_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
@@ -421,7 +420,6 @@ &sdhci1 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index 9bfa0a969bfc..a29847735c6e 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -646,7 +646,6 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
 		clock-names = "clk_ahb", "clk_xin";
-		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 5c546ae76d3e..f308076d608a 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -508,7 +508,6 @@ &sdhci1 {
 	pinctrl-names = "default";
 	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
index c0c45b8a0245..8237b8c815b8 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
@@ -292,7 +292,6 @@ &sdhci1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	bus-width = <4>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 	no-1-8-v;
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index cce04e188ff6..b286eaa02ada 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -471,7 +471,6 @@ &sdhci1 {
 	pinctrl-names = "default";
 	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
-	ti,driver-strength-ohm = <50>;
 	disable-wp;
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
index 55102d35cecc..1f4dc5ad1696 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
@@ -422,7 +422,6 @@ &sdhci1 {
 	cd-gpios = <&main_gpio1 77 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	no-mmc;
-	ti,driver-strength-ohm = <50>;
 	ti,fails-without-test-cd;
 	/* Enabled by overlay */
 };
-- 
2.43.0



From jm at ti.com  Tue Feb 13 15:56:56 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 17:56:56 -0600
Subject: [PATCH v3 4/9] arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <20240213235701.2438513-5-jm@ti.com>

Update MMC0/MMC1 OTAP/ITAP values according to the datasheet
[0], refer to Table 7-68 for MMC0 and Table 7-77 for MMC1.

[0] https://www.ti.com/lit/ds/symlink/am6442.pdf

Fixes: 8abae9389bdb ("arm64: dts: ti: Add support for AM642 SoC")
Signed-off-by: Judith Mendez <jm at ti.com>
---
Changes since V3:
- No change
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index ddd382a0d735..9bfa0a969bfc 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -633,6 +633,9 @@ sdhci0: mmc at fa10000 {
 		ti,otap-del-sel-mmc-hs = <0x0>;
 		ti,otap-del-sel-ddr52 = <0x6>;
 		ti,otap-del-sel-hs200 = <0x7>;
+		ti,itap-del-sel-legacy = <0x10>;
+		ti,itap-del-sel-mmc-hs = <0xa>;
+		ti,itap-del-sel-ddr52 = <0x3>;
 		status = "disabled";
 	};
 
@@ -645,12 +648,16 @@ sdhci1: mmc at fa00000 {
 		clock-names = "clk_ahb", "clk_xin";
 		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
-		ti,otap-del-sel-sd-hs = <0xf>;
+		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
 		ti,otap-del-sel-sdr25 = <0xf>;
 		ti,otap-del-sel-sdr50 = <0xc>;
 		ti,otap-del-sel-sdr104 = <0x6>;
 		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		ti,clkbuf-sel = <0x7>;
 		status = "disabled";
 	};
-- 
2.43.0



From jm at ti.com  Tue Feb 13 15:56:55 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 17:56:55 -0600
Subject: [PATCH v3 3/9] arm64: dts: ti: k3-am62a7-sk: Enable eMMC support
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <20240213235701.2438513-4-jm@ti.com>

From: Nitin Yadav <n-yadav at ti.com>

Add support for 32GB eMMC card on AM62A7 SK. Includes adding mmc0
pins settings. Add mmc0 alias for sdhci0 in k3-am62a7-sk.dts.

Signed-off-by: Nitin Yadav <n-yadav at ti.com>
Signed-off-by: Judith Mendez <jm at ti.com>
---
Changes since V3:
- No change
---
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts | 26 +++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index f5ae91bf1bdb..c99b2e90f76d 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -20,6 +20,7 @@ aliases {
 		serial0 = &wkup_uart0;
 		serial2 = &main_uart0;
 		serial3 = &main_uart1;
+		mmc0 = &sdhci0;
 		mmc1 = &sdhci1;
 	};
 
@@ -263,6 +264,22 @@ AM62AX_IOPAD(0x0b4, PIN_INPUT_PULLUP, 1) /* (K24) GPMC0_CSn3.I2C2_SDA */
 		>;
 	};
 
+	main_mmc0_pins_default: main-mmc0-default-pins {
+		pinctrl-single,pins = <
+			AM62AX_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */
+			AM62AX_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLKLB */
+			AM62AX_IOPAD(0x21c, PIN_INPUT, 0) /* (AB1) MMC0_CLK */
+			AM62AX_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */
+			AM62AX_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */
+			AM62AX_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */
+			AM62AX_IOPAD(0x208, PIN_INPUT_PULLUP, 0) /* (Y4) MMC0_DAT3 */
+			AM62AX_IOPAD(0x204, PIN_INPUT_PULLUP, 0) /* (AB2) MMC0_DAT4 */
+			AM62AX_IOPAD(0x200, PIN_INPUT_PULLUP, 0) /* (AC1) MMC0_DAT5 */
+			AM62AX_IOPAD(0x1fc, PIN_INPUT_PULLUP, 0) /* (AD2) MMC0_DAT6 */
+			AM62AX_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		pinctrl-single,pins = <
 			AM62AX_IOPAD(0x23c, PIN_INPUT, 0) /* (A21) MMC1_CMD */
@@ -550,6 +567,15 @@ &main_i2c2 {
 	clock-frequency = <400000>;
 };
 
+&sdhci0 {
+	/* eMMC */
+	status = "okay";
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc0_pins_default>;
+	disable-wp;
+};
+
 &sdhci1 {
 	/* SD/MMC */
 	status = "okay";
-- 
2.43.0



From jm at ti.com  Tue Feb 13 15:56:54 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 17:56:54 -0600
Subject: [PATCH v3 2/9] arm64: dts: ti: k3-am62a-main: Add sdhci2 instance
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <20240213235701.2438513-3-jm@ti.com>

Add sdhci2 DT node in k3-am62a-main for mmc2. Add otap/itap
values according to the datasheet[0], Refer to Table 7-97.

[0] https://www.ti.com/lit/ds/symlink/am62a3.pdf

Signed-off-by: Judith Mendez <jm at ti.com>
---
Changes since V3:
- No change
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 24 +++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index ce5f278235a4..6806288ec227 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -579,6 +579,30 @@ sdhci1: mmc at fa00000 {
 		status = "disabled";
 	};
 
+	sdhci2: mmc at fa20000 {
+		compatible = "ti,am62-sdhci";
+		reg = <0x00 0xfa20000 0x00 0x260>, <0x00 0xfa28000 0x00 0x134>;
+		interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
+		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
+		ti,clkbuf-sel = <0x7>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-sdr104 = <0x6>;
+		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
+		no-1-8-v;
+		status = "disabled";
+	};
+
 	usbss0: dwc3-usb at f900000 {
 		compatible = "ti,am62-usb";
 		reg = <0x00 0x0f900000 0x00 0x800>;
-- 
2.43.0



From jm at ti.com  Tue Feb 13 15:56:52 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 17:56:52 -0600
Subject: [PATCH v3 0/9] Fix MMC properties on Sitara K3 devices
Message-ID: <20240213235701.2438513-1-jm@ti.com>

This patch series aims to fix and update MMC nodes for TI
Sitara K3 devices with the following changes.

The series introduces sdhci0 and sdhci2 nodes and enables
eMMC for AM62ax platform.

Also introduce fixes for MMC ITAP/OTAP values for AM64x
platform according to device datasheet [0], and add ITAP/
OTAP values for AM62p to enable the highest timing possible
for MMC0 and MMC1, according to device datasheet [1].

The DLL properties ti,trm-icp and ti,driver-strength-ohm
should be removed for soft PHYs since drive strength cannot
be changed, so remove these properties when not applicable.
Since this fix touches non-TI boards and therefore cannot be
tested, all tested-by's are welcome.

Also include a few fixes for ti,clkbuf-sel, bus-width,
and bootph-all device tree properties in MMC nodes.

This series was tested on:
- AM62a SK
- AM62x SK
- AM62p SK
- AM64x GP EVM
- AM64x SK EVM
- Beagleplay

[0] https://www.ti.com/lit/ds/symlink/am6442.pdf
[1] https://www.ti.com/lit/ds/symlink/am62p.pdf

Fixes since V2:
- Remove ti,driver-strength-ohm property in sdhci1 node for
 k3-am642-tqma64xxl-mbax4xxl and k3-am642-phyboard-electra-rdk board files.
- Add Francesco's Acked-by

V2: https://lore.kernel.org/linux-devicetree/20240213002416.1560357-1-jm at ti.com/
V1: https://lore.kernel.org/linux-devicetree/22af7436-8833-4049-bdbb-f79bb3314ee8 at ti.com/
RFC: https://lore.kernel.org/linux-devicetree/c94b7399-31c0-4e7d-a616-8f29c86a27ba at ti.com/

Judith Mendez (7):
  arm64: dts: ti: k3-am62a-main: Add sdhci2 instance
  arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
  arm64: dts: ti: k3-am62p: Add ITAP/OTAP values for MMC
  arm64: dts: ti: k3-am6*: Remove DLL properties for soft PHYs
  arm64: dts: ti: k3-am6*: Fix ti,clkbuf-sel property in MMC nodes
  arm64: dts: ti: k3-am6*: Fix bus-width property in MMC nodes
  arm64: dts: ti: k3-am6*: Add bootph-all property in MMC node

Nitin Yadav (2):
  arm64: dts: ti: k3-am62a-main: Add sdhci0 instance
  arm64: dts: ti: k3-am62a7-sk: Enable eMMC support

 arch/arm64/boot/dts/ti/k3-am62-main.dtsi      | 12 +++--
 .../boot/dts/ti/k3-am62-phycore-som.dtsi      |  1 -
 .../boot/dts/ti/k3-am62-verdin-dahlia.dtsi    |  1 -
 .../arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi |  1 -
 .../boot/dts/ti/k3-am62-verdin-wifi.dtsi      |  1 -
 arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi    |  2 -
 .../arm64/boot/dts/ti/k3-am625-beagleplay.dts |  4 --
 .../dts/ti/k3-am625-phyboard-lyra-rdk.dts     |  1 -
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi     | 45 ++++++++++++++++++-
 arch/arm64/boot/dts/ti/k3-am62a7-sk.dts       | 27 ++++++++++-
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi     | 44 ++++++++++++++++--
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts       |  3 +-
 .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi |  2 -
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi      | 15 +++++--
 arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  4 +-
 .../dts/ti/k3-am642-phyboard-electra-rdk.dts  |  1 -
 arch/arm64/boot/dts/ti/k3-am642-sk.dts        |  2 -
 .../dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts    |  1 -
 18 files changed, 129 insertions(+), 38 deletions(-)


base-commit: 1e6bbc5185bcd113c8d2f7aa0a02f588a6bdbe5d
-- 
2.43.0



From jm at ti.com  Tue Feb 13 15:57:01 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 17:57:01 -0600
Subject: [PATCH v3 9/9] arm64: dts: ti: k3-am6*: Add bootph-all property in MMC node
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <20240213235701.2438513-10-jm@ti.com>

Add missing bootph-all property for AM62p MMC0 and AM64x
MMC0 nodes.

Signed-off-by: Judith Mendez <jm at ti.com>
---
Changes since V3:
- No change
---
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 1 +
 arch/arm64/boot/dts/ti/k3-am642-evm.dts | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 5c9b73726ebd..e86f34e835c1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -413,6 +413,7 @@ &sdhci0 {
 	status = "okay";
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
+	bootph-all;
 };
 
 &sdhci1 {
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 83f2b00726b5..fcadfb7a353c 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -497,6 +497,7 @@ &sdhci0 {
 	non-removable;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
+	bootph-all;
 };
 
 /* SD/MMC */
-- 
2.43.0



From jm at ti.com  Tue Feb 13 15:57:00 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 17:57:00 -0600
Subject: [PATCH v3 8/9] arm64: dts: ti: k3-am6*: Fix bus-width property in MMC nodes
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <20240213235701.2438513-9-jm@ti.com>

Move bus-width property to *main.dtsi, above the OTAP/ITAP
delay values. While there is no error with where it is
currently at, it is easier to read the MMC node if the
bus-width property is located above the OTAP/ITAP delay
values consistently across MMC nodes.

Add missing bus-width for MMC2 in k3-am62-main.

Signed-off-by: Judith Mendez <jm at ti.com>
---
Changes since V3:
- No change
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi       | 5 +++--
 arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 1 -
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi      | 2 +-
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi       | 2 ++
 arch/arm64/boot/dts/ti/k3-am642-evm.dts        | 2 --
 arch/arm64/boot/dts/ti/k3-am642-sk.dts         | 1 -
 6 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 410b390ce5d5..55420eb1c620 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -559,9 +559,9 @@ sdhci0: mmc at fa10000 {
 		clock-names = "clk_ahb", "clk_xin";
 		assigned-clocks = <&k3_clks 57 6>;
 		assigned-clock-parents = <&k3_clks 57 8>;
+		bus-width = <8>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
-		bus-width = <8>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-mmc-hs = <0x0>;
@@ -579,6 +579,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
@@ -591,7 +592,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x1>;
 		ti,itap-del-sel-sdr12 = <0xa>;
 		ti,itap-del-sel-sdr25 = <0x1>;
-		bus-width = <4>;
 		status = "disabled";
 	};
 
@@ -602,6 +602,7 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
index bb6a5837bcb3..a34e0df2ab86 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -842,7 +842,6 @@ &sdhci2 {
 	vmmc-supply = <&wlan_en>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&wifi_pins_default>, <&wifi_32k_clk>;
-	bus-width = <4>;
 	non-removable;
 	ti,fails-without-test-cd;
 	cap-power-off-card;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index ddb76cd66f88..253c1857eedf 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -561,6 +561,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
@@ -573,7 +574,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x0>;
 		ti,itap-del-sel-sdr12 = <0x0>;
 		ti,itap-del-sel-sdr25 = <0x0>;
-		bus-width = <4>;
 		no-1-8-v;
 		status = "disabled";
 	};
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index bea05be7cb48..bc9c9ff993e6 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -626,6 +626,7 @@ sdhci0: mmc at fa10000 {
 		power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 57 0>, <&k3_clks 57 1>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <8>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
 		ti,clkbuf-sel = <0x7>;
@@ -647,6 +648,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
 		clock-names = "clk_ahb", "clk_xin";
+		bus-width = <4>;
 		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index f308076d608a..83f2b00726b5 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -494,7 +494,6 @@ eeprom at 0 {
 /* eMMC */
 &sdhci0 {
 	status = "okay";
-	bus-width = <8>;
 	non-removable;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
@@ -506,7 +505,6 @@ &sdhci1 {
 	status = "okay";
 	vmmc-supply = <&vdd_mmc1>;
 	pinctrl-names = "default";
-	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	disable-wp;
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index b286eaa02ada..67cd41bf806e 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -469,7 +469,6 @@ &sdhci1 {
 	status = "okay";
 	vmmc-supply = <&vdd_mmc1>;
 	pinctrl-names = "default";
-	bus-width = <4>;
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	disable-wp;
 };
-- 
2.43.0



From jm at ti.com  Tue Feb 13 15:56:59 2024
From: jm at ti.com (Judith Mendez)
Date: Tue, 13 Feb 2024 17:56:59 -0600
Subject: [PATCH v3 7/9] arm64: dts: ti: k3-am6*: Fix ti,clkbuf-sel property in MMC nodes
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <20240213235701.2438513-8-jm@ti.com>

Move ti,clkbuf-sel property above the OTAP/ITAP delay values.
While there is no error with where it is currently at, it is
easier to read the MMC node if ti,clkbuf-sel is located above
the OTAP/ITAP delay values consistently across MMC nodes.

Add missing ti,clkbuf-sel for MMC0 in k3-am64-main.

Signed-off-by: Judith Mendez <jm at ti.com>
---
Changes since V3:
- No change
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi  | 4 ++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 2 +-
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi  | 3 ++-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 79ed5cbbbda1..410b390ce5d5 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -579,6 +579,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
@@ -590,7 +591,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x1>;
 		ti,itap-del-sel-sdr12 = <0xa>;
 		ti,itap-del-sel-sdr25 = <0x1>;
-		ti,clkbuf-sel = <0x7>;
 		bus-width = <4>;
 		status = "disabled";
 	};
@@ -602,6 +602,7 @@ sdhci2: mmc at fa20000 {
 		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x8>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0x0>;
@@ -613,7 +614,6 @@ sdhci2: mmc at fa20000 {
 		ti,itap-del-sel-sd-hs = <0xa>;
 		ti,itap-del-sel-sdr12 = <0xa>;
 		ti,itap-del-sel-sdr25 = <0x1>;
-		ti,clkbuf-sel = <0x7>;
 		status = "disabled";
 	};
 
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index f283777d54b4..ddb76cd66f88 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -561,6 +561,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
@@ -572,7 +573,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x0>;
 		ti,itap-del-sel-sdr12 = <0x0>;
 		ti,itap-del-sel-sdr25 = <0x0>;
-		ti,clkbuf-sel = <0x7>;
 		bus-width = <4>;
 		no-1-8-v;
 		status = "disabled";
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index a29847735c6e..bea05be7cb48 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -628,6 +628,7 @@ sdhci0: mmc at fa10000 {
 		clock-names = "clk_ahb", "clk_xin";
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
+		ti,clkbuf-sel = <0x7>;
 		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-mmc-hs = <0x0>;
@@ -646,6 +647,7 @@ sdhci1: mmc at fa00000 {
 		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
 		clock-names = "clk_ahb", "clk_xin";
+		ti,clkbuf-sel = <0x7>;
 		ti,otap-del-sel-legacy = <0x0>;
 		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
@@ -657,7 +659,6 @@ sdhci1: mmc at fa00000 {
 		ti,itap-del-sel-sd-hs = <0x0>;
 		ti,itap-del-sel-sdr12 = <0x0>;
 		ti,itap-del-sel-sdr25 = <0x0>;
-		ti,clkbuf-sel = <0x7>;
 		status = "disabled";
 	};
 
-- 
2.43.0



From dianders at chromium.org  Tue Feb 13 16:03:11 2024
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 13 Feb 2024 16:03:11 -0800
Subject: [PATCH 04/22] usb: core: Set connect_type of ports based on DT node
In-Reply-To: <20240210070934.2549994-5-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-5-swboyd@chromium.org>
Message-ID: <CAD=FV=UuunNnXJ0kAzRPVy0DX7Wv2eQOa-fMJQ-aKtaGnyQaQA@mail.gmail.com>

Hi,

On Fri, Feb 9, 2024 at 11:09?PM Stephen Boyd <swboyd at chromium.org> wrote:
>
> When a USB hub is described in DT, such as any device that matches the
> onboard-hub driver, the connect_type is set to "unknown" or
> USB_PORT_CONNECT_TYPE_UNKNOWN. This makes any device plugged into that
> USB port report their 'removable' device attribute as "unknown". Improve
> the connect_type attribute for ports, and in turn the removable
> attribute for USB devices, by looking for child devices with a reg
> property or an OF graph when the device is described in DT.
>
> If the graph exists, endpoints that are connected to a remote node must
> be something like a usb-{a,b,c}-connector compatible node, or an
> intermediate node like a redriver, and not a hardwired USB device on the
> board. Set the connect_type to USB_PORT_CONNECT_TYPE_HOT_PLUG in this
> case because the device is going to be plugged in. Set the connect_type
> to USB_PORT_CONNECT_TYPE_HARD_WIRED if there's a child node for the port
> like 'device at 2' for port2. Set the connect_type to USB_PORT_NOT_USED if
> there isn't an endpoint or child node corresponding to the port number.

The above sounds good, but then I look at patch #18 ("dt-bindings:
chrome: Add binding for ChromeOS Pogo pin connector") and patch #22
("arm64: dts: qcom: sc7180-trogdor: Wire up USB and DP to
usb-c-connectors") and it makes my Spidey Sense tingle.

Specifically, I _think_ if a port is "hard wired" that can sometimes
tell the system that the port is a bit more trusted. In the case of
the "pogo" pins on detachables, though, I don't _think_ there's
anything that prevents someone from making a "pogo to USB A port"
adapter and then you could plug anything you wanted into the pogo
port. If there's any extra trust given to these "internal" ports a
nefarious attacker could presumably abuse that trust for the pogo
pins.

I have no idea if this is a realistic concern or not. I'm about 95%
sure that hardwired "PCIe" ports get extra trust and get "deferred
IOMMU flush" enabled and, in the case of PCIe, that actually is a real
security hole. For USB, though, I think the system is more isolated by
the USB host controller so I'm not sure that there is any extra trust
given to "hard wired" ports. ...so maybe the answer here is to just
ignore my rambling. ...or maybe the answer here is that everything is
fine but patches #18 and #22 should be modified not to cause the pogo
pins to be considered as "hard wired" since they really aren't...


-Doug


From eahariha at linux.microsoft.com  Tue Feb 13 16:19:08 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Tue, 13 Feb 2024 16:19:08 -0800
Subject: [PATCH] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM
 Neoverse N2 errata
In-Reply-To: <ZcqtUxhqUbYoRH-G@linux.dev>
References: <20240212232909.2276378-1-eahariha@linux.microsoft.com>
 <ZcqtUxhqUbYoRH-G@linux.dev>
Message-ID: <18b3ac3e-2bfc-4fce-9be4-3e75e487f9fc@linux.microsoft.com>

On 2/12/2024 3:44 PM, Oliver Upton wrote:
> Hi Easwar,
> 
> On Mon, Feb 12, 2024 at 11:29:06PM +0000, Easwar Hariharan wrote:
>> Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft
>> implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore
>> suffers from all the same errata.
> 
> Can you comment at all on where one might find this MIDR? That is, does
> your hypervisor report the native MIDR of the implementation or does it
> repaint it as an Arm Neoverse N2 (0x410FD490)?

We will check on the Microsoft hypervisor's plans, and get back to you.

Notwithstanding that, we do have baremetal use cases for Microsoft Azure Cobalt 100
as well where this MIDR value will show through.

> 
>> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
>> index 7c7493cb571f..a632a7514e55 100644
>> --- a/arch/arm64/include/asm/cputype.h
>> +++ b/arch/arm64/include/asm/cputype.h
>> @@ -61,6 +61,7 @@
>>  #define ARM_CPU_IMP_HISI		0x48
>>  #define ARM_CPU_IMP_APPLE		0x61
>>  #define ARM_CPU_IMP_AMPERE		0xC0
>> +#define ARM_CPU_IMP_MICROSOFT		0x6D
>>  
>>  #define ARM_CPU_PART_AEM_V8		0xD0F
>>  #define ARM_CPU_PART_FOUNDATION		0xD00
>> @@ -135,6 +136,8 @@
>>  
>>  #define AMPERE_CPU_PART_AMPERE1		0xAC3
>>  
>> +#define MSFT_CPU_PART_AZURE_COBALT_100	0xD49 /* Based on r0p0 of ARM Neoverse N2 */
>> +
>>  #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
>>  #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
>>  #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
>> @@ -193,6 +196,7 @@
>>  #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)
>>  #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
>>  #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
>> +#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MSFT_CPU_PART_AZURE_COBALT_100)
> 
> nitpick: consistently use the abbreviated 'MSFT' for all the definitions
> you're adding.
> 

I was rather hoping to use Microsoft throughout, but I chose MSFT for the CPU_PART* to align columns
with the other defines. :) If consistency is of a higher priority than column alignment, I can change it
to MICROSOFT rather than MSFT throughout.

Thanks,
Easwar



From justinstitt at google.com  Tue Feb 13 16:22:57 2024
From: justinstitt at google.com (Justin Stitt)
Date: Wed, 14 Feb 2024 00:22:57 +0000
Subject: [PATCH v2 1/2] ASoC: meson: aiu: fix function pointer type
 mismatch
In-Reply-To: <20240213215807.3326688-2-jbrunet@baylibre.com>
References: <20240213215807.3326688-1-jbrunet@baylibre.com>
 <20240213215807.3326688-2-jbrunet@baylibre.com>
Message-ID: <20240214002257.bfp6wk5j3wsaq6f6@google.com>

Hi,

On Tue, Feb 13, 2024 at 10:58:03PM +0100, Jerome Brunet wrote:
> clang-16 warns about casting functions to incompatible types, as is done
> here to call clk_disable_unprepare:
>
> sound/soc/meson/aiu.c:243:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>   243 |                                        (void(*)(void *))clk_disable_unprepare,
>
> The pattern of getting, enabling and setting a disable callback for a
> clock can be replaced with devm_clk_get_enabled(), which also fixes
> this warning.
>
> Fixes: 6ae9ca9ce986 ("ASoC: meson: aiu: add i2s and spdif support")
> Reported-by: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>

Silences the warning and makes the code more readable without adding any
new helpers. Awesome!

Reviewed-by: Justin Stitt <justinstitt at google.com>
> ---
>  sound/soc/meson/aiu.c | 19 ++++---------------
>  sound/soc/meson/aiu.h |  1 -
>  2 files changed, 4 insertions(+), 16 deletions(-)
>
> diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c
> index 7109b81cc3d0..5d1419ed7a62 100644
> --- a/sound/soc/meson/aiu.c
> +++ b/sound/soc/meson/aiu.c
> @@ -212,11 +212,12 @@ static const char * const aiu_spdif_ids[] = {
>  static int aiu_clk_get(struct device *dev)
>  {
>  	struct aiu *aiu = dev_get_drvdata(dev);
> +	struct clk *pclk;
>  	int ret;
>
> -	aiu->pclk = devm_clk_get(dev, "pclk");
> -	if (IS_ERR(aiu->pclk))
> -		return dev_err_probe(dev, PTR_ERR(aiu->pclk), "Can't get the aiu pclk\n");
> +	pclk = devm_clk_get_enabled(dev, "pclk");
> +	if (IS_ERR(pclk))
> +		return dev_err_probe(dev, PTR_ERR(pclk), "Can't get the aiu pclk\n");
>
>  	aiu->spdif_mclk = devm_clk_get(dev, "spdif_mclk");
>  	if (IS_ERR(aiu->spdif_mclk))
> @@ -233,18 +234,6 @@ static int aiu_clk_get(struct device *dev)
>  	if (ret)
>  		return dev_err_probe(dev, ret, "Can't get the spdif clocks\n");
>
> -	ret = clk_prepare_enable(aiu->pclk);
> -	if (ret) {
> -		dev_err(dev, "peripheral clock enable failed\n");
> -		return ret;
> -	}
> -
> -	ret = devm_add_action_or_reset(dev,
> -				       (void(*)(void *))clk_disable_unprepare,
> -				       aiu->pclk);
> -	if (ret)
> -		dev_err(dev, "failed to add reset action on pclk");
> -
>  	return ret;
>  }
>
> diff --git a/sound/soc/meson/aiu.h b/sound/soc/meson/aiu.h
> index 393b6c2307e4..0f94c8bf6081 100644
> --- a/sound/soc/meson/aiu.h
> +++ b/sound/soc/meson/aiu.h
> @@ -33,7 +33,6 @@ struct aiu_platform_data {
>  };
>
>  struct aiu {
> -	struct clk *pclk;
>  	struct clk *spdif_mclk;
>  	struct aiu_interface i2s;
>  	struct aiu_interface spdif;
> --
> 2.43.0
>
Thanks
Justin


From justinstitt at google.com  Tue Feb 13 16:27:08 2024
From: justinstitt at google.com (Justin Stitt)
Date: Wed, 14 Feb 2024 00:27:08 +0000
Subject: [PATCH v2 2/2] ASoC: meson: t9015: fix function pointer type
 mismatch
In-Reply-To: <20240213215807.3326688-3-jbrunet@baylibre.com>
References: <20240213215807.3326688-1-jbrunet@baylibre.com>
 <20240213215807.3326688-3-jbrunet@baylibre.com>
Message-ID: <20240214002708.bhpvpt7cv7o4os5t@google.com>

Hi,

On Tue, Feb 13, 2024 at 10:58:04PM +0100, Jerome Brunet wrote:
> clang-16 warns about casting functions to incompatible types, as is done
> here to call clk_disable_unprepare:
>
> sound/soc/meson/t9015.c:274:4: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>   274 |                         (void(*)(void *))clk_disable_unprepare,
>
> The pattern of getting, enabling and setting a disable callback for a
> clock can be replaced with devm_clk_get_enabled(), which also fixes
> this warning.
>
> Fixes: 33901f5b9b16 ("ASoC: meson: add t9015 internal DAC driver")
> Reported-by: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>

Reviewed-by: Justin Stitt <justinstitt at google.com>
> ---
>  sound/soc/meson/t9015.c | 20 ++++----------------
>  1 file changed, 4 insertions(+), 16 deletions(-)
>
> diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c
> index 9c6b4dac6893..571f65788c59 100644
> --- a/sound/soc/meson/t9015.c
> +++ b/sound/soc/meson/t9015.c
> @@ -48,7 +48,6 @@
>  #define POWER_CFG	0x10
>
>  struct t9015 {
> -	struct clk *pclk;
>  	struct regulator *avdd;
>  };
>
> @@ -249,6 +248,7 @@ static int t9015_probe(struct platform_device *pdev)
>  	struct t9015 *priv;
>  	void __iomem *regs;
>  	struct regmap *regmap;
> +	struct clk *pclk;
>  	int ret;
>
>  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> @@ -256,26 +256,14 @@ static int t9015_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  	platform_set_drvdata(pdev, priv);
>
> -	priv->pclk = devm_clk_get(dev, "pclk");
> -	if (IS_ERR(priv->pclk))
> -		return dev_err_probe(dev, PTR_ERR(priv->pclk), "failed to get core clock\n");
> +	pclk = devm_clk_get_enabled(dev, "pclk");
> +	if (IS_ERR(pclk))
> +		return dev_err_probe(dev, PTR_ERR(pclk), "failed to get core clock\n");
>
>  	priv->avdd = devm_regulator_get(dev, "AVDD");
>  	if (IS_ERR(priv->avdd))
>  		return dev_err_probe(dev, PTR_ERR(priv->avdd), "failed to AVDD\n");
>
> -	ret = clk_prepare_enable(priv->pclk);
> -	if (ret) {
> -		dev_err(dev, "core clock enable failed\n");
> -		return ret;
> -	}
> -
> -	ret = devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			priv->pclk);
> -	if (ret)
> -		return ret;
> -
>  	ret = device_reset(dev);
>  	if (ret) {
>  		dev_err(dev, "reset failed\n");
> --
> 2.43.0
>
Thanks
Justin


From dianders at chromium.org  Tue Feb 13 17:17:34 2024
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 13 Feb 2024 17:17:34 -0800
Subject: [PATCH 18/22] dt-bindings: chrome: Add binding for ChromeOS Pogo
 pin connector
In-Reply-To: <20240210070934.2549994-19-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-19-swboyd@chromium.org>
Message-ID: <CAD=FV=WE4bgwTWTKjPbQR9RCt-SEVZXfQtXoaXAjvTiZiMr=wA@mail.gmail.com>

Hi,

On Fri, Feb 9, 2024 at 11:10?PM Stephen Boyd <swboyd at chromium.org> wrote:
>
> Describe the set of pins used to connect the detachable keyboard on
> detachable ChromeOS devices. The set of pins is called the "pogo pins".
> It's basically USB 2.0 with an extra pin for base detection. We expect
> to find a keyboard on the other side of this connector with a specific
> vid/pid, so describe that as a child device at the port of the usb
> device connected upstream.

Can you remind me what the side effects would be if a different
VID/PID shows up there? I know it's not an end-user scenario, but I
have a pre-production "coachz" keyboard that's actually programmed
incorrectly and shows up as the wrong PID. Presumably I could either
throw the old hardware away or figure out a way to re-program it and
it's really not a big deal, but just curious what happens...


-Doug


From quic_jinlmao at quicinc.com  Tue Feb 13 17:43:26 2024
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Wed, 14 Feb 2024 09:43:26 +0800
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename
 qcom,dsb-element-size
In-Reply-To: <20240213222957.GA2502642-robh@kernel.org>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
 <20240213160521.15925-2-quic_jinlmao@quicinc.com>
 <20240213222957.GA2502642-robh@kernel.org>
Message-ID: <a062ce8d-638a-4a33-8afa-45ad47efcd72@quicinc.com>


On 2/14/2024 6:29 AM, Rob Herring wrote:
> On Tue, Feb 13, 2024 at 08:05:17AM -0800, Mao Jinlong wrote:
>> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
>> bit.
> That may be, but this is an ABI and you are stuck with it. Unless, you
> can justify why that doesn't matter. (IIRC, this is new, so maybe no
> users yet?)

Hi Rob,

Because for CMB type, it uses qcom,cmb-element-bits. So I change the 
format to be the same as
CMB.

Thanks
Jinlong Mao



From anshuman.khandual at arm.com  Tue Feb 13 19:35:29 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 14 Feb 2024 09:05:29 +0530
Subject: [PATCH V4 03/11] coresight: tmc: Extract device properties from
 AMBA pid based table lookup
In-Reply-To: <39c01eae-049b-4f5b-b86e-4af22c8246c1@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-4-anshuman.khandual@arm.com>
 <44597c9a-79bd-40f8-87a7-b53582132583@arm.com>
 <0c65f3b0-a879-444c-b0a4-4af485e72166@arm.com>
 <39c01eae-049b-4f5b-b86e-4af22c8246c1@arm.com>
Message-ID: <14d4c862-0880-408c-bc4e-5047c7eace87@arm.com>



On 2/13/24 16:02, Suzuki K Poulose wrote:
> On 13/02/2024 03:13, Anshuman Khandual wrote:
>>
>>
>> On 2/12/24 17:43, Suzuki K Poulose wrote:
>>> On 23/01/2024 05:46, Anshuman Khandual wrote:
>>>> This extracts device properties from AMBA pid based table lookup. This also
>>>> defers tmc_etr_setup_caps() after the coresight device has been initialized
>>>> so that PID value can be read.
>>>>
>>>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>>>> Cc: Mike Leach <mike.leach at linaro.org>
>>>> Cc: James Clark <james.clark 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>
>>>> ---
>>>> ?? .../hwtracing/coresight/coresight-tmc-core.c? | 19 +++++++++++++------
>>>> ?? 1 file changed, 13 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
>>>> index 7ec5365e2b64..e71db3099a29 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
>>>> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
>>>> @@ -370,16 +370,24 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
>>>> ?????? return (auth & TMC_AUTH_NSID_MASK) == 0x3;
>>>> ?? }
>>>> ?? +#define TMC_AMBA_MASK 0xfffff
>>>> +
>>>> +static const struct amba_id tmc_ids[];
>>>> +
>>>> ?? /* Detect and initialise the capabilities of a TMC ETR */
>>>> -static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
>>>> +static int tmc_etr_setup_caps(struct device *parent, u32 devid)
>>>> ?? {
>>>> ?????? int rc;
>>>> -??? u32 dma_mask = 0;
>>>> +??? u32 tmc_pid, dma_mask = 0;
>>>> ?????? struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
>>>> +??? void *dev_caps;
>>>> ?? ????? if (!tmc_etr_has_non_secure_access(drvdata))
>>>> ?????????? return -EACCES;
>>>> ?? +??? tmc_pid = coresight_get_pid(&drvdata->csdev->access) & TMC_AMBA_MASK;
>>>> +??? dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid);
>>>> +
>>>> ?????? /* Set the unadvertised capabilities */
>>>> ?????? tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
>>>> ?? @@ -497,10 +505,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>>> ?????????? desc.type = CORESIGHT_DEV_TYPE_SINK;
>>>> ?????????? desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
>>>> ?????????? desc.ops = &tmc_etr_cs_ops;
>>>> -??????? ret = tmc_etr_setup_caps(dev, devid,
>>>> -???????????????????? coresight_get_uci_data(id));
>>>> -??????? if (ret)
>>>> -??????????? goto out;
>>>> ?????????? idr_init(&drvdata->idr);
>>>> ?????????? mutex_init(&drvdata->idr_mutex);
>>>> ?????????? dev_list = &etr_devs;
>>>> @@ -539,6 +543,9 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>>> ?????????? goto out;
>>>> ?????? }
>>>> ?? +??? if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
>>>> +??????? ret = tmc_etr_setup_caps(dev, devid);
>>>> +
>>>
>>> With this change, we silently accept an ETR that may only have "SECURE" access only and crash later while we try to enable tracing. You could
>>> pass in the "access" (which is already in 'desc.access' in the original
>>> call site and deal with it ?
>>
>> Just wondering, if something like the following will help ? A failed tmc_etr_setup_caps()
>> because of failed tmc_etr_has_non_secure_access(), will unregister the coresight device
>> before returning.
>>
>> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
>> @@ -538,8 +538,13 @@ static int __tmc_probe(struct device *dev, struct resource *res)
>> ???????????????? goto out;
>> ???????? }
>> ? -?????? if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
>> +?????? if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
>> ???????????????? ret = tmc_etr_setup_caps(dev, devid);
>> +?????????????? if (ret) {
>> +?????????????????????? coresight_unregister(drvdata->csdev);
>> +?????????????????????? goto out;
>> +?????????????? }
>> +?????? }
> 
> Why do we move the tmc_etr_setup_caps() in the first place ? We could retain where that was and pass "desc.access" parameter rather than registering the csdev and then relying csdev->access ?

Agreed, and after implementing the changes suggested above, the entire patch
will look something like the following. Please do confirm if this looks good
enough.

--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -370,16 +370,25 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
        return (auth & TMC_AUTH_NSID_MASK) == 0x3;
 }
 
+#define TMC_AMBA_MASK 0xfffff
+
+static const struct amba_id tmc_ids[];
+
 /* Detect and initialise the capabilities of a TMC ETR */
-static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
+static int tmc_etr_setup_caps(struct device *parent, u32 devid,
+                             struct csdev_access *access)
 {
        int rc;
-       u32 dma_mask = 0;
+       u32 tmc_pid, dma_mask = 0;
        struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
+       void *dev_caps;
 
        if (!tmc_etr_has_non_secure_access(drvdata))
                return -EACCES;
 
+       tmc_pid = coresight_get_pid(access) & TMC_AMBA_MASK;
+       dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid);
+
        /* Set the unadvertised capabilities */
        tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
 
@@ -497,8 +506,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
                desc.type = CORESIGHT_DEV_TYPE_SINK;
                desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
                desc.ops = &tmc_etr_cs_ops;
-               ret = tmc_etr_setup_caps(dev, devid,
-                                        coresight_get_uci_data(id));
+               ret = tmc_etr_setup_caps(dev, devid, &desc.access);
                if (ret)
                        goto out;
                idr_init(&drvdata->idr);



From tim at feathertop.org  Tue Feb 13 20:00:06 2024
From: tim at feathertop.org (Tim Lunn)
Date: Wed, 14 Feb 2024 15:00:06 +1100
Subject: [PATCH] dt-bindings: rockchip: Fix Hardkernel ODROID-M1 board
 bindings
In-Reply-To: <2185016.Icojqenx9y@phil>
References: <20240115145142.6292-1-lee@kyuhyuk.kr> <47795047.XUcTiDjVJD@diego>
 <194a0894-a9f9-4c5e-b304-e7278104d8e7@feathertop.org>
 <2185016.Icojqenx9y@phil>
Message-ID: <3aa1fe01-0d7d-4d42-af31-8cdd24363910@feathertop.org>

Hi Heiko,

On 2/14/24 06:31, Heiko Stuebner wrote:
> Hi Tim,
>
> Am Mittwoch, 17. Januar 2024, 11:03:26 CET schrieb Tim Lunn:
>> On 1/17/24 06:55, Heiko St?bner wrote:
>>> Am Dienstag, 16. Januar 2024, 20:26:05 CET schrieb Rob Herring:
>>>> On Tue, Jan 16, 2024 at 09:31:35AM +0100, Heiko St?bner wrote:
>>>>> Am Dienstag, 16. Januar 2024, 08:24:44 CET schrieb Krzysztof Kozlowski:
>>>>>> On 16/01/2024 03:00, Tim Lunn wrote:
>>>>>>> On 1/16/24 01:58, Krzysztof Kozlowski wrote:
>>>>>>>> On 15/01/2024 15:51, KyuHyuk Lee wrote:
>>>>>>>>> The vendor in ODROID-M1 is hardkernel, but it was incorrectly written
>>>>>>>>> as rockchip. Fixed the vendor prefix correctly.
>>>>>>>>>
>>>>>>>>> Signed-off-by: KyuHyuk Lee <lee at kyuhyuk.kr>
>>>>>>>>> ---
>>>>>>>>>     Documentation/devicetree/bindings/arm/rockchip.yaml | 2 +-
>>>>>>>>>     1 file changed, 1 insertion(+), 1 deletion(-)
>>>>>>>> You need to start testing your patches. Your last M1 fails as well in
>>>>>>>> multiple places.
>>>>>>>>
>>>>>>>> It does not look like you tested the DTS against bindings. Please run
>>>>>>>> `make dtbs_check W=1` (see
>>>>>>>> Documentation/devicetree/bindings/writing-schema.rst or
>>>>>>>> https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
>>>>>>>> for instructions).
>>>>>>>>
>>>>>>>> The DTS change will break the users, so would be nice to mention this in
>>>>>>>> its commit msg.
>>>>>>> I notice there are a couple of other boards that incorrectly use
>>>>>>> rockchip as the vendor also:
>>>>>>>
>>>>>>>              - const: rockchip,rk3399-orangepi
>>>>>>>              - const: rockchip,rk3568-bpi-r2pro
>>>>>>>
>>>>>>> Perhaps these should also be fixed at the same time?
>>>>>> What is happening with rockchip boards?
>>>>> Copy-paste stuff ... boards using rockchip,boardname instead of
>>>>> vendor,boardname for their compatible.
>>>>>
>>>>> I do remember us noticing this a number of times on some boards
>>>>> and requesting fixes, but looks like some slipped through.
>>>>>
>>>>> So I guess Tim is suggesting changing the compatible, but with boards
>>>>> being merged a while ago, this would break backwards compatibility.
>>>>> So I guess both the Orange and Banana Pies will need to live with that.
>>>> You may get away with it because we generally don't use the names...
>>>>
>>>> Though there are some discussions to start using them to select dtbs by
>>>> bootloaders.
>>> Ah, that's good to know (both points) ... so essentially right now would be
>>> a good time to do what Tim suggested, before the names get actual usage.
>>>
>>> @Tim: is that something you'd want to do?
>>>
>> Sure, I will prepare patches and send them out soon.
> As I stumbled upon this patch just now, how is that coming along? :-)


Thanks for the reminder, I will send them now ;)

Regards
 ? Tim

>
> Thanks
> Heiko
>
>


From tim at feathertop.org  Tue Feb 13 20:07:27 2024
From: tim at feathertop.org (Tim Lunn)
Date: Wed, 14 Feb 2024 15:07:27 +1100
Subject: [PATCH 0/4] Fix vendor strings on Rockchip boards
Message-ID: <20240214040731.3069111-1-tim@feathertop.org>


A couple of rockchip boards incorrectly list their vendor as Rockchip
when they are in fact not manufactured by Rockchip.

Fix the vendor strings to correctly list the manufacturer


Tim Lunn (4):
  dt-bindings: arm: rockchip: Correct vendor for Orange Pi RK3399 board
  dt-bindings: arm: rockchip: Correct vendor for Banana Pi R2 Pro
  arm64: dts: rockchip: adjust vendor on Banana Pi R2 Pro board
  arm64: dts: rockchip: adjust vendor on orangepi rk3399 board

 Documentation/devicetree/bindings/arm/rockchip.yaml | 8 ++++----
 arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts    | 2 +-
 arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts  | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

-- 
2.40.1



From tim at feathertop.org  Tue Feb 13 20:07:28 2024
From: tim at feathertop.org (Tim Lunn)
Date: Wed, 14 Feb 2024 15:07:28 +1100
Subject: [PATCH 1/4] dt-bindings: arm: rockchip: Correct vendor for Orange Pi RK3399 board
In-Reply-To: <20240214040731.3069111-1-tim@feathertop.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
Message-ID: <20240214040731.3069111-2-tim@feathertop.org>

The vendor for this board was incorrectly listed as Rockchip. Fix this
now while they are not used anywhere, in the future they may be used by
bootloader to select dts.

Update the vendor to Xunlong.

Signed-off-by: Tim Lunn <tim at feathertop.org>
---

 Documentation/devicetree/bindings/arm/rockchip.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 5cf5cbef2cf5..29f922f3ca4e 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -626,9 +626,9 @@ properties:
           - const: openailab,eaidk-610
           - const: rockchip,rk3399
 
-      - description: Orange Pi RK3399 board
+      - description: Xunlong Orange Pi RK3399 board
         items:
-          - const: rockchip,rk3399-orangepi
+          - const: xunlong,rk3399-orangepi
           - const: rockchip,rk3399
 
       - description: Phytec phyCORE-RK3288 Rapid Development Kit
-- 
2.40.1



From tim at feathertop.org  Tue Feb 13 20:07:29 2024
From: tim at feathertop.org (Tim Lunn)
Date: Wed, 14 Feb 2024 15:07:29 +1100
Subject: [PATCH 2/4] dt-bindings: arm: rockchip: Correct vendor for Banana Pi R2 Pro
In-Reply-To: <20240214040731.3069111-1-tim@feathertop.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
Message-ID: <20240214040731.3069111-3-tim@feathertop.org>

The vendor for this board was incorrectly listed as Rockchip. Fix this
now while they are not used anywhere, in the future they may be used by
bootloader to select dts.

Update the vendor to Sinovoip.

Signed-off-by: Tim Lunn <tim at feathertop.org>
---

 Documentation/devicetree/bindings/arm/rockchip.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 29f922f3ca4e..89261b9601ce 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -940,9 +940,9 @@ properties:
           - const: rockchip,rk3568-evb1-v10
           - const: rockchip,rk3568
 
-      - description: Rockchip RK3568 Banana Pi R2 Pro
+      - description: Sinovoip RK3568 Banana Pi R2 Pro
         items:
-          - const: rockchip,rk3568-bpi-r2pro
+          - const: sinovoip,rk3568-bpi-r2pro
           - const: rockchip,rk3568
 
       - description: Sonoff iHost Smart Home Hub
-- 
2.40.1



From tim at feathertop.org  Tue Feb 13 20:07:30 2024
From: tim at feathertop.org (Tim Lunn)
Date: Wed, 14 Feb 2024 15:07:30 +1100
Subject: [PATCH 3/4] arm64: dts: rockchip: adjust vendor on Banana Pi R2 Pro board
In-Reply-To: <20240214040731.3069111-1-tim@feathertop.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
Message-ID: <20240214040731.3069111-4-tim@feathertop.org>

Adjust compatible string to match the board vendor of Sinovoip

Signed-off-by: Tim Lunn <tim at feathertop.org>
---

 arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
index f9127ddfbb7d..7b5f3904ef61 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
@@ -13,7 +13,7 @@
 
 / {
 	model = "Bananapi-R2 Pro (RK3568) DDR4 Board";
-	compatible = "rockchip,rk3568-bpi-r2pro", "rockchip,rk3568";
+	compatible = "sinovoip,rk3568-bpi-r2pro", "rockchip,rk3568";
 
 	aliases {
 		ethernet0 = &gmac0;
-- 
2.40.1



From tim at feathertop.org  Tue Feb 13 20:07:31 2024
From: tim at feathertop.org (Tim Lunn)
Date: Wed, 14 Feb 2024 15:07:31 +1100
Subject: [PATCH 4/4] arm64: dts: rockchip: adjust vendor on orangepi rk3399 board
In-Reply-To: <20240214040731.3069111-1-tim@feathertop.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
Message-ID: <20240214040731.3069111-5-tim@feathertop.org>

Adjust compatible string to match the board vendor of Xunlong

Signed-off-by: Tim Lunn <tim at feathertop.org>
---

 arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
index e7551449e718..e26e2d86279c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
@@ -14,7 +14,7 @@
 
 / {
 	model = "Orange Pi RK3399 Board";
-	compatible = "rockchip,rk3399-orangepi", "rockchip,rk3399";
+	compatible = "xunlong,rk3399-orangepi", "rockchip,rk3399";
 
 	aliases {
 		ethernet0 = &gmac;
-- 
2.40.1



From dsimic at manjaro.org  Tue Feb 13 20:14:21 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 14 Feb 2024 05:14:21 +0100
Subject: [PATCH 0/4] Fix vendor strings on Rockchip boards
In-Reply-To: <20240214040731.3069111-1-tim@feathertop.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
Message-ID: <c03220db663279c9e83bab81f3d829e7@manjaro.org>

Hello Tim,

On 2024-02-14 05:07, Tim Lunn wrote:
> A couple of rockchip boards incorrectly list their vendor as Rockchip
> when they are in fact not manufactured by Rockchip.
> 
> Fix the vendor strings to correctly list the manufacturer

Just checking, have you verified that the old, incorrect "compatible"
strings from the board dts files aren't used anywhere in the kernel 
code,
such as in some drivers?

Otherwise, for the entire series:

Reviewed-by: Dragan Simic <dsimic at manjaro.org>

> Tim Lunn (4):
>   dt-bindings: arm: rockchip: Correct vendor for Orange Pi RK3399 board
>   dt-bindings: arm: rockchip: Correct vendor for Banana Pi R2 Pro
>   arm64: dts: rockchip: adjust vendor on Banana Pi R2 Pro board
>   arm64: dts: rockchip: adjust vendor on orangepi rk3399 board
> 
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 8 ++++----
>  arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts    | 2 +-
>  arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts  | 2 +-
>  3 files changed, 6 insertions(+), 6 deletions(-)


From kvijayab at amd.com  Tue Feb 13 20:17:54 2024
From: kvijayab at amd.com (Kishon Vijay Abraham I)
Date: Wed, 14 Feb 2024 09:47:54 +0530
Subject: [PATCH 0/2] PCI endpoint BAR hardware description cleanup
In-Reply-To: <20240210012634.600301-1-cassel@kernel.org>
References: <20240210012634.600301-1-cassel@kernel.org>
Message-ID: <7a243a1e-6b47-bc2f-c538-b57db1c9c580@amd.com>

Hi Niklas,

On 2/10/2024 6:56 AM, Niklas Cassel wrote:
> The series is based on top of:
> https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=endpoint
> 
> 
> Hello all,
> 
> This series cleans up the hardware description for PCI endpoint BARs.
> 
> The problems with the existing hardware description:
> -The documentation is lackluster.
> -Some of the names are confusingly similar, e.g. fixed_64bit and
>   fixed_size, even though these are for completely unrelated things.
> -The way that the BARs are defined in the endpoint controller drivers
>   is messy, because the left hand side is not a BAR, so you can mark a
>   BAR as e.g. both fixed size and reserved.
> 
> This series tries to address all the problems above.
> 
> Personally, I think that the code is more readable, both the endpoint
> controller drivers, but also pci-epc-core.c.

Thank you for cleaning this up!

FWIW:
Reviewed-by: Kishon Vijay Abraham I <kishon at kernel.org>
> 
> (Oh, and as you can probably guess, I will be sending out a patch series
> that adds BAR_RESIZABLE to enum pci_epc_bar_type in the coming week(s).)
> 
> 
> Kind regards,
> Niklas
> 
> 
> Niklas Cassel (2):
>    PCI: endpoint: Clean up hardware description for BARs
>    PCI: endpoint: Drop only_64bit on reserved BARs
> 
>   drivers/pci/controller/dwc/pci-imx6.c         |  3 +-
>   drivers/pci/controller/dwc/pci-keystone.c     | 12 +++---
>   .../pci/controller/dwc/pci-layerscape-ep.c    |  5 ++-
>   drivers/pci/controller/dwc/pcie-keembay.c     |  8 +++-
>   drivers/pci/controller/dwc/pcie-rcar-gen4.c   |  4 +-
>   drivers/pci/controller/dwc/pcie-tegra194.c    | 10 +++--
>   drivers/pci/controller/dwc/pcie-uniphier-ep.c | 15 ++++++--
>   drivers/pci/controller/pcie-rcar-ep.c         | 14 ++++---
>   drivers/pci/endpoint/functions/pci-epf-ntb.c  |  4 +-
>   drivers/pci/endpoint/functions/pci-epf-test.c |  8 ++--
>   drivers/pci/endpoint/functions/pci-epf-vntb.c |  2 +-
>   drivers/pci/endpoint/pci-epc-core.c           | 25 +++++-------
>   drivers/pci/endpoint/pci-epf-core.c           | 15 ++++----
>   include/linux/pci-epc.h                       | 38 ++++++++++++++++---
>   14 files changed, 105 insertions(+), 58 deletions(-)
> 


From tim at feathertop.org  Tue Feb 13 20:27:08 2024
From: tim at feathertop.org (Tim Lunn)
Date: Wed, 14 Feb 2024 15:27:08 +1100
Subject: [PATCH 0/4] Fix vendor strings on Rockchip boards
In-Reply-To: <c03220db663279c9e83bab81f3d829e7@manjaro.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
 <c03220db663279c9e83bab81f3d829e7@manjaro.org>
Message-ID: <e952d127-b12d-4b5a-838b-807a876db707@feathertop.org>

Hi Dragan,

On 2/14/24 15:14, Dragan Simic wrote:
> Hello Tim,
>
> On 2024-02-14 05:07, Tim Lunn wrote:
>> A couple of rockchip boards incorrectly list their vendor as Rockchip
>> when they are in fact not manufactured by Rockchip.
>>
>> Fix the vendor strings to correctly list the manufacturer
>
> Just checking, have you verified that the old, incorrect "compatible"
> strings from the board dts files aren't used anywhere in the kernel code,
> such as in some drivers?
>
Yes I checked that, there are no remaining references to the 
old/incorrect compatible strings in kernel code

Regards
 ?? Tim
> Otherwise, for the entire series:
>
> Reviewed-by: Dragan Simic <dsimic at manjaro.org>
>
>> Tim Lunn (4):
>> ? dt-bindings: arm: rockchip: Correct vendor for Orange Pi RK3399 board
>> ? dt-bindings: arm: rockchip: Correct vendor for Banana Pi R2 Pro
>> ? arm64: dts: rockchip: adjust vendor on Banana Pi R2 Pro board
>> ? arm64: dts: rockchip: adjust vendor on orangepi rk3399 board
>>
>> ?Documentation/devicetree/bindings/arm/rockchip.yaml | 8 ++++----
>> ?arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts??? | 2 +-
>> ?arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts? | 2 +-
>> ?3 files changed, 6 insertions(+), 6 deletions(-)


From hj96.nam at samsung.com  Tue Feb 13 20:52:14 2024
From: hj96.nam at samsung.com (Hojin Nam)
Date: Wed, 14 Feb 2024 13:52:14 +0900
Subject: [PATCH] perf: CXL: fix CPMU filter value mask length
References: <CGME20240214045214epcms2p81d2ea826483fb4aecf19930f2755d55b@epcms2p8>
Message-ID: <20240214045214epcms2p81d2ea826483fb4aecf19930f2755d55b@epcms2p8>

CPMU filter value is described as 4B length in CXL r3.0 8.2.7.2.2.
However, it is used as 2B length in code and comments.

Fixes: 5d7107c72796 ("perf: CXL Performance Monitoring Unit driver")
Signed-off-by: Hojin Nam
---
 drivers/perf/cxl_pmu.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index 365d964b0f6a..ca5e92f28b4a 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -59,7 +59,7 @@
 #define   CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK     GENMASK_ULL(63, 59)

 #define CXL_PMU_FILTER_CFG_REG(n, f)   (0x400 + 4 * ((f) + (n) * 8))
-#define   CXL_PMU_FILTER_CFG_VALUE_MSK                 GENMASK(15, 0)
+#define   CXL_PMU_FILTER_CFG_VALUE_MSK                 GENMASK(31, 0)

 #define CXL_PMU_COUNTER_REG(n)         (0xc00 + 8 * (n))

@@ -314,9 +314,9 @@ static bool cxl_pmu_config1_get_edge(struct perf_event *event)
 }

 /*
- * CPMU specification allows for 8 filters, each with a 16 bit value...
- * So we need to find 8x16bits to store it in.
- * As the value used for disable is 0xffff, a separate enable switch
+ * CPMU specification allows for 8 filters, each with a 32 bit value...
+ * So we need to find 8x32bits to store it in.
+ * As the value used for disable is 0xffff_ffff, a separate enable switch
  * is needed.
  */

@@ -642,7 +642,7 @@ static void cxl_pmu_event_start(struct perf_event *event, int flags)
                if (cxl_pmu_config1_hdm_filter_en(event))
                        cfg = cxl_pmu_config2_get_hdm_decoder(event);
                else
-                       cfg = GENMASK(15, 0); /* No filtering if 0xFFFF_FFFF */
+                       cfg = GENMASK(31, 0); /* No filtering if 0xFFFF_FFFF */
                writeq(cfg, base + CXL_PMU_FILTER_CFG_REG(hwc->idx, 0));
        }

--
2.34.1


From quic_pbrahma at quicinc.com  Tue Feb 13 20:59:06 2024
From: quic_pbrahma at quicinc.com (Pratyush Brahma)
Date: Wed, 14 Feb 2024 10:29:06 +0530
Subject: [PATCH v1 08/10] iommu/arm-smmu-qcom: Merge table from
 arm-smmu-qcom-debug into match data
In-Reply-To: <CAA8EJpoJUZDUxpA1+LJTEVRaMQJrpZ7iU9_dZ3uQvzPKE_UUfg@mail.gmail.com>
References: <20221114170635.1406534-9-dmitry.baryshkov@linaro.org>
 <a61a3561-0dde-472b-b8a5-451703f6d8ee@quicinc.com>
 <CAA8EJpoJUZDUxpA1+LJTEVRaMQJrpZ7iU9_dZ3uQvzPKE_UUfg@mail.gmail.com>
Message-ID: <8a2a4ae4-26d3-40f2-b87b-336093a1ec8f@quicinc.com>


On 2/13/2024 4:40 PM, Dmitry Baryshkov wrote:
> On Tue, 13 Feb 2024 at 12:29, Pratyush Brahma <quic_pbrahma at quicinc.com> wrote:
>> Hi
>>
>> Patch [1] introduces a use after free bug in the function
>> "qcom_smmu_create()" in file: drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> wherein devm_krealloc() frees the old pointer marked by "smmu" but it is
>> still being accessed later in qcom_smmu_impl_data() in the same function
>> as:
>>
>> qsmmu->cfg = qcom_smmu_impl_data(smmu);
>>
>> The current patchset [2] implicitly fixes this issue as it doesn't
>> access the freed ptr in the line:
>>
>> qsmmu->cfg = data->cfg;
>>
>> Hence, can this patchset[2] be propagated to branches where patchset[1]
>> has been propagated already? The bug is currently present in all branches
>> that have patchset[1] but do not have patchset[2].
Can you please comment on your thoughts on this as well?
>>
>> RFC:
>>
>> This bug would be reintroduced if patchset [3] is accepted. This makes
>> the path prone to such errors as it relies on the
>> developer's understanding on the internal implementation of devm_krealloc().
> realloc is a basic function. Not understanding it is a significant
> problem for the developer.
>
>> Hence, a better fix IMO, would be to remove the confusion around the
>> freed "smmu" ptr in the following way:
> Could you please post a proper patch, which can be reviewed and
> accepted or declined?
Sure, will do.
>
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> index 549ae4dba3a6..6dd142ce75d1 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> @@ -463,11 +463,12 @@ static struct arm_smmu_device
>> *qcom_smmu_create(struct arm_smmu_device *smmu,
>>           qsmmu = devm_krealloc(smmu->dev, smmu, sizeof(*qsmmu), GFP_KERNEL);
>>           if (!qsmmu)
>>                   return ERR_PTR(-ENOMEM);
>> +       smmu = &qsmmu->smmu;
>>
>>           qsmmu->smmu.impl = impl;
>>           qsmmu->cfg = data->cfg;
>>
>> -       return &qsmmu->smmu;
>> +       return smmu;
>>    }
>>
>> This is similar to the patch[4] which I've sent in-reply-to patch[3].
>> Will send a formal patch if you think this approach is better.
>>
>> Please let me know your thoughts.
> None of the other implementations does this. If you are going to fix
> qcom implementation, please fix all implementations.
Ohh okay. Wasn't aware that this may be an issue in other 
implementations as well.
Will check and raise a formal patch.
>   However a better
> option might be to change arm-smmu to remove devm_krealloc() usage at
> all.
>
Can you please elaborate on your thoughts on how removing devm_krealloc()
usage would be better? Is it because this implementation is error prone 
or do you
think this isn't required at all?


I agree on your previous comment that realloc is a basic function and 
developers
should understand that before using it. But as you've pointed out that 
implementations other than
qcom may also have this issue, I'm inclined to think that the usage of 
the api is quite error prone and
there may be some room for improving the usage text perhaps or some 
other way.
>
> --
> With best wishes
> Dmitry
Thanks,
Pratyush


From yoshihiro.shimoda.uh at renesas.com  Tue Feb 13 21:20:50 2024
From: yoshihiro.shimoda.uh at renesas.com (Yoshihiro Shimoda)
Date: Wed, 14 Feb 2024 14:20:50 +0900
Subject: [PATCH] irqchip/gic-v3-its: Workaround Renesas R-Car GICv3 ITS
Message-ID: <20240214052050.1966439-1-yoshihiro.shimoda.uh@renesas.com>

The GICv3 ITS on Renesas R-Car has limitations:
 - It can access lower 32-bits memory area only.
 - It cannot use Sharable/cache attributes.

So, set ITS_FLAGS_FORCE_NON_SHAREABLE flag, and set GFP_DMA to all
memory allocation APIs for getting lower 32-bits memory area on
the R-Car. Note that GFP_DMA32 cannot work correctly because
the environment doens't have DMA32 zone like below:

[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000048000000-0x00000000ffffffff]
[    0.000000]   DMA32    empty
[    0.000000]   Normal   [mem 0x0000000100000000-0x00000004ffffffff]

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
---
 arch/arm64/Kconfig               |  9 +++++
 drivers/irqchip/irq-gic-v3-its.c | 59 +++++++++++++++++++++-----------
 2 files changed, 48 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c1a16a9dae72..49fe3006e142 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1250,6 +1250,15 @@ config SOCIONEXT_SYNQUACER_PREITS
 
 	  If unsure, say Y.
 
+config RENESAS_RCAR_GIC_ITS
+	bool "Renesas R-Car: Workaround for GICv3 ITS"
+	default n
+	help
+	  Renesas R-Car Gen4 SoCs has a limitation about GICv3 ITS which can
+	  access lower 32-bits memory address range only.
+
+	  If unsure, say Y.
+
 endmenu # "ARM errata workarounds via the alternatives framework"
 
 choice
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index d097001c1e3e..e0e672b561b9 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -186,6 +186,7 @@ static LIST_HEAD(its_nodes);
 static DEFINE_RAW_SPINLOCK(its_lock);
 static struct rdists *gic_rdists;
 static struct irq_domain *its_parent;
+static gfp_t its_gfp_quirk;
 
 static unsigned long its_list_map;
 static u16 vmovp_seq_num;
@@ -1846,7 +1847,7 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
 		struct its_vlpi_map *maps;
 
 		maps = kcalloc(its_dev->event_map.nr_lpis, sizeof(*maps),
-			       GFP_ATOMIC);
+			       GFP_ATOMIC | its_gfp_quirk);
 		if (!maps) {
 			ret = -ENOMEM;
 			goto out;
@@ -2044,7 +2045,7 @@ static struct lpi_range *mk_lpi_range(u32 base, u32 span)
 {
 	struct lpi_range *range;
 
-	range = kmalloc(sizeof(*range), GFP_KERNEL);
+	range = kmalloc(sizeof(*range), GFP_KERNEL | its_gfp_quirk);
 	if (range) {
 		range->base_id = base;
 		range->span = span;
@@ -2169,7 +2170,7 @@ static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids)
 	if (err)
 		goto out;
 
-	bitmap = bitmap_zalloc(nr_irqs, GFP_ATOMIC);
+	bitmap = bitmap_zalloc(nr_irqs, GFP_ATOMIC | its_gfp_quirk);
 	if (!bitmap)
 		goto out;
 
@@ -2201,7 +2202,7 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags)
 {
 	struct page *prop_page;
 
-	prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
+	prop_page = alloc_pages(gfp_flags | its_gfp_quirk, get_order(LPI_PROPBASE_SZ));
 	if (!prop_page)
 		return NULL;
 
@@ -2335,7 +2336,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 		order = get_order(GITS_BASER_PAGES_MAX * psz);
 	}
 
-	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
+	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO | its_gfp_quirk, order);
 	if (!page)
 		return -ENOMEM;
 
@@ -2808,7 +2809,7 @@ static bool allocate_vpe_l2_table(int cpu, u32 id)
 
 	/* Allocate memory for 2nd level table */
 	if (!table[idx]) {
-		page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(psz));
+		page = alloc_pages(GFP_KERNEL | __GFP_ZERO | its_gfp_quirk, get_order(psz));
 		if (!page)
 			return false;
 
@@ -2860,7 +2861,7 @@ static int allocate_vpe_l1_table(void)
 	if (val & GICR_VPROPBASER_4_1_VALID)
 		goto out;
 
-	gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_ATOMIC);
+	gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_ATOMIC | its_gfp_quirk);
 	if (!gic_data_rdist()->vpe_table_mask)
 		return -ENOMEM;
 
@@ -2927,7 +2928,7 @@ static int allocate_vpe_l1_table(void)
 
 	pr_debug("np = %d, npg = %lld, psz = %d, epp = %d, esz = %d\n",
 		 np, npg, psz, epp, esz);
-	page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, get_order(np * PAGE_SIZE));
+	page = alloc_pages(GFP_ATOMIC | __GFP_ZERO | its_gfp_quirk, get_order(np * PAGE_SIZE));
 	if (!page)
 		return -ENOMEM;
 
@@ -2957,7 +2958,7 @@ static int its_alloc_collections(struct its_node *its)
 	int i;
 
 	its->collections = kcalloc(nr_cpu_ids, sizeof(*its->collections),
-				   GFP_KERNEL);
+				   GFP_KERNEL | its_gfp_quirk);
 	if (!its->collections)
 		return -ENOMEM;
 
@@ -2971,7 +2972,7 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags)
 {
 	struct page *pend_page;
 
-	pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
+	pend_page = alloc_pages(gfp_flags | __GFP_ZERO | its_gfp_quirk,
 				get_order(LPI_PENDBASE_SZ));
 	if (!pend_page)
 		return NULL;
@@ -3319,7 +3320,7 @@ static bool its_alloc_table_entry(struct its_node *its,
 
 	/* Allocate memory for 2nd level table */
 	if (!table[idx]) {
-		page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
+		page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO | its_gfp_quirk,
 					get_order(baser->psz));
 		if (!page)
 			return false;
@@ -3415,7 +3416,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 	if (WARN_ON(!is_power_of_2(nvecs)))
 		nvecs = roundup_pow_of_two(nvecs);
 
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL | its_gfp_quirk);
 	/*
 	 * Even if the device wants a single LPI, the ITT must be
 	 * sized as a power of two (and you need at least one bit...).
@@ -3423,14 +3424,14 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 	nr_ites = max(2, nvecs);
 	sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1);
 	sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
-	itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node);
+	itt = kzalloc_node(sz, GFP_KERNEL | its_gfp_quirk, its->numa_node);
 	if (alloc_lpis) {
 		lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis);
 		if (lpi_map)
 			col_map = kcalloc(nr_lpis, sizeof(*col_map),
-					  GFP_KERNEL);
+					  GFP_KERNEL | its_gfp_quirk);
 	} else {
-		col_map = kcalloc(nr_ites, sizeof(*col_map), GFP_KERNEL);
+		col_map = kcalloc(nr_ites, sizeof(*col_map), GFP_KERNEL | its_gfp_quirk);
 		nr_lpis = 0;
 		lpi_base = 0;
 	}
@@ -4754,6 +4755,16 @@ static bool __maybe_unused its_enable_rk3588001(void *data)
 	return true;
 }
 
+static bool __maybe_unused its_enable_renesas_rcar_gic_its(void *data)
+{
+	struct its_node *its = data;
+
+	its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
+	its_gfp_quirk = GFP_DMA;
+
+	return true;
+}
+
 static bool its_set_non_coherent(void *data)
 {
 	struct its_node *its = data;
@@ -4815,6 +4826,14 @@ static const struct gic_quirk its_quirks[] = {
 		.mask   = 0xffffffff,
 		.init   = its_enable_rk3588001,
 	},
+#endif
+#ifdef CONFIG_RENESAS_RCAR_GIC_ITS
+	{
+		.desc   = "ITS: Renesas R-Car Gen4 GICv3 ITS",
+		.iidr   = 0x0201743b,
+		.mask   = 0xffffffff,
+		.init   = its_enable_renesas_rcar_gic_its,
+	},
 #endif
 	{
 		.desc   = "ITS: non-coherent attribute",
@@ -4974,7 +4993,7 @@ static int its_init_domain(struct its_node *its)
 	struct irq_domain *inner_domain;
 	struct msi_domain_info *info;
 
-	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	info = kzalloc(sizeof(*info), GFP_KERNEL | its_gfp_quirk);
 	if (!info)
 		return -ENOMEM;
 
@@ -5011,7 +5030,7 @@ static int its_init_vpe_domain(void)
 
 	entries = roundup_pow_of_two(nr_cpu_ids);
 	vpe_proxy.vpes = kcalloc(entries, sizeof(*vpe_proxy.vpes),
-				 GFP_KERNEL);
+				 GFP_KERNEL | its_gfp_quirk);
 	if (!vpe_proxy.vpes)
 		return -ENOMEM;
 
@@ -5108,7 +5127,7 @@ static int __init its_probe_one(struct its_node *its)
 		}
 	}
 
-	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
+	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO | its_gfp_quirk,
 				get_order(ITS_CMD_QUEUE_SZ));
 	if (!page) {
 		err = -ENOMEM;
@@ -5352,7 +5371,7 @@ static struct its_node __init *its_node_init(struct resource *res,
 
 	pr_info("ITS %pR\n", res);
 
-	its = kzalloc(sizeof(*its), GFP_KERNEL);
+	its = kzalloc(sizeof(*its), GFP_KERNEL | its_gfp_quirk);
 	if (!its)
 		goto out_unmap;
 
@@ -5520,7 +5539,7 @@ static void __init acpi_table_parse_srat_its(void)
 		return;
 
 	its_srat_maps = kmalloc_array(count, sizeof(struct its_srat_map),
-				      GFP_KERNEL);
+				      GFP_KERNEL | its_gfp_quirk);
 	if (!its_srat_maps)
 		return;
 
-- 
2.25.1



From balakrishnan.s at microchip.com  Tue Feb 13 21:43:43 2024
From: balakrishnan.s at microchip.com (Balakrishnan Sambath)
Date: Wed, 14 Feb 2024 11:13:43 +0530
Subject: [PATCH] dt-bindings: mfd: Convert atmel-flexcom to json-schema
Message-ID: <20240214-sama5d2-flexcom-yaml-v1-1-5dedd0eba08e@microchip.com>

From: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>

Convert the Atmel flexcom device tree bindings to json schema.

Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>
---
The yaml DT bindings for the atmel-flexcom driver were submitted
upstream in a separate patch series in 2022 [1] which was Acked-by
Krzysztof Kozlowski. However, it has been observed recently that the
patch has not been merged into the mainline codebase.When attempting to
apply the patch to the latest upstream kernel,a conflict arose due to a
recent addition to the original device tree binding in text format. The
conflict has now been resolved and we are sending a updated version of
the patch. 
[1]https://lore.kernel.org/linux-arm-kernel/22063373-6060-d605-62af-35d82ba1729c at linaro.org/
---
 .../bindings/mfd/atmel,sama5d2-flexcom.yaml        | 92 ++++++++++++++++++++++
 .../devicetree/bindings/mfd/atmel-flexcom.txt      | 64 ---------------
 2 files changed, 92 insertions(+), 64 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml b/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml
new file mode 100644
index 000000000000..f28522cd987a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/atmel,sama5d2-flexcom.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel Flexcom (Flexible Serial Communication Unit)
+
+maintainers:
+  - Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
+
+description:
+  The Atmel Flexcom is just a wrapper which embeds a SPI controller,
+  an I2C controller and an USART. Only one function can be used at a
+  time and is chosen at boot time according to the device tree.
+
+properties:
+  compatible:
+    enum:
+      - atmel,sama5d2-flexcom
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges:
+    description:
+      One range for the full I/O register region. (including USART,
+      TWI and SPI registers).
+    items:
+      maxItems: 3
+
+  atmel,flexcom-mode:
+    description: |
+      Specifies the flexcom mode as follows:
+      1: USART
+      2: SPI
+      3: I2C.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2, 3]
+
+patternProperties:
+  "^serial@[0-9a-f]+$":
+    type: object
+    description:
+      Child node describing USART. See atmel-usart.txt for details
+      of USART bindings.
+
+  "^spi@[0-9a-f]+$":
+    type: object
+    description:
+      Child node describing SPI. See ../spi/spi_atmel.txt for details
+      of SPI bindings.
+
+  "^i2c@[0-9a-f]+$":
+    $ref: /schemas/i2c/atmel,at91sam-i2c.yaml
+    description:
+      Child node describing I2C.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+  - atmel,flexcom-mode
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    flx0: flexcom at f8034000 {
+        compatible = "atmel,sama5d2-flexcom";
+        reg = <0xf8034000 0x200>;
+        clocks = <&flx0_clk>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0x0 0xf8034000 0x800>;
+        atmel,flexcom-mode = <2>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt b/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt
deleted file mode 100644
index af692e8833a5..000000000000
--- a/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-* Device tree bindings for Atmel Flexcom (Flexible Serial Communication Unit)
-
-The Atmel Flexcom is just a wrapper which embeds a SPI controller, an I2C
-controller and an USART. Only one function can be used at a time and is chosen
-at boot time according to the device tree.
-
-Required properties:
-- compatible:		Should be "atmel,sama5d2-flexcom"
-			or "microchip,sam9x7-flexcom", "atmel,sama5d2-flexcom"
-- reg:			Should be the offset/length value for Flexcom dedicated
-			I/O registers (without USART, TWI or SPI registers).
-- clocks:		Should be the Flexcom peripheral clock from PMC.
-- #address-cells:	Should be <1>
-- #size-cells:		Should be <1>
-- ranges:		Should be one range for the full I/O register region
-			(including USART, TWI and SPI registers).
-- atmel,flexcom-mode:	Should be one of the following values:
-			- <1> for USART
-			- <2> for SPI
-			- <3> for I2C
-
-Required child:
-A single available child device of type matching the "atmel,flexcom-mode"
-property.
-
-The phandle provided by the clocks property of the child is the same as one for
-the Flexcom parent.
-
-For other properties, please refer to the documentations of the respective
-device:
-- ../serial/atmel-usart.txt
-- ../spi/spi_atmel.txt
-- ../i2c/i2c-at91.txt
-
-Example:
-
-flexcom at f8034000 {
-	compatible = "atmel,sama5d2-flexcom";
-	reg = <0xf8034000 0x200>;
-	clocks = <&flx0_clk>;
-	#address-cells = <1>;
-	#size-cells = <1>;
-	ranges = <0x0 0xf8034000 0x800>;
-	atmel,flexcom-mode = <2>;
-
-	spi at 400 {
-		compatible = "atmel,at91rm9200-spi";
-		reg = <0x400 0x200>;
-		interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_flx0_default>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		clocks = <&flx0_clk>;
-		clock-names = "spi_clk";
-		atmel,fifo-size = <32>;
-
-		flash at 0 {
-			compatible = "atmel,at25f512b";
-			reg = <0>;
-			spi-max-frequency = <20000000>;
-		};
-	};
-};

---
base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
change-id: 20240213-sama5d2-flexcom-yaml-30ccf6996358

Best regards,
-- 
Balakrishnan Sambath <balakrishnan.s at microchip.com>



From zajec5 at gmail.com  Tue Feb 13 22:12:30 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 14 Feb 2024 07:12:30 +0100
Subject: [PATCH V4 0/3] dt-bindings: clock: mediatek: convert MT7622-related bindings to the json-schema
Message-ID: <20240214061233.24645-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

There are more MediaTek bindings to convert but for now I focused on
those used by MT7622.

V2: Move bindings to /clock/
    Use clock-controller@ nodenames
    Drop incorrectly specified "syscon"

V3: Update titles of all 3 bindings
    Simplify HIFSYS compatbile (drop "items:")

V4: Use "clock: " prefix in subjects
    Send including clock maintainers

Rafa? Mi?ecki (3):
  dt-bindings: clock: mediatek: convert hifsys to the json-schema clock
  dt-bindings: clock: mediatek: convert PCIESYS to the json-schema clock
  dt-bindings: clock: mediatek: convert SSUSBSYS to the json-schema
    clock

 .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
 .../arm/mediatek/mediatek,pciesys.txt         | 25 ----------
 .../arm/mediatek/mediatek,ssusbsys.txt        | 25 ----------
 .../clock/mediatek,mt2701-hifsys.yaml         | 50 +++++++++++++++++++
 .../clock/mediatek,mt7622-pciesys.yaml        | 45 +++++++++++++++++
 .../clock/mediatek,mt7622-ssusbsys.yaml       | 45 +++++++++++++++++
 6 files changed, 140 insertions(+), 76 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml

-- 
2.35.3



From zajec5 at gmail.com  Tue Feb 13 22:12:33 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 14 Feb 2024 07:12:33 +0100
Subject: [PATCH V4 3/3] dt-bindings: clock: mediatek: convert SSUSBSYS to the json-schema clock
In-Reply-To: <20240214061233.24645-1-zajec5@gmail.com>
References: <20240214061233.24645-1-zajec5@gmail.com>
Message-ID: <20240214061233.24645-4-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Documented "reg" property
2. Dropped "syscon" as it was incorrectly used
3. Adjusted nodename, "compatible" and "reg" in example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../arm/mediatek/mediatek,ssusbsys.txt        | 25 -----------
 .../clock/mediatek,mt7622-ssusbsys.yaml       | 45 +++++++++++++++++++
 2 files changed, 45 insertions(+), 25 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
deleted file mode 100644
index 7cb02c930613..000000000000
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-MediaTek SSUSBSYS controller
-============================
-
-The MediaTek SSUSBSYS controller provides various clocks to the system.
-
-Required Properties:
-
-- compatible: Should be:
-	- "mediatek,mt7622-ssusbsys", "syscon"
-	- "mediatek,mt7629-ssusbsys", "syscon"
-- #clock-cells: Must be 1
-- #reset-cells: Must be 1
-
-The SSUSBSYS controller uses the common clk binding from
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-
-Example:
-
-ssusbsys: ssusbsys at 1a000000 {
-	compatible = "mediatek,mt7622-ssusbsys", "syscon";
-	reg = <0 0x1a000000 0 0x1000>;
-	#clock-cells = <1>;
-	#reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml
new file mode 100644
index 000000000000..da93eccdcfc1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7622-ssusbsys.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt7622-ssusbsys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek SSUSBSYS clock and reset controller
+
+description:
+  The MediaTek SSUSBSYS controller provides various clocks to the system.
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7622-ssusbsys
+      - mediatek,mt7629-ssusbsys
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+    description: The available clocks are defined in dt-bindings/clock/mt*-clk.h
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 1a000000 {
+        compatible = "mediatek,mt7622-ssusbsys";
+        reg = <0x1a000000 0x1000>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
-- 
2.35.3



From zajec5 at gmail.com  Tue Feb 13 22:12:32 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 14 Feb 2024 07:12:32 +0100
Subject: [PATCH V4 2/3] dt-bindings: clock: mediatek: convert PCIESYS to the json-schema clock
In-Reply-To: <20240214061233.24645-1-zajec5@gmail.com>
References: <20240214061233.24645-1-zajec5@gmail.com>
Message-ID: <20240214061233.24645-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Documented "reg" property
2. Dropped "syscon" as it was incorrectly used
3. Adjusted nodename, "compatible" and "reg" in example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../arm/mediatek/mediatek,pciesys.txt         | 25 -----------
 .../clock/mediatek,mt7622-pciesys.yaml        | 45 +++++++++++++++++++
 2 files changed, 45 insertions(+), 25 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
deleted file mode 100644
index d179a61536f4..000000000000
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-MediaTek PCIESYS controller
-============================
-
-The MediaTek PCIESYS controller provides various clocks to the system.
-
-Required Properties:
-
-- compatible: Should be:
-	- "mediatek,mt7622-pciesys", "syscon"
-	- "mediatek,mt7629-pciesys", "syscon"
-- #clock-cells: Must be 1
-- #reset-cells: Must be 1
-
-The PCIESYS controller uses the common clk binding from
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-
-Example:
-
-pciesys: pciesys at 1a100800 {
-	compatible = "mediatek,mt7622-pciesys", "syscon";
-	reg = <0 0x1a100800 0 0x1000>;
-	#clock-cells = <1>;
-	#reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml
new file mode 100644
index 000000000000..c77111d10f90
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt7622-pciesys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek PCIESYS clock and reset controller
+
+description:
+  The MediaTek PCIESYS controller provides various clocks to the system.
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7622-pciesys
+      - mediatek,mt7629-pciesys
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+    description: The available clocks are defined in dt-bindings/clock/mt*-clk.h
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 1a100800 {
+        compatible = "mediatek,mt7622-pciesys";
+        reg = <0x1a100800 0x1000>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
-- 
2.35.3



From zajec5 at gmail.com  Tue Feb 13 22:12:31 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 14 Feb 2024 07:12:31 +0100
Subject: [PATCH V4 1/3] dt-bindings: clock: mediatek: convert hifsys to the json-schema clock
In-Reply-To: <20240214061233.24645-1-zajec5@gmail.com>
References: <20240214061233.24645-1-zajec5@gmail.com>
Message-ID: <20240214061233.24645-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This helps validating DTS files. Introduced changes:
1. Documented "reg" property
2. Documented "#reset-cells" property
3. Dropped "syscon" as it was incorrectly used
4. Adjusted "compatible" and "reg" in example

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../bindings/arm/mediatek/mediatek,hifsys.txt | 26 ----------
 .../clock/mediatek,mt2701-hifsys.yaml         | 50 +++++++++++++++++++
 2 files changed, 50 insertions(+), 26 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
 create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
deleted file mode 100644
index 323905af82c3..000000000000
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Mediatek hifsys controller
-============================
-
-The Mediatek hifsys controller provides various clocks and reset
-outputs to the system.
-
-Required Properties:
-
-- compatible: Should be:
-	- "mediatek,mt2701-hifsys", "syscon"
-	- "mediatek,mt7622-hifsys", "syscon"
-	- "mediatek,mt7623-hifsys", "mediatek,mt2701-hifsys", "syscon"
-- #clock-cells: Must be 1
-
-The hifsys controller uses the common clk binding from
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-
-Example:
-
-hifsys: clock-controller at 1a000000 {
-	compatible = "mediatek,mt2701-hifsys", "syscon";
-	reg = <0 0x1a000000 0 0x1000>;
-	#clock-cells = <1>;
-	#reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
new file mode 100644
index 000000000000..9e7c725093aa
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt2701-hifsys.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mediatek,mt2701-hifsys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek HIFSYS clock and reset controller
+
+description:
+  The MediaTek HIFSYS controller provides various clocks and reset outputs to
+  the system.
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - mediatek,mt2701-hifsys
+          - mediatek,mt7622-hifsys
+      - items:
+          - enum:
+              - mediatek,mt7623-hifsys
+          - const: mediatek,mt2701-hifsys
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+    description: The available clocks are defined in dt-bindings/clock/mt*-clk.h
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - reg
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 1a000000 {
+        compatible = "mediatek,mt2701-hifsys";
+        reg = <0x1a000000 0x1000>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
-- 
2.35.3



From zajec5 at gmail.com  Tue Feb 13 22:34:40 2024
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Wed, 14 Feb 2024 07:34:40 +0100
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible for
 MT7988
In-Reply-To: <20240213-resource-evaluator-0754cfd5882d@spud>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <20240213-resource-evaluator-0754cfd5882d@spud>
Message-ID: <d4391868-ddcd-4f66-b539-28d245fa83df@gmail.com>

On 13.02.2024 19:18, Conor Dooley wrote:
> On Tue, Feb 13, 2024 at 05:46:32PM +0100, Rafa? Mi?ecki wrote:
>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>
>> MT7988 has on-SoC controller that can control up to 8 PWMs.
> 
> I see a binding and a dts patch, but no driver patch, how come?

I believe that to avoid cross-trees patchsets (which are sometimes
tricky for maintainers) there are two ways of submiting such changes:
1. dt-binding + driver; then (separately) DTS
2. dt-binding + DTS; then (separately) driver

I chose later in this case as my personal priority right now is to deal
with all MediaTek DTS files.

Is that wrong or unacceptable?


> Also, what makes this incompatibly different with the other devices in
> the binding, like the 8183?

It can control 8 PWMs unlike any other SoC block except for MT2712.
It uses different registers than MT2712 thought.


> Cheers,
> Conor.
> 
>>
>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>> ---
>>   Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml b/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
>> index 0fbe8a6469eb..a5c308801619 100644
>> --- a/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
>> +++ b/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
>> @@ -24,6 +24,7 @@ properties:
>>             - mediatek,mt7629-pwm
>>             - mediatek,mt7981-pwm
>>             - mediatek,mt7986-pwm
>> +          - mediatek,mt7988-pwm
>>             - mediatek,mt8183-pwm
>>             - mediatek,mt8365-pwm
>>             - mediatek,mt8516-pwm
>> -- 
>> 2.35.3
>>



From balakrishnan.s at microchip.com  Tue Feb 13 22:40:06 2024
From: balakrishnan.s at microchip.com (Balakrishnan Sambath)
Date: Wed, 14 Feb 2024 12:10:06 +0530
Subject: [PATCH] dt-bindings: sound:atmel-at91sam9g20ek: convert bindings
 to json-schema
Message-ID: <20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b@microchip.com>

Convert atmel-at91sam9g20ek-wm8731-audio DT binding to yaml
based json-schema.Change file name to match json-scheme naming.

Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>
---
 .../bindings/sound/atmel,at91sam9g20ek-wm8731.yaml | 60 ++++++++++++++++++++++
 .../sound/atmel-at91sam9g20ek-wm8731-audio.txt     | 26 ----------
 2 files changed, 60 insertions(+), 26 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml b/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml
new file mode 100644
index 000000000000..f6330707fe1b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/atmel,at91sam9g20ek-wm8731.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel at91sam9g20ek wm8731 audio complex
+
+maintainers:
+  - Balakrishnan Sambath <balakrishnan.s at microchip.com>
+
+properties:
+  compatible:
+    const: atmel,at91sam9g20ek-wm8731-audio
+
+  atmel,model:
+    $ref: /schemas/types.yaml#/definitions/string
+    description: The user-visible name of this sound complex.
+  atmel,audio-routing:
+    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+    description: A list of the connections between audio components.
+    minItems: 2
+    items:
+      enum:
+        # Board Connectors
+        - "Ext Spk"
+        - "Int MIC"
+
+        # CODEC Pins
+        - LHPOUT
+        - MICIN
+  atmel,ssc-controller:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of the SSC controller
+  atmel,audio-codec:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of WM8731 audio codec
+
+required:
+  - compatible
+  - atmel,model
+  - atmel,audio-routing
+  - atmel,ssc-controller
+  - atmel,audio-codec
+
+additionalProperties: false
+
+examples:
+  - |
+    sound {
+        compatible = "atmel,at91sam9g20ek-wm8731-audio";
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_pck0_as_mck>;
+        atmel,model = "wm8731 @ AT91SAMG20EK";
+        atmel,audio-routing =
+            "Ext Spk", "LHPOUT",
+            "Int MIC", "MICIN";
+        atmel,ssc-controller = <&ssc0>;
+        atmel,audio-codec = <&wm8731>;
+    };
diff --git a/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt b/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt
deleted file mode 100644
index 9c5a9947b64d..000000000000
--- a/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-* Atmel at91sam9g20ek wm8731 audio complex
-
-Required properties:
-  - compatible: "atmel,at91sam9g20ek-wm8731-audio"
-  - atmel,model: The user-visible name of this sound complex.
-  - atmel,audio-routing: A list of the connections between audio components.
-  - atmel,ssc-controller: The phandle of the SSC controller
-  - atmel,audio-codec: The phandle of the WM8731 audio codec
-Optional properties:
-  - pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt
-
-Example:
-sound {
-	compatible = "atmel,at91sam9g20ek-wm8731-audio";
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_pck0_as_mck>;
-
-	atmel,model = "wm8731 @ AT91SAMG20EK";
-
-	atmel,audio-routing =
-		"Ext Spk", "LHPOUT",
-		"Int MIC", "MICIN";
-
-	atmel,ssc-controller = <&ssc0>;
-	atmel,audio-codec = <&wm8731>;
-};

---
base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
change-id: 20240214-at91sam9g20ek-wm8731-yaml-404ddddbb91a

Best regards,
-- 
Balakrishnan Sambath <balakrishnan.s at microchip.com>



From vigneshr at ti.com  Tue Feb 13 23:28:38 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Wed, 14 Feb 2024 12:58:38 +0530
Subject: [RESEND PATCH v2 1/4] arm64: dts: ti: k3-j7200-common-proc-board:
 Modify Pinmux for wkup_uart0 and mcu_uart0
In-Reply-To: <20240212104417.1058993-2-b-kapoor@ti.com>
References: <20240212104417.1058993-1-b-kapoor@ti.com>
 <20240212104417.1058993-2-b-kapoor@ti.com>
Message-ID: <2c1da868-0295-4398-8811-6367c589df52@ti.com>



On 12/02/24 16:14, Bhavya Kapoor wrote:
> WKUP_PADCONFIG registers for wkup_uart0 and mcu_uart0 lies
> under wkup_pmx2 for J7200. Thus, modify pinmux for both
> of them.
> 
> Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
> ---


This warrants a Fixes: tag. Can you provide one here? I can fix it up
when merging.

>  .../boot/dts/ti/k3-j7200-common-proc-board.dts  | 17 +++++++++--------
>  1 file changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
> index 1d8bddcae90e..160580a0584a 100644
> --- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
> +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
> @@ -119,24 +119,25 @@ transceiver3: can-phy3 {
>  };
>  
>  &wkup_pmx0 {
> +};
> +
> +&wkup_pmx2 {
>  	mcu_uart0_pins_default: mcu-uart0-default-pins {
>  		pinctrl-single,pins = <
> -			J721E_WKUP_IOPAD(0xf4, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
> -			J721E_WKUP_IOPAD(0xf0, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
> -			J721E_WKUP_IOPAD(0xf8, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
> -			J721E_WKUP_IOPAD(0xfc, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
> +			J721E_WKUP_IOPAD(0x90, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
> +			J721E_WKUP_IOPAD(0x94, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
> +			J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
> +			J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
>  		>;
>  	};
>  
>  	wkup_uart0_pins_default: wkup-uart0-default-pins {
>  		pinctrl-single,pins = <
> -			J721E_WKUP_IOPAD(0xb0, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
> -			J721E_WKUP_IOPAD(0xb4, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
> +			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
> +			J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
>  		>;
>  	};
> -};
>  
> -&wkup_pmx2 {
>  	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
>  		pinctrl-single,pins = <
>  			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */

-- 
Regards
Vignesh


From duoming at zju.edu.cn  Tue Feb 13 23:33:18 2024
From: duoming at zju.edu.cn (Duoming Zhou)
Date: Wed, 14 Feb 2024 15:33:18 +0800
Subject: [PATCH] clk: zynq: Prevent null pointer dereference caused by kmalloc failure
Message-ID: <20240214073318.82573-1-duoming@zju.edu.cn>

The kmalloc in zynq_clk_setup will return null if the
physical memory has run out. As a result, if we use
snprintf to write data to the null address, the null
pointer dereference bug will happen.

The required memory is only 11 bytes, so this patch
adds a "__GFP_NOFAIL" flag in kmalloc in order that
the kmalloc will never return with failure.

Fixes: 0ee52b157b8e ("clk: zynq: Add clock controller driver")
Signed-off-by: Duoming Zhou <duoming at zju.edu.cn>
---
 drivers/clk/zynq/clkc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
index 7bdeaff2bfd..7621c2f0046 100644
--- a/drivers/clk/zynq/clkc.c
+++ b/drivers/clk/zynq/clkc.c
@@ -427,7 +427,7 @@ static void __init zynq_clk_setup(struct device_node *np)
 			SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock);
 
 	tmp = strlen("mio_clk_00x");
-	clk_name = kmalloc(tmp, GFP_KERNEL);
+	clk_name = kmalloc(tmp, GFP_KERNEL | __GFP_NOFAIL);
 	for (i = 0; i < NUM_MIO_PINS; i++) {
 		int idx;
 
-- 
2.17.1



From vaishnav.a at ti.com  Tue Feb 13 23:43:44 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Wed, 14 Feb 2024 13:13:44 +0530
Subject: [PATCH v2 3/3] arm64: dts: ti: Add support for TI J722S
 Evaluation Module
In-Reply-To: <CZ386ITQ83KH.1KNOV5MXLXPBF@kernel.org>
References: <20240206100608.127702-1-vaishnav.a@ti.com>
 <20240206100608.127702-4-vaishnav.a@ti.com>
 <CZ386ITQ83KH.1KNOV5MXLXPBF@kernel.org>
Message-ID: <45bd5618-2e22-4715-9724-92f1d4b84608@ti.com>

Hi Michael,

On 12/02/24 21:32, Michael Walle wrote:
> Hi,
> 
> On Tue Feb 6, 2024 at 11:06 AM CET, Vaishnav Achath wrote:
>> +# Boards with J722s SoC
>> +dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb
> 
> I'm a bit confused by your names. What are the new/correct ones now?
> Some seem to use the amXX names and some the jXX ones. I've read [1]
> and it appears it was suggested to use the am67 names for the device
> trees. Esp. because there is already, am62, am64, am65, am68 and
> am69 in as names for the device trees.
> 
> The TRM you've linked in the cover letter doesn't shed much light
> either. It just lists both.
> 

Both names are correct, for other Jacinto devices J721S2 and J784S4, the 
industrial variants (AM68, AM69 respectively) and those boards were 
announced at a later point of time and since the automotive/J7 variants 
were introduced first, the SoC dtsi and files have the J7XX names, for 
AM62/AM64 there is no confusion in naming, in this case the initial TRM 
itself mentions J722S and AM67 variants with similar capabilities, the 
reasoning behind continuing with the J722S name is because the initial 
support is being added for J722S EVM (the top marking on the SoC package 
populated on the EVM say XJ722SAMW, this can be seen in the schematics 
also), please let know if this clarifies the confusion.

Thanks and Regards,
Vaishnav

> -michael
> 
> [1] https://lore.kernel.org/all/81f90d13-da10-4a68-a0e7-95212f40b3e8 at ti.com/


From mihai.sain at microchip.com  Wed Feb 14 00:03:45 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Wed, 14 Feb 2024 10:03:45 +0200
Subject: [PATCH v2 0/3] Add initial support for Microchip SAMA7G54 Curiosity board
Message-ID: <20240214080348.7540-1-mihai.sain@microchip.com>

This patch series adds initial support for Microchip SAMA7G54 Curiosity board.

Changes in v2:
--------------

* Remove bootargs.
* Use phandle style for clock nodes.
* Use color and function for gpio-leds.
* Remove status okay from leds, nand, eeprom, pmic, flash.
* Use generic name like pmic for mcp16502 regulator.

Mihai Sain (3):
  dt-bindings: ARM: at91: Document Microchip SAMA7G54 Curiosity
  ARM: dts: microchip: sama7g5: Add flexcom 10 node
  ARM: dts: microchip: sama7g54_curiosity: Add initial device tree of the board

 .../devicetree/bindings/arm/atmel-at91.yaml   |   6 +
 arch/arm/boot/dts/microchip/Makefile          |   4 +-
 .../dts/microchip/at91-sama7g54_curiosity.dts | 487 ++++++++++++++++++
 arch/arm/boot/dts/microchip/sama7g5.dtsi      |  26 +
 4 files changed, 522 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts

-- 
2.43.0



From mihai.sain at microchip.com  Wed Feb 14 00:03:46 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Wed, 14 Feb 2024 10:03:46 +0200
Subject: [PATCH v2 1/3] dt-bindings: ARM: at91: Document Microchip SAMA7G54 Curiosity
In-Reply-To: <20240214080348.7540-1-mihai.sain@microchip.com>
References: <20240214080348.7540-1-mihai.sain@microchip.com>
Message-ID: <20240214080348.7540-2-mihai.sain@microchip.com>

Document device tree binding of the Microchip SAMA7G54 Curiosity board.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index 89d75fbb1de4..82f37328cc69 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -179,6 +179,12 @@ properties:
           - const: microchip,sama7g5
           - const: microchip,sama7
 
+      - description: Microchip SAMA7G54 Curiosity Board
+        items:
+          - const: microchip,sama7g54-curiosity
+          - const: microchip,sama7g5
+          - const: microchip,sama7
+
       - description: Microchip LAN9662 Evaluation Boards.
         items:
           - enum:
-- 
2.43.0



From mihai.sain at microchip.com  Wed Feb 14 00:03:47 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Wed, 14 Feb 2024 10:03:47 +0200
Subject: [PATCH v2 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <20240214080348.7540-1-mihai.sain@microchip.com>
References: <20240214080348.7540-1-mihai.sain@microchip.com>
Message-ID: <20240214080348.7540-3-mihai.sain@microchip.com>

Add flexcom 10 node for usage on the SAMA7G54 Curiosity board.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/sama7g5.dtsi | 26 ++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
index 269e0a3ca269..c90e404e8ed9 100644
--- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
+++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
@@ -958,6 +958,32 @@ i2c9: i2c at 600 {
 			};
 		};
 
+		flx10: flexcom at e2820000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe2820000 0x200>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe2820000 0x800>;
+			status = "disabled";
+
+			i2c10: i2c at 600 {
+				compatible = "microchip,sama7g5-i2c", "microchip,sam9x60-i2c";
+				reg = <0x600 0x200>;
+				interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
+				atmel,fifo-size = <32>;
+				dmas = <&dma0 AT91_XDMAC_DT_PERID(25)>,
+					<&dma0 AT91_XDMAC_DT_PERID(26)>;
+				dma-names = "rx", "tx";
+				atmel,use-dma-rx;
+				atmel,use-dma-tx;
+				status = "disabled";
+			};
+		};
+
 		flx11: flexcom at e2824000 {
 			compatible = "atmel,sama5d2-flexcom";
 			reg = <0xe2824000 0x200>;
-- 
2.43.0



From mihai.sain at microchip.com  Wed Feb 14 00:03:48 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Wed, 14 Feb 2024 10:03:48 +0200
Subject: [PATCH v2 3/3] ARM: dts: microchip: sama7g54_curiosity: Add initial device tree of the board
In-Reply-To: <20240214080348.7540-1-mihai.sain@microchip.com>
References: <20240214080348.7540-1-mihai.sain@microchip.com>
Message-ID: <20240214080348.7540-4-mihai.sain@microchip.com>

Add initial device tree of the SAMA7G54 Curiosity board.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/Makefile          |   4 +-
 .../dts/microchip/at91-sama7g54_curiosity.dts | 487 ++++++++++++++++++
 2 files changed, 490 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts

diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
index efde9546c8f4..29b2a788748f 100644
--- a/arch/arm/boot/dts/microchip/Makefile
+++ b/arch/arm/boot/dts/microchip/Makefile
@@ -12,6 +12,7 @@ DTC_FLAGS_at91-sama5d3_eds := -@
 DTC_FLAGS_at91-sama5d3_xplained := -@
 DTC_FLAGS_at91-sama5d4_xplained := -@
 DTC_FLAGS_at91-sama7g5ek := -@
+DTC_FLAGS_at91-sama7g54_curiosity := -@
 dtb-$(CONFIG_SOC_AT91RM9200) += \
 	at91rm9200ek.dtb \
 	mpa1600.dtb
@@ -87,7 +88,8 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
 	at91-sama5d4ek.dtb \
 	at91-vinco.dtb
 dtb-$(CONFIG_SOC_SAMA7G5) += \
-	at91-sama7g5ek.dtb
+	at91-sama7g5ek.dtb \
+	at91-sama7g54_curiosity.dtb
 
 dtb-$(CONFIG_SOC_LAN966) += \
 	lan966x-kontron-kswitch-d10-mmt-6g-2gs.dtb \
diff --git a/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
new file mode 100644
index 000000000000..a6504c3781f4
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
@@ -0,0 +1,487 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sama7g54_curiosity.dts - Device Tree file for SAMA7G54 Curiosity Board
+ *
+ * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Mihai Sain <mihai.sain at microchip.com>
+ *
+ */
+/dts-v1/;
+#include "sama7g5-pinfunc.h"
+#include "sama7g5.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/pinctrl/at91.h>
+
+/ {
+	model = "Microchip SAMA7G54 Curiosity";
+	compatible = "microchip,sama7g54-curiosity", "microchip,sama7g5", "microchip,sama7";
+
+	aliases {
+		serial0 = &uart3;
+		i2c0 = &i2c10;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_key_gpio_default>;
+
+		button-user {
+			label = "user-button";
+			gpios = <&pioA PIN_PD19 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_PROG1>;
+			wakeup-source;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_led_gpio_default>;
+
+		led-red {
+			color = <LED_COLOR_ID_RED>;
+			function = LED_FUNCTION_POWER;
+			gpios = <&pioA PIN_PD13 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		led-green {
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_BOOT;
+			gpios = <&pioA PIN_PD14 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		led-blue {
+			color = <LED_COLOR_ID_BLUE>;
+			function = LED_FUNCTION_CPU;
+			gpios = <&pioA PIN_PB15 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x10000000>; // 256 MiB DDR3L-1066 16-bit
+	};
+};
+
+&adc {
+	vddana-supply = <&vddout25>;
+	vref-supply = <&vddout25>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_mikrobus1_an_default &pinctrl_mikrobus2_an_default>;
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vddcpu>;
+};
+
+&dma0 {
+	status = "okay";
+};
+
+&dma1 {
+	status = "okay";
+};
+
+&dma2 {
+	status = "okay";
+};
+
+&ebi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_nand_default>;
+	status = "okay";
+
+	nand_controller: nand-controller {
+		status = "okay";
+
+		nand at 3 {
+			reg = <0x3 0x0 0x800000>;
+			atmel,rb = <0>;
+			nand-bus-width = <8>;
+			nand-ecc-mode = "hw";
+			nand-ecc-strength = <8>;
+			nand-ecc-step-size = <512>;
+			nand-on-flash-bbt;
+			label = "nand";
+
+			partitions {
+				compatible = "fixed-partitions";
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				at91bootstrap at 0 {
+					label = "nand: at91bootstrap";
+					reg = <0x0 0x40000>;
+				};
+
+				bootloader at 40000 {
+					label = "nand: u-boot";
+					reg = <0x40000 0x100000>;
+				};
+
+				bootloaderenv at 140000 {
+					label = "nand: u-boot env";
+					reg = <0x140000 0x40000>;
+				};
+
+				dtb at 180000 {
+					label = "nand: device tree";
+					reg = <0x180000 0x80000>;
+				};
+
+				kernel at 200000 {
+					label = "nand: kernel";
+					reg = <0x200000 0x600000>;
+				};
+
+				rootfs at 800000 {
+					label = "nand: rootfs";
+					reg = <0x800000 0x1f800000>;
+				};
+			};
+		};
+	};
+};
+
+&flx3 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+	status = "okay";
+
+	uart3: serial at 200 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flx3_default>;
+		status = "okay";
+	};
+};
+
+&flx10 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
+	status = "okay";
+
+	i2c10: i2c at 600 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flx10_default>;
+		i2c-analog-filter;
+		i2c-digital-filter;
+		i2c-digital-filter-width-ns = <35>;
+		status = "okay";
+
+		adc at 1f {
+			compatible = "microchip,pac1934";
+			reg = <0x1f>;
+		};
+
+		eeprom at 51 {
+			compatible = "atmel,24c02";
+			reg = <0x51>;
+			pagesize = <16>;
+			size = <256>;
+			vcc-supply = <&vdd_3v3>;
+		};
+
+		pmic at 5b {
+			compatible = "microchip,mcp16502";
+			reg = <0x5b>;
+
+			regulators {
+				vdd_3v3: VDD_IO {
+					regulator-name = "VDD_IO";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-microvolt = <3300000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+						regulator-mode = <4>;
+					};
+				};
+
+				vddioddr: VDD_DDR {
+					regulator-name = "VDD_DDR";
+					regulator-min-microvolt = <1350000>;
+					regulator-max-microvolt = <1350000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-microvolt = <1350000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-on-in-suspend;
+						regulator-suspend-microvolt = <1350000>;
+						regulator-mode = <4>;
+					};
+				};
+
+				vddcore: VDD_CORE {
+					regulator-name = "VDD_CORE";
+					regulator-min-microvolt = <1150000>;
+					regulator-max-microvolt = <1150000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-voltage = <1150000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+						regulator-mode = <4>;
+					};
+				};
+
+				vddcpu: VDD_OTHER {
+					regulator-name = "VDD_OTHER";
+					regulator-min-microvolt = <1050000>;
+					regulator-max-microvolt = <1250000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-ramp-delay = <3125>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-voltage = <1050000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+						regulator-mode = <4>;
+					};
+				};
+
+				vldo1: LDO1 {
+					regulator-name = "LDO1";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-suspend-voltage = <1800000>;
+						regulator-on-in-suspend;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+					};
+				};
+
+				vldo2: LDO2 {
+					regulator-name = "LDO2";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-suspend-voltage = <3300000>;
+						regulator-on-in-suspend;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+					};
+				};
+			};
+		};
+	};
+};
+
+&main_xtal {
+	clock-frequency = <24000000>;
+};
+
+&qspi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi1_default>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-max-frequency = <100000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+		m25p,fast-read;
+	};
+};
+
+&pioA {
+	pinctrl_flx3_default: flx3-default {
+		pinmux = <PIN_PD16__FLEXCOM3_IO0>,
+			 <PIN_PD17__FLEXCOM3_IO1>;
+		bias-pull-up;
+	};
+
+	pinctrl_flx10_default: flx10-default {
+		pinmux = <PIN_PC30__FLEXCOM10_IO0>,
+			 <PIN_PC31__FLEXCOM10_IO1>;
+		bias-pull-up;
+	};
+
+	pinctrl_key_gpio_default: key-gpio-default {
+		pinmux = <PIN_PD19__GPIO>;
+		bias-pull-up;
+	};
+
+	pinctrl_led_gpio_default: led-gpio-default {
+		pinmux = <PIN_PD13__GPIO>,
+			 <PIN_PD14__GPIO>,
+			 <PIN_PB15__GPIO>;
+		bias-pull-up;
+	};
+
+	pinctrl_mikrobus1_an_default: mikrobus1-an-default {
+		pinmux = <PIN_PC15__GPIO>;
+		bias-disable;
+	};
+
+	pinctrl_mikrobus2_an_default: mikrobus2-an-default {
+		pinmux = <PIN_PC13__GPIO>;
+		bias-disable;
+	};
+
+	pinctrl_nand_default: nand-default {
+		pinmux = <PIN_PD9__D0>,
+			 <PIN_PD10__D1>,
+			 <PIN_PD11__D2>,
+			 <PIN_PC21__D3>,
+			 <PIN_PC22__D4>,
+			 <PIN_PC23__D5>,
+			 <PIN_PC24__D6>,
+			 <PIN_PD2__D7>,
+			 <PIN_PD3__NANDRDY>,
+			 <PIN_PD4__NCS3_NANDCS>,
+			 <PIN_PD5__NWE_NWR0_NANDWE>,
+			 <PIN_PD6__NRD_NANDOE>,
+			 <PIN_PD7__A21_NANDALE>,
+			 <PIN_PD8__A22_NANDCLE>;
+		bias-disable;
+		slew-rate = <0>;
+	};
+
+	pinctrl_qspi1_default: qspi1-default {
+		pinmux = <PIN_PB22__QSPI1_IO3>,
+			 <PIN_PB23__QSPI1_IO2>,
+			 <PIN_PB24__QSPI1_IO1>,
+			 <PIN_PB25__QSPI1_IO0>,
+			 <PIN_PB26__QSPI1_CS>,
+			 <PIN_PB27__QSPI1_SCK>;
+		bias-pull-up;
+		slew-rate = <0>;
+	};
+
+	pinctrl_sdmmc0_default: sdmmc0-default {
+		pinmux = <PIN_PA0__SDMMC0_CK>,
+			 <PIN_PA1__SDMMC0_CMD>,
+			 <PIN_PA2__SDMMC0_RSTN>,
+			 <PIN_PA3__SDMMC0_DAT0>,
+			 <PIN_PA4__SDMMC0_DAT1>,
+			 <PIN_PA5__SDMMC0_DAT2>,
+			 <PIN_PA6__SDMMC0_DAT3>;
+		bias-pull-up;
+		slew-rate = <0>;
+	};
+
+	pinctrl_sdmmc1_default: sdmmc1-default {
+		pinmux = <PIN_PB29__SDMMC1_CMD>,
+			 <PIN_PB30__SDMMC1_CK>,
+			 <PIN_PB31__SDMMC1_DAT0>,
+			 <PIN_PC0__SDMMC1_DAT1>,
+			 <PIN_PC1__SDMMC1_DAT2>,
+			 <PIN_PC2__SDMMC1_DAT3>,
+			 <PIN_PC4__SDMMC1_CD>;
+		bias-pull-up;
+		slew-rate = <0>;
+	};
+};
+
+&rtt {
+	atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
+};
+
+// M.2 slot for wireless card
+&sdmmc0 {
+	bus-width = <4>;
+	cd-gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	sdhci-caps-mask = <0x0 0x00200000>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc0_default>;
+	status = "okay";
+};
+
+// micro SD socket
+&sdmmc1 {
+	bus-width = <4>;
+	disable-wp;
+	sdhci-caps-mask = <0x0 0x00200000>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc1_default>;
+	status = "okay";
+};
+
+&slow_xtal {
+	clock-frequency = <32768>;
+};
+
+&shdwc {
+	debounce-delay-us = <976>;
+	status = "okay";
+
+	input at 0 {
+		reg = <0>;
+	};
+};
+
+&tcb0 {
+	timer0: timer at 0 {
+		compatible = "atmel,tcb-timer";
+		reg = <0>;
+	};
+
+	timer1: timer at 1 {
+		compatible = "atmel,tcb-timer";
+		reg = <1>;
+	};
+};
+
+&trng {
+	status = "okay";
+};
+
+&vddout25 {
+	vin-supply = <&vdd_3v3>;
+	status = "okay";
+};
-- 
2.43.0



From horatiu.vultur at microchip.com  Wed Feb 14 00:14:42 2024
From: horatiu.vultur at microchip.com (Horatiu Vultur)
Date: Wed, 14 Feb 2024 09:14:42 +0100
Subject: [PATCH net-next] net: sparx5: Add spinlock for frame
 transmission from CPU
In-Reply-To: <5476743f-3648-4038-97f8-a9df22c0f507@gmail.com>
References: <20240213121705.4070598-1-horatiu.vultur@microchip.com>
 <5476743f-3648-4038-97f8-a9df22c0f507@gmail.com>
Message-ID: <20240214081442.w533wvcvqpvq5352@DEN-DL-M31836.microchip.com>

The 02/13/2024 09:26, Florian Fainelli wrote:
> 
> On 2/13/24 04:17, Horatiu Vultur wrote:
> > Both registers used when doing manual injection or fdma injection are
> > shared between all the net devices of the switch. It was noticed that
> > when having two process which each of them trying to inject frames on
> > different ethernet ports, that the HW started to behave strange, by
> > sending out more frames then expected. When doing fdma injection it is
> > required to set the frame in the DCB and then make sure that the next
> > pointer of the last DCB is invalid. But because there is no locks for
> > this, then easily this pointer between the DCB can be broken and then it
> > would create a loop of DCBs. And that means that the HW will
> > continuously transmit these frames in a loop. Until the SW will break
> > this loop.
> > Therefore to fix this issue, add a spin lock for when accessing the
> > registers for manual or fdma injection.
> > 
> > Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>
> 
> Any reason you targeted 'net-next' rather than 'net', as this appears to
> be clearly a bug fix here?

Yes, it is a bug but it is not something that happens all the
time and I thought this fits more into the lines of 'This could be a
problem ...' therefore I had targeted 'net-next'.
But if you consider that I should target 'net' instead of 'net-next' I
can do that.

> --
> Florian
> 

-- 
/Horatiu


From geert at linux-m68k.org  Wed Feb 14 00:35:38 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 09:35:38 +0100
Subject: [PATCH v2 00/15] arm64: renesas: Add R-Car V4M and Gray Hawk
 Single support
In-Reply-To: <CAMuHMdUswhJ3BQLnOQZC7X7qc7SFCqsr9Uy65LfBT_BNWfyhFQ@mail.gmail.com>
References: <cover.1706194617.git.geert+renesas@glider.be> <CAPDyKFpxaEUHvKKb+spxV6HG2P2gLx5qM1mLPxJie+PdkmTL4w@mail.gmail.com>
 <CAMuHMdUswhJ3BQLnOQZC7X7qc7SFCqsr9Uy65LfBT_BNWfyhFQ@mail.gmail.com>
Message-ID: <CAMuHMdX1tjgPJ8t+XoASuMvzvSognu7q2=aGfBO8r77JsbR82w@mail.gmail.com>

Hi Ulf,

On Wed, Jan 31, 2024 at 3:56?PM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> On Tue, Jan 30, 2024 at 2:11?PM Ulf Hansson <ulf.hansson at linaro.org> wrote:
> > On Thu, 25 Jan 2024 at 16:34, Geert Uytterhoeven
> > <geert+renesas at glider.be> wrote:
> > > This patch series adds initial support for the Renesas R-Car V4M
> > > (R8A779G0) SoC and the Renesas Gray Hawk Single development board.
> > >
> > > As both driver code and DTS have hard dependencies on DT binding
> > > definitions, most patches in this series are supposed to go in through
> > > the renesas-devel and/or renesas-clk trees, using a shared branch for DT
> > > binding definitions, as usual.  For the PM domain patches (03, 04, 09),
> > > Ulf already offered to apply these to his pmdomain tree, and provide an
> > > immutable "dt" branch, to be pulled in my renesas-devel tree.
> >
> > Patch 3,4 and 9 (I dropped the copyright line in patch9, as pointed
> > out by Niklas) applied for next, thanks!
> >
> > Patch 3,4 are also available at the immutable dt branch for you to pull in.
>
> Thank you!
>
> I have pulled the immutable branch, added the remaining DT binding
> definitions, and queued all remaining patches.

It looks like you have applied copies of all commits on the "dt"
branch to the "next"
branch, so now there are two copies?

See the output of "git range-diff v6.8-rc1..pmdomain/dt
v6.8-rc4..pmdomain/next".

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  Wed Feb 14 01:03:26 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 14 Feb 2024 10:03:26 +0100
Subject: [PATCH v2 2/2] arm64: dts: mediatek: mt8186: Add missing xhci
 clock to usb controllers
In-Reply-To: <20240213-mt8186-ssusb-domain-clk-fix-v2-2-1f981d35f3fd@collabora.com>
References: <20240213-mt8186-ssusb-domain-clk-fix-v2-0-1f981d35f3fd@collabora.com>
 <20240213-mt8186-ssusb-domain-clk-fix-v2-2-1f981d35f3fd@collabora.com>
Message-ID: <6fea6cd3-031b-4d5a-8bba-f01f6afa12b3@collabora.com>

Il 13/02/24 16:02, N?colas F. R. A. Prado ha scritto:
> The mtu3 usb controllers don't list the xhci clock, though they require
> it, and thus rely on the bootloader leaving it on in order to work.
> 
> When booting with the upstream arm64 defconfig, the usb controllers will
> defer probe until modules have loaded since they have an indirect
> dependency on CONFIG_MTK_CMDQ, which is configured as a module. However
> at the point where modules are loaded, unused clocks are also disabled,
> causing the usb controllers to probe without the xhci clock enabled and
> fail to probe:
> 
> mtu3 11201000.usb: clks of sts1 are not stable!
> mtu3 11201000.usb: device enable failed -110
> mtu3 11201000.usb: mtu3 hw init failed:-110
> mtu3 11201000.usb: failed to initialize gadget
> mtu3: probe of 11201000.usb failed with error -110
> 
> (and same for the one at 11281000)
> 
> Add the missing clock for the usb controllers so that they can
> successfully probe without relying on the bootloader state.
> 
> Fixes: f6c3e61c5486 ("arm64: dts: mediatek: mt8186: Add MTU3 nodes")
> Signed-off-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  Wed Feb 14 01:03:28 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 14 Feb 2024 10:03:28 +0100
Subject: [PATCH v2 1/2] arm64: dts: mediatek: mt8186: Add missing clocks
 to ssusb power domains
In-Reply-To: <20240213-mt8186-ssusb-domain-clk-fix-v2-1-1f981d35f3fd@collabora.com>
References: <20240213-mt8186-ssusb-domain-clk-fix-v2-0-1f981d35f3fd@collabora.com>
 <20240213-mt8186-ssusb-domain-clk-fix-v2-1-1f981d35f3fd@collabora.com>
Message-ID: <c8878258-9f3b-4e2f-a022-3bd43bcfd02e@collabora.com>

Il 13/02/24 16:02, N?colas F. R. A. Prado ha scritto:
> The ssusb power domains currently don't list any clocks, despite
> depending on some, and thus rely on the bootloader leaving the required
> clocks on in order to work.
> 
> When booting with the upstream arm64 defconfig, the power domain
> controller will defer probe until modules have loaded since it has an
> indirect dependency on CONFIG_MTK_CMDQ, which is configured as a module.
> However at the point where modules are loaded, unused clocks are also
> disabled, causing the ssusb domains to fail to be enabled and
> consequently the controller to fail probe:
> 
> mtk-power-controller 10006000.syscon:power-controller: /soc/syscon at 10006000/power-controller/power-domain at 4: failed to power on domain: -110
> mtk-power-controller: probe of 10006000.syscon:power-controller failed with error -110
> 
> Add the missing clocks for the ssusb power domains so that they can
> successfully probe without relying on the bootloader state.
> 
> Fixes: d9e43c1e7a38 ("arm64: dts: mt8186: Add power domains controller")
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From michal.vokac at ysoft.com  Wed Feb 14 01:03:28 2024
From: michal.vokac at ysoft.com (=?UTF-8?q?Michal=20Vok=C3=A1=C4=8D?=)
Date: Wed, 14 Feb 2024 10:03:28 +0100
Subject: [PATCH v2 2/2] ARM: dts: imx6dl-yapp4: Move the internal switch PHYs under the switch node
In-Reply-To: <1707901408-17084-1-git-send-email-michal.vokac@ysoft.com>
References: <1707901408-17084-1-git-send-email-michal.vokac@ysoft.com>
Message-ID: <1707901408-17084-2-git-send-email-michal.vokac@ysoft.com>

We identified that the PHYs actually do not work since commit 7da7b84fee58
("ARM: dts: imx6dl-yapp4: Move phy reset into switch node") as
a coincidence of several circumstances.

The reset signal is kept asserted by a pull-down resistor on the board
unless it is deasserted by GPIO from the SoC. This is to keep the switch
dead until it is configured properly by the kernel and user space.

Prior to the referenced commit the switch was reset by the FEC driver
and the reset GPIO was actively deasserted. The mdio-bus was scanned
and the attached switch and its PHYs were found and configured.

With the referenced commit the switch is reset by the qca8k driver.
Because of another bug in the qca8k driver, functionality of the reset
pin depends on its pre-kernel configuration. See commit c44fc98f0a8f
("net: dsa: qca8k: fix illegal usage of GPIO")

The problem did not appear until we removed support for the switch
and configuration of its reset pin from the bootloader.

To fix that, properly describe the internal mdio-bus configuration of
the qca8334 switch. The PHYs are internal to the switch and sit on its
internal mdio-bus.

Fixes: 7da7b84fee58 ("ARM: dts: imx6dl-yapp4: Move phy reset into switch node")
Signed-off-by: Michal Vok?? <michal.vokac at ysoft.com>
---
changes in v2:
- none

 arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi | 23 ++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
index 5763f8253d51..eec1f9092572 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
@@ -133,14 +133,6 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		phy_port2: phy at 1 {
-			reg = <1>;
-		};
-
-		phy_port3: phy at 2 {
-			reg = <2>;
-		};
-
 		switch at 10 {
 			compatible = "qca,qca8334";
 			reg = <0x10>;
@@ -165,15 +157,30 @@
 				eth2: port at 2 {
 					reg = <2>;
 					label = "eth2";
+					phy-mode = "internal";
 					phy-handle = <&phy_port2>;
 				};
 
 				eth1: port at 3 {
 					reg = <3>;
 					label = "eth1";
+					phy-mode = "internal";
 					phy-handle = <&phy_port3>;
 				};
 			};
+
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				phy_port2: ethernet-phy at 1 {
+					reg = <1>;
+				};
+
+				phy_port3: ethernet-phy at 2 {
+					reg = <2>;
+				};
+			};
 		};
 	};
 };
-- 
2.1.4



From michal.vokac at ysoft.com  Wed Feb 14 01:03:27 2024
From: michal.vokac at ysoft.com (=?UTF-8?q?Michal=20Vok=C3=A1=C4=8D?=)
Date: Wed, 14 Feb 2024 10:03:27 +0100
Subject: [PATCH v2 1/2] ARM: dts: imx6dl-yapp4: Fix typo in the QCA switch register address
Message-ID: <1707901408-17084-1-git-send-email-michal.vokac@ysoft.com>

This change does not have any functional effect. The switch works just
fine without this patch as it has full access to all the addresses
on the bus. This is simply a clean-up to set the node name address
and reg address to the same value.

Fixes: 15b43e497ffd ("ARM: dts: imx6dl-yapp4: Use correct pseudo PHY address for the switch")
Signed-off-by: Michal Vok?? <michal.vokac at ysoft.com>
---
changes in v2:
- Reword the commit message so it is clear that this patch does not
  fix a functional problem.

 arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
index cfb0fc924b42..5763f8253d51 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
@@ -143,7 +143,7 @@
 
 		switch at 10 {
 			compatible = "qca,qca8334";
-			reg = <10>;
+			reg = <0x10>;
 			reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
 
 			switch_ports: ports {
-- 
2.1.4



From krzysztof.kozlowski at linaro.org  Wed Feb 14 01:05:47 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 14 Feb 2024 10:05:47 +0100
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible for
 MT7988
In-Reply-To: <onnokyq7ciza7i7jzc74cun2khpst5iocuccks2cm433ux3za3@dou4oacrvuxj>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <onnokyq7ciza7i7jzc74cun2khpst5iocuccks2cm433ux3za3@dou4oacrvuxj>
Message-ID: <2dac95be-b23a-4c42-ac67-241100c7a51b@linaro.org>

On 13/02/2024 18:48, Uwe Kleine-K?nig wrote:
> Hello Rafa?,
> 
> On Tue, Feb 13, 2024 at 05:46:32PM +0100, Rafa? Mi?ecki wrote:
>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>
>> MT7988 has on-SoC controller that can control up to 8 PWMs.
>>
>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> please make sure that the email address used for sending the patch
> matches the Signed-off-by line.
> 
> (It depends on the pickyness of the relevant maintainer if that is a
> stopper or not.)

Does not have to... It must match From field which is correct here.
Syntax like:

From: Foo <foo at com>
Signed-off-by: Foo <foo at com>
Signed-off-by: Foo <my-other-email-foo at com>

makes sense only if copyrights change (e.g. change of employers) and/or
one email stop working. How would be the point of having to SoBs for the
same person in other cases?

Best regards,
Krzysztof



From angelogioacchino.delregno at collabora.com  Wed Feb 14 01:09:58 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 14 Feb 2024 10:09:58 +0100
Subject: [PATCH 2/2] arm64: dts: mediatek: mt7988: add PWM controller
In-Reply-To: <20240213164633.25447-2-zajec5@gmail.com>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <20240213164633.25447-2-zajec5@gmail.com>
Message-ID: <36baacb4-4aa9-421f-bde0-c4be7d7f4aa1@collabora.com>

Il 13/02/24 17:46, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Add binding for on-SoC controller that can control up to 8 PWMs.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>   arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 21 ++++++++++++++++++++-
>   1 file changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> index bba97de4fb44..67007626b5cd 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
> @@ -1,5 +1,6 @@
>   // SPDX-License-Identifier: GPL-2.0-only OR MIT
>   
> +#include <dt-bindings/clock/mediatek,mt7988-clk.h>
>   #include <dt-bindings/interrupt-controller/arm-gic.h>
>   
>   / {
> @@ -78,7 +79,7 @@ gic: interrupt-controller at c000000 {
>   			#interrupt-cells = <3>;
>   		};
>   
> -		clock-controller at 10001000 {
> +		infracfg: clock-controller at 10001000 {
>   			compatible = "mediatek,mt7988-infracfg", "syscon";
>   			reg = <0 0x10001000 0 0x1000>;
>   			#clock-cells = <1>;
> @@ -103,6 +104,24 @@ clock-controller at 1001e000 {
>   			#clock-cells = <1>;
>   		};
>   
> +		pwm at 10048000 {
> +			compatible = "mediatek,mt7988-pwm";

I can't take this unless there's a driver that supports your device.

Regards,
Angelo

> +			reg = <0 0x10048000 0 0x1000>;
> +			clocks = <&infracfg CLK_INFRA_66M_PWM_BCK>,
> +				 <&infracfg CLK_INFRA_66M_PWM_HCK>,
> +				 <&infracfg CLK_INFRA_66M_PWM_CK1>,
> +				 <&infracfg CLK_INFRA_66M_PWM_CK2>,
> +				 <&infracfg CLK_INFRA_66M_PWM_CK3>,
> +				 <&infracfg CLK_INFRA_66M_PWM_CK4>,
> +				 <&infracfg CLK_INFRA_66M_PWM_CK5>,
> +				 <&infracfg CLK_INFRA_66M_PWM_CK6>,
> +				 <&infracfg CLK_INFRA_66M_PWM_CK7>,
> +				 <&infracfg CLK_INFRA_66M_PWM_CK8>;
> +			clock-names = "top", "main", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6",
> +				      "pwm7","pwm8";
> +			#pwm-cells = <2>;
> +		};
> +
>   		clock-controller at 11f40000 {
>   			compatible = "mediatek,mt7988-xfi-pll";
>   			reg = <0 0x11f40000 0 0x1000>;




From angelogioacchino.delregno at collabora.com  Wed Feb 14 01:19:12 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 14 Feb 2024 10:19:12 +0100
Subject: [PATCH] arm64: dts: mediatek: replace underscores in node names
In-Reply-To: <20240213144626.341463-1-krzysztof.kozlowski@linaro.org>
References: <20240213144626.341463-1-krzysztof.kozlowski@linaro.org>
Message-ID: <170790234013.477427.13548425234687450683.b4-ty@collabora.com>

On Tue, 13 Feb 2024 15:46:26 +0100, Krzysztof Kozlowski wrote:
> Underscores should not be used in node names (dtc with W=2 warns about
> them), so replace them with hyphens.
> 
> 

Applied to v6.8-next/dts64, thanks!

[1/1] arm64: dts: mediatek: replace underscores in node names
      https://git.kernel.org/mediatek/c/e630c7b0

Cheers,
Angelo



From quic_kathirav at quicinc.com  Wed Feb 14 01:19:41 2024
From: quic_kathirav at quicinc.com (Kathiravan Thirumoorthy)
Date: Wed, 14 Feb 2024 14:49:41 +0530
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com>
 <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
Message-ID: <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>



On 1/26/2024 1:35 AM, Andrew Lunn wrote:
> On Mon, Jan 22, 2024 at 11:26:58AM +0530, Kathiravan Thirumoorthy wrote:
>> gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk are
>> enabled by default and it's RCG is properly configured by bootloader.
> 
> Which bootloader? Mainline barebox?


Thanks for taking time to review the patches. I couldn't get time to 
respond back, sorry for the delay.

I was referring to the U-boot which is delivered as part of the QSDK. I 
will call it out explicitly in the next patch.

> 
>> Some of the NSS clocks needs these clocks to be enabled. To avoid
>> these clocks being disabled by clock framework, drop these entries
>> from the clock table and enable it in the driver probe itself.
> 
> If they are critical clocks, i would expect a device to reference
> them. The CCF only disabled unused clocks in late_initcall_sync(),
> which means all drivers should of probed and taken a reference on any
> clocks they require.


Some of the NSSCC clocks are enabled by bootloaders and CCF disables the 
same (because currently there are no consumers for these clocks 
available in the tree. These clocks are consumed by the Networking 
drivers which are being upstreamed). To access the NSSCC clocks, 
gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk clocks 
needs to be enabled, else system is going to reboot. To prevent this, I 
enabled it in probe.

However looking back, gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, 
gcc_nssnoc_nsscc_clk are consumed by the networking drivers only. So is 
it okay to drop these clocks from the GCC driver and add it back once 
the actual consumer needs it? So that we don't have to enable it in probe.

Please let me know your thoughts.


> 
> Please correctly describe the clock tree in device tree, not hide
> clocks because your DT description is not complete.
> 
>      Andrew
> 
> ---
> pw-bot: cr


From quic_kathirav at quicinc.com  Wed Feb 14 01:20:33 2024
From: quic_kathirav at quicinc.com (Kathiravan Thirumoorthy)
Date: Wed, 14 Feb 2024 14:50:33 +0530
Subject: [PATCH v4 3/8] dt-bindings: clock: ipq5332: add definition for
 GPLL0_OUT_AUX clock
In-Reply-To: <b939445e-c0a8-48fd-bc95-25c4f22e1e0d@lunn.ch>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-3-19fa30019770@quicinc.com>
 <b939445e-c0a8-48fd-bc95-25c4f22e1e0d@lunn.ch>
Message-ID: <d121c049-ad77-4783-b42e-626c809fe98c@quicinc.com>



On 1/26/2024 1:37 AM, Andrew Lunn wrote:
> On Mon, Jan 22, 2024 at 11:26:59AM +0530, Kathiravan Thirumoorthy wrote:
>> Add the definition for GPLL0_OUT_AUX clock.
> 
> The commit message should answer the question "Why?". Why are you
> adding this clock? What consumes it?
> 
>         Andrew


Ack, will add more details in the next spin.


From robh at kernel.org  Wed Feb 14 01:22:53 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 14 Feb 2024 03:22:53 -0600
Subject: [PATCH] dt-bindings: sound:atmel-at91sam9g20ek: convert
 bindings to json-schema
In-Reply-To: <20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b@microchip.com>
References: <20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b@microchip.com>
Message-ID: <170790257251.233964.609546720299928474.robh@kernel.org>


On Wed, 14 Feb 2024 12:10:06 +0530, Balakrishnan Sambath wrote:
> Convert atmel-at91sam9g20ek-wm8731-audio DT binding to yaml
> based json-schema.Change file name to match json-scheme naming.
> 
> Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>
> ---
>  .../bindings/sound/atmel,at91sam9g20ek-wm8731.yaml | 60 ++++++++++++++++++++++
>  .../sound/atmel-at91sam9g20ek-wm8731-audio.txt     | 26 ----------
>  2 files changed, 60 insertions(+), 26 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:
./Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml:26:11: [error] string value is redundantly quoted with any quotes (quoted-strings)
./Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml:27:11: [error] string value is redundantly quoted with any quotes (quoted-strings)

dtschema/dtc warnings/errors:

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b at microchip.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From zajec5 at gmail.com  Wed Feb 14 01:24:32 2024
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Wed, 14 Feb 2024 10:24:32 +0100
Subject: [PATCH 2/2] arm64: dts: mediatek: mt7988: add PWM controller
In-Reply-To: <36baacb4-4aa9-421f-bde0-c4be7d7f4aa1@collabora.com>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <20240213164633.25447-2-zajec5@gmail.com>
 <36baacb4-4aa9-421f-bde0-c4be7d7f4aa1@collabora.com>
Message-ID: <bbacfaad-a182-4df5-8317-640e32a1954a@gmail.com>

On 14.02.2024 10:09, AngeloGioacchino Del Regno wrote:
> Il 13/02/24 17:46, Rafa? Mi?ecki ha scritto:
>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>
>> Add binding for on-SoC controller that can control up to 8 PWMs.
>>
>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>> ---
>> ? arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 21 ++++++++++++++++++++-
>> ? 1 file changed, 20 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
>> index bba97de4fb44..67007626b5cd 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
>> +++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
>> @@ -1,5 +1,6 @@
>> ? // SPDX-License-Identifier: GPL-2.0-only OR MIT
>> +#include <dt-bindings/clock/mediatek,mt7988-clk.h>
>> ? #include <dt-bindings/interrupt-controller/arm-gic.h>
>> ? / {
>> @@ -78,7 +79,7 @@ gic: interrupt-controller at c000000 {
>> ????????????? #interrupt-cells = <3>;
>> ????????? };
>> -??????? clock-controller at 10001000 {
>> +??????? infracfg: clock-controller at 10001000 {
>> ????????????? compatible = "mediatek,mt7988-infracfg", "syscon";
>> ????????????? reg = <0 0x10001000 0 0x1000>;
>> ????????????? #clock-cells = <1>;
>> @@ -103,6 +104,24 @@ clock-controller at 1001e000 {
>> ????????????? #clock-cells = <1>;
>> ????????? };
>> +??????? pwm at 10048000 {
>> +??????????? compatible = "mediatek,mt7988-pwm";
> 
> I can't take this unless there's a driver that supports your device.

I'd argue you should rather look for a documented binding rather than a
(Linux?) driver. Otherwise you would refuse changes that are not
strictly Linux related. DTS files are meant to describe hardware in a
generic way and not be driven by Linux drivers / design.

Example:
We have bindings for "brcm,bcm6345-timer" and "bcm63138-timer" (see
commit e112f2de151b) and DTS files with those bindings.
There is no Linux driver for that hardware block as there is no need
for it.


In this context I'm explaining binding thing with Conor in discussion
on PATCH 1/1. So stay tuned :)


From rogerq at kernel.org  Wed Feb 14 01:25:24 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 14 Feb 2024 11:25:24 +0200
Subject: [PATCH v1] arm64: dts: ti: k3-am62-main: disable usb lpm
In-Reply-To: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
References: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
Message-ID: <8fc9bac2-d0ce-4c24-b88b-fab1f65dcf37@kernel.org>



On 09/02/2024 15:02, Andrejs Cainikovs wrote:
> From: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
> 
> AM62 USB works with some devices, while failing to operate with others.
> 
> [  560.189822] xhci-hcd xhci-hcd.4.auto: xHCI Host Controller
> [  560.195631] xhci-hcd xhci-hcd.4.auto: new USB bus registered, assigned bus number 2
> [  574.388509] xhci-hcd xhci-hcd.4.auto: can't setup: -110
> [  574.393814] xhci-hcd xhci-hcd.4.auto: USB bus 2 deregistered
> [  574.399544] xhci-hcd: probe of xhci-hcd.4.auto failed with error -110
> 
> This seems to be related to LPM (Link Power Management), and disabling it
> turns USB into reliable working state.
> 
> As per AM62 reference manual:
> 
>> 4.8.2.1 USB2SS Unsupported Features
>>
>> The following features are not supported on this family of devices:
>> ...
>> - USB 2.0 ECN: Link Power Management (LPM)
>> ...
> 
> Fixes: 2240f96cf3cd ("arm64: dts: ti: k3-am62-main: Add support for USB")
> Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>

Reviewed-by: Roger Quadros <rogerq at kernel.org>


From angelogioacchino.delregno at collabora.com  Wed Feb 14 01:27:54 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 14 Feb 2024 10:27:54 +0100
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible for
 MT7988
In-Reply-To: <d4391868-ddcd-4f66-b539-28d245fa83df@gmail.com>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <20240213-resource-evaluator-0754cfd5882d@spud>
 <d4391868-ddcd-4f66-b539-28d245fa83df@gmail.com>
Message-ID: <e957b044-fe84-4b72-bdf1-cbc40c722019@collabora.com>

Il 14/02/24 07:34, Rafa? Mi?ecki ha scritto:
> On 13.02.2024 19:18, Conor Dooley wrote:
>> On Tue, Feb 13, 2024 at 05:46:32PM +0100, Rafa? Mi?ecki wrote:
>>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>>
>>> MT7988 has on-SoC controller that can control up to 8 PWMs.
>>
>> I see a binding and a dts patch, but no driver patch, how come?
> 
> I believe that to avoid cross-trees patchsets (which are sometimes
> tricky for maintainers) there are two ways of submiting such changes:
> 1. dt-binding + driver; then (separately) DTS
> 2. dt-binding + DTS; then (separately) driver
> 
> I chose later in this case as my personal priority right now is to deal
> with all MediaTek DTS files.
> 
> Is that wrong or unacceptable?
> 

It's not wrong but it's partially unacceptable, at least on my side.

In my opinion (and I believe many do agree with me), sending the binding along
with the driver is the right choice, and if you also want to include the dts
that is also appreciated: series can go through multiple maintainers applying
subsets - it's ok to do.

I want to put emphasis on sending the binding with the driver, as this allows
for a better review on everyone's side because we do see the full picture and
we can give better advices: in this case, I'm not sure whether adding a new
compatible for MT7988 in an enum is a good idea, as the compatible string may
be shared with one of the *eleven* SoCs that are supported in the PWM driver,
meaning that (hardware speaking!) the PWM controller in 7988 might be the same
as the one in mt1234.

Thanks for the great work that you're doing on the bindings btw.
Keep it up!
Angelo

> 
>> Also, what makes this incompatibly different with the other devices in
>> the binding, like the 8183?
> 
> It can control 8 PWMs unlike any other SoC block except for MT2712.
> It uses different registers than MT2712 thought.
> 
> 
>> Cheers,
>> Conor.
>>
>>>
>>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>>> ---
>>> ? Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml | 1 +
>>> ? 1 file changed, 1 insertion(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml 
>>> b/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
>>> index 0fbe8a6469eb..a5c308801619 100644
>>> --- a/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
>>> +++ b/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
>>> @@ -24,6 +24,7 @@ properties:
>>> ??????????? - mediatek,mt7629-pwm
>>> ??????????? - mediatek,mt7981-pwm
>>> ??????????? - mediatek,mt7986-pwm
>>> +????????? - mediatek,mt7988-pwm
>>> ??????????? - mediatek,mt8183-pwm
>>> ??????????? - mediatek,mt8365-pwm
>>> ??????????? - mediatek,mt8516-pwm
>>> -- 
>>> 2.35.3
>>>
> 




From quic_kathirav at quicinc.com  Wed Feb 14 01:28:04 2024
From: quic_kathirav at quicinc.com (Kathiravan Thirumoorthy)
Date: Wed, 14 Feb 2024 14:58:04 +0530
Subject: [PATCH v4 4/8] clk: qcom: ipq5332: add gpll0_out_aux clock
In-Reply-To: <635f5e41-1ca2-4b4e-86a5-fdb8f7b27ef9@lunn.ch>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-4-19fa30019770@quicinc.com>
 <635f5e41-1ca2-4b4e-86a5-fdb8f7b27ef9@lunn.ch>
Message-ID: <222b330d-ecc0-4755-b1b5-674e11dcec5c@quicinc.com>



On 1/26/2024 1:41 AM, Andrew Lunn wrote:
> On Mon, Jan 22, 2024 at 11:27:00AM +0530, Kathiravan Thirumoorthy wrote:
>> Add support for gpll0_out_aux clock which acts as the parent for
>> certain networking subsystem (NSS) clocks.
> 
> This answers the question i asked for the previous patch.
> 
> Why did you split this into two patches?


driver and binding patch should be separate patches, else checkpatch 
will complain it.

> 
> Please also give a more detailed description, rather than the vague
> 'certain networking subsystem (NSS) clocks'


Sure, will call out the clock names explicitly in the next spin.

> 
> If you device tree and drivers are correct, i should be able to work
> out what the clock tree looks like, so there is no point trying to
> hide the information.


Clocks which are part of the NSSCC are used by the Networking drivers 
which are in the pipeline for upstream. Once the networking patches are 
submitted in the list, we should be able to get the clear picture of the 
clock tree.


> 
>       Andrew


From p.sakharov at ispras.ru  Wed Feb 14 01:27:17 2024
From: p.sakharov at ispras.ru (Pavel Sakharov)
Date: Wed, 14 Feb 2024 12:27:17 +0300
Subject: [PATCH net v2] net: stmmac: Fix incorrect dereference in interrupt handlers
In-Reply-To: <20240206150704.GD1104779@kernel.org>
Message-ID: <20240214092718.331891-1-p.sakharov@ispras.ru>

If 'dev' or 'data' is NULL, the 'priv' variable has an incorrect address
when dereferencing calling netdev_err().

Since we get as 'dev_id' or 'data' what was passed as the 'dev' argument
to request_irq() during interrupt initialization (that is, the net_device
and rx/tx queue pointers initialized at the time of the call) and since
there are usually no checks for the 'dev_id' argument in such handlers
in other drivers, remove these checks from the handlers in stmmac driver.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 8532f613bc78 ("net: stmmac: introduce MSI Interrupt routines for mac, safety, RX & TX")
Signed-off-by: Pavel Sakharov <p.sakharov at ispras.ru>
---
v2: Drop the second argument checks in the handlers as suggested by Serge Semin <fancer.lancer at gmail.com>.

 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 -------------------
 1 file changed, 20 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 75d029704503..e80d77bd9f1f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -6059,11 +6059,6 @@ static irqreturn_t stmmac_mac_interrupt(int irq, void *dev_id)
 	struct net_device *dev = (struct net_device *)dev_id;
 	struct stmmac_priv *priv = netdev_priv(dev);
 
-	if (unlikely(!dev)) {
-		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
-		return IRQ_NONE;
-	}
-
 	/* Check if adapter is up */
 	if (test_bit(STMMAC_DOWN, &priv->state))
 		return IRQ_HANDLED;
@@ -6079,11 +6074,6 @@ static irqreturn_t stmmac_safety_interrupt(int irq, void *dev_id)
 	struct net_device *dev = (struct net_device *)dev_id;
 	struct stmmac_priv *priv = netdev_priv(dev);
 
-	if (unlikely(!dev)) {
-		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
-		return IRQ_NONE;
-	}
-
 	/* Check if adapter is up */
 	if (test_bit(STMMAC_DOWN, &priv->state))
 		return IRQ_HANDLED;
@@ -6105,11 +6095,6 @@ static irqreturn_t stmmac_msi_intr_tx(int irq, void *data)
 	dma_conf = container_of(tx_q, struct stmmac_dma_conf, tx_queue[chan]);
 	priv = container_of(dma_conf, struct stmmac_priv, dma_conf);
 
-	if (unlikely(!data)) {
-		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
-		return IRQ_NONE;
-	}
-
 	/* Check if adapter is up */
 	if (test_bit(STMMAC_DOWN, &priv->state))
 		return IRQ_HANDLED;
@@ -6136,11 +6121,6 @@ static irqreturn_t stmmac_msi_intr_rx(int irq, void *data)
 	dma_conf = container_of(rx_q, struct stmmac_dma_conf, rx_queue[chan]);
 	priv = container_of(dma_conf, struct stmmac_priv, dma_conf);
 
-	if (unlikely(!data)) {
-		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
-		return IRQ_NONE;
-	}
-
 	/* Check if adapter is up */
 	if (test_bit(STMMAC_DOWN, &priv->state))
 		return IRQ_HANDLED;
-- 
2.43.0



From ulf.hansson at linaro.org  Wed Feb 14 01:30:13 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 14 Feb 2024 10:30:13 +0100
Subject: [PATCH v2 00/15] arm64: renesas: Add R-Car V4M and Gray Hawk
 Single support
In-Reply-To: <CAMuHMdX1tjgPJ8t+XoASuMvzvSognu7q2=aGfBO8r77JsbR82w@mail.gmail.com>
References: <cover.1706194617.git.geert+renesas@glider.be> <CAPDyKFpxaEUHvKKb+spxV6HG2P2gLx5qM1mLPxJie+PdkmTL4w@mail.gmail.com>
 <CAMuHMdUswhJ3BQLnOQZC7X7qc7SFCqsr9Uy65LfBT_BNWfyhFQ@mail.gmail.com> <CAMuHMdX1tjgPJ8t+XoASuMvzvSognu7q2=aGfBO8r77JsbR82w@mail.gmail.com>
Message-ID: <CAPDyKFrTZPv+9sVtCgB2i+U-kS4R+qC_r3q_hQ-dVbHM4yDyKQ@mail.gmail.com>

On Wed, 14 Feb 2024 at 09:35, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>
> Hi Ulf,
>
> On Wed, Jan 31, 2024 at 3:56?PM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> > On Tue, Jan 30, 2024 at 2:11?PM Ulf Hansson <ulf.hansson at linaro.org> wrote:
> > > On Thu, 25 Jan 2024 at 16:34, Geert Uytterhoeven
> > > <geert+renesas at glider.be> wrote:
> > > > This patch series adds initial support for the Renesas R-Car V4M
> > > > (R8A779G0) SoC and the Renesas Gray Hawk Single development board.
> > > >
> > > > As both driver code and DTS have hard dependencies on DT binding
> > > > definitions, most patches in this series are supposed to go in through
> > > > the renesas-devel and/or renesas-clk trees, using a shared branch for DT
> > > > binding definitions, as usual.  For the PM domain patches (03, 04, 09),
> > > > Ulf already offered to apply these to his pmdomain tree, and provide an
> > > > immutable "dt" branch, to be pulled in my renesas-devel tree.
> > >
> > > Patch 3,4 and 9 (I dropped the copyright line in patch9, as pointed
> > > out by Niklas) applied for next, thanks!
> > >
> > > Patch 3,4 are also available at the immutable dt branch for you to pull in.
> >
> > Thank you!
> >
> > I have pulled the immutable branch, added the remaining DT binding
> > definitions, and queued all remaining patches.
>
> It looks like you have applied copies of all commits on the "dt"
> branch to the "next"
> branch, so now there are two copies?
>
> See the output of "git range-diff v6.8-rc1..pmdomain/dt
> v6.8-rc4..pmdomain/next".

I screwed up - and thanks for pointing this out! Problem is taken care of now.

Kind regards
Uffe


From bhargav.r at ltts.com  Wed Feb 14 01:31:06 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Wed, 14 Feb 2024 15:01:06 +0530
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI TPS65224 PMIC
In-Reply-To: <20240209-blitz-fidgety-78469aa80d6d@spud>
References: <20240209-blitz-fidgety-78469aa80d6d@spud>
Message-ID: <20240214093106.86483-1-bhargav.r@ltts.com>

Hi Conor,

On Fri 2/9/2024 10:41 PM, Conor Dooley wrote:
> On Thu, Feb 08, 2024 at 04:23:33PM +0530, Bhargav Raviprakash wrote:
> > TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
> > regulators, it includes additional features like GPIOs, watchdog, ESMs
> > (Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
> > managing the state of the device.
> 
> > TPS6594 and TPS65224 have significant functional overlap.
> 
> What does "significant functional overlap" mean? Does one implement a
> compatible subset of the other? I assume the answer is no, given there
> seems to be some core looking registers at different addresses.
> 
> Thanks,
> Conor.

The intention behind ?significant functional overlap? was meant to
indicate a lot of the features between TPS6594 and TPS65224 overlap,
while there are some features specific to TPS65224.
There is compatibility between the PMIC register maps, I2C, PFSM,
and other drivers even though there are some core registers at
different addresses.

Would it be more appropriate to say the 2 devices are compatible and have
sufficient feature overlap rather than significant functional overlap?

Thank you for your review and feedback!                                     

Regards,
Bhargav


From msp at baylibre.com  Wed Feb 14 01:31:56 2024
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Wed, 14 Feb 2024 10:31:56 +0100
Subject: [PATCH 2/4] dt-bindings: hwinfo: ti,k3-socinfo: Add nvmem-cells
In-Reply-To: <20240206184305.GA1875492-robh@kernel.org>
References: <20240206143711.2410135-1-msp@baylibre.com>
 <20240206143711.2410135-3-msp@baylibre.com>
 <20240206184305.GA1875492-robh@kernel.org>
Message-ID: <z56fiu2jpokp57sjvnrdcbfy7brpq2ag4yxpektqlhtidecx4n@vc7dsurhxorb>

Hi Rob,

On Tue, Feb 06, 2024 at 06:43:05PM +0000, Rob Herring wrote:
> On Tue, Feb 06, 2024 at 03:37:09PM +0100, Markus Schneider-Pargmann wrote:
> > The information k3-socinfo requires is stored in an efuse area. This
> > area is required by other devices/drivers as well, so using nvmem-cells
> > can be a cleaner way to describe which information are used.
> > 
> > If nvmem-cells are supplied, the address range is not required.
> > Cells chipvariant, chippartno and chipmanufacturer are introduced to
> > cover all required information.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> > Reviewed-by: Andrew Davis <afd at ti.com>
> > ---
> >  .../bindings/hwinfo/ti,k3-socinfo.yaml        | 23 ++++++++++++++++++-
> >  1 file changed, 22 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
> > index dada28b47ea0..f085b7275b7d 100644
> > --- a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
> > +++ b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
> > @@ -26,9 +26,24 @@ properties:
> >    reg:
> >      maxItems: 1
> >  
> > +  nvmem-cells:
> > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > +
> > +  nvmem-cell-names:
> > +    items:
> > +      - const: chipvariant
> > +      - const: chippartno
> > +      - const: chipmanufacturer
> > +
> >  required:
> >    - compatible
> > -  - reg
> > +
> > +oneOf:
> > +  - required:
> > +      - reg
> > +  - required:
> > +      - nvmem-cells
> > +      - nvmem-cell-names
> >  
> >  additionalProperties: false
> >  
> > @@ -38,3 +53,9 @@ examples:
> >          compatible = "ti,am654-chipid";
> >          reg = <0x43000014 0x4>;
> >      };
> > +  - |
> > +    chipid: chipid at 14 {
> > +        compatible = "ti,am654-chipid";
> 
> This isn't compatible if you have a completely different way to access 
> it. 

Thanks, it is not entirely clear to me how I could go forward with this?
Are you suggesting to use a different compatible? Or is it something
else I could do to proceed with this conversion?

Thank you!

Best,
Markus


From n-francis at ti.com  Wed Feb 14 01:33:18 2024
From: n-francis at ti.com (Neha Malcom Francis)
Date: Wed, 14 Feb 2024 15:03:18 +0530
Subject: [PATCH v2 1/2] arm64: dts: ti: k3-am69-sk: fix PMIC interrupt
 number
In-Reply-To: <20240209171146.307465-1-romain.naour@smile.fr>
References: <20240209171146.307465-1-romain.naour@smile.fr>
Message-ID: <75241296-c698-4983-9dcd-9f59c31cb286@ti.com>

Hi Romain

On 09/02/24 22:41, Romain Naour wrote:
> The tps659413 node set WKUP_GPIO0_83 (AA37) pin as input to be used as
> PMIC interrupt but uses 39 (WKUP_GPIO0_39) as "interrupts" property.
> 
> Replace 39 by 83 after checking in the board schematic [1].
> 
> [1] https://www.ti.com/tool/SK-AM69
> 
> Fixes: 865a1593bf99 ("arm64: dts: ti: k3-am69-sk: Add support for TPS6594 PMIC")
> Cc: Neha Malcom Francis <n-francis at ti.com>
> Signed-off-by: Romain Naour <romain.naour at smile.fr>
> ---
>   arch/arm64/boot/dts/ti/k3-am69-sk.dts | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> index 8da591579868..95c9d3da59d3 100644
> --- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> @@ -646,7 +646,7 @@ tps659413: pmic at 48 {
>   		pinctrl-names = "default";
>   		pinctrl-0 = <&pmic_irq_pins_default>;
>   		interrupt-parent = <&wkup_gpio0>;
> -		interrupts = <39 IRQ_TYPE_EDGE_FALLING>;
> +		interrupts = <83 IRQ_TYPE_EDGE_FALLING>;
>   		gpio-controller;
>   		#gpio-cells = <2>;
>   		ti,primary-pmic;

Thanks for catching this!

Reviewed-by: Neha Malcom Francis <n-francis at ti.com>

-- 
Thanking You
Neha Malcom Francis


From n-francis at ti.com  Wed Feb 14 01:33:36 2024
From: n-francis at ti.com (Neha Malcom Francis)
Date: Wed, 14 Feb 2024 15:03:36 +0530
Subject: [PATCH v2 2/2] arm64: dts: ti: k3-j721e-sk: fix PMIC interrupt
 number
In-Reply-To: <20240209171146.307465-2-romain.naour@smile.fr>
References: <20240209171146.307465-1-romain.naour@smile.fr>
 <20240209171146.307465-2-romain.naour@smile.fr>
Message-ID: <a8ed43ca-d2fb-4dce-ba9f-9c52e5a05b1a@ti.com>

On 09/02/24 22:41, Romain Naour wrote:
> The tps659413 and tps659411 nodes set WKUP_GPIO0_7 (G28) pin as input
> to be used as PMIC interrupt but uses 9 (WKUP_GPIO0_9) as
> "interrupts" property.
> 
> Replace 9 by 7 for both tps659413 and tps659411 after checking in the
> board schematic [1].
> 
> [1] https://www.ti.com/tool/SK-TDA4VM
> 
> Fixes: b808cef0be46 ("arm64: dts: ti: k3-j721e-sk: Add TPS6594 family PMICs")
> Cc: Neha Malcom Francis <n-francis at ti.com>
> Signed-off-by: Romain Naour <romain.naour at smile.fr>
> ---
> v2: update tps659411 interrupts parameter too.
> ---
>   arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
> index 188dfe291a32..658764f7d544 100644
> --- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
> @@ -574,7 +574,7 @@ tps659413: pmic at 48 {
>   		pinctrl-names = "default";
>   		pinctrl-0 = <&pmic_irq_pins_default>;
>   		interrupt-parent = <&wkup_gpio0>;
> -		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
> +		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
>   		gpio-controller;
>   		#gpio-cells = <2>;
>   		ti,primary-pmic;
> @@ -651,7 +651,7 @@ tps659411: pmic at 4c {
>   		reg = <0x4c>;
>   		system-power-controller;
>   		interrupt-parent = <&wkup_gpio0>;
> -		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
> +		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
>   		gpio-controller;
>   		#gpio-cells = <2>;
>   		buck1234-supply = <&vsys_3v3>;


Reviewed-by: Neha Malcom Francis <n-francis at ti.com>

-- 
Thanking You
Neha Malcom Francis


From angelogioacchino.delregno at collabora.com  Wed Feb 14 01:33:57 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 14 Feb 2024 10:33:57 +0100
Subject: [PATCH 2/2] arm64: dts: mediatek: mt7988: add PWM controller
In-Reply-To: <bbacfaad-a182-4df5-8317-640e32a1954a@gmail.com>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <20240213164633.25447-2-zajec5@gmail.com>
 <36baacb4-4aa9-421f-bde0-c4be7d7f4aa1@collabora.com>
 <bbacfaad-a182-4df5-8317-640e32a1954a@gmail.com>
Message-ID: <b5dce02f-414a-42df-8210-3e80a769e324@collabora.com>

Il 14/02/24 10:24, Rafa? Mi?ecki ha scritto:
> On 14.02.2024 10:09, AngeloGioacchino Del Regno wrote:
>> Il 13/02/24 17:46, Rafa? Mi?ecki ha scritto:
>>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>>
>>> Add binding for on-SoC controller that can control up to 8 PWMs.
>>>
>>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>>> ---
>>> ? arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 21 ++++++++++++++++++++-
>>> ? 1 file changed, 20 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi 
>>> b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
>>> index bba97de4fb44..67007626b5cd 100644
>>> --- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
>>> +++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
>>> @@ -1,5 +1,6 @@
>>> ? // SPDX-License-Identifier: GPL-2.0-only OR MIT
>>> +#include <dt-bindings/clock/mediatek,mt7988-clk.h>
>>> ? #include <dt-bindings/interrupt-controller/arm-gic.h>
>>> ? / {
>>> @@ -78,7 +79,7 @@ gic: interrupt-controller at c000000 {
>>> ????????????? #interrupt-cells = <3>;
>>> ????????? };
>>> -??????? clock-controller at 10001000 {
>>> +??????? infracfg: clock-controller at 10001000 {
>>> ????????????? compatible = "mediatek,mt7988-infracfg", "syscon";
>>> ????????????? reg = <0 0x10001000 0 0x1000>;
>>> ????????????? #clock-cells = <1>;
>>> @@ -103,6 +104,24 @@ clock-controller at 1001e000 {
>>> ????????????? #clock-cells = <1>;
>>> ????????? };
>>> +??????? pwm at 10048000 {
>>> +??????????? compatible = "mediatek,mt7988-pwm";
>>
>> I can't take this unless there's a driver that supports your device.
> 
> I'd argue you should rather look for a documented binding rather than a
> (Linux?) driver. Otherwise you would refuse changes that are not
> strictly Linux related. DTS files are meant to describe hardware in a
> generic way and not be driven by Linux drivers / design.
> 

Of course, devicetree describes hardware - that is pretty much globally known.

As I wrote in the bindings patch, I still anyway want to see the driver part
for this block before deciding if your description of this hardware is correct.

Regards,
Angelo



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:30:56 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:30:56 +0100
Subject: [PATCH v6 009/164] pwm: atmel: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <f8ca10033204111e4eb2e7a4dad0bd1f7586c735.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-atmel.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 2f7d6c43be85..96e1676a5c51 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -210,7 +210,7 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
 	shift = fls(cycles) - atmel_pwm->data->cfg.period_bits;
 
 	if (shift > PWM_MAX_PRES) {
-		dev_err(chip->dev, "pres exceeds the maximum value\n");
+		dev_err(pwmchip_parent(chip), "pres exceeds the maximum value\n");
 		return -EINVAL;
 	} else if (shift > 0) {
 		*pres = shift;
@@ -321,7 +321,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 		ret = atmel_pwm_calculate_cprd_and_pres(chip, clkrate, state, &cprd,
 							&pres);
 		if (ret) {
-			dev_err(chip->dev,
+			dev_err(pwmchip_parent(chip),
 				"failed to calculate cprd and prescaler\n");
 			return ret;
 		}
@@ -333,7 +333,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 		} else {
 			ret = clk_enable(atmel_pwm->clk);
 			if (ret) {
-				dev_err(chip->dev, "failed to enable clock\n");
+				dev_err(pwmchip_parent(chip), "failed to enable clock\n");
 				return ret;
 			}
 		}
@@ -481,7 +481,7 @@ static int atmel_pwm_enable_clk_if_on(struct pwm_chip *chip, bool on)
 	for (i = 0; i < cnt; i++) {
 		ret = clk_enable(atmel_pwm->clk);
 		if (ret) {
-			dev_err(chip->dev,
+			dev_err(pwmchip_parent(chip),
 				"failed to enable clock for pwm %pe\n",
 				ERR_PTR(ret));
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:04 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:04 +0100
Subject: [PATCH v6 017/164] pwm: bcm-iproc: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <cdc6136b94f685c85a615e9e5ccbd7ebb2f91cfc.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-bcm-iproc driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-bcm-iproc.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/pwm/pwm-bcm-iproc.c b/drivers/pwm/pwm-bcm-iproc.c
index 758254025683..f4c9f10e490e 100644
--- a/drivers/pwm/pwm-bcm-iproc.c
+++ b/drivers/pwm/pwm-bcm-iproc.c
@@ -34,14 +34,13 @@
 #define IPROC_PWM_PRESCALE_MAX			0x3f
 
 struct iproc_pwmc {
-	struct pwm_chip chip;
 	void __iomem *base;
 	struct clk *clk;
 };
 
 static inline struct iproc_pwmc *to_iproc_pwmc(struct pwm_chip *chip)
 {
-	return container_of(chip, struct iproc_pwmc, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static void iproc_pwmc_enable(struct iproc_pwmc *ip, unsigned int channel)
@@ -187,20 +186,20 @@ static const struct pwm_ops iproc_pwm_ops = {
 
 static int iproc_pwmc_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct iproc_pwmc *ip;
 	unsigned int i;
 	u32 value;
 	int ret;
 
-	ip = devm_kzalloc(&pdev->dev, sizeof(*ip), GFP_KERNEL);
-	if (!ip)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 4, sizeof(*ip));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	ip = to_iproc_pwmc(chip);
 
 	platform_set_drvdata(pdev, ip);
 
-	ip->chip.dev = &pdev->dev;
-	ip->chip.ops = &iproc_pwm_ops;
-	ip->chip.npwm = 4;
+	chip->ops = &iproc_pwm_ops;
 
 	ip->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ip->base))
@@ -214,14 +213,14 @@ static int iproc_pwmc_probe(struct platform_device *pdev)
 	/* Set full drive and normal polarity for all channels */
 	value = readl(ip->base + IPROC_PWM_CTRL_OFFSET);
 
-	for (i = 0; i < ip->chip.npwm; i++) {
+	for (i = 0; i < chip->npwm; i++) {
 		value &= ~(1 << IPROC_PWM_CTRL_TYPE_SHIFT(i));
 		value |= 1 << IPROC_PWM_CTRL_POLARITY_SHIFT(i);
 	}
 
 	writel(value, ip->base + IPROC_PWM_CTRL_OFFSET);
 
-	ret = devm_pwmchip_add(&pdev->dev, &ip->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0)
 		return dev_err_probe(&pdev->dev, ret,
 				     "failed to add PWM chip\n");
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:09 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:09 +0100
Subject: [PATCH v6 022/164] pwm: brcmstb: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <adf9cb04f5d84ae604e97d4dc0708ff3677d72d7.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-brcmstb driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-brcmstb.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-brcmstb.c b/drivers/pwm/pwm-brcmstb.c
index 0fdeb0b2dbf3..82d27d07ba91 100644
--- a/drivers/pwm/pwm-brcmstb.c
+++ b/drivers/pwm/pwm-brcmstb.c
@@ -54,7 +54,6 @@
 struct brcmstb_pwm {
 	void __iomem *base;
 	struct clk *clk;
-	struct pwm_chip chip;
 };
 
 static inline u32 brcmstb_pwm_readl(struct brcmstb_pwm *p,
@@ -77,7 +76,7 @@ static inline void brcmstb_pwm_writel(struct brcmstb_pwm *p, u32 value,
 
 static inline struct brcmstb_pwm *to_brcmstb_pwm(struct pwm_chip *chip)
 {
-	return container_of(chip, struct brcmstb_pwm, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 /*
@@ -230,12 +229,14 @@ MODULE_DEVICE_TABLE(of, brcmstb_pwm_of_match);
 
 static int brcmstb_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct brcmstb_pwm *p;
 	int ret;
 
-	p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
-	if (!p)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 2, sizeof(*p));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	p = to_brcmstb_pwm(chip);
 
 	p->clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(p->clk))
@@ -244,15 +245,13 @@ static int brcmstb_pwm_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, p);
 
-	p->chip.dev = &pdev->dev;
-	p->chip.ops = &brcmstb_pwm_ops;
-	p->chip.npwm = 2;
+	chip->ops = &brcmstb_pwm_ops;
 
 	p->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(p->base))
 		return PTR_ERR(p->base);
 
-	ret = devm_pwmchip_add(&pdev->dev, &p->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret)
 		return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:30:58 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:30:58 +0100
Subject: [PATCH v6 011/164] pwm: atmel-hlcdc: Prepare removing pwm_chip from driver data
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <0e97342f15540c7330d405eaaf3e68baa8e1e488.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will drop struct
pwm_chip chip from struct atmel_hlcdc_pwm. Use the pwm_chip as driver
data instead of the atmel_hlcdc_pwm to get access to the pwm_chip in
the .suspend() and .resume() callbacks and atmel_hlcdc_pwm_remove()
without using atmel->chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-atmel-hlcdc.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c
index 1f6fc9a9fcf3..f3f6c951bda5 100644
--- a/drivers/pwm/pwm-atmel-hlcdc.c
+++ b/drivers/pwm/pwm-atmel-hlcdc.c
@@ -182,10 +182,11 @@ static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_sama5d3_errata = {
 
 static int atmel_hlcdc_pwm_suspend(struct device *dev)
 {
-	struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev);
+	struct pwm_chip *chip = dev_get_drvdata(dev);
+	struct atmel_hlcdc_pwm *atmel = to_atmel_hlcdc_pwm(chip);
 
 	/* Keep the periph clock enabled if the PWM is still running. */
-	if (!pwm_is_enabled(&atmel->chip.pwms[0]))
+	if (!pwm_is_enabled(&chip->pwms[0]))
 		clk_disable_unprepare(atmel->hlcdc->periph_clk);
 
 	return 0;
@@ -193,11 +194,12 @@ static int atmel_hlcdc_pwm_suspend(struct device *dev)
 
 static int atmel_hlcdc_pwm_resume(struct device *dev)
 {
-	struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev);
+	struct pwm_chip *chip = dev_get_drvdata(dev);
+	struct atmel_hlcdc_pwm *atmel = to_atmel_hlcdc_pwm(chip);
 	struct pwm_state state;
 	int ret;
 
-	pwm_get_state(&atmel->chip.pwms[0], &state);
+	pwm_get_state(&chip->pwms[0], &state);
 
 	/* Re-enable the periph clock it was stopped during suspend. */
 	if (!state.enabled) {
@@ -206,8 +208,7 @@ static int atmel_hlcdc_pwm_resume(struct device *dev)
 			return ret;
 	}
 
-	return atmel_hlcdc_pwm_apply(&atmel->chip, &atmel->chip.pwms[0],
-				     &state);
+	return atmel_hlcdc_pwm_apply(chip, &chip->pwms[0], &state);
 }
 
 static DEFINE_SIMPLE_DEV_PM_OPS(atmel_hlcdc_pwm_pm_ops,
@@ -243,6 +244,7 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match;
 	struct device *dev = &pdev->dev;
+	struct pwm_chip *chip;
 	struct atmel_hlcdc_pwm *atmel;
 	struct atmel_hlcdc *hlcdc;
 	int ret;
@@ -262,26 +264,28 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
 		atmel->errata = match->data;
 
 	atmel->hlcdc = hlcdc;
-	atmel->chip.ops = &atmel_hlcdc_pwm_ops;
-	atmel->chip.dev = dev;
-	atmel->chip.npwm = 1;
+	chip = &atmel->chip;
+	chip->ops = &atmel_hlcdc_pwm_ops;
+	chip->dev = dev;
+	chip->npwm = 1;
 
-	ret = pwmchip_add(&atmel->chip);
+	ret = pwmchip_add(chip);
 	if (ret) {
 		clk_disable_unprepare(hlcdc->periph_clk);
 		return ret;
 	}
 
-	platform_set_drvdata(pdev, atmel);
+	platform_set_drvdata(pdev, chip);
 
 	return 0;
 }
 
 static void atmel_hlcdc_pwm_remove(struct platform_device *pdev)
 {
-	struct atmel_hlcdc_pwm *atmel = platform_get_drvdata(pdev);
+	struct pwm_chip *chip = platform_get_drvdata(pdev);
+	struct atmel_hlcdc_pwm *atmel = to_atmel_hlcdc_pwm(chip);
 
-	pwmchip_remove(&atmel->chip);
+	pwmchip_remove(chip);
 
 	clk_disable_unprepare(atmel->hlcdc->periph_clk);
 }
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:12 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:12 +0100
Subject: [PATCH v6 025/164] pwm: clps711x: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <334e633bb8e4c26dc59883b068466387769b65f9.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-clps711x driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-clps711x.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-clps711x.c b/drivers/pwm/pwm-clps711x.c
index f3b4af7963be..c950e1dbd2b8 100644
--- a/drivers/pwm/pwm-clps711x.c
+++ b/drivers/pwm/pwm-clps711x.c
@@ -12,7 +12,6 @@
 #include <linux/pwm.h>
 
 struct clps711x_chip {
-	struct pwm_chip chip;
 	void __iomem *pmpcon;
 	struct clk *clk;
 	spinlock_t lock;
@@ -20,7 +19,7 @@ struct clps711x_chip {
 
 static inline struct clps711x_chip *to_clps711x_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct clps711x_chip, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
@@ -76,11 +75,13 @@ static const struct pwm_ops clps711x_pwm_ops = {
 
 static int clps711x_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct clps711x_chip *priv;
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 2, sizeof(*priv));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	priv = to_clps711x_chip(chip);
 
 	priv->pmpcon = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->pmpcon))
@@ -90,13 +91,11 @@ static int clps711x_pwm_probe(struct platform_device *pdev)
 	if (IS_ERR(priv->clk))
 		return PTR_ERR(priv->clk);
 
-	priv->chip.ops = &clps711x_pwm_ops;
-	priv->chip.dev = &pdev->dev;
-	priv->chip.npwm = 2;
+	chip->ops = &clps711x_pwm_ops;
 
 	spin_lock_init(&priv->lock);
 
-	return devm_pwmchip_add(&pdev->dev, &priv->chip);
+	return devm_pwmchip_add(&pdev->dev, chip);
 }
 
 static const struct of_device_id __maybe_unused clps711x_pwm_dt_ids[] = {
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:03 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:03 +0100
Subject: [PATCH v6 016/164] pwm: bcm2835: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <441489772bdfbb2cd206fd534b36c63e8c50843a.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-bcm2835 driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-bcm2835.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c
index 711c174bbe23..aa35acbb0cbc 100644
--- a/drivers/pwm/pwm-bcm2835.c
+++ b/drivers/pwm/pwm-bcm2835.c
@@ -24,7 +24,6 @@
 #define PERIOD_MIN		0x2
 
 struct bcm2835_pwm {
-	struct pwm_chip chip;
 	void __iomem *base;
 	struct clk *clk;
 	unsigned long rate;
@@ -32,7 +31,7 @@ struct bcm2835_pwm {
 
 static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip)
 {
-	return container_of(chip, struct bcm2835_pwm, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
@@ -134,12 +133,14 @@ static void devm_clk_rate_exclusive_put(void *data)
 
 static int bcm2835_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct bcm2835_pwm *pc;
 	int ret;
 
-	pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
-	if (!pc)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 2, sizeof(*pc));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	pc = to_bcm2835_pwm(chip);
 
 	pc->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(pc->base))
@@ -165,14 +166,12 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, -EINVAL,
 				     "failed to get clock rate\n");
 
-	pc->chip.dev = &pdev->dev;
-	pc->chip.ops = &bcm2835_pwm_ops;
-	pc->chip.atomic = true;
-	pc->chip.npwm = 2;
+	chip->ops = &bcm2835_pwm_ops;
+	chip->atomic = true;
 
 	platform_set_drvdata(pdev, pc);
 
-	ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0)
 		return dev_err_probe(&pdev->dev, ret,
 				     "failed to add pwmchip\n");
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:30:55 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:30:55 +0100
Subject: [PATCH v6 008/164] pwm: atmel: Change prototype of a helper to prepare further changes
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <c9a92f77760e401debfe0c9bfc086222f31fb3c4.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will make it harder to
determine the pwm_chip from a given atmel_pwm_chip. To just not have to
do that, rework atmel_pwm_enable_clk_if_on() to take a pwm_chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-atmel.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 47bcc8a3bf9d..2f7d6c43be85 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -462,8 +462,9 @@ static const struct of_device_id atmel_pwm_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids);
 
-static int atmel_pwm_enable_clk_if_on(struct atmel_pwm_chip *atmel_pwm, bool on)
+static int atmel_pwm_enable_clk_if_on(struct pwm_chip *chip, bool on)
 {
+	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
 	unsigned int i, cnt = 0;
 	unsigned long sr;
 	int ret = 0;
@@ -472,7 +473,7 @@ static int atmel_pwm_enable_clk_if_on(struct atmel_pwm_chip *atmel_pwm, bool on)
 	if (!sr)
 		return 0;
 
-	cnt = bitmap_weight(&sr, atmel_pwm->chip.npwm);
+	cnt = bitmap_weight(&sr, chip->npwm);
 
 	if (!on)
 		goto disable_clk;
@@ -480,7 +481,7 @@ static int atmel_pwm_enable_clk_if_on(struct atmel_pwm_chip *atmel_pwm, bool on)
 	for (i = 0; i < cnt; i++) {
 		ret = clk_enable(atmel_pwm->clk);
 		if (ret) {
-			dev_err(atmel_pwm->chip.dev,
+			dev_err(chip->dev,
 				"failed to enable clock for pwm %pe\n",
 				ERR_PTR(ret));
 
@@ -501,6 +502,7 @@ static int atmel_pwm_enable_clk_if_on(struct atmel_pwm_chip *atmel_pwm, bool on)
 static int atmel_pwm_probe(struct platform_device *pdev)
 {
 	struct atmel_pwm_chip *atmel_pwm;
+	struct pwm_chip *chip;
 	int ret;
 
 	atmel_pwm = devm_kzalloc(&pdev->dev, sizeof(*atmel_pwm), GFP_KERNEL);
@@ -521,15 +523,16 @@ static int atmel_pwm_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, PTR_ERR(atmel_pwm->clk),
 				     "failed to get prepared PWM clock\n");
 
-	atmel_pwm->chip.dev = &pdev->dev;
-	atmel_pwm->chip.ops = &atmel_pwm_ops;
-	atmel_pwm->chip.npwm = 4;
+	chip = &atmel_pwm->chip;
+	chip->dev = &pdev->dev;
+	chip->ops = &atmel_pwm_ops;
+	chip->npwm = 4;
 
-	ret = atmel_pwm_enable_clk_if_on(atmel_pwm, true);
+	ret = atmel_pwm_enable_clk_if_on(chip, true);
 	if (ret < 0)
 		return ret;
 
-	ret = devm_pwmchip_add(&pdev->dev, &atmel_pwm->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0) {
 		dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
 		goto disable_clk;
@@ -538,7 +541,7 @@ static int atmel_pwm_probe(struct platform_device *pdev)
 	return 0;
 
 disable_clk:
-	atmel_pwm_enable_clk_if_on(atmel_pwm, false);
+	atmel_pwm_enable_clk_if_on(chip, false);
 
 	return ret;
 }
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:02 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:02 +0100
Subject: [PATCH v6 015/164] pwm: atmel-tcb: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <c845e6c9d27c8a4037755b2ae702b0039947a3c1.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-atmel-tcb driver to further changes of the pwm
core outlined in the commit introducing devm_pwmchip_alloc(). There is
no intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-atmel-tcb.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c
index 9d928e26b403..528e54c5999d 100644
--- a/drivers/pwm/pwm-atmel-tcb.c
+++ b/drivers/pwm/pwm-atmel-tcb.c
@@ -47,7 +47,6 @@ struct atmel_tcb_channel {
 };
 
 struct atmel_tcb_pwm_chip {
-	struct pwm_chip chip;
 	spinlock_t lock;
 	u8 channel;
 	u8 width;
@@ -63,7 +62,7 @@ static const u8 atmel_tcb_divisors[] = { 2, 8, 32, 128, 0, };
 
 static inline struct atmel_tcb_pwm_chip *to_tcb_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct atmel_tcb_pwm_chip, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int atmel_tcb_pwm_request(struct pwm_chip *chip,
@@ -397,9 +396,10 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 	int err;
 	int channel;
 
-	tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
-	if (tcbpwm == NULL)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, NPWM, sizeof(*tcbpwm));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	tcbpwm = to_tcb_chip(chip);
 
 	err = of_property_read_u32(np, "reg", &channel);
 	if (err < 0) {
@@ -437,10 +437,7 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 		}
 	}
 
-	chip = &tcbpwm->chip;
-	chip->dev = &pdev->dev;
 	chip->ops = &atmel_tcb_pwm_ops;
-	chip->npwm = NPWM;
 	tcbpwm->channel = channel;
 	tcbpwm->width = config->counter_width;
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:00 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:00 +0100
Subject: [PATCH v6 013/164] pwm: atmel-tcb: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <463d43cab01f97f3c4247c63cc08e76aa15684c4.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-atmel-tcb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c
index d42c897cb85e..80121ab81a01 100644
--- a/drivers/pwm/pwm-atmel-tcb.c
+++ b/drivers/pwm/pwm-atmel-tcb.c
@@ -327,7 +327,7 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	if ((atcbpwm && atcbpwm->duty > 0 &&
 			atcbpwm->duty != atcbpwm->period) &&
 		(atcbpwm->div != i || atcbpwm->period != period)) {
-		dev_err(chip->dev,
+		dev_err(pwmchip_parent(chip),
 			"failed to configure period_ns: PWM group already configured with a different value\n");
 		return -EINVAL;
 	}
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:30:57 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:30:57 +0100
Subject: [PATCH v6 010/164] pwm: atmel: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <f2a83af5660de461b4dcaf76929e9813bddfeff1.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-atmel driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-atmel.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 96e1676a5c51..bfb408804d6a 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -77,7 +77,6 @@ struct atmel_pwm_data {
 };
 
 struct atmel_pwm_chip {
-	struct pwm_chip chip;
 	struct clk *clk;
 	void __iomem *base;
 	const struct atmel_pwm_data *data;
@@ -99,7 +98,7 @@ struct atmel_pwm_chip {
 
 static inline struct atmel_pwm_chip *to_atmel_pwm_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct atmel_pwm_chip, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static inline u32 atmel_pwm_readl(struct atmel_pwm_chip *chip,
@@ -505,10 +504,11 @@ static int atmel_pwm_probe(struct platform_device *pdev)
 	struct pwm_chip *chip;
 	int ret;
 
-	atmel_pwm = devm_kzalloc(&pdev->dev, sizeof(*atmel_pwm), GFP_KERNEL);
-	if (!atmel_pwm)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 4, sizeof(*atmel_pwm));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
 
+	atmel_pwm = to_atmel_pwm_chip(chip);
 	atmel_pwm->data = of_device_get_match_data(&pdev->dev);
 
 	atmel_pwm->update_pending = 0;
@@ -523,10 +523,7 @@ static int atmel_pwm_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, PTR_ERR(atmel_pwm->clk),
 				     "failed to get prepared PWM clock\n");
 
-	chip = &atmel_pwm->chip;
-	chip->dev = &pdev->dev;
 	chip->ops = &atmel_pwm_ops;
-	chip->npwm = 4;
 
 	ret = atmel_pwm_enable_clk_if_on(chip, true);
 	if (ret < 0)
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:01 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:01 +0100
Subject: [PATCH v6 014/164] pwm: atmel-tcb: Prepare removing pwm_chip from driver data
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <6a90083e9d1ab1c34422161593d6d7a669143217.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will drop struct
pwm_chip chip from struct atmel_tcb_pwm_chip. Use the pwm_chip as driver
data instead of the atmel_tcb_pwm_chip to get access to the pwm_chip in
the .suspend() and .resume() callbacks and atmel_tcb_pwm_remove()
without using tcbpwm->chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-atmel-tcb.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c
index 80121ab81a01..9d928e26b403 100644
--- a/drivers/pwm/pwm-atmel-tcb.c
+++ b/drivers/pwm/pwm-atmel-tcb.c
@@ -388,6 +388,7 @@ static const struct of_device_id atmel_tcb_of_match[] = {
 
 static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	const struct of_device_id *match;
 	struct atmel_tcb_pwm_chip *tcbpwm;
 	const struct atmel_tcb_config *config;
@@ -436,9 +437,10 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 		}
 	}
 
-	tcbpwm->chip.dev = &pdev->dev;
-	tcbpwm->chip.ops = &atmel_tcb_pwm_ops;
-	tcbpwm->chip.npwm = NPWM;
+	chip = &tcbpwm->chip;
+	chip->dev = &pdev->dev;
+	chip->ops = &atmel_tcb_pwm_ops;
+	chip->npwm = NPWM;
 	tcbpwm->channel = channel;
 	tcbpwm->width = config->counter_width;
 
@@ -448,11 +450,11 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 
 	spin_lock_init(&tcbpwm->lock);
 
-	err = pwmchip_add(&tcbpwm->chip);
+	err = pwmchip_add(chip);
 	if (err < 0)
 		goto err_disable_clk;
 
-	platform_set_drvdata(pdev, tcbpwm);
+	platform_set_drvdata(pdev, chip);
 
 	return 0;
 
@@ -473,9 +475,10 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 
 static void atmel_tcb_pwm_remove(struct platform_device *pdev)
 {
-	struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
+	struct pwm_chip *chip = platform_get_drvdata(pdev);
+	struct atmel_tcb_pwm_chip *tcbpwm = to_tcb_chip(chip);
 
-	pwmchip_remove(&tcbpwm->chip);
+	pwmchip_remove(chip);
 
 	clk_disable_unprepare(tcbpwm->slow_clk);
 	clk_put(tcbpwm->gclk);
@@ -491,7 +494,8 @@ MODULE_DEVICE_TABLE(of, atmel_tcb_pwm_dt_ids);
 
 static int atmel_tcb_pwm_suspend(struct device *dev)
 {
-	struct atmel_tcb_pwm_chip *tcbpwm = dev_get_drvdata(dev);
+	struct pwm_chip *chip = dev_get_drvdata(dev);
+	struct atmel_tcb_pwm_chip *tcbpwm = to_tcb_chip(chip);
 	struct atmel_tcb_channel *chan = &tcbpwm->bkup;
 	unsigned int channel = tcbpwm->channel;
 
@@ -505,7 +509,8 @@ static int atmel_tcb_pwm_suspend(struct device *dev)
 
 static int atmel_tcb_pwm_resume(struct device *dev)
 {
-	struct atmel_tcb_pwm_chip *tcbpwm = dev_get_drvdata(dev);
+	struct pwm_chip *chip = dev_get_drvdata(dev);
+	struct atmel_tcb_pwm_chip *tcbpwm = to_tcb_chip(chip);
 	struct atmel_tcb_channel *chan = &tcbpwm->bkup;
 	unsigned int channel = tcbpwm->channel;
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:47 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:47 +0100
Subject: [PATCH v6 060/164] pwm: lpc18xx-sct: Drop hardly used member from driver private data
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <427a719a24dd7ff5ebbac3e260a1773c094c7489.1707900770.git.u.kleine-koenig@pengutronix.de>

The device pointer is only used once in lpc18xx_pwm_request(). There the
pwm_chip is available, too, which has a pointer to the same structure.
Replace the usage accordingly and drop the then write-only member
variable.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-lpc18xx-sct.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
index fe891fa71a1d..754ea2c3f49b 100644
--- a/drivers/pwm/pwm-lpc18xx-sct.c
+++ b/drivers/pwm/pwm-lpc18xx-sct.c
@@ -92,7 +92,6 @@ struct lpc18xx_pwm_data {
 };
 
 struct lpc18xx_pwm_chip {
-	struct device *dev;
 	struct pwm_chip chip;
 	void __iomem *base;
 	struct clk *pwm_clk;
@@ -289,7 +288,7 @@ static int lpc18xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 				    LPC18XX_PWM_EVENT_MAX);
 
 	if (event >= LPC18XX_PWM_EVENT_MAX) {
-		dev_err(lpc18xx_pwm->dev,
+		dev_err(chip->dev,
 			"maximum number of simultaneous channels reached\n");
 		return -EBUSY;
 	}
@@ -358,8 +357,6 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
 	if (!lpc18xx_pwm)
 		return -ENOMEM;
 
-	lpc18xx_pwm->dev = &pdev->dev;
-
 	lpc18xx_pwm->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(lpc18xx_pwm->base))
 		return PTR_ERR(lpc18xx_pwm->base);
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:48 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:48 +0100
Subject: [PATCH v6 061/164] pwm: lpc18xx-sct: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <e4fb330c8dbf8fecd365afe3f8b33f8c7952eb38.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-lpc18xx-sct.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
index 754ea2c3f49b..46eeca27d9ab 100644
--- a/drivers/pwm/pwm-lpc18xx-sct.c
+++ b/drivers/pwm/pwm-lpc18xx-sct.c
@@ -197,7 +197,7 @@ static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	if (period_ns < lpc18xx_pwm->min_period_ns ||
 	    period_ns > lpc18xx_pwm->max_period_ns) {
-		dev_err(chip->dev, "period %d not in range\n", period_ns);
+		dev_err(pwmchip_parent(chip), "period %d not in range\n", period_ns);
 		return -ERANGE;
 	}
 
@@ -213,7 +213,7 @@ static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 */
 	if (requested_events > 2 && lpc18xx_pwm->period_ns != period_ns &&
 	    lpc18xx_pwm->period_ns) {
-		dev_err(chip->dev, "conflicting period requested for PWM %u\n",
+		dev_err(pwmchip_parent(chip), "conflicting period requested for PWM %u\n",
 			pwm->hwpwm);
 		mutex_unlock(&lpc18xx_pwm->period_lock);
 		return -EBUSY;
@@ -288,7 +288,7 @@ static int lpc18xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 				    LPC18XX_PWM_EVENT_MAX);
 
 	if (event >= LPC18XX_PWM_EVENT_MAX) {
-		dev_err(chip->dev,
+		dev_err(pwmchip_parent(chip),
 			"maximum number of simultaneous channels reached\n");
 		return -EBUSY;
 	}
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:50 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:50 +0100
Subject: [PATCH v6 063/164] pwm: lpc18xx-sct: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <d480891340e927705843cd09e5777d4daaa6c9cc.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-lpc18xx-sct driver to further changes of the pwm
core outlined in the commit introducing devm_pwmchip_alloc(). There is
no intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-lpc18xx-sct.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
index 9b1e8141aec7..04b76d257fd8 100644
--- a/drivers/pwm/pwm-lpc18xx-sct.c
+++ b/drivers/pwm/pwm-lpc18xx-sct.c
@@ -92,7 +92,6 @@ struct lpc18xx_pwm_data {
 };
 
 struct lpc18xx_pwm_chip {
-	struct pwm_chip chip;
 	void __iomem *base;
 	struct clk *pwm_clk;
 	unsigned long clk_rate;
@@ -109,7 +108,7 @@ struct lpc18xx_pwm_chip {
 static inline struct lpc18xx_pwm_chip *
 to_lpc18xx_pwm_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct lpc18xx_pwm_chip, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static inline void lpc18xx_pwm_writel(struct lpc18xx_pwm_chip *lpc18xx_pwm,
@@ -353,11 +352,10 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
 	int ret;
 	u64 val;
 
-	lpc18xx_pwm = devm_kzalloc(&pdev->dev, sizeof(*lpc18xx_pwm),
-				   GFP_KERNEL);
-	if (!lpc18xx_pwm)
-		return -ENOMEM;
-	chip = &lpc18xx_pwm->chip;
+	chip = devm_pwmchip_alloc(&pdev->dev, LPC18XX_NUM_PWMS, sizeof(*lpc18xx_pwm));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
 
 	lpc18xx_pwm->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(lpc18xx_pwm->base))
@@ -388,9 +386,7 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
 	lpc18xx_pwm->min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC,
 						  lpc18xx_pwm->clk_rate);
 
-	chip->dev = &pdev->dev;
 	chip->ops = &lpc18xx_pwm_ops;
-	chip->npwm = LPC18XX_NUM_PWMS;
 
 	/* SCT counter must be in unify (32 bit) mode */
 	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CONFIG,
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:30:54 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:30:54 +0100
Subject: [PATCH v6 007/164] pwm: apple: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <34cf20a82ca07bb4ec0578b193daa5caed37825e.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-apple driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-apple.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-apple.c b/drivers/pwm/pwm-apple.c
index 4d755b628d9e..6e58aca2f13c 100644
--- a/drivers/pwm/pwm-apple.c
+++ b/drivers/pwm/pwm-apple.c
@@ -32,14 +32,13 @@
 #define APPLE_PWM_CTRL_OUTPUT_ENABLE BIT(14)
 
 struct apple_pwm {
-	struct pwm_chip chip;
 	void __iomem *base;
 	u64 clkrate;
 };
 
 static inline struct apple_pwm *to_apple_pwm(struct pwm_chip *chip)
 {
-	return container_of(chip, struct apple_pwm, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int apple_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -103,13 +102,16 @@ static const struct pwm_ops apple_pwm_ops = {
 
 static int apple_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct apple_pwm *fpwm;
 	struct clk *clk;
 	int ret;
 
-	fpwm = devm_kzalloc(&pdev->dev, sizeof(*fpwm), GFP_KERNEL);
-	if (!fpwm)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*fpwm));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+
+	fpwm = to_apple_pwm(chip);
 
 	fpwm->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(fpwm->base))
@@ -129,11 +131,9 @@ static int apple_pwm_probe(struct platform_device *pdev)
 	if (fpwm->clkrate > NSEC_PER_SEC)
 		return dev_err_probe(&pdev->dev, -EINVAL, "pwm clock out of range");
 
-	fpwm->chip.dev = &pdev->dev;
-	fpwm->chip.npwm = 1;
-	fpwm->chip.ops = &apple_pwm_ops;
+	chip->ops = &apple_pwm_ops;
 
-	ret = devm_pwmchip_add(&pdev->dev, &fpwm->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0)
 		return dev_err_probe(&pdev->dev, ret, "unable to add pwm chip");
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:34 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:34 +0100
Subject: [PATCH v6 047/164] pwm: imx1: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <c6995e0d281255a7514edf9f25a561302dcaf65f.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-imx1 driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Also convert the to_pwm_imx1_chip() helper macro to a static inline to
get some type safety.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-imx1.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-imx1.c b/drivers/pwm/pwm-imx1.c
index d175d895f22a..1d2aae2d278f 100644
--- a/drivers/pwm/pwm-imx1.c
+++ b/drivers/pwm/pwm-imx1.c
@@ -28,10 +28,12 @@ struct pwm_imx1_chip {
 	struct clk *clk_ipg;
 	struct clk *clk_per;
 	void __iomem *mmio_base;
-	struct pwm_chip chip;
 };
 
-#define to_pwm_imx1_chip(chip)	container_of(chip, struct pwm_imx1_chip, chip)
+static inline struct pwm_imx1_chip *to_pwm_imx1_chip(struct pwm_chip *chip)
+{
+	return pwmchip_get_drvdata(chip);
+}
 
 static int pwm_imx1_clk_prepare_enable(struct pwm_chip *chip)
 {
@@ -156,11 +158,13 @@ MODULE_DEVICE_TABLE(of, pwm_imx1_dt_ids);
 
 static int pwm_imx1_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct pwm_imx1_chip *imx;
 
-	imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL);
-	if (!imx)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*imx));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	imx = to_pwm_imx1_chip(chip);
 
 	imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
 	if (IS_ERR(imx->clk_ipg))
@@ -172,15 +176,13 @@ static int pwm_imx1_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_per),
 				     "failed to get peripheral clock\n");
 
-	imx->chip.ops = &pwm_imx1_ops;
-	imx->chip.dev = &pdev->dev;
-	imx->chip.npwm = 1;
+	chip->ops = &pwm_imx1_ops;
 
 	imx->mmio_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(imx->mmio_base))
 		return PTR_ERR(imx->mmio_base);
 
-	return devm_pwmchip_add(&pdev->dev, &imx->chip);
+	return devm_pwmchip_add(&pdev->dev, chip);
 }
 
 static struct platform_driver pwm_imx1_driver = {
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:35 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:35 +0100
Subject: [PATCH v6 048/164] pwm: imx27: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <a8e3e3b3ea0684c9b289999c6f09eedbc2520f54.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-imx27.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
index 7d9bc43f12b0..5d796453519a 100644
--- a/drivers/pwm/pwm-imx27.c
+++ b/drivers/pwm/pwm-imx27.c
@@ -145,7 +145,7 @@ static int pwm_imx27_get_state(struct pwm_chip *chip,
 		state->polarity = PWM_POLARITY_INVERSED;
 		break;
 	default:
-		dev_warn(chip->dev, "can't set polarity, output disconnected");
+		dev_warn(pwmchip_parent(chip), "can't set polarity, output disconnected");
 	}
 
 	prescaler = MX3_PWMCR_PRESCALER_GET(val);
@@ -177,7 +177,7 @@ static int pwm_imx27_get_state(struct pwm_chip *chip,
 static void pwm_imx27_sw_reset(struct pwm_chip *chip)
 {
 	struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
-	struct device *dev = chip->dev;
+	struct device *dev = pwmchip_parent(chip);
 	int wait_count = 0;
 	u32 cr;
 
@@ -196,7 +196,7 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
 				     struct pwm_device *pwm)
 {
 	struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
-	struct device *dev = chip->dev;
+	struct device *dev = pwmchip_parent(chip);
 	unsigned int period_ms;
 	int fifoav;
 	u32 sr;
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:37 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:37 +0100
Subject: [PATCH v6 050/164] pwm: imx-tpm: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <5de5d53295fa445d58a79f83421dd3406166c3c6.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-tmp driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-imx-tpm.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c
index 9fc290e647e1..b04b974c5f32 100644
--- a/drivers/pwm/pwm-imx-tpm.c
+++ b/drivers/pwm/pwm-imx-tpm.c
@@ -57,7 +57,6 @@
 #define PWM_IMX_TPM_MOD_MOD	GENMASK(PWM_IMX_TPM_MOD_WIDTH - 1, 0)
 
 struct imx_tpm_pwm_chip {
-	struct pwm_chip chip;
 	struct clk *clk;
 	void __iomem *base;
 	struct mutex lock;
@@ -75,7 +74,7 @@ struct imx_tpm_pwm_param {
 static inline struct imx_tpm_pwm_chip *
 to_imx_tpm_pwm_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct imx_tpm_pwm_chip, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 /*
@@ -336,35 +335,40 @@ static const struct pwm_ops imx_tpm_pwm_ops = {
 
 static int pwm_imx_tpm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct imx_tpm_pwm_chip *tpm;
+	void __iomem *base;
 	int ret;
+	unsigned int npwm;
 	u32 val;
 
-	tpm = devm_kzalloc(&pdev->dev, sizeof(*tpm), GFP_KERNEL);
-	if (!tpm)
-		return -ENOMEM;
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	/* get number of channels */
+	val = readl(base + PWM_IMX_TPM_PARAM);
+	npwm = FIELD_GET(PWM_IMX_TPM_PARAM_CHAN, val);
+
+	chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*tpm));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	tpm = to_imx_tpm_pwm_chip(chip);
 
 	platform_set_drvdata(pdev, tpm);
 
-	tpm->base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(tpm->base))
-		return PTR_ERR(tpm->base);
+	tpm->base = base;
 
 	tpm->clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(tpm->clk))
 		return dev_err_probe(&pdev->dev, PTR_ERR(tpm->clk),
 				     "failed to get PWM clock\n");
 
-	tpm->chip.dev = &pdev->dev;
-	tpm->chip.ops = &imx_tpm_pwm_ops;
-
-	/* get number of channels */
-	val = readl(tpm->base + PWM_IMX_TPM_PARAM);
-	tpm->chip.npwm = FIELD_GET(PWM_IMX_TPM_PARAM_CHAN, val);
+	chip->ops = &imx_tpm_pwm_ops;
 
 	mutex_init(&tpm->lock);
 
-	ret = devm_pwmchip_add(&pdev->dev, &tpm->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret)
 		return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:36 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:36 +0100
Subject: [PATCH v6 049/164] pwm: imx27: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <3da748c80e9bbe29e7c119190dbc4bd67d159f22.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-imx27 driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Also convert the to_pwm_imx27_chip() helper macro to a static inline to
get some type safety.

Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-imx27.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
index 5d796453519a..54589f0b3b78 100644
--- a/drivers/pwm/pwm-imx27.c
+++ b/drivers/pwm/pwm-imx27.c
@@ -83,7 +83,6 @@ struct pwm_imx27_chip {
 	struct clk	*clk_ipg;
 	struct clk	*clk_per;
 	void __iomem	*mmio_base;
-	struct pwm_chip	chip;
 
 	/*
 	 * The driver cannot read the current duty cycle from the hardware if
@@ -93,7 +92,10 @@ struct pwm_imx27_chip {
 	unsigned int duty_cycle;
 };
 
-#define to_pwm_imx27_chip(chip)	container_of(chip, struct pwm_imx27_chip, chip)
+static inline struct pwm_imx27_chip *to_pwm_imx27_chip(struct pwm_chip *chip)
+{
+	return pwmchip_get_drvdata(chip);
+}
 
 static int pwm_imx27_clk_prepare_enable(struct pwm_imx27_chip *imx)
 {
@@ -306,13 +308,15 @@ MODULE_DEVICE_TABLE(of, pwm_imx27_dt_ids);
 
 static int pwm_imx27_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct pwm_imx27_chip *imx;
 	int ret;
 	u32 pwmcr;
 
-	imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL);
-	if (imx == NULL)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*imx));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	imx = to_pwm_imx27_chip(chip);
 
 	imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
 	if (IS_ERR(imx->clk_ipg))
@@ -324,9 +328,7 @@ static int pwm_imx27_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_per),
 				     "failed to get peripheral clock\n");
 
-	imx->chip.ops = &pwm_imx27_ops;
-	imx->chip.dev = &pdev->dev;
-	imx->chip.npwm = 1;
+	chip->ops = &pwm_imx27_ops;
 
 	imx->mmio_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(imx->mmio_base))
@@ -341,7 +343,7 @@ static int pwm_imx27_probe(struct platform_device *pdev)
 	if (!(pwmcr & MX3_PWMCR_EN))
 		pwm_imx27_clk_disable_unprepare(imx);
 
-	return devm_pwmchip_add(&pdev->dev, &imx->chip);
+	return devm_pwmchip_add(&pdev->dev, chip);
 }
 
 static struct platform_driver imx_pwm_driver = {
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:49 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:49 +0100
Subject: [PATCH v6 062/164] pwm: lpc18xx-sct: Prepare removing pwm_chip from driver data
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <b7bf8c421ff754ec3e985ec6235f4ddd6e5e27a4.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will drop struct
pwm_chip chip from struct lpc18xx_pwm_chip. Use the pwm_chip as driver
data instead of the lpc18xx_pwm_chip to get access to the pwm_chip in
lpc18xx_pwm_remove() without using lpc18xx_pwm->chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-lpc18xx-sct.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
index 46eeca27d9ab..9b1e8141aec7 100644
--- a/drivers/pwm/pwm-lpc18xx-sct.c
+++ b/drivers/pwm/pwm-lpc18xx-sct.c
@@ -348,6 +348,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_pwm_of_match);
 
 static int lpc18xx_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct lpc18xx_pwm_chip *lpc18xx_pwm;
 	int ret;
 	u64 val;
@@ -356,6 +357,7 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
 				   GFP_KERNEL);
 	if (!lpc18xx_pwm)
 		return -ENOMEM;
+	chip = &lpc18xx_pwm->chip;
 
 	lpc18xx_pwm->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(lpc18xx_pwm->base))
@@ -386,9 +388,9 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
 	lpc18xx_pwm->min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC,
 						  lpc18xx_pwm->clk_rate);
 
-	lpc18xx_pwm->chip.dev = &pdev->dev;
-	lpc18xx_pwm->chip.ops = &lpc18xx_pwm_ops;
-	lpc18xx_pwm->chip.npwm = LPC18XX_NUM_PWMS;
+	chip->dev = &pdev->dev;
+	chip->ops = &lpc18xx_pwm_ops;
+	chip->npwm = LPC18XX_NUM_PWMS;
 
 	/* SCT counter must be in unify (32 bit) mode */
 	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CONFIG,
@@ -420,21 +422,22 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
 	val |= LPC18XX_PWM_PRE(0);
 	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL, val);
 
-	ret = pwmchip_add(&lpc18xx_pwm->chip);
+	ret = pwmchip_add(chip);
 	if (ret < 0)
 		return dev_err_probe(&pdev->dev, ret, "pwmchip_add failed\n");
 
-	platform_set_drvdata(pdev, lpc18xx_pwm);
+	platform_set_drvdata(pdev, chip);
 
 	return 0;
 }
 
 static void lpc18xx_pwm_remove(struct platform_device *pdev)
 {
-	struct lpc18xx_pwm_chip *lpc18xx_pwm = platform_get_drvdata(pdev);
+	struct pwm_chip *chip = platform_get_drvdata(pdev);
+	struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
 	u32 val;
 
-	pwmchip_remove(&lpc18xx_pwm->chip);
+	pwmchip_remove(chip);
 
 	val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
 	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL,
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:51 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:51 +0100
Subject: [PATCH v6 064/164] pwm: lpc32xx: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <ef26238772ee9ca455a49e9b976a4f66654b26f7.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-lpc32xx driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Also convert the to_lpc32xx_pwm_chip() helper macro to a static inline
to get some type safety.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-lpc32xx.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c
index 1d9f3e7a2434..c748537e57d1 100644
--- a/drivers/pwm/pwm-lpc32xx.c
+++ b/drivers/pwm/pwm-lpc32xx.c
@@ -15,7 +15,6 @@
 #include <linux/slab.h>
 
 struct lpc32xx_pwm_chip {
-	struct pwm_chip chip;
 	struct clk *clk;
 	void __iomem *base;
 };
@@ -23,8 +22,10 @@ struct lpc32xx_pwm_chip {
 #define PWM_ENABLE	BIT(31)
 #define PWM_PIN_LEVEL	BIT(30)
 
-#define to_lpc32xx_pwm_chip(_chip) \
-	container_of(_chip, struct lpc32xx_pwm_chip, chip)
+static inline struct lpc32xx_pwm_chip *to_lpc32xx_pwm_chip(struct pwm_chip *chip)
+{
+	return pwmchip_get_drvdata(chip);
+}
 
 static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			      int duty_ns, int period_ns)
@@ -119,13 +120,15 @@ static const struct pwm_ops lpc32xx_pwm_ops = {
 
 static int lpc32xx_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct lpc32xx_pwm_chip *lpc32xx;
 	int ret;
 	u32 val;
 
-	lpc32xx = devm_kzalloc(&pdev->dev, sizeof(*lpc32xx), GFP_KERNEL);
-	if (!lpc32xx)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*lpc32xx));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	lpc32xx = to_lpc32xx_pwm_chip(chip);
 
 	lpc32xx->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(lpc32xx->base))
@@ -135,16 +138,14 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
 	if (IS_ERR(lpc32xx->clk))
 		return PTR_ERR(lpc32xx->clk);
 
-	lpc32xx->chip.dev = &pdev->dev;
-	lpc32xx->chip.ops = &lpc32xx_pwm_ops;
-	lpc32xx->chip.npwm = 1;
+	chip->ops = &lpc32xx_pwm_ops;
 
 	/* If PWM is disabled, configure the output to the default value */
 	val = readl(lpc32xx->base);
 	val &= ~PWM_PIN_LEVEL;
 	writel(val, lpc32xx->base);
 
-	ret = devm_pwmchip_add(&pdev->dev, &lpc32xx->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to add PWM chip, error %d\n", ret);
 		return ret;
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:02 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:02 +0100
Subject: [PATCH v6 075/164] pwm: mtk-disp: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <a70bf253dc41c61d9b901423710c97f235e372c3.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-mtk-disp driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-mtk-disp.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index 186aa5c04435..bafd6b6195f6 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -42,7 +42,6 @@ struct mtk_pwm_data {
 };
 
 struct mtk_disp_pwm {
-	struct pwm_chip chip;
 	const struct mtk_pwm_data *data;
 	struct clk *clk_main;
 	struct clk *clk_mm;
@@ -52,7 +51,7 @@ struct mtk_disp_pwm {
 
 static inline struct mtk_disp_pwm *to_mtk_disp_pwm(struct pwm_chip *chip)
 {
-	return container_of(chip, struct mtk_disp_pwm, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static void mtk_disp_pwm_update_bits(struct mtk_disp_pwm *mdp, u32 offset,
@@ -231,12 +230,14 @@ static const struct pwm_ops mtk_disp_pwm_ops = {
 
 static int mtk_disp_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct mtk_disp_pwm *mdp;
 	int ret;
 
-	mdp = devm_kzalloc(&pdev->dev, sizeof(*mdp), GFP_KERNEL);
-	if (!mdp)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*mdp));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	mdp = to_mtk_disp_pwm(chip);
 
 	mdp->data = of_device_get_match_data(&pdev->dev);
 
@@ -254,11 +255,9 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, PTR_ERR(mdp->clk_mm),
 				     "Failed to get mm clock\n");
 
-	mdp->chip.dev = &pdev->dev;
-	mdp->chip.ops = &mtk_disp_pwm_ops;
-	mdp->chip.npwm = 1;
+	chip->ops = &mtk_disp_pwm_ops;
 
-	ret = devm_pwmchip_add(&pdev->dev, &mdp->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0)
 		return dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n");
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:58 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:58 +0100
Subject: [PATCH v6 071/164] pwm: meson: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <02d5f32001c4d0817fa79f5831cfd16b7e345f00.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-meson.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 7ce41811537d..8f67d6ba443d 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -122,7 +122,7 @@ static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct meson_pwm *meson = to_meson_pwm(chip);
 	struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
-	struct device *dev = chip->dev;
+	struct device *dev = pwmchip_parent(chip);
 	int err;
 
 	err = clk_prepare_enable(channel->clk);
@@ -170,19 +170,19 @@ static int meson_pwm_calc(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	fin_freq = clk_round_rate(channel->clk, freq);
 	if (fin_freq == 0) {
-		dev_err(chip->dev, "invalid source clock frequency\n");
+		dev_err(pwmchip_parent(chip), "invalid source clock frequency\n");
 		return -EINVAL;
 	}
 
-	dev_dbg(chip->dev, "fin_freq: %lu Hz\n", fin_freq);
+	dev_dbg(pwmchip_parent(chip), "fin_freq: %lu Hz\n", fin_freq);
 
 	cnt = div_u64(fin_freq * period, NSEC_PER_SEC);
 	if (cnt > 0xffff) {
-		dev_err(chip->dev, "unable to get period cnt\n");
+		dev_err(pwmchip_parent(chip), "unable to get period cnt\n");
 		return -EINVAL;
 	}
 
-	dev_dbg(chip->dev, "period=%llu cnt=%u\n", period, cnt);
+	dev_dbg(pwmchip_parent(chip), "period=%llu cnt=%u\n", period, cnt);
 
 	if (duty == period) {
 		channel->hi = cnt;
@@ -193,7 +193,7 @@ static int meson_pwm_calc(struct pwm_chip *chip, struct pwm_device *pwm,
 	} else {
 		duty_cnt = div_u64(fin_freq * duty, NSEC_PER_SEC);
 
-		dev_dbg(chip->dev, "duty=%llu duty_cnt=%u\n", duty, duty_cnt);
+		dev_dbg(pwmchip_parent(chip), "duty=%llu duty_cnt=%u\n", duty, duty_cnt);
 
 		channel->hi = duty_cnt;
 		channel->lo = cnt - duty_cnt;
@@ -217,7 +217,7 @@ static void meson_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 
 	err = clk_set_rate(channel->clk, channel->rate);
 	if (err)
-		dev_err(chip->dev, "setting clock rate failed\n");
+		dev_err(pwmchip_parent(chip), "setting clock rate failed\n");
 
 	spin_lock_irqsave(&meson->lock, flags);
 
@@ -439,7 +439,7 @@ static int meson_pwm_init_channels(struct pwm_chip *chip)
 {
 	struct meson_pwm *meson = to_meson_pwm(chip);
 	struct clk_parent_data mux_parent_data[MESON_MAX_MUX_PARENTS] = {};
-	struct device *dev = chip->dev;
+	struct device *dev = pwmchip_parent(chip);
 	unsigned int i;
 	char name[255];
 	int err;
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:57 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:57 +0100
Subject: [PATCH v6 070/164] pwm: meson: Change prototype of a few helpers to prepare further changes
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <157084e1dd464da0097edba880240868c1c0b27e.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will make it harder to
determine the pwm_chip from a given meson_pwm. To just not have to do
that, rework meson_pwm_calc(), meson_pwm_enable(), meson_pwm_disable()
and meson_pwm_init_channels() to take a pwm_chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-meson.c | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 2971bbf3b5e7..7ce41811537d 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -143,9 +143,10 @@ static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
 	clk_disable_unprepare(channel->clk);
 }
 
-static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
+static int meson_pwm_calc(struct pwm_chip *chip, struct pwm_device *pwm,
 			  const struct pwm_state *state)
 {
+	struct meson_pwm *meson = to_meson_pwm(chip);
 	struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
 	unsigned int cnt, duty_cnt;
 	unsigned long fin_freq;
@@ -169,19 +170,19 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
 
 	fin_freq = clk_round_rate(channel->clk, freq);
 	if (fin_freq == 0) {
-		dev_err(meson->chip.dev, "invalid source clock frequency\n");
+		dev_err(chip->dev, "invalid source clock frequency\n");
 		return -EINVAL;
 	}
 
-	dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq);
+	dev_dbg(chip->dev, "fin_freq: %lu Hz\n", fin_freq);
 
 	cnt = div_u64(fin_freq * period, NSEC_PER_SEC);
 	if (cnt > 0xffff) {
-		dev_err(meson->chip.dev, "unable to get period cnt\n");
+		dev_err(chip->dev, "unable to get period cnt\n");
 		return -EINVAL;
 	}
 
-	dev_dbg(meson->chip.dev, "period=%llu cnt=%u\n", period, cnt);
+	dev_dbg(chip->dev, "period=%llu cnt=%u\n", period, cnt);
 
 	if (duty == period) {
 		channel->hi = cnt;
@@ -192,7 +193,7 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
 	} else {
 		duty_cnt = div_u64(fin_freq * duty, NSEC_PER_SEC);
 
-		dev_dbg(meson->chip.dev, "duty=%llu duty_cnt=%u\n", duty, duty_cnt);
+		dev_dbg(chip->dev, "duty=%llu duty_cnt=%u\n", duty, duty_cnt);
 
 		channel->hi = duty_cnt;
 		channel->lo = cnt - duty_cnt;
@@ -203,8 +204,9 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
 	return 0;
 }
 
-static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
+static void meson_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
+	struct meson_pwm *meson = to_meson_pwm(chip);
 	struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
 	struct meson_pwm_channel_data *channel_data;
 	unsigned long flags;
@@ -215,7 +217,7 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
 
 	err = clk_set_rate(channel->clk, channel->rate);
 	if (err)
-		dev_err(meson->chip.dev, "setting clock rate failed\n");
+		dev_err(chip->dev, "setting clock rate failed\n");
 
 	spin_lock_irqsave(&meson->lock, flags);
 
@@ -230,8 +232,9 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
 	spin_unlock_irqrestore(&meson->lock, flags);
 }
 
-static void meson_pwm_disable(struct meson_pwm *meson, struct pwm_device *pwm)
+static void meson_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
+	struct meson_pwm *meson = to_meson_pwm(chip);
 	unsigned long flags;
 	u32 value;
 
@@ -269,16 +272,16 @@ static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			channel->hi = ~0;
 			channel->lo = 0;
 
-			meson_pwm_enable(meson, pwm);
+			meson_pwm_enable(chip, pwm);
 		} else {
-			meson_pwm_disable(meson, pwm);
+			meson_pwm_disable(chip, pwm);
 		}
 	} else {
-		err = meson_pwm_calc(meson, pwm, state);
+		err = meson_pwm_calc(chip, pwm, state);
 		if (err < 0)
 			return err;
 
-		meson_pwm_enable(meson, pwm);
+		meson_pwm_enable(chip, pwm);
 	}
 
 	return 0;
@@ -432,10 +435,11 @@ static const struct of_device_id meson_pwm_matches[] = {
 };
 MODULE_DEVICE_TABLE(of, meson_pwm_matches);
 
-static int meson_pwm_init_channels(struct meson_pwm *meson)
+static int meson_pwm_init_channels(struct pwm_chip *chip)
 {
+	struct meson_pwm *meson = to_meson_pwm(chip);
 	struct clk_parent_data mux_parent_data[MESON_MAX_MUX_PARENTS] = {};
-	struct device *dev = meson->chip.dev;
+	struct device *dev = chip->dev;
 	unsigned int i;
 	char name[255];
 	int err;
@@ -445,7 +449,7 @@ static int meson_pwm_init_channels(struct meson_pwm *meson)
 		mux_parent_data[i].name = meson->data->parent_names[i];
 	}
 
-	for (i = 0; i < meson->chip.npwm; i++) {
+	for (i = 0; i < chip->npwm; i++) {
 		struct meson_pwm_channel *channel = &meson->channels[i];
 		struct clk_parent_data div_parent = {}, gate_parent = {};
 		struct clk_init_data init = {};
@@ -543,7 +547,7 @@ static int meson_pwm_probe(struct platform_device *pdev)
 
 	meson->data = of_device_get_match_data(&pdev->dev);
 
-	err = meson_pwm_init_channels(meson);
+	err = meson_pwm_init_channels(&meson->chip);
 	if (err < 0)
 		return err;
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:56 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:56 +0100
Subject: [PATCH v6 069/164] pwm: mediatek: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <513b2037c00ebf2f3a69472f4b99adaf4fb40d83.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-mediatek driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-mediatek.c | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 6cf7543a3826..c5fca0f1ebc7 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -42,7 +42,6 @@ struct pwm_mediatek_of_data {
 
 /**
  * struct pwm_mediatek_chip - struct representing PWM chip
- * @chip: linux PWM chip representation
  * @regs: base address of PWM chip
  * @clk_top: the top clock generator
  * @clk_main: the clock used by PWM core
@@ -50,7 +49,6 @@ struct pwm_mediatek_of_data {
  * @soc: pointer to chip's platform data
  */
 struct pwm_mediatek_chip {
-	struct pwm_chip chip;
 	void __iomem *regs;
 	struct clk *clk_top;
 	struct clk *clk_main;
@@ -69,7 +67,7 @@ static const unsigned int mtk_pwm_reg_offset_v2[] = {
 static inline struct pwm_mediatek_chip *
 to_pwm_mediatek_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct pwm_mediatek_chip, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int pwm_mediatek_clk_enable(struct pwm_chip *chip,
@@ -232,21 +230,26 @@ static const struct pwm_ops pwm_mediatek_ops = {
 
 static int pwm_mediatek_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct pwm_mediatek_chip *pc;
+	const struct pwm_mediatek_of_data *soc;
 	unsigned int i;
 	int ret;
 
-	pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
-	if (!pc)
-		return -ENOMEM;
+	soc = of_device_get_match_data(&pdev->dev);
 
-	pc->soc = of_device_get_match_data(&pdev->dev);
+	chip = devm_pwmchip_alloc(&pdev->dev, soc->num_pwms, sizeof(*pc));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	pc = to_pwm_mediatek_chip(chip);
+
+	pc->soc = soc;
 
 	pc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(pc->regs))
 		return PTR_ERR(pc->regs);
 
-	pc->clk_pwms = devm_kmalloc_array(&pdev->dev, pc->soc->num_pwms,
+	pc->clk_pwms = devm_kmalloc_array(&pdev->dev, soc->num_pwms,
 				    sizeof(*pc->clk_pwms), GFP_KERNEL);
 	if (!pc->clk_pwms)
 		return -ENOMEM;
@@ -261,7 +264,7 @@ static int pwm_mediatek_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk_main),
 				     "Failed to get main clock\n");
 
-	for (i = 0; i < pc->soc->num_pwms; i++) {
+	for (i = 0; i < soc->num_pwms; i++) {
 		char name[8];
 
 		snprintf(name, sizeof(name), "pwm%d", i + 1);
@@ -272,11 +275,9 @@ static int pwm_mediatek_probe(struct platform_device *pdev)
 					     "Failed to get %s clock\n", name);
 	}
 
-	pc->chip.dev = &pdev->dev;
-	pc->chip.ops = &pwm_mediatek_ops;
-	pc->chip.npwm = pc->soc->num_pwms;
+	chip->ops = &pwm_mediatek_ops;
 
-	ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0)
 		return dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n");
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:18 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:18 +0100
Subject: [PATCH v6 091/164] pwm: rochchip: Prepare removing pwm_chip from driver data
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <301657442c578cc8d330ad2b07463d59fed4bff6.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will drop struct
pwm_chip chip from struct rockchip_pwm_chip. Use the pwm_chip as driver
data instead of the rockchip_pwm_chip to get access to the pwm_chip in
rockchip_pwm_remove() without using pc->chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-rockchip.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index a7c647e37837..c001eb6b17ae 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -296,6 +296,7 @@ MODULE_DEVICE_TABLE(of, rockchip_pwm_dt_ids);
 
 static int rockchip_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct rockchip_pwm_chip *pc;
 	u32 enable_conf, ctrl;
 	bool enabled;
@@ -304,6 +305,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
 	pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
 	if (!pc)
 		return -ENOMEM;
+	chip = &pc->chip;
 
 	pc->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(pc->base))
@@ -337,18 +339,18 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
 		goto err_clk;
 	}
 
-	platform_set_drvdata(pdev, pc);
+	platform_set_drvdata(pdev, chip);
 
 	pc->data = device_get_match_data(&pdev->dev);
-	pc->chip.dev = &pdev->dev;
-	pc->chip.ops = &rockchip_pwm_ops;
-	pc->chip.npwm = 1;
+	chip->dev = &pdev->dev;
+	chip->ops = &rockchip_pwm_ops;
+	chip->npwm = 1;
 
 	enable_conf = pc->data->enable_conf;
 	ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
 	enabled = (ctrl & enable_conf) == enable_conf;
 
-	ret = pwmchip_add(&pc->chip);
+	ret = pwmchip_add(chip);
 	if (ret < 0) {
 		dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n");
 		goto err_pclk;
@@ -372,9 +374,10 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
 
 static void rockchip_pwm_remove(struct platform_device *pdev)
 {
-	struct rockchip_pwm_chip *pc = platform_get_drvdata(pdev);
+	struct pwm_chip *chip = platform_get_drvdata(pdev);
+	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
 
-	pwmchip_remove(&pc->chip);
+	pwmchip_remove(chip);
 
 	clk_unprepare(pc->pclk);
 	clk_unprepare(pc->clk);
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:59 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:59 +0100
Subject: [PATCH v6 072/164] pwm: meson: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <6cc57880e910e6ffd8df15bc4a41c42fe9523293.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-meson driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-meson.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 8f67d6ba443d..40a5b64c26f5 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -102,7 +102,6 @@ struct meson_pwm_data {
 };
 
 struct meson_pwm {
-	struct pwm_chip chip;
 	const struct meson_pwm_data *data;
 	struct meson_pwm_channel channels[MESON_NUM_PWMS];
 	void __iomem *base;
@@ -115,7 +114,7 @@ struct meson_pwm {
 
 static inline struct meson_pwm *to_meson_pwm(struct pwm_chip *chip)
 {
-	return container_of(chip, struct meson_pwm, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
@@ -529,29 +528,29 @@ static int meson_pwm_init_channels(struct pwm_chip *chip)
 
 static int meson_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct meson_pwm *meson;
 	int err;
 
-	meson = devm_kzalloc(&pdev->dev, sizeof(*meson), GFP_KERNEL);
-	if (!meson)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, MESON_NUM_PWMS, sizeof(*meson));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	meson = to_meson_pwm(chip);
 
 	meson->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(meson->base))
 		return PTR_ERR(meson->base);
 
 	spin_lock_init(&meson->lock);
-	meson->chip.dev = &pdev->dev;
-	meson->chip.ops = &meson_pwm_ops;
-	meson->chip.npwm = MESON_NUM_PWMS;
+	chip->ops = &meson_pwm_ops;
 
 	meson->data = of_device_get_match_data(&pdev->dev);
 
-	err = meson_pwm_init_channels(&meson->chip);
+	err = meson_pwm_init_channels(chip);
 	if (err < 0)
 		return err;
 
-	err = devm_pwmchip_add(&pdev->dev, &meson->chip);
+	err = devm_pwmchip_add(&pdev->dev, chip);
 	if (err < 0)
 		return dev_err_probe(&pdev->dev, err,
 				     "failed to register PWM chip\n");
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:19 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:19 +0100
Subject: [PATCH v6 092/164] pwm: rockchip: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <61a3f48710e3e795beb2e496c8c673bbc0f6c932.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-rockchip driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-rockchip.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index c001eb6b17ae..0fa7575dbb54 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -30,7 +30,6 @@
 #define PWM_LP_DISABLE		(0 << 8)
 
 struct rockchip_pwm_chip {
-	struct pwm_chip chip;
 	struct clk *clk;
 	struct clk *pclk;
 	const struct rockchip_pwm_data *data;
@@ -54,7 +53,7 @@ struct rockchip_pwm_data {
 
 static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct rockchip_pwm_chip, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int rockchip_pwm_get_state(struct pwm_chip *chip,
@@ -302,10 +301,10 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
 	bool enabled;
 	int ret, count;
 
-	pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
-	if (!pc)
-		return -ENOMEM;
-	chip = &pc->chip;
+	chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*pc));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	pc = to_rockchip_pwm_chip(chip);
 
 	pc->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(pc->base))
@@ -342,9 +341,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, chip);
 
 	pc->data = device_get_match_data(&pdev->dev);
-	chip->dev = &pdev->dev;
 	chip->ops = &rockchip_pwm_ops;
-	chip->npwm = 1;
 
 	enable_conf = pc->data->enable_conf;
 	ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:01 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:01 +0100
Subject: [PATCH v6 074/164] pwm: mtk-disp: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <93ba7ef22f8d26f17e64326249d5da54ab8014ea.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-mtk-disp.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index a72f7be36996..186aa5c04435 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -91,14 +91,14 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	if (!mdp->enabled) {
 		err = clk_prepare_enable(mdp->clk_main);
 		if (err < 0) {
-			dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n",
+			dev_err(pwmchip_parent(chip), "Can't enable mdp->clk_main: %pe\n",
 				ERR_PTR(err));
 			return err;
 		}
 
 		err = clk_prepare_enable(mdp->clk_mm);
 		if (err < 0) {
-			dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n",
+			dev_err(pwmchip_parent(chip), "Can't enable mdp->clk_mm: %pe\n",
 				ERR_PTR(err));
 			clk_disable_unprepare(mdp->clk_main);
 			return err;
@@ -181,13 +181,13 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip,
 
 	err = clk_prepare_enable(mdp->clk_main);
 	if (err < 0) {
-		dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
+		dev_err(pwmchip_parent(chip), "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
 		return err;
 	}
 
 	err = clk_prepare_enable(mdp->clk_mm);
 	if (err < 0) {
-		dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
+		dev_err(pwmchip_parent(chip), "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
 		clk_disable_unprepare(mdp->clk_main);
 		return err;
 	}
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:43 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:43 +0100
Subject: [PATCH v6 116/164] pwm: stm32: Change prototype of helper that detects npwm to prepare further changes
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <13d4d3e90a9ee1bcd04674dfdc16f242615b8320.1707900770.git.u.kleine-koenig@pengutronix.de>

When the stm32 pwm driver is converted to pwmchip_alloc(), the number of
available PWM lines must be known before the driver private data can be
allocated. So rework the helper function that determines this number to
not take the driver private data struct as input parameter.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stm32.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index 4d12f3d849cd..1440b706ee57 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -606,7 +606,7 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
 	priv->have_complementary_output = (ccer != 0);
 }
 
-static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv,
+static unsigned int stm32_pwm_detect_channels(struct regmap *regmap,
 					      unsigned int *num_enabled)
 {
 	u32 ccer, ccer_backup;
@@ -615,10 +615,10 @@ static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv,
 	 * If channels enable bits don't exist writing 1 will have no
 	 * effect so we can detect and count them.
 	 */
-	regmap_read(priv->regmap, TIM_CCER, &ccer_backup);
-	regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE);
-	regmap_read(priv->regmap, TIM_CCER, &ccer);
-	regmap_write(priv->regmap, TIM_CCER, ccer_backup);
+	regmap_read(regmap, TIM_CCER, &ccer_backup);
+	regmap_set_bits(regmap, TIM_CCER, TIM_CCER_CCXE);
+	regmap_read(regmap, TIM_CCER, &ccer);
+	regmap_write(regmap, TIM_CCER, ccer_backup);
 
 	*num_enabled = hweight32(ccer_backup & TIM_CCER_CCXE);
 
@@ -657,7 +657,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 
 	chip->dev = dev;
 	chip->ops = &stm32pwm_ops;
-	chip->npwm = stm32_pwm_detect_channels(priv, &num_enabled);
+	chip->npwm = stm32_pwm_detect_channels(ddata->regmap, &num_enabled);
 
 	/* Initialize clock refcount to number of enabled PWM channels. */
 	for (i = 0; i < num_enabled; i++)
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:46 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:46 +0100
Subject: [PATCH v6 119/164] pwm: stm32-lp: Prepare removing pwm_chip from driver data
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <df47d1aff9b529c9a4762b6ba339a18cecba1497.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will drop struct
pwm_chip chip from struct stm32_pwm_lp. Use the pwm_chip as driver
data instead of the stm32_pwm_lp to get access to the pwm_chip in
stm32_pwm_lp_suspend() without using priv->chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stm32-lp.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
index bbab6be314a8..b46d8193dd0f 100644
--- a/drivers/pwm/pwm-stm32-lp.c
+++ b/drivers/pwm/pwm-stm32-lp.c
@@ -197,6 +197,7 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev)
 {
 	struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
 	struct stm32_pwm_lp *priv;
+	struct pwm_chip *chip;
 	int ret;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -205,28 +206,29 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev)
 
 	priv->regmap = ddata->regmap;
 	priv->clk = ddata->clk;
-	priv->chip.dev = &pdev->dev;
-	priv->chip.ops = &stm32_pwm_lp_ops;
-	priv->chip.npwm = 1;
+	chip = &priv->chip;
+	chip->dev = &pdev->dev;
+	chip->ops = &stm32_pwm_lp_ops;
+	chip->npwm = 1;
 
-	ret = devm_pwmchip_add(&pdev->dev, &priv->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0)
 		return ret;
 
-	platform_set_drvdata(pdev, priv);
+	platform_set_drvdata(pdev, chip);
 
 	return 0;
 }
 
 static int stm32_pwm_lp_suspend(struct device *dev)
 {
-	struct stm32_pwm_lp *priv = dev_get_drvdata(dev);
+	struct pwm_chip *chip = dev_get_drvdata(dev);
 	struct pwm_state state;
 
-	pwm_get_state(&priv->chip.pwms[0], &state);
+	pwm_get_state(&chip->pwms[0], &state);
 	if (state.enabled) {
 		dev_err(dev, "The consumer didn't stop us (%s)\n",
-			priv->chip.pwms[0].label);
+			chip->pwms[0].label);
 		return -EBUSY;
 	}
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:49 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:49 +0100
Subject: [PATCH v6 122/164] pwm: stmpe: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <2136fbdf9b1e6bac479b935b439e2be73a003b97.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stmpe.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/pwm/pwm-stmpe.c b/drivers/pwm/pwm-stmpe.c
index 19c0c0f39675..05f3f38031ee 100644
--- a/drivers/pwm/pwm-stmpe.c
+++ b/drivers/pwm/pwm-stmpe.c
@@ -44,7 +44,7 @@ static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 
 	ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS);
 	if (ret < 0) {
-		dev_dbg(chip->dev, "error reading PWM#%u control\n",
+		dev_dbg(pwmchip_parent(chip), "error reading PWM#%u control\n",
 			pwm->hwpwm);
 		return ret;
 	}
@@ -53,7 +53,7 @@ static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 
 	ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value);
 	if (ret) {
-		dev_dbg(chip->dev, "error writing PWM#%u control\n",
+		dev_dbg(pwmchip_parent(chip), "error writing PWM#%u control\n",
 			pwm->hwpwm);
 		return ret;
 	}
@@ -70,7 +70,7 @@ static int stmpe_24xx_pwm_disable(struct pwm_chip *chip,
 
 	ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS);
 	if (ret < 0) {
-		dev_dbg(chip->dev, "error reading PWM#%u control\n",
+		dev_dbg(pwmchip_parent(chip), "error reading PWM#%u control\n",
 			pwm->hwpwm);
 		return ret;
 	}
@@ -79,7 +79,7 @@ static int stmpe_24xx_pwm_disable(struct pwm_chip *chip,
 
 	ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value);
 	if (ret)
-		dev_dbg(chip->dev, "error writing PWM#%u control\n",
+		dev_dbg(pwmchip_parent(chip), "error writing PWM#%u control\n",
 			pwm->hwpwm);
 	return ret;
 }
@@ -125,7 +125,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		ret = stmpe_set_altfunc(stmpe_pwm->stmpe, BIT(pin),
 					STMPE_BLOCK_PWM);
 		if (ret) {
-			dev_err(chip->dev, "unable to connect PWM#%u to pin\n",
+			dev_err(pwmchip_parent(chip), "unable to connect PWM#%u to pin\n",
 				pwm->hwpwm);
 			return ret;
 		}
@@ -150,7 +150,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		return -ENODEV;
 	}
 
-	dev_dbg(chip->dev, "PWM#%u: config duty %d ns, period %d ns\n",
+	dev_dbg(pwmchip_parent(chip), "PWM#%u: config duty %d ns, period %d ns\n",
 		pwm->hwpwm, duty_ns, period_ns);
 
 	if (duty_ns == 0) {
@@ -216,7 +216,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			program[1] = BRANCH;
 		}
 
-		dev_dbg(chip->dev,
+		dev_dbg(pwmchip_parent(chip),
 			"PWM#%u: value = %02x, last_duty = %02x, program=%04x,%04x,%04x\n",
 			pwm->hwpwm, value, last, program[0], program[1],
 			program[2]);
@@ -233,7 +233,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 
 		ret = stmpe_reg_write(stmpe_pwm->stmpe, offset, value);
 		if (ret) {
-			dev_dbg(chip->dev, "error writing register %02x: %d\n",
+			dev_dbg(pwmchip_parent(chip), "error writing register %02x: %d\n",
 				offset, ret);
 			return ret;
 		}
@@ -242,7 +242,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 
 		ret = stmpe_reg_write(stmpe_pwm->stmpe, offset, value);
 		if (ret) {
-			dev_dbg(chip->dev, "error writing register %02x: %d\n",
+			dev_dbg(pwmchip_parent(chip), "error writing register %02x: %d\n",
 				offset, ret);
 			return ret;
 		}
@@ -255,7 +255,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	/* Sleep for 200ms so we're sure it will take effect */
 	msleep(200);
 
-	dev_dbg(chip->dev, "programmed PWM#%u, %u bytes\n", pwm->hwpwm, i);
+	dev_dbg(pwmchip_parent(chip), "programmed PWM#%u, %u bytes\n", pwm->hwpwm, i);
 
 	return 0;
 }
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:26 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:26 +0100
Subject: [PATCH v6 099/164] pwm: samsung: Simplify by using devm functions in probe
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <d46ec625c14c460039082f74ec8ca3084b7c8e3a.1707900770.git.u.kleine-koenig@pengutronix.de>

With using devm_clk_get_enabled() and devm_pwmchip_add() the
.remove_new() callback can be dropped and an error path in .probe()
simplified.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-samsung.c | 22 ++--------------------
 1 file changed, 2 insertions(+), 20 deletions(-)

diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index cabdcdf37ec9..81a2e66e927e 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -577,18 +577,12 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 	if (IS_ERR(our_chip->base))
 		return PTR_ERR(our_chip->base);
 
-	our_chip->base_clk = devm_clk_get(&pdev->dev, "timers");
+	our_chip->base_clk = devm_clk_get_enabled(&pdev->dev, "timers");
 	if (IS_ERR(our_chip->base_clk)) {
 		dev_err(dev, "failed to get timer base clk\n");
 		return PTR_ERR(our_chip->base_clk);
 	}
 
-	ret = clk_prepare_enable(our_chip->base_clk);
-	if (ret < 0) {
-		dev_err(dev, "failed to enable base clock\n");
-		return ret;
-	}
-
 	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
 		if (our_chip->variant.output_mask & BIT(chan))
 			pwm_samsung_set_invert(our_chip, chan, true);
@@ -599,10 +593,9 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, chip);
 
-	ret = pwmchip_add(chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0) {
 		dev_err(dev, "failed to register PWM chip\n");
-		clk_disable_unprepare(our_chip->base_clk);
 		return ret;
 	}
 
@@ -614,16 +607,6 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static void pwm_samsung_remove(struct platform_device *pdev)
-{
-	struct pwm_chip *chip = platform_get_drvdata(pdev);
-	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
-
-	pwmchip_remove(chip);
-
-	clk_disable_unprepare(our_chip->base_clk);
-}
-
 static int pwm_samsung_resume(struct device *dev)
 {
 	struct pwm_chip *chip = dev_get_drvdata(dev);
@@ -666,7 +649,6 @@ static struct platform_driver pwm_samsung_driver = {
 		.of_match_table = of_match_ptr(samsung_pwm_matches),
 	},
 	.probe		= pwm_samsung_probe,
-	.remove_new	= pwm_samsung_remove,
 };
 module_platform_driver(pwm_samsung_driver);
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:51 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:51 +0100
Subject: [PATCH v6 124/164] pwm: sun4i: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <3ddaec73f3abefb45625d0a469026fa8d13da8c0.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-sun4i.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 1a439025540d..44edf1ce5739 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -245,7 +245,7 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	if (!cstate.enabled) {
 		ret = clk_prepare_enable(sun4i_pwm->clk);
 		if (ret) {
-			dev_err(chip->dev, "failed to enable PWM clock\n");
+			dev_err(pwmchip_parent(chip), "failed to enable PWM clock\n");
 			return ret;
 		}
 	}
@@ -253,7 +253,7 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler,
 				  &bypass);
 	if (ret) {
-		dev_err(chip->dev, "period exceeds the maximum value\n");
+		dev_err(pwmchip_parent(chip), "period exceeds the maximum value\n");
 		if (!cstate.enabled)
 			clk_disable_unprepare(sun4i_pwm->clk);
 		return ret;
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:33:15 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:33:15 +0100
Subject: [PATCH v6 148/164] pwm: vt8500: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <b203c4448db23ebad1165b7bce43ac41468c4e89.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-vt8500 driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Also convert the to_vt8500_chip() helper macro to a static inline to
get some type safety.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-vt8500.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c
index fb4dbc88b0a3..016c82d65527 100644
--- a/drivers/pwm/pwm-vt8500.c
+++ b/drivers/pwm/pwm-vt8500.c
@@ -45,12 +45,14 @@
 #define STATUS_ALL_UPDATE	0x0F
 
 struct vt8500_chip {
-	struct pwm_chip chip;
 	void __iomem *base;
 	struct clk *clk;
 };
 
-#define to_vt8500_chip(chip)	container_of(chip, struct vt8500_chip, chip)
+static inline struct vt8500_chip *to_vt8500_chip(struct pwm_chip *chip)
+{
+	return pwmchip_get_drvdata(chip);
+}
 
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
 static inline void vt8500_pwm_busy_wait(struct pwm_chip *chip, int nr, u8 bitmask)
@@ -240,14 +242,12 @@ static int vt8500_pwm_probe(struct platform_device *pdev)
 	if (!np)
 		return dev_err_probe(&pdev->dev, -EINVAL, "invalid devicetree node\n");
 
-	vt8500 = devm_kzalloc(&pdev->dev, sizeof(*vt8500), GFP_KERNEL);
-	if (vt8500 == NULL)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, VT8500_NR_PWMS, sizeof(*vt8500));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	vt8500 = to_vt8500_chip(chip);
 
-	chip = &vt8500->chip;
-	chip->dev = &pdev->dev;
 	chip->ops = &vt8500_pwm_ops;
-	chip->npwm = VT8500_NR_PWMS;
 
 	vt8500->clk = devm_clk_get_prepared(&pdev->dev, NULL);
 	if (IS_ERR(vt8500->clk))
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:45 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:45 +0100
Subject: [PATCH v6 118/164] pwm: stm32-lp: Simplify code to determine the pwmchip's parent device
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <9ad2399e1a683a6344b12d7f70498393b8f8b9de.1707900770.git.u.kleine-koenig@pengutronix.de>

There is already a pointer to the pwmchip, make use of it directly
instead of using the struct stm32_pwm_lp *priv just obtained from
it. This also has the advantage of not using struct stm32_pwm_lp::chip
any more which will be dropped soon.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stm32-lp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
index 439068f3eca1..bbab6be314a8 100644
--- a/drivers/pwm/pwm-stm32-lp.c
+++ b/drivers/pwm/pwm-stm32-lp.c
@@ -61,7 +61,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	do_div(div, NSEC_PER_SEC);
 	if (!div) {
 		/* Clock is too slow to achieve requested period. */
-		dev_dbg(priv->chip.dev, "Can't reach %llu ns\n", state->period);
+		dev_dbg(chip->dev, "Can't reach %llu ns\n", state->period);
 		return -EINVAL;
 	}
 
@@ -69,7 +69,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	while (div > STM32_LPTIM_MAX_ARR) {
 		presc++;
 		if ((1 << presc) > STM32_LPTIM_MAX_PRESCALER) {
-			dev_err(priv->chip.dev, "max prescaler exceeded\n");
+			dev_err(chip->dev, "max prescaler exceeded\n");
 			return -EINVAL;
 		}
 		div = prd >> presc;
@@ -130,7 +130,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 				       (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
 				       100, 1000);
 	if (ret) {
-		dev_err(priv->chip.dev, "ARR/CMP registers write issue\n");
+		dev_err(chip->dev, "ARR/CMP registers write issue\n");
 		goto err;
 	}
 	ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:41 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:41 +0100
Subject: [PATCH v6 114/164] pwm: stm32: Change prototype of a helper to prepare further changes
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <33790c64563cb0434d7156d96f189c6037b3eb0b.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will make it harder to
determine the pwm_chip from a given stm32_pwm. To just not have to do
that, rework stm32_pwm_raw_capture() to take a pwm_chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stm32.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index 202114c00ad3..ec15bc51d930 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -90,11 +90,12 @@ static u32 active_channels(struct stm32_pwm *dev)
  * - Period     = t2 - t0
  * - Duty cycle = t1 - t0
  */
-static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm,
+static int stm32_pwm_raw_capture(struct pwm_chip *chip, struct pwm_device *pwm,
 				 unsigned long tmo_ms, u32 *raw_prd,
 				 u32 *raw_dty)
 {
-	struct device *parent = priv->chip.dev->parent;
+	struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
+	struct device *parent = pwmchip_parent(chip)->parent;
 	enum stm32_timers_dmas dma_id;
 	u32 ccen, ccr;
 	int ret;
@@ -170,7 +171,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	ret = clk_enable(priv->clk);
 	if (ret) {
-		dev_err(chip->dev, "failed to enable counter clock\n");
+		dev_err(pwmchip_parent(chip), "failed to enable counter clock\n");
 		goto unlock;
 	}
 
@@ -208,7 +209,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
 			   TIM_CCER_CC12P : TIM_CCER_CC34P, pwm->hwpwm < 2 ?
 			   TIM_CCER_CC2P : TIM_CCER_CC4P);
 
-	ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty);
+	ret = stm32_pwm_raw_capture(chip, pwm, tmo_ms, &raw_prd, &raw_dty);
 	if (ret)
 		goto stop;
 
@@ -229,7 +230,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
 		/* 2nd measure with new scale */
 		psc /= scale;
 		regmap_write(priv->regmap, TIM_PSC, psc);
-		ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd,
+		ret = stm32_pwm_raw_capture(chip, pwm, tmo_ms, &raw_prd,
 					    &raw_dty);
 		if (ret)
 			goto stop;
@@ -257,7 +258,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
 			   FIELD_PREP(TIM_CCMR_IC1PSC, icpsc) |
 			   FIELD_PREP(TIM_CCMR_IC2PSC, icpsc));
 
-	ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty);
+	ret = stm32_pwm_raw_capture(chip, pwm, tmo_ms, &raw_prd, &raw_dty);
 	if (ret)
 		goto stop;
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:33:16 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:33:16 +0100
Subject: [PATCH v6 149/164] pwm: xilinx: Prepare removing pwm_chip from driver data
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <738b9929c1d13bde64050f8bbc4ce8d85f58cc7a.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will drop struct
pwm_chip chip from struct xilinx_pwm_device. Use the pwm_chip as driver
data instead of the xilinx_pwm_device to get access to the pwm_chip in
xilinx_pwm_remove() without using xilinx_pwm->chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-xilinx.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-xilinx.c b/drivers/pwm/pwm-xilinx.c
index 5f3c2a6fed11..0ca79fe8c105 100644
--- a/drivers/pwm/pwm-xilinx.c
+++ b/drivers/pwm/pwm-xilinx.c
@@ -214,6 +214,7 @@ static int xilinx_pwm_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct xilinx_timer_priv *priv;
+	struct pwm_chip *chip;
 	struct xilinx_pwm_device *xilinx_pwm;
 	u32 pwm_cells, one_timer, width;
 	void __iomem *regs;
@@ -228,8 +229,9 @@ static int xilinx_pwm_probe(struct platform_device *pdev)
 	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;
+	chip = &xilinx_pwm->chip;
+	platform_set_drvdata(pdev, chip);
 
 	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))
@@ -278,10 +280,10 @@ static int xilinx_pwm_probe(struct platform_device *pdev)
 		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);
+	chip->dev = dev;
+	chip->ops = &xilinx_pwm_ops;
+	chip->npwm = 1;
+	ret = pwmchip_add(chip);
 	if (ret) {
 		clk_rate_exclusive_put(priv->clk);
 		clk_disable_unprepare(priv->clk);
@@ -293,11 +295,12 @@ static int xilinx_pwm_probe(struct platform_device *pdev)
 
 static void xilinx_pwm_remove(struct platform_device *pdev)
 {
-	struct xilinx_pwm_device *xilinx_pwm = platform_get_drvdata(pdev);
+	struct pwm_chip *chip = platform_get_drvdata(pdev);
+	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
 
-	pwmchip_remove(&xilinx_pwm->chip);
-	clk_rate_exclusive_put(xilinx_pwm->priv.clk);
-	clk_disable_unprepare(xilinx_pwm->priv.clk);
+	pwmchip_remove(chip);
+	clk_rate_exclusive_put(priv->clk);
+	clk_disable_unprepare(priv->clk);
 }
 
 static const struct of_device_id xilinx_pwm_of_match[] = {
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:33:17 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:33:17 +0100
Subject: [PATCH v6 150/164] pwm: xilinx: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <7cbc32771e94103b8c1c817cfdd613d7a2fc01b9.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-xilinx driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-xilinx.c | 19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/pwm/pwm-xilinx.c b/drivers/pwm/pwm-xilinx.c
index 0ca79fe8c105..3a7deebb0d0c 100644
--- a/drivers/pwm/pwm-xilinx.c
+++ b/drivers/pwm/pwm-xilinx.c
@@ -80,15 +80,10 @@ unsigned int xilinx_timer_get_period(struct xilinx_timer_priv *priv,
 #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;
+	return pwmchip_get_drvdata(chip);
 }
 
 static bool xilinx_timer_pwm_enabled(u32 tcsr0, u32 tcsr1)
@@ -215,7 +210,6 @@ static int xilinx_pwm_probe(struct platform_device *pdev)
 	struct device_node *np = dev->of_node;
 	struct xilinx_timer_priv *priv;
 	struct pwm_chip *chip;
-	struct xilinx_pwm_device *xilinx_pwm;
 	u32 pwm_cells, one_timer, width;
 	void __iomem *regs;
 
@@ -226,11 +220,10 @@ static int xilinx_pwm_probe(struct platform_device *pdev)
 	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;
-	priv = &xilinx_pwm->priv;
-	chip = &xilinx_pwm->chip;
+	chip = devm_pwmchip_alloc(dev, 1, sizeof(*priv));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	priv = xilinx_pwm_chip_to_priv(chip);
 	platform_set_drvdata(pdev, chip);
 
 	regs = devm_platform_ioremap_resource(pdev, 0);
@@ -280,9 +273,7 @@ static int xilinx_pwm_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, ret, "Clock enable failed\n");
 	clk_rate_exclusive_get(priv->clk);
 
-	chip->dev = dev;
 	chip->ops = &xilinx_pwm_ops;
-	chip->npwm = 1;
 	ret = pwmchip_add(chip);
 	if (ret) {
 		clk_rate_exclusive_put(priv->clk);
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:31:55 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:31:55 +0100
Subject: [PATCH v6 068/164] pwm: mediatek: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <819996ee175bec0ab71acc385c78e7233617e136.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-mediatek.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 562102a47ac0..6cf7543a3826 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -149,7 +149,7 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	if (clkdiv > PWM_CLK_DIV_MAX) {
 		pwm_mediatek_clk_disable(chip, pwm);
-		dev_err(chip->dev, "period of %d ns not supported\n", period_ns);
+		dev_err(pwmchip_parent(chip), "period of %d ns not supported\n", period_ns);
 		return -EINVAL;
 	}
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:27 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:27 +0100
Subject: [PATCH v6 100/164] pwm: samsung: Simplify using dev_err_probe()
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <27a55fc05eb13802c9eddc600d0460e279388999.1707900770.git.u.kleine-koenig@pengutronix.de>

dev_err_probe() simplifies and improves the idiom "emit error message +
return error code". Apply it accordingly.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-samsung.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index 81a2e66e927e..d3dc9b5b80d6 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -564,10 +564,9 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 		if (ret)
 			return ret;
 	} else {
-		if (!pdev->dev.platform_data) {
-			dev_err(&pdev->dev, "no platform data specified\n");
-			return -EINVAL;
-		}
+		if (!pdev->dev.platform_data)
+			return dev_err_probe(&pdev->dev, -EINVAL,
+					     "no platform data specified\n");
 
 		memcpy(&our_chip->variant, pdev->dev.platform_data,
 							sizeof(our_chip->variant));
@@ -578,10 +577,9 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 		return PTR_ERR(our_chip->base);
 
 	our_chip->base_clk = devm_clk_get_enabled(&pdev->dev, "timers");
-	if (IS_ERR(our_chip->base_clk)) {
-		dev_err(dev, "failed to get timer base clk\n");
-		return PTR_ERR(our_chip->base_clk);
-	}
+	if (IS_ERR(our_chip->base_clk))
+		return dev_err_probe(dev, PTR_ERR(our_chip->base_clk),
+				     "failed to get timer base clk\n");
 
 	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
 		if (our_chip->variant.output_mask & BIT(chan))
@@ -594,10 +592,8 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, chip);
 
 	ret = devm_pwmchip_add(&pdev->dev, chip);
-	if (ret < 0) {
-		dev_err(dev, "failed to register PWM chip\n");
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "failed to register PWM chip\n");
 
 	dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n",
 		clk_get_rate(our_chip->base_clk),
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:24 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:24 +0100
Subject: [PATCH v6 097/164] pwm: samsung: Change prototype of helpers to prepare further changes
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <33ea7d7fbf3be4a542ae8aafa213470c5831487e.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will make it harder to
determine the pwm_chip from a given samsung_pwm_chip. To just not have
to do that, rework pwm_samsung_calc_tin() and pwm_samsung_parse_dt take
a pwm_chip. Also use the pwm_chip as driver data instead of the
samsung_pwm_chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-samsung.c | 41 ++++++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index 0f9a2a5e3ebc..ecd612adf19d 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -181,9 +181,10 @@ static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *our_chip,
 	return rate / (reg + 1);
 }
 
-static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *our_chip,
+static unsigned long pwm_samsung_calc_tin(struct pwm_chip *chip,
 					  unsigned int chan, unsigned long freq)
 {
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
 	struct samsung_pwm_variant *variant = &our_chip->variant;
 	unsigned long rate;
 	struct clk *clk;
@@ -197,12 +198,12 @@ static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *our_chip,
 				return rate;
 		}
 
-		dev_warn(our_chip->chip.dev,
+		dev_warn(chip->dev,
 			"tclk of PWM %d is inoperational, using tdiv\n", chan);
 	}
 
 	rate = pwm_samsung_get_tin_rate(our_chip, chan);
-	dev_dbg(our_chip->chip.dev, "tin parent at %lu\n", rate);
+	dev_dbg(chip->dev, "tin parent at %lu\n", rate);
 
 	/*
 	 * Compare minimum PWM frequency that can be achieved with possible
@@ -329,7 +330,7 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		dev_dbg(chip->dev, "duty_ns=%d, period_ns=%d (%u)\n",
 						duty_ns, period_ns, period);
 
-		tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period);
+		tin_rate = pwm_samsung_calc_tin(chip, pwm->hwpwm, period);
 
 		dev_dbg(chip->dev, "tin_rate=%lu\n", tin_rate);
 
@@ -506,9 +507,10 @@ static const struct of_device_id samsung_pwm_matches[] = {
 };
 MODULE_DEVICE_TABLE(of, samsung_pwm_matches);
 
-static int pwm_samsung_parse_dt(struct samsung_pwm_chip *our_chip)
+static int pwm_samsung_parse_dt(struct pwm_chip *chip)
 {
-	struct device_node *np = our_chip->chip.dev->of_node;
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct device_node *np = chip->dev->of_node;
 	const struct of_device_id *match;
 	struct property *prop;
 	const __be32 *cur;
@@ -522,7 +524,7 @@ static int pwm_samsung_parse_dt(struct samsung_pwm_chip *our_chip)
 
 	of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
 		if (val >= SAMSUNG_PWM_NUM) {
-			dev_err(our_chip->chip.dev,
+			dev_err(chip->dev,
 				"%s: invalid channel index in samsung,pwm-outputs property\n",
 								__func__);
 			continue;
@@ -533,7 +535,7 @@ static int pwm_samsung_parse_dt(struct samsung_pwm_chip *our_chip)
 	return 0;
 }
 #else
-static int pwm_samsung_parse_dt(struct samsung_pwm_chip *our_chip)
+static int pwm_samsung_parse_dt(struct pwm_chip *chip)
 {
 	return -ENODEV;
 }
@@ -543,6 +545,7 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct samsung_pwm_chip *our_chip;
+	struct pwm_chip *chip;
 	unsigned int chan;
 	int ret;
 
@@ -550,13 +553,14 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 	if (our_chip == NULL)
 		return -ENOMEM;
 
-	our_chip->chip.dev = &pdev->dev;
-	our_chip->chip.ops = &pwm_samsung_ops;
-	our_chip->chip.npwm = SAMSUNG_PWM_NUM;
+	chip = &our_chip->chip;
+	chip->dev = &pdev->dev;
+	chip->ops = &pwm_samsung_ops;
+	chip->npwm = SAMSUNG_PWM_NUM;
 	our_chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
 
 	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
-		ret = pwm_samsung_parse_dt(our_chip);
+		ret = pwm_samsung_parse_dt(chip);
 		if (ret)
 			return ret;
 	} else {
@@ -593,9 +597,9 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 	our_chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
 	our_chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
 
-	platform_set_drvdata(pdev, our_chip);
+	platform_set_drvdata(pdev, chip);
 
-	ret = pwmchip_add(&our_chip->chip);
+	ret = pwmchip_add(chip);
 	if (ret < 0) {
 		dev_err(dev, "failed to register PWM chip\n");
 		clk_disable_unprepare(our_chip->base_clk);
@@ -612,17 +616,18 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 
 static void pwm_samsung_remove(struct platform_device *pdev)
 {
-	struct samsung_pwm_chip *our_chip = platform_get_drvdata(pdev);
+	struct pwm_chip *chip = platform_get_drvdata(pdev);
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
 
-	pwmchip_remove(&our_chip->chip);
+	pwmchip_remove(chip);
 
 	clk_disable_unprepare(our_chip->base_clk);
 }
 
 static int pwm_samsung_resume(struct device *dev)
 {
-	struct samsung_pwm_chip *our_chip = dev_get_drvdata(dev);
-	struct pwm_chip *chip = &our_chip->chip;
+	struct pwm_chip *chip = dev_get_drvdata(dev);
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
 	unsigned int i;
 
 	for (i = 0; i < SAMSUNG_PWM_NUM; i++) {
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:33:11 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:33:11 +0100
Subject: [PATCH v6 144/164] pwm: visconti: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <24e779de69365686bb004742cd8f07cbda131212.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-visconti driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-visconti.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-visconti.c b/drivers/pwm/pwm-visconti.c
index 8d736d558122..9e55380957be 100644
--- a/drivers/pwm/pwm-visconti.c
+++ b/drivers/pwm/pwm-visconti.c
@@ -34,13 +34,12 @@
 #define PIPGM_PWMC_POLARITY_MASK	GENMASK(5, 5)
 
 struct visconti_pwm_chip {
-	struct pwm_chip chip;
 	void __iomem *base;
 };
 
 static inline struct visconti_pwm_chip *visconti_pwm_from_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct visconti_pwm_chip, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int visconti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -134,22 +133,22 @@ static const struct pwm_ops visconti_pwm_ops = {
 static int visconti_pwm_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct pwm_chip *chip;
 	struct visconti_pwm_chip *priv;
 	int ret;
 
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(dev, 4, sizeof(*priv));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	priv = visconti_pwm_from_chip(chip);
 
 	priv->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->base))
 		return PTR_ERR(priv->base);
 
-	priv->chip.dev = dev;
-	priv->chip.ops = &visconti_pwm_ops;
-	priv->chip.npwm = 4;
+	chip->ops = &visconti_pwm_ops;
 
-	ret = devm_pwmchip_add(&pdev->dev, &priv->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0)
 		return dev_err_probe(&pdev->dev, ret, "Cannot register visconti PWM\n");
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:12 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:12 +0100
Subject: [PATCH v6 085/164] pwm: raspberrypi-poe: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <6758bcddb150f2c4353469937f1a68ecb87465ed.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-raspberrypi-poe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-raspberrypi-poe.c b/drivers/pwm/pwm-raspberrypi-poe.c
index 1ad814fdec6b..f10e8a624c51 100644
--- a/drivers/pwm/pwm-raspberrypi-poe.c
+++ b/drivers/pwm/pwm-raspberrypi-poe.c
@@ -122,7 +122,7 @@ static int raspberrypi_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	ret = raspberrypi_pwm_set_property(rpipwm->firmware, RPI_PWM_CUR_DUTY_REG,
 					   duty_cycle);
 	if (ret) {
-		dev_err(chip->dev, "Failed to set duty cycle: %pe\n",
+		dev_err(pwmchip_parent(chip), "Failed to set duty cycle: %pe\n",
 			ERR_PTR(ret));
 		return ret;
 	}
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:28 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:28 +0100
Subject: [PATCH v6 101/164] pwm: samsung: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <f188e68bdea8d5a24277a10c8c9a6350a9c246ac.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-samsung driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-samsung.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index d3dc9b5b80d6..efb60c9f0cb3 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -69,7 +69,6 @@ struct samsung_pwm_channel {
 
 /**
  * struct samsung_pwm_chip - private data of PWM chip
- * @chip:		generic PWM chip
  * @variant:		local copy of hardware variant data
  * @inverter_mask:	inverter status for all channels - one bit per channel
  * @disabled_mask:	disabled status for all channels - one bit per channel
@@ -80,7 +79,6 @@ struct samsung_pwm_channel {
  * @channel:		per channel driver data
  */
 struct samsung_pwm_chip {
-	struct pwm_chip chip;
 	struct samsung_pwm_variant variant;
 	u8 inverter_mask;
 	u8 disabled_mask;
@@ -110,7 +108,7 @@ static DEFINE_SPINLOCK(samsung_pwm_lock);
 static inline
 struct samsung_pwm_chip *to_samsung_pwm_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct samsung_pwm_chip, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static inline unsigned int to_tcon_channel(unsigned int channel)
@@ -549,14 +547,12 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 	unsigned int chan;
 	int ret;
 
-	our_chip = devm_kzalloc(&pdev->dev, sizeof(*our_chip), GFP_KERNEL);
-	if (our_chip == NULL)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, SAMSUNG_PWM_NUM, sizeof(*our_chip));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	our_chip = to_samsung_pwm_chip(chip);
 
-	chip = &our_chip->chip;
-	chip->dev = &pdev->dev;
 	chip->ops = &pwm_samsung_ops;
-	chip->npwm = SAMSUNG_PWM_NUM;
 	our_chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
 
 	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:47 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:47 +0100
Subject: [PATCH v6 120/164] pwm: stm32-lp: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <d79148ed49389c657b72df05758032be2b516ceb.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stm32-lp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
index b46d8193dd0f..958043bc5c92 100644
--- a/drivers/pwm/pwm-stm32-lp.c
+++ b/drivers/pwm/pwm-stm32-lp.c
@@ -61,7 +61,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	do_div(div, NSEC_PER_SEC);
 	if (!div) {
 		/* Clock is too slow to achieve requested period. */
-		dev_dbg(chip->dev, "Can't reach %llu ns\n", state->period);
+		dev_dbg(pwmchip_parent(chip), "Can't reach %llu ns\n", state->period);
 		return -EINVAL;
 	}
 
@@ -69,7 +69,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	while (div > STM32_LPTIM_MAX_ARR) {
 		presc++;
 		if ((1 << presc) > STM32_LPTIM_MAX_PRESCALER) {
-			dev_err(chip->dev, "max prescaler exceeded\n");
+			dev_err(pwmchip_parent(chip), "max prescaler exceeded\n");
 			return -EINVAL;
 		}
 		div = prd >> presc;
@@ -130,7 +130,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 				       (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
 				       100, 1000);
 	if (ret) {
-		dev_err(chip->dev, "ARR/CMP registers write issue\n");
+		dev_err(pwmchip_parent(chip), "ARR/CMP registers write issue\n");
 		goto err;
 	}
 	ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:25 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:25 +0100
Subject: [PATCH v6 098/164] pwm: samsung: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <421ee291a065aeae7a1552f22da4173313e789ad.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-samsung.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index ecd612adf19d..cabdcdf37ec9 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -198,12 +198,12 @@ static unsigned long pwm_samsung_calc_tin(struct pwm_chip *chip,
 				return rate;
 		}
 
-		dev_warn(chip->dev,
+		dev_warn(pwmchip_parent(chip),
 			"tclk of PWM %d is inoperational, using tdiv\n", chan);
 	}
 
 	rate = pwm_samsung_get_tin_rate(our_chip, chan);
-	dev_dbg(chip->dev, "tin parent at %lu\n", rate);
+	dev_dbg(pwmchip_parent(chip), "tin parent at %lu\n", rate);
 
 	/*
 	 * Compare minimum PWM frequency that can be achieved with possible
@@ -233,7 +233,7 @@ static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
 	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
 
 	if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) {
-		dev_warn(chip->dev,
+		dev_warn(pwmchip_parent(chip),
 			"tried to request PWM channel %d without output\n",
 			pwm->hwpwm);
 		return -EINVAL;
@@ -327,12 +327,12 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
 
 		period = NSEC_PER_SEC / period_ns;
 
-		dev_dbg(chip->dev, "duty_ns=%d, period_ns=%d (%u)\n",
+		dev_dbg(pwmchip_parent(chip), "duty_ns=%d, period_ns=%d (%u)\n",
 						duty_ns, period_ns, period);
 
 		tin_rate = pwm_samsung_calc_tin(chip, pwm->hwpwm, period);
 
-		dev_dbg(chip->dev, "tin_rate=%lu\n", tin_rate);
+		dev_dbg(pwmchip_parent(chip), "tin_rate=%lu\n", tin_rate);
 
 		tin_ns = NSEC_PER_SEC / tin_rate;
 		tcnt = period_ns / tin_ns;
@@ -356,7 +356,7 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	/* -1UL will give 100% duty. */
 	--tcmp;
 
-	dev_dbg(chip->dev, "tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
+	dev_dbg(pwmchip_parent(chip), "tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
 
 	/* Update PWM registers. */
 	writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm));
@@ -368,7 +368,7 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * shortly afer this update (before it autoreloaded the new values).
 	 */
 	if (oldtcmp == (u32) -1) {
-		dev_dbg(chip->dev, "Forcing manual update");
+		dev_dbg(pwmchip_parent(chip), "Forcing manual update");
 		pwm_samsung_manual_update(our_chip, pwm);
 	}
 
@@ -510,7 +510,7 @@ MODULE_DEVICE_TABLE(of, samsung_pwm_matches);
 static int pwm_samsung_parse_dt(struct pwm_chip *chip)
 {
 	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
-	struct device_node *np = chip->dev->of_node;
+	struct device_node *np = pwmchip_parent(chip)->of_node;
 	const struct of_device_id *match;
 	struct property *prop;
 	const __be32 *cur;
@@ -524,7 +524,7 @@ static int pwm_samsung_parse_dt(struct pwm_chip *chip)
 
 	of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
 		if (val >= SAMSUNG_PWM_NUM) {
-			dev_err(chip->dev,
+			dev_err(pwmchip_parent(chip),
 				"%s: invalid channel index in samsung,pwm-outputs property\n",
 								__func__);
 			continue;
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:33:12 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:33:12 +0100
Subject: [PATCH v6 145/164] pwm: vt8500: Change prototype of a helper to prepare further changes
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <fb384c550b359e7707219f87872bcf36482875ff.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will make it harder to
determine the pwm_chip from a given vt8500_chip. To just not have to do
that, rework vt8500_pwm_busy_wait() to take a pwm_chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-vt8500.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c
index 7bfeacee05d0..3646bd45b101 100644
--- a/drivers/pwm/pwm-vt8500.c
+++ b/drivers/pwm/pwm-vt8500.c
@@ -53,8 +53,9 @@ struct vt8500_chip {
 #define to_vt8500_chip(chip)	container_of(chip, struct vt8500_chip, chip)
 
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
-static inline void vt8500_pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 bitmask)
+static inline void vt8500_pwm_busy_wait(struct pwm_chip *chip, int nr, u8 bitmask)
 {
+	struct vt8500_chip *vt8500 = to_vt8500_chip(chip);
 	int loops = msecs_to_loops(10);
 	u32 mask = bitmask << (nr << 8);
 
@@ -62,7 +63,7 @@ static inline void vt8500_pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 b
 		cpu_relax();
 
 	if (unlikely(!loops))
-		dev_warn(vt8500->chip.dev, "Waiting for status bits 0x%x to clear timed out\n",
+		dev_warn(chip->dev, "Waiting for status bits 0x%x to clear timed out\n",
 			 mask);
 }
 
@@ -103,18 +104,18 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	dc = div64_u64(c, period_ns);
 
 	writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm));
-	vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE);
+	vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_SCALAR_UPDATE);
 
 	writel(pv, vt8500->base + REG_PERIOD(pwm->hwpwm));
-	vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_PERIOD_UPDATE);
+	vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_PERIOD_UPDATE);
 
 	writel(dc, vt8500->base + REG_DUTY(pwm->hwpwm));
-	vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_DUTY_UPDATE);
+	vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_DUTY_UPDATE);
 
 	val = readl(vt8500->base + REG_CTRL(pwm->hwpwm));
 	val |= CTRL_AUTOLOAD;
 	writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
-	vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
+	vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE);
 
 	clk_disable(vt8500->clk);
 	return 0;
@@ -135,7 +136,7 @@ static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 	val = readl(vt8500->base + REG_CTRL(pwm->hwpwm));
 	val |= CTRL_ENABLE;
 	writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
-	vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
+	vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE);
 
 	return 0;
 }
@@ -148,7 +149,7 @@ static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 	val = readl(vt8500->base + REG_CTRL(pwm->hwpwm));
 	val &= ~CTRL_ENABLE;
 	writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
-	vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
+	vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE);
 
 	clk_disable(vt8500->clk);
 }
@@ -168,7 +169,7 @@ static int vt8500_pwm_set_polarity(struct pwm_chip *chip,
 		val &= ~CTRL_INVERT;
 
 	writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
-	vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
+	vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE);
 
 	return 0;
 }
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:30:48 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:30:48 +0100
Subject: [PATCH v6 001/164] pwm: Provide an inline function to get the parent device of a given chip
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <cc30090d2f9762bed9854a55612144bccc910781.1707900770.git.u.kleine-koenig@pengutronix.de>

Currently a pwm_chip stores in its struct device *dev member a pointer
to the parent device. Preparing a change that embeds a full struct
device in struct pwm_chip, this accessor function should be used in all
drivers directly accessing chip->dev now. This way struct pwm_chip and
this new function can be changed without having to touch all drivers in
the same change set.

Make use of this function in the framework's core sources.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/core.c  | 42 +++++++++++++++++++++---------------------
 drivers/pwm/sysfs.c |  4 ++--
 include/linux/pwm.h |  5 +++++
 3 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 1b4c3d0caa82..830a697826af 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -71,18 +71,18 @@ static void pwm_apply_debug(struct pwm_device *pwm,
 
 	if (s2.polarity != state->polarity &&
 	    state->duty_cycle < state->period)
-		dev_warn(chip->dev, ".apply ignored .polarity\n");
+		dev_warn(pwmchip_parent(chip), ".apply ignored .polarity\n");
 
 	if (state->enabled &&
 	    last->polarity == state->polarity &&
 	    last->period > s2.period &&
 	    last->period <= state->period)
-		dev_warn(chip->dev,
+		dev_warn(pwmchip_parent(chip),
 			 ".apply didn't pick the best available period (requested: %llu, applied: %llu, possible: %llu)\n",
 			 state->period, s2.period, last->period);
 
 	if (state->enabled && state->period < s2.period)
-		dev_warn(chip->dev,
+		dev_warn(pwmchip_parent(chip),
 			 ".apply is supposed to round down period (requested: %llu, applied: %llu)\n",
 			 state->period, s2.period);
 
@@ -91,20 +91,20 @@ static void pwm_apply_debug(struct pwm_device *pwm,
 	    last->period == s2.period &&
 	    last->duty_cycle > s2.duty_cycle &&
 	    last->duty_cycle <= state->duty_cycle)
-		dev_warn(chip->dev,
+		dev_warn(pwmchip_parent(chip),
 			 ".apply didn't pick the best available duty cycle (requested: %llu/%llu, applied: %llu/%llu, possible: %llu/%llu)\n",
 			 state->duty_cycle, state->period,
 			 s2.duty_cycle, s2.period,
 			 last->duty_cycle, last->period);
 
 	if (state->enabled && state->duty_cycle < s2.duty_cycle)
-		dev_warn(chip->dev,
+		dev_warn(pwmchip_parent(chip),
 			 ".apply is supposed to round down duty_cycle (requested: %llu/%llu, applied: %llu/%llu)\n",
 			 state->duty_cycle, state->period,
 			 s2.duty_cycle, s2.period);
 
 	if (!state->enabled && s2.enabled && s2.duty_cycle > 0)
-		dev_warn(chip->dev,
+		dev_warn(pwmchip_parent(chip),
 			 "requested disabled, but yielded enabled with duty > 0\n");
 
 	/* reapply the state that the driver reported being configured. */
@@ -112,7 +112,7 @@ static void pwm_apply_debug(struct pwm_device *pwm,
 	trace_pwm_apply(pwm, &s1, err);
 	if (err) {
 		*last = s1;
-		dev_err(chip->dev, "failed to reapply current setting\n");
+		dev_err(pwmchip_parent(chip), "failed to reapply current setting\n");
 		return;
 	}
 
@@ -127,7 +127,7 @@ static void pwm_apply_debug(struct pwm_device *pwm,
 	    s1.polarity != last->polarity ||
 	    (s1.enabled && s1.period != last->period) ||
 	    (s1.enabled && s1.duty_cycle != last->duty_cycle)) {
-		dev_err(chip->dev,
+		dev_err(pwmchip_parent(chip),
 			".apply is not idempotent (ena=%d pol=%d %llu/%llu) -> (ena=%d pol=%d %llu/%llu)\n",
 			s1.enabled, s1.polarity, s1.duty_cycle, s1.period,
 			last->enabled, last->polarity, last->duty_cycle,
@@ -318,7 +318,7 @@ static struct pwm_chip *pwmchip_find_by_name(const char *name)
 	mutex_lock(&pwm_lock);
 
 	idr_for_each_entry_ul(&pwm_chips, chip, tmp, id) {
-		const char *chip_name = dev_name(chip->dev);
+		const char *chip_name = dev_name(pwmchip_parent(chip));
 
 		if (chip_name && strcmp(chip_name, name) == 0) {
 			mutex_unlock(&pwm_lock);
@@ -456,19 +456,19 @@ EXPORT_SYMBOL_GPL(of_pwm_single_xlate);
 
 static void of_pwmchip_add(struct pwm_chip *chip)
 {
-	if (!chip->dev || !chip->dev->of_node)
+	if (!pwmchip_parent(chip) || !pwmchip_parent(chip)->of_node)
 		return;
 
 	if (!chip->of_xlate)
 		chip->of_xlate = of_pwm_xlate_with_flags;
 
-	of_node_get(chip->dev->of_node);
+	of_node_get(pwmchip_parent(chip)->of_node);
 }
 
 static void of_pwmchip_remove(struct pwm_chip *chip)
 {
-	if (chip->dev)
-		of_node_put(chip->dev->of_node);
+	if (pwmchip_parent(chip))
+		of_node_put(pwmchip_parent(chip)->of_node);
 }
 
 static bool pwm_ops_check(const struct pwm_chip *chip)
@@ -479,7 +479,7 @@ static bool pwm_ops_check(const struct pwm_chip *chip)
 		return false;
 
 	if (IS_ENABLED(CONFIG_PWM_DEBUG) && !ops->get_state)
-		dev_warn(chip->dev,
+		dev_warn(pwmchip_parent(chip),
 			 "Please implement the .get_state() callback\n");
 
 	return true;
@@ -500,7 +500,7 @@ int __pwmchip_add(struct pwm_chip *chip, struct module *owner)
 	unsigned int i;
 	int ret;
 
-	if (!chip || !chip->dev || !chip->ops || !chip->npwm)
+	if (!chip || !pwmchip_parent(chip) || !chip->ops || !chip->npwm)
 		return -EINVAL;
 
 	if (!pwm_ops_check(chip))
@@ -594,15 +594,15 @@ static struct device_link *pwm_device_link_add(struct device *dev,
 		 * impact the PM sequence ordering: the PWM supplier may get
 		 * suspended before the consumer.
 		 */
-		dev_warn(pwm->chip->dev,
+		dev_warn(pwmchip_parent(pwm->chip),
 			 "No consumer device specified to create a link to\n");
 		return NULL;
 	}
 
-	dl = device_link_add(dev, pwm->chip->dev, DL_FLAG_AUTOREMOVE_CONSUMER);
+	dl = device_link_add(dev, pwmchip_parent(pwm->chip), DL_FLAG_AUTOREMOVE_CONSUMER);
 	if (!dl) {
 		dev_err(dev, "failed to create device link to %s\n",
-			dev_name(pwm->chip->dev));
+			dev_name(pwmchip_parent(pwm->chip)));
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -617,7 +617,7 @@ static struct pwm_chip *fwnode_to_pwmchip(struct fwnode_handle *fwnode)
 	mutex_lock(&pwm_lock);
 
 	idr_for_each_entry_ul(&pwm_chips, chip, tmp, id)
-		if (chip->dev && device_match_fwnode(chip->dev, fwnode)) {
+		if (pwmchip_parent(chip) && device_match_fwnode(pwmchip_parent(chip), fwnode)) {
 			mutex_unlock(&pwm_lock);
 			return chip;
 		}
@@ -1085,8 +1085,8 @@ static int pwm_seq_show(struct seq_file *s, void *v)
 
 	seq_printf(s, "%s%d: %s/%s, %d PWM device%s\n",
 		   (char *)s->private, chip->id,
-		   chip->dev->bus ? chip->dev->bus->name : "no-bus",
-		   dev_name(chip->dev), chip->npwm,
+		   pwmchip_parent(chip)->bus ? pwmchip_parent(chip)->bus->name : "no-bus",
+		   dev_name(pwmchip_parent(chip)), chip->npwm,
 		   (chip->npwm != 1) ? "s" : "");
 
 	pwm_dbg_show(chip, s);
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index 1698609d91c8..3f434a771fb5 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -509,10 +509,10 @@ void pwmchip_sysfs_export(struct pwm_chip *chip)
 	 * If device_create() fails the pwm_chip is still usable by
 	 * the kernel it's just not exported.
 	 */
-	parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
+	parent = device_create(&pwm_class, pwmchip_parent(chip), MKDEV(0, 0), chip,
 			       "pwmchip%d", chip->id);
 	if (IS_ERR(parent)) {
-		dev_warn(chip->dev,
+		dev_warn(pwmchip_parent(chip),
 			 "device_create failed for pwm_chip sysfs export\n");
 	}
 }
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 8ffe9ae7a23a..07af6910bdce 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -289,6 +289,11 @@ struct pwm_chip {
 	struct pwm_device *pwms;
 };
 
+static inline struct device *pwmchip_parent(const struct pwm_chip *chip)
+{
+	return chip->dev;
+}
+
 #if IS_ENABLED(CONFIG_PWM)
 /* PWM user APIs */
 int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state);
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:54 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:54 +0100
Subject: [PATCH v6 127/164] pwm: sun4i: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <9d175b4e27878618cef2e75b6ecbf01ad5d18164.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-sun4i driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-sun4i.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 2437e5961f5e..5c29590d1821 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -81,7 +81,6 @@ struct sun4i_pwm_data {
 };
 
 struct sun4i_pwm_chip {
-	struct pwm_chip chip;
 	struct clk *bus_clk;
 	struct clk *clk;
 	struct reset_control *rst;
@@ -92,7 +91,7 @@ struct sun4i_pwm_chip {
 
 static inline struct sun4i_pwm_chip *to_sun4i_pwm_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct sun4i_pwm_chip, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static inline u32 sun4i_pwm_readl(struct sun4i_pwm_chip *sun4ichip,
@@ -385,18 +384,20 @@ MODULE_DEVICE_TABLE(of, sun4i_pwm_dt_ids);
 static int sun4i_pwm_probe(struct platform_device *pdev)
 {
 	struct pwm_chip *chip;
+	const struct sun4i_pwm_data *data;
 	struct sun4i_pwm_chip *sun4ichip;
 	int ret;
 
-	sun4ichip = devm_kzalloc(&pdev->dev, sizeof(*sun4ichip), GFP_KERNEL);
-	if (!sun4ichip)
-		return -ENOMEM;
-	chip = &sun4ichip->chip;
-
-	sun4ichip->data = of_device_get_match_data(&pdev->dev);
-	if (!sun4ichip->data)
+	data = of_device_get_match_data(&pdev->dev);
+	if (!data)
 		return -ENODEV;
 
+	chip = devm_pwmchip_alloc(&pdev->dev, data->npwm, sizeof(*sun4ichip));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	sun4ichip = to_sun4i_pwm_chip(chip);
+
+	sun4ichip->data = data;
 	sun4ichip->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(sun4ichip->base))
 		return PTR_ERR(sun4ichip->base);
@@ -453,9 +454,7 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 		goto err_bus;
 	}
 
-	chip->dev = &pdev->dev;
 	chip->ops = &sun4i_pwm_ops;
-	chip->npwm = sun4ichip->data->npwm;
 
 	spin_lock_init(&sun4ichip->ctrl_lock);
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:53 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:53 +0100
Subject: [PATCH v6 126/164] pwm: sun4i: Consistently name driver data sun4ichip
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <705f54a13b59fff50eaa345d8b1e0c691345b996.1707900770.git.u.kleine-koenig@pengutronix.de>

The driver uses three different names for variables of type
sun4i_pwm_chip:

	$ git grep 'struct sun4i_pwm_chip \*' v6.8-rc1 -- drivers/pwm/pwm-sun4i.c
	v6.8-rc1:drivers/pwm/pwm-sun4i.c:static inline struct sun4i_pwm_chip *to_sun4i_pwm_chip(struct pwm_chip *chip)
	v6.8-rc1:drivers/pwm/pwm-sun4i.c:static inline u32 sun4i_pwm_readl(struct sun4i_pwm_chip *chip,
	v6.8-rc1:drivers/pwm/pwm-sun4i.c:static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
	v6.8-rc1:drivers/pwm/pwm-sun4i.c:       struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
	v6.8-rc1:drivers/pwm/pwm-sun4i.c:static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
	v6.8-rc1:drivers/pwm/pwm-sun4i.c:       struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
	v6.8-rc1:drivers/pwm/pwm-sun4i.c:       struct sun4i_pwm_chip *sun4ichip;
	v6.8-rc1:drivers/pwm/pwm-sun4i.c:       struct sun4i_pwm_chip *sun4ichip = platform_get_drvdata(pdev);

"chip" is usually reserved for variables of type struct pwm_chip. So
pick sun4ichip as common name which better matches the type name than
sun4i_pwm.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-sun4i.c | 64 ++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index c2f579043915..2437e5961f5e 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -95,32 +95,32 @@ static inline struct sun4i_pwm_chip *to_sun4i_pwm_chip(struct pwm_chip *chip)
 	return container_of(chip, struct sun4i_pwm_chip, chip);
 }
 
-static inline u32 sun4i_pwm_readl(struct sun4i_pwm_chip *chip,
+static inline u32 sun4i_pwm_readl(struct sun4i_pwm_chip *sun4ichip,
 				  unsigned long offset)
 {
-	return readl(chip->base + offset);
+	return readl(sun4ichip->base + offset);
 }
 
-static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
+static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *sun4ichip,
 				    u32 val, unsigned long offset)
 {
-	writel(val, chip->base + offset);
+	writel(val, sun4ichip->base + offset);
 }
 
 static int sun4i_pwm_get_state(struct pwm_chip *chip,
 			       struct pwm_device *pwm,
 			       struct pwm_state *state)
 {
-	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	struct sun4i_pwm_chip *sun4ichip = to_sun4i_pwm_chip(chip);
 	u64 clk_rate, tmp;
 	u32 val;
 	unsigned int prescaler;
 
-	clk_rate = clk_get_rate(sun4i_pwm->clk);
+	clk_rate = clk_get_rate(sun4ichip->clk);
 	if (!clk_rate)
 		return -EINVAL;
 
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+	val = sun4i_pwm_readl(sun4ichip, PWM_CTRL_REG);
 
 	/*
 	 * PWM chapter in H6 manual has a diagram which explains that if bypass
@@ -128,7 +128,7 @@ static int sun4i_pwm_get_state(struct pwm_chip *chip,
 	 * proved that also enable bit is ignored in this case.
 	 */
 	if ((val & BIT_CH(PWM_BYPASS, pwm->hwpwm)) &&
-	    sun4i_pwm->data->has_direct_mod_clk_output) {
+	    sun4ichip->data->has_direct_mod_clk_output) {
 		state->period = DIV_ROUND_UP_ULL(NSEC_PER_SEC, clk_rate);
 		state->duty_cycle = DIV_ROUND_UP_ULL(state->period, 2);
 		state->polarity = PWM_POLARITY_NORMAL;
@@ -137,7 +137,7 @@ static int sun4i_pwm_get_state(struct pwm_chip *chip,
 	}
 
 	if ((PWM_REG_PRESCAL(val, pwm->hwpwm) == PWM_PRESCAL_MASK) &&
-	    sun4i_pwm->data->has_prescaler_bypass)
+	    sun4ichip->data->has_prescaler_bypass)
 		prescaler = 1;
 	else
 		prescaler = prescaler_table[PWM_REG_PRESCAL(val, pwm->hwpwm)];
@@ -156,7 +156,7 @@ static int sun4i_pwm_get_state(struct pwm_chip *chip,
 	else
 		state->enabled = false;
 
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CH_PRD(pwm->hwpwm));
+	val = sun4i_pwm_readl(sun4ichip, PWM_CH_PRD(pwm->hwpwm));
 
 	tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_DTY(val);
 	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
@@ -167,7 +167,7 @@ static int sun4i_pwm_get_state(struct pwm_chip *chip,
 	return 0;
 }
 
-static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
+static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4ichip,
 			       const struct pwm_state *state,
 			       u32 *dty, u32 *prd, unsigned int *prsclr,
 			       bool *bypass)
@@ -175,9 +175,9 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
 	u64 clk_rate, div = 0;
 	unsigned int prescaler = 0;
 
-	clk_rate = clk_get_rate(sun4i_pwm->clk);
+	clk_rate = clk_get_rate(sun4ichip->clk);
 
-	*bypass = sun4i_pwm->data->has_direct_mod_clk_output &&
+	*bypass = sun4ichip->data->has_direct_mod_clk_output &&
 		  state->enabled &&
 		  (state->period * clk_rate >= NSEC_PER_SEC) &&
 		  (state->period * clk_rate < 2 * NSEC_PER_SEC) &&
@@ -187,7 +187,7 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
 	if (*bypass)
 		return 0;
 
-	if (sun4i_pwm->data->has_prescaler_bypass) {
+	if (sun4ichip->data->has_prescaler_bypass) {
 		/* First, test without any prescaler when available */
 		prescaler = PWM_PRESCAL_MASK;
 		/*
@@ -233,7 +233,7 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
 static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			   const struct pwm_state *state)
 {
-	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	struct sun4i_pwm_chip *sun4ichip = to_sun4i_pwm_chip(chip);
 	struct pwm_state cstate;
 	u32 ctrl, duty = 0, period = 0, val;
 	int ret;
@@ -243,31 +243,31 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	pwm_get_state(pwm, &cstate);
 
 	if (!cstate.enabled) {
-		ret = clk_prepare_enable(sun4i_pwm->clk);
+		ret = clk_prepare_enable(sun4ichip->clk);
 		if (ret) {
 			dev_err(pwmchip_parent(chip), "failed to enable PWM clock\n");
 			return ret;
 		}
 	}
 
-	ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler,
+	ret = sun4i_pwm_calculate(sun4ichip, state, &duty, &period, &prescaler,
 				  &bypass);
 	if (ret) {
 		dev_err(pwmchip_parent(chip), "period exceeds the maximum value\n");
 		if (!cstate.enabled)
-			clk_disable_unprepare(sun4i_pwm->clk);
+			clk_disable_unprepare(sun4ichip->clk);
 		return ret;
 	}
 
-	spin_lock(&sun4i_pwm->ctrl_lock);
-	ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+	spin_lock(&sun4ichip->ctrl_lock);
+	ctrl = sun4i_pwm_readl(sun4ichip, PWM_CTRL_REG);
 
-	if (sun4i_pwm->data->has_direct_mod_clk_output) {
+	if (sun4ichip->data->has_direct_mod_clk_output) {
 		if (bypass) {
 			ctrl |= BIT_CH(PWM_BYPASS, pwm->hwpwm);
 			/* We can skip other parameter */
-			sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
-			spin_unlock(&sun4i_pwm->ctrl_lock);
+			sun4i_pwm_writel(sun4ichip, ctrl, PWM_CTRL_REG);
+			spin_unlock(&sun4ichip->ctrl_lock);
 			return 0;
 		}
 
@@ -277,14 +277,14 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	if (PWM_REG_PRESCAL(ctrl, pwm->hwpwm) != prescaler) {
 		/* Prescaler changed, the clock has to be gated */
 		ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-		sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
+		sun4i_pwm_writel(sun4ichip, ctrl, PWM_CTRL_REG);
 
 		ctrl &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
 		ctrl |= BIT_CH(prescaler, pwm->hwpwm);
 	}
 
 	val = (duty & PWM_DTY_MASK) | PWM_PRD(period);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
+	sun4i_pwm_writel(sun4ichip, val, PWM_CH_PRD(pwm->hwpwm));
 
 	if (state->polarity != PWM_POLARITY_NORMAL)
 		ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
@@ -296,9 +296,9 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	if (state->enabled)
 		ctrl |= BIT_CH(PWM_EN, pwm->hwpwm);
 
-	sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
+	sun4i_pwm_writel(sun4ichip, ctrl, PWM_CTRL_REG);
 
-	spin_unlock(&sun4i_pwm->ctrl_lock);
+	spin_unlock(&sun4ichip->ctrl_lock);
 
 	if (state->enabled)
 		return 0;
@@ -310,14 +310,14 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	else
 		usleep_range(delay_us, delay_us * 2);
 
-	spin_lock(&sun4i_pwm->ctrl_lock);
-	ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+	spin_lock(&sun4ichip->ctrl_lock);
+	ctrl = sun4i_pwm_readl(sun4ichip, PWM_CTRL_REG);
 	ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
 	ctrl &= ~BIT_CH(PWM_EN, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
-	spin_unlock(&sun4i_pwm->ctrl_lock);
+	sun4i_pwm_writel(sun4ichip, ctrl, PWM_CTRL_REG);
+	spin_unlock(&sun4ichip->ctrl_lock);
 
-	clk_disable_unprepare(sun4i_pwm->clk);
+	clk_disable_unprepare(sun4ichip->clk);
 
 	return 0;
 }
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:33:13 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:33:13 +0100
Subject: [PATCH v6 146/164] pwm: vt8500: Introduce a local pwm_chip variable in .probe()
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <7d903b608609d46cf1ee1e06530f516f42af1ebb.1707900770.git.u.kleine-koenig@pengutronix.de>

This simplifies converting the driver to pwmchip_alloc() as there is only
a single code line left that makes use of struct vt8500_chip::chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-vt8500.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c
index 3646bd45b101..6da9b8f88afc 100644
--- a/drivers/pwm/pwm-vt8500.c
+++ b/drivers/pwm/pwm-vt8500.c
@@ -232,6 +232,7 @@ MODULE_DEVICE_TABLE(of, vt8500_pwm_dt_ids);
 
 static int vt8500_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct vt8500_chip *vt8500;
 	struct device_node *np = pdev->dev.of_node;
 	int ret;
@@ -243,9 +244,10 @@ static int vt8500_pwm_probe(struct platform_device *pdev)
 	if (vt8500 == NULL)
 		return -ENOMEM;
 
-	vt8500->chip.dev = &pdev->dev;
-	vt8500->chip.ops = &vt8500_pwm_ops;
-	vt8500->chip.npwm = VT8500_NR_PWMS;
+	chip = &vt8500->chip;
+	chip->dev = &pdev->dev;
+	chip->ops = &vt8500_pwm_ops;
+	chip->npwm = VT8500_NR_PWMS;
 
 	vt8500->clk = devm_clk_get_prepared(&pdev->dev, NULL);
 	if (IS_ERR(vt8500->clk))
@@ -255,7 +257,7 @@ static int vt8500_pwm_probe(struct platform_device *pdev)
 	if (IS_ERR(vt8500->base))
 		return PTR_ERR(vt8500->base);
 
-	ret = devm_pwmchip_add(&pdev->dev, &vt8500->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0)
 		return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:33:14 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:33:14 +0100
Subject: [PATCH v6 147/164] pwm: vt8500: Make use of pwmchip_parent() accessor
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <c3c45a08f2ccb8bb13b4042c73f93064876586eb.1707900770.git.u.kleine-koenig@pengutronix.de>

struct pwm_chip::dev is about to change. To not have to touch this
driver in the same commit as struct pwm_chip::dev, use the accessor
function provided for exactly this purpose.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-vt8500.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c
index 6da9b8f88afc..fb4dbc88b0a3 100644
--- a/drivers/pwm/pwm-vt8500.c
+++ b/drivers/pwm/pwm-vt8500.c
@@ -63,7 +63,7 @@ static inline void vt8500_pwm_busy_wait(struct pwm_chip *chip, int nr, u8 bitmas
 		cpu_relax();
 
 	if (unlikely(!loops))
-		dev_warn(chip->dev, "Waiting for status bits 0x%x to clear timed out\n",
+		dev_warn(pwmchip_parent(chip), "Waiting for status bits 0x%x to clear timed out\n",
 			 mask);
 }
 
@@ -78,7 +78,7 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	err = clk_enable(vt8500->clk);
 	if (err < 0) {
-		dev_err(chip->dev, "failed to enable clock\n");
+		dev_err(pwmchip_parent(chip), "failed to enable clock\n");
 		return err;
 	}
 
@@ -129,7 +129,7 @@ static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 
 	err = clk_enable(vt8500->clk);
 	if (err < 0) {
-		dev_err(chip->dev, "failed to enable clock\n");
+		dev_err(pwmchip_parent(chip), "failed to enable clock\n");
 		return err;
 	}
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:52 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:52 +0100
Subject: [PATCH v6 125/164] pwm: sun4i: Prepare removing pwm_chip from driver data
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <f8e3fb96fe341ba0a4bed982aa731c5c7c355b83.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will drop struct
pwm_chip chip from struct sun4i_pwm_chip. Use the pwm_chip as driver
data instead of the sun4i_pwm_chip to get access to the pwm_chip in
sun4i_pwm_remove() without using sun4ichip->chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-sun4i.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 44edf1ce5739..c2f579043915 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -384,12 +384,14 @@ MODULE_DEVICE_TABLE(of, sun4i_pwm_dt_ids);
 
 static int sun4i_pwm_probe(struct platform_device *pdev)
 {
+	struct pwm_chip *chip;
 	struct sun4i_pwm_chip *sun4ichip;
 	int ret;
 
 	sun4ichip = devm_kzalloc(&pdev->dev, sizeof(*sun4ichip), GFP_KERNEL);
 	if (!sun4ichip)
 		return -ENOMEM;
+	chip = &sun4ichip->chip;
 
 	sun4ichip->data = of_device_get_match_data(&pdev->dev);
 	if (!sun4ichip->data)
@@ -451,19 +453,19 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 		goto err_bus;
 	}
 
-	sun4ichip->chip.dev = &pdev->dev;
-	sun4ichip->chip.ops = &sun4i_pwm_ops;
-	sun4ichip->chip.npwm = sun4ichip->data->npwm;
+	chip->dev = &pdev->dev;
+	chip->ops = &sun4i_pwm_ops;
+	chip->npwm = sun4ichip->data->npwm;
 
 	spin_lock_init(&sun4ichip->ctrl_lock);
 
-	ret = pwmchip_add(&sun4ichip->chip);
+	ret = pwmchip_add(chip);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
 		goto err_pwm_add;
 	}
 
-	platform_set_drvdata(pdev, sun4ichip);
+	platform_set_drvdata(pdev, chip);
 
 	return 0;
 
@@ -477,9 +479,10 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 
 static void sun4i_pwm_remove(struct platform_device *pdev)
 {
-	struct sun4i_pwm_chip *sun4ichip = platform_get_drvdata(pdev);
+	struct pwm_chip *chip = platform_get_drvdata(pdev);
+	struct sun4i_pwm_chip *sun4ichip = to_sun4i_pwm_chip(chip);
 
-	pwmchip_remove(&sun4ichip->chip);
+	pwmchip_remove(chip);
 
 	clk_disable_unprepare(sun4ichip->bus_clk);
 	reset_control_assert(sun4ichip->rst);
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:30:59 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:30:59 +0100
Subject: [PATCH v6 012/164] pwm: atmel-hlcdc: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <4724c6a0f052160ac80ba5a3065c9470778b7457.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-atmel-hlcdc driver to further changes of the pwm
core outlined in the commit introducing devm_pwmchip_alloc(). There is
no intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-atmel-hlcdc.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c
index f3f6c951bda5..166f1d16aba6 100644
--- a/drivers/pwm/pwm-atmel-hlcdc.c
+++ b/drivers/pwm/pwm-atmel-hlcdc.c
@@ -28,7 +28,6 @@ struct atmel_hlcdc_pwm_errata {
 };
 
 struct atmel_hlcdc_pwm {
-	struct pwm_chip chip;
 	struct atmel_hlcdc *hlcdc;
 	struct clk *cur_clk;
 	const struct atmel_hlcdc_pwm_errata *errata;
@@ -36,7 +35,7 @@ struct atmel_hlcdc_pwm {
 
 static inline struct atmel_hlcdc_pwm *to_atmel_hlcdc_pwm(struct pwm_chip *chip)
 {
-	return container_of(chip, struct atmel_hlcdc_pwm, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int atmel_hlcdc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -251,9 +250,10 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
 
 	hlcdc = dev_get_drvdata(dev->parent);
 
-	atmel = devm_kzalloc(dev, sizeof(*atmel), GFP_KERNEL);
-	if (!atmel)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(dev, 1, sizeof(*atmel));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	atmel = to_atmel_hlcdc_pwm(chip);
 
 	ret = clk_prepare_enable(hlcdc->periph_clk);
 	if (ret)
@@ -264,10 +264,7 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
 		atmel->errata = match->data;
 
 	atmel->hlcdc = hlcdc;
-	chip = &atmel->chip;
 	chip->ops = &atmel_hlcdc_pwm_ops;
-	chip->dev = dev;
-	chip->npwm = 1;
 
 	ret = pwmchip_add(chip);
 	if (ret) {
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:40 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:40 +0100
Subject: [PATCH v6 113/164] pwm: stm32: Simplify code to determine the pwmchip's parent device
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <54ace92a3c02d22f15a79c7ecf00c29f28386a33.1707900770.git.u.kleine-koenig@pengutronix.de>

There is already a pointer to the pwmchip, make use of it directly
instead of using the struct stm32_pwm *priv just obtained from it. This
also has the advantage of not using struct stm32_pwm::chip any more
which will be dropped soon.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stm32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index 5f10cba492ec..202114c00ad3 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -170,7 +170,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	ret = clk_enable(priv->clk);
 	if (ret) {
-		dev_err(priv->chip.dev, "failed to enable counter clock\n");
+		dev_err(chip->dev, "failed to enable counter clock\n");
 		goto unlock;
 	}
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:23 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:23 +0100
Subject: [PATCH v6 096/164] pwm: samsung: Simplify code to determine the pwmchip's parent device
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <4e8400a42979b6be0b80dff5ae964d8e9d6232eb.1707900770.git.u.kleine-koenig@pengutronix.de>

There is already a pointer to the pwmchip, make use of it directly
instead of using the struct samsung_pwm_chip *our_chip just obtained
from it. This also has the advantage of not using struct
samsung_pwm_chip::chip any more which will be dropped soon.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-samsung.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index 6e77302f7368..0f9a2a5e3ebc 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -326,12 +326,12 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
 
 		period = NSEC_PER_SEC / period_ns;
 
-		dev_dbg(our_chip->chip.dev, "duty_ns=%d, period_ns=%d (%u)\n",
+		dev_dbg(chip->dev, "duty_ns=%d, period_ns=%d (%u)\n",
 						duty_ns, period_ns, period);
 
 		tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period);
 
-		dev_dbg(our_chip->chip.dev, "tin_rate=%lu\n", tin_rate);
+		dev_dbg(chip->dev, "tin_rate=%lu\n", tin_rate);
 
 		tin_ns = NSEC_PER_SEC / tin_rate;
 		tcnt = period_ns / tin_ns;
@@ -355,8 +355,7 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	/* -1UL will give 100% duty. */
 	--tcmp;
 
-	dev_dbg(our_chip->chip.dev,
-				"tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
+	dev_dbg(chip->dev, "tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
 
 	/* Update PWM registers. */
 	writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm));
@@ -368,7 +367,7 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * shortly afer this update (before it autoreloaded the new values).
 	 */
 	if (oldtcmp == (u32) -1) {
-		dev_dbg(our_chip->chip.dev, "Forcing manual update");
+		dev_dbg(chip->dev, "Forcing manual update");
 		pwm_samsung_manual_update(our_chip, pwm);
 	}
 
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:13 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:13 +0100
Subject: [PATCH v6 086/164] pwm: raspberrypi-poe: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <4654a6438ab618574afc3bb73bf402df7c254ee2.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-raspberrypi-poe driver to further changes of the
pwm core outlined in the commit introducing devm_pwmchip_alloc(). There
is no intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-raspberrypi-poe.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-raspberrypi-poe.c b/drivers/pwm/pwm-raspberrypi-poe.c
index f10e8a624c51..8921e7ea2cea 100644
--- a/drivers/pwm/pwm-raspberrypi-poe.c
+++ b/drivers/pwm/pwm-raspberrypi-poe.c
@@ -27,7 +27,6 @@
 
 struct raspberrypi_pwm {
 	struct rpi_firmware *firmware;
-	struct pwm_chip chip;
 	unsigned int duty_cycle;
 };
 
@@ -40,7 +39,7 @@ struct raspberrypi_pwm_prop {
 static inline
 struct raspberrypi_pwm *raspberrypi_pwm_from_chip(struct pwm_chip *chip)
 {
-	return container_of(chip, struct raspberrypi_pwm, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int raspberrypi_pwm_set_property(struct rpi_firmware *firmware,
@@ -142,6 +141,7 @@ static int raspberrypi_pwm_probe(struct platform_device *pdev)
 	struct device_node *firmware_node;
 	struct device *dev = &pdev->dev;
 	struct rpi_firmware *firmware;
+	struct pwm_chip *chip;
 	struct raspberrypi_pwm *rpipwm;
 	int ret;
 
@@ -157,14 +157,14 @@ static int raspberrypi_pwm_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -EPROBE_DEFER,
 				     "Failed to get firmware handle\n");
 
-	rpipwm = devm_kzalloc(&pdev->dev, sizeof(*rpipwm), GFP_KERNEL);
-	if (!rpipwm)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, RASPBERRYPI_FIRMWARE_PWM_NUM,
+				  sizeof(*rpipwm));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	rpipwm = raspberrypi_pwm_from_chip(chip);
 
 	rpipwm->firmware = firmware;
-	rpipwm->chip.dev = dev;
-	rpipwm->chip.ops = &raspberrypi_pwm_ops;
-	rpipwm->chip.npwm = RASPBERRYPI_FIRMWARE_PWM_NUM;
+	chip->ops = &raspberrypi_pwm_ops;
 
 	ret = raspberrypi_pwm_get_property(rpipwm->firmware, RPI_PWM_CUR_DUTY_REG,
 					   &rpipwm->duty_cycle);
@@ -173,7 +173,7 @@ static int raspberrypi_pwm_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	return devm_pwmchip_add(dev, &rpipwm->chip);
+	return devm_pwmchip_add(dev, chip);
 }
 
 static const struct of_device_id raspberrypi_pwm_of_match[] = {
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:50 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:50 +0100
Subject: [PATCH v6 123/164] pwm: stmpe: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <7e3dbf3b70126038c0ba16331ca8c07cab575bd3.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-stmpe driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stmpe.c | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/pwm/pwm-stmpe.c b/drivers/pwm/pwm-stmpe.c
index 05f3f38031ee..bb91062d5f1d 100644
--- a/drivers/pwm/pwm-stmpe.c
+++ b/drivers/pwm/pwm-stmpe.c
@@ -27,13 +27,12 @@
 
 struct stmpe_pwm {
 	struct stmpe *stmpe;
-	struct pwm_chip chip;
 	u8 last_duty;
 };
 
 static inline struct stmpe_pwm *to_stmpe_pwm(struct pwm_chip *chip)
 {
-	return container_of(chip, struct stmpe_pwm, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
@@ -292,33 +291,36 @@ static const struct pwm_ops stmpe_24xx_pwm_ops = {
 static int __init stmpe_pwm_probe(struct platform_device *pdev)
 {
 	struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
+	struct pwm_chip *chip;
 	struct stmpe_pwm *stmpe_pwm;
 	int ret;
 
-	stmpe_pwm = devm_kzalloc(&pdev->dev, sizeof(*stmpe_pwm), GFP_KERNEL);
-	if (!stmpe_pwm)
-		return -ENOMEM;
+	switch (stmpe->partnum) {
+	case STMPE2401:
+	case STMPE2403:
+		break;
+	case STMPE1601:
+		return dev_err_probe(&pdev->dev, -ENODEV,
+				     "STMPE1601 not yet supported\n");
+	default:
+		return dev_err_probe(&pdev->dev, -ENODEV,
+				     "Unknown STMPE PWM\n");
+	}
+
+	chip = devm_pwmchip_alloc(&pdev->dev, 3, sizeof(*stmpe_pwm));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	stmpe_pwm = to_stmpe_pwm(chip);
 
 	stmpe_pwm->stmpe = stmpe;
-	stmpe_pwm->chip.dev = &pdev->dev;
 
-	if (stmpe->partnum == STMPE2401 || stmpe->partnum == STMPE2403) {
-		stmpe_pwm->chip.ops = &stmpe_24xx_pwm_ops;
-		stmpe_pwm->chip.npwm = 3;
-	} else {
-		if (stmpe->partnum == STMPE1601)
-			dev_err(&pdev->dev, "STMPE1601 not yet supported\n");
-		else
-			dev_err(&pdev->dev, "Unknown STMPE PWM\n");
-
-		return -ENODEV;
-	}
+	chip->ops = &stmpe_24xx_pwm_ops;
 
 	ret = stmpe_enable(stmpe, STMPE_BLOCK_PWM);
 	if (ret)
 		return ret;
 
-	ret = pwmchip_add(&stmpe_pwm->chip);
+	ret = pwmchip_add(chip);
 	if (ret) {
 		stmpe_disable(stmpe, STMPE_BLOCK_PWM);
 		return ret;
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:03 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:03 +0100
Subject: [PATCH v6 076/164] pwm: mxs: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <39203f3bfbf4e97654db78bdc7e0c9a2b72c1368.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-mxs driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Also convert the to_mxs_pwm_chip() helper macro to a static inline to
get some type safety.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-mxs.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/pwm/pwm-mxs.c b/drivers/pwm/pwm-mxs.c
index 1b5e787d78f1..8cad214b1c29 100644
--- a/drivers/pwm/pwm-mxs.c
+++ b/drivers/pwm/pwm-mxs.c
@@ -37,12 +37,14 @@ static const u8 cdiv_shift[PERIOD_CDIV_MAX] = {
 };
 
 struct mxs_pwm_chip {
-	struct pwm_chip chip;
 	struct clk *clk;
 	void __iomem *base;
 };
 
-#define to_mxs_pwm_chip(_chip) container_of(_chip, struct mxs_pwm_chip, chip)
+static inline struct mxs_pwm_chip *to_mxs_pwm_chip(struct pwm_chip *chip)
+{
+	return pwmchip_get_drvdata(chip);
+}
 
 static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			 const struct pwm_state *state)
@@ -120,12 +122,21 @@ static const struct pwm_ops mxs_pwm_ops = {
 static int mxs_pwm_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
+	struct pwm_chip *chip;
 	struct mxs_pwm_chip *mxs;
+	u32 npwm;
 	int ret;
 
-	mxs = devm_kzalloc(&pdev->dev, sizeof(*mxs), GFP_KERNEL);
-	if (!mxs)
-		return -ENOMEM;
+	ret = of_property_read_u32(np, "fsl,pwm-number", &npwm);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to get pwm number: %d\n", ret);
+		return ret;
+	}
+
+	chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*mxs));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	mxs = to_mxs_pwm_chip(chip);
 
 	mxs->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(mxs->base))
@@ -135,21 +146,14 @@ static int mxs_pwm_probe(struct platform_device *pdev)
 	if (IS_ERR(mxs->clk))
 		return PTR_ERR(mxs->clk);
 
-	mxs->chip.dev = &pdev->dev;
-	mxs->chip.ops = &mxs_pwm_ops;
-
-	ret = of_property_read_u32(np, "fsl,pwm-number", &mxs->chip.npwm);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "failed to get pwm number: %d\n", ret);
-		return ret;
-	}
+	chip->ops = &mxs_pwm_ops;
 
 	/* FIXME: Only do this if the PWM isn't already running */
 	ret = stmp_reset_block(mxs->base);
 	if (ret)
 		return dev_err_probe(&pdev->dev, ret, "failed to reset PWM\n");
 
-	ret = devm_pwmchip_add(&pdev->dev, &mxs->chip);
+	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to add pwm chip %d\n", ret);
 		return ret;
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:48 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:48 +0100
Subject: [PATCH v6 121/164] pwm: stm32-lp: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <04af7b3d00bc932dd025200a3bf74527c29ca47a.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-stm32-lp driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stm32-lp.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
index 958043bc5c92..989731256f50 100644
--- a/drivers/pwm/pwm-stm32-lp.c
+++ b/drivers/pwm/pwm-stm32-lp.c
@@ -18,14 +18,13 @@
 #include <linux/pwm.h>
 
 struct stm32_pwm_lp {
-	struct pwm_chip chip;
 	struct clk *clk;
 	struct regmap *regmap;
 };
 
 static inline struct stm32_pwm_lp *to_stm32_pwm_lp(struct pwm_chip *chip)
 {
-	return container_of(chip, struct stm32_pwm_lp, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 /* STM32 Low-Power Timer is preceded by a configurable power-of-2 prescaler */
@@ -200,16 +199,14 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev)
 	struct pwm_chip *chip;
 	int ret;
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
+	chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*priv));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	priv = to_stm32_pwm_lp(chip);
 
 	priv->regmap = ddata->regmap;
 	priv->clk = ddata->clk;
-	chip = &priv->chip;
-	chip->dev = &pdev->dev;
 	chip->ops = &stm32_pwm_lp_ops;
-	chip->npwm = 1;
 
 	ret = devm_pwmchip_add(&pdev->dev, chip);
 	if (ret < 0)
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:44 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:44 +0100
Subject: [PATCH v6 117/164] pwm: stm32: Make use of devm_pwmchip_alloc() function
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <59e5dfff2b878cc8590e286572672e4f10e35380.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the pwm-stm32 driver to further changes of the pwm core
outlined in the commit introducing devm_pwmchip_alloc(). There is no
intended semantical change and the driver should behave as before.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stm32.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index 1440b706ee57..0c028d17c075 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -27,7 +27,6 @@ struct stm32_breakinput {
 };
 
 struct stm32_pwm {
-	struct pwm_chip chip;
 	struct mutex lock; /* protect pwm config/enable */
 	struct clk *clk;
 	struct regmap *regmap;
@@ -40,7 +39,7 @@ struct stm32_pwm {
 
 static inline struct stm32_pwm *to_stm32_pwm_dev(struct pwm_chip *chip)
 {
-	return container_of(chip, struct stm32_pwm, chip);
+	return pwmchip_get_drvdata(chip);
 }
 
 static u32 active_channels(struct stm32_pwm *dev)
@@ -632,14 +631,16 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 	struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent);
 	struct pwm_chip *chip;
 	struct stm32_pwm *priv;
-	unsigned int num_enabled;
+	unsigned int npwm, num_enabled;
 	unsigned int i;
 	int ret;
 
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-	chip = &priv->chip;
+	npwm = stm32_pwm_detect_channels(ddata->regmap, &num_enabled);
+
+	chip = devm_pwmchip_alloc(dev, npwm, sizeof(*priv));
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+	priv = to_stm32_pwm_dev(chip);
 
 	mutex_init(&priv->lock);
 	priv->regmap = ddata->regmap;
@@ -655,9 +656,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 
 	stm32_pwm_detect_complementary(priv);
 
-	chip->dev = dev;
 	chip->ops = &stm32pwm_ops;
-	chip->npwm = stm32_pwm_detect_channels(ddata->regmap, &num_enabled);
 
 	/* Initialize clock refcount to number of enabled PWM channels. */
 	for (i = 0; i < num_enabled; i++)
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 14 01:32:42 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 14 Feb 2024 10:32:42 +0100
Subject: [PATCH v6 115/164] pwm: stm32: Prepare removing pwm_chip from driver data
In-Reply-To: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <3db96cd915d9d8fc350a7193c0d55dd109b1f035.1707900770.git.u.kleine-koenig@pengutronix.de>

This prepares the driver for further changes that will drop struct
pwm_chip chip from struct stm32_pwm. Use the pwm_chip as driver
data instead of the stm32_pwm to get access to the pwm_chip in
stm32_pwm_suspend() without using priv->chip.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/pwm/pwm-stm32.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index ec15bc51d930..4d12f3d849cd 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -630,6 +630,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent);
+	struct pwm_chip *chip;
 	struct stm32_pwm *priv;
 	unsigned int num_enabled;
 	unsigned int i;
@@ -638,6 +639,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
+	chip = &priv->chip;
 
 	mutex_init(&priv->lock);
 	priv->regmap = ddata->regmap;
@@ -653,37 +655,38 @@ static int stm32_pwm_probe(struct platform_device *pdev)
 
 	stm32_pwm_detect_complementary(priv);
 
-	priv->chip.dev = dev;
-	priv->chip.ops = &stm32pwm_ops;
-	priv->chip.npwm = stm32_pwm_detect_channels(priv, &num_enabled);
+	chip->dev = dev;
+	chip->ops = &stm32pwm_ops;
+	chip->npwm = stm32_pwm_detect_channels(priv, &num_enabled);
 
 	/* Initialize clock refcount to number of enabled PWM channels. */
 	for (i = 0; i < num_enabled; i++)
 		clk_enable(priv->clk);
 
-	ret = devm_pwmchip_add(dev, &priv->chip);
+	ret = devm_pwmchip_add(dev, chip);
 	if (ret < 0)
 		return ret;
 
-	platform_set_drvdata(pdev, priv);
+	platform_set_drvdata(pdev, chip);
 
 	return 0;
 }
 
 static int stm32_pwm_suspend(struct device *dev)
 {
-	struct stm32_pwm *priv = dev_get_drvdata(dev);
+	struct pwm_chip *chip = dev_get_drvdata(dev);
+	struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
 	unsigned int i;
 	u32 ccer, mask;
 
 	/* Look for active channels */
 	ccer = active_channels(priv);
 
-	for (i = 0; i < priv->chip.npwm; i++) {
+	for (i = 0; i < chip->npwm; i++) {
 		mask = TIM_CCER_CC1E << (i * 4);
 		if (ccer & mask) {
 			dev_err(dev, "PWM %u still in use by consumer %s\n",
-				i, priv->chip.pwms[i].label);
+				i, chip->pwms[i].label);
 			return -EBUSY;
 		}
 	}
@@ -693,7 +696,8 @@ static int stm32_pwm_suspend(struct device *dev)
 
 static int stm32_pwm_resume(struct device *dev)
 {
-	struct stm32_pwm *priv = dev_get_drvdata(dev);
+	struct pwm_chip *chip = dev_get_drvdata(dev);
+	struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
 	int ret;
 
 	ret = pinctrl_pm_select_default_state(dev);
-- 
2.43.0



From james.clark at arm.com  Wed Feb 14 01:36:10 2024
From: james.clark at arm.com (James Clark)
Date: Wed, 14 Feb 2024 09:36:10 +0000
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename
 qcom,dsb-element-size
In-Reply-To: <a062ce8d-638a-4a33-8afa-45ad47efcd72@quicinc.com>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
 <20240213160521.15925-2-quic_jinlmao@quicinc.com>
 <20240213222957.GA2502642-robh@kernel.org>
 <a062ce8d-638a-4a33-8afa-45ad47efcd72@quicinc.com>
Message-ID: <df3162c0-4b29-77a2-20b5-b36637fb11cf@arm.com>



On 14/02/2024 01:43, Jinlong Mao wrote:
> 
> On 2/14/2024 6:29 AM, Rob Herring wrote:
>> On Tue, Feb 13, 2024 at 08:05:17AM -0800, Mao Jinlong wrote:
>>> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
>>> bit.
>> That may be, but this is an ABI and you are stuck with it. Unless, you
>> can justify why that doesn't matter. (IIRC, this is new, so maybe no
>> users yet?)
> 
> Hi Rob,
> 
> Because for CMB type, it uses qcom,cmb-element-bits. So I change the
> format to be the same as
> CMB.
> 
> Thanks
> Jinlong Mao
> 

I think what Rob was trying to say was that in the interest of not
breaking existing DTs it's best to leave the existing names as they are,
even if they aren't technically correct. And to only add new parameters
with the -bits suffix, even if it's inconsistent with what's already there.



From conor at kernel.org  Wed Feb 14 01:38:32 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 14 Feb 2024 09:38:32 +0000
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI
 TPS65224 PMIC
In-Reply-To: <20240214093106.86483-1-bhargav.r@ltts.com>
References: <20240209-blitz-fidgety-78469aa80d6d@spud>
 <20240214093106.86483-1-bhargav.r@ltts.com>
Message-ID: <20240214-galley-dweller-1e9872229d80@spud>

On Wed, Feb 14, 2024 at 03:01:06PM +0530, Bhargav Raviprakash wrote:
> Hi Conor,
> 
> On Fri 2/9/2024 10:41 PM, Conor Dooley wrote:
> > On Thu, Feb 08, 2024 at 04:23:33PM +0530, Bhargav Raviprakash wrote:
> > > TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
> > > regulators, it includes additional features like GPIOs, watchdog, ESMs
> > > (Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
> > > managing the state of the device.
> > 
> > > TPS6594 and TPS65224 have significant functional overlap.
> > 
> > What does "significant functional overlap" mean? Does one implement a
> > compatible subset of the other? I assume the answer is no, given there
> > seems to be some core looking registers at different addresses.
> 
> The intention behind ?significant functional overlap? was meant to
> indicate a lot of the features between TPS6594 and TPS65224 overlap,
> while there are some features specific to TPS65224.
> There is compatibility between the PMIC register maps, I2C, PFSM,
> and other drivers even though there are some core registers at
> different addresses.
> 
> Would it be more appropriate to say the 2 devices are compatible and have
> sufficient feature overlap rather than significant functional overlap?

If core registers are at different addresses, then it is unlikely that
these devices are compatible. In this context, compatible means that
existing software intended for the 6594 would run without modification
on the 65224, although maybe only supporting a subset of features.
If that's not the case, then the devices are not compatible.
-------------- 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/20240214/dedf311b/attachment-0001.sig>

From Ben.Gainey at arm.com  Wed Feb 14 01:40:57 2024
From: Ben.Gainey at arm.com (Ben Gainey)
Date: Wed, 14 Feb 2024 09:40:57 +0000
Subject: [RFC PATCH 0/2] perf: A mechanism for efficient support for
 per-function metrics
In-Reply-To: <20240123113420.1928154-1-ben.gainey@arm.com>
References: <20240123113420.1928154-1-ben.gainey@arm.com>
Message-ID: <7b6c55a93f5064147b85795d471a8ae990817d3b.camel@arm.com>

Hi all

Appreciate everyone is busy, but if you have some time I'd appreciate
some comments, particularly around whether this make sense to approach
as an Arm-only PMU feature or has wider applicability?

Thanks
Ben




On Tue, 2024-01-23 at 11:34 +0000, Ben Gainey wrote:
> I've been working on an approach to supporting per-function metrics
> for
> aarch64 cores, which requires some changes to the arm_pmuv3 driver,
> and
> I'm wondering if this approach would make sense as a generic feature
> that could be used to enable the same on other architectures?
> 
> The basic idea is as follows:
> 
> ?* Periodically sample one or more counters as needed for the chosen
> ?? set of metrics.
> ?* Record a sample count for each symbol so as to identify hot
> ?? functions.
> ?* Accumulate counter totals for each of the counters in each of the
> ?? metrics *but* only do this where the previous sample's symbol
> ?? matches the current sample's symbol.
> 
> Discarding the counter deltas for any given sample is important to
> ensure that couters are correctly attributed to a single function,
> without this step the resulting metrics trend towards some average
> value across the top 'n' functions. It is acknowledged that it is
> possible for this heuristic to fail, for example if samples to land
> either side of a nested call, so a sufficiently small sample window
> over which the counters are collected must be used to reduce the risk
> of misattribution.
> 
> So far, this can be acheived without any further modifications to
> perf
> tools or the kernel. However as noted it requires the counter
> collection window to be sufficiently small; in testing on
> Neoverse-N1/-V1, a window of about 300 cycles gives good results.
> Using
> the cycle counter with a sample_period of 300 is possible, but such
> an
> approach generates significant amounts of capture data, and
> introduces
> a lot of overhead and probe effect. Whilst the kernel will throttle
> such a configuration, which helps to mitigate a large portion of the
> bandwidth and capture overhead, it is not something that can be
> controlled for on a per event basis, or for non-root users, and
> because
> throttling is controlled as a percentage of time its affects vary
> from
> machine to machine.
> 
> For this to work efficiently, it is useful to provide a means to
> decouple the sample window (time over which events are counted) from
> the sample period (time between interesting samples). This patcheset
> modifies the Arm PMU driver to support alternating between two
> sample_period values, providing a simple and inexpensive way for
> tools
> to separate out the sample period and the sample window. It is
> expected
> to be used with the cycle counter event, alternating between a long
> and
> short period and subsequently discarding the counter data for samples
> with the long period. The combined long and short period gives the
> overall sampling period, and the short sample period gives the sample
> window. The symbol taken from the sample at the end of the long
> period
> can be used by tools to ensure correct attribution as described
> previously. The cycle counter is recommended as it provides fair
> temporal distribution of samples as would be required for the
> per-symbol sample count mentioned previously, and because the PMU can
> be programmed to overflow after a sufficiently short window; this may
> not be possible with software timer (for example). This patch does
> not
> restrict to only the cycle counter, it is possible there could be
> other
> novel uses based on different events.
> 
> To test this I have developed a simple `perf script` based python
> script. For a limited set of Arm PMU events it will post process a
> `perf record`-ing and generate a table of metrics. Along side this I
> have developed a benchmark application that rotates through a
> sequence
> of different classes of behaviour that can be detected by the Arm PMU
> (eg. mispredics, cache misses, different instruction mixes). The path
> through the benchmark can be rotated after each iteration so as to
> ensure the results don't land on some lucky harmonic with the sample
> period. The script can be used with and without the strobing patch
> allowing comparison of the results. Testing was on Juno (A53+A57), 
> N1SDP, Gravaton 2 and 3. In addition this approach has been applied
> to
> a few of Arm's tools projects and has correctly identified
> improvements
> and regressions. 
> 
> Headline results from testing indicate that ~300 cycles sample window
> gives good results with or without the strobing patch. When the
> strobing patch is used, the resulting `perf.data` files are typically
> 25-50x smaller that without, and take ~25x less time for the python
> script to post-process. Without strobing, the test application's
> runtime was x20 slower when sampling every 300 cycles as compared to
> every 1000000 cycles. With strobing enabled such that the long period
> was 999700 cycles and the short period was 300 cycles, the test
> applications runtime was only x1.2 slower than every 1000000 cycles.
> Notably, without the patch, L1D cache miss rates are significantly
> higher than with the patch, which we attribute to increased impact on
> the cache that trapping into the kernel every 300 cycles has. These
> results are given with `perf_cpu_time_max_percent=25`. When tested
> with `perf_cpu_time_max_percent=100` the size and time comparisons
> are
> more significant. Disabling throttling did not lead to obvious
> improvements in the collected metrics, suggesting that the sampling
> approach is sufficient to collect representative metrics.
> 
> Cursory testing on a Xeon(R) W-2145 sampling every 300 cycles
> (without
> the patch) suggests this approach would work for some counters.
> Calculating branch miss rates for example appears to be correct,
> likewise UOPS_EXECUTED.THREAD seems to give something like a sensible
> cycles-per-uop value. On the other hand the fixed function
> instructions
> counter does not appear to sample correctly (it seems to report
> either
> very small or very large numbers). No idea whats going on there, so
> any
> insight welcome...
> 
> This patch modifies the arm_pmu and introduces an additional field in
> config2 to configure the behaviour. If we think there is broad
> applicability, would it make sense to move into perf_event_attr flags
> or field, and possibly pull up into core? If we don't think so, then
> some feedback around the core header and arm_pmu modifications would
> be appreciated.
> 
> A copy of the post-processing script is available at 
> https://github.com/ARM-
> software/gator/blob/prototypes/strobing/prototypes/strobing-
> patches/test-script/generate-function-metrics.py
> note that the script its self has a dependency on
> https://lore.kernel.org/linux-perf-users/20240123103137.1890779-1-
> ben.gainey at arm.com/
> 
> 
> Ben Gainey (2):
> ? arm_pmu: Allow the PMU to alternate between two sample_period
> values.
> ? arm_pmuv3: Add config bits for sample period strobing
> 
> ?drivers/perf/arm_pmu.c?????? | 74 +++++++++++++++++++++++++++++-----
> --
> ?drivers/perf/arm_pmuv3.c???? | 25 ++++++++++++
> ?include/linux/perf/arm_pmu.h |? 1 +
> ?include/linux/perf_event.h?? | 10 ++++-
> ?4 files changed, 95 insertions(+), 15 deletions(-)
> 


From vigneshr at ti.com  Wed Feb 14 01:42:56 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Wed, 14 Feb 2024 15:12:56 +0530
Subject: [PATCH v2 3/3] arm64: dts: ti: Add support for TI J722S
 Evaluation Module
In-Reply-To: <45bd5618-2e22-4715-9724-92f1d4b84608@ti.com>
References: <20240206100608.127702-1-vaishnav.a@ti.com>
 <20240206100608.127702-4-vaishnav.a@ti.com>
 <CZ386ITQ83KH.1KNOV5MXLXPBF@kernel.org>
 <45bd5618-2e22-4715-9724-92f1d4b84608@ti.com>
Message-ID: <40e15761-70b3-4343-a4b3-653bc4e6637e@ti.com>



On 14/02/24 13:13, Vaishnav Achath wrote:
> Hi Michael,
> 
> On 12/02/24 21:32, Michael Walle wrote:
>> Hi,
>>
>> On Tue Feb 6, 2024 at 11:06 AM CET, Vaishnav Achath wrote:
>>> +# Boards with J722s SoC
>>> +dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb
>>
>> I'm a bit confused by your names. What are the new/correct ones now?
>> Some seem to use the amXX names and some the jXX ones. I've read [1]
>> and it appears it was suggested to use the am67 names for the device
>> trees. Esp. because there is already, am62, am64, am65, am68 and
>> am69 in as names for the device trees.
>>
>> The TRM you've linked in the cover letter doesn't shed much light
>> either. It just lists both.
>>
> 
> Both names are correct, for other Jacinto devices J721S2 and J784S4, the
> industrial variants (AM68, AM69 respectively) and those boards were
> announced at a later point of time and since the automotive/J7 variants
> were introduced first, the SoC dtsi and files have the J7XX names, for
> AM62/AM64 there is no confusion in naming, in this case the initial TRM
> itself mentions J722S and AM67 variants with similar capabilities, the
> reasoning behind continuing with the J722S name is because the initial
> support is being added for J722S EVM (the top marking on the SoC package
> populated on the EVM say XJ722SAMW, this can be seen in the schematics
> also), please let know if this clarifies the confusion.
> 

AM64,AM62x/A/P are from different product line (Sitara) and don't have
any other aliases.

On the other hand, Jacinto SoCs have both J7xx variant and AM6xx part
numbers. Its being really unpredictable wrt when AM6xx variants of
Jacinto devices come out. So as a general rule, we name the DTS files
based on the name of the first device that comes out in the market which
has consistently been J7xx.

-- 
Regards
Vignesh


From andrejs.cainikovs at toradex.com  Wed Feb 14 01:46:01 2024
From: andrejs.cainikovs at toradex.com (Andrejs Cainikovs)
Date: Wed, 14 Feb 2024 10:46:01 +0100
Subject: [PATCH v1] arm64: dts: ti: k3-am62-main: disable usb lpm
In-Reply-To: <2629cd30-23aa-4f03-8452-ae13297fd6b6@kernel.org>
References: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
 <2629cd30-23aa-4f03-8452-ae13297fd6b6@kernel.org>
Message-ID: <b27e4519-a9fc-43bb-be6b-35d69d65755d@toradex.com>

On 12/02/2024 13:13, Roger Quadros wrote:
> Hi Andrejs,
> 
> On 09/02/2024 15:02, Andrejs Cainikovs wrote:
>> From: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
>>
>> AM62 USB works with some devices, while failing to operate with others.
> 
> Could you please share which devices failed to work for you?

Hi Roger,

This USB memory stick is the one that is failing most of the time:
ID 058f:6387 Alcor Micro Corp. Flash Drive (DigiKey 1GB)

I used following test to reproduce the issue: boot without any devices
connected, once booted - connect to PC for gadget mode (RNDIS), and then
unplug cable and connect USB drive.

I did not had any failures with this USB memory stick, btw:
ID 0951:1643 Kingston Technology DataTraveler G3

/Andrejs
>>
>> [  560.189822] xhci-hcd xhci-hcd.4.auto: xHCI Host Controller
>> [  560.195631] xhci-hcd xhci-hcd.4.auto: new USB bus registered, assigned bus number 2
>> [  574.388509] xhci-hcd xhci-hcd.4.auto: can't setup: -110
>> [  574.393814] xhci-hcd xhci-hcd.4.auto: USB bus 2 deregistered
>> [  574.399544] xhci-hcd: probe of xhci-hcd.4.auto failed with error -110
>>
>> This seems to be related to LPM (Link Power Management), and disabling it
>> turns USB into reliable working state.
>>
>> As per AM62 reference manual:
>>
>>> 4.8.2.1 USB2SS Unsupported Features
>>>
>>> The following features are not supported on this family of devices:
>>> ...
>>> - USB 2.0 ECN: Link Power Management (LPM)
>>> ...
>>
>> Fixes: 2240f96cf3cd ("arm64: dts: ti: k3-am62-main: Add support for USB")
>> Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>
>> ---
>>  arch/arm64/boot/dts/ti/k3-am62-main.dtsi | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>> index 464b7565d085..c49fbce5cb70 100644
>> --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>> +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
>> @@ -640,6 +640,8 @@ usb0: usb at 31000000 {
>>  			interrupt-names = "host", "peripheral";
>>  			maximum-speed = "high-speed";
>>  			dr_mode = "otg";
>> +			snps,usb2-gadget-lpm-disable;
>> +			snps,usb2-lpm-disable;
>>  		};
>>  	};
>>  
>> @@ -663,6 +665,8 @@ usb1: usb at 31100000 {
>>  			interrupt-names = "host", "peripheral";
>>  			maximum-speed = "high-speed";
>>  			dr_mode = "otg";
>> +			snps,usb2-gadget-lpm-disable;
>> +			snps,usb2-lpm-disable;
>>  		};
>>  	};
>>  
> 
> Instead of this could you please check if this series fixes the issue for you?
> https://lore.kernel.org/all/20240205141221.56076-1-rogerq at kernel.org/
>



From krzysztof.kozlowski at linaro.org  Wed Feb 14 01:53:31 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 14 Feb 2024 10:53:31 +0100
Subject: [PATCH] Add eSPI device driver (flash channel)
In-Reply-To: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
References: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
Message-ID: <630b892e-a948-4683-97bd-5633fc81f917@linaro.org>

On 13/02/2024 15:36, Manojkiran Eda wrote:
> This patch adds the driver support for the eSPI controller of
> Aspeed 5/6th generation SoCs. This controller is a slave device
> communicating with a master over Enhanced Serial Peripheral
> Interface (eSPI).
> 
> eSPI supports 4 channels, namely peripheral, virtual wire,
> out-of-band, and flash, and operates at max frequency of 66MHz.
> 
> But at the moment, this patch set only supports the flash channel.
> 
> Signed-off-by: Manojkiran Eda <manojkiran.eda at gmail.com>
> ---
> Hello everyone,
> 
> I'm presenting a revised version of the eSPI device driver patch series found at the following link:
> 
> https://lore.kernel.org/openbmc/20220516005412.4844-1-chiawei_wang at aspeedtech.com/ 

What changed? Please provide changelog and continue with versioning.


> 
> This update addresses the issues identified during the review process.
> 
> While the previous patch series attempted to incorporate support for all four different channels of eSPI,
> this new series focuses on upstreaming the flash channel initially, ensuring that all review comments are
> duly addressed, before progressing further.
> 
> Results:
> 
> Successfully conducted a flash update via eSPI.
> 
> Note:
> 
> This marks my inaugural endeavor in contributing code to the kernel subsystem. I kindly request reviewers
> to incorporate as many details as possible in the review comments.
> ---
>  .../devicetree/bindings/soc/aspeed/espi.yaml       | 125 ++++++
>  arch/arm/boot/dts/aspeed/aspeed-g6.dtsi            |  16 +-

These are all separatge patches.

Please run scripts/checkpatch.pl and fix reported warnings. Some
warnings can be ignored, but the code here looks like it needs a fix.
Feel free to get in touch if the warning is not clear.

>  drivers/mtd/mtdcore.c                              |   2 +-
>  drivers/soc/aspeed/Kconfig                         |  10 +
>  drivers/soc/aspeed/Makefile                        |   3 +
>  drivers/soc/aspeed/aspeed-espi-ctrl.c              | 197 +++++++++
>  drivers/soc/aspeed/aspeed-espi-ctrl.h              | 169 ++++++++
>  drivers/soc/aspeed/aspeed-espi-flash.c             | 466 +++++++++++++++++++++
>  drivers/soc/aspeed/aspeed-espi-flash.h             |  45 ++
>  include/uapi/linux/espi/aspeed-espi-ioc.h          | 103 +++++
>  10 files changed, 1134 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/soc/aspeed/espi.yaml b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> new file mode 100644
> index 000000000000..6521a351d18d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> @@ -0,0 +1,125 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# # Copyright (c) 2021 Aspeed Technology Inc.
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/soc/aspeed/espi.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"

It does not look like you tested the bindings, at least after quick
look. Please run `make dt_binding_check` (see
Documentation/devicetree/bindings/writing-schema.rst for instructions).
Maybe you need to update your dtschema and yamllint.

Not reviewing further. Test your code....

Best regards,
Krzysztof



From ak at linux.intel.com  Wed Feb 14 01:55:23 2024
From: ak at linux.intel.com (Andi Kleen)
Date: Wed, 14 Feb 2024 01:55:23 -0800
Subject: [RFC PATCH 0/2] A mechanism for efficient support for
 per-function metrics
In-Reply-To: <20240123113420.1928154-1-ben.gainey@arm.com> (Ben Gainey's
	message of "Tue, 23 Jan 2024 11:34:18 +0000")
References: <20240123113420.1928154-1-ben.gainey@arm.com>
Message-ID: <87r0hfwet0.fsf@linux.intel.com>

Ben Gainey <ben.gainey at arm.com> writes:

> I've been working on an approach to supporting per-function metrics for
> aarch64 cores, which requires some changes to the arm_pmuv3 driver, and
> I'm wondering if this approach would make sense as a generic feature
> that could be used to enable the same on other architectures?
>
> The basic idea is as follows:
>
>  * Periodically sample one or more counters as needed for the chosen
>    set of metrics.
>  * Record a sample count for each symbol so as to identify hot
>    functions.
>  * Accumulate counter totals for each of the counters in each of the
>    metrics *but* only do this where the previous sample's symbol
>    matches the current sample's symbol.

It sounds very similar to what perf script -F +metric already does
(or did if it wasn't broken currently). It would be a straight forward
extension here to add this "same as previous" check.

Of course the feature is somewhat dubious in that it will have a very
strong systematic bias against short functions and even long functions
in some alternating execution patterns. I assume you did some
experiments to characterize this. It would be important
to emphasize this in any documentation.

> For this to work efficiently, it is useful to provide a means to
> decouple the sample window (time over which events are counted) from
> the sample period (time between interesting samples). This patcheset
> modifies the Arm PMU driver to support alternating between two
> sample_period values, providing a simple and inexpensive way for tools
> to separate out the sample period and the sample window. It is expected
> to be used with the cycle counter event, alternating between a long and
> short period and subsequently discarding the counter data for samples
> with the long period. The combined long and short period gives the
> overall sampling period, and the short sample period gives the sample
> window. The symbol taken from the sample at the end of the long period
> can be used by tools to ensure correct attribution as described
> previously. The cycle counter is recommended as it provides fair
> temporal distribution of samples as would be required for the
> per-symbol sample count mentioned previously, and because the PMU can
> be programmed to overflow after a sufficiently short window; this may
> not be possible with software timer (for example). This patch does not
> restrict to only the cycle counter, it is possible there could be other
> novel uses based on different events.

I don't see anything ARM specific with the technique, so if it's done
it should be done generically IMHO


> Cursory testing on a Xeon(R) W-2145 sampling every 300 cycles (without
> the patch) suggests this approach would work for some counters.
> Calculating branch miss rates for example appears to be correct,
> likewise UOPS_EXECUTED.THREAD seems to give something like a sensible
> cycles-per-uop value. On the other hand the fixed function instructions
> counter does not appear to sample correctly (it seems to report either
> very small or very large numbers). No idea whats going on there, so any
> insight welcome...

If you use precise samples with 3p there is a restriction on the periods
that is enforced by the kernel. Non precise or single/double p should
support arbitrary, except that any p is always period + 1.

One drawback of the technique on x86 is that it won't allow multi record
pebs (collecting samples without interrupts), so the overhead might
be intrinsically higher.

-Andi


From alexander.stein at ew.tq-group.com  Wed Feb 14 01:56:44 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 14 Feb 2024 10:56:44 +0100
Subject: [PATCH 1/1] arm64: dts: freescale: tqma9352: Update I2C eeprom compatible
In-Reply-To: <20240212223501.GA2674720-robh@kernel.org>
References: <20240110100526.478771-1-alexander.stein@ew.tq-group.com> <20240212223501.GA2674720-robh@kernel.org>
Message-ID: <4899550.31r3eYUQgx@steina-w>

Hi Rob,

thanks for the feedback.

Am Montag, 12. Februar 2024, 23:35:01 CET schrieb Rob Herring:
> On Wed, Jan 10, 2024 at 11:05:26AM +0100, Alexander Stein wrote:
> > Now that there is a dedicated compatible for the idendification page use
> > that instead. This also allows the removal the size and pagesize
> > properties.
> 
> This commit message fails to answer Why?

The original DT entry using the regular "atmel,24c64" compatible is just a 
workaround. The size and pagesize properties are added to match that dedicated 
memory block.

> And fails to mention the ABI break.

Can you elaborate the ABI break?

> 
> > Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> > 
> >  arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi | 4 +---
> >  1 file changed, 1 insertion(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
> > b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi index
> > f6e422dc2663e..9d2328c185c90 100644
> > --- a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
> > @@ -122,10 +122,8 @@ eeprom1: eeprom at 57 {
> > 
> >  	/* protectable identification memory (part of M24C64-D @57) */
> >  	eeprom at 5f {
> > 
> > -		compatible = "st,24c64", "atmel,24c64";
> > +		compatible = "atmel,24c64d-wl";
> 
> This compatible is not documented. Please add it to schema.

It already is. Please refer to commit 0997ff1fc1436 ("dt-bindings: at24: add 
ST M24C64-D Additional Write lockable page").

Thanks,
Alexander

> >  		reg = <0x5f>;
> > 
> > -		size = <32>;
> > -		pagesize = <32>;
> > 
> >  		vcc-supply = <&reg_v3v3>;
> >  	
> >  	};


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From krzysztof.kozlowski at linaro.org  Wed Feb 14 01:57:35 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 14 Feb 2024 10:57:35 +0100
Subject: [PATCH 1/3] dt-bindings: auxdisplay: hit, hd44780: drop redundant
 GPIO node
In-Reply-To: <ZcucO8R8ZOtR38jl@smile.fi.intel.com>
References: <20240212083426.26757-1-krzysztof.kozlowski@linaro.org>
 <CAMuHMdU-c5_Z2AMNtNH4Cc4JUrn+oKU-1CumEOAP6=5Zomcj_A@mail.gmail.com>
 <2922eece-5486-4eff-af99-f7060cb61d17@linaro.org>
 <20240212115837.efz73yxinkysdmgh@runtux.com>
 <e2a5b005-7916-4296-b072-c24efd4b3357@linaro.org>
 <Zcogl6tqbMdQldKA@smile.fi.intel.com>
 <d603a588-d312-486e-b6c9-647a6b90580c@linaro.org>
 <20240213161905.GA1459669-robh@kernel.org>
 <ZcucO8R8ZOtR38jl@smile.fi.intel.com>
Message-ID: <d4337a53-8f4b-4782-8ce1-b0e4d7893e28@linaro.org>

On 13/02/2024 17:43, Andy Shevchenko wrote:
> On Tue, Feb 13, 2024 at 10:19:05AM -0600, Rob Herring wrote:
>> On Mon, Feb 12, 2024 at 02:59:02PM +0100, Krzysztof Kozlowski wrote:
>>> On 12/02/2024 14:43, Andy Shevchenko wrote:
>>>> On Mon, Feb 12, 2024 at 02:38:27PM +0100, Krzysztof Kozlowski wrote:
>>>>> On 12/02/2024 12:58, Ralf Schlatterbeck wrote:
> 
> ...
> 
>>>>> Anyway, binding examples should not be collection of unrelated
>>>>> solutions, because then we should accept for each device schema several
>>>>> other variations and combinations.
>>>>
>>>> Is this documented?
>>>
>>> Yes, writing schema says what the example is. We repeated it multiple
>>> times on multiple reviews, we made multiple commits multiple times and I
>>> briefly mentioned it also in my talks.
>>
>> While yes, this is the guidance, I think this case has provided enough
>> justification to keep it. Let's move on please.
> 
> Thank you, Rob.
> 
> Krzysztof, can you send v2, I'll apply it to the tree?

Sure.

Best regards,
Krzysztof



From conor at kernel.org  Wed Feb 14 02:06:44 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 14 Feb 2024 10:06:44 +0000
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible
 for MT7988
In-Reply-To: <e957b044-fe84-4b72-bdf1-cbc40c722019@collabora.com>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <20240213-resource-evaluator-0754cfd5882d@spud>
 <d4391868-ddcd-4f66-b539-28d245fa83df@gmail.com>
 <e957b044-fe84-4b72-bdf1-cbc40c722019@collabora.com>
Message-ID: <20240214-reversion-arguably-37bbee9caf78@spud>

On Wed, Feb 14, 2024 at 10:27:54AM +0100, AngeloGioacchino Del Regno wrote:
> Il 14/02/24 07:34, Rafa? Mi?ecki ha scritto:
> > On 13.02.2024 19:18, Conor Dooley wrote:
> > > On Tue, Feb 13, 2024 at 05:46:32PM +0100, Rafa? Mi?ecki wrote:
> > > > From: Rafa? Mi?ecki <rafal at milecki.pl>
> > > > 
> > > > MT7988 has on-SoC controller that can control up to 8 PWMs.
> > > 
> > > I see a binding and a dts patch, but no driver patch, how come?
> > 
> > I believe that to avoid cross-trees patchsets (which are sometimes
> > tricky for maintainers) there are two ways of submiting such changes:
> > 1. dt-binding + driver; then (separately) DTS
> > 2. dt-binding + DTS; then (separately) driver
> > 
> > I chose later in this case as my personal priority right now is to deal
> > with all MediaTek DTS files.
> > 
> > Is that wrong or unacceptable?
> > 
> 
> It's not wrong but it's partially unacceptable, at least on my side.

> I want to put emphasis on sending the binding with the driver, as this allows
> for a better review on everyone's side because we do see the full picture and
> we can give better advices: in this case, I'm not sure whether adding a new
> compatible for MT7988 in an enum is a good idea, as the compatible string may
> be shared with one of the *eleven* SoCs that are supported in the PWM driver,
> meaning that (hardware speaking!) the PWM controller in 7988 might be the same
> as the one in mt1234.

Re-ordering to make my reply make more sense...

> In my opinion (and I believe many do agree with me), sending the binding along
> with the driver is the right choice, and if you also want to include the dts
> that is also appreciated: series can go through multiple maintainers applying
> subsets - it's ok to do.

Ye, either of those two makes my life a lot easier. I can then at least
go and check the driver patch to see if things match up. In this case, I
would want to check that the driver requires changes to support this
device, given the commit message mentions nothing about the difference
between this device and others. I'd still probably request that the
commit message be improved to explain the lack of a fallback, but at
least I would be clear about what I want and could provide a conditional
Ack.

If you're not sending the bindings patch with the driver, there's an
extra onus on you to explain exactly what makes this device incompatible
with the other devices in the enum, although in an ideal world it'd make
no difference and every bindings patch would contain that information.

> > 
> > > Also, what makes this incompatibly different with the other devices in
> > > the binding, like the 8183?
> > 
> > It can control 8 PWMs unlike any other SoC block except for MT2712.
> > It uses different registers than MT2712 thought.

Put this information in your commit message next time :)

Cheers,
Conor.
-------------- 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/20240214/cfbc9610/attachment-0001.sig>

From b-kapoor at ti.com  Wed Feb 14 02:12:17 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Wed, 14 Feb 2024 15:42:17 +0530
Subject: [RESEND PATCH v2 1/4] arm64: dts: ti: k3-j7200-common-proc-board:
 Modify Pinmux for wkup_uart0 and mcu_uart0
In-Reply-To: <2c1da868-0295-4398-8811-6367c589df52@ti.com>
References: <20240212104417.1058993-1-b-kapoor@ti.com>
 <20240212104417.1058993-2-b-kapoor@ti.com>
 <2c1da868-0295-4398-8811-6367c589df52@ti.com>
Message-ID: <a113aa78-82d5-48c8-bfd4-663144936798@ti.com>


On 14/02/24 12:58 pm, Vignesh Raghavendra wrote:
>
> On 12/02/24 16:14, Bhavya Kapoor wrote:
>> WKUP_PADCONFIG registers for wkup_uart0 and mcu_uart0 lies
>> under wkup_pmx2 for J7200. Thus, modify pinmux for both
>> of them.
>>
>> Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
>> ---
>
> This warrants a Fixes: tag. Can you provide one here? I can fix it up
> when merging.
Yes , i agree to that. I will send a v3 with the required changes
>>   .../boot/dts/ti/k3-j7200-common-proc-board.dts  | 17 +++++++++--------
>>   1 file changed, 9 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
>> index 1d8bddcae90e..160580a0584a 100644
>> --- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
>> @@ -119,24 +119,25 @@ transceiver3: can-phy3 {
>>   };
>>   
>>   &wkup_pmx0 {
>> +};
>> +
>> +&wkup_pmx2 {
>>   	mcu_uart0_pins_default: mcu-uart0-default-pins {
>>   		pinctrl-single,pins = <
>> -			J721E_WKUP_IOPAD(0xf4, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
>> -			J721E_WKUP_IOPAD(0xf0, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
>> -			J721E_WKUP_IOPAD(0xf8, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
>> -			J721E_WKUP_IOPAD(0xfc, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
>> +			J721E_WKUP_IOPAD(0x90, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
>> +			J721E_WKUP_IOPAD(0x94, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
>> +			J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
>> +			J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
>>   		>;
>>   	};
>>   
>>   	wkup_uart0_pins_default: wkup-uart0-default-pins {
>>   		pinctrl-single,pins = <
>> -			J721E_WKUP_IOPAD(0xb0, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
>> -			J721E_WKUP_IOPAD(0xb4, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
>> +			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
>> +			J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
>>   		>;
>>   	};
>> -};
>>   
>> -&wkup_pmx2 {
>>   	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
>>   		pinctrl-single,pins = <
>>   			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */


From vigneshr at ti.com  Wed Feb 14 02:13:15 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Wed, 14 Feb 2024 15:43:15 +0530
Subject: [PATCH v3 3/7] arm64: dts: ti: iot2050: Factor out arduino
 connector bits
In-Reply-To: <3366367dc9f190c9e21027b9a810886791e99245.1707463401.git.jan.kiszka@siemens.com>
References: <cover.1707463401.git.jan.kiszka@siemens.com>
 <3366367dc9f190c9e21027b9a810886791e99245.1707463401.git.jan.kiszka@siemens.com>
Message-ID: <4f122f5d-e430-4299-b6c5-bbe778aad736@ti.com>



On 09/02/24 12:53, Jan Kiszka wrote:
> From: Jan Kiszka <jan.kiszka at siemens.com>
> 
> A new variant is to be added which will not have a arduino connector
> like the existing ones. Factor out all bits that are specific to this
> connector.
> 
> The split is not perfect because wkup_gpio0 is defined based on what is
> common to all variants having the connector, thus containing also
> connector-unrelated information. But this is still cleaner than
> replicating this node into all 4 variants.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
> ---
>  .../ti/k3-am65-iot2050-arduino-connector.dtsi | 768 ++++++++++++++++++
>  .../boot/dts/ti/k3-am65-iot2050-common.dtsi   | 753 -----------------
>  .../ti/k3-am6528-iot2050-basic-common.dtsi    |   1 +
>  .../dts/ti/k3-am6548-iot2050-advanced-m2.dts  |   1 +
>  .../dts/ti/k3-am6548-iot2050-advanced-pg2.dts |   1 +
>  .../dts/ti/k3-am6548-iot2050-advanced.dts     |   1 +
>  6 files changed, 772 insertions(+), 753 deletions(-)
>  create mode 100644 
> arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
> 
> diff --git 
> a/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi 
> b/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
> new file mode 100644
> index 000000000000..cd86f412b837
> --- /dev/null
> +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
> @@ -0,0 +1,768 @@
> +// SPDX-License-Identifier: GPL-2.0

This and elsewhere in the series should be

// SPDX-License-Identifier: GPL-2.0-only

as fixed up by Nishanth in [0]. I can fix that locally, let me know.

[0] https://lore.kernel.org/r/20240122145539.194512-16-nm at ti.com

-- 
Regards
Vignesh


From suzuki.poulose at arm.com  Wed Feb 14 02:16:56 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 14 Feb 2024 10:16:56 +0000
Subject: [PATCH V4 03/11] coresight: tmc: Extract device properties from
 AMBA pid based table lookup
In-Reply-To: <14d4c862-0880-408c-bc4e-5047c7eace87@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-4-anshuman.khandual@arm.com>
 <44597c9a-79bd-40f8-87a7-b53582132583@arm.com>
 <0c65f3b0-a879-444c-b0a4-4af485e72166@arm.com>
 <39c01eae-049b-4f5b-b86e-4af22c8246c1@arm.com>
 <14d4c862-0880-408c-bc4e-5047c7eace87@arm.com>
Message-ID: <653d8ae0-4eed-4fa4-b7ac-0668af93c030@arm.com>

On 14/02/2024 03:35, Anshuman Khandual wrote:
> 
> 
> On 2/13/24 16:02, Suzuki K Poulose wrote:
>> On 13/02/2024 03:13, Anshuman Khandual wrote:
>>>
>>>
>>> On 2/12/24 17:43, Suzuki K Poulose wrote:
>>>> On 23/01/2024 05:46, Anshuman Khandual wrote:
>>>>> This extracts device properties from AMBA pid based table lookup. This also
>>>>> defers tmc_etr_setup_caps() after the coresight device has been initialized
>>>>> so that PID value can be read.
>>>>>
>>>>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>>>>> Cc: Mike Leach <mike.leach at linaro.org>
>>>>> Cc: James Clark <james.clark 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>
>>>>> ---
>>>>>  ?? .../hwtracing/coresight/coresight-tmc-core.c? | 19 +++++++++++++------
>>>>>  ?? 1 file changed, 13 insertions(+), 6 deletions(-)
>>>>>
>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
>>>>> index 7ec5365e2b64..e71db3099a29 100644
>>>>> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
>>>>> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
>>>>> @@ -370,16 +370,24 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
>>>>>  ?????? return (auth & TMC_AUTH_NSID_MASK) == 0x3;
>>>>>  ?? }
>>>>>  ?? +#define TMC_AMBA_MASK 0xfffff
>>>>> +
>>>>> +static const struct amba_id tmc_ids[];
>>>>> +
>>>>>  ?? /* Detect and initialise the capabilities of a TMC ETR */
>>>>> -static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
>>>>> +static int tmc_etr_setup_caps(struct device *parent, u32 devid)
>>>>>  ?? {
>>>>>  ?????? int rc;
>>>>> -??? u32 dma_mask = 0;
>>>>> +??? u32 tmc_pid, dma_mask = 0;
>>>>>  ?????? struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
>>>>> +??? void *dev_caps;
>>>>>  ?? ????? if (!tmc_etr_has_non_secure_access(drvdata))
>>>>>  ?????????? return -EACCES;
>>>>>  ?? +??? tmc_pid = coresight_get_pid(&drvdata->csdev->access) & TMC_AMBA_MASK;
>>>>> +??? dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid);
>>>>> +
>>>>>  ?????? /* Set the unadvertised capabilities */
>>>>>  ?????? tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
>>>>>  ?? @@ -497,10 +505,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>>>>  ?????????? desc.type = CORESIGHT_DEV_TYPE_SINK;
>>>>>  ?????????? desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
>>>>>  ?????????? desc.ops = &tmc_etr_cs_ops;
>>>>> -??????? ret = tmc_etr_setup_caps(dev, devid,
>>>>> -???????????????????? coresight_get_uci_data(id));
>>>>> -??????? if (ret)
>>>>> -??????????? goto out;
>>>>>  ?????????? idr_init(&drvdata->idr);
>>>>>  ?????????? mutex_init(&drvdata->idr_mutex);
>>>>>  ?????????? dev_list = &etr_devs;
>>>>> @@ -539,6 +543,9 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>>>>  ?????????? goto out;
>>>>>  ?????? }
>>>>>  ?? +??? if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
>>>>> +??????? ret = tmc_etr_setup_caps(dev, devid);
>>>>> +
>>>>
>>>> With this change, we silently accept an ETR that may only have "SECURE" access only and crash later while we try to enable tracing. You could
>>>> pass in the "access" (which is already in 'desc.access' in the original
>>>> call site and deal with it ?
>>>
>>> Just wondering, if something like the following will help ? A failed tmc_etr_setup_caps()
>>> because of failed tmc_etr_has_non_secure_access(), will unregister the coresight device
>>> before returning.
>>>
>>> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
>>> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
>>> @@ -538,8 +538,13 @@ static int __tmc_probe(struct device *dev, struct resource *res)
>>>  ???????????????? goto out;
>>>  ???????? }
>>>  ? -?????? if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
>>> +?????? if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
>>>  ???????????????? ret = tmc_etr_setup_caps(dev, devid);
>>> +?????????????? if (ret) {
>>> +?????????????????????? coresight_unregister(drvdata->csdev);
>>> +?????????????????????? goto out;
>>> +?????????????? }
>>> +?????? }
>>
>> Why do we move the tmc_etr_setup_caps() in the first place ? We could retain where that was and pass "desc.access" parameter rather than registering the csdev and then relying csdev->access ?
> 
> Agreed, and after implementing the changes suggested above, the entire patch
> will look something like the following. Please do confirm if this looks good
> enough.
> 
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -370,16 +370,25 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
>          return (auth & TMC_AUTH_NSID_MASK) == 0x3;
>   }
>   
> +#define TMC_AMBA_MASK 0xfffff
> +
> +static const struct amba_id tmc_ids[];
> +
>   /* Detect and initialise the capabilities of a TMC ETR */
> -static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
> +static int tmc_etr_setup_caps(struct device *parent, u32 devid,
> +                             struct csdev_access *access)
>   {
>          int rc;
> -       u32 dma_mask = 0;
> +       u32 tmc_pid, dma_mask = 0;
>          struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
> +       void *dev_caps;
>   
>          if (!tmc_etr_has_non_secure_access(drvdata))
>                  return -EACCES;
>   
> +       tmc_pid = coresight_get_pid(access) & TMC_AMBA_MASK;
> +       dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid);
> +
>          /* Set the unadvertised capabilities */
>          tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
>   
> @@ -497,8 +506,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>                  desc.type = CORESIGHT_DEV_TYPE_SINK;
>                  desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
>                  desc.ops = &tmc_etr_cs_ops;
> -               ret = tmc_etr_setup_caps(dev, devid,
> -                                        coresight_get_uci_data(id));
> +               ret = tmc_etr_setup_caps(dev, devid, &desc.access);
>                  if (ret)
>                          goto out;
>                  idr_init(&drvdata->idr);
> 

That looks much better. Thanks

Suzuki



From zajec5 at gmail.com  Wed Feb 14 02:19:10 2024
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Wed, 14 Feb 2024 11:19:10 +0100
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible for
 MT7988
In-Reply-To: <20240214-reversion-arguably-37bbee9caf78@spud>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <20240213-resource-evaluator-0754cfd5882d@spud>
 <d4391868-ddcd-4f66-b539-28d245fa83df@gmail.com>
 <e957b044-fe84-4b72-bdf1-cbc40c722019@collabora.com>
 <20240214-reversion-arguably-37bbee9caf78@spud>
Message-ID: <eb97a068-4de6-4500-993b-86737844de70@gmail.com>

On 14.02.2024 11:06, Conor Dooley wrote:
> On Wed, Feb 14, 2024 at 10:27:54AM +0100, AngeloGioacchino Del Regno wrote:
>> Il 14/02/24 07:34, Rafa? Mi?ecki ha scritto:
>>> On 13.02.2024 19:18, Conor Dooley wrote:
>>>> On Tue, Feb 13, 2024 at 05:46:32PM +0100, Rafa? Mi?ecki wrote:
>>>>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>>>>
>>>>> MT7988 has on-SoC controller that can control up to 8 PWMs.
>>>>
>>>> I see a binding and a dts patch, but no driver patch, how come?
>>>
>>> I believe that to avoid cross-trees patchsets (which are sometimes
>>> tricky for maintainers) there are two ways of submiting such changes:
>>> 1. dt-binding + driver; then (separately) DTS
>>> 2. dt-binding + DTS; then (separately) driver
>>>
>>> I chose later in this case as my personal priority right now is to deal
>>> with all MediaTek DTS files.
>>>
>>> Is that wrong or unacceptable?
>>>
>>
>> It's not wrong but it's partially unacceptable, at least on my side.
> 
>> I want to put emphasis on sending the binding with the driver, as this allows
>> for a better review on everyone's side because we do see the full picture and
>> we can give better advices: in this case, I'm not sure whether adding a new
>> compatible for MT7988 in an enum is a good idea, as the compatible string may
>> be shared with one of the *eleven* SoCs that are supported in the PWM driver,
>> meaning that (hardware speaking!) the PWM controller in 7988 might be the same
>> as the one in mt1234.
> 
> Re-ordering to make my reply make more sense...
> 
>> In my opinion (and I believe many do agree with me), sending the binding along
>> with the driver is the right choice, and if you also want to include the dts
>> that is also appreciated: series can go through multiple maintainers applying
>> subsets - it's ok to do.
> 
> Ye, either of those two makes my life a lot easier. I can then at least
> go and check the driver patch to see if things match up. In this case, I
> would want to check that the driver requires changes to support this
> device, given the commit message mentions nothing about the difference
> between this device and others. I'd still probably request that the
> commit message be improved to explain the lack of a fallback, but at
> least I would be clear about what I want and could provide a conditional
> Ack.
> 
> If you're not sending the bindings patch with the driver, there's an
> extra onus on you to explain exactly what makes this device incompatible
> with the other devices in the enum, although in an ideal world it'd make
> no difference and every bindings patch would contain that information.

I understand, thanks guys for discussing this with me.

I'll send V2 with Linux driver part.


>>>
>>>> Also, what makes this incompatibly different with the other devices in
>>>> the binding, like the 8183?
>>>
>>> It can control 8 PWMs unlike any other SoC block except for MT2712.
>>> It uses different registers than MT2712 thought.
> 
> Put this information in your commit message next time :)
> 
> Cheers,
> Conor.



From w.egorov at phytec.de  Wed Feb 14 02:26:49 2024
From: w.egorov at phytec.de (Wadim Egorov)
Date: Wed, 14 Feb 2024 11:26:49 +0100
Subject: [PATCH v3 0/9] Fix MMC properties on Sitara K3 devices
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <6c8feafd-a34c-4c7b-b6cd-4cd73b086259@phytec.de>


Am 14.02.24 um 00:56 schrieb Judith Mendez:
> This patch series aims to fix and update MMC nodes for TI
> Sitara K3 devices with the following changes.
>
> The series introduces sdhci0 and sdhci2 nodes and enables
> eMMC for AM62ax platform.
>
> Also introduce fixes for MMC ITAP/OTAP values for AM64x
> platform according to device datasheet [0], and add ITAP/
> OTAP values for AM62p to enable the highest timing possible
> for MMC0 and MMC1, according to device datasheet [1].
>
> The DLL properties ti,trm-icp and ti,driver-strength-ohm
> should be removed for soft PHYs since drive strength cannot
> be changed, so remove these properties when not applicable.
> Since this fix touches non-TI boards and therefore cannot be
> tested, all tested-by's are welcome.
>
> Also include a few fixes for ti,clkbuf-sel, bus-width,
> and bootph-all device tree properties in MMC nodes.
>
> This series was tested on:
> - AM62a SK
> - AM62x SK
> - AM62p SK
> - AM64x GP EVM
> - AM64x SK EVM
> - Beagleplay

Adding my Tested-by for the phyBOARD-Electra-AM642 board.

Tested-by: Wadim Egorov <w.egorov at phytec.de>


>
> [0] https://www.ti.com/lit/ds/symlink/am6442.pdf
> [1] https://www.ti.com/lit/ds/symlink/am62p.pdf
>
> Fixes since V2:
> - Remove ti,driver-strength-ohm property in sdhci1 node for
>   k3-am642-tqma64xxl-mbax4xxl and k3-am642-phyboard-electra-rdk board files.
> - Add Francesco's Acked-by
>
> V2: https://lore.kernel.org/linux-devicetree/20240213002416.1560357-1-jm at ti.com/
> V1: https://lore.kernel.org/linux-devicetree/22af7436-8833-4049-bdbb-f79bb3314ee8 at ti.com/
> RFC: https://lore.kernel.org/linux-devicetree/c94b7399-31c0-4e7d-a616-8f29c86a27ba at ti.com/
>
> Judith Mendez (7):
>    arm64: dts: ti: k3-am62a-main: Add sdhci2 instance
>    arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
>    arm64: dts: ti: k3-am62p: Add ITAP/OTAP values for MMC
>    arm64: dts: ti: k3-am6*: Remove DLL properties for soft PHYs
>    arm64: dts: ti: k3-am6*: Fix ti,clkbuf-sel property in MMC nodes
>    arm64: dts: ti: k3-am6*: Fix bus-width property in MMC nodes
>    arm64: dts: ti: k3-am6*: Add bootph-all property in MMC node
>
> Nitin Yadav (2):
>    arm64: dts: ti: k3-am62a-main: Add sdhci0 instance
>    arm64: dts: ti: k3-am62a7-sk: Enable eMMC support
>
>   arch/arm64/boot/dts/ti/k3-am62-main.dtsi      | 12 +++--
>   .../boot/dts/ti/k3-am62-phycore-som.dtsi      |  1 -
>   .../boot/dts/ti/k3-am62-verdin-dahlia.dtsi    |  1 -
>   .../arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi |  1 -
>   .../boot/dts/ti/k3-am62-verdin-wifi.dtsi      |  1 -
>   arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi    |  2 -
>   .../arm64/boot/dts/ti/k3-am625-beagleplay.dts |  4 --
>   .../dts/ti/k3-am625-phyboard-lyra-rdk.dts     |  1 -
>   arch/arm64/boot/dts/ti/k3-am62a-main.dtsi     | 45 ++++++++++++++++++-
>   arch/arm64/boot/dts/ti/k3-am62a7-sk.dts       | 27 ++++++++++-
>   arch/arm64/boot/dts/ti/k3-am62p-main.dtsi     | 44 ++++++++++++++++--
>   arch/arm64/boot/dts/ti/k3-am62p5-sk.dts       |  3 +-
>   .../arm64/boot/dts/ti/k3-am62x-sk-common.dtsi |  2 -
>   arch/arm64/boot/dts/ti/k3-am64-main.dtsi      | 15 +++++--
>   arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  4 +-
>   .../dts/ti/k3-am642-phyboard-electra-rdk.dts  |  1 -
>   arch/arm64/boot/dts/ti/k3-am642-sk.dts        |  2 -
>   .../dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts    |  1 -
>   18 files changed, 129 insertions(+), 38 deletions(-)
>
>
> base-commit: 1e6bbc5185bcd113c8d2f7aa0a02f588a6bdbe5d


From cassel at kernel.org  Wed Feb 14 02:38:47 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Wed, 14 Feb 2024 11:38:47 +0100
Subject: [PATCH 0/2] PCI endpoint BAR hardware description cleanup
In-Reply-To: <7a243a1e-6b47-bc2f-c538-b57db1c9c580@amd.com>
References: <20240210012634.600301-1-cassel@kernel.org>
 <7a243a1e-6b47-bc2f-c538-b57db1c9c580@amd.com>
Message-ID: <ZcyYNzYo9HiQi4DY@x1-carbon>

On Wed, Feb 14, 2024 at 09:47:54AM +0530, Kishon Vijay Abraham I wrote:
> Hi Niklas,
> 
> On 2/10/2024 6:56 AM, Niklas Cassel wrote:
> > The series is based on top of:
> > https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=endpoint
> > 
> > 
> > Hello all,
> > 
> > This series cleans up the hardware description for PCI endpoint BARs.
> > 
> > The problems with the existing hardware description:
> > -The documentation is lackluster.
> > -Some of the names are confusingly similar, e.g. fixed_64bit and
> >   fixed_size, even though these are for completely unrelated things.
> > -The way that the BARs are defined in the endpoint controller drivers
> >   is messy, because the left hand side is not a BAR, so you can mark a
> >   BAR as e.g. both fixed size and reserved.
> > 
> > This series tries to address all the problems above.
> > 
> > Personally, I think that the code is more readable, both the endpoint
> > controller drivers, but also pci-epc-core.c.
> 
> Thank you for cleaning this up!
> 
> FWIW:
> Reviewed-by: Kishon Vijay Abraham I <kishon at kernel.org>

IMHO, a FWIW is quite the undersell here, as there is no R-b I would value
higher than the R-b from the original author or the pci endpoint subsystem :)


Kind regards,
Niklas


From gregkh at linuxfoundation.org  Wed Feb 14 02:39:25 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 14 Feb 2024 11:39:25 +0100
Subject: [PATCH v6 001/164] pwm: Provide an inline function to get the
 parent device of a given chip
In-Reply-To: <cc30090d2f9762bed9854a55612144bccc910781.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
 <cc30090d2f9762bed9854a55612144bccc910781.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <2024021414-sedan-banking-f6b5@gregkh>

On Wed, Feb 14, 2024 at 10:30:48AM +0100, Uwe Kleine-K?nig wrote:
> Currently a pwm_chip stores in its struct device *dev member a pointer
> to the parent device. Preparing a change that embeds a full struct
> device in struct pwm_chip, this accessor function should be used in all
> drivers directly accessing chip->dev now. This way struct pwm_chip and
> this new function can be changed without having to touch all drivers in
> the same change set.
> 
> Make use of this function in the framework's core sources.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From francesco at dolcini.it  Wed Feb 14 02:52:23 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Wed, 14 Feb 2024 11:52:23 +0100
Subject: MXSFB error: -ENODEV: Cannot connect bridge
In-Reply-To: <20240212110706.ibrreoj2wgzhltyw@pengutronix.de>
References: <34yzygh3mbwpqr2re7nxmhyxy3s7qmqy4vhxvoyxnoguktriur@z66m7gvpqlia>
 <20240212110706.ibrreoj2wgzhltyw@pengutronix.de>
Message-ID: <20240214105223.GA78582@francesco-nb>

+ Linux regression.

This is a regression on v6.8-rc1.

On Mon, Feb 12, 2024 at 12:07:06PM +0100, Roland Hieber wrote:
> On Thu, Feb 08, 2024 at 12:58:02PM -0300, Hiago De Franco wrote:
> > Hello all,
> > 
> > while doing some tests with kernel v6.8-rc3 and Colibri iMX7D, we
> > noticed the following error:
> > 
> > [    0.432547] mxsfb 30730000.lcdif: error -ENODEV: Cannot connect bridge
> > 
> > This was introduced by commit edbbae7fba495284f72f05768696572691231558
> > ("ARM: dts: imx7: add MIPI-DSI support"). This patch is routing the
> > lcdif to the mipi_dsi_in_lcdif endpoint, however we do not have the DSI
> > pins available in our edge connector. Instead, we use the parallel RGB
> > LCD interface directly with, as example, an external LVDS transmitter:
> > 
> > &lcdif {
> > ...
> > 	status = "disabled";
> > 
> > 	port {
> > 		lcdif_out: endpoint {
> > 			remote-endpoint = <&lcd_panel_in>;
> > 		};
> > 	};
> > };
> > 
> > By applying the following patch, the issue is gone and the LVDS works
> > again:
> > 
> > diff --git a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
> > index ebf7befcc11e..9c81c6baa2d3 100644
> > --- a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
> > +++ b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
> > @@ -834,16 +834,6 @@ lcdif: lcdif at 30730000 {
> >  					<&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>;
> >  				clock-names = "pix", "axi";
> >  				status = "disabled";
> > -
> > -				port {
> > -					#address-cells = <1>;
> > -					#size-cells = <0>;
> > -
> > -					lcdif_out_mipi_dsi: endpoint at 0 {
> > -						reg = <0>;
> > -						remote-endpoint = <&mipi_dsi_in_lcdif>;
> > -					};
> > -				};
> >  			};
> >  
> >  			mipi_csi: mipi-csi at 30750000 {
> > @@ -895,22 +885,6 @@ mipi_dsi: dsi at 30760000 {
> >  				samsung,esc-clock-frequency = <20000000>;
> >  				samsung,pll-clock-frequency = <24000000>;
> >  				status = "disabled";
> > -
> > -				ports {
> > -					#address-cells = <1>;
> > -					#size-cells = <0>;
> > -
> > -					port at 0 {
> > -						reg = <0>;
> > -						#address-cells = <1>;
> > -						#size-cells = <0>;
> > -
> > -						mipi_dsi_in_lcdif: endpoint at 0 {
> > -							reg = <0>;
> > -							remote-endpoint = <&lcdif_out_mipi_dsi>;
> > -						};
> > -					};
> > -				};
> >  			};
> >  		};
> > 
> > I would like to know your opinion about this patch before sending it,
> > does it makes sense for you? I understand that routing to endpoint
> > should be done in the SoM device tree, so we are free to rout other
> > endpoint without issues.
> 
> As far as I understood, the LCDIF -> DSI connection is always present in
> the SoC. Can you overwrite the routing in your dts like this:?
> 
>     &lcdif_out_mipi_dsi {
>         remote-endpoint = <&lcd_panel_in>;
>     };
> 
> I'm not sure what is the best default solution here for imx7s.dtsi. Also
> the labels don't work out in that case, this could be improved.

For sure for something to be defined a solution it should not introduce
regressions :-)

This commit makes other boards not work anymore, specifically this
reports is about colibri-imx7.

With that said, the following patch solves the issue

diff --git a/arch/arm/boot/dts/nxp/imx/imx7-colibri.dtsi b/arch/arm/boot/dts/nxp/imx/imx7-colibri.dtsi
index 9fe51884af79..966ad13e7c78 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7-colibri.dtsi
@@ -536,12 +536,15 @@ &lcdif {
        status = "disabled";

        port {
-               lcdif_out: endpoint {
+               lcdif_out: endpoint at 0 {
+                       reg = <0>;
                        remote-endpoint = <&lcd_panel_in>;
                };
        };
 };

+/delete-node/ &mipi_dsi_in_lcdif;
+
 /* Colibri PWM<A> */
 &pwm1 {
        pinctrl-names = "default";


However, ... I do not really like the delete node, but it's required to
prevent this error:

arch/arm/boot/dts/nxp/imx/imx7s.dtsi:908.37-911.9: Warning (graph_endpoint): /soc/bus at 30400000/dsi at 30760000/ports/port at 0/endpoint at 0: graph connection to node '/soc/bus at 30400000/lcdif at 30730000/port/endpoint at 0' is not bidirectional

With that said, unless you have a better solution I would just send a
revert for your change.

Francesco



From maz at kernel.org  Wed Feb 14 02:58:15 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 10:58:15 +0000
Subject: [PATCH] irqchip/gic-v3-its: Workaround Renesas R-Car GICv3 ITS
In-Reply-To: <20240214052050.1966439-1-yoshihiro.shimoda.uh@renesas.com>
References: <20240214052050.1966439-1-yoshihiro.shimoda.uh@renesas.com>
Message-ID: <865xyr5n3s.wl-maz@kernel.org>

[+ Geert, who deals with Renesas SoCs on a daily basis]

Hi Yoshihiro,

On Wed, 14 Feb 2024 05:20:50 +0000,
Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com> wrote:
> 
> The GICv3 ITS on Renesas R-Car has limitations:
>  - It can access lower 32-bits memory area only.
>  - It cannot use Sharable/cache attributes.
> 
> So, set ITS_FLAGS_FORCE_NON_SHAREABLE flag, and set GFP_DMA to all
> memory allocation APIs for getting lower 32-bits memory area on
> the R-Car. Note that GFP_DMA32 cannot work correctly because
> the environment doens't have DMA32 zone like below:

nit: doesn't

> 
> [    0.000000] Zone ranges:
> [    0.000000]   DMA      [mem 0x0000000048000000-0x00000000ffffffff]
> [    0.000000]   DMA32    empty
> [    0.000000]   Normal   [mem 0x0000000100000000-0x00000004ffffffff]

Unfortunately, none of that is a universal truth. The way DMA and
DMA32 are expressed is pretty variable. See this for example:

https://lore.kernel.org/all/cover.1703683642.git.baruch at tkos.co.il/

So I can't see how you can reliably rely on this layout. It may work
today on your platform, but I wouldn't take this as a guarantee.

>
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
> ---
>  arch/arm64/Kconfig               |  9 +++++
>  drivers/irqchip/irq-gic-v3-its.c | 59 +++++++++++++++++++++-----------
>  2 files changed, 48 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index c1a16a9dae72..49fe3006e142 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1250,6 +1250,15 @@ config SOCIONEXT_SYNQUACER_PREITS
>  
>  	  If unsure, say Y.
>  
> +config RENESAS_RCAR_GIC_ITS
> +	bool "Renesas R-Car: Workaround for GICv3 ITS"
> +	default n
> +	help
> +	  Renesas R-Car Gen4 SoCs has a limitation about GICv3 ITS which can
> +	  access lower 32-bits memory address range only.
> +
> +	  If unsure, say Y.

Either this should be 'default y', or you should drop this last line.
Being 'default n' and saying 'if you don't know, say y' is
counterproductive.

Also:

- This must carry an official erratum number

- You must document it in Documentation/arch/arm64/silicon-errata.rst

> +
>  endmenu # "ARM errata workarounds via the alternatives framework"
>  
>  choice
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index d097001c1e3e..e0e672b561b9 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -186,6 +186,7 @@ static LIST_HEAD(its_nodes);
>  static DEFINE_RAW_SPINLOCK(its_lock);
>  static struct rdists *gic_rdists;
>  static struct irq_domain *its_parent;
> +static gfp_t its_gfp_quirk;

Why is that global? Why isn't this computed on a per-ITS basis? Since
you are introducing a generic mechanism here, you shouldn't assume
that all ITSs are subjected to the same issue.

>  
>  static unsigned long its_list_map;
>  static u16 vmovp_seq_num;
> @@ -1846,7 +1847,7 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
>  		struct its_vlpi_map *maps;
>  
>  		maps = kcalloc(its_dev->event_map.nr_lpis, sizeof(*maps),
> -			       GFP_ATOMIC);
> +			       GFP_ATOMIC | its_gfp_quirk);

This data structure is never exposed to the GIC. Why do we need to
constraint this allocation?

>  		if (!maps) {
>  			ret = -ENOMEM;
>  			goto out;
> @@ -2044,7 +2045,7 @@ static struct lpi_range *mk_lpi_range(u32 base, u32 span)
>  {
>  	struct lpi_range *range;
>  
> -	range = kmalloc(sizeof(*range), GFP_KERNEL);
> +	range = kmalloc(sizeof(*range), GFP_KERNEL | its_gfp_quirk);

Same thing.

>  	if (range) {
>  		range->base_id = base;
>  		range->span = span;
> @@ -2169,7 +2170,7 @@ static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids)
>  	if (err)
>  		goto out;
>  
> -	bitmap = bitmap_zalloc(nr_irqs, GFP_ATOMIC);
> +	bitmap = bitmap_zalloc(nr_irqs, GFP_ATOMIC | its_gfp_quirk);

Same thing.

>  	if (!bitmap)
>  		goto out;
>  
> @@ -2201,7 +2202,7 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags)
>  {
>  	struct page *prop_page;
>  
> -	prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
> +	prop_page = alloc_pages(gfp_flags | its_gfp_quirk, get_order(LPI_PROPBASE_SZ));

This only affects the redistributors. Why should we constraint it?

>  	if (!prop_page)
>  		return NULL;
>  
> @@ -2335,7 +2336,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
>  		order = get_order(GITS_BASER_PAGES_MAX * psz);
>  	}
>  
> -	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
> +	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO | its_gfp_quirk, order);
>  	if (!page)
>  		return -ENOMEM;
>  
> @@ -2808,7 +2809,7 @@ static bool allocate_vpe_l2_table(int cpu, u32 id)
>  
>  	/* Allocate memory for 2nd level table */
>  	if (!table[idx]) {
> -		page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(psz));
> +		page = alloc_pages(GFP_KERNEL | __GFP_ZERO | its_gfp_quirk, get_order(psz));
>  		if (!page)
>  			return false;
>  
> @@ -2860,7 +2861,7 @@ static int allocate_vpe_l1_table(void)
>  	if (val & GICR_VPROPBASER_4_1_VALID)
>  		goto out;
>  
> -	gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_ATOMIC);
> +	gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_ATOMIC | its_gfp_quirk);

This is a cpumask allocation, not exposed to the GIC. What is the
reason for constraining it?

>  	if (!gic_data_rdist()->vpe_table_mask)
>  		return -ENOMEM;
>  
> @@ -2927,7 +2928,7 @@ static int allocate_vpe_l1_table(void)
>  
>  	pr_debug("np = %d, npg = %lld, psz = %d, epp = %d, esz = %d\n",
>  		 np, npg, psz, epp, esz);
> -	page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, get_order(np * PAGE_SIZE));
> +	page = alloc_pages(GFP_ATOMIC | __GFP_ZERO | its_gfp_quirk, get_order(np * PAGE_SIZE));
>  	if (!page)
>  		return -ENOMEM;
>  
> @@ -2957,7 +2958,7 @@ static int its_alloc_collections(struct its_node *its)
>  	int i;
>  
>  	its->collections = kcalloc(nr_cpu_ids, sizeof(*its->collections),
> -				   GFP_KERNEL);
> +				   GFP_KERNEL | its_gfp_quirk);

Same thing.

>  	if (!its->collections)
>  		return -ENOMEM;
>  
> @@ -2971,7 +2972,7 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags)
>  {
>  	struct page *pend_page;
>  
> -	pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
> +	pend_page = alloc_pages(gfp_flags | __GFP_ZERO | its_gfp_quirk,
>  				get_order(LPI_PENDBASE_SZ));

This is a redistributor-private allocation. If it is the ITSs that are
affected by this bug, why are the pending tables constrained?

>  	if (!pend_page)
>  		return NULL;
> @@ -3319,7 +3320,7 @@ static bool its_alloc_table_entry(struct its_node *its,
>  
>  	/* Allocate memory for 2nd level table */
>  	if (!table[idx]) {
> -		page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
> +		page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO | its_gfp_quirk,
>  					get_order(baser->psz));
>  		if (!page)
>  			return false;
> @@ -3415,7 +3416,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
>  	if (WARN_ON(!is_power_of_2(nvecs)))
>  		nvecs = roundup_pow_of_two(nvecs);
>  
> -	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> +	dev = kzalloc(sizeof(*dev), GFP_KERNEL | its_gfp_quirk);
>  	/*
>  	 * Even if the device wants a single LPI, the ITT must be
>  	 * sized as a power of two (and you need at least one bit...).
> @@ -3423,14 +3424,14 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
>  	nr_ites = max(2, nvecs);
>  	sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1);
>  	sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
> -	itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node);
> +	itt = kzalloc_node(sz, GFP_KERNEL | its_gfp_quirk, its->numa_node);
>  	if (alloc_lpis) {
>  		lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis);
>  		if (lpi_map)
>  			col_map = kcalloc(nr_lpis, sizeof(*col_map),
> -					  GFP_KERNEL);
> +					  GFP_KERNEL | its_gfp_quirk);

This is kernel-private memory, not visible by the GIC.

>  	} else {
> -		col_map = kcalloc(nr_ites, sizeof(*col_map), GFP_KERNEL);
> +		col_map = kcalloc(nr_ites, sizeof(*col_map), GFP_KERNEL | its_gfp_quirk);

Same thing.

>  		nr_lpis = 0;
>  		lpi_base = 0;
>  	}
> @@ -4754,6 +4755,16 @@ static bool __maybe_unused its_enable_rk3588001(void *data)
>  	return true;
>  }
>  
> +static bool __maybe_unused its_enable_renesas_rcar_gic_its(void *data)
> +{
> +	struct its_node *its = data;
> +
> +	its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
> +	its_gfp_quirk = GFP_DMA;
> +
> +	return true;
> +}
> +
>  static bool its_set_non_coherent(void *data)
>  {
>  	struct its_node *its = data;
> @@ -4815,6 +4826,14 @@ static const struct gic_quirk its_quirks[] = {
>  		.mask   = 0xffffffff,
>  		.init   = its_enable_rk3588001,
>  	},
> +#endif
> +#ifdef CONFIG_RENESAS_RCAR_GIC_ITS
> +	{
> +		.desc   = "ITS: Renesas R-Car Gen4 GICv3 ITS",
> +		.iidr   = 0x0201743b,
> +		.mask   = 0xffffffff,
> +		.init   = its_enable_renesas_rcar_gic_its,
> +	},

Huh. This describes a GIC600 implemented by ARM. Which means your are
actively forcing your quirk on *every* implementations, including
those that are not affected by this hardware issue. Definitely not
acceptable.

>  #endif
>  	{
>  		.desc   = "ITS: non-coherent attribute",
> @@ -4974,7 +4993,7 @@ static int its_init_domain(struct its_node *its)
>  	struct irq_domain *inner_domain;
>  	struct msi_domain_info *info;
>  
> -	info = kzalloc(sizeof(*info), GFP_KERNEL);
> +	info = kzalloc(sizeof(*info), GFP_KERNEL | its_gfp_quirk);

Kernel memory only.

>  	if (!info)
>  		return -ENOMEM;
>  
> @@ -5011,7 +5030,7 @@ static int its_init_vpe_domain(void)
>  
>  	entries = roundup_pow_of_two(nr_cpu_ids);
>  	vpe_proxy.vpes = kcalloc(entries, sizeof(*vpe_proxy.vpes),
> -				 GFP_KERNEL);
> +				 GFP_KERNEL | its_gfp_quirk);
>  	if (!vpe_proxy.vpes)
>  		return -ENOMEM;
>  
> @@ -5108,7 +5127,7 @@ static int __init its_probe_one(struct its_node *its)
>  		}
>  	}
>  
> -	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
> +	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO | its_gfp_quirk,
>  				get_order(ITS_CMD_QUEUE_SZ));
>  	if (!page) {
>  		err = -ENOMEM;
> @@ -5352,7 +5371,7 @@ static struct its_node __init *its_node_init(struct resource *res,
>  
>  	pr_info("ITS %pR\n", res);
>  
> -	its = kzalloc(sizeof(*its), GFP_KERNEL);
> +	its = kzalloc(sizeof(*its), GFP_KERNEL | its_gfp_quirk);

Kernel memory only.

>  	if (!its)
>  		goto out_unmap;
>  
> @@ -5520,7 +5539,7 @@ static void __init acpi_table_parse_srat_its(void)
>  		return;
>  
>  	its_srat_maps = kmalloc_array(count, sizeof(struct its_srat_map),
> -				      GFP_KERNEL);
> +				      GFP_KERNEL | its_gfp_quirk);

Kernel memory only.

>  	if (!its_srat_maps)
>  		return;
>  

I suggest that you start reading the architecture spec and understand
what is the memory that is accessible by the GIC, because at least
half of this patch is completely unnecessary.

You also need to be clear about what is affected by this bug: ITS
only? or also the RDs?  If both are affected, they need to be handled
separately.

In any case, you must not assume that all ITSs in a system are
subjected to this bug, which means that you must have per-ITS tracking
of the GFP flags.

Finally, the DMA story itself needs to be sorted out, because you are
relying on something that is incredibly fragile.

HTH,

	M.

-- 
Without deviation from the norm, progress is not possible.


From b-kapoor at ti.com  Wed Feb 14 02:58:43 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Wed, 14 Feb 2024 16:28:43 +0530
Subject: [PATCH v3 1/4] arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for wkup_uart0 and mcu_uart0
In-Reply-To: <20240214105846.1096733-1-b-kapoor@ti.com>
References: <20240214105846.1096733-1-b-kapoor@ti.com>
Message-ID: <20240214105846.1096733-2-b-kapoor@ti.com>

WKUP_PADCONFIG registers for wkup_uart0 and mcu_uart0 lies
under wkup_pmx2 for J7200. Thus, modify pinmux for both
of them.

Fixes: 3709ea7f960e ("arm64: dts: ti: k3-j7200-common-proc-board: Add uart pinmux")
Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 .../boot/dts/ti/k3-j7200-common-proc-board.dts  | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
index 1d8bddcae90e..160580a0584a 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -119,24 +119,25 @@ transceiver3: can-phy3 {
 };
 
 &wkup_pmx0 {
+};
+
+&wkup_pmx2 {
 	mcu_uart0_pins_default: mcu-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0xf4, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
-			J721E_WKUP_IOPAD(0xf0, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
-			J721E_WKUP_IOPAD(0xf8, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
-			J721E_WKUP_IOPAD(0xfc, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+			J721E_WKUP_IOPAD(0x90, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
+			J721E_WKUP_IOPAD(0x94, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+			J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
+			J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
 		>;
 	};
 
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0xb0, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
-			J721E_WKUP_IOPAD(0xb4, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
+			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
+			J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
 		>;
 	};
-};
 
-&wkup_pmx2 {
 	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
 		pinctrl-single,pins = <
 			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
-- 
2.34.1



From b-kapoor at ti.com  Wed Feb 14 02:58:42 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Wed, 14 Feb 2024 16:28:42 +0530
Subject: [PATCH v3 0/4] arm64: dts: ti: Modify pinmux for wkup_uart0 and mcu_uart0
Message-ID: <20240214105846.1096733-1-b-kapoor@ti.com>

WKUP_PADCONFIG registers for wkup_uart0 and mcu_uart0 lies under
wkup_pmx2 for J7200. Thus, modify pinmux for both of them. Also,
remove the redundant clock-frequency property from mcu_uart0 node.

Only Tx and Rx Signal lines for wkup_uart0 are brought out on
J721S2 Common Proc Board and J784S4 EVM, but CTS and RTS signal lines
are not brought out. Thus, remove pinmux for CTS and RTS signal lines
for wkup_uart0 in J721S2 and J784S4.

v1 Link : https://lore.kernel.org/all/20240208110602.931573-1-b-kapoor at ti.com/
v2 Link : https://lore.kernel.org/all/20240212104417.1058993-1-b-kapoor at ti.com/

Changelog v1->v2:
 - Divided Pinmux and clock frequency patch(1/3) for J7200 into 2 patches
 - Change commit message to include wkup_uart0 for referring to the instance

Changelog v1->v2:
 - Added Fixes tag in Commit message

Rebased to 20240214

Bhavya Kapoor (4):
  arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for
    wkup_uart0 and mcu_uart0
  arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency
    from mcu_uart0
  arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and
    RTS in wkup_uart0
  arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in
    wkup_uart0

 .../boot/dts/ti/k3-j7200-common-proc-board.dts | 18 +++++++++---------
 .../dts/ti/k3-j721s2-common-proc-board.dts     |  2 --
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts       |  2 --
 3 files changed, 9 insertions(+), 13 deletions(-)

-- 
2.34.1



From b-kapoor at ti.com  Wed Feb 14 02:58:44 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Wed, 14 Feb 2024 16:28:44 +0530
Subject: [PATCH v3 2/4] arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency from mcu_uart0
In-Reply-To: <20240214105846.1096733-1-b-kapoor@ti.com>
References: <20240214105846.1096733-1-b-kapoor@ti.com>
Message-ID: <20240214105846.1096733-3-b-kapoor@ti.com>

Clock-frequency property is already present in mcu_uart0 node of the
k3-j7200-mcu-wakeup.dtsi file. Thus, remove redundant clock-frequency
property from mcu_uart0 node.

Fixes: 3709ea7f960e ("arm64: dts: ti: k3-j7200-common-proc-board: Add uart pinmux")
Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
index 160580a0584a..6593c5da82c0 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -273,7 +273,6 @@ &mcu_uart0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_uart0_pins_default>;
-	clock-frequency = <96000000>;
 };
 
 &main_uart0 {
-- 
2.34.1



From b-kapoor at ti.com  Wed Feb 14 02:58:45 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Wed, 14 Feb 2024 16:28:45 +0530
Subject: [PATCH v3 3/4] arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and RTS in wkup_uart0
In-Reply-To: <20240214105846.1096733-1-b-kapoor@ti.com>
References: <20240214105846.1096733-1-b-kapoor@ti.com>
Message-ID: <20240214105846.1096733-4-b-kapoor@ti.com>

Only Tx and Rx Signal lines for wkup_uart0 are brought out on
the Common Proc Board through SoM, but CTS and RTS signal lines
are not brought on the board. Thus, remove pinmux for CTS and RTS
signal lines for wkup_uart0 in J721S2.

Fixes: f5e9ee0b354a ("arm64: dts: ti: k3-j721s2-common-proc-board: Add uart pinmux")
Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
index 361365bb5523..6371cb1c1fe7 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -190,8 +190,6 @@ J721S2_IOPAD(0x038, PIN_OUTPUT, 0) /* (AB28) MCASP0_ACLKX.MCAN5_TX */
 &wkup_pmx2 {
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (E25) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-			J721S2_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (F28) WKUP_GPIO0_7.WKUP_UART0_RTSn */
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */
 		>;
-- 
2.34.1



From b-kapoor at ti.com  Wed Feb 14 02:58:46 2024
From: b-kapoor at ti.com (Bhavya Kapoor)
Date: Wed, 14 Feb 2024 16:28:46 +0530
Subject: [PATCH v3 4/4] arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in wkup_uart0
In-Reply-To: <20240214105846.1096733-1-b-kapoor@ti.com>
References: <20240214105846.1096733-1-b-kapoor@ti.com>
Message-ID: <20240214105846.1096733-5-b-kapoor@ti.com>

Only Tx and Rx Signal lines for wkup_uart0 are brought out on
the J784S4 EVM from SoC, but CTS and RTS signal lines are not
brought on the EVM. Thus, remove pinmux for CTS and RTS signal
lines for wkup_uart0 in J784S4.

Fixes: 6fa5d37a2f34 ("arm64: dts: ti: k3-j784s4-evm: Add mcu and wakeup uarts")
Signed-off-by: Bhavya Kapoor <b-kapoor at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
index 57e7cb8ea2b8..9f16642ccd5f 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -336,8 +336,6 @@ &wkup_pmx2 {
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
-			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-			J721S2_WKUP_IOPAD(0x074, PIN_INPUT, 0) /* (L36) WKUP_GPIO0_7.WKUP_UART0_RTSn */
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_INPUT, 0) /* (K34) WKUP_UART0_TXD */
 		>;
-- 
2.34.1



From mark.rutland at arm.com  Wed Feb 14 03:11:14 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 14 Feb 2024 11:11:14 +0000
Subject: [PATCH] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM
 Neoverse N2 errata
In-Reply-To: <18b3ac3e-2bfc-4fce-9be4-3e75e487f9fc@linux.microsoft.com>
References: <20240212232909.2276378-1-eahariha@linux.microsoft.com>
 <ZcqtUxhqUbYoRH-G@linux.dev>
 <18b3ac3e-2bfc-4fce-9be4-3e75e487f9fc@linux.microsoft.com>
Message-ID: <Zcyf0oIJe7ukH0si@FVFF77S0Q05N>

On Tue, Feb 13, 2024 at 04:19:08PM -0800, Easwar Hariharan wrote:
> >> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> >> index 7c7493cb571f..a632a7514e55 100644
> >> --- a/arch/arm64/include/asm/cputype.h
> >> +++ b/arch/arm64/include/asm/cputype.h
> >> @@ -61,6 +61,7 @@
> >>  #define ARM_CPU_IMP_HISI		0x48
> >>  #define ARM_CPU_IMP_APPLE		0x61
> >>  #define ARM_CPU_IMP_AMPERE		0xC0
> >> +#define ARM_CPU_IMP_MICROSOFT		0x6D
> >>  
> >>  #define ARM_CPU_PART_AEM_V8		0xD0F
> >>  #define ARM_CPU_PART_FOUNDATION		0xD00
> >> @@ -135,6 +136,8 @@
> >>  
> >>  #define AMPERE_CPU_PART_AMPERE1		0xAC3
> >>  
> >> +#define MSFT_CPU_PART_AZURE_COBALT_100	0xD49 /* Based on r0p0 of ARM Neoverse N2 */
> >> +
> >>  #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
> >>  #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
> >>  #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
> >> @@ -193,6 +196,7 @@
> >>  #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)
> >>  #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
> >>  #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
> >> +#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MSFT_CPU_PART_AZURE_COBALT_100)
> > 
> > nitpick: consistently use the abbreviated 'MSFT' for all the definitions
> > you're adding.
> 
> I was rather hoping to use Microsoft throughout, but I chose MSFT for the CPU_PART* to align columns
> with the other defines. :) If consistency is of a higher priority than column alignment, I can change it
> to MICROSOFT rather than MSFT throughout.

Consistency across the definitions is more important than alignmen; please
choose either "MSFT" or "MICROSOFT" and use that consistently.

Mark.


From luca.ceresoli at bootlin.com  Wed Feb 14 03:14:38 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 14 Feb 2024 12:14:38 +0100
Subject: [PATCH V4 1/6] dt-bindings: phy: add binding for the i.MX8MP
 HDMI PHY
In-Reply-To: <20240210204606.11944-2-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
	<20240210204606.11944-2-aford173@gmail.com>
Message-ID: <20240214121438.331a9f20@booty>

Hi Adam,

On Sat, 10 Feb 2024 14:45:57 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> Add a DT binding for the HDMI PHY found on the i.MX8MP SoC.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

I was a bit puzzled by this v4 series as it comes after v8... however
thanks for keeping up!

This patch is identical to the v8 I already reviewed, so:

Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From luca.ceresoli at bootlin.com  Wed Feb 14 03:14:48 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 14 Feb 2024 12:14:48 +0100
Subject: [PATCH V4 2/6] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240210204606.11944-3-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
	<20240210204606.11944-3-aford173@gmail.com>
Message-ID: <20240214121448.451e2e1c@booty>

On Sat, 10 Feb 2024 14:45:58 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the driver for the Samsung HDMI PHY found on the
> i.MX8MP SoC. Based on downstream implementation from
> Sandor Yu <Sandor.yu at nxp.com>.  According to the TRM, the PHY
> receives parallel data from the link and serializes it.  It
> also sets the PLL clock needed for the TX serializer.
> 
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v2)
> Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
> Co-developed-by: Marco Felsch <m.felsch at pengutronix.de>
> Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> # Kontron BL
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> Signed-off-by: Adam Ford <aford173 at gmail.com>

[...]

> +static int phy_clk_register(struct fsl_samsung_hdmi_phy *phy)
> +{
> +	struct device *dev = phy->dev;
> +	struct device_node *np = dev->of_node;
> +	struct clk_init_data init;
> +	const char *parent_name;
> +	struct clk *phyclk;
> +	int ret;
> +
> +	parent_name = __clk_get_name(phy->refclk);
> +
> +	init.parent_names = &parent_name;
> +	init.num_parents = 1;
> +	init.flags = 0;
> +	init.name = "hdmi_pclk";
> +	init.ops = &phy_clk_ops;
> +
> +	phy->hw.init = &init;
> +
> +	phyclk = devm_clk_register(dev, &phy->hw);
> +	if (IS_ERR(phyclk))
> +		return dev_err_probe(dev, PTR_ERR(phyclk),
> +				     "failed to register clock\n");
> +
> +	ret = of_clk_add_provider(np, of_clk_src_simple_get, phyclk);

As per my v8 review, this function is deprecated:
https://elixir.bootlin.com/linux/v6.8-rc4/source/drivers/clk/clk.c#L4881

However:

[Tested using Avnet MSC SM2S-IMX8PLUS SoM on Avnet MSC SM2-MB-EP1]
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

Luca

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From luca.ceresoli at bootlin.com  Wed Feb 14 03:15:05 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 14 Feb 2024 12:15:05 +0100
Subject: [PATCH V4 3/6] arm64: dts: imx8mp: add HDMI power-domains
In-Reply-To: <20240210204606.11944-4-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
	<20240210204606.11944-4-aford173@gmail.com>
Message-ID: <20240214121505.2aff7e69@booty>

On Sat, 10 Feb 2024 14:45:59 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the PGC and HDMI blk-ctrl nodes providing power control for
> HDMI subsystem peripherals.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

[Tested using Avnet MSC SM2S-IMX8PLUS SoM on Avnet MSC SM2-MB-EP1]
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From luca.ceresoli at bootlin.com  Wed Feb 14 03:15:17 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 14 Feb 2024 12:15:17 +0100
Subject: [PATCH V4 4/6] arm64: dts: imx8mp: add HDMI irqsteer
In-Reply-To: <20240210204606.11944-5-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
	<20240210204606.11944-5-aford173@gmail.com>
Message-ID: <20240214121517.54552a4a@booty>

On Sat, 10 Feb 2024 14:46:00 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> The HDMI irqsteer is a secondary interrupt controller within the HDMI
> subsystem that maps all HDMI peripheral IRQs into a single upstream
> IRQ line.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> ---
> V2:  Add my (Adam) s-o-b and re-order position under AIPS4
> ---
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> index 0730d4cf9bc4..9b8ab367d774 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -1927,6 +1927,19 @@ hdmi_blk_ctrl: blk-ctrl at 32fc0000 {
>  						     "hdcp", "hrv";
>  				#power-domain-cells = <1>;
>  			};
> +
> +			irqsteer_hdmi: interrupt-controller at 32fc2000 {
> +				compatible = "fsl,imx-irqsteer";
> +				reg = <0x32fc2000 0x44>;

The last register being at offset 0x44, this should be <0x32fc2000
0x48> or even <... 0x1000> as the TRM mentions a 4 kB size.

[Tested using Avnet MSC SM2S-IMX8PLUS SoM on Avnet MSC SM2-MB-EP1]
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>


Luca

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From luca.ceresoli at bootlin.com  Wed Feb 14 03:15:22 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 14 Feb 2024 12:15:22 +0100
Subject: [PATCH V4 5/6] arm64: dts: imx8mp: add HDMI display pipeline
In-Reply-To: <20240210204606.11944-6-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
	<20240210204606.11944-6-aford173@gmail.com>
Message-ID: <20240214121522.7c1ed4bf@booty>

On Sat, 10 Feb 2024 14:46:01 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the DT nodes for all the peripherals that make up the
> HDMI display pipeline.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> ---
> V3:  Re-ordered the HDMI parts to properly come after irqstree_hdmi
>      inside AIPS4.  Change size of LCDIF3 and PVI to match TRM sizes
>      of 4KB.
> 
> V2:  I took this from Lucas' original submission with the following:
>      Removed extra clock from HDMI-TX since it is now part of the
>      power domain
>      Added interrupt-parent to PVI
>      Changed the name of the HDMI tranmitter to fsl,imx8mp-hdmi-tx
>      Added ports to HDMI-tx

[Tested using Avnet MSC SM2S-IMX8PLUS SoM on Avnet MSC SM2-MB-EP1]
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From luca.ceresoli at bootlin.com  Wed Feb 14 03:15:26 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 14 Feb 2024 12:15:26 +0100
Subject: [PATCH V4 6/6] arm64: defconfig: Enable
 DRM_IMX8MP_DW_HDMI_BRIDGE as module
In-Reply-To: <20240210204606.11944-7-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
	<20240210204606.11944-7-aford173@gmail.com>
Message-ID: <20240214121526.384440d1@booty>

On Sat, 10 Feb 2024 14:46:02 -0600
Adam Ford <aford173 at gmail.com> wrote:

> The i.MX8M Plus has support for an HDMI transmitter.  The
> video is genereated by lcdif3, routed to the hdmi parallel
> video interface, then fed to a DW HDMI bridge to support
> up to 4K video output.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

[Tested using Avnet MSC SM2S-IMX8PLUS SoM on Avnet MSC SM2-MB-EP1]
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From jan.kiszka at siemens.com  Wed Feb 14 03:21:53 2024
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Wed, 14 Feb 2024 12:21:53 +0100
Subject: [PATCH v3 3/7] arm64: dts: ti: iot2050: Factor out arduino
 connector bits
In-Reply-To: <4f122f5d-e430-4299-b6c5-bbe778aad736@ti.com>
References: <cover.1707463401.git.jan.kiszka@siemens.com>
 <3366367dc9f190c9e21027b9a810886791e99245.1707463401.git.jan.kiszka@siemens.com>
 <4f122f5d-e430-4299-b6c5-bbe778aad736@ti.com>
Message-ID: <78aac8b5-4ae0-4a0d-9b74-35bf88e3cbf2@siemens.com>

On 14.02.24 11:13, Vignesh Raghavendra wrote:
> 
> 
> On 09/02/24 12:53, Jan Kiszka wrote:
>> From: Jan Kiszka <jan.kiszka at siemens.com>
>>
>> A new variant is to be added which will not have a arduino connector
>> like the existing ones. Factor out all bits that are specific to this
>> connector.
>>
>> The split is not perfect because wkup_gpio0 is defined based on what is
>> common to all variants having the connector, thus containing also
>> connector-unrelated information. But this is still cleaner than
>> replicating this node into all 4 variants.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
>> ---
>>  .../ti/k3-am65-iot2050-arduino-connector.dtsi | 768 ++++++++++++++++++
>>  .../boot/dts/ti/k3-am65-iot2050-common.dtsi   | 753 -----------------
>>  .../ti/k3-am6528-iot2050-basic-common.dtsi    |   1 +
>>  .../dts/ti/k3-am6548-iot2050-advanced-m2.dts  |   1 +
>>  .../dts/ti/k3-am6548-iot2050-advanced-pg2.dts |   1 +
>>  .../dts/ti/k3-am6548-iot2050-advanced.dts     |   1 +
>>  6 files changed, 772 insertions(+), 753 deletions(-)
>>  create mode 100644 
>> arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
>>
>> diff --git 
>> a/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi 
>> b/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
>> new file mode 100644
>> index 000000000000..cd86f412b837
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
>> @@ -0,0 +1,768 @@
>> +// SPDX-License-Identifier: GPL-2.0
> 
> This and elsewhere in the series should be
> 
> // SPDX-License-Identifier: GPL-2.0-only
> 
> as fixed up by Nishanth in [0]. I can fix that locally, let me know.
> 

Yes, please.

> [0] https://lore.kernel.org/r/20240122145539.194512-16-nm at ti.com
> 

Thanks,
Jan

-- 
Siemens AG, Technology
Linux Expert Center



From andrejs.cainikovs at gmail.com  Wed Feb 14 03:27:08 2024
From: andrejs.cainikovs at gmail.com (Andrejs Cainikovs)
Date: Wed, 14 Feb 2024 12:27:08 +0100
Subject: [PATCH v3 5/5] usb: dwc3-am62: add workaround for Errata i2409
In-Reply-To: <20240201183522.ssj553rwefr2wuqi@iaqt7>
References: <20240201183522.ssj553rwefr2wuqi@iaqt7>
Message-ID: <20240214112708.157743-1-andrejs.cainikovs@gmail.com>

> All AM62 devices have Errata i2409 [1] due to which
> USB2 PHY may lock up due to short suspend.
> 
> Workaround involves setting bit 5 and 4 PLL_REG12
> in PHY2 register space after USB controller is brought
> out of LPSC reset but before controller initialization.
> 
> Handle this workaround.

Tested-by: Andrejs Cainikovs <andrejs.cainikovs at toradex.com>

You have requested [1] to check whether this patch
fixes issues I observed, and I can confirm it does.

[1]: https://lore.kernel.org/all/2629cd30-23aa-4f03-8452-ae13297fd6b6 at kernel.org/


From francesco at dolcini.it  Wed Feb 14 03:30:07 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Wed, 14 Feb 2024 12:30:07 +0100
Subject: [PATCH] ARM: imx_v6_v7_defconfig: Restore
 CONFIG_BACKLIGHT_CLASS_DEVICE
In-Reply-To: <20240201180054.3869350-1-festevam@gmail.com>
References: <20240201180054.3869350-1-festevam@gmail.com>
Message-ID: <20240214113007.GA88408@francesco-nb>

Hello Fabio,

On Thu, Feb 01, 2024 at 03:00:54PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> Since commit bfac19e239a7 ("fbdev: mx3fb: Remove the driver") backlight
> is no longer functional.
> 
> The fbdev mx3fb driver used to automatically select 
> CONFIG_BACKLIGHT_CLASS_DEVICE.
> 
> Now that the mx3fb driver has been removed, enable the
> CONFIG_BACKLIGHT_CLASS_DEVICE option so that backlight can still work
> by default.
> 
> Tested on a imx6dl-sabresd board.
> 
> Cc: stable at vger.kernel.org
> Fixes: bfac19e239a7 ("fbdev: mx3fb: Remove the driver")
> Signed-off-by: Fabio Estevam <festevam at denx.de>

Reviewed-by: Francesco Dolcini <francesco.dolcini at toradex.com>
Tested-by: Francesco Dolcini <francesco.dolcini at toradex.com> # Toradex Colibri iMX7



From chiawei_wang at aspeedtech.com  Wed Feb 14 03:34:31 2024
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Wed, 14 Feb 2024 11:34:31 +0000
Subject: =?big5?B?pl7C0DogW1BBVENIXSBBZGQgZVNQSSBkZXZpY2UgZHJpdmVyIChmbGFzaCBjaGFu?=
 =?big5?Q?nel)?=
In-Reply-To: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
References: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
Message-ID: <KL1PR06MB665234A65DB334B3BDF6AFA6914E2@KL1PR06MB6652.apcprd06.prod.outlook.com>

Most of the implementation originates from Aspeed.
Please preserve the Aspeed copyright before adding the IBM one.

For removing IOCTL and adopting MTD interface, I thought we have already discussed this in public and in private many times.
The MTD interface acting as a master to control flash can NOT serve SAFS (a.k.a. eDAF), which is the major use case of eSPI flash channel on numerous Intel/AMD platforms.

Is SAFS not necessary on your platform?
If so, please consider to rename the driver to espi-mafs to be more specific. As the driver does not support SAFS actually.

I am not saying IOCTL is the best solution.
If there is a more user-firendly interface, I would be glad to revise the implementation as well.
But, the truth is that most existing kernel subsystems act in the master roles, which makes them hard to be applied on eSPI slave.
And this is also well explained in the previous mailing thread.

We appreciate that you are willing to help on the open source contribution. 
However, please co-work with Aspeed before submitting drivers of Aspeed HW.
Otherwise, a misleading driver on the community are going to bring tons of customer issues to Aspeed.

Thanks,
Chiawei

> Sent by: Manojkiran Eda <manojkiran.eda at gmail.com>
> ---
> Hello everyone,
> 
> I'm presenting a revised version of the eSPI device driver patch series found at the following link:
> 
> https://lore.kernel.org/openbmc/20220516005412.4844-1-chiawei_wang at aspeedtech.com/ 
> 
> This update addresses the issues identified during the review process.
> 
> While the previous patch series attempted to incorporate support for all four different channels of eSPI,
> this new series focuses on upstreaming the flash channel initially, ensuring that all review comments are
> duly addressed, before progressing further.
> 
> Results:

> Successfully conducted a flash update via eSPI.

> Note:

> This marks my inaugural endeavor in contributing code to the kernel subsystem. I kindly request reviewers
> to incorporate as many details as possible in the review comments.

From dmitry.baryshkov at linaro.org  Wed Feb 14 03:45:53 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 14 Feb 2024 13:45:53 +0200
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com> <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
Message-ID: <CAA8EJpqO3j-BEQ9tcbH5HpskpbC7bJpEEpc5Y5ySb2B5c+WC3g@mail.gmail.com>

On Wed, 14 Feb 2024 at 11:20, Kathiravan Thirumoorthy
<quic_kathirav at quicinc.com> wrote:
>
>
>
> On 1/26/2024 1:35 AM, Andrew Lunn wrote:
> > On Mon, Jan 22, 2024 at 11:26:58AM +0530, Kathiravan Thirumoorthy wrote:
> >> gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk are
> >> enabled by default and it's RCG is properly configured by bootloader.
> >
> > Which bootloader? Mainline barebox?
>
>
> Thanks for taking time to review the patches. I couldn't get time to
> respond back, sorry for the delay.
>
> I was referring to the U-boot which is delivered as part of the QSDK. I
> will call it out explicitly in the next patch.
>
> >
> >> Some of the NSS clocks needs these clocks to be enabled. To avoid
> >> these clocks being disabled by clock framework, drop these entries
> >> from the clock table and enable it in the driver probe itself.
> >
> > If they are critical clocks, i would expect a device to reference
> > them. The CCF only disabled unused clocks in late_initcall_sync(),
> > which means all drivers should of probed and taken a reference on any
> > clocks they require.
>
>
> Some of the NSSCC clocks are enabled by bootloaders and CCF disables the
> same (because currently there are no consumers for these clocks
> available in the tree. These clocks are consumed by the Networking
> drivers which are being upstreamed). To access the NSSCC clocks,
> gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk clocks
> needs to be enabled, else system is going to reboot. To prevent this, I
> enabled it in probe.
>
> However looking back, gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk,
> gcc_nssnoc_nsscc_clk are consumed by the networking drivers only. So is
> it okay to drop these clocks from the GCC driver and add it back once
> the actual consumer needs it? So that we don't have to enable it in probe.
>
> Please let me know your thoughts.

If there are no in-kernel consumers, there is no need to worry about
them at all, nobody is going to access corresponding hardware. If you
have out-of-tree modules, you also probably have your out-of-tree
overlays. So you can make use of these clocks in your overlay. I don't
see a point in dropping the clock if it is going to be readded later.

-- 
With best wishes
Dmitry


From cristian.ciocaltea at collabora.com  Wed Feb 14 03:45:35 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 14 Feb 2024 13:45:35 +0200
Subject: [PATCH v4 0/2] Add support for RK3588 HDMI/eDP Combo PHY
Message-ID: <20240214-phy-hdptx-v4-0-e7974f46c1a7@collabora.com>

Add driver and bindings to add initial support the Rockchip HDMI/eDP TX
Combo PHY found on RK3588 SoC.

The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
and eDP links.

Please note that currently only the TMDS related functionality has been
implemented.  This has been tested on Radxa ROCK 5B and Rockchip EVB1
boards.

Changes in v4:
- Used consistent naming by replacing hdptx_*/rockchip_* with rk_hdptx_*
  (Johan)
- Link to v3:
  https://lore.kernel.org/r/20240212-phy-hdptx-v3-0-2cde680cd024 at collabora.com

Changes in v3:
- Collected R-b & T-b tags from Heiko
- Converted all *_REG() args to lowercase (Vinod)
- Dropped unnecessary register read/write wrappers (Vinod)
- Added rate overflow check in hdptx_phy_clk_pll_calc() (Luis)
- Link to v2:
  https://lore.kernel.org/r/20240205-phy-hdptx-v2-0-a7150814c047 at collabora.com

Changes in v2:
- Rebased series onto next-20240129
- Removed patch 'dt-bindings: soc: rockchip: Add rk3588 hdptxphy syscon'
  already applied by Heiko
- For consistency with SoC TRM, replaced all references to DP with eDP
- Updated PHY schema per Krzysztof's review; also collected his R-b tag
- Dropped FRL, EARC and 10-bit color depth functionality until the HDMI
  configuration options become available in PHY API
- Squashed lots of regmap_write operations via regmap_multi_reg_write
  (Sebastian)
- Introduced parametrized {CMN|SB|LNTOP|LANE}_REG() macros to replace
  the long list of register defines
- Optimized handling of the config arrays by using ARRAY_SIZE() (Sascha)
- Link to v1:
  https://lore.kernel.org/r/20240119193806.1030214-1-cristian.ciocaltea at collabora.com

---
Cristian Ciocaltea (2):
      dt-bindings: phy: Add Rockchip HDMI/eDP Combo PHY schema
      phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver

 .../bindings/phy/rockchip,rk3588-hdptx-phy.yaml    |   91 ++
 drivers/phy/rockchip/Kconfig                       |    8 +
 drivers/phy/rockchip/Makefile                      |    1 +
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c  | 1028 ++++++++++++++++++++
 4 files changed, 1128 insertions(+)
---
base-commit: 596764183be8ebb13352b281a442a1f1151c9b06
change-id: 20240128-phy-hdptx-8a98ab60d18e



From cristian.ciocaltea at collabora.com  Wed Feb 14 03:45:36 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 14 Feb 2024 13:45:36 +0200
Subject: [PATCH v4 1/2] dt-bindings: phy: Add Rockchip HDMI/eDP Combo PHY
 schema
In-Reply-To: <20240214-phy-hdptx-v4-0-e7974f46c1a7@collabora.com>
References: <20240214-phy-hdptx-v4-0-e7974f46c1a7@collabora.com>
Message-ID: <20240214-phy-hdptx-v4-1-e7974f46c1a7@collabora.com>

Add dt-binding schema for the HDMI/eDP Transmitter Combo PHY found on
Rockchip RK3588 SoC.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 .../bindings/phy/rockchip,rk3588-hdptx-phy.yaml    | 91 ++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml
new file mode 100644
index 000000000000..54e822c715f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3588-hdptx-phy.yaml
@@ -0,0 +1,91 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/rockchip,rk3588-hdptx-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC HDMI/eDP Transmitter Combo PHY
+
+maintainers:
+  - Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3588-hdptx-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Reference clock
+      - description: APB clock
+
+  clock-names:
+    items:
+      - const: ref
+      - const: apb
+
+  "#phy-cells":
+    const: 0
+
+  resets:
+    items:
+      - description: PHY reset line
+      - description: APB reset line
+      - description: INIT reset line
+      - description: CMN reset line
+      - description: LANE reset line
+      - description: ROPLL reset line
+      - description: LCPLL reset line
+
+  reset-names:
+    items:
+      - const: phy
+      - const: apb
+      - const: init
+      - const: cmn
+      - const: lane
+      - const: ropll
+      - const: lcpll
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: Some PHY related data is accessed through GRF regs.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+  - resets
+  - reset-names
+  - rockchip,grf
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
+    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      phy at fed60000 {
+        compatible = "rockchip,rk3588-hdptx-phy";
+        reg = <0x0 0xfed60000 0x0 0x2000>;
+        clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
+        clock-names = "ref", "apb";
+        #phy-cells = <0>;
+        resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
+                 <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
+                 <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
+                 <&cru SRST_HDPTX0_LCPLL>;
+        reset-names = "phy", "apb", "init", "cmn", "lane", "ropll", "lcpll";
+        rockchip,grf = <&hdptxphy_grf>;
+      };
+    };

-- 
2.43.0



From cristian.ciocaltea at collabora.com  Wed Feb 14 03:45:37 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 14 Feb 2024 13:45:37 +0200
Subject: [PATCH v4 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <20240214-phy-hdptx-v4-0-e7974f46c1a7@collabora.com>
References: <20240214-phy-hdptx-v4-0-e7974f46c1a7@collabora.com>
Message-ID: <20240214-phy-hdptx-v4-2-e7974f46c1a7@collabora.com>

Add driver for the HDMI/eDP TX Combo PHY found on Rockchip RK3588 SoC.

The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
and eDP links.  The maximum data rate is 12Gbps (FRL), while the minimum
is 250Mbps (TMDS).

Only the TMDS link is currently supported.

Co-developed-by: Algea Cao <algea.cao at rock-chips.com>
Signed-off-by: Algea Cao <algea.cao at rock-chips.com>
Tested-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/phy/rockchip/Kconfig                      |    8 +
 drivers/phy/rockchip/Makefile                     |    1 +
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 1028 +++++++++++++++++++++
 3 files changed, 1037 insertions(+)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 94360fc96a6f..a34f67bb7e61 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -83,6 +83,14 @@ config PHY_ROCKCHIP_PCIE
 	help
 	  Enable this to support the Rockchip PCIe PHY.
 
+config PHY_ROCKCHIP_SAMSUNG_HDPTX
+	tristate "Rockchip Samsung HDMI/eDP Combo PHY driver"
+	depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
+	select GENERIC_PHY
+	help
+	  Enable this to support the Rockchip HDMI/eDP Combo PHY
+	  with Samsung IP block.
+
 config PHY_ROCKCHIP_SNPS_PCIE3
 	tristate "Rockchip Snps PCIe3 PHY Driver"
 	depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
index 7eab129230d1..3d911304e654 100644
--- a/drivers/phy/rockchip/Makefile
+++ b/drivers/phy/rockchip/Makefile
@@ -8,6 +8,7 @@ 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_SAMSUNG_HDPTX)	+= phy-rockchip-samsung-hdptx.o
 obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3)	+= phy-rockchip-snps-pcie3.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-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
new file mode 100644
index 000000000000..946c01210ac8
--- /dev/null
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -0,0 +1,1028 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2024 Collabora Ltd.
+ *
+ * Author: Algea Cao <algea.cao at rock-chips.com>
+ * Author: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/rational.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#define GRF_HDPTX_CON0			0x00
+#define HDPTX_I_PLL_EN			BIT(7)
+#define HDPTX_I_BIAS_EN			BIT(6)
+#define HDPTX_I_BGR_EN			BIT(5)
+#define GRF_HDPTX_STATUS		0x80
+#define HDPTX_O_PLL_LOCK_DONE		BIT(3)
+#define HDPTX_O_PHY_CLK_RDY		BIT(2)
+#define HDPTX_O_PHY_RDY			BIT(1)
+#define HDPTX_O_SB_RDY			BIT(0)
+
+#define HDTPX_REG(_n, _min, _max)				\
+	(							\
+		BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) +	\
+		BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) +	\
+		((0x##_n) * 4)					\
+	)
+
+#define CMN_REG(n)			HDTPX_REG(n, 0000, 00a7)
+#define SB_REG(n)			HDTPX_REG(n, 0100, 0129)
+#define LNTOP_REG(n)			HDTPX_REG(n, 0200, 0229)
+#define LANE_REG(n)			HDTPX_REG(n, 0300, 062d)
+
+/* CMN_REG(0008) */
+#define LCPLL_EN_MASK			BIT(6)
+#define LCPLL_LCVCO_MODE_EN_MASK	BIT(4)
+/* CMN_REG(001e) */
+#define LCPLL_PI_EN_MASK		BIT(5)
+#define LCPLL_100M_CLK_EN_MASK		BIT(0)
+/* CMN_REG(0025) */
+#define LCPLL_PMS_IQDIV_RSTN		BIT(4)
+/* CMN_REG(0028) */
+#define LCPLL_SDC_FRAC_EN		BIT(2)
+#define LCPLL_SDC_FRAC_RSTN		BIT(0)
+/* CMN_REG(002d) */
+#define LCPLL_SDC_N_MASK		GENMASK(3, 1)
+/* CMN_REG(002e) */
+#define LCPLL_SDC_NUMBERATOR_MASK	GENMASK(5, 0)
+/* CMN_REG(002f) */
+#define LCPLL_SDC_DENOMINATOR_MASK	GENMASK(7, 2)
+#define LCPLL_SDC_NDIV_RSTN		BIT(0)
+/* CMN_REG(003d) */
+#define ROPLL_LCVCO_EN			BIT(4)
+/* CMN_REG(004e) */
+#define ROPLL_PI_EN			BIT(5)
+/* CMN_REG(005c) */
+#define ROPLL_PMS_IQDIV_RSTN		BIT(5)
+/* CMN_REG(005e) */
+#define ROPLL_SDM_EN_MASK		BIT(6)
+#define ROPLL_SDM_FRAC_EN_RBR		BIT(3)
+#define ROPLL_SDM_FRAC_EN_HBR		BIT(2)
+#define ROPLL_SDM_FRAC_EN_HBR2		BIT(1)
+#define ROPLL_SDM_FRAC_EN_HBR3		BIT(0)
+/* CMN_REG(0064) */
+#define ROPLL_SDM_NUM_SIGN_RBR_MASK	BIT(3)
+/* CMN_REG(0069) */
+#define ROPLL_SDC_N_RBR_MASK		GENMASK(2, 0)
+/* CMN_REG(0074) */
+#define ROPLL_SDC_NDIV_RSTN		BIT(2)
+#define ROPLL_SSC_EN			BIT(0)
+/* CMN_REG(0081) */
+#define OVRD_PLL_CD_CLK_EN		BIT(8)
+#define PLL_CD_HSCLK_EAST_EN		BIT(0)
+/* CMN_REG(0086) */
+#define PLL_PCG_POSTDIV_SEL_MASK	GENMASK(7, 4)
+#define PLL_PCG_CLK_SEL_MASK		GENMASK(3, 1)
+#define PLL_PCG_CLK_EN			BIT(0)
+/* CMN_REG(0087) */
+#define PLL_FRL_MODE_EN			BIT(3)
+#define PLL_TX_HS_CLK_EN		BIT(2)
+/* CMN_REG(0089) */
+#define LCPLL_ALONE_MODE		BIT(1)
+/* CMN_REG(0097) */
+#define DIG_CLK_SEL			BIT(1)
+#define ROPLL_REF			BIT(1)
+#define LCPLL_REF			0
+/* CMN_REG(0099) */
+#define CMN_ROPLL_ALONE_MODE		BIT(2)
+#define ROPLL_ALONE_MODE		BIT(2)
+/* CMN_REG(009a) */
+#define HS_SPEED_SEL			BIT(0)
+#define DIV_10_CLOCK			BIT(0)
+/* CMN_REG(009b) */
+#define IS_SPEED_SEL			BIT(4)
+#define LINK_SYMBOL_CLOCK		BIT(4)
+#define LINK_SYMBOL_CLOCK1_2		0
+
+/* SB_REG(0102) */
+#define OVRD_SB_RXTERM_EN_MASK		BIT(5)
+#define SB_RXTERM_EN_MASK		BIT(4)
+#define ANA_SB_RXTERM_OFFSP_MASK	GENMASK(3, 0)
+/* SB_REG(0103) */
+#define ANA_SB_RXTERM_OFFSN_MASK	GENMASK(6, 3)
+#define OVRD_SB_RX_RESCAL_DONE_MASK	BIT(1)
+#define SB_RX_RESCAL_DONE_MASK		BIT(0)
+/* SB_REG(0104) */
+#define OVRD_SB_EN_MASK			BIT(5)
+#define SB_EN_MASK			BIT(4)
+/* SB_REG(0105) */
+#define OVRD_SB_EARC_CMDC_EN_MASK	BIT(6)
+#define SB_EARC_CMDC_EN_MASK		BIT(5)
+#define ANA_SB_TX_HLVL_PROG_MASK	GENMASK(2, 0)
+/* SB_REG(0106) */
+#define ANA_SB_TX_LLVL_PROG_MASK	GENMASK(6, 4)
+/* SB_REG(0109) */
+#define ANA_SB_DMRX_AFC_DIV_RATIO_MASK	GENMASK(2, 0)
+/* SB_REG(010f) */
+#define OVRD_SB_VREG_EN_MASK		BIT(7)
+#define SB_VREG_EN_MASK			BIT(6)
+#define OVRD_SB_VREG_LPF_BYPASS_MASK	BIT(5)
+#define SB_VREG_LPF_BYPASS_MASK		BIT(4)
+#define ANA_SB_VREG_GAIN_CTRL_MASK	GENMASK(3, 0)
+/* SB_REG(0110) */
+#define ANA_SB_VREG_REF_SEL_MASK	BIT(0)
+/* SB_REG(0113) */
+#define SB_RX_RCAL_OPT_CODE_MASK	GENMASK(5, 4)
+#define SB_RX_RTERM_CTRL_MASK		GENMASK(3, 0)
+/* SB_REG(0114) */
+#define SB_TG_SB_EN_DELAY_TIME_MASK	GENMASK(5, 3)
+#define SB_TG_RXTERM_EN_DELAY_TIME_MASK	GENMASK(2, 0)
+/* SB_REG(0115) */
+#define SB_READY_DELAY_TIME_MASK	GENMASK(5, 3)
+#define SB_TG_OSC_EN_DELAY_TIME_MASK	GENMASK(2, 0)
+/* SB_REG(0116) */
+#define AFC_RSTN_DELAY_TIME_MASK	GENMASK(6, 4)
+/* SB_REG(0117) */
+#define FAST_PULSE_TIME_MASK		GENMASK(3, 0)
+/* SB_REG(011b) */
+#define SB_EARC_SIG_DET_BYPASS_MASK	BIT(4)
+#define SB_AFC_TOL_MASK			GENMASK(3, 0)
+/* SB_REG(011f) */
+#define SB_PWM_AFC_CTRL_MASK		GENMASK(7, 2)
+#define SB_RCAL_RSTN_MASK		BIT(1)
+/* SB_REG(0120) */
+#define SB_EARC_EN_MASK			BIT(1)
+#define SB_EARC_AFC_EN_MASK		BIT(2)
+/* SB_REG(0123) */
+#define OVRD_SB_READY_MASK		BIT(5)
+#define SB_READY_MASK			BIT(4)
+
+/* LNTOP_REG(0200) */
+#define PROTOCOL_SEL			BIT(2)
+#define HDMI_MODE			BIT(2)
+#define HDMI_TMDS_FRL_SEL		BIT(1)
+/* LNTOP_REG(0206) */
+#define DATA_BUS_SEL			BIT(0)
+#define DATA_BUS_36_40			BIT(0)
+/* LNTOP_REG(0207) */
+#define LANE_EN				0xf
+#define ALL_LANE_EN			0xf
+
+/* LANE_REG(0312) */
+#define LN0_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN0_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN0_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN0_TX_SER_RATE_SEL_HBR3	BIT(2)
+/* LANE_REG(0412) */
+#define LN1_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN1_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN1_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN1_TX_SER_RATE_SEL_HBR3	BIT(2)
+/* LANE_REG(0512) */
+#define LN2_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN2_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN2_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN2_TX_SER_RATE_SEL_HBR3	BIT(2)
+/* LANE_REG(0612) */
+#define LN3_TX_SER_RATE_SEL_RBR		BIT(5)
+#define LN3_TX_SER_RATE_SEL_HBR		BIT(4)
+#define LN3_TX_SER_RATE_SEL_HBR2	BIT(3)
+#define LN3_TX_SER_RATE_SEL_HBR3	BIT(2)
+
+struct lcpll_config {
+	u32 bit_rate;
+	u8 lcvco_mode_en;
+	u8 pi_en;
+	u8 clk_en_100m;
+	u8 pms_mdiv;
+	u8 pms_mdiv_afc;
+	u8 pms_pdiv;
+	u8 pms_refdiv;
+	u8 pms_sdiv;
+	u8 pi_cdiv_rstn;
+	u8 pi_cdiv_sel;
+	u8 sdm_en;
+	u8 sdm_rstn;
+	u8 sdc_frac_en;
+	u8 sdc_rstn;
+	u8 sdm_deno;
+	u8 sdm_num_sign;
+	u8 sdm_num;
+	u8 sdc_n;
+	u8 sdc_n2;
+	u8 sdc_num;
+	u8 sdc_deno;
+	u8 sdc_ndiv_rstn;
+	u8 ssc_en;
+	u8 ssc_fm_dev;
+	u8 ssc_fm_freq;
+	u8 ssc_clk_div_sel;
+	u8 cd_tx_ser_rate_sel;
+};
+
+struct ropll_config {
+	u32 bit_rate;
+	u8 pms_mdiv;
+	u8 pms_mdiv_afc;
+	u8 pms_pdiv;
+	u8 pms_refdiv;
+	u8 pms_sdiv;
+	u8 pms_iqdiv_rstn;
+	u8 ref_clk_sel;
+	u8 sdm_en;
+	u8 sdm_rstn;
+	u8 sdc_frac_en;
+	u8 sdc_rstn;
+	u8 sdm_clk_div;
+	u8 sdm_deno;
+	u8 sdm_num_sign;
+	u8 sdm_num;
+	u8 sdc_n;
+	u8 sdc_num;
+	u8 sdc_deno;
+	u8 sdc_ndiv_rstn;
+	u8 ssc_en;
+	u8 ssc_fm_dev;
+	u8 ssc_fm_freq;
+	u8 ssc_clk_div_sel;
+	u8 ana_cpp_ctrl;
+	u8 ana_lpf_c_sel;
+	u8 cd_tx_ser_rate_sel;
+};
+
+enum rk_hdptx_reset {
+	RST_PHY = 0,
+	RST_APB,
+	RST_INIT,
+	RST_CMN,
+	RST_LANE,
+	RST_ROPLL,
+	RST_LCPLL,
+	RST_MAX
+};
+
+struct rk_hdptx_phy {
+	struct device *dev;
+	struct regmap *regmap;
+	struct regmap *grf;
+
+	struct phy *phy;
+	struct phy_config *phy_cfg;
+	struct clk_bulk_data *clks;
+	int nr_clks;
+	struct reset_control_bulk_data rsts[RST_MAX];
+};
+
+static const struct ropll_config ropll_tmds_cfg[] = {
+	{ 5940000, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 3712500, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 2970000, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1620000, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1856250, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1540000, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1485000, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5,
+	  0x10, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1462500, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1190000, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1065000, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 1080000, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 855000, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 835000, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 928125, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 742500, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 650000, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1,
+	  1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 337500, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5,
+	  1, 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 400000, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 270000, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0,
+	  0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+	{ 251750, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1,
+	  1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, },
+};
+
+static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = {
+	REG_SEQ0(CMN_REG(0009), 0x0c),
+	REG_SEQ0(CMN_REG(000a), 0x83),
+	REG_SEQ0(CMN_REG(000b), 0x06),
+	REG_SEQ0(CMN_REG(000c), 0x20),
+	REG_SEQ0(CMN_REG(000d), 0xb8),
+	REG_SEQ0(CMN_REG(000e), 0x0f),
+	REG_SEQ0(CMN_REG(000f), 0x0f),
+	REG_SEQ0(CMN_REG(0010), 0x04),
+	REG_SEQ0(CMN_REG(0011), 0x00),
+	REG_SEQ0(CMN_REG(0012), 0x26),
+	REG_SEQ0(CMN_REG(0013), 0x22),
+	REG_SEQ0(CMN_REG(0014), 0x24),
+	REG_SEQ0(CMN_REG(0015), 0x77),
+	REG_SEQ0(CMN_REG(0016), 0x08),
+	REG_SEQ0(CMN_REG(0017), 0x00),
+	REG_SEQ0(CMN_REG(0018), 0x04),
+	REG_SEQ0(CMN_REG(0019), 0x48),
+	REG_SEQ0(CMN_REG(001a), 0x01),
+	REG_SEQ0(CMN_REG(001b), 0x00),
+	REG_SEQ0(CMN_REG(001c), 0x01),
+	REG_SEQ0(CMN_REG(001d), 0x64),
+	REG_SEQ0(CMN_REG(001f), 0x00),
+	REG_SEQ0(CMN_REG(0026), 0x53),
+	REG_SEQ0(CMN_REG(0029), 0x01),
+	REG_SEQ0(CMN_REG(0030), 0x00),
+	REG_SEQ0(CMN_REG(0031), 0x20),
+	REG_SEQ0(CMN_REG(0032), 0x30),
+	REG_SEQ0(CMN_REG(0033), 0x0b),
+	REG_SEQ0(CMN_REG(0034), 0x23),
+	REG_SEQ0(CMN_REG(0035), 0x00),
+	REG_SEQ0(CMN_REG(0038), 0x00),
+	REG_SEQ0(CMN_REG(0039), 0x00),
+	REG_SEQ0(CMN_REG(003a), 0x00),
+	REG_SEQ0(CMN_REG(003b), 0x00),
+	REG_SEQ0(CMN_REG(003c), 0x80),
+	REG_SEQ0(CMN_REG(003e), 0x0c),
+	REG_SEQ0(CMN_REG(003f), 0x83),
+	REG_SEQ0(CMN_REG(0040), 0x06),
+	REG_SEQ0(CMN_REG(0041), 0x20),
+	REG_SEQ0(CMN_REG(0042), 0xb8),
+	REG_SEQ0(CMN_REG(0043), 0x00),
+	REG_SEQ0(CMN_REG(0044), 0x46),
+	REG_SEQ0(CMN_REG(0045), 0x24),
+	REG_SEQ0(CMN_REG(0046), 0xff),
+	REG_SEQ0(CMN_REG(0047), 0x00),
+	REG_SEQ0(CMN_REG(0048), 0x44),
+	REG_SEQ0(CMN_REG(0049), 0xfa),
+	REG_SEQ0(CMN_REG(004a), 0x08),
+	REG_SEQ0(CMN_REG(004b), 0x00),
+	REG_SEQ0(CMN_REG(004c), 0x01),
+	REG_SEQ0(CMN_REG(004d), 0x64),
+	REG_SEQ0(CMN_REG(004e), 0x14),
+	REG_SEQ0(CMN_REG(004f), 0x00),
+	REG_SEQ0(CMN_REG(0050), 0x00),
+	REG_SEQ0(CMN_REG(005d), 0x0c),
+	REG_SEQ0(CMN_REG(005f), 0x01),
+	REG_SEQ0(CMN_REG(006b), 0x04),
+	REG_SEQ0(CMN_REG(0073), 0x30),
+	REG_SEQ0(CMN_REG(0074), 0x00),
+	REG_SEQ0(CMN_REG(0075), 0x20),
+	REG_SEQ0(CMN_REG(0076), 0x30),
+	REG_SEQ0(CMN_REG(0077), 0x08),
+	REG_SEQ0(CMN_REG(0078), 0x0c),
+	REG_SEQ0(CMN_REG(0079), 0x00),
+	REG_SEQ0(CMN_REG(007b), 0x00),
+	REG_SEQ0(CMN_REG(007c), 0x00),
+	REG_SEQ0(CMN_REG(007d), 0x00),
+	REG_SEQ0(CMN_REG(007e), 0x00),
+	REG_SEQ0(CMN_REG(007f), 0x00),
+	REG_SEQ0(CMN_REG(0080), 0x00),
+	REG_SEQ0(CMN_REG(0081), 0x09),
+	REG_SEQ0(CMN_REG(0082), 0x04),
+	REG_SEQ0(CMN_REG(0083), 0x24),
+	REG_SEQ0(CMN_REG(0084), 0x20),
+	REG_SEQ0(CMN_REG(0085), 0x03),
+	REG_SEQ0(CMN_REG(0086), 0x01),
+	REG_SEQ0(CMN_REG(0087), 0x0c),
+	REG_SEQ0(CMN_REG(008a), 0x55),
+	REG_SEQ0(CMN_REG(008b), 0x25),
+	REG_SEQ0(CMN_REG(008c), 0x2c),
+	REG_SEQ0(CMN_REG(008d), 0x22),
+	REG_SEQ0(CMN_REG(008e), 0x14),
+	REG_SEQ0(CMN_REG(008f), 0x20),
+	REG_SEQ0(CMN_REG(0090), 0x00),
+	REG_SEQ0(CMN_REG(0091), 0x00),
+	REG_SEQ0(CMN_REG(0092), 0x00),
+	REG_SEQ0(CMN_REG(0093), 0x00),
+	REG_SEQ0(CMN_REG(009a), 0x11),
+	REG_SEQ0(CMN_REG(009b), 0x10),
+};
+
+static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = {
+	REG_SEQ0(CMN_REG(0008), 0x00),
+	REG_SEQ0(CMN_REG(0011), 0x01),
+	REG_SEQ0(CMN_REG(0017), 0x20),
+	REG_SEQ0(CMN_REG(001e), 0x14),
+	REG_SEQ0(CMN_REG(0020), 0x00),
+	REG_SEQ0(CMN_REG(0021), 0x00),
+	REG_SEQ0(CMN_REG(0022), 0x11),
+	REG_SEQ0(CMN_REG(0023), 0x00),
+	REG_SEQ0(CMN_REG(0024), 0x00),
+	REG_SEQ0(CMN_REG(0025), 0x53),
+	REG_SEQ0(CMN_REG(0026), 0x00),
+	REG_SEQ0(CMN_REG(0027), 0x00),
+	REG_SEQ0(CMN_REG(0028), 0x01),
+	REG_SEQ0(CMN_REG(002a), 0x00),
+	REG_SEQ0(CMN_REG(002b), 0x00),
+	REG_SEQ0(CMN_REG(002c), 0x00),
+	REG_SEQ0(CMN_REG(002d), 0x00),
+	REG_SEQ0(CMN_REG(002e), 0x04),
+	REG_SEQ0(CMN_REG(002f), 0x00),
+	REG_SEQ0(CMN_REG(0030), 0x20),
+	REG_SEQ0(CMN_REG(0031), 0x30),
+	REG_SEQ0(CMN_REG(0032), 0x0b),
+	REG_SEQ0(CMN_REG(0033), 0x23),
+	REG_SEQ0(CMN_REG(0034), 0x00),
+	REG_SEQ0(CMN_REG(003d), 0x40),
+	REG_SEQ0(CMN_REG(0042), 0x78),
+	REG_SEQ0(CMN_REG(004e), 0x34),
+	REG_SEQ0(CMN_REG(005c), 0x25),
+	REG_SEQ0(CMN_REG(005e), 0x4f),
+	REG_SEQ0(CMN_REG(0074), 0x04),
+	REG_SEQ0(CMN_REG(0081), 0x01),
+	REG_SEQ0(CMN_REG(0087), 0x04),
+	REG_SEQ0(CMN_REG(0089), 0x00),
+	REG_SEQ0(CMN_REG(0095), 0x00),
+	REG_SEQ0(CMN_REG(0097), 0x02),
+	REG_SEQ0(CMN_REG(0099), 0x04),
+	REG_SEQ0(CMN_REG(009b), 0x00),
+};
+
+static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = {
+	REG_SEQ0(SB_REG(0114), 0x00),
+	REG_SEQ0(SB_REG(0115), 0x00),
+	REG_SEQ0(SB_REG(0116), 0x00),
+	REG_SEQ0(SB_REG(0117), 0x00),
+};
+
+static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = {
+	REG_SEQ0(LNTOP_REG(0201), 0x00),
+	REG_SEQ0(LNTOP_REG(0202), 0x00),
+	REG_SEQ0(LNTOP_REG(0203), 0x0f),
+	REG_SEQ0(LNTOP_REG(0204), 0xff),
+	REG_SEQ0(LNTOP_REG(0205), 0xff),
+};
+
+static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = {
+	REG_SEQ0(LNTOP_REG(0201), 0x07),
+	REG_SEQ0(LNTOP_REG(0202), 0xc1),
+	REG_SEQ0(LNTOP_REG(0203), 0xf0),
+	REG_SEQ0(LNTOP_REG(0204), 0x7c),
+	REG_SEQ0(LNTOP_REG(0205), 0x1f),
+};
+
+static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = {
+	REG_SEQ0(LANE_REG(0303), 0x0c),
+	REG_SEQ0(LANE_REG(0307), 0x20),
+	REG_SEQ0(LANE_REG(030a), 0x17),
+	REG_SEQ0(LANE_REG(030b), 0x77),
+	REG_SEQ0(LANE_REG(030c), 0x77),
+	REG_SEQ0(LANE_REG(030d), 0x77),
+	REG_SEQ0(LANE_REG(030e), 0x38),
+	REG_SEQ0(LANE_REG(0310), 0x03),
+	REG_SEQ0(LANE_REG(0311), 0x0f),
+	REG_SEQ0(LANE_REG(0316), 0x02),
+	REG_SEQ0(LANE_REG(031b), 0x01),
+	REG_SEQ0(LANE_REG(031f), 0x15),
+	REG_SEQ0(LANE_REG(0320), 0xa0),
+	REG_SEQ0(LANE_REG(0403), 0x0c),
+	REG_SEQ0(LANE_REG(0407), 0x20),
+	REG_SEQ0(LANE_REG(040a), 0x17),
+	REG_SEQ0(LANE_REG(040b), 0x77),
+	REG_SEQ0(LANE_REG(040c), 0x77),
+	REG_SEQ0(LANE_REG(040d), 0x77),
+	REG_SEQ0(LANE_REG(040e), 0x38),
+	REG_SEQ0(LANE_REG(0410), 0x03),
+	REG_SEQ0(LANE_REG(0411), 0x0f),
+	REG_SEQ0(LANE_REG(0416), 0x02),
+	REG_SEQ0(LANE_REG(041b), 0x01),
+	REG_SEQ0(LANE_REG(041f), 0x15),
+	REG_SEQ0(LANE_REG(0420), 0xa0),
+	REG_SEQ0(LANE_REG(0503), 0x0c),
+	REG_SEQ0(LANE_REG(0507), 0x20),
+	REG_SEQ0(LANE_REG(050a), 0x17),
+	REG_SEQ0(LANE_REG(050b), 0x77),
+	REG_SEQ0(LANE_REG(050c), 0x77),
+	REG_SEQ0(LANE_REG(050d), 0x77),
+	REG_SEQ0(LANE_REG(050e), 0x38),
+	REG_SEQ0(LANE_REG(0510), 0x03),
+	REG_SEQ0(LANE_REG(0511), 0x0f),
+	REG_SEQ0(LANE_REG(0516), 0x02),
+	REG_SEQ0(LANE_REG(051b), 0x01),
+	REG_SEQ0(LANE_REG(051f), 0x15),
+	REG_SEQ0(LANE_REG(0520), 0xa0),
+	REG_SEQ0(LANE_REG(0603), 0x0c),
+	REG_SEQ0(LANE_REG(0607), 0x20),
+	REG_SEQ0(LANE_REG(060a), 0x17),
+	REG_SEQ0(LANE_REG(060b), 0x77),
+	REG_SEQ0(LANE_REG(060c), 0x77),
+	REG_SEQ0(LANE_REG(060d), 0x77),
+	REG_SEQ0(LANE_REG(060e), 0x38),
+	REG_SEQ0(LANE_REG(0610), 0x03),
+	REG_SEQ0(LANE_REG(0611), 0x0f),
+	REG_SEQ0(LANE_REG(0616), 0x02),
+	REG_SEQ0(LANE_REG(061b), 0x01),
+	REG_SEQ0(LANE_REG(061f), 0x15),
+	REG_SEQ0(LANE_REG(0620), 0xa0),
+};
+
+static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = {
+	REG_SEQ0(LANE_REG(0312), 0x00),
+	REG_SEQ0(LANE_REG(031e), 0x00),
+	REG_SEQ0(LANE_REG(0412), 0x00),
+	REG_SEQ0(LANE_REG(041e), 0x00),
+	REG_SEQ0(LANE_REG(0512), 0x00),
+	REG_SEQ0(LANE_REG(051e), 0x00),
+	REG_SEQ0(LANE_REG(0612), 0x00),
+	REG_SEQ0(LANE_REG(061e), 0x08),
+	REG_SEQ0(LANE_REG(0303), 0x2f),
+	REG_SEQ0(LANE_REG(0403), 0x2f),
+	REG_SEQ0(LANE_REG(0503), 0x2f),
+	REG_SEQ0(LANE_REG(0603), 0x2f),
+	REG_SEQ0(LANE_REG(0305), 0x03),
+	REG_SEQ0(LANE_REG(0405), 0x03),
+	REG_SEQ0(LANE_REG(0505), 0x03),
+	REG_SEQ0(LANE_REG(0605), 0x03),
+	REG_SEQ0(LANE_REG(0306), 0x1c),
+	REG_SEQ0(LANE_REG(0406), 0x1c),
+	REG_SEQ0(LANE_REG(0506), 0x1c),
+	REG_SEQ0(LANE_REG(0606), 0x1c),
+};
+
+static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case 0x0000 ... 0x029c:
+	case 0x0400 ... 0x04a4:
+	case 0x0800 ... 0x08a4:
+	case 0x0c00 ... 0x0cb4:
+	case 0x1000 ... 0x10b4:
+	case 0x1400 ... 0x14b4:
+	case 0x1800 ... 0x18b4:
+		return true;
+	}
+
+	return false;
+}
+
+static const struct regmap_config rk_hdptx_phy_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.writeable_reg = rk_hdptx_phy_is_rw_reg,
+	.readable_reg = rk_hdptx_phy_is_rw_reg,
+	.fast_io = true,
+	.max_register = 0x18b4,
+};
+
+#define rk_hdptx_multi_reg_write(hdptx, seq) \
+	regmap_multi_reg_write((hdptx)->regmap, seq, ARRAY_SIZE(seq))
+
+static void rk_hdptx_pre_power_up(struct rk_hdptx_phy *hdptx)
+{
+	u32 val;
+
+	reset_control_assert(hdptx->rsts[RST_APB].rstc);
+	usleep_range(20, 25);
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+
+	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
+
+	val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+}
+
+static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx)
+{
+	u32 val;
+	int ret;
+
+	reset_control_deassert(hdptx->rsts[RST_LANE].rstc);
+
+	val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
+	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
+				       (val & HDPTX_O_PHY_RDY) &&
+				       (val & HDPTX_O_PLL_LOCK_DONE),
+				       100, 5000);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get PHY lane lock: %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(hdptx->dev, "PHY lane locked\n");
+
+	return 0;
+}
+
+static int rk_hdptx_post_enable_pll(struct rk_hdptx_phy *hdptx)
+{
+	u32 val;
+	int ret;
+
+	val = (HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16 |
+	       HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN;
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+
+	usleep_range(10, 15);
+	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
+
+	usleep_range(10, 15);
+	val = HDPTX_I_PLL_EN << 16 | HDPTX_I_PLL_EN;
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+
+	usleep_range(10, 15);
+	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
+
+	ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val,
+				       val & HDPTX_O_PHY_CLK_RDY, 20, 400);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to get PHY clk ready: %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(hdptx->dev, "PHY clk ready\n");
+
+	return 0;
+}
+
+static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx)
+{
+	u32 val;
+
+	/* reset phy and apb, or phy locked flag may keep 1 */
+	reset_control_assert(hdptx->rsts[RST_PHY].rstc);
+	usleep_range(20, 30);
+	reset_control_deassert(hdptx->rsts[RST_PHY].rstc);
+
+	reset_control_assert(hdptx->rsts[RST_APB].rstc);
+	usleep_range(20, 30);
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+
+	regmap_write(hdptx->regmap, LANE_REG(0300), 0x82);
+	regmap_write(hdptx->regmap, SB_REG(010f), 0xc1);
+	regmap_write(hdptx->regmap, SB_REG(0110), 0x1);
+	regmap_write(hdptx->regmap, LANE_REG(0301), 0x80);
+	regmap_write(hdptx->regmap, LANE_REG(0401), 0x80);
+	regmap_write(hdptx->regmap, LANE_REG(0501), 0x80);
+	regmap_write(hdptx->regmap, LANE_REG(0601), 0x80);
+
+	reset_control_assert(hdptx->rsts[RST_LANE].rstc);
+	reset_control_assert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_assert(hdptx->rsts[RST_INIT].rstc);
+
+	val = (HDPTX_I_PLL_EN | HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN) << 16;
+	regmap_write(hdptx->grf, GRF_HDPTX_CON0, val);
+}
+
+static bool rk_hdptx_phy_clk_pll_calc(unsigned int data_rate,
+				      struct ropll_config *cfg)
+{
+	const unsigned int fout = data_rate / 2, fref = 24000;
+	unsigned long k = 0, lc, k_sub, lc_sub;
+	unsigned int fvco, sdc;
+	u32 mdiv, sdiv, n = 8;
+
+	if (fout > 0xfffffff)
+		return false;
+
+	for (sdiv = 16; sdiv >= 1; sdiv--) {
+		if (sdiv % 2 && sdiv != 1)
+			continue;
+
+		fvco = fout * sdiv;
+
+		if (fvco < 2000000 || fvco > 4000000)
+			continue;
+
+		mdiv = DIV_ROUND_UP(fvco, fref);
+		if (mdiv < 20 || mdiv > 255)
+			continue;
+
+		if (fref * mdiv - fvco) {
+			for (sdc = 264000; sdc <= 750000; sdc += fref)
+				if (sdc * n > fref * mdiv)
+					break;
+
+			if (sdc > 750000)
+				continue;
+
+			rational_best_approximation(fref * mdiv - fvco,
+						    sdc / 16,
+						    GENMASK(6, 0),
+						    GENMASK(7, 0),
+						    &k, &lc);
+
+			rational_best_approximation(sdc * n - fref * mdiv,
+						    sdc,
+						    GENMASK(6, 0),
+						    GENMASK(7, 0),
+						    &k_sub, &lc_sub);
+		}
+
+		break;
+	}
+
+	if (sdiv < 1)
+		return false;
+
+	if (cfg) {
+		cfg->pms_mdiv = mdiv;
+		cfg->pms_mdiv_afc = mdiv;
+		cfg->pms_pdiv = 1;
+		cfg->pms_refdiv = 1;
+		cfg->pms_sdiv = sdiv - 1;
+
+		cfg->sdm_en = k > 0 ? 1 : 0;
+		if (cfg->sdm_en) {
+			cfg->sdm_deno = lc;
+			cfg->sdm_num_sign = 1;
+			cfg->sdm_num = k;
+			cfg->sdc_n = n - 3;
+			cfg->sdc_num = k_sub;
+			cfg->sdc_deno = lc_sub;
+		}
+	}
+
+	return true;
+}
+
+static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
+					  unsigned int rate)
+{
+	const struct ropll_config *cfg = NULL;
+	struct ropll_config rc = {0};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
+		if (rate == ropll_tmds_cfg[i].bit_rate) {
+			cfg = &ropll_tmds_cfg[i];
+			break;
+		}
+
+	if (!cfg) {
+		if (rk_hdptx_phy_clk_pll_calc(rate, &rc)) {
+			cfg = &rc;
+		} else {
+			dev_err(hdptx->dev, "%s cannot find pll cfg\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	dev_dbg(hdptx->dev, "mdiv=%u, sdiv=%u, sdm_en=%u, k_sign=%u, k=%u, lc=%u\n",
+		cfg->pms_mdiv, cfg->pms_sdiv + 1, cfg->sdm_en,
+		cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno);
+
+	rk_hdptx_pre_power_up(hdptx);
+
+	reset_control_assert(hdptx->rsts[RST_ROPLL].rstc);
+	usleep_range(20, 30);
+	reset_control_deassert(hdptx->rsts[RST_ROPLL].rstc);
+
+	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq);
+
+	regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv);
+	regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc);
+	regmap_write(hdptx->regmap, CMN_REG(0059),
+		     (cfg->pms_pdiv << 4) | cfg->pms_refdiv);
+	regmap_write(hdptx->regmap, CMN_REG(005a), cfg->pms_sdiv << 4);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(005e), ROPLL_SDM_EN_MASK,
+			   FIELD_PREP(ROPLL_SDM_EN_MASK, cfg->sdm_en));
+	if (!cfg->sdm_en)
+		regmap_update_bits(hdptx->regmap, CMN_REG(005e), 0xf, 0);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0064), ROPLL_SDM_NUM_SIGN_RBR_MASK,
+			   FIELD_PREP(ROPLL_SDM_NUM_SIGN_RBR_MASK, cfg->sdm_num_sign));
+
+	regmap_write(hdptx->regmap, CMN_REG(0060), cfg->sdm_deno);
+	regmap_write(hdptx->regmap, CMN_REG(0065), cfg->sdm_num);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0069), ROPLL_SDC_N_RBR_MASK,
+			   FIELD_PREP(ROPLL_SDC_N_RBR_MASK, cfg->sdc_n));
+
+	regmap_write(hdptx->regmap, CMN_REG(006c), cfg->sdc_num);
+	regmap_write(hdptx->regmap, CMN_REG(0070), cfg->sdc_deno);
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK,
+			   FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv));
+
+	regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN,
+			   PLL_PCG_CLK_EN);
+
+	return rk_hdptx_post_enable_pll(hdptx);
+}
+
+static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
+					   unsigned int rate)
+{
+	u32 val;
+	int ret;
+
+	ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
+	if (ret)
+		return ret;
+
+	if (!(val & HDPTX_O_PLL_LOCK_DONE)) {
+		ret = rk_hdptx_ropll_tmds_cmn_config(hdptx, rate);
+		if (ret)
+			return ret;
+	}
+
+	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq);
+
+	regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
+
+	if (rate >= 3400000) {
+		/* For 1/40 bitrate clk */
+		rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq);
+	} else {
+		/* For 1/10 bitrate clk */
+		rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_lowbr_seq);
+	}
+
+	regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07);
+	regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f);
+
+	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq);
+	rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq);
+
+	return rk_hdptx_post_enable_lane(hdptx);
+}
+
+static int rk_hdptx_phy_power_on(struct phy *phy)
+{
+	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
+	int ret, bus_width = phy_get_bus_width(hdptx->phy);
+	/*
+	 * FIXME: Temporary workaround to pass pixel_clk_rate
+	 * from the HDMI bridge driver until phy_configure_opts_hdmi
+	 * becomes available in the PHY API.
+	 */
+	unsigned int rate = bus_width & 0xfffffff;
+
+	dev_dbg(hdptx->dev, "%s bus_width=%x rate=%u\n",
+		__func__, bus_width, rate);
+
+	ret = pm_runtime_resume_and_get(hdptx->dev);
+	if (ret) {
+		dev_err(hdptx->dev, "Failed to resume phy: %d\n", ret);
+		return ret;
+	}
+
+	ret = rk_hdptx_ropll_tmds_mode_config(hdptx, rate);
+	if (ret)
+		pm_runtime_put(hdptx->dev);
+
+	return ret;
+}
+
+static int rk_hdptx_phy_power_off(struct phy *phy)
+{
+	struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy);
+	u32 val;
+	int ret;
+
+	ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &val);
+	if (ret == 0 && (val & HDPTX_O_PLL_LOCK_DONE))
+		rk_hdptx_phy_disable(hdptx);
+
+	pm_runtime_put(hdptx->dev);
+
+	return ret;
+}
+
+static const struct phy_ops rk_hdptx_phy_ops = {
+	.power_on  = rk_hdptx_phy_power_on,
+	.power_off = rk_hdptx_phy_power_off,
+	.owner	   = THIS_MODULE,
+};
+
+static int rk_hdptx_phy_runtime_suspend(struct device *dev)
+{
+	struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(hdptx->nr_clks, hdptx->clks);
+
+	return 0;
+}
+
+static int rk_hdptx_phy_runtime_resume(struct device *dev)
+{
+	struct rk_hdptx_phy *hdptx = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(hdptx->nr_clks, hdptx->clks);
+	if (ret)
+		dev_err(hdptx->dev, "Failed to enable clocks: %d\n", ret);
+
+	return ret;
+}
+
+static int rk_hdptx_phy_probe(struct platform_device *pdev)
+{
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	struct rk_hdptx_phy *hdptx;
+	void __iomem *regs;
+	int ret;
+
+	hdptx = devm_kzalloc(dev, sizeof(*hdptx), GFP_KERNEL);
+	if (!hdptx)
+		return -ENOMEM;
+
+	hdptx->dev = dev;
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return dev_err_probe(dev, PTR_ERR(regs),
+				     "Failed to ioremap resource\n");
+
+	ret = devm_clk_bulk_get_all(dev, &hdptx->clks);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to get clocks\n");
+	if (ret == 0)
+		return dev_err_probe(dev, -EINVAL, "Missing clocks\n");
+
+	hdptx->nr_clks = ret;
+
+	hdptx->regmap = devm_regmap_init_mmio(dev, regs,
+					      &rk_hdptx_phy_regmap_config);
+	if (IS_ERR(hdptx->regmap))
+		return dev_err_probe(dev, PTR_ERR(hdptx->regmap),
+				     "Failed to init regmap\n");
+
+	hdptx->rsts[RST_PHY].id = "phy";
+	hdptx->rsts[RST_APB].id = "apb";
+	hdptx->rsts[RST_INIT].id = "init";
+	hdptx->rsts[RST_CMN].id = "cmn";
+	hdptx->rsts[RST_LANE].id = "lane";
+	hdptx->rsts[RST_ROPLL].id = "ropll";
+	hdptx->rsts[RST_LCPLL].id = "lcpll";
+
+	ret = devm_reset_control_bulk_get_exclusive(dev, RST_MAX, hdptx->rsts);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to get resets\n");
+
+	hdptx->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+						     "rockchip,grf");
+	if (IS_ERR(hdptx->grf))
+		return dev_err_probe(dev, PTR_ERR(hdptx->grf),
+				     "Could not get GRF syscon\n");
+
+	hdptx->phy = devm_phy_create(dev, NULL, &rk_hdptx_phy_ops);
+	if (IS_ERR(hdptx->phy))
+		return dev_err_probe(dev, PTR_ERR(hdptx->phy),
+				     "Failed to create HDMI PHY\n");
+
+	platform_set_drvdata(pdev, hdptx);
+	phy_set_drvdata(hdptx->phy, hdptx);
+	phy_set_bus_width(hdptx->phy, 8);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider))
+		return dev_err_probe(dev, PTR_ERR(phy_provider),
+				     "Failed to register PHY provider\n");
+
+	reset_control_deassert(hdptx->rsts[RST_APB].rstc);
+	reset_control_deassert(hdptx->rsts[RST_CMN].rstc);
+	reset_control_deassert(hdptx->rsts[RST_INIT].rstc);
+
+	return 0;
+}
+
+static const struct dev_pm_ops rk_hdptx_phy_pm_ops = {
+	RUNTIME_PM_OPS(rk_hdptx_phy_runtime_suspend,
+		       rk_hdptx_phy_runtime_resume, NULL)
+};
+
+static const struct of_device_id rk_hdptx_phy_of_match[] = {
+	{ .compatible = "rockchip,rk3588-hdptx-phy", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, rk_hdptx_phy_of_match);
+
+static struct platform_driver rk_hdptx_phy_driver = {
+	.probe  = rk_hdptx_phy_probe,
+	.driver = {
+		.name = "rockchip-hdptx-phy",
+		.pm = &rk_hdptx_phy_pm_ops,
+		.of_match_table = rk_hdptx_phy_of_match,
+	},
+};
+module_platform_driver(rk_hdptx_phy_driver);
+
+MODULE_AUTHOR("Algea Cao <algea.cao at rock-chips.com>");
+MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea at collabora.com>");
+MODULE_DESCRIPTION("Samsung HDMI/eDP Transmitter Combo PHY Driver");
+MODULE_LICENSE("GPL");

-- 
2.43.0



From cristian.ciocaltea at collabora.com  Wed Feb 14 03:50:18 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 14 Feb 2024 13:50:18 +0200
Subject: [PATCH v3 2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY
 driver
In-Reply-To: <b89552bf-cb04-42b1-94ac-5529205b3be1@gmail.com>
References: <20240212-phy-hdptx-v3-0-2cde680cd024@collabora.com>
 <20240212-phy-hdptx-v3-2-2cde680cd024@collabora.com>
 <b89552bf-cb04-42b1-94ac-5529205b3be1@gmail.com>
Message-ID: <87fe0e42-d4b9-43d4-87e2-0d054283c7b7@collabora.com>

On 2/13/24 01:29, Johan Jonker wrote:
> 
> On 2/12/24 19:52, Cristian Ciocaltea wrote:
>> Add driver for the HDMI/eDP TX Combo PHY found on Rockchip RK3588 SoC.

[...]

> For Linux FTRACE filters it is needed that all functions in a driver start with the same function prefix.
> Currently there's a mix of hdtpx_* and rockchip_*
> Maybe use rk_hdtpx_* ??? similar to for example rk_nfc_* in rockchip-nand-controller.c

Done in v4:

https://lore.kernel.org/all/20240214-phy-hdptx-v4-0-e7974f46c1a7 at collabora.com/

Thanks,
Cristian


From bhargav.r at ltts.com  Wed Feb 14 04:02:49 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Wed, 14 Feb 2024 17:32:49 +0530
Subject: [RESEND PATCH v1 01/13] mfd: tps6594: Add register definitions for TI TPS65224 PMIC
In-Reply-To: <20240209173517.i67qttasxjum7oek@strum>
References: <20240209173517.i67qttasxjum7oek@strum>
Message-ID: <20240214120249.89716-1-bhargav.r@ltts.com>

Hi,

On Fri, 9 Feb 2024 11:35:17 -0600, Nishanth Menon wrote:
> On 16:23-20240208, Bhargav Raviprakash wrote:
> > From: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
> > 
> > Extend TPS6594 PMIC register and field definitions to support TPS65224
> > power management IC.
> > 
> > TPS65224 is software compatible to TPS6594 and can re-use many of the
> > same definitions, new definitions are added to support additional
> > controls available on TPS65224.
> > 
> > Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
> 
> You've got to Sign-off as part of recommendations read [1]
> 
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst#n451
> -- 
> Regards,
> Nishanth Menon

Thanks for your feedback. We will do the sign-off in next patch version.

Regards,
Bhargav


From Jonathan.Cameron at Huawei.com  Wed Feb 14 04:06:07 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Wed, 14 Feb 2024 12:06:07 +0000
Subject: [PATCH] perf: CXL: fix CPMU filter value mask length
In-Reply-To: <20240214045214epcms2p81d2ea826483fb4aecf19930f2755d55b@epcms2p8>
References: <CGME20240214045214epcms2p81d2ea826483fb4aecf19930f2755d55b@epcms2p8>
	<20240214045214epcms2p81d2ea826483fb4aecf19930f2755d55b@epcms2p8>
Message-ID: <20240214120607.00002bdd@Huawei.com>

On Wed, 14 Feb 2024 13:52:14 +0900
Hojin Nam <hj96.nam at samsung.com> wrote:

> CPMU filter value is described as 4B length in CXL r3.0 8.2.7.2.2.
> However, it is used as 2B length in code and comments.
> 
> Fixes: 5d7107c72796 ("perf: CXL Performance Monitoring Unit driver")
> Signed-off-by: Hojin Nam
Sign off broken.

I have my suspicions about why this is the case (bit of history involved
that I won't go into) but indeed this is wrong. So with SoB fixed.

However, I think the driver only supports HDM filtering currently so
you can't actually hit this. Hence not sure the fixes tag is
appropriate. If you can hit this limitation please post the command.

Worth noting that we still don't have a way to attach this to
switch USPs or host bridges, so the increase in HDM decoders to 32 for
those in r3.1 isn't yet relevant.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
 
> ---
>  drivers/perf/cxl_pmu.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
> index 365d964b0f6a..ca5e92f28b4a 100644
> --- a/drivers/perf/cxl_pmu.c
> +++ b/drivers/perf/cxl_pmu.c
> @@ -59,7 +59,7 @@
>  #define   CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK     GENMASK_ULL(63, 59)
> 
>  #define CXL_PMU_FILTER_CFG_REG(n, f)   (0x400 + 4 * ((f) + (n) * 8))
> -#define   CXL_PMU_FILTER_CFG_VALUE_MSK                 GENMASK(15, 0)
> +#define   CXL_PMU_FILTER_CFG_VALUE_MSK                 GENMASK(31, 0)
> 
>  #define CXL_PMU_COUNTER_REG(n)         (0xc00 + 8 * (n))
> 
> @@ -314,9 +314,9 @@ static bool cxl_pmu_config1_get_edge(struct perf_event *event)
>  }
> 
>  /*
> - * CPMU specification allows for 8 filters, each with a 16 bit value...
> - * So we need to find 8x16bits to store it in.
> - * As the value used for disable is 0xffff, a separate enable switch
> + * CPMU specification allows for 8 filters, each with a 32 bit value...
> + * So we need to find 8x32bits to store it in.
> + * As the value used for disable is 0xffff_ffff, a separate enable switch
>   * is needed.
>   */
> 
> @@ -642,7 +642,7 @@ static void cxl_pmu_event_start(struct perf_event *event, int flags)
>                 if (cxl_pmu_config1_hdm_filter_en(event))
>                         cfg = cxl_pmu_config2_get_hdm_decoder(event);
>                 else
> -                       cfg = GENMASK(15, 0); /* No filtering if 0xFFFF_FFFF */
> +                       cfg = GENMASK(31, 0); /* No filtering if 0xFFFF_FFFF */
>                 writeq(cfg, base + CXL_PMU_FILTER_CFG_REG(hwc->idx, 0));
>         }
> 
> --
> 2.34.1



From broonie at kernel.org  Wed Feb 14 04:24:56 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 14 Feb 2024 12:24:56 +0000
Subject: [PATCH] dt-bindings: sound:atmel-at91sam9g20ek: convert bindings
 to json-schema
In-Reply-To: <20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b@microchip.com>
References: <20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b@microchip.com>
Message-ID: <aa707af2-b0ef-46de-83ae-584756d5569d@sirena.org.uk>

On Wed, Feb 14, 2024 at 12:10:06PM +0530, Balakrishnan Sambath wrote:
> Convert atmel-at91sam9g20ek-wm8731-audio DT binding to yaml
> based json-schema.Change file name to match json-scheme naming.

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/20240214/2852ff2e/attachment.sig>

From ardb+git at google.com  Wed Feb 14 04:28:46 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:46 +0100
Subject: [PATCH v8 00/43] arm64: Add support for LPA2 and WXN at stage 1
Message-ID: <20240214122845.2033971-45-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

This v8 covers the remaining changes that implement support for LPA2 and
WXN at stage 1, now that some of the prerequisites are in place.

v4: https://lore.kernel.org/r/20230912141549.278777-63-ardb at google.com/
v5: https://lore.kernel.org/r/20231124101840.944737-41-ardb at google.com/
v6: https://lore.kernel.org/r/20231129111555.3594833-43-ardb at google.com/
v7: https://lore.kernel.org/r/20240123145258.1462979-52-ardb%2Bgit%40google.com/

-%-

Changes in v8:
- rebase onto arm64/reorg-va-space and drop the patches that were merged
- bring back the KVM change to rely on vabits_actual to decide at which
  level a walk of the user space page tables should start

Changes in v7:
- rebase onto v6.8-rc1 which includes some patches of the previous
  revision, and includes the KVM changes for LPA2

The first ~30 patches rework the early init code, reimplementing most of
the page table and relocation handling in C code. There are several
reasons why this is needed:
- we generally prefer C code over asm for these things, and the macros
  that currently exist in head.S for creating the kernel page tables
  are a good example why;
- we no longer need to create the kernel mapping in two passes, which
  means we can remove the logic that copies parts of the fixmap and the
  KAsan shadow from one set of page tables to the other; this is
  especially advantageous for KAsan with LPA2, which needs more
  elaborate shadow handling across multiple levels, since the KAsan
  region cannot be placed on exact pgd_t boundaries in that case;
- we can read the ID registers and parse command line overrides before
  creating the page tables, which simplifies the LPA2 case, as flicking
  the global TCR_EL1.DS bit at a later stage would require elaborate
  repainting of all page table descriptors, some of which with the MMU
  disabled;
- we can use more elaborate logic to create the mappings, which means we
  can use more precise mappings for code and data sections even when
  using 2 MiB granularity, and this is a prerequisite for running with
  WXN.

As part of the ID map changes, we decouple the ID map size from the
kernel VA size, and switch to a 48-bit VA map for all configurations.

The next ~10 patches rework the existing LVA support as a CPU feature,
which simplifies some code and gets rid of the vabits_actual variable.
Then, LPA2 support is implemented in the same vein. This requires adding
support for 5 level paging as well, given that LPA2 introduces a new
paging level '-1' when using 4k pages.

Combined with the vmemmap changes at the start of the series, the
resulting LPA2/4k pages configuration will have the exact same VA space
layout as the ordinary 4k/4 levels configuration, and so LPA2 support
can reasonably be enabled by default, as the fallback is seamless on
non-LPA2 hardware.

In the 16k/LPA2 case, the fallback also reduces the number of paging
levels, resulting in a 47-bit VA space. This is based on the assumption
that hybrid LPA2/non-LPA2 16k pages kernels in production use would
prefer not to take the performance hit of 4 level paging to gain only a
single additional bit of VA space. (Note that generic Android kernels
use only 3 levels of paging today.) Bespoke 16k configurations can still
configure 48-bit virtual addressing as before.

Finally, enable support for running with the WXN control enabled. This
was previously part of a separate series, but given that the delta is
tiny, it is included here as well.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Ryan Roberts <ryan.roberts at arm.com>
Cc: Anshuman Khandual <anshuman.khandual at arm.com>
Cc: Kees Cook <keescook at chromium.org>

Ard Biesheuvel (43):
  arm64: kernel: Manage absolute relocations in code built under pi/
  arm64: kernel: Don't rely on objcopy to make code under pi/ __init
  arm64: head: move relocation handling to C code
  arm64: idreg-override: Move to early mini C runtime
  arm64: kernel: Remove early fdt remap code
  arm64: head: Clear BSS and the kernel page tables in one go
  arm64: Move feature overrides into the BSS section
  arm64: head: Run feature override detection before mapping the kernel
  arm64: head: move dynamic shadow call stack patching into early C
    runtime
  arm64: cpufeature: Add helper to test for CPU feature overrides
  arm64: kaslr: Use feature override instead of parsing the cmdline
    again
  arm64: idreg-override: Create a pseudo feature for rodata=off
  arm64: Add helpers to probe local CPU for PAC and BTI support
  arm64: head: allocate more pages for the kernel mapping
  arm64: head: move memstart_offset_seed handling to C code
  arm64: mm: Make kaslr_requires_kpti() a static inline
  arm64: mmu: Make __cpu_replace_ttbr1() out of line
  arm64: head: Move early kernel mapping routines into C code
  arm64: mm: Use 48-bit virtual addressing for the permanent ID map
  arm64: pgtable: Decouple PGDIR size macros from PGD/PUD/PMD levels
  arm64: kernel: Create initial ID map from C code
  arm64: mm: avoid fixmap for early swapper_pg_dir updates
  arm64: mm: omit redundant remap of kernel image
  arm64: Revert "mm: provide idmap pointer to cpu_replace_ttbr1()"
  arm64: mm: Handle LVA support as a CPU feature
  arm64: mm: Add feature override support for LVA
  arm64: Avoid #define'ing PTE_MAYBE_NG to 0x0 for asm use
  arm64: Add ESR decoding for exceptions involving translation level -1
  arm64: mm: Wire up TCR.DS bit to PTE shareability fields
  arm64: mm: Add LPA2 support to phys<->pte conversion routines
  arm64: mm: Add definitions to support 5 levels of paging
  arm64: mm: add LPA2 and 5 level paging support to G-to-nG conversion
  arm64: Enable LPA2 at boot if supported by the system
  arm64: mm: Add 5 level paging support to fixmap and swapper handling
  arm64: kasan: Reduce minimum shadow alignment and enable 5 level
    paging
  arm64: mm: Add support for folding PUDs at runtime
  arm64: ptdump: Disregard unaddressable VA space
  arm64: ptdump: Deal with translation levels folded at runtime
  arm64: kvm: avoid CONFIG_PGTABLE_LEVELS for runtime levels
  arm64: Enable 52-bit virtual addressing for 4k and 16k granule configs
  arm64: defconfig: Enable LPA2 support
  mm: add arch hook to validate mmap() prot flags
  arm64: mm: add support for WXN memory translation attribute

 arch/arm64/Kconfig                          |  38 +-
 arch/arm64/configs/defconfig                |   1 -
 arch/arm64/include/asm/archrandom.h         |   2 -
 arch/arm64/include/asm/assembler.h          |  55 +--
 arch/arm64/include/asm/cpufeature.h         | 116 +++++
 arch/arm64/include/asm/esr.h                |  13 +-
 arch/arm64/include/asm/fixmap.h             |   2 +-
 arch/arm64/include/asm/kasan.h              |   2 -
 arch/arm64/include/asm/kernel-pgtable.h     | 103 ++---
 arch/arm64/include/asm/kvm_emulate.h        |  10 +-
 arch/arm64/include/asm/memory.h             |  17 +-
 arch/arm64/include/asm/mman.h               |  36 ++
 arch/arm64/include/asm/mmu.h                |  40 +-
 arch/arm64/include/asm/mmu_context.h        |  83 ++--
 arch/arm64/include/asm/pgalloc.h            |  53 ++-
 arch/arm64/include/asm/pgtable-hwdef.h      |  33 +-
 arch/arm64/include/asm/pgtable-prot.h       |  20 +-
 arch/arm64/include/asm/pgtable-types.h      |   6 +
 arch/arm64/include/asm/pgtable.h            | 219 ++++++++-
 arch/arm64/include/asm/scs.h                |  36 +-
 arch/arm64/include/asm/setup.h              |   3 -
 arch/arm64/include/asm/tlb.h                |   3 +
 arch/arm64/kernel/Makefile                  |  13 +-
 arch/arm64/kernel/cpufeature.c              | 111 +++--
 arch/arm64/kernel/head.S                    | 463 ++------------------
 arch/arm64/kernel/image-vars.h              |  35 +-
 arch/arm64/kernel/kaslr.c                   |   4 +-
 arch/arm64/kernel/module.c                  |   2 +-
 arch/arm64/kernel/pi/Makefile               |  27 +-
 arch/arm64/kernel/{ => pi}/idreg-override.c |  80 ++--
 arch/arm64/kernel/pi/kaslr_early.c          |  67 +--
 arch/arm64/kernel/pi/map_kernel.c           | 276 ++++++++++++
 arch/arm64/kernel/pi/map_range.c            | 105 +++++
 arch/arm64/kernel/{ => pi}/patch-scs.c      |  36 +-
 arch/arm64/kernel/pi/pi.h                   |  36 ++
 arch/arm64/kernel/pi/relacheck.c            | 130 ++++++
 arch/arm64/kernel/pi/relocate.c             |  64 +++
 arch/arm64/kernel/setup.c                   |  22 -
 arch/arm64/kernel/sleep.S                   |   3 -
 arch/arm64/kernel/vmlinux.lds.S             |  17 +-
 arch/arm64/kvm/mmu.c                        |  17 +-
 arch/arm64/mm/fault.c                       |  30 +-
 arch/arm64/mm/fixmap.c                      |  36 +-
 arch/arm64/mm/init.c                        |   2 +-
 arch/arm64/mm/kasan_init.c                  | 159 +++++--
 arch/arm64/mm/mmap.c                        |   4 +
 arch/arm64/mm/mmu.c                         | 255 ++++++-----
 arch/arm64/mm/pgd.c                         |  17 +-
 arch/arm64/mm/proc.S                        | 122 +++++-
 arch/arm64/mm/ptdump.c                      |  21 +-
 arch/arm64/tools/cpucaps                    |   1 +
 include/linux/mman.h                        |  15 +
 mm/mmap.c                                   |   3 +
 53 files changed, 1948 insertions(+), 1116 deletions(-)
 rename arch/arm64/kernel/{ => pi}/idreg-override.c (83%)
 create mode 100644 arch/arm64/kernel/pi/map_kernel.c
 create mode 100644 arch/arm64/kernel/pi/map_range.c
 rename arch/arm64/kernel/{ => pi}/patch-scs.c (89%)
 create mode 100644 arch/arm64/kernel/pi/pi.h
 create mode 100644 arch/arm64/kernel/pi/relacheck.c
 create mode 100644 arch/arm64/kernel/pi/relocate.c

-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:47 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:47 +0100
Subject: [PATCH v8 01/43] arm64: kernel: Manage absolute relocations in code
 built under pi/
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-46-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The mini C runtime runs before relocations are processed, and so it
cannot rely on statically initialized pointer variables.

Add a check to ensure that such code does not get introduced by
accident, by going over the relocations in each object, identifying the
ones that operate on data sections that are part of the executable
image, and raising an error if any relocations of type R_AARCH64_ABS64
exist. Note that such relocations are permitted in other places (e.g.,
debug sections) and will never occur in compiler generated code sections
when using the small code model, so only check sections that have
SHF_ALLOC set and SHF_EXECINSTR cleared.

To accommodate cases where statically initialized symbol references are
unavoidable, introduce a special case for ELF input data sections that
have ".rodata.prel64" in their names, and in these cases, instead of
rejecting any encountered ABS64 relocations, convert them into PREL64
relocations, which don't require any runtime fixups. Note that the code
in question must still be modified to deal with this, as it needs to
convert the 64-bit signed offsets into absolute addresses before use.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/pi/Makefile    |   9 +-
 arch/arm64/kernel/pi/pi.h        |  18 +++
 arch/arm64/kernel/pi/relacheck.c | 130 ++++++++++++++++++++
 3 files changed, 155 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile
index c844a0546d7f..bc32a431fe35 100644
--- a/arch/arm64/kernel/pi/Makefile
+++ b/arch/arm64/kernel/pi/Makefile
@@ -22,11 +22,16 @@ KCSAN_SANITIZE	:= n
 UBSAN_SANITIZE	:= n
 KCOV_INSTRUMENT	:= n
 
+hostprogs	:= relacheck
+
+quiet_cmd_piobjcopy = $(quiet_cmd_objcopy)
+      cmd_piobjcopy = $(cmd_objcopy) && $(obj)/relacheck $(@) $(<)
+
 $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
 			       --remove-section=.note.gnu.property \
 			       --prefix-alloc-sections=.init
-$(obj)/%.pi.o: $(obj)/%.o FORCE
-	$(call if_changed,objcopy)
+$(obj)/%.pi.o: $(obj)/%.o $(obj)/relacheck FORCE
+	$(call if_changed,piobjcopy)
 
 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
diff --git a/arch/arm64/kernel/pi/pi.h b/arch/arm64/kernel/pi/pi.h
new file mode 100644
index 000000000000..7c2d9bbf0ff9
--- /dev/null
+++ b/arch/arm64/kernel/pi/pi.h
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2023 Google LLC
+// Author: Ard Biesheuvel <ardb at google.com>
+
+#define __prel64_initconst	__section(".init.rodata.prel64")
+
+#define PREL64(type, name)	union { type *name; prel64_t name ## _prel; }
+
+#define prel64_pointer(__d)	(typeof(__d))prel64_to_pointer(&__d##_prel)
+
+typedef volatile signed long prel64_t;
+
+static inline void *prel64_to_pointer(const prel64_t *offset)
+{
+	if (!*offset)
+		return NULL;
+	return (void *)offset + *offset;
+}
diff --git a/arch/arm64/kernel/pi/relacheck.c b/arch/arm64/kernel/pi/relacheck.c
new file mode 100644
index 000000000000..b0cd4d0d275b
--- /dev/null
+++ b/arch/arm64/kernel/pi/relacheck.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 - Google LLC
+ * Author: Ard Biesheuvel <ardb at google.com>
+ */
+
+#include <elf.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define HOST_ORDER ELFDATA2LSB
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define HOST_ORDER ELFDATA2MSB
+#endif
+
+static Elf64_Ehdr *ehdr;
+static Elf64_Shdr *shdr;
+static const char *strtab;
+static bool swap;
+
+static uint64_t swab_elfxword(uint64_t val)
+{
+	return swap ? __builtin_bswap64(val) : val;
+}
+
+static uint32_t swab_elfword(uint32_t val)
+{
+	return swap ? __builtin_bswap32(val) : val;
+}
+
+static uint16_t swab_elfhword(uint16_t val)
+{
+	return swap ? __builtin_bswap16(val) : val;
+}
+
+int main(int argc, char *argv[])
+{
+	struct stat stat;
+	int fd, ret;
+
+	if (argc < 3) {
+		fprintf(stderr, "file arguments missing\n");
+		exit(EXIT_FAILURE);
+	}
+
+	fd = open(argv[1], O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "failed to open %s\n", argv[1]);
+		exit(EXIT_FAILURE);
+	}
+
+	ret = fstat(fd, &stat);
+	if (ret < 0) {
+		fprintf(stderr, "failed to stat() %s\n", argv[1]);
+		exit(EXIT_FAILURE);
+	}
+
+	ehdr = mmap(0, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+	if (ehdr == MAP_FAILED) {
+		fprintf(stderr, "failed to mmap() %s\n", argv[1]);
+		exit(EXIT_FAILURE);
+	}
+
+	swap = ehdr->e_ident[EI_DATA] != HOST_ORDER;
+	shdr = (void *)ehdr + swab_elfxword(ehdr->e_shoff);
+	strtab = (void *)ehdr +
+		 swab_elfxword(shdr[swab_elfhword(ehdr->e_shstrndx)].sh_offset);
+
+	for (int i = 0; i < swab_elfhword(ehdr->e_shnum); i++) {
+		unsigned long info, flags;
+		bool prel64 = false;
+		Elf64_Rela *rela;
+		int numrela;
+
+		if (swab_elfword(shdr[i].sh_type) != SHT_RELA)
+			continue;
+
+		/* only consider RELA sections operating on data */
+		info = swab_elfword(shdr[i].sh_info);
+		flags = swab_elfxword(shdr[info].sh_flags);
+		if ((flags & (SHF_ALLOC | SHF_EXECINSTR)) != SHF_ALLOC)
+			continue;
+
+		/*
+		 * We generally don't permit ABS64 relocations in the code that
+		 * runs before relocation processing occurs. If statically
+		 * initialized absolute symbol references are unavoidable, they
+		 * may be emitted into a *.rodata.prel64 section and they will
+		 * be converted to place-relative 64-bit references. This
+		 * requires special handling in the referring code.
+		 */
+		if (strstr(strtab + swab_elfword(shdr[info].sh_name),
+			   ".rodata.prel64")) {
+			prel64 = true;
+		}
+
+		rela = (void *)ehdr + swab_elfxword(shdr[i].sh_offset);
+		numrela = swab_elfxword(shdr[i].sh_size) / sizeof(*rela);
+
+		for (int j = 0; j < numrela; j++) {
+			uint64_t info = swab_elfxword(rela[j].r_info);
+
+			if (ELF64_R_TYPE(info) != R_AARCH64_ABS64)
+				continue;
+
+			if (prel64) {
+				/* convert ABS64 into PREL64 */
+				info ^= R_AARCH64_ABS64 ^ R_AARCH64_PREL64;
+				rela[j].r_info = swab_elfxword(info);
+			} else {
+				fprintf(stderr,
+					"Unexpected absolute relocations detected in %s\n",
+					argv[2]);
+				close(fd);
+				unlink(argv[1]);
+				exit(EXIT_FAILURE);
+			}
+		}
+	}
+	close(fd);
+	return 0;
+}
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:49 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:49 +0100
Subject: [PATCH v8 03/43] arm64: head: move relocation handling to C code
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-48-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Now that we have a mini C runtime before the kernel mapping is up, we
can move the non-trivial relocation processing code out of head.S and
reimplement it in C.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/Makefile      |   3 +-
 arch/arm64/kernel/head.S        | 104 ++------------------
 arch/arm64/kernel/pi/Makefile   |   5 +-
 arch/arm64/kernel/pi/relocate.c |  62 ++++++++++++
 arch/arm64/kernel/vmlinux.lds.S |  12 ++-
 5 files changed, 82 insertions(+), 104 deletions(-)

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 467cb7117273..78f14084f6d7 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -57,7 +57,8 @@ obj-$(CONFIG_ACPI)			+= acpi.o
 obj-$(CONFIG_ACPI_NUMA)			+= acpi_numa.o
 obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)	+= acpi_parking_protocol.o
 obj-$(CONFIG_PARAVIRT)			+= paravirt.o
-obj-$(CONFIG_RANDOMIZE_BASE)		+= kaslr.o pi/
+obj-$(CONFIG_RELOCATABLE)		+= pi/
+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	\
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index cab7f91949d8..a8fa64fc30d7 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -81,7 +81,7 @@
 	 *  x20        primary_entry() .. __primary_switch()    CPU boot mode
 	 *  x21        primary_entry() .. start_kernel()        FDT pointer passed at boot in x0
 	 *  x22        create_idmap() .. start_kernel()         ID map VA of the DT blob
-	 *  x23        primary_entry() .. start_kernel()        physical misalignment/KASLR offset
+	 *  x23        __primary_switch()                       physical misalignment/KASLR offset
 	 *  x24        __primary_switch()                       linear map KASLR seed
 	 *  x25        primary_entry() .. start_kernel()        supported VA size
 	 *  x28        create_idmap()                           callee preserved temp register
@@ -389,7 +389,7 @@ SYM_FUNC_START_LOCAL(create_idmap)
 	/* Remap the kernel page tables r/w in the ID map */
 	adrp	x1, _text
 	adrp	x2, init_pg_dir
-	adrp	x3, init_pg_end
+	adrp	x3, _end
 	bic	x4, x2, #SWAPPER_BLOCK_SIZE - 1
 	mov_q	x5, SWAPPER_RW_MMUFLAGS
 	mov	x6, #SWAPPER_BLOCK_SHIFT
@@ -779,97 +779,6 @@ SYM_FUNC_START_LOCAL(__no_granule_support)
 	b	1b
 SYM_FUNC_END(__no_granule_support)
 
-#ifdef CONFIG_RELOCATABLE
-SYM_FUNC_START_LOCAL(__relocate_kernel)
-	/*
-	 * Iterate over each entry in the relocation table, and apply the
-	 * relocations in place.
-	 */
-	adr_l	x9, __rela_start
-	adr_l	x10, __rela_end
-	mov_q	x11, KIMAGE_VADDR		// default virtual offset
-	add	x11, x11, x23			// actual virtual offset
-
-0:	cmp	x9, x10
-	b.hs	1f
-	ldp	x12, x13, [x9], #24
-	ldr	x14, [x9, #-8]
-	cmp	w13, #R_AARCH64_RELATIVE
-	b.ne	0b
-	add	x14, x14, x23			// relocate
-	str	x14, [x12, x23]
-	b	0b
-
-1:
-#ifdef CONFIG_RELR
-	/*
-	 * Apply RELR relocations.
-	 *
-	 * RELR is a compressed format for storing relative relocations. The
-	 * encoded sequence of entries looks like:
-	 * [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
-	 *
-	 * i.e. start with an address, followed by any number of bitmaps. The
-	 * address entry encodes 1 relocation. The subsequent bitmap entries
-	 * encode up to 63 relocations each, at subsequent offsets following
-	 * the last address entry.
-	 *
-	 * The bitmap entries must have 1 in the least significant bit. The
-	 * assumption here is that an address cannot have 1 in lsb. Odd
-	 * addresses are not supported. Any odd addresses are stored in the RELA
-	 * section, which is handled above.
-	 *
-	 * Excluding the least significant bit in the bitmap, each non-zero
-	 * bit in the bitmap represents a relocation to be applied to
-	 * a corresponding machine word that follows the base address
-	 * word. The second least significant bit represents the machine
-	 * word immediately following the initial address, and each bit
-	 * that follows represents the next word, in linear order. As such,
-	 * a single bitmap can encode up to 63 relocations in a 64-bit object.
-	 *
-	 * In this implementation we store the address of the next RELR table
-	 * entry in x9, the address being relocated by the current address or
-	 * bitmap entry in x13 and the address being relocated by the current
-	 * bit in x14.
-	 */
-	adr_l	x9, __relr_start
-	adr_l	x10, __relr_end
-
-2:	cmp	x9, x10
-	b.hs	7f
-	ldr	x11, [x9], #8
-	tbnz	x11, #0, 3f			// branch to handle bitmaps
-	add	x13, x11, x23
-	ldr	x12, [x13]			// relocate address entry
-	add	x12, x12, x23
-	str	x12, [x13], #8			// adjust to start of bitmap
-	b	2b
-
-3:	mov	x14, x13
-4:	lsr	x11, x11, #1
-	cbz	x11, 6f
-	tbz	x11, #0, 5f			// skip bit if not set
-	ldr	x12, [x14]			// relocate bit
-	add	x12, x12, x23
-	str	x12, [x14]
-
-5:	add	x14, x14, #8			// move to next bit's address
-	b	4b
-
-6:	/*
-	 * Move to the next bitmap's address. 8 is the word size, and 63 is the
-	 * number of significant bits in a bitmap entry.
-	 */
-	add	x13, x13, #(8 * 63)
-	b	2b
-
-7:
-#endif
-	ret
-
-SYM_FUNC_END(__relocate_kernel)
-#endif
-
 SYM_FUNC_START_LOCAL(__primary_switch)
 	adrp	x1, reserved_pg_dir
 	adrp	x2, init_idmap_pg_dir
@@ -877,11 +786,11 @@ SYM_FUNC_START_LOCAL(__primary_switch)
 #ifdef CONFIG_RELOCATABLE
 	adrp	x23, KERNEL_START
 	and	x23, x23, MIN_KIMG_ALIGN - 1
-#ifdef CONFIG_RANDOMIZE_BASE
-	mov	x0, x22
-	adrp	x1, init_pg_end
+	adrp	x1, early_init_stack
 	mov	sp, x1
 	mov	x29, xzr
+#ifdef CONFIG_RANDOMIZE_BASE
+	mov	x0, x22
 	bl	__pi_kaslr_early_init
 	and	x24, x0, #SZ_2M - 1		// capture memstart offset seed
 	bic	x0, x0, #SZ_2M - 1
@@ -894,7 +803,8 @@ SYM_FUNC_START_LOCAL(__primary_switch)
 	adrp	x1, init_pg_dir
 	load_ttbr1 x1, x1, x2
 #ifdef CONFIG_RELOCATABLE
-	bl	__relocate_kernel
+	mov	x0, x23
+	bl	__pi_relocate_kernel
 #endif
 	ldr	x8, =__primary_switched
 	adrp	x0, KERNEL_START		// __pa(KERNEL_START)
diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile
index 2bbe866417d4..d084c1dcf416 100644
--- a/arch/arm64/kernel/pi/Makefile
+++ b/arch/arm64/kernel/pi/Makefile
@@ -38,5 +38,6 @@ $(obj)/lib-%.pi.o: OBJCOPYFLAGS += --prefix-alloc-sections=.init
 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
-obj-y		:= kaslr_early.pi.o lib-fdt.pi.o lib-fdt_ro.pi.o
-extra-y		:= $(patsubst %.pi.o,%.o,$(obj-y))
+obj-y				:= relocate.pi.o
+obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr_early.pi.o lib-fdt.pi.o lib-fdt_ro.pi.o
+extra-y				:= $(patsubst %.pi.o,%.o,$(obj-y))
diff --git a/arch/arm64/kernel/pi/relocate.c b/arch/arm64/kernel/pi/relocate.c
new file mode 100644
index 000000000000..1853408ea76b
--- /dev/null
+++ b/arch/arm64/kernel/pi/relocate.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2023 Google LLC
+// Authors: Ard Biesheuvel <ardb at google.com>
+//          Peter Collingbourne <pcc at google.com>
+
+#include <linux/elf.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+extern const Elf64_Rela rela_start[], rela_end[];
+extern const u64 relr_start[], relr_end[];
+
+void __init relocate_kernel(u64 offset)
+{
+	u64 *place = NULL;
+
+	for (const Elf64_Rela *rela = rela_start; rela < rela_end; rela++) {
+		if (ELF64_R_TYPE(rela->r_info) != R_AARCH64_RELATIVE)
+			continue;
+		*(u64 *)(rela->r_offset + offset) = rela->r_addend + offset;
+	}
+
+	if (!IS_ENABLED(CONFIG_RELR) || !offset)
+		return;
+
+	/*
+	 * Apply RELR relocations.
+	 *
+	 * RELR is a compressed format for storing relative relocations. The
+	 * encoded sequence of entries looks like:
+	 * [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
+	 *
+	 * i.e. start with an address, followed by any number of bitmaps. The
+	 * address entry encodes 1 relocation. The subsequent bitmap entries
+	 * encode up to 63 relocations each, at subsequent offsets following
+	 * the last address entry.
+	 *
+	 * The bitmap entries must have 1 in the least significant bit. The
+	 * assumption here is that an address cannot have 1 in lsb. Odd
+	 * addresses are not supported. Any odd addresses are stored in the
+	 * RELA section, which is handled above.
+	 *
+	 * With the exception of the least significant bit, each bit in the
+	 * bitmap corresponds with a machine word that follows the base address
+	 * word, and the bit value indicates whether or not a relocation needs
+	 * to be applied to it. The second least significant bit represents the
+	 * machine word immediately following the initial address, and each bit
+	 * that follows represents the next word, in linear order. As such, a
+	 * single bitmap can encode up to 63 relocations in a 64-bit object.
+	 */
+	for (const u64 *relr = relr_start; relr < relr_end; relr++) {
+		if ((*relr & 1) == 0) {
+			place = (u64 *)(*relr + offset);
+			*place++ += offset;
+		} else {
+			for (u64 *p = place, r = *relr >> 1; r; p++, r >>= 1)
+				if (r & 1)
+					*p += offset;
+			place += 63;
+		}
+	}
+}
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 3cd7e76cc562..8dd5dda66f7c 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -270,15 +270,15 @@ SECTIONS
 	HYPERVISOR_RELOC_SECTION
 
 	.rela.dyn : ALIGN(8) {
-		__rela_start = .;
+		__pi_rela_start = .;
 		*(.rela .rela*)
-		__rela_end = .;
+		__pi_rela_end = .;
 	}
 
 	.relr.dyn : ALIGN(8) {
-		__relr_start = .;
+		__pi_relr_start = .;
 		*(.relr.dyn)
-		__relr_end = .;
+		__pi_relr_end = .;
 	}
 
 	. = ALIGN(SEGMENT_ALIGN);
@@ -317,6 +317,10 @@ SECTIONS
 	init_pg_dir = .;
 	. += INIT_DIR_SIZE;
 	init_pg_end = .;
+#ifdef CONFIG_RELOCATABLE
+	. += SZ_4K;		/* stack for the early relocation code */
+	early_init_stack = .;
+#endif
 
 	. = ALIGN(SEGMENT_ALIGN);
 	__pecoff_data_size = ABSOLUTE(. - __initdata_begin);
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:48 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:48 +0100
Subject: [PATCH v8 02/43] arm64: kernel: Don't rely on objcopy to make code
 under pi/ __init
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-47-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

We will add some code under pi/ that contains global variables that
should not end up in __initdata, as they will not be writable via the
initial ID map. So only rely on objcopy for making the libfdt code
__init, and use explicit annotations for the rest.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/pi/Makefile      |  6 ++++--
 arch/arm64/kernel/pi/kaslr_early.c | 16 +++++++++-------
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile
index bc32a431fe35..2bbe866417d4 100644
--- a/arch/arm64/kernel/pi/Makefile
+++ b/arch/arm64/kernel/pi/Makefile
@@ -28,11 +28,13 @@ quiet_cmd_piobjcopy = $(quiet_cmd_objcopy)
       cmd_piobjcopy = $(cmd_objcopy) && $(obj)/relacheck $(@) $(<)
 
 $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
-			       --remove-section=.note.gnu.property \
-			       --prefix-alloc-sections=.init
+			       --remove-section=.note.gnu.property
 $(obj)/%.pi.o: $(obj)/%.o $(obj)/relacheck FORCE
 	$(call if_changed,piobjcopy)
 
+# ensure that all the lib- code ends up as __init code and data
+$(obj)/lib-%.pi.o: OBJCOPYFLAGS += --prefix-alloc-sections=.init
+
 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
diff --git a/arch/arm64/kernel/pi/kaslr_early.c b/arch/arm64/kernel/pi/kaslr_early.c
index b9e0bb4bc6a9..167081b30a15 100644
--- a/arch/arm64/kernel/pi/kaslr_early.c
+++ b/arch/arm64/kernel/pi/kaslr_early.c
@@ -17,7 +17,7 @@
 #include <asm/pgtable.h>
 
 /* taken from lib/string.c */
-static char *__strstr(const char *s1, const char *s2)
+static char *__init __strstr(const char *s1, const char *s2)
 {
 	size_t l1, l2;
 
@@ -33,7 +33,7 @@ static char *__strstr(const char *s1, const char *s2)
 	}
 	return NULL;
 }
-static bool cmdline_contains_nokaslr(const u8 *cmdline)
+static bool __init cmdline_contains_nokaslr(const u8 *cmdline)
 {
 	const u8 *str;
 
@@ -41,7 +41,7 @@ static bool cmdline_contains_nokaslr(const u8 *cmdline)
 	return str == cmdline || (str > cmdline && *(str - 1) == ' ');
 }
 
-static bool is_kaslr_disabled_cmdline(void *fdt)
+static bool __init is_kaslr_disabled_cmdline(void *fdt)
 {
 	if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
 		int node;
@@ -67,17 +67,19 @@ static bool is_kaslr_disabled_cmdline(void *fdt)
 	return cmdline_contains_nokaslr(CONFIG_CMDLINE);
 }
 
-static u64 get_kaslr_seed(void *fdt)
+static u64 __init get_kaslr_seed(void *fdt)
 {
+	static char const chosen_str[] __initconst = "chosen";
+	static char const seed_str[] __initconst = "kaslr-seed";
 	int node, len;
 	fdt64_t *prop;
 	u64 ret;
 
-	node = fdt_path_offset(fdt, "/chosen");
+	node = fdt_path_offset(fdt, chosen_str);
 	if (node < 0)
 		return 0;
 
-	prop = fdt_getprop_w(fdt, node, "kaslr-seed", &len);
+	prop = fdt_getprop_w(fdt, node, seed_str, &len);
 	if (!prop || len != sizeof(u64))
 		return 0;
 
@@ -86,7 +88,7 @@ static u64 get_kaslr_seed(void *fdt)
 	return ret;
 }
 
-asmlinkage u64 kaslr_early_init(void *fdt)
+asmlinkage u64 __init kaslr_early_init(void *fdt)
 {
 	u64 seed, range;
 
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:51 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:51 +0100
Subject: [PATCH v8 05/43] arm64: kernel: Remove early fdt remap code
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-50-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The early FDT remap code is no longer used so let's drop it.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/setup.h |  3 ---
 arch/arm64/kernel/setup.c      | 15 ---------------
 2 files changed, 18 deletions(-)

diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
index 2e4d7da74fb8..ba269a7a3201 100644
--- a/arch/arm64/include/asm/setup.h
+++ b/arch/arm64/include/asm/setup.h
@@ -7,9 +7,6 @@
 
 #include <uapi/asm/setup.h>
 
-void *get_early_fdt_ptr(void);
-void early_fdt_map(u64 dt_phys);
-
 /*
  * These two variables are used in the head.S file.
  */
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 42c690bb2d60..97d2143669cf 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -166,21 +166,6 @@ static void __init smp_build_mpidr_hash(void)
 		pr_warn("Large number of MPIDR hash buckets detected\n");
 }
 
-static void *early_fdt_ptr __initdata;
-
-void __init *get_early_fdt_ptr(void)
-{
-	return early_fdt_ptr;
-}
-
-asmlinkage void __init early_fdt_map(u64 dt_phys)
-{
-	int fdt_size;
-
-	early_fixmap_init();
-	early_fdt_ptr = fixmap_remap_fdt(dt_phys, &fdt_size, PAGE_KERNEL);
-}
-
 static void __init setup_machine_fdt(phys_addr_t dt_phys)
 {
 	int size;
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:50 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:50 +0100
Subject: [PATCH v8 04/43] arm64: idreg-override: Move to early mini C runtime
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-49-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

We will want to parse the ID register overrides even earlier, so that we
can take them into account before creating the kernel mapping. So
migrate the code and make it work in the context of the early C runtime.
We will move the invocation to an earlier stage in a subsequent patch.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/Makefile                  |  4 +--
 arch/arm64/kernel/head.S                    |  5 ++-
 arch/arm64/kernel/image-vars.h              |  9 +++++
 arch/arm64/kernel/pi/Makefile               |  5 +--
 arch/arm64/kernel/{ => pi}/idreg-override.c | 35 +++++++++-----------
 5 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 78f14084f6d7..4236f1e0fffa 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -33,8 +33,7 @@ obj-y			:= debug-monitors.o entry.o irq.o fpsimd.o		\
 			   return_address.o cpuinfo.o cpu_errata.o		\
 			   cpufeature.o alternative.o cacheinfo.o		\
 			   smp.o smp_spin_table.o topology.o smccc-call.o	\
-			   syscall.o proton-pack.o idreg-override.o idle.o	\
-			   patching.o
+			   syscall.o proton-pack.o idle.o patching.o pi/
 
 obj-$(CONFIG_COMPAT)			+= sys32.o signal32.o			\
 					   sys_compat.o
@@ -57,7 +56,6 @@ obj-$(CONFIG_ACPI)			+= acpi.o
 obj-$(CONFIG_ACPI_NUMA)			+= acpi_numa.o
 obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)	+= acpi_parking_protocol.o
 obj-$(CONFIG_PARAVIRT)			+= paravirt.o
-obj-$(CONFIG_RELOCATABLE)		+= pi/
 obj-$(CONFIG_RANDOMIZE_BASE)		+= kaslr.o
 obj-$(CONFIG_HIBERNATION)		+= hibernate.o hibernate-asm.o
 obj-$(CONFIG_ELF_CORE)			+= elfcore.o
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index a8fa64fc30d7..ca5e5fbefcd3 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -510,10 +510,9 @@ 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
 	mov	x0, x20				// pass the full boot status
-	bl	init_feature_override		// Parse cpu feature overrides
+	mov	x1, x22				// pass the low FDT mapping
+	bl	__pi_init_feature_override	// Parse cpu feature overrides
 #ifdef CONFIG_UNWIND_PATCH_PAC_INTO_SCS
 	bl	scs_patch_vmlinux
 #endif
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index e931ce078a00..eacc3d167733 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -37,6 +37,15 @@ PROVIDE(__pi___memmove			= __pi_memmove);
 PROVIDE(__pi___memset			= __pi_memset);
 
 PROVIDE(__pi_vabits_actual		= vabits_actual);
+PROVIDE(__pi_id_aa64isar1_override	= id_aa64isar1_override);
+PROVIDE(__pi_id_aa64isar2_override	= id_aa64isar2_override);
+PROVIDE(__pi_id_aa64mmfr1_override	= id_aa64mmfr1_override);
+PROVIDE(__pi_id_aa64pfr0_override	= id_aa64pfr0_override);
+PROVIDE(__pi_id_aa64pfr1_override	= id_aa64pfr1_override);
+PROVIDE(__pi_id_aa64smfr0_override	= id_aa64smfr0_override);
+PROVIDE(__pi_id_aa64zfr0_override	= id_aa64zfr0_override);
+PROVIDE(__pi_arm64_sw_feature_override	= arm64_sw_feature_override);
+PROVIDE(__pi__ctype			= _ctype);
 
 #ifdef CONFIG_KVM
 
diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile
index d084c1dcf416..7f6dfce893c3 100644
--- a/arch/arm64/kernel/pi/Makefile
+++ b/arch/arm64/kernel/pi/Makefile
@@ -38,6 +38,7 @@ $(obj)/lib-%.pi.o: OBJCOPYFLAGS += --prefix-alloc-sections=.init
 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
-obj-y				:= relocate.pi.o
-obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr_early.pi.o lib-fdt.pi.o lib-fdt_ro.pi.o
+obj-y				:= idreg-override.pi.o lib-fdt.pi.o lib-fdt_ro.pi.o
+obj-$(CONFIG_RELOCATABLE)	+= relocate.pi.o
+obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr_early.pi.o
 extra-y				:= $(patsubst %.pi.o,%.o,$(obj-y))
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
similarity index 93%
rename from arch/arm64/kernel/idreg-override.c
rename to arch/arm64/kernel/pi/idreg-override.c
index e30fd9e32ef3..f9e05c10faab 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -14,6 +14,8 @@
 #include <asm/cpufeature.h>
 #include <asm/setup.h>
 
+#include "pi.h"
+
 #define FTR_DESC_NAME_LEN	20
 #define FTR_DESC_FIELD_LEN	10
 #define FTR_ALIAS_NAME_LEN	30
@@ -21,15 +23,6 @@
 
 static u64 __boot_status __initdata;
 
-// temporary __prel64 related definitions
-// to be removed when this code is moved under pi/
-
-#define __prel64_initconst	__initconst
-
-#define PREL64(type, name)	union { type *name; }
-
-#define prel64_pointer(__d)	(__d)
-
 typedef bool filter_t(u64 val);
 
 struct ftr_set_desc {
@@ -313,16 +306,11 @@ static __init void __parse_cmdline(const char *cmdline, bool parse_aliases)
 	} while (1);
 }
 
-static __init const u8 *get_bootargs_cmdline(void)
+static __init const u8 *get_bootargs_cmdline(const void *fdt)
 {
 	const u8 *prop;
-	void *fdt;
 	int node;
 
-	fdt = get_early_fdt_ptr();
-	if (!fdt)
-		return NULL;
-
 	node = fdt_path_offset(fdt, "/chosen");
 	if (node < 0)
 		return NULL;
@@ -334,9 +322,9 @@ static __init const u8 *get_bootargs_cmdline(void)
 	return strlen(prop) ? prop : NULL;
 }
 
-static __init void parse_cmdline(void)
+static __init void parse_cmdline(const void *fdt)
 {
-	const u8 *prop = get_bootargs_cmdline();
+	const u8 *prop = get_bootargs_cmdline(fdt);
 
 	if (IS_ENABLED(CONFIG_CMDLINE_FORCE) || !prop)
 		__parse_cmdline(CONFIG_CMDLINE, true);
@@ -346,9 +334,9 @@ static __init void parse_cmdline(void)
 }
 
 /* Keep checkers quiet */
-void init_feature_override(u64 boot_status);
+void init_feature_override(u64 boot_status, const void *fdt);
 
-asmlinkage void __init init_feature_override(u64 boot_status)
+asmlinkage void __init init_feature_override(u64 boot_status, const void *fdt)
 {
 	struct arm64_ftr_override *override;
 	const struct ftr_set_desc *reg;
@@ -364,7 +352,7 @@ asmlinkage void __init init_feature_override(u64 boot_status)
 
 	__boot_status = boot_status;
 
-	parse_cmdline();
+	parse_cmdline(fdt);
 
 	for (i = 0; i < ARRAY_SIZE(regs); i++) {
 		reg = prel64_pointer(regs[i].reg);
@@ -373,3 +361,10 @@ asmlinkage void __init init_feature_override(u64 boot_status)
 				       (unsigned long)(override + 1));
 	}
 }
+
+char * __init skip_spaces(const char *str)
+{
+	while (isspace(*str))
+		++str;
+	return (char *)str;
+}
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:52 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:52 +0100
Subject: [PATCH v8 06/43] arm64: head: Clear BSS and the kernel page tables in
 one go
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-51-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

We will move the CPU feature overrides into BSS in a subsequent patch,
and this requires that BSS is zeroed before the feature override
detection code runs. So let's map BSS read-write in the ID map, and zero
it via this mapping.

Since the kernel page tables are right next to it, and also zeroed via
the ID map, let's drop the separate clear_page_tables() function, and
just zero everything in one go.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/head.S        | 33 +++++++-------------
 arch/arm64/kernel/vmlinux.lds.S |  3 ++
 2 files changed, 14 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index ca5e5fbefcd3..2af518161f3a 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -177,17 +177,6 @@ SYM_CODE_START_LOCAL(preserve_boot_args)
 	ret
 SYM_CODE_END(preserve_boot_args)
 
-SYM_FUNC_START_LOCAL(clear_page_tables)
-	/*
-	 * Clear the init page tables.
-	 */
-	adrp	x0, init_pg_dir
-	adrp	x1, init_pg_end
-	sub	x2, x1, x0
-	mov	x1, xzr
-	b	__pi_memset			// tail call
-SYM_FUNC_END(clear_page_tables)
-
 /*
  * Macro to populate page table entries, these entries can be pointers to the next level
  * or last level entries pointing to physical memory.
@@ -386,9 +375,9 @@ SYM_FUNC_START_LOCAL(create_idmap)
 
 	map_memory x0, x1, x3, x6, x7, x3, IDMAP_PGD_ORDER, x10, x11, x12, x13, x14, EXTRA_SHIFT
 
-	/* Remap the kernel page tables r/w in the ID map */
+	/* Remap BSS and the kernel page tables r/w in the ID map */
 	adrp	x1, _text
-	adrp	x2, init_pg_dir
+	adrp	x2, __bss_start
 	adrp	x3, _end
 	bic	x4, x2, #SWAPPER_BLOCK_SIZE - 1
 	mov_q	x5, SWAPPER_RW_MMUFLAGS
@@ -489,14 +478,6 @@ SYM_FUNC_START_LOCAL(__primary_switched)
 	mov	x0, x20
 	bl	set_cpu_boot_mode_flag
 
-	// Clear BSS
-	adr_l	x0, __bss_start
-	mov	x1, xzr
-	adr_l	x2, __bss_stop
-	sub	x2, x2, x0
-	bl	__pi_memset
-	dsb	ishst				// Make zero page visible to PTW
-
 #if VA_BITS > 48
 	adr_l	x8, vabits_actual		// Set this early so KASAN early init
 	str	x25, [x8]			// ... observes the correct value
@@ -782,6 +763,15 @@ SYM_FUNC_START_LOCAL(__primary_switch)
 	adrp	x1, reserved_pg_dir
 	adrp	x2, init_idmap_pg_dir
 	bl	__enable_mmu
+
+	// Clear BSS
+	adrp	x0, __bss_start
+	mov	x1, xzr
+	adrp	x2, init_pg_end
+	sub	x2, x2, x0
+	bl	__pi_memset
+	dsb	ishst				// Make zero page visible to PTW
+
 #ifdef CONFIG_RELOCATABLE
 	adrp	x23, KERNEL_START
 	and	x23, x23, MIN_KIMG_ALIGN - 1
@@ -796,7 +786,6 @@ SYM_FUNC_START_LOCAL(__primary_switch)
 	orr	x23, x23, x0			// record kernel offset
 #endif
 #endif
-	bl	clear_page_tables
 	bl	create_kernel_mapping
 
 	adrp	x1, init_pg_dir
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 8dd5dda66f7c..8a3c6aacc355 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -311,12 +311,15 @@ SECTIONS
 	__pecoff_data_rawsize = ABSOLUTE(. - __initdata_begin);
 	_edata = .;
 
+	/* start of zero-init region */
 	BSS_SECTION(SBSS_ALIGN, 0, 0)
 
 	. = ALIGN(PAGE_SIZE);
 	init_pg_dir = .;
 	. += INIT_DIR_SIZE;
 	init_pg_end = .;
+	/* end of zero-init region */
+
 #ifdef CONFIG_RELOCATABLE
 	. += SZ_4K;		/* stack for the early relocation code */
 	early_init_stack = .;
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:54 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:54 +0100
Subject: [PATCH v8 08/43] arm64: head: Run feature override detection before
 mapping the kernel
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-53-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

To permit the feature overrides to be taken into account before the
KASLR init code runs and the kernel mapping is created, move the
detection code to an earlier stage in the boot.

In a subsequent patch, this will be taken advantage of by merging the
preliminary and permanent mappings of the kernel text and data into a
single one that gets created and relocated before start_kernel() is
called.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/head.S        | 17 +++++++++--------
 arch/arm64/kernel/vmlinux.lds.S |  4 +---
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 2af518161f3a..865ecc1f8255 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -375,9 +375,9 @@ SYM_FUNC_START_LOCAL(create_idmap)
 
 	map_memory x0, x1, x3, x6, x7, x3, IDMAP_PGD_ORDER, x10, x11, x12, x13, x14, EXTRA_SHIFT
 
-	/* Remap BSS and the kernel page tables r/w in the ID map */
+	/* Remap [.init].data, BSS and the kernel page tables r/w in the ID map */
 	adrp	x1, _text
-	adrp	x2, __bss_start
+	adrp	x2, __initdata_begin
 	adrp	x3, _end
 	bic	x4, x2, #SWAPPER_BLOCK_SIZE - 1
 	mov_q	x5, SWAPPER_RW_MMUFLAGS
@@ -491,9 +491,6 @@ SYM_FUNC_START_LOCAL(__primary_switched)
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 	bl	kasan_early_init
 #endif
-	mov	x0, x20				// pass the full boot status
-	mov	x1, x22				// pass the low FDT mapping
-	bl	__pi_init_feature_override	// Parse cpu feature overrides
 #ifdef CONFIG_UNWIND_PATCH_PAC_INTO_SCS
 	bl	scs_patch_vmlinux
 #endif
@@ -772,12 +769,16 @@ SYM_FUNC_START_LOCAL(__primary_switch)
 	bl	__pi_memset
 	dsb	ishst				// Make zero page visible to PTW
 
-#ifdef CONFIG_RELOCATABLE
-	adrp	x23, KERNEL_START
-	and	x23, x23, MIN_KIMG_ALIGN - 1
 	adrp	x1, early_init_stack
 	mov	sp, x1
 	mov	x29, xzr
+	mov	x0, x20				// pass the full boot status
+	mov	x1, x22				// pass the low FDT mapping
+	bl	__pi_init_feature_override	// Parse cpu feature overrides
+
+#ifdef CONFIG_RELOCATABLE
+	adrp	x23, KERNEL_START
+	and	x23, x23, MIN_KIMG_ALIGN - 1
 #ifdef CONFIG_RANDOMIZE_BASE
 	mov	x0, x22
 	bl	__pi_kaslr_early_init
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 8a3c6aacc355..3afb4223a5e8 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -320,10 +320,8 @@ SECTIONS
 	init_pg_end = .;
 	/* end of zero-init region */
 
-#ifdef CONFIG_RELOCATABLE
-	. += SZ_4K;		/* stack for the early relocation code */
+	. += SZ_4K;		/* stack for the early C runtime */
 	early_init_stack = .;
-#endif
 
 	. = ALIGN(SEGMENT_ALIGN);
 	__pecoff_data_size = ABSOLUTE(. - __initdata_begin);
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:53 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:53 +0100
Subject: [PATCH v8 07/43] arm64: Move feature overrides into the BSS section
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-52-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

In order to allow the CPU feature override detection code to run even
earlier, move the feature override global variables into BSS, which is
the only part of the static kernel image that is mapped read-write in
the initial ID map.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 8d1a634a403e..a99ad79adee2 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -655,13 +655,13 @@ static const struct arm64_ftr_bits ftr_raz[] = {
 #define ARM64_FTR_REG(id, table)		\
 	__ARM64_FTR_REG_OVERRIDE(#id, id, table, &no_override)
 
-struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
-struct arm64_ftr_override __ro_after_init id_aa64pfr0_override;
-struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
-struct arm64_ftr_override __ro_after_init id_aa64zfr0_override;
-struct arm64_ftr_override __ro_after_init id_aa64smfr0_override;
-struct arm64_ftr_override __ro_after_init id_aa64isar1_override;
-struct arm64_ftr_override __ro_after_init id_aa64isar2_override;
+struct arm64_ftr_override id_aa64mmfr1_override;
+struct arm64_ftr_override id_aa64pfr0_override;
+struct arm64_ftr_override id_aa64pfr1_override;
+struct arm64_ftr_override id_aa64zfr0_override;
+struct arm64_ftr_override id_aa64smfr0_override;
+struct arm64_ftr_override id_aa64isar1_override;
+struct arm64_ftr_override id_aa64isar2_override;
 
 struct arm64_ftr_override arm64_sw_feature_override;
 
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:55 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:55 +0100
Subject: [PATCH v8 09/43] arm64: head: move dynamic shadow call stack patching
 into early C runtime
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-54-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Once we update the early kernel mapping code to only map the kernel once
with the right permissions, we can no longer perform code patching via
this mapping.

So move this code to an earlier stage of the boot, right after applying
the relocations.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/scs.h           |  4 +--
 arch/arm64/kernel/Makefile             |  8 ------
 arch/arm64/kernel/head.S               |  8 +++---
 arch/arm64/kernel/module.c             |  2 +-
 arch/arm64/kernel/pi/Makefile          | 10 +++++---
 arch/arm64/kernel/{ => pi}/patch-scs.c | 26 ++++++++++----------
 6 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/arch/arm64/include/asm/scs.h b/arch/arm64/include/asm/scs.h
index 3fdae5fe3142..eca2ba5a6276 100644
--- a/arch/arm64/include/asm/scs.h
+++ b/arch/arm64/include/asm/scs.h
@@ -72,8 +72,8 @@ static inline void dynamic_scs_init(void)
 static inline void dynamic_scs_init(void) {}
 #endif
 
-int scs_patch(const u8 eh_frame[], int size);
-asmlinkage void scs_patch_vmlinux(void);
+int __pi_scs_patch(const u8 eh_frame[], int size);
+asmlinkage void __pi_scs_patch_vmlinux(void);
 
 #endif /* __ASSEMBLY __ */
 
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 4236f1e0fffa..14b4a179bad3 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -71,14 +71,6 @@ 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_UNWIND_PATCH_PAC_INTO_SCS)	+= patch-scs.o
-
-# We need to prevent the SCS patching code from patching itself. Using
-# -mbranch-protection=none here to avoid the patchable PAC opcodes from being
-# generated triggers an issue with full LTO on Clang, which stops emitting PAC
-# instructions altogether. So disable LTO as well for the compilation unit.
-CFLAGS_patch-scs.o			+= -mbranch-protection=none
-CFLAGS_REMOVE_patch-scs.o		+= $(CC_FLAGS_LTO)
 
 # Force dependency (vdso*-wrap.S includes vdso.so through incbin)
 $(obj)/vdso-wrap.o: $(obj)/vdso/vdso.so
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 865ecc1f8255..b320702032a7 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -490,9 +490,6 @@ SYM_FUNC_START_LOCAL(__primary_switched)
 #endif
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 	bl	kasan_early_init
-#endif
-#ifdef CONFIG_UNWIND_PATCH_PAC_INTO_SCS
-	bl	scs_patch_vmlinux
 #endif
 	mov	x0, x20
 	bl	finalise_el2			// Prefer VHE if possible
@@ -794,6 +791,11 @@ SYM_FUNC_START_LOCAL(__primary_switch)
 #ifdef CONFIG_RELOCATABLE
 	mov	x0, x23
 	bl	__pi_relocate_kernel
+#endif
+#ifdef CONFIG_UNWIND_PATCH_PAC_INTO_SCS
+	ldr	x0, =__eh_frame_start
+	ldr	x1, =__eh_frame_end
+	bl	__pi_scs_patch_vmlinux
 #endif
 	ldr	x8, =__primary_switched
 	adrp	x0, KERNEL_START		// __pa(KERNEL_START)
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index dd851297596e..47e0be610bb6 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -595,7 +595,7 @@ int module_finalize(const Elf_Ehdr *hdr,
 	if (scs_is_dynamic()) {
 		s = find_section(hdr, sechdrs, ".init.eh_frame");
 		if (s)
-			scs_patch((void *)s->sh_addr, s->sh_size);
+			__pi_scs_patch((void *)s->sh_addr, s->sh_size);
 	}
 
 	return module_init_ftrace_plt(hdr, sechdrs, me);
diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile
index 7f6dfce893c3..a8b302245f15 100644
--- a/arch/arm64/kernel/pi/Makefile
+++ b/arch/arm64/kernel/pi/Makefile
@@ -38,7 +38,9 @@ $(obj)/lib-%.pi.o: OBJCOPYFLAGS += --prefix-alloc-sections=.init
 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
-obj-y				:= idreg-override.pi.o lib-fdt.pi.o lib-fdt_ro.pi.o
-obj-$(CONFIG_RELOCATABLE)	+= relocate.pi.o
-obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr_early.pi.o
-extra-y				:= $(patsubst %.pi.o,%.o,$(obj-y))
+obj-y					:= idreg-override.pi.o \
+					   lib-fdt.pi.o lib-fdt_ro.pi.o
+obj-$(CONFIG_RELOCATABLE)		+= relocate.pi.o
+obj-$(CONFIG_RANDOMIZE_BASE)		+= kaslr_early.pi.o
+obj-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS)	+= patch-scs.pi.o
+extra-y					:= $(patsubst %.pi.o,%.o,$(obj-y))
diff --git a/arch/arm64/kernel/patch-scs.c b/arch/arm64/kernel/pi/patch-scs.c
similarity index 91%
rename from arch/arm64/kernel/patch-scs.c
rename to arch/arm64/kernel/pi/patch-scs.c
index a1fe4b4ff591..c65ef40d1e6b 100644
--- a/arch/arm64/kernel/patch-scs.c
+++ b/arch/arm64/kernel/pi/patch-scs.c
@@ -4,14 +4,11 @@
  * Author: Ard Biesheuvel <ardb at google.com>
  */
 
-#include <linux/bug.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/linkage.h>
-#include <linux/printk.h>
 #include <linux/types.h>
 
-#include <asm/cacheflush.h>
 #include <asm/scs.h>
 
 //
@@ -81,7 +78,11 @@ static void __always_inline scs_patch_loc(u64 loc)
 		 */
 		return;
 	}
-	dcache_clean_pou(loc, loc + sizeof(u32));
+	if (IS_ENABLED(CONFIG_ARM64_WORKAROUND_CLEAN_CACHE))
+		asm("dc civac, %0" :: "r"(loc));
+	else
+		asm(ALTERNATIVE("dc cvau, %0", "nop", ARM64_HAS_CACHE_IDC)
+		    :: "r"(loc));
 }
 
 /*
@@ -128,10 +129,10 @@ struct eh_frame {
 	};
 };
 
-static int noinstr scs_handle_fde_frame(const struct eh_frame *frame,
-					bool fde_has_augmentation_data,
-					int code_alignment_factor,
-					bool dry_run)
+static int scs_handle_fde_frame(const struct eh_frame *frame,
+				bool fde_has_augmentation_data,
+				int code_alignment_factor,
+				bool dry_run)
 {
 	int size = frame->size - offsetof(struct eh_frame, opcodes) + 4;
 	u64 loc = (u64)offset_to_ptr(&frame->initial_loc);
@@ -198,14 +199,13 @@ static int noinstr scs_handle_fde_frame(const struct eh_frame *frame,
 			break;
 
 		default:
-			pr_err("unhandled opcode: %02x in FDE frame %lx\n", opcode[-1], (uintptr_t)frame);
 			return -ENOEXEC;
 		}
 	}
 	return 0;
 }
 
-int noinstr scs_patch(const u8 eh_frame[], int size)
+int scs_patch(const u8 eh_frame[], int size)
 {
 	const u8 *p = eh_frame;
 
@@ -251,12 +251,12 @@ int noinstr scs_patch(const u8 eh_frame[], int size)
 	return 0;
 }
 
-asmlinkage void __init scs_patch_vmlinux(void)
+asmlinkage void __init scs_patch_vmlinux(const u8 start[], const u8 end[])
 {
 	if (!should_patch_pac_into_scs())
 		return;
 
-	WARN_ON(scs_patch(__eh_frame_start, __eh_frame_end - __eh_frame_start));
-	icache_inval_all_pou();
+	scs_patch(start, end - start);
+	asm("ic ialluis");
 	isb();
 }
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:56 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:56 +0100
Subject: [PATCH v8 10/43] arm64: cpufeature: Add helper to test for CPU
 feature overrides
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-55-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Add some helpers to extract and apply feature overrides to the bare
idreg values. This involves inspecting the value and mask of the
specific field that we are interested in, given that an override
value/mask pair might be invalid for one field but valid for another.

Then, wire up the new helper for the hVHE test - note that we can drop
the sysreg test here, as the override will be invalid when trying to
enable hVHE on non-VHE capable hardware.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/cpufeature.h | 39 ++++++++++++++++++++
 arch/arm64/kernel/cpufeature.c      |  9 +----
 2 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 21c824edf8ce..acd8f4949583 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -915,6 +915,45 @@ extern struct arm64_ftr_override id_aa64isar2_override;
 
 extern struct arm64_ftr_override arm64_sw_feature_override;
 
+static inline
+u64 arm64_apply_feature_override(u64 val, int feat, int width,
+				 const struct arm64_ftr_override *override)
+{
+	u64 oval = override->val;
+
+	/*
+	 * When it encounters an invalid override (e.g., an override that
+	 * cannot be honoured due to a missing CPU feature), the early idreg
+	 * override code will set the mask to 0x0 and the value to non-zero for
+	 * the field in question. In order to determine whether the override is
+	 * valid or not for the field we are interested in, we first need to
+	 * disregard bits belonging to other fields.
+	 */
+	oval &= GENMASK_ULL(feat + width - 1, feat);
+
+	/*
+	 * The override is valid if all value bits are accounted for in the
+	 * mask. If so, replace the masked bits with the override value.
+	 */
+	if (oval == (oval & override->mask)) {
+		val &= ~override->mask;
+		val |= oval;
+	}
+
+	/* Extract the field from the updated value */
+	return cpuid_feature_extract_unsigned_field(val, feat);
+}
+
+static inline bool arm64_test_sw_feature_override(int feat)
+{
+	/*
+	 * Software features are pseudo CPU features that have no underlying
+	 * CPUID system register value to apply the override to.
+	 */
+	return arm64_apply_feature_override(0, feat, 4,
+					    &arm64_sw_feature_override);
+}
+
 u32 get_kvm_ipa_limit(void);
 void dump_cpu_features(void);
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a99ad79adee2..d0ffb872a31a 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2042,14 +2042,7 @@ static bool has_nested_virt_support(const struct arm64_cpu_capabilities *cap,
 static bool hvhe_possible(const struct arm64_cpu_capabilities *entry,
 			  int __unused)
 {
-	u64 val;
-
-	val = read_sysreg(id_aa64mmfr1_el1);
-	if (!cpuid_feature_extract_unsigned_field(val, ID_AA64MMFR1_EL1_VH_SHIFT))
-		return false;
-
-	val = arm64_sw_feature_override.val & arm64_sw_feature_override.mask;
-	return cpuid_feature_extract_unsigned_field(val, ARM64_SW_FEATURE_OVERRIDE_HVHE);
+	return arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_HVHE);
 }
 
 #ifdef CONFIG_ARM64_PAN
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:57 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:57 +0100
Subject: [PATCH v8 11/43] arm64: kaslr: Use feature override instead of
 parsing the cmdline again
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-56-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The early kaslr code open codes the detection of 'nokaslr' on the kernel
command line, and this is no longer necessary now that the feature
detection code, which also looks for the same string, executes before
this code.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/cpufeature.h |  5 ++
 arch/arm64/kernel/kaslr.c           |  4 +-
 arch/arm64/kernel/pi/kaslr_early.c  | 53 +-------------------
 3 files changed, 7 insertions(+), 55 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index acd8f4949583..e309255b7f04 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -954,6 +954,11 @@ static inline bool arm64_test_sw_feature_override(int feat)
 					    &arm64_sw_feature_override);
 }
 
+static inline bool kaslr_disabled_cmdline(void)
+{
+	return arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_NOKASLR);
+}
+
 u32 get_kvm_ipa_limit(void);
 void dump_cpu_features(void);
 
diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index 12c7f3c8ba76..1da3e25f9d9e 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -16,9 +16,7 @@ bool __ro_after_init __kaslr_is_enabled = false;
 
 void __init kaslr_init(void)
 {
-	if (cpuid_feature_extract_unsigned_field(arm64_sw_feature_override.val &
-						 arm64_sw_feature_override.mask,
-						 ARM64_SW_FEATURE_OVERRIDE_NOKASLR)) {
+	if (kaslr_disabled_cmdline()) {
 		pr_info("KASLR disabled on command line\n");
 		return;
 	}
diff --git a/arch/arm64/kernel/pi/kaslr_early.c b/arch/arm64/kernel/pi/kaslr_early.c
index 167081b30a15..f2305e276ec3 100644
--- a/arch/arm64/kernel/pi/kaslr_early.c
+++ b/arch/arm64/kernel/pi/kaslr_early.c
@@ -16,57 +16,6 @@
 #include <asm/memory.h>
 #include <asm/pgtable.h>
 
-/* taken from lib/string.c */
-static char *__init __strstr(const char *s1, const char *s2)
-{
-	size_t l1, l2;
-
-	l2 = strlen(s2);
-	if (!l2)
-		return (char *)s1;
-	l1 = strlen(s1);
-	while (l1 >= l2) {
-		l1--;
-		if (!memcmp(s1, s2, l2))
-			return (char *)s1;
-		s1++;
-	}
-	return NULL;
-}
-static bool __init cmdline_contains_nokaslr(const u8 *cmdline)
-{
-	const u8 *str;
-
-	str = __strstr(cmdline, "nokaslr");
-	return str == cmdline || (str > cmdline && *(str - 1) == ' ');
-}
-
-static bool __init is_kaslr_disabled_cmdline(void *fdt)
-{
-	if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
-		int node;
-		const u8 *prop;
-
-		node = fdt_path_offset(fdt, "/chosen");
-		if (node < 0)
-			goto out;
-
-		prop = fdt_getprop(fdt, node, "bootargs", NULL);
-		if (!prop)
-			goto out;
-
-		if (cmdline_contains_nokaslr(prop))
-			return true;
-
-		if (IS_ENABLED(CONFIG_CMDLINE_EXTEND))
-			goto out;
-
-		return false;
-	}
-out:
-	return cmdline_contains_nokaslr(CONFIG_CMDLINE);
-}
-
 static u64 __init get_kaslr_seed(void *fdt)
 {
 	static char const chosen_str[] __initconst = "chosen";
@@ -92,7 +41,7 @@ asmlinkage u64 __init kaslr_early_init(void *fdt)
 {
 	u64 seed, range;
 
-	if (is_kaslr_disabled_cmdline(fdt))
+	if (kaslr_disabled_cmdline())
 		return 0;
 
 	seed = get_kaslr_seed(fdt);
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:58 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:58 +0100
Subject: [PATCH v8 12/43] arm64: idreg-override: Create a pseudo feature for rodata=off
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-57-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Add rodata=off to the set of kernel command line options that is parsed
early using the CPU feature override detection code, so we can easily
refer to it when creating the kernel mapping.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/cpufeature.h   | 1 +
 arch/arm64/kernel/pi/idreg-override.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index e309255b7f04..03c34242bfc7 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -17,6 +17,7 @@
 
 #define ARM64_SW_FEATURE_OVERRIDE_NOKASLR	0
 #define ARM64_SW_FEATURE_OVERRIDE_HVHE		4
+#define ARM64_SW_FEATURE_OVERRIDE_RODATA_OFF	8
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
index f9e05c10faab..e4bcabcc6860 100644
--- a/arch/arm64/kernel/pi/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -159,6 +159,7 @@ static const struct ftr_set_desc sw_features __prel64_initconst = {
 	.fields		= {
 		FIELD("nokaslr", ARM64_SW_FEATURE_OVERRIDE_NOKASLR, NULL),
 		FIELD("hvhe", ARM64_SW_FEATURE_OVERRIDE_HVHE, hvhe_filter),
+		FIELD("rodataoff", ARM64_SW_FEATURE_OVERRIDE_RODATA_OFF, NULL),
 		{}
 	},
 };
@@ -190,6 +191,7 @@ static const struct {
 	{ "arm64.nomops",		"id_aa64isar2.mops=0" },
 	{ "arm64.nomte",		"id_aa64pfr1.mte=0" },
 	{ "nokaslr",			"arm64_sw.nokaslr=1" },
+	{ "rodata=off",			"arm64_sw.rodataoff=1" },
 };
 
 static int __init parse_hexdigit(const char *p, u64 *v)
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:28:59 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:28:59 +0100
Subject: [PATCH v8 13/43] arm64: Add helpers to probe local CPU for PAC and
 BTI support
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-58-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Add some helpers that will be used by the early kernel mapping code to
check feature support on the local CPU. This permits the early kernel
mapping to be created with the right attributes, removing the need for
tearing it down and recreating it.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/cpufeature.h | 32 ++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 03c34242bfc7..e3edae1825f3 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -963,6 +963,38 @@ static inline bool kaslr_disabled_cmdline(void)
 u32 get_kvm_ipa_limit(void);
 void dump_cpu_features(void);
 
+static inline bool cpu_has_bti(void)
+{
+	if (!IS_ENABLED(CONFIG_ARM64_BTI))
+		return false;
+
+	return arm64_apply_feature_override(read_cpuid(ID_AA64PFR1_EL1),
+					    ID_AA64PFR1_EL1_BT_SHIFT, 4,
+					    &id_aa64pfr1_override);
+}
+
+static inline bool cpu_has_pac(void)
+{
+	u64 isar1, isar2;
+
+	if (!IS_ENABLED(CONFIG_ARM64_PTR_AUTH))
+		return false;
+
+	isar1 = read_cpuid(ID_AA64ISAR1_EL1);
+	isar2 = read_cpuid(ID_AA64ISAR2_EL1);
+
+	if (arm64_apply_feature_override(isar1, ID_AA64ISAR1_EL1_APA_SHIFT, 4,
+					 &id_aa64isar1_override))
+		return true;
+
+	if (arm64_apply_feature_override(isar1, ID_AA64ISAR1_EL1_API_SHIFT, 4,
+					 &id_aa64isar1_override))
+		return true;
+
+	return arm64_apply_feature_override(isar2, ID_AA64ISAR2_EL1_APA3_SHIFT, 4,
+					    &id_aa64isar2_override);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:00 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:00 +0100
Subject: [PATCH v8 14/43] arm64: head: allocate more pages for the kernel mapping
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-59-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

In preparation for switching to an early kernel mapping routine that
maps each segment according to its precise boundaries, and with the
correct attributes, let's allocate some extra pages for page tables for
the 4k page size configuration. This is necessary because the start and
end of each segment may not be aligned to the block size, and so we'll
need an extra page table at each segment boundary.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/kernel-pgtable.h | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 83ddb14b95a5..0631604995ee 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -68,7 +68,7 @@
 			+ EARLY_PGDS((vstart), (vend), add) 	/* each PGDIR needs a next level page table */	\
 			+ EARLY_PUDS((vstart), (vend), add)	/* each PUD needs a next level page table */	\
 			+ EARLY_PMDS((vstart), (vend), add))	/* each PMD needs a next level page table */
-#define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR, _end, EXTRA_PAGE))
+#define INIT_DIR_SIZE (PAGE_SIZE * (EARLY_PAGES(KIMAGE_VADDR, _end, EXTRA_PAGE) + EARLY_SEGMENT_EXTRA_PAGES))
 
 /* the initial ID map may need two extra pages if it needs to be extended */
 #if VA_BITS < 48
@@ -89,6 +89,15 @@
 #define SWAPPER_TABLE_SHIFT	PMD_SHIFT
 #endif
 
+/* The number of segments in the kernel image (text, rodata, inittext, initdata, data+bss) */
+#define KERNEL_SEGMENT_COUNT	5
+
+#if SWAPPER_BLOCK_SIZE > SEGMENT_ALIGN
+#define EARLY_SEGMENT_EXTRA_PAGES (KERNEL_SEGMENT_COUNT + 1)
+#else
+#define EARLY_SEGMENT_EXTRA_PAGES 0
+#endif
+
 /*
  * Initial memory map attributes.
  */
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:05 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:05 +0100
Subject: [PATCH v8 19/43] arm64: mm: Use 48-bit virtual addressing for the
 permanent ID map
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-64-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Even though we support loading kernels anywhere in 48-bit addressable
physical memory, we create the ID maps based on the number of levels
that we happened to configure for the kernel VA and user VA spaces.

The reason for this is that the PGD/PUD/PMD based classification of
translation levels, along with the associated folding when the number of
levels is less than 5, does not permit creating a page table hierarchy
of a set number of levels. This means that, for instance, on 39-bit VA
kernels we need to configure an additional level above PGD level on the
fly, and 36-bit VA kernels still only support 47-bit virtual addressing
with this trick applied.

Now that we have a separate helper to populate page table hierarchies
that does not define the levels in terms of PUDS/PMDS/etc at all, let's
reuse it to create the permanent ID map with a fixed VA size of 48 bits.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/kernel-pgtable.h |  3 ++
 arch/arm64/kernel/head.S                |  5 +++
 arch/arm64/kvm/mmu.c                    | 15 +++------
 arch/arm64/mm/mmu.c                     | 32 +++++++++++---------
 arch/arm64/mm/proc.S                    |  9 ++----
 5 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 0631604995ee..742a4b2778f7 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -35,6 +35,9 @@
 #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
 #endif
 
+#define IDMAP_VA_BITS		48
+#define IDMAP_LEVELS		ARM64_HW_PGTABLE_LEVELS(IDMAP_VA_BITS)
+#define IDMAP_ROOT_LEVEL	(4 - IDMAP_LEVELS)
 
 /*
  * A relocatable kernel may execute from an address that differs from the one at
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index ffacce7b5a02..a1c29d64e875 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -729,6 +729,11 @@ SYM_FUNC_START_LOCAL(__no_granule_support)
 SYM_FUNC_END(__no_granule_support)
 
 SYM_FUNC_START_LOCAL(__primary_switch)
+	mrs		x1, tcr_el1
+	mov		x2, #64 - VA_BITS
+	tcr_set_t0sz	x1, x2
+	msr		tcr_el1, x1
+
 	adrp	x1, reserved_pg_dir
 	adrp	x2, init_idmap_pg_dir
 	bl	__enable_mmu
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index d14504821b79..6fa9e816df40 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1874,16 +1874,9 @@ int __init kvm_mmu_init(u32 *hyp_va_bits)
 	BUG_ON((hyp_idmap_start ^ (hyp_idmap_end - 1)) & PAGE_MASK);
 
 	/*
-	 * The ID map may be configured to use an extended virtual address
-	 * range. This is only the case if system RAM is out of range for the
-	 * currently configured page size and VA_BITS_MIN, in which case we will
-	 * also need the extended virtual range for the HYP ID map, or we won't
-	 * be able to enable the EL2 MMU.
-	 *
-	 * However, in some cases the ID map may be configured for fewer than
-	 * the number of VA bits used by the regular kernel stage 1. This
-	 * happens when VA_BITS=52 and the kernel image is placed in PA space
-	 * below 48 bits.
+	 * The ID map is always configured for 48 bits of translation, which
+	 * may be fewer than the number of VA bits used by the regular kernel
+	 * stage 1, when VA_BITS=52.
 	 *
 	 * At EL2, there is only one TTBR register, and we can't switch between
 	 * translation tables *and* update TCR_EL2.T0SZ at the same time. Bottom
@@ -1894,7 +1887,7 @@ int __init kvm_mmu_init(u32 *hyp_va_bits)
 	 * 1 VA bits to assure that the hypervisor can both ID map its code page
 	 * and map any kernel memory.
 	 */
-	idmap_bits = 64 - ((idmap_t0sz & TCR_T0SZ_MASK) >> TCR_T0SZ_OFFSET);
+	idmap_bits = IDMAP_VA_BITS;
 	kernel_bits = vabits_actual;
 	*hyp_va_bits = max(idmap_bits, kernel_bits);
 
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f9332eea318f..a991f195592b 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -757,22 +757,21 @@ static void __init map_kernel(pgd_t *pgdp)
 	kasan_copy_shadow(pgdp);
 }
 
+void __pi_map_range(u64 *pgd, u64 start, u64 end, u64 pa, pgprot_t prot,
+		    int level, pte_t *tbl, bool may_use_cont, u64 va_offset);
+
+static u8 idmap_ptes[IDMAP_LEVELS - 1][PAGE_SIZE] __aligned(PAGE_SIZE) __ro_after_init,
+	  kpti_ptes[IDMAP_LEVELS - 1][PAGE_SIZE] __aligned(PAGE_SIZE) __ro_after_init;
+
 static void __init create_idmap(void)
 {
 	u64 start = __pa_symbol(__idmap_text_start);
-	u64 size = __pa_symbol(__idmap_text_end) - start;
-	pgd_t *pgd = idmap_pg_dir;
-	u64 pgd_phys;
-
-	/* check if we need an additional level of translation */
-	if (VA_BITS < 48 && idmap_t0sz < (64 - VA_BITS_MIN)) {
-		pgd_phys = early_pgtable_alloc(PAGE_SHIFT);
-		set_pgd(&idmap_pg_dir[start >> VA_BITS],
-			__pgd(pgd_phys | P4D_TYPE_TABLE));
-		pgd = __va(pgd_phys);
-	}
-	__create_pgd_mapping(pgd, start, start, size, PAGE_KERNEL_ROX,
-			     early_pgtable_alloc, 0);
+	u64 end   = __pa_symbol(__idmap_text_end);
+	u64 ptep  = __pa_symbol(idmap_ptes);
+
+	__pi_map_range(&ptep, start, end, start, PAGE_KERNEL_ROX,
+		       IDMAP_ROOT_LEVEL, (pte_t *)idmap_pg_dir, false,
+		       __phys_to_virt(ptep) - ptep);
 
 	if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) {
 		extern u32 __idmap_kpti_flag;
@@ -782,8 +781,10 @@ static void __init create_idmap(void)
 		 * The KPTI G-to-nG conversion code needs a read-write mapping
 		 * of its synchronization flag in the ID map.
 		 */
-		__create_pgd_mapping(pgd, pa, pa, sizeof(u32), PAGE_KERNEL,
-				     early_pgtable_alloc, 0);
+		ptep = __pa_symbol(kpti_ptes);
+		__pi_map_range(&ptep, pa, pa + sizeof(u32), pa, PAGE_KERNEL,
+			       IDMAP_ROOT_LEVEL, (pte_t *)idmap_pg_dir, false,
+			       __phys_to_virt(ptep) - ptep);
 	}
 }
 
@@ -808,6 +809,7 @@ void __init paging_init(void)
 	memblock_allow_resize();
 
 	create_idmap();
+	idmap_t0sz = TCR_T0SZ(IDMAP_VA_BITS);
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 7c1bdaf25408..47ede52bb900 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -421,9 +421,9 @@ SYM_FUNC_START(__cpu_setup)
 	mair	.req	x17
 	tcr	.req	x16
 	mov_q	mair, MAIR_EL1_SET
-	mov_q	tcr, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
-			TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
-			TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS
+	mov_q	tcr, TCR_T0SZ(IDMAP_VA_BITS) | TCR_T1SZ(VA_BITS) | TCR_CACHE_FLAGS | \
+		     TCR_SMP_FLAGS | TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
+		     TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS
 
 	tcr_clear_errata_bits tcr, x9, x5
 
@@ -431,10 +431,7 @@ SYM_FUNC_START(__cpu_setup)
 	sub		x9, xzr, x0
 	add		x9, x9, #64
 	tcr_set_t1sz	tcr, x9
-#else
-	idmap_get_t0sz	x9
 #endif
-	tcr_set_t0sz	tcr, x9
 
 	/*
 	 * Set the IPS bits in TCR_EL1.
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:04 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:04 +0100
Subject: [PATCH v8 18/43] arm64: head: Move early kernel mapping routines into
 C code
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-63-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The asm version of the kernel mapping code works fine for creating a
coarse grained identity map, but for mapping the kernel down to its
exact boundaries with the right attributes, it is not suitable. This is
why we create a preliminary RWX kernel mapping first, and then rebuild
it from scratch later on.

So let's reimplement this in C, in a way that will make it unnecessary
to create the kernel page tables yet another time in paging_init().

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/archrandom.h   |   2 -
 arch/arm64/include/asm/scs.h          |  32 +---
 arch/arm64/kernel/head.S              |  52 +------
 arch/arm64/kernel/image-vars.h        |  19 +++
 arch/arm64/kernel/pi/Makefile         |   1 +
 arch/arm64/kernel/pi/idreg-override.c |  22 ++-
 arch/arm64/kernel/pi/kaslr_early.c    |  12 +-
 arch/arm64/kernel/pi/map_kernel.c     | 164 ++++++++++++++++++++
 arch/arm64/kernel/pi/map_range.c      |  88 +++++++++++
 arch/arm64/kernel/pi/patch-scs.c      |  16 +-
 arch/arm64/kernel/pi/pi.h             |  14 ++
 arch/arm64/kernel/pi/relocate.c       |   2 +
 arch/arm64/kernel/setup.c             |   7 -
 arch/arm64/kernel/vmlinux.lds.S       |   4 +-
 arch/arm64/mm/proc.S                  |   1 +
 15 files changed, 315 insertions(+), 121 deletions(-)

diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index ecdb3cfcd0f8..8babfbe31f95 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -129,6 +129,4 @@ static inline bool __init __early_cpu_has_rndr(void)
 	return (ftr >> ID_AA64ISAR0_EL1_RNDR_SHIFT) & 0xf;
 }
 
-u64 kaslr_early_init(void *fdt);
-
 #endif /* _ASM_ARCHRANDOM_H */
diff --git a/arch/arm64/include/asm/scs.h b/arch/arm64/include/asm/scs.h
index eca2ba5a6276..2e010ea76be2 100644
--- a/arch/arm64/include/asm/scs.h
+++ b/arch/arm64/include/asm/scs.h
@@ -33,37 +33,11 @@
 #include <asm/cpufeature.h>
 
 #ifdef CONFIG_UNWIND_PATCH_PAC_INTO_SCS
-static inline bool should_patch_pac_into_scs(void)
-{
-	u64 reg;
-
-	/*
-	 * We only enable the shadow call stack dynamically if we are running
-	 * on a system that does not implement PAC or BTI. PAC and SCS provide
-	 * roughly the same level of protection, and BTI relies on the PACIASP
-	 * instructions serving as landing pads, preventing us from patching
-	 * those instructions into something else.
-	 */
-	reg = read_sysreg_s(SYS_ID_AA64ISAR1_EL1);
-	if (SYS_FIELD_GET(ID_AA64ISAR1_EL1, APA, reg) |
-	    SYS_FIELD_GET(ID_AA64ISAR1_EL1, API, reg))
-		return false;
-
-	reg = read_sysreg_s(SYS_ID_AA64ISAR2_EL1);
-	if (SYS_FIELD_GET(ID_AA64ISAR2_EL1, APA3, reg))
-		return false;
-
-	if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) {
-		reg = read_sysreg_s(SYS_ID_AA64PFR1_EL1);
-		if (reg & (0xf << ID_AA64PFR1_EL1_BT_SHIFT))
-			return false;
-	}
-	return true;
-}
-
 static inline void dynamic_scs_init(void)
 {
-	if (should_patch_pac_into_scs()) {
+	extern bool __pi_dynamic_scs_is_enabled;
+
+	if (__pi_dynamic_scs_is_enabled) {
 		pr_info("Enabling dynamic shadow call stack\n");
 		static_branch_enable(&dynamic_scs_enabled);
 	}
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index aa7766dc64d9..ffacce7b5a02 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -81,7 +81,6 @@
 	 *  x20        primary_entry() .. __primary_switch()    CPU boot mode
 	 *  x21        primary_entry() .. start_kernel()        FDT pointer passed at boot in x0
 	 *  x22        create_idmap() .. start_kernel()         ID map VA of the DT blob
-	 *  x23        __primary_switch()                       physical misalignment/KASLR offset
 	 *  x25        primary_entry() .. start_kernel()        supported VA size
 	 *  x28        create_idmap()                           callee preserved temp register
 	 */
@@ -408,24 +407,6 @@ SYM_FUNC_START_LOCAL(create_idmap)
 0:	ret	x28
 SYM_FUNC_END(create_idmap)
 
-SYM_FUNC_START_LOCAL(create_kernel_mapping)
-	adrp	x0, init_pg_dir
-	mov_q	x5, KIMAGE_VADDR		// compile time __va(_text)
-#ifdef CONFIG_RELOCATABLE
-	add	x5, x5, x23			// add KASLR displacement
-#endif
-	adrp	x6, _end			// runtime __pa(_end)
-	adrp	x3, _text			// runtime __pa(_text)
-	sub	x6, x6, x3			// _end - _text
-	add	x6, x6, x5			// runtime __va(_end)
-	mov_q	x7, SWAPPER_RW_MMUFLAGS
-
-	map_memory x0, x1, x5, x6, x7, x3, (VA_BITS - PGDIR_SHIFT), x10, x11, x12, x13, x14
-
-	dsb	ishst				// sync with page table walker
-	ret
-SYM_FUNC_END(create_kernel_mapping)
-
 	/*
 	 * Initialize CPU registers with task-specific and cpu-specific context.
 	 *
@@ -752,44 +733,13 @@ SYM_FUNC_START_LOCAL(__primary_switch)
 	adrp	x2, init_idmap_pg_dir
 	bl	__enable_mmu
 
-	// Clear BSS
-	adrp	x0, __bss_start
-	mov	x1, xzr
-	adrp	x2, init_pg_end
-	sub	x2, x2, x0
-	bl	__pi_memset
-	dsb	ishst				// Make zero page visible to PTW
-
 	adrp	x1, early_init_stack
 	mov	sp, x1
 	mov	x29, xzr
 	mov	x0, x20				// pass the full boot status
 	mov	x1, x22				// pass the low FDT mapping
-	bl	__pi_init_feature_override	// Parse cpu feature overrides
-
-#ifdef CONFIG_RELOCATABLE
-	adrp	x23, KERNEL_START
-	and	x23, x23, MIN_KIMG_ALIGN - 1
-#ifdef CONFIG_RANDOMIZE_BASE
-	mov	x0, x22
-	bl	__pi_kaslr_early_init
-	bic	x0, x0, #SZ_2M - 1
-	orr	x23, x23, x0			// record kernel offset
-#endif
-#endif
-	bl	create_kernel_mapping
+	bl	__pi_early_map_kernel		// Map and relocate the kernel
 
-	adrp	x1, init_pg_dir
-	load_ttbr1 x1, x1, x2
-#ifdef CONFIG_RELOCATABLE
-	mov	x0, x23
-	bl	__pi_relocate_kernel
-#endif
-#ifdef CONFIG_UNWIND_PATCH_PAC_INTO_SCS
-	ldr	x0, =__eh_frame_start
-	ldr	x1, =__eh_frame_end
-	bl	__pi_scs_patch_vmlinux
-#endif
 	ldr	x8, =__primary_switched
 	adrp	x0, KERNEL_START		// __pa(KERNEL_START)
 	br	x8
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 8d96052079e8..e566b32f9c22 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -45,9 +45,28 @@ PROVIDE(__pi_id_aa64pfr1_override	= id_aa64pfr1_override);
 PROVIDE(__pi_id_aa64smfr0_override	= id_aa64smfr0_override);
 PROVIDE(__pi_id_aa64zfr0_override	= id_aa64zfr0_override);
 PROVIDE(__pi_arm64_sw_feature_override	= arm64_sw_feature_override);
+PROVIDE(__pi_arm64_use_ng_mappings	= arm64_use_ng_mappings);
+#ifdef CONFIG_CAVIUM_ERRATUM_27456
+PROVIDE(__pi_cavium_erratum_27456_cpus	= cavium_erratum_27456_cpus);
+#endif
 PROVIDE(__pi__ctype			= _ctype);
 PROVIDE(__pi_memstart_offset_seed	= memstart_offset_seed);
 
+PROVIDE(__pi_init_pg_dir		= init_pg_dir);
+PROVIDE(__pi_init_pg_end		= init_pg_end);
+
+PROVIDE(__pi__text			= _text);
+PROVIDE(__pi__stext               	= _stext);
+PROVIDE(__pi__etext               	= _etext);
+PROVIDE(__pi___start_rodata       	= __start_rodata);
+PROVIDE(__pi___inittext_begin     	= __inittext_begin);
+PROVIDE(__pi___inittext_end       	= __inittext_end);
+PROVIDE(__pi___initdata_begin     	= __initdata_begin);
+PROVIDE(__pi___initdata_end       	= __initdata_end);
+PROVIDE(__pi__data                	= _data);
+PROVIDE(__pi___bss_start		= __bss_start);
+PROVIDE(__pi__end			= _end);
+
 #ifdef CONFIG_KVM
 
 /*
diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile
index a8b302245f15..8c2f80a46b93 100644
--- a/arch/arm64/kernel/pi/Makefile
+++ b/arch/arm64/kernel/pi/Makefile
@@ -39,6 +39,7 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
 obj-y					:= idreg-override.pi.o \
+					   map_kernel.pi.o map_range.pi.o \
 					   lib-fdt.pi.o lib-fdt_ro.pi.o
 obj-$(CONFIG_RELOCATABLE)		+= relocate.pi.o
 obj-$(CONFIG_RANDOMIZE_BASE)		+= kaslr_early.pi.o
diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
index e4bcabcc6860..1884bd936c0d 100644
--- a/arch/arm64/kernel/pi/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -308,37 +308,35 @@ static __init void __parse_cmdline(const char *cmdline, bool parse_aliases)
 	} while (1);
 }
 
-static __init const u8 *get_bootargs_cmdline(const void *fdt)
+static __init const u8 *get_bootargs_cmdline(const void *fdt, int node)
 {
+	static char const bootargs[] __initconst = "bootargs";
 	const u8 *prop;
-	int node;
 
-	node = fdt_path_offset(fdt, "/chosen");
 	if (node < 0)
 		return NULL;
 
-	prop = fdt_getprop(fdt, node, "bootargs", NULL);
+	prop = fdt_getprop(fdt, node, bootargs, NULL);
 	if (!prop)
 		return NULL;
 
 	return strlen(prop) ? prop : NULL;
 }
 
-static __init void parse_cmdline(const void *fdt)
+static __init void parse_cmdline(const void *fdt, int chosen)
 {
-	const u8 *prop = get_bootargs_cmdline(fdt);
+	static char const cmdline[] __initconst = CONFIG_CMDLINE;
+	const u8 *prop = get_bootargs_cmdline(fdt, chosen);
 
 	if (IS_ENABLED(CONFIG_CMDLINE_FORCE) || !prop)
-		__parse_cmdline(CONFIG_CMDLINE, true);
+		__parse_cmdline(cmdline, true);
 
 	if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && prop)
 		__parse_cmdline(prop, true);
 }
 
-/* Keep checkers quiet */
-void init_feature_override(u64 boot_status, const void *fdt);
-
-asmlinkage void __init init_feature_override(u64 boot_status, const void *fdt)
+void __init init_feature_override(u64 boot_status, const void *fdt,
+				  int chosen)
 {
 	struct arm64_ftr_override *override;
 	const struct ftr_set_desc *reg;
@@ -354,7 +352,7 @@ asmlinkage void __init init_feature_override(u64 boot_status, const void *fdt)
 
 	__boot_status = boot_status;
 
-	parse_cmdline(fdt);
+	parse_cmdline(fdt, chosen);
 
 	for (i = 0; i < ARRAY_SIZE(regs); i++) {
 		reg = prel64_pointer(regs[i].reg);
diff --git a/arch/arm64/kernel/pi/kaslr_early.c b/arch/arm64/kernel/pi/kaslr_early.c
index eeecee7ffd6f..0257b43819db 100644
--- a/arch/arm64/kernel/pi/kaslr_early.c
+++ b/arch/arm64/kernel/pi/kaslr_early.c
@@ -16,17 +16,17 @@
 #include <asm/memory.h>
 #include <asm/pgtable.h>
 
+#include "pi.h"
+
 extern u16 memstart_offset_seed;
 
-static u64 __init get_kaslr_seed(void *fdt)
+static u64 __init get_kaslr_seed(void *fdt, int node)
 {
-	static char const chosen_str[] __initconst = "chosen";
 	static char const seed_str[] __initconst = "kaslr-seed";
-	int node, len;
 	fdt64_t *prop;
 	u64 ret;
+	int len;
 
-	node = fdt_path_offset(fdt, chosen_str);
 	if (node < 0)
 		return 0;
 
@@ -39,14 +39,14 @@ static u64 __init get_kaslr_seed(void *fdt)
 	return ret;
 }
 
-asmlinkage u64 __init kaslr_early_init(void *fdt)
+u64 __init kaslr_early_init(void *fdt, int chosen)
 {
 	u64 seed, range;
 
 	if (kaslr_disabled_cmdline())
 		return 0;
 
-	seed = get_kaslr_seed(fdt);
+	seed = get_kaslr_seed(fdt, chosen);
 	if (!seed) {
 		if (!__early_cpu_has_rndr() ||
 		    !__arm64_rndr((unsigned long *)&seed))
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
new file mode 100644
index 000000000000..f206373b28b0
--- /dev/null
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2023 Google LLC
+// Author: Ard Biesheuvel <ardb at google.com>
+
+#include <linux/init.h>
+#include <linux/libfdt.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/sizes.h>
+#include <linux/string.h>
+
+#include <asm/memory.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+#include "pi.h"
+
+extern const u8 __eh_frame_start[], __eh_frame_end[];
+
+extern void idmap_cpu_replace_ttbr1(void *pgdir);
+
+static void __init map_segment(pgd_t *pg_dir, u64 *pgd, u64 va_offset,
+			       void *start, void *end, pgprot_t prot,
+			       bool may_use_cont, int root_level)
+{
+	map_range(pgd, ((u64)start + va_offset) & ~PAGE_OFFSET,
+		  ((u64)end + va_offset) & ~PAGE_OFFSET, (u64)start,
+		  prot, root_level, (pte_t *)pg_dir, may_use_cont, 0);
+}
+
+static void __init unmap_segment(pgd_t *pg_dir, u64 va_offset, void *start,
+				 void *end, int root_level)
+{
+	map_segment(pg_dir, NULL, va_offset, start, end, __pgprot(0),
+		    false, root_level);
+}
+
+static void __init map_kernel(u64 kaslr_offset, u64 va_offset, int root_level)
+{
+	bool enable_scs = IS_ENABLED(CONFIG_UNWIND_PATCH_PAC_INTO_SCS);
+	bool twopass = IS_ENABLED(CONFIG_RELOCATABLE);
+	u64 pgdp = (u64)init_pg_dir + PAGE_SIZE;
+	pgprot_t text_prot = PAGE_KERNEL_ROX;
+	pgprot_t data_prot = PAGE_KERNEL;
+	pgprot_t prot;
+
+	/*
+	 * External debuggers may need to write directly to the text mapping to
+	 * install SW breakpoints. Allow this (only) when explicitly requested
+	 * with rodata=off.
+	 */
+	if (arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_RODATA_OFF))
+		text_prot = PAGE_KERNEL_EXEC;
+
+	/*
+	 * We only enable the shadow call stack dynamically if we are running
+	 * on a system that does not implement PAC or BTI. PAC and SCS provide
+	 * roughly the same level of protection, and BTI relies on the PACIASP
+	 * instructions serving as landing pads, preventing us from patching
+	 * those instructions into something else.
+	 */
+	if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL) && cpu_has_pac())
+		enable_scs = false;
+
+	if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) && cpu_has_bti()) {
+		enable_scs = false;
+
+		/*
+		 * If we have a CPU that supports BTI and a kernel built for
+		 * BTI then mark the kernel executable text as guarded pages
+		 * now so we don't have to rewrite the page tables later.
+		 */
+		text_prot = __pgprot_modify(text_prot, PTE_GP, PTE_GP);
+	}
+
+	/* Map all code read-write on the first pass if needed */
+	twopass |= enable_scs;
+	prot = twopass ? data_prot : text_prot;
+
+	map_segment(init_pg_dir, &pgdp, va_offset, _stext, _etext, prot,
+		    !twopass, root_level);
+	map_segment(init_pg_dir, &pgdp, va_offset, __start_rodata,
+		    __inittext_begin, data_prot, false, root_level);
+	map_segment(init_pg_dir, &pgdp, va_offset, __inittext_begin,
+		    __inittext_end, prot, false, root_level);
+	map_segment(init_pg_dir, &pgdp, va_offset, __initdata_begin,
+		    __initdata_end, data_prot, false, root_level);
+	map_segment(init_pg_dir, &pgdp, va_offset, _data, _end, data_prot,
+		    true, root_level);
+	dsb(ishst);
+
+	idmap_cpu_replace_ttbr1(init_pg_dir);
+
+	if (twopass) {
+		if (IS_ENABLED(CONFIG_RELOCATABLE))
+			relocate_kernel(kaslr_offset);
+
+		if (enable_scs) {
+			scs_patch(__eh_frame_start + va_offset,
+				  __eh_frame_end - __eh_frame_start);
+			asm("ic ialluis");
+
+			dynamic_scs_is_enabled = true;
+		}
+
+		/*
+		 * Unmap the text region before remapping it, to avoid
+		 * potential TLB conflicts when creating the contiguous
+		 * descriptors.
+		 */
+		unmap_segment(init_pg_dir, va_offset, _stext, _etext,
+			      root_level);
+		dsb(ishst);
+		isb();
+		__tlbi(vmalle1);
+		isb();
+
+		/*
+		 * Remap these segments with different permissions
+		 * No new page table allocations should be needed
+		 */
+		map_segment(init_pg_dir, NULL, va_offset, _stext, _etext,
+			    text_prot, true, root_level);
+		map_segment(init_pg_dir, NULL, va_offset, __inittext_begin,
+			    __inittext_end, text_prot, false, root_level);
+		dsb(ishst);
+	}
+}
+
+asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt)
+{
+	static char const chosen_str[] __initconst = "/chosen";
+	u64 va_base, pa_base = (u64)&_text;
+	u64 kaslr_offset = pa_base % MIN_KIMG_ALIGN;
+	int root_level = 4 - CONFIG_PGTABLE_LEVELS;
+	int chosen;
+
+	/* Clear BSS and the initial page tables */
+	memset(__bss_start, 0, (u64)init_pg_end - (u64)__bss_start);
+
+	/* Parse the command line for CPU feature overrides */
+	chosen = fdt_path_offset(fdt, chosen_str);
+	init_feature_override(boot_status, fdt, chosen);
+
+	/*
+	 * The virtual KASLR displacement modulo 2MiB is decided by the
+	 * physical placement of the image, as otherwise, we might not be able
+	 * to create the early kernel mapping using 2 MiB block descriptors. So
+	 * take the low bits of the KASLR offset from the physical address, and
+	 * fill in the high bits from the seed.
+	 */
+	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
+		u64 kaslr_seed = kaslr_early_init(fdt, chosen);
+
+		if (kaslr_seed && kaslr_requires_kpti())
+			arm64_use_ng_mappings = true;
+
+		kaslr_offset |= kaslr_seed & ~(MIN_KIMG_ALIGN - 1);
+	}
+
+	va_base = KIMAGE_VADDR + kaslr_offset;
+	map_kernel(kaslr_offset, va_base - pa_base, root_level);
+}
diff --git a/arch/arm64/kernel/pi/map_range.c b/arch/arm64/kernel/pi/map_range.c
new file mode 100644
index 000000000000..c31feda18f47
--- /dev/null
+++ b/arch/arm64/kernel/pi/map_range.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2023 Google LLC
+// Author: Ard Biesheuvel <ardb at google.com>
+
+#include <linux/types.h>
+#include <linux/sizes.h>
+
+#include <asm/memory.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+#include "pi.h"
+
+/**
+ * map_range - Map a contiguous range of physical pages into virtual memory
+ *
+ * @pte:		Address of physical pointer to array of pages to
+ *			allocate page tables from
+ * @start:		Virtual address of the start of the range
+ * @end:		Virtual address of the end of the range (exclusive)
+ * @pa:			Physical address of the start of the range
+ * @prot:		Access permissions of the range
+ * @level:		Translation level for the mapping
+ * @tbl:		The level @level page table to create the mappings in
+ * @may_use_cont:	Whether the use of the contiguous attribute is allowed
+ * @va_offset:		Offset between a physical page and its current mapping
+ * 			in the VA space
+ */
+void __init map_range(u64 *pte, u64 start, u64 end, u64 pa, pgprot_t prot,
+		      int level, pte_t *tbl, bool may_use_cont, u64 va_offset)
+{
+	u64 cmask = (level == 3) ? CONT_PTE_SIZE - 1 : U64_MAX;
+	u64 protval = pgprot_val(prot) & ~PTE_TYPE_MASK;
+	int lshift = (3 - level) * (PAGE_SHIFT - 3);
+	u64 lmask = (PAGE_SIZE << lshift) - 1;
+
+	start	&= PAGE_MASK;
+	pa	&= PAGE_MASK;
+
+	/* Advance tbl to the entry that covers start */
+	tbl += (start >> (lshift + PAGE_SHIFT)) % PTRS_PER_PTE;
+
+	/*
+	 * Set the right block/page bits for this level unless we are
+	 * clearing the mapping
+	 */
+	if (protval)
+		protval |= (level < 3) ? PMD_TYPE_SECT : PTE_TYPE_PAGE;
+
+	while (start < end) {
+		u64 next = min((start | lmask) + 1, PAGE_ALIGN(end));
+
+		if (level < 3 && (start | next | pa) & lmask) {
+			/*
+			 * This chunk needs a finer grained mapping. Create a
+			 * table mapping if necessary and recurse.
+			 */
+			if (pte_none(*tbl)) {
+				*tbl = __pte(__phys_to_pte_val(*pte) |
+					     PMD_TYPE_TABLE | PMD_TABLE_UXN);
+				*pte += PTRS_PER_PTE * sizeof(pte_t);
+			}
+			map_range(pte, start, next, pa, prot, level + 1,
+				  (pte_t *)(__pte_to_phys(*tbl) + va_offset),
+				  may_use_cont, va_offset);
+		} else {
+			/*
+			 * Start a contiguous range if start and pa are
+			 * suitably aligned
+			 */
+			if (((start | pa) & cmask) == 0 && may_use_cont)
+				protval |= PTE_CONT;
+
+			/*
+			 * Clear the contiguous attribute if the remaining
+			 * range does not cover a contiguous block
+			 */
+			if ((end & ~cmask) <= start)
+				protval &= ~PTE_CONT;
+
+			/* Put down a block or page mapping */
+			*tbl = __pte(__phys_to_pte_val(pa) | protval);
+		}
+		pa += next - start;
+		start = next;
+		tbl++;
+	}
+}
diff --git a/arch/arm64/kernel/pi/patch-scs.c b/arch/arm64/kernel/pi/patch-scs.c
index c65ef40d1e6b..49d8b40e61bc 100644
--- a/arch/arm64/kernel/pi/patch-scs.c
+++ b/arch/arm64/kernel/pi/patch-scs.c
@@ -11,6 +11,10 @@
 
 #include <asm/scs.h>
 
+#include "pi.h"
+
+bool dynamic_scs_is_enabled;
+
 //
 // This minimal DWARF CFI parser is partially based on the code in
 // arch/arc/kernel/unwind.c, and on the document below:
@@ -46,8 +50,6 @@
 #define DW_CFA_GNU_negative_offset_extended 0x2f
 #define DW_CFA_hi_user                      0x3f
 
-extern const u8 __eh_frame_start[], __eh_frame_end[];
-
 enum {
 	PACIASP		= 0xd503233f,
 	AUTIASP		= 0xd50323bf,
@@ -250,13 +252,3 @@ int scs_patch(const u8 eh_frame[], int size)
 	}
 	return 0;
 }
-
-asmlinkage void __init scs_patch_vmlinux(const u8 start[], const u8 end[])
-{
-	if (!should_patch_pac_into_scs())
-		return;
-
-	scs_patch(start, end - start);
-	asm("ic ialluis");
-	isb();
-}
diff --git a/arch/arm64/kernel/pi/pi.h b/arch/arm64/kernel/pi/pi.h
index 7c2d9bbf0ff9..d307c58e9741 100644
--- a/arch/arm64/kernel/pi/pi.h
+++ b/arch/arm64/kernel/pi/pi.h
@@ -2,6 +2,8 @@
 // Copyright 2023 Google LLC
 // Author: Ard Biesheuvel <ardb at google.com>
 
+#include <linux/types.h>
+
 #define __prel64_initconst	__section(".init.rodata.prel64")
 
 #define PREL64(type, name)	union { type *name; prel64_t name ## _prel; }
@@ -16,3 +18,15 @@ static inline void *prel64_to_pointer(const prel64_t *offset)
 		return NULL;
 	return (void *)offset + *offset;
 }
+
+extern bool dynamic_scs_is_enabled;
+
+void init_feature_override(u64 boot_status, const void *fdt, int chosen);
+u64 kaslr_early_init(void *fdt, int chosen);
+void relocate_kernel(u64 offset);
+int scs_patch(const u8 eh_frame[], int size);
+
+void map_range(u64 *pgd, u64 start, u64 end, u64 pa, pgprot_t prot,
+	       int level, pte_t *tbl, bool may_use_cont, u64 va_offset);
+
+asmlinkage void early_map_kernel(u64 boot_status, void *fdt);
diff --git a/arch/arm64/kernel/pi/relocate.c b/arch/arm64/kernel/pi/relocate.c
index 1853408ea76b..2407d2696398 100644
--- a/arch/arm64/kernel/pi/relocate.c
+++ b/arch/arm64/kernel/pi/relocate.c
@@ -7,6 +7,8 @@
 #include <linux/init.h>
 #include <linux/types.h>
 
+#include "pi.h"
+
 extern const Elf64_Rela rela_start[], rela_end[];
 extern const u64 relr_start[], relr_end[];
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 0ef45d1927b3..0ea45b6d0177 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -283,13 +283,6 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 
 	kaslr_init();
 
-	/*
-	 * If know now we are going to need KPTI then use non-global
-	 * mappings from the start, avoiding the cost of rewriting
-	 * everything later.
-	 */
-	arm64_use_ng_mappings = kaslr_enabled() && kaslr_requires_kpti();
-
 	early_fixmap_init();
 	early_ioremap_init();
 
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 3afb4223a5e8..755a22d4f840 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -126,9 +126,9 @@ jiffies = jiffies_64;
 #ifdef CONFIG_UNWIND_TABLES
 #define UNWIND_DATA_SECTIONS				\
 	.eh_frame : {					\
-		__eh_frame_start = .;			\
+		__pi___eh_frame_start = .;		\
 		*(.eh_frame)				\
-		__eh_frame_end = .;			\
+		__pi___eh_frame_end = .;		\
 	}
 #else
 #define UNWIND_DATA_SECTIONS
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index f66c37a1610e..7c1bdaf25408 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -195,6 +195,7 @@ SYM_TYPED_FUNC_START(idmap_cpu_replace_ttbr1)
 
 	ret
 SYM_FUNC_END(idmap_cpu_replace_ttbr1)
+SYM_FUNC_ALIAS(__pi_idmap_cpu_replace_ttbr1, idmap_cpu_replace_ttbr1)
 	.popsection
 
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:09 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:09 +0100
Subject: [PATCH v8 23/43] arm64: mm: omit redundant remap of kernel image
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-68-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Now that the early kernel mapping is created with all the right
attributes and segment boundaries, there is no longer a need to recreate
it and switch to it. This also means we no longer have to copy the kasan
shadow or some parts of the fixmap from one set of page tables to the
other.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/fixmap.h   |  1 -
 arch/arm64/include/asm/kasan.h    |  2 -
 arch/arm64/include/asm/mmu.h      |  2 +-
 arch/arm64/kernel/image-vars.h    |  1 +
 arch/arm64/kernel/pi/map_kernel.c |  6 +-
 arch/arm64/mm/fixmap.c            | 34 --------
 arch/arm64/mm/kasan_init.c        | 15 ----
 arch/arm64/mm/mmu.c               | 85 ++++----------------
 8 files changed, 21 insertions(+), 125 deletions(-)

diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index 58c294a96676..8aabd45e9a13 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -100,7 +100,6 @@ enum fixed_addresses {
 #define FIXMAP_PAGE_IO     __pgprot(PROT_DEVICE_nGnRE)
 
 void __init early_fixmap_init(void);
-void __init fixmap_copy(pgd_t *pgdir);
 
 #define __early_set_fixmap __set_fixmap
 
diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
index 7eefc525a9df..e1b57c13f8a4 100644
--- a/arch/arm64/include/asm/kasan.h
+++ b/arch/arm64/include/asm/kasan.h
@@ -17,11 +17,9 @@
 
 asmlinkage void kasan_early_init(void);
 void kasan_init(void);
-void kasan_copy_shadow(pgd_t *pgdir);
 
 #else
 static inline void kasan_init(void) { }
-static inline void kasan_copy_shadow(pgd_t *pgdir) { }
 #endif
 
 #endif
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index d0b8b4b413b6..65977c7783c5 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -110,7 +110,7 @@ static inline bool kaslr_requires_kpti(void)
 }
 
 #define INIT_MM_CONTEXT(name)	\
-	.pgd = init_pg_dir,
+	.pgd = swapper_pg_dir,
 
 #endif	/* !__ASSEMBLY__ */
 #endif
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 941a14c05184..e140c5bda90b 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -55,6 +55,7 @@ PROVIDE(__pi_memstart_offset_seed	= memstart_offset_seed);
 PROVIDE(__pi_init_idmap_pg_dir		= init_idmap_pg_dir);
 PROVIDE(__pi_init_pg_dir		= init_pg_dir);
 PROVIDE(__pi_init_pg_end		= init_pg_end);
+PROVIDE(__pi_swapper_pg_dir		= swapper_pg_dir);
 
 PROVIDE(__pi__text			= _text);
 PROVIDE(__pi__stext               	= _stext);
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
index f86e878d366d..4b76a007a50d 100644
--- a/arch/arm64/kernel/pi/map_kernel.c
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -124,8 +124,12 @@ static void __init map_kernel(u64 kaslr_offset, u64 va_offset, int root_level)
 			    text_prot, true, root_level);
 		map_segment(init_pg_dir, NULL, va_offset, __inittext_begin,
 			    __inittext_end, text_prot, false, root_level);
-		dsb(ishst);
 	}
+
+	/* Copy the root page table to its final location */
+	memcpy((void *)swapper_pg_dir + va_offset, init_pg_dir, PGD_SIZE);
+	dsb(ishst);
+	idmap_cpu_replace_ttbr1(swapper_pg_dir);
 }
 
 static void __init map_fdt(u64 fdt)
diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
index 6fc17b2e1714..9404f282f829 100644
--- a/arch/arm64/mm/fixmap.c
+++ b/arch/arm64/mm/fixmap.c
@@ -170,37 +170,3 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
 
 	return dt_virt;
 }
-
-/*
- * Copy the fixmap region into a new pgdir.
- */
-void __init fixmap_copy(pgd_t *pgdir)
-{
-	if (!READ_ONCE(pgd_val(*pgd_offset_pgd(pgdir, FIXADDR_TOT_START)))) {
-		/*
-		 * The fixmap falls in a separate pgd to the kernel, and doesn't
-		 * live in the carveout for the swapper_pg_dir. We can simply
-		 * re-use the existing dir for the fixmap.
-		 */
-		set_pgd(pgd_offset_pgd(pgdir, FIXADDR_TOT_START),
-			READ_ONCE(*pgd_offset_k(FIXADDR_TOT_START)));
-	} else if (CONFIG_PGTABLE_LEVELS > 3) {
-		pgd_t *bm_pgdp;
-		p4d_t *bm_p4dp;
-		pud_t *bm_pudp;
-		/*
-		 * The fixmap shares its top level pgd entry with the kernel
-		 * mapping. This can really only occur when we are running
-		 * with 16k/4 levels, so we can simply reuse the pud level
-		 * entry instead.
-		 */
-		BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
-		bm_pgdp = pgd_offset_pgd(pgdir, FIXADDR_TOT_START);
-		bm_p4dp = p4d_offset(bm_pgdp, FIXADDR_TOT_START);
-		bm_pudp = pud_set_fixmap_offset(bm_p4dp, FIXADDR_TOT_START);
-		pud_populate(&init_mm, bm_pudp, lm_alias(bm_pmd));
-		pud_clear_fixmap();
-	} else {
-		BUG();
-	}
-}
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 4c7ad574b946..89828ad2bca7 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -189,21 +189,6 @@ static void __init kasan_map_populate(unsigned long start, unsigned long end,
 	kasan_pgd_populate(start & PAGE_MASK, PAGE_ALIGN(end), node, false);
 }
 
-/*
- * Copy the current shadow region into a new pgdir.
- */
-void __init kasan_copy_shadow(pgd_t *pgdir)
-{
-	pgd_t *pgdp, *pgdp_new, *pgdp_end;
-
-	pgdp = pgd_offset_k(KASAN_SHADOW_START);
-	pgdp_end = pgd_offset_k(KASAN_SHADOW_END);
-	pgdp_new = pgd_offset_pgd(pgdir, KASAN_SHADOW_START);
-	do {
-		set_pgd(pgdp_new, READ_ONCE(*pgdp));
-	} while (pgdp++, pgdp_new++, pgdp != pgdp_end);
-}
-
 static void __init clear_pgds(unsigned long start,
 			unsigned long end)
 {
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 9758f7e3f4b6..3db40b517947 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -648,9 +648,9 @@ void mark_rodata_ro(void)
 	debug_checkwx();
 }
 
-static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
-				      pgprot_t prot, struct vm_struct *vma,
-				      int flags, unsigned long vm_flags)
+static void __init declare_vma(struct vm_struct *vma,
+			       void *va_start, void *va_end,
+			       unsigned long vm_flags)
 {
 	phys_addr_t pa_start = __pa_symbol(va_start);
 	unsigned long size = va_end - va_start;
@@ -658,9 +658,6 @@ static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
 	BUG_ON(!PAGE_ALIGNED(pa_start));
 	BUG_ON(!PAGE_ALIGNED(size));
 
-	__create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot,
-			     early_pgtable_alloc, flags);
-
 	if (!(vm_flags & VM_NO_GUARD))
 		size += PAGE_SIZE;
 
@@ -673,12 +670,12 @@ static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
 	vm_area_add_early(vma);
 }
 
+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 static pgprot_t kernel_exec_prot(void)
 {
 	return rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
 }
 
-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 static int __init map_entry_trampoline(void)
 {
 	int i;
@@ -713,60 +710,17 @@ core_initcall(map_entry_trampoline);
 #endif
 
 /*
- * Open coded check for BTI, only for use to determine configuration
- * for early mappings for before the cpufeature code has run.
- */
-static bool arm64_early_this_cpu_has_bti(void)
-{
-	u64 pfr1;
-
-	if (!IS_ENABLED(CONFIG_ARM64_BTI_KERNEL))
-		return false;
-
-	pfr1 = __read_sysreg_by_encoding(SYS_ID_AA64PFR1_EL1);
-	return cpuid_feature_extract_unsigned_field(pfr1,
-						    ID_AA64PFR1_EL1_BT_SHIFT);
-}
-
-/*
- * Create fine-grained mappings for the kernel.
+ * Declare the VMA areas for the kernel
  */
-static void __init map_kernel(pgd_t *pgdp)
+static void __init declare_kernel_vmas(void)
 {
-	static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext,
-				vmlinux_initdata, vmlinux_data;
-
-	/*
-	 * External debuggers may need to write directly to the text
-	 * mapping to install SW breakpoints. Allow this (only) when
-	 * explicitly requested with rodata=off.
-	 */
-	pgprot_t text_prot = kernel_exec_prot();
-
-	/*
-	 * If we have a CPU that supports BTI and a kernel built for
-	 * BTI then mark the kernel executable text as guarded pages
-	 * now so we don't have to rewrite the page tables later.
-	 */
-	if (arm64_early_this_cpu_has_bti())
-		text_prot = __pgprot_modify(text_prot, PTE_GP, PTE_GP);
+	static struct vm_struct vmlinux_seg[KERNEL_SEGMENT_COUNT];
 
-	/*
-	 * Only rodata will be remapped with different permissions later on,
-	 * all other segments are allowed to use contiguous mappings.
-	 */
-	map_kernel_segment(pgdp, _stext, _etext, text_prot, &vmlinux_text, 0,
-			   VM_NO_GUARD);
-	map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL,
-			   &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD);
-	map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot,
-			   &vmlinux_inittext, 0, VM_NO_GUARD);
-	map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL,
-			   &vmlinux_initdata, 0, VM_NO_GUARD);
-	map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0);
-
-	fixmap_copy(pgdp);
-	kasan_copy_shadow(pgdp);
+	declare_vma(&vmlinux_seg[0], _stext, _etext, VM_NO_GUARD);
+	declare_vma(&vmlinux_seg[1], __start_rodata, __inittext_begin, VM_NO_GUARD);
+	declare_vma(&vmlinux_seg[2], __inittext_begin, __inittext_end, VM_NO_GUARD);
+	declare_vma(&vmlinux_seg[3], __initdata_begin, __initdata_end, VM_NO_GUARD);
+	declare_vma(&vmlinux_seg[4], _data, _end, 0);
 }
 
 void __pi_map_range(u64 *pgd, u64 start, u64 end, u64 pa, pgprot_t prot,
@@ -802,23 +756,12 @@ static void __init create_idmap(void)
 
 void __init paging_init(void)
 {
-	pgd_t *pgdp = pgd_set_fixmap(__pa_symbol(swapper_pg_dir));
-	extern pgd_t init_idmap_pg_dir[];
-
-	map_kernel(pgdp);
-	map_mem(pgdp);
-
-	pgd_clear_fixmap();
-
-	cpu_replace_ttbr1(lm_alias(swapper_pg_dir), init_idmap_pg_dir);
-	init_mm.pgd = swapper_pg_dir;
-
-	memblock_phys_free(__pa_symbol(init_pg_dir),
-			   __pa_symbol(init_pg_end) - __pa_symbol(init_pg_dir));
+	map_mem(swapper_pg_dir);
 
 	memblock_allow_resize();
 
 	create_idmap();
+	declare_kernel_vmas();
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:02 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:02 +0100
Subject: [PATCH v8 16/43] arm64: mm: Make kaslr_requires_kpti() a static inline
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-61-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

In preparation for moving the first assignment of arm64_use_ng_mappings
to an earlier stage in the boot, ensure that kaslr_requires_kpti() is
accessible without relying on the core kernel's view on whether or not
KASLR is enabled. So make it a static inline, and move the
kaslr_enabled() check out of it and into the callers, one of which will
disappear in a subsequent patch.

Once/when support for the obsolete ThunderX 1 platform is dropped, this
check reduces to a E0PD feature check on the local CPU.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/mmu.h   | 38 +++++++++++++++++-
 arch/arm64/kernel/cpufeature.c | 42 +-------------------
 arch/arm64/kernel/setup.c      |  2 +-
 3 files changed, 39 insertions(+), 43 deletions(-)

diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 2fcf51231d6e..d0b8b4b413b6 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -71,7 +71,43 @@ extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
 			       pgprot_t prot, bool page_mappings_only);
 extern void *fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot);
 extern void mark_linear_text_alias_ro(void);
-extern bool kaslr_requires_kpti(void);
+
+/*
+ * This check is triggered during the early boot before the cpufeature
+ * is initialised. Checking the status on the local CPU allows the boot
+ * CPU to detect the need for non-global mappings and thus avoiding a
+ * pagetable re-write after all the CPUs are booted. This check will be
+ * anyway run on individual CPUs, allowing us to get the consistent
+ * state once the SMP CPUs are up and thus make the switch to non-global
+ * mappings if required.
+ */
+static inline bool kaslr_requires_kpti(void)
+{
+	/*
+	 * E0PD does a similar job to KPTI so can be used instead
+	 * where available.
+	 */
+	if (IS_ENABLED(CONFIG_ARM64_E0PD)) {
+		u64 mmfr2 = read_sysreg_s(SYS_ID_AA64MMFR2_EL1);
+		if (cpuid_feature_extract_unsigned_field(mmfr2,
+						ID_AA64MMFR2_EL1_E0PD_SHIFT))
+			return false;
+	}
+
+	/*
+	 * Systems affected by Cavium erratum 24756 are incompatible
+	 * with KPTI.
+	 */
+	if (IS_ENABLED(CONFIG_CAVIUM_ERRATUM_27456)) {
+		extern const struct midr_range cavium_erratum_27456_cpus[];
+
+		if (is_midr_in_range_list(read_cpuid_id(),
+					  cavium_erratum_27456_cpus))
+			return false;
+	}
+
+	return true;
+}
 
 #define INIT_MM_CONTEXT(name)	\
 	.pgd = init_pg_dir,
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index d0ffb872a31a..7064cf13f226 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1620,46 +1620,6 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope)
 	return has_cpuid_feature(entry, scope);
 }
 
-/*
- * This check is triggered during the early boot before the cpufeature
- * is initialised. Checking the status on the local CPU allows the boot
- * CPU to detect the need for non-global mappings and thus avoiding a
- * pagetable re-write after all the CPUs are booted. This check will be
- * anyway run on individual CPUs, allowing us to get the consistent
- * state once the SMP CPUs are up and thus make the switch to non-global
- * mappings if required.
- */
-bool kaslr_requires_kpti(void)
-{
-	if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE))
-		return false;
-
-	/*
-	 * E0PD does a similar job to KPTI so can be used instead
-	 * where available.
-	 */
-	if (IS_ENABLED(CONFIG_ARM64_E0PD)) {
-		u64 mmfr2 = read_sysreg_s(SYS_ID_AA64MMFR2_EL1);
-		if (cpuid_feature_extract_unsigned_field(mmfr2,
-						ID_AA64MMFR2_EL1_E0PD_SHIFT))
-			return false;
-	}
-
-	/*
-	 * Systems affected by Cavium erratum 24756 are incompatible
-	 * with KPTI.
-	 */
-	if (IS_ENABLED(CONFIG_CAVIUM_ERRATUM_27456)) {
-		extern const struct midr_range cavium_erratum_27456_cpus[];
-
-		if (is_midr_in_range_list(read_cpuid_id(),
-					  cavium_erratum_27456_cpus))
-			return false;
-	}
-
-	return kaslr_enabled();
-}
-
 static bool __meltdown_safe = true;
 static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
 
@@ -1712,7 +1672,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
 	}
 
 	/* Useful for KASLR robustness */
-	if (kaslr_requires_kpti()) {
+	if (kaslr_enabled() && kaslr_requires_kpti()) {
 		if (!__kpti_forced) {
 			str = "KASLR";
 			__kpti_forced = 1;
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 97d2143669cf..0ef45d1927b3 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -288,7 +288,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 	 * mappings from the start, avoiding the cost of rewriting
 	 * everything later.
 	 */
-	arm64_use_ng_mappings = kaslr_requires_kpti();
+	arm64_use_ng_mappings = kaslr_enabled() && kaslr_requires_kpti();
 
 	early_fixmap_init();
 	early_ioremap_init();
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:08 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:08 +0100
Subject: [PATCH v8 22/43] arm64: mm: avoid fixmap for early swapper_pg_dir updates
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-67-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Early in the boot, when .rodata is still writable, we can poke
swapper_pg_dir entries directly, and there is no need to go through the
fixmap. After a future patch, we will enter the kernel with
swapper_pg_dir already active, and early swapper_pg_dir updates for
creating the fixmap page table hierarchy itself cannot go through the
fixmap for obvious reaons. So let's keep track of whether rodata is
writable, and update the descriptor directly in that case.

As the same reasoning applies to early KASAN init, make the function
noinstr as well.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/mm/mmu.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 14a62c773201..9758f7e3f4b6 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -55,6 +55,8 @@ EXPORT_SYMBOL(kimage_voffset);
 
 u32 __boot_cpu_mode[] = { BOOT_CPU_MODE_EL2, BOOT_CPU_MODE_EL1 };
 
+static bool rodata_is_rw __ro_after_init = true;
+
 /*
  * The booting CPU updates the failed status @__early_cpu_boot_status,
  * with MMU turned off.
@@ -71,10 +73,21 @@ EXPORT_SYMBOL(empty_zero_page);
 static DEFINE_SPINLOCK(swapper_pgdir_lock);
 static DEFINE_MUTEX(fixmap_lock);
 
-void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
+void noinstr set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
 {
 	pgd_t *fixmap_pgdp;
 
+	/*
+	 * Don't bother with the fixmap if swapper_pg_dir is still mapped
+	 * writable in the kernel mapping.
+	 */
+	if (rodata_is_rw) {
+		WRITE_ONCE(*pgdp, pgd);
+		dsb(ishst);
+		isb();
+		return;
+	}
+
 	spin_lock(&swapper_pgdir_lock);
 	fixmap_pgdp = pgd_set_fixmap(__pa_symbol(pgdp));
 	WRITE_ONCE(*fixmap_pgdp, pgd);
@@ -628,6 +641,7 @@ void mark_rodata_ro(void)
 	 * to cover NOTES and EXCEPTION_TABLE.
 	 */
 	section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata;
+	WRITE_ONCE(rodata_is_rw, false);
 	update_mapping_prot(__pa_symbol(__start_rodata), (unsigned long)__start_rodata,
 			    section_size, PAGE_KERNEL_RO);
 
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:03 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:03 +0100
Subject: [PATCH v8 17/43] arm64: mmu: Make __cpu_replace_ttbr1() out of line
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-62-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

__cpu_replace_ttbr1() is a static inline, and so it gets instantiated
wherever it is used. This is not really necessary, as it is never called
on a hot path. It also has the unfortunate side effect that the symbol
idmap_cpu_replace_ttbr1 may never be referenced from kCFI enabled C
code, and this means the type id symbol may not exist either.  This will
result in a build error once we start referring to this symbol from asm
code as well. (Note that this problem only occurs when CnP, KAsan and
suspend/resume are all disabled in the Kconfig but that is a valid
config, if unusual).

So let's just move it out of line so all callers will share the same
implementation, which will reference idmap_cpu_replace_ttbr1
unconditionally.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/mmu_context.h | 32 +-------------------
 arch/arm64/mm/mmu.c                  | 32 ++++++++++++++++++++
 2 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index 9ce4200508b1..926fbbcecbe0 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -148,37 +148,7 @@ static inline void cpu_install_ttbr0(phys_addr_t ttbr0, unsigned long t0sz)
 	isb();
 }
 
-/*
- * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD,
- * avoiding the possibility of conflicting TLB entries being allocated.
- */
-static inline void __cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap, bool cnp)
-{
-	typedef void (ttbr_replace_func)(phys_addr_t);
-	extern ttbr_replace_func idmap_cpu_replace_ttbr1;
-	ttbr_replace_func *replace_phys;
-	unsigned long daif;
-
-	/* phys_to_ttbr() zeros lower 2 bits of ttbr with 52-bit PA */
-	phys_addr_t ttbr1 = phys_to_ttbr(virt_to_phys(pgdp));
-
-	if (cnp)
-		ttbr1 |= TTBR_CNP_BIT;
-
-	replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1);
-
-	__cpu_install_idmap(idmap);
-
-	/*
-	 * We really don't want to take *any* exceptions while TTBR1 is
-	 * in the process of being replaced so mask everything.
-	 */
-	daif = local_daif_save();
-	replace_phys(ttbr1);
-	local_daif_restore(daif);
-
-	cpu_uninstall_idmap();
-}
+void __cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap, bool cnp);
 
 static inline void cpu_enable_swapper_cnp(void)
 {
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 1ac7467d34c9..f9332eea318f 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1486,3 +1486,35 @@ void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte
 {
 	set_pte_at(vma->vm_mm, addr, ptep, pte);
 }
+
+/*
+ * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD,
+ * avoiding the possibility of conflicting TLB entries being allocated.
+ */
+void __cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap, bool cnp)
+{
+	typedef void (ttbr_replace_func)(phys_addr_t);
+	extern ttbr_replace_func idmap_cpu_replace_ttbr1;
+	ttbr_replace_func *replace_phys;
+	unsigned long daif;
+
+	/* phys_to_ttbr() zeros lower 2 bits of ttbr with 52-bit PA */
+	phys_addr_t ttbr1 = phys_to_ttbr(virt_to_phys(pgdp));
+
+	if (cnp)
+		ttbr1 |= TTBR_CNP_BIT;
+
+	replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1);
+
+	__cpu_install_idmap(idmap);
+
+	/*
+	 * We really don't want to take *any* exceptions while TTBR1 is
+	 * in the process of being replaced so mask everything.
+	 */
+	daif = local_daif_save();
+	replace_phys(ttbr1);
+	local_daif_restore(daif);
+
+	cpu_uninstall_idmap();
+}
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:11 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:11 +0100
Subject: [PATCH v8 25/43] arm64: mm: Handle LVA support as a CPU feature
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-70-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Currently, we detect CPU support for 52-bit virtual addressing (LVA)
extremely early, before creating the kernel page tables or enabling the
MMU. We cannot override the feature this early, and so large virtual
addressing is always enabled on CPUs that implement support for it if
the software support for it was enabled at build time. It also means we
rely on non-trivial code in asm to deal with this feature.

Given that both the ID map and the TTBR1 mapping of the kernel image are
guaranteed to be 48-bit addressable, it is not actually necessary to
enable support this early, and instead, we can model it as a CPU
feature. That way, we can rely on code patching to get the correct
TCR.T1SZ values programmed on secondary boot and resume from suspend.

On the primary boot path, we simply enable the MMU with 48-bit virtual
addressing initially, and update TCR.T1SZ if LVA is supported from C
code, right before creating the kernel mapping. Given that TTBR1 still
points to reserved_pg_dir at this point, updating TCR.T1SZ should be
safe without the need for explicit TLB maintenance.

Since this gets rid of all accesses to the vabits_actual variable from
asm code that occurred before TCR.T1SZ had been programmed, we no longer
have a need for this variable, and we can replace it with a C expression
that produces the correct value directly, based on the value of TCR.T1SZ.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/cpufeature.h |  9 ++++++
 arch/arm64/include/asm/memory.h     | 13 ++++++++-
 arch/arm64/kernel/cpufeature.c      | 13 +++++++++
 arch/arm64/kernel/head.S            | 29 +++++---------------
 arch/arm64/kernel/image-vars.h      |  1 -
 arch/arm64/kernel/pi/map_kernel.c   |  3 ++
 arch/arm64/kernel/sleep.S           |  3 --
 arch/arm64/mm/mmu.c                 |  5 ----
 arch/arm64/mm/proc.S                |  9 +++---
 arch/arm64/tools/cpucaps            |  1 +
 10 files changed, 49 insertions(+), 37 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index e3edae1825f3..4f4dc5496ee3 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -995,6 +995,15 @@ static inline bool cpu_has_pac(void)
 					    &id_aa64isar2_override);
 }
 
+static inline bool cpu_has_lva(void)
+{
+	u64 mmfr2;
+
+	mmfr2 = read_sysreg_s(SYS_ID_AA64MMFR2_EL1);
+	return cpuid_feature_extract_unsigned_field(mmfr2,
+						    ID_AA64MMFR2_EL1_VARange_SHIFT);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 60904a6c4b42..9680d7444b3b 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -209,9 +209,20 @@
 #include <asm/boot.h>
 #include <asm/bug.h>
 #include <asm/sections.h>
+#include <asm/sysreg.h>
+
+static inline u64 __pure read_tcr(void)
+{
+	u64  tcr;
+
+	// read_sysreg() uses asm volatile, so avoid it here
+	asm("mrs %0, tcr_el1" : "=r"(tcr));
+	return tcr;
+}
 
 #if VA_BITS > 48
-extern u64			vabits_actual;
+// For reasons of #include hell, we can't use TCR_T1SZ_OFFSET/TCR_T1SZ_MASK here
+#define vabits_actual		(64 - ((read_tcr() >> 16) & 63))
 #else
 #define vabits_actual		((u64)VA_BITS)
 #endif
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 7064cf13f226..8eb8c7f7b317 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2692,6 +2692,19 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
 		.matches = has_lpa2,
 	},
+#ifdef CONFIG_ARM64_VA_BITS_52
+	{
+		.desc = "52-bit Virtual Addressing (LVA)",
+		.capability = ARM64_HAS_VA52,
+		.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
+		.sys_reg = SYS_ID_AA64MMFR2_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_width = 4,
+		.field_pos = ID_AA64MMFR2_EL1_VARange_SHIFT,
+		.matches = has_cpuid_feature,
+		.min_field_value = ID_AA64MMFR2_EL1_VARange_52,
+	},
+#endif
 	{},
 };
 
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 545b5d8976f4..e25351addfd0 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -80,7 +80,6 @@
 	 *  x19        primary_entry() .. start_kernel()        whether we entered with the MMU on
 	 *  x20        primary_entry() .. __primary_switch()    CPU boot mode
 	 *  x21        primary_entry() .. start_kernel()        FDT pointer passed at boot in x0
-	 *  x25        primary_entry() .. start_kernel()        supported VA size
 	 */
 SYM_CODE_START(primary_entry)
 	bl	record_mmu_state
@@ -125,14 +124,6 @@ SYM_CODE_START(primary_entry)
 	 * On return, the CPU will be ready for the MMU to be turned on and
 	 * the TCR will have been set.
 	 */
-#if VA_BITS > 48
-	mrs_s	x0, SYS_ID_AA64MMFR2_EL1
-	tst	x0, ID_AA64MMFR2_EL1_VARange_MASK
-	mov	x0, #VA_BITS
-	mov	x25, #VA_BITS_MIN
-	csel	x25, x25, x0, eq
-	mov	x0, x25
-#endif
 	bl	__cpu_setup			// initialise processor
 	b	__primary_switch
 SYM_CODE_END(primary_entry)
@@ -242,11 +233,6 @@ SYM_FUNC_START_LOCAL(__primary_switched)
 	mov	x0, x20
 	bl	set_cpu_boot_mode_flag
 
-#if VA_BITS > 48
-	adr_l	x8, vabits_actual		// Set this early so KASAN early init
-	str	x25, [x8]			// ... observes the correct value
-	dc	civac, x8			// Make visible to booting secondaries
-#endif
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 	bl	kasan_early_init
 #endif
@@ -376,10 +362,13 @@ SYM_FUNC_START_LOCAL(secondary_startup)
 	 * Common entry point for secondary CPUs.
 	 */
 	mov	x20, x0				// preserve boot mode
+
+#ifdef CONFIG_ARM64_VA_BITS_52
+alternative_if ARM64_HAS_VA52
 	bl	__cpu_secondary_check52bitva
-#if VA_BITS > 48
-	ldr_l	x0, vabits_actual
+alternative_else_nop_endif
 #endif
+
 	bl	__cpu_setup			// initialise processor
 	adrp	x1, swapper_pg_dir
 	adrp	x2, idmap_pg_dir
@@ -482,12 +471,8 @@ SYM_FUNC_START(__enable_mmu)
 	ret
 SYM_FUNC_END(__enable_mmu)
 
+#ifdef CONFIG_ARM64_VA_BITS_52
 SYM_FUNC_START(__cpu_secondary_check52bitva)
-#if VA_BITS > 48
-	ldr_l	x0, vabits_actual
-	cmp	x0, #52
-	b.ne	2f
-
 	mrs_s	x0, SYS_ID_AA64MMFR2_EL1
 	and	x0, x0, ID_AA64MMFR2_EL1_VARange_MASK
 	cbnz	x0, 2f
@@ -498,9 +483,9 @@ SYM_FUNC_START(__cpu_secondary_check52bitva)
 	wfi
 	b	1b
 
-#endif
 2:	ret
 SYM_FUNC_END(__cpu_secondary_check52bitva)
+#endif
 
 SYM_FUNC_START_LOCAL(__no_granule_support)
 	/* Indicate that this CPU can't boot and is stuck in the kernel */
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index e140c5bda90b..2b9d702abe0f 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -36,7 +36,6 @@ PROVIDE(__pi___memcpy			= __pi_memcpy);
 PROVIDE(__pi___memmove			= __pi_memmove);
 PROVIDE(__pi___memset			= __pi_memset);
 
-PROVIDE(__pi_vabits_actual		= vabits_actual);
 PROVIDE(__pi_id_aa64isar1_override	= id_aa64isar1_override);
 PROVIDE(__pi_id_aa64isar2_override	= id_aa64isar2_override);
 PROVIDE(__pi_id_aa64mmfr1_override	= id_aa64mmfr1_override);
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
index 4b76a007a50d..1853825aa29d 100644
--- a/arch/arm64/kernel/pi/map_kernel.c
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -165,6 +165,9 @@ asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt)
 	chosen = fdt_path_offset(fdt, chosen_str);
 	init_feature_override(boot_status, fdt, chosen);
 
+	if (VA_BITS > VA_BITS_MIN && cpu_has_lva())
+		sysreg_clear_set(tcr_el1, TCR_T1SZ_MASK, TCR_T1SZ(VA_BITS));
+
 	/*
 	 * The virtual KASLR displacement modulo 2MiB is decided by the
 	 * physical placement of the image, as otherwise, we might not be able
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index 2aa5129d8253..f093cdf71be1 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -102,9 +102,6 @@ SYM_CODE_START(cpu_resume)
 	mov	x0, xzr
 	bl	init_kernel_el
 	mov	x19, x0			// preserve boot mode
-#if VA_BITS > 48
-	ldr_l	x0, vabits_actual
-#endif
 	bl	__cpu_setup
 	/* enable the MMU early - so we can access sleep_save_stash by va */
 	adrp	x1, swapper_pg_dir
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index a3d23da92d87..ba00d0205447 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -45,11 +45,6 @@
 #define NO_CONT_MAPPINGS	BIT(1)
 #define NO_EXEC_MAPPINGS	BIT(2)	/* assumes FEAT_HPDS is not used */
 
-#if VA_BITS > 48
-u64 vabits_actual __ro_after_init = VA_BITS_MIN;
-EXPORT_SYMBOL(vabits_actual);
-#endif
-
 u64 kimage_voffset __ro_after_init;
 EXPORT_SYMBOL(kimage_voffset);
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 55c366dbda8f..d104ddab26a4 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -397,8 +397,6 @@ SYM_FUNC_END(idmap_kpti_install_ng_mappings)
  *
  *	Initialise the processor for turning the MMU on.
  *
- * Input:
- *	x0 - actual number of VA bits (ignored unless VA_BITS > 48)
  * Output:
  *	Return in x0 the value of the SCTLR_EL1 register.
  */
@@ -422,16 +420,17 @@ SYM_FUNC_START(__cpu_setup)
 	mair	.req	x17
 	tcr	.req	x16
 	mov_q	mair, MAIR_EL1_SET
-	mov_q	tcr, TCR_T0SZ(IDMAP_VA_BITS) | TCR_T1SZ(VA_BITS) | TCR_CACHE_FLAGS | \
+	mov_q	tcr, TCR_T0SZ(IDMAP_VA_BITS) | TCR_T1SZ(VA_BITS_MIN) | TCR_CACHE_FLAGS | \
 		     TCR_SMP_FLAGS | TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
 		     TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS
 
 	tcr_clear_errata_bits tcr, x9, x5
 
 #ifdef CONFIG_ARM64_VA_BITS_52
-	sub		x9, xzr, x0
-	add		x9, x9, #64
+	mov		x9, #64 - VA_BITS
+alternative_if ARM64_HAS_VA52
 	tcr_set_t1sz	tcr, x9
+alternative_else_nop_endif
 #endif
 
 	/*
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index b912b1409fc0..b370d808b3ec 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -50,6 +50,7 @@ HAS_STAGE2_FWB
 HAS_TCR2
 HAS_TIDCP1
 HAS_TLB_RANGE
+HAS_VA52
 HAS_VIRT_HOST_EXTN
 HAS_WFXT
 HW_DBM
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:07 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:07 +0100
Subject: [PATCH v8 21/43] arm64: kernel: Create initial ID map from C code
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-66-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The asm code that creates the initial ID map is rather intricate and
hard to follow. This is problematic because it makes adding support for
things like LPA2 or WXN more difficult than necessary. Also, it is
parameterized like the rest of the MM code to run with a configurable
number of levels, which is rather pointless, given that all AArch64 CPUs
implement support for 48-bit virtual addressing, and that many systems
exist with DRAM located outside of the 39-bit addressable range, which
is the only smaller VA size that is widely used, and we need additional
tricks to make things work in that combination.

So let's bite the bullet, and rip out all the asm macros, and fiddly
code, and replace it with a C implementation based on the newly added
routines for creating the early kernel VA mappings. And while at it,
create the initial ID map based on 48-bit virtual addressing as well,
regardless of the number of configured levels for the kernel proper.

Note that this code may execute with the MMU and caches disabled, and is
therefore not permitted to make unaligned accesses. This shouldn't
generally happen in any case for the algorithm as implemented, but to be
sure, let's pass -mstrict-align to the compiler just in case.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/assembler.h      |  14 -
 arch/arm64/include/asm/kernel-pgtable.h |  50 ++--
 arch/arm64/include/asm/mmu_context.h    |   6 +-
 arch/arm64/kernel/head.S                | 267 ++------------------
 arch/arm64/kernel/image-vars.h          |   1 +
 arch/arm64/kernel/pi/Makefile           |   3 +
 arch/arm64/kernel/pi/map_kernel.c       |  18 ++
 arch/arm64/kernel/pi/map_range.c        |  12 +
 arch/arm64/kernel/pi/pi.h               |   4 +
 arch/arm64/mm/mmu.c                     |   5 -
 arch/arm64/mm/proc.S                    |   3 +-
 11 files changed, 88 insertions(+), 295 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 513787e43329..6a467c694039 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -345,20 +345,6 @@ alternative_cb_end
 	bfi	\valreg, \t1sz, #TCR_T1SZ_OFFSET, #TCR_TxSZ_WIDTH
 	.endm
 
-/*
- * idmap_get_t0sz - get the T0SZ value needed to cover the ID map
- *
- * Calculate the maximum allowed value for TCR_EL1.T0SZ so that the
- * entire ID map region can be mapped. As T0SZ == (64 - #bits used),
- * this number conveniently equals the number of leading zeroes in
- * the physical address of _end.
- */
-	.macro	idmap_get_t0sz, reg
-	adrp	\reg, _end
-	orr	\reg, \reg, #(1 << VA_BITS_MIN) - 1
-	clz	\reg, \reg
-	.endm
-
 /*
  * tcr_compute_pa_size - set TCR.(I)PS to the highest supported
  * ID_AA64MMFR0_EL1.PARange value
diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index f1fc98a233d5..bf05a77873a4 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -29,6 +29,7 @@
 #define SWAPPER_TABLE_SHIFT	(SWAPPER_BLOCK_SHIFT + PAGE_SHIFT - 3)
 
 #define SWAPPER_PGTABLE_LEVELS		(CONFIG_PGTABLE_LEVELS - SWAPPER_SKIP_LEVEL)
+#define INIT_IDMAP_PGTABLE_LEVELS	(IDMAP_LEVELS - SWAPPER_SKIP_LEVEL)
 
 #define IDMAP_VA_BITS		48
 #define IDMAP_LEVELS		ARM64_HW_PGTABLE_LEVELS(IDMAP_VA_BITS)
@@ -48,44 +49,39 @@
 #define EARLY_ENTRIES(vstart, vend, shift, add) \
 	(SPAN_NR_ENTRIES(vstart, vend, shift) + (add))
 
-#define EARLY_LEVEL(lvl, vstart, vend, add)	\
-	(SWAPPER_PGTABLE_LEVELS > lvl ? EARLY_ENTRIES(vstart, vend, SWAPPER_BLOCK_SHIFT + lvl * (PAGE_SHIFT - 3), add) : 0)
+#define EARLY_LEVEL(lvl, lvls, vstart, vend, add)	\
+	(lvls > lvl ? EARLY_ENTRIES(vstart, vend, SWAPPER_BLOCK_SHIFT + lvl * (PAGE_SHIFT - 3), add) : 0)
 
-#define EARLY_PAGES(vstart, vend, add) (1 	/* PGDIR page */				\
-	+ EARLY_LEVEL(3, (vstart), (vend), add) /* each entry needs a next level page table */	\
-	+ EARLY_LEVEL(2, (vstart), (vend), add)	/* each entry needs a next level page table */	\
-	+ EARLY_LEVEL(1, (vstart), (vend), add))/* each entry needs a next level page table */
-#define INIT_DIR_SIZE (PAGE_SIZE * (EARLY_PAGES(KIMAGE_VADDR, _end, EXTRA_PAGE) + EARLY_SEGMENT_EXTRA_PAGES))
+#define EARLY_PAGES(lvls, vstart, vend, add) (1 	/* PGDIR page */				\
+	+ EARLY_LEVEL(3, (lvls), (vstart), (vend), add) /* each entry needs a next level page table */	\
+	+ EARLY_LEVEL(2, (lvls), (vstart), (vend), add)	/* each entry needs a next level page table */	\
+	+ EARLY_LEVEL(1, (lvls), (vstart), (vend), add))/* each entry needs a next level page table */
+#define INIT_DIR_SIZE (PAGE_SIZE * (EARLY_PAGES(SWAPPER_PGTABLE_LEVELS, KIMAGE_VADDR, _end, EXTRA_PAGE) \
+				    + EARLY_SEGMENT_EXTRA_PAGES))
 
-/* the initial ID map may need two extra pages if it needs to be extended */
-#if VA_BITS < 48
-#define INIT_IDMAP_DIR_SIZE	((INIT_IDMAP_DIR_PAGES + 2) * PAGE_SIZE)
-#else
-#define INIT_IDMAP_DIR_SIZE	(INIT_IDMAP_DIR_PAGES * PAGE_SIZE)
-#endif
-#define INIT_IDMAP_DIR_PAGES	EARLY_PAGES(KIMAGE_VADDR, _end + MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE, 1)
+#define INIT_IDMAP_DIR_PAGES	(EARLY_PAGES(INIT_IDMAP_PGTABLE_LEVELS, KIMAGE_VADDR, _end, 1))
+#define INIT_IDMAP_DIR_SIZE	((INIT_IDMAP_DIR_PAGES + EARLY_IDMAP_EXTRA_PAGES) * PAGE_SIZE)
+
+#define INIT_IDMAP_FDT_PAGES	(EARLY_PAGES(INIT_IDMAP_PGTABLE_LEVELS, 0UL, UL(MAX_FDT_SIZE), 1) - 1)
+#define INIT_IDMAP_FDT_SIZE	((INIT_IDMAP_FDT_PAGES + EARLY_IDMAP_EXTRA_FDT_PAGES) * PAGE_SIZE)
 
 /* The number of segments in the kernel image (text, rodata, inittext, initdata, data+bss) */
 #define KERNEL_SEGMENT_COUNT	5
 
 #if SWAPPER_BLOCK_SIZE > SEGMENT_ALIGN
 #define EARLY_SEGMENT_EXTRA_PAGES (KERNEL_SEGMENT_COUNT + 1)
-#else
-#define EARLY_SEGMENT_EXTRA_PAGES 0
-#endif
-
 /*
- * Initial memory map attributes.
+ * The initial ID map consists of the kernel image, mapped as two separate
+ * segments, and may appear misaligned wrt the swapper block size. This means
+ * we need 3 additional pages. The DT could straddle a swapper block boundary,
+ * so it may need 2.
  */
-#define SWAPPER_PTE_FLAGS	(PTE_TYPE_PAGE | PTE_AF | PTE_SHARED | PTE_UXN)
-#define SWAPPER_PMD_FLAGS	(PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S | PTE_UXN)
-
-#ifdef CONFIG_ARM64_4K_PAGES
-#define SWAPPER_RW_MMUFLAGS	(PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS | PTE_WRITE)
-#define SWAPPER_RX_MMUFLAGS	(SWAPPER_RW_MMUFLAGS | PMD_SECT_RDONLY)
+#define EARLY_IDMAP_EXTRA_PAGES		3
+#define EARLY_IDMAP_EXTRA_FDT_PAGES	2
 #else
-#define SWAPPER_RW_MMUFLAGS	(PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS | PTE_WRITE)
-#define SWAPPER_RX_MMUFLAGS	(SWAPPER_RW_MMUFLAGS | PTE_RDONLY)
+#define EARLY_SEGMENT_EXTRA_PAGES	0
+#define EARLY_IDMAP_EXTRA_PAGES		0
+#define EARLY_IDMAP_EXTRA_FDT_PAGES	0
 #endif
 
 #endif	/* __ASM_KERNEL_PGTABLE_H */
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index 926fbbcecbe0..a8a89a0f2867 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -61,11 +61,9 @@ static inline void cpu_switch_mm(pgd_t *pgd, struct mm_struct *mm)
 }
 
 /*
- * TCR.T0SZ value to use when the ID map is active. Usually equals
- * TCR_T0SZ(VA_BITS), unless system RAM is positioned very high in
- * physical memory, in which case it will be smaller.
+ * TCR.T0SZ value to use when the ID map is active.
  */
-extern int idmap_t0sz;
+#define idmap_t0sz	TCR_T0SZ(IDMAP_VA_BITS)
 
 /*
  * Ensure TCR.T0SZ is set to the provided value.
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index a1c29d64e875..545b5d8976f4 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -80,26 +80,42 @@
 	 *  x19        primary_entry() .. start_kernel()        whether we entered with the MMU on
 	 *  x20        primary_entry() .. __primary_switch()    CPU boot mode
 	 *  x21        primary_entry() .. start_kernel()        FDT pointer passed at boot in x0
-	 *  x22        create_idmap() .. start_kernel()         ID map VA of the DT blob
 	 *  x25        primary_entry() .. start_kernel()        supported VA size
-	 *  x28        create_idmap()                           callee preserved temp register
 	 */
 SYM_CODE_START(primary_entry)
 	bl	record_mmu_state
 	bl	preserve_boot_args
-	bl	create_idmap
+
+	adrp	x1, early_init_stack
+	mov	sp, x1
+	mov	x29, xzr
+	adrp	x0, init_idmap_pg_dir
+	bl	__pi_create_init_idmap
+
+	/*
+	 * If the page tables have been populated with non-cacheable
+	 * accesses (MMU disabled), invalidate those tables again to
+	 * remove any speculatively loaded cache lines.
+	 */
+	cbnz	x19, 0f
+	dmb     sy
+	mov	x1, x0				// end of used region
+	adrp    x0, init_idmap_pg_dir
+	adr_l	x2, dcache_inval_poc
+	blr	x2
+	b	1f
 
 	/*
 	 * If we entered with the MMU and caches on, clean the ID mapped part
 	 * of the primary boot code to the PoC so we can safely execute it with
 	 * the MMU off.
 	 */
-	cbz	x19, 0f
-	adrp	x0, __idmap_text_start
+0:	adrp	x0, __idmap_text_start
 	adr_l	x1, __idmap_text_end
 	adr_l	x2, dcache_clean_poc
 	blr	x2
-0:	mov	x0, x19
+
+1:	mov	x0, x19
 	bl	init_kernel_el			// w0=cpu_boot_mode
 	mov	x20, x0
 
@@ -175,238 +191,6 @@ SYM_CODE_START_LOCAL(preserve_boot_args)
 	ret
 SYM_CODE_END(preserve_boot_args)
 
-/*
- * Macro to populate page table entries, these entries can be pointers to the next level
- * or last level entries pointing to physical memory.
- *
- *	tbl:	page table address
- *	rtbl:	pointer to page table or physical memory
- *	index:	start index to write
- *	eindex:	end index to write - [index, eindex] written to
- *	flags:	flags for pagetable entry to or in
- *	inc:	increment to rtbl between each entry
- *	tmp1:	temporary variable
- *
- * Preserves:	tbl, eindex, flags, inc
- * Corrupts:	index, tmp1
- * Returns:	rtbl
- */
-	.macro populate_entries, tbl, rtbl, index, eindex, flags, inc, tmp1
-.Lpe\@:	phys_to_pte \tmp1, \rtbl
-	orr	\tmp1, \tmp1, \flags	// tmp1 = table entry
-	str	\tmp1, [\tbl, \index, lsl #3]
-	add	\rtbl, \rtbl, \inc	// rtbl = pa next level
-	add	\index, \index, #1
-	cmp	\index, \eindex
-	b.ls	.Lpe\@
-	.endm
-
-/*
- * Compute indices of table entries from virtual address range. If multiple entries
- * were needed in the previous page table level then the next page table level is assumed
- * to be composed of multiple pages. (This effectively scales the end index).
- *
- *	vstart:	virtual address of start of range
- *	vend:	virtual address of end of range - we map [vstart, vend]
- *	shift:	shift used to transform virtual address into index
- *	order:  #imm 2log(number of entries in page table)
- *	istart:	index in table corresponding to vstart
- *	iend:	index in table corresponding to vend
- *	count:	On entry: how many extra entries were required in previous level, scales
- *			  our end index.
- *		On exit: returns how many extra entries required for next page table level
- *
- * Preserves:	vstart, vend
- * Returns:	istart, iend, count
- */
-	.macro compute_indices, vstart, vend, shift, order, istart, iend, count
-	ubfx	\istart, \vstart, \shift, \order
-	ubfx	\iend, \vend, \shift, \order
-	add	\iend, \iend, \count, lsl \order
-	sub	\count, \iend, \istart
-	.endm
-
-/*
- * Map memory for specified virtual address range. Each level of page table needed supports
- * multiple entries. If a level requires n entries the next page table level is assumed to be
- * formed from n pages.
- *
- *	tbl:	location of page table
- *	rtbl:	address to be used for first level page table entry (typically tbl + PAGE_SIZE)
- *	vstart:	virtual address of start of range
- *	vend:	virtual address of end of range - we map [vstart, vend - 1]
- *	flags:	flags to use to map last level entries
- *	phys:	physical address corresponding to vstart - physical memory is contiguous
- *	order:  #imm 2log(number of entries in PGD table)
- *
- * If extra_shift is set, an extra level will be populated if the end address does
- * not fit in 'extra_shift' bits. This assumes vend is in the TTBR0 range.
- *
- * Temporaries:	istart, iend, tmp, count, sv - these need to be different registers
- * Preserves:	vstart, flags
- * Corrupts:	tbl, rtbl, vend, istart, iend, tmp, count, sv
- */
-	.macro map_memory, tbl, rtbl, vstart, vend, flags, phys, order, istart, iend, tmp, count, sv, extra_shift
-	sub \vend, \vend, #1
-	add \rtbl, \tbl, #PAGE_SIZE
-	mov \count, #0
-
-	.ifnb	\extra_shift
-	tst	\vend, #~((1 << (\extra_shift)) - 1)
-	b.eq	.L_\@
-	compute_indices \vstart, \vend, #\extra_shift, #(PAGE_SHIFT - 3), \istart, \iend, \count
-	mov \sv, \rtbl
-	populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
-	mov \tbl, \sv
-	.endif
-.L_\@:
-	compute_indices \vstart, \vend, #PGDIR_SHIFT, #\order, \istart, \iend, \count
-	mov \sv, \rtbl
-	populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
-	mov \tbl, \sv
-
-#if SWAPPER_PGTABLE_LEVELS > 3
-	compute_indices \vstart, \vend, #PUD_SHIFT, #(PAGE_SHIFT - 3), \istart, \iend, \count
-	mov \sv, \rtbl
-	populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
-	mov \tbl, \sv
-#endif
-
-#if SWAPPER_PGTABLE_LEVELS > 2
-	compute_indices \vstart, \vend, #SWAPPER_TABLE_SHIFT, #(PAGE_SHIFT - 3), \istart, \iend, \count
-	mov \sv, \rtbl
-	populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
-	mov \tbl, \sv
-#endif
-
-	compute_indices \vstart, \vend, #SWAPPER_BLOCK_SHIFT, #(PAGE_SHIFT - 3), \istart, \iend, \count
-	bic \rtbl, \phys, #SWAPPER_BLOCK_SIZE - 1
-	populate_entries \tbl, \rtbl, \istart, \iend, \flags, #SWAPPER_BLOCK_SIZE, \tmp
-	.endm
-
-/*
- * Remap a subregion created with the map_memory macro with modified attributes
- * or output address. The entire remapped region must have been covered in the
- * invocation of map_memory.
- *
- * x0: last level table address (returned in first argument to map_memory)
- * x1: start VA of the existing mapping
- * x2: start VA of the region to update
- * x3: end VA of the region to update (exclusive)
- * x4: start PA associated with the region to update
- * x5: attributes to set on the updated region
- * x6: order of the last level mappings
- */
-SYM_FUNC_START_LOCAL(remap_region)
-	sub	x3, x3, #1		// make end inclusive
-
-	// Get the index offset for the start of the last level table
-	lsr	x1, x1, x6
-	bfi	x1, xzr, #0, #PAGE_SHIFT - 3
-
-	// Derive the start and end indexes into the last level table
-	// associated with the provided region
-	lsr	x2, x2, x6
-	lsr	x3, x3, x6
-	sub	x2, x2, x1
-	sub	x3, x3, x1
-
-	mov	x1, #1
-	lsl	x6, x1, x6		// block size at this level
-
-	populate_entries x0, x4, x2, x3, x5, x6, x7
-	ret
-SYM_FUNC_END(remap_region)
-
-SYM_FUNC_START_LOCAL(create_idmap)
-	mov	x28, lr
-	/*
-	 * The ID map carries a 1:1 mapping of the physical address range
-	 * covered by the loaded image, which could be anywhere in DRAM. This
-	 * means that the required size of the VA (== PA) space is decided at
-	 * boot time, and could be more than the configured size of the VA
-	 * space for ordinary kernel and user space mappings.
-	 *
-	 * There are three cases to consider here:
-	 * - 39 <= VA_BITS < 48, and the ID map needs up to 48 VA bits to cover
-	 *   the placement of the image. In this case, we configure one extra
-	 *   level of translation on the fly for the ID map only. (This case
-	 *   also covers 42-bit VA/52-bit PA on 64k pages).
-	 *
-	 * - VA_BITS == 48, and the ID map needs more than 48 VA bits. This can
-	 *   only happen when using 64k pages, in which case we need to extend
-	 *   the root level table rather than add a level. Note that we can
-	 *   treat this case as 'always extended' as long as we take care not
-	 *   to program an unsupported T0SZ value into the TCR register.
-	 *
-	 * - Combinations that would require two additional levels of
-	 *   translation are not supported, e.g., VA_BITS==36 on 16k pages, or
-	 *   VA_BITS==39/4k pages with 5-level paging, where the input address
-	 *   requires more than 47 or 48 bits, respectively.
-	 */
-#if (VA_BITS < 48)
-#define IDMAP_PGD_ORDER	(VA_BITS - PGDIR_SHIFT)
-#define EXTRA_SHIFT	(PGDIR_SHIFT + PAGE_SHIFT - 3)
-
-	/*
-	 * If VA_BITS < 48, we have to configure an additional table level.
-	 * First, we have to verify our assumption that the current value of
-	 * VA_BITS was chosen such that all translation levels are fully
-	 * utilised, and that lowering T0SZ will always result in an additional
-	 * translation level to be configured.
-	 */
-#if VA_BITS != EXTRA_SHIFT
-#error "Mismatch between VA_BITS and page size/number of translation levels"
-#endif
-#else
-#define IDMAP_PGD_ORDER	(PHYS_MASK_SHIFT - PGDIR_SHIFT)
-#define EXTRA_SHIFT
-	/*
-	 * If VA_BITS == 48, we don't have to configure an additional
-	 * translation level, but the top-level table has more entries.
-	 */
-#endif
-	adrp	x0, init_idmap_pg_dir
-	adrp	x3, _text
-	adrp	x6, _end + MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE
-	mov_q	x7, SWAPPER_RX_MMUFLAGS
-
-	map_memory x0, x1, x3, x6, x7, x3, IDMAP_PGD_ORDER, x10, x11, x12, x13, x14, EXTRA_SHIFT
-
-	/* Remap [.init].data, BSS and the kernel page tables r/w in the ID map */
-	adrp	x1, _text
-	adrp	x2, __initdata_begin
-	adrp	x3, _end
-	bic	x4, x2, #SWAPPER_BLOCK_SIZE - 1
-	mov_q	x5, SWAPPER_RW_MMUFLAGS
-	mov	x6, #SWAPPER_BLOCK_SHIFT
-	bl	remap_region
-
-	/* Remap the FDT after the kernel image */
-	adrp	x1, _text
-	adrp	x22, _end + SWAPPER_BLOCK_SIZE
-	bic	x2, x22, #SWAPPER_BLOCK_SIZE - 1
-	bfi	x22, x21, #0, #SWAPPER_BLOCK_SHIFT		// remapped FDT address
-	add	x3, x2, #MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE
-	bic	x4, x21, #SWAPPER_BLOCK_SIZE - 1
-	mov_q	x5, SWAPPER_RW_MMUFLAGS
-	mov	x6, #SWAPPER_BLOCK_SHIFT
-	bl	remap_region
-
-	/*
-	 * Since the page tables have been populated with non-cacheable
-	 * accesses (MMU disabled), invalidate those tables again to
-	 * remove any speculatively loaded cache lines.
-	 */
-	cbnz	x19, 0f				// skip cache invalidation if MMU is on
-	dmb	sy
-
-	adrp	x0, init_idmap_pg_dir
-	adrp	x1, init_idmap_pg_end
-	bl	dcache_inval_poc
-0:	ret	x28
-SYM_FUNC_END(create_idmap)
-
 	/*
 	 * Initialize CPU registers with task-specific and cpu-specific context.
 	 *
@@ -729,11 +513,6 @@ SYM_FUNC_START_LOCAL(__no_granule_support)
 SYM_FUNC_END(__no_granule_support)
 
 SYM_FUNC_START_LOCAL(__primary_switch)
-	mrs		x1, tcr_el1
-	mov		x2, #64 - VA_BITS
-	tcr_set_t0sz	x1, x2
-	msr		tcr_el1, x1
-
 	adrp	x1, reserved_pg_dir
 	adrp	x2, init_idmap_pg_dir
 	bl	__enable_mmu
@@ -742,7 +521,7 @@ SYM_FUNC_START_LOCAL(__primary_switch)
 	mov	sp, x1
 	mov	x29, xzr
 	mov	x0, x20				// pass the full boot status
-	mov	x1, x22				// pass the low FDT mapping
+	mov	x1, x21				// pass the FDT
 	bl	__pi_early_map_kernel		// Map and relocate the kernel
 
 	ldr	x8, =__primary_switched
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index e566b32f9c22..941a14c05184 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -52,6 +52,7 @@ PROVIDE(__pi_cavium_erratum_27456_cpus	= cavium_erratum_27456_cpus);
 PROVIDE(__pi__ctype			= _ctype);
 PROVIDE(__pi_memstart_offset_seed	= memstart_offset_seed);
 
+PROVIDE(__pi_init_idmap_pg_dir		= init_idmap_pg_dir);
 PROVIDE(__pi_init_pg_dir		= init_pg_dir);
 PROVIDE(__pi_init_pg_end		= init_pg_end);
 
diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile
index 8c2f80a46b93..4393b41f0b71 100644
--- a/arch/arm64/kernel/pi/Makefile
+++ b/arch/arm64/kernel/pi/Makefile
@@ -11,6 +11,9 @@ KBUILD_CFLAGS	:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) -fpie \
 		   -fno-asynchronous-unwind-tables -fno-unwind-tables \
 		   $(call cc-option,-fno-addrsig)
 
+# this code may run with the MMU off so disable unaligned accesses
+CFLAGS_map_range.o += -mstrict-align
+
 # remove SCS flags from all objects in this directory
 KBUILD_CFLAGS	:= $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS))
 # disable LTO
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
index f206373b28b0..f86e878d366d 100644
--- a/arch/arm64/kernel/pi/map_kernel.c
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -128,6 +128,22 @@ static void __init map_kernel(u64 kaslr_offset, u64 va_offset, int root_level)
 	}
 }
 
+static void __init map_fdt(u64 fdt)
+{
+	static u8 ptes[INIT_IDMAP_FDT_SIZE] __initdata __aligned(PAGE_SIZE);
+	u64 efdt = fdt + MAX_FDT_SIZE;
+	u64 ptep = (u64)ptes;
+
+	/*
+	 * Map up to MAX_FDT_SIZE bytes, but avoid overlap with
+	 * the kernel image.
+	 */
+	map_range(&ptep, fdt, (u64)_text > fdt ? min((u64)_text, efdt) : efdt,
+		  fdt, PAGE_KERNEL, IDMAP_ROOT_LEVEL,
+		  (pte_t *)init_idmap_pg_dir, false, 0);
+	dsb(ishst);
+}
+
 asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt)
 {
 	static char const chosen_str[] __initconst = "/chosen";
@@ -136,6 +152,8 @@ asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt)
 	int root_level = 4 - CONFIG_PGTABLE_LEVELS;
 	int chosen;
 
+	map_fdt((u64)fdt);
+
 	/* Clear BSS and the initial page tables */
 	memset(__bss_start, 0, (u64)init_pg_end - (u64)__bss_start);
 
diff --git a/arch/arm64/kernel/pi/map_range.c b/arch/arm64/kernel/pi/map_range.c
index c31feda18f47..79e4f6a2efe1 100644
--- a/arch/arm64/kernel/pi/map_range.c
+++ b/arch/arm64/kernel/pi/map_range.c
@@ -86,3 +86,15 @@ void __init map_range(u64 *pte, u64 start, u64 end, u64 pa, pgprot_t prot,
 		tbl++;
 	}
 }
+
+asmlinkage u64 __init create_init_idmap(pgd_t *pg_dir)
+{
+	u64 ptep = (u64)pg_dir + PAGE_SIZE;
+
+	map_range(&ptep, (u64)_stext, (u64)__initdata_begin, (u64)_stext,
+		  PAGE_KERNEL_ROX, IDMAP_ROOT_LEVEL, (pte_t *)pg_dir, false, 0);
+	map_range(&ptep, (u64)__initdata_begin, (u64)_end, (u64)__initdata_begin,
+		  PAGE_KERNEL, IDMAP_ROOT_LEVEL, (pte_t *)pg_dir, false, 0);
+
+	return ptep;
+}
diff --git a/arch/arm64/kernel/pi/pi.h b/arch/arm64/kernel/pi/pi.h
index d307c58e9741..1ea282a5f96a 100644
--- a/arch/arm64/kernel/pi/pi.h
+++ b/arch/arm64/kernel/pi/pi.h
@@ -21,6 +21,8 @@ static inline void *prel64_to_pointer(const prel64_t *offset)
 
 extern bool dynamic_scs_is_enabled;
 
+extern pgd_t init_idmap_pg_dir[];
+
 void init_feature_override(u64 boot_status, const void *fdt, int chosen);
 u64 kaslr_early_init(void *fdt, int chosen);
 void relocate_kernel(u64 offset);
@@ -30,3 +32,5 @@ void map_range(u64 *pgd, u64 start, u64 end, u64 pa, pgprot_t prot,
 	       int level, pte_t *tbl, bool may_use_cont, u64 va_offset);
 
 asmlinkage void early_map_kernel(u64 boot_status, void *fdt);
+
+asmlinkage u64 create_init_idmap(pgd_t *pgd);
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index a991f195592b..14a62c773201 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -45,8 +45,6 @@
 #define NO_CONT_MAPPINGS	BIT(1)
 #define NO_EXEC_MAPPINGS	BIT(2)	/* assumes FEAT_HPDS is not used */
 
-int idmap_t0sz __ro_after_init;
-
 #if VA_BITS > 48
 u64 vabits_actual __ro_after_init = VA_BITS_MIN;
 EXPORT_SYMBOL(vabits_actual);
@@ -793,8 +791,6 @@ void __init paging_init(void)
 	pgd_t *pgdp = pgd_set_fixmap(__pa_symbol(swapper_pg_dir));
 	extern pgd_t init_idmap_pg_dir[];
 
-	idmap_t0sz = 63UL - __fls(__pa_symbol(_end) | GENMASK(VA_BITS_MIN - 1, 0));
-
 	map_kernel(pgdp);
 	map_mem(pgdp);
 
@@ -809,7 +805,6 @@ void __init paging_init(void)
 	memblock_allow_resize();
 
 	create_idmap();
-	idmap_t0sz = TCR_T0SZ(IDMAP_VA_BITS);
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 47ede52bb900..55c366dbda8f 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -200,7 +200,8 @@ SYM_FUNC_ALIAS(__pi_idmap_cpu_replace_ttbr1, idmap_cpu_replace_ttbr1)
 
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 
-#define KPTI_NG_PTE_FLAGS	(PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS | PTE_WRITE)
+#define KPTI_NG_PTE_FLAGS	(PTE_ATTRINDX(MT_NORMAL) | PTE_TYPE_PAGE | \
+				 PTE_AF | PTE_SHARED | PTE_UXN | PTE_WRITE)
 
 	.pushsection ".idmap.text", "a"
 
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:12 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:12 +0100
Subject: [PATCH v8 26/43] arm64: mm: Add feature override support for LVA
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-71-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Add support for overriding the VARange field of the MMFR2 CPU ID
register. This permits the associated LVA feature to be overridden early
enough for the boot code that creates the kernel mapping to take it into
account.

Given that LPA2 implies LVA, disabling the latter should disable the
former as well. So override the ID_AA64MMFR0.TGran field of the current
page size as well if it advertises support for 52-bit addressing.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/assembler.h    | 17 ++++++-----
 arch/arm64/include/asm/cpufeature.h   |  4 +++
 arch/arm64/kernel/cpufeature.c        |  8 +++--
 arch/arm64/kernel/image-vars.h        |  2 ++
 arch/arm64/kernel/pi/idreg-override.c | 31 ++++++++++++++++++++
 5 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 6a467c694039..68a99b116256 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -576,18 +576,21 @@ alternative_endif
 	.endm
 
 /*
- * Offset ttbr1 to allow for 48-bit kernel VAs set with 52-bit PTRS_PER_PGD.
+ * If the kernel is built for 52-bit virtual addressing but the hardware only
+ * supports 48 bits, we cannot program the pgdir address into TTBR1 directly,
+ * but we have to add an offset so that the TTBR1 address corresponds with the
+ * pgdir entry that covers the lowest 48-bit addressable VA.
+ *
  * orr is used as it can cover the immediate value (and is idempotent).
- * In future this may be nop'ed out when dealing with 52-bit kernel VAs.
  * 	ttbr: Value of ttbr to set, modified.
  */
 	.macro	offset_ttbr1, ttbr, tmp
 #ifdef CONFIG_ARM64_VA_BITS_52
-	mrs_s	\tmp, SYS_ID_AA64MMFR2_EL1
-	and	\tmp, \tmp, #(0xf << ID_AA64MMFR2_EL1_VARange_SHIFT)
-	cbnz	\tmp, .Lskipoffs_\@
-	orr	\ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
-.Lskipoffs_\@ :
+	mrs	\tmp, tcr_el1
+	and	\tmp, \tmp, #TCR_T1SZ_MASK
+	cmp	\tmp, #TCR_T1SZ(VA_BITS_MIN)
+	orr	\tmp, \ttbr, #TTBR1_BADDR_4852_OFFSET
+	csel	\ttbr, \tmp, \ttbr, eq
 #endif
 	.endm
 
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 4f4dc5496ee3..a2ac31aecdd9 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -906,7 +906,9 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)
 s64 arm64_ftr_safe_value(const struct arm64_ftr_bits *ftrp, s64 new, s64 cur);
 struct arm64_ftr_reg *get_arm64_ftr_reg(u32 sys_id);
 
+extern struct arm64_ftr_override id_aa64mmfr0_override;
 extern struct arm64_ftr_override id_aa64mmfr1_override;
+extern struct arm64_ftr_override id_aa64mmfr2_override;
 extern struct arm64_ftr_override id_aa64pfr0_override;
 extern struct arm64_ftr_override id_aa64pfr1_override;
 extern struct arm64_ftr_override id_aa64zfr0_override;
@@ -1000,6 +1002,8 @@ static inline bool cpu_has_lva(void)
 	u64 mmfr2;
 
 	mmfr2 = read_sysreg_s(SYS_ID_AA64MMFR2_EL1);
+	mmfr2 &= ~id_aa64mmfr2_override.mask;
+	mmfr2 |= id_aa64mmfr2_override.val;
 	return cpuid_feature_extract_unsigned_field(mmfr2,
 						    ID_AA64MMFR2_EL1_VARange_SHIFT);
 }
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 8eb8c7f7b317..ed9670d8360c 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -655,7 +655,9 @@ static const struct arm64_ftr_bits ftr_raz[] = {
 #define ARM64_FTR_REG(id, table)		\
 	__ARM64_FTR_REG_OVERRIDE(#id, id, table, &no_override)
 
+struct arm64_ftr_override id_aa64mmfr0_override;
 struct arm64_ftr_override id_aa64mmfr1_override;
+struct arm64_ftr_override id_aa64mmfr2_override;
 struct arm64_ftr_override id_aa64pfr0_override;
 struct arm64_ftr_override id_aa64pfr1_override;
 struct arm64_ftr_override id_aa64zfr0_override;
@@ -719,10 +721,12 @@ static const struct __ftr_reg_entry {
 			       &id_aa64isar2_override),
 
 	/* Op1 = 0, CRn = 0, CRm = 7 */
-	ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0),
+	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0,
+			       &id_aa64mmfr0_override),
 	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64MMFR1_EL1, ftr_id_aa64mmfr1,
 			       &id_aa64mmfr1_override),
-	ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
+	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2,
+			       &id_aa64mmfr2_override),
 	ARM64_FTR_REG(SYS_ID_AA64MMFR3_EL1, ftr_id_aa64mmfr3),
 
 	/* Op1 = 1, CRn = 0, CRm = 0 */
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 2b9d702abe0f..ff81f809a240 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -38,7 +38,9 @@ PROVIDE(__pi___memset			= __pi_memset);
 
 PROVIDE(__pi_id_aa64isar1_override	= id_aa64isar1_override);
 PROVIDE(__pi_id_aa64isar2_override	= id_aa64isar2_override);
+PROVIDE(__pi_id_aa64mmfr0_override	= id_aa64mmfr0_override);
 PROVIDE(__pi_id_aa64mmfr1_override	= id_aa64mmfr1_override);
+PROVIDE(__pi_id_aa64mmfr2_override	= id_aa64mmfr2_override);
 PROVIDE(__pi_id_aa64pfr0_override	= id_aa64pfr0_override);
 PROVIDE(__pi_id_aa64pfr1_override	= id_aa64pfr1_override);
 PROVIDE(__pi_id_aa64smfr0_override	= id_aa64smfr0_override);
diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
index 1884bd936c0d..aad399796e81 100644
--- a/arch/arm64/kernel/pi/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -59,6 +59,35 @@ static const struct ftr_set_desc mmfr1 __prel64_initconst = {
 	},
 };
 
+
+static bool __init mmfr2_varange_filter(u64 val)
+{
+	int __maybe_unused feat;
+
+	if (val)
+		return false;
+
+#ifdef CONFIG_ARM64_LPA2
+	feat = cpuid_feature_extract_signed_field(read_sysreg(id_aa64mmfr0_el1),
+						  ID_AA64MMFR0_EL1_TGRAN_SHIFT);
+	if (feat >= ID_AA64MMFR0_EL1_TGRAN_LPA2) {
+		id_aa64mmfr0_override.val |=
+			(ID_AA64MMFR0_EL1_TGRAN_LPA2 - 1) << ID_AA64MMFR0_EL1_TGRAN_SHIFT;
+		id_aa64mmfr0_override.mask |= 0xfU << ID_AA64MMFR0_EL1_TGRAN_SHIFT;
+	}
+#endif
+	return true;
+}
+
+static const struct ftr_set_desc mmfr2 __prel64_initconst = {
+	.name		= "id_aa64mmfr2",
+	.override	= &id_aa64mmfr2_override,
+	.fields		= {
+		FIELD("varange", ID_AA64MMFR2_EL1_VARange_SHIFT, mmfr2_varange_filter),
+		{}
+	},
+};
+
 static bool __init pfr0_sve_filter(u64 val)
 {
 	/*
@@ -167,6 +196,7 @@ static const struct ftr_set_desc sw_features __prel64_initconst = {
 static const
 PREL64(const struct ftr_set_desc, reg) regs[] __prel64_initconst = {
 	{ &mmfr1	},
+	{ &mmfr2	},
 	{ &pfr0 	},
 	{ &pfr1 	},
 	{ &isar1	},
@@ -192,6 +222,7 @@ static const struct {
 	{ "arm64.nomte",		"id_aa64pfr1.mte=0" },
 	{ "nokaslr",			"arm64_sw.nokaslr=1" },
 	{ "rodata=off",			"arm64_sw.rodataoff=1" },
+	{ "arm64.nolva",		"id_aa64mmfr2.varange=0" },
 };
 
 static int __init parse_hexdigit(const char *p, u64 *v)
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:13 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:13 +0100
Subject: [PATCH v8 27/43] arm64: Avoid #define'ing PTE_MAYBE_NG to 0x0 for asm use
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-72-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The PROT_* macros resolve to expressions that are only valid in C and
not in assembler, and so they are only usable from C code. Currently, we
make an exception for the permission indirection init code in proc.S,
which doesn't care about the bits that are conditionally set, and so we
just #define PTE_MAYBE_NG to 0x0 for any assembler file that includes
these definitions.

This is dodgy because this means that PROT_NORMAL and friends is
generally available in asm code, but defined in a way that deviates from
the definition that C code will observe, which might lead to hard to
diagnose issues down the road.

So instead, #define PTE_MAYBE_NG only in the place where the PIE
constants are evaluated, and #undef it again right after. This allows us
to drop the #define from pgtable-prot.h, and avoid the risk of deviating
definitions between asm and C.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgtable-prot.h |  4 ----
 arch/arm64/mm/proc.S                  | 13 +++++++++++++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 483dbfa39c4c..63ced9ccec21 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -57,10 +57,6 @@
 #define _PAGE_READONLY_EXEC	(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN)
 #define _PAGE_EXECONLY		(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
 
-#ifdef __ASSEMBLY__
-#define PTE_MAYBE_NG	0
-#endif
-
 #ifndef __ASSEMBLY__
 
 #include <asm/cpufeature.h>
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index d104ddab26a4..6e1b2bc41a9f 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -456,11 +456,24 @@ alternative_else_nop_endif
 	ubfx	x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
 	cbz	x1, .Lskip_indirection
 
+	/*
+	 * The PROT_* macros describing the various memory types may resolve to
+	 * C expressions if they include the PTE_MAYBE_* macros, and so they
+	 * can only be used from C code. The PIE_E* constants below are also
+	 * defined in terms of those macros, but will mask out those
+	 * PTE_MAYBE_* constants, whether they are set or not. So #define them
+	 * as 0x0 here so we can evaluate the PIE_E* constants in asm context.
+	 */
+
+#define PTE_MAYBE_NG		0
+
 	mov_q	x0, PIE_E0
 	msr	REG_PIRE0_EL1, x0
 	mov_q	x0, PIE_E1
 	msr	REG_PIR_EL1, x0
 
+#undef PTE_MAYBE_NG
+
 	mov	x0, TCR2_EL1x_PIE
 	msr	REG_TCR2_EL1, x0
 
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:14 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:14 +0100
Subject: [PATCH v8 28/43] arm64: Add ESR decoding for exceptions involving
 translation level -1
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-73-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The LPA2 feature introduces new FSC values to report abort exceptions
related to translation level -1. Define these and wire them up.

Reuse the new ESR FSC classification helpers that arrived via the KVM
arm64 tree, and update the one for translation faults to check
specifically for a translation fault at level -1. (Access flag or
permission faults cannot occur at level -1 because they alway involve a
descriptor at the superior level so changing those helpers is not
needed).

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/esr.h         | 13 ++++-----
 arch/arm64/include/asm/kvm_emulate.h | 10 ++-----
 arch/arm64/mm/fault.c                | 30 +++++++-------------
 3 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 353fe08546cf..81606bf7d5ac 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -117,15 +117,9 @@
 #define ESR_ELx_FSC_ACCESS	(0x08)
 #define ESR_ELx_FSC_FAULT	(0x04)
 #define ESR_ELx_FSC_PERM	(0x0C)
-#define ESR_ELx_FSC_SEA_TTW0	(0x14)
-#define ESR_ELx_FSC_SEA_TTW1	(0x15)
-#define ESR_ELx_FSC_SEA_TTW2	(0x16)
-#define ESR_ELx_FSC_SEA_TTW3	(0x17)
+#define ESR_ELx_FSC_SEA_TTW(n)	(0x14 + (n))
 #define ESR_ELx_FSC_SECC	(0x18)
-#define ESR_ELx_FSC_SECC_TTW0	(0x1c)
-#define ESR_ELx_FSC_SECC_TTW1	(0x1d)
-#define ESR_ELx_FSC_SECC_TTW2	(0x1e)
-#define ESR_ELx_FSC_SECC_TTW3	(0x1f)
+#define ESR_ELx_FSC_SECC_TTW(n)	(0x1c + (n))
 
 /* ISS field definitions for Data Aborts */
 #define ESR_ELx_ISV_SHIFT	(24)
@@ -394,6 +388,9 @@ static inline bool esr_is_data_abort(unsigned long esr)
 
 static inline bool esr_fsc_is_translation_fault(unsigned long esr)
 {
+	/* Translation fault, level -1 */
+	if ((esr & ESR_ELx_FSC) == 0b101011)
+		return true;
 	return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT;
 }
 
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index b804fe832184..6f5b41c70103 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -425,15 +425,9 @@ static __always_inline bool kvm_vcpu_abt_issea(const struct kvm_vcpu *vcpu)
 {
 	switch (kvm_vcpu_trap_get_fault(vcpu)) {
 	case ESR_ELx_FSC_EXTABT:
-	case ESR_ELx_FSC_SEA_TTW0:
-	case ESR_ELx_FSC_SEA_TTW1:
-	case ESR_ELx_FSC_SEA_TTW2:
-	case ESR_ELx_FSC_SEA_TTW3:
+	case ESR_ELx_FSC_SEA_TTW(-1) ... ESR_ELx_FSC_SEA_TTW(3):
 	case ESR_ELx_FSC_SECC:
-	case ESR_ELx_FSC_SECC_TTW0:
-	case ESR_ELx_FSC_SECC_TTW1:
-	case ESR_ELx_FSC_SECC_TTW2:
-	case ESR_ELx_FSC_SECC_TTW3:
+	case ESR_ELx_FSC_SECC_TTW(-1) ... ESR_ELx_FSC_SECC_TTW(3):
 		return true;
 	default:
 		return false;
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 55f6455a8284..60265ede48fe 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -257,16 +257,14 @@ static bool is_el1_data_abort(unsigned long esr)
 static inline bool is_el1_permission_fault(unsigned long addr, unsigned long esr,
 					   struct pt_regs *regs)
 {
-	unsigned long fsc_type = esr & ESR_ELx_FSC_TYPE;
-
 	if (!is_el1_data_abort(esr) && !is_el1_instruction_abort(esr))
 		return false;
 
-	if (fsc_type == ESR_ELx_FSC_PERM)
+	if (esr_fsc_is_permission_fault(esr))
 		return true;
 
 	if (is_ttbr0_addr(addr) && system_uses_ttbr0_pan())
-		return fsc_type == ESR_ELx_FSC_FAULT &&
+		return esr_fsc_is_translation_fault(esr) &&
 			(regs->pstate & PSR_PAN_BIT);
 
 	return false;
@@ -279,8 +277,7 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr,
 	unsigned long flags;
 	u64 par, dfsc;
 
-	if (!is_el1_data_abort(esr) ||
-	    (esr & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT)
+	if (!is_el1_data_abort(esr) || !esr_fsc_is_translation_fault(esr))
 		return false;
 
 	local_irq_save(flags);
@@ -301,7 +298,7 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr,
 	 * treat the translation fault as spurious.
 	 */
 	dfsc = FIELD_GET(SYS_PAR_EL1_FST, par);
-	return (dfsc & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT;
+	return !esr_fsc_is_translation_fault(dfsc);
 }
 
 static void die_kernel_fault(const char *msg, unsigned long addr,
@@ -368,11 +365,6 @@ static bool is_el1_mte_sync_tag_check_fault(unsigned long esr)
 	return false;
 }
 
-static bool is_translation_fault(unsigned long esr)
-{
-	return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT;
-}
-
 static void __do_kernel_fault(unsigned long addr, unsigned long esr,
 			      struct pt_regs *regs)
 {
@@ -405,7 +397,7 @@ static void __do_kernel_fault(unsigned long addr, unsigned long esr,
 	} else if (addr < PAGE_SIZE) {
 		msg = "NULL pointer dereference";
 	} else {
-		if (is_translation_fault(esr) &&
+		if (esr_fsc_is_translation_fault(esr) &&
 		    kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
 			return;
 
@@ -782,18 +774,18 @@ static const struct fault_info fault_info[] = {
 	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level 1 translation fault"	},
 	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level 2 translation fault"	},
 	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level 3 translation fault"	},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 8"			},
+	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 0 access flag fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 1 access flag fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 access flag fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 3 access flag fault"	},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 12"			},
+	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 0 permission fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 1 permission fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 permission fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 3 permission fault"	},
 	{ do_sea,		SIGBUS,  BUS_OBJERR,	"synchronous external abort"	},
 	{ do_tag_check_fault,	SIGSEGV, SEGV_MTESERR,	"synchronous tag check fault"	},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 18"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 19"			},
+	{ do_sea,		SIGKILL, SI_KERNEL,	"level -1 (translation table walk)"	},
 	{ do_sea,		SIGKILL, SI_KERNEL,	"level 0 (translation table walk)"	},
 	{ do_sea,		SIGKILL, SI_KERNEL,	"level 1 (translation table walk)"	},
 	{ do_sea,		SIGKILL, SI_KERNEL,	"level 2 (translation table walk)"	},
@@ -801,7 +793,7 @@ static const struct fault_info fault_info[] = {
 	{ do_sea,		SIGBUS,  BUS_OBJERR,	"synchronous parity or ECC error" },	// Reserved when RAS is implemented
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 25"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 26"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 27"			},
+	{ do_sea,		SIGKILL, SI_KERNEL,	"level -1 synchronous parity error (translation table walk)"	},	// Reserved when RAS is implemented
 	{ do_sea,		SIGKILL, SI_KERNEL,	"level 0 synchronous parity error (translation table walk)"	},	// Reserved when RAS is implemented
 	{ do_sea,		SIGKILL, SI_KERNEL,	"level 1 synchronous parity error (translation table walk)"	},	// Reserved when RAS is implemented
 	{ do_sea,		SIGKILL, SI_KERNEL,	"level 2 synchronous parity error (translation table walk)"	},	// Reserved when RAS is implemented
@@ -815,9 +807,9 @@ static const struct fault_info fault_info[] = {
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 38"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 39"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 40"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 41"			},
+	{ do_bad,		SIGKILL, SI_KERNEL,	"level -1 address size fault"	},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 42"			},
-	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 43"			},
+	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level -1 translation fault"	},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 44"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 45"			},
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 46"			},
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:15 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:15 +0100
Subject: [PATCH v8 29/43] arm64: mm: Wire up TCR.DS bit to PTE shareability fields
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-74-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

When LPA2 is enabled, bits 8 and 9 of page and block descriptors become
part of the output address instead of carrying shareability attributes
for the region in question.

So avoid setting these bits if TCR.DS == 1, which means LPA2 is enabled.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/Kconfig                     |  4 ++++
 arch/arm64/include/asm/pgtable-hwdef.h |  1 +
 arch/arm64/include/asm/pgtable-prot.h  | 16 ++++++++++++++--
 arch/arm64/mm/mmap.c                   |  4 ++++
 arch/arm64/mm/proc.S                   |  2 ++
 5 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aa7c1d435139..8c2c36fffcf5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1377,6 +1377,10 @@ config ARM64_PA_BITS
 	default 48 if ARM64_PA_BITS_48
 	default 52 if ARM64_PA_BITS_52
 
+config ARM64_LPA2
+	def_bool y
+	depends on ARM64_PA_BITS_52 && !ARM64_64K_PAGES
+
 choice
 	prompt "Endianness"
 	default CPU_LITTLE_ENDIAN
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index e4944d517c99..b770f98fc0b5 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -284,6 +284,7 @@
 #define TCR_E0PD1		(UL(1) << 56)
 #define TCR_TCMA0		(UL(1) << 57)
 #define TCR_TCMA1		(UL(1) << 58)
+#define TCR_DS			(UL(1) << 59)
 
 /*
  * TTBR.
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 63ced9ccec21..dd9ee67d1d87 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -30,8 +30,8 @@
 #define _PROT_DEFAULT		(PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
 #define _PROT_SECT_DEFAULT	(PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
 
-#define PROT_DEFAULT		(_PROT_DEFAULT | PTE_MAYBE_NG)
-#define PROT_SECT_DEFAULT	(_PROT_SECT_DEFAULT | PMD_MAYBE_NG)
+#define PROT_DEFAULT		(PTE_TYPE_PAGE | PTE_MAYBE_NG | PTE_MAYBE_SHARED | PTE_AF)
+#define PROT_SECT_DEFAULT	(PMD_TYPE_SECT | PMD_MAYBE_NG | PMD_MAYBE_SHARED | PMD_SECT_AF)
 
 #define PROT_DEVICE_nGnRnE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
 #define PROT_DEVICE_nGnRE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
@@ -67,7 +67,19 @@ extern bool arm64_use_ng_mappings;
 #define PTE_MAYBE_NG		(arm64_use_ng_mappings ? PTE_NG : 0)
 #define PMD_MAYBE_NG		(arm64_use_ng_mappings ? PMD_SECT_NG : 0)
 
+#ifndef CONFIG_ARM64_LPA2
 #define lpa2_is_enabled()	false
+#define PTE_MAYBE_SHARED	PTE_SHARED
+#define PMD_MAYBE_SHARED	PMD_SECT_S
+#else
+static inline bool __pure lpa2_is_enabled(void)
+{
+	return read_tcr() & TCR_DS;
+}
+
+#define PTE_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PTE_SHARED)
+#define PMD_MAYBE_SHARED	(lpa2_is_enabled() ? 0 : PMD_SECT_S)
+#endif
 
 /*
  * If we have userspace only BTI we don't want to mark kernel pages
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 645fe60d000f..642bdf908b22 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -73,6 +73,10 @@ static int __init adjust_protection_map(void)
 		protection_map[VM_EXEC | VM_SHARED] = PAGE_EXECONLY;
 	}
 
+	if (lpa2_is_enabled())
+		for (int i = 0; i < ARRAY_SIZE(protection_map); i++)
+			pgprot_val(protection_map[i]) &= ~PTE_SHARED;
+
 	return 0;
 }
 arch_initcall(adjust_protection_map);
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 6e1b2bc41a9f..7c46f8cfd6ae 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -466,6 +466,7 @@ alternative_else_nop_endif
 	 */
 
 #define PTE_MAYBE_NG		0
+#define PTE_MAYBE_SHARED	0
 
 	mov_q	x0, PIE_E0
 	msr	REG_PIRE0_EL1, x0
@@ -473,6 +474,7 @@ alternative_else_nop_endif
 	msr	REG_PIR_EL1, x0
 
 #undef PTE_MAYBE_NG
+#undef PTE_MAYBE_SHARED
 
 	mov	x0, TCR2_EL1x_PIE
 	msr	REG_TCR2_EL1, x0
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:06 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:06 +0100
Subject: [PATCH v8 20/43] arm64: pgtable: Decouple PGDIR size macros from
 PGD/PUD/PMD levels
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-65-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The mapping from PGD/PUD/PMD to levels and shifts is very confusing,
given that, due to folding, the shifts may be equal for different
levels, if the macros are even #define'd to begin with.

In a subsequent patch, we will modify the ID mapping code to decouple
the number of levels from the kernel's view of how these types are
folded, so prepare for this by reformulating the macros without the use
of these types.

Instead, use SWAPPER_BLOCK_SHIFT as the base quantity, and derive it
from either PAGE_SHIFT or PMD_SHIFT, which -if defined at all- are
defined unambiguously for a given page size, regardless of the number of
configured levels.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/kernel-pgtable.h | 65 ++++++--------------
 1 file changed, 19 insertions(+), 46 deletions(-)

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 742a4b2778f7..f1fc98a233d5 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -13,27 +13,22 @@
 #include <asm/sparsemem.h>
 
 /*
- * The linear mapping and the start of memory are both 2M aligned (per
- * the arm64 booting.txt requirements). Hence we can use section mapping
- * with 4K (section size = 2M) but not with 16K (section size = 32M) or
- * 64K (section size = 512M).
+ * The physical and virtual addresses of the start of the kernel image are
+ * equal modulo 2 MiB (per the arm64 booting.txt requirements). Hence we can
+ * use section mapping with 4K (section size = 2M) but not with 16K (section
+ * size = 32M) or 64K (section size = 512M).
  */
-
-/*
- * The idmap and swapper page tables need some space reserved in the kernel
- * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
- * map the kernel. With the 64K page configuration, swapper and idmap need to
- * map to pte level. The swapper also maps the FDT (see __create_page_tables
- * for more information). Note that the number of ID map translation levels
- * could be increased on the fly if system RAM is out of reach for the default
- * VA range, so pages required to map highest possible PA are reserved in all
- * cases.
- */
-#ifdef CONFIG_ARM64_4K_PAGES
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
+#if defined(PMD_SIZE) && PMD_SIZE <= MIN_KIMG_ALIGN
+#define SWAPPER_BLOCK_SHIFT	PMD_SHIFT
+#define SWAPPER_SKIP_LEVEL	1
 #else
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
+#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
+#define SWAPPER_SKIP_LEVEL	0
 #endif
+#define SWAPPER_BLOCK_SIZE	(UL(1) << SWAPPER_BLOCK_SHIFT)
+#define SWAPPER_TABLE_SHIFT	(SWAPPER_BLOCK_SHIFT + PAGE_SHIFT - 3)
+
+#define SWAPPER_PGTABLE_LEVELS		(CONFIG_PGTABLE_LEVELS - SWAPPER_SKIP_LEVEL)
 
 #define IDMAP_VA_BITS		48
 #define IDMAP_LEVELS		ARM64_HW_PGTABLE_LEVELS(IDMAP_VA_BITS)
@@ -53,24 +48,13 @@
 #define EARLY_ENTRIES(vstart, vend, shift, add) \
 	(SPAN_NR_ENTRIES(vstart, vend, shift) + (add))
 
-#define EARLY_PGDS(vstart, vend, add) (EARLY_ENTRIES(vstart, vend, PGDIR_SHIFT, add))
-
-#if SWAPPER_PGTABLE_LEVELS > 3
-#define EARLY_PUDS(vstart, vend, add) (EARLY_ENTRIES(vstart, vend, PUD_SHIFT, add))
-#else
-#define EARLY_PUDS(vstart, vend, add) (0)
-#endif
+#define EARLY_LEVEL(lvl, vstart, vend, add)	\
+	(SWAPPER_PGTABLE_LEVELS > lvl ? EARLY_ENTRIES(vstart, vend, SWAPPER_BLOCK_SHIFT + lvl * (PAGE_SHIFT - 3), add) : 0)
 
-#if SWAPPER_PGTABLE_LEVELS > 2
-#define EARLY_PMDS(vstart, vend, add) (EARLY_ENTRIES(vstart, vend, SWAPPER_TABLE_SHIFT, add))
-#else
-#define EARLY_PMDS(vstart, vend, add) (0)
-#endif
-
-#define EARLY_PAGES(vstart, vend, add) ( 1 			/* PGDIR page */				\
-			+ EARLY_PGDS((vstart), (vend), add) 	/* each PGDIR needs a next level page table */	\
-			+ EARLY_PUDS((vstart), (vend), add)	/* each PUD needs a next level page table */	\
-			+ EARLY_PMDS((vstart), (vend), add))	/* each PMD needs a next level page table */
+#define EARLY_PAGES(vstart, vend, add) (1 	/* PGDIR page */				\
+	+ EARLY_LEVEL(3, (vstart), (vend), add) /* each entry needs a next level page table */	\
+	+ EARLY_LEVEL(2, (vstart), (vend), add)	/* each entry needs a next level page table */	\
+	+ EARLY_LEVEL(1, (vstart), (vend), add))/* each entry needs a next level page table */
 #define INIT_DIR_SIZE (PAGE_SIZE * (EARLY_PAGES(KIMAGE_VADDR, _end, EXTRA_PAGE) + EARLY_SEGMENT_EXTRA_PAGES))
 
 /* the initial ID map may need two extra pages if it needs to be extended */
@@ -81,17 +65,6 @@
 #endif
 #define INIT_IDMAP_DIR_PAGES	EARLY_PAGES(KIMAGE_VADDR, _end + MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE, 1)
 
-/* Initial memory map size */
-#ifdef CONFIG_ARM64_4K_PAGES
-#define SWAPPER_BLOCK_SHIFT	PMD_SHIFT
-#define SWAPPER_BLOCK_SIZE	PMD_SIZE
-#define SWAPPER_TABLE_SHIFT	PUD_SHIFT
-#else
-#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
-#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
-#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
-#endif
-
 /* The number of segments in the kernel image (text, rodata, inittext, initdata, data+bss) */
 #define KERNEL_SEGMENT_COUNT	5
 
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:16 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:16 +0100
Subject: [PATCH v8 30/43] arm64: mm: Add LPA2 support to phys<->pte conversion routines
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-75-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

In preparation for enabling LPA2 support, introduce the mask values for
converting between physical addresses and their representations in a
page table descriptor.

While at it, move the pte_to_phys asm macro into its only user, so that
we can freely modify it to use its input value register as a temp
register.

For LPA2, the PTE_ADDR_MASK contains two non-adjacent sequences of zero
bits, which means it no longer fits into the immediate field of an
ordinary ALU instruction. So let's redefine it to include the bits in
between as well, and only use it when converting from physical address
to PTE representation, where the distinction does not matter. Also
update the name accordingly to emphasize this.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/assembler.h     | 16 ++--------------
 arch/arm64/include/asm/pgtable-hwdef.h | 10 +++++++---
 arch/arm64/include/asm/pgtable.h       |  5 +++--
 arch/arm64/mm/proc.S                   |  8 ++++++++
 4 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 68a99b116256..7eedcb36ebe0 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -612,25 +612,13 @@ alternative_endif
 
 	.macro	phys_to_pte, pte, phys
 #ifdef CONFIG_ARM64_PA_BITS_52
-	/*
-	 * We assume \phys is 64K aligned and this is guaranteed by only
-	 * supporting this configuration with 64K pages.
-	 */
-	orr	\pte, \phys, \phys, lsr #36
-	and	\pte, \pte, #PTE_ADDR_MASK
+	orr	\pte, \phys, \phys, lsr #PTE_ADDR_HIGH_SHIFT
+	and	\pte, \pte, #PHYS_TO_PTE_ADDR_MASK
 #else
 	mov	\pte, \phys
 #endif
 	.endm
 
-	.macro	pte_to_phys, phys, pte
-	and	\phys, \pte, #PTE_ADDR_MASK
-#ifdef CONFIG_ARM64_PA_BITS_52
-	orr	\phys, \phys, \phys, lsl #PTE_ADDR_HIGH_SHIFT
-	and	\phys, \phys, GENMASK_ULL(PHYS_MASK_SHIFT - 1, PAGE_SHIFT)
-#endif
-	.endm
-
 /*
  * tcr_clear_errata_bits - Clear TCR bits that trigger an errata on this CPU.
  */
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index b770f98fc0b5..4426f48f2ae0 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -155,13 +155,17 @@
 #define PTE_PXN			(_AT(pteval_t, 1) << 53)	/* Privileged XN */
 #define PTE_UXN			(_AT(pteval_t, 1) << 54)	/* User XN */
 
-#define PTE_ADDR_LOW		(((_AT(pteval_t, 1) << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
+#define PTE_ADDR_LOW		(((_AT(pteval_t, 1) << (50 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
 #ifdef CONFIG_ARM64_PA_BITS_52
+#ifdef CONFIG_ARM64_64K_PAGES
 #define PTE_ADDR_HIGH		(_AT(pteval_t, 0xf) << 12)
-#define PTE_ADDR_MASK		(PTE_ADDR_LOW | PTE_ADDR_HIGH)
 #define PTE_ADDR_HIGH_SHIFT	36
+#define PHYS_TO_PTE_ADDR_MASK	(PTE_ADDR_LOW | PTE_ADDR_HIGH)
 #else
-#define PTE_ADDR_MASK		PTE_ADDR_LOW
+#define PTE_ADDR_HIGH		(_AT(pteval_t, 0x3) << 8)
+#define PTE_ADDR_HIGH_SHIFT	42
+#define PHYS_TO_PTE_ADDR_MASK	GENMASK_ULL(49, 8)
+#endif
 #endif
 
 /*
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 522c21348ae8..61de7b1516bc 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -80,15 +80,16 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 #ifdef CONFIG_ARM64_PA_BITS_52
 static inline phys_addr_t __pte_to_phys(pte_t pte)
 {
+	pte_val(pte) &= ~PTE_MAYBE_SHARED;
 	return (pte_val(pte) & PTE_ADDR_LOW) |
 		((pte_val(pte) & PTE_ADDR_HIGH) << PTE_ADDR_HIGH_SHIFT);
 }
 static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
 {
-	return (phys | (phys >> PTE_ADDR_HIGH_SHIFT)) & PTE_ADDR_MASK;
+	return (phys | (phys >> PTE_ADDR_HIGH_SHIFT)) & PHYS_TO_PTE_ADDR_MASK;
 }
 #else
-#define __pte_to_phys(pte)	(pte_val(pte) & PTE_ADDR_MASK)
+#define __pte_to_phys(pte)	(pte_val(pte) & PTE_ADDR_LOW)
 #define __phys_to_pte_val(phys)	(phys)
 #endif
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 7c46f8cfd6ae..d03434b7bca5 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -205,6 +205,14 @@ SYM_FUNC_ALIAS(__pi_idmap_cpu_replace_ttbr1, idmap_cpu_replace_ttbr1)
 
 	.pushsection ".idmap.text", "a"
 
+	.macro	pte_to_phys, phys, pte
+	and	\phys, \pte, #PTE_ADDR_LOW
+#ifdef CONFIG_ARM64_PA_BITS_52
+	and	\pte, \pte, #PTE_ADDR_HIGH
+	orr	\phys, \phys, \pte, lsl #PTE_ADDR_HIGH_SHIFT
+#endif
+	.endm
+
 	.macro	kpti_mk_tbl_ng, type, num_entries
 	add	end_\type\()p, cur_\type\()p, #\num_entries * 8
 .Ldo_\type:
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:01 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:01 +0100
Subject: [PATCH v8 15/43] arm64: head: move memstart_offset_seed handling to C code
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-60-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Now that we can set BSS variables from the early code running from the
ID map, we can set memstart_offset_seed directly from the C code that
derives the value instead of passing it back and forth between C and asm
code.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/head.S           | 7 -------
 arch/arm64/kernel/image-vars.h     | 1 +
 arch/arm64/kernel/pi/kaslr_early.c | 4 ++++
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b320702032a7..aa7766dc64d9 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -82,7 +82,6 @@
 	 *  x21        primary_entry() .. start_kernel()        FDT pointer passed at boot in x0
 	 *  x22        create_idmap() .. start_kernel()         ID map VA of the DT blob
 	 *  x23        __primary_switch()                       physical misalignment/KASLR offset
-	 *  x24        __primary_switch()                       linear map KASLR seed
 	 *  x25        primary_entry() .. start_kernel()        supported VA size
 	 *  x28        create_idmap()                           callee preserved temp register
 	 */
@@ -483,11 +482,6 @@ SYM_FUNC_START_LOCAL(__primary_switched)
 	str	x25, [x8]			// ... observes the correct value
 	dc	civac, x8			// Make visible to booting secondaries
 #endif
-
-#ifdef CONFIG_RANDOMIZE_BASE
-	adrp	x5, memstart_offset_seed	// Save KASLR linear map seed
-	strh	w24, [x5, :lo12:memstart_offset_seed]
-#endif
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 	bl	kasan_early_init
 #endif
@@ -779,7 +773,6 @@ SYM_FUNC_START_LOCAL(__primary_switch)
 #ifdef CONFIG_RANDOMIZE_BASE
 	mov	x0, x22
 	bl	__pi_kaslr_early_init
-	and	x24, x0, #SZ_2M - 1		// capture memstart offset seed
 	bic	x0, x0, #SZ_2M - 1
 	orr	x23, x23, x0			// record kernel offset
 #endif
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index eacc3d167733..8d96052079e8 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -46,6 +46,7 @@ PROVIDE(__pi_id_aa64smfr0_override	= id_aa64smfr0_override);
 PROVIDE(__pi_id_aa64zfr0_override	= id_aa64zfr0_override);
 PROVIDE(__pi_arm64_sw_feature_override	= arm64_sw_feature_override);
 PROVIDE(__pi__ctype			= _ctype);
+PROVIDE(__pi_memstart_offset_seed	= memstart_offset_seed);
 
 #ifdef CONFIG_KVM
 
diff --git a/arch/arm64/kernel/pi/kaslr_early.c b/arch/arm64/kernel/pi/kaslr_early.c
index f2305e276ec3..eeecee7ffd6f 100644
--- a/arch/arm64/kernel/pi/kaslr_early.c
+++ b/arch/arm64/kernel/pi/kaslr_early.c
@@ -16,6 +16,8 @@
 #include <asm/memory.h>
 #include <asm/pgtable.h>
 
+extern u16 memstart_offset_seed;
+
 static u64 __init get_kaslr_seed(void *fdt)
 {
 	static char const chosen_str[] __initconst = "chosen";
@@ -51,6 +53,8 @@ asmlinkage u64 __init kaslr_early_init(void *fdt)
 			return 0;
 	}
 
+	memstart_offset_seed = seed & U16_MAX;
+
 	/*
 	 * OK, so we are proceeding with KASLR enabled. Calculate a suitable
 	 * kernel image offset from the seed. Let's place the kernel in the
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:17 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:17 +0100
Subject: [PATCH v8 31/43] arm64: mm: Add definitions to support 5 levels of paging
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-76-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Add the required types and descriptor accessors to support 5 levels of
paging in the common code. This is one of the prerequisites for
supporting 52-bit virtual addressing with 4k pages.

Note that this does not cover the code that handles kernel mappings or
the fixmap.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgalloc.h       | 41 ++++++++++
 arch/arm64/include/asm/pgtable-hwdef.h | 22 +++++-
 arch/arm64/include/asm/pgtable-types.h |  6 ++
 arch/arm64/include/asm/pgtable.h       | 82 +++++++++++++++++++-
 arch/arm64/mm/mmu.c                    | 31 +++++++-
 arch/arm64/mm/pgd.c                    | 15 +++-
 6 files changed, 188 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 237224484d0f..cae8c648f462 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -60,6 +60,47 @@ static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
 }
 #endif	/* CONFIG_PGTABLE_LEVELS > 3 */
 
+#if CONFIG_PGTABLE_LEVELS > 4
+
+static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t p4dp, pgdval_t prot)
+{
+	if (pgtable_l5_enabled())
+		set_pgd(pgdp, __pgd(__phys_to_pgd_val(p4dp) | prot));
+}
+
+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgdp, p4d_t *p4dp)
+{
+	pgdval_t pgdval = PGD_TYPE_TABLE;
+
+	pgdval |= (mm == &init_mm) ? PGD_TABLE_UXN : PGD_TABLE_PXN;
+	__pgd_populate(pgdp, __pa(p4dp), pgdval);
+}
+
+static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+	gfp_t gfp = GFP_PGTABLE_USER;
+
+	if (mm == &init_mm)
+		gfp = GFP_PGTABLE_KERNEL;
+	return (p4d_t *)get_zeroed_page(gfp);
+}
+
+static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
+{
+	if (!pgtable_l5_enabled())
+		return;
+	BUG_ON((unsigned long)p4d & (PAGE_SIZE-1));
+	free_page((unsigned long)p4d);
+}
+
+#define __p4d_free_tlb(tlb, p4d, addr)  p4d_free((tlb)->mm, p4d)
+#else
+static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t p4dp, pgdval_t prot)
+{
+	BUILD_BUG();
+}
+#endif	/* CONFIG_PGTABLE_LEVELS > 4 */
+
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
 extern void pgd_free(struct mm_struct *mm, pgd_t *pgdp);
 
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 4426f48f2ae0..ef207a0d4f0d 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -26,10 +26,10 @@
 #define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
 
 /*
- * Size mapped by an entry at level n ( 0 <= n <= 3)
+ * Size mapped by an entry at level n ( -1 <= n <= 3)
  * We map (PAGE_SHIFT - 3) at all translation levels and PAGE_SHIFT bits
  * in the final page. The maximum number of translation levels supported by
- * the architecture is 4. Hence, starting at level n, we have further
+ * the architecture is 5. Hence, starting at level n, we have further
  * ((4 - n) - 1) levels of translation excluding the offset within the page.
  * So, the total number of bits mapped by an entry at level n is :
  *
@@ -62,9 +62,16 @@
 #define PTRS_PER_PUD		(1 << (PAGE_SHIFT - 3))
 #endif
 
+#if CONFIG_PGTABLE_LEVELS > 4
+#define P4D_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(0)
+#define P4D_SIZE		(_AC(1, UL) << P4D_SHIFT)
+#define P4D_MASK		(~(P4D_SIZE-1))
+#define PTRS_PER_P4D		(1 << (PAGE_SHIFT - 3))
+#endif
+
 /*
  * PGDIR_SHIFT determines the size a top-level page table entry can map
- * (depending on the configuration, this level can be 0, 1 or 2).
+ * (depending on the configuration, this level can be -1, 0, 1 or 2).
  */
 #define PGDIR_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - CONFIG_PGTABLE_LEVELS)
 #define PGDIR_SIZE		(_AC(1, UL) << PGDIR_SHIFT)
@@ -87,6 +94,15 @@
 /*
  * Hardware page table definitions.
  *
+ * Level -1 descriptor (PGD).
+ */
+#define PGD_TYPE_TABLE		(_AT(pgdval_t, 3) << 0)
+#define PGD_TABLE_BIT		(_AT(pgdval_t, 1) << 1)
+#define PGD_TYPE_MASK		(_AT(pgdval_t, 3) << 0)
+#define PGD_TABLE_PXN		(_AT(pgdval_t, 1) << 59)
+#define PGD_TABLE_UXN		(_AT(pgdval_t, 1) << 60)
+
+/*
  * Level 0 descriptor (P4D).
  */
 #define P4D_TYPE_TABLE		(_AT(p4dval_t, 3) << 0)
diff --git a/arch/arm64/include/asm/pgtable-types.h b/arch/arm64/include/asm/pgtable-types.h
index b8f158ae2527..6d6d4065b0cb 100644
--- a/arch/arm64/include/asm/pgtable-types.h
+++ b/arch/arm64/include/asm/pgtable-types.h
@@ -36,6 +36,12 @@ typedef struct { pudval_t pud; } pud_t;
 #define __pud(x)	((pud_t) { (x) } )
 #endif
 
+#if CONFIG_PGTABLE_LEVELS > 4
+typedef struct { p4dval_t p4d; } p4d_t;
+#define p4d_val(x)	((x).p4d)
+#define __p4d(x)	((p4d_t) { (x) } )
+#endif
+
 typedef struct { pgdval_t pgd; } pgd_t;
 #define pgd_val(x)	((x).pgd)
 #define __pgd(x)	((pgd_t) { (x) } )
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 61de7b1516bc..7eb2b933ed3c 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -808,7 +808,6 @@ static inline pud_t *p4d_pgtable(p4d_t p4d)
 #else
 
 #define p4d_page_paddr(p4d)	({ BUILD_BUG(); 0;})
-#define pgd_page_paddr(pgd)	({ BUILD_BUG(); 0;})
 
 /* Match pud_offset folding in <asm/generic/pgtable-nopud.h> */
 #define pud_set_fixmap(addr)		NULL
@@ -819,6 +818,87 @@ static inline pud_t *p4d_pgtable(p4d_t p4d)
 
 #endif  /* CONFIG_PGTABLE_LEVELS > 3 */
 
+#if CONFIG_PGTABLE_LEVELS > 4
+
+static __always_inline bool pgtable_l5_enabled(void)
+{
+	if (!alternative_has_cap_likely(ARM64_ALWAYS_BOOT))
+		return vabits_actual == VA_BITS;
+	return alternative_has_cap_unlikely(ARM64_HAS_VA52);
+}
+
+static inline bool mm_p4d_folded(const struct mm_struct *mm)
+{
+	return !pgtable_l5_enabled();
+}
+#define mm_p4d_folded  mm_p4d_folded
+
+#define p4d_ERROR(e)	\
+	pr_err("%s:%d: bad p4d %016llx.\n", __FILE__, __LINE__, p4d_val(e))
+
+#define pgd_none(pgd)		(pgtable_l5_enabled() && !pgd_val(pgd))
+#define pgd_bad(pgd)		(pgtable_l5_enabled() && !(pgd_val(pgd) & 2))
+#define pgd_present(pgd)	(!pgd_none(pgd))
+
+static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)
+{
+	if (in_swapper_pgdir(pgdp)) {
+		set_swapper_pgd(pgdp, __pgd(pgd_val(pgd)));
+		return;
+	}
+
+	WRITE_ONCE(*pgdp, pgd);
+	dsb(ishst);
+	isb();
+}
+
+static inline void pgd_clear(pgd_t *pgdp)
+{
+	if (pgtable_l5_enabled())
+		set_pgd(pgdp, __pgd(0));
+}
+
+static inline phys_addr_t pgd_page_paddr(pgd_t pgd)
+{
+	return __pgd_to_phys(pgd);
+}
+
+#define p4d_index(addr)		(((addr) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
+
+static inline p4d_t *pgd_to_folded_p4d(pgd_t *pgdp, unsigned long addr)
+{
+	return (p4d_t *)PTR_ALIGN_DOWN(pgdp, PAGE_SIZE) + p4d_index(addr);
+}
+
+static inline phys_addr_t p4d_offset_phys(pgd_t *pgdp, unsigned long addr)
+{
+	BUG_ON(!pgtable_l5_enabled());
+
+	return pgd_page_paddr(READ_ONCE(*pgdp)) + p4d_index(addr) * sizeof(p4d_t);
+}
+
+static inline
+p4d_t *p4d_offset_lockless(pgd_t *pgdp, pgd_t pgd, unsigned long addr)
+{
+	if (!pgtable_l5_enabled())
+		return pgd_to_folded_p4d(pgdp, addr);
+	return (p4d_t *)__va(pgd_page_paddr(pgd)) + p4d_index(addr);
+}
+#define p4d_offset_lockless p4d_offset_lockless
+
+static inline p4d_t *p4d_offset(pgd_t *pgdp, unsigned long addr)
+{
+	return p4d_offset_lockless(pgdp, READ_ONCE(*pgdp), addr);
+}
+
+#define pgd_page(pgd)		pfn_to_page(__phys_to_pfn(__pgd_to_phys(pgd)))
+
+#else
+
+static inline bool pgtable_l5_enabled(void) { return false; }
+
+#endif  /* CONFIG_PGTABLE_LEVELS > 4 */
+
 #define pgd_ERROR(e)	\
 	pr_err("%s:%d: bad pgd %016llx.\n", __FILE__, __LINE__, pgd_val(e))
 
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index ba00d0205447..d2e9dec38a15 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1025,7 +1025,7 @@ static void free_empty_pud_table(p4d_t *p4dp, unsigned long addr,
 	if (CONFIG_PGTABLE_LEVELS <= 3)
 		return;
 
-	if (!pgtable_range_aligned(start, end, floor, ceiling, PGDIR_MASK))
+	if (!pgtable_range_aligned(start, end, floor, ceiling, P4D_MASK))
 		return;
 
 	/*
@@ -1048,8 +1048,8 @@ static void free_empty_p4d_table(pgd_t *pgdp, unsigned long addr,
 				 unsigned long end, unsigned long floor,
 				 unsigned long ceiling)
 {
-	unsigned long next;
 	p4d_t *p4dp, p4d;
+	unsigned long i, next, start = addr;
 
 	do {
 		next = p4d_addr_end(addr, end);
@@ -1061,6 +1061,27 @@ static void free_empty_p4d_table(pgd_t *pgdp, unsigned long addr,
 		WARN_ON(!p4d_present(p4d));
 		free_empty_pud_table(p4dp, addr, next, floor, ceiling);
 	} while (addr = next, addr < end);
+
+	if (!pgtable_l5_enabled())
+		return;
+
+	if (!pgtable_range_aligned(start, end, floor, ceiling, PGDIR_MASK))
+		return;
+
+	/*
+	 * Check whether we can free the p4d page if the rest of the
+	 * entries are empty. Overlap with other regions have been
+	 * handled by the floor/ceiling check.
+	 */
+	p4dp = p4d_offset(pgdp, 0UL);
+	for (i = 0; i < PTRS_PER_P4D; i++) {
+		if (!p4d_none(READ_ONCE(p4dp[i])))
+			return;
+	}
+
+	pgd_clear(pgdp);
+	__flush_tlb_kernel_pgtable(start);
+	free_hotplug_pgtable_page(virt_to_page(p4dp));
 }
 
 static void free_empty_tables(unsigned long addr, unsigned long end,
@@ -1145,6 +1166,12 @@ int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot)
 	return 1;
 }
 
+#ifndef __PAGETABLE_P4D_FOLDED
+void p4d_clear_huge(p4d_t *p4dp)
+{
+}
+#endif
+
 int pud_clear_huge(pud_t *pudp)
 {
 	if (!pud_sect(READ_ONCE(*pudp)))
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 4a64089e5771..3c4f8a279d2b 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -17,11 +17,20 @@
 
 static struct kmem_cache *pgd_cache __ro_after_init;
 
+static bool pgdir_is_page_size(void)
+{
+	if (PGD_SIZE == PAGE_SIZE)
+		return true;
+	if (CONFIG_PGTABLE_LEVELS == 5)
+		return !pgtable_l5_enabled();
+	return false;
+}
+
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
 	gfp_t gfp = GFP_PGTABLE_USER;
 
-	if (PGD_SIZE == PAGE_SIZE)
+	if (pgdir_is_page_size())
 		return (pgd_t *)__get_free_page(gfp);
 	else
 		return kmem_cache_alloc(pgd_cache, gfp);
@@ -29,7 +38,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 
 void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
-	if (PGD_SIZE == PAGE_SIZE)
+	if (pgdir_is_page_size())
 		free_page((unsigned long)pgd);
 	else
 		kmem_cache_free(pgd_cache, pgd);
@@ -37,7 +46,7 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 
 void __init pgtable_cache_init(void)
 {
-	if (PGD_SIZE == PAGE_SIZE)
+	if (pgdir_is_page_size())
 		return;
 
 #ifdef CONFIG_ARM64_PA_BITS_52
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:10 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:10 +0100
Subject: [PATCH v8 24/43] arm64: Revert "mm: provide idmap pointer to cpu_replace_ttbr1()"
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-69-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

This reverts commit 1682c45b920643c, which is no longer needed now that
we create the permanent kernel mapping directly during early boot.

This is a RINO (revert in name only) given that some of the code has
moved around, but the changes are straight-forward.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/mmu_context.h | 17 ++++++-----------
 arch/arm64/mm/kasan_init.c           |  4 ++--
 arch/arm64/mm/mmu.c                  |  4 ++--
 3 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index a8a89a0f2867..c768d16b81a4 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -108,18 +108,13 @@ static inline void cpu_uninstall_idmap(void)
 		cpu_switch_mm(mm->pgd, mm);
 }
 
-static inline void __cpu_install_idmap(pgd_t *idmap)
+static inline void cpu_install_idmap(void)
 {
 	cpu_set_reserved_ttbr0();
 	local_flush_tlb_all();
 	cpu_set_idmap_tcr_t0sz();
 
-	cpu_switch_mm(lm_alias(idmap), &init_mm);
-}
-
-static inline void cpu_install_idmap(void)
-{
-	__cpu_install_idmap(idmap_pg_dir);
+	cpu_switch_mm(lm_alias(idmap_pg_dir), &init_mm);
 }
 
 /*
@@ -146,21 +141,21 @@ static inline void cpu_install_ttbr0(phys_addr_t ttbr0, unsigned long t0sz)
 	isb();
 }
 
-void __cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap, bool cnp);
+void __cpu_replace_ttbr1(pgd_t *pgdp, bool cnp);
 
 static inline void cpu_enable_swapper_cnp(void)
 {
-	__cpu_replace_ttbr1(lm_alias(swapper_pg_dir), idmap_pg_dir, true);
+	__cpu_replace_ttbr1(lm_alias(swapper_pg_dir), true);
 }
 
-static inline void cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap)
+static inline void cpu_replace_ttbr1(pgd_t *pgdp)
 {
 	/*
 	 * Only for early TTBR1 replacement before cpucaps are finalized and
 	 * before we've decided whether to use CNP.
 	 */
 	WARN_ON(system_capabilities_finalized());
-	__cpu_replace_ttbr1(pgdp, idmap, false);
+	__cpu_replace_ttbr1(pgdp, false);
 }
 
 /*
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 89828ad2bca7..a86ab99587c9 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -225,7 +225,7 @@ static void __init kasan_init_shadow(void)
 	 */
 	memcpy(tmp_pg_dir, swapper_pg_dir, sizeof(tmp_pg_dir));
 	dsb(ishst);
-	cpu_replace_ttbr1(lm_alias(tmp_pg_dir), idmap_pg_dir);
+	cpu_replace_ttbr1(lm_alias(tmp_pg_dir));
 
 	clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
@@ -261,7 +261,7 @@ static void __init kasan_init_shadow(void)
 				PAGE_KERNEL_RO));
 
 	memset(kasan_early_shadow_page, KASAN_SHADOW_INIT, PAGE_SIZE);
-	cpu_replace_ttbr1(lm_alias(swapper_pg_dir), idmap_pg_dir);
+	cpu_replace_ttbr1(lm_alias(swapper_pg_dir));
 }
 
 static void __init kasan_init_depth(void)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 3db40b517947..a3d23da92d87 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1445,7 +1445,7 @@ void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte
  * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD,
  * avoiding the possibility of conflicting TLB entries being allocated.
  */
-void __cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap, bool cnp)
+void __cpu_replace_ttbr1(pgd_t *pgdp, bool cnp)
 {
 	typedef void (ttbr_replace_func)(phys_addr_t);
 	extern ttbr_replace_func idmap_cpu_replace_ttbr1;
@@ -1460,7 +1460,7 @@ void __cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap, bool cnp)
 
 	replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1);
 
-	__cpu_install_idmap(idmap);
+	cpu_install_idmap();
 
 	/*
 	 * We really don't want to take *any* exceptions while TTBR1 is
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:18 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:18 +0100
Subject: [PATCH v8 32/43] arm64: mm: add LPA2 and 5 level paging support to
 G-to-nG conversion
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-77-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Add support for 5 level paging in the G-to-nG routine that creates its
own temporary page tables to traverse the swapper page tables. Also add
support for running the 5 level configuration with the top level folded
at runtime, to support CPUs that do not implement the LPA2 extension.

While at it, wire up the level skipping logic so it will also trigger on
4 level configurations with LPA2 enabled at build time but not active at
runtime, as we'll fall back to 3 level paging in that case.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/cpufeature.c |  9 ++-
 arch/arm64/mm/proc.S           | 70 +++++++++++++++++---
 2 files changed, 66 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index ed9670d8360c..bc5e4e569864 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1765,6 +1765,9 @@ static int __init __kpti_install_ng_mappings(void *__unused)
 	pgd_t *kpti_ng_temp_pgd;
 	u64 alloc = 0;
 
+	if (levels == 5 && !pgtable_l5_enabled())
+		levels = 4;
+
 	remap_fn = (void *)__pa_symbol(idmap_kpti_install_ng_mappings);
 
 	if (!cpu) {
@@ -1778,9 +1781,9 @@ static int __init __kpti_install_ng_mappings(void *__unused)
 		//
 		// The physical pages are laid out as follows:
 		//
-		// +--------+-/-------+-/------ +-\\--------+
-		// :  PTE[] : | PMD[] : | PUD[] : || PGD[]  :
-		// +--------+-\-------+-\------ +-//--------+
+		// +--------+-/-------+-/------ +-/------ +-\\\--------+
+		// :  PTE[] : | PMD[] : | PUD[] : | P4D[] : ||| PGD[]  :
+		// +--------+-\-------+-\------ +-\------ +-///--------+
 		//      ^
 		// The first page is mapped into this hierarchy at a PMD_SHIFT
 		// aligned virtual address, so that we can manipulate the PTE
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index d03434b7bca5..fa0d7c63f8d2 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -216,16 +216,15 @@ SYM_FUNC_ALIAS(__pi_idmap_cpu_replace_ttbr1, idmap_cpu_replace_ttbr1)
 	.macro	kpti_mk_tbl_ng, type, num_entries
 	add	end_\type\()p, cur_\type\()p, #\num_entries * 8
 .Ldo_\type:
-	ldr	\type, [cur_\type\()p]		// Load the entry
+	ldr	\type, [cur_\type\()p], #8	// Load the entry and advance
 	tbz	\type, #0, .Lnext_\type		// Skip invalid and
 	tbnz	\type, #11, .Lnext_\type	// non-global entries
 	orr	\type, \type, #PTE_NG		// Same bit for blocks and pages
-	str	\type, [cur_\type\()p]		// Update the entry
+	str	\type, [cur_\type\()p, #-8]	// Update the entry
 	.ifnc	\type, pte
 	tbnz	\type, #1, .Lderef_\type
 	.endif
 .Lnext_\type:
-	add	cur_\type\()p, cur_\type\()p, #8
 	cmp	cur_\type\()p, end_\type\()p
 	b.ne	.Ldo_\type
 	.endm
@@ -235,18 +234,18 @@ SYM_FUNC_ALIAS(__pi_idmap_cpu_replace_ttbr1, idmap_cpu_replace_ttbr1)
 	 * fixmap slot associated with the current level.
 	 */
 	.macro	kpti_map_pgtbl, type, level
-	str	xzr, [temp_pte, #8 * (\level + 1)]	// break before make
+	str	xzr, [temp_pte, #8 * (\level + 2)]	// break before make
 	dsb	nshst
-	add	pte, temp_pte, #PAGE_SIZE * (\level + 1)
+	add	pte, temp_pte, #PAGE_SIZE * (\level + 2)
 	lsr	pte, pte, #12
 	tlbi	vaae1, pte
 	dsb	nsh
 	isb
 
 	phys_to_pte pte, cur_\type\()p
-	add	cur_\type\()p, temp_pte, #PAGE_SIZE * (\level + 1)
+	add	cur_\type\()p, temp_pte, #PAGE_SIZE * (\level + 2)
 	orr	pte, pte, pte_flags
-	str	pte, [temp_pte, #8 * (\level + 1)]
+	str	pte, [temp_pte, #8 * (\level + 2)]
 	dsb	nshst
 	.endm
 
@@ -279,6 +278,8 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
 	end_ptep	.req	x15
 	pte		.req	x16
 	valid		.req	x17
+	cur_p4dp	.req	x19
+	end_p4dp	.req	x20
 
 	mov	x5, x3				// preserve temp_pte arg
 	mrs	swapper_ttb, ttbr1_el1
@@ -286,6 +287,12 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
 
 	cbnz	cpu, __idmap_kpti_secondary
 
+#if CONFIG_PGTABLE_LEVELS > 4
+	stp	x29, x30, [sp, #-32]!
+	mov	x29, sp
+	stp	x19, x20, [sp, #16]
+#endif
+
 	/* We're the boot CPU. Wait for the others to catch up */
 	sevl
 1:	wfe
@@ -303,9 +310,32 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
 	mov_q	pte_flags, KPTI_NG_PTE_FLAGS
 
 	/* Everybody is enjoying the idmap, so we can rewrite swapper. */
+
+#ifdef CONFIG_ARM64_LPA2
+	/*
+	 * If LPA2 support is configured, but 52-bit virtual addressing is not
+	 * enabled at runtime, we will fall back to one level of paging less,
+	 * and so we have to walk swapper_pg_dir as if we dereferenced its
+	 * address from a PGD level entry, and terminate the PGD level loop
+	 * right after.
+	 */
+	adrp	pgd, swapper_pg_dir	// walk &swapper_pg_dir at the next level
+	mov	cur_pgdp, end_pgdp	// must be equal to terminate the PGD loop
+alternative_if_not ARM64_HAS_VA52
+	b	.Lderef_pgd		// skip to the next level
+alternative_else_nop_endif
+	/*
+	 * LPA2 based 52-bit virtual addressing requires 52-bit physical
+	 * addressing to be enabled as well. In this case, the shareability
+	 * bits are repurposed as physical address bits, and should not be
+	 * set in pte_flags.
+	 */
+	bic	pte_flags, pte_flags, #PTE_SHARED
+#endif
+
 	/* PGD */
 	adrp		cur_pgdp, swapper_pg_dir
-	kpti_map_pgtbl	pgd, 0
+	kpti_map_pgtbl	pgd, -1
 	kpti_mk_tbl_ng	pgd, PTRS_PER_PGD
 
 	/* Ensure all the updated entries are visible to secondary CPUs */
@@ -318,16 +348,33 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
 
 	/* Set the flag to zero to indicate that we're all done */
 	str	wzr, [flag_ptr]
+#if CONFIG_PGTABLE_LEVELS > 4
+	ldp	x19, x20, [sp, #16]
+	ldp	x29, x30, [sp], #32
+#endif
 	ret
 
 .Lderef_pgd:
+	/* P4D */
+	.if		CONFIG_PGTABLE_LEVELS > 4
+	p4d		.req	x30
+	pte_to_phys	cur_p4dp, pgd
+	kpti_map_pgtbl	p4d, 0
+	kpti_mk_tbl_ng	p4d, PTRS_PER_P4D
+	b		.Lnext_pgd
+	.else		/* CONFIG_PGTABLE_LEVELS <= 4 */
+	p4d		.req	pgd
+	.set		.Lnext_p4d, .Lnext_pgd
+	.endif
+
+.Lderef_p4d:
 	/* PUD */
 	.if		CONFIG_PGTABLE_LEVELS > 3
 	pud		.req	x10
-	pte_to_phys	cur_pudp, pgd
+	pte_to_phys	cur_pudp, p4d
 	kpti_map_pgtbl	pud, 1
 	kpti_mk_tbl_ng	pud, PTRS_PER_PUD
-	b		.Lnext_pgd
+	b		.Lnext_p4d
 	.else		/* CONFIG_PGTABLE_LEVELS <= 3 */
 	pud		.req	pgd
 	.set		.Lnext_pud, .Lnext_pgd
@@ -371,6 +418,9 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
 	.unreq	end_ptep
 	.unreq	pte
 	.unreq	valid
+	.unreq	cur_p4dp
+	.unreq	end_p4dp
+	.unreq	p4d
 
 	/* Secondary CPUs end up here */
 __idmap_kpti_secondary:
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:19 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:19 +0100
Subject: [PATCH v8 33/43] arm64: Enable LPA2 at boot if supported by the system
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-78-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Update the early kernel mapping code to take 52-bit virtual addressing
into account based on the LPA2 feature. This is a bit more involved than
LVA (which is supported with 64k pages only), given that some page table
descriptor bits change meaning in this case.

To keep the handling in asm to a minimum, the initial ID map is still
created with 48-bit virtual addressing, which implies that the kernel
image must be loaded into 48-bit addressable physical memory. This is
currently required by the boot protocol, even though we happen to
support placement outside of that for LVA/64k based configurations.

Enabling LPA2 involves more than setting TCR.T1SZ to a lower value,
there is also a DS bit in TCR that needs to be set, and which changes
the meaning of bits [9:8] in all page table descriptors. Since we cannot
enable DS and every live page table descriptor at the same time, let's
pivot through another temporary mapping. This avoids the need to
reintroduce manipulations of the page tables with the MMU and caches
disabled.

To permit the LPA2 feature to be overridden on the kernel command line,
which may be necessary to work around silicon errata, or to deal with
mismatched features on heterogeneous SoC designs, test for CPU feature
overrides first, and only then enable LPA2.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/assembler.h  |  8 ++-
 arch/arm64/include/asm/cpufeature.h | 18 +++++
 arch/arm64/include/asm/memory.h     |  4 ++
 arch/arm64/kernel/head.S            |  8 +++
 arch/arm64/kernel/image-vars.h      |  1 +
 arch/arm64/kernel/pi/map_kernel.c   | 70 +++++++++++++++++++-
 arch/arm64/kernel/pi/map_range.c    | 11 ++-
 arch/arm64/kernel/pi/pi.h           |  4 +-
 arch/arm64/mm/init.c                |  2 +-
 arch/arm64/mm/mmu.c                 |  6 +-
 arch/arm64/mm/proc.S                |  3 +
 11 files changed, 124 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 7eedcb36ebe0..ce7b95cd6e79 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -581,11 +581,17 @@ alternative_endif
  * but we have to add an offset so that the TTBR1 address corresponds with the
  * pgdir entry that covers the lowest 48-bit addressable VA.
  *
+ * Note that this trick is only used for LVA/64k pages - LPA2/4k pages uses an
+ * additional paging level, and on LPA2/16k pages, we would end up with a root
+ * level table with only 2 entries, which is suboptimal in terms of TLB
+ * utilization, so there we fall back to 47 bits of translation if LPA2 is not
+ * supported.
+ *
  * orr is used as it can cover the immediate value (and is idempotent).
  * 	ttbr: Value of ttbr to set, modified.
  */
 	.macro	offset_ttbr1, ttbr, tmp
-#ifdef CONFIG_ARM64_VA_BITS_52
+#if defined(CONFIG_ARM64_VA_BITS_52) && !defined(CONFIG_ARM64_LPA2)
 	mrs	\tmp, tcr_el1
 	and	\tmp, \tmp, #TCR_T1SZ_MASK
 	cmp	\tmp, #TCR_T1SZ(VA_BITS_MIN)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index a2ac31aecdd9..a8f97690ce1f 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -1008,6 +1008,24 @@ static inline bool cpu_has_lva(void)
 						    ID_AA64MMFR2_EL1_VARange_SHIFT);
 }
 
+static inline bool cpu_has_lpa2(void)
+{
+#ifdef CONFIG_ARM64_LPA2
+	u64 mmfr0;
+	int feat;
+
+	mmfr0 = read_sysreg(id_aa64mmfr0_el1);
+	mmfr0 &= ~id_aa64mmfr0_override.mask;
+	mmfr0 |= id_aa64mmfr0_override.val;
+	feat = cpuid_feature_extract_signed_field(mmfr0,
+						  ID_AA64MMFR0_EL1_TGRAN_SHIFT);
+
+	return feat >= ID_AA64MMFR0_EL1_TGRAN_LPA2;
+#else
+	return false;
+#endif
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 9680d7444b3b..b850b1b91471 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -54,7 +54,11 @@
 #define FIXADDR_TOP		(-UL(SZ_8M))
 
 #if VA_BITS > 48
+#ifdef CONFIG_ARM64_16K_PAGES
+#define VA_BITS_MIN		(47)
+#else
 #define VA_BITS_MIN		(48)
+#endif
 #else
 #define VA_BITS_MIN		(VA_BITS)
 #endif
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index e25351addfd0..405e9bce8c73 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -89,6 +89,7 @@ SYM_CODE_START(primary_entry)
 	mov	sp, x1
 	mov	x29, xzr
 	adrp	x0, init_idmap_pg_dir
+	mov	x1, xzr
 	bl	__pi_create_init_idmap
 
 	/*
@@ -473,9 +474,16 @@ SYM_FUNC_END(__enable_mmu)
 
 #ifdef CONFIG_ARM64_VA_BITS_52
 SYM_FUNC_START(__cpu_secondary_check52bitva)
+#ifndef CONFIG_ARM64_LPA2
 	mrs_s	x0, SYS_ID_AA64MMFR2_EL1
 	and	x0, x0, ID_AA64MMFR2_EL1_VARange_MASK
 	cbnz	x0, 2f
+#else
+	mrs	x0, id_aa64mmfr0_el1
+	sbfx	x0, x0, #ID_AA64MMFR0_EL1_TGRAN_SHIFT, 4
+	cmp	x0, #ID_AA64MMFR0_EL1_TGRAN_LPA2
+	b.ge	2f
+#endif
 
 	update_early_cpu_boot_status \
 		CPU_STUCK_IN_KERNEL | CPU_STUCK_REASON_52_BIT_VA, x0, x1
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index ff81f809a240..ba4f8f7d6a91 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -54,6 +54,7 @@ PROVIDE(__pi__ctype			= _ctype);
 PROVIDE(__pi_memstart_offset_seed	= memstart_offset_seed);
 
 PROVIDE(__pi_init_idmap_pg_dir		= init_idmap_pg_dir);
+PROVIDE(__pi_init_idmap_pg_end		= init_idmap_pg_end);
 PROVIDE(__pi_init_pg_dir		= init_pg_dir);
 PROVIDE(__pi_init_pg_end		= init_pg_end);
 PROVIDE(__pi_swapper_pg_dir		= swapper_pg_dir);
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
index 1853825aa29d..5fa08e13e17e 100644
--- a/arch/arm64/kernel/pi/map_kernel.c
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -127,11 +127,64 @@ static void __init map_kernel(u64 kaslr_offset, u64 va_offset, int root_level)
 	}
 
 	/* Copy the root page table to its final location */
-	memcpy((void *)swapper_pg_dir + va_offset, init_pg_dir, PGD_SIZE);
+	memcpy((void *)swapper_pg_dir + va_offset, init_pg_dir, PAGE_SIZE);
 	dsb(ishst);
 	idmap_cpu_replace_ttbr1(swapper_pg_dir);
 }
 
+static void noinline __section(".idmap.text") set_ttbr0_for_lpa2(u64 ttbr)
+{
+	u64 sctlr = read_sysreg(sctlr_el1);
+	u64 tcr = read_sysreg(tcr_el1) | TCR_DS;
+
+	asm("	msr	sctlr_el1, %0		;"
+	    "	isb				;"
+	    "   msr     ttbr0_el1, %1		;"
+	    "   msr     tcr_el1, %2		;"
+	    "	isb				;"
+	    "	tlbi    vmalle1			;"
+	    "	dsb     nsh			;"
+	    "	isb				;"
+	    "	msr     sctlr_el1, %3		;"
+	    "	isb				;"
+	    ::	"r"(sctlr & ~SCTLR_ELx_M), "r"(ttbr), "r"(tcr), "r"(sctlr));
+}
+
+static void __init remap_idmap_for_lpa2(void)
+{
+	/* clear the bits that change meaning once LPA2 is turned on */
+	pteval_t mask = PTE_SHARED;
+
+	/*
+	 * We have to clear bits [9:8] in all block or page descriptors in the
+	 * initial ID map, as otherwise they will be (mis)interpreted as
+	 * physical address bits once we flick the LPA2 switch (TCR.DS). Since
+	 * we cannot manipulate live descriptors in that way without creating
+	 * potential TLB conflicts, let's create another temporary ID map in a
+	 * LPA2 compatible fashion, and update the initial ID map while running
+	 * from that.
+	 */
+	create_init_idmap(init_pg_dir, mask);
+	dsb(ishst);
+	set_ttbr0_for_lpa2((u64)init_pg_dir);
+
+	/*
+	 * Recreate the initial ID map with the same granularity as before.
+	 * Don't bother with the FDT, we no longer need it after this.
+	 */
+	memset(init_idmap_pg_dir, 0,
+	       (u64)init_idmap_pg_dir - (u64)init_idmap_pg_end);
+
+	create_init_idmap(init_idmap_pg_dir, mask);
+	dsb(ishst);
+
+	/* switch back to the updated initial ID map */
+	set_ttbr0_for_lpa2((u64)init_idmap_pg_dir);
+
+	/* wipe the temporary ID map from memory */
+	memset(init_pg_dir, 0, (u64)init_pg_end - (u64)init_pg_dir);
+}
+
 static void __init map_fdt(u64 fdt)
 {
 	static u8 ptes[INIT_IDMAP_FDT_SIZE] __initdata __aligned(PAGE_SIZE);
@@ -154,6 +207,7 @@ asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt)
 	u64 va_base, pa_base = (u64)&_text;
 	u64 kaslr_offset = pa_base % MIN_KIMG_ALIGN;
 	int root_level = 4 - CONFIG_PGTABLE_LEVELS;
+	int va_bits = VA_BITS;
 	int chosen;
 
 	map_fdt((u64)fdt);
@@ -165,8 +219,15 @@ asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt)
 	chosen = fdt_path_offset(fdt, chosen_str);
 	init_feature_override(boot_status, fdt, chosen);
 
-	if (VA_BITS > VA_BITS_MIN && cpu_has_lva())
-		sysreg_clear_set(tcr_el1, TCR_T1SZ_MASK, TCR_T1SZ(VA_BITS));
+	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && !cpu_has_lva()) {
+		va_bits = VA_BITS_MIN;
+	} else if (IS_ENABLED(CONFIG_ARM64_LPA2) && !cpu_has_lpa2()) {
+		va_bits = VA_BITS_MIN;
+		root_level++;
+	}
+
+	if (va_bits > VA_BITS_MIN)
+		sysreg_clear_set(tcr_el1, TCR_T1SZ_MASK, TCR_T1SZ(va_bits));
 
 	/*
 	 * The virtual KASLR displacement modulo 2MiB is decided by the
@@ -184,6 +245,9 @@ asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt)
 		kaslr_offset |= kaslr_seed & ~(MIN_KIMG_ALIGN - 1);
 	}
 
+	if (IS_ENABLED(CONFIG_ARM64_LPA2) && va_bits > VA_BITS_MIN)
+		remap_idmap_for_lpa2();
+
 	va_base = KIMAGE_VADDR + kaslr_offset;
 	map_kernel(kaslr_offset, va_base - pa_base, root_level);
 }
diff --git a/arch/arm64/kernel/pi/map_range.c b/arch/arm64/kernel/pi/map_range.c
index 79e4f6a2efe1..5410b2cac590 100644
--- a/arch/arm64/kernel/pi/map_range.c
+++ b/arch/arm64/kernel/pi/map_range.c
@@ -87,14 +87,19 @@ void __init map_range(u64 *pte, u64 start, u64 end, u64 pa, pgprot_t prot,
 	}
 }
 
-asmlinkage u64 __init create_init_idmap(pgd_t *pg_dir)
+asmlinkage u64 __init create_init_idmap(pgd_t *pg_dir, pteval_t clrmask)
 {
 	u64 ptep = (u64)pg_dir + PAGE_SIZE;
+	pgprot_t text_prot = PAGE_KERNEL_ROX;
+	pgprot_t data_prot = PAGE_KERNEL;
+
+	pgprot_val(text_prot) &= ~clrmask;
+	pgprot_val(data_prot) &= ~clrmask;
 
 	map_range(&ptep, (u64)_stext, (u64)__initdata_begin, (u64)_stext,
-		  PAGE_KERNEL_ROX, IDMAP_ROOT_LEVEL, (pte_t *)pg_dir, false, 0);
+		  text_prot, IDMAP_ROOT_LEVEL, (pte_t *)pg_dir, false, 0);
 	map_range(&ptep, (u64)__initdata_begin, (u64)_end, (u64)__initdata_begin,
-		  PAGE_KERNEL, IDMAP_ROOT_LEVEL, (pte_t *)pg_dir, false, 0);
+		  data_prot, IDMAP_ROOT_LEVEL, (pte_t *)pg_dir, false, 0);
 
 	return ptep;
 }
diff --git a/arch/arm64/kernel/pi/pi.h b/arch/arm64/kernel/pi/pi.h
index 1ea282a5f96a..c91e5e965cd3 100644
--- a/arch/arm64/kernel/pi/pi.h
+++ b/arch/arm64/kernel/pi/pi.h
@@ -21,7 +21,7 @@ static inline void *prel64_to_pointer(const prel64_t *offset)
 
 extern bool dynamic_scs_is_enabled;
 
-extern pgd_t init_idmap_pg_dir[];
+extern pgd_t init_idmap_pg_dir[], init_idmap_pg_end[];
 
 void init_feature_override(u64 boot_status, const void *fdt, int chosen);
 u64 kaslr_early_init(void *fdt, int chosen);
@@ -33,4 +33,4 @@ void map_range(u64 *pgd, u64 start, u64 end, u64 pa, pgprot_t prot,
 
 asmlinkage void early_map_kernel(u64 boot_status, void *fdt);
 
-asmlinkage u64 create_init_idmap(pgd_t *pgd);
+asmlinkage u64 create_init_idmap(pgd_t *pgd, pteval_t clrmask);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 74c1db8ce271..0f427b50fdc3 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -238,7 +238,7 @@ void __init arm64_memblock_init(void)
 	 * physical address of PAGE_OFFSET, we have to *subtract* from it.
 	 */
 	if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52))
-		memstart_addr -= _PAGE_OFFSET(48) - _PAGE_OFFSET(52);
+		memstart_addr -= _PAGE_OFFSET(vabits_actual) - _PAGE_OFFSET(52);
 
 	/*
 	 * Apply the memory limit if it was set. Since the kernel may be loaded
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index d2e9dec38a15..d30ae4d3fdd9 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -582,8 +582,12 @@ static void __init map_mem(pgd_t *pgdp)
 	 * entries at any level are being shared between the linear region and
 	 * the vmalloc region. Check whether this is true for the PGD level, in
 	 * which case it is guaranteed to be true for all other levels as well.
+	 * (Unless we are running with support for LPA2, in which case the
+	 * entire reduced VA space is covered by a single pgd_t which will have
+	 * been populated without the PXNTable attribute by the time we get here.)
 	 */
-	BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end));
+	BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end) &&
+		     pgd_index(_PAGE_OFFSET(VA_BITS_MIN)) != PTRS_PER_PGD - 1);
 
 	early_kfence_pool = arm64_kfence_alloc_pool();
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index fa0d7c63f8d2..9d40f3ffd8d2 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -488,6 +488,9 @@ SYM_FUNC_START(__cpu_setup)
 	mov		x9, #64 - VA_BITS
 alternative_if ARM64_HAS_VA52
 	tcr_set_t1sz	tcr, x9
+#ifdef CONFIG_ARM64_LPA2
+	orr		tcr, tcr, #TCR_DS
+#endif
 alternative_else_nop_endif
 #endif
 
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:22 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:22 +0100
Subject: [PATCH v8 36/43] arm64: mm: Add support for folding PUDs at runtime
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-81-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

In order to support LPA2 on 16k pages in a way that permits non-LPA2
systems to run the same kernel image, we have to be able to fall back to
at most 48 bits of virtual addressing.

Falling back to 48 bits would result in a level 0 with only 2 entries,
which is suboptimal in terms of TLB utilization. So instead, let's fall
back to 47 bits in that case. This means we need to be able to fold PUDs
dynamically, similar to how we fold P4Ds for 48 bit virtual addressing
on LPA2 with 4k pages.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgalloc.h | 12 ++-
 arch/arm64/include/asm/pgtable.h | 87 +++++++++++++++++---
 arch/arm64/include/asm/tlb.h     |  3 +
 arch/arm64/kernel/cpufeature.c   |  2 +
 arch/arm64/mm/mmu.c              |  2 +-
 arch/arm64/mm/pgd.c              |  2 +
 6 files changed, 95 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index cae8c648f462..aeba2cf15a25 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -14,6 +14,7 @@
 #include <asm/tlbflush.h>
 
 #define __HAVE_ARCH_PGD_FREE
+#define __HAVE_ARCH_PUD_FREE
 #include <asm-generic/pgalloc.h>
 
 #define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
@@ -43,7 +44,8 @@ static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
 
 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));
+	if (pgtable_l4_enabled())
+		set_p4d(p4dp, __p4d(__phys_to_p4d_val(pudp) | prot));
 }
 
 static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
@@ -53,6 +55,14 @@ static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
 	p4dval |= (mm == &init_mm) ? P4D_TABLE_UXN : P4D_TABLE_PXN;
 	__p4d_populate(p4dp, __pa(pudp), p4dval);
 }
+
+static inline void pud_free(struct mm_struct *mm, pud_t *pud)
+{
+	if (!pgtable_l4_enabled())
+		return;
+	BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
+	free_page((unsigned long)pud);
+}
 #else
 static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
 {
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 3d7fb3cde83d..b3c716fa8121 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -759,12 +759,27 @@ static inline pmd_t *pud_pgtable(pud_t pud)
 
 #if CONFIG_PGTABLE_LEVELS > 3
 
+static __always_inline bool pgtable_l4_enabled(void)
+{
+	if (CONFIG_PGTABLE_LEVELS > 4 || !IS_ENABLED(CONFIG_ARM64_LPA2))
+		return true;
+	if (!alternative_has_cap_likely(ARM64_ALWAYS_BOOT))
+		return vabits_actual == VA_BITS;
+	return alternative_has_cap_unlikely(ARM64_HAS_VA52);
+}
+
+static inline bool mm_pud_folded(const struct mm_struct *mm)
+{
+	return !pgtable_l4_enabled();
+}
+#define mm_pud_folded  mm_pud_folded
+
 #define pud_ERROR(e)	\
 	pr_err("%s:%d: bad pud %016llx.\n", __FILE__, __LINE__, pud_val(e))
 
-#define p4d_none(p4d)		(!p4d_val(p4d))
-#define p4d_bad(p4d)		(!(p4d_val(p4d) & 2))
-#define p4d_present(p4d)	(p4d_val(p4d))
+#define p4d_none(p4d)		(pgtable_l4_enabled() && !p4d_val(p4d))
+#define p4d_bad(p4d)		(pgtable_l4_enabled() && !(p4d_val(p4d) & 2))
+#define p4d_present(p4d)	(!p4d_none(p4d))
 
 static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
 {
@@ -780,7 +795,8 @@ static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
 
 static inline void p4d_clear(p4d_t *p4dp)
 {
-	set_p4d(p4dp, __p4d(0));
+	if (pgtable_l4_enabled())
+		set_p4d(p4dp, __p4d(0));
 }
 
 static inline phys_addr_t p4d_page_paddr(p4d_t p4d)
@@ -788,25 +804,74 @@ static inline phys_addr_t p4d_page_paddr(p4d_t p4d)
 	return __p4d_to_phys(p4d);
 }
 
+#define pud_index(addr)		(((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
+
+static inline pud_t *p4d_to_folded_pud(p4d_t *p4dp, unsigned long addr)
+{
+	return (pud_t *)PTR_ALIGN_DOWN(p4dp, PAGE_SIZE) + pud_index(addr);
+}
+
 static inline pud_t *p4d_pgtable(p4d_t p4d)
 {
 	return (pud_t *)__va(p4d_page_paddr(p4d));
 }
 
-/* Find an entry in the first-level page table. */
-#define pud_offset_phys(dir, addr)	(p4d_page_paddr(READ_ONCE(*(dir))) + pud_index(addr) * sizeof(pud_t))
+static inline phys_addr_t pud_offset_phys(p4d_t *p4dp, unsigned long addr)
+{
+	BUG_ON(!pgtable_l4_enabled());
 
-#define pud_set_fixmap(addr)		((pud_t *)set_fixmap_offset(FIX_PUD, addr))
-#define pud_set_fixmap_offset(p4d, addr)	pud_set_fixmap(pud_offset_phys(p4d, addr))
-#define pud_clear_fixmap()		clear_fixmap(FIX_PUD)
+	return p4d_page_paddr(READ_ONCE(*p4dp)) + pud_index(addr) * sizeof(pud_t);
+}
 
-#define p4d_page(p4d)		pfn_to_page(__phys_to_pfn(__p4d_to_phys(p4d)))
+static inline
+pud_t *pud_offset_lockless(p4d_t *p4dp, p4d_t p4d, unsigned long addr)
+{
+	if (!pgtable_l4_enabled())
+		return p4d_to_folded_pud(p4dp, addr);
+	return (pud_t *)__va(p4d_page_paddr(p4d)) + pud_index(addr);
+}
+#define pud_offset_lockless pud_offset_lockless
+
+static inline pud_t *pud_offset(p4d_t *p4dp, unsigned long addr)
+{
+	return pud_offset_lockless(p4dp, READ_ONCE(*p4dp), addr);
+}
+#define pud_offset	pud_offset
+
+static inline pud_t *pud_set_fixmap(unsigned long addr)
+{
+	if (!pgtable_l4_enabled())
+		return NULL;
+	return (pud_t *)set_fixmap_offset(FIX_PUD, addr);
+}
+
+static inline pud_t *pud_set_fixmap_offset(p4d_t *p4dp, unsigned long addr)
+{
+	if (!pgtable_l4_enabled())
+		return p4d_to_folded_pud(p4dp, addr);
+	return pud_set_fixmap(pud_offset_phys(p4dp, addr));
+}
+
+static inline void pud_clear_fixmap(void)
+{
+	if (pgtable_l4_enabled())
+		clear_fixmap(FIX_PUD);
+}
 
 /* use ONLY for statically allocated translation tables */
-#define pud_offset_kimg(dir,addr)	((pud_t *)__phys_to_kimg(pud_offset_phys((dir), (addr))))
+static inline pud_t *pud_offset_kimg(p4d_t *p4dp, u64 addr)
+{
+	if (!pgtable_l4_enabled())
+		return p4d_to_folded_pud(p4dp, addr);
+	return (pud_t *)__phys_to_kimg(pud_offset_phys(p4dp, addr));
+}
+
+#define p4d_page(p4d)		pfn_to_page(__phys_to_pfn(__p4d_to_phys(p4d)))
 
 #else
 
+static inline bool pgtable_l4_enabled(void) { return false; }
+
 #define p4d_page_paddr(p4d)	({ BUILD_BUG(); 0;})
 
 /* Match pud_offset folding in <asm/generic/pgtable-nopud.h> */
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 0150deb332af..a947c6e784ed 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -103,6 +103,9 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp,
 {
 	struct ptdesc *ptdesc = virt_to_ptdesc(pudp);
 
+	if (!pgtable_l4_enabled())
+		return;
+
 	pagetable_pud_dtor(ptdesc);
 	tlb_remove_ptdesc(tlb, ptdesc);
 }
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index bc5e4e569864..94f035f6c421 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1767,6 +1767,8 @@ static int __init __kpti_install_ng_mappings(void *__unused)
 
 	if (levels == 5 && !pgtable_l5_enabled())
 		levels = 4;
+	else if (levels == 4 && !pgtable_l4_enabled())
+		levels = 3;
 
 	remap_fn = (void *)__pa_symbol(idmap_kpti_install_ng_mappings);
 
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 8e5b3a7c5afd..b131ed31a6c8 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1065,7 +1065,7 @@ static void free_empty_pud_table(p4d_t *p4dp, unsigned long addr,
 		free_empty_pmd_table(pudp, addr, next, floor, ceiling);
 	} while (addr = next, addr < end);
 
-	if (CONFIG_PGTABLE_LEVELS <= 3)
+	if (!pgtable_l4_enabled())
 		return;
 
 	if (!pgtable_range_aligned(start, end, floor, ceiling, P4D_MASK))
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 3c4f8a279d2b..0c501cabc238 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -21,6 +21,8 @@ static bool pgdir_is_page_size(void)
 {
 	if (PGD_SIZE == PAGE_SIZE)
 		return true;
+	if (CONFIG_PGTABLE_LEVELS == 4)
+		return !pgtable_l4_enabled();
 	if (CONFIG_PGTABLE_LEVELS == 5)
 		return !pgtable_l5_enabled();
 	return false;
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:23 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:23 +0100
Subject: [PATCH v8 37/43] arm64: ptdump: Disregard unaddressable VA space
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-82-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Configurations built with support for 52-bit virtual addressing can also
run on CPUs that only support 48 bits of VA space, in which case only
that part of swapper_pg_dir that represents the 48-bit addressable
region is relevant, and everything else is ignored by the hardware.

Our software pagetable walker has little in the way of input address
validation, and so it will happily start a walk from an address that is
not representable by the number of paging levels that are actually
active, resulting in lots of bogus output from the page table dumper
unless we take care to start at a valid address.

So define the start address at runtime based on vabits_actual.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/mm/ptdump.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
index 5f0849528ccf..16d0cf1d85c4 100644
--- a/arch/arm64/mm/ptdump.c
+++ b/arch/arm64/mm/ptdump.c
@@ -313,7 +313,6 @@ static void __init ptdump_initialize(void)
 
 static struct ptdump_info kernel_ptdump_info __ro_after_init = {
 	.mm		= &init_mm,
-	.base_addr	= PAGE_OFFSET,
 };
 
 void ptdump_check_wx(void)
@@ -329,7 +328,7 @@ void ptdump_check_wx(void)
 		.ptdump = {
 			.note_page = note_page,
 			.range = (struct ptdump_range[]) {
-				{PAGE_OFFSET, ~0UL},
+				{_PAGE_OFFSET(vabits_actual), ~0UL},
 				{0, 0}
 			}
 		}
@@ -370,6 +369,7 @@ static int __init ptdump_init(void)
 	static struct addr_marker address_markers[ARRAY_SIZE(m)] __ro_after_init;
 
 	kernel_ptdump_info.markers = memcpy(address_markers, m, sizeof(m));
+	kernel_ptdump_info.base_addr = page_offset;
 
 	ptdump_initialize();
 	ptdump_debugfs_register(&kernel_ptdump_info, "kernel_page_tables");
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:24 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:24 +0100
Subject: [PATCH v8 38/43] arm64: ptdump: Deal with translation levels folded
 at runtime
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-83-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Currently, the ptdump code deals with folded PMD or PUD levels at build
time, by omitting those levels when invoking note_page. IOW, note_page()
is never invoked with level == 1 if P4Ds are folded in the build
configuration.

With the introduction of LPA2 support, we will defer some of these
folding decisions to runtime, so let's take care of this by overriding
the 'level' argument when this condition triggers.

Substituting the PUD or PMD strings for "PGD" when the level in question
is folded at build time is no longer necessary, and so the conditional
expressions can be simplified. This also makes the indirection of the
'name' field unnecessary, so change that into a char[] array, and make
the whole thing __ro_after_init.

Note that the mm_p?d_folded() functions currently ignore their mm
pointer arguments, but let's wire them up correctly anyway.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/mm/ptdump.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
index 16d0cf1d85c4..5b87f8d623f7 100644
--- a/arch/arm64/mm/ptdump.c
+++ b/arch/arm64/mm/ptdump.c
@@ -48,6 +48,7 @@ struct pg_state {
 	struct ptdump_state ptdump;
 	struct seq_file *seq;
 	const struct addr_marker *marker;
+	const struct mm_struct *mm;
 	unsigned long start_address;
 	int level;
 	u64 current_prot;
@@ -144,12 +145,12 @@ static const struct prot_bits pte_bits[] = {
 
 struct pg_level {
 	const struct prot_bits *bits;
-	const char *name;
-	size_t num;
+	char name[4];
+	int num;
 	u64 mask;
 };
 
-static struct pg_level pg_level[] = {
+static struct pg_level pg_level[] __ro_after_init = {
 	{ /* pgd */
 		.name	= "PGD",
 		.bits	= pte_bits,
@@ -159,11 +160,11 @@ static struct pg_level pg_level[] = {
 		.bits	= pte_bits,
 		.num	= ARRAY_SIZE(pte_bits),
 	}, { /* pud */
-		.name	= (CONFIG_PGTABLE_LEVELS > 3) ? "PUD" : "PGD",
+		.name	= "PUD",
 		.bits	= pte_bits,
 		.num	= ARRAY_SIZE(pte_bits),
 	}, { /* pmd */
-		.name	= (CONFIG_PGTABLE_LEVELS > 2) ? "PMD" : "PGD",
+		.name	= "PMD",
 		.bits	= pte_bits,
 		.num	= ARRAY_SIZE(pte_bits),
 	}, { /* pte */
@@ -227,6 +228,11 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
 	static const char units[] = "KMGTPE";
 	u64 prot = 0;
 
+	/* check if the current level has been folded dynamically */
+	if ((level == 1 && mm_p4d_folded(st->mm)) ||
+	    (level == 2 && mm_pud_folded(st->mm)))
+		level = 0;
+
 	if (level >= 0)
 		prot = val & pg_level[level].mask;
 
@@ -288,6 +294,7 @@ void ptdump_walk(struct seq_file *s, struct ptdump_info *info)
 	st = (struct pg_state){
 		.seq = s,
 		.marker = info->markers,
+		.mm = info->mm,
 		.level = -1,
 		.ptdump = {
 			.note_page = note_page,
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:20 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:20 +0100
Subject: [PATCH v8 34/43] arm64: mm: Add 5 level paging support to fixmap and
 swapper handling
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-79-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Add support for using 5 levels of paging in the fixmap, as well as in
the kernel page table handling code which uses fixmaps internally.
This also handles the case where a 5 level build runs on hardware that
only supports 4 levels of paging.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/fixmap.h  |  1 +
 arch/arm64/include/asm/pgtable.h | 45 ++++++++++++++++---
 arch/arm64/mm/fixmap.c           |  2 +-
 arch/arm64/mm/mmu.c              | 47 ++++++++++++++++++--
 4 files changed, 85 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index 8aabd45e9a13..87e307804b99 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -87,6 +87,7 @@ enum fixed_addresses {
 	FIX_PTE,
 	FIX_PMD,
 	FIX_PUD,
+	FIX_P4D,
 	FIX_PGD,
 
 	__end_of_fixed_addresses
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7eb2b933ed3c..3d7fb3cde83d 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -621,12 +621,12 @@ static inline bool pud_table(pud_t pud) { return true; }
 				 PUD_TYPE_TABLE)
 #endif
 
-extern pgd_t init_pg_dir[PTRS_PER_PGD];
+extern pgd_t init_pg_dir[];
 extern pgd_t init_pg_end[];
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
-extern pgd_t tramp_pg_dir[PTRS_PER_PGD];
-extern pgd_t reserved_pg_dir[PTRS_PER_PGD];
+extern pgd_t swapper_pg_dir[];
+extern pgd_t idmap_pg_dir[];
+extern pgd_t tramp_pg_dir[];
+extern pgd_t reserved_pg_dir[];
 
 extern void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd);
 
@@ -891,12 +891,47 @@ static inline p4d_t *p4d_offset(pgd_t *pgdp, unsigned long addr)
 	return p4d_offset_lockless(pgdp, READ_ONCE(*pgdp), addr);
 }
 
+static inline p4d_t *p4d_set_fixmap(unsigned long addr)
+{
+	if (!pgtable_l5_enabled())
+		return NULL;
+	return (p4d_t *)set_fixmap_offset(FIX_P4D, addr);
+}
+
+static inline p4d_t *p4d_set_fixmap_offset(pgd_t *pgdp, unsigned long addr)
+{
+	if (!pgtable_l5_enabled())
+		return pgd_to_folded_p4d(pgdp, addr);
+	return p4d_set_fixmap(p4d_offset_phys(pgdp, addr));
+}
+
+static inline void p4d_clear_fixmap(void)
+{
+	if (pgtable_l5_enabled())
+		clear_fixmap(FIX_P4D);
+}
+
+/* use ONLY for statically allocated translation tables */
+static inline p4d_t *p4d_offset_kimg(pgd_t *pgdp, u64 addr)
+{
+	if (!pgtable_l5_enabled())
+		return pgd_to_folded_p4d(pgdp, addr);
+	return (p4d_t *)__phys_to_kimg(p4d_offset_phys(pgdp, addr));
+}
+
 #define pgd_page(pgd)		pfn_to_page(__phys_to_pfn(__pgd_to_phys(pgd)))
 
 #else
 
 static inline bool pgtable_l5_enabled(void) { return false; }
 
+/* Match p4d_offset folding in <asm/generic/pgtable-nop4d.h> */
+#define p4d_set_fixmap(addr)		NULL
+#define p4d_set_fixmap_offset(p4dp, addr)	((p4d_t *)p4dp)
+#define p4d_clear_fixmap()
+
+#define p4d_offset_kimg(dir,addr)	((p4d_t *)dir)
+
 #endif  /* CONFIG_PGTABLE_LEVELS > 4 */
 
 #define pgd_ERROR(e)	\
diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
index 9404f282f829..d22506e9c7fd 100644
--- a/arch/arm64/mm/fixmap.c
+++ b/arch/arm64/mm/fixmap.c
@@ -104,7 +104,7 @@ void __init early_fixmap_init(void)
 	unsigned long end = FIXADDR_TOP;
 
 	pgd_t *pgdp = pgd_offset_k(addr);
-	p4d_t *p4dp = p4d_offset(pgdp, addr);
+	p4d_t *p4dp = p4d_offset_kimg(pgdp, addr);
 
 	early_fixmap_init_pud(p4dp, addr, end);
 }
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index d30ae4d3fdd9..8e5b3a7c5afd 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -313,15 +313,14 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
 	} while (addr = next, addr != end);
 }
 
-static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
+static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
 			   phys_addr_t phys, pgprot_t prot,
 			   phys_addr_t (*pgtable_alloc)(int),
 			   int flags)
 {
 	unsigned long next;
-	pud_t *pudp;
-	p4d_t *p4dp = p4d_offset(pgdp, addr);
 	p4d_t p4d = READ_ONCE(*p4dp);
+	pud_t *pudp;
 
 	if (p4d_none(p4d)) {
 		p4dval_t p4dval = P4D_TYPE_TABLE | P4D_TABLE_UXN;
@@ -369,6 +368,46 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
 	pud_clear_fixmap();
 }
 
+static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
+			   phys_addr_t phys, pgprot_t prot,
+			   phys_addr_t (*pgtable_alloc)(int),
+			   int flags)
+{
+	unsigned long next;
+	pgd_t pgd = READ_ONCE(*pgdp);
+	p4d_t *p4dp;
+
+	if (pgd_none(pgd)) {
+		pgdval_t pgdval = PGD_TYPE_TABLE | PGD_TABLE_UXN;
+		phys_addr_t p4d_phys;
+
+		if (flags & NO_EXEC_MAPPINGS)
+			pgdval |= PGD_TABLE_PXN;
+		BUG_ON(!pgtable_alloc);
+		p4d_phys = pgtable_alloc(P4D_SHIFT);
+		__pgd_populate(pgdp, p4d_phys, pgdval);
+		pgd = READ_ONCE(*pgdp);
+	}
+	BUG_ON(pgd_bad(pgd));
+
+	p4dp = p4d_set_fixmap_offset(pgdp, addr);
+	do {
+		p4d_t old_p4d = READ_ONCE(*p4dp);
+
+		next = p4d_addr_end(addr, end);
+
+		alloc_init_pud(p4dp, addr, next, phys, prot,
+			       pgtable_alloc, flags);
+
+		BUG_ON(p4d_val(old_p4d) != 0 &&
+		       p4d_val(old_p4d) != READ_ONCE(p4d_val(*p4dp)));
+
+		phys += next - addr;
+	} while (p4dp++, addr = next, addr != end);
+
+	p4d_clear_fixmap();
+}
+
 static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
 					unsigned long virt, phys_addr_t size,
 					pgprot_t prot,
@@ -391,7 +430,7 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
 
 	do {
 		next = pgd_addr_end(addr, end);
-		alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc,
+		alloc_init_p4d(pgdp, addr, next, phys, prot, pgtable_alloc,
 			       flags);
 		phys += next - addr;
 	} while (pgdp++, addr = next, addr != end);
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:21 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:21 +0100
Subject: [PATCH v8 35/43] arm64: kasan: Reduce minimum shadow alignment and
 enable 5 level paging
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-80-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Allow the KASAN init code to deal with 5 levels of paging, and relax the
requirement that the shadow region is aligned to the top level pgd_t
size. This is necessary for LPA2 based 52-bit virtual addressing, where
the KASAN shadow will never be aligned to the pgd_t size. Allowing this
also enables the 16k/48-bit case for KASAN, which is a nice bonus.

This involves some hackery to manipulate the root and next level page
tables without having to distinguish all the various configurations,
including 16k/48-bits (which has a two entry pgd_t level), and LPA2
configurations running with one translation level less on non-LPA2
hardware.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/Kconfig         |   2 +-
 arch/arm64/mm/kasan_init.c | 148 +++++++++++++++++---
 2 files changed, 130 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 8c2c36fffcf5..9ca3316d6379 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -164,7 +164,7 @@ config ARM64
 	select HAVE_ARCH_HUGE_VMAP
 	select HAVE_ARCH_JUMP_LABEL
 	select HAVE_ARCH_JUMP_LABEL_RELATIVE
-	select HAVE_ARCH_KASAN if !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
+	select HAVE_ARCH_KASAN
 	select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
 	select HAVE_ARCH_KASAN_SW_TAGS if HAVE_ARCH_KASAN
 	select HAVE_ARCH_KASAN_HW_TAGS if (HAVE_ARCH_KASAN && ARM64_MTE)
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index a86ab99587c9..fbddbf9faf19 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -23,7 +23,7 @@
 
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 
-static pgd_t tmp_pg_dir[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE);
+static pgd_t tmp_pg_dir[PTRS_PER_PTE] __initdata __aligned(PAGE_SIZE);
 
 /*
  * The p*d_populate functions call virt_to_phys implicitly so they can't be used
@@ -99,6 +99,19 @@ static pud_t *__init kasan_pud_offset(p4d_t *p4dp, unsigned long addr, int node,
 	return early ? pud_offset_kimg(p4dp, addr) : pud_offset(p4dp, addr);
 }
 
+static p4d_t *__init kasan_p4d_offset(pgd_t *pgdp, unsigned long addr, int node,
+				      bool early)
+{
+	if (pgd_none(READ_ONCE(*pgdp))) {
+		phys_addr_t p4d_phys = early ?
+				__pa_symbol(kasan_early_shadow_p4d)
+					: kasan_alloc_zeroed_page(node);
+		__pgd_populate(pgdp, p4d_phys, PGD_TYPE_TABLE);
+	}
+
+	return early ? p4d_offset_kimg(pgdp, addr) : p4d_offset(pgdp, addr);
+}
+
 static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
 				      unsigned long end, int node, bool early)
 {
@@ -144,12 +157,12 @@ static void __init kasan_p4d_populate(pgd_t *pgdp, unsigned long addr,
 				      unsigned long end, int node, bool early)
 {
 	unsigned long next;
-	p4d_t *p4dp = p4d_offset(pgdp, addr);
+	p4d_t *p4dp = kasan_p4d_offset(pgdp, addr, node, early);
 
 	do {
 		next = p4d_addr_end(addr, end);
 		kasan_pud_populate(p4dp, addr, next, node, early);
-	} while (p4dp++, addr = next, addr != end);
+	} while (p4dp++, addr = next, addr != end && p4d_none(READ_ONCE(*p4dp)));
 }
 
 static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
@@ -165,19 +178,48 @@ static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
 	} while (pgdp++, addr = next, addr != end);
 }
 
+#if defined(CONFIG_ARM64_64K_PAGES) || CONFIG_PGTABLE_LEVELS > 4
+#define SHADOW_ALIGN	P4D_SIZE
+#else
+#define SHADOW_ALIGN	PUD_SIZE
+#endif
+
+/*
+ * Return whether 'addr' is aligned to the size covered by a root level
+ * descriptor.
+ */
+static bool __init root_level_aligned(u64 addr)
+{
+	int shift = (ARM64_HW_PGTABLE_LEVELS(vabits_actual) - 1) * (PAGE_SHIFT - 3);
+
+	return (addr % (PAGE_SIZE << shift)) == 0;
+}
+
 /* The early shadow maps everything to a single page of zeroes */
 asmlinkage void __init kasan_early_init(void)
 {
 	BUILD_BUG_ON(KASAN_SHADOW_OFFSET !=
 		KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT)));
-	/*
-	 * We cannot check the actual value of KASAN_SHADOW_START during build,
-	 * as it depends on vabits_actual. As a best-effort approach, check
-	 * potential values calculated based on VA_BITS and VA_BITS_MIN.
-	 */
-	BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS), PGDIR_SIZE));
-	BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS_MIN), PGDIR_SIZE));
-	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
+	BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS), SHADOW_ALIGN));
+	BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS_MIN), SHADOW_ALIGN));
+	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, SHADOW_ALIGN));
+
+	if (!root_level_aligned(KASAN_SHADOW_START)) {
+		/*
+		 * The start address is misaligned, and so the next level table
+		 * will be shared with the linear region. This can happen with
+		 * 4 or 5 level paging, so install a generic pte_t[] as the
+		 * next level. This prevents the kasan_pgd_populate call below
+		 * from inserting an entry that refers to the shared KASAN zero
+		 * shadow pud_t[]/p4d_t[], which could end up getting corrupted
+		 * when the linear region is mapped.
+		 */
+		static pte_t tbl[PTRS_PER_PTE] __page_aligned_bss;
+		pgd_t *pgdp = pgd_offset_k(KASAN_SHADOW_START);
+
+		set_pgd(pgdp, __pgd(__pa_symbol(tbl) | PGD_TYPE_TABLE));
+	}
+
 	kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE,
 			   true);
 }
@@ -189,20 +231,75 @@ static void __init kasan_map_populate(unsigned long start, unsigned long end,
 	kasan_pgd_populate(start & PAGE_MASK, PAGE_ALIGN(end), node, false);
 }
 
-static void __init clear_pgds(unsigned long start,
-			unsigned long end)
+/*
+ * Return the descriptor index of 'addr' in the root level table
+ */
+static int __init root_level_idx(u64 addr)
 {
 	/*
-	 * Remove references to kasan page tables from
-	 * swapper_pg_dir. pgd_clear() can't be used
-	 * here because it's nop on 2,3-level pagetable setups
+	 * On 64k pages, the TTBR1 range root tables are extended for 52-bit
+	 * virtual addressing, and TTBR1 will simply point to the pgd_t entry
+	 * that covers the start of the 48-bit addressable VA space if LVA is
+	 * not implemented. This means we need to index the table as usual,
+	 * instead of masking off bits based on vabits_actual.
 	 */
-	for (; start < end; start += PGDIR_SIZE)
-		set_pgd(pgd_offset_k(start), __pgd(0));
+	u64 vabits = IS_ENABLED(CONFIG_ARM64_64K_PAGES) ? VA_BITS
+							: vabits_actual;
+	int shift = (ARM64_HW_PGTABLE_LEVELS(vabits) - 1) * (PAGE_SHIFT - 3);
+
+	return (addr & ~_PAGE_OFFSET(vabits)) >> (shift + PAGE_SHIFT);
+}
+
+/*
+ * Clone a next level table from swapper_pg_dir into tmp_pg_dir
+ */
+static void __init clone_next_level(u64 addr, pgd_t *tmp_pg_dir, pud_t *pud)
+{
+	int idx = root_level_idx(addr);
+	pgd_t pgd = READ_ONCE(swapper_pg_dir[idx]);
+	pud_t *pudp = (pud_t *)__phys_to_kimg(__pgd_to_phys(pgd));
+
+	memcpy(pud, pudp, PAGE_SIZE);
+	tmp_pg_dir[idx] = __pgd(__phys_to_pgd_val(__pa_symbol(pud)) |
+				PUD_TYPE_TABLE);
+}
+
+/*
+ * Return the descriptor index of 'addr' in the next level table
+ */
+static int __init next_level_idx(u64 addr)
+{
+	int shift = (ARM64_HW_PGTABLE_LEVELS(vabits_actual) - 2) * (PAGE_SHIFT - 3);
+
+	return (addr >> (shift + PAGE_SHIFT)) % PTRS_PER_PTE;
+}
+
+/*
+ * Dereference the table descriptor at 'pgd_idx' and clear the entries from
+ * 'start' to 'end' (exclusive) from the table.
+ */
+static void __init clear_next_level(int pgd_idx, int start, int end)
+{
+	pgd_t pgd = READ_ONCE(swapper_pg_dir[pgd_idx]);
+	pud_t *pudp = (pud_t *)__phys_to_kimg(__pgd_to_phys(pgd));
+
+	memset(&pudp[start], 0, (end - start) * sizeof(pud_t));
+}
+
+static void __init clear_shadow(u64 start, u64 end)
+{
+	int l = root_level_idx(start), m = root_level_idx(end);
+
+	if (!root_level_aligned(start))
+		clear_next_level(l++, next_level_idx(start), PTRS_PER_PTE);
+	if (!root_level_aligned(end))
+		clear_next_level(m, 0, next_level_idx(end));
+	memset(&swapper_pg_dir[l], 0, (m - l) * sizeof(pgd_t));
 }
 
 static void __init kasan_init_shadow(void)
 {
+	static pud_t pud[2][PTRS_PER_PUD] __initdata __aligned(PAGE_SIZE);
 	u64 kimg_shadow_start, kimg_shadow_end;
 	u64 mod_shadow_start;
 	u64 vmalloc_shadow_end;
@@ -224,10 +321,23 @@ static void __init kasan_init_shadow(void)
 	 * setup will be finished.
 	 */
 	memcpy(tmp_pg_dir, swapper_pg_dir, sizeof(tmp_pg_dir));
+
+	/*
+	 * If the start or end address of the shadow region is not aligned to
+	 * the root level size, we have to allocate a temporary next-level table
+	 * in each case, clone the next level of descriptors, and install the
+	 * table into tmp_pg_dir. Note that with 5 levels of paging, the next
+	 * level will in fact be p4d_t, but that makes no difference in this
+	 * case.
+	 */
+	if (!root_level_aligned(KASAN_SHADOW_START))
+		clone_next_level(KASAN_SHADOW_START, tmp_pg_dir, pud[0]);
+	if (!root_level_aligned(KASAN_SHADOW_END))
+		clone_next_level(KASAN_SHADOW_END, tmp_pg_dir, pud[1]);
 	dsb(ishst);
 	cpu_replace_ttbr1(lm_alias(tmp_pg_dir));
 
-	clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
+	clear_shadow(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
 	kasan_map_populate(kimg_shadow_start, kimg_shadow_end,
 			   early_pfn_to_nid(virt_to_pfn(lm_alias(KERNEL_START))));
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:26 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:26 +0100
Subject: [PATCH v8 40/43] arm64: Enable 52-bit virtual addressing for 4k and
 16k granule configs
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-85-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Update Kconfig to permit 4k and 16k granule configurations to be built
with 52-bit virtual addressing, now that all the prerequisites are in
place.

While at it, update the feature description so it matches on the
appropriate feature bits depending on the page size. For simplicity,
let's just keep ARM64_HAS_VA52 as the feature name.

Note that LPA2 based 52-bit virtual addressing requires 52-bit physical
addressing support to be enabled as well, as programming TCR.TxSZ to
values below 16 is not allowed unless TCR.DS is set, which is what
activates the 52-bit physical addressing support.

While supporting the converse (52-bit physical addressing without 52-bit
virtual addressing) would be possible in principle, let's keep things
simple, by only allowing these features to be enabled at the same time.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/Kconfig             | 17 ++++++++-------
 arch/arm64/kernel/cpufeature.c | 22 ++++++++++++++++----
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 9ca3316d6379..eed8fef08a10 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -368,7 +368,9 @@ config PGTABLE_LEVELS
 	default 3 if ARM64_64K_PAGES && (ARM64_VA_BITS_48 || ARM64_VA_BITS_52)
 	default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
 	default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
+	default 4 if ARM64_16K_PAGES && (ARM64_VA_BITS_48 || ARM64_VA_BITS_52)
 	default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
+	default 5 if ARM64_4K_PAGES && ARM64_VA_BITS_52
 
 config ARCH_SUPPORTS_UPROBES
 	def_bool y
@@ -396,13 +398,13 @@ config BUILTIN_RETURN_ADDRESS_STRIPS_PAC
 config KASAN_SHADOW_OFFSET
 	hex
 	depends on KASAN_GENERIC || KASAN_SW_TAGS
-	default 0xdfff800000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && !KASAN_SW_TAGS
-	default 0xdfffc00000000000 if ARM64_VA_BITS_47 && !KASAN_SW_TAGS
+	default 0xdfff800000000000 if (ARM64_VA_BITS_48 || (ARM64_VA_BITS_52 && !ARM64_16K_PAGES)) && !KASAN_SW_TAGS
+	default 0xdfffc00000000000 if (ARM64_VA_BITS_47 || ARM64_VA_BITS_52) && ARM64_16K_PAGES && !KASAN_SW_TAGS
 	default 0xdffffe0000000000 if ARM64_VA_BITS_42 && !KASAN_SW_TAGS
 	default 0xdfffffc000000000 if ARM64_VA_BITS_39 && !KASAN_SW_TAGS
 	default 0xdffffff800000000 if ARM64_VA_BITS_36 && !KASAN_SW_TAGS
-	default 0xefff800000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && KASAN_SW_TAGS
-	default 0xefffc00000000000 if ARM64_VA_BITS_47 && KASAN_SW_TAGS
+	default 0xefff800000000000 if (ARM64_VA_BITS_48 || (ARM64_VA_BITS_52 && !ARM64_16K_PAGES)) && KASAN_SW_TAGS
+	default 0xefffc00000000000 if (ARM64_VA_BITS_47 || ARM64_VA_BITS_52) && ARM64_16K_PAGES && KASAN_SW_TAGS
 	default 0xeffffe0000000000 if ARM64_VA_BITS_42 && KASAN_SW_TAGS
 	default 0xefffffc000000000 if ARM64_VA_BITS_39 && KASAN_SW_TAGS
 	default 0xeffffff800000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS
@@ -1310,7 +1312,7 @@ config ARM64_VA_BITS_48
 
 config ARM64_VA_BITS_52
 	bool "52-bit"
-	depends on ARM64_64K_PAGES && (ARM64_PAN || !ARM64_SW_TTBR0_PAN)
+	depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN
 	help
 	  Enable 52-bit virtual addressing for userspace when explicitly
 	  requested via a hint to mmap(). The kernel will also use 52-bit
@@ -1357,10 +1359,11 @@ choice
 
 config ARM64_PA_BITS_48
 	bool "48-bit"
+	depends on ARM64_64K_PAGES || !ARM64_VA_BITS_52
 
 config ARM64_PA_BITS_52
-	bool "52-bit (ARMv8.2)"
-	depends on ARM64_64K_PAGES
+	bool "52-bit"
+	depends on ARM64_64K_PAGES || ARM64_VA_BITS_52
 	depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN
 	help
 	  Enable support for a 52-bit physical address space, introduced as
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 94f035f6c421..0be9296e9253 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2703,15 +2703,29 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 	},
 #ifdef CONFIG_ARM64_VA_BITS_52
 	{
-		.desc = "52-bit Virtual Addressing (LVA)",
 		.capability = ARM64_HAS_VA52,
 		.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
-		.sys_reg = SYS_ID_AA64MMFR2_EL1,
-		.sign = FTR_UNSIGNED,
+		.matches = has_cpuid_feature,
 		.field_width = 4,
+#ifdef CONFIG_ARM64_64K_PAGES
+		.desc = "52-bit Virtual Addressing (LVA)",
+		.sign = FTR_SIGNED,
+		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.field_pos = ID_AA64MMFR2_EL1_VARange_SHIFT,
-		.matches = has_cpuid_feature,
 		.min_field_value = ID_AA64MMFR2_EL1_VARange_52,
+#else
+		.desc = "52-bit Virtual Addressing (LPA2)",
+		.sys_reg = SYS_ID_AA64MMFR0_EL1,
+#ifdef CONFIG_ARM64_4K_PAGES
+		.sign = FTR_SIGNED,
+		.field_pos = ID_AA64MMFR0_EL1_TGRAN4_SHIFT,
+		.min_field_value = ID_AA64MMFR0_EL1_TGRAN4_52_BIT,
+#else
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64MMFR0_EL1_TGRAN16_SHIFT,
+		.min_field_value = ID_AA64MMFR0_EL1_TGRAN16_52_BIT,
+#endif
+#endif
 	},
 #endif
 	{},
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:27 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:27 +0100
Subject: [PATCH v8 41/43] arm64: defconfig: Enable LPA2 support
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-86-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

We typically enable support in defconfig for all architectural features
for which we can detect at runtime if the hardware actually supports
them.

Now that we have implemented support for LPA2 based 52-bit virtual
addressing in a way that should not impact 48-bit operation on non-LPA2
CPU, we can do the same, and enable 52-bit virtual addressing by
default.

Catalin adds:

  Currently the "Virtual address space size" arch/arm64/Kconfig menu
  entry sets different defaults for each page size. However, all are
  overridden by the defconfig to 48 bits. Set the new default in
  Kconfig and remove the defconfig line.

[ardb: squash follow-up fix from Catalin]
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/Kconfig           | 4 +---
 arch/arm64/configs/defconfig | 1 -
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index eed8fef08a10..160856de9bbb 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1283,9 +1283,7 @@ endchoice
 
 choice
 	prompt "Virtual address space size"
-	default ARM64_VA_BITS_39 if ARM64_4K_PAGES
-	default ARM64_VA_BITS_47 if ARM64_16K_PAGES
-	default ARM64_VA_BITS_42 if ARM64_64K_PAGES
+	default ARM64_VA_BITS_52
 	help
 	  Allows choosing one of multiple possible virtual address
 	  space sizes. The level of translation table is determined by
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e6cf3e5d63c3..f086b0624ec8 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -76,7 +76,6 @@ CONFIG_ARCH_VEXPRESS=y
 CONFIG_ARCH_VISCONTI=y
 CONFIG_ARCH_XGENE=y
 CONFIG_ARCH_ZYNQMP=y
-CONFIG_ARM64_VA_BITS_48=y
 CONFIG_SCHED_MC=y
 CONFIG_SCHED_SMT=y
 CONFIG_NUMA=y
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:25 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:25 +0100
Subject: [PATCH v8 39/43] arm64: kvm: avoid CONFIG_PGTABLE_LEVELS for runtime levels
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-84-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

get_user_mapping_size() uses vabits_actual and CONFIG_PGTABLE_LEVELS to
provide the starting point for a table walk. This is fine for LVA, as
the number of translation levels is the same regardless of whether LVA
is enabled. However, with LPA2, this will no longer be the case, so
let's derive the number of levels from the number of VA bits directly.

Acked-by: Marc Zyngier <maz at kernel.org>
Acked-by: Oliver Upton <oliver.upton at linux.dev>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kvm/mmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 6fa9e816df40..cd9456a03e38 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -805,7 +805,7 @@ static int get_user_mapping_size(struct kvm *kvm, u64 addr)
 		.pgd		= (kvm_pteref_t)kvm->mm->pgd,
 		.ia_bits	= vabits_actual,
 		.start_level	= (KVM_PGTABLE_LAST_LEVEL -
-				   CONFIG_PGTABLE_LEVELS + 1),
+				   ARM64_HW_PGTABLE_LEVELS(pgt.ia_bits) + 1),
 		.mm_ops		= &kvm_user_mm_ops,
 	};
 	unsigned long flags;
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:28 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:28 +0100
Subject: [PATCH v8 42/43] mm: add arch hook to validate mmap() prot flags
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-87-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

Add a hook to permit architectures to perform validation on the prot
flags passed to mmap(), like arch_validate_prot() does for mprotect().
This will be used by arm64 to reject PROT_WRITE+PROT_EXEC mappings on
configurations that run with WXN enabled.

Reviewed-by: Kees Cook <keescook at chromium.org>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 include/linux/mman.h | 15 +++++++++++++++
 mm/mmap.c            |  3 +++
 2 files changed, 18 insertions(+)

diff --git a/include/linux/mman.h b/include/linux/mman.h
index dc7048824be8..ec5e7f606e43 100644
--- a/include/linux/mman.h
+++ b/include/linux/mman.h
@@ -124,6 +124,21 @@ static inline bool arch_validate_flags(unsigned long flags)
 #define arch_validate_flags arch_validate_flags
 #endif
 
+#ifndef arch_validate_mmap_prot
+/*
+ * This is called from mmap(), which ignores unknown prot bits so the default
+ * is to accept anything.
+ *
+ * Returns true if the prot flags are valid
+ */
+static inline bool arch_validate_mmap_prot(unsigned long prot,
+					   unsigned long addr)
+{
+	return true;
+}
+#define arch_validate_mmap_prot arch_validate_mmap_prot
+#endif
+
 /*
  * Optimisation macro.  It is equivalent to:
  *      (x & bit1) ? bit2 : 0
diff --git a/mm/mmap.c b/mm/mmap.c
index d89770eaab6b..977a8c3fd9f5 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1229,6 +1229,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
 		if (!(file && path_noexec(&file->f_path)))
 			prot |= PROT_EXEC;
 
+	if (!arch_validate_mmap_prot(prot, addr))
+		return -EACCES;
+
 	/* force arch specific MAP_FIXED handling in get_unmapped_area */
 	if (flags & MAP_FIXED_NOREPLACE)
 		flags |= MAP_FIXED;
-- 
2.43.0.687.g38aa6559b0-goog



From ardb+git at google.com  Wed Feb 14 04:29:29 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 13:29:29 +0100
Subject: [PATCH v8 43/43] arm64: mm: add support for WXN memory translation attribute
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <20240214122845.2033971-88-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

The AArch64 virtual memory system supports a global WXN control, which
can be enabled to make all writable mappings implicitly no-exec. This is
a useful hardening feature, as it prevents mistakes in managing page
table permissions from being exploited to attack the system.

When enabled at EL1, the restrictions apply to both EL1 and EL0. EL1 is
completely under our control, and has been cleaned up to allow WXN to be
enabled from boot onwards. EL0 is not under our control, but given that
widely deployed security features such as selinux or PaX already limit
the ability of user space to create mappings that are writable and
executable at the same time, the impact of enabling this for EL0 is
expected to be limited. (For this reason, common user space libraries
that have a legitimate need for manipulating executable code already
carry fallbacks such as [0].)

If enabled at compile time, the feature can still be disabled at boot if
needed, by passing arm64.nowxn on the kernel command line.

[0] https://github.com/libffi/libffi/blob/master/src/closures.c#L440

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Kees Cook <keescook at chromium.org>
---
 arch/arm64/Kconfig                    | 11 ++++++
 arch/arm64/include/asm/cpufeature.h   |  8 +++++
 arch/arm64/include/asm/mman.h         | 36 ++++++++++++++++++++
 arch/arm64/include/asm/mmu_context.h  | 30 +++++++++++++++-
 arch/arm64/kernel/pi/idreg-override.c |  4 ++-
 arch/arm64/kernel/pi/map_kernel.c     | 23 +++++++++++++
 arch/arm64/mm/proc.S                  |  6 ++++
 7 files changed, 116 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 160856de9bbb..7761ffc6dbcf 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1608,6 +1608,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_WXN
+	bool "Enable WXN attribute so all writable mappings are non-exec"
+	help
+	  Set the WXN bit in the SCTLR system register so that all writable
+	  mappings are treated as if the PXN/UXN bit is set as well.
+	  If this is set to Y, it can still be disabled at runtime by
+	  passing 'arm64.nowxn' on the kernel command line.
+
+	  This should only be set if no software needs to be supported that
+	  relies on being able to execute from writable mappings.
+
 config ARM64_SW_TTBR0_PAN
 	bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
 	help
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index a8f97690ce1f..ee33b7e52da7 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -18,6 +18,7 @@
 #define ARM64_SW_FEATURE_OVERRIDE_NOKASLR	0
 #define ARM64_SW_FEATURE_OVERRIDE_HVHE		4
 #define ARM64_SW_FEATURE_OVERRIDE_RODATA_OFF	8
+#define ARM64_SW_FEATURE_OVERRIDE_NOWXN		12
 
 #ifndef __ASSEMBLY__
 
@@ -962,6 +963,13 @@ static inline bool kaslr_disabled_cmdline(void)
 	return arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_NOKASLR);
 }
 
+static inline bool arm64_wxn_enabled(void)
+{
+	if (!IS_ENABLED(CONFIG_ARM64_WXN))
+		return false;
+	return !arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_NOWXN);
+}
+
 u32 get_kvm_ipa_limit(void);
 void dump_cpu_features(void);
 
diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h
index 5966ee4a6154..6d4940342ba7 100644
--- a/arch/arm64/include/asm/mman.h
+++ b/arch/arm64/include/asm/mman.h
@@ -35,11 +35,40 @@ 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 bool arm64_check_wx_prot(unsigned long prot,
+				       struct task_struct *tsk)
+{
+	/*
+	 * When we are running with SCTLR_ELx.WXN==1, writable mappings are
+	 * implicitly non-executable. This means we should reject such mappings
+	 * when user space attempts to create them using mmap() or mprotect().
+	 */
+	if (arm64_wxn_enabled() &&
+	    ((prot & (PROT_WRITE | PROT_EXEC)) == (PROT_WRITE | PROT_EXEC))) {
+		/*
+		 * User space libraries such as libffi carry elaborate
+		 * heuristics to decide whether it is worth it to even attempt
+		 * to create writable executable mappings, as PaX or selinux
+		 * enabled systems will outright reject it. They will usually
+		 * fall back to something else (e.g., two separate shared
+		 * mmap()s of a temporary file) on failure.
+		 */
+		pr_info_ratelimited(
+			"process %s (%d) attempted to create PROT_WRITE+PROT_EXEC mapping\n",
+			tsk->comm, tsk->pid);
+		return false;
+	}
+	return true;
+}
+
 static inline bool arch_validate_prot(unsigned long prot,
 	unsigned long addr __always_unused)
 {
 	unsigned long supported = PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM;
 
+	if (!arm64_check_wx_prot(prot, current))
+		return false;
+
 	if (system_supports_bti())
 		supported |= PROT_BTI;
 
@@ -50,6 +79,13 @@ static inline bool arch_validate_prot(unsigned long prot,
 }
 #define arch_validate_prot(prot, addr) arch_validate_prot(prot, addr)
 
+static inline bool arch_validate_mmap_prot(unsigned long prot,
+					   unsigned long addr)
+{
+	return arm64_check_wx_prot(prot, current);
+}
+#define arch_validate_mmap_prot arch_validate_mmap_prot
+
 static inline bool arch_validate_flags(unsigned long vm_flags)
 {
 	if (!system_supports_mte())
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index c768d16b81a4..f0fe2d09d139 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -20,13 +20,41 @@
 #include <asm/cpufeature.h>
 #include <asm/daifflags.h>
 #include <asm/proc-fns.h>
-#include <asm-generic/mm_hooks.h>
 #include <asm/cputype.h>
 #include <asm/sysreg.h>
 #include <asm/tlbflush.h>
 
 extern bool rodata_full;
 
+static inline int arch_dup_mmap(struct mm_struct *oldmm,
+				struct mm_struct *mm)
+{
+	return 0;
+}
+
+static inline void arch_exit_mmap(struct mm_struct *mm)
+{
+}
+
+static inline void arch_unmap(struct mm_struct *mm,
+			unsigned long start, unsigned long end)
+{
+}
+
+static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
+		bool write, bool execute, bool foreign)
+{
+	if (IS_ENABLED(CONFIG_ARM64_WXN) && execute &&
+	    (vma->vm_flags & (VM_WRITE | VM_EXEC)) == (VM_WRITE | VM_EXEC)) {
+		pr_warn_ratelimited(
+			"process %s (%d) attempted to execute from writable memory\n",
+			current->comm, current->pid);
+		/* disallow unless the nowxn override is set */
+		return !arm64_wxn_enabled();
+	}
+	return true;
+}
+
 static inline void contextidr_thread_switch(struct task_struct *next)
 {
 	if (!IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR))
diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
index aad399796e81..bccfee34f62f 100644
--- a/arch/arm64/kernel/pi/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -189,6 +189,7 @@ static const struct ftr_set_desc sw_features __prel64_initconst = {
 		FIELD("nokaslr", ARM64_SW_FEATURE_OVERRIDE_NOKASLR, NULL),
 		FIELD("hvhe", ARM64_SW_FEATURE_OVERRIDE_HVHE, hvhe_filter),
 		FIELD("rodataoff", ARM64_SW_FEATURE_OVERRIDE_RODATA_OFF, NULL),
+		FIELD("nowxn", ARM64_SW_FEATURE_OVERRIDE_NOWXN, NULL),
 		{}
 	},
 };
@@ -221,8 +222,9 @@ static const struct {
 	{ "arm64.nomops",		"id_aa64isar2.mops=0" },
 	{ "arm64.nomte",		"id_aa64pfr1.mte=0" },
 	{ "nokaslr",			"arm64_sw.nokaslr=1" },
-	{ "rodata=off",			"arm64_sw.rodataoff=1" },
+	{ "rodata=off",			"arm64_sw.rodataoff=1 arm64_sw.nowxn=1" },
 	{ "arm64.nolva",		"id_aa64mmfr2.varange=0" },
+	{ "arm64.nowxn",		"arm64_sw.nowxn=1" },
 };
 
 static int __init parse_hexdigit(const char *p, u64 *v)
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
index 5fa08e13e17e..cac1e1f63c44 100644
--- a/arch/arm64/kernel/pi/map_kernel.c
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -132,6 +132,25 @@ static void __init map_kernel(u64 kaslr_offset, u64 va_offset, int root_level)
 	idmap_cpu_replace_ttbr1(swapper_pg_dir);
 }
 
+static void noinline __section(".idmap.text") disable_wxn(void)
+{
+	u64 sctlr = read_sysreg(sctlr_el1) & ~SCTLR_ELx_WXN;
+
+	/*
+	 * We cannot safely clear the WXN bit while the MMU and caches are on,
+	 * so turn the MMU off, flush the TLBs and turn it on again but with
+	 * the WXN bit cleared this time.
+	 */
+	asm("	msr	sctlr_el1, %0		;"
+	    "	isb				;"
+	    "	tlbi    vmalle1			;"
+	    "	dsb     nsh			;"
+	    "	isb				;"
+	    "	msr     sctlr_el1, %1		;"
+	    "	isb				;"
+	    ::	"r"(sctlr & ~SCTLR_ELx_M), "r"(sctlr));
+}
+
 static void noinline __section(".idmap.text") set_ttbr0_for_lpa2(u64 ttbr)
 {
 	u64 sctlr = read_sysreg(sctlr_el1);
@@ -229,6 +248,10 @@ asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt)
 	if (va_bits > VA_BITS_MIN)
 		sysreg_clear_set(tcr_el1, TCR_T1SZ_MASK, TCR_T1SZ(va_bits));
 
+	if (IS_ENABLED(CONFIG_ARM64_WXN) &&
+	    arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_NOWXN))
+		disable_wxn();
+
 	/*
 	 * The virtual KASLR displacement modulo 2MiB is decided by the
 	 * physical placement of the image, as otherwise, we might not be able
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 9d40f3ffd8d2..bfd2ad896108 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -546,6 +546,12 @@ alternative_else_nop_endif
 	 * Prepare SCTLR
 	 */
 	mov_q	x0, INIT_SCTLR_EL1_MMU_ON
+#ifdef CONFIG_ARM64_WXN
+	ldr_l	x1, arm64_sw_feature_override + FTR_OVR_VAL_OFFSET
+	tst	x1, #0xf << ARM64_SW_FEATURE_OVERRIDE_NOWXN
+	orr	x1, x0, #SCTLR_ELx_WXN
+	csel	x0, x0, x1, ne
+#endif
 	ret					// return to head.S
 
 	.unreq	mair
-- 
2.43.0.687.g38aa6559b0-goog



From aford173 at gmail.com  Wed Feb 14 04:32:40 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed, 14 Feb 2024 06:32:40 -0600
Subject: [PATCH V4 1/6] dt-bindings: phy: add binding for the i.MX8MP HDMI PHY
In-Reply-To: <20240214121438.331a9f20@booty>
References: <20240210204606.11944-1-aford173@gmail.com> <20240210204606.11944-2-aford173@gmail.com>
 <20240214121438.331a9f20@booty>
Message-ID: <CAHCN7x+y9bcdEqDkpma1oaY88WvjHsWUOm55B4XNsPy5HM_-vw@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:14?AM Luca Ceresoli <luca.ceresoli at bootlin.com> wrote:
>
> Hi Adam,
>
> On Sat, 10 Feb 2024 14:45:57 -0600
> Adam Ford <aford173 at gmail.com> wrote:
>
> > From: Lucas Stach <l.stach at pengutronix.de>
> >
> > Add a DT binding for the HDMI PHY found on the i.MX8MP SoC.
> >
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
> > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>
> I was a bit puzzled by this v4 series as it comes after v8... however
> thanks for keeping up!

It was confusing to me to try and figure out where the latest of each
of the various components were found.  I tried to explain it in the
cover letter, but basically the previous V8 was due to the fact that
some portion of it had been attempted 7 times.  When it was brought to
my attention that the PHY driver I used was not he right one and the
HDMI-TX and the PVI driver were already applied, I reverted to using
the revision history of the version of the PHY driver I pulled which
was V3 and with my changes became V4.

I debated on making this V9, but inreality this code was only
attempted 3 times, and the subsequent device tree stuff had undergone
some changes, but it was easier to keep them paired together with the
PHY driver so the series could be applied as a whole.

I will be making a V5 due to some build-bot feedback and your
feedback, but I'll be sure to pull your tags when I try again.  I just
want to give people around a week to mull it over and test it.

adam
>
> This patch is identical to the v8 I already reviewed, so:
>
> Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


From aford173 at gmail.com  Wed Feb 14 04:35:36 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed, 14 Feb 2024 06:35:36 -0600
Subject: [PATCH V4 2/6] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240214121448.451e2e1c@booty>
References: <20240210204606.11944-1-aford173@gmail.com> <20240210204606.11944-3-aford173@gmail.com>
 <20240214121448.451e2e1c@booty>
Message-ID: <CAHCN7xKa3svzoRiQZ=KO-zwpmXL7Dw7hOp7B0MF-2EQCQ=f-eA@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:14?AM Luca Ceresoli <luca.ceresoli at bootlin.com> wrote:
>
> On Sat, 10 Feb 2024 14:45:58 -0600
> Adam Ford <aford173 at gmail.com> wrote:
>
> > From: Lucas Stach <l.stach at pengutronix.de>
> >
> > This adds the driver for the Samsung HDMI PHY found on the
> > i.MX8MP SoC. Based on downstream implementation from
> > Sandor Yu <Sandor.yu at nxp.com>.  According to the TRM, the PHY
> > receives parallel data from the link and serializes it.  It
> > also sets the PLL clock needed for the TX serializer.
> >
> > Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v2)
> > Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
> > Co-developed-by: Marco Felsch <m.felsch at pengutronix.de>
> > Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> # Kontron BL
> > Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
>
> [...]
>
> > +static int phy_clk_register(struct fsl_samsung_hdmi_phy *phy)
> > +{
> > +     struct device *dev = phy->dev;
> > +     struct device_node *np = dev->of_node;
> > +     struct clk_init_data init;
> > +     const char *parent_name;
> > +     struct clk *phyclk;
> > +     int ret;
> > +
> > +     parent_name = __clk_get_name(phy->refclk);
> > +
> > +     init.parent_names = &parent_name;
> > +     init.num_parents = 1;
> > +     init.flags = 0;
> > +     init.name = "hdmi_pclk";
> > +     init.ops = &phy_clk_ops;
> > +
> > +     phy->hw.init = &init;
> > +
> > +     phyclk = devm_clk_register(dev, &phy->hw);
> > +     if (IS_ERR(phyclk))
> > +             return dev_err_probe(dev, PTR_ERR(phyclk),
> > +                                  "failed to register clock\n");
> > +
> > +     ret = of_clk_add_provider(np, of_clk_src_simple_get, phyclk);
>
> As per my v8 review, this function is deprecated:
> https://elixir.bootlin.com/linux/v6.8-rc4/source/drivers/clk/clk.c#L4881
>

When I found out that the entire driver I pulled was the wrong
starting point, and noticed that this version had very little in
common with the previous one, I didn't review the feedback knowing tha
tI would have thrown away any of the tags from it since it was such a
drastic change.  I should have caught it, but I missed it, so
apologies for that.  I will be sure to include this feedback in the
next attempt.


> However:
>
> [Tested using Avnet MSC SM2S-IMX8PLUS SoM on Avnet MSC SM2-MB-EP1]
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

Thanks for testing.

adam
>
> Luca
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


From aford173 at gmail.com  Wed Feb 14 04:36:36 2024
From: aford173 at gmail.com (Adam Ford)
Date: Wed, 14 Feb 2024 06:36:36 -0600
Subject: [PATCH V4 4/6] arm64: dts: imx8mp: add HDMI irqsteer
In-Reply-To: <20240214121517.54552a4a@booty>
References: <20240210204606.11944-1-aford173@gmail.com> <20240210204606.11944-5-aford173@gmail.com>
 <20240214121517.54552a4a@booty>
Message-ID: <CAHCN7xLnXMZJkTjWBP5HW0h2-bUOyeNEL2oO0rnV5tNaz9Hv7A@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:15?AM Luca Ceresoli <luca.ceresoli at bootlin.com> wrote:
>
> On Sat, 10 Feb 2024 14:46:00 -0600
> Adam Ford <aford173 at gmail.com> wrote:
>
> > From: Lucas Stach <l.stach at pengutronix.de>
> >
> > The HDMI irqsteer is a secondary interrupt controller within the HDMI
> > subsystem that maps all HDMI peripheral IRQs into a single upstream
> > IRQ line.
> >
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
> > ---
> > V2:  Add my (Adam) s-o-b and re-order position under AIPS4
> > ---
> >  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > index 0730d4cf9bc4..9b8ab367d774 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > @@ -1927,6 +1927,19 @@ hdmi_blk_ctrl: blk-ctrl at 32fc0000 {
> >                                                    "hdcp", "hrv";
> >                               #power-domain-cells = <1>;
> >                       };
> > +
> > +                     irqsteer_hdmi: interrupt-controller at 32fc2000 {
> > +                             compatible = "fsl,imx-irqsteer";
> > +                             reg = <0x32fc2000 0x44>;
>
> The last register being at offset 0x44, this should be <0x32fc2000
> 0x48> or even <... 0x1000> as the TRM mentions a 4 kB size.

I'll do 0x1000 in the next revision to match the documentation since
there doesn't appear to be any overlap.

adam
>
> [Tested using Avnet MSC SM2S-IMX8PLUS SoM on Avnet MSC SM2-MB-EP1]
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
>
>
> Luca
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


From devarsht at ti.com  Wed Feb 14 04:51:50 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Wed, 14 Feb 2024 18:21:50 +0530
Subject: [PATCH v2 1/2] dt-bindings: display: ti,am65x-dss: Add support for common1 region
In-Reply-To: <20240214125151.1965137-1-devarsht@ti.com>
References: <20240214125151.1965137-1-devarsht@ti.com>
Message-ID: <20240214125151.1965137-2-devarsht@ti.com>

TI keystone display subsystem present in AM65 and other SoCs such as AM62
support two separate register spaces namely "common" and "common1" which
can be used by two separate hosts to program the display controller as
described in respective Technical Reference Manuals [1].

The common1 register space has similar set of configuration registers as
supported in common register space except the global configuration
registers which are exclusive to common region.

This adds binding for "common1" register region too as supported by the
hardware.

[1]:
AM62x TRM:
https://www.ti.com/lit/pdf/spruiv7 (Section 14.8.9.1 DSS Registers)

AM65x TRM:
https://www.ti.com/lit/pdf/spruid7 (Section 12.6.5 DSS Registers)

AM62A TRM:
https://www.ti.com/lit/pdf/spruj16 (Section 14.9.9.1 DSS Registers)

Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
V2: Add Acked-by tag
---
 .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
index b6767ef0d24d..55e3e490d0e6 100644
--- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
+++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
@@ -37,6 +37,7 @@ properties:
       - description: OVR2 overlay manager for vp2
       - description: VP1 video port 1
       - description: VP2 video port 2
+      - description: common1 DSS register area
 
   reg-names:
     items:
@@ -47,6 +48,7 @@ properties:
       - const: ovr2
       - const: vp1
       - const: vp2
+      - const: common1
 
   clocks:
     items:
@@ -147,9 +149,10 @@ examples:
                     <0x04a07000 0x1000>, /* ovr1 */
                     <0x04a08000 0x1000>, /* ovr2 */
                     <0x04a0a000 0x1000>, /* vp1 */
-                    <0x04a0b000 0x1000>; /* vp2 */
+                    <0x04a0b000 0x1000>, /* vp2 */
+                    <0x04a01000 0x1000>; /* common1 */
             reg-names = "common", "vidl1", "vid",
-                    "ovr1", "ovr2", "vp1", "vp2";
+                    "ovr1", "ovr2", "vp1", "vp2", "common1";
             ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
             power-domains = <&k3_pds 67 TI_SCI_PD_EXCLUSIVE>;
             clocks =        <&k3_clks 67 1>,
-- 
2.34.1



From devarsht at ti.com  Wed Feb 14 04:51:49 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Wed, 14 Feb 2024 18:21:49 +0530
Subject: [PATCH v2 0/2] Add common1 region for AM62, AM62A & AM65x
Message-ID: <20240214125151.1965137-1-devarsht@ti.com>

This adds DSS common1 region for respective SoCs supporting it.

Devarsh Thakkar (2):
  dt-bindings: display: ti,am65x-dss: Add support for common1 region
  arm64: dts: ti: Add common1 register space for AM62x, AM62A & AM65x
    SoCs

 .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi                   | 5 +++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi                  | 5 +++--
 arch/arm64/boot/dts/ti/k3-am65-main.dtsi                   | 5 +++--
 4 files changed, 14 insertions(+), 8 deletions(-)

-- 
2.34.1



From devarsht at ti.com  Wed Feb 14 04:51:51 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Wed, 14 Feb 2024 18:21:51 +0530
Subject: [PATCH v2 2/2] arm64: dts: ti: Add common1 register space for AM62x, AM62A & AM65x SoCs
In-Reply-To: <20240214125151.1965137-1-devarsht@ti.com>
References: <20240214125151.1965137-1-devarsht@ti.com>
Message-ID: <20240214125151.1965137-3-devarsht@ti.com>

This adds common1 register space for AM62x, AM62A and AM65x SoC's which are
using TI's Keystone display hardware and supporting it as described in
Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml

Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
---
V2: Add common1 region for AM62A SoC too
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi  | 5 +++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 5 +++--
 arch/arm64/boot/dts/ti/k3-am65-main.dtsi  | 5 +++--
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index fe0cc4a9a501..8cee4d94cdd3 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -779,9 +779,10 @@ dss: dss at 30200000 {
 		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
 		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
 		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
-		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			    "ovr1", "ovr2", "vp1", "vp2";
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
 		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 186 6>,
 			 <&dss_vp1_clk>,
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 972971159a62..f475daea548e 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -994,9 +994,10 @@ dss: dss at 30200000 {
 		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
 		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
 		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Tied OFF in the SoC */
-		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			    "ovr1", "ovr2", "vp1", "vp2";
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
 		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 186 6>,
 			 <&k3_clks 186 0>,
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index 07010d31350e..ff857117d719 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -991,9 +991,10 @@ dss: dss at 4a00000 {
 		      <0x0 0x04a07000 0x0 0x1000>, /* ovr1 */
 		      <0x0 0x04a08000 0x0 0x1000>, /* ovr2 */
 		      <0x0 0x04a0a000 0x0 0x1000>, /* vp1 */
-		      <0x0 0x04a0b000 0x0 0x1000>; /* vp2 */
+		      <0x0 0x04a0b000 0x0 0x1000>, /* vp2 */
+		      <0x0 0x04a01000 0x0 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			"ovr1", "ovr2", "vp1", "vp2";
+			"ovr1", "ovr2", "vp1", "vp2", "common1";
 
 		ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
 
-- 
2.34.1



From lkp at intel.com  Wed Feb 14 05:01:22 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 14 Feb 2024 21:01:22 +0800
Subject: [PATCH 1/3] tee: optee: Move pool_op helper functions
In-Reply-To: <20240213145239.379875-2-balint.dobszay@arm.com>
References: <20240213145239.379875-2-balint.dobszay@arm.com>
Message-ID: <202402142042.JLQEGKBr-lkp@intel.com>

Hi Balint,

kernel test robot noticed the following build errors:

[auto build test ERROR on lwn/docs-next]
[also build test ERROR on soc/for-next linus/master v6.8-rc4 next-20240214]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Balint-Dobszay/tee-optee-Move-pool_op-helper-functions/20240213-225716
base:   git://git.lwn.net/linux.git docs-next
patch link:    https://lore.kernel.org/r/20240213145239.379875-2-balint.dobszay%40arm.com
patch subject: [PATCH 1/3] tee: optee: Move pool_op helper functions
config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20240214/202402142042.JLQEGKBr-lkp at intel.com/config)
compiler: s390-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240214/202402142042.JLQEGKBr-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402142042.JLQEGKBr-lkp at intel.com/

All errors (new ones prefixed by >>):

   drivers/tee/tee_shm.c: In function 'tee_shm_pool_op_alloc_helper':
>> drivers/tee/tee_shm.c:227:22: error: implicit declaration of function 'virt_to_phys'; did you mean 'virt_to_pfn'? [-Werror=implicit-function-declaration]
     227 |         shm->paddr = virt_to_phys(shm->kaddr);
         |                      ^~~~~~~~~~~~
         |                      virt_to_pfn
   cc1: some warnings being treated as errors


vim +227 drivers/tee/tee_shm.c

   204	
   205	int tee_shm_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
   206					 size_t size, size_t align,
   207					 int (*shm_register)(struct tee_context *ctx,
   208							     struct tee_shm *shm,
   209							     struct page **pages,
   210							     size_t num_pages,
   211							     unsigned long start))
   212	{
   213		size_t nr_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE;
   214		struct page **pages;
   215		unsigned int i;
   216		int rc = 0;
   217	
   218		/*
   219		 * Ignore alignment since this is already going to be page aligned
   220		 * and there's no need for any larger alignment.
   221		 */
   222		shm->kaddr = alloc_pages_exact(nr_pages * PAGE_SIZE,
   223					       GFP_KERNEL | __GFP_ZERO);
   224		if (!shm->kaddr)
   225			return -ENOMEM;
   226	
 > 227		shm->paddr = virt_to_phys(shm->kaddr);
   228		shm->size = nr_pages * PAGE_SIZE;
   229	
   230		pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL);
   231		if (!pages) {
   232			rc = -ENOMEM;
   233			goto err;
   234		}
   235	
   236		for (i = 0; i < nr_pages; i++)
   237			pages[i] = virt_to_page((u8 *)shm->kaddr + i * PAGE_SIZE);
   238	
   239		shm->pages = pages;
   240		shm->num_pages = nr_pages;
   241	
   242		if (shm_register) {
   243			rc = shm_register(shm->ctx, shm, pages, nr_pages,
   244					  (unsigned long)shm->kaddr);
   245			if (rc)
   246				goto err;
   247		}
   248	
   249		return 0;
   250	err:
   251		free_pages_exact(shm->kaddr, shm->size);
   252		shm->kaddr = NULL;
   253		return rc;
   254	}
   255	EXPORT_SYMBOL_GPL(tee_shm_pool_op_alloc_helper);
   256	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From alexandre.torgue at foss.st.com  Wed Feb 14 05:04:41 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Wed, 14 Feb 2024 14:04:41 +0100
Subject: [PATCH] ARM: dts: stm32: lxa-tac: reduce RGMII interface drive
 strength
In-Reply-To: <20240129114649.2458468-2-u.kleine-koenig@pengutronix.de>
References: <20240129114649.2458468-2-u.kleine-koenig@pengutronix.de>
Message-ID: <a82bf354-f900-4f12-a9b7-0927403ecac3@foss.st.com>

Hi

On 1/29/24 12:46, Uwe Kleine-K?nig wrote:
> From: Leonard G?hrs <l.goehrs at pengutronix.de>
> 
> This results in an improvement of EMI performance by reducing the
> 125MHz emission and its harmonics caused by the RGMII clock line.
> 
> Signed-off-by: Leonard G?hrs <l.goehrs at pengutronix.de>
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> ---
>   arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
> index 7e835a7cf64a..cfaf8adde319 100644
> --- a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
> +++ b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
> @@ -471,6 +471,10 @@ switch: switch at 0 {
>   		interrupt-parent = <&gpioa>;
>   		interrupts = <6 IRQ_TYPE_EDGE_RISING>;
>   
> +		/* Reduce RGMII EMI emissions by reducing drive strength */
> +		microchip,hi-drive-strength-microamp = <2000>;
> +		microchip,lo-drive-strength-microamp = <8000>;
> +
>   		ports {
>   			#address-cells = <1>;
>   			#size-cells = <0>;

Applied on stm32-next.

Thanks
Alex


From lkp at intel.com  Wed Feb 14 05:11:57 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 14 Feb 2024 21:11:57 +0800
Subject: [PATCH 1/3] tee: optee: Move pool_op helper functions
In-Reply-To: <20240213145239.379875-2-balint.dobszay@arm.com>
References: <20240213145239.379875-2-balint.dobszay@arm.com>
Message-ID: <202402142000.xRg35j1i-lkp@intel.com>

Hi Balint,

kernel test robot noticed the following build errors:

[auto build test ERROR on lwn/docs-next]
[also build test ERROR on soc/for-next linus/master v6.8-rc4 next-20240214]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Balint-Dobszay/tee-optee-Move-pool_op-helper-functions/20240213-225716
base:   git://git.lwn.net/linux.git docs-next
patch link:    https://lore.kernel.org/r/20240213145239.379875-2-balint.dobszay%40arm.com
patch subject: [PATCH 1/3] tee: optee: Move pool_op helper functions
config: i386-buildonly-randconfig-002-20240214 (https://download.01.org/0day-ci/archive/20240214/202402142000.xRg35j1i-lkp at intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240214/202402142000.xRg35j1i-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402142000.xRg35j1i-lkp at intel.com/

All errors (new ones prefixed by >>):

>> drivers/tee/tee_shm.c:227:15: error: call to undeclared function 'virt_to_phys'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     227 |         shm->paddr = virt_to_phys(shm->kaddr);
         |                      ^
   1 error generated.


vim +/virt_to_phys +227 drivers/tee/tee_shm.c

   204	
   205	int tee_shm_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
   206					 size_t size, size_t align,
   207					 int (*shm_register)(struct tee_context *ctx,
   208							     struct tee_shm *shm,
   209							     struct page **pages,
   210							     size_t num_pages,
   211							     unsigned long start))
   212	{
   213		size_t nr_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE;
   214		struct page **pages;
   215		unsigned int i;
   216		int rc = 0;
   217	
   218		/*
   219		 * Ignore alignment since this is already going to be page aligned
   220		 * and there's no need for any larger alignment.
   221		 */
   222		shm->kaddr = alloc_pages_exact(nr_pages * PAGE_SIZE,
   223					       GFP_KERNEL | __GFP_ZERO);
   224		if (!shm->kaddr)
   225			return -ENOMEM;
   226	
 > 227		shm->paddr = virt_to_phys(shm->kaddr);
   228		shm->size = nr_pages * PAGE_SIZE;
   229	
   230		pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL);
   231		if (!pages) {
   232			rc = -ENOMEM;
   233			goto err;
   234		}
   235	
   236		for (i = 0; i < nr_pages; i++)
   237			pages[i] = virt_to_page((u8 *)shm->kaddr + i * PAGE_SIZE);
   238	
   239		shm->pages = pages;
   240		shm->num_pages = nr_pages;
   241	
   242		if (shm_register) {
   243			rc = shm_register(shm->ctx, shm, pages, nr_pages,
   244					  (unsigned long)shm->kaddr);
   245			if (rc)
   246				goto err;
   247		}
   248	
   249		return 0;
   250	err:
   251		free_pages_exact(shm->kaddr, shm->size);
   252		shm->kaddr = NULL;
   253		return rc;
   254	}
   255	EXPORT_SYMBOL_GPL(tee_shm_pool_op_alloc_helper);
   256	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From geert+renesas at glider.be  Wed Feb 14 05:18:03 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 14:18:03 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: gray-hawk-single: Add eMMC support
In-Reply-To: <cover.1707915763.git.geert+renesas@glider.be>
References: <cover.1707915763.git.geert+renesas@glider.be>
Message-ID: <208bfc781b1488e253e19626ad80876c34c86758.1707915763.git.geert+renesas@glider.be>

From: Cong Dang <cong.dang.xn at renesas.com>

Describe the eMMC on the Gray Hawk Single board.

Signed-off-by: Cong Dang <cong.dang.xn at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Apply to r8a779h0-gray-hawk-single.dts.
---
 .../dts/renesas/r8a779h0-gray-hawk-single.dts | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
index fcb58b92daae31e1..c951dbb8b047e0c0 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
+++ b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
@@ -33,6 +33,24 @@ memory at 480000000 {
 		device_type = "memory";
 		reg = <0x4 0x80000000 0x1 0x80000000>;
 	};
+
+	reg_1p8v: regulator-1p8v {
+			compatible = "regulator-fixed";
+			regulator-name = "fixed-1.8V";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-boot-on;
+			regulator-always-on;
+	};
+
+	reg_3p3v: regulator-3p3v {
+			compatible = "regulator-fixed";
+			regulator-name = "fixed-3.3V";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-boot-on;
+			regulator-always-on;
+	};
 };
 
 &avb0 {
@@ -105,6 +123,23 @@ eeprom at 53 {
 	};
 };
 
+&mmc0 {
+	pinctrl-0 = <&mmc_pins>;
+	pinctrl-1 = <&mmc_pins>;
+	pinctrl-names = "default", "state_uhs";
+
+	vmmc-supply = <&reg_3p3v>;
+	vqmmc-supply = <&reg_1p8v>;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	bus-width = <8>;
+	no-sd;
+	no-sdio;
+	non-removable;
+	full-pwr-cycle-in-suspend;
+	status = "okay";
+};
+
 &pfc {
 	pinctrl-0 = <&scif_clk_pins>;
 	pinctrl-names = "default";
@@ -137,6 +172,12 @@ i2c0_pins: i2c0 {
 		function = "i2c0";
 	};
 
+	mmc_pins: mmc {
+		groups = "mmc_data8", "mmc_ctrl", "mmc_ds";
+		function = "mmc";
+		power-source = <1800>;
+	};
+
 	scif_clk_pins: scif-clk {
 		groups = "scif_clk";
 		function = "scif_clk";
-- 
2.34.1



From geert+renesas at glider.be  Wed Feb 14 05:18:02 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 14:18:02 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: r8a779h0: Add SD/MMC node
In-Reply-To: <cover.1707915763.git.geert+renesas@glider.be>
References: <cover.1707915763.git.geert+renesas@glider.be>
Message-ID: <4433cd73049ae517ea163bc703555ee8d9a4dd82.1707915763.git.geert+renesas@glider.be>

From: Cong Dang <cong.dang.xn at renesas.com>

Add a device node for SD/MMC on Renesas R-Car V4M (R8A779H0) SoC.

Signed-off-by: Cong Dang <cong.dang.xn at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Add missing SD0H clock,
  - Add missing clock-names property.
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index 66a93c88f8742431..d50ed1989ef52da7 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -532,6 +532,20 @@ avb2: ethernet at e6820000 {
 			status = "disabled";
 		};
 
+		mmc0: mmc at ee140000 {
+			compatible = "renesas,sdhi-r8a779h0",
+				     "renesas,rcar-gen4-sdhi";
+			reg = <0 0xee140000 0 0x2000>;
+			interrupts = <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 706>,
+				 <&cpg CPG_CORE R8A779H0_CLK_SD0H>;
+			clock-names = "core", "clkh";
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 706>;
+			max-frequency = <200000000>;
+			status = "disabled";
+		};
+
 		gic: interrupt-controller at f1000000 {
 			compatible = "arm,gic-v3";
 			#interrupt-cells = <3>;
-- 
2.34.1



From geert+renesas at glider.be  Wed Feb 14 05:18:01 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 14:18:01 +0100
Subject: [PATCH 0/2] arm64: dts: renesas: r8a779h0/gray-hawk-single: Add eMMC support
Message-ID: <cover.1707915763.git.geert+renesas@glider.be>

        Hi all,

This patch series adds SD/MMC support for the Renesas R-Car V4M
(R8A779H0) Soc and eMMC support for the Gray Hawk Single development
board.

This has been tested on Gray Hawk Single (eMMC read speed is ca. 240
MiB/s).

I intend to queue this in renesas-devel for v6.9.
As usual, I have updated my topic branch at [1].

Thanks for your comments!

[1] https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/log/?h=topic/v4m-gray-hawk-single-v2

Cong Dang (2):
  arm64: dts: renesas: r8a779h0: Add SD/MMC node
  arm64: dts: renesas: gray-hawk-single: Add eMMC support

 .../dts/renesas/r8a779h0-gray-hawk-single.dts | 41 +++++++++++++++++++
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi     | 14 +++++++
 2 files changed, 55 insertions(+)

-- 
2.34.1

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 maz at kernel.org  Wed Feb 14 05:18:02 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:02 +0000
Subject: [PATCH v4 01/26] arm64: sysreg: Add missing ID_AA64ISAR[13]_EL1 fields and variants
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-2-maz@kernel.org>

Despite having the control bits for FEAT_SPECRES and FEAT_PACM,
the ID registers fields are either incomplete or missing.

Fix it.

Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/tools/sysreg | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index fa3fe0856880..53daaaef46cb 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1366,6 +1366,7 @@ EndEnum
 UnsignedEnum	43:40	SPECRES
 	0b0000	NI
 	0b0001	IMP
+	0b0010	COSP_RCTX
 EndEnum
 UnsignedEnum	39:36	SB
 	0b0000	NI
@@ -1492,7 +1493,12 @@ EndEnum
 EndSysreg
 
 Sysreg	ID_AA64ISAR3_EL1	3	0	0	6	3
-Res0	63:12
+Res0	63:16
+UnsignedEnum	15:12	PACM
+	0b0000	NI
+	0b0001	TRIVIAL_IMP
+	0b0010	FULL_IMP
+EndEnum
 UnsignedEnum	11:8	TLBIW
 	0b0000	NI
 	0b0001	IMP
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:03 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:03 +0000
Subject: [PATCH v4 02/26] KVM: arm64: Add feature checking helpers
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-3-maz@kernel.org>

In order to make it easier to check whether a particular feature
is exposed to a guest, add a new set of helpers, with kvm_has_feat()
being the most useful.

Let's start making use of them in the PMU code (courtesy of Oliver).
Follow-up changes will introduce additional use patterns.

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Co-developed--by: Oliver Upton <oliver.upton at linux.dev>
Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 44 +++++++++++++++++++++++++++++++
 arch/arm64/kvm/pmu-emul.c         | 11 ++++----
 arch/arm64/kvm/sys_regs.c         |  6 ++---
 include/kvm/arm_pmu.h             | 11 --------
 4 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 21c57b812569..527da3d2cedb 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1233,4 +1233,48 @@ static inline void kvm_hyp_reserve(void) { }
 void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
 bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
 
+#define __expand_field_sign_unsigned(id, fld, val)			\
+	((u64)SYS_FIELD_VALUE(id, fld, val))
+
+#define __expand_field_sign_signed(id, fld, val)			\
+	({								\
+		u64 __val = SYS_FIELD_VALUE(id, fld, val);		\
+		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
+	})
+
+#define expand_field_sign(id, fld, val)					\
+	(id##_##fld##_SIGNED ?						\
+	 __expand_field_sign_signed(id, fld, val) :			\
+	 __expand_field_sign_unsigned(id, fld, val))
+
+#define get_idreg_field_unsigned(kvm, id, fld)				\
+	({								\
+		u64 __val = IDREG((kvm), SYS_##id);			\
+		FIELD_GET(id##_##fld##_MASK, __val);			\
+	})
+
+#define get_idreg_field_signed(kvm, id, fld)				\
+	({								\
+		u64 __val = get_idreg_field_unsigned(kvm, id, fld);	\
+		sign_extend64(__val, id##_##fld##_WIDTH - 1);		\
+	})
+
+#define get_idreg_field_enum(kvm, id, fld)				\
+	get_idreg_field_unsigned(kvm, id, fld)
+
+#define get_idreg_field(kvm, id, fld)					\
+	(id##_##fld##_SIGNED ?						\
+	 get_idreg_field_signed(kvm, id, fld) :				\
+	 get_idreg_field_unsigned(kvm, id, fld))
+
+#define kvm_has_feat(kvm, id, fld, limit)				\
+	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit))
+
+#define kvm_has_feat_enum(kvm, id, fld, val)				\
+	(get_idreg_field_unsigned((kvm), id, fld) == __expand_field_sign_unsigned(id, fld, val))
+
+#define kvm_has_feat_range(kvm, id, fld, min, max)			\
+	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
+	 get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 3d9467ff73bc..925522470b2b 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -64,12 +64,11 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm)
 {
 	u64 mask = ARMV8_PMU_EXCLUDE_EL1 | ARMV8_PMU_EXCLUDE_EL0 |
 		   kvm_pmu_event_mask(kvm);
-	u64 pfr0 = IDREG(kvm, SYS_ID_AA64PFR0_EL1);
 
-	if (SYS_FIELD_GET(ID_AA64PFR0_EL1, EL2, pfr0))
+	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL2, IMP))
 		mask |= ARMV8_PMU_INCLUDE_EL2;
 
-	if (SYS_FIELD_GET(ID_AA64PFR0_EL1, EL3, pfr0))
+	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL3, IMP))
 		mask |= ARMV8_PMU_EXCLUDE_NS_EL0 |
 			ARMV8_PMU_EXCLUDE_NS_EL1 |
 			ARMV8_PMU_EXCLUDE_EL3;
@@ -83,8 +82,10 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm)
  */
 static bool kvm_pmc_is_64bit(struct kvm_pmc *pmc)
 {
+	struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc);
+
 	return (pmc->idx == ARMV8_PMU_CYCLE_IDX ||
-		kvm_pmu_is_3p5(kvm_pmc_to_vcpu(pmc)));
+		kvm_has_feat(vcpu->kvm, ID_AA64DFR0_EL1, PMUVer, V3P5));
 }
 
 static bool kvm_pmc_has_64bit_overflow(struct kvm_pmc *pmc)
@@ -556,7 +557,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val)
 		return;
 
 	/* Fixup PMCR_EL0 to reconcile the PMU version and the LP bit */
-	if (!kvm_pmu_is_3p5(vcpu))
+	if (!kvm_has_feat(vcpu->kvm, ID_AA64DFR0_EL1, PMUVer, V3P5))
 		val &= ~ARMV8_PMU_PMCR_LP;
 
 	/* The reset bits don't indicate any state, and shouldn't be saved. */
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 041b11825578..3c31f8cb9eef 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -505,10 +505,9 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
 			  struct sys_reg_params *p,
 			  const struct sys_reg_desc *r)
 {
-	u64 val = IDREG(vcpu->kvm, SYS_ID_AA64MMFR1_EL1);
 	u32 sr = reg_to_encoding(r);
 
-	if (!(val & (0xfUL << ID_AA64MMFR1_EL1_LO_SHIFT))) {
+	if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR1_EL1, LO, IMP)) {
 		kvm_inject_undefined(vcpu);
 		return false;
 	}
@@ -2748,8 +2747,7 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
 		return ignore_write(vcpu, p);
 	} else {
 		u64 dfr = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1);
-		u64 pfr = IDREG(vcpu->kvm, SYS_ID_AA64PFR0_EL1);
-		u32 el3 = !!SYS_FIELD_GET(ID_AA64PFR0_EL1, EL3, pfr);
+		u32 el3 = kvm_has_feat(vcpu->kvm, ID_AA64PFR0_EL1, EL3, IMP);
 
 		p->regval = ((SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr) << 28) |
 			     (SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, dfr) << 24) |
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 4b9d8fb393a8..eb4c369a79eb 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -90,16 +90,6 @@ void kvm_vcpu_pmu_resync_el0(void);
 			vcpu->arch.pmu.events = *kvm_get_pmu_events();	\
 	} while (0)
 
-/*
- * Evaluates as true when emulating PMUv3p5, and false otherwise.
- */
-#define kvm_pmu_is_3p5(vcpu) ({						\
-	u64 val = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1);		\
-	u8 pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer, val);	\
-									\
-	pmuver >= ID_AA64DFR0_EL1_PMUVer_V3P5;				\
-})
-
 u8 kvm_arm_pmu_get_pmuver_limit(void);
 u64 kvm_pmu_evtyper_mask(struct kvm *kvm);
 int kvm_arm_set_default_pmu(struct kvm *kvm);
@@ -168,7 +158,6 @@ static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
 }
 
 #define kvm_vcpu_has_pmu(vcpu)		({ false; })
-#define kvm_pmu_is_3p5(vcpu)		({ false; })
 static inline void kvm_pmu_update_vcpu_events(struct kvm_vcpu *vcpu) {}
 static inline void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) {}
 static inline void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) {}
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:05 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:05 +0000
Subject: [PATCH v4 04/26] KVM: arm64: nv: Add sanitising to EL2 configuration registers
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-5-maz@kernel.org>

We can now start making use of our sanitising masks by setting them
to values that depend on the guest's configuration.

First up are VTTBR_EL2, VTCR_EL2, VMPIDR_EL2 and HCR_EL2.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/nested.c | 58 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index c976cd4b8379..29ed529681e2 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -181,7 +181,7 @@ u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg sr)
 	return v;
 }
 
-static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
+static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
 {
 	int i = sr - __VNCR_START__;
 
@@ -191,6 +191,7 @@ static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u
 
 int kvm_init_nv_sysregs(struct kvm *kvm)
 {
+	u64 res0, res1;
 	int ret = 0;
 
 	mutex_lock(&kvm->arch.config_lock);
@@ -209,6 +210,61 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		kvm->arch.id_regs[i] = limit_nv_id_reg(IDX_IDREG(i),
 						       kvm->arch.id_regs[i]);
 
+	/* VTTBR_EL2 */
+	res0 = res1 = 0;
+	if (!kvm_has_feat_enum(kvm, ID_AA64MMFR1_EL1, VMIDBits, 16))
+		res0 |= GENMASK(63, 56);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, CnP, IMP))
+		res0 |= VTTBR_CNP_BIT;
+	set_sysreg_masks(kvm, VTTBR_EL2, res0, res1);
+
+	/* VTCR_EL2 */
+	res0 = GENMASK(63, 32) | GENMASK(30, 20);
+	res1 = BIT(31);
+	set_sysreg_masks(kvm, VTCR_EL2, res0, res1);
+
+	/* VMPIDR_EL2 */
+	res0 = GENMASK(63, 40) | GENMASK(30, 24);
+	res1 = BIT(31);
+	set_sysreg_masks(kvm, VMPIDR_EL2, res0, res1);
+
+	/* HCR_EL2 */
+	res0 = BIT(48);
+	res1 = HCR_RW;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, TWED, IMP))
+		res0 |= GENMASK(63, 59);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, MTE, MTE2))
+		res0 |= (HCR_TID5 | HCR_DCT | HCR_ATA);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, EVT, TTLBxS))
+		res0 |= (HCR_TTLBIS | HCR_TTLBOS);
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, CSV2, CSV2_2) &&
+	    !kvm_has_feat(kvm, ID_AA64PFR1_EL1, CSV2_frac, CSV2_1p2))
+		res0 |= HCR_ENSCXT;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, EVT, IMP))
+		res0 |= (HCR_TOCU | HCR_TICAB | HCR_TID4);
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1))
+		res0 |= HCR_AMVOFFEN;
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1))
+		res0 |= HCR_FIEN;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, FWB, IMP))
+		res0 |= HCR_FWB;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, NV2))
+		res0 |= HCR_NV2;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, IMP))
+		res0 |= (HCR_AT | HCR_NV1 | HCR_NV);
+	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
+	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_GENERIC)))
+		res0 |= (HCR_API | HCR_APK);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TME, IMP))
+		res0 |= BIT(39);
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP))
+		res0 |= (HCR_TEA | HCR_TERR);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
+		res0 |= HCR_TLOR;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR4_EL1, E2H0, IMP))
+		res1 |= HCR_E2H;
+	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
+
 out:
 	mutex_unlock(&kvm->arch.config_lock);
 
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:01 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:01 +0000
Subject: [PATCH v4 00/26] KVM/arm64: VM configuration enforcement
Message-ID: <20240214131827.2856277-1-maz@kernel.org>

This is the fourth version of this configurationm enforcement series
after additional reviewing from Suzuki and Oliver. Many thanks to
both.

I think I have taken most of the feedback into account, but please
shout if I have ignored something.

* From v3: [3]

  - Fixed copy-paste issue while testing for the PAC flags

  - Added Suzuki's RB on patch #2

* From v2: [2]

  - Fix totally broken handling of negative features by delegating the
    work that requires a functionnal brain to other people

  - Fix handling of HCR_ENSCXT as RES0 instead of RES1 (and its
    consequences...)

  - Add handling of VTTBR_EL2.CNP being RES0

  - Add a snapshot of all RES0/RES1 fields so that we can catch them
    being changed behind our backs

  - Various cleanups

* From v1: [1]

  - Fix embarrassing crash with FEAT_MOPS

  - Better error handling in the FGT code

  - Added/Fixed comments

  - Simplified the __vcpu_sys_reg() macro

  - Fixed FEAT_PIR handling

  - Folded in Oliver's PMU rework

[1] https://lore.kernel.org/all/20240122201852.262057-1-maz at kernel.org
[2] https://lore.kernel.org/all/20240130204533.693853-1-maz at kernel.org
[3] https://lore.kernel.org/all/20240205103431.1104133-1-maz at kernel.org

Marc Zyngier (26):
  arm64: sysreg: Add missing ID_AA64ISAR[13]_EL1 fields and variants
  KVM: arm64: Add feature checking helpers
  KVM: arm64: nv: Add sanitising to VNCR-backed sysregs
  KVM: arm64: nv: Add sanitising to EL2 configuration registers
  KVM: arm64: nv: Add sanitising to VNCR-backed FGT sysregs
  KVM: arm64: nv: Add sanitising to VNCR-backed HCRX_EL2
  KVM: arm64: nv: Drop sanitised_sys_reg() helper
  KVM: arm64: Unify HDFG[WR]TR_GROUP FGT identifiers
  KVM: arm64: nv: Correctly handle negative polarity FGTs
  KVM: arm64: nv: Turn encoding ranges into discrete XArray stores
  KVM: arm64: Drop the requirement for XARRAY_MULTI
  KVM: arm64: nv: Move system instructions to their own sys_reg_desc
    array
  KVM: arm64: Always populate the trap configuration xarray
  KVM: arm64: Register AArch64 system register entries with the sysreg
    xarray
  KVM: arm64: Use the xarray as the primary sysreg/sysinsn walker
  KVM: arm64: Rename __check_nv_sr_forward() to triage_sysreg_trap()
  KVM: arm64: Add Fine-Grained UNDEF tracking information
  KVM: arm64: Propagate and handle Fine-Grained UNDEF bits
  KVM: arm64: Move existing feature disabling over to FGU infrastructure
  KVM: arm64: Streamline save/restore of HFG[RW]TR_EL2
  KVM: arm64: Make TLBI OS/Range UNDEF if not advertised to the guest
  KVM: arm64: Make PIR{,E0}_EL1 UNDEF if S1PIE is not advertised to the
    guest
  KVM: arm64: Make AMU sysreg UNDEF if FEAT_AMU is not advertised to the
    guest
  KVM: arm64: Make FEAT_MOPS UNDEF if not advertised to the guest
  KVM: arm64: Snapshot all non-zero RES0/RES1 sysreg fields for later
    checking
  KVM: arm64: Add debugfs file for guest's ID registers

 arch/arm64/include/asm/kvm_arm.h           |   4 +-
 arch/arm64/include/asm/kvm_host.h          |  98 +++++++-
 arch/arm64/include/asm/kvm_nested.h        |   1 -
 arch/arm64/kvm/Kconfig                     |   1 -
 arch/arm64/kvm/arm.c                       |   7 +
 arch/arm64/kvm/check-res-bits.h            | 121 ++++++++++
 arch/arm64/kvm/emulate-nested.c            | 231 +++++++++++++-----
 arch/arm64/kvm/hyp/include/hyp/switch.h    | 130 +++++-----
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h |  24 +-
 arch/arm64/kvm/nested.c                    | 267 ++++++++++++++++++++-
 arch/arm64/kvm/pmu-emul.c                  |  11 +-
 arch/arm64/kvm/sys_regs.c                  | 238 +++++++++++++++---
 arch/arm64/kvm/sys_regs.h                  |   2 +
 arch/arm64/tools/sysreg                    |   8 +-
 include/kvm/arm_pmu.h                      |  11 -
 15 files changed, 973 insertions(+), 181 deletions(-)
 create mode 100644 arch/arm64/kvm/check-res-bits.h

-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:04 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:04 +0000
Subject: [PATCH v4 03/26] KVM: arm64: nv: Add sanitising to VNCR-backed sysregs
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-4-maz@kernel.org>

VNCR-backed "registers" are actually only memory. Which means that
there is zero control over what the guest can write, and that it
is the hypervisor's job to actually sanitise the content of the
backing store. Yeah, this is fun.

In order to preserve some form of sanity, add a repainting mechanism
that makes use of a per-VM set of RES0/RES1 masks, one pair per VNCR
register. These masks get applied on access to the backing store via
__vcpu_sys_reg(), ensuring that the state that is consumed by KVM is
correct.

So far, nothing populates these masks, but stay tuned.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 22 ++++++++++++++++-
 arch/arm64/kvm/arm.c              |  1 +
 arch/arm64/kvm/nested.c           | 41 ++++++++++++++++++++++++++++++-
 3 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 527da3d2cedb..8cda003d6267 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -238,6 +238,8 @@ static inline u16 kvm_mpidr_index(struct kvm_mpidr_data *data, u64 mpidr)
 	return index;
 }
 
+struct kvm_sysreg_masks;
+
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
 
@@ -312,6 +314,9 @@ struct kvm_arch {
 #define KVM_ARM_ID_REG_NUM	(IDREG_IDX(sys_reg(3, 0, 0, 7, 7)) + 1)
 	u64 id_regs[KVM_ARM_ID_REG_NUM];
 
+	/* Masks for VNCR-baked sysregs */
+	struct kvm_sysreg_masks	*sysreg_masks;
+
 	/*
 	 * For an untrusted host VM, 'pkvm.handle' is used to lookup
 	 * the associated pKVM instance in the hypervisor.
@@ -474,6 +479,13 @@ enum vcpu_sysreg {
 	NR_SYS_REGS	/* Nothing after this line! */
 };
 
+struct kvm_sysreg_masks {
+	struct {
+		u64	res0;
+		u64	res1;
+	} mask[NR_SYS_REGS - __VNCR_START__];
+};
+
 struct kvm_cpu_context {
 	struct user_pt_regs regs;	/* sp = sp_el0 */
 
@@ -868,7 +880,15 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
 
 #define ctxt_sys_reg(c,r)	(*__ctxt_sys_reg(c,r))
 
-#define __vcpu_sys_reg(v,r)	(ctxt_sys_reg(&(v)->arch.ctxt, (r)))
+u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg);
+#define __vcpu_sys_reg(v,r)						\
+	(*({								\
+		const struct kvm_cpu_context *ctxt = &(v)->arch.ctxt;	\
+		u64 *__r = __ctxt_sys_reg(ctxt, (r));			\
+		if (vcpu_has_nv((v)) && (r) >= __VNCR_START__)		\
+			*__r = kvm_vcpu_sanitise_vncr_reg((v), (r));	\
+		__r;							\
+	}))
 
 u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg);
 void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a25265aca432..c063e84fc72c 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -206,6 +206,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 		pkvm_destroy_hyp_vm(kvm);
 
 	kfree(kvm->arch.mpidr_data);
+	kfree(kvm->arch.sysreg_masks);
 	kvm_destroy_vcpus(kvm);
 
 	kvm_unshare_hyp(kvm, kvm + 1);
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index d55e809e26cb..c976cd4b8379 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -163,15 +163,54 @@ static u64 limit_nv_id_reg(u32 id, u64 val)
 
 	return val;
 }
+
+u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg sr)
+{
+	u64 v = ctxt_sys_reg(&vcpu->arch.ctxt, sr);
+	struct kvm_sysreg_masks *masks;
+
+	masks = vcpu->kvm->arch.sysreg_masks;
+
+	if (masks) {
+		sr -= __VNCR_START__;
+
+		v &= ~masks->mask[sr].res0;
+		v |= masks->mask[sr].res1;
+	}
+
+	return v;
+}
+
+static void __maybe_unused set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
+{
+	int i = sr - __VNCR_START__;
+
+	kvm->arch.sysreg_masks->mask[i].res0 = res0;
+	kvm->arch.sysreg_masks->mask[i].res1 = res1;
+}
+
 int kvm_init_nv_sysregs(struct kvm *kvm)
 {
+	int ret = 0;
+
 	mutex_lock(&kvm->arch.config_lock);
 
+	if (kvm->arch.sysreg_masks)
+		goto out;
+
+	kvm->arch.sysreg_masks = kzalloc(sizeof(*(kvm->arch.sysreg_masks)),
+					 GFP_KERNEL);
+	if (!kvm->arch.sysreg_masks) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
 	for (int i = 0; i < KVM_ARM_ID_REG_NUM; i++)
 		kvm->arch.id_regs[i] = limit_nv_id_reg(IDX_IDREG(i),
 						       kvm->arch.id_regs[i]);
 
+out:
 	mutex_unlock(&kvm->arch.config_lock);
 
-	return 0;
+	return ret;
 }
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:08 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:08 +0000
Subject: [PATCH v4 07/26] KVM: arm64: nv: Drop sanitised_sys_reg() helper
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-8-maz@kernel.org>

Now that we have the infrastructure to enforce a sanitised register
value depending on the VM configuration, drop the helper that only
used the architectural RES0 value.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 22 +++++++---------------
 1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 431fd429932d..7a4a886adb9d 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1897,14 +1897,6 @@ static bool check_fgt_bit(u64 val, const union trap_config tc)
 	return ((val >> tc.bit) & 1) == tc.pol;
 }
 
-#define sanitised_sys_reg(vcpu, reg)			\
-	({						\
-		u64 __val;				\
-		__val = __vcpu_sys_reg(vcpu, reg);	\
-		__val &= ~__ ## reg ## _RES0;		\
-		(__val);				\
-	})
-
 bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 {
 	union trap_config tc;
@@ -1940,25 +1932,25 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 
 	case HFGxTR_GROUP:
 		if (is_read)
-			val = sanitised_sys_reg(vcpu, HFGRTR_EL2);
+			val = __vcpu_sys_reg(vcpu, HFGRTR_EL2);
 		else
-			val = sanitised_sys_reg(vcpu, HFGWTR_EL2);
+			val = __vcpu_sys_reg(vcpu, HFGWTR_EL2);
 		break;
 
 	case HDFGRTR_GROUP:
 	case HDFGWTR_GROUP:
 		if (is_read)
-			val = sanitised_sys_reg(vcpu, HDFGRTR_EL2);
+			val = __vcpu_sys_reg(vcpu, HDFGRTR_EL2);
 		else
-			val = sanitised_sys_reg(vcpu, HDFGWTR_EL2);
+			val = __vcpu_sys_reg(vcpu, HDFGWTR_EL2);
 		break;
 
 	case HAFGRTR_GROUP:
-		val = sanitised_sys_reg(vcpu, HAFGRTR_EL2);
+		val = __vcpu_sys_reg(vcpu, HAFGRTR_EL2);
 		break;
 
 	case HFGITR_GROUP:
-		val = sanitised_sys_reg(vcpu, HFGITR_EL2);
+		val = __vcpu_sys_reg(vcpu, HFGITR_EL2);
 		switch (tc.fgf) {
 			u64 tmp;
 
@@ -1966,7 +1958,7 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 			break;
 
 		case HCRX_FGTnXS:
-			tmp = sanitised_sys_reg(vcpu, HCRX_EL2);
+			tmp = __vcpu_sys_reg(vcpu, HCRX_EL2);
 			if (tmp & HCRX_EL2_FGTnXS)
 				tc.fgt = __NO_FGT_GROUP__;
 		}
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:07 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:07 +0000
Subject: [PATCH v4 06/26] KVM: arm64: nv: Add sanitising to VNCR-backed HCRX_EL2
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-7-maz@kernel.org>

Just like its little friends, HCRX_EL2 gets the feature set treatment
when backed by VNCR.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/nested.c | 42 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index eda05eb16c0a..ced30c90521a 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -265,6 +265,48 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		res1 |= HCR_E2H;
 	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
 
+	/* HCRX_EL2 */
+	res0 = HCRX_EL2_RES0;
+	res1 = HCRX_EL2_RES1;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR3_EL1, PACM, TRIVIAL_IMP))
+		res0 |= HCRX_EL2_PACMEn;
+	if (!kvm_has_feat(kvm, ID_AA64PFR2_EL1, FPMR, IMP))
+		res0 |= HCRX_EL2_EnFPM;
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
+		res0 |= HCRX_EL2_GCSEn;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, SYSREG_128, IMP))
+		res0 |= HCRX_EL2_EnIDCP128;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, ADERR, DEV_ASYNC))
+		res0 |= (HCRX_EL2_EnSDERR | HCRX_EL2_EnSNERR);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, DF2, IMP))
+		res0 |= HCRX_EL2_TMEA;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, D128, IMP))
+		res0 |= HCRX_EL2_D128En;
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
+		res0 |= HCRX_EL2_PTTWI;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, SCTLRX, IMP))
+		res0 |= HCRX_EL2_SCTLR2En;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, TCRX, IMP))
+		res0 |= HCRX_EL2_TCR2En;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, MOPS, IMP))
+		res0 |= (HCRX_EL2_MSCEn | HCRX_EL2_MCE2);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, CMOW, IMP))
+		res0 |= HCRX_EL2_CMOW;
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, NMI, IMP))
+		res0 |= (HCRX_EL2_VFNMI | HCRX_EL2_VINMI | HCRX_EL2_TALLINT);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP) ||
+	    !(read_sysreg_s(SYS_SMIDR_EL1) & SMIDR_EL1_SMPS))
+		res0 |= HCRX_EL2_SMPME;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, XS, IMP))
+		res0 |= (HCRX_EL2_FGTnXS | HCRX_EL2_FnXS);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_V))
+		res0 |= HCRX_EL2_EnASR;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64))
+		res0 |= HCRX_EL2_EnALS;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA))
+		res0 |= HCRX_EL2_EnAS0;
+	set_sysreg_masks(kvm, HCRX_EL2, res0, res1);
+
 	/* HFG[RW]TR_EL2 */
 	res0 = res1 = 0;
 	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:09 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:09 +0000
Subject: [PATCH v4 08/26] KVM: arm64: Unify HDFG[WR]TR_GROUP FGT identifiers
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-9-maz@kernel.org>

There is no reason to have separate FGT group identifiers for
the debug fine grain trapping. The sole requirement is to provide
the *names* so that the SR_FGF() macro can do its magic of picking
the correct bit definition.

So let's alias HDFGWTR_GROUP and HDFGRTR_GROUP.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 7a4a886adb9d..8a1cfcf553a2 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1010,7 +1010,7 @@ enum fgt_group_id {
 	__NO_FGT_GROUP__,
 	HFGxTR_GROUP,
 	HDFGRTR_GROUP,
-	HDFGWTR_GROUP,
+	HDFGWTR_GROUP = HDFGRTR_GROUP,
 	HFGITR_GROUP,
 	HAFGRTR_GROUP,
 
@@ -1938,7 +1938,6 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 		break;
 
 	case HDFGRTR_GROUP:
-	case HDFGWTR_GROUP:
 		if (is_read)
 			val = __vcpu_sys_reg(vcpu, HDFGRTR_EL2);
 		else
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:12 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:12 +0000
Subject: [PATCH v4 11/26] KVM: arm64: Drop the requirement for XARRAY_MULTI
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-12-maz@kernel.org>

Now that we don't use xa_store_range() anymore, drop the added
complexity of XARRAY_MULTI for KVM. It is likely still pulled
in by other bits of the kernel though.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6c3c8ca73e7f..5c2a672c06a8 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -39,7 +39,6 @@ menuconfig KVM
 	select HAVE_KVM_VCPU_RUN_PID_CHANGE
 	select SCHED_INFO
 	select GUEST_PERF_EVENTS if PERF_EVENTS
-	select XARRAY_MULTI
 	help
 	  Support hosting virtualized guest machines.
 
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:10 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:10 +0000
Subject: [PATCH v4 09/26] KVM: arm64: nv: Correctly handle negative polarity FGTs
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-10-maz@kernel.org>

Negative trap bits are a massive pain. They are, on the surface,
indistinguishable from RES0 bits. Do you trap? or do you ignore?

Thankfully, we now have the right infrastructure to check for RES0
bits as long as the register is backed by VNCR, which is the case
for the FGT registers.

Use that information as a discriminant when handling a trap that
is potentially caused by a FGT.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 59 +++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 8a1cfcf553a2..ef46c2e45307 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1892,9 +1892,61 @@ static enum trap_behaviour compute_trap_behaviour(struct kvm_vcpu *vcpu,
 	return __compute_trap_behaviour(vcpu, tc.cgt, b);
 }
 
-static bool check_fgt_bit(u64 val, const union trap_config tc)
+static u64 kvm_get_sysreg_res0(struct kvm *kvm, enum vcpu_sysreg sr)
 {
-	return ((val >> tc.bit) & 1) == tc.pol;
+	struct kvm_sysreg_masks *masks;
+
+	/* Only handle the VNCR-backed regs for now */
+	if (sr < __VNCR_START__)
+		return 0;
+
+	masks = kvm->arch.sysreg_masks;
+
+	return masks->mask[sr - __VNCR_START__].res0;
+}
+
+static bool check_fgt_bit(struct kvm *kvm, bool is_read,
+			  u64 val, const union trap_config tc)
+{
+	enum vcpu_sysreg sr;
+
+	if (tc.pol)
+		return (val & BIT(tc.bit));
+
+	/*
+	 * FGTs with negative polarities are an absolute nightmare, as
+	 * we need to evaluate the bit in the light of the feature
+	 * that defines it. WTF were they thinking?
+	 *
+	 * So let's check if the bit has been earmarked as RES0, as
+	 * this indicates an unimplemented feature.
+	 */
+	if (val & BIT(tc.bit))
+		return false;
+
+	switch ((enum fgt_group_id)tc.fgt) {
+	case HFGxTR_GROUP:
+		sr = is_read ? HFGRTR_EL2 : HFGWTR_EL2;
+		break;
+
+	case HDFGRTR_GROUP:
+		sr = is_read ? HDFGRTR_EL2 : HDFGWTR_EL2;
+		break;
+
+	case HAFGRTR_GROUP:
+		sr = HAFGRTR_EL2;
+		break;
+
+	case HFGITR_GROUP:
+		sr = HFGITR_EL2;
+		break;
+
+	default:
+		WARN_ONCE(1, "Unhandled FGT group");
+		return false;
+	}
+
+	return !(kvm_get_sysreg_res0(kvm, sr) & BIT(tc.bit));
 }
 
 bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
@@ -1969,7 +2021,8 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 		return false;
 	}
 
-	if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(val, tc))
+	if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(vcpu->kvm, is_read,
+							val, tc))
 		goto inject;
 
 	b = compute_trap_behaviour(vcpu, tc);
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:13 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:13 +0000
Subject: [PATCH v4 12/26] KVM: arm64: nv: Move system instructions to their own sys_reg_desc array
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-13-maz@kernel.org>

As NV results in a bunch of system instructions being trapped, it makes
sense to pull the system instructions into their own little array, where
they will eventually be joined by AT, TLBI and a bunch of other CMOs.

Based on an initial patch by Jintack Lim.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 59 +++++++++++++++++++++++++++++----------
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 3c31f8cb9eef..70043bd78cd4 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2196,16 +2196,6 @@ static u64 reset_hcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
  * guest...
  */
 static const struct sys_reg_desc sys_reg_descs[] = {
-	{ SYS_DESC(SYS_DC_ISW), access_dcsw },
-	{ SYS_DESC(SYS_DC_IGSW), access_dcgsw },
-	{ SYS_DESC(SYS_DC_IGDSW), access_dcgsw },
-	{ SYS_DESC(SYS_DC_CSW), access_dcsw },
-	{ SYS_DESC(SYS_DC_CGSW), access_dcgsw },
-	{ SYS_DESC(SYS_DC_CGDSW), access_dcgsw },
-	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
-	{ SYS_DESC(SYS_DC_CIGSW), access_dcgsw },
-	{ SYS_DESC(SYS_DC_CIGDSW), access_dcgsw },
-
 	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 },
@@ -2737,6 +2727,18 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(SP_EL2, NULL, reset_unknown, 0),
 };
 
+static struct sys_reg_desc sys_insn_descs[] = {
+	{ SYS_DESC(SYS_DC_ISW), access_dcsw },
+	{ SYS_DESC(SYS_DC_IGSW), access_dcgsw },
+	{ SYS_DESC(SYS_DC_IGDSW), access_dcgsw },
+	{ SYS_DESC(SYS_DC_CSW), access_dcsw },
+	{ SYS_DESC(SYS_DC_CGSW), access_dcgsw },
+	{ SYS_DESC(SYS_DC_CGDSW), access_dcgsw },
+	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
+	{ SYS_DESC(SYS_DC_CIGSW), access_dcgsw },
+	{ SYS_DESC(SYS_DC_CIGDSW), access_dcgsw },
+};
+
 static const struct sys_reg_desc *first_idreg;
 
 static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
@@ -3429,6 +3431,24 @@ static bool emulate_sys_reg(struct kvm_vcpu *vcpu,
 	return false;
 }
 
+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;
+}
+
 static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
 {
 	const struct sys_reg_desc *idreg = first_idreg;
@@ -3476,7 +3496,8 @@ 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_reg -- 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)
@@ -3493,12 +3514,19 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
 	params = esr_sys64_to_params(esr);
 	params.regval = vcpu_get_reg(vcpu, Rt);
 
-	if (!emulate_sys_reg(vcpu, &params))
+	/* System registers have Op0=={2,3}, as per DDI487 J.a C5.1.2 */
+	if (params.Op0 == 2 || params.Op0 == 3) {
+		if (!emulate_sys_reg(vcpu, &params))
+			return 1;
+
+		if (!params.is_write)
+			vcpu_set_reg(vcpu, Rt, params.regval);
+
 		return 1;
+	}
 
-	if (!params.is_write)
-		vcpu_set_reg(vcpu, Rt, params.regval);
-	return 1;
+	/* Hints, PSTATE (Op0 == 0) and System instructions (Op0 == 1) */
+	return emulate_sys_instr(vcpu, &params);
 }
 
 /******************************************************************************
@@ -3952,6 +3980,7 @@ int __init kvm_sys_reg_table_init(void)
 	valid &= check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs), true);
 	valid &= check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs), true);
 	valid &= check_sysreg_table(invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs), false);
+	valid &= check_sysreg_table(sys_insn_descs, ARRAY_SIZE(sys_insn_descs), false);
 
 	if (!valid)
 		return -EINVAL;
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:06 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:06 +0000
Subject: [PATCH v4 05/26] KVM: arm64: nv: Add sanitising to VNCR-backed FGT sysregs
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-6-maz@kernel.org>

Fine Grained Traps are controlled by a whole bunch of features.
Each one of them must be checked and the corresponding masks
computed so that we don't let the guest apply traps it shouldn't
be using.

This takes care of HFG[IRW]TR_EL2, HDFG[RW]TR_EL2, and HAFGRTR_EL2.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/kvm/nested.c | 128 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 29ed529681e2..eda05eb16c0a 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -265,6 +265,134 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 		res1 |= HCR_E2H;
 	set_sysreg_masks(kvm, HCR_EL2, res0, res1);
 
+	/* HFG[RW]TR_EL2 */
+	res0 = res1 = 0;
+	if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
+	      __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_GENERIC)))
+		res0 |= (HFGxTR_EL2_APDAKey | HFGxTR_EL2_APDBKey |
+			 HFGxTR_EL2_APGAKey | HFGxTR_EL2_APIAKey |
+			 HFGxTR_EL2_APIBKey);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
+		res0 |= (HFGxTR_EL2_LORC_EL1 | HFGxTR_EL2_LOREA_EL1 |
+			 HFGxTR_EL2_LORID_EL1 | HFGxTR_EL2_LORN_EL1 |
+			 HFGxTR_EL2_LORSA_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, CSV2, CSV2_2) &&
+	    !kvm_has_feat(kvm, ID_AA64PFR1_EL1, CSV2_frac, CSV2_1p2))
+		res0 |= (HFGxTR_EL2_SCXTNUM_EL1 | HFGxTR_EL2_SCXTNUM_EL0);
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, GIC, IMP))
+		res0 |= HFGxTR_EL2_ICC_IGRPENn_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP))
+		res0 |= (HFGxTR_EL2_ERRIDR_EL1 | HFGxTR_EL2_ERRSELR_EL1 |
+			 HFGxTR_EL2_ERXFR_EL1 | HFGxTR_EL2_ERXCTLR_EL1 |
+			 HFGxTR_EL2_ERXSTATUS_EL1 | HFGxTR_EL2_ERXMISCn_EL1 |
+			 HFGxTR_EL2_ERXPFGF_EL1 | HFGxTR_EL2_ERXPFGCTL_EL1 |
+			 HFGxTR_EL2_ERXPFGCDN_EL1 | HFGxTR_EL2_ERXADDR_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA))
+		res0 |= HFGxTR_EL2_nACCDATA_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
+		res0 |= (HFGxTR_EL2_nGCS_EL0 | HFGxTR_EL2_nGCS_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
+		res0 |= (HFGxTR_EL2_nSMPRI_EL1 | HFGxTR_EL2_nTPIDR2_EL0);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
+		res0 |= HFGxTR_EL2_nRCWMASK_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
+		res0 |= (HFGxTR_EL2_nPIRE0_EL1 | HFGxTR_EL2_nPIR_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1POE, IMP))
+		res0 |= (HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nPOR_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
+		res0 |= HFGxTR_EL2_nS2POR_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, AIE, IMP))
+		res0 |= (HFGxTR_EL2_nMAIR2_EL1 | HFGxTR_EL2_nAMAIR2_EL1);
+	set_sysreg_masks(kvm, HFGRTR_EL2, res0 | __HFGRTR_EL2_RES0, res1);
+	set_sysreg_masks(kvm, HFGWTR_EL2, res0 | __HFGWTR_EL2_RES0, res1);
+
+	/* HDFG[RW]TR_EL2 */
+	res0 = res1 = 0;
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
+		res0 |= HDFGRTR_EL2_OSDLR_EL1;
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
+		res0 |= (HDFGRTR_EL2_PMEVCNTRn_EL0 | HDFGRTR_EL2_PMEVTYPERn_EL0 |
+			 HDFGRTR_EL2_PMCCFILTR_EL0 | HDFGRTR_EL2_PMCCNTR_EL0 |
+			 HDFGRTR_EL2_PMCNTEN | HDFGRTR_EL2_PMINTEN |
+			 HDFGRTR_EL2_PMOVS | HDFGRTR_EL2_PMSELR_EL0 |
+			 HDFGRTR_EL2_PMMIR_EL1 | HDFGRTR_EL2_PMUSERENR_EL0 |
+			 HDFGRTR_EL2_PMCEIDn_EL0);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, IMP))
+		res0 |= (HDFGRTR_EL2_PMBLIMITR_EL1 | HDFGRTR_EL2_PMBPTR_EL1 |
+			 HDFGRTR_EL2_PMBSR_EL1 | HDFGRTR_EL2_PMSCR_EL1 |
+			 HDFGRTR_EL2_PMSEVFR_EL1 | HDFGRTR_EL2_PMSFCR_EL1 |
+			 HDFGRTR_EL2_PMSICR_EL1 | HDFGRTR_EL2_PMSIDR_EL1 |
+			 HDFGRTR_EL2_PMSIRR_EL1 | HDFGRTR_EL2_PMSLATFR_EL1 |
+			 HDFGRTR_EL2_PMBIDR_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP))
+		res0 |= (HDFGRTR_EL2_TRC | HDFGRTR_EL2_TRCAUTHSTATUS |
+			 HDFGRTR_EL2_TRCAUXCTLR | HDFGRTR_EL2_TRCCLAIM |
+			 HDFGRTR_EL2_TRCCNTVRn | HDFGRTR_EL2_TRCID |
+			 HDFGRTR_EL2_TRCIMSPECn | HDFGRTR_EL2_TRCOSLSR |
+			 HDFGRTR_EL2_TRCPRGCTLR | HDFGRTR_EL2_TRCSEQSTR |
+			 HDFGRTR_EL2_TRCSSCSRn | HDFGRTR_EL2_TRCSTATR |
+			 HDFGRTR_EL2_TRCVICTLR);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
+		res0 |= (HDFGRTR_EL2_TRBBASER_EL1 | HDFGRTR_EL2_TRBIDR_EL1 |
+			 HDFGRTR_EL2_TRBLIMITR_EL1 | HDFGRTR_EL2_TRBMAR_EL1 |
+			 HDFGRTR_EL2_TRBPTR_EL1 | HDFGRTR_EL2_TRBSR_EL1 |
+			 HDFGRTR_EL2_TRBTRG_EL1);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, BRBE, IMP))
+		res0 |= (HDFGRTR_EL2_nBRBIDR | HDFGRTR_EL2_nBRBCTL |
+			 HDFGRTR_EL2_nBRBDATA);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, V1P2))
+		res0 |= HDFGRTR_EL2_nPMSNEVFR_EL1;
+	set_sysreg_masks(kvm, HDFGRTR_EL2, res0 | HDFGRTR_EL2_RES0, res1);
+
+	/* Reuse the bits from the read-side and add the write-specific stuff */
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
+		res0 |= (HDFGWTR_EL2_PMCR_EL0 | HDFGWTR_EL2_PMSWINC_EL0);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP))
+		res0 |= HDFGWTR_EL2_TRCOSLAR;
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
+		res0 |= HDFGWTR_EL2_TRFCR_EL1;
+	set_sysreg_masks(kvm, HFGWTR_EL2, res0 | HDFGWTR_EL2_RES0, res1);
+
+	/* HFGITR_EL2 */
+	res0 = HFGITR_EL2_RES0;
+	res1 = HFGITR_EL2_RES1;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, DPB, DPB2))
+		res0 |= HFGITR_EL2_DCCVADP;
+	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, PAN, PAN2))
+		res0 |= (HFGITR_EL2_ATS1E1RP | HFGITR_EL2_ATS1E1WP);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+		res0 |= (HFGITR_EL2_TLBIRVAALE1OS | HFGITR_EL2_TLBIRVALE1OS |
+			 HFGITR_EL2_TLBIRVAAE1OS | HFGITR_EL2_TLBIRVAE1OS |
+			 HFGITR_EL2_TLBIVAALE1OS | HFGITR_EL2_TLBIVALE1OS |
+			 HFGITR_EL2_TLBIVAAE1OS | HFGITR_EL2_TLBIASIDE1OS |
+			 HFGITR_EL2_TLBIVAE1OS | HFGITR_EL2_TLBIVMALLE1OS);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
+		res0 |= (HFGITR_EL2_TLBIRVAALE1 | HFGITR_EL2_TLBIRVALE1 |
+			 HFGITR_EL2_TLBIRVAAE1 | HFGITR_EL2_TLBIRVAE1 |
+			 HFGITR_EL2_TLBIRVAALE1IS | HFGITR_EL2_TLBIRVALE1IS |
+			 HFGITR_EL2_TLBIRVAAE1IS | HFGITR_EL2_TLBIRVAE1IS |
+			 HFGITR_EL2_TLBIRVAALE1OS | HFGITR_EL2_TLBIRVALE1OS |
+			 HFGITR_EL2_TLBIRVAAE1OS | HFGITR_EL2_TLBIRVAE1OS);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, SPECRES, IMP))
+		res0 |= (HFGITR_EL2_CFPRCTX | HFGITR_EL2_DVPRCTX |
+			 HFGITR_EL2_CPPRCTX);
+	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, BRBE, IMP))
+		res0 |= (HFGITR_EL2_nBRBINJ | HFGITR_EL2_nBRBIALL);
+	if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
+		res0 |= (HFGITR_EL2_nGCSPUSHM_EL1 | HFGITR_EL2_nGCSSTR_EL1 |
+			 HFGITR_EL2_nGCSEPP);
+	if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, SPECRES, COSP_RCTX))
+		res0 |= HFGITR_EL2_COSPRCTX;
+	if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, ATS1A, IMP))
+		res0 |= HFGITR_EL2_ATS1E1A;
+	set_sysreg_masks(kvm, HFGITR_EL2, res0, res1);
+
+	/* HAFGRTR_EL2 - not a lot to see here */
+	res0 = HAFGRTR_EL2_RES0;
+	res1 = HAFGRTR_EL2_RES1;
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1))
+		res0 |= ~(res0 | res1);
+	set_sysreg_masks(kvm, HAFGRTR_EL2, res0, res1);
 out:
 	mutex_unlock(&kvm->arch.config_lock);
 
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:19 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:19 +0000
Subject: [PATCH v4 18/26] KVM: arm64: Propagate and handle Fine-Grained UNDEF bits
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-19-maz@kernel.org>

In order to correctly honor our FGU bits, they must be converted
into a set of FGT bits. They get merged as part of the existing
FGT setting.

Similarly, the UNDEF injection phase takes place when handling
the trap.

This results in a bit of rework in the FGT macros in order to
help with the code generation, as burying per-CPU accesses in
macros results in a lot of expansion, not to mention the vcpu->kvm
access on nvhe (kern_hyp_va() is not optimisation-friendly).

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c         | 11 ++++
 arch/arm64/kvm/hyp/include/hyp/switch.h | 81 +++++++++++++++++++------
 2 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index b67078b8271b..4697ba41b3a9 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2017,6 +2017,17 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
 	if (!tc.val)
 		goto local;
 
+	/*
+	 * If a sysreg can be trapped using a FGT, first check whether we
+	 * trap for the purpose of forbidding the feature. In that case,
+	 * inject an UNDEF.
+	 */
+	if (tc.fgt != __NO_FGT_GROUP__ &&
+	    (vcpu->kvm->arch.fgu[tc.fgt] & BIT(tc.bit))) {
+		kvm_inject_undefined(vcpu);
+		return true;
+	}
+
 	/*
 	 * If we're not nesting, immediately return to the caller, with the
 	 * sysreg index, should we have it.
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index a038320cdb08..a09149fd91ed 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -79,14 +79,48 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
 		clr |= ~hfg & __ ## reg ## _nMASK; 			\
 	} while(0)
 
-#define update_fgt_traps_cs(vcpu, reg, clr, set)			\
+#define reg_to_fgt_group_id(reg)					\
+	({								\
+		enum fgt_group_id id;					\
+		switch(reg) {						\
+		case HFGRTR_EL2:					\
+		case HFGWTR_EL2:					\
+			id = HFGxTR_GROUP;				\
+			break;						\
+		case HFGITR_EL2:					\
+			id = HFGITR_GROUP;				\
+			break;						\
+		case HDFGRTR_EL2:					\
+		case HDFGWTR_EL2:					\
+			id = HDFGRTR_GROUP;				\
+			break;						\
+		case HAFGRTR_EL2:					\
+			id = HAFGRTR_GROUP;				\
+			break;						\
+		default:						\
+			BUILD_BUG_ON(1);				\
+		}							\
+									\
+		id;							\
+	})
+
+#define compute_undef_clr_set(vcpu, kvm, reg, clr, set)			\
+	do {								\
+		u64 hfg = kvm->arch.fgu[reg_to_fgt_group_id(reg)];	\
+		set |= hfg & __ ## reg ## _MASK;			\
+		clr |= hfg & __ ## reg ## _nMASK; 			\
+	} while(0)
+
+#define update_fgt_traps_cs(hctxt, vcpu, kvm, reg, clr, set)		\
 	do {								\
-		struct kvm_cpu_context *hctxt =				\
-			&this_cpu_ptr(&kvm_host_data)->host_ctxt;	\
 		u64 c = 0, s = 0;					\
 									\
 		ctxt_sys_reg(hctxt, reg) = read_sysreg_s(SYS_ ## reg);	\
-		compute_clr_set(vcpu, reg, c, s);			\
+		if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu))		\
+			compute_clr_set(vcpu, reg, c, s);		\
+									\
+		compute_undef_clr_set(vcpu, kvm, reg, c, s);		\
+									\
 		s |= set;						\
 		c |= clr;						\
 		if (c || s) {						\
@@ -97,8 +131,8 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
 		}							\
 	} while(0)
 
-#define update_fgt_traps(vcpu, reg)		\
-	update_fgt_traps_cs(vcpu, reg, 0, 0)
+#define update_fgt_traps(hctxt, vcpu, kvm, reg)		\
+	update_fgt_traps_cs(hctxt, vcpu, kvm, reg, 0, 0)
 
 /*
  * Validate the fine grain trap masks.
@@ -122,6 +156,7 @@ static inline bool cpu_has_amu(void)
 static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
 	u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0, tmp;
 	u64 r_val, w_val;
 
@@ -157,6 +192,9 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 		compute_clr_set(vcpu, HFGWTR_EL2, w_clr, w_set);
 	}
 
+	compute_undef_clr_set(vcpu, kvm, HFGRTR_EL2, r_clr, r_set);
+	compute_undef_clr_set(vcpu, kvm, HFGWTR_EL2, w_clr, w_set);
+
 	/* The default to trap everything not handled or supported in KVM. */
 	tmp = HFGxTR_EL2_nAMAIR2_EL1 | HFGxTR_EL2_nMAIR2_EL1 | HFGxTR_EL2_nS2POR_EL1 |
 	      HFGxTR_EL2_nPOR_EL1 | HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nACCDATA_EL1;
@@ -172,20 +210,26 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	write_sysreg_s(r_val, SYS_HFGRTR_EL2);
 	write_sysreg_s(w_val, SYS_HFGWTR_EL2);
 
-	if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
-		return;
-
-	update_fgt_traps(vcpu, HFGITR_EL2);
-	update_fgt_traps(vcpu, HDFGRTR_EL2);
-	update_fgt_traps(vcpu, HDFGWTR_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HFGITR_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HDFGRTR_EL2);
+	update_fgt_traps(hctxt, vcpu, kvm, HDFGWTR_EL2);
 
 	if (cpu_has_amu())
-		update_fgt_traps(vcpu, HAFGRTR_EL2);
+		update_fgt_traps(hctxt, vcpu, kvm, HAFGRTR_EL2);
 }
 
+#define __deactivate_fgt(htcxt, vcpu, kvm, reg)				\
+	do {								\
+		if ((vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) ||	\
+		    kvm->arch.fgu[reg_to_fgt_group_id(reg)])		\
+			write_sysreg_s(ctxt_sys_reg(hctxt, reg),	\
+				       SYS_ ## reg);			\
+	} while(0)
+
 static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
+	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
 
 	if (!cpus_have_final_cap(ARM64_HAS_FGT))
 		return;
@@ -193,15 +237,12 @@ static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	write_sysreg_s(ctxt_sys_reg(hctxt, HFGRTR_EL2), SYS_HFGRTR_EL2);
 	write_sysreg_s(ctxt_sys_reg(hctxt, HFGWTR_EL2), SYS_HFGWTR_EL2);
 
-	if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
-		return;
-
-	write_sysreg_s(ctxt_sys_reg(hctxt, HFGITR_EL2), SYS_HFGITR_EL2);
-	write_sysreg_s(ctxt_sys_reg(hctxt, HDFGRTR_EL2), SYS_HDFGRTR_EL2);
-	write_sysreg_s(ctxt_sys_reg(hctxt, HDFGWTR_EL2), SYS_HDFGWTR_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HFGITR_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HDFGRTR_EL2);
+	__deactivate_fgt(hctxt, vcpu, kvm, HDFGWTR_EL2);
 
 	if (cpu_has_amu())
-		write_sysreg_s(ctxt_sys_reg(hctxt, HAFGRTR_EL2), SYS_HAFGRTR_EL2);
+		__deactivate_fgt(hctxt, vcpu, kvm, HAFGRTR_EL2);
 }
 
 static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:14 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:14 +0000
Subject: [PATCH v4 13/26] KVM: arm64: Always populate the trap configuration xarray
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-14-maz@kernel.org>

As we are going to rely more and more on the global xarray that
contains the trap configuration, always populate it, even in the
non-NV case.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 70043bd78cd4..57f3d0c53fc3 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3995,8 +3995,5 @@ int __init kvm_sys_reg_table_init(void)
 	if (!first_idreg)
 		return -EINVAL;
 
-	if (kvm_get_mode() == KVM_MODE_NV)
-		return populate_nv_trap_config();
-
-	return 0;
+	return populate_nv_trap_config();
 }
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:15 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:15 +0000
Subject: [PATCH v4 14/26] KVM: arm64: Register AArch64 system register entries with the sysreg xarray
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-15-maz@kernel.org>

In order to reduce the number of lookups that we have to perform
when handling a sysreg, register each AArch64 sysreg descriptor
with the global xarray. The index of the descriptor is stored
as a 10 bit field in the data word.

Subsequent patches will retrieve and use the stored index.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  3 +++
 arch/arm64/kvm/emulate-nested.c   | 39 +++++++++++++++++++++++++++++--
 arch/arm64/kvm/sys_regs.c         | 11 ++++++++-
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 8cda003d6267..914fd54179bb 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1078,6 +1078,9 @@ int kvm_handle_cp10_id(struct kvm_vcpu *vcpu);
 void kvm_reset_sys_regs(struct kvm_vcpu *vcpu);
 
 int __init kvm_sys_reg_table_init(void);
+struct sys_reg_desc;
+int __init populate_sysreg_config(const struct sys_reg_desc *sr,
+				  unsigned int idx);
 int __init populate_nv_trap_config(void);
 
 bool lock_all_vcpus(struct kvm *kvm);
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 42f5b4483c80..ddf760b4dda5 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -427,12 +427,14 @@ static const complex_condition_check ccc[] = {
  * [19:14]	bit number in the FGT register (6 bits)
  * [20]		trap polarity (1 bit)
  * [25:21]	FG filter (5 bits)
- * [62:26]	Unused (37 bits)
+ * [35:26]	Main SysReg table index (10 bits)
+ * [62:36]	Unused (27 bits)
  * [63]		RES0 - Must be zero, as lost on insertion in the xarray
  */
 #define TC_CGT_BITS	10
 #define TC_FGT_BITS	4
 #define TC_FGF_BITS	5
+#define TC_SRI_BITS	10
 
 union trap_config {
 	u64	val;
@@ -442,7 +444,8 @@ union trap_config {
 		unsigned long	bit:6;		 /* Bit number */
 		unsigned long	pol:1;		 /* Polarity */
 		unsigned long	fgf:TC_FGF_BITS; /* Fine Grained Filter */
-		unsigned long	unused:37;	 /* Unused, should be zero */
+		unsigned long	sri:TC_SRI_BITS; /* SysReg Index */
+		unsigned long	unused:27;	 /* Unused, should be zero */
 		unsigned long	mbz:1;		 /* Must Be Zero */
 	};
 };
@@ -1868,6 +1871,38 @@ int __init populate_nv_trap_config(void)
 	return ret;
 }
 
+int __init populate_sysreg_config(const struct sys_reg_desc *sr,
+				  unsigned int idx)
+{
+	union trap_config tc;
+	u32 encoding;
+	void *ret;
+
+	/*
+	 * 0 is a valid value for the index, but not for the storage.
+	 * We'll store (idx+1), so check against an offset'd limit.
+	 */
+	if (idx >= (BIT(TC_SRI_BITS) - 1)) {
+		kvm_err("sysreg %s (%d) out of range\n", sr->name, idx);
+		return -EINVAL;
+	}
+
+	encoding = sys_reg(sr->Op0, sr->Op1, sr->CRn, sr->CRm, sr->Op2);
+	tc = get_trap_config(encoding);
+
+	if (tc.sri) {
+		kvm_err("sysreg %s (%d) duplicate entry (%d)\n",
+			sr->name, idx - 1, tc.sri);
+		return -EINVAL;
+	}
+
+	tc.sri = idx + 1;
+	ret = xa_store(&sr_forward_xa, encoding,
+		       xa_mk_value(tc.val), GFP_KERNEL);
+
+	return xa_err(ret);
+}
+
 static enum trap_behaviour get_behaviour(struct kvm_vcpu *vcpu,
 					 const struct trap_bits *tb)
 {
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 57f3d0c53fc3..a410e99f827e 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3972,6 +3972,7 @@ int __init kvm_sys_reg_table_init(void)
 	struct sys_reg_params params;
 	bool valid = true;
 	unsigned int i;
+	int ret = 0;
 
 	/* Make sure tables are unique and in order. */
 	valid &= check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs), false);
@@ -3995,5 +3996,13 @@ int __init kvm_sys_reg_table_init(void)
 	if (!first_idreg)
 		return -EINVAL;
 
-	return populate_nv_trap_config();
+	ret = populate_nv_trap_config();
+
+	for (i = 0; !ret && i < ARRAY_SIZE(sys_reg_descs); i++)
+		ret = populate_sysreg_config(sys_reg_descs + i, i);
+
+	for (i = 0; !ret && i < ARRAY_SIZE(sys_insn_descs); i++)
+		ret = populate_sysreg_config(sys_insn_descs + i, i);
+
+	return ret;
 }
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:21 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:21 +0000
Subject: [PATCH v4 20/26] KVM: arm64: Streamline save/restore of HFG[RW]TR_EL2
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-21-maz@kernel.org>

The way we save/restore HFG[RW]TR_EL2 can now be simplified, and
the Ampere erratum hack is the only thing that still stands out.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 42 ++++++-------------------
 1 file changed, 9 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 245f9c1ca666..2d5891518006 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -157,8 +157,6 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
 	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
-	u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0;
-	u64 r_val, w_val;
 
 	CHECK_FGT_MASKS(HFGRTR_EL2);
 	CHECK_FGT_MASKS(HFGWTR_EL2);
@@ -171,34 +169,10 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	if (!cpus_have_final_cap(ARM64_HAS_FGT))
 		return;
 
-	ctxt_sys_reg(hctxt, HFGRTR_EL2) = read_sysreg_s(SYS_HFGRTR_EL2);
-	ctxt_sys_reg(hctxt, HFGWTR_EL2) = read_sysreg_s(SYS_HFGWTR_EL2);
-
-	/*
-	 * Trap guest writes to TCR_EL1 to prevent it from enabling HA or HD.
-	 */
-	if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
-		w_set |= HFGxTR_EL2_TCR_EL1_MASK;
-
-	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
-		compute_clr_set(vcpu, HFGRTR_EL2, r_clr, r_set);
-		compute_clr_set(vcpu, HFGWTR_EL2, w_clr, w_set);
-	}
-
-	compute_undef_clr_set(vcpu, kvm, HFGRTR_EL2, r_clr, r_set);
-	compute_undef_clr_set(vcpu, kvm, HFGWTR_EL2, w_clr, w_set);
-
-	r_val = __HFGRTR_EL2_nMASK;
-	r_val |= r_set;
-	r_val &= ~r_clr;
-
-	w_val = __HFGWTR_EL2_nMASK;
-	w_val |= w_set;
-	w_val &= ~w_clr;
-
-	write_sysreg_s(r_val, SYS_HFGRTR_EL2);
-	write_sysreg_s(w_val, SYS_HFGWTR_EL2);
-
+	update_fgt_traps(hctxt, vcpu, kvm, HFGRTR_EL2);
+	update_fgt_traps_cs(hctxt, vcpu, kvm, HFGWTR_EL2, 0,
+			    cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38) ?
+			    HFGxTR_EL2_TCR_EL1_MASK : 0);
 	update_fgt_traps(hctxt, vcpu, kvm, HFGITR_EL2);
 	update_fgt_traps(hctxt, vcpu, kvm, HDFGRTR_EL2);
 	update_fgt_traps(hctxt, vcpu, kvm, HDFGWTR_EL2);
@@ -223,9 +197,11 @@ static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	if (!cpus_have_final_cap(ARM64_HAS_FGT))
 		return;
 
-	write_sysreg_s(ctxt_sys_reg(hctxt, HFGRTR_EL2), SYS_HFGRTR_EL2);
-	write_sysreg_s(ctxt_sys_reg(hctxt, HFGWTR_EL2), SYS_HFGWTR_EL2);
-
+	__deactivate_fgt(hctxt, vcpu, kvm, HFGRTR_EL2);
+	if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
+		write_sysreg_s(ctxt_sys_reg(hctxt, HFGWTR_EL2), SYS_HFGWTR_EL2);
+	else
+		__deactivate_fgt(hctxt, vcpu, kvm, HFGWTR_EL2);
 	__deactivate_fgt(hctxt, vcpu, kvm, HFGITR_EL2);
 	__deactivate_fgt(hctxt, vcpu, kvm, HDFGRTR_EL2);
 	__deactivate_fgt(hctxt, vcpu, kvm, HDFGWTR_EL2);
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:17 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:17 +0000
Subject: [PATCH v4 16/26] KVM: arm64: Rename __check_nv_sr_forward() to triage_sysreg_trap()
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-17-maz@kernel.org>

__check_nv_sr_forward() is not specific to NV anymore, and does
a lot more. Rename it to triage_sysreg_trap(), making it plain
that its role is to handle where an exception is to be handled.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h | 1 -
 arch/arm64/kvm/emulate-nested.c     | 2 +-
 arch/arm64/kvm/sys_regs.c           | 2 +-
 arch/arm64/kvm/sys_regs.h           | 2 ++
 4 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 68465f87d308..c77d795556e1 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -60,7 +60,6 @@ static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
 	return ttbr0 & ~GENMASK_ULL(63, 48);
 }
 
-extern bool __check_nv_sr_forward(struct kvm_vcpu *vcpu, int *sr_idx);
 
 int kvm_init_nv_sysregs(struct kvm *kvm);
 
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 5aeaa688755f..4f2a32a8f247 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2007,7 +2007,7 @@ static bool check_fgt_bit(struct kvm *kvm, bool is_read,
 	return !(kvm_get_sysreg_res0(kvm, sr) & BIT(tc.bit));
 }
 
-bool __check_nv_sr_forward(struct kvm_vcpu *vcpu, int *sr_index)
+bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
 {
 	union trap_config tc;
 	enum trap_behaviour b;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index bc076ef8440b..938df5dc3684 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3482,7 +3482,7 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
 
 	trace_kvm_handle_sys_reg(esr);
 
-	if (__check_nv_sr_forward(vcpu, &sr_idx))
+	if (triage_sysreg_trap(vcpu, &sr_idx))
 		return 1;
 
 	params = esr_sys64_to_params(esr);
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index c65c129b3500..997eea21ba2a 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -233,6 +233,8 @@ int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
 int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
 			 const struct sys_reg_desc table[], unsigned int num);
 
+bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index);
+
 #define AA32(_x)	.aarch32_map = AA32_##_x
 #define Op0(_x) 	.Op0 = _x
 #define Op1(_x) 	.Op1 = _x
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:18 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:18 +0000
Subject: [PATCH v4 17/26] KVM: arm64: Add Fine-Grained UNDEF tracking information
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-18-maz@kernel.org>

In order to efficiently handle system register access being disabled,
and this resulting in an UNDEF exception being injected, we introduce
the (slightly dubious) concept of Fine-Grained UNDEF, modeled after
the architectural Fine-Grained Traps.

For each FGT group, we keep a 64 bit word that has the exact same
bit assignment as the corresponding FGT register, where a 1 indicates
that trapping this register should result in an UNDEF exception being
reinjected.

So far, nothing populates this information, nor sets the corresponding
trap bits.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 21 +++++++++++++++++++++
 arch/arm64/kvm/emulate-nested.c   | 12 ------------
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 914fd54179bb..c69b258fc989 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -240,9 +240,30 @@ static inline u16 kvm_mpidr_index(struct kvm_mpidr_data *data, u64 mpidr)
 
 struct kvm_sysreg_masks;
 
+enum fgt_group_id {
+	__NO_FGT_GROUP__,
+	HFGxTR_GROUP,
+	HDFGRTR_GROUP,
+	HDFGWTR_GROUP = HDFGRTR_GROUP,
+	HFGITR_GROUP,
+	HAFGRTR_GROUP,
+
+	/* Must be last */
+	__NR_FGT_GROUP_IDS__
+};
+
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
 
+	/*
+	 * Fine-Grained UNDEF, mimicking the FGT layout defined by the
+	 * architecture. We track them globally, as we present the
+	 * same feature-set to all vcpus.
+	 *
+	 * Index 0 is currently spare.
+	 */
+	u64 fgu[__NR_FGT_GROUP_IDS__];
+
 	/* Interrupt controller */
 	struct vgic_dist	vgic;
 
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 4f2a32a8f247..b67078b8271b 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1009,18 +1009,6 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
 
 static DEFINE_XARRAY(sr_forward_xa);
 
-enum fgt_group_id {
-	__NO_FGT_GROUP__,
-	HFGxTR_GROUP,
-	HDFGRTR_GROUP,
-	HDFGWTR_GROUP = HDFGRTR_GROUP,
-	HFGITR_GROUP,
-	HAFGRTR_GROUP,
-
-	/* Must be last */
-	__NR_FGT_GROUP_IDS__
-};
-
 enum fg_filter_id {
 	__NO_FGF__,
 	HCRX_FGTnXS,
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:20 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:20 +0000
Subject: [PATCH v4 19/26] KVM: arm64: Move existing feature disabling over to FGU infrastructure
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-20-maz@kernel.org>

We already trap a bunch of existing features for the purpose of
disabling them (MAIR2, POR, ACCDATA, SME...).

Let's move them over to our brand new FGU infrastructure.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h       |  4 ++++
 arch/arm64/kvm/arm.c                    |  6 ++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h | 17 +++--------------
 arch/arm64/kvm/sys_regs.c               | 23 +++++++++++++++++++++++
 4 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index c69b258fc989..968a997b3f02 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -297,6 +297,8 @@ struct kvm_arch {
 #define KVM_ARCH_FLAG_TIMER_PPIS_IMMUTABLE		6
 	/* Initial ID reg values loaded */
 #define KVM_ARCH_FLAG_ID_REGS_INITIALIZED		7
+	/* Fine-Grained UNDEF initialised */
+#define KVM_ARCH_FLAG_FGU_INITIALIZED			8
 	unsigned long flags;
 
 	/* VM-wide vCPU feature set */
@@ -1107,6 +1109,8 @@ int __init populate_nv_trap_config(void);
 bool lock_all_vcpus(struct kvm *kvm);
 void unlock_all_vcpus(struct kvm *kvm);
 
+void kvm_init_sysreg(struct kvm_vcpu *);
+
 /* MMIO helpers */
 void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
 unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index c063e84fc72c..9f806c9b7d5d 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -675,6 +675,12 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
 			return ret;
 	}
 
+	/*
+	 * This needs to happen after NV has imposed its own restrictions on
+	 * the feature set
+	 */
+	kvm_init_sysreg(vcpu);
+
 	ret = kvm_timer_enable(vcpu);
 	if (ret)
 		return ret;
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index a09149fd91ed..245f9c1ca666 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -157,7 +157,7 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
 	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
-	u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0, tmp;
+	u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0;
 	u64 r_val, w_val;
 
 	CHECK_FGT_MASKS(HFGRTR_EL2);
@@ -174,13 +174,6 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	ctxt_sys_reg(hctxt, HFGRTR_EL2) = read_sysreg_s(SYS_HFGRTR_EL2);
 	ctxt_sys_reg(hctxt, HFGWTR_EL2) = read_sysreg_s(SYS_HFGWTR_EL2);
 
-	if (cpus_have_final_cap(ARM64_SME)) {
-		tmp = HFGxTR_EL2_nSMPRI_EL1_MASK | HFGxTR_EL2_nTPIDR2_EL0_MASK;
-
-		r_clr |= tmp;
-		w_clr |= tmp;
-	}
-
 	/*
 	 * Trap guest writes to TCR_EL1 to prevent it from enabling HA or HD.
 	 */
@@ -195,15 +188,11 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
 	compute_undef_clr_set(vcpu, kvm, HFGRTR_EL2, r_clr, r_set);
 	compute_undef_clr_set(vcpu, kvm, HFGWTR_EL2, w_clr, w_set);
 
-	/* The default to trap everything not handled or supported in KVM. */
-	tmp = HFGxTR_EL2_nAMAIR2_EL1 | HFGxTR_EL2_nMAIR2_EL1 | HFGxTR_EL2_nS2POR_EL1 |
-	      HFGxTR_EL2_nPOR_EL1 | HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nACCDATA_EL1;
-
-	r_val = __HFGRTR_EL2_nMASK & ~tmp;
+	r_val = __HFGRTR_EL2_nMASK;
 	r_val |= r_set;
 	r_val &= ~r_clr;
 
-	w_val = __HFGWTR_EL2_nMASK & ~tmp;
+	w_val = __HFGWTR_EL2_nMASK;
 	w_val |= w_set;
 	w_val &= ~w_clr;
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 938df5dc3684..39e7c7f74717 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3942,6 +3942,29 @@ int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm, struct reg_mask_range *
 	return 0;
 }
 
+void kvm_init_sysreg(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+
+	mutex_lock(&kvm->arch.config_lock);
+
+	if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags))
+		goto out;
+
+	kvm->arch.fgu[HFGxTR_GROUP] = (HFGxTR_EL2_nAMAIR2_EL1		|
+				       HFGxTR_EL2_nMAIR2_EL1		|
+				       HFGxTR_EL2_nS2POR_EL1		|
+				       HFGxTR_EL2_nPOR_EL1		|
+				       HFGxTR_EL2_nPOR_EL0		|
+				       HFGxTR_EL2_nACCDATA_EL1		|
+				       HFGxTR_EL2_nSMPRI_EL1_MASK	|
+				       HFGxTR_EL2_nTPIDR2_EL0_MASK);
+
+	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
+out:
+	mutex_unlock(&kvm->arch.config_lock);
+}
+
 int __init kvm_sys_reg_table_init(void)
 {
 	struct sys_reg_params params;
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:16 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:16 +0000
Subject: [PATCH v4 15/26] KVM: arm64: Use the xarray as the primary sysreg/sysinsn walker
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-16-maz@kernel.org>

Since we always start sysreg/sysinsn handling by searching the
xarray, use it as the source of the index in the correct sys_reg_desc
array.

This allows some cleanup, such as moving the handling of unknown
sysregs in a single location.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h |  2 +-
 arch/arm64/kvm/emulate-nested.c     | 40 +++++++++++++-----
 arch/arm64/kvm/sys_regs.c           | 63 +++++++++--------------------
 3 files changed, 50 insertions(+), 55 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 4882905357f4..68465f87d308 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -60,7 +60,7 @@ static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
 	return ttbr0 & ~GENMASK_ULL(63, 48);
 }
 
-extern bool __check_nv_sr_forward(struct kvm_vcpu *vcpu);
+extern bool __check_nv_sr_forward(struct kvm_vcpu *vcpu, int *sr_idx);
 
 int kvm_init_nv_sysregs(struct kvm *kvm);
 
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index ddf760b4dda5..5aeaa688755f 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2007,7 +2007,7 @@ static bool check_fgt_bit(struct kvm *kvm, bool is_read,
 	return !(kvm_get_sysreg_res0(kvm, sr) & BIT(tc.bit));
 }
 
-bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
+bool __check_nv_sr_forward(struct kvm_vcpu *vcpu, int *sr_index)
 {
 	union trap_config tc;
 	enum trap_behaviour b;
@@ -2015,9 +2015,6 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 	u32 sysreg;
 	u64 esr, val;
 
-	if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
-		return false;
-
 	esr = kvm_vcpu_get_esr(vcpu);
 	sysreg = esr_sys64_to_sysreg(esr);
 	is_read = (esr & ESR_ELx_SYS64_ISS_DIR_MASK) == ESR_ELx_SYS64_ISS_DIR_READ;
@@ -2028,13 +2025,16 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 	 * A value of 0 for the whole entry means that we know nothing
 	 * for this sysreg, and that it cannot be re-injected into the
 	 * nested hypervisor. In this situation, let's cut it short.
-	 *
-	 * Note that ultimately, we could also make use of the xarray
-	 * to store the index of the sysreg in the local descriptor
-	 * array, avoiding another search... Hint, hint...
 	 */
 	if (!tc.val)
-		return false;
+		goto local;
+
+	/*
+	 * If we're not nesting, immediately return to the caller, with the
+	 * sysreg index, should we have it.
+	 */
+	if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
+		goto local;
 
 	switch ((enum fgt_group_id)tc.fgt) {
 	case __NO_FGT_GROUP__:
@@ -2076,7 +2076,7 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 	case __NR_FGT_GROUP_IDS__:
 		/* Something is really wrong, bail out */
 		WARN_ONCE(1, "__NR_FGT_GROUP_IDS__");
-		return false;
+		goto local;
 	}
 
 	if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(vcpu->kvm, is_read,
@@ -2089,6 +2089,26 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
 	    ((b & BEHAVE_FORWARD_WRITE) && !is_read))
 		goto inject;
 
+local:
+	if (!tc.sri) {
+		struct sys_reg_params params;
+
+		params = esr_sys64_to_params(esr);
+
+		/*
+		 * Check for the IMPDEF range, as per DDI0487 J.a,
+		 * D18.3.2 Reserved encodings for IMPLEMENTATION
+		 * DEFINED registers.
+		 */
+		if (!(params.Op0 == 3 && (params.CRn & 0b1011) == 0b1011))
+			print_sys_reg_msg(&params,
+					  "Unsupported guest access at: %lx\n",
+					  *vcpu_pc(vcpu));
+		kvm_inject_undefined(vcpu);
+		return true;
+	}
+
+	*sr_index = tc.sri - 1;
 	return false;
 
 inject:
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index a410e99f827e..bc076ef8440b 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3395,12 +3395,6 @@ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu)
 	return kvm_handle_cp_32(vcpu, &params, cp14_regs, ARRAY_SIZE(cp14_regs));
 }
 
-static bool is_imp_def_sys_reg(struct sys_reg_params *params)
-{
-	// See ARM DDI 0487E.a, section D12.3.2
-	return params->Op0 == 3 && (params->CRn & 0b1011) == 0b1011;
-}
-
 /**
  * emulate_sys_reg - Emulate a guest access to an AArch64 system register
  * @vcpu: The VCPU pointer
@@ -3409,44 +3403,22 @@ static bool is_imp_def_sys_reg(struct sys_reg_params *params)
  * Return: true if the system register access was successful, false otherwise.
  */
 static bool emulate_sys_reg(struct kvm_vcpu *vcpu,
-			   struct sys_reg_params *params)
+			    struct sys_reg_params *params)
 {
 	const struct sys_reg_desc *r;
 
 	r = find_reg(params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
-
 	if (likely(r)) {
 		perform_access(vcpu, params, r);
 		return true;
 	}
 
-	if (is_imp_def_sys_reg(params)) {
-		kvm_inject_undefined(vcpu);
-	} else {
-		print_sys_reg_msg(params,
-				  "Unsupported guest sys_reg access at: %lx [%08lx]\n",
-				  *vcpu_pc(vcpu), *vcpu_cpsr(vcpu));
-		kvm_inject_undefined(vcpu);
-	}
-	return false;
-}
-
-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));
+	print_sys_reg_msg(params,
+			  "Unsupported guest sys_reg access at: %lx [%08lx]\n",
+			  *vcpu_pc(vcpu), *vcpu_cpsr(vcpu));
+	kvm_inject_undefined(vcpu);
 
-	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;
+	return false;
 }
 
 static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
@@ -3502,31 +3474,34 @@ void kvm_reset_sys_regs(struct kvm_vcpu *vcpu)
  */
 int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
 {
+	const struct sys_reg_desc *desc = NULL;
 	struct sys_reg_params params;
 	unsigned long esr = kvm_vcpu_get_esr(vcpu);
 	int Rt = kvm_vcpu_sys_get_rt(vcpu);
+	int sr_idx;
 
 	trace_kvm_handle_sys_reg(esr);
 
-	if (__check_nv_sr_forward(vcpu))
+	if (__check_nv_sr_forward(vcpu, &sr_idx))
 		return 1;
 
 	params = esr_sys64_to_params(esr);
 	params.regval = vcpu_get_reg(vcpu, Rt);
 
 	/* System registers have Op0=={2,3}, as per DDI487 J.a C5.1.2 */
-	if (params.Op0 == 2 || params.Op0 == 3) {
-		if (!emulate_sys_reg(vcpu, &params))
-			return 1;
+	if (params.Op0 == 2 || params.Op0 == 3)
+		desc = &sys_reg_descs[sr_idx];
+	else
+		desc = &sys_insn_descs[sr_idx];
 
-		if (!params.is_write)
-			vcpu_set_reg(vcpu, Rt, params.regval);
+	perform_access(vcpu, &params, desc);
 
-		return 1;
-	}
+	/* Read from system register? */
+	if (!params.is_write &&
+	    (params.Op0 == 2 || params.Op0 == 3))
+		vcpu_set_reg(vcpu, Rt, params.regval);
 
-	/* Hints, PSTATE (Op0 == 0) and System instructions (Op0 == 1) */
-	return emulate_sys_instr(vcpu, &params);
+	return 1;
 }
 
 /******************************************************************************
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:11 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:11 +0000
Subject: [PATCH v4 10/26] KVM: arm64: nv: Turn encoding ranges into discrete XArray stores
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-11-maz@kernel.org>

In order to be able to store different values for member of an
encoding range, replace xa_store_range() calls with discrete
xa_store() calls and an encoding iterator.

We end-up using a bit more memory, but we gain some flexibility
that we will make use of shortly.

Take this opportunity to tidy up the error handling path.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/kvm/emulate-nested.c | 49 ++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index ef46c2e45307..42f5b4483c80 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1757,6 +1757,28 @@ static __init void print_nv_trap_error(const struct encoding_to_trap_config *tc,
 		err);
 }
 
+static u32 encoding_next(u32 encoding)
+{
+	u8 op0, op1, crn, crm, op2;
+
+	op0 = sys_reg_Op0(encoding);
+	op1 = sys_reg_Op1(encoding);
+	crn = sys_reg_CRn(encoding);
+	crm = sys_reg_CRm(encoding);
+	op2 = sys_reg_Op2(encoding);
+
+	if (op2 < Op2_mask)
+		return sys_reg(op0, op1, crn, crm, op2 + 1);
+	if (crm < CRm_mask)
+		return sys_reg(op0, op1, crn, crm + 1, 0);
+	if (crn < CRn_mask)
+		return sys_reg(op0, op1, crn + 1, 0, 0);
+	if (op1 < Op1_mask)
+		return sys_reg(op0, op1 + 1, 0, 0, 0);
+
+	return sys_reg(op0 + 1, 0, 0, 0, 0);
+}
+
 int __init populate_nv_trap_config(void)
 {
 	int ret = 0;
@@ -1775,23 +1797,18 @@ int __init populate_nv_trap_config(void)
 			ret = -EINVAL;
 		}
 
-		if (cgt->encoding != cgt->end) {
-			prev = xa_store_range(&sr_forward_xa,
-					      cgt->encoding, cgt->end,
-					      xa_mk_value(cgt->tc.val),
-					      GFP_KERNEL);
-		} else {
-			prev = xa_store(&sr_forward_xa, cgt->encoding,
+		for (u32 enc = cgt->encoding; enc <= cgt->end; enc = encoding_next(enc)) {
+			prev = xa_store(&sr_forward_xa, enc,
 					xa_mk_value(cgt->tc.val), GFP_KERNEL);
 			if (prev && !xa_is_err(prev)) {
 				ret = -EINVAL;
 				print_nv_trap_error(cgt, "Duplicate CGT", ret);
 			}
-		}
 
-		if (xa_is_err(prev)) {
-			ret = xa_err(prev);
-			print_nv_trap_error(cgt, "Failed CGT insertion", ret);
+			if (xa_is_err(prev)) {
+				ret = xa_err(prev);
+				print_nv_trap_error(cgt, "Failed CGT insertion", ret);
+			}
 		}
 	}
 
@@ -1804,6 +1821,7 @@ int __init populate_nv_trap_config(void)
 	for (int i = 0; i < ARRAY_SIZE(encoding_to_fgt); i++) {
 		const struct encoding_to_trap_config *fgt = &encoding_to_fgt[i];
 		union trap_config tc;
+		void *prev;
 
 		if (fgt->tc.fgt >= __NR_FGT_GROUP_IDS__) {
 			ret = -EINVAL;
@@ -1818,8 +1836,13 @@ int __init populate_nv_trap_config(void)
 		}
 
 		tc.val |= fgt->tc.val;
-		xa_store(&sr_forward_xa, fgt->encoding,
-			 xa_mk_value(tc.val), GFP_KERNEL);
+		prev = xa_store(&sr_forward_xa, fgt->encoding,
+				xa_mk_value(tc.val), GFP_KERNEL);
+
+		if (xa_is_err(prev)) {
+			ret = xa_err(prev);
+			print_nv_trap_error(fgt, "Failed FGT insertion", ret);
+		}
 	}
 
 	kvm_info("nv: %ld fine grained trap handlers\n",
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:22 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:22 +0000
Subject: [PATCH v4 21/26] KVM: arm64: Make TLBI OS/Range UNDEF if not advertised to the guest
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-22-maz@kernel.org>

Outer Shareable and Range TLBI instructions shouldn't be made available
to the guest if they are not advertised. Use FGU to disable those,
and set HCR_EL2.TLBIOS in the case the host doesn't have FGT. Note
that in that later case, we cannot efficiently disable TLBI Range
instructions, as this would require to trap all TLBIs.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/kvm/sys_regs.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 39e7c7f74717..f07ee7c89822 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3948,6 +3948,14 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
 
 	mutex_lock(&kvm->arch.config_lock);
 
+	/*
+	 * In the absence of FGT, we cannot independently trap TLBI
+	 * Range instructions. This isn't great, but trapping all
+	 * TLBIs would be far worse. Live with it...
+	 */
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+		vcpu->arch.hcr_el2 |= HCR_TTLBOS;
+
 	if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags))
 		goto out;
 
@@ -3960,6 +3968,32 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
 				       HFGxTR_EL2_nSMPRI_EL1_MASK	|
 				       HFGxTR_EL2_nTPIDR2_EL0_MASK);
 
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+		kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1OS|
+						HFGITR_EL2_TLBIRVALE1OS	|
+						HFGITR_EL2_TLBIRVAAE1OS	|
+						HFGITR_EL2_TLBIRVAE1OS	|
+						HFGITR_EL2_TLBIVAALE1OS	|
+						HFGITR_EL2_TLBIVALE1OS	|
+						HFGITR_EL2_TLBIVAAE1OS	|
+						HFGITR_EL2_TLBIASIDE1OS	|
+						HFGITR_EL2_TLBIVAE1OS	|
+						HFGITR_EL2_TLBIVMALLE1OS);
+
+	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
+		kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1	|
+						HFGITR_EL2_TLBIRVALE1	|
+						HFGITR_EL2_TLBIRVAAE1	|
+						HFGITR_EL2_TLBIRVAE1	|
+						HFGITR_EL2_TLBIRVAALE1IS|
+						HFGITR_EL2_TLBIRVALE1IS	|
+						HFGITR_EL2_TLBIRVAAE1IS	|
+						HFGITR_EL2_TLBIRVAE1IS	|
+						HFGITR_EL2_TLBIRVAALE1OS|
+						HFGITR_EL2_TLBIRVALE1OS	|
+						HFGITR_EL2_TLBIRVAAE1OS	|
+						HFGITR_EL2_TLBIRVAE1OS);
+
 	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
 out:
 	mutex_unlock(&kvm->arch.config_lock);
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:23 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:23 +0000
Subject: [PATCH v4 22/26] KVM: arm64: Make PIR{,E0}_EL1 UNDEF if S1PIE is not advertised to the guest
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-23-maz@kernel.org>

As part of the ongoing effort to honor the guest configuration,
add the necessary checks to make PIR_EL1 and co UNDEF if not
advertised to the guest, and avoid context switching them.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 24 +++++++++++++++++++---
 arch/arm64/kvm/sys_regs.c                  |  4 ++++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index bb6b571ec627..4be6a7fa0070 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -27,16 +27,34 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt)
 	ctxt_sys_reg(ctxt, TPIDRRO_EL0)	= read_sysreg(tpidrro_el0);
 }
 
-static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt)
+static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt)
 {
 	struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu;
 
 	if (!vcpu)
 		vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt);
 
+	return vcpu;
+}
+
+static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt)
+{
+	struct kvm_vcpu *vcpu = ctxt_to_vcpu(ctxt);
+
 	return kvm_has_mte(kern_hyp_va(vcpu->kvm));
 }
 
+static inline bool ctxt_has_s1pie(struct kvm_cpu_context *ctxt)
+{
+	struct kvm_vcpu *vcpu;
+
+	if (!cpus_have_final_cap(ARM64_HAS_S1PIE))
+		return false;
+
+	vcpu = ctxt_to_vcpu(ctxt);
+	return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, S1PIE, IMP);
+}
+
 static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
 {
 	ctxt_sys_reg(ctxt, SCTLR_EL1)	= read_sysreg_el1(SYS_SCTLR);
@@ -55,7 +73,7 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
 	ctxt_sys_reg(ctxt, CONTEXTIDR_EL1) = read_sysreg_el1(SYS_CONTEXTIDR);
 	ctxt_sys_reg(ctxt, AMAIR_EL1)	= read_sysreg_el1(SYS_AMAIR);
 	ctxt_sys_reg(ctxt, CNTKCTL_EL1)	= read_sysreg_el1(SYS_CNTKCTL);
-	if (cpus_have_final_cap(ARM64_HAS_S1PIE)) {
+	if (ctxt_has_s1pie(ctxt)) {
 		ctxt_sys_reg(ctxt, PIR_EL1)	= read_sysreg_el1(SYS_PIR);
 		ctxt_sys_reg(ctxt, PIRE0_EL1)	= read_sysreg_el1(SYS_PIRE0);
 	}
@@ -131,7 +149,7 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
 	write_sysreg_el1(ctxt_sys_reg(ctxt, CONTEXTIDR_EL1), SYS_CONTEXTIDR);
 	write_sysreg_el1(ctxt_sys_reg(ctxt, AMAIR_EL1),	SYS_AMAIR);
 	write_sysreg_el1(ctxt_sys_reg(ctxt, CNTKCTL_EL1), SYS_CNTKCTL);
-	if (cpus_have_final_cap(ARM64_HAS_S1PIE)) {
+	if (ctxt_has_s1pie(ctxt)) {
 		write_sysreg_el1(ctxt_sys_reg(ctxt, PIR_EL1),	SYS_PIR);
 		write_sysreg_el1(ctxt_sys_reg(ctxt, PIRE0_EL1),	SYS_PIRE0);
 	}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index f07ee7c89822..da9db99c77e7 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3994,6 +3994,10 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
 						HFGITR_EL2_TLBIRVAAE1OS	|
 						HFGITR_EL2_TLBIRVAE1OS);
 
+	if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
+		kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 |
+						HFGxTR_EL2_nPIR_EL1);
+
 	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
 out:
 	mutex_unlock(&kvm->arch.config_lock);
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:27 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:27 +0000
Subject: [PATCH v4 26/26] KVM: arm64: Add debugfs file for guest's ID registers
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-27-maz@kernel.org>

Debugging ID register setup can be a complicated affair. Give the
kernel hacker a way to dump that state in an easy to parse way.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  3 ++
 arch/arm64/kvm/sys_regs.c         | 81 +++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 3feabde9c926..181fef12e8e8 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -319,6 +319,9 @@ struct kvm_arch {
 	/* PMCR_EL0.N value for the guest */
 	u8 pmcr_n;
 
+	/* Iterator for idreg debugfs */
+	u8	idreg_debugfs_iter;
+
 	/* Hypercall features firmware registers' descriptor */
 	struct kvm_smccc_features smccc_feat;
 	struct maple_tree smccc_filter;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index b5335e5a6e6e..e3faedc8b7a3 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -12,6 +12,7 @@
 #include <linux/bitfield.h>
 #include <linux/bsearch.h>
 #include <linux/cacheinfo.h>
+#include <linux/debugfs.h>
 #include <linux/kvm_host.h>
 #include <linux/mm.h>
 #include <linux/printk.h>
@@ -3422,6 +3423,81 @@ static bool emulate_sys_reg(struct kvm_vcpu *vcpu,
 	return false;
 }
 
+static void *idregs_debug_start(struct seq_file *s, loff_t *pos)
+{
+	struct kvm *kvm = s->private;
+	u8 *iter;
+
+	mutex_lock(&kvm->arch.config_lock);
+
+	iter = &kvm->arch.idreg_debugfs_iter;
+	if (*iter == (u8)~0) {
+		*iter = *pos;
+		if (*iter >= KVM_ARM_ID_REG_NUM)
+			iter = NULL;
+	} else {
+		iter = ERR_PTR(-EBUSY);
+	}
+
+	mutex_unlock(&kvm->arch.config_lock);
+
+	return iter;
+}
+
+static void *idregs_debug_next(struct seq_file *s, void *v, loff_t *pos)
+{
+	struct kvm *kvm = s->private;
+
+	(*pos)++;
+
+	if ((kvm->arch.idreg_debugfs_iter + 1) < KVM_ARM_ID_REG_NUM) {
+		kvm->arch.idreg_debugfs_iter++;
+
+		return &kvm->arch.idreg_debugfs_iter;
+	}
+
+	return NULL;
+}
+
+static void idregs_debug_stop(struct seq_file *s, void *v)
+{
+	struct kvm *kvm = s->private;
+
+	if (IS_ERR(v))
+		return;
+
+	mutex_lock(&kvm->arch.config_lock);
+
+	kvm->arch.idreg_debugfs_iter = ~0;
+
+	mutex_unlock(&kvm->arch.config_lock);
+}
+
+static int idregs_debug_show(struct seq_file *s, void *v)
+{
+	struct kvm *kvm = s->private;
+	const struct sys_reg_desc *desc;
+
+	desc = first_idreg + kvm->arch.idreg_debugfs_iter;
+
+	if (!desc->name)
+		return 0;
+
+	seq_printf(s, "%20s:\t%016llx\n",
+		   desc->name, IDREG(kvm, IDX_IDREG(kvm->arch.idreg_debugfs_iter)));
+
+	return 0;
+}
+
+static const struct seq_operations idregs_debug_sops = {
+	.start	= idregs_debug_start,
+	.next	= idregs_debug_next,
+	.stop	= idregs_debug_stop,
+	.show	= idregs_debug_show,
+};
+
+DEFINE_SEQ_ATTRIBUTE(idregs_debug);
+
 static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
 {
 	const struct sys_reg_desc *idreg = first_idreg;
@@ -3441,6 +3517,11 @@ static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
 		id = reg_to_encoding(idreg);
 	}
 
+	kvm->arch.idreg_debugfs_iter = ~0;
+
+	debugfs_create_file("idregs", 0444, kvm->debugfs_dentry, kvm,
+			    &idregs_debug_fops);
+
 	set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags);
 }
 
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:24 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:24 +0000
Subject: [PATCH v4 23/26] KVM: arm64: Make AMU sysreg UNDEF if FEAT_AMU is not advertised to the guest
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-24-maz@kernel.org>

No AMU? No AMU! IF we see an AMU-related trap, let's turn it into
an UNDEF!

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index da9db99c77e7..38ed47bd29db 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3998,6 +3998,10 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
 		kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 |
 						HFGxTR_EL2_nPIR_EL1);
 
+	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
+		kvm->arch.fgu[HAFGRTR_GROUP] |= ~(HAFGRTR_EL2_RES0 |
+						  HAFGRTR_EL2_RES1);
+
 	set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
 out:
 	mutex_unlock(&kvm->arch.config_lock);
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:25 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:25 +0000
Subject: [PATCH v4 24/26] KVM: arm64: Make FEAT_MOPS UNDEF if not advertised to the guest
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-25-maz@kernel.org>

We unconditionally enable FEAT_MOPS, which is obviously wrong.

So let's only do that when it is advertised to the guest.
Which means we need to rely on a per-vcpu HCRX_EL2 shadow register.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
---
 arch/arm64/include/asm/kvm_arm.h        | 4 +---
 arch/arm64/include/asm/kvm_host.h       | 1 +
 arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +-
 arch/arm64/kvm/sys_regs.c               | 7 +++++++
 4 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3c6f8ba1e479..a1769e415d72 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -102,9 +102,7 @@
 #define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
 #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
 
-#define HCRX_GUEST_FLAGS \
-	(HCRX_EL2_SMPME | HCRX_EL2_TCR2En | \
-	 (cpus_have_final_cap(ARM64_HAS_MOPS) ? (HCRX_EL2_MSCEn | HCRX_EL2_MCE2) : 0))
+#define HCRX_GUEST_FLAGS (HCRX_EL2_SMPME | HCRX_EL2_TCR2En)
 #define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En)
 
 /* TCR_EL2 Registers bits */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 968a997b3f02..3feabde9c926 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -584,6 +584,7 @@ struct kvm_vcpu_arch {
 
 	/* Values of trap registers for the guest. */
 	u64 hcr_el2;
+	u64 hcrx_el2;
 	u64 mdcr_el2;
 	u64 cptr_el2;
 
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 2d5891518006..e3fcf8c4d5b4 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -236,7 +236,7 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
 	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
 
 	if (cpus_have_final_cap(ARM64_HAS_HCX)) {
-		u64 hcrx = HCRX_GUEST_FLAGS;
+		u64 hcrx = vcpu->arch.hcrx_el2;
 		if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
 			u64 clr = 0, set = 0;
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 38ed47bd29db..2cb69efac1dc 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3956,6 +3956,13 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu)
 	if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
 		vcpu->arch.hcr_el2 |= HCR_TTLBOS;
 
+	if (cpus_have_final_cap(ARM64_HAS_HCX)) {
+		vcpu->arch.hcrx_el2 = HCRX_GUEST_FLAGS;
+
+		if (kvm_has_feat(kvm, ID_AA64ISAR2_EL1, MOPS, IMP))
+			vcpu->arch.hcrx_el2 |= (HCRX_EL2_MSCEn | HCRX_EL2_MCE2);
+	}
+
 	if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags))
 		goto out;
 
-- 
2.39.2



From maz at kernel.org  Wed Feb 14 05:18:26 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 13:18:26 +0000
Subject: [PATCH v4 25/26] KVM: arm64: Snapshot all non-zero RES0/RES1 sysreg fields for later checking
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <20240214131827.2856277-26-maz@kernel.org>

As KVM now strongly relies on accurately handling the RES0/RES1 bits
on a number of paths, add a compile-time checker that will blow in
the face of the innocent bystander, should they try to sneak in an
update that changes any of these RES0/RES1 fields.

It is expected that such an update will come with the relevant
KVM update if needed.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/check-res-bits.h | 121 ++++++++++++++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c       |   3 +
 2 files changed, 124 insertions(+)
 create mode 100644 arch/arm64/kvm/check-res-bits.h

diff --git a/arch/arm64/kvm/check-res-bits.h b/arch/arm64/kvm/check-res-bits.h
new file mode 100644
index 000000000000..967b5d171d53
--- /dev/null
+++ b/arch/arm64/kvm/check-res-bits.h
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 - Google LLC
+ * Author: Marc Zyngier <maz at kernel.org>
+ */
+
+#include <asm/sysreg-defs.h>
+
+/*
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * If any of these BUILD_BUG_ON() fails, that's because some bits that
+ * were reserved have gained some other meaning, and KVM needs to know
+ * about those.
+ *
+ * In such case, do *NOT* blindly change the assertion so that it
+ * passes, but also teach the rest of the code about the actual
+ * change.
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+static inline void check_res_bits(void)
+{
+	BUILD_BUG_ON(OSDTRRX_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(MDCCINT_EL1_RES0		!= (GENMASK_ULL(63, 31) | GENMASK_ULL(28, 0)));
+	BUILD_BUG_ON(MDSCR_EL1_RES0		!= (GENMASK_ULL(63, 36) | GENMASK_ULL(28, 28) | GENMASK_ULL(25, 24) | GENMASK_ULL(20, 20) | GENMASK_ULL(18, 16) | GENMASK_ULL(11, 7) | GENMASK_ULL(5, 1)));
+	BUILD_BUG_ON(OSDTRTX_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(OSECCR_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(OSLAR_EL1_RES0		!= (GENMASK_ULL(63, 1)));
+	BUILD_BUG_ON(ID_PFR0_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_PFR1_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_DFR0_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_AFR0_EL1_RES0		!= (GENMASK_ULL(63, 16)));
+	BUILD_BUG_ON(ID_MMFR0_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_MMFR1_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_MMFR2_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_MMFR3_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_ISAR0_EL1_RES0		!= (GENMASK_ULL(63, 28)));
+	BUILD_BUG_ON(ID_ISAR1_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_ISAR2_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_ISAR3_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_ISAR4_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_ISAR5_EL1_RES0		!= (GENMASK_ULL(63, 32) | GENMASK_ULL(23, 20)));
+	BUILD_BUG_ON(ID_ISAR6_EL1_RES0		!= (GENMASK_ULL(63, 28)));
+	BUILD_BUG_ON(ID_MMFR4_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(MVFR0_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(MVFR1_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(MVFR2_EL1_RES0		!= (GENMASK_ULL(63, 8)));
+	BUILD_BUG_ON(ID_PFR2_EL1_RES0		!= (GENMASK_ULL(63, 12)));
+	BUILD_BUG_ON(ID_DFR1_EL1_RES0		!= (GENMASK_ULL(63, 8)));
+	BUILD_BUG_ON(ID_MMFR5_EL1_RES0		!= (GENMASK_ULL(63, 8)));
+	BUILD_BUG_ON(ID_AA64PFR1_EL1_RES0	!= (GENMASK_ULL(23, 20)));
+	BUILD_BUG_ON(ID_AA64PFR2_EL1_RES0	!= (GENMASK_ULL(63, 36) | GENMASK_ULL(31, 12)));
+	BUILD_BUG_ON(ID_AA64ZFR0_EL1_RES0	!= (GENMASK_ULL(63, 60) | GENMASK_ULL(51, 48) | GENMASK_ULL(39, 36) | GENMASK_ULL(31, 28) | GENMASK_ULL(15, 8)));
+	BUILD_BUG_ON(ID_AA64SMFR0_EL1_RES0	!= (GENMASK_ULL(62, 61) | GENMASK_ULL(51, 49) | GENMASK_ULL(31, 31) | GENMASK_ULL(27, 0)));
+	BUILD_BUG_ON(ID_AA64FPFR0_EL1_RES0	!= (GENMASK_ULL(63, 32) | GENMASK_ULL(27, 2)));
+	BUILD_BUG_ON(ID_AA64DFR0_EL1_RES0	!= (GENMASK_ULL(27, 24) | GENMASK_ULL(19, 16)));
+	BUILD_BUG_ON(ID_AA64DFR1_EL1_RES0	!= (GENMASK_ULL(63, 0)));
+	BUILD_BUG_ON(ID_AA64AFR0_EL1_RES0	!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(ID_AA64AFR1_EL1_RES0	!= (GENMASK_ULL(63, 0)));
+	BUILD_BUG_ON(ID_AA64ISAR0_EL1_RES0	!= (GENMASK_ULL(3, 0)));
+	BUILD_BUG_ON(ID_AA64ISAR2_EL1_RES0	!= (GENMASK_ULL(47, 44)));
+	BUILD_BUG_ON(ID_AA64ISAR3_EL1_RES0	!= (GENMASK_ULL(63, 16)));
+	BUILD_BUG_ON(ID_AA64MMFR0_EL1_RES0	!= (GENMASK_ULL(55, 48)));
+	BUILD_BUG_ON(ID_AA64MMFR2_EL1_RES0	!= (GENMASK_ULL(47, 44)));
+	BUILD_BUG_ON(ID_AA64MMFR3_EL1_RES0	!= (GENMASK_ULL(51, 48)));
+	BUILD_BUG_ON(ID_AA64MMFR4_EL1_RES0	!= (GENMASK_ULL(63, 40) | GENMASK_ULL(35, 28) | GENMASK_ULL(3, 0)));
+	BUILD_BUG_ON(SCTLR_EL1_RES0		!= (GENMASK_ULL(17, 17)));
+	BUILD_BUG_ON(CPACR_ELx_RES0		!= (GENMASK_ULL(63, 30) | GENMASK_ULL(27, 26) | GENMASK_ULL(23, 22) | GENMASK_ULL(19, 18) | GENMASK_ULL(15, 0)));
+	BUILD_BUG_ON(SMPRI_EL1_RES0		!= (GENMASK_ULL(63, 4)));
+	BUILD_BUG_ON(ZCR_ELx_RES0		!= (GENMASK_ULL(63, 9)));
+	BUILD_BUG_ON(SMCR_ELx_RES0		!= (GENMASK_ULL(63, 32) | GENMASK_ULL(29, 9)));
+	BUILD_BUG_ON(GCSCR_ELx_RES0		!= (GENMASK_ULL(63, 10) | GENMASK_ULL(7, 7) | GENMASK_ULL(4, 1)));
+	BUILD_BUG_ON(GCSPR_ELx_RES0		!= (GENMASK_ULL(2, 0)));
+	BUILD_BUG_ON(GCSCRE0_EL1_RES0		!= (GENMASK_ULL(63, 11) | GENMASK_ULL(7, 6) | GENMASK_ULL(4, 1)));
+	BUILD_BUG_ON(ALLINT_RES0		!= (GENMASK_ULL(63, 14) | GENMASK_ULL(12, 0)));
+	BUILD_BUG_ON(PMSCR_EL1_RES0		!= (GENMASK_ULL(63, 8) | GENMASK_ULL(2, 2)));
+	BUILD_BUG_ON(PMSICR_EL1_RES0		!= (GENMASK_ULL(55, 32)));
+	BUILD_BUG_ON(PMSIRR_EL1_RES0		!= (GENMASK_ULL(63, 32) | GENMASK_ULL(7, 1)));
+	BUILD_BUG_ON(PMSFCR_EL1_RES0		!= (GENMASK_ULL(63, 19) | GENMASK_ULL(15, 4)));
+	BUILD_BUG_ON(PMSLATFR_EL1_RES0		!= (GENMASK_ULL(63, 16)));
+	BUILD_BUG_ON(PMSIDR_EL1_RES0		!= (GENMASK_ULL(63, 25) | GENMASK_ULL(7, 7)));
+	BUILD_BUG_ON(PMBLIMITR_EL1_RES0		!= (GENMASK_ULL(11, 6) | GENMASK_ULL(4, 3)));
+	BUILD_BUG_ON(PMBSR_EL1_RES0		!= (GENMASK_ULL(63, 32) | GENMASK_ULL(25, 20)));
+	BUILD_BUG_ON(PMBIDR_EL1_RES0		!= (GENMASK_ULL(63, 12) | GENMASK_ULL(7, 6)));
+	BUILD_BUG_ON(CONTEXTIDR_ELx_RES0	!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(CCSIDR_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(CLIDR_EL1_RES0		!= (GENMASK_ULL(63, 47)));
+	BUILD_BUG_ON(CCSIDR2_EL1_RES0		!= (GENMASK_ULL(63, 24)));
+	BUILD_BUG_ON(GMID_EL1_RES0		!= (GENMASK_ULL(63, 4)));
+	BUILD_BUG_ON(SMIDR_EL1_RES0		!= (GENMASK_ULL(63, 32) | GENMASK_ULL(14, 12)));
+	BUILD_BUG_ON(CSSELR_EL1_RES0		!= (GENMASK_ULL(63, 5)));
+	BUILD_BUG_ON(CTR_EL0_RES0		!= (GENMASK_ULL(63, 38) | GENMASK_ULL(30, 30) | GENMASK_ULL(13, 4)));
+	BUILD_BUG_ON(CTR_EL0_RES1       	!= (GENMASK_ULL(31, 31)));
+	BUILD_BUG_ON(DCZID_EL0_RES0		!= (GENMASK_ULL(63, 5)));
+	BUILD_BUG_ON(SVCR_RES0			!= (GENMASK_ULL(63, 2)));
+	BUILD_BUG_ON(FPMR_RES0			!= (GENMASK_ULL(63, 38) | GENMASK_ULL(23, 23) | GENMASK_ULL(13, 9)));
+	BUILD_BUG_ON(HFGxTR_EL2_RES0		!= (GENMASK_ULL(51, 51)));
+	BUILD_BUG_ON(HFGITR_EL2_RES0		!= (GENMASK_ULL(63, 63) | GENMASK_ULL(61, 61)));
+	BUILD_BUG_ON(HDFGRTR_EL2_RES0		!= (GENMASK_ULL(49, 49) | GENMASK_ULL(42, 42) | GENMASK_ULL(39, 38) | GENMASK_ULL(21, 20) | GENMASK_ULL(8, 8)));
+	BUILD_BUG_ON(HDFGWTR_EL2_RES0		!= (GENMASK_ULL(63, 63) | GENMASK_ULL(59, 58) | GENMASK_ULL(51, 51) | GENMASK_ULL(47, 47) | GENMASK_ULL(43, 43) | GENMASK_ULL(40, 38) | GENMASK_ULL(34, 34) | GENMASK_ULL(30, 30) | GENMASK_ULL(22, 22) | GENMASK_ULL(9, 9) | GENMASK_ULL(6, 6)));
+	BUILD_BUG_ON(HAFGRTR_EL2_RES0		!= (GENMASK_ULL(63, 50) | GENMASK_ULL(16, 5)));
+	BUILD_BUG_ON(HCRX_EL2_RES0		!= (GENMASK_ULL(63, 25) | GENMASK_ULL(13, 12)));
+	BUILD_BUG_ON(DACR32_EL2_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(PMSCR_EL2_RES0		!= (GENMASK_ULL(63, 8) | GENMASK_ULL(2, 2)));
+	BUILD_BUG_ON(TCR2_EL1x_RES0		!= (GENMASK_ULL(63, 16) | GENMASK_ULL(13, 12) | GENMASK_ULL(9, 6)));
+	BUILD_BUG_ON(TCR2_EL2_RES0		!= (GENMASK_ULL(63, 16)));
+	BUILD_BUG_ON(LORSA_EL1_RES0		!= (GENMASK_ULL(63, 52) | GENMASK_ULL(15, 1)));
+	BUILD_BUG_ON(LOREA_EL1_RES0		!= (GENMASK_ULL(63, 52) | GENMASK_ULL(15, 0)));
+	BUILD_BUG_ON(LORN_EL1_RES0		!= (GENMASK_ULL(63, 8)));
+	BUILD_BUG_ON(LORC_EL1_RES0		!= (GENMASK_ULL(63, 10) | GENMASK_ULL(1, 1)));
+	BUILD_BUG_ON(LORID_EL1_RES0		!= (GENMASK_ULL(63, 24) | GENMASK_ULL(15, 8)));
+	BUILD_BUG_ON(ISR_EL1_RES0		!= (GENMASK_ULL(63, 11) | GENMASK_ULL(5, 0)));
+	BUILD_BUG_ON(ICC_NMIAR1_EL1_RES0	!= (GENMASK_ULL(63, 24)));
+	BUILD_BUG_ON(TRBLIMITR_EL1_RES0		!= (GENMASK_ULL(11, 7)));
+	BUILD_BUG_ON(TRBBASER_EL1_RES0		!= (GENMASK_ULL(11, 0)));
+	BUILD_BUG_ON(TRBSR_EL1_RES0		!= (GENMASK_ULL(63, 56) | GENMASK_ULL(25, 24) | GENMASK_ULL(19, 19) | GENMASK_ULL(16, 16)));
+	BUILD_BUG_ON(TRBMAR_EL1_RES0		!= (GENMASK_ULL(63, 12)));
+	BUILD_BUG_ON(TRBTRG_EL1_RES0		!= (GENMASK_ULL(63, 32)));
+	BUILD_BUG_ON(TRBIDR_EL1_RES0		!= (GENMASK_ULL(63, 12) | GENMASK_ULL(7, 6)));
+}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 2cb69efac1dc..b5335e5a6e6e 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -31,6 +31,7 @@
 
 #include <trace/events/kvm.h>
 
+#include "check-res-bits.h"
 #include "sys_regs.h"
 
 #include "trace.h"
@@ -4021,6 +4022,8 @@ int __init kvm_sys_reg_table_init(void)
 	unsigned int i;
 	int ret = 0;
 
+	check_res_bits();
+
 	/* Make sure tables are unique and in order. */
 	valid &= check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs), false);
 	valid &= check_sysreg_table(cp14_regs, ARRAY_SIZE(cp14_regs), true);
-- 
2.39.2



From geert+renesas at glider.be  Wed Feb 14 05:19:27 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 14:19:27 +0100
Subject: [PATCH] arm64: dts: renesas: r8a779h0: Add DMA support
Message-ID: <44de886cd83f41659d2f6962c0e277f548fb0adb.1707916707.git.geert+renesas@glider.be>

Add device nodes for the Direct Memory Access Controllers for System
(SYS-DMAC) on the Renesas R-Car V4M (R8A779H0) SoC.

Link all DMA consumers to the corresponding DMA controller channels.

Based on patches in the BSP by Thanh Le and Minh Le.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
To be queued in renesas-devel for v6.9.

HSCIF0 DMA tested by removing the uart_console() check from
sci_request_dma().
I2C0 DMA tested by removing the I2C_M_DMA_SAFE check from rcar_i2c_dma()
(the AT24 EEPROM driver uses regmap, thus can't set I2C_M_DMA_SAFE).

Changes compared to the BSP:
  - Mix and match multiple patches,
  - Add missing "renesas,rcar-gen4-dmac" compatible fallbacks,
  - Add HSCIF0 DMA.
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 75 +++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index d50ed1989ef52da7..46c586f4e326959f 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -326,6 +326,9 @@ i2c0: i2c at e6500000 {
 			clocks = <&cpg CPG_MOD 518>;
 			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
 			resets = <&cpg 518>;
+			dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+			       <&dmac2 0x91>, <&dmac2 0x90>;
+			dma-names = "tx", "rx", "tx", "rx";
 			i2c-scl-internal-delay-ns = <110>;
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -340,6 +343,9 @@ i2c1: i2c at e6508000 {
 			clocks = <&cpg CPG_MOD 519>;
 			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
 			resets = <&cpg 519>;
+			dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+			       <&dmac2 0x93>, <&dmac2 0x92>;
+			dma-names = "tx", "rx", "tx", "rx";
 			i2c-scl-internal-delay-ns = <110>;
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -354,6 +360,9 @@ i2c2: i2c at e6510000 {
 			clocks = <&cpg CPG_MOD 520>;
 			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
 			resets = <&cpg 520>;
+			dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+			       <&dmac2 0x95>, <&dmac2 0x94>;
+			dma-names = "tx", "rx", "tx", "rx";
 			i2c-scl-internal-delay-ns = <110>;
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -368,6 +377,9 @@ i2c3: i2c at e66d0000 {
 			clocks = <&cpg CPG_MOD 521>;
 			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
 			resets = <&cpg 521>;
+			dmas = <&dmac1 0x97>, <&dmac1 0x96>,
+			       <&dmac2 0x97>, <&dmac2 0x96>;
+			dma-names = "tx", "rx", "tx", "rx";
 			i2c-scl-internal-delay-ns = <110>;
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -385,6 +397,9 @@ hscif0: serial at e6540000 {
 			clock-names = "fck", "brg_int", "scif_clk";
 			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
 			resets = <&cpg 514>;
+			dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+			       <&dmac2 0x31>, <&dmac2 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
 			status = "disabled";
 		};
 
@@ -532,6 +547,66 @@ avb2: ethernet at e6820000 {
 			status = "disabled";
 		};
 
+		dmac1: dma-controller at e7350000 {
+			compatible = "renesas,dmac-r8a779h0",
+				     "renesas,rcar-gen4-dmac";
+			reg = <0 0xe7350000 0 0x1000>,
+			      <0 0xe7300000 0 0x10000>;
+			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3", "ch4",
+					  "ch5", "ch6", "ch7", "ch8", "ch9",
+					  "ch10", "ch11", "ch12", "ch13",
+					  "ch14", "ch15";
+			clocks = <&cpg CPG_MOD 709>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 709>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+		};
+
+		dmac2: dma-controller at e7351000 {
+			compatible = "renesas,dmac-r8a779h0",
+				     "renesas,rcar-gen4-dmac";
+			reg = <0 0xe7351000 0 0x1000>,
+			      <0 0xe7310000 0 0x10000>;
+			interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					  "ch0", "ch1", "ch2", "ch3", "ch4",
+					  "ch5", "ch6", "ch7";
+			clocks = <&cpg CPG_MOD 710>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 710>;
+			#dma-cells = <1>;
+			dma-channels = <8>;
+		};
+
 		mmc0: mmc at ee140000 {
 			compatible = "renesas,sdhi-r8a779h0",
 				     "renesas,rcar-gen4-sdhi";
-- 
2.34.1



From broonie at kernel.org  Wed Feb 14 05:22:04 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 14 Feb 2024 13:22:04 +0000
Subject: [PATCH v2 0/2] ASoC: meson: aiu: fix function pointer type
 mismatch
In-Reply-To: <20240213215807.3326688-1-jbrunet@baylibre.com>
References: <20240213215807.3326688-1-jbrunet@baylibre.com>
Message-ID: <170791692451.143237.6316282376548391909.b4-ty@kernel.org>

On Tue, 13 Feb 2024 22:58:02 +0100, Jerome Brunet wrote:
> This patchset fixes 2 -Wcast-function-type-strict warning in amlogic
> audio drivers with clang 16.
> 
> Changes since v1: [0]
> * use devm_clk_get_enabled() instead of adding a dedicated helper in each
>   driver.
> * Split the patch, 1 per fixed commit to make it easier for stable.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/2] ASoC: meson: aiu: fix function pointer type mismatch
      commit: 98ac85a00f31d2e9d5452b825a9ed0153d934043
[2/2] ASoC: meson: t9015: fix function pointer type mismatch
      commit: 5ad992c71b6a8e8a547954addc7af9fbde6ca10a

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 geert at linux-m68k.org  Wed Feb 14 05:24:29 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 14:24:29 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: gray-hawk-single: Add Ethernet support
In-Reply-To: <b83b21b6477a0e31f99eaedbd36c03014b72ec8a.1707661382.git.geert+renesas@glider.be>
References: <cover.1707661382.git.geert+renesas@glider.be> <b83b21b6477a0e31f99eaedbd36c03014b72ec8a.1707661382.git.geert+renesas@glider.be>
Message-ID: <CAMuHMdV=cr9JHuoHR8iO-ZJ6DL+KMAL2bMDZJ-8qN1+6=QD=cg@mail.gmail.com>

On Sun, Feb 11, 2024 at 3:31?PM Geert Uytterhoeven
<geert+renesas at glider.be> wrote:
> From: Thanh Quan <thanh.quan.xn at renesas.com>
>
> Describe the wiring of the first Ethernet AVB instance to the Micrel
> KSZ9031RNXVB PHY.
>
> Signed-off-by: Thanh Quan <thanh.quan.xn at renesas.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
> Changes compared to the BSP:
>   - Split in separate commits for SoC and board support,
>   - Apply to r8a779h0-gray-hawk-single.dts.

> --- a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
> +++ b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts

This lacks the addition of #include <dt-bindings/gpio/gpio.h>,
which is needed for the use of GPIO_* flags below.

> @@ -34,6 +35,24 @@ memory at 480000000 {
>         };
>  };
>
> +&avb0 {
> +       pinctrl-0 = <&avb0_pins>;
> +       pinctrl-names = "default";
> +       phy-handle = <&phy0>;
> +       tx-internal-delay-ps = <2000>;
> +       status = "okay";
> +
> +       phy0: ethernet-phy at 0 {
> +               compatible = "ethernet-phy-id0022.1622",
> +                            "ethernet-phy-ieee802.3-c22";
> +               rxc-skew-ps = <1500>;
> +               reg = <0>;
> +               interrupt-parent = <&gpio7>;
> +               interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
> +               reset-gpios = <&gpio7 10 GPIO_ACTIVE_LOW>;
> +       };
> +};
> +

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 alexandre.torgue at foss.st.com  Wed Feb 14 05:40:58 2024
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Wed, 14 Feb 2024 14:40:58 +0100
Subject: [PATCH 0/5] Add display support for stm32mp135f-dk board
In-Reply-To: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
Message-ID: <0c551a84-5c4a-4d79-ae59-d5b0d34b017d@foss.st.com>

Hi Raphael

On 2/5/24 10:06, Raphael Gallais-Pou wrote:
> This serie aims to enable display support for the stm32mp135f-dk board
> 
> Those are only patches of the device-tree since the driver support has
> already been added [1].
> 
> It respectivelly:
> 	- adds support for the display controller on stm32mp135
> 	- adds pinctrl for the display controller
> 	- enables panel, backlight and display controller on
> 	  stm32mp135f-dk
> 
> Finally it fixes the flags on the panel default mode in the
> 'panel-simple' driver, allowing to override the default mode by one
> described in the device tree, and push further the blanking limit on the
> panel.
> 
> [1] commit 1726cee3d053 ("drm/stm: ltdc: support of new hardware version")
> 
> Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
> ---
> Raphael Gallais-Pou (5):
>        ARM: dts: stm32: add LTDC support for STM32MP13x SoC family
>        ARM: dts: stm32: add LTDC pinctrl on STM32MP13x SoC family
>        ARM: dts: stm32: enable display support on stm32mp135f-dk board
>        drm/panel: simple: fix flags on RK043FN48H
>        drm/panel: simple: push blanking limit on RK32FN48H
> 
>   arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 57 +++++++++++++++++++++++++++++
>   arch/arm/boot/dts/st/stm32mp135.dtsi        | 11 ++++++
>   arch/arm/boot/dts/st/stm32mp135f-dk.dts     | 55 ++++++++++++++++++++++++++++
>   drivers/gpu/drm/panel/panel-simple.c        |  7 ++--
>   4 files changed, 127 insertions(+), 3 deletions(-)
> ---
> base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
> change-id: 20240124-ltdc_mp13-2f86a782424c
> 
> Best regards,

I got the following errors during YAML verification:

arch/arm/boot/dts/st/stm32mp135f-dk.dtb: /soc/i2c at 40012000/pinctrl at 21: 
failed to match any schema with compatible: ['microchip,mcp23017']
/local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb: 
panel-backlight: 'default-brightness-level' does not match any of the 
regexes: 'pinctrl-[0-9]+'
	from schema $id: 
http://devicetree.org/schemas/leds/backlight/gpio-backlight.yaml#
/local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb: 
panel-rgb: data-mapping:0: 'bgr666' is not one of ['jeida-18', 
'jeida-24', 'vesa-24']
	from schema $id: 
http://devicetree.org/schemas/display/panel/panel-simple.yaml#
/local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb: 
panel-rgb: compatible: ['rocktech,rk043fn48h', 'panel-dpi'] is too long
	from schema $id: 
http://devicetree.org/schemas/display/panel/panel-simple.yaml#
/local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb: 
panel-rgb: data-mapping: False schema does not allow ['bgr666']
	from schema $id: 
http://devicetree.org/schemas/display/panel/panel-simple.yaml#
/local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb: 
panel-rgb: 'height-mm', 'panel-timing', 'width-mm' do not match any of 
the regexes: 'pinctrl-[0-9]+'
	from schema $id: 
http://devicetree.org/schemas/display/panel/panel-simple.yaml#
/local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb: 
panel-rgb: 'data-mapping' does not match any of the regexes: 
'pinctrl-[0-9]+'
	from schema $id: 
http://devicetree.org/schemas/display/panel/panel-dpi.yaml#

Do I miss something ?

Alex




From andy at black.fi.intel.com  Wed Feb 14 05:45:16 2024
From: andy at black.fi.intel.com (Andy Shevchenko)
Date: Wed, 14 Feb 2024 15:45:16 +0200
Subject: [PATCH v9 1/4] serial: 8250: Add 8250 port clock update method
In-Reply-To: <20200723003357.26897-2-Sergey.Semin@baikalelectronics.ru>
References: <20200723003357.26897-1-Sergey.Semin@baikalelectronics.ru>
 <20200723003357.26897-2-Sergey.Semin@baikalelectronics.ru>
Message-ID: <ZczD7KPbeRnY4CFc@black.fi.intel.com>

On Thu, Jul 23, 2020 at 03:33:54AM +0300, Serge Semin wrote:
> Some platforms can be designed in a way so the UART port reference clock
> might be asynchronously changed at some point. In Baikal-T1 SoC this may
> happen due to the reference clock being shared between two UART ports, on
> the Allwinner SoC the reference clock is derived from the CPU clock, so
> any CPU frequency change should get to be known/reflected by/in the UART
> controller as well. But it's not enough to just update the
> uart_port->uartclk field of the corresponding UART port, the 8250
> controller reference clock divisor should be altered so to preserve
> current baud rate setting. All of these things is done in a coherent
> way by calling the serial8250_update_uartclk() method provided in this
> patch. Though note that it isn't supposed to be called from within the
> UART port callbacks because the locks using to the protect the UART port
> data are already taken in there.

...

> +/*
> + * Note in order to avoid the tty port mutex deadlock don't use the next method
> + * within the uart port callbacks. Primarily it's supposed to be utilized to
> + * handle a sudden reference clock rate change.
> + */
> +void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk)
> +{
> +	struct uart_8250_port *up = up_to_u8250p(port);
> +	unsigned int baud, quot, frac = 0;
> +	struct ktermios *termios;
> +	unsigned long flags;
> +
> +	mutex_lock(&port->state->port.mutex);
> +
> +	if (port->uartclk == uartclk)
> +		goto out_lock;
> +
> +	port->uartclk = uartclk;
> +	termios = &port->state->port.tty->termios;
> +
> +	baud = serial8250_get_baud_rate(port, termios, NULL);
> +	quot = serial8250_get_divisor(port, baud, &frac);
> +
> +	serial8250_rpm_get(up);
> +	spin_lock_irqsave(&port->lock, flags);
> +
> +	uart_update_timeout(port, termios->c_cflag, baud);
> +
> +	serial8250_set_divisor(port, baud, quot, frac);
> +	serial_port_out(port, UART_LCR, up->lcr);
> +	serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
> +
> +	spin_unlock_irqrestore(&port->lock, flags);
> +	serial8250_rpm_put(up);
> +
> +out_lock:
> +	mutex_unlock(&port->state->port.mutex);

While looking for something else I have stumbled over this function.
My Q is, since it has some duplications with
serial8250_do_set_termios(), can we actually call the latter (or
derevative that can be called in both) in the above code instead of
duplicating some lines?

	if (port UART clock has to be updated)
	  call (unlocked version of) serial8250_do_set_termios()

Serge, what do you think?

> +}

-- 
With Best Regards,
Andy Shevchenko




From andrew at lunn.ch  Wed Feb 14 05:54:55 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 14 Feb 2024 14:54:55 +0100
Subject: [PATCH v2 1/2] ARM: dts: imx6dl-yapp4: Fix typo in the QCA
 switch register address
In-Reply-To: <1707901408-17084-1-git-send-email-michal.vokac@ysoft.com>
References: <1707901408-17084-1-git-send-email-michal.vokac@ysoft.com>
Message-ID: <8c765a36-4718-4f5f-a8d0-3763ac97ab7b@lunn.ch>

On Wed, Feb 14, 2024 at 10:03:27AM +0100, Michal Vok?? wrote:
> This change does not have any functional effect. The switch works just
> fine without this patch as it has full access to all the addresses
> on the bus. This is simply a clean-up to set the node name address
> and reg address to the same value.
> 
> Fixes: 15b43e497ffd ("ARM: dts: imx6dl-yapp4: Use correct pseudo PHY address for the switch")
> Signed-off-by: Michal Vok?? <michal.vokac at ysoft.com>

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

    Andrew


From robh at kernel.org  Wed Feb 14 05:58:24 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 14 Feb 2024 07:58:24 -0600
Subject: [PATCH] dt-bindings: sound:atmel-at91sam9g20ek: convert bindings
 to json-schema
In-Reply-To: <20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b@microchip.com>
References: <20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b@microchip.com>
Message-ID: <20240214135824.GA692740-robh@kernel.org>

On Wed, Feb 14, 2024 at 12:10:06PM +0530, Balakrishnan Sambath wrote:
> Convert atmel-at91sam9g20ek-wm8731-audio DT binding to yaml
> based json-schema.Change file name to match json-scheme naming.
> 
> Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>
> ---
>  .../bindings/sound/atmel,at91sam9g20ek-wm8731.yaml | 60 ++++++++++++++++++++++
>  .../sound/atmel-at91sam9g20ek-wm8731-audio.txt     | 26 ----------
>  2 files changed, 60 insertions(+), 26 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml b/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml
> new file mode 100644
> index 000000000000..f6330707fe1b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml
> @@ -0,0 +1,60 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/atmel,at91sam9g20ek-wm8731.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Atmel at91sam9g20ek wm8731 audio complex
> +
> +maintainers:
> +  - Balakrishnan Sambath <balakrishnan.s at microchip.com>
> +
> +properties:
> +  compatible:
> +    const: atmel,at91sam9g20ek-wm8731-audio
> +
> +  atmel,model:
> +    $ref: /schemas/types.yaml#/definitions/string
> +    description: The user-visible name of this sound complex.

blank line between DT properties

> +  atmel,audio-routing:
> +    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
> +    description: A list of the connections between audio components.
> +    minItems: 2

No max?

> +    items:
> +      enum:
> +        # Board Connectors
> +        - "Ext Spk"
> +        - "Int MIC"
> +
> +        # CODEC Pins
> +        - LHPOUT
> +        - MICIN
> +  atmel,ssc-controller:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: The phandle of the SSC controller
> +  atmel,audio-codec:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: The phandle of WM8731 audio codec
> +
> +required:
> +  - compatible
> +  - atmel,model
> +  - atmel,audio-routing
> +  - atmel,ssc-controller
> +  - atmel,audio-codec
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    sound {
> +        compatible = "atmel,at91sam9g20ek-wm8731-audio";
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&pinctrl_pck0_as_mck>;
> +        atmel,model = "wm8731 @ AT91SAMG20EK";
> +        atmel,audio-routing =
> +            "Ext Spk", "LHPOUT",
> +            "Int MIC", "MICIN";
> +        atmel,ssc-controller = <&ssc0>;
> +        atmel,audio-codec = <&wm8731>;
> +    };


From regressions at leemhuis.info  Wed Feb 14 06:00:47 2024
From: regressions at leemhuis.info (Linux regression tracking (Thorsten Leemhuis))
Date: Wed, 14 Feb 2024 15:00:47 +0100
Subject: 6.7 regression: platform 4809c000.mmc: deferred probe pending
In-Reply-To: <mvmcyt13idm.fsf@suse.de>
References: <mvmcyt13idm.fsf@suse.de>
Message-ID: <c92385d2-1909-43a8-aea8-cd9a8687a898@leemhuis.info>

[CCing the regression list, as it should be in the loop for regressions:
https://docs.kernel.org/admin-guide/reporting-regressions.html]

Hi, Thorsten here, the Linux kernel's regression tracker.

Thanks for the report.Added the omap list and the omap mmc maintainer;
the root of the problem might be somewhere else, but maybe we get some
help from there.

On 12.02.24 14:46, Andreas Schwab wrote:
> I'm getting these messages on the PandaBoard since 6.7:
> 
> [   29.285522][  T156] platform 4809c000.mmc: deferred probe pending
> [   29.291748][  T156] platform 4a0ab000.usb_otg_hs: deferred probe pending
> [   29.298522][  T156] platform 58005000.encoder: deferred probe pending
> [   29.305053][  T156] platform 58006000.encoder: deferred probe pending
> [   29.305145][  T156] i2c 0-004b: deferred probe pending
> [   29.316772][  T156] platform 40132000.target-module: deferred probe pending
> [   37.382110][  T156] pbias_mmc_omap4: disabling
> 
> As a result, the SD card is not found.
> Any idea what's going on here?

Haven't heard of anything like that. Unless some developer replies with
some idea in a day or two I guess you will have to bisect the problem.

[TLDR: I'm adding this report to the list of tracked Linux kernel
regressions; the text you find below is based on a few templates
paragraphs you might have encountered already in similar form.
See link in footer if these mails annoy you.]

Anyway, to be sure the issue doesn't fall through the cracks unnoticed,
I'm adding it to regzbot, the Linux kernel regression tracking bot:

#regzbot ^introduced v6.6..v6.7
#regzbot title arm: omap: platform 4809c000.mmc: deferred probe pending
#regzbot ignore-activity

This isn't a regression? This issue or a fix for it are already
discussed somewhere else? It was fixed already? You want to clarify when
the regression started to happen? Or point out I got the title or
something else totally wrong? Then just reply and tell me -- ideally
while also telling regzbot about it, as explained by the page listed in
the footer of this mail.

Developers: When fixing the issue, remember to add 'Link:' tags pointing
to the report (the parent of this mail). See page linked in footer for
details.

Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat)
--
Everything you wanna know about Linux kernel regression tracking:
https://linux-regtracking.leemhuis.info/about/#tldr
That page also explains what to do if mails like this annoy you.



From zajec5 at gmail.com  Wed Feb 14 06:04:53 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 14 Feb 2024 15:04:53 +0100
Subject: [PATCH V2 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible for MT7988
Message-ID: <20240214140454.6438-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

MT7988 has on-SoC controller that can control up to 8 PWM interfaces. It
differs from blocks on other SoCs (amount of PWMs & registers) so it
needs its own compatible string.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Explain new compatibility string reason in commit body

 Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml b/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
index 0fbe8a6469eb..a5c308801619 100644
--- a/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
@@ -24,6 +24,7 @@ properties:
           - mediatek,mt7629-pwm
           - mediatek,mt7981-pwm
           - mediatek,mt7986-pwm
+          - mediatek,mt7988-pwm
           - mediatek,mt8183-pwm
           - mediatek,mt8365-pwm
           - mediatek,mt8516-pwm
-- 
2.35.3



From zajec5 at gmail.com  Wed Feb 14 06:04:54 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 14 Feb 2024 15:04:54 +0100
Subject: [PATCH V2 2/2] pwm: mediatek: add support for MT7988
In-Reply-To: <20240214140454.6438-1-zajec5@gmail.com>
References: <20240214140454.6438-1-zajec5@gmail.com>
Message-ID: <20240214140454.6438-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

MT7988 uses new registers layout just like MT7981 but it supports 8 PWM
interfaces.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: New patch in the series

 drivers/pwm/pwm-mediatek.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 562102a47ac0..292c8bd5b343 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -339,6 +339,13 @@ static const struct pwm_mediatek_of_data mt7986_pwm_data = {
 	.reg_offset = mtk_pwm_reg_offset_v1,
 };
 
+static const struct pwm_mediatek_of_data mt7988_pwm_data = {
+	.num_pwms = 8,
+	.pwm45_fixup = false,
+	.has_ck_26m_sel = false,
+	.reg_offset = mtk_pwm_reg_offset_v2,
+};
+
 static const struct pwm_mediatek_of_data mt8183_pwm_data = {
 	.num_pwms = 4,
 	.pwm45_fixup = false,
@@ -369,6 +376,7 @@ static const struct of_device_id pwm_mediatek_of_match[] = {
 	{ .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
 	{ .compatible = "mediatek,mt7981-pwm", .data = &mt7981_pwm_data },
 	{ .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
+	{ .compatible = "mediatek,mt7988-pwm", .data = &mt7988_pwm_data },
 	{ .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
 	{ .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data },
 	{ .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
-- 
2.35.3



From daniel at makrotopia.org  Wed Feb 14 06:12:15 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Wed, 14 Feb 2024 14:12:15 +0000
Subject: [PATCH V2 2/2] pwm: mediatek: add support for MT7988
In-Reply-To: <20240214140454.6438-2-zajec5@gmail.com>
References: <20240214140454.6438-1-zajec5@gmail.com>
 <20240214140454.6438-2-zajec5@gmail.com>
Message-ID: <ZczKP-L7MptwnKF_@makrotopia.org>

On Wed, Feb 14, 2024 at 03:04:54PM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7988 uses new registers layout just like MT7981 but it supports 8 PWM
> interfaces.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: Daniel Golle <daniel at makrotopia.org>

> ---
> V2: New patch in the series
> 
>  drivers/pwm/pwm-mediatek.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> index 562102a47ac0..292c8bd5b343 100644
> --- a/drivers/pwm/pwm-mediatek.c
> +++ b/drivers/pwm/pwm-mediatek.c
> @@ -339,6 +339,13 @@ static const struct pwm_mediatek_of_data mt7986_pwm_data = {
>  	.reg_offset = mtk_pwm_reg_offset_v1,
>  };
>  
> +static const struct pwm_mediatek_of_data mt7988_pwm_data = {
> +	.num_pwms = 8,
> +	.pwm45_fixup = false,
> +	.has_ck_26m_sel = false,
> +	.reg_offset = mtk_pwm_reg_offset_v2,
> +};
> +
>  static const struct pwm_mediatek_of_data mt8183_pwm_data = {
>  	.num_pwms = 4,
>  	.pwm45_fixup = false,
> @@ -369,6 +376,7 @@ static const struct of_device_id pwm_mediatek_of_match[] = {
>  	{ .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
>  	{ .compatible = "mediatek,mt7981-pwm", .data = &mt7981_pwm_data },
>  	{ .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
> +	{ .compatible = "mediatek,mt7988-pwm", .data = &mt7988_pwm_data },
>  	{ .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
>  	{ .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data },
>  	{ .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
> -- 
> 2.35.3
> 
> 


From quic_jinlmao at quicinc.com  Wed Feb 14 06:18:20 2024
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Wed, 14 Feb 2024 22:18:20 +0800
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename
 qcom,dsb-element-size
In-Reply-To: <df3162c0-4b29-77a2-20b5-b36637fb11cf@arm.com>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
 <20240213160521.15925-2-quic_jinlmao@quicinc.com>
 <20240213222957.GA2502642-robh@kernel.org>
 <a062ce8d-638a-4a33-8afa-45ad47efcd72@quicinc.com>
 <df3162c0-4b29-77a2-20b5-b36637fb11cf@arm.com>
Message-ID: <162256e1-416f-46ea-9698-9de507768cb0@quicinc.com>


On 2/14/2024 5:36 PM, James Clark wrote:
>
> On 14/02/2024 01:43, Jinlong Mao wrote:
>> On 2/14/2024 6:29 AM, Rob Herring wrote:
>>> On Tue, Feb 13, 2024 at 08:05:17AM -0800, Mao Jinlong wrote:
>>>> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
>>>> bit.
>>> That may be, but this is an ABI and you are stuck with it. Unless, you
>>> can justify why that doesn't matter. (IIRC, this is new, so maybe no
>>> users yet?)
>> Hi Rob,
>>
>> Because for CMB type, it uses qcom,cmb-element-bits. So I change the
>> format to be the same as
>> CMB.
>>
>> Thanks
>> Jinlong Mao
>>
> I think what Rob was trying to say was that in the interest of not
> breaking existing DTs it's best to leave the existing names as they are,
> even if they aren't technically correct. And to only add new parameters
> with the -bits suffix, even if it's inconsistent with what's already there.

Hi Rob & James,

There is no tpdm nodes in any DT as of now. So I want to make this 
change before any tpdm
node is added in DT.

Thanks
Jinlong Mao

>
> _______________________________________________
> CoreSight mailing list -- coresight at lists.linaro.org
> To unsubscribe send an email to coresight-leave at lists.linaro.org


From dan.scally at ideasonboard.com  Wed Feb 14 06:19:03 2024
From: dan.scally at ideasonboard.com (Daniel Scally)
Date: Wed, 14 Feb 2024 14:19:03 +0000
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240214141906.245685-1-dan.scally@ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
Message-ID: <20240214141906.245685-3-dan.scally@ideasonboard.com>

Add the yaml binding for ARM's Mali-C55 Image Signal Processor.

Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
---
Changes in v2:

	- Added clocks information
	- Fixed the warnings raised by Rob

 .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml

diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
new file mode 100644
index 000000000000..30038cfec3a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ARM Mali-C55 Image Signal Processor
+
+maintainers:
+  - Daniel Scally <dan.scally at ideasonboard.com>
+  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
+
+properties:
+  compatible:
+    const: arm,mali-c55
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: ISP video clock
+      - description: ISP AXI clock
+      - description: ISP AHB-lite clock
+
+  clock-names:
+    items:
+      - const: vclk
+      - const: aclk
+      - const: hclk
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+
+        properties:
+          endpoint:
+            $ref: /schemas/graph.yaml#/properties/endpoint
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    mali_c55: isp at 400000 {
+      compatible = "arm,mali-c55";
+      reg = <0x400000 0x200000>;
+      clocks = <&clk 0>, <&clk 1>, <&clk 2>;
+      clock-names = "vclk", "aclk", "hclk";
+      interrupts = <0>;
+
+      ports {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        port at 0 {
+          reg = <0>;
+          isp_in: endpoint {
+              remote-endpoint = <&mipi_out>;
+          };
+        };
+      };
+    };
+...
-- 
2.34.1



From dan.scally at ideasonboard.com  Wed Feb 14 06:19:02 2024
From: dan.scally at ideasonboard.com (Daniel Scally)
Date: Wed, 14 Feb 2024 14:19:02 +0000
Subject: [PATCH v2 1/5] media: uapi: Add MEDIA_BUS_FMT_RGB202020_1X60 format code
In-Reply-To: <20240214141906.245685-1-dan.scally@ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
Message-ID: <20240214141906.245685-2-dan.scally@ideasonboard.com>

The Mali-C55 ISP by ARM requires 20-bits per colour channel input on
the bus. Add a new media bus format code to represent it.

Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
---
Changes in v2:

	- none

 .../media/v4l/subdev-formats.rst              | 168 ++++++++++++++++++
 include/uapi/linux/media-bus-format.h         |   3 +-
 2 files changed, 170 insertions(+), 1 deletion(-)

diff --git a/Documentation/userspace-api/media/v4l/subdev-formats.rst b/Documentation/userspace-api/media/v4l/subdev-formats.rst
index eb3cd20b0cf2..269b61926855 100644
--- a/Documentation/userspace-api/media/v4l/subdev-formats.rst
+++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst
@@ -2223,6 +2223,174 @@ The following table list existing packed 48bit wide RGB formats.
 
     \endgroup
 
+The following table list existing packed 60bit wide RGB formats.
+
+.. tabularcolumns:: |p{4.0cm}|p{0.7cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _v4l2-mbus-pixelcode-rgb-60:
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. flat-table:: 60bit RGB formats
+    :header-rows:  3
+    :stub-columns: 0
+    :widths: 36 7 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+
+    * - Identifier
+      - Code
+      -
+      - :cspan:`31` Data organization
+    * -
+      -
+      - Bit
+      -
+      -
+      -
+      -
+      - 59
+      - 58
+      - 57
+      - 56
+      - 55
+      - 54
+      - 53
+      - 52
+      - 51
+      - 50
+      - 49
+      - 48
+      - 47
+      - 46
+      - 45
+      - 44
+      - 43
+      - 42
+      - 41
+      - 40
+      - 39
+      - 38
+      - 37
+      - 36
+      - 35
+      - 34
+      - 33
+      - 32
+    * -
+      -
+      -
+      - 31
+      - 30
+      - 29
+      - 28
+      - 27
+      - 26
+      - 25
+      - 24
+      - 23
+      - 22
+      - 21
+      - 20
+      - 19
+      - 18
+      - 17
+      - 16
+      - 15
+      - 14
+      - 13
+      - 12
+      - 11
+      - 10
+      - 9
+      - 8
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _MEDIA-BUS-FMT-RGB202020-1X60:
+
+      - MEDIA_BUS_FMT_RGB202020_1X60
+      - 0x1026
+      -
+      -
+      -
+      -
+      -
+      - r\ :sub:`19`
+      - r\ :sub:`18`
+      - r\ :sub:`17`
+      - r\ :sub:`16`
+      - r\ :sub:`15`
+      - r\ :sub:`14`
+      - r\ :sub:`13`
+      - r\ :sub:`12`
+      - r\ :sub:`11`
+      - r\ :sub:`10`
+      - r\ :sub:`8`
+      - r\ :sub:`8`
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`19`
+      - g\ :sub:`18`
+      - g\ :sub:`17`
+      - g\ :sub:`16`
+      - g\ :sub:`15`
+      - g\ :sub:`14`
+      - g\ :sub:`13`
+      - g\ :sub:`12`
+    * -
+      -
+      -
+      - g\ :sub:`11`
+      - g\ :sub:`10`
+      - g\ :sub:`9`
+      - g\ :sub:`8`
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`19`
+      - b\ :sub:`18`
+      - b\ :sub:`17`
+      - b\ :sub:`16`
+      - b\ :sub:`15`
+      - b\ :sub:`14`
+      - b\ :sub:`13`
+      - b\ :sub:`12`
+      - b\ :sub:`11`
+      - b\ :sub:`10`
+      - b\ :sub:`9`
+      - b\ :sub:`8`
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+.. raw:: latex
+
+    \endgroup
+
 On LVDS buses, usually each sample is transferred serialized in seven
 time slots per pixel clock, on three (18-bit) or four (24-bit)
 differential data pairs at the same time. The remaining bits are used
diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h
index f05f747e444d..8633818cc33c 100644
--- a/include/uapi/linux/media-bus-format.h
+++ b/include/uapi/linux/media-bus-format.h
@@ -34,7 +34,7 @@
 
 #define MEDIA_BUS_FMT_FIXED			0x0001
 
-/* RGB - next is	0x1026 */
+/* RGB - next is	0x1027 */
 #define MEDIA_BUS_FMT_RGB444_1X12		0x1016
 #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE	0x1001
 #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE	0x1002
@@ -72,6 +72,7 @@
 #define MEDIA_BUS_FMT_RGB888_1X36_CPADLO	0x1021
 #define MEDIA_BUS_FMT_RGB121212_1X36		0x1019
 #define MEDIA_BUS_FMT_RGB161616_1X48		0x101a
+#define MEDIA_BUS_FMT_RGB202020_1X60		0x1026
 
 /* YUV (including grey) - next is	0x202f */
 #define MEDIA_BUS_FMT_Y8_1X8			0x2001
-- 
2.34.1



From dan.scally at ideasonboard.com  Wed Feb 14 06:19:01 2024
From: dan.scally at ideasonboard.com (Daniel Scally)
Date: Wed, 14 Feb 2024 14:19:01 +0000
Subject: [PATCH v2 0/5] Add Arm Mali-C55 Image Signal Processor Driver
Message-ID: <20240214141906.245685-1-dan.scally@ideasonboard.com>

Hello all

This patchset introduces a driver for Arm's Mali-C55 Image Signal Processor.
The driver uses the media controller API and in this initial support implements
both of the ISP's capture pipelines allowing a range of output formats plus
downscaling and cropping. The capture pipelines are named "Full resolution" and
"Downscale" and so abbreviated FR and DS throughout the driver.

The driver exposes 4 V4L2 subdevices:

- mali-c55 isp: input data formatting
- mali-c55 tpg: test pattern generator (modeled as a camera sensor entity)
- mali-c55 resizer fr: downscale / crop and format setting for the FR pipe
- mali-c55 resizer ds: downscale / crop and format setting for the DS pipe

Conspicuously missing from the list are subdevices for the ISP's statistics and
parameters; work is progressing in these areas and we plan on introducing them
in later series on top of this one.

Thanks
Dan

Daniel Scally (5):
  media: uapi: Add MEDIA_BUS_FMT_RGB202020_1X60 format code
  dt-bindings: media: Add bindings for ARM mali-c55
  media: mali-c55: Add Mali-C55 ISP driver
  media: Documentation: Add Mali-C55 ISP Documentation
  MAINTAINERS: Add entry for mali-c55 driver

 .../admin-guide/media/mali-c55-graph.dot      |   19 +
 Documentation/admin-guide/media/mali-c55.rst  |  318 +++++
 .../admin-guide/media/v4l-drivers.rst         |    1 +
 .../bindings/media/arm,mali-c55.yaml          |   77 ++
 .../media/v4l/subdev-formats.rst              |  168 +++
 MAINTAINERS                                   |   10 +
 drivers/media/platform/Kconfig                |    1 +
 drivers/media/platform/Makefile               |    1 +
 drivers/media/platform/arm/Kconfig            |    5 +
 drivers/media/platform/arm/Makefile           |    2 +
 drivers/media/platform/arm/mali-c55/Kconfig   |   18 +
 drivers/media/platform/arm/mali-c55/Makefile  |    9 +
 .../platform/arm/mali-c55/mali-c55-capture.c  | 1021 +++++++++++++++++
 .../platform/arm/mali-c55/mali-c55-common.h   |  271 +++++
 .../platform/arm/mali-c55/mali-c55-core.c     |  767 +++++++++++++
 .../platform/arm/mali-c55/mali-c55-isp.c      |  682 +++++++++++
 .../arm/mali-c55/mali-c55-registers.h         |  180 +++
 .../arm/mali-c55/mali-c55-resizer-coefs.h     |  382 ++++++
 .../platform/arm/mali-c55/mali-c55-resizer.c  |  678 +++++++++++
 .../platform/arm/mali-c55/mali-c55-tpg.c      |  425 +++++++
 include/uapi/linux/media-bus-format.h         |    3 +-
 21 files changed, 5037 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/admin-guide/media/mali-c55-graph.dot
 create mode 100644 Documentation/admin-guide/media/mali-c55.rst
 create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
 create mode 100644 drivers/media/platform/arm/Kconfig
 create mode 100644 drivers/media/platform/arm/Makefile
 create mode 100644 drivers/media/platform/arm/mali-c55/Kconfig
 create mode 100644 drivers/media/platform/arm/mali-c55/Makefile
 create mode 100644 drivers/media/platform/arm/mali-c55/mali-c55-capture.c
 create mode 100644 drivers/media/platform/arm/mali-c55/mali-c55-common.h
 create mode 100644 drivers/media/platform/arm/mali-c55/mali-c55-core.c
 create mode 100644 drivers/media/platform/arm/mali-c55/mali-c55-isp.c
 create mode 100644 drivers/media/platform/arm/mali-c55/mali-c55-registers.h
 create mode 100644 drivers/media/platform/arm/mali-c55/mali-c55-resizer-coefs.h
 create mode 100644 drivers/media/platform/arm/mali-c55/mali-c55-resizer.c
 create mode 100644 drivers/media/platform/arm/mali-c55/mali-c55-tpg.c

-- 
2.34.1



From dan.scally at ideasonboard.com  Wed Feb 14 06:19:05 2024
From: dan.scally at ideasonboard.com (Daniel Scally)
Date: Wed, 14 Feb 2024 14:19:05 +0000
Subject: [PATCH v2 4/5] media: Documentation: Add Mali-C55 ISP Documentation
In-Reply-To: <20240214141906.245685-1-dan.scally@ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
Message-ID: <20240214141906.245685-5-dan.scally@ideasonboard.com>

Add a documentation page for the mali-c55 driver, which gives a brief
overview of the hardware and explains how to use the driver's capture
devices and the crop/scaler functions.

Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
---
Changes in v2:

	- none

 .../admin-guide/media/mali-c55-graph.dot      |  19 ++
 Documentation/admin-guide/media/mali-c55.rst  | 318 ++++++++++++++++++
 .../admin-guide/media/v4l-drivers.rst         |   1 +
 3 files changed, 338 insertions(+)
 create mode 100644 Documentation/admin-guide/media/mali-c55-graph.dot
 create mode 100644 Documentation/admin-guide/media/mali-c55.rst

diff --git a/Documentation/admin-guide/media/mali-c55-graph.dot b/Documentation/admin-guide/media/mali-c55-graph.dot
new file mode 100644
index 000000000000..0775ba42bf4c
--- /dev/null
+++ b/Documentation/admin-guide/media/mali-c55-graph.dot
@@ -0,0 +1,19 @@
+digraph board {
+        rankdir=TB
+        n00000001 [label="{{} | mali-c55 tpg\n/dev/v4l-subdev0 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+        n00000001:port0 -> n00000003:port0 [style=dashed]
+        n00000003 [label="{{<port0> 0} | mali-c55 isp\n/dev/v4l-subdev1 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
+        n00000003:port1 -> n00000007:port0 [style=bold]
+        n00000003:port2 -> n00000007:port2 [style=bold]
+        n00000003:port1 -> n0000000b:port0 [style=bold]
+        n00000007 [label="{{<port0> 0 | <port2> 2} | mali-c55 resizer fr\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+        n00000007:port1 -> n0000000e [style=bold]
+        n0000000b [label="{{<port0> 0} | mali-c55 resizer ds\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+        n0000000b:port1 -> n00000012 [style=bold]
+        n0000000e [label="mali-c55 fr\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
+        n00000012 [label="mali-c55 ds\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
+        n00000022 [label="{{<port0> 0} | csi2-rx\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+        n00000022:port1 -> n00000003:port0
+        n00000027 [label="{{} | imx415 1-001a\n/dev/v4l-subdev5 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+        n00000027:port0 -> n00000022:port0 [style=bold]
+}
\ No newline at end of file
diff --git a/Documentation/admin-guide/media/mali-c55.rst b/Documentation/admin-guide/media/mali-c55.rst
new file mode 100644
index 000000000000..83f630c3bd9d
--- /dev/null
+++ b/Documentation/admin-guide/media/mali-c55.rst
@@ -0,0 +1,318 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========================================
+ARM Mali-C55 Image Signal Processor driver
+==========================================
+
+Introduction
+============
+
+This file documents the driver for ARM's Mali-C55 Image Signal Processor. The
+driver is located under drivers/media/platform/arm/mali-c55.
+
+The Mali-C55 ISP receives data in either raw Bayer format or RGB/YUV format from
+sensors through either a parallel interface or a memory bus before processing it
+and outputting it through an internal DMA engine. Two output pipelines are
+possible (though one may not be fitted, depending on the implementation). These
+are referred to as "Full resolution" and "Downscale", but the naming is historic
+and both pipes are capable of cropping/scaling operations. An integrated test
+pattern generator can be used to drive the ISP and produce image data in the
+absence of a connected camera sensor. The driver module is named mali_c55, and
+is enabled through the CONFIG_VIDEO_MALI_C55 config option.
+
+The driver implements V4L2, Media Controller and V4L2 Subdevice interfaces and
+expects camera sensors connected to the ISP to have V4L2 subdevice interfaces.
+
+Mali-C55 ISP hardware
+=====================
+
+A high level functional view of the Mali-C55 ISP is presented below. The ISP
+takes input from either a live source or through a DMA engine for memory input,
+depending on the SoC integration.::
+
+  +---------+    +----------+                                     +--------+
+  | Sensor  |--->| CSI-2 Rx |                "Full Resolution"    |  DMA   |
+  +---------+    +----------+   |\                 Output    +--->| Writer |
+                       |        | \                          |    +--------+
+                       |        |  \    +----------+  +------+---> Streaming I/O
+  +------------+       +------->|   |   |          |  |
+  |            |                |   |-->| Mali-C55 |--+
+  | DMA Reader |--------------->|   |   |    ISP   |  |
+  |            |                |  /    |          |  |      +---> Streaming I/O
+  +------------+                | /     +----------+  |      |
+                                |/                    +------+
+				                             |    +--------+
+                                                             +--->|  DMA   |
+                                               "Downscaled"       | Writer |
+					          Output          +--------+
+
+Media Controller Topology
+=========================
+
+An example of the ISP's topology (as implemented in a system with an IMX415
+camera sensor and generic CSI-2 receiver) is below:
+
+
+.. kernel-figure:: mali-c55-graph.dot
+    :alt:   mali-c55-graph.dot
+    :align: center
+
+The driver has 4 V4L2 subdevices:
+
+- `mali_c55 isp`: Responsible for configuring input crop and color space
+                  conversion
+- `mali_c55 tpg`: The test pattern generator, emulating a camera sensor.
+- `mali_c55 resizer fr`: The Full-Resolution pipe resizer
+- `mali_c55 resizer ds`: The Downscale pipe resizer
+
+The driver has 2 V4L2 video devices:
+
+- `mali-c55 fr`: The full-resolution pipe's capture device
+- `mali-c55 ds`: The downscale pipe's capture device
+
+Idiosyncrasies
+--------------
+
+**mali-c55 isp**
+The `mali-c55 isp` subdevice has a single sink pad to which all sources of data
+should be connected. The active source is selected by enabling the appropriate
+media link and disabling all others. The ISP has two source pads, reflecting the
+different paths through which it can internally route data. Tap points within
+the ISP allow users to divert data to avoid processing by some or all of the
+hardware's processing steps. The diagram below is intended only to highlight how
+the bypassing works and is not a true reflection of those processing steps; for
+a high-level functional block diagram see ARM's developer page for the
+ISP [3]_::
+
+  +--------------------------------------------------------------+
+  |                Possible Internal ISP Data Routes             |
+  |          +------------+  +----------+  +------------+        |
+  +---+      |            |  |          |  |  Colour    |    +---+
+  | 0 |--+-->| Processing |->| Demosaic |->|   Space    |--->| 1 |
+  +---+  |   |            |  |          |  | Conversion |    +---+
+  |      |   +------------+  +----------+  +------------+        |
+  |      |                                                   +---+
+  |      +---------------------------------------------------| 2 |
+  |                                                          +---+
+  |                                                              |
+  +--------------------------------------------------------------+
+
+
+.. flat-table::
+    :header-rows: 1
+
+    * - Pad
+      - Direction
+      - Purpose
+
+    * - 0
+      - sink
+      - Data input, connected to the TPG and camera sensors
+
+    * - 1
+      - source
+      - RGB/YUV data, connected to the FR and DS V4L2 subdevices
+
+    * - 2
+      - source
+      - RAW bayer data, connected to the FR V4L2 subdevices
+
+**mali-c55 resizer fr**
+The `mali-c55 resizer fr` subdevice has two _sink_ pads to reflect the different
+insertion points in the hardware (either RAW or demosaiced data):
+
+.. flat-table::
+    :header-rows: 1
+
+    * - Pad
+      - Direction
+      - Purpose
+
+    * - 0
+      - sink
+      - Data input connected to the ISP's demosaiced stream.
+
+    * - 1
+      - source
+      - Data output connected to the capture video device
+
+    * - 2
+      - sink
+      - Data input connected to the ISP's raw data stream
+
+The data source in use is selected through the routing API; two routes each of a
+single stream are available:
+
+.. flat-table::
+    :header-rows: 1
+
+    * - Sink Pad
+      - Source Pad
+      - Purpose
+
+    * - 0
+      - 1
+      - Demosaiced data route
+
+    * - 2
+      - 1
+      - Raw data route
+
+
+If the demosaiced route is active then the FR pipe is only capable of output
+in RGB/YUV formats. If the raw route is active then the output reflects the
+input (which may be either Bayer or RGB/YUV data).
+
+Using the driver to capture video
+=================================
+
+Using the media controller APIs we can configure the input source and ISP to
+capture images in a variety of formats. In the examples below, configuring the
+media graph is done with the v4l-utils [1]_ package's media-ctl utility.
+Capturing the images is done with yavta [2]_.
+
+Configuring the input source
+----------------------------
+
+The first step is to set the input source that we wish by enabling the correct
+media link. Using the example topology above, we can select the TPG as follows:
+
+.. code-block:: none
+
+    media-ctl -l "'lte-csi2-rx':1->'mali-c55 isp':0[0]"
+    media-ctl -l "'mali-c55 tpg':0->'mali-c55 isp':0[1]"
+
+Capturing bayer data from the source and processing to RGB/YUV
+--------------------------------------------------------------
+To capture 1920x1080 bayer data from the source and push it through the ISP's
+full processing pipeline, we configure the data formats appropriately on the
+source, ISP and resizer subdevices and set the FR resizer's routing to select
+processed data. The media bus format on the resizer's source pad will be either
+RGB121212_1X36 or YUV10_1X30, depending on whether you want to capture RGB or
+YUV. The ISP's debayering block outputs RGB data natively, setting the source
+pad format to YUV10_1X30 enables the colour space conversion block.
+
+In this example we target RGB565 output, so select RGB121212_1X36 as the resizer
+source pad's format:
+
+.. code-block:: none
+
+    # Set formats on the TPG and ISP
+    media-ctl -V "'mali-c55 tpg':0[fmt:SRGGB16_1X16/1920x1080]"
+    media-ctl -V "'mali-c55 isp':0[fmt:SRGGB16_1X16/1920x1080]"
+    media-ctl -V "'mali-c55 isp':1[fmt:SRGGB16_1X16/1920x1080]"
+
+    # Set routing on the FR resizer
+    media-ctl -R "'mali-c55 resizer fr'[0/0->1/0[1],2/0->1/0[0]]"
+
+    # Set format on the resizer, must be done AFTER the routing.
+    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/1920x1080]"
+
+The downscale output can also be used to stream data at the same time. In this
+case only processed data can be captured and so no routing need be set:
+
+.. code-block:: none
+
+    # Set format on the resizer
+    media-ctl -V "'mali-c55 resizer ds':1[fmt:RGB121212_1X36/1920x1080]"
+
+Following which images can be captured from both the FR and DS output's video
+devices (simultaneously, if desired):
+
+.. code-block:: none
+
+    yavta -f RGB565 -s 1920x1080 -c10 /dev/video0
+    yavta -f RGB565 -s 1920x1080 -c10 /dev/video1
+
+Cropping the image
+~~~~~~~~~~~~~~~~~~
+
+Both the full resolution and downscale pipes can crop to a minimum resolution of
+640x480. To crop the image simply configure the resizer's sink pad's crop and
+compose rectangles and set the format on the video device:
+
+.. code-block:: none
+
+    media-ctl -V "'mali-c55 resizer fr':0[fmt:RGB121212_1X36/1920x1080 crop:(480,270)/640x480 compose:(0,0)/640x480]"
+    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/640x480]"
+    yavta -f RGB565 -s 640x480 -c10 /dev/video0
+
+Downscaling the image
+~~~~~~~~~~~~~~~~~~~~~
+
+Both the full resolution and downscale pipes can downscale the image by up to 8x
+provided the minimum 640x480 resolution is adhered to. For the best image result
+the scaling ratio for each dimension should be the same. To configure scaling we
+use the compose rectangle on the resizer's sink pad:
+
+.. code-block:: none
+
+    media-ctl -V "'mali-c55 resizer fr':0[fmt:RGB121212_1X36/1920x1080 crop:(0,0)/1920x1080 compose:(0,0)/640x480]"
+    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/640x480]"
+    yavta -f RGB565 -s 640x480 -c10 /dev/video0
+
+Capturing images in YUV formats
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If we need to output YUV data rather than RGB the color space conversion block
+needs to be active, which is achieved by setting MEDIA_BUS_FMT_YUV10_1X30 on the
+resizer's source pad. We can then configure a capture format like NV12 (here in
+its multi-planar variant)
+
+.. code-block:: none
+
+    media-ctl -V "'mali-c55 resizer fr':1[fmt:YUV10_1X30/1920x1080]"
+    yavta -f NV12M -s 1920x1080 -c10 /dev/video0
+
+Capturing RGB data from the source and processing it with the resizers
+----------------------------------------------------------------------
+
+The Mali-C55 ISP can work with sensors capable of outputting RGB data. In this
+case although none of the image quality blocks would be used it can still
+crop/scale the data in the usual way.
+
+To achieve this, the ISP's sink pad's format is set to
+MEDIA_BUS_FMT_RGB202020_1X60 - this reflects the format that data must be in to
+work with the ISP. Converting the camera sensor's output to that format is the
+responsibility of external hardware.
+
+In this example we ask the test pattern generator to give us RGB data instead of
+bayer.
+
+.. code-block:: none
+
+    media-ctl -V "'mali-c55 tpg':0[fmt:RGB202020_1X60/1920x1080]"
+    media-ctl -V "'mali-c55 isp':0[fmt:RGB202020_1X60/1920x1080]"
+
+Cropping or scaling the data can be done in exactly the same way as outlined
+earlier.
+
+Capturing raw data from the source and outputting it unmodified
+-----------------------------------------------------------------
+
+The ISP can additionally capture raw data from the source and output it on the
+full resolution pipe only, completely unmodified. In this case the downscale
+pipe can still process the data normally and be used at the same time.
+
+To configure raw bypass the FR resizer's subdevice's routing table needs to be
+configured, followed by formats in the appropriate places:
+
+.. code-block:: none
+
+    # We need to configure the routing table for the resizer to use the bypass
+    # path along with set formats on the resizer's bypass sink pad. Doing this
+    # necessitates a single media-ctl command, as multiple calls to the program
+    # reset the routing table.
+    media-ctl -R "'mali-c55 resizer fr'[0/0->1/0[0],2/0->1/0[1]]"\
+    -V "'mali-c55 isp':0[fmt:RGB202020_1X60/1920x1080],"\
+       "'mali-c55 resizer fr':2[fmt:RGB202020_1X60/1920x1080],"\
+       "'mali-c55 resizer fr':1[fmt:RGB202020_1X60/1920x1080]"
+
+    # Set format on the video device and stream
+    yavta -f RGB565 -s 1920x1080 -c10 /dev/video0
+
+References
+==========
+.. [1] https://git.linuxtv.org/v4l-utils.git/
+.. [2] https://git.ideasonboard.org/yavta.git
+.. [3] https://developer.arm.com/Processors/Mali-C55
diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentation/admin-guide/media/v4l-drivers.rst
index f4bb2605f07e..af033c892808 100644
--- a/Documentation/admin-guide/media/v4l-drivers.rst
+++ b/Documentation/admin-guide/media/v4l-drivers.rst
@@ -17,6 +17,7 @@ Video4Linux (V4L) driver-specific documentation
 	imx7
 	ipu3
 	ivtv
+	mali-c55
 	mgb4
 	omap3isp
 	omap4_camera
-- 
2.34.1



From dan.scally at ideasonboard.com  Wed Feb 14 06:19:06 2024
From: dan.scally at ideasonboard.com (Daniel Scally)
Date: Wed, 14 Feb 2024 14:19:06 +0000
Subject: [PATCH v2 5/5] MAINTAINERS: Add entry for mali-c55 driver
In-Reply-To: <20240214141906.245685-1-dan.scally@ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
Message-ID: <20240214141906.245685-6-dan.scally@ideasonboard.com>

Add a MAINTAINERS entry for the mali-c55 driver and its associated
documentation.

Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
---
Changes in v2:

	- none

 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8d1052fa6a69..bec50bfb09ec 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1668,6 +1668,16 @@ F:	Documentation/gpu/panfrost.rst
 F:	drivers/gpu/drm/panfrost/
 F:	include/uapi/drm/panfrost_drm.h
 
+ARM MALI-C55 ISP DRIVER
+M:	Daniel Scally <dan.scally at ideasonboard.com>
+M:	Jacopo Mondi <jacopo.mondi at ideasonboard.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+T:	git git://linuxtv.org/media_tree.git
+F:	Documentation/admin-guide/media/mali-c55.rst
+F:	Documentation/devicetree/bindings/media/arm,mali-c55.yaml
+F:	drivers/media/platform/arm/mali-c55/
+
 ARM MALI-DP DRM DRIVER
 M:	Liviu Dudau <liviu.dudau at arm.com>
 S:	Supported
-- 
2.34.1



From laurent.pinchart at ideasonboard.com  Wed Feb 14 06:28:25 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 14 Feb 2024 16:28:25 +0200
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240214141906.245685-3-dan.scally@ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
Message-ID: <20240214142825.GA7873@pendragon.ideasonboard.com>

Hi Dan,

Thank you for the patch.

On Wed, Feb 14, 2024 at 02:19:03PM +0000, Daniel Scally wrote:
> Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
> 
> Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> ---
> Changes in v2:
> 
> 	- Added clocks information
> 	- Fixed the warnings raised by Rob
> 
>  .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
>  1 file changed, 77 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> new file mode 100644
> index 000000000000..30038cfec3a4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> @@ -0,0 +1,77 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ARM Mali-C55 Image Signal Processor
> +
> +maintainers:
> +  - Daniel Scally <dan.scally at ideasonboard.com>
> +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> +
> +properties:
> +  compatible:
> +    const: arm,mali-c55
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: ISP video clock

I wonder if we need this clock. Granted, it's an input clock to the ISP,
but it's part of the input video bus. I don't expect anyone would ever
need to control it manually, it should be provided by the video source
automatically.

> +      - description: ISP AXI clock
> +      - description: ISP AHB-lite clock

These two other clocks look good to me.

> +
> +  clock-names:
> +    items:
> +      - const: vclk
> +      - const: aclk
> +      - const: hclk
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +
> +        properties:
> +          endpoint:
> +            $ref: /schemas/graph.yaml#/properties/endpoint
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    mali_c55: isp at 400000 {
> +      compatible = "arm,mali-c55";
> +      reg = <0x400000 0x200000>;
> +      clocks = <&clk 0>, <&clk 1>, <&clk 2>;
> +      clock-names = "vclk", "aclk", "hclk";
> +      interrupts = <0>;
> +
> +      ports {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        port at 0 {
> +          reg = <0>;
> +          isp_in: endpoint {
> +              remote-endpoint = <&mipi_out>;
> +          };
> +        };
> +      };
> +    };
> +...

-- 
Regards,

Laurent Pinchart


From andrew at lunn.ch  Wed Feb 14 06:44:39 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 14 Feb 2024 15:44:39 +0100
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com>
 <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
Message-ID: <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>

On Wed, Feb 14, 2024 at 02:49:41PM +0530, Kathiravan Thirumoorthy wrote:
> 
> 
> On 1/26/2024 1:35 AM, Andrew Lunn wrote:
> > On Mon, Jan 22, 2024 at 11:26:58AM +0530, Kathiravan Thirumoorthy wrote:
> > > gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk are
> > > enabled by default and it's RCG is properly configured by bootloader.
> > 
> > Which bootloader? Mainline barebox?
> 
> 
> Thanks for taking time to review the patches. I couldn't get time to respond
> back, sorry for the delay.
> 
> I was referring to the U-boot which is delivered as part of the QSDK. I will
> call it out explicitly in the next patch.

I've never used QSDK u-boot, so i can only make comments based on my
experience with other vendors build of u-boot. That experience is, its
broken for my use cases, and i try to replace it as soon as possible
with upstream.

I generally want to TFTP boot the kernel and the DT blob. Sometimes
vendor u-boot has networking disabled. Or the TFTP client is
missing. If it is there, the IP addresses are fixed, and i don't want
to modify my network to make it compatible with the vendor
requirements. If the IP addresses can be configured, sometimes there
is no FLASH support so its not possible to actually write the
configuration to FLASH so that it does the right thing on reboot
etc...

Often the vendor u-boot is a black box, no sources. Can you give me a
git URL for the u-boot in QSDK? If the sources are open, i could at
least rebuild it with everything turned on.

But still, it is better that Linux makes no assumptions about what the
boot loader has done. That makes it much easier to change the
bootloader.

> > > Some of the NSS clocks needs these clocks to be enabled. To avoid
> > > these clocks being disabled by clock framework, drop these entries
> > > from the clock table and enable it in the driver probe itself.
> > 
> > If they are critical clocks, i would expect a device to reference
> > them. The CCF only disabled unused clocks in late_initcall_sync(),
> > which means all drivers should of probed and taken a reference on any
> > clocks they require.
> 
> 
> Some of the NSSCC clocks are enabled by bootloaders and CCF disables the
> same (because currently there are no consumers for these clocks available in
> the tree. These clocks are consumed by the Networking drivers which are
> being upstreamed).

If there is no network drivers, you don't need clocks to the
networking hardware. So CCF turning them off seems correct.

Once you have actual drivers, this should solve itself, the drivers
will consume the clocks.

> However looking back, gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk,
> gcc_nssnoc_nsscc_clk are consumed by the networking drivers only. So is it
> okay to drop these clocks from the GCC driver and add it back once the
> actual consumer needs it?

But why should you remove them. If nothing is using them, they should
be turned off.

   Andrew


From geert+renesas at glider.be  Wed Feb 14 06:57:42 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 15:57:42 +0100
Subject: [PATCH] ARM: dts: renesas: rcar-gen2: Add missing #interrupt-cells to DA9063 nodes
Message-ID: <a351e503ea97fb1af68395843f513925ff1bdf26.1707922460.git.geert+renesas@glider.be>

make dtbs_check W=2:

    arch/arm/boot/dts/renesas/r8a7790-lager.dts:444.11-458.5: Warning (interrupt_provider): /i2c-mux4/pmic at 58: Missing '#interrupt-cells' in interrupt provider
    ...

Fix this by adding the missing #interrupt-cells properties.

Reported-by: Rob Herring <robh at kernel.org>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
To be queued in renesas-devel for v6.9.

 arch/arm/boot/dts/renesas/r8a7790-lager.dts   | 1 +
 arch/arm/boot/dts/renesas/r8a7790-stout.dts   | 1 +
 arch/arm/boot/dts/renesas/r8a7791-koelsch.dts | 1 +
 arch/arm/boot/dts/renesas/r8a7791-porter.dts  | 1 +
 arch/arm/boot/dts/renesas/r8a7792-blanche.dts | 1 +
 arch/arm/boot/dts/renesas/r8a7793-gose.dts    | 1 +
 arch/arm/boot/dts/renesas/r8a7794-alt.dts     | 1 +
 arch/arm/boot/dts/renesas/r8a7794-silk.dts    | 1 +
 8 files changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/renesas/r8a7790-lager.dts b/arch/arm/boot/dts/renesas/r8a7790-lager.dts
index 2fba4d084001b964..8590981245a62057 100644
--- a/arch/arm/boot/dts/renesas/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/renesas/r8a7790-lager.dts
@@ -447,6 +447,7 @@ pmic at 58 {
 			interrupt-parent = <&irqc0>;
 			interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
 			interrupt-controller;
+			#interrupt-cells = <2>;
 
 			rtc {
 				compatible = "dlg,da9063-rtc";
diff --git a/arch/arm/boot/dts/renesas/r8a7790-stout.dts b/arch/arm/boot/dts/renesas/r8a7790-stout.dts
index f9bc5b4f019d0213..683f7395fab0b696 100644
--- a/arch/arm/boot/dts/renesas/r8a7790-stout.dts
+++ b/arch/arm/boot/dts/renesas/r8a7790-stout.dts
@@ -347,6 +347,7 @@ pmic at 58 {
 		interrupt-parent = <&irqc0>;
 		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-controller;
+		#interrupt-cells = <2>;
 
 		onkey {
 			compatible = "dlg,da9063-onkey";
diff --git a/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts b/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts
index e9c13bb03772af44..0efd9f98c75aced0 100644
--- a/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts
@@ -819,6 +819,7 @@ pmic at 58 {
 		interrupt-parent = <&irqc0>;
 		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-controller;
+		#interrupt-cells = <2>;
 
 		rtc {
 			compatible = "dlg,da9063-rtc";
diff --git a/arch/arm/boot/dts/renesas/r8a7791-porter.dts b/arch/arm/boot/dts/renesas/r8a7791-porter.dts
index 7e8bc06715f6564b..93c86e9216455577 100644
--- a/arch/arm/boot/dts/renesas/r8a7791-porter.dts
+++ b/arch/arm/boot/dts/renesas/r8a7791-porter.dts
@@ -413,6 +413,7 @@ pmic at 5a {
 		interrupt-parent = <&irqc0>;
 		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-controller;
+		#interrupt-cells = <2>;
 
 		watchdog {
 			compatible = "dlg,da9063-watchdog";
diff --git a/arch/arm/boot/dts/renesas/r8a7792-blanche.dts b/arch/arm/boot/dts/renesas/r8a7792-blanche.dts
index 4f9838cf97ee4fb6..540a9ad28f28ac1a 100644
--- a/arch/arm/boot/dts/renesas/r8a7792-blanche.dts
+++ b/arch/arm/boot/dts/renesas/r8a7792-blanche.dts
@@ -381,6 +381,7 @@ pmic at 58 {
 		interrupt-parent = <&irqc>;
 		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-controller;
+		#interrupt-cells = <2>;
 
 		rtc {
 			compatible = "dlg,da9063-rtc";
diff --git a/arch/arm/boot/dts/renesas/r8a7793-gose.dts b/arch/arm/boot/dts/renesas/r8a7793-gose.dts
index 1744fdbf9e0ce08d..1ea6c757893bc0bf 100644
--- a/arch/arm/boot/dts/renesas/r8a7793-gose.dts
+++ b/arch/arm/boot/dts/renesas/r8a7793-gose.dts
@@ -759,6 +759,7 @@ pmic at 58 {
 		interrupt-parent = <&irqc0>;
 		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-controller;
+		#interrupt-cells = <2>;
 
 		rtc {
 			compatible = "dlg,da9063-rtc";
diff --git a/arch/arm/boot/dts/renesas/r8a7794-alt.dts b/arch/arm/boot/dts/renesas/r8a7794-alt.dts
index c0d067df22a03d4e..b5ecafbb2e4de582 100644
--- a/arch/arm/boot/dts/renesas/r8a7794-alt.dts
+++ b/arch/arm/boot/dts/renesas/r8a7794-alt.dts
@@ -453,6 +453,7 @@ pmic at 58 {
 		interrupt-parent = <&gpio3>;
 		interrupts = <31 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-controller;
+		#interrupt-cells = <2>;
 
 		rtc {
 			compatible = "dlg,da9063-rtc";
diff --git a/arch/arm/boot/dts/renesas/r8a7794-silk.dts b/arch/arm/boot/dts/renesas/r8a7794-silk.dts
index 43d480a7f3eacc21..595e074085eb4cd3 100644
--- a/arch/arm/boot/dts/renesas/r8a7794-silk.dts
+++ b/arch/arm/boot/dts/renesas/r8a7794-silk.dts
@@ -439,6 +439,7 @@ pmic at 58 {
 		interrupt-parent = <&gpio3>;
 		interrupts = <31 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-controller;
+		#interrupt-cells = <2>;
 
 		onkey {
 			compatible = "dlg,da9063-onkey";
-- 
2.34.1



From kuba at kernel.org  Wed Feb 14 07:09:08 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Wed, 14 Feb 2024 07:09:08 -0800
Subject: [PATCH net-next] net: sparx5: Add spinlock for frame
 transmission from CPU
In-Reply-To: <20240214081442.w533wvcvqpvq5352@DEN-DL-M31836.microchip.com>
References: <20240213121705.4070598-1-horatiu.vultur@microchip.com>
	<5476743f-3648-4038-97f8-a9df22c0f507@gmail.com>
	<20240214081442.w533wvcvqpvq5352@DEN-DL-M31836.microchip.com>
Message-ID: <20240214070908.37b49ddf@kernel.org>

On Wed, 14 Feb 2024 09:14:42 +0100 Horatiu Vultur wrote:
> > Any reason you targeted 'net-next' rather than 'net', as this appears to
> > be clearly a bug fix here?  
> 
> Yes, it is a bug but it is not something that happens all the
> time and I thought this fits more into the lines of 'This could be a
> problem ...' therefore I had targeted 'net-next'.
> But if you consider that I should target 'net' instead of 'net-next' I
> can do that.

Definitely a bug fix worthy of net, yes, please.


From ardb at kernel.org  Wed Feb 14 07:23:18 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 14 Feb 2024 16:23:18 +0100
Subject: [PATCH 2/4] ARM: Move asm statements accessing TTBCR into C functions
In-Reply-To: <20240123-arm32-lpae-pan-v1-2-7ea98a20514c@linaro.org>
References: <20240123-arm32-lpae-pan-v1-0-7ea98a20514c@linaro.org> <20240123-arm32-lpae-pan-v1-2-7ea98a20514c@linaro.org>
Message-ID: <CAMj1kXGL_FLBuSCQpBsJt_2cJRS0+L1m-sdSuZZ_m1D0=57Tmg@mail.gmail.com>

On Tue, 23 Jan 2024 at 22:16, Linus Walleij <linus.walleij at linaro.org> wrote:
>
> From: Catalin Marinas <catalin.marinas at arm.com>
>
> This patch implements cpu_get_ttbcr() and cpu_set_ttbcr() and replaces
> the corresponding asm statements.
>
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> Reviewed-by: Kees Cook <keescook at chromium.org>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
>  arch/arm/include/asm/proc-fns.h | 12 ++++++++++++
>  arch/arm/mm/mmu.c               |  7 +++----
>  2 files changed, 15 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
> index 280396483f5d..a13e5cf3d1ff 100644
> --- a/arch/arm/include/asm/proc-fns.h
> +++ b/arch/arm/include/asm/proc-fns.h
> @@ -178,6 +178,18 @@ extern void cpu_resume(void);
>         })
>  #endif
>
> +static inline unsigned int cpu_get_ttbcr(void)
> +{
> +       unsigned int ttbcr;
> +       asm("mrc p15, 0, %0, c2, c0, 2" : "=r" (ttbcr));
> +       return ttbcr;
> +}
> +
> +static inline void cpu_set_ttbcr(unsigned int ttbcr)
> +{
> +       asm volatile("mcr p15, 0, %0, c2, c0, 2" : : "r" (ttbcr));

Nit: the 'volatile' is unnecessary here - there are no output
operands, so the compiler has to assume that the statement has side
effects.

> +}
> +
>  #else  /*!CONFIG_MMU */
>
>  #define cpu_switch_mm(pgd,mm)  { }
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index 674ed71573a8..9a780da6a4e1 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -1687,9 +1687,8 @@ static void __init early_paging_init(const struct machine_desc *mdesc)
>          */
>         cr = get_cr();
>         set_cr(cr & ~(CR_I | CR_C));
> -       asm("mrc p15, 0, %0, c2, c0, 2" : "=r" (ttbcr));
> -       asm volatile("mcr p15, 0, %0, c2, c0, 2"
> -               : : "r" (ttbcr & ~(3 << 8 | 3 << 10)));
> +       ttbcr = cpu_get_ttbcr();
> +       cpu_set_ttbcr(ttbcr & ~(3 << 8 | 3 << 10));
>         flush_cache_all();
>
>         /*
> @@ -1701,7 +1700,7 @@ static void __init early_paging_init(const struct machine_desc *mdesc)
>         lpae_pgtables_remap(offset, pa_pgd);
>
>         /* Re-enable the caches and cacheable TLB walks */
> -       asm volatile("mcr p15, 0, %0, c2, c0, 2" : : "r" (ttbcr));
> +       cpu_set_ttbcr(ttbcr);
>         set_cr(cr);
>  }
>
>
> --
> 2.34.1
>


From robh at kernel.org  Wed Feb 14 07:32:07 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 14 Feb 2024 15:32:07 +0000
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename qcom,dsb-element-size
In-Reply-To: <162256e1-416f-46ea-9698-9de507768cb0@quicinc.com>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
 <20240213160521.15925-2-quic_jinlmao@quicinc.com> <20240213222957.GA2502642-robh@kernel.org>
 <a062ce8d-638a-4a33-8afa-45ad47efcd72@quicinc.com> <df3162c0-4b29-77a2-20b5-b36637fb11cf@arm.com>
 <162256e1-416f-46ea-9698-9de507768cb0@quicinc.com>
Message-ID: <CAL_JsqL2aQw4zoLjvZq-M2_Sb8Q5KkAOcgfGOL2yf9ngixh3+A@mail.gmail.com>

On Wed, Feb 14, 2024 at 8:18?AM Jinlong Mao <quic_jinlmao at quicinc.com> wrote:
>
>
> On 2/14/2024 5:36 PM, James Clark wrote:
> >
> > On 14/02/2024 01:43, Jinlong Mao wrote:
> >> On 2/14/2024 6:29 AM, Rob Herring wrote:
> >>> On Tue, Feb 13, 2024 at 08:05:17AM -0800, Mao Jinlong wrote:
> >>>> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
> >>>> bit.
> >>> That may be, but this is an ABI and you are stuck with it. Unless, you
> >>> can justify why that doesn't matter. (IIRC, this is new, so maybe no
> >>> users yet?)
> >> Hi Rob,
> >>
> >> Because for CMB type, it uses qcom,cmb-element-bits. So I change the
> >> format to be the same as
> >> CMB.
> >>
> >> Thanks
> >> Jinlong Mao
> >>
> > I think what Rob was trying to say was that in the interest of not
> > breaking existing DTs it's best to leave the existing names as they are,
> > even if they aren't technically correct. And to only add new parameters
> > with the -bits suffix, even if it's inconsistent with what's already there.
>
> Hi Rob & James,
>
> There is no tpdm nodes in any DT as of now. So I want to make this
> change before any tpdm
> node is added in DT.

Then the commit msg needs to state that detail.

Rob


From gregkh at linuxfoundation.org  Wed Feb 14 07:34:17 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 14 Feb 2024 16:34:17 +0100
Subject: [PATCH 4/9] PCI: create platform devices for child OF
 nodes of the port node
In-Reply-To: <CAMRc=MeWgp27YcS=-dbYdN1is1MEuZ2ar=pW_p9oY0Nf1EbFHA@mail.gmail.com>
References: <20240117160748.37682-1-brgl@bgdev.pl>
 <20240117160748.37682-5-brgl@bgdev.pl>
 <2024011707-alibi-pregnancy-a64b@gregkh>
 <CAMRc=Mef7wxRccnfQ=EDLckpb1YN4DNLoC=AYL8v1LLJ=uFH2Q@mail.gmail.com>
 <2024011836-wok-treadmill-c517@gregkh>
 <d2he3ufg6m46zos4swww4t3peyq55blxhirsx37ou37rwqxmz2@5khumvic62je>
 <CAMRc=MeXJjpJhDjyn_P-SGo4rDnEuT9kGN5jAbRcuM_c7_aDzQ@mail.gmail.com>
 <oiwvcvu6wdmpvhss3t7uaqkl5q73mki5pz6liuv66bap4dr2mp@jtjjwzlvt6za>
 <CAMRc=McT8wt6UbKtyofkJo3WcyJ-S4d2MPp8oZmjWbX6LGbETQ@mail.gmail.com>
 <CAMRc=MeWgp27YcS=-dbYdN1is1MEuZ2ar=pW_p9oY0Nf1EbFHA@mail.gmail.com>
Message-ID: <2024021413-grumbling-unlivable-c145@gregkh>

On Wed, Feb 07, 2024 at 05:32:38PM +0100, Bartosz Golaszewski wrote:
> On Fri, Feb 2, 2024 at 11:02?AM Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> >
> > On Fri, Feb 2, 2024 at 1:03?AM Bjorn Andersson <andersson at kernel.org> wrote:
> > >
> >
> > [snip]
> >
> > > > >
> > > > > I believe I missed this part of the discussion, why does this need to be
> > > > > a platform_device? What does the platform_bus bring that can't be
> > > > > provided by some other bus?
> > > > >
> > > >
> > > > Does it need to be a platform_device? No, of course not. Does it make
> > > > sense for it to be one? Yes, for two reasons:
> > > >
> > > > 1. The ATH11K WLAN module is represented on the device tree like a
> > > > platform device, we know it's always there and it consumes regulators
> > > > from another platform device. The fact it uses PCIe doesn't change the
> > > > fact that it is logically a platform device.
> > >
> > > Are you referring to the ath11k SNOC (firmware running on co-processor
> > > in the SoC) variant?
> > >
> > > Afaict the PCIe-attached ath11k is not represented as a platform_device
> > > in DeviceTree.
> > >
> >
> > My bad. In RB5 it isn't (yet - I want to add it in the power
> > sequencing series). It is in X13s though[1].
> >
> > > Said platform_device is also not a child under the PCIe bus, so this
> > > would be a different platform_device...
> > >
> >
> > It's the child of the PCIe port node but there's a reason for it to
> > have the `compatible` property. It's because it's an entity of whose
> > existence we are aware before the system boots.
> >
> > > > 2. The platform bus already provides us with the entire infrastructure
> > > > that we'd now need to duplicate (possibly adding bugs) in order to
> > > > introduce a "power sequencing bus".
> > > >
> > >
> > > This is a perfectly reasonable desire. Look at our PMICs, they are full
> > > of platform_devices. But through the years it's been said many times,
> > > that this is not a valid or good reason for using platform_devices, and
> > > as a result we have e.g. auxiliary bus.
> > >
> >
> > Ok, so I cannot find this information anywhere (nor any example). Do
> > you happen to know if the auxiliary bus offers any software node
> > integration so that the `compatible` property from DT can get
> > seamlessly mapped to auxiliary device IDs?
> >
> 
> So I was just trying to port this to using the auxiliary bus, only to
> find myself literally reimplementing functions from
> drivers/of/device.c. I have a feeling that this is simply wrong. If
> we're instantiating devices well defined on the device-tree then IMO
> we *should* make them platform devices. Anything else and we'll be
> reimplementing drivers/of/ because we will need to parse the device
> nodes, check the compatible, match it against drivers etc. Things that
> are already implemented for the platform bus and of_* APIs.
> 
> Greg: Could you chime in and confirm that it's alright to use the
> platform bus here? Or maybe there is some infrastructure to create
> auxiliary devices from software nodes?

Note, I HATE the use of the platform bus here, but I don't have a better
suggestion.

I'd love for the auxbus to work, and if you can create that from
software nodes, all the better!  But I don't think that's possible just
yet, and you would end up implementing all the same stuff that the
platform bus has today for this functionality, so I doubt it would be
worth it.

thanks,

greg k-h


From krzysztof.kozlowski at linaro.org  Wed Feb 14 07:44:20 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 14 Feb 2024 16:44:20 +0100
Subject: [PATCH V2 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible
 for MT7988
In-Reply-To: <20240214140454.6438-1-zajec5@gmail.com>
References: <20240214140454.6438-1-zajec5@gmail.com>
Message-ID: <1449b798-1486-47e9-b5fe-cf8e366b2e52@linaro.org>

On 14/02/2024 15:04, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7988 has on-SoC controller that can control up to 8 PWM interfaces. It
> differs from blocks on other SoCs (amount of PWMs & registers) so it
> needs its own compatible string.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From robh at kernel.org  Wed Feb 14 07:45:14 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 14 Feb 2024 15:45:14 +0000
Subject: [PATCH] ARM: dts: renesas: rcar-gen2: Add missing
 #interrupt-cells to DA9063 nodes
In-Reply-To: <a351e503ea97fb1af68395843f513925ff1bdf26.1707922460.git.geert+renesas@glider.be>
References: <a351e503ea97fb1af68395843f513925ff1bdf26.1707922460.git.geert+renesas@glider.be>
Message-ID: <CAL_Jsq+2Bfb20VUaoPDq-4=ebzCtm_rc96GYqYA7CykLOJMVMQ@mail.gmail.com>

On Wed, Feb 14, 2024 at 8:57?AM Geert Uytterhoeven
<geert+renesas at glider.be> wrote:
>
> make dtbs_check W=2:
>
>     arch/arm/boot/dts/renesas/r8a7790-lager.dts:444.11-458.5: Warning (interrupt_provider): /i2c-mux4/pmic at 58: Missing '#interrupt-cells' in interrupt provider
>     ...
>
> Fix this by adding the missing #interrupt-cells properties.
>
> Reported-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
> To be queued in renesas-devel for v6.9.
>
>  arch/arm/boot/dts/renesas/r8a7790-lager.dts   | 1 +
>  arch/arm/boot/dts/renesas/r8a7790-stout.dts   | 1 +
>  arch/arm/boot/dts/renesas/r8a7791-koelsch.dts | 1 +
>  arch/arm/boot/dts/renesas/r8a7791-porter.dts  | 1 +
>  arch/arm/boot/dts/renesas/r8a7792-blanche.dts | 1 +
>  arch/arm/boot/dts/renesas/r8a7793-gose.dts    | 1 +
>  arch/arm/boot/dts/renesas/r8a7794-alt.dts     | 1 +
>  arch/arm/boot/dts/renesas/r8a7794-silk.dts    | 1 +
>  8 files changed, 8 insertions(+)

Reviewed-by: Rob Herring <robh at kernel.org>


From devarsht at ti.com  Wed Feb 14 07:47:12 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Wed, 14 Feb 2024 21:17:12 +0530
Subject: [RFC PATCH 2/3] drm/tidss: Add support for display sharing
In-Reply-To: <qiqrhpqtnox47wj6az7t3fjp4vc6k32fw42tp5slqggrhe6utb@i7lkpaf3v3od>
References: <20240116134142.2092483-1-devarsht@ti.com>
 <20240116134142.2092483-3-devarsht@ti.com>
 <vgfzhamtiwkpdyk5ndagsb63subclinotoe6tsi3wu6z7454ec@igxfzjc5gyqm>
 <88018f5f-a7db-7278-e5c3-bb1dbf0e3f14@ti.com>
 <qiqrhpqtnox47wj6az7t3fjp4vc6k32fw42tp5slqggrhe6utb@i7lkpaf3v3od>
Message-ID: <2f4cf2a7-ce7a-bb34-f722-7e66ea41def7@ti.com>

Hi Maxime,

Thanks for the quick reply.

On 13/02/24 19:34, Maxime Ripard wrote:
> Hi Devarsh,
> 
> On Thu, Feb 08, 2024 at 06:26:17PM +0530, Devarsh Thakkar wrote:
>> Hi Maxime,
>>
>> Thanks a lot for checking on this.
>>
>> On 26/01/24 17:45, Maxime Ripard wrote:
>>> Hi,
>>>
>>> Thanks a lot for working on that.
>>>
>>> On Tue, Jan 16, 2024 at 07:11:41PM +0530, Devarsh Thakkar wrote:
>>>> Display subsystem present in TI Keystone family of devices supports sharing
>>>> of display between multiple hosts as it provides separate register space
>>>> (common* region) for each host to programming display controller and also a
>>>> unique interrupt line for each host.
>>>>
>>>> This adds support for display sharing, by allowing partitioning of
>>>> resources either at video port level or at video plane level as
>>>> described below :
>>>>
>>>> 1) Linux can own (i.e have write access) completely one or more of video
>>>> ports along with corresponding resources (viz. overlay managers,
>>>> video planes) used by Linux in context of those video ports.
>>>> Even if Linux is owning
>>>> these video ports it can still share this video port with a remote core
>>>> which can own one or more video planes associated with this video port.
>>>>
>>>> 2) Linux owns one or more of the video planes with video port
>>>> (along with corresponding overlay manager) associated with these planes
>>>> being owned and controlled by a remote core. Linux still has read-only
>>>> access to the associated video port and overlay managers so that it can
>>>> parse the settings made by remote core.
>>>
>>> So, just to make sure we're on the same page. 1) means Linux drives the
>>> whole display engine, but can lend planes to the R5? How does that work,
>>> is Linux aware of the workload being there (plane size, format, etc) ?
>>>
>>
>> Well, there is no dynamic procedure being followed for lending. The
>> partitioning scheme is decided and known before hand, and the remote
>> core firmware updated and compiled accordingly, and similarly the
>> device-tree overlay for Linux is also updated with partitioning
>> information before bootup.
>>
>> What would happen here is that Linux will know before-hand this
>> partitioning information via device-tree properties and won't enumerate
>> the plane owned by RTOS, but it will enumerate the rest of the display
>> components and initialize the DSS, after which user can load the DSS
>> firmware on remote core and this firmware will only have control of
>> plane as it was compiled with that configuration.
> 
> Right. If the RTOS is in control of a single plane, how it is expected
> to deal with Linux shutting the CRTC down, or enforcing a configuration
> that isn't compatible with what the RTOS expects (like a plane with a
> higher zpos masking its plane), what is the mechanism to reconcile it?
> 

Just for the note, for this "RTOS control single plane" mode, we don't have a
firmware available to test (right now we are only supporting example for "RTOS
controlling the display mode" as shared here [1]) and hence this is not
validated but the idea was to keep dt-bindings generic enough to support them
in future and that's why I referred to it here.

Coming back to your questions, with the current scheme the Linux (tidss) would
be expected to make sure the CRTC being shared with RTOS is never shutdown and
the RTOS plane should never gets masked.

I think the IPC based scheme would have been mainly needed for the case where
you have a single entity controlling the display for e.g you have a single
display controller register space and a single IRQ but you have multiple
planes and say you want to divide these planes to different host processors.
In that case you want a single entity to act as a main entity and be in
control of DSS and rest of the processors communicate with the "main entity"
to request display resources and plane updates and main entity also programs
dss on their behalf.

But unlike above, TI DSS7 is designed to support static partitioning of
display resources among multiple hosts, where each host can program the
display hardware independently using separate register space and having a
separate irq and without requirement of any communication between the hosts.
Now as this feature is unique to TI DSS7 we want to support this feature in
tidss driver. The DSS resource partitioning feature is described in detail
here [2]

>>> And 2) would mean that the display engine is under the R5 control and
>>> Linux only gets to fill the plane and let the firmware know of what it
>>> wants?
>>>
>>
>> Here too the partitioning information is pre-decided and remote core
>> firmware and device-tree overlay for Linux updated accordingly. But in
>> this case as remote core firmware owns the display (minus the plane
>> owned by Linux) it is started and initialized during the bootloader
>> phase itself where it initializes the DSS and starts rendering using the
>> plane owned by it and Linux just latches to the DSS without
>> re-initializing it, with write access only to the plane that is owned by
>> Linux. You can refer [1] for more details on this.
>>
>>> If so, do we even need the tidss driver in the second case? We could
>>> just write a fwkms driver of some sorts that could be used by multiple
>>> implementations of the same "defer to firmware" logic.
>>>
>>
>> This feature of static partitioning of DSS resources is specific to DSS7
>> hardware (which is controlled by tidss driver) which supports dedicated
>> register space and interrupt line for each of the hosts [0], so that
>> multiple hosts can drive the display controller simultaneously as  per
>> the desired static partitioning of resources, and so I don't think a
>> separate driver is required here and tidss seems the right place to
>> support this, where using this device-tree approach different resource
>> partitioning schemas can be achieved as described here [1]. This was
>> also aligned with Tomi too where we discussed that tidss is the right
>> place to support this as we are simply leveraging the DSS hardware
>> capabilities of static partitioning here.
> 
> If the only thing tidss does in the "owned by RTOS" is forwarding KMS
> atomic states to the RTOS, then I'm still not sure why we need to
> involve tidss at all.
> 

I think maybe here is the point of misunderstanding. We are not forwarding
atomic states to RTOS here. Linux (tidss) is infact, accessing the display
register space assigned to it (common1 assigned to Linux, commmon0 assigned to
RTOS) and also writing to DSS plane registers for the plane assigned to it
(say VID assigned to Linux and VIDL assigned to RTOS).

> It's not just about interrupts, it's also about how your arbitrate
> between what Linux wants and what the RTOS wants. Like if the RTOS still
> wants to output something but Linux wants to disable it, how do you
> reconcile the two?
> 

The scheme involves static partitioning of display resource which are assigned
compile-time to RTOS and Linux. Here the RTOS firmware is compiled with
specific ownership/display resources as desired by user and this assignment
stays intact.

If there is a more complex use-case which requires dynamic
assignment/arbitration of resources then I agree those require some sort of
IPC scheme but this is not what we target with these series. This series is
simply to support static partitioning feature (separate register space,
separate irq, firewalling support etc) of TI DSS hardware across the multiple
hosts and there are use-cases too for which this scheme suffices.

> You have to have something that reconciles both, and typically for
> firmware-based setup this will be the firmware's job.
> 
> That's very similar to what the RaspberryPi did with fkms, and I believe
> that having a generic KMS-on-remoteproc driver when the firmware has
> control over the display is the path forward.
> 

The kms-on-remoteproc scheme is different and maybe more useful for those
processors not supporting this static partitioning hardware feature. On the
other hand, I believe there are still use-cases where this unique static
partitioning hardware feature of TI DSS will suffice without any requirement
of IPC. And it makes the firmware simpler (and the job of RTOS developer
easier too) as no IPC is required.

I am curious to understand Rpi DSS hardware and take a look at fkms and it's
firmware code though if it is public ?

>>>> For both the cases, the resources used in context of processing core
>>>> running Linux along with ownership information are exposed by user as
>>>> part of device-tree blob and driver uses an updated feature list tailored
>>>> for this shared mode accordingly. The driver also auto-populates
>>>> matching overlay managers and output types from shared video
>>>> port list provided in device-tree blob.
>>>> In dispc_feature struct remove const access specfier for output_type
>>>> array as it is required to be updated dynamically in run-time for shared
>>>> mode.
>>>
>>> I'm also not entirely sure that the device tree is the right path there.
>>> Surely the firmware capabilities will evolve over time, while the device
>>> tree won't. Is there some way to make it discoverable at probe time by
>>> the driver?
>>
>> I think the main highlight of the sharing feature is the hardware
>> capability where each host is provided separate irq and register space
>> to program display for their display context independently
> 
> Wait, what do you mean by display context here?
> 

By context I mean to what that specific host wants to display. For e.g. if
RTOS is owning a plane, then it can update it's framebuffer and update plane
registers independently.

[1]
https://software-dl.ti.com/processor-sdk-linux/esd/AM62PX/09_01_00_08/exports/docs/system/Demo_User_Guides/Display_Cluster_User_Guide.html
[2] https://www.ti.com/lit/zip/spruj52 ((Section 12.6.3.14 DISPC Resources
Sharing))

Regards
Devarsh

> Maxime


From krzysztof.kozlowski at linaro.org  Wed Feb 14 07:54:37 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 14 Feb 2024 16:54:37 +0100
Subject: [PATCH v2 1/2] dt-bindings: auxdisplay: adjust example indentation and use generic node names
Message-ID: <20240214155438.155139-1-krzysztof.kozlowski@linaro.org>

The example DTS should be indented with two or four (preferred) spaces,
as mentioned in Writing Schema document.  While re-indenting, change the
node names to somehow generic names, as expected by Devicetree
specification.

Cc: Geert Uytterhoeven <geert at linux-m68k.org>
Cc: Ralf Schlatterbeck <rsc at runtux.com>
Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---

Changes in v2:
1. Previous, removing GPIO expander node is gone, update GPIO expander
   example as well: node name and indentation.
---
 .../auxdisplay/arm,versatile-lcd.yaml         |  4 +-
 .../bindings/auxdisplay/hit,hd44780.yaml      | 62 ++++++++++---------
 .../bindings/auxdisplay/holtek,ht16k33.yaml   | 50 +++++++--------
 .../bindings/auxdisplay/img,ascii-lcd.yaml    |  4 +-
 4 files changed, 61 insertions(+), 59 deletions(-)

diff --git a/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml b/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml
index 5d02bd032a85..439f7b811a94 100644
--- a/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml
@@ -39,6 +39,6 @@ additionalProperties: false
 examples:
   - |
     lcd at 10008000 {
-            compatible = "arm,versatile-lcd";
-            reg = <0x10008000 0x1000>;
+        compatible = "arm,versatile-lcd";
+        reg = <0x10008000 0x1000>;
     };
diff --git a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
index 406a922a714e..e26d61af9011 100644
--- a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
@@ -84,42 +84,44 @@ additionalProperties: false
 examples:
   - |
     #include <dt-bindings/gpio/gpio.h>
-    auxdisplay {
-            compatible = "hit,hd44780";
+    display-controller {
+        compatible = "hit,hd44780";
 
-            data-gpios = <&hc595 0 GPIO_ACTIVE_HIGH>,
-                         <&hc595 1 GPIO_ACTIVE_HIGH>,
-                         <&hc595 2 GPIO_ACTIVE_HIGH>,
-                         <&hc595 3 GPIO_ACTIVE_HIGH>;
-            enable-gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
-            rs-gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
+        data-gpios = <&hc595 0 GPIO_ACTIVE_HIGH>,
+                     <&hc595 1 GPIO_ACTIVE_HIGH>,
+                     <&hc595 2 GPIO_ACTIVE_HIGH>,
+                     <&hc595 3 GPIO_ACTIVE_HIGH>;
+        enable-gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
+        rs-gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
 
-            display-height-chars = <2>;
-            display-width-chars = <16>;
+        display-height-chars = <2>;
+        display-width-chars = <16>;
     };
+
   - |
     #include <dt-bindings/gpio/gpio.h>
     i2c {
-            #address-cells = <1>;
-            #size-cells = <0>;
+        #address-cells = <1>;
+        #size-cells = <0>;
 
-            pcf8574: pcf8574 at 27 {
-                    compatible = "nxp,pcf8574";
-                    reg = <0x27>;
-                    gpio-controller;
-                    #gpio-cells = <2>;
-            };
+        pcf8574: gpio-expander at 27 {
+            compatible = "nxp,pcf8574";
+            reg = <0x27>;
+            gpio-controller;
+            #gpio-cells = <2>;
+        };
     };
-    hd44780 {
-            compatible = "hit,hd44780";
-            display-height-chars = <2>;
-            display-width-chars = <16>;
-            data-gpios = <&pcf8574 4 0>,
-                         <&pcf8574 5 0>,
-                         <&pcf8574 6 0>,
-                         <&pcf8574 7 0>;
-            enable-gpios = <&pcf8574 2 0>;
-            rs-gpios = <&pcf8574 0 0>;
-            rw-gpios = <&pcf8574 1 0>;
-            backlight-gpios = <&pcf8574 3 0>;
+
+    display-controller {
+        compatible = "hit,hd44780";
+        display-height-chars = <2>;
+        display-width-chars = <16>;
+        data-gpios = <&pcf8574 4 0>,
+                     <&pcf8574 5 0>,
+                     <&pcf8574 6 0>,
+                     <&pcf8574 7 0>;
+        enable-gpios = <&pcf8574 2 0>;
+        rs-gpios = <&pcf8574 0 0>;
+        rw-gpios = <&pcf8574 1 0>;
+        backlight-gpios = <&pcf8574 3 0>;
     };
diff --git a/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml b/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
index be95f6b97b41..b90eec2077b4 100644
--- a/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
@@ -74,31 +74,31 @@ examples:
     #include <dt-bindings/input/input.h>
     #include <dt-bindings/leds/common.h>
     i2c {
-            #address-cells = <1>;
-            #size-cells = <0>;
+        #address-cells = <1>;
+        #size-cells = <0>;
 
-            ht16k33: ht16k33 at 70 {
-                    compatible = "holtek,ht16k33";
-                    reg = <0x70>;
-                    refresh-rate-hz = <20>;
-                    interrupt-parent = <&gpio4>;
-                    interrupts = <5 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>;
-                    debounce-delay-ms = <50>;
-                    linux,keymap = <MATRIX_KEY(2, 0, KEY_F6)>,
-                                   <MATRIX_KEY(3, 0, KEY_F8)>,
-                                   <MATRIX_KEY(4, 0, KEY_F10)>,
-                                   <MATRIX_KEY(5, 0, KEY_F4)>,
-                                   <MATRIX_KEY(6, 0, KEY_F2)>,
-                                   <MATRIX_KEY(2, 1, KEY_F5)>,
-                                   <MATRIX_KEY(3, 1, KEY_F7)>,
-                                   <MATRIX_KEY(4, 1, KEY_F9)>,
-                                   <MATRIX_KEY(5, 1, KEY_F3)>,
-                                   <MATRIX_KEY(6, 1, KEY_F1)>;
+        display-controller at 70 {
+            compatible = "holtek,ht16k33";
+            reg = <0x70>;
+            refresh-rate-hz = <20>;
+            interrupt-parent = <&gpio4>;
+            interrupts = <5 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>;
+            debounce-delay-ms = <50>;
+            linux,keymap = <MATRIX_KEY(2, 0, KEY_F6)>,
+                           <MATRIX_KEY(3, 0, KEY_F8)>,
+                           <MATRIX_KEY(4, 0, KEY_F10)>,
+                           <MATRIX_KEY(5, 0, KEY_F4)>,
+                           <MATRIX_KEY(6, 0, KEY_F2)>,
+                           <MATRIX_KEY(2, 1, KEY_F5)>,
+                           <MATRIX_KEY(3, 1, KEY_F7)>,
+                           <MATRIX_KEY(4, 1, KEY_F9)>,
+                           <MATRIX_KEY(5, 1, KEY_F3)>,
+                           <MATRIX_KEY(6, 1, KEY_F1)>;
 
-                    led {
-                            color = <LED_COLOR_ID_RED>;
-                            function = LED_FUNCTION_BACKLIGHT;
-                            linux,default-trigger = "backlight";
-                    };
+            led {
+                color = <LED_COLOR_ID_RED>;
+                function = LED_FUNCTION_BACKLIGHT;
+                linux,default-trigger = "backlight";
             };
-      };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/auxdisplay/img,ascii-lcd.yaml b/Documentation/devicetree/bindings/auxdisplay/img,ascii-lcd.yaml
index 1899b23de7d1..55e9831b3f67 100644
--- a/Documentation/devicetree/bindings/auxdisplay/img,ascii-lcd.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/img,ascii-lcd.yaml
@@ -50,6 +50,6 @@ additionalProperties: false
 examples:
   - |
     lcd: lcd at 17fff000 {
-            compatible = "img,boston-lcd";
-            reg = <0x17fff000 0x8>;
+        compatible = "img,boston-lcd";
+        reg = <0x17fff000 0x8>;
     };
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Wed Feb 14 07:54:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 14 Feb 2024 16:54:38 +0100
Subject: [PATCH v2 2/2] dt-bindings: auxdisplay: hit,hd44780: use defines for GPIO flags
In-Reply-To: <20240214155438.155139-1-krzysztof.kozlowski@linaro.org>
References: <20240214155438.155139-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240214155438.155139-2-krzysztof.kozlowski@linaro.org>

Improve example DTS readability by using known defines for GPIO flags.

Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---

Changes in v2:
1. None
---
 .../bindings/auxdisplay/hit,hd44780.yaml         | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
index e26d61af9011..3ca0e9863d83 100644
--- a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml
@@ -116,12 +116,12 @@ examples:
         compatible = "hit,hd44780";
         display-height-chars = <2>;
         display-width-chars = <16>;
-        data-gpios = <&pcf8574 4 0>,
-                     <&pcf8574 5 0>,
-                     <&pcf8574 6 0>,
-                     <&pcf8574 7 0>;
-        enable-gpios = <&pcf8574 2 0>;
-        rs-gpios = <&pcf8574 0 0>;
-        rw-gpios = <&pcf8574 1 0>;
-        backlight-gpios = <&pcf8574 3 0>;
+        data-gpios = <&pcf8574 4 GPIO_ACTIVE_HIGH>,
+                     <&pcf8574 5 GPIO_ACTIVE_HIGH>,
+                     <&pcf8574 6 GPIO_ACTIVE_HIGH>,
+                     <&pcf8574 7 GPIO_ACTIVE_HIGH>;
+        enable-gpios = <&pcf8574 2 GPIO_ACTIVE_HIGH>;
+        rs-gpios = <&pcf8574 0 GPIO_ACTIVE_HIGH>;
+        rw-gpios = <&pcf8574 1 GPIO_ACTIVE_HIGH>;
+        backlight-gpios = <&pcf8574 3 GPIO_ACTIVE_HIGH>;
     };
-- 
2.34.1



From suzuki.poulose at arm.com  Wed Feb 14 07:56:05 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 14 Feb 2024 15:56:05 +0000
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename
 qcom,dsb-element-size
In-Reply-To: <20240213222957.GA2502642-robh@kernel.org>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
 <20240213160521.15925-2-quic_jinlmao@quicinc.com>
 <20240213222957.GA2502642-robh@kernel.org>
Message-ID: <c70df5a6-20af-4cee-b147-5847751fa36b@arm.com>

On 13/02/2024 22:29, Rob Herring wrote:
> On Tue, Feb 13, 2024 at 08:05:17AM -0800, Mao Jinlong wrote:
>> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
>> bit.
> 
> That may be, but this is an ABI and you are stuck with it. Unless, you
> can justify why that doesn't matter. (IIRC, this is new, so maybe no
> users yet?)

This was added and support queued in v6.8. This change won't make it to 
v6.8 (given it has to go via two levels and is technically not a fix).

As James also pointed out, it doesn't matter what the name is (now that
it has been published).

Suzuki



From angelogioacchino.delregno at collabora.com  Wed Feb 14 07:57:21 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 14 Feb 2024 16:57:21 +0100
Subject: [PATCH V2 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible
 for MT7988
In-Reply-To: <20240214140454.6438-1-zajec5@gmail.com>
References: <20240214140454.6438-1-zajec5@gmail.com>
Message-ID: <137bc832-80fe-4dec-bbe5-caca2c1c5b97@collabora.com>

Il 14/02/24 15:04, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7988 has on-SoC controller that can control up to 8 PWM interfaces. It
> differs from blocks on other SoCs (amount of PWMs & registers) so it
> needs its own compatible string.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Wed Feb 14 07:57:22 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 14 Feb 2024 16:57:22 +0100
Subject: [PATCH V2 2/2] pwm: mediatek: add support for MT7988
In-Reply-To: <20240214140454.6438-2-zajec5@gmail.com>
References: <20240214140454.6438-1-zajec5@gmail.com>
 <20240214140454.6438-2-zajec5@gmail.com>
Message-ID: <f5998e7c-674b-4ee5-b25f-d280db2f912d@collabora.com>

Il 14/02/24 15:04, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7988 uses new registers layout just like MT7981 but it supports 8 PWM
> interfaces.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From geert at linux-m68k.org  Wed Feb 14 08:02:41 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 17:02:41 +0100
Subject: [PATCH v2 1/2] dt-bindings: auxdisplay: adjust example
 indentation and use generic node names
In-Reply-To: <20240214155438.155139-1-krzysztof.kozlowski@linaro.org>
References: <20240214155438.155139-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CAMuHMdUOS5eXgJtbkZe3crVp0R0OC6Bug2LJskT1pSgkkTaQtA@mail.gmail.com>

On Wed, Feb 14, 2024 at 4:54?PM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
> The example DTS should be indented with two or four (preferred) spaces,
> as mentioned in Writing Schema document.  While re-indenting, change the
> node names to somehow generic names, as expected by Devicetree
> specification.
>
> Cc: Geert Uytterhoeven <geert at linux-m68k.org>
> Cc: Ralf Schlatterbeck <rsc at runtux.com>
> Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>
> Changes in v2:
> 1. Previous, removing GPIO expander node is gone, update GPIO expander
>    example as well: node name and indentation.

Reviewed-by: Geert Uytterhoeven <geert at linux-m68k.org>

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 robh at kernel.org  Wed Feb 14 08:03:34 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 14 Feb 2024 16:03:34 +0000
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename qcom,dsb-element-size
In-Reply-To: <c70df5a6-20af-4cee-b147-5847751fa36b@arm.com>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
 <20240213160521.15925-2-quic_jinlmao@quicinc.com> <20240213222957.GA2502642-robh@kernel.org>
 <c70df5a6-20af-4cee-b147-5847751fa36b@arm.com>
Message-ID: <CAL_JsqKdAzPEGh941S05kraTjOcEpsPCnDRkppNkb8pBCpZu6g@mail.gmail.com>

On Wed, Feb 14, 2024 at 9:56?AM Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>
> On 13/02/2024 22:29, Rob Herring wrote:
> > On Tue, Feb 13, 2024 at 08:05:17AM -0800, Mao Jinlong wrote:
> >> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
> >> bit.
> >
> > That may be, but this is an ABI and you are stuck with it. Unless, you
> > can justify why that doesn't matter. (IIRC, this is new, so maybe no
> > users yet?)
>
> This was added and support queued in v6.8. This change won't make it to
> v6.8 (given it has to go via two levels and is technically not a fix).

I'd argue it is a fix. But given no users yet, delaying is fine.

> As James also pointed out, it doesn't matter what the name is (now that
> it has been published).

v6.8 final is what we consider published.

Rob


From geert at linux-m68k.org  Wed Feb 14 08:03:57 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 17:03:57 +0100
Subject: [PATCH v2 2/2] dt-bindings: auxdisplay: hit,hd44780: use defines
 for GPIO flags
In-Reply-To: <20240214155438.155139-2-krzysztof.kozlowski@linaro.org>
References: <20240214155438.155139-1-krzysztof.kozlowski@linaro.org> <20240214155438.155139-2-krzysztof.kozlowski@linaro.org>
Message-ID: <CAMuHMdVqOecSzjPqGiQ6t--o55NmY+BfA6KfGrDkt6Xx-nj8Jw@mail.gmail.com>

On Wed, Feb 14, 2024 at 4:54?PM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
> Improve example DTS readability by using known defines for GPIO flags.
>
> Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>
> Changes in v2:
> 1. None

Reviewed-by: Geert Uytterhoeven <geert at linux-m68k.org>

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 geert at linux-m68k.org  Wed Feb 14 08:16:45 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 17:16:45 +0100
Subject: [PATCH v2 6/6] mfd: tmio: Move header to platform_data
In-Reply-To: <20240213220221.2380-14-wsa+renesas@sang-engineering.com>
References: <20240213220221.2380-8-wsa+renesas@sang-engineering.com> <20240213220221.2380-14-wsa+renesas@sang-engineering.com>
Message-ID: <CAMuHMdV6oh4x4LQKu7-UTMU+g1WGnUehyN+vJcGug2EZFuyf7w@mail.gmail.com>

On Tue, Feb 13, 2024 at 11:04?PM Wolfram Sang
<wsa+renesas at sang-engineering.com> wrote:
> All the MFD components are gone from the header meanwhile. Only the MMC
> relevant data is left which makes it a platform_data for the MMC
> controller. Move the header to the now fitting directory.
>
> Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
> Acked-by: Lee Jones <lee at kernel.org>
> Acked-by: Ulf Hansson <ulf.hansson at linaro.org> # For MMC
> Acked-by: John Paul Adrian Glaubitz <glaubitz at physik.fu-berlin.de>

Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>

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 suzuki.poulose at arm.com  Wed Feb 14 08:18:33 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 14 Feb 2024 16:18:33 +0000
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename
 qcom,dsb-element-size
In-Reply-To: <CAL_JsqKdAzPEGh941S05kraTjOcEpsPCnDRkppNkb8pBCpZu6g@mail.gmail.com>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
 <20240213160521.15925-2-quic_jinlmao@quicinc.com>
 <20240213222957.GA2502642-robh@kernel.org>
 <c70df5a6-20af-4cee-b147-5847751fa36b@arm.com>
 <CAL_JsqKdAzPEGh941S05kraTjOcEpsPCnDRkppNkb8pBCpZu6g@mail.gmail.com>
Message-ID: <729a4c17-9e86-467f-85cf-652c503fa14e@arm.com>

On 14/02/2024 16:03, Rob Herring wrote:
> On Wed, Feb 14, 2024 at 9:56?AM Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>>
>> On 13/02/2024 22:29, Rob Herring wrote:
>>> On Tue, Feb 13, 2024 at 08:05:17AM -0800, Mao Jinlong wrote:
>>>> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
>>>> bit.
>>>
>>> That may be, but this is an ABI and you are stuck with it. Unless, you
>>> can justify why that doesn't matter. (IIRC, this is new, so maybe no
>>> users yet?)
>>
>> This was added and support queued in v6.8. This change won't make it to
>> v6.8 (given it has to go via two levels and is technically not a fix).
> 
> I'd argue it is a fix. But given no users yet, delaying is fine.

I agree it is a fix, but not something that maintainers would like to
pull it during an rc cycle. As you said, since there are no real users
for this yet (and given it is all under a single vendor), it may be fine
to queue this if the DT maintainers are OK with this.


> 
>> As James also pointed out, it doesn't matter what the name is (now that
>> it has been published).
> 
> v6.8 final is what we consider published.

I can't send this to Greg as a fix. For v6.8. We can fix it for v6.9 cycle.

Suzuki
> 
> Rob



From theo.lebrun at bootlin.com  Wed Feb 14 08:23:56 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:23:56 +0100
Subject: [PATCH 03/23] dt-bindings: gpio: nomadik: add mobileye,eyeq5-gpio
 compatible
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-3-f88c0ccf372b@bootlin.com>

This GPIO controller is used on the Mobileye EyeQ5 SoC. Add its
compatible to the dt-bindings. One difference is that the block as
integrated on EyeQ5 does not support sleep-mode.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 .../devicetree/bindings/gpio/st,nomadik-gpio.yaml        | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
index bbd23daed229..e44cf292bc6d 100644
--- a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
@@ -19,7 +19,9 @@ properties:
     pattern: "^gpio@[0-9a-f]+$"
 
   compatible:
-    const: st,nomadik-gpio
+    enum:
+      - st,nomadik-gpio
+      - mobileye,eyeq5-gpio
 
   reg:
     maxItems: 1
@@ -65,6 +67,18 @@ required:
 
 unevaluatedProperties: false
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: st,nomadik-gpio
+    then:
+      properties:
+        st,supports-sleepmode:
+          description: Whether the controller can sleep or not.
+          $ref: /schemas/types.yaml#/definitions/flag
+
 examples:
   - |
     gpio1: gpio at 8012e080 {

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:23:55 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:23:55 +0100
Subject: [PATCH 02/23] dt-bindings: gpio: nomadik: add optional ngpios
 property
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-2-f88c0ccf372b@bootlin.com>

This GPIO controller can support a lesser number of GPIOs than 32.
Express that in devicetree using an optional, generic property.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
index a999908173d2..bbd23daed229 100644
--- a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
@@ -50,6 +50,10 @@ properties:
   gpio-ranges:
     maxItems: 1
 
+  ngpios:
+    minimum: 0
+    maximum: 32
+
 required:
   - compatible
   - reg

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:23:54 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:23:54 +0100
Subject: [PATCH 01/23] dt-bindings: gpio: nomadik: convert into yaml format
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-1-f88c0ccf372b@bootlin.com>

Create gpio/st,nomadik-gpio.yaml json-schema dt-bindings file as a
direct translation from gpio-nmk.txt. Remove the txt file.

Add clocks and gpio-ranges properties which were missing and are being
used in Nomadik devicetrees.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 .../devicetree/bindings/gpio/gpio-nmk.txt          | 31 ---------
 .../devicetree/bindings/gpio/st,nomadik-gpio.yaml  | 75 ++++++++++++++++++++++
 MAINTAINERS                                        |  1 +
 3 files changed, 76 insertions(+), 31 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/gpio-nmk.txt b/Documentation/devicetree/bindings/gpio/gpio-nmk.txt
deleted file mode 100644
index 8315ac7780ef..000000000000
--- a/Documentation/devicetree/bindings/gpio/gpio-nmk.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-Nomadik GPIO controller
-
-Required properties:
-- compatible            : Should be "st,nomadik-gpio".
-- reg                   : Physical base address and length of the controller's registers.
-- interrupts            : The interrupt outputs from the controller.
-- #gpio-cells           : Should be two:
-                            The first cell is the pin number.
-                            The second cell is used to specify optional parameters:
-                              - bits[3:0] trigger type and level flags:
-                                  1 = low-to-high edge triggered.
-                                  2 = high-to-low edge triggered.
-                                  4 = active high level-sensitive.
-                                  8 = active low level-sensitive.
-- gpio-controller       : Marks the device node as a GPIO controller.
-- interrupt-controller  : Marks the device node as an interrupt controller.
-- gpio-bank             : Specifies which bank a controller owns.
-- st,supports-sleepmode : Specifies whether controller can sleep or not
-
-Example:
-
-                gpio1: gpio at 8012e080 {
-                        compatible = "st,nomadik-gpio";
-                        reg =  <0x8012e080 0x80>;
-                        interrupts = <0 120 0x4>;
-                        #gpio-cells = <2>;
-                        gpio-controller;
-                        interrupt-controller;
-                        st,supports-sleepmode;
-                        gpio-bank = <1>;
-                };
diff --git a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
new file mode 100644
index 000000000000..a999908173d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/st,nomadik-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nomadik GPIO controller
+
+description:
+  The Nomadik GPIO driver handles Nomadik SoC GPIO blocks. This block has also
+  been called ST STA2X11. On the Nomadik platform, this driver is intertwined
+  with pinctrl-nomadik.
+
+maintainers:
+  - Linus Walleij <linus.walleij at linaro.org>
+
+properties:
+  $nodename:
+    pattern: "^gpio@[0-9a-f]+$"
+
+  compatible:
+    const: st,nomadik-gpio
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  "#gpio-cells":
+    const: 2
+
+  gpio-controller: true
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+  gpio-bank:
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  st,supports-sleepmode:
+    description: Whether the controller can sleep or not.
+    $ref: /schemas/types.yaml#/definitions/flag
+
+  clocks:
+    maxItems: 1
+
+  gpio-ranges:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - "#gpio-cells"
+  - gpio-controller
+  - interrupt-controller
+  - gpio-bank
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    gpio1: gpio at 8012e080 {
+        compatible = "st,nomadik-gpio";
+        reg =  <0x8012e080 0x80>;
+        interrupts = <0 120 0x4>;
+        #gpio-cells = <2>;
+        gpio-controller;
+        interrupt-controller;
+        st,supports-sleepmode;
+        gpio-bank = <1>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 9134384171fe..0cb2c459d1cf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2465,6 +2465,7 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
 F:	Documentation/devicetree/bindings/arm/ste-*
 F:	Documentation/devicetree/bindings/arm/ux500.yaml
 F:	Documentation/devicetree/bindings/arm/ux500/
+F:	Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
 F:	Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
 F:	arch/arm/boot/dts/st/ste-*
 F:	arch/arm/mach-nomadik/

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:23:53 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:23:53 +0100
Subject: [PATCH 00/23] Rework Nomadik GPIO to add Mobileye EyeQ5 support
Message-ID: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>

Hi,

This patch series reworks the Nomadik GPIO driver to bring it up to date
to current kernel standards. We then add Mobileye EyeQ5 support that
uses the same IP block but with limited functionality. We also add
features required by our newly supported platform:

 - Dynamic GPIO ID allocation;
 - Make clock optional;
 - Shared IRQ (usecase: EyeQ5 has two banks using the same IRQ);
 - Handle variadic GPIO counts (usecase: EyeQ5 has <32 GPIOs per bank);
 - Grab optional reset at probe (usecase: EyeQ5 has a reset available).

This GPIO platform driver was previously declared & registered inside
drivers/pinctrl/nomadik/pinctrl-nomadik.c, side-by-side with the
pinctrl driver. Both are tightly integrated, mostly for muxing reasons.
Now that gpio-nomadik is used for another platform, we loosen the
relationship. The behavior should not change on already supported
hardware but I do not have Nomadik hardware to test for that.

We have some dependencies, kept neatly to the end. Those are:
- The base platform support series from Gr?gory [1]. This relates to the
  last four patches (20 thru 23), ie defconfig and devicetree.
- The OLB syscon support series [0]. It provides reset and pinctrl nodes
  inside the devicetree. This relates to the last two patches (22 and
  23), ie resets and gpio-ranges DT props. GPIO works fine without it
  if patches 22 and 23 are dropped.

This has been tested on the EyeQ5 hardware, with the two parent series
applied. It also works fine without the OLB syscon series when our last
two patches are removed. It has been built on both Arm defconfigs that
rely on pinctrl-nomadik: nhk8815_defconfig and u8500_defconfig. I don't
have any Nomadik hardware to test though.

Have a nice day,
Th?o

[0]: https://lore.kernel.org/lkml/20240212-mbly-clk-v6-0-c46fa1f93839 at bootlin.com/
[1]: https://lore.kernel.org/lkml/20240205153503.574468-1-gregory.clement at bootlin.com/

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
Th?o Lebrun (23):
      dt-bindings: gpio: nomadik: convert into yaml format
      dt-bindings: gpio: nomadik: add optional ngpios property
      dt-bindings: gpio: nomadik: add mobileye,eyeq5-gpio compatible
      dt-bindings: gpio: nomadik: add optional reset property
      gpio: nomadik: extract GPIO platform driver from drivers/pinctrl/nomadik/
      pinctrl: nomadik: fix build warning (-Wformat)
      pinctrl: nomadik: fix build warning (-Wpointer-to-int-cast)
      pinctrl: nomadik: minimise indentation in probe
      pinctrl: nomadik: follow type-system kernel coding conventions
      pinctrl: nomadik: follow whitespace kernel coding conventions
      pinctrl: nomadik: follow conditional kernel coding conventions
      gpio: nomadik: request dynamic ID allocation
      gpio: nomadik: fix offset bug in nmk_pmx_set()
      gpio: nomadik: make clock optional
      gpio: nomadik: change driver name from gpio to gpio-nomadik
      gpio: nomadik: support shared GPIO IRQs
      gpio: nomadik: handle variadic GPIO count
      gpio: nomadik: support mobileye,eyeq5-gpio
      gpio: nomadik: grab optional reset control and deassert it at probe
      MIPS: eyeq5_defconfig: enable GPIO by default
      MIPS: mobileye: eyeq5: add two GPIO bank nodes
      MIPS: mobileye: eyeq5: add resets to GPIO banks
      MIPS: mobileye: eyeq5: map GPIOs to pins using gpio-ranges

 .../devicetree/bindings/gpio/gpio-nmk.txt          |  31 -
 .../devicetree/bindings/gpio/st,nomadik-gpio.yaml  |  96 +++
 MAINTAINERS                                        |   2 +
 arch/mips/boot/dts/mobileye/eyeq5.dtsi             |  30 +
 arch/mips/configs/eyeq5_defconfig                  |   2 +
 drivers/gpio/Kconfig                               |  13 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-nomadik.c                        | 725 ++++++++++++++++
 drivers/pinctrl/nomadik/Kconfig                    |   5 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c   |   3 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c  |   3 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik.c          | 938 +++------------------
 .../linux/gpio/gpio-nomadik.h                      | 124 ++-
 13 files changed, 1118 insertions(+), 855 deletions(-)
---
base-commit: d55aa725e32849f709b61eab3b7a50b810a71a84
change-id: 20231023-mbly-gpio-a30571ec3283

Best regards,
-- 
Th?o Lebrun <theo.lebrun at bootlin.com>



From theo.lebrun at bootlin.com  Wed Feb 14 08:23:59 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:23:59 +0100
Subject: [PATCH 06/23] pinctrl: nomadik: fix build warning (-Wformat)
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-6-f88c0ccf372b@bootlin.com>

Fix compiler warning found in the pinctrl-nomadik platform driver. GCC
message is as such:

drivers/pinctrl/nomadik/pinctrl-nomadik.c:855:21: warning:
format ?%u? expects argument of type ?unsigned int?, but argument 5
has type ?size_t {aka const long unsigned int}? [-Wformat=]

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index f3897dbfa2c3..d2a40c3dd0f6 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -871,7 +871,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function,
 	if (g->altsetting < 0)
 		return -EINVAL;
 
-	dev_dbg(npct->dev, "enable group %s, %u pins\n", g->grp.name, g->grp.npins);
+	dev_dbg(npct->dev, "enable group %s, %zu pins\n", g->grp.name, g->grp.npins);
 
 	/*
 	 * If we're setting altfunc C by setting both AFSLA and AFSLB to 1,

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:23:57 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:23:57 +0100
Subject: [PATCH 04/23] dt-bindings: gpio: nomadik: add optional reset
 property
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-4-f88c0ccf372b@bootlin.com>

Add optional reset device-tree property to the Nomadik GPIO controller.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
index e44cf292bc6d..d104662ec445 100644
--- a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
@@ -56,6 +56,9 @@ properties:
     minimum: 0
     maximum: 32
 
+  resets:
+    maxItems: 1
+
 required:
   - compatible
   - reg

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:00 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:00 +0100
Subject: [PATCH 07/23] pinctrl: nomadik: fix build warning
 (-Wpointer-to-int-cast)
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-7-f88c0ccf372b@bootlin.com>

Fix compiler warning found in the pinctrl-nomadik platform driver. GCC
message is as such:

drivers/pinctrl/nomadik/pinctrl-nomadik.c:1169:12: warning: cast from
pointer to integer of different size [-Wpointer-to-int-cast]

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index d2a40c3dd0f6..60443de439fd 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -1174,14 +1174,14 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *prcm_np;
 	struct nmk_pinctrl *npct;
-	unsigned int version = 0;
+	uintptr_t version = 0;
 	int i;
 
 	npct = devm_kzalloc(&pdev->dev, sizeof(*npct), GFP_KERNEL);
 	if (!npct)
 		return -ENOMEM;
 
-	version = (unsigned int)device_get_match_data(&pdev->dev);
+	version = (uintptr_t)device_get_match_data(&pdev->dev);
 
 	/* Poke in other ASIC variants here */
 	if (version == PINCTRL_NMK_STN8815)

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:01 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:01 +0100
Subject: [PATCH 08/23] pinctrl: nomadik: minimise indentation in probe
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-8-f88c0ccf372b@bootlin.com>

nmk_pinctrl_probe() iterates over each GPIO block. Use an early
conditional continue to skip to the next iteration rather than indent
all the loop code block.

Do not change code logic. The block is changed from:

	for (i = 0; i < NMK_MAX_BANKS; i++) {
		x = of_parse_phandle(...);
		if (x) {
			... do work ...
		}
	}

To:

	for (i = 0; i < NMK_MAX_BANKS; i++) {
		x = of_parse_phandle(...);
		if (!x)
			continue;

		... do work ...
	}

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 60443de439fd..c1cb3a363692 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -1201,17 +1201,16 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
 		struct nmk_gpio_chip *nmk_chip;
 
 		gpio_np = of_parse_phandle(np, "nomadik-gpio-chips", i);
-		if (gpio_np) {
-			dev_info(&pdev->dev,
-				 "populate NMK GPIO %d \"%pOFn\"\n",
-				 i, gpio_np);
-			nmk_chip = nmk_gpio_populate_chip(gpio_np, pdev);
-			if (IS_ERR(nmk_chip))
-				dev_err(&pdev->dev,
-					"could not populate nmk chip struct "
-					"- continue anyway\n");
-			of_node_put(gpio_np);
-		}
+		if (!gpio_np)
+			continue;
+
+		dev_info(&pdev->dev, "populate NMK GPIO %d \"%pOFn\"\n",
+			 i, gpio_np);
+		nmk_chip = nmk_gpio_populate_chip(gpio_np, pdev);
+		if (IS_ERR(nmk_chip))
+			dev_err(&pdev->dev,
+				"could not populate nmk chip struct - continue anyway\n");
+		of_node_put(gpio_np);
 	}
 
 	prcm_np = of_parse_phandle(np, "prcm", 0);

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:02 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:02 +0100
Subject: [PATCH 09/23] pinctrl: nomadik: follow type-system kernel coding
 conventions
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-9-f88c0ccf372b@bootlin.com>

Fix strict checkpatch warnings relative to types. Warning types
addressed:

   WARNING: do not add new typedefs
   WARNING: Prefer 'unsigned int' to bare use of 'unsigned'
   WARNING: static const char * array should probably be static const
            char * const

Total messages before: 1 errors, 40 warnings, 39 checks.
Total messages after:  1 errors,  2 warnings, 38 checks.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 78 +++++++++++++++----------------
 1 file changed, 38 insertions(+), 40 deletions(-)

diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index c1cb3a363692..94338a3c8d4f 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -71,8 +71,6 @@
  * PIN_CFG	   - default config with alternate function
  */
 
-typedef unsigned long pin_cfg_t;
-
 #define PIN_NUM_MASK		0x1ff
 #define PIN_NUM(x)		((x) & PIN_NUM_MASK)
 
@@ -215,7 +213,7 @@ struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
 DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
 
 static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
-				unsigned offset, int gpio_mode)
+				unsigned int offset, int gpio_mode)
 {
 	u32 afunc, bfunc;
 
@@ -230,7 +228,7 @@ static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
 }
 
 static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
-				unsigned offset, enum nmk_gpio_pull pull)
+				unsigned int offset, enum nmk_gpio_pull pull)
 {
 	u32 pdis;
 
@@ -254,7 +252,7 @@ static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
 }
 
 static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip,
-				  unsigned offset, bool lowemi)
+				  unsigned int offset, bool lowemi)
 {
 	bool enabled = nmk_chip->lowemi & BIT(offset);
 
@@ -271,13 +269,13 @@ static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip,
 }
 
 static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
-				  unsigned offset)
+				  unsigned int offset)
 {
 	writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC);
 }
 
 static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
-				     unsigned offset, int gpio_mode,
+				     unsigned int offset, int gpio_mode,
 				     bool glitch)
 {
 	u32 rwimsc = nmk_chip->rwimsc;
@@ -304,7 +302,7 @@ static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
 }
 
 static void
-nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
+nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned int offset)
 {
 	u32 falling = nmk_chip->fimsc & BIT(offset);
 	u32 rising = nmk_chip->rimsc & BIT(offset);
@@ -343,7 +341,7 @@ static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value)
 }
 
 static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
-	unsigned offset, unsigned alt_num)
+	unsigned int offset, unsigned int alt_num)
 {
 	int i;
 	u16 reg;
@@ -515,15 +513,15 @@ static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
 }
 
 static const char *nmk_get_group_name(struct pinctrl_dev *pctldev,
-				       unsigned selector)
+				       unsigned int selector)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 
 	return npct->soc->groups[selector].grp.name;
 }
 
-static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
-			      const unsigned **pins,
+static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
+			      const unsigned int **pins,
 			      unsigned int *num_pins)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
@@ -533,7 +531,7 @@ static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
 	return 0;
 }
 
-static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned pin)
+static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned int pin)
 {
 	int i;
 	struct nmk_gpio_chip *nmk_gpio;
@@ -549,7 +547,7 @@ static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned pin)
 	return NULL;
 }
 
-static struct gpio_chip *find_gc_from_pin(unsigned pin)
+static struct gpio_chip *find_gc_from_pin(unsigned int pin)
 {
 	struct nmk_gpio_chip *nmk_gpio = find_nmk_gpio_from_pin(pin);
 
@@ -559,7 +557,7 @@ static struct gpio_chip *find_gc_from_pin(unsigned pin)
 }
 
 static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
-		   unsigned offset)
+		   unsigned int offset)
 {
 	struct gpio_chip *chip = find_gc_from_pin(offset);
 
@@ -570,8 +568,8 @@ static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
 	nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset);
 }
 
-static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
-		unsigned *num_maps, const char *group,
+static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned int *reserved_maps,
+		unsigned int *num_maps, const char *group,
 		const char *function)
 {
 	if (*num_maps == *reserved_maps)
@@ -586,9 +584,9 @@ static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
 }
 
 static int nmk_dt_add_map_configs(struct pinctrl_map **map,
-		unsigned *reserved_maps,
-		unsigned *num_maps, const char *group,
-		unsigned long *configs, unsigned num_configs)
+		unsigned int *reserved_maps,
+		unsigned int *num_maps, const char *group,
+		unsigned long *configs, unsigned int num_configs)
 {
 	unsigned long *dup_configs;
 
@@ -727,8 +725,8 @@ static bool nmk_pinctrl_dt_get_config(struct device_node *np,
 static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
 		struct device_node *np,
 		struct pinctrl_map **map,
-		unsigned *reserved_maps,
-		unsigned *num_maps)
+		unsigned int *reserved_maps,
+		unsigned int *num_maps)
 {
 	int ret;
 	const char *function = NULL;
@@ -795,9 +793,9 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
 
 static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 				 struct device_node *np_config,
-				 struct pinctrl_map **map, unsigned *num_maps)
+				 struct pinctrl_map **map, unsigned int *num_maps)
 {
-	unsigned reserved_maps;
+	unsigned int reserved_maps;
 	struct device_node *np;
 	int ret;
 
@@ -835,7 +833,7 @@ static int nmk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
 }
 
 static const char *nmk_pmx_get_func_name(struct pinctrl_dev *pctldev,
-					 unsigned function)
+					 unsigned int function)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 
@@ -843,7 +841,7 @@ static const char *nmk_pmx_get_func_name(struct pinctrl_dev *pctldev,
 }
 
 static int nmk_pmx_get_func_groups(struct pinctrl_dev *pctldev,
-				   unsigned function,
+				   unsigned int function,
 				   const char * const **groups,
 				   unsigned * const num_groups)
 {
@@ -855,8 +853,8 @@ static int nmk_pmx_get_func_groups(struct pinctrl_dev *pctldev,
 	return 0;
 }
 
-static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function,
-		       unsigned group)
+static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
+		       unsigned int group)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 	const struct nmk_pingroup *g;
@@ -913,7 +911,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function,
 
 	for (i = 0; i < g->grp.npins; i++) {
 		struct nmk_gpio_chip *nmk_chip;
-		unsigned bit;
+		unsigned int bit;
 
 		nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i]);
 		if (!nmk_chip) {
@@ -966,12 +964,12 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function,
 
 static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 				   struct pinctrl_gpio_range *range,
-				   unsigned offset)
+				   unsigned int offset)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 	struct nmk_gpio_chip *nmk_chip;
 	struct gpio_chip *chip;
-	unsigned bit;
+	unsigned int bit;
 
 	if (!range) {
 		dev_err(npct->dev, "invalid range\n");
@@ -997,7 +995,7 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 
 static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev,
 				  struct pinctrl_gpio_range *range,
-				  unsigned offset)
+				  unsigned int offset)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 
@@ -1015,30 +1013,30 @@ static const struct pinmux_ops nmk_pinmux_ops = {
 	.strict = true,
 };
 
-static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
+static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
 			      unsigned long *config)
 {
 	/* Not implemented */
 	return -EINVAL;
 }
 
-static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
-			      unsigned long *configs, unsigned num_configs)
+static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
+			      unsigned long *configs, unsigned int num_configs)
 {
-	static const char *pullnames[] = {
+	static const char * const pullnames[] = {
 		[NMK_GPIO_PULL_NONE]	= "none",
 		[NMK_GPIO_PULL_UP]	= "up",
 		[NMK_GPIO_PULL_DOWN]	= "down",
 		[3] /* illegal */	= "??"
 	};
-	static const char *slpmnames[] = {
+	static const char * const slpmnames[] = {
 		[NMK_GPIO_SLPM_INPUT]		= "input/wakeup",
 		[NMK_GPIO_SLPM_NOCHANGE]	= "no-change/no-wakeup",
 	};
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 	struct nmk_gpio_chip *nmk_chip;
-	unsigned bit;
-	pin_cfg_t cfg;
+	unsigned int bit;
+	unsigned long cfg;
 	int pull, slpm, output, val, i;
 	bool lowemi, gpiomode, sleep;
 
@@ -1055,7 +1053,7 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
 		 * here we just ignore that part. It's being handled by the
 		 * framework and pinmux callback respectively.
 		 */
-		cfg = (pin_cfg_t) configs[i];
+		cfg = configs[i];
 		pull = PIN_PULL(cfg);
 		slpm = PIN_SLPM(cfg);
 		output = PIN_DIR(cfg);

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:04 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:04 +0100
Subject: [PATCH 11/23] pinctrl: nomadik: follow conditional kernel coding
 conventions
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-11-f88c0ccf372b@bootlin.com>

Fix strict checkpatch warnings relative to if-else blocks and bool
expressions. Message types addressed:

   CHECK: Comparison to NULL could be written "!nmk_cfg_params[index].choice"
   CHECK: Unbalanced braces around else statement
   CHECK: Using comparison to false is error prone
   CHECK: Using comparison to true is error prone
   CHECK: braces {} should be used on all arms of this statement

Before: 0 errors, 1 warnings, 16 checks.
After:  0 errors, 1 warnings,  7 checks.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 83e7868bc1d7..8099dd947701 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -377,7 +377,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
 	 */
 	if (!alt_num) {
 		for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
-			if (pin_desc->altcx[i].used == true) {
+			if (pin_desc->altcx[i].used) {
 				reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
 				bit = pin_desc->altcx[i].control_bit;
 				if (readl(npct->prcm_base + reg) & BIT(bit)) {
@@ -392,7 +392,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
 	}
 
 	alt_index = alt_num - 1;
-	if (pin_desc->altcx[alt_index].used == false) {
+	if (!pin_desc->altcx[alt_index].used) {
 		dev_warn(npct->dev,
 			 "PRCM GPIOCR: pin %i: alternate-C%i does not exist\n",
 			 offset, alt_num);
@@ -406,7 +406,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
 	for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
 		if (i == alt_index)
 			continue;
-		if (pin_desc->altcx[i].used == true) {
+		if (pin_desc->altcx[i].used) {
 			reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
 			bit = pin_desc->altcx[i].control_bit;
 			if (readl(npct->prcm_base + reg) & BIT(bit)) {
@@ -494,7 +494,7 @@ int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpi
 	pin_desc = npct->soc->altcx_pins + i;
 	gpiocr_regs = npct->soc->prcm_gpiocr_registers;
 	for (i = 0; i < PRCM_IDX_GPIOCR_ALTC_MAX; i++) {
-		if (pin_desc->altcx[i].used == true) {
+		if (pin_desc->altcx[i].used) {
 			reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
 			bit = pin_desc->altcx[i].control_bit;
 			if (readl(npct->prcm_base + reg) & BIT(bit))
@@ -676,9 +676,9 @@ static const struct nmk_cfg_param nmk_cfg_params[] = {
 
 static int nmk_dt_pin_config(int index, int val, unsigned long *config)
 {
-	if (nmk_cfg_params[index].choice == NULL)
+	if (!nmk_cfg_params[index].choice) {
 		*config = nmk_cfg_params[index].config;
-	else {
+	} else {
 		/* test if out of range */
 		if  (val < nmk_cfg_params[index].size) {
 			*config = nmk_cfg_params[index].config |
@@ -1102,9 +1102,9 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
 		if (gpiomode)
 			/* No glitch when going to GPIO mode */
 			__nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
-		if (output)
+		if (output) {
 			__nmk_gpio_make_output(nmk_chip, bit, val);
-		else {
+		} else {
 			__nmk_gpio_make_input(nmk_chip, bit);
 			__nmk_gpio_set_pull(nmk_chip, bit, pull);
 		}

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:03 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:03 +0100
Subject: [PATCH 10/23] pinctrl: nomadik: follow whitespace kernel coding
 conventions
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-10-f88c0ccf372b@bootlin.com>

Fix strict checkpatch warnings relative to whitespace. Message types
addressed:

   ERROR: space required before the open parenthesis '('
   WARNING: quoted string split across lines
   CHECK: Alignment should match open parenthesis
   CHECK: Please don't use multiple blank lines
   CHECK: line length of 103 exceeds 100 columns
   CHECK: spaces preferred around that '+' (ctx:VxV)

Before: 1 errors, 2 warnings, 38 checks.
After:  0 errors, 1 warnings, 16 checks.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 65 +++++++++++++++----------------
 1 file changed, 32 insertions(+), 33 deletions(-)

diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 94338a3c8d4f..83e7868bc1d7 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -165,7 +165,6 @@
 #define PIN_SLEEPMODE_DISABLED	(0 << PIN_SLEEPMODE_SHIFT)
 #define PIN_SLEEPMODE_ENABLED	(1 << PIN_SLEEPMODE_SHIFT)
 
-
 /* Shortcuts.  Use these instead of separate DIR, PULL, and VAL.  */
 #define PIN_INPUT_PULLDOWN	(PIN_DIR_INPUT | PIN_PULL_DOWN)
 #define PIN_INPUT_PULLUP	(PIN_DIR_INPUT | PIN_PULL_UP)
@@ -341,7 +340,7 @@ static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value)
 }
 
 static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
-	unsigned int offset, unsigned int alt_num)
+				    unsigned int offset, unsigned int alt_num)
 {
 	int i;
 	u16 reg;
@@ -385,7 +384,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
 					nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0);
 					dev_dbg(npct->dev,
 						"PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
-						offset, i+1);
+						offset, i + 1);
 				}
 			}
 		}
@@ -395,8 +394,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
 	alt_index = alt_num - 1;
 	if (pin_desc->altcx[alt_index].used == false) {
 		dev_warn(npct->dev,
-			"PRCM GPIOCR: pin %i: alternate-C%i does not exist\n",
-			offset, alt_num);
+			 "PRCM GPIOCR: pin %i: alternate-C%i does not exist\n",
+			 offset, alt_num);
 		return;
 	}
 
@@ -414,7 +413,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
 				nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0);
 				dev_dbg(npct->dev,
 					"PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
-					offset, i+1);
+					offset, i + 1);
 			}
 		}
 	}
@@ -422,7 +421,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
 	reg = gpiocr_regs[pin_desc->altcx[alt_index].reg_index];
 	bit = pin_desc->altcx[alt_index].control_bit;
 	dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n",
-		offset, alt_index+1);
+		offset, alt_index + 1);
 	nmk_write_masked(npct->prcm_base + reg, BIT(bit), BIT(bit));
 }
 
@@ -499,7 +498,7 @@ int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpi
 			reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
 			bit = pin_desc->altcx[i].control_bit;
 			if (readl(npct->prcm_base + reg) & BIT(bit))
-				return NMK_GPIO_ALT_C+i+1;
+				return NMK_GPIO_ALT_C + i + 1;
 		}
 	}
 	return NMK_GPIO_ALT_C;
@@ -513,7 +512,7 @@ static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
 }
 
 static const char *nmk_get_group_name(struct pinctrl_dev *pctldev,
-				       unsigned int selector)
+				      unsigned int selector)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 
@@ -536,12 +535,12 @@ static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned int pin)
 	int i;
 	struct nmk_gpio_chip *nmk_gpio;
 
-	for(i = 0; i < NMK_MAX_BANKS; i++) {
+	for (i = 0; i < NMK_MAX_BANKS; i++) {
 		nmk_gpio = nmk_gpio_chips[i];
 		if (!nmk_gpio)
 			continue;
 		if (pin >= nmk_gpio->chip.base &&
-			pin < nmk_gpio->chip.base + nmk_gpio->chip.ngpio)
+		    pin < nmk_gpio->chip.base + nmk_gpio->chip.ngpio)
 			return nmk_gpio;
 	}
 	return NULL;
@@ -557,7 +556,7 @@ static struct gpio_chip *find_gc_from_pin(unsigned int pin)
 }
 
 static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
-		   unsigned int offset)
+			     unsigned int offset)
 {
 	struct gpio_chip *chip = find_gc_from_pin(offset);
 
@@ -569,8 +568,8 @@ static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
 }
 
 static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned int *reserved_maps,
-		unsigned int *num_maps, const char *group,
-		const char *function)
+			      unsigned int *num_maps, const char *group,
+			      const char *function)
 {
 	if (*num_maps == *reserved_maps)
 		return -ENOSPC;
@@ -584,9 +583,9 @@ static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned int *reserved_m
 }
 
 static int nmk_dt_add_map_configs(struct pinctrl_map **map,
-		unsigned int *reserved_maps,
-		unsigned int *num_maps, const char *group,
-		unsigned long *configs, unsigned int num_configs)
+				  unsigned int *reserved_maps,
+				  unsigned int *num_maps, const char *group,
+				  unsigned long *configs, unsigned int num_configs)
 {
 	unsigned long *dup_configs;
 
@@ -702,15 +701,14 @@ static const char *nmk_find_pin_name(struct pinctrl_dev *pctldev, const char *pi
 }
 
 static bool nmk_pinctrl_dt_get_config(struct device_node *np,
-		unsigned long *configs)
+				      unsigned long *configs)
 {
 	bool has_config = 0;
 	unsigned long cfg = 0;
 	int i, val, ret;
 
 	for (i = 0; i < ARRAY_SIZE(nmk_cfg_params); i++) {
-		ret = of_property_read_u32(np,
-				nmk_cfg_params[i].property, &val);
+		ret = of_property_read_u32(np, nmk_cfg_params[i].property, &val);
 		if (ret != -EINVAL) {
 			if (nmk_dt_pin_config(i, val, &cfg) == 0) {
 				*configs |= cfg;
@@ -723,10 +721,10 @@ static bool nmk_pinctrl_dt_get_config(struct device_node *np,
 }
 
 static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
-		struct device_node *np,
-		struct pinctrl_map **map,
-		unsigned int *reserved_maps,
-		unsigned int *num_maps)
+					 struct device_node *np,
+					 struct pinctrl_map **map,
+					 unsigned int *reserved_maps,
+					 unsigned int *num_maps)
 {
 	int ret;
 	const char *function = NULL;
@@ -751,7 +749,7 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
 
 		of_property_for_each_string(np, "groups", prop, group) {
 			ret = nmk_dt_add_map_mux(map, reserved_maps, num_maps,
-					  group, function);
+						 group, function);
 			if (ret < 0)
 				goto exit;
 		}
@@ -792,8 +790,9 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
 }
 
 static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
-				 struct device_node *np_config,
-				 struct pinctrl_map **map, unsigned int *num_maps)
+				      struct device_node *np_config,
+				      struct pinctrl_map **map,
+				      unsigned int *num_maps)
 {
 	unsigned int reserved_maps;
 	struct device_node *np;
@@ -805,7 +804,7 @@ static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 
 	for_each_child_of_node(np_config, np) {
 		ret = nmk_pinctrl_dt_subnode_to_map(pctldev, np, map,
-				&reserved_maps, num_maps);
+						    &reserved_maps, num_maps);
 		if (ret < 0) {
 			pinctrl_utils_free_map(pctldev, *map, *num_maps);
 			of_node_put(np);
@@ -920,7 +919,8 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 				g->grp.pins[i], g->grp.name, i);
 			goto out_glitch;
 		}
-		dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", g->grp.pins[i], g->altsetting);
+		dev_dbg(npct->dev, "setting pin %d to altsetting %d\n",
+			g->grp.pins[i], g->altsetting);
 
 		clk_enable(nmk_chip->clk);
 		bit = g->grp.pins[i] % NMK_GPIO_PER_CHIP;
@@ -934,7 +934,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 		nmk_gpio_disable_lazy_irq(nmk_chip, bit);
 
 		__nmk_gpio_set_mode_safe(nmk_chip, bit,
-			(g->altsetting & NMK_GPIO_ALT_C), glitch);
+					 (g->altsetting & NMK_GPIO_ALT_C), glitch);
 		clk_disable(nmk_chip->clk);
 
 		/*
@@ -947,7 +947,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 		 */
 		if ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C)
 			nmk_prcm_altcx_set_mode(npct, g->grp.pins[i],
-				g->altsetting >> NMK_GPIO_ALT_CX_SHIFT);
+						g->altsetting >> NMK_GPIO_ALT_CX_SHIFT);
 	}
 
 	/* When all pins are successfully reconfigured we get here */
@@ -1219,8 +1219,7 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
 	if (!npct->prcm_base) {
 		if (version == PINCTRL_NMK_STN8815) {
 			dev_info(&pdev->dev,
-				 "No PRCM base, "
-				 "assuming no ALT-Cx control is available\n");
+				 "No PRCM base, assuming no ALT-Cx control is available\n");
 		} else {
 			dev_err(&pdev->dev, "missing PRCM base address\n");
 			return -EINVAL;

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:06 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:06 +0100
Subject: [PATCH 13/23] gpio: nomadik: fix offset bug in nmk_pmx_set()
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-13-f88c0ccf372b@bootlin.com>

Previously, the statement looked like:

    slpm[x] &= ~BIT(g->pins[i]);

Where:
 - slpm is a unsigned int pointer;
 - g->pins[i] is a pin number which can grow to more than 32.

The expected shift amount is a pin bank offset.

This bug does not occur on every group or pin: the altsetting must be
NMK_GPIO_ALT_C and the pin must be 32 or above. It is possible that it
occurred. For example, in pinctrl-nomadik-db8500.c, pin group i2c3_c_2
has the right altsetting and has pins 229 and 230.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index c7693fbc0484..99bdb25f358d 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -913,8 +913,9 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 		 */
 		for (i = 0; i < g->grp.npins; i++) {
 			struct nmk_gpio_chip *nmk_chip;
+			unsigned int bit;
 
-			nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], NULL);
+			nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], &bit);
 			if (!nmk_chip) {
 				dev_err(npct->dev,
 					"invalid pin offset %d in group %s at index %d\n",
@@ -922,7 +923,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 				goto out_pre_slpm_init;
 			}
 
-			slpm[nmk_chip->bank] &= ~BIT(g->grp.pins[i]);
+			slpm[nmk_chip->bank] &= ~BIT(bit);
 		}
 		nmk_gpio_glitch_slpm_init(slpm);
 	}

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:05 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:05 +0100
Subject: [PATCH 12/23] gpio: nomadik: request dynamic ID allocation
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-12-f88c0ccf372b@bootlin.com>

Move away from statically allocated GPIO IDs. Switch to dynamic ID
allocation. Static IDs are deprecated because they cause issues when
multiple GPIO controllers are to be found on the same platform.

Add a bit of complexity to do pin number -> GPIO chip + offset.
Previously, bank number and offsets were retrieved using division and
remainder (bank size being constant 32). Now, to get the pin number
matching a bank base, we must know the sum of ngpios of previous banks.
This is done in find_nmk_gpio_from_pin() which also exposes the offset
inside the bank.

Also remove the assumption that bank sizes are constant. Instead of
using NMK_GPIO_PER_CHIP as bank size, use nmk_gpio_chips[i]->ngpio.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/gpio/gpio-nomadik.c               |  2 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 55 +++++++++++++++++++++----------
 2 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
index e39477e1a58f..8d47aef8d2c4 100644
--- a/drivers/gpio/gpio-nomadik.c
+++ b/drivers/gpio/gpio-nomadik.c
@@ -516,7 +516,7 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
 
 	nmk_chip->bank = id;
 	chip = &nmk_chip->chip;
-	chip->base = id * NMK_GPIO_PER_CHIP;
+	chip->base = -1;
 	chip->ngpio = NMK_GPIO_PER_CHIP;
 	chip->label = dev_name(&gpio_pdev->dev);
 	chip->parent = &gpio_pdev->dev;
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 8099dd947701..c7693fbc0484 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -530,25 +530,33 @@ static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector
 	return 0;
 }
 
-static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned int pin)
+/* This makes the mapping from pin number to a GPIO chip. We also return the pin
+ * offset in the GPIO chip for convenience (and to avoid a second loop).
+ */
+static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned int pin,
+						    unsigned int *offset)
 {
-	int i;
+	int i, j = 0;
 	struct nmk_gpio_chip *nmk_gpio;
 
+	/* We assume that pins are allocated in bank order. */
 	for (i = 0; i < NMK_MAX_BANKS; i++) {
 		nmk_gpio = nmk_gpio_chips[i];
 		if (!nmk_gpio)
 			continue;
-		if (pin >= nmk_gpio->chip.base &&
-		    pin < nmk_gpio->chip.base + nmk_gpio->chip.ngpio)
+		if (pin >= j && pin < j + nmk_gpio->chip.ngpio) {
+			if (offset)
+				*offset = pin - j;
 			return nmk_gpio;
+		}
+		j += nmk_gpio->chip.ngpio;
 	}
 	return NULL;
 }
 
 static struct gpio_chip *find_gc_from_pin(unsigned int pin)
 {
-	struct nmk_gpio_chip *nmk_gpio = find_nmk_gpio_from_pin(pin);
+	struct nmk_gpio_chip *nmk_gpio = find_nmk_gpio_from_pin(pin, NULL);
 
 	if (nmk_gpio)
 		return &nmk_gpio->chip;
@@ -903,8 +911,19 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 		 * Then mask the pins that need to be sleeping now when we're
 		 * switching to the ALT C function.
 		 */
-		for (i = 0; i < g->grp.npins; i++)
-			slpm[g->grp.pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->grp.pins[i]);
+		for (i = 0; i < g->grp.npins; i++) {
+			struct nmk_gpio_chip *nmk_chip;
+
+			nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], NULL);
+			if (!nmk_chip) {
+				dev_err(npct->dev,
+					"invalid pin offset %d in group %s at index %d\n",
+					g->grp.pins[i], g->grp.name, i);
+				goto out_pre_slpm_init;
+			}
+
+			slpm[nmk_chip->bank] &= ~BIT(g->grp.pins[i]);
+		}
 		nmk_gpio_glitch_slpm_init(slpm);
 	}
 
@@ -912,7 +931,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 		struct nmk_gpio_chip *nmk_chip;
 		unsigned int bit;
 
-		nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i]);
+		nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], &bit);
 		if (!nmk_chip) {
 			dev_err(npct->dev,
 				"invalid pin offset %d in group %s at index %d\n",
@@ -923,7 +942,6 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 			g->grp.pins[i], g->altsetting);
 
 		clk_enable(nmk_chip->clk);
-		bit = g->grp.pins[i] % NMK_GPIO_PER_CHIP;
 		/*
 		 * If the pin is switching to altfunc, and there was an
 		 * interrupt installed on it which has been lazy disabled,
@@ -954,17 +972,18 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
 	ret = 0;
 
 out_glitch:
-	if (glitch) {
+	if (glitch)
 		nmk_gpio_glitch_slpm_restore(slpm);
+out_pre_slpm_init:
+	if (glitch)
 		spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-	}
 
 	return ret;
 }
 
 static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 				   struct pinctrl_gpio_range *range,
-				   unsigned int offset)
+				   unsigned int pin)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 	struct nmk_gpio_chip *nmk_chip;
@@ -982,10 +1001,11 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 	chip = range->gc;
 	nmk_chip = gpiochip_get_data(chip);
 
-	dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset);
+	dev_dbg(npct->dev, "enable pin %u as GPIO\n", pin);
+
+	find_nmk_gpio_from_pin(pin, &bit);
 
 	clk_enable(nmk_chip->clk);
-	bit = offset % NMK_GPIO_PER_CHIP;
 	/* There is no glitch when converting any pin to GPIO */
 	__nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
 	clk_disable(nmk_chip->clk);
@@ -995,11 +1015,11 @@ static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
 
 static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev,
 				  struct pinctrl_gpio_range *range,
-				  unsigned int offset)
+				  unsigned int pin)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 
-	dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset);
+	dev_dbg(npct->dev, "disable pin %u as GPIO\n", pin);
 	/* Set the pin to some default state, GPIO is usually default */
 }
 
@@ -1040,7 +1060,7 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
 	int pull, slpm, output, val, i;
 	bool lowemi, gpiomode, sleep;
 
-	nmk_chip = find_nmk_gpio_from_pin(pin);
+	nmk_chip = find_nmk_gpio_from_pin(pin, &bit);
 	if (!nmk_chip) {
 		dev_err(npct->dev,
 			"invalid pin offset %d\n", pin);
@@ -1098,7 +1118,6 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
 			lowemi ? "on" : "off");
 
 		clk_enable(nmk_chip->clk);
-		bit = pin % NMK_GPIO_PER_CHIP;
 		if (gpiomode)
 			/* No glitch when going to GPIO mode */
 			__nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:23:58 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:23:58 +0100
Subject: [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from
 drivers/pinctrl/nomadik/
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>

Previously, drivers/pinctrl/nomadik/pinctrl-nomadik.c registered two
platform drivers: pinctrl & GPIO. Move the GPIO aspect to the
drivers/gpio/ folder, as would be expected.

Both drivers are intertwined for a reason; pinctrl requires access to
GPIO registers for pinmuxing, pull-disable, disabling interrupts while
setting the muxing and wakeup control. Information sharing is done
through a shared array containing GPIO chips and a few helper
functions. That shared array is not touched from gpio-nomadik when
CONFIG_PINCTRL_NOMADIK is not defined.

Make no change to the code that moved into gpio-nomadik; there should be
no behavior change following. A few functions are shared and header
comments are added. Checkpatch warnings are addressed. NUM_BANKS is
renamed to NMK_MAX_BANKS.

It is supported to compile gpio-nomadik without pinctrl-nomadik. The
opposite is not true.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 MAINTAINERS                                        |   1 +
 drivers/gpio/Kconfig                               |  12 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-nomadik.c                        | 660 +++++++++++++++++++
 drivers/pinctrl/nomadik/Kconfig                    |   5 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c   |   3 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c  |   3 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik.c          | 722 +--------------------
 .../linux/gpio/gpio-nomadik.h                      | 122 +++-
 9 files changed, 804 insertions(+), 725 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0cb2c459d1cf..3f864e773267 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2474,6 +2474,7 @@ F:	drivers/clk/clk-nomadik.c
 F:	drivers/clocksource/clksrc-dbx500-prcmu.c
 F:	drivers/dma/ste_dma40*
 F:	drivers/pmdomain/st/ste-ux500-pm-domain.c
+F:	drivers/gpio/gpio-nomadik.c
 F:	drivers/hwspinlock/u8500_hsem.c
 F:	drivers/i2c/busses/i2c-nomadik.c
 F:	drivers/iio/adc/ab8500-gpadc.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 1301cec94f12..ff83371251c1 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -478,6 +478,18 @@ config GPIO_MXS
 	select GPIO_GENERIC
 	select GENERIC_IRQ_CHIP
 
+config GPIO_NOMADIK
+	bool "Nomadik GPIO driver"
+	depends on ARCH_U8500 || ARCH_NOMADIK || COMPILE_TEST
+	select OF_GPIO
+	select GPIOLIB_IRQCHIP
+	help
+	  Say yes here to support the Nomadik SoC GPIO block.
+
+	  It handles up to 32 GPIOs per bank, that can all be interrupt sources.
+	  It is deeply interconnected with the associated pinctrl driver as GPIO
+	  registers handle muxing ("alternate functions") as well.
+
 config GPIO_NPCM_SGPIO
 	bool "Nuvoton SGPIO support"
 	depends on ARCH_NPCM || COMPILE_TEST
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 9e40af196aae..9fc2f5931b22 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -116,6 +116,7 @@ obj-$(CONFIG_GPIO_MT7621)		+= gpio-mt7621.o
 obj-$(CONFIG_GPIO_MVEBU)		+= gpio-mvebu.o
 obj-$(CONFIG_GPIO_MXC)			+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)			+= gpio-mxs.o
+obj-$(CONFIG_GPIO_NOMADIK)		+= gpio-nomadik.o
 obj-$(CONFIG_GPIO_NPCM_SGPIO)		+= gpio-npcm-sgpio.o
 obj-$(CONFIG_GPIO_OCTEON)		+= gpio-octeon.o
 obj-$(CONFIG_GPIO_OMAP)			+= gpio-omap.o
diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
new file mode 100644
index 000000000000..e39477e1a58f
--- /dev/null
+++ b/drivers/gpio/gpio-nomadik.c
@@ -0,0 +1,660 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * GPIO driver for the IP block found in the Nomadik SoC; it is an AMBA device,
+ * managing 32 pins with alternate functions. It can also handle the STA2X11
+ * block from ST.
+ *
+ * The GPIO chips are shared with pinctrl-nomadik if used; it needs access for
+ * pinmuxing functionality and others.
+ *
+ * Copyright (C) 2008,2009 STMicroelectronics
+ * Copyright (C) 2009 Alessandro Rubini <rubini at unipv.it>
+ *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar at st.com>
+ * Copyright (C) 2011-2013 Linus Walleij <linus.walleij at linaro.org>
+ */
+#include <linux/cleanup.h>
+#include <linux/clk.h>
+#include <linux/gpio/driver.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/seq_file.h>
+#include <linux/types.h>
+
+#include <linux/gpio/gpio-nomadik.h>
+
+#ifndef CONFIG_PINCTRL_NOMADIK
+static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
+#endif
+
+void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset,
+			 enum nmk_gpio_slpm mode)
+{
+	u32 slpm;
+
+	slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
+	if (mode == NMK_GPIO_SLPM_NOCHANGE)
+		slpm |= BIT(offset);
+	else
+		slpm &= ~BIT(offset);
+	writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
+}
+
+static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
+				  unsigned int offset, int val)
+{
+	if (val)
+		writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATS);
+	else
+		writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATC);
+}
+
+void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
+			    unsigned int offset, int val)
+{
+	writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRS);
+	__nmk_gpio_set_output(nmk_chip, offset, val);
+}
+
+/* IRQ functions */
+
+static void nmk_gpio_irq_ack(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
+
+	clk_enable(nmk_chip->clk);
+	writel(BIT(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
+	clk_disable(nmk_chip->clk);
+}
+
+enum nmk_gpio_irq_type {
+	NORMAL,
+	WAKE,
+};
+
+static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
+				  int offset, enum nmk_gpio_irq_type which,
+				  bool enable)
+{
+	u32 *rimscval;
+	u32 *fimscval;
+	u32 rimscreg;
+	u32 fimscreg;
+
+	if (which == NORMAL) {
+		rimscreg = NMK_GPIO_RIMSC;
+		fimscreg = NMK_GPIO_FIMSC;
+		rimscval = &nmk_chip->rimsc;
+		fimscval = &nmk_chip->fimsc;
+	} else  {
+		rimscreg = NMK_GPIO_RWIMSC;
+		fimscreg = NMK_GPIO_FWIMSC;
+		rimscval = &nmk_chip->rwimsc;
+		fimscval = &nmk_chip->fwimsc;
+	}
+
+	/* we must individually set/clear the two edges */
+	if (nmk_chip->edge_rising & BIT(offset)) {
+		if (enable)
+			*rimscval |= BIT(offset);
+		else
+			*rimscval &= ~BIT(offset);
+		writel(*rimscval, nmk_chip->addr + rimscreg);
+	}
+	if (nmk_chip->edge_falling & BIT(offset)) {
+		if (enable)
+			*fimscval |= BIT(offset);
+		else
+			*fimscval &= ~BIT(offset);
+		writel(*fimscval, nmk_chip->addr + fimscreg);
+	}
+}
+
+static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
+				int offset, bool on)
+{
+	/*
+	 * Ensure WAKEUP_ENABLE is on.  No need to disable it if wakeup is
+	 * disabled, since setting SLPM to 1 increases power consumption, and
+	 * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
+	 */
+	if (nmk_chip->sleepmode && on) {
+		__nmk_gpio_set_slpm(nmk_chip, offset,
+				    NMK_GPIO_SLPM_WAKEUP_ENABLE);
+	}
+
+	__nmk_gpio_irq_modify(nmk_chip, offset, WAKE, on);
+}
+
+static void nmk_gpio_irq_maskunmask(struct nmk_gpio_chip *nmk_chip,
+				    struct irq_data *d, bool enable)
+{
+	unsigned long flags;
+
+	clk_enable(nmk_chip->clk);
+	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+	spin_lock(&nmk_chip->lock);
+
+	__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
+
+	if (!(nmk_chip->real_wake & BIT(d->hwirq)))
+		__nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
+
+	spin_unlock(&nmk_chip->lock);
+	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+	clk_disable(nmk_chip->clk);
+}
+
+static void nmk_gpio_irq_mask(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
+
+	nmk_gpio_irq_maskunmask(nmk_chip, d, false);
+	gpiochip_disable_irq(gc, irqd_to_hwirq(d));
+}
+
+static void nmk_gpio_irq_unmask(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
+
+	gpiochip_enable_irq(gc, irqd_to_hwirq(d));
+	nmk_gpio_irq_maskunmask(nmk_chip, d, true);
+}
+
+static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
+	unsigned long flags;
+
+	clk_enable(nmk_chip->clk);
+	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+	spin_lock(&nmk_chip->lock);
+
+	if (irqd_irq_disabled(d))
+		__nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
+
+	if (on)
+		nmk_chip->real_wake |= BIT(d->hwirq);
+	else
+		nmk_chip->real_wake &= ~BIT(d->hwirq);
+
+	spin_unlock(&nmk_chip->lock);
+	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+	clk_disable(nmk_chip->clk);
+
+	return 0;
+}
+
+static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
+	bool enabled = !irqd_irq_disabled(d);
+	bool wake = irqd_is_wakeup_set(d);
+	unsigned long flags;
+
+	if (type & IRQ_TYPE_LEVEL_HIGH)
+		return -EINVAL;
+	if (type & IRQ_TYPE_LEVEL_LOW)
+		return -EINVAL;
+
+	clk_enable(nmk_chip->clk);
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+
+	if (enabled)
+		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
+
+	if (enabled || wake)
+		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
+
+	nmk_chip->edge_rising &= ~BIT(d->hwirq);
+	if (type & IRQ_TYPE_EDGE_RISING)
+		nmk_chip->edge_rising |= BIT(d->hwirq);
+
+	nmk_chip->edge_falling &= ~BIT(d->hwirq);
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		nmk_chip->edge_falling |= BIT(d->hwirq);
+
+	if (enabled)
+		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
+
+	if (enabled || wake)
+		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
+
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+	clk_disable(nmk_chip->clk);
+
+	return 0;
+}
+
+static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
+
+	clk_enable(nmk_chip->clk);
+	nmk_gpio_irq_unmask(d);
+	return 0;
+}
+
+static void nmk_gpio_irq_shutdown(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
+
+	nmk_gpio_irq_mask(d);
+	clk_disable(nmk_chip->clk);
+}
+
+static void nmk_gpio_irq_handler(struct irq_desc *desc)
+{
+	struct irq_chip *host_chip = irq_desc_get_chip(desc);
+	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
+	u32 status;
+
+	chained_irq_enter(host_chip, desc);
+
+	clk_enable(nmk_chip->clk);
+	status = readl(nmk_chip->addr + NMK_GPIO_IS);
+	clk_disable(nmk_chip->clk);
+
+	while (status) {
+		int bit = __ffs(status);
+
+		generic_handle_domain_irq(chip->irq.domain, bit);
+		status &= ~BIT(bit);
+	}
+
+	chained_irq_exit(host_chip, desc);
+}
+
+/* I/O Functions */
+
+static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned int offset)
+{
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
+	int dir;
+
+	clk_enable(nmk_chip->clk);
+
+	dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset);
+
+	clk_disable(nmk_chip->clk);
+
+	if (dir)
+		return GPIO_LINE_DIRECTION_OUT;
+
+	return GPIO_LINE_DIRECTION_IN;
+}
+
+static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
+
+	clk_enable(nmk_chip->clk);
+
+	writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC);
+
+	clk_disable(nmk_chip->clk);
+
+	return 0;
+}
+
+static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
+	int value;
+
+	clk_enable(nmk_chip->clk);
+
+	value = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
+
+	clk_disable(nmk_chip->clk);
+
+	return value;
+}
+
+static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned int offset,
+				int val)
+{
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
+
+	clk_enable(nmk_chip->clk);
+
+	__nmk_gpio_set_output(nmk_chip, offset, val);
+
+	clk_disable(nmk_chip->clk);
+}
+
+static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned int offset,
+				int val)
+{
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
+
+	clk_enable(nmk_chip->clk);
+
+	__nmk_gpio_make_output(nmk_chip, offset, val);
+
+	clk_disable(nmk_chip->clk);
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+static int nmk_gpio_get_mode(struct nmk_gpio_chip *nmk_chip, int offset)
+{
+	u32 afunc, bfunc;
+
+	clk_enable(nmk_chip->clk);
+
+	afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & BIT(offset);
+	bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & BIT(offset);
+
+	clk_disable(nmk_chip->clk);
+
+	return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
+}
+
+void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev,
+			   struct gpio_chip *chip, unsigned int offset,
+			   unsigned int gpio)
+{
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
+	int mode;
+	bool is_out;
+	bool data_out;
+	bool pull;
+	static const char * const modes[] = {
+		[NMK_GPIO_ALT_GPIO]	= "gpio",
+		[NMK_GPIO_ALT_A]	= "altA",
+		[NMK_GPIO_ALT_B]	= "altB",
+		[NMK_GPIO_ALT_C]	= "altC",
+		[NMK_GPIO_ALT_C + 1]	= "altC1",
+		[NMK_GPIO_ALT_C + 2]	= "altC2",
+		[NMK_GPIO_ALT_C + 3]	= "altC3",
+		[NMK_GPIO_ALT_C + 4]	= "altC4",
+	};
+
+	char *label = gpiochip_dup_line_label(chip, offset);
+	if (IS_ERR(label))
+		return;
+
+	clk_enable(nmk_chip->clk);
+	is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
+	pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & BIT(offset));
+	data_out = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
+	mode = nmk_gpio_get_mode(nmk_chip, offset);
+#ifdef CONFIG_PINCTRL_NOMADIK
+	if (mode == NMK_GPIO_ALT_C && pctldev)
+		mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio);
+#endif
+
+	if (is_out) {
+		seq_printf(s, " gpio-%-3d (%-20.20s) out %s           %s",
+			   gpio,
+			   label ?: "(none)",
+			   data_out ? "hi" : "lo",
+			   (mode < 0) ? "unknown" : modes[mode]);
+	} else {
+		int irq = chip->to_irq(chip, offset);
+		const int pullidx = pull ? 1 : 0;
+		int val;
+		static const char * const pulls[] = {
+			"none        ",
+			"pull enabled",
+		};
+
+		seq_printf(s, " gpio-%-3d (%-20.20s) in  %s %s",
+			   gpio,
+			   label ?: "(none)",
+			   pulls[pullidx],
+			   (mode < 0) ? "unknown" : modes[mode]);
+
+		val = nmk_gpio_get_input(chip, offset);
+		seq_printf(s, " VAL %d", val);
+
+		/*
+		 * This races with request_irq(), set_irq_type(),
+		 * and set_irq_wake() ... but those are "rare".
+		 */
+		if (irq > 0 && irq_has_action(irq)) {
+			char *trigger;
+			bool wake;
+
+			if (nmk_chip->edge_rising & BIT(offset))
+				trigger = "edge-rising";
+			else if (nmk_chip->edge_falling & BIT(offset))
+				trigger = "edge-falling";
+			else
+				trigger = "edge-undefined";
+
+			wake = !!(nmk_chip->real_wake & BIT(offset));
+
+			seq_printf(s, " irq-%d %s%s",
+				   irq, trigger, wake ? " wakeup" : "");
+		}
+	}
+	clk_disable(nmk_chip->clk);
+}
+
+static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	unsigned int i, gpio = chip->base;
+
+	for (i = 0; i < chip->ngpio; i++, gpio++) {
+		nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio);
+		seq_puts(s, "\n");
+	}
+}
+
+#else
+
+static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
+					 struct pinctrl_dev *pctldev,
+					 struct gpio_chip *chip,
+					 unsigned int offset,
+					 unsigned int gpio)
+{
+}
+
+#define nmk_gpio_dbg_show	NULL
+
+#endif
+
+/*
+ * We will allocate memory for the state container using devm* allocators
+ * binding to the first device reaching this point, it doesn't matter if
+ * it is the pin controller or GPIO driver. However we need to use the right
+ * platform device when looking up resources so pay attention to pdev.
+ */
+struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
+					     struct platform_device *pdev)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	struct platform_device *gpio_pdev;
+	struct gpio_chip *chip;
+	struct resource *res;
+	struct clk *clk;
+	void __iomem *base;
+	u32 id;
+
+	gpio_pdev = of_find_device_by_node(np);
+	if (!gpio_pdev) {
+		pr_err("populate \"%pOFn\": device not found\n", np);
+		return ERR_PTR(-ENODEV);
+	}
+	if (of_property_read_u32(np, "gpio-bank", &id)) {
+		dev_err(&pdev->dev, "populate: gpio-bank property not found\n");
+		platform_device_put(gpio_pdev);
+		return ERR_PTR(-EINVAL);
+	}
+
+#ifdef CONFIG_PINCTRL_NOMADIK
+	/* Already populated? */
+	nmk_chip = nmk_gpio_chips[id];
+	if (nmk_chip) {
+		platform_device_put(gpio_pdev);
+		return nmk_chip;
+	}
+#endif
+
+	nmk_chip = devm_kzalloc(&pdev->dev, sizeof(*nmk_chip), GFP_KERNEL);
+	if (!nmk_chip) {
+		platform_device_put(gpio_pdev);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	nmk_chip->bank = id;
+	chip = &nmk_chip->chip;
+	chip->base = id * NMK_GPIO_PER_CHIP;
+	chip->ngpio = NMK_GPIO_PER_CHIP;
+	chip->label = dev_name(&gpio_pdev->dev);
+	chip->parent = &gpio_pdev->dev;
+
+	res = platform_get_resource(gpio_pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		platform_device_put(gpio_pdev);
+		return ERR_CAST(base);
+	}
+	nmk_chip->addr = base;
+
+	clk = clk_get(&gpio_pdev->dev, NULL);
+	if (IS_ERR(clk)) {
+		platform_device_put(gpio_pdev);
+		return (void *)clk;
+	}
+	clk_prepare(clk);
+	nmk_chip->clk = clk;
+
+#ifdef CONFIG_PINCTRL_NOMADIK
+	BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
+	nmk_gpio_chips[id] = nmk_chip;
+#endif
+	return nmk_chip;
+}
+
+static void nmk_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
+
+	seq_printf(p, "nmk%u-%u-%u", nmk_chip->bank,
+		   gc->base, gc->base + gc->ngpio - 1);
+}
+
+static const struct irq_chip nmk_irq_chip = {
+	.irq_ack = nmk_gpio_irq_ack,
+	.irq_mask = nmk_gpio_irq_mask,
+	.irq_unmask = nmk_gpio_irq_unmask,
+	.irq_set_type = nmk_gpio_irq_set_type,
+	.irq_set_wake = nmk_gpio_irq_set_wake,
+	.irq_startup = nmk_gpio_irq_startup,
+	.irq_shutdown = nmk_gpio_irq_shutdown,
+	.irq_print_chip = nmk_gpio_irq_print_chip,
+	.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE,
+	GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
+static int nmk_gpio_probe(struct platform_device *dev)
+{
+	struct device_node *np = dev->dev.of_node;
+	struct nmk_gpio_chip *nmk_chip;
+	struct gpio_chip *chip;
+	struct gpio_irq_chip *girq;
+	bool supports_sleepmode;
+	int irq;
+	int ret;
+
+	nmk_chip = nmk_gpio_populate_chip(np, dev);
+	if (IS_ERR(nmk_chip)) {
+		dev_err(&dev->dev, "could not populate nmk chip struct\n");
+		return PTR_ERR(nmk_chip);
+	}
+
+	supports_sleepmode =
+		of_property_read_bool(np, "st,supports-sleepmode");
+
+	/* Correct platform device ID */
+	dev->id = nmk_chip->bank;
+
+	irq = platform_get_irq(dev, 0);
+	if (irq < 0)
+		return irq;
+
+	/*
+	 * The virt address in nmk_chip->addr is in the nomadik register space,
+	 * so we can simply convert the resource address, without remapping
+	 */
+	nmk_chip->sleepmode = supports_sleepmode;
+	spin_lock_init(&nmk_chip->lock);
+
+	chip = &nmk_chip->chip;
+	chip->parent = &dev->dev;
+	chip->request = gpiochip_generic_request;
+	chip->free = gpiochip_generic_free;
+	chip->get_direction = nmk_gpio_get_dir;
+	chip->direction_input = nmk_gpio_make_input;
+	chip->get = nmk_gpio_get_input;
+	chip->direction_output = nmk_gpio_make_output;
+	chip->set = nmk_gpio_set_output;
+	chip->dbg_show = nmk_gpio_dbg_show;
+	chip->can_sleep = false;
+	chip->owner = THIS_MODULE;
+
+	girq = &chip->irq;
+	gpio_irq_chip_set_chip(girq, &nmk_irq_chip);
+	girq->parent_handler = nmk_gpio_irq_handler;
+	girq->num_parents = 1;
+	girq->parents = devm_kcalloc(&dev->dev, 1,
+				     sizeof(*girq->parents),
+				     GFP_KERNEL);
+	if (!girq->parents)
+		return -ENOMEM;
+	girq->parents[0] = irq;
+	girq->default_type = IRQ_TYPE_NONE;
+	girq->handler = handle_edge_irq;
+
+	clk_enable(nmk_chip->clk);
+	nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
+	clk_disable(nmk_chip->clk);
+
+	ret = gpiochip_add_data(chip, nmk_chip);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(dev, nmk_chip);
+
+	dev_info(&dev->dev, "chip registered\n");
+
+	return 0;
+}
+
+static const struct of_device_id nmk_gpio_match[] = {
+	{ .compatible = "st,nomadik-gpio", },
+	{}
+};
+
+static struct platform_driver nmk_gpio_driver = {
+	.driver = {
+		.name = "gpio",
+		.of_match_table = nmk_gpio_match,
+	},
+	.probe = nmk_gpio_probe,
+};
+
+static int __init nmk_gpio_init(void)
+{
+	return platform_driver_register(&nmk_gpio_driver);
+}
+subsys_initcall(nmk_gpio_init);
diff --git a/drivers/pinctrl/nomadik/Kconfig b/drivers/pinctrl/nomadik/Kconfig
index 0fea167c283f..f47f0755a835 100644
--- a/drivers/pinctrl/nomadik/Kconfig
+++ b/drivers/pinctrl/nomadik/Kconfig
@@ -22,11 +22,10 @@ if (ARCH_U8500 || ARCH_NOMADIK)
 
 config PINCTRL_NOMADIK
 	bool "Nomadik pin controller driver"
-	depends on OF && GPIOLIB
+	depends on OF
 	select PINMUX
 	select PINCONF
-	select OF_GPIO
-	select GPIOLIB_IRQCHIP
+	select GPIO_NOMADIK
 
 config PINCTRL_STN8815
 	bool "STN8815 pin controller driver"
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
index 490e0959e8be..0b4a3dd9d8c7 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
@@ -3,8 +3,9 @@
 #include <linux/types.h>
 
 #include <linux/pinctrl/pinctrl.h>
+#include <linux/gpio/driver.h>
 
-#include "pinctrl-nomadik.h"
+#include <linux/gpio/gpio-nomadik.h>
 
 /* All the pins that can be used for GPIO and some other functions */
 #define _GPIO(offset)		(offset)
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
index 1552222ac68e..c5a52fcaba30 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
@@ -3,8 +3,9 @@
 #include <linux/types.h>
 
 #include <linux/pinctrl/pinctrl.h>
+#include <linux/gpio/driver.h>
 
-#include "pinctrl-nomadik.h"
+#include <linux/gpio/gpio-nomadik.h>
 
 /* All the pins that can be used for GPIO and some other functions */
 #define _GPIO(offset)		(offset)
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 7911353ac97d..f3897dbfa2c3 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Generic GPIO driver for logic cells found in the Nomadik SoC
+ * Pinmux & pinconf driver for the IP block found in the Nomadik SoC. This
+ * depends on gpio-nomadik and some handling is intertwined; see nmk_gpio_chips
+ * which is used by this driver to access the GPIO banks array.
  *
  * Copyright (C) 2008,2009 STMicroelectronics
  * Copyright (C) 2009 Alessandro Rubini <rubini at unipv.it>
@@ -25,6 +27,7 @@
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/types.h>
 
 /* Since we request GPIOs from ourself */
 #include <linux/pinctrl/consumer.h>
@@ -36,15 +39,7 @@
 #include "../core.h"
 #include "../pinctrl-utils.h"
 
-#include "pinctrl-nomadik.h"
-
-/*
- * The GPIO module in the Nomadik family of Systems-on-Chip is an
- * AMBA device, managing 32 pins and alternate functions.  The logic block
- * is currently used in the Nomadik and ux500.
- *
- * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
- */
+#include <linux/gpio/gpio-nomadik.h>
 
 /*
  * pin configurations are represented by 32-bit integers:
@@ -200,75 +195,6 @@ typedef unsigned long pin_cfg_t;
 	(PIN_CFG_DEFAULT |\
 	 (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
 
-/*
- * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
- * the "gpio" namespace for generic and cross-machine functions
- */
-
-#define GPIO_BLOCK_SHIFT 5
-#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT)
-#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP)
-
-/* Register in the logic block */
-#define NMK_GPIO_DAT	0x00
-#define NMK_GPIO_DATS	0x04
-#define NMK_GPIO_DATC	0x08
-#define NMK_GPIO_PDIS	0x0c
-#define NMK_GPIO_DIR	0x10
-#define NMK_GPIO_DIRS	0x14
-#define NMK_GPIO_DIRC	0x18
-#define NMK_GPIO_SLPC	0x1c
-#define NMK_GPIO_AFSLA	0x20
-#define NMK_GPIO_AFSLB	0x24
-#define NMK_GPIO_LOWEMI	0x28
-
-#define NMK_GPIO_RIMSC	0x40
-#define NMK_GPIO_FIMSC	0x44
-#define NMK_GPIO_IS	0x48
-#define NMK_GPIO_IC	0x4c
-#define NMK_GPIO_RWIMSC	0x50
-#define NMK_GPIO_FWIMSC	0x54
-#define NMK_GPIO_WKS	0x58
-/* These appear in DB8540 and later ASICs */
-#define NMK_GPIO_EDGELEVEL 0x5C
-#define NMK_GPIO_LEVEL	0x60
-
-
-/* Pull up/down values */
-enum nmk_gpio_pull {
-	NMK_GPIO_PULL_NONE,
-	NMK_GPIO_PULL_UP,
-	NMK_GPIO_PULL_DOWN,
-};
-
-/* Sleep mode */
-enum nmk_gpio_slpm {
-	NMK_GPIO_SLPM_INPUT,
-	NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
-	NMK_GPIO_SLPM_NOCHANGE,
-	NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
-};
-
-struct nmk_gpio_chip {
-	struct gpio_chip chip;
-	void __iomem *addr;
-	struct clk *clk;
-	unsigned int bank;
-	void (*set_ioforce)(bool enable);
-	spinlock_t lock;
-	bool sleepmode;
-	/* Keep track of configured edges */
-	u32 edge_rising;
-	u32 edge_falling;
-	u32 real_wake;
-	u32 rwimsc;
-	u32 fwimsc;
-	u32 rimsc;
-	u32 fimsc;
-	u32 pull_up;
-	u32 lowemi;
-};
-
 /**
  * struct nmk_pinctrl - state container for the Nomadik pin controller
  * @dev: containing device pointer
@@ -283,11 +209,10 @@ struct nmk_pinctrl {
 	void __iomem *prcm_base;
 };
 
-static struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
+/* See nmk_gpio_populate_chip() that fills this array. */
+struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
 
-static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
-
-#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips)
+DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
 
 static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
 				unsigned offset, int gpio_mode)
@@ -304,19 +229,6 @@ static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
 	writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
 }
 
-static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
-				unsigned offset, enum nmk_gpio_slpm mode)
-{
-	u32 slpm;
-
-	slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
-	if (mode == NMK_GPIO_SLPM_NOCHANGE)
-		slpm |= BIT(offset);
-	else
-		slpm &= ~BIT(offset);
-	writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
-}
-
 static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
 				unsigned offset, enum nmk_gpio_pull pull)
 {
@@ -364,22 +276,6 @@ static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
 	writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC);
 }
 
-static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
-				  unsigned offset, int val)
-{
-	if (val)
-		writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATS);
-	else
-		writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATC);
-}
-
-static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
-				  unsigned offset, int val)
-{
-	writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRS);
-	__nmk_gpio_set_output(nmk_chip, offset, val);
-}
-
 static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
 				     unsigned offset, int gpio_mode,
 				     bool glitch)
@@ -548,7 +444,7 @@ static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
 {
 	int i;
 
-	for (i = 0; i < NUM_BANKS; i++) {
+	for (i = 0; i < NMK_MAX_BANKS; i++) {
 		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
 		unsigned int temp = slpm[i];
 
@@ -566,7 +462,7 @@ static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
 {
 	int i;
 
-	for (i = 0; i < NUM_BANKS; i++) {
+	for (i = 0; i < NMK_MAX_BANKS; i++) {
 		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
 
 		if (!chip)
@@ -578,7 +474,8 @@ static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
 	}
 }
 
-static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
+/* Only called by gpio-nomadik but requires knowledge of struct nmk_pinctrl. */
+int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
 {
 	int i;
 	u16 reg;
@@ -610,576 +507,6 @@ static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev,
 	return NMK_GPIO_ALT_C;
 }
 
-/* IRQ functions */
-
-static void nmk_gpio_irq_ack(struct irq_data *d)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
-	clk_enable(nmk_chip->clk);
-	writel(BIT(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
-	clk_disable(nmk_chip->clk);
-}
-
-enum nmk_gpio_irq_type {
-	NORMAL,
-	WAKE,
-};
-
-static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
-				  int offset, enum nmk_gpio_irq_type which,
-				  bool enable)
-{
-	u32 *rimscval;
-	u32 *fimscval;
-	u32 rimscreg;
-	u32 fimscreg;
-
-	if (which == NORMAL) {
-		rimscreg = NMK_GPIO_RIMSC;
-		fimscreg = NMK_GPIO_FIMSC;
-		rimscval = &nmk_chip->rimsc;
-		fimscval = &nmk_chip->fimsc;
-	} else  {
-		rimscreg = NMK_GPIO_RWIMSC;
-		fimscreg = NMK_GPIO_FWIMSC;
-		rimscval = &nmk_chip->rwimsc;
-		fimscval = &nmk_chip->fwimsc;
-	}
-
-	/* we must individually set/clear the two edges */
-	if (nmk_chip->edge_rising & BIT(offset)) {
-		if (enable)
-			*rimscval |= BIT(offset);
-		else
-			*rimscval &= ~BIT(offset);
-		writel(*rimscval, nmk_chip->addr + rimscreg);
-	}
-	if (nmk_chip->edge_falling & BIT(offset)) {
-		if (enable)
-			*fimscval |= BIT(offset);
-		else
-			*fimscval &= ~BIT(offset);
-		writel(*fimscval, nmk_chip->addr + fimscreg);
-	}
-}
-
-static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
-				int offset, bool on)
-{
-	/*
-	 * Ensure WAKEUP_ENABLE is on.  No need to disable it if wakeup is
-	 * disabled, since setting SLPM to 1 increases power consumption, and
-	 * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
-	 */
-	if (nmk_chip->sleepmode && on) {
-		__nmk_gpio_set_slpm(nmk_chip, offset,
-				    NMK_GPIO_SLPM_WAKEUP_ENABLE);
-	}
-
-	__nmk_gpio_irq_modify(nmk_chip, offset, WAKE, on);
-}
-
-static void nmk_gpio_irq_maskunmask(struct nmk_gpio_chip *nmk_chip,
-				    struct irq_data *d, bool enable)
-{
-	unsigned long flags;
-
-	clk_enable(nmk_chip->clk);
-	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
-	spin_lock(&nmk_chip->lock);
-
-	__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
-
-	if (!(nmk_chip->real_wake & BIT(d->hwirq)))
-		__nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
-
-	spin_unlock(&nmk_chip->lock);
-	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-	clk_disable(nmk_chip->clk);
-}
-
-static void nmk_gpio_irq_mask(struct irq_data *d)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
-	nmk_gpio_irq_maskunmask(nmk_chip, d, false);
-	gpiochip_disable_irq(gc, irqd_to_hwirq(d));
-}
-
-static void nmk_gpio_irq_unmask(struct irq_data *d)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
-	gpiochip_enable_irq(gc, irqd_to_hwirq(d));
-	nmk_gpio_irq_maskunmask(nmk_chip, d, true);
-}
-
-static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-	unsigned long flags;
-
-	clk_enable(nmk_chip->clk);
-	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
-	spin_lock(&nmk_chip->lock);
-
-	if (irqd_irq_disabled(d))
-		__nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
-
-	if (on)
-		nmk_chip->real_wake |= BIT(d->hwirq);
-	else
-		nmk_chip->real_wake &= ~BIT(d->hwirq);
-
-	spin_unlock(&nmk_chip->lock);
-	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-	clk_disable(nmk_chip->clk);
-
-	return 0;
-}
-
-static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-	bool enabled = !irqd_irq_disabled(d);
-	bool wake = irqd_is_wakeup_set(d);
-	unsigned long flags;
-
-	if (type & IRQ_TYPE_LEVEL_HIGH)
-		return -EINVAL;
-	if (type & IRQ_TYPE_LEVEL_LOW)
-		return -EINVAL;
-
-	clk_enable(nmk_chip->clk);
-	spin_lock_irqsave(&nmk_chip->lock, flags);
-
-	if (enabled)
-		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
-
-	if (enabled || wake)
-		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
-
-	nmk_chip->edge_rising &= ~BIT(d->hwirq);
-	if (type & IRQ_TYPE_EDGE_RISING)
-		nmk_chip->edge_rising |= BIT(d->hwirq);
-
-	nmk_chip->edge_falling &= ~BIT(d->hwirq);
-	if (type & IRQ_TYPE_EDGE_FALLING)
-		nmk_chip->edge_falling |= BIT(d->hwirq);
-
-	if (enabled)
-		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
-
-	if (enabled || wake)
-		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
-
-	spin_unlock_irqrestore(&nmk_chip->lock, flags);
-	clk_disable(nmk_chip->clk);
-
-	return 0;
-}
-
-static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
-	clk_enable(nmk_chip->clk);
-	nmk_gpio_irq_unmask(d);
-	return 0;
-}
-
-static void nmk_gpio_irq_shutdown(struct irq_data *d)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
-	nmk_gpio_irq_mask(d);
-	clk_disable(nmk_chip->clk);
-}
-
-static void nmk_gpio_irq_handler(struct irq_desc *desc)
-{
-	struct irq_chip *host_chip = irq_desc_get_chip(desc);
-	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-	u32 status;
-
-	chained_irq_enter(host_chip, desc);
-
-	clk_enable(nmk_chip->clk);
-	status = readl(nmk_chip->addr + NMK_GPIO_IS);
-	clk_disable(nmk_chip->clk);
-
-	while (status) {
-		int bit = __ffs(status);
-
-		generic_handle_domain_irq(chip->irq.domain, bit);
-		status &= ~BIT(bit);
-	}
-
-	chained_irq_exit(host_chip, desc);
-}
-
-/* I/O Functions */
-
-static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned offset)
-{
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-	int dir;
-
-	clk_enable(nmk_chip->clk);
-
-	dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset);
-
-	clk_disable(nmk_chip->clk);
-
-	if (dir)
-		return GPIO_LINE_DIRECTION_OUT;
-
-	return GPIO_LINE_DIRECTION_IN;
-}
-
-static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-
-	clk_enable(nmk_chip->clk);
-
-	writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC);
-
-	clk_disable(nmk_chip->clk);
-
-	return 0;
-}
-
-static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-	int value;
-
-	clk_enable(nmk_chip->clk);
-
-	value = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
-
-	clk_disable(nmk_chip->clk);
-
-	return value;
-}
-
-static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
-				int val)
-{
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-
-	clk_enable(nmk_chip->clk);
-
-	__nmk_gpio_set_output(nmk_chip, offset, val);
-
-	clk_disable(nmk_chip->clk);
-}
-
-static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
-				int val)
-{
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-
-	clk_enable(nmk_chip->clk);
-
-	__nmk_gpio_make_output(nmk_chip, offset, val);
-
-	clk_disable(nmk_chip->clk);
-
-	return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static int nmk_gpio_get_mode(struct nmk_gpio_chip *nmk_chip, int offset)
-{
-	u32 afunc, bfunc;
-
-	clk_enable(nmk_chip->clk);
-
-	afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & BIT(offset);
-	bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & BIT(offset);
-
-	clk_disable(nmk_chip->clk);
-
-	return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
-}
-
-static void nmk_gpio_dbg_show_one(struct seq_file *s,
-	struct pinctrl_dev *pctldev, struct gpio_chip *chip,
-	unsigned offset, unsigned gpio)
-{
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-	int mode;
-	bool is_out;
-	bool data_out;
-	bool pull;
-	const char *modes[] = {
-		[NMK_GPIO_ALT_GPIO]	= "gpio",
-		[NMK_GPIO_ALT_A]	= "altA",
-		[NMK_GPIO_ALT_B]	= "altB",
-		[NMK_GPIO_ALT_C]	= "altC",
-		[NMK_GPIO_ALT_C+1]	= "altC1",
-		[NMK_GPIO_ALT_C+2]	= "altC2",
-		[NMK_GPIO_ALT_C+3]	= "altC3",
-		[NMK_GPIO_ALT_C+4]	= "altC4",
-	};
-
-	char *label = gpiochip_dup_line_label(chip, offset);
-	if (IS_ERR(label))
-		return;
-
-	clk_enable(nmk_chip->clk);
-	is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
-	pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & BIT(offset));
-	data_out = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
-	mode = nmk_gpio_get_mode(nmk_chip, offset);
-	if ((mode == NMK_GPIO_ALT_C) && pctldev)
-		mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio);
-
-	if (is_out) {
-		seq_printf(s, " gpio-%-3d (%-20.20s) out %s           %s",
-			   gpio,
-			   label ?: "(none)",
-			   data_out ? "hi" : "lo",
-			   (mode < 0) ? "unknown" : modes[mode]);
-	} else {
-		int irq = chip->to_irq(chip, offset);
-		const int pullidx = pull ? 1 : 0;
-		int val;
-		static const char * const pulls[] = {
-			"none        ",
-			"pull enabled",
-		};
-
-		seq_printf(s, " gpio-%-3d (%-20.20s) in  %s %s",
-			   gpio,
-			   label ?: "(none)",
-			   pulls[pullidx],
-			   (mode < 0) ? "unknown" : modes[mode]);
-
-		val = nmk_gpio_get_input(chip, offset);
-		seq_printf(s, " VAL %d", val);
-
-		/*
-		 * This races with request_irq(), set_irq_type(),
-		 * and set_irq_wake() ... but those are "rare".
-		 */
-		if (irq > 0 && irq_has_action(irq)) {
-			char *trigger;
-			bool wake;
-
-			if (nmk_chip->edge_rising & BIT(offset))
-				trigger = "edge-rising";
-			else if (nmk_chip->edge_falling & BIT(offset))
-				trigger = "edge-falling";
-			else
-				trigger = "edge-undefined";
-
-			wake = !!(nmk_chip->real_wake & BIT(offset));
-
-			seq_printf(s, " irq-%d %s%s",
-				   irq, trigger, wake ? " wakeup" : "");
-		}
-	}
-	clk_disable(nmk_chip->clk);
-}
-
-static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
-{
-	unsigned		i;
-	unsigned		gpio = chip->base;
-
-	for (i = 0; i < chip->ngpio; i++, gpio++) {
-		nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio);
-		seq_printf(s, "\n");
-	}
-}
-
-#else
-static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
-					 struct pinctrl_dev *pctldev,
-					 struct gpio_chip *chip,
-					 unsigned offset, unsigned gpio)
-{
-}
-#define nmk_gpio_dbg_show	NULL
-#endif
-
-/*
- * We will allocate memory for the state container using devm* allocators
- * binding to the first device reaching this point, it doesn't matter if
- * it is the pin controller or GPIO driver. However we need to use the right
- * platform device when looking up resources so pay attention to pdev.
- */
-static struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
-						struct platform_device *pdev)
-{
-	struct nmk_gpio_chip *nmk_chip;
-	struct platform_device *gpio_pdev;
-	struct gpio_chip *chip;
-	struct resource *res;
-	struct clk *clk;
-	void __iomem *base;
-	u32 id;
-
-	gpio_pdev = of_find_device_by_node(np);
-	if (!gpio_pdev) {
-		pr_err("populate \"%pOFn\": device not found\n", np);
-		return ERR_PTR(-ENODEV);
-	}
-	if (of_property_read_u32(np, "gpio-bank", &id)) {
-		dev_err(&pdev->dev, "populate: gpio-bank property not found\n");
-		platform_device_put(gpio_pdev);
-		return ERR_PTR(-EINVAL);
-	}
-
-	/* Already populated? */
-	nmk_chip = nmk_gpio_chips[id];
-	if (nmk_chip) {
-		platform_device_put(gpio_pdev);
-		return nmk_chip;
-	}
-
-	nmk_chip = devm_kzalloc(&pdev->dev, sizeof(*nmk_chip), GFP_KERNEL);
-	if (!nmk_chip) {
-		platform_device_put(gpio_pdev);
-		return ERR_PTR(-ENOMEM);
-	}
-
-	nmk_chip->bank = id;
-	chip = &nmk_chip->chip;
-	chip->base = id * NMK_GPIO_PER_CHIP;
-	chip->ngpio = NMK_GPIO_PER_CHIP;
-	chip->label = dev_name(&gpio_pdev->dev);
-	chip->parent = &gpio_pdev->dev;
-
-	res = platform_get_resource(gpio_pdev, IORESOURCE_MEM, 0);
-	base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(base)) {
-		platform_device_put(gpio_pdev);
-		return ERR_CAST(base);
-	}
-	nmk_chip->addr = base;
-
-	clk = clk_get(&gpio_pdev->dev, NULL);
-	if (IS_ERR(clk)) {
-		platform_device_put(gpio_pdev);
-		return (void *) clk;
-	}
-	clk_prepare(clk);
-	nmk_chip->clk = clk;
-
-	BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
-	nmk_gpio_chips[id] = nmk_chip;
-	return nmk_chip;
-}
-
-static void nmk_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
-
-	seq_printf(p, "nmk%u-%u-%u", nmk_chip->bank,
-		   gc->base, gc->base + gc->ngpio - 1);
-}
-
-static const struct irq_chip nmk_irq_chip = {
-	.irq_ack = nmk_gpio_irq_ack,
-	.irq_mask = nmk_gpio_irq_mask,
-	.irq_unmask = nmk_gpio_irq_unmask,
-	.irq_set_type = nmk_gpio_irq_set_type,
-	.irq_set_wake = nmk_gpio_irq_set_wake,
-	.irq_startup = nmk_gpio_irq_startup,
-	.irq_shutdown = nmk_gpio_irq_shutdown,
-	.irq_print_chip = nmk_gpio_irq_print_chip,
-	.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE,
-	GPIOCHIP_IRQ_RESOURCE_HELPERS,
-};
-
-static int nmk_gpio_probe(struct platform_device *dev)
-{
-	struct device_node *np = dev->dev.of_node;
-	struct nmk_gpio_chip *nmk_chip;
-	struct gpio_chip *chip;
-	struct gpio_irq_chip *girq;
-	bool supports_sleepmode;
-	int irq;
-	int ret;
-
-	nmk_chip = nmk_gpio_populate_chip(np, dev);
-	if (IS_ERR(nmk_chip)) {
-		dev_err(&dev->dev, "could not populate nmk chip struct\n");
-		return PTR_ERR(nmk_chip);
-	}
-
-	supports_sleepmode =
-		of_property_read_bool(np, "st,supports-sleepmode");
-
-	/* Correct platform device ID */
-	dev->id = nmk_chip->bank;
-
-	irq = platform_get_irq(dev, 0);
-	if (irq < 0)
-		return irq;
-
-	/*
-	 * The virt address in nmk_chip->addr is in the nomadik register space,
-	 * so we can simply convert the resource address, without remapping
-	 */
-	nmk_chip->sleepmode = supports_sleepmode;
-	spin_lock_init(&nmk_chip->lock);
-
-	chip = &nmk_chip->chip;
-	chip->parent = &dev->dev;
-	chip->request = gpiochip_generic_request;
-	chip->free = gpiochip_generic_free;
-	chip->get_direction = nmk_gpio_get_dir;
-	chip->direction_input = nmk_gpio_make_input;
-	chip->get = nmk_gpio_get_input;
-	chip->direction_output = nmk_gpio_make_output;
-	chip->set = nmk_gpio_set_output;
-	chip->dbg_show = nmk_gpio_dbg_show;
-	chip->can_sleep = false;
-	chip->owner = THIS_MODULE;
-
-	girq = &chip->irq;
-	gpio_irq_chip_set_chip(girq, &nmk_irq_chip);
-	girq->parent_handler = nmk_gpio_irq_handler;
-	girq->num_parents = 1;
-	girq->parents = devm_kcalloc(&dev->dev, 1,
-				     sizeof(*girq->parents),
-				     GFP_KERNEL);
-	if (!girq->parents)
-		return -ENOMEM;
-	girq->parents[0] = irq;
-	girq->default_type = IRQ_TYPE_NONE;
-	girq->handler = handle_edge_irq;
-
-	clk_enable(nmk_chip->clk);
-	nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
-	clk_disable(nmk_chip->clk);
-
-	ret = gpiochip_add_data(chip, nmk_chip);
-	if (ret)
-		return ret;
-
-	platform_set_drvdata(dev, nmk_chip);
-
-	dev_info(&dev->dev, "chip registered\n");
-
-	return 0;
-}
-
 static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
@@ -1197,12 +524,12 @@ static const char *nmk_get_group_name(struct pinctrl_dev *pctldev,
 
 static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
 			      const unsigned **pins,
-			      unsigned *npins)
+			      unsigned int *num_pins)
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 
 	*pins = npct->soc->groups[selector].grp.pins;
-	*npins = npct->soc->groups[selector].grp.npins;
+	*num_pins = npct->soc->groups[selector].grp.npins;
 	return 0;
 }
 
@@ -1533,7 +860,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function,
 {
 	struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
 	const struct nmk_pingroup *g;
-	static unsigned int slpm[NUM_BANKS];
+	static unsigned int slpm[NMK_MAX_BANKS];
 	unsigned long flags = 0;
 	bool glitch;
 	int ret = -EINVAL;
@@ -1919,19 +1246,6 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static const struct of_device_id nmk_gpio_match[] = {
-	{ .compatible = "st,nomadik-gpio", },
-	{}
-};
-
-static struct platform_driver nmk_gpio_driver = {
-	.driver = {
-		.name = "gpio",
-		.of_match_table = nmk_gpio_match,
-	},
-	.probe = nmk_gpio_probe,
-};
-
 static SIMPLE_DEV_PM_OPS(nmk_pinctrl_pm_ops,
 			nmk_pinctrl_suspend,
 			nmk_pinctrl_resume);
@@ -1945,12 +1259,6 @@ static struct platform_driver nmk_pinctrl_driver = {
 	.probe = nmk_pinctrl_probe,
 };
 
-static int __init nmk_gpio_init(void)
-{
-	return platform_driver_register(&nmk_gpio_driver);
-}
-subsys_initcall(nmk_gpio_init);
-
 static int __init nmk_pinctrl_init(void)
 {
 	return platform_driver_register(&nmk_pinctrl_driver);
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.h b/include/linux/gpio/gpio-nomadik.h
similarity index 61%
rename from drivers/pinctrl/nomadik/pinctrl-nomadik.h
rename to include/linux/gpio/gpio-nomadik.h
index 1ef2559bc571..0166ddb71f43 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.h
+++ b/include/linux/gpio/gpio-nomadik.h
@@ -1,16 +1,74 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef PINCTRL_PINCTRL_NOMADIK_H
-#define PINCTRL_PINCTRL_NOMADIK_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-#include <linux/pinctrl/pinctrl.h>
+#ifndef __LINUX_GPIO_NOMADIK_H
+#define __LINUX_GPIO_NOMADIK_H
 
 /* Package definitions */
 #define PINCTRL_NMK_STN8815	0
 #define PINCTRL_NMK_DB8500	1
 
+#define GPIO_BLOCK_SHIFT 5
+#define NMK_GPIO_PER_CHIP BIT(GPIO_BLOCK_SHIFT)
+#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP)
+
+/* Register in the logic block */
+#define NMK_GPIO_DAT	0x00
+#define NMK_GPIO_DATS	0x04
+#define NMK_GPIO_DATC	0x08
+#define NMK_GPIO_PDIS	0x0c
+#define NMK_GPIO_DIR	0x10
+#define NMK_GPIO_DIRS	0x14
+#define NMK_GPIO_DIRC	0x18
+#define NMK_GPIO_SLPC	0x1c
+#define NMK_GPIO_AFSLA	0x20
+#define NMK_GPIO_AFSLB	0x24
+#define NMK_GPIO_LOWEMI	0x28
+
+#define NMK_GPIO_RIMSC	0x40
+#define NMK_GPIO_FIMSC	0x44
+#define NMK_GPIO_IS	0x48
+#define NMK_GPIO_IC	0x4c
+#define NMK_GPIO_RWIMSC	0x50
+#define NMK_GPIO_FWIMSC	0x54
+#define NMK_GPIO_WKS	0x58
+/* These appear in DB8540 and later ASICs */
+#define NMK_GPIO_EDGELEVEL 0x5C
+#define NMK_GPIO_LEVEL	0x60
+
+/* Pull up/down values */
+enum nmk_gpio_pull {
+	NMK_GPIO_PULL_NONE,
+	NMK_GPIO_PULL_UP,
+	NMK_GPIO_PULL_DOWN,
+};
+
+/* Sleep mode */
+enum nmk_gpio_slpm {
+	NMK_GPIO_SLPM_INPUT,
+	NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
+	NMK_GPIO_SLPM_NOCHANGE,
+	NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
+};
+
+struct nmk_gpio_chip {
+	struct gpio_chip chip;
+	void __iomem *addr;
+	struct clk *clk;
+	unsigned int bank;
+	void (*set_ioforce)(bool enable);
+	spinlock_t lock;
+	bool sleepmode;
+	/* Keep track of configured edges */
+	u32 edge_rising;
+	u32 edge_falling;
+	u32 real_wake;
+	u32 rwimsc;
+	u32 fwimsc;
+	u32 rimsc;
+	u32 fimsc;
+	u32 pull_up;
+	u32 lowemi;
+};
+
 /* Alternate functions: function C is set in hw by setting both A and B */
 #define NMK_GPIO_ALT_GPIO	0
 #define NMK_GPIO_ALT_A	1
@@ -104,7 +162,7 @@ struct prcm_gpiocr_altcx_pin_desc {
 struct nmk_function {
 	const char *name;
 	const char * const *groups;
-	unsigned ngroups;
+	unsigned int ngroups;
 };
 
 /**
@@ -141,13 +199,13 @@ struct nmk_pingroup {
  */
 struct nmk_pinctrl_soc_data {
 	const struct pinctrl_pin_desc *pins;
-	unsigned npins;
+	unsigned int npins;
 	const struct nmk_function *functions;
-	unsigned nfunctions;
+	unsigned int nfunctions;
 	const struct nmk_pingroup *groups;
-	unsigned ngroups;
+	unsigned int ngroups;
 	const struct prcm_gpiocr_altcx_pin_desc *altcx_pins;
-	unsigned npins_altcx;
+	unsigned int npins_altcx;
 	const u16 *prcm_gpiocr_registers;
 };
 
@@ -177,4 +235,42 @@ nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
 
 #endif
 
-#endif /* PINCTRL_PINCTRL_NOMADIK_H */
+#ifdef CONFIG_PINCTRL_DB8540
+
+void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
+struct platform_device;
+
+/*
+ * Symbols declared in gpio-nomadik used by pinctrl-nomadik. If pinctrl-nomadik
+ * is enabled, then gpio-nomadik is enabled as well; the reverse if not always
+ * true.
+ */
+void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev,
+			   struct gpio_chip *chip, unsigned int offset,
+			   unsigned int gpio);
+void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
+			    unsigned int offset, int val);
+void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset,
+			 enum nmk_gpio_slpm mode);
+struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
+					     struct platform_device *pdev);
+
+/* Symbols declared in pinctrl-nomadik used by gpio-nomadik. */
+#ifdef CONFIG_PINCTRL_NOMADIK
+extern struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
+extern spinlock_t nmk_gpio_slpm_lock;
+int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev,
+					    int gpio);
+#endif
+
+#endif /* __LINUX_GPIO_NOMADIK_H */

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:07 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:07 +0100
Subject: [PATCH 14/23] gpio: nomadik: make clock optional
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-14-f88c0ccf372b@bootlin.com>

Not all platforms using this platform driver expose a clock for this
GPIO controller. Turn clk_get() into clk_get_optional() to avoid
failing when no clocks are provided.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/gpio/gpio-nomadik.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
index 8d47aef8d2c4..2e7d3840b714 100644
--- a/drivers/gpio/gpio-nomadik.c
+++ b/drivers/gpio/gpio-nomadik.c
@@ -529,7 +529,7 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
 	}
 	nmk_chip->addr = base;
 
-	clk = clk_get(&gpio_pdev->dev, NULL);
+	clk = clk_get_optional(&gpio_pdev->dev, NULL);
 	if (IS_ERR(clk)) {
 		platform_device_put(gpio_pdev);
 		return (void *)clk;

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:08 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:08 +0100
Subject: [PATCH 15/23] gpio: nomadik: change driver name from gpio to
 gpio-nomadik
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-15-f88c0ccf372b@bootlin.com>

This GPIO driver is historically related to the Nomadik platform. It
however can be used by others as it implements the ST STA2X11 IP block.
Pick a less ambiguous name for it.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/gpio/gpio-nomadik.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
index 2e7d3840b714..25c8490aa1b6 100644
--- a/drivers/gpio/gpio-nomadik.c
+++ b/drivers/gpio/gpio-nomadik.c
@@ -647,7 +647,7 @@ static const struct of_device_id nmk_gpio_match[] = {
 
 static struct platform_driver nmk_gpio_driver = {
 	.driver = {
-		.name = "gpio",
+		.name = "nomadik-gpio",
 		.of_match_table = nmk_gpio_match,
 	},
 	.probe = nmk_gpio_probe,

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:09 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:09 +0100
Subject: [PATCH 16/23] gpio: nomadik: support shared GPIO IRQs
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-16-f88c0ccf372b@bootlin.com>

Support a single IRQs used by multiple GPIO banks. Change the IRQ
handler type from a chained handler (as used by gpiolib
for ->parent_handler) to a threaded IRQ.

Use a fake raw spinlock to ensure generic_handle_irq() is called in a
no-irq context. See Documentation/driver-api/gpio/driver.rst, "CHAINED
CASCADED GPIO IRQCHIPS" for additional information.

The Mobileye EyeQ5 platform uses this GPIO controller and share an IRQ
for its two banks.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/gpio/gpio-nomadik.c       | 67 +++++++++++++++++++++------------------
 include/linux/gpio/gpio-nomadik.h |  1 +
 2 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
index 25c8490aa1b6..5b1e3b3efcff 100644
--- a/drivers/gpio/gpio-nomadik.c
+++ b/drivers/gpio/gpio-nomadik.c
@@ -254,27 +254,31 @@ static void nmk_gpio_irq_shutdown(struct irq_data *d)
 	clk_disable(nmk_chip->clk);
 }
 
-static void nmk_gpio_irq_handler(struct irq_desc *desc)
+static irqreturn_t nmk_gpio_irq_handler(int irq, void *dev_id)
 {
-	struct irq_chip *host_chip = irq_desc_get_chip(desc);
-	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
-	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
-	u32 status;
-
-	chained_irq_enter(host_chip, desc);
+	struct nmk_gpio_chip *nmk_chip = dev_id;
+	struct gpio_chip *chip = &nmk_chip->chip;
+	unsigned long mask = GENMASK(chip->ngpio - 1, 0);
+	unsigned long flags, status;
+	int bit;
 
 	clk_enable(nmk_chip->clk);
+
 	status = readl(nmk_chip->addr + NMK_GPIO_IS);
-	clk_disable(nmk_chip->clk);
 
-	while (status) {
-		int bit = __ffs(status);
+	/* Ensure we cannot leave pending bits; this should never occur. */
+	if (unlikely(status & ~mask))
+		writel(status & ~mask, nmk_chip->addr + NMK_GPIO_IC);
+
+	clk_disable(nmk_chip->clk);
 
+	for_each_set_bit(bit, &status, chip->ngpio) {
+		raw_spin_lock_irqsave(&nmk_chip->fake_lock, flags);
 		generic_handle_domain_irq(chip->irq.domain, bit);
-		status &= ~BIT(bit);
+		raw_spin_unlock_irqrestore(&nmk_chip->fake_lock, flags);
 	}
 
-	chained_irq_exit(host_chip, desc);
+	return IRQ_RETVAL((status & mask) != 0);
 }
 
 /* I/O Functions */
@@ -566,19 +570,20 @@ static const struct irq_chip nmk_irq_chip = {
 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
 };
 
-static int nmk_gpio_probe(struct platform_device *dev)
+static int nmk_gpio_probe(struct platform_device *pdev)
 {
-	struct device_node *np = dev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct nmk_gpio_chip *nmk_chip;
-	struct gpio_chip *chip;
 	struct gpio_irq_chip *girq;
 	bool supports_sleepmode;
+	struct gpio_chip *chip;
 	int irq;
 	int ret;
 
-	nmk_chip = nmk_gpio_populate_chip(np, dev);
+	nmk_chip = nmk_gpio_populate_chip(np, pdev);
 	if (IS_ERR(nmk_chip)) {
-		dev_err(&dev->dev, "could not populate nmk chip struct\n");
+		dev_err(dev, "could not populate nmk chip struct\n");
 		return PTR_ERR(nmk_chip);
 	}
 
@@ -586,9 +591,9 @@ static int nmk_gpio_probe(struct platform_device *dev)
 		of_property_read_bool(np, "st,supports-sleepmode");
 
 	/* Correct platform device ID */
-	dev->id = nmk_chip->bank;
+	pdev->id = nmk_chip->bank;
 
-	irq = platform_get_irq(dev, 0);
+	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
 		return irq;
 
@@ -600,7 +605,7 @@ static int nmk_gpio_probe(struct platform_device *dev)
 	spin_lock_init(&nmk_chip->lock);
 
 	chip = &nmk_chip->chip;
-	chip->parent = &dev->dev;
+	chip->parent = dev;
 	chip->request = gpiochip_generic_request;
 	chip->free = gpiochip_generic_free;
 	chip->get_direction = nmk_gpio_get_dir;
@@ -614,17 +619,19 @@ static int nmk_gpio_probe(struct platform_device *dev)
 
 	girq = &chip->irq;
 	gpio_irq_chip_set_chip(girq, &nmk_irq_chip);
-	girq->parent_handler = nmk_gpio_irq_handler;
-	girq->num_parents = 1;
-	girq->parents = devm_kcalloc(&dev->dev, 1,
-				     sizeof(*girq->parents),
-				     GFP_KERNEL);
-	if (!girq->parents)
-		return -ENOMEM;
-	girq->parents[0] = irq;
+	girq->parent_handler = NULL;
+	girq->num_parents = 0;
+	girq->parents = NULL;
 	girq->default_type = IRQ_TYPE_NONE;
 	girq->handler = handle_edge_irq;
 
+	ret = devm_request_irq(dev, irq, nmk_gpio_irq_handler, IRQF_SHARED,
+			       dev_name(dev), nmk_chip);
+	if (ret) {
+		dev_err(dev, "failed requesting IRQ\n");
+		return ret;
+	}
+
 	clk_enable(nmk_chip->clk);
 	nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
 	clk_disable(nmk_chip->clk);
@@ -633,9 +640,9 @@ static int nmk_gpio_probe(struct platform_device *dev)
 	if (ret)
 		return ret;
 
-	platform_set_drvdata(dev, nmk_chip);
+	platform_set_drvdata(pdev, nmk_chip);
 
-	dev_info(&dev->dev, "chip registered\n");
+	dev_info(dev, "chip registered\n");
 
 	return 0;
 }
diff --git a/include/linux/gpio/gpio-nomadik.h b/include/linux/gpio/gpio-nomadik.h
index 0166ddb71f43..8f7bb756ad35 100644
--- a/include/linux/gpio/gpio-nomadik.h
+++ b/include/linux/gpio/gpio-nomadik.h
@@ -56,6 +56,7 @@ struct nmk_gpio_chip {
 	unsigned int bank;
 	void (*set_ioforce)(bool enable);
 	spinlock_t lock;
+	raw_spinlock_t fake_lock;
 	bool sleepmode;
 	/* Keep track of configured edges */
 	u32 edge_rising;

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:10 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:10 +0100
Subject: [PATCH 17/23] gpio: nomadik: handle variadic GPIO count
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-17-f88c0ccf372b@bootlin.com>

Read the "ngpios" device-tree property to determine the number of GPIOs
for a bank. If not available, fallback to NMK_GPIO_PER_CHIP ie 32 ie
the current behavior.

The IP block always supports 32 GPIOs, but platforms can expose a lesser
amount. The Mobileye EyeQ5 is in this case; one bank is 29 GPIOs and
the other is 23.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/gpio/gpio-nomadik.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
index 5b1e3b3efcff..02b53c58adf7 100644
--- a/drivers/gpio/gpio-nomadik.c
+++ b/drivers/gpio/gpio-nomadik.c
@@ -490,7 +490,7 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
 	struct resource *res;
 	struct clk *clk;
 	void __iomem *base;
-	u32 id;
+	u32 id, ngpio;
 
 	gpio_pdev = of_find_device_by_node(np);
 	if (!gpio_pdev) {
@@ -518,10 +518,15 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
 		return ERR_PTR(-ENOMEM);
 	}
 
+	if (of_property_read_u32(np, "ngpios", &ngpio)) {
+		ngpio = NMK_GPIO_PER_CHIP;
+		dev_dbg(&pdev->dev, "populate: using default ngpio (%d)\n", ngpio);
+	}
+
 	nmk_chip->bank = id;
 	chip = &nmk_chip->chip;
 	chip->base = -1;
-	chip->ngpio = NMK_GPIO_PER_CHIP;
+	chip->ngpio = ngpio;
 	chip->label = dev_name(&gpio_pdev->dev);
 	chip->parent = &gpio_pdev->dev;
 

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:11 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:11 +0100
Subject: [PATCH 18/23] gpio: nomadik: support mobileye,eyeq5-gpio
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-18-f88c0ccf372b@bootlin.com>

We create a custom compatible for the STA2X11 IP block as integrated
into the Mobileye EyeQ5 platform. Its wake and alternate functions have
been disabled, we want to avoid touching those registers.

We both do: (1) early return in functions that do not support the
platform, but with warnings, and (2) avoid calling those functions in
the first place.

We ensure that pinctrl-nomadik is not used with this STA2X11 variant.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/gpio/Kconfig                      |  5 +--
 drivers/gpio/gpio-nomadik.c               | 52 ++++++++++++++++++++++++++-----
 drivers/pinctrl/nomadik/pinctrl-nomadik.c |  2 ++
 include/linux/gpio/gpio-nomadik.h         |  1 +
 4 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ff83371251c1..fe6112abb73a 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -480,11 +480,12 @@ config GPIO_MXS
 
 config GPIO_NOMADIK
 	bool "Nomadik GPIO driver"
-	depends on ARCH_U8500 || ARCH_NOMADIK || COMPILE_TEST
+	depends on ARCH_U8500 || ARCH_NOMADIK || MACH_EYEQ5 || COMPILE_TEST
 	select OF_GPIO
 	select GPIOLIB_IRQCHIP
 	help
-	  Say yes here to support the Nomadik SoC GPIO block.
+	  Say yes here to support the Nomadik SoC GPIO block. This block is also
+	  used by the Mobileye EyeQ5 SoC.
 
 	  It handles up to 32 GPIOs per bank, that can all be interrupt sources.
 	  It is deeply interconnected with the associated pinctrl driver as GPIO
diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
index 02b53c58adf7..21bb6d6363fc 100644
--- a/drivers/gpio/gpio-nomadik.c
+++ b/drivers/gpio/gpio-nomadik.c
@@ -7,6 +7,12 @@
  * The GPIO chips are shared with pinctrl-nomadik if used; it needs access for
  * pinmuxing functionality and others.
  *
+ * This driver also handles the mobileye,eyeq5-gpio compatible. It is an STA2X11
+ * but with only data, direction and interrupts register active. We want to
+ * avoid touching SLPM, RWIMSC, FWIMSC, AFSLA and AFSLB registers; that is,
+ * wake and alternate function registers. It is NOT compatible with
+ * pinctrl-nomadik.
+ *
  * Copyright (C) 2008,2009 STMicroelectronics
  * Copyright (C) 2009 Alessandro Rubini <rubini at unipv.it>
  *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar at st.com>
@@ -31,11 +37,17 @@
 static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
 #endif
 
+#define NMK_GPIO_FLAG_QUIRK_MBLY	BIT(0)
+
 void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset,
 			 enum nmk_gpio_slpm mode)
 {
 	u32 slpm;
 
+	/* We should NOT have been called. */
+	if (WARN_ON(nmk_chip->quirk_mbly))
+		return;
+
 	slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
 	if (mode == NMK_GPIO_SLPM_NOCHANGE)
 		slpm |= BIT(offset);
@@ -92,6 +104,9 @@ static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
 		rimscval = &nmk_chip->rimsc;
 		fimscval = &nmk_chip->fimsc;
 	} else  {
+		/* We should NOT have been called. */
+		if (WARN_ON(nmk_chip->quirk_mbly))
+			return;
 		rimscreg = NMK_GPIO_RWIMSC;
 		fimscreg = NMK_GPIO_FWIMSC;
 		rimscval = &nmk_chip->rwimsc;
@@ -118,6 +133,10 @@ static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
 static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
 				int offset, bool on)
 {
+	/* We should NOT have been called. */
+	if (WARN_ON(nmk_chip->quirk_mbly))
+		return;
+
 	/*
 	 * Ensure WAKEUP_ENABLE is on.  No need to disable it if wakeup is
 	 * disabled, since setting SLPM to 1 increases power consumption, and
@@ -142,7 +161,7 @@ static void nmk_gpio_irq_maskunmask(struct nmk_gpio_chip *nmk_chip,
 
 	__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
 
-	if (!(nmk_chip->real_wake & BIT(d->hwirq)))
+	if (!nmk_chip->quirk_mbly && !(nmk_chip->real_wake & BIT(d->hwirq)))
 		__nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
 
 	spin_unlock(&nmk_chip->lock);
@@ -174,6 +193,10 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
 	struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
 	unsigned long flags;
 
+	/* Handler is registered in all cases. */
+	if (nmk_chip->quirk_mbly)
+		return -ENXIO;
+
 	clk_enable(nmk_chip->clk);
 	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
 	spin_lock(&nmk_chip->lock);
@@ -212,7 +235,7 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 	if (enabled)
 		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
 
-	if (enabled || wake)
+	if (!nmk_chip->quirk_mbly && (enabled || wake))
 		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
 
 	nmk_chip->edge_rising &= ~BIT(d->hwirq);
@@ -226,7 +249,7 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 	if (enabled)
 		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
 
-	if (enabled || wake)
+	if (!nmk_chip->quirk_mbly && (enabled || wake))
 		__nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
 
 	spin_unlock_irqrestore(&nmk_chip->lock, flags);
@@ -359,6 +382,10 @@ static int nmk_gpio_get_mode(struct nmk_gpio_chip *nmk_chip, int offset)
 {
 	u32 afunc, bfunc;
 
+	/* We don't support modes. */
+	if (nmk_chip->quirk_mbly)
+		return NMK_GPIO_ALT_GPIO;
+
 	clk_enable(nmk_chip->clk);
 
 	afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & BIT(offset);
@@ -490,6 +517,7 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
 	struct resource *res;
 	struct clk *clk;
 	void __iomem *base;
+	uintptr_t flags;
 	u32 id, ngpio;
 
 	gpio_pdev = of_find_device_by_node(np);
@@ -523,6 +551,8 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
 		dev_dbg(&pdev->dev, "populate: using default ngpio (%d)\n", ngpio);
 	}
 
+	flags = (uintptr_t)of_device_get_match_data(&gpio_pdev->dev);
+	nmk_chip->quirk_mbly = !!(flags & NMK_GPIO_FLAG_QUIRK_MBLY);
 	nmk_chip->bank = id;
 	chip = &nmk_chip->chip;
 	chip->base = -1;
@@ -637,9 +667,11 @@ static int nmk_gpio_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	clk_enable(nmk_chip->clk);
-	nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
-	clk_disable(nmk_chip->clk);
+	if (!nmk_chip->quirk_mbly) {
+		clk_enable(nmk_chip->clk);
+		nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
+		clk_disable(nmk_chip->clk);
+	}
 
 	ret = gpiochip_add_data(chip, nmk_chip);
 	if (ret)
@@ -653,7 +685,13 @@ static int nmk_gpio_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id nmk_gpio_match[] = {
-	{ .compatible = "st,nomadik-gpio", },
+	{
+		.compatible = "st,nomadik-gpio",
+	},
+	{
+		.compatible = "mobileye,eyeq5-gpio",
+		.data = (void*)NMK_GPIO_FLAG_QUIRK_MBLY,
+	},
 	{}
 };
 
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 99bdb25f358d..d1c5f353c6a9 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -1229,6 +1229,8 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev,
 				"could not populate nmk chip struct - continue anyway\n");
 		of_node_put(gpio_np);
+		/* We are NOT compatible with mobileye,eyeq5-gpio. */
+		BUG_ON(nmk_chip->quirk_mbly);
 	}
 
 	prcm_np = of_parse_phandle(np, "prcm", 0);
diff --git a/include/linux/gpio/gpio-nomadik.h b/include/linux/gpio/gpio-nomadik.h
index 8f7bb756ad35..8d0134dd3771 100644
--- a/include/linux/gpio/gpio-nomadik.h
+++ b/include/linux/gpio/gpio-nomadik.h
@@ -58,6 +58,7 @@ struct nmk_gpio_chip {
 	spinlock_t lock;
 	raw_spinlock_t fake_lock;
 	bool sleepmode;
+	bool quirk_mbly;
 	/* Keep track of configured edges */
 	u32 edge_rising;
 	u32 edge_falling;

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:12 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:12 +0100
Subject: [PATCH 19/23] gpio: nomadik: grab optional reset control and
 deassert it at probe
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-19-f88c0ccf372b@bootlin.com>

Fetch a reference to the optional shared reset control and deassert it
if it exists.

Optional because not all platforms that use this driver have a reset
attached to the reset block. Shared because some platforms that use the
reset (at least Mobileye EyeQ5) share the reset across banks.

Do not keep a reference to the reset control as it is not needed
afterwards; the driver does not handle suspend, does not use runtime PM
and does not register a remove callback.

The operation is done in nmk_gpio_populate_chip(). This function is
called by either gpio-nomadik or pinctrl-nomadik, whoever comes first.
This is here for historic reasons and could probably be removed now; it
seems gpio-ranges enforces the ordering to be pinctrl-first. It is not
the topic of the present patch however.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/gpio/gpio-nomadik.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
index 21bb6d6363fc..b623c093b54d 100644
--- a/drivers/gpio/gpio-nomadik.c
+++ b/drivers/gpio/gpio-nomadik.c
@@ -513,12 +513,14 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
 {
 	struct nmk_gpio_chip *nmk_chip;
 	struct platform_device *gpio_pdev;
+	struct reset_control *reset;
 	struct gpio_chip *chip;
 	struct resource *res;
 	struct clk *clk;
 	void __iomem *base;
 	uintptr_t flags;
 	u32 id, ngpio;
+	int ret;
 
 	gpio_pdev = of_find_device_by_node(np);
 	if (!gpio_pdev) {
@@ -576,6 +578,19 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
 	clk_prepare(clk);
 	nmk_chip->clk = clk;
 
+	reset = devm_reset_control_get_optional_shared(&gpio_pdev->dev, NULL);
+	if (IS_ERR(reset)) {
+		dev_err(&pdev->dev, "failed getting reset control: %ld\n",
+			PTR_ERR(reset));
+		return ERR_CAST(reset);
+	}
+
+	ret = reset_control_deassert(reset);
+	if (ret) {
+		dev_err(&pdev->dev, "failed reset deassert: %d\n", ret);
+		return ERR_PTR(ret);
+	}
+
 #ifdef CONFIG_PINCTRL_NOMADIK
 	BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
 	nmk_gpio_chips[id] = nmk_chip;

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:13 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:13 +0100
Subject: [PATCH 20/23] MIPS: eyeq5_defconfig: enable GPIO by default
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-20-f88c0ccf372b@bootlin.com>

Add both CONFIG_GPIOLIB=y and CONFIG_GPIO_NOMADIK=y to our platform
defconfig. Default config is CONFIG_GPIOLIB=n.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 arch/mips/configs/eyeq5_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/mips/configs/eyeq5_defconfig b/arch/mips/configs/eyeq5_defconfig
index c35c29a4d479..6f052d4c5e58 100644
--- a/arch/mips/configs/eyeq5_defconfig
+++ b/arch/mips/configs/eyeq5_defconfig
@@ -66,6 +66,8 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_HW_RANDOM=y
 # CONFIG_PTP_1588_CLOCK is not set
 CONFIG_PINCTRL=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_NOMADIK=y
 CONFIG_MFD_SYSCON=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_BELKIN=y

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:14 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:14 +0100
Subject: [PATCH 21/23] MIPS: mobileye: eyeq5: add two GPIO bank nodes
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-21-f88c0ccf372b@bootlin.com>

This platform uses the same GPIO controller as Nomadik. It however has
its own pinconf & pinmux controller. EyeQ5 is the first platform to use
gpio-nomadik independently from pinctrl-nomadik.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 arch/mips/boot/dts/mobileye/eyeq5.dtsi | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
index 8d4f65ec912d..0f18ac73620b 100644
--- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi
+++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
@@ -158,6 +158,32 @@ timer {
 				clocks = <&core0_clk>;
 			};
 		};
+
+		gpio0: gpio at 1400000 {
+			compatible = "mobileye,eyeq5-gpio";
+			reg = <0x0 0x1400000 0x0 0x1000>;
+			gpio-bank = <0>;
+			ngpios = <29>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 14 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio at 1500000 {
+			compatible = "mobileye,eyeq5-gpio";
+			reg = <0x0 0x1500000 0x0 0x1000>;
+			gpio-bank = <1>;
+			ngpios = <23>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 14 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
 	};
 };
 

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:15 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:15 +0100
Subject: [PATCH 22/23] MIPS: mobileye: eyeq5: add resets to GPIO banks
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-22-f88c0ccf372b@bootlin.com>

The two GPIO banks share a single reset line.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 arch/mips/boot/dts/mobileye/eyeq5.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
index 0f18ac73620b..5f00d129c057 100644
--- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi
+++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
@@ -170,6 +170,7 @@ gpio0: gpio at 1400000 {
 			#gpio-cells = <2>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
+			resets = <&reset 0 26>;
 		};
 
 		gpio1: gpio at 1500000 {
@@ -183,6 +184,7 @@ gpio1: gpio at 1500000 {
 			#gpio-cells = <2>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
+			resets = <&reset 0 26>;
 		};
 	};
 };

-- 
2.43.1



From theo.lebrun at bootlin.com  Wed Feb 14 08:24:16 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 14 Feb 2024 17:24:16 +0100
Subject: [PATCH 23/23] MIPS: mobileye: eyeq5: map GPIOs to pins using
 gpio-ranges
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <20240214-mbly-gpio-v1-23-f88c0ccf372b@bootlin.com>

Create a mapping between the GPIO controllers and the pin controllers.
GPIO is handled in a one-instance-per-bank manner while pinctrl is done
with a single instance for both pin banks.

See gpio-ranges documentation:
Documentation/devicetree/bindings/gpio/gpio.txt

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 arch/mips/boot/dts/mobileye/eyeq5.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
index 5f00d129c057..68f6c81331d7 100644
--- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi
+++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
@@ -168,6 +168,7 @@ gpio0: gpio at 1400000 {
 			interrupts = <GIC_SHARED 14 IRQ_TYPE_LEVEL_HIGH>;
 			gpio-controller;
 			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 0 29>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			resets = <&reset 0 26>;
@@ -182,6 +183,7 @@ gpio1: gpio at 1500000 {
 			interrupts = <GIC_SHARED 14 IRQ_TYPE_LEVEL_HIGH>;
 			gpio-controller;
 			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 29 23>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			resets = <&reset 0 26>;

-- 
2.43.1



From sebastianene at google.com  Wed Feb 14 08:29:45 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Wed, 14 Feb 2024 16:29:45 +0000
Subject: [PATCH v5 4/4] KVM: arm64: Initialize the ptdump parser with
 stage-2 attributes
In-Reply-To: <ZcuihokcWA3q-pZS@linux.dev>
References: <20240207144832.1017815-2-sebastianene@google.com>
 <20240207144832.1017815-6-sebastianene@google.com>
 <Zcq7AoII8qLWwjsu@linux.dev>
 <Zcuf1ZUvwhxBobuG@google.com>
 <ZcuihokcWA3q-pZS@linux.dev>
Message-ID: <ZczqeTEOVVcRPNi3@google.com>

On Tue, Feb 13, 2024 at 05:10:30PM +0000, Oliver Upton wrote:
> On Tue, Feb 13, 2024 at 04:59:01PM +0000, Sebastian Ene wrote:
> > On Tue, Feb 13, 2024 at 12:42:42AM +0000, Oliver Upton wrote:
> > > On Wed, Feb 07, 2024 at 02:48:33PM +0000, Sebastian Ene wrote:
> 
> [...]
> 
> > > > +
> > > > +	snprintf(marker_msg, MARKER_MSG_LEN, "IPA bits %2u start lvl %1d",
> > > > +		 pgtable->ia_bits, pgtable->start_level);
> > > > +
> > > > +	ipa_addr_marker[0].name = marker_msg;
> > > 
> > > Is the dynamic name worth the added complexity? I see nothing wrong with
> > > exposing additional debugfs files for simple attributes like the IPA
> > > range and page table levels.
> > > 
> > > I know it isn't *that* much, just looking for every opportunity to
> > > simplify further.
> > > 
> > 
> > We can keep them separate, I have no strong opinion about this. I think
> > this was Vincent's, original suggestion to have them so I will check with
> > him as well.
> 
> Well, if we get to the place where there's a single struct containing
> all of the required data upfront then this becomes less of an issue.
> This is useful information still, so let's see if we can go about it the
> other way.
> 

Allright, I will create separate entries for getting the ipa_space and the start
level which will be exposed in the vm debugfs dir.

> > > > +	ret = kvm_ptdump_parser_init(&parser_state, mmu->pgt, m);
> > > > +	if (ret)
> > > > +		return ret;
> > > > +
> > > 
> > > Can this be done at open(), or am I missing something?
> > > 
> > 
> > I guess we can do this in open() but then we will have to add again that
> > struct that wraps some ptdump specific state tracking. It seemed a bit cleaner in
> > this way. What do you think ?
> 
> Allocating something that looks like an iterator end embedding it in
> ->private isn't too uncommon.
> 

Ack, will stick to this approach in this case.

> > > >  	write_lock(&guest_kvm->mmu_lock);
> > > >  	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
> > > >  	write_unlock(&guest_kvm->mmu_lock);
> > > >  
> > > > +	kvm_ptdump_parser_teardown(&parser_state);
> > > 
> > > Same question here, can this happen at close()? I guess you'll need a
> > > struct to encapsulate pg_state and a pointer to the VM at least.
> > >
> > 
> > Right, I tried to avoid using a separate struct as we discussed in v4.
> 
> Sorry, I hope I didn't confuse you in my prior feedback.
> 
> What I had issue with was the multiple layers of function ptr / ops
> structs for managing the file interface. I have zero concerns with
> organizing the _data_ for the walk this way.
>

Right, I see what you mean, thanks for the clarification.

> > > Actually, come to think of it, if you embed all of the data you need for
> > > the walker into a structure you can just do a single allocation for it
> > > upfront.
> 
> -- 
> Thanks,
> Oliver

Thanks for the feedback,
Seb


From geert at linux-m68k.org  Wed Feb 14 08:46:32 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 17:46:32 +0100
Subject: [PATCH v2] dt-bindings: arm: realview: Spelling s/ARM 11/Arm11/,
 s/Cortex A-/Cortex-A/
In-Reply-To: <CACRpkdYcyxQVjiMqoUJ1JbOLeywoeDGR8dY+ZLZT1kdmk1kSVA@mail.gmail.com>
References: <3d4b1bbc105ccb8cc0a4ea79b76c70df7d0683e6.1694768749.git.geert+renesas@glider.be>
 <CACRpkdYcyxQVjiMqoUJ1JbOLeywoeDGR8dY+ZLZT1kdmk1kSVA@mail.gmail.com>
Message-ID: <CAMuHMdXftwMRPRb=U58XTOigo0Q0q_i+6M3hQfLdo88QXd2Ykg@mail.gmail.com>

Hi Linus,

On Fri, Sep 15, 2023 at 1:34?PM Linus Walleij <linus.walleij at linaro.org> wrote:
> On Fri, Sep 15, 2023 at 11:07?AM Geert Uytterhoeven
> <geert+renesas at glider.be> wrote:
> > Fix misspellings of "Arm11", "Cortex-A8", and "Cortex-A9".
> >
> > While at it, add a missing comma before "and", and reflow the paragraph.
> >
> > Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> > Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>
> Picked up the patch and applied it on my versatile-dts branch,
> thanks for cleaning this up Geert!

Looks like this fell through the cracks?
Should I resend?
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 geert at linux-m68k.org  Wed Feb 14 08:46:57 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 14 Feb 2024 17:46:57 +0100
Subject: [PATCH] ARM: dts: arm: realview: Fix development chip ROM
 compatible value
In-Reply-To: <CACRpkdbgBtAmyxfiXrZ75gAdc1DeaqMaHRNVX=nz7SuzxFU40w@mail.gmail.com>
References: <946079fe606d18b97578db42dd57a31acf38b26a.1693407641.git.geert+renesas@glider.be>
 <CACRpkdbgBtAmyxfiXrZ75gAdc1DeaqMaHRNVX=nz7SuzxFU40w@mail.gmail.com>
Message-ID: <CAMuHMdWJ7-3ULokmvFPRuvquTme6HFzsK=VUKpvP=CVOVqnDQQ@mail.gmail.com>

Hi Linus,

On Tue, Sep 12, 2023 at 9:18?AM Linus Walleij <linus.walleij at linaro.org> wrote:
> On Wed, Aug 30, 2023 at 5:03?PM Geert Uytterhoeven
> <geert+renesas at glider.be> wrote:
> > When the development chip ROM was added, the "direct-mapped" compatible
> > value was already obsolete.  In addition, the device node lacked the
> > accompanying "probe-type" property, causing the old physmap_of_core
> > driver to fall back to trying all available probe types.
> > Unfortunately this fallback was lost when the DT and pdata cases were
> > merged.
> >
> > Fix this by using the modern "mtd-rom" compatible value instead.
> >
> > Fixes: 5c3f5edbe0a1dff3 ("ARM: realview: add flash devices to the PB1176 DTS")
> > Fixes: 642b1e8dbed7bbbf ("mtd: maps: Merge physmap_of.c into physmap-core.c")
> > Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
>
> Patch applied!

Looks like this fell through the cracks?
Shall I resend?
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 balint.dobszay at arm.com  Wed Feb 14 08:56:41 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Wed, 14 Feb 2024 17:56:41 +0100
Subject: [PATCH 3/3] Documentation: tee: Add TS-TEE driver
In-Reply-To: <bbb40718-9bfa-4431-a3b0-c09d068fd6cc@infradead.org>
References: <20240213145239.379875-1-balint.dobszay@arm.com>
 <20240213145239.379875-4-balint.dobszay@arm.com>
 <bbb40718-9bfa-4431-a3b0-c09d068fd6cc@infradead.org>
Message-ID: <40BCD479-90FC-4B32-AA97-A7B39CA8A3FC@arm.com>

Hi Randy,

On 13 Feb 2024, at 22:44, Randy Dunlap wrote:

> Hi--
>
> On 2/13/24 06:52, Balint Dobszay wrote:
>> Add documentation for the Trusted Services TEE driver.
>>
>> Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
>> ---
>>  Documentation/tee/index.rst  |  1 +
>>  Documentation/tee/ts-tee.rst | 70 ++++++++++++++++++++++++++++++++++++
>>  2 files changed, 71 insertions(+)
>>  create mode 100644 Documentation/tee/ts-tee.rst
>>
>
>> diff --git a/Documentation/tee/ts-tee.rst b/Documentation/tee/ts-tee.rst
>> new file mode 100644
>> index 000000000000..e121ebbbfab7
>> --- /dev/null
>> +++ b/Documentation/tee/ts-tee.rst
>> @@ -0,0 +1,70 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +
>> +=================================
>> +TS-TEE (Trusted Services project)
>> +=================================
>> +
>> +This driver provides access to secure services implemented by Trusted Services.
>> +
>> +Trusted Services [1] is a TrustedFirmware.org project that provides a framework
>> +for developing and deploying device Root of Trust services in FF-A [2] S-EL0
>> +Secure Partitions. The project hosts the reference implementation of the Arm
>> +Platform Security Architecture [3] for Arm A-profile devices.
>> +
>> +The FF-A Secure Partitions (SP) are accessible through the FF-A driver [4] which
>> +provides the low level communication for this driver. On top of that the Trusted
>> +Services RPC protocol is used [5]. To use the driver from user space a reference
>> +implementation is provided at [6], which is part of the Trusted Services client
>> +library called libts [7].
>> +
>
> Fix run-on sentences:
>
>> +All Trusted Services (TS) SPs have the same FF-A UUID, it identifies the TS RPC
>
>                                                     UUID. It
> or
>                                                     UUIT; it
>
>> +protocol. A TS SP can host one or more services (e.g. PSA Crypto, PSA ITS, etc).
>> +A service is identified by its service UUID, the same type of service cannot be
>
>                                           UUID;
>
>> +present twice in the same SP. During SP boot each service in the SP is assigned
>> +an "interface ID", this is just a short ID to simplify message addressing.
>
>       "interface ID." This
>
>> +
>> +The generic TEE design is to share memory at once with the TEE implementation,
>> +which can then be reused to communicate with multiple TAs. However, in case of
>
> "TA" is not defined.
>
>> +FF-A, memory sharing works on an endpoint level, i.e. memory is shared with a
>> +specific SP. User space has to be able to separately share memory with each SP
>> +based on its endpoint ID, therefore a separate TEE device is registered for each
>
>                          ID; therefore
>
>> +discovered TS SP. Opening the SP corresponds to opening the TEE device and
>> +creating a TEE context. A TS SP hosts one or more services, opening a service
>
>                                                      services. Opening

Thanks for the comments, I'll address them in the next version.

Regards,
Balint


From will at kernel.org  Wed Feb 14 09:00:30 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 14 Feb 2024 17:00:30 +0000
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240213140033.GB989297@nvidia.com>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
 <20240208125846.GA23290@willie-the-truck>
 <20240208142729.GH10476@nvidia.com>
 <20240213112015.GB28517@willie-the-truck>
 <20240213121850.GH4048826@nvidia.com>
 <20240213125456.GA28844@willie-the-truck>
 <20240213133045.GA989297@nvidia.com>
 <20240213135627.GD28926@willie-the-truck>
 <20240213140033.GB989297@nvidia.com>
Message-ID: <20240214170030.GB31927@willie-the-truck>

On Tue, Feb 13, 2024 at 10:00:33AM -0400, Jason Gunthorpe wrote:
> On Tue, Feb 13, 2024 at 01:56:28PM +0000, Will Deacon wrote:
> 
> > I can write it as a full patch if you prefer (and I'll need your help to
> > test it), but I was really hoping to continue the discussion so you could
> > spin a v2.
> 
> No worries, I'll take care of it, just need to understand what we have
> agreed.

Cheers. I finished the diff off anyway, as it's basically just merging
the thing I sent with the rest of your patch. What do you reckon?

Will

--->8

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index 05722121f00e..128f61a705c7 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -588,6 +588,12 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
 {
 	int ret = 0;
 	struct mm_struct *mm = domain->mm;
+	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+
+	/* Pre-allocate the CD leaf table without any locks held */
+	ret = arm_smmu_init_cd_table(master, id);
+	if (ret)
+		return ret;
 
 	mutex_lock(&sva_lock);
 	ret = __arm_smmu_sva_bind(dev, mm);
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 0ffb1cf17e0b..e48f2b46f25e 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1019,7 +1019,10 @@ static void arm_smmu_write_cd_l1_desc(__le64 *dst,
 	WRITE_ONCE(*dst, cpu_to_le64(val));
 }
 
-static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
+static __le64 *
+__arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid,
+		      int (*cd_alloc)(struct arm_smmu_device *,
+				      struct arm_smmu_l1_ctx_desc *))
 {
 	__le64 *l1ptr;
 	unsigned int idx;
@@ -1033,7 +1036,7 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
 	idx = ssid >> CTXDESC_SPLIT;
 	l1_desc = &cd_table->l1_desc[idx];
 	if (!l1_desc->l2ptr) {
-		if (arm_smmu_alloc_cd_leaf_table(smmu, l1_desc))
+		if (!cd_alloc || cd_alloc(smmu, l1_desc))
 			return NULL;
 
 		l1ptr = cd_table->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
@@ -1045,6 +1048,19 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
 	return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS;
 }
 
+static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
+{
+	return __arm_smmu_get_cd_ptr(master, ssid, NULL);
+}
+
+int arm_smmu_init_cd_table(struct arm_smmu_master *master, int ssid)
+{
+	if (!__arm_smmu_get_cd_ptr(master, ssid, arm_smmu_alloc_cd_leaf_table))
+		return -ENOMEM;
+
+	return 0;
+}
+
 int arm_smmu_write_ctx_desc(struct arm_smmu_master *master, int ssid,
 			    struct arm_smmu_ctx_desc *cd)
 {
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 65fb388d5173..cc42cede77bc 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -748,6 +748,7 @@ extern struct xarray arm_smmu_asid_xa;
 extern struct mutex arm_smmu_asid_lock;
 extern struct arm_smmu_ctx_desc quiet_cd;
 
+int arm_smmu_init_cd_table(struct arm_smmu_master *smmu_master, int ssid);
 int arm_smmu_write_ctx_desc(struct arm_smmu_master *smmu_master, int ssid,
 			    struct arm_smmu_ctx_desc *cd);
 void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid);


From will at kernel.org  Wed Feb 14 09:00:34 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 14 Feb 2024 17:00:34 +0000
Subject: [PATCH] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
In-Reply-To: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
References: <20240213-iommu-revert-domain-alloc-v1-1-325ff55dece4@linaro.org>
Message-ID: <170782679599.2166016.11725176923934129944.b4-ty@kernel.org>

On Tue, 13 Feb 2024 13:31:56 +0200, Dmitry Baryshkov wrote:
> This reverts commit 9b3febc3a3da ("iommu/arm-smmu: Convert to
> domain_alloc_paging()"). It breaks Qualcomm MSM8996 platform. Calling
> arm_smmu_write_context_bank() from new codepath results in the platform
> being reset because of the unclocked hardware access.
> 
> 

Applied to will (for-joerg/arm-smmu/fixes), thanks!

[1/1] Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"
      https://git.kernel.org/will/c/b419c5e2d978

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From khilman at kernel.org  Wed Feb 14 09:04:10 2024
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 14 Feb 2024 09:04:10 -0800
Subject: [RESEND PATCH v1 04/13] mfd: tps6594-i2c: Add TI TPS65224 PMIC I2C
In-Reply-To: <20240208105343.1212902-5-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
 <20240208105343.1212902-5-bhargav.r@ltts.com>
Message-ID: <7hplwz565x.fsf@baylibre.com>

Hello,

Bhargav Raviprakash <bhargav.r at ltts.com> writes:

> Add support for TPS65224 PMIC in TPS6594's I2C driver which has
> significant functional overlap.
>
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>

Thanks for the patch adding TPS65224 support

[...]

> @@ -216,15 +217,18 @@ static int tps6594_i2c_probe(struct i2c_client *client)
>  	tps->reg = client->addr;
>  	tps->irq = client->irq;
>  
> -	tps->regmap = devm_regmap_init(dev, NULL, client, &tps6594_i2c_regmap_config);
> -	if (IS_ERR(tps->regmap))
> -		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
> -
>  	match = of_match_device(tps6594_i2c_of_match_table, dev);
>  	if (!match)
>  		return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n");
>  	tps->chip_id = (unsigned long)match->data;
>  
> +	if (tps->chip_id == TPS65224)
> +		tps6594_i2c_regmap_config.volatile_table = &tps65224_volatile_table;

minor nit: for chip-specific differnces like this, rather than do this
kind of "if" check here to update the regmap_config, instead use the
compatible match data have a separate i2c_regmap_config match table for
tps65224.

Kevin


From mathieu.poirier at linaro.org  Wed Feb 14 09:21:03 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 14 Feb 2024 10:21:03 -0700
Subject: [PATCH v10 4/4] remoteproc: zynqmp: parse TCM from device tree
In-Reply-To: <20240213175450.3097308-5-tanmay.shah@amd.com>
References: <20240213175450.3097308-1-tanmay.shah@amd.com>
 <20240213175450.3097308-5-tanmay.shah@amd.com>
Message-ID: <Zcz2f3eZrXrRAX6F@p14s>

Good morning,

On Tue, Feb 13, 2024 at 09:54:50AM -0800, Tanmay Shah wrote:
> ZynqMP TCM information was fixed in driver. Now ZynqMP TCM information
> is available in device-tree. Parse TCM information in driver
> as per new bindings.
> 
> Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
> ---
> 
> Changes in v10:
>   - Remove redundant changes to handle TCM in lockstep mode
> 
> Changes in v9:
>   - Introduce new API to request and release core1 TCM power-domains in
>     lockstep mode. This will be used during prepare -> add_tcm_banks
>     callback to enable TCM in lockstep mode.
>   - Parse TCM from device-tree in lockstep mode and split mode in
>     uniform way.
>   - Fix TCM representation in device-tree in lockstep mode.
> 
> Changes in v8:
>   - Remove pm_domains framework
>   - Remove checking of pm_domain_id validation to power on/off tcm
>   - Remove spurious change
>   - parse power-domains property from device-tree and use EEMI calls
>     to power on/off TCM instead of using pm domains framework
> 
> Changes in v7:
>   - move checking of pm_domain_id from previous patch
>   - fix mem_bank_data memory allocation
> 
>  drivers/remoteproc/xlnx_r5_remoteproc.c | 112 ++++++++++++++++++++++--
>  1 file changed, 107 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
> index 42b0384d34f2..49e8eaf83fce 100644
> --- a/drivers/remoteproc/xlnx_r5_remoteproc.c
> +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
> @@ -74,8 +74,8 @@ struct mbox_info {
>  };
>  
>  /*
> - * Hardcoded TCM bank values. This will be removed once TCM bindings are
> - * accepted for system-dt specifications and upstreamed in linux kernel
> + * Hardcoded TCM bank values. This will stay in driver to maintain backward
> + * compatibility with device-tree that does not have TCM information.
>   */
>  static const struct mem_bank_data zynqmp_tcm_banks_split[] = {
>  	{0xffe00000UL, 0x0, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
> @@ -757,6 +757,103 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)
>  	return ERR_PTR(ret);
>  }
>  
> +static int zynqmp_r5_get_tcm_node_from_dt(struct zynqmp_r5_cluster *cluster)
> +{
> +	int i, j, tcm_bank_count, ret, tcm_pd_idx, pd_count;
> +	struct of_phandle_args out_args = {0};

Is this really needed?  As far as I can tell it isn't.  

Otherwise and if it wasn't for the modification on the DT side, I would apply
this patch.

Thanks,
Mathieu

> +	struct zynqmp_r5_core *r5_core;
> +	struct platform_device *cpdev;
> +	struct mem_bank_data *tcm;
> +	struct device_node *np;
> +	struct resource *res;
> +	u64 abs_addr, size;
> +	struct device *dev;
> +
> +	for (i = 0; i < cluster->core_count; i++) {
> +		r5_core = cluster->r5_cores[i];
> +		dev = r5_core->dev;
> +		np = r5_core->np;
> +
> +		pd_count = of_count_phandle_with_args(np, "power-domains",
> +						      "#power-domain-cells");
> +
> +		if (pd_count <= 0) {
> +			dev_err(dev, "invalid power-domains property, %d\n", pd_count);
> +			return -EINVAL;
> +		}
> +
> +		/* First entry in power-domains list is for r5 core, rest for TCM. */
> +		tcm_bank_count = pd_count - 1;
> +
> +		if (tcm_bank_count <= 0) {
> +			dev_err(dev, "invalid TCM count %d\n", tcm_bank_count);
> +			return -EINVAL;
> +		}
> +
> +		r5_core->tcm_banks = devm_kcalloc(dev, tcm_bank_count,
> +						  sizeof(struct mem_bank_data *),
> +						  GFP_KERNEL);
> +		if (!r5_core->tcm_banks)
> +			ret = -ENOMEM;
> +
> +		r5_core->tcm_bank_count = tcm_bank_count;
> +		for (j = 0, tcm_pd_idx = 1; j < tcm_bank_count; j++, tcm_pd_idx++) {
> +			tcm = devm_kzalloc(dev, sizeof(struct mem_bank_data),
> +					   GFP_KERNEL);
> +			if (!tcm)
> +				return -ENOMEM;
> +
> +			r5_core->tcm_banks[j] = tcm;
> +
> +			/* Get power-domains id of TCM. */
> +			ret = of_parse_phandle_with_args(np, "power-domains",
> +							 "#power-domain-cells",
> +							 tcm_pd_idx, &out_args);
> +			if (ret) {
> +				dev_err(r5_core->dev,
> +					"failed to get tcm %d pm domain, ret %d\n",
> +					tcm_pd_idx, ret);
> +				return ret;
> +			}
> +			tcm->pm_domain_id = out_args.args[0];
> +			of_node_put(out_args.np);
> +
> +			/* Get TCM address without translation. */
> +			ret = of_property_read_reg(np, j, &abs_addr, &size);
> +			if (ret) {
> +				dev_err(dev, "failed to get reg property\n");
> +				return ret;
> +			}
> +
> +			/*
> +			 * Remote processor can address only 32 bits
> +			 * so convert 64-bits into 32-bits. This will discard
> +			 * any unwanted upper 32-bits.
> +			 */
> +			tcm->da = (u32)abs_addr;
> +			tcm->size = (u32)size;
> +
> +			cpdev = to_platform_device(dev);
> +			res = platform_get_resource(cpdev, IORESOURCE_MEM, j);
> +			if (!res) {
> +				dev_err(dev, "failed to get tcm resource\n");
> +				return -EINVAL;
> +			}
> +
> +			tcm->addr = (u32)res->start;
> +			tcm->bank_name = (char *)res->name;
> +			res = devm_request_mem_region(dev, tcm->addr, tcm->size,
> +						      tcm->bank_name);
> +			if (!res) {
> +				dev_err(dev, "failed to request tcm resource\n");
> +				return -EINVAL;
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  /**
>   * zynqmp_r5_get_tcm_node()
>   * Ideally this function should parse tcm node and store information
> @@ -835,9 +932,14 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
>  	struct zynqmp_r5_core *r5_core;
>  	int ret, i;
>  
> -	ret = zynqmp_r5_get_tcm_node(cluster);
> -	if (ret < 0) {
> -		dev_err(dev, "can't get tcm node, err %d\n", ret);
> +	r5_core = cluster->r5_cores[0];
> +	if (of_find_property(r5_core->np, "reg", NULL))
> +		ret = zynqmp_r5_get_tcm_node_from_dt(cluster);
> +	else
> +		ret = zynqmp_r5_get_tcm_node(cluster);
> +
> +	if (ret) {
> +		dev_err(dev, "can't get tcm, err %d\n", ret);
>  		return ret;
>  	}
>  
> -- 
> 2.25.1
> 


From arnaud.pouliquen at foss.st.com  Wed Feb 14 09:21:24 2024
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Wed, 14 Feb 2024 18:21:24 +0100
Subject: [PATCH v3 4/7] remoteproc: core: Implement the support of an alternative boot
In-Reply-To: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
Message-ID: <20240214172127.1022199-5-arnaud.pouliquen@foss.st.com>

Implement a new method to load a firmware and start the remote processor.
In this method the firmware is loaded first and then the loaded resource
table is obtained.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
---
 drivers/remoteproc/remoteproc_core.c | 86 +++++++++++++++++++++++++++-
 include/linux/remoteproc.h           |  2 +
 2 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 34b0093689da..47956e07365e 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -38,6 +38,7 @@
 #include <linux/virtio_ring.h>
 #include <asm/byteorder.h>
 #include <linux/platform_device.h>
+#include <linux/tee_remoteproc.h>
 
 #include "remoteproc_internal.h"
 
@@ -1493,6 +1494,86 @@ static int rproc_set_rsc_table(struct rproc *rproc)
 	return 0;
 }
 
+/*
+ * Alternative method to load a firmware and boot a remote processor with it.
+ * Similar to rproc_fw_boot but the resource table is obtained and parsed only after loading the
+ * firmware.
+ */
+static int rproc_alt_fw_boot(struct rproc *rproc, const struct firmware *fw)
+{
+	struct device *dev = &rproc->dev;
+	const char *name = rproc->firmware;
+	int ret;
+
+	dev_info(dev, "Booting a private format image %s, size %zd\n", name, fw->size);
+
+	/*
+	 * if enabling an IOMMU isn't relevant for this rproc, this is
+	 * just a nop
+	 */
+	ret = rproc_enable_iommu(rproc);
+	if (ret) {
+		dev_err(dev, "can't enable iommu: %d\n", ret);
+		return ret;
+	}
+
+	/* Prepare rproc for firmware loading if needed */
+	ret = rproc_prepare_device(rproc);
+	if (ret) {
+		dev_err(dev, "can't prepare rproc %s: %d\n", rproc->name, ret);
+		goto disable_iommu;
+	}
+
+	/* load the image to memory */
+	ret = rproc_load_segments(rproc, fw);
+	if (ret) {
+		dev_err(dev, "Failed to load firmware: %d\n", ret);
+		return ret;
+	}
+
+	ret = rproc_set_rsc_table(rproc);
+	if (ret) {
+		dev_err(dev, "can't load resource table: %d\n", ret);
+		goto unprepare_device;
+	}
+
+	/* reset max_notifyid */
+	rproc->max_notifyid = -1;
+
+	/* reset handled vdev */
+	rproc->nb_vdev = 0;
+
+	/* handle fw resources which are required to boot rproc */
+	ret = rproc_handle_resources(rproc, rproc_loading_handlers);
+	if (ret) {
+		dev_err(dev, "Failed to process resources: %d\n", ret);
+		goto clean_up_resources;
+	}
+
+	/* Allocate carveout resources associated to rproc */
+	ret = rproc_alloc_registered_carveouts(rproc);
+	if (ret) {
+		dev_err(dev, "Failed to allocate associated carveouts: %d\n",
+			ret);
+		goto clean_up_resources;
+	}
+
+	ret = rproc_start(rproc, fw);
+	if (ret)
+		goto clean_up_resources;
+
+	return 0;
+
+clean_up_resources:
+	rproc_resource_cleanup(rproc);
+unprepare_device:
+	/* release HW resources if needed */
+	rproc_unprepare_device(rproc);
+disable_iommu:
+	rproc_disable_iommu(rproc);
+	return ret;
+}
+
 static int rproc_reset_rsc_table_on_detach(struct rproc *rproc)
 {
 	struct resource_table *table_ptr;
@@ -1957,7 +2038,10 @@ int rproc_boot(struct rproc *rproc)
 			goto downref_rproc;
 		}
 
-		ret = rproc_fw_boot(rproc, firmware_p);
+		if (rproc->alt_boot)
+			ret = rproc_alt_fw_boot(rproc, firmware_p);
+		else
+			ret = rproc_fw_boot(rproc, firmware_p);
 
 		release_firmware(firmware_p);
 	}
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index b4795698d8c2..ba219a77e055 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -544,6 +544,7 @@ enum rproc_features {
  * @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
+ * @alt_boot flag to indicate if remoteproc should use the alternate boot method.
  * @features: indicate remoteproc features
  */
 struct rproc {
@@ -585,6 +586,7 @@ struct rproc {
 	u16 elf_machine;
 	struct cdev cdev;
 	bool cdev_put_on_release;
+	bool alt_boot;
 	DECLARE_BITMAP(features, RPROC_MAX_FEATURES);
 };
 
-- 
2.25.1



From arnaud.pouliquen at foss.st.com  Wed Feb 14 09:21:23 2024
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Wed, 14 Feb 2024 18:21:23 +0100
Subject: [PATCH v3 3/7] remoteproc: core: Add check on cached_table pointer
In-Reply-To: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
Message-ID: <20240214172127.1022199-4-arnaud.pouliquen@foss.st.com>

Add a check on the optional rproc->cached_table to perform the memory
copy only if it is not null.

2 use cases to support:
- starting on boot, in which case rproc->cached_table can be null,
- starting on crash recovery, where the cached table is used to save
  the resource table configuration on stop and re-apply the configuration
  on the re-start.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
---
 drivers/remoteproc/remoteproc_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 283ca071e35c..34b0093689da 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1278,7 +1278,7 @@ static int rproc_start(struct rproc *rproc, const struct firmware *fw)
 	 * that any subsequent changes will be applied to the loaded version.
 	 */
 	loaded_table = rproc_find_loaded_rsc_table(rproc, fw);
-	if (loaded_table) {
+	if (loaded_table && rproc->cached_table) {
 		memcpy(loaded_table, rproc->cached_table, rproc->table_sz);
 		rproc->table_ptr = loaded_table;
 	}
-- 
2.25.1



From arnaud.pouliquen at foss.st.com  Wed Feb 14 09:21:25 2024
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Wed, 14 Feb 2024 18:21:25 +0100
Subject: [PATCH v3 5/7] dt-bindings: remoteproc: Add compatibility for TEE support
In-Reply-To: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
Message-ID: <20240214172127.1022199-6-arnaud.pouliquen@foss.st.com>

The "st,stm32mp1-m4-tee" compatible is utilized in a system configuration
where the Cortex-M4 firmware is loaded by the Trusted execution Environment
(TEE).
For instance, this compatible is used in both the Linux and OP-TEE
device-tree:
- In OP-TEE, a node is defined in the device tree with the
  st,stm32mp1-m4-tee to support signed remoteproc firmware.
  Based on DT properties, OP-TEE authenticates, loads, starts, and stops
  the firmware.
- On Linux, when the compatibility is set, the Cortex-M resets should not
  be declared in the device tree.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
---
V1 to V2 updates
- update "st,stm32mp1-m4" compatible description to generalize
- remove the 'reset-names' requirement in one conditional branch, as the
  property is already part of the condition test.
---
 .../bindings/remoteproc/st,stm32-rproc.yaml   | 51 ++++++++++++++++---
 1 file changed, 43 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
index 370af61d8f28..36ea54016b76 100644
--- a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
@@ -16,7 +16,12 @@ maintainers:
 
 properties:
   compatible:
-    const: st,stm32mp1-m4
+    enum:
+      - st,stm32mp1-m4
+      - st,stm32mp1-m4-tee
+    description:
+      Use "st,stm32mp1-m4" for the Cortex-M4 coprocessor management by non-secure context
+      Use "st,stm32mp1-m4-tee" for the Cortex-M4 coprocessor management by secure context
 
   reg:
     description:
@@ -142,21 +147,41 @@ properties:
 required:
   - compatible
   - reg
-  - resets
 
 allOf:
   - if:
       properties:
-        reset-names:
-          not:
-            contains:
-              const: hold_boot
+        compatible:
+          contains:
+            const: st,stm32mp1-m4
     then:
+      if:
+        properties:
+          reset-names:
+            not:
+              contains:
+                const: hold_boot
+      then:
+        required:
+          - st,syscfg-holdboot
+      else:
+        properties:
+          st,syscfg-holdboot: false
+        required:
+          - reset-names
       required:
-        - st,syscfg-holdboot
-    else:
+        - resets
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: st,stm32mp1-m4-tee
+    then:
       properties:
         st,syscfg-holdboot: false
+        reset-names: false
+        resets: false
 
 additionalProperties: false
 
@@ -188,5 +213,15 @@ examples:
       st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>;
       st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>;
     };
+  - |
+    #include <dt-bindings/reset/stm32mp1-resets.h>
+    m4 at 10000000 {
+      compatible = "st,stm32mp1-m4-tee";
+      reg = <0x10000000 0x40000>,
+            <0x30000000 0x40000>,
+            <0x38000000 0x10000>;
+      st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>;
+      st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>;
+    };
 
 ...
-- 
2.25.1



From arnaud.pouliquen at foss.st.com  Wed Feb 14 09:21:22 2024
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Wed, 14 Feb 2024 18:21:22 +0100
Subject: [PATCH v3 2/7] remoteproc: Extract the firmware load from the start
In-Reply-To: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
Message-ID: <20240214172127.1022199-3-arnaud.pouliquen@foss.st.com>

With the introduction of tee_remoteproc, the firmware has to be loaded
first before parsing the resource table. This constraint is linked to
the firmware authentication, that contains the resource table.
In OP-TEE, this authentication is correlated with the load of the
firmware (the loaded segments authenticated after being copied
to the destination memory). Removing rproc_load_segments will allow
it to be called earlier in the boot sequence.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
---
 drivers/remoteproc/remoteproc_core.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 695cce218e8c..283ca071e35c 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1269,13 +1269,6 @@ static int rproc_start(struct rproc *rproc, const struct firmware *fw)
 	struct device *dev = &rproc->dev;
 	int ret;
 
-	/* load the ELF segments to memory */
-	ret = rproc_load_segments(rproc, fw);
-	if (ret) {
-		dev_err(dev, "Failed to load program segments: %d\n", ret);
-		return ret;
-	}
-
 	/*
 	 * The starting device has been given the rproc->cached_table as the
 	 * resource table. The address of the vring along with the other
@@ -1430,6 +1423,13 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
 		goto clean_up_resources;
 	}
 
+	/* load the ELF segments to memory */
+	ret = rproc_load_segments(rproc, fw);
+	if (ret) {
+		dev_err(dev, "Failed to load program segments: %d\n", ret);
+		return ret;
+	}
+
 	ret = rproc_start(rproc, fw);
 	if (ret)
 		goto clean_up_resources;
@@ -1808,6 +1808,13 @@ static int rproc_boot_recovery(struct rproc *rproc)
 		return ret;
 	}
 
+	/* load the ELF segments to memory */
+	ret = rproc_load_segments(rproc, firmware_p);
+	if (ret) {
+		dev_err(dev, "Failed to load program segments: %d\n", ret);
+		return ret;
+	}
+
 	/* boot the remote processor up again */
 	ret = rproc_start(rproc, firmware_p);
 
-- 
2.25.1



From arnaud.pouliquen at foss.st.com  Wed Feb 14 09:21:20 2024
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Wed, 14 Feb 2024 18:21:20 +0100
Subject: [PATCH v3 0/7] Introduction of a remoteproc tee to load signed firmware
Message-ID: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>

Updates from the previous version [1]:

This version proposes another approach based on an alternate load and boot
of the coprocessor. Therefore, the constraint introduced by tee_remoteproc
is that the firmware has to be authenticated and loaded before the resource
table can be obtained.

The existing boot sequence is:

  1) Get the resource table and store it in a cache,
     calling rproc->ops->parse_fw().
  2) Parse the resource table and handle resources,
     calling rproc_handle_resources.
  3) Load the firmware, calling rproc->ops->load().
  4) Start the firmware, calling rproc->ops->start().
 
=> Steps 1 and 2 are executed in rproc_fw_boot(), while steps 3 and 4 are
   executed in rproc_start().
=> the use of rproc->ops->load() ops is mandatory

The boot sequence needed for TEE boot is:

  1) Load the firmware.
  2) Get the loaded resource, no cache.
  3) Parse the resource table and handle resources.
  4) Start the firmware.

Then the crash recovery also has to be managed.For recovery, the cache is
used to temporarily save the resource table and then reapply it on
restart:
  1) Stop the remote processor, calling rproc->ops->stop().
  2) Load the firmware, calling rproc->ops->load().
  3) Copy cached resource table.
  4) Start the remote processor, calling rproc->ops->start().

=> This sequence is also needed when TEE manages the boot of the remote
   processor.
=> The rproc->ops->load() is also used in recovery sequence.

Based on the sequences described above, the proposal is to:

- Rework tee_rproc API to better match the rproc_ops structure.
  This allows to simply map the function to implement the load ops, which
  is not optional. The tee_rproc_load_fw() is updated in consequence. 
- Remove the call of rproc_load_segments from rproc_start() to dissociate
  the load and the start. This is necessary to implement the boot sequence
  requested for the TEE remote proc support.
- Introduce an rproc_alt_fw_boot() function that is an alternative boot
  sequence, which implements the sequence requested for the TEE remoteproc
  support.


[1] https://lore.kernel.org/lkml/20240118100433.3984196-1-arnaud.pouliquen at foss.st.com/T/


Description of the feature:

This series proposes the implementation of a remoteproc tee driver to
communicate with a TEE trusted application responsible for authenticating and
loading the remoteproc firmware image in an Arm secure context.

1) Principle:

The remoteproc tee driver provides services to communicate with the OP-TEE
trusted application running on the Trusted Execution Context (TEE).
The trusted application in TEE manages the remote processor lifecycle:

- authenticating and loading firmware images,
- isolating and securing the remote processor memories,
- supporting multi-firmware (e.g., TF-M + Zephyr on a Cortex-M33),
- managing the start and stop of the firmware by the TEE.

2) Format of the signed image:

Refer to:
https://github.com/OP-TEE/optee_os/blob/master/ta/remoteproc/src/remoteproc_core.c#L18-L57

3) OP-TEE trusted application API:

Refer to:
https://github.com/OP-TEE/optee_os/blob/master/ta/remoteproc/include/ta_remoteproc.h

4) OP-TEE signature script

Refer to:
https://github.com/OP-TEE/optee_os/blob/master/scripts/sign_rproc_fw.py

Example of usage:
sign_rproc_fw.py --in <fw1.elf> --in <fw2.elf> --out <signed_fw.sign> --key ${OP-TEE_PATH}/keys/default.pem


5) Impact on User space Application

No sysfs impact.the user only needs to provide the signed firmware image
instead of the ELF image.


For more information about the implementation, a presentation is available here
(note that the format of the signed image has evolved between the presentation
and the integration in OP-TEE).

https://resources.linaro.org/en/resource/6c5bGvZwUAjX56fvxthxds

Arnaud Pouliquen (7):
  remoteproc: Add TEE support
  remoteproc: Extract the firmware load from the start
  remoteproc: core: Add check on cached_table pointer
  remoteproc: core: Implement the support of an alternative boot
  dt-bindings: remoteproc: Add compatibility for TEE support
  remoteproc: stm32: Create sub-functions to request shutdown and
    release
  remoteproc: stm32: Add support of an OP-TEE TA to load the firmware

 .../bindings/remoteproc/st,stm32-rproc.yaml   |  51 ++-
 drivers/remoteproc/Kconfig                    |   9 +
 drivers/remoteproc/Makefile                   |   1 +
 drivers/remoteproc/remoteproc_core.c          | 109 ++++-
 drivers/remoteproc/stm32_rproc.c              | 169 ++++++--
 drivers/remoteproc/tee_remoteproc.c           | 397 ++++++++++++++++++
 include/linux/remoteproc.h                    |   2 +
 include/linux/tee_remoteproc.h                | 102 +++++
 8 files changed, 784 insertions(+), 56 deletions(-)
 create mode 100644 drivers/remoteproc/tee_remoteproc.c
 create mode 100644 include/linux/tee_remoteproc.h

-- 
2.25.1



From arnaud.pouliquen at foss.st.com  Wed Feb 14 09:21:21 2024
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Wed, 14 Feb 2024 18:21:21 +0100
Subject: [PATCH v3 1/7] remoteproc: Add TEE support
In-Reply-To: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
Message-ID: <20240214172127.1022199-2-arnaud.pouliquen@foss.st.com>

From: Arnaud Pouliquen <arnaud.pouliquen at st.com>

Add a remoteproc TEE (Trusted Execution Environment) driver
that will be probed by the TEE bus. If the associated Trusted
application is supported on secure part this device offers a client
interface to load a firmware in the secure part.
This firmware could be authenticated and decrypted by the secure
trusted application.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at st.com>
---
update from V2
- Use 'tee_rproc' prefix for all functions
- rename tee_rproc_get_loaded_rsc_table to tee_rproc_find_loaded_rsc_table
- redefine fonction to better match with the rproc_ops structure format
	- replace 'struct tee_rproc' parameter by 'struct rproc' parameter
	- rename 'rproc_tee_get_rsc_table()' to tee_rproc_get_loaded_rsc_table()
	  and rework it to remove the cached_table management.
	- introduce tee_rproc_get_context() to get the tee_rproc struct from the
          rproc struct
	- rename tee_rproc_get_loaded_rsc_table() to tee_rproc_find_loaded_rsc_table()
- remove useless check on tee_rproc_ctx structure in tee_rproc_register()
  and tee_rproc_unregister()
- fix test on the return of tee_rproc_ctx = devm_kzalloc()
- remove useless includes and unused tee_rproc_mem structure.
---
 drivers/remoteproc/Kconfig          |   9 +
 drivers/remoteproc/Makefile         |   1 +
 drivers/remoteproc/tee_remoteproc.c | 397 ++++++++++++++++++++++++++++
 include/linux/tee_remoteproc.h      | 102 +++++++
 4 files changed, 509 insertions(+)
 create mode 100644 drivers/remoteproc/tee_remoteproc.c
 create mode 100644 include/linux/tee_remoteproc.h

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 48845dc8fa85..85299606806c 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -365,6 +365,15 @@ config XLNX_R5_REMOTEPROC
 
 	  It's safe to say N if not interested in using RPU r5f cores.
 
+
+config TEE_REMOTEPROC
+	tristate "trusted firmware support by a TEE application"
+	depends on OPTEE
+	help
+	  Support for trusted remote processors firmware. The firmware
+	  authentication and/or decryption are managed by a trusted application.
+	  This can be either built-in or a loadable module.
+
 endif # REMOTEPROC
 
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 91314a9b43ce..fa8daebce277 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_RCAR_REMOTEPROC)		+= rcar_rproc.o
 obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
 obj-$(CONFIG_ST_SLIM_REMOTEPROC)	+= st_slim_rproc.o
 obj-$(CONFIG_STM32_RPROC)		+= stm32_rproc.o
+obj-$(CONFIG_TEE_REMOTEPROC)		+= tee_remoteproc.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_XLNX_R5_REMOTEPROC)	+= xlnx_r5_remoteproc.o
diff --git a/drivers/remoteproc/tee_remoteproc.c b/drivers/remoteproc/tee_remoteproc.c
new file mode 100644
index 000000000000..ac727e062d00
--- /dev/null
+++ b/drivers/remoteproc/tee_remoteproc.c
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
+ * Author: Arnaud Pouliquen <arnaud.pouliquen at st.com>
+ */
+
+#include <linux/firmware.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/remoteproc.h>
+#include <linux/slab.h>
+#include <linux/tee_drv.h>
+#include <linux/tee_remoteproc.h>
+
+#include "remoteproc_internal.h"
+
+#define MAX_TEE_PARAM_ARRY_MEMBER	4
+
+/*
+ * Authentication of the firmware and load in the remote processor memory
+ *
+ * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
+ * [in]	 params[1].memref:	buffer containing the image of the buffer
+ */
+#define TA_RPROC_FW_CMD_LOAD_FW		1
+
+/*
+ * Start the remote processor
+ *
+ * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
+ */
+#define TA_RPROC_FW_CMD_START_FW	2
+
+/*
+ * Stop the remote processor
+ *
+ * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
+ */
+#define TA_RPROC_FW_CMD_STOP_FW		3
+
+/*
+ * Return the address of the resource table, or 0 if not found
+ * No check is done to verify that the address returned is accessible by
+ * the non secure context. If the resource table is loaded in a protected
+ * memory the access by the non secure context will lead to a data abort.
+ *
+ * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
+ * [out]  params[1].value.a:	32bit LSB resource table memory address
+ * [out]  params[1].value.b:	32bit MSB resource table memory address
+ * [out]  params[2].value.a:	32bit LSB resource table memory size
+ * [out]  params[2].value.b:	32bit MSB resource table memory size
+ */
+#define TA_RPROC_FW_CMD_GET_RSC_TABLE	4
+
+/*
+ * Return the address of the core dump
+ *
+ * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
+ * [out] params[1].memref:	address of the core dump image if exist,
+ *				else return Null
+ */
+#define TA_RPROC_FW_CMD_GET_COREDUMP	5
+
+struct tee_rproc__context {
+	struct list_head sessions;
+	struct tee_context *tee_ctx;
+	struct device *dev;
+};
+
+static struct tee_rproc__context *tee_rproc_ctx;
+
+static void prepare_args(struct tee_rproc *trproc, int cmd,
+			 struct tee_ioctl_invoke_arg *arg,
+			 struct tee_param *param, unsigned int num_params)
+{
+	memset(arg, 0, sizeof(*arg));
+	memset(param, 0, MAX_TEE_PARAM_ARRY_MEMBER * sizeof(*param));
+
+	arg->func = cmd;
+	arg->session = trproc->session_id;
+	arg->num_params = num_params + 1;
+
+	param[0] = (struct tee_param) {
+		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
+		.u.value.a = trproc->rproc_id,
+	};
+}
+
+static struct tee_rproc *tee_rproc_get_context(struct rproc *rproc)
+{
+	struct tee_rproc *entry, *tmp;
+
+	list_for_each_entry_safe(entry, tmp, &tee_rproc_ctx->sessions, node) {
+		if (entry->rproc == rproc)
+			return entry;
+	}
+
+	return NULL;
+}
+
+int tee_rproc_load_fw(struct rproc *rproc, const struct firmware *fw)
+{
+	struct tee_ioctl_invoke_arg arg;
+	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
+	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
+	struct tee_shm *fw_shm;
+	int ret;
+
+	if (!trproc)
+		return -EINVAL;
+
+	fw_shm = tee_shm_register_kernel_buf(tee_rproc_ctx->tee_ctx, (void *)fw->data, fw->size);
+	if (IS_ERR(fw_shm))
+		return PTR_ERR(fw_shm);
+
+	prepare_args(trproc, TA_RPROC_FW_CMD_LOAD_FW, &arg, param, 1);
+
+	/* Provide the address of the firmware image */
+	param[1] = (struct tee_param) {
+		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
+		.u.memref = {
+			.shm = fw_shm,
+			.size = fw->size,
+			.shm_offs = 0,
+		},
+	};
+
+	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		dev_err(tee_rproc_ctx->dev,
+			"TA_RPROC_FW_CMD_LOAD_FW invoke failed TEE err: %x, ret:%x\n",
+			arg.ret, ret);
+		if (!ret)
+			ret = -EIO;
+	}
+
+	tee_shm_free(fw_shm);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tee_rproc_load_fw);
+
+struct resource_table *tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
+{
+	struct tee_ioctl_invoke_arg arg;
+	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
+	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
+	int ret;
+
+	if (!trproc)
+		return ERR_PTR(-EINVAL);
+
+	prepare_args(trproc, TA_RPROC_FW_CMD_GET_RSC_TABLE, &arg, param, 2);
+
+	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
+	param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
+
+	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		dev_err(tee_rproc_ctx->dev,
+			"TA_RPROC_FW_CMD_GET_RSC_TABLE invoke failed TEE err: %x, ret:%x\n",
+			arg.ret, ret);
+		return ERR_PTR(-EIO);
+	}
+
+	*table_sz = param[2].u.value.a;
+
+	/* If the size is null no resource table defined in the image */
+	if (!*table_sz)
+		return NULL;
+
+	/* Store the resource table address that would be updated by the remote core. */
+	trproc->rsc_table = ioremap_wc(param[1].u.value.a, *table_sz);
+	if (IS_ERR_OR_NULL(trproc->rsc_table)) {
+		dev_err(tee_rproc_ctx->dev, "Unable to map memory region: %lld+%zx\n",
+			param[1].u.value.a, *table_sz);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return trproc->rsc_table;
+}
+EXPORT_SYMBOL_GPL(tee_rproc_get_loaded_rsc_table);
+
+struct resource_table *tee_rproc_find_loaded_rsc_table(struct rproc *rproc,
+						       const struct firmware *fw)
+{
+	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
+	size_t table_sz;
+
+	if (!trproc)
+		return ERR_PTR(-EINVAL);
+
+	if (!trproc->rsc_table)
+		trproc->rsc_table = tee_rproc_get_loaded_rsc_table(rproc, &table_sz);
+
+	return trproc->rsc_table;
+}
+EXPORT_SYMBOL_GPL(tee_rproc_find_loaded_rsc_table);
+
+int tee_rproc_start(struct rproc *rproc)
+{
+	struct tee_ioctl_invoke_arg arg;
+	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
+	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
+	int ret;
+
+	if (!trproc)
+		return -EINVAL;
+
+	prepare_args(trproc, TA_RPROC_FW_CMD_START_FW, &arg, param, 0);
+
+	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		dev_err(tee_rproc_ctx->dev,
+			"TA_RPROC_FW_CMD_START_FW invoke failed TEE err: %x, ret:%x\n",
+			arg.ret, ret);
+		if (!ret)
+			ret = -EIO;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tee_rproc_start);
+
+int tee_rproc_stop(struct rproc *rproc)
+{
+	struct tee_ioctl_invoke_arg arg;
+	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
+	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
+	int ret;
+
+	if (!trproc)
+		return -EINVAL;
+
+	prepare_args(trproc, TA_RPROC_FW_CMD_STOP_FW, &arg, param, 0);
+
+	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		dev_err(tee_rproc_ctx->dev,
+			"TA_RPROC_FW_CMD_STOP_FW invoke failed TEE err: %x, ret:%x\n",
+			arg.ret, ret);
+		if (!ret)
+			ret = -EIO;
+	}
+	if (trproc->rsc_table)
+		iounmap(trproc->rsc_table);
+	trproc->rsc_table = NULL;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tee_rproc_stop);
+
+static const struct tee_client_device_id stm32_tee_rproc_id_table[] = {
+	{UUID_INIT(0x80a4c275, 0x0a47, 0x4905,
+		   0x82, 0x85, 0x14, 0x86, 0xa9, 0x77, 0x1a, 0x08)},
+	{}
+};
+
+struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id)
+{
+	struct tee_client_device *tee_device;
+	struct tee_ioctl_open_session_arg sess_arg;
+	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
+	struct tee_rproc *trproc;
+	int ret;
+
+	/*
+	 * The device is not probed by the TEE bus. We ignore the reason (bus could be not yet
+	 * probed or service not available in the secure firmware)
+	 * Assumption here is that the TEE bus is not probed.
+	 */
+	if (!tee_rproc_ctx)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	trproc =  devm_kzalloc(dev, sizeof(*trproc), GFP_KERNEL);
+	if (!trproc)
+		return ERR_PTR(-ENOMEM);
+
+	tee_device = to_tee_client_device(tee_rproc_ctx->dev);
+	memset(&sess_arg, 0, sizeof(sess_arg));
+
+	/* Open session with rproc_tee load the OP-TEE Trusted Application */
+	memcpy(sess_arg.uuid, tee_device->id.uuid.b, TEE_IOCTL_UUID_LEN);
+
+	sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
+	sess_arg.num_params = 1;
+
+	param[0] = (struct tee_param) {
+		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
+		.u.value.a = rproc_id,
+	};
+
+	ret = tee_client_open_session(tee_rproc_ctx->tee_ctx, &sess_arg, param);
+	if (ret < 0 || sess_arg.ret != 0) {
+		dev_err(dev, "tee_client_open_session failed, err: %x\n", sess_arg.ret);
+		return ERR_PTR(-EINVAL);
+	}
+
+	trproc->parent =  dev;
+	trproc->rproc_id = rproc_id;
+	trproc->session_id = sess_arg.session;
+
+	list_add_tail(&trproc->node, &tee_rproc_ctx->sessions);
+
+	return trproc;
+}
+EXPORT_SYMBOL_GPL(tee_rproc_register);
+
+int tee_rproc_unregister(struct tee_rproc *trproc)
+{
+	int ret;
+
+	ret = tee_client_close_session(tee_rproc_ctx->tee_ctx, trproc->session_id);
+	if (ret < 0)
+		dev_err(trproc->parent,	"tee_client_close_session failed, err: %x\n", ret);
+
+	list_del(&trproc->node);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tee_rproc_unregister);
+
+static int tee_rproc_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
+{
+	/* Today we support only the OP-TEE, could be extend to other tees */
+	return (ver->impl_id == TEE_IMPL_ID_OPTEE);
+}
+
+static int tee_rproc_probe(struct device *dev)
+{
+	struct tee_context *tee_ctx;
+	int ret;
+
+	/* Open context with TEE driver */
+	tee_ctx = tee_client_open_context(NULL, tee_rproc_ctx_match, NULL, NULL);
+	if (IS_ERR(tee_ctx))
+		return PTR_ERR(tee_ctx);
+
+	tee_rproc_ctx = devm_kzalloc(dev, sizeof(*tee_ctx), GFP_KERNEL);
+	if (!tee_rproc_ctx) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	tee_rproc_ctx->dev = dev;
+	tee_rproc_ctx->tee_ctx = tee_ctx;
+	INIT_LIST_HEAD(&tee_rproc_ctx->sessions);
+
+	return 0;
+err:
+	tee_client_close_context(tee_ctx);
+
+	return ret;
+}
+
+static int tee_rproc_remove(struct device *dev)
+{
+	struct tee_rproc *entry, *tmp;
+
+	list_for_each_entry_safe(entry, tmp, &tee_rproc_ctx->sessions, node) {
+		tee_client_close_session(tee_rproc_ctx->tee_ctx, entry->session_id);
+		list_del(&entry->node);
+		kfree(entry);
+	}
+
+	tee_client_close_context(tee_rproc_ctx->tee_ctx);
+
+	return 0;
+}
+
+MODULE_DEVICE_TABLE(tee, stm32_tee_rproc_id_table);
+
+static struct tee_client_driver tee_rproc_fw_driver = {
+	.id_table	= stm32_tee_rproc_id_table,
+	.driver		= {
+		.name		= KBUILD_MODNAME,
+		.bus		= &tee_bus_type,
+		.probe		= tee_rproc_probe,
+		.remove		= tee_rproc_remove,
+	},
+};
+
+static int __init tee_rproc_fw_mod_init(void)
+{
+	return driver_register(&tee_rproc_fw_driver.driver);
+}
+
+static void __exit tee_rproc_fw_mod_exit(void)
+{
+	driver_unregister(&tee_rproc_fw_driver.driver);
+}
+
+module_init(tee_rproc_fw_mod_init);
+module_exit(tee_rproc_fw_mod_exit);
+
+MODULE_DESCRIPTION(" TEE remote processor control driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/tee_remoteproc.h b/include/linux/tee_remoteproc.h
new file mode 100644
index 000000000000..7c9e91e989ba
--- /dev/null
+++ b/include/linux/tee_remoteproc.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright(c) 2023 STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef TEE_REMOTEPROC_H
+#define TEE_REMOTEPROC_H
+
+#include <linux/tee_drv.h>
+#include <linux/firmware.h>
+#include <linux/remoteproc.h>
+
+struct rproc;
+
+/**
+ * struct tee_rproc - TEE remoteproc structure
+ * @node:		Reference in list
+ * @rproc:		Remoteproc reference
+ * @parent:		Parent device
+ * @rproc_id:		Identifier of the target firmware
+ * @session_id:		TEE session identifier
+ * @rsc_table:		Resource table virtual address.
+ */
+struct tee_rproc {
+	struct list_head node;
+	struct rproc *rproc;
+	struct device *parent;
+	u32 rproc_id;
+	u32 session_id;
+	struct resource_table *rsc_table;
+};
+
+#if IS_ENABLED(CONFIG_TEE_REMOTEPROC)
+
+struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id);
+int tee_rproc_unregister(struct tee_rproc *trproc);
+
+int tee_rproc_load_fw(struct rproc *rproc, const struct firmware *fw);
+struct resource_table *tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz);
+struct resource_table *tee_rproc_find_loaded_rsc_table(struct rproc *rproc,
+						       const struct firmware *fw);
+int tee_rproc_start(struct rproc *rproc);
+int tee_rproc_stop(struct rproc *rproc);
+
+#else
+
+static inline struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline int tee_rproc_unregister(struct tee_rproc *trproc)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return 0;
+}
+
+static inline int tee_rproc_load_fw(struct rproc *rproc,  const struct firmware *fw)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return 0;
+}
+
+static inline int tee_rproc_start(struct rproc *rproc)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return 0;
+}
+
+static inline int tee_rproc_stop(struct rproc *rproc)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return 0;
+}
+
+static inline struct resource_table *
+tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return NULL;
+}
+
+static inline struct resource_table *
+tee_rproc_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return NULL;
+}
+#endif /* CONFIG_TEE_REMOTEPROC */
+#endif /* TEE_REMOTEPROC_H */
-- 
2.25.1



From arnaud.pouliquen at foss.st.com  Wed Feb 14 09:21:26 2024
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Wed, 14 Feb 2024 18:21:26 +0100
Subject: [PATCH v3 6/7] remoteproc: stm32: Create sub-functions to request shutdown and release
In-Reply-To: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
Message-ID: <20240214172127.1022199-7-arnaud.pouliquen@foss.st.com>

To prepare for the support of TEE remoteproc, create sub-functions
that can be used in both cases, with and without TEE support.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
---
 drivers/remoteproc/stm32_rproc.c | 84 +++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 33 deletions(-)

diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 4f469f0bcf8b..fcc0001e2657 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -209,6 +209,54 @@ static int stm32_rproc_mbox_idx(struct rproc *rproc, const unsigned char *name)
 	return -EINVAL;
 }
 
+static void stm32_rproc_request_shutdown(struct rproc *rproc)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+	int err, dummy_data, idx;
+
+	/* Request shutdown of the remote processor */
+	if (rproc->state != RPROC_OFFLINE && rproc->state != RPROC_CRASHED) {
+		idx = stm32_rproc_mbox_idx(rproc, STM32_MBX_SHUTDOWN);
+		if (idx >= 0 && ddata->mb[idx].chan) {
+			/* A dummy data is sent to allow to block on transmit. */
+			err = mbox_send_message(ddata->mb[idx].chan,
+						&dummy_data);
+			if (err < 0)
+				dev_warn(&rproc->dev, "warning: remote FW shutdown without ack\n");
+		}
+	}
+}
+
+static int stm32_rproc_release(struct rproc *rproc)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+	unsigned int err = 0;
+
+	/* To allow platform Standby power mode, set remote proc Deep Sleep. */
+	if (ddata->pdds.map) {
+		err = regmap_update_bits(ddata->pdds.map, ddata->pdds.reg,
+					 ddata->pdds.mask, 1);
+		if (err) {
+			dev_err(&rproc->dev, "failed to set pdds\n");
+			return err;
+		}
+	}
+
+	/* Update coprocessor state to OFF if available. */
+	if (ddata->m4_state.map) {
+		err = regmap_update_bits(ddata->m4_state.map,
+					 ddata->m4_state.reg,
+					 ddata->m4_state.mask,
+					 M4_STATE_OFF);
+		if (err) {
+			dev_err(&rproc->dev, "failed to set copro state\n");
+			return err;
+		}
+	}
+
+	return err;
+}
+
 static int stm32_rproc_prepare(struct rproc *rproc)
 {
 	struct device *dev = rproc->dev.parent;
@@ -519,17 +567,9 @@ static int stm32_rproc_detach(struct rproc *rproc)
 static int stm32_rproc_stop(struct rproc *rproc)
 {
 	struct stm32_rproc *ddata = rproc->priv;
-	int err, idx;
+	int err;
 
-	/* request shutdown of the remote processor */
-	if (rproc->state != RPROC_OFFLINE && rproc->state != RPROC_CRASHED) {
-		idx = stm32_rproc_mbox_idx(rproc, STM32_MBX_SHUTDOWN);
-		if (idx >= 0 && ddata->mb[idx].chan) {
-			err = mbox_send_message(ddata->mb[idx].chan, "detach");
-			if (err < 0)
-				dev_warn(&rproc->dev, "warning: remote FW shutdown without ack\n");
-		}
-	}
+	stm32_rproc_request_shutdown(rproc);
 
 	err = stm32_rproc_set_hold_boot(rproc, true);
 	if (err)
@@ -541,29 +581,7 @@ static int stm32_rproc_stop(struct rproc *rproc)
 		return err;
 	}
 
-	/* to allow platform Standby power mode, set remote proc Deep Sleep */
-	if (ddata->pdds.map) {
-		err = regmap_update_bits(ddata->pdds.map, ddata->pdds.reg,
-					 ddata->pdds.mask, 1);
-		if (err) {
-			dev_err(&rproc->dev, "failed to set pdds\n");
-			return err;
-		}
-	}
-
-	/* update coprocessor state to OFF if available */
-	if (ddata->m4_state.map) {
-		err = regmap_update_bits(ddata->m4_state.map,
-					 ddata->m4_state.reg,
-					 ddata->m4_state.mask,
-					 M4_STATE_OFF);
-		if (err) {
-			dev_err(&rproc->dev, "failed to set copro state\n");
-			return err;
-		}
-	}
-
-	return 0;
+	return stm32_rproc_release(rproc);
 }
 
 static void stm32_rproc_kick(struct rproc *rproc, int vqid)
-- 
2.25.1



From arnaud.pouliquen at foss.st.com  Wed Feb 14 09:21:27 2024
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Wed, 14 Feb 2024 18:21:27 +0100
Subject: [PATCH v3 7/7] remoteproc: stm32: Add support of an OP-TEE TA to load the firmware
In-Reply-To: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
Message-ID: <20240214172127.1022199-8-arnaud.pouliquen@foss.st.com>

The new TEE remoteproc device is used to manage remote firmware in a
secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
introduced to delegate the loading of the firmware to the trusted
execution context. In such cases, the firmware should be signed and
adhere to the image format defined by the TEE.

A new "to_attach" field is introduced to differentiate the use cases
"firmware loaded by the boot stage" and "firmware loaded by the TEE".

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
---
V2 to V3 update:
- remove stm32_rproc_tee_elf_sanity_check(), stm32_rproc_tee_elf_load()
  stm32_rproc_tee_elf_find_loaded_rsc_table() and  stm32_rproc_tee_start() that are bnow unused
- use new rproc::alt_boot field to sepcify that the alternate fboot method is used
- use stm32_rproc::to_attach field to differenciate attch mode from remoteproc tee boot mode.
- remove the used of stm32_rproc::fw_loaded
---
 drivers/remoteproc/stm32_rproc.c | 85 +++++++++++++++++++++++++++++---
 1 file changed, 79 insertions(+), 6 deletions(-)

diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index fcc0001e2657..9cfcf66462e0 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -20,6 +20,7 @@
 #include <linux/remoteproc.h>
 #include <linux/reset.h>
 #include <linux/slab.h>
+#include <linux/tee_remoteproc.h>
 #include <linux/workqueue.h>
 
 #include "remoteproc_internal.h"
@@ -49,6 +50,9 @@
 #define M4_STATE_STANDBY	4
 #define M4_STATE_CRASH		5
 
+/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
+#define STM32_MP1_M4_PROC_ID    0
+
 struct stm32_syscon {
 	struct regmap *map;
 	u32 reg;
@@ -90,6 +94,8 @@ struct stm32_rproc {
 	struct stm32_mbox mb[MBOX_NB_MBX];
 	struct workqueue_struct *workqueue;
 	bool hold_boot_smc;
+	bool to_attach;
+	struct tee_rproc *trproc;
 	void __iomem *rsc_va;
 };
 
@@ -253,10 +259,30 @@ static int stm32_rproc_release(struct rproc *rproc)
 			return err;
 		}
 	}
+	ddata->to_attach = false;
 
 	return err;
 }
 
+static int stm32_rproc_tee_attach(struct rproc *rproc)
+{
+	/* Nothing to do, remote proc already started by the secured context. */
+	return 0;
+}
+
+static int stm32_rproc_tee_stop(struct rproc *rproc)
+{
+	int err;
+
+	stm32_rproc_request_shutdown(rproc);
+
+	err = tee_rproc_stop(rproc);
+	if (err)
+		return err;
+
+	return stm32_rproc_release(rproc);
+}
+
 static int stm32_rproc_prepare(struct rproc *rproc)
 {
 	struct device *dev = rproc->dev.parent;
@@ -637,10 +663,14 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
 {
 	struct stm32_rproc *ddata = rproc->priv;
 	struct device *dev = rproc->dev.parent;
+	struct tee_rproc *trproc = ddata->trproc;
 	phys_addr_t rsc_pa;
 	u32 rsc_da;
 	int err;
 
+	if (trproc && !ddata->to_attach)
+		return tee_rproc_get_loaded_rsc_table(rproc, table_sz);
+
 	/* The resource table has already been mapped, nothing to do */
 	if (ddata->rsc_va)
 		goto done;
@@ -693,8 +723,20 @@ static const struct rproc_ops st_rproc_ops = {
 	.get_boot_addr	= rproc_elf_get_boot_addr,
 };
 
+static const struct rproc_ops st_rproc_tee_ops = {
+	.prepare	= stm32_rproc_prepare,
+	.start		= tee_rproc_start,
+	.stop		= stm32_rproc_tee_stop,
+	.attach		= stm32_rproc_tee_attach,
+	.kick		= stm32_rproc_kick,
+	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
+	.find_loaded_rsc_table = tee_rproc_find_loaded_rsc_table,
+	.load		= tee_rproc_load_fw,
+};
+
 static const struct of_device_id stm32_rproc_match[] = {
-	{ .compatible = "st,stm32mp1-m4" },
+	{.compatible = "st,stm32mp1-m4",},
+	{.compatible = "st,stm32mp1-m4-tee",},
 	{},
 };
 MODULE_DEVICE_TABLE(of, stm32_rproc_match);
@@ -853,6 +895,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct stm32_rproc *ddata;
 	struct device_node *np = dev->of_node;
+	struct tee_rproc *trproc = NULL;
 	struct rproc *rproc;
 	unsigned int state;
 	int ret;
@@ -861,12 +904,33 @@ static int stm32_rproc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
-	if (!rproc)
-		return -ENOMEM;
+	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
+		/*
+		 * Delegate the firmware management to the secure context.
+		 * The firmware loaded has to be signed.
+		 */
+		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
+		if (IS_ERR(trproc)) {
+			dev_err_probe(dev, PTR_ERR(trproc),
+				      "signed firmware not supported by TEE\n");
+			return PTR_ERR(trproc);
+		}
+	}
 
-	ddata = rproc->priv;
+	rproc = rproc_alloc(dev, np->name,
+			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
+			    NULL, sizeof(*ddata));
+	if (!rproc) {
+		ret = -ENOMEM;
+		goto free_tee;
+	}
 
+	ddata = rproc->priv;
+	ddata->trproc = trproc;
+	if (trproc) {
+		rproc->alt_boot = true;
+		trproc->rproc = rproc;
+	}
 	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
 
 	ret = stm32_rproc_parse_dt(pdev, ddata, &rproc->auto_boot);
@@ -881,8 +945,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
 	if (ret)
 		goto free_rproc;
 
-	if (state == M4_STATE_CRUN)
+	if (state == M4_STATE_CRUN) {
 		rproc->state = RPROC_DETACHED;
+		ddata->to_attach = true;
+	}
 
 	rproc->has_iommu = false;
 	ddata->workqueue = create_workqueue(dev_name(dev));
@@ -916,6 +982,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
 		device_init_wakeup(dev, false);
 	}
 	rproc_free(rproc);
+free_tee:
+	if (trproc)
+		tee_rproc_unregister(trproc);
+
 	return ret;
 }
 
@@ -923,6 +993,7 @@ static void stm32_rproc_remove(struct platform_device *pdev)
 {
 	struct rproc *rproc = platform_get_drvdata(pdev);
 	struct stm32_rproc *ddata = rproc->priv;
+	struct tee_rproc *trproc = ddata->trproc;
 	struct device *dev = &pdev->dev;
 
 	if (atomic_read(&rproc->power) > 0)
@@ -937,6 +1008,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
 		device_init_wakeup(dev, false);
 	}
 	rproc_free(rproc);
+	if (trproc)
+		tee_rproc_unregister(trproc);
 }
 
 static int stm32_rproc_suspend(struct device *dev)
-- 
2.25.1



From khilman at kernel.org  Wed Feb 14 09:26:13 2024
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 14 Feb 2024 09:26:13 -0800
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI
 TPS65224 PMIC
In-Reply-To: <20240214-galley-dweller-1e9872229d80@spud>
References: <20240209-blitz-fidgety-78469aa80d6d@spud>
 <20240214093106.86483-1-bhargav.r@ltts.com>
 <20240214-galley-dweller-1e9872229d80@spud>
Message-ID: <7hil2r5556.fsf@baylibre.com>

Conor Dooley <conor at kernel.org> writes:

> On Wed, Feb 14, 2024 at 03:01:06PM +0530, Bhargav Raviprakash wrote:
>> Hi Conor,
>> 
>> On Fri 2/9/2024 10:41 PM, Conor Dooley wrote:
>> > On Thu, Feb 08, 2024 at 04:23:33PM +0530, Bhargav Raviprakash wrote:
>> > > TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
>> > > regulators, it includes additional features like GPIOs, watchdog, ESMs
>> > > (Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
>> > > managing the state of the device.
>> > 
>> > > TPS6594 and TPS65224 have significant functional overlap.
>> > 
>> > What does "significant functional overlap" mean? Does one implement a
>> > compatible subset of the other? I assume the answer is no, given there
>> > seems to be some core looking registers at different addresses.
>> 
>> The intention behind ?significant functional overlap? was meant to
>> indicate a lot of the features between TPS6594 and TPS65224 overlap,
>> while there are some features specific to TPS65224.
>> There is compatibility between the PMIC register maps, I2C, PFSM,
>> and other drivers even though there are some core registers at
>> different addresses.
>> 
>> Would it be more appropriate to say the 2 devices are compatible and have
>> sufficient feature overlap rather than significant functional overlap?
>
> If core registers are at different addresses, then it is unlikely that
> these devices are compatible.

That's not necessarily true.  Hardware designers can sometimes be
creative. :)

> In this context, compatible means that existing software intended for
> the 6594 would run without modification on the 65224, although maybe
> only supporting a subset of features.  If that's not the case, then
> the devices are not compatible.

Compatible is a fuzzy term... so we need to get into the gray area.

What's going on here is that this new part is derivative in many
signifcant (but not all) ways from an existing similar part.  When
writing drivers for new, derivative parts, there's always a choice
between 1) extending the existing driver (using a new compatible string
& match table for the diffs) or 2) creating a new driver which will have
a bunch of duplicated code.

The first verion of this series[1] took the 2nd approach, but due to the
significant functional (and feature) overlap, the recommendation was
instead to take the "reuse" path to avoid signficant amounts of
duplicated code.

Of course, it's possible that while going down the "reuse" path, there
may be a point where creating a separate driver for some aspects might
make sense, but that needs to be justified.  Based on a quick glance of
what I see in this series so far (I have not done a detailed review),
the differences with the new device look to me like they can be handled
with chip-specific data in a match table.

Kevin

[1] https://lore.kernel.org/lkml/20231026133226.290040-1-sirisha.gairuboina at Ltts.com/


From conor at kernel.org  Wed Feb 14 09:37:17 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 14 Feb 2024 17:37:17 +0000
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240214142825.GA7873@pendragon.ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <20240214142825.GA7873@pendragon.ideasonboard.com>
Message-ID: <20240214-velcro-pushy-0cbd18b23361@spud>

On Wed, Feb 14, 2024 at 04:28:25PM +0200, Laurent Pinchart wrote:
> Hi Dan,
> 
> Thank you for the patch.
> 
> On Wed, Feb 14, 2024 at 02:19:03PM +0000, Daniel Scally wrote:
> > Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
> > 
> > Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> > Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> > ---
> > Changes in v2:
> > 
> > 	- Added clocks information
> > 	- Fixed the warnings raised by Rob
> > 
> >  .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
> >  1 file changed, 77 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > new file mode 100644
> > index 000000000000..30038cfec3a4
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > @@ -0,0 +1,77 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: ARM Mali-C55 Image Signal Processor
> > +
> > +maintainers:
> > +  - Daniel Scally <dan.scally at ideasonboard.com>
> > +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > +
> > +properties:
> > +  compatible:
> > +    const: arm,mali-c55
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    items:
> > +      - description: ISP video clock
> 
> I wonder if we need this clock. Granted, it's an input clock to the ISP,
> but it's part of the input video bus. I don't expect anyone would ever
> need to control it manually, it should be provided by the video source
> automatically.

I'd say that if there's a clock controller providing this clock, even if
it is implicit in the video feed it's good to have here. Being able to
increment the refcount on that clock would be good, even if you don't
actually control it manually?

> 
> > +      - description: ISP AXI clock
> > +      - description: ISP AHB-lite clock
> 
> These two other clocks look good to me.
> 
> > +
> > +  clock-names:
> > +    items:
> > +      - const: vclk
> > +      - const: aclk
> > +      - const: hclk

Why not "video" "axi" "ahb-lite"? There's 3 useful letters between the
tree clock names you've provided - they're all clocks, so having "clk"
in them is just noise :)

Cheers,
Conor.
-------------- 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/20240214/5e1b9e7a/attachment-0001.sig>

From andriy.shevchenko at linux.intel.com  Wed Feb 14 09:37:41 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 14 Feb 2024 19:37:41 +0200
Subject: [PATCH v2 1/2] dt-bindings: auxdisplay: adjust example
 indentation and use generic node names
In-Reply-To: <20240214155438.155139-1-krzysztof.kozlowski@linaro.org>
References: <20240214155438.155139-1-krzysztof.kozlowski@linaro.org>
Message-ID: <Zcz6ZbZZBhVeOELO@smile.fi.intel.com>

On Wed, Feb 14, 2024 at 04:54:37PM +0100, Krzysztof Kozlowski wrote:
> The example DTS should be indented with two or four (preferred) spaces,
> as mentioned in Writing Schema document.  While re-indenting, change the
> node names to somehow generic names, as expected by Devicetree
> specification.

Applied, thanks!

-- 
With Best Regards,
Andy Shevchenko




From andriy.shevchenko at linux.intel.com  Wed Feb 14 09:37:56 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 14 Feb 2024 19:37:56 +0200
Subject: [PATCH v2 2/2] dt-bindings: auxdisplay: hit,hd44780: use defines
 for GPIO flags
In-Reply-To: <20240214155438.155139-2-krzysztof.kozlowski@linaro.org>
References: <20240214155438.155139-1-krzysztof.kozlowski@linaro.org>
 <20240214155438.155139-2-krzysztof.kozlowski@linaro.org>
Message-ID: <Zcz6dMz2h2jrhOXu@smile.fi.intel.com>

On Wed, Feb 14, 2024 at 04:54:38PM +0100, Krzysztof Kozlowski wrote:
> Improve example DTS readability by using known defines for GPIO flags.

Applied, thanks!

-- 
With Best Regards,
Andy Shevchenko




From me at kylehuey.com  Wed Feb 14 09:39:33 2024
From: me at kylehuey.com (Kyle Huey)
Date: Wed, 14 Feb 2024 09:39:33 -0800
Subject: [RESEND PATCH v5 2/4] perf/bpf: Remove unneeded uses_default_overflow_handler.
In-Reply-To: <20240214173950.18570-1-khuey@kylehuey.com>
References: <20240214173950.18570-1-khuey@kylehuey.com>
Message-ID: <20240214173950.18570-3-khuey@kylehuey.com>

Now that struct perf_event's orig_overflow_handler is gone, there's no need
for the functions and macros to support looking past overflow_handler to
orig_overflow_handler.

This patch is solely a refactoring and results in no behavior change.

Signed-off-by: Kyle Huey <khuey at kylehuey.com>
Acked-by: Will Deacon <will at kernel.org>
Acked-by: Song Liu <song at kernel.org>
Acked-by: Jiri Olsa <jolsa at kernel.org>
---
 arch/arm/kernel/hw_breakpoint.c   |  8 ++++----
 arch/arm64/kernel/hw_breakpoint.c |  4 ++--
 include/linux/perf_event.h        | 16 ++--------------
 3 files changed, 8 insertions(+), 20 deletions(-)

diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index dc0fb7a81371..054e9199f30d 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -626,7 +626,7 @@ int hw_breakpoint_arch_parse(struct perf_event *bp,
 	hw->address &= ~alignment_mask;
 	hw->ctrl.len <<= offset;
 
-	if (uses_default_overflow_handler(bp)) {
+	if (is_default_overflow_handler(bp)) {
 		/*
 		 * Mismatch breakpoints are required for single-stepping
 		 * breakpoints.
@@ -798,7 +798,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
 		 * Otherwise, insert a temporary mismatch breakpoint so that
 		 * we can single-step over the watchpoint trigger.
 		 */
-		if (!uses_default_overflow_handler(wp))
+		if (!is_default_overflow_handler(wp))
 			continue;
 step:
 		enable_single_step(wp, instruction_pointer(regs));
@@ -811,7 +811,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
 		info->trigger = addr;
 		pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
 		perf_bp_event(wp, regs);
-		if (uses_default_overflow_handler(wp))
+		if (is_default_overflow_handler(wp))
 			enable_single_step(wp, instruction_pointer(regs));
 	}
 
@@ -886,7 +886,7 @@ static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs)
 			info->trigger = addr;
 			pr_debug("breakpoint fired: address = 0x%x\n", addr);
 			perf_bp_event(bp, regs);
-			if (uses_default_overflow_handler(bp))
+			if (is_default_overflow_handler(bp))
 				enable_single_step(bp, addr);
 			goto unlock;
 		}
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 35225632d70a..db2a1861bb97 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -654,7 +654,7 @@ static int breakpoint_handler(unsigned long unused, unsigned long esr,
 		perf_bp_event(bp, regs);
 
 		/* Do we need to handle the stepping? */
-		if (uses_default_overflow_handler(bp))
+		if (is_default_overflow_handler(bp))
 			step = 1;
 unlock:
 		rcu_read_unlock();
@@ -733,7 +733,7 @@ static u64 get_distance_from_watchpoint(unsigned long addr, u64 val,
 static int watchpoint_report(struct perf_event *wp, unsigned long addr,
 			     struct pt_regs *regs)
 {
-	int step = uses_default_overflow_handler(wp);
+	int step = is_default_overflow_handler(wp);
 	struct arch_hw_breakpoint *info = counter_arch_bp(wp);
 
 	info->trigger = addr;
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index c7f54fd74d89..c8bd5bb6610c 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1341,8 +1341,9 @@ extern int perf_event_output(struct perf_event *event,
 			     struct pt_regs *regs);
 
 static inline bool
-__is_default_overflow_handler(perf_overflow_handler_t overflow_handler)
+is_default_overflow_handler(struct perf_event *event)
 {
+	perf_overflow_handler_t overflow_handler = event->overflow_handler;
 	if (likely(overflow_handler == perf_event_output_forward))
 		return true;
 	if (unlikely(overflow_handler == perf_event_output_backward))
@@ -1350,19 +1351,6 @@ __is_default_overflow_handler(perf_overflow_handler_t overflow_handler)
 	return false;
 }
 
-#define is_default_overflow_handler(event) \
-	__is_default_overflow_handler((event)->overflow_handler)
-
-#ifdef CONFIG_BPF_SYSCALL
-static inline bool uses_default_overflow_handler(struct perf_event *event)
-{
-	return is_default_overflow_handler(event);
-}
-#else
-#define uses_default_overflow_handler(event) \
-	is_default_overflow_handler(event)
-#endif
-
 extern void
 perf_event_header__init_id(struct perf_event_header *header,
 			   struct perf_sample_data *data,
-- 
2.34.1



From conor at kernel.org  Wed Feb 14 09:45:39 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 14 Feb 2024 17:45:39 +0000
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI
 TPS65224 PMIC
In-Reply-To: <7hil2r5556.fsf@baylibre.com>
References: <20240209-blitz-fidgety-78469aa80d6d@spud>
 <20240214093106.86483-1-bhargav.r@ltts.com>
 <20240214-galley-dweller-1e9872229d80@spud>
 <7hil2r5556.fsf@baylibre.com>
Message-ID: <20240214-depraved-unfunded-3f0b3d6bf3e2@spud>

On Wed, Feb 14, 2024 at 09:26:13AM -0800, Kevin Hilman wrote:
> Conor Dooley <conor at kernel.org> writes:
> > On Wed, Feb 14, 2024 at 03:01:06PM +0530, Bhargav Raviprakash wrote:
> >> On Fri 2/9/2024 10:41 PM, Conor Dooley wrote:
> >> > On Thu, Feb 08, 2024 at 04:23:33PM +0530, Bhargav Raviprakash wrote:
> >> > > TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
> >> > > regulators, it includes additional features like GPIOs, watchdog, ESMs
> >> > > (Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
> >> > > managing the state of the device.
> >> > 
> >> > > TPS6594 and TPS65224 have significant functional overlap.
> >> > 
> >> > What does "significant functional overlap" mean? Does one implement a
> >> > compatible subset of the other? I assume the answer is no, given there
> >> > seems to be some core looking registers at different addresses.
> >> 
> >> The intention behind ?significant functional overlap? was meant to
> >> indicate a lot of the features between TPS6594 and TPS65224 overlap,
> >> while there are some features specific to TPS65224.
> >> There is compatibility between the PMIC register maps, I2C, PFSM,
> >> and other drivers even though there are some core registers at
> >> different addresses.
> >> 
> >> Would it be more appropriate to say the 2 devices are compatible and have
> >> sufficient feature overlap rather than significant functional overlap?
> >
> > If core registers are at different addresses, then it is unlikely that
> > these devices are compatible.
> 
> That's not necessarily true.  Hardware designers can sometimes be
> creative. :)

Hence "unlikely" in my mail :)

> > In this context, compatible means that existing software intended for
> > the 6594 would run without modification on the 65224, although maybe
> > only supporting a subset of features.  If that's not the case, then
> > the devices are not compatible.
> 
> Compatible is a fuzzy term... so we need to get into the gray area.
> 
> What's going on here is that this new part is derivative in many
> signifcant (but not all) ways from an existing similar part.  When
> writing drivers for new, derivative parts, there's always a choice
> between 1) extending the existing driver (using a new compatible string
> & match table for the diffs) or 2) creating a new driver which will have
> a bunch of duplicated code.
> 
> The first verion of this series[1] took the 2nd approach, but due to the
> significant functional (and feature) overlap, the recommendation was
> instead to take the "reuse" path to avoid signficant amounts of
> duplicated code.
> 
> Of course, it's possible that while going down the "reuse" path, there
> may be a point where creating a separate driver for some aspects might
> make sense, but that needs to be justified.  Based on a quick glance of
> what I see in this series so far (I have not done a detailed review),
> the differences with the new device look to me like they can be handled
> with chip-specific data in a match table.

This is all nice information, but not really relevant here - this is a
binding patch, not a driver one & the conversation stemmed from me
making sure that a fallback compatible was not suitable. Whether or not
there are multiple drivers or not is someone else's problem!

Thanks,
Conor.
-------------- 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/20240214/65b10c84/attachment.sig>

From conor at kernel.org  Wed Feb 14 09:54:26 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 14 Feb 2024 17:54:26 +0000
Subject: [PATCH v2 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <20240214080348.7540-3-mihai.sain@microchip.com>
References: <20240214080348.7540-1-mihai.sain@microchip.com>
 <20240214080348.7540-3-mihai.sain@microchip.com>
Message-ID: <20240214-robe-pregnancy-a1b056c9fe14@spud>

On Wed, Feb 14, 2024 at 10:03:47AM +0200, Mihai Sain wrote:
> Add flexcom 10 node for usage on the SAMA7G54 Curiosity board.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/sama7g5.dtsi | 26 ++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> index 269e0a3ca269..c90e404e8ed9 100644
> --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
> +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> @@ -958,6 +958,32 @@ i2c9: i2c at 600 {
>  			};
>  		};
>  
> +		flx10: flexcom at e2820000 {
> +			compatible = "atmel,sama5d2-flexcom";
> +			reg = <0xe2820000 0x200>;

This is a sama7g5, how come this flexcom is using a sama5d2 compatible?

Cheers,
Conor.

> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0x0 0xe2820000 0x800>;
> +			status = "disabled";
> +
> +			i2c10: i2c at 600 {
> +				compatible = "microchip,sama7g5-i2c", "microchip,sam9x60-i2c";
> +				reg = <0x600 0x200>;
> +				interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +				clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
> +				atmel,fifo-size = <32>;
> +				dmas = <&dma0 AT91_XDMAC_DT_PERID(25)>,
> +					<&dma0 AT91_XDMAC_DT_PERID(26)>;
> +				dma-names = "rx", "tx";
> +				atmel,use-dma-rx;
> +				atmel,use-dma-tx;
> +				status = "disabled";
> +			};
> +		};
> +
>  		flx11: flexcom at e2824000 {
>  			compatible = "atmel,sama5d2-flexcom";
>  			reg = <0xe2824000 0x200>;
> -- 
> 2.43.0
> 
-------------- 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/20240214/7151eb4c/attachment-0001.sig>

From eahariha at linux.microsoft.com  Wed Feb 14 09:55:18 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Wed, 14 Feb 2024 17:55:18 +0000
Subject: [PATCH v2] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM Neoverse N2 errata
Message-ID: <20240214175522.2457857-1-eahariha@linux.microsoft.com>

Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft
implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore
suffers from all the same errata.

CC: stable at vger.kernel.org # 5.15+
Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>
---
changelog:
v1->v2:
* v1: https://lore.kernel.org/linux-arm-kernel/20240212232909.2276378-1-eahariha at linux.microsoft.com/T/#u
* Consistently use MICROSOFT throughout
---
 Documentation/arch/arm64/silicon-errata.rst | 7 +++++++
 arch/arm64/include/asm/cputype.h            | 4 ++++
 arch/arm64/kernel/cpu_errata.c              | 3 +++
 3 files changed, 14 insertions(+)

diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index e8c2ce1f9df6..45a7f4932fe0 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -243,3 +243,10 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ASR            | ASR8601         | #8601001        | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
++----------------+-----------------+-----------------+-----------------------------+
+| Microsoft      | Azure Cobalt 100| #2139208        | ARM64_ERRATUM_2139208       |
++----------------+-----------------+-----------------+-----------------------------+
+| Microsoft      | Azure Cobalt 100| #2067961        | ARM64_ERRATUM_2067961       |
++----------------+-----------------+-----------------+-----------------------------+
+| Microsoft      | Azure Cobalt 100| #2253138        | ARM64_ERRATUM_2253138       |
++----------------+-----------------+-----------------+-----------------------------+
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 7c7493cb571f..52f076afeb96 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -61,6 +61,7 @@
 #define ARM_CPU_IMP_HISI		0x48
 #define ARM_CPU_IMP_APPLE		0x61
 #define ARM_CPU_IMP_AMPERE		0xC0
+#define ARM_CPU_IMP_MICROSOFT		0x6D
 
 #define ARM_CPU_PART_AEM_V8		0xD0F
 #define ARM_CPU_PART_FOUNDATION		0xD00
@@ -135,6 +136,8 @@
 
 #define AMPERE_CPU_PART_AMPERE1		0xAC3
 
+#define MICROSOFT_CPU_PART_AZURE_COBALT_100	0xD49 /* Based on r0p0 of ARM Neoverse N2 */
+
 #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
 #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
 #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
@@ -193,6 +196,7 @@
 #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)
 #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
 #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
+#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100)
 
 /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
 #define MIDR_FUJITSU_ERRATUM_010001		MIDR_FUJITSU_A64FX
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 967c7c7a4e7d..76b8dd37092a 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -374,6 +374,7 @@ static const struct midr_range erratum_1463225[] = {
 static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
 #ifdef CONFIG_ARM64_ERRATUM_2139208
 	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_2119858
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
@@ -387,6 +388,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
 static const struct midr_range tsb_flush_fail_cpus[] = {
 #ifdef CONFIG_ARM64_ERRATUM_2067961
 	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_2054223
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
@@ -399,6 +401,7 @@ static const struct midr_range tsb_flush_fail_cpus[] = {
 static struct midr_range trbe_write_out_of_range_cpus[] = {
 #ifdef CONFIG_ARM64_ERRATUM_2253138
 	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_2224489
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
-- 
2.34.1



From andersson at kernel.org  Wed Feb 14 09:57:20 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Wed, 14 Feb 2024 11:57:20 -0600
Subject: [PATCH] arm64: defconfig: Enable X1E80100 multimedia clock controllers configs
In-Reply-To: <20240208-x1e80100-configs-v1-1-9e027bee5209@linaro.org>
References: <20240208-x1e80100-configs-v1-1-9e027bee5209@linaro.org>
Message-ID: <170793345828.27225.16242770102119393725.b4-ty@kernel.org>


On Thu, 08 Feb 2024 15:19:00 +0200, Abel Vesa wrote:
> Enable as modules the CAM, GPU, DISP and TCSR clock controllers for
> Qualcomm X1E80100 platform.
> 
> 

Applied, thanks!

[1/1] arm64: defconfig: Enable X1E80100 multimedia clock controllers configs
      commit: 1734e725ef512c1f9def3febc5920ef43decbe93

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From andersson at kernel.org  Wed Feb 14 09:57:38 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Wed, 14 Feb 2024 11:57:38 -0600
Subject: [PATCH v2] arm64: defconfig: Enable GCC and interconnect for QDU1000/QRU1000
In-Reply-To: <20240213095459.18402-1-quic_kbajaj@quicinc.com>
References: <20240213095459.18402-1-quic_kbajaj@quicinc.com>
Message-ID: <170793345822.27225.4479785108702422116.b4-ty@kernel.org>


On Tue, 13 Feb 2024 15:24:59 +0530, Komal Bajaj wrote:
> Add the QDU1000/QRU1000 GCC and interconnect drivers as built-in.
> These are necessary for the Qualcomm QDU1000/QRU1000 platform to boot
> to shell.
> 
> 

Applied, thanks!

[1/1] arm64: defconfig: Enable GCC and interconnect for QDU1000/QRU1000
      commit: 0b76fc39b7d8ad012a6ae2e39094ca7cf00c33dd

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From andersson at kernel.org  Wed Feb 14 09:57:35 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Wed, 14 Feb 2024 11:57:35 -0600
Subject: [PATCH] arm64: deconfig: enable Goodix Berlin SPI touchscreen driver as module
In-Reply-To: <20240203-topic-sm8x50-upstream-goodix-spi-defconfig-v1-1-b69ed85ddd05@linaro.org>
References: <20240203-topic-sm8x50-upstream-goodix-spi-defconfig-v1-1-b69ed85ddd05@linaro.org>
Message-ID: <170793345829.27225.7630789789345289123.b4-ty@kernel.org>


On Sat, 03 Feb 2024 21:20:17 +0100, Neil Armstrong wrote:
> enable Goodix Berlin SPI driver as module since used on the
> Qualcomm SM8550 QRD and SM8650 QRD platforms.
> 
> 

Applied, thanks!

[1/1] arm64: deconfig: enable Goodix Berlin SPI touchscreen driver as module
      commit: 95af34a4c25c2e5429bf76643cdab9c2d3cde6e3

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From jonathanh at nvidia.com  Wed Feb 14 10:02:16 2024
From: jonathanh at nvidia.com (Jon Hunter)
Date: Wed, 14 Feb 2024 18:02:16 +0000
Subject: [PATCH] arm64: tegra: Set the correct PHY mode for MGBE
In-Reply-To: <20240202100812.866143-1-thierry.reding@gmail.com>
References: <20240202100812.866143-1-thierry.reding@gmail.com>
Message-ID: <98b992b7-503f-48d3-86ce-4db7d76205f9@nvidia.com>


On 02/02/2024 10:08, Thierry Reding wrote:
> From: Thierry Reding <treding at nvidia.com>
> 
> The PHY is configured in 10GBASE-R, so make sure to reflect that in DT.
> 
> Signed-off-by: Thierry Reding <treding at nvidia.com>
> ---
>   arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
> index ea13c4a7027c..81a82933e350 100644
> --- a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
> +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
> @@ -175,7 +175,7 @@ ethernet at 6800000 {
>   			status = "okay";
>   
>   			phy-handle = <&mgbe0_phy>;
> -			phy-mode = "usxgmii";
> +			phy-mode = "10gbase-r";
>   
>   			mdio {
>   				#address-cells = <1>;

Reviewed-by: Jon Hunter <jonathanh at nvidia.com>
Tested-by: Jon Hunter <jonathanh at nvidia.com>

I just realised that v6.8-rc4 is still broken without the above for 
Jetson AGX Orin. Can we get this into v6.8 as a fix?

Thanks!
Jon

-- 
nvpublic


From khilman at kernel.org  Wed Feb 14 10:02:42 2024
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 14 Feb 2024 10:02:42 -0800
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI
 TPS65224 PMIC
In-Reply-To: <20240214-depraved-unfunded-3f0b3d6bf3e2@spud>
References: <20240209-blitz-fidgety-78469aa80d6d@spud>
 <20240214093106.86483-1-bhargav.r@ltts.com>
 <20240214-galley-dweller-1e9872229d80@spud> <7hil2r5556.fsf@baylibre.com>
 <20240214-depraved-unfunded-3f0b3d6bf3e2@spud>
Message-ID: <7hfrxu6i0t.fsf@baylibre.com>

Conor Dooley <conor at kernel.org> writes:

> On Wed, Feb 14, 2024 at 09:26:13AM -0800, Kevin Hilman wrote:
>> Conor Dooley <conor at kernel.org> writes:
>> > On Wed, Feb 14, 2024 at 03:01:06PM +0530, Bhargav Raviprakash wrote:
>> >> On Fri 2/9/2024 10:41 PM, Conor Dooley wrote:
>> >> > On Thu, Feb 08, 2024 at 04:23:33PM +0530, Bhargav Raviprakash wrote:
>> >> > > TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
>> >> > > regulators, it includes additional features like GPIOs, watchdog, ESMs
>> >> > > (Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
>> >> > > managing the state of the device.
>> >> > 
>> >> > > TPS6594 and TPS65224 have significant functional overlap.
>> >> > 
>> >> > What does "significant functional overlap" mean? Does one implement a
>> >> > compatible subset of the other? I assume the answer is no, given there
>> >> > seems to be some core looking registers at different addresses.
>> >> 
>> >> The intention behind ?significant functional overlap? was meant to
>> >> indicate a lot of the features between TPS6594 and TPS65224 overlap,
>> >> while there are some features specific to TPS65224.
>> >> There is compatibility between the PMIC register maps, I2C, PFSM,
>> >> and other drivers even though there are some core registers at
>> >> different addresses.
>> >> 
>> >> Would it be more appropriate to say the 2 devices are compatible and have
>> >> sufficient feature overlap rather than significant functional overlap?
>> >
>> > If core registers are at different addresses, then it is unlikely that
>> > these devices are compatible.
>> 
>> That's not necessarily true.  Hardware designers can sometimes be
>> creative. :)
>
> Hence "unlikely" in my mail :)
>
>> > In this context, compatible means that existing software intended for
>> > the 6594 would run without modification on the 65224, although maybe
>> > only supporting a subset of features.  If that's not the case, then
>> > the devices are not compatible.
>> 
>> Compatible is a fuzzy term... so we need to get into the gray area.
>> 
>> What's going on here is that this new part is derivative in many
>> signifcant (but not all) ways from an existing similar part.  When
>> writing drivers for new, derivative parts, there's always a choice
>> between 1) extending the existing driver (using a new compatible string
>> & match table for the diffs) or 2) creating a new driver which will have
>> a bunch of duplicated code.
>> 
>> The first verion of this series[1] took the 2nd approach, but due to the
>> significant functional (and feature) overlap, the recommendation was
>> instead to take the "reuse" path to avoid signficant amounts of
>> duplicated code.
>> 
>> Of course, it's possible that while going down the "reuse" path, there
>> may be a point where creating a separate driver for some aspects might
>> make sense, but that needs to be justified.  Based on a quick glance of
>> what I see in this series so far (I have not done a detailed review),
>> the differences with the new device look to me like they can be handled
>> with chip-specific data in a match table.
>
> This is all nice information, but not really relevant here - this is a
> binding patch, not a driver one & the conversation stemmed from me
> making sure that a fallback compatible was not suitable.

hehe, oops. <blush>.  my fault for mixing the two together

Sorry for the noise.

Kevin


From conor at kernel.org  Wed Feb 14 10:04:17 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 14 Feb 2024 18:04:17 +0000
Subject: [PATCH] dt-bindings: mfd: Convert atmel-flexcom to json-schema
In-Reply-To: <20240214-sama5d2-flexcom-yaml-v1-1-5dedd0eba08e@microchip.com>
References: <20240214-sama5d2-flexcom-yaml-v1-1-5dedd0eba08e@microchip.com>
Message-ID: <20240214-vagueness-voice-15fb82c56bfb@spud>

On Wed, Feb 14, 2024 at 11:13:43AM +0530, Balakrishnan Sambath wrote:
> From: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
> 
> Convert the Atmel flexcom device tree bindings to json schema.
> 
> Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>
> ---
> The yaml DT bindings for the atmel-flexcom driver were submitted
> upstream in a separate patch series in 2022 [1] which was Acked-by
> Krzysztof Kozlowski. However, it has been observed recently that the
> patch has not been merged into the mainline codebase.When attempting to
> apply the patch to the latest upstream kernel,a conflict arose due to a
> recent addition to the original device tree binding in text format. The
> conflict has now been resolved and we are sending a updated version of
> the patch. 

I don't think you actually resolved this conflict:

> +properties:
> +  compatible:
> +    enum:
> +      - atmel,sama5d2-flexcom

> -- compatible:		Should be "atmel,sama5d2-flexcom"

> -			or "microchip,sam9x7-flexcom", "atmel,sama5d2-flexcom"

This line here is the "recent addition", but this is not in the new yaml
binding.

Please fix!

Thanks,
Conor.
-------------- 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/20240214/afd0a5ad/attachment.sig>

From eauger at redhat.com  Wed Feb 14 10:07:58 2024
From: eauger at redhat.com (Eric Auger)
Date: Wed, 14 Feb 2024 19:07:58 +0100
Subject: [PATCH v1 2/4] KVM: arm64: Document
 KVM_ARM_GET_REG_WRITABLE_MASKS
In-Reply-To: <86a5o45sb8.wl-maz@kernel.org>
References: <20230919175017.538312-1-jingzhangos@google.com>
 <20230919175017.538312-3-jingzhangos@google.com>
 <82b72bd2-c079-40c3-90b8-30174f2a8fe0@redhat.com>
 <86a5o45sb8.wl-maz@kernel.org>
Message-ID: <25434f0e-d9c9-45dc-82a1-7466bc59a6e2@redhat.com>

Hi Marc,

On 2/13/24 15:53, Marc Zyngier wrote:
> Hey Eric,
> 
> On Tue, 13 Feb 2024 13:59:31 +0000,
> Eric Auger <eauger at redhat.com> wrote:
>>
>> Hi,
>>
>> On 9/19/23 19:50, Jing Zhang wrote:
>>> Add some basic documentation on how to get feature ID register writable
>>> masks from userspace.
>>>
>>> Signed-off-by: Jing Zhang <jingzhangos at google.com>
>>> ---
>>>  Documentation/virt/kvm/api.rst | 42 ++++++++++++++++++++++++++++++++++
>>>  1 file changed, 42 insertions(+)
>>>
>>> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
>>> index 21a7578142a1..2defb5e198ce 100644
>>> --- a/Documentation/virt/kvm/api.rst
>>> +++ b/Documentation/virt/kvm/api.rst
>>> @@ -6070,6 +6070,48 @@ writes to the CNTVCT_EL0 and CNTPCT_EL0 registers using the SET_ONE_REG
>>>  interface. No error will be returned, but the resulting offset will not be
>>>  applied.
>>>  
>>> +4.139 KVM_ARM_GET_REG_WRITABLE_MASKS
>>> +-------------------------------------------
>>> +
>>> +:Capability: KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES
>>> +:Architectures: arm64
>>> +:Type: vm ioctl
>>> +:Parameters: struct reg_mask_range (in/out)
>>> +:Returns: 0 on success, < 0 on error
>>> +
>>> +
>>> +::
>>> +
>>> +        #define ARM64_FEATURE_ID_SPACE_SIZE	(3 * 8 * 8)
>>> +        #define ARM64_FEATURE_ID_RANGE_IDREGS	BIT(0)
>>> +
>>> +        struct reg_mask_range {
>>> +                __u64 addr;             /* Pointer to mask array */
>>> +                __u32 range;            /* Requested range */
>>> +                __u32 reserved[13];
>>> +        };
>>> +
>>> +This ioctl copies the writable masks for Feature ID registers to userspace.
>>> +The Feature ID space is defined as the AArch64 System register space with
>>> +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}.
>> when attempting a migration between Ampere Altra and ThunderXv2 the
>> first hurdle is to handle a failure when writing ICC_CTLR_EL1
>> (3.0.12.12.4) on dest. This reg is outside of the scope of the above
>> single range (BIT(0)).
> 
> Indeed. But more importantly, this isn't really an ID register. Plenty
> of variable bits in there.
> 
>> This may be questionable if we want to migrate between those types of
>> machines but the goal is to exercise different scenarios to have a
>> gloval view of the problems.
> 
> I think this is a valuable experiment, and we should definitely
> explore this sort of things (as I cannot see the diversity of ARM
> system slowing down any time soon).
> 
>>
>> This reg exposes some RO capabilities such as ExtRange, A3V, SEIS,hyp/nvhe/hyp-main.c
>> IDBits, ...
>> So to get the migration going further I would need to tweek this on the
>> source - for instance I guess SEIS could be reset despite the host HW
>> cap - without making too much trouble.
> 
> I'm not sure SEIS is such an easy one: if you promised the guest that
> it would never get an SError doing the most stupid things (SEIS=0), it
> really shouldn't get one after migration. If you advertised it on the
> source HW (Altra), a migration to TX2 would be fine.
I see. Indeed for sure we must make sure KVM cannot inject SEIs in the
guest if SEIS is not advertised on guest side.

In this case SEIS is 0 on src Altra. On dst TX2 ich_vtr_el2 advertises
it and host seis =1 causing set_gic_ctlr to fail (vgic-sys-reg-v3.c).

> 
> The other bits are possible to change depending on the requirements of
> the VM (aff3, IDBits), and ExtRange should always be set to 0 (because
> our GIC implementation doesn't support EPPI/ESPI).
> 
> The really ugly part here is that if you want to affect these bits,
> you will need to trap and emulate the access. Not a big deal, but in
> the absence of FGT, you will need to handle the full Common trap
> group, which is going to slow things down (you will have to trap
> ICV_PMR_EL1, for example).
Would it be sensible to simplify things and only support the new range
if FGT is supported?
> 
>> What would you recommend, adding a new range? But I guess we need to
>> design ranges carefully otherwise we may be quickly limited by the
>> number of flag bits.
> 
> I can see a need to adding a range that would cover non-ID registers
> that have RO fields. But we also need to consider the case of EL2
> registers that take part in this.
Yes I need to better understand the consistency with ICH_VTR_EL2
> 
> For example, ICV_CTLR_EL1 and ICH_VTR_EL2 and deeply linked, and share
> some fields. Without NV, no need to expose HCR_VTR_EL2. With NV, this
> register actually drives ICV_CTLR_EL1.
understood.
> 
> So careful planning is required here, and the impact of this measured.

Understood. More time needed to study the code ;-)

Thanks!

Eric
> 
> Thanks,
> 
> 	M.
> 



From khilman at kernel.org  Wed Feb 14 10:10:17 2024
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 14 Feb 2024 10:10:17 -0800
Subject: [RESEND PATCH v1 05/13] mfd: tps6594-spi: Add TI TPS65224 PMIC SPI
In-Reply-To: <20240208105343.1212902-6-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
 <20240208105343.1212902-6-bhargav.r@ltts.com>
Message-ID: <7hcysy6ho6.fsf@baylibre.com>

Bhargav Raviprakash <bhargav.r at ltts.com> writes:

> Add support for TPS65224 PMIC in the TPS6594 driver as they share
> significant functional overlap.
>
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> ---
>  drivers/mfd/tps6594-spi.c | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
> index 5afb1736f..7ec66d31b 100644
> --- a/drivers/mfd/tps6594-spi.c
> +++ b/drivers/mfd/tps6594-spi.c
> @@ -1,6 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0
>  /*
> - * SPI access driver for TI TPS6594/TPS6593/LP8764 PMICs
> + * SPI access driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
>   *
>   * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
>   */
> @@ -66,7 +66,7 @@ static int tps6594_spi_reg_write(void *context, unsigned int reg, unsigned int v
>  	return spi_write(spi, buf, count);
>  }
>  
> -static const struct regmap_config tps6594_spi_regmap_config = {
> +static struct regmap_config tps6594_spi_regmap_config = {
>  	.reg_bits = 16,
>  	.val_bits = 8,
>  	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
> @@ -81,6 +81,7 @@ static const struct of_device_id tps6594_spi_of_match_table[] = {
>  	{ .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
>  	{ .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
>  	{ .compatible = "ti,lp8764-q1",  .data = (void *)LP8764,  },
> +	{ .compatible = "ti,tps65224-q1", .data = (void *)TPS65224, },
>  	{}
>  };
>  MODULE_DEVICE_TABLE(of, tps6594_spi_of_match_table);
> @@ -101,15 +102,18 @@ static int tps6594_spi_probe(struct spi_device *spi)
>  	tps->reg = spi_get_chipselect(spi, 0);
>  	tps->irq = spi->irq;
>  
> -	tps->regmap = devm_regmap_init(dev, NULL, spi, &tps6594_spi_regmap_config);
> -	if (IS_ERR(tps->regmap))
> -		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
> -
>  	match = of_match_device(tps6594_spi_of_match_table, dev);
>  	if (!match)
>  		return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n");
>  	tps->chip_id = (unsigned long)match->data;
>  
> +	if (tps->chip_id == TPS65224)
> +		tps6594_spi_regmap_config.volatile_table = &tps65224_volatile_table;

Similar to my comment on the i2c series, but to be more specific:

Rather than use the .data pointer in the of_match_table as simply a
chip_id, instead make that into a struct that can contain chip-specific
values/pointers etc, and then each compatible can have a custom struct
(if needed.)

This way, at probe/match time, all the chip-specific data is setup using
that struct, so that at runtime, there doesn't need to be any "if
(chip_id)" checking.

Kevin


From conor at kernel.org  Wed Feb 14 10:10:25 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 14 Feb 2024 18:10:25 +0000
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI
 TPS65224 PMIC
In-Reply-To: <7hfrxu6i0t.fsf@baylibre.com>
References: <20240209-blitz-fidgety-78469aa80d6d@spud>
 <20240214093106.86483-1-bhargav.r@ltts.com>
 <20240214-galley-dweller-1e9872229d80@spud>
 <7hil2r5556.fsf@baylibre.com>
 <20240214-depraved-unfunded-3f0b3d6bf3e2@spud>
 <7hfrxu6i0t.fsf@baylibre.com>
Message-ID: <20240214-canola-strongman-69b7fc90bd31@spud>

On Wed, Feb 14, 2024 at 10:02:42AM -0800, Kevin Hilman wrote:
> Sorry for the noise.

nw chief
-------------- 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/20240214/4699dcdf/attachment.sig>

From conor at kernel.org  Wed Feb 14 10:12:19 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 14 Feb 2024 18:12:19 +0000
Subject: [PATCH 0/4] Fix vendor strings on Rockchip boards
In-Reply-To: <e952d127-b12d-4b5a-838b-807a876db707@feathertop.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
 <c03220db663279c9e83bab81f3d829e7@manjaro.org>
 <e952d127-b12d-4b5a-838b-807a876db707@feathertop.org>
Message-ID: <20240214-moocher-womanless-21201b67b76d@spud>

On Wed, Feb 14, 2024 at 03:27:08PM +1100, Tim Lunn wrote:
> Hi Dragan,
> 
> On 2/14/24 15:14, Dragan Simic wrote:
> > Hello Tim,
> > 
> > On 2024-02-14 05:07, Tim Lunn wrote:
> > > A couple of rockchip boards incorrectly list their vendor as Rockchip
> > > when they are in fact not manufactured by Rockchip.
> > > 
> > > Fix the vendor strings to correctly list the manufacturer
> > 
> > Just checking, have you verified that the old, incorrect "compatible"
> > strings from the board dts files aren't used anywhere in the kernel code,
> > such as in some drivers?
> > 
> Yes I checked that, there are no remaining references to the old/incorrect
> compatible strings in kernel code

What about other code? Like a BSD or a bootloader? If nothing is using
them
Acked-by: Conor Dooley <conor.dooley at microchip.com>

Fixes tags I think wouldn't go amiss, but I'm not expecting a resend
with them.

Cheers,
Conor.
-------------- 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/20240214/f66988d9/attachment.sig>

From mark.rutland at arm.com  Wed Feb 14 10:14:51 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 14 Feb 2024 18:14:51 +0000
Subject: [PATCH v2] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM
 Neoverse N2 errata
In-Reply-To: <20240214175522.2457857-1-eahariha@linux.microsoft.com>
References: <20240214175522.2457857-1-eahariha@linux.microsoft.com>
Message-ID: <Zc0DEmbhgPMessV0@FVFF77S0Q05N>

On Wed, Feb 14, 2024 at 05:55:18PM +0000, Easwar Hariharan wrote:
> Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft
> implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore
> suffers from all the same errata.
> 
> CC: stable at vger.kernel.org # 5.15+
> Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

I assume that Catalin/Will will take this through the arm64 tree.

Mark.

> ---
> changelog:
> v1->v2:
> * v1: https://lore.kernel.org/linux-arm-kernel/20240212232909.2276378-1-eahariha at linux.microsoft.com/T/#u
> * Consistently use MICROSOFT throughout
> ---
>  Documentation/arch/arm64/silicon-errata.rst | 7 +++++++
>  arch/arm64/include/asm/cputype.h            | 4 ++++
>  arch/arm64/kernel/cpu_errata.c              | 3 +++
>  3 files changed, 14 insertions(+)
> 
> diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
> index e8c2ce1f9df6..45a7f4932fe0 100644
> --- a/Documentation/arch/arm64/silicon-errata.rst
> +++ b/Documentation/arch/arm64/silicon-errata.rst
> @@ -243,3 +243,10 @@ stable kernels.
>  +----------------+-----------------+-----------------+-----------------------------+
>  | ASR            | ASR8601         | #8601001        | N/A                         |
>  +----------------+-----------------+-----------------+-----------------------------+
> ++----------------+-----------------+-----------------+-----------------------------+
> +| Microsoft      | Azure Cobalt 100| #2139208        | ARM64_ERRATUM_2139208       |
> ++----------------+-----------------+-----------------+-----------------------------+
> +| Microsoft      | Azure Cobalt 100| #2067961        | ARM64_ERRATUM_2067961       |
> ++----------------+-----------------+-----------------+-----------------------------+
> +| Microsoft      | Azure Cobalt 100| #2253138        | ARM64_ERRATUM_2253138       |
> ++----------------+-----------------+-----------------+-----------------------------+
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 7c7493cb571f..52f076afeb96 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -61,6 +61,7 @@
>  #define ARM_CPU_IMP_HISI		0x48
>  #define ARM_CPU_IMP_APPLE		0x61
>  #define ARM_CPU_IMP_AMPERE		0xC0
> +#define ARM_CPU_IMP_MICROSOFT		0x6D
>  
>  #define ARM_CPU_PART_AEM_V8		0xD0F
>  #define ARM_CPU_PART_FOUNDATION		0xD00
> @@ -135,6 +136,8 @@
>  
>  #define AMPERE_CPU_PART_AMPERE1		0xAC3
>  
> +#define MICROSOFT_CPU_PART_AZURE_COBALT_100	0xD49 /* Based on r0p0 of ARM Neoverse N2 */
> +
>  #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
>  #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
>  #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
> @@ -193,6 +196,7 @@
>  #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)
>  #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
>  #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
> +#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100)
>  
>  /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
>  #define MIDR_FUJITSU_ERRATUM_010001		MIDR_FUJITSU_A64FX
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 967c7c7a4e7d..76b8dd37092a 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -374,6 +374,7 @@ static const struct midr_range erratum_1463225[] = {
>  static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
>  #ifdef CONFIG_ARM64_ERRATUM_2139208
>  	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> +	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_2119858
>  	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> @@ -387,6 +388,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
>  static const struct midr_range tsb_flush_fail_cpus[] = {
>  #ifdef CONFIG_ARM64_ERRATUM_2067961
>  	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> +	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_2054223
>  	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> @@ -399,6 +401,7 @@ static const struct midr_range tsb_flush_fail_cpus[] = {
>  static struct midr_range trbe_write_out_of_range_cpus[] = {
>  #ifdef CONFIG_ARM64_ERRATUM_2253138
>  	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> +	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_2224489
>  	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> -- 
> 2.34.1
> 


From jernej.skrabec at gmail.com  Wed Feb 14 10:16:19 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Wed, 14 Feb 2024 19:16:19 +0100
Subject: [PATCH v6 124/164] pwm: sun4i: Make use of pwmchip_parent() accessor
In-Reply-To: <3ddaec73f3abefb45625d0a469026fa8d13da8c0.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
 <3ddaec73f3abefb45625d0a469026fa8d13da8c0.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <2717935.mvXUDI8C0e@jernej-laptop>

Dne sreda, 14. februar 2024 ob 10:32:51 CET je Uwe Kleine-K?nig napisal(a):
> struct pwm_chip::dev is about to change. To not have to touch this
> driver in the same commit as struct pwm_chip::dev, use the accessor
> function provided for exactly this purpose.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From jernej.skrabec at gmail.com  Wed Feb 14 10:18:37 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Wed, 14 Feb 2024 19:18:37 +0100
Subject: [PATCH v6 125/164] pwm: sun4i: Prepare removing pwm_chip from driver data
In-Reply-To: <f8e3fb96fe341ba0a4bed982aa731c5c7c355b83.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
 <f8e3fb96fe341ba0a4bed982aa731c5c7c355b83.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <6016472.lOV4Wx5bFT@jernej-laptop>

Dne sreda, 14. februar 2024 ob 10:32:52 CET je Uwe Kleine-K?nig napisal(a):
> This prepares the driver for further changes that will drop struct
> pwm_chip chip from struct sun4i_pwm_chip. Use the pwm_chip as driver
> data instead of the sun4i_pwm_chip to get access to the pwm_chip in
> sun4i_pwm_remove() without using sun4ichip->chip.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From jernej.skrabec at gmail.com  Wed Feb 14 10:20:12 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Wed, 14 Feb 2024 19:20:12 +0100
Subject: [PATCH v6 126/164] pwm: sun4i: Consistently name driver data sun4ichip
In-Reply-To: <705f54a13b59fff50eaa345d8b1e0c691345b996.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
 <705f54a13b59fff50eaa345d8b1e0c691345b996.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <4544997.LvFx2qVVIh@jernej-laptop>

Dne sreda, 14. februar 2024 ob 10:32:53 CET je Uwe Kleine-K?nig napisal(a):
> The driver uses three different names for variables of type
> sun4i_pwm_chip:
> 
> 	$ git grep 'struct sun4i_pwm_chip \*' v6.8-rc1 -- drivers/pwm/pwm-sun4i.c
> 	v6.8-rc1:drivers/pwm/pwm-sun4i.c:static inline struct sun4i_pwm_chip *to_sun4i_pwm_chip(struct pwm_chip *chip)
> 	v6.8-rc1:drivers/pwm/pwm-sun4i.c:static inline u32 sun4i_pwm_readl(struct sun4i_pwm_chip *chip,
> 	v6.8-rc1:drivers/pwm/pwm-sun4i.c:static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
> 	v6.8-rc1:drivers/pwm/pwm-sun4i.c:       struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
> 	v6.8-rc1:drivers/pwm/pwm-sun4i.c:static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
> 	v6.8-rc1:drivers/pwm/pwm-sun4i.c:       struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
> 	v6.8-rc1:drivers/pwm/pwm-sun4i.c:       struct sun4i_pwm_chip *sun4ichip;
> 	v6.8-rc1:drivers/pwm/pwm-sun4i.c:       struct sun4i_pwm_chip *sun4ichip = platform_get_drvdata(pdev);
> 
> "chip" is usually reserved for variables of type struct pwm_chip. So
> pick sun4ichip as common name which better matches the type name than
> sun4i_pwm.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Acked-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From cristian.marussi at arm.com  Wed Feb 14 10:21:29 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 14 Feb 2024 18:21:29 +0000
Subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock
 .is_notify_supported callback
In-Reply-To: <fc28f615-eaaf-459a-96e2-fce104f77fe7@quicinc.com>
References: <20240212123233.1230090-7-cristian.marussi@arm.com>
 <202402131047.2NVZWHma-lkp@intel.com>
 <ZcstL8tRVKIUFoBr@pluto>
 <fc28f615-eaaf-459a-96e2-fce104f77fe7@quicinc.com>
Message-ID: <Zc0EqV69sg6Dqnti@pluto>

On Tue, Feb 13, 2024 at 10:24:48AM -0800, Nikunj Kela wrote:
> 
> On 2/13/2024 12:49 AM, Cristian Marussi wrote:
> > On Tue, Feb 13, 2024 at 10:58:23AM +0800, kernel test robot wrote:
> > > Hi Cristian,
> > > 
> > > kernel test robot noticed the following build errors:
> > > 
> > > [auto build test ERROR on soc/for-next]
> > > [also build test ERROR on linus/master v6.8-rc4 next-20240212]
> > > [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#_base_tree_information]
> > > 
> > Hi,
> > 
> > this series, as stated in the cover-letter, is based off the current tip of
> > 
> > 	sudeep/for-next/scmi/updates
> > 
> > and particularly needs commit:
> > 
> > 	9c5bc650031e firmware: arm_scmi: Rework clock domain info lookups
> > 
> > from there, since it contains the missing scmi_clock_domain_lookup().
> > 
> > Not_sure/dont_known if there is any way to convey this "based-on-branch"
> > info to your/any CI at the moment.
> > 
> > Thanks,
> > Cristian
> Maybe add supdeep's tree in MAINTAINERS and use 'base-commit'.

Thanks Nikunj, I'll try with base-commit.
Cristian

> > > url:    https://github.com/intel-lab-lkp/linux/commits/Cristian-Marussi/firmware-arm_scmi-Check-for-notification-support/20240212-203727
> > > base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
> > > patch link:    https://lore.kernel.org/r/20240212123233.1230090-7-cristian.marussi%40arm.com
> > > patch subject: [PATCH 06/11] firmware: arm_scmi: Implement Clock .is_notify_supported callback
> > > config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20240213/202402131047.2NVZWHma-lkp at intel.com/config)
> > > compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project c08b90c50bcac9f3f563c79491c8dbcbe7c3b574)
> > > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240213/202402131047.2NVZWHma-lkp at intel.com/reproduce)
> > > 
> > > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > > the same patch/commit), kindly add following tags
> > > | Reported-by: kernel test robot <lkp at intel.com>
> > > | Closes: https://lore.kernel.org/oe-kbuild-all/202402131047.2NVZWHma-lkp at intel.com/
> > > 
> > > All errors (new ones prefixed by >>):
> > > 
> > > > > drivers/firmware/arm_scmi/clock.c:853:8: error: call to undeclared function 'scmi_clock_domain_lookup'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
> > >       853 |         clk = scmi_clock_domain_lookup(ci, src_id);
> > >           |               ^
> > > > > drivers/firmware/arm_scmi/clock.c:853:6: error: incompatible integer to pointer conversion assigning to 'struct scmi_clock_info *' from 'int' [-Wint-conversion]
> > >       853 |         clk = scmi_clock_domain_lookup(ci, src_id);
> > >           |             ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > >     2 errors generated.
> > > 
> > > 
> > > vim +/scmi_clock_domain_lookup +853 drivers/firmware/arm_scmi/clock.c
> > > 
> > >     842	
> > >     843	static bool scmi_clk_notify_supported(const struct scmi_protocol_handle *ph,
> > >     844					      u8 evt_id, u32 src_id)
> > >     845	{
> > >     846		bool supported;
> > >     847		struct scmi_clock_info *clk;
> > >     848		struct clock_info *ci = ph->get_priv(ph);
> > >     849	
> > >     850		if (evt_id >= ARRAY_SIZE(evt_2_cmd))
> > >     851			return false;
> > >     852	
> > >   > 853		clk = scmi_clock_domain_lookup(ci, src_id);
> > >     854		if (IS_ERR(clk))
> > >     855			return false;
> > >     856	
> > >     857		if (evt_id == SCMI_EVENT_CLOCK_RATE_CHANGED)
> > >     858			supported = clk->rate_changed_notifications;
> > >     859		else
> > >     860			supported = clk->rate_change_requested_notifications;
> > >     861	
> > >     862		return supported;
> > >     863	}
> > >     864	
> > > 
> > > -- 
> > > 0-DAY CI Kernel Test Service
> > > https://github.com/intel/lkp-tests/wiki


From jernej.skrabec at gmail.com  Wed Feb 14 10:22:53 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Wed, 14 Feb 2024 19:22:53 +0100
Subject: [PATCH v6 127/164] pwm: sun4i: Make use of devm_pwmchip_alloc() function
In-Reply-To: <9d175b4e27878618cef2e75b6ecbf01ad5d18164.1707900770.git.u.kleine-koenig@pengutronix.de>
References: <cover.1707900770.git.u.kleine-koenig@pengutronix.de>
 <9d175b4e27878618cef2e75b6ecbf01ad5d18164.1707900770.git.u.kleine-koenig@pengutronix.de>
Message-ID: <4868529.GXAFRqVoOG@jernej-laptop>

Dne sreda, 14. februar 2024 ob 10:32:54 CET je Uwe Kleine-K?nig napisal(a):
> This prepares the pwm-sun4i driver to further changes of the pwm core
> outlined in the commit introducing devm_pwmchip_alloc(). There is no
> intended semantical change and the driver should behave as before.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From cristian.marussi at arm.com  Wed Feb 14 10:30:00 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 14 Feb 2024 18:30:00 +0000
Subject: [PATCH 1/7] firmware: arm_scmi: Add a common helper to check if a message is supported
In-Reply-To: <20240214183006.3403207-1-cristian.marussi@arm.com>
References: <20240214183006.3403207-1-cristian.marussi@arm.com>
Message-ID: <20240214183006.3403207-2-cristian.marussi@arm.com>

A common helper is provided to check if a specific protocol message is
supported or not.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c    | 34 +++++++++++++++++++++++++++
 drivers/firmware/arm_scmi/protocols.h |  4 ++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 3ea64b22cf0d..4a64ad5c21ee 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1754,10 +1754,44 @@ static void scmi_common_fastchannel_db_ring(struct scmi_fc_db_info *db)
 #endif
 }
 
+/**
+ * scmi_protocol_msg_check  - Check protocol message attributes
+ *
+ * @ph: A reference to the protocol handle.
+ * @message_id: The ID of the message to check.
+ * @attributes: A parameter to optionally return the retrieved message
+ *		attributes, in case of Success.
+ *
+ * An helper to check protocol message attributes for a specific protocol
+ * and message pair.
+ *
+ * Return: 0 on SUCCESS
+ */
+static int scmi_protocol_msg_check(const struct scmi_protocol_handle *ph,
+				   u32 message_id, u32 *attributes)
+{
+	int ret;
+	struct scmi_xfer *t;
+
+	ret = xfer_get_init(ph, PROTOCOL_MESSAGE_ATTRIBUTES,
+			    sizeof(__le32), 0, &t);
+	if (ret)
+		return ret;
+
+	put_unaligned_le32(message_id, t->tx.buf);
+	ret = do_xfer(ph, t);
+	if (!ret && attributes)
+		*attributes = get_unaligned_le32(t->rx.buf);
+	xfer_put(ph, t);
+
+	return ret;
+}
+
 static const struct scmi_proto_helpers_ops helpers_ops = {
 	.extended_name_get = scmi_common_extended_name_get,
 	.iter_response_init = scmi_iterator_init,
 	.iter_response_run = scmi_iterator_run,
+	.protocol_msg_check = scmi_protocol_msg_check,
 	.fastchannel_init = scmi_common_fastchannel_init,
 	.fastchannel_db_ring = scmi_common_fastchannel_db_ring,
 };
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index e683c26f24eb..26a3edd49fea 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -251,6 +251,8 @@ struct scmi_fc_info {
  *			provided in @ops.
  * @iter_response_run: A common helper to trigger the run of a previously
  *		       initialized iterator.
+ * @protocol_msg_check: A common helper to check is a specific protocol message
+ *			is supported.
  * @fastchannel_init: A common helper used to initialize FC descriptors by
  *		      gathering FC descriptions from the SCMI platform server.
  * @fastchannel_db_ring: A common helper to ring a FC doorbell.
@@ -264,6 +266,8 @@ struct scmi_proto_helpers_ops {
 				    unsigned int max_resources, u8 msg_id,
 				    size_t tx_size, void *priv);
 	int (*iter_response_run)(void *iter);
+	int (*protocol_msg_check)(const struct scmi_protocol_handle *ph,
+				  u32 message_id, u32 *attributes);
 	void (*fastchannel_init)(const struct scmi_protocol_handle *ph,
 				 u8 describe_id, u32 message_id,
 				 u32 valid_size, u32 domain,
-- 
2.43.0



From cristian.marussi at arm.com  Wed Feb 14 10:29:59 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 14 Feb 2024 18:29:59 +0000
Subject: [PATCH 0/7] SCMI V3.2 Misc updates
Message-ID: <20240214183006.3403207-1-cristian.marussi@arm.com>

Hi,

another round of updates related to the last v3.2 SCMI spec, mostly around
Clock protocol.

Note that the series is based on sudeep/for-next/scmi/updates on top of

  7dd3d11f4dac ("clk: scmi: Add support for forbidden clock state controls")

and patch [1/7], which was included in the recently posted [1], it is
included also here just for ease of usage. (since needed also here ofc)

Having said that, [2/7] add a centralized support to the SCMI core to
handle v3.2 optional protocol version negotiation, so that at protocol
initialization time, mif the platform advertised version is newer than
supported by the kernel and protocol version negotiation is supported,
the SCMI core will attempt to negotiate an older protocol version.

Patches 3,4,5 adds the remaining last missing bits of Clock v3.2 protocol
and bumps the supported protocol version to 0x30000 (v3.2).

On top of these new SCMI additions, [6/7] reworks at first slightly how the
clk-scmi driver configures per-clock CLK ops, and then [7/7] adds support
for clock get/set duty cycle, as allowed by the last v3.2 spec additions,
but only if the related SCMI clk domain supports that specific clock
permissions.

Thanks,
Cristian

[1]: https://lore.kernel.org/linux-arm-kernel/20240212123233.1230090-3-cristian.marussi at arm.com/
---

Cristian Marussi (7):
  firmware: arm_scmi: Add a common helper to check if a message is
    supported
  firmware: arm_scmi: Add support for v3.2 NEGOTIATE_PROTOCOL_VERSION
  firmware: arm_scmi: Add Clock check for extended config support
  firmware: arm_scmi: Add standard Clock OEM definitions
  firmware: arm_scmi: Update supported Clock protocol version
  clk: scmi: Allocate CLK operations dynamically
  clk: scmi: Support get/set duty_cycle operations

 drivers/clk/clk-scmi.c                | 168 +++++++++++++++++---------
 drivers/firmware/arm_scmi/clock.c     |  67 +++++++---
 drivers/firmware/arm_scmi/driver.c    |  99 ++++++++++++++-
 drivers/firmware/arm_scmi/protocols.h |   5 +
 include/linux/scmi_protocol.h         |  15 ++-
 5 files changed, 270 insertions(+), 84 deletions(-)

-- 
2.43.0



From cristian.marussi at arm.com  Wed Feb 14 10:30:01 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 14 Feb 2024 18:30:01 +0000
Subject: [PATCH 2/7] firmware: arm_scmi: Add support for v3.2 NEGOTIATE_PROTOCOL_VERSION
In-Reply-To: <20240214183006.3403207-1-cristian.marussi@arm.com>
References: <20240214183006.3403207-1-cristian.marussi@arm.com>
Message-ID: <20240214183006.3403207-3-cristian.marussi@arm.com>

Freshly introduced NEGOTIATE_PROTOCOL_VERSION allows the agent to ascertain
upfront if a specific, usually older, protocol version is supported by the
platform.

It is used by the agent in case the platform has advertised the support of
a newer protocol version than the latest version supported by the agent,
since backward compatibility cannot be automatically assumed.

Emit a warning about possible incompatibility when negotiation was not
possible or just print the successfully negotiated protocol.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c    | 65 ++++++++++++++++++++++++---
 drivers/firmware/arm_scmi/protocols.h |  1 +
 2 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 4a64ad5c21ee..34d77802c990 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -86,6 +86,12 @@ struct scmi_xfers_info {
  * @users: A refcount to track effective users of this protocol.
  * @priv: Reference for optional protocol private data.
  * @version: Protocol version supported by the platform as detected at runtime.
+ * @negotiated_version: When the platform supports a newer protocol version,
+ *			the agent will try to negotiate with the platform the
+ *			usage of the newest version known to it, since
+ *			backward compatibility is NOT automatically assured.
+ *			This field is NON-zero when a successful negotiation
+ *			has completed.
  * @ph: An embedded protocol handle that will be passed down to protocol
  *	initialization code to identify this instance.
  *
@@ -99,6 +105,7 @@ struct scmi_protocol_instance {
 	refcount_t			users;
 	void				*priv;
 	unsigned int			version;
+	unsigned int			negotiated_version;
 	struct scmi_protocol_handle	ph;
 };
 
@@ -1815,6 +1822,44 @@ scmi_revision_area_get(const struct scmi_protocol_handle *ph)
 	return pi->handle->version;
 }
 
+/**
+ * scmi_protocol_version_negotiate  - Negotiate protocol version
+ *
+ * @ph: A reference to the protocol handle.
+ *
+ * An helper to negotiate a protocol version different from the latest
+ * advertised as supported from the platform: on Success backward
+ * compatibility is assured by the platform.
+ *
+ * Return: 0 on Success
+ */
+static int scmi_protocol_version_negotiate(struct scmi_protocol_handle *ph)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_protocol_instance *pi = ph_to_pi(ph);
+
+	/* At first check if NEGOTIATE_PROTOCOL_VERSION is supported ... */
+	ret = scmi_protocol_msg_check(ph, NEGOTIATE_PROTOCOL_VERSION, NULL);
+	if (ret)
+		return ret;
+
+	/* ... then attempt protocol version negotiation */
+	ret = xfer_get_init(ph, NEGOTIATE_PROTOCOL_VERSION,
+			    sizeof(__le32), 0, &t);
+	if (ret)
+		return ret;
+
+	put_unaligned_le32(pi->proto->supported_version, t->tx.buf);
+	ret = do_xfer(ph, t);
+	if (!ret)
+		pi->negotiated_version = pi->proto->supported_version;
+
+	xfer_put(ph, t);
+
+	return ret;
+}
+
 /**
  * scmi_alloc_init_protocol_instance  - Allocate and initialize a protocol
  * instance descriptor.
@@ -1887,11 +1932,21 @@ scmi_alloc_init_protocol_instance(struct scmi_info *info,
 	devres_close_group(handle->dev, pi->gid);
 	dev_dbg(handle->dev, "Initialized protocol: 0x%X\n", pi->proto->id);
 
-	if (pi->version > proto->supported_version)
-		dev_warn(handle->dev,
-			 "Detected UNSUPPORTED higher version 0x%X for protocol 0x%X."
-			 "Backward compatibility is NOT assured.\n",
-			 pi->version, pi->proto->id);
+	if (pi->version > proto->supported_version) {
+		ret = scmi_protocol_version_negotiate(&pi->ph);
+		if (!ret) {
+			dev_info(handle->dev,
+				 "Protocol 0x%X successfully negotiated version 0x%X\n",
+				 proto->id, pi->negotiated_version);
+		} else {
+			dev_warn(handle->dev,
+				 "Detected UNSUPPORTED higher version 0x%X for protocol 0x%X.\n",
+				 pi->version, pi->proto->id);
+			dev_warn(handle->dev,
+				 "Trying version 0x%X. Backward compatibility is NOT assured.\n",
+				 pi->proto->supported_version);
+		}
+	}
 
 	return pi;
 
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index 26a3edd49fea..693019fff0f6 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -33,6 +33,7 @@ enum scmi_common_cmd {
 	PROTOCOL_VERSION = 0x0,
 	PROTOCOL_ATTRIBUTES = 0x1,
 	PROTOCOL_MESSAGE_ATTRIBUTES = 0x2,
+	NEGOTIATE_PROTOCOL_VERSION = 0x10,
 };
 
 /**
-- 
2.43.0



From cristian.marussi at arm.com  Wed Feb 14 10:30:02 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 14 Feb 2024 18:30:02 +0000
Subject: [PATCH 3/7] firmware: arm_scmi: Add Clock check for extended config support
In-Reply-To: <20240214183006.3403207-1-cristian.marussi@arm.com>
References: <20240214183006.3403207-1-cristian.marussi@arm.com>
Message-ID: <20240214183006.3403207-4-cristian.marussi@arm.com>

SCMI v3.2 added support to set/get Clock custom OEM types; such support is
conditionally present, though, depending on an extended config attribute
bit possibly advertised by the platform server on a per-domain base.

Add a check to verify if OEM types are supported before allowing any kind
of OEM-specific get/set operation and also a check around all Clock v3.2
features.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
base-commit: 7dd3d11f4dac301e958f00e18db4901a35cefc70
---
 drivers/firmware/arm_scmi/clock.c | 33 +++++++++++++++++++++++++------
 include/linux/scmi_protocol.h     |  1 +
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 959e48aba1b5..9d80ad95b467 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -54,6 +54,7 @@ struct scmi_msg_resp_clock_attributes {
 #define SUPPORTS_RATE_CHANGE_REQUESTED_NOTIF(x)	((x) & BIT(30))
 #define SUPPORTS_EXTENDED_NAMES(x)		((x) & BIT(29))
 #define SUPPORTS_PARENT_CLOCK(x)		((x) & BIT(28))
+#define SUPPORTS_EXTENDED_CONFIG(x)		((x) & BIT(27))
 #define SUPPORTS_GET_PERMISSIONS(x)		((x) & BIT(1))
 	u8 name[SCMI_SHORT_NAME_MAX_SIZE];
 	__le32 clock_enable_latency;
@@ -372,10 +373,14 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph,
 			clk->rate_changed_notifications = true;
 		if (SUPPORTS_RATE_CHANGE_REQUESTED_NOTIF(attributes))
 			clk->rate_change_requested_notifications = true;
-		if (SUPPORTS_PARENT_CLOCK(attributes))
-			scmi_clock_possible_parents(ph, clk_id, clk);
-		if (SUPPORTS_GET_PERMISSIONS(attributes))
-			scmi_clock_get_permissions(ph, clk_id, clk);
+		if (PROTOCOL_REV_MAJOR(version) >= 0x3) {
+			if (SUPPORTS_PARENT_CLOCK(attributes))
+				scmi_clock_possible_parents(ph, clk_id, clk);
+			if (SUPPORTS_GET_PERMISSIONS(attributes))
+				scmi_clock_get_permissions(ph, clk_id, clk);
+			if (SUPPORTS_EXTENDED_CONFIG(attributes))
+				clk->extended_config = true;
+		}
 	}
 
 	return ret;
@@ -684,7 +689,7 @@ scmi_clock_get_parent(const struct scmi_protocol_handle *ph, u32 clk_id,
 	return ret;
 }
 
-/* For SCMI clock v2.1 and onwards */
+/* For SCMI clock v3.0 and onwards */
 static int
 scmi_clock_config_set_v2(const struct scmi_protocol_handle *ph, u32 clk_id,
 			 enum clk_state state, u8 oem_type, u32 oem_val,
@@ -757,7 +762,7 @@ static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id,
 				    NULL_OEM_TYPE, 0, atomic);
 }
 
-/* For SCMI clock v2.1 and onwards */
+/* For SCMI clock v3.0 and onwards */
 static int
 scmi_clock_config_get_v2(const struct scmi_protocol_handle *ph, u32 clk_id,
 			 u8 oem_type, u32 *attributes, bool *enabled,
@@ -844,6 +849,14 @@ static int scmi_clock_config_oem_set(const struct scmi_protocol_handle *ph,
 				     bool atomic)
 {
 	struct clock_info *ci = ph->get_priv(ph);
+	struct scmi_clock_info *clk;
+
+	clk = scmi_clock_domain_lookup(ci, clk_id);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	if (!clk->extended_config)
+		return -EOPNOTSUPP;
 
 	return ci->clock_config_set(ph, clk_id, CLK_STATE_UNCHANGED,
 				    oem_type, oem_val, atomic);
@@ -854,6 +867,14 @@ static int scmi_clock_config_oem_get(const struct scmi_protocol_handle *ph,
 				     u32 *attributes, bool atomic)
 {
 	struct clock_info *ci = ph->get_priv(ph);
+	struct scmi_clock_info *clk;
+
+	clk = scmi_clock_domain_lookup(ci, clk_id);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	if (!clk->extended_config)
+		return -EOPNOTSUPP;
 
 	return ci->clock_config_get(ph, clk_id, oem_type, attributes,
 				    NULL, oem_val, atomic);
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 0cc40af5519a..caeca3f51be2 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -50,6 +50,7 @@ struct scmi_clock_info {
 	bool state_ctrl_forbidden;
 	bool rate_ctrl_forbidden;
 	bool parent_ctrl_forbidden;
+	bool extended_config;
 	union {
 		struct {
 			int num_rates;
-- 
2.43.0



From cristian.marussi at arm.com  Wed Feb 14 10:30:03 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 14 Feb 2024 18:30:03 +0000
Subject: [PATCH 4/7] firmware: arm_scmi: Add standard Clock OEM definitions
In-Reply-To: <20240214183006.3403207-1-cristian.marussi@arm.com>
References: <20240214183006.3403207-1-cristian.marussi@arm.com>
Message-ID: <20240214183006.3403207-5-cristian.marussi@arm.com>

Add a common enum to define the standard Clock OEM types defined by the
SCMI specification, so as to enable the configuration of such extended
configuration properties with the existent clock protocol operations.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/clock.c | 32 ++++++++++++++++++-------------
 include/linux/scmi_protocol.h     | 14 +++++++++++---
 2 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 9d80ad95b467..4e7f072142b9 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -163,10 +163,12 @@ struct clock_info {
 	struct scmi_clock_info *clk;
 	int (*clock_config_set)(const struct scmi_protocol_handle *ph,
 				u32 clk_id, enum clk_state state,
-				u8 oem_type, u32 oem_val, bool atomic);
+				enum scmi_clock_oem_config oem_type,
+				u32 oem_val, bool atomic);
 	int (*clock_config_get)(const struct scmi_protocol_handle *ph,
-				u32 clk_id, u8 oem_type, u32 *attributes,
-				bool *enabled, u32 *oem_val, bool atomic);
+				u32 clk_id, enum scmi_clock_oem_config oem_type,
+				u32 *attributes, bool *enabled, u32 *oem_val,
+				bool atomic);
 };
 
 static enum scmi_clock_protocol_cmd evt_2_cmd[] = {
@@ -602,7 +604,8 @@ 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,
-		      enum clk_state state, u8 __unused0, u32 __unused1,
+		      enum clk_state state,
+		      enum scmi_clock_oem_config __unused0, u32 __unused1,
 		      bool atomic)
 {
 	int ret;
@@ -692,7 +695,8 @@ scmi_clock_get_parent(const struct scmi_protocol_handle *ph, u32 clk_id,
 /* For SCMI clock v3.0 and onwards */
 static int
 scmi_clock_config_set_v2(const struct scmi_protocol_handle *ph, u32 clk_id,
-			 enum clk_state state, u8 oem_type, u32 oem_val,
+			 enum clk_state state,
+			 enum scmi_clock_oem_config oem_type, u32 oem_val,
 			 bool atomic)
 {
 	int ret;
@@ -765,8 +769,8 @@ static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id,
 /* For SCMI clock v3.0 and onwards */
 static int
 scmi_clock_config_get_v2(const struct scmi_protocol_handle *ph, u32 clk_id,
-			 u8 oem_type, u32 *attributes, bool *enabled,
-			 u32 *oem_val, bool atomic)
+			 enum scmi_clock_oem_config oem_type, u32 *attributes,
+			 bool *enabled, u32 *oem_val, bool atomic)
 {
 	int ret;
 	u32 flags;
@@ -807,8 +811,8 @@ scmi_clock_config_get_v2(const struct scmi_protocol_handle *ph, u32 clk_id,
 
 static int
 scmi_clock_config_get(const struct scmi_protocol_handle *ph, u32 clk_id,
-		      u8 oem_type, u32 *attributes, bool *enabled,
-		      u32 *oem_val, bool atomic)
+		      enum scmi_clock_oem_config oem_type, u32 *attributes,
+		      bool *enabled, u32 *oem_val, bool atomic)
 {
 	int ret;
 	struct scmi_xfer *t;
@@ -845,8 +849,9 @@ static int scmi_clock_state_get(const struct scmi_protocol_handle *ph,
 }
 
 static int scmi_clock_config_oem_set(const struct scmi_protocol_handle *ph,
-				     u32 clk_id, u8 oem_type, u32 oem_val,
-				     bool atomic)
+				     u32 clk_id,
+				     enum scmi_clock_oem_config oem_type,
+				     u32 oem_val, bool atomic)
 {
 	struct clock_info *ci = ph->get_priv(ph);
 	struct scmi_clock_info *clk;
@@ -863,8 +868,9 @@ static int scmi_clock_config_oem_set(const struct scmi_protocol_handle *ph,
 }
 
 static int scmi_clock_config_oem_get(const struct scmi_protocol_handle *ph,
-				     u32 clk_id, u8 oem_type, u32 *oem_val,
-				     u32 *attributes, bool atomic)
+				     u32 clk_id,
+				     enum scmi_clock_oem_config oem_type,
+				     u32 *oem_val, u32 *attributes, bool atomic)
 {
 	struct clock_info *ci = ph->get_priv(ph);
 	struct scmi_clock_info *clk;
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index caeca3f51be2..24e8de581744 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -76,6 +76,13 @@ struct scmi_handle;
 struct scmi_device;
 struct scmi_protocol_handle;
 
+enum scmi_clock_oem_config {
+	SCMI_CLOCK_CFG_DUTY_CYCLE = 0x1,
+	SCMI_CLOCK_CFG_PHASE,
+	SCMI_CLOCK_CFG_OEM_START = 0x80,
+	SCMI_CLOCK_CFG_OEM_END = 0xFF,
+};
+
 /**
  * struct scmi_clk_proto_ops - represents the various operations provided
  *	by SCMI Clock Protocol
@@ -108,10 +115,11 @@ struct scmi_clk_proto_ops {
 	int (*state_get)(const struct scmi_protocol_handle *ph, u32 clk_id,
 			 bool *enabled, bool atomic);
 	int (*config_oem_get)(const struct scmi_protocol_handle *ph, u32 clk_id,
-			      u8 oem_type, u32 *oem_val, u32 *attributes,
-			      bool atomic);
+			      enum scmi_clock_oem_config oem_type,
+			      u32 *oem_val, u32 *attributes, bool atomic);
 	int (*config_oem_set)(const struct scmi_protocol_handle *ph, u32 clk_id,
-			      u8 oem_type, u32 oem_val, bool atomic);
+			      enum scmi_clock_oem_config oem_type,
+			      u32 oem_val, bool atomic);
 	int (*parent_get)(const struct scmi_protocol_handle *ph, u32 clk_id, u32 *parent_id);
 	int (*parent_set)(const struct scmi_protocol_handle *ph, u32 clk_id, u32 parent_id);
 };
-- 
2.43.0



From cristian.marussi at arm.com  Wed Feb 14 10:30:04 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 14 Feb 2024 18:30:04 +0000
Subject: [PATCH 5/7] firmware: arm_scmi: Update supported Clock protocol version
In-Reply-To: <20240214183006.3403207-1-cristian.marussi@arm.com>
References: <20240214183006.3403207-1-cristian.marussi@arm.com>
Message-ID: <20240214183006.3403207-6-cristian.marussi@arm.com>

Update supported Clock protocol version to v3.2 (0x30000)

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/clock.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 4e7f072142b9..ca1729fd42cf 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -13,7 +13,7 @@
 #include "notify.h"
 
 /* Updated only after ALL the mandatory features for that version are merged */
-#define SCMI_PROTOCOL_SUPPORTED_VERSION		0x20000
+#define SCMI_PROTOCOL_SUPPORTED_VERSION		0x30000
 
 enum scmi_clock_protocol_cmd {
 	CLOCK_ATTRIBUTES = 0x3,
-- 
2.43.0



From cristian.marussi at arm.com  Wed Feb 14 10:30:05 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 14 Feb 2024 18:30:05 +0000
Subject: [PATCH 6/7] clk: scmi: Allocate CLK operations dynamically
In-Reply-To: <20240214183006.3403207-1-cristian.marussi@arm.com>
References: <20240214183006.3403207-1-cristian.marussi@arm.com>
Message-ID: <20240214183006.3403207-7-cristian.marussi@arm.com>

SCMI Clocks descriptors expose and increasing number of properties that in
turn lead to a different set of supported CLK operations to be associated
dynamically with a clock.

Providing statically pre-defined CLK operations structs for all the
possible combinations of allowed properties is cumbersome and error-prone.

Allocate per-clock operations descriptor dynamically and populate it with
the strictly needed set of operations depending on the advertised clock
properties.

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>
---
 drivers/clk/clk-scmi.c | 129 ++++++++++++++++++++++-------------------
 1 file changed, 70 insertions(+), 59 deletions(-)

diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index 5747b6d651f0..b91a0dbd2fe0 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -158,51 +158,6 @@ static int scmi_clk_atomic_is_enabled(struct clk_hw *hw)
 	return !!enabled;
 }
 
-/*
- * We can provide enable/disable/is_enabled 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,
-	.prepare = scmi_clk_enable,
-	.unprepare = scmi_clk_disable,
-	.set_parent = scmi_clk_set_parent,
-	.get_parent = scmi_clk_get_parent,
-	.determine_rate = scmi_clk_determine_rate,
-};
-
-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,
-	.is_enabled = scmi_clk_atomic_is_enabled,
-	.set_parent = scmi_clk_set_parent,
-	.get_parent = scmi_clk_get_parent,
-	.determine_rate = scmi_clk_determine_rate,
-};
-
-static const struct clk_ops scmi_no_state_ctrl_clk_ops = {
-	.recalc_rate = scmi_clk_recalc_rate,
-	.round_rate = scmi_clk_round_rate,
-	.set_rate = scmi_clk_set_rate,
-	.set_parent = scmi_clk_set_parent,
-	.get_parent = scmi_clk_get_parent,
-	.determine_rate = scmi_clk_determine_rate,
-};
-
 static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
 			     const struct clk_ops *scmi_ops)
 {
@@ -239,6 +194,71 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
 	return ret;
 }
 
+/**
+ * scmi_clk_ops_alloc() - Alloc and configure CLK ops
+ * @sclk: A reference to an SCMI clock descriptor
+ * @atomic_capable: A flag to indicate if atomic mode is supported by the
+ *		    transport
+ * @atomic_threshold: Platform atomic threshold value
+ *
+ * Allocate and configure a proper set of CLK operations depending on the
+ * specific SCMI clock characteristics and platform atomic operation capability.
+ *
+ * We can provide enable/disable/is_enabled 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.
+ *
+ * Return: A pointer to the allocated and configured clk_ops on Success,
+ *	   NULL otherwise.
+ */
+static const struct clk_ops *
+scmi_clk_ops_alloc(struct scmi_clk *sclk, bool atomic_capable,
+		   unsigned int atomic_threshold)
+{
+	const struct scmi_clock_info *ci = sclk->info;
+	struct clk_ops *ops;
+
+	ops = devm_kzalloc(sclk->dev, sizeof(*ops), GFP_KERNEL);
+	if (!ops)
+		return NULL;
+
+	/*
+	 * 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 (!ci->state_ctrl_forbidden) {
+		if (atomic_capable && ci->enable_latency <= atomic_threshold) {
+			ops->enable = scmi_clk_atomic_enable;
+			ops->disable = scmi_clk_atomic_disable;
+		} else {
+			ops->prepare = scmi_clk_enable;
+			ops->unprepare = scmi_clk_disable;
+		}
+	}
+
+	if (atomic_capable)
+		ops->is_enabled = scmi_clk_atomic_is_enabled;
+
+	/* Rate ops */
+	ops->recalc_rate = scmi_clk_recalc_rate;
+	ops->round_rate = scmi_clk_round_rate;
+	ops->determine_rate = scmi_clk_determine_rate;
+	if (!ci->rate_ctrl_forbidden)
+		ops->set_rate = scmi_clk_set_rate;
+
+	/* Parent ops */
+	ops->get_parent = scmi_clk_get_parent;
+	if (!ci->parent_ctrl_forbidden)
+		ops->set_parent = scmi_clk_set_parent;
+
+	return ops;
+}
+
 static int scmi_clocks_probe(struct scmi_device *sdev)
 {
 	int idx, count, err;
@@ -294,18 +314,9 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
 		sclk->ph = ph;
 		sclk->dev = dev;
 
-		/*
-		 * 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 (sclk->info->state_ctrl_forbidden)
-			scmi_ops = &scmi_no_state_ctrl_clk_ops;
-		else if (is_atomic &&
-			 sclk->info->enable_latency <= atomic_threshold)
-			scmi_ops = &scmi_atomic_clk_ops;
-		else
-			scmi_ops = &scmi_clk_ops;
+		scmi_ops = scmi_clk_ops_alloc(sclk, is_atomic, atomic_threshold);
+		if (!scmi_ops)
+			return -ENOMEM;
 
 		/* Initialize clock parent data. */
 		if (sclk->info->num_parents > 0) {
@@ -324,13 +335,13 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
 		if (err) {
 			dev_err(dev, "failed to register clock %d\n", idx);
 			devm_kfree(dev, sclk->parent_data);
+			devm_kfree(dev, scmi_ops);
 			devm_kfree(dev, sclk);
 			hws[idx] = NULL;
 		} else {
 			dev_dbg(dev, "Registered clock:%s%s\n",
 				sclk->info->name,
-				scmi_ops == &scmi_atomic_clk_ops ?
-				" (atomic ops)" : "");
+				scmi_ops->enable ? " (atomic ops)" : "");
 			hws[idx] = &sclk->hw;
 		}
 	}
-- 
2.43.0



From cristian.marussi at arm.com  Wed Feb 14 10:30:06 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 14 Feb 2024 18:30:06 +0000
Subject: [PATCH 7/7] clk: scmi: Support get/set duty_cycle operations
In-Reply-To: <20240214183006.3403207-1-cristian.marussi@arm.com>
References: <20240214183006.3403207-1-cristian.marussi@arm.com>
Message-ID: <20240214183006.3403207-8-cristian.marussi@arm.com>

Provide the CLK framework callbacks related to get/set clock duty cycle if
the relared SCMI clock supports OEM extended configurations.

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>
---
 drivers/clk/clk-scmi.c | 45 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index b91a0dbd2fe0..9d3b1e749226 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -158,6 +158,45 @@ static int scmi_clk_atomic_is_enabled(struct clk_hw *hw)
 	return !!enabled;
 }
 
+static int scmi_clk_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
+{
+	int ret;
+	u32 val;
+	struct scmi_clk *clk = to_scmi_clk(hw);
+
+	ret = scmi_proto_clk_ops->config_oem_get(clk->ph, clk->id,
+						 SCMI_CLOCK_CFG_DUTY_CYCLE,
+						 &val, NULL, false);
+	if (!ret) {
+		duty->num = val;
+		duty->den = 100;
+	} else {
+		dev_warn(clk->dev,
+			 "Failed to get duty cycle for clock ID %d\n", clk->id);
+	}
+
+	return ret;
+}
+
+static int scmi_clk_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
+{
+	int ret;
+	u32 val;
+	struct scmi_clk *clk = to_scmi_clk(hw);
+
+	/* SCMI OEM Duty Cycle is expressed as a percentage */
+	val = (duty->num * 100) / duty->den;
+	ret = scmi_proto_clk_ops->config_oem_set(clk->ph, clk->id,
+						 SCMI_CLOCK_CFG_DUTY_CYCLE,
+						 val, false);
+	if (ret)
+		dev_warn(clk->dev,
+			 "Failed to set duty cycle(%u/%u) for clock ID %d\n",
+			 duty->num, duty->den, clk->id);
+
+	return ret;
+}
+
 static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
 			     const struct clk_ops *scmi_ops)
 {
@@ -256,6 +295,12 @@ scmi_clk_ops_alloc(struct scmi_clk *sclk, bool atomic_capable,
 	if (!ci->parent_ctrl_forbidden)
 		ops->set_parent = scmi_clk_set_parent;
 
+	/* Duty cycle */
+	if (ci->extended_config) {
+		ops->get_duty_cycle = scmi_clk_get_duty_cycle;
+		ops->set_duty_cycle = scmi_clk_set_duty_cycle;
+	}
+
 	return ops;
 }
 
-- 
2.43.0



From dsimic at manjaro.org  Wed Feb 14 10:30:44 2024
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 14 Feb 2024 19:30:44 +0100
Subject: [PATCH 0/4] Fix vendor strings on Rockchip boards
In-Reply-To: <20240214-moocher-womanless-21201b67b76d@spud>
References: <20240214040731.3069111-1-tim@feathertop.org>
 <c03220db663279c9e83bab81f3d829e7@manjaro.org>
 <e952d127-b12d-4b5a-838b-807a876db707@feathertop.org>
 <20240214-moocher-womanless-21201b67b76d@spud>
Message-ID: <d9a17e535f8e414f91fe06b2b71849f9@manjaro.org>

Hello Conor,

On 2024-02-14 19:12, Conor Dooley wrote:
> On Wed, Feb 14, 2024 at 03:27:08PM +1100, Tim Lunn wrote:
>> On 2/14/24 15:14, Dragan Simic wrote:
>> > On 2024-02-14 05:07, Tim Lunn wrote:
>> > > A couple of rockchip boards incorrectly list their vendor as Rockchip
>> > > when they are in fact not manufactured by Rockchip.
>> > >
>> > > Fix the vendor strings to correctly list the manufacturer
>> >
>> > Just checking, have you verified that the old, incorrect "compatible"
>> > strings from the board dts files aren't used anywhere in the kernel code,
>> > such as in some drivers?
>> >
>> Yes I checked that, there are no remaining references to the 
>> old/incorrect
>> compatible strings in kernel code
> 
> What about other code? Like a BSD or a bootloader? If nothing is using
> them
> Acked-by: Conor Dooley <conor.dooley at microchip.com>

I just quickly checked U-Boot and it's fine.

> Fixes tags I think wouldn't go amiss, but I'm not expecting a resend
> with them.


From conor at kernel.org  Wed Feb 14 10:31:01 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 14 Feb 2024 18:31:01 +0000
Subject: =?utf-8?B?5Zue6KaG?= =?utf-8?Q?=3A?= [PATCH] Add eSPI device
 driver (flash channel)
In-Reply-To: <KL1PR06MB665234A65DB334B3BDF6AFA6914E2@KL1PR06MB6652.apcprd06.prod.outlook.com>
References: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
 <KL1PR06MB665234A65DB334B3BDF6AFA6914E2@KL1PR06MB6652.apcprd06.prod.outlook.com>
Message-ID: <20240214-yoyo-platinum-dcd0e7e16a22@spud>

On Wed, Feb 14, 2024 at 11:34:31AM +0000, ChiaWei Wang wrote:
> We appreciate that you are willing to help on the open source contribution. 
> However, please co-work with Aspeed before submitting drivers of Aspeed HW.
> Otherwise, a misleading driver on the community are going to bring tons of customer issues to Aspeed.

It may not apply in this particular case as Aspeed did write the
original driver and it is polite to work with previous authors
when respinning a patchset, but in general there is no need to work
with a hardware vendor before writing drivers for their hardware.

Blocking a driver because that company might receive more support
requests is not the kernel's problem.

Cheers,
Conor.

-------------- 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/20240214/b0863e96/attachment.sig>

From jgg at nvidia.com  Wed Feb 14 11:09:54 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Wed, 14 Feb 2024 15:09:54 -0400
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240214170030.GB31927@willie-the-truck>
References: <0-v1-210234560de7+69a-smmu_cd_atomic_jgg@nvidia.com>
 <20240208125846.GA23290@willie-the-truck>
 <20240208142729.GH10476@nvidia.com>
 <20240213112015.GB28517@willie-the-truck>
 <20240213121850.GH4048826@nvidia.com>
 <20240213125456.GA28844@willie-the-truck>
 <20240213133045.GA989297@nvidia.com>
 <20240213135627.GD28926@willie-the-truck>
 <20240213140033.GB989297@nvidia.com>
 <20240214170030.GB31927@willie-the-truck>
Message-ID: <20240214190954.GI1088888@nvidia.com>

On Wed, Feb 14, 2024 at 05:00:30PM +0000, Will Deacon wrote:

> 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 0ffb1cf17e0b..e48f2b46f25e 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1019,7 +1019,10 @@ static void arm_smmu_write_cd_l1_desc(__le64 *dst,
>  	WRITE_ONCE(*dst, cpu_to_le64(val));
>  }
>  
> -static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
> +static __le64 *
> +__arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid,
> +		      int (*cd_alloc)(struct arm_smmu_device *,
> +				      struct arm_smmu_l1_ctx_desc *))
>  {
>  	__le64 *l1ptr;
>  	unsigned int idx;
> @@ -1033,7 +1036,7 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
>  	idx = ssid >> CTXDESC_SPLIT;
>  	l1_desc = &cd_table->l1_desc[idx];
>  	if (!l1_desc->l2ptr) {
> -		if (arm_smmu_alloc_cd_leaf_table(smmu, l1_desc))
> +		if (!cd_alloc || cd_alloc(smmu, l1_desc))
>  			return NULL;
>  
>  		l1ptr = cd_table->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
> @@ -1045,6 +1048,19 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
>  	return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS;
>  }
>  
> +static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
> +{
> +	return __arm_smmu_get_cd_ptr(master, ssid, NULL);
> +}

I think this will break arm_smmu_write_ctx_desc() which requires
allocation behavior to install the SSID0 in a two level table?

> +int arm_smmu_init_cd_table(struct arm_smmu_master *master, int ssid)
> +{
> +	if (!__arm_smmu_get_cd_ptr(master, ssid, arm_smmu_alloc_cd_leaf_table))
> +		return -ENOMEM;
> +
> +	return 0;
> +}

And this does not compose well with the rest of where we are going. At
the end there are 7 calls to arm_smmu_get_cd_ptr(), all need
allocation except for two (clear and mmu notifier release)

Better to add a noalloc version. Also 'bool noalloc' would be clearer
than a function pointer without obfuscating the control flow.

Also I don't think this should go to -rc, it is not fixing any
bug. The preallocation is enough. Making more clarity for this
confused code is a nice to have at best.

How about this instead as a -next patch:

--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -288,10 +288,11 @@ static const struct mmu_notifier_ops arm_smmu_mmu_notifier_ops = {
 
 /* Allocate or get existing MMU notifier for this {domain, mm} pair */
 static struct arm_smmu_mmu_notifier *
-arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
+arm_smmu_mmu_notifier_get(struct arm_smmu_master *true_master,
+                         struct arm_smmu_domain *smmu_domain,
                          struct mm_struct *mm)
 {
-       int ret;
+       int ret = 0;
        unsigned long flags;
        struct arm_smmu_ctx_desc *cd;
        struct arm_smmu_mmu_notifier *smmu_mn;
@@ -327,8 +328,15 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
 
        spin_lock_irqsave(&smmu_domain->devices_lock, flags);
        list_for_each_entry(master, &smmu_domain->devices, domain_head) {
-               ret = arm_smmu_write_ctx_desc(master, mm_get_enqcmd_pasid(mm),
-                                             cd);
+               /*
+                * A limitation of the current SVA code requires the RID
+                * smmu_domain to be unique to the actual master.
+                */
+               if (WARN_ON(master != true_master))
+                       ret = -EINVAL;
+               if (!ret)
+                       ret = arm_smmu_write_ctx_desc(
+                               master, mm_get_enqcmd_pasid(mm), cd);
                if (ret) {
                        list_for_each_entry_from_reverse(
                                master, &smmu_domain->devices, domain_head)
@@ -398,7 +406,7 @@ static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
 
        bond->mm = mm;
 
-       bond->smmu_mn = arm_smmu_mmu_notifier_get(smmu_domain, mm);
+       bond->smmu_mn = arm_smmu_mmu_notifier_get(master, smmu_domain, mm);
        if (IS_ERR(bond->smmu_mn)) {
                ret = PTR_ERR(bond->smmu_mn);
                goto err_free_bond;

Thanks,
Jason


From helgaas at kernel.org  Wed Feb 14 11:12:49 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 14 Feb 2024 13:12:49 -0600
Subject: [PATCH V16 13/13] PCI: tegra: Add Tegra194 PCIe support
In-Reply-To: <20190813113627.27251-14-vidyas@nvidia.com>
Message-ID: <20240214191249.GA1263222@bhelgaas>

Hi Vidya, question about ancient history:

On Tue, Aug 13, 2019 at 05:06:27PM +0530, Vidya Sagar wrote:
> Add support for Synopsys DesignWare core IP based PCIe host controller
> present in Tegra194 SoC.
> ...

> +static int tegra_pcie_dw_host_init(struct pcie_port *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
> +	u32 val, tmp, offset, speed;
> +
> +	tegra_pcie_prepare_host(pp);
> +
> +	if (dw_pcie_wait_for_link(pci)) {
> +		/*
> +		 * There are some endpoints which can't get the link up if
> +		 * root port has Data Link Feature (DLF) enabled.
> +		 * Refer Spec rev 4.0 ver 1.0 sec 3.4.2 & 7.7.4 for more info
> +		 * on Scaled Flow Control and DLF.
> +		 * So, need to confirm that is indeed the case here and attempt
> +		 * link up once again with DLF disabled.

This comment suggests that there's an issue with *Endpoints*, not an
issue with the Root Port.  If so, it seems like this problem could
occur with all Root Ports, not just Tegra194.  Do you remember any
details about this?

I don't remember hearing about any similar issues, and this driver is
the only place PCI_EXT_CAP_ID_DLF is referenced, so maybe it is
actually something related to Tegra194?

> +		val = appl_readl(pcie, APPL_DEBUG);
> +		val &= APPL_DEBUG_LTSSM_STATE_MASK;
> +		val >>= APPL_DEBUG_LTSSM_STATE_SHIFT;
> +		tmp = appl_readl(pcie, APPL_LINK_STATUS);
> +		tmp &= APPL_LINK_STATUS_RDLH_LINK_UP;
> +		if (!(val == 0x11 && !tmp)) {
> +			/* Link is down for all good reasons */
> +			return 0;
> +		}
> +
> +		dev_info(pci->dev, "Link is down in DLL");
> +		dev_info(pci->dev, "Trying again with DLFE disabled\n");
> +		/* Disable LTSSM */
> +		val = appl_readl(pcie, APPL_CTRL);
> +		val &= ~APPL_CTRL_LTSSM_EN;
> +		appl_writel(pcie, val, APPL_CTRL);
> +
> +		reset_control_assert(pcie->core_rst);
> +		reset_control_deassert(pcie->core_rst);
> +
> +		offset = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_DLF);
> +		val = dw_pcie_readl_dbi(pci, offset + PCI_DLF_CAP);
> +		val &= ~PCI_DLF_EXCHANGE_ENABLE;
> +		dw_pcie_writel_dbi(pci, offset, val);
> +
> +		tegra_pcie_prepare_host(pp);
> +
> +		if (dw_pcie_wait_for_link(pci))
> +			return 0;
> +	}
> +
> +	speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) &
> +		PCI_EXP_LNKSTA_CLS;
> +	clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]);
> +
> +	tegra_pcie_enable_interrupts(pp);
> +
> +	return 0;
> +}


From Ben.Gainey at arm.com  Wed Feb 14 11:13:50 2024
From: Ben.Gainey at arm.com (Ben Gainey)
Date: Wed, 14 Feb 2024 19:13:50 +0000
Subject: [RFC PATCH 0/2] A mechanism for efficient support for
 per-function metrics
In-Reply-To: <87r0hfwet0.fsf@linux.intel.com>
References: <20240123113420.1928154-1-ben.gainey@arm.com>
	 <87r0hfwet0.fsf@linux.intel.com>
Message-ID: <7de25cbdc9df21e1723d209ca8bd377a55bb54e4.camel@arm.com>

Hi Andi

Thanks for commenting...

On Wed, 2024-02-14 at 01:55 -0800, Andi Kleen wrote:
> Ben Gainey <ben.gainey at arm.com> writes:
> 
> > I've been working on an approach to supporting per-function metrics
> > for
> > aarch64 cores, which requires some changes to the arm_pmuv3 driver,
> > and
> > I'm wondering if this approach would make sense as a generic
> > feature
> > that could be used to enable the same on other architectures?
> > 
> > The basic idea is as follows:
> > 
> > ?* Periodically sample one or more counters as needed for the
> > chosen
> > ?? set of metrics.
> > ?* Record a sample count for each symbol so as to identify hot
> > ?? functions.
> > ?* Accumulate counter totals for each of the counters in each of
> > the
> > ?? metrics *but* only do this where the previous sample's symbol
> > ?? matches the current sample's symbol.
> 
> It sounds very similar to what perf script -F +metric already does
> (or did if it wasn't broken currently). It would be a straight
> forward
> extension here to add this "same as previous" check.


Nice, I wasn't aware of this feature. I'll have a play...


> 
> Of course the feature is somewhat dubious in that it will have a very
> strong systematic bias against short functions and even long
> functions
> in some alternating execution patterns. I assume you did some
> experiments to characterize this. It would be important
> to emphasize this in any documentation.

The way I have been thinking about this is that for each sample you
always maintain a periodic sample count so that the relative ranking of
functions is maintained, and that the "same as previous" check is a way
to enhance the attributability of the PMU data for any given sample. 

But it absolutely correct to say that this will bias the availability
of PMU data in the way you have describe. The bias depends on sample
window size, workload characteristics and so on.

It should be possible to provide a per metric "valid sample" count that
can be used to judge the  "quality" of the metrics for each symbol,
which may allow the user to make some adjustments to the recording
paramters (modify sample period, or sample window size for example).

I'll have a think about the best way to convey this in docs. I have a
few ideas for ways to further impove the attributability / identify
cases where short functions are missed, but they'd not affect the
implementation of anything in the kernel, just perhaps the tool's post-
processing.


> 
> > For this to work efficiently, it is useful to provide a means to
> > decouple the sample window (time over which events are counted)
> > from
> > the sample period (time between interesting samples). This
> > patcheset
> > modifies the Arm PMU driver to support alternating between two
> > sample_period values, providing a simple and inexpensive way for
> > tools
> > to separate out the sample period and the sample window. It is
> > expected
> > to be used with the cycle counter event, alternating between a long
> > and
> > short period and subsequently discarding the counter data for
> > samples
> > with the long period. The combined long and short period gives the
> > overall sampling period, and the short sample period gives the
> > sample
> > window. The symbol taken from the sample at the end of the long
> > period
> > can be used by tools to ensure correct attribution as described
> > previously. The cycle counter is recommended as it provides fair
> > temporal distribution of samples as would be required for the
> > per-symbol sample count mentioned previously, and because the PMU
> > can
> > be programmed to overflow after a sufficiently short window; this
> > may
> > not be possible with software timer (for example). This patch does
> > not
> > restrict to only the cycle counter, it is possible there could be
> > other
> > novel uses based on different events.
> 
> I don't see anything ARM specific with the technique, so if it's done
> it should be done generically IMHO


Great. When i was originally thinking about the implementation of the
event strobing feature I was thinking:

 * Add `strobe_sample` flag bit to opt into the fature
   - This will be mutually exclusive with `freq`.
 * Add `strobe_period` field to hold the alternate sample period (for
the sample window.
 * Have all PMU drivers check and reject the `strobe_sample` flag by
default; the swizzling of the period will be done in the PMU driver its
self if it make sense to support this feature for a given PMU.
   - Do you think this is sensible, or would be better handled in core?

Any obvious issues with this approach?

> 
> 
> > Cursory testing on a Xeon(R) W-2145 sampling every 300 cycles
> > (without
> > the patch) suggests this approach would work for some counters.
> > Calculating branch miss rates for example appears to be correct,
> > likewise UOPS_EXECUTED.THREAD seems to give something like a
> > sensible
> > cycles-per-uop value. On the other hand the fixed function
> > instructions
> > counter does not appear to sample correctly (it seems to report
> > either
> > very small or very large numbers). No idea whats going on there, so
> > any
> > insight welcome...
> 
> If you use precise samples with 3p there is a restriction on the
> periods
> that is enforced by the kernel. Non precise or single/double p should
> support arbitrary, except that any p is always period + 1.

Is there some default value for precise? when testing I didn't set any
specific value for p modifier.


> 
> One drawback of the technique on x86 is that it won't allow multi
> record
> pebs (collecting samples without interrupts), so the overhead might
> be intrinsically higher.
> 
> -Andi


Sure, I think this kind of detail was why I was thinking it should be
the PMU driver rather than core that handles the strobing feature,
since there may be other considerations / better ways to collect the
metrics samples.

Regards
Ben

From tglx at linutronix.de  Wed Feb 14 11:54:49 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Wed, 14 Feb 2024 20:54:49 +0100
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <CAK9=C2Vwtj2gZg-P73yLMxu0rPXQ3YrRRuxq6HcpHMXgs-jHaw@mail.gmail.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <CAK9=C2Vwtj2gZg-P73yLMxu0rPXQ3YrRRuxq6HcpHMXgs-jHaw@mail.gmail.com>
Message-ID: <87bk8ig6t2.ffs@tglx>

Anup!

On Sat, Jan 27 2024 at 21:50, Anup Patel wrote:
>> Changes since v11:
>>  - Rebased on Linux-6.8-rc1
>>  - Included kernel/irq related patches from "genirq, irqchip: Convert ARM
>>    MSI handling to per device MSI domains" series by Thomas.
>>    (PATCH7, PATCH8, PATCH9, PATCH14, PATCH16, PATCH17, PATCH18, PATCH19,
>>     PATCH20, PATCH21, PATCH22, PATCH23, and PATCH32 of
>>     https://lore.kernel.org/linux-arm-kernel/20221121135653.208611233 at linutronix.de/)
>>  - Updated APLIC MSI-mode driver to use the new WIRED_TO_MSI mechanism.
>>  - Updated IMSIC driver to support per-device MSI domains for PCI and
>>    platform devices.
>
> I have rebased and included 13 patches (which add per-device MSI domain
> infrastructure) from your series [1]. In this series, the IMSIC driver
> implements the msi_parent_ops and APLIC driver implements wired-to-msi
> bridge using your new infrastructure.
>
> The remaining 27 patches of your series [1] requires testing on ARM
> platforms which I don't have. I suggest these remaining patches to
> go as separate series.

Of course. Darwi (in Cc) is going to work on the ARM parts when he
returns from vacation. I'm going to apply the infrastructure patches
(1-13) in the next days so they are out of the way for you and Darwi,
unless someone has any objections.

Thanks for picking this up and driving it forward!

        tglx


From maz at kernel.org  Wed Feb 14 12:16:23 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 14 Feb 2024 20:16:23 +0000
Subject: [PATCH v1 2/4] KVM: arm64: Document KVM_ARM_GET_REG_WRITABLE_MASKS
In-Reply-To: <25434f0e-d9c9-45dc-82a1-7466bc59a6e2@redhat.com>
References: <20230919175017.538312-1-jingzhangos@google.com>
	<20230919175017.538312-3-jingzhangos@google.com>
	<82b72bd2-c079-40c3-90b8-30174f2a8fe0@redhat.com>
	<86a5o45sb8.wl-maz@kernel.org>
	<25434f0e-d9c9-45dc-82a1-7466bc59a6e2@redhat.com>
Message-ID: <86ttma4x9k.wl-maz@kernel.org>

Hi Eric,

On Wed, 14 Feb 2024 18:07:58 +0000,
Eric Auger <eauger at redhat.com> wrote:
> 
> > I'm not sure SEIS is such an easy one: if you promised the guest that
> > it would never get an SError doing the most stupid things (SEIS=0), it
> > really shouldn't get one after migration. If you advertised it on the
> > source HW (Altra), a migration to TX2 would be fine.
> I see. Indeed for sure we must make sure KVM cannot inject SEIs in the
> guest if SEIS is not advertised on guest side.

The problem isn't KVM injecting an SError, but the HW doing it (that's
what SEIS indicates). On some HW, it only takes an old enough EFI
build to trigger those.

> In this case SEIS is 0 on src Altra. On dst TX2 ich_vtr_el2 advertises
> it and host seis =1 causing set_gic_ctlr to fail (vgic-sys-reg-v3.c).
> 
> > 
> > The other bits are possible to change depending on the requirements of
> > the VM (aff3, IDBits), and ExtRange should always be set to 0 (because
> > our GIC implementation doesn't support EPPI/ESPI).
> > 
> > The really ugly part here is that if you want to affect these bits,
> > you will need to trap and emulate the access. Not a big deal, but in
> > the absence of FGT, you will need to handle the full Common trap
> > group, which is going to slow things down (you will have to trap
> > ICV_PMR_EL1, for example).
> Would it be sensible to simplify things and only support the new range
> if FGT is supported?

I'm not sure that helps. The only FGT that covers the GIC is for
ICC_IGRPENn_EL1, and we don't care much about that guy. So
ICH_VMCR_EL2.TC it is, and that sucks a bit. But if that's what you
want to show, you don't have a choice.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From jernej.skrabec at gmail.com  Wed Feb 14 12:29:30 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Wed, 14 Feb 2024 21:29:30 +0100
Subject: [PATCH v4 1/7] soc: sunxi: sram: export register 0 for THS on H616
In-Reply-To: <20240209144221.3602382-2-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
 <20240209144221.3602382-2-andre.przywara@arm.com>
Message-ID: <2172811.irdbgypaU6@jernej-laptop>

Dne petek, 09. februar 2024 ob 15:42:15 CET je Andre Przywara napisal(a):
> The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
> in the SRAM control block. If bit 16 is set (the reset value), the
> temperature readings of the THS are way off, leading to reports about
> 200C, at normal ambient temperatures. Clearing this bits brings the
> reported values down to reasonable ranges.
> The BSP code clears this bit in firmware (U-Boot), and has an explicit
> comment about this, but offers no real explanation.
> 
> Since we should not rely on firmware settings, allow other code (the THS
> driver) to access this register, by exporting it through the already
> existing regmap. This mimics what we already do for the LDO control and
> the EMAC register.

Are you sure that this bit doesn't control actual SRAM region?

Best regards,
Jernej

> 
> Since this bit is in the very same register as the actual SRAM switch,
> we need to change the regmap lock to the SRAM lock. Fortunately regmap
> has provisions for that, so we just need to hook in there.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  drivers/soc/sunxi/sunxi_sram.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
> index 4458b2e0562b0..71cdd1b257eeb 100644
> --- a/drivers/soc/sunxi/sunxi_sram.c
> +++ b/drivers/soc/sunxi/sunxi_sram.c
> @@ -287,6 +287,7 @@ EXPORT_SYMBOL(sunxi_sram_release);
>  struct sunxi_sramc_variant {
>  	int num_emac_clocks;
>  	bool has_ldo_ctrl;
> +	bool has_ths_offset;
>  };
>  
>  static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
> @@ -308,8 +309,10 @@ static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
>  
>  static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
>  	.num_emac_clocks = 2,
> +	.has_ths_offset = true,
>  };
>  
> +#define SUNXI_SRAM_THS_OFFSET_REG	0x0
>  #define SUNXI_SRAM_EMAC_CLOCK_REG	0x30
>  #define SUNXI_SYS_LDO_CTRL_REG		0x150
>  
> @@ -318,6 +321,8 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
>  {
>  	const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
>  
> +	if (reg == SUNXI_SRAM_THS_OFFSET_REG && variant->has_ths_offset)
> +		return true;
>  	if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG &&
>  	    reg <  SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
>  		return true;
> @@ -327,6 +332,21 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
>  	return false;
>  }
>  
> +
> +static void sunxi_sram_lock(void *_lock)
> +{
> +	spinlock_t *lock = _lock;
> +
> +	spin_lock(lock);
> +}
> +
> +static void sunxi_sram_unlock(void *_lock)
> +{
> +	spinlock_t *lock = _lock;
> +
> +	spin_unlock(lock);
> +}
> +
>  static struct regmap_config sunxi_sram_regmap_config = {
>  	.reg_bits       = 32,
>  	.val_bits       = 32,
> @@ -336,6 +356,9 @@ static struct regmap_config sunxi_sram_regmap_config = {
>  	/* other devices have no business accessing other registers */
>  	.readable_reg	= sunxi_sram_regmap_accessible_reg,
>  	.writeable_reg	= sunxi_sram_regmap_accessible_reg,
> +	.lock		= sunxi_sram_lock,
> +	.unlock		= sunxi_sram_unlock,
> +	.lock_arg	= &sram_lock,
>  };
>  
>  static int __init sunxi_sram_probe(struct platform_device *pdev)
> 






From jernej.skrabec at gmail.com  Wed Feb 14 12:31:42 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Wed, 14 Feb 2024 21:31:42 +0100
Subject: [PATCH v4 3/7] thermal: sun8i: explain unknown H6 register value
In-Reply-To: <20240209144221.3602382-4-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
 <20240209144221.3602382-4-andre.przywara@arm.com>
Message-ID: <3274538.aeNJFYEL58@jernej-laptop>

Dne petek, 09. februar 2024 ob 15:42:17 CET je Andre Przywara napisal(a):
> So far we were ORing in some "unknown" value into the THS control
> register on the Allwinner H6. This part of the register is not explained
> in the H6 manual, but the H616 manual details those bits, and on closer
> inspection the THS IP blocks in both SoCs seem very close:
> - The BSP code for both SoCs writes the same values into THS_CTRL.
> - The reset values of at least the first three registers are the same.
> 
> Replace the "unknown" value with its proper meaning: "acquire time",
> most probably the sample part of the sample & hold circuit of the ADC,
> according to its explanation in the H616 manual.
> 
> No functional change, just a macro rename and adjustment.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Nice!

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  drivers/thermal/sun8i_thermal.c | 29 ++++++++++++++++-------------
>  1 file changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
> index 6a8e386dbc8dc..42bee03c4e507 100644
> --- a/drivers/thermal/sun8i_thermal.c
> +++ b/drivers/thermal/sun8i_thermal.c
> @@ -50,7 +50,8 @@
>  #define SUN8I_THS_CTRL2_T_ACQ1(x)		((GENMASK(15, 0) & (x)) << 16)
>  #define SUN8I_THS_DATA_IRQ_STS(x)		BIT(x + 8)
>  
> -#define SUN50I_THS_CTRL0_T_ACQ(x)		((GENMASK(15, 0) & (x)) << 16)
> +#define SUN50I_THS_CTRL0_T_ACQ(x)		(GENMASK(15, 0) & ((x) - 1))
> +#define SUN50I_THS_CTRL0_T_SAMPLE_PER(x)	((GENMASK(15, 0) & ((x) - 1)) << 16)
>  #define SUN50I_THS_FILTER_EN			BIT(2)
>  #define SUN50I_THS_FILTER_TYPE(x)		(GENMASK(1, 0) & (x))
>  #define SUN50I_H6_THS_PC_TEMP_PERIOD(x)		((GENMASK(19, 0) & (x)) << 12)
> @@ -410,25 +411,27 @@ static int sun8i_h3_thermal_init(struct ths_device *tmdev)
>  	return 0;
>  }
>  
> -/*
> - * Without this undocumented value, the returned temperatures would
> - * be higher than real ones by about 20C.
> - */
> -#define SUN50I_H6_CTRL0_UNK 0x0000002f
> -
>  static int sun50i_h6_thermal_init(struct ths_device *tmdev)
>  {
>  	int val;
>  
>  	/*
> -	 * T_acq = 20us
> -	 * clkin = 24MHz
> -	 *
> -	 * x = T_acq * clkin - 1
> -	 *   = 479
> +	 * The manual recommends an overall sample frequency of 50 KHz (20us,
> +	 * 480 cycles at 24 MHz), which provides plenty of time for both the
> +	 * acquisition time (>24 cycles) and the actual conversion time
> +	 * (>14 cycles).
> +	 * The lower half of the CTRL register holds the "acquire time", in
> +	 * clock cycles, which the manual recommends to be 2us:
> +	 * 24MHz * 2us = 48 cycles.
> +	 * The high half of THS_CTRL encodes the sample frequency, in clock
> +	 * cycles: 24MHz * 20us = 480 cycles.
> +	 * This is explained in the H616 manual, but apparently wrongly
> +	 * described in the H6 manual, although the BSP code does the same
> +	 * for both SoCs.
>  	 */
>  	regmap_write(tmdev->regmap, SUN50I_THS_CTRL0,
> -		     SUN50I_H6_CTRL0_UNK | SUN50I_THS_CTRL0_T_ACQ(479));
> +		     SUN50I_THS_CTRL0_T_ACQ(48) |
> +		     SUN50I_THS_CTRL0_T_SAMPLE_PER(480));
>  	/* average over 4 samples */
>  	regmap_write(tmdev->regmap, SUN50I_H6_THS_MFC,
>  		     SUN50I_THS_FILTER_EN |
> 






From jacob.e.keller at intel.com  Wed Feb 14 12:31:35 2024
From: jacob.e.keller at intel.com (Jacob Keller)
Date: Wed, 14 Feb 2024 12:31:35 -0800
Subject: [PATCH] net: stmmac: xgmac: fix initializer element is not
 constant error
In-Reply-To: <20240212154319.907447-1-shiftee@posteo.net>
References: <20240212154319.907447-1-shiftee@posteo.net>
Message-ID: <44c29a45-86fa-4e41-b4b5-e69187f0712e@intel.com>



On 2/12/2024 7:43 AM, Mark O'Donovan wrote:
> GCC prior to 8.x gives an "initializer element is not constant"
> error for the uses of dpp_tx_err in dwxgmac3_dma_dpp_errors.
> Newer compilers accept either version.
> 
> More info here:
> https://lore.kernel.org/all/20240103-fix-bq24190_charger-vbus_desc-non-const-v1-1-115ddf798c70 at kernel.org
> 
> Signed-off-by: Mark O'Donovan <shiftee at posteo.net>
> ---

I'm not sure whether the Linux kernel project has an explicit cutoff for
what versions of GCC (or other compilers) are supported. GCC 8 was first
released in 2018.

The fix provided here is fairly straight forward, and while I do think
the benefit of using builtin types vs using the macros is nice, I don't
see that as a strong enough reason to hold up supporting the older compiler.

Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>

>  drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> index 323c57f03c93..c02c035b81c0 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> @@ -830,8 +830,8 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
>  	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
>  };
>  
> -static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
> -static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
> +#define dpp_rx_err "Read Rx Descriptor Parity checker Error"
> +#define dpp_tx_err "Read Tx Descriptor Parity checker Error"
>  static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
>  	{ true, "TDPES0", dpp_tx_err },
>  	{ true, "TDPES1", dpp_tx_err },
> 
> base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de


From jernej.skrabec at gmail.com  Wed Feb 14 12:35:42 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Wed, 14 Feb 2024 21:35:42 +0100
Subject: [PATCH v4 4/7] thermal: sun8i: extend H6 calibration to support 4 sensors
In-Reply-To: <20240209144221.3602382-5-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
 <20240209144221.3602382-5-andre.przywara@arm.com>
Message-ID: <10416904.nUPlyArG6x@jernej-laptop>

Dne petek, 09. februar 2024 ob 15:42:18 CET je Andre Przywara napisal(a):
> From: Maksim Kiselev <bigunclemax at gmail.com>
> 
> The H616 SoC resembles the H6 thermal sensor controller, with a few
> changes like four sensors.
> 
> Extend sun50i_h6_ths_calibrate() function to support calibration of
> these sensors.
> 
> Signed-off-by: Maksim Kiselev <bigunclemax at gmail.com>
> Co-developed-by: Martin Botka <martin.botka at somainline.org>
> Reviewed-by: Andre Przywara <andre.przywara at arm.com>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From oliver.upton at linux.dev  Wed Feb 14 12:58:21 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Wed, 14 Feb 2024 12:58:21 -0800
Subject: [PATCH v2] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM
 Neoverse N2 errata
In-Reply-To: <20240214175522.2457857-1-eahariha@linux.microsoft.com>
References: <20240214175522.2457857-1-eahariha@linux.microsoft.com>
Message-ID: <Zc0pbaa0mnQta-mw@linux.dev>

On Wed, Feb 14, 2024 at 05:55:18PM +0000, Easwar Hariharan wrote:
> Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft
> implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore
> suffers from all the same errata.
> 
> CC: stable at vger.kernel.org # 5.15+
> Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>

Reviewed-by: Oliver Upton <oliver.upton at linux.dev>

-- 
Thanks,
Oliver


From abel.vesa at linaro.org  Wed Feb 14 13:13:45 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 14 Feb 2024 23:13:45 +0200
Subject: [PATCH RFC v3 0/4] spmi: pmic-arb: Add support for multiple buses
Message-ID: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>

This RFC prepares for and adds support for 2 buses, which is supported
in HW starting with version 7. Until now, none of the currently
supported platforms in upstream have used the second bus. The X1E80100
platform, on the other hand, needs the second bus for the USB2.0 to work
as there are 3 SMB2360 PMICs which provide eUSB2 repeaters and they are
all found on the second bus.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
Changes in v3:
- Split the change into 3 separate patches. First 2 patches are moving
  apid init and core resources into version specific ops. Third one is
  adding the support for 2 buses and dedicated compatible.
- Added separate bindings patch
- Link to v2: https://lore.kernel.org/r/20240213-spmi-multi-master-support-v2-1-b3b102326906 at linaro.org

Changes in v2:
- Reworked it so that it registers a spmi controller for each bus
  rather than relying on the generic framework to pass on the bus
  (master) id.
- Link to v1: https://lore.kernel.org/r/20240207-spmi-multi-master-support-v1-0-ce57f301c7fd at linaro.org

---
Abel Vesa (4):
      dt-bindings: spmi: Add PMIC ARB v7 schema
      spmi: pmic-arb: Make the APID init a version operation
      spmi: pmic-arb: Make core resources acquiring a version operation
      spmi: pmic-arb: Add multi bus support

 .../bindings/spmi/qcom,spmi-pmic-arb-v7.yaml       | 119 +++
 drivers/spmi/spmi-pmic-arb.c                       | 956 +++++++++++++--------
 2 files changed, 712 insertions(+), 363 deletions(-)
---
base-commit: 2c3b09aac00d7835023bbc4473ee06696be64fa8
change-id: 20240207-spmi-multi-master-support-832a704b779b

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>



From abel.vesa at linaro.org  Wed Feb 14 13:13:46 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 14 Feb 2024 23:13:46 +0200
Subject: [PATCH RFC v3 1/4] dt-bindings: spmi: Add PMIC ARB v7 schema
In-Reply-To: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
Message-ID: <20240214-spmi-multi-master-support-v3-1-0bae0ef04faf@linaro.org>

Add dedicated schema for PMIC ARB v7 as it allows multiple
buses by declaring them as child nodes. These child nodes
will follow the generic spmi bus bindings.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 .../bindings/spmi/qcom,spmi-pmic-arb-v7.yaml       | 119 +++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml
new file mode 100644
index 000000000000..8a93d2145aa5
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spmi/qcom,spmi-pmic-arb-v7.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SPMI Controller v7 (PMIC Arbiter)
+
+maintainers:
+  - Stephen Boyd <sboyd at kernel.org>
+
+description: |
+  The SPMI PMIC Arbiter v7 is found on Snapdragon chipsets. It is an SPMI
+  controller with wrapping arbitration logic to allow for multiple on-chip
+  devices to control up to 2 SPMI separate buses.
+
+  The PMIC Arbiter can also act as an interrupt controller, providing interrupts
+  to slave devices.
+
+properties:
+  compatible:
+    const: qcom,spmi-pmic-arb-v7
+
+  reg:
+    items:
+      - description: core registers
+      - description: tx-channel per virtual slave regosters
+      - description: rx-channel (called observer) per virtual slave registers
+
+  reg-names:
+    items:
+      - const: core
+      - const: chnls
+      - const: obsrvr
+
+  ranges: true
+
+  '#address-cells':
+    const: 2
+
+  '#size-cells':
+    const: 2
+
+  qcom,ee:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 5
+    description: >
+      indicates the active Execution Environment identifier
+
+  qcom,channel:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 5
+    description: >
+      which of the PMIC Arb provided channels to use for accesses
+
+patternProperties:
+  "spmi@[0-1]$":
+    type: object
+    $ref: /schemas/spmi/spmi.yaml
+
+required:
+  - compatible
+  - reg-names
+  - qcom,ee
+  - qcom,channel
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    spmi: arbiter at c400000 {
+      compatible = "qcom,spmi-pmic-arb-v7";
+      reg = <0x0c400000 0x3000>,
+            <0x0c500000 0x4000000>,
+            <0x0c440000 0x80000>;
+      reg-names = "core", "chnls", "obsrvr";
+
+      qcom,ee = <0>;
+      qcom,channel = <0>;
+
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      spmi_bus0: spmi at 0 {
+        reg = <0 0x0c42d000 0 0x4000>,
+              <0 0x0c4c0000 0 0x10000>;
+        reg-names = "cnfg", "intr";
+
+        interrupt-names = "periph_irq";
+        interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-controller;
+        #interrupt-cells = <4>;
+
+        qcom,bus-id = <0>;
+
+        #address-cells = <2>;
+        #size-cells = <0>;
+      };
+
+      spmi_bus1: spmi at 1 {
+        reg = <0 0x0c432000 0 0x4000>,
+              <0 0x0c4d0000 0 0x10000>;
+        reg-names = "cnfg", "intr";
+
+        interrupt-names = "periph_irq";
+        interrupts-extended = <&pdc 3 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-controller;
+        #interrupt-cells = <4>;
+
+        qcom,bus-id = <1>;
+
+        #address-cells = <2>;
+        #size-cells = <0>;
+      };
+    };

-- 
2.34.1



From abel.vesa at linaro.org  Wed Feb 14 13:13:47 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 14 Feb 2024 23:13:47 +0200
Subject: [PATCH RFC v3 2/4] spmi: pmic-arb: Make the APID init a version
 operation
In-Reply-To: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
Message-ID: <20240214-spmi-multi-master-support-v3-2-0bae0ef04faf@linaro.org>

Rather than using conditionals in probe function, add the APID init
as a version specific operation. Due to v7, which supports multiple
buses, pass on the bus index to be used for sorting out the apid base
and count.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 199 +++++++++++++++++++++++++++----------------
 1 file changed, 124 insertions(+), 75 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 9ed1180fe31f..23939c0d225f 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -183,6 +183,7 @@ struct spmi_pmic_arb {
  * struct pmic_arb_ver_ops - version dependent functionality.
  *
  * @ver_str:		version string.
+ * @init_apid:		finds the apid base and count
  * @ppid_to_apid:	finds the apid for a given ppid.
  * @non_data_cmd:	on v1 issues an spmi non-data command.
  *			on v2 no HW support, returns -EOPNOTSUPP.
@@ -202,6 +203,7 @@ struct spmi_pmic_arb {
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
+	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
 	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
 	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
@@ -942,6 +944,38 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 	return 0;
 }
 
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
+{
+	/*
+	 * Initialize max_apid/min_apid to the opposite bounds, during
+	 * the irq domain translation, we are sure to update these
+	 */
+	pmic_arb->max_apid = 0;
+	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
+
+	return 0;
+}
+
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	u32 *mapping_table;
+
+	if (index) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs,
+				     sizeof(*mapping_table), GFP_KERNEL);
+	if (!mapping_table)
+		return -ENOMEM;
+
+	pmic_arb->mapping_table = mapping_table;
+
+	return pmic_arb_init_apid_min_max(pmic_arb);
+}
+
 static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 {
 	u32 *mapping_table = pmic_arb->mapping_table;
@@ -1144,6 +1178,40 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0x1000 * pmic_arb->ee + 0x8000 * apid;
 }
 
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	int ret;
+
+	if (index) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	pmic_arb->base_apid = 0;
+	pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+					   PMIC_ARB_FEATURES_PERIPH_MASK;
+
+	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+			pmic_arb->base_apid + pmic_arb->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	if (ret) {
+		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v5 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
@@ -1178,6 +1246,49 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return offset;
 }
 
+/*
+ * Only v7 supports 2 bus buses. Each bus will get a different apid count,
+ * read from different registers.
+ */
+static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	int ret;
+
+	if (index == 0) {
+		pmic_arb->base_apid = 0;
+		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else if (index == 1) {
+		pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						  PMIC_ARB_FEATURES_PERIPH_MASK;
+		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+			pmic_arb->base_apid + pmic_arb->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	if (ret) {
+		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v7 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
@@ -1358,6 +1469,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v1,
 	.offset			= pmic_arb_offset_v1,
@@ -1372,6 +1484,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.ver_str		= "v2",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1386,6 +1499,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.ver_str		= "v3",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1400,6 +1514,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.ver_str		= "v5",
+	.init_apid		= pmic_arb_init_apid_v5,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v5,
@@ -1414,6 +1529,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.ver_str		= "v7",
+	.init_apid		= pmic_arb_init_apid_v7,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v7,
@@ -1439,7 +1555,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	struct spmi_controller *ctrl;
 	struct resource *res;
 	void __iomem *core;
-	u32 *mapping_table;
 	u32 channel, ee, hw_ver;
 	int err;
 
@@ -1467,12 +1582,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	pmic_arb->core_size = resource_size(res);
 
-	pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
-					      sizeof(*pmic_arb->ppid_to_apid),
-					      GFP_KERNEL);
-	if (!pmic_arb->ppid_to_apid)
-		return -ENOMEM;
-
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
 	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
@@ -1506,58 +1615,17 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 			return PTR_ERR(pmic_arb->wr_base);
 	}
 
-	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
+		 pmic_arb->ver_ops->ver_str, hw_ver);
 
-	if (hw_ver >= PMIC_ARB_VERSION_V7_MIN) {
+	if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+	else
 		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
-		/* Optional property for v7: */
-		of_property_read_u32(pdev->dev.of_node, "qcom,bus-id",
-					&pmic_arb->bus_instance);
-		if (pmic_arb->bus_instance > 1) {
-			dev_err(&pdev->dev, "invalid bus instance (%u) specified\n",
-				pmic_arb->bus_instance);
-			return -EINVAL;
-		}
-
-		if (pmic_arb->bus_instance == 0) {
-			pmic_arb->base_apid = 0;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		} else {
-			pmic_arb->base_apid =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES1) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		}
 
-		if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->base_apid + pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	} else if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		pmic_arb->base_apid = 0;
-		pmic_arb->apid_count = readl_relaxed(core + PMIC_ARB_FEATURES) &
-					PMIC_ARB_FEATURES_PERIPH_MASK;
-
-		if (pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	}
-
-	pmic_arb->apid_data = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					   sizeof(*pmic_arb->apid_data),
-					   GFP_KERNEL);
-	if (!pmic_arb->apid_data)
-		return -ENOMEM;
-
-	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
-		 pmic_arb->ver_ops->ver_str, hw_ver);
+	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
+	if (err)
+		return err;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
 	pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
@@ -1599,16 +1667,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	}
 
 	pmic_arb->ee = ee;
-	mapping_table = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					sizeof(*mapping_table), GFP_KERNEL);
-	if (!mapping_table)
-		return -ENOMEM;
-
-	pmic_arb->mapping_table = mapping_table;
-	/* Initialize max_apid/min_apid to the opposite bounds, during
-	 * the irq domain translation, we are sure to update these */
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
 
 	platform_set_drvdata(pdev, ctrl);
 	raw_spin_lock_init(&pmic_arb->lock);
@@ -1617,15 +1675,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	ctrl->read_cmd = pmic_arb_read_cmd;
 	ctrl->write_cmd = pmic_arb_write_cmd;
 
-	if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		err = pmic_arb_read_apid_map_v5(pmic_arb);
-		if (err) {
-			dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n",
-				err);
-			return err;
-		}
-	}
-
 	dev_dbg(&pdev->dev, "adding irq domain\n");
 	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
 					 &pmic_arb_irq_domain_ops, pmic_arb);

-- 
2.34.1



From abel.vesa at linaro.org  Wed Feb 14 13:13:48 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 14 Feb 2024 23:13:48 +0200
Subject: [PATCH RFC v3 3/4] spmi: pmic-arb: Make core resources acquiring a
 version operation
In-Reply-To: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
Message-ID: <20240214-spmi-multi-master-support-v3-3-0bae0ef04faf@linaro.org>

Rather than setting up the core, obsrv and chnls in probe by using
version specific conditionals, add a dedicated "get_core_resources"
version specific op and move the acquiring in there.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 111 ++++++++++++++++++++++++++++++-------------
 1 file changed, 78 insertions(+), 33 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 23939c0d225f..489556467a4c 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -203,6 +203,7 @@ struct spmi_pmic_arb {
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
+	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
 	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
 	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
@@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
 	return 0;
 }
 
+static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->wr_base = core;
+	pmic_arb->rd_base = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+	return 0;
+}
+
 static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
 {
 	u32 *mapping_table;
@@ -1063,6 +1077,41 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 	return apid;
 }
 
+static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					   "obsrvr");
+	pmic_arb->rd_base = devm_ioremap(dev, res->start,
+					 resource_size(res));
+	if (IS_ERR(pmic_arb->rd_base))
+		return PTR_ERR(pmic_arb->rd_base);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					   "chnls");
+	pmic_arb->wr_base = devm_ioremap(dev, res->start,
+					 resource_size(res));
+	if (IS_ERR(pmic_arb->wr_base))
+		return PTR_ERR(pmic_arb->wr_base);
+
+	return 0;
+}
+
+static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->core = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+	return pmic_arb_get_obsrvr_chnls_v2(pdev);
+}
+
 static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 {
 	u16 apid_valid;
@@ -1246,6 +1295,18 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return offset;
 }
 
+static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->core = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+
+	return pmic_arb_get_obsrvr_chnls_v2(pdev);
+}
+
 /*
  * Only v7 supports 2 bus buses. Each bus will get a different apid count,
  * read from different registers.
@@ -1469,6 +1530,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
+	.get_core_resources	= pmic_arb_get_core_resources_v1,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v1,
@@ -1484,6 +1546,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.ver_str		= "v2",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1499,6 +1562,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.ver_str		= "v3",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1514,6 +1578,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.ver_str		= "v5",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v5,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1529,6 +1594,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.ver_str		= "v7",
+	.get_core_resources	= pmic_arb_get_core_resources_v7,
 	.init_apid		= pmic_arb_init_apid_v7,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1584,44 +1650,23 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
-	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
+	if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
 		pmic_arb->ver_ops = &pmic_arb_v1;
-		pmic_arb->wr_base = core;
-		pmic_arb->rd_base = core;
-	} else {
-		pmic_arb->core = core;
-
-		if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v2;
-		else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v3;
-		else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v5;
-		else
-			pmic_arb->ver_ops = &pmic_arb_v7;
-
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   "obsrvr");
-		pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start,
-						 resource_size(res));
-		if (IS_ERR(pmic_arb->rd_base))
-			return PTR_ERR(pmic_arb->rd_base);
-
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   "chnls");
-		pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start,
-						 resource_size(res));
-		if (IS_ERR(pmic_arb->wr_base))
-			return PTR_ERR(pmic_arb->wr_base);
-	}
+	else if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v2;
+	else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v3;
+	else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v5;
+	else
+		pmic_arb->ver_ops = &pmic_arb_v7;
 
 	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
 		 pmic_arb->ver_ops->ver_str, hw_ver);
 
-	if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
-		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
-	else
-		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
+	if (err)
+		return err;
 
 	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
 	if (err)

-- 
2.34.1



From abel.vesa at linaro.org  Wed Feb 14 13:13:49 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 14 Feb 2024 23:13:49 +0200
Subject: [PATCH RFC v3 4/4] spmi: pmic-arb: Add multi bus support
In-Reply-To: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
Message-ID: <20240214-spmi-multi-master-support-v3-4-0bae0ef04faf@linaro.org>

Starting with HW version 7, there are actually two separate buses
(with two separate sets of wires). So in order to support both
buses, we need to register a separate spmi controller for each one.
Add a separate compatible for v7 only, but allow the legacy platforms
that have v7 to still work with the old one, for DT backwards
compatibility.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 730 +++++++++++++++++++++++++------------------
 1 file changed, 433 insertions(+), 297 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 489556467a4c..9c0ad9342cac 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -13,6 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spmi.h>
@@ -94,6 +96,8 @@ enum pmic_arb_channel {
 	PMIC_ARB_CHANNEL_OBS,
 };
 
+#define PMIC_ARB_MAX_BUSES		2
+
 /* Maximum number of support PMIC peripherals */
 #define PMIC_ARB_MAX_PERIPHS		512
 #define PMIC_ARB_MAX_PERIPHS_V7		1024
@@ -125,58 +129,68 @@ struct apid_data {
 	u8		irq_ee;
 };
 
+struct spmi_pmic_arb;
+
 /**
- * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ * struct spmi_pmic_arb_bus - SPMI PMIC Arbiter Bus object
  *
- * @rd_base:		on v1 "core", on v2 "observer" register base off DT.
- * @wr_base:		on v1 "core", on v2 "chnls"    register base off DT.
  * @intr:		address of the SPMI interrupt control registers.
  * @cnfg:		address of the PMIC Arbiter configuration registers.
- * @lock:		lock to synchronize accesses.
- * @channel:		execution environment channel to use for accesses.
- * @irq:		PMIC ARB interrupt.
- * @ee:			the current Execution Environment
- * @bus_instance:	on v7: 0 = primary SPMI bus, 1 = secondary SPMI bus
- * @min_apid:		minimum APID (used for bounding IRQ search)
- * @max_apid:		maximum APID
+ * @domain:		irq domain object for PMIC IRQ domain
  * @base_apid:		on v7: minimum APID associated with the particular SPMI
  *			bus instance
  * @apid_count:		on v5 and v7: number of APIDs associated with the
  *			particular SPMI bus instance
  * @mapping_table:	in-memory copy of PPID -> APID mapping table.
- * @domain:		irq domain object for PMIC IRQ domain
- * @spmic:		SPMI controller object
- * @ver_ops:		version dependent operations.
  * @ppid_to_apid:	in-memory copy of PPID -> APID mapping table.
- * @last_apid:		Highest value APID in use
  * @apid_data:		Table of data for all APIDs
+ * @last_apid:		Highest value APID in use
+ * @irq:		PMIC ARB interrupt.
+ */
+struct spmi_pmic_arb_bus {
+	struct spmi_pmic_arb	*pmic_arb;
+	struct irq_domain	*domain;
+	void __iomem		*intr;
+	void __iomem		*cnfg;
+	struct spmi_controller	*spmic;
+	u16			base_apid;
+	int			apid_count;
+	u32			*mapping_table;
+	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
+	u16			*ppid_to_apid;
+	u16			last_apid;
+	struct apid_data	*apid_data;
+	u16			min_apid;
+	u16			max_apid;
+	int			irq;
+	u8			id;
+};
+
+/**
+ * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ *
+ * @rd_base:		on v1 "core", on v2 "observer" register base off DT.
+ * @wr_base:		on v1 "core", on v2 "chnls"    register base off DT.
+ * @lock:		lock to synchronize accesses.
+ * @channel:		execution environment channel to use for accesses.
+ * @ee:			the current Execution Environment
+ * @min_apid:		minimum APID (used for bounding IRQ search)
+ * @max_apid:		maximum APID
+ * @ver_ops:		version dependent operations.
  * @max_periphs:	Number of elements in apid_data[]
  */
 struct spmi_pmic_arb {
 	void __iomem		*rd_base;
 	void __iomem		*wr_base;
-	void __iomem		*intr;
-	void __iomem		*cnfg;
 	void __iomem		*core;
 	resource_size_t		core_size;
 	raw_spinlock_t		lock;
 	u8			channel;
-	int			irq;
 	u8			ee;
-	u32			bus_instance;
-	u16			min_apid;
-	u16			max_apid;
-	u16			base_apid;
-	int			apid_count;
-	u32			*mapping_table;
-	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
-	struct irq_domain	*domain;
-	struct spmi_controller	*spmic;
 	const struct pmic_arb_ver_ops *ver_ops;
-	u16			*ppid_to_apid;
-	u16			last_apid;
-	struct apid_data	*apid_data;
 	int			max_periphs;
+	struct spmi_pmic_arb_bus buses[PMIC_ARB_MAX_BUSES];
+	int			buses_available;
 };
 
 /**
@@ -204,21 +218,21 @@ struct spmi_pmic_arb {
 struct pmic_arb_ver_ops {
 	const char *ver_str;
 	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
-	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
-	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
+	int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index);
+	int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
-	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type);
+	int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+		      enum pmic_arb_channel ch_type);
 	u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
 	int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
 	/* Interrupts controller functionality (offset of PIC registers) */
-	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb *pmic_arb, u8 m,
+	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb_bus *bus, u8 m,
 					  u16 n);
-	void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*acc_enable)(struct spmi_pmic_arb_bus *bus, u16 n);
+	void __iomem *(*irq_status)(struct spmi_pmic_arb_bus *bus, u16 n);
+	void __iomem *(*irq_clear)(struct spmi_pmic_arb_bus *bus, u16 n);
 	u32 (*apid_map_offset)(u16 n);
-	void __iomem *(*apid_owner)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*apid_owner)(struct spmi_pmic_arb_bus *bus, u16 n);
 };
 
 static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -266,13 +280,14 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 				  void __iomem *base, u8 sid, u16 addr,
 				  enum pmic_arb_channel ch_type)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 status = 0;
 	u32 timeout = PMIC_ARB_TIMEOUT_US;
 	u32 offset;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type);
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr, ch_type);
 	if (rc < 0)
 		return rc;
 
@@ -284,21 +299,21 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 
 		if (status & PMIC_ARB_STATUS_DONE) {
 			if (status & PMIC_ARB_STATUS_DENIED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction denied (%#x)\n",
+					__func__, bus->id, sid, addr, status);
 				return -EPERM;
 			}
 
 			if (status & PMIC_ARB_STATUS_FAILURE) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction failed (%#x) reg: 0x%x\n",
+					__func__, bus->id, sid, addr, status, offset);
 				WARN_ON(1);
 				return -EIO;
 			}
 
 			if (status & PMIC_ARB_STATUS_DROPPED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction dropped (%#x)\n",
+					__func__, bus->id, sid, addr, status);
 				return -EIO;
 			}
 
@@ -307,8 +322,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 		udelay(1);
 	}
 
-	dev_err(&ctrl->dev, "%s: %#x %#x: timeout, status %#x\n",
-		__func__, sid, addr, status);
+	dev_err(&ctrl->dev, "%s: %#x %#x %#x: timeout, status %#x\n",
+		__func__, bus->id, sid, addr, status);
 	return -ETIMEDOUT;
 }
 
@@ -316,12 +331,13 @@ static int
 pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[0];
 	unsigned long flags;
 	u32 cmd;
 	int rc;
 	u32 offset;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW);
+	rc = pmic_arb->ver_ops->offset(bus, sid, 0, PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
@@ -357,20 +373,21 @@ static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
 	return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid);
 }
 
-static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 sid,
+static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb_bus *bus, u8 opc, u8 sid,
 				 u16 addr, size_t len, u32 *cmd, u32 *offset)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr,
 				       PMIC_ARB_CHANNEL_OBS);
 	if (rc < 0)
 		return rc;
 
 	*offset = rc;
 	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-		dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+		dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
 			PMIC_ARB_MAX_TRANS_BYTES, len);
 		return  -EINVAL;
 	}
@@ -394,7 +411,8 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      u32 offset, u8 sid, u16 addr, u8 *buf,
 				      size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
@@ -416,12 +434,13 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 			     u16 addr, u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned long flags;
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_read_cmd(bus, opc, sid, addr, len, &cmd,
 				   &offset);
 	if (rc)
 		return rc;
@@ -433,21 +452,22 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 	return rc;
 }
 
-static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc,
+static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb_bus *bus, u8 opc,
 				  u8 sid, u16 addr, size_t len, u32 *cmd,
 				  u32 *offset)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr,
 					PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
 	*offset = rc;
 	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-		dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+		dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
 			PMIC_ARB_MAX_TRANS_BYTES, len);
 		return  -EINVAL;
 	}
@@ -473,7 +493,8 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      u32 offset, u8 sid, u16 addr,
 				      const u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 
 	/* Write data to FIFOs */
@@ -492,12 +513,13 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 			      u16 addr, const u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned long flags;
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_write_cmd(bus, opc, sid, addr, len, &cmd,
 				    &offset);
 	if (rc)
 		return rc;
@@ -513,18 +535,19 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr,
 				 const u8 *buf, const u8 *mask, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 read_cmd, read_offset, write_cmd, write_offset;
 	u8 temp[PMIC_ARB_MAX_TRANS_BYTES];
 	unsigned long flags;
 	int rc, i;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, SPMI_CMD_EXT_READL, sid, addr, len,
+	rc = pmic_arb_fmt_read_cmd(bus, SPMI_CMD_EXT_READL, sid, addr, len,
 				   &read_cmd, &read_offset);
 	if (rc)
 		return rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, SPMI_CMD_EXT_WRITEL, sid, addr,
+	rc = pmic_arb_fmt_write_cmd(bus, SPMI_CMD_EXT_WRITEL, sid, addr,
 				    len, &write_cmd, &write_offset);
 	if (rc)
 		return rc;
@@ -567,25 +590,25 @@ struct spmi_pmic_arb_qpnpint_type {
 static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
 			       size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
+	if (pmic_arb_write_cmd(bus->spmic, SPMI_CMD_EXT_WRITEL, sid,
 			       (per << 8) + reg, buf, len))
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
 }
 
 static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, sid,
+	if (pmic_arb_read_cmd(bus->spmic, SPMI_CMD_EXT_READL, sid,
 			      (per << 8) + reg, buf, len))
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
 }
 
@@ -593,47 +616,49 @@ static int qpnpint_spmi_masked_write(struct irq_data *d, u8 reg,
 				     const void *buf, const void *mask,
 				     size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 	int rc;
 
-	rc = pmic_arb_masked_write(pmic_arb->spmic, sid, (per << 8) + reg, buf,
+	rc = pmic_arb_masked_write(bus->spmic, sid, (per << 8) + reg, buf,
 				   mask, len);
 	if (rc)
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
 				    d->irq, rc);
 	return rc;
 }
 
-static void cleanup_irq(struct spmi_pmic_arb *pmic_arb, u16 apid, int id)
+static void cleanup_irq(struct spmi_pmic_arb_bus *bus, u16 apid, int id)
 {
-	u16 ppid = pmic_arb->apid_data[apid].ppid;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	u16 ppid = bus->apid_data[apid].ppid;
 	u8 sid = ppid >> 8;
 	u8 per = ppid & 0xFF;
 	u8 irq_mask = BIT(id);
 
-	dev_err_ratelimited(&pmic_arb->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
-			__func__, apid, sid, per, id);
-	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	dev_err_ratelimited(&bus->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
+			    __func__, apid, sid, per, id);
+	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(bus, apid));
 }
 
-static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
+static int periph_interrupt(struct spmi_pmic_arb_bus *bus, u16 apid)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned int irq;
 	u32 status, id;
 	int handled = 0;
-	u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF;
-	u8 per = pmic_arb->apid_data[apid].ppid & 0xFF;
+	u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF;
+	u8 per = bus->apid_data[apid].ppid & 0xFF;
 
-	status = readl_relaxed(pmic_arb->ver_ops->irq_status(pmic_arb, apid));
+	status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid));
 	while (status) {
 		id = ffs(status) - 1;
 		status &= ~BIT(id);
-		irq = irq_find_mapping(pmic_arb->domain,
-					spec_to_hwirq(sid, per, id, apid));
+		irq = irq_find_mapping(bus->domain,
+				       spec_to_hwirq(sid, per, id, apid));
 		if (irq == 0) {
-			cleanup_irq(pmic_arb, apid, id);
+			cleanup_irq(bus, apid, id);
 			continue;
 		}
 		generic_handle_irq(irq);
@@ -645,16 +670,17 @@ static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
 
 static void pmic_arb_chained_irq(struct irq_desc *desc)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb_bus *bus = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int first = pmic_arb->min_apid;
-	int last = pmic_arb->max_apid;
+	int first = bus->min_apid;
+	int last = bus->max_apid;
 	/*
 	 * acc_offset will be non-zero for the secondary SPMI bus instance on
 	 * v7 controllers.
 	 */
-	int acc_offset = pmic_arb->base_apid >> 5;
+	int acc_offset = bus->base_apid >> 5;
 	u8 ee = pmic_arb->ee;
 	u32 status, enable, handled = 0;
 	int i, id, apid;
@@ -665,7 +691,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	chained_irq_enter(chip, desc);
 
 	for (i = first >> 5; i <= last >> 5; ++i) {
-		status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i - acc_offset));
+		status = readl_relaxed(ver_ops->owner_acc_status(bus, ee, i - acc_offset));
 		if (status)
 			acc_valid = true;
 
@@ -679,9 +705,9 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 				continue;
 			}
 			enable = readl_relaxed(
-					ver_ops->acc_enable(pmic_arb, apid));
+					ver_ops->acc_enable(bus, apid));
 			if (enable & SPMI_PIC_ACC_ENABLE_BIT)
-				if (periph_interrupt(pmic_arb, apid) != 0)
+				if (periph_interrupt(bus, apid) != 0)
 					handled++;
 		}
 	}
@@ -690,19 +716,19 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	if (!acc_valid) {
 		for (i = first; i <= last; i++) {
 			/* skip if APPS is not irq owner */
-			if (pmic_arb->apid_data[i].irq_ee != pmic_arb->ee)
+			if (bus->apid_data[i].irq_ee != pmic_arb->ee)
 				continue;
 
 			irq_status = readl_relaxed(
-					     ver_ops->irq_status(pmic_arb, i));
+					     ver_ops->irq_status(bus, i));
 			if (irq_status) {
 				enable = readl_relaxed(
-					     ver_ops->acc_enable(pmic_arb, i));
+					     ver_ops->acc_enable(bus, i));
 				if (enable & SPMI_PIC_ACC_ENABLE_BIT) {
-					dev_dbg(&pmic_arb->spmic->dev,
+					dev_dbg(&bus->spmic->dev,
 						"Dispatching IRQ for apid=%d status=%x\n",
 						i, irq_status);
-					if (periph_interrupt(pmic_arb, i) != 0)
+					if (periph_interrupt(bus, i) != 0)
 						handled++;
 				}
 			}
@@ -717,12 +743,13 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 
 static void qpnpint_irq_ack(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 data;
 
-	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(bus, apid));
 
 	data = BIT(irq);
 	qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
@@ -738,14 +765,15 @@ static void qpnpint_irq_mask(struct irq_data *d)
 
 static void qpnpint_irq_unmask(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 buf[2];
 
 	writel_relaxed(SPMI_PIC_ACC_ENABLE_BIT,
-			ver_ops->acc_enable(pmic_arb, apid));
+			ver_ops->acc_enable(bus, apid));
 
 	qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1);
 	if (!(buf[0] & BIT(irq))) {
@@ -802,9 +830,9 @@ static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
 
 static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 
-	return irq_set_irq_wake(pmic_arb->irq, on);
+	return irq_set_irq_wake(bus->irq, on);
 }
 
 static int qpnpint_get_irqchip_state(struct irq_data *d,
@@ -826,17 +854,18 @@ static int qpnpint_get_irqchip_state(struct irq_data *d,
 static int qpnpint_irq_domain_activate(struct irq_domain *domain,
 				       struct irq_data *d, bool reserve)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 periph = hwirq_to_per(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u16 sid = hwirq_to_sid(d->hwirq);
 	u16 irq = hwirq_to_irq(d->hwirq);
 	u8 buf;
 
-	if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
+	if (bus->apid_data[apid].irq_ee != pmic_arb->ee) {
+		dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
 			sid, periph, irq, pmic_arb->ee,
-			pmic_arb->apid_data[apid].irq_ee);
+			bus->apid_data[apid].irq_ee);
 		return -ENODEV;
 	}
 
@@ -863,15 +892,16 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 					unsigned long *out_hwirq,
 					unsigned int *out_type)
 {
-	struct spmi_pmic_arb *pmic_arb = d->host_data;
+	struct spmi_pmic_arb_bus *bus = d->host_data;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 *intspec = fwspec->param;
 	u16 apid, ppid;
 	int rc;
 
-	dev_dbg(&pmic_arb->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
+	dev_dbg(&bus->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
 		intspec[0], intspec[1], intspec[2]);
 
-	if (irq_domain_get_of_node(d) != pmic_arb->spmic->dev.of_node)
+	if (irq_domain_get_of_node(d) != bus->spmic->dev.of_node)
 		return -EINVAL;
 	if (fwspec->param_count != 4)
 		return -EINVAL;
@@ -879,37 +909,38 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 		return -EINVAL;
 
 	ppid = intspec[0] << 8 | intspec[1];
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
 	if (rc < 0) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
-		intspec[0], intspec[1], intspec[2], rc);
+		dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
+			intspec[0], intspec[1], intspec[2], rc);
 		return rc;
 	}
 
 	apid = rc;
 	/* Keep track of {max,min}_apid for bounding search during interrupt */
-	if (apid > pmic_arb->max_apid)
-		pmic_arb->max_apid = apid;
-	if (apid < pmic_arb->min_apid)
-		pmic_arb->min_apid = apid;
+	if (apid > bus->max_apid)
+		bus->max_apid = apid;
+	if (apid < bus->min_apid)
+		bus->min_apid = apid;
 
 	*out_hwirq = spec_to_hwirq(intspec[0], intspec[1], intspec[2], apid);
 	*out_type  = intspec[3] & IRQ_TYPE_SENSE_MASK;
 
-	dev_dbg(&pmic_arb->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
+	dev_dbg(&bus->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
 
 	return 0;
 }
 
 static struct lock_class_key qpnpint_irq_lock_class, qpnpint_irq_request_class;
 
-static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb,
+static void qpnpint_irq_domain_map(struct spmi_pmic_arb_bus *bus,
 				   struct irq_domain *domain, unsigned int virq,
 				   irq_hw_number_t hwirq, unsigned int type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	irq_flow_handler_t handler;
 
-	dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
+	dev_dbg(&bus->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
 		virq, hwirq, type);
 
 	if (type & IRQ_TYPE_EDGE_BOTH)
@@ -928,7 +959,7 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 				    unsigned int virq, unsigned int nr_irqs,
 				    void *data)
 {
-	struct spmi_pmic_arb *pmic_arb = domain->host_data;
+	struct spmi_pmic_arb_bus *bus = domain->host_data;
 	struct irq_fwspec *fwspec = data;
 	irq_hw_number_t hwirq;
 	unsigned int type;
@@ -939,20 +970,22 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 		return ret;
 
 	for (i = 0; i < nr_irqs; i++)
-		qpnpint_irq_domain_map(pmic_arb, domain, virq + i, hwirq + i,
+		qpnpint_irq_domain_map(bus, domain, virq + i, hwirq + i,
 				       type);
 
 	return 0;
 }
 
-static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb_bus *bus)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+
 	/*
 	 * Initialize max_apid/min_apid to the opposite bounds, during
 	 * the irq domain translation, we are sure to update these
 	 */
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
+	bus->max_apid = 0;
+	bus->min_apid = pmic_arb->max_periphs - 1;
 
 	return 0;
 }
@@ -970,43 +1003,44 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
 	return 0;
 }
 
-static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 *mapping_table;
 
 	if (index) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
 			index);
 		return -EINVAL;
 	}
 
-	mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs,
+	mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs,
 				     sizeof(*mapping_table), GFP_KERNEL);
 	if (!mapping_table)
 		return -ENOMEM;
 
-	pmic_arb->mapping_table = mapping_table;
+	bus->mapping_table = mapping_table;
 
-	return pmic_arb_init_apid_min_max(pmic_arb);
+	return pmic_arb_init_apid_min_max(bus);
 }
 
-static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	u32 *mapping_table = pmic_arb->mapping_table;
+	u32 *mapping_table = bus->mapping_table;
 	int index = 0, i;
 	u16 apid_valid;
 	u16 apid;
 	u32 data;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = bus->ppid_to_apid[ppid];
 	if (apid_valid & PMIC_ARB_APID_VALID) {
 		apid = apid_valid & ~PMIC_ARB_APID_VALID;
 		return apid;
 	}
 
 	for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
-		if (!test_and_set_bit(index, pmic_arb->mapping_table_valid))
-			mapping_table[index] = readl_relaxed(pmic_arb->cnfg +
+		if (!test_and_set_bit(index, bus->mapping_table_valid))
+			mapping_table[index] = readl_relaxed(bus->cnfg +
 						SPMI_MAPPING_TABLE_REG(index));
 
 		data = mapping_table[index];
@@ -1016,9 +1050,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				bus->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				bus->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		} else {
@@ -1026,9 +1060,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				bus->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				bus->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		}
@@ -1038,24 +1072,26 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 }
 
 /* v1 offset per ee */
-static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v1(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return 0x800 + 0x80 * pmic_arb->channel;
 }
 
-static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static u16 pmic_arb_find_apid(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid];
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	struct apid_data *apidd = &bus->apid_data[bus->last_apid];
 	u32 regval, offset;
 	u16 id, apid;
 
-	for (apid = pmic_arb->last_apid; ; apid++, apidd++) {
+	for (apid = bus->last_apid; ; apid++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(apid);
 		if (offset >= pmic_arb->core_size)
 			break;
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus,
 								     apid));
 		apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 		apidd->write_ee = apidd->irq_ee;
@@ -1065,14 +1101,14 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 			continue;
 
 		id = (regval >> 8) & PMIC_ARB_PPID_MASK;
-		pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
+		bus->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
 		apidd->ppid = id;
 		if (id == ppid) {
 			apid |= PMIC_ARB_APID_VALID;
 			break;
 		}
 	}
-	pmic_arb->last_apid = apid & ~PMIC_ARB_APID_VALID;
+	bus->last_apid = apid & ~PMIC_ARB_APID_VALID;
 
 	return apid;
 }
@@ -1112,21 +1148,22 @@ static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
 	return pmic_arb_get_obsrvr_chnls_v2(pdev);
 }
 
-static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
 	u16 apid_valid;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = bus->ppid_to_apid[ppid];
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
-		apid_valid = pmic_arb_find_apid(pmic_arb, ppid);
+		apid_valid = pmic_arb_find_apid(bus, ppid);
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
 	return apid_valid & ~PMIC_ARB_APID_VALID;
 }
 
-static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	struct apid_data *apidd;
 	struct apid_data *prev_apidd;
 	u16 i, apid, ppid, apid_max;
@@ -1148,9 +1185,9 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 	 * where N = number of APIDs supported by the primary bus and
 	 *       M = number of APIDs supported by the secondary bus
 	 */
-	apidd = &pmic_arb->apid_data[pmic_arb->base_apid];
-	apid_max = pmic_arb->base_apid + pmic_arb->apid_count;
-	for (i = pmic_arb->base_apid; i < apid_max; i++, apidd++) {
+	apidd = &bus->apid_data[bus->base_apid];
+	apid_max = bus->base_apid + bus->apid_count;
+	for (i = bus->base_apid; i < apid_max; i++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(i);
 		if (offset >= pmic_arb->core_size)
 			break;
@@ -1161,19 +1198,18 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		ppid = (regval >> 8) & PMIC_ARB_PPID_MASK;
 		is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval);
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
-								     i));
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i));
 		apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 
 		apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE;
 
-		valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
-		apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
-		prev_apidd = &pmic_arb->apid_data[apid];
+		valid = bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
+		apid = bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+		prev_apidd = &bus->apid_data[apid];
 
 		if (!valid || apidd->write_ee == pmic_arb->ee) {
 			/* First PPID mapping or one for this EE */
-			pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+			bus->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
 		} else if (valid && is_irq_ee &&
 			   prev_apidd->write_ee == pmic_arb->ee) {
 			/*
@@ -1184,42 +1220,43 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		}
 
 		apidd->ppid = ppid;
-		pmic_arb->last_apid = i;
+		bus->last_apid = i;
 	}
 
 	/* Dump the mapping table for debug purposes. */
-	dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
+	dev_dbg(&bus->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
 	for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) {
-		apid = pmic_arb->ppid_to_apid[ppid];
+		apid = bus->ppid_to_apid[ppid];
 		if (apid & PMIC_ARB_APID_VALID) {
 			apid &= ~PMIC_ARB_APID_VALID;
-			apidd = &pmic_arb->apid_data[apid];
-			dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n",
-			      ppid, apid, apidd->write_ee, apidd->irq_ee);
+			apidd = &bus->apid_data[apid];
+			dev_dbg(&bus->spmic->dev, "%#03X %3u %2u %2u\n",
+				ppid, apid, apidd->write_ee, apidd->irq_ee);
 		}
 	}
 
 	return 0;
 }
 
-static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
+	if (!(bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
-	return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+	return bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
 }
 
 /* v2 offset per ppid and per ee */
-static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	u16 ppid;
 	int rc;
 
 	ppid = sid << 8 | ((addr >> 8) & 0xFF);
-	rc = pmic_arb_ppid_to_apid_v2(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v2(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1227,33 +1264,34 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0x1000 * pmic_arb->ee + 0x8000 * apid;
 }
 
-static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	int ret;
 
 	if (index) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
 			index);
 		return -EINVAL;
 	}
 
-	pmic_arb->base_apid = 0;
-	pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+	bus->base_apid = 0;
+	bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 					   PMIC_ARB_FEATURES_PERIPH_MASK;
 
-	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
-			pmic_arb->base_apid + pmic_arb->apid_count);
+	if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+		dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+			bus->base_apid + bus->apid_count);
 		return -EINVAL;
 	}
 
-	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	ret = pmic_arb_init_apid_min_max(bus);
 	if (ret)
 		return ret;
 
-	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	ret = pmic_arb_read_apid_map_v5(bus);
 	if (ret) {
-		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+		dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
 			ret);
 		return ret;
 	}
@@ -1265,15 +1303,16 @@ static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
  * v5 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v5(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v5(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1283,8 +1322,8 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
-			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+		if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+			dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
 		}
@@ -1311,38 +1350,39 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
  * Only v7 supports 2 bus buses. Each bus will get a different apid count,
  * read from different registers.
  */
-static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	int ret;
 
 	if (index == 0) {
-		pmic_arb->base_apid = 0;
-		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+		bus->base_apid = 0;
+		bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 						   PMIC_ARB_FEATURES_PERIPH_MASK;
 	} else if (index == 1) {
-		pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+		bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 						  PMIC_ARB_FEATURES_PERIPH_MASK;
-		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+		bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
 						   PMIC_ARB_FEATURES_PERIPH_MASK;
 	} else {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
-			index);
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
+			bus->id);
 		return -EINVAL;
 	}
 
-	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
-			pmic_arb->base_apid + pmic_arb->apid_count);
+	if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+		dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+			bus->base_apid + bus->apid_count);
 		return -EINVAL;
 	}
 
-	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	ret = pmic_arb_init_apid_min_max(bus);
 	if (ret)
 		return ret;
 
-	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	ret = pmic_arb_read_apid_map_v5(bus);
 	if (ret) {
-		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+		dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
 			ret);
 		return ret;
 	}
@@ -1354,15 +1394,16 @@ static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
  * v7 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v7(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1372,8 +1413,8 @@ static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x8000 * pmic_arb->ee + 0x20 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
-			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+		if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+			dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
 		}
@@ -1395,104 +1436,110 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x20 * m + 0x4 * n;
+	return bus->intr + 0x20 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x100000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x200000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x10000 * m + 0x4 * n;
+	return bus->intr + 0x10000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x200 + 0x4 * n;
+	return bus->intr + 0x200 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * n;
+	return bus->intr + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x600 + 0x4 * n;
+	return bus->intr + 0x600 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x4 + 0x1000 * n;
+	return bus->intr + 0x4 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0xA00 + 0x4 * n;
+	return bus->intr + 0xA00 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x8 + 0x1000 * n;
+	return bus->intr + 0x8 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x1000 * n;
 }
 
@@ -1512,9 +1559,9 @@ static u32 pmic_arb_apid_map_offset_v7(u16 n)
 }
 
 static void __iomem *
-pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->cnfg + 0x700 + 0x4 * n;
+	return bus->cnfg + 0x700 + 0x4 * n;
 }
 
 /*
@@ -1523,9 +1570,9 @@ pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
  * 0.
  */
 static void __iomem *
-pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->cnfg + 0x4 * (n - pmic_arb->base_apid);
+	return  bus->cnfg + 0x4 * (n - bus->base_apid);
 }
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
@@ -1615,21 +1662,152 @@ static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
 	.translate = qpnpint_irq_domain_translate,
 };
 
+static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
+				  struct device_node *node,
+				  struct spmi_pmic_arb *pmic_arb)
+{
+	int bus_index = pmic_arb->buses_available;
+	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[bus_index];
+	struct device *dev = &pdev->dev;
+	struct spmi_controller *ctrl;
+	void __iomem *intr;
+	void __iomem *cnfg;
+	int index, ret;
+	u32 irq;
+
+	ctrl = devm_spmi_controller_alloc(dev, sizeof(*ctrl));
+	if (IS_ERR(ctrl))
+		return PTR_ERR(ctrl);
+
+	ctrl->cmd = pmic_arb_cmd;
+	ctrl->read_cmd = pmic_arb_read_cmd;
+	ctrl->write_cmd = pmic_arb_write_cmd;
+
+	bus = spmi_controller_get_drvdata(ctrl);
+	bus->spmic = ctrl;
+
+	bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID,
+					 sizeof(*bus->ppid_to_apid),
+					 GFP_KERNEL);
+	if (!bus->ppid_to_apid)
+		return -ENOMEM;
+
+	bus->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs,
+				      sizeof(*bus->apid_data),
+				      GFP_KERNEL);
+	if (!bus->apid_data)
+		return -ENOMEM;
+
+	/* Optional property for v7: */
+	of_property_read_u32(node, "qcom,bus-id", &bus_index);
+
+	index = of_property_match_string(node, "reg-names", "cnfg");
+	if (index < 0) {
+		dev_err(dev, "cnfg reg region missing");
+		return -EINVAL;
+	}
+
+	cnfg = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(cnfg))
+		return PTR_ERR(cnfg);
+
+	index = of_property_match_string(node, "reg-names", "intr");
+	if (index < 0) {
+		dev_err(dev, "intr reg region missing");
+		return -EINVAL;
+	}
+
+	intr = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(intr))
+		return PTR_ERR(intr);
+
+	irq = of_irq_get_byname(node, "periph_irq");
+	if (irq < 0)
+		return irq;
+
+	bus->pmic_arb = pmic_arb;
+	bus->intr = intr;
+	bus->cnfg = cnfg;
+	bus->irq = irq;
+	bus->id = bus_index;
+
+	ret = pmic_arb->ver_ops->init_apid(bus, bus_index);
+	if (ret)
+		return ret;
+
+	dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index);
+
+	bus->domain = irq_domain_add_tree(dev->of_node,
+					  &pmic_arb_irq_domain_ops, bus);
+	if (!bus->domain) {
+		dev_err(&pdev->dev, "unable to create irq_domain\n");
+		return -ENOMEM;
+	}
+
+	irq_set_chained_handler_and_data(bus->irq,
+					 pmic_arb_chained_irq, bus);
+
+	bus->spmic->dev.of_node = node;
+	dev_set_name(&bus->spmic->dev, "spmi-%d", bus_index);
+
+	ret = devm_spmi_controller_add(dev, bus->spmic);
+	if (ret)
+		return ret;
+
+	pmic_arb->buses_available++;
+
+	return 0;
+}
+
+static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb,
+					struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct device_node *child;
+	int ret;
+
+	/* legacy mode doesn't provide child node for the bus */
+	if (of_device_is_compatible(node, "qcom,spmi-pmic-arb-v7")) {
+		for_each_available_child_of_node(node, child) {
+			if (of_node_name_eq(child, "spmi")) {
+				ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb);
+				if (ret)
+					return ret;
+			}
+		}
+	} else {
+		ret = spmi_pmic_arb_bus_init(pdev, node, pmic_arb);
+	}
+
+	return ret;
+}
+
+static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb)
+{
+	int i;
+
+	for (i = 0; i < PMIC_ARB_MAX_BUSES; i++) {
+		struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[i];
+
+		irq_set_chained_handler_and_data(bus->irq,
+						 NULL, NULL);
+		irq_domain_remove(bus->domain);
+	}
+}
+
 static int spmi_pmic_arb_probe(struct platform_device *pdev)
 {
 	struct spmi_pmic_arb *pmic_arb;
-	struct spmi_controller *ctrl;
+	struct device *dev = &pdev->dev;
 	struct resource *res;
 	void __iomem *core;
 	u32 channel, ee, hw_ver;
 	int err;
 
-	ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*pmic_arb));
-	if (IS_ERR(ctrl))
-		return PTR_ERR(ctrl);
-
-	pmic_arb = spmi_controller_get_drvdata(ctrl);
-	pmic_arb->spmic = ctrl;
+	pmic_arb = devm_kzalloc(dev, sizeof(*pmic_arb), GFP_KERNEL);
+	if (!pmic_arb)
+		return -ENOMEM;
 
 	/*
 	 * Please don't replace this with devm_platform_ioremap_resource() or
@@ -1642,12 +1820,15 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	 * which does not result in a devm_request_mem_region() call.
 	 */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
-	core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
+	core = devm_ioremap(dev, res->start, resource_size(res));
 	if (IS_ERR(core))
 		return PTR_ERR(core);
 
 	pmic_arb->core_size = resource_size(res);
 
+	platform_set_drvdata(pdev, pmic_arb);
+	raw_spin_lock_init(&pmic_arb->lock);
+
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
 	if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
@@ -1661,30 +1842,12 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	else
 		pmic_arb->ver_ops = &pmic_arb_v7;
 
-	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
-		 pmic_arb->ver_ops->ver_str, hw_ver);
-
 	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
 	if (err)
 		return err;
 
-	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
-	if (err)
-		return err;
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
-	pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->intr))
-		return PTR_ERR(pmic_arb->intr);
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
-	pmic_arb->cnfg = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->cnfg))
-		return PTR_ERR(pmic_arb->cnfg);
-
-	pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq");
-	if (pmic_arb->irq < 0)
-		return pmic_arb->irq;
+	dev_info(dev, "PMIC arbiter version %s (0x%x)\n",
+		 pmic_arb->ver_ops->ver_str, hw_ver);
 
 	err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
 	if (err) {
@@ -1713,46 +1876,19 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	pmic_arb->ee = ee;
 
-	platform_set_drvdata(pdev, ctrl);
-	raw_spin_lock_init(&pmic_arb->lock);
-
-	ctrl->cmd = pmic_arb_cmd;
-	ctrl->read_cmd = pmic_arb_read_cmd;
-	ctrl->write_cmd = pmic_arb_write_cmd;
-
-	dev_dbg(&pdev->dev, "adding irq domain\n");
-	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
-					 &pmic_arb_irq_domain_ops, pmic_arb);
-	if (!pmic_arb->domain) {
-		dev_err(&pdev->dev, "unable to create irq_domain\n");
-		return -ENOMEM;
-	}
-
-	irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq,
-					pmic_arb);
-	err = spmi_controller_add(ctrl);
-	if (err)
-		goto err_domain_remove;
-
-	return 0;
-
-err_domain_remove:
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
-	return err;
+	return spmi_pmic_arb_register_buses(pmic_arb, pdev);
 }
 
 static void spmi_pmic_arb_remove(struct platform_device *pdev)
 {
-	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
-	spmi_controller_remove(ctrl);
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	spmi_pmic_arb_deregister_buses(pmic_arb);
 }
 
 static const struct of_device_id spmi_pmic_arb_match_table[] = {
 	{ .compatible = "qcom,spmi-pmic-arb", },
+	{ .compatible = "qcom,spmi-pmic-arb-v7", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);

-- 
2.34.1



From konrad.dybcio at linaro.org  Wed Feb 14 13:16:58 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Wed, 14 Feb 2024 22:16:58 +0100
Subject: [PATCH RFC v3 2/4] spmi: pmic-arb: Make the APID init a version
 operation
In-Reply-To: <20240214-spmi-multi-master-support-v3-2-0bae0ef04faf@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-2-0bae0ef04faf@linaro.org>
Message-ID: <d9f88786-abe3-4826-adbd-fee461a70c2c@linaro.org>

On 14.02.2024 22:13, Abel Vesa wrote:
> Rather than using conditionals in probe function, add the APID init
> as a version specific operation. Due to v7, which supports multiple
> buses, pass on the bus index to be used for sorting out the apid base
> and count.
> 
> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> ---

[...]


> +
>  /*
>   * v5 offset per ee and per apid for observer channels and per apid for
>   * read/write channels.
> @@ -1178,6 +1246,49 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
>  	return offset;
>  }
>  
> +/*
> + * Only v7 supports 2 bus buses. Each bus will get a different apid count,

"bus buses"?

Konrad


From konrad.dybcio at linaro.org  Wed Feb 14 13:18:33 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Wed, 14 Feb 2024 22:18:33 +0100
Subject: [PATCH RFC v3 3/4] spmi: pmic-arb: Make core resources acquiring
 a version operation
In-Reply-To: <20240214-spmi-multi-master-support-v3-3-0bae0ef04faf@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-3-0bae0ef04faf@linaro.org>
Message-ID: <d9d8e86b-a499-49d1-90ad-6fae5b7dcbb7@linaro.org>

On 14.02.2024 22:13, Abel Vesa wrote:
> Rather than setting up the core, obsrv and chnls in probe by using
> version specific conditionals, add a dedicated "get_core_resources"
> version specific op and move the acquiring in there.
> 
> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> ---
>  drivers/spmi/spmi-pmic-arb.c | 111 ++++++++++++++++++++++++++++++-------------
>  1 file changed, 78 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> index 23939c0d225f..489556467a4c 100644
> --- a/drivers/spmi/spmi-pmic-arb.c
> +++ b/drivers/spmi/spmi-pmic-arb.c
> @@ -203,6 +203,7 @@ struct spmi_pmic_arb {
>   */
>  struct pmic_arb_ver_ops {
>  	const char *ver_str;
> +	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
>  	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
>  	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
>  	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
> @@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
>  	return 0;
>  }
>  
> +static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
> +					  void __iomem *core)
> +{
> +	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> +
> +	pmic_arb->wr_base = core;
> +	pmic_arb->rd_base = core;
> +
> +	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
> +
> +	return 0;
> +}
> +
>  static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
>  {
>  	u32 *mapping_table;
> @@ -1063,6 +1077,41 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
>  	return apid;
>  }
>  
> +static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
> +{
> +	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,

It's no longer indented to deep, no need to keep such aggressive wrapping

> +					   "obsrvr");
> +	pmic_arb->rd_base = devm_ioremap(dev, res->start,
> +					 resource_size(res));
> +	if (IS_ERR(pmic_arb->rd_base))
> +		return PTR_ERR(pmic_arb->rd_base);
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> +					   "chnls");
> +	pmic_arb->wr_base = devm_ioremap(dev, res->start,
> +					 resource_size(res));
> +	if (IS_ERR(pmic_arb->wr_base))
> +		return PTR_ERR(pmic_arb->wr_base);

Could probably make it "devm_platform_get_and_ioremap_resource "

Konrad


From abel.vesa at linaro.org  Wed Feb 14 13:36:29 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 14 Feb 2024 23:36:29 +0200
Subject: [PATCH RFC v3 3/4] spmi: pmic-arb: Make core resources acquiring
 a version operation
In-Reply-To: <d9d8e86b-a499-49d1-90ad-6fae5b7dcbb7@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-3-0bae0ef04faf@linaro.org>
 <d9d8e86b-a499-49d1-90ad-6fae5b7dcbb7@linaro.org>
Message-ID: <Zc0yXR/fC2OcObLB@linaro.org>

On 24-02-14 22:18:33, Konrad Dybcio wrote:
> On 14.02.2024 22:13, Abel Vesa wrote:
> > Rather than setting up the core, obsrv and chnls in probe by using
> > version specific conditionals, add a dedicated "get_core_resources"
> > version specific op and move the acquiring in there.
> > 
> > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > ---
> >  drivers/spmi/spmi-pmic-arb.c | 111 ++++++++++++++++++++++++++++++-------------
> >  1 file changed, 78 insertions(+), 33 deletions(-)
> > 
> > diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> > index 23939c0d225f..489556467a4c 100644
> > --- a/drivers/spmi/spmi-pmic-arb.c
> > +++ b/drivers/spmi/spmi-pmic-arb.c
> > @@ -203,6 +203,7 @@ struct spmi_pmic_arb {
> >   */
> >  struct pmic_arb_ver_ops {
> >  	const char *ver_str;
> > +	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
> >  	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
> >  	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
> >  	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
> > @@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
> >  	return 0;
> >  }
> >  
> > +static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
> > +					  void __iomem *core)
> > +{
> > +	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> > +
> > +	pmic_arb->wr_base = core;
> > +	pmic_arb->rd_base = core;
> > +
> > +	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
> > +
> > +	return 0;
> > +}
> > +
> >  static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
> >  {
> >  	u32 *mapping_table;
> > @@ -1063,6 +1077,41 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
> >  	return apid;
> >  }
> >  
> > +static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
> > +{
> > +	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> > +	struct device *dev = &pdev->dev;
> > +	struct resource *res;
> > +
> > +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> 
> It's no longer indented to deep, no need to keep such aggressive wrapping
> 

The pmic_arb_get_obsrvr_chnls_v2 is used by both:
pmic_arb_get_core_resources_v2
pmic_arb_get_core_resources_v7

> > +					   "obsrvr");
> > +	pmic_arb->rd_base = devm_ioremap(dev, res->start,
> > +					 resource_size(res));
> > +	if (IS_ERR(pmic_arb->rd_base))
> > +		return PTR_ERR(pmic_arb->rd_base);
> > +
> > +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > +					   "chnls");
> > +	pmic_arb->wr_base = devm_ioremap(dev, res->start,
> > +					 resource_size(res));
> > +	if (IS_ERR(pmic_arb->wr_base))
> > +		return PTR_ERR(pmic_arb->wr_base);
> 
> Could probably make it "devm_platform_get_and_ioremap_resource "

The reason this needs to stay as is is because of reason explained by
the following comment found in probe:

/*                                                                           
 * Please don't replace this with devm_platform_ioremap_resource() or        
 * devm_ioremap_resource().  These both result in a call to                  
 * devm_request_mem_region() which prevents multiple mappings of this        
 * register address range.  SoCs with PMIC arbiter v7 may define two         
 * arbiter devices, for the two physical SPMI interfaces, which  share       
 * some register address ranges (i.e. "core", "obsrvr", and "chnls").        
 * Ensure that both devices probe successfully by calling devm_ioremap()     
 * which does not result in a devm_request_mem_region() call.                
 */                                                                          

Even though, AFAICT, there is no platform that adds a second node for
the second bus, currently, in mainline, we should probably allow the
"legacy" approach to still work.

> 
> Konrad


From abel.vesa at linaro.org  Wed Feb 14 13:37:31 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 14 Feb 2024 23:37:31 +0200
Subject: [PATCH RFC v3 2/4] spmi: pmic-arb: Make the APID init a version
 operation
In-Reply-To: <d9f88786-abe3-4826-adbd-fee461a70c2c@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-2-0bae0ef04faf@linaro.org>
 <d9f88786-abe3-4826-adbd-fee461a70c2c@linaro.org>
Message-ID: <Zc0ymyR87km2rZjW@linaro.org>

On 24-02-14 22:16:58, Konrad Dybcio wrote:
> On 14.02.2024 22:13, Abel Vesa wrote:
> > Rather than using conditionals in probe function, add the APID init
> > as a version specific operation. Due to v7, which supports multiple
> > buses, pass on the bus index to be used for sorting out the apid base
> > and count.
> > 
> > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > ---
> 
> [...]
> 
> 
> > +
> >  /*
> >   * v5 offset per ee and per apid for observer channels and per apid for
> >   * read/write channels.
> > @@ -1178,6 +1246,49 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
> >  	return offset;
> >  }
> >  
> > +/*
> > + * Only v7 supports 2 bus buses. Each bus will get a different apid count,
> 
> "bus buses"?

Urgh. Will fix in the next version.

> 
> Konrad


From andi.shyti at kernel.org  Wed Feb 14 13:42:03 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Wed, 14 Feb 2024 22:42:03 +0100
Subject: [PATCH] i2c: pasemi: split driver into two separate modules
In-Reply-To: <20240212111933.963985-1-arnd@kernel.org>
References: <20240212111933.963985-1-arnd@kernel.org>
Message-ID: <170794692308.4040459.7350373390928340229.b4-ty@kernel.org>

Hi

On Mon, 12 Feb 2024 12:19:04 +0100, Arnd Bergmann wrote:
> On powerpc, it is possible to compile test both the new apple (arm) and
> old pasemi (powerpc) drivers for the i2c hardware at the same time,
> which leads to a warning about linking the same object file twice:
> 
> scripts/Makefile.build:244: drivers/i2c/busses/Makefile: i2c-pasemi-core.o is added to multiple modules: i2c-apple i2c-pasemi
> 
> Rework the driver to have an explicit helper module, letting Kbuild
> take care of whether this should be built-in or a loadable driver.
> 
> [...]

Applied to i2c/i2c-host-fixes on

git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git

Thank you,
Andi

Patches applied
===============
[1/1] i2c: pasemi: split driver into two separate modules
      commit: 3fab8a74c71a4ba32b2fa1dca7340f9107ff8dfc



From konrad.dybcio at linaro.org  Wed Feb 14 13:43:43 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Wed, 14 Feb 2024 22:43:43 +0100
Subject: [PATCH 3/5] drm: msm: add support for A750 GPU
In-Reply-To: <bcad544c-7ca2-4b4f-805b-4ccaedbd091c@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
 <20240212-topic-sm8650-gpu-v1-3-708a40b747b5@linaro.org>
 <b5d76a25-045a-4acd-ad20-d28855b40222@linaro.org>
 <bcad544c-7ca2-4b4f-805b-4ccaedbd091c@linaro.org>
Message-ID: <13d65685-b306-43ad-b9ca-a799f2cf73e5@linaro.org>

On 12.02.2024 15:45, Neil Armstrong wrote:
> On 12/02/2024 11:46, Konrad Dybcio wrote:
>> On 12.02.2024 11:37, Neil Armstrong wrote:
>>> Add support for the A750 GPU found on the SM8650 platform
>>>
>>> Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
>>> doesn't have an HWCFG block but a separate register set.
>>>
>>> The missing registers are added in the a6xx.xml.h file that would
>>> require a subsequent sync and the non-existent hwcfg is handled
>>> in a6xx_set_hwcg().
>>
>> These should also be submitted to mesa to make sure the next header sync
>> doesn't wipe them
> 
> Ack submitting them right now: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27576

Thanks

> 
>>
>> [...]
>>
>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>> @@ -958,10 +958,11 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>> ????? struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>>> ????? struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
>>> ????? const struct adreno_reglist *reg;
>>> +??? bool skip_programming = !(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu));
>>
>> is_a750?
> 
> OK right, I was thinking of the next gpu which will probably also miss an hwcfg
> 
>>
>>> ????? unsigned int i;
>>> ????? u32 val, clock_cntl_on, cgc_mode;
>>> ? -??? if (!adreno_gpu->info->hwcg)
>>> +??? if (skip_programming)
>>> ????????? return;
>>> ? ????? if (adreno_is_a630(adreno_gpu))
>>> @@ -982,6 +983,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>> ??????????????? state ? 0x5555 : 0);
>>> ????? }
>>> ? +??? if (!adreno_gpu->info->hwcg) {
>>
>> I don't think this block of code is reachable now, no?
> 
> It is because we didn't skip when adreno_is_a7xx(adreno_gpu)

Ahh I misread the brackets within the assignment

> 
>>
>> Maybe remove the skip_programming and if_a750 here?
> This would require:
>>> -??? if (!adreno_gpu->info->hwcg || )
>>> +??? if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
> 
> and:
> 
>>> +??? if (adreno_is_a750(adreno_gpu)) {
> 
> But if the next gpu also doesn't have an hwcfg, we will need to use
> the current design...
> 
> I just tried with:
> ====================><===============================
> @@ -961,7 +961,7 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
> ??????? unsigned int i;
> ??????? u32 val, clock_cntl_on, cgc_mode;
> 
> -?????? if (!adreno_gpu->info->hwcg)
> +?????? if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
> ??????????????? return;
> 
> ??????? if (adreno_is_a630(adreno_gpu))
> @@ -982,6 +982,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
> ????????????????????????? state ? 0x5555 : 0);
> ??????? }
> 
> +?????? if (adreno_is_a750(adreno_gpu)) {
> +?????????????? gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
> +?????????????? gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
> +
> +?????????????? if (state) {
> +?????????????????????? gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
> +
> +?????????????????????? if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
> +??????????????????????????????????????????? val & A7XX_RBBM_CGC_P2S_STATUS_TXDONE, 1, 10)) {
> +?????????????????????????????? dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
> +?????????????????????????????? return;
> +?????????????????????? }
> +
> +?????????????????????? gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
> +?????????????? }
> +
> +?????????????? return;
> +?????? }
> +
> ??????? val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
> 
> ??????? /* Don't re-program the registers if they are already correct */
> ====================><===============================
> 
> And it works fine, does it work it for you ?

Let's keep it as-is in the original submission, as I've mentioned, I had
misread the code

Konrad

> 
>>
>>> +??????? gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
>>> +??????? gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
>>> +
>>> +??????? if (state) {
>>> +??????????? gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
>>> +
>>> +??????????? if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
>>> +???????????????????????? val & BIT(0), 1, 10)) {
>>
>> We should define that bit name (the err suggests it's
>> REG_A7XX_RBBM_GCC_P2S_STATUS_TXDONE or so)
>>
>> [...]
>>
>>> +static inline int adreno_is_a750(struct adreno_gpu *gpu)
>>> +{
>>> +??? return gpu->info->chip_ids[0] == 0x43051401;
>>> +}
>>> +
>>> ? /* Placeholder to make future diffs smaller */
>>
>> Please also remove this comment now that it's invalid
> 
> Ack
> 
>>
>> Konrad
> 
> Thanks,
> Neil
> 


From konrad.dybcio at linaro.org  Wed Feb 14 13:44:55 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Wed, 14 Feb 2024 22:44:55 +0100
Subject: [PATCH RFC v3 3/4] spmi: pmic-arb: Make core resources acquiring
 a version operation
In-Reply-To: <Zc0yXR/fC2OcObLB@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-3-0bae0ef04faf@linaro.org>
 <d9d8e86b-a499-49d1-90ad-6fae5b7dcbb7@linaro.org>
 <Zc0yXR/fC2OcObLB@linaro.org>
Message-ID: <5e878fd9-8215-499d-ac1c-191cb5bfe798@linaro.org>

On 14.02.2024 22:36, Abel Vesa wrote:
> On 24-02-14 22:18:33, Konrad Dybcio wrote:
>> On 14.02.2024 22:13, Abel Vesa wrote:
>>> Rather than setting up the core, obsrv and chnls in probe by using
>>> version specific conditionals, add a dedicated "get_core_resources"
>>> version specific op and move the acquiring in there.
>>>
>>> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
>>> ---
>>>  drivers/spmi/spmi-pmic-arb.c | 111 ++++++++++++++++++++++++++++++-------------
>>>  1 file changed, 78 insertions(+), 33 deletions(-)
>>>
>>> diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
>>> index 23939c0d225f..489556467a4c 100644
>>> --- a/drivers/spmi/spmi-pmic-arb.c
>>> +++ b/drivers/spmi/spmi-pmic-arb.c
>>> @@ -203,6 +203,7 @@ struct spmi_pmic_arb {
>>>   */
>>>  struct pmic_arb_ver_ops {
>>>  	const char *ver_str;
>>> +	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
>>>  	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
>>>  	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
>>>  	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
>>> @@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
>>>  	return 0;
>>>  }
>>>  
>>> +static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
>>> +					  void __iomem *core)
>>> +{
>>> +	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
>>> +
>>> +	pmic_arb->wr_base = core;
>>> +	pmic_arb->rd_base = core;
>>> +
>>> +	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>>  static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
>>>  {
>>>  	u32 *mapping_table;
>>> @@ -1063,6 +1077,41 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
>>>  	return apid;
>>>  }
>>>  
>>> +static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
>>> +{
>>> +	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
>>> +	struct device *dev = &pdev->dev;
>>> +	struct resource *res;
>>> +
>>> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
>>
>> It's no longer indented to deep, no need to keep such aggressive wrapping
>>
> 
> The pmic_arb_get_obsrvr_chnls_v2 is used by both:
> pmic_arb_get_core_resources_v2
> pmic_arb_get_core_resources_v7

I meant line wrapping

> 
>>> +					   "obsrvr");
>>> +	pmic_arb->rd_base = devm_ioremap(dev, res->start,
>>> +					 resource_size(res));
>>> +	if (IS_ERR(pmic_arb->rd_base))
>>> +		return PTR_ERR(pmic_arb->rd_base);
>>> +
>>> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
>>> +					   "chnls");
>>> +	pmic_arb->wr_base = devm_ioremap(dev, res->start,
>>> +					 resource_size(res));
>>> +	if (IS_ERR(pmic_arb->wr_base))
>>> +		return PTR_ERR(pmic_arb->wr_base);
>>
>> Could probably make it "devm_platform_get_and_ioremap_resource "
> 
> The reason this needs to stay as is is because of reason explained by
> the following comment found in probe:
> 
> /*                                                                           
>  * Please don't replace this with devm_platform_ioremap_resource() or        
>  * devm_ioremap_resource().  These both result in a call to                  
>  * devm_request_mem_region() which prevents multiple mappings of this        
>  * register address range.  SoCs with PMIC arbiter v7 may define two         
>  * arbiter devices, for the two physical SPMI interfaces, which  share       
>  * some register address ranges (i.e. "core", "obsrvr", and "chnls").        
>  * Ensure that both devices probe successfully by calling devm_ioremap()     
>  * which does not result in a devm_request_mem_region() call.                
>  */                                                                          
> 
> Even though, AFAICT, there is no platform that adds a second node for
> the second bus, currently, in mainline, we should probably allow the
> "legacy" approach to still work.

OK right, let's keep it.

Konrad


From irogers at google.com  Wed Feb 14 14:02:44 2024
From: irogers at google.com (Ian Rogers)
Date: Wed, 14 Feb 2024 14:02:44 -0800
Subject: [PATCH v3 0/8] Clean up libperf cpumap's empty function
In-Reply-To: <20240202234057.2085863-1-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com>
Message-ID: <CAP-5=fVjAHqAHHLqE=3v2bP6S6k98psiuZds7TUTFCT7RgMFdQ@mail.gmail.com>

On Fri, Feb 2, 2024 at 3:41?PM Ian Rogers <irogers at google.com> wrote:
>
> Rename and clean up the use of libperf CPU map functions particularly
> focussing on perf_cpu_map__empty that may return true for maps
> containing CPUs but also with an "any CPU"/dummy value.
>
> perf_cpu_map__nr is also troubling in that iterating an empty CPU map
> will yield the "any CPU"/dummy value. Reduce the appearance of some
> calls to this by using the perf_cpu_map__for_each_cpu macro.
>
> v3: Address handling of "any" is arm-spe/cs-etm patch.
> v2: 6 patches were merged by Arnaldo. New patch added ensure empty
>     maps are allocated as NULL (suggested by James Clark). Hopefully a
>     fix to "perf arm-spe/cs-etm: Directly iterate CPU maps".
>
> Ian Rogers (8):
>   libperf cpumap: Add any, empty and min helpers
>   libperf cpumap: Ensure empty cpumap is NULL from alloc
>   perf arm-spe/cs-etm: Directly iterate CPU maps
>   perf intel-pt/intel-bts: Switch perf_cpu_map__has_any_cpu_or_is_empty
>     use
>   perf cpumap: Clean up use of perf_cpu_map__has_any_cpu_or_is_empty
>   perf arm64 header: Remove unnecessary CPU map get and put
>   perf stat: Remove duplicate cpus_map_matched function
>   perf cpumap: Use perf_cpu_map__for_each_cpu when possible

Ping. Thanks,
Ian

>  tools/lib/perf/cpumap.c                       |  33 ++++-
>  tools/lib/perf/include/perf/cpumap.h          |  16 +++
>  tools/lib/perf/libperf.map                    |   4 +
>  tools/perf/arch/arm/util/cs-etm.c             | 114 ++++++++----------
>  tools/perf/arch/arm64/util/arm-spe.c          |   4 +-
>  tools/perf/arch/arm64/util/header.c           |  13 +-
>  tools/perf/arch/x86/util/intel-bts.c          |   4 +-
>  tools/perf/arch/x86/util/intel-pt.c           |  10 +-
>  tools/perf/builtin-c2c.c                      |   6 +-
>  tools/perf/builtin-stat.c                     |  31 +----
>  tools/perf/tests/bitmap.c                     |  13 +-
>  tools/perf/tests/topology.c                   |  46 +++----
>  tools/perf/util/auxtrace.c                    |   4 +-
>  tools/perf/util/bpf_kwork.c                   |  16 +--
>  tools/perf/util/bpf_kwork_top.c               |  12 +-
>  tools/perf/util/cpumap.c                      |  12 +-
>  tools/perf/util/record.c                      |   2 +-
>  .../scripting-engines/trace-event-python.c    |  12 +-
>  tools/perf/util/session.c                     |   5 +-
>  tools/perf/util/stat.c                        |   2 +-
>  tools/perf/util/svghelper.c                   |  20 ++-
>  21 files changed, 192 insertions(+), 187 deletions(-)
>
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From shiftee at posteo.net  Wed Feb 14 14:07:58 2024
From: shiftee at posteo.net (Mark O'Donovan)
Date: Wed, 14 Feb 2024 22:07:58 +0000
Subject: [PATCH] net: stmmac: xgmac: fix initializer element is not
 constant error
In-Reply-To: <44c29a45-86fa-4e41-b4b5-e69187f0712e@intel.com>
References: <20240212154319.907447-1-shiftee@posteo.net>
 <44c29a45-86fa-4e41-b4b5-e69187f0712e@intel.com>
Message-ID: <867da21e-7f30-4caf-9f78-260d426e4186@posteo.net>

On 14/02/2024 20:31, Jacob Keller wrote:
> 
> 
> On 2/12/2024 7:43 AM, Mark O'Donovan wrote:
>> GCC prior to 8.x gives an "initializer element is not constant"
>> error for the uses of dpp_tx_err in dwxgmac3_dma_dpp_errors.
>> Newer compilers accept either version.
>>
>> More info here:
>> https://lore.kernel.org/all/20240103-fix-bq24190_charger-vbus_desc-non-const-v1-1-115ddf798c70 at kernel.org
>>
>> Signed-off-by: Mark O'Donovan <shiftee at posteo.net>
>> ---
> 
> I'm not sure whether the Linux kernel project has an explicit cutoff for
> what versions of GCC (or other compilers) are supported. GCC 8 was first
> released in 2018.
> 
> The fix provided here is fairly straight forward, and while I do think
> the benefit of using builtin types vs using the macros is nice, I don't
> see that as a strong enough reason to hold up supporting the older compiler.
> 
> Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
> 
>>   drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>> index 323c57f03c93..c02c035b81c0 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>> @@ -830,8 +830,8 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
>>   	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
>>   };
>>   
>> -static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
>> -static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
>> +#define dpp_rx_err "Read Rx Descriptor Parity checker Error"
>> +#define dpp_tx_err "Read Tx Descriptor Parity checker Error"
>>   static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
>>   	{ true, "TDPES0", dpp_tx_err },
>>   	{ true, "TDPES1", dpp_tx_err },
>>
>> base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de

Thanks Jacob.

The minimum versions for compilers and other tools are documented here:
https://www.kernel.org/doc/html/latest/process/changes.html

I am using a SLES 15 server to build, the first version of which came out in 2017.

Mark


From devnull+zachary.goldstein.concurrent-rt.com at kernel.org  Wed Feb 14 14:21:54 2024
From: devnull+zachary.goldstein.concurrent-rt.com at kernel.org (Zachary Goldstein via B4 Relay)
Date: Wed, 14 Feb 2024 17:21:54 -0500
Subject: [PATCH] arm64: ls1046ardb: Replace XGMII with 10GBASE-R phy mode
Message-ID: <20240214-ls1046-dts-use-10gbase-r-v1-1-8c2d68547393@concurrent-rt.com>

From: Zachary Goldstein <zachary.goldstein at concurrent-rt.com>

The AQR107 family does not support XGMII, but USXGMII and
10GBASE-R instead. Since ce64c1f77a9d ("net: phy: aquantia: add USXGMII
support and warn if XGMII mode is set") the kernel warns about XGMII
being used. The LS1046A SoC does not support USXGMII, so use 10GBASE-R
instead.

Signed-off-by: Zachary Goldstein <zachary.goldstein at concurrent-rt.com>
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
index 07f6cc6e354a..d2066f733dc5 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
@@ -149,7 +149,7 @@ ethernet at ea000 {
 
 	ethernet at f0000 { /* 10GEC1 */
 		phy-handle = <&aqr106_phy>;
-		phy-connection-type = "xgmii";
+		phy-connection-type = "10gbase-r";
 	};
 
 	ethernet at f2000 { /* 10GEC2 */

---
2.40.1
base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de



From david at redhat.com  Wed Feb 14 14:40:22 2024
From: david at redhat.com (David Hildenbrand)
Date: Wed, 14 Feb 2024 23:40:22 +0100
Subject: [PATCH v3 12/15] mm/memory: pass PTE to copy_present_pte()
In-Reply-To: <20240129124649.189745-13-david@redhat.com>
References: <20240129124649.189745-1-david@redhat.com>
 <20240129124649.189745-13-david@redhat.com>
Message-ID: <13f296b8-e882-47fd-b939-c2141dc28717@redhat.com>

On 29.01.24 13:46, David Hildenbrand wrote:
> We already read it, let's just forward it.
> 
> This patch is based on work by Ryan Roberts.
> 
> Reviewed-by: Ryan Roberts <ryan.roberts at arm.com>
> Signed-off-by: David Hildenbrand <david at redhat.com>
> ---
>   mm/memory.c | 7 +++----
>   1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/mm/memory.c b/mm/memory.c
> index a3bdb25f4c8d..41b24da5be38 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -959,10 +959,9 @@ static inline void __copy_present_pte(struct vm_area_struct *dst_vma,
>    */
>   static inline int
>   copy_present_pte(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
> -		 pte_t *dst_pte, pte_t *src_pte, unsigned long addr, int *rss,
> -		 struct folio **prealloc)
> +		 pte_t *dst_pte, pte_t *src_pte, pte_t pte, unsigned long addr,
> +		 int *rss, struct folio **prealloc)
>   {
> -	pte_t pte = ptep_get(src_pte);
>   	struct page *page;
>   	struct folio *folio;
>   
> @@ -1103,7 +1102,7 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
>   		}
>   		/* copy_present_pte() will clear `*prealloc' if consumed */
>   		ret = copy_present_pte(dst_vma, src_vma, dst_pte, src_pte,
> -				       addr, rss, &prealloc);
> +				       ptent, addr, rss, &prealloc);
>   		/*
>   		 * If we need a pre-allocated page for this pte, drop the
>   		 * locks, allocate, and try again.

The following fixup for that device-exclusive thingy on top (fixing a hmm
selftest I just discovered to be broken).


 From 8f9e44f25087dc71890b8d9bd680375691232e85 Mon Sep 17 00:00:00 2001
From: David Hildenbrand <david at redhat.com>
Date: Wed, 14 Feb 2024 23:09:29 +0100
Subject: [PATCH] fixup: mm/memory: pass PTE to copy_present_pte()

For device-exclusive nonswp entries (is_device_exclusive_entry()),
copy_nonpresent_pte() can turn the PTEs into actual present PTEs while
holding the page table lock.

We hae to re-read the PTE after that operation, such that we won't be
working on the stale non-present PTE, assuming it would be present.

This fixes the hmm "exclusive_cow" selftest.

  ./run_vmtests.sh -t hmm
  # #  RUN           hmm.hmm_device_private.exclusive_cow ...
  # #            OK  hmm.hmm_device_private.exclusive_cow
  # ok 23 hmm.hmm_device_private.exclusive_cow

Signed-off-by: David Hildenbrand <david at redhat.com>
---
  mm/memory.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/mm/memory.c b/mm/memory.c
index 3b8e56eb08a3..29a75f38df7c 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1208,6 +1208,8 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
  				progress += 8;
  				continue;
  			}
+			ptent = ptep_get(src_pte);
+			VM_WARN_ON_ONCE(!pte_present(ptent));
  
  			/*
  			 * Device exclusive entry restored, continue by copying
-- 
2.43.0


-- 
Cheers,

David / dhildenb



From frkoenig at chromium.org  Wed Feb 14 15:17:01 2024
From: frkoenig at chromium.org (Fritz Koenig)
Date: Wed, 14 Feb 2024 15:17:01 -0800
Subject: [PATCH] media: mediatek: vcodec: setting request complete before
 buffer done
In-Reply-To: <95daea30-14e6-4c0b-8a0c-60641efc9d92@collabora.com>
References: <20240111071713.16331-1-yunfei.dong@mediatek.com> <95daea30-14e6-4c0b-8a0c-60641efc9d92@collabora.com>
Message-ID: <CAMfZQbzcg64mO13_2=FCPu5A79f7BqD77OJMXReHKove6vVSFA@mail.gmail.com>

I have seen issues with this patch. It does fix the original issue,
but now some kernel panics are occuring.

[  369.634206] ------------[ cut here ]------------
[  369.634214]  __schedule+0x4bc/0x8b8
[  369.634216] WARNING: CPU: 6 PID: 6520 at
drivers/media/common/videobuf2/videobuf2-core.c:1063
vb2_buffer_done+0x184/0x228 [videobuf2_common]
[  369.634220] Modules linked in:
[  369.634231]  schedule+0x54/0xe0
[  369.634232]  8021q veth rfcomm algif_hash
[  369.634246]  schedule_preempt_disabled+0x2c/0x48
[  369.634247]  algif_skcipher af_alg lzo_rle
[  369.634262]  __mutex_lock+0x138/0x2ac
[  369.634272]  __mutex_lock_slowpath+0x1c/0x28
[  369.634281]  mutex_lock+0x50/0x74
[  369.634306]  fops_vcodec_open+0x5c/0x2e0 [mtk_vcodec_dec
879370ff125adc9fa45bebb553dd6005c95bb957]
[  369.634307]  lzo_compress zram uinput xt_cgroup
[  369.634322]  v4l2_open+0xa8/0x104
[  369.634323]  xt_MASQUERADE mtk_vcodec_dec_hw cros_ec_rpmsg
[  369.634339]  chrdev_open+0x12c/0x1c4
[  369.634340]  mt7921e mt7921_common mt76_connac_lib mt76
[  369.634355]  do_dentry_open+0x114/0x37c
[  369.634367]  vfs_open+0x3c/0x48
[  369.634377]  path_openat+0x1c8/0x8ac
[  369.634378]  mtk_vcodec_dec v4l2_h264 mtk_vcodec_enc v4l2_vp9
[  369.634393]  do_filp_open+0x94/0x11c
[  369.634395]  uvcvideo mtk_vcodec_dbgfs mtk_mdp3
[  369.634409]  do_sys_openat2+0x88/0x220
[  369.634419]  do_sys_open+0x60/0x88
[  369.634420]  mtk_vcodec_common btusb mtk_vpu
[  369.634433]  __arm64_sys_openat+0x30/0x3c
[  369.634435]  btmtk videobuf2_vmalloc btintel videobuf2_dma_contig
[  369.634450]  el0_svc_common+0xcc/0x1cc
[  369.634452]  videobuf2_memops v4l2_mem2mem videobuf2_v4l2 btbcm
[  369.634465]  do_el0_svc+0x30/0x90
[  369.634467]  btrtl videobuf2_common mac80211 cros_ec_typec
[  369.634480]  el0_svc+0x10/0x1c
[  369.634481]  typec
[  369.634491] PDLOG 2024/01/27 21:48:10.904 P0 SNK Charger ???
15175mV max 15000mV / 3000mA
[  369.634492]  snd_sof_mt8195 mtk_scp
[  369.634506]  el0_sync_handler+0x78/0x108
[  369.634507]  mtk_rpmsg snd_sof_xtensa_dsp
[  369.634520]  el0_sync+0x184/0x1c0
[  369.634521]  rpmsg_core mtk_adsp_common adsp_pcm mtk_scp_ipi
snd_sof_of snd_sof snd_sof_utils ip6table_nat fuse bluetooth
ecdh_generic ecc cfg80211 iio_trig_sysfs cros_ec_lid_angle
cros_ec_sensors cros_ec_sensors_core industrialio_triggered_buffer
kfifo_buf cros_ec_sensorhub r8153_ecm cdc_ether usbnet r8152 mii
joydev
[  369.634539] CPU: 6 PID: 6520 Comm: ThreadPoolForeg Tainted: G
 W         5.10.208-24103-g572c076ef3bf #1
69a06d15b220b7bbb6ae94835957d4263c132312
[  369.634540] Hardware name: MediaTek Tomato board (DT)
[  369.634541] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO BTYPE=--)
[  369.634544] pc : vb2_buffer_done+0x184/0x228 [videobuf2_common]
[  369.634546] lr : vb2ops_vdec_stop_streaming+0x58/0x130 [mtk_vcodec_dec]
[  369.634547] sp : ffffffc015be3a40
[  369.634548] x29: ffffffc015be3a40 x28: 0000000000000013
[  369.634550] x27: ffffffc015be3c70
[  369.634554] Kernel panic - not syncing: hung_task: blocked tasks
[  369.634556] x26: ffffffd6141bea30
[  369.634563] x25: ffffff8d656e6020 x24: ffffff8d16fc0500
[  369.634573] CPU: 3 PID: 68 Comm: khungtaskd Tainted: G        W
    5.10.208-24103-g572c076ef3bf #1
69a06d15b220b7bbb6ae94835957d4263c132312
[  369.634574] x23: ffffff8d68cc94d0 x22: ffffff8d656e6328
[  369.634585] Hardware name: MediaTek Tomato board (DT)
[  369.634586] x21: 0000000000000000 x20: ffffff8d656e6208
[  369.634592] Call trace:
[  369.634593] x19: ffffff8d656e6000 x18: 0000000000001000
[  369.634604]  dump_backtrace+0x0/0x1e8
[  369.634605] x17: 6165642820314e4f x16: ffffffd68b3da1ac
[  369.634614]  show_stack+0x20/0x2c
[  369.634616] x15: 4c20736920747865 x14: 0000000000000003
[  369.634625]  dump_stack+0xd8/0x134
[  369.634626] x13: 0000000000000004 x12: 000000017a6a3d80
[  369.634635]  panic+0x168/0x3b4
[  369.634636] x11: c000000104dcc4c1 x10: 00000000ffffffff
[  369.634648]  hung_task_panic+0x0/0x3c
[  369.634649] x9 : ffffffd6141ba860 x8 : 0000000000000000
[  369.634660]  kthread+0x140/0x150
[  369.634662] x7 : 0000000000000000 x6 : 362e39363320205b
[  369.634671]  ret_from_fork+0x10/0x30
[  369.634673] x5 : ffffffd68c1a9e40 x4 : 0000000000000000
[  369.634676] x3 : ffffffc015be36a8 x2 : ffffffc015be36b0
[  369.634678] x1 : 0000000000000006 x0 : ffffff8d79780400
[  369.634680] Call trace:
[  369.634682]  vb2_buffer_done+0x184/0x228 [videobuf2_common
90d29a32bbd63b16e1c5ddef29383225f924f6e6]
[  369.634684]  vb2ops_vdec_stop_streaming+0x58/0x130 [mtk_vcodec_dec
879370ff125adc9fa45bebb553dd6005c95bb957]
[  369.634687] SMP: stopping secondary CPUs
[  369.634690]  __vb2_queue_cancel+0x40/0x1f0 [videobuf2_common
90d29a32bbd63b16e1c5ddef29383225f924f6e6]
[  369.634695]  vb2_core_streamoff+0x30/0xb4 [videobuf2_common
90d29a32bbd63b16e1c5ddef29383225f924f6e6]
[  369.634699]  vb2_streamoff+0x38/0x60 [videobuf2_v4l2
57948a05e97f8b4aaa75f86af62463f9372d2eda]
[  369.634702]  v4l2_m2m_streamoff+0x60/0x13c [v4l2_mem2mem
b612f8be320a497ae465ef738b2ab624e86ad82f]
[  369.634703]  v4l2_m2m_ioctl_streamoff+0x20/0x2c [v4l2_mem2mem
b612f8be320a497ae465ef738b2ab624e86ad82f]
[  369.634705]  v4l_streamoff+0x2c/0x38
[  369.634707]  __video_do_ioctl+0x2c4/0x3dc
[  369.634709]  video_usercopy+0x6d8/0xfac
[  369.634711]  video_ioctl2+0x20/0x2c
[  369.634712]  v4l2_ioctl+0x54/0x64
[  369.634714]  __arm64_sys_ioctl+0x98/0xd0
[  369.634716]  el0_svc_common+0xcc/0x1cc
[  369.634718]  do_el0_svc+0x30/0x90
[  369.634720]  el0_svc+0x10/0x1c
[  369.634722]  el0_sync_handler+0x78/0x108
[  369.634723]  el0_sync+0x184/0x1c0
[  369.634725] ---[ end trace bf910434181f5b65 ]---
[  369.634735] Kernel Offset: 0x167a800000 from 0xffffffc010000000
[  369.634747] PHYS_OFFSET: 0xfffffff400000000
[  369.634760] CPU features: 0x08040026,6a80aa38
[  369.634770] Memory Limit: none


On Thu, Jan 11, 2024 at 1:15?AM Benjamin Gaignard
<benjamin.gaignard at collabora.com> wrote:
>
>
> Le 11/01/2024 ? 08:17, Yunfei Dong a ?crit :
> > The request status of output queue will be set to MEDIA_REQUEST_STATE_COMPLETE
> > when user space dequeue output buffer. Then calling v4l2_ctrl_request_complete
> > will get below warning, need to call v4l2_ctrl_request_complete before
> > v4l2_m2m_buf_done.
> > Workqueue: core-decoder vdec_msg_queue_core_work [mtk_vcodec_dec]
> > pstate: 80c00089 (Nzcv daIf +PAN +UAO -TCO BTYPE=--)
> > pc : media_request_object_bind+0xa8/0x124
> > lr : media_request_object_bind+0x50/0x124
> > sp : ffffffc011393be0
> > x29: ffffffc011393be0 x28: 0000000000000000
> > x27: ffffff890c280248 x26: ffffffe21a71ab88
> > x25: 0000000000000000 x24: ffffff890c280280
> > x23: ffffff890c280280 x22: 00000000fffffff0
> > x21: 0000000000000000 x20: ffffff890260d280
> > x19: ffffff890260d2e8 x18: 0000000000001000
> > x17: 0000000000000400 x16: ffffffe21a4584a0
> > x15: 000000000053361d x14: 0000000000000018
> > x13: 0000000000000004 x12: ffffffa82427d000
> > x11: ffffffe21ac3fce0 x10: 0000000000000001
> > x9 : 0000000000000000 x8 : 0000000000000003
> > x7 : 0000000000000000 x6 : 000000000000003f
> > x5 : 0000000000000040 x4 : ffffff89052e7b98
> > x3 : 0000000000000000 x2 : 0000000000000001
> > x1 : 0000000000000000 x0 : 0000000000000000
> > Call trace:
> >   media_request_object_bind+0xa8/0x124
> >   v4l2_ctrl_request_bind+0xc4/0x168
> >   v4l2_ctrl_request_complete+0x198/0x1f4
> >   mtk_vdec_stateless_cap_to_disp+0x58/0x8c [mtk_vcodec_dec 245a7c1e48ff1b2451a50e1dfcb174262b6b462c]
> >   vdec_vp9_slice_core_decode+0x1c0/0x268 [mtk_vcodec_dec 245a7c1e48ff1b2451a50e1dfcb174262b6b462c]
> >   vdec_msg_queue_core_work+0x60/0x11c [mtk_vcodec_dec 245a7c1e48ff1b2451a50e1dfcb174262b6b462c]
> >   process_one_work+0x140/0x480
> >   worker_thread+0x12c/0x2f8
> >   kthread+0x13c/0x1d8
> >   ret_from_fork+0x10/0x30
> >
> > 'Fixes: 7b182b8d9c852 ("media: mediatek: vcodec: Refactor get and put capture buffer flow")'
> > Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
>
> Reviewed-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
>
> > ---
> >   .../mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h     |  3 ++-
> >   .../vcodec/decoder/mtk_vcodec_dec_stateless.c        | 12 +++++++-----
> >   .../vcodec/decoder/vdec/vdec_av1_req_lat_if.c        |  7 +++++--
> >   .../vcodec/decoder/vdec/vdec_h264_req_multi_if.c     |  3 ++-
> >   .../vcodec/decoder/vdec/vdec_hevc_req_multi_if.c     |  3 ++-
> >   .../vcodec/decoder/vdec/vdec_vp9_req_lat_if.c        |  6 ++++--
> >   .../mediatek/vcodec/decoder/vdec_msg_queue.h         |  2 ++
> >   7 files changed, 24 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
> > index 849b89dd205c..3f5b625330bc 100644
> > --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
> > +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
> > @@ -111,7 +111,8 @@ struct mtk_vcodec_dec_pdata {
> >       int (*flush_decoder)(struct mtk_vcodec_dec_ctx *ctx);
> >       struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_dec_ctx *ctx);
> >       void (*cap_to_disp)(struct mtk_vcodec_dec_ctx *ctx, int error,
> > -                         struct media_request *src_buf_req);
> > +                         struct media_request *src_buf_req,
> > +                         struct vb2_v4l2_buffer *vb2_v4l2_src);
> >
> >       const struct vb2_ops *vdec_vb2_ops;
> >
> > diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
> > index d54b3833790d..2efa34b6750b 100644
> > --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
> > +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
> > @@ -245,7 +245,8 @@ static const struct v4l2_frmsize_stepwise stepwise_fhd = {
> >   };
> >
> >   static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_dec_ctx *ctx, int error,
> > -                                        struct media_request *src_buf_req)
> > +                                        struct media_request *src_buf_req,
> > +                                        struct vb2_v4l2_buffer *vb2_v4l2_src)
> >   {
> >       struct vb2_v4l2_buffer *vb2_dst;
> >       enum vb2_buffer_state state;
> > @@ -266,6 +267,9 @@ static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_dec_ctx *ctx, int e
> >
> >       if (src_buf_req)
> >               v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
> > +
> > +     if (vb2_v4l2_src)
> > +             v4l2_m2m_buf_done(vb2_v4l2_src, state);
> >   }
> >
> >   static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_dec_ctx *ctx)
> > @@ -374,14 +378,12 @@ static void mtk_vdec_worker(struct work_struct *work)
> >       state = ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE;
> >       if (!IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch) ||
> >           ctx->current_codec == V4L2_PIX_FMT_VP8_FRAME) {
> > -             v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx, state);
> >               if (src_buf_req)
> >                       v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
> > +             v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx, state);
> >       } else {
> > -             if (ret != -EAGAIN) {
> > +             if (ret != -EAGAIN)
> >                       v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
> > -                     v4l2_m2m_buf_done(vb2_v4l2_src, state);
> > -             }
> >               v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
> >       }
> >   }
> > diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
> > index 2b6a5adbc419..f277b907c345 100644
> > --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
> > +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
> > @@ -1064,6 +1064,8 @@ static int vdec_av1_slice_setup_lat_from_src_buf(struct vdec_av1_slice_instance
> >               return -EINVAL;
> >
> >       lat_buf->src_buf_req = src->vb2_buf.req_obj.req;
> > +     lat_buf->vb2_v4l2_src = src;
> > +
> >       dst = &lat_buf->ts_info;
> >       v4l2_m2m_buf_copy_metadata(src, dst, true);
> >       vsi->frame.cur_ts = dst->vb2_buf.timestamp;
> > @@ -2187,7 +2189,7 @@ static int vdec_av1_slice_core_decode(struct vdec_lat_buf *lat_buf)
> >                      &instance->core_vsi->trans.dma_addr_end);
> >       vdec_msg_queue_update_ube_rptr(&ctx->msg_queue, instance->core_vsi->trans.dma_addr_end);
> >
> > -     ctx->dev->vdec_pdata->cap_to_disp(ctx, 0, lat_buf->src_buf_req);
> > +     ctx->dev->vdec_pdata->cap_to_disp(ctx, 0, lat_buf->src_buf_req, lat_buf->vb2_v4l2_src);
> >
> >       return 0;
> >
> > @@ -2196,7 +2198,8 @@ static int vdec_av1_slice_core_decode(struct vdec_lat_buf *lat_buf)
> >       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, 1, lat_buf->src_buf_req);
> > +             ctx->dev->vdec_pdata->cap_to_disp(ctx, 1, lat_buf->src_buf_req,
> > +                                               lat_buf->vb2_v4l2_src);
> >
> >       return ret;
> >   }
> > diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
> > index 0e741e0dc8ba..7033999018ca 100644
> > --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
> > +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
> > @@ -533,7 +533,7 @@ static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf)
> >
> >   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, !!err, lat_buf->src_buf_req);
> > +     ctx->dev->vdec_pdata->cap_to_disp(ctx, !!err, lat_buf->src_buf_req, lat_buf->vb2_v4l2_src);
> >       mtk_vdec_debug(ctx, "core decode done err=%d", err);
> >       ctx->decoded_frame_cnt++;
> >       return 0;
> > @@ -606,6 +606,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
> >
> >       inst->vsi->dec.nal_info = buf[nal_start_idx];
> >       lat_buf->src_buf_req = src_buf_info->m2m_buf.vb.vb2_buf.req_obj.req;
> > +     lat_buf->vb2_v4l2_src = &src_buf_info->m2m_buf.vb;
> >       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);
> > diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
> > index 06ed47df693b..67fe3c4bfac3 100644
> > --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
> > +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
> > @@ -742,6 +742,7 @@ static int vdec_hevc_slice_setup_lat_buffer(struct vdec_hevc_slice_inst *inst,
> >
> >       src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
> >       lat_buf->src_buf_req = src_buf_info->m2m_buf.vb.vb2_buf.req_obj.req;
> > +     lat_buf->vb2_v4l2_src = &src_buf_info->m2m_buf.vb;
> >       v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb, &lat_buf->ts_info, true);
> >
> >       *res_chg = inst->resolution_changed;
> > @@ -961,7 +962,7 @@ static int vdec_hevc_slice_core_decode(struct vdec_lat_buf *lat_buf)
> >
> >   vdec_dec_end:
> >       vdec_msg_queue_update_ube_rptr(&lat_buf->ctx->msg_queue, share_info->trans.dma_addr_end);
> > -     ctx->dev->vdec_pdata->cap_to_disp(ctx, !!err, lat_buf->src_buf_req);
> > +     ctx->dev->vdec_pdata->cap_to_disp(ctx, !!err, lat_buf->src_buf_req, lat_buf->vb2_v4l2_src);
> >       mtk_vdec_debug(ctx, "core decode done err=%d", err);
> >       ctx->decoded_frame_cnt++;
> >       return 0;
> > diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
> > index 69d37b93bd35..a7734d032269 100644
> > --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
> > +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
> > @@ -723,6 +723,7 @@ static int vdec_vp9_slice_setup_lat_from_src_buf(struct vdec_vp9_slice_instance
> >               return -EINVAL;
> >
> >       lat_buf->src_buf_req = src->vb2_buf.req_obj.req;
> > +     lat_buf->vb2_v4l2_src = src;
> >
> >       dst = &lat_buf->ts_info;
> >       v4l2_m2m_buf_copy_metadata(src, dst, true);
> > @@ -2188,7 +2189,7 @@ static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf)
> >       mtk_vdec_debug(ctx, "core dma_addr_end 0x%lx\n",
> >                      (unsigned long)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, 0, lat_buf->src_buf_req);
> > +     ctx->dev->vdec_pdata->cap_to_disp(ctx, 0, lat_buf->src_buf_req, lat_buf->vb2_v4l2_src);
> >
> >       return 0;
> >
> > @@ -2198,7 +2199,8 @@ static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf)
> >               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, 1, lat_buf->src_buf_req);
> > +                     ctx->dev->vdec_pdata->cap_to_disp(ctx, 1, lat_buf->src_buf_req,
> > +                                                       lat_buf->vb2_v4l2_src);
> >       }
> >       return ret;
> >   }
> > diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.h
> > index 1d9beb9e4a14..b0f2443d186f 100644
> > --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.h
> > +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.h
> > @@ -55,6 +55,7 @@ struct vdec_msg_queue_ctx {
> >    * @rd_mv_addr:     mv addr for av1 lat hardware output, core hardware input
> >    * @tile_addr:      tile buffer for av1 core input
> >    * @ts_info: need to set timestamp from output to capture
> > + * @vb2_v4l2_src: the vb2 buffer of output queue
> >    * @src_buf_req: output buffer media request object
> >    *
> >    * @private_data: shared information used to lat and core hardware
> > @@ -71,6 +72,7 @@ struct vdec_lat_buf {
> >       struct mtk_vcodec_mem rd_mv_addr;
> >       struct mtk_vcodec_mem tile_addr;
> >       struct vb2_v4l2_buffer ts_info;
> > +     struct vb2_v4l2_buffer *vb2_v4l2_src;
> >       struct media_request *src_buf_req;
> >
> >       void *private_data;


From tim at feathertop.org  Wed Feb 14 15:37:30 2024
From: tim at feathertop.org (Tim Lunn)
Date: Thu, 15 Feb 2024 10:37:30 +1100
Subject: [PATCH 2/4] dt-bindings: arm: rockchip: Correct vendor for Banana
 Pi R2 Pro
In-Reply-To: <20240214040731.3069111-3-tim@feathertop.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
 <20240214040731.3069111-3-tim@feathertop.org>
Message-ID: <3f1c1f14-9a6e-4d07-8311-59d7b55e1c9d@feathertop.org>


On 2/14/24 15:07, Tim Lunn wrote:
> The vendor for this board was incorrectly listed as Rockchip. Fix this
> now while they are not used anywhere, in the future they may be used by
> bootloader to select dts.
>
> Update the vendor to Sinovoip.
>
> Signed-off-by: Tim Lunn <tim at feathertop.org>
Fixes: 8ad885126daa ("dt-bindings: rockchip: Add BananaPi R2 Pro Board")
> ---
>
>   Documentation/devicetree/bindings/arm/rockchip.yaml | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
> index 29f922f3ca4e..89261b9601ce 100644
> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> @@ -940,9 +940,9 @@ properties:
>             - const: rockchip,rk3568-evb1-v10
>             - const: rockchip,rk3568
>   
> -      - description: Rockchip RK3568 Banana Pi R2 Pro
> +      - description: Sinovoip RK3568 Banana Pi R2 Pro
>           items:
> -          - const: rockchip,rk3568-bpi-r2pro
> +          - const: sinovoip,rk3568-bpi-r2pro
>             - const: rockchip,rk3568
>   
>         - description: Sonoff iHost Smart Home Hub


From tim at feathertop.org  Wed Feb 14 15:45:39 2024
From: tim at feathertop.org (Tim Lunn)
Date: Thu, 15 Feb 2024 10:45:39 +1100
Subject: [PATCH 1/4] dt-bindings: arm: rockchip: Correct vendor for Orange
 Pi RK3399 board
In-Reply-To: <20240214040731.3069111-2-tim@feathertop.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
 <20240214040731.3069111-2-tim@feathertop.org>
Message-ID: <0e6cee7c-9726-4d45-a06a-a8882e271e7b@feathertop.org>


On 2/14/24 15:07, Tim Lunn wrote:
> The vendor for this board was incorrectly listed as Rockchip. Fix this
> now while they are not used anywhere, in the future they may be used by
> bootloader to select dts.
>
> Update the vendor to Xunlong.
>
> Signed-off-by: Tim Lunn <tim at feathertop.org>
Fixes: 08b64bd2c681 ("arm64: dts: rockchip: Add support for the Orange 
Pi RK3399 board")
> ---
>
>   Documentation/devicetree/bindings/arm/rockchip.yaml | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
> index 5cf5cbef2cf5..29f922f3ca4e 100644
> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> @@ -626,9 +626,9 @@ properties:
>             - const: openailab,eaidk-610
>             - const: rockchip,rk3399
>   
> -      - description: Orange Pi RK3399 board
> +      - description: Xunlong Orange Pi RK3399 board
>           items:
> -          - const: rockchip,rk3399-orangepi
> +          - const: xunlong,rk3399-orangepi
>             - const: rockchip,rk3399
>   
>         - description: Phytec phyCORE-RK3288 Rapid Development Kit


From swboyd at chromium.org  Wed Feb 14 15:51:17 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Wed, 14 Feb 2024 15:51:17 -0800
Subject: [PATCH 04/22] usb: core: Set connect_type of ports based on DT node
In-Reply-To: <CAD=FV=UuunNnXJ0kAzRPVy0DX7Wv2eQOa-fMJQ-aKtaGnyQaQA@mail.gmail.com>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-5-swboyd@chromium.org>
 <CAD=FV=UuunNnXJ0kAzRPVy0DX7Wv2eQOa-fMJQ-aKtaGnyQaQA@mail.gmail.com>
Message-ID: <CAE-0n51b9=BJv6PMmsdLDT7tcgKT63qrqNknp-CQd5BOb1dhjA@mail.gmail.com>

Quoting Doug Anderson (2024-02-13 16:03:11)
> Hi,
>
> On Fri, Feb 9, 2024 at 11:09?PM Stephen Boyd <swboyd at chromium.org> wrote:
> >
> > When a USB hub is described in DT, such as any device that matches the
> > onboard-hub driver, the connect_type is set to "unknown" or
> > USB_PORT_CONNECT_TYPE_UNKNOWN. This makes any device plugged into that
> > USB port report their 'removable' device attribute as "unknown". Improve
> > the connect_type attribute for ports, and in turn the removable
> > attribute for USB devices, by looking for child devices with a reg
> > property or an OF graph when the device is described in DT.
> >
> > If the graph exists, endpoints that are connected to a remote node must
> > be something like a usb-{a,b,c}-connector compatible node, or an
> > intermediate node like a redriver, and not a hardwired USB device on the
> > board. Set the connect_type to USB_PORT_CONNECT_TYPE_HOT_PLUG in this
> > case because the device is going to be plugged in. Set the connect_type
> > to USB_PORT_CONNECT_TYPE_HARD_WIRED if there's a child node for the port
> > like 'device at 2' for port2. Set the connect_type to USB_PORT_NOT_USED if
> > there isn't an endpoint or child node corresponding to the port number.
>
> The above sounds good, but then I look at patch #18 ("dt-bindings:
> chrome: Add binding for ChromeOS Pogo pin connector") and patch #22
> ("arm64: dts: qcom: sc7180-trogdor: Wire up USB and DP to
> usb-c-connectors") and it makes my Spidey Sense tingle.
>
> Specifically, I _think_ if a port is "hard wired" that can sometimes
> tell the system that the port is a bit more trusted. In the case of
> the "pogo" pins on detachables, though, I don't _think_ there's
> anything that prevents someone from making a "pogo to USB A port"
> adapter and then you could plug anything you wanted into the pogo
> port. If there's any extra trust given to these "internal" ports a
> nefarious attacker could presumably abuse that trust for the pogo
> pins.

The pogo pins on detachables are connected via the OF graph, so they are
only ever going to be either "not connected" or "hotplug". They can't
become "hard wired" because they're not a child node with a reg property
corresponding to the USB port.

>
> I have no idea if this is a realistic concern or not. I'm about 95%
> sure that hardwired "PCIe" ports get extra trust and get "deferred
> IOMMU flush" enabled and, in the case of PCIe, that actually is a real
> security hole. For USB, though, I think the system is more isolated by
> the USB host controller so I'm not sure that there is any extra trust
> given to "hard wired" ports. ...so maybe the answer here is to just
> ignore my rambling. ...or maybe the answer here is that everything is
> fine but patches #18 and #22 should be modified not to cause the pogo
> pins to be considered as "hard wired" since they really aren't...
>

Pogo pins should be considered hot plug with this patch series, but I
will double check that I didn't mess up that logic.


From swboyd at chromium.org  Wed Feb 14 16:07:43 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Wed, 14 Feb 2024 16:07:43 -0800
Subject: [PATCH 18/22] dt-bindings: chrome: Add binding for ChromeOS Pogo
 pin connector
In-Reply-To: <18ac05fb-a78d-4e95-a73d-461f509cdc5f@linaro.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-19-swboyd@chromium.org>
 <18ac05fb-a78d-4e95-a73d-461f509cdc5f@linaro.org>
Message-ID: <CAE-0n50Y_GRMt8km=XjGC5Zm5dvb2t4gccznJn9HEFS4p7y8fQ@mail.gmail.com>

Quoting Krzysztof Kozlowski (2024-02-11 05:39:36)
> On 10/02/2024 08:09, Stephen Boyd wrote:
> > diff --git a/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml b/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml
> > new file mode 100644
> > index 000000000000..5ba68fd95fcd
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml
> > @@ -0,0 +1,61 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
[...]
>
> > +properties:
> > +  compatible:
> > +    const: google,pogo-pin-connector
> > +
> > +  "#address-cells":
> > +    const: 1
> > +
> > +  "#size-cells":
> > +    const: 0
> > +
> > +  port:
> > +    $ref: /schemas/graph.yaml#/properties/port
> > +    description: Connection to USB2 port providing USB signals
> > +    required:
> > +      - endpoint
>
> Drop required.

Why? I'd like to make it so you can't have the node defined without
connecting it up to the rest of the system. Is that bad?

>
>
> > +
> > +patternProperties:
> > +  "^keyboard@[0-9a-f]{1,2}$":
> > +    description: The detachable keyboard
>
> If this is detachable why do you define it in DT? Only hard-wired USB
> devices, which need some sort of special handling. are described in DT.

>From the commit text:

 We expect to find a keyboard on the other side of this connector with a
 specific vid/pid, so describe that as a child device at the port of the
 usb device connected upstream.

ChromeOS userspace is checking that the connected device downstream of
this port has the expected vid/pid to quickly rule out USB keyboards
that aren't the detachable keyboard. I wanted to express this in DT so
that it didn't live in ChromeOS userspace forever.


From swboyd at chromium.org  Wed Feb 14 16:10:36 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Wed, 14 Feb 2024 16:10:36 -0800
Subject: [PATCH 18/22] dt-bindings: chrome: Add binding for ChromeOS Pogo
 pin connector
In-Reply-To: <CAD=FV=WE4bgwTWTKjPbQR9RCt-SEVZXfQtXoaXAjvTiZiMr=wA@mail.gmail.com>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-19-swboyd@chromium.org>
 <CAD=FV=WE4bgwTWTKjPbQR9RCt-SEVZXfQtXoaXAjvTiZiMr=wA@mail.gmail.com>
Message-ID: <CAE-0n53H-WPSr4tnmjq2Z54daKYD3PPzmxy28GsYAd29MTXiWA@mail.gmail.com>

Quoting Doug Anderson (2024-02-13 17:17:34)
> Hi,
>
> On Fri, Feb 9, 2024 at 11:10?PM Stephen Boyd <swboyd at chromium.org> wrote:
> >
> > Describe the set of pins used to connect the detachable keyboard on
> > detachable ChromeOS devices. The set of pins is called the "pogo pins".
> > It's basically USB 2.0 with an extra pin for base detection. We expect
> > to find a keyboard on the other side of this connector with a specific
> > vid/pid, so describe that as a child device at the port of the usb
> > device connected upstream.
>
> Can you remind me what the side effects would be if a different
> VID/PID shows up there? I know it's not an end-user scenario, but I
> have a pre-production "coachz" keyboard that's actually programmed
> incorrectly and shows up as the wrong PID. Presumably I could either
> throw the old hardware away or figure out a way to re-program it and
> it's really not a big deal, but just curious what happens...

As far as I know nothing happens besides ChromeOS userspace treats the
keyboard as "external" so things like smarter base detection, e.g.
wraparound keyboard detection or kickstand mode, may not work. I think
you get a popup box telling you the keyboard isn't the trusted one.


From tim at feathertop.org  Wed Feb 14 16:28:33 2024
From: tim at feathertop.org (Tim Lunn)
Date: Thu, 15 Feb 2024 11:28:33 +1100
Subject: [PATCH 0/4] Fix vendor strings on Rockchip boards
In-Reply-To: <20240214-moocher-womanless-21201b67b76d@spud>
References: <20240214040731.3069111-1-tim@feathertop.org>
 <c03220db663279c9e83bab81f3d829e7@manjaro.org>
 <e952d127-b12d-4b5a-838b-807a876db707@feathertop.org>
 <20240214-moocher-womanless-21201b67b76d@spud>
Message-ID: <cd648b49-b954-45e5-aba7-dee85c0785e5@feathertop.org>

Hi Conor,

On 2/15/24 05:12, Conor Dooley wrote:
> On Wed, Feb 14, 2024 at 03:27:08PM +1100, Tim Lunn wrote:
>> Hi Dragan,
>>
>> On 2/14/24 15:14, Dragan Simic wrote:
>>> Hello Tim,
>>>
>>> On 2024-02-14 05:07, Tim Lunn wrote:
>>>> A couple of rockchip boards incorrectly list their vendor as Rockchip
>>>> when they are in fact not manufactured by Rockchip.
>>>>
>>>> Fix the vendor strings to correctly list the manufacturer
>>> Just checking, have you verified that the old, incorrect "compatible"
>>> strings from the board dts files aren't used anywhere in the kernel code,
>>> such as in some drivers?
>>>
>> Yes I checked that, there are no remaining references to the old/incorrect
>> compatible strings in kernel code
> What about other code? Like a BSD or a bootloader? If nothing is using
> them
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
>
> Fixes tags I think wouldn't go amiss, but I'm not expecting a resend
> with them.
I've added the fixes tags to the email thread.

Regards
 ? Tim
>
> Cheers,
> Conor.


From swboyd at chromium.org  Wed Feb 14 16:35:15 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Wed, 14 Feb 2024 16:35:15 -0800
Subject: [PATCH 21/22] arm64: dts: qcom: sc7180-trogdor: Make
 clamshell/detachable fragments
In-Reply-To: <CAD=FV=WovmtKFiG0OMzpus9=z8UJ+Ev3TrwsVia8pSegvjwUiw@mail.gmail.com>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-22-swboyd@chromium.org>
 <CAD=FV=WovmtKFiG0OMzpus9=z8UJ+Ev3TrwsVia8pSegvjwUiw@mail.gmail.com>
Message-ID: <CAE-0n52qgKrasAw1AbZ97zMk1xz6P4KkxNLi4cBpNKy5wWu+1A@mail.gmail.com>

Quoting Doug Anderson (2024-02-13 15:34:38)
> Hi,
>
> On Fri, Feb 9, 2024 at 11:10?PM Stephen Boyd <swboyd at chromium.org> wrote:
> >
> > + * Copyright 2024 Google LLC.
> > + */
> > +
>
> Tiny nit: should this file have a comment like "/* This file must be
> included after sc7180-trogdor.dtsi */" like the clamshell file?

I was copying the comment for the keyboard include file, but the
detachable doesn't have that include. I can add it here though, that's
fine.

>
>
> > diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
> > index e9f213d27711..c3fd6760de7a 100644
> > --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
> > +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
> > @@ -5,8 +5,7 @@
> >   * Copyright 2020 Google LLC.
> >   */
> >
> > -/* This file must be included after sc7180-trogdor.dtsi */
> > -#include <arm/cros-ec-keyboard.dtsi>
> > +#include "sc7180-trogdor-clamshell.dtsi"
>
> nit: Not that it was terribly consistent before, but in lazor you
> remove the "This file must be included after sc7180-trogdor.dtsi"
> because (I guess) it moved to the clamshell file. However, in other
> dts files you don't remove it. pazquel has the exact same comment and
> it's not removed. Pompom has a slight variant of the comment where it
> explains the reason (to modify cros_ec) and it's not removed. Could
> make it more consistent...

Sure I can make it more consistent with the explanation. Which way to go
though? Remove it from the boards and put it into the fragment files?


From dianders at chromium.org  Wed Feb 14 16:39:45 2024
From: dianders at chromium.org (Doug Anderson)
Date: Wed, 14 Feb 2024 16:39:45 -0800
Subject: [PATCH 21/22] arm64: dts: qcom: sc7180-trogdor: Make
 clamshell/detachable fragments
In-Reply-To: <CAE-0n52qgKrasAw1AbZ97zMk1xz6P4KkxNLi4cBpNKy5wWu+1A@mail.gmail.com>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-22-swboyd@chromium.org>
 <CAD=FV=WovmtKFiG0OMzpus9=z8UJ+Ev3TrwsVia8pSegvjwUiw@mail.gmail.com> <CAE-0n52qgKrasAw1AbZ97zMk1xz6P4KkxNLi4cBpNKy5wWu+1A@mail.gmail.com>
Message-ID: <CAD=FV=XAcXs1hmJB_Rd42+Q3gQDuw=2L+igCyWnnnSYtqdifPA@mail.gmail.com>

Hi,

On Wed, Feb 14, 2024 at 4:35?PM Stephen Boyd <swboyd at chromium.org> wrote:
>
> > > -/* This file must be included after sc7180-trogdor.dtsi */
> > > -#include <arm/cros-ec-keyboard.dtsi>
> > > +#include "sc7180-trogdor-clamshell.dtsi"
> >
> > nit: Not that it was terribly consistent before, but in lazor you
> > remove the "This file must be included after sc7180-trogdor.dtsi"
> > because (I guess) it moved to the clamshell file. However, in other
> > dts files you don't remove it. pazquel has the exact same comment and
> > it's not removed. Pompom has a slight variant of the comment where it
> > explains the reason (to modify cros_ec) and it's not removed. Could
> > make it more consistent...
>
> Sure I can make it more consistent with the explanation. Which way to go
> though? Remove it from the boards and put it into the fragment files?

I don't care too much. I guess I'd lean toward just putting it in the
fragment files just to copy it fewer times.

-Doug


From swboyd at chromium.org  Wed Feb 14 16:44:53 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Wed, 14 Feb 2024 16:44:53 -0800
Subject: [PATCH 01/22] dt-bindings: gpio: Add binding for ChromeOS EC GPIO controller
In-Reply-To: <a6ce4811-2a3d-4df6-aad3-9942a1bcfedd@linaro.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-2-swboyd@chromium.org>
 <a6ce4811-2a3d-4df6-aad3-9942a1bcfedd@linaro.org>
Message-ID: <CAE-0n50Ms_QcscgGrFe55O-j5j+GA+GvvDmp=Qo60bcSD9VxUQ@mail.gmail.com>

Quoting Krzysztof Kozlowski (2024-02-11 05:26:33)
> On 10/02/2024 08:09, Stephen Boyd wrote:
> > The ChromeOS embedded controller (EC) supports setting the state of
> > GPIOs when the system is unlocked, and getting the state of GPIOs in all
> > cases. The GPIOs are on the EC itself, so the EC acts similar to a GPIO
> > expander. Add a binding to describe these GPIOs in DT so that other
> > devices described in DT can read the GPIOs on the EC.
>
> ...
>
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    spi {
> > +      #address-cells = <1>;
> > +      #size-cells = <0>;
> > +
> > +      cros-ec at 0 {
> > +        compatible = "google,cros-ec-spi";
> > +        reg = <0>;
> > +        interrupts = <101 0>;
>
> This is should be proper define but then are you sure interrupt is type
> NONE? Does not look right.
>

I copied this from cros-ec-typec.yaml so I'll have to fix them all!


From chunkuang.hu at kernel.org  Wed Feb 14 16:49:23 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 15 Feb 2024 00:49:23 +0000
Subject: [PATCH 1/9] soc: mediatek: cmdq: Remove unused helper funciton
In-Reply-To: <20240215004931.3808-1-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
Message-ID: <20240215004931.3808-2-chunkuang.hu@kernel.org>

cmdq_pkt_create(), cmdq_pkt_destroy(), and cmdq_pkt_flush_async()
are not used by all client drivers (MediaTek drm driver and
MediaTek mdp3 driver), so remove them.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 59 --------------------------
 include/linux/soc/mediatek/mtk-cmdq.h  | 40 -----------------
 2 files changed, 99 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index b0cd071c4719..67e17974d1e6 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -105,50 +105,6 @@ void cmdq_mbox_destroy(struct cmdq_client *client)
 }
 EXPORT_SYMBOL(cmdq_mbox_destroy);
 
-struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
-{
-	struct cmdq_pkt *pkt;
-	struct device *dev;
-	dma_addr_t dma_addr;
-
-	pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
-	if (!pkt)
-		return ERR_PTR(-ENOMEM);
-	pkt->va_base = kzalloc(size, GFP_KERNEL);
-	if (!pkt->va_base) {
-		kfree(pkt);
-		return ERR_PTR(-ENOMEM);
-	}
-	pkt->buf_size = size;
-	pkt->cl = (void *)client;
-
-	dev = client->chan->mbox->dev;
-	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
-				  DMA_TO_DEVICE);
-	if (dma_mapping_error(dev, dma_addr)) {
-		dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
-		kfree(pkt->va_base);
-		kfree(pkt);
-		return ERR_PTR(-ENOMEM);
-	}
-
-	pkt->pa_base = dma_addr;
-
-	return pkt;
-}
-EXPORT_SYMBOL(cmdq_pkt_create);
-
-void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
-{
-	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
-
-	dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
-			 DMA_TO_DEVICE);
-	kfree(pkt->va_base);
-	kfree(pkt);
-}
-EXPORT_SYMBOL(cmdq_pkt_destroy);
-
 static int cmdq_pkt_append_command(struct cmdq_pkt *pkt,
 				   struct cmdq_instruction inst)
 {
@@ -426,19 +382,4 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 }
 EXPORT_SYMBOL(cmdq_pkt_finalize);
 
-int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
-{
-	int err;
-	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
-
-	err = mbox_send_message(client->chan, pkt);
-	if (err < 0)
-		return err;
-	/* We can send next packet immediately, so just call txdone. */
-	mbox_client_txdone(client->chan, 0);
-
-	return 0;
-}
-EXPORT_SYMBOL(cmdq_pkt_flush_async);
-
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 649955d2cf5c..6c42d817d368 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -59,21 +59,6 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, int index);
  */
 void cmdq_mbox_destroy(struct cmdq_client *client);
 
-/**
- * cmdq_pkt_create() - create a CMDQ packet
- * @client:	the CMDQ mailbox client
- * @size:	required CMDQ buffer size
- *
- * Return: CMDQ packet pointer
- */
-struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size);
-
-/**
- * cmdq_pkt_destroy() - destroy the CMDQ packet
- * @pkt:	the CMDQ packet
- */
-void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
-
 /**
  * cmdq_pkt_write() - append write command to the CMDQ packet
  * @pkt:	the CMDQ packet
@@ -266,19 +251,6 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
  */
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
 
-/**
- * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
- *                          packet and call back at the end of done packet
- * @pkt:	the CMDQ packet
- *
- * Return: 0 for success; else the error code is returned
- *
- * Trigger CMDQ to asynchronously execute the CMDQ packet and call back
- * at the end of done packet. Note that this is an ASYNC function. When the
- * function returned, it may or may not be finished.
- */
-int cmdq_pkt_flush_async(struct cmdq_pkt *pkt);
-
 #else /* IS_ENABLED(CONFIG_MTK_CMDQ) */
 
 static inline int cmdq_dev_get_client_reg(struct device *dev,
@@ -294,13 +266,6 @@ static inline struct cmdq_client *cmdq_mbox_create(struct device *dev, int index
 
 static inline void cmdq_mbox_destroy(struct cmdq_client *client) { }
 
-static inline  struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
-{
-	return ERR_PTR(-EINVAL);
-}
-
-static inline void cmdq_pkt_destroy(struct cmdq_pkt *pkt) { }
-
 static inline int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
 {
 	return -ENOENT;
@@ -384,11 +349,6 @@ static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 	return -EINVAL;
 }
 
-static inline int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
-{
-	return -EINVAL;
-}
-
 #endif /* IS_ENABLED(CONFIG_MTK_CMDQ) */
 
 #endif	/* __MTK_CMDQ_H__ */
-- 
2.34.1



From chunkuang.hu at kernel.org  Wed Feb 14 16:49:24 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 15 Feb 2024 00:49:24 +0000
Subject: [PATCH 2/9] soc: mediatek: cmdq: Add parameter shift_pa to cmdq_pkt_jump()
In-Reply-To: <20240215004931.3808-1-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
Message-ID: <20240215004931.3808-3-chunkuang.hu@kernel.org>

In original design, cmdq_pkt_jump() call cmdq_get_shift_pa() every
time to get shift_pa. But the shift_pa is constant value for each
SoC, so client driver just need to call cmdq_get_shift_pa() once
and pass shift_pa to cmdq_pkt_jump() to prevent frequent function
call.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 5 ++---
 include/linux/soc/mediatek/mtk-cmdq.h  | 6 ++++--
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 67e17974d1e6..ed4ef95adf5b 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -348,14 +348,13 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
-int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 {
 	struct cmdq_instruction inst = {};
 
 	inst.op = CMDQ_CODE_JUMP;
 	inst.offset = CMDQ_JUMP_RELATIVE;
-	inst.value = addr >>
-		cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
+	inst.value = addr >> shift_pa;
 	return cmdq_pkt_append_command(pkt, inst);
 }
 EXPORT_SYMBOL(cmdq_pkt_jump);
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 6c42d817d368..6215191a328d 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -238,10 +238,12 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
  *		     a physical address which should contains more instruction.
  * @pkt:        the CMDQ packet
  * @addr:       physical address of target instruction buffer
+ * @shift_pa:	shift bits of physical address in CMDQ instruction. This value
+ *		is got by cmdq_get_shift_pa().
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
 
 /**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
@@ -339,7 +341,7 @@ static inline int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
 	return -EINVAL;
 }
 
-static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 {
 	return -EINVAL;
 }
-- 
2.34.1



From chunkuang.hu at kernel.org  Wed Feb 14 16:49:22 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 15 Feb 2024 00:49:22 +0000
Subject: [PATCH 0/9] Remove cl in struct cmdq_pkt
Message-ID: <20240215004931.3808-1-chunkuang.hu@kernel.org>

cl in struct cmdq_pkt is used to store struct cmdq_client, but every client
driver has the struct cmdq_client information, so it's not necessary to
store struct cmdq_client in struct cmdq_pkt. Because mailbox maintainer
do not like to mix mailbox patch with other patches in a series, so
mailbox patch [1] would be sent independently.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/commit/?h=mediatek-cmdq8&id=a1b2f7a7488285975c1f439086f1c4cc51a13bb9

Chun-Kuang Hu (9):
  soc: mediatek: cmdq: Remove unused helper funciton
  soc: mediatek: cmdq: Add parameter shift_pa to cmdq_pkt_jump()
  soc: mediatek: cmdq: Add cmdq_pkt_eoc() helper function
  soc: mediatek: cmdq: Add cmdq_pkt_nop() helper function
  drm/mediatek: Drop calling cmdq_pkt_finalize()
  media: platform: mtk-mdp3: drop calling cmdq_pkt_finalize()
  soc: mediatek: cmdq: Remove cmdq_pkt_finalize() helper function
  drm/mediatek: Do not store struct cmdq_client in struct cmdq_pkt
  media: platform: mtk-mdp3: do not store struct cmdq_client in struct
    cmdq_pkt

 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       |  9 +-
 .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c    | 14 ++-
 .../platform/mediatek/mdp3/mtk-mdp3-core.c    |  2 +
 .../platform/mediatek/mdp3/mtk-mdp3-core.h    |  1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c        | 85 +++----------------
 include/linux/soc/mediatek/mtk-cmdq.h         | 50 ++++-------
 6 files changed, 39 insertions(+), 122 deletions(-)

-- 
2.34.1



From chunkuang.hu at kernel.org  Wed Feb 14 16:49:25 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 15 Feb 2024 00:49:25 +0000
Subject: [PATCH 3/9] soc: mediatek: cmdq: Add cmdq_pkt_eoc() helper function
In-Reply-To: <20240215004931.3808-1-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
Message-ID: <20240215004931.3808-4-chunkuang.hu@kernel.org>

cmdq_pkt_eoc() append eoc command to CMDQ packet. eoc command
would ask GCE to generate IRQ. It's usually appended to the end
of packet to notify all command in the packet is done.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 10 ++++++++++
 include/linux/soc/mediatek/mtk-cmdq.h  | 15 +++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index ed4ef95adf5b..e982997117c2 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -359,6 +359,16 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 }
 EXPORT_SYMBOL(cmdq_pkt_jump);
 
+int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
+{
+	struct cmdq_instruction inst = { {0} };
+
+	inst.op = CMDQ_CODE_EOC;
+	inst.value = CMDQ_EOC_IRQ_EN;
+	return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_eoc);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
 	struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 6215191a328d..a67f719dec0b 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -245,6 +245,16 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
  */
 int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
 
+/**
+ * cmdq_pkt_eoc() - Append eoc command to the CMDQ packet, ask GCE
+ *		    to generate IRQ. It's usually appended to the end of
+ *		    packet to notify that all command in the packet is done.
+ * @pkt:	the CMDQ packet
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
+
 /**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:	the CMDQ packet
@@ -346,6 +356,11 @@ static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_
 	return -EINVAL;
 }
 
+static inline int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
+{
+	return -EINVAL;
+}
+
 static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
 	return -EINVAL;
-- 
2.34.1



From chunkuang.hu at kernel.org  Wed Feb 14 16:49:26 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 15 Feb 2024 00:49:26 +0000
Subject: [PATCH 4/9] soc: mediatek: cmdq: Add cmdq_pkt_nop() helper function
In-Reply-To: <20240215004931.3808-1-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
Message-ID: <20240215004931.3808-5-chunkuang.hu@kernel.org>

cmdq_pkt_nop() append nop command to the packet. nop command ask
GCE to do no operation.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 11 +++++++++++
 include/linux/soc/mediatek/mtk-cmdq.h  | 16 ++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index e982997117c2..1be950b4ec7f 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -369,6 +369,17 @@ int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
 }
 EXPORT_SYMBOL(cmdq_pkt_eoc);
 
+int cmdq_pkt_nop(struct cmdq_pkt *pkt, u8 shift_pa)
+{
+	struct cmdq_instruction inst = { {0} };
+
+	/* Jumping to next instruction is equal to no operation */
+	inst.op = CMDQ_CODE_JUMP;
+	inst.value = CMDQ_INST_SIZE >> shift_pa;
+	return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_nop);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
 	struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index a67f719dec0b..8179ba5238f9 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -255,6 +255,17 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
  */
 int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
 
+/**
+ * cmdq_pkt_nop() - Append nop command to the CMDQ packet, ask GCE
+ *		    to do no operation.
+ * @pkt:	the CMDQ packet
+ * @shift_pa:	shift bits of physical address in CMDQ instruction. This value
+ *		is got by cmdq_get_shift_pa().
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_nop(struct cmdq_pkt *pkt, u8 shift_pa);
+
 /**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:	the CMDQ packet
@@ -361,6 +372,11 @@ static inline int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
 	return -EINVAL;
 }
 
+static inline int cmdq_pkt_nop(struct cmdq_pkt *pkt, u8 shift_pa)
+{
+	return -EINVAL;
+}
+
 static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
 	return -EINVAL;
-- 
2.34.1



From chunkuang.hu at kernel.org  Wed Feb 14 16:49:27 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 15 Feb 2024 00:49:27 +0000
Subject: [PATCH 5/9] drm/mediatek: Drop calling cmdq_pkt_finalize()
In-Reply-To: <20240215004931.3808-1-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
Message-ID: <20240215004931.3808-6-chunkuang.hu@kernel.org>

For some client driver, it want to reduce latency between excuting
previous packet command and next packet command, so append jump
command to the end of previous packet and the jump destination
address is the start address of next packet command buffer. Before
next packet exist, the previous packet has no information of where
to jump to, so append nop command first. When next packet exist,
change nop command to jump command. For mediatek drm driver, it
never has next packet, so appending nop command is redundant.
Because cmdq_pkt_finalize() would append nop command, so change
calling cmdq_pkt_finalize() to cmdq_pkt_eoc() to prevent append
redundant nop command.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index c729af3b9822..df693fa268ce 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -593,7 +593,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
 		cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
 		cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
 		mtk_crtc_ddp_config(crtc, cmdq_handle);
-		cmdq_pkt_finalize(cmdq_handle);
+		cmdq_pkt_eoc(cmdq_handle);
 		dma_sync_single_for_device(mtk_crtc->cmdq_client.chan->mbox->dev,
 					   cmdq_handle->pa_base,
 					   cmdq_handle->cmd_buf_size,
-- 
2.34.1



From chunkuang.hu at kernel.org  Wed Feb 14 16:49:28 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 15 Feb 2024 00:49:28 +0000
Subject: [PATCH 6/9] media: platform: mtk-mdp3: drop calling cmdq_pkt_finalize()
In-Reply-To: <20240215004931.3808-1-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
Message-ID: <20240215004931.3808-7-chunkuang.hu@kernel.org>

Because client driver has the information of struct cmdq_client, so
it's not necessary to store struct cmdq_client in struct cmdq_pkt.
cmdq_pkt_finalize() use struct cmdq_client in struct cmdq_pkt, so it's
going to be abandoned. Therefore, use cmdq_pkt_eoc() and cmdq_pkt_nop()
to replace cmdq_pkt_finalize().

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 3 ++-
 drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c | 2 ++
 drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h | 1 +
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
index 6adac857a477..a420d492d879 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
@@ -471,7 +471,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 		dev_err(dev, "mdp_path_config error\n");
 		goto err_free_path;
 	}
-	cmdq_pkt_finalize(&cmd->pkt);
+	cmdq_pkt_eoc(&cmd->pkt);
+	cmdq_pkt_nop(&cmd->pkt, mdp->cmdq_shift_pa);
 
 	for (i = 0; i < num_comp; i++)
 		memcpy(&comps[i], path->comps[i].comp,
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
index 94f4ed78523b..2214744c937c 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
@@ -231,6 +231,8 @@ static int mdp_probe(struct platform_device *pdev)
 		goto err_put_scp;
 	}
 
+	mdp->cmdq_shift_pa = cmdq_get_shift_pa(mdp->cmdq_clt->chan);
+
 	init_waitqueue_head(&mdp->callback_wq);
 	ida_init(&mdp->mdp_ida);
 	platform_set_drvdata(pdev, mdp);
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
index 7e21d226ceb8..ed61e0bb69ee 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
@@ -83,6 +83,7 @@ struct mdp_dev {
 	u32					id_count;
 	struct ida				mdp_ida;
 	struct cmdq_client			*cmdq_clt;
+	u8					cmdq_shift_pa;
 	wait_queue_head_t			callback_wq;
 
 	struct v4l2_device			v4l2_dev;
-- 
2.34.1



From chunkuang.hu at kernel.org  Wed Feb 14 16:49:29 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 15 Feb 2024 00:49:29 +0000
Subject: [PATCH 7/9] soc: mediatek: cmdq: Remove cmdq_pkt_finalize() helper function
In-Reply-To: <20240215004931.3808-1-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
Message-ID: <20240215004931.3808-8-chunkuang.hu@kernel.org>

Because client driver has the information of struct cmdq_client, so
it's not necessary to store struct cmdq_client in struct cmdq_pkt.
cmdq_pkt_finalize() use struct cmdq_client in struct cmdq_pkt, so
client driver use cmdq_pkt_eoc() and cmdq_pkt_nop() to replace
cmdq_pkt_finalize() and this function could be removed.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 22 ----------------------
 include/linux/soc/mediatek/mtk-cmdq.h  | 13 -------------
 2 files changed, 35 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 1be950b4ec7f..9b937db7398c 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -380,26 +380,4 @@ int cmdq_pkt_nop(struct cmdq_pkt *pkt, u8 shift_pa)
 }
 EXPORT_SYMBOL(cmdq_pkt_nop);
 
-int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
-{
-	struct cmdq_instruction inst = { {0} };
-	int err;
-
-	/* insert EOC and generate IRQ for each command iteration */
-	inst.op = CMDQ_CODE_EOC;
-	inst.value = CMDQ_EOC_IRQ_EN;
-	err = cmdq_pkt_append_command(pkt, inst);
-	if (err < 0)
-		return err;
-
-	/* JUMP to end */
-	inst.op = CMDQ_CODE_JUMP;
-	inst.value = CMDQ_JUMP_PASS >>
-		cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
-	err = cmdq_pkt_append_command(pkt, inst);
-
-	return err;
-}
-EXPORT_SYMBOL(cmdq_pkt_finalize);
-
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 8179ba5238f9..f1d571475b52 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -266,14 +266,6 @@ int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
  */
 int cmdq_pkt_nop(struct cmdq_pkt *pkt, u8 shift_pa);
 
-/**
- * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
- * @pkt:	the CMDQ packet
- *
- * Return: 0 for success; else the error code is returned
- */
-int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
-
 #else /* IS_ENABLED(CONFIG_MTK_CMDQ) */
 
 static inline int cmdq_dev_get_client_reg(struct device *dev,
@@ -377,11 +369,6 @@ static inline int cmdq_pkt_nop(struct cmdq_pkt *pkt, u8 shift_pa)
 	return -EINVAL;
 }
 
-static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
-{
-	return -EINVAL;
-}
-
 #endif /* IS_ENABLED(CONFIG_MTK_CMDQ) */
 
 #endif	/* __MTK_CMDQ_H__ */
-- 
2.34.1



From chunkuang.hu at kernel.org  Wed Feb 14 16:49:30 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 15 Feb 2024 00:49:30 +0000
Subject: [PATCH 8/9] drm/mediatek: Do not store struct cmdq_client in struct cmdq_pkt
In-Reply-To: <20240215004931.3808-1-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
Message-ID: <20240215004931.3808-9-chunkuang.hu@kernel.org>

MediaTek drm driver has the struct cmdq_client information, so
it's not necessary to store this information in struct cmdq_pkt.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index df693fa268ce..0d54cbefee0b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -123,7 +123,6 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *
 		return -ENOMEM;
 
 	pkt->buf_size = size;
-	pkt->cl = (void *)client;
 
 	dev = client->chan->mbox->dev;
 	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
@@ -139,10 +138,8 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *
 	return 0;
 }
 
-static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+static void mtk_drm_cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt)
 {
-	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
-
 	dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
 			 DMA_TO_DEVICE);
 	kfree(pkt->va_base);
@@ -156,7 +153,7 @@ static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
 
 	mtk_mutex_put(mtk_crtc->mutex);
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-	mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle);
+	mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_client, &mtk_crtc->cmdq_handle);
 
 	if (mtk_crtc->cmdq_client.chan) {
 		mbox_free_channel(mtk_crtc->cmdq_client.chan);
-- 
2.34.1



From chunkuang.hu at kernel.org  Wed Feb 14 16:49:31 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 15 Feb 2024 00:49:31 +0000
Subject: [PATCH 9/9] media: platform: mtk-mdp3: do not store struct cmdq_client in struct cmdq_pkt
In-Reply-To: <20240215004931.3808-1-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
Message-ID: <20240215004931.3808-10-chunkuang.hu@kernel.org>

MediaTek mdp3 driver has the struct cmdq_client information, so
it's not necessary to store struct cmdq_client in struct cmdq_pkt.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
index a420d492d879..6aa32ab018b4 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
@@ -298,7 +298,6 @@ static int mdp_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
 		return -ENOMEM;
 
 	pkt->buf_size = size;
-	pkt->cl = (void *)client;
 
 	dev = client->chan->mbox->dev;
 	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
@@ -314,10 +313,8 @@ static int mdp_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
 	return 0;
 }
 
-static void mdp_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+static void mdp_cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt)
 {
-	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
-
 	dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
 			 DMA_TO_DEVICE);
 	kfree(pkt->va_base);
@@ -341,7 +338,7 @@ static void mdp_auto_release_work(struct work_struct *work)
 	atomic_dec(&mdp->job_count);
 	wake_up(&mdp->callback_wq);
 
-	mdp_cmdq_pkt_destroy(&cmd->pkt);
+	mdp_cmdq_pkt_destroy(mdp->cmdq_clt, &cmd->pkt);
 	kfree(cmd->comps);
 	cmd->comps = NULL;
 	kfree(cmd);
@@ -388,7 +385,7 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg)
 		atomic_dec(&mdp->job_count);
 		wake_up(&mdp->callback_wq);
 
-		mdp_cmdq_pkt_destroy(&cmd->pkt);
+		mdp_cmdq_pkt_destroy(mdp->cmdq_clt, &cmd->pkt);
 		kfree(cmd->comps);
 		cmd->comps = NULL;
 		kfree(cmd);
@@ -513,7 +510,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 err_free_comps:
 	kfree(comps);
 err_destroy_pkt:
-	mdp_cmdq_pkt_destroy(&cmd->pkt);
+	mdp_cmdq_pkt_destroy(mdp->cmdq_clt, &cmd->pkt);
 err_free_cmd:
 	kfree(cmd);
 err_cancel_job:
-- 
2.34.1



From kuba at kernel.org  Wed Feb 14 16:59:02 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Wed, 14 Feb 2024 16:59:02 -0800
Subject: [PATCH net-next v7 00/13] Introduce PHY listing and
 link_topology tracking
In-Reply-To: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
Message-ID: <20240214165902.55bf3a04@kernel.org>

On Tue, 13 Feb 2024 16:04:17 +0100 Maxime Chevallier wrote:
> This is V7 for the link topology addition, allowing to track all PHYs
> that are linked to netdevices.
> 
> The main change in V7 is the protection of the main internal API
> entrypoints (link_topo_init/cleanup, link_topo_add/del_phy) by
> IS_REACHABLE(CONFIG_PHYLIB).
> 
> That's restrictive, but it looks difficult to do otherwise while still keep the
> data structure opaque and not add dependency clutter with PHYLIB.
> 
> As you can tell, I'm unsure about this, so please don't hesitate to
> comment on that part :)
> 
> The other changes are very minor, the only one is a call to netdev_put
> in the .done() netlink callback.
> 
> As a remainder, here's what the PHY listings would look like :
>  - eth0 has a 88x3310 acting as media converter, and an SFP module with
>    an embedded 88e1111 PHY
>  - eth2 has a 88e1510 PHY

Needs a rebase, core has been busy lately:

Applying: net: phy: Introduce ethernet link topology representation
Using index info to reconstruct a base tree...
M	MAINTAINERS
M	drivers/net/phy/Makefile
M	drivers/net/phy/phy_device.c
M	include/linux/netdevice.h
M	include/linux/phy.h
M	net/core/dev.c
Falling back to patching base and 3-way merge...
Auto-merging net/core/dev.c
CONFLICT (content): Merge conflict in net/core/dev.c
Auto-merging include/linux/phy.h
Auto-merging include/linux/netdevice.h
Auto-merging drivers/net/phy/phy_device.c
Auto-merging drivers/net/phy/Makefile
Auto-merging MAINTAINERS
Recorded preimage for 'net/core/dev.c'
-- 
pw-bot: cr


From andre.przywara at arm.com  Wed Feb 14 17:28:47 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Thu, 15 Feb 2024 01:28:47 +0000
Subject: [PATCH v4 1/7] soc: sunxi: sram: export register 0 for THS on
 H616
In-Reply-To: <2172811.irdbgypaU6@jernej-laptop>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
	<20240209144221.3602382-2-andre.przywara@arm.com>
	<2172811.irdbgypaU6@jernej-laptop>
Message-ID: <20240215012847.7d0eeda9@minigeek.lan>

On Wed, 14 Feb 2024 21:29:30 +0100
Jernej ?krabec <jernej.skrabec at gmail.com> wrote:

Hi Jernej,

thanks for having a look and the tags on the other patches!

> Dne petek, 09. februar 2024 ob 15:42:15 CET je Andre Przywara napisal(a):
> > The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
> > in the SRAM control block. If bit 16 is set (the reset value), the
> > temperature readings of the THS are way off, leading to reports about
> > 200C, at normal ambient temperatures. Clearing this bits brings the
> > reported values down to reasonable ranges.
> > The BSP code clears this bit in firmware (U-Boot), and has an explicit
> > comment about this, but offers no real explanation.
> > 
> > Since we should not rely on firmware settings, allow other code (the THS
> > driver) to access this register, by exporting it through the already
> > existing regmap. This mimics what we already do for the LDO control and
> > the EMAC register.  
> 
> Are you sure that this bit doesn't control actual SRAM region?

Pretty much so, yes: I did some experiments from U-Boot:
I filled SRAM C with some pattern, then read this back. Then flipped bit
16, read again: same result. Then wrote something again and read it
back: no change. In fact no bits at 0x3000000 had any effect on SRAM
accessibility, only clearing bit 24 in 0x3000004 made the whole SRAM C
(0x28000-0x47fff) go read-as-zero/write-ignore, from the CPU side.

I then triggered the THS device, to do temperature readings, but
this didn't change a single byte in the SRAM regions, with or without
bit 16 set. It only changed the returned values, at 0x50704c0.

So yes, I am pretty certain there is no SRAM region that gets switched.
Even if we would want to claim there is: I wouldn't know which
address values to put into the SRAM DT node.

So I guess it's another example of: oh, we have this spare bit here. Or
it's some kind of chicken bit? I don't know, and I think the BSP code
we have seen didn't offer an explanation as well.

Cheers,
Andre
> 
> Best regards,
> Jernej
> 
> > 
> > Since this bit is in the very same register as the actual SRAM switch,
> > we need to change the regmap lock to the SRAM lock. Fortunately regmap
> > has provisions for that, so we just need to hook in there.
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  drivers/soc/sunxi/sunxi_sram.c | 23 +++++++++++++++++++++++
> >  1 file changed, 23 insertions(+)
> > 
> > diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
> > index 4458b2e0562b0..71cdd1b257eeb 100644
> > --- a/drivers/soc/sunxi/sunxi_sram.c
> > +++ b/drivers/soc/sunxi/sunxi_sram.c
> > @@ -287,6 +287,7 @@ EXPORT_SYMBOL(sunxi_sram_release);
> >  struct sunxi_sramc_variant {
> >  	int num_emac_clocks;
> >  	bool has_ldo_ctrl;
> > +	bool has_ths_offset;
> >  };
> >  
> >  static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
> > @@ -308,8 +309,10 @@ static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
> >  
> >  static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
> >  	.num_emac_clocks = 2,
> > +	.has_ths_offset = true,
> >  };
> >  
> > +#define SUNXI_SRAM_THS_OFFSET_REG	0x0
> >  #define SUNXI_SRAM_EMAC_CLOCK_REG	0x30
> >  #define SUNXI_SYS_LDO_CTRL_REG		0x150
> >  
> > @@ -318,6 +321,8 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
> >  {
> >  	const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
> >  
> > +	if (reg == SUNXI_SRAM_THS_OFFSET_REG && variant->has_ths_offset)
> > +		return true;
> >  	if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG &&
> >  	    reg <  SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
> >  		return true;
> > @@ -327,6 +332,21 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
> >  	return false;
> >  }
> >  
> > +
> > +static void sunxi_sram_lock(void *_lock)
> > +{
> > +	spinlock_t *lock = _lock;
> > +
> > +	spin_lock(lock);
> > +}
> > +
> > +static void sunxi_sram_unlock(void *_lock)
> > +{
> > +	spinlock_t *lock = _lock;
> > +
> > +	spin_unlock(lock);
> > +}
> > +
> >  static struct regmap_config sunxi_sram_regmap_config = {
> >  	.reg_bits       = 32,
> >  	.val_bits       = 32,
> > @@ -336,6 +356,9 @@ static struct regmap_config sunxi_sram_regmap_config = {
> >  	/* other devices have no business accessing other registers */
> >  	.readable_reg	= sunxi_sram_regmap_accessible_reg,
> >  	.writeable_reg	= sunxi_sram_regmap_accessible_reg,
> > +	.lock		= sunxi_sram_lock,
> > +	.unlock		= sunxi_sram_unlock,
> > +	.lock_arg	= &sram_lock,
> >  };
> >  
> >  static int __init sunxi_sram_probe(struct platform_device *pdev)
> >   
> 
> 
> 
> 
> 



From swboyd at chromium.org  Wed Feb 14 17:52:33 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Wed, 14 Feb 2024 17:52:33 -0800
Subject: [PATCH 13/22] dt-bindings: chrome: Add google,cros-ec-typec-switch
 binding
In-Reply-To: <46ac6ab8-b0a5-497d-91b6-1d2ced33184b@linaro.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-14-swboyd@chromium.org>
 <46ac6ab8-b0a5-497d-91b6-1d2ced33184b@linaro.org>
Message-ID: <CAE-0n52TzOAqN8Y7EdJPjDxY2iY-6Jr-Pq8fFMFtF-cXo5+OyA@mail.gmail.com>

Quoting Krzysztof Kozlowski (2024-02-11 05:34:25)
> On 10/02/2024 08:09, Stephen Boyd wrote:
> > Add a binding for the USB type-c switch controls found on some ChromeOS
> > Embedded Controllers (ECs). When this device is a mode switch, it takes
> > one DisplayPort (DP) port as input and some number (possibly zero) of
> > USB SuperSpeed ports (bundles of USB SS lanes) as input, and muxes those
> > lanes into USB type-c SuperSpeed lanes suitable for the SSTRX1/2 pins on
> > a usb-c-connector. When this device is an orientation switch, it
> > redirects the DP lanes to the proper USB type-c SSTRX lanes.
> >
> > Cc: Rob Herring <robh+dt at kernel.org>
> > Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> > Cc: Conor Dooley <conor+dt at kernel.org>
> > Cc: Lee Jones <lee at kernel.org>
> > Cc: Benson Leung <bleung at chromium.org>
> > Cc: Guenter Roeck <groeck at chromium.org>
> > Cc: Prashant Malani <pmalani at chromium.org>
> > Cc: Tzung-Bi Shih <tzungbi at kernel.org>
> > Cc: <devicetree at vger.kernel.org>
> > Cc: <chrome-platform at lists.linux.dev>
> > Cc: Pin-yen Lin <treapking at chromium.org>
> > Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> > ---
> >  .../chrome/google,cros-ec-typec-switch.yaml   | 365 ++++++++++++++++++
> >  .../bindings/mfd/google,cros-ec.yaml          |   5 +
> >  2 files changed, 370 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml b/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
> > new file mode 100644
> > index 000000000000..17a0ba928f5d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
> > @@ -0,0 +1,365 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/chrome/google,cros-ec-typec-switch.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Google Chrome OS EC(Embedded Controller) USB Type C Switch
> > +
> > +maintainers:
> > +  - Benson Leung <bleung at chromium.org>
> > +  - Prashant Malani <pmalani at chromium.org>
> > +  - Stephen Boyd <swboyd at chromium.org>
> > +
> > +description:
> > +  Chrome OS devices have an Embedded Controller(EC) which has access to USB
> > +  Type C switching. This node is intended to allow the OS to control Type C
> > +  signal muxing for USB-C orientation and alternate modes. The node for this
> > +  device should be under a cros-ec node like google,cros-ec-spi.
> > +
>
> If this is USB Type C switch, then you miss reference to
> usb-switch.yaml, but then ports look a bit different.

Thanks for the pointer. I suspect that's in linux-next only? I'm going
to move this to the cros-ec-typec.yaml file but I'll still need some
sort of property like 'mode-switch' or 'orientation-switch' to describe
what needs to be done in the kernel by changing lane assignments in the
drm_bridge.

One problem with those properties is that they're boolean for the whole
device. If I have a google,cros-ec-typec node that has two input DP
ports and two output USB-C ports then it may be that one port needs
orientation switching and the other only needs to do mode switching.
This needs to be expressed somehow and a top-level boolean property
doesn't do that. It could be part of the DP endpoint node itself.

Also I don't know how to indicate that mode switching can't be changed
here directly. For example, on Trogdor the mode is switched by the EC,
and the kernel can't change the mode. Changing DP lane assignments isn't
going to change the situation either. The mode is still going to be
something like DP+USB, or just DP, etc. Maybe there needs to be a
different property, like 'dp-mode-lane-assignment = <array of ports>',
that indicates which DP ports need to do lane assignment or
'dp-orientation-lane-assignment = <array of ports>' for orientation
control. Either way, I'm saying that 'mode-switch' and
'orientation-switch' properties don't make any sense here. I was using
them to wedge the code into the typec switch callbacks, but if I move
this into the cros-ec-typec driver then I don't need them.

>
> > +
> > +  no-hpd:
> > +    description: Indicates this device doesn't signal HPD for DisplayPort
> > +    type: boolean
> > +
> > +  ports:
[...]
> > +
> > +          endpoint at 7:
> > +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
> > +            description: USB-C data for EC's 7th type-c port
> > +            unevaluatedProperties: false
> > +            properties:
> > +              data-lanes:
> > +                $ref: /schemas/types.yaml#/definitions/uint32-array
> > +                description: |
> > +                  An array of physical USB-C data lane indexes.
> > +                  - 0 is SSRX1 lane
> > +                  - 1 is SSTX1 lane
> > +                  - 2 is SSTX2 lane
> > +                  - 3 is SSRX2 lane
> > +                minItems: 4
> > +                maxItems: 4
> > +                items:
> > +                  maximum: 3
> > +
> > +        anyOf:
> > +          - required:
> > +              - endpoint at 0
>
> I don't get what you want to say here. This anyOf should have no effect.

I'm trying to say that there should be at least one usb-c data lane
output endpoint if there's a port at 2 (usb-c output).

>
> > +          - required:
> > +              - endpoint at 1
> > +          - required:
> > +              - endpoint at 2
[...]
>
> > +
> > +required:
> > +  - compatible
> > +  - ports
> > +
> > +allOf:
> > +  - if:
> > +      properties:
> > +        no-hpd: true
>
> I don't understand this either. What is it for? Where did you see such
> syntax?

This is saying that if the no-hpd property is present then the port at 0
port (DP input port) is required. Otherwise no-hpd doesn't really make
any sense because this device isn't muxing DP onto USB type-c connectors.

I found this syntax by searching the schema website and reading this
page[1]. The last yellow note about "country" not being a required
property led me to this syntax.

[1] https://json-schema.org/understanding-json-schema/reference/conditionals#ifthenelse


From chiawei_wang at aspeedtech.com  Wed Feb 14 17:56:00 2024
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Thu, 15 Feb 2024 01:56:00 +0000
Subject: =?utf-8?B?UkU6IOWbnuimhjogW1BBVENIXSBBZGQgZVNQSSBkZXZpY2UgZHJpdmVyIChm?=
 =?utf-8?Q?lash_channel)?=
In-Reply-To: <20240214-yoyo-platinum-dcd0e7e16a22@spud>
References: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
 <KL1PR06MB665234A65DB334B3BDF6AFA6914E2@KL1PR06MB6652.apcprd06.prod.outlook.com>
 <20240214-yoyo-platinum-dcd0e7e16a22@spud>
Message-ID: <TYZPR06MB6640F82C539F0B17BCDCC55E914D2@TYZPR06MB6640.apcprd06.prod.outlook.com>

> 
> On Wed, Feb 14, 2024 at 11:34:31AM +0000, ChiaWei Wang wrote:
> > We appreciate that you are willing to help on the open source contribution.
> > However, please co-work with Aspeed before submitting drivers of Aspeed
> HW.
> > Otherwise, a misleading driver on the community are going to bring tons of
> customer issues to Aspeed.
> 
> It may not apply in this particular case as Aspeed did write the original driver
> and it is polite to work with previous authors when respinning a patchset, but in
> general there is no need to work with a hardware vendor before writing drivers
> for their hardware.
> 
> Blocking a driver because that company might receive more support requests
> is not the kernel's problem.

I agree with that and Aspeed will not refuse to support.

However, in this case, the authors, IBM, and Aspeed already have discussion (at least 4 times) before and foresee "issues" on practical eSPI SAFS use.
If there is already a known issue of the driver, why ignoring the previous discussion and push it?
A compromise is to ask for driver renaming to espi-mafs to avoid confusion.
Otherwise we need to explain, again, why the driver does not fulfill the SAFS expectation.

Regards,
Chiawei


From oliver.upton at linux.dev  Wed Feb 14 18:02:24 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 15 Feb 2024 02:02:24 +0000
Subject: [PATCH 2/2] arm64: cpufeatures: Only check for NV1 if NV is
 present
In-Reply-To: <86bk8k5ts3.wl-maz@kernel.org>
References: <20240212144736.1933112-1-maz@kernel.org>
 <CGME20240212144758eucas1p1345ba6f2000c10a4b33f8575f0a8d22b@eucas1p1.samsung.com>
 <20240212144736.1933112-3-maz@kernel.org>
 <5b2d8fee-9d0f-48f7-b9ec-b86e95387a61@samsung.com>
 <86bk8k5ts3.wl-maz@kernel.org>
Message-ID: <Zc1wsKzAvooOvR-v@linux.dev>

On Tue, Feb 13, 2024 at 02:21:48PM +0000, Marc Zyngier wrote:
> From cd75279d3b6c387c13972b61c486a203d9652e97 Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <maz at kernel.org>
> Date: Tue, 13 Feb 2024 13:37:57 +0000
> Subject: [PATCH] arm64: cpufeatures: Fix FEAT_NV check when checking for
>  FEAT_NV1
> 
> Using this_cpu_has_cap() has the potential to go wrong when
> used system-wide on a preemptible kernel. Instead, use the
> __system_matches_cap() helper when checking for FEAT_NV in the
> FEAT_NV1 probing helper.
> 
> Fixes: 3673d01a2f55 ("arm64: cpufeatures: Only check for NV1 if NV is present")
> Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

b4 wasn't very happy with grabbing this patch in reply to a series
(probably user error), but I've picked this up for kvmarm/next.

https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git/commit/?id=9aa030cee1c45d6e962f6bf22ba63d4aff2b1644

-- 
Thanks,
Oliver


From quic_jinlmao at quicinc.com  Wed Feb 14 18:12:03 2024
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Thu, 15 Feb 2024 10:12:03 +0800
Subject: [PATCH v1 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename
 qcom,dsb-element-size
In-Reply-To: <729a4c17-9e86-467f-85cf-652c503fa14e@arm.com>
References: <20240213160521.15925-1-quic_jinlmao@quicinc.com>
 <20240213160521.15925-2-quic_jinlmao@quicinc.com>
 <20240213222957.GA2502642-robh@kernel.org>
 <c70df5a6-20af-4cee-b147-5847751fa36b@arm.com>
 <CAL_JsqKdAzPEGh941S05kraTjOcEpsPCnDRkppNkb8pBCpZu6g@mail.gmail.com>
 <729a4c17-9e86-467f-85cf-652c503fa14e@arm.com>
Message-ID: <4a124dff-f92d-4f2e-a6bf-bd7ad75a08df@quicinc.com>


On 2/15/2024 12:18 AM, Suzuki K Poulose wrote:
> On 14/02/2024 16:03, Rob Herring wrote:
>> On Wed, Feb 14, 2024 at 9:56?AM Suzuki K Poulose 
>> <suzuki.poulose at arm.com> wrote:
>>>
>>> On 13/02/2024 22:29, Rob Herring wrote:
>>>> On Tue, Feb 13, 2024 at 08:05:17AM -0800, Mao Jinlong wrote:
>>>>> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
>>>>> bit.
>>>>
>>>> That may be, but this is an ABI and you are stuck with it. Unless, you
>>>> can justify why that doesn't matter. (IIRC, this is new, so maybe no
>>>> users yet?)
>>>
>>> This was added and support queued in v6.8. This change won't make it to
>>> v6.8 (given it has to go via two levels and is technically not a fix).
>>
>> I'd argue it is a fix. But given no users yet, delaying is fine.
>
> I agree it is a fix, but not something that maintainers would like to
> pull it during an rc cycle. As you said, since there are no real users
> for this yet (and given it is all under a single vendor), it may be fine
> to queue this if the DT maintainers are OK with this.
>
>
>>
>>> As James also pointed out, it doesn't matter what the name is (now that
>>> it has been published).
>>
>> v6.8 final is what we consider published.
>
> I can't send this to Greg as a fix. For v6.8. We can fix it for v6.9 
> cycle.
>
> Suzuki
>
Thanks all for the comments. I will update the commit message and fix 
the warning.

Thanks
Jinlong Mao

>>
>> Rob
>


From Kuan-Ying.Lee at mediatek.com  Wed Feb 14 19:02:01 2024
From: Kuan-Ying.Lee at mediatek.com (=?utf-8?B?S3Vhbi1ZaW5nIExlZSAo5p2O5Yag56mOKQ==?=)
Date: Thu, 15 Feb 2024 03:02:01 +0000
Subject: [PATCH] scripts/gdb/vmalloc: fix vmallocinfo error
In-Reply-To: <20240207155929.cc107bcc14b982789bdc9fab@linux-foundation.org>
References: <20240207085856.11190-1-Kuan-Ying.Lee@mediatek.com>
	 <20240207155623.a943328ba0b77859246e0d9f@linux-foundation.org>
	 <20240207155929.cc107bcc14b982789bdc9fab@linux-foundation.org>
Message-ID: <8e2fbab4c611cc1bbf45f58e88736a0bd0bd6fa2.camel@mediatek.com>

On Wed, 2024-02-07 at 15:59 -0800, Andrew Morton wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  On Wed, 7 Feb 2024 15:56:23 -0800 Andrew Morton <
> akpm at linux-foundation.org> wrote:
> 
> > > [1] 
> https://lore.kernel.org/linux-mm/20240102184633.748113-1-urezki at gmail.com/
> > 
> > vmap_area_list was removed by 
> https://lkml.kernel.org/r/20240102184633.748113-6-urezki at gmail.com
> > 
> > So I think this patch is actually a fix against mm.git:mm-
> unstable's
> > mm-vmalloc-remove-vmap_area_list.patch?
> > 

Yes, you are right.
Thanks for helping to fix the commit message.

> > However this gdb function was probably probably broken earlier in
> that
> > series, so perhaps this patch would be best staged as a predecessor
> to
> > Ulad's vmalloc series.
> 
> ie, this:
> 
> 
> From: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
> Subject: scripts/gdb/vmalloc: fix vmallocinfo error
> Date: Wed, 7 Feb 2024 16:58:51 +0800
> 
> The patch series "Mitigate a vmap lock contention" removes
> vmap_area_list,
> which will break the gdb vmallocinfo command:
> 
> (gdb) lx-vmallocinfo
> Python Exception <class 'gdb.error'>: No symbol "vmap_area_list" in
> current context.
> Error occurred in Python: No symbol "vmap_area_list" in current
> context.
> 
> So we can instead use vmap_nodes to iterate all vmallocinfo.
> 
> Link: 
> https://lkml.kernel.org/r/20240207085856.11190-1-Kuan-Ying.Lee at mediatek.com
> Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
> Cc: Casper Li <casper.li at mediatek.com>
> Cc: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> Cc: Chinwen Chang <chinwen.chang at mediatek.com>
> Cc: Jan Kiszka <jan.kiszka at siemens.com>
> Cc: Kieran Bingham <kbingham at kernel.org>
> Cc: Matthias Brugger <matthias.bgg at gmail.com>
> Cc: Qun-Wei Lin <qun-wei.lin at mediatek.com>
> Cc: Uladzislau Rezki (Sony) <urezki at gmail.com>
> Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
> ---
> 
>  scripts/gdb/linux/vmalloc.py |   56 +++++++++++++++++---------------
> -
>  1 file changed, 29 insertions(+), 27 deletions(-)
> 
> --- a/scripts/gdb/linux/vmalloc.py~scripts-gdb-vmalloc-fix-
> vmallocinfo-error
> +++ a/scripts/gdb/linux/vmalloc.py
> @@ -29,32 +29,34 @@ class LxVmallocInfo(gdb.Command):
>          if not constants.LX_CONFIG_MMU:
>              raise gdb.GdbError("Requires MMU support")
>  
> -        vmap_area_list = gdb.parse_and_eval('vmap_area_list')
> -        for vmap_area in lists.list_for_each_entry(vmap_area_list,
> vmap_area_ptr_type, "list"):
> -            if not vmap_area['vm']:
> -                gdb.write("0x%x-0x%x %10d vm_map_ram\n" %
> (vmap_area['va_start'], vmap_area['va_end'],
> -                    vmap_area['va_end'] - vmap_area['va_start']))
> -                continue
> -            v = vmap_area['vm']
> -            gdb.write("0x%x-0x%x %10d" % (v['addr'], v['addr'] +
> v['size'], v['size']))
> -            if v['caller']:
> -                gdb.write(" %s" % str(v['caller']).split(' ')[-1])
> -            if v['nr_pages']:
> -                gdb.write(" pages=%d" % v['nr_pages'])
> -            if v['phys_addr']:
> -                gdb.write(" phys=0x%x" % v['phys_addr'])
> -            if v['flags'] & constants.LX_VM_IOREMAP:
> -                gdb.write(" ioremap")
> -            if v['flags'] & constants.LX_VM_ALLOC:
> -                gdb.write(" vmalloc")
> -            if v['flags'] & constants.LX_VM_MAP:
> -                gdb.write(" vmap")
> -            if v['flags'] & constants.LX_VM_USERMAP:
> -                gdb.write(" user")
> -            if v['flags'] & constants.LX_VM_DMA_COHERENT:
> -                gdb.write(" dma-coherent")
> -            if is_vmalloc_addr(v['pages']):
> -                gdb.write(" vpages")
> -            gdb.write("\n")
> +        nr_vmap_nodes = gdb.parse_and_eval('nr_vmap_nodes')
> +        for i in range(0, nr_vmap_nodes):
> +            vn = gdb.parse_and_eval('&vmap_nodes[%d]' % i)
> +            for vmap_area in
> lists.list_for_each_entry(vn['busy']['head'], vmap_area_ptr_type,
> "list"):
> +                if not vmap_area['vm']:
> +                    gdb.write("0x%x-0x%x %10d vm_map_ram\n" %
> (vmap_area['va_start'], vmap_area['va_end'],
> +                        vmap_area['va_end'] -
> vmap_area['va_start']))
> +                    continue
> +                v = vmap_area['vm']
> +                gdb.write("0x%x-0x%x %10d" % (v['addr'], v['addr'] +
> v['size'], v['size']))
> +                if v['caller']:
> +                    gdb.write(" %s" % str(v['caller']).split(' ')[-
> 1])
> +                if v['nr_pages']:
> +                    gdb.write(" pages=%d" % v['nr_pages'])
> +                if v['phys_addr']:
> +                    gdb.write(" phys=0x%x" % v['phys_addr'])
> +                if v['flags'] & constants.LX_VM_IOREMAP:
> +                    gdb.write(" ioremap")
> +                if v['flags'] & constants.LX_VM_ALLOC:
> +                    gdb.write(" vmalloc")
> +                if v['flags'] & constants.LX_VM_MAP:
> +                    gdb.write(" vmap")
> +                if v['flags'] & constants.LX_VM_USERMAP:
> +                    gdb.write(" user")
> +                if v['flags'] & constants.LX_VM_DMA_COHERENT:
> +                    gdb.write(" dma-coherent")
> +                if is_vmalloc_addr(v['pages']):
> +                    gdb.write(" vpages")
> +                gdb.write("\n")
>  
>  LxVmallocInfo()
> _
> 

From yong.liang.choong at linux.intel.com  Wed Feb 14 19:04:50 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:04:50 +0800
Subject: [PATCH net-next v5 0/9] Enable SGMII and 2500BASEX interface mode switching for Intel platforms
Message-ID: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>

From: root <root at YongLiang-Ubuntu20-iLBPG12.png.intel.com>

During the interface mode change, the 'phylink_major_config' function
will be triggered in phylink. The modification of the following functions
will be triggered to support the switching between SGMII and 2500BASEX
interfaces mode for the Intel platform.

- mac_get_pcs_neg_mode: A new function that selects the PCS negotiation
  mode according to the interface mode.
- xpcs_do_config: Re-initiate clause 37 auto-negotiation for SGMII interface
  mode to perform auto-negotiation.
- mac_finish: Configures the SerDes according to the interface mode.

With the above changes, the code will work as follows during the
interface mode change. The PCS and PCS negotiation mode will be selected
for PCS configuration according to the interface mode. Then, the MAC
driver will perform SerDes configuration on the 'mac_finish' based on the
interface mode. During the SerDes configuration, the selected interface
mode will identify TSN lane registers from FIA and then send IPC commands
to the Power Management Controller (PMC) through the PMC driver/API.
PMC will act as a proxy to program the PLL registers.

Change log:
v1 -> v2: 
 - Add static to pmc_lpm_modes declaration
 - Add cur_link_an_mode to the kernel doc
 - Combine 2 commits i.e. "stmmac: intel: Separate driver_data of ADL-N
 from TGL" and "net: stmmac: Add 1G/2.5G auto-negotiation
 support for ADL-N" into 1 commit.

v2 -> v3:
 - Create `pmc_ipc.c` file for `intel_pmc_ipc()` function and 
 allocate the file in `arch/x86/platform/intel/` directory.
 - Update phylink's AN mode during phy interface change and 
 not exposing phylink's AN mode into phylib.
 
 v3 -> v4:
 - Introduce `allow_switch_interface` flag to have all ethtool 
 link modes that are supported and advertised will be published.
 - Introduce `mac_get_pcs_neg_mode` function that selects the PCS 
 negotiation mode according to the interface mode.
 - Remove pcs-xpcs.c changes and handle pcs during `mac_select_pcs`
 function
 - Configure SerDes base on the interface on `mac_finish` function.
 
 v4 -> v5:
 - remove 'allow_switch_interface' related patches.
 - remove 'mac_select_pcs' related patches.
 - add a soft reset according to XPCS datasheet for re-initiate Clause 37
 auto-negotiation when switching to SGMII interface mode.

Choong Yong Liang (7):
  net: phylink: provide mac_get_pcs_neg_mode() function
  net: phylink: add phylink_pcs_neg_mode() declaration into phylink.h
  net: stmmac: select PCS negotiation mode according to the interface
    mode
  net: pcs: xpcs: re-initiate clause 37 Auto-negotiation
  net: stmmac: configure SerDes on mac_finish
  stmmac: intel: interface switching support for EHL platform
  stmmac: intel: interface switching support for ADL-N platform

David E. Box (1):
  arch: x86: Add IPC mailbox accessor function and add SoC register
    access

Tan, Tee Min (1):
  stmmac: intel: configure SerDes according to the interface mode

 MAINTAINERS                                   |   2 +
 arch/x86/Kconfig                              |   9 +
 arch/x86/platform/intel/Makefile              |   1 +
 arch/x86/platform/intel/pmc_ipc.c             |  75 ++++++
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |   2 +
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 233 ++++++++++++++++--
 .../net/ethernet/stmicro/stmmac/dwmac-intel.h |  81 ++++++
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  30 +++
 drivers/net/pcs/pcs-xpcs.c                    |  62 ++++-
 drivers/net/phy/phylink.c                     |  21 +-
 include/linux/phylink.h                       |   8 +
 .../linux/platform_data/x86/intel_pmc_ipc.h   |  34 +++
 include/linux/stmmac.h                        |   5 +
 13 files changed, 538 insertions(+), 25 deletions(-)
 create mode 100644 arch/x86/platform/intel/pmc_ipc.c
 create mode 100644 include/linux/platform_data/x86/intel_pmc_ipc.h

-- 
2.34.1



From yong.liang.choong at linux.intel.com  Wed Feb 14 19:04:51 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:04:51 +0800
Subject: [PATCH net-next v5 1/9] net: phylink: provide mac_get_pcs_neg_mode() function
In-Reply-To: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
Message-ID: <20240215030500.3067426-2-yong.liang.choong@linux.intel.com>

Phylink invokes the 'mac_get_pcs_neg_mode' function during interface mode
switching and initial startup.

This function is optional; if 'phylink_pcs_neg_mode' fails to accurately
reflect the current PCS negotiation mode, the MAC driver can determine the
mode based on the interface mode, current link negotiation mode, and
advertising link mode.

For instance, if the interface switches from 2500baseX to SGMII mode,
and the current link mode is MLO_AN_PHY, calling 'phylink_pcs_neg_mode'
would yield PHYLINK_PCS_NEG_OUTBAND. Since the MAC and PCS driver require
PHYLINK_PCS_NEG_INBAND_ENABLED, the 'mac_get_pcs_neg_mode' function
will calculate the mode based on the interface, current link negotiation
mode, and advertising link mode, returning PHYLINK_PCS_NEG_OUTBAND to
enable the PCS to configure the correct settings.

Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
---
 drivers/net/phy/phylink.c | 14 +++++++++++---
 include/linux/phylink.h   |  5 +++++
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 503fd7c40523..b38b39a6d1f0 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1151,9 +1151,17 @@ static void phylink_major_config(struct phylink *pl, bool restart,
 
 	phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
 
-	pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode,
-						state->interface,
-						state->advertising);
+	if (pl->mac_ops->mac_get_pcs_neg_mode) {
+		pl->pcs_neg_mode = pl->mac_ops->mac_get_pcs_neg_mode
+						(pl->config,
+						 pl->cur_link_an_mode,
+						 state->interface,
+						 state->advertising);
+	} else {
+		pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode,
+							state->interface,
+							state->advertising);
+	}
 
 	if (pl->using_mac_select_pcs) {
 		pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 6ba411732a0d..f0a6c00e8dab 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -168,6 +168,7 @@ void phylink_limit_mac_speed(struct phylink_config *config, u32 max_speed);
  * @mac_finish: finish a major reconfiguration of the interface.
  * @mac_link_down: take the link down.
  * @mac_link_up: allow the link to come up.
+ * @mac_get_pcs_neg_mode: Get PCS negotiation mode for interface mode.
  *
  * The individual methods are described more fully below.
  */
@@ -188,6 +189,10 @@ struct phylink_mac_ops {
 			    struct phy_device *phy, unsigned int mode,
 			    phy_interface_t interface, int speed, int duplex,
 			    bool tx_pause, bool rx_pause);
+	unsigned int (*mac_get_pcs_neg_mode)(struct phylink_config *config,
+					     unsigned int mode,
+					     phy_interface_t interface,
+					     const unsigned long *advertising);
 };
 
 #if 0 /* For kernel-doc purposes only. */
-- 
2.34.1



From yong.liang.choong at linux.intel.com  Wed Feb 14 19:04:52 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:04:52 +0800
Subject: [PATCH net-next v5 2/9] net: phylink: add phylink_pcs_neg_mode() declaration into phylink.h
In-Reply-To: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
Message-ID: <20240215030500.3067426-3-yong.liang.choong@linux.intel.com>

Add phylink_pcs_neg_mode() declaration to the header file for other modules
to call the function.

Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
---
 drivers/net/phy/phylink.c | 7 ++++---
 include/linux/phylink.h   | 3 +++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index b38b39a6d1f0..b4345042d3fe 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1093,9 +1093,9 @@ static void phylink_pcs_an_restart(struct phylink *pl)
  * Note: this is for cases where the PCS itself is involved in negotiation
  * (e.g. Clause 37, SGMII and similar) not Clause 73.
  */
-static unsigned int phylink_pcs_neg_mode(unsigned int mode,
-					 phy_interface_t interface,
-					 const unsigned long *advertising)
+unsigned int phylink_pcs_neg_mode(unsigned int mode,
+				  phy_interface_t interface,
+				  const unsigned long *advertising)
 {
 	unsigned int neg_mode;
 
@@ -1139,6 +1139,7 @@ static unsigned int phylink_pcs_neg_mode(unsigned int mode,
 
 	return neg_mode;
 }
+EXPORT_SYMBOL_GPL(phylink_pcs_neg_mode);
 
 static void phylink_major_config(struct phylink *pl, bool restart,
 				  const struct phylink_link_state *state)
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index f0a6c00e8dab..74af8cfbdd92 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -594,6 +594,9 @@ int phylink_ethtool_set_eee(struct phylink *link, struct ethtool_keee *eee);
 int phylink_mii_ioctl(struct phylink *, struct ifreq *, int);
 int phylink_speed_down(struct phylink *pl, bool sync);
 int phylink_speed_up(struct phylink *pl);
+unsigned int phylink_pcs_neg_mode(unsigned int mode,
+				  phy_interface_t interface,
+				  const unsigned long *advertising);
 
 #define phylink_zero(bm) \
 	bitmap_zero(bm, __ETHTOOL_LINK_MODE_MASK_NBITS)
-- 
2.34.1



From yong.liang.choong at linux.intel.com  Wed Feb 14 19:04:53 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:04:53 +0800
Subject: [PATCH net-next v5 3/9] net: stmmac: select PCS negotiation mode according to the interface mode
In-Reply-To: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
Message-ID: <20240215030500.3067426-4-yong.liang.choong@linux.intel.com>

The 'stmmac_get_pcs_neg_mode' is invoked during link initialization or
interface mode changes.

In cases where 'priv->plat->get_pcs_neg_mode' is absent, the default
'phylink_pcs_neg_mode' function is utilized.

Additionally, the 'intel_get_pcs_neg_mode' function is available to
determine the PCS negotiation mode based on the provided interface mode.

Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 48 +++++++++++++++----
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 17 +++++++
 include/linux/stmmac.h                        |  2 +
 3 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 60283543ffc8..6f12e80b8a05 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -414,6 +414,39 @@ static void intel_mgbe_pse_crossts_adj(struct intel_priv_data *intel_priv,
 	}
 }
 
+static bool is_fixed_link(struct pci_dev *pdev)
+{
+	struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev);
+	bool is_fixed_link = false;
+
+	if (fwnode) {
+		struct fwnode_handle *fixed_node;
+
+		fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link");
+		if (fixed_node)
+			is_fixed_link = true;
+
+		fwnode_handle_put(fixed_node);
+	}
+
+	return is_fixed_link;
+}
+
+static unsigned int intel_get_pcs_neg_mode(phy_interface_t interface,
+					   struct pci_dev *pdev)
+{
+	unsigned int neg_mode;
+
+	if ((interface == PHY_INTERFACE_MODE_SGMII ||
+	     interface == PHY_INTERFACE_MODE_1000BASEX) &&
+	     !is_fixed_link(pdev))
+		neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
+	else
+		neg_mode = PHYLINK_PCS_NEG_OUTBAND;
+
+	return neg_mode;
+}
+
 static void common_default_data(struct plat_stmmacenet_data *plat)
 {
 	plat->clk_csr = 2;	/* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
@@ -590,15 +623,8 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
 	}
 
 	/* For fixed-link setup, we clear xpcs_an_inband */
-	if (fwnode) {
-		struct fwnode_handle *fixed_node;
-
-		fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link");
-		if (fixed_node)
-			plat->mdio_bus_data->xpcs_an_inband = false;
-
-		fwnode_handle_put(fixed_node);
-	}
+	if (is_fixed_link(pdev))
+		plat->mdio_bus_data->xpcs_an_inband = false;
 
 	/* Ensure mdio bus scan skips intel serdes and pcs-xpcs */
 	plat->mdio_bus_data->phy_mask = 1 << INTEL_MGBE_ADHOC_ADDR;
@@ -649,7 +675,7 @@ static int ehl_sgmii_data(struct pci_dev *pdev,
 	plat->speed_mode_2500 = intel_speed_mode_2500;
 	plat->serdes_powerup = intel_serdes_powerup;
 	plat->serdes_powerdown = intel_serdes_powerdown;
-
+	plat->get_pcs_neg_mode = intel_get_pcs_neg_mode;
 	plat->clk_ptp_rate = 204800000;
 
 	return ehl_common_data(pdev, plat);
@@ -708,6 +734,7 @@ static int ehl_pse0_sgmii1g_data(struct pci_dev *pdev,
 	plat->speed_mode_2500 = intel_speed_mode_2500;
 	plat->serdes_powerup = intel_serdes_powerup;
 	plat->serdes_powerdown = intel_serdes_powerdown;
+	plat->get_pcs_neg_mode = intel_get_pcs_neg_mode;
 	return ehl_pse0_common_data(pdev, plat);
 }
 
@@ -749,6 +776,7 @@ static int ehl_pse1_sgmii1g_data(struct pci_dev *pdev,
 	plat->speed_mode_2500 = intel_speed_mode_2500;
 	plat->serdes_powerup = intel_serdes_powerup;
 	plat->serdes_powerdown = intel_serdes_powerdown;
+	plat->get_pcs_neg_mode = intel_get_pcs_neg_mode;
 	return ehl_pse1_common_data(pdev, plat);
 }
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ae2ffa9595d6..dbd16fc38888 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1104,11 +1104,28 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 		stmmac_hwtstamp_correct_latency(priv, priv);
 }
 
+static unsigned int stmmac_get_pcs_neg_mode(struct phylink_config *config,
+					    unsigned int mode,
+					    phy_interface_t interface,
+					    const unsigned long *advertising)
+{
+	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
+	unsigned int neg_mode;
+
+	if (priv->plat->get_pcs_neg_mode)
+		neg_mode = priv->plat->get_pcs_neg_mode(interface, priv->plat->pdev);
+	else
+		neg_mode = phylink_pcs_neg_mode(mode, interface, advertising);
+
+	return neg_mode;
+}
+
 static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
 	.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,
+	.mac_get_pcs_neg_mode = stmmac_get_pcs_neg_mode,
 };
 
 /**
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index dfa1828cd756..ffd66722eeda 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -277,6 +277,8 @@ struct plat_stmmacenet_data {
 	int (*serdes_powerup)(struct net_device *ndev, void *priv);
 	void (*serdes_powerdown)(struct net_device *ndev, void *priv);
 	void (*speed_mode_2500)(struct net_device *ndev, void *priv);
+	unsigned int (*get_pcs_neg_mode)(phy_interface_t interface,
+					 struct pci_dev *pdev);
 	void (*ptp_clk_freq_config)(struct stmmac_priv *priv);
 	int (*init)(struct platform_device *pdev, void *priv);
 	void (*exit)(struct platform_device *pdev, void *priv);
-- 
2.34.1



From yong.liang.choong at linux.intel.com  Wed Feb 14 19:04:54 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:04:54 +0800
Subject: [PATCH net-next v5 4/9] net: pcs: xpcs: re-initiate clause 37 Auto-negotiation
In-Reply-To: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
Message-ID: <20240215030500.3067426-5-yong.liang.choong@linux.intel.com>

According to the XPCS datasheet, a soft reset is required to initiate
Clause 37 auto-negotiation when the XPCS switches interface modes.

When the interface mode is set to 2500BASE-X, Clause 37 Auto-Negotiation
is turned off.

Subsequently, when the interface mode switches from 2500BASE-X to SGMII,
re-initiating Clause 37 auto-negotiation is required for the SGMII
interface mode to function properly.

Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
---
 drivers/net/pcs/pcs-xpcs.c | 62 +++++++++++++++++++++++++++++++++++---
 1 file changed, 57 insertions(+), 5 deletions(-)

diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 52a7757ee419..cf1ed89d6418 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -848,6 +848,60 @@ static int xpcs_config_2500basex(struct dw_xpcs *xpcs)
 	return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret);
 }
 
+static int xpcs_switch_to_aneg_c37_sgmii(const struct xpcs_compat *compat,
+					 struct dw_xpcs *xpcs,
+					 unsigned int neg_mode)
+{
+	bool an_c37_enabled;
+	int ret, mdio_ctrl;
+
+	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+		mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
+		if (mdio_ctrl < 0)
+			return mdio_ctrl;
+
+		an_c37_enabled = mdio_ctrl & AN_CL37_EN;
+		if (!an_c37_enabled) {
+			//Perform soft reset to initiate C37 auto-negotiation
+			ret = xpcs_soft_reset(xpcs, compat);
+			if (ret)
+				return ret;
+		}
+	}
+	return 0;
+}
+
+static int xpcs_switch_interface_mode(const struct xpcs_compat *compat,
+				      struct dw_xpcs *xpcs,
+				      phy_interface_t interface,
+				      unsigned int neg_mode)
+{
+	int ret;
+
+	if (xpcs->dev_flag == DW_DEV_TXGBE) {
+		ret = txgbe_xpcs_switch_mode(xpcs, interface);
+		if (ret)
+			return ret;
+	} else {
+		if (xpcs->interface != interface) {
+			xpcs->interface = interface;
+
+			switch (compat->an_mode) {
+			case DW_AN_C37_SGMII:
+				ret = xpcs_switch_to_aneg_c37_sgmii(compat,
+								    xpcs,
+								    neg_mode);
+				if (ret)
+					return ret;
+				break;
+			default:
+				return 0;
+			}
+		}
+	}
+	return 0;
+}
+
 int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
 		   const unsigned long *advertising, unsigned int neg_mode)
 {
@@ -858,11 +912,9 @@ int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
 	if (!compat)
 		return -ENODEV;
 
-	if (xpcs->dev_flag == DW_DEV_TXGBE) {
-		ret = txgbe_xpcs_switch_mode(xpcs, interface);
-		if (ret)
-			return ret;
-	}
+	ret = xpcs_switch_interface_mode(compat, xpcs, interface, neg_mode);
+	if (ret)
+		return ret;
 
 	switch (compat->an_mode) {
 	case DW_10GBASER:
-- 
2.34.1



From yong.liang.choong at linux.intel.com  Wed Feb 14 19:04:55 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:04:55 +0800
Subject: [PATCH net-next v5 5/9] arch: x86: Add IPC mailbox accessor function and add SoC register access
In-Reply-To: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
Message-ID: <20240215030500.3067426-6-yong.liang.choong@linux.intel.com>

From: "David E. Box" <david.e.box at linux.intel.com>

- Exports intel_pmc_ipc() for host access to the PMC IPC mailbox
- Add support to use IPC command allows host to access SoC registers
through PMC firmware that are otherwise inaccessible to the host due to
security policies.

Signed-off-by: David E. Box <david.e.box at linux.intel.com>
Signed-off-by: Chao Qin <chao.qin at intel.com>
Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
---
 MAINTAINERS                                   |  2 +
 arch/x86/Kconfig                              |  9 +++
 arch/x86/platform/intel/Makefile              |  1 +
 arch/x86/platform/intel/pmc_ipc.c             | 75 +++++++++++++++++++
 .../linux/platform_data/x86/intel_pmc_ipc.h   | 34 +++++++++
 5 files changed, 121 insertions(+)
 create mode 100644 arch/x86/platform/intel/pmc_ipc.c
 create mode 100644 include/linux/platform_data/x86/intel_pmc_ipc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 2b775f4369e0..0276f1d53caf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10996,8 +10996,10 @@ M:	Rajneesh Bhardwaj <irenic.rajneesh at gmail.com>
 M:	David E Box <david.e.box at intel.com>
 L:	platform-driver-x86 at vger.kernel.org
 S:	Maintained
+F:	arch/x86/platform/intel/pmc_ipc.c
 F:	Documentation/ABI/testing/sysfs-platform-intel-pmc
 F:	drivers/platform/x86/intel/pmc/
+F:	linux/platform_data/x86/intel_pmc_ipc.h
 
 INTEL PMIC GPIO DRIVERS
 M:	Andy Shevchenko <andy at kernel.org>
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5edec175b9bf..bceae28b9381 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -666,6 +666,15 @@ config X86_AMD_PLATFORM_DEVICE
 	  I2C and UART depend on COMMON_CLK to set clock. GPIO driver is
 	  implemented under PINCTRL subsystem.
 
+config INTEL_PMC_IPC
+	tristate "Intel Core SoC Power Management Controller IPC mailbox"
+	depends on ACPI
+	help
+	  This option enables sideband register access support for Intel SoC
+	  power management controller IPC mailbox.
+
+	  If you don't require the option or are in doubt, say N.
+
 config IOSF_MBI
 	tristate "Intel SoC IOSF Sideband support for SoC platforms"
 	depends on PCI
diff --git a/arch/x86/platform/intel/Makefile b/arch/x86/platform/intel/Makefile
index dbee3b00f9d0..470fc68de6ba 100644
--- a/arch/x86/platform/intel/Makefile
+++ b/arch/x86/platform/intel/Makefile
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_IOSF_MBI)			+= iosf_mbi.o
+obj-$(CONFIG_INTEL_PMC_IPC)		+= pmc_ipc.o
\ No newline at end of file
diff --git a/arch/x86/platform/intel/pmc_ipc.c b/arch/x86/platform/intel/pmc_ipc.c
new file mode 100644
index 000000000000..a96234982710
--- /dev/null
+++ b/arch/x86/platform/intel/pmc_ipc.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Intel Core SoC Power Management Controller IPC mailbox
+ *
+ * Copyright (c) 2023, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * Authors: Choong Yong Liang <yong.liang.choong at linux.intel.com>
+ *          David E. Box <david.e.box at linux.intel.com>
+ */
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/platform_data/x86/intel_pmc_ipc.h>
+
+#define PMC_IPCS_PARAM_COUNT           7
+
+int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, u32 *rbuf)
+{
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object params[PMC_IPCS_PARAM_COUNT] = {
+		{.type = ACPI_TYPE_INTEGER,},
+		{.type = ACPI_TYPE_INTEGER,},
+		{.type = ACPI_TYPE_INTEGER,},
+		{.type = ACPI_TYPE_INTEGER,},
+		{.type = ACPI_TYPE_INTEGER,},
+		{.type = ACPI_TYPE_INTEGER,},
+		{.type = ACPI_TYPE_INTEGER,},
+	};
+	struct acpi_object_list arg_list = { PMC_IPCS_PARAM_COUNT, params };
+	union acpi_object *obj;
+	int status;
+
+	if (!ipc_cmd || !rbuf)
+		return -EINVAL;
+
+	/*
+	 * 0: IPC Command
+	 * 1: IPC Sub Command
+	 * 2: Size
+	 * 3-6: Write Buffer for offset
+	 */
+	params[0].integer.value = ipc_cmd->cmd;
+	params[1].integer.value = ipc_cmd->sub_cmd;
+	params[2].integer.value = ipc_cmd->size;
+	params[3].integer.value = ipc_cmd->wbuf[0];
+	params[4].integer.value = ipc_cmd->wbuf[1];
+	params[5].integer.value = ipc_cmd->wbuf[2];
+	params[6].integer.value = ipc_cmd->wbuf[3];
+
+	status = acpi_evaluate_object(NULL, "\\IPCS", &arg_list, &buffer);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	obj = buffer.pointer;
+	/* Check if the number of elements in package is 5 */
+	if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 5) {
+		const union acpi_object *objs = obj->package.elements;
+
+		if ((u8)objs[0].integer.value != 0)
+			return -EINVAL;
+
+		rbuf[0] = objs[1].integer.value;
+		rbuf[1] = objs[2].integer.value;
+		rbuf[2] = objs[3].integer.value;
+		rbuf[3] = objs[4].integer.value;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(intel_pmc_ipc);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Intel PMC IPC Mailbox accessor");
diff --git a/include/linux/platform_data/x86/intel_pmc_ipc.h b/include/linux/platform_data/x86/intel_pmc_ipc.h
new file mode 100644
index 000000000000..d47b89f873fc
--- /dev/null
+++ b/include/linux/platform_data/x86/intel_pmc_ipc.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Intel Core SoC Power Management Controller Header File
+ *
+ * Copyright (c) 2023, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * Authors: Choong Yong Liang <yong.liang.choong at linux.intel.com>
+ *          David E. Box <david.e.box at linux.intel.com>
+ */
+#ifndef INTEL_PMC_IPC_H
+#define INTEL_PMC_IPC_H
+
+#define IPC_SOC_REGISTER_ACCESS			0xAA
+#define IPC_SOC_SUB_CMD_READ			0x00
+#define IPC_SOC_SUB_CMD_WRITE			0x01
+
+struct pmc_ipc_cmd {
+	u32 cmd;
+	u32 sub_cmd;
+	u32 size;
+	u32 wbuf[4];
+};
+
+/**
+ * intel_pmc_ipc() - PMC IPC Mailbox accessor
+ * @ipc_cmd:  struct pmc_ipc_cmd prepared with input to send
+ * @rbuf:     Allocated u32[4] array for returned IPC data
+ *
+ * Return: 0 on success. Non-zero on mailbox error
+ */
+int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, u32 *rbuf);
+
+#endif /* INTEL_PMC_IPC_H */
-- 
2.34.1



From yong.liang.choong at linux.intel.com  Wed Feb 14 19:04:56 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:04:56 +0800
Subject: [PATCH net-next v5 6/9] net: stmmac: configure SerDes on mac_finish
In-Reply-To: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
Message-ID: <20240215030500.3067426-7-yong.liang.choong@linux.intel.com>

SerDes will configure according to the provided interface mode after
finish a major reconfiguration of the interface mode.

Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 +++++++++++++
 include/linux/stmmac.h                            |  3 +++
 2 files changed, 16 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index dbd16fc38888..69a33e9f1a5c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1120,12 +1120,25 @@ static unsigned int stmmac_get_pcs_neg_mode(struct phylink_config *config,
 	return neg_mode;
 }
 
+static int stmmac_mac_finish(struct phylink_config *config, unsigned int mode,
+			     phy_interface_t interface)
+{
+	struct net_device *ndev = to_net_dev(config->dev);
+	struct stmmac_priv *priv = netdev_priv(ndev);
+
+	if (priv->plat->config_serdes)
+		priv->plat->config_serdes(ndev, priv->plat->bsp_priv, interface);
+
+	return 0;
+}
+
 static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
 	.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,
 	.mac_get_pcs_neg_mode = stmmac_get_pcs_neg_mode,
+	.mac_finish = stmmac_mac_finish,
 };
 
 /**
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index ffd66722eeda..fd3d7d25f871 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -279,6 +279,9 @@ struct plat_stmmacenet_data {
 	void (*speed_mode_2500)(struct net_device *ndev, void *priv);
 	unsigned int (*get_pcs_neg_mode)(phy_interface_t interface,
 					 struct pci_dev *pdev);
+	int (*config_serdes)(struct net_device *ndev,
+			     void *priv,
+			     phy_interface_t interface);
 	void (*ptp_clk_freq_config)(struct stmmac_priv *priv);
 	int (*init)(struct platform_device *pdev, void *priv);
 	void (*exit)(struct platform_device *pdev, void *priv);
-- 
2.34.1



From yong.liang.choong at linux.intel.com  Wed Feb 14 19:04:57 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:04:57 +0800
Subject: [PATCH net-next v5 7/9] stmmac: intel: configure SerDes according to the interface mode
In-Reply-To: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
Message-ID: <20240215030500.3067426-8-yong.liang.choong@linux.intel.com>

From: "Tan, Tee Min" <tee.min.tan at linux.intel.com>

Intel platform will configure the SerDes through PMC api based on the
provided interface mode.

This patch adds several new functions below:-
- intel_tsn_interface_is_available(): This new function reads FIA lane
  ownership registers and common lane registers through IPC commands
  to know which lane the mGbE port is assigned to.
- intel_config_serdes(): To configure the SerDes based on the assigned
  lane and latest interface mode, it sends IPC command to the PMC through
  PMC driver/API. The PMC acts as a proxy for R/W on behalf of the driver.
- intel_set_reg_access(): Set the register access to the available TSN
  interface.

Signed-off-by: Tan, Tee Min <tee.min.tan at linux.intel.com>
Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |   2 +
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 115 +++++++++++++++++-
 .../net/ethernet/stmicro/stmmac/dwmac-intel.h |  75 ++++++++++++
 3 files changed, 191 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 4ec61f1ee71a..25405c305a21 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -273,6 +273,8 @@ config DWMAC_INTEL
 	default X86
 	depends on X86 && STMMAC_ETH && PCI
 	depends on COMMON_CLK
+	depends on ACPI
+	select INTEL_PMC_IPC
 	help
 	  This selects the Intel platform specific bus support for the
 	  stmmac driver. This driver is used for Intel Quark/EHL/TGL.
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 6f12e80b8a05..74cc0aa96faf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -5,6 +5,7 @@
 #include <linux/clk-provider.h>
 #include <linux/pci.h>
 #include <linux/dmi.h>
+#include <linux/platform_data/x86/intel_pmc_ipc.h>
 #include "dwmac-intel.h"
 #include "dwmac4.h"
 #include "stmmac.h"
@@ -14,6 +15,9 @@ struct intel_priv_data {
 	int mdio_adhoc_addr;	/* mdio address for serdes & etc */
 	unsigned long crossts_adj;
 	bool is_pse;
+	const int *tsn_lane_registers;
+	int max_tsn_lane_registers;
+	int pid_modphy;
 };
 
 /* This struct is used to associate PCI Function of MAC controller on a board,
@@ -93,7 +97,7 @@ static int intel_serdes_powerup(struct net_device *ndev, void *priv_data)
 	data &= ~SERDES_RATE_MASK;
 	data &= ~SERDES_PCLK_MASK;
 
-	if (priv->plat->max_speed == 2500)
+	if (priv->plat->phy_interface == PHY_INTERFACE_MODE_2500BASEX)
 		data |= SERDES_RATE_PCIE_GEN2 << SERDES_RATE_PCIE_SHIFT |
 			SERDES_PCLK_37p5MHZ << SERDES_PCLK_SHIFT;
 	else
@@ -447,6 +451,103 @@ static unsigned int intel_get_pcs_neg_mode(phy_interface_t interface,
 	return neg_mode;
 }
 
+static bool intel_tsn_interface_is_available(struct net_device *ndev,
+					     struct intel_priv_data *intel_priv)
+{
+	struct stmmac_priv *priv = netdev_priv(ndev);
+	struct pmc_ipc_cmd tmp = {0};
+	u32 rbuf[4] = {0};
+	int ret, i, j;
+
+	if (priv->plat->serdes_powerup) {
+		tmp.cmd = IPC_SOC_REGISTER_ACCESS;
+		tmp.sub_cmd = IPC_SOC_SUB_CMD_READ;
+
+		for (i = 0; i < 5; i++) {
+			tmp.wbuf[0] = R_PCH_FIA_15_PCR_LOS1_REG_BASE + i;
+
+			ret = intel_pmc_ipc(&tmp, rbuf);
+			if (ret < 0) {
+				netdev_info(priv->dev,
+					    "Failed to read from PMC.\n");
+				return false;
+			}
+
+			for (j = 0; j <= intel_priv->max_tsn_lane_registers; j++)
+				if ((rbuf[0] >>
+				    (4 * (intel_priv->tsn_lane_registers[j] % 8)) &
+				     B_PCH_FIA_PCR_L0O) == 0xB)
+					return true;
+		}
+	}
+	return false;
+}
+
+static int intel_set_reg_access(const struct pmc_serdes_regs *regs, int max_regs)
+{
+	int ret = 0, i;
+
+	for (i = 0; i < max_regs; i++) {
+		struct pmc_ipc_cmd tmp = {0};
+		u32 buf[4] = {0};
+
+		tmp.cmd = IPC_SOC_REGISTER_ACCESS;
+		tmp.sub_cmd = IPC_SOC_SUB_CMD_WRITE;
+		tmp.wbuf[0] = (u32)regs[i].index;
+		tmp.wbuf[1] = regs[i].val;
+
+		ret = intel_pmc_ipc(&tmp, buf);
+		if (ret < 0)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int intel_config_serdes(struct net_device *ndev,
+			       void *intel_data,
+			       phy_interface_t interface)
+{
+	struct intel_priv_data *intel_priv = intel_data;
+	struct stmmac_priv *priv = netdev_priv(ndev);
+	int ret = 0;
+
+	if (!intel_tsn_interface_is_available(ndev, intel_priv)) {
+		netdev_info(priv->dev,
+			    "No TSN interface available to set the registers.\n");
+		goto pmc_read_error;
+	}
+
+	if (intel_priv->pid_modphy == PID_MODPHY1) {
+		if (interface == PHY_INTERFACE_MODE_2500BASEX) {
+			ret = intel_set_reg_access(pid_modphy1_2p5g_regs,
+						   ARRAY_SIZE(pid_modphy1_2p5g_regs));
+		} else {
+			ret = intel_set_reg_access(pid_modphy1_1g_regs,
+						   ARRAY_SIZE(pid_modphy1_1g_regs));
+		}
+	} else {
+		if (interface == PHY_INTERFACE_MODE_2500BASEX) {
+			ret = intel_set_reg_access(pid_modphy3_2p5g_regs,
+						   ARRAY_SIZE(pid_modphy3_2p5g_regs));
+		} else {
+			ret = intel_set_reg_access(pid_modphy3_1g_regs,
+						   ARRAY_SIZE(pid_modphy3_1g_regs));
+		}
+	}
+
+	priv->plat->phy_interface = interface;
+
+	if (ret < 0)
+		goto pmc_read_error;
+
+pmc_read_error:
+	intel_serdes_powerdown(ndev, intel_priv);
+	intel_serdes_powerup(ndev, intel_priv);
+
+	return ret;
+}
+
 static void common_default_data(struct plat_stmmacenet_data *plat)
 {
 	plat->clk_csr = 2;	/* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
@@ -622,6 +723,15 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
 		plat->mdio_bus_data->xpcs_an_inband = true;
 	}
 
+	/* When the platform is able to switch between PHY_INTERFACE_MODE_SGMII
+	 * and PHY_INTERFACE_MODE_2500BASEX interfaces, we clear xpcs_an_inband
+	 * for PHY_INTERFACE_MODE_2500BASEX interface
+	 */
+	if (plat->phy_interface == PHY_INTERFACE_MODE_SGMII &&
+	    plat->max_speed == 2500) {
+		plat->mdio_bus_data->xpcs_an_inband = false;
+	}
+
 	/* For fixed-link setup, we clear xpcs_an_inband */
 	if (is_fixed_link(pdev))
 		plat->mdio_bus_data->xpcs_an_inband = false;
@@ -676,6 +786,7 @@ static int ehl_sgmii_data(struct pci_dev *pdev,
 	plat->serdes_powerup = intel_serdes_powerup;
 	plat->serdes_powerdown = intel_serdes_powerdown;
 	plat->get_pcs_neg_mode = intel_get_pcs_neg_mode;
+	plat->config_serdes = intel_config_serdes;
 	plat->clk_ptp_rate = 204800000;
 
 	return ehl_common_data(pdev, plat);
@@ -735,6 +846,7 @@ static int ehl_pse0_sgmii1g_data(struct pci_dev *pdev,
 	plat->serdes_powerup = intel_serdes_powerup;
 	plat->serdes_powerdown = intel_serdes_powerdown;
 	plat->get_pcs_neg_mode = intel_get_pcs_neg_mode;
+	plat->config_serdes = intel_config_serdes;
 	return ehl_pse0_common_data(pdev, plat);
 }
 
@@ -777,6 +889,7 @@ static int ehl_pse1_sgmii1g_data(struct pci_dev *pdev,
 	plat->serdes_powerup = intel_serdes_powerup;
 	plat->serdes_powerdown = intel_serdes_powerdown;
 	plat->get_pcs_neg_mode = intel_get_pcs_neg_mode;
+	plat->config_serdes = intel_config_serdes;
 	return ehl_pse1_common_data(pdev, plat);
 }
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
index 0a37987478c1..79c35ba969ea 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
@@ -50,4 +50,79 @@
 #define PCH_PTP_CLK_FREQ_19_2MHZ	(GMAC_GPO0)
 #define PCH_PTP_CLK_FREQ_200MHZ		(0)
 
+#define	PID_MODPHY1 0xAA
+#define	PID_MODPHY3 0xA8
+
+#if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
+struct pmc_serdes_regs {
+	u8 index;
+	u32 val;
+};
+
+/* Modphy Register index */
+#define R_PCH_FIA_15_PCR_LOS1_REG_BASE			8
+#define R_PCH_FIA_15_PCR_LOS2_REG_BASE			9
+#define R_PCH_FIA_15_PCR_LOS3_REG_BASE			10
+#define R_PCH_FIA_15_PCR_LOS4_REG_BASE			11
+#define R_PCH_FIA_15_PCR_LOS5_REG_BASE			12
+#define B_PCH_FIA_PCR_L0O				GENMASK(3, 0)
+#define PID_MODPHY1_B_MODPHY_PCR_LCPLL_DWORD0		13
+#define PID_MODPHY1_N_MODPHY_PCR_LCPLL_DWORD2		14
+#define PID_MODPHY1_N_MODPHY_PCR_LCPLL_DWORD7		15
+#define PID_MODPHY1_N_MODPHY_PCR_LPPLL_DWORD10		16
+#define PID_MODPHY1_N_MODPHY_PCR_CMN_ANA_DWORD30	17
+#define PID_MODPHY3_B_MODPHY_PCR_LCPLL_DWORD0		18
+#define PID_MODPHY3_N_MODPHY_PCR_LCPLL_DWORD2		19
+#define PID_MODPHY3_N_MODPHY_PCR_LCPLL_DWORD7		20
+#define PID_MODPHY3_N_MODPHY_PCR_LPPLL_DWORD10		21
+#define PID_MODPHY3_N_MODPHY_PCR_CMN_ANA_DWORD30	22
+
+#define B_MODPHY_PCR_LCPLL_DWORD0_1G		0x46AAAA41
+#define N_MODPHY_PCR_LCPLL_DWORD2_1G		0x00000139
+#define N_MODPHY_PCR_LCPLL_DWORD7_1G		0x002A0003
+#define N_MODPHY_PCR_LPPLL_DWORD10_1G		0x00170008
+#define N_MODPHY_PCR_CMN_ANA_DWORD30_1G		0x0000D4AC
+#define B_MODPHY_PCR_LCPLL_DWORD0_2P5G		0x58555551
+#define N_MODPHY_PCR_LCPLL_DWORD2_2P5G		0x0000012D
+#define N_MODPHY_PCR_LCPLL_DWORD7_2P5G		0x001F0003
+#define N_MODPHY_PCR_LPPLL_DWORD10_2P5G		0x00170008
+#define N_MODPHY_PCR_CMN_ANA_DWORD30_2P5G	0x8200ACAC
+
+static const struct pmc_serdes_regs pid_modphy3_1g_regs[] = {
+	{ PID_MODPHY3_B_MODPHY_PCR_LCPLL_DWORD0,	B_MODPHY_PCR_LCPLL_DWORD0_1G },
+	{ PID_MODPHY3_N_MODPHY_PCR_LCPLL_DWORD2,	N_MODPHY_PCR_LCPLL_DWORD2_1G },
+	{ PID_MODPHY3_N_MODPHY_PCR_LCPLL_DWORD7,	N_MODPHY_PCR_LCPLL_DWORD7_1G },
+	{ PID_MODPHY3_N_MODPHY_PCR_LPPLL_DWORD10,	N_MODPHY_PCR_LPPLL_DWORD10_1G },
+	{ PID_MODPHY3_N_MODPHY_PCR_CMN_ANA_DWORD30,	N_MODPHY_PCR_CMN_ANA_DWORD30_1G },
+	{}
+};
+
+static const struct pmc_serdes_regs pid_modphy3_2p5g_regs[] = {
+	{ PID_MODPHY3_B_MODPHY_PCR_LCPLL_DWORD0,	B_MODPHY_PCR_LCPLL_DWORD0_2P5G },
+	{ PID_MODPHY3_N_MODPHY_PCR_LCPLL_DWORD2,	N_MODPHY_PCR_LCPLL_DWORD2_2P5G },
+	{ PID_MODPHY3_N_MODPHY_PCR_LCPLL_DWORD7,	N_MODPHY_PCR_LCPLL_DWORD7_2P5G },
+	{ PID_MODPHY3_N_MODPHY_PCR_LPPLL_DWORD10,	N_MODPHY_PCR_LPPLL_DWORD10_2P5G },
+	{ PID_MODPHY3_N_MODPHY_PCR_CMN_ANA_DWORD30,	N_MODPHY_PCR_CMN_ANA_DWORD30_2P5G },
+	{}
+};
+
+static const struct pmc_serdes_regs pid_modphy1_1g_regs[] = {
+	{ PID_MODPHY1_B_MODPHY_PCR_LCPLL_DWORD0,	B_MODPHY_PCR_LCPLL_DWORD0_1G },
+	{ PID_MODPHY1_N_MODPHY_PCR_LCPLL_DWORD2,	N_MODPHY_PCR_LCPLL_DWORD2_1G },
+	{ PID_MODPHY1_N_MODPHY_PCR_LCPLL_DWORD7,	N_MODPHY_PCR_LCPLL_DWORD7_1G },
+	{ PID_MODPHY1_N_MODPHY_PCR_LPPLL_DWORD10,	N_MODPHY_PCR_LPPLL_DWORD10_1G },
+	{ PID_MODPHY1_N_MODPHY_PCR_CMN_ANA_DWORD30,	N_MODPHY_PCR_CMN_ANA_DWORD30_1G },
+	{}
+};
+
+static const struct pmc_serdes_regs pid_modphy1_2p5g_regs[] = {
+	{ PID_MODPHY1_B_MODPHY_PCR_LCPLL_DWORD0,	B_MODPHY_PCR_LCPLL_DWORD0_2P5G },
+	{ PID_MODPHY1_N_MODPHY_PCR_LCPLL_DWORD2,	N_MODPHY_PCR_LCPLL_DWORD2_2P5G },
+	{ PID_MODPHY1_N_MODPHY_PCR_LCPLL_DWORD7,	N_MODPHY_PCR_LCPLL_DWORD7_2P5G },
+	{ PID_MODPHY1_N_MODPHY_PCR_LPPLL_DWORD10,	N_MODPHY_PCR_LPPLL_DWORD10_2P5G },
+	{ PID_MODPHY1_N_MODPHY_PCR_CMN_ANA_DWORD30,	N_MODPHY_PCR_CMN_ANA_DWORD30_2P5G },
+	{}
+};
+#endif /* CONFIG_INTEL_PMC_IPC */
+
 #endif /* __DWMAC_INTEL_H__ */
-- 
2.34.1



From yong.liang.choong at linux.intel.com  Wed Feb 14 19:04:58 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:04:58 +0800
Subject: [PATCH net-next v5 8/9] stmmac: intel: interface switching support for EHL platform
In-Reply-To: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
Message-ID: <20240215030500.3067426-9-yong.liang.choong@linux.intel.com>

'intel_get_pcs_neg_mode' and 'intel_config_serdes' was provided to
handle interface mode change for EHL platform.

Modphy register lane was provided to configure serdes on interface
mode changing.

Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 21 +++++++++++++++++--
 .../net/ethernet/stmicro/stmmac/dwmac-intel.h |  4 ++++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 74cc0aa96faf..c79d8e3c3b24 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -759,6 +759,8 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
 static int ehl_common_data(struct pci_dev *pdev,
 			   struct plat_stmmacenet_data *plat)
 {
+	struct intel_priv_data *intel_priv = plat->bsp_priv;
+
 	plat->rx_queues_to_use = 8;
 	plat->tx_queues_to_use = 8;
 	plat->flags |= STMMAC_FLAG_USE_PHY_WOL;
@@ -774,21 +776,28 @@ static int ehl_common_data(struct pci_dev *pdev,
 	plat->safety_feat_cfg->prtyen = 0;
 	plat->safety_feat_cfg->tmouten = 0;
 
+	intel_priv->tsn_lane_registers = ehl_tsn_lane_registers;
+	intel_priv->max_tsn_lane_registers = ARRAY_SIZE(ehl_tsn_lane_registers);
+
 	return intel_mgbe_common_data(pdev, plat);
 }
 
 static int ehl_sgmii_data(struct pci_dev *pdev,
 			  struct plat_stmmacenet_data *plat)
 {
+	struct intel_priv_data *intel_priv = plat->bsp_priv;
+
 	plat->bus_id = 1;
 	plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
-	plat->speed_mode_2500 = intel_speed_mode_2500;
+	plat->max_speed = SPEED_2500;
 	plat->serdes_powerup = intel_serdes_powerup;
 	plat->serdes_powerdown = intel_serdes_powerdown;
 	plat->get_pcs_neg_mode = intel_get_pcs_neg_mode;
 	plat->config_serdes = intel_config_serdes;
 	plat->clk_ptp_rate = 204800000;
 
+	intel_priv->pid_modphy = PID_MODPHY3;
+
 	return ehl_common_data(pdev, plat);
 }
 
@@ -841,12 +850,16 @@ static struct stmmac_pci_info ehl_pse0_rgmii1g_info = {
 static int ehl_pse0_sgmii1g_data(struct pci_dev *pdev,
 				 struct plat_stmmacenet_data *plat)
 {
+	struct intel_priv_data *intel_priv = plat->bsp_priv;
+
 	plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
-	plat->speed_mode_2500 = intel_speed_mode_2500;
+	plat->max_speed = SPEED_2500;
 	plat->serdes_powerup = intel_serdes_powerup;
 	plat->serdes_powerdown = intel_serdes_powerdown;
 	plat->get_pcs_neg_mode = intel_get_pcs_neg_mode;
 	plat->config_serdes = intel_config_serdes;
+	intel_priv->pid_modphy = PID_MODPHY1;
+
 	return ehl_pse0_common_data(pdev, plat);
 }
 
@@ -884,12 +897,16 @@ static struct stmmac_pci_info ehl_pse1_rgmii1g_info = {
 static int ehl_pse1_sgmii1g_data(struct pci_dev *pdev,
 				 struct plat_stmmacenet_data *plat)
 {
+	struct intel_priv_data *intel_priv = plat->bsp_priv;
+
 	plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
 	plat->speed_mode_2500 = intel_speed_mode_2500;
 	plat->serdes_powerup = intel_serdes_powerup;
 	plat->serdes_powerdown = intel_serdes_powerdown;
 	plat->get_pcs_neg_mode = intel_get_pcs_neg_mode;
 	plat->config_serdes = intel_config_serdes;
+	intel_priv->pid_modphy = PID_MODPHY1;
+
 	return ehl_pse1_common_data(pdev, plat);
 }
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
index 79c35ba969ea..093eed977ab0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
@@ -123,6 +123,10 @@ static const struct pmc_serdes_regs pid_modphy1_2p5g_regs[] = {
 	{ PID_MODPHY1_N_MODPHY_PCR_CMN_ANA_DWORD30,	N_MODPHY_PCR_CMN_ANA_DWORD30_2P5G },
 	{}
 };
+
+static const int ehl_tsn_lane_registers[] = {7, 8, 9, 10, 11};
+#else
+static const int ehl_tsn_lane_registers[] = {};
 #endif /* CONFIG_INTEL_PMC_IPC */
 
 #endif /* __DWMAC_INTEL_H__ */
-- 
2.34.1



From yong.liang.choong at linux.intel.com  Wed Feb 14 19:04:59 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:04:59 +0800
Subject: [PATCH net-next v5 9/9] stmmac: intel: interface switching support for ADL-N platform
In-Reply-To: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
Message-ID: <20240215030500.3067426-10-yong.liang.choong@linux.intel.com>

'intel_get_pcs_neg_mode' and 'intel_config_serdes' was provided to
handle interface mode change for ADL-S platform.

Modphy register lane was provided to configure serdes on interface
mode changing.

Signed-off-by: Michael Sit Wei Hong <michael.wei.hong.sit at intel.com>
Signed-off-by: Choong Yong Liang <yong.liang.choong at linux.intel.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 49 ++++++++++++++++++-
 .../net/ethernet/stmicro/stmmac/dwmac-intel.h |  2 +
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index c79d8e3c3b24..f0f3d35bdb69 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -992,6 +992,53 @@ static int adls_sgmii_phy1_data(struct pci_dev *pdev,
 static struct stmmac_pci_info adls_sgmii1g_phy1_info = {
 	.setup = adls_sgmii_phy1_data,
 };
+
+static int adln_common_data(struct pci_dev *pdev,
+			    struct plat_stmmacenet_data *plat)
+{
+	struct intel_priv_data *intel_priv = plat->bsp_priv;
+
+	plat->rx_queues_to_use = 6;
+	plat->tx_queues_to_use = 4;
+	plat->clk_ptp_rate = 204800000;
+
+	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 = 0;
+	plat->safety_feat_cfg->prtyen = 0;
+	plat->safety_feat_cfg->tmouten = 0;
+
+	intel_priv->tsn_lane_registers = adln_tsn_lane_registers;
+	intel_priv->max_tsn_lane_registers = ARRAY_SIZE(adln_tsn_lane_registers);
+
+	return intel_mgbe_common_data(pdev, plat);
+}
+
+static int adln_sgmii_phy0_data(struct pci_dev *pdev,
+				struct plat_stmmacenet_data *plat)
+{
+	struct intel_priv_data *intel_priv = plat->bsp_priv;
+
+	plat->bus_id = 1;
+	plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+	plat->max_speed = SPEED_2500;
+	plat->serdes_powerup = intel_serdes_powerup;
+	plat->serdes_powerdown = intel_serdes_powerdown;
+	plat->get_pcs_neg_mode = intel_get_pcs_neg_mode;
+	plat->config_serdes = intel_config_serdes;
+	intel_priv->pid_modphy = PID_MODPHY1;
+
+	return adln_common_data(pdev, plat);
+}
+
+static struct stmmac_pci_info adln_sgmii1g_phy0_info = {
+	.setup = adln_sgmii_phy0_data,
+};
+
 static const struct stmmac_pci_func_data galileo_stmmac_func_data[] = {
 	{
 		.func = 6,
@@ -1374,7 +1421,7 @@ static const struct pci_device_id intel_eth_pci_id_table[] = {
 	{ PCI_DEVICE_DATA(INTEL, TGLH_SGMII1G_1, &tgl_sgmii1g_phy1_info) },
 	{ PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_0, &adls_sgmii1g_phy0_info) },
 	{ PCI_DEVICE_DATA(INTEL, ADLS_SGMII1G_1, &adls_sgmii1g_phy1_info) },
-	{ PCI_DEVICE_DATA(INTEL, ADLN_SGMII1G, &tgl_sgmii1g_phy0_info) },
+	{ PCI_DEVICE_DATA(INTEL, ADLN_SGMII1G, &adln_sgmii1g_phy0_info) },
 	{ PCI_DEVICE_DATA(INTEL, RPLP_SGMII1G, &tgl_sgmii1g_phy0_info) },
 	{}
 };
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
index 093eed977ab0..2c6b50958988 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
@@ -124,8 +124,10 @@ static const struct pmc_serdes_regs pid_modphy1_2p5g_regs[] = {
 	{}
 };
 
+static const int adln_tsn_lane_registers[] = {6};
 static const int ehl_tsn_lane_registers[] = {7, 8, 9, 10, 11};
 #else
+static const int adln_tsn_lane_registers[] = {};
 static const int ehl_tsn_lane_registers[] = {};
 #endif /* CONFIG_INTEL_PMC_IPC */
 
-- 
2.34.1



From yong.liang.choong at linux.intel.com  Wed Feb 14 19:14:27 2024
From: yong.liang.choong at linux.intel.com (Choong Yong Liang)
Date: Thu, 15 Feb 2024 11:14:27 +0800
Subject: [PATCH net-next v4 06/11] net: stmmac: resetup XPCS according to
 the new interface mode
In-Reply-To: <Zbys2orOUikYxeOm@shell.armlinux.org.uk>
References: <20240129130253.1400707-1-yong.liang.choong@linux.intel.com>
 <20240129130253.1400707-7-yong.liang.choong@linux.intel.com>
 <ZbjNn+C/VHegH2t7@shell.armlinux.org.uk>
 <9e23671e-788c-4191-bdb4-94915ff7da5a@linux.intel.com>
 <ZbtYaXkNf2ZF1prE@shell.armlinux.org.uk>
 <2ad1f55c-f361-4439-9174-6af1bb429d55@linux.intel.com>
 <Zbys2orOUikYxeOm@shell.armlinux.org.uk>
Message-ID: <9154ea9e-863b-49b3-8729-1ba077872bcc@linux.intel.com>



On 2/2/2024 4:50 pm, Russell King (Oracle) wrote:
>> Thank you for taking the time to review, got your concerns, and I'll address
>> the following concerns before submitting a new patch series:
>>
>> 1. Remove allow_switch_interface and have the PHY driver fill in
>> phydev->possible_interfaces.
> 
> Yes please.
> 

Hi Russell,

I regret to inform you that I didn't implement everything exactly as 
proposed in the new patch series. My intention was to simplify the series, 
focusing solely on managing SGMII and 2500BASE-X interface mode switching. 
The recommendation to have the PHY driver fill in 
"phydev->possible_interfaces" will be addressed in a separate patch 
submission. I hope this is acceptable.

In the new patch series, I removed "allow_switch_interface" patches. The 
current solution continues to work with PHYs that are C45 and follow the 
legacy path, such as Marvell Alaska 88E2110. For the upcoming patch series, 
I will implement "phydev->possible_interfaces" for C22 and C45 PHYs.


>> 2. Rework on the PCS to have similar implementation with the following patch
>> "net: macb: use .mac_select_pcs() interface"
>> (https://lore.kernel.org/netdev/E1n568J-002SZX-Gr at rmk-PC.armlinux.org.uk/T/).
> 
> mac_select_pcs() is about returning to phylink the PCS that the MAC
> needs to use for the specified interface mode, or NULL if no PCS is
> required, nothing more, nothing less.
> 
> Plase do not copy that mac_select_pcs() implementation - changing the
> "ops" underneath phylink is no longer permitted.
> 

Upon further examination, I discovered that no change is required for the 
"mac_select_pcs()" function; we can still use the same PCS. According to 
the XPCS datasheet, a soft reset is necessary to re-initiate Clause 37 
auto-negotiation when switching to SGMII interface mode. This is the only 
setting required for properly configuring the SGMII interface mode, and 
nothing extra is needed for 2500BASE-X configuration.

In the new patch series, I removed "mac_select_pcs()" related patches and 
added a "xpcs_soft_reset()" patch for the XPCS.


From tzungbi at kernel.org  Wed Feb 14 19:37:42 2024
From: tzungbi at kernel.org (Tzung-Bi Shih)
Date: Thu, 15 Feb 2024 11:37:42 +0800
Subject: [PATCH v4 0/4] Allow coreboot modules to autoload and enable
 cbmem in the arm64 defconfig
In-Reply-To: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
References: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
Message-ID: <Zc2HBmDPJnHt0WJC@google.com>

On Mon, Feb 12, 2024 at 09:50:04AM -0500, N?colas F. R. A. Prado wrote:
> This series adds the missing pieces to the coreboot bus and the module
> alias generation to allow coreboot modules to be automatically loaded
> when matching devices are detected.
> 
> The configs for cbmem coreboot entries are then enabled in the arm64
> defconfig, as modules, to allow reading logs from coreboot on arm64
> Chromebooks, which is useful for debugging the boot process.
> 
> [...]
> 
> ---
> N?colas F. R. A. Prado (4):
>       firmware: coreboot: Generate modalias uevent for devices
>       firmware: coreboot: Generate aliases for coreboot modules
>       firmware: coreboot: Replace tag with id table in driver struct
>       arm64: defconfig: Enable support for cbmem entries in the coreboot table
> 
>  arch/arm64/configs/defconfig                   |  3 +++

Hi Catalin and Will,

Is it OK to you if I pick the 4th patch (which touches the above files) to
chrome-platform-firmware tree for the next merge window?

>  include/linux/mod_devicetable.h                | 10 ++++++++++
>  scripts/mod/devicetable-offsets.c              |  3 +++
>  scripts/mod/file2alias.c                       | 10 ++++++++++

Hi Masahiro,

Is it OK to you if I pick the 2nd patch (which touches the above files) to
chrome-platform-firmware tree for the next merge window?


From vigneshr at ti.com  Wed Feb 14 20:17:07 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 15 Feb 2024 09:47:07 +0530
Subject: [PATCH v4 1/4] arm64: dts: ti: k3-j784s4: Add Wave5 Video
 Encoder/Decoder Node
In-Reply-To: <20240205194706.3605309-2-b-brnich@ti.com>
References: <20240205194706.3605309-1-b-brnich@ti.com>
 <20240205194706.3605309-2-b-brnich@ti.com>
Message-ID: <52608865-b3db-45a9-907f-e954cce88b51@ti.com>

Hi Brandon

On 06/02/24 01:17, Brandon Brnich wrote:
> This patch adds support for the Wave521cl on the J784S4-evm.
> 
> Signed-off-by: Brandon Brnich <b-brnich at ti.com>
> ---
>  arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 18 ++++++++++++++++++
>  arch/arm64/boot/dts/ti/k3-j784s4.dtsi      |  2 ++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> index f2b720ed1e4f..e628e748f215 100644
> --- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
> @@ -662,6 +662,24 @@ main_i2c6: i2c at 2060000 {
>  		status = "disabled";
>  	};
>  
> +	vpu0: video-codec at 4210000 {
> +		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
> +		reg = <0x00 0x4210000 0x00 0x10000>;
> +		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&k3_clks 241 2>;
> +		clock-names = "vcodec";

Binding doesn't allow clock-names [0]

[0] Documentation/devicetree/bindings/media/cnm,wave521c.yaml

> +		power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>;
> +	};
> +
> +	vpu1: video-codec at 4220000 {
> +		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
> +		reg = <0x00 0x4220000 0x00 0x10000>;
> +		interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&k3_clks 242 2>;
> +		clock-names = "vcodec";
> +		power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
> +	};
> +
>  	main_sdhci0: mmc at 4f80000 {
>  		compatible = "ti,j721e-sdhci-8bit";
>  		reg = <0x00 0x04f80000 0x00 0x1000>,
> diff --git a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
> index 4398c3a463e1..2f633721a0c6 100644
> --- a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
> @@ -235,6 +235,8 @@ cbass_main: bus at 100000 {
>  		ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
>  			 <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
>  			 <0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */
> +			 <0x00 0x04210000 0x00 0x04210000 0x00 0x00010000>, /* VPU0 */
> +			 <0x00 0x04220000 0x00 0x04220000 0x00 0x00010000>, /* VPU1 */
>  			 <0x00 0x0d000000 0x00 0x0d000000 0x00 0x01000000>, /* PCIe Core*/
>  			 <0x00 0x10000000 0x00 0x10000000 0x00 0x08000000>, /* PCIe0 DAT0 */
>  			 <0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */

-- 
Regards
Vignesh


From quic_snehshah at quicinc.com  Wed Feb 14 20:47:41 2024
From: quic_snehshah at quicinc.com (Sneh Shah)
Date: Thu, 15 Feb 2024 10:17:41 +0530
Subject: [PATCH net-next v4] net: stmmac: dwmac-qcom-ethqos: Add support
 for 2.5G SGMII
In-Reply-To: <20240212173015.0341f0ee@kernel.org>
References: <20240208111714.11456-1-quic_snehshah@quicinc.com>
 <20240212173015.0341f0ee@kernel.org>
Message-ID: <7a567b50-66f1-4737-ae6c-0dabd1d39bcf@quicinc.com>



On 2/13/2024 7:00 AM, Jakub Kicinski wrote:
> On Thu,  8 Feb 2024 16:47:14 +0530 Sneh Shah wrote:
>> Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000
>> mode for 1G/100M/10M speed.
>> Added changes to configure serdes phy and mac based on link speed.
>> Changing serdes phy speed involves multiple register writes for
>> serdes block. To avoid redundant write operations only update serdes
>> phy when new speed is different.
> 
> Sounds like 2 separate changes in one patch, please split the
> optimization of not writing the registers multiple times and
> the 2.5G support.
> 

Optimization is part of 2.5G support change only. with introduction of
2.5G speed support we need to update reconfigure serdes phy. there are
2 different serdes configs.
1. config for 2.5G
2. common config 1G/100M/10M

The change here is not to reconfigure serdes phy among
1G/100M/10M speeds and only reconfigure if it switches to 2.5G.

>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
>> index 31631e3f89d0..6bbdbb7bef44 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
>> @@ -106,6 +106,7 @@ struct qcom_ethqos {
>>  	struct clk *link_clk;
>>  	struct phy *serdes_phy;
>>  	unsigned int speed;
>> +	int serdes_speed;
> 
> Why signed if speed itself is unsigned?

In stmmac speed can be assigned as SPEED_UNKNOWN which will be -1.
I will fix speed being unsigned int in a separate patch.

> 
>>  	/* Enable and restart the Auto-Negotiation */
>>  	if (ane)
>>  		value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN;
>> +	else
>> +		value &= ~GMAC_AN_CTRL_ANE;
> 
> That looks unrelated. Either a separate patch or please explain in the
> commit msg why.

For 2.5G speed support MAC PCS autoneg needs to be disabled.
This adds the change to disable PCS autoneg. I will update commit
message to add more dtails


From itaru.kitayama at linux.dev  Wed Feb 14 21:26:50 2024
From: itaru.kitayama at linux.dev (Itaru Kitayama)
Date: Thu, 15 Feb 2024 14:26:50 +0900
Subject: [PATCH v8 04/10] KVM: selftests: Add support for
 allocating/managing protected guest memory
In-Reply-To: <20240203000917.376631-5-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
 <20240203000917.376631-5-seanjc@google.com>
Message-ID: <Zc2gmlr2zgK690nu@vm3>

On Fri, Feb 02, 2024 at 04:09:10PM -0800, Sean Christopherson wrote:
> From: Peter Gonda <pgonda at google.com>
> 
> Add support for differentiating between protected (a.k.a. private, a.k.a.
> encrypted) memory and normal (a.k.a. shared) memory for VMs that support
> protected guest memory, e.g. x86's SEV.  Provide and manage a common
> bitmap for tracking whether a given physical page resides in protected
> memory, as support for protected memory isn't x86 specific, i.e. adding a
> arch hook would be a net negative now, and in the future.
> 
> Cc: Paolo Bonzini <pbonzini at redhat.com>
> Cc: Sean Christopherson <seanjc at google.com>
> Cc: Vishal Annapurve <vannapurve at google.com>
> Cc: Ackerley Tng <ackerleytng at google.com>
> cc: Andrew Jones <andrew.jones at linux.dev>
> Cc: Tom Lendacky <thomas.lendacky at amd.com>
> Cc: Michael Roth <michael.roth at amd.com>
> Originally-by: Michael Roth <michael.roth at amd.com>
> Signed-off-by: Peter Gonda <pgonda at google.com>
> Co-developed-by: Sean Christopherson <seanjc at google.com>
> Signed-off-by: Sean Christopherson <seanjc at google.com>
> ---
>  .../selftests/kvm/include/kvm_util_base.h     | 25 +++++++++++++++++--
>  tools/testing/selftests/kvm/lib/kvm_util.c    | 22 +++++++++++++---
>  2 files changed, 41 insertions(+), 6 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
> index d9dc31af2f96..a82149305349 100644
> --- a/tools/testing/selftests/kvm/include/kvm_util_base.h
> +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
> @@ -46,6 +46,7 @@ typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */
>  struct userspace_mem_region {
>  	struct kvm_userspace_memory_region2 region;
>  	struct sparsebit *unused_phy_pages;
> +	struct sparsebit *protected_phy_pages;
>  	int fd;
>  	off_t offset;
>  	enum vm_mem_backing_src_type backing_src_type;
> @@ -573,6 +574,13 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,
>  		uint64_t guest_paddr, uint32_t slot, uint64_t npages,
>  		uint32_t flags, int guest_memfd_fd, uint64_t guest_memfd_offset);
>  
> +#ifndef vm_arch_has_protected_memory
> +static inline bool vm_arch_has_protected_memory(struct kvm_vm *vm)
> +{
> +	return false;
> +}
> +#endif
> +
>  void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags);
>  void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa);
>  void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot);
> @@ -836,10 +844,23 @@ const char *exit_reason_str(unsigned int exit_reason);
>  
>  vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm, vm_paddr_t paddr_min,
>  			     uint32_t memslot);
> -vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
> -			      vm_paddr_t paddr_min, uint32_t memslot);
> +vm_paddr_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
> +				vm_paddr_t paddr_min, uint32_t memslot,
> +				bool protected);
>  vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm);
>  
> +static inline vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
> +					    vm_paddr_t paddr_min, uint32_t memslot)
> +{
> +	/*
> +	 * By default, allocate memory as protected for VMs that support
> +	 * protected memory, as the majority of memory for such VMs is
> +	 * protected, i.e. using shared memory is effectively opt-in.
> +	 */
> +	return __vm_phy_pages_alloc(vm, num, paddr_min, memslot,
> +				    vm_arch_has_protected_memory(vm));
> +}
> +
>  /*
>   * ____vm_create() does KVM_CREATE_VM and little else.  __vm_create() also
>   * loads the test binary into guest memory and creates an IRQ chip (x86 only).
> diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
> index a53caf81eb87..ea677aa019ef 100644
> --- a/tools/testing/selftests/kvm/lib/kvm_util.c
> +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
> @@ -717,6 +717,7 @@ static void __vm_mem_region_delete(struct kvm_vm *vm,
>  	vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION2, &region->region);
>  
>  	sparsebit_free(&region->unused_phy_pages);
> +	sparsebit_free(&region->protected_phy_pages);
>  	ret = munmap(region->mmap_start, region->mmap_size);
>  	TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("munmap()", ret));
>  	if (region->fd >= 0) {
> @@ -1098,6 +1099,8 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,
>  	}
>  
>  	region->unused_phy_pages = sparsebit_alloc();
> +	if (vm_arch_has_protected_memory(vm))
> +		region->protected_phy_pages = sparsebit_alloc();
>  	sparsebit_set_num(region->unused_phy_pages,
>  		guest_paddr >> vm->page_shift, npages);
>  	region->region.slot = slot;
> @@ -1924,6 +1927,10 @@ void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
>  			region->host_mem);
>  		fprintf(stream, "%*sunused_phy_pages: ", indent + 2, "");
>  		sparsebit_dump(stream, region->unused_phy_pages, 0);
> +		if (region->protected_phy_pages) {
> +			fprintf(stream, "%*sprotected_phy_pages: ", indent + 2, "");
> +			sparsebit_dump(stream, region->protected_phy_pages, 0);
> +		}
>  	}
>  	fprintf(stream, "%*sMapped Virtual Pages:\n", indent, "");
>  	sparsebit_dump(stream, vm->vpages_mapped, indent + 2);
> @@ -2025,6 +2032,7 @@ const char *exit_reason_str(unsigned int exit_reason)
>   *   num - number of pages
>   *   paddr_min - Physical address minimum
>   *   memslot - Memory region to allocate page from
> + *   protected - True if the pages will be used as protected/private memory
>   *
>   * Output Args: None
>   *
> @@ -2036,8 +2044,9 @@ const char *exit_reason_str(unsigned int exit_reason)
>   * and their base address is returned. A TEST_ASSERT failure occurs if
>   * not enough pages are available at or above paddr_min.
>   */
> -vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
> -			      vm_paddr_t paddr_min, uint32_t memslot)
> +vm_paddr_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
> +				vm_paddr_t paddr_min, uint32_t memslot,
> +				bool protected)
>  {
>  	struct userspace_mem_region *region;
>  	sparsebit_idx_t pg, base;
> @@ -2050,8 +2059,10 @@ vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
>  		paddr_min, vm->page_size);
>  
>  	region = memslot2region(vm, memslot);
> +	TEST_ASSERT(!protected || region->protected_phy_pages,
> +		    "Region doesn't support protected memory");
> +
>  	base = pg = paddr_min >> vm->page_shift;
> -
>  	do {
>  		for (; pg < base + num; ++pg) {
>  			if (!sparsebit_is_set(region->unused_phy_pages, pg)) {
> @@ -2070,8 +2081,11 @@ vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
>  		abort();
>  	}
>  
> -	for (pg = base; pg < base + num; ++pg)
> +	for (pg = base; pg < base + num; ++pg) {
>  		sparsebit_clear(region->unused_phy_pages, pg);
> +		if (protected)
> +			sparsebit_set(region->protected_phy_pages, pg);
> +	}
>  
>  	return base * vm->page_size;
>  }

Reviewed-by: Itaru Kitayama <itaru.kitayama at fujitsu.com>

> -- 
> 2.43.0.594.gd9cf4e227d-goog
> 


From itaru.kitayama at linux.dev  Wed Feb 14 21:29:28 2024
From: itaru.kitayama at linux.dev (Itaru Kitayama)
Date: Thu, 15 Feb 2024 14:29:28 +0900
Subject: [PATCH v8 05/10] KVM: selftests: Add support for protected
 vm_vaddr_* allocations
In-Reply-To: <20240203000917.376631-6-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
 <20240203000917.376631-6-seanjc@google.com>
Message-ID: <Zc2hOL1y+GIMaMux@vm3>

On Fri, Feb 02, 2024 at 04:09:11PM -0800, Sean Christopherson wrote:
> From: Michael Roth <michael.roth at amd.com>
> 
> Test programs may wish to allocate shared vaddrs for things like
> sharing memory with the guest. Since protected vms will have their
> memory encrypted by default an interface is needed to explicitly
> request shared pages.
> 
> Implement this by splitting the common code out from vm_vaddr_alloc()
> and introducing a new vm_vaddr_alloc_shared().
> 
> Cc: Paolo Bonzini <pbonzini at redhat.com>
> Cc: Sean Christopherson <seanjc at google.com>
> Cc: Vishal Annapurve <vannapurve at google.com>
> Cc: Ackerly Tng <ackerleytng at google.com>
> cc: Andrew Jones <andrew.jones at linux.dev>
> Cc: Tom Lendacky <thomas.lendacky at amd.com>
> Cc: Michael Roth <michael.roth at amd.com>
> Signed-off-by: Michael Roth <michael.roth at amd.com>
> Signed-off-by: Peter Gonda <pgonda at google.com>
> Signed-off-by: Sean Christopherson <seanjc at google.com>
> ---
>  .../selftests/kvm/include/kvm_util_base.h     |  3 +++
>  tools/testing/selftests/kvm/lib/kvm_util.c    | 26 +++++++++++++++----
>  2 files changed, 24 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
> index a82149305349..cb3159af6db3 100644
> --- a/tools/testing/selftests/kvm/include/kvm_util_base.h
> +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
> @@ -590,6 +590,9 @@ vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_mi
>  vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min);
>  vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
>  			    enum kvm_mem_region_type type);
> +vm_vaddr_t vm_vaddr_alloc_shared(struct kvm_vm *vm, size_t sz,
> +				 vm_vaddr_t vaddr_min,
> +				 enum kvm_mem_region_type type);
>  vm_vaddr_t vm_vaddr_alloc_pages(struct kvm_vm *vm, int nr_pages);
>  vm_vaddr_t __vm_vaddr_alloc_page(struct kvm_vm *vm,
>  				 enum kvm_mem_region_type type);
> diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
> index ea677aa019ef..e7f4f84f2e68 100644
> --- a/tools/testing/selftests/kvm/lib/kvm_util.c
> +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
> @@ -1431,15 +1431,17 @@ vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz,
>  	return pgidx_start * vm->page_size;
>  }
>  
> -vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
> -			    enum kvm_mem_region_type type)
> +static vm_vaddr_t ____vm_vaddr_alloc(struct kvm_vm *vm, size_t sz,
> +				     vm_vaddr_t vaddr_min,
> +				     enum kvm_mem_region_type type,
> +				     bool protected)
>  {
>  	uint64_t pages = (sz >> vm->page_shift) + ((sz % vm->page_size) != 0);
>  
>  	virt_pgd_alloc(vm);
> -	vm_paddr_t paddr = vm_phy_pages_alloc(vm, pages,
> -					      KVM_UTIL_MIN_PFN * vm->page_size,
> -					      vm->memslots[type]);
> +	vm_paddr_t paddr = __vm_phy_pages_alloc(vm, pages,
> +						KVM_UTIL_MIN_PFN * vm->page_size,
> +						vm->memslots[type], protected);
>  
>  	/*
>  	 * Find an unused range of virtual page addresses of at least
> @@ -1459,6 +1461,20 @@ vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
>  	return vaddr_start;
>  }
>  
> +vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
> +			    enum kvm_mem_region_type type)
> +{
> +	return ____vm_vaddr_alloc(vm, sz, vaddr_min, type,
> +				  vm_arch_has_protected_memory(vm));
> +}
> +
> +vm_vaddr_t vm_vaddr_alloc_shared(struct kvm_vm *vm, size_t sz,
> +				 vm_vaddr_t vaddr_min,
> +				 enum kvm_mem_region_type type)
> +{
> +	return ____vm_vaddr_alloc(vm, sz, vaddr_min, type, false);
> +}
> +
>  /*
>   * VM Virtual Address Allocate
>   *
Reviewied-by: Itaru Kitayama <itaru.kitayama at fujitsu.com>

> -- 
> 2.43.0.594.gd9cf4e227d-goog
> 


From apatel at ventanamicro.com  Wed Feb 14 21:48:15 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 15 Feb 2024 11:18:15 +0530
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <87bk8ig6t2.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <CAK9=C2Vwtj2gZg-P73yLMxu0rPXQ3YrRRuxq6HcpHMXgs-jHaw@mail.gmail.com> <87bk8ig6t2.ffs@tglx>
Message-ID: <CAK9=C2WsSSHgDF+7ruxx_QF0Lk+Dsx2F2Y-_NabnxrJ_qWhgGQ@mail.gmail.com>

On Thu, Feb 15, 2024 at 1:24?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> Anup!
>
> On Sat, Jan 27 2024 at 21:50, Anup Patel wrote:
> >> Changes since v11:
> >>  - Rebased on Linux-6.8-rc1
> >>  - Included kernel/irq related patches from "genirq, irqchip: Convert ARM
> >>    MSI handling to per device MSI domains" series by Thomas.
> >>    (PATCH7, PATCH8, PATCH9, PATCH14, PATCH16, PATCH17, PATCH18, PATCH19,
> >>     PATCH20, PATCH21, PATCH22, PATCH23, and PATCH32 of
> >>     https://lore.kernel.org/linux-arm-kernel/20221121135653.208611233 at linutronix.de/)
> >>  - Updated APLIC MSI-mode driver to use the new WIRED_TO_MSI mechanism.
> >>  - Updated IMSIC driver to support per-device MSI domains for PCI and
> >>    platform devices.
> >
> > I have rebased and included 13 patches (which add per-device MSI domain
> > infrastructure) from your series [1]. In this series, the IMSIC driver
> > implements the msi_parent_ops and APLIC driver implements wired-to-msi
> > bridge using your new infrastructure.
> >
> > The remaining 27 patches of your series [1] requires testing on ARM
> > platforms which I don't have. I suggest these remaining patches to
> > go as separate series.
>
> Of course. Darwi (in Cc) is going to work on the ARM parts when he
> returns from vacation. I'm going to apply the infrastructure patches
> (1-13) in the next days so they are out of the way for you and Darwi,
> unless someone has any objections.
>
> Thanks for picking this up and driving it forward!

Thanks Thomas, I will be sending v13 of this series next week.

For the time being, I will carry the 13 infrastructure patches in
this series until they land in upstream Linux so that it is easier
for people to try this series.

Regards,
Anup


From masahiroy at kernel.org  Wed Feb 14 21:50:47 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Thu, 15 Feb 2024 14:50:47 +0900
Subject: [PATCH v4 2/4] firmware: coreboot: Generate aliases for coreboot modules
In-Reply-To: <20240212-coreboot-mod-defconfig-v4-2-d14172676f6d@collabora.com>
References: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com> <20240212-coreboot-mod-defconfig-v4-2-d14172676f6d@collabora.com>
Message-ID: <CAK7LNASTG=xzodA6sAKTBaq09aDPZ9oqxcX2Q4iCuPrL+foQ8g@mail.gmail.com>

On Mon, Feb 12, 2024 at 11:51?PM N?colas F. R. A. Prado
<nfraprado at collabora.com> wrote:
>
> Generate aliases for coreboot modules to allow automatic module probing.
>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Reviewed-by: Brian Norris <briannorris at chromium.org>
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>


Acked-by: Masahiro Yamada <masahiroy at kernel.org>



-- 
Best Regards
Masahiro Yamada


From anshuman.khandual at arm.com  Wed Feb 14 21:51:59 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 15 Feb 2024 11:21:59 +0530
Subject: [PATCH] arm64/sysreg: Update ID_AA64DFR0_EL1 and ID_DFR0_EL1
Message-ID: <20240215055159.2440898-1-anshuman.khandual@arm.com>

This just updates ID_DFR0_EL1.CopDbg and ID_AA64DFR0_EL1.DebugVer register
fields as per the definitions based on DDI0601 2023-12.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Brown <broonie 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/tools/sysreg | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 4c9b67934367..94692abfeeb9 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -231,6 +231,7 @@ Enum	3:0	CopDbg
 	0b1000	Debugv8p2
 	0b1001	Debugv8p4
 	0b1010	Debugv8p8
+	0b1011	Debugv8p9
 EndEnum
 EndSysreg
 
@@ -1247,6 +1248,7 @@ UnsignedEnum	3:0	DebugVer
 	0b1000	V8P2
 	0b1001	V8P4
 	0b1010	V8P8
+	0b1011	V8P9
 EndEnum
 EndSysreg
 
-- 
2.25.1



From masahiroy at kernel.org  Wed Feb 14 21:52:00 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Thu, 15 Feb 2024 14:52:00 +0900
Subject: [PATCH v4 0/4] Allow coreboot modules to autoload and enable
 cbmem in the arm64 defconfig
In-Reply-To: <Zc2HBmDPJnHt0WJC@google.com>
References: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com> <Zc2HBmDPJnHt0WJC@google.com>
Message-ID: <CAK7LNATc0KkstjU8ErryV-GckvUKTsjR8naTRSifjw_TZYdSig@mail.gmail.com>

On Thu, Feb 15, 2024 at 12:37?PM Tzung-Bi Shih <tzungbi at kernel.org> wrote:
>
> On Mon, Feb 12, 2024 at 09:50:04AM -0500, N?colas F. R. A. Prado wrote:
> > This series adds the missing pieces to the coreboot bus and the module
> > alias generation to allow coreboot modules to be automatically loaded
> > when matching devices are detected.
> >
> > The configs for cbmem coreboot entries are then enabled in the arm64
> > defconfig, as modules, to allow reading logs from coreboot on arm64
> > Chromebooks, which is useful for debugging the boot process.
> >
> > [...]
> >
> > ---
> > N?colas F. R. A. Prado (4):
> >       firmware: coreboot: Generate modalias uevent for devices
> >       firmware: coreboot: Generate aliases for coreboot modules
> >       firmware: coreboot: Replace tag with id table in driver struct
> >       arm64: defconfig: Enable support for cbmem entries in the coreboot table
> >
> >  arch/arm64/configs/defconfig                   |  3 +++
>
> Hi Catalin and Will,
>
> Is it OK to you if I pick the 4th patch (which touches the above files) to
> chrome-platform-firmware tree for the next merge window?
>
> >  include/linux/mod_devicetable.h                | 10 ++++++++++
> >  scripts/mod/devicetable-offsets.c              |  3 +++
> >  scripts/mod/file2alias.c                       | 10 ++++++++++
>
> Hi Masahiro,
>
> Is it OK to you if I pick the 2nd patch (which touches the above files) to
> chrome-platform-firmware tree for the next merge window?


Yes.


I gave Acked-by to 2/4 so it makes your life easier.




-- 
Best Regards
Masahiro Yamada


From vigneshr at ti.com  Wed Feb 14 21:52:14 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 15 Feb 2024 11:22:14 +0530
Subject: [PATCH v2 1/2] dt-bindings: display: ti,am65x-dss: Add support
 for common1 region
In-Reply-To: <20240214125151.1965137-2-devarsht@ti.com>
References: <20240214125151.1965137-1-devarsht@ti.com>
 <20240214125151.1965137-2-devarsht@ti.com>
Message-ID: <395e55f2-00d7-475c-9d71-0d51831bfe1c@ti.com>



On 14/02/24 18:21, Devarsh Thakkar wrote:
> TI keystone display subsystem present in AM65 and other SoCs such as AM62
> support two separate register spaces namely "common" and "common1" which
> can be used by two separate hosts to program the display controller as
> described in respective Technical Reference Manuals [1].
> 
> The common1 register space has similar set of configuration registers as
> supported in common register space except the global configuration
> registers which are exclusive to common region.
> 
> This adds binding for "common1" register region too as supported by the
> hardware.
> 
> [1]:
> AM62x TRM:
> https://www.ti.com/lit/pdf/spruiv7 (Section 14.8.9.1 DSS Registers)
> 
> AM65x TRM:
> https://www.ti.com/lit/pdf/spruid7 (Section 12.6.5 DSS Registers)
> 
> AM62A TRM:
> https://www.ti.com/lit/pdf/spruj16 (Section 14.9.9.1 DSS Registers)
> 
> Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> ---


I guess all AM65/62/62a DSS variants always had this common1 reg region
but wasn't captured in the binding? If so, then this looks like a bug in
the original adding this yaml and as such should have Fixes: tag and so
should DT patch (patch 2/2)

> V2: Add Acked-by tag
> ---
>  .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> index b6767ef0d24d..55e3e490d0e6 100644
> --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> @@ -37,6 +37,7 @@ properties:
>        - description: OVR2 overlay manager for vp2
>        - description: VP1 video port 1
>        - description: VP2 video port 2
> +      - description: common1 DSS register area
>  
>    reg-names:
>      items:
> @@ -47,6 +48,7 @@ properties:
>        - const: ovr2
>        - const: vp1
>        - const: vp2
> +      - const: common1
>  
>    clocks:
>      items:
> @@ -147,9 +149,10 @@ examples:
>                      <0x04a07000 0x1000>, /* ovr1 */
>                      <0x04a08000 0x1000>, /* ovr2 */
>                      <0x04a0a000 0x1000>, /* vp1 */
> -                    <0x04a0b000 0x1000>; /* vp2 */
> +                    <0x04a0b000 0x1000>, /* vp2 */
> +                    <0x04a01000 0x1000>; /* common1 */
>              reg-names = "common", "vidl1", "vid",
> -                    "ovr1", "ovr2", "vp1", "vp2";
> +                    "ovr1", "ovr2", "vp1", "vp2", "common1";
>              ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
>              power-domains = <&k3_pds 67 TI_SCI_PD_EXCLUSIVE>;
>              clocks =        <&k3_clks 67 1>,

-- 
Regards
Vignesh


From ck.hu at mediatek.com  Wed Feb 14 22:02:20 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 15 Feb 2024 06:02:20 +0000
Subject: [PATCH v5 1/9] drm/mediatek: dsi: Use GENMASK() for register mask
 definitions
In-Reply-To: <20240207145307.1626009-2-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
	 <20240207145307.1626009-2-angelogioacchino.delregno@collabora.com>
Message-ID: <ed036e1dcaec3c050da07e42483e3747b06c6cda.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-02-07 at 15:52 +0100, AngeloGioacchino Del Regno wrote:
> Change magic numerical masks with usage of the GENMASK() macro
> to improve readability.
> 
> This commit brings no functional changes.

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

> 
> Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 45 +++++++++++++++-------------
> --
>  1 file changed, 23 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index a2fdfc8ddb15..c66e18006070 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -58,18 +58,18 @@
>  
>  #define DSI_TXRX_CTRL		0x18
>  #define VC_NUM				BIT(1)
> -#define LANE_NUM			(0xf << 2)
> +#define LANE_NUM			GENMASK(5, 2)
>  #define DIS_EOT				BIT(6)
>  #define NULL_EN				BIT(7)
>  #define TE_FREERUN			BIT(8)
>  #define EXT_TE_EN			BIT(9)
>  #define EXT_TE_EDGE			BIT(10)
> -#define MAX_RTN_SIZE			(0xf << 12)
> +#define MAX_RTN_SIZE			GENMASK(15, 12)
>  #define HSTX_CKLP_EN			BIT(16)
>  
>  #define DSI_PSCTRL		0x1c
> -#define DSI_PS_WC			0x3fff
> -#define DSI_PS_SEL			(3 << 16)
> +#define DSI_PS_WC			GENMASK(13, 0)
> +#define DSI_PS_SEL			GENMASK(17, 16)
>  #define PACKED_PS_16BIT_RGB565		(0 << 16)
>  #define LOOSELY_PS_18BIT_RGB666		(1 << 16)
>  #define PACKED_PS_18BIT_RGB666		(2 << 16)
> @@ -109,26 +109,26 @@
>  #define LD0_WAKEUP_EN			BIT(2)
>  
>  #define DSI_PHY_TIMECON0	0x110
> -#define LPX				(0xff << 0)
> -#define HS_PREP				(0xff << 8)
> -#define HS_ZERO				(0xff << 16)
> -#define HS_TRAIL			(0xff << 24)
> +#define LPX				GENMASK(7, 0)
> +#define HS_PREP				GENMASK(15, 8)
> +#define HS_ZERO				GENMASK(23, 16)
> +#define HS_TRAIL			GENMASK(31, 24)
>  
>  #define DSI_PHY_TIMECON1	0x114
> -#define TA_GO				(0xff << 0)
> -#define TA_SURE				(0xff << 8)
> -#define TA_GET				(0xff << 16)
> -#define DA_HS_EXIT			(0xff << 24)
> +#define TA_GO				GENMASK(7, 0)
> +#define TA_SURE				GENMASK(15, 8)
> +#define TA_GET				GENMASK(23, 16)
> +#define DA_HS_EXIT			GENMASK(31, 24)
>  
>  #define DSI_PHY_TIMECON2	0x118
> -#define CONT_DET			(0xff << 0)
> -#define CLK_ZERO			(0xff << 16)
> -#define CLK_TRAIL			(0xff << 24)
> +#define CONT_DET			GENMASK(7, 0)
> +#define CLK_ZERO			GENMASK(23, 16)
> +#define CLK_TRAIL			GENMASK(31, 24)
>  
>  #define DSI_PHY_TIMECON3	0x11c
> -#define CLK_HS_PREP			(0xff << 0)
> -#define CLK_HS_POST			(0xff << 8)
> -#define CLK_HS_EXIT			(0xff << 16)
> +#define CLK_HS_PREP			GENMASK(7, 0)
> +#define CLK_HS_POST			GENMASK(15, 8)
> +#define CLK_HS_EXIT			GENMASK(23, 16)
>  
>  #define DSI_VM_CMD_CON		0x130
>  #define VM_CMD_EN			BIT(0)
> @@ -138,13 +138,14 @@
>  #define FORCE_COMMIT			BIT(0)
>  #define BYPASS_SHADOW			BIT(1)
>  
> -#define CONFIG				(0xff << 0)
> +/* CMDQ related bits */
> +#define CONFIG				GENMASK(7, 0)
>  #define SHORT_PACKET			0
>  #define LONG_PACKET			2
>  #define BTA				BIT(2)
> -#define DATA_ID				(0xff << 8)
> -#define DATA_0				(0xff << 16)
> -#define DATA_1				(0xff << 24)
> +#define DATA_ID				GENMASK(15, 8)
> +#define DATA_0				GENMASK(23, 16)
> +#define DATA_1				GENMASK(31, 24)
>  
>  #define NS_TO_CYCLE(n, c)    ((n) / (c) + (((n) % (c)) ? 1 : 0))
>  

From ck.hu at mediatek.com  Wed Feb 14 22:12:18 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 15 Feb 2024 06:12:18 +0000
Subject: [PATCH v5 2/9] drm/mediatek: dsi: Fix DSI RGB666 formats and
 definitions
In-Reply-To: <20240207145307.1626009-3-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
	 <20240207145307.1626009-3-angelogioacchino.delregno@collabora.com>
Message-ID: <23017aad8135b41bffede3b55c0ac273daef0b82.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-02-07 at 15:53 +0100, AngeloGioacchino Del Regno wrote:
> The register bits definitions for RGB666 formats are wrong in
> multiple
> ways: first, in the DSI_PS_SEL bits region, the Packed 18-bits RGB666
> format is selected with bit 1, while the Loosely Packed one is bit 2,
> and second - the definition name "LOOSELY_PS_18BIT_RGB666" is wrong
> because the loosely packed format is 24 bits instead!
> 
> Either way, functions mtk_dsi_ps_control_vact() and
> mtk_dsi_ps_control()
> do not even agree on the DSI_PS_SEL bit to set in DSI_PSCTRL: one
> sets
> loosely packed (24) on RGB666, the other sets packed (18), and the
> other
> way around for RGB666_PACKED.
> 
> Fixing this entire stack of issues is done in one go:
>  - Use the correct bit for the Loosely Packed RGB666 definition
>  - Rename LOOSELY_PS_18BIT_RGB666 to LOOSELY_PS_24BIT_RGB666
>  - Change ps_bpp_mode in mtk_dsi_ps_control_vact() to set:
>     - Loosely Packed, 24-bits for MIPI_DSI_FMT_RGB666
>     - Packed, 18-bits for MIPI_DSI_FMT_RGB666_PACKED

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

> 
> Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
> Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index c66e18006070..8af0afbe9e3d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -71,8 +71,8 @@
>  #define DSI_PS_WC			GENMASK(13, 0)
>  #define DSI_PS_SEL			GENMASK(17, 16)
>  #define PACKED_PS_16BIT_RGB565		(0 << 16)
> -#define LOOSELY_PS_18BIT_RGB666		(1 << 16)
> -#define PACKED_PS_18BIT_RGB666		(2 << 16)
> +#define PACKED_PS_18BIT_RGB666		(1 << 16)
> +#define LOOSELY_PS_24BIT_RGB666		(2 << 16)
>  #define PACKED_PS_24BIT_RGB888		(3 << 16)
>  
>  #define DSI_VSA_NL		0x20
> @@ -370,10 +370,10 @@ static void mtk_dsi_ps_control_vact(struct
> mtk_dsi *dsi)
>  		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
>  		break;
>  	case MIPI_DSI_FMT_RGB666:
> -		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
> +		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
>  		break;
>  	case MIPI_DSI_FMT_RGB666_PACKED:
> -		ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;
> +		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
>  		break;
>  	case MIPI_DSI_FMT_RGB565:
>  		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
> @@ -427,7 +427,7 @@ static void mtk_dsi_ps_control(struct mtk_dsi
> *dsi)
>  		dsi_tmp_buf_bpp = 3;
>  		break;
>  	case MIPI_DSI_FMT_RGB666:
> -		tmp_reg = LOOSELY_PS_18BIT_RGB666;
> +		tmp_reg = LOOSELY_PS_24BIT_RGB666;
>  		dsi_tmp_buf_bpp = 3;
>  		break;
>  	case MIPI_DSI_FMT_RGB666_PACKED:

From anshuman.khandual at arm.com  Wed Feb 14 22:52:36 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 15 Feb 2024 12:22:36 +0530
Subject: [PATCH v2] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM
 Neoverse N2 errata
In-Reply-To: <20240214175522.2457857-1-eahariha@linux.microsoft.com>
References: <20240214175522.2457857-1-eahariha@linux.microsoft.com>
Message-ID: <32e59978-fbf3-4612-bfd0-03807ef2abb0@arm.com>



On 2/14/24 23:25, Easwar Hariharan wrote:
> Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft
> implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore
> suffers from all the same errata.
> 
> CC: stable at vger.kernel.org # 5.15+
> Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>

Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>

> ---
> changelog:
> v1->v2:
> * v1: https://lore.kernel.org/linux-arm-kernel/20240212232909.2276378-1-eahariha at linux.microsoft.com/T/#u
> * Consistently use MICROSOFT throughout
> ---
>  Documentation/arch/arm64/silicon-errata.rst | 7 +++++++
>  arch/arm64/include/asm/cputype.h            | 4 ++++
>  arch/arm64/kernel/cpu_errata.c              | 3 +++
>  3 files changed, 14 insertions(+)
> 
> diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
> index e8c2ce1f9df6..45a7f4932fe0 100644
> --- a/Documentation/arch/arm64/silicon-errata.rst
> +++ b/Documentation/arch/arm64/silicon-errata.rst
> @@ -243,3 +243,10 @@ stable kernels.
>  +----------------+-----------------+-----------------+-----------------------------+
>  | ASR            | ASR8601         | #8601001        | N/A                         |
>  +----------------+-----------------+-----------------+-----------------------------+
> ++----------------+-----------------+-----------------+-----------------------------+
> +| Microsoft      | Azure Cobalt 100| #2139208        | ARM64_ERRATUM_2139208       |
> ++----------------+-----------------+-----------------+-----------------------------+
> +| Microsoft      | Azure Cobalt 100| #2067961        | ARM64_ERRATUM_2067961       |
> ++----------------+-----------------+-----------------+-----------------------------+
> +| Microsoft      | Azure Cobalt 100| #2253138        | ARM64_ERRATUM_2253138       |
> ++----------------+-----------------+-----------------+-----------------------------+
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 7c7493cb571f..52f076afeb96 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -61,6 +61,7 @@
>  #define ARM_CPU_IMP_HISI		0x48
>  #define ARM_CPU_IMP_APPLE		0x61
>  #define ARM_CPU_IMP_AMPERE		0xC0
> +#define ARM_CPU_IMP_MICROSOFT		0x6D
>  
>  #define ARM_CPU_PART_AEM_V8		0xD0F
>  #define ARM_CPU_PART_FOUNDATION		0xD00
> @@ -135,6 +136,8 @@
>  
>  #define AMPERE_CPU_PART_AMPERE1		0xAC3
>  
> +#define MICROSOFT_CPU_PART_AZURE_COBALT_100	0xD49 /* Based on r0p0 of ARM Neoverse N2 */
> +
>  #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
>  #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
>  #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
> @@ -193,6 +196,7 @@
>  #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)
>  #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
>  #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
> +#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100)
>  
>  /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
>  #define MIDR_FUJITSU_ERRATUM_010001		MIDR_FUJITSU_A64FX
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 967c7c7a4e7d..76b8dd37092a 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -374,6 +374,7 @@ static const struct midr_range erratum_1463225[] = {
>  static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
>  #ifdef CONFIG_ARM64_ERRATUM_2139208
>  	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> +	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_2119858
>  	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> @@ -387,6 +388,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
>  static const struct midr_range tsb_flush_fail_cpus[] = {
>  #ifdef CONFIG_ARM64_ERRATUM_2067961
>  	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> +	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_2054223
>  	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> @@ -399,6 +401,7 @@ static const struct midr_range tsb_flush_fail_cpus[] = {
>  static struct midr_range trbe_write_out_of_range_cpus[] = {
>  #ifdef CONFIG_ARM64_ERRATUM_2253138
>  	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> +	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_2224489
>  	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),


From anshuman.khandual at arm.com  Wed Feb 14 22:54:54 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 15 Feb 2024 12:24:54 +0530
Subject: [PATCH] arm64/sysreg: Add register fields for ID_AA64DFR1_EL1
Message-ID: <20240215065454.2489075-1-anshuman.khandual@arm.com>

This adds register fields for ID_AA64DFR1_EL1 as per the definitions based
on DDI0601 2023-12.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Brown <broonie 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/tools/sysreg | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 94692abfeeb9..1cd06edfad3b 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1253,7 +1253,33 @@ EndEnum
 EndSysreg
 
 Sysreg	ID_AA64DFR1_EL1	3	0	0	5	1
-Res0	63:0
+Field	63:56	ABL_CMPs
+Field	55:52	DPFZS
+UnsignedEnum	51:48	EBEP
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	47:44	ITE
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	43:40	ABLE
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	39:36	PMICNTR
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	35:32	SPMU
+	0b0000	NI
+	0b0001	IMP
+	0b0010	IMP_SPMZR
+EndEnum
+Field	31:24	CTX_CMPs
+Field	23:16	WRPs
+Field	15:8	BRPs
+Field	7:0	SYSPMUID
 EndSysreg
 
 Sysreg	ID_AA64AFR0_EL1	3	0	0	5	4
-- 
2.25.1



From jirislaby at kernel.org  Wed Feb 14 23:01:33 2024
From: jirislaby at kernel.org (Jiri Slaby)
Date: Thu, 15 Feb 2024 08:01:33 +0100
Subject: [PATCH net] net: stmmac: xgmac: use #define for string constants
In-Reply-To: <20240208-xgmac-const-v1-1-e69a1eeabfc8@kernel.org>
References: <20240208-xgmac-const-v1-1-e69a1eeabfc8@kernel.org>
Message-ID: <485dbc5a-a04b-40c2-9481-955eaa5ce2e2@kernel.org>

On 08. 02. 24, 10:48, Simon Horman wrote:
> The cited commit introduces and uses the string constants dpp_tx_err and
> dpp_rx_err. These are assigned to constant fields of the array
> dwxgmac3_error_desc.
> 
> It has been reported that on GCC 6 and 7.5.0 this results in warnings
> such as:
> 
>    .../dwxgmac2_core.c:836:20: error: initialiser element is not constant
>     { true, "TDPES0", dpp_tx_err },
> 
> I have been able to reproduce this using: GCC 7.5.0, 8.4.0, 9.4.0 and 10.5.0.
> But not GCC 13.2.0.
> 
> So it seems this effects older compilers but not newer ones.
> As Jon points out in his report, the minimum compiler supported by
> the kernel is GCC 5.1, so it does seem that this ought to be fixed.
> 
> It is not clear to me what combination of 'const', if any, would address
> this problem.

You cannot make it more const than it is now ;). (You have a const 
pointer to const data already.)

> So this patch takes of using #defines for the string
> constants

That's indeed ugly. What about NOT creating a pointer to an array at 
all? See below.

> Compile tested only.
> 
> Fixes: 46eba193d04f ("net: stmmac: xgmac: fix handling of DPP safety error for DMA channels")
> Reported-by: Jon Hunter <jonathanh at nvidia.com>
> Closes: https://lore.kernel.org/netdev/c25eb595-8d91-40ea-9f52-efa15ebafdbc at nvidia.com/
> Reported-by: kernel test robot <lkp at intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202402081135.lAxxBXHk-lkp at intel.com/
> Signed-off-by: Simon Horman <horms at kernel.org>
> ---
>   .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c    | 69 +++++++++++-----------
>   1 file changed, 35 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> index 323c57f03c93..1af2f89a0504 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> @@ -830,41 +830,42 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
>   	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
>   };
>   
> -static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
> -static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";

The usual (even documented, I believe) way to do this is:

static const char dpp_tx_err[] = "Read Tx Descriptor Parity checker Error";

Then keep:
{ true, "TDPES0", dpp_tx_err },

Doesn't it do the right job?

> +#define DPP_RX_ERR "Read Rx Descriptor Parity checker Error"
> +#define DPP_TX_ERR "Read Tx Descriptor Parity checker Error"

thanks,
-- 
js
suse labs



From ak at linux.intel.com  Wed Feb 14 23:08:40 2024
From: ak at linux.intel.com (Andi Kleen)
Date: Wed, 14 Feb 2024 23:08:40 -0800
Subject: [RFC PATCH 0/2] A mechanism for efficient support for
 per-function metrics
In-Reply-To: <7de25cbdc9df21e1723d209ca8bd377a55bb54e4.camel@arm.com>
References: <20240123113420.1928154-1-ben.gainey@arm.com>
 <87r0hfwet0.fsf@linux.intel.com>
 <7de25cbdc9df21e1723d209ca8bd377a55bb54e4.camel@arm.com>
Message-ID: <Zc24eLqZycmIg3d2@tassilo>

On Wed, Feb 14, 2024 at 07:13:50PM +0000, Ben Gainey wrote:
> 
> Nice, I wasn't aware of this feature. I'll have a play...

You have to use an old perf version for now, still need to fix it.
> 
> 
> > 
> > Of course the feature is somewhat dubious in that it will have a very
> > strong systematic bias against short functions and even long
> > functions
> > in some alternating execution patterns. I assume you did some
> > experiments to characterize this. It would be important
> > to emphasize this in any documentation.
> 
> The way I have been thinking about this is that for each sample you
> always maintain a periodic sample count so that the relative ranking of
> functions is maintained, and that the "same as previous" check is a way
> to enhance the attributability of the PMU data for any given sample. 
> 
> But it absolutely correct to say that this will bias the availability
> of PMU data in the way you have describe. The bias depends on sample
> window size, workload characteristics and so on.

I would be more comfortable with it if you added some randomization
on the window sizes. That would limit bias and worst case sampling
error.

> It should be possible to provide a per metric "valid sample" count that
> can be used to judge the  "quality" of the metrics for each symbol,
> which may allow the user to make some adjustments to the recording
> paramters (modify sample period, or sample window size for example).

Even that would be misleading because it assumes that the IP stayed
in the same function between the two samples. But you could have
something like

F1  sample
F2
F1  sample

and if you're unlucky this could happen systematically. The
randomization would fight it somewhat, but even there you might
be very very unlucky.

The only sure way to judge it really is to run branch trace in parallel and see
if it is correct.

Also there is of course the problem that on a modern core the
reordering window might well be larger than your sample window, so any notion
of things happening inside a short window is quite fuzzy.

> > 
> > I don't see anything ARM specific with the technique, so if it's done
> > it should be done generically IMHO
> 
> 
> Great. When i was originally thinking about the implementation of the
> event strobing feature I was thinking:
> 
>  * Add `strobe_sample` flag bit to opt into the fature
>    - This will be mutually exclusive with `freq`.
>  * Add `strobe_period` field to hold the alternate sample period (for
> the sample window.
>  * Have all PMU drivers check and reject the `strobe_sample` flag by
> default; the swizzling of the period will be done in the PMU driver its
> self if it make sense to support this feature for a given PMU.
>    - Do you think this is sensible, or would be better handled in core?

I would have a common function in core that is called from the PMU
drivers, similar to how the adaptive period is done today.

> > > the patch) suggests this approach would work for some counters.
> > > Calculating branch miss rates for example appears to be correct,
> > > likewise UOPS_EXECUTED.THREAD seems to give something like a
> > > sensible
> > > cycles-per-uop value. On the other hand the fixed function
> > > instructions
> > > counter does not appear to sample correctly (it seems to report
> > > either
> > > very small or very large numbers). No idea whats going on there, so
> > > any
> > > insight welcome...
> > 
> > If you use precise samples with 3p there is a restriction on the
> > periods
> > that is enforced by the kernel. Non precise or single/double p should
> > support arbitrary, except that any p is always period + 1.
> 
> Is there some default value for precise? when testing I didn't set any
> specific value for p modifier.

In some cases the perf tool tries to use the highest, e.g. if you don't
specify anything.

If you used :p (and not :P) it should have taken the number you
specified. Single :p is normally not useful because it samples
the -1 IP, normal use is either two or three p. Three p is more
precise but also has some restrictions on the sampling period
and the counters that can be used.

-Andi


From ck.hu at mediatek.com  Wed Feb 14 23:07:52 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 15 Feb 2024 07:07:52 +0000
Subject: [PATCH v5 3/9] drm/mediatek: dsi: Cleanup functions
 mtk_dsi_ps_control{_vact}()
In-Reply-To: <20240207145307.1626009-4-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
	 <20240207145307.1626009-4-angelogioacchino.delregno@collabora.com>
Message-ID: <5ad39702eb09a122e4302529dd4d9f12c37f7706.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-02-07 at 15:53 +0100, AngeloGioacchino Del Regno wrote:
> Function mtk_dsi_ps_control() is a subset of
> mtk_dsi_ps_control_vact():
> merge the two in one mtk_dsi_ps_control() function by adding one
> function parameter `config_vact` which, when true, writes the VACT
> related registers.

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

> 
> Reviewed-by: Fei Shao <fshao at chromium.org>
> Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 76 +++++++++-------------------
> --
>  1 file changed, 23 insertions(+), 53 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 8af0afbe9e3d..7d38e9500700 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -351,40 +351,6 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi
> *dsi)
>  	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
>  }
>  
> -static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
> -{
> -	struct videomode *vm = &dsi->vm;
> -	u32 dsi_buf_bpp, ps_wc;
> -	u32 ps_bpp_mode;
> -
> -	if (dsi->format == MIPI_DSI_FMT_RGB565)
> -		dsi_buf_bpp = 2;
> -	else
> -		dsi_buf_bpp = 3;
> -
> -	ps_wc = vm->hactive * dsi_buf_bpp;
> -	ps_bpp_mode = ps_wc;
> -
> -	switch (dsi->format) {
> -	case MIPI_DSI_FMT_RGB888:
> -		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
> -		break;
> -	case MIPI_DSI_FMT_RGB666:
> -		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
> -		break;
> -	case MIPI_DSI_FMT_RGB666_PACKED:
> -		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
> -		break;
> -	case MIPI_DSI_FMT_RGB565:
> -		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
> -		break;
> -	}
> -
> -	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
> -	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
> -	writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
> -}
> -
>  static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
>  {
>  	u32 tmp_reg;
> @@ -416,36 +382,40 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi
> *dsi)
>  	writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
>  }
>  
> -static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
> +static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool
> config_vact)
>  {
> -	u32 dsi_tmp_buf_bpp;
> -	u32 tmp_reg;
> +	struct videomode *vm = &dsi->vm;
> +	u32 dsi_buf_bpp, ps_wc;
> +	u32 ps_bpp_mode;
> +
> +	if (dsi->format == MIPI_DSI_FMT_RGB565)
> +		dsi_buf_bpp = 2;
> +	else
> +		dsi_buf_bpp = 3;
> +
> +	ps_wc = vm->hactive * dsi_buf_bpp;
> +	ps_bpp_mode = ps_wc;
>  
>  	switch (dsi->format) {
>  	case MIPI_DSI_FMT_RGB888:
> -		tmp_reg = PACKED_PS_24BIT_RGB888;
> -		dsi_tmp_buf_bpp = 3;
> +		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
>  		break;
>  	case MIPI_DSI_FMT_RGB666:
> -		tmp_reg = LOOSELY_PS_24BIT_RGB666;
> -		dsi_tmp_buf_bpp = 3;
> +		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
>  		break;
>  	case MIPI_DSI_FMT_RGB666_PACKED:
> -		tmp_reg = PACKED_PS_18BIT_RGB666;
> -		dsi_tmp_buf_bpp = 3;
> +		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
>  		break;
>  	case MIPI_DSI_FMT_RGB565:
> -		tmp_reg = PACKED_PS_16BIT_RGB565;
> -		dsi_tmp_buf_bpp = 2;
> -		break;
> -	default:
> -		tmp_reg = PACKED_PS_24BIT_RGB888;
> -		dsi_tmp_buf_bpp = 3;
> +		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
>  		break;
>  	}
>  
> -	tmp_reg += dsi->vm.hactive * dsi_tmp_buf_bpp & DSI_PS_WC;
> -	writel(tmp_reg, dsi->regs + DSI_PSCTRL);
> +	if (config_vact) {
> +		writel(vm->vactive, dsi->regs + DSI_VACT_NL);
> +		writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
> +	}
> +	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
>  }
>  
>  static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
> @@ -521,7 +491,7 @@ static void mtk_dsi_config_vdo_timing(struct
> mtk_dsi *dsi)
>  	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
>  	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
>  
> -	mtk_dsi_ps_control(dsi);
> +	mtk_dsi_ps_control(dsi, false);
>  }
>  
>  static void mtk_dsi_start(struct mtk_dsi *dsi)
> @@ -666,7 +636,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>  	mtk_dsi_reset_engine(dsi);
>  	mtk_dsi_phy_timconfig(dsi);
>  
> -	mtk_dsi_ps_control_vact(dsi);
> +	mtk_dsi_ps_control(dsi, true);
>  	mtk_dsi_set_vm_cmd(dsi);
>  	mtk_dsi_config_vdo_timing(dsi);
>  	mtk_dsi_set_interrupt_enable(dsi);

From claudiu.beznea at tuxon.dev  Wed Feb 14 23:19:14 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Thu, 15 Feb 2024 09:19:14 +0200
Subject: [PATCH v2 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <20240214080348.7540-3-mihai.sain@microchip.com>
References: <20240214080348.7540-1-mihai.sain@microchip.com>
 <20240214080348.7540-3-mihai.sain@microchip.com>
Message-ID: <20a20d63-3968-45e7-a4aa-0197c55e6656@tuxon.dev>

Hi, Mihai,

On 14.02.2024 10:03, Mihai Sain wrote:
> Add flexcom 10 node for usage on the SAMA7G54 Curiosity board.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/sama7g5.dtsi | 26 ++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> index 269e0a3ca269..c90e404e8ed9 100644
> --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
> +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> @@ -958,6 +958,32 @@ i2c9: i2c at 600 {
>  			};
>  		};
>  
> +		flx10: flexcom at e2820000 {
> +			compatible = "atmel,sama5d2-flexcom";
> +			reg = <0xe2820000 0x200>;
> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0x0 0xe2820000 0x800>;
> +			status = "disabled";
> +
> +			i2c10: i2c at 600 {
> +				compatible = "microchip,sama7g5-i2c", "microchip,sam9x60-i2c";
> +				reg = <0x600 0x200>;
> +				interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +				clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
> +				atmel,fifo-size = <32>;
> +				dmas = <&dma0 AT91_XDMAC_DT_PERID(25)>,
> +					<&dma0 AT91_XDMAC_DT_PERID(26)>;
> +				dma-names = "rx", "tx";

Please use the same pattern used by the rest of the i2c flexcom nodes, meaning:
				dma-names = "tx", "rx";

and, with this, reverse the order of dmas, too.

> +				atmel,use-dma-rx;
> +				atmel,use-dma-tx;

These are uart properties.

> +				status = "disabled";
> +			};
> +		};
> +
>  		flx11: flexcom at e2824000 {
>  			compatible = "atmel,sama5d2-flexcom";
>  			reg = <0xe2824000 0x200>;


From maxime.chevallier at bootlin.com  Wed Feb 14 23:19:39 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Thu, 15 Feb 2024 08:19:39 +0100
Subject: [PATCH net-next v7 00/13] Introduce PHY listing and
 link_topology tracking
In-Reply-To: <20240214165902.55bf3a04@kernel.org>
References: <20240213150431.1796171-1-maxime.chevallier@bootlin.com>
	<20240214165902.55bf3a04@kernel.org>
Message-ID: <20240215081939.1df19818@device-28.home>

Hi Jakub,

On Wed, 14 Feb 2024 16:59:02 -0800
Jakub Kicinski <kuba at kernel.org> wrote:

> On Tue, 13 Feb 2024 16:04:17 +0100 Maxime Chevallier wrote:
> > This is V7 for the link topology addition, allowing to track all PHYs
> > that are linked to netdevices.
> > 
> > The main change in V7 is the protection of the main internal API
> > entrypoints (link_topo_init/cleanup, link_topo_add/del_phy) by
> > IS_REACHABLE(CONFIG_PHYLIB).
> > 
> > That's restrictive, but it looks difficult to do otherwise while still keep the
> > data structure opaque and not add dependency clutter with PHYLIB.
> > 
> > As you can tell, I'm unsure about this, so please don't hesitate to
> > comment on that part :)
> > 
> > The other changes are very minor, the only one is a call to netdev_put
> > in the .done() netlink callback.
> > 
> > As a remainder, here's what the PHY listings would look like :
> >  - eth0 has a 88x3310 acting as media converter, and an SFP module with
> >    an embedded 88e1111 PHY
> >  - eth2 has a 88e1510 PHY  
> 
> Needs a rebase, core has been busy lately:

Arg, I'll send a rebased version, sorry about that

Best regards,

Maxime


From claudiu.beznea at tuxon.dev  Wed Feb 14 23:23:26 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Thu, 15 Feb 2024 09:23:26 +0200
Subject: [PATCH v2 3/3] ARM: dts: microchip: sama7g54_curiosity: Add
 initial device tree of the board
In-Reply-To: <20240214080348.7540-4-mihai.sain@microchip.com>
References: <20240214080348.7540-1-mihai.sain@microchip.com>
 <20240214080348.7540-4-mihai.sain@microchip.com>
Message-ID: <e75c3dcd-ed8d-4026-8ac4-0eff209f3df5@tuxon.dev>



On 14.02.2024 10:03, Mihai Sain wrote:
> Add initial device tree of the SAMA7G54 Curiosity board.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/Makefile          |   4 +-
>  .../dts/microchip/at91-sama7g54_curiosity.dts | 487 ++++++++++++++++++
>  2 files changed, 490 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
> 
> diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
> index efde9546c8f4..29b2a788748f 100644
> --- a/arch/arm/boot/dts/microchip/Makefile
> +++ b/arch/arm/boot/dts/microchip/Makefile
> @@ -12,6 +12,7 @@ DTC_FLAGS_at91-sama5d3_eds := -@
>  DTC_FLAGS_at91-sama5d3_xplained := -@
>  DTC_FLAGS_at91-sama5d4_xplained := -@
>  DTC_FLAGS_at91-sama7g5ek := -@
> +DTC_FLAGS_at91-sama7g54_curiosity := -@

Alphanumerical sort, thus DTC_FLAGS_at91-sama7g54_curiosity comes before
DTC_FLAGS_at91-sama7g5ek

>  dtb-$(CONFIG_SOC_AT91RM9200) += \
>  	at91rm9200ek.dtb \
>  	mpa1600.dtb
> @@ -87,7 +88,8 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
>  	at91-sama5d4ek.dtb \
>  	at91-vinco.dtb
>  dtb-$(CONFIG_SOC_SAMA7G5) += \
> -	at91-sama7g5ek.dtb
> +	at91-sama7g5ek.dtb \
> +	at91-sama7g54_curiosity.dtb

Same here.

>  
>  dtb-$(CONFIG_SOC_LAN966) += \
>  	lan966x-kontron-kswitch-d10-mmt-6g-2gs.dtb \
> diff --git a/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
> new file mode 100644
> index 000000000000..a6504c3781f4
> --- /dev/null
> +++ b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
> @@ -0,0 +1,487 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * at91-sama7g54_curiosity.dts - Device Tree file for SAMA7G54 Curiosity Board
> + *
> + * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
> + *
> + * Author: Mihai Sain <mihai.sain at microchip.com>
> + *
> + */
> +/dts-v1/;
> +#include "sama7g5-pinfunc.h"
> +#include "sama7g5.dtsi"
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/leds/common.h>
> +#include <dt-bindings/mfd/atmel-flexcom.h>
> +#include <dt-bindings/pinctrl/at91.h>
> +
> +/ {
> +	model = "Microchip SAMA7G54 Curiosity";
> +	compatible = "microchip,sama7g54-curiosity", "microchip,sama7g5", "microchip,sama7";
> +
> +	aliases {
> +		serial0 = &uart3;
> +		i2c0 = &i2c10;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_key_gpio_default>;
> +
> +		button-user {
> +			label = "user-button";
> +			gpios = <&pioA PIN_PD19 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_PROG1>;
> +			wakeup-source;
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_led_gpio_default>;
> +
> +		led-red {
> +			color = <LED_COLOR_ID_RED>;
> +			function = LED_FUNCTION_POWER;
> +			gpios = <&pioA PIN_PD13 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +		};
> +
> +		led-green {
> +			color = <LED_COLOR_ID_GREEN>;
> +			function = LED_FUNCTION_BOOT;
> +			gpios = <&pioA PIN_PD14 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +		};
> +
> +		led-blue {
> +			color = <LED_COLOR_ID_BLUE>;
> +			function = LED_FUNCTION_CPU;
> +			gpios = <&pioA PIN_PB15 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "heartbeat";
> +		};
> +	};
> +
> +	memory at 60000000 {
> +		device_type = "memory";
> +		reg = <0x60000000 0x10000000>; // 256 MiB DDR3L-1066 16-bit
> +	};
> +};
> +
> +&adc {
> +	vddana-supply = <&vddout25>;
> +	vref-supply = <&vddout25>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_mikrobus1_an_default &pinctrl_mikrobus2_an_default>;
> +	status = "okay";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&vddcpu>;
> +};
> +
> +&dma0 {
> +	status = "okay";
> +};
> +
> +&dma1 {
> +	status = "okay";
> +};
> +
> +&dma2 {
> +	status = "okay";
> +};
> +
> +&ebi {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_nand_default>;
> +	status = "okay";
> +
> +	nand_controller: nand-controller {
> +		status = "okay";
> +
> +		nand at 3 {
> +			reg = <0x3 0x0 0x800000>;
> +			atmel,rb = <0>;
> +			nand-bus-width = <8>;
> +			nand-ecc-mode = "hw";
> +			nand-ecc-strength = <8>;
> +			nand-ecc-step-size = <512>;
> +			nand-on-flash-bbt;
> +			label = "nand";
> +
> +			partitions {
> +				compatible = "fixed-partitions";
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +
> +				at91bootstrap at 0 {
> +					label = "nand: at91bootstrap";
> +					reg = <0x0 0x40000>;
> +				};
> +
> +				bootloader at 40000 {
> +					label = "nand: u-boot";
> +					reg = <0x40000 0x100000>;
> +				};
> +
> +				bootloaderenv at 140000 {
> +					label = "nand: u-boot env";
> +					reg = <0x140000 0x40000>;
> +				};
> +
> +				dtb at 180000 {
> +					label = "nand: device tree";
> +					reg = <0x180000 0x80000>;
> +				};
> +
> +				kernel at 200000 {
> +					label = "nand: kernel";
> +					reg = <0x200000 0x600000>;
> +				};
> +
> +				rootfs at 800000 {
> +					label = "nand: rootfs";
> +					reg = <0x800000 0x1f800000>;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&flx3 {
> +	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
> +	status = "okay";
> +
> +	uart3: serial at 200 {
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_flx3_default>;
> +		status = "okay";
> +	};
> +};
> +
> +&flx10 {
> +	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
> +	status = "okay";
> +
> +	i2c10: i2c at 600 {
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_flx10_default>;
> +		i2c-analog-filter;
> +		i2c-digital-filter;
> +		i2c-digital-filter-width-ns = <35>;
> +		status = "okay";
> +
> +		adc at 1f {
> +			compatible = "microchip,pac1934";

There is no driver for this one in the upstream Linux and the compatible is
not documented. I would remove the node until the driver lands in mainline
Linux.

> +			reg = <0x1f>;
> +		};
> +
> +		eeprom at 51 {
> +			compatible = "atmel,24c02";
> +			reg = <0x51>;
> +			pagesize = <16>;
> +			size = <256>;
> +			vcc-supply = <&vdd_3v3>;
> +		};
> +
> +		pmic at 5b {
> +			compatible = "microchip,mcp16502";
> +			reg = <0x5b>;
> +
> +			regulators {
> +				vdd_3v3: VDD_IO {
> +					regulator-name = "VDD_IO";
> +					regulator-min-microvolt = <3300000>;
> +					regulator-max-microvolt = <3300000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-microvolt = <3300000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vddioddr: VDD_DDR {
> +					regulator-name = "VDD_DDR";
> +					regulator-min-microvolt = <1350000>;
> +					regulator-max-microvolt = <1350000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-microvolt = <1350000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-on-in-suspend;
> +						regulator-suspend-microvolt = <1350000>;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vddcore: VDD_CORE {
> +					regulator-name = "VDD_CORE";
> +					regulator-min-microvolt = <1150000>;
> +					regulator-max-microvolt = <1150000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-voltage = <1150000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vddcpu: VDD_OTHER {
> +					regulator-name = "VDD_OTHER";
> +					regulator-min-microvolt = <1050000>;
> +					regulator-max-microvolt = <1250000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-ramp-delay = <3125>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-voltage = <1050000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vldo1: LDO1 {
> +					regulator-name = "LDO1";
> +					regulator-min-microvolt = <1800000>;
> +					regulator-max-microvolt = <1800000>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-suspend-voltage = <1800000>;
> +						regulator-on-in-suspend;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +					};
> +				};
> +
> +				vldo2: LDO2 {
> +					regulator-name = "LDO2";
> +					regulator-min-microvolt = <3300000>;
> +					regulator-max-microvolt = <3300000>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-suspend-voltage = <3300000>;
> +						regulator-on-in-suspend;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +					};
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&main_xtal {
> +	clock-frequency = <24000000>;
> +};
> +
> +&qspi1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_qspi1_default>;
> +	status = "okay";
> +
> +	flash at 0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0x0>;
> +		spi-max-frequency = <100000000>;
> +		spi-tx-bus-width = <4>;
> +		spi-rx-bus-width = <4>;
> +		m25p,fast-read;
> +	};
> +};
> +
> +&pioA {
> +	pinctrl_flx3_default: flx3-default {
> +		pinmux = <PIN_PD16__FLEXCOM3_IO0>,
> +			 <PIN_PD17__FLEXCOM3_IO1>;
> +		bias-pull-up;
> +	};
> +
> +	pinctrl_flx10_default: flx10-default {
> +		pinmux = <PIN_PC30__FLEXCOM10_IO0>,
> +			 <PIN_PC31__FLEXCOM10_IO1>;
> +		bias-pull-up;
> +	};
> +
> +	pinctrl_key_gpio_default: key-gpio-default {
> +		pinmux = <PIN_PD19__GPIO>;
> +		bias-pull-up;
> +	};
> +
> +	pinctrl_led_gpio_default: led-gpio-default {
> +		pinmux = <PIN_PD13__GPIO>,
> +			 <PIN_PD14__GPIO>,
> +			 <PIN_PB15__GPIO>;
> +		bias-pull-up;
> +	};
> +
> +	pinctrl_mikrobus1_an_default: mikrobus1-an-default {
> +		pinmux = <PIN_PC15__GPIO>;
> +		bias-disable;
> +	};
> +
> +	pinctrl_mikrobus2_an_default: mikrobus2-an-default {
> +		pinmux = <PIN_PC13__GPIO>;
> +		bias-disable;
> +	};
> +
> +	pinctrl_nand_default: nand-default {
> +		pinmux = <PIN_PD9__D0>,
> +			 <PIN_PD10__D1>,
> +			 <PIN_PD11__D2>,
> +			 <PIN_PC21__D3>,
> +			 <PIN_PC22__D4>,
> +			 <PIN_PC23__D5>,
> +			 <PIN_PC24__D6>,
> +			 <PIN_PD2__D7>,
> +			 <PIN_PD3__NANDRDY>,
> +			 <PIN_PD4__NCS3_NANDCS>,
> +			 <PIN_PD5__NWE_NWR0_NANDWE>,
> +			 <PIN_PD6__NRD_NANDOE>,
> +			 <PIN_PD7__A21_NANDALE>,
> +			 <PIN_PD8__A22_NANDCLE>;
> +		bias-disable;
> +		slew-rate = <0>;
> +	};
> +
> +	pinctrl_qspi1_default: qspi1-default {
> +		pinmux = <PIN_PB22__QSPI1_IO3>,
> +			 <PIN_PB23__QSPI1_IO2>,
> +			 <PIN_PB24__QSPI1_IO1>,
> +			 <PIN_PB25__QSPI1_IO0>,
> +			 <PIN_PB26__QSPI1_CS>,
> +			 <PIN_PB27__QSPI1_SCK>;
> +		bias-pull-up;
> +		slew-rate = <0>;
> +	};
> +
> +	pinctrl_sdmmc0_default: sdmmc0-default {
> +		pinmux = <PIN_PA0__SDMMC0_CK>,
> +			 <PIN_PA1__SDMMC0_CMD>,
> +			 <PIN_PA2__SDMMC0_RSTN>,
> +			 <PIN_PA3__SDMMC0_DAT0>,
> +			 <PIN_PA4__SDMMC0_DAT1>,
> +			 <PIN_PA5__SDMMC0_DAT2>,
> +			 <PIN_PA6__SDMMC0_DAT3>;
> +		bias-pull-up;
> +		slew-rate = <0>;
> +	};
> +
> +	pinctrl_sdmmc1_default: sdmmc1-default {
> +		pinmux = <PIN_PB29__SDMMC1_CMD>,
> +			 <PIN_PB30__SDMMC1_CK>,
> +			 <PIN_PB31__SDMMC1_DAT0>,
> +			 <PIN_PC0__SDMMC1_DAT1>,
> +			 <PIN_PC1__SDMMC1_DAT2>,
> +			 <PIN_PC2__SDMMC1_DAT3>,
> +			 <PIN_PC4__SDMMC1_CD>;
> +		bias-pull-up;
> +		slew-rate = <0>;
> +	};
> +};
> +
> +&rtt {
> +	atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
> +};
> +
> +// M.2 slot for wireless card

Use C style comment instead /* */

> +&sdmmc0 {
> +	bus-width = <4>;
> +	cd-gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
> +	disable-wp;
> +	sdhci-caps-mask = <0x0 0x00200000>;
> +	vmmc-supply = <&vdd_3v3>;
> +	vqmmc-supply = <&vdd_3v3>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sdmmc0_default>;
> +	status = "okay";
> +};
> +
> +// micro SD socket
> +&sdmmc1 {
> +	bus-width = <4>;
> +	disable-wp;
> +	sdhci-caps-mask = <0x0 0x00200000>;
> +	vmmc-supply = <&vdd_3v3>;
> +	vqmmc-supply = <&vdd_3v3>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sdmmc1_default>;
> +	status = "okay";
> +};
> +
> +&slow_xtal {
> +	clock-frequency = <32768>;
> +};
> +
> +&shdwc {
> +	debounce-delay-us = <976>;
> +	status = "okay";
> +
> +	input at 0 {
> +		reg = <0>;
> +	};
> +};
> +
> +&tcb0 {
> +	timer0: timer at 0 {
> +		compatible = "atmel,tcb-timer";
> +		reg = <0>;
> +	};
> +
> +	timer1: timer at 1 {
> +		compatible = "atmel,tcb-timer";
> +		reg = <1>;
> +	};
> +};
> +
> +&trng {
> +	status = "okay";
> +};
> +
> +&vddout25 {
> +	vin-supply = <&vdd_3v3>;
> +	status = "okay";
> +};


From claudiu.beznea at tuxon.dev  Wed Feb 14 23:25:38 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Thu, 15 Feb 2024 09:25:38 +0200
Subject: [PATCH v2 3/3] ARM: dts: microchip: sama7g54_curiosity: Add
 initial device tree of the board
In-Reply-To: <20240214080348.7540-4-mihai.sain@microchip.com>
References: <20240214080348.7540-1-mihai.sain@microchip.com>
 <20240214080348.7540-4-mihai.sain@microchip.com>
Message-ID: <58fe3ecd-5aa4-4164-abc3-206e0d6ccb26@tuxon.dev>



On 14.02.2024 10:03, Mihai Sain wrote:
> Add initial device tree of the SAMA7G54 Curiosity board.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/Makefile          |   4 +-
>  .../dts/microchip/at91-sama7g54_curiosity.dts | 487 ++++++++++++++++++
>  2 files changed, 490 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
> 
> diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
> index efde9546c8f4..29b2a788748f 100644
> --- a/arch/arm/boot/dts/microchip/Makefile
> +++ b/arch/arm/boot/dts/microchip/Makefile
> @@ -12,6 +12,7 @@ DTC_FLAGS_at91-sama5d3_eds := -@
>  DTC_FLAGS_at91-sama5d3_xplained := -@
>  DTC_FLAGS_at91-sama5d4_xplained := -@
>  DTC_FLAGS_at91-sama7g5ek := -@
> +DTC_FLAGS_at91-sama7g54_curiosity := -@

Alphanumerical sort, thus DTC_FLAGS_at91-sama7g54_curiosity comes before
DTC_FLAGS_at91-sama7g5ek

>  dtb-$(CONFIG_SOC_AT91RM9200) += \
>  	at91rm9200ek.dtb \
>  	mpa1600.dtb
> @@ -87,7 +88,8 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
>  	at91-sama5d4ek.dtb \
>  	at91-vinco.dtb
>  dtb-$(CONFIG_SOC_SAMA7G5) += \
> -	at91-sama7g5ek.dtb
> +	at91-sama7g5ek.dtb \
> +	at91-sama7g54_curiosity.dtb

Same here.

>  
>  dtb-$(CONFIG_SOC_LAN966) += \
>  	lan966x-kontron-kswitch-d10-mmt-6g-2gs.dtb \
> diff --git a/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
> new file mode 100644
> index 000000000000..a6504c3781f4
> --- /dev/null
> +++ b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
> @@ -0,0 +1,487 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * at91-sama7g54_curiosity.dts - Device Tree file for SAMA7G54 Curiosity Board
> + *
> + * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
> + *
> + * Author: Mihai Sain <mihai.sain at microchip.com>
> + *
> + */
> +/dts-v1/;
> +#include "sama7g5-pinfunc.h"
> +#include "sama7g5.dtsi"
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/leds/common.h>
> +#include <dt-bindings/mfd/atmel-flexcom.h>
> +#include <dt-bindings/pinctrl/at91.h>
> +
> +/ {
> +	model = "Microchip SAMA7G54 Curiosity";
> +	compatible = "microchip,sama7g54-curiosity", "microchip,sama7g5", "microchip,sama7";
> +
> +	aliases {
> +		serial0 = &uart3;
> +		i2c0 = &i2c10;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_key_gpio_default>;
> +
> +		button-user {
> +			label = "user-button";
> +			gpios = <&pioA PIN_PD19 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_PROG1>;
> +			wakeup-source;
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_led_gpio_default>;
> +
> +		led-red {
> +			color = <LED_COLOR_ID_RED>;
> +			function = LED_FUNCTION_POWER;
> +			gpios = <&pioA PIN_PD13 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +		};
> +
> +		led-green {
> +			color = <LED_COLOR_ID_GREEN>;
> +			function = LED_FUNCTION_BOOT;
> +			gpios = <&pioA PIN_PD14 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +		};
> +
> +		led-blue {
> +			color = <LED_COLOR_ID_BLUE>;
> +			function = LED_FUNCTION_CPU;
> +			gpios = <&pioA PIN_PB15 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "heartbeat";
> +		};
> +	};
> +
> +	memory at 60000000 {
> +		device_type = "memory";
> +		reg = <0x60000000 0x10000000>; // 256 MiB DDR3L-1066 16-bit
> +	};
> +};
> +
> +&adc {
> +	vddana-supply = <&vddout25>;
> +	vref-supply = <&vddout25>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_mikrobus1_an_default &pinctrl_mikrobus2_an_default>;
> +	status = "okay";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&vddcpu>;
> +};
> +
> +&dma0 {
> +	status = "okay";
> +};
> +
> +&dma1 {
> +	status = "okay";
> +};
> +
> +&dma2 {
> +	status = "okay";
> +};
> +
> +&ebi {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_nand_default>;
> +	status = "okay";
> +
> +	nand_controller: nand-controller {
> +		status = "okay";
> +
> +		nand at 3 {
> +			reg = <0x3 0x0 0x800000>;
> +			atmel,rb = <0>;
> +			nand-bus-width = <8>;
> +			nand-ecc-mode = "hw";
> +			nand-ecc-strength = <8>;
> +			nand-ecc-step-size = <512>;
> +			nand-on-flash-bbt;
> +			label = "nand";
> +
> +			partitions {
> +				compatible = "fixed-partitions";
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +
> +				at91bootstrap at 0 {
> +					label = "nand: at91bootstrap";
> +					reg = <0x0 0x40000>;
> +				};
> +
> +				bootloader at 40000 {
> +					label = "nand: u-boot";
> +					reg = <0x40000 0x100000>;
> +				};
> +
> +				bootloaderenv at 140000 {
> +					label = "nand: u-boot env";
> +					reg = <0x140000 0x40000>;
> +				};
> +
> +				dtb at 180000 {
> +					label = "nand: device tree";
> +					reg = <0x180000 0x80000>;
> +				};
> +
> +				kernel at 200000 {
> +					label = "nand: kernel";
> +					reg = <0x200000 0x600000>;
> +				};
> +
> +				rootfs at 800000 {
> +					label = "nand: rootfs";
> +					reg = <0x800000 0x1f800000>;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&flx3 {
> +	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
> +	status = "okay";
> +
> +	uart3: serial at 200 {
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_flx3_default>;
> +		status = "okay";
> +	};
> +};
> +
> +&flx10 {
> +	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
> +	status = "okay";
> +
> +	i2c10: i2c at 600 {
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_flx10_default>;
> +		i2c-analog-filter;
> +		i2c-digital-filter;
> +		i2c-digital-filter-width-ns = <35>;
> +		status = "okay";
> +
> +		adc at 1f {
> +			compatible = "microchip,pac1934";

There is no driver for this one in the upstream Linux and the compatible is
not documented. I would remove the node until the driver lands in mainline
Linux.

> +			reg = <0x1f>;
> +		};
> +
> +		eeprom at 51 {
> +			compatible = "atmel,24c02";
> +			reg = <0x51>;
> +			pagesize = <16>;
> +			size = <256>;
> +			vcc-supply = <&vdd_3v3>;
> +		};
> +
> +		pmic at 5b {
> +			compatible = "microchip,mcp16502";
> +			reg = <0x5b>;
> +
> +			regulators {
> +				vdd_3v3: VDD_IO {
> +					regulator-name = "VDD_IO";
> +					regulator-min-microvolt = <3300000>;
> +					regulator-max-microvolt = <3300000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-microvolt = <3300000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vddioddr: VDD_DDR {
> +					regulator-name = "VDD_DDR";
> +					regulator-min-microvolt = <1350000>;
> +					regulator-max-microvolt = <1350000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-microvolt = <1350000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-on-in-suspend;
> +						regulator-suspend-microvolt = <1350000>;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vddcore: VDD_CORE {
> +					regulator-name = "VDD_CORE";
> +					regulator-min-microvolt = <1150000>;
> +					regulator-max-microvolt = <1150000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-voltage = <1150000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vddcpu: VDD_OTHER {
> +					regulator-name = "VDD_OTHER";
> +					regulator-min-microvolt = <1050000>;
> +					regulator-max-microvolt = <1250000>;
> +					regulator-initial-mode = <2>;
> +					regulator-allowed-modes = <2>, <4>;
> +					regulator-ramp-delay = <3125>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-on-in-suspend;
> +						regulator-suspend-voltage = <1050000>;
> +						regulator-mode = <4>;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +						regulator-mode = <4>;
> +					};
> +				};
> +
> +				vldo1: LDO1 {
> +					regulator-name = "LDO1";
> +					regulator-min-microvolt = <1800000>;
> +					regulator-max-microvolt = <1800000>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-suspend-voltage = <1800000>;
> +						regulator-on-in-suspend;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +					};
> +				};
> +
> +				vldo2: LDO2 {
> +					regulator-name = "LDO2";
> +					regulator-min-microvolt = <3300000>;
> +					regulator-max-microvolt = <3300000>;
> +					regulator-always-on;
> +
> +					regulator-state-standby {
> +						regulator-suspend-voltage = <3300000>;
> +						regulator-on-in-suspend;
> +					};
> +
> +					regulator-state-mem {
> +						regulator-off-in-suspend;
> +					};
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&main_xtal {
> +	clock-frequency = <24000000>;
> +};
> +
> +&qspi1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_qspi1_default>;
> +	status = "okay";
> +
> +	flash at 0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0x0>;
> +		spi-max-frequency = <100000000>;
> +		spi-tx-bus-width = <4>;
> +		spi-rx-bus-width = <4>;
> +		m25p,fast-read;
> +	};
> +};
> +
> +&pioA {
> +	pinctrl_flx3_default: flx3-default {
> +		pinmux = <PIN_PD16__FLEXCOM3_IO0>,
> +			 <PIN_PD17__FLEXCOM3_IO1>;
> +		bias-pull-up;
> +	};
> +
> +	pinctrl_flx10_default: flx10-default {
> +		pinmux = <PIN_PC30__FLEXCOM10_IO0>,
> +			 <PIN_PC31__FLEXCOM10_IO1>;
> +		bias-pull-up;
> +	};
> +
> +	pinctrl_key_gpio_default: key-gpio-default {
> +		pinmux = <PIN_PD19__GPIO>;
> +		bias-pull-up;
> +	};
> +
> +	pinctrl_led_gpio_default: led-gpio-default {
> +		pinmux = <PIN_PD13__GPIO>,
> +			 <PIN_PD14__GPIO>,
> +			 <PIN_PB15__GPIO>;
> +		bias-pull-up;
> +	};
> +
> +	pinctrl_mikrobus1_an_default: mikrobus1-an-default {
> +		pinmux = <PIN_PC15__GPIO>;
> +		bias-disable;
> +	};
> +
> +	pinctrl_mikrobus2_an_default: mikrobus2-an-default {
> +		pinmux = <PIN_PC13__GPIO>;
> +		bias-disable;
> +	};
> +
> +	pinctrl_nand_default: nand-default {
> +		pinmux = <PIN_PD9__D0>,
> +			 <PIN_PD10__D1>,
> +			 <PIN_PD11__D2>,
> +			 <PIN_PC21__D3>,
> +			 <PIN_PC22__D4>,
> +			 <PIN_PC23__D5>,
> +			 <PIN_PC24__D6>,
> +			 <PIN_PD2__D7>,
> +			 <PIN_PD3__NANDRDY>,
> +			 <PIN_PD4__NCS3_NANDCS>,
> +			 <PIN_PD5__NWE_NWR0_NANDWE>,
> +			 <PIN_PD6__NRD_NANDOE>,
> +			 <PIN_PD7__A21_NANDALE>,
> +			 <PIN_PD8__A22_NANDCLE>;
> +		bias-disable;
> +		slew-rate = <0>;
> +	};
> +
> +	pinctrl_qspi1_default: qspi1-default {
> +		pinmux = <PIN_PB22__QSPI1_IO3>,
> +			 <PIN_PB23__QSPI1_IO2>,
> +			 <PIN_PB24__QSPI1_IO1>,
> +			 <PIN_PB25__QSPI1_IO0>,
> +			 <PIN_PB26__QSPI1_CS>,
> +			 <PIN_PB27__QSPI1_SCK>;
> +		bias-pull-up;
> +		slew-rate = <0>;
> +	};
> +
> +	pinctrl_sdmmc0_default: sdmmc0-default {
> +		pinmux = <PIN_PA0__SDMMC0_CK>,
> +			 <PIN_PA1__SDMMC0_CMD>,
> +			 <PIN_PA2__SDMMC0_RSTN>,
> +			 <PIN_PA3__SDMMC0_DAT0>,
> +			 <PIN_PA4__SDMMC0_DAT1>,
> +			 <PIN_PA5__SDMMC0_DAT2>,
> +			 <PIN_PA6__SDMMC0_DAT3>;
> +		bias-pull-up;
> +		slew-rate = <0>;
> +	};
> +
> +	pinctrl_sdmmc1_default: sdmmc1-default {
> +		pinmux = <PIN_PB29__SDMMC1_CMD>,
> +			 <PIN_PB30__SDMMC1_CK>,
> +			 <PIN_PB31__SDMMC1_DAT0>,
> +			 <PIN_PC0__SDMMC1_DAT1>,
> +			 <PIN_PC1__SDMMC1_DAT2>,
> +			 <PIN_PC2__SDMMC1_DAT3>,
> +			 <PIN_PC4__SDMMC1_CD>;
> +		bias-pull-up;
> +		slew-rate = <0>;
> +	};
> +};
> +
> +&rtt {
> +	atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
> +};
> +
> +// M.2 slot for wireless card

Use C style comment instead /* */

> +&sdmmc0 {
> +	bus-width = <4>;
> +	cd-gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
> +	disable-wp;
> +	sdhci-caps-mask = <0x0 0x00200000>;
> +	vmmc-supply = <&vdd_3v3>;
> +	vqmmc-supply = <&vdd_3v3>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sdmmc0_default>;
> +	status = "okay";
> +};
> +
> +// micro SD socket
> +&sdmmc1 {
> +	bus-width = <4>;
> +	disable-wp;
> +	sdhci-caps-mask = <0x0 0x00200000>;
> +	vmmc-supply = <&vdd_3v3>;
> +	vqmmc-supply = <&vdd_3v3>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sdmmc1_default>;
> +	status = "okay";
> +};
> +
> +&slow_xtal {
> +	clock-frequency = <32768>;
> +};
> +
> +&shdwc {
> +	debounce-delay-us = <976>;
> +	status = "okay";
> +
> +	input at 0 {
> +		reg = <0>;
> +	};
> +};
> +
> +&tcb0 {
> +	timer0: timer at 0 {
> +		compatible = "atmel,tcb-timer";
> +		reg = <0>;
> +	};
> +
> +	timer1: timer at 1 {
> +		compatible = "atmel,tcb-timer";
> +		reg = <1>;
> +	};
> +};
> +
> +&trng {
> +	status = "okay";
> +};
> +
> +&vddout25 {
> +	vin-supply = <&vdd_3v3>;
> +	status = "okay";
> +};


From viresh.kumar at linaro.org  Wed Feb 14 23:26:53 2024
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 15 Feb 2024 12:56:53 +0530
Subject: [PATCH 1/3] dt-bindings: cpufreq: Add nvmem-cells for chip
 information
In-Reply-To: <20240206145721.2418893-2-msp@baylibre.com>
References: <20240206145721.2418893-1-msp@baylibre.com>
 <20240206145721.2418893-2-msp@baylibre.com>
Message-ID: <20240215072653.lscrdrmsges3psmc@vireshk-i7>

On 06-02-24, 15:57, Markus Schneider-Pargmann wrote:
> Add nvmem-cells to describe chip information like chipvariant and
> chipspeed. If nvmem-cells are used, the syscon property is not necessary
> anymore.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> Acked-by: Andrew Davis <afd at ti.com>

Rob,

Can you please review / Ack this one ?

-- 
viresh


From ck.hu at mediatek.com  Wed Feb 14 23:33:32 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 15 Feb 2024 07:33:32 +0000
Subject: [PATCH v5 4/9] drm/mediatek: dsi: Use bitfield macros where
 useful
In-Reply-To: <20240207145307.1626009-5-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
	 <20240207145307.1626009-5-angelogioacchino.delregno@collabora.com>
Message-ID: <1d2310c8ebc8be3630ed6386fba7c6fbce9bfb07.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-02-07 at 15:53 +0100, AngeloGioacchino Del Regno wrote:
> Instead of open coding bitshifting for various register fields,
> use the bitfield macro FIELD_PREP(): this allows to enhance the
> human readability, decrease likeliness of mistakes (and register
> field overflowing) and also to simplify the code.
> The latter is especially seen in mtk_dsi_rxtx_control(), where
> it was possible to change a switch to a short for loop and to
> also remove the need to check for maximum DSI lanes == 4 thanks
> to the FIELD_PREP macro masking the value.
> 
> While at it, also add the missing DA_HS_SYNC bitmask, used in
> mtk_dsi_phy_timconfig().
> 
> Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 97 ++++++++++++++++----------
> ----
>  1 file changed, 52 insertions(+), 45 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 7d38e9500700..a330bb94c44a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -3,6 +3,7 @@
>   * Copyright (c) 2015 MediaTek Inc.
>   */
>  
> +#include <linux/bitfield.h>
>  #include <linux/clk.h>
>  #include <linux/component.h>
>  #include <linux/iopoll.h>
> @@ -70,16 +71,19 @@
>  #define DSI_PSCTRL		0x1c
>  #define DSI_PS_WC			GENMASK(13, 0)
>  #define DSI_PS_SEL			GENMASK(17, 16)
> -#define PACKED_PS_16BIT_RGB565		(0 << 16)
> -#define PACKED_PS_18BIT_RGB666		(1 << 16)
> -#define LOOSELY_PS_24BIT_RGB666		(2 << 16)
> -#define PACKED_PS_24BIT_RGB888		(3 << 16)
> +#define PACKED_PS_16BIT_RGB565		0
> +#define PACKED_PS_18BIT_RGB666		1
> +#define LOOSELY_PS_24BIT_RGB666		2
> +#define PACKED_PS_24BIT_RGB888		3
>  
>  #define DSI_VSA_NL		0x20
>  #define DSI_VBP_NL		0x24
>  #define DSI_VFP_NL		0x28
>  #define DSI_VACT_NL		0x2C
> +#define VACT_NL				GENMASK(14, 0)
>  #define DSI_SIZE_CON		0x38
> +#define DSI_HEIGHT				GENMASK(30, 16)
> +#define DSI_WIDTH				GENMASK(14, 0)
>  #define DSI_HSA_WC		0x50
>  #define DSI_HBP_WC		0x54
>  #define DSI_HFP_WC		0x58
> @@ -122,6 +126,7 @@
>  
>  #define DSI_PHY_TIMECON2	0x118
>  #define CONT_DET			GENMASK(7, 0)
> +#define DA_HS_SYNC			GENMASK(15, 8)
>  #define CLK_ZERO			GENMASK(23, 16)
>  #define CLK_TRAIL			GENMASK(31, 24)
>  
> @@ -253,14 +258,23 @@ static void mtk_dsi_phy_timconfig(struct
> mtk_dsi *dsi)
>  	timing->clk_hs_zero = timing->clk_hs_trail * 4;
>  	timing->clk_hs_exit = 2 * timing->clk_hs_trail;
>  
> -	timcon0 = timing->lpx | timing->da_hs_prepare << 8 |
> -		  timing->da_hs_zero << 16 | timing->da_hs_trail << 24;
> -	timcon1 = timing->ta_go | timing->ta_sure << 8 |
> -		  timing->ta_get << 16 | timing->da_hs_exit << 24;
> -	timcon2 = 1 << 8 | timing->clk_hs_zero << 16 |
> -		  timing->clk_hs_trail << 24;
> -	timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 |
> -		  timing->clk_hs_exit << 16;
> +	timcon0 = FIELD_PREP(LPX, timing->lpx) |
> +		  FIELD_PREP(HS_PREP, timing->da_hs_prepare) |
> +		  FIELD_PREP(HS_ZERO, timing->da_hs_zero) |
> +		  FIELD_PREP(HS_TRAIL, timing->da_hs_trail);
> +
> +	timcon1 = FIELD_PREP(TA_GO, timing->ta_go) |
> +		  FIELD_PREP(TA_SURE, timing->ta_sure) |
> +		  FIELD_PREP(TA_GET, timing->ta_get) |
> +		  FIELD_PREP(DA_HS_EXIT, timing->da_hs_exit);
> +
> +	timcon2 = FIELD_PREP(DA_HS_SYNC, 1) |
> +		  FIELD_PREP(CLK_ZERO, timing->clk_hs_zero) |
> +		  FIELD_PREP(CLK_TRAIL, timing->clk_hs_trail);
> +
> +	timcon3 = FIELD_PREP(CLK_HS_PREP, timing->clk_hs_prepare) |
> +		  FIELD_PREP(CLK_HS_POST, timing->clk_hs_post) |
> +		  FIELD_PREP(CLK_HS_EXIT, timing->clk_hs_exit);
>  
>  	writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
>  	writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
> @@ -353,69 +367,61 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi
> *dsi)
>  
>  static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
>  {
> -	u32 tmp_reg;
> +	u32 regval, tmp_reg = 0;
> +	u8 i;
>  
> -	switch (dsi->lanes) {
> -	case 1:
> -		tmp_reg = 1 << 2;
> -		break;
> -	case 2:
> -		tmp_reg = 3 << 2;
> -		break;
> -	case 3:
> -		tmp_reg = 7 << 2;
> -		break;
> -	case 4:
> -		tmp_reg = 0xf << 2;
> -		break;
> -	default:
> -		tmp_reg = 0xf << 2;
> -		break;
> -	}
> +	/* Number of DSI lanes (max 4 lanes), each bit enables one DSI
> lane. */
> +	for (i = 0; i < dsi->lanes; i++)
> +		tmp_reg |= BIT(i);
> +
> +	regval = FIELD_PREP(LANE_NUM, tmp_reg);
>  
>  	if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
> -		tmp_reg |= HSTX_CKLP_EN;
> +		regval |= HSTX_CKLP_EN;
>  
>  	if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
> -		tmp_reg |= DIS_EOT;
> +		regval |= DIS_EOT;
>  
> -	writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
> +	writel(regval, dsi->regs + DSI_TXRX_CTRL);
>  }
>  
>  static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool
> config_vact)
>  {
> -	struct videomode *vm = &dsi->vm;
> -	u32 dsi_buf_bpp, ps_wc;
> -	u32 ps_bpp_mode;
> +	u32 dsi_buf_bpp, ps_val, ps_wc, vact_nl;
>  
>  	if (dsi->format == MIPI_DSI_FMT_RGB565)
>  		dsi_buf_bpp = 2;
>  	else
>  		dsi_buf_bpp = 3;
>  
> -	ps_wc = vm->hactive * dsi_buf_bpp;
> -	ps_bpp_mode = ps_wc;
> +	/* Word count */
> +	ps_wc = FIELD_PREP(DSI_PS_WC, dsi->vm.hactive * dsi_buf_bpp);
> +	ps_val = ps_wc;
>  
> +	/* Pixel Stream type */
>  	switch (dsi->format) {
> +	default:
> +		fallthrough;

This is not related to bitfield macro. You remove default in previous
patch but add it back in this patch. I think this should be moved to
previous patch. After this change,

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

>  	case MIPI_DSI_FMT_RGB888:
> -		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
> +		ps_val |= FIELD_PREP(DSI_PS_SEL,
> PACKED_PS_24BIT_RGB888);
>  		break;
>  	case MIPI_DSI_FMT_RGB666:
> -		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
> +		ps_val |= FIELD_PREP(DSI_PS_SEL,
> LOOSELY_PS_24BIT_RGB666);
>  		break;
>  	case MIPI_DSI_FMT_RGB666_PACKED:
> -		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
> +		ps_val |= FIELD_PREP(DSI_PS_SEL,
> PACKED_PS_18BIT_RGB666);
>  		break;
>  	case MIPI_DSI_FMT_RGB565:
> -		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
> +		ps_val |= FIELD_PREP(DSI_PS_SEL,
> PACKED_PS_16BIT_RGB565);
>  		break;
>  	}
>  
>  	if (config_vact) {
> -		writel(vm->vactive, dsi->regs + DSI_VACT_NL);
> +		vact_nl = FIELD_PREP(VACT_NL, dsi->vm.vactive);
> +		writel(vact_nl, dsi->regs + DSI_VACT_NL);
>  		writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
>  	}
> -	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
> +	writel(ps_val, dsi->regs + DSI_PSCTRL);
>  }
>  
>  static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
> @@ -442,7 +448,8 @@ static void mtk_dsi_config_vdo_timing(struct
> mtk_dsi *dsi)
>  	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
>  
>  	if (dsi->driver_data->has_size_ctl)
> -		writel(vm->vactive << 16 | vm->hactive,
> +		writel(FIELD_PREP(DSI_HEIGHT, vm->vactive) |
> +		       FIELD_PREP(DSI_WIDTH, vm->hactive),
>  		       dsi->regs + DSI_SIZE_CON);
>  
>  	horizontal_sync_active_byte = (vm->hsync_len * dsi_tmp_buf_bpp
> - 10);

From ck.hu at mediatek.com  Wed Feb 14 23:40:11 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 15 Feb 2024 07:40:11 +0000
Subject: [PATCH v5 5/9] drm/mediatek: dsi: Replace open-coded instance of
 HZ_PER_MHZ
In-Reply-To: <20240207145307.1626009-6-angelogioacchino.delregno@collabora.com>
References: <20240207145307.1626009-1-angelogioacchino.delregno@collabora.com>
	 <20240207145307.1626009-6-angelogioacchino.delregno@collabora.com>
Message-ID: <eb882267ee845fac3dc8905f46945e57afc38ffc.camel@mediatek.com>

Hi, Angelo:

On Wed, 2024-02-07 at 15:53 +0100, AngeloGioacchino Del Regno wrote:
> In mtk_dsi_phy_timconfig(), we're dividing the `data_rate` variable,
> expressed in Hz to retrieve a value in MHz: instead of open-coding,
> use the HZ_PER_MHZ definition, available in linux/units.h.

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

> 
> Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index a330bb94c44a..52758cab0abf 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -13,6 +13,7 @@
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
>  #include <linux/reset.h>
> +#include <linux/units.h>
>  
>  #include <video/mipi_display.h>
>  #include <video/videomode.h>
> @@ -238,7 +239,7 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32
> offset, u32 mask, u32 data)
>  static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
>  {
>  	u32 timcon0, timcon1, timcon2, timcon3;
> -	u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, 1000000);
> +	u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, HZ_PER_MHZ);
>  	struct mtk_phy_timing *timing = &dsi->phy_timing;
>  
>  	timing->lpx = (60 * data_rate_mhz / (8 * 1000)) + 1;

From horatiu.vultur at microchip.com  Thu Feb 15 00:07:42 2024
From: horatiu.vultur at microchip.com (Horatiu Vultur)
Date: Thu, 15 Feb 2024 09:07:42 +0100
Subject: [PATCH net-next] net: sparx5: Add spinlock for frame
 transmission from CPU
In-Reply-To: <20240214070908.37b49ddf@kernel.org>
References: <20240213121705.4070598-1-horatiu.vultur@microchip.com>
 <5476743f-3648-4038-97f8-a9df22c0f507@gmail.com>
 <20240214081442.w533wvcvqpvq5352@DEN-DL-M31836.microchip.com>
 <20240214070908.37b49ddf@kernel.org>
Message-ID: <20240215080742.t2yswxegwob34ouy@DEN-DL-M31836.microchip.com>

The 02/14/2024 07:09, Jakub Kicinski wrote:
> 
> On Wed, 14 Feb 2024 09:14:42 +0100 Horatiu Vultur wrote:
> > > Any reason you targeted 'net-next' rather than 'net', as this appears to
> > > be clearly a bug fix here?
> >
> > Yes, it is a bug but it is not something that happens all the
> > time and I thought this fits more into the lines of 'This could be a
> > problem ...' therefore I had targeted 'net-next'.
> > But if you consider that I should target 'net' instead of 'net-next' I
> > can do that.
> 
> Definitely a bug fix worthy of net, yes, please.

Perfect, I will do that.

> 

-- 
/Horatiu


From hj96.nam at samsung.com  Thu Feb 15 00:09:06 2024
From: hj96.nam at samsung.com (Hojin Nam)
Date: Thu, 15 Feb 2024 17:09:06 +0900
Subject: [PATCH v2] perf: CXL: fix CPMU filter value mask length
References: <CGME20240215080906epcms2p2c49c6b9bfe271e1d089ad35ab527b958@epcms2p2>
Message-ID: <20240215080906epcms2p2c49c6b9bfe271e1d089ad35ab527b958@epcms2p2>

CPMU filter value is described as 4B length in CXL r3.0 8.2.7.2.2.
However, it is used as 2B length in code and comments.

Signed-off-by: Hojin Nam <hj96.nam at samsung.com>
---

Hi Jonathan,
as you said, I didn't actually hit this. I just found it by simply
comparing the code to the CXL Spec. I removed Fixes tag and 
repaired broken sign off, Thank you!

Changes since v1:
- Remove Fixes tag (Jonathan)
- Repair broken sign off (Jonathan)

 drivers/perf/cxl_pmu.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index 365d964b0f6a..ca5e92f28b4a 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -59,7 +59,7 @@
 #define   CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK     GENMASK_ULL(63, 59)

 #define CXL_PMU_FILTER_CFG_REG(n, f)   (0x400 + 4 * ((f) + (n) * 8))
-#define   CXL_PMU_FILTER_CFG_VALUE_MSK                 GENMASK(15, 0)
+#define   CXL_PMU_FILTER_CFG_VALUE_MSK                 GENMASK(31, 0)

 #define CXL_PMU_COUNTER_REG(n)         (0xc00 + 8 * (n))

@@ -314,9 +314,9 @@ static bool cxl_pmu_config1_get_edge(struct perf_event *event)
 }

 /*
- * CPMU specification allows for 8 filters, each with a 16 bit value...
- * So we need to find 8x16bits to store it in.
- * As the value used for disable is 0xffff, a separate enable switch
+ * CPMU specification allows for 8 filters, each with a 32 bit value...
+ * So we need to find 8x32bits to store it in.
+ * As the value used for disable is 0xffff_ffff, a separate enable switch
  * is needed.
  */

@@ -642,7 +642,7 @@ static void cxl_pmu_event_start(struct perf_event *event, int flags)
                if (cxl_pmu_config1_hdm_filter_en(event))
                        cfg = cxl_pmu_config2_get_hdm_decoder(event);
                else
-                       cfg = GENMASK(15, 0); /* No filtering if 0xFFFF_FFFF */
+                       cfg = GENMASK(31, 0); /* No filtering if 0xFFFF_FFFF */
                writeq(cfg, base + CXL_PMU_FILTER_CFG_REG(hwc->idx, 0));
        }

--
2.34.1


From raphael.gallais-pou at foss.st.com  Thu Feb 15 00:15:12 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Thu, 15 Feb 2024 09:15:12 +0100
Subject: [PATCH 0/5] Add display support for stm32mp135f-dk board
In-Reply-To: <0c551a84-5c4a-4d79-ae59-d5b0d34b017d@foss.st.com>
References: <20240205-ltdc_mp13-v1-0-072d24bf1b36@foss.st.com>
 <0c551a84-5c4a-4d79-ae59-d5b0d34b017d@foss.st.com>
Message-ID: <77b05018-bdab-4737-a64b-1b7404626200@foss.st.com>

Hi Alex

On 2/14/24 14:40, Alexandre TORGUE wrote:
> Hi Raphael
>
> On 2/5/24 10:06, Raphael Gallais-Pou wrote:
>> This serie aims to enable display support for the stm32mp135f-dk board
>>
>> Those are only patches of the device-tree since the driver support has
>> already been added [1].
>>
>> It respectivelly:
>> ????- adds support for the display controller on stm32mp135
>> ????- adds pinctrl for the display controller
>> ????- enables panel, backlight and display controller on
>> ????? stm32mp135f-dk
>>
>> Finally it fixes the flags on the panel default mode in the
>> 'panel-simple' driver, allowing to override the default mode by one
>> described in the device tree, and push further the blanking limit on the
>> panel.
>>
>> [1] commit 1726cee3d053 ("drm/stm: ltdc: support of new hardware version")
>>
>> Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
>> ---
>> Raphael Gallais-Pou (5):
>> ?????? ARM: dts: stm32: add LTDC support for STM32MP13x SoC family
>> ?????? ARM: dts: stm32: add LTDC pinctrl on STM32MP13x SoC family
>> ?????? ARM: dts: stm32: enable display support on stm32mp135f-dk board
>> ?????? drm/panel: simple: fix flags on RK043FN48H
>> ?????? drm/panel: simple: push blanking limit on RK32FN48H
>>
>> ? arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 57 +++++++++++++++++++++++++++++
>> ? arch/arm/boot/dts/st/stm32mp135.dtsi??????? | 11 ++++++
>> ? arch/arm/boot/dts/st/stm32mp135f-dk.dts???? | 55 ++++++++++++++++++++++++++++
>> ? drivers/gpu/drm/panel/panel-simple.c??????? |? 7 ++--
>> ? 4 files changed, 127 insertions(+), 3 deletions(-)
>> ---
>> base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
>> change-id: 20240124-ltdc_mp13-2f86a782424c
>>
>> Best regards,
>
> I got the following errors during YAML verification:
>
> arch/arm/boot/dts/st/stm32mp135f-dk.dtb: /soc/i2c at 40012000/pinctrl at 21: failed
> to match any schema with compatible: ['microchip,mcp23017']
> /local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb:
> panel-backlight: 'default-brightness-level' does not match any of the regexes:
> 'pinctrl-[0-9]+'
> ????from schema $id:
> http://devicetree.org/schemas/leds/backlight/gpio-backlight.yaml#
> /local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb:
> panel-rgb: data-mapping:0: 'bgr666' is not one of ['jeida-18', 'jeida-24',
> 'vesa-24']
> ????from schema $id:
> http://devicetree.org/schemas/display/panel/panel-simple.yaml#
> /local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb:
> panel-rgb: compatible: ['rocktech,rk043fn48h', 'panel-dpi'] is too long
> ????from schema $id:
> http://devicetree.org/schemas/display/panel/panel-simple.yaml#
> /local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb:
> panel-rgb: data-mapping: False schema does not allow ['bgr666']
> ????from schema $id:
> http://devicetree.org/schemas/display/panel/panel-simple.yaml#
> /local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb:
> panel-rgb: 'height-mm', 'panel-timing', 'width-mm' do not match any of the
> regexes: 'pinctrl-[0-9]+'
> ????from schema $id:
> http://devicetree.org/schemas/display/panel/panel-simple.yaml#
> /local/home/frq08678/STLINUX/kernel/my-kernel/stm32/arch/arm/boot/dts/st/stm32mp135f-dk.dtb:
> panel-rgb: 'data-mapping' does not match any of the regexes: 'pinctrl-[0-9]+'
> ????from schema $id: http://devicetree.org/schemas/display/panel/panel-dpi.yaml#
>
> Do I miss something ?


I think I messed using a wrong? make option :

make DTBS_CHECK=y W=1 -j$(nproc) st/stm32mp135f-dk.dtb

instead of

make CHECK_DTBS=y W=1 -j$(nproc) st/stm32mp135f-dk.dtb


I'll send a fix promptly.


Thanks,

Rapha?l

>
> Alex
>
>


From krzysztof.kozlowski at linaro.org  Thu Feb 15 00:24:13 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 09:24:13 +0100
Subject: [PATCH 1/3] dt-bindings: cpufreq: Add nvmem-cells for chip
 information
In-Reply-To: <20240206145721.2418893-2-msp@baylibre.com>
References: <20240206145721.2418893-1-msp@baylibre.com>
 <20240206145721.2418893-2-msp@baylibre.com>
Message-ID: <98c9d3ce-8a97-499f-b78a-b918a06ec779@linaro.org>

On 06/02/2024 15:57, Markus Schneider-Pargmann wrote:
> Add nvmem-cells to describe chip information like chipvariant and
> chipspeed. If nvmem-cells are used, the syscon property is not necessary
> anymore.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> Acked-by: Andrew Davis <afd at ti.com>

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb 15 00:24:30 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 09:24:30 +0100
Subject: [PATCH 3/3] arm64: dts: ti: k3-am625: Use nvmem-cells for opp
In-Reply-To: <20240206145721.2418893-4-msp@baylibre.com>
References: <20240206145721.2418893-1-msp@baylibre.com>
 <20240206145721.2418893-4-msp@baylibre.com>
Message-ID: <f010b72e-955f-4bb9-aad7-5cb9bb91502c@linaro.org>

On 06/02/2024 15:57, Markus Schneider-Pargmann wrote:
> Use nvmem cells referring to chip variant and speed grade for the
> operating points.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> ---
>  arch/arm64/boot/dts/ti/k3-am625.dtsi | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am625.dtsi b/arch/arm64/boot/dts/ti/k3-am625.dtsi
> index 4193c2b3eed6..d60e1be9eb89 100644
> --- a/arch/arm64/boot/dts/ti/k3-am625.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am625.dtsi
> @@ -105,6 +105,8 @@ a53_opp_table: opp-table {
>  		compatible = "operating-points-v2-ti-cpu";
>  		opp-shared;
>  		syscon = <&wkup_conf>;
> +		nvmem-cells = <&chip_variant>, <&chip_speed>;
> +		nvmem-cell-names = "chipvariant", "chipspeed";

It does not look like you tested the DTS against bindings. Please run
`make dtbs_check W=1` (see
Documentation/devicetree/bindings/writing-schema.rst or
https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
for instructions).

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb 15 00:25:00 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 09:25:00 +0100
Subject: [PATCH 1/3] dt-bindings: cpufreq: Add nvmem-cells for chip
 information
In-Reply-To: <20240215072653.lscrdrmsges3psmc@vireshk-i7>
References: <20240206145721.2418893-1-msp@baylibre.com>
 <20240206145721.2418893-2-msp@baylibre.com>
 <20240215072653.lscrdrmsges3psmc@vireshk-i7>
Message-ID: <46645341-1484-42d8-8540-580b586e2315@linaro.org>

On 15/02/2024 08:26, Viresh Kumar wrote:
> On 06-02-24, 15:57, Markus Schneider-Pargmann wrote:
>> Add nvmem-cells to describe chip information like chipvariant and
>> chipspeed. If nvmem-cells are used, the syscon property is not necessary
>> anymore.
>>
>> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
>> Acked-by: Andrew Davis <afd at ti.com>
> 
> Rob,
> 
> Can you please review / Ack this one ?

Done now, although it is not aligned with DTS in this patchset, so this
does not look tested...

Best regards,
Krzysztof



From devarsht at ti.com  Thu Feb 15 00:32:05 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Thu, 15 Feb 2024 14:02:05 +0530
Subject: [PATCH v3 2/2] arm64: dts: ti: Add common1 register space for AM62x, AM62A & AM65x SoCs
In-Reply-To: <20240215083205.2902634-1-devarsht@ti.com>
References: <20240215083205.2902634-1-devarsht@ti.com>
Message-ID: <20240215083205.2902634-3-devarsht@ti.com>

This adds common1 register space for AM62x, AM62A and AM65x SoC's which are
using TI's Keystone display hardware and supporting it as described in
Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml

Fixes: 3618811657b3 ("arm64: dts: ti: k3-am62a-main: Add node for Display SubSystem (DSS)")
Fixes: 8ccc1073c7bb ("arm64: dts: ti: k3-am62-main: Add node for DSS")
Fixes: fc539b90eda2 ("arm64: dts: ti: am654: Add DSS node")
Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
---
V2: Add common1 region for AM62A SoC too
V3: Add Fixes tag
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi  | 5 +++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 5 +++--
 arch/arm64/boot/dts/ti/k3-am65-main.dtsi  | 5 +++--
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index fe0cc4a9a501..8cee4d94cdd3 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -779,9 +779,10 @@ dss: dss at 30200000 {
 		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
 		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
 		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
-		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			    "ovr1", "ovr2", "vp1", "vp2";
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
 		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 186 6>,
 			 <&dss_vp1_clk>,
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 972971159a62..f475daea548e 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -994,9 +994,10 @@ dss: dss at 30200000 {
 		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
 		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
 		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Tied OFF in the SoC */
-		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			    "ovr1", "ovr2", "vp1", "vp2";
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
 		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 186 6>,
 			 <&k3_clks 186 0>,
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index 07010d31350e..ff857117d719 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -991,9 +991,10 @@ dss: dss at 4a00000 {
 		      <0x0 0x04a07000 0x0 0x1000>, /* ovr1 */
 		      <0x0 0x04a08000 0x0 0x1000>, /* ovr2 */
 		      <0x0 0x04a0a000 0x0 0x1000>, /* vp1 */
-		      <0x0 0x04a0b000 0x0 0x1000>; /* vp2 */
+		      <0x0 0x04a0b000 0x0 0x1000>, /* vp2 */
+		      <0x0 0x04a01000 0x0 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			"ovr1", "ovr2", "vp1", "vp2";
+			"ovr1", "ovr2", "vp1", "vp2", "common1";
 
 		ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
 
-- 
2.34.1



From devarsht at ti.com  Thu Feb 15 00:32:04 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Thu, 15 Feb 2024 14:02:04 +0530
Subject: [PATCH v3 1/2] dt-bindings: display: ti,am65x-dss: Add support for common1 region
In-Reply-To: <20240215083205.2902634-1-devarsht@ti.com>
References: <20240215083205.2902634-1-devarsht@ti.com>
Message-ID: <20240215083205.2902634-2-devarsht@ti.com>

TI keystone display subsystem present in AM65 and other SoCs such as AM62
support two separate register spaces namely "common" and "common1" which
can be used by two separate hosts to program the display controller as
described in respective Technical Reference Manuals [1].

The common1 register space has similar set of configuration registers as
supported in common register space except the global configuration
registers which are exclusive to common region.

This adds binding for "common1" register region too as supported by the
hardware.

[1]:
AM62x TRM:
https://www.ti.com/lit/pdf/spruiv7 (Section 14.8.9.1 DSS Registers)

AM65x TRM:
https://www.ti.com/lit/pdf/spruid7 (Section 12.6.5 DSS Registers)

Fixes: 2d8730f1021f ("dt-bindings: display: ti,am65x-dss: Add dt-schema yaml binding")
Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
V2: Add Acked-by tag
V3: Add Fixes tag
---
 .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
index b6767ef0d24d..55e3e490d0e6 100644
--- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
+++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
@@ -37,6 +37,7 @@ properties:
       - description: OVR2 overlay manager for vp2
       - description: VP1 video port 1
       - description: VP2 video port 2
+      - description: common1 DSS register area
 
   reg-names:
     items:
@@ -47,6 +48,7 @@ properties:
       - const: ovr2
       - const: vp1
       - const: vp2
+      - const: common1
 
   clocks:
     items:
@@ -147,9 +149,10 @@ examples:
                     <0x04a07000 0x1000>, /* ovr1 */
                     <0x04a08000 0x1000>, /* ovr2 */
                     <0x04a0a000 0x1000>, /* vp1 */
-                    <0x04a0b000 0x1000>; /* vp2 */
+                    <0x04a0b000 0x1000>, /* vp2 */
+                    <0x04a01000 0x1000>; /* common1 */
             reg-names = "common", "vidl1", "vid",
-                    "ovr1", "ovr2", "vp1", "vp2";
+                    "ovr1", "ovr2", "vp1", "vp2", "common1";
             ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
             power-domains = <&k3_pds 67 TI_SCI_PD_EXCLUSIVE>;
             clocks =        <&k3_clks 67 1>,
-- 
2.34.1



From devarsht at ti.com  Thu Feb 15 00:32:03 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Thu, 15 Feb 2024 14:02:03 +0530
Subject: [PATCH v3 0/2] Add common1 region for AM62, AM62A & AM65x
Message-ID: <20240215083205.2902634-1-devarsht@ti.com>

This adds DSS common1 region for respective SoCs supporting it.

Changelog:
V2 : Remove do-not-merge tag and add am62a dss common1 reion
V3 : Add Fixes tag to each commit
 
Devarsh Thakkar (2):
  dt-bindings: display: ti,am65x-dss: Add support for common1 region
  arm64: dts: ti: Add common1 register space for AM62x, AM62A & AM65x
    SoCs

 .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi                   | 5 +++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi                  | 5 +++--
 arch/arm64/boot/dts/ti/k3-am65-main.dtsi                   | 5 +++--
 4 files changed, 14 insertions(+), 8 deletions(-)

-- 
2.34.1



From horatiu.vultur at microchip.com  Thu Feb 15 00:33:33 2024
From: horatiu.vultur at microchip.com (Horatiu Vultur)
Date: Thu, 15 Feb 2024 09:33:33 +0100
Subject: [PATCH net v2] net: sparx5: Add spinlock for frame transmission from CPU
Message-ID: <20240215083333.2139380-1-horatiu.vultur@microchip.com>

Both registers used when doing manual injection or fdma injection are
shared between all the net devices of the switch. It was noticed that
when having two process which each of them trying to inject frames on
different ethernet ports, that the HW started to behave strange, by
sending out more frames then expected. When doing fdma injection it is
required to set the frame in the DCB and then make sure that the next
pointer of the last DCB is invalid. But because there is no locks for
this, then easily this pointer between the DCB can be broken and then it
would create a loop of DCBs. And that means that the HW will
continuously transmit these frames in a loop. Until the SW will break
this loop.
Therefore to fix this issue, add a spin lock for when accessing the
registers for manual or fdma injection.

Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Reviewed-by: Daniel Machon <daniel.machon at microchip.com>
---
v1->v2:
- target net instead of net-next
---
 drivers/net/ethernet/microchip/sparx5/sparx5_main.c   | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_main.h   | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_packet.c | 2 ++
 3 files changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index d1f7fc8b1b71a..3c066b62e6894 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -757,6 +757,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, sparx5);
 	sparx5->pdev = pdev;
 	sparx5->dev = &pdev->dev;
+	spin_lock_init(&sparx5->tx_lock);
 
 	/* Do switch core reset if available */
 	reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index 6f565c0c0c3dc..316fed5f27355 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -280,6 +280,7 @@ struct sparx5 {
 	int xtr_irq;
 	/* Frame DMA */
 	int fdma_irq;
+	spinlock_t tx_lock; /* lock for frame transmission */
 	struct sparx5_rx rx;
 	struct sparx5_tx tx;
 	/* PTP */
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
index 6db6ac6a3bbc2..ac7e1cffbcecf 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
@@ -244,10 +244,12 @@ netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	skb_tx_timestamp(skb);
+	spin_lock(&sparx5->tx_lock);
 	if (sparx5->fdma_irq > 0)
 		ret = sparx5_fdma_xmit(sparx5, ifh, skb);
 	else
 		ret = sparx5_inject(sparx5, ifh, skb, dev);
+	spin_unlock(&sparx5->tx_lock);
 
 	if (ret == -EBUSY)
 		goto busy;
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb 15 00:34:53 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 09:34:53 +0100
Subject: [PATCH 13/22] dt-bindings: chrome: Add
 google,cros-ec-typec-switch binding
In-Reply-To: <CAE-0n52TzOAqN8Y7EdJPjDxY2iY-6Jr-Pq8fFMFtF-cXo5+OyA@mail.gmail.com>
References: <20240210070934.2549994-1-swboyd@chromium.org>
 <20240210070934.2549994-14-swboyd@chromium.org>
 <46ac6ab8-b0a5-497d-91b6-1d2ced33184b@linaro.org>
 <CAE-0n52TzOAqN8Y7EdJPjDxY2iY-6Jr-Pq8fFMFtF-cXo5+OyA@mail.gmail.com>
Message-ID: <dfcb1556-fa09-4d2e-b128-341e9725d3de@linaro.org>

On 15/02/2024 02:52, Stephen Boyd wrote:
> Quoting Krzysztof Kozlowski (2024-02-11 05:34:25)
>> On 10/02/2024 08:09, Stephen Boyd wrote:
>>> Add a binding for the USB type-c switch controls found on some ChromeOS
>>> Embedded Controllers (ECs). When this device is a mode switch, it takes
>>> one DisplayPort (DP) port as input and some number (possibly zero) of
>>> USB SuperSpeed ports (bundles of USB SS lanes) as input, and muxes those
>>> lanes into USB type-c SuperSpeed lanes suitable for the SSTRX1/2 pins on
>>> a usb-c-connector. When this device is an orientation switch, it
>>> redirects the DP lanes to the proper USB type-c SSTRX lanes.
>>>
>>> Cc: Rob Herring <robh+dt at kernel.org>
>>> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
>>> Cc: Conor Dooley <conor+dt at kernel.org>
>>> Cc: Lee Jones <lee at kernel.org>
>>> Cc: Benson Leung <bleung at chromium.org>
>>> Cc: Guenter Roeck <groeck at chromium.org>
>>> Cc: Prashant Malani <pmalani at chromium.org>
>>> Cc: Tzung-Bi Shih <tzungbi at kernel.org>
>>> Cc: <devicetree at vger.kernel.org>
>>> Cc: <chrome-platform at lists.linux.dev>
>>> Cc: Pin-yen Lin <treapking at chromium.org>
>>> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
>>> ---
>>>  .../chrome/google,cros-ec-typec-switch.yaml   | 365 ++++++++++++++++++
>>>  .../bindings/mfd/google,cros-ec.yaml          |   5 +
>>>  2 files changed, 370 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml b/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
>>> new file mode 100644
>>> index 000000000000..17a0ba928f5d
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/chrome/google,cros-ec-typec-switch.yaml
>>> @@ -0,0 +1,365 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/chrome/google,cros-ec-typec-switch.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Google Chrome OS EC(Embedded Controller) USB Type C Switch
>>> +
>>> +maintainers:
>>> +  - Benson Leung <bleung at chromium.org>
>>> +  - Prashant Malani <pmalani at chromium.org>
>>> +  - Stephen Boyd <swboyd at chromium.org>
>>> +
>>> +description:
>>> +  Chrome OS devices have an Embedded Controller(EC) which has access to USB
>>> +  Type C switching. This node is intended to allow the OS to control Type C
>>> +  signal muxing for USB-C orientation and alternate modes. The node for this
>>> +  device should be under a cros-ec node like google,cros-ec-spi.
>>> +
>>
>> If this is USB Type C switch, then you miss reference to
>> usb-switch.yaml, but then ports look a bit different.
> 
> Thanks for the pointer. I suspect that's in linux-next only? I'm going

Yes, Greg's tree.

> to move this to the cros-ec-typec.yaml file but I'll still need some
> sort of property like 'mode-switch' or 'orientation-switch' to describe
> what needs to be done in the kernel by changing lane assignments in the
> drm_bridge.
> 
> One problem with those properties is that they're boolean for the whole
> device. If I have a google,cros-ec-typec node that has two input DP
> ports and two output USB-C ports then it may be that one port needs
> orientation switching and the other only needs to do mode switching.
> This needs to be expressed somehow and a top-level boolean property
> doesn't do that. It could be part of the DP endpoint node itself.

Maybe it can be added to the connector binding as well.

> 
> Also I don't know how to indicate that mode switching can't be changed
> here directly. For example, on Trogdor the mode is switched by the EC,
> and the kernel can't change the mode. Changing DP lane assignments isn't
> going to change the situation either. The mode is still going to be
> something like DP+USB, or just DP, etc. Maybe there needs to be a
> different property, like 'dp-mode-lane-assignment = <array of ports>',
> that indicates which DP ports need to do lane assignment or
> 'dp-orientation-lane-assignment = <array of ports>' for orientation
> control. Either way, I'm saying that 'mode-switch' and
> 'orientation-switch' properties don't make any sense here. I was using
> them to wedge the code into the typec switch callbacks, but if I move
> this into the cros-ec-typec driver then I don't need them.

OK

> 
>>
>>> +
>>> +  no-hpd:
>>> +    description: Indicates this device doesn't signal HPD for DisplayPort
>>> +    type: boolean
>>> +
>>> +  ports:
> [...]
>>> +
>>> +          endpoint at 7:
>>> +            $ref: /schemas/graph.yaml#/$defs/endpoint-base
>>> +            description: USB-C data for EC's 7th type-c port
>>> +            unevaluatedProperties: false
>>> +            properties:
>>> +              data-lanes:
>>> +                $ref: /schemas/types.yaml#/definitions/uint32-array
>>> +                description: |
>>> +                  An array of physical USB-C data lane indexes.
>>> +                  - 0 is SSRX1 lane
>>> +                  - 1 is SSTX1 lane
>>> +                  - 2 is SSTX2 lane
>>> +                  - 3 is SSRX2 lane
>>> +                minItems: 4
>>> +                maxItems: 4
>>> +                items:
>>> +                  maximum: 3
>>> +
>>> +        anyOf:
>>> +          - required:
>>> +              - endpoint at 0
>>
>> I don't get what you want to say here. This anyOf should have no effect.
> 
> I'm trying to say that there should be at least one usb-c data lane
> output endpoint if there's a port at 2 (usb-c output).

Wait, my bad, this is good. At least one endpoint will be required.

> 
>>
>>> +          - required:
>>> +              - endpoint at 1
>>> +          - required:
>>> +              - endpoint at 2
> [...]
>>
>>> +
>>> +required:
>>> +  - compatible
>>> +  - ports
>>> +
>>> +allOf:
>>> +  - if:
>>> +      properties:
>>> +        no-hpd: true
>>
>> I don't understand this either. What is it for? Where did you see such
>> syntax?
> 
> This is saying that if the no-hpd property is present then the port at 0
> port (DP input port) is required. Otherwise no-hpd doesn't really make
> any sense because this device isn't muxing DP onto USB type-c connectors.

Then you only need if: required: like here:

https://elixir.bootlin.com/linux/v6.4-rc7/source/Documentation/devicetree/bindings/net/qcom,ipa.yaml#L174

> 
> I found this syntax by searching the schema website and reading this
> page[1]. The last yellow note about "country" not being a required
> property led me to this syntax.
> 
> [1] https://json-schema.org/understanding-json-schema/reference/conditionals#ifthenelse

Best regards,
Krzysztof



From viresh.kumar at linaro.org  Thu Feb 15 00:36:01 2024
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 15 Feb 2024 14:06:01 +0530
Subject: [PATCH 1/3] dt-bindings: cpufreq: Add nvmem-cells for chip
 information
In-Reply-To: <46645341-1484-42d8-8540-580b586e2315@linaro.org>
References: <20240206145721.2418893-1-msp@baylibre.com>
 <20240206145721.2418893-2-msp@baylibre.com>
 <20240215072653.lscrdrmsges3psmc@vireshk-i7>
 <46645341-1484-42d8-8540-580b586e2315@linaro.org>
Message-ID: <20240215083601.33dye7nypov2cz54@vireshk-i7>

On 15-02-24, 09:25, Krzysztof Kozlowski wrote:
> On 15/02/2024 08:26, Viresh Kumar wrote:
> > On 06-02-24, 15:57, Markus Schneider-Pargmann wrote:
> >> Add nvmem-cells to describe chip information like chipvariant and
> >> chipspeed. If nvmem-cells are used, the syscon property is not necessary
> >> anymore.
> >>
> >> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> >> Acked-by: Andrew Davis <afd at ti.com>
> > 
> > Rob,
> > 
> > Can you please review / Ack this one ?
> 
> Done now, although it is not aligned with DTS in this patchset, so this
> does not look tested...

I will wait for them to be fixed then.

-- 
viresh


From krzysztof.kozlowski at linaro.org  Thu Feb 15 00:39:18 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 09:39:18 +0100
Subject: [PATCH 18/22] dt-bindings: chrome: Add binding for ChromeOS Pogo
 pin connector
In-Reply-To: <CAE-0n50Y_GRMt8km=XjGC5Zm5dvb2t4gccznJn9HEFS4p7y8fQ@mail.gmail.com>
References: <20240210070934.2549994-1-swboyd@chromium.org>
 <20240210070934.2549994-19-swboyd@chromium.org>
 <18ac05fb-a78d-4e95-a73d-461f509cdc5f@linaro.org>
 <CAE-0n50Y_GRMt8km=XjGC5Zm5dvb2t4gccznJn9HEFS4p7y8fQ@mail.gmail.com>
Message-ID: <7be10595-3852-4fec-a53c-b7d8ddde84c3@linaro.org>

On 15/02/2024 01:07, Stephen Boyd wrote:
> Quoting Krzysztof Kozlowski (2024-02-11 05:39:36)
>> On 10/02/2024 08:09, Stephen Boyd wrote:
>>> diff --git a/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml b/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml
>>> new file mode 100644
>>> index 000000000000..5ba68fd95fcd
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/chrome/google,pogo-pin-connector.yaml
>>> @@ -0,0 +1,61 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
> [...]
>>
>>> +properties:
>>> +  compatible:
>>> +    const: google,pogo-pin-connector
>>> +
>>> +  "#address-cells":
>>> +    const: 1
>>> +
>>> +  "#size-cells":
>>> +    const: 0
>>> +
>>> +  port:
>>> +    $ref: /schemas/graph.yaml#/properties/port
>>> +    description: Connection to USB2 port providing USB signals
>>> +    required:
>>> +      - endpoint
>>
>> Drop required.
> 
> Why? I'd like to make it so you can't have the node defined without
> connecting it up to the rest of the system. Is that bad?

Hm, I double checked and you're right. I thought endpoint is required
anyway by graph.yaml in dtschema, but it seems it is not.

> 
>>
>>
>>> +
>>> +patternProperties:
>>> +  "^keyboard@[0-9a-f]{1,2}$":
>>> +    description: The detachable keyboard
>>
>> If this is detachable why do you define it in DT? Only hard-wired USB
>> devices, which need some sort of special handling. are described in DT.
> 
> From the commit text:
> 
>  We expect to find a keyboard on the other side of this connector with a
>  specific vid/pid, so describe that as a child device at the port of the
>  usb device connected upstream.
> 
> ChromeOS userspace is checking that the connected device downstream of
> this port has the expected vid/pid to quickly rule out USB keyboards
> that aren't the detachable keyboard. I wanted to express this in DT so
> that it didn't live in ChromeOS userspace forever.

OK,

Best regards,
Krzysztof



From horatiu.vultur at microchip.com  Thu Feb 15 00:41:01 2024
From: horatiu.vultur at microchip.com (Horatiu Vultur)
Date: Thu, 15 Feb 2024 09:41:01 +0100
Subject: [PATCH net v2] net: sparx5: Add spinlock for frame transmission
 from CPU
In-Reply-To: <20240215083333.2139380-1-horatiu.vultur@microchip.com>
References: <20240215083333.2139380-1-horatiu.vultur@microchip.com>
Message-ID: <20240215084101.bunwttvbsx4ecmad@DEN-DL-M31836.microchip.com>

The 02/15/2024 09:33, Horatiu Vultur wrote:
> Both registers used when doing manual injection or fdma injection are
> shared between all the net devices of the switch. It was noticed that
> when having two process which each of them trying to inject frames on
> different ethernet ports, that the HW started to behave strange, by
> sending out more frames then expected. When doing fdma injection it is
> required to set the frame in the DCB and then make sure that the next
> pointer of the last DCB is invalid. But because there is no locks for
> this, then easily this pointer between the DCB can be broken and then it
> would create a loop of DCBs. And that means that the HW will
> continuously transmit these frames in a loop. Until the SW will break
> this loop.
> Therefore to fix this issue, add a spin lock for when accessing the
> registers for manual or fdma injection.
> 
> Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>
> Reviewed-by: Daniel Machon <daniel.machon at microchip.com>

Argh... I forgot to add the Fixes tag:
Fixes: f3cad2611a77 ("net: sparx5: add hostmode with phylink support")

> ---
> v1->v2:
> - target net instead of net-next
> ---
>  drivers/net/ethernet/microchip/sparx5/sparx5_main.c   | 1 +
>  drivers/net/ethernet/microchip/sparx5/sparx5_main.h   | 1 +
>  drivers/net/ethernet/microchip/sparx5/sparx5_packet.c | 2 ++
>  3 files changed, 4 insertions(+)
> 
> diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
> index d1f7fc8b1b71a..3c066b62e6894 100644
> --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
> +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
> @@ -757,6 +757,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
>  	platform_set_drvdata(pdev, sparx5);
>  	sparx5->pdev = pdev;
>  	sparx5->dev = &pdev->dev;
> +	spin_lock_init(&sparx5->tx_lock);
>  
>  	/* Do switch core reset if available */
>  	reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");
> diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
> index 6f565c0c0c3dc..316fed5f27355 100644
> --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
> +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
> @@ -280,6 +280,7 @@ struct sparx5 {
>  	int xtr_irq;
>  	/* Frame DMA */
>  	int fdma_irq;
> +	spinlock_t tx_lock; /* lock for frame transmission */
>  	struct sparx5_rx rx;
>  	struct sparx5_tx tx;
>  	/* PTP */
> diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
> index 6db6ac6a3bbc2..ac7e1cffbcecf 100644
> --- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
> +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
> @@ -244,10 +244,12 @@ netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
>  	}
>  
>  	skb_tx_timestamp(skb);
> +	spin_lock(&sparx5->tx_lock);
>  	if (sparx5->fdma_irq > 0)
>  		ret = sparx5_fdma_xmit(sparx5, ifh, skb);
>  	else
>  		ret = sparx5_inject(sparx5, ifh, skb, dev);
> +	spin_unlock(&sparx5->tx_lock);
>  
>  	if (ret == -EBUSY)
>  		goto busy;
> -- 
> 2.34.1
> 

-- 
/Horatiu


From angelogioacchino.delregno at collabora.com  Thu Feb 15 00:53:07 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 09:53:07 +0100
Subject: [PATCH v6 0/9] MediaTek DRM - DSI driver cleanups
Message-ID: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>

Changes in v6:
 - Moved default case from patch [4/9] to patch [3/9]

Changes in v5:
 - Changed patch 1 to not fix the DSI_PS_SEL mask for newer SoCs

Changes in v4:
 - Added a fix for RGB666 formats setting and for wrong register
   definitions for packed vs loosely packed formats
 - Added a commit to make use of mipi_dsi_pixel_format_to_bpp() helper
   instead of open coding the same

Changes in v3:
 - Rebased over next-20240131
 - Added bitfield.h inclusion in patch 3
 - Added three more cleanup commits to the mix to simplify
   the probe function and remove gotos.

Changes in v2:
 - Rebased over next-20231213

This series performs some cleanups for mtk_dsi, enhancing human
readability, using kernel provided macros where possible and
also reducing code size.

Tested on MT8173 and MT8192 Chromebooks (using a DSI<->DP bridge)
and on MT6795 Sony Xperia M5 (DSI video mode panel).


AngeloGioacchino Del Regno (9):
  drm/mediatek: dsi: Use GENMASK() for register mask definitions
  drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
  drm/mediatek: dsi: Cleanup functions mtk_dsi_ps_control{_vact}()
  drm/mediatek: dsi: Use bitfield macros where useful
  drm/mediatek: dsi: Replace open-coded instance of HZ_PER_MHZ
  drm/mediatek: dsi: Register DSI host after acquiring clocks and PHY
  drm/mediatek: dsi: Simplify with dev_err_probe and remove gotos
  drm/mediatek: dsi: Compress of_device_id entries and add sentinel
  drm/mediatek: dsi: Use mipi_dsi_pixel_format_to_bpp() helper function

 drivers/gpu/drm/mediatek/mtk_dsi.c | 310 ++++++++++++-----------------
 1 file changed, 126 insertions(+), 184 deletions(-)

-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb 15 00:53:08 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 09:53:08 +0100
Subject: [PATCH v6 1/9] drm/mediatek: dsi: Use GENMASK() for register mask definitions
In-Reply-To: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240215085316.56835-2-angelogioacchino.delregno@collabora.com>

Change magic numerical masks with usage of the GENMASK() macro
to improve readability.

This commit brings no functional changes.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 45 +++++++++++++++---------------
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index a2fdfc8ddb15..c66e18006070 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -58,18 +58,18 @@
 
 #define DSI_TXRX_CTRL		0x18
 #define VC_NUM				BIT(1)
-#define LANE_NUM			(0xf << 2)
+#define LANE_NUM			GENMASK(5, 2)
 #define DIS_EOT				BIT(6)
 #define NULL_EN				BIT(7)
 #define TE_FREERUN			BIT(8)
 #define EXT_TE_EN			BIT(9)
 #define EXT_TE_EDGE			BIT(10)
-#define MAX_RTN_SIZE			(0xf << 12)
+#define MAX_RTN_SIZE			GENMASK(15, 12)
 #define HSTX_CKLP_EN			BIT(16)
 
 #define DSI_PSCTRL		0x1c
-#define DSI_PS_WC			0x3fff
-#define DSI_PS_SEL			(3 << 16)
+#define DSI_PS_WC			GENMASK(13, 0)
+#define DSI_PS_SEL			GENMASK(17, 16)
 #define PACKED_PS_16BIT_RGB565		(0 << 16)
 #define LOOSELY_PS_18BIT_RGB666		(1 << 16)
 #define PACKED_PS_18BIT_RGB666		(2 << 16)
@@ -109,26 +109,26 @@
 #define LD0_WAKEUP_EN			BIT(2)
 
 #define DSI_PHY_TIMECON0	0x110
-#define LPX				(0xff << 0)
-#define HS_PREP				(0xff << 8)
-#define HS_ZERO				(0xff << 16)
-#define HS_TRAIL			(0xff << 24)
+#define LPX				GENMASK(7, 0)
+#define HS_PREP				GENMASK(15, 8)
+#define HS_ZERO				GENMASK(23, 16)
+#define HS_TRAIL			GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON1	0x114
-#define TA_GO				(0xff << 0)
-#define TA_SURE				(0xff << 8)
-#define TA_GET				(0xff << 16)
-#define DA_HS_EXIT			(0xff << 24)
+#define TA_GO				GENMASK(7, 0)
+#define TA_SURE				GENMASK(15, 8)
+#define TA_GET				GENMASK(23, 16)
+#define DA_HS_EXIT			GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON2	0x118
-#define CONT_DET			(0xff << 0)
-#define CLK_ZERO			(0xff << 16)
-#define CLK_TRAIL			(0xff << 24)
+#define CONT_DET			GENMASK(7, 0)
+#define CLK_ZERO			GENMASK(23, 16)
+#define CLK_TRAIL			GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON3	0x11c
-#define CLK_HS_PREP			(0xff << 0)
-#define CLK_HS_POST			(0xff << 8)
-#define CLK_HS_EXIT			(0xff << 16)
+#define CLK_HS_PREP			GENMASK(7, 0)
+#define CLK_HS_POST			GENMASK(15, 8)
+#define CLK_HS_EXIT			GENMASK(23, 16)
 
 #define DSI_VM_CMD_CON		0x130
 #define VM_CMD_EN			BIT(0)
@@ -138,13 +138,14 @@
 #define FORCE_COMMIT			BIT(0)
 #define BYPASS_SHADOW			BIT(1)
 
-#define CONFIG				(0xff << 0)
+/* CMDQ related bits */
+#define CONFIG				GENMASK(7, 0)
 #define SHORT_PACKET			0
 #define LONG_PACKET			2
 #define BTA				BIT(2)
-#define DATA_ID				(0xff << 8)
-#define DATA_0				(0xff << 16)
-#define DATA_1				(0xff << 24)
+#define DATA_ID				GENMASK(15, 8)
+#define DATA_0				GENMASK(23, 16)
+#define DATA_1				GENMASK(31, 24)
 
 #define NS_TO_CYCLE(n, c)    ((n) / (c) + (((n) % (c)) ? 1 : 0))
 
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb 15 00:53:09 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 09:53:09 +0100
Subject: [PATCH v6 2/9] drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
In-Reply-To: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240215085316.56835-3-angelogioacchino.delregno@collabora.com>

The register bits definitions for RGB666 formats are wrong in multiple
ways: first, in the DSI_PS_SEL bits region, the Packed 18-bits RGB666
format is selected with bit 1, while the Loosely Packed one is bit 2,
and second - the definition name "LOOSELY_PS_18BIT_RGB666" is wrong
because the loosely packed format is 24 bits instead!

Either way, functions mtk_dsi_ps_control_vact() and mtk_dsi_ps_control()
do not even agree on the DSI_PS_SEL bit to set in DSI_PSCTRL: one sets
loosely packed (24) on RGB666, the other sets packed (18), and the other
way around for RGB666_PACKED.

Fixing this entire stack of issues is done in one go:
 - Use the correct bit for the Loosely Packed RGB666 definition
 - Rename LOOSELY_PS_18BIT_RGB666 to LOOSELY_PS_24BIT_RGB666
 - Change ps_bpp_mode in mtk_dsi_ps_control_vact() to set:
    - Loosely Packed, 24-bits for MIPI_DSI_FMT_RGB666
    - Packed, 18-bits for MIPI_DSI_FMT_RGB666_PACKED

Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index c66e18006070..8af0afbe9e3d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -71,8 +71,8 @@
 #define DSI_PS_WC			GENMASK(13, 0)
 #define DSI_PS_SEL			GENMASK(17, 16)
 #define PACKED_PS_16BIT_RGB565		(0 << 16)
-#define LOOSELY_PS_18BIT_RGB666		(1 << 16)
-#define PACKED_PS_18BIT_RGB666		(2 << 16)
+#define PACKED_PS_18BIT_RGB666		(1 << 16)
+#define LOOSELY_PS_24BIT_RGB666		(2 << 16)
 #define PACKED_PS_24BIT_RGB888		(3 << 16)
 
 #define DSI_VSA_NL		0x20
@@ -370,10 +370,10 @@ static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
 		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
+		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-		ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;
+		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB565:
 		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
@@ -427,7 +427,7 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
 		dsi_tmp_buf_bpp = 3;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		tmp_reg = LOOSELY_PS_18BIT_RGB666;
+		tmp_reg = LOOSELY_PS_24BIT_RGB666;
 		dsi_tmp_buf_bpp = 3;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb 15 00:53:10 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 09:53:10 +0100
Subject: [PATCH v6 3/9] drm/mediatek: dsi: Cleanup functions mtk_dsi_ps_control{_vact}()
In-Reply-To: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240215085316.56835-4-angelogioacchino.delregno@collabora.com>

Function mtk_dsi_ps_control() is a subset of mtk_dsi_ps_control_vact():
merge the two in one mtk_dsi_ps_control() function by adding one
function parameter `config_vact` which, when true, writes the VACT
related registers.

Reviewed-by: Fei Shao <fshao at chromium.org>
Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 78 ++++++++++--------------------
 1 file changed, 25 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 8af0afbe9e3d..0a83875ec1ba 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -351,40 +351,6 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
 	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
 }
 
-static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
-{
-	struct videomode *vm = &dsi->vm;
-	u32 dsi_buf_bpp, ps_wc;
-	u32 ps_bpp_mode;
-
-	if (dsi->format == MIPI_DSI_FMT_RGB565)
-		dsi_buf_bpp = 2;
-	else
-		dsi_buf_bpp = 3;
-
-	ps_wc = vm->hactive * dsi_buf_bpp;
-	ps_bpp_mode = ps_wc;
-
-	switch (dsi->format) {
-	case MIPI_DSI_FMT_RGB888:
-		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
-		break;
-	case MIPI_DSI_FMT_RGB666:
-		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
-		break;
-	case MIPI_DSI_FMT_RGB666_PACKED:
-		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
-		break;
-	case MIPI_DSI_FMT_RGB565:
-		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
-		break;
-	}
-
-	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
-	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
-	writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
-}
-
 static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 {
 	u32 tmp_reg;
@@ -416,36 +382,42 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 	writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
 }
 
-static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
+static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
 {
-	u32 dsi_tmp_buf_bpp;
-	u32 tmp_reg;
+	struct videomode *vm = &dsi->vm;
+	u32 dsi_buf_bpp, ps_wc;
+	u32 ps_bpp_mode;
+
+	if (dsi->format == MIPI_DSI_FMT_RGB565)
+		dsi_buf_bpp = 2;
+	else
+		dsi_buf_bpp = 3;
+
+	ps_wc = vm->hactive * dsi_buf_bpp;
+	ps_bpp_mode = ps_wc;
 
 	switch (dsi->format) {
+	default:
+		fallthrough;
 	case MIPI_DSI_FMT_RGB888:
-		tmp_reg = PACKED_PS_24BIT_RGB888;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		tmp_reg = LOOSELY_PS_24BIT_RGB666;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-		tmp_reg = PACKED_PS_18BIT_RGB666;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB565:
-		tmp_reg = PACKED_PS_16BIT_RGB565;
-		dsi_tmp_buf_bpp = 2;
-		break;
-	default:
-		tmp_reg = PACKED_PS_24BIT_RGB888;
-		dsi_tmp_buf_bpp = 3;
+		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
 		break;
 	}
 
-	tmp_reg += dsi->vm.hactive * dsi_tmp_buf_bpp & DSI_PS_WC;
-	writel(tmp_reg, dsi->regs + DSI_PSCTRL);
+	if (config_vact) {
+		writel(vm->vactive, dsi->regs + DSI_VACT_NL);
+		writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
+	}
+	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
 }
 
 static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
@@ -521,7 +493,7 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
 	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
 
-	mtk_dsi_ps_control(dsi);
+	mtk_dsi_ps_control(dsi, false);
 }
 
 static void mtk_dsi_start(struct mtk_dsi *dsi)
@@ -666,7 +638,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	mtk_dsi_reset_engine(dsi);
 	mtk_dsi_phy_timconfig(dsi);
 
-	mtk_dsi_ps_control_vact(dsi);
+	mtk_dsi_ps_control(dsi, true);
 	mtk_dsi_set_vm_cmd(dsi);
 	mtk_dsi_config_vdo_timing(dsi);
 	mtk_dsi_set_interrupt_enable(dsi);
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb 15 00:53:11 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 09:53:11 +0100
Subject: [PATCH v6 4/9] drm/mediatek: dsi: Use bitfield macros where useful
In-Reply-To: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240215085316.56835-5-angelogioacchino.delregno@collabora.com>

Instead of open coding bitshifting for various register fields,
use the bitfield macro FIELD_PREP(): this allows to enhance the
human readability, decrease likeliness of mistakes (and register
field overflowing) and also to simplify the code.
The latter is especially seen in mtk_dsi_rxtx_control(), where
it was possible to change a switch to a short for loop and to
also remove the need to check for maximum DSI lanes == 4 thanks
to the FIELD_PREP macro masking the value.

While at it, also add the missing DA_HS_SYNC bitmask, used in
mtk_dsi_phy_timconfig().

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 95 ++++++++++++++++--------------
 1 file changed, 50 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 0a83875ec1ba..a330bb94c44a 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2015 MediaTek Inc.
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/iopoll.h>
@@ -70,16 +71,19 @@
 #define DSI_PSCTRL		0x1c
 #define DSI_PS_WC			GENMASK(13, 0)
 #define DSI_PS_SEL			GENMASK(17, 16)
-#define PACKED_PS_16BIT_RGB565		(0 << 16)
-#define PACKED_PS_18BIT_RGB666		(1 << 16)
-#define LOOSELY_PS_24BIT_RGB666		(2 << 16)
-#define PACKED_PS_24BIT_RGB888		(3 << 16)
+#define PACKED_PS_16BIT_RGB565		0
+#define PACKED_PS_18BIT_RGB666		1
+#define LOOSELY_PS_24BIT_RGB666		2
+#define PACKED_PS_24BIT_RGB888		3
 
 #define DSI_VSA_NL		0x20
 #define DSI_VBP_NL		0x24
 #define DSI_VFP_NL		0x28
 #define DSI_VACT_NL		0x2C
+#define VACT_NL				GENMASK(14, 0)
 #define DSI_SIZE_CON		0x38
+#define DSI_HEIGHT				GENMASK(30, 16)
+#define DSI_WIDTH				GENMASK(14, 0)
 #define DSI_HSA_WC		0x50
 #define DSI_HBP_WC		0x54
 #define DSI_HFP_WC		0x58
@@ -122,6 +126,7 @@
 
 #define DSI_PHY_TIMECON2	0x118
 #define CONT_DET			GENMASK(7, 0)
+#define DA_HS_SYNC			GENMASK(15, 8)
 #define CLK_ZERO			GENMASK(23, 16)
 #define CLK_TRAIL			GENMASK(31, 24)
 
@@ -253,14 +258,23 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
 	timing->clk_hs_zero = timing->clk_hs_trail * 4;
 	timing->clk_hs_exit = 2 * timing->clk_hs_trail;
 
-	timcon0 = timing->lpx | timing->da_hs_prepare << 8 |
-		  timing->da_hs_zero << 16 | timing->da_hs_trail << 24;
-	timcon1 = timing->ta_go | timing->ta_sure << 8 |
-		  timing->ta_get << 16 | timing->da_hs_exit << 24;
-	timcon2 = 1 << 8 | timing->clk_hs_zero << 16 |
-		  timing->clk_hs_trail << 24;
-	timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 |
-		  timing->clk_hs_exit << 16;
+	timcon0 = FIELD_PREP(LPX, timing->lpx) |
+		  FIELD_PREP(HS_PREP, timing->da_hs_prepare) |
+		  FIELD_PREP(HS_ZERO, timing->da_hs_zero) |
+		  FIELD_PREP(HS_TRAIL, timing->da_hs_trail);
+
+	timcon1 = FIELD_PREP(TA_GO, timing->ta_go) |
+		  FIELD_PREP(TA_SURE, timing->ta_sure) |
+		  FIELD_PREP(TA_GET, timing->ta_get) |
+		  FIELD_PREP(DA_HS_EXIT, timing->da_hs_exit);
+
+	timcon2 = FIELD_PREP(DA_HS_SYNC, 1) |
+		  FIELD_PREP(CLK_ZERO, timing->clk_hs_zero) |
+		  FIELD_PREP(CLK_TRAIL, timing->clk_hs_trail);
+
+	timcon3 = FIELD_PREP(CLK_HS_PREP, timing->clk_hs_prepare) |
+		  FIELD_PREP(CLK_HS_POST, timing->clk_hs_post) |
+		  FIELD_PREP(CLK_HS_EXIT, timing->clk_hs_exit);
 
 	writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
 	writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
@@ -353,71 +367,61 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
 
 static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 {
-	u32 tmp_reg;
+	u32 regval, tmp_reg = 0;
+	u8 i;
 
-	switch (dsi->lanes) {
-	case 1:
-		tmp_reg = 1 << 2;
-		break;
-	case 2:
-		tmp_reg = 3 << 2;
-		break;
-	case 3:
-		tmp_reg = 7 << 2;
-		break;
-	case 4:
-		tmp_reg = 0xf << 2;
-		break;
-	default:
-		tmp_reg = 0xf << 2;
-		break;
-	}
+	/* Number of DSI lanes (max 4 lanes), each bit enables one DSI lane. */
+	for (i = 0; i < dsi->lanes; i++)
+		tmp_reg |= BIT(i);
+
+	regval = FIELD_PREP(LANE_NUM, tmp_reg);
 
 	if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
-		tmp_reg |= HSTX_CKLP_EN;
+		regval |= HSTX_CKLP_EN;
 
 	if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
-		tmp_reg |= DIS_EOT;
+		regval |= DIS_EOT;
 
-	writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
+	writel(regval, dsi->regs + DSI_TXRX_CTRL);
 }
 
 static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
 {
-	struct videomode *vm = &dsi->vm;
-	u32 dsi_buf_bpp, ps_wc;
-	u32 ps_bpp_mode;
+	u32 dsi_buf_bpp, ps_val, ps_wc, vact_nl;
 
 	if (dsi->format == MIPI_DSI_FMT_RGB565)
 		dsi_buf_bpp = 2;
 	else
 		dsi_buf_bpp = 3;
 
-	ps_wc = vm->hactive * dsi_buf_bpp;
-	ps_bpp_mode = ps_wc;
+	/* Word count */
+	ps_wc = FIELD_PREP(DSI_PS_WC, dsi->vm.hactive * dsi_buf_bpp);
+	ps_val = ps_wc;
 
+	/* Pixel Stream type */
 	switch (dsi->format) {
 	default:
 		fallthrough;
 	case MIPI_DSI_FMT_RGB888:
-		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_24BIT_RGB888);
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, LOOSELY_PS_24BIT_RGB666);
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_18BIT_RGB666);
 		break;
 	case MIPI_DSI_FMT_RGB565:
-		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
+		ps_val |= FIELD_PREP(DSI_PS_SEL, PACKED_PS_16BIT_RGB565);
 		break;
 	}
 
 	if (config_vact) {
-		writel(vm->vactive, dsi->regs + DSI_VACT_NL);
+		vact_nl = FIELD_PREP(VACT_NL, dsi->vm.vactive);
+		writel(vact_nl, dsi->regs + DSI_VACT_NL);
 		writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
 	}
-	writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
+	writel(ps_val, dsi->regs + DSI_PSCTRL);
 }
 
 static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
@@ -444,7 +448,8 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 	writel(vm->vactive, dsi->regs + DSI_VACT_NL);
 
 	if (dsi->driver_data->has_size_ctl)
-		writel(vm->vactive << 16 | vm->hactive,
+		writel(FIELD_PREP(DSI_HEIGHT, vm->vactive) |
+		       FIELD_PREP(DSI_WIDTH, vm->hactive),
 		       dsi->regs + DSI_SIZE_CON);
 
 	horizontal_sync_active_byte = (vm->hsync_len * dsi_tmp_buf_bpp - 10);
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb 15 00:53:12 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 09:53:12 +0100
Subject: [PATCH v6 5/9] drm/mediatek: dsi: Replace open-coded instance of HZ_PER_MHZ
In-Reply-To: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240215085316.56835-6-angelogioacchino.delregno@collabora.com>

In mtk_dsi_phy_timconfig(), we're dividing the `data_rate` variable,
expressed in Hz to retrieve a value in MHz: instead of open-coding,
use the HZ_PER_MHZ definition, available in linux/units.h.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index a330bb94c44a..52758cab0abf 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -13,6 +13,7 @@
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
+#include <linux/units.h>
 
 #include <video/mipi_display.h>
 #include <video/videomode.h>
@@ -238,7 +239,7 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, u32 mask, u32 data)
 static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
 {
 	u32 timcon0, timcon1, timcon2, timcon3;
-	u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, 1000000);
+	u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, HZ_PER_MHZ);
 	struct mtk_phy_timing *timing = &dsi->phy_timing;
 
 	timing->lpx = (60 * data_rate_mhz / (8 * 1000)) + 1;
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb 15 00:53:13 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 09:53:13 +0100
Subject: [PATCH v6 6/9] drm/mediatek: dsi: Register DSI host after acquiring clocks and PHY
In-Reply-To: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240215085316.56835-7-angelogioacchino.delregno@collabora.com>

Registering the dsi host with its ops before getting dsi->regs is
simply wrong: even though there's nothing (for now) asynchronously
calling those ops before the end of the probe function, installing
ops that are using iospace(s) and clocks before even initializing
those is too fragile.

Register the DSI host after getting clocks, iospace and PHY.
This wil also allow to simplify the error paths in a later commit.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 52758cab0abf..b3dd6251d611 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1114,14 +1114,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	if (!dsi)
 		return -ENOMEM;
 
-	dsi->host.ops = &mtk_dsi_ops;
-	dsi->host.dev = dev;
-	ret = mipi_dsi_host_register(&dsi->host);
-	if (ret < 0) {
-		dev_err(dev, "failed to register DSI host: %d\n", ret);
-		return ret;
-	}
-
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
@@ -1130,7 +1122,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 
 		if (ret != -EPROBE_DEFER)
 			dev_err(dev, "Failed to get engine clock: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	dsi->digital_clk = devm_clk_get(dev, "digital");
@@ -1139,14 +1131,14 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 
 		if (ret != -EPROBE_DEFER)
 			dev_err(dev, "Failed to get digital clock: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	dsi->hs_clk = devm_clk_get(dev, "hs");
 	if (IS_ERR(dsi->hs_clk)) {
 		ret = PTR_ERR(dsi->hs_clk);
 		dev_err(dev, "Failed to get hs clock: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1154,20 +1146,28 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	if (IS_ERR(dsi->regs)) {
 		ret = PTR_ERR(dsi->regs);
 		dev_err(dev, "Failed to ioremap memory: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	dsi->phy = devm_phy_get(dev, "dphy");
 	if (IS_ERR(dsi->phy)) {
 		ret = PTR_ERR(dsi->phy);
 		dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
-		goto err_unregister_host;
+		return ret;
 	}
 
 	irq_num = platform_get_irq(pdev, 0);
 	if (irq_num < 0) {
 		ret = irq_num;
-		goto err_unregister_host;
+		return ret;
+	}
+
+	dsi->host.ops = &mtk_dsi_ops;
+	dsi->host.dev = dev;
+	ret = mipi_dsi_host_register(&dsi->host);
+	if (ret < 0) {
+		dev_err(dev, "failed to register DSI host: %d\n", ret);
+		return ret;
 	}
 
 	ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq,
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb 15 00:53:14 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 09:53:14 +0100
Subject: [PATCH v6 7/9] drm/mediatek: dsi: Simplify with dev_err_probe and remove gotos
In-Reply-To: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240215085316.56835-8-angelogioacchino.delregno@collabora.com>

Most of the functions that are called in the probe callback are
devm managed, or all but mipi_dsi_host_register(): simplify the probe
function's error paths with dev_err_probe() and remove the lonely
instance of `goto err_unregister_host` by just directly calling the
mipi_dsi_host_unregister() function in the devm_request_irq() error
path, allowing to also remove the same label.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 60 +++++++++---------------------
 1 file changed, 18 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index b3dd6251d611..195ff4dfc3a3 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1117,64 +1117,44 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
-	if (IS_ERR(dsi->engine_clk)) {
-		ret = PTR_ERR(dsi->engine_clk);
+	if (IS_ERR(dsi->engine_clk))
+		return dev_err_probe(dev, PTR_ERR(dsi->engine_clk),
+				     "Failed to get engine clock\n");
 
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get engine clock: %d\n", ret);
-		return ret;
-	}
 
 	dsi->digital_clk = devm_clk_get(dev, "digital");
-	if (IS_ERR(dsi->digital_clk)) {
-		ret = PTR_ERR(dsi->digital_clk);
-
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get digital clock: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->digital_clk))
+		return dev_err_probe(dev, PTR_ERR(dsi->digital_clk),
+				     "Failed to get digital clock\n");
 
 	dsi->hs_clk = devm_clk_get(dev, "hs");
-	if (IS_ERR(dsi->hs_clk)) {
-		ret = PTR_ERR(dsi->hs_clk);
-		dev_err(dev, "Failed to get hs clock: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->hs_clk))
+		return dev_err_probe(dev, PTR_ERR(dsi->hs_clk), "Failed to get hs clock\n");
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dsi->regs = devm_ioremap_resource(dev, regs);
-	if (IS_ERR(dsi->regs)) {
-		ret = PTR_ERR(dsi->regs);
-		dev_err(dev, "Failed to ioremap memory: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->regs))
+		return dev_err_probe(dev, PTR_ERR(dsi->regs), "Failed to ioremap memory\n");
 
 	dsi->phy = devm_phy_get(dev, "dphy");
-	if (IS_ERR(dsi->phy)) {
-		ret = PTR_ERR(dsi->phy);
-		dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(dsi->phy))
+		return dev_err_probe(dev, PTR_ERR(dsi->phy), "Failed to get MIPI-DPHY\n");
 
 	irq_num = platform_get_irq(pdev, 0);
-	if (irq_num < 0) {
-		ret = irq_num;
-		return ret;
-	}
+	if (irq_num < 0)
+		return irq_num;
 
 	dsi->host.ops = &mtk_dsi_ops;
 	dsi->host.dev = dev;
 	ret = mipi_dsi_host_register(&dsi->host);
-	if (ret < 0) {
-		dev_err(dev, "failed to register DSI host: %d\n", ret);
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to register DSI host\n");
 
 	ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq,
 			       IRQF_TRIGGER_NONE, dev_name(&pdev->dev), dsi);
 	if (ret) {
-		dev_err(&pdev->dev, "failed to request mediatek dsi irq\n");
-		goto err_unregister_host;
+		mipi_dsi_host_unregister(&dsi->host);
+		return dev_err_probe(&pdev->dev, ret, "Failed to request DSI irq\n");
 	}
 
 	init_waitqueue_head(&dsi->irq_wait_queue);
@@ -1186,10 +1166,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
 	return 0;
-
-err_unregister_host:
-	mipi_dsi_host_unregister(&dsi->host);
-	return ret;
 }
 
 static void mtk_dsi_remove(struct platform_device *pdev)
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb 15 00:53:15 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 09:53:15 +0100
Subject: [PATCH v6 8/9] drm/mediatek: dsi: Compress of_device_id entries and add sentinel
In-Reply-To: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240215085316.56835-9-angelogioacchino.delregno@collabora.com>

All entries fit in 82 columns, which is acceptable: compress all of
the mtk_dsi_of_match[] entries to a single line for each.

While at it, also add the usual sentinel comment to the last entry.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 195ff4dfc3a3..b644505de98a 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1204,17 +1204,12 @@ static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = {
 };
 
 static const struct of_device_id mtk_dsi_of_match[] = {
-	{ .compatible = "mediatek,mt2701-dsi",
-	  .data = &mt2701_dsi_driver_data },
-	{ .compatible = "mediatek,mt8173-dsi",
-	  .data = &mt8173_dsi_driver_data },
-	{ .compatible = "mediatek,mt8183-dsi",
-	  .data = &mt8183_dsi_driver_data },
-	{ .compatible = "mediatek,mt8186-dsi",
-	  .data = &mt8186_dsi_driver_data },
-	{ .compatible = "mediatek,mt8188-dsi",
-	  .data = &mt8188_dsi_driver_data },
-	{ },
+	{ .compatible = "mediatek,mt2701-dsi", .data = &mt2701_dsi_driver_data },
+	{ .compatible = "mediatek,mt8173-dsi", .data = &mt8173_dsi_driver_data },
+	{ .compatible = "mediatek,mt8183-dsi", .data = &mt8183_dsi_driver_data },
+	{ .compatible = "mediatek,mt8186-dsi", .data = &mt8186_dsi_driver_data },
+	{ .compatible = "mediatek,mt8188-dsi", .data = &mt8188_dsi_driver_data },
+	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mtk_dsi_of_match);
 
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Thu Feb 15 00:53:16 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 09:53:16 +0100
Subject: [PATCH v6 9/9] drm/mediatek: dsi: Use mipi_dsi_pixel_format_to_bpp() helper function
In-Reply-To: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240215085316.56835-10-angelogioacchino.delregno@collabora.com>

Instead of open coding, use the mipi_dsi_pixel_format_to_bpp() helper
function from drm_mipi_dsi.h in mtk_dsi_poweron() and for validation
in mtk_dsi_bridge_mode_valid().

Note that this function changes the behavior of this driver: previously,
in case of unknown formats, it would (wrongly) assume that it should
account for a 24-bits format - now it will return an error and refuse
to set clocks and/or enable the DSI.

This is done because setting the wrong data rate will only produce a
garbage output that the display will misinterpret both because this
driver doesn't actually provide any extra-spec format support and/or
because the data rate (hence, the HS clock) will be wrong.

Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index b644505de98a..9501f4019199 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -598,19 +598,12 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	if (++dsi->refcount != 1)
 		return 0;
 
-	switch (dsi->format) {
-	case MIPI_DSI_FMT_RGB565:
-		bit_per_pixel = 16;
-		break;
-	case MIPI_DSI_FMT_RGB666_PACKED:
-		bit_per_pixel = 18;
-		break;
-	case MIPI_DSI_FMT_RGB666:
-	case MIPI_DSI_FMT_RGB888:
-	default:
-		bit_per_pixel = 24;
-		break;
+	ret = mipi_dsi_pixel_format_to_bpp(dsi->format);
+	if (ret < 0) {
+		dev_err(dev, "Unknown MIPI DSI format %d\n", dsi->format);
+		return ret;
 	}
+	bit_per_pixel = ret;
 
 	dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock * bit_per_pixel,
 					  dsi->lanes);
@@ -793,12 +786,11 @@ mtk_dsi_bridge_mode_valid(struct drm_bridge *bridge,
 			  const struct drm_display_mode *mode)
 {
 	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
-	u32 bpp;
+	int bpp;
 
-	if (dsi->format == MIPI_DSI_FMT_RGB565)
-		bpp = 16;
-	else
-		bpp = 24;
+	bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+	if (bpp < 0)
+		return MODE_ERROR;
 
 	if (mode->clock * bpp / dsi->lanes > 1500000)
 		return MODE_CLOCK_HIGH;
-- 
2.43.0



From krzk at kernel.org  Thu Feb 15 00:54:37 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 09:54:37 +0100
Subject: [PATCH RFC v3 1/4] dt-bindings: spmi: Add PMIC ARB v7 schema
In-Reply-To: <20240214-spmi-multi-master-support-v3-1-0bae0ef04faf@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-1-0bae0ef04faf@linaro.org>
Message-ID: <ea9d31c4-e5c4-4869-8bf9-caef3dd32829@kernel.org>

On 14/02/2024 22:13, Abel Vesa wrote:
> Add dedicated schema for PMIC ARB v7 as it allows multiple
> buses by declaring them as child nodes. These child nodes
> will follow the generic spmi bus bindings.
> 
> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> ---

Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline), work on fork of kernel
(don't, instead use mainline) or you ignore some maintainers (really
don't). Just use b4 and everything should be fine, although remember
about `b4 prep --auto-to-cc` if you added new patches to the patchset.

You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time, thus I will skip this patch entirely till you follow
the process allowing the patch to be tested.

Please kindly resend and include all necessary To/Cc entries.


Best regards,
Krzysztof



From vaishnav.a at ti.com  Thu Feb 15 00:55:09 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 15 Feb 2024 14:25:09 +0530
Subject: [PATCH v4 0/9] Add CSI2RX capture support on TI J7 platforms
Message-ID: <20240215085518.552692-1-vaishnav.a@ti.com>

Hi,

This series adds support for CSI2RX capture support on J7 platforms,
series was tested for CSI2RX capture on OV5640 sensor and RPI camera
v2 IMX219 sensor on J721e Common Processor Board, J721E Starter kit,
J721S2 Common Processor Board, AM68 Starter Kit, J784s4 EVM and AM69
Starter kit.

V1: https://lore.kernel.org/all/20240129132742.1189783-1-vaishnav.a at ti.com/
V2: https://lore.kernel.org/all/20240208084254.295289-1-vaishnav.a at ti.com/
V3: https://lore.kernel.org/all/20240208123233.391115-1-vaishnav.a at ti.com/

Changelog:
V3->V4:
  * Add additional port information in overlays to fix DTC warning:
	Warning (graph_child_address): graph node has single child node,
	#address-cells/#size-cells are not necessary  
V2->V3:
  * Fix order of properties in patch 6/7/8 as per dts coding style.
V1->V2:
  * Address feedback from Jai and Andrew
    * Rename overlays to indicate first platform supported/dual camera.
    * Add missed build test.
    * Add board schematics for all commit messages.

Test logs:
J721E EVM OV5640 - https://gist.github.com/vaishnavachath/b08521386cfbe1939facf39b8b2d796b
J721S2 EVM OV5640 - https://gist.github.com/vaishnavachath/1b0d60da6b6464cf12334cd5e161a79b
J784s4 EVM OV5640 - https://gist.github.com/vaishnavachath/02b70df94d2d41662eff99f4ce966d67
TDA4VM SK IMX219 - https://gist.github.com/vaishnavachath/64fc6edd6cc060027812bebd6573df07
AM68 SK IMX219 - https://gist.github.com/vaishnavachath/d522254ff5e797bc853e0706fbea932a
AM69 SK IMX219 - https://gist.github.com/vaishnavachath/8dbd960cc89d691886df371c53aac399

Only a single set of overlays for dual RPI IMX219 is included in the series
for reference and other overlays to test OV5640 can be found here:
https://gist.github.com/vaishnavachath/d0a052106892fe9f3096733931e9ad5f

Vaishnav Achath (9):
  arm64: dts: ti: k3-j721s2-common-proc-board: Enable camera peripherals
  arm64: dts: ti: k3-j784s4-evm: Enable camera peripherals
  arm64: dts: ti: k3-am68-sk-base-board: Enable camera peripherals
  arm64: dts: ti: k3-am69-sk: Enable camera peripherals
  arm64: dts: ti: k3-j721e-sk: Model CSI2RX connector mux
  arm64: dts: ti: k3-j721e-main: Add CSI2RX capture nodes
  arm64: dts: ti: k3-j721s2-main: Add CSI2RX capture nodes
  arm64: dts: ti: k3-j784s4-main: Add CSI2RX capture nodes
  arm64: dts: ti: k3-j721e-sk: Add overlay for IMX219

 arch/arm64/boot/dts/ti/Makefile               |  13 ++
 .../boot/dts/ti/k3-am68-sk-base-board.dts     |  50 +++++
 arch/arm64/boot/dts/ti/k3-am69-sk.dts         |  51 +++++
 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi     | 122 ++++++++++++
 .../dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso  | 165 ++++++++++++++++
 arch/arm64/boot/dts/ti/k3-j721e-sk.dts        |  19 +-
 .../dts/ti/k3-j721s2-common-proc-board.dts    |  25 +++
 arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi    | 123 +++++++++++-
 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts      |  25 +++
 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi    | 183 +++++++++++++++++-
 10 files changed, 772 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso

-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb 15 00:55:10 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 15 Feb 2024 14:25:10 +0530
Subject: [PATCH v4 1/9] arm64: dts: ti: k3-j721s2-common-proc-board: Enable camera peripherals
In-Reply-To: <20240215085518.552692-1-vaishnav.a@ti.com>
References: <20240215085518.552692-1-vaishnav.a@ti.com>
Message-ID: <20240215085518.552692-2-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On J721S2 Common Processor Board,
this is routed to I2C-5, so enable the instance and the TCA6408
GPIO expander on the bus.

Common Processor Board schematics: https://www.ti.com/lit/zip/sprr411
J721S2 SoM schematics: https://www.ti.com/lit/zip/sprr439

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
Reviewed-by: Jai Luthra <j-luthra at ti.com>
---

V1->V2: Update commit message with schematics.

 .../dts/ti/k3-j721s2-common-proc-board.dts    | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
index 361365bb5523..5631735c9b7a 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -147,6 +147,13 @@ J721S2_IOPAD(0x060, PIN_INPUT_PULLUP, 13) /* (AC27) MCASP2_AXR1.I2C3_SDA */
 		>;
 	};
 
+	main_i2c5_pins_default: main-i2c5-default-pins {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x01c, PIN_INPUT, 8) /* (Y24) MCAN15_TX.I2C5_SCL */
+			J721S2_IOPAD(0x018, PIN_INPUT, 8) /* (W23) MCAN14_RX.I2C5_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		pinctrl-single,pins = <
 			J721S2_IOPAD(0x104, PIN_INPUT, 0) /* (P23) MMC1_CLK */
@@ -356,6 +363,24 @@ exp2: gpio at 22 {
 	};
 };
 
+&main_i2c5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c5_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	exp5: gpio at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI2_EXP_RSTZ", "CSI2_EXP_A_GPIO0",
+				  "CSI2_EXP_A_GPIO1", "CSI2_EXP_A_GPIO2",
+				  "CSI2_EXP_B_GPIO1", "CSI2_EXP_B_GPIO2",
+				  "CSI2_EXP_B_GPIO3", "CSI2_EXP_B_GPIO4";
+	};
+};
+
 &main_sdhci0 {
 	/* eMMC */
 	status = "okay";
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb 15 00:55:11 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 15 Feb 2024 14:25:11 +0530
Subject: [PATCH v4 2/9] arm64: dts: ti: k3-j784s4-evm: Enable camera peripherals
In-Reply-To: <20240215085518.552692-1-vaishnav.a@ti.com>
References: <20240215085518.552692-1-vaishnav.a@ti.com>
Message-ID: <20240215085518.552692-3-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On J784S4 EVM, this is routed
to I2C-5, so enable the instance and the TCA6408 GPIO expander
on the bus.

J784S4 EVM schematics: https://www.ti.com/lit/zip/sprr458

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
Reviewed-by: Jai Luthra <j-luthra at ti.com>
---

V1->V2: Update commit message with schematics.

 arch/arm64/boot/dts/ti/k3-j784s4-evm.dts | 25 ++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
index 57e7cb8ea2b8..bb2558b68381 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -297,6 +297,13 @@ J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */
 		>;
 	};
 
+	main_i2c5_pins_default: main-i2c5-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x01c, PIN_INPUT, 8) /* (AG34) MCAN15_TX.I2C5_SCL */
+			J784S4_IOPAD(0x018, PIN_INPUT, 8) /* (AK36) MCAN14_RX.I2C5_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
@@ -761,6 +768,24 @@ exp2: gpio at 22 {
 	};
 };
 
+&main_i2c5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c5_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	exp5: gpio at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI2_EXP_RSTZ", "CSI2_EXP_A_GPIO0",
+				  "CSI2_EXP_A_GPIO1", "CSI2_EXP_A_GPIO3",
+				  "CSI2_EXP_B_GPIO1", "CSI2_EXP_B_GPIO2",
+				  "CSI2_EXP_B_GPIO3", "CSI2_EXP_B_GPIO4";
+	};
+};
+
 &main_sdhci0 {
 	bootph-all;
 	/* eMMC */
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb 15 00:55:12 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 15 Feb 2024 14:25:12 +0530
Subject: [PATCH v4 3/9] arm64: dts: ti: k3-am68-sk-base-board: Enable camera peripherals
In-Reply-To: <20240215085518.552692-1-vaishnav.a@ti.com>
References: <20240215085518.552692-1-vaishnav.a@ti.com>
Message-ID: <20240215085518.552692-4-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On AM68 Starter Kit, this is routed
to I2C-1, so enable the instance and the TCA9543 I2C switch on the bus.

AM68 SK schematics: https://www.ti.com/lit/zip/sprr463

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
Reviewed-by: Jai Luthra <j-luthra at ti.com>
---

V1->V2: Update commit message with schematics.

 .../boot/dts/ti/k3-am68-sk-base-board.dts     | 50 +++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
index f48155dd16a3..d743f023cdd9 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts
@@ -169,6 +169,13 @@ tfp410_out: endpoint {
 			};
 		};
 	};
+
+	csi_mux: mux-controller {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&exp3 1 GPIO_ACTIVE_HIGH>;
+		idle-state = <0>;
+	};
 };
 
 &main_pmx0 {
@@ -186,6 +193,13 @@ J721S2_IOPAD(0x0e4, PIN_INPUT, 0) /* (AE24) I2C0_SDA */
 		>;
 	};
 
+	main_i2c1_pins_default: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			J721S2_IOPAD(0x0ac, PIN_INPUT, 13) /* (AC25) MCASP0_AXR15.I2C1_SCL */
+			J721S2_IOPAD(0x0b0, PIN_INPUT, 13) /* (AD26) MCASP1_AXR3.I2C1_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		pinctrl-single,pins = <
 			J721S2_IOPAD(0x104, PIN_INPUT, 0) /* (P23) MMC1_CLK */
@@ -431,6 +445,42 @@ exp1: gpio at 21 {
 	};
 };
 
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	status = "okay";
+
+	exp3: gpio at 20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI_VIO_SEL", "CSI_SEL_FPC_EXPn",
+				  "IO_EXP_CSI2_EXP_RSTz","CSI0_B_GPIO1",
+				  "CSI1_B_GPIO1";
+	};
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		cam0_i2c: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		cam1_i2c: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+	};
+};
+
 &main_i2c4 {
 	status = "okay";
 	pinctrl-names = "default";
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb 15 00:55:13 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 15 Feb 2024 14:25:13 +0530
Subject: [PATCH v4 4/9] arm64: dts: ti: k3-am69-sk: Enable camera peripherals
In-Reply-To: <20240215085518.552692-1-vaishnav.a@ti.com>
References: <20240215085518.552692-1-vaishnav.a@ti.com>
Message-ID: <20240215085518.552692-5-vaishnav.a@ti.com>

CSI cameras are controlled using I2C. On AM69 Starter Kit, this is routed
to I2C-1, so enable the instance, TCA9543 I2C switch and the TCA6408
GPIO expander on the bus. AM69 SK has the CSI2RX routed to a MIPI CSI
connector and to 22-pin RPi camera connector through an analog mux with
GPIO control, model that so that an overlay can control the mux state
according to connected cameras.

AM69 SK schematics: https://www.ti.com/lit/zip/sprr466

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
Reviewed-by: Jai Luthra <j-luthra at ti.com>
---

V1->V2: Update commit message with schematics.

 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 51 +++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 5f0a43a69333..46cf90bb3eb8 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -322,6 +322,14 @@ tfp410_out: endpoint {
 			};
 		};
 	};
+
+	csi_mux: mux-controller {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&exp2 1 GPIO_ACTIVE_HIGH>;
+		idle-state = <0>;
+	};
+
 };
 
 &main_pmx0 {
@@ -341,6 +349,13 @@ J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */
 		>;
 	};
 
+	main_i2c1_pins_default: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0ac, PIN_INPUT_PULLUP, 13) /* (AE34) MCASP0_AXR15.I2C1_SCL */
+			J784S4_IOPAD(0x0b0, PIN_INPUT_PULLUP, 13) /* (AL33) MCASP1_AXR3.I2C1_SDA */
+		>;
+	};
+
 	main_mmc1_pins_default: main-mmc1-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
@@ -775,6 +790,42 @@ exp1: gpio at 21 {
 	};
 };
 
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	exp2: gpio at 21 {
+		compatible = "ti,tca6408";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names = "CSI_VIO_SEL", "CSI_MUX_SEL_2", "CSI2_RSTz",
+				  "IO_EXP_CAM0_GPIO1", "IO_EXP_CAM1_GPIO1";
+	};
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		cam0_i2c: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		cam1_i2c: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+	};
+};
+
 &main_sdhci0 {
 	bootph-all;
 	/* eMMC */
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb 15 00:55:14 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 15 Feb 2024 14:25:14 +0530
Subject: [PATCH v4 5/9] arm64: dts: ti: k3-j721e-sk: Model CSI2RX connector mux
In-Reply-To: <20240215085518.552692-1-vaishnav.a@ti.com>
References: <20240215085518.552692-1-vaishnav.a@ti.com>
Message-ID: <20240215085518.552692-6-vaishnav.a@ti.com>

J721E SK has the CSI2RX routed to a MIPI CSI connector and to 15-pin
RPi camera connector through an analog mux with GPIO control, model that
so that an overlay can control the mux state according to connected
cameras. Also provide labels to the I2C mux bus instances so that a
generic overlay can be used across multiple platforms.

J721E SK schematics: https://www.ti.com/lit/zip/sprr438

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
Reviewed-by: Jai Luthra <j-luthra at ti.com>
---

V1->V2: Update commit message with schematics.

 arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
index 6950b1ff124f..5dbc85bc5038 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
@@ -286,6 +286,15 @@ tfp410_out: endpoint {
 			};
 		};
 	};
+
+	csi_mux: mux-controller {
+		compatible = "gpio-mux";
+		#mux-state-cells = <1>;
+		mux-gpios = <&main_gpio0 88 GPIO_ACTIVE_HIGH>;
+		idle-state = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&main_csi_mux_sel_pins_default>;
+	};
 };
 
 &main_pmx0 {
@@ -352,6 +361,12 @@ J721E_IOPAD(0x214, PIN_OUTPUT, 4) /* (V4) MCAN1_TX.USB1_DRVVBUS */
 		>;
 	};
 
+	main_csi_mux_sel_pins_default: main-csi-mux-sel-default-pins {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x164, PIN_OUTPUT, 7) /* (V29) RGMII5_TD2 */
+		>;
+	};
+
 	dp0_pins_default: dp0-default-pins {
 		pinctrl-single,pins = <
 			J721E_IOPAD(0x1c4, PIN_INPUT, 5) /* SPI0_CS1.DP0_HPD */
@@ -858,14 +873,14 @@ i2c-mux at 70 {
 		reg = <0x70>;
 
 		/* CSI0 I2C */
-		i2c at 0 {
+		cam0_i2c: i2c at 0 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0>;
 		};
 
 		/* CSI1 I2C */
-		i2c at 1 {
+		cam1_i2c: i2c at 1 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <1>;
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb 15 00:55:15 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 15 Feb 2024 14:25:15 +0530
Subject: [PATCH v4 6/9] arm64: dts: ti: k3-j721e-main: Add CSI2RX capture nodes
In-Reply-To: <20240215085518.552692-1-vaishnav.a@ti.com>
References: <20240215085518.552692-1-vaishnav.a@ti.com>
Message-ID: <20240215085518.552692-7-vaishnav.a@ti.com>

J721E has two CSI2RX capture subsystem featuring Cadence CSI2RX,
DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
keep them disabled by default.

J721E TRM (Section 12.7 Camera Subsystem):
	https://www.ti.com/lit/zip/spruil1

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
Reviewed-by: Jai Luthra <j-luthra at ti.com>
---

V2->V3: Fix order of properties as per dts coding style.
V1->V2: Update commit message with TRM.

 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 122 ++++++++++++++++++++++
 1 file changed, 122 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index 062a6fca5a31..841752d20de1 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -572,6 +572,128 @@ main_timerio_output: pinctrl at 104280 {
 		pinctrl-single,function-mask = <0x0000001f>;
 	};
 
+	ti_csi2rx0: ticsi2rx at 4500000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x0 0x4500000 0x0 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_udmap 0x4940>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 26 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 4504000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x0 0x4504000 0x0 0x1000>;
+			clocks = <&k3_clks 26 2>, <&k3_clks 26 0>, <&k3_clks 26 2>,
+				<&k3_clks 26 2>, <&k3_clks 26 3>, <&k3_clks 26 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx1: ticsi2rx at 4510000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x0 0x4510000 0x0 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_udmap 0x4960>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 27 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx1: csi-bridge at 4514000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x0 0x4514000 0x0 0x1000>;
+			clocks = <&k3_clks 27 2>, <&k3_clks 27 0>, <&k3_clks 27 2>,
+				 <&k3_clks 27 2>, <&k3_clks 27 3>, <&k3_clks 27 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				      "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy1>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi1_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi1_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi1_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi1_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi1_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 4580000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x0 0x4580000 0x0 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy1: phy at 4590000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x0 0x4590000 0x0 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 148 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
 	serdes_wiz0: wiz at 5000000 {
 		compatible = "ti,j721e-wiz-16g";
 		#address-cells = <1>;
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb 15 00:55:16 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 15 Feb 2024 14:25:16 +0530
Subject: [PATCH v4 7/9] arm64: dts: ti: k3-j721s2-main: Add CSI2RX capture nodes
In-Reply-To: <20240215085518.552692-1-vaishnav.a@ti.com>
References: <20240215085518.552692-1-vaishnav.a@ti.com>
Message-ID: <20240215085518.552692-8-vaishnav.a@ti.com>

J721S2 has two CSI2RX capture subsystem featuring Cadence CSI2RX,
DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
keep them disabled by default. J721S2 uses a dedicated BCDMA instance
for CSI-RX traffic, so enable that as well.

J721S2 TRM (Section 12.7 Camera Subsystem):
	https://www.ti.com/lit/zip/spruj28

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
Reviewed-by: Jai Luthra <j-luthra at ti.com>
---

V2->V3: Fix order of properties as per dts coding style.
V1->V2: Update commit message with TRM.

 arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi | 123 ++++++++++++++++++++-
 1 file changed, 122 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
index dcaa4da0d678..9063aa609993 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -1122,7 +1122,6 @@ main_bcdma_csi: dma-controller at 311a0000 {
 			ti,sci-dev-id = <225>;
 			ti,sci-rm-range-rchan = <0x21>;
 			ti,sci-rm-range-tchan = <0x22>;
-			status = "disabled";
 		};
 
 		cpts at 310d0000 {
@@ -1233,6 +1232,128 @@ usb0: usb at 6000000 {
 		};
 	};
 
+	ti_csi2rx0: ticsi2rx at 4500000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x04500000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x4940 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 38 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 4504000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04504000 0x00 0x1000>;
+			clocks = <&k3_clks 38 3>, <&k3_clks 38 1>, <&k3_clks 38 3>,
+				<&k3_clks 38 3>, <&k3_clks 38 4>, <&k3_clks 38 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx1: ticsi2rx at 4510000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x04510000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x4960 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx1: csi-bridge at 4514000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04514000 0x00 0x1000>;
+			clocks = <&k3_clks 39 3>, <&k3_clks 39 1>, <&k3_clks 39 3>,
+				<&k3_clks 39 3>, <&k3_clks 39 4>, <&k3_clks 39 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy1>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi1_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi1_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi1_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi1_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi1_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 4580000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04580000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy1: phy at 4590000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04590000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
 	serdes_wiz0: wiz at 5060000 {
 		compatible = "ti,j721s2-wiz-10g";
 		#address-cells = <1>;
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb 15 00:55:17 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 15 Feb 2024 14:25:17 +0530
Subject: [PATCH v4 8/9] arm64: dts: ti: k3-j784s4-main: Add CSI2RX capture nodes
In-Reply-To: <20240215085518.552692-1-vaishnav.a@ti.com>
References: <20240215085518.552692-1-vaishnav.a@ti.com>
Message-ID: <20240215085518.552692-9-vaishnav.a@ti.com>

J784S4 has three CSI2RX capture subsystem featuring Cadence CSI2RX,
DPHY and TI's pixel grabbing wrapper. Add nodes for the same and
keep them disabled by default. J784S4 uses a dedicated BCDMA instance
for CSI-RX traffic, so enable that as well.

J784S4 TRM (Section 12.7 Camera Subsystem):
	https://www.ti.com/lit/zip/spruj52

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
Reviewed-by: Jai Luthra <j-luthra at ti.com>
---

V2->V3: Fix order of properties as per dts coding style.
V1->V2: Update commit message with TRM.

 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 183 ++++++++++++++++++++-
 1 file changed, 182 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
index 3cb964982792..42e4ca1d0b65 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -662,6 +662,188 @@ main_i2c6: i2c at 2060000 {
 		status = "disabled";
 	};
 
+	ti_csi2rx0: ticsi2rx at 4500000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x04500000 0x00 0x00001000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x4940 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 72 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 4504000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04504000 0x00 0x00001000>;
+			clocks = <&k3_clks 72 2>, <&k3_clks 72 0>, <&k3_clks 72 2>,
+				<&k3_clks 72 2>, <&k3_clks 72 3>, <&k3_clks 72 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx1: ticsi2rx at 4510000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x04510000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x4960 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 73 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx1: csi-bridge at 4514000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04514000 0x00 0x00001000>;
+			clocks = <&k3_clks 73 2>, <&k3_clks 73 0>, <&k3_clks 73 2>,
+				<&k3_clks 73 2>, <&k3_clks 73 3>, <&k3_clks 73 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy1>;
+			phy-names = "dphy";
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi1_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi1_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi1_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi1_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi1_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	ti_csi2rx2: ticsi2rx at 4520000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x04520000 0x00 0x00001000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x4980 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 74 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx2: csi-bridge at 4524000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x04524000 0x00 0x00001000>;
+			clocks = <&k3_clks 74 2>, <&k3_clks 74 0>, <&k3_clks 74 2>,
+				<&k3_clks 74 2>, <&k3_clks 74 3>, <&k3_clks 74 3>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy2>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi2_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi2_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi2_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi2_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi2_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 4580000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04580000 0x00 0x00001100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 212 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy1: phy at 4590000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x04590000 0x00 0x00001100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 213 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
+	dphy2: phy at 45a0000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x045a0000 0x00 0x00001100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 214 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
+
 	main_sdhci0: mmc at 4f80000 {
 		compatible = "ti,j721e-sdhci-8bit";
 		reg = <0x00 0x04f80000 0x00 0x1000>,
@@ -1224,7 +1406,6 @@ main_bcdma_csi: dma-controller at 311a0000 {
 			ti,sci-dev-id = <281>;
 			ti,sci-rm-range-rchan = <0x21>;
 			ti,sci-rm-range-tchan = <0x22>;
-			status = "disabled";
 		};
 
 		cpts at 310d0000 {
-- 
2.34.1



From vaishnav.a at ti.com  Thu Feb 15 00:55:18 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Thu, 15 Feb 2024 14:25:18 +0530
Subject: [PATCH v4 9/9] arm64: dts: ti: k3-j721e-sk: Add overlay for IMX219
In-Reply-To: <20240215085518.552692-1-vaishnav.a@ti.com>
References: <20240215085518.552692-1-vaishnav.a@ti.com>
Message-ID: <20240215085518.552692-10-vaishnav.a@ti.com>

RPi v2 Camera (IMX219) is an 8MP camera that can be used with SK-AM69,
J721E SK, and AM68 SK through the 22-pin CSI-RX connector.

Add a reference overlay for dual IMX219 RPI camera v2 modules
which can be used across AM68 SK, AM69 SK, TDA4VM SK boards
that have a 15/22-pin FFC connector. Also enable build testing
and symbols for all the three platforms.

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
Reviewed-by: Jai Luthra <j-luthra at ti.com>
---

V3->V4:
* Add additional port information in overlays to fix DTC warning:
	Warning (graph_child_address): graph node has single child node,
	#address-cells/#size-cells are not necessary 

V1->V2:
 * Rename overlays to indicate first platform (j721e-sk) supported
   and dual camera.
 * Add missed build test, fix missing newline.

 arch/arm64/boot/dts/ti/Makefile               |  13 ++
 .../dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso  | 165 ++++++++++++++++++
 2 files changed, 178 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 4a570dffb638..e019efd3ce94 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -69,6 +69,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi-exp-board.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-dual-imx219.dtbo
 
 # Boards with J721s2 SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board.dtb
@@ -106,8 +107,14 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
+k3-am68-sk-base-board-csi2-dual-imx219-dtbs := k3-am68-sk-base-board.dtb \
+	k3-j721e-sk-csi2-dual-imx219.dtbo
+k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
+	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
 	k3-j721e-evm-pcie0-ep.dtbo
+k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
+	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
 	k3-j721s2-evm-pcie1-ep.dtbo
 dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
@@ -122,7 +129,10 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am62a7-sk-hdmi-audio.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
+	k3-am68-sk-base-board-csi2-dual-imx219-dtbs \
+	k3-am69-sk-csi2-dual-imx219-dtbs \
 	k3-j721e-evm-pcie0-ep.dtb \
+	k3-j721e-sk-csi2-dual-imx219-dtbs \
 	k3-j721s2-evm-pcie1-ep.dtb
 
 # Enable support for device-tree overlays
@@ -132,5 +142,8 @@ DTC_FLAGS_k3-am62-lp-sk += -@
 DTC_FLAGS_k3-am62a7-sk += -@
 DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
 DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
+DTC_FLAGS_k3-am68-sk-base-board += -@
+DTC_FLAGS_k3-am69-sk += -@
 DTC_FLAGS_k3-j721e-common-proc-board += -@
+DTC_FLAGS_k3-j721e-sk += -@
 DTC_FLAGS_k3-j721s2-common-proc-board += -@
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso b/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso
new file mode 100644
index 000000000000..47bb5480b5b0
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for dual RPi Camera V2.1 (Sony IMX219) interfaced with CSI2
+ * on J721E SK, AM68 SK or AM69-SK board.
+ * https://datasheets.raspberrypi.org/camera/camera-v2-schematic.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	clk_imx219_fixed: imx219-xclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+};
+
+&csi_mux {
+	idle-state = <1>;
+};
+
+/* CAM0 I2C */
+&cam0_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	imx219_0: imx219-0 at 10 {
+		compatible = "sony,imx219";
+		reg = <0x10>;
+
+		clocks = <&clk_imx219_fixed>;
+		clock-names = "xclk";
+
+		port {
+			csi2_cam0: endpoint {
+				remote-endpoint = <&csi2rx0_in_sensor>;
+				link-frequencies = /bits/ 64 <456000000>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+/* CAM1 I2C */
+&cam1_i2c {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	imx219_1: imx219-1 at 10 {
+		compatible = "sony,imx219";
+		reg = <0x10>;
+
+		clocks = <&clk_imx219_fixed>;
+		clock-names = "xclk";
+
+		port {
+			csi2_cam1: endpoint {
+				remote-endpoint = <&csi2rx1_in_sensor>;
+				link-frequencies = /bits/ 64 <456000000>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+
+&cdns_csi2rx0 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi0_port0: port at 0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx0_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam0>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+
+		csi0_port1: port at 1 {
+			reg = <1>;
+			status = "disabled";
+		};
+
+		csi0_port2: port at 2 {
+			reg = <2>;
+			status = "disabled";
+		};
+
+		csi0_port3: port at 3 {
+			reg = <3>;
+			status = "disabled";
+		};
+
+		csi0_port4: port at 4 {
+			reg = <4>;
+			status = "disabled";
+		};
+	};
+};
+
+&dphy0 {
+	status = "okay";
+};
+
+&ti_csi2rx0 {
+	status = "okay";
+};
+
+&cdns_csi2rx1 {
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		csi1_port0: port at 0 {
+			reg = <0>;
+			status = "okay";
+
+			csi2rx1_in_sensor: endpoint {
+				remote-endpoint = <&csi2_cam1>;
+				bus-type = <4>; /* CSI2 DPHY. */
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+			};
+		};
+
+		csi1_port1: port at 1 {
+			reg = <1>;
+			status = "disabled";
+		};
+
+		csi1_port2: port at 2 {
+			reg = <2>;
+			status = "disabled";
+		};
+
+		csi1_port3: port at 3 {
+			reg = <3>;
+			status = "disabled";
+		};
+
+		csi1_port4: port at 4 {
+			reg = <4>;
+			status = "disabled";
+		};
+	};
+};
+
+&dphy1 {
+	status = "okay";
+};
+
+&ti_csi2rx1 {
+	status = "okay";
+};
-- 
2.34.1



From mihai.carabas at oracle.com  Wed Feb 14 23:41:43 2024
From: mihai.carabas at oracle.com (Mihai Carabas)
Date: Thu, 15 Feb 2024 09:41:43 +0200
Subject: [PATCH v4 1/8] x86: Move ARCH_HAS_CPU_RELAX to arch
In-Reply-To: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
References: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
Message-ID: <1707982910-27680-2-git-send-email-mihai.carabas@oracle.com>

From: Joao Martins <joao.m.martins at oracle.com>

ARM64 is going to use it for haltpoll support (for poll-state)
so move the definition to be arch-agnostic and allow architectures
to override it.

Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
---
 arch/Kconfig     | 3 +++
 arch/x86/Kconfig | 4 +---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index a5af0edd3eb8..5b2e8a88853c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1363,6 +1363,9 @@ config RELR
 config ARCH_HAS_MEM_ENCRYPT
 	bool
 
+config ARCH_HAS_CPU_RELAX
+	bool
+
 config ARCH_HAS_CC_PLATFORM
 	bool
 
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5edec175b9bf..8c4312133832 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -73,6 +73,7 @@ config X86
 	select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
 	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_CPU_PASID		if IOMMU_SVA
+	select ARCH_HAS_CPU_RELAX
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE	if !X86_PAE
@@ -367,9 +368,6 @@ config ARCH_MAY_HAVE_PC_FDC
 config GENERIC_CALIBRATE_DELAY
 	def_bool y
 
-config ARCH_HAS_CPU_RELAX
-	def_bool y
-
 config ARCH_HIBERNATION_POSSIBLE
 	def_bool y
 
-- 
1.8.3.1



From mihai.carabas at oracle.com  Wed Feb 14 23:41:45 2024
From: mihai.carabas at oracle.com (Mihai Carabas)
Date: Thu, 15 Feb 2024 09:41:45 +0200
Subject: [PATCH v4 3/8] governors/haltpoll: Drop kvm_para_available() check
In-Reply-To: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
References: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
Message-ID: <1707982910-27680-4-git-send-email-mihai.carabas@oracle.com>

From: Joao Martins <joao.m.martins at oracle.com>

This is duplicated already in the haltpoll idle driver,
and there's no need to re-check KVM guest availability in
the governor.

Either guests uses the module which explicitly selects this
governor, and given that it has the lowest rating of all governors
(menu=20,teo=19,ladder=10/25,haltpoll=9) means that unless it's
the only one compiled in, it won't be selected.

Dropping such check also allows to test haltpoll in baremetal.

Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
Acked-by: Rafael J. Wysocki <rafael at kernel.org>
---
 drivers/cpuidle/governors/haltpoll.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/cpuidle/governors/haltpoll.c b/drivers/cpuidle/governors/haltpoll.c
index 1dff3a52917d..c9b69651d377 100644
--- a/drivers/cpuidle/governors/haltpoll.c
+++ b/drivers/cpuidle/governors/haltpoll.c
@@ -143,10 +143,7 @@ static int haltpoll_enable_device(struct cpuidle_driver *drv,
 
 static int __init init_haltpoll(void)
 {
-	if (kvm_para_available())
-		return cpuidle_register_governor(&haltpoll_governor);
-
-	return 0;
+	return cpuidle_register_governor(&haltpoll_governor);
 }
 
 postcore_initcall(init_haltpoll);
-- 
1.8.3.1



From mihai.carabas at oracle.com  Wed Feb 14 23:41:44 2024
From: mihai.carabas at oracle.com (Mihai Carabas)
Date: Thu, 15 Feb 2024 09:41:44 +0200
Subject: [PATCH v4 2/8] x86/kvm: Move haltpoll_want() to be arch defined
In-Reply-To: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
References: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
Message-ID: <1707982910-27680-3-git-send-email-mihai.carabas@oracle.com>

From: Joao Martins <joao.m.martins at oracle.com>

Right now, kvm_para_has_hint(KVM_HINTS_REALTIME) is x86 only, and so in the
pursuit of making cpuidle-haltpoll arch independent, move the check for
haltpoll enablement to be defined per architecture. Same thing for
boot_option_idle_override. To that end, add a arch_haltpoll_want() and move the
check there.

Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
Signed-off-by: Ankur Arora <ankur.a.arora at oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
Acked-by: Rafael J. Wysocki <rafael at kernel.org>
---
 arch/x86/include/asm/cpuidle_haltpoll.h |  1 +
 arch/x86/kernel/kvm.c                   | 10 ++++++++++
 drivers/cpuidle/cpuidle-haltpoll.c      |  8 ++------
 include/linux/cpuidle_haltpoll.h        |  5 +++++
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/cpuidle_haltpoll.h b/arch/x86/include/asm/cpuidle_haltpoll.h
index c8b39c6716ff..2c5a53ce266f 100644
--- a/arch/x86/include/asm/cpuidle_haltpoll.h
+++ b/arch/x86/include/asm/cpuidle_haltpoll.h
@@ -4,5 +4,6 @@
 
 void arch_haltpoll_enable(unsigned int cpu);
 void arch_haltpoll_disable(unsigned int cpu);
+bool arch_haltpoll_want(void);
 
 #endif
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 428ee74002e1..259212eb478d 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -1150,4 +1150,14 @@ void arch_haltpoll_disable(unsigned int cpu)
 	smp_call_function_single(cpu, kvm_enable_host_haltpoll, NULL, 1);
 }
 EXPORT_SYMBOL_GPL(arch_haltpoll_disable);
+
+bool arch_haltpoll_want(void)
+{
+	/* Do not load haltpoll if idle= is passed */
+	if (boot_option_idle_override != IDLE_NO_OVERRIDE)
+		return false;
+
+	return kvm_para_has_hint(KVM_HINTS_REALTIME);
+}
+EXPORT_SYMBOL_GPL(arch_haltpoll_want);
 #endif
diff --git a/drivers/cpuidle/cpuidle-haltpoll.c b/drivers/cpuidle/cpuidle-haltpoll.c
index d8515d5c0853..d68550270802 100644
--- a/drivers/cpuidle/cpuidle-haltpoll.c
+++ b/drivers/cpuidle/cpuidle-haltpoll.c
@@ -95,7 +95,7 @@ static void haltpoll_uninit(void)
 
 static bool haltpoll_want(void)
 {
-	return kvm_para_has_hint(KVM_HINTS_REALTIME) || force;
+	return (kvm_para_available() && arch_haltpoll_want()) || force;
 }
 
 static int __init haltpoll_init(void)
@@ -103,11 +103,7 @@ static int __init haltpoll_init(void)
 	int ret;
 	struct cpuidle_driver *drv = &haltpoll_driver;
 
-	/* Do not load haltpoll if idle= is passed */
-	if (boot_option_idle_override != IDLE_NO_OVERRIDE)
-		return -ENODEV;
-
-	if (!kvm_para_available() || !haltpoll_want())
+	if (!haltpoll_want())
 		return -ENODEV;
 
 	cpuidle_poll_state_init(drv);
diff --git a/include/linux/cpuidle_haltpoll.h b/include/linux/cpuidle_haltpoll.h
index d50c1e0411a2..bae68a6603e3 100644
--- a/include/linux/cpuidle_haltpoll.h
+++ b/include/linux/cpuidle_haltpoll.h
@@ -12,5 +12,10 @@ static inline void arch_haltpoll_enable(unsigned int cpu)
 static inline void arch_haltpoll_disable(unsigned int cpu)
 {
 }
+
+static inline bool arch_haltpoll_want(void)
+{
+	return false;
+}
 #endif
 #endif
-- 
1.8.3.1



From mihai.carabas at oracle.com  Wed Feb 14 23:41:42 2024
From: mihai.carabas at oracle.com (Mihai Carabas)
Date: Thu, 15 Feb 2024 09:41:42 +0200
Subject: [PATCH v4] Enable haltpoll for arm64
Message-ID: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>

This patchset enables the usage of haltpoll governer on arm64. This is
specifically interesting for KVM guests by reducing the IPC latencies.

Here are some benchmarks without/with haltpoll for a KVM guest:

a) without haltpoll:
perf bench sched pipe
# Running 'sched/pipe' benchmark:
# Executed 1000000 pipe operations between two processes

     Total time: 8.138 [sec]

            8.138094 usecs/op
             122878 ops/sec

b) with haltpoll:
perf bench sched pipe
# Running 'sched/pipe' benchmark:
# Executed 1000000 pipe operations between two processes

     Total time: 5.003 [sec]

            5.003085 usecs/op
             199876 ops/sec

v4 changes from v3:
- change 7/8 per Rafael input: drop the parens and use ret for the final check
- add 8/8 which renames the guard for building poll_state

v3 changes from v2:
- fix 1/7 per Petr Mladek - remove ARCH_HAS_CPU_RELAX from arch/x86/Kconfig
- add Ack-by from Rafael Wysocki on 2/7

v2 changes from v1:
- added patch 7 where we change cpu_relax with smp_cond_load_relaxed per PeterZ
  (this improves by 50% at least the CPU cycles consumed in the tests above:
  10,716,881,137 now vs 14,503,014,257 before)
- removed the ifdef from patch 1 per RafaelW


Joao Martins (6):
  x86: Move ARCH_HAS_CPU_RELAX to arch
  x86/kvm: Move haltpoll_want() to be arch defined
  governors/haltpoll: Drop kvm_para_available() check
  arm64: Select ARCH_HAS_CPU_RELAX
  arm64: Define TIF_POLLING_NRFLAG
  cpuidle-haltpoll: ARM64 support

Mihai Carabas (2):
  cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed
  cpuidle: replace with HAS_CPU_RELAX with HAS_WANTS_IDLE_POLL

 arch/Kconfig                            |  3 +++
 arch/arm64/Kconfig                      |  1 +
 arch/arm64/include/asm/thread_info.h    |  6 ++++++
 arch/x86/Kconfig                        |  4 +---
 arch/x86/include/asm/cpuidle_haltpoll.h |  1 +
 arch/x86/kernel/kvm.c                   | 10 ++++++++++
 drivers/acpi/processor_idle.c           |  4 ++--
 drivers/cpuidle/Kconfig                 |  4 ++--
 drivers/cpuidle/Makefile                |  2 +-
 drivers/cpuidle/cpuidle-haltpoll.c      |  8 ++------
 drivers/cpuidle/governors/haltpoll.c    |  5 +----
 drivers/cpuidle/poll_state.c            | 15 ++++++++++-----
 include/linux/cpuidle.h                 |  2 +-
 include/linux/cpuidle_haltpoll.h        |  5 +++++
 14 files changed, 46 insertions(+), 24 deletions(-)

-- 
1.8.3.1



From mihai.carabas at oracle.com  Wed Feb 14 23:41:46 2024
From: mihai.carabas at oracle.com (Mihai Carabas)
Date: Thu, 15 Feb 2024 09:41:46 +0200
Subject: [PATCH v4 4/8] arm64: Select ARCH_HAS_CPU_RELAX
In-Reply-To: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
References: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
Message-ID: <1707982910-27680-5-git-send-email-mihai.carabas@oracle.com>

From: Joao Martins <joao.m.martins at oracle.com>

ARCH_HAS_CPU_RELAX controls the build of poll-state, so select it from ARM64
kconfig.

Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aa7c1d435139..bc628a3165eb 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -107,6 +107,7 @@ config ARM64
 	select ARCH_WANT_LD_ORPHAN_WARN
 	select ARCH_WANTS_NO_INSTR
 	select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
+	select ARCH_HAS_CPU_RELAX
 	select ARCH_HAS_UBSAN_SANITIZE_ALL
 	select ARM_AMBA
 	select ARM_ARCH_TIMER
-- 
1.8.3.1



From mihai.carabas at oracle.com  Wed Feb 14 23:41:47 2024
From: mihai.carabas at oracle.com (Mihai Carabas)
Date: Thu, 15 Feb 2024 09:41:47 +0200
Subject: [PATCH v4 5/8] arm64: Define TIF_POLLING_NRFLAG
In-Reply-To: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
References: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
Message-ID: <1707982910-27680-6-git-send-email-mihai.carabas@oracle.com>

From: Joao Martins <joao.m.martins at oracle.com>

The default idle method for arm64 is WFI and it therefore
unconditionally requires the reschedule interrupt when idle.

Commit 842514849a61 ("arm64: Remove TIF_POLLING_NRFLAG") had
reverted it because WFI was the only idle method. ARM64 support
for haltpoll means that poll_idle() polls for TIF_POLLING_NRFLAG,
so define on arm64 *only if* haltpoll is built, using the same bit.

Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
---
 arch/arm64/include/asm/thread_info.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index e72a3bf9e563..72273a2168fa 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -69,6 +69,9 @@ struct thread_info {
 #define TIF_SYSCALL_TRACEPOINT	10	/* syscall tracepoint for ftrace */
 #define TIF_SECCOMP		11	/* syscall secure computing */
 #define TIF_SYSCALL_EMU		12	/* syscall emulation active */
+#if IS_ENABLED(CONFIG_HALTPOLL_CPUIDLE) || IS_ENABLED(CONFIG_HALTPOLL_CPUIDLE_MODULE)
+#define TIF_POLLING_NRFLAG      16      /* poll_idle() polls TIF_NEED_RESCHED */
+#endif
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 #define TIF_FREEZE		19
 #define TIF_RESTORE_SIGMASK	20
@@ -91,6 +94,9 @@ struct thread_info {
 #define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_SYSCALL_EMU	(1 << TIF_SYSCALL_EMU)
+#if IS_ENABLED(CONFIG_HALTPOLL_CPUIDLE) || IS_ENABLED(CONFIG_HALTPOLL_CPUIDLE_MODULE)
+#define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
+#endif
 #define _TIF_UPROBE		(1 << TIF_UPROBE)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
 #define _TIF_32BIT		(1 << TIF_32BIT)
-- 
1.8.3.1



From mihai.carabas at oracle.com  Wed Feb 14 23:41:48 2024
From: mihai.carabas at oracle.com (Mihai Carabas)
Date: Thu, 15 Feb 2024 09:41:48 +0200
Subject: [PATCH v4 6/8] cpuidle-haltpoll: ARM64 support
In-Reply-To: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
References: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
Message-ID: <1707982910-27680-7-git-send-email-mihai.carabas@oracle.com>

From: Joao Martins <joao.m.martins at oracle.com>

To test whether it's a guest or not for the default cases, the haltpoll
driver uses the kvm_para* helpers to find out if it's a guest or not.

ARM64 doesn't have or defined any of these, so it remains disabled on
the default. Although it allows to be force-loaded.

Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
---
 drivers/cpuidle/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index cac5997dca50..067927eda466 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -35,7 +35,7 @@ config CPU_IDLE_GOV_TEO
 
 config CPU_IDLE_GOV_HALTPOLL
 	bool "Haltpoll governor (for virtualized systems)"
-	depends on KVM_GUEST
+	depends on (X86 && KVM_GUEST) || ARM64
 	help
 	  This governor implements haltpoll idle state selection, to be
 	  used in conjunction with the haltpoll cpuidle driver, allowing
@@ -73,7 +73,7 @@ endmenu
 
 config HALTPOLL_CPUIDLE
 	tristate "Halt poll cpuidle driver"
-	depends on X86 && KVM_GUEST
+	depends on (X86 && KVM_GUEST) || ARM64
 	select CPU_IDLE_GOV_HALTPOLL
 	default y
 	help
-- 
1.8.3.1



From mihai.carabas at oracle.com  Wed Feb 14 23:41:49 2024
From: mihai.carabas at oracle.com (Mihai Carabas)
Date: Thu, 15 Feb 2024 09:41:49 +0200
Subject: [PATCH v4 7/8] cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed
In-Reply-To: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
References: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
Message-ID: <1707982910-27680-8-git-send-email-mihai.carabas@oracle.com>

cpu_relax on ARM64 does a simple "yield". Thus we replace it with
smp_cond_load_relaxed which basically does a "wfe".

Suggested-by: Peter Zijlstra <peterz at infradead.org>
Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
---
 drivers/cpuidle/poll_state.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c
index 9b6d90a72601..1e45be906e72 100644
--- a/drivers/cpuidle/poll_state.c
+++ b/drivers/cpuidle/poll_state.c
@@ -13,6 +13,7 @@
 static int __cpuidle poll_idle(struct cpuidle_device *dev,
 			       struct cpuidle_driver *drv, int index)
 {
+	unsigned long ret;
 	u64 time_start;
 
 	time_start = local_clock_noinstr();
@@ -26,12 +27,16 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev,
 
 		limit = cpuidle_poll_time(drv, dev);
 
-		while (!need_resched()) {
-			cpu_relax();
-			if (loop_count++ < POLL_IDLE_RELAX_COUNT)
-				continue;
-
+		for (;;) {
 			loop_count = 0;
+
+			ret = smp_cond_load_relaxed(&current_thread_info()->flags,
+						    VAL & _TIF_NEED_RESCHED ||
+						    loop_count++ >= POLL_IDLE_RELAX_COUNT);
+
+			if (!(ret & _TIF_NEED_RESCHED))
+				break;
+
 			if (local_clock_noinstr() - time_start > limit) {
 				dev->poll_time_limit = true;
 				break;
-- 
1.8.3.1



From mihai.carabas at oracle.com  Wed Feb 14 23:41:50 2024
From: mihai.carabas at oracle.com (Mihai Carabas)
Date: Thu, 15 Feb 2024 09:41:50 +0200
Subject: [PATCH v4 8/8] cpuidle: replace with HAS_CPU_RELAX with HAS_WANTS_IDLE_POLL
In-Reply-To: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
References: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
Message-ID: <1707982910-27680-9-git-send-email-mihai.carabas@oracle.com>

Replace ARCH_HAS_CPU_RELAX with ARCH_WANTS_IDLE_POLL for clarity as it controls
the building of poll_state.

Suggested-by: Will Deacon <will at kernel.org>
Signed-off-by: Ankur arora <ankur.a.arora at oracle.com>
Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
---
 arch/Kconfig                  | 2 +-
 arch/arm64/Kconfig            | 2 +-
 arch/x86/Kconfig              | 2 +-
 drivers/acpi/processor_idle.c | 4 ++--
 drivers/cpuidle/Makefile      | 2 +-
 include/linux/cpuidle.h       | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 5b2e8a88853c..e7659a3a7d58 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1363,7 +1363,7 @@ config RELR
 config ARCH_HAS_MEM_ENCRYPT
 	bool
 
-config ARCH_HAS_CPU_RELAX
+config ARCH_WANTS_IDLE_POLL
 	bool
 
 config ARCH_HAS_CC_PLATFORM
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index bc628a3165eb..7c963f7c10e4 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -107,7 +107,7 @@ config ARM64
 	select ARCH_WANT_LD_ORPHAN_WARN
 	select ARCH_WANTS_NO_INSTR
 	select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
-	select ARCH_HAS_CPU_RELAX
+	select ARCH_WANTS_IDLE_POLL
 	select ARCH_HAS_UBSAN_SANITIZE_ALL
 	select ARM_AMBA
 	select ARM_ARCH_TIMER
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 8c4312133832..90f5d16be8c0 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -73,7 +73,7 @@ config X86
 	select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
 	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_CPU_PASID		if IOMMU_SVA
-	select ARCH_HAS_CPU_RELAX
+	select ARCH_WANTS_IDLE_POLL
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE	if !X86_PAE
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 55437f5e0c3a..6a0a1f16a5c3 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -36,7 +36,7 @@
 #include <asm/cpu.h>
 #endif
 
-#define ACPI_IDLE_STATE_START	(IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX) ? 1 : 0)
+#define ACPI_IDLE_STATE_START	(IS_ENABLED(CONFIG_ARCH_WANTS_IDLE_POLL) ? 1 : 0)
 
 static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
 module_param(max_cstate, uint, 0400);
@@ -787,7 +787,7 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr)
 	if (max_cstate == 0)
 		max_cstate = 1;
 
-	if (IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX)) {
+	if (IS_ENABLED(CONFIG_ARCH_WANTS_IDLE_POLL)) {
 		cpuidle_poll_state_init(drv);
 		count = 1;
 	} else {
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index d103342b7cfc..23f48d99f0f2 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -7,7 +7,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_ARCH_WANTS_IDLE_POLL)	  += poll_state.o
 obj-$(CONFIG_HALTPOLL_CPUIDLE)		  += cpuidle-haltpoll.o
 
 ##################################################################################
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 3183aeb7f5b4..53e55a91d55d 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -275,7 +275,7 @@ static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev,
 }
 #endif
 
-#if defined(CONFIG_CPU_IDLE) && defined(CONFIG_ARCH_HAS_CPU_RELAX)
+#if defined(CONFIG_CPU_IDLE) && defined(CONFIG_ARCH_WANTS_IDLE_POLL)
 void cpuidle_poll_state_init(struct cpuidle_driver *drv);
 #else
 static inline void cpuidle_poll_state_init(struct cpuidle_driver *drv) {}
-- 
1.8.3.1



From neil.armstrong at linaro.org  Thu Feb 15 00:58:52 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Thu, 15 Feb 2024 09:58:52 +0100
Subject: [PATCH 3/5] drm: msm: add support for A750 GPU
In-Reply-To: <13d65685-b306-43ad-b9ca-a799f2cf73e5@linaro.org>
References: <20240212-topic-sm8650-gpu-v1-0-708a40b747b5@linaro.org>
 <20240212-topic-sm8650-gpu-v1-3-708a40b747b5@linaro.org>
 <b5d76a25-045a-4acd-ad20-d28855b40222@linaro.org>
 <bcad544c-7ca2-4b4f-805b-4ccaedbd091c@linaro.org>
 <13d65685-b306-43ad-b9ca-a799f2cf73e5@linaro.org>
Message-ID: <6aea55e7-2ca6-444c-b111-e3cc45bd28a5@linaro.org>

On 14/02/2024 22:43, Konrad Dybcio wrote:
> On 12.02.2024 15:45, Neil Armstrong wrote:
>> On 12/02/2024 11:46, Konrad Dybcio wrote:
>>> On 12.02.2024 11:37, Neil Armstrong wrote:
>>>> Add support for the A750 GPU found on the SM8650 platform
>>>>
>>>> Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
>>>> doesn't have an HWCFG block but a separate register set.
>>>>
>>>> The missing registers are added in the a6xx.xml.h file that would
>>>> require a subsequent sync and the non-existent hwcfg is handled
>>>> in a6xx_set_hwcg().
>>>
>>> These should also be submitted to mesa to make sure the next header sync
>>> doesn't wipe them
>>
>> Ack submitting them right now: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27576
> 
> Thanks
> 
>>
>>>
>>> [...]
>>>
>>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>>>> @@ -958,10 +958,11 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>>>  ????? struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>>>>  ????? struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
>>>>  ????? const struct adreno_reglist *reg;
>>>> +??? bool skip_programming = !(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu));
>>>
>>> is_a750?
>>
>> OK right, I was thinking of the next gpu which will probably also miss an hwcfg
>>
>>>
>>>>  ????? unsigned int i;
>>>>  ????? u32 val, clock_cntl_on, cgc_mode;
>>>>  ? -??? if (!adreno_gpu->info->hwcg)
>>>> +??? if (skip_programming)
>>>>  ????????? return;
>>>>  ? ????? if (adreno_is_a630(adreno_gpu))
>>>> @@ -982,6 +983,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>>>  ??????????????? state ? 0x5555 : 0);
>>>>  ????? }
>>>>  ? +??? if (!adreno_gpu->info->hwcg) {
>>>
>>> I don't think this block of code is reachable now, no?
>>
>> It is because we didn't skip when adreno_is_a7xx(adreno_gpu)
> 
> Ahh I misread the brackets within the assignment
> 
>>
>>>
>>> Maybe remove the skip_programming and if_a750 here?
>> This would require:
>>>> -??? if (!adreno_gpu->info->hwcg || )
>>>> +??? if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
>>
>> and:
>>
>>>> +??? if (adreno_is_a750(adreno_gpu)) {
>>
>> But if the next gpu also doesn't have an hwcfg, we will need to use
>> the current design...
>>
>> I just tried with:
>> ====================><===============================
>> @@ -961,7 +961,7 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>  ??????? unsigned int i;
>>  ??????? u32 val, clock_cntl_on, cgc_mode;
>>
>> -?????? if (!adreno_gpu->info->hwcg)
>> +?????? if (!(adreno_gpu->info->hwcg || adreno_is_a750(adreno_gpu)))
>>  ??????????????? return;
>>
>>  ??????? if (adreno_is_a630(adreno_gpu))
>> @@ -982,6 +982,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>>  ????????????????????????? state ? 0x5555 : 0);
>>  ??????? }
>>
>> +?????? if (adreno_is_a750(adreno_gpu)) {
>> +?????????????? gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
>> +?????????????? gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
>> +
>> +?????????????? if (state) {
>> +?????????????????????? gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
>> +
>> +?????????????????????? if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
>> +??????????????????????????????????????????? val & A7XX_RBBM_CGC_P2S_STATUS_TXDONE, 1, 10)) {
>> +?????????????????????????????? dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
>> +?????????????????????????????? return;
>> +?????????????????????? }
>> +
>> +?????????????????????? gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
>> +?????????????? }
>> +
>> +?????????????? return;
>> +?????? }
>> +
>>  ??????? val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
>>
>>  ??????? /* Don't re-program the registers if they are already correct */
>> ====================><===============================
>>
>> And it works fine, does it work it for you ?
> 
> Let's keep it as-is in the original submission, as I've mentioned, I had
> misread the code

Ack thanks

Neil

> 
> Konrad
> 
>>
>>>
>>>> +??????? gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
>>>> +??????? gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
>>>> +
>>>> +??????? if (state) {
>>>> +??????????? gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
>>>> +
>>>> +??????????? if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
>>>> +???????????????????????? val & BIT(0), 1, 10)) {
>>>
>>> We should define that bit name (the err suggests it's
>>> REG_A7XX_RBBM_GCC_P2S_STATUS_TXDONE or so)
>>>
>>> [...]
>>>
>>>> +static inline int adreno_is_a750(struct adreno_gpu *gpu)
>>>> +{
>>>> +??? return gpu->info->chip_ids[0] == 0x43051401;
>>>> +}
>>>> +
>>>>  ? /* Placeholder to make future diffs smaller */
>>>
>>> Please also remove this comment now that it's invalid
>>
>> Ack
>>
>>>
>>> Konrad
>>
>> Thanks,
>> Neil
>>



From krzk at kernel.org  Thu Feb 15 00:59:50 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 09:59:50 +0100
Subject: [PATCH 2/3] tee: tstee: Add Trusted Services TEE driver
In-Reply-To: <20240213145239.379875-3-balint.dobszay@arm.com>
References: <20240213145239.379875-1-balint.dobszay@arm.com>
 <20240213145239.379875-3-balint.dobszay@arm.com>
Message-ID: <ed8aaee7-be14-43ab-981c-d2ac04f4fc71@kernel.org>

On 13/02/2024 15:52, Balint Dobszay wrote:
> The Trusted Services project provides a framework for developing and
> deploying device Root of Trust services in FF-A Secure Partitions. The
> FF-A SPs are accessible through the FF-A driver, but this doesn't
> provide a user space interface. The goal of this TEE driver is to make
> Trusted Services SPs accessible for user space clients.
> 
> All TS SPs have the same FF-A UUID, it identifies the RPC protocol used
> by TS. A TS SP can host one or more services, a service is identified by
> its service UUID. The same type of service cannot be present twice in
> the same SP. During SP boot each service in an SP is assigned an
> interface ID, this is just a short ID to simplify message addressing.
> There is 1:1 mapping between TS SPs and TEE devices, i.e. a separate TEE
> device is registered for each TS SP. This is required since contrary to
> the generic TEE design where memory is shared with the whole TEE
> implementation, in case of FF-A, memory is shared with a specific SP. A
> user space client has to be able to separately share memory with each SP
> based on its endpoint ID.
> 
> Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
> ---


> +static int tstee_probe(struct ffa_device *ffa_dev)
> +{
> +	struct tstee *tstee;
> +	int rc;
> +
> +	ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev);
> +
> +	if (!tstee_check_rpc_compatible(ffa_dev))
> +		return -EINVAL;
> +
> +	tstee = kzalloc(sizeof(*tstee), GFP_KERNEL);
> +	if (!tstee)
> +		return -ENOMEM;
> +
> +	tstee->ffa_dev = ffa_dev;
> +
> +	tstee->pool = tstee_create_shm_pool();
> +	if (IS_ERR(tstee->pool)) {
> +		rc = PTR_ERR(tstee->pool);
> +		tstee->pool = NULL;
> +		goto err;

Is it logically correct to call here tee_device_unregister()?

> +	}
> +
> +	tstee->teedev = tee_device_alloc(&tstee_desc, NULL, tstee->pool, tstee);
> +	if (IS_ERR(tstee->teedev)) {
> +		rc = PTR_ERR(tstee->teedev);
> +		tstee->teedev = NULL;
> +		goto err;
> +	}
> +
> +	rc = tee_device_register(tstee->teedev);
> +	if (rc)
> +		goto err;
> +
> +	ffa_dev_set_drvdata(ffa_dev, tstee);
> +
> +	pr_info("driver initialized for endpoint 0x%x\n", ffa_dev->vm_id);

Don't print simple probe success messages. Anyway all prints in device
context should be dev_*.

> +
> +	return 0;
> +
> +err:
> +	tstee_deinit_common(tstee);
> +	return rc;
> +}
> +
> +static void tstee_remove(struct ffa_device *ffa_dev)
> +{
> +	tstee_deinit_common(ffa_dev->dev.driver_data);
> +}
> +
> +static const struct ffa_device_id tstee_device_ids[] = {
> +	/* TS RPC protocol UUID: bdcd76d7-825e-4751-963b-86d4f84943ac */
> +	{ TS_RPC_UUID },
> +	{}
> +};
> +
> +static struct ffa_driver tstee_driver = {
> +	.name = "arm_tstee",
> +	.probe = tstee_probe,
> +	.remove = tstee_remove,
> +	.id_table = tstee_device_ids,
> +};
> +
> +static int __init mod_init(void)
> +{
> +	return ffa_register(&tstee_driver);
> +}
> +module_init(mod_init)
> +
> +static void __exit mod_exit(void)
> +{
> +	ffa_unregister(&tstee_driver);
> +}
> +module_exit(mod_exit)
> +
> +MODULE_ALIAS("arm-tstee");

Why do you need this alias? I don't see MODULE_DEVICE_TABLE, so how this
bus handles module loading?


Best regards,
Krzysztof



From d-gole at ti.com  Thu Feb 15 00:59:51 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Thu, 15 Feb 2024 14:29:51 +0530
Subject: [PATCH 1/3] dt-bindings: cpufreq: Add nvmem-cells for chip
 information
In-Reply-To: <20240206145721.2418893-2-msp@baylibre.com>
References: <20240206145721.2418893-1-msp@baylibre.com>
 <20240206145721.2418893-2-msp@baylibre.com>
Message-ID: <20240215085951.xrcitu2so5gqcewn@dhruva>

Hi,

On Feb 06, 2024 at 15:57:19 +0100, Markus Schneider-Pargmann wrote:
> Add nvmem-cells to describe chip information like chipvariant and
> chipspeed. If nvmem-cells are used, the syscon property is not necessary
> anymore.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> Acked-by: Andrew Davis <afd at ti.com>
> ---
>  .../bindings/opp/operating-points-v2-ti-cpu.yaml | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml b/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml
> index 02d1d2c17129..b1881a0834fe 100644
> --- a/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml
> +++ b/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml
> @@ -34,6 +34,14 @@ properties:
>        points to syscon node representing the control module
>        register space of the SoC.
>  
> +  nvmem-cells:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +
> +  nvmem-cell-names:
> +    items:
> +      - const: chipvariant
> +      - const: chipspeed
> +
>    opp-shared: true
>  
>  patternProperties:
> @@ -55,7 +63,13 @@ patternProperties:
>  
>  required:
>    - compatible
> -  - syscon
> +
> +oneOf:
> +  - required:
> +      - syscon
> +  - required:
> +      - nvmem-cells
> +      - nvmem-cell-names

Reviewed-by: Dhruva Gole <d-gole at ti.com>


-- 
Best regards,
Dhruva Gole <d-gole at ti.com>


From krzysztof.kozlowski at linaro.org  Thu Feb 15 01:06:55 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 10:06:55 +0100
Subject: [PATCH v10 2/4] dt-bindings: remoteproc: add Tightly Coupled
 Memory (TCM) bindings
In-Reply-To: <b931a24c-f676-4ddb-bb7c-e7a509d5dd4b@amd.com>
References: <20240213175450.3097308-1-tanmay.shah@amd.com>
 <20240213175450.3097308-3-tanmay.shah@amd.com>
 <170785205177.2155555.1311787541370066483.robh@kernel.org>
 <b931a24c-f676-4ddb-bb7c-e7a509d5dd4b@amd.com>
Message-ID: <135e3154-2a55-40ac-9ba9-2de00833b903@linaro.org>

On 13/02/2024 21:37, Tanmay Shah wrote:
> Hello,
> 
> Thanks for reviews please find my comments below.
> 
> On 2/13/24 1:20 PM, Rob Herring wrote:
>> On Tue, 13 Feb 2024 09:54:48 -0800, Tanmay Shah wrote:
>>> From: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
>>>
>>> Introduce bindings for TCM memory address space on AMD-xilinx Zynq
>>> UltraScale+ platform. It will help in defining TCM in device-tree
>>> and make it's access platform agnostic and data-driven.
>>>
>>> Tightly-coupled memories(TCMs) are low-latency memory that provides
>>> predictable instruction execution and predictable data load/store
>>> timing. Each Cortex-R5F processor contains two 64-bit wide 64 KB memory
>>> banks on the ATCM and BTCM ports, for a total of 128 KB of memory.
>>>
>>> The TCM resources(reg, reg-names and power-domain) are documented for
>>> each TCM in the R5 node. The reg and reg-names are made as required
>>> properties as we don't want to hardcode TCM addresses for future
>>> platforms and for zu+ legacy implementation will ensure that the
>>> old dts w/o reg/reg-names works and stable ABI is maintained.
>>>
>>> It also extends the examples for TCM split and lockstep modes.
>>>
>>> Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
>>> Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
>>> ---
>>>
>>> Changes in v10:
>>>   - modify number of "reg", "reg-names" and "power-domains" entries
>>>     based on cluster mode
>>>   - Add extra optional atcm and btcm in "reg" property for lockstep mode
>>>   - Add "reg-names" for extra optional atcm and btcm for lockstep mode
>>>   - Drop previous Ack as bindings has new change
>>>
>>> Changes in v9:
>>>   - None
>>> Changes in v8:
>>>   - None
>>> Changes in v7:
>>>   - None
>>> Changes in v6:
>>>   - None
>>> Changes in v5:
>>>   - None
>>>
>>> Changes in v4:
>>>   - Use address-cells and size-cells value 2
>>>   - Modify ranges property as per new value of address-cells
>>>     and size-cells
>>>   - Modify child node "reg" property accordingly
>>>   - Remove previous ack for further review
>>>
>>> v4 link: https://lore.kernel.org/all/20230829181900.2561194-2-tanmay.shah at amd.com/
>>>
>>>  .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 ++++++++++++++++--
>>>  1 file changed, 170 insertions(+), 22 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:
>> ./Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml:118:13: [warning] wrong indentation: expected 10 but found 12 (indentation)
> Ack. I will fix this.
> 
> However, can I still get reviews on patch itself so if something else needs to be fixed I can fix in next revision as well.

Sorry, I have too many patches to review to provide feedback on work
which does not build/compile/test. First use automated tooling, like
building a C code, to detect as many issues as possible then ask for
reviewing. Not the other way around.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb 15 01:11:09 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 10:11:09 +0100
Subject: [PATCH 01/23] dt-bindings: gpio: nomadik: convert into yaml
 format
In-Reply-To: <20240214-mbly-gpio-v1-1-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-1-f88c0ccf372b@bootlin.com>
Message-ID: <be4e6ded-6596-472b-a988-0909a5451a72@linaro.org>

On 14/02/2024 17:23, Th?o Lebrun wrote:
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  "#gpio-cells":
> +    const: 2
> +
> +  gpio-controller: true
> +
> +  interrupt-controller: true
> +
> +  "#interrupt-cells":
> +    const: 2
> +
> +  gpio-bank:
> +    $ref: /schemas/types.yaml#/definitions/uint32

Missing description, unless it is a common property (but then where do I
find it?).

> +
> +  st,supports-sleepmode:
> +    description: Whether the controller can sleep or not.
> +    $ref: /schemas/types.yaml#/definitions/flag
> +
> +  clocks:
> +    maxItems: 1
> +
> +  gpio-ranges:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - "#gpio-cells"
> +  - gpio-controller
> +  - interrupt-controller
> +  - gpio-bank


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb 15 01:12:12 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 10:12:12 +0100
Subject: [PATCH 02/23] dt-bindings: gpio: nomadik: add optional ngpios
 property
In-Reply-To: <20240214-mbly-gpio-v1-2-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-2-f88c0ccf372b@bootlin.com>
Message-ID: <51cb3592-8cf1-4c0b-9810-54c85c29995d@linaro.org>

On 14/02/2024 17:23, Th?o Lebrun wrote:
> This GPIO controller can support a lesser number of GPIOs than 32.
> Express that in devicetree using an optional, generic property.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb 15 01:13:12 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 10:13:12 +0100
Subject: [PATCH 03/23] dt-bindings: gpio: nomadik: add mobileye,eyeq5-gpio
 compatible
In-Reply-To: <20240214-mbly-gpio-v1-3-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-3-f88c0ccf372b@bootlin.com>
Message-ID: <9e19c820-c9aa-4eef-a594-f7305b03eea4@linaro.org>

On 14/02/2024 17:23, Th?o Lebrun wrote:
> This GPIO controller is used on the Mobileye EyeQ5 SoC. Add its
> compatible to the dt-bindings. One difference is that the block as
> integrated on EyeQ5 does not support sleep-mode.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  .../devicetree/bindings/gpio/st,nomadik-gpio.yaml        | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> index bbd23daed229..e44cf292bc6d 100644
> --- a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> +++ b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> @@ -19,7 +19,9 @@ properties:
>      pattern: "^gpio@[0-9a-f]+$"
>  
>    compatible:
> -    const: st,nomadik-gpio
> +    enum:
> +      - st,nomadik-gpio
> +      - mobileye,eyeq5-gpio
>  
>    reg:
>      maxItems: 1
> @@ -65,6 +67,18 @@ required:
>  
>  unevaluatedProperties: false
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: st,nomadik-gpio
> +    then:
> +      properties:
> +        st,supports-sleepmode:
> +          description: Whether the controller can sleep or not.
> +          $ref: /schemas/types.yaml#/definitions/flag

You already have such property, so you are defining it second time. You
want instead if: for eyeq5-gpio making it:
then:
  properties:
    st,supports-sleepmode: false

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb 15 01:13:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 10:13:26 +0100
Subject: [PATCH 04/23] dt-bindings: gpio: nomadik: add optional reset
 property
In-Reply-To: <20240214-mbly-gpio-v1-4-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-4-f88c0ccf372b@bootlin.com>
Message-ID: <df57330b-ae6c-4e4b-ab74-e683770736a9@linaro.org>

On 14/02/2024 17:23, Th?o Lebrun wrote:
> Add optional reset device-tree property to the Nomadik GPIO controller.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From d-gole at ti.com  Thu Feb 15 01:13:30 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Thu, 15 Feb 2024 14:43:30 +0530
Subject: [PATCH 2/3] cpufreq: ti-cpufreq: Support nvmem for chip version
In-Reply-To: <20240206145721.2418893-3-msp@baylibre.com>
References: <20240206145721.2418893-1-msp@baylibre.com>
 <20240206145721.2418893-3-msp@baylibre.com>
Message-ID: <20240215091330.bzprmfsz2dw2j7xa@dhruva>

Hi,

On Feb 06, 2024 at 15:57:20 +0100, Markus Schneider-Pargmann wrote:
> Support using nvmem-cells 'chipvariant' and 'chipspeed' instead of
> syscon. This makes it more flexible and moves more configuration into
> the devicetree.
> 
> If nvmem-cells are present, probing will fail if the configuration of
> these cells is broken. If nvmem-cells is not present syscon will be
> used.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> ---
>  drivers/cpufreq/ti-cpufreq.c | 105 ++++++++++++++++++++++-------------
>  1 file changed, 66 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
> index 46c41e2ca727..3ee72b1309f0 100644
> --- a/drivers/cpufreq/ti-cpufreq.c
> +++ b/drivers/cpufreq/ti-cpufreq.c
> @@ -10,6 +10,7 @@
>  #include <linux/io.h>
>  #include <linux/mfd/syscon.h>
>  #include <linux/module.h>
> +#include <linux/nvmem-consumer.h>
>  #include <linux/init.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> @@ -65,6 +66,7 @@ struct ti_cpufreq_soc_data {
>  
>  struct ti_cpufreq_data {
>  	struct device *cpu_dev;
> +	struct device *dev;
>  	struct device_node *opp_node;
>  	struct regmap *syscon;
>  	const struct ti_cpufreq_soc_data *soc_data;
> @@ -244,31 +246,40 @@ static struct ti_cpufreq_soc_data am625_soc_data = {
>  static int ti_cpufreq_get_efuse(struct ti_cpufreq_data *opp_data,
>  				u32 *efuse_value)
>  {
> +	struct device_node *np = opp_data->opp_node;

Umm.. slightly confused, where is *np being used?

>  	struct device *dev = opp_data->cpu_dev;
>  	u32 efuse;
>  	int ret;
>  
> -	ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset,
> -			  &efuse);
> -	if (ret == -EIO) {
> -		/* not a syscon register! */
> -		void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
> -				opp_data->soc_data->efuse_offset, 4);
> -
> -		if (!regs)
> -			return -ENOMEM;
> -		efuse = readl(regs);
> -		iounmap(regs);
> +	ret = nvmem_cell_read_u32(opp_data->dev, "chipspeed", &efuse);
> +	if (ret && (ret != -ENOENT || !opp_data->syscon))
> +		return dev_err_probe(dev, ret,
> +				     "Failed to read nvmem cell 'chipspeed': %pe",
> +				     ERR_PTR(ret));
> +
> +	if (ret) {
> +		ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset,
> +				  &efuse);
> +		if (ret == -EIO) {
> +			/* not a syscon register! */
> +			void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
> +					opp_data->soc_data->efuse_offset, 4);
> +
> +			if (!regs)
> +				return -ENOMEM;
> +			efuse = readl(regs);
> +			iounmap(regs);
> +			}
> +		else if (ret) {

else should be enough I guess, no need of elif?

> +			dev_err(dev,
> +				"Failed to read the efuse value from syscon: %d\n",
> +				ret);
> +			return ret;
>  		}
> -	else if (ret) {
> -		dev_err(dev,
> -			"Failed to read the efuse value from syscon: %d\n",
> -			ret);
> -		return ret;
> -	}
>  
> -	efuse = (efuse & opp_data->soc_data->efuse_mask);
> -	efuse >>= opp_data->soc_data->efuse_shift;
> +		efuse = (efuse & opp_data->soc_data->efuse_mask);
> +		efuse >>= opp_data->soc_data->efuse_shift;
> +	}
>  
>  	*efuse_value = opp_data->soc_data->efuse_xlate(opp_data, efuse);
>  
> @@ -285,30 +296,41 @@ static int ti_cpufreq_get_efuse(struct ti_cpufreq_data *opp_data,
>  static int ti_cpufreq_get_rev(struct ti_cpufreq_data *opp_data,
>  			      u32 *revision_value)
>  {
> +	struct device_node *np = opp_data->opp_node;

where is this used? Atleast, in this patch I don't see it...

>  	struct device *dev = opp_data->cpu_dev;
>  	u32 revision;
>  	int ret;
>  
> -	ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset,
> -			  &revision);
> -	if (ret == -EIO) {
> -		/* not a syscon register! */
> -		void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
> -				opp_data->soc_data->rev_offset, 4);
> -
> -		if (!regs)
> -			return -ENOMEM;
> -		revision = readl(regs);
> -		iounmap(regs);
> +	ret = nvmem_cell_read_u32(opp_data->dev, "chipvariant", &revision);
> +	if (ret && (ret != -ENOENT || !opp_data->syscon))
> +		return dev_err_probe(dev, ret,
> +				     "Failed to read nvmem cell 'chipvariant': %pe",
> +				     ERR_PTR(ret));
> +
> +	if (ret) {
> +		ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset,
> +				  &revision);
> +		if (ret == -EIO) {
> +			/* not a syscon register! */
> +			void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
> +					opp_data->soc_data->rev_offset, 4);
> +
> +			if (!regs)
> +				return -ENOMEM;
> +			revision = readl(regs);
> +			iounmap(regs);
> +			}
> +		else if (ret) {

Do you really have to? This code will reach only if(ret) is satisfied,
the elif feels redundant. Else should be fine

> +			dev_err(dev,
> +				"Failed to read the revision number from syscon: %d\n",
> +				ret);
> +			return ret;
>  		}
> -	else if (ret) {
> -		dev_err(dev,
> -			"Failed to read the revision number from syscon: %d\n",
> -			ret);
> -		return ret;
> +
> +		revision = (revision >> REVISION_SHIFT) & REVISION_MASK;
>  	}
>  
> -	*revision_value = BIT((revision >> REVISION_SHIFT) & REVISION_MASK);
> +	*revision_value = BIT(revision);
>  
>  	return 0;
>  }
> @@ -392,9 +414,14 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
>  		goto register_cpufreq_dt;
>  	}
>  
> -	ret = ti_cpufreq_setup_syscon_register(opp_data);
> -	if (ret)
> -		goto fail_put_node;
> +	opp_data->dev = &pdev->dev;
> +	opp_data->dev->of_node = opp_data->opp_node;
> +
> +	if (!of_property_read_bool(opp_data->opp_node, "nvmem-cells")) {
> +		ret = ti_cpufreq_setup_syscon_register(opp_data);
> +		if (ret)
> +			goto fail_put_node;
> +	}

Mostly looks okay, with above comments addressed:

Reviewed-by: Dhruva Gole <d-gole at ti.com>

-- 
Best regards,
Dhruva Gole <d-gole at ti.com>


From mihai.sain at microchip.com  Thu Feb 15 01:15:21 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Thu, 15 Feb 2024 11:15:21 +0200
Subject: [PATCH v3 0/3] Add initial support for Microchip SAMA7G54 Curiosity board
Message-ID: <20240215091524.14732-1-mihai.sain@microchip.com>

This patch series adds initial support for Microchip SAMA7G54 Curiosity board.

Changes in v3:
--------------

* Update flexcom 10 node in order to match previous flexcom definitions.
* Use alphanumerical sorting in Makefile.
* Remove adc subnode from flx10 node.
* Use C style comment.

Changes in v2:
--------------

* Remove bootargs.
* Use phandle style for clock nodes.
* Use color and function for gpio-leds.
* Remove status okay from leds, nand, eeprom, pmic, flash.
* Use generic name like pmic for mcp16502 regulator.

Mihai Sain (3):
  dt-bindings: ARM: at91: Document Microchip SAMA7G54 Curiosity
  ARM: dts: microchip: sama7g5: Add flexcom 10 node
  ARM: dts: microchip: sama7g54_curiosity: Add initial device tree of the board

 .../devicetree/bindings/arm/atmel-at91.yaml   |   6 +
 arch/arm/boot/dts/microchip/Makefile          |   2 +
 .../dts/microchip/at91-sama7g54_curiosity.dts | 482 ++++++++++++++++++
 arch/arm/boot/dts/microchip/sama7g5.dtsi      |  24 +
 4 files changed, 514 insertions(+)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts

-- 
2.43.0



From ck.hu at mediatek.com  Thu Feb 15 01:15:29 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 15 Feb 2024 09:15:29 +0000
Subject: [PATCH v6 6/9] drm/mediatek: dsi: Register DSI host after
 acquiring clocks and PHY
In-Reply-To: <20240215085316.56835-7-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
	 <20240215085316.56835-7-angelogioacchino.delregno@collabora.com>
Message-ID: <c7cd73ffaa3a330cfce03a343c4ecc6c52936040.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-02-15 at 09:53 +0100, AngeloGioacchino Del Regno wrote:
> Registering the dsi host with its ops before getting dsi->regs is
> simply wrong: even though there's nothing (for now) asynchronously
> calling those ops before the end of the probe function, installing
> ops that are using iospace(s) and clocks before even initializing
> those is too fragile.
> 
> Register the DSI host after getting clocks, iospace and PHY.
> This wil also allow to simplify the error paths in a later commit.

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

> 
> Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 28 ++++++++++++++--------------
>  1 file changed, 14 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 52758cab0abf..b3dd6251d611 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -1114,14 +1114,6 @@ static int mtk_dsi_probe(struct
> platform_device *pdev)
>  	if (!dsi)
>  		return -ENOMEM;
>  
> -	dsi->host.ops = &mtk_dsi_ops;
> -	dsi->host.dev = dev;
> -	ret = mipi_dsi_host_register(&dsi->host);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to register DSI host: %d\n", ret);
> -		return ret;
> -	}
> -
>  	dsi->driver_data = of_device_get_match_data(dev);
>  
>  	dsi->engine_clk = devm_clk_get(dev, "engine");
> @@ -1130,7 +1122,7 @@ static int mtk_dsi_probe(struct platform_device
> *pdev)
>  
>  		if (ret != -EPROBE_DEFER)
>  			dev_err(dev, "Failed to get engine clock:
> %d\n", ret);
> -		goto err_unregister_host;
> +		return ret;
>  	}
>  
>  	dsi->digital_clk = devm_clk_get(dev, "digital");
> @@ -1139,14 +1131,14 @@ static int mtk_dsi_probe(struct
> platform_device *pdev)
>  
>  		if (ret != -EPROBE_DEFER)
>  			dev_err(dev, "Failed to get digital clock:
> %d\n", ret);
> -		goto err_unregister_host;
> +		return ret;
>  	}
>  
>  	dsi->hs_clk = devm_clk_get(dev, "hs");
>  	if (IS_ERR(dsi->hs_clk)) {
>  		ret = PTR_ERR(dsi->hs_clk);
>  		dev_err(dev, "Failed to get hs clock: %d\n", ret);
> -		goto err_unregister_host;
> +		return ret;
>  	}
>  
>  	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> @@ -1154,20 +1146,28 @@ static int mtk_dsi_probe(struct
> platform_device *pdev)
>  	if (IS_ERR(dsi->regs)) {
>  		ret = PTR_ERR(dsi->regs);
>  		dev_err(dev, "Failed to ioremap memory: %d\n", ret);
> -		goto err_unregister_host;
> +		return ret;
>  	}
>  
>  	dsi->phy = devm_phy_get(dev, "dphy");
>  	if (IS_ERR(dsi->phy)) {
>  		ret = PTR_ERR(dsi->phy);
>  		dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
> -		goto err_unregister_host;
> +		return ret;
>  	}
>  
>  	irq_num = platform_get_irq(pdev, 0);
>  	if (irq_num < 0) {
>  		ret = irq_num;
> -		goto err_unregister_host;
> +		return ret;
> +	}
> +
> +	dsi->host.ops = &mtk_dsi_ops;
> +	dsi->host.dev = dev;
> +	ret = mipi_dsi_host_register(&dsi->host);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to register DSI host: %d\n", ret);
> +		return ret;
>  	}
>  
>  	ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq,

From mihai.sain at microchip.com  Thu Feb 15 01:15:22 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Thu, 15 Feb 2024 11:15:22 +0200
Subject: [PATCH v3 1/3] dt-bindings: ARM: at91: Document Microchip SAMA7G54 Curiosity
In-Reply-To: <20240215091524.14732-1-mihai.sain@microchip.com>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
Message-ID: <20240215091524.14732-2-mihai.sain@microchip.com>

Document device tree binding of the Microchip SAMA7G54 Curiosity board.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index 89d75fbb1de4..82f37328cc69 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -179,6 +179,12 @@ properties:
           - const: microchip,sama7g5
           - const: microchip,sama7
 
+      - description: Microchip SAMA7G54 Curiosity Board
+        items:
+          - const: microchip,sama7g54-curiosity
+          - const: microchip,sama7g5
+          - const: microchip,sama7
+
       - description: Microchip LAN9662 Evaluation Boards.
         items:
           - enum:
-- 
2.43.0



From mihai.sain at microchip.com  Thu Feb 15 01:15:23 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Thu, 15 Feb 2024 11:15:23 +0200
Subject: [PATCH v3 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <20240215091524.14732-1-mihai.sain@microchip.com>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
Message-ID: <20240215091524.14732-3-mihai.sain@microchip.com>

Add flexcom 10 node for usage on the SAMA7G54 Curiosity board.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/sama7g5.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
index 269e0a3ca269..c030b318985a 100644
--- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
+++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
@@ -958,6 +958,30 @@ i2c9: i2c at 600 {
 			};
 		};
 
+		flx10: flexcom at e2820000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe2820000 0x200>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe2820000 0x800>;
+			status = "disabled";
+
+			i2c10: i2c at 600 {
+				compatible = "microchip,sama7g5-i2c", "microchip,sam9x60-i2c";
+				reg = <0x600 0x200>;
+				interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
+				atmel,fifo-size = <32>;
+				dmas = <&dma0 AT91_XDMAC_DT_PERID(26)>,
+					<&dma0 AT91_XDMAC_DT_PERID(25)>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+		};
+
 		flx11: flexcom at e2824000 {
 			compatible = "atmel,sama5d2-flexcom";
 			reg = <0xe2824000 0x200>;
-- 
2.43.0



From mihai.sain at microchip.com  Thu Feb 15 01:15:24 2024
From: mihai.sain at microchip.com (Mihai Sain)
Date: Thu, 15 Feb 2024 11:15:24 +0200
Subject: [PATCH v3 3/3] ARM: dts: microchip: sama7g54_curiosity: Add initial device tree of the board
In-Reply-To: <20240215091524.14732-1-mihai.sain@microchip.com>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
Message-ID: <20240215091524.14732-4-mihai.sain@microchip.com>

Add initial device tree of the SAMA7G54 Curiosity board.

Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
---
 arch/arm/boot/dts/microchip/Makefile          |   2 +
 .../dts/microchip/at91-sama7g54_curiosity.dts | 482 ++++++++++++++++++
 2 files changed, 484 insertions(+)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts

diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
index efde9546c8f4..0c45c8d17468 100644
--- a/arch/arm/boot/dts/microchip/Makefile
+++ b/arch/arm/boot/dts/microchip/Makefile
@@ -11,6 +11,7 @@ DTC_FLAGS_at91-sama5d2_xplained := -@
 DTC_FLAGS_at91-sama5d3_eds := -@
 DTC_FLAGS_at91-sama5d3_xplained := -@
 DTC_FLAGS_at91-sama5d4_xplained := -@
+DTC_FLAGS_at91-sama7g54_curiosity := -@
 DTC_FLAGS_at91-sama7g5ek := -@
 dtb-$(CONFIG_SOC_AT91RM9200) += \
 	at91rm9200ek.dtb \
@@ -87,6 +88,7 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
 	at91-sama5d4ek.dtb \
 	at91-vinco.dtb
 dtb-$(CONFIG_SOC_SAMA7G5) += \
+	at91-sama7g54_curiosity.dtb \
 	at91-sama7g5ek.dtb
 
 dtb-$(CONFIG_SOC_LAN966) += \
diff --git a/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
new file mode 100644
index 000000000000..4f609e9e510e
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
@@ -0,0 +1,482 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sama7g54_curiosity.dts - Device Tree file for SAMA7G54 Curiosity Board
+ *
+ * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Mihai Sain <mihai.sain at microchip.com>
+ *
+ */
+/dts-v1/;
+#include "sama7g5-pinfunc.h"
+#include "sama7g5.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/pinctrl/at91.h>
+
+/ {
+	model = "Microchip SAMA7G54 Curiosity";
+	compatible = "microchip,sama7g54-curiosity", "microchip,sama7g5", "microchip,sama7";
+
+	aliases {
+		serial0 = &uart3;
+		i2c0 = &i2c10;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_key_gpio_default>;
+
+		button-user {
+			label = "user-button";
+			gpios = <&pioA PIN_PD19 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_PROG1>;
+			wakeup-source;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_led_gpio_default>;
+
+		led-red {
+			color = <LED_COLOR_ID_RED>;
+			function = LED_FUNCTION_POWER;
+			gpios = <&pioA PIN_PD13 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		led-green {
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_BOOT;
+			gpios = <&pioA PIN_PD14 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		led-blue {
+			color = <LED_COLOR_ID_BLUE>;
+			function = LED_FUNCTION_CPU;
+			gpios = <&pioA PIN_PB15 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x10000000>; /* 256 MiB DDR3L-1066 16-bit */
+	};
+};
+
+&adc {
+	vddana-supply = <&vddout25>;
+	vref-supply = <&vddout25>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_mikrobus1_an_default &pinctrl_mikrobus2_an_default>;
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vddcpu>;
+};
+
+&dma0 {
+	status = "okay";
+};
+
+&dma1 {
+	status = "okay";
+};
+
+&dma2 {
+	status = "okay";
+};
+
+&ebi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_nand_default>;
+	status = "okay";
+
+	nand_controller: nand-controller {
+		status = "okay";
+
+		nand at 3 {
+			reg = <0x3 0x0 0x800000>;
+			atmel,rb = <0>;
+			nand-bus-width = <8>;
+			nand-ecc-mode = "hw";
+			nand-ecc-strength = <8>;
+			nand-ecc-step-size = <512>;
+			nand-on-flash-bbt;
+			label = "nand";
+
+			partitions {
+				compatible = "fixed-partitions";
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				at91bootstrap at 0 {
+					label = "nand: at91bootstrap";
+					reg = <0x0 0x40000>;
+				};
+
+				bootloader at 40000 {
+					label = "nand: u-boot";
+					reg = <0x40000 0x100000>;
+				};
+
+				bootloaderenv at 140000 {
+					label = "nand: u-boot env";
+					reg = <0x140000 0x40000>;
+				};
+
+				dtb at 180000 {
+					label = "nand: device tree";
+					reg = <0x180000 0x80000>;
+				};
+
+				kernel at 200000 {
+					label = "nand: kernel";
+					reg = <0x200000 0x600000>;
+				};
+
+				rootfs at 800000 {
+					label = "nand: rootfs";
+					reg = <0x800000 0x1f800000>;
+				};
+			};
+		};
+	};
+};
+
+&flx3 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+	status = "okay";
+
+	uart3: serial at 200 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flx3_default>;
+		status = "okay";
+	};
+};
+
+&flx10 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
+	status = "okay";
+
+	i2c10: i2c at 600 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_flx10_default>;
+		i2c-analog-filter;
+		i2c-digital-filter;
+		i2c-digital-filter-width-ns = <35>;
+		status = "okay";
+
+		eeprom at 51 {
+			compatible = "atmel,24c02";
+			reg = <0x51>;
+			pagesize = <16>;
+			size = <256>;
+			vcc-supply = <&vdd_3v3>;
+		};
+
+		pmic at 5b {
+			compatible = "microchip,mcp16502";
+			reg = <0x5b>;
+
+			regulators {
+				vdd_3v3: VDD_IO {
+					regulator-name = "VDD_IO";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-microvolt = <3300000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+						regulator-mode = <4>;
+					};
+				};
+
+				vddioddr: VDD_DDR {
+					regulator-name = "VDD_DDR";
+					regulator-min-microvolt = <1350000>;
+					regulator-max-microvolt = <1350000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-microvolt = <1350000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-on-in-suspend;
+						regulator-suspend-microvolt = <1350000>;
+						regulator-mode = <4>;
+					};
+				};
+
+				vddcore: VDD_CORE {
+					regulator-name = "VDD_CORE";
+					regulator-min-microvolt = <1150000>;
+					regulator-max-microvolt = <1150000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-voltage = <1150000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+						regulator-mode = <4>;
+					};
+				};
+
+				vddcpu: VDD_OTHER {
+					regulator-name = "VDD_OTHER";
+					regulator-min-microvolt = <1050000>;
+					regulator-max-microvolt = <1250000>;
+					regulator-initial-mode = <2>;
+					regulator-allowed-modes = <2>, <4>;
+					regulator-ramp-delay = <3125>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-on-in-suspend;
+						regulator-suspend-voltage = <1050000>;
+						regulator-mode = <4>;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+						regulator-mode = <4>;
+					};
+				};
+
+				vldo1: LDO1 {
+					regulator-name = "LDO1";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-suspend-voltage = <1800000>;
+						regulator-on-in-suspend;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+					};
+				};
+
+				vldo2: LDO2 {
+					regulator-name = "LDO2";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-always-on;
+
+					regulator-state-standby {
+						regulator-suspend-voltage = <3300000>;
+						regulator-on-in-suspend;
+					};
+
+					regulator-state-mem {
+						regulator-off-in-suspend;
+					};
+				};
+			};
+		};
+	};
+};
+
+&main_xtal {
+	clock-frequency = <24000000>;
+};
+
+&qspi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_qspi1_default>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-max-frequency = <100000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+		m25p,fast-read;
+	};
+};
+
+&pioA {
+	pinctrl_flx3_default: flx3-default {
+		pinmux = <PIN_PD16__FLEXCOM3_IO0>,
+			 <PIN_PD17__FLEXCOM3_IO1>;
+		bias-pull-up;
+	};
+
+	pinctrl_flx10_default: flx10-default {
+		pinmux = <PIN_PC30__FLEXCOM10_IO0>,
+			 <PIN_PC31__FLEXCOM10_IO1>;
+		bias-pull-up;
+	};
+
+	pinctrl_key_gpio_default: key-gpio-default {
+		pinmux = <PIN_PD19__GPIO>;
+		bias-pull-up;
+	};
+
+	pinctrl_led_gpio_default: led-gpio-default {
+		pinmux = <PIN_PD13__GPIO>,
+			 <PIN_PD14__GPIO>,
+			 <PIN_PB15__GPIO>;
+		bias-pull-up;
+	};
+
+	pinctrl_mikrobus1_an_default: mikrobus1-an-default {
+		pinmux = <PIN_PC15__GPIO>;
+		bias-disable;
+	};
+
+	pinctrl_mikrobus2_an_default: mikrobus2-an-default {
+		pinmux = <PIN_PC13__GPIO>;
+		bias-disable;
+	};
+
+	pinctrl_nand_default: nand-default {
+		pinmux = <PIN_PD9__D0>,
+			 <PIN_PD10__D1>,
+			 <PIN_PD11__D2>,
+			 <PIN_PC21__D3>,
+			 <PIN_PC22__D4>,
+			 <PIN_PC23__D5>,
+			 <PIN_PC24__D6>,
+			 <PIN_PD2__D7>,
+			 <PIN_PD3__NANDRDY>,
+			 <PIN_PD4__NCS3_NANDCS>,
+			 <PIN_PD5__NWE_NWR0_NANDWE>,
+			 <PIN_PD6__NRD_NANDOE>,
+			 <PIN_PD7__A21_NANDALE>,
+			 <PIN_PD8__A22_NANDCLE>;
+		bias-disable;
+		slew-rate = <0>;
+	};
+
+	pinctrl_qspi1_default: qspi1-default {
+		pinmux = <PIN_PB22__QSPI1_IO3>,
+			 <PIN_PB23__QSPI1_IO2>,
+			 <PIN_PB24__QSPI1_IO1>,
+			 <PIN_PB25__QSPI1_IO0>,
+			 <PIN_PB26__QSPI1_CS>,
+			 <PIN_PB27__QSPI1_SCK>;
+		bias-pull-up;
+		slew-rate = <0>;
+	};
+
+	pinctrl_sdmmc0_default: sdmmc0-default {
+		pinmux = <PIN_PA0__SDMMC0_CK>,
+			 <PIN_PA1__SDMMC0_CMD>,
+			 <PIN_PA2__SDMMC0_RSTN>,
+			 <PIN_PA3__SDMMC0_DAT0>,
+			 <PIN_PA4__SDMMC0_DAT1>,
+			 <PIN_PA5__SDMMC0_DAT2>,
+			 <PIN_PA6__SDMMC0_DAT3>;
+		bias-pull-up;
+		slew-rate = <0>;
+	};
+
+	pinctrl_sdmmc1_default: sdmmc1-default {
+		pinmux = <PIN_PB29__SDMMC1_CMD>,
+			 <PIN_PB30__SDMMC1_CK>,
+			 <PIN_PB31__SDMMC1_DAT0>,
+			 <PIN_PC0__SDMMC1_DAT1>,
+			 <PIN_PC1__SDMMC1_DAT2>,
+			 <PIN_PC2__SDMMC1_DAT3>,
+			 <PIN_PC4__SDMMC1_CD>;
+		bias-pull-up;
+		slew-rate = <0>;
+	};
+};
+
+&rtt {
+	atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
+};
+
+/* M.2 slot for wireless card */
+&sdmmc0 {
+	bus-width = <4>;
+	cd-gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	sdhci-caps-mask = <0x0 0x00200000>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc0_default>;
+	status = "okay";
+};
+
+/* micro SD socket */
+&sdmmc1 {
+	bus-width = <4>;
+	disable-wp;
+	sdhci-caps-mask = <0x0 0x00200000>;
+	vmmc-supply = <&vdd_3v3>;
+	vqmmc-supply = <&vdd_3v3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc1_default>;
+	status = "okay";
+};
+
+&slow_xtal {
+	clock-frequency = <32768>;
+};
+
+&shdwc {
+	debounce-delay-us = <976>;
+	status = "okay";
+
+	input at 0 {
+		reg = <0>;
+	};
+};
+
+&tcb0 {
+	timer0: timer at 0 {
+		compatible = "atmel,tcb-timer";
+		reg = <0>;
+	};
+
+	timer1: timer at 1 {
+		compatible = "atmel,tcb-timer";
+		reg = <1>;
+	};
+};
+
+&trng {
+	status = "okay";
+};
+
+&vddout25 {
+	vin-supply = <&vdd_3v3>;
+	status = "okay";
+};
-- 
2.43.0



From ck.hu at mediatek.com  Thu Feb 15 01:17:21 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 15 Feb 2024 09:17:21 +0000
Subject: [PATCH v6 7/9] drm/mediatek: dsi: Simplify with dev_err_probe and
 remove gotos
In-Reply-To: <20240215085316.56835-8-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
	 <20240215085316.56835-8-angelogioacchino.delregno@collabora.com>
Message-ID: <c18471671dbac2b9018950af105d39a15d8ea68d.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-02-15 at 09:53 +0100, AngeloGioacchino Del Regno wrote:
> Most of the functions that are called in the probe callback are
> devm managed, or all but mipi_dsi_host_register(): simplify the probe
> function's error paths with dev_err_probe() and remove the lonely
> instance of `goto err_unregister_host` by just directly calling the
> mipi_dsi_host_unregister() function in the devm_request_irq() error
> path, allowing to also remove the same label.

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

> 
> Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 60 +++++++++-------------------
> --
>  1 file changed, 18 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index b3dd6251d611..195ff4dfc3a3 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -1117,64 +1117,44 @@ static int mtk_dsi_probe(struct
> platform_device *pdev)
>  	dsi->driver_data = of_device_get_match_data(dev);
>  
>  	dsi->engine_clk = devm_clk_get(dev, "engine");
> -	if (IS_ERR(dsi->engine_clk)) {
> -		ret = PTR_ERR(dsi->engine_clk);
> +	if (IS_ERR(dsi->engine_clk))
> +		return dev_err_probe(dev, PTR_ERR(dsi->engine_clk),
> +				     "Failed to get engine clock\n");
>  
> -		if (ret != -EPROBE_DEFER)
> -			dev_err(dev, "Failed to get engine clock:
> %d\n", ret);
> -		return ret;
> -	}
>  
>  	dsi->digital_clk = devm_clk_get(dev, "digital");
> -	if (IS_ERR(dsi->digital_clk)) {
> -		ret = PTR_ERR(dsi->digital_clk);
> -
> -		if (ret != -EPROBE_DEFER)
> -			dev_err(dev, "Failed to get digital clock:
> %d\n", ret);
> -		return ret;
> -	}
> +	if (IS_ERR(dsi->digital_clk))
> +		return dev_err_probe(dev, PTR_ERR(dsi->digital_clk),
> +				     "Failed to get digital clock\n");
>  
>  	dsi->hs_clk = devm_clk_get(dev, "hs");
> -	if (IS_ERR(dsi->hs_clk)) {
> -		ret = PTR_ERR(dsi->hs_clk);
> -		dev_err(dev, "Failed to get hs clock: %d\n", ret);
> -		return ret;
> -	}
> +	if (IS_ERR(dsi->hs_clk))
> +		return dev_err_probe(dev, PTR_ERR(dsi->hs_clk), "Failed
> to get hs clock\n");
>  
>  	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	dsi->regs = devm_ioremap_resource(dev, regs);
> -	if (IS_ERR(dsi->regs)) {
> -		ret = PTR_ERR(dsi->regs);
> -		dev_err(dev, "Failed to ioremap memory: %d\n", ret);
> -		return ret;
> -	}
> +	if (IS_ERR(dsi->regs))
> +		return dev_err_probe(dev, PTR_ERR(dsi->regs), "Failed
> to ioremap memory\n");
>  
>  	dsi->phy = devm_phy_get(dev, "dphy");
> -	if (IS_ERR(dsi->phy)) {
> -		ret = PTR_ERR(dsi->phy);
> -		dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
> -		return ret;
> -	}
> +	if (IS_ERR(dsi->phy))
> +		return dev_err_probe(dev, PTR_ERR(dsi->phy), "Failed to
> get MIPI-DPHY\n");
>  
>  	irq_num = platform_get_irq(pdev, 0);
> -	if (irq_num < 0) {
> -		ret = irq_num;
> -		return ret;
> -	}
> +	if (irq_num < 0)
> +		return irq_num;
>  
>  	dsi->host.ops = &mtk_dsi_ops;
>  	dsi->host.dev = dev;
>  	ret = mipi_dsi_host_register(&dsi->host);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to register DSI host: %d\n", ret);
> -		return ret;
> -	}
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "Failed to register DSI
> host\n");
>  
>  	ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq,
>  			       IRQF_TRIGGER_NONE, dev_name(&pdev->dev), 
> dsi);
>  	if (ret) {
> -		dev_err(&pdev->dev, "failed to request mediatek dsi
> irq\n");
> -		goto err_unregister_host;
> +		mipi_dsi_host_unregister(&dsi->host);
> +		return dev_err_probe(&pdev->dev, ret, "Failed to
> request DSI irq\n");
>  	}
>  
>  	init_waitqueue_head(&dsi->irq_wait_queue);
> @@ -1186,10 +1166,6 @@ static int mtk_dsi_probe(struct
> platform_device *pdev)
>  	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>  
>  	return 0;
> -
> -err_unregister_host:
> -	mipi_dsi_host_unregister(&dsi->host);
> -	return ret;
>  }
>  
>  static void mtk_dsi_remove(struct platform_device *pdev)

From neil.armstrong at linaro.org  Thu Feb 15 01:20:22 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 15 Feb 2024 10:20:22 +0100
Subject: [PATCH v2 0/6] drm/msm: Add support for the A750 GPU found on the
 SM8650 platform
Message-ID: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>

Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
doesn't have an HWCFG block but a separate register set.

The missing registers are added in the a6xx.xml.h file that would
require a subsequent sync and the non-existent hwcfg is handled
in a6xx_set_hwcg().

The A750 GPU info are added under the adreno_is_a750() macro and
the ADRENO_7XX_GEN3 family id.

This adds:
- the GMU and SMMU bindings
- DRM driver changes
- DT nodes

Dependencies: None

Tested using Mesa's !26934 Merge Request [0] on the SM8650-QRD
and with kmscube & vkcube to test basic rendering.

[0] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26934

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
Changes in v2:
- Added separate a6xx.xml.h sync from https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27576
- Collected review tags
- Inlined skip_programming
- Use A7XX_RBBM_CGC_P2S_STATUS_TXDONE instead of BIT(0)
- Drop now useless placeholder comment
- Removed interconnect properties
- Rebased on current linux-next
- Link to v1: https://lore.kernel.org/r/20240212-topic-sm8650-gpu-v1-0-708a40b747b5 at linaro.org

---
Neil Armstrong (6):
      dt-bindings: display/msm/gmu: Document Adreno 750 GMU
      dt-bindings: arm-smmu: Document SM8650 GPU SMMU
      drm/msm/a6xx: Add missing regs for A750
      drm/msm: add support for A750 GPU
      arm64: dts: qcom: sm8650: add GPU nodes
      arm64: dts: qcom: sm8650-qrd: enable GPU

 .../devicetree/bindings/display/msm/gmu.yaml       |   1 +
 .../devicetree/bindings/iommu/arm,smmu.yaml        |   7 +-
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts            |   8 +
 arch/arm64/boot/dts/qcom/sm8650.dtsi               | 166 +++++++++++++++++++++
 drivers/gpu/drm/msm/adreno/a6xx.xml.h              |   9 ++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c              |   2 +
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c              |  28 +++-
 drivers/gpu/drm/msm/adreno/adreno_device.c         |  14 ++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h            |  10 +-
 9 files changed, 238 insertions(+), 7 deletions(-)
---
base-commit: 5a30f6bdb84228f160b331eed2ccfde00bfb3ab4
change-id: 20240208-topic-sm8650-gpu-489d5e2c2b17

Best regards,
-- 
Neil Armstrong <neil.armstrong at linaro.org>



From neil.armstrong at linaro.org  Thu Feb 15 01:20:23 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 15 Feb 2024 10:20:23 +0100
Subject: [PATCH v2 1/6] dt-bindings: display/msm/gmu: Document Adreno 750
 GMU
In-Reply-To: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
Message-ID: <20240215-topic-sm8650-gpu-v2-1-6be0b4bf2e09@linaro.org>

Document the Adreno 750 GMU found on the SM8650 platform.

Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>
Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 Documentation/devicetree/bindings/display/msm/gmu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml b/Documentation/devicetree/bindings/display/msm/gmu.yaml
index 4e1c25b42908..b3837368a260 100644
--- a/Documentation/devicetree/bindings/display/msm/gmu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml
@@ -224,6 +224,7 @@ allOf:
             enum:
               - qcom,adreno-gmu-730.1
               - qcom,adreno-gmu-740.1
+              - qcom,adreno-gmu-750.1
     then:
       properties:
         reg:

-- 
2.34.1



From neil.armstrong at linaro.org  Thu Feb 15 01:20:24 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 15 Feb 2024 10:20:24 +0100
Subject: [PATCH v2 2/6] dt-bindings: arm-smmu: Document SM8650 GPU SMMU
In-Reply-To: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
Message-ID: <20240215-topic-sm8650-gpu-v2-2-6be0b4bf2e09@linaro.org>

Document the GPU SMMU found on the SM8650 platform.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index a4042ae24770..3ad5c850f3bf 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -93,6 +93,7 @@ properties:
               - qcom,sm8350-smmu-500
               - qcom,sm8450-smmu-500
               - qcom,sm8550-smmu-500
+              - qcom,sm8650-smmu-500
           - const: qcom,adreno-smmu
           - const: qcom,smmu-500
           - const: arm,mmu-500
@@ -508,7 +509,10 @@ allOf:
   - if:
       properties:
         compatible:
-          const: qcom,sm8550-smmu-500
+          contains:
+            enum:
+              - qcom,sm8550-smmu-500
+              - qcom,sm8650-smmu-500
     then:
       properties:
         clock-names:
@@ -544,7 +548,6 @@ allOf:
               - qcom,sdx65-smmu-500
               - qcom,sm6350-smmu-500
               - qcom,sm6375-smmu-500
-              - qcom,sm8650-smmu-500
               - qcom,x1e80100-smmu-500
     then:
       properties:

-- 
2.34.1



From neil.armstrong at linaro.org  Thu Feb 15 01:20:25 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 15 Feb 2024 10:20:25 +0100
Subject: [PATCH v2 3/6] drm/msm/a6xx: Add missing regs for A750
In-Reply-To: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
Message-ID: <20240215-topic-sm8650-gpu-v2-3-6be0b4bf2e09@linaro.org>

Sync missing regs for A750 clock gating control related registers
from Mesa a6xx.xml.h generated file.

Those registers were added in the !27576 merge request [1].

[1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27576

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/gpu/drm/msm/adreno/a6xx.xml.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
index 863b5e3b0e67..58877464692a 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
@@ -1725,6 +1725,8 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00
 
 #define REG_A6XX_RBBM_BLOCK_SW_RESET_CMD2			0x00000046
 
+#define REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL				0x000000ad
+
 #define REG_A6XX_RBBM_CLOCK_CNTL				0x000000ae
 
 #define REG_A6XX_RBBM_CLOCK_CNTL_SP0				0x000000b0
@@ -1939,12 +1941,19 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00
 
 #define REG_A6XX_RBBM_CLOCK_HYST_HLSQ				0x0000011d
 
+#define REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD			0x0000011e
+
+#define REG_A7XX_RBBM_CGC_P2S_TRIG_CMD				0x0000011f
+
 #define REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE			0x00000120
 
 #define REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE			0x00000121
 
 #define REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE			0x00000122
 
+#define REG_A7XX_RBBM_CGC_P2S_STATUS				0x00000122
+#define A7XX_RBBM_CGC_P2S_STATUS_TXDONE				0x00000001
+
 #define REG_A7XX_RBBM_CLOCK_HYST2_VFD				0x0000012f
 
 #define REG_A6XX_RBBM_LPAC_GBIF_CLIENT_QOS_CNTL			0x000005ff

-- 
2.34.1



From neil.armstrong at linaro.org  Thu Feb 15 01:20:26 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 15 Feb 2024 10:20:26 +0100
Subject: [PATCH v2 4/6] drm/msm: add support for A750 GPU
In-Reply-To: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
Message-ID: <20240215-topic-sm8650-gpu-v2-4-6be0b4bf2e09@linaro.org>

Add support for the A750 GPU found on the SM8650 platform

Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
doesn't have an HWCFG block but a separate register set.

The A750 GPU info are added under the adreno_is_a750() macro and
the ADRENO_7XX_GEN3 family id.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c      |  2 ++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c      | 28 +++++++++++++++++++++++++---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++++++++++++++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h    | 10 ++++++++--
 4 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 8c4900444b2c..325881d8ff08 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -842,6 +842,8 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
 		 */
 		if (adreno_is_a740(adreno_gpu))
 			chipid_min = 2;
+		else if (adreno_is_a750(adreno_gpu))
+			chipid_min = 9;
 		else
 			return -EINVAL;
 
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c9c55e2ea584..475b601a48ee 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -961,7 +961,7 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 	unsigned int i;
 	u32 val, clock_cntl_on, cgc_mode;
 
-	if (!adreno_gpu->info->hwcg)
+	if (!(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu)))
 		return;
 
 	if (adreno_is_a630(adreno_gpu))
@@ -982,6 +982,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 			  state ? 0x5555 : 0);
 	}
 
+	if (!adreno_gpu->info->hwcg) {
+		gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
+		gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
+
+		if (state) {
+			gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
+
+			if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
+					     val & A7XX_RBBM_CGC_P2S_STATUS_TXDONE, 1, 10)) {
+				dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
+				return;
+			}
+
+			gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
+		}
+
+		return;
+	}
+
 	val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
 
 	/* Don't re-program the registers if they are already correct */
@@ -1239,7 +1258,9 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu)
 		count = ARRAY_SIZE(a660_protect);
 		count_max = 48;
 		BUILD_BUG_ON(ARRAY_SIZE(a660_protect) > 48);
-	} else if (adreno_is_a730(adreno_gpu) || adreno_is_a740(adreno_gpu)) {
+	} else if (adreno_is_a730(adreno_gpu) ||
+		   adreno_is_a740(adreno_gpu) ||
+		   adreno_is_a750(adreno_gpu)) {
 		regs = a730_protect;
 		count = ARRAY_SIZE(a730_protect);
 		count_max = 48;
@@ -2880,7 +2901,8 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
 
 	/* gpu->info only gets assigned in adreno_gpu_init() */
 	is_a7xx = config->info->family == ADRENO_7XX_GEN1 ||
-		  config->info->family == ADRENO_7XX_GEN2;
+		  config->info->family == ADRENO_7XX_GEN2 ||
+		  config->info->family == ADRENO_7XX_GEN3;
 
 	a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 2ce7d7b1690d..e2582c91d7e7 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -522,6 +522,20 @@ static const struct adreno_info gpulist[] = {
 		.zapfw = "a740_zap.mdt",
 		.hwcg = a740_hwcg,
 		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */
+		.family = ADRENO_7XX_GEN3,
+		.fw = {
+			[ADRENO_FW_SQE] = "gen70900_sqe.fw",
+			[ADRENO_FW_GMU] = "gmu_gen70900.bin",
+		},
+		.gmem = 3 * SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "gen70900_zap.mbn",
+		.address_space_size = SZ_16G,
 	},
 };
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index bc14df96feb0..9e9415df2cea 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -48,6 +48,7 @@ enum adreno_family {
 	ADRENO_6XX_GEN4,  /* a660 family */
 	ADRENO_7XX_GEN1,  /* a730 family */
 	ADRENO_7XX_GEN2,  /* a740 family */
+	ADRENO_7XX_GEN3,  /* a750 family */
 };
 
 #define ADRENO_QUIRK_TWO_PASS_USE_WFI		BIT(0)
@@ -423,12 +424,17 @@ static inline int adreno_is_a740(struct adreno_gpu *gpu)
 	return gpu->info->chip_ids[0] == 0x43050a01;
 }
 
-/* Placeholder to make future diffs smaller */
+static inline int adreno_is_a750(struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x43051401;
+}
+
 static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
 {
 	if (WARN_ON_ONCE(!gpu->info))
 		return false;
-	return gpu->info->family == ADRENO_7XX_GEN2;
+	return gpu->info->family == ADRENO_7XX_GEN2 ||
+	       gpu->info->family == ADRENO_7XX_GEN3;
 }
 
 static inline int adreno_is_a7xx(struct adreno_gpu *gpu)

-- 
2.34.1



From neil.armstrong at linaro.org  Thu Feb 15 01:20:27 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 15 Feb 2024 10:20:27 +0100
Subject: [PATCH v2 5/6] arm64: dts: qcom: sm8650: add GPU nodes
In-Reply-To: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
Message-ID: <20240215-topic-sm8650-gpu-v2-5-6be0b4bf2e09@linaro.org>

Add GPU nodes for the SM8650 platform.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/boot/dts/qcom/sm8650.dtsi | 166 +++++++++++++++++++++++++++++++++++
 1 file changed, 166 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
index 62e6ae93a9a8..27dcef27b6ad 100644
--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -2589,6 +2589,128 @@ tcsr: clock-controller at 1fc0000 {
 			#reset-cells = <1>;
 		};
 
+		gpu: gpu at 3d00000 {
+			compatible = "qcom,adreno-43051401", "qcom,adreno";
+			reg = <0x0 0x03d00000 0x0 0x40000>,
+			      <0x0 0x03d9e000 0x0 0x1000>,
+			      <0x0 0x03d61000 0x0 0x800>;
+			reg-names = "kgsl_3d0_reg_memory",
+				    "cx_mem",
+				    "cx_dbgc";
+
+			interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+
+			iommus = <&adreno_smmu 0 0x0>,
+				 <&adreno_smmu 1 0x0>;
+
+			operating-points-v2 = <&gpu_opp_table>;
+
+			qcom,gmu = <&gmu>;
+
+			status = "disabled";
+
+			zap-shader {
+				memory-region = <&gpu_micro_code_mem>;
+			};
+
+			/* Speedbin needs more work on A740+, keep only lower freqs */
+			gpu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-680000000 {
+					opp-hz = /bits/ 64 <680000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+				};
+
+				opp-629000000 {
+					opp-hz = /bits/ 64 <629000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+				};
+
+				opp-578000000 {
+					opp-hz = /bits/ 64 <578000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+				};
+
+				opp-500000000 {
+					opp-hz = /bits/ 64 <500000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+				};
+
+				opp-422000000 {
+					opp-hz = /bits/ 64 <422000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+				};
+
+				opp-366000000 {
+					opp-hz = /bits/ 64 <366000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+				};
+
+				opp-310000000 {
+					opp-hz = /bits/ 64 <310000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+				};
+
+				opp-231000000 {
+					opp-hz = /bits/ 64 <231000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+				};
+			};
+		};
+
+		gmu: gmu at 3d6a000 {
+			compatible = "qcom,adreno-gmu-750.1", "qcom,adreno-gmu";
+			reg = <0x0 0x03d6a000 0x0 0x35000>,
+			      <0x0 0x03d50000 0x0 0x10000>,
+			      <0x0 0x0b280000 0x0 0x10000>;
+			reg-names = "gmu", "rscc", "gmu_pdc";
+
+			interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hfi", "gmu";
+
+			clocks = <&gpucc GPU_CC_AHB_CLK>,
+				 <&gpucc GPU_CC_CX_GMU_CLK>,
+				 <&gpucc GPU_CC_CXO_CLK>,
+				 <&gcc GCC_DDRSS_GPU_AXI_CLK>,
+				 <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gpucc GPU_CC_HUB_CX_INT_CLK>,
+				 <&gpucc GPU_CC_DEMET_CLK>;
+			clock-names = "ahb",
+				      "gmu",
+				      "cxo",
+				      "axi",
+				      "memnoc",
+				      "hub",
+				      "demet";
+
+			power-domains = <&gpucc GPU_CX_GDSC>,
+					<&gpucc GPU_GX_GDSC>;
+			power-domain-names = "cx",
+					     "gx";
+
+			iommus = <&adreno_smmu 5 0x0>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			operating-points-v2 = <&gmu_opp_table>;
+
+			gmu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-625000000 {
+					opp-hz = /bits/ 64 <625000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+				};
+
+				opp-260000000 {
+					opp-hz = /bits/ 64 <260000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+				};
+			};
+		};
+
 		gpucc: clock-controller at 3d90000 {
 			compatible = "qcom,sm8650-gpucc";
 			reg = <0 0x03d90000 0 0xa000>;
@@ -2602,6 +2724,50 @@ gpucc: clock-controller at 3d90000 {
 			#power-domain-cells = <1>;
 		};
 
+		adreno_smmu: iommu at 3da0000 {
+			compatible = "qcom,sm8650-smmu-500", "qcom,adreno-smmu",
+				     "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x03da0000 0x0 0x40000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <1>;
+			interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 659 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 661 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 664 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 668 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 699 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+				 <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+				 <&gpucc GPU_CC_AHB_CLK>;
+			clock-names = "hlos",
+				      "bus",
+				      "iface",
+				      "ahb";
+			power-domains = <&gpucc GPU_CX_GDSC>;
+			dma-coherent;
+		};
+
 		ipa: ipa at 3f40000 {
 			compatible = "qcom,sm8650-ipa", "qcom,sm8550-ipa";
 

-- 
2.34.1



From neil.armstrong at linaro.org  Thu Feb 15 01:20:28 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 15 Feb 2024 10:20:28 +0100
Subject: [PATCH v2 6/6] arm64: dts: qcom: sm8650-qrd: enable GPU
In-Reply-To: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
Message-ID: <20240215-topic-sm8650-gpu-v2-6-6be0b4bf2e09@linaro.org>

Add path of the GPU firmware for the SM8650-QRD board

Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>
Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
index b07cac2e5bc8..dc91f0bf4b8c 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
@@ -766,6 +766,14 @@ &ipa {
 	status = "okay";
 };
 
+&gpu {
+	status = "okay";
+
+	zap-shader {
+		firmware-name = "qcom/sm8650/gen70900_zap.mbn";
+	};
+};
+
 &lpass_tlmm {
 	spkr_1_sd_n_active: spkr-1-sd-n-active-state {
 		pins = "gpio21";

-- 
2.34.1



From ck.hu at mediatek.com  Thu Feb 15 01:20:45 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 15 Feb 2024 09:20:45 +0000
Subject: [PATCH v6 8/9] drm/mediatek: dsi: Compress of_device_id entries
 and add sentinel
In-Reply-To: <20240215085316.56835-9-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
	 <20240215085316.56835-9-angelogioacchino.delregno@collabora.com>
Message-ID: <d491ddeba2f0ffad7360899a5c0f247af2f21681.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-02-15 at 09:53 +0100, AngeloGioacchino Del Regno wrote:
> All entries fit in 82 columns, which is acceptable: compress all of
> the mtk_dsi_of_match[] entries to a single line for each.
> 
> While at it, also add the usual sentinel comment to the last entry.

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

> 
> Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 17 ++++++-----------
>  1 file changed, 6 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 195ff4dfc3a3..b644505de98a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -1204,17 +1204,12 @@ static const struct mtk_dsi_driver_data
> mt8188_dsi_driver_data = {
>  };
>  
>  static const struct of_device_id mtk_dsi_of_match[] = {
> -	{ .compatible = "mediatek,mt2701-dsi",
> -	  .data = &mt2701_dsi_driver_data },
> -	{ .compatible = "mediatek,mt8173-dsi",
> -	  .data = &mt8173_dsi_driver_data },
> -	{ .compatible = "mediatek,mt8183-dsi",
> -	  .data = &mt8183_dsi_driver_data },
> -	{ .compatible = "mediatek,mt8186-dsi",
> -	  .data = &mt8186_dsi_driver_data },
> -	{ .compatible = "mediatek,mt8188-dsi",
> -	  .data = &mt8188_dsi_driver_data },
> -	{ },
> +	{ .compatible = "mediatek,mt2701-dsi", .data =
> &mt2701_dsi_driver_data },
> +	{ .compatible = "mediatek,mt8173-dsi", .data =
> &mt8173_dsi_driver_data },
> +	{ .compatible = "mediatek,mt8183-dsi", .data =
> &mt8183_dsi_driver_data },
> +	{ .compatible = "mediatek,mt8186-dsi", .data =
> &mt8186_dsi_driver_data },
> +	{ .compatible = "mediatek,mt8188-dsi", .data =
> &mt8188_dsi_driver_data },
> +	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, mtk_dsi_of_match);
>  

From sakari.ailus at iki.fi  Thu Feb 15 01:21:01 2024
From: sakari.ailus at iki.fi (Sakari Ailus)
Date: Thu, 15 Feb 2024 09:21:01 +0000
Subject: [PATCH v4 3/5] media: platform: mediatek: isp_30: add mediatek
 ISP3.0 sensor interface
In-Reply-To: <20240110141443.364655-4-jstephan@baylibre.com>
References: <20240110141443.364655-1-jstephan@baylibre.com>
 <20240110141443.364655-4-jstephan@baylibre.com>
Message-ID: <Zc3XfbuwR3e1grDu@valkosipuli.retiisi.eu>

Hi Julien,

Thanks for the patch.

On Wed, Jan 10, 2024 at 03:14:40PM +0100, Julien Stephan wrote:
> From: Louis Kuo <louis.kuo at mediatek.com>
> 
> This will add the mediatek ISP3.0 seninf (sensor interface) driver found
> on several Mediatek SoCs such as the mt8365.
> 
> Then seninf module has 4 physical CSI-2 inputs. Depending on the soc they
> may not be all connected.
> 
> Signed-off-by: Louis Kuo <louis.kuo at mediatek.com>
> Signed-off-by: Phi-bang Nguyen <pnguyen at baylibre.com>
> Signed-off-by: Florian Sylvestre <fsylvestre at baylibre.com>
> Co-developed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Co-developed-by: Julien Stephan <jstephan at baylibre.com>
> Signed-off-by: Julien Stephan <jstephan at baylibre.com>
> ---
>  MAINTAINERS                                   |    1 +
>  drivers/media/platform/mediatek/Kconfig       |    1 +
>  drivers/media/platform/mediatek/Makefile      |    1 +
>  drivers/media/platform/mediatek/isp/Kconfig   |    2 +
>  drivers/media/platform/mediatek/isp/Makefile  |    3 +
>  .../platform/mediatek/isp/isp_30/Kconfig      |   16 +
>  .../platform/mediatek/isp/isp_30/Makefile     |    3 +
>  .../mediatek/isp/isp_30/seninf/Makefile       |    5 +
>  .../mediatek/isp/isp_30/seninf/mtk_seninf.c   | 1488 +++++++++++++++++
>  .../isp/isp_30/seninf/mtk_seninf_reg.h        |  112 ++
>  10 files changed, 1632 insertions(+)
>  create mode 100644 drivers/media/platform/mediatek/isp/Kconfig
>  create mode 100644 drivers/media/platform/mediatek/isp/Makefile
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/Kconfig
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/Makefile
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/seninf/Makefile
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/seninf/mtk_seninf.c
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/seninf/mtk_seninf_reg.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3ea2158864e1..52d200d5e36c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -13618,6 +13618,7 @@ M:	Andy Hsieh <andy.hsieh at mediatek.com>
>  S:	Supported
>  F:	Documentation/devicetree/bindings/media/mediatek,mt8365-camsv.yaml
>  F:	Documentation/devicetree/bindings/media/mediatek,mt8365-seninf.yaml
> +F:	drivers/media/platform/mediatek/isp/isp_30/seninf/*
>  
>  MEDIATEK SMI DRIVER
>  M:	Yong Wu <yong.wu at mediatek.com>
> diff --git a/drivers/media/platform/mediatek/Kconfig b/drivers/media/platform/mediatek/Kconfig
> index 84104e2cd024..4e0a5a43f35e 100644
> --- a/drivers/media/platform/mediatek/Kconfig
> +++ b/drivers/media/platform/mediatek/Kconfig
> @@ -7,3 +7,4 @@ source "drivers/media/platform/mediatek/mdp/Kconfig"
>  source "drivers/media/platform/mediatek/vcodec/Kconfig"
>  source "drivers/media/platform/mediatek/vpu/Kconfig"
>  source "drivers/media/platform/mediatek/mdp3/Kconfig"
> +source "drivers/media/platform/mediatek/isp/Kconfig"
> diff --git a/drivers/media/platform/mediatek/Makefile b/drivers/media/platform/mediatek/Makefile
> index 38e6ba917fe5..695f05f525a6 100644
> --- a/drivers/media/platform/mediatek/Makefile
> +++ b/drivers/media/platform/mediatek/Makefile
> @@ -4,3 +4,4 @@ obj-y += mdp/
>  obj-y += vcodec/
>  obj-y += vpu/
>  obj-y += mdp3/
> +obj-y += isp/
> diff --git a/drivers/media/platform/mediatek/isp/Kconfig b/drivers/media/platform/mediatek/isp/Kconfig
> new file mode 100644
> index 000000000000..708b9a6660d2
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/Kconfig
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +source "drivers/media/platform/mediatek/isp/isp_30/Kconfig"
> diff --git a/drivers/media/platform/mediatek/isp/Makefile b/drivers/media/platform/mediatek/isp/Makefile
> new file mode 100644
> index 000000000000..a81ab33d0dd3
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +obj-y += isp_30/
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/Kconfig b/drivers/media/platform/mediatek/isp/isp_30/Kconfig
> new file mode 100644
> index 000000000000..9791312589fb
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/Kconfig
> @@ -0,0 +1,16 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +config MTK_SENINF30
> +	tristate "MediaTek ISP3.0 SENINF driver"
> +	depends on VIDEO_V4L2_SUBDEV_API
> +	depends on MEDIA_CAMERA_SUPPORT
> +	depends on ARCH_MEDIATEK || COMPILE_TEST
> +	depends on OF
> +	select V4L2_FWNODE
> +	default n
> +	help
> +	  This driver provides a MIPI CSI-2 receiver interface to connect
> +	  an external camera module with MediaTek ISP3.0. It is able to handle
> +	  multiple cameras at the same time.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called mtk-seninf.
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/Makefile b/drivers/media/platform/mediatek/isp/isp_30/Makefile
> new file mode 100644
> index 000000000000..ac3142de4739
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_MTK_SENINF30) += seninf/
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/seninf/Makefile b/drivers/media/platform/mediatek/isp/isp_30/seninf/Makefile
> new file mode 100644
> index 000000000000..f28480d6d6c3
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/seninf/Makefile
> @@ -0,0 +1,5 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +mtk-seninf-objs += mtk_seninf.o
> +
> +obj-$(CONFIG_MTK_SENINF30) += mtk-seninf.o
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/seninf/mtk_seninf.c b/drivers/media/platform/mediatek/isp/isp_30/seninf/mtk_seninf.c
> new file mode 100644
> index 000000000000..67b2c697d9ca
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/seninf/mtk_seninf.c
> @@ -0,0 +1,1488 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022 MediaTek Inc.
> + */
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/of_graph.h>
> +#include <linux/of_platform.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/videodev2.h>
> +#include <media/media-device.h>
> +#include <media/media-entity.h>
> +#include <media/v4l2-async.h>
> +#include <media/v4l2-common.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-dev.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-event.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-mc.h>
> +#include <media/v4l2-subdev.h>
> +
> +#include "mtk_seninf_reg.h"
> +
> +#define SENINF_TIMESTAMP_STEP		0x67
> +#define SENINF_SETTLE_DELAY		0x15
> +#define SENINF_HS_TRAIL_PARAMETER	0x8
> +
> +#define SENINF_MAX_NUM_INPUTS		4
> +#define SENINF_MAX_NUM_OUTPUTS		6
> +#define SENINF_MAX_NUM_MUXES		6
> +#define SENINF_MAX_NUM_PADS		(SENINF_MAX_NUM_INPUTS + \
> +					 SENINF_MAX_NUM_OUTPUTS)
> +
> +#define SENINF_DEFAULT_BUS_FMT		MEDIA_BUS_FMT_SGRBG10_1X10
> +#define SENINF_DEFAULT_WIDTH		1920
> +#define SENINF_DEFAULT_HEIGHT		1080
> +
> +#define SENINF_PAD_10BIT		0
> +
> +#define SENINF_TEST_MODEL		0
> +#define SENINF_NORMAL_MODEL		1
> +#define SENINF_ALL_ERR_IRQ_EN		0x7f
> +#define SENINF_IRQ_CLR_SEL		0x80000000
> +
> +#define SENINF_MIPI_SENSOR		0x8
> +
> +#define MTK_CSI_MAX_LANES 4
> +
> +/* Port number in the device tree. */
> +enum mtk_seninf_port {
> +	CSI_PORT_0 = 0,	/* 4D1C or 2D1C */
> +	CSI_PORT_1,	/* 4D1C */
> +	CSI_PORT_2,	/* 4D1C */
> +	CSI_PORT_0B,	/* 2D1C */
> +};
> +
> +enum mtk_seninf_id {
> +	SENINF_1 = 0,
> +	SENINF_2 = 1,
> +	SENINF_3 = 2,
> +	SENINF_5 = 4,
> +};
> +
> +static const u32 port_to_seninf_id[] = {
> +	[CSI_PORT_0] = SENINF_1,
> +	[CSI_PORT_1] = SENINF_3,
> +	[CSI_PORT_2] = SENINF_5,
> +	[CSI_PORT_0B] = SENINF_2,
> +};
> +
> +enum mtk_seninf_phy_mode {
> +	SENINF_PHY_MODE_NONE,
> +	SENINF_PHY_MODE_4D1C,
> +	SENINF_PHY_MODE_2D1C,
> +};
> +
> +enum mtk_seninf_format_flag {
> +	MTK_SENINF_FORMAT_BAYER = BIT(0),
> +	MTK_SENINF_FORMAT_DPCM = BIT(1),
> +	MTK_SENINF_FORMAT_JPEG = BIT(2),
> +	MTK_SENINF_FORMAT_INPUT_ONLY = BIT(3),
> +};
> +
> +/**
> + * struct mtk_seninf_conf - Model-specific SENINF parameters
> + * @model: Model description
> + * @nb_inputs: Number of SENINF inputs
> + * @nb_muxes: Number of SENINF MUX (FIFO) instances
> + * @nb_outputs: Number of outputs (to CAM and CAMSV instances)
> + */
> +struct mtk_seninf_conf {
> +	const char *model;
> +	u8 nb_inputs;
> +	u8 nb_muxes;
> +	u8 nb_outputs;
> +};
> +
> +/**
> + * struct mtk_seninf_format_info - Information about media bus formats
> + * @code: V4L2 media bus code
> + * @flags: Flags describing the format, as a combination of MTK_SENINF_FORMAT_*
> + */
> +struct mtk_seninf_format_info {
> +	u32 code;
> +	u32 flags;
> +};
> +
> +/**
> + * struct mtk_seninf_input - SENINF input block
> + * @pad: DT port and media entity pad number
> + * @seninf_id: SENINF hardware instance ID
> + * @base: Memory mapped I/O based address
> + * @seninf: Back pointer to the mtk_seninf
> + * @phy: PHY connected to the input
> + * @phy_mode: PHY operation mode (NONE when the input is not connected)
> + * @bus: CSI-2 bus configuration from DT
> + * @source_sd: Source subdev connected to the input
> + */
> +struct mtk_seninf_input {
> +	enum mtk_seninf_port pad;
> +	enum mtk_seninf_id seninf_id;
> +	void __iomem *base;
> +	struct mtk_seninf *seninf;
> +
> +	struct phy *phy;
> +	enum mtk_seninf_phy_mode phy_mode;
> +
> +	struct v4l2_mbus_config_mipi_csi2 bus;
> +
> +	struct v4l2_subdev *source_sd;
> +};
> +
> +/**
> + * struct mtk_seninf_mux - SENINF MUX channel
> + * @pad: DT port and media entity pad number
> + * @mux_id: MUX hardware instance ID
> + * @base: Memory mapped I/O based address
> + * @seninf: Back pointer to the mtk_seninf
> + */
> +struct mtk_seninf_mux {
> +	unsigned int pad;
> +	unsigned int mux_id;
> +	void __iomem *base;
> +	struct mtk_seninf *seninf;
> +};
> +
> +/**
> + * struct mtk_seninf - Top-level SENINF device
> + * @dev: The (platform) device
> + * @phy: PHYs at the SENINF inputs
> + * @num_clks: Number of clocks in the clks array
> + * @clks: Clocks
> + * @base: Memory mapped I/O base address
> + * @media_dev: Media controller device
> + * @v4l2_dev: V4L2 device
> + * @subdev: V4L2 subdevice
> + * @pads: Media entity pads
> + * @notifier: V4L2 async notifier for source subdevs
> + * @ctrl_handler: V4L2 controls handler
> + * @source_format: Active format on the source pad
> + * @inputs: Array of SENINF inputs
> + * @muxes: Array of MUXes
> + * @conf: Model-specific SENINF parameters
> + * @is_testmode: Whether or not the test pattern generator is enabled
> + */
> +struct mtk_seninf {
> +	struct device *dev;
> +	struct phy *phy[5];
> +	unsigned int num_clks;
> +	struct clk_bulk_data *clks;
> +	void __iomem *base;
> +
> +	struct media_device media_dev;
> +	struct v4l2_device v4l2_dev;
> +	struct v4l2_subdev subdev;
> +	struct media_pad pads[SENINF_MAX_NUM_PADS];
> +	struct v4l2_async_notifier notifier;
> +	struct v4l2_ctrl_handler ctrl_handler;
> +
> +	struct mtk_seninf_input inputs[SENINF_MAX_NUM_INPUTS];
> +	struct mtk_seninf_mux muxes[SENINF_MAX_NUM_MUXES];
> +
> +	const struct mtk_seninf_conf *conf;
> +
> +	bool is_testmode;
> +};
> +
> +inline struct mtk_seninf *sd_to_mtk_seninf(struct v4l2_subdev *sd)
> +{
> +	return container_of(sd, struct mtk_seninf, subdev);
> +}
> +
> +static inline bool mtk_seninf_pad_is_sink(struct mtk_seninf *priv,
> +					  unsigned int pad)
> +{
> +	return pad < priv->conf->nb_inputs;

It'd be a bit cleaner to test pad flags instead.

> +}
> +
> +static inline bool mtk_seninf_pad_is_source(struct mtk_seninf *priv,
> +					    unsigned int pad)
> +{
> +	return !mtk_seninf_pad_is_sink(priv, pad);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Formats
> + */
> +
> +static const struct mtk_seninf_format_info mtk_seninf_formats[] = {
> +	{
> +		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SBGGR14_1X14,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGBRG14_1X14,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGRBG14_1X14,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SRGGB14_1X14,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SBGGR16_1X16,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGBRG16_1X16,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGRBG16_1X16,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SRGGB16_1X16,
> +		.flags = MTK_SENINF_FORMAT_BAYER,
> +	}, {
> +		.code = MEDIA_BUS_FMT_UYVY8_1X16,
> +	}, {
> +		.code = MEDIA_BUS_FMT_VYUY8_1X16,
> +	}, {
> +		.code = MEDIA_BUS_FMT_YUYV8_1X16,
> +	}, {
> +		.code = MEDIA_BUS_FMT_YVYU8_1X16,
> +	}, {
> +		.code = MEDIA_BUS_FMT_JPEG_1X8,
> +		.flags = MTK_SENINF_FORMAT_JPEG,
> +	}, {
> +		.code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8,
> +		.flags = MTK_SENINF_FORMAT_JPEG,
> +	},
> +	/* Keep the input-only formats last. */
> +	{
> +		.code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
> +		.flags = MTK_SENINF_FORMAT_DPCM | MTK_SENINF_FORMAT_INPUT_ONLY,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
> +		.flags = MTK_SENINF_FORMAT_DPCM | MTK_SENINF_FORMAT_INPUT_ONLY,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
> +		.flags = MTK_SENINF_FORMAT_DPCM | MTK_SENINF_FORMAT_INPUT_ONLY,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
> +		.flags = MTK_SENINF_FORMAT_DPCM | MTK_SENINF_FORMAT_INPUT_ONLY,
> +	}
> +};
> +
> +static const struct mtk_seninf_format_info *mtk_seninf_format_info(u32 code)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(mtk_seninf_formats); ++i) {
> +		if (mtk_seninf_formats[i].code == code)
> +			return &mtk_seninf_formats[i];
> +	}
> +
> +	return NULL;
> +}
> +
> +static void __mtk_seninf_update(struct mtk_seninf *priv, u32 reg,
> +				u32 mask, u32 value)
> +{
> +	u32 val = readl(priv->base + reg);
> +
> +	writel((val & ~mask) | (value & mask), priv->base + reg);
> +}
> +
> +#define mtk_seninf_update(priv, reg, field, val)			\
> +	__mtk_seninf_update(priv, reg, reg##_##field,		\

Please align the backslashes.

> +			    FIELD_PREP(reg##_##field, val))
> +
> +static void __mtk_seninf_input_update(struct mtk_seninf_input *input, u32 reg,
> +				      u32 mask, u32 value)
> +{
> +	u32 val = readl(input->base + reg);
> +
> +	writel((val & ~mask) | (value & mask), input->base + reg);
> +}
> +
> +#define mtk_seninf_input_update(input, reg, field, val)			\
> +	__mtk_seninf_input_update(input, reg, reg##_##field,	\
> +				  FIELD_PREP(reg##_##field, val))
> +
> +static u32 mtk_seninf_mux_read(struct mtk_seninf_mux *mux, u32 reg)
> +{
> +	return readl(mux->base + reg);
> +}
> +
> +static void mtk_seninf_mux_write(struct mtk_seninf_mux *mux, u32 reg,
> +				 u32 value)
> +{
> +	writel(value, mux->base + reg);
> +}
> +
> +static void __mtk_seninf_mux_update(struct mtk_seninf_mux *mux, u32 reg,
> +				    u32 mask, u32 value)
> +{
> +	u32 val = mtk_seninf_mux_read(mux, reg);
> +
> +	mtk_seninf_mux_write(mux, reg, (val & ~mask) | (value & mask));
> +}
> +
> +#define mtk_seninf_mux_update(mux, reg, field, val)			\
> +	__mtk_seninf_mux_update(mux, reg, reg##_##field,	\
> +				FIELD_PREP(reg##_##field, val))
> +
> +/* -----------------------------------------------------------------------------
> + * Hardware Configuration
> + *
> + * The SENINF is the camera sensor interface. On the input side it contains
> + * input channels (also named SENINF), each made of a CSI-2 receiver, an
> + * interface for parallel sensors, and a test pattern generator. The inputs are
> + * routed through a N:M crossbar switch (TOP MUX) to VC/DT filters with a FIFO
> + * (MUX). The MUX are routed to another N:M crossbar switch (CAM MUX), whose
> + * output is then connected to other IP cores.
> + *
> + *            +-------------------------------------------------------+
> + *            | SENINF                                                |
> + *            |                                                       |
> + * +-------+  |   +----------+    TOP MUX                             |
> + * |       |  |   |  SENINF  |      |\                        CAM MUX |
> + * | D-PHY | ---> | CSI-2 RX | ---> | |      +------------+      |\   |
> + * |       |  |   |   TPG    |   -> | | ---> | MUX (FIFO) | ---> | | ---> CAMSV
> + * +-------+  |   +----------+   -> | |      +------------+   -> | |  |
> + *            |                     |/                        -> | |  |
> + *            |                                                  |/   |
> + *            |                                                       |
> + *    ...     |       ...                         ...                --->
> + *            |                                                       |
> + *            |                                                       |
> + *            +-------------------------------------------------------+
> + *
> + * The number of PHYs, SENINF and MUX differ between SoCs. MT8167 has a single
> + * MUX and thus no output CAM MUX crossbar switch.
> + */
> +
> +static void mtk_seninf_csi2_setup_phy(struct mtk_seninf *priv)
> +{
> +	/* CSI0 */
> +	if (priv->inputs[CSI_PORT_0].phy) {
> +		struct mtk_seninf_input *input = &priv->inputs[CSI_PORT_0];
> +
> +		mtk_seninf_update(priv, SENINF_TOP_PHY_SENINF_CTL_CSI0,
> +				  DPHY_MODE, 0 /* 4D1C*/);
> +		mtk_seninf_update(priv, SENINF_TOP_PHY_SENINF_CTL_CSI0,
> +				  CK_SEL_1, input->bus.clock_lane);
> +		mtk_seninf_update(priv, SENINF_TOP_PHY_SENINF_CTL_CSI0,
> +				  CK_SEL_2, 2);
> +		mtk_seninf_update(priv, SENINF_TOP_PHY_SENINF_CTL_CSI0,
> +				  PHY_SENINF_LANE_MUX_CSI0_EN, 1);
> +	}
> +
> +	/* CSI1 */
> +	if (priv->inputs[CSI_PORT_1].phy) {
> +		struct mtk_seninf_input *input = &priv->inputs[CSI_PORT_1];
> +
> +		mtk_seninf_update(priv, SENINF_TOP_PHY_SENINF_CTL_CSI1,
> +				  DPHY_MODE, 0 /* 4D1C */);
> +		mtk_seninf_update(priv, SENINF_TOP_PHY_SENINF_CTL_CSI1,
> +				  CK_SEL_1, input->bus.clock_lane);
> +		mtk_seninf_update(priv, SENINF_TOP_PHY_SENINF_CTL_CSI1,
> +				  PHY_SENINF_LANE_MUX_CSI1_EN, 1);
> +	}
> +}
> +
> +static void mtk_seninf_input_setup_csi2_rx(struct mtk_seninf_input *input)
> +{
> +	unsigned int lanes[MTK_CSI_MAX_LANES] = { };
> +	unsigned int i;
> +
> +	/*
> +	 * Configure data lane muxing. In 2D1C mode, lanes 0 to 2 correspond to
> +	 * CSIx[AB]_L{0,1,2}, and in 4D1C lanes 0 to 5 correspond to
> +	 * CSIxA_L{0,1,2}, CSIxB_L{0,1,2}.
> +	 *
> +	 * The clock lane must be skipped when calculating the index of the
> +	 * physical data lane. For instance, in 4D1C mode, the sensor clock
> +	 * lane is typically connected to lane 2 (CSIxA_L2), and the sensor
> +	 * data lanes 0-3 to lanes 1 (CSIxA_L1), 3 (CSIxB_L0), 0 (CSIxA_L0) and
> +	 * 4 (CSIxB_L1). The when skipping the clock lane, the data lane
> +	 * indices become 1, 2, 0 and 3.
> +	 */
> +	for (i = 0; i < input->bus.num_data_lanes; ++i) {
> +		lanes[i] = input->bus.data_lanes[i];
> +		if (lanes[i] > input->bus.clock_lane)
> +			lanes[i]--;
> +	}
> +
> +	mtk_seninf_input_update(input, MIPI_RX_CON24_CSI0, CSI0_BIST_LN0_MUX, lanes[0]);
> +	mtk_seninf_input_update(input, MIPI_RX_CON24_CSI0, CSI0_BIST_LN1_MUX, lanes[1]);
> +	mtk_seninf_input_update(input, MIPI_RX_CON24_CSI0, CSI0_BIST_LN2_MUX, lanes[2]);
> +	mtk_seninf_input_update(input, MIPI_RX_CON24_CSI0, CSI0_BIST_LN3_MUX, lanes[3]);
> +}
> +
> +static void mtk_seninf_input_setup_csi2(struct mtk_seninf_input *input,
> +					struct v4l2_subdev_state *state)
> +{
> +	const struct mtk_seninf_format_info *fmtinfo;
> +	const struct v4l2_mbus_framefmt *format;
> +	unsigned int num_data_lanes = input->bus.num_data_lanes;
> +	unsigned int val = 0;

u32?

> +
> +	format = v4l2_subdev_state_get_stream_format(state, input->pad, 0);
> +	fmtinfo = mtk_seninf_format_info(format->code);
> +
> +	/* Configure timestamp */
> +	writel(SENINF_TIMESTAMP_STEP, input->base + SENINF_TG1_TM_STP);
> +
> +	/* HQ */
> +	writel(0x0, input->base + SENINF_TG1_PH_CNT);
> +	writel(0x10001, input->base + SENINF_TG1_SEN_CK);
> +
> +	/* First Enable Sensor interface and select pad (0x1a04_0200) */
> +	mtk_seninf_input_update(input, SENINF_CTRL, SENINF_EN, 1);
> +	mtk_seninf_input_update(input, SENINF_CTRL, PAD2CAM_DATA_SEL, SENINF_PAD_10BIT);
> +	mtk_seninf_input_update(input, SENINF_CTRL, SENINF_SRC_SEL, 0);
> +	mtk_seninf_input_update(input, SENINF_CTRL_EXT, SENINF_CSI2_IP_EN, 1);
> +	mtk_seninf_input_update(input, SENINF_CTRL_EXT, SENINF_NCSI2_IP_EN, 0);
> +
> +	/* DPCM Enable */
> +	if (fmtinfo->flags & MTK_SENINF_FORMAT_DPCM)
> +		val = SENINF_CSI2_DPCM_DI_2A_DPCM_EN;
> +	else
> +		val = SENINF_CSI2_DPCM_DI_30_DPCM_EN;
> +	writel(val, input->base + SENINF_CSI2_DPCM);
> +
> +	/* Settle delay */
> +	mtk_seninf_input_update(input, SENINF_CSI2_LNRD_TIMING,
> +				DATA_SETTLE_PARAMETER, SENINF_SETTLE_DELAY);
> +
> +	/* HQ */
> +	writel(0x10, input->base + SENINF_CSI2_LNRC_FSM);
> +
> +	/* CSI2 control */
> +	val = readl(input->base + SENINF_CSI2_CTL)
> +	    | (FIELD_PREP(SENINF_CSI2_CTL_ED_SEL, DATA_HEADER_ORDER_DI_WCL_WCH)
> +	    | SENINF_CSI2_CTL_CLOCK_LANE_EN | (BIT(num_data_lanes) - 1));

These two lines should be aligned right of "= ", not at it.

> +	writel(val, input->base + SENINF_CSI2_CTL);
> +
> +	mtk_seninf_input_update(input, SENINF_CSI2_RESYNC_MERGE_CTL,
> +				BYPASS_LANE_RESYNC, 0);
> +	mtk_seninf_input_update(input, SENINF_CSI2_RESYNC_MERGE_CTL, CDPHY_SEL, 0);
> +	mtk_seninf_input_update(input, SENINF_CSI2_RESYNC_MERGE_CTL,
> +				CPHY_LANE_RESYNC_CNT, 3);
> +	mtk_seninf_input_update(input, SENINF_CSI2_MODE, CSR_CSI2_MODE, 0);
> +	mtk_seninf_input_update(input, SENINF_CSI2_MODE, CSR_CSI2_HEADER_LEN, 0);
> +	mtk_seninf_input_update(input, SENINF_CSI2_DPHY_SYNC, SYNC_SEQ_MASK_0, 0xff00);
> +	mtk_seninf_input_update(input, SENINF_CSI2_DPHY_SYNC, SYNC_SEQ_PAT_0, 0x001d);
> +
> +	mtk_seninf_input_update(input, SENINF_CSI2_CTL, CLOCK_HS_OPTION, 0);
> +	mtk_seninf_input_update(input, SENINF_CSI2_CTL, HSRX_DET_EN, 0);
> +	mtk_seninf_input_update(input, SENINF_CSI2_CTL, HS_TRAIL_EN, 1);
> +	mtk_seninf_input_update(input, SENINF_CSI2_HS_TRAIL, HS_TRAIL_PARAMETER,
> +				SENINF_HS_TRAIL_PARAMETER);
> +
> +	/* Set debug port to output packet number */
> +	mtk_seninf_input_update(input, SENINF_CSI2_DGB_SEL, DEBUG_EN, 1);
> +	mtk_seninf_input_update(input, SENINF_CSI2_DGB_SEL, DEBUG_SEL, 0x1a);
> +
> +	/* HQ */
> +	writel(0xfffffffe, input->base + SENINF_CSI2_SPARE0);
> +
> +	/* Enable CSI2 IRQ mask */
> +	/* Turn on all interrupt */
> +	writel(0xffffffff, input->base + SENINF_CSI2_INT_EN);
> +	/* Write clear CSI2 IRQ */
> +	writel(0xffffffff, input->base + SENINF_CSI2_INT_STATUS);
> +	/* Enable CSI2 Extend IRQ mask */
> +	/* Turn on all interrupt */
> +	mtk_seninf_input_update(input, SENINF_CTRL, CSI2_SW_RST, 1);
> +	udelay(1);
> +	mtk_seninf_input_update(input, SENINF_CTRL, CSI2_SW_RST, 0);
> +}
> +
> +static void mtk_seninf_mux_setup(struct mtk_seninf_mux *mux,
> +				 struct mtk_seninf_input *input,
> +				 struct v4l2_subdev_state *state)
> +{
> +	const struct mtk_seninf_format_info *fmtinfo;
> +	const struct v4l2_mbus_framefmt *format;
> +	unsigned int pix_sel_ext;
> +	unsigned int pix_sel;
> +	unsigned int hs_pol = 0;
> +	unsigned int vs_pol = 0;
> +	unsigned int val;
> +	u32 rst_mask;
> +
> +	format = v4l2_subdev_state_get_stream_format(state, input->pad, 0);
> +	fmtinfo = mtk_seninf_format_info(format->code);
> +
> +	/* Enable mux */
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_MUX_EN, 1);
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_SRC_SEL, SENINF_MIPI_SENSOR);
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL_EXT, SENINF_SRC_SEL_EXT, SENINF_NORMAL_MODEL);

Could you run

	./scripts/checkpatch.pl --strict --max-line-length=80

on the set?

There are probably reasons to do otherwise for e.g. register definitions or
where you really can't do that without breaking other CodingStyle rules.

> +
> +	pix_sel_ext = 0;
> +	pix_sel = 1;

These local variables are redundant.

> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL_EXT, SENINF_PIX_SEL_EXT, pix_sel_ext);
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_PIX_SEL, pix_sel);
> +
> +	if (fmtinfo->flags & MTK_SENINF_FORMAT_JPEG) {
> +		mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FULL_WR_EN, 0);
> +		mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FLUSH_EN,
> +				      FIFO_FLUSH_EN_JPEG_2_PIXEL_MODE);
> +		mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_PUSH_EN,
> +				FIFO_PUSH_EN_JPEG_2_PIXEL_MODE);
> +	} else {
> +		mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FULL_WR_EN, 2);
> +		mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FLUSH_EN,
> +				     FIFO_FLUSH_EN_NORMAL_MODE);
> +		mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_PUSH_EN,
> +				FIFO_PUSH_EN_NORMAL_MODE);
> +	}
> +
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_HSYNC_POL, hs_pol);
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_VSYNC_POL, vs_pol);

Same for vs_pol. Or should you get the value from the endpoint?

> +
> +	val = mtk_seninf_mux_read(mux, SENINF_MUX_CTRL);
> +	rst_mask = SENINF_MUX_CTRL_SENINF_IRQ_SW_RST | SENINF_MUX_CTRL_SENINF_MUX_SW_RST;
> +
> +	mtk_seninf_mux_write(mux, SENINF_MUX_CTRL, val | rst_mask);
> +	mtk_seninf_mux_write(mux, SENINF_MUX_CTRL, val & ~rst_mask);
> +
> +	/* HQ */
> +	mtk_seninf_mux_write(mux, SENINF_MUX_SPARE, 0xc2000);
> +}
> +
> +static void mtk_seninf_top_mux_setup(struct mtk_seninf *priv,
> +				     enum mtk_seninf_id seninf_id,
> +				     struct mtk_seninf_mux *mux)
> +{
> +	unsigned int val;
> +
> +	/*
> +	 * Use the top mux (from SENINF input to MUX) to configure routing, and
> +	 * hardcode a 1:1 mapping from the MUX instances to the SENINF outputs.
> +	 */
> +	val = readl(priv->base + SENINF_TOP_MUX_CTRL)
> +		& ~(0xf << (mux->mux_id * 4));

Alignment.

> +	val |= (seninf_id & 0xf) << (mux->mux_id * 4);
> +	writel(val, priv->base + SENINF_TOP_MUX_CTRL);
> +
> +	writel(0x76541010, priv->base + SENINF_TOP_CAM_MUX_CTRL);

What does this do? A comment would be nice, and even nicer it would be to
have a macro (or macros) for constructing this magic number using them.

> +}
> +
> +static void seninf_enable_test_pattern(struct mtk_seninf *priv,
> +				       struct v4l2_subdev_state *state)
> +{
> +	struct mtk_seninf_input *input = &priv->inputs[CSI_PORT_0];
> +	struct mtk_seninf_mux *mux = &priv->muxes[0];
> +	const struct mtk_seninf_format_info *fmtinfo;
> +	const struct v4l2_mbus_framefmt *format;
> +	unsigned int val;
> +	unsigned int pix_sel_ext;
> +	unsigned int pix_sel;
> +	unsigned int hs_pol = 0;
> +	unsigned int vs_pol = 0;
> +	unsigned int seninf = 0;
> +	unsigned int tm_size = 0;
> +	unsigned int mux_id = mux->mux_id;
> +
> +	format = v4l2_subdev_state_get_stream_format(state, priv->conf->nb_inputs, 0);
> +	fmtinfo = mtk_seninf_format_info(format->code);
> +
> +	mtk_seninf_update(priv, SENINF_TOP_CTRL, MUX_LP_MODE, 0);
> +
> +	mtk_seninf_update(priv, SENINF_TOP_CTRL, SENINF_PCLK_EN, 1);
> +	mtk_seninf_update(priv, SENINF_TOP_CTRL, SENINF2_PCLK_EN, 1);
> +
> +	mtk_seninf_input_update(input, SENINF_CTRL, SENINF_EN, 1);
> +	mtk_seninf_input_update(input, SENINF_CTRL, SENINF_SRC_SEL, 1);
> +	mtk_seninf_input_update(input, SENINF_CTRL_EXT,
> +				SENINF_TESTMDL_IP_EN, 1);
> +
> +	mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_EN, 1);
> +	mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_PAT, 0xc);
> +	mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_VSYNC, 4);
> +	mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_DUMMYPXL, 0x28);
> +
> +	if (fmtinfo->flags & MTK_SENINF_FORMAT_BAYER)
> +		mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_FMT, 0x0);
> +	else
> +		mtk_seninf_input_update(input, SENINF_TG1_TM_CTL, TM_FMT, 0x1);
> +
> +	tm_size = FIELD_PREP(SENINF_TG1_TM_SIZE_TM_LINE, format->height + 8);
> +	switch (format->code) {
> +	case MEDIA_BUS_FMT_UYVY8_1X16:
> +	case MEDIA_BUS_FMT_VYUY8_1X16:
> +	case MEDIA_BUS_FMT_YUYV8_1X16:
> +	case MEDIA_BUS_FMT_YVYU8_1X16:
> +		tm_size |= FIELD_PREP(SENINF_TG1_TM_SIZE_TM_PXL, format->width * 2);
> +		break;
> +	default:
> +		tm_size |= FIELD_PREP(SENINF_TG1_TM_SIZE_TM_PXL, format->width);
> +		break;
> +	}
> +	writel(tm_size, input->base + SENINF_TG1_TM_SIZE);
> +
> +	writel(TEST_MODEL_CLK_DIVIDED_CNT, input->base + SENINF_TG1_TM_CLK);
> +	writel(TIME_STAMP_DIVIDER, input->base + SENINF_TG1_TM_STP);
> +
> +	/* Set top mux */
> +	val = (readl(priv->base + SENINF_TOP_MUX_CTRL) & (~(0xf << (mux_id * 4)))) |
> +		((seninf & 0xf) << (mux_id * 4));
> +	writel(val, priv->base + SENINF_TOP_MUX_CTRL);
> +
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_MUX_EN, 1);
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL_EXT,
> +			      SENINF_SRC_SEL_EXT, SENINF_TEST_MODEL);
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_SRC_SEL, 1);
> +
> +	pix_sel_ext = 0;
> +	pix_sel = 1;
> +
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL_EXT,
> +			      SENINF_PIX_SEL_EXT, pix_sel_ext);
> +
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_PIX_SEL, pix_sel);
> +
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_PUSH_EN, 0x1f);
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FLUSH_EN, 0x1b);
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, FIFO_FULL_WR_EN, 2);
> +
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_HSYNC_POL, hs_pol);
> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_VSYNC_POL, vs_pol);

These seem to be redundant.

> +	mtk_seninf_mux_update(mux, SENINF_MUX_CTRL, SENINF_HSYNC_MASK, 1);
> +
> +	mtk_seninf_mux_write(mux, SENINF_MUX_INTEN,
> +			     SENINF_IRQ_CLR_SEL | SENINF_ALL_ERR_IRQ_EN);
> +
> +	mtk_seninf_mux_write(mux, SENINF_MUX_CTRL,
> +			     mtk_seninf_mux_read(mux, SENINF_MUX_CTRL) |
> +			     SENINF_MUX_CTRL_SENINF_IRQ_SW_RST |
> +			     SENINF_MUX_CTRL_SENINF_MUX_SW_RST);
> +	udelay(1);
> +	mtk_seninf_mux_write(mux, SENINF_MUX_CTRL,
> +			     mtk_seninf_mux_read(mux, SENINF_MUX_CTRL) &
> +			     ~(SENINF_MUX_CTRL_SENINF_IRQ_SW_RST |
> +			       SENINF_MUX_CTRL_SENINF_MUX_SW_RST));
> +
> +	//check this

	/* comment */

> +	writel(0x76540010, priv->base + SENINF_TOP_CAM_MUX_CTRL);
> +
> +	dev_dbg(priv->dev, "%s: OK\n", __func__);

This can certainly be removed.

> +}
> +
> +static void mtk_seninf_start(struct mtk_seninf *priv,
> +			     struct v4l2_subdev_state *state,
> +			     struct mtk_seninf_input *input,
> +			     struct mtk_seninf_mux *mux)
> +{
> +	phy_power_on(input->phy);
> +
> +	mtk_seninf_input_setup_csi2_rx(input);
> +	mtk_seninf_input_setup_csi2(input, state);
> +
> +	mtk_seninf_mux_setup(mux, input, state);
> +	mtk_seninf_top_mux_setup(priv, input->seninf_id, mux);
> +}
> +
> +static void mtk_seninf_stop(struct mtk_seninf *priv,
> +			    struct mtk_seninf_input *input)
> +{
> +	unsigned int val;
> +
> +	/* Disable CSI2(2.5G) first */
> +	val = readl(input->base + SENINF_CSI2_CTL);
> +	val &= ~(SENINF_CSI2_CTL_CLOCK_LANE_EN |
> +		 SENINF_CSI2_CTL_DATA_LANE3_EN |
> +		 SENINF_CSI2_CTL_DATA_LANE2_EN |
> +		 SENINF_CSI2_CTL_DATA_LANE1_EN |
> +		 SENINF_CSI2_CTL_DATA_LANE0_EN);
> +	writel(val, input->base + SENINF_CSI2_CTL);
> +
> +	if (!priv->is_testmode)
> +		phy_power_off(input->phy);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Controls
> + */
> +
> +static int seninf_set_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	struct mtk_seninf *priv = container_of(ctrl->handler,
> +					       struct mtk_seninf, ctrl_handler);
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_TEST_PATTERN:
> +		priv->is_testmode = !!ctrl->val;

You could instead store the pointer to the control and use ctrl->val where
you need this.

> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct v4l2_ctrl_ops seninf_ctrl_ops = {
> +	.s_ctrl = seninf_set_ctrl,
> +};
> +
> +static const char *const seninf_test_pattern_menu[] = {
> +	"No test pattern",
> +	"Static horizontal color bars",
> +};
> +
> +static int seninf_initialize_controls(struct mtk_seninf *priv)
> +{
> +	struct v4l2_ctrl_handler *handler;
> +	int ret;
> +
> +	handler = &priv->ctrl_handler;
> +	ret = v4l2_ctrl_handler_init(handler, 2);
> +	if (ret)
> +		return ret;
> +
> +	v4l2_ctrl_new_std_menu_items(handler, &seninf_ctrl_ops,
> +				     V4L2_CID_TEST_PATTERN,
> +				     ARRAY_SIZE(seninf_test_pattern_menu) - 1,
> +				     0, 0, seninf_test_pattern_menu);
> +
> +	priv->is_testmode = false;
> +
> +	if (handler->error) {
> +		ret = handler->error;
> +		dev_err(priv->dev,
> +			"Failed to init controls(%d)\n", ret);
> +		v4l2_ctrl_handler_free(handler);
> +		return ret;
> +	}
> +
> +	priv->subdev.ctrl_handler = handler;
> +
> +	return 0;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdev Operations
> + */
> +static int seninf_s_stream(struct v4l2_subdev *sd, unsigned int source_pad,
> +			   int on)
> +{
> +	struct mtk_seninf *priv = sd_to_mtk_seninf(sd);
> +	struct v4l2_subdev_state *state;
> +	struct mtk_seninf_input *input;
> +	struct mtk_seninf_mux *mux;
> +	struct v4l2_subdev *source;
> +	u32 sink_pad;
> +	int ret;
> +
> +	/* Stream control can only operate on source pads. */
> +	if (source_pad < priv->conf->nb_inputs ||
> +	    source_pad >= priv->conf->nb_inputs + priv->conf->nb_outputs)
> +		return -EINVAL;
> +
> +	/*
> +	 * Locate the SENINF input and MUX for the source pad.
> +	 *
> +	 * Hardcode a 1:1 mapping of MUX instances to SENINF
> +	 * outputs to match the TOP_CAM_MUX configuration in
> +	 * mtk_seninf_top_mux_setup().
> +	 */
> +	state = v4l2_subdev_lock_and_get_active_state(&priv->subdev);
> +	if (!state)
> +		return -EPIPE;
> +
> +	ret = v4l2_subdev_routing_find_opposite_end(&state->routing, source_pad, 0, &sink_pad,
> +						    NULL);
> +	if (ret) {
> +		dev_dbg(priv->dev, "No sink pad routed to source pad %u\n", source_pad);
> +		goto unlock;
> +	}
> +
> +	input = &priv->inputs[sink_pad];
> +	mux = &priv->muxes[source_pad - priv->conf->nb_inputs];
> +
> +	if (!on) {
> +		if (!priv->is_testmode) {
> +			source = input->source_sd;
> +			ret = v4l2_subdev_call(source, video, s_stream, 0);
> +			if (ret)
> +				dev_err(priv->dev,
> +					"failed to stop source %s: %d\n",
> +					source->entity.name, ret);
> +		}
> +
> +		mtk_seninf_stop(priv, input);
> +		pm_runtime_put(priv->dev);
> +		goto unlock;
> +	}
> +
> +	ret = pm_runtime_get_sync(priv->dev);
> +	if (ret < 0) {
> +		dev_err(priv->dev, "Failed to pm_runtime_get_sync: %d\n", ret);
> +		pm_runtime_put_noidle(priv->dev);
> +		goto unlock;
> +	}
> +
> +	/* If test mode is enabled, just enable the test pattern generator. */
> +	if (priv->is_testmode) {
> +		seninf_enable_test_pattern(priv, state);
> +		ret = 0;
> +		goto unlock;
> +	}
> +
> +	/* Start the SENINF first and then the source. */
> +	mtk_seninf_start(priv, state, input, mux);
> +
> +	source = input->source_sd;
> +	ret = v4l2_subdev_call(source, video, s_stream, 1);
> +	if (ret) {
> +		dev_err(priv->dev, "failed to start source %s: %d\n",
> +			source->entity.name, ret);
> +		mtk_seninf_stop(priv, input);
> +		pm_runtime_put(priv->dev);
> +	}
> +
> +unlock:
> +	v4l2_subdev_unlock_state(state);
> +	return ret;
> +};
> +
> +static int seninf_enable_streams(struct v4l2_subdev *sd,
> +				 struct v4l2_subdev_state *state, u32 pad,
> +				 u64 streams_mask)
> +{
> +	return seninf_s_stream(sd, pad, 1);
> +}
> +
> +static int seninf_disable_streams(struct v4l2_subdev *sd,
> +				  struct v4l2_subdev_state *state, u32 pad,
> +				  u64 streams_mask)
> +{
> +	return seninf_s_stream(sd, pad, 0);
> +}
> +
> +static const struct v4l2_mbus_framefmt mtk_seninf_default_fmt = {
> +	.code = SENINF_DEFAULT_BUS_FMT,
> +	.width = SENINF_DEFAULT_WIDTH,
> +	.height = SENINF_DEFAULT_HEIGHT,
> +	.field = V4L2_FIELD_NONE,
> +	.colorspace = V4L2_COLORSPACE_SRGB,
> +	.xfer_func = V4L2_XFER_FUNC_DEFAULT,
> +	.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
> +	.quantization = V4L2_QUANTIZATION_DEFAULT,
> +};
> +
> +static int __seninf_set_routing(struct v4l2_subdev *sd,
> +				struct v4l2_subdev_state *state,
> +				struct v4l2_subdev_krouting *routing)
> +{
> +	int ret;
> +
> +	ret = v4l2_subdev_routing_validate(sd, routing, V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
> +	if (ret)
> +		return ret;
> +
> +	ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing,
> +					       &mtk_seninf_default_fmt);

	return ...;

> +
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int seninf_init_cfg(struct v4l2_subdev *sd,
> +			   struct v4l2_subdev_state *state)
> +{
> +	struct mtk_seninf *priv = sd_to_mtk_seninf(sd);
> +	struct v4l2_subdev_route routes[SENINF_MAX_NUM_OUTPUTS] = { };
> +	struct v4l2_subdev_krouting routing = {
> +		.routes = routes,
> +	};
> +	unsigned int i;
> +
> +	/*
> +	 * Initialize one route for supported source pads.
> +	 * It is a single route from the first sink pad to the source pad,
> +	 * while on SENINF 5.0 the routing table will map sink pads to source
> +	 * pads connected to CAMSV 1:1 (skipping the first two source pads
> +	 * connected to the CAM instances).
> +	 */
> +	routing.num_routes = priv->conf->nb_outputs;

You can do this assignment in the declaration.

> +
> +	for (i = 0; i < routing.num_routes; i++) {
> +		struct v4l2_subdev_route *route = &routes[i];
> +
> +		route->sink_pad = i;
> +		route->sink_stream = 0;
> +		route->source_pad = priv->conf->nb_inputs + i;
> +		route->source_stream = 0;
> +		route->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
> +	}
> +
> +	return __seninf_set_routing(sd, state, &routing);
> +}
> +
> +static int seninf_enum_mbus_code(struct v4l2_subdev *sd,
> +				 struct v4l2_subdev_state *state,
> +				 struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	const struct mtk_seninf_format_info *fmtinfo;
> +	struct mtk_seninf *priv = sd_to_mtk_seninf(sd);
> +
> +	if (code->index >= ARRAY_SIZE(mtk_seninf_formats))
> +		return -EINVAL;
> +
> +	fmtinfo = &mtk_seninf_formats[code->index];
> +	if (fmtinfo->flags & MTK_SENINF_FORMAT_INPUT_ONLY &&
> +	    mtk_seninf_pad_is_source(priv, code->pad))
> +		return -EINVAL;
> +
> +	code->code = fmtinfo->code;
> +
> +	return 0;
> +}
> +
> +static int seninf_set_fmt(struct v4l2_subdev *sd,
> +			  struct v4l2_subdev_state *state,
> +			  struct v4l2_subdev_format *fmt)
> +{
> +	struct mtk_seninf *priv = sd_to_mtk_seninf(sd);
> +	const struct mtk_seninf_format_info *fmtinfo;
> +	struct v4l2_mbus_framefmt *format;
> +
> +	/*
> +	 * TODO (?): We should disallow setting formats on the source pad
> +	 * completely, as the SENINF can't perform any processing. This would
> +	 * however break usage of the test pattern generator, as there would be
> +	 * no way to configure formats at all when no active input is selected.
> +	 */

Could you instead expose the TPG as a new sub-device? We'll have internal
pads, too, in the future.

> +
> +	/*
> +	 * Default to the first format if the requested media bus code isn't
> +	 * supported.
> +	 */
> +	fmtinfo = mtk_seninf_format_info(fmt->format.code);
> +	if (!fmtinfo) {
> +		fmtinfo = &mtk_seninf_formats[0];
> +		fmt->format.code = fmtinfo->code;
> +	}
> +
> +	/* Interlaced formats are not supported yet. */
> +	fmt->format.field = V4L2_FIELD_NONE;
> +
> +	/* Store the format. */
> +	format = v4l2_subdev_state_get_stream_format(state, fmt->pad, fmt->stream);
> +	if (!format)
> +		return -EINVAL;
> +
> +	*format = fmt->format;
> +
> +	if (mtk_seninf_pad_is_source(priv, fmt->pad))
> +		return 0;
> +
> +	/* Propagate the format to the corresponding source pad. */
> +	format = v4l2_subdev_state_get_opposite_stream_format(state, fmt->pad,
> +							      fmt->stream);
> +	if (!format)
> +		return -EINVAL;
> +
> +	*format = fmt->format;
> +
> +	return 0;
> +}
> +
> +static int seninf_set_routing(struct v4l2_subdev *sd,
> +			      struct v4l2_subdev_state *state,
> +			      enum v4l2_subdev_format_whence which,
> +			      struct v4l2_subdev_krouting *routing)
> +{
> +	return __seninf_set_routing(sd, state, routing);
> +}
> +
> +static const struct v4l2_subdev_core_ops seninf_subdev_core_ops = {
> +	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> +	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
> +};
> +
> +static const struct v4l2_subdev_pad_ops seninf_subdev_pad_ops = {
> +	.init_cfg = seninf_init_cfg,
> +	.enum_mbus_code = seninf_enum_mbus_code,
> +	.get_fmt = v4l2_subdev_get_fmt,
> +	.set_fmt = seninf_set_fmt,
> +	.link_validate = v4l2_subdev_link_validate_default,
> +	.set_routing = seninf_set_routing,
> +	.enable_streams = seninf_enable_streams,
> +	.disable_streams = seninf_disable_streams,
> +};
> +
> +static const struct v4l2_subdev_ops seninf_subdev_ops = {
> +	.core = &seninf_subdev_core_ops,
> +	.pad = &seninf_subdev_pad_ops,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Media Entity Operations
> + */
> +
> +static const struct media_entity_operations seninf_media_ops = {
> +	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
> +	.link_validate = v4l2_subdev_link_validate,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Async Subdev Notifier
> + */
> +
> +struct mtk_seninf_async_subdev {
> +	struct v4l2_async_connection asc;
> +	struct mtk_seninf_input *input;
> +	unsigned int port;
> +};
> +
> +static int mtk_seninf_fwnode_parse(struct device *dev,
> +				   unsigned int id)

A better name for "id" would be "port".

> +
> +{
> +	static const char * const phy_names[] = { "csi0", "csi1", "csi2", "csi0b"};
> +	struct mtk_seninf *priv = dev_get_drvdata(dev);
> +	struct fwnode_handle *ep, *fwnode;
> +	struct mtk_seninf_input *input;
> +	struct mtk_seninf_async_subdev *asd;
> +	struct v4l2_fwnode_endpoint vep = {
> +		.bus_type = V4L2_MBUS_CSI2_DPHY,
> +	};

Fits on a single line.

> +	unsigned int port;
> +	int ret;
> +
> +	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), id, 0, 0);
> +	if (!ep)
> +		return 0;
> +
> +	fwnode = fwnode_graph_get_remote_endpoint(ep);
> +	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> +	if (ret) {
> +		dev_err(dev, "Failed to parse %pOF\n", to_of_node(fwnode));
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	asd = v4l2_async_nf_add_fwnode(&priv->notifier, fwnode,
> +				       struct mtk_seninf_async_subdev);
> +	if (IS_ERR(asd)) {
> +		ret = PTR_ERR(asd);
> +		goto out;
> +	}
> +
> +	port = vep.base.port;
> +	asd->port = port;
> +
> +	if (mtk_seninf_pad_is_source(priv, port)) {
> +		ret = 0;
> +		goto out;
> +	}
> +
> +	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY) {

As you requested D-PHY, there's no longer need to check it here.
(v4l2_fwnode_endpoint_parse() returns an error otherwise.)

> +		dev_err(dev, "Only CSI2 bus type is currently supported\n");
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	input = &priv->inputs[port];
> +
> +	input->pad = port;
> +	input->seninf_id = port_to_seninf_id[port];
> +	input->base = priv->base + 0x1000 * input->seninf_id;
> +	input->seninf = priv;
> +
> +	input->bus = vep.bus.mipi_csi2;
> +
> +	input->phy = devm_phy_get(dev, phy_names[port]);
> +	if (IS_ERR(input->phy)) {
> +		dev_err(dev, "failed to get phy:%ld\n", PTR_ERR(input->phy));
> +		ret = PTR_ERR(input->phy);
> +		goto out;
> +	}
> +	input->phy_mode = SENINF_PHY_MODE_4D1C;
> +
> +	asd->input = input;
> +
> +	ret = 0;
> +out:
> +	fwnode_handle_put(ep);
> +	fwnode_handle_put(fwnode);
> +	return ret;
> +}
> +
> +static int mtk_seninf_notifier_bound(struct v4l2_async_notifier *notifier,
> +				     struct v4l2_subdev *sd,
> +				     struct v4l2_async_connection *asc)
> +{
> +	struct mtk_seninf *priv = container_of(notifier, struct mtk_seninf, notifier);
> +	struct mtk_seninf_async_subdev *asd =
> +		container_of(asc, struct mtk_seninf_async_subdev, asc);
> +	struct device_link *link;
> +	int ret;
> +
> +	dev_dbg(priv->dev, "%s bound to SENINF port %u\n", sd->entity.name, asd->port);
> +
> +	if (mtk_seninf_pad_is_sink(priv, asd->port)) {
> +		struct mtk_seninf_input *input = asd->input;
> +
> +		input->source_sd = sd;
> +
> +		link = device_link_add(priv->dev, sd->dev,
> +				       DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);

Could you explain a little why do you need a device link here? Same below
actually.

> +		if (!link) {
> +			dev_err(priv->dev,
> +				"Failed to create device link from source %s\n", sd->name);
> +			return -EINVAL;
> +		}
> +
> +		ret = v4l2_create_fwnode_links_to_pad(sd, &priv->pads[input->pad],
> +						      MEDIA_LNK_FL_IMMUTABLE |
> +						      MEDIA_LNK_FL_ENABLED);
> +	} else {
> +		link = device_link_add(sd->dev, priv->dev,
> +				       DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
> +		if (!link) {
> +			dev_err(priv->dev,
> +				"Failed to create device link to output %s\n", sd->name);
> +			return -EINVAL;
> +		}
> +
> +		ret = v4l2_create_fwnode_links_to_pad(&priv->subdev,
> +						      &sd->entity.pads[0],
> +						      MEDIA_LNK_FL_IMMUTABLE |
> +						      MEDIA_LNK_FL_ENABLED);
> +	}
> +	if (ret) {
> +		dev_err(priv->dev, "Failed to create links between SENINF port %u and %s (%d)\n",
> +			asd->port, sd->entity.name, ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_seninf_notifier_complete(struct v4l2_async_notifier *notifier)
> +{
> +	struct mtk_seninf *priv = container_of(notifier, struct mtk_seninf, notifier);
> +	int ret;
> +
> +	ret = v4l2_device_register_subdev_nodes(&priv->v4l2_dev);
> +	if (ret) {
> +		dev_err(priv->dev, "Failed to register subdev nodes: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct v4l2_async_notifier_operations mtk_seninf_async_ops = {
> +	.bound = mtk_seninf_notifier_bound,
> +	.complete = mtk_seninf_notifier_complete,
> +};
> +
> +static int mtk_seninf_media_init(struct mtk_seninf *priv)
> +{
> +	struct media_device *media_dev = &priv->media_dev;
> +	const struct mtk_seninf_conf *conf = priv->conf;
> +	u8 num_pads = conf->nb_outputs + conf->nb_inputs;

unsigned int?

> +	struct media_pad *pads = priv->pads;
> +	struct device *dev = priv->dev;
> +	unsigned int i;
> +	int ret;
> +
> +	media_dev->dev = dev;
> +	strscpy(media_dev->model, conf->model, sizeof(media_dev->model));
> +	snprintf(media_dev->bus_info, sizeof(media_dev->bus_info),
> +		 "platform:%s", dev_name(dev));

media_device_init() already does this.

> +	media_dev->hw_revision = 0;
> +	media_device_init(media_dev);
> +
> +	for (i = 0; i < conf->nb_inputs; i++)
> +		pads[i].flags = MEDIA_PAD_FL_SINK;
> +	for (i = conf->nb_inputs; i < num_pads; i++)
> +		pads[i].flags = MEDIA_PAD_FL_SOURCE;
> +
> +	ret = media_entity_pads_init(&priv->subdev.entity, num_pads, pads);
> +	if (ret) {
> +		media_device_cleanup(media_dev);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_seninf_v4l2_async_register(struct mtk_seninf *priv)
> +{
> +	const struct mtk_seninf_conf *conf = priv->conf;
> +	struct device *dev = priv->dev;
> +	unsigned int i;
> +	int ret;
> +
> +	v4l2_async_nf_init(&priv->notifier, &priv->v4l2_dev);
> +
> +	for (i = 0; i < conf->nb_inputs + conf->nb_outputs; ++i) {
> +		ret = mtk_seninf_fwnode_parse(dev, i);
> +
> +		if (ret) {
> +			dev_err(dev, "Failed to parse endpoint at port %d, err: %d\n", i, ret);
> +			goto err_clean_notififer;
> +		}
> +	}
> +
> +	priv->notifier.ops = &mtk_seninf_async_ops;
> +	ret = v4l2_async_nf_register(&priv->notifier);
> +	if (ret) {
> +		dev_err(dev, "Failed to register async notifier: %d\n", ret);
> +		goto err_clean_notififer;
> +	}
> +	return 0;
> +
> +err_clean_notififer:
> +	v4l2_async_nf_cleanup(&priv->notifier);
> +
> +	return ret;
> +}
> +
> +static int mtk_seninf_v4l2_register(struct mtk_seninf *priv)
> +{
> +	struct v4l2_subdev *sd = &priv->subdev;
> +	struct device *dev = priv->dev;
> +	int ret;
> +
> +	/* Initialize media device & pads. */
> +	ret = mtk_seninf_media_init(priv);
> +	if (ret)
> +		return ret;
> +
> +	/* Initialize & register v4l2 device. */
> +	priv->v4l2_dev.mdev = &priv->media_dev;
> +
> +	ret = v4l2_device_register(dev, &priv->v4l2_dev);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "Failed to register V4L2 device: %d\n", ret);
> +		goto err_clean_media;
> +	}
> +
> +	/* Initialize & register subdev. */
> +	v4l2_subdev_init(sd, &seninf_subdev_ops);
> +	sd->dev = dev;
> +	sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
> +	sd->entity.ops = &seninf_media_ops;
> +	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS
> +		  |  V4L2_SUBDEV_FL_STREAMS;

Alignment. '|' should also be on the previous line, i.e. wrap after it.
The same applies to the rest of the set, too.

> +	strscpy(sd->name, dev_name(dev), sizeof(sd->name));
> +	ret = seninf_initialize_controls(priv);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "Failed to initialize controls: %d\n", ret);
> +		goto err_unreg_v4l2;
> +	}
> +	v4l2_set_subdevdata(sd, priv);
> +
> +	ret = v4l2_subdev_init_finalize(sd);
> +	if (ret)
> +		goto err_free_handler;
> +
> +	ret = v4l2_device_register_subdev(&priv->v4l2_dev, sd);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "Failed to register subdev: %d\n", ret);
> +		goto err_cleanup_subdev;
> +	}
> +
> +	/* Set up async device */
> +	ret = mtk_seninf_v4l2_async_register(priv);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "Failed to register v4l2 async notifier: %d\n", ret);
> +		goto err_unreg_subdev;
> +	}
> +
> +	/* Register media device */
> +	ret = media_device_register(&priv->media_dev);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "failed to register media device: %d\n", ret);
> +		goto err_unreg_notifier;
> +	}
> +
> +	return 0;
> +
> +err_unreg_notifier:
> +	v4l2_async_nf_unregister(&priv->notifier);
> +err_unreg_subdev:
> +	v4l2_device_unregister_subdev(sd);
> +err_cleanup_subdev:
> +	v4l2_subdev_cleanup(sd);
> +err_free_handler:
> +	v4l2_ctrl_handler_free(&priv->ctrl_handler);
> +err_unreg_v4l2:
> +	v4l2_device_unregister(&priv->v4l2_dev);
> +err_clean_media:
> +	media_entity_cleanup(&sd->entity);
> +	media_device_cleanup(&priv->media_dev);
> +
> +	return ret;
> +}
> +
> +static int seninf_probe(struct platform_device *pdev)
> +{
> +	/* List of clocks required by seninf. */

I think this comment is redundant.

> +	static const char * const clk_names[] = { "camsys", "top_mux" };
> +	struct device *dev = &pdev->dev;
> +	struct mtk_seninf *priv;
> +	unsigned int i;
> +	int ret;
> +
> +	priv = devm_kzalloc(dev, sizeof(struct mtk_seninf), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->conf = of_device_get_match_data(dev);
> +
> +	dev_set_drvdata(dev, priv);
> +	priv->dev = dev;
> +
> +	priv->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(priv->base))
> +		return PTR_ERR(priv->base);
> +
> +	priv->num_clks = ARRAY_SIZE(clk_names);
> +	priv->clks = devm_kcalloc(dev, priv->num_clks,
> +				  sizeof(*priv->clks), GFP_KERNEL);
> +	if (!priv->clks)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < priv->num_clks; ++i)
> +		priv->clks[i].id = clk_names[i];
> +
> +	ret = devm_clk_bulk_get(dev, priv->num_clks, priv->clks);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "failed to get seninf clock:%d\n", ret);
> +
> +	for (i = 0; i < priv->conf->nb_muxes; ++i) {
> +		struct mtk_seninf_mux *mux = &priv->muxes[i];
> +
> +		mux->pad = priv->conf->nb_inputs + i;
> +		mux->mux_id = i;
> +		mux->base = priv->base + 0x1000 * i;
> +		mux->seninf = priv;
> +	}
> +
> +	ret = mtk_seninf_v4l2_register(priv);
> +	if (ret)
> +		return ret;
> +
> +	devm_pm_runtime_enable(dev);
> +
> +	return ret;
> +}
> +
> +static int seninf_pm_suspend(struct device *dev)
> +{
> +	struct mtk_seninf *priv = dev_get_drvdata(dev);
> +
> +	dev_dbg(dev, "seninf runtime suspend\n");

Maybe this could be removed?

> +	clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
> +
> +	return 0;
> +}
> +
> +static int seninf_pm_resume(struct device *dev)
> +{
> +	struct mtk_seninf *priv = dev_get_drvdata(dev);
> +	int ret;
> +
> +	dev_dbg(dev, "seninf runtime resume\n");

This, too.

> +	ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
> +	if (ret) {
> +		dev_err(dev, "failed to enable clock:%d\n", ret);
> +		return ret;
> +	}
> +
> +	mtk_seninf_csi2_setup_phy(priv);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops runtime_pm_ops = {
> +	SET_RUNTIME_PM_OPS(seninf_pm_suspend, seninf_pm_resume, NULL)
> +	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
> +};
> +
> +static int seninf_remove(struct platform_device *pdev)
> +{
> +	struct mtk_seninf *priv = dev_get_drvdata(&pdev->dev);
> +
> +	media_device_unregister(&priv->media_dev);
> +	media_device_cleanup(&priv->media_dev);
> +	v4l2_async_nf_unregister(&priv->notifier);
> +	v4l2_async_nf_cleanup(&priv->notifier);
> +	v4l2_device_unregister_subdev(&priv->subdev);
> +	v4l2_subdev_cleanup(&priv->subdev);
> +	v4l2_ctrl_handler_free(&priv->ctrl_handler);
> +	media_entity_cleanup(&priv->subdev.entity);
> +	v4l2_device_unregister(&priv->v4l2_dev);
> +
> +	return 0;
> +}
> +
> +static const struct mtk_seninf_conf seninf_8365_conf = {
> +	.model = "mtk-camsys-3.0",
> +	.nb_inputs = 4,
> +	.nb_muxes = 6,
> +	.nb_outputs = 4,
> +};
> +
> +static const struct of_device_id mtk_seninf_of_match[] = {
> +	{ .compatible = "mediatek,mt8365-seninf", .data = &seninf_8365_conf },
> +	{ /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, mtk_seninf_of_match);
> +
> +static struct platform_driver seninf_pdrv = {
> +	.driver	= {
> +		.name = "mtk-seninf",
> +		.pm = &runtime_pm_ops,
> +		.of_match_table = mtk_seninf_of_match,
> +	},
> +	.probe	= seninf_probe,
> +	.remove	= seninf_remove,
> +};
> +
> +module_platform_driver(seninf_pdrv);
> +
> +MODULE_DESCRIPTION("MTK sensor interface driver");
> +MODULE_AUTHOR("Louis Kuo <louis.kuo at mediatek.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/seninf/mtk_seninf_reg.h b/drivers/media/platform/mediatek/isp/isp_30/seninf/mtk_seninf_reg.h
> new file mode 100644
> index 000000000000..768ad5d641be
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/seninf/mtk_seninf_reg.h
> @@ -0,0 +1,112 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2022 MediaTek Inc.
> + */
> +
> +#ifndef __SENINF_REG_H__
> +#define __SENINF_REG_H__
> +
> +#include <linux/bits.h>
> +
> +#define SENINF_TOP_CTRL							0x0000
> +#define SENINF_TOP_CTRL_MUX_LP_MODE					BIT(31)
> +#define SENINF_TOP_CTRL_SENINF_PCLK_EN					BIT(10)
> +#define SENINF_TOP_CTRL_SENINF2_PCLK_EN					BIT(11)
> +#define SENINF_TOP_MUX_CTRL						0x0008
> +#define SENINF_TOP_CAM_MUX_CTRL						0x0010
> +#define SENINF_TOP_PHY_SENINF_CTL_CSI0					0x001c
> +#define SENINF_TOP_PHY_SENINF_CTL_CSI0_DPHY_MODE			BIT(0)
> +#define SENINF_TOP_PHY_SENINF_CTL_CSI0_CK_SEL_1				GENMASK(10, 8)
> +#define SENINF_TOP_PHY_SENINF_CTL_CSI0_CK_SEL_2				GENMASK(13, 12)
> +#define SENINF_TOP_PHY_SENINF_CTL_CSI0_PHY_SENINF_LANE_MUX_CSI0_EN	BIT(31)
> +#define SENINF_TOP_PHY_SENINF_CTL_CSI1					0x0020
> +#define SENINF_TOP_PHY_SENINF_CTL_CSI1_DPHY_MODE			BIT(0)
> +#define SENINF_TOP_PHY_SENINF_CTL_CSI1_CK_SEL_1				GENMASK(10, 8)
> +#define SENINF_TOP_PHY_SENINF_CTL_CSI1_PHY_SENINF_LANE_MUX_CSI1_EN	BIT(31)
> +#define SENINF_CTRL							0x0200
> +#define SENINF_CTRL_SENINF_EN						BIT(0)
> +#define SENINF_CTRL_CSI2_SW_RST						BIT(7)
> +#define SENINF_CTRL_SENINF_SRC_SEL					GENMASK(14, 12)
> +#define SENINF_CTRL_PAD2CAM_DATA_SEL					GENMASK(30, 28)
> +#define SENINF_CTRL_EXT							0x0204
> +#define SENINF_CTRL_EXT_SENINF_TESTMDL_IP_EN				BIT(1)
> +#define SENINF_CTRL_EXT_SENINF_NCSI2_IP_EN				BIT(5)
> +#define SENINF_CTRL_EXT_SENINF_CSI2_IP_EN				BIT(6)
> +#define SENINF_TG1_PH_CNT						0x0600
> +#define SENINF_TG1_SEN_CK						0x0604
> +#define SENINF_TG1_TM_CTL						0x0608
> +#define SENINF_TG1_TM_CTL_TM_EN						BIT(0)
> +#define SENINF_TG1_TM_CTL_TM_FMT					BIT(2)
> +#define SENINF_TG1_TM_CTL_TM_PAT					GENMASK(7, 4)
> +#define SENINF_TG1_TM_CTL_TM_VSYNC					GENMASK(15, 8)
> +#define SENINF_TG1_TM_CTL_TM_DUMMYPXL					GENMASK(23, 16)
> +#define SENINF_TG1_TM_SIZE						0x060c
> +#define SENINF_TG1_TM_SIZE_TM_LINE					GENMASK(29, 16)
> +#define SENINF_TG1_TM_SIZE_TM_PXL					GENMASK(12, 0)
> +#define SENINF_TG1_TM_CLK						0x0610
> +#define TEST_MODEL_CLK_DIVIDED_CNT					8
> +#define SENINF_TG1_TM_STP						0x0614
> +#define TIME_STAMP_DIVIDER						1
> +#define MIPI_RX_CON24_CSI0						0x0824
> +#define MIPI_RX_CON24_CSI0_CSI0_BIST_LN0_MUX				GENMASK(25, 24)
> +#define MIPI_RX_CON24_CSI0_CSI0_BIST_LN1_MUX				GENMASK(27, 26)
> +#define MIPI_RX_CON24_CSI0_CSI0_BIST_LN2_MUX				GENMASK(29, 28)
> +#define MIPI_RX_CON24_CSI0_CSI0_BIST_LN3_MUX				GENMASK(31, 30)
> +#define SENINF_CSI2_CTL							0x0a00
> +#define SENINF_CSI2_CTL_DATA_LANE0_EN					BIT(0)
> +#define SENINF_CSI2_CTL_DATA_LANE1_EN					BIT(1)
> +#define SENINF_CSI2_CTL_DATA_LANE2_EN					BIT(2)
> +#define SENINF_CSI2_CTL_DATA_LANE3_EN					BIT(3)
> +#define SENINF_CSI2_CTL_CLOCK_LANE_EN					BIT(4)
> +#define SENINF_CSI2_CTL_HSRX_DET_EN					BIT(7)
> +#define SENINF_CSI2_CTL_ED_SEL						BIT(16)
> +#define DATA_HEADER_ORDER_DI_WCL_WCH					1
> +#define SENINF_CSI2_CTL_HS_TRAIL_EN					BIT(25)
> +#define SENINF_CSI2_CTL_CLOCK_HS_OPTION					BIT(27)
> +#define SENINF_CSI2_LNRD_TIMING						0x0a08
> +#define SENINF_CSI2_LNRD_TIMING_DATA_SETTLE_PARAMETER			GENMASK(15, 8)
> +#define SENINF_CSI2_DPCM						0x0a0c
> +#define SENINF_CSI2_DPCM_DI_30_DPCM_EN					BIT(7)
> +#define SENINF_CSI2_DPCM_DI_2A_DPCM_EN					BIT(15)
> +#define SENINF_CSI2_INT_EN						0x0a10
> +#define SENINF_CSI2_INT_STATUS						0x0a14
> +#define SENINF_CSI2_DGB_SEL						0x0a18
> +#define SENINF_CSI2_DGB_SEL_DEBUG_SEL					GENMASK(7, 0)
> +#define SENINF_CSI2_DGB_SEL_DEBUG_EN					BIT(31)
> +#define SENINF_CSI2_SPARE0						0x0a20
> +#define SENINF_CSI2_LNRC_FSM						0x0a28
> +#define SENINF_CSI2_HS_TRAIL						0x0a40
> +#define SENINF_CSI2_HS_TRAIL_HS_TRAIL_PARAMETER				GENMASK(7, 0)
> +#define SENINF_CSI2_RESYNC_MERGE_CTL					0x0a74
> +#define SENINF_CSI2_RESYNC_MERGE_CTL_CPHY_LANE_RESYNC_CNT		GENMASK(2, 0)
> +#define SENINF_CSI2_RESYNC_MERGE_CTL_BYPASS_LANE_RESYNC			BIT(10)
> +#define SENINF_CSI2_RESYNC_MERGE_CTL_CDPHY_SEL				BIT(11)
> +#define SENINF_CSI2_MODE						0x0ae8
> +#define SENINF_CSI2_MODE_CSR_CSI2_MODE					GENMASK(7, 0)
> +#define SENINF_CSI2_MODE_CSR_CSI2_HEADER_LEN				GENMASK(10, 8)
> +#define SENINF_CSI2_DPHY_SYNC						0x0b20
> +#define SENINF_CSI2_DPHY_SYNC_SYNC_SEQ_MASK_0				GENMASK(15, 0)
> +#define SENINF_CSI2_DPHY_SYNC_SYNC_SEQ_PAT_0				GENMASK(31, 16)
> +#define SENINF_MUX_CTRL							0x0d00
> +#define SENINF_MUX_CTRL_SENINF_MUX_SW_RST				BIT(0)
> +#define SENINF_MUX_CTRL_SENINF_IRQ_SW_RST				BIT(1)
> +#define SENINF_MUX_CTRL_SENINF_HSYNC_MASK				BIT(7)
> +#define SENINF_MUX_CTRL_SENINF_PIX_SEL					BIT(8)
> +#define SENINF_MUX_CTRL_SENINF_VSYNC_POL				BIT(9)
> +#define SENINF_MUX_CTRL_SENINF_HSYNC_POL				BIT(10)
> +#define SENINF_MUX_CTRL_SENINF_SRC_SEL					GENMASK(15, 12)
> +#define SENINF_MUX_CTRL_FIFO_PUSH_EN					GENMASK(21, 16)
> +#define FIFO_PUSH_EN_NORMAL_MODE					0x1f
> +#define FIFO_PUSH_EN_JPEG_2_PIXEL_MODE					0x1e
> +#define SENINF_MUX_CTRL_FIFO_FLUSH_EN					GENMASK(28, 22)
> +#define FIFO_FLUSH_EN_NORMAL_MODE					0x1b
> +#define FIFO_FLUSH_EN_JPEG_2_PIXEL_MODE					0x18
> +#define SENINF_MUX_CTRL_FIFO_FULL_WR_EN					GENMASK(29, 28)
> +#define SENINF_MUX_CTRL_SENINF_MUX_EN					BIT(31)
> +#define SENINF_MUX_INTEN						0x0d04
> +#define SENINF_MUX_SPARE						0x0d2c
> +#define SENINF_MUX_CTRL_EXT						0x0d3c
> +#define SENINF_MUX_CTRL_EXT_SENINF_SRC_SEL_EXT				GENMASK(1, 0)
> +#define SENINF_MUX_CTRL_EXT_SENINF_PIX_SEL_EXT				BIT(4)
> +
> +#endif /* __SENINF_REG_H__ */

-- 
Kind regards,

Sakari Ailus


From vigneshr at ti.com  Thu Feb 15 01:21:44 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 15 Feb 2024 14:51:44 +0530
Subject: (subset) [PATCH 01/11] arm64: dts: ti: k3-am64: Convert serdes_ln_ctrl node into reg-mux
In-Reply-To: <20240124184722.150615-1-afd@ti.com>
References: <20240124184722.150615-1-afd@ti.com>
Message-ID: <170798859433.1495814.14458901296374501325.b4-ty@ti.com>

Hi Andrew Davis,

On Wed, 24 Jan 2024 12:47:12 -0600, Andrew Davis wrote:
> This removes a dependency on the parent node being a syscon node.
> Convert from mmio-mux to reg-mux adjusting node name and properties
> as needed.
> 
> 

Dropping 2/11 as indicated. Rest applied.

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[01/11] arm64: dts: ti: k3-am64: Convert serdes_ln_ctrl node into reg-mux
        commit: 91e93fdae6bab038f5913f766a9640371f9c630a
[02/11] arm64: dts: tidd: k3-am65: Convert serdes_mux node into reg-mux
        (no commit info)
[03/11] arm64: dts: ti: k3-j7200: Convert serdes_ln_ctrl node into reg-mux
        commit: 80d835defb8c9c696be35d86cb7949e5e7c0f1f6
[04/11] arm64: dts: ti: k3-j7200: Convert usb_serdes_mux node into reg-mux
        commit: 6b52caf93289a0f0f9980b7d21a5ae376c2afe8e
[05/11] arm64: dts: ti: k3-j721e: Convert serdes_ln_ctrl node into reg-mux
        commit: 4cd6d56c3c81e31aba3d69a6cf872770e8945dc7
[06/11] arm64: dts: ti: k3-j721e: Convert usb_serdes_mux node into reg-mux
        commit: 62b19a64e121e9ce081d18a77436a846585b9c7e
[07/11] arm64: dts: ti: k3-j721s2: Convert usb_serdes_mux node into reg-mux
        commit: 6b3a4da3ed71473126036c363261c5f1271e8e51
[08/11] arm64: dts: ti: k3-j721s2: Convert serdes_ln_ctrl node into reg-mux
        commit: 0985bf59052fbc932ff05ea760c8d177f390f20c
[09/11] arm64: dts: ti: k3-j7200: Make the FSS node a simple-bus
        commit: 3829ee48a4c44c28e397859c8df1d9e2ed7c5b3b
[10/11] arm64: dts: ti: k3-am62: Make the main_conf node a simple-bus
        commit: 3f6de97ee917ddabea8dcfab315fa6806cf7f230
[11/11] arm64: dts: ti: k3-am62a: Make the main_conf node a simple-bus
        commit: ad163bb36344f0432d8aee48553a17997b926c29

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Thu Feb 15 01:24:34 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 15 Feb 2024 14:54:34 +0530
Subject: [PATCH v2 0/3] arm64: dts: ti: am65x: Add PCIe + USB DT overlay files
In-Reply-To: <20240208-for-v6-9-am65-overlays-2-0-v2-0-70bae3e91597@kernel.org>
References: <20240208-for-v6-9-am65-overlays-2-0-v2-0-70bae3e91597@kernel.org>
Message-ID: <170798904376.1504164.3974928327305600054.b4-ty@ti.com>

Hi Roger Quadros,

On Thu, 08 Feb 2024 15:51:42 +0200, Roger Quadros wrote:
> There are 2 types of (PCIe + USB) expansion cards that are provided with
> the AM654 board configurations.
> 
> 1) 2 lane PCIe + USB 2.0 card is supplied with the AM65 IDK
> configuration [1]
> 
> 2) 1 lane PCIe + USB 3.0 card is supplied with the AM65 GP EVM
> configuration [2]
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/3] arm64: dts: ti: am65x: Fix dtbs_install for Rocktech OLDI overlay
      commit: 8ada14cafc5e185c668198617cd1ab4f1d8d325a
[2/3] arm64: dts: ti: Add DT overlay for PCIe + USB2.0 SERDES personality card
      commit: aea902b9e0cb9c596aa2e70a9c8d7d7a15673e45
[3/3] arm64: dts: ti: Add DT overlay for PCIe + USB3.0 SERDES personality card
      commit: c472011e7aeef5f7a7d9f40c3c275d8ab82aa745

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From abel.vesa at linaro.org  Thu Feb 15 01:25:38 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Thu, 15 Feb 2024 11:25:38 +0200
Subject: [PATCH RFC v3 1/4] dt-bindings: spmi: Add PMIC ARB v7 schema
In-Reply-To: <ea9d31c4-e5c4-4869-8bf9-caef3dd32829@kernel.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-1-0bae0ef04faf@linaro.org>
 <ea9d31c4-e5c4-4869-8bf9-caef3dd32829@kernel.org>
Message-ID: <Zc3YkgrkauRcZfNB@linaro.org>

On 24-02-15 09:54:37, Krzysztof Kozlowski wrote:
> On 14/02/2024 22:13, Abel Vesa wrote:
> > Add dedicated schema for PMIC ARB v7 as it allows multiple
> > buses by declaring them as child nodes. These child nodes
> > will follow the generic spmi bus bindings.
> > 
> > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > ---
> 
> Please use scripts/get_maintainers.pl to get a list of necessary people
> and lists to CC. It might happen, that command when run on an older
> kernel, gives you outdated entries. Therefore please be sure you base
> your patches on recent Linux kernel.
> 
> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
> people, so fix your workflow. Tools might also fail if you work on some
> ancient tree (don't, instead use mainline), work on fork of kernel
> (don't, instead use mainline) or you ignore some maintainers (really
> don't). Just use b4 and everything should be fine, although remember
> about `b4 prep --auto-to-cc` if you added new patches to the patchset.
> 
> You missed at least devicetree list (maybe more), so this won't be
> tested by automated tooling. Performing review on untested code might be
> a waste of time, thus I will skip this patch entirely till you follow
> the process allowing the patch to be tested.
> 
> Please kindly resend and include all necessary To/Cc entries.
> 

Forgot to run "b4 prep --auto-to-cc" AFTER I added the bindings patch.
Sorry about that. Will do it for the next version.

> 
> Best regards,
> Krzysztof
> 


From dmitry.baryshkov at linaro.org  Thu Feb 15 01:25:33 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 15 Feb 2024 11:25:33 +0200
Subject: [PATCH v2 2/6] dt-bindings: arm-smmu: Document SM8650 GPU SMMU
In-Reply-To: <20240215-topic-sm8650-gpu-v2-2-6be0b4bf2e09@linaro.org>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org> <20240215-topic-sm8650-gpu-v2-2-6be0b4bf2e09@linaro.org>
Message-ID: <CAA8EJprpYEhGi5b+uWGWtOa+qbSwUR8C0j9NLC+ah_-nvy-=Ng@mail.gmail.com>

On Thu, 15 Feb 2024 at 11:20, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>
> Document the GPU SMMU found on the SM8650 platform.
>
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---
>  Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> index a4042ae24770..3ad5c850f3bf 100644
> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> @@ -93,6 +93,7 @@ properties:
>                - qcom,sm8350-smmu-500
>                - qcom,sm8450-smmu-500
>                - qcom,sm8550-smmu-500
> +              - qcom,sm8650-smmu-500
>            - const: qcom,adreno-smmu
>            - const: qcom,smmu-500
>            - const: arm,mmu-500
> @@ -508,7 +509,10 @@ allOf:
>    - if:
>        properties:
>          compatible:
> -          const: qcom,sm8550-smmu-500
> +          contains:
> +            enum:
> +              - qcom,sm8550-smmu-500
> +              - qcom,sm8650-smmu-500

Doesn't this cause warnings for non-GPU SMMU on this platform?

>      then:
>        properties:
>          clock-names:
> @@ -544,7 +548,6 @@ allOf:
>                - qcom,sdx65-smmu-500
>                - qcom,sm6350-smmu-500
>                - qcom,sm6375-smmu-500
> -              - qcom,sm8650-smmu-500
>                - qcom,x1e80100-smmu-500
>      then:
>        properties:
>
> --
> 2.34.1
>


-- 
With best wishes
Dmitry


From vigneshr at ti.com  Thu Feb 15 01:26:01 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 15 Feb 2024 14:56:01 +0530
Subject: [PATCH v2 1/2] arm64: dts: ti: k3-am69-sk: fix PMIC interrupt number
In-Reply-To: <20240209171146.307465-1-romain.naour@smile.fr>
References: <20240209171146.307465-1-romain.naour@smile.fr>
Message-ID: <170798813443.1487216.13269796960509910423.b4-ty@ti.com>

Hi Romain Naour,

On Fri, 09 Feb 2024 18:11:45 +0100, Romain Naour wrote:
> The tps659413 node set WKUP_GPIO0_83 (AA37) pin as input to be used as
> PMIC interrupt but uses 39 (WKUP_GPIO0_39) as "interrupts" property.
> 
> Replace 39 by 83 after checking in the board schematic [1].
> 
> [1] https://www.ti.com/tool/SK-AM69
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/2] arm64: dts: ti: k3-am69-sk: fix PMIC interrupt number
      commit: 9673acae37ce06bebfe75b38c15952cab05da896
[2/2] arm64: dts: ti: k3-j721e-sk: fix PMIC interrupt number
      commit: 59974c38ded179cac63a3fa1a8adaaa1048cdc41

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Thu Feb 15 01:26:17 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 15 Feb 2024 14:56:17 +0530
Subject: [PATCH v3] arm64: dts: ti: am62-phyboard-lyra: Add overlay to enable a GPIO fan
In-Reply-To: <20240213005248.1027842-1-nmorrisson@phytec.com>
References: <20240213005248.1027842-1-nmorrisson@phytec.com>
Message-ID: <170798813444.1487216.17136908853088424547.b4-ty@ti.com>

Hi Nathan Morrisson,

On Mon, 12 Feb 2024 16:52:48 -0800, Nathan Morrisson wrote:
> The phyBOARD-Lyra has a GPIO fan header. This overlay enables the fan
> header and sets the fan to turn on at 65C.
> 
> 

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: am62-phyboard-lyra: Add overlay to enable a GPIO fan
      commit: 192a0c70ef164b7b00a9d0126d961f10318e058a

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From abel.vesa at linaro.org  Thu Feb 15 01:26:49 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Thu, 15 Feb 2024 11:26:49 +0200
Subject: [PATCH RFC v3 3/4] spmi: pmic-arb: Make core resources acquiring
 a version operation
In-Reply-To: <5e878fd9-8215-499d-ac1c-191cb5bfe798@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-3-0bae0ef04faf@linaro.org>
 <d9d8e86b-a499-49d1-90ad-6fae5b7dcbb7@linaro.org>
 <Zc0yXR/fC2OcObLB@linaro.org>
 <5e878fd9-8215-499d-ac1c-191cb5bfe798@linaro.org>
Message-ID: <Zc3Y2YmjZ1gYjmmq@linaro.org>

On 24-02-14 22:44:55, Konrad Dybcio wrote:
> On 14.02.2024 22:36, Abel Vesa wrote:
> > On 24-02-14 22:18:33, Konrad Dybcio wrote:
> >> On 14.02.2024 22:13, Abel Vesa wrote:
> >>> Rather than setting up the core, obsrv and chnls in probe by using
> >>> version specific conditionals, add a dedicated "get_core_resources"
> >>> version specific op and move the acquiring in there.
> >>>
> >>> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> >>> ---
> >>>  drivers/spmi/spmi-pmic-arb.c | 111 ++++++++++++++++++++++++++++++-------------
> >>>  1 file changed, 78 insertions(+), 33 deletions(-)
> >>>
> >>> diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> >>> index 23939c0d225f..489556467a4c 100644
> >>> --- a/drivers/spmi/spmi-pmic-arb.c
> >>> +++ b/drivers/spmi/spmi-pmic-arb.c
> >>> @@ -203,6 +203,7 @@ struct spmi_pmic_arb {
> >>>   */
> >>>  struct pmic_arb_ver_ops {
> >>>  	const char *ver_str;
> >>> +	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
> >>>  	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
> >>>  	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
> >>>  	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
> >>> @@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
> >>>  	return 0;
> >>>  }
> >>>  
> >>> +static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
> >>> +					  void __iomem *core)
> >>> +{
> >>> +	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> >>> +
> >>> +	pmic_arb->wr_base = core;
> >>> +	pmic_arb->rd_base = core;
> >>> +
> >>> +	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
> >>> +
> >>> +	return 0;
> >>> +}
> >>> +
> >>>  static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
> >>>  {
> >>>  	u32 *mapping_table;
> >>> @@ -1063,6 +1077,41 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
> >>>  	return apid;
> >>>  }
> >>>  
> >>> +static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
> >>> +{
> >>> +	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> >>> +	struct device *dev = &pdev->dev;
> >>> +	struct resource *res;
> >>> +
> >>> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> >>
> >> It's no longer indented to deep, no need to keep such aggressive wrapping
> >>
> > 
> > The pmic_arb_get_obsrvr_chnls_v2 is used by both:
> > pmic_arb_get_core_resources_v2
> > pmic_arb_get_core_resources_v7
> 
> I meant line wrapping

Oh, ok. Will do.

> 
> > 
> >>> +					   "obsrvr");
> >>> +	pmic_arb->rd_base = devm_ioremap(dev, res->start,
> >>> +					 resource_size(res));
> >>> +	if (IS_ERR(pmic_arb->rd_base))
> >>> +		return PTR_ERR(pmic_arb->rd_base);
> >>> +
> >>> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> >>> +					   "chnls");
> >>> +	pmic_arb->wr_base = devm_ioremap(dev, res->start,
> >>> +					 resource_size(res));
> >>> +	if (IS_ERR(pmic_arb->wr_base))
> >>> +		return PTR_ERR(pmic_arb->wr_base);
> >>
> >> Could probably make it "devm_platform_get_and_ioremap_resource "
> > 
> > The reason this needs to stay as is is because of reason explained by
> > the following comment found in probe:
> > 
> > /*                                                                           
> >  * Please don't replace this with devm_platform_ioremap_resource() or        
> >  * devm_ioremap_resource().  These both result in a call to                  
> >  * devm_request_mem_region() which prevents multiple mappings of this        
> >  * register address range.  SoCs with PMIC arbiter v7 may define two         
> >  * arbiter devices, for the two physical SPMI interfaces, which  share       
> >  * some register address ranges (i.e. "core", "obsrvr", and "chnls").        
> >  * Ensure that both devices probe successfully by calling devm_ioremap()     
> >  * which does not result in a devm_request_mem_region() call.                
> >  */                                                                          
> > 
> > Even though, AFAICT, there is no platform that adds a second node for
> > the second bus, currently, in mainline, we should probably allow the
> > "legacy" approach to still work.
> 
> OK right, let's keep it.
> 
> Konrad


From Jonathan.Cameron at Huawei.com  Thu Feb 15 01:27:12 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 15 Feb 2024 09:27:12 +0000
Subject: [PATCH v2] perf: CXL: fix CPMU filter value mask length
In-Reply-To: <20240215080906epcms2p2c49c6b9bfe271e1d089ad35ab527b958@epcms2p2>
References: <CGME20240215080906epcms2p2c49c6b9bfe271e1d089ad35ab527b958@epcms2p2>
	<20240215080906epcms2p2c49c6b9bfe271e1d089ad35ab527b958@epcms2p2>
Message-ID: <20240215092712.000048cd@Huawei.com>

On Thu, 15 Feb 2024 17:09:06 +0900
Hojin Nam <hj96.nam at samsung.com> wrote:

> CPMU filter value is described as 4B length in CXL r3.0 8.2.7.2.2.
> However, it is used as 2B length in code and comments.
> 
> Signed-off-by: Hojin Nam <hj96.nam at samsung.com>

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

Thanks for tidying this up.

> ---
> 
> Hi Jonathan,
> as you said, I didn't actually hit this. I just found it by simply
> comparing the code to the CXL Spec. I removed Fixes tag and 
> repaired broken sign off, Thank you!
> 
> Changes since v1:
> - Remove Fixes tag (Jonathan)
> - Repair broken sign off (Jonathan)
> 
>  drivers/perf/cxl_pmu.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
> index 365d964b0f6a..ca5e92f28b4a 100644
> --- a/drivers/perf/cxl_pmu.c
> +++ b/drivers/perf/cxl_pmu.c
> @@ -59,7 +59,7 @@
>  #define   CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK     GENMASK_ULL(63, 59)
> 
>  #define CXL_PMU_FILTER_CFG_REG(n, f)   (0x400 + 4 * ((f) + (n) * 8))
> -#define   CXL_PMU_FILTER_CFG_VALUE_MSK                 GENMASK(15, 0)
> +#define   CXL_PMU_FILTER_CFG_VALUE_MSK                 GENMASK(31, 0)
> 
>  #define CXL_PMU_COUNTER_REG(n)         (0xc00 + 8 * (n))
> 
> @@ -314,9 +314,9 @@ static bool cxl_pmu_config1_get_edge(struct perf_event *event)
>  }
> 
>  /*
> - * CPMU specification allows for 8 filters, each with a 16 bit value...
> - * So we need to find 8x16bits to store it in.
> - * As the value used for disable is 0xffff, a separate enable switch
> + * CPMU specification allows for 8 filters, each with a 32 bit value...
> + * So we need to find 8x32bits to store it in.
> + * As the value used for disable is 0xffff_ffff, a separate enable switch
>   * is needed.
>   */
> 
> @@ -642,7 +642,7 @@ static void cxl_pmu_event_start(struct perf_event *event, int flags)
>                 if (cxl_pmu_config1_hdm_filter_en(event))
>                         cfg = cxl_pmu_config2_get_hdm_decoder(event);
>                 else
> -                       cfg = GENMASK(15, 0); /* No filtering if 0xFFFF_FFFF */
> +                       cfg = GENMASK(31, 0); /* No filtering if 0xFFFF_FFFF */
>                 writeq(cfg, base + CXL_PMU_FILTER_CFG_REG(hwc->idx, 0));
>         }
> 
> --
> 2.34.1



From neil.armstrong at linaro.org  Thu Feb 15 01:29:56 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Thu, 15 Feb 2024 10:29:56 +0100
Subject: [PATCH v2 2/6] dt-bindings: arm-smmu: Document SM8650 GPU SMMU
In-Reply-To: <CAA8EJprpYEhGi5b+uWGWtOa+qbSwUR8C0j9NLC+ah_-nvy-=Ng@mail.gmail.com>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
 <20240215-topic-sm8650-gpu-v2-2-6be0b4bf2e09@linaro.org>
 <CAA8EJprpYEhGi5b+uWGWtOa+qbSwUR8C0j9NLC+ah_-nvy-=Ng@mail.gmail.com>
Message-ID: <ffb16ef6-fc9a-42b1-b9c3-4e8f6b52d849@linaro.org>

On 15/02/2024 10:25, Dmitry Baryshkov wrote:
> On Thu, 15 Feb 2024 at 11:20, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>>
>> Document the GPU SMMU found on the SM8650 platform.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
>> ---
>>   Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 7 +++++--
>>   1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
>> index a4042ae24770..3ad5c850f3bf 100644
>> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
>> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
>> @@ -93,6 +93,7 @@ properties:
>>                 - qcom,sm8350-smmu-500
>>                 - qcom,sm8450-smmu-500
>>                 - qcom,sm8550-smmu-500
>> +              - qcom,sm8650-smmu-500
>>             - const: qcom,adreno-smmu
>>             - const: qcom,smmu-500
>>             - const: arm,mmu-500
>> @@ -508,7 +509,10 @@ allOf:
>>     - if:
>>         properties:
>>           compatible:
>> -          const: qcom,sm8550-smmu-500
>> +          contains:
>> +            enum:
>> +              - qcom,sm8550-smmu-500
>> +              - qcom,sm8650-smmu-500
> 
> Doesn't this cause warnings for non-GPU SMMU on this platform?

No because it doesn't add those to required, it simply allows clock the properties.

> 
>>       then:
>>         properties:
>>           clock-names:
>> @@ -544,7 +548,6 @@ allOf:
>>                 - qcom,sdx65-smmu-500
>>                 - qcom,sm6350-smmu-500
>>                 - qcom,sm6375-smmu-500
>> -              - qcom,sm8650-smmu-500
>>                 - qcom,x1e80100-smmu-500
>>       then:
>>         properties:
>>
>> --
>> 2.34.1
>>
> 
> 



From dmitry.baryshkov at linaro.org  Thu Feb 15 01:30:23 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 15 Feb 2024 11:30:23 +0200
Subject: [PATCH RFC v3 3/4] spmi: pmic-arb: Make core resources acquiring
 a version operation
In-Reply-To: <Zc0yXR/fC2OcObLB@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-3-0bae0ef04faf@linaro.org>
 <d9d8e86b-a499-49d1-90ad-6fae5b7dcbb7@linaro.org> <Zc0yXR/fC2OcObLB@linaro.org>
Message-ID: <CAA8EJpq=kYeZfNbFtfQ_oLS0Xi4imyEGV+dDNO+h6LZfqmpxZg@mail.gmail.com>

On Wed, 14 Feb 2024 at 23:36, Abel Vesa <abel.vesa at linaro.org> wrote:
>
> On 24-02-14 22:18:33, Konrad Dybcio wrote:
> > On 14.02.2024 22:13, Abel Vesa wrote:
> > > Rather than setting up the core, obsrv and chnls in probe by using
> > > version specific conditionals, add a dedicated "get_core_resources"
> > > version specific op and move the acquiring in there.
> > >
> > > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > > ---
> > >  drivers/spmi/spmi-pmic-arb.c | 111 ++++++++++++++++++++++++++++++-------------
> > >  1 file changed, 78 insertions(+), 33 deletions(-)
> > >
> > > diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> > > index 23939c0d225f..489556467a4c 100644
> > > --- a/drivers/spmi/spmi-pmic-arb.c
> > > +++ b/drivers/spmi/spmi-pmic-arb.c
> > > @@ -203,6 +203,7 @@ struct spmi_pmic_arb {
> > >   */
> > >  struct pmic_arb_ver_ops {
> > >     const char *ver_str;
> > > +   int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
> > >     int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
> > >     int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
> > >     /* spmi commands (read_cmd, write_cmd, cmd) functionality */
> > > @@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
> > >     return 0;
> > >  }
> > >
> > > +static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
> > > +                                     void __iomem *core)
> > > +{
> > > +   struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> > > +
> > > +   pmic_arb->wr_base = core;
> > > +   pmic_arb->rd_base = core;
> > > +
> > > +   pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
> > > +
> > > +   return 0;
> > > +}
> > > +
> > >  static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
> > >  {
> > >     u32 *mapping_table;
> > > @@ -1063,6 +1077,41 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
> > >     return apid;
> > >  }
> > >
> > > +static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
> > > +{
> > > +   struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> > > +   struct device *dev = &pdev->dev;
> > > +   struct resource *res;
> > > +
> > > +   res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> >
> > It's no longer indented to deep, no need to keep such aggressive wrapping
> >
>
> The pmic_arb_get_obsrvr_chnls_v2 is used by both:
> pmic_arb_get_core_resources_v2
> pmic_arb_get_core_resources_v7
>
> > > +                                      "obsrvr");
> > > +   pmic_arb->rd_base = devm_ioremap(dev, res->start,
> > > +                                    resource_size(res));
> > > +   if (IS_ERR(pmic_arb->rd_base))
> > > +           return PTR_ERR(pmic_arb->rd_base);
> > > +
> > > +   res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > > +                                      "chnls");
> > > +   pmic_arb->wr_base = devm_ioremap(dev, res->start,
> > > +                                    resource_size(res));
> > > +   if (IS_ERR(pmic_arb->wr_base))
> > > +           return PTR_ERR(pmic_arb->wr_base);
> >
> > Could probably make it "devm_platform_get_and_ioremap_resource "
>
> The reason this needs to stay as is is because of reason explained by
> the following comment found in probe:
>
> /*
>  * Please don't replace this with devm_platform_ioremap_resource() or
>  * devm_ioremap_resource().  These both result in a call to
>  * devm_request_mem_region() which prevents multiple mappings of this
>  * register address range.  SoCs with PMIC arbiter v7 may define two
>  * arbiter devices, for the two physical SPMI interfaces, which  share
>  * some register address ranges (i.e. "core", "obsrvr", and "chnls").
>  * Ensure that both devices probe successfully by calling devm_ioremap()
>  * which does not result in a devm_request_mem_region() call.
>  */
>
> Even though, AFAICT, there is no platform that adds a second node for
> the second bus, currently, in mainline, we should probably allow the
> "legacy" approach to still work.

If there were no DT files which used two SPMI devices, I think we
should drop this comment and use existing helpers. We must keep
compatibility with the existing DTs, not with the _possible_ device
trees.

>
> >
> > Konrad



-- 
With best wishes
Dmitry


From vigneshr at ti.com  Thu Feb 15 01:31:29 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 15 Feb 2024 15:01:29 +0530
Subject: [PATCH v2] arm64: dts: ti: verdin-am62: add support for Verdin USB1 interface
In-Reply-To: <20240209130106.38739-1-andrejs.cainikovs@gmail.com>
References: <20240209130106.38739-1-andrejs.cainikovs@gmail.com>
Message-ID: <170798947718.1512489.5264967357166684685.b4-ty@ti.com>

Hi Andrejs Cainikovs,

On Fri, 09 Feb 2024 14:01:06 +0100, Andrejs Cainikovs wrote:
> Add support for Verdin USB1 interface, implements role switch
> functionality using "gpio-usb-b-connector", VBUS is also now
> controlled with "regulator-fixed" using a standard GPIO.
> 
> 

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: verdin-am62: add support for Verdin USB1 interface
      commit: 5125c19d75d8d9609dbcca1201f393fcb3b41c1d

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From alexander.stein at ew.tq-group.com  Thu Feb 15 01:32:12 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Thu, 15 Feb 2024 10:32:12 +0100
Subject: [PATCH v5 0/2] extcon-usb-gpio YAML conversion
Message-ID: <20240215093214.796821-1-alexander.stein@ew.tq-group.com>

Hi everyone,

it seems these two patches got missed from v4[1]. So v5 is a new version only
containing the patches not applied yet. The rebase also includes a slight
change to the mediatek patch.

Changes in v5:
* rebased to next-20240215

Best regards,
Alexander

[1] https://lore.kernel.org/all/20230724103914.1779027-1-alexander.stein at ew.tq-group.com/

Alexander Stein (2):
  dt-bindings: extcon-usb-gpio: convert to DT schema format
  arm64: dts: mediatek: Replace deprecated extcon-usb-gpio
    id-gpio/vbus-gpio properties

 .../bindings/extcon/extcon-usb-gpio.txt       | 21 --------
 .../bindings/extcon/extcon-usb-gpio.yaml      | 51 +++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt2712-evb.dts   |  4 +-
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts   |  2 +-
 4 files changed, 54 insertions(+), 24 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/extcon/extcon-usb-gpio.txt
 create mode 100644 Documentation/devicetree/bindings/extcon/extcon-usb-gpio.yaml

-- 
2.34.1



From alexander.stein at ew.tq-group.com  Thu Feb 15 01:32:13 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Thu, 15 Feb 2024 10:32:13 +0100
Subject: [PATCH v5 1/2] dt-bindings: extcon-usb-gpio: convert to DT schema format
In-Reply-To: <20240215093214.796821-1-alexander.stein@ew.tq-group.com>
References: <20240215093214.796821-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240215093214.796821-2-alexander.stein@ew.tq-group.com>

Convert the binding to DT schema format. Change the GPIO properties to new
naming convention using -gpios as well.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/extcon/extcon-usb-gpio.txt       | 21 --------
 .../bindings/extcon/extcon-usb-gpio.yaml      | 51 +++++++++++++++++++
 2 files changed, 51 insertions(+), 21 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/extcon/extcon-usb-gpio.txt
 create mode 100644 Documentation/devicetree/bindings/extcon/extcon-usb-gpio.yaml

diff --git a/Documentation/devicetree/bindings/extcon/extcon-usb-gpio.txt b/Documentation/devicetree/bindings/extcon/extcon-usb-gpio.txt
deleted file mode 100644
index dfc14f71e81fb..0000000000000
--- a/Documentation/devicetree/bindings/extcon/extcon-usb-gpio.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-USB GPIO Extcon device
-
-This is a virtual device used to generate USB cable states from the USB ID pin
-connected to a GPIO pin.
-
-Required properties:
-- compatible: Should be "linux,extcon-usb-gpio"
-
-Either one of id-gpio or vbus-gpio must be present. Both can be present as well.
-- id-gpio: gpio for USB ID pin. See gpio binding.
-- vbus-gpio: gpio for USB VBUS pin.
-
-Example: Examples of extcon-usb-gpio node in dra7-evm.dts as listed below:
-	extcon_usb1 {
-		compatible = "linux,extcon-usb-gpio";
-		id-gpio = <&gpio6 1 GPIO_ACTIVE_HIGH>;
-	}
-
-	&omap_dwc3_1 {
-		extcon = <&extcon_usb1>;
-	};
diff --git a/Documentation/devicetree/bindings/extcon/extcon-usb-gpio.yaml b/Documentation/devicetree/bindings/extcon/extcon-usb-gpio.yaml
new file mode 100644
index 0000000000000..136f865b87816
--- /dev/null
+++ b/Documentation/devicetree/bindings/extcon/extcon-usb-gpio.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/extcon/extcon-usb-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: USB GPIO Extcon device
+
+maintainers:
+  - Alexander Stein <alexander.stein at ew.tq-group.com>
+
+description:
+  This is a virtual device used to generate USB cable states from the
+  USB ID pin connected to a GPIO pin.
+  Deprecated, use USB connector node instead.
+
+deprecated: true
+
+properties:
+  compatible:
+    const: linux,extcon-usb-gpio
+
+  id-gpios:
+    description: An input gpio for USB ID pin.
+    maxItems: 1
+
+  vbus-gpios:
+    description: An input gpio for USB VBus pin, used to detect presence of
+      VBUS 5V.
+    maxItems: 1
+
+required:
+  - compatible
+
+anyOf:
+  - required:
+      - id-gpios
+  - required:
+      - vbus-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    extcon-usb1 {
+      compatible = "linux,extcon-usb-gpio";
+      id-gpios = <&gpio6 1 GPIO_ACTIVE_HIGH>;
+      vbus-gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>;
+    };
-- 
2.34.1



From dmitry.baryshkov at linaro.org  Thu Feb 15 01:32:10 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 15 Feb 2024 11:32:10 +0200
Subject: [PATCH v2 2/6] dt-bindings: arm-smmu: Document SM8650 GPU SMMU
In-Reply-To: <ffb16ef6-fc9a-42b1-b9c3-4e8f6b52d849@linaro.org>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
 <20240215-topic-sm8650-gpu-v2-2-6be0b4bf2e09@linaro.org> <CAA8EJprpYEhGi5b+uWGWtOa+qbSwUR8C0j9NLC+ah_-nvy-=Ng@mail.gmail.com>
 <ffb16ef6-fc9a-42b1-b9c3-4e8f6b52d849@linaro.org>
Message-ID: <CAA8EJpobWYu8LoHZarOw82z78=kLJrKH0P4ncK6sX7zE1nHuqQ@mail.gmail.com>

On Thu, 15 Feb 2024 at 11:29, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>
> On 15/02/2024 10:25, Dmitry Baryshkov wrote:
> > On Thu, 15 Feb 2024 at 11:20, Neil Armstrong <neil.armstrong at linaro.org> wrote:
> >>
> >> Document the GPU SMMU found on the SM8650 platform.
> >>
> >> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> >> ---
> >>   Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 7 +++++--
> >>   1 file changed, 5 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> >> index a4042ae24770..3ad5c850f3bf 100644
> >> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> >> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> >> @@ -93,6 +93,7 @@ properties:
> >>                 - qcom,sm8350-smmu-500
> >>                 - qcom,sm8450-smmu-500
> >>                 - qcom,sm8550-smmu-500
> >> +              - qcom,sm8650-smmu-500
> >>             - const: qcom,adreno-smmu
> >>             - const: qcom,smmu-500
> >>             - const: arm,mmu-500
> >> @@ -508,7 +509,10 @@ allOf:
> >>     - if:
> >>         properties:
> >>           compatible:
> >> -          const: qcom,sm8550-smmu-500
> >> +          contains:
> >> +            enum:
> >> +              - qcom,sm8550-smmu-500
> >> +              - qcom,sm8650-smmu-500
> >
> > Doesn't this cause warnings for non-GPU SMMU on this platform?
>
> No because it doesn't add those to required, it simply allows clock the properties.

Can we further constrain this branch so that it is applicable only to
the Adreno SMMUs (and enforce requirement)? And maybe constrain the
second if-branch so that it doesn't apply to the Adreno SMMUs?

>
> >
> >>       then:
> >>         properties:
> >>           clock-names:
> >> @@ -544,7 +548,6 @@ allOf:
> >>                 - qcom,sdx65-smmu-500
> >>                 - qcom,sm6350-smmu-500
> >>                 - qcom,sm6375-smmu-500
> >> -              - qcom,sm8650-smmu-500
> >>                 - qcom,x1e80100-smmu-500
> >>       then:
> >>         properties:
> >>
> >> --
> >> 2.34.1
> >>
> >
> >
>


-- 
With best wishes
Dmitry


From alexander.stein at ew.tq-group.com  Thu Feb 15 01:32:14 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Thu, 15 Feb 2024 10:32:14 +0100
Subject: [PATCH v5 2/2] arm64: dts: mediatek: Replace deprecated extcon-usb-gpio id-gpio/vbus-gpio properties
In-Reply-To: <20240215093214.796821-1-alexander.stein@ew.tq-group.com>
References: <20240215093214.796821-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240215093214.796821-3-alexander.stein@ew.tq-group.com>

Use id-gpios and vbus-gpios instead.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Acked-by: Shawn Guo <shawnguo at kernel.org>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/boot/dts/mediatek/mt2712-evb.dts | 4 ++--
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
index fffdb7bbf889e..0c38f7b517637 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
@@ -43,12 +43,12 @@ cpus_fixed_vproc1: regulator-vproc-buck1 {
 
 	extcon_usb: extcon_iddig {
 		compatible = "linux,extcon-usb-gpio";
-		id-gpio = <&pio 12 GPIO_ACTIVE_HIGH>;
+		id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>;
 	};
 
 	extcon_usb1: extcon_iddig1 {
 		compatible = "linux,extcon-usb-gpio";
-		id-gpio = <&pio 14 GPIO_ACTIVE_HIGH>;
+		id-gpios = <&pio 14 GPIO_ACTIVE_HIGH>;
 	};
 
 	usb_p0_vbus: regulator-usb-p0-vbus {
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0e5c628d1ec3e..3fab21f59d183 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -41,7 +41,7 @@ hdmi_connector_in: endpoint {
 
 	extcon_usb: extcon_iddig {
 		compatible = "linux,extcon-usb-gpio";
-		id-gpio = <&pio 16 GPIO_ACTIVE_HIGH>;
+		id-gpios = <&pio 16 GPIO_ACTIVE_HIGH>;
 	};
 
 	usb_p1_vbus: regulator-usb-p1 {
-- 
2.34.1



From vigneshr at ti.com  Thu Feb 15 01:32:10 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 15 Feb 2024 15:02:10 +0530
Subject: [PATCH v1] arm64: dts: ti: verdin-am62: Set VDD CORE minimum voltage to 0.75V
In-Reply-To: <20240213155622.18309-1-francesco@dolcini.it>
References: <20240213155622.18309-1-francesco@dolcini.it>
Message-ID: <170798813445.1487216.11059927145774998794.b4-ty@ti.com>

Hi Francesco Dolcini,

On Tue, 13 Feb 2024 16:56:22 +0100, Francesco Dolcini wrote:
> Set VDD_CORE minimum voltage to 0.75V, TI AM62 can run at either 0.75V
> or 0.85V depending on the actual speed grade and on the maximum
> configured speed (1.4GHz frequency requires 0.85V).
> 
> The actual value is programmed into the PMIC EEPROM during manufacturing
> (according to the SOC speed grade) and this ensure that both the voltage
> values are valid and therefore the OS will not overwrite the value
> programmed into the PMIC.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: verdin-am62: Set VDD CORE minimum voltage to 0.75V
      commit: 2af8358ad64fb4bf012a6dc2917fbfc78a2093b2

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From u.kleine-koenig at pengutronix.de  Thu Feb 15 01:39:00 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Thu, 15 Feb 2024 10:39:00 +0100
Subject: [PATCH v2] clk: Add a devm variant of clk_rate_exclusive_get()
In-Reply-To: <f4noroegkbikrsjeisqlel46cu54emhnndtncnj4shygsbcaem@lixfb7ezeo5t>
References: <20240104225512.1124519-2-u.kleine-koenig@pengutronix.de>
 <f4noroegkbikrsjeisqlel46cu54emhnndtncnj4shygsbcaem@lixfb7ezeo5t>
Message-ID: <a2v3qm3erl7lfsmg445zyhihvtybbeis4ntrsdlqdf5wpjlyy5@bc7k5zyvzeyz>

Hello,

On Thu, Jan 25, 2024 at 10:44:45PM +0100, Uwe Kleine-K?nig wrote:
> On Thu, Jan 04, 2024 at 11:55:11PM +0100, Uwe Kleine-K?nig wrote:
> > This allows to simplify drivers that use clk_rate_exclusive_get()
> > in their probe routine as calling clk_rate_exclusive_put() is cared for
> > automatically.
> > 
> > Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> > ---
> > Changes since (implicit) v1, sent with Message-Id:
> > 744a6371f94fe96f527eea6e52a600914e6fb6b5.1702403904.git.u.kleine-koenig at pengutronix.de:
> 
> Given that I'm not the only one waiting for this change (see
> https://lore.kernel.org/linux-i2c/20240119072223.3986183-1-alexander.stein at ew.tq-group.com)
> here comes a gentil ping. It would be great to get this patch into next
> now the merge window is closed.

Is there a chance to get this into next and then v6.9-rc1?

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/20240215/20bec29f/attachment.sig>

From vigneshr at ti.com  Thu Feb 15 01:45:56 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 15 Feb 2024 15:15:56 +0530
Subject: [PATCH v1] arm64: dts: ti: k3-am62-main: disable usb lpm
In-Reply-To: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
References: <20240209130213.38908-1-andrejs.cainikovs@gmail.com>
Message-ID: <170798813445.1487216.9575227386692519157.b4-ty@ti.com>

Hi Andrejs Cainikovs,

On Fri, 09 Feb 2024 14:02:12 +0100, Andrejs Cainikovs wrote:
> AM62 USB works with some devices, while failing to operate with others.
> 
> [  560.189822] xhci-hcd xhci-hcd.4.auto: xHCI Host Controller
> [  560.195631] xhci-hcd xhci-hcd.4.auto: new USB bus registered, assigned bus number 2
> [  574.388509] xhci-hcd xhci-hcd.4.auto: can't setup: -110
> [  574.393814] xhci-hcd xhci-hcd.4.auto: USB bus 2 deregistered
> [  574.399544] xhci-hcd: probe of xhci-hcd.4.auto failed with error -110
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: k3-am62-main: disable usb lpm
      commit: 576ad1d1d8b12a632598f7963d640f9422781f9a

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Thu Feb 15 01:46:26 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 15 Feb 2024 15:16:26 +0530
Subject: [PATCH v5 1/1] arm64: dts: ti: k3-am62-wakeup: Configure ti-sysc for wkup_uart0
In-Reply-To: <20240213112510.6334-1-tony@atomide.com>
References: <20240213112510.6334-1-tony@atomide.com>
Message-ID: <170798813444.1487216.15857951204754633461.b4-ty@ti.com>

Hi Tony Lindgren,

On Tue, 13 Feb 2024 13:25:08 +0200, Tony Lindgren wrote:
> The devices in the wkup domain are capable of waking up the system from
> suspend. We can configure the wkup domain devices in a generic way using
> the ti-sysc interconnect target module driver like we have done with the
> earlier TI SoCs.
> 
> As ti-sysc manages the SYSCONFIG related registers independent of the
> child hardware device, the wake-up configuration is also set even if
> wkup_uart0 is reserved by sysfw.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: k3-am62-wakeup: Configure ti-sysc for wkup_uart0
      commit: 403ffe31494f38196628f26c570430bdaabcf617

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From tony at atomide.com  Thu Feb 15 01:46:40 2024
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 15 Feb 2024 11:46:40 +0200
Subject: 6.7 regression: platform 4809c000.mmc: deferred probe pending
In-Reply-To: <c92385d2-1909-43a8-aea8-cd9a8687a898@leemhuis.info>
References: <mvmcyt13idm.fsf@suse.de>
 <c92385d2-1909-43a8-aea8-cd9a8687a898@leemhuis.info>
Message-ID: <20240215094640.GS52537@atomide.com>

* Linux regression tracking (Thorsten Leemhuis) <regressions at leemhuis.info> [240214 14:01]:
> [CCing the regression list, as it should be in the loop for regressions:
> https://docs.kernel.org/admin-guide/reporting-regressions.html]
> 
> Hi, Thorsten here, the Linux kernel's regression tracker.
> 
> Thanks for the report.Added the omap list and the omap mmc maintainer;
> the root of the problem might be somewhere else, but maybe we get some
> help from there.
> 
> On 12.02.24 14:46, Andreas Schwab wrote:
> > I'm getting these messages on the PandaBoard since 6.7:
> > 
> > [   29.285522][  T156] platform 4809c000.mmc: deferred probe pending
> > [   29.291748][  T156] platform 4a0ab000.usb_otg_hs: deferred probe pending
> > [   29.298522][  T156] platform 58005000.encoder: deferred probe pending
> > [   29.305053][  T156] platform 58006000.encoder: deferred probe pending
> > [   29.305145][  T156] i2c 0-004b: deferred probe pending
> > [   29.316772][  T156] platform 40132000.target-module: deferred probe pending
> > [   37.382110][  T156] pbias_mmc_omap4: disabling
> > 
> > As a result, the SD card is not found.
> > Any idea what's going on here?
> 
> Haven't heard of anything like that. Unless some developer replies with
> some idea in a day or two I guess you will have to bisect the problem.

There was a regression recently with the PMIC which would cause NFSroot
on devices to keep working but may have affected MMC. Please check that
commit 7a29fa05aeca ("mfd: twl6030-irq: Revert to use of_match_device()")
is applied. If that does not help, then git bisect is the way to go.

Regards,

Tony


From theo.lebrun at bootlin.com  Thu Feb 15 01:47:58 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 10:47:58 +0100
Subject: [PATCH 01/23] dt-bindings: gpio: nomadik: convert into yaml
 format
In-Reply-To: <be4e6ded-6596-472b-a988-0909a5451a72@linaro.org>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-1-f88c0ccf372b@bootlin.com>
 <be4e6ded-6596-472b-a988-0909a5451a72@linaro.org>
Message-ID: <CZ5K3DSVZTAI.2TCVJ2LHGVBPC@bootlin.com>

Hello,

On Thu Feb 15, 2024 at 10:11 AM CET, Krzysztof Kozlowski wrote:
> On 14/02/2024 17:23, Th?o Lebrun wrote:
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  "#gpio-cells":
> > +    const: 2
> > +
> > +  gpio-controller: true
> > +
> > +  interrupt-controller: true
> > +
> > +  "#interrupt-cells":
> > +    const: 2
> > +
> > +  gpio-bank:
> > +    $ref: /schemas/types.yaml#/definitions/uint32
>
> Missing description, unless it is a common property (but then where do I
> find it?).

Missing indeed. Will become:

  gpio-bank:
    description: System-wide GPIO bank index.
    $ref: /schemas/types.yaml#/definitions/uint32

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From ck.hu at mediatek.com  Thu Feb 15 01:28:16 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 15 Feb 2024 09:28:16 +0000
Subject: [PATCH v6 9/9] drm/mediatek: dsi: Use
 mipi_dsi_pixel_format_to_bpp() helper function
In-Reply-To: <20240215085316.56835-10-angelogioacchino.delregno@collabora.com>
References: <20240215085316.56835-1-angelogioacchino.delregno@collabora.com>
	 <20240215085316.56835-10-angelogioacchino.delregno@collabora.com>
Message-ID: <fb9a5c679cae73b0784e792729395a07be0c65cd.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-02-15 at 09:53 +0100, AngeloGioacchino Del Regno wrote:
> Instead of open coding, use the mipi_dsi_pixel_format_to_bpp() helper
> function from drm_mipi_dsi.h in mtk_dsi_poweron() and for validation
> in mtk_dsi_bridge_mode_valid().
> 
> Note that this function changes the behavior of this driver:
> previously,
> in case of unknown formats, it would (wrongly) assume that it should
> account for a 24-bits format - now it will return an error and refuse
> to set clocks and/or enable the DSI.
> 
> This is done because setting the wrong data rate will only produce a
> garbage output that the display will misinterpret both because this
> driver doesn't actually provide any extra-spec format support and/or
> because the data rate (hence, the HS clock) will be wrong.

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

> 
> Reviewed-by: Alexandre Mergnat <amergnat at baylibre.com>
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 26 +++++++++-----------------
>  1 file changed, 9 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index b644505de98a..9501f4019199 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -598,19 +598,12 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>  	if (++dsi->refcount != 1)
>  		return 0;
>  
> -	switch (dsi->format) {
> -	case MIPI_DSI_FMT_RGB565:
> -		bit_per_pixel = 16;
> -		break;
> -	case MIPI_DSI_FMT_RGB666_PACKED:
> -		bit_per_pixel = 18;
> -		break;
> -	case MIPI_DSI_FMT_RGB666:
> -	case MIPI_DSI_FMT_RGB888:
> -	default:
> -		bit_per_pixel = 24;
> -		break;
> +	ret = mipi_dsi_pixel_format_to_bpp(dsi->format);
> +	if (ret < 0) {
> +		dev_err(dev, "Unknown MIPI DSI format %d\n", dsi-
> >format);
> +		return ret;
>  	}
> +	bit_per_pixel = ret;
>  
>  	dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock *
> bit_per_pixel,
>  					  dsi->lanes);
> @@ -793,12 +786,11 @@ mtk_dsi_bridge_mode_valid(struct drm_bridge
> *bridge,
>  			  const struct drm_display_mode *mode)
>  {
>  	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
> -	u32 bpp;
> +	int bpp;
>  
> -	if (dsi->format == MIPI_DSI_FMT_RGB565)
> -		bpp = 16;
> -	else
> -		bpp = 24;
> +	bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> +	if (bpp < 0)
> +		return MODE_ERROR;
>  
>  	if (mode->clock * bpp / dsi->lanes > 1500000)
>  		return MODE_CLOCK_HIGH;

From theo.lebrun at bootlin.com  Thu Feb 15 01:52:44 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 10:52:44 +0100
Subject: [PATCH 03/23] dt-bindings: gpio: nomadik: add
 mobileye,eyeq5-gpio compatible
In-Reply-To: <9e19c820-c9aa-4eef-a594-f7305b03eea4@linaro.org>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-3-f88c0ccf372b@bootlin.com>
 <9e19c820-c9aa-4eef-a594-f7305b03eea4@linaro.org>
Message-ID: <CZ5K713P9WDB.FN0HZ3ANLTNC@bootlin.com>

Hello,

On Thu Feb 15, 2024 at 10:13 AM CET, Krzysztof Kozlowski wrote:
> On 14/02/2024 17:23, Th?o Lebrun wrote:
> > This GPIO controller is used on the Mobileye EyeQ5 SoC. Add its
> > compatible to the dt-bindings. One difference is that the block as
> > integrated on EyeQ5 does not support sleep-mode.
> > 
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> > ---
> >  .../devicetree/bindings/gpio/st,nomadik-gpio.yaml        | 16 +++++++++++++++-
> >  1 file changed, 15 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> > index bbd23daed229..e44cf292bc6d 100644
> > --- a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> > +++ b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> > @@ -19,7 +19,9 @@ properties:
> >      pattern: "^gpio@[0-9a-f]+$"
> >  
> >    compatible:
> > -    const: st,nomadik-gpio
> > +    enum:
> > +      - st,nomadik-gpio
> > +      - mobileye,eyeq5-gpio
> >  
> >    reg:
> >      maxItems: 1
> > @@ -65,6 +67,18 @@ required:
> >  
> >  unevaluatedProperties: false
> >  
> > +allOf:
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: st,nomadik-gpio
> > +    then:
> > +      properties:
> > +        st,supports-sleepmode:
> > +          description: Whether the controller can sleep or not.
> > +          $ref: /schemas/types.yaml#/definitions/flag
>
> You already have such property, so you are defining it second time. You
> want instead if: for eyeq5-gpio making it:
> then:
>   properties:
>     st,supports-sleepmode: false

Good catch. I hesitated between declaring the property inside an
if-statement or disabling it inside an if-statement as you show here. I
ended-up mixing those two approaches.

Wil pick the if-eyeq5-then-disable-prop solution.

Thanks for the review Krzysztof!

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From u.kleine-koenig at pengutronix.de  Thu Feb 15 01:54:28 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Thu, 15 Feb 2024 10:54:28 +0100
Subject: [linux][PATCH v6 2/3] dt-bindings: atmel,hlcdc: convert pwm
 bindings to json-schema
In-Reply-To: <20240202001733.91455-3-dharma.b@microchip.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-3-dharma.b@microchip.com>
Message-ID: <4psibzz7xylyp3zbmp3gup2gojh77bsllkyosbfdacyw4gzxuw@djl7eg4oeg2r>

Hello,

On Fri, Feb 02, 2024 at 05:47:32AM +0530, Dharma Balasubiramani wrote:
> Convert device tree bindings for Atmel's HLCDC PWM controller to YAML
> format.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> ---
> Changelog
> v5 -> v6
> - Drop the example as we have one complete example in mfd binding.
> v4 -> v5
> v3 -> v4
> - No changes
> Note: The clean up patch will be sent later as Sam suggested.
> v2 -> v3
> - Remove '|' in description, as there is no formatting to preserve.
> - Delete the description for pwm-cells.
> - Drop the label for pwm node as it not used.
> v1 -> v2
> - Remove the explicit copyrights.
> - Modify title (not include words like binding/driver).
> - Modify description actually describing the hardware and not the driver.
> - Remove pinctrl properties which aren't required.
> - Drop parent node and it's other sub-device node which are not related here.
> ---
>  .../bindings/pwm/atmel,hlcdc-pwm.yaml         | 35 +++++++++++++++++++
>  .../bindings/pwm/atmel-hlcdc-pwm.txt          | 29 ---------------
>  2 files changed, 35 insertions(+), 29 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml
>  delete mode 100644 Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt
> 
> diff --git a/Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml b/Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml
> new file mode 100644
> index 000000000000..0e92868a2b68
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml
> @@ -0,0 +1,35 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pwm/atmel,hlcdc-pwm.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Atmel's HLCDC's PWM controller
> +
> +maintainers:
> +  - Nicolas Ferre <nicolas.ferre at microchip.com>
> +  - Alexandre Belloni <alexandre.belloni at bootlin.com>
> +  - Claudiu Beznea <claudiu.beznea at tuxon.dev>
> +
> +description:
> +  The LCDC integrates a Pulse Width Modulation (PWM) Controller. This block
> +  generates the LCD contrast control signal (LCD_PWM) that controls the
> +  display's contrast by software. LCDC_PWM is an 8-bit PWM signal that can be
> +  converted to an analog voltage with a simple passive filter. LCD display
> +  panels have different backlight specifications in terms of minimum/maximum
> +  values for PWM frequency. If the LCDC PWM frequency range does not match the
> +  LCD display panel, it is possible to use the standalone PWM Controller to
> +  drive the backlight.
> +
> +properties:
> +  compatible:
> +    const: atmel,hlcdc-pwm
> +
> +  "#pwm-cells":
> +    const: 3
> +
> +required:
> +  - compatible
> +  - "#pwm-cells"
> +
> +additionalProperties: false
> diff --git a/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt b/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt
> deleted file mode 100644
> index afa501bf7f94..000000000000
> --- a/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt
> +++ /dev/null
> @@ -1,29 +0,0 @@
> -Device-Tree bindings for Atmel's HLCDC (High-end LCD Controller) PWM driver
> -
> -The Atmel HLCDC PWM is subdevice of the HLCDC MFD device.
> -See ../mfd/atmel-hlcdc.txt for more details.
> -
> -Required properties:
> - - compatible: value should be one of the following:
> -   "atmel,hlcdc-pwm"
> - - pinctr-names: the pin control state names. Should contain "default".
> - - pinctrl-0: should contain the pinctrl states described by pinctrl
> -   default.
> - - #pwm-cells: should be set to 3. This PWM chip use the default 3 cells
> -   bindings defined in pwm.yaml in this directory.
> -
> -Example:
> -
> -	hlcdc: hlcdc at f0030000 {
> -		compatible = "atmel,sama5d3-hlcdc";
> -		reg = <0xf0030000 0x2000>;
> -		clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>;
> -		clock-names = "periph_clk","sys_clk", "slow_clk";
> -
> -		hlcdc_pwm: hlcdc-pwm {
> -			compatible = "atmel,hlcdc-pwm";
> -			pinctrl-names = "default";
> -			pinctrl-0 = <&pinctrl_lcd_pwm>;
> -			#pwm-cells = <3>;
> -		};
> -	};

I guess dropping the example is fine because it's included now in the
mfd binding.

Applied to

	https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/for-next

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/20240215/2784454c/attachment.sig>

From maz at kernel.org  Thu Feb 15 01:57:22 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 15 Feb 2024 09:57:22 +0000
Subject: [PATCH v2] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM Neoverse N2 errata
In-Reply-To: <20240214175522.2457857-1-eahariha@linux.microsoft.com>
References: <20240214175522.2457857-1-eahariha@linux.microsoft.com>
Message-ID: <86r0he3v99.wl-maz@kernel.org>

On Wed, 14 Feb 2024 17:55:18 +0000,
Easwar Hariharan <eahariha at linux.microsoft.com> wrote:
> 
> Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft
> implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore
> suffers from all the same errata.
> 
> CC: stable at vger.kernel.org # 5.15+
> Signed-off-by: Easwar Hariharan <eahariha at linux.microsoft.com>

Thanks for respinning this.

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

	M.

-- 
Without deviation from the norm, progress is not possible.


From jens.wiklander at linaro.org  Thu Feb 15 02:00:36 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 15 Feb 2024 11:00:36 +0100
Subject: [PATCH 2/3] tee: tstee: Add Trusted Services TEE driver
In-Reply-To: <20240213145239.379875-3-balint.dobszay@arm.com>
References: <20240213145239.379875-1-balint.dobszay@arm.com> <20240213145239.379875-3-balint.dobszay@arm.com>
Message-ID: <CAHUa44Fzr5zMRkMZUfPNOu+nbAkp+n2FcrgrJ-U8R__qS42fzw@mail.gmail.com>

Hi Balint,

On Tue, Feb 13, 2024 at 3:54?PM Balint Dobszay <balint.dobszay at arm.com> wrote:
>
> The Trusted Services project provides a framework for developing and
> deploying device Root of Trust services in FF-A Secure Partitions. The
> FF-A SPs are accessible through the FF-A driver, but this doesn't
> provide a user space interface. The goal of this TEE driver is to make
> Trusted Services SPs accessible for user space clients.
>
> All TS SPs have the same FF-A UUID, it identifies the RPC protocol used
> by TS. A TS SP can host one or more services, a service is identified by
> its service UUID. The same type of service cannot be present twice in
> the same SP. During SP boot each service in an SP is assigned an
> interface ID, this is just a short ID to simplify message addressing.
> There is 1:1 mapping between TS SPs and TEE devices, i.e. a separate TEE
> device is registered for each TS SP. This is required since contrary to
> the generic TEE design where memory is shared with the whole TEE
> implementation, in case of FF-A, memory is shared with a specific SP. A
> user space client has to be able to separately share memory with each SP
> based on its endpoint ID.
>
> Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
> ---
>  drivers/tee/Kconfig               |   1 +
>  drivers/tee/Makefile              |   1 +
>  drivers/tee/tstee/Kconfig         |  11 +
>  drivers/tee/tstee/Makefile        |   3 +
>  drivers/tee/tstee/core.c          | 501 ++++++++++++++++++++++++++++++
>  drivers/tee/tstee/tstee_private.h |  92 ++++++
>  include/uapi/linux/tee.h          |   1 +
>  7 files changed, 610 insertions(+)
>  create mode 100644 drivers/tee/tstee/Kconfig
>  create mode 100644 drivers/tee/tstee/Makefile
>  create mode 100644 drivers/tee/tstee/core.c
>  create mode 100644 drivers/tee/tstee/tstee_private.h
>
> diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig
> index 73a147202e88..61b507c18780 100644
> --- a/drivers/tee/Kconfig
> +++ b/drivers/tee/Kconfig
> @@ -15,5 +15,6 @@ if TEE
>
>  source "drivers/tee/optee/Kconfig"
>  source "drivers/tee/amdtee/Kconfig"
> +source "drivers/tee/tstee/Kconfig"
>
>  endif
> diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
> index 68da044afbfa..5488cba30bd2 100644
> --- a/drivers/tee/Makefile
> +++ b/drivers/tee/Makefile
> @@ -5,3 +5,4 @@ tee-objs += tee_shm.o
>  tee-objs += tee_shm_pool.o
>  obj-$(CONFIG_OPTEE) += optee/
>  obj-$(CONFIG_AMDTEE) += amdtee/
> +obj-$(CONFIG_ARM_TSTEE) += tstee/
> diff --git a/drivers/tee/tstee/Kconfig b/drivers/tee/tstee/Kconfig
> new file mode 100644
> index 000000000000..d32f91d47398
> --- /dev/null
> +++ b/drivers/tee/tstee/Kconfig
> @@ -0,0 +1,11 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +config ARM_TSTEE
> +       tristate "Arm Trusted Services TEE driver"
> +       depends on ARM_FFA_TRANSPORT
> +       default n
> +       help
> +         The Trusted Services project provides a framework for developing and
> +         deploying device Root of Trust services in FF-A Secure Partitions.
> +         This driver provides an interface to make Trusted Services Secure
> +         Partitions accessible for user space clients, since the FF-A driver
> +         doesn't implement a user space interface directly.
> diff --git a/drivers/tee/tstee/Makefile b/drivers/tee/tstee/Makefile
> new file mode 100644
> index 000000000000..5227020ebd30
> --- /dev/null
> +++ b/drivers/tee/tstee/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +arm-tstee-objs := core.o
> +obj-$(CONFIG_ARM_TSTEE) = arm-tstee.o
> diff --git a/drivers/tee/tstee/core.c b/drivers/tee/tstee/core.c
> new file mode 100644
> index 000000000000..8d6bbe4d03ed
> --- /dev/null
> +++ b/drivers/tee/tstee/core.c
> @@ -0,0 +1,501 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2023, Arm Limited
> + */
> +
> +#define DRIVER_NAME "Arm TSTEE"
> +#define pr_fmt(fmt) DRIVER_NAME ": " fmt
> +
> +#include <linux/arm_ffa.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <linux/limits.h>
> +#include <linux/list.h>
> +#include <linux/mm.h>
> +#include <linux/module.h>
> +#include <linux/scatterlist.h>
> +#include <linux/slab.h>
> +#include <linux/stat.h>
> +#include <linux/tee_drv.h>
> +#include <linux/types.h>
> +#include <linux/uaccess.h>
> +
> +#include "tstee_private.h"
> +
> +#define FFA_DIRECT_REQ_ARG_NUM 5
> +#define FFA_INVALID_MEM_HANDLE U64_MAX
> +
> +static void arg_list_to_ffa_data(const u32 *args, struct ffa_send_direct_data *data)

The preferred limit on the length of a single line is 80 columns
https://www.kernel.org/doc/html/latest/process/coding-style.html#breaking-long-lines-and-strings


> +{
> +       data->data0 = args[0];
> +       data->data1 = args[1];
> +       data->data2 = args[2];
> +       data->data3 = args[3];
> +       data->data4 = args[4];
> +}
> +
> +static void arg_list_from_ffa_data(const struct ffa_send_direct_data *data, u32 *args)
> +{
> +       args[0] = lower_32_bits(data->data0);
> +       args[1] = lower_32_bits(data->data1);
> +       args[2] = lower_32_bits(data->data2);
> +       args[3] = lower_32_bits(data->data3);
> +       args[4] = lower_32_bits(data->data4);
> +}
> +
> +static void tstee_get_version(struct tee_device *teedev, struct tee_ioctl_version_data *vers)
> +{
> +       struct tstee *tstee = tee_get_drvdata(teedev);
> +       struct tee_ioctl_version_data v = {
> +               .impl_id = TEE_IMPL_ID_TSTEE,
> +               /* FF-A endpoint ID only uses the lower 16 bits */
> +               .impl_caps = lower_16_bits(tstee->ffa_dev->vm_id),
> +               .gen_caps = 0,
> +       };
> +
> +       *vers = v;
> +}
> +
> +static int tstee_open(struct tee_context *ctx)
> +{
> +       struct ts_context_data *ctxdata;
> +
> +       ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
> +       if (!ctxdata)
> +               return -ENOMEM;
> +
> +       mutex_init(&ctxdata->mutex);
> +       idr_init(&ctxdata->sess_ids);
> +       INIT_LIST_HEAD(&ctxdata->sess_list);
> +
> +       ctx->data = ctxdata;
> +
> +       return 0;
> +}
> +
> +static void tstee_release(struct tee_context *ctx)
> +{
> +       struct ts_context_data *ctxdata = ctx->data;
> +       struct ts_session *sess, *sess_tmp;
> +
> +       if (!ctxdata)
> +               return;
> +
> +       list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list, list_node) {
> +               list_del(&sess->list_node);
> +               idr_remove(&ctxdata->sess_ids, sess->session_id);
> +               kfree(sess);
> +       }
> +
> +       idr_destroy(&ctxdata->sess_ids);
> +       mutex_destroy(&ctxdata->mutex);
> +
> +       kfree(ctxdata);
> +       ctx->data = NULL;
> +}
> +
> +static struct ts_session *find_session(struct ts_context_data *ctxdata, u32 session_id)
> +{
> +       struct ts_session *sess;
> +
> +       list_for_each_entry(sess, &ctxdata->sess_list, list_node)
> +               if (sess->session_id == session_id)
> +                       return sess;

Since you have an idr, why not use idr_find() instead?

> +
> +       return NULL;
> +}
> +
> +static int tstee_open_session(struct tee_context *ctx, struct tee_ioctl_open_session_arg *arg,
> +                             struct tee_param *param __always_unused)
> +{
> +       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
> +       struct ffa_device *ffa_dev = tstee->ffa_dev;
> +       struct ts_context_data *ctxdata = ctx->data;
> +       struct ffa_send_direct_data ffa_data;
> +       struct ts_session *sess = NULL;
> +       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
> +       int sess_id;
> +       int rc;
> +
> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
> +                                                                 TS_RPC_OP_SERVICE_INFO);
> +
> +       memcpy((u8 *)(ffa_args + TS_RPC_SERVICE_INFO_UUID0), arg->uuid, UUID_SIZE);

Is the cast needed?

> +
> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
> +       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
> +       if (rc)
> +               return rc;
> +
> +       arg_list_from_ffa_data(&ffa_data, ffa_args);
> +
> +       if (ffa_args[TS_RPC_SERVICE_INFO_RPC_STATUS] != TS_RPC_OK)
> +               return -ENODEV;
> +
> +       if (ffa_args[TS_RPC_SERVICE_INFO_IFACE] > U8_MAX)
> +               return -EINVAL;
> +
> +       sess = kzalloc(sizeof(*sess), GFP_KERNEL);
> +       if (!sess)
> +               return -ENOMEM;
> +
> +       sess_id = idr_alloc(&ctxdata->sess_ids, sess, 1, 0, GFP_KERNEL);

This needs to be protected by the mutex.

> +       if (sess_id < 0) {
> +               kfree(sess);
> +               return sess_id;
> +       }
> +
> +       sess->session_id = sess_id;
> +       sess->iface_id = ffa_args[TS_RPC_SERVICE_INFO_IFACE];
> +
> +       mutex_lock(&ctxdata->mutex);
> +       list_add(&sess->list_node, &ctxdata->sess_list);
> +       mutex_unlock(&ctxdata->mutex);
> +
> +       arg->session = sess_id;
> +       arg->ret = 0;
> +
> +       return 0;
> +}
> +
> +static int tstee_close_session(struct tee_context *ctx, u32 session)
> +{
> +       struct ts_context_data *ctxdata = ctx->data;
> +       struct ts_session *sess;
> +
> +       mutex_lock(&ctxdata->mutex);
> +       sess = find_session(ctxdata, session);
> +       if (sess)
> +               list_del(&sess->list_node);
> +
> +       mutex_unlock(&ctxdata->mutex);
> +
> +       if (!sess)
> +               return -EINVAL;
> +
> +       idr_remove(&ctxdata->sess_ids, sess->session_id);
> +       kfree(sess);
> +
> +       return 0;
> +}
> +
> +static int tstee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
> +                            struct tee_param *param)
> +{
> +       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
> +       struct ffa_device *ffa_dev = tstee->ffa_dev;
> +       struct ts_context_data *ctxdata = ctx->data;
> +       struct ffa_send_direct_data ffa_data;
> +       struct tee_shm *shm = NULL;
> +       struct ts_session *sess;
> +       u32 req_len, ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
> +       int shm_id, rc;
> +       u8 iface_id;
> +       u64 handle;
> +       u16 opcode;
> +
> +       mutex_lock(&ctxdata->mutex);
> +       sess = find_session(ctxdata, arg->session);
> +
> +       /* Do this while holding the mutex to make sure that the session wasn't closed meanwhile */
> +       if (sess)
> +               iface_id = sess->iface_id;
> +
> +       mutex_unlock(&ctxdata->mutex);
> +       if (!sess)
> +               return -EINVAL;
> +
> +       opcode = lower_16_bits(arg->func);
> +       shm_id = lower_32_bits(param[0].u.value.a);
> +       req_len = lower_32_bits(param[0].u.value.b);
> +
> +       if (shm_id != 0) {
> +               shm = tee_shm_get_from_id(ctx, shm_id);
> +               if (IS_ERR(shm))
> +                       return PTR_ERR(shm);
> +
> +               if (shm->size < req_len) {
> +                       pr_err("request doesn't fit into shared memory buffer\n");
> +                       rc = -EINVAL;
> +                       goto out;
> +               }
> +
> +               handle = shm->sec_world_id;
> +       } else {
> +               handle = FFA_INVALID_MEM_HANDLE;
> +       }
> +
> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(iface_id, opcode);
> +       ffa_args[TS_RPC_SERVICE_MEM_HANDLE_LSW] = lower_32_bits(handle);
> +       ffa_args[TS_RPC_SERVICE_MEM_HANDLE_MSW] = upper_32_bits(handle);
> +       ffa_args[TS_RPC_SERVICE_REQ_LEN] = req_len;
> +       ffa_args[TS_RPC_SERVICE_CLIENT_ID] = 0;
> +
> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
> +       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
> +       if (rc)
> +               goto out;
> +
> +       arg_list_from_ffa_data(&ffa_data, ffa_args);
> +
> +       if (ffa_args[TS_RPC_SERVICE_RPC_STATUS] != TS_RPC_OK) {
> +               pr_err("invoke_func rpc status: %d\n", ffa_args[TS_RPC_SERVICE_RPC_STATUS]);
> +               rc = -EINVAL;
> +               goto out;
> +       }
> +
> +       arg->ret = ffa_args[TS_RPC_SERVICE_STATUS];
> +       if (shm && shm->size >= ffa_args[TS_RPC_SERVICE_RESP_LEN])
> +               param[0].u.value.a = ffa_args[TS_RPC_SERVICE_RESP_LEN];
> +
> +out:
> +       if (shm)
> +               tee_shm_put(shm);
> +
> +       return rc;
> +}
> +
> +static int tstee_shm_register(struct tee_context *ctx, struct tee_shm *shm, struct page **pages,
> +                             size_t num_pages, unsigned long start __always_unused)
> +{
> +       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
> +       struct ffa_device *ffa_dev = tstee->ffa_dev;
> +       struct ffa_mem_region_attributes mem_attr = {
> +               .receiver = tstee->ffa_dev->vm_id,
> +               .attrs = FFA_MEM_RW,
> +               .flag = 0,
> +       };
> +       struct ffa_mem_ops_args mem_args = {
> +               .attrs = &mem_attr,
> +               .use_txbuf = true,
> +               .nattrs = 1,
> +               .flags = 0,
> +       };
> +       struct ffa_send_direct_data ffa_data;
> +       struct sg_table sgt;
> +       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
> +       int rc;
> +
> +       rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0, num_pages * PAGE_SIZE,
> +                                      GFP_KERNEL);
> +       if (rc)
> +               return rc;
> +
> +       mem_args.sg = sgt.sgl;
> +       rc = ffa_dev->ops->mem_ops->memory_share(&mem_args);
> +       sg_free_table(&sgt);
> +       if (rc)
> +               return rc;
> +
> +       shm->sec_world_id = mem_args.g_handle;
> +
> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
> +                                                                 TS_RPC_OP_RETRIEVE_MEM);
> +       ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_LSW] = lower_32_bits(shm->sec_world_id);
> +       ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_MSW] = upper_32_bits(shm->sec_world_id);
> +       ffa_args[TS_RPC_RETRIEVE_MEM_TAG_LSW] = 0;
> +       ffa_args[TS_RPC_RETRIEVE_MEM_TAG_MSW] = 0;
> +
> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
> +       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
> +       if (rc) {
> +               (void)ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
> +               return rc;
> +       }
> +
> +       arg_list_from_ffa_data(&ffa_data, ffa_args);
> +
> +       if (ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS] != TS_RPC_OK) {
> +               pr_err("shm_register rpc status: %d\n", ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS]);
> +               ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int tstee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
> +{
> +       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
> +       struct ffa_device *ffa_dev = tstee->ffa_dev;
> +       struct ffa_send_direct_data ffa_data;
> +       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
> +       int rc;
> +
> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
> +                                                                 TS_RPC_OP_RELINQ_MEM);
> +       ffa_args[TS_RPC_RELINQ_MEM_HANDLE_LSW] = lower_32_bits(shm->sec_world_id);
> +       ffa_args[TS_RPC_RELINQ_MEM_HANDLE_MSW] = upper_32_bits(shm->sec_world_id);
> +
> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
> +       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
> +       if (rc)
> +               return rc;
> +       arg_list_from_ffa_data(&ffa_data, ffa_args);
> +
> +       if (ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS] != TS_RPC_OK) {
> +               pr_err("shm_unregister rpc status: %d\n", ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS]);
> +               return -EINVAL;
> +       }
> +
> +       rc = ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
> +
> +       return rc;
> +}
> +
> +static const struct tee_driver_ops tstee_ops = {
> +       .get_version = tstee_get_version,
> +       .open = tstee_open,
> +       .release = tstee_release,
> +       .open_session = tstee_open_session,
> +       .close_session = tstee_close_session,
> +       .invoke_func = tstee_invoke_func,
> +       .shm_register = tstee_shm_register,
> +       .shm_unregister = tstee_shm_unregister,
> +};
> +
> +static const struct tee_desc tstee_desc = {
> +       .name = "tstee-clnt",
> +       .ops = &tstee_ops,
> +       .owner = THIS_MODULE,
> +};
> +
> +static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm, size_t size, size_t align)
> +{
> +       return tee_shm_pool_op_alloc_helper(pool, shm, size, align, tstee_shm_register);
> +}
> +
> +static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm)
> +{
> +       tee_shm_pool_op_free_helper(pool, shm, tstee_shm_unregister);
> +}
> +
> +static void pool_op_destroy_pool(struct tee_shm_pool *pool)
> +{
> +       kfree(pool);
> +}
> +
> +static const struct tee_shm_pool_ops pool_ops = {
> +       .alloc = pool_op_alloc,
> +       .free = pool_op_free,
> +       .destroy_pool = pool_op_destroy_pool,
> +};
> +
> +static struct tee_shm_pool *tstee_create_shm_pool(void)
> +{
> +       struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
> +
> +       if (!pool)
> +               return ERR_PTR(-ENOMEM);
> +
> +       pool->ops = &pool_ops;
> +
> +       return pool;
> +}
> +
> +static bool tstee_check_rpc_compatible(struct ffa_device *ffa_dev)
> +{
> +       struct ffa_send_direct_data ffa_data;
> +       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
> +
> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
> +                                                                 TS_RPC_OP_GET_VERSION);
> +
> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
> +       if (ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data))
> +               return false;
> +
> +       arg_list_from_ffa_data(&ffa_data, ffa_args);
> +
> +       return ffa_args[TS_RPC_GET_VERSION_RESP] == TS_RPC_PROTOCOL_VERSION;
> +}
> +
> +static void tstee_deinit_common(struct tstee *tstee)
> +{
> +       tee_device_unregister(tstee->teedev);
> +       if (tstee->pool)
> +               tee_shm_pool_free(tstee->pool);
> +
> +       kfree(tstee);
> +}
> +
> +static int tstee_probe(struct ffa_device *ffa_dev)
> +{
> +       struct tstee *tstee;
> +       int rc;
> +
> +       ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev);
> +
> +       if (!tstee_check_rpc_compatible(ffa_dev))
> +               return -EINVAL;
> +
> +       tstee = kzalloc(sizeof(*tstee), GFP_KERNEL);
> +       if (!tstee)
> +               return -ENOMEM;
> +
> +       tstee->ffa_dev = ffa_dev;
> +
> +       tstee->pool = tstee_create_shm_pool();
> +       if (IS_ERR(tstee->pool)) {
> +               rc = PTR_ERR(tstee->pool);
> +               tstee->pool = NULL;
> +               goto err;
> +       }
> +
> +       tstee->teedev = tee_device_alloc(&tstee_desc, NULL, tstee->pool, tstee);
> +       if (IS_ERR(tstee->teedev)) {
> +               rc = PTR_ERR(tstee->teedev);
> +               tstee->teedev = NULL;
> +               goto err;
> +       }
> +
> +       rc = tee_device_register(tstee->teedev);
> +       if (rc)
> +               goto err;
> +
> +       ffa_dev_set_drvdata(ffa_dev, tstee);
> +
> +       pr_info("driver initialized for endpoint 0x%x\n", ffa_dev->vm_id);
> +
> +       return 0;
> +
> +err:
> +       tstee_deinit_common(tstee);
> +       return rc;
> +}
> +
> +static void tstee_remove(struct ffa_device *ffa_dev)
> +{
> +       tstee_deinit_common(ffa_dev->dev.driver_data);
> +}
> +
> +static const struct ffa_device_id tstee_device_ids[] = {
> +       /* TS RPC protocol UUID: bdcd76d7-825e-4751-963b-86d4f84943ac */
> +       { TS_RPC_UUID },
> +       {}
> +};
> +
> +static struct ffa_driver tstee_driver = {
> +       .name = "arm_tstee",
> +       .probe = tstee_probe,
> +       .remove = tstee_remove,
> +       .id_table = tstee_device_ids,
> +};
> +
> +static int __init mod_init(void)
> +{
> +       return ffa_register(&tstee_driver);
> +}
> +module_init(mod_init)
> +
> +static void __exit mod_exit(void)
> +{
> +       ffa_unregister(&tstee_driver);
> +}
> +module_exit(mod_exit)
> +
> +MODULE_ALIAS("arm-tstee");
> +MODULE_AUTHOR("Balint Dobszay <balint.dobszay at arm.com>");
> +MODULE_DESCRIPTION("Arm Trusted Services TEE driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/tee/tstee/tstee_private.h b/drivers/tee/tstee/tstee_private.h
> new file mode 100644
> index 000000000000..81eeda220a5c
> --- /dev/null
> +++ b/drivers/tee/tstee/tstee_private.h
> @@ -0,0 +1,92 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2023, Arm Limited
> + */
> +
> +#ifndef TSTEE_PRIVATE_H
> +#define TSTEE_PRIVATE_H
> +
> +#include <linux/arm_ffa.h>
> +#include <linux/bitops.h>
> +#include <linux/idr.h>
> +#include <linux/tee_drv.h>
> +#include <linux/types.h>
> +#include <linux/uuid.h>
> +
> +/* UUID of this protocol */

It would be nice to have a link or reference to the description of the ABI.

> +#define TS_RPC_UUID UUID_INIT(0xbdcd76d7, 0x825e, 0x4751, \
> +                             0x96, 0x3b, 0x86, 0xd4, 0xf8, 0x49, 0x43, 0xac)
> +
> +/* Protocol version*/
> +#define TS_RPC_PROTOCOL_VERSION                (1)
> +
> +/* Status codes */
> +#define TS_RPC_OK                      (0)
> +
> +/* RPC control register */
> +#define TS_RPC_CTRL_REG                        (0)
> +#define OPCODE_MASK                    GENMASK(15, 0)
> +#define IFACE_ID_MASK                  GENMASK(23, 16)
> +#define TS_RPC_CTRL_OPCODE(x)          ((u16)(FIELD_GET(OPCODE_MASK, (x))))
> +#define TS_RPC_CTRL_IFACE_ID(x)                ((u8)(FIELD_GET(IFACE_ID_MASK, (x))))
> +#define TS_RPC_CTRL_PACK_IFACE_OPCODE(i, o)    \
> +       (FIELD_PREP(IFACE_ID_MASK, (i)) | FIELD_PREP(OPCODE_MASK, (o)))
> +#define TS_RPC_CTRL_SAP_RC             BIT(30)
> +#define TS_RPC_CTRL_SAP_ERR            BIT(31)
> +
> +/* Interface ID for RPC management operations */
> +#define TS_RPC_MGMT_IFACE_ID           (0xff)
> +
> +/* Management calls */
> +#define TS_RPC_OP_GET_VERSION          (0x0000)
> +#define TS_RPC_GET_VERSION_RESP                (1)
> +
> +#define TS_RPC_OP_RETRIEVE_MEM         (0x0001)
> +#define TS_RPC_RETRIEVE_MEM_HANDLE_LSW (1)
> +#define TS_RPC_RETRIEVE_MEM_HANDLE_MSW (2)
> +#define TS_RPC_RETRIEVE_MEM_TAG_LSW    (3)
> +#define TS_RPC_RETRIEVE_MEM_TAG_MSW    (4)
> +#define TS_RPC_RETRIEVE_MEM_RPC_STATUS (1)
> +
> +#define TS_RPC_OP_RELINQ_MEM           (0x0002)
> +#define TS_RPC_RELINQ_MEM_HANDLE_LSW   (1)
> +#define TS_RPC_RELINQ_MEM_HANDLE_MSW   (2)
> +#define TS_RPC_RELINQ_MEM_RPC_STATUS   (1)
> +
> +#define TS_RPC_OP_SERVICE_INFO         (0x0003)
> +#define TS_RPC_SERVICE_INFO_UUID0      (1)
> +#define TS_RPC_SERVICE_INFO_UUID1      (2)
> +#define TS_RPC_SERVICE_INFO_UUID2      (3)
> +#define TS_RPC_SERVICE_INFO_UUID3      (4)
> +#define TS_RPC_SERVICE_INFO_RPC_STATUS (1)
> +#define TS_RPC_SERVICE_INFO_IFACE      (2)
> +
> +/* Service call */
> +#define TS_RPC_SERVICE_MEM_HANDLE_LSW  (1)
> +#define TS_RPC_SERVICE_MEM_HANDLE_MSW  (2)
> +#define TS_RPC_SERVICE_REQ_LEN         (3)
> +#define TS_RPC_SERVICE_CLIENT_ID       (4)
> +#define TS_RPC_SERVICE_RPC_STATUS      (1)
> +#define TS_RPC_SERVICE_STATUS          (2)
> +#define TS_RPC_SERVICE_RESP_LEN                (3)
> +
> +struct tstee {
> +       struct ffa_device *ffa_dev;
> +       struct tee_device *teedev;
> +       struct tee_shm_pool *pool;
> +};
> +
> +struct ts_session {
> +       struct list_head list_node;
> +       u32 session_id;
> +       u8 iface_id;
> +};
> +
> +struct ts_context_data {
> +       struct list_head sess_list;
> +       struct idr sess_ids;

Why do you need both a linked list and an IDR? Wouldn't the IDR be enough?

Cheers,
Jens

> +       /* Serializes access to this struct */
> +       struct mutex mutex;
> +};
> +
> +#endif /* TSTEE_PRIVATE_H */
> diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
> index 23e57164693c..d0430bee8292 100644
> --- a/include/uapi/linux/tee.h
> +++ b/include/uapi/linux/tee.h
> @@ -56,6 +56,7 @@
>   */
>  #define TEE_IMPL_ID_OPTEE      1
>  #define TEE_IMPL_ID_AMDTEE     2
> +#define TEE_IMPL_ID_TSTEE      3
>
>  /*
>   * OP-TEE specific capabilities
> --
> 2.34.1
>


From u.kleine-koenig at pengutronix.de  Thu Feb 15 02:02:04 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Thu, 15 Feb 2024 11:02:04 +0100
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
Message-ID: <aamdttvdk3jmswvy3rw3debk3ouddkgjbs6xmixroe6kqakjw4@lnd5crcgoeyj>

On Mon, Feb 12, 2024 at 11:23:02AM +0100, Krzysztof Kozlowski wrote:
> On 08/02/2024 11:43, Lee Jones wrote:
> > On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
> >> Convert the atmel,hlcdc binding to DT schema format.
> >>
> >> Align clocks and clock-names properties to clearly indicate that the LCD
> >> controller expects lvds_pll_clk when interfaced with the lvds display. This
> >> alignment with the specific hardware requirements ensures accurate device tree
> >> configuration for systems utilizing the HLCDC IP.
> >>
> >> [...]
> > 
> > Applied, thanks!
> > 
> > [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
> >       commit: cb946db1335b599ece363d33966bf653ed0fa58a
> > 
> 
> Next is still failing.

Failing in the sense of dtbs_check, right?

> Dharma,
> You must explain and clearly mark dependencies between patches.
> 
> Lee,
> Can you pick up two previous patches as well?

I applied the pwm patch now. If Lee wants to pick up this one via his
tree that would be fine for me, too. If that's the case please tell me,
then I'll drop it from my for-next branch again. Feel free to add
my Acked-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de> for patch
#2 then.

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/20240215/dae361dc/attachment.sig>

From p.zabel at pengutronix.de  Thu Feb 15 02:03:24 2024
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Thu, 15 Feb 2024 11:03:24 +0100
Subject: [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from
 drivers/pinctrl/nomadik/
In-Reply-To: <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
	 <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>
Message-ID: <e031566a85ae0da0ee71dffba5d87c6414ef83e1.camel@pengutronix.de>

On Mi, 2024-02-14 at 17:23 +0100, Th?o Lebrun wrote:
[...]
> diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
> new file mode 100644
> index 000000000000..e39477e1a58f
> --- /dev/null
> +++ b/drivers/gpio/gpio-nomadik.c
> @@ -0,0 +1,660 @@
[...]
> +static int nmk_gpio_probe(struct platform_device *dev)
> +{
[...]
> +	ret = gpiochip_add_data(chip, nmk_chip);

Use devm_gpiochip_add_data() to cleanup on unbind, before nmk_chip goes
away. Or make the driver un-unbindable via suppress_bind_attrs. In that
case you could drop devm_ prefixes everywhere for consistency.

regards
Philipp


From shawn.sung at mediatek.com  Thu Feb 15 02:11:10 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:10 +0800
Subject: [PATCH v5 04/13] drm/mediatek: Fix errors when reporting rotation capability
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-5-shawn.sung@mediatek.com>

Create rotation property according to the hardware capability.
Since currently OVL of all chips support same rotation,
no need to define it in the driver data.

Fixes: 84d805753983 ("drm/mediatek: Support reflect-y plane rotation")

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  1 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c       | 19 +++++++------------
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   |  9 +++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.c      |  2 +-
 5 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 4a5661334fb1a..cd5ca5359b0f0 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -126,6 +126,7 @@ void mtk_ovl_adaptor_register_vblank_cb(struct device *dev, void (*vblank_cb)(vo
 void mtk_ovl_adaptor_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_adaptor_enable_vblank(struct device *dev);
 void mtk_ovl_adaptor_disable_vblank(struct device *dev);
+unsigned int mtk_ovl_adaptor_supported_rotations(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);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 5aaf4342cdbda..c42fce38a35eb 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -289,6 +289,10 @@ unsigned int mtk_ovl_layer_nr(struct device *dev)
 
 unsigned int mtk_ovl_supported_rotations(struct device *dev)
 {
+	/*
+	 * although currently OVL can only do reflection,
+	 * reflect x + reflect y = rotate 180
+	 */
 	return DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
 	       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
 }
@@ -297,27 +301,18 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
 			struct mtk_plane_state *mtk_state)
 {
 	struct drm_plane_state *state = &mtk_state->base;
-	unsigned int rotation = 0;
 
-	rotation = drm_rotation_simplify(state->rotation,
-					 DRM_MODE_ROTATE_0 |
-					 DRM_MODE_REFLECT_X |
-					 DRM_MODE_REFLECT_Y);
-	rotation &= ~DRM_MODE_ROTATE_0;
-
-	/* We can only do reflection, not rotation */
-	if ((rotation & DRM_MODE_ROTATE_MASK) != 0)
+	/* check if any unsupported rotation is set */
+	if (state->rotation & ~mtk_ovl_supported_rotations(dev))
 		return -EINVAL;
 
 	/*
 	 * TODO: Rotating/reflecting YUV buffers is not supported at this time.
 	 *	 Only RGB[AX] variants are supported.
 	 */
-	if (state->fb->format->is_yuv && rotation != 0)
+	if (state->fb->format->is_yuv && (state->rotation & ~DRM_MODE_ROTATE_0))
 		return -EINVAL;
 
-	state->rotation = rotation;
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index 6d4334955e3d3..d4a13a1402148 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -379,6 +379,15 @@ void mtk_ovl_adaptor_register_vblank_cb(struct device *dev, void (*vblank_cb)(vo
 				     vblank_cb, vblank_cb_data);
 }
 
+unsigned int mtk_ovl_adaptor_supported_rotations(struct device *dev)
+{
+	/*
+	 * should still return DRM_MODE_ROTATE_0 if rotation is not supported,
+	 * or IGT will fail.
+	 */
+	return DRM_MODE_ROTATE_0;
+}
+
 void mtk_ovl_adaptor_unregister_vblank_cb(struct device *dev)
 {
 	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 94590227c56a9..b47be6955d9b8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -417,6 +417,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
 	.get_formats = mtk_ovl_adaptor_get_formats,
 	.get_num_formats = mtk_ovl_adaptor_get_num_formats,
 	.mode_valid = mtk_ovl_adaptor_mode_valid,
+	.supported_rotations = mtk_ovl_adaptor_supported_rotations,
 };
 
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index f10d4cc6c2234..2dc28a79f7603 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -338,7 +338,7 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
 		return err;
 	}
 
-	if (supported_rotations & ~DRM_MODE_ROTATE_0) {
+	if (supported_rotations) {
 		err = drm_plane_create_rotation_property(plane,
 							 DRM_MODE_ROTATE_0,
 							 supported_rotations);
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:09 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:09 +0800
Subject: [PATCH v5 03/13] drm/mediatek: Add missing plane settings when async update
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-4-shawn.sung@mediatek.com>

Fix an issue that plane coordinate was not saved when
calling async update.

Fixes: 920fffcc8912 ("drm/mediatek: update cursors by using async atomic update")

Reviewed-by: CK Hu <ck.hu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index ddc9355b06d51..f10d4cc6c2234 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -227,6 +227,8 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane,
 	plane->state->src_y = new_state->src_y;
 	plane->state->src_h = new_state->src_h;
 	plane->state->src_w = new_state->src_w;
+	plane->state->dst.x1 = new_state->dst.x1;
+	plane->state->dst.y1 = new_state->dst.y1;
 
 	mtk_plane_update_new_state(new_state, new_plane_state);
 	swap(plane->state->fb, new_state->fb);
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:07 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:07 +0800
Subject: [PATCH v5 01/13] soc: mediatek: Disable 9-bit alpha in ETHDR
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-2-shawn.sung@mediatek.com>

ETHDR 9-bit alpha should be disabled by default,
otherwise alpha blending will not work.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/soc/mediatek/mtk-mmsys.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index afb2c40c85c15..00eff18a3bcea 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -236,6 +236,7 @@ void mtk_mmsys_mixer_in_config(struct device *dev, int idx, bool alpha_sel, u16
 
 	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_ALPHA + (idx - 1) * 4, ~0,
 			      alpha << 16 | alpha, cmdq_pkt);
+	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_HDR_TOP_CFG, BIT(15 + idx), 0, cmdq_pkt);
 	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_HDR_TOP_CFG, BIT(19 + idx),
 			      alpha_sel << (19 + idx), cmdq_pkt);
 	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_PAD + (idx - 1) * 4,
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:14 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:14 +0800
Subject: [PATCH v5 08/13] drm/mediatek: Support alpha blending in OVL
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-9-shawn.sung@mediatek.com>

Support "Pre-multiplied" and "None" blend mode on MediaTek's chips.
Before this patch, only the "Coverage" mode is supported.

Please refer to the description of the commit
"drm/mediatek: Support alpha blending in display driver"
for more information.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 83 +++++++++++++++++++++----
 1 file changed, 72 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index c42fce38a35eb..98c989fddcc08 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -39,6 +39,7 @@
 #define DISP_REG_OVL_PITCH_MSB(n)		(0x0040 + 0x20 * (n))
 #define OVL_PITCH_MSB_2ND_SUBBUF			BIT(16)
 #define DISP_REG_OVL_PITCH(n)			(0x0044 + 0x20 * (n))
+#define OVL_CONST_BLEND					BIT(28)
 #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
 #define DISP_REG_OVL_ADDR_MT2701		0x0040
@@ -52,13 +53,16 @@
 #define GMC_THRESHOLD_HIGH	((1 << GMC_THRESHOLD_BITS) / 4)
 #define GMC_THRESHOLD_LOW	((1 << GMC_THRESHOLD_BITS) / 8)
 
+#define OVL_CON_CLRFMT_MAN	BIT(23)
 #define OVL_CON_BYTE_SWAP	BIT(24)
-#define OVL_CON_MTX_YUV_TO_RGB	(6 << 16)
+#define OVL_CON_RGB_SWAP	BIT(25)
 #define OVL_CON_CLRFMT_RGB	(1 << 12)
 #define OVL_CON_CLRFMT_RGBA8888	(2 << 12)
 #define OVL_CON_CLRFMT_ARGB8888	(3 << 12)
 #define OVL_CON_CLRFMT_UYVY	(4 << 12)
 #define OVL_CON_CLRFMT_YUYV	(5 << 12)
+#define OVL_CON_MTX_YUV_TO_RGB	(6 << 16)
+#define OVL_CON_CLRFMT_PARGB8888	(OVL_CON_CLRFMT_ARGB8888 | OVL_CON_CLRFMT_MAN)
 #define OVL_CON_CLRFMT_RGB565(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
 					0 : OVL_CON_CLRFMT_RGB)
 #define OVL_CON_CLRFMT_RGB888(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
@@ -72,6 +76,22 @@
 #define	OVL_CON_VIRT_FLIP	BIT(9)
 #define	OVL_CON_HORZ_FLIP	BIT(10)
 
+static inline bool is_10bit_rgb(u32 fmt)
+{
+	switch (fmt) {
+	case DRM_FORMAT_XRGB2101010:
+	case DRM_FORMAT_ARGB2101010:
+	case DRM_FORMAT_RGBX1010102:
+	case DRM_FORMAT_RGBA1010102:
+	case DRM_FORMAT_XBGR2101010:
+	case DRM_FORMAT_ABGR2101010:
+	case DRM_FORMAT_BGRX1010102:
+	case DRM_FORMAT_BGRA1010102:
+		return true;
+	}
+	return false;
+}
+
 static const u32 mt8173_formats[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -89,12 +109,20 @@ static const u32 mt8173_formats[] = {
 static const u32 mt8195_formats[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XRGB2101010,
 	DRM_FORMAT_ARGB2101010,
 	DRM_FORMAT_BGRX8888,
 	DRM_FORMAT_BGRA8888,
+	DRM_FORMAT_BGRX1010102,
 	DRM_FORMAT_BGRA1010102,
 	DRM_FORMAT_ABGR8888,
 	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_XBGR2101010,
+	DRM_FORMAT_ABGR2101010,
+	DRM_FORMAT_RGBX8888,
+	DRM_FORMAT_RGBA8888,
+	DRM_FORMAT_RGBX1010102,
+	DRM_FORMAT_RGBA1010102,
 	DRM_FORMAT_RGB888,
 	DRM_FORMAT_BGR888,
 	DRM_FORMAT_RGB565,
@@ -254,9 +282,7 @@ static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
 	reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
 	reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
 
-	if (format == DRM_FORMAT_RGBA1010102 ||
-	    format == DRM_FORMAT_BGRA1010102 ||
-	    format == DRM_FORMAT_ARGB2101010)
+	if (is_10bit_rgb(format))
 		bit_depth = OVL_CON_CLRFMT_10_BIT;
 
 	reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
@@ -274,7 +300,13 @@ void mtk_ovl_config(struct device *dev, unsigned int w,
 	if (w != 0 && h != 0)
 		mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, ovl->regs,
 				      DISP_REG_OVL_ROI_SIZE);
-	mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_BGCLR);
+
+	/*
+	 * The background color should be opaque black (ARGB),
+	 * otherwise there will be no effect with alpha blend
+	 */
+	mtk_ddp_write_relaxed(cmdq_pkt, 0xff000000, &ovl->cmdq_reg,
+			      ovl->regs, DISP_REG_OVL_ROI_BGCLR);
 
 	mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);
 	mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);
@@ -352,7 +384,8 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int idx,
 		      DISP_REG_OVL_RDMA_CTRL(idx));
 }
 
-static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
+static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt,
+				    unsigned int blend_mode)
 {
 	/* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
 	 * is defined in mediatek HW data sheet.
@@ -371,17 +404,37 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
 		return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
 	case DRM_FORMAT_RGBX8888:
 	case DRM_FORMAT_RGBA8888:
+		return blend_mode == DRM_MODE_BLEND_COVERAGE ?
+		       OVL_CON_CLRFMT_ARGB8888 :
+		       OVL_CON_CLRFMT_PARGB8888;
+	case DRM_FORMAT_RGBX1010102:
+	case DRM_FORMAT_RGBA1010102:
 		return OVL_CON_CLRFMT_ARGB8888;
 	case DRM_FORMAT_BGRX8888:
 	case DRM_FORMAT_BGRA8888:
+		return OVL_CON_BYTE_SWAP |
+		       (blend_mode == DRM_MODE_BLEND_COVERAGE ?
+		       OVL_CON_CLRFMT_ARGB8888 :
+		       OVL_CON_CLRFMT_PARGB8888);
+	case DRM_FORMAT_BGRX1010102:
 	case DRM_FORMAT_BGRA1010102:
 		return OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP;
 	case DRM_FORMAT_XRGB8888:
 	case DRM_FORMAT_ARGB8888:
+		return blend_mode == DRM_MODE_BLEND_COVERAGE ?
+		       OVL_CON_CLRFMT_RGBA8888 :
+		       OVL_CON_CLRFMT_PARGB8888;
+	case DRM_FORMAT_XRGB2101010:
 	case DRM_FORMAT_ARGB2101010:
 		return OVL_CON_CLRFMT_RGBA8888;
 	case DRM_FORMAT_XBGR8888:
 	case DRM_FORMAT_ABGR8888:
+		return OVL_CON_RGB_SWAP |
+		       (blend_mode == DRM_MODE_BLEND_COVERAGE ?
+		       OVL_CON_CLRFMT_RGBA8888 :
+		       OVL_CON_CLRFMT_PARGB8888);
+	case DRM_FORMAT_XBGR2101010:
+	case DRM_FORMAT_ABGR2101010:
 		return OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP;
 	case DRM_FORMAT_UYVY:
 		return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB;
@@ -403,6 +456,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 	unsigned int fmt = pending->format;
 	unsigned int offset = (pending->y << 16) | pending->x;
 	unsigned int src_size = (pending->height << 16) | pending->width;
+	unsigned int blend_mode = state->base.pixel_blend_mode;
+	unsigned int ignore_pixel_alpha = 0;
 	unsigned int con;
 	bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
 	union overlay_pitch {
@@ -420,9 +475,15 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 		return;
 	}
 
-	con = ovl_fmt_convert(ovl, fmt);
-	if (state->base.fb && state->base.fb->format->has_alpha)
-		con |= OVL_CON_AEN | OVL_CON_ALPHA;
+	con = ovl_fmt_convert(ovl, fmt, blend_mode);
+	if (state->base.fb) {
+		con |= OVL_CON_AEN;
+		con |= state->base.alpha & OVL_CON_ALPHA;
+	}
+
+	if (blend_mode == DRM_MODE_BLEND_PIXEL_NONE ||
+	    (state->base.fb && !state->base.fb->format->has_alpha))
+		ignore_pixel_alpha = OVL_CONST_BLEND;
 
 	if (pending->rotation & DRM_MODE_REFLECT_Y) {
 		con |= OVL_CON_VIRT_FLIP;
@@ -439,8 +500,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 
 	mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
 			      DISP_REG_OVL_CON(idx));
-	mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, &ovl->cmdq_reg, ovl->regs,
-			      DISP_REG_OVL_PITCH(idx));
+	mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha,
+			      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx));
 	mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
 			      DISP_REG_OVL_SRC_SIZE(idx));
 	mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs,
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:15 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:15 +0800
Subject: [PATCH v5 09/13] drm/mediatek: Support alpha blending in Mixer
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-10-shawn.sung@mediatek.com>

Support "Pre-multiplied" and "None" blend mode on MediaTek's chips.
Before this patch, only the "Coverage" mode is supported.

Please refer to the description of the commit
"drm/mediatek: Support alpha blending in display driver"
for more information.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_ethdr.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index 69872b77922eb..e95331c068151 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -5,6 +5,7 @@
 
 #include <drm/drm_fourcc.h>
 #include <drm/drm_framebuffer.h>
+#include <drm/drm_blend.h>
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/of_device.h>
@@ -35,6 +36,7 @@
 #define MIX_SRC_L0_EN				BIT(0)
 #define MIX_L_SRC_CON(n)		(0x28 + 0x18 * (n))
 #define NON_PREMULTI_SOURCE			(2 << 12)
+#define PREMULTI_SOURCE				(3 << 12)
 #define MIX_L_SRC_SIZE(n)		(0x30 + 0x18 * (n))
 #define MIX_L_SRC_OFFSET(n)		(0x34 + 0x18 * (n))
 #define MIX_FUNC_DCM0			0x120
@@ -153,7 +155,8 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
 	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;
+	unsigned int mix_con = NON_PREMULTI_SOURCE;
+	bool replace_src_a = false;
 
 	dev_dbg(dev, "%s+ idx:%d", __func__, idx);
 
@@ -170,19 +173,28 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
 		return;
 	}
 
-	if (state->base.fb && state->base.fb->format->has_alpha)
-		alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA;
+	mix_con |= MIXER_ALPHA_AEN | (state->base.alpha & MIXER_ALPHA);
 
-	mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, alpha_con ? false : true,
-				  DEFAULT_9BIT_ALPHA,
+	if (state->base.pixel_blend_mode != DRM_MODE_BLEND_COVERAGE)
+		mix_con |= PREMULTI_SOURCE;
+
+	if (state->base.pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE ||
+	    (state->base.fb && !state->base.fb->format->has_alpha)) {
+		/*
+		 * Mixer doesn't support CONST_BLD mode,
+		 * use a trick to make the output equivalent
+		 */
+		replace_src_a = true;
+	}
+
+	mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, replace_src_a, MIXER_ALPHA,
 				  pending->x & 1 ? MIXER_INX_MODE_EVEN_EXTEND :
 				  MIXER_INX_MODE_BYPASS, align_width / 2 - 1, 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(cmdq_pkt, mix_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx));
 	mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer->cmdq_base, mixer->regs, MIX_SRC_CON,
 			   BIT(idx));
 }
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:19 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:19 +0800
Subject: [PATCH v5 13/13] drm/mediatek: Add comments for the structures
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-14-shawn.sung@mediatek.com>

Add comments for the structures to improve readability.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 21 +++++++++++++-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 22 ++++++++++++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 32 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h      | 17 +++++++++++
 drivers/gpu/drm/mediatek/mtk_ethdr.c        | 11 +++++++
 5 files changed, 99 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index cf35783ad4b02..b92c5c3c590a0 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -164,6 +164,20 @@ static const u32 mt8195_ovl_crc_ofs[] = {
 	DISP_REG_OVL_CRC,
 };
 
+/**
+ * struct mtk_disp_ovl_data - ovl driver data
+ * @addr: offset of the first layer (layer-0)
+ * @gmc_bits: gmc (gating memory clock) bit masks for adjusting positivity for ovl
+ * @layer_nr: layer numbers that ovl supports
+ * @fmt_rgb565_is_0: whether or not rgb565 is represented as 0
+ * @smi_id_en: determine if smi needs to be enabled
+ * @supports_afbc: determine if ovl supports afbc
+ * @formats: format table that ovl supports
+ * @num_formats: number of formats that ovl supports
+ * @supports_clrfmt_ext: whether the ovl supports clear format (for alpha blend)
+ * @crc_ofs: crc offset table
+ * @crc_cnt: count of crc registers (could be more than one bank)
+ */
 struct mtk_disp_ovl_data {
 	unsigned int addr;
 	unsigned int gmc_bits;
@@ -178,10 +192,15 @@ struct mtk_disp_ovl_data {
 	size_t crc_cnt;
 };
 
-/*
+/**
  * struct mtk_disp_ovl - DISP_OVL driver structure
  * @crtc: associated crtc to report vblank events to
+ * @clk: clock of the ovl
+ * @regs: base address of the ovl register that can be accessed by cpu
+ * @cmdq_reg: register related info for cmdq (subsys, offset ...etc.)
  * @data: platform data
+ * @vblank_cb: callback function when vblank irq happened
+ * @vblank_cb_data: data to the callback function
  * @crc: crc related information
  */
 struct mtk_disp_ovl {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 6cb1ed419dee7..b4f7b3d3bbeb6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -28,14 +28,30 @@
  * struct mtk_drm_crtc - MediaTek specific crtc structure.
  * @base: crtc object.
  * @enabled: records whether crtc_enable succeeded
+ * @pending_needs_vblank: determine if we need to handle vblank event
+ * @event: the vblank event to handle
  * @planes: array of 4 drm_plane structures, one for each overlay plane
+ * @layer_nr: layer numbers that the crtc supports
  * @pending_planes: whether any plane has pending changes to be applied
+ * @pending_async_planes: if there is any pending async update
+ * @cmdq_client: a handler to control cmdq (mbox channel, thread ...etc.)
+ * @cmdq_handle: cmdq packet to store the commands
+ * @cmdq_event: cmdq event that the thread is waiting for
+ * @cmdq_vblank_cnt: vblank count that is dedicated for the cmdq thread
+ * @cb_blocking_queue: wait queue to determine if cmdq is blocked
  * @mmsys_dev: pointer to the mmsys device for configuration registers
+ * @dma_dev: pointer to the dma device (usually rdma)
  * @mutex: handle to one of the ten disp_mutex streams
- * @ddp_comp_nr: number of components in ddp_comp
+ * @ddp_comp_nr_ori: number of the components excludes the route (origin)
+ * @max_ddp_comp_nr: maximum number of the components in routes
+ * @ddp_comp_nr: number of the components in the current path
  * @ddp_comp: array of pointers the mtk_ddp_comp structures used by this crtc
- *
- * TODO: Needs update: this header is missing a bunch of member descriptions.
+ * @conn_route_nr: number of the components in route
+ * @conn_routes: route to the connector
+ * @hw_lock: mutex lock to avoid race condition when layer config
+ * @config_updating: determine if the layer configuration is done
+ * @crc_provider: get crc provider of the crtc
+ * @frames: count the frames that are added to crc entry
  */
 struct mtk_drm_crtc {
 	struct drm_crtc			base;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 231017470607e..dcf8466b8f857 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -48,6 +48,38 @@ enum mtk_ddp_comp_type {
 
 struct mtk_ddp_comp;
 struct cmdq_pkt;
+
+/* struct mtk_ddp_comp_funcs - function pointers of the ddp components
+ * @clk_enable: enable the clocks of the component
+ * @clk_disable: disable the clocks of the component
+ * @config: configure the component
+ * @start: start (enable) the component
+ * @stop: stop (disable) the component
+ * @register_vblank_cb: to register a callback function when vblank irq occurs
+ * @unregister_vblank_cb: to unregister the callback function from the vblank irq
+ * @enable_vblank: enable vblank irq
+ * @disable_vblank: disable vblank irq
+ * @supported_rotations: return rotation capability of the component
+ * @layer_nr: how many layers the component supports
+ * @layer_check: to check if the state of the layer is valid for the component
+ * @layer_config: to configure the component according to the state of the layer
+ * @gamma_set: to set gamma for the component
+ * @bgclr_in_on: turn on background color
+ * @bgclr_in_off: turn off background color
+ * @ctm_set: set color transformation matrix
+ * @dma_dev_get: return the device that uses direct memory access
+ * @get_formats: get the format that is currently in use by the component
+ * @get_num_formats: get number of the formats that the component supports
+ * @connect: connect the sub modules of the component
+ * @disconnect: disconnect the sub modules of the component
+ * @add: add the device to the component (mount them in the mutex)
+ * @remove: remove the device from the component (unmount them from the mutex)
+ * @encoder_index: get the encoder index of the component
+ * @crc: return the start of crc array
+ * @crc_cnt: how many CRCs the component supports
+ * @crc_entry: get the pointer to the crc entry
+ * @crc_read: call this function to read crc from the hardware component
+ */
 struct mtk_ddp_comp_funcs {
 	int (*power_on)(struct device *dev);
 	void (*power_off)(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 414764b4546ba..8ee1f36a6c2b8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -33,6 +33,23 @@ struct mtk_drm_route {
 	const unsigned int route_ddp;
 };
 
+/**
+ * struct mtk_mmsys_driver_data - capabilities for the mmsys
+ * @main_path: path of the main display
+ * @main_len: length of the main display path
+ * @ext_path: path of the external display
+ * @ext_len: length of the external display path
+ * @third_path: path of the third display
+ * @third_len: length of the third display path
+ * @conn_routes: routing table of all the possible connectors
+ * @conn_routes_num: number of the routing table for the connectors
+ * @shadow_register: whether or not shadow register is enabled
+ * @mmsys_id: multi-media system ID
+ * @mmsys_dev_num: number of devices for in the mmsys as a whole
+ * @max_pitch: maximum pitch in bytes that the mmsys supports
+ * @min_width: minimum fb pixel width on this device
+ * @min_height: minimum fb pixel height on this device
+ */
 struct mtk_mmsys_driver_data {
 	const unsigned int *main_path;
 	unsigned int main_len;
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index 30eb2c3d95c0b..eae72deacfd2c 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -82,6 +82,17 @@ struct mtk_ethdr_comp {
 	struct cmdq_client_reg	cmdq_base;
 };
 
+/**
+ * struct mtk_ethdr - ethdr driver data
+ * @ethdr_comp: components of ethdr(mixer)
+ * @ethdr_clk: clocks of ethdr components
+ * @mmsys_dev: mmsys device that ethdr binds to
+ * @vblank_cb: callback function when vblank irq occurs
+ * @vblank_cb_data: data fo vblank callback
+ * @irq: irq that triggers irq handler
+ * @reset_ctl: reset control of ethdr
+ * @crc: crc information
+ */
 struct mtk_ethdr {
 	struct mtk_ethdr_comp	ethdr_comp[ETHDR_ID_MAX];
 	struct clk_bulk_data	ethdr_clk[ETHDR_CLK_NUM];
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:08 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:08 +0800
Subject: [PATCH v5 02/13] drm/mediatek: Add OVL compatible name for MT8195
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-3-shawn.sung@mediatek.com>

Add OVL compatible name for MT8195.
Without this commit, DRM won't work after modifying the device tree.

Reviewed-by: CK Hu <ck.hu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index cc746de91834c..890e1e93a2227 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -762,6 +762,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8192-disp-ovl",
 	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8195-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
 	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt8192-disp-ovl-2l",
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:13 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:13 +0800
Subject: [PATCH v5 07/13] drm/mediatek: Support alpha blending in display driver
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-8-shawn.sung@mediatek.com>

Support "Pre-multiplied" and "None" blend mode on MediaTek's chips by
adding correct blend mode property when the planes init.
Before this patch, only the "Coverage" mode (default) is supported.

For more information, there are three pixel blend modes in DRM driver:
"None", "Pre-multiplied", and "Coverage".

To understand the difference between these modes, let's take a look at
the following two approaches to do alpha blending:

1. Straight:
dst.RGB = src.RGB * src.A + dst.RGB * (1 - src.A)
This is straightforward and easy to understand, when the source layer is
compositing with the destination layer, it's alpha will affect the
result. This is also known as "post-multiplied", or "Coverage" mode.

2. Pre-multiplied:
dst.RGB = src.RGB + dst.RGB * (1 - src.A)
Since the source RGB have already multiplied its alpha, only destination
RGB need to multiply it. This is the "Pre-multiplied" mode in DRM.

For the "None" blend mode in DRM, it means the pixel alpha is ignored
when compositing the layers, only the constant alpha for the composited
layer will take effects.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 2dc28a79f7603..4e0206c45efd7 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -346,6 +346,17 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
 			DRM_INFO("Create rotation property failed\n");
 	}
 
+	err = drm_plane_create_alpha_property(plane);
+	if (err)
+		DRM_ERROR("failed to create property: alpha\n");
+
+	err = drm_plane_create_blend_mode_property(plane,
+						   BIT(DRM_MODE_BLEND_PREMULTI) |
+						   BIT(DRM_MODE_BLEND_COVERAGE) |
+						   BIT(DRM_MODE_BLEND_PIXEL_NONE));
+	if (err)
+		DRM_ERROR("failed to create property: blend_mode\n");
+
 	drm_plane_helper_add(plane, &mtk_plane_helper_funcs);
 
 	return 0;
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:17 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:17 +0800
Subject: [PATCH v5 11/13] drm/mediatek: Support CRC in OVL
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-12-shawn.sung@mediatek.com>

We choose OVL as the CRC generator from other hardware
components that are also capable of calculating CRCs,
since its frame done event triggers vblanks, it can be
used as a signal to know when is safe to retrieve CRC of
the frame.

Please note that position of the hardware component
that is chosen as CRC generator in the display path is
significant. For example, while OVL is the first module
in VDOSYS0, its CRC won't be affected by the modules
after it, which means effects applied by PQ, Gamma,
Dither or any other components after OVL won't be
calculated in CRC generation.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   3 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 197 +++++++++++++++++++-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   3 +
 3 files changed, 193 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index cd5ca5359b0f0..7ef8dbb07c2db 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -104,6 +104,9 @@ void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
 const u32 *mtk_ovl_get_formats(struct device *dev);
 size_t mtk_ovl_get_num_formats(struct device *dev);
+size_t mtk_ovl_crc_cnt(struct device *dev);
+u32 *mtk_ovl_crc_entry(struct device *dev);
+void mtk_ovl_crc_read(struct device *dev);
 
 void mtk_ovl_adaptor_add_comp(struct device *dev, struct mtk_mutex *mutex);
 void mtk_ovl_adaptor_remove_comp(struct device *dev, struct mtk_mutex *mutex);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 98c989fddcc08..cf35783ad4b02 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -25,12 +25,20 @@
 #define OVL_FME_CPL_INT					BIT(1)
 #define DISP_REG_OVL_INTSTA			0x0008
 #define DISP_REG_OVL_EN				0x000c
+#define OVL_EN						BIT(0)
+#define OVL_OP_8BIT_MODE				BIT(4)
+#define OVL_HG_FOVL_CK_ON				BIT(8)
+#define OVL_HF_FOVL_CK_ON				BIT(10)
+#define DISP_REG_OVL_TRIG			0x0010
+#define OVL_CRC_EN					BIT(8)
+#define OVL_CRC_CLR					BIT(9)
 #define DISP_REG_OVL_RST			0x0014
 #define DISP_REG_OVL_ROI_SIZE			0x0020
 #define DISP_REG_OVL_DATAPATH_CON		0x0024
 #define OVL_LAYER_SMI_ID_EN				BIT(0)
 #define OVL_BGCLR_SEL_IN				BIT(2)
 #define OVL_LAYER_AFBC_EN(n)				BIT(4+n)
+#define OVL_OUTPUT_CLAMP				BIT(26)
 #define DISP_REG_OVL_ROI_BGCLR			0x0028
 #define DISP_REG_OVL_SRC_CON			0x002c
 #define DISP_REG_OVL_CON(n)			(0x0030 + 0x20 * (n))
@@ -43,7 +51,26 @@
 #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
 #define DISP_REG_OVL_ADDR_MT2701		0x0040
+#define DISP_REG_OVL_CRC			0x0270
+#define OVL_CRC_OUT_MASK				GENMASK(30, 0)
 #define DISP_REG_OVL_CLRFMT_EXT			0x02D0
+#define DISP_REG_OVL_CLRFMT_EXT1		0x02D8
+#define OVL_CLRFMT_EXT1_CSC_EN(n)			(1 << (((n) * 4) + 1))
+#define DISP_REG_OVL_Y2R_PARA_R0(n)		(0x0134 + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_RMY				(GENMASK(14, 0))
+#define DISP_REG_OVL_Y2R_PARA_G0(n)		(0x013c + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_GMU				(GENMASK(30, 16))
+#define DISP_REG_OVL_Y2R_PARA_B1(n)		(0x0148 + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_BMV				(GENMASK(14, 0))
+#define DISP_REG_OVL_Y2R_PARA_YUV_A_0(n)	(0x014c + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_YA				(GENMASK(10, 0))
+#define OVL_Y2R_PARA_C_CF_UA				(GENMASK(26, 16))
+#define DISP_REG_OVL_Y2R_PARA_YUV_A_1(n)	(0x0150 + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_VA				(GENMASK(10, 0))
+#define DISP_REG_OVL_Y2R_PRE_ADD2(n)		(0x0154 + 0x28 * (n))
+#define DISP_REG_OVL_R2R_R0(n)			(0x0500 + 0x40 * (n))
+#define DISP_REG_OVL_R2R_G1(n)			(0x0510 + 0x40 * (n))
+#define DISP_REG_OVL_R2R_B2(n)			(0x0520 + 0x40 * (n))
 #define DISP_REG_OVL_ADDR_MT8173		0x0f40
 #define DISP_REG_OVL_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n))
 #define DISP_REG_OVL_HDR_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n) + 0x04)
@@ -56,6 +83,8 @@
 #define OVL_CON_CLRFMT_MAN	BIT(23)
 #define OVL_CON_BYTE_SWAP	BIT(24)
 #define OVL_CON_RGB_SWAP	BIT(25)
+#define OVL_CON_MTX_AUTO_DIS	BIT(26)
+#define OVL_CON_MTX_EN		BIT(27)
 #define OVL_CON_CLRFMT_RGB	(1 << 12)
 #define OVL_CON_CLRFMT_RGBA8888	(2 << 12)
 #define OVL_CON_CLRFMT_ARGB8888	(3 << 12)
@@ -63,6 +92,7 @@
 #define OVL_CON_CLRFMT_YUYV	(5 << 12)
 #define OVL_CON_MTX_YUV_TO_RGB	(6 << 16)
 #define OVL_CON_CLRFMT_PARGB8888	(OVL_CON_CLRFMT_ARGB8888 | OVL_CON_CLRFMT_MAN)
+#define OVL_CON_MTX_PROGRAMMABLE	(8 << 16)
 #define OVL_CON_CLRFMT_RGB565(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
 					0 : OVL_CON_CLRFMT_RGB)
 #define OVL_CON_CLRFMT_RGB888(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
@@ -130,6 +160,10 @@ static const u32 mt8195_formats[] = {
 	DRM_FORMAT_YUYV,
 };
 
+static const u32 mt8195_ovl_crc_ofs[] = {
+	DISP_REG_OVL_CRC,
+};
+
 struct mtk_disp_ovl_data {
 	unsigned int addr;
 	unsigned int gmc_bits;
@@ -140,12 +174,15 @@ struct mtk_disp_ovl_data {
 	const u32 *formats;
 	size_t num_formats;
 	bool supports_clrfmt_ext;
+	const u32 *crc_ofs;
+	size_t crc_cnt;
 };
 
 /*
  * struct mtk_disp_ovl - DISP_OVL driver structure
  * @crtc: associated crtc to report vblank events to
  * @data: platform data
+ * @crc: crc related information
  */
 struct mtk_disp_ovl {
 	struct drm_crtc			*crtc;
@@ -155,8 +192,30 @@ struct mtk_disp_ovl {
 	const struct mtk_disp_ovl_data	*data;
 	void				(*vblank_cb)(void *data);
 	void				*vblank_cb_data;
+	struct mtk_drm_crc		crc;
 };
 
+size_t mtk_ovl_crc_cnt(struct device *dev)
+{
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+	return ovl->crc.cnt;
+}
+
+u32 *mtk_ovl_crc_entry(struct device *dev)
+{
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+	return ovl->crc.va;
+}
+
+void mtk_ovl_crc_read(struct device *dev)
+{
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+	mtk_drm_crc_read(&ovl->crc, ovl->regs);
+}
+
 static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
 {
 	struct mtk_disp_ovl *priv = dev_id;
@@ -236,21 +295,40 @@ void mtk_ovl_clk_disable(struct device *dev)
 void mtk_ovl_start(struct device *dev)
 {
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+	unsigned int reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
 
-	if (ovl->data->smi_id_en) {
-		unsigned int reg;
+	if (ovl->data->smi_id_en)
+		reg |= OVL_LAYER_SMI_ID_EN;
 
-		reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
-		reg = reg | OVL_LAYER_SMI_ID_EN;
-		writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+	/*
+	 * When doing Y2R conversion, it's common to get an output
+	 * that is larger than 10 bits (negative numbers).
+	 * Enable this bit to clamp the output to 10 bits per channel
+	 * (should always be enabled)
+	 */
+	reg |= OVL_OUTPUT_CLAMP;
+	writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+
+	reg = OVL_EN;
+	if (ovl->data->crc_cnt) {
+		/* enable crc  and its related clocks */
+		writel_relaxed(OVL_CRC_EN, ovl->regs + DISP_REG_OVL_TRIG);
+		reg |= OVL_OP_8BIT_MODE | OVL_HG_FOVL_CK_ON | OVL_HF_FOVL_CK_ON;
 	}
-	writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN);
+	writel_relaxed(reg, ovl->regs + DISP_REG_OVL_EN);
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	mtk_drm_crc_cmdq_start(&ovl->crc);
+#endif
 }
 
 void mtk_ovl_stop(struct device *dev)
 {
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
 
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	mtk_drm_crc_cmdq_stop(&ovl->crc);
+#endif
 	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_EN);
 	if (ovl->data->smi_id_en) {
 		unsigned int reg;
@@ -485,6 +563,83 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 	    (state->base.fb && !state->base.fb->format->has_alpha))
 		ignore_pixel_alpha = OVL_CONST_BLEND;
 
+	/*
+	 * OVL only supports 8 bits data in CRC calculation, transform 10-bit
+	 * RGB to 8-bit RGB by leveraging the ability of the Y2R (YUV-to-RGB)
+	 * hardware to multiply coefficients, although there is nothing to do
+	 * with the YUV format.
+	 */
+	if (ovl->data->supports_clrfmt_ext) {
+		u32 y2r_coef = 0, y2r_offset = 0, r2r_coef = 0, csc_en = 0;
+
+		if (is_10bit_rgb(fmt)) {
+			con |= OVL_CON_MTX_AUTO_DIS | OVL_CON_MTX_EN | OVL_CON_MTX_PROGRAMMABLE;
+
+			/*
+			 * Y2R coefficient setting
+			 * bit 13 is 2^1, bit 12 is 2^0, bit 11 is 2^-1,
+			 * bit 10 is 2^-2 = 0.25
+			 */
+			y2r_coef = BIT(10);
+
+			/* -1 in 10bit */
+			y2r_offset = GENMASK(10, 0) - 1;
+
+			/*
+			 * R2R coefficient setting
+			 * bit 19 is 2^1, bit 18 is 2^0, bit 17 is 2^-1,
+			 * bit 20 is 2^2 = 4
+			 */
+			r2r_coef = BIT(20);
+
+			/* CSC_EN is for R2R */
+			csc_en = OVL_CLRFMT_EXT1_CSC_EN(idx);
+
+			/*
+			 * 1. YUV input data - 1 and shift right for 2 bits to remove it
+			 * [R']   [0.25    0    0]   [Y in - 1]
+			 * [G'] = [   0 0.25    0] * [U in - 1]
+			 * [B']   [   0    0 0.25]   [V in - 1]
+			 *
+			 * 2. shift left for 2 bit letting the last 2 bits become 0
+			 * [R out]   [ 4  0  0]   [R']
+			 * [G out] = [ 0  4  0] * [G']
+			 * [B out]   [ 0  0  4]   [B']
+			 */
+		}
+
+		mtk_ddp_write_mask(cmdq_pkt, y2r_coef,
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_R0(idx),
+				   OVL_Y2R_PARA_C_CF_RMY);
+		mtk_ddp_write_mask(cmdq_pkt, (y2r_coef << 16),
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_G0(idx),
+				   OVL_Y2R_PARA_C_CF_GMU);
+		mtk_ddp_write_mask(cmdq_pkt, y2r_coef,
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_B1(idx),
+				   OVL_Y2R_PARA_C_CF_BMV);
+
+		mtk_ddp_write_mask(cmdq_pkt, y2r_offset,
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_0(idx),
+				   OVL_Y2R_PARA_C_CF_YA);
+		mtk_ddp_write_mask(cmdq_pkt, (y2r_offset << 16),
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_0(idx),
+				   OVL_Y2R_PARA_C_CF_UA);
+		mtk_ddp_write_mask(cmdq_pkt, y2r_offset,
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_1(idx),
+				   OVL_Y2R_PARA_C_CF_VA);
+
+		mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
+				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_R0(idx));
+		mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
+				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_G1(idx));
+		mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
+				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_B2(idx));
+
+		mtk_ddp_write_mask(cmdq_pkt, csc_en,
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CLRFMT_EXT1,
+				   OVL_CLRFMT_EXT1_CSC_EN(idx));
+	}
+
 	if (pending->rotation & DRM_MODE_REFLECT_Y) {
 		con |= OVL_CON_VIRT_FLIP;
 		addr += (pending->height - 1) * pending->pitch;
@@ -591,15 +746,31 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
 		dev_err(dev, "failed to ioremap ovl\n");
 		return PTR_ERR(priv->regs);
 	}
+
+	priv->data = of_device_get_match_data(dev);
+	platform_set_drvdata(pdev, priv);
+
+	if (priv->data->crc_cnt) {
+		mtk_drm_crc_init(&priv->crc,
+				 priv->data->crc_ofs, priv->data->crc_cnt,
+				 DISP_REG_OVL_TRIG, OVL_CRC_CLR);
+	}
+
 #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);
 
+	if (priv->data->crc_cnt) {
+		if (of_property_read_u32_index(dev->of_node,
+					       "mediatek,gce-events", 0,
+					       &priv->crc.cmdq_event)) {
+			dev_warn(dev, "failed to get gce-events for crc\n");
+		}
+		priv->crc.cmdq_reg = &priv->cmdq_reg;
+		mtk_drm_crc_cmdq_create(dev, &priv->crc);
+	}
+#endif
 	ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
 			       IRQF_TRIGGER_NONE, dev_name(dev), priv);
 	if (ret < 0) {
@@ -620,6 +791,10 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
 
 static void mtk_disp_ovl_remove(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+	mtk_drm_crc_destroy(&ovl->crc);
 	component_del(&pdev->dev, &mtk_disp_ovl_component_ops);
 	pm_runtime_disable(&pdev->dev);
 }
@@ -690,6 +865,8 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
 	.formats = mt8195_formats,
 	.num_formats = ARRAY_SIZE(mt8195_formats),
 	.supports_clrfmt_ext = true,
+	.crc_ofs = mt8195_ovl_crc_ofs,
+	.crc_cnt = ARRAY_SIZE(mt8195_ovl_crc_ofs),
 };
 
 static const struct of_device_id mtk_disp_ovl_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 b47be6955d9b8..ea04b2769ae8b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -349,6 +349,9 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = {
 	.clk_enable = mtk_ovl_clk_enable,
 	.clk_disable = mtk_ovl_clk_disable,
 	.config = mtk_ovl_config,
+	.crc_cnt = mtk_ovl_crc_cnt,
+	.crc_entry = mtk_ovl_crc_entry,
+	.crc_read = mtk_ovl_crc_read,
 	.start = mtk_ovl_start,
 	.stop = mtk_ovl_stop,
 	.register_vblank_cb = mtk_ovl_register_vblank_cb,
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:16 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:16 +0800
Subject: [PATCH v5 10/13] drm/mediatek: Support CRC in display driver
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-11-shawn.sung@mediatek.com>

Register CRC related function pointers to support
CRC retrieval.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 239 ++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |  39 ++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   3 +
 3 files changed, 281 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 14cf75fa217f9..6cb1ed419dee7 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -68,6 +68,9 @@ struct mtk_drm_crtc {
 	/* lock for display hardware access */
 	struct mutex			hw_lock;
 	bool				config_updating;
+
+	struct mtk_ddp_comp		*crc_provider;
+	unsigned int			frames;
 };
 
 struct mtk_crtc_state {
@@ -635,6 +638,14 @@ static void mtk_crtc_ddp_irq(void *data)
 	struct drm_crtc *crtc = data;
 	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_drm_private *priv = crtc->dev->dev_private;
+	struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
+
+	/*
+	 * crc providers should make sure the crc is always correct
+	 * by resetting it in .crc_read()
+	 */
+	if (crtc->crc.opened)
+		comp->funcs->crc_read(comp->dev);
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
@@ -646,6 +657,24 @@ static void mtk_crtc_ddp_irq(void *data)
 	if (!priv->data->shadow_register)
 		mtk_crtc_ddp_config(crtc, NULL);
 #endif
+
+	/*
+	 * drm_crtc_add_crc_entry() could take more than 50ms to finish
+	 * put it at the end of the isr
+	 */
+	if (crtc->crc.opened) {
+		/*
+		 * skip the first crc because the first frame is configured by
+		 * mtk_crtc_ddp_hw_init() when atomic enable
+		 */
+		if (++mtk_crtc->frames > 1) {
+			drm_crtc_add_crc_entry(crtc, true,
+					       drm_crtc_vblank_count(crtc),
+					       comp->funcs->crc_entry(comp->dev));
+		}
+	} else {
+		mtk_crtc->frames = 0;
+	}
 	mtk_drm_finish_page_flip(mtk_crtc);
 }
 
@@ -704,6 +733,40 @@ static void mtk_drm_crtc_update_output(struct drm_crtc *crtc,
 	}
 }
 
+static int mtk_drm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src)
+{
+	if (src && strcmp(src, "auto") != 0) {
+		DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
+			  __func__, drm_crtc_index(crtc), src);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int mtk_drm_crtc_verify_crc_source(struct drm_crtc *crtc,
+					  const char *src,
+					  size_t *cnt)
+{
+	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
+
+	if (!comp) {
+		DRM_ERROR("%s(crtc-%d): no crc provider\n",
+			  __func__, drm_crtc_index(crtc));
+		return -ENOENT;
+	}
+
+	if (src && strcmp(src, "auto") != 0) {
+		DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
+			  __func__, drm_crtc_index(crtc), src);
+		return -EINVAL;
+	}
+
+	*cnt = comp->funcs->crc_cnt(comp->dev);
+
+	return 0;
+}
+
 int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
 			     struct mtk_plane_state *state)
 {
@@ -841,6 +904,8 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
 	.atomic_destroy_state	= mtk_drm_crtc_destroy_state,
 	.enable_vblank		= mtk_drm_crtc_enable_vblank,
 	.disable_vblank		= mtk_drm_crtc_disable_vblank,
+	.set_crc_source		= mtk_drm_crtc_set_crc_source,
+	.verify_crc_source	= mtk_drm_crtc_verify_crc_source,
 };
 
 static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
@@ -1033,6 +1098,11 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 
 			if (comp->funcs->ctm_set)
 				has_ctm = true;
+
+			if (comp->funcs->crc_cnt &&
+			    comp->funcs->crc_entry &&
+			    comp->funcs->crc_read)
+				mtk_crtc->crc_provider = comp;
 		}
 
 		mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq,
@@ -1137,3 +1207,172 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 
 	return 0;
 }
+
+void mtk_drm_crc_init(struct mtk_drm_crc *crc,
+		      const u32 *crc_offset_table, size_t crc_count,
+		      u32 reset_offset, u32 reset_mask)
+{
+	crc->ofs = crc_offset_table;
+	crc->cnt = crc_count;
+	crc->rst_ofs = reset_offset;
+	crc->rst_msk = reset_mask;
+	crc->va = kcalloc(crc->cnt, sizeof(*crc->va), GFP_KERNEL);
+	if (!crc->va) {
+		DRM_ERROR("failed to allocate memory for crc\n");
+		crc->cnt = 0;
+	}
+}
+
+void mtk_drm_crc_read(struct mtk_drm_crc *crc, void __iomem *reg)
+{
+	if (!crc->cnt || !crc->ofs || !crc->va)
+		return;
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	/* sync to see the most up-to-date copy of the DMA buffer */
+	dma_sync_single_for_cpu(crc->cmdq_client.chan->mbox->dev,
+				crc->pa, crc->cnt * sizeof(*crc->va),
+				DMA_FROM_DEVICE);
+#else
+	/* read crc with cpu for the platforms without cmdq */
+	{
+		u32 n;
+
+		for (n = 0; n < crc->cnt; n++)
+			crc->va[n] = readl(reg + crc->ofs[n]);
+
+		n = readl(reg + crc->rst_ofs);
+
+		/* pull reset bit */
+		n |= crc->rst_msk;
+		writel(n, reg + crc->rst_ofs);
+
+		/* release reset bit */
+		n &= ~crc->rst_msk;
+		writel(n, reg + crc->rst_ofs);
+	}
+#endif
+}
+
+void mtk_drm_crc_destroy(struct mtk_drm_crc *crc)
+{
+	if (!crc->cnt)
+		return;
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	if (crc->pa) {
+		dma_unmap_single(crc->cmdq_client.chan->mbox->dev,
+				 crc->pa, crc->cnt * sizeof(*crc->va),
+				 DMA_TO_DEVICE);
+		crc->pa = 0;
+	}
+	if (crc->cmdq_client.chan) {
+		mtk_drm_cmdq_pkt_destroy(&crc->cmdq_handle);
+		mbox_free_channel(crc->cmdq_client.chan);
+		crc->cmdq_client.chan = NULL;
+	}
+#endif
+	kfree(crc->va);
+	crc->va = NULL;
+	crc->cnt = 0;
+}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+void mtk_drm_crc_cmdq_create(struct device *dev, struct mtk_drm_crc *crc)
+{
+	int i;
+
+	if (!crc->cnt) {
+		dev_warn(dev, "%s: not support\n", __func__);
+		goto cleanup;
+	}
+
+	if (!crc->ofs) {
+		dev_warn(dev, "%s: not defined\n", __func__);
+		goto cleanup;
+	}
+
+	crc->cmdq_client.client.dev = dev;
+	crc->cmdq_client.client.tx_block = false;
+	crc->cmdq_client.client.knows_txdone = true;
+	crc->cmdq_client.client.rx_callback = NULL;
+	crc->cmdq_client.chan = mbox_request_channel(&crc->cmdq_client.client, 0);
+	if (IS_ERR(crc->cmdq_client.chan)) {
+		dev_warn(dev, "%s: failed to create mailbox client\n", __func__);
+		crc->cmdq_client.chan = NULL;
+		goto cleanup;
+	}
+
+	if (mtk_drm_cmdq_pkt_create(&crc->cmdq_client, &crc->cmdq_handle, PAGE_SIZE)) {
+		dev_warn(dev, "%s: failed to create cmdq packet\n", __func__);
+		goto cleanup;
+	}
+
+	if (!crc->va) {
+		dev_warn(dev, "%s: no memory\n", __func__);
+		goto cleanup;
+	}
+
+	/* map the entry to get a dma address for cmdq to store the crc */
+	crc->pa = dma_map_single(crc->cmdq_client.chan->mbox->dev,
+				 crc->va, crc->cnt * sizeof(*crc->va),
+				 DMA_FROM_DEVICE);
+
+	if (dma_mapping_error(crc->cmdq_client.chan->mbox->dev, crc->pa)) {
+		dev_err(dev, "%s: failed to map dma\n", __func__);
+		goto cleanup;
+	}
+
+	if (crc->cmdq_event)
+		cmdq_pkt_wfe(&crc->cmdq_handle, crc->cmdq_event, true);
+
+	for (i = 0; i < crc->cnt; i++) {
+		/* put crc to spr1 register */
+		cmdq_pkt_read_s(&crc->cmdq_handle, crc->cmdq_reg->subsys,
+				crc->cmdq_reg->offset + crc->ofs[i],
+				CMDQ_THR_SPR_IDX1);
+
+		/* copy spr1 register to physical address of the crc */
+		cmdq_pkt_assign(&crc->cmdq_handle, CMDQ_THR_SPR_IDX0,
+				CMDQ_ADDR_HIGH(crc->pa + i * sizeof(*crc->va)));
+		cmdq_pkt_write_s(&crc->cmdq_handle, CMDQ_THR_SPR_IDX0,
+				 CMDQ_ADDR_LOW(crc->pa + i * sizeof(*crc->va)),
+				 CMDQ_THR_SPR_IDX1);
+	}
+	/* reset crc */
+	mtk_ddp_write_mask(&crc->cmdq_handle, ~0, crc->cmdq_reg, 0,
+			   crc->rst_ofs, crc->rst_msk);
+
+	/* clear reset bit */
+	mtk_ddp_write_mask(&crc->cmdq_handle, 0, crc->cmdq_reg, 0,
+			   crc->rst_ofs, crc->rst_msk);
+
+	/* jump to head of the cmdq packet */
+	cmdq_pkt_jump(&crc->cmdq_handle, crc->cmdq_handle.pa_base);
+
+	return;
+cleanup:
+	mtk_drm_crc_destroy(crc);
+}
+
+void mtk_drm_crc_cmdq_start(struct mtk_drm_crc *crc)
+{
+	if (!crc->cmdq_client.chan)
+		return;
+
+	dma_sync_single_for_device(crc->cmdq_client.chan->mbox->dev,
+				   crc->cmdq_handle.pa_base,
+				   crc->cmdq_handle.cmd_buf_size,
+				   DMA_TO_DEVICE);
+	mbox_send_message(crc->cmdq_client.chan, &crc->cmdq_handle);
+	mbox_client_txdone(crc->cmdq_client.chan, 0);
+}
+
+void mtk_drm_crc_cmdq_stop(struct mtk_drm_crc *crc)
+{
+	if (!crc->cmdq_client.chan)
+		return;
+
+	mbox_flush(crc->cmdq_client.chan, 2000);
+}
+#endif
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index 3c224595fa714..0683ec4bc26f6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -15,6 +15,45 @@
 #define MTK_MAX_BPC	10
 #define MTK_MIN_BPC	3
 
+/**
+ * struct mtk_drm_crc - crc related information
+ * @ofs: register offset of crc
+ * @rst_ofs: register offset of crc reset
+ * @rst_msk: register mask of crc reset
+ * @cnt: count of crc
+ * @va: pointer to the start of crc array
+ * @pa: physical address of the crc for gce to access
+ * @cmdq_event: the event to trigger the cmdq
+ * @cmdq_reg: address of the register that cmdq is going to access
+ * @cmdq_client: handler to control cmdq (mbox channel, thread ...etc.)
+ * @cmdq_handle: cmdq packet to store the commands
+ */
+struct mtk_drm_crc {
+	const u32 *ofs;
+	u32 rst_ofs;
+	u32 rst_msk;
+	size_t cnt;
+	u32 *va;
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	dma_addr_t pa;
+	u32 cmdq_event;
+	struct cmdq_client_reg *cmdq_reg;
+	struct cmdq_client cmdq_client;
+	struct cmdq_pkt cmdq_handle;
+#endif
+};
+
+void mtk_drm_crc_init(struct mtk_drm_crc *crc,
+		      const u32 *crc_offset_table, size_t crc_count,
+		      u32 reset_offset, u32 reset_mask);
+void mtk_drm_crc_read(struct mtk_drm_crc *crc, void __iomem *reg);
+void mtk_drm_crc_destroy(struct mtk_drm_crc *crc);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+void mtk_drm_crc_cmdq_create(struct device *dev, struct mtk_drm_crc *crc);
+void mtk_drm_crc_cmdq_start(struct mtk_drm_crc *crc);
+void mtk_drm_crc_cmdq_stop(struct mtk_drm_crc *crc);
+#endif
+
 void mtk_drm_crtc_commit(struct drm_crtc *crtc);
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
 			const unsigned int *path,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 215b7234ff13c..231017470607e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -87,6 +87,9 @@ struct mtk_ddp_comp_funcs {
 	void (*remove)(struct device *dev, struct mtk_mutex *mutex);
 	unsigned int (*encoder_index)(struct device *dev);
 	enum drm_mode_status (*mode_valid)(struct device *dev, const struct drm_display_mode *mode);
+	size_t (*crc_cnt)(struct device *dev);
+	u32 *(*crc_entry)(struct device *dev);
+	void (*crc_read)(struct device *dev);
 };
 
 struct mtk_ddp_comp {
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:11 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:11 +0800
Subject: [PATCH v5 05/13] drm/mediatek: Set DRM mode configs accordingly
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-6-shawn.sung@mediatek.com>

Set DRM mode configs limitation according to the hardware capabilities
and pass the IGT checks as below:

- The test "graphics.IgtKms.kms_plane" requires a frame buffer with
  width of 4512 pixels (> 4096).
- The test "graphics.IgtKms.kms_cursor_crc" checks if the cursor size is
  defined, and run the test with cursor size from 1x1 to 512x512.

Please notice that the test conditions may change as IGT is updated.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 25 +++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |  3 +++
 2 files changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 890e1e93a2227..8cf157ec66ba6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -296,6 +296,9 @@ static const struct mtk_mmsys_driver_data mt8188_vdosys0_driver_data = {
 	.conn_routes = mt8188_mtk_ddp_main_routes,
 	.num_conn_routes = ARRAY_SIZE(mt8188_mtk_ddp_main_routes),
 	.mmsys_dev_num = 2,
+	.max_pitch = GENMASK(15, 0),
+	.min_width = 1,
+	.min_height = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
@@ -310,6 +313,9 @@ 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,
+	.max_pitch = GENMASK(15, 0),
+	.min_width = 1,
+	.min_height = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
@@ -317,6 +323,9 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
 	.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
 	.mmsys_id = 1,
 	.mmsys_dev_num = 2,
+	.max_pitch = GENMASK(15, 0),
+	.min_width = 2, /* 2-pixel align when ethdr is bypassed */
+	.min_height = 1,
 };
 
 static const struct of_device_id mtk_drm_of_ids[] = {
@@ -495,6 +504,18 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 		for (j = 0; j < private->data->mmsys_dev_num; j++) {
 			priv_n = private->all_drm_private[j];
 
+			if (priv_n->data->max_pitch) {
+				/* Save 4 bytes for the color depth (pitch = width * bpp) */
+				drm->mode_config.max_width  = priv_n->data->max_pitch >> 2;
+				drm->mode_config.max_height = priv_n->data->max_pitch >> 2;
+			}
+
+			if (priv_n->data->min_width)
+				drm->mode_config.min_width = priv_n->data->min_width;
+
+			if (priv_n->data->min_height)
+				drm->mode_config.min_height = priv_n->data->min_height;
+
 			if (i == CRTC_MAIN && priv_n->data->main_len) {
 				ret = mtk_drm_crtc_create(drm, priv_n->data->main_path,
 							  priv_n->data->main_len, j,
@@ -522,6 +543,10 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 		}
 	}
 
+	/* IGT will check if the cursor size is configured */
+	drm->mode_config.cursor_width = drm->mode_config.max_width;
+	drm->mode_config.cursor_height = drm->mode_config.max_height;
+
 	/* Use OVL device for all DMA memory allocations */
 	crtc = drm_crtc_from_index(drm, 0);
 	if (crtc)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 33fadb08dc1c7..414764b4546ba 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -46,6 +46,9 @@ struct mtk_mmsys_driver_data {
 	bool shadow_register;
 	unsigned int mmsys_id;
 	unsigned int mmsys_dev_num;
+
+	u32 max_pitch;
+	int min_width, min_height;
 };
 
 struct mtk_drm_private {
-- 
2.18.0



From shawn.sung at mediatek.com  Thu Feb 15 02:11:06 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:06 +0800
Subject: [PATCH v5 00/13] Support IGT in display driver
Message-ID: <20240215101119.12629-1-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

This series is based on 20240207021510.24035-2-shawn.sung at mediatek.com.

This series adds support for running IGT (Intel GPU Tool) tests
with MediaTek display driver. The following changes will be
applied:

1. Add a new API for creating GCE thread loop to retrieve CRCs
   from the hardware component
2. Support hardware CRC calculation in both VDOSYS0 and VDOSYS1
3. Support alpha blending in both VDOSYS0 and VDOSYS1

Changes in v5:
- Add more descriptions to the codes
- Add DRM mode configs to the driver data
- Squash and rearrange the commits

Changes in v4:
- Separate the patch into smaller ones
- Change the title of some patches
- Revert the changes that are not related to the series

Changes in v3:
- Modify the dt-binding document of Mediatek OVL
- Set DRM mode configs accroding to the hardware capabilities
- Replace cmdq_pkt_jump_absolute() with cmdq_pkt_jump()

Changes in v2:
- Simplify CMDQ by adding commands that are currently used only
- Integrate CRC related codes into new APIs for Mixer and OVL to reuse
- Add CPU version CRC retrieval when CMDQ is disabled

Hsiao Chien Sung (13):
  soc: mediatek: Disable 9-bit alpha in ETHDR
  drm/mediatek: Add OVL compatible name for MT8195
  drm/mediatek: Add missing plane settings when async update
  drm/mediatek: Fix errors when reporting rotation capability
  drm/mediatek: Set DRM mode configs accordingly
  drm/mediatek: Turn off the layers with zero width or height
  drm/mediatek: Support alpha blending in display driver
  drm/mediatek: Support alpha blending in OVL
  drm/mediatek: Support alpha blending in Mixer
  drm/mediatek: Support CRC in display driver
  drm/mediatek: Support CRC in OVL
  drm/mediatek: Support CRC in OVL adaptor
  drm/mediatek: Add comments for the structures

 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   7 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c       | 320 ++++++++++++++++--
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   |  32 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 261 +++++++++++++-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h       |  39 +++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |   7 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  35 ++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  27 ++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |  20 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c      |  15 +-
 drivers/gpu/drm/mediatek/mtk_ethdr.c          | 106 +++++-
 drivers/gpu/drm/mediatek/mtk_ethdr.h          |   5 +
 drivers/soc/mediatek/mtk-mmsys.c              |   1 +
 13 files changed, 828 insertions(+), 47 deletions(-)

--
2.18.0



From u.kleine-koenig at pengutronix.de  Thu Feb 15 02:12:30 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Thu, 15 Feb 2024 11:12:30 +0100
Subject: [PATCH] pwm: imx-tpm: reset module on probe
In-Reply-To: <3d866664-d2fd-4d36-9e8f-5242327e41b9@nxp.com>
References: <20240201122242.1597601-1-viorel.suman@oss.nxp.com>
 <vvldfzpthexjb7bir5imrdslgnnqztl2rdclfp6qiesj6hgiea@o53kcxs66mjr>
 <3d866664-d2fd-4d36-9e8f-5242327e41b9@nxp.com>
Message-ID: <zeieriiouilwf23g4v5wv7oetdee43qcm5lvxiygyxmxm7lgde@m3a2uain6g45>

Hello,

On Thu, Feb 01, 2024 at 06:25:26PM +0200, Viorel Suman wrote:
> On 2/1/24 15:38, Uwe Kleine-K?nig wrote:
> > > +	/* Resets all internal logic and registers */
> > > +	writel(PWM_IMX_TPM_GLOBAL_RST, tpm->base + PWM_IMX_TPM_GLOBAL);
> > > +	writel(0, tpm->base + PWM_IMX_TPM_GLOBAL);
> > > +
> > This opposes the use case that the bootloader setup the pwm-backlight to
> > show a splash screen that is simply taken over by Linux without
> > flickering, right?
> 
> Yes, I was not aware of such use case. Is it acceptable if I'll update
> 
> the patch in a such way so that the software reset happens as function
> 
> of a property in the related DTS node ?

That sounds wrong. Why do you reset at all? If at all, only reset if all
channels are disabled (if at all).

> > Otherwise the commit log should motivate why "the module takes the
> > default state" is better than the status quo and what this default state
> > is.
> 
> The default state above means IP internal logic being reset to the initial
> state and
> 
> registers values being set to their reset values. We're facing a situation
> on iMX95 when
> 
> A core may be reset independently from the rest of the SoC, this triggers a
> new
> 
> SPL->U-Boot->Linux boot, and in Linux probe phase PWM will inherit its state
> from
> 
> previous Linux runtime - this leads to some issues in suspend/resume
> functionality.

What kind of issues?

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/20240215/9190cfd6/attachment.sig>

From p.zabel at pengutronix.de  Thu Feb 15 02:19:14 2024
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Thu, 15 Feb 2024 11:19:14 +0100
Subject: [PATCH 19/23] gpio: nomadik: grab optional reset control and
 deassert it at probe
In-Reply-To: <20240214-mbly-gpio-v1-19-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
	 <20240214-mbly-gpio-v1-19-f88c0ccf372b@bootlin.com>
Message-ID: <d51dbac55d3677031bfab8bfe959f7b556b1c373.camel@pengutronix.de>

On Mi, 2024-02-14 at 17:24 +0100, Th?o Lebrun wrote:
> Fetch a reference to the optional shared reset control and deassert it
> if it exists.
> 
> Optional because not all platforms that use this driver have a reset
> attached to the reset block. Shared because some platforms that use the
> reset (at least Mobileye EyeQ5) share the reset across banks.
> 
> Do not keep a reference to the reset control as it is not needed
> afterwards; the driver does not handle suspend, does not use runtime PM
> and does not register a remove callback.

I suppose you don't care that the reset is only ever deasserted once
and never asserted again on this hardware, but for shared reset
controls the expectation is that deassert/assert calls are balanced:

https://docs.kernel.org/driver-api/reset.html?highlight=balanced#assertion-and-deassertion

So maybe this warrants a comment in the code. Or do you mean to
suppress unbind via suppress_bind_attrs to explain away any missing
cleanup?

> The operation is done in nmk_gpio_populate_chip(). This function is
> called by either gpio-nomadik or pinctrl-nomadik, whoever comes first.
> This is here for historic reasons and could probably be removed now; it
> seems gpio-ranges enforces the ordering to be pinctrl-first. It is not
> the topic of the present patch however.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  drivers/gpio/gpio-nomadik.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
> index 21bb6d6363fc..b623c093b54d 100644
> --- a/drivers/gpio/gpio-nomadik.c
> +++ b/drivers/gpio/gpio-nomadik.c
> @@ -513,12 +513,14 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
>  {
>  	struct nmk_gpio_chip *nmk_chip;
>  	struct platform_device *gpio_pdev;
> +	struct reset_control *reset;
>  	struct gpio_chip *chip;
>  	struct resource *res;
>  	struct clk *clk;
>  	void __iomem *base;
>  	uintptr_t flags;
>  	u32 id, ngpio;
> +	int ret;
>  
>  	gpio_pdev = of_find_device_by_node(np);
>  	if (!gpio_pdev) {
> @@ -576,6 +578,19 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
>  	clk_prepare(clk);
>  	nmk_chip->clk = clk;
>  
> +	reset = devm_reset_control_get_optional_shared(&gpio_pdev->dev, NULL);
> +	if (IS_ERR(reset)) {
> +		dev_err(&pdev->dev, "failed getting reset control: %ld\n",
> +			PTR_ERR(reset));
> +		return ERR_CAST(reset);

Consider using dev_err_probe() here.

regards
Philipp


From shawn.sung at mediatek.com  Thu Feb 15 02:11:18 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:18 +0800
Subject: [PATCH v5 12/13] drm/mediatek: Support CRC in OVL adaptor
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-13-shawn.sung@mediatek.com>

We choose Mixer as CRC generator in OVL adaptor since
its frame done event will trigger vblanks, we can know
when is safe to retrieve CRC of the frame.

In OVL adaptor, there's no image procession after Mixer,
unlike the OVL in VDOSYS0, Mixer's CRC will include all
the effects that are applied to the frame.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  3 +
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 21 +++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  3 +
 drivers/gpu/drm/mediatek/mtk_ethdr.c          | 62 +++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_ethdr.h          |  5 ++
 5 files changed, 94 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 7ef8dbb07c2db..7ff4a5f8d7926 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -138,6 +138,9 @@ const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
 size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
 enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
 						const struct drm_display_mode *mode);
+size_t mtk_ovl_adaptor_crc_cnt(struct device *dev);
+u32 *mtk_ovl_adaptor_crc_entry(struct device *dev);
+void mtk_ovl_adaptor_crc_read(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index 68a20312ac6f1..61a8cf9b686ab 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -206,6 +206,27 @@ void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
 	mtk_ethdr_layer_config(ethdr, idx, state, cmdq_pkt);
 }
 
+size_t mtk_ovl_adaptor_crc_cnt(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	return mtk_ethdr_crc_cnt(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
+u32 *mtk_ovl_adaptor_crc_entry(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	return mtk_ethdr_crc_entry(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
+void mtk_ovl_adaptor_crc_read(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	mtk_ethdr_crc_read(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
 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)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index ea04b2769ae8b..43368eb342e2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -404,6 +404,9 @@ 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,
+	.crc_cnt = mtk_ovl_adaptor_crc_cnt,
+	.crc_entry = mtk_ovl_adaptor_crc_entry,
+	.crc_read = mtk_ovl_adaptor_crc_read,
 	.start = mtk_ovl_adaptor_start,
 	.stop = mtk_ovl_adaptor_stop,
 	.layer_nr = mtk_ovl_adaptor_layer_nr,
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index e95331c068151..30eb2c3d95c0b 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -24,6 +24,9 @@
 #define MIX_FME_CPL_INTEN			BIT(1)
 #define MIX_INTSTA			0x8
 #define MIX_EN				0xc
+#define MIX_TRIG			0x10
+#define MIX_TRIG_CRC_EN				BIT(8)
+#define MIX_TRIG_CRC_RST			BIT(9)
 #define MIX_RST				0x14
 #define MIX_ROI_SIZE			0x18
 #define MIX_DATAPATH_CON		0x1c
@@ -39,6 +42,11 @@
 #define PREMULTI_SOURCE				(3 << 12)
 #define MIX_L_SRC_SIZE(n)		(0x30 + 0x18 * (n))
 #define MIX_L_SRC_OFFSET(n)		(0x34 + 0x18 * (n))
+
+/* CRC register offsets for odd and even lines */
+#define MIX_CRC_ODD			0x110
+#define MIX_CRC_EVEN			0x114
+
 #define MIX_FUNC_DCM0			0x120
 #define MIX_FUNC_DCM1			0x124
 #define MIX_FUNC_DCM_ENABLE			0xffffffff
@@ -82,6 +90,7 @@ struct mtk_ethdr {
 	void			*vblank_cb_data;
 	int			irq;
 	struct reset_control	*reset_ctl;
+	struct mtk_drm_crc	crc;
 };
 
 static const char * const ethdr_clk_str[] = {
@@ -100,6 +109,32 @@ static const char * const ethdr_clk_str[] = {
 	"vdo_be_async",
 };
 
+static const u32 ethdr_crc_ofs[] = {
+	MIX_CRC_ODD,
+	MIX_CRC_EVEN,
+};
+
+size_t mtk_ethdr_crc_cnt(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	return priv->crc.cnt;
+}
+
+u32 *mtk_ethdr_crc_entry(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	return priv->crc.va;
+}
+
+void mtk_ethdr_crc_read(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	mtk_drm_crc_read(&priv->crc, priv->ethdr_comp[ETHDR_MIXER].regs);
+}
+
 void mtk_ethdr_register_vblank_cb(struct device *dev,
 				  void (*vblank_cb)(void *),
 				  void *vblank_cb_data)
@@ -256,6 +291,13 @@ void mtk_ethdr_start(struct device *dev)
 	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
 
 	writel(1, mixer->regs + MIX_EN);
+
+	if (priv->crc.cnt) {
+		writel(MIX_TRIG_CRC_EN, mixer->regs + MIX_TRIG);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+		mtk_drm_crc_cmdq_start(&priv->crc);
+#endif
+	}
 }
 
 void mtk_ethdr_stop(struct device *dev)
@@ -263,6 +305,9 @@ 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];
 
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	mtk_drm_crc_cmdq_stop(&priv->crc);
+#endif
 	writel(0, mixer->regs + MIX_EN);
 	writel(1, mixer->regs + MIX_RST);
 	reset_control_reset(priv->reset_ctl);
@@ -317,6 +362,10 @@ static int mtk_ethdr_probe(struct platform_device *pdev)
 	if (!priv)
 		return -ENOMEM;
 
+	mtk_drm_crc_init(&priv->crc,
+			 ethdr_crc_ofs, ARRAY_SIZE(ethdr_crc_ofs),
+			 MIX_TRIG, MIX_TRIG_CRC_RST);
+
 	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);
@@ -325,6 +374,16 @@ static int mtk_ethdr_probe(struct platform_device *pdev)
 					      &priv->ethdr_comp[i].cmdq_base, i);
 		if (ret)
 			dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+
+		if (i == ETHDR_MIXER) {
+			if (of_property_read_u32_index(dev->of_node,
+						       "mediatek,gce-events", i,
+						       &priv->crc.cmdq_event)) {
+				dev_warn(dev, "failed to get gce-events for crc\n");
+			}
+			priv->crc.cmdq_reg = &priv->ethdr_comp[i].cmdq_base;
+			mtk_drm_crc_cmdq_create(dev, &priv->crc);
+		}
 #endif
 		dev_dbg(dev, "[DRM]regs:0x%p, node:%d\n", priv->ethdr_comp[i].regs, i);
 	}
@@ -365,6 +424,9 @@ static int mtk_ethdr_probe(struct platform_device *pdev)
 
 static int mtk_ethdr_remove(struct platform_device *pdev)
 {
+	struct mtk_ethdr *priv = dev_get_drvdata(&pdev->dev);
+
+	mtk_drm_crc_destroy(&priv->crc);
 	component_del(&pdev->dev, &mtk_ethdr_component_ops);
 	return 0;
 }
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.h b/drivers/gpu/drm/mediatek/mtk_ethdr.h
index 81af9edea3f74..d17d7256bd120 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.h
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.h
@@ -22,4 +22,9 @@ void mtk_ethdr_register_vblank_cb(struct device *dev,
 void mtk_ethdr_unregister_vblank_cb(struct device *dev);
 void mtk_ethdr_enable_vblank(struct device *dev);
 void mtk_ethdr_disable_vblank(struct device *dev);
+
+size_t mtk_ethdr_crc_cnt(struct device *dev);
+u32 *mtk_ethdr_crc_entry(struct device *dev);
+void mtk_ethdr_crc_read(struct device *dev);
+
 #endif
-- 
2.18.0



From schwab at suse.de  Thu Feb 15 02:28:27 2024
From: schwab at suse.de (Andreas Schwab)
Date: Thu, 15 Feb 2024 11:28:27 +0100
Subject: 6.7 regression: platform 4809c000.mmc: deferred probe pending
In-Reply-To: <20240215094640.GS52537@atomide.com> (Tony Lindgren's message of
	"Thu, 15 Feb 2024 11:46:40 +0200")
References: <mvmcyt13idm.fsf@suse.de>
	<c92385d2-1909-43a8-aea8-cd9a8687a898@leemhuis.info>
	<20240215094640.GS52537@atomide.com>
Message-ID: <mvmeddeyqb8.fsf@suse.de>

On Feb 15 2024, Tony Lindgren wrote:

> There was a regression recently with the PMIC which would cause NFSroot
> on devices to keep working but may have affected MMC. Please check that
> commit 7a29fa05aeca ("mfd: twl6030-irq: Revert to use of_match_device()")
> is applied.

That commit hasn't hit stable yet.  Maybe it's because it references a
non-existant commit id (1e0c866887f4 instead of 830fafce06e6).

-- 
Andreas Schwab, SUSE Labs, schwab at suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


From angelogioacchino.delregno at collabora.com  Thu Feb 15 02:29:42 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 11:29:42 +0100
Subject: [PATCH 6/9] media: platform: mtk-mdp3: drop calling
 cmdq_pkt_finalize()
In-Reply-To: <20240215004931.3808-7-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
 <20240215004931.3808-7-chunkuang.hu@kernel.org>
Message-ID: <4dcfaf49-aaac-4980-a149-02fec3109f31@collabora.com>

Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> Because client driver has the information of struct cmdq_client, so
> it's not necessary to store struct cmdq_client in struct cmdq_pkt.
> cmdq_pkt_finalize() use struct cmdq_client in struct cmdq_pkt, so it's
> going to be abandoned. Therefore, use cmdq_pkt_eoc() and cmdq_pkt_nop()
> to replace cmdq_pkt_finalize().

No, it's not because cmdq_pkt_finalize() has cmdq_client, but because we want
finer grain control over the CMDQ packets, as not all cases require the NOP
packet to be appended after EOC.

Besides, honestly I'm not even sure if the NOP is always required in MDP3, so...

...Moudy, you know the MDP3 way better than anyone else - can you please
check if NOP is actually needed here?

Thanks!
Angelo

> 
> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> ---
>   drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 3 ++-
>   drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c | 2 ++
>   drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h | 1 +
>   3 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
> index 6adac857a477..a420d492d879 100644
> --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
> +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
> @@ -471,7 +471,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
>   		dev_err(dev, "mdp_path_config error\n");
>   		goto err_free_path;
>   	}
> -	cmdq_pkt_finalize(&cmd->pkt);
> +	cmdq_pkt_eoc(&cmd->pkt);
> +	cmdq_pkt_nop(&cmd->pkt, mdp->cmdq_shift_pa);
>   
>   	for (i = 0; i < num_comp; i++)
>   		memcpy(&comps[i], path->comps[i].comp,
> diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
> index 94f4ed78523b..2214744c937c 100644
> --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
> +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
> @@ -231,6 +231,8 @@ static int mdp_probe(struct platform_device *pdev)
>   		goto err_put_scp;
>   	}
>   
> +	mdp->cmdq_shift_pa = cmdq_get_shift_pa(mdp->cmdq_clt->chan);
> +
>   	init_waitqueue_head(&mdp->callback_wq);
>   	ida_init(&mdp->mdp_ida);
>   	platform_set_drvdata(pdev, mdp);
> diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
> index 7e21d226ceb8..ed61e0bb69ee 100644
> --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
> +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
> @@ -83,6 +83,7 @@ struct mdp_dev {
>   	u32					id_count;
>   	struct ida				mdp_ida;
>   	struct cmdq_client			*cmdq_clt;
> +	u8					cmdq_shift_pa;
>   	wait_queue_head_t			callback_wq;
>   
>   	struct v4l2_device			v4l2_dev;



From danishanwar at ti.com  Thu Feb 15 02:30:34 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Thu, 15 Feb 2024 16:00:34 +0530
Subject: [PATCH v5 1/3] arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
In-Reply-To: <20240215103036.2825096-1-danishanwar@ti.com>
References: <20240215103036.2825096-1-danishanwar@ti.com>
Message-ID: <20240215103036.2825096-2-danishanwar@ti.com>

From: Suman Anna <s-anna at ti.com>

The ICSSG IP on AM64x SoCs have two Industrial Ethernet Peripherals (IEPs)
to manage/generate Industrial Ethernet functions such as time stamping.
Each IEP sub-module is sourced from an internal clock mux that can be
derived from either of the IP instance's ICSSG_IEP_GCLK or from another
internal ICSSG CORE_CLK mux. Add both the IEP nodes for both the ICSSG
instances. The IEP clock is currently configured to be derived
indirectly from the ICSSG_ICLK running at 250 MHz.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
Signed-off-by: Suman Anna <s-anna at ti.com>
Reviewed-by: Ravi Gunasekaran <r-gunasekaran at ti.com>
Reviewed-by: Roger Quadros <rogerq at kernel.org>
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index ddd382a0d735..c678366623b7 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -1225,6 +1225,18 @@ icssg0_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg0_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
+		icssg0_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
 		icssg0_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
@@ -1366,6 +1378,18 @@ icssg1_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg1_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
+		icssg1_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
 		icssg1_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
-- 
2.34.1



From danishanwar at ti.com  Thu Feb 15 02:30:33 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Thu, 15 Feb 2024 16:00:33 +0530
Subject: [PATCH v5 0/3] Add AM64x ICSSG Ethernet support
Message-ID: <20240215103036.2825096-1-danishanwar@ti.com>

Hi All,

This series adds support for ICSSG ethernet on AM64x. 
This series is based on the latest next-20240214 linux-next.

AM64x EVM has three ethernet ports. One is dedicated to CPSW and one is
dedicated to ICSSG1. The remaining port is muxed between CPSW and ICSSG1
ICSSG1 ports. The ICSSG1 node is added in the k3-am642-evm.dts. By default
the muxed port is used by CPSW so 2nd ICSSG1 port is disabled in the
k3-am642-evm.dts. But overlay k3-am642-evm-icssg1-dualemac.dtso can be
applied to use muxed port as ICSSG1.

This is the v5 of the series [v1].

Changes from v4 to v5:
*) Added Roger's RB tag in patch 1/3 and 3/3
*) Modified commit message of patch 3/3
*) Dropped ti,syscon-rgmii-delay property from patch 2/3 as it is no
   longer needed.
*) Reverted the renaming of mdio-mux nodes back to 'mdio-mux-1' and
   'mdio-mux-2' from 'mdio-mux at 1' and 'mdio-mux at 0' as the later was
   throwing DTBS_CHECK warnings.

Changes from v3 to v4:
*) Dropped ethernet3 alias from k3-am642-evm.dts as suggested by Roger.
*) Dropped extra blank lines from k3-am642-evm.dts.
*) Updated commit message of patch 3/3
*) Updated licensing header in k3-am642-evm-icssg1-dualemac.dtso.
*) Fixed up alias for ethernet1 to icssg1_emac1 in
   k3-am642-evm-icssg1-dualemac.dtso as suggested by Roger.
*) Renamed 'mdio-mux-1' and 'mdio-mux-2' to 'mdio-mux at 1' and 'mdio-mux at 0'
   respectively as suggested by Roger.

Changes from v2 to v3:
*) No functional changes.
*) Rebased on latest linux-next (next-20240122) after 6.8-rc1.

Changes from v1 to v2:
*) Fixed aliases section in k3-am642-evm.dts
*) Fixed firmware-names in k3-am642-evm.dts
*) Changed icssg1_phy1 to ethernet-phy at f from ethernet-phy at 0 as suggested
   by Andrew L.
*) Changed makefile to handle overlays using CONFIG_OF_ALL_DTBS as
   suggested by Nishant and Andrew Davis.
*) Fixed aliases section in k3-am642-evm-icssg1-dualemac.dtso
*) Fixed pinctrl in k3-am642-evm-icssg1-dualemac.dtso
*) Updated commit message of patch 3/3 of the series to warn about adding
   label name to 'mdio-mux-1' node.

[v1] https://lore.kernel.org/all/20231207081917.340167-1-danishanwar at ti.com/
[v2] https://lore.kernel.org/all/20231212165832.3933335-1-danishanwar at ti.com/
[v3] https://lore.kernel.org/all/20240122113045.1711818-1-danishanwar at ti.com/
[v4] https://lore.kernel.org/all/20240205090546.4000446-1-danishanwar at ti.com/

Thanks and Regards,
MD Danish Anwar

MD Danish Anwar (2):
  arm64: dts: ti: k3-am642-evm: add ICSSG1 Ethernet support
  arm64: dts: ti: k3-am642-evm: add overlay for ICSSG1 2nd port

Suman Anna (1):
  arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes

 arch/arm64/boot/dts/ti/Makefile               |  5 +
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi      | 24 +++++
 .../dts/ti/k3-am642-evm-icssg1-dualemac.dtso  | 79 +++++++++++++++
 arch/arm64/boot/dts/ti/k3-am642-evm.dts       | 97 ++++++++++++++++++-
 4 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso

base-commit: 2c3b09aac00d7835023bbc4473ee06696be64fa8
-- 
2.34.1



From danishanwar at ti.com  Thu Feb 15 02:30:36 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Thu, 15 Feb 2024 16:00:36 +0530
Subject: [PATCH v5 3/3] arm64: dts: ti: k3-am642-evm: add overlay for ICSSG1 2nd port
In-Reply-To: <20240215103036.2825096-1-danishanwar@ti.com>
References: <20240215103036.2825096-1-danishanwar@ti.com>
Message-ID: <20240215103036.2825096-4-danishanwar@ti.com>

The am642-evm doesn't allow to enable 2 x CPSW3g ports and 2 x ICSSG1 ports
all together, so base k3-am642-evm.dts enables by default 2 x CPSW3g ports
and 1 x ICSSG1 ports, but it is also possible to support 1 x CPSW3g ports
and 2 x ICSSG1 ports configuration.

This patch adds overlay to support 1 x CPSW3g ports and 2 x ICSSG1 ports
configuration:
- Add label name 'mdio_mux_1' for 'mdio-mux-1' node so that the node
  'mdio-mux-1' can be disabled in the overlay using the label name.
- disable 2nd CPSW3g port
- update CPSW3g pinmuxes to not use RGMII2
- disable mdio-mux-1 and define mdio-mux-2 to route ICSSG1 MDIO to the
  shared DP83869 PHY
- add and enable ICSSG1 RGMII2 pinmuxes
- enable ICSSG1 MII1 port

Reviewed-by: Ravi Gunasekaran <r-gunasekaran at ti.com>
Reviewed-by: Roger Quadros <rogerq at kernel.org>
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 arch/arm64/boot/dts/ti/Makefile               |  5 ++
 .../dts/ti/k3-am642-evm-icssg1-dualemac.dtso  | 79 +++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am642-evm.dts       |  2 +-
 3 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 4a570dffb638..2d255f31b3a6 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am642-evm-icssg1-dualemac.dtbo
 
 # Boards with AM65x SoC
 k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
@@ -106,6 +107,8 @@ k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
 	k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
+k3-am642-evm-icssg1-dualemac-dtbs := \
+	k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
 k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
 	k3-j721e-evm-pcie0-ep.dtbo
 k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
@@ -122,6 +125,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am62a7-sk-hdmi-audio.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
+	k3-am642-evm-icssg1-dualemac.dtb \
 	k3-j721e-evm-pcie0-ep.dtb \
 	k3-j721s2-evm-pcie1-ep.dtb
 
@@ -131,6 +135,7 @@ DTC_FLAGS_k3-am625-sk += -@
 DTC_FLAGS_k3-am62-lp-sk += -@
 DTC_FLAGS_k3-am62a7-sk += -@
 DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
+DTC_FLAGS_k3-am642-evm += -@
 DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
 DTC_FLAGS_k3-j721e-common-proc-board += -@
 DTC_FLAGS_k3-j721s2-common-proc-board += -@
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
new file mode 100644
index 000000000000..af2fd3e7448b
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT overlay for enabling 2nd ICSSG1 port on AM642 EVM
+ *
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	aliases {
+		ethernet1 = "/icssg1-eth/ethernet-ports/port at 1";
+	};
+
+	mdio-mux-2 {
+		compatible = "mdio-mux-multiplexer";
+		mux-controls = <&mdio_mux>;
+		mdio-parent-bus = <&icssg1_mdio>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		mdio at 0 {
+			reg = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			icssg1_phy2: ethernet-phy at 3 {
+				reg = <3>;
+				tx-internal-delay-ps = <250>;
+				rx-internal-delay-ps = <2000>;
+			};
+		};
+	};
+};
+
+&main_pmx0 {
+	icssg1_rgmii2_pins_default: icssg1-rgmii2-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0108, PIN_INPUT, 2) /* (W11) PRG1_PRU1_GPO0.RGMII2_RD0 */
+			AM64X_IOPAD(0x010c, PIN_INPUT, 2) /* (V11) PRG1_PRU1_GPO1.RGMII2_RD1 */
+			AM64X_IOPAD(0x0110, PIN_INPUT, 2) /* (AA12) PRG1_PRU1_GPO2.RGMII2_RD2 */
+			AM64X_IOPAD(0x0114, PIN_INPUT, 2) /* (Y12) PRG1_PRU1_GPO3.RGMII2_RD3 */
+			AM64X_IOPAD(0x0120, PIN_INPUT, 2) /* (U11) PRG1_PRU1_GPO6.RGMII2_RXC */
+			AM64X_IOPAD(0x0118, PIN_INPUT, 2) /* (W12) PRG1_PRU1_GPO4.RGMII2_RX_CTL */
+			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2) /* (AA10) PRG1_PRU1_GPO11.RGMII2_TD0 */
+			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2) /* (V10) PRG1_PRU1_GPO12.RGMII2_TD1 */
+			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2) /* (U10) PRG1_PRU1_GPO13.RGMII2_TD2 */
+			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2) /* (AA11) PRG1_PRU1_GPO14.RGMII2_TD3 */
+			AM64X_IOPAD(0x0148, PIN_OUTPUT, 2) /* (Y10) PRG1_PRU1_GPO16.RGMII2_TXC */
+			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2) /* (Y11) PRG1_PRU1_GPO15.RGMII2_TX_CTL */
+		>;
+	};
+};
+
+&cpsw3g {
+	pinctrl-0 = <&rgmii1_pins_default>;
+};
+
+&cpsw_port2 {
+	status = "disabled";
+};
+
+&mdio_mux_1 {
+	status = "disabled";
+};
+
+&icssg1_eth {
+	pinctrl-0 = <&icssg1_rgmii1_pins_default>, <&icssg1_rgmii2_pins_default>;
+};
+
+&icssg1_emac1 {
+	status = "okay";
+	phy-handle = <&icssg1_phy2>;
+	phy-mode = "rgmii-id";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index daa925106856..03dac3adebde 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -199,7 +199,7 @@ mdio_mux: mux-controller {
 		mux-gpios = <&exp1 12 GPIO_ACTIVE_HIGH>;
 	};
 
-	mdio-mux-1 {
+	mdio_mux_1: mdio-mux-1 {
 		compatible = "mdio-mux-multiplexer";
 		mux-controls = <&mdio_mux>;
 		mdio-parent-bus = <&cpsw3g_mdio>;
-- 
2.34.1



From danishanwar at ti.com  Thu Feb 15 02:30:35 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Thu, 15 Feb 2024 16:00:35 +0530
Subject: [PATCH v5 2/3] arm64: dts: ti: k3-am642-evm: add ICSSG1 Ethernet support
In-Reply-To: <20240215103036.2825096-1-danishanwar@ti.com>
References: <20240215103036.2825096-1-danishanwar@ti.com>
Message-ID: <20240215103036.2825096-3-danishanwar@ti.com>

ICSSG1 provides dual Gigabit Ethernet support with proper FW loaded.

The ICSSG1 MII0 (RGMII1) has DP83869 PHY attached to it. The ICSSG1 shares
MII1 (RGMII2) PHY DP83869 with CPSW3g and it's assigned by default to
CPSW3g. The MDIO access to MII1 (RGMII2) PHY DP83869 is controlled by MDIO
bus switch and also assigned to CPSW3g. Therefore the ICSSG1 MII1 (RGMII2)
port is kept disable and ICSSG1 is enabled in single MAC mode by
default.

Reviewed-by: Ravi Gunasekaran <r-gunasekaran at ti.com>
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am642-evm.dts | 95 +++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 5c546ae76d3e..daa925106856 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -32,6 +32,7 @@ aliases {
 		mmc1 = &sdhci1;
 		ethernet0 = &cpsw_port1;
 		ethernet1 = &cpsw_port2;
+		ethernet2 = &icssg1_emac0;
 	};
 
 	memory at 80000000 {
@@ -229,6 +230,64 @@ transceiver2: can-phy1 {
 		max-bitrate = <5000000>;
 		standby-gpios = <&exp1 9 GPIO_ACTIVE_HIGH>;
 	};
+
+	icssg1_eth: icssg1-eth {
+		compatible = "ti,am642-icssg-prueth";
+		pinctrl-names = "default";
+		pinctrl-0 = <&icssg1_rgmii1_pins_default>;
+		sram = <&oc_sram>;
+		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
+		firmware-name = "ti-pruss/am64x-sr2-pru0-prueth-fw.elf",
+				"ti-pruss/am64x-sr2-rtu0-prueth-fw.elf",
+				"ti-pruss/am64x-sr2-txpru0-prueth-fw.elf",
+				"ti-pruss/am64x-sr2-pru1-prueth-fw.elf",
+				"ti-pruss/am64x-sr2-rtu1-prueth-fw.elf",
+				"ti-pruss/am64x-sr2-txpru1-prueth-fw.elf";
+
+		ti,pruss-gp-mux-sel = <2>,	/* MII mode */
+				      <2>,
+				      <2>,
+				      <2>,	/* MII mode */
+				      <2>,
+				      <2>;
+		ti,mii-g-rt = <&icssg1_mii_g_rt>;
+		ti,mii-rt = <&icssg1_mii_rt>;
+		ti,iep = <&icssg1_iep0>,  <&icssg1_iep1>;
+		interrupt-parent = <&icssg1_intc>;
+		interrupts = <24 0 2>, <25 1 3>;
+		interrupt-names = "tx_ts0", "tx_ts1";
+		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
+		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
+		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
+		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+			    "rx0", "rx1";
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			icssg1_emac0: port at 0 {
+				reg = <0>;
+				phy-handle = <&icssg1_phy1>;
+				phy-mode = "rgmii-id";
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+			};
+			icssg1_emac1: port at 1 {
+				reg = <1>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				status = "disabled";
+			};
+		};
+	};
 };
 
 &main_pmx0 {
@@ -383,6 +442,30 @@ ddr_vtt_pins_default: ddr-vtt-default-pins {
 			AM64X_IOPAD(0x0030, PIN_OUTPUT_PULLUP, 7) /* (L18) OSPI0_CSN1.GPIO0_12 */
 		>;
 	};
+
+	icssg1_mdio1_pins_default: icssg1-mdio1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0) /* (Y6) PRG1_MDIO0_MDC */
+			AM64X_IOPAD(0x0158, PIN_INPUT, 0) /* (AA6) PRG1_MDIO0_MDIO */
+		>;
+	};
+
+	icssg1_rgmii1_pins_default: icssg1-rgmii1-default-pins{
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x00b8, PIN_INPUT, 2) /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
+			AM64X_IOPAD(0x00bc, PIN_INPUT, 2) /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
+			AM64X_IOPAD(0x00c0, PIN_INPUT, 2) /* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
+			AM64X_IOPAD(0x00c4, PIN_INPUT, 2) /* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
+			AM64X_IOPAD(0x00d0, PIN_INPUT, 2) /* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
+			AM64X_IOPAD(0x00c8, PIN_INPUT, 2) /* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
+			AM64X_IOPAD(0x00e4, PIN_INPUT, 2) /* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
+			AM64X_IOPAD(0x00e8, PIN_INPUT, 2) /* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
+			AM64X_IOPAD(0x00ec, PIN_INPUT, 2) /* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
+			AM64X_IOPAD(0x00f0, PIN_INPUT, 2) /* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
+			AM64X_IOPAD(0x00f8, PIN_INPUT, 2) /* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
+			AM64X_IOPAD(0x00f4, PIN_INPUT, 2) /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
+		>;
+	};
 };
 
 &main_uart0 {
@@ -725,3 +808,15 @@ &main_mcan1 {
 	pinctrl-0 = <&main_mcan1_pins_default>;
 	phys = <&transceiver2>;
 };
+
+&icssg1_mdio {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&icssg1_mdio1_pins_default>;
+
+	icssg1_phy1: ethernet-phy at f {
+		reg = <0xf>;
+		tx-internal-delay-ps = <250>;
+		rx-internal-delay-ps = <2000>;
+	};
+};
-- 
2.34.1



From shawn.sung at mediatek.com  Thu Feb 15 02:11:12 2024
From: shawn.sung at mediatek.com (Hsiao Chien Sung)
Date: Thu, 15 Feb 2024 18:11:12 +0800
Subject: [PATCH v5 06/13] drm/mediatek: Turn off the layers with zero width or height
In-Reply-To: <20240215101119.12629-1-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
Message-ID: <20240215101119.12629-7-shawn.sung@mediatek.com>

We found that IGT (Intel GPU Tool) will try to commit layers with
zero width or height and lead to undefined behaviors in hardware.
Disable the layers in such a situation.

Fixes: 777b7bc86a0a3 ("drm/mediatek: Add ovl_adaptor support for MT8195")
Fixes: fa97fe71f6f93 ("drm/mediatek: Add ETHDR support for MT8195")

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 2 +-
 drivers/gpu/drm/mediatek/mtk_ethdr.c            | 7 ++++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index d4a13a1402148..68a20312ac6f1 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -157,7 +157,7 @@ void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
 	merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx];
 	ethdr = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0];
 
-	if (!pending->enable) {
+	if (!pending->enable || !pending->width || !pending->height) {
 		mtk_merge_stop_cmdq(merge, cmdq_pkt);
 		mtk_mdp_rdma_stop(rdma_l, cmdq_pkt);
 		mtk_mdp_rdma_stop(rdma_r, cmdq_pkt);
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index 73dc4da3ba3bd..69872b77922eb 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -160,7 +160,12 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
 	if (idx >= 4)
 		return;
 
-	if (!pending->enable) {
+	if (!pending->enable || !pending->width || !pending->height) {
+		/*
+		 * instead of disabling layer with MIX_SRC_CON directly
+		 * set the size to 0 to avoid screen shift due to mixer
+		 * mode switch (hardware behavior)
+		 */
 		mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx));
 		return;
 	}
-- 
2.18.0



From jens.wiklander at linaro.org  Thu Feb 15 02:32:07 2024
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 15 Feb 2024 11:32:07 +0100
Subject: [PATCH 2/3] tee: tstee: Add Trusted Services TEE driver
In-Reply-To: <ed8aaee7-be14-43ab-981c-d2ac04f4fc71@kernel.org>
References: <20240213145239.379875-1-balint.dobszay@arm.com>
 <20240213145239.379875-3-balint.dobszay@arm.com> <ed8aaee7-be14-43ab-981c-d2ac04f4fc71@kernel.org>
Message-ID: <CAHUa44FUmXMCLvJEB8v2_H4j+yNzR+YMU0xSO6uaaqF0BHj_2Q@mail.gmail.com>

On Thu, Feb 15, 2024 at 9:59?AM Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On 13/02/2024 15:52, Balint Dobszay wrote:
> > The Trusted Services project provides a framework for developing and
> > deploying device Root of Trust services in FF-A Secure Partitions. The
> > FF-A SPs are accessible through the FF-A driver, but this doesn't
> > provide a user space interface. The goal of this TEE driver is to make
> > Trusted Services SPs accessible for user space clients.
> >
> > All TS SPs have the same FF-A UUID, it identifies the RPC protocol used
> > by TS. A TS SP can host one or more services, a service is identified by
> > its service UUID. The same type of service cannot be present twice in
> > the same SP. During SP boot each service in an SP is assigned an
> > interface ID, this is just a short ID to simplify message addressing.
> > There is 1:1 mapping between TS SPs and TEE devices, i.e. a separate TEE
> > device is registered for each TS SP. This is required since contrary to
> > the generic TEE design where memory is shared with the whole TEE
> > implementation, in case of FF-A, memory is shared with a specific SP. A
> > user space client has to be able to separately share memory with each SP
> > based on its endpoint ID.
> >
> > Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
> > ---
>
>
> > +static int tstee_probe(struct ffa_device *ffa_dev)
> > +{
> > +     struct tstee *tstee;
> > +     int rc;
> > +
> > +     ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev);
> > +
> > +     if (!tstee_check_rpc_compatible(ffa_dev))
> > +             return -EINVAL;
> > +
> > +     tstee = kzalloc(sizeof(*tstee), GFP_KERNEL);
> > +     if (!tstee)
> > +             return -ENOMEM;
> > +
> > +     tstee->ffa_dev = ffa_dev;
> > +
> > +     tstee->pool = tstee_create_shm_pool();
> > +     if (IS_ERR(tstee->pool)) {
> > +             rc = PTR_ERR(tstee->pool);
> > +             tstee->pool = NULL;
> > +             goto err;
>
> Is it logically correct to call here tee_device_unregister()?

It is harmless since it ignores null pointers, but you have a point.
It doesn't make sense to call tee_device_unregister() before
tee_device_register() has been called.

Thanks,
Jens

>
> > +     }
> > +
> > +     tstee->teedev = tee_device_alloc(&tstee_desc, NULL, tstee->pool, tstee);
> > +     if (IS_ERR(tstee->teedev)) {
> > +             rc = PTR_ERR(tstee->teedev);
> > +             tstee->teedev = NULL;
> > +             goto err;
> > +     }
> > +
> > +     rc = tee_device_register(tstee->teedev);
> > +     if (rc)
> > +             goto err;
> > +
> > +     ffa_dev_set_drvdata(ffa_dev, tstee);
> > +
> > +     pr_info("driver initialized for endpoint 0x%x\n", ffa_dev->vm_id);
>
> Don't print simple probe success messages. Anyway all prints in device
> context should be dev_*.
>
> > +
> > +     return 0;
> > +
> > +err:
> > +     tstee_deinit_common(tstee);
> > +     return rc;
> > +}
> > +
> > +static void tstee_remove(struct ffa_device *ffa_dev)
> > +{
> > +     tstee_deinit_common(ffa_dev->dev.driver_data);
> > +}
> > +
> > +static const struct ffa_device_id tstee_device_ids[] = {
> > +     /* TS RPC protocol UUID: bdcd76d7-825e-4751-963b-86d4f84943ac */
> > +     { TS_RPC_UUID },
> > +     {}
> > +};
> > +
> > +static struct ffa_driver tstee_driver = {
> > +     .name = "arm_tstee",
> > +     .probe = tstee_probe,
> > +     .remove = tstee_remove,
> > +     .id_table = tstee_device_ids,
> > +};
> > +
> > +static int __init mod_init(void)
> > +{
> > +     return ffa_register(&tstee_driver);
> > +}
> > +module_init(mod_init)
> > +
> > +static void __exit mod_exit(void)
> > +{
> > +     ffa_unregister(&tstee_driver);
> > +}
> > +module_exit(mod_exit)
> > +
> > +MODULE_ALIAS("arm-tstee");
>
> Why do you need this alias? I don't see MODULE_DEVICE_TABLE, so how this
> bus handles module loading?
>
>
> Best regards,
> Krzysztof
>


From ryan.roberts at arm.com  Thu Feb 15 02:31:47 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:47 +0000
Subject: [PATCH v6 00/18] Transparent Contiguous PTEs for User Mappings
Message-ID: <20240215103205.2607016-1-ryan.roberts@arm.com>

Hi All,

This is a series to opportunistically and transparently use contpte mappings
(set the contiguous bit in ptes) for user memory when those mappings meet the
requirements. The change benefits arm64, but there is some (very) minor
refactoring for x86 to enable its integration with core-mm.

It is part of a wider effort to improve performance by allocating and mapping
variable-sized blocks of memory (folios). One aim is for the 4K kernel to
approach the performance of the 16K kernel, but without breaking compatibility
and without the associated increase in memory. Another aim is to benefit the 16K
and 64K kernels by enabling 2M THP, since this is the contpte size for those
kernels. We have good performance data that demonstrates both aims are being met
(see below).

Of course this is only one half of the change. We require the mapped physical
memory to be the correct size and alignment for this to actually be useful (i.e.
64K for 4K pages, or 2M for 16K/64K pages). Fortunately folios are solving this
problem for us. Filesystems that support it (XFS, AFS, EROFS, tmpfs, ...) will
allocate large folios up to the PMD size today, and more filesystems are coming.
And for anonymous memory, "multi-size THP" is now upstream.


Patch Layout
============

In this version, I've split the patches to better show each optimization:

  - 1-2:    mm prep: misc code and docs cleanups
  - 3-6:    mm,arm64,x86 prep: Add pte_advance_pfn() and make pte_next_pfn() a
            generic wrapper around it
  - 7-11:   arm64 prep: Refactor ptep helpers into new layer
  - 12:     functional contpte implementation
  - 23-18:  various optimizations on top of the contpte implementation


Testing
=======

I've tested this series on both Ampere Altra (bare metal) and Apple M2 (VM):
  - mm selftests (inc new tests written for multi-size THP); no regressions
  - Speedometer Java script benchmark in Chromium web browser; no issues
  - Kernel compilation; no issues
  - Various tests under high memory pressure with swap enabled; no issues


Performance
===========

High Level Use Cases
~~~~~~~~~~~~~~~~~~~~

First some high level use cases (kernel compilation and speedometer JavaScript
benchmarks). These are running on Ampere Altra (I've seen similar improvements
on Android/Pixel 6).

baseline:                  mm-unstable (mTHP switched off)
mTHP:                      + enable 16K, 32K, 64K mTHP sizes "always"
mTHP + contpte:            + this series
mTHP + contpte + exefolio: + patch at [6], which series supports

Kernel Compilation with -j8 (negative is faster):

| kernel                    | real-time | kern-time | user-time |
|---------------------------|-----------|-----------|-----------|
| baseline                  |      0.0% |      0.0% |      0.0% |
| mTHP                      |     -5.0% |    -39.1% |     -0.7% |
| mTHP + contpte            |     -6.0% |    -41.4% |     -1.5% |
| mTHP + contpte + exefolio |     -7.8% |    -43.1% |     -3.4% |

Kernel Compilation with -j80 (negative is faster):

| kernel                    | real-time | kern-time | user-time |
|---------------------------|-----------|-----------|-----------|
| baseline                  |      0.0% |      0.0% |      0.0% |
| mTHP                      |     -5.0% |    -36.6% |     -0.6% |
| mTHP + contpte            |     -6.1% |    -38.2% |     -1.6% |
| mTHP + contpte + exefolio |     -7.4% |    -39.2% |     -3.2% |

Speedometer (positive is faster):

| kernel                    | runs_per_min |
|:--------------------------|--------------|
| baseline                  |         0.0% |
| mTHP                      |         1.5% |
| mTHP + contpte            |         3.2% |
| mTHP + contpte + exefolio |         4.5% |


Micro Benchmarks
~~~~~~~~~~~~~~~~

The following microbenchmarks are intended to demonstrate the performance of
fork() and munmap() do not regress. I'm showing results for order-0 (4K)
mappings, and for order-9 (2M) PTE-mapped THP. Thanks to David for sharing his
benchmarks.

baseline:                  mm-unstable + batch zap [7] series
contpte-basic:             + patches 0-19; functional contpte implementation
contpte-batch:             + patches 20-23; implement new batched APIs
contpte-inline:            + patch 24; __always_inline to help compiler
contpte-fold:              + patch 25; fold contpte mapping when sensible

Primary platform is Ampere Altra bare metal. I'm also showing results for M2 VM
(on top of MacOS) for reference, although experience suggests this might not be
the most reliable for performance numbers of this sort:

| FORK           |         order-0        |         order-9        |
| Ampere Altra   |------------------------|------------------------|
| (pte-map)      |       mean |     stdev |       mean |     stdev |
|----------------|------------|-----------|------------|-----------|
| baseline       |       0.0% |      2.7% |       0.0% |      0.2% |
| contpte-basic  |       6.3% |      1.4% |    1948.7% |      0.2% |
| contpte-batch  |       7.6% |      2.0% |      -1.9% |      0.4% |
| contpte-inline |       3.6% |      1.5% |      -1.0% |      0.2% |
| contpte-fold   |       4.6% |      2.1% |      -1.8% |      0.2% |

| MUNMAP         |         order-0        |         order-9        |
| Ampere Altra   |------------------------|------------------------|
| (pte-map)      |       mean |     stdev |       mean |     stdev |
|----------------|------------|-----------|------------|-----------|
| baseline       |       0.0% |      0.5% |       0.0% |      0.3% |
| contpte-basic  |       1.8% |      0.3% |    1104.8% |      0.1% |
| contpte-batch  |      -0.3% |      0.4% |       2.7% |      0.1% |
| contpte-inline |      -0.1% |      0.6% |       0.9% |      0.1% |
| contpte-fold   |       0.1% |      0.6% |       0.8% |      0.1% |

| FORK           |         order-0        |         order-9        |
| Apple M2 VM    |------------------------|------------------------|
| (pte-map)      |       mean |     stdev |       mean |     stdev |
|----------------|------------|-----------|------------|-----------|
| baseline       |       0.0% |      1.4% |       0.0% |      0.8% |
| contpte-basic  |       6.8% |      1.2% |     469.4% |      1.4% |
| contpte-batch  |      -7.7% |      2.0% |      -8.9% |      0.7% |
| contpte-inline |      -6.0% |      2.1% |      -6.0% |      2.0% |
| contpte-fold   |       5.9% |      1.4% |      -6.4% |      1.4% |

| MUNMAP         |         order-0        |         order-9        |
| Apple M2 VM    |------------------------|------------------------|
| (pte-map)      |       mean |     stdev |       mean |     stdev |
|----------------|------------|-----------|------------|-----------|
| baseline       |       0.0% |      0.6% |       0.0% |      0.4% |
| contpte-basic  |       1.6% |      0.6% |     233.6% |      0.7% |
| contpte-batch  |       1.9% |      0.3% |      -3.9% |      0.4% |
| contpte-inline |       2.2% |      0.8% |      -1.6% |      0.9% |
| contpte-fold   |       1.5% |      0.7% |      -1.7% |      0.7% |

Misc
~~~~

John Hubbard at Nvidia has indicated dramatic 10x performance improvements for
some workloads at [8], when using 64K base page kernel.


---
This series applies on top of [7], which in turn applies on top of mm-unstable
(649936c3db47). A branch is available at [9].

I believe this is ready to go into mm-unstable as soon as [7] is in (which I
also believe to be ready). Catalin has said he is happy for this to go via the
mm-untable branch, once suitably acked by arm64 folks; Mark has reviewed v5 and
I've made all of his suggested minor changes - hopefully he is comfortable
acking the remaining patches now.

Note: the quoted perf numbers are against v5, but I've rerun a subset of the
tests against this version and results are consistent. Code changes are all
minor and are not expected to make any difference anyway.


Changes since v5 [5]
====================

  - Keep pte_next_pfn() as generic wrapper around pte_advance_pfn(). Allowed
    dropping arm and powerpc changes (per David)
  - Reshaped "Refactor ptep helpers into new layer" into 4 patches to better
    show the conversion process (no change to code diff) (per Mark)
  - Added comment to justify pte_mknoncont() at public API interface (per Mark)
  - Added check for efi_mm in mm_is_user() (per Mark)
  - Simplified a couple of pointer alignment statements (per Mark)
  - Added braces for if in contpte_try_unfold_partial() (per Mark)
  - Renamed some variables in __contpte_try_fold() (per Mark)
  - Fixed couple of comment typos (per Mark)
  - Enhanced docs for pte_batch_hint() (per David)
  - Minor tidy up in folio_pte_batch() (per David)
  - Picked up RBs/Acks (thanks to David, Mark, Ard)


Changes since v4 [4]
====================

  - Rebased onto David's generic fork and zap batching work
      - I had an implementation similar to this prior to v4, but ditched it
        because I couldn't make it reliably provide a speedup; David succeeded.
      - roughly speaking, a few functions get renamed compared to v4:
          - pte_batch_remaining() -> pte_batch_hint()
	  - set_wrprotects() -> wrprotect_ptes()
          - clear_ptes() -> [get_and_]clear_full_ptes()
      - Had to convert pte_next_pfn() to pte_advance_pfn()
      - Integration into core-mm is simpler because most has been done by
        David's work
  - Reworked patches to better show the progression from basic implementation to
    the various optimizations.
  - Removed the 'full' flag that I added to set_ptes() and set_wrprotects() in
    v4: I've been able to make up most of the performance in other ways, so this
    keeps the interface simpler.
  - Simplified contpte_set_ptes(nr > 1): Observed that set_ptes(nr > 1) is only
    called for ptes that are initially not present. So updated the spec to
    require that, and no longer need to check if any ptes are initially present
    when applying a contpte mapping.


Changes since v3 [3]
====================

  - Added v3#1 to batch set_ptes() when splitting a huge pmd to ptes; avoids
    need to fold contpte blocks for perf improvement
  - Separated the clear_ptes() fast path into its own inline function (Alistair)
  - Reworked core-mm changes to copy_present_ptes() and zap_pte_range() to
    remove overhead when memory is all order-0 folios (for arm64 and !arm64)
  - Significant optimization of arm64 backend fork operations (set_ptes_full()
    and set_wrprotects()) to ensure no regression when memory is order-0 folios.
  - fixed local variable declarations to be reverse xmas tree. - Added
    documentation for the new backend APIs (pte_batch_remaining(),
    set_ptes_full(), clear_ptes(), ptep_set_wrprotects())
  - Renamed tlb_get_guaranteed_space() -> tlb_reserve_space() and pass requested
    number of slots. Avoids allocating memory when not needed; perf improvement.


Changes since v2 [2]
====================

  - Removed contpte_ptep_get_and_clear_full() optimisation for exit() (v2#14),
    and replaced with a batch-clearing approach using a new arch helper,
    clear_ptes() (v3#2 and v3#15) (Alistair and Barry)
  - (v2#1 / v3#1)
      - Fixed folio refcounting so that refcount >= mapcount always (DavidH)
      - Reworked batch demarcation to avoid pte_pgprot() (DavidH)
      - Reverted return semantic of copy_present_page() and instead fix it up in
        copy_present_ptes() (Alistair)
      - Removed page_cont_mapped_vaddr() and replaced with simpler logic
        (Alistair)
      - Made batch accounting clearer in copy_pte_range() (Alistair)
  - (v2#12 / v3#13)
      - Renamed contpte_fold() -> contpte_convert() and hoisted setting/
        clearing CONT_PTE bit to higher level (Alistair)


Changes since v1 [1]
====================

  - Export contpte_* symbols so that modules can continue to call inline
    functions (e.g. ptep_get) which may now call the contpte_* functions (thanks
    to JohnH)
  - Use pte_valid() instead of pte_present() where sensible (thanks to Catalin)
  - Factor out (pte_valid() && pte_cont()) into new pte_valid_cont() helper
    (thanks to Catalin)
  - Fixed bug in contpte_ptep_set_access_flags() where TLBIs were missed (thanks
    to Catalin)
  - Added ARM64_CONTPTE expert Kconfig (enabled by default) (thanks to Anshuman)
  - Simplified contpte_ptep_get_and_clear_full()
  - Improved various code comments


[1] https://lore.kernel.org/linux-arm-kernel/20230622144210.2623299-1-ryan.roberts at arm.com/
[2] https://lore.kernel.org/linux-arm-kernel/20231115163018.1303287-1-ryan.roberts at arm.com/
[3] https://lore.kernel.org/linux-arm-kernel/20231204105440.61448-1-ryan.roberts at arm.com/
[4] https://lore.kernel.org/lkml/20231218105100.172635-1-ryan.roberts at arm.com/
[5] https://lore.kernel.org/linux-mm/633af0a7-0823-424f-b6ef-374d99483f05 at arm.com/
[6] https://lore.kernel.org/lkml/08c16f7d-f3b3-4f22-9acc-da943f647dc3 at arm.com/
[7] https://lore.kernel.org/linux-mm/20240214204435.167852-1-david at redhat.com/
[8] https://lore.kernel.org/linux-mm/c507308d-bdd4-5f9e-d4ff-e96e4520be85 at nvidia.com/
[9] https://gitlab.arm.com/linux-arm/linux-rr/-/tree/features/granule_perf/contpte-lkml_v6


Thanks,
Ryan

Ryan Roberts (18):
  mm: Clarify the spec for set_ptes()
  mm: thp: Batch-collapse PMD with set_ptes()
  mm: Introduce pte_advance_pfn() and use for pte_next_pfn()
  arm64/mm: Convert pte_next_pfn() to pte_advance_pfn()
  x86/mm: Convert pte_next_pfn() to pte_advance_pfn()
  mm: Tidy up pte_next_pfn() definition
  arm64/mm: Convert READ_ONCE(*ptep) to ptep_get(ptep)
  arm64/mm: Convert set_pte_at() to set_ptes(..., 1)
  arm64/mm: Convert ptep_clear() to ptep_get_and_clear()
  arm64/mm: New ptep layer to manage contig bit
  arm64/mm: Split __flush_tlb_range() to elide trailing DSB
  arm64/mm: Wire up PTE_CONT for user mappings
  arm64/mm: Implement new wrprotect_ptes() batch API
  arm64/mm: Implement new [get_and_]clear_full_ptes() batch APIs
  mm: Add pte_batch_hint() to reduce scanning in folio_pte_batch()
  arm64/mm: Implement pte_batch_hint()
  arm64/mm: __always_inline to improve fork() perf
  arm64/mm: Automatically fold contpte mappings

 arch/arm64/Kconfig                |   9 +
 arch/arm64/include/asm/pgtable.h  | 411 ++++++++++++++++++++++++++----
 arch/arm64/include/asm/tlbflush.h |  13 +-
 arch/arm64/kernel/efi.c           |   4 +-
 arch/arm64/kernel/mte.c           |   2 +-
 arch/arm64/kvm/guest.c            |   2 +-
 arch/arm64/mm/Makefile            |   1 +
 arch/arm64/mm/contpte.c           | 404 +++++++++++++++++++++++++++++
 arch/arm64/mm/fault.c             |  12 +-
 arch/arm64/mm/fixmap.c            |   4 +-
 arch/arm64/mm/hugetlbpage.c       |  40 +--
 arch/arm64/mm/kasan_init.c        |   6 +-
 arch/arm64/mm/mmu.c               |  16 +-
 arch/arm64/mm/pageattr.c          |   6 +-
 arch/arm64/mm/trans_pgd.c         |   6 +-
 arch/x86/include/asm/pgtable.h    |   8 +-
 include/linux/efi.h               |   5 +
 include/linux/pgtable.h           |  32 ++-
 mm/huge_memory.c                  |  58 +++--
 mm/memory.c                       |  19 +-
 20 files changed, 924 insertions(+), 134 deletions(-)
 create mode 100644 arch/arm64/mm/contpte.c

--
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:49 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:49 +0000
Subject: [PATCH v6 02/18] mm: thp: Batch-collapse PMD with set_ptes()
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-3-ryan.roberts@arm.com>

Refactor __split_huge_pmd_locked() so that a present PMD can be
collapsed to PTEs in a single batch using set_ptes().

This should improve performance a little bit, but the real motivation is
to remove the need for the arm64 backend to have to fold the contpte
entries. Instead, since the ptes are set as a batch, the contpte blocks
can be initially set up pre-folded (once the arm64 contpte support is
added in the next few patches). This leads to noticeable performance
improvement during split.

Acked-by: David Hildenbrand <david at redhat.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 mm/huge_memory.c | 58 +++++++++++++++++++++++++++---------------------
 1 file changed, 33 insertions(+), 25 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 016e20bd813e..14888b15121e 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2579,15 +2579,16 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
 
 	pte = pte_offset_map(&_pmd, haddr);
 	VM_BUG_ON(!pte);
-	for (i = 0, addr = haddr; i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE) {
-		pte_t entry;
-		/*
-		 * Note that NUMA hinting access restrictions are not
-		 * transferred to avoid any possibility of altering
-		 * permissions across VMAs.
-		 */
-		if (freeze || pmd_migration) {
+
+	/*
+	 * Note that NUMA hinting access restrictions are not transferred to
+	 * avoid any possibility of altering permissions across VMAs.
+	 */
+	if (freeze || pmd_migration) {
+		for (i = 0, addr = haddr; i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE) {
+			pte_t entry;
 			swp_entry_t swp_entry;
+
 			if (write)
 				swp_entry = make_writable_migration_entry(
 							page_to_pfn(page + i));
@@ -2606,25 +2607,32 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
 				entry = pte_swp_mksoft_dirty(entry);
 			if (uffd_wp)
 				entry = pte_swp_mkuffd_wp(entry);
-		} else {
-			entry = mk_pte(page + i, READ_ONCE(vma->vm_page_prot));
-			if (write)
-				entry = pte_mkwrite(entry, vma);
-			if (!young)
-				entry = pte_mkold(entry);
-			/* NOTE: this may set soft-dirty too on some archs */
-			if (dirty)
-				entry = pte_mkdirty(entry);
-			if (soft_dirty)
-				entry = pte_mksoft_dirty(entry);
-			if (uffd_wp)
-				entry = pte_mkuffd_wp(entry);
+
+			VM_WARN_ON(!pte_none(ptep_get(pte + i)));
+			set_pte_at(mm, addr, pte + i, entry);
 		}
-		VM_BUG_ON(!pte_none(ptep_get(pte)));
-		set_pte_at(mm, addr, pte, entry);
-		pte++;
+	} else {
+		pte_t entry;
+
+		entry = mk_pte(page, READ_ONCE(vma->vm_page_prot));
+		if (write)
+			entry = pte_mkwrite(entry, vma);
+		if (!young)
+			entry = pte_mkold(entry);
+		/* NOTE: this may set soft-dirty too on some archs */
+		if (dirty)
+			entry = pte_mkdirty(entry);
+		if (soft_dirty)
+			entry = pte_mksoft_dirty(entry);
+		if (uffd_wp)
+			entry = pte_mkuffd_wp(entry);
+
+		for (i = 0; i < HPAGE_PMD_NR; i++)
+			VM_WARN_ON(!pte_none(ptep_get(pte + i)));
+
+		set_ptes(mm, haddr, pte, entry, HPAGE_PMD_NR);
 	}
-	pte_unmap(pte - 1);
+	pte_unmap(pte);
 
 	if (!pmd_migration)
 		folio_remove_rmap_pmd(folio, page, vma);
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:50 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:50 +0000
Subject: [PATCH v6 03/18] mm: Introduce pte_advance_pfn() and use for pte_next_pfn()
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-4-ryan.roberts@arm.com>

The goal is to be able to advance a PTE by an arbitrary number of PFNs.
So introduce a new API that takes a nr param. Define the default
implementation here and allow for architectures to override.
pte_next_pfn() becomes a wrapper around pte_advance_pfn().

Follow up commits will convert each overriding architecture's
pte_next_pfn() to pte_advance_pfn().

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 include/linux/pgtable.h | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 231370e1b80f..b7ac8358f2aa 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -212,14 +212,17 @@ static inline int pmd_dirty(pmd_t pmd)
 #define arch_flush_lazy_mmu_mode()	do {} while (0)
 #endif
 
-
 #ifndef pte_next_pfn
-static inline pte_t pte_next_pfn(pte_t pte)
+#ifndef pte_advance_pfn
+static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 {
-	return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
+	return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
 }
 #endif
 
+#define pte_next_pfn(pte) pte_advance_pfn(pte, 1)
+#endif
+
 #ifndef set_ptes
 /**
  * set_ptes - Map consecutive pages to a contiguous range of addresses.
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:51 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:51 +0000
Subject: [PATCH v6 04/18] arm64/mm: Convert pte_next_pfn() to pte_advance_pfn()
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-5-ryan.roberts@arm.com>

Core-mm needs to be able to advance the pfn by an arbitrary amount, so
override the new pte_advance_pfn() API to do so.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 52d0b0a763f1..b6d3e9e0a946 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -351,10 +351,10 @@ static inline pgprot_t pte_pgprot(pte_t pte)
 	return __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte));
 }
 
-#define pte_next_pfn pte_next_pfn
-static inline pte_t pte_next_pfn(pte_t pte)
+#define pte_advance_pfn pte_advance_pfn
+static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 {
-	return pfn_pte(pte_pfn(pte) + 1, pte_pgprot(pte));
+	return pfn_pte(pte_pfn(pte) + nr, pte_pgprot(pte));
 }
 
 static inline void set_ptes(struct mm_struct *mm,
@@ -370,7 +370,7 @@ static inline void set_ptes(struct mm_struct *mm,
 		if (--nr == 0)
 			break;
 		ptep++;
-		pte = pte_next_pfn(pte);
+		pte = pte_advance_pfn(pte, 1);
 	}
 }
 #define set_ptes set_ptes
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:48 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:48 +0000
Subject: [PATCH v6 01/18] mm: Clarify the spec for set_ptes()
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-2-ryan.roberts@arm.com>

set_ptes() spec implies that it can only be used to set a present pte
because it interprets the PFN field to increment it. However,
set_pte_at() has been implemented on top of set_ptes() since set_ptes()
was introduced, and set_pte_at() allows setting a pte to a not-present
state. So clarify the spec to state that when nr==1, new state of pte
may be present or not present. When nr>1, new state of all ptes must be
present.

While we are at it, tighten the spec to set requirements around the
initial state of ptes; when nr==1 it may be either present or
not-present. But when nr>1 all ptes must initially be not-present. All
set_ptes() callsites already conform to this requirement. Stating it
explicitly is useful because it allows for a simplification to the
upcoming arm64 contpte implementation.

Acked-by: David Hildenbrand <david at redhat.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 include/linux/pgtable.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 49ab1f73b5c2..231370e1b80f 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -229,6 +229,10 @@ static inline pte_t pte_next_pfn(pte_t pte)
  * @pte: Page table entry for the first page.
  * @nr: Number of pages to map.
  *
+ * When nr==1, initial state of pte may be present or not present, and new state
+ * may be present or not present. When nr>1, initial state of all ptes must be
+ * not present, and new state must be present.
+ *
  * May be overridden by the architecture, or the architecture can define
  * set_pte() and PFN_PTE_SHIFT.
  *
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:52 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:52 +0000
Subject: [PATCH v6 05/18] x86/mm: Convert pte_next_pfn() to pte_advance_pfn()
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-6-ryan.roberts@arm.com>

Core-mm needs to be able to advance the pfn by an arbitrary amount, so
override the new pte_advance_pfn() API to do so.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/x86/include/asm/pgtable.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index b50b2ef63672..69ed0ea0641b 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -955,13 +955,13 @@ static inline int pte_same(pte_t a, pte_t b)
 	return a.pte == b.pte;
 }
 
-static inline pte_t pte_next_pfn(pte_t pte)
+static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 {
 	if (__pte_needs_invert(pte_val(pte)))
-		return __pte(pte_val(pte) - (1UL << PFN_PTE_SHIFT));
-	return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
+		return __pte(pte_val(pte) - (nr << PFN_PTE_SHIFT));
+	return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
 }
-#define pte_next_pfn	pte_next_pfn
+#define pte_advance_pfn	pte_advance_pfn
 
 static inline int pte_present(pte_t a)
 {
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:53 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:53 +0000
Subject: [PATCH v6 06/18] mm: Tidy up pte_next_pfn() definition
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-7-ryan.roberts@arm.com>

Now that the all architecture overrides of pte_next_pfn() have been
replaced with pte_advance_pfn(), we can simplify the definition of the
generic pte_next_pfn() macro so that it is unconditionally defined.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 include/linux/pgtable.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index b7ac8358f2aa..bc005d84f764 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -212,7 +212,6 @@ static inline int pmd_dirty(pmd_t pmd)
 #define arch_flush_lazy_mmu_mode()	do {} while (0)
 #endif
 
-#ifndef pte_next_pfn
 #ifndef pte_advance_pfn
 static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 {
@@ -221,7 +220,6 @@ static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 #endif
 
 #define pte_next_pfn(pte) pte_advance_pfn(pte, 1)
-#endif
 
 #ifndef set_ptes
 /**
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:54 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:54 +0000
Subject: [PATCH v6 07/18] arm64/mm: Convert READ_ONCE(*ptep) to ptep_get(ptep)
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-8-ryan.roberts@arm.com>

There are a number of places in the arch code that read a pte by using
the READ_ONCE() macro. Refactor these call sites to instead use the
ptep_get() helper, which itself is a READ_ONCE(). Generated code should
be the same.

This will benefit us when we shortly introduce the transparent contpte
support. In this case, ptep_get() will become more complex so we now
have all the code abstracted through it.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 12 +++++++++---
 arch/arm64/kernel/efi.c          |  2 +-
 arch/arm64/mm/fault.c            |  4 ++--
 arch/arm64/mm/hugetlbpage.c      |  6 +++---
 arch/arm64/mm/kasan_init.c       |  2 +-
 arch/arm64/mm/mmu.c              | 12 ++++++------
 arch/arm64/mm/pageattr.c         |  4 ++--
 arch/arm64/mm/trans_pgd.c        |  2 +-
 8 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index b6d3e9e0a946..de034ca40bad 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -275,6 +275,12 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
 	}
 }
 
+#define ptep_get ptep_get
+static inline pte_t ptep_get(pte_t *ptep)
+{
+	return READ_ONCE(*ptep);
+}
+
 extern void __sync_icache_dcache(pte_t pteval);
 bool pgattr_change_is_safe(u64 old, u64 new);
 
@@ -302,7 +308,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
 	if (!IS_ENABLED(CONFIG_DEBUG_VM))
 		return;
 
-	old_pte = READ_ONCE(*ptep);
+	old_pte = ptep_get(ptep);
 
 	if (!pte_valid(old_pte) || !pte_valid(pte))
 		return;
@@ -904,7 +910,7 @@ static inline int __ptep_test_and_clear_young(pte_t *ptep)
 {
 	pte_t old_pte, pte;
 
-	pte = READ_ONCE(*ptep);
+	pte = ptep_get(ptep);
 	do {
 		old_pte = pte;
 		pte = pte_mkold(pte);
@@ -986,7 +992,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
 {
 	pte_t old_pte, pte;
 
-	pte = READ_ONCE(*ptep);
+	pte = ptep_get(ptep);
 	do {
 		old_pte = pte;
 		pte = pte_wrprotect(pte);
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 0228001347be..d0e08e93b246 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -103,7 +103,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
 {
 	struct set_perm_data *spd = data;
 	const efi_memory_desc_t *md = spd->md;
-	pte_t pte = READ_ONCE(*ptep);
+	pte_t pte = ptep_get(ptep);
 
 	if (md->attribute & EFI_MEMORY_RO)
 		pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 55f6455a8284..a254761fa1bd 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -191,7 +191,7 @@ static void show_pte(unsigned long addr)
 		if (!ptep)
 			break;
 
-		pte = READ_ONCE(*ptep);
+		pte = ptep_get(ptep);
 		pr_cont(", pte=%016llx", pte_val(pte));
 		pte_unmap(ptep);
 	} while(0);
@@ -214,7 +214,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
 			  pte_t entry, int dirty)
 {
 	pteval_t old_pteval, pteval;
-	pte_t pte = READ_ONCE(*ptep);
+	pte_t pte = ptep_get(ptep);
 
 	if (pte_same(pte, entry))
 		return 0;
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 6720ec8d50e7..2892f925ed66 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -485,7 +485,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
 	size_t pgsize;
 	pte_t pte;
 
-	if (!pte_cont(READ_ONCE(*ptep))) {
+	if (!pte_cont(ptep_get(ptep))) {
 		ptep_set_wrprotect(mm, addr, ptep);
 		return;
 	}
@@ -510,7 +510,7 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
 	size_t pgsize;
 	int ncontig;
 
-	if (!pte_cont(READ_ONCE(*ptep)))
+	if (!pte_cont(ptep_get(ptep)))
 		return ptep_clear_flush(vma, addr, ptep);
 
 	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
@@ -543,7 +543,7 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr
 		 * when the permission changes from executable to non-executable
 		 * in cases where cpu is affected with errata #2645198.
 		 */
-		if (pte_user_exec(READ_ONCE(*ptep)))
+		if (pte_user_exec(ptep_get(ptep)))
 			return huge_ptep_clear_flush(vma, addr, ptep);
 	}
 	return huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 4c7ad574b946..c2a9f4f6c7dd 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -113,7 +113,7 @@ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
 			memset(__va(page_phys), KASAN_SHADOW_INIT, PAGE_SIZE);
 		next = addr + PAGE_SIZE;
 		set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
-	} while (ptep++, addr = next, addr != end && pte_none(READ_ONCE(*ptep)));
+	} while (ptep++, addr = next, addr != end && pte_none(ptep_get(ptep)));
 }
 
 static void __init kasan_pmd_populate(pud_t *pudp, unsigned long addr,
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 3a27d887f7dd..343629a17042 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -173,7 +173,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
 
 	ptep = pte_set_fixmap_offset(pmdp, addr);
 	do {
-		pte_t old_pte = READ_ONCE(*ptep);
+		pte_t old_pte = ptep_get(ptep);
 
 		set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
 
@@ -182,7 +182,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
 		 * only allow updates to the permission attributes.
 		 */
 		BUG_ON(!pgattr_change_is_safe(pte_val(old_pte),
-					      READ_ONCE(pte_val(*ptep))));
+					      pte_val(ptep_get(ptep))));
 
 		phys += PAGE_SIZE;
 	} while (ptep++, addr += PAGE_SIZE, addr != end);
@@ -852,7 +852,7 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
 
 	do {
 		ptep = pte_offset_kernel(pmdp, addr);
-		pte = READ_ONCE(*ptep);
+		pte = ptep_get(ptep);
 		if (pte_none(pte))
 			continue;
 
@@ -985,7 +985,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
 
 	do {
 		ptep = pte_offset_kernel(pmdp, addr);
-		pte = READ_ONCE(*ptep);
+		pte = ptep_get(ptep);
 
 		/*
 		 * This is just a sanity check here which verifies that
@@ -1004,7 +1004,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
 	 */
 	ptep = pte_offset_kernel(pmdp, 0UL);
 	for (i = 0; i < PTRS_PER_PTE; i++) {
-		if (!pte_none(READ_ONCE(ptep[i])))
+		if (!pte_none(ptep_get(&ptep[i])))
 			return;
 	}
 
@@ -1473,7 +1473,7 @@ pte_t ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, pte
 		 * when the permission changes from executable to non-executable
 		 * in cases where cpu is affected with errata #2645198.
 		 */
-		if (pte_user_exec(READ_ONCE(*ptep)))
+		if (pte_user_exec(ptep_get(ptep)))
 			return ptep_clear_flush(vma, addr, ptep);
 	}
 	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 924843f1f661..73a5e8f82586 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -36,7 +36,7 @@ bool can_set_direct_map(void)
 static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
 {
 	struct page_change_data *cdata = data;
-	pte_t pte = READ_ONCE(*ptep);
+	pte_t pte = ptep_get(ptep);
 
 	pte = clear_pte_bit(pte, cdata->clear_mask);
 	pte = set_pte_bit(pte, cdata->set_mask);
@@ -245,5 +245,5 @@ bool kernel_page_present(struct page *page)
 		return true;
 
 	ptep = pte_offset_kernel(pmdp, addr);
-	return pte_valid(READ_ONCE(*ptep));
+	return pte_valid(ptep_get(ptep));
 }
diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
index 7b14df3c6477..f71ab4704cce 100644
--- a/arch/arm64/mm/trans_pgd.c
+++ b/arch/arm64/mm/trans_pgd.c
@@ -33,7 +33,7 @@ static void *trans_alloc(struct trans_pgd_info *info)
 
 static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
 {
-	pte_t pte = READ_ONCE(*src_ptep);
+	pte_t pte = ptep_get(src_ptep);
 
 	if (pte_valid(pte)) {
 		/*
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:55 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:55 +0000
Subject: [PATCH v6 08/18] arm64/mm: Convert set_pte_at() to set_ptes(..., 1)
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-9-ryan.roberts@arm.com>

Since set_ptes() was introduced, set_pte_at() has been implemented as a
generic macro around set_ptes(..., 1). So this change should continue to
generate the same code. However, making this change prepares us for the
transparent contpte support. It means we can reroute set_ptes() to
__set_ptes(). Since set_pte_at() is a generic macro, there will be no
equivalent __set_pte_at() to reroute to.

Note that a couple of calls to set_pte_at() remain in the arch code.
This is intentional, since those call sites are acting on behalf of
core-mm and should continue to call into the public set_ptes() rather
than the arch-private __set_ptes().

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h |  2 +-
 arch/arm64/kernel/mte.c          |  2 +-
 arch/arm64/kvm/guest.c           |  2 +-
 arch/arm64/mm/fault.c            |  2 +-
 arch/arm64/mm/hugetlbpage.c      | 10 +++++-----
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index de034ca40bad..9a2df85eb493 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1084,7 +1084,7 @@ static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
 #endif /* CONFIG_ARM64_MTE */
 
 /*
- * On AArch64, the cache coherency is handled via the set_pte_at() function.
+ * On AArch64, the cache coherency is handled via the set_ptes() function.
  */
 static inline void update_mmu_cache_range(struct vm_fault *vmf,
 		struct vm_area_struct *vma, unsigned long addr, pte_t *ptep,
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index a41ef3213e1e..59bfe2e96f8f 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -67,7 +67,7 @@ int memcmp_pages(struct page *page1, struct page *page2)
 	/*
 	 * If the page content is identical but at least one of the pages is
 	 * tagged, return non-zero to avoid KSM merging. If only one of the
-	 * pages is tagged, set_pte_at() may zero or change the tags of the
+	 * pages is tagged, set_ptes() may zero or change the tags of the
 	 * other page via mte_sync_tags().
 	 */
 	if (page_mte_tagged(page1) || page_mte_tagged(page2))
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index aaf1d4939739..6e0df623c8e9 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -1072,7 +1072,7 @@ int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
 		} else {
 			/*
 			 * Only locking to serialise with a concurrent
-			 * set_pte_at() in the VMM but still overriding the
+			 * set_ptes() in the VMM but still overriding the
 			 * tags, hence ignoring the return value.
 			 */
 			try_page_mte_tagging(page);
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index a254761fa1bd..3235e23309ec 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -205,7 +205,7 @@ static void show_pte(unsigned long addr)
  *
  * It needs to cope with hardware update of the accessed/dirty state by other
  * agents in the system and can safely skip the __sync_icache_dcache() call as,
- * like set_pte_at(), the PTE is never changed from no-exec to exec here.
+ * like set_ptes(), the PTE is never changed from no-exec to exec here.
  *
  * Returns whether or not the PTE actually changed.
  */
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 2892f925ed66..27f6160890d1 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -247,12 +247,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 
 	if (!pte_present(pte)) {
 		for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
-			set_pte_at(mm, addr, ptep, pte);
+			set_ptes(mm, addr, ptep, pte, 1);
 		return;
 	}
 
 	if (!pte_cont(pte)) {
-		set_pte_at(mm, addr, ptep, pte);
+		set_ptes(mm, addr, ptep, pte, 1);
 		return;
 	}
 
@@ -263,7 +263,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	clear_flush(mm, addr, ptep, pgsize, ncontig);
 
 	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
-		set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
+		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
 }
 
 pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -471,7 +471,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 
 	hugeprot = pte_pgprot(pte);
 	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
-		set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
+		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
 
 	return 1;
 }
@@ -500,7 +500,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
 	pfn = pte_pfn(pte);
 
 	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
-		set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
+		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
 }
 
 pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:56 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:56 +0000
Subject: [PATCH v6 09/18] arm64/mm: Convert ptep_clear() to ptep_get_and_clear()
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-10-ryan.roberts@arm.com>

ptep_clear() is a generic wrapper around the arch-implemented
ptep_get_and_clear(). We are about to convert ptep_get_and_clear() into
a public version and private version (__ptep_get_and_clear()) to support
the transparent contpte work. We won't have a private version of
ptep_clear() so let's convert it to directly call ptep_get_and_clear().

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/mm/hugetlbpage.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 27f6160890d1..48e8b429879d 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -229,7 +229,7 @@ static void clear_flush(struct mm_struct *mm,
 	unsigned long i, saddr = addr;
 
 	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
-		ptep_clear(mm, addr, ptep);
+		ptep_get_and_clear(mm, addr, ptep);
 
 	flush_tlb_range(&vma, saddr, addr);
 }
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:58 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:58 +0000
Subject: [PATCH v6 11/18] arm64/mm: Split __flush_tlb_range() to elide trailing DSB
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-12-ryan.roberts@arm.com>

Split __flush_tlb_range() into __flush_tlb_range_nosync() +
__flush_tlb_range(), in the same way as the existing flush_tlb_page()
arrangement. This allows calling __flush_tlb_range_nosync() to elide the
trailing DSB. Forthcoming "contpte" code will take advantage of this
when clearing the young bit from a contiguous range of ptes.

Ordering between dsb and mmu_notifier_arch_invalidate_secondary_tlbs()
has changed, but now aligns with the ordering of __flush_tlb_page(). It
has been discussed that __flush_tlb_page() may be wrong though.
Regardless, both will be resolved separately if needed.

Reviewed-by: David Hildenbrand <david at redhat.com>
Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/tlbflush.h | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index 1deb5d789c2e..3b0e8248e1a4 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -422,7 +422,7 @@ do {									\
 #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \
 	__flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false, kvm_lpa2_is_enabled());
 
-static inline void __flush_tlb_range(struct vm_area_struct *vma,
+static inline void __flush_tlb_range_nosync(struct vm_area_struct *vma,
 				     unsigned long start, unsigned long end,
 				     unsigned long stride, bool last_level,
 				     int tlb_level)
@@ -456,10 +456,19 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
 		__flush_tlb_range_op(vae1is, start, pages, stride, asid,
 				     tlb_level, true, lpa2_is_enabled());
 
-	dsb(ish);
 	mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
 }
 
+static inline void __flush_tlb_range(struct vm_area_struct *vma,
+				     unsigned long start, unsigned long end,
+				     unsigned long stride, bool last_level,
+				     int tlb_level)
+{
+	__flush_tlb_range_nosync(vma, start, end, stride,
+				 last_level, tlb_level);
+	dsb(ish);
+}
+
 static inline void flush_tlb_range(struct vm_area_struct *vma,
 				   unsigned long start, unsigned long end)
 {
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:57 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:57 +0000
Subject: [PATCH v6 10/18] arm64/mm: New ptep layer to manage contig bit
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-11-ryan.roberts@arm.com>

Create a new layer for the in-table PTE manipulation APIs. For now, The
existing API is prefixed with double underscore to become the
arch-private API and the public API is just a simple wrapper that calls
the private API.

The public API implementation will subsequently be used to transparently
manipulate the contiguous bit where appropriate. But since there are
already some contig-aware users (e.g. hugetlb, kernel mapper), we must
first ensure those users use the private API directly so that the future
contig-bit manipulations in the public API do not interfere with those
existing uses.

The following APIs are treated this way:

 - ptep_get
 - set_pte
 - set_ptes
 - pte_clear
 - ptep_get_and_clear
 - ptep_test_and_clear_young
 - ptep_clear_flush_young
 - ptep_set_wrprotect
 - ptep_set_access_flags

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 83 +++++++++++++++++---------------
 arch/arm64/kernel/efi.c          |  4 +-
 arch/arm64/kernel/mte.c          |  2 +-
 arch/arm64/kvm/guest.c           |  2 +-
 arch/arm64/mm/fault.c            | 12 ++---
 arch/arm64/mm/fixmap.c           |  4 +-
 arch/arm64/mm/hugetlbpage.c      | 40 +++++++--------
 arch/arm64/mm/kasan_init.c       |  6 +--
 arch/arm64/mm/mmu.c              | 14 +++---
 arch/arm64/mm/pageattr.c         |  6 +--
 arch/arm64/mm/trans_pgd.c        |  6 +--
 11 files changed, 93 insertions(+), 86 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 9a2df85eb493..7336d40a893a 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -93,7 +93,8 @@ 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(ptep, __pte(0))
 #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
 
 /*
@@ -137,7 +138,7 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
  * so that we don't erroneously return false for pages that have been
  * remapped as PROT_NONE but are yet to be flushed from the TLB.
  * Note that we can't make any assumptions based on the state of the access
- * flag, since ptep_clear_flush_young() elides a DSB when invalidating the
+ * flag, since __ptep_clear_flush_young() elides a DSB when invalidating the
  * TLB.
  */
 #define pte_accessible(mm, pte)	\
@@ -261,7 +262,7 @@ static inline pte_t pte_mkdevmap(pte_t pte)
 	return set_pte_bit(pte, __pgprot(PTE_DEVMAP | PTE_SPECIAL));
 }
 
-static inline void set_pte(pte_t *ptep, pte_t pte)
+static inline void __set_pte(pte_t *ptep, pte_t pte)
 {
 	WRITE_ONCE(*ptep, pte);
 
@@ -275,8 +276,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
 	}
 }
 
-#define ptep_get ptep_get
-static inline pte_t ptep_get(pte_t *ptep)
+static inline pte_t __ptep_get(pte_t *ptep)
 {
 	return READ_ONCE(*ptep);
 }
@@ -308,7 +308,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
 	if (!IS_ENABLED(CONFIG_DEBUG_VM))
 		return;
 
-	old_pte = ptep_get(ptep);
+	old_pte = __ptep_get(ptep);
 
 	if (!pte_valid(old_pte) || !pte_valid(pte))
 		return;
@@ -317,7 +317,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
 
 	/*
 	 * Check for potential race with hardware updates of the pte
-	 * (ptep_set_access_flags safely changes valid ptes without going
+	 * (__ptep_set_access_flags safely changes valid ptes without going
 	 * through an invalid entry).
 	 */
 	VM_WARN_ONCE(!pte_young(pte),
@@ -363,23 +363,22 @@ static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 	return pfn_pte(pte_pfn(pte) + nr, pte_pgprot(pte));
 }
 
-static inline void set_ptes(struct mm_struct *mm,
-			    unsigned long __always_unused addr,
-			    pte_t *ptep, pte_t pte, unsigned int nr)
+static inline void __set_ptes(struct mm_struct *mm,
+			      unsigned long __always_unused addr,
+			      pte_t *ptep, pte_t pte, unsigned int nr)
 {
 	page_table_check_ptes_set(mm, ptep, pte, nr);
 	__sync_cache_and_tags(pte, nr);
 
 	for (;;) {
 		__check_safe_pte_update(mm, ptep, pte);
-		set_pte(ptep, pte);
+		__set_pte(ptep, pte);
 		if (--nr == 0)
 			break;
 		ptep++;
 		pte = pte_advance_pfn(pte, 1);
 	}
 }
-#define set_ptes set_ptes
 
 /*
  * Huge pte definitions.
@@ -546,7 +545,7 @@ static inline void __set_pte_at(struct mm_struct *mm,
 {
 	__sync_cache_and_tags(pte, nr);
 	__check_safe_pte_update(mm, ptep, pte);
-	set_pte(ptep, pte);
+	__set_pte(ptep, pte);
 }
 
 static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
@@ -860,8 +859,7 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
 	return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
 }
 
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-extern int ptep_set_access_flags(struct vm_area_struct *vma,
+extern int __ptep_set_access_flags(struct vm_area_struct *vma,
 				 unsigned long address, pte_t *ptep,
 				 pte_t entry, int dirty);
 
@@ -871,7 +869,8 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
 					unsigned long address, pmd_t *pmdp,
 					pmd_t entry, int dirty)
 {
-	return ptep_set_access_flags(vma, address, (pte_t *)pmdp, pmd_pte(entry), dirty);
+	return __ptep_set_access_flags(vma, address, (pte_t *)pmdp,
+							pmd_pte(entry), dirty);
 }
 
 static inline int pud_devmap(pud_t pud)
@@ -905,12 +904,13 @@ static inline bool pud_user_accessible_page(pud_t pud)
 /*
  * 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 vm_area_struct *vma,
+					      unsigned long address,
+					      pte_t *ptep)
 {
 	pte_t old_pte, pte;
 
-	pte = ptep_get(ptep);
+	pte = __ptep_get(ptep);
 	do {
 		old_pte = pte;
 		pte = pte_mkold(pte);
@@ -921,18 +921,10 @@ static inline int __ptep_test_and_clear_young(pte_t *ptep)
 	return pte_young(pte);
 }
 
-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);
-}
-
-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
+static inline int __ptep_clear_flush_young(struct vm_area_struct *vma,
 					 unsigned long address, pte_t *ptep)
 {
-	int young = ptep_test_and_clear_young(vma, address, ptep);
+	int young = __ptep_test_and_clear_young(vma, address, ptep);
 
 	if (young) {
 		/*
@@ -955,12 +947,11 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 					    unsigned long address,
 					    pmd_t *pmdp)
 {
-	return ptep_test_and_clear_young(vma, address, (pte_t *)pmdp);
+	return __ptep_test_and_clear_young(vma, address, (pte_t *)pmdp);
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t __ptep_get_and_clear(struct mm_struct *mm,
 				       unsigned long address, pte_t *ptep)
 {
 	pte_t pte = __pte(xchg_relaxed(&pte_val(*ptep), 0));
@@ -984,15 +975,15 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
 /*
- * ptep_set_wrprotect - mark read-only while trasferring potential hardware
+ * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
  * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
  */
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
+static inline void __ptep_set_wrprotect(struct mm_struct *mm,
+					unsigned long address, pte_t *ptep)
 {
 	pte_t old_pte, pte;
 
-	pte = ptep_get(ptep);
+	pte = __ptep_get(ptep);
 	do {
 		old_pte = pte;
 		pte = pte_wrprotect(pte);
@@ -1006,7 +997,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
 static inline void pmdp_set_wrprotect(struct mm_struct *mm,
 				      unsigned long address, pmd_t *pmdp)
 {
-	ptep_set_wrprotect(mm, address, (pte_t *)pmdp);
+	__ptep_set_wrprotect(mm, address, (pte_t *)pmdp);
 }
 
 #define pmdp_establish pmdp_establish
@@ -1084,7 +1075,7 @@ static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
 #endif /* CONFIG_ARM64_MTE */
 
 /*
- * On AArch64, the cache coherency is handled via the set_ptes() function.
+ * On AArch64, the cache coherency is handled via the __set_ptes() function.
  */
 static inline void update_mmu_cache_range(struct vm_fault *vmf,
 		struct vm_area_struct *vma, unsigned long addr, pte_t *ptep,
@@ -1136,6 +1127,22 @@ extern pte_t ptep_modify_prot_start(struct vm_area_struct *vma,
 extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
 				    unsigned long addr, pte_t *ptep,
 				    pte_t old_pte, pte_t new_pte);
+
+#define ptep_get				__ptep_get
+#define set_pte					__set_pte
+#define set_ptes				__set_ptes
+#define pte_clear				__pte_clear
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define ptep_get_and_clear			__ptep_get_and_clear
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define ptep_test_and_clear_young		__ptep_test_and_clear_young
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define ptep_clear_flush_young			__ptep_clear_flush_young
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define ptep_set_wrprotect			__ptep_set_wrprotect
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+#define ptep_set_access_flags			__ptep_set_access_flags
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_PGTABLE_H */
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index d0e08e93b246..9afcc690fe73 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -103,7 +103,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
 {
 	struct set_perm_data *spd = data;
 	const efi_memory_desc_t *md = spd->md;
-	pte_t pte = ptep_get(ptep);
+	pte_t pte = __ptep_get(ptep);
 
 	if (md->attribute & EFI_MEMORY_RO)
 		pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
@@ -111,7 +111,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
 		pte = set_pte_bit(pte, __pgprot(PTE_PXN));
 	else if (system_supports_bti_kernel() && spd->has_bti)
 		pte = set_pte_bit(pte, __pgprot(PTE_GP));
-	set_pte(ptep, pte);
+	__set_pte(ptep, pte);
 	return 0;
 }
 
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index 59bfe2e96f8f..dcdcccd40891 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -67,7 +67,7 @@ int memcmp_pages(struct page *page1, struct page *page2)
 	/*
 	 * If the page content is identical but at least one of the pages is
 	 * tagged, return non-zero to avoid KSM merging. If only one of the
-	 * pages is tagged, set_ptes() may zero or change the tags of the
+	 * pages is tagged, __set_ptes() may zero or change the tags of the
 	 * other page via mte_sync_tags().
 	 */
 	if (page_mte_tagged(page1) || page_mte_tagged(page2))
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 6e0df623c8e9..629145fd3161 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -1072,7 +1072,7 @@ int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
 		} else {
 			/*
 			 * Only locking to serialise with a concurrent
-			 * set_ptes() in the VMM but still overriding the
+			 * __set_ptes() in the VMM but still overriding the
 			 * tags, hence ignoring the return value.
 			 */
 			try_page_mte_tagging(page);
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 3235e23309ec..9a1c66183d16 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -191,7 +191,7 @@ static void show_pte(unsigned long addr)
 		if (!ptep)
 			break;
 
-		pte = ptep_get(ptep);
+		pte = __ptep_get(ptep);
 		pr_cont(", pte=%016llx", pte_val(pte));
 		pte_unmap(ptep);
 	} while(0);
@@ -205,16 +205,16 @@ static void show_pte(unsigned long addr)
  *
  * It needs to cope with hardware update of the accessed/dirty state by other
  * agents in the system and can safely skip the __sync_icache_dcache() call as,
- * like set_ptes(), the PTE is never changed from no-exec to exec here.
+ * like __set_ptes(), the PTE is never changed from no-exec to exec here.
  *
  * Returns whether or not the PTE actually changed.
  */
-int ptep_set_access_flags(struct vm_area_struct *vma,
-			  unsigned long address, pte_t *ptep,
-			  pte_t entry, int dirty)
+int __ptep_set_access_flags(struct vm_area_struct *vma,
+			    unsigned long address, pte_t *ptep,
+			    pte_t entry, int dirty)
 {
 	pteval_t old_pteval, pteval;
-	pte_t pte = ptep_get(ptep);
+	pte_t pte = __ptep_get(ptep);
 
 	if (pte_same(pte, entry))
 		return 0;
diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
index c0a3301203bd..bfc02568805a 100644
--- a/arch/arm64/mm/fixmap.c
+++ b/arch/arm64/mm/fixmap.c
@@ -121,9 +121,9 @@ void __set_fixmap(enum fixed_addresses idx,
 	ptep = fixmap_pte(addr);
 
 	if (pgprot_val(flags)) {
-		set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
+		__set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
 	} else {
-		pte_clear(&init_mm, addr, ptep);
+		__pte_clear(&init_mm, addr, ptep);
 		flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
 	}
 }
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 48e8b429879d..0f0e10bb0a95 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -145,14 +145,14 @@ pte_t huge_ptep_get(pte_t *ptep)
 {
 	int ncontig, i;
 	size_t pgsize;
-	pte_t orig_pte = ptep_get(ptep);
+	pte_t orig_pte = __ptep_get(ptep);
 
 	if (!pte_present(orig_pte) || !pte_cont(orig_pte))
 		return orig_pte;
 
 	ncontig = num_contig_ptes(page_size(pte_page(orig_pte)), &pgsize);
 	for (i = 0; i < ncontig; i++, ptep++) {
-		pte_t pte = ptep_get(ptep);
+		pte_t pte = __ptep_get(ptep);
 
 		if (pte_dirty(pte))
 			orig_pte = pte_mkdirty(orig_pte);
@@ -177,11 +177,11 @@ static pte_t get_clear_contig(struct mm_struct *mm,
 			     unsigned long pgsize,
 			     unsigned long ncontig)
 {
-	pte_t orig_pte = ptep_get(ptep);
+	pte_t orig_pte = __ptep_get(ptep);
 	unsigned long i;
 
 	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) {
-		pte_t pte = ptep_get_and_clear(mm, addr, ptep);
+		pte_t pte = __ptep_get_and_clear(mm, addr, ptep);
 
 		/*
 		 * If HW_AFDBM is enabled, then the HW could turn on
@@ -229,7 +229,7 @@ static void clear_flush(struct mm_struct *mm,
 	unsigned long i, saddr = addr;
 
 	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
-		ptep_get_and_clear(mm, addr, ptep);
+		__ptep_get_and_clear(mm, addr, ptep);
 
 	flush_tlb_range(&vma, saddr, addr);
 }
@@ -247,12 +247,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 
 	if (!pte_present(pte)) {
 		for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
-			set_ptes(mm, addr, ptep, pte, 1);
+			__set_ptes(mm, addr, ptep, pte, 1);
 		return;
 	}
 
 	if (!pte_cont(pte)) {
-		set_ptes(mm, addr, ptep, pte, 1);
+		__set_ptes(mm, addr, ptep, pte, 1);
 		return;
 	}
 
@@ -263,7 +263,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 	clear_flush(mm, addr, ptep, pgsize, ncontig);
 
 	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
-		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
+		__set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
 }
 
 pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -393,7 +393,7 @@ void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
 	ncontig = num_contig_ptes(sz, &pgsize);
 
 	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
-		pte_clear(mm, addr, ptep);
+		__pte_clear(mm, addr, ptep);
 }
 
 pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
@@ -401,10 +401,10 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
 {
 	int ncontig;
 	size_t pgsize;
-	pte_t orig_pte = ptep_get(ptep);
+	pte_t orig_pte = __ptep_get(ptep);
 
 	if (!pte_cont(orig_pte))
-		return ptep_get_and_clear(mm, addr, ptep);
+		return __ptep_get_and_clear(mm, addr, ptep);
 
 	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
 
@@ -424,11 +424,11 @@ static int __cont_access_flags_changed(pte_t *ptep, pte_t pte, int ncontig)
 {
 	int i;
 
-	if (pte_write(pte) != pte_write(ptep_get(ptep)))
+	if (pte_write(pte) != pte_write(__ptep_get(ptep)))
 		return 1;
 
 	for (i = 0; i < ncontig; i++) {
-		pte_t orig_pte = ptep_get(ptep + i);
+		pte_t orig_pte = __ptep_get(ptep + i);
 
 		if (pte_dirty(pte) != pte_dirty(orig_pte))
 			return 1;
@@ -452,7 +452,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 	pte_t orig_pte;
 
 	if (!pte_cont(pte))
-		return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+		return __ptep_set_access_flags(vma, addr, ptep, pte, dirty);
 
 	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
 	dpfn = pgsize >> PAGE_SHIFT;
@@ -471,7 +471,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 
 	hugeprot = pte_pgprot(pte);
 	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
-		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
+		__set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
 
 	return 1;
 }
@@ -485,8 +485,8 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
 	size_t pgsize;
 	pte_t pte;
 
-	if (!pte_cont(ptep_get(ptep))) {
-		ptep_set_wrprotect(mm, addr, ptep);
+	if (!pte_cont(__ptep_get(ptep))) {
+		__ptep_set_wrprotect(mm, addr, ptep);
 		return;
 	}
 
@@ -500,7 +500,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
 	pfn = pte_pfn(pte);
 
 	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
-		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
+		__set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
 }
 
 pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -510,7 +510,7 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
 	size_t pgsize;
 	int ncontig;
 
-	if (!pte_cont(ptep_get(ptep)))
+	if (!pte_cont(__ptep_get(ptep)))
 		return ptep_clear_flush(vma, addr, ptep);
 
 	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
@@ -543,7 +543,7 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr
 		 * when the permission changes from executable to non-executable
 		 * in cases where cpu is affected with errata #2645198.
 		 */
-		if (pte_user_exec(ptep_get(ptep)))
+		if (pte_user_exec(__ptep_get(ptep)))
 			return huge_ptep_clear_flush(vma, addr, ptep);
 	}
 	return huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index c2a9f4f6c7dd..9ee16cfce587 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -112,8 +112,8 @@ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
 		if (!early)
 			memset(__va(page_phys), KASAN_SHADOW_INIT, PAGE_SIZE);
 		next = addr + PAGE_SIZE;
-		set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
-	} while (ptep++, addr = next, addr != end && pte_none(ptep_get(ptep)));
+		__set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
+	} while (ptep++, addr = next, addr != end && pte_none(__ptep_get(ptep)));
 }
 
 static void __init kasan_pmd_populate(pud_t *pudp, unsigned long addr,
@@ -271,7 +271,7 @@ static void __init kasan_init_shadow(void)
 	 * so we should make sure that it maps the zero page read-only.
 	 */
 	for (i = 0; i < PTRS_PER_PTE; i++)
-		set_pte(&kasan_early_shadow_pte[i],
+		__set_pte(&kasan_early_shadow_pte[i],
 			pfn_pte(sym_to_pfn(kasan_early_shadow_page),
 				PAGE_KERNEL_RO));
 
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 343629a17042..6208c7541f87 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -173,16 +173,16 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
 
 	ptep = pte_set_fixmap_offset(pmdp, addr);
 	do {
-		pte_t old_pte = ptep_get(ptep);
+		pte_t old_pte = __ptep_get(ptep);
 
-		set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
+		__set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
 
 		/*
 		 * After the PTE entry has been populated once, we
 		 * only allow updates to the permission attributes.
 		 */
 		BUG_ON(!pgattr_change_is_safe(pte_val(old_pte),
-					      pte_val(ptep_get(ptep))));
+					      pte_val(__ptep_get(ptep))));
 
 		phys += PAGE_SIZE;
 	} while (ptep++, addr += PAGE_SIZE, addr != end);
@@ -852,12 +852,12 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
 
 	do {
 		ptep = pte_offset_kernel(pmdp, addr);
-		pte = ptep_get(ptep);
+		pte = __ptep_get(ptep);
 		if (pte_none(pte))
 			continue;
 
 		WARN_ON(!pte_present(pte));
-		pte_clear(&init_mm, addr, ptep);
+		__pte_clear(&init_mm, addr, ptep);
 		flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
 		if (free_mapped)
 			free_hotplug_page_range(pte_page(pte),
@@ -985,7 +985,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
 
 	do {
 		ptep = pte_offset_kernel(pmdp, addr);
-		pte = ptep_get(ptep);
+		pte = __ptep_get(ptep);
 
 		/*
 		 * This is just a sanity check here which verifies that
@@ -1004,7 +1004,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
 	 */
 	ptep = pte_offset_kernel(pmdp, 0UL);
 	for (i = 0; i < PTRS_PER_PTE; i++) {
-		if (!pte_none(ptep_get(&ptep[i])))
+		if (!pte_none(__ptep_get(&ptep[i])))
 			return;
 	}
 
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 73a5e8f82586..0c4e3ecf989d 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -36,12 +36,12 @@ bool can_set_direct_map(void)
 static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
 {
 	struct page_change_data *cdata = data;
-	pte_t pte = ptep_get(ptep);
+	pte_t pte = __ptep_get(ptep);
 
 	pte = clear_pte_bit(pte, cdata->clear_mask);
 	pte = set_pte_bit(pte, cdata->set_mask);
 
-	set_pte(ptep, pte);
+	__set_pte(ptep, pte);
 	return 0;
 }
 
@@ -245,5 +245,5 @@ bool kernel_page_present(struct page *page)
 		return true;
 
 	ptep = pte_offset_kernel(pmdp, addr);
-	return pte_valid(ptep_get(ptep));
+	return pte_valid(__ptep_get(ptep));
 }
diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
index f71ab4704cce..5139a28130c0 100644
--- a/arch/arm64/mm/trans_pgd.c
+++ b/arch/arm64/mm/trans_pgd.c
@@ -33,7 +33,7 @@ static void *trans_alloc(struct trans_pgd_info *info)
 
 static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
 {
-	pte_t pte = ptep_get(src_ptep);
+	pte_t pte = __ptep_get(src_ptep);
 
 	if (pte_valid(pte)) {
 		/*
@@ -41,7 +41,7 @@ static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
 		 * read only (code, rodata). Clear the RDONLY bit from
 		 * the temporary mappings we use during restore.
 		 */
-		set_pte(dst_ptep, pte_mkwrite_novma(pte));
+		__set_pte(dst_ptep, pte_mkwrite_novma(pte));
 	} else if ((debug_pagealloc_enabled() ||
 		   is_kfence_address((void *)addr)) && !pte_none(pte)) {
 		/*
@@ -55,7 +55,7 @@ static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
 		 */
 		BUG_ON(!pfn_valid(pte_pfn(pte)));
 
-		set_pte(dst_ptep, pte_mkpresent(pte_mkwrite_novma(pte)));
+		__set_pte(dst_ptep, pte_mkpresent(pte_mkwrite_novma(pte)));
 	}
 }
 
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:31:59 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:31:59 +0000
Subject: [PATCH v6 12/18] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-13-ryan.roberts@arm.com>

With the ptep API sufficiently refactored, we can now introduce a new
"contpte" API layer, which transparently manages the PTE_CONT bit for
user mappings.

In this initial implementation, only suitable batches of PTEs, set via
set_ptes(), are mapped with the PTE_CONT bit. Any subsequent
modification of individual PTEs will cause an "unfold" operation to
repaint the contpte block as individual PTEs before performing the
requested operation. While, a modification of a single PTE could cause
the block of PTEs to which it belongs to become eligible for "folding"
into a contpte entry, "folding" is not performed in this initial
implementation due to the costs of checking the requirements are met.
Due to this, contpte mappings will degrade back to normal pte mappings
over time if/when protections are changed. This will be solved in a
future patch.

Since a contpte block only has a single access and dirty bit, the
semantic here changes slightly; when getting a pte (e.g. ptep_get())
that is part of a contpte mapping, the access and dirty information are
pulled from the block (so all ptes in the block return the same
access/dirty info). When changing the access/dirty info on a pte (e.g.
ptep_set_access_flags()) that is part of a contpte mapping, this change
will affect the whole contpte block. This is works fine in practice
since we guarantee that only a single folio is mapped by a contpte
block, and the core-mm tracks access/dirty information per folio.

In order for the public functions, which used to be pure inline, to
continue to be callable by modules, export all the contpte_* symbols
that are now called by those public inline functions.

The feature is enabled/disabled with the ARM64_CONTPTE Kconfig parameter
at build time. It defaults to enabled as long as its dependency,
TRANSPARENT_HUGEPAGE is also enabled. The core-mm depends upon
TRANSPARENT_HUGEPAGE to be able to allocate large folios, so if its not
enabled, then there is no chance of meeting the physical contiguity
requirement for contpte mappings.

Acked-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/Kconfig               |   9 +
 arch/arm64/include/asm/pgtable.h | 167 ++++++++++++++++++
 arch/arm64/mm/Makefile           |   1 +
 arch/arm64/mm/contpte.c          | 285 +++++++++++++++++++++++++++++++
 include/linux/efi.h              |   5 +
 5 files changed, 467 insertions(+)
 create mode 100644 arch/arm64/mm/contpte.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e8275a40afbd..5a7ac1f37bdc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2229,6 +2229,15 @@ config UNWIND_PATCH_PAC_INTO_SCS
 	select UNWIND_TABLES
 	select DYNAMIC_SCS
 
+config ARM64_CONTPTE
+	bool "Contiguous PTE mappings for user memory" if EXPERT
+	depends on TRANSPARENT_HUGEPAGE
+	default y
+	help
+	  When enabled, user mappings are configured using the PTE contiguous
+	  bit, for any mappings that meet the size and alignment requirements.
+	  This reduces TLB pressure and improves performance.
+
 endmenu # "Kernel Features"
 
 menu "Boot options"
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7336d40a893a..831099cfc96b 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -133,6 +133,10 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
  */
 #define pte_valid_not_user(pte) \
 	((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN))
+/*
+ * Returns true if the pte is valid and has the contiguous bit set.
+ */
+#define pte_valid_cont(pte)	(pte_valid(pte) && pte_cont(pte))
 /*
  * Could the pte be present in the TLB? We must check mm_tlb_flush_pending
  * so that we don't erroneously return false for pages that have been
@@ -1128,6 +1132,167 @@ extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
 				    unsigned long addr, pte_t *ptep,
 				    pte_t old_pte, pte_t new_pte);
 
+#ifdef CONFIG_ARM64_CONTPTE
+
+/*
+ * The contpte APIs are used to transparently manage the contiguous bit in ptes
+ * where it is possible and makes sense to do so. The PTE_CONT bit is considered
+ * a private implementation detail of the public ptep API (see below).
+ */
+extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, pte_t pte);
+extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
+extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
+extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, pte_t pte, unsigned int nr);
+extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep);
+extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep);
+extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep,
+				pte_t entry, int dirty);
+
+static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
+					pte_t *ptep, pte_t pte)
+{
+	if (unlikely(pte_valid_cont(pte)))
+		__contpte_try_unfold(mm, addr, ptep, pte);
+}
+
+/*
+ * The below functions constitute the public API that arm64 presents to the
+ * core-mm to manipulate PTE entries within their page tables (or at least this
+ * is the subset of the API that arm64 needs to implement). These public
+ * versions will automatically and transparently apply the contiguous bit where
+ * it makes sense to do so. Therefore any users that are contig-aware (e.g.
+ * hugetlb, kernel mapper) should NOT use these APIs, but instead use the
+ * private versions, which are prefixed with double underscore. All of these
+ * APIs except for ptep_get_lockless() are expected to be called with the PTL
+ * held. Although the contiguous bit is considered private to the
+ * implementation, it is deliberately allowed to leak through the getters (e.g.
+ * ptep_get()), back to core code. This is required so that pte_leaf_size() can
+ * provide an accurate size for perf_get_pgtable_size(). But this leakage means
+ * its possible a pte will be passed to a setter with the contiguous bit set, so
+ * we explicitly clear the contiguous bit in those cases to prevent accidentally
+ * setting it in the pgtable.
+ */
+
+#define ptep_get ptep_get
+static inline pte_t ptep_get(pte_t *ptep)
+{
+	pte_t pte = __ptep_get(ptep);
+
+	if (likely(!pte_valid_cont(pte)))
+		return pte;
+
+	return contpte_ptep_get(ptep, pte);
+}
+
+#define ptep_get_lockless ptep_get_lockless
+static inline pte_t ptep_get_lockless(pte_t *ptep)
+{
+	pte_t pte = __ptep_get(ptep);
+
+	if (likely(!pte_valid_cont(pte)))
+		return pte;
+
+	return contpte_ptep_get_lockless(ptep);
+}
+
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+	/*
+	 * We don't have the mm or vaddr so cannot unfold contig entries (since
+	 * it requires tlb maintenance). set_pte() is not used in core code, so
+	 * this should never even be called. Regardless do our best to service
+	 * any call and emit a warning if there is any attempt to set a pte on
+	 * top of an existing contig range.
+	 */
+	pte_t orig_pte = __ptep_get(ptep);
+
+	WARN_ON_ONCE(pte_valid_cont(orig_pte));
+	__set_pte(ptep, pte_mknoncont(pte));
+}
+
+#define set_ptes set_ptes
+static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, pte_t pte, unsigned int nr)
+{
+	pte = pte_mknoncont(pte);
+
+	if (likely(nr == 1)) {
+		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+		__set_ptes(mm, addr, ptep, pte, 1);
+	} else {
+		contpte_set_ptes(mm, addr, ptep, pte, nr);
+	}
+}
+
+static inline void pte_clear(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep)
+{
+	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+	__pte_clear(mm, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep)
+{
+	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+	return __ptep_get_and_clear(mm, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep)
+{
+	pte_t orig_pte = __ptep_get(ptep);
+
+	if (likely(!pte_valid_cont(orig_pte)))
+		return __ptep_test_and_clear_young(vma, addr, ptep);
+
+	return contpte_ptep_test_and_clear_young(vma, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep)
+{
+	pte_t orig_pte = __ptep_get(ptep);
+
+	if (likely(!pte_valid_cont(orig_pte)))
+		return __ptep_clear_flush_young(vma, addr, ptep);
+
+	return contpte_ptep_clear_flush_young(vma, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep)
+{
+	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+	__ptep_set_wrprotect(mm, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+static inline int ptep_set_access_flags(struct vm_area_struct *vma,
+				unsigned long addr, pte_t *ptep,
+				pte_t entry, int dirty)
+{
+	pte_t orig_pte = __ptep_get(ptep);
+
+	entry = pte_mknoncont(entry);
+
+	if (likely(!pte_valid_cont(orig_pte)))
+		return __ptep_set_access_flags(vma, addr, ptep, entry, dirty);
+
+	return contpte_ptep_set_access_flags(vma, addr, ptep, entry, dirty);
+}
+
+#else /* CONFIG_ARM64_CONTPTE */
+
 #define ptep_get				__ptep_get
 #define set_pte					__set_pte
 #define set_ptes				__set_ptes
@@ -1143,6 +1308,8 @@ extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags			__ptep_set_access_flags
 
+#endif /* CONFIG_ARM64_CONTPTE */
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_PGTABLE_H */
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index dbd1bc95967d..60454256945b 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -3,6 +3,7 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   cache.o copypage.o flush.o \
 				   ioremap.o mmap.o pgd.o mmu.o \
 				   context.o proc.o pageattr.o fixmap.o
+obj-$(CONFIG_ARM64_CONTPTE)	+= contpte.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_PTDUMP_CORE)	+= ptdump.o
 obj-$(CONFIG_PTDUMP_DEBUGFS)	+= ptdump_debugfs.o
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
new file mode 100644
index 000000000000..6d7f40667fa2
--- /dev/null
+++ b/arch/arm64/mm/contpte.c
@@ -0,0 +1,285 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+
+#include <linux/mm.h>
+#include <linux/efi.h>
+#include <linux/export.h>
+#include <asm/tlbflush.h>
+
+static inline bool mm_is_user(struct mm_struct *mm)
+{
+	/*
+	 * Don't attempt to apply the contig bit to kernel mappings, because
+	 * dynamically adding/removing the contig bit can cause page faults.
+	 * These racing faults are ok for user space, since they get serialized
+	 * on the PTL. But kernel mappings can't tolerate faults.
+	 */
+	if (unlikely(mm_is_efi(mm)))
+		return false;
+	return mm != &init_mm;
+}
+
+static inline pte_t *contpte_align_down(pte_t *ptep)
+{
+	return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
+}
+
+static void contpte_convert(struct mm_struct *mm, unsigned long addr,
+			    pte_t *ptep, pte_t pte)
+{
+	struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0);
+	unsigned long start_addr;
+	pte_t *start_ptep;
+	int i;
+
+	start_ptep = ptep = contpte_align_down(ptep);
+	start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+	pte = pfn_pte(ALIGN_DOWN(pte_pfn(pte), CONT_PTES), pte_pgprot(pte));
+
+	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) {
+		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
+
+		if (pte_dirty(ptent))
+			pte = pte_mkdirty(pte);
+
+		if (pte_young(ptent))
+			pte = pte_mkyoung(pte);
+	}
+
+	__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
+
+	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
+}
+
+void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
+			pte_t *ptep, pte_t pte)
+{
+	/*
+	 * We have already checked that the ptes are contiguous in
+	 * contpte_try_unfold(), so just check that the mm is user space.
+	 */
+	if (!mm_is_user(mm))
+		return;
+
+	pte = pte_mknoncont(pte);
+	contpte_convert(mm, addr, ptep, pte);
+}
+EXPORT_SYMBOL(__contpte_try_unfold);
+
+pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
+{
+	/*
+	 * Gather access/dirty bits, which may be populated in any of the ptes
+	 * of the contig range. We are guaranteed to be holding the PTL, so any
+	 * contiguous range cannot be unfolded or otherwise modified under our
+	 * feet.
+	 */
+
+	pte_t pte;
+	int i;
+
+	ptep = contpte_align_down(ptep);
+
+	for (i = 0; i < CONT_PTES; i++, ptep++) {
+		pte = __ptep_get(ptep);
+
+		if (pte_dirty(pte))
+			orig_pte = pte_mkdirty(orig_pte);
+
+		if (pte_young(pte))
+			orig_pte = pte_mkyoung(orig_pte);
+	}
+
+	return orig_pte;
+}
+EXPORT_SYMBOL(contpte_ptep_get);
+
+pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
+{
+	/*
+	 * Gather access/dirty bits, which may be populated in any of the ptes
+	 * of the contig range. We may not be holding the PTL, so any contiguous
+	 * range may be unfolded/modified/refolded under our feet. Therefore we
+	 * ensure we read a _consistent_ contpte range by checking that all ptes
+	 * in the range are valid and have CONT_PTE set, that all pfns are
+	 * contiguous and that all pgprots are the same (ignoring access/dirty).
+	 * If we find a pte that is not consistent, then we must be racing with
+	 * an update so start again. If the target pte does not have CONT_PTE
+	 * set then that is considered consistent on its own because it is not
+	 * part of a contpte range.
+	 */
+
+	pgprot_t orig_prot;
+	unsigned long pfn;
+	pte_t orig_pte;
+	pgprot_t prot;
+	pte_t *ptep;
+	pte_t pte;
+	int i;
+
+retry:
+	orig_pte = __ptep_get(orig_ptep);
+
+	if (!pte_valid_cont(orig_pte))
+		return orig_pte;
+
+	orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
+	ptep = contpte_align_down(orig_ptep);
+	pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
+
+	for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
+		pte = __ptep_get(ptep);
+		prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
+
+		if (!pte_valid_cont(pte) ||
+		   pte_pfn(pte) != pfn ||
+		   pgprot_val(prot) != pgprot_val(orig_prot))
+			goto retry;
+
+		if (pte_dirty(pte))
+			orig_pte = pte_mkdirty(orig_pte);
+
+		if (pte_young(pte))
+			orig_pte = pte_mkyoung(orig_pte);
+	}
+
+	return orig_pte;
+}
+EXPORT_SYMBOL(contpte_ptep_get_lockless);
+
+void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
+					pte_t *ptep, pte_t pte, unsigned int nr)
+{
+	unsigned long next;
+	unsigned long end;
+	unsigned long pfn;
+	pgprot_t prot;
+
+	/*
+	 * The set_ptes() spec guarantees that when nr > 1, the initial state of
+	 * all ptes is not-present. Therefore we never need to unfold or
+	 * otherwise invalidate a range before we set the new ptes.
+	 * contpte_set_ptes() should never be called for nr < 2.
+	 */
+	VM_WARN_ON(nr == 1);
+
+	if (!mm_is_user(mm))
+		return __set_ptes(mm, addr, ptep, pte, nr);
+
+	end = addr + (nr << PAGE_SHIFT);
+	pfn = pte_pfn(pte);
+	prot = pte_pgprot(pte);
+
+	do {
+		next = pte_cont_addr_end(addr, end);
+		nr = (next - addr) >> PAGE_SHIFT;
+		pte = pfn_pte(pfn, prot);
+
+		if (((addr | next | (pfn << PAGE_SHIFT)) & ~CONT_PTE_MASK) == 0)
+			pte = pte_mkcont(pte);
+		else
+			pte = pte_mknoncont(pte);
+
+		__set_ptes(mm, addr, ptep, pte, nr);
+
+		addr = next;
+		ptep += nr;
+		pfn += nr;
+
+	} while (addr != end);
+}
+EXPORT_SYMBOL(contpte_set_ptes);
+
+int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
+					unsigned long addr, pte_t *ptep)
+{
+	/*
+	 * ptep_clear_flush_young() technically requires us to clear the access
+	 * flag for a _single_ pte. However, the core-mm code actually tracks
+	 * access/dirty per folio, not per page. And since we only create a
+	 * contig range when the range is covered by a single folio, we can get
+	 * away with clearing young for the whole contig range here, so we avoid
+	 * having to unfold.
+	 */
+
+	int young = 0;
+	int i;
+
+	ptep = contpte_align_down(ptep);
+	addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+
+	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
+		young |= __ptep_test_and_clear_young(vma, addr, ptep);
+
+	return young;
+}
+EXPORT_SYMBOL(contpte_ptep_test_and_clear_young);
+
+int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
+					unsigned long addr, pte_t *ptep)
+{
+	int young;
+
+	young = contpte_ptep_test_and_clear_young(vma, addr, ptep);
+
+	if (young) {
+		/*
+		 * See comment in __ptep_clear_flush_young(); same rationale for
+		 * eliding the trailing DSB applies here.
+		 */
+		addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+		__flush_tlb_range_nosync(vma, addr, addr + CONT_PTE_SIZE,
+					 PAGE_SIZE, true, 3);
+	}
+
+	return young;
+}
+EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
+
+int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
+					unsigned long addr, pte_t *ptep,
+					pte_t entry, int dirty)
+{
+	unsigned long start_addr;
+	pte_t orig_pte;
+	int i;
+
+	/*
+	 * Gather the access/dirty bits for the contiguous range. If nothing has
+	 * changed, its a noop.
+	 */
+	orig_pte = pte_mknoncont(ptep_get(ptep));
+	if (pte_val(orig_pte) == pte_val(entry))
+		return 0;
+
+	/*
+	 * We can fix up access/dirty bits without having to unfold the contig
+	 * range. But if the write bit is changing, we must unfold.
+	 */
+	if (pte_write(orig_pte) == pte_write(entry)) {
+		/*
+		 * For HW access management, we technically only need to update
+		 * the flag on a single pte in the range. But for SW access
+		 * management, we need to update all the ptes to prevent extra
+		 * faults. Avoid per-page tlb flush in __ptep_set_access_flags()
+		 * and instead flush the whole range at the end.
+		 */
+		ptep = contpte_align_down(ptep);
+		start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+
+		for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
+			__ptep_set_access_flags(vma, addr, ptep, entry, 0);
+
+		if (dirty)
+			__flush_tlb_range(vma, start_addr, addr,
+							PAGE_SIZE, true, 3);
+	} else {
+		__contpte_try_unfold(vma->vm_mm, addr, ptep, orig_pte);
+		__ptep_set_access_flags(vma, addr, ptep, entry, dirty);
+	}
+
+	return 1;
+}
+EXPORT_SYMBOL(contpte_ptep_set_access_flags);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index c74f47711f0b..57da15e7429c 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -692,6 +692,11 @@ extern struct efi {
 
 extern struct mm_struct efi_mm;
 
+static inline bool mm_is_efi(struct mm_struct *mm)
+{
+	return IS_ENABLED(CONFIG_EFI) && mm == &efi_mm;
+}
+
 static inline int
 efi_guidcmp (efi_guid_t left, efi_guid_t right)
 {
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:32:00 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:32:00 +0000
Subject: [PATCH v6 13/18] arm64/mm: Implement new wrprotect_ptes() batch API
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-14-ryan.roberts@arm.com>

Optimize the contpte implementation to fix some of the fork performance
regression introduced by the initial contpte commit. Subsequent patches
will solve it entirely.

During fork(), any private memory in the parent must be write-protected.
Previously this was done 1 PTE at a time. But the core-mm supports
batched wrprotect via the new wrprotect_ptes() API. So let's implement
that API and for fully covered contpte mappings, we no longer need to
unfold the contpte. This has 2 benefits:

  - reduced unfolding, reduces the number of tlbis that must be issued.
  - The memory remains contpte-mapped ("folded") in the parent, so it
    continues to benefit from the more efficient use of the TLB after
    the fork.

The optimization to wrprotect a whole contpte block without unfolding is
possible thanks to the tightening of the Arm ARM in respect to the
definition and behaviour when 'Misprogramming the Contiguous bit'. See
section D21194 at https://developer.arm.com/documentation/102105/ja-07/

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 61 ++++++++++++++++++++++++++------
 arch/arm64/mm/contpte.c          | 38 ++++++++++++++++++++
 2 files changed, 89 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 831099cfc96b..8643227c318b 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -978,16 +978,12 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
-/*
- * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
- * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
- */
-static inline void __ptep_set_wrprotect(struct mm_struct *mm,
-					unsigned long address, pte_t *ptep)
+static inline void ___ptep_set_wrprotect(struct mm_struct *mm,
+					unsigned long address, pte_t *ptep,
+					pte_t pte)
 {
-	pte_t old_pte, pte;
+	pte_t old_pte;
 
-	pte = __ptep_get(ptep);
 	do {
 		old_pte = pte;
 		pte = pte_wrprotect(pte);
@@ -996,6 +992,25 @@ static inline void __ptep_set_wrprotect(struct mm_struct *mm,
 	} while (pte_val(pte) != pte_val(old_pte));
 }
 
+/*
+ * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
+ * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
+ */
+static inline void __ptep_set_wrprotect(struct mm_struct *mm,
+					unsigned long address, pte_t *ptep)
+{
+	___ptep_set_wrprotect(mm, address, ptep, __ptep_get(ptep));
+}
+
+static inline void __wrprotect_ptes(struct mm_struct *mm, unsigned long address,
+				pte_t *ptep, unsigned int nr)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr; i++, address += PAGE_SIZE, ptep++)
+		__ptep_set_wrprotect(mm, address, ptep);
+}
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_PMDP_SET_WRPROTECT
 static inline void pmdp_set_wrprotect(struct mm_struct *mm,
@@ -1149,6 +1164,8 @@ extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep);
 extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep);
+extern void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr);
 extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep,
 				pte_t entry, int dirty);
@@ -1268,12 +1285,35 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
 	return contpte_ptep_clear_flush_young(vma, addr, ptep);
 }
 
+#define wrprotect_ptes wrprotect_ptes
+static inline void wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr)
+{
+	if (likely(nr == 1)) {
+		/*
+		 * Optimization: wrprotect_ptes() can only be called for present
+		 * ptes so we only need to check contig bit as condition for
+		 * unfold, and we can remove the contig bit from the pte we read
+		 * to avoid re-reading. This speeds up fork() which is sensitive
+		 * for order-0 folios. Equivalent to contpte_try_unfold().
+		 */
+		pte_t orig_pte = __ptep_get(ptep);
+
+		if (unlikely(pte_cont(orig_pte))) {
+			__contpte_try_unfold(mm, addr, ptep, orig_pte);
+			orig_pte = pte_mknoncont(orig_pte);
+		}
+		___ptep_set_wrprotect(mm, addr, ptep, orig_pte);
+	} else {
+		contpte_wrprotect_ptes(mm, addr, ptep, nr);
+	}
+}
+
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 static inline void ptep_set_wrprotect(struct mm_struct *mm,
 				unsigned long addr, pte_t *ptep)
 {
-	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
-	__ptep_set_wrprotect(mm, addr, ptep);
+	wrprotect_ptes(mm, addr, ptep, 1);
 }
 
 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
@@ -1305,6 +1345,7 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
 #define ptep_clear_flush_young			__ptep_clear_flush_young
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 #define ptep_set_wrprotect			__ptep_set_wrprotect
+#define wrprotect_ptes				__wrprotect_ptes
 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags			__ptep_set_access_flags
 
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index 6d7f40667fa2..bedb58524535 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -26,6 +26,26 @@ static inline pte_t *contpte_align_down(pte_t *ptep)
 	return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
 }
 
+static void contpte_try_unfold_partial(struct mm_struct *mm, unsigned long addr,
+					pte_t *ptep, unsigned int nr)
+{
+	/*
+	 * Unfold any partially covered contpte block at the beginning and end
+	 * of the range.
+	 */
+
+	if (ptep != contpte_align_down(ptep) || nr < CONT_PTES)
+		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+
+	if (ptep + nr != contpte_align_down(ptep + nr)) {
+		unsigned long last_addr = addr + PAGE_SIZE * (nr - 1);
+		pte_t *last_ptep = ptep + nr - 1;
+
+		contpte_try_unfold(mm, last_addr, last_ptep,
+				   __ptep_get(last_ptep));
+	}
+}
+
 static void contpte_convert(struct mm_struct *mm, unsigned long addr,
 			    pte_t *ptep, pte_t pte)
 {
@@ -238,6 +258,24 @@ int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
 }
 EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
 
+void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
+					pte_t *ptep, unsigned int nr)
+{
+	/*
+	 * If wrprotecting an entire contig range, we can avoid unfolding. Just
+	 * set wrprotect and wait for the later mmu_gather flush to invalidate
+	 * the tlb. Until the flush, the page may or may not be wrprotected.
+	 * After the flush, it is guaranteed wrprotected. If it's a partial
+	 * range though, we must unfold, because we can't have a case where
+	 * CONT_PTE is set but wrprotect applies to a subset of the PTEs; this
+	 * would cause it to continue to be unpredictable after the flush.
+	 */
+
+	contpte_try_unfold_partial(mm, addr, ptep, nr);
+	__wrprotect_ptes(mm, addr, ptep, nr);
+}
+EXPORT_SYMBOL(contpte_wrprotect_ptes);
+
 int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
 					unsigned long addr, pte_t *ptep,
 					pte_t entry, int dirty)
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:32:01 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:32:01 +0000
Subject: [PATCH v6 14/18] arm64/mm: Implement new [get_and_]clear_full_ptes() batch APIs
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-15-ryan.roberts@arm.com>

Optimize the contpte implementation to fix some of the
exit/munmap/dontneed performance regression introduced by the initial
contpte commit. Subsequent patches will solve it entirely.

During exit(), munmap() or madvise(MADV_DONTNEED), mappings must be
cleared. Previously this was done 1 PTE at a time. But the core-mm
supports batched clear via the new [get_and_]clear_full_ptes() APIs. So
let's implement those APIs and for fully covered contpte mappings, we no
longer need to unfold the contpte. This significantly reduces unfolding
operations, reducing the number of tlbis that must be issued.

Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 67 ++++++++++++++++++++++++++++++++
 arch/arm64/mm/contpte.c          | 17 ++++++++
 2 files changed, 84 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 8643227c318b..a8f1a35e3086 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -965,6 +965,37 @@ static inline pte_t __ptep_get_and_clear(struct mm_struct *mm,
 	return pte;
 }
 
+static inline void __clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr, int full)
+{
+	for (;;) {
+		__ptep_get_and_clear(mm, addr, ptep);
+		if (--nr == 0)
+			break;
+		ptep++;
+		addr += PAGE_SIZE;
+	}
+}
+
+static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep,
+				unsigned int nr, int full)
+{
+	pte_t pte, tmp_pte;
+
+	pte = __ptep_get_and_clear(mm, addr, ptep);
+	while (--nr) {
+		ptep++;
+		addr += PAGE_SIZE;
+		tmp_pte = __ptep_get_and_clear(mm, addr, ptep);
+		if (pte_dirty(tmp_pte))
+			pte = pte_mkdirty(pte);
+		if (pte_young(tmp_pte))
+			pte = pte_mkyoung(pte);
+	}
+	return pte;
+}
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
 static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
@@ -1160,6 +1191,11 @@ extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
 extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
 extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
 				pte_t *ptep, pte_t pte, unsigned int nr);
+extern void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr, int full);
+extern pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep,
+				unsigned int nr, int full);
 extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep);
 extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
@@ -1253,6 +1289,35 @@ static inline void pte_clear(struct mm_struct *mm,
 	__pte_clear(mm, addr, ptep);
 }
 
+#define clear_full_ptes clear_full_ptes
+static inline void clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr, int full)
+{
+	if (likely(nr == 1)) {
+		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+		__clear_full_ptes(mm, addr, ptep, nr, full);
+	} else {
+		contpte_clear_full_ptes(mm, addr, ptep, nr, full);
+	}
+}
+
+#define get_and_clear_full_ptes get_and_clear_full_ptes
+static inline pte_t get_and_clear_full_ptes(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep,
+				unsigned int nr, int full)
+{
+	pte_t pte;
+
+	if (likely(nr == 1)) {
+		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+		pte = __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
+	} else {
+		pte = contpte_get_and_clear_full_ptes(mm, addr, ptep, nr, full);
+	}
+
+	return pte;
+}
+
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 				unsigned long addr, pte_t *ptep)
@@ -1337,6 +1402,8 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
 #define set_pte					__set_pte
 #define set_ptes				__set_ptes
 #define pte_clear				__pte_clear
+#define clear_full_ptes				__clear_full_ptes
+#define get_and_clear_full_ptes			__get_and_clear_full_ptes
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 #define ptep_get_and_clear			__ptep_get_and_clear
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index bedb58524535..50e0173dc5ee 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -212,6 +212,23 @@ void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
 }
 EXPORT_SYMBOL(contpte_set_ptes);
 
+void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, unsigned int nr, int full)
+{
+	contpte_try_unfold_partial(mm, addr, ptep, nr);
+	__clear_full_ptes(mm, addr, ptep, nr, full);
+}
+EXPORT_SYMBOL(contpte_clear_full_ptes);
+
+pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep,
+				unsigned int nr, int full)
+{
+	contpte_try_unfold_partial(mm, addr, ptep, nr);
+	return __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
+}
+EXPORT_SYMBOL(contpte_get_and_clear_full_ptes);
+
 int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
 					unsigned long addr, pte_t *ptep)
 {
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:32:02 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:32:02 +0000
Subject: [PATCH v6 15/18] mm: Add pte_batch_hint() to reduce scanning in folio_pte_batch()
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-16-ryan.roberts@arm.com>

Some architectures (e.g. arm64) can tell from looking at a pte, if some
follow-on ptes also map contiguous physical memory with the same pgprot.
(for arm64, these are contpte mappings).

Take advantage of this knowledge to optimize folio_pte_batch() so that
it can skip these ptes when scanning to create a batch. By default, if
an arch does not opt-in, folio_pte_batch() returns a compile-time 1, so
the changes are optimized out and the behaviour is as before.

arm64 will opt-in to providing this hint in the next patch, which will
greatly reduce the cost of ptep_get() when scanning a range of contptes.

Acked-by: David Hildenbrand <david at redhat.com>
Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 include/linux/pgtable.h | 21 +++++++++++++++++++++
 mm/memory.c             | 19 ++++++++++++-------
 2 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index bc005d84f764..a36cf4e124b0 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -212,6 +212,27 @@ static inline int pmd_dirty(pmd_t pmd)
 #define arch_flush_lazy_mmu_mode()	do {} while (0)
 #endif
 
+#ifndef pte_batch_hint
+/**
+ * pte_batch_hint - Number of pages that can be added to batch without scanning.
+ * @ptep: Page table pointer for the entry.
+ * @pte: Page table entry.
+ *
+ * Some architectures know that a set of contiguous ptes all map the same
+ * contiguous memory with the same permissions. In this case, it can provide a
+ * hint to aid pte batching without the core code needing to scan every pte.
+ *
+ * An architecture implementation may ignore the PTE accessed state. Further,
+ * the dirty state must apply atomically to all the PTEs described by the hint.
+ *
+ * May be overridden by the architecture, else pte_batch_hint is always 1.
+ */
+static inline unsigned int pte_batch_hint(pte_t *ptep, pte_t pte)
+{
+	return 1;
+}
+#endif
+
 #ifndef pte_advance_pfn
 static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
 {
diff --git a/mm/memory.c b/mm/memory.c
index 3b8e56eb08a3..4dd8e35b593a 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -988,16 +988,20 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
 {
 	unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio);
 	const pte_t *end_ptep = start_ptep + max_nr;
-	pte_t expected_pte = __pte_batch_clear_ignored(pte_next_pfn(pte), flags);
-	pte_t *ptep = start_ptep + 1;
+	pte_t expected_pte, *ptep;
 	bool writable;
+	int nr;
 
 	if (any_writable)
 		*any_writable = false;
 
 	VM_WARN_ON_FOLIO(!pte_present(pte), folio);
 
-	while (ptep != end_ptep) {
+	nr = pte_batch_hint(start_ptep, pte);
+	expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, nr), flags);
+	ptep = start_ptep + nr;
+
+	while (ptep < end_ptep) {
 		pte = ptep_get(ptep);
 		if (any_writable)
 			writable = !!pte_write(pte);
@@ -1011,17 +1015,18 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
 		 * corner cases the next PFN might fall into a different
 		 * folio.
 		 */
-		if (pte_pfn(pte) == folio_end_pfn)
+		if (pte_pfn(pte) >= folio_end_pfn)
 			break;
 
 		if (any_writable)
 			*any_writable |= writable;
 
-		expected_pte = pte_next_pfn(expected_pte);
-		ptep++;
+		nr = pte_batch_hint(ptep, pte);
+		expected_pte = pte_advance_pfn(expected_pte, nr);
+		ptep += nr;
 	}
 
-	return ptep - start_ptep;
+	return min(ptep - start_ptep, max_nr);
 }
 
 /*
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:32:04 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:32:04 +0000
Subject: [PATCH v6 17/18] arm64/mm: __always_inline to improve fork() perf
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-18-ryan.roberts@arm.com>

As set_ptes() and wrprotect_ptes() become a bit more complex, the
compiler may choose not to inline them. But this is critical for fork()
performance. So mark the functions, along with contpte_try_unfold()
which is called by them, as __always_inline. This is worth ~1% on the
fork() microbenchmark with order-0 folios (the common case).

Acked-by: Mark Rutland <mark.rutland at arm.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index d759a20d2929..8310875133ff 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1206,8 +1206,8 @@ extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep,
 				pte_t entry, int dirty);
 
-static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
-					pte_t *ptep, pte_t pte)
+static __always_inline void contpte_try_unfold(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep, pte_t pte)
 {
 	if (unlikely(pte_valid_cont(pte)))
 		__contpte_try_unfold(mm, addr, ptep, pte);
@@ -1278,7 +1278,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
 }
 
 #define set_ptes set_ptes
-static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
+static __always_inline void set_ptes(struct mm_struct *mm, unsigned long addr,
 				pte_t *ptep, pte_t pte, unsigned int nr)
 {
 	pte = pte_mknoncont(pte);
@@ -1360,8 +1360,8 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
 }
 
 #define wrprotect_ptes wrprotect_ptes
-static inline void wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
-				pte_t *ptep, unsigned int nr)
+static __always_inline void wrprotect_ptes(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep, unsigned int nr)
 {
 	if (likely(nr == 1)) {
 		/*
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:32:03 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:32:03 +0000
Subject: [PATCH v6 16/18] arm64/mm: Implement pte_batch_hint()
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-17-ryan.roberts@arm.com>

When core code iterates over a range of ptes and calls ptep_get() for
each of them, if the range happens to cover contpte mappings, the number
of pte reads becomes amplified by a factor of the number of PTEs in a
contpte block. This is because for each call to ptep_get(), the
implementation must read all of the ptes in the contpte block to which
it belongs to gather the access and dirty bits.

This causes a hotspot for fork(), as well as operations that unmap
memory such as munmap(), exit and madvise(MADV_DONTNEED). Fortunately we
can fix this by implementing pte_batch_hint() which allows their
iterators to skip getting the contpte tail ptes when gathering the batch
of ptes to operate on. This results in the number of PTE reads returning
to 1 per pte.

Acked-by: Mark Rutland <mark.rutland at arm.com>
Reviewed-by: David Hildenbrand <david at redhat.com>
Tested-by: John Hubbard <jhubbard at nvidia.com>
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index a8f1a35e3086..d759a20d2929 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1213,6 +1213,15 @@ static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
 		__contpte_try_unfold(mm, addr, ptep, pte);
 }
 
+#define pte_batch_hint pte_batch_hint
+static inline unsigned int pte_batch_hint(pte_t *ptep, pte_t pte)
+{
+	if (!pte_valid_cont(pte))
+		return 1;
+
+	return CONT_PTES - (((unsigned long)ptep >> 3) & (CONT_PTES - 1));
+}
+
 /*
  * The below functions constitute the public API that arm64 presents to the
  * core-mm to manipulate PTE entries within their page tables (or at least this
-- 
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 02:32:05 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 10:32:05 +0000
Subject: [PATCH v6 18/18] arm64/mm: Automatically fold contpte mappings
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <20240215103205.2607016-19-ryan.roberts@arm.com>

There are situations where a change to a single PTE could cause the
contpte block in which it resides to become foldable (i.e. could be
repainted with the contiguous bit). Such situations arise, for example,
when user space temporarily changes protections, via mprotect, for
individual pages, such can be the case for certain garbage collectors.

We would like to detect when such a PTE change occurs. However this can
be expensive due to the amount of checking required. Therefore only
perform the checks when an indiviual PTE is modified via mprotect
(ptep_modify_prot_commit() -> set_pte_at() -> set_ptes(nr=1)) and only
when we are setting the final PTE in a contpte-aligned block.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 26 +++++++++++++
 arch/arm64/mm/contpte.c          | 64 ++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 8310875133ff..401087e8a43d 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1185,6 +1185,8 @@ extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
  * where it is possible and makes sense to do so. The PTE_CONT bit is considered
  * a private implementation detail of the public ptep API (see below).
  */
+extern void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, pte_t pte);
 extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
 				pte_t *ptep, pte_t pte);
 extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
@@ -1206,6 +1208,29 @@ extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
 				unsigned long addr, pte_t *ptep,
 				pte_t entry, int dirty);
 
+static __always_inline void contpte_try_fold(struct mm_struct *mm,
+				unsigned long addr, pte_t *ptep, pte_t pte)
+{
+	/*
+	 * Only bother trying if both the virtual and physical addresses are
+	 * aligned and correspond to the last entry in a contig range. The core
+	 * code mostly modifies ranges from low to high, so this is the likely
+	 * the last modification in the contig range, so a good time to fold.
+	 * We can't fold special mappings, because there is no associated folio.
+	 */
+
+	const unsigned long contmask = CONT_PTES - 1;
+	bool valign = ((addr >> PAGE_SHIFT) & contmask) == contmask;
+
+	if (unlikely(valign)) {
+		bool palign = (pte_pfn(pte) & contmask) == contmask;
+
+		if (unlikely(palign &&
+		    pte_valid(pte) && !pte_cont(pte) && !pte_special(pte)))
+			__contpte_try_fold(mm, addr, ptep, pte);
+	}
+}
+
 static __always_inline void contpte_try_unfold(struct mm_struct *mm,
 				unsigned long addr, pte_t *ptep, pte_t pte)
 {
@@ -1286,6 +1311,7 @@ static __always_inline void set_ptes(struct mm_struct *mm, unsigned long addr,
 	if (likely(nr == 1)) {
 		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
 		__set_ptes(mm, addr, ptep, pte, 1);
+		contpte_try_fold(mm, addr, ptep, pte);
 	} else {
 		contpte_set_ptes(mm, addr, ptep, pte, nr);
 	}
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index 50e0173dc5ee..16788f07716d 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -73,6 +73,70 @@ static void contpte_convert(struct mm_struct *mm, unsigned long addr,
 	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
 }
 
+void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
+			pte_t *ptep, pte_t pte)
+{
+	/*
+	 * We have already checked that the virtual and pysical addresses are
+	 * correctly aligned for a contpte mapping in contpte_try_fold() so the
+	 * remaining checks are to ensure that the contpte range is fully
+	 * covered by a single folio, and ensure that all the ptes are valid
+	 * with contiguous PFNs and matching prots. We ignore the state of the
+	 * access and dirty bits for the purpose of deciding if its a contiguous
+	 * range; the folding process will generate a single contpte entry which
+	 * has a single access and dirty bit. Those 2 bits are the logical OR of
+	 * their respective bits in the constituent pte entries. In order to
+	 * ensure the contpte range is covered by a single folio, we must
+	 * recover the folio from the pfn, but special mappings don't have a
+	 * folio backing them. Fortunately contpte_try_fold() already checked
+	 * that the pte is not special - we never try to fold special mappings.
+	 * Note we can't use vm_normal_page() for this since we don't have the
+	 * vma.
+	 */
+
+	unsigned long folio_start, folio_end;
+	unsigned long cont_start, cont_end;
+	pte_t expected_pte, subpte;
+	struct folio *folio;
+	struct page *page;
+	unsigned long pfn;
+	pte_t *orig_ptep;
+	pgprot_t prot;
+
+	int i;
+
+	if (!mm_is_user(mm))
+		return;
+
+	page = pte_page(pte);
+	folio = page_folio(page);
+	folio_start = addr - (page - &folio->page) * PAGE_SIZE;
+	folio_end = folio_start + folio_nr_pages(folio) * PAGE_SIZE;
+	cont_start = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+	cont_end = cont_start + CONT_PTE_SIZE;
+
+	if (folio_start > cont_start || folio_end < cont_end)
+		return;
+
+	pfn = ALIGN_DOWN(pte_pfn(pte), CONT_PTES);
+	prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
+	expected_pte = pfn_pte(pfn, prot);
+	orig_ptep = ptep;
+	ptep = contpte_align_down(ptep);
+
+	for (i = 0; i < CONT_PTES; i++) {
+		subpte = pte_mkold(pte_mkclean(__ptep_get(ptep)));
+		if (!pte_same(subpte, expected_pte))
+			return;
+		expected_pte = pte_advance_pfn(expected_pte, 1);
+		ptep++;
+	}
+
+	pte = pte_mkcont(pte);
+	contpte_convert(mm, addr, orig_ptep, pte);
+}
+EXPORT_SYMBOL(__contpte_try_fold);
+
 void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
 			pte_t *ptep, pte_t pte)
 {
-- 
2.25.1



From quic_riteshk at quicinc.com  Thu Feb 15 02:39:29 2024
From: quic_riteshk at quicinc.com (Ritesh Kumar)
Date: Thu, 15 Feb 2024 16:09:29 +0530
Subject: [PATCH v3 2/2] arm64: dts: qcom: qcm6490-idp: add display and panel
In-Reply-To: <20240215103929.19357-1-quic_riteshk@quicinc.com>
References: <20240215103929.19357-1-quic_riteshk@quicinc.com>
Message-ID: <20240215103929.19357-3-quic_riteshk@quicinc.com>

Enable Display Subsystem with Novatek NT36672E Panel
on qcm6490 idp platform.

Signed-off-by: Ritesh Kumar <quic_riteshk at quicinc.com>

---
v2: Fixed review comments from Dmitry and Konrad
      - moved pinctrl-names after pinctrl-0 property.
      - removed gpu disablement change after validating gpu.
    Rebased the patch
      - rebased the patch to resolve conflicts.
v3: Fixed review comments from Dmitry
      - renamed panel supply to regulator-lcd-disp-bias.
      - moved backlight as per sort order.
---
 arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 92 ++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
index 502a5a383bde..6d6506726827 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
+++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
@@ -10,6 +10,7 @@
 #define PM7250B_SID1 9
 
 #include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 #include "sc7280.dtsi"
 #include "pm7250b.dtsi"
@@ -35,10 +36,29 @@
 		serial0 = &uart5;
 	};
 
+	pm8350c_pwm_backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pm8350c_pwm 3 65535>;
+		enable-gpios = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&pmic_lcd_bl_en>;
+		pinctrl-names = "default";
+	};
+
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
+	lcd_disp_bias: regulator-lcd-disp-bias {
+		compatible = "regulator-fixed";
+		regulator-name = "lcd_disp_bias";
+		regulator-min-microvolt = <5500000>;
+		regulator-max-microvolt = <5500000>;
+		gpio = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		pinctrl-0 = <&lcd_disp_bias_en>;
+		pinctrl-names = "default";
+	};
+
 	reserved-memory {
 		xbl_mem: xbl at 80700000 {
 			reg = <0x0 0x80700000 0x0 0x100000>;
@@ -421,7 +441,79 @@
 	};
 };
 
+&mdss {
+	status = "okay";
+};
+
+&mdss_dsi {
+	vdda-supply = <&vreg_l6b_1p2>;
+	status = "okay";
+
+	panel at 0 {
+		compatible = "novatek,nt36672e";
+		reg = <0>;
+
+		reset-gpios = <&tlmm 44 GPIO_ACTIVE_HIGH>;
+
+		vddi-supply = <&vreg_l8c_1p62>;
+		avdd-supply = <&lcd_disp_bias>;
+		avee-supply = <&lcd_disp_bias>;
+
+		backlight = <&pm8350c_pwm_backlight>;
+
+		port {
+			panel0_in: endpoint {
+				remote-endpoint = <&mdss_dsi0_out>;
+			};
+		};
+	};
+};
+
+&mdss_dsi0_out {
+	remote-endpoint = <&panel0_in>;
+	data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi_phy {
+	vdds-supply = <&vreg_l10c_0p88>;
+	status = "okay";
+};
+
+&pm7250b_gpios {
+	lcd_disp_bias_en: lcd-disp-bias-en-state {
+		pins = "gpio2";
+		function = "func1";
+		bias-disable;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+		input-disable;
+		output-enable;
+		power-source = <0>;
+	};
+};
+
+&pm8350c_gpios {
+	pmic_lcd_bl_en: pmic-lcd-bl-en-state {
+		pins = "gpio7";
+		function = "normal";
+		bias-disable;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+		output-low;
+		power-source = <0>;
+	};
+
+	pmic_lcd_bl_pwm: pmic-lcd-bl-pwm-state {
+		pins = "gpio8";
+		function = "func1";
+		bias-disable;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+		output-low;
+		power-source = <0>;
+	};
+};
+
 &pm8350c_pwm {
+	pinctrl-0 = <&pmic_lcd_bl_pwm>;
+	pinctrl-names = "default";
 	status = "okay";
 
 	multi-led {
-- 
2.17.1



From quic_riteshk at quicinc.com  Thu Feb 15 02:39:27 2024
From: quic_riteshk at quicinc.com (Ritesh Kumar)
Date: Thu, 15 Feb 2024 16:09:27 +0530
Subject: [PATCH v3 0/2] add display and panel on qcm6490 idp
Message-ID: <20240215103929.19357-1-quic_riteshk@quicinc.com>

Build the Novatek NT36672E DSI Panel driver as module and enable
display subsystem on Qualcomm qcm6490 idp board.

---
This series depends on following series:
1. https://lore.kernel.org/all/20231222073135.2512313-1-quic_uchheda at quicinc.com/
   (arm64: dts: qcom: qcm6490-idp: Add support for PM7250B PMIC)
2. https://lore.kernel.org/all/20240108095902.22725-1-quic_riteshk at quicinc.com/
   (Add support for Novatek NT36672E LCD DSI panel)
3. https://lore.kernel.org/all/20240116071803.5264-1-quic_riteshk at quicinc.com/t/#u
   (drm/panel: novatek-nt36672e: Include <linux/of.h>)

v2: Fixed review comments from Dmitry and Konrad
      - moved pinctrl-names after pinctrl-0 property.
      - removed gpu disablement change after validating gpu.
      - updated commit text.
    Rebased the patch
      - rebased the patch to resolve conflicts.
v3: Fixed review comments from Dmitry
      - renamed panel supply to regulator-lcd-disp-bias.
      - moved backlight as per sort order.
---

Ritesh Kumar (2):
  arm64: defconfig: enable Novatek NT36672E DSI Panel driver
  arm64: dts: qcom: qcm6490-idp: add display and panel

 arch/arm64/boot/dts/qcom/qcm6490-idp.dts | 92 ++++++++++++++++++++++++
 arch/arm64/configs/defconfig             |  1 +
 2 files changed, 93 insertions(+)

-- 
2.17.1



From quic_riteshk at quicinc.com  Thu Feb 15 02:39:28 2024
From: quic_riteshk at quicinc.com (Ritesh Kumar)
Date: Thu, 15 Feb 2024 16:09:28 +0530
Subject: [PATCH v3 1/2] arm64: defconfig: enable Novatek NT36672E DSI Panel driver
In-Reply-To: <20240215103929.19357-1-quic_riteshk@quicinc.com>
References: <20240215103929.19357-1-quic_riteshk@quicinc.com>
Message-ID: <20240215103929.19357-2-quic_riteshk@quicinc.com>

Build the Novatek NT36672E DSI Panel driver as module
because it is used on Qualcomm qcm6490 idp board.

Signed-off-by: Ritesh Kumar <quic_riteshk at quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

---
v2: Fixed review comment from Dmitry
      - updated commit text.
v3: No change
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index b8adb28185ad..e1f0045a65de 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -863,6 +863,7 @@ CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_PANEL_EDP=m
 CONFIG_DRM_PANEL_ILITEK_ILI9882T=m
 CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
+CONFIG_DRM_PANEL_NOVATEK_NT36672E=m
 CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
 CONFIG_DRM_PANEL_SITRONIX_ST7703=m
 CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
-- 
2.17.1



From angelogioacchino.delregno at collabora.com  Thu Feb 15 02:40:35 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 11:40:35 +0100
Subject: [PATCH 1/9] soc: mediatek: cmdq: Remove unused helper funciton
In-Reply-To: <20240215004931.3808-2-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
 <20240215004931.3808-2-chunkuang.hu@kernel.org>
Message-ID: <c87af05e-9017-4806-88b1-7aa65f2b7070@collabora.com>

Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> cmdq_pkt_create(), cmdq_pkt_destroy(), and cmdq_pkt_flush_async()
> are not used by all client drivers (MediaTek drm driver and
> MediaTek mdp3 driver),
> 

Hello CK,

We can technically force the hand to say that this is true - but only because
these two functions are copy-pasted in both mediatek-drm and MDP3 drivers with
no meaningful changes, as in, the only change is that `pkt` is supposed to be
preallocated in both of the variants, while the one in mtk-cmdq-helper allocates
it on its own.

Code duplication is something that we want to avoid, not something that we want
to embrace: removing those functions from cmdq-helper with the plan to keep
duplicating them in each MediaTek driver that uses CMDQ packets is plain wrong.

This - especially because I'm sure that we will see yet another copy-paste of
those two functions in a future ISP driver, bringing the duplication count to
3 (or actually, 3 by 2 functions = 6 times).

On the other hand, removing the cmdq_pkt_flush_async() function is something
that I *do* support, as it's only doing two simple calls that are not even
specific to cmdq, but more like "generic stuff".

In short, as it is right now, this is a NACK - but if you change this commit to
remove only cmdq_pkt_flush_async() I would agree.

The right thing to do is to remove the duplicated functions:
  - mtk_drm_cmdq_pkt_create()
  - mtk_drm_cmdq_pkt_destroy()
  - mdp_cmdq_pkt_create()
  - mdp_cmdq_pkt_destroy()

...and migrate both drivers to use the common cmdq helper code instea, but that's
something that can come later.

For now, you can simply perform the ->cl removal on all duplicated functions, then
we can migrate them all to the common helper, removing duplication all along.

Regards,
Angelo

> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> ---
>   drivers/soc/mediatek/mtk-cmdq-helper.c | 59 --------------------------
>   include/linux/soc/mediatek/mtk-cmdq.h  | 40 -----------------
>   2 files changed, 99 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index b0cd071c4719..67e17974d1e6 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -105,50 +105,6 @@ void cmdq_mbox_destroy(struct cmdq_client *client)
>   }
>   EXPORT_SYMBOL(cmdq_mbox_destroy);
>   
> -struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
> -{
> -	struct cmdq_pkt *pkt;
> -	struct device *dev;
> -	dma_addr_t dma_addr;
> -
> -	pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
> -	if (!pkt)
> -		return ERR_PTR(-ENOMEM);
> -	pkt->va_base = kzalloc(size, GFP_KERNEL);
> -	if (!pkt->va_base) {
> -		kfree(pkt);
> -		return ERR_PTR(-ENOMEM);
> -	}
> -	pkt->buf_size = size;
> -	pkt->cl = (void *)client;
> -
> -	dev = client->chan->mbox->dev;
> -	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
> -				  DMA_TO_DEVICE);
> -	if (dma_mapping_error(dev, dma_addr)) {
> -		dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
> -		kfree(pkt->va_base);
> -		kfree(pkt);
> -		return ERR_PTR(-ENOMEM);
> -	}
> -
> -	pkt->pa_base = dma_addr;
> -
> -	return pkt;
> -}
> -EXPORT_SYMBOL(cmdq_pkt_create);
> -
> -void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
> -{
> -	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
> -
> -	dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
> -			 DMA_TO_DEVICE);
> -	kfree(pkt->va_base);
> -	kfree(pkt);
> -}
> -EXPORT_SYMBOL(cmdq_pkt_destroy);
> -
>   static int cmdq_pkt_append_command(struct cmdq_pkt *pkt,
>   				   struct cmdq_instruction inst)
>   {
> @@ -426,19 +382,4 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
>   }
>   EXPORT_SYMBOL(cmdq_pkt_finalize);
>   
> -int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
> -{
> -	int err;
> -	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
> -
> -	err = mbox_send_message(client->chan, pkt);
> -	if (err < 0)
> -		return err;
> -	/* We can send next packet immediately, so just call txdone. */
> -	mbox_client_txdone(client->chan, 0);
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL(cmdq_pkt_flush_async);
> -
>   MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> index 649955d2cf5c..6c42d817d368 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -59,21 +59,6 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, int index);
>    */
>   void cmdq_mbox_destroy(struct cmdq_client *client);
>   
> -/**
> - * cmdq_pkt_create() - create a CMDQ packet
> - * @client:	the CMDQ mailbox client
> - * @size:	required CMDQ buffer size
> - *
> - * Return: CMDQ packet pointer
> - */
> -struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size);
> -
> -/**
> - * cmdq_pkt_destroy() - destroy the CMDQ packet
> - * @pkt:	the CMDQ packet
> - */
> -void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
> -
>   /**
>    * cmdq_pkt_write() - append write command to the CMDQ packet
>    * @pkt:	the CMDQ packet
> @@ -266,19 +251,6 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
>    */
>   int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
>   
> -/**
> - * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
> - *                          packet and call back at the end of done packet
> - * @pkt:	the CMDQ packet
> - *
> - * Return: 0 for success; else the error code is returned
> - *
> - * Trigger CMDQ to asynchronously execute the CMDQ packet and call back
> - * at the end of done packet. Note that this is an ASYNC function. When the
> - * function returned, it may or may not be finished.
> - */
> -int cmdq_pkt_flush_async(struct cmdq_pkt *pkt);
> -
>   #else /* IS_ENABLED(CONFIG_MTK_CMDQ) */
>   
>   static inline int cmdq_dev_get_client_reg(struct device *dev,
> @@ -294,13 +266,6 @@ static inline struct cmdq_client *cmdq_mbox_create(struct device *dev, int index
>   
>   static inline void cmdq_mbox_destroy(struct cmdq_client *client) { }
>   
> -static inline  struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
> -{
> -	return ERR_PTR(-EINVAL);
> -}
> -
> -static inline void cmdq_pkt_destroy(struct cmdq_pkt *pkt) { }
> -
>   static inline int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
>   {
>   	return -ENOENT;
> @@ -384,11 +349,6 @@ static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
>   	return -EINVAL;
>   }
>   
> -static inline int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
> -{
> -	return -EINVAL;
> -}
> -
>   #endif /* IS_ENABLED(CONFIG_MTK_CMDQ) */
>   
>   #endif	/* __MTK_CMDQ_H__ */



From angelogioacchino.delregno at collabora.com  Thu Feb 15 02:40:38 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 11:40:38 +0100
Subject: [PATCH 5/9] drm/mediatek: Drop calling cmdq_pkt_finalize()
In-Reply-To: <20240215004931.3808-6-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
 <20240215004931.3808-6-chunkuang.hu@kernel.org>
Message-ID: <8f34e44c-48d7-43b4-ae6a-827d4e3fa122@collabora.com>

Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> For some client driver, it want to reduce latency between excuting
> previous packet command and next packet command, so append jump
> command to the end of previous packet and the jump destination
> address is the start address of next packet command buffer. Before
> next packet exist, the previous packet has no information of where
> to jump to, so append nop command first. When next packet exist,
> change nop command to jump command. For mediatek drm driver, it
> never has next packet, so appending nop command is redundant.
> Because cmdq_pkt_finalize() would append nop command, so change
> calling cmdq_pkt_finalize() to cmdq_pkt_eoc() to prevent append
> redundant nop command.
> 
> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

Makes sense.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Thu Feb 15 02:40:40 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 11:40:40 +0100
Subject: [PATCH 8/9] drm/mediatek: Do not store struct cmdq_client in
 struct cmdq_pkt
In-Reply-To: <20240215004931.3808-9-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
 <20240215004931.3808-9-chunkuang.hu@kernel.org>
Message-ID: <602e4364-c65a-4a32-a411-444a40a5c1d7@collabora.com>

Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> MediaTek drm driver has the struct cmdq_client information, so
> it's not necessary to store this information in struct cmdq_pkt.
> 
> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

As said in patch [1/9], this should be done in the common function, not in each
copy-pasted function in mtk_drm and mtk-mdp3.

Regards,
Angelo



From angelogioacchino.delregno at collabora.com  Thu Feb 15 02:40:43 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 11:40:43 +0100
Subject: [PATCH 3/9] soc: mediatek: cmdq: Add cmdq_pkt_eoc() helper
 function
In-Reply-To: <20240215004931.3808-4-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
 <20240215004931.3808-4-chunkuang.hu@kernel.org>
Message-ID: <1821c17e-6a40-4d1a-bc5a-06e8dd944456@collabora.com>

Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> cmdq_pkt_eoc() append eoc command to CMDQ packet. eoc command
> would ask GCE to generate IRQ. It's usually appended to the end
> of packet to notify all command in the packet is done.
> 
> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> ---
>   drivers/soc/mediatek/mtk-cmdq-helper.c | 10 ++++++++++
>   include/linux/soc/mediatek/mtk-cmdq.h  | 15 +++++++++++++++
>   2 files changed, 25 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index ed4ef95adf5b..e982997117c2 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -359,6 +359,16 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
>   }
>   EXPORT_SYMBOL(cmdq_pkt_jump);
>   
> +int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
> +{
> +	struct cmdq_instruction inst = { {0} };
> +
> +	inst.op = CMDQ_CODE_EOC;
> +	inst.value = CMDQ_EOC_IRQ_EN;
> +	return cmdq_pkt_append_command(pkt, inst);
> +}
> +EXPORT_SYMBOL(cmdq_pkt_eoc);
> +
>   int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
>   {
>   	struct cmdq_instruction inst = { {0} };
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> index 6215191a328d..a67f719dec0b 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -245,6 +245,16 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
>    */
>   int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
>   
> +/**
> + * cmdq_pkt_eoc() - Append eoc command to the CMDQ packet, ask GCE
> + *		    to generate IRQ. It's usually appended to the end of
> + *		    packet to notify that all command in the packet is done.
> + * @pkt:	the CMDQ packet
> + *
> + * Return: 0 for success; else the error code is returned

/**
  * cmdq_pkt_eoc() - Append EOC and ask GCE to generate an IRQ at end of execution
  * @pkt:	The CMDQ packet
  *
  * Appends an End Of Code (EOC) command to the CMDQ packet and asks the GCE
  * to generate an interrupt at the end of the execution of all commands in
  * the pipeline.
  * The EOC command is usually appended to the end of the pipeline to notify
  * that all commands are done.
  *
  * Return: 0 for success or negative error number
  */

Apart from that,

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> + */
> +int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
> +
>   /**
>    * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
>    * @pkt:	the CMDQ packet
> @@ -346,6 +356,11 @@ static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_
>   	return -EINVAL;
>   }
>   
> +static inline int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
> +{
> +	return -EINVAL;
> +}
> +
>   static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
>   {
>   	return -EINVAL;



From angelogioacchino.delregno at collabora.com  Thu Feb 15 02:40:47 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 11:40:47 +0100
Subject: [PATCH 4/9] soc: mediatek: cmdq: Add cmdq_pkt_nop() helper
 function
In-Reply-To: <20240215004931.3808-5-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
 <20240215004931.3808-5-chunkuang.hu@kernel.org>
Message-ID: <680fcb9a-d7e2-4a15-877e-09c01024ed53@collabora.com>

Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> cmdq_pkt_nop() append nop command to the packet. nop command ask
> GCE to do no operation.
> 
> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> ---
>   drivers/soc/mediatek/mtk-cmdq-helper.c | 11 +++++++++++
>   include/linux/soc/mediatek/mtk-cmdq.h  | 16 ++++++++++++++++
>   2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index e982997117c2..1be950b4ec7f 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -369,6 +369,17 @@ int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
>   }
>   EXPORT_SYMBOL(cmdq_pkt_eoc);
>   
> +int cmdq_pkt_nop(struct cmdq_pkt *pkt, u8 shift_pa)
> +{
> +	struct cmdq_instruction inst = { {0} };
> +
> +	/* Jumping to next instruction is equal to no operation */
> +	inst.op = CMDQ_CODE_JUMP;
> +	inst.value = CMDQ_INST_SIZE >> shift_pa;
> +	return cmdq_pkt_append_command(pkt, inst);
> +}
> +EXPORT_SYMBOL(cmdq_pkt_nop);
> +
>   int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
>   {
>   	struct cmdq_instruction inst = { {0} };
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> index a67f719dec0b..8179ba5238f9 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -255,6 +255,17 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
>    */
>   int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
>   
> +/**
> + * cmdq_pkt_nop() - Append nop command to the CMDQ packet, ask GCE
> + *		    to do no operation.

  * cmdq_pkt_nop() - Append No-Operation (NOP) command to a CMDQ packet

After which...
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Thu Feb 15 02:40:52 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 11:40:52 +0100
Subject: [PATCH 2/9] soc: mediatek: cmdq: Add parameter shift_pa to
 cmdq_pkt_jump()
In-Reply-To: <20240215004931.3808-3-chunkuang.hu@kernel.org>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
 <20240215004931.3808-3-chunkuang.hu@kernel.org>
Message-ID: <21d17701-e40b-49c5-bf16-5e70a6daa2c4@collabora.com>

Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> In original design, cmdq_pkt_jump() call cmdq_get_shift_pa() every
> time to get shift_pa. But the shift_pa is constant value for each
> SoC, so client driver just need to call cmdq_get_shift_pa() once
> and pass shift_pa to cmdq_pkt_jump() to prevent frequent function
> call.
> 

As far as I understand, the CMDQ supports both relative and absolute jumps, right?

Here's my proposal:
  - Add a new function cmdq_pkt_jump_rel() or cmdq_pkt_jump_relative()
    * note: I prefer "rel", as maybe in a future we'll get a jump_abs function? :-)
  - Don't touch the cmdq_pkt_jump() function for one cycle
    - Migrate mediatek-drm to use cmdq_pkt_jump_rel()
  - Remove cmdq_pkt_jump() in the next cycle.

What do you think?

Regards,
Angelo

> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> ---
>   drivers/soc/mediatek/mtk-cmdq-helper.c | 5 ++---
>   include/linux/soc/mediatek/mtk-cmdq.h  | 6 ++++--
>   2 files changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index 67e17974d1e6..ed4ef95adf5b 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -348,14 +348,13 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
>   }
>   EXPORT_SYMBOL(cmdq_pkt_assign);
>   
> -int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
> +int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
>   {
>   	struct cmdq_instruction inst = {};
>   
>   	inst.op = CMDQ_CODE_JUMP;
>   	inst.offset = CMDQ_JUMP_RELATIVE;
> -	inst.value = addr >>
> -		cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
> +	inst.value = addr >> shift_pa;
>   	return cmdq_pkt_append_command(pkt, inst);
>   }
>   EXPORT_SYMBOL(cmdq_pkt_jump);
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> index 6c42d817d368..6215191a328d 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -238,10 +238,12 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
>    *		     a physical address which should contains more instruction.
>    * @pkt:        the CMDQ packet
>    * @addr:       physical address of target instruction buffer
> + * @shift_pa:	shift bits of physical address in CMDQ instruction. This value
> + *		is got by cmdq_get_shift_pa().
>    *
>    * Return: 0 for success; else the error code is returned
>    */
> -int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
> +int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
>   
>   /**
>    * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
> @@ -339,7 +341,7 @@ static inline int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
>   	return -EINVAL;
>   }
>   
> -static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
> +static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
>   {
>   	return -EINVAL;
>   }





From david at redhat.com  Thu Feb 15 02:40:49 2024
From: david at redhat.com (David Hildenbrand)
Date: Thu, 15 Feb 2024 11:40:49 +0100
Subject: [PATCH v6 03/18] mm: Introduce pte_advance_pfn() and use for
 pte_next_pfn()
In-Reply-To: <20240215103205.2607016-4-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-4-ryan.roberts@arm.com>
Message-ID: <3dd9a4b1-d912-4a92-9450-97ca816a267b@redhat.com>

On 15.02.24 11:31, Ryan Roberts wrote:
> The goal is to be able to advance a PTE by an arbitrary number of PFNs.
> So introduce a new API that takes a nr param. Define the default
> implementation here and allow for architectures to override.
> pte_next_pfn() becomes a wrapper around pte_advance_pfn().
> 
> Follow up commits will convert each overriding architecture's
> pte_next_pfn() to pte_advance_pfn().
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>   include/linux/pgtable.h | 9 ++++++---
>   1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 231370e1b80f..b7ac8358f2aa 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -212,14 +212,17 @@ static inline int pmd_dirty(pmd_t pmd)
>   #define arch_flush_lazy_mmu_mode()	do {} while (0)
>   #endif
>   
> -
>   #ifndef pte_next_pfn
> -static inline pte_t pte_next_pfn(pte_t pte)
> +#ifndef pte_advance_pfn
> +static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>   {
> -	return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
> +	return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
>   }
>   #endif
>   
> +#define pte_next_pfn(pte) pte_advance_pfn(pte, 1)
> +#endif
> +
>   #ifndef set_ptes
>   /**
>    * set_ptes - Map consecutive pages to a contiguous range of addresses.

Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From david at redhat.com  Thu Feb 15 02:42:26 2024
From: david at redhat.com (David Hildenbrand)
Date: Thu, 15 Feb 2024 11:42:26 +0100
Subject: [PATCH v6 04/18] arm64/mm: Convert pte_next_pfn() to
 pte_advance_pfn()
In-Reply-To: <20240215103205.2607016-5-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-5-ryan.roberts@arm.com>
Message-ID: <e9ce88d6-0e2e-4b8b-825a-bcb85180e21d@redhat.com>

On 15.02.24 11:31, Ryan Roberts wrote:
> Core-mm needs to be able to advance the pfn by an arbitrary amount, so
> override the new pte_advance_pfn() API to do so.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>   arch/arm64/include/asm/pgtable.h | 8 ++++----
>   1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 52d0b0a763f1..b6d3e9e0a946 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -351,10 +351,10 @@ static inline pgprot_t pte_pgprot(pte_t pte)
>   	return __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte));
>   }
>   
> -#define pte_next_pfn pte_next_pfn
> -static inline pte_t pte_next_pfn(pte_t pte)
> +#define pte_advance_pfn pte_advance_pfn
> +static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>   {
> -	return pfn_pte(pte_pfn(pte) + 1, pte_pgprot(pte));
> +	return pfn_pte(pte_pfn(pte) + nr, pte_pgprot(pte));
>   }
>   
>   static inline void set_ptes(struct mm_struct *mm,
> @@ -370,7 +370,7 @@ static inline void set_ptes(struct mm_struct *mm,
>   		if (--nr == 0)
>   			break;
>   		ptep++;
> -		pte = pte_next_pfn(pte);
> +		pte = pte_advance_pfn(pte, 1);


Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From david at redhat.com  Thu Feb 15 02:43:01 2024
From: david at redhat.com (David Hildenbrand)
Date: Thu, 15 Feb 2024 11:43:01 +0100
Subject: [PATCH v6 05/18] x86/mm: Convert pte_next_pfn() to
 pte_advance_pfn()
In-Reply-To: <20240215103205.2607016-6-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-6-ryan.roberts@arm.com>
Message-ID: <6ff877c4-dc97-4572-b45c-2384c1d40fba@redhat.com>

On 15.02.24 11:31, Ryan Roberts wrote:
> Core-mm needs to be able to advance the pfn by an arbitrary amount, so
> override the new pte_advance_pfn() API to do so.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>   arch/x86/include/asm/pgtable.h | 8 ++++----
>   1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
> index b50b2ef63672..69ed0ea0641b 100644
> --- a/arch/x86/include/asm/pgtable.h
> +++ b/arch/x86/include/asm/pgtable.h
> @@ -955,13 +955,13 @@ static inline int pte_same(pte_t a, pte_t b)
>   	return a.pte == b.pte;
>   }
>   
> -static inline pte_t pte_next_pfn(pte_t pte)
> +static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>   {
>   	if (__pte_needs_invert(pte_val(pte)))
> -		return __pte(pte_val(pte) - (1UL << PFN_PTE_SHIFT));
> -	return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
> +		return __pte(pte_val(pte) - (nr << PFN_PTE_SHIFT));
> +	return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
>   }
> -#define pte_next_pfn	pte_next_pfn
> +#define pte_advance_pfn	pte_advance_pfn
>   
>   static inline int pte_present(pte_t a)
>   {

Reviewed-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From avromanov at salutedevices.com  Thu Feb 15 02:43:09 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Thu, 15 Feb 2024 10:43:09 +0000
Subject: [PATCH v4 00/20] Support more Amlogic SoC families in crypto
 driver
In-Reply-To: <ZcsYaPIUrBSg8iXu@Red>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <ZcsYaPIUrBSg8iXu@Red>
Message-ID: <20240215104251.pcqj532ekhq5dfbt@cab-wsm-0029881.sigma.sbrf.ru>

Hello,

On Tue, Feb 13, 2024 at 08:21:12AM +0100, Corentin Labbe wrote:
> Le Mon, Feb 12, 2024 at 04:50:48PM +0300, Alexey Romanov a 'ecrit :
> > Hello!
> > 
> > This patchset expand the funcionality of the Amlogic
> > crypto driver by adding support for more SoC families:
> > AXG, G12A, G12B, SM1, A1, S4.
> > 
> > Also specify and enable crypto node in device tree
> > for reference Amlogic devices.
> > 
> > Tested on AXG, G12A/B, SM1, A1 and S4 devices via
> > custom tests [1] and tcrypt module.
> > 
> > ---
> > 
> 
> I started to test on Lepotato board and added patchs up to  "drivers: crypto: meson: process more than MAXDESCS descriptors"
> booting lead to:

Can you please give me your test cases?
Which tool are you using or is it something custom?

> [   18.559922] gxl-crypto c883e000.crypto: will run requests pump with realtime priority
> [   18.562492] gxl-crypto c883e000.crypto: will run requests pump with realtime priority
> [   18.570328] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
> [   18.581135] Mem abort info:
> [   18.581354]   ESR = 0x0000000096000006
> [   18.585138]   EC = 0x25: DABT (current EL), IL = 32 bits
> [   18.593005]   SET = 0, FnV = 0
> [   18.593334]   EA = 0, S1PTW = 0
> [   18.597329]   FSC = 0x06: level 2 translation fault
> [   18.604250] Data abort info:
> [   18.604282]   ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
> [   18.612243]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> [   18.614552]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> [   18.624249] user pgtable: 4k pages, 48-bit VAs, pgdp=000000007b8ab000
> [   18.626196] [0000000000000028] pgd=080000007b8ac003, p4d=080000007b8ac003, pud=080000007b8ad003, pmd=0000000000000000
> [   18.640426] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
> [   18.642929] Modules linked in: of_mdio fixed_phy fwnode_mdio sm4_ce(-) sm4 meson_rng meson_canvas libphy rng_core meson_gxbb_wdt watchdog amlogic_gxl_crypto(+) ghash_generic gcm xctr xts cts essiv authenc cmac xcbc ccm
> [   18.662164] CPU: 3 PID: 264 Comm: cryptomgr_test Not tainted 6.8.0-rc1-00052-gf70f2b0814a0 #11
> [   18.670698] Hardware name: Libre Computer AML-S905X-CC (DT)
> [   18.676220] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [   18.683118] pc : meson_get_engine_number+0x2c/0x50 [amlogic_gxl_crypto]
> [   18.689674] lr : meson_skencrypt+0x38/0x8c [amlogic_gxl_crypto]
> [   18.695539] sp : ffff800081393790
> [   18.698816] x29: ffff800081393790 x28: 0000000000000400 x27: ffff800080874a80
> [   18.705888] x26: ffff800081393830 x25: ffff800081393bd8 x24: ffff000001aaa000
> [   18.712961] x23: 0000000000000001 x22: 0000000000000000 x21: ffff0000011b1c50
> [   18.720033] x20: ffff00007bac8248 x19: ffff0000011b1c00 x18: ffffffffffffffff
> [   18.727105] x17: 00000000000001a4 x16: ffff800078edc1f0 x15: ffff8000813938e0
> [   18.734178] x14: ffff800101393bd7 x13: 0000000000000000 x12: 0000000000000000
> [   18.741250] x11: 000000000000021c x10: fffffffff81213e0 x9 : 00000000000730d5
> [   18.748323] x8 : ffff0000011b1ca8 x7 : fefefefefefefefe x6 : fffffc000007a302
> [   18.755395] x5 : ffff800078eb4148 x4 : 0000000000000000 x3 : 0000000000000028
> [   18.762468] x2 : ffff000001aaa040 x1 : 0000000000000000 x0 : 0000000000000000
> [   18.769541] Call trace:
> [   18.771956]  meson_get_engine_number+0x2c/0x50 [amlogic_gxl_crypto]
> [   18.778167]  crypto_skcipher_encrypt+0xe0/0x124
> [   18.782651]  test_skcipher_vec_cfg+0x2a8/0x6b0
> [   18.787050]  test_skcipher_vec+0x80/0x1c4
> [   18.791017]  alg_test_skcipher+0xbc/0x1fc
> [   18.794985]  alg_test+0x140/0x628
> [   18.798262]  cryptomgr_test+0x24/0x44
> [   18.801885]  kthread+0x110/0x114
> [   18.805076]  ret_from_fork+0x10/0x20
> [   18.808617] Code: 1b008440 d65f03c0 9100a003 f9800071 (885f7c61) 
> [   18.814651] ---[ end trace 0000000000000000 ]---
> [   18.862270] meson8b-dwmac c9410000.ethernet: IRQ eth_wake_irq not found
> [   18.863897] meson8b-dwmac c9410000.ethernet: IRQ eth_lpi not found
> [   18.870349] meson8b-dwmac c9410000.ethernet: PTP uses main clock
> [   18.880548] meson8b-dwmac c9410000.ethernet: User ID: 0x11, Synopsys ID: 0x37
> [   18.882403] meson8b-dwmac c9410000.ethernet: 	DWMAC1000
> [   18.887926] meson8b-dwmac c9410000.ethernet: DMA HW capability register supported
> [   18.895215] meson8b-dwmac c9410000.ethernet: RX Checksum Offload Engine supported
> [   18.902627] meson8b-dwmac c9410000.ethernet: COE Type 2
> [   18.907756] meson8b-dwmac c9410000.ethernet: TX Checksum insertion supported
> [   18.914750] meson8b-dwmac c9410000.ethernet: Wake-Up On Lan supported
> [   18.921246] meson8b-dwmac c9410000.ethernet: Normal descriptors
> [   18.927017] meson8b-dwmac c9410000.ethernet: Ring mode enabled
> [   18.932782] meson8b-dwmac c9410000.ethernet: Enable RX Mitigation via HW Watchdog Timer

-- 
Thank you,
Alexey

From david at redhat.com  Thu Feb 15 02:43:25 2024
From: david at redhat.com (David Hildenbrand)
Date: Thu, 15 Feb 2024 11:43:25 +0100
Subject: [PATCH v6 06/18] mm: Tidy up pte_next_pfn() definition
In-Reply-To: <20240215103205.2607016-7-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-7-ryan.roberts@arm.com>
Message-ID: <b956a94f-8731-4b14-b8c2-ed6b33a67182@redhat.com>

On 15.02.24 11:31, Ryan Roberts wrote:
> Now that the all architecture overrides of pte_next_pfn() have been
> replaced with pte_advance_pfn(), we can simplify the definition of the
> generic pte_next_pfn() macro so that it is unconditionally defined.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>   include/linux/pgtable.h | 2 --
>   1 file changed, 2 deletions(-)
> 
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index b7ac8358f2aa..bc005d84f764 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -212,7 +212,6 @@ static inline int pmd_dirty(pmd_t pmd)
>   #define arch_flush_lazy_mmu_mode()	do {} while (0)
>   #endif
>   
> -#ifndef pte_next_pfn
>   #ifndef pte_advance_pfn
>   static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>   {
> @@ -221,7 +220,6 @@ static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>   #endif
>   
>   #define pte_next_pfn(pte) pte_advance_pfn(pte, 1)
> -#endif
>   
>   #ifndef set_ptes
>   /**

Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From angelogioacchino.delregno at collabora.com  Thu Feb 15 02:45:54 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 11:45:54 +0100
Subject: [PATCH v5 06/13] drm/mediatek: Turn off the layers with zero
 width or height
In-Reply-To: <20240215101119.12629-7-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
 <20240215101119.12629-7-shawn.sung@mediatek.com>
Message-ID: <1fdf2c07-8240-4711-a708-b555932dabc6@collabora.com>

Il 15/02/24 11:11, Hsiao Chien Sung ha scritto:
> We found that IGT (Intel GPU Tool) will try to commit layers with
> zero width or height and lead to undefined behaviors in hardware.
> Disable the layers in such a situation.
> 
> Fixes: 777b7bc86a0a3 ("drm/mediatek: Add ovl_adaptor support for MT8195")
> Fixes: fa97fe71f6f93 ("drm/mediatek: Add ETHDR support for MT8195")
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>

This commit should be sent separately from this series, as it is fixing things
that are not related just to IGT, but also to corner cases in regular non-testing
usecases.

In any case, it's not mandatory as that depends on what the maintainer prefers,
so it's CK's call anyway.

Besides that,

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 2 +-
>   drivers/gpu/drm/mediatek/mtk_ethdr.c            | 7 ++++++-
>   2 files changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> index d4a13a1402148..68a20312ac6f1 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> @@ -157,7 +157,7 @@ void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
>   	merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx];
>   	ethdr = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0];
>   
> -	if (!pending->enable) {
> +	if (!pending->enable || !pending->width || !pending->height) {
>   		mtk_merge_stop_cmdq(merge, cmdq_pkt);
>   		mtk_mdp_rdma_stop(rdma_l, cmdq_pkt);
>   		mtk_mdp_rdma_stop(rdma_r, cmdq_pkt);
> diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
> index 73dc4da3ba3bd..69872b77922eb 100644
> --- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
> +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
> @@ -160,7 +160,12 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
>   	if (idx >= 4)
>   		return;
>   
> -	if (!pending->enable) {
> +	if (!pending->enable || !pending->width || !pending->height) {
> +		/*
> +		 * instead of disabling layer with MIX_SRC_CON directly
> +		 * set the size to 0 to avoid screen shift due to mixer
> +		 * mode switch (hardware behavior)
> +		 */
>   		mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx));
>   		return;
>   	}



From angelogioacchino.delregno at collabora.com  Thu Feb 15 02:46:21 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 11:46:21 +0100
Subject: [PATCH v5 07/13] drm/mediatek: Support alpha blending in display
 driver
In-Reply-To: <20240215101119.12629-8-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
 <20240215101119.12629-8-shawn.sung@mediatek.com>
Message-ID: <96cbca68-052f-42dd-a410-da9061d54c06@collabora.com>

Il 15/02/24 11:11, Hsiao Chien Sung ha scritto:
> Support "Pre-multiplied" and "None" blend mode on MediaTek's chips by
> adding correct blend mode property when the planes init.
> Before this patch, only the "Coverage" mode (default) is supported.
> 
> For more information, there are three pixel blend modes in DRM driver:
> "None", "Pre-multiplied", and "Coverage".
> 
> To understand the difference between these modes, let's take a look at
> the following two approaches to do alpha blending:
> 
> 1. Straight:
> dst.RGB = src.RGB * src.A + dst.RGB * (1 - src.A)
> This is straightforward and easy to understand, when the source layer is
> compositing with the destination layer, it's alpha will affect the
> result. This is also known as "post-multiplied", or "Coverage" mode.
> 
> 2. Pre-multiplied:
> dst.RGB = src.RGB + dst.RGB * (1 - src.A)
> Since the source RGB have already multiplied its alpha, only destination
> RGB need to multiply it. This is the "Pre-multiplied" mode in DRM.
> 
> For the "None" blend mode in DRM, it means the pixel alpha is ignored
> when compositing the layers, only the constant alpha for the composited
> layer will take effects.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> Reviewed-by: CK Hu <ck.hu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From durai.manickamkr at microchip.com  Thu Feb 15 02:45:44 2024
From: durai.manickamkr at microchip.com (Durai Manickam KR)
Date: Thu, 15 Feb 2024 16:15:44 +0530
Subject: [PATCH] dt-bindings: dma: convert atmel-dma.txt to YAML
Message-ID: <20240215-dmac-v1-1-8f1c6f031c98@microchip.com>

Added a description, required properties and appropriate compatibles
for all the SoCs that are supported by microchip.

Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
---
 .../devicetree/bindings/dma/atmel-dma.txt          | 42 -------------
 .../bindings/dma/microchip,at91-dma.yaml           | 71 ++++++++++++++++++++++
 2 files changed, 71 insertions(+), 42 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/atmel-dma.txt b/Documentation/devicetree/bindings/dma/atmel-dma.txt
deleted file mode 100644
index f69bcf5a6343..000000000000
--- a/Documentation/devicetree/bindings/dma/atmel-dma.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-* Atmel Direct Memory Access Controller (DMA)
-
-Required properties:
-- compatible: Should be "atmel,<chip>-dma".
-- reg: Should contain DMA registers location and length.
-- interrupts: Should contain DMA interrupt.
-- #dma-cells: Must be <2>, used to represent the number of integer cells in
-the dmas property of client devices.
-
-Example:
-
-dma0: dma at ffffec00 {
-	compatible = "atmel,at91sam9g45-dma";
-	reg = <0xffffec00 0x200>;
-	interrupts = <21>;
-	#dma-cells = <2>;
-};
-
-DMA clients connected to the Atmel DMA controller must use the format
-described in the dma.txt file, using a three-cell specifier for each channel:
-a phandle plus two integer cells.
-The three cells in order are:
-
-1. A phandle pointing to the DMA controller.
-2. The memory interface (16 most significant bits), the peripheral interface
-(16 less significant bits).
-3. Parameters for the at91 DMA configuration register which are device
-dependent:
-  - bit 7-0: peripheral identifier for the hardware handshaking interface. The
-  identifier can be different for tx and rx.
-  - bit 11-8: FIFO configuration. 0 for half FIFO, 1 for ALAP, 2 for ASAP.
-
-Example:
-
-i2c0 at i2c@f8010000 {
-	compatible = "atmel,at91sam9x5-i2c";
-	reg = <0xf8010000 0x100>;
-	interrupts = <9 4 6>;
-	dmas = <&dma0 1 7>,
-	       <&dma0 1 8>;
-	dma-names = "tx", "rx";
-};
diff --git a/Documentation/devicetree/bindings/dma/microchip,at91-dma.yaml b/Documentation/devicetree/bindings/dma/microchip,at91-dma.yaml
new file mode 100644
index 000000000000..a0a582902e4d
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/microchip,at91-dma.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/microchip,at91-dma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel Direct Memory Access Controller (DMA)
+
+maintainers:
+  - Ludovic Desroches <ludovic.desroches at microchip.com>
+  - Tudor Ambarus <tudor.ambarus at linaro.org>
+
+description: |
+  The Atmel Direct Memory Access Controller (DMAC) transfers data from a source
+  peripheral to a destination peripheral over one or more AMBA buses. One channel
+  is required for each source/destination pair. In the most basic configuration,
+  the DMAC has one master interface and one channel. The master interface reads
+  the data from a source and writes it to a destination. Two AMBA transfers are
+  required for each DMAC data transfer. This is also known as a dual-access transfer.
+  The DMAC is programmed via the APB interface.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - atmel,at91sam9g45-dma
+          - atmel,at91sam9rl-dma
+  reg:
+    description: Should contain DMA registers location and length.
+    maxItems: 1
+
+  interrupts:
+    description: Should contain the DMA interrupts associated to the DMA channels.
+    maxItems: 1
+
+  "#dma-cells":
+    description:
+      Must be <2>, used to represent the number of integer cells in the dmas
+      property of client devices.
+    const: 2
+
+  clocks:
+    description: Should contain a clock specifier for each entry in clock-names.
+    maxItems: 1
+
+  clock-names:
+    description: Should contain the clock of the DMA controller.
+    const: dma_clk
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - "#dma-cells"
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    dma0: dma-controller at ffffec00 {
+            compatible = "atmel,at91sam9g45-dma";
+            reg = <0xffffec00 0x200>;
+            interrupts = <21>;
+            #dma-cells = <2>;
+            clocks = <&pmc 2 20>;
+            clock-names = "dma_clk";
+    };
+
+...

---
base-commit: 7e90b5c295ec1e47c8ad865429f046970c549a66
change-id: 20240214-dmac-5f48fd7f3b9d

Best regards,
-- 
Durai Manickam KR <durai.manickamkr at microchip.com>



From pabeni at redhat.com  Thu Feb 15 02:47:20 2024
From: pabeni at redhat.com (Paolo Abeni)
Date: Thu, 15 Feb 2024 11:47:20 +0100
Subject: [PATCH] net: stmmac: xgmac: fix initializer element is not
 constant error
In-Reply-To: <867da21e-7f30-4caf-9f78-260d426e4186@posteo.net>
References: <20240212154319.907447-1-shiftee@posteo.net>
	 <44c29a45-86fa-4e41-b4b5-e69187f0712e@intel.com>
	 <867da21e-7f30-4caf-9f78-260d426e4186@posteo.net>
Message-ID: <3e15fbcc6cc87f4bafea8bc0a7164366cb1f4439.camel@redhat.com>

Hi,

On Wed, 2024-02-14 at 22:07 +0000, Mark O'Donovan wrote:
> On 14/02/2024 20:31, Jacob Keller wrote:
> > 
> > 
> > On 2/12/2024 7:43 AM, Mark O'Donovan wrote:
> > > GCC prior to 8.x gives an "initializer element is not constant"
> > > error for the uses of dpp_tx_err in dwxgmac3_dma_dpp_errors.
> > > Newer compilers accept either version.
> > > 
> > > More info here:
> > > https://lore.kernel.org/all/20240103-fix-bq24190_charger-vbus_desc-non-const-v1-1-115ddf798c70 at kernel.org
> > > 
> > > Signed-off-by: Mark O'Donovan <shiftee at posteo.net>
> > > ---
> > 
> > I'm not sure whether the Linux kernel project has an explicit cutoff for
> > what versions of GCC (or other compilers) are supported. GCC 8 was first
> > released in 2018.
> > 
> > The fix provided here is fairly straight forward, and while I do think
> > the benefit of using builtin types vs using the macros is nice, I don't
> > see that as a strong enough reason to hold up supporting the older compiler.
> > 
> > Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
> > 
> > >   drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 4 ++--
> > >   1 file changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > > index 323c57f03c93..c02c035b81c0 100644
> > > --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > > +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> > > @@ -830,8 +830,8 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
> > >   	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
> > >   };
> > >   
> > > -static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
> > > -static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
> > > +#define dpp_rx_err "Read Rx Descriptor Parity checker Error"
> > > +#define dpp_tx_err "Read Tx Descriptor Parity checker Error"
> > >   static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
> > >   	{ true, "TDPES0", dpp_tx_err },
> > >   	{ true, "TDPES1", dpp_tx_err },
> > > 
> > > base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de
> 
> Thanks Jacob.
> 
> The minimum versions for compilers and other tools are documented here:
> https://www.kernel.org/doc/html/latest/process/changes.html
> 
> I am using a SLES 15 server to build, the first version of which came out in 2017.

Note that we already have net commit
1692b9775e745f84b69dc8ad0075b0855a43db4e addressing this issue.

Thanks,

Paolo



From avromanov at salutedevices.com  Thu Feb 15 02:47:24 2024
From: avromanov at salutedevices.com (Alexey Romanov)
Date: Thu, 15 Feb 2024 10:47:24 +0000
Subject: [PATCH v4 00/20] Support more Amlogic SoC families in crypto
 driver
In-Reply-To: <ZcsYaPIUrBSg8iXu@Red>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <ZcsYaPIUrBSg8iXu@Red>
Message-ID: <20240215104719.njq6ie2niisntcnv@cab-wsm-0029881.sigma.sbrf.ru>

On Tue, Feb 13, 2024 at 08:21:12AM +0100, Corentin Labbe wrote:
> Le Mon, Feb 12, 2024 at 04:50:48PM +0300, Alexey Romanov a 'ecrit :
> > Hello!
> > 
> > This patchset expand the funcionality of the Amlogic
> > crypto driver by adding support for more SoC families:
> > AXG, G12A, G12B, SM1, A1, S4.
> > 
> > Also specify and enable crypto node in device tree
> > for reference Amlogic devices.
> > 
> > Tested on AXG, G12A/B, SM1, A1 and S4 devices via
> > custom tests [1] and tcrypt module.
> > 
> > ---
> > 
> 
> added patchs up to  "drivers: crypto: meson: process more than MAXDESCS descriptors"

Including this patch or not?

-- 
Thank you,
Alexey

From mripard at kernel.org  Thu Feb 15 02:53:17 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 15 Feb 2024 11:53:17 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi:
 Add Broadcast RGB property
In-Reply-To: <ZcsqoPCJDjA5PJUF@intel.com>
References: <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
 <ZcsqoPCJDjA5PJUF@intel.com>
Message-ID: <dti6zcuzszhut5m4g2bxiwfogwctfhktv2mwuqlij7wtvh3bny@ry4mxpiqidmt>

On Tue, Feb 13, 2024 at 10:38:56AM +0200, Ville Syrj?l? wrote:
> On Mon, Feb 12, 2024 at 05:53:48PM +0100, Maxime Ripard wrote:
> > On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> > > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > > > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > > > Hi,
> > > > > > > > > > 
> > > > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > > > >  /**
> > > > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > > > >   *
> > > > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > > > + *
> > > > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > > > + *
> > > > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > > > + *
> > > > > > > > > > > > > + *      Full:
> > > > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > > > + *
> > > > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > > > + *
> > > > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > > > + *
> > > > > > > > > > > > 
> > > > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > > > different things being affected:
> > > > > > > > > > > > 
> > > > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > > > 
> > > > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > > > 
> > > > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > > > 
> > > > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > > > signalling, what happens?
> > > > > > > > > > > 
> > > > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > > > YCbCr?
> > > > > > > > > > 
> > > > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > > > vc4 will follow the value of the property.
> > > > > > > > > 
> > > > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > > > That should explain why it's only affecting RGB.
> > > > > > > > 
> > > > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > > > itself.
> > > > > > > > 
> > > > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > > > to enable it.
> > > > > > > > 
> > > > > > > > vc4 supports it.
> > > > > > > 
> > > > > > > Someone implemented it incorrectly then.
> > > > > > 
> > > > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > > > document any of it, and when people try to clean things up they get told
> > > > > > that we got it all wrong.
> > > > > 
> > > > > FWIW, this was an i915 property and if another driver uses the same
> > > > > property name it must have the same behavior. Yes, it isn't standardized
> > > > > and yes, it's not documented (hence this effort here) but it's still on
> > > > > vc4 to make the property compatible.
> > > > 
> > > > How is it not compatible? It's a superset of what i915 provides, but
> > > > it's strictly compatible with it.
> > > 
> > > No it is not.
> > 
> > The property is compatible with i915 interpretation of it, whether you
> > like it or not. And that's what Sebastian was referring to.
> > 
> > > Eg. what happens if you set the thing to full range for RGB (which you
> > > must on many broken monitors), and then the kernel automagically
> > > switches to YCbCr (for whatever reason) but the monitor doesn't
> > > support full range YCbCr? Answer: you get crap output.
> > 
> > And that part is just moving goalposts.
> 
> No. Allowing users to get correct colors with broken displays
> is the sole reason why this property even exists.

HDMI 1.4, Section 6.6 - Video Quantization Ranges:

  If the sink?s EDID declares a selectable YCC Quantization Range
  (QY=1), then it shall expect limited range pixel values if it receives
  AVI YQ=0 and it shall expect full range pixel values if it receives
  AVI YQ=1. For other values of YQ, the sink shall expect pixel values
  with the default range for the transmitted video format.

So, the only concern you have is if the EDID has QY set to 1 but the
monitor doesn't actually support it? If so, could we qualify the monitor
as a "broken display" and thus would require that property to apply to
YUV too?

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/20240215/7f3b2bb3/attachment-0001.sig>

From danishanwar at ti.com  Thu Feb 15 02:54:07 2024
From: danishanwar at ti.com (MD Danish Anwar)
Date: Thu, 15 Feb 2024 16:24:07 +0530
Subject: [PATCH] arm64: dts: ti: k3-am654: Drop ti,syscon-rgmii-delay from ICSSG nodes
Message-ID: <20240215105407.2868266-1-danishanwar@ti.com>

Drop ti,syscon-rgmii-delay from ICSSG0, ICSSG1 and ICSSG2 node as this
property is no longer used by ICSSG driver.

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso | 2 --
 arch/arm64/boot/dts/ti/k3-am654-idk.dtso    | 4 ----
 2 files changed, 6 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso b/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
index 0a6e75265ba9..bb0e29873df7 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
@@ -68,7 +68,6 @@ icssg2_emac0: port at 0 {
 				reg = <0>;
 				phy-handle = <&icssg2_phy0>;
 				phy-mode = "rgmii-id";
-				ti,syscon-rgmii-delay = <&scm_conf 0x4120>;
 				/* Filled in by bootloader */
 				local-mac-address = [00 00 00 00 00 00];
 			};
@@ -76,7 +75,6 @@ icssg2_emac1: port at 1 {
 				reg = <1>;
 				phy-handle = <&icssg2_phy1>;
 				phy-mode = "rgmii-id";
-				ti,syscon-rgmii-delay = <&scm_conf 0x4124>;
 				/* Filled in by bootloader */
 				local-mac-address = [00 00 00 00 00 00];
 			};
diff --git a/arch/arm64/boot/dts/ti/k3-am654-idk.dtso b/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
index 8bdb87fcbde0..d4bc80032587 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
@@ -72,7 +72,6 @@ icssg0_emac0: port at 0 {
 				reg = <0>;
 				phy-handle = <&icssg0_phy0>;
 				phy-mode = "rgmii-id";
-				ti,syscon-rgmii-delay = <&scm_conf 0x4100>;
 				/* Filled in by bootloader */
 				local-mac-address = [00 00 00 00 00 00];
 			};
@@ -80,7 +79,6 @@ icssg0_emac1: port at 1 {
 				reg = <1>;
 				phy-handle = <&icssg0_phy1>;
 				phy-mode = "rgmii-id";
-				ti,syscon-rgmii-delay = <&scm_conf 0x4104>;
 				/* Filled in by bootloader */
 				local-mac-address = [00 00 00 00 00 00];
 			};
@@ -140,7 +138,6 @@ icssg1_emac0: port at 0 {
 				reg = <0>;
 				phy-handle = <&icssg1_phy0>;
 				phy-mode = "rgmii-id";
-				ti,syscon-rgmii-delay = <&scm_conf 0x4110>;
 				/* Filled in by bootloader */
 				local-mac-address = [00 00 00 00 00 00];
 			};
@@ -148,7 +145,6 @@ icssg1_emac1: port at 1 {
 				reg = <1>;
 				phy-handle = <&icssg1_phy1>;
 				phy-mode = "rgmii-id";
-				ti,syscon-rgmii-delay = <&scm_conf 0x4114>;
 				/* Filled in by bootloader */
 				local-mac-address = [00 00 00 00 00 00];
 			};
-- 
2.34.1



From durai.manickamkr at microchip.com  Thu Feb 15 02:55:15 2024
From: durai.manickamkr at microchip.com (Durai Manickam KR)
Date: Thu, 15 Feb 2024 16:25:15 +0530
Subject: [PATCH] dt-bindings: dma: convert atmel-xdma.txt to YAML
Message-ID: <20240215-xdma-v1-1-1139960cf096@microchip.com>

Added a description, required properties and appropriate compatibles
for all the SoCs that are supported by microchip for the XDMAC.

Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
---
 .../devicetree/bindings/dma/atmel-xdma.txt         | 54 ---------------
 .../bindings/dma/microchip,at91-xdma.yaml          | 77 ++++++++++++++++++++++
 2 files changed, 77 insertions(+), 54 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/atmel-xdma.txt b/Documentation/devicetree/bindings/dma/atmel-xdma.txt
deleted file mode 100644
index 76d649b3a25d..000000000000
--- a/Documentation/devicetree/bindings/dma/atmel-xdma.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-* Atmel Extensible Direct Memory Access Controller (XDMAC)
-
-* XDMA Controller
-Required properties:
-- compatible: Should be "atmel,sama5d4-dma", "microchip,sam9x60-dma" or
-  "microchip,sama7g5-dma" or
-  "microchip,sam9x7-dma", "atmel,sama5d4-dma".
-- reg: Should contain DMA registers location and length.
-- interrupts: Should contain DMA interrupt.
-- #dma-cells: Must be <1>, used to represent the number of integer cells in
-the dmas property of client devices.
-  - The 1st cell specifies the channel configuration register:
-    - bit 13: SIF, source interface identifier, used to get the memory
-    interface identifier,
-    - bit 14: DIF, destination interface identifier, used to get the peripheral
-    interface identifier,
-    - bit 30-24: PERID, peripheral identifier.
-
-Example:
-
-dma1: dma-controller at f0004000 {
-	compatible = "atmel,sama5d4-dma";
-	reg = <0xf0004000 0x200>;
-	interrupts = <50 4 0>;
-	#dma-cells = <1>;
-};
-
-
-* DMA clients
-DMA clients connected to the Atmel XDMA controller must use the format
-described in the dma.txt file, using a one-cell specifier for each channel.
-The two cells in order are:
-1. A phandle pointing to the DMA controller.
-2. Channel configuration register. Configurable fields are:
-    - bit 13: SIF, source interface identifier, used to get the memory
-    interface identifier,
-    - bit 14: DIF, destination interface identifier, used to get the peripheral
-    interface identifier,
-  - bit 30-24: PERID, peripheral identifier.
-
-Example:
-
-i2c2: i2c at f8024000 {
-	compatible = "atmel,at91sam9x5-i2c";
-	reg = <0xf8024000 0x4000>;
-	interrupts = <34 4 6>;
-	dmas = <&dma1
-		(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
-		 | AT91_XDMAC_DT_PERID(6))>,
-	       <&dma1
-		(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
-		| AT91_XDMAC_DT_PERID(7))>;
-	dma-names = "tx", "rx";
-};
diff --git a/Documentation/devicetree/bindings/dma/microchip,at91-xdma.yaml b/Documentation/devicetree/bindings/dma/microchip,at91-xdma.yaml
new file mode 100644
index 000000000000..0bd79c7b5e6f
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/microchip,at91-xdma.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/microchip,at91-xdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel Extensible Direct Memory Access Controller (XDMAC)
+
+maintainers:
+  - Durai Manickam KR <durai.manickamkr at microchip.com>
+
+description: |
+  The Atmel Extensible Direct Memory Access Controller (XDMAC) performs peripheral
+  data transfer and memory move operations over one or two bus ports through the
+  unidirectional communication channel. Each channel is fully programmable and
+  provides both peripheral or memory-to-memory transfers.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - atmel,sama5d4-dma
+          - microchip,sama7g5-dma
+          - microchip,sam9x7-dma
+      - items:
+          - const: atmel,sama5d4-dma
+          - const: microchip,sam9x60-dma
+  reg:
+    description: Should contain DMA registers location and length.
+    maxItems: 1
+
+  interrupts:
+    description: Should contain the DMA interrupts associated to the DMA channels.
+    maxItems: 1
+
+  "#dma-cells":
+    description: |
+      Must be <1>, used to represent the number of integer cells in the dmas
+      property of client device.
+      -The 1st cell specifies the channel configuration register:
+      -bit 13: SIF, source interface identifier, used to get the memory
+               interface identifier,
+      -bit 14: DIF, destination interface identifier, used to get the peripheral
+               interface identifier,
+      -bit 30-24: PERID, peripheral identifier.
+    const: 1
+
+  clocks:
+    description: Should contain a clock specifier for each entry in clock-names.
+    maxItems: 1
+
+  clock-names:
+    description: Should contain the clock of the DMA controller.
+    const: dma_clk
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - "#dma-cells"
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    dma0: dma-controller at f0004000 {
+            compatible = "atmel,sama5d4-dma";
+            reg = <0xffffec00 0x200>;
+            interrupts = <50 4 0>;
+            #dma-cells = <1>;
+            clocks = <&pmc 2 20>;
+            clock-names = "dma_clk";
+    };
+
+...

---
base-commit: 8d3dea210042f54b952b481838c1e7dfc4ec751d
change-id: 20240215-xdma-36e8bdbf8141

Best regards,
-- 
Durai Manickam KR <durai.manickamkr at microchip.com>



From suzuki.poulose at arm.com  Thu Feb 15 02:55:32 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu, 15 Feb 2024 10:55:32 +0000
Subject: [PATCH V4 02/11] coresight: stm: Extract device name from AMBA
 pid based table lookup
In-Reply-To: <20240123054608.1790189-3-anshuman.khandual@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-3-anshuman.khandual@arm.com>
Message-ID: <56d56f85-6172-4fb1-a002-fe82ffc8a66a@arm.com>

On 23/01/2024 05:45, Anshuman Khandual wrote:
> Instead of using AMBA private data field, extract the device name from AMBA
> pid based table lookup using new coresight_get_uci_data_from_amba() helper.
> 
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: James Clark <james.clark at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>   drivers/hwtracing/coresight/coresight-priv.h | 10 ++++++++++
>   drivers/hwtracing/coresight/coresight-stm.c  | 14 +++++++++++++-
>   2 files changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
> index 767076e07970..68cbb036cec8 100644
> --- a/drivers/hwtracing/coresight/coresight-priv.h
> +++ b/drivers/hwtracing/coresight/coresight-priv.h
> @@ -221,6 +221,16 @@ static inline void *coresight_get_uci_data(const struct amba_id *id)
>   	return uci_id->data;
>   }
>   
> +static inline void *coresight_get_uci_data_from_amba(const struct amba_id *table, u32 pid)
> +{
> +	while (table->mask) {
> +		if ((table->id & table->mask) == pid)

Why are we masking table->id ? table->id is a static value that the
driver wants to check for "variants" of a given device. The table->mask
is there to filter out the "irrelevant" bits of the PID that we read
from the device. So this should instead be:

		if ((table->mask & pid) == table->id)

> +			return coresight_get_uci_data(table);
> +		table++;
> +	};
> +	return NULL;
> +}
> +
>   void coresight_release_platform_data(struct coresight_device *csdev,
>   				     struct device *dev,
>   				     struct coresight_platform_data *pdata);
> diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
> index a1c27c901ad1..9cdca4f86cab 100644
> --- a/drivers/hwtracing/coresight/coresight-stm.c
> +++ b/drivers/hwtracing/coresight/coresight-stm.c
> @@ -804,6 +804,18 @@ static void stm_init_generic_data(struct stm_drvdata *drvdata,
>   	drvdata->stm.set_options = stm_generic_set_options;
>   }
>   
> +#define STM_AMBA_MASK 0xfffff
> +
> +static const struct amba_id stm_ids[];
> +
> +static char *stm_csdev_name(struct coresight_device *csdev)
> +{
> +	u32 stm_pid = coresight_get_pid(&csdev->access) & STM_AMBA_MASK;

Similar to above:

Why do we apply a "custom" mask to the PID and later check the PID with
that of the table->pid.

The way it is supposed work is :

	(table->mask & dev_pid) == table->pid

the table->mask is there for a reason: i.e., to get the relevant bits 
from the device_pid and compare it against "the" expected value 
(table->pid).


Suzuki

> +	void *uci_data = coresight_get_uci_data_from_amba(stm_ids, stm_pid);
> +
> +	return uci_data ? (char *)uci_data : "STM";
> +}
> +
>   static int stm_probe(struct amba_device *adev, const struct amba_id *id)
>   {
>   	int ret, trace_id;
> @@ -900,7 +912,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
>   	pm_runtime_put(&adev->dev);
>   
>   	dev_info(&drvdata->csdev->dev, "%s initialized\n",
> -		 (char *)coresight_get_uci_data(id));
> +		 stm_csdev_name(drvdata->csdev));
>   	return 0;
>   
>   cs_unregister:



From mripard at kernel.org  Thu Feb 15 03:00:01 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 15 Feb 2024 12:00:01 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi:
 Add Broadcast RGB property
In-Reply-To: <20240212170618.GA1372043@toolbox>
References: <73peztbeeikb3fg6coxu3punxllgtyrmgco34tnxkojtsjbr3s@26bud3sjbcez>
 <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
 <20240212170618.GA1372043@toolbox>
Message-ID: <2mih3humepuedtli7ge52ncom4uffkqravdpalncgfyucmwdzc@bp5o7i3ky77a>

On Mon, Feb 12, 2024 at 06:06:18PM +0100, Sebastian Wick wrote:
> On Mon, Feb 12, 2024 at 05:53:48PM +0100, Maxime Ripard wrote:
> > On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> > > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > > > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > > > Hi,
> > > > > > > > > > 
> > > > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > > > >  /**
> > > > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > > > >   *
> > > > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > > > + *
> > > > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > > > + *
> > > > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > > > + *
> > > > > > > > > > > > > + *      Full:
> > > > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > > > + *
> > > > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > > > + *
> > > > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > > > + *
> > > > > > > > > > > > 
> > > > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > > > different things being affected:
> > > > > > > > > > > > 
> > > > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > > > 
> > > > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > > > 
> > > > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > > > 
> > > > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > > > signalling, what happens?
> > > > > > > > > > > 
> > > > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > > > YCbCr?
> > > > > > > > > > 
> > > > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > > > vc4 will follow the value of the property.
> > > > > > > > > 
> > > > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > > > That should explain why it's only affecting RGB.
> > > > > > > > 
> > > > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > > > itself.
> > > > > > > > 
> > > > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > > > to enable it.
> > > > > > > > 
> > > > > > > > vc4 supports it.
> > > > > > > 
> > > > > > > Someone implemented it incorrectly then.
> > > > > > 
> > > > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > > > document any of it, and when people try to clean things up they get told
> > > > > > that we got it all wrong.
> > > > > 
> > > > > FWIW, this was an i915 property and if another driver uses the same
> > > > > property name it must have the same behavior. Yes, it isn't standardized
> > > > > and yes, it's not documented (hence this effort here) but it's still on
> > > > > vc4 to make the property compatible.
> > > > 
> > > > How is it not compatible? It's a superset of what i915 provides, but
> > > > it's strictly compatible with it.
> > > 
> > > No it is not.
> > 
> > The property is compatible with i915 interpretation of it, whether you
> > like it or not. And that's what Sebastian was referring to.
> > 
> > > Eg. what happens if you set the thing to full range for RGB (which you
> > > must on many broken monitors), and then the kernel automagically
> > > switches to YCbCr (for whatever reason) but the monitor doesn't
> > > support full range YCbCr? Answer: you get crap output.
> > 
> > And that part is just moving goalposts.
> 
> But it's really not.

It really is. This whole discussion started by "well it would be nice if
we made that property handled by the core", and we're now at the "we
need to deal with broken YCbCr displays and i915 opinion about them"
stage. After creating documentation, unit tests, etc. It's the textbook
definition of moving goalposts. And while i915 won't be affected by all
that work.

That series has been stuck for multiple iterations on pointless and
mundane debates while the biggest part and whole point of it is not
getting any review. So yeah, sorry, it's frustrating.

> The Broadcast RGB property kind of works from a user space perspective
> because it's a workaround for broken sinks. If a sink expects limited
> range we can force full range. If this however affects YCbCr modes as
> well, then this isn't a workaround for broken RGB range anymore
> because it now breaks YCbCr.

Or, you know, it's a workaround for broken YCbCr display.

> Sorry, but vc4 just has to change.
> 
> And again: let's please stop trying to improve the property.

I'm not. I'm super close to just dropping that patch entirely and keep
the current situation that seems to work fine for everyone.

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/20240215/119ec70f/attachment-0001.sig>

From laurent.pinchart at ideasonboard.com  Thu Feb 15 03:02:05 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Thu, 15 Feb 2024 13:02:05 +0200
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240214-velcro-pushy-0cbd18b23361@spud>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <20240214142825.GA7873@pendragon.ideasonboard.com>
 <20240214-velcro-pushy-0cbd18b23361@spud>
Message-ID: <20240215110205.GD7873@pendragon.ideasonboard.com>

On Wed, Feb 14, 2024 at 05:37:17PM +0000, Conor Dooley wrote:
> On Wed, Feb 14, 2024 at 04:28:25PM +0200, Laurent Pinchart wrote:
> > On Wed, Feb 14, 2024 at 02:19:03PM +0000, Daniel Scally wrote:
> > > Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
> > > 
> > > Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> > > Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> > > ---
> > > Changes in v2:
> > > 
> > > 	- Added clocks information
> > > 	- Fixed the warnings raised by Rob
> > > 
> > >  .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
> > >  1 file changed, 77 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > > 
> > > diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > > new file mode 100644
> > > index 000000000000..30038cfec3a4
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > > @@ -0,0 +1,77 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: ARM Mali-C55 Image Signal Processor
> > > +
> > > +maintainers:
> > > +  - Daniel Scally <dan.scally at ideasonboard.com>
> > > +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > > +
> > > +properties:
> > > +  compatible:
> > > +    const: arm,mali-c55
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  interrupts:
> > > +    maxItems: 1
> > > +
> > > +  clocks:
> > > +    items:
> > > +      - description: ISP video clock
> > 
> > I wonder if we need this clock. Granted, it's an input clock to the ISP,
> > but it's part of the input video bus. I don't expect anyone would ever
> > need to control it manually, it should be provided by the video source
> > automatically.
> 
> I'd say that if there's a clock controller providing this clock, even if
> it is implicit in the video feed it's good to have here. Being able to
> increment the refcount on that clock would be good, even if you don't
> actually control it manually?

I don't expect there would be a clock controller to directly reference
in most cases. It depends a bit on where the clock domain crossing
between the source (often a CSI-2 receiver) and the ISP is. If it's
implemented in glue logic bundled with the ISP, which wouldn't be
described in DT as a separate node, then there's a higher chance we'll
have a clock controller for vclk. If it's implemented in the source,
vclk will just come from the source, which won't be listed as a clock
controller.

One option would be to make this clock optional, by moving it to the end
of the clocks list, and setting

	minItems: 2
	maxItems: 3

> > > +      - description: ISP AXI clock
> > > +      - description: ISP AHB-lite clock
> > 
> > These two other clocks look good to me.
> > 
> > > +
> > > +  clock-names:
> > > +    items:
> > > +      - const: vclk
> > > +      - const: aclk
> > > +      - const: hclk
> 
> Why not "video" "axi" "ahb-lite"? There's 3 useful letters between the
> tree clock names you've provided - they're all clocks, so having "clk"
> in them is just noise :)

As far as I understand, the names proposed by Dan come directly from the
IP core documentation.

-- 
Regards,

Laurent Pinchart


From angelogioacchino.delregno at collabora.com  Thu Feb 15 03:02:22 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 12:02:22 +0100
Subject: [PATCH v5 08/13] drm/mediatek: Support alpha blending in OVL
In-Reply-To: <20240215101119.12629-9-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
 <20240215101119.12629-9-shawn.sung@mediatek.com>
Message-ID: <7664fece-c29a-4374-a59c-4ce8fe831494@collabora.com>

Il 15/02/24 11:11, Hsiao Chien Sung ha scritto:
> Support "Pre-multiplied" and "None" blend mode on MediaTek's chips.
> Before this patch, only the "Coverage" mode is supported.
> 
> Please refer to the description of the commit
> "drm/mediatek: Support alpha blending in display driver"
> for more information.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 83 +++++++++++++++++++++----
>   1 file changed, 72 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index c42fce38a35eb..98c989fddcc08 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -39,6 +39,7 @@
>   #define DISP_REG_OVL_PITCH_MSB(n)		(0x0040 + 0x20 * (n))
>   #define OVL_PITCH_MSB_2ND_SUBBUF			BIT(16)
>   #define DISP_REG_OVL_PITCH(n)			(0x0044 + 0x20 * (n))
> +#define OVL_CONST_BLEND					BIT(28)
>   #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
>   #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
>   #define DISP_REG_OVL_ADDR_MT2701		0x0040
> @@ -52,13 +53,16 @@
>   #define GMC_THRESHOLD_HIGH	((1 << GMC_THRESHOLD_BITS) / 4)
>   #define GMC_THRESHOLD_LOW	((1 << GMC_THRESHOLD_BITS) / 8)
>   
> +#define OVL_CON_CLRFMT_MAN	BIT(23)
>   #define OVL_CON_BYTE_SWAP	BIT(24)
> -#define OVL_CON_MTX_YUV_TO_RGB	(6 << 16)
> +#define OVL_CON_RGB_SWAP	BIT(25)
>   #define OVL_CON_CLRFMT_RGB	(1 << 12)
>   #define OVL_CON_CLRFMT_RGBA8888	(2 << 12)
>   #define OVL_CON_CLRFMT_ARGB8888	(3 << 12)
>   #define OVL_CON_CLRFMT_UYVY	(4 << 12)
>   #define OVL_CON_CLRFMT_YUYV	(5 << 12)
> +#define OVL_CON_MTX_YUV_TO_RGB	(6 << 16)
> +#define OVL_CON_CLRFMT_PARGB8888	(OVL_CON_CLRFMT_ARGB8888 | OVL_CON_CLRFMT_MAN)
>   #define OVL_CON_CLRFMT_RGB565(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
>   					0 : OVL_CON_CLRFMT_RGB)
>   #define OVL_CON_CLRFMT_RGB888(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
> @@ -72,6 +76,22 @@
>   #define	OVL_CON_VIRT_FLIP	BIT(9)
>   #define	OVL_CON_HORZ_FLIP	BIT(10)
>   
> +static inline bool is_10bit_rgb(u32 fmt)
> +{
> +	switch (fmt) {
> +	case DRM_FORMAT_XRGB2101010:
> +	case DRM_FORMAT_ARGB2101010:
> +	case DRM_FORMAT_RGBX1010102:
> +	case DRM_FORMAT_RGBA1010102:
> +	case DRM_FORMAT_XBGR2101010:
> +	case DRM_FORMAT_ABGR2101010:
> +	case DRM_FORMAT_BGRX1010102:
> +	case DRM_FORMAT_BGRA1010102:
> +		return true;
> +	}
> +	return false;
> +}
> +
>   static const u32 mt8173_formats[] = {
>   	DRM_FORMAT_XRGB8888,
>   	DRM_FORMAT_ARGB8888,
> @@ -89,12 +109,20 @@ static const u32 mt8173_formats[] = {
>   static const u32 mt8195_formats[] = {
>   	DRM_FORMAT_XRGB8888,
>   	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_XRGB2101010,
>   	DRM_FORMAT_ARGB2101010,
>   	DRM_FORMAT_BGRX8888,
>   	DRM_FORMAT_BGRA8888,
> +	DRM_FORMAT_BGRX1010102,
>   	DRM_FORMAT_BGRA1010102,
>   	DRM_FORMAT_ABGR8888,
>   	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_XBGR2101010,
> +	DRM_FORMAT_ABGR2101010,
> +	DRM_FORMAT_RGBX8888,
> +	DRM_FORMAT_RGBA8888,
> +	DRM_FORMAT_RGBX1010102,
> +	DRM_FORMAT_RGBA1010102,
>   	DRM_FORMAT_RGB888,
>   	DRM_FORMAT_BGR888,
>   	DRM_FORMAT_RGB565,
> @@ -254,9 +282,7 @@ static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
>   	reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
>   	reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
>   
> -	if (format == DRM_FORMAT_RGBA1010102 ||
> -	    format == DRM_FORMAT_BGRA1010102 ||
> -	    format == DRM_FORMAT_ARGB2101010)
> +	if (is_10bit_rgb(format))
>   		bit_depth = OVL_CON_CLRFMT_10_BIT;
>   
>   	reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
> @@ -274,7 +300,13 @@ void mtk_ovl_config(struct device *dev, unsigned int w,
>   	if (w != 0 && h != 0)
>   		mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, ovl->regs,
>   				      DISP_REG_OVL_ROI_SIZE);
> -	mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_BGCLR);
> +
> +	/*
> +	 * The background color should be opaque black (ARGB),
> +	 * otherwise there will be no effect with alpha blend
> +	 */
> +	mtk_ddp_write_relaxed(cmdq_pkt, 0xff000000, &ovl->cmdq_reg,
> +			      ovl->regs, DISP_REG_OVL_ROI_BGCLR);

Multiple (all of?) OVL color registers, like{L0-3,EL0-2}_YUV1BIT_COLOR(x),
ROI_BGCLR, L{0-3}_CLR and others do follow this exact layout:

#define OVL_COLOR_ALPHA				GENMASK(31, 24)
#define OVL_COLOR_GREEN				GENMASK(23, 16)
#define OVL_COLOR_RED				GENMASK(15, 8)
#define OVL_COLOR_BLUE				GENMASK(7, 0)

...so we can define those as they're valid for multiple registers, and then
we can use the definition instead of an apparently random value.

/*
  * The background color should be opaque black (ARGB),
  * otherwise there will be no effect with alpha blend
  */
mtk_ddp_write_relaxed(cmdq_pkt, OVL_COLOR_ALPHA, &ovl->cmdq_reg,
		      ovl->regs, DISP_REG_OVL_ROI_BGCLR);

Everything else looks ok.

Regards,
Angelo



From devnull+forbidden405.outlook.com at kernel.org  Thu Feb 15 03:03:38 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Thu, 15 Feb 2024 19:03:38 +0800
Subject: [PATCH] mmc: host: replace 1st argument to struct device * for
 mmc_of_parse_clk_phase()
Message-ID: <20240215-mmc_phase-v1-1-f27644ee13e4@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

Parsing dt usaully happens very early, sometimes even bofore struct
mmc_host is allocated (e.g. dw_mci_probe() and dw_mci_parse_dt() in
dw_mmc.c). Looking at the source of mmc_of_parse_clk_phase(), it's
actually not mandatory to have a initialized mmc_host first, instead we
can pass struct device * to it directly.

Also fix the only current user (sdhci-of-aspeed.c).

Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 drivers/mmc/core/host.c            | 4 +---
 drivers/mmc/host/sdhci-of-aspeed.c | 2 +-
 include/linux/mmc/host.h           | 2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index cf396e8f34e9..8b2844ac5dc5 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -234,10 +234,8 @@ static void mmc_of_parse_timing_phase(struct device *dev, const char *prop,
 }
 
 void
-mmc_of_parse_clk_phase(struct mmc_host *host, struct mmc_clk_phase_map *map)
+mmc_of_parse_clk_phase(struct device *dev, struct mmc_clk_phase_map *map)
 {
-	struct device *dev = host->parent;
-
 	mmc_of_parse_timing_phase(dev, "clk-phase-legacy",
 				  &map->phase[MMC_TIMING_LEGACY]);
 	mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs",
diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
index 42d54532cabe..430c1f90037b 100644
--- a/drivers/mmc/host/sdhci-of-aspeed.c
+++ b/drivers/mmc/host/sdhci-of-aspeed.c
@@ -435,7 +435,7 @@ static int aspeed_sdhci_probe(struct platform_device *pdev)
 		goto err_sdhci_add;
 
 	if (dev->phase_desc)
-		mmc_of_parse_clk_phase(host->mmc, &dev->phase_map);
+		mmc_of_parse_clk_phase(&pdev->dev, &dev->phase_map);
 
 	ret = sdhci_add_host(host);
 	if (ret)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 2f445c651742..5894bf912f7b 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -539,7 +539,7 @@ struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra);
 int mmc_add_host(struct mmc_host *);
 void mmc_remove_host(struct mmc_host *);
 void mmc_free_host(struct mmc_host *);
-void mmc_of_parse_clk_phase(struct mmc_host *host,
+void mmc_of_parse_clk_phase(struct device *dev,
 			    struct mmc_clk_phase_map *map);
 int mmc_of_parse(struct mmc_host *host);
 int mmc_of_parse_voltage(struct mmc_host *host, u32 *mask);

---
base-commit: 9d64bf433c53cab2f48a3fff7a1f2a696bc5229a
change-id: 20240215-mmc_phase-26e85511285d

Best regards,
-- 
Yang Xiwen <forbidden405 at outlook.com>



From suzuki.poulose at arm.com  Thu Feb 15 03:04:04 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu, 15 Feb 2024 11:04:04 +0000
Subject: [PATCH V4 01/11] coresight: etm4x: Fix unbalanced
 pm_runtime_enable()
In-Reply-To: <20240123054608.1790189-2-anshuman.khandual@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-2-anshuman.khandual@arm.com>
Message-ID: <68eb9e4e-de77-4854-8212-816c66d5f657@arm.com>

On 23/01/2024 05:45, Anshuman Khandual wrote:
> There is an unbalanced pm_runtime_enable() in etm4_probe_platform_dev()
> when etm4_probe() fails. This problem can be observed via the coresight
> etm4 module's (load -> unload -> load) sequence when etm4_probe() fails
> in etm4_probe_platform_dev().
> 
> [   63.379943] coresight-etm4x 7040000.etm: Unbalanced pm_runtime_enable!
> [   63.393630] coresight-etm4x 7140000.etm: Unbalanced pm_runtime_enable!
> [   63.407455] coresight-etm4x 7240000.etm: Unbalanced pm_runtime_enable!
> [   63.420983] coresight-etm4x 7340000.etm: Unbalanced pm_runtime_enable!
> [   63.420999] coresight-etm4x 7440000.etm: Unbalanced pm_runtime_enable!
> [   63.441209] coresight-etm4x 7540000.etm: Unbalanced pm_runtime_enable!
> [   63.454689] coresight-etm4x 7640000.etm: Unbalanced pm_runtime_enable!
> [   63.474982] coresight-etm4x 7740000.etm: Unbalanced pm_runtime_enable!
> 
> This fixes the above problem - with an explicit pm_runtime_disable() call
> when etm4_probe() fails during etm4_probe_platform_dev().

Fixes: 5214b563588e ("coresight: etm4x: Add support for sysreg only devices"

> 
> Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
> Cc: Hanjun Guo <guohanjun at huawei.com>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: "Rafael J. Wysocki" <rafael at kernel.org>
> Cc: Len Brown <lenb at kernel.org>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: James Clark <james.clark at arm.com>
> Cc: Leo Yan <leo.yan at linaro.org>
> Cc: linux-acpi at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: coresight at lists.linaro.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
> Changes in V4:
> 
> - New patch in the series
> 
>   drivers/hwtracing/coresight/coresight-etm4x-core.c | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index ce1995a2827f..7c693b45ac05 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -2217,6 +2217,9 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
>   	ret = etm4_probe(&pdev->dev);
>   
>   	pm_runtime_put(&pdev->dev);
> +	if (ret)
> +		pm_runtime_disable(&pdev->dev);
> +
>   	return ret;
>   }
>   

Looks good to me. I have glanced through the other platform device 
driver code in coresight subsystem and they all seem to be safe, except
for Ultrasoc-smb, which doesn't do any power managment. It may be, 
because it is only supported on an ACPI system.

Suzuki



From tim at feathertop.org  Thu Feb 15 03:04:23 2024
From: tim at feathertop.org (Tim Lunn)
Date: Thu, 15 Feb 2024 22:04:23 +1100
Subject: [PATCH 0/2] dts fixes for Sonoff iHost
Message-ID: <20240215110425.934740-1-tim@feathertop.org>

A couple of tweaks to the dts for Sonoff iHost.

Add aliases for sdio and sdmmc to ensure consistent ordering of devices
on boot.

Tweak sdio properties to improve detection of the rtl8723ds sdio wifi module.


Tim Lunn (2):
  ARM: dts: rockchip: mmc aliases for Sonoff iHost
  ARM: dts: rockchip: Wifi improvements for Sonoff iHost

 arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

-- 
2.40.1



From tim at feathertop.org  Thu Feb 15 03:04:24 2024
From: tim at feathertop.org (Tim Lunn)
Date: Thu, 15 Feb 2024 22:04:24 +1100
Subject: [PATCH 1/2] ARM: dts: rockchip: mmc aliases for Sonoff iHost
In-Reply-To: <20240215110425.934740-1-tim@feathertop.org>
References: <20240215110425.934740-1-tim@feathertop.org>
Message-ID: <20240215110425.934740-2-tim@feathertop.org>

Add aliases for sdio and sdmmc to ensure consistent ordering of
mmc devices on boot

Signed-off-by: Tim Lunn <tim at feathertop.org>
---

 arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi b/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi
index 32b329e87a0c..ba6c3a674f22 100644
--- a/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi
+++ b/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi
@@ -8,6 +8,8 @@ / {
 	aliases {
 		ethernet0 = &gmac;
 		mmc0 = &emmc;
+		mmc1 = &sdio;
+		mmc2 = &sdmmc;
 	};
 
 	chosen {
-- 
2.40.1



From tim at feathertop.org  Thu Feb 15 03:04:25 2024
From: tim at feathertop.org (Tim Lunn)
Date: Thu, 15 Feb 2024 22:04:25 +1100
Subject: [PATCH 2/2] ARM: dts: rockchip: Wifi improvements for Sonoff iHost
In-Reply-To: <20240215110425.934740-1-tim@feathertop.org>
References: <20240215110425.934740-1-tim@feathertop.org>
Message-ID: <20240215110425.934740-3-tim@feathertop.org>

In some instances the kernel fails to detect the sdio wifi module
in the Sonoff iHost.

Tweak sdio properties to improve detection of rtl8723ds wifi module

Signed-off-by: Tim Lunn <tim at feathertop.org>
---

 arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi b/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi
index ba6c3a674f22..9a87dc0d5f66 100644
--- a/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi
+++ b/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi
@@ -327,7 +327,7 @@ &pmu_io_domains {
 	pmuio1-supply = <&vcc3v3_sys>;
 	vccio1-supply = <&vcc_1v8>;
 	vccio2-supply = <&vccio_sd>;
-	vccio3-supply = <&vcc_1v8>;
+	vccio3-supply = <&vcc3v3_sd>;
 	vccio4-supply = <&vcc_dovdd>;
 	vccio5-supply = <&vcc_1v8>;
 	vccio6-supply = <&vcc_1v8>;
@@ -345,14 +345,14 @@ &sdio {
 	cap-sd-highspeed;
 	cap-sdio-irq;
 	keep-power-in-suspend;
-	max-frequency = <100000000>;
+	max-frequency = <50000000>;
 	mmc-pwrseq = <&sdio_pwrseq>;
 	non-removable;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc1_clk &sdmmc1_cmd &sdmmc1_bus4>;
 	rockchip,default-sample-phase = <90>;
-	sd-uhs-sdr104;
-	vmmc-supply = <&vcc3v3_sys>;
+	sd-uhs-sdr50;
+	vmmc-supply = <&vcc3v3_sd>;
 	vqmmc-supply = <&vcc_1v8>;
 	status = "okay";
 };
-- 
2.40.1



From angelogioacchino.delregno at collabora.com  Thu Feb 15 03:06:38 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 12:06:38 +0100
Subject: [PATCH v5 10/13] drm/mediatek: Support CRC in display driver
In-Reply-To: <20240215101119.12629-11-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
 <20240215101119.12629-11-shawn.sung@mediatek.com>
Message-ID: <44529502-250b-4c8a-94c3-2c481d1385cf@collabora.com>

Il 15/02/24 11:11, Hsiao Chien Sung ha scritto:
> Register CRC related function pointers to support
> CRC retrieval.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 239 ++++++++++++++++++++
>   drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |  39 ++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   3 +
>   3 files changed, 281 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 14cf75fa217f9..6cb1ed419dee7 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -68,6 +68,9 @@ struct mtk_drm_crtc {
>   	/* lock for display hardware access */
>   	struct mutex			hw_lock;
>   	bool				config_updating;
> +
> +	struct mtk_ddp_comp		*crc_provider;
> +	unsigned int			frames;
>   };
>   
>   struct mtk_crtc_state {
> @@ -635,6 +638,14 @@ static void mtk_crtc_ddp_irq(void *data)
>   	struct drm_crtc *crtc = data;
>   	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
>   	struct mtk_drm_private *priv = crtc->dev->dev_private;
> +	struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
> +
> +	/*
> +	 * crc providers should make sure the crc is always correct
> +	 * by resetting it in .crc_read()
> +	 */
> +	if (crtc->crc.opened)
> +		comp->funcs->crc_read(comp->dev);
>   
>   #if IS_REACHABLE(CONFIG_MTK_CMDQ)
>   	if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
> @@ -646,6 +657,24 @@ static void mtk_crtc_ddp_irq(void *data)
>   	if (!priv->data->shadow_register)
>   		mtk_crtc_ddp_config(crtc, NULL);
>   #endif
> +
> +	/*
> +	 * drm_crtc_add_crc_entry() could take more than 50ms to finish
> +	 * put it at the end of the isr
> +	 */
> +	if (crtc->crc.opened) {
> +		/*
> +		 * skip the first crc because the first frame is configured by
> +		 * mtk_crtc_ddp_hw_init() when atomic enable
> +		 */
> +		if (++mtk_crtc->frames > 1) {
> +			drm_crtc_add_crc_entry(crtc, true,
> +					       drm_crtc_vblank_count(crtc),
> +					       comp->funcs->crc_entry(comp->dev));
> +		}
> +	} else {
> +		mtk_crtc->frames = 0;
> +	}
>   	mtk_drm_finish_page_flip(mtk_crtc);
>   }
>   
> @@ -704,6 +733,40 @@ static void mtk_drm_crtc_update_output(struct drm_crtc *crtc,
>   	}
>   }
>   
> +static int mtk_drm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src)
> +{
> +	if (src && strcmp(src, "auto") != 0) {
> +		DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
> +			  __func__, drm_crtc_index(crtc), src);
> +		return -EINVAL;
> +	}
> +	return 0;
> +}
> +
> +static int mtk_drm_crtc_verify_crc_source(struct drm_crtc *crtc,
> +					  const char *src,
> +					  size_t *cnt)
> +{
> +	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> +	struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
> +
> +	if (!comp) {
> +		DRM_ERROR("%s(crtc-%d): no crc provider\n",
> +			  __func__, drm_crtc_index(crtc));
> +		return -ENOENT;
> +	}
> +
> +	if (src && strcmp(src, "auto") != 0) {
> +		DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
> +			  __func__, drm_crtc_index(crtc), src);
> +		return -EINVAL;
> +	}
> +
> +	*cnt = comp->funcs->crc_cnt(comp->dev);
> +
> +	return 0;
> +}
> +
>   int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
>   			     struct mtk_plane_state *state)
>   {
> @@ -841,6 +904,8 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
>   	.atomic_destroy_state	= mtk_drm_crtc_destroy_state,
>   	.enable_vblank		= mtk_drm_crtc_enable_vblank,
>   	.disable_vblank		= mtk_drm_crtc_disable_vblank,
> +	.set_crc_source		= mtk_drm_crtc_set_crc_source,
> +	.verify_crc_source	= mtk_drm_crtc_verify_crc_source,
>   };
>   
>   static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
> @@ -1033,6 +1098,11 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>   
>   			if (comp->funcs->ctm_set)
>   				has_ctm = true;
> +
> +			if (comp->funcs->crc_cnt &&
> +			    comp->funcs->crc_entry &&
> +			    comp->funcs->crc_read)
> +				mtk_crtc->crc_provider = comp;
>   		}
>   
>   		mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq,
> @@ -1137,3 +1207,172 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>   
>   	return 0;
>   }
> +
> +void mtk_drm_crc_init(struct mtk_drm_crc *crc,
> +		      const u32 *crc_offset_table, size_t crc_count,
> +		      u32 reset_offset, u32 reset_mask)
> +{
> +	crc->ofs = crc_offset_table;
> +	crc->cnt = crc_count;
> +	crc->rst_ofs = reset_offset;
> +	crc->rst_msk = reset_mask;
> +	crc->va = kcalloc(crc->cnt, sizeof(*crc->va), GFP_KERNEL);
> +	if (!crc->va) {
> +		DRM_ERROR("failed to allocate memory for crc\n");
> +		crc->cnt = 0;
> +	}
> +}
> +
> +void mtk_drm_crc_read(struct mtk_drm_crc *crc, void __iomem *reg)
> +{

	u32 n; goes here

> +	if (!crc->cnt || !crc->ofs || !crc->va)
> +		return;
> +
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	/* sync to see the most up-to-date copy of the DMA buffer */
> +	dma_sync_single_for_cpu(crc->cmdq_client.chan->mbox->dev,
> +				crc->pa, crc->cnt * sizeof(*crc->va),
> +				DMA_FROM_DEVICE);
> +#else
> +	/* read crc with cpu for the platforms without cmdq */
> +	{

then you don't need the braces.

Regards,
Angelo



From angelogioacchino.delregno at collabora.com  Thu Feb 15 03:09:56 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 15 Feb 2024 12:09:56 +0100
Subject: (subset) [PATCH v5 0/2] extcon-usb-gpio YAML conversion
In-Reply-To: <20240215093214.796821-1-alexander.stein@ew.tq-group.com>
References: <20240215093214.796821-1-alexander.stein@ew.tq-group.com>
Message-ID: <170799536802.115820.17735258763796183400.b4-ty@collabora.com>

On Thu, 15 Feb 2024 10:32:12 +0100, Alexander Stein wrote:
> it seems these two patches got missed from v4[1]. So v5 is a new version only
> containing the patches not applied yet. The rebase also includes a slight
> change to the mediatek patch.
> 
> Changes in v5:
> * rebased to next-20240215
> 
> [...]

Applied to v6.8-next/dts64, thanks!

[2/2] arm64: dts: mediatek: Replace deprecated extcon-usb-gpio id-gpio/vbus-gpio properties
      https://git.kernel.org/mediatek/c/5b6df373

Cheers,
Angelo



From gregkh at linuxfoundation.org  Thu Feb 15 03:16:34 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Thu, 15 Feb 2024 12:16:34 +0100
Subject: 6.7 regression: platform 4809c000.mmc: deferred probe pending
In-Reply-To: <mvmeddeyqb8.fsf@suse.de>
References: <mvmcyt13idm.fsf@suse.de>
 <c92385d2-1909-43a8-aea8-cd9a8687a898@leemhuis.info>
 <20240215094640.GS52537@atomide.com>
 <mvmeddeyqb8.fsf@suse.de>
Message-ID: <2024021516-stricken-bubble-bf8d@gregkh>

On Thu, Feb 15, 2024 at 11:28:27AM +0100, Andreas Schwab wrote:
> On Feb 15 2024, Tony Lindgren wrote:
> 
> > There was a regression recently with the PMIC which would cause NFSroot
> > on devices to keep working but may have affected MMC. Please check that
> > commit 7a29fa05aeca ("mfd: twl6030-irq: Revert to use of_match_device()")
> > is applied.
> 
> That commit hasn't hit stable yet.  Maybe it's because it references a
> non-existant commit id (1e0c866887f4 instead of 830fafce06e6).

Yeah, our tools can't do about a commit that does not have a cc: stable@
tag in it AND the only commit it does reference is not one actually in
the tree at all.

An impossible task for us here, please ask stable at vger.kernel.org to
take the commit if this is needed, and let us know how far back it
should go.

thanks,

greg k-h


From mark.rutland at arm.com  Thu Feb 15 03:17:59 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:17:59 +0000
Subject: [PATCH v6 04/18] arm64/mm: Convert pte_next_pfn() to
 pte_advance_pfn()
In-Reply-To: <20240215103205.2607016-5-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-5-ryan.roberts@arm.com>
Message-ID: <Zc3y5xVnazx5jgwv@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:31:51AM +0000, Ryan Roberts wrote:
> Core-mm needs to be able to advance the pfn by an arbitrary amount, so
> override the new pte_advance_pfn() API to do so.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/pgtable.h | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 52d0b0a763f1..b6d3e9e0a946 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -351,10 +351,10 @@ static inline pgprot_t pte_pgprot(pte_t pte)
>  	return __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte));
>  }
>  
> -#define pte_next_pfn pte_next_pfn
> -static inline pte_t pte_next_pfn(pte_t pte)
> +#define pte_advance_pfn pte_advance_pfn
> +static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>  {
> -	return pfn_pte(pte_pfn(pte) + 1, pte_pgprot(pte));
> +	return pfn_pte(pte_pfn(pte) + nr, pte_pgprot(pte));
>  }
>  
>  static inline void set_ptes(struct mm_struct *mm,
> @@ -370,7 +370,7 @@ static inline void set_ptes(struct mm_struct *mm,
>  		if (--nr == 0)
>  			break;
>  		ptep++;
> -		pte = pte_next_pfn(pte);
> +		pte = pte_advance_pfn(pte, 1);
>  	}
>  }
>  #define set_ptes set_ptes
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Thu Feb 15 03:18:46 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:18:46 +0000
Subject: [PATCH v6 07/18] arm64/mm: Convert READ_ONCE(*ptep) to
 ptep_get(ptep)
In-Reply-To: <20240215103205.2607016-8-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-8-ryan.roberts@arm.com>
Message-ID: <Zc3zFpQtO7QxALWB@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:31:54AM +0000, Ryan Roberts wrote:
> There are a number of places in the arch code that read a pte by using
> the READ_ONCE() macro. Refactor these call sites to instead use the
> ptep_get() helper, which itself is a READ_ONCE(). Generated code should
> be the same.
> 
> This will benefit us when we shortly introduce the transparent contpte
> support. In this case, ptep_get() will become more complex so we now
> have all the code abstracted through it.
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/pgtable.h | 12 +++++++++---
>  arch/arm64/kernel/efi.c          |  2 +-
>  arch/arm64/mm/fault.c            |  4 ++--
>  arch/arm64/mm/hugetlbpage.c      |  6 +++---
>  arch/arm64/mm/kasan_init.c       |  2 +-
>  arch/arm64/mm/mmu.c              | 12 ++++++------
>  arch/arm64/mm/pageattr.c         |  4 ++--
>  arch/arm64/mm/trans_pgd.c        |  2 +-
>  8 files changed, 25 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index b6d3e9e0a946..de034ca40bad 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -275,6 +275,12 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
>  	}
>  }
>  
> +#define ptep_get ptep_get
> +static inline pte_t ptep_get(pte_t *ptep)
> +{
> +	return READ_ONCE(*ptep);
> +}
> +
>  extern void __sync_icache_dcache(pte_t pteval);
>  bool pgattr_change_is_safe(u64 old, u64 new);
>  
> @@ -302,7 +308,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
>  	if (!IS_ENABLED(CONFIG_DEBUG_VM))
>  		return;
>  
> -	old_pte = READ_ONCE(*ptep);
> +	old_pte = ptep_get(ptep);
>  
>  	if (!pte_valid(old_pte) || !pte_valid(pte))
>  		return;
> @@ -904,7 +910,7 @@ static inline int __ptep_test_and_clear_young(pte_t *ptep)
>  {
>  	pte_t old_pte, pte;
>  
> -	pte = READ_ONCE(*ptep);
> +	pte = ptep_get(ptep);
>  	do {
>  		old_pte = pte;
>  		pte = pte_mkold(pte);
> @@ -986,7 +992,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
>  {
>  	pte_t old_pte, pte;
>  
> -	pte = READ_ONCE(*ptep);
> +	pte = ptep_get(ptep);
>  	do {
>  		old_pte = pte;
>  		pte = pte_wrprotect(pte);
> diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
> index 0228001347be..d0e08e93b246 100644
> --- a/arch/arm64/kernel/efi.c
> +++ b/arch/arm64/kernel/efi.c
> @@ -103,7 +103,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
>  {
>  	struct set_perm_data *spd = data;
>  	const efi_memory_desc_t *md = spd->md;
> -	pte_t pte = READ_ONCE(*ptep);
> +	pte_t pte = ptep_get(ptep);
>  
>  	if (md->attribute & EFI_MEMORY_RO)
>  		pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 55f6455a8284..a254761fa1bd 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -191,7 +191,7 @@ static void show_pte(unsigned long addr)
>  		if (!ptep)
>  			break;
>  
> -		pte = READ_ONCE(*ptep);
> +		pte = ptep_get(ptep);
>  		pr_cont(", pte=%016llx", pte_val(pte));
>  		pte_unmap(ptep);
>  	} while(0);
> @@ -214,7 +214,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
>  			  pte_t entry, int dirty)
>  {
>  	pteval_t old_pteval, pteval;
> -	pte_t pte = READ_ONCE(*ptep);
> +	pte_t pte = ptep_get(ptep);
>  
>  	if (pte_same(pte, entry))
>  		return 0;
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 6720ec8d50e7..2892f925ed66 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -485,7 +485,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
>  	size_t pgsize;
>  	pte_t pte;
>  
> -	if (!pte_cont(READ_ONCE(*ptep))) {
> +	if (!pte_cont(ptep_get(ptep))) {
>  		ptep_set_wrprotect(mm, addr, ptep);
>  		return;
>  	}
> @@ -510,7 +510,7 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
>  	size_t pgsize;
>  	int ncontig;
>  
> -	if (!pte_cont(READ_ONCE(*ptep)))
> +	if (!pte_cont(ptep_get(ptep)))
>  		return ptep_clear_flush(vma, addr, ptep);
>  
>  	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
> @@ -543,7 +543,7 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr
>  		 * when the permission changes from executable to non-executable
>  		 * in cases where cpu is affected with errata #2645198.
>  		 */
> -		if (pte_user_exec(READ_ONCE(*ptep)))
> +		if (pte_user_exec(ptep_get(ptep)))
>  			return huge_ptep_clear_flush(vma, addr, ptep);
>  	}
>  	return huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
> diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
> index 4c7ad574b946..c2a9f4f6c7dd 100644
> --- a/arch/arm64/mm/kasan_init.c
> +++ b/arch/arm64/mm/kasan_init.c
> @@ -113,7 +113,7 @@ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
>  			memset(__va(page_phys), KASAN_SHADOW_INIT, PAGE_SIZE);
>  		next = addr + PAGE_SIZE;
>  		set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
> -	} while (ptep++, addr = next, addr != end && pte_none(READ_ONCE(*ptep)));
> +	} while (ptep++, addr = next, addr != end && pte_none(ptep_get(ptep)));
>  }
>  
>  static void __init kasan_pmd_populate(pud_t *pudp, unsigned long addr,
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 3a27d887f7dd..343629a17042 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -173,7 +173,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
>  
>  	ptep = pte_set_fixmap_offset(pmdp, addr);
>  	do {
> -		pte_t old_pte = READ_ONCE(*ptep);
> +		pte_t old_pte = ptep_get(ptep);
>  
>  		set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
>  
> @@ -182,7 +182,7 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
>  		 * only allow updates to the permission attributes.
>  		 */
>  		BUG_ON(!pgattr_change_is_safe(pte_val(old_pte),
> -					      READ_ONCE(pte_val(*ptep))));
> +					      pte_val(ptep_get(ptep))));
>  
>  		phys += PAGE_SIZE;
>  	} while (ptep++, addr += PAGE_SIZE, addr != end);
> @@ -852,7 +852,7 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
>  
>  	do {
>  		ptep = pte_offset_kernel(pmdp, addr);
> -		pte = READ_ONCE(*ptep);
> +		pte = ptep_get(ptep);
>  		if (pte_none(pte))
>  			continue;
>  
> @@ -985,7 +985,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
>  
>  	do {
>  		ptep = pte_offset_kernel(pmdp, addr);
> -		pte = READ_ONCE(*ptep);
> +		pte = ptep_get(ptep);
>  
>  		/*
>  		 * This is just a sanity check here which verifies that
> @@ -1004,7 +1004,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
>  	 */
>  	ptep = pte_offset_kernel(pmdp, 0UL);
>  	for (i = 0; i < PTRS_PER_PTE; i++) {
> -		if (!pte_none(READ_ONCE(ptep[i])))
> +		if (!pte_none(ptep_get(&ptep[i])))
>  			return;
>  	}
>  
> @@ -1473,7 +1473,7 @@ pte_t ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, pte
>  		 * when the permission changes from executable to non-executable
>  		 * in cases where cpu is affected with errata #2645198.
>  		 */
> -		if (pte_user_exec(READ_ONCE(*ptep)))
> +		if (pte_user_exec(ptep_get(ptep)))
>  			return ptep_clear_flush(vma, addr, ptep);
>  	}
>  	return ptep_get_and_clear(vma->vm_mm, addr, ptep);
> diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> index 924843f1f661..73a5e8f82586 100644
> --- a/arch/arm64/mm/pageattr.c
> +++ b/arch/arm64/mm/pageattr.c
> @@ -36,7 +36,7 @@ bool can_set_direct_map(void)
>  static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
>  {
>  	struct page_change_data *cdata = data;
> -	pte_t pte = READ_ONCE(*ptep);
> +	pte_t pte = ptep_get(ptep);
>  
>  	pte = clear_pte_bit(pte, cdata->clear_mask);
>  	pte = set_pte_bit(pte, cdata->set_mask);
> @@ -245,5 +245,5 @@ bool kernel_page_present(struct page *page)
>  		return true;
>  
>  	ptep = pte_offset_kernel(pmdp, addr);
> -	return pte_valid(READ_ONCE(*ptep));
> +	return pte_valid(ptep_get(ptep));
>  }
> diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
> index 7b14df3c6477..f71ab4704cce 100644
> --- a/arch/arm64/mm/trans_pgd.c
> +++ b/arch/arm64/mm/trans_pgd.c
> @@ -33,7 +33,7 @@ static void *trans_alloc(struct trans_pgd_info *info)
>  
>  static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
>  {
> -	pte_t pte = READ_ONCE(*src_ptep);
> +	pte_t pte = ptep_get(src_ptep);
>  
>  	if (pte_valid(pte)) {
>  		/*
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Thu Feb 15 03:19:28 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:19:28 +0000
Subject: [PATCH v6 08/18] arm64/mm: Convert set_pte_at() to set_ptes(...,
 1)
In-Reply-To: <20240215103205.2607016-9-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-9-ryan.roberts@arm.com>
Message-ID: <Zc3zQPkI6AHF7ZQd@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:31:55AM +0000, Ryan Roberts wrote:
> Since set_ptes() was introduced, set_pte_at() has been implemented as a
> generic macro around set_ptes(..., 1). So this change should continue to
> generate the same code. However, making this change prepares us for the
> transparent contpte support. It means we can reroute set_ptes() to
> __set_ptes(). Since set_pte_at() is a generic macro, there will be no
> equivalent __set_pte_at() to reroute to.
> 
> Note that a couple of calls to set_pte_at() remain in the arch code.
> This is intentional, since those call sites are acting on behalf of
> core-mm and should continue to call into the public set_ptes() rather
> than the arch-private __set_ptes().
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/pgtable.h |  2 +-
>  arch/arm64/kernel/mte.c          |  2 +-
>  arch/arm64/kvm/guest.c           |  2 +-
>  arch/arm64/mm/fault.c            |  2 +-
>  arch/arm64/mm/hugetlbpage.c      | 10 +++++-----
>  5 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index de034ca40bad..9a2df85eb493 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -1084,7 +1084,7 @@ static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
>  #endif /* CONFIG_ARM64_MTE */
>  
>  /*
> - * On AArch64, the cache coherency is handled via the set_pte_at() function.
> + * On AArch64, the cache coherency is handled via the set_ptes() function.
>   */
>  static inline void update_mmu_cache_range(struct vm_fault *vmf,
>  		struct vm_area_struct *vma, unsigned long addr, pte_t *ptep,
> diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
> index a41ef3213e1e..59bfe2e96f8f 100644
> --- a/arch/arm64/kernel/mte.c
> +++ b/arch/arm64/kernel/mte.c
> @@ -67,7 +67,7 @@ int memcmp_pages(struct page *page1, struct page *page2)
>  	/*
>  	 * If the page content is identical but at least one of the pages is
>  	 * tagged, return non-zero to avoid KSM merging. If only one of the
> -	 * pages is tagged, set_pte_at() may zero or change the tags of the
> +	 * pages is tagged, set_ptes() may zero or change the tags of the
>  	 * other page via mte_sync_tags().
>  	 */
>  	if (page_mte_tagged(page1) || page_mte_tagged(page2))
> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
> index aaf1d4939739..6e0df623c8e9 100644
> --- a/arch/arm64/kvm/guest.c
> +++ b/arch/arm64/kvm/guest.c
> @@ -1072,7 +1072,7 @@ int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
>  		} else {
>  			/*
>  			 * Only locking to serialise with a concurrent
> -			 * set_pte_at() in the VMM but still overriding the
> +			 * set_ptes() in the VMM but still overriding the
>  			 * tags, hence ignoring the return value.
>  			 */
>  			try_page_mte_tagging(page);
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index a254761fa1bd..3235e23309ec 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -205,7 +205,7 @@ static void show_pte(unsigned long addr)
>   *
>   * It needs to cope with hardware update of the accessed/dirty state by other
>   * agents in the system and can safely skip the __sync_icache_dcache() call as,
> - * like set_pte_at(), the PTE is never changed from no-exec to exec here.
> + * like set_ptes(), the PTE is never changed from no-exec to exec here.
>   *
>   * Returns whether or not the PTE actually changed.
>   */
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 2892f925ed66..27f6160890d1 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -247,12 +247,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
>  
>  	if (!pte_present(pte)) {
>  		for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
> -			set_pte_at(mm, addr, ptep, pte);
> +			set_ptes(mm, addr, ptep, pte, 1);
>  		return;
>  	}
>  
>  	if (!pte_cont(pte)) {
> -		set_pte_at(mm, addr, ptep, pte);
> +		set_ptes(mm, addr, ptep, pte, 1);
>  		return;
>  	}
>  
> @@ -263,7 +263,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
>  	clear_flush(mm, addr, ptep, pgsize, ncontig);
>  
>  	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
> -		set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
> +		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
>  }
>  
>  pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
> @@ -471,7 +471,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
>  
>  	hugeprot = pte_pgprot(pte);
>  	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
> -		set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
> +		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
>  
>  	return 1;
>  }
> @@ -500,7 +500,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
>  	pfn = pte_pfn(pte);
>  
>  	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
> -		set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
> +		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
>  }
>  
>  pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Thu Feb 15 03:20:21 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:20:21 +0000
Subject: [PATCH v6 09/18] arm64/mm: Convert ptep_clear() to
 ptep_get_and_clear()
In-Reply-To: <20240215103205.2607016-10-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-10-ryan.roberts@arm.com>
Message-ID: <Zc3zdawsMCsEb9Q4@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:31:56AM +0000, Ryan Roberts wrote:
> ptep_clear() is a generic wrapper around the arch-implemented
> ptep_get_and_clear(). We are about to convert ptep_get_and_clear() into
> a public version and private version (__ptep_get_and_clear()) to support
> the transparent contpte work. We won't have a private version of
> ptep_clear() so let's convert it to directly call ptep_get_and_clear().
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/mm/hugetlbpage.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 27f6160890d1..48e8b429879d 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -229,7 +229,7 @@ static void clear_flush(struct mm_struct *mm,
>  	unsigned long i, saddr = addr;
>  
>  	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
> -		ptep_clear(mm, addr, ptep);
> +		ptep_get_and_clear(mm, addr, ptep);
>  
>  	flush_tlb_range(&vma, saddr, addr);
>  }
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Thu Feb 15 03:23:17 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:23:17 +0000
Subject: [PATCH v6 10/18] arm64/mm: New ptep layer to manage contig bit
In-Reply-To: <20240215103205.2607016-11-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-11-ryan.roberts@arm.com>
Message-ID: <Zc30JQJEoAMqdt_T@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:31:57AM +0000, Ryan Roberts wrote:
> Create a new layer for the in-table PTE manipulation APIs. For now, The
> existing API is prefixed with double underscore to become the
> arch-private API and the public API is just a simple wrapper that calls
> the private API.
> 
> The public API implementation will subsequently be used to transparently
> manipulate the contiguous bit where appropriate. But since there are
> already some contig-aware users (e.g. hugetlb, kernel mapper), we must
> first ensure those users use the private API directly so that the future
> contig-bit manipulations in the public API do not interfere with those
> existing uses.
> 
> The following APIs are treated this way:
> 
>  - ptep_get
>  - set_pte
>  - set_ptes
>  - pte_clear
>  - ptep_get_and_clear
>  - ptep_test_and_clear_young
>  - ptep_clear_flush_young
>  - ptep_set_wrprotect
>  - ptep_set_access_flags
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/pgtable.h | 83 +++++++++++++++++---------------
>  arch/arm64/kernel/efi.c          |  4 +-
>  arch/arm64/kernel/mte.c          |  2 +-
>  arch/arm64/kvm/guest.c           |  2 +-
>  arch/arm64/mm/fault.c            | 12 ++---
>  arch/arm64/mm/fixmap.c           |  4 +-
>  arch/arm64/mm/hugetlbpage.c      | 40 +++++++--------
>  arch/arm64/mm/kasan_init.c       |  6 +--
>  arch/arm64/mm/mmu.c              | 14 +++---
>  arch/arm64/mm/pageattr.c         |  6 +--
>  arch/arm64/mm/trans_pgd.c        |  6 +--
>  11 files changed, 93 insertions(+), 86 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 9a2df85eb493..7336d40a893a 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -93,7 +93,8 @@ 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(ptep, __pte(0))
>  #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
>  
>  /*
> @@ -137,7 +138,7 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>   * so that we don't erroneously return false for pages that have been
>   * remapped as PROT_NONE but are yet to be flushed from the TLB.
>   * Note that we can't make any assumptions based on the state of the access
> - * flag, since ptep_clear_flush_young() elides a DSB when invalidating the
> + * flag, since __ptep_clear_flush_young() elides a DSB when invalidating the
>   * TLB.
>   */
>  #define pte_accessible(mm, pte)	\
> @@ -261,7 +262,7 @@ static inline pte_t pte_mkdevmap(pte_t pte)
>  	return set_pte_bit(pte, __pgprot(PTE_DEVMAP | PTE_SPECIAL));
>  }
>  
> -static inline void set_pte(pte_t *ptep, pte_t pte)
> +static inline void __set_pte(pte_t *ptep, pte_t pte)
>  {
>  	WRITE_ONCE(*ptep, pte);
>  
> @@ -275,8 +276,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
>  	}
>  }
>  
> -#define ptep_get ptep_get
> -static inline pte_t ptep_get(pte_t *ptep)
> +static inline pte_t __ptep_get(pte_t *ptep)
>  {
>  	return READ_ONCE(*ptep);
>  }
> @@ -308,7 +308,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
>  	if (!IS_ENABLED(CONFIG_DEBUG_VM))
>  		return;
>  
> -	old_pte = ptep_get(ptep);
> +	old_pte = __ptep_get(ptep);
>  
>  	if (!pte_valid(old_pte) || !pte_valid(pte))
>  		return;
> @@ -317,7 +317,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
>  
>  	/*
>  	 * Check for potential race with hardware updates of the pte
> -	 * (ptep_set_access_flags safely changes valid ptes without going
> +	 * (__ptep_set_access_flags safely changes valid ptes without going
>  	 * through an invalid entry).
>  	 */
>  	VM_WARN_ONCE(!pte_young(pte),
> @@ -363,23 +363,22 @@ static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
>  	return pfn_pte(pte_pfn(pte) + nr, pte_pgprot(pte));
>  }
>  
> -static inline void set_ptes(struct mm_struct *mm,
> -			    unsigned long __always_unused addr,
> -			    pte_t *ptep, pte_t pte, unsigned int nr)
> +static inline void __set_ptes(struct mm_struct *mm,
> +			      unsigned long __always_unused addr,
> +			      pte_t *ptep, pte_t pte, unsigned int nr)
>  {
>  	page_table_check_ptes_set(mm, ptep, pte, nr);
>  	__sync_cache_and_tags(pte, nr);
>  
>  	for (;;) {
>  		__check_safe_pte_update(mm, ptep, pte);
> -		set_pte(ptep, pte);
> +		__set_pte(ptep, pte);
>  		if (--nr == 0)
>  			break;
>  		ptep++;
>  		pte = pte_advance_pfn(pte, 1);
>  	}
>  }
> -#define set_ptes set_ptes
>  
>  /*
>   * Huge pte definitions.
> @@ -546,7 +545,7 @@ static inline void __set_pte_at(struct mm_struct *mm,
>  {
>  	__sync_cache_and_tags(pte, nr);
>  	__check_safe_pte_update(mm, ptep, pte);
> -	set_pte(ptep, pte);
> +	__set_pte(ptep, pte);
>  }
>  
>  static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
> @@ -860,8 +859,7 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
>  	return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
>  }
>  
> -#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
> -extern int ptep_set_access_flags(struct vm_area_struct *vma,
> +extern int __ptep_set_access_flags(struct vm_area_struct *vma,
>  				 unsigned long address, pte_t *ptep,
>  				 pte_t entry, int dirty);
>  
> @@ -871,7 +869,8 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
>  					unsigned long address, pmd_t *pmdp,
>  					pmd_t entry, int dirty)
>  {
> -	return ptep_set_access_flags(vma, address, (pte_t *)pmdp, pmd_pte(entry), dirty);
> +	return __ptep_set_access_flags(vma, address, (pte_t *)pmdp,
> +							pmd_pte(entry), dirty);
>  }
>  
>  static inline int pud_devmap(pud_t pud)
> @@ -905,12 +904,13 @@ static inline bool pud_user_accessible_page(pud_t pud)
>  /*
>   * 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 vm_area_struct *vma,
> +					      unsigned long address,
> +					      pte_t *ptep)
>  {
>  	pte_t old_pte, pte;
>  
> -	pte = ptep_get(ptep);
> +	pte = __ptep_get(ptep);
>  	do {
>  		old_pte = pte;
>  		pte = pte_mkold(pte);
> @@ -921,18 +921,10 @@ static inline int __ptep_test_and_clear_young(pte_t *ptep)
>  	return pte_young(pte);
>  }
>  
> -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);
> -}
> -
> -#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
> -static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
> +static inline int __ptep_clear_flush_young(struct vm_area_struct *vma,
>  					 unsigned long address, pte_t *ptep)
>  {
> -	int young = ptep_test_and_clear_young(vma, address, ptep);
> +	int young = __ptep_test_and_clear_young(vma, address, ptep);
>  
>  	if (young) {
>  		/*
> @@ -955,12 +947,11 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
>  					    unsigned long address,
>  					    pmd_t *pmdp)
>  {
> -	return ptep_test_and_clear_young(vma, address, (pte_t *)pmdp);
> +	return __ptep_test_and_clear_young(vma, address, (pte_t *)pmdp);
>  }
>  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
>  
> -#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
> -static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
> +static inline pte_t __ptep_get_and_clear(struct mm_struct *mm,
>  				       unsigned long address, pte_t *ptep)
>  {
>  	pte_t pte = __pte(xchg_relaxed(&pte_val(*ptep), 0));
> @@ -984,15 +975,15 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
>  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
>  
>  /*
> - * ptep_set_wrprotect - mark read-only while trasferring potential hardware
> + * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
>   * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
>   */
> -#define __HAVE_ARCH_PTEP_SET_WRPROTECT
> -static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
> +static inline void __ptep_set_wrprotect(struct mm_struct *mm,
> +					unsigned long address, pte_t *ptep)
>  {
>  	pte_t old_pte, pte;
>  
> -	pte = ptep_get(ptep);
> +	pte = __ptep_get(ptep);
>  	do {
>  		old_pte = pte;
>  		pte = pte_wrprotect(pte);
> @@ -1006,7 +997,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
>  static inline void pmdp_set_wrprotect(struct mm_struct *mm,
>  				      unsigned long address, pmd_t *pmdp)
>  {
> -	ptep_set_wrprotect(mm, address, (pte_t *)pmdp);
> +	__ptep_set_wrprotect(mm, address, (pte_t *)pmdp);
>  }
>  
>  #define pmdp_establish pmdp_establish
> @@ -1084,7 +1075,7 @@ static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
>  #endif /* CONFIG_ARM64_MTE */
>  
>  /*
> - * On AArch64, the cache coherency is handled via the set_ptes() function.
> + * On AArch64, the cache coherency is handled via the __set_ptes() function.
>   */
>  static inline void update_mmu_cache_range(struct vm_fault *vmf,
>  		struct vm_area_struct *vma, unsigned long addr, pte_t *ptep,
> @@ -1136,6 +1127,22 @@ extern pte_t ptep_modify_prot_start(struct vm_area_struct *vma,
>  extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
>  				    unsigned long addr, pte_t *ptep,
>  				    pte_t old_pte, pte_t new_pte);
> +
> +#define ptep_get				__ptep_get
> +#define set_pte					__set_pte
> +#define set_ptes				__set_ptes
> +#define pte_clear				__pte_clear
> +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
> +#define ptep_get_and_clear			__ptep_get_and_clear
> +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
> +#define ptep_test_and_clear_young		__ptep_test_and_clear_young
> +#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
> +#define ptep_clear_flush_young			__ptep_clear_flush_young
> +#define __HAVE_ARCH_PTEP_SET_WRPROTECT
> +#define ptep_set_wrprotect			__ptep_set_wrprotect
> +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
> +#define ptep_set_access_flags			__ptep_set_access_flags
> +
>  #endif /* !__ASSEMBLY__ */
>  
>  #endif /* __ASM_PGTABLE_H */
> diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
> index d0e08e93b246..9afcc690fe73 100644
> --- a/arch/arm64/kernel/efi.c
> +++ b/arch/arm64/kernel/efi.c
> @@ -103,7 +103,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
>  {
>  	struct set_perm_data *spd = data;
>  	const efi_memory_desc_t *md = spd->md;
> -	pte_t pte = ptep_get(ptep);
> +	pte_t pte = __ptep_get(ptep);
>  
>  	if (md->attribute & EFI_MEMORY_RO)
>  		pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
> @@ -111,7 +111,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
>  		pte = set_pte_bit(pte, __pgprot(PTE_PXN));
>  	else if (system_supports_bti_kernel() && spd->has_bti)
>  		pte = set_pte_bit(pte, __pgprot(PTE_GP));
> -	set_pte(ptep, pte);
> +	__set_pte(ptep, pte);
>  	return 0;
>  }
>  
> diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
> index 59bfe2e96f8f..dcdcccd40891 100644
> --- a/arch/arm64/kernel/mte.c
> +++ b/arch/arm64/kernel/mte.c
> @@ -67,7 +67,7 @@ int memcmp_pages(struct page *page1, struct page *page2)
>  	/*
>  	 * If the page content is identical but at least one of the pages is
>  	 * tagged, return non-zero to avoid KSM merging. If only one of the
> -	 * pages is tagged, set_ptes() may zero or change the tags of the
> +	 * pages is tagged, __set_ptes() may zero or change the tags of the
>  	 * other page via mte_sync_tags().
>  	 */
>  	if (page_mte_tagged(page1) || page_mte_tagged(page2))
> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
> index 6e0df623c8e9..629145fd3161 100644
> --- a/arch/arm64/kvm/guest.c
> +++ b/arch/arm64/kvm/guest.c
> @@ -1072,7 +1072,7 @@ int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
>  		} else {
>  			/*
>  			 * Only locking to serialise with a concurrent
> -			 * set_ptes() in the VMM but still overriding the
> +			 * __set_ptes() in the VMM but still overriding the
>  			 * tags, hence ignoring the return value.
>  			 */
>  			try_page_mte_tagging(page);
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 3235e23309ec..9a1c66183d16 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -191,7 +191,7 @@ static void show_pte(unsigned long addr)
>  		if (!ptep)
>  			break;
>  
> -		pte = ptep_get(ptep);
> +		pte = __ptep_get(ptep);
>  		pr_cont(", pte=%016llx", pte_val(pte));
>  		pte_unmap(ptep);
>  	} while(0);
> @@ -205,16 +205,16 @@ static void show_pte(unsigned long addr)
>   *
>   * It needs to cope with hardware update of the accessed/dirty state by other
>   * agents in the system and can safely skip the __sync_icache_dcache() call as,
> - * like set_ptes(), the PTE is never changed from no-exec to exec here.
> + * like __set_ptes(), the PTE is never changed from no-exec to exec here.
>   *
>   * Returns whether or not the PTE actually changed.
>   */
> -int ptep_set_access_flags(struct vm_area_struct *vma,
> -			  unsigned long address, pte_t *ptep,
> -			  pte_t entry, int dirty)
> +int __ptep_set_access_flags(struct vm_area_struct *vma,
> +			    unsigned long address, pte_t *ptep,
> +			    pte_t entry, int dirty)
>  {
>  	pteval_t old_pteval, pteval;
> -	pte_t pte = ptep_get(ptep);
> +	pte_t pte = __ptep_get(ptep);
>  
>  	if (pte_same(pte, entry))
>  		return 0;
> diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
> index c0a3301203bd..bfc02568805a 100644
> --- a/arch/arm64/mm/fixmap.c
> +++ b/arch/arm64/mm/fixmap.c
> @@ -121,9 +121,9 @@ void __set_fixmap(enum fixed_addresses idx,
>  	ptep = fixmap_pte(addr);
>  
>  	if (pgprot_val(flags)) {
> -		set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
> +		__set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
>  	} else {
> -		pte_clear(&init_mm, addr, ptep);
> +		__pte_clear(&init_mm, addr, ptep);
>  		flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
>  	}
>  }
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 48e8b429879d..0f0e10bb0a95 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -145,14 +145,14 @@ pte_t huge_ptep_get(pte_t *ptep)
>  {
>  	int ncontig, i;
>  	size_t pgsize;
> -	pte_t orig_pte = ptep_get(ptep);
> +	pte_t orig_pte = __ptep_get(ptep);
>  
>  	if (!pte_present(orig_pte) || !pte_cont(orig_pte))
>  		return orig_pte;
>  
>  	ncontig = num_contig_ptes(page_size(pte_page(orig_pte)), &pgsize);
>  	for (i = 0; i < ncontig; i++, ptep++) {
> -		pte_t pte = ptep_get(ptep);
> +		pte_t pte = __ptep_get(ptep);
>  
>  		if (pte_dirty(pte))
>  			orig_pte = pte_mkdirty(orig_pte);
> @@ -177,11 +177,11 @@ static pte_t get_clear_contig(struct mm_struct *mm,
>  			     unsigned long pgsize,
>  			     unsigned long ncontig)
>  {
> -	pte_t orig_pte = ptep_get(ptep);
> +	pte_t orig_pte = __ptep_get(ptep);
>  	unsigned long i;
>  
>  	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) {
> -		pte_t pte = ptep_get_and_clear(mm, addr, ptep);
> +		pte_t pte = __ptep_get_and_clear(mm, addr, ptep);
>  
>  		/*
>  		 * If HW_AFDBM is enabled, then the HW could turn on
> @@ -229,7 +229,7 @@ static void clear_flush(struct mm_struct *mm,
>  	unsigned long i, saddr = addr;
>  
>  	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
> -		ptep_get_and_clear(mm, addr, ptep);
> +		__ptep_get_and_clear(mm, addr, ptep);
>  
>  	flush_tlb_range(&vma, saddr, addr);
>  }
> @@ -247,12 +247,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
>  
>  	if (!pte_present(pte)) {
>  		for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
> -			set_ptes(mm, addr, ptep, pte, 1);
> +			__set_ptes(mm, addr, ptep, pte, 1);
>  		return;
>  	}
>  
>  	if (!pte_cont(pte)) {
> -		set_ptes(mm, addr, ptep, pte, 1);
> +		__set_ptes(mm, addr, ptep, pte, 1);
>  		return;
>  	}
>  
> @@ -263,7 +263,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
>  	clear_flush(mm, addr, ptep, pgsize, ncontig);
>  
>  	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
> -		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
> +		__set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
>  }
>  
>  pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
> @@ -393,7 +393,7 @@ void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
>  	ncontig = num_contig_ptes(sz, &pgsize);
>  
>  	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
> -		pte_clear(mm, addr, ptep);
> +		__pte_clear(mm, addr, ptep);
>  }
>  
>  pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
> @@ -401,10 +401,10 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
>  {
>  	int ncontig;
>  	size_t pgsize;
> -	pte_t orig_pte = ptep_get(ptep);
> +	pte_t orig_pte = __ptep_get(ptep);
>  
>  	if (!pte_cont(orig_pte))
> -		return ptep_get_and_clear(mm, addr, ptep);
> +		return __ptep_get_and_clear(mm, addr, ptep);
>  
>  	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
>  
> @@ -424,11 +424,11 @@ static int __cont_access_flags_changed(pte_t *ptep, pte_t pte, int ncontig)
>  {
>  	int i;
>  
> -	if (pte_write(pte) != pte_write(ptep_get(ptep)))
> +	if (pte_write(pte) != pte_write(__ptep_get(ptep)))
>  		return 1;
>  
>  	for (i = 0; i < ncontig; i++) {
> -		pte_t orig_pte = ptep_get(ptep + i);
> +		pte_t orig_pte = __ptep_get(ptep + i);
>  
>  		if (pte_dirty(pte) != pte_dirty(orig_pte))
>  			return 1;
> @@ -452,7 +452,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
>  	pte_t orig_pte;
>  
>  	if (!pte_cont(pte))
> -		return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
> +		return __ptep_set_access_flags(vma, addr, ptep, pte, dirty);
>  
>  	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
>  	dpfn = pgsize >> PAGE_SHIFT;
> @@ -471,7 +471,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
>  
>  	hugeprot = pte_pgprot(pte);
>  	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
> -		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
> +		__set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
>  
>  	return 1;
>  }
> @@ -485,8 +485,8 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
>  	size_t pgsize;
>  	pte_t pte;
>  
> -	if (!pte_cont(ptep_get(ptep))) {
> -		ptep_set_wrprotect(mm, addr, ptep);
> +	if (!pte_cont(__ptep_get(ptep))) {
> +		__ptep_set_wrprotect(mm, addr, ptep);
>  		return;
>  	}
>  
> @@ -500,7 +500,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
>  	pfn = pte_pfn(pte);
>  
>  	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
> -		set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
> +		__set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
>  }
>  
>  pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
> @@ -510,7 +510,7 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
>  	size_t pgsize;
>  	int ncontig;
>  
> -	if (!pte_cont(ptep_get(ptep)))
> +	if (!pte_cont(__ptep_get(ptep)))
>  		return ptep_clear_flush(vma, addr, ptep);
>  
>  	ncontig = find_num_contig(mm, addr, ptep, &pgsize);
> @@ -543,7 +543,7 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr
>  		 * when the permission changes from executable to non-executable
>  		 * in cases where cpu is affected with errata #2645198.
>  		 */
> -		if (pte_user_exec(ptep_get(ptep)))
> +		if (pte_user_exec(__ptep_get(ptep)))
>  			return huge_ptep_clear_flush(vma, addr, ptep);
>  	}
>  	return huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
> diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
> index c2a9f4f6c7dd..9ee16cfce587 100644
> --- a/arch/arm64/mm/kasan_init.c
> +++ b/arch/arm64/mm/kasan_init.c
> @@ -112,8 +112,8 @@ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
>  		if (!early)
>  			memset(__va(page_phys), KASAN_SHADOW_INIT, PAGE_SIZE);
>  		next = addr + PAGE_SIZE;
> -		set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
> -	} while (ptep++, addr = next, addr != end && pte_none(ptep_get(ptep)));
> +		__set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
> +	} while (ptep++, addr = next, addr != end && pte_none(__ptep_get(ptep)));
>  }
>  
>  static void __init kasan_pmd_populate(pud_t *pudp, unsigned long addr,
> @@ -271,7 +271,7 @@ static void __init kasan_init_shadow(void)
>  	 * so we should make sure that it maps the zero page read-only.
>  	 */
>  	for (i = 0; i < PTRS_PER_PTE; i++)
> -		set_pte(&kasan_early_shadow_pte[i],
> +		__set_pte(&kasan_early_shadow_pte[i],
>  			pfn_pte(sym_to_pfn(kasan_early_shadow_page),
>  				PAGE_KERNEL_RO));
>  
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 343629a17042..6208c7541f87 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -173,16 +173,16 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
>  
>  	ptep = pte_set_fixmap_offset(pmdp, addr);
>  	do {
> -		pte_t old_pte = ptep_get(ptep);
> +		pte_t old_pte = __ptep_get(ptep);
>  
> -		set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
> +		__set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
>  
>  		/*
>  		 * After the PTE entry has been populated once, we
>  		 * only allow updates to the permission attributes.
>  		 */
>  		BUG_ON(!pgattr_change_is_safe(pte_val(old_pte),
> -					      pte_val(ptep_get(ptep))));
> +					      pte_val(__ptep_get(ptep))));
>  
>  		phys += PAGE_SIZE;
>  	} while (ptep++, addr += PAGE_SIZE, addr != end);
> @@ -852,12 +852,12 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
>  
>  	do {
>  		ptep = pte_offset_kernel(pmdp, addr);
> -		pte = ptep_get(ptep);
> +		pte = __ptep_get(ptep);
>  		if (pte_none(pte))
>  			continue;
>  
>  		WARN_ON(!pte_present(pte));
> -		pte_clear(&init_mm, addr, ptep);
> +		__pte_clear(&init_mm, addr, ptep);
>  		flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
>  		if (free_mapped)
>  			free_hotplug_page_range(pte_page(pte),
> @@ -985,7 +985,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
>  
>  	do {
>  		ptep = pte_offset_kernel(pmdp, addr);
> -		pte = ptep_get(ptep);
> +		pte = __ptep_get(ptep);
>  
>  		/*
>  		 * This is just a sanity check here which verifies that
> @@ -1004,7 +1004,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
>  	 */
>  	ptep = pte_offset_kernel(pmdp, 0UL);
>  	for (i = 0; i < PTRS_PER_PTE; i++) {
> -		if (!pte_none(ptep_get(&ptep[i])))
> +		if (!pte_none(__ptep_get(&ptep[i])))
>  			return;
>  	}
>  
> diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> index 73a5e8f82586..0c4e3ecf989d 100644
> --- a/arch/arm64/mm/pageattr.c
> +++ b/arch/arm64/mm/pageattr.c
> @@ -36,12 +36,12 @@ bool can_set_direct_map(void)
>  static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
>  {
>  	struct page_change_data *cdata = data;
> -	pte_t pte = ptep_get(ptep);
> +	pte_t pte = __ptep_get(ptep);
>  
>  	pte = clear_pte_bit(pte, cdata->clear_mask);
>  	pte = set_pte_bit(pte, cdata->set_mask);
>  
> -	set_pte(ptep, pte);
> +	__set_pte(ptep, pte);
>  	return 0;
>  }
>  
> @@ -245,5 +245,5 @@ bool kernel_page_present(struct page *page)
>  		return true;
>  
>  	ptep = pte_offset_kernel(pmdp, addr);
> -	return pte_valid(ptep_get(ptep));
> +	return pte_valid(__ptep_get(ptep));
>  }
> diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
> index f71ab4704cce..5139a28130c0 100644
> --- a/arch/arm64/mm/trans_pgd.c
> +++ b/arch/arm64/mm/trans_pgd.c
> @@ -33,7 +33,7 @@ static void *trans_alloc(struct trans_pgd_info *info)
>  
>  static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
>  {
> -	pte_t pte = ptep_get(src_ptep);
> +	pte_t pte = __ptep_get(src_ptep);
>  
>  	if (pte_valid(pte)) {
>  		/*
> @@ -41,7 +41,7 @@ static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
>  		 * read only (code, rodata). Clear the RDONLY bit from
>  		 * the temporary mappings we use during restore.
>  		 */
> -		set_pte(dst_ptep, pte_mkwrite_novma(pte));
> +		__set_pte(dst_ptep, pte_mkwrite_novma(pte));
>  	} else if ((debug_pagealloc_enabled() ||
>  		   is_kfence_address((void *)addr)) && !pte_none(pte)) {
>  		/*
> @@ -55,7 +55,7 @@ static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
>  		 */
>  		BUG_ON(!pfn_valid(pte_pfn(pte)));
>  
> -		set_pte(dst_ptep, pte_mkpresent(pte_mkwrite_novma(pte)));
> +		__set_pte(dst_ptep, pte_mkpresent(pte_mkwrite_novma(pte)));
>  	}
>  }
>  
> -- 
> 2.25.1
> 


From suzuki.poulose at arm.com  Thu Feb 15 03:23:57 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu, 15 Feb 2024 11:23:57 +0000
Subject: [PATCH V4 05/11] coresight: replicator: Move ACPI support from
 AMBA driver to platform driver
In-Reply-To: <20240123054608.1790189-6-anshuman.khandual@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-6-anshuman.khandual@arm.com>
Message-ID: <b72c54bf-17a8-453c-8fbb-fbc90abdb45a@arm.com>

Hi Anshuman

On 23/01/2024 05:46, Anshuman Khandual wrote:
> Add support for the dynamic replicator device in the platform driver, which
> can then be used on ACPI based platforms. This change would now allow
> runtime power management for repliacator devices on ACPI based systems.
> 
> The driver would try to enable the APB clock if available. Also, rename the
> code to reflect the fact that it now handles both static and dynamic
> replicators.
> 
> Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: James Clark <james.clark at arm.com>
> Cc: linux-acpi at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: coresight at lists.linaro.org
> Tested-by: Sudeep Holla <sudeep.holla at arm.com> # Boot and driver probe only
> Acked-by: Sudeep Holla <sudeep.holla at arm.com> # For ACPI related changes
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>

I think the patch is doing three different things:

1) Use new helper to register/remove AMBA/Platform drivers
2) Refactor replicator_probe() to make sure it can be reused for 
platform/amba driver, by moving the pm_runtime_put() to the callers.
3) Actually moving the ACPI driver to Platform driver

While (1) and (3) are obvious, (2) gave me hard time to review this
patch, without proper description. If you don't mind, are you able to
split the patch and add proper description of the 3 changes mentioned
above.


Kind regards
Suzuki

> ---
> Changes in V4:
> 
> - Added pm_runtime_disable() in replicator_platform_probe()
> - Changed replicator_platform_remove() for platform_driver->remove_new()
> 
>   drivers/acpi/arm64/amba.c                     |  1 -
>   .../coresight/coresight-replicator.c          | 81 ++++++++++---------
>   2 files changed, 43 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c
> index 171b5c2c7edd..270f4e3819a2 100644
> --- a/drivers/acpi/arm64/amba.c
> +++ b/drivers/acpi/arm64/amba.c
> @@ -27,7 +27,6 @@ static const struct acpi_device_id amba_id_list[] = {
>   	{"ARMHC503", 0}, /* ARM CoreSight Debug */
>   	{"ARMHC979", 0}, /* ARM CoreSight TPIU */
>   	{"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
> -	{"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
>   	{"ARMHC9CA", 0}, /* ARM CoreSight CATU */
>   	{"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */
>   	{"", 0},
> diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
> index 91d93060dda5..9b5f52725f43 100644
> --- a/drivers/hwtracing/coresight/coresight-replicator.c
> +++ b/drivers/hwtracing/coresight/coresight-replicator.c
> @@ -31,6 +31,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator");
>    * @base:	memory mapped base address for this component. Also indicates
>    *		whether this one is programmable or not.
>    * @atclk:	optional clock for the core parts of the replicator.
> + * @pclk:	APB clock if present, otherwise NULL
>    * @csdev:	component vitals needed by the framework
>    * @spinlock:	serialize enable/disable operations.
>    * @check_idfilter_val: check if the context is lost upon clock removal.
> @@ -38,6 +39,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator");
>   struct replicator_drvdata {
>   	void __iomem		*base;
>   	struct clk		*atclk;
> +	struct clk		*pclk;
>   	struct coresight_device	*csdev;
>   	spinlock_t		spinlock;
>   	bool			check_idfilter_val;
> @@ -243,6 +245,10 @@ static int replicator_probe(struct device *dev, struct resource *res)
>   			return ret;
>   	}
>   
> +	drvdata->pclk = coresight_get_enable_apb_pclk(dev);
> +	if (IS_ERR(drvdata->pclk))
> +		return -ENODEV;
> +
>   	/*
>   	 * Map the device base for dynamic-replicator, which has been
>   	 * validated by AMBA core
> @@ -285,7 +291,6 @@ static int replicator_probe(struct device *dev, struct resource *res)
>   	}
>   
>   	replicator_reset(drvdata);
> -	pm_runtime_put(dev);
>   
>   out_disable_clk:
>   	if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
> @@ -301,29 +306,33 @@ static int replicator_remove(struct device *dev)
>   	return 0;
>   }
>   
> -static int static_replicator_probe(struct platform_device *pdev)
> +static int replicator_platform_probe(struct platform_device *pdev)
>   {
> +	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>   	int ret;
>   
>   	pm_runtime_get_noresume(&pdev->dev);
>   	pm_runtime_set_active(&pdev->dev);
>   	pm_runtime_enable(&pdev->dev);
>   
> -	/* Static replicators do not have programming base */
> -	ret = replicator_probe(&pdev->dev, NULL);
> -
> -	if (ret) {
> -		pm_runtime_put_noidle(&pdev->dev);
> +	ret = replicator_probe(&pdev->dev, res);
> +	pm_runtime_put(&pdev->dev);
> +	if (ret)
>   		pm_runtime_disable(&pdev->dev);
> -	}
>   
>   	return ret;
>   }
>   
> -static void static_replicator_remove(struct platform_device *pdev)
> +static void replicator_platform_remove(struct platform_device *pdev)
>   {
> -	replicator_remove(&pdev->dev);
> +	struct replicator_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
> +
> +	if (drvdata)
> +		replicator_remove(&pdev->dev);
> +
>   	pm_runtime_disable(&pdev->dev);
> +	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> +		clk_put(drvdata->pclk);
>   }
>   
>   #ifdef CONFIG_PM
> @@ -334,6 +343,8 @@ static int replicator_runtime_suspend(struct device *dev)
>   	if (drvdata && !IS_ERR(drvdata->atclk))
>   		clk_disable_unprepare(drvdata->atclk);
>   
> +	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> +		clk_disable_unprepare(drvdata->pclk);
>   	return 0;
>   }
>   
> @@ -344,6 +355,8 @@ static int replicator_runtime_resume(struct device *dev)
>   	if (drvdata && !IS_ERR(drvdata->atclk))
>   		clk_prepare_enable(drvdata->atclk);
>   
> +	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
> +		clk_prepare_enable(drvdata->pclk);
>   	return 0;
>   }
>   #endif
> @@ -353,31 +366,32 @@ static const struct dev_pm_ops replicator_dev_pm_ops = {
>   			   replicator_runtime_resume, NULL)
>   };
>   
> -static const struct of_device_id static_replicator_match[] = {
> +static const struct of_device_id replicator_match[] = {
>   	{.compatible = "arm,coresight-replicator"},
>   	{.compatible = "arm,coresight-static-replicator"},
>   	{}
>   };
>   
> -MODULE_DEVICE_TABLE(of, static_replicator_match);
> +MODULE_DEVICE_TABLE(of, replicator_match);
>   
>   #ifdef CONFIG_ACPI
> -static const struct acpi_device_id static_replicator_acpi_ids[] = {
> +static const struct acpi_device_id replicator_acpi_ids[] = {
>   	{"ARMHC985", 0}, /* ARM CoreSight Static Replicator */
> +	{"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
>   	{}
>   };
>   
> -MODULE_DEVICE_TABLE(acpi, static_replicator_acpi_ids);
> +MODULE_DEVICE_TABLE(acpi, replicator_acpi_ids);
>   #endif
>   
> -static struct platform_driver static_replicator_driver = {
> -	.probe          = static_replicator_probe,
> -	.remove_new     = static_replicator_remove,
> +static struct platform_driver replicator_driver = {
> +	.probe          = replicator_platform_probe,
> +	.remove_new     = replicator_platform_remove,
>   	.driver         = {
> -		.name   = "coresight-static-replicator",
> +		.name   = "coresight-replicator",
>   		/* THIS_MODULE is taken care of by platform_driver_register() */
> -		.of_match_table = of_match_ptr(static_replicator_match),
> -		.acpi_match_table = ACPI_PTR(static_replicator_acpi_ids),
> +		.of_match_table = of_match_ptr(replicator_match),
> +		.acpi_match_table = ACPI_PTR(replicator_acpi_ids),
>   		.pm	= &replicator_dev_pm_ops,
>   		.suppress_bind_attrs = true,
>   	},
> @@ -386,7 +400,13 @@ static struct platform_driver static_replicator_driver = {
>   static int dynamic_replicator_probe(struct amba_device *adev,
>   				    const struct amba_id *id)
>   {
> -	return replicator_probe(&adev->dev, &adev->res);
> +	int ret;
> +
> +	ret = replicator_probe(&adev->dev, &adev->res);
> +	if (!ret)
> +		pm_runtime_put(&adev->dev);
> +
> +	return ret;
>   }
>   
>   static void dynamic_replicator_remove(struct amba_device *adev)
> @@ -416,27 +436,12 @@ static struct amba_driver dynamic_replicator_driver = {
>   
>   static int __init replicator_init(void)
>   {
> -	int ret;
> -
> -	ret = platform_driver_register(&static_replicator_driver);
> -	if (ret) {
> -		pr_info("Error registering platform driver\n");
> -		return ret;
> -	}
> -
> -	ret = amba_driver_register(&dynamic_replicator_driver);
> -	if (ret) {
> -		pr_info("Error registering amba driver\n");
> -		platform_driver_unregister(&static_replicator_driver);
> -	}
> -
> -	return ret;
> +	return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver);
>   }
>   
>   static void __exit replicator_exit(void)
>   {
> -	platform_driver_unregister(&static_replicator_driver);
> -	amba_driver_unregister(&dynamic_replicator_driver);
> +	coresight_remove_driver(&dynamic_replicator_driver, &replicator_driver);
>   }
>   
>   module_init(replicator_init);



From mark.rutland at arm.com  Thu Feb 15 03:24:16 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:24:16 +0000
Subject: [PATCH v6 11/18] arm64/mm: Split __flush_tlb_range() to elide
 trailing DSB
In-Reply-To: <20240215103205.2607016-12-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-12-ryan.roberts@arm.com>
Message-ID: <Zc30YGd3yBVpLNqn@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:31:58AM +0000, Ryan Roberts wrote:
> Split __flush_tlb_range() into __flush_tlb_range_nosync() +
> __flush_tlb_range(), in the same way as the existing flush_tlb_page()
> arrangement. This allows calling __flush_tlb_range_nosync() to elide the
> trailing DSB. Forthcoming "contpte" code will take advantage of this
> when clearing the young bit from a contiguous range of ptes.
> 
> Ordering between dsb and mmu_notifier_arch_invalidate_secondary_tlbs()
> has changed, but now aligns with the ordering of __flush_tlb_page(). It
> has been discussed that __flush_tlb_page() may be wrong though.
> Regardless, both will be resolved separately if needed.
> 
> Reviewed-by: David Hildenbrand <david at redhat.com>
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/tlbflush.h | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
> index 1deb5d789c2e..3b0e8248e1a4 100644
> --- a/arch/arm64/include/asm/tlbflush.h
> +++ b/arch/arm64/include/asm/tlbflush.h
> @@ -422,7 +422,7 @@ do {									\
>  #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \
>  	__flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false, kvm_lpa2_is_enabled());
>  
> -static inline void __flush_tlb_range(struct vm_area_struct *vma,
> +static inline void __flush_tlb_range_nosync(struct vm_area_struct *vma,
>  				     unsigned long start, unsigned long end,
>  				     unsigned long stride, bool last_level,
>  				     int tlb_level)
> @@ -456,10 +456,19 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
>  		__flush_tlb_range_op(vae1is, start, pages, stride, asid,
>  				     tlb_level, true, lpa2_is_enabled());
>  
> -	dsb(ish);
>  	mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
>  }
>  
> +static inline void __flush_tlb_range(struct vm_area_struct *vma,
> +				     unsigned long start, unsigned long end,
> +				     unsigned long stride, bool last_level,
> +				     int tlb_level)
> +{
> +	__flush_tlb_range_nosync(vma, start, end, stride,
> +				 last_level, tlb_level);
> +	dsb(ish);
> +}
> +
>  static inline void flush_tlb_range(struct vm_area_struct *vma,
>  				   unsigned long start, unsigned long end)
>  {
> -- 
> 2.25.1
> 


From suzuki.poulose at arm.com  Thu Feb 15 03:25:48 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu, 15 Feb 2024 11:25:48 +0000
Subject: [PATCH V4 05/11] coresight: replicator: Move ACPI support from
 AMBA driver to platform driver
In-Reply-To: <b72c54bf-17a8-453c-8fbb-fbc90abdb45a@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-6-anshuman.khandual@arm.com>
 <b72c54bf-17a8-453c-8fbb-fbc90abdb45a@arm.com>
Message-ID: <b0c8b92e-53bc-4232-a748-ff3e6b94b112@arm.com>

On 15/02/2024 11:23, Suzuki K Poulose wrote:
> Hi Anshuman
> 
> On 23/01/2024 05:46, Anshuman Khandual wrote:
>> Add support for the dynamic replicator device in the platform driver, 
>> which
>> can then be used on ACPI based platforms. This change would now allow
>> runtime power management for repliacator devices on ACPI based systems.
>>
>> The driver would try to enable the APB clock if available. Also, 
>> rename the
>> code to reflect the fact that it now handles both static and dynamic
>> replicators.
>>
>> Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
>> Cc: Sudeep Holla <sudeep.holla at arm.com>
>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Cc: Mike Leach <mike.leach at linaro.org>
>> Cc: James Clark <james.clark at arm.com>
>> Cc: linux-acpi at vger.kernel.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: coresight at lists.linaro.org
>> Tested-by: Sudeep Holla <sudeep.holla at arm.com> # Boot and driver probe 
>> only
>> Acked-by: Sudeep Holla <sudeep.holla at arm.com> # For ACPI related changes
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> 
> I think the patch is doing three different things:
> 
> 1) Use new helper to register/remove AMBA/Platform drivers
> 2) Refactor replicator_probe() to make sure it can be reused for 
> platform/amba driver, by moving the pm_runtime_put() to the callers.
> 3) Actually moving the ACPI driver to Platform driver
> 
> While (1) and (3) are obvious, (2) gave me hard time to review this
> patch, without proper description. If you don't mind, are you able to
> split the patch and add proper description of the 3 changes mentioned
> above.
> 

You could even move (1) for all the existing drivers into a single patch
or even fold it with the patch that introduces the helpers. That way it
is cleaner and easier to review. And (2) & (3) could be in the same 
patch for each driver, but please add something in the description for (2).

Suzuki

> 
> Kind regards
> Suzuki
> 
>> ---
>> Changes in V4:
>>
>> - Added pm_runtime_disable() in replicator_platform_probe()
>> - Changed replicator_platform_remove() for platform_driver->remove_new()
>>
>> ? drivers/acpi/arm64/amba.c???????????????????? |? 1 -
>> ? .../coresight/coresight-replicator.c????????? | 81 ++++++++++---------
>> ? 2 files changed, 43 insertions(+), 39 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c
>> index 171b5c2c7edd..270f4e3819a2 100644
>> --- a/drivers/acpi/arm64/amba.c
>> +++ b/drivers/acpi/arm64/amba.c
>> @@ -27,7 +27,6 @@ static const struct acpi_device_id amba_id_list[] = {
>> ????? {"ARMHC503", 0}, /* ARM CoreSight Debug */
>> ????? {"ARMHC979", 0}, /* ARM CoreSight TPIU */
>> ????? {"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
>> -??? {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
>> ????? {"ARMHC9CA", 0}, /* ARM CoreSight CATU */
>> ????? {"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */
>> ????? {"", 0},
>> diff --git a/drivers/hwtracing/coresight/coresight-replicator.c 
>> b/drivers/hwtracing/coresight/coresight-replicator.c
>> index 91d93060dda5..9b5f52725f43 100644
>> --- a/drivers/hwtracing/coresight/coresight-replicator.c
>> +++ b/drivers/hwtracing/coresight/coresight-replicator.c
>> @@ -31,6 +31,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, 
>> "replicator");
>> ?? * @base:??? memory mapped base address for this component. Also 
>> indicates
>> ?? *??????? whether this one is programmable or not.
>> ?? * @atclk:??? optional clock for the core parts of the replicator.
>> + * @pclk:??? APB clock if present, otherwise NULL
>> ?? * @csdev:??? component vitals needed by the framework
>> ?? * @spinlock:??? serialize enable/disable operations.
>> ?? * @check_idfilter_val: check if the context is lost upon clock 
>> removal.
>> @@ -38,6 +39,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, 
>> "replicator");
>> ? struct replicator_drvdata {
>> ????? void __iomem??????? *base;
>> ????? struct clk??????? *atclk;
>> +??? struct clk??????? *pclk;
>> ????? struct coresight_device??? *csdev;
>> ????? spinlock_t??????? spinlock;
>> ????? bool??????????? check_idfilter_val;
>> @@ -243,6 +245,10 @@ static int replicator_probe(struct device *dev, 
>> struct resource *res)
>> ????????????? return ret;
>> ????? }
>> +??? drvdata->pclk = coresight_get_enable_apb_pclk(dev);
>> +??? if (IS_ERR(drvdata->pclk))
>> +??????? return -ENODEV;
>> +
>> ????? /*
>> ?????? * Map the device base for dynamic-replicator, which has been
>> ?????? * validated by AMBA core
>> @@ -285,7 +291,6 @@ static int replicator_probe(struct device *dev, 
>> struct resource *res)
>> ????? }
>> ????? replicator_reset(drvdata);
>> -??? pm_runtime_put(dev);
>> ? out_disable_clk:
>> ????? if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
>> @@ -301,29 +306,33 @@ static int replicator_remove(struct device *dev)
>> ????? return 0;
>> ? }
>> -static int static_replicator_probe(struct platform_device *pdev)
>> +static int replicator_platform_probe(struct platform_device *pdev)
>> ? {
>> +??? struct resource *res = platform_get_resource(pdev, 
>> IORESOURCE_MEM, 0);
>> ????? int ret;
>> ????? pm_runtime_get_noresume(&pdev->dev);
>> ????? pm_runtime_set_active(&pdev->dev);
>> ????? pm_runtime_enable(&pdev->dev);
>> -??? /* Static replicators do not have programming base */
>> -??? ret = replicator_probe(&pdev->dev, NULL);
>> -
>> -??? if (ret) {
>> -??????? pm_runtime_put_noidle(&pdev->dev);
>> +??? ret = replicator_probe(&pdev->dev, res);
>> +??? pm_runtime_put(&pdev->dev);
>> +??? if (ret)
>> ????????? pm_runtime_disable(&pdev->dev);
>> -??? }
>> ????? return ret;
>> ? }
>> -static void static_replicator_remove(struct platform_device *pdev)
>> +static void replicator_platform_remove(struct platform_device *pdev)
>> ? {
>> -??? replicator_remove(&pdev->dev);
>> +??? struct replicator_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
>> +
>> +??? if (drvdata)
>> +??????? replicator_remove(&pdev->dev);
>> +
>> ????? pm_runtime_disable(&pdev->dev);
>> +??? if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
>> +??????? clk_put(drvdata->pclk);
>> ? }
>> ? #ifdef CONFIG_PM
>> @@ -334,6 +343,8 @@ static int replicator_runtime_suspend(struct 
>> device *dev)
>> ????? if (drvdata && !IS_ERR(drvdata->atclk))
>> ????????? clk_disable_unprepare(drvdata->atclk);
>> +??? if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
>> +??????? clk_disable_unprepare(drvdata->pclk);
>> ????? return 0;
>> ? }
>> @@ -344,6 +355,8 @@ static int replicator_runtime_resume(struct device 
>> *dev)
>> ????? if (drvdata && !IS_ERR(drvdata->atclk))
>> ????????? clk_prepare_enable(drvdata->atclk);
>> +??? if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
>> +??????? clk_prepare_enable(drvdata->pclk);
>> ????? return 0;
>> ? }
>> ? #endif
>> @@ -353,31 +366,32 @@ static const struct dev_pm_ops 
>> replicator_dev_pm_ops = {
>> ???????????????? replicator_runtime_resume, NULL)
>> ? };
>> -static const struct of_device_id static_replicator_match[] = {
>> +static const struct of_device_id replicator_match[] = {
>> ????? {.compatible = "arm,coresight-replicator"},
>> ????? {.compatible = "arm,coresight-static-replicator"},
>> ????? {}
>> ? };
>> -MODULE_DEVICE_TABLE(of, static_replicator_match);
>> +MODULE_DEVICE_TABLE(of, replicator_match);
>> ? #ifdef CONFIG_ACPI
>> -static const struct acpi_device_id static_replicator_acpi_ids[] = {
>> +static const struct acpi_device_id replicator_acpi_ids[] = {
>> ????? {"ARMHC985", 0}, /* ARM CoreSight Static Replicator */
>> +??? {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
>> ????? {}
>> ? };
>> -MODULE_DEVICE_TABLE(acpi, static_replicator_acpi_ids);
>> +MODULE_DEVICE_TABLE(acpi, replicator_acpi_ids);
>> ? #endif
>> -static struct platform_driver static_replicator_driver = {
>> -??? .probe????????? = static_replicator_probe,
>> -??? .remove_new???? = static_replicator_remove,
>> +static struct platform_driver replicator_driver = {
>> +??? .probe????????? = replicator_platform_probe,
>> +??? .remove_new???? = replicator_platform_remove,
>> ????? .driver???????? = {
>> -??????? .name?? = "coresight-static-replicator",
>> +??????? .name?? = "coresight-replicator",
>> ????????? /* THIS_MODULE is taken care of by 
>> platform_driver_register() */
>> -??????? .of_match_table = of_match_ptr(static_replicator_match),
>> -??????? .acpi_match_table = ACPI_PTR(static_replicator_acpi_ids),
>> +??????? .of_match_table = of_match_ptr(replicator_match),
>> +??????? .acpi_match_table = ACPI_PTR(replicator_acpi_ids),
>> ????????? .pm??? = &replicator_dev_pm_ops,
>> ????????? .suppress_bind_attrs = true,
>> ????? },
>> @@ -386,7 +400,13 @@ static struct platform_driver 
>> static_replicator_driver = {
>> ? static int dynamic_replicator_probe(struct amba_device *adev,
>> ????????????????????? const struct amba_id *id)
>> ? {
>> -??? return replicator_probe(&adev->dev, &adev->res);
>> +??? int ret;
>> +
>> +??? ret = replicator_probe(&adev->dev, &adev->res);
>> +??? if (!ret)
>> +??????? pm_runtime_put(&adev->dev);
>> +
>> +??? return ret;
>> ? }
>> ? static void dynamic_replicator_remove(struct amba_device *adev)
>> @@ -416,27 +436,12 @@ static struct amba_driver 
>> dynamic_replicator_driver = {
>> ? static int __init replicator_init(void)
>> ? {
>> -??? int ret;
>> -
>> -??? ret = platform_driver_register(&static_replicator_driver);
>> -??? if (ret) {
>> -??????? pr_info("Error registering platform driver\n");
>> -??????? return ret;
>> -??? }
>> -
>> -??? ret = amba_driver_register(&dynamic_replicator_driver);
>> -??? if (ret) {
>> -??????? pr_info("Error registering amba driver\n");
>> -??????? platform_driver_unregister(&static_replicator_driver);
>> -??? }
>> -
>> -??? return ret;
>> +??? return coresight_init_driver("replicator", 
>> &dynamic_replicator_driver, &replicator_driver);
>> ? }
>> ? static void __exit replicator_exit(void)
>> ? {
>> -??? platform_driver_unregister(&static_replicator_driver);
>> -??? amba_driver_unregister(&dynamic_replicator_driver);
>> +??? coresight_remove_driver(&dynamic_replicator_driver, 
>> &replicator_driver);
>> ? }
>> ? module_init(replicator_init);
> 



From vidyas at nvidia.com  Thu Feb 15 03:25:47 2024
From: vidyas at nvidia.com (Vidya Sagar)
Date: Thu, 15 Feb 2024 16:55:47 +0530
Subject: [PATCH V16 13/13] PCI: tegra: Add Tegra194 PCIe support
In-Reply-To: <20240214191249.GA1263222@bhelgaas>
References: <20240214191249.GA1263222@bhelgaas>
Message-ID: <17dadf66-055c-4796-a905-44e37b6fcfe3@nvidia.com>


On 15-02-2024 00:42, Bjorn Helgaas wrote:
> External email: Use caution opening links or attachments
>
>
> Hi Vidya, question about ancient history:
>
> On Tue, Aug 13, 2019 at 05:06:27PM +0530, Vidya Sagar wrote:
>> Add support for Synopsys DesignWare core IP based PCIe host controller
>> present in Tegra194 SoC.
>> ...
>> +static int tegra_pcie_dw_host_init(struct pcie_port *pp)
>> +{
>> +     struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>> +     struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
>> +     u32 val, tmp, offset, speed;
>> +
>> +     tegra_pcie_prepare_host(pp);
>> +
>> +     if (dw_pcie_wait_for_link(pci)) {
>> +             /*
>> +              * There are some endpoints which can't get the link up if
>> +              * root port has Data Link Feature (DLF) enabled.
>> +              * Refer Spec rev 4.0 ver 1.0 sec 3.4.2 & 7.7.4 for more info
>> +              * on Scaled Flow Control and DLF.
>> +              * So, need to confirm that is indeed the case here and attempt
>> +              * link up once again with DLF disabled.
> This comment suggests that there's an issue with *Endpoints*, not an
> issue with the Root Port.  If so, it seems like this problem could
> occur with all Root Ports, not just Tegra194.  Do you remember any
> details about this?
>
> I don't remember hearing about any similar issues, and this driver is
> the only place PCI_EXT_CAP_ID_DLF is referenced, so maybe it is
> actually something related to Tegra194?
We noticed PCIe link-up issues with some endpoints. link-up at the physical
layer level but NOT at the Data link layer level precisely. We further
figured out that it is the DLFE DLLPs that the root port sends during the
link up process which are causing the endpoints get confused and preventing
them from sending the InitFC DLLPs leading to the link not being up at
Data Link Layer level.

PCIe spec rev4.0, Rev 4.0, ver 1.0, Section-3.3 says that (verbatim) 
"The Data
Link Feature Exchange Enable field permits systems to disable the Data Link
Feature Exchange. This can be used to work around legacy hardware that does
not correctly ignore the DLLP".

Based on this, we added the following code to retry link-up with DLFE 
disabled,
only upon confirming that the link came up at phy level but not at the 
DL level
in the previous attempt.

Thanks,

Vidya Sagar

>
>> +             val = appl_readl(pcie, APPL_DEBUG);
>> +             val &= APPL_DEBUG_LTSSM_STATE_MASK;
>> +             val >>= APPL_DEBUG_LTSSM_STATE_SHIFT;
>> +             tmp = appl_readl(pcie, APPL_LINK_STATUS);
>> +             tmp &= APPL_LINK_STATUS_RDLH_LINK_UP;
>> +             if (!(val == 0x11 && !tmp)) {
>> +                     /* Link is down for all good reasons */
>> +                     return 0;
>> +             }
>> +
>> +             dev_info(pci->dev, "Link is down in DLL");
>> +             dev_info(pci->dev, "Trying again with DLFE disabled\n");
>> +             /* Disable LTSSM */
>> +             val = appl_readl(pcie, APPL_CTRL);
>> +             val &= ~APPL_CTRL_LTSSM_EN;
>> +             appl_writel(pcie, val, APPL_CTRL);
>> +
>> +             reset_control_assert(pcie->core_rst);
>> +             reset_control_deassert(pcie->core_rst);
>> +
>> +             offset = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_DLF);
>> +             val = dw_pcie_readl_dbi(pci, offset + PCI_DLF_CAP);
>> +             val &= ~PCI_DLF_EXCHANGE_ENABLE;
>> +             dw_pcie_writel_dbi(pci, offset, val);
>> +
>> +             tegra_pcie_prepare_host(pp);
>> +
>> +             if (dw_pcie_wait_for_link(pci))
>> +                     return 0;
>> +     }
>> +
>> +     speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) &
>> +             PCI_EXP_LNKSTA_CLS;
>> +     clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]);
>> +
>> +     tegra_pcie_enable_interrupts(pp);
>> +
>> +     return 0;
>> +}


From mark.rutland at arm.com  Thu Feb 15 03:27:07 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:27:07 +0000
Subject: [PATCH v6 12/18] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <20240215103205.2607016-13-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-13-ryan.roberts@arm.com>
Message-ID: <Zc31C2Kt263s5PI1@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:31:59AM +0000, Ryan Roberts wrote:
> With the ptep API sufficiently refactored, we can now introduce a new
> "contpte" API layer, which transparently manages the PTE_CONT bit for
> user mappings.
> 
> In this initial implementation, only suitable batches of PTEs, set via
> set_ptes(), are mapped with the PTE_CONT bit. Any subsequent
> modification of individual PTEs will cause an "unfold" operation to
> repaint the contpte block as individual PTEs before performing the
> requested operation. While, a modification of a single PTE could cause
> the block of PTEs to which it belongs to become eligible for "folding"
> into a contpte entry, "folding" is not performed in this initial
> implementation due to the costs of checking the requirements are met.
> Due to this, contpte mappings will degrade back to normal pte mappings
> over time if/when protections are changed. This will be solved in a
> future patch.
> 
> Since a contpte block only has a single access and dirty bit, the
> semantic here changes slightly; when getting a pte (e.g. ptep_get())
> that is part of a contpte mapping, the access and dirty information are
> pulled from the block (so all ptes in the block return the same
> access/dirty info). When changing the access/dirty info on a pte (e.g.
> ptep_set_access_flags()) that is part of a contpte mapping, this change
> will affect the whole contpte block. This is works fine in practice
> since we guarantee that only a single folio is mapped by a contpte
> block, and the core-mm tracks access/dirty information per folio.
> 
> In order for the public functions, which used to be pure inline, to
> continue to be callable by modules, export all the contpte_* symbols
> that are now called by those public inline functions.
> 
> The feature is enabled/disabled with the ARM64_CONTPTE Kconfig parameter
> at build time. It defaults to enabled as long as its dependency,
> TRANSPARENT_HUGEPAGE is also enabled. The core-mm depends upon
> TRANSPARENT_HUGEPAGE to be able to allocate large folios, so if its not
> enabled, then there is no chance of meeting the physical contiguity
> requirement for contpte mappings.
> 
> Acked-by: Ard Biesheuvel <ardb at kernel.org>
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/Kconfig               |   9 +
>  arch/arm64/include/asm/pgtable.h | 167 ++++++++++++++++++
>  arch/arm64/mm/Makefile           |   1 +
>  arch/arm64/mm/contpte.c          | 285 +++++++++++++++++++++++++++++++
>  include/linux/efi.h              |   5 +
>  5 files changed, 467 insertions(+)
>  create mode 100644 arch/arm64/mm/contpte.c
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index e8275a40afbd..5a7ac1f37bdc 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -2229,6 +2229,15 @@ config UNWIND_PATCH_PAC_INTO_SCS
>  	select UNWIND_TABLES
>  	select DYNAMIC_SCS
>  
> +config ARM64_CONTPTE
> +	bool "Contiguous PTE mappings for user memory" if EXPERT
> +	depends on TRANSPARENT_HUGEPAGE
> +	default y
> +	help
> +	  When enabled, user mappings are configured using the PTE contiguous
> +	  bit, for any mappings that meet the size and alignment requirements.
> +	  This reduces TLB pressure and improves performance.
> +
>  endmenu # "Kernel Features"
>  
>  menu "Boot options"
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 7336d40a893a..831099cfc96b 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -133,6 +133,10 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>   */
>  #define pte_valid_not_user(pte) \
>  	((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN))
> +/*
> + * Returns true if the pte is valid and has the contiguous bit set.
> + */
> +#define pte_valid_cont(pte)	(pte_valid(pte) && pte_cont(pte))
>  /*
>   * Could the pte be present in the TLB? We must check mm_tlb_flush_pending
>   * so that we don't erroneously return false for pages that have been
> @@ -1128,6 +1132,167 @@ extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
>  				    unsigned long addr, pte_t *ptep,
>  				    pte_t old_pte, pte_t new_pte);
>  
> +#ifdef CONFIG_ARM64_CONTPTE
> +
> +/*
> + * The contpte APIs are used to transparently manage the contiguous bit in ptes
> + * where it is possible and makes sense to do so. The PTE_CONT bit is considered
> + * a private implementation detail of the public ptep API (see below).
> + */
> +extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, pte_t pte);
> +extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
> +extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
> +extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, pte_t pte, unsigned int nr);
> +extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep);
> +extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep);
> +extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep,
> +				pte_t entry, int dirty);
> +
> +static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
> +					pte_t *ptep, pte_t pte)
> +{
> +	if (unlikely(pte_valid_cont(pte)))
> +		__contpte_try_unfold(mm, addr, ptep, pte);
> +}
> +
> +/*
> + * The below functions constitute the public API that arm64 presents to the
> + * core-mm to manipulate PTE entries within their page tables (or at least this
> + * is the subset of the API that arm64 needs to implement). These public
> + * versions will automatically and transparently apply the contiguous bit where
> + * it makes sense to do so. Therefore any users that are contig-aware (e.g.
> + * hugetlb, kernel mapper) should NOT use these APIs, but instead use the
> + * private versions, which are prefixed with double underscore. All of these
> + * APIs except for ptep_get_lockless() are expected to be called with the PTL
> + * held. Although the contiguous bit is considered private to the
> + * implementation, it is deliberately allowed to leak through the getters (e.g.
> + * ptep_get()), back to core code. This is required so that pte_leaf_size() can
> + * provide an accurate size for perf_get_pgtable_size(). But this leakage means
> + * its possible a pte will be passed to a setter with the contiguous bit set, so
> + * we explicitly clear the contiguous bit in those cases to prevent accidentally
> + * setting it in the pgtable.
> + */
> +
> +#define ptep_get ptep_get
> +static inline pte_t ptep_get(pte_t *ptep)
> +{
> +	pte_t pte = __ptep_get(ptep);
> +
> +	if (likely(!pte_valid_cont(pte)))
> +		return pte;
> +
> +	return contpte_ptep_get(ptep, pte);
> +}
> +
> +#define ptep_get_lockless ptep_get_lockless
> +static inline pte_t ptep_get_lockless(pte_t *ptep)
> +{
> +	pte_t pte = __ptep_get(ptep);
> +
> +	if (likely(!pte_valid_cont(pte)))
> +		return pte;
> +
> +	return contpte_ptep_get_lockless(ptep);
> +}
> +
> +static inline void set_pte(pte_t *ptep, pte_t pte)
> +{
> +	/*
> +	 * We don't have the mm or vaddr so cannot unfold contig entries (since
> +	 * it requires tlb maintenance). set_pte() is not used in core code, so
> +	 * this should never even be called. Regardless do our best to service
> +	 * any call and emit a warning if there is any attempt to set a pte on
> +	 * top of an existing contig range.
> +	 */
> +	pte_t orig_pte = __ptep_get(ptep);
> +
> +	WARN_ON_ONCE(pte_valid_cont(orig_pte));
> +	__set_pte(ptep, pte_mknoncont(pte));
> +}
> +
> +#define set_ptes set_ptes
> +static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, pte_t pte, unsigned int nr)
> +{
> +	pte = pte_mknoncont(pte);
> +
> +	if (likely(nr == 1)) {
> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +		__set_ptes(mm, addr, ptep, pte, 1);
> +	} else {
> +		contpte_set_ptes(mm, addr, ptep, pte, nr);
> +	}
> +}
> +
> +static inline void pte_clear(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep)
> +{
> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +	__pte_clear(mm, addr, ptep);
> +}
> +
> +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
> +static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep)
> +{
> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +	return __ptep_get_and_clear(mm, addr, ptep);
> +}
> +
> +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
> +static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep)
> +{
> +	pte_t orig_pte = __ptep_get(ptep);
> +
> +	if (likely(!pte_valid_cont(orig_pte)))
> +		return __ptep_test_and_clear_young(vma, addr, ptep);
> +
> +	return contpte_ptep_test_and_clear_young(vma, addr, ptep);
> +}
> +
> +#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
> +static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep)
> +{
> +	pte_t orig_pte = __ptep_get(ptep);
> +
> +	if (likely(!pte_valid_cont(orig_pte)))
> +		return __ptep_clear_flush_young(vma, addr, ptep);
> +
> +	return contpte_ptep_clear_flush_young(vma, addr, ptep);
> +}
> +
> +#define __HAVE_ARCH_PTEP_SET_WRPROTECT
> +static inline void ptep_set_wrprotect(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep)
> +{
> +	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +	__ptep_set_wrprotect(mm, addr, ptep);
> +}
> +
> +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
> +static inline int ptep_set_access_flags(struct vm_area_struct *vma,
> +				unsigned long addr, pte_t *ptep,
> +				pte_t entry, int dirty)
> +{
> +	pte_t orig_pte = __ptep_get(ptep);
> +
> +	entry = pte_mknoncont(entry);
> +
> +	if (likely(!pte_valid_cont(orig_pte)))
> +		return __ptep_set_access_flags(vma, addr, ptep, entry, dirty);
> +
> +	return contpte_ptep_set_access_flags(vma, addr, ptep, entry, dirty);
> +}
> +
> +#else /* CONFIG_ARM64_CONTPTE */
> +
>  #define ptep_get				__ptep_get
>  #define set_pte					__set_pte
>  #define set_ptes				__set_ptes
> @@ -1143,6 +1308,8 @@ extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
>  #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
>  #define ptep_set_access_flags			__ptep_set_access_flags
>  
> +#endif /* CONFIG_ARM64_CONTPTE */
> +
>  #endif /* !__ASSEMBLY__ */
>  
>  #endif /* __ASM_PGTABLE_H */
> diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
> index dbd1bc95967d..60454256945b 100644
> --- a/arch/arm64/mm/Makefile
> +++ b/arch/arm64/mm/Makefile
> @@ -3,6 +3,7 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
>  				   cache.o copypage.o flush.o \
>  				   ioremap.o mmap.o pgd.o mmu.o \
>  				   context.o proc.o pageattr.o fixmap.o
> +obj-$(CONFIG_ARM64_CONTPTE)	+= contpte.o
>  obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
>  obj-$(CONFIG_PTDUMP_CORE)	+= ptdump.o
>  obj-$(CONFIG_PTDUMP_DEBUGFS)	+= ptdump_debugfs.o
> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
> new file mode 100644
> index 000000000000..6d7f40667fa2
> --- /dev/null
> +++ b/arch/arm64/mm/contpte.c
> @@ -0,0 +1,285 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2023 ARM Ltd.
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/efi.h>
> +#include <linux/export.h>
> +#include <asm/tlbflush.h>
> +
> +static inline bool mm_is_user(struct mm_struct *mm)
> +{
> +	/*
> +	 * Don't attempt to apply the contig bit to kernel mappings, because
> +	 * dynamically adding/removing the contig bit can cause page faults.
> +	 * These racing faults are ok for user space, since they get serialized
> +	 * on the PTL. But kernel mappings can't tolerate faults.
> +	 */
> +	if (unlikely(mm_is_efi(mm)))
> +		return false;
> +	return mm != &init_mm;
> +}
> +
> +static inline pte_t *contpte_align_down(pte_t *ptep)
> +{
> +	return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
> +}
> +
> +static void contpte_convert(struct mm_struct *mm, unsigned long addr,
> +			    pte_t *ptep, pte_t pte)
> +{
> +	struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0);
> +	unsigned long start_addr;
> +	pte_t *start_ptep;
> +	int i;
> +
> +	start_ptep = ptep = contpte_align_down(ptep);
> +	start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> +	pte = pfn_pte(ALIGN_DOWN(pte_pfn(pte), CONT_PTES), pte_pgprot(pte));
> +
> +	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) {
> +		pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
> +
> +		if (pte_dirty(ptent))
> +			pte = pte_mkdirty(pte);
> +
> +		if (pte_young(ptent))
> +			pte = pte_mkyoung(pte);
> +	}
> +
> +	__flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
> +
> +	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
> +}
> +
> +void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
> +			pte_t *ptep, pte_t pte)
> +{
> +	/*
> +	 * We have already checked that the ptes are contiguous in
> +	 * contpte_try_unfold(), so just check that the mm is user space.
> +	 */
> +	if (!mm_is_user(mm))
> +		return;
> +
> +	pte = pte_mknoncont(pte);
> +	contpte_convert(mm, addr, ptep, pte);
> +}
> +EXPORT_SYMBOL(__contpte_try_unfold);
> +
> +pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
> +{
> +	/*
> +	 * Gather access/dirty bits, which may be populated in any of the ptes
> +	 * of the contig range. We are guaranteed to be holding the PTL, so any
> +	 * contiguous range cannot be unfolded or otherwise modified under our
> +	 * feet.
> +	 */
> +
> +	pte_t pte;
> +	int i;
> +
> +	ptep = contpte_align_down(ptep);
> +
> +	for (i = 0; i < CONT_PTES; i++, ptep++) {
> +		pte = __ptep_get(ptep);
> +
> +		if (pte_dirty(pte))
> +			orig_pte = pte_mkdirty(orig_pte);
> +
> +		if (pte_young(pte))
> +			orig_pte = pte_mkyoung(orig_pte);
> +	}
> +
> +	return orig_pte;
> +}
> +EXPORT_SYMBOL(contpte_ptep_get);
> +
> +pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
> +{
> +	/*
> +	 * Gather access/dirty bits, which may be populated in any of the ptes
> +	 * of the contig range. We may not be holding the PTL, so any contiguous
> +	 * range may be unfolded/modified/refolded under our feet. Therefore we
> +	 * ensure we read a _consistent_ contpte range by checking that all ptes
> +	 * in the range are valid and have CONT_PTE set, that all pfns are
> +	 * contiguous and that all pgprots are the same (ignoring access/dirty).
> +	 * If we find a pte that is not consistent, then we must be racing with
> +	 * an update so start again. If the target pte does not have CONT_PTE
> +	 * set then that is considered consistent on its own because it is not
> +	 * part of a contpte range.
> +	 */
> +
> +	pgprot_t orig_prot;
> +	unsigned long pfn;
> +	pte_t orig_pte;
> +	pgprot_t prot;
> +	pte_t *ptep;
> +	pte_t pte;
> +	int i;
> +
> +retry:
> +	orig_pte = __ptep_get(orig_ptep);
> +
> +	if (!pte_valid_cont(orig_pte))
> +		return orig_pte;
> +
> +	orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
> +	ptep = contpte_align_down(orig_ptep);
> +	pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
> +
> +	for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
> +		pte = __ptep_get(ptep);
> +		prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
> +
> +		if (!pte_valid_cont(pte) ||
> +		   pte_pfn(pte) != pfn ||
> +		   pgprot_val(prot) != pgprot_val(orig_prot))
> +			goto retry;
> +
> +		if (pte_dirty(pte))
> +			orig_pte = pte_mkdirty(orig_pte);
> +
> +		if (pte_young(pte))
> +			orig_pte = pte_mkyoung(orig_pte);
> +	}
> +
> +	return orig_pte;
> +}
> +EXPORT_SYMBOL(contpte_ptep_get_lockless);
> +
> +void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
> +					pte_t *ptep, pte_t pte, unsigned int nr)
> +{
> +	unsigned long next;
> +	unsigned long end;
> +	unsigned long pfn;
> +	pgprot_t prot;
> +
> +	/*
> +	 * The set_ptes() spec guarantees that when nr > 1, the initial state of
> +	 * all ptes is not-present. Therefore we never need to unfold or
> +	 * otherwise invalidate a range before we set the new ptes.
> +	 * contpte_set_ptes() should never be called for nr < 2.
> +	 */
> +	VM_WARN_ON(nr == 1);
> +
> +	if (!mm_is_user(mm))
> +		return __set_ptes(mm, addr, ptep, pte, nr);
> +
> +	end = addr + (nr << PAGE_SHIFT);
> +	pfn = pte_pfn(pte);
> +	prot = pte_pgprot(pte);
> +
> +	do {
> +		next = pte_cont_addr_end(addr, end);
> +		nr = (next - addr) >> PAGE_SHIFT;
> +		pte = pfn_pte(pfn, prot);
> +
> +		if (((addr | next | (pfn << PAGE_SHIFT)) & ~CONT_PTE_MASK) == 0)
> +			pte = pte_mkcont(pte);
> +		else
> +			pte = pte_mknoncont(pte);
> +
> +		__set_ptes(mm, addr, ptep, pte, nr);
> +
> +		addr = next;
> +		ptep += nr;
> +		pfn += nr;
> +
> +	} while (addr != end);
> +}
> +EXPORT_SYMBOL(contpte_set_ptes);
> +
> +int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
> +					unsigned long addr, pte_t *ptep)
> +{
> +	/*
> +	 * ptep_clear_flush_young() technically requires us to clear the access
> +	 * flag for a _single_ pte. However, the core-mm code actually tracks
> +	 * access/dirty per folio, not per page. And since we only create a
> +	 * contig range when the range is covered by a single folio, we can get
> +	 * away with clearing young for the whole contig range here, so we avoid
> +	 * having to unfold.
> +	 */
> +
> +	int young = 0;
> +	int i;
> +
> +	ptep = contpte_align_down(ptep);
> +	addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> +
> +	for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
> +		young |= __ptep_test_and_clear_young(vma, addr, ptep);
> +
> +	return young;
> +}
> +EXPORT_SYMBOL(contpte_ptep_test_and_clear_young);
> +
> +int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
> +					unsigned long addr, pte_t *ptep)
> +{
> +	int young;
> +
> +	young = contpte_ptep_test_and_clear_young(vma, addr, ptep);
> +
> +	if (young) {
> +		/*
> +		 * See comment in __ptep_clear_flush_young(); same rationale for
> +		 * eliding the trailing DSB applies here.
> +		 */
> +		addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> +		__flush_tlb_range_nosync(vma, addr, addr + CONT_PTE_SIZE,
> +					 PAGE_SIZE, true, 3);
> +	}
> +
> +	return young;
> +}
> +EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
> +
> +int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
> +					unsigned long addr, pte_t *ptep,
> +					pte_t entry, int dirty)
> +{
> +	unsigned long start_addr;
> +	pte_t orig_pte;
> +	int i;
> +
> +	/*
> +	 * Gather the access/dirty bits for the contiguous range. If nothing has
> +	 * changed, its a noop.
> +	 */
> +	orig_pte = pte_mknoncont(ptep_get(ptep));
> +	if (pte_val(orig_pte) == pte_val(entry))
> +		return 0;
> +
> +	/*
> +	 * We can fix up access/dirty bits without having to unfold the contig
> +	 * range. But if the write bit is changing, we must unfold.
> +	 */
> +	if (pte_write(orig_pte) == pte_write(entry)) {
> +		/*
> +		 * For HW access management, we technically only need to update
> +		 * the flag on a single pte in the range. But for SW access
> +		 * management, we need to update all the ptes to prevent extra
> +		 * faults. Avoid per-page tlb flush in __ptep_set_access_flags()
> +		 * and instead flush the whole range at the end.
> +		 */
> +		ptep = contpte_align_down(ptep);
> +		start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> +
> +		for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
> +			__ptep_set_access_flags(vma, addr, ptep, entry, 0);
> +
> +		if (dirty)
> +			__flush_tlb_range(vma, start_addr, addr,
> +							PAGE_SIZE, true, 3);
> +	} else {
> +		__contpte_try_unfold(vma->vm_mm, addr, ptep, orig_pte);
> +		__ptep_set_access_flags(vma, addr, ptep, entry, dirty);
> +	}
> +
> +	return 1;
> +}
> +EXPORT_SYMBOL(contpte_ptep_set_access_flags);
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index c74f47711f0b..57da15e7429c 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -692,6 +692,11 @@ extern struct efi {
>  
>  extern struct mm_struct efi_mm;
>  
> +static inline bool mm_is_efi(struct mm_struct *mm)
> +{
> +	return IS_ENABLED(CONFIG_EFI) && mm == &efi_mm;
> +}
> +
>  static inline int
>  efi_guidcmp (efi_guid_t left, efi_guid_t right)
>  {
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Thu Feb 15 03:28:20 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:28:20 +0000
Subject: [PATCH v6 13/18] arm64/mm: Implement new wrprotect_ptes() batch
 API
In-Reply-To: <20240215103205.2607016-14-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-14-ryan.roberts@arm.com>
Message-ID: <Zc31VN2j7DJYmgoJ@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:32:00AM +0000, Ryan Roberts wrote:
> Optimize the contpte implementation to fix some of the fork performance
> regression introduced by the initial contpte commit. Subsequent patches
> will solve it entirely.
> 
> During fork(), any private memory in the parent must be write-protected.
> Previously this was done 1 PTE at a time. But the core-mm supports
> batched wrprotect via the new wrprotect_ptes() API. So let's implement
> that API and for fully covered contpte mappings, we no longer need to
> unfold the contpte. This has 2 benefits:
> 
>   - reduced unfolding, reduces the number of tlbis that must be issued.
>   - The memory remains contpte-mapped ("folded") in the parent, so it
>     continues to benefit from the more efficient use of the TLB after
>     the fork.
> 
> The optimization to wrprotect a whole contpte block without unfolding is
> possible thanks to the tightening of the Arm ARM in respect to the
> definition and behaviour when 'Misprogramming the Contiguous bit'. See
> section D21194 at https://developer.arm.com/documentation/102105/ja-07/
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/pgtable.h | 61 ++++++++++++++++++++++++++------
>  arch/arm64/mm/contpte.c          | 38 ++++++++++++++++++++
>  2 files changed, 89 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 831099cfc96b..8643227c318b 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -978,16 +978,12 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
>  }
>  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
>  
> -/*
> - * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
> - * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
> - */
> -static inline void __ptep_set_wrprotect(struct mm_struct *mm,
> -					unsigned long address, pte_t *ptep)
> +static inline void ___ptep_set_wrprotect(struct mm_struct *mm,
> +					unsigned long address, pte_t *ptep,
> +					pte_t pte)
>  {
> -	pte_t old_pte, pte;
> +	pte_t old_pte;
>  
> -	pte = __ptep_get(ptep);
>  	do {
>  		old_pte = pte;
>  		pte = pte_wrprotect(pte);
> @@ -996,6 +992,25 @@ static inline void __ptep_set_wrprotect(struct mm_struct *mm,
>  	} while (pte_val(pte) != pte_val(old_pte));
>  }
>  
> +/*
> + * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
> + * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
> + */
> +static inline void __ptep_set_wrprotect(struct mm_struct *mm,
> +					unsigned long address, pte_t *ptep)
> +{
> +	___ptep_set_wrprotect(mm, address, ptep, __ptep_get(ptep));
> +}
> +
> +static inline void __wrprotect_ptes(struct mm_struct *mm, unsigned long address,
> +				pte_t *ptep, unsigned int nr)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < nr; i++, address += PAGE_SIZE, ptep++)
> +		__ptep_set_wrprotect(mm, address, ptep);
> +}
> +
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  #define __HAVE_ARCH_PMDP_SET_WRPROTECT
>  static inline void pmdp_set_wrprotect(struct mm_struct *mm,
> @@ -1149,6 +1164,8 @@ extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep);
>  extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep);
> +extern void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr);
>  extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep,
>  				pte_t entry, int dirty);
> @@ -1268,12 +1285,35 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
>  	return contpte_ptep_clear_flush_young(vma, addr, ptep);
>  }
>  
> +#define wrprotect_ptes wrprotect_ptes
> +static inline void wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr)
> +{
> +	if (likely(nr == 1)) {
> +		/*
> +		 * Optimization: wrprotect_ptes() can only be called for present
> +		 * ptes so we only need to check contig bit as condition for
> +		 * unfold, and we can remove the contig bit from the pte we read
> +		 * to avoid re-reading. This speeds up fork() which is sensitive
> +		 * for order-0 folios. Equivalent to contpte_try_unfold().
> +		 */
> +		pte_t orig_pte = __ptep_get(ptep);
> +
> +		if (unlikely(pte_cont(orig_pte))) {
> +			__contpte_try_unfold(mm, addr, ptep, orig_pte);
> +			orig_pte = pte_mknoncont(orig_pte);
> +		}
> +		___ptep_set_wrprotect(mm, addr, ptep, orig_pte);
> +	} else {
> +		contpte_wrprotect_ptes(mm, addr, ptep, nr);
> +	}
> +}
> +
>  #define __HAVE_ARCH_PTEP_SET_WRPROTECT
>  static inline void ptep_set_wrprotect(struct mm_struct *mm,
>  				unsigned long addr, pte_t *ptep)
>  {
> -	contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> -	__ptep_set_wrprotect(mm, addr, ptep);
> +	wrprotect_ptes(mm, addr, ptep, 1);
>  }
>  
>  #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
> @@ -1305,6 +1345,7 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
>  #define ptep_clear_flush_young			__ptep_clear_flush_young
>  #define __HAVE_ARCH_PTEP_SET_WRPROTECT
>  #define ptep_set_wrprotect			__ptep_set_wrprotect
> +#define wrprotect_ptes				__wrprotect_ptes
>  #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
>  #define ptep_set_access_flags			__ptep_set_access_flags
>  
> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
> index 6d7f40667fa2..bedb58524535 100644
> --- a/arch/arm64/mm/contpte.c
> +++ b/arch/arm64/mm/contpte.c
> @@ -26,6 +26,26 @@ static inline pte_t *contpte_align_down(pte_t *ptep)
>  	return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
>  }
>  
> +static void contpte_try_unfold_partial(struct mm_struct *mm, unsigned long addr,
> +					pte_t *ptep, unsigned int nr)
> +{
> +	/*
> +	 * Unfold any partially covered contpte block at the beginning and end
> +	 * of the range.
> +	 */
> +
> +	if (ptep != contpte_align_down(ptep) || nr < CONT_PTES)
> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +
> +	if (ptep + nr != contpte_align_down(ptep + nr)) {
> +		unsigned long last_addr = addr + PAGE_SIZE * (nr - 1);
> +		pte_t *last_ptep = ptep + nr - 1;
> +
> +		contpte_try_unfold(mm, last_addr, last_ptep,
> +				   __ptep_get(last_ptep));
> +	}
> +}
> +
>  static void contpte_convert(struct mm_struct *mm, unsigned long addr,
>  			    pte_t *ptep, pte_t pte)
>  {
> @@ -238,6 +258,24 @@ int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
>  }
>  EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
>  
> +void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
> +					pte_t *ptep, unsigned int nr)
> +{
> +	/*
> +	 * If wrprotecting an entire contig range, we can avoid unfolding. Just
> +	 * set wrprotect and wait for the later mmu_gather flush to invalidate
> +	 * the tlb. Until the flush, the page may or may not be wrprotected.
> +	 * After the flush, it is guaranteed wrprotected. If it's a partial
> +	 * range though, we must unfold, because we can't have a case where
> +	 * CONT_PTE is set but wrprotect applies to a subset of the PTEs; this
> +	 * would cause it to continue to be unpredictable after the flush.
> +	 */
> +
> +	contpte_try_unfold_partial(mm, addr, ptep, nr);
> +	__wrprotect_ptes(mm, addr, ptep, nr);
> +}
> +EXPORT_SYMBOL(contpte_wrprotect_ptes);
> +
>  int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>  					unsigned long addr, pte_t *ptep,
>  					pte_t entry, int dirty)
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Thu Feb 15 03:28:58 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:28:58 +0000
Subject: [PATCH v6 14/18] arm64/mm: Implement new
 [get_and_]clear_full_ptes() batch APIs
In-Reply-To: <20240215103205.2607016-15-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-15-ryan.roberts@arm.com>
Message-ID: <Zc31esUwBD2jgYiX@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:32:01AM +0000, Ryan Roberts wrote:
> Optimize the contpte implementation to fix some of the
> exit/munmap/dontneed performance regression introduced by the initial
> contpte commit. Subsequent patches will solve it entirely.
> 
> During exit(), munmap() or madvise(MADV_DONTNEED), mappings must be
> cleared. Previously this was done 1 PTE at a time. But the core-mm
> supports batched clear via the new [get_and_]clear_full_ptes() APIs. So
> let's implement those APIs and for fully covered contpte mappings, we no
> longer need to unfold the contpte. This significantly reduces unfolding
> operations, reducing the number of tlbis that must be issued.
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/pgtable.h | 67 ++++++++++++++++++++++++++++++++
>  arch/arm64/mm/contpte.c          | 17 ++++++++
>  2 files changed, 84 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 8643227c318b..a8f1a35e3086 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -965,6 +965,37 @@ static inline pte_t __ptep_get_and_clear(struct mm_struct *mm,
>  	return pte;
>  }
>  
> +static inline void __clear_full_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr, int full)
> +{
> +	for (;;) {
> +		__ptep_get_and_clear(mm, addr, ptep);
> +		if (--nr == 0)
> +			break;
> +		ptep++;
> +		addr += PAGE_SIZE;
> +	}
> +}
> +
> +static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep,
> +				unsigned int nr, int full)
> +{
> +	pte_t pte, tmp_pte;
> +
> +	pte = __ptep_get_and_clear(mm, addr, ptep);
> +	while (--nr) {
> +		ptep++;
> +		addr += PAGE_SIZE;
> +		tmp_pte = __ptep_get_and_clear(mm, addr, ptep);
> +		if (pte_dirty(tmp_pte))
> +			pte = pte_mkdirty(pte);
> +		if (pte_young(tmp_pte))
> +			pte = pte_mkyoung(pte);
> +	}
> +	return pte;
> +}
> +
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  #define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
>  static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
> @@ -1160,6 +1191,11 @@ extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
>  extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
>  extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
>  				pte_t *ptep, pte_t pte, unsigned int nr);
> +extern void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr, int full);
> +extern pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep,
> +				unsigned int nr, int full);
>  extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep);
>  extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
> @@ -1253,6 +1289,35 @@ static inline void pte_clear(struct mm_struct *mm,
>  	__pte_clear(mm, addr, ptep);
>  }
>  
> +#define clear_full_ptes clear_full_ptes
> +static inline void clear_full_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr, int full)
> +{
> +	if (likely(nr == 1)) {
> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +		__clear_full_ptes(mm, addr, ptep, nr, full);
> +	} else {
> +		contpte_clear_full_ptes(mm, addr, ptep, nr, full);
> +	}
> +}
> +
> +#define get_and_clear_full_ptes get_and_clear_full_ptes
> +static inline pte_t get_and_clear_full_ptes(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep,
> +				unsigned int nr, int full)
> +{
> +	pte_t pte;
> +
> +	if (likely(nr == 1)) {
> +		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
> +		pte = __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
> +	} else {
> +		pte = contpte_get_and_clear_full_ptes(mm, addr, ptep, nr, full);
> +	}
> +
> +	return pte;
> +}
> +
>  #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
>  static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
>  				unsigned long addr, pte_t *ptep)
> @@ -1337,6 +1402,8 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
>  #define set_pte					__set_pte
>  #define set_ptes				__set_ptes
>  #define pte_clear				__pte_clear
> +#define clear_full_ptes				__clear_full_ptes
> +#define get_and_clear_full_ptes			__get_and_clear_full_ptes
>  #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
>  #define ptep_get_and_clear			__ptep_get_and_clear
>  #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
> index bedb58524535..50e0173dc5ee 100644
> --- a/arch/arm64/mm/contpte.c
> +++ b/arch/arm64/mm/contpte.c
> @@ -212,6 +212,23 @@ void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
>  }
>  EXPORT_SYMBOL(contpte_set_ptes);
>  
> +void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, unsigned int nr, int full)
> +{
> +	contpte_try_unfold_partial(mm, addr, ptep, nr);
> +	__clear_full_ptes(mm, addr, ptep, nr, full);
> +}
> +EXPORT_SYMBOL(contpte_clear_full_ptes);
> +
> +pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep,
> +				unsigned int nr, int full)
> +{
> +	contpte_try_unfold_partial(mm, addr, ptep, nr);
> +	return __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
> +}
> +EXPORT_SYMBOL(contpte_get_and_clear_full_ptes);
> +
>  int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
>  					unsigned long addr, pte_t *ptep)
>  {
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Thu Feb 15 03:30:56 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:30:56 +0000
Subject: [PATCH v6 18/18] arm64/mm: Automatically fold contpte mappings
In-Reply-To: <20240215103205.2607016-19-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-19-ryan.roberts@arm.com>
Message-ID: <Zc318I6LWPODE24n@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:32:05AM +0000, Ryan Roberts wrote:
> There are situations where a change to a single PTE could cause the
> contpte block in which it resides to become foldable (i.e. could be
> repainted with the contiguous bit). Such situations arise, for example,
> when user space temporarily changes protections, via mprotect, for
> individual pages, such can be the case for certain garbage collectors.
> 
> We would like to detect when such a PTE change occurs. However this can
> be expensive due to the amount of checking required. Therefore only
> perform the checks when an indiviual PTE is modified via mprotect
> (ptep_modify_prot_commit() -> set_pte_at() -> set_ptes(nr=1)) and only
> when we are setting the final PTE in a contpte-aligned block.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/pgtable.h | 26 +++++++++++++
>  arch/arm64/mm/contpte.c          | 64 ++++++++++++++++++++++++++++++++
>  2 files changed, 90 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 8310875133ff..401087e8a43d 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -1185,6 +1185,8 @@ extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
>   * where it is possible and makes sense to do so. The PTE_CONT bit is considered
>   * a private implementation detail of the public ptep API (see below).
>   */
> +extern void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
> +				pte_t *ptep, pte_t pte);
>  extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>  				pte_t *ptep, pte_t pte);
>  extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
> @@ -1206,6 +1208,29 @@ extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
>  				unsigned long addr, pte_t *ptep,
>  				pte_t entry, int dirty);
>  
> +static __always_inline void contpte_try_fold(struct mm_struct *mm,
> +				unsigned long addr, pte_t *ptep, pte_t pte)
> +{
> +	/*
> +	 * Only bother trying if both the virtual and physical addresses are
> +	 * aligned and correspond to the last entry in a contig range. The core
> +	 * code mostly modifies ranges from low to high, so this is the likely
> +	 * the last modification in the contig range, so a good time to fold.
> +	 * We can't fold special mappings, because there is no associated folio.
> +	 */
> +
> +	const unsigned long contmask = CONT_PTES - 1;
> +	bool valign = ((addr >> PAGE_SHIFT) & contmask) == contmask;
> +
> +	if (unlikely(valign)) {
> +		bool palign = (pte_pfn(pte) & contmask) == contmask;
> +
> +		if (unlikely(palign &&
> +		    pte_valid(pte) && !pte_cont(pte) && !pte_special(pte)))
> +			__contpte_try_fold(mm, addr, ptep, pte);
> +	}
> +}
> +
>  static __always_inline void contpte_try_unfold(struct mm_struct *mm,
>  				unsigned long addr, pte_t *ptep, pte_t pte)
>  {
> @@ -1286,6 +1311,7 @@ static __always_inline void set_ptes(struct mm_struct *mm, unsigned long addr,
>  	if (likely(nr == 1)) {
>  		contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
>  		__set_ptes(mm, addr, ptep, pte, 1);
> +		contpte_try_fold(mm, addr, ptep, pte);
>  	} else {
>  		contpte_set_ptes(mm, addr, ptep, pte, nr);
>  	}
> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
> index 50e0173dc5ee..16788f07716d 100644
> --- a/arch/arm64/mm/contpte.c
> +++ b/arch/arm64/mm/contpte.c
> @@ -73,6 +73,70 @@ static void contpte_convert(struct mm_struct *mm, unsigned long addr,
>  	__set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
>  }
>  
> +void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
> +			pte_t *ptep, pte_t pte)
> +{
> +	/*
> +	 * We have already checked that the virtual and pysical addresses are
> +	 * correctly aligned for a contpte mapping in contpte_try_fold() so the
> +	 * remaining checks are to ensure that the contpte range is fully
> +	 * covered by a single folio, and ensure that all the ptes are valid
> +	 * with contiguous PFNs and matching prots. We ignore the state of the
> +	 * access and dirty bits for the purpose of deciding if its a contiguous
> +	 * range; the folding process will generate a single contpte entry which
> +	 * has a single access and dirty bit. Those 2 bits are the logical OR of
> +	 * their respective bits in the constituent pte entries. In order to
> +	 * ensure the contpte range is covered by a single folio, we must
> +	 * recover the folio from the pfn, but special mappings don't have a
> +	 * folio backing them. Fortunately contpte_try_fold() already checked
> +	 * that the pte is not special - we never try to fold special mappings.
> +	 * Note we can't use vm_normal_page() for this since we don't have the
> +	 * vma.
> +	 */
> +
> +	unsigned long folio_start, folio_end;
> +	unsigned long cont_start, cont_end;
> +	pte_t expected_pte, subpte;
> +	struct folio *folio;
> +	struct page *page;
> +	unsigned long pfn;
> +	pte_t *orig_ptep;
> +	pgprot_t prot;
> +
> +	int i;
> +
> +	if (!mm_is_user(mm))
> +		return;
> +
> +	page = pte_page(pte);
> +	folio = page_folio(page);
> +	folio_start = addr - (page - &folio->page) * PAGE_SIZE;
> +	folio_end = folio_start + folio_nr_pages(folio) * PAGE_SIZE;
> +	cont_start = ALIGN_DOWN(addr, CONT_PTE_SIZE);
> +	cont_end = cont_start + CONT_PTE_SIZE;
> +
> +	if (folio_start > cont_start || folio_end < cont_end)
> +		return;
> +
> +	pfn = ALIGN_DOWN(pte_pfn(pte), CONT_PTES);
> +	prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
> +	expected_pte = pfn_pte(pfn, prot);
> +	orig_ptep = ptep;
> +	ptep = contpte_align_down(ptep);
> +
> +	for (i = 0; i < CONT_PTES; i++) {
> +		subpte = pte_mkold(pte_mkclean(__ptep_get(ptep)));
> +		if (!pte_same(subpte, expected_pte))
> +			return;
> +		expected_pte = pte_advance_pfn(expected_pte, 1);
> +		ptep++;
> +	}
> +
> +	pte = pte_mkcont(pte);
> +	contpte_convert(mm, addr, orig_ptep, pte);
> +}
> +EXPORT_SYMBOL(__contpte_try_fold);
> +
>  void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
>  			pte_t *ptep, pte_t pte)
>  {
> -- 
> 2.25.1
> 


From a-bhatia1 at ti.com  Thu Feb 15 03:33:00 2024
From: a-bhatia1 at ti.com (Aradhya Bhatia)
Date: Thu, 15 Feb 2024 17:03:00 +0530
Subject: [PATCH v3 1/2] dt-bindings: display: ti,am65x-dss: Add support
 for common1 region
In-Reply-To: <20240215083205.2902634-2-devarsht@ti.com>
References: <20240215083205.2902634-1-devarsht@ti.com>
 <20240215083205.2902634-2-devarsht@ti.com>
Message-ID: <5c73328c-5a83-4937-aafe-af55d14fcb89@ti.com>



On 15/02/24 14:02, Devarsh Thakkar wrote:
> TI keystone display subsystem present in AM65 and other SoCs such as AM62
> support two separate register spaces namely "common" and "common1" which
> can be used by two separate hosts to program the display controller as
> described in respective Technical Reference Manuals [1].
> 
> The common1 register space has similar set of configuration registers as
> supported in common register space except the global configuration
> registers which are exclusive to common region.
> 
> This adds binding for "common1" register region too as supported by the
> hardware.
> 
> [1]:
> AM62x TRM:
> https://www.ti.com/lit/pdf/spruiv7 (Section 14.8.9.1 DSS Registers)
> 
> AM65x TRM:
> https://www.ti.com/lit/pdf/spruid7 (Section 12.6.5 DSS Registers)

Can you add the TRM link for AM62A too?

With that sorted,

Reviewed-by: Aradhya Bhatia <a-bhatia1 at ti.com>

> 
> Fixes: 2d8730f1021f ("dt-bindings: display: ti,am65x-dss: Add dt-schema yaml binding")
> Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>> ---
> V2: Add Acked-by tag
> V3: Add Fixes tag
> ---
>  .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> index b6767ef0d24d..55e3e490d0e6 100644
> --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> @@ -37,6 +37,7 @@ properties:
>        - description: OVR2 overlay manager for vp2
>        - description: VP1 video port 1
>        - description: VP2 video port 2
> +      - description: common1 DSS register area
>  
>    reg-names:
>      items:
> @@ -47,6 +48,7 @@ properties:
>        - const: ovr2
>        - const: vp1
>        - const: vp2
> +      - const: common1
>  
>    clocks:
>      items:
> @@ -147,9 +149,10 @@ examples:
>                      <0x04a07000 0x1000>, /* ovr1 */
>                      <0x04a08000 0x1000>, /* ovr2 */
>                      <0x04a0a000 0x1000>, /* vp1 */
> -                    <0x04a0b000 0x1000>; /* vp2 */
> +                    <0x04a0b000 0x1000>, /* vp2 */
> +                    <0x04a01000 0x1000>; /* common1 */
>              reg-names = "common", "vidl1", "vid",
> -                    "ovr1", "ovr2", "vp1", "vp2";
> +                    "ovr1", "ovr2", "vp1", "vp2", "common1";
>              ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
>              power-domains = <&k3_pds 67 TI_SCI_PD_EXCLUSIVE>;
>              clocks =        <&k3_clks 67 1>,


From a-bhatia1 at ti.com  Thu Feb 15 03:34:07 2024
From: a-bhatia1 at ti.com (Aradhya Bhatia)
Date: Thu, 15 Feb 2024 17:04:07 +0530
Subject: [PATCH v3 2/2] arm64: dts: ti: Add common1 register space for
 AM62x, AM62A & AM65x SoCs
In-Reply-To: <20240215083205.2902634-3-devarsht@ti.com>
References: <20240215083205.2902634-1-devarsht@ti.com>
 <20240215083205.2902634-3-devarsht@ti.com>
Message-ID: <2242fca2-3cef-4ef9-adfc-322822e6a24e@ti.com>

Thanks for the fixes, Devarsh!

On 15/02/24 14:02, Devarsh Thakkar wrote:
> This adds common1 register space for AM62x, AM62A and AM65x SoC's which are
> using TI's Keystone display hardware and supporting it as described in
> Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> 
> Fixes: 3618811657b3 ("arm64: dts: ti: k3-am62a-main: Add node for Display SubSystem (DSS)")
> Fixes: 8ccc1073c7bb ("arm64: dts: ti: k3-am62-main: Add node for DSS")
> Fixes: fc539b90eda2 ("arm64: dts: ti: am654: Add DSS node")
> Signed-off-by: Devarsh Thakkar <devarsht at ti.com>

Reviewed-by: Aradhya Bhatia <a-bhatia1 at ti.com>

> ---
> V2: Add common1 region for AM62A SoC too
> V3: Add Fixes tag
> ---
>  arch/arm64/boot/dts/ti/k3-am62-main.dtsi  | 5 +++--
>  arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 5 +++--
>  arch/arm64/boot/dts/ti/k3-am65-main.dtsi  | 5 +++--
>  3 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> index fe0cc4a9a501..8cee4d94cdd3 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> @@ -779,9 +779,10 @@ dss: dss at 30200000 {
>  		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
>  		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
>  		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
> -		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
> +		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
> +		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
>  		reg-names = "common", "vidl1", "vid",
> -			    "ovr1", "ovr2", "vp1", "vp2";
> +			    "ovr1", "ovr2", "vp1", "vp2", "common1";
>  		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&k3_clks 186 6>,
>  			 <&dss_vp1_clk>,
> diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> index 972971159a62..f475daea548e 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> @@ -994,9 +994,10 @@ dss: dss at 30200000 {
>  		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
>  		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
>  		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Tied OFF in the SoC */
> -		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
> +		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
> +		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
>  		reg-names = "common", "vidl1", "vid",
> -			    "ovr1", "ovr2", "vp1", "vp2";
> +			    "ovr1", "ovr2", "vp1", "vp2", "common1";
>  		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&k3_clks 186 6>,
>  			 <&k3_clks 186 0>,
> diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> index 07010d31350e..ff857117d719 100644
> --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> @@ -991,9 +991,10 @@ dss: dss at 4a00000 {
>  		      <0x0 0x04a07000 0x0 0x1000>, /* ovr1 */
>  		      <0x0 0x04a08000 0x0 0x1000>, /* ovr2 */
>  		      <0x0 0x04a0a000 0x0 0x1000>, /* vp1 */
> -		      <0x0 0x04a0b000 0x0 0x1000>; /* vp2 */
> +		      <0x0 0x04a0b000 0x0 0x1000>, /* vp2 */
> +		      <0x0 0x04a01000 0x0 0x1000>; /* common1 */
>  		reg-names = "common", "vidl1", "vid",
> -			"ovr1", "ovr2", "vp1", "vp2";
> +			"ovr1", "ovr2", "vp1", "vp2", "common1";
>  
>  		ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
>  


From u.kleine-koenig at pengutronix.de  Thu Feb 15 03:34:23 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Thu, 15 Feb 2024 12:34:23 +0100
Subject: [PATCH V2 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible
 for MT7988
In-Reply-To: <20240214140454.6438-1-zajec5@gmail.com>
References: <20240214140454.6438-1-zajec5@gmail.com>
Message-ID: <ive5ueu7oq4hdfzxjevalssaotfmq2jb47zxanwbscxdaldum2@3bpqogbuhbjs>

Hello,

On Wed, Feb 14, 2024 at 03:04:53PM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7988 has on-SoC controller that can control up to 8 PWM interfaces. It
> differs from blocks on other SoCs (amount of PWMs & registers) so it
> needs its own compatible string.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
> V2: Explain new compatibility string reason in commit body
> 
>  Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml | 1 +
>  1 file changed, 1 insertion(+)

Applied both patches to
https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/for-next

Best regards and thanks
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/20240215/7fe37799/attachment.sig>

From mark.rutland at arm.com  Thu Feb 15 03:36:23 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 15 Feb 2024 11:36:23 +0000
Subject: [PATCH v6 00/18] Transparent Contiguous PTEs for User Mappings
In-Reply-To: <20240215103205.2607016-1-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
Message-ID: <Zc33Nx2ieCnzVfCe@FVFF77S0Q05N>

On Thu, Feb 15, 2024 at 10:31:47AM +0000, Ryan Roberts wrote:
> Hi All,
> 
> This is a series to opportunistically and transparently use contpte mappings
> (set the contiguous bit in ptes) for user memory when those mappings meet the
> requirements. The change benefits arm64, but there is some (very) minor
> refactoring for x86 to enable its integration with core-mm.

I've looked over each of the arm64-specific patches, and those all seem good to
me. I've thrown my local Syzkaller instance at the series, and I'll shout if
that hits anything that's not clearly a latent issue prior to this series.

The other bits also look good to me, so FWIW, for the series as a whole:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.


From will at kernel.org  Thu Feb 15 03:38:17 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 15 Feb 2024 11:38:17 +0000
Subject: [PATCH rc] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240214190954.GI1088888@nvidia.com>
References: <20240208125846.GA23290@willie-the-truck>
 <20240208142729.GH10476@nvidia.com>
 <20240213112015.GB28517@willie-the-truck>
 <20240213121850.GH4048826@nvidia.com>
 <20240213125456.GA28844@willie-the-truck>
 <20240213133045.GA989297@nvidia.com>
 <20240213135627.GD28926@willie-the-truck>
 <20240213140033.GB989297@nvidia.com>
 <20240214170030.GB31927@willie-the-truck>
 <20240214190954.GI1088888@nvidia.com>
Message-ID: <20240215113816.GA358@willie-the-truck>

On Wed, Feb 14, 2024 at 03:09:54PM -0400, Jason Gunthorpe wrote:
> On Wed, Feb 14, 2024 at 05:00:30PM +0000, Will Deacon wrote:
> 
> > 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 0ffb1cf17e0b..e48f2b46f25e 100644
> > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > @@ -1019,7 +1019,10 @@ static void arm_smmu_write_cd_l1_desc(__le64 *dst,
> >  	WRITE_ONCE(*dst, cpu_to_le64(val));
> >  }
> >  
> > -static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
> > +static __le64 *
> > +__arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid,
> > +		      int (*cd_alloc)(struct arm_smmu_device *,
> > +				      struct arm_smmu_l1_ctx_desc *))
> >  {
> >  	__le64 *l1ptr;
> >  	unsigned int idx;
> > @@ -1033,7 +1036,7 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
> >  	idx = ssid >> CTXDESC_SPLIT;
> >  	l1_desc = &cd_table->l1_desc[idx];
> >  	if (!l1_desc->l2ptr) {
> > -		if (arm_smmu_alloc_cd_leaf_table(smmu, l1_desc))
> > +		if (!cd_alloc || cd_alloc(smmu, l1_desc))
> >  			return NULL;
> >  
> >  		l1ptr = cd_table->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
> > @@ -1045,6 +1048,19 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
> >  	return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS;
> >  }
> >  
> > +static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
> > +{
> > +	return __arm_smmu_get_cd_ptr(master, ssid, NULL);
> > +}
> 
> I think this will break arm_smmu_write_ctx_desc() which requires
> allocation behavior to install the SSID0 in a two level table?

Ah yes, you're quite right. We'd need to add the allocation to
arm_smmu_attach_dev() as well.

> > +int arm_smmu_init_cd_table(struct arm_smmu_master *master, int ssid)
> > +{
> > +	if (!__arm_smmu_get_cd_ptr(master, ssid, arm_smmu_alloc_cd_leaf_table))
> > +		return -ENOMEM;
> > +
> > +	return 0;
> > +}
> 
> And this does not compose well with the rest of where we are going. At
> the end there are 7 calls to arm_smmu_get_cd_ptr(), all need
> allocation except for two (clear and mmu notifier release)
> 
> Better to add a noalloc version. Also 'bool noalloc' would be clearer
> than a function pointer without obfuscating the control flow.
> 
> Also I don't think this should go to -rc, it is not fixing any
> bug. The preallocation is enough. Making more clarity for this
> confused code is a nice to have at best.
> 
> How about this instead as a -next patch:
> 
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> @@ -288,10 +288,11 @@ static const struct mmu_notifier_ops arm_smmu_mmu_notifier_ops = {
>  
>  /* Allocate or get existing MMU notifier for this {domain, mm} pair */
>  static struct arm_smmu_mmu_notifier *
> -arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
> +arm_smmu_mmu_notifier_get(struct arm_smmu_master *true_master,
> +                         struct arm_smmu_domain *smmu_domain,
>                           struct mm_struct *mm)
>  {
> -       int ret;
> +       int ret = 0;
>         unsigned long flags;
>         struct arm_smmu_ctx_desc *cd;
>         struct arm_smmu_mmu_notifier *smmu_mn;
> @@ -327,8 +328,15 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
>  
>         spin_lock_irqsave(&smmu_domain->devices_lock, flags);
>         list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> -               ret = arm_smmu_write_ctx_desc(master, mm_get_enqcmd_pasid(mm),
> -                                             cd);
> +               /*
> +                * A limitation of the current SVA code requires the RID
> +                * smmu_domain to be unique to the actual master.
> +                */
> +               if (WARN_ON(master != true_master))
> +                       ret = -EINVAL;
> +               if (!ret)
> +                       ret = arm_smmu_write_ctx_desc(
> +                               master, mm_get_enqcmd_pasid(mm), cd);
>                 if (ret) {
>                         list_for_each_entry_from_reverse(
>                                 master, &smmu_domain->devices, domain_head)
> @@ -398,7 +406,7 @@ static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
>  
>         bond->mm = mm;
>  
> -       bond->smmu_mn = arm_smmu_mmu_notifier_get(smmu_domain, mm);
> +       bond->smmu_mn = arm_smmu_mmu_notifier_get(master, smmu_domain, mm);
>         if (IS_ERR(bond->smmu_mn)) {
>                 ret = PTR_ERR(bond->smmu_mn);
>                 goto err_free_bond;

This is what I originally had in mind, but for some reason I thought you
weren't happy with it. Mind if I fold it into your -rc patch? I'd really
like them to go in together.

Will


From will at kernel.org  Thu Feb 15 03:44:57 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 15 Feb 2024 11:44:57 +0000
Subject: [PATCH v2] perf: CXL: fix CPMU filter value mask length
In-Reply-To: <20240215080906epcms2p2c49c6b9bfe271e1d089ad35ab527b958@epcms2p2>
References: <CGME20240215080906epcms2p2c49c6b9bfe271e1d089ad35ab527b958@epcms2p2>
 <20240215080906epcms2p2c49c6b9bfe271e1d089ad35ab527b958@epcms2p2>
Message-ID: <20240215114457.GB358@willie-the-truck>

Hi Hojin,

On Thu, Feb 15, 2024 at 05:09:06PM +0900, Hojin Nam wrote:
> CPMU filter value is described as 4B length in CXL r3.0 8.2.7.2.2.
> However, it is used as 2B length in code and comments.
> 
> Signed-off-by: Hojin Nam <hj96.nam at samsung.com>
> ---
> 
> Hi Jonathan,
> as you said, I didn't actually hit this. I just found it by simply
> comparing the code to the CXL Spec. I removed Fixes tag and 
> repaired broken sign off, Thank you!
> 
> Changes since v1:
> - Remove Fixes tag (Jonathan)
> - Repair broken sign off (Jonathan)
> 
>  drivers/perf/cxl_pmu.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
> index 365d964b0f6a..ca5e92f28b4a 100644
> --- a/drivers/perf/cxl_pmu.c
> +++ b/drivers/perf/cxl_pmu.c
> @@ -59,7 +59,7 @@
>  #define   CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK     GENMASK_ULL(63, 59)
> 
>  #define CXL_PMU_FILTER_CFG_REG(n, f)   (0x400 + 4 * ((f) + (n) * 8))
> -#define   CXL_PMU_FILTER_CFG_VALUE_MSK                 GENMASK(15, 0)
> +#define   CXL_PMU_FILTER_CFG_VALUE_MSK                 GENMASK(31, 0)

Unfortunately, your patch appears to be whitespace-damaged (missing space,
tabs converted to space) so I'm not able to apply it :(

Will


From maz at kernel.org  Thu Feb 15 03:47:46 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 15 Feb 2024 11:47:46 +0000
Subject: [PATCH v12 01/25] irqchip/gic-v3: Make gic_irq_domain_select() robust for zero parameter count
In-Reply-To: <20240127161753.114685-2-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
	<20240127161753.114685-2-apatel@ventanamicro.com>
Message-ID: <86plwy3q59.wl-maz@kernel.org>

On Sat, 27 Jan 2024 16:17:29 +0000,
Anup Patel <apatel at ventanamicro.com> wrote:
> 
> From: Thomas Gleixner <tglx at linutronix.de>
> 
> Currently the irqdomain select callback is only invoked when the parameter
> count of the fwspec arguments is not zero. That makes sense because then
> the match is on the firmware node and eventually on the bus_token, which is
> already handled in the core code.
> 
> The upcoming support for per device MSI domains requires to do real bus
> token specific checks in the MSI parent domains with a zero parameter
> count.
> 
> Make the gic-v3 select() callback handle that case.
> 
> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: 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 maz at kernel.org  Thu Feb 15 03:54:11 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 15 Feb 2024 11:54:11 +0000
Subject: [PATCH v12 04/25] genirq/irqdomain: Add DOMAIN_BUS_DEVICE_IMS
In-Reply-To: <20240127161753.114685-5-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
	<20240127161753.114685-5-apatel@ventanamicro.com>
Message-ID: <86o7ci3puk.wl-maz@kernel.org>

On Sat, 27 Jan 2024 16:17:32 +0000,
Anup Patel <apatel at ventanamicro.com> wrote:
> 
> From: Thomas Gleixner <tglx at linutronix.de>
> 
> Add a new domain bus token to prepare for device MSI which aims to replace
> the existing platform MSI maze.
> 
> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> ---
>  include/linux/irqdomain_defs.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/linux/irqdomain_defs.h b/include/linux/irqdomain_defs.h
> index c29921fd8cd1..4c69151cb9d2 100644
> --- a/include/linux/irqdomain_defs.h
> +++ b/include/linux/irqdomain_defs.h
> @@ -26,6 +26,7 @@ enum irq_domain_bus_token {
>  	DOMAIN_BUS_DMAR,
>  	DOMAIN_BUS_AMDVI,
>  	DOMAIN_BUS_PCI_DEVICE_IMS,
> +	DOMAIN_BUS_DEVICE_IMS,

Only a personal taste, but since we keep calling it "device MSI",
which it really is, I find it slightly odd to name the token
"DEVICE_IMS".

From what I understand, IMS is PCIe specific. Platform (and by
extension device) MSI extends far beyond PCIe. So here, DEVICE_MSI
would make a lot more sense and avoid confusion.

But hey, I don't have much skin in this game, and I can probably
mentally rotate the acronym...

	M.

-- 
Without deviation from the norm, progress is not possible.


From devarsht at ti.com  Thu Feb 15 03:55:14 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Thu, 15 Feb 2024 17:25:14 +0530
Subject: [PATCH v4 0/2] Add common1 region for AM62, AM62A & AM65x
Message-ID: <20240215115516.3157909-1-devarsht@ti.com>

This adds DSS common1 region for respective SoCs supporting it.

Changelog:
V2 : Remove do-not-merge tag and add am62a dss common1 reion
V3 : Add Fixes tag to each commit
V4 : Add Reviewed-by tag and AM62A SoC TRM Link
 
Devarsh Thakkar (2):
  dt-bindings: display: ti,am65x-dss: Add support for common1 region
  arm64: dts: ti: Add common1 register space for AM62x, AM62A & AM65x
    SoCs

 .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi                   | 5 +++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi                  | 5 +++--
 arch/arm64/boot/dts/ti/k3-am65-main.dtsi                   | 5 +++--
 4 files changed, 14 insertions(+), 8 deletions(-)

-- 
2.34.1



From sakari.ailus at iki.fi  Thu Feb 15 03:55:27 2024
From: sakari.ailus at iki.fi (Sakari Ailus)
Date: Thu, 15 Feb 2024 11:55:27 +0000
Subject: [PATCH v4 4/5] media: platform: mediatek: isp_30: add mediatek
 ISP3.0 camsv
In-Reply-To: <20240110141443.364655-5-jstephan@baylibre.com>
References: <20240110141443.364655-1-jstephan@baylibre.com>
 <20240110141443.364655-5-jstephan@baylibre.com>
Message-ID: <Zc37r7xf84gNpWra@valkosipuli.retiisi.eu>

Hi Julien,

On Wed, Jan 10, 2024 at 03:14:41PM +0100, Julien Stephan wrote:
> From: Phi-bang Nguyen <pnguyen at baylibre.com>
> 
> This driver provides a path to bypass the SoC ISP so that image data
> coming from the SENINF can go directly into memory without any image
> processing. This allows the use of an external ISP.
> 
> Signed-off-by: Phi-bang Nguyen <pnguyen at baylibre.com>
> Signed-off-by: Florian Sylvestre <fsylvestre at baylibre.com>
> [Paul Elder fix irq locking]
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> Co-developed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Co-developed-by: Julien Stephan <jstephan at baylibre.com>
> Signed-off-by: Julien Stephan <jstephan at baylibre.com>
> ---
>  MAINTAINERS                                   |   1 +
>  .../platform/mediatek/isp/isp_30/Kconfig      |  19 +
>  .../platform/mediatek/isp/isp_30/Makefile     |   1 +
>  .../mediatek/isp/isp_30/camsv/Makefile        |   7 +
>  .../mediatek/isp/isp_30/camsv/mtk_camsv.c     | 328 ++++++++
>  .../mediatek/isp/isp_30/camsv/mtk_camsv.h     | 199 +++++
>  .../isp/isp_30/camsv/mtk_camsv30_hw.c         | 427 ++++++++++
>  .../isp/isp_30/camsv/mtk_camsv30_regs.h       |  60 ++
>  .../isp/isp_30/camsv/mtk_camsv_video.c        | 774 ++++++++++++++++++
>  9 files changed, 1816 insertions(+)
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/camsv/Makefile
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv.c
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv.h
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv30_hw.c
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv30_regs.h
>  create mode 100644 drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv_video.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 52d200d5e36c..ffe4d3ae62e5 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -13618,6 +13618,7 @@ M:	Andy Hsieh <andy.hsieh at mediatek.com>
>  S:	Supported
>  F:	Documentation/devicetree/bindings/media/mediatek,mt8365-camsv.yaml
>  F:	Documentation/devicetree/bindings/media/mediatek,mt8365-seninf.yaml
> +F:	drivers/media/platform/mediatek/isp/isp_30/camsv/*
>  F:	drivers/media/platform/mediatek/isp/isp_30/seninf/*
>  
>  MEDIATEK SMI DRIVER
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/Kconfig b/drivers/media/platform/mediatek/isp/isp_30/Kconfig
> index 9791312589fb..5293a061ae0b 100644
> --- a/drivers/media/platform/mediatek/isp/isp_30/Kconfig
> +++ b/drivers/media/platform/mediatek/isp/isp_30/Kconfig
> @@ -14,3 +14,22 @@ config MTK_SENINF30
>  
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called mtk-seninf.
> +
> +config MTK_CAMSV30
> +	tristate "MediaTek ISP3.0 CAMSV driver"
> +	depends on VIDEO_V4L2_SUBDEV_API
> +	depends on ARCH_MEDIATEK || COMPILE_TEST
> +	depends on OF
> +	depends on PM
> +	select VIDEOBUF2_VMALLOC
> +	select VIDEOBUF2_DMA_CONTIG
> +	select MTK_SENINF30
> +	select PHY_MTK_MIPI_CSI_0_5
> +	default n
> +	help
> +	  This driver provides a path to bypass the SoC ISP so that
> +	  image data come from the SENINF can go directly into memory
> +	  without any image processing.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called mtk-camsv30.
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/Makefile b/drivers/media/platform/mediatek/isp/isp_30/Makefile
> index ac3142de4739..a76f440c5358 100644
> --- a/drivers/media/platform/mediatek/isp/isp_30/Makefile
> +++ b/drivers/media/platform/mediatek/isp/isp_30/Makefile
> @@ -1,3 +1,4 @@
>  # SPDX-License-Identifier: GPL-2.0
>  
>  obj-$(CONFIG_MTK_SENINF30) += seninf/
> +obj-$(CONFIG_MTK_CAMSV30) += camsv/
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/camsv/Makefile b/drivers/media/platform/mediatek/isp/isp_30/camsv/Makefile
> new file mode 100644
> index 000000000000..fffbc6e7cb78
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/camsv/Makefile
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +mtk-camsv30-objs += mtk_camsv.o
> +mtk-camsv30-objs += mtk_camsv30_hw.o
> +mtk-camsv30-objs += mtk_camsv_video.o
> +
> +obj-$(CONFIG_MTK_CAMSV30) += mtk-camsv30.o
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv.c b/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv.c
> new file mode 100644
> index 000000000000..37ee07d503b9
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv.c
> @@ -0,0 +1,328 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 BayLibre
> + * Copyright (c) 2022 MediaTek Inc.
> + */
> +
> +#include <media/v4l2-async.h>
> +#include <media/v4l2-device.h>
> +
> +#include "mtk_camsv.h"
> +
> +static inline struct mtk_cam_dev *to_mtk_cam_dev(struct v4l2_subdev *sd)
> +{
> +	return container_of(sd, struct mtk_cam_dev, subdev);
> +}
> +
> +static const u32 mtk_cam_mbus_formats[] = {
> +	MEDIA_BUS_FMT_SBGGR8_1X8,
> +	MEDIA_BUS_FMT_SGBRG8_1X8,
> +	MEDIA_BUS_FMT_SGRBG8_1X8,
> +	MEDIA_BUS_FMT_SRGGB8_1X8,
> +	MEDIA_BUS_FMT_SBGGR10_1X10,
> +	MEDIA_BUS_FMT_SGBRG10_1X10,
> +	MEDIA_BUS_FMT_SGRBG10_1X10,
> +	MEDIA_BUS_FMT_SRGGB10_1X10,
> +	MEDIA_BUS_FMT_SBGGR12_1X12,
> +	MEDIA_BUS_FMT_SGBRG12_1X12,
> +	MEDIA_BUS_FMT_SGRBG12_1X12,
> +	MEDIA_BUS_FMT_SRGGB12_1X12,
> +	MEDIA_BUS_FMT_UYVY8_1X16,
> +	MEDIA_BUS_FMT_VYUY8_1X16,
> +	MEDIA_BUS_FMT_YUYV8_1X16,
> +	MEDIA_BUS_FMT_YVYU8_1X16,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdev Operations
> + */
> +
> +static int mtk_cam_cio_stream_on(struct mtk_cam_dev *cam)
> +{
> +	struct device *dev = cam->dev;
> +	struct v4l2_subdev *seninf;
> +	int ret;
> +
> +	if (!cam->seninf) {
> +		cam->seninf = media_pad_remote_pad_first(&cam->subdev_pads[MTK_CAM_CIO_PAD_SENINF]);
> +		if (!cam->seninf) {
> +			dev_err(dev, "%s: No SENINF connected\n", __func__);
> +			return -ENOLINK;
> +		}
> +	}
> +
> +	seninf = media_entity_to_v4l2_subdev(cam->seninf->entity);
> +
> +	/* Seninf must stream on first */
> +	ret = v4l2_subdev_call(seninf, pad, enable_streams, NULL, cam->seninf->index, 0);
> +	if (ret) {
> +		dev_err(dev, "failed to stream on %s:%d\n",
> +			seninf->entity.name, ret);
> +		return ret;
> +	}
> +
> +	cam->streaming = true;
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_cio_stream_off(struct mtk_cam_dev *cam)
> +{
> +	int ret;
> +
> +	if (cam->seninf) {
> +		struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(cam->seninf->entity);
> +
> +		ret = v4l2_subdev_call(sd, pad, disable_streams, NULL,
> +				       cam->seninf->index, 0);
> +		if (ret) {
> +			dev_err(cam->dev, "failed to stream off %s:%d\n",
> +				sd->entity.name, ret);
> +			return ret;
> +		}
> +	}
> +
> +	cam->streaming = false;
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_sd_s_stream(struct v4l2_subdev *sd, int enable)
> +{
> +	struct mtk_cam_dev *cam = to_mtk_cam_dev(sd);
> +
> +	if (enable) {
> +		/* Align vb2_core_streamon design */
> +		if (cam->streaming) {
> +			dev_warn(cam->dev, "already streaming on\n");
> +			return 0;
> +		}
> +		return mtk_cam_cio_stream_on(cam);
> +	}
> +
> +	if (!cam->streaming) {
> +		dev_warn(cam->dev, "already streaming off\n");
> +		return 0;
> +	}
> +
> +	return mtk_cam_cio_stream_off(cam);
> +}
> +
> +static struct v4l2_mbus_framefmt *
> +mtk_cam_get_pad_format(struct mtk_cam_dev *cam,
> +		       struct v4l2_subdev_state *sd_state,
> +		       unsigned int pad, u32 which)
> +{
> +	switch (which) {
> +	case V4L2_SUBDEV_FORMAT_TRY:
> +		return v4l2_subdev_get_try_format(&cam->subdev, sd_state, pad);
> +	case V4L2_SUBDEV_FORMAT_ACTIVE:
> +		return &cam->formats[pad];

Please use v4l2_subdev_state_get_format() instead. Do not store the format
information in your own context struct.

> +	default:
> +		return NULL;
> +	}
> +}
> +
> +static int mtk_cam_init_cfg(struct v4l2_subdev *sd,
> +			    struct v4l2_subdev_state *sd_state)
> +{
> +	static const struct v4l2_mbus_framefmt def_format = {
> +		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
> +		.width = IMG_DEF_WIDTH,
> +		.height = IMG_DEF_HEIGHT,
> +		.field = V4L2_FIELD_NONE,
> +		.colorspace = V4L2_COLORSPACE_SRGB,
> +		.xfer_func = V4L2_XFER_FUNC_DEFAULT,
> +		.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
> +		.quantization = V4L2_QUANTIZATION_DEFAULT,
> +	};
> +

Extra newline.

> +	struct mtk_cam_dev *cam = to_mtk_cam_dev(sd);
> +	u32 which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
> +		  : V4L2_SUBDEV_FORMAT_ACTIVE;
> +	struct v4l2_mbus_framefmt *format;
> +	unsigned int i;
> +
> +	for (i = 0; i < sd->entity.num_pads; i++) {
> +		format = mtk_cam_get_pad_format(cam, sd_state, i, which);
> +		*format = def_format;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_enum_mbus_code(struct v4l2_subdev *sd,
> +				  struct v4l2_subdev_state *sd_state,
> +				  struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	if (code->index >= ARRAY_SIZE(mtk_cam_mbus_formats))
> +		return -EINVAL;
> +
> +	code->code = mtk_cam_mbus_formats[code->index];
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_get_fmt(struct v4l2_subdev *sd,
> +			   struct v4l2_subdev_state *sd_state,
> +			   struct v4l2_subdev_format *fmt)
> +{
> +	struct mtk_cam_dev *cam = to_mtk_cam_dev(sd);
> +
> +	fmt->format = *mtk_cam_get_pad_format(cam, sd_state, fmt->pad,
> +					      fmt->which);
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_set_fmt(struct v4l2_subdev *sd,
> +			   struct v4l2_subdev_state *sd_state,
> +			   struct v4l2_subdev_format *fmt)
> +{
> +	struct mtk_cam_dev *cam = to_mtk_cam_dev(sd);
> +	struct v4l2_mbus_framefmt *format;
> +	unsigned int i;
> +
> +	/*
> +	 * We only support pass-through mode, the format on source pads can't
> +	 * be modified.
> +	 */
> +	if (fmt->pad != MTK_CAM_CIO_PAD_SENINF)
> +		return mtk_cam_get_fmt(sd, sd_state, fmt);
> +
> +	for (i = 0; i < ARRAY_SIZE(mtk_cam_mbus_formats); ++i) {
> +		if (mtk_cam_mbus_formats[i] == fmt->format.code)
> +			break;
> +	}
> +
> +	if (i == ARRAY_SIZE(mtk_cam_mbus_formats))
> +		fmt->format.code = mtk_cam_mbus_formats[0];
> +
> +	format = mtk_cam_get_pad_format(cam, sd_state, fmt->pad, fmt->which);
> +	format->width = fmt->format.width;
> +	format->height = fmt->format.height;
> +	format->code = fmt->format.code;
> +
> +	fmt->format = *format;
> +
> +	/* Propagate the format to the source pad. */
> +	format = mtk_cam_get_pad_format(cam, sd_state, MTK_CAM_CIO_PAD_VIDEO,
> +					fmt->which);
> +	format->width = fmt->format.width;
> +	format->height = fmt->format.height;
> +	format->code = fmt->format.code;
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_subdev_registered(struct v4l2_subdev *sd)
> +{
> +	struct mtk_cam_dev *cam = to_mtk_cam_dev(sd);
> +
> +	/* Create the video device and link. */
> +	return mtk_cam_video_register(cam);
> +}
> +
> +static const struct v4l2_subdev_video_ops mtk_cam_subdev_video_ops = {
> +	.s_stream = mtk_cam_sd_s_stream,
> +};
> +
> +static const struct v4l2_subdev_pad_ops mtk_cam_subdev_pad_ops = {
> +	.init_cfg = mtk_cam_init_cfg,
> +	.enum_mbus_code = mtk_cam_enum_mbus_code,
> +	.set_fmt = mtk_cam_set_fmt,
> +	.get_fmt = mtk_cam_get_fmt,
> +	.link_validate = v4l2_subdev_link_validate_default,
> +};
> +
> +static const struct v4l2_subdev_ops mtk_cam_subdev_ops = {
> +	.video = &mtk_cam_subdev_video_ops,
> +	.pad = &mtk_cam_subdev_pad_ops,
> +};
> +
> +static const struct v4l2_subdev_internal_ops mtk_cam_internal_ops = {
> +	.registered = mtk_cam_subdev_registered,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Media Entity Operations
> + */
> +
> +static const struct media_entity_operations mtk_cam_media_entity_ops = {
> +	.link_validate = v4l2_subdev_link_validate,
> +	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Init & Cleanup
> + */
> +
> +static int mtk_cam_v4l2_register(struct mtk_cam_dev *cam)
> +{
> +	struct device *dev = cam->dev;
> +	int ret;
> +
> +	cam->subdev_pads[MTK_CAM_CIO_PAD_SENINF].flags = MEDIA_PAD_FL_SINK;
> +	cam->subdev_pads[MTK_CAM_CIO_PAD_VIDEO].flags = MEDIA_PAD_FL_SOURCE;
> +
> +	/* Initialize subdev pads */
> +	ret = media_entity_pads_init(&cam->subdev.entity,
> +				     ARRAY_SIZE(cam->subdev_pads),
> +				     cam->subdev_pads);
> +	if (ret) {
> +		dev_err(dev, "failed to initialize media pads:%d\n", ret);
> +		return ret;
> +	}
> +
> +	/* Initialize subdev */
> +	v4l2_subdev_init(&cam->subdev, &mtk_cam_subdev_ops);
> +
> +	cam->subdev.dev = dev;
> +	cam->subdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
> +	cam->subdev.entity.ops = &mtk_cam_media_entity_ops;
> +	cam->subdev.internal_ops = &mtk_cam_internal_ops;
> +	cam->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
> +	strscpy(cam->subdev.name, dev_name(dev), sizeof(cam->subdev.name));
> +	v4l2_set_subdevdata(&cam->subdev, cam);
> +
> +	mtk_cam_init_cfg(&cam->subdev, NULL);
> +
> +	ret = v4l2_async_register_subdev(&cam->subdev);
> +	if (ret) {
> +		dev_err(dev, "failed to initialize subdev:%d\n", ret);
> +		media_entity_cleanup(&cam->subdev.entity);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static void mtk_cam_v4l2_unregister(struct mtk_cam_dev *cam)
> +{
> +	mtk_cam_video_unregister(&cam->vdev);
> +
> +	media_entity_cleanup(&cam->subdev.entity);
> +	v4l2_async_unregister_subdev(&cam->subdev);
> +}
> +
> +int mtk_cam_dev_init(struct mtk_cam_dev *cam_dev)
> +{
> +	int ret;
> +
> +	mutex_init(&cam_dev->op_lock);
> +
> +	/* v4l2 sub-device registration */
> +	ret = mtk_cam_v4l2_register(cam_dev);
> +	if (ret) {
> +		mutex_destroy(&cam_dev->op_lock);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +void mtk_cam_dev_cleanup(struct mtk_cam_dev *cam)
> +{
> +	mtk_cam_v4l2_unregister(cam);
> +	mutex_destroy(&cam->op_lock);
> +}
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv.h b/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv.h
> new file mode 100644
> index 000000000000..f7aec8c49db6
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv.h
> @@ -0,0 +1,199 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2020 BayLibre
> + * Copyright (c) 2022 MediaTek Inc.
> + */
> +
> +#ifndef __MTK_CAMSV_H__
> +#define __MTK_CAMSV_H__
> +
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <linux/of_graph.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/videodev2.h>
> +#include <media/media-entity.h>
> +#include <media/v4l2-subdev.h>
> +#include <media/videobuf2-core.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <media/videobuf2-v4l2.h>
> +#include <soc/mediatek/smi.h>
> +
> +#define IMG_MAX_WIDTH			5376
> +#define IMG_MAX_HEIGHT			4032
> +#define IMG_DEF_WIDTH			1920
> +#define IMG_DEF_HEIGHT			1080
> +#define IMG_MIN_WIDTH			80
> +#define IMG_MIN_HEIGHT			60
> +
> +#define MTK_CAM_CIO_PAD_SENINF		0
> +#define MTK_CAM_CIO_PAD_VIDEO		1
> +#define MTK_CAM_CIO_NUM_PADS		2

You could add "U", these are all unsigned (int).

> +
> +struct mtk_cam_format_info {
> +	u32 code;
> +	u32 fourcc;
> +	bool packed;
> +	u8 bpp;
> +};
> +
> +struct mtk_cam_dev_buffer {
> +	struct vb2_v4l2_buffer v4l2_buf;
> +	struct list_head list;
> +	dma_addr_t daddr;
> +	void *vaddr;
> +};
> +
> +struct mtk_cam_sparams {
> +	u32 w_factor;
> +	u32 module_en_pak;
> +	u32 fmt_sel;
> +	u32 pak;
> +	u32 imgo_stride;
> +};
> +
> +/**
> + * struct mtk_cam_vdev_desc - MTK camera device descriptor
> + * @name: name of the node
> + * @cap: supported V4L2 capabilities
> + * @buf_type: supported V4L2 buffer type
> + * @link_flags: default media link flags
> + * @def_width: the default format width
> + * @def_height: the default format height
> + * @num_fmts: the number of supported node formats
> + * @max_buf_count: maximum VB2 buffer count
> + * @ioctl_ops:  mapped to v4l2_ioctl_ops
> + * @fmts: supported format
> + * @frmsizes: supported V4L2 frame size number
> + */
> +struct mtk_cam_vdev_desc {
> +	const char *name;
> +	u32 cap;
> +	u32 buf_type;
> +	u32 link_flags;
> +	u32 def_width;
> +	u32 def_height;
> +	u8 num_fmts;
> +	u8 max_buf_count;
> +	const struct v4l2_ioctl_ops *ioctl_ops;
> +	const u32 *fmts;
> +	const struct v4l2_frmsizeenum *frmsizes;

How different are these for different devices? You seem to support only
one. Do you need this struct at all?

> +};
> +
> +/**
> + * struct mtk_cam_video_device - MediaTek video device structure
> + * @desc: The node description of video device
> + * @vdev_pad: The media pad graph object of video device
> + * @vdev: The video device instance
> + * @vbq: A videobuf queue of video device
> + * @vdev_lock: Serializes vb2 queue and video device operations
> + * @format: The V4L2 format of video device
> + * @fmtinfo: Information about the current format
> + */
> +struct mtk_cam_video_device {
> +	const struct mtk_cam_vdev_desc *desc;
> +
> +	struct media_pad vdev_pad;
> +	struct video_device vdev;
> +	struct vb2_queue vbq;
> +
> +	/* Serializes vb2 queue and video device operations */
> +	struct mutex vdev_lock;
> +
> +	struct v4l2_pix_format_mplane format;
> +	const struct mtk_cam_format_info *fmtinfo;
> +};
> +
> +/**
> + * struct mtk_cam_dev - MediaTek camera device structure.
> + * @dev: Pointer to device.
> + * @regs: Base address of CAMSV.
> + * @regs_img0: Base address of CAMSV IMG0.
> + * @regs_tg: Base address of CAMSV TG.
> + * @num_clks: Number of clocks.
> + * @clks: The clocks.
> + * @irq: Irq fired when buffer is ready.
> + * @conf: soc specific driver data.
> + * @pipeline: Media pipeline information.
> + * @subdev: The V4L2 sub-device instance.
> + * @subdev_pads: Media pads of this sub-device.
> + * @formats: Media bus format for all pads.
> + * @vdev: The video device node.
> + * @seninf: Pointer to the seninf pad.
> + * @streaming: Indicate the overall streaming status is on or off.
> + * @stream_count: Number of streaming video nodes.
> + * @sequence: Buffer sequence number.
> + * @op_lock: Serializes driver's VB2 callback operations.
> + * @irqlock: Protects the buffer list.
> + * @buf_list: List head for the buffer list.
> + * @hw_functions: Hardware specific functions.
> + * @dummy: Dummy buffer used when user buffer is not available.
> + * @dummy_size : Size of the dummy buffer.
> + * @is_dummy_used: True if dummy buffer is currently used.
> + */
> +struct mtk_cam_dev {
> +	struct device *dev;
> +	void __iomem *regs;
> +	void __iomem *regs_img0;
> +	void __iomem *regs_tg;
> +
> +	unsigned int num_clks;
> +	struct clk_bulk_data *clks;
> +	unsigned int irq;
> +	const struct mtk_cam_conf *conf;
> +
> +	struct media_pipeline pipeline;
> +	struct v4l2_subdev subdev;
> +	struct media_pad subdev_pads[MTK_CAM_CIO_NUM_PADS];
> +	struct v4l2_mbus_framefmt formats[MTK_CAM_CIO_NUM_PADS];

The format information should be stored in sub-device state.

> +	struct mtk_cam_video_device vdev;
> +	struct media_pad *seninf;
> +	unsigned int streaming;
> +	unsigned int stream_count;
> +	unsigned int sequence;
> +
> +	struct mutex op_lock;
> +	spinlock_t irqlock;
> +
> +	struct list_head buf_list;
> +
> +	struct mtk_cam_hw_functions *hw_functions;
> +
> +	struct mtk_cam_dev_buffer dummy;
> +	unsigned int dummy_size;
> +	bool is_dummy_used;
> +};
> +
> +/**
> + * struct mtk_cam_conf - MediaTek camera configuration structure
> + * @tg_sen_mode: TG sensor mode
> + * @module_en: module enable
> + * @imgo_con: dma control register
> + * @imgo_con2: dma control register 2
> + */
> +struct mtk_cam_conf {
> +	u32 tg_sen_mode;
> +	u32 module_en;
> +	u32 imgo_con;
> +	u32 imgo_con2;
> +};
> +
> +struct mtk_cam_hw_functions {
> +	void (*mtk_cam_setup)(struct mtk_cam_dev *cam_dev, u32 width,
> +			      u32 height, u32 bpl, u32 mbus_fmt);
> +	void (*mtk_cam_update_buffers_add)(struct mtk_cam_dev *cam_dev,
> +					   struct mtk_cam_dev_buffer *buf);
> +	void (*mtk_cam_cmos_vf_hw_enable)(struct mtk_cam_dev *cam_dev,
> +					  bool pak_en);
> +	void (*mtk_cam_cmos_vf_hw_disable)(struct mtk_cam_dev *cam_dev,
> +					   bool pak_en);

Is there a reason why these are not called directly? They appear to be the
same in all cases.

> +};
> +
> +int mtk_cam_dev_init(struct mtk_cam_dev *cam_dev);
> +void mtk_cam_dev_cleanup(struct mtk_cam_dev *cam_dev);
> +int mtk_cam_video_register(struct mtk_cam_dev *cam_dev);
> +void mtk_cam_video_unregister(struct mtk_cam_video_device *vdev);
> +
> +#endif /* __MTK_CAMSV_H__ */
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv30_hw.c b/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv30_hw.c
> new file mode 100644
> index 000000000000..3b8ccdab2af0
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv30_hw.c
> @@ -0,0 +1,427 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 BayLibre
> + * Copyright (c) 2022 MediaTek Inc.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/interrupt.h>
> +#include <linux/iommu.h>
> +#include <linux/iopoll.h>
> +#include <linux/ktime.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +
> +#include "mtk_camsv.h"
> +#include "mtk_camsv30_regs.h"
> +
> +#define MTK_CAMSV30_AUTOSUSPEND_DELAY_MS 100
> +
> +static const struct mtk_cam_conf camsv30_conf = {
> +	.tg_sen_mode = 0x00010002U, /* TIME_STP_EN = 1. DBL_DATA_BUS = 1 */
> +	.module_en = 0x40000001U, /* enable double buffer and TG */
> +	.imgo_con = 0x80000080U, /* DMA FIFO depth and burst */
> +	.imgo_con2 = 0x00020002U, /* DMA priority */

It would be nicer to have macro names for the bits of these, they appear
register configuration-like values.

> +};
> +
> +static void fmt_to_sparams(u32 mbus_fmt, struct mtk_cam_sparams *sparams)
> +{
> +	switch (mbus_fmt) {
> +	/* SBGGR values coming from isp5.0 configuration.
> +	 * not tested on isp2.0
> +	 */

/*
 * Multi-line
 * comment.
 */

> +	case MEDIA_BUS_FMT_SBGGR12_1X12:
> +	case MEDIA_BUS_FMT_SGBRG12_1X12:
> +	case MEDIA_BUS_FMT_SGRBG12_1X12:
> +	case MEDIA_BUS_FMT_SRGGB12_1X12:
> +		sparams->w_factor = 1;
> +		sparams->module_en_pak = 0x4;
> +		sparams->fmt_sel = 0x2;
> +		sparams->pak = 0x5;
> +		sparams->imgo_stride = 0x000B0000;
> +		break;
> +	case MEDIA_BUS_FMT_SBGGR10_1X10:
> +	case MEDIA_BUS_FMT_SGBRG10_1X10:
> +	case MEDIA_BUS_FMT_SGRBG10_1X10:
> +	case MEDIA_BUS_FMT_SRGGB10_1X10:
> +		sparams->w_factor = 1;
> +		sparams->module_en_pak = 0x4;
> +		sparams->fmt_sel = 0x1;
> +		sparams->pak = 0x6;
> +		sparams->imgo_stride = 0x000B0000;
> +		break;
> +	case MEDIA_BUS_FMT_SBGGR8_1X8:
> +	case MEDIA_BUS_FMT_SGBRG8_1X8:
> +	case MEDIA_BUS_FMT_SGRBG8_1X8:
> +	case MEDIA_BUS_FMT_SRGGB8_1X8:
> +		sparams->w_factor = 1;
> +		sparams->module_en_pak = 0x4;
> +		sparams->fmt_sel = 0x0;
> +		sparams->pak = 0x7;
> +		sparams->imgo_stride = 0x000B0000;
> +		break;
> +	case MEDIA_BUS_FMT_UYVY8_1X16:
> +	case MEDIA_BUS_FMT_VYUY8_1X16:
> +	case MEDIA_BUS_FMT_YUYV8_1X16:
> +	case MEDIA_BUS_FMT_YVYU8_1X16:
> +		sparams->w_factor = 2;
> +		sparams->module_en_pak = 0x8;
> +		sparams->fmt_sel = 0x1000003;
> +		sparams->pak = 0x0;
> +		sparams->imgo_stride = 0x00090000;
> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
> +static void mtk_camsv30_update_buffers_add(struct mtk_cam_dev *cam_dev,
> +					   struct mtk_cam_dev_buffer *buf)
> +{
> +	writel(buf->daddr, cam_dev->regs_img0 + CAMSV_IMGO_SV_BASE_ADDR);
> +
> +	writel(0x1U, cam_dev->regs + CAMSV_IMGO_FBC);
> +}
> +
> +static void mtk_camsv30_cmos_vf_hw_enable(struct mtk_cam_dev *cam_dev,
> +					  bool pak_en)
> +{
> +	u32 clk_en;
> +
> +	clk_en = CAMSV_TG_DP_CLK_EN | CAMSV_DMA_DP_CLK_EN;
> +	if (pak_en)
> +		clk_en |= CAMSV_PAK_DP_CLK_EN;
> +	writel(clk_en, cam_dev->regs + CAMSV_CLK_EN);
> +	writel(readl(cam_dev->regs_tg + CAMSV_TG_VF_CON) | CAMSV_TG_VF_CON_VFDATA_EN,
> +			cam_dev->regs_tg + CAMSV_TG_VF_CON);
> +}
> +
> +static void mtk_camsv30_cmos_vf_hw_disable(struct mtk_cam_dev *cam_dev,
> +					   bool pak_en)
> +{
> +	writel(readl(cam_dev->regs_tg + CAMSV_TG_SEN_MODE) & ~CAMSV_TG_SEN_MODE_CMOS_EN,
> +			cam_dev->regs_tg + CAMSV_TG_SEN_MODE);
> +	writel(readl(cam_dev->regs_tg + CAMSV_TG_VF_CON) & ~CAMSV_TG_VF_CON_VFDATA_EN,
> +			cam_dev->regs_tg + CAMSV_TG_VF_CON);
> +}
> +
> +static void mtk_camsv30_setup(struct mtk_cam_dev *cam_dev, u32 w, u32 h,
> +			      u32 bpl, u32 mbus_fmt)
> +{
> +	const struct mtk_cam_conf *conf = cam_dev->conf;
> +	u32 int_en = INT_ST_MASK_CAMSV;
> +	u32 tmp;
> +	struct mtk_cam_sparams sparams;
> +
> +	fmt_to_sparams(mbus_fmt, &sparams);
> +
> +	if (pm_runtime_resume_and_get(cam_dev->dev) < 0) {
> +		dev_err(cam_dev->dev, "failed to get pm_runtime\n");
> +		return;
> +	}
> +
> +	spin_lock_irq(&cam_dev->irqlock);
> +
> +	writel(conf->tg_sen_mode, cam_dev->regs_tg + CAMSV_TG_SEN_MODE);
> +
> +	writel((w * sparams.w_factor) << 16U, cam_dev->regs_tg + CAMSV_TG_SEN_GRAB_PXL);
> +
> +	writel(h << 16U, cam_dev->regs_tg + CAMSV_TG_SEN_GRAB_LIN);
> +
> +	/* YUV_U2S_DIS: disable YUV sensor unsigned to signed */
> +	writel(0x1000U, cam_dev->regs_tg + CAMSV_TG_PATH_CFG);
> +
> +	/* Reset cam */
> +	writel(CAMSV_SW_RST, cam_dev->regs + CAMSV_SW_CTL);
> +	writel(0x0U, cam_dev->regs + CAMSV_SW_CTL);
> +	writel(CAMSV_IMGO_RST_TRIG, cam_dev->regs + CAMSV_SW_CTL);
> +
> +	readl_poll_timeout_atomic(cam_dev->regs + CAMSV_SW_CTL, tmp,
> +			(tmp == (CAMSV_IMGO_RST_TRIG | CAMSV_IMGO_RST_ST)), 10, 200);

Alignment. Same elsewhere in the function.

> +
> +	writel(0x0U, cam_dev->regs + CAMSV_SW_CTL);
> +
> +	writel(int_en, cam_dev->regs + CAMSV_INT_EN);
> +
> +	writel(conf->module_en | sparams.module_en_pak,
> +	      cam_dev->regs + CAMSV_MODULE_EN);
> +	writel(sparams.fmt_sel, cam_dev->regs + CAMSV_FMT_SEL);
> +	writel(sparams.pak, cam_dev->regs + CAMSV_PAK);
> +
> +	writel(bpl - 1U, cam_dev->regs_img0 + CAMSV_IMGO_SV_XSIZE);
> +	writel(h - 1U, cam_dev->regs_img0 + CAMSV_IMGO_SV_YSIZE);
> +
> +	writel(sparams.imgo_stride | bpl, cam_dev->regs_img0 + CAMSV_IMGO_SV_STRIDE);
> +
> +	writel(conf->imgo_con, cam_dev->regs_img0 + CAMSV_IMGO_SV_CON);
> +	writel(conf->imgo_con2, cam_dev->regs_img0 + CAMSV_IMGO_SV_CON2);
> +
> +	/* CMOS_EN first */
> +	writel(readl(cam_dev->regs_tg + CAMSV_TG_SEN_MODE) | CAMSV_TG_SEN_MODE_CMOS_EN,
> +			cam_dev->regs_tg + CAMSV_TG_SEN_MODE);
> +
> +	/* finally, CAMSV_MODULE_EN : IMGO_EN */
> +	writel(readl(cam_dev->regs + CAMSV_MODULE_EN) | CAMSV_MODULE_EN_IMGO_EN,
> +		    cam_dev->regs + CAMSV_MODULE_EN);
> +
> +	spin_unlock_irq(&cam_dev->irqlock);
> +	pm_runtime_put_autosuspend(cam_dev->dev);
> +}
> +
> +static irqreturn_t isp_irq_camsv30(int irq, void *data)
> +{
> +	struct mtk_cam_dev *cam_dev = (struct mtk_cam_dev *)data;
> +	struct mtk_cam_dev_buffer *buf;
> +	unsigned int irq_status;
> +
> +	spin_lock(&cam_dev->irqlock);
> +
> +	irq_status = readl(cam_dev->regs + CAMSV_INT_STATUS);
> +
> +	if (irq_status & INT_ST_MASK_CAMSV_ERR) {
> +		dev_err(cam_dev->dev, "irq error 0x%x\n",
> +			(unsigned int)(irq_status & INT_ST_MASK_CAMSV_ERR));

Maybe %lx and remove the casting?

> +	}
> +
> +	/* De-queue frame */
> +	if (irq_status & CAMSV_IRQ_PASS1_DON) {
> +		cam_dev->sequence++;
> +
> +		if (!cam_dev->is_dummy_used) {
> +			buf = list_first_entry_or_null(&cam_dev->buf_list,
> +						       struct mtk_cam_dev_buffer,
> +						       list);
> +			if (buf) {
> +				buf->v4l2_buf.sequence = cam_dev->sequence;
> +				buf->v4l2_buf.vb2_buf.timestamp = ktime_get_ns();
> +				vb2_buffer_done(&buf->v4l2_buf.vb2_buf,
> +						VB2_BUF_STATE_DONE);
> +				list_del(&buf->list);
> +			}
> +		}
> +
> +		if (list_empty(&cam_dev->buf_list)) {
> +			mtk_camsv30_update_buffers_add(cam_dev, &cam_dev->dummy);
> +			cam_dev->is_dummy_used = true;
> +		} else {
> +			buf = list_first_entry_or_null(&cam_dev->buf_list,
> +						       struct mtk_cam_dev_buffer,
> +						       list);
> +			mtk_camsv30_update_buffers_add(cam_dev, buf);
> +			cam_dev->is_dummy_used = false;
> +		}
> +	}
> +
> +	spin_unlock(&cam_dev->irqlock);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int mtk_camsv30_runtime_suspend(struct device *dev)
> +{
> +	struct mtk_cam_dev *cam_dev = dev_get_drvdata(dev);
> +	struct vb2_queue *vbq = &cam_dev->vdev.vbq;
> +
> +	if (vb2_is_streaming(vbq)) {
> +		mutex_lock(&cam_dev->op_lock);
> +		v4l2_subdev_call(&cam_dev->subdev, video, s_stream, 0);
> +		mutex_unlock(&cam_dev->op_lock);
> +	}
> +
> +	clk_bulk_disable_unprepare(cam_dev->num_clks, cam_dev->clks);
> +
> +	return 0;
> +}
> +
> +static int mtk_camsv30_runtime_resume(struct device *dev)
> +{
> +	struct mtk_cam_dev *cam_dev = dev_get_drvdata(dev);
> +	struct mtk_cam_video_device *vdev = &cam_dev->vdev;
> +	const struct v4l2_pix_format_mplane *fmt = &vdev->format;
> +	struct vb2_queue *vbq = &vdev->vbq;
> +	struct mtk_cam_dev_buffer *buf, *buf_prev;
> +	int ret;
> +	unsigned long flags = 0;
> +
> +	ret = clk_bulk_prepare_enable(cam_dev->num_clks, cam_dev->clks);
> +	if (ret) {
> +		dev_err(dev, "failed to enable clock:%d\n", ret);
> +		return ret;
> +	}
> +
> +	if (vb2_is_streaming(vbq)) {
> +
> +		mtk_camsv30_setup(cam_dev, fmt->width, fmt->height,
> +				  fmt->plane_fmt[0].bytesperline, vdev->fmtinfo->code);
> +
> +		spin_lock_irqsave(&cam_dev->irqlock, flags);
> +		buf = list_first_entry_or_null(&cam_dev->buf_list,
> +					       struct mtk_cam_dev_buffer,
> +					       list);
> +		if (buf) {
> +			mtk_camsv30_update_buffers_add(cam_dev, buf);
> +			cam_dev->is_dummy_used = false;
> +		} else {
> +			mtk_camsv30_update_buffers_add(cam_dev, &cam_dev->dummy);
> +			cam_dev->is_dummy_used = true;
> +		}
> +
> +		mtk_camsv30_cmos_vf_hw_enable(cam_dev, vdev->fmtinfo->packed);
> +
> +		spin_unlock_irqrestore(&cam_dev->irqlock, flags);
> +
> +		/* Stream on the sub-device */
> +		mutex_lock(&cam_dev->op_lock);
> +		ret = v4l2_subdev_call(&cam_dev->subdev, video, s_stream, 1);
> +
> +		if (ret) {
> +			cam_dev->stream_count--;
> +			if (cam_dev->stream_count == 0)
> +				media_pipeline_stop(vdev->vdev.entity.pads);
> +		}
> +		mutex_unlock(&cam_dev->op_lock);
> +
> +		if (ret)
> +			goto fail_no_stream;
> +	}
> +
> +	return 0;
> +
> +fail_no_stream:
> +	spin_lock_irqsave(&cam_dev->irqlock, flags);
> +	list_for_each_entry_safe(buf, buf_prev, &cam_dev->buf_list, list) {
> +		buf->daddr = 0ULL;
> +		list_del(&buf->list);
> +		vb2_buffer_done(&buf->v4l2_buf.vb2_buf, VB2_BUF_STATE_ERROR);
> +	}
> +	spin_unlock_irqrestore(&cam_dev->irqlock, flags);
> +	return ret;
> +}
> +
> +static struct mtk_cam_hw_functions mtk_camsv30_hw_functions = {

const.

> +	.mtk_cam_setup = mtk_camsv30_setup,
> +	.mtk_cam_update_buffers_add = mtk_camsv30_update_buffers_add,
> +	.mtk_cam_cmos_vf_hw_enable = mtk_camsv30_cmos_vf_hw_enable,
> +	.mtk_cam_cmos_vf_hw_disable = mtk_camsv30_cmos_vf_hw_disable,
> +};
> +
> +static int mtk_camsv30_probe(struct platform_device *pdev)
> +{
> +	static const char * const clk_names[] = { "cam", "camtg", "camsv"};
> +
> +	struct mtk_cam_dev *cam_dev;
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +	int i;
> +
> +	if (!iommu_present(&platform_bus_type))
> +		return -EPROBE_DEFER;
> +
> +	cam_dev = devm_kzalloc(dev, sizeof(*cam_dev), GFP_KERNEL);
> +	if (!cam_dev)
> +		return -ENOMEM;
> +
> +	cam_dev->conf = of_device_get_match_data(dev);
> +	if (!cam_dev->conf)
> +		return -ENODEV;
> +
> +	cam_dev->dev = dev;
> +	dev_set_drvdata(dev, cam_dev);
> +
> +	cam_dev->regs = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(cam_dev->regs))
> +		return dev_err_probe(dev, PTR_ERR(cam_dev->regs),
> +				"failed to map register base\n");
> +
> +
> +	cam_dev->regs_img0 = devm_platform_ioremap_resource(pdev, 1);
> +
> +	if (IS_ERR(cam_dev->regs_img0))
> +		return dev_err_probe(dev, PTR_ERR(cam_dev->regs_img0),
> +				"failed to map img0 register base\n");
> +
> +
> +	cam_dev->regs_tg = devm_platform_ioremap_resource(pdev, 2);
> +	if (IS_ERR(cam_dev->regs_tg))
> +		return dev_err_probe(dev, PTR_ERR(cam_dev->regs_tg),
> +				"failed to map TG register base\n");
> +
> +
> +	cam_dev->num_clks = ARRAY_SIZE(clk_names);
> +	cam_dev->clks = devm_kcalloc(dev, cam_dev->num_clks,
> +				     sizeof(*cam_dev->clks), GFP_KERNEL);
> +	if (!cam_dev->clks)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < cam_dev->num_clks; ++i)
> +		cam_dev->clks[i].id = clk_names[i];
> +
> +	ret = devm_clk_bulk_get(dev, cam_dev->num_clks, cam_dev->clks);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "failed to get clocks: %i\n", ret);
> +
> +
> +	cam_dev->irq = platform_get_irq(pdev, 0);
> +	ret = devm_request_irq(dev, cam_dev->irq,
> +			       isp_irq_camsv30, 0,
> +			       dev_name(dev), cam_dev);

Fits on fewer lines.

> +	if (ret != 0)
> +		return dev_err_probe(dev, -ENODEV, "failed to request irq=%d\n",
> +				cam_dev->irq);

Alignment.

> +
> +	cam_dev->hw_functions = &mtk_camsv30_hw_functions;
> +
> +	spin_lock_init(&cam_dev->irqlock);
> +
> +	/* initialise runtime power management */
> +	pm_runtime_set_autosuspend_delay(dev, MTK_CAMSV30_AUTOSUSPEND_DELAY_MS);
> +	pm_runtime_use_autosuspend(dev);
> +	pm_runtime_set_suspended(dev);
> +	pm_runtime_enable(dev);
> +
> +	/* Initialize the v4l2 common part */
> +	return mtk_cam_dev_init(cam_dev);
> +}
> +
> +static int mtk_camsv30_remove(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_cam_dev *cam_dev = dev_get_drvdata(dev);
> +
> +	mtk_cam_dev_cleanup(cam_dev);
> +	pm_runtime_put_autosuspend(dev);
> +	pm_runtime_disable(dev);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops mtk_camsv30_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +				pm_runtime_force_resume)
> +	SET_RUNTIME_PM_OPS(mtk_camsv30_runtime_suspend,
> +			   mtk_camsv30_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id mtk_camsv30_of_ids[] = {
> +	{ .compatible = "mediatek,mt8365-camsv", .data = &camsv30_conf },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_camsv30_of_ids);
> +
> +static struct platform_driver mtk_camsv30_driver = {
> +	.probe = mtk_camsv30_probe,
> +	.remove = mtk_camsv30_remove,
> +	.driver = {
> +		.name = "mtk-camsv-isp30",
> +		.of_match_table = mtk_camsv30_of_ids,
> +		.pm = &mtk_camsv30_pm_ops,
> +	}
> +};
> +
> +module_platform_driver(mtk_camsv30_driver);
> +
> +MODULE_DESCRIPTION("MediaTek CAMSV ISP3.0 driver");
> +MODULE_AUTHOR("Florian Sylvestre <fsylvestre at baylibre.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv30_regs.h b/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv30_regs.h
> new file mode 100644
> index 000000000000..6d30087270cc
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv30_regs.h
> @@ -0,0 +1,60 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2022 MediaTek Inc.
> + */
> +
> +#ifndef __MTK_CAMSV30_REGS_H__
> +#define __MTK_CAMSV30_REGS_H__
> +
> +/* CAMSV */
> +#define CAMSV_MODULE_EN				0x0000
> +#define CAMSV_MODULE_EN_IMGO_EN			BIT(4)
> +#define CAMSV_FMT_SEL				0x0004
> +#define CAMSV_INT_EN				0x0008
> +#define CAMSV_INT_STATUS			0x000c
> +#define CAMSV_SW_CTL				0x0010
> +#define CAMSV_IMGO_FBC				0x001C
> +#define CAMSV_CLK_EN				0x0020
> +#define CAMSV_PAK				0x003c
> +
> +/* CAMSV_TG */
> +#define CAMSV_TG_SEN_MODE			0x0010
> +#define CAMSV_TG_VF_CON				0x0014
> +#define CAMSV_TG_SEN_GRAB_PXL			0x0018
> +#define CAMSV_TG_SEN_GRAB_LIN			0x001c
> +#define CAMSV_TG_PATH_CFG			0x0020
> +
> +/* CAMSV_IMG0 */
> +#define CAMSV_IMGO_SV_BASE_ADDR			0x0000
> +#define CAMSV_IMGO_SV_XSIZE			0x0008
> +#define CAMSV_IMGO_SV_YSIZE			0x000c
> +#define CAMSV_IMGO_SV_STRIDE			0x0010
> +#define CAMSV_IMGO_SV_CON			0x0014
> +#define CAMSV_IMGO_SV_CON2			0x0018
> +
> +#define CAMSV_TG_SEN_MODE_CMOS_EN		BIT(0)
> +#define CAMSV_TG_VF_CON_VFDATA_EN		BIT(0)
> +
> +/* CAMSV_CLK_EN bits */
> +#define CAMSV_TG_DP_CLK_EN			BIT(0)
> +#define CAMSV_PAK_DP_CLK_EN			BIT(2)
> +#define CAMSV_DMA_DP_CLK_EN			BIT(15)
> +
> +/* CAMSV_SW_CTL bits */
> +#define CAMSV_IMGO_RST_TRIG			BIT(0)
> +#define CAMSV_IMGO_RST_ST			BIT(1)
> +#define CAMSV_SW_RST				BIT(2)
> +
> +/* IRQ BITS */
> +#define CAMSV_IRQ_TG_ERR			BIT(4)
> +#define CAMSV_IRQ_TG_GBERR			BIT(5)
> +#define CAMSV_IRQ_PASS1_DON			BIT(10)
> +#define CAMSV_IRQ_IMGO_ERR			BIT(16)
> +
> +#define INT_ST_MASK_CAMSV                                                      \
> +	(CAMSV_IRQ_PASS1_DON)
> +
> +#define INT_ST_MASK_CAMSV_ERR                                                  \
> +	(CAMSV_IRQ_TG_ERR | CAMSV_IRQ_TG_GBERR | CAMSV_IRQ_IMGO_ERR)
> +
> +#endif /* __MTK_CAMSV30_REGS_H__ */
> diff --git a/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv_video.c b/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv_video.c
> new file mode 100644
> index 000000000000..2ea474eabb99
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_30/camsv/mtk_camsv_video.c
> @@ -0,0 +1,774 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * mtk_camsv_video.c - V4L2 video node support
> + *
> + * Copyright (c) 2020 BayLibre
> + * Copyright (c) 2022 MediaTek Inc.
> + */
> +
> +#include <linux/version.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-event.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/v4l2-mediabus.h>
> +
> +#include "mtk_camsv.h"
> +
> +static inline struct mtk_cam_video_device *
> +file_to_mtk_cam_video_device(struct file *__file)
> +{
> +	return container_of(video_devdata(__file),
> +			    struct mtk_cam_video_device, vdev);
> +}
> +
> +static inline struct mtk_cam_video_device *
> +vb2_queue_to_mtk_cam_video_device(struct vb2_queue *vq)
> +{
> +	return container_of(vq, struct mtk_cam_video_device, vbq);
> +}
> +
> +static inline struct mtk_cam_dev_buffer *
> +to_mtk_cam_dev_buffer(struct vb2_buffer *buf)
> +{
> +	return container_of(buf, struct mtk_cam_dev_buffer, v4l2_buf.vb2_buf);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Format Information
> + */
> +
> +static const struct mtk_cam_format_info mtk_cam_format_info[] = {
> +	{
> +		.fourcc = V4L2_PIX_FMT_SBGGR8,
> +		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
> +		.packed = true,
> +		.bpp = 8,
> +	}, {
> +		.fourcc = V4L2_PIX_FMT_SGBRG8,
> +		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
> +		.packed = true,
> +		.bpp = 8,
> +	}, {
> +		.fourcc = V4L2_PIX_FMT_SGRBG8,
> +		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
> +		.packed = true,
> +		.bpp = 8,
> +	}, {
> +		.fourcc = V4L2_PIX_FMT_SRGGB8,
> +		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
> +		.packed = true,
> +		.bpp = 8,
> +	}, {
> +		.fourcc = V4L2_PIX_FMT_YUYV,
> +		.code = MEDIA_BUS_FMT_YUYV8_1X16,
> +		.packed = true,
> +		.bpp = 16,
> +	}, {
> +		.fourcc = V4L2_PIX_FMT_YVYU,
> +		.code = MEDIA_BUS_FMT_YVYU8_1X16,
> +		.packed = true,
> +		.bpp = 16,
> +	}, {
> +		.fourcc = V4L2_PIX_FMT_UYVY,
> +		.code = MEDIA_BUS_FMT_UYVY8_1X16,
> +		.packed = true,
> +		.bpp = 16,
> +	}, {
> +		.fourcc = V4L2_PIX_FMT_VYUY,
> +		.code = MEDIA_BUS_FMT_VYUY8_1X16,
> +		.packed = true,
> +		.bpp = 16,
> +	},
> +};
> +
> +static const struct mtk_cam_format_info *
> +mtk_cam_format_info_by_fourcc(u32 fourcc)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(mtk_cam_format_info); ++i) {
> +		const struct mtk_cam_format_info *info =
> +			&mtk_cam_format_info[i];
> +
> +		if (info->fourcc == fourcc)
> +			return info;
> +	}
> +
> +	return NULL;
> +}
> +
> +static const struct mtk_cam_format_info *
> +mtk_cam_format_info_by_code(u32 code)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(mtk_cam_format_info); ++i) {
> +		const struct mtk_cam_format_info *info =
> +			&mtk_cam_format_info[i];
> +
> +		if (info->code == code)
> +			return info;
> +	}
> +
> +	return NULL;
> +}
> +
> +static bool mtk_cam_dev_find_fmt(const struct mtk_cam_vdev_desc *desc,
> +				 u32 format)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < desc->num_fmts; i++) {
> +		if (desc->fmts[i] == format)
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
> +static void calc_bpl_size_pix_mp(const struct mtk_cam_format_info *fmtinfo,
> +				 struct v4l2_pix_format_mplane *pix_mp)
> +{
> +	unsigned int bpl;
> +	unsigned int i;
> +
> +	bpl = ALIGN(DIV_ROUND_UP(pix_mp->width * fmtinfo->bpp, 8), 2);
> +
> +	for (i = 0; i < pix_mp->num_planes; ++i) {
> +		pix_mp->plane_fmt[i].bytesperline = bpl;
> +		pix_mp->plane_fmt[i].sizeimage = bpl * pix_mp->height;
> +	}
> +}
> +
> +static void mtk_cam_dev_load_default_fmt(struct mtk_cam_dev *cam)
> +{
> +	struct mtk_cam_video_device *vdev = &cam->vdev;
> +	struct v4l2_pix_format_mplane *fmt = &vdev->format;
> +
> +	fmt->num_planes = 1;
> +	fmt->pixelformat = vdev->desc->fmts[0];
> +	fmt->width = vdev->desc->def_width;
> +	fmt->height = vdev->desc->def_height;
> +
> +	fmt->colorspace = V4L2_COLORSPACE_SRGB;
> +	fmt->field = V4L2_FIELD_NONE;
> +	fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> +	fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
> +	fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
> +
> +	vdev->fmtinfo = mtk_cam_format_info_by_fourcc(fmt->pixelformat);
> +
> +	calc_bpl_size_pix_mp(vdev->fmtinfo, fmt);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * VB2 Queue Operations
> + */
> +
> +static int mtk_cam_vb2_queue_setup(struct vb2_queue *vq,
> +				   unsigned int *num_buffers,
> +				   unsigned int *num_planes,
> +				   unsigned int sizes[],
> +				   struct device *alloc_devs[])
> +{
> +	struct mtk_cam_video_device *vdev =
> +		vb2_queue_to_mtk_cam_video_device(vq);
> +	unsigned int max_buffer_count = vdev->desc->max_buf_count;
> +	const struct v4l2_pix_format_mplane *fmt = &vdev->format;
> +	unsigned int size;
> +	unsigned int np_conf;
> +	unsigned int i;
> +
> +	/* Check the limitation of buffer size */
> +	if (max_buffer_count)
> +		*num_buffers = clamp_val(*num_buffers, 1, max_buffer_count);
> +
> +	size = fmt->plane_fmt[0].sizeimage;
> +	/* Add for q.create_bufs with fmt.g_sizeimage(p) / 2 test */
> +
> +	np_conf = 1;
> +
> +	if (*num_planes == 0) {
> +		*num_planes = np_conf;
> +		for (i = 0; i < *num_planes; ++i)
> +			sizes[i] = size;
> +	} else if (*num_planes != np_conf || sizes[0] < size) {
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_vb2_buf_init(struct vb2_buffer *vb)
> +{
> +	struct mtk_cam_dev_buffer *buf = to_mtk_cam_dev_buffer(vb);
> +
> +	buf->daddr = 0ULL;
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_vb2_buf_prepare(struct vb2_buffer *vb)
> +{
> +	struct mtk_cam_video_device *vdev =
> +		vb2_queue_to_mtk_cam_video_device(vb->vb2_queue);
> +	struct mtk_cam_dev *cam = vb2_get_drv_priv(vb->vb2_queue);
> +	struct mtk_cam_dev_buffer *buf = to_mtk_cam_dev_buffer(vb);
> +	const struct v4l2_pix_format_mplane *fmt = &vdev->format;
> +	u32 size;
> +	int i;
> +
> +	for (i = 0; i < vb->num_planes; i++) {
> +		size = fmt->plane_fmt[i].sizeimage;
> +		if (vb2_plane_size(vb, i) < size) {
> +			dev_err(cam->dev, "plane size is too small:%lu<%u\n",
> +				vb2_plane_size(vb, i), size);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	buf->v4l2_buf.field = V4L2_FIELD_NONE;
> +
> +	for (i = 0; i < vb->num_planes; i++) {
> +		size = fmt->plane_fmt[i].sizeimage;
> +		vb2_set_plane_payload(vb, i, size);
> +	}
> +
> +	if (buf->daddr == 0ULL)

	if (!buf->daddr)

> +		buf->daddr = vb2_dma_contig_plane_dma_addr(vb, 0);
> +
> +	return 0;
> +}
> +
> +static void mtk_cam_vb2_buf_queue(struct vb2_buffer *vb)
> +{
> +	struct mtk_cam_dev *cam = vb2_get_drv_priv(vb->vb2_queue);
> +	struct mtk_cam_dev_buffer *buf = to_mtk_cam_dev_buffer(vb);
> +	unsigned long flags = 0;
> +
> +	/* added the buffer into the tracking list */
> +	spin_lock_irqsave(&cam->irqlock, flags);
> +	list_add_tail(&buf->list, &cam->buf_list);
> +	spin_unlock_irqrestore(&cam->irqlock, flags);
> +}
> +
> +static void mtk_cam_vb2_return_all_buffers(struct mtk_cam_dev *cam,
> +					   enum vb2_buffer_state state)
> +{
> +	struct mtk_cam_dev_buffer *buf, *buf_prev;
> +	unsigned long flags = 0;
> +
> +	spin_lock_irqsave(&cam->irqlock, flags);
> +	list_for_each_entry_safe(buf, buf_prev, &cam->buf_list, list) {
> +		buf->daddr = 0ULL;
> +		list_del(&buf->list);
> +		vb2_buffer_done(&buf->v4l2_buf.vb2_buf, state);
> +	}
> +	spin_unlock_irqrestore(&cam->irqlock, flags);
> +}
> +
> +static void mtk_cam_cmos_vf_enable(struct mtk_cam_dev *cam_dev,
> +				   bool enable, bool pak_en)
> +{
> +	struct device *dev = cam_dev->dev;
> +	unsigned long flags = 0;

No need to initialise flags. Same elsewhere.

> +
> +	if (pm_runtime_get_sync(dev) < 0) {
> +		dev_err(dev, "failed to get pm_runtime\n");
> +		goto out;
> +	}
> +
> +	spin_lock_irqsave(&cam_dev->irqlock, flags);
> +	if (enable)
> +		(*cam_dev->hw_functions->mtk_cam_cmos_vf_hw_enable)(cam_dev, pak_en);
> +	else
> +		(*cam_dev->hw_functions->mtk_cam_cmos_vf_hw_disable)(cam_dev, pak_en);

cam_dev->...(...);

> +	spin_unlock_irqrestore(&cam_dev->irqlock, flags);
> +
> +out:
> +	pm_runtime_put_autosuspend(dev);
> +}
> +
> +static int mtk_cam_verify_format(struct mtk_cam_dev *cam)
> +{
> +	struct mtk_cam_video_device *vdev = &cam->vdev;
> +	struct v4l2_subdev_format fmt = {
> +		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
> +		.pad = MTK_CAM_CIO_PAD_VIDEO,
> +	};
> +	int ret;
> +
> +	ret = v4l2_subdev_call(&cam->subdev, pad, get_fmt, NULL, &fmt);
> +	if (ret < 0)
> +		return ret == -ENOIOCTLCMD ? -EINVAL : ret;
> +
> +	if (vdev->fmtinfo->code != fmt.format.code ||
> +	    vdev->format.height != fmt.format.height ||
> +	    vdev->format.width != fmt.format.width)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_vb2_start_streaming(struct vb2_queue *vq,
> +				       unsigned int count)
> +{
> +	struct mtk_cam_dev *cam = vb2_get_drv_priv(vq);
> +	struct mtk_cam_dev_buffer *buf;
> +	struct mtk_cam_video_device *vdev =
> +		vb2_queue_to_mtk_cam_video_device(vq);
> +	struct device *dev = cam->dev;
> +	const struct v4l2_pix_format_mplane *fmt = &vdev->format;
> +	int ret;
> +	unsigned long flags = 0;
> +
> +	if (pm_runtime_get_sync(dev) < 0) {
> +		dev_err(dev, "failed to get pm_runtime\n");
> +		pm_runtime_put_autosuspend(dev);
> +		return -1;
> +	}
> +
> +	(*cam->hw_functions->mtk_cam_setup)(cam, fmt->width, fmt->height,
> +			fmt->plane_fmt[0].bytesperline, vdev->fmtinfo->code);
> +
> +
> +	/* Enable CMOS and VF */
> +	mtk_cam_cmos_vf_enable(cam, true, vdev->fmtinfo->packed);
> +
> +	mutex_lock(&cam->op_lock);
> +
> +	ret = mtk_cam_verify_format(cam);

This should be called via the link_validate callback instead.

> +	if (ret < 0)
> +		goto fail_unlock;
> +
> +	/* Start streaming of the whole pipeline now*/
> +	if (!cam->pipeline.start_count) {
> +		ret = media_pipeline_start(vdev->vdev.entity.pads,
> +					   &cam->pipeline);
> +		if (ret) {
> +			dev_err(dev, "failed to start pipeline:%d\n", ret);
> +			goto fail_unlock;
> +		}
> +	}
> +
> +	/* Media links are fixed after media_pipeline_start */
> +	cam->stream_count++;
> +
> +	cam->sequence = (unsigned int)-1;
> +
> +	/* Stream on the sub-device */
> +	ret = v4l2_subdev_call(&cam->subdev, video, s_stream, 1);
> +	if (ret)
> +		goto fail_no_stream;
> +
> +	mutex_unlock(&cam->op_lock);
> +
> +	/* Create dummy buffer */
> +	cam->dummy_size = fmt->plane_fmt[0].sizeimage;
> +
> +	cam->dummy.vaddr = dma_alloc_coherent(cam->dev, cam->dummy_size,
> +					      &cam->dummy.daddr, GFP_KERNEL);
> +	if (!cam->dummy.vaddr) {
> +		ret = -ENOMEM;
> +		goto fail_no_buffer;
> +	}
> +
> +	/* update first buffer address */
> +
> +	/* added the buffer into the tracking list */
> +	spin_lock_irqsave(&cam->irqlock, flags);
> +	if (list_empty(&cam->buf_list)) {
> +		(*cam->hw_functions->mtk_cam_update_buffers_add)(cam, &cam->dummy);
> +		cam->is_dummy_used = true;
> +	} else {
> +		buf = list_first_entry_or_null(&cam->buf_list,
> +					       struct mtk_cam_dev_buffer,
> +					       list);
> +		(*cam->hw_functions->mtk_cam_update_buffers_add)(cam, buf);
> +		cam->is_dummy_used = false;
> +	}
> +	spin_unlock_irqrestore(&cam->irqlock, flags);
> +
> +	return 0;
> +
> +fail_no_buffer:
> +	mutex_lock(&cam->op_lock);
> +	v4l2_subdev_call(&cam->subdev, video, s_stream, 0);
> +fail_no_stream:
> +	cam->stream_count--;
> +	if (cam->stream_count == 0)
> +		media_pipeline_stop(vdev->vdev.entity.pads);
> +fail_unlock:
> +	mutex_unlock(&cam->op_lock);
> +	mtk_cam_vb2_return_all_buffers(cam, VB2_BUF_STATE_QUEUED);
> +
> +	return ret;
> +}
> +
> +static void mtk_cam_vb2_stop_streaming(struct vb2_queue *vq)
> +{
> +	struct mtk_cam_dev *cam = vb2_get_drv_priv(vq);
> +	struct mtk_cam_video_device *vdev =
> +		vb2_queue_to_mtk_cam_video_device(vq);
> +
> +	/* Disable CMOS and VF */
> +	mtk_cam_cmos_vf_enable(cam, false, false);
> +
> +	mutex_lock(&cam->op_lock);
> +
> +	v4l2_subdev_call(&cam->subdev, video, s_stream, 0);
> +
> +	mtk_cam_vb2_return_all_buffers(cam, VB2_BUF_STATE_ERROR);
> +	cam->stream_count--;
> +	if (cam->stream_count) {
> +		mutex_unlock(&cam->op_lock);
> +		return;
> +	}
> +
> +	/* Destroy dummy buffer */
> +	if (cam->dummy.vaddr) {
> +		dma_free_coherent(cam->dev, cam->dummy_size, cam->dummy.vaddr,
> +				  cam->dummy.daddr);
> +		memset(&cam->dummy, 0, sizeof(cam->dummy));
> +		cam->dummy_size = 0;
> +		cam->is_dummy_used = false;
> +	}
> +
> +	mutex_unlock(&cam->op_lock);
> +
> +	media_pipeline_stop(vdev->vdev.entity.pads);
> +}
> +
> +static const struct vb2_ops mtk_cam_vb2_ops = {
> +	.queue_setup = mtk_cam_vb2_queue_setup,
> +	.buf_init = mtk_cam_vb2_buf_init,
> +	.buf_prepare = mtk_cam_vb2_buf_prepare,
> +	.buf_queue = mtk_cam_vb2_buf_queue,
> +	.start_streaming = mtk_cam_vb2_start_streaming,
> +	.stop_streaming = mtk_cam_vb2_stop_streaming,
> +	.wait_prepare = vb2_ops_wait_prepare,
> +	.wait_finish = vb2_ops_wait_finish,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Video IOCTLs
> + */
> +
> +static int mtk_cam_vidioc_querycap(struct file *file, void *fh,
> +				   struct v4l2_capability *cap)
> +{
> +	struct mtk_cam_dev *cam = video_drvdata(file);
> +
> +	strscpy(cap->driver, dev_driver_string(cam->dev), sizeof(cap->driver));
> +	strscpy(cap->card, dev_driver_string(cam->dev), sizeof(cap->card));
> +	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
> +		 dev_name(cam->dev));

The bus_info field is set by the V4L2 framework.

> +
> +	/* Minimum v4l2 api kernel version required by libcamera is 5.0.0 */
> +	cap->version = KERNEL_VERSION(5, 0, 0);

Hmm. You can drop this.

> +
> +	return 0;
> +}
> +
> +static int mtk_cam_vidioc_enum_fmt(struct file *file, void *fh,
> +				   struct v4l2_fmtdesc *f)
> +{
> +	struct mtk_cam_video_device *vdev = file_to_mtk_cam_video_device(file);
> +	const struct mtk_cam_format_info *fmtinfo;
> +	unsigned int i;
> +
> +	/* If mbus_code is not set enumerate all supported formats. */
> +	if (!f->mbus_code) {
> +		if (f->index >= vdev->desc->num_fmts)
> +			return -EINVAL;
> +
> +		/* f->description is filled in v4l_fill_fmtdesc function */
> +		f->pixelformat = vdev->desc->fmts[f->index];
> +		f->flags = 0;
> +
> +		return 0;
> +	}
> +
> +	/*
> +	 * Otherwise only enumerate supported pixel formats corresponding to
> +	 * that bus code.
> +	 */
> +	if (f->index)
> +		return -EINVAL;
> +
> +	fmtinfo = mtk_cam_format_info_by_code(f->mbus_code);
> +	if (!fmtinfo)
> +		return -EINVAL;
> +
> +	for (i = 0; i < vdev->desc->num_fmts; ++i) {
> +		if (vdev->desc->fmts[i] == fmtinfo->fourcc) {
> +			f->pixelformat = fmtinfo->fourcc;
> +			f->flags = 0;
> +			return 0;
> +		}
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int mtk_cam_vidioc_g_fmt(struct file *file, void *fh,
> +				struct v4l2_format *f)
> +{
> +	struct mtk_cam_video_device *vdev = file_to_mtk_cam_video_device(file);
> +
> +	f->fmt.pix_mp = vdev->format;
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_vidioc_try_fmt(struct file *file, void *fh,
> +				  struct v4l2_format *f)
> +{
> +	struct mtk_cam_video_device *vdev = file_to_mtk_cam_video_device(file);
> +	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
> +	const struct mtk_cam_format_info *fmtinfo;
> +
> +	/* Validate pixelformat */
> +	if (!mtk_cam_dev_find_fmt(vdev->desc, pix_mp->pixelformat))
> +		pix_mp->pixelformat = vdev->desc->fmts[0];
> +
> +	pix_mp->width = clamp_val(pix_mp->width, IMG_MIN_WIDTH, IMG_MAX_WIDTH);
> +	pix_mp->height = clamp_val(pix_mp->height, IMG_MIN_HEIGHT,
> +				   IMG_MAX_HEIGHT);
> +
> +	pix_mp->num_planes = 1;
> +
> +	fmtinfo = mtk_cam_format_info_by_fourcc(pix_mp->pixelformat);
> +	calc_bpl_size_pix_mp(fmtinfo, pix_mp);
> +
> +	/* Constant format fields */
> +	pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
> +	pix_mp->field = V4L2_FIELD_NONE;
> +	pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> +	pix_mp->quantization = V4L2_QUANTIZATION_DEFAULT;
> +	pix_mp->xfer_func = V4L2_XFER_FUNC_DEFAULT;
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_vidioc_s_fmt(struct file *file, void *fh,
> +				struct v4l2_format *f)
> +{
> +	struct mtk_cam_dev *cam = video_drvdata(file);
> +	struct mtk_cam_video_device *vdev = file_to_mtk_cam_video_device(file);
> +	int ret;
> +
> +	if (vb2_is_busy(vdev->vdev.queue)) {
> +		dev_dbg(cam->dev, "%s: queue is busy\n", __func__);
> +		return -EBUSY;
> +	}
> +
> +	ret = mtk_cam_vidioc_try_fmt(file, fh, f);
> +	if (ret)
> +		return ret;
> +
> +	/* Configure to video device */
> +	vdev->format = f->fmt.pix_mp;
> +	vdev->fmtinfo =
> +		mtk_cam_format_info_by_fourcc(f->fmt.pix_mp.pixelformat);
> +
> +	return 0;
> +}
> +
> +static int mtk_cam_vidioc_enum_framesizes(struct file *file, void *priv,
> +					  struct v4l2_frmsizeenum *sizes)
> +{
> +	struct mtk_cam_video_device *vdev = file_to_mtk_cam_video_device(file);
> +
> +	if (sizes->index)
> +		return -EINVAL;
> +
> +	if (!mtk_cam_dev_find_fmt(vdev->desc, sizes->pixel_format))
> +		return -EINVAL;
> +
> +	sizes->type = vdev->desc->frmsizes->type;
> +	memcpy(&sizes->stepwise, &vdev->desc->frmsizes->stepwise,
> +	       sizeof(sizes->stepwise));
> +
> +	return 0;
> +}
> +
> +static const struct v4l2_ioctl_ops mtk_cam_v4l2_vcap_ioctl_ops = {
> +	.vidioc_querycap = mtk_cam_vidioc_querycap,
> +	.vidioc_enum_framesizes = mtk_cam_vidioc_enum_framesizes,
> +	.vidioc_enum_fmt_vid_cap = mtk_cam_vidioc_enum_fmt,
> +	.vidioc_g_fmt_vid_cap_mplane = mtk_cam_vidioc_g_fmt,
> +	.vidioc_s_fmt_vid_cap_mplane = mtk_cam_vidioc_s_fmt,
> +	.vidioc_try_fmt_vid_cap_mplane = mtk_cam_vidioc_try_fmt,
> +	.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_streamon = vb2_ioctl_streamon,
> +	.vidioc_streamoff = vb2_ioctl_streamoff,
> +	.vidioc_expbuf = vb2_ioctl_expbuf,
> +	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
> +	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
> +};
> +
> +static const struct v4l2_file_operations mtk_cam_v4l2_fops = {
> +	.unlocked_ioctl = video_ioctl2,
> +	.open = v4l2_fh_open,
> +	.release = vb2_fop_release,
> +	.poll = vb2_fop_poll,
> +	.mmap = vb2_fop_mmap,
> +#ifdef CONFIG_COMPAT
> +	.compat_ioctl32 = v4l2_compat_ioctl32,

Do you need this?

> +#endif
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Init & Cleanup
> + */
> +
> +static const u32 stream_out_fmts[] = {
> +	/* The 1st entry is the default image format */
> +	V4L2_PIX_FMT_SBGGR8,
> +	V4L2_PIX_FMT_SGBRG8,
> +	V4L2_PIX_FMT_SGRBG8,
> +	V4L2_PIX_FMT_SRGGB8,
> +	V4L2_PIX_FMT_UYVY,
> +	V4L2_PIX_FMT_VYUY,
> +	V4L2_PIX_FMT_YUYV,
> +	V4L2_PIX_FMT_YVYU,
> +};
> +
> +static const struct mtk_cam_vdev_desc video_stream = {
> +	.name = "video stream",
> +	.cap = V4L2_CAP_VIDEO_CAPTURE_MPLANE,
> +	.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
> +	.link_flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED,
> +	.fmts = stream_out_fmts,
> +	.num_fmts = ARRAY_SIZE(stream_out_fmts),
> +	.def_width = 1920,
> +	.def_height = 1080,

You have macros for these.

> +	.ioctl_ops = &mtk_cam_v4l2_vcap_ioctl_ops,
> +	.frmsizes =
> +		&(struct v4l2_frmsizeenum){
> +			.index = 0,
> +			.type = V4L2_FRMSIZE_TYPE_CONTINUOUS,
> +			.stepwise = {
> +				.max_width = IMG_MAX_WIDTH,
> +				.min_width = IMG_MIN_WIDTH,
> +				.max_height = IMG_MAX_HEIGHT,
> +				.min_height = IMG_MIN_HEIGHT,
> +				.step_height = 1,
> +				.step_width = 1,
> +			},
> +		},
> +};
> +
> +int mtk_cam_video_register(struct mtk_cam_dev *cam)
> +{
> +	struct device *dev = cam->dev;
> +	struct mtk_cam_video_device *cam_vdev = &cam->vdev;
> +	struct video_device *vdev = &cam_vdev->vdev;
> +	struct vb2_queue *vbq = &cam_vdev->vbq;
> +	int ret;
> +
> +	vb2_dma_contig_set_max_seg_size(cam->dev, DMA_BIT_MASK(32));
> +
> +	cam_vdev->desc = &video_stream;
> +
> +	/* Initialize mtk_cam_video_device */
> +	mtk_cam_dev_load_default_fmt(cam);
> +
> +	cam_vdev->vdev_pad.flags = MEDIA_PAD_FL_SOURCE;
> +
> +	/* Initialize media entities */
> +	ret = media_entity_pads_init(&vdev->entity, 1, &cam_vdev->vdev_pad);
> +	if (ret) {
> +		dev_err(dev, "failed to initialize media pad:%d\n", ret);
> +		return ret;
> +	}
> +	cam_vdev->vdev_pad.flags = MEDIA_PAD_FL_SINK;
> +
> +	vbq->type = cam_vdev->desc->buf_type;
> +	vbq->io_modes = VB2_MMAP | VB2_DMABUF;
> +	vbq->dev = dev;
> +	vbq->ops = &mtk_cam_vb2_ops;
> +	vbq->mem_ops = &vb2_dma_contig_memops;
> +	vbq->buf_struct_size = sizeof(struct mtk_cam_dev_buffer);
> +	/*
> +	 * TODO: The hardware supports SOF interrupts, switch to a SOF
> +	 * timestamp source would give better accuracy, but first requires
> +	 * extending the V4L2 API to support it.
> +	 */
> +	vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
> +			     | V4L2_BUF_FLAG_TSTAMP_SRC_EOF;
> +
> +	/* No minimum buffers limitation */
> +	vbq->min_buffers_needed = 0;
> +	vbq->drv_priv = cam;
> +
> +	vbq->lock = &cam_vdev->vdev_lock;
> +	ret = vb2_queue_init(vbq);
> +	if (ret) {
> +		dev_err(dev, "failed to init. vb2 queue:%d\n", ret);
> +		goto fail_media_clean;
> +	}
> +
> +	/* Initialize vdev */
> +	snprintf(vdev->name, sizeof(vdev->name), "%s %s",
> +		 dev_name(dev), cam_vdev->desc->name);
> +
> +	/* Set cap/type/ioctl_ops of the video device */
> +	vdev->device_caps = cam_vdev->desc->cap | V4L2_CAP_STREAMING
> +			  | V4L2_CAP_IO_MC;
> +	vdev->ioctl_ops = cam_vdev->desc->ioctl_ops;
> +	vdev->fops = &mtk_cam_v4l2_fops;
> +	vdev->release = video_device_release_empty;
> +	vdev->lock = &cam_vdev->vdev_lock;
> +	vdev->v4l2_dev = cam->subdev.v4l2_dev;
> +	vdev->queue = &cam_vdev->vbq;
> +	vdev->vfl_dir = VFL_DIR_RX;
> +	vdev->entity.function = MEDIA_ENT_F_IO_V4L;
> +	vdev->entity.ops = NULL;

This was presumably already NULL.

> +	video_set_drvdata(vdev, cam);
> +
> +	/* Initialize miscellaneous variables */
> +	mutex_init(&cam_vdev->vdev_lock);
> +	INIT_LIST_HEAD(&cam->buf_list);
> +
> +	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
> +	if (ret) {
> +		dev_err(dev, "failed to register vde:%d\n", ret);
> +		goto fail_vb2_rel;
> +	}
> +
> +	/* Create link between the video pad and the subdev pad. */
> +	ret = media_create_pad_link(&cam->subdev.entity,
> +				    MTK_CAM_CIO_PAD_VIDEO,
> +				    &vdev->entity, 0, cam_vdev->desc->link_flags);
> +
> +	if (ret)
> +		goto fail_vdev_ureg;
> +
> +	return 0;
> +
> +fail_vdev_ureg:
> +	video_unregister_device(vdev);
> +fail_vb2_rel:
> +	mutex_destroy(&cam_vdev->vdev_lock);
> +	vb2_queue_release(vbq);
> +fail_media_clean:
> +	media_entity_cleanup(&vdev->entity);
> +
> +	return ret;
> +}
> +
> +void mtk_cam_video_unregister(struct mtk_cam_video_device *vdev)
> +{
> +	video_unregister_device(&vdev->vdev);
> +	vb2_queue_release(&vdev->vbq);
> +	media_entity_cleanup(&vdev->vdev.entity);
> +	mutex_destroy(&vdev->vdev_lock);
> +	vb2_dma_contig_clear_max_seg_size(&vdev->vdev.dev);
> +}

-- 
Kind regards,

Sakari Ailus


From devarsht at ti.com  Thu Feb 15 03:55:16 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Thu, 15 Feb 2024 17:25:16 +0530
Subject: [PATCH v4 2/2] arm64: dts: ti: Add common1 register space for AM62x, AM62A & AM65x SoCs
In-Reply-To: <20240215115516.3157909-1-devarsht@ti.com>
References: <20240215115516.3157909-1-devarsht@ti.com>
Message-ID: <20240215115516.3157909-3-devarsht@ti.com>

This adds common1 register space for AM62x, AM62A and AM65x SoC's which are
using TI's Keystone display hardware and supporting it as described in
Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml

Fixes: 3618811657b3 ("arm64: dts: ti: k3-am62a-main: Add node for Display SubSystem (DSS)")
Fixes: 8ccc1073c7bb ("arm64: dts: ti: k3-am62-main: Add node for DSS")
Fixes: fc539b90eda2 ("arm64: dts: ti: am654: Add DSS node")
Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
Reviewed-by: Aradhya Bhatia <a-bhatia1 at ti.com>
---
V2: Add common1 region for AM62A SoC too
V3: Add Fixes tag
V4: Add Reviewed-by
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi  | 5 +++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 5 +++--
 arch/arm64/boot/dts/ti/k3-am65-main.dtsi  | 5 +++--
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index fe0cc4a9a501..8cee4d94cdd3 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -779,9 +779,10 @@ dss: dss at 30200000 {
 		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
 		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
 		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
-		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			    "ovr1", "ovr2", "vp1", "vp2";
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
 		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 186 6>,
 			 <&dss_vp1_clk>,
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 972971159a62..f475daea548e 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -994,9 +994,10 @@ dss: dss at 30200000 {
 		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
 		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
 		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Tied OFF in the SoC */
-		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			    "ovr1", "ovr2", "vp1", "vp2";
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
 		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 186 6>,
 			 <&k3_clks 186 0>,
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index 07010d31350e..ff857117d719 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -991,9 +991,10 @@ dss: dss at 4a00000 {
 		      <0x0 0x04a07000 0x0 0x1000>, /* ovr1 */
 		      <0x0 0x04a08000 0x0 0x1000>, /* ovr2 */
 		      <0x0 0x04a0a000 0x0 0x1000>, /* vp1 */
-		      <0x0 0x04a0b000 0x0 0x1000>; /* vp2 */
+		      <0x0 0x04a0b000 0x0 0x1000>, /* vp2 */
+		      <0x0 0x04a01000 0x0 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			"ovr1", "ovr2", "vp1", "vp2";
+			"ovr1", "ovr2", "vp1", "vp2", "common1";
 
 		ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
 
-- 
2.34.1



From devarsht at ti.com  Thu Feb 15 03:55:15 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Thu, 15 Feb 2024 17:25:15 +0530
Subject: [PATCH v4 1/2] dt-bindings: display: ti,am65x-dss: Add support for common1 region
In-Reply-To: <20240215115516.3157909-1-devarsht@ti.com>
References: <20240215115516.3157909-1-devarsht@ti.com>
Message-ID: <20240215115516.3157909-2-devarsht@ti.com>

TI keystone display subsystem present in AM65 and other SoCs such as AM62
support two separate register spaces namely "common" and "common1" which
can be used by two separate hosts to program the display controller as
described in respective Technical Reference Manuals [1].

The common1 register space has similar set of configuration registers as
supported in common register space except the global configuration
registers which are exclusive to common region.

This adds binding for "common1" register region too as supported by the
hardware.

[1]:
AM62x TRM:
https://www.ti.com/lit/pdf/spruiv7 (Section 14.8.9.1 DSS Registers)

AM65x TRM:
https://www.ti.com/lit/pdf/spruid7 (Section 12.6.5 DSS Registers)

AM62A TRM:
https://www.ti.com/lit/pdf/spruj16 (Section 14.9.9 Display Subsystem Registers)

Fixes: 2d8730f1021f ("dt-bindings: display: ti,am65x-dss: Add dt-schema yaml binding")
Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
Reviewed-by: Aradhya Bhatia <a-bhatia1 at ti.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
V2: Add Acked-by tag
V3: Add Fixes tag
V4: Add Reviewed-by and AM62A TRM link
---
 .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
index b6767ef0d24d..55e3e490d0e6 100644
--- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
+++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
@@ -37,6 +37,7 @@ properties:
       - description: OVR2 overlay manager for vp2
       - description: VP1 video port 1
       - description: VP2 video port 2
+      - description: common1 DSS register area
 
   reg-names:
     items:
@@ -47,6 +48,7 @@ properties:
       - const: ovr2
       - const: vp1
       - const: vp2
+      - const: common1
 
   clocks:
     items:
@@ -147,9 +149,10 @@ examples:
                     <0x04a07000 0x1000>, /* ovr1 */
                     <0x04a08000 0x1000>, /* ovr2 */
                     <0x04a0a000 0x1000>, /* vp1 */
-                    <0x04a0b000 0x1000>; /* vp2 */
+                    <0x04a0b000 0x1000>, /* vp2 */
+                    <0x04a01000 0x1000>; /* common1 */
             reg-names = "common", "vidl1", "vid",
-                    "ovr1", "ovr2", "vp1", "vp2";
+                    "ovr1", "ovr2", "vp1", "vp2", "common1";
             ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
             power-domains = <&k3_pds 67 TI_SCI_PD_EXCLUSIVE>;
             clocks =        <&k3_clks 67 1>,
-- 
2.34.1



From maz at kernel.org  Thu Feb 15 03:57:41 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 15 Feb 2024 11:57:41 +0000
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <87bk8ig6t2.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
	<CAK9=C2Vwtj2gZg-P73yLMxu0rPXQ3YrRRuxq6HcpHMXgs-jHaw@mail.gmail.com>
	<87bk8ig6t2.ffs@tglx>
Message-ID: <86mss23poq.wl-maz@kernel.org>

On Wed, 14 Feb 2024 19:54:49 +0000,
Thomas Gleixner <tglx at linutronix.de> wrote:
> 
> Anup!
> 
> On Sat, Jan 27 2024 at 21:50, Anup Patel wrote:
> >> Changes since v11:
> >>  - Rebased on Linux-6.8-rc1
> >>  - Included kernel/irq related patches from "genirq, irqchip: Convert ARM
> >>    MSI handling to per device MSI domains" series by Thomas.
> >>    (PATCH7, PATCH8, PATCH9, PATCH14, PATCH16, PATCH17, PATCH18, PATCH19,
> >>     PATCH20, PATCH21, PATCH22, PATCH23, and PATCH32 of
> >>     https://lore.kernel.org/linux-arm-kernel/20221121135653.208611233 at linutronix.de/)
> >>  - Updated APLIC MSI-mode driver to use the new WIRED_TO_MSI mechanism.
> >>  - Updated IMSIC driver to support per-device MSI domains for PCI and
> >>    platform devices.
> >
> > I have rebased and included 13 patches (which add per-device MSI domain
> > infrastructure) from your series [1]. In this series, the IMSIC driver
> > implements the msi_parent_ops and APLIC driver implements wired-to-msi
> > bridge using your new infrastructure.
> >
> > The remaining 27 patches of your series [1] requires testing on ARM
> > platforms which I don't have. I suggest these remaining patches to
> > go as separate series.
> 
> Of course. Darwi (in Cc) is going to work on the ARM parts when he
> returns from vacation. I'm going to apply the infrastructure patches
> (1-13) in the next days so they are out of the way for you and Darwi,
> unless someone has any objections.

FWIW, I've fiven the first 13 patches a go on two of the most
problematic platforms (Huawei's D05, and Marvell's McBin). Nothing
immediately broke, so it's obviously perfect.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From ryan.roberts at arm.com  Thu Feb 15 04:17:52 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 12:17:52 +0000
Subject: [RFC PATCH v1 0/4] Reduce cost of ptep_get_lockless on arm64
Message-ID: <20240215121756.2734131-1-ryan.roberts@arm.com>

This is an RFC for a series that aims to reduce the cost and complexity of
ptep_get_lockless() for arm64 when supporting transparent contpte mappings [1].
The approach came from discussion with Mark and David [2].

It introduces a new helper, ptep_get_lockless_norecency(), which allows the
access and dirty bits in the returned pte to be incorrect. This relaxation
permits arm64's implementation to just read the single target pte, and avoids
having to iterate over the full contpte block to gather the access and dirty
bits, for the contpte case.

It turns out that none of the call sites using ptep_get_lockless() require
accurate access and dirty bit information, so we can also convert those sites.
Although a couple of places need care (see patches 2 and 3).

Arguably patch 3 is a bit fragile, given the wide accessibility of
vmf->orig_pte. So it might make sense to drop this patch and stick to using
ptep_get_lockless() in the page fault path. I'm keen to hear opinions.

I've chosen the name "recency" because it's shortish and somewhat descriptive,
and is alredy used in a couple of places to mean similar things (see mglru and
damon). I'm open to other names if anyone has better ideas.

If concensus is that this approach is generally acceptable, I intend to create a
series in future to do a similar thing with ptep_get() -> ptep_get_norecency().

---
This series applies on top of [1].

[1] https://lore.kernel.org/linux-mm/20240215103205.2607016-1-ryan.roberts at arm.com/
[2] https://lore.kernel.org/linux-mm/a91cfe1c-289e-4828-8cfc-be34eb69a71b at redhat.com/

Thanks,
Ryan

Ryan Roberts (4):
  mm: Introduce ptep_get_lockless_norecency()
  mm/gup: Use ptep_get_lockless_norecency()
  mm/memory: Use ptep_get_lockless_norecency() for orig_pte
  arm64/mm: Override ptep_get_lockless_norecency()

 arch/arm64/include/asm/pgtable.h |  6 ++++
 include/linux/pgtable.h          | 55 ++++++++++++++++++++++++++++--
 kernel/events/core.c             |  2 +-
 mm/gup.c                         |  7 ++--
 mm/hugetlb.c                     |  2 +-
 mm/khugepaged.c                  |  2 +-
 mm/memory.c                      | 57 ++++++++++++++++++++------------
 mm/swap_state.c                  |  2 +-
 mm/swapfile.c                    |  2 +-
 9 files changed, 102 insertions(+), 33 deletions(-)

--
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 04:17:54 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 12:17:54 +0000
Subject: [RFC PATCH v1 2/4] mm/gup: Use ptep_get_lockless_norecency()
In-Reply-To: <20240215121756.2734131-1-ryan.roberts@arm.com>
References: <20240215121756.2734131-1-ryan.roberts@arm.com>
Message-ID: <20240215121756.2734131-3-ryan.roberts@arm.com>

Gup needs to read ptes locklessly, so it uses ptep_get_lockless().
However, the returned access and dirty bits are unimportant so let's
switch over to ptep_get_lockless_norecency().

The wrinkle is that gup needs to check that the pte hasn't changed once
it has pinned the folio following this model:

    pte = ptep_get_lockless_norecency(ptep)
    ...
    if (!pte_same(pte, ptep_get_lockless(ptep)))
            // RACE!
    ...

And now that pte may not contain correct access and dirty information,
the pte_same() comparison could spuriously fail. So let's introduce a
new pte_same_norecency() helper which will ignore the access and dirty
bits when doing the comparison.

Note that previously, ptep_get() was being used for the comparison; this
is technically incorrect because the PTL is not held. I've also
converted the comparison to use the preferred pmd_same() helper instead
of doing a raw value comparison.

As a side-effect, this new approach removes the possibility of
concurrent read/write to the page causing a spurious fast gup failure,
because the access and dirty bits are no longer used in the comparison.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 include/linux/pgtable.h | 18 ++++++++++++++++++
 mm/gup.c                |  7 ++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 9dd40fdbd825..8123affa8baf 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -936,6 +936,24 @@ static inline int pte_same(pte_t pte_a, pte_t pte_b)
 }
 #endif

+/**
+ * pte_same_norecency - Compare pte_a and pte_b, ignoring young and dirty bits,
+ *			if the ptes are present.
+ *
+ * @pte_a: First pte to compare.
+ * @pte_b: Second pte to compare.
+ *
+ * Returns 1 if the ptes match, else 0.
+ */
+static inline int pte_same_norecency(pte_t pte_a, pte_t pte_b)
+{
+	if (pte_present(pte_a))
+		pte_a = pte_mkold(pte_mkclean(pte_a));
+	if (pte_present(pte_b))
+		pte_b = pte_mkold(pte_mkclean(pte_b));
+	return pte_same(pte_a, pte_b);
+}
+
 #ifndef __HAVE_ARCH_PTE_UNUSED
 /*
  * Some architectures provide facilities to virtualization guests
diff --git a/mm/gup.c b/mm/gup.c
index df83182ec72d..0f96d0a5ec09 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -2576,7 +2576,7 @@ static int gup_pte_range(pmd_t pmd, pmd_t *pmdp, unsigned long addr,
 	if (!ptep)
 		return 0;
 	do {
-		pte_t pte = ptep_get_lockless(ptep);
+		pte_t pte = ptep_get_lockless_norecency(ptep);
 		struct page *page;
 		struct folio *folio;

@@ -2617,8 +2617,9 @@ static int gup_pte_range(pmd_t pmd, pmd_t *pmdp, unsigned long addr,
 			goto pte_unmap;
 		}

-		if (unlikely(pmd_val(pmd) != pmd_val(*pmdp)) ||
-		    unlikely(pte_val(pte) != pte_val(ptep_get(ptep)))) {
+		if (unlikely(!pmd_same(pmd, *pmdp)) ||
+		    unlikely(!pte_same_norecency(pte,
+					ptep_get_lockless_norecency(ptep)))) {
 			gup_put_folio(folio, 1, flags);
 			goto pte_unmap;
 		}
--
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 04:17:53 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 12:17:53 +0000
Subject: [RFC PATCH v1 1/4] mm: Introduce ptep_get_lockless_norecency()
In-Reply-To: <20240215121756.2734131-1-ryan.roberts@arm.com>
References: <20240215121756.2734131-1-ryan.roberts@arm.com>
Message-ID: <20240215121756.2734131-2-ryan.roberts@arm.com>

With the introduction of contpte mapping support for arm64, that
architecture's implementation of ptep_get_lockless() has become very
complex due to the need to gather access and dirty bits from across all
of the ptes in the contpte block. This requires careful implementation
to ensure the returned value is consistent (because its not possible to
read all ptes atomically), but even in the common case when there is no
racing modification, we have to read all ptes, which gives an ~O(n^2)
cost if the core-mm is iterating over a range, and performing a
ptep_get_lockless() on each pte.

Solve this by introducing ptep_get_lockless_norecency(), which does not
make any guarantees about access and dirty bits. Therefore it can simply
read the single target pte.

At the same time, convert all call sites that previously used
ptep_get_lockless() but don't care about access and dirty state.

We may want to do something similar for ptep_get() (i.e.
ptep_get_norecency()) in future; it doesn't suffer from the consistency
problem because the PTL serializes it with any modifications, but does
suffer the same O(n^2) cost.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 include/linux/pgtable.h | 37 ++++++++++++++++++++++++++++++++++---
 kernel/events/core.c    |  2 +-
 mm/hugetlb.c            |  2 +-
 mm/khugepaged.c         |  2 +-
 mm/memory.c             |  2 +-
 mm/swap_state.c         |  2 +-
 mm/swapfile.c           |  2 +-
 7 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index a36cf4e124b0..9dd40fdbd825 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -528,16 +528,47 @@ static inline pmd_t pmdp_get_lockless(pmd_t *pmdp)
 #endif /* CONFIG_PGTABLE_LEVELS > 2 */
 #endif /* CONFIG_GUP_GET_PXX_LOW_HIGH */

-/*
- * We require that the PTE can be read atomically.
- */
 #ifndef ptep_get_lockless
+/**
+ * ptep_get_lockless - Get a pte without holding the page table lock. Young and
+ *                     dirty bits are guaranteed to accurately reflect the state
+ *                     of the pte at the time of the call.
+ * @ptep: Page table pointer for pte to get.
+ *
+ * If young and dirty information is not required, use
+ * ptep_get_lockless_norecency() which can be faster on some architectures.
+ *
+ * May be overridden by the architecture; otherwise, implemented using
+ * ptep_get(), on the assumption that it is atomic.
+ *
+ * Context: Any.
+ */
 static inline pte_t ptep_get_lockless(pte_t *ptep)
 {
 	return ptep_get(ptep);
 }
 #endif

+#ifndef ptep_get_lockless_norecency
+/**
+ * ptep_get_lockless_norecency - Get a pte without holding the page table lock.
+ *				 Young and dirty bits may not be accurate.
+ * @ptep: Page table pointer for pte to get.
+ *
+ * Prefer this over ptep_get_lockless() when young and dirty information is not
+ * required since it can be faster on some architectures.
+ *
+ * May be overridden by the architecture; otherwise, implemented using the more
+ * precise ptep_get_lockless().
+ *
+ * Context: Any.
+ */
+static inline pte_t ptep_get_lockless_norecency(pte_t *ptep)
+{
+	return ptep_get_lockless(ptep);
+}
+#endif
+
 #ifndef pmdp_get_lockless
 static inline pmd_t pmdp_get_lockless(pmd_t *pmdp)
 {
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f0f0f71213a1..27991312d635 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7583,7 +7583,7 @@ static u64 perf_get_pgtable_size(struct mm_struct *mm, unsigned long addr)
 	if (!ptep)
 		goto again;

-	pte = ptep_get_lockless(ptep);
+	pte = ptep_get_lockless_norecency(ptep);
 	if (pte_present(pte))
 		size = pte_leaf_size(pte);
 	pte_unmap(ptep);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 68283e54c899..41dc44eb8454 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -7517,7 +7517,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
 	}

 	if (pte) {
-		pte_t pteval = ptep_get_lockless(pte);
+		pte_t pteval = ptep_get_lockless_norecency(pte);

 		BUG_ON(pte_present(pteval) && !pte_huge(pteval));
 	}
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 2771fc043b3b..1a6c9ed8237a 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1019,7 +1019,7 @@ static int __collapse_huge_page_swapin(struct mm_struct *mm,
 			}
 		}

-		vmf.orig_pte = ptep_get_lockless(pte);
+		vmf.orig_pte = ptep_get_lockless_norecency(pte);
 		if (!is_swap_pte(vmf.orig_pte))
 			continue;

diff --git a/mm/memory.c b/mm/memory.c
index 4dd8e35b593a..8e65fa1884f1 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4353,7 +4353,7 @@ static bool pte_range_none(pte_t *pte, int nr_pages)
 	int i;

 	for (i = 0; i < nr_pages; i++) {
-		if (!pte_none(ptep_get_lockless(pte + i)))
+		if (!pte_none(ptep_get_lockless_norecency(pte + i)))
 			return false;
 	}

diff --git a/mm/swap_state.c b/mm/swap_state.c
index 2f540748f7c0..061c6c16c7ff 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -837,7 +837,7 @@ static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask,
 			if (!pte)
 				break;
 		}
-		pentry = ptep_get_lockless(pte);
+		pentry = ptep_get_lockless_norecency(pte);
 		if (!is_swap_pte(pentry))
 			continue;
 		entry = pte_to_swp_entry(pentry);
diff --git a/mm/swapfile.c b/mm/swapfile.c
index d1bd8d1e17bd..c414dd238814 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1857,7 +1857,7 @@ static int unuse_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
 				break;
 		}

-		ptent = ptep_get_lockless(pte);
+		ptent = ptep_get_lockless_norecency(pte);

 		if (!is_swap_pte(ptent))
 			continue;
--
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 04:17:55 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 12:17:55 +0000
Subject: [RFC PATCH v1 3/4] mm/memory: Use ptep_get_lockless_norecency() for orig_pte
In-Reply-To: <20240215121756.2734131-1-ryan.roberts@arm.com>
References: <20240215121756.2734131-1-ryan.roberts@arm.com>
Message-ID: <20240215121756.2734131-4-ryan.roberts@arm.com>

Let's convert handle_pte_fault()'s use of ptep_get_lockless() to
ptep_get_lockless_norecency() to save orig_pte.

There are a number of places that follow this model:

    orig_pte = ptep_get_lockless(ptep)
    ...
    <lock>
    if (!pte_same(orig_pte, ptep_get(ptep)))
            // RACE!
    ...
    <unlock>

So we need to be careful to convert all of those to use
pte_same_norecency() so that the access and dirty bits are excluded from
the comparison.

Additionally there are a couple of places that genuinely rely on the
access and dirty bits of orig_pte, but with some careful refactoring, we
can use ptep_get() once we are holding the lock to achieve equivalent
logic.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 mm/memory.c | 55 +++++++++++++++++++++++++++++++++--------------------
 1 file changed, 34 insertions(+), 21 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 8e65fa1884f1..075245314ec3 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3014,7 +3014,7 @@ static inline int pte_unmap_same(struct vm_fault *vmf)
 #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPTION)
 	if (sizeof(pte_t) > sizeof(unsigned long)) {
 		spin_lock(vmf->ptl);
-		same = pte_same(ptep_get(vmf->pte), vmf->orig_pte);
+		same = pte_same_norecency(ptep_get(vmf->pte), vmf->orig_pte);
 		spin_unlock(vmf->ptl);
 	}
 #endif
@@ -3062,11 +3062,14 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,
 	 * take a double page fault, so mark it accessed here.
 	 */
 	vmf->pte = NULL;
-	if (!arch_has_hw_pte_young() && !pte_young(vmf->orig_pte)) {
+	if (!arch_has_hw_pte_young()) {
 		pte_t entry;

 		vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl);
-		if (unlikely(!vmf->pte || !pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
+		if (likely(vmf->pte))
+			entry = ptep_get(vmf->pte);
+		if (unlikely(!vmf->pte ||
+			     !pte_same_norecency(entry, vmf->orig_pte))) {
 			/*
 			 * Other thread has already handled the fault
 			 * and update local tlb only
@@ -3077,9 +3080,11 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,
 			goto pte_unlock;
 		}

-		entry = pte_mkyoung(vmf->orig_pte);
-		if (ptep_set_access_flags(vma, addr, vmf->pte, entry, 0))
-			update_mmu_cache_range(vmf, vma, addr, vmf->pte, 1);
+		if (!pte_young(entry)) {
+			entry = pte_mkyoung(entry);
+			if (ptep_set_access_flags(vma, addr, vmf->pte, entry, 0))
+				update_mmu_cache_range(vmf, vma, addr, vmf->pte, 1);
+		}
 	}

 	/*
@@ -3094,7 +3099,8 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,

 		/* Re-validate under PTL if the page is still mapped */
 		vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl);
-		if (unlikely(!vmf->pte || !pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
+		if (unlikely(!vmf->pte ||
+			     !pte_same_norecency(ptep_get(vmf->pte), vmf->orig_pte))) {
 			/* The PTE changed under us, update local tlb */
 			if (vmf->pte)
 				update_mmu_tlb(vma, addr, vmf->pte);
@@ -3369,14 +3375,17 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
 	 * Re-check the pte - we dropped the lock
 	 */
 	vmf->pte = pte_offset_map_lock(mm, vmf->pmd, vmf->address, &vmf->ptl);
-	if (likely(vmf->pte && pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
+	if (likely(vmf->pte))
+		entry = ptep_get(vmf->pte);
+	if (likely(vmf->pte && pte_same_norecency(entry, vmf->orig_pte))) {
 		if (old_folio) {
 			if (!folio_test_anon(old_folio)) {
 				dec_mm_counter(mm, mm_counter_file(old_folio));
 				inc_mm_counter(mm, MM_ANONPAGES);
 			}
 		} else {
-			ksm_might_unmap_zero_page(mm, vmf->orig_pte);
+			/* Needs dirty bit so can't use vmf->orig_pte. */
+			ksm_might_unmap_zero_page(mm, entry);
 			inc_mm_counter(mm, MM_ANONPAGES);
 		}
 		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
@@ -3494,7 +3503,7 @@ static vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf, struct folio *folio
 	 * We might have raced with another page fault while we released the
 	 * pte_offset_map_lock.
 	 */
-	if (!pte_same(ptep_get(vmf->pte), vmf->orig_pte)) {
+	if (!pte_same_norecency(ptep_get(vmf->pte), vmf->orig_pte)) {
 		update_mmu_tlb(vmf->vma, vmf->address, vmf->pte);
 		pte_unmap_unlock(vmf->pte, vmf->ptl);
 		return VM_FAULT_NOPAGE;
@@ -3883,7 +3892,8 @@ static vm_fault_t remove_device_exclusive_entry(struct vm_fault *vmf)

 	vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address,
 				&vmf->ptl);
-	if (likely(vmf->pte && pte_same(ptep_get(vmf->pte), vmf->orig_pte)))
+	if (likely(vmf->pte &&
+		   pte_same_norecency(ptep_get(vmf->pte), vmf->orig_pte)))
 		restore_exclusive_pte(vma, vmf->page, vmf->address, vmf->pte);

 	if (vmf->pte)
@@ -3928,7 +3938,7 @@ static vm_fault_t pte_marker_clear(struct vm_fault *vmf)
 	 * quickly from a PTE_MARKER_UFFD_WP into PTE_MARKER_POISONED.
 	 * So is_pte_marker() check is not enough to safely drop the pte.
 	 */
-	if (pte_same(vmf->orig_pte, ptep_get(vmf->pte)))
+	if (pte_same_norecency(vmf->orig_pte, ptep_get(vmf->pte)))
 		pte_clear(vmf->vma->vm_mm, vmf->address, vmf->pte);
 	pte_unmap_unlock(vmf->pte, vmf->ptl);
 	return 0;
@@ -4028,8 +4038,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 			vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
 					vmf->address, &vmf->ptl);
 			if (unlikely(!vmf->pte ||
-				     !pte_same(ptep_get(vmf->pte),
-							vmf->orig_pte)))
+				     !pte_same_norecency(ptep_get(vmf->pte),
+							 vmf->orig_pte)))
 				goto unlock;

 			/*
@@ -4117,7 +4127,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 			vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
 					vmf->address, &vmf->ptl);
 			if (likely(vmf->pte &&
-				   pte_same(ptep_get(vmf->pte), vmf->orig_pte)))
+				   pte_same_norecency(ptep_get(vmf->pte),
+						      vmf->orig_pte)))
 				ret = VM_FAULT_OOM;
 			goto unlock;
 		}
@@ -4187,7 +4198,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 	 */
 	vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address,
 			&vmf->ptl);
-	if (unlikely(!vmf->pte || !pte_same(ptep_get(vmf->pte), vmf->orig_pte)))
+	if (unlikely(!vmf->pte ||
+		     !pte_same_norecency(ptep_get(vmf->pte), vmf->orig_pte)))
 		goto out_nomap;

 	if (unlikely(!folio_test_uptodate(folio))) {
@@ -4747,7 +4759,7 @@ void set_pte_range(struct vm_fault *vmf, struct folio *folio,
 static bool vmf_pte_changed(struct vm_fault *vmf)
 {
 	if (vmf->flags & FAULT_FLAG_ORIG_PTE_VALID)
-		return !pte_same(ptep_get(vmf->pte), vmf->orig_pte);
+		return !pte_same_norecency(ptep_get(vmf->pte), vmf->orig_pte);

 	return !pte_none(ptep_get(vmf->pte));
 }
@@ -5125,7 +5137,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
 	 * the pfn may be screwed if the read is non atomic.
 	 */
 	spin_lock(vmf->ptl);
-	if (unlikely(!pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
+	if (unlikely(!pte_same_norecency(ptep_get(vmf->pte), vmf->orig_pte))) {
 		pte_unmap_unlock(vmf->pte, vmf->ptl);
 		goto out;
 	}
@@ -5197,7 +5209,8 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
 					       vmf->address, &vmf->ptl);
 		if (unlikely(!vmf->pte))
 			goto out;
-		if (unlikely(!pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
+		if (unlikely(!pte_same_norecency(ptep_get(vmf->pte),
+							  vmf->orig_pte))) {
 			pte_unmap_unlock(vmf->pte, vmf->ptl);
 			goto out;
 		}
@@ -5343,7 +5356,7 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
 						 vmf->address, &vmf->ptl);
 		if (unlikely(!vmf->pte))
 			return 0;
-		vmf->orig_pte = ptep_get_lockless(vmf->pte);
+		vmf->orig_pte = ptep_get_lockless_norecency(vmf->pte);
 		vmf->flags |= FAULT_FLAG_ORIG_PTE_VALID;

 		if (pte_none(vmf->orig_pte)) {
@@ -5363,7 +5376,7 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)

 	spin_lock(vmf->ptl);
 	entry = vmf->orig_pte;
-	if (unlikely(!pte_same(ptep_get(vmf->pte), entry))) {
+	if (unlikely(!pte_same_norecency(ptep_get(vmf->pte), entry))) {
 		update_mmu_tlb(vmf->vma, vmf->address, vmf->pte);
 		goto unlock;
 	}
--
2.25.1



From ryan.roberts at arm.com  Thu Feb 15 04:17:56 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 12:17:56 +0000
Subject: [RFC PATCH v1 4/4] arm64/mm: Override ptep_get_lockless_norecency()
In-Reply-To: <20240215121756.2734131-1-ryan.roberts@arm.com>
References: <20240215121756.2734131-1-ryan.roberts@arm.com>
Message-ID: <20240215121756.2734131-5-ryan.roberts@arm.com>

Override ptep_get_lockless_norecency() when CONFIG_ARM64_CONTPTE is
enabled. Because this API doesn't require the access and dirty bits to
be accurate, for the contpte case, we can avoid reading all ptes in the
contpte block to collect those bits, in contrast to ptep_get_lockless().

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 401087e8a43d..c0e4ccf74714 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1287,6 +1287,12 @@ static inline pte_t ptep_get_lockless(pte_t *ptep)
 	return contpte_ptep_get_lockless(ptep);
 }

+#define ptep_get_lockless_norecency ptep_get_lockless_norecency
+static inline pte_t ptep_get_lockless_norecency(pte_t *ptep)
+{
+	return __ptep_get(ptep);
+}
+
 static inline void set_pte(pte_t *ptep, pte_t pte)
 {
 	/*
--
2.25.1



From will at kernel.org  Thu Feb 15 04:44:37 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 15 Feb 2024 12:44:37 +0000
Subject: [PATCH v2] arm64/sve: Lower the maximum allocation for the SVE ptrace regset
In-Reply-To: <20240213-arm64-sve-ptrace-regset-size-v2-1-c7600ca74b9b@kernel.org>
References: <20240213-arm64-sve-ptrace-regset-size-v2-1-c7600ca74b9b@kernel.org>
Message-ID: <170799768132.3746307.14703611184129999692.b4-ty@kernel.org>

On Tue, 13 Feb 2024 18:24:38 +0000, Mark Brown wrote:
> Doug Anderson observed that ChromeOS crashes are being reported which
> include failing allocations of order 7 during core dumps due to ptrace
> allocating storage for regsets:
> 
>   chrome: page allocation failure: order:7,
>           mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
>           nodemask=(null),cpuset=urgent,mems_allowed=0
>    ...
>   regset_get_alloc+0x1c/0x28
>   elf_core_dump+0x3d8/0xd8c
>   do_coredump+0xeb8/0x1378
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64/sve: Lower the maximum allocation for the SVE ptrace regset
      https://git.kernel.org/arm64/c/2813926261e4

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Thu Feb 15 04:44:38 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 15 Feb 2024 12:44:38 +0000
Subject: [PATCH v2] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM Neoverse N2 errata
In-Reply-To: <20240214175522.2457857-1-eahariha@linux.microsoft.com>
References: <20240214175522.2457857-1-eahariha@linux.microsoft.com>
Message-ID: <170799764265.3746091.15823620803100752366.b4-ty@kernel.org>

On Wed, 14 Feb 2024 17:55:18 +0000, Easwar Hariharan wrote:
> Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft
> implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore
> suffers from all the same errata.
> 
> 

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM Neoverse N2 errata
      https://git.kernel.org/arm64/c/fb091ff39479

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From quic_jinlmao at quicinc.com  Thu Feb 15 04:44:37 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Thu, 15 Feb 2024 04:44:37 -0800
Subject: [PATCH v2 2/2] coresight-tpda: Change qcom,dsb-element-size to qcom,dsb-elem-bits
In-Reply-To: <20240215124439.30037-1-quic_jinlmao@quicinc.com>
References: <20240215124439.30037-1-quic_jinlmao@quicinc.com>
Message-ID: <20240215124439.30037-3-quic_jinlmao@quicinc.com>

Change qcom,dsb-element-size to qcom,dsb-elem-bits as the unit is bit.

Fixes: 57e7235aa1d1 ("coresight-tpda: Add DSB dataset support")
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpda.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 6863afe7ca94..5d20e10be24b 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -70,7 +70,7 @@ static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
 
 	if (tpdm_has_dsb_dataset(tpdm_data)) {
 		rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
-				"qcom,dsb-element-size", &drvdata->dsb_esize);
+				"qcom,dsb-element-bits", &drvdata->dsb_esize);
 	}
 	if (tpdm_has_cmb_dataset(tpdm_data)) {
 		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
-- 
2.41.0



From quic_jinlmao at quicinc.com  Thu Feb 15 04:44:36 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Thu, 15 Feb 2024 04:44:36 -0800
Subject: [PATCH v2 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename qcom,dsb-element-size
In-Reply-To: <20240215124439.30037-1-quic_jinlmao@quicinc.com>
References: <20240215124439.30037-1-quic_jinlmao@quicinc.com>
Message-ID: <20240215124439.30037-2-quic_jinlmao@quicinc.com>

Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
bit. There is no tpdm node in any DT as of now. Make this change before
any tpdm node is added to DT.

Fixes: 2a8d9b371566 ("dt-bindings: arm: Add support for DSB element size")
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml         | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
index d0647ffaed71..8eec07d9d454 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
@@ -44,12 +44,11 @@ properties:
     minItems: 1
     maxItems: 2
 
-  qcom,dsb-element-size:
+  qcom,dsb-element-bits:
     description:
       Specifies the DSB(Discrete Single Bit) element size supported by
       the monitor. The associated aggregator will read this size before it
       is enabled. DSB element size currently only supports 32-bit and 64-bit.
-    $ref: /schemas/types.yaml#/definitions/uint8
     enum: [32, 64]
 
   qcom,cmb-element-bits:
@@ -111,7 +110,7 @@ examples:
       compatible = "qcom,coresight-tpdm", "arm,primecell";
       reg = <0x0684c000 0x1000>;
 
-      qcom,dsb-element-size = /bits/ 8 <32>;
+      qcom,dsb-element-bits = <32>;
       qcom,dsb-msrs-num = <16>;
 
       clocks = <&aoss_qmp>;
-- 
2.41.0



From quic_jinlmao at quicinc.com  Thu Feb 15 04:44:35 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Thu, 15 Feb 2024 04:44:35 -0800
Subject: [PATCH v2 0/2] coresight: tpdm: Change qcom,dsb-element-size to qcom,dsb-elem-bits
Message-ID: <20240215124439.30037-1-quic_jinlmao@quicinc.com>

As unit of dsb element size is bit, change qcom,dsb-element-size to
qcom,dsb-elem-bits. And CMB uses -bits suffix as well. There is no
TPDM node in any DT now. Make such change before any TPDM node is added
to DT. 

Change since V1:
1. Update the commit message for dt-binding.
2. Fix the dt_binding_check error for dt-binding change.

Mao Jinlong (2):
  dt-bindings: arm: qcom,coresight-tpdm: Rename qcom,dsb-element-size
  coresight-tpda: Change qcom,dsb-element-size to qcom,dsb-elem-bits

 .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml         | 5 ++---
 drivers/hwtracing/coresight/coresight-tpda.c                 | 2 +-
 2 files changed, 3 insertions(+), 4 deletions(-)

-- 
2.41.0



From diogo.ivo at siemens.com  Thu Feb 15 04:44:54 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Thu, 15 Feb 2024 12:44:54 +0000
Subject: [PATCH net] net: ti: icssg-prueth: Remove duplicate cleanup calls
 in emac_ndo_stop()
In-Reply-To: <20240206152052.98217-1-diogo.ivo@siemens.com>
References: <20240206152052.98217-1-diogo.ivo@siemens.com>
Message-ID: <ce2c5ee0-3bed-490e-ac57-58e849ec1eee@siemens.com>


On 2/6/24 15:20, Diogo Ivo wrote:
> Remove the duplicate calls to prueth_emac_stop() and
> prueth_cleanup_tx_chns() in emac_ndo_stop().
>
> Fixes: 128d5874c082 ("net: ti: icssg-prueth: Add ICSSG ethernet driver")
> Fixes: 186734c15886 ("net: ti: icssg-prueth: add packet timestamping and ptp support")
> Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
> ---
>   drivers/net/ethernet/ti/icssg/icssg_prueth.c | 4 ----
>   1 file changed, 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> index 411898a4f38c..cf7b73f8f450 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
> @@ -1489,9 +1489,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>   	/* Destroying the queued work in ndo_stop() */
>   	cancel_delayed_work_sync(&emac->stats_work);
>   
> -	/* stop PRUs */
> -	prueth_emac_stop(emac);
> -
>   	if (prueth->emacs_initialized == 1)
>   		icss_iep_exit(emac->iep);
>   
> @@ -1502,7 +1499,6 @@ static int emac_ndo_stop(struct net_device *ndev)
>   
>   	free_irq(emac->rx_chns.irq[rx_flow], emac);
>   	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
> -	prueth_cleanup_tx_chns(emac);
>   
>   	prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows);
>   	prueth_cleanup_tx_chns(emac);

Hello,

Gentle ping on this patch.


Thank you,

Diogo



From broonie at kernel.org  Thu Feb 15 05:00:38 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 15 Feb 2024 13:00:38 +0000
Subject: [PATCH] arm64/sysreg: Update ID_AA64DFR0_EL1 and ID_DFR0_EL1
In-Reply-To: <20240215055159.2440898-1-anshuman.khandual@arm.com>
References: <20240215055159.2440898-1-anshuman.khandual@arm.com>
Message-ID: <b103244b-7776-48fb-8055-5c003d773087@sirena.org.uk>

On Thu, Feb 15, 2024 at 11:21:59AM +0530, Anshuman Khandual wrote:

> This just updates ID_DFR0_EL1.CopDbg and ID_AA64DFR0_EL1.DebugVer register
> fields as per the definitions based on DDI0601 2023-12.

Just as a general note for non-trival registers it's easier to review if
we change one register per patch, it avoids having to re-review the same
registers repeatedly and for incremental changes like this it helps with
the fact that diff does badly at offering context.

> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -231,6 +231,7 @@ Enum	3:0	CopDbg
>  	0b1000	Debugv8p2
>  	0b1001	Debugv8p4
>  	0b1010	Debugv8p8
> +	0b1011	Debugv8p9
>  EndEnum
>  EndSysreg

This is ID_AA64DFR0_EL1 and is missing at least an update to PMSVer.

>  
> @@ -1247,6 +1248,7 @@ UnsignedEnum	3:0	DebugVer
>  	0b1000	V8P2
>  	0b1001	V8P4
>  	0b1010	V8P8
> +	0b1011	V8P9
>  EndEnum
>  EndSysreg

This is ID_DFR0_EL1 and is missing an update to at least PerfMon.
-------------- 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/20240215/e68884c8/attachment-0001.sig>

From broonie at kernel.org  Thu Feb 15 05:04:09 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 15 Feb 2024 13:04:09 +0000
Subject: [PATCH] arm64/sysreg: Add register fields for ID_AA64DFR1_EL1
In-Reply-To: <20240215065454.2489075-1-anshuman.khandual@arm.com>
References: <20240215065454.2489075-1-anshuman.khandual@arm.com>
Message-ID: <d2722ae9-d29c-41f9-9eec-f829589adf6e@sirena.org.uk>

On Thu, Feb 15, 2024 at 12:24:54PM +0530, Anshuman Khandual wrote:

>  Sysreg	ID_AA64DFR1_EL1	3	0	0	5	1
> -Res0	63:0
> +Field	63:56	ABL_CMPs
> +Field	55:52	DPFZS

This is documented in the architecture as an enumeration, though I'm not
immediately seeing what values to use.

Otherwise this looks good.
-------------- 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/20240215/d2b6784c/attachment.sig>

From geert+renesas at glider.be  Thu Feb 15 05:17:13 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 15 Feb 2024 14:17:13 +0100
Subject: [PATCH resend] arm64: dts: mediatek: mt8186: bpi-r3: Convert to sugar syntax
Message-ID: <8c10c4bf701583d015506712ba9239dbc7547426.1708002920.git.geert+renesas@glider.be>

Overlay syntactic sugar for generating target-path fragments is
supported by the version of dtc supplied with the kernel since commit
50aafd60898a8b3e ("scripts/dtc: Update to upstream version
v1.4.6-21-g84e414b0b5bc").  Hence convert the Bananapi R3 overlay
devicetree source files to sugar syntax, improving readability.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
No changes in generated dtbo.
---
 .../mt7986a-bananapi-bpi-r3-emmc.dtso         | 28 +++---
 .../mt7986a-bananapi-bpi-r3-nand.dtso         | 74 ++++++++-------
 .../mediatek/mt7986a-bananapi-bpi-r3-nor.dtso | 90 +++++++++----------
 .../mediatek/mt7986a-bananapi-bpi-r3-sd.dtso  | 16 ++--
 4 files changed, 98 insertions(+), 110 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
index 779dc6782bb1986f..047a8388811eb9c0 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
@@ -9,21 +9,17 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-
-	fragment at 0 {
-		target-path = "/soc/mmc at 11230000";
-		__overlay__ {
-			bus-width = <8>;
-			max-frequency = <200000000>;
-			cap-mmc-highspeed;
-			mmc-hs200-1_8v;
-			mmc-hs400-1_8v;
-			hs400-ds-delay = <0x14014>;
-			non-removable;
-			no-sd;
-			no-sdio;
-			status = "okay";
-		};
-	};
 };
 
+&{/soc/mmc at 11230000} {
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	hs400-ds-delay = <0x14014>;
+	non-removable;
+	no-sd;
+	no-sdio;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
index 543c13385d6e3f82..12ec15e3188de082 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
@@ -9,46 +9,44 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
+};
+
+&{/soc/spi at 1100a000} {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	spi_nand: spi_nand at 0 {
+		compatible = "spi-nand";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		spi-tx-buswidth = <4>;
+		spi-rx-buswidth = <4>;
 
-	fragment at 0 {
-		target-path = "/soc/spi at 1100a000";
-		__overlay__ {
+		partitions {
+			compatible = "fixed-partitions";
 			#address-cells = <1>;
-			#size-cells = <0>;
-			spi_nand: spi_nand at 0 {
-				compatible = "spi-nand";
-				reg = <0>;
-				spi-max-frequency = <10000000>;
-				spi-tx-buswidth = <4>;
-				spi-rx-buswidth = <4>;
-
-				partitions {
-					compatible = "fixed-partitions";
-					#address-cells = <1>;
-					#size-cells = <1>;
-
-					partition at 0 {
-						label = "bl2";
-						reg = <0x0 0x100000>;
-						read-only;
-					};
-
-					partition at 100000 {
-						label = "reserved";
-						reg = <0x100000 0x280000>;
-					};
-
-					partition at 380000 {
-						label = "fip";
-						reg = <0x380000 0x200000>;
-						read-only;
-					};
-
-					partition at 580000 {
-						label = "ubi";
-						reg = <0x580000 0x7a80000>;
-					};
-				};
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "bl2";
+				reg = <0x0 0x100000>;
+				read-only;
+			};
+
+			partition at 100000 {
+				label = "reserved";
+				reg = <0x100000 0x280000>;
+			};
+
+			partition at 380000 {
+				label = "fip";
+				reg = <0x380000 0x200000>;
+				read-only;
+			};
+
+			partition at 580000 {
+				label = "ubi";
+				reg = <0x580000 0x7a80000>;
 			};
 		};
 	};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
index e48881be4ed60c98..6a0d529b54aca5bd 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
@@ -9,54 +9,52 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
+};
+
+&{/soc/spi at 1100a000} {
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-	fragment at 0 {
-		target-path = "/soc/spi at 1100a000";
-		__overlay__ {
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
 			#address-cells = <1>;
-			#size-cells = <0>;
-			flash at 0 {
-				compatible = "jedec,spi-nor";
-				reg = <0>;
-				spi-max-frequency = <10000000>;
-
-				partitions {
-					compatible = "fixed-partitions";
-					#address-cells = <1>;
-					#size-cells = <1>;
-
-					partition at 0 {
-						label = "bl2";
-						reg = <0x0 0x40000>;
-						read-only;
-					};
-
-					partition at 40000 {
-						label = "u-boot-env";
-						reg = <0x40000 0x40000>;
-					};
-
-					partition at 80000 {
-						label = "reserved2";
-						reg = <0x80000 0x80000>;
-					};
-
-					partition at 100000 {
-						label = "fip";
-						reg = <0x100000 0x80000>;
-						read-only;
-					};
-
-					partition at 180000 {
-						label = "recovery";
-						reg = <0x180000 0xa80000>;
-					};
-
-					partition at c00000 {
-						label = "fit";
-						reg = <0xc00000 0x1400000>;
-					};
-				};
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "bl2";
+				reg = <0x0 0x40000>;
+				read-only;
+			};
+
+			partition at 40000 {
+				label = "u-boot-env";
+				reg = <0x40000 0x40000>;
+			};
+
+			partition at 80000 {
+				label = "reserved2";
+				reg = <0x80000 0x80000>;
+			};
+
+			partition at 100000 {
+				label = "fip";
+				reg = <0x100000 0x80000>;
+				read-only;
+			};
+
+			partition at 180000 {
+				label = "recovery";
+				reg = <0x180000 0xa80000>;
+			};
+
+			partition at c00000 {
+				label = "fit";
+				reg = <0xc00000 0x1400000>;
 			};
 		};
 	};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
index f623bce075ce6ea4..d9e01967acc471b8 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
@@ -9,15 +9,11 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-
-	fragment at 0 {
-		target-path = "/soc/mmc at 11230000";
-		__overlay__ {
-			bus-width = <4>;
-			max-frequency = <52000000>;
-			cap-sd-highspeed;
-			status = "okay";
-		};
-	};
 };
 
+&{/soc/mmc at 11230000} {
+	bus-width = <4>;
+	max-frequency = <52000000>;
+	cap-sd-highspeed;
+	status = "okay";
+};
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb 15 05:20:39 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 15 Feb 2024 14:20:39 +0100
Subject: [PATCH v2] arm64: dts: mediatek: mt8186: bpi-r3: Convert to sugar syntax
Message-ID: <8c10c4bf701583d015506712ba9239dbc7547426.1708003159.git.geert+renesas@glider.be>

Overlay syntactic sugar for generating target-path fragments is
supported by the version of dtc supplied with the kernel since commit
50aafd60898a8b3e ("scripts/dtc: Update to upstream version
v1.4.6-21-g84e414b0b5bc").  Hence convert the Bananapi R3 overlay
devicetree source files to sugar syntax, improving readability.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
No changes in generated dtbo.

v2:
  - Rebase on top of commit e630c7b0b6a69f66 ("arm64: dts: mediatek:
    replace underscores in node names") in next-20240215.

---
 .../mt7986a-bananapi-bpi-r3-emmc.dtso         | 28 +++---
 .../mt7986a-bananapi-bpi-r3-nand.dtso         | 74 ++++++++-------
 .../mediatek/mt7986a-bananapi-bpi-r3-nor.dtso | 90 +++++++++----------
 .../mediatek/mt7986a-bananapi-bpi-r3-sd.dtso  | 16 ++--
 4 files changed, 98 insertions(+), 110 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
index 779dc6782bb1986f..047a8388811eb9c0 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
@@ -9,21 +9,17 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-
-	fragment at 0 {
-		target-path = "/soc/mmc at 11230000";
-		__overlay__ {
-			bus-width = <8>;
-			max-frequency = <200000000>;
-			cap-mmc-highspeed;
-			mmc-hs200-1_8v;
-			mmc-hs400-1_8v;
-			hs400-ds-delay = <0x14014>;
-			non-removable;
-			no-sd;
-			no-sdio;
-			status = "okay";
-		};
-	};
 };
 
+&{/soc/mmc at 11230000} {
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	hs400-ds-delay = <0x14014>;
+	non-removable;
+	no-sd;
+	no-sdio;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
index 543c13385d6e3f82..12ec15e3188de082 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
@@ -9,46 +9,44 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
+};
+
+&{/soc/spi at 1100a000} {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	spi_nand: flash at 0 {
+		compatible = "spi-nand";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		spi-tx-buswidth = <4>;
+		spi-rx-buswidth = <4>;
 
-	fragment at 0 {
-		target-path = "/soc/spi at 1100a000";
-		__overlay__ {
+		partitions {
+			compatible = "fixed-partitions";
 			#address-cells = <1>;
-			#size-cells = <0>;
-			spi_nand: flash at 0 {
-				compatible = "spi-nand";
-				reg = <0>;
-				spi-max-frequency = <10000000>;
-				spi-tx-buswidth = <4>;
-				spi-rx-buswidth = <4>;
-
-				partitions {
-					compatible = "fixed-partitions";
-					#address-cells = <1>;
-					#size-cells = <1>;
-
-					partition at 0 {
-						label = "bl2";
-						reg = <0x0 0x100000>;
-						read-only;
-					};
-
-					partition at 100000 {
-						label = "reserved";
-						reg = <0x100000 0x280000>;
-					};
-
-					partition at 380000 {
-						label = "fip";
-						reg = <0x380000 0x200000>;
-						read-only;
-					};
-
-					partition at 580000 {
-						label = "ubi";
-						reg = <0x580000 0x7a80000>;
-					};
-				};
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "bl2";
+				reg = <0x0 0x100000>;
+				read-only;
+			};
+
+			partition at 100000 {
+				label = "reserved";
+				reg = <0x100000 0x280000>;
+			};
+
+			partition at 380000 {
+				label = "fip";
+				reg = <0x380000 0x200000>;
+				read-only;
+			};
+
+			partition at 580000 {
+				label = "ubi";
+				reg = <0x580000 0x7a80000>;
 			};
 		};
 	};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
index e48881be4ed60c98..6a0d529b54aca5bd 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
@@ -9,54 +9,52 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
+};
+
+&{/soc/spi at 1100a000} {
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-	fragment at 0 {
-		target-path = "/soc/spi at 1100a000";
-		__overlay__ {
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
 			#address-cells = <1>;
-			#size-cells = <0>;
-			flash at 0 {
-				compatible = "jedec,spi-nor";
-				reg = <0>;
-				spi-max-frequency = <10000000>;
-
-				partitions {
-					compatible = "fixed-partitions";
-					#address-cells = <1>;
-					#size-cells = <1>;
-
-					partition at 0 {
-						label = "bl2";
-						reg = <0x0 0x40000>;
-						read-only;
-					};
-
-					partition at 40000 {
-						label = "u-boot-env";
-						reg = <0x40000 0x40000>;
-					};
-
-					partition at 80000 {
-						label = "reserved2";
-						reg = <0x80000 0x80000>;
-					};
-
-					partition at 100000 {
-						label = "fip";
-						reg = <0x100000 0x80000>;
-						read-only;
-					};
-
-					partition at 180000 {
-						label = "recovery";
-						reg = <0x180000 0xa80000>;
-					};
-
-					partition at c00000 {
-						label = "fit";
-						reg = <0xc00000 0x1400000>;
-					};
-				};
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "bl2";
+				reg = <0x0 0x40000>;
+				read-only;
+			};
+
+			partition at 40000 {
+				label = "u-boot-env";
+				reg = <0x40000 0x40000>;
+			};
+
+			partition at 80000 {
+				label = "reserved2";
+				reg = <0x80000 0x80000>;
+			};
+
+			partition at 100000 {
+				label = "fip";
+				reg = <0x100000 0x80000>;
+				read-only;
+			};
+
+			partition at 180000 {
+				label = "recovery";
+				reg = <0x180000 0xa80000>;
+			};
+
+			partition at c00000 {
+				label = "fit";
+				reg = <0xc00000 0x1400000>;
 			};
 		};
 	};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
index f623bce075ce6ea4..d9e01967acc471b8 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
@@ -9,15 +9,11 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-
-	fragment at 0 {
-		target-path = "/soc/mmc at 11230000";
-		__overlay__ {
-			bus-width = <4>;
-			max-frequency = <52000000>;
-			cap-sd-highspeed;
-			status = "okay";
-		};
-	};
 };
 
+&{/soc/mmc at 11230000} {
+	bus-width = <4>;
+	max-frequency = <52000000>;
+	cap-sd-highspeed;
+	status = "okay";
+};
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb 15 05:21:51 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 15 Feb 2024 14:21:51 +0100
Subject: [PATCH resend] ARM: Kconfig: Spelling s/Cortex A-/Cortex-A/
Message-ID: <b2d0140f01703ee451b0136186b09e02e3326b13.1708003251.git.geert+renesas@glider.be>

Fix a misspelling of "Cortex-A9", to make it easier to find which errata
are applicable to Cortex-A9 CPU cores.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0af6709570d147f3..ed2249fbb839eb16 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -732,7 +732,7 @@ config ARM_ERRATA_764319
 	bool "ARM errata: Read to DBGPRSR and DBGOSLSR may generate Undefined instruction"
 	depends on CPU_V7
 	help
-	  This option enables the workaround for the 764319 Cortex A-9 erratum.
+	  This option enables the workaround for the 764319 Cortex-A9 erratum.
 	  CP14 read accesses to the DBGPRSR and DBGOSLSR registers generate an
 	  unexpected Undefined Instruction exception when the DBGSWENABLE
 	  external pin is set to 0, even when the CP14 accesses are performed
-- 
2.34.1



From geert+renesas at glider.be  Thu Feb 15 05:23:11 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 15 Feb 2024 14:23:11 +0100
Subject: [PATCH resend] ARM: Alpine: Spelling s/initialiing/initializing/
Message-ID: <bdbfee1c04bb9326f4782afcc29b048ff5ef4546.1708003331.git.geert+renesas@glider.be>

Fix a misspelling of "initializing".

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm/mach-alpine/alpine_cpu_pm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-alpine/alpine_cpu_pm.c b/arch/arm/mach-alpine/alpine_cpu_pm.c
index 13ae8412e9ce6451..b48da6f12b6cc46a 100644
--- a/arch/arm/mach-alpine/alpine_cpu_pm.c
+++ b/arch/arm/mach-alpine/alpine_cpu_pm.c
@@ -29,7 +29,7 @@ int alpine_cpu_wakeup(unsigned int phys_cpu, uint32_t phys_resume_addr)
 	/*
 	 * Set CPU resume address -
 	 * secure firmware running on boot will jump to this address
-	 * after setting proper CPU mode, and initialiing e.g. secure
+	 * after setting proper CPU mode, and initializing e.g. secure
 	 * regs (the same mode all CPUs are booted to - usually HYP)
 	 */
 	writel(phys_resume_addr,
-- 
2.34.1



From abel.vesa at linaro.org  Thu Feb 15 05:32:08 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Thu, 15 Feb 2024 15:32:08 +0200
Subject: [PATCH RFC v3 3/4] spmi: pmic-arb: Make core resources acquiring
 a version operation
In-Reply-To: <CAA8EJpq=kYeZfNbFtfQ_oLS0Xi4imyEGV+dDNO+h6LZfqmpxZg@mail.gmail.com>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-3-0bae0ef04faf@linaro.org>
 <d9d8e86b-a499-49d1-90ad-6fae5b7dcbb7@linaro.org>
 <Zc0yXR/fC2OcObLB@linaro.org>
 <CAA8EJpq=kYeZfNbFtfQ_oLS0Xi4imyEGV+dDNO+h6LZfqmpxZg@mail.gmail.com>
Message-ID: <Zc4SWIViTS0uf952@linaro.org>

On 24-02-15 11:30:23, Dmitry Baryshkov wrote:
> On Wed, 14 Feb 2024 at 23:36, Abel Vesa <abel.vesa at linaro.org> wrote:
> >
> > On 24-02-14 22:18:33, Konrad Dybcio wrote:
> > > On 14.02.2024 22:13, Abel Vesa wrote:
> > > > Rather than setting up the core, obsrv and chnls in probe by using
> > > > version specific conditionals, add a dedicated "get_core_resources"
> > > > version specific op and move the acquiring in there.
> > > >
> > > > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > > > ---
> > > >  drivers/spmi/spmi-pmic-arb.c | 111 ++++++++++++++++++++++++++++++-------------
> > > >  1 file changed, 78 insertions(+), 33 deletions(-)
> > > >
> > > > diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> > > > index 23939c0d225f..489556467a4c 100644
> > > > --- a/drivers/spmi/spmi-pmic-arb.c
> > > > +++ b/drivers/spmi/spmi-pmic-arb.c
> > > > @@ -203,6 +203,7 @@ struct spmi_pmic_arb {
> > > >   */
> > > >  struct pmic_arb_ver_ops {
> > > >     const char *ver_str;
> > > > +   int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
> > > >     int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
> > > >     int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
> > > >     /* spmi commands (read_cmd, write_cmd, cmd) functionality */
> > > > @@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
> > > >     return 0;
> > > >  }
> > > >
> > > > +static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
> > > > +                                     void __iomem *core)
> > > > +{
> > > > +   struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> > > > +
> > > > +   pmic_arb->wr_base = core;
> > > > +   pmic_arb->rd_base = core;
> > > > +
> > > > +   pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
> > > > +
> > > > +   return 0;
> > > > +}
> > > > +
> > > >  static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
> > > >  {
> > > >     u32 *mapping_table;
> > > > @@ -1063,6 +1077,41 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
> > > >     return apid;
> > > >  }
> > > >
> > > > +static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
> > > > +{
> > > > +   struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> > > > +   struct device *dev = &pdev->dev;
> > > > +   struct resource *res;
> > > > +
> > > > +   res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > >
> > > It's no longer indented to deep, no need to keep such aggressive wrapping
> > >
> >
> > The pmic_arb_get_obsrvr_chnls_v2 is used by both:
> > pmic_arb_get_core_resources_v2
> > pmic_arb_get_core_resources_v7
> >
> > > > +                                      "obsrvr");
> > > > +   pmic_arb->rd_base = devm_ioremap(dev, res->start,
> > > > +                                    resource_size(res));
> > > > +   if (IS_ERR(pmic_arb->rd_base))
> > > > +           return PTR_ERR(pmic_arb->rd_base);
> > > > +
> > > > +   res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > > > +                                      "chnls");
> > > > +   pmic_arb->wr_base = devm_ioremap(dev, res->start,
> > > > +                                    resource_size(res));
> > > > +   if (IS_ERR(pmic_arb->wr_base))
> > > > +           return PTR_ERR(pmic_arb->wr_base);
> > >
> > > Could probably make it "devm_platform_get_and_ioremap_resource "
> >
> > The reason this needs to stay as is is because of reason explained by
> > the following comment found in probe:
> >
> > /*
> >  * Please don't replace this with devm_platform_ioremap_resource() or
> >  * devm_ioremap_resource().  These both result in a call to
> >  * devm_request_mem_region() which prevents multiple mappings of this
> >  * register address range.  SoCs with PMIC arbiter v7 may define two
> >  * arbiter devices, for the two physical SPMI interfaces, which  share
> >  * some register address ranges (i.e. "core", "obsrvr", and "chnls").
> >  * Ensure that both devices probe successfully by calling devm_ioremap()
> >  * which does not result in a devm_request_mem_region() call.
> >  */
> >
> > Even though, AFAICT, there is no platform that adds a second node for
> > the second bus, currently, in mainline, we should probably allow the
> > "legacy" approach to still work.
> 
> If there were no DT files which used two SPMI devices, I think we
> should drop this comment and use existing helpers. We must keep
> compatibility with the existing DTs, not with the _possible_ device
> trees.

Sure.

Should I drop the qcom,bus-id from the driver as well? It is optional
after all.

> 
> >
> > >
> > > Konrad
> 
> 
> 
> -- 
> With best wishes
> Dmitry


From robh at kernel.org  Thu Feb 15 05:32:40 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 07:32:40 -0600
Subject: [PATCH v3 2/5] dt-bindings: fpga: xlnx,fpga-slave-serial: rename
 gpios
In-Reply-To: <20240207180142.79625-3-charles.perry@savoirfairelinux.com>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com>
 <20240207180142.79625-3-charles.perry@savoirfairelinux.com>
Message-ID: <20240215133240.GA4061942-robh@kernel.org>

On Wed, Feb 07, 2024 at 01:01:25PM -0500, Charles Perry wrote:
> By convention, gpio consumer names should not contain underscores
> (prog_b here) and shouldn't contain active low suffixes (-b here).

Yes, that is the preference, but we are stuck with supporting the old 
name. It is not worth it to carry both in the binding and kernel.

Rob


From neil.armstrong at linaro.org  Thu Feb 15 05:33:06 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Thu, 15 Feb 2024 14:33:06 +0100
Subject: [PATCH v2 2/6] dt-bindings: arm-smmu: Document SM8650 GPU SMMU
In-Reply-To: <CAA8EJpobWYu8LoHZarOw82z78=kLJrKH0P4ncK6sX7zE1nHuqQ@mail.gmail.com>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
 <20240215-topic-sm8650-gpu-v2-2-6be0b4bf2e09@linaro.org>
 <CAA8EJprpYEhGi5b+uWGWtOa+qbSwUR8C0j9NLC+ah_-nvy-=Ng@mail.gmail.com>
 <ffb16ef6-fc9a-42b1-b9c3-4e8f6b52d849@linaro.org>
 <CAA8EJpobWYu8LoHZarOw82z78=kLJrKH0P4ncK6sX7zE1nHuqQ@mail.gmail.com>
Message-ID: <2df69499-4ffa-46a9-8e7f-041e87ad3034@linaro.org>

On 15/02/2024 10:32, Dmitry Baryshkov wrote:
> On Thu, 15 Feb 2024 at 11:29, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>>
>> On 15/02/2024 10:25, Dmitry Baryshkov wrote:
>>> On Thu, 15 Feb 2024 at 11:20, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>>>>
>>>> Document the GPU SMMU found on the SM8650 platform.
>>>>
>>>> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
>>>> ---
>>>>    Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 7 +++++--
>>>>    1 file changed, 5 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
>>>> index a4042ae24770..3ad5c850f3bf 100644
>>>> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
>>>> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
>>>> @@ -93,6 +93,7 @@ properties:
>>>>                  - qcom,sm8350-smmu-500
>>>>                  - qcom,sm8450-smmu-500
>>>>                  - qcom,sm8550-smmu-500
>>>> +              - qcom,sm8650-smmu-500
>>>>              - const: qcom,adreno-smmu
>>>>              - const: qcom,smmu-500
>>>>              - const: arm,mmu-500
>>>> @@ -508,7 +509,10 @@ allOf:
>>>>      - if:
>>>>          properties:
>>>>            compatible:
>>>> -          const: qcom,sm8550-smmu-500
>>>> +          contains:
>>>> +            enum:
>>>> +              - qcom,sm8550-smmu-500
>>>> +              - qcom,sm8650-smmu-500
>>>
>>> Doesn't this cause warnings for non-GPU SMMU on this platform?
>>
>> No because it doesn't add those to required, it simply allows clock the properties.
> 
> Can we further constrain this branch so that it is applicable only to
> the Adreno SMMUs (and enforce requirement)? And maybe constrain the
> second if-branch so that it doesn't apply to the Adreno SMMUs?

Indeed, it's done like that for the a6 gpu, I'll send a fix for that

Neil

> 
>>
>>>
>>>>        then:
>>>>          properties:
>>>>            clock-names:
>>>> @@ -544,7 +548,6 @@ allOf:
>>>>                  - qcom,sdx65-smmu-500
>>>>                  - qcom,sm6350-smmu-500
>>>>                  - qcom,sm6375-smmu-500
>>>> -              - qcom,sm8650-smmu-500
>>>>                  - qcom,x1e80100-smmu-500
>>>>        then:
>>>>          properties:
>>>>
>>>> --
>>>> 2.34.1
>>>>
>>>
>>>
>>
> 
> 



From will at kernel.org  Thu Feb 15 05:49:53 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 15 Feb 2024 13:49:53 +0000
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <20240215134952.GA690@willie-the-truck>

Hi Jason,

On Tue, Feb 06, 2024 at 11:12:38AM -0400, Jason Gunthorpe wrote:
> As the comment in arm_smmu_write_strtab_ent() explains, this routine has
> been limited to only work correctly in certain scenarios that the caller
> must ensure. Generally the caller must put the STE into ABORT or BYPASS
> before attempting to program it to something else.

This is looking pretty good now, but I have a few comments inline.

>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 330 ++++++++++++++++----
>  1 file changed, 263 insertions(+), 67 deletions(-)
> 
> 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 0ffb1cf17e0b2e..f0b915567cbcdc 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -48,6 +48,21 @@ enum arm_smmu_msi_index {
>  	ARM_SMMU_MAX_MSIS,
>  };
>  
> +struct arm_smmu_entry_writer_ops;
> +struct arm_smmu_entry_writer {
> +	const struct arm_smmu_entry_writer_ops *ops;
> +	struct arm_smmu_master *master;
> +};
> +
> +struct arm_smmu_entry_writer_ops {
> +	unsigned int num_entry_qwords;
> +	__le64 v_bit;
> +	void (*get_used)(const __le64 *entry, __le64 *used);
> +	void (*sync)(struct arm_smmu_entry_writer *writer);
> +};

Can we avoid the indirection for now, please? I'm sure we'll want it later
when you extend this to CDs, but for the initial support it just makes it
more difficult to follow the flow. Should be a trivial thing to drop, I
hope.

> +static void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
>  {
> +	unsigned int cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ent[0]));
> +
> +	used_bits[0] = cpu_to_le64(STRTAB_STE_0_V);
> +	if (!(ent[0] & cpu_to_le64(STRTAB_STE_0_V)))
> +		return;
> +
> +	/*
> +	 * See 13.5 Summary of attribute/permission configuration fields for the
> +	 * SHCFG behavior. It is only used for BYPASS, including S1DSS BYPASS,
> +	 * and S2 only.
> +	 */
> +	if (cfg == STRTAB_STE_0_CFG_BYPASS ||
> +	    cfg == STRTAB_STE_0_CFG_S2_TRANS ||
> +	    (cfg == STRTAB_STE_0_CFG_S1_TRANS &&
> +	     FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
> +		     STRTAB_STE_1_S1DSS_BYPASS))
> +		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_SHCFG);

Huh, SHCFG is really getting in the way here, isn't it? I think it also
means we don't have a "hitless" transition from stage-2 translation ->
bypass. I'm inclined to leave it set to "use incoming" all the time; the
only difference I can see is if you have stage-2 translation and a
master emitting outer-shareable transactions, in which case they'd now
be outer-shareable instead of inner-shareable, which I think is harmless.

Additionally, it looks like there's an existing buglet here in that we
shouldn't set SHCFG if SMMU_IDR1.ATTR_TYPES_OVR == 0.

> +
> +	used_bits[0] |= cpu_to_le64(STRTAB_STE_0_CFG);
> +	switch (cfg) {
> +	case STRTAB_STE_0_CFG_ABORT:
> +	case STRTAB_STE_0_CFG_BYPASS:
> +		break;
> +	case STRTAB_STE_0_CFG_S1_TRANS:
> +		used_bits[0] |= cpu_to_le64(STRTAB_STE_0_S1FMT |
> +					    STRTAB_STE_0_S1CTXPTR_MASK |
> +					    STRTAB_STE_0_S1CDMAX);
> +		used_bits[1] |=
> +			cpu_to_le64(STRTAB_STE_1_S1DSS | STRTAB_STE_1_S1CIR |
> +				    STRTAB_STE_1_S1COR | STRTAB_STE_1_S1CSH |
> +				    STRTAB_STE_1_S1STALLD | STRTAB_STE_1_STRW);
> +		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_EATS);
> +		used_bits[2] |= cpu_to_le64(STRTAB_STE_2_S2VMID);
> +		break;
> +	case STRTAB_STE_0_CFG_S2_TRANS:
> +		used_bits[1] |=
> +			cpu_to_le64(STRTAB_STE_1_EATS);
> +		used_bits[2] |=
> +			cpu_to_le64(STRTAB_STE_2_S2VMID | STRTAB_STE_2_VTCR |
> +				    STRTAB_STE_2_S2AA64 | STRTAB_STE_2_S2ENDI |
> +				    STRTAB_STE_2_S2PTW | STRTAB_STE_2_S2R);
> +		used_bits[3] |= cpu_to_le64(STRTAB_STE_3_S2TTB_MASK);
> +		break;

With SHCFG fixed, can we go a step further with this and simply identify
the live qwords directly, rather than on a field-by-field basis? I think
we should be able to do the same "hitless" transitions you want with the
coarser granularity.

Will


From geert+renesas at glider.be  Thu Feb 15 05:54:48 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 15 Feb 2024 14:54:48 +0100
Subject: [PATCH v2] ARM: ptrace: Use bitfield helpers
Message-ID: <f73e6deb1bef9696661a62498ee5a56ac9a389ce.1708005130.git.geert+renesas@glider.be>

The isa_mode() macro extracts two fields, and recombines them into a
single value.

Make this more obvious by using the FIELD_GET() helper, and shifting the
result into its final resting place.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
No changes in generated assembler code.

v2:
  - Drop irrelevant comment about non-existing off-by-one error,
  - Remove unnecessary parens.
---
 arch/arm/include/asm/ptrace.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 7f44e88d1f25bcc5..14a38cc67e0bc966 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -10,6 +10,7 @@
 #include <uapi/asm/ptrace.h>
 
 #ifndef __ASSEMBLY__
+#include <linux/bitfield.h>
 #include <linux/types.h>
 
 struct pt_regs {
@@ -35,8 +36,8 @@ struct svc_pt_regs {
 
 #ifndef CONFIG_CPU_V7M
 #define isa_mode(regs) \
-	((((regs)->ARM_cpsr & PSR_J_BIT) >> (__ffs(PSR_J_BIT) - 1)) | \
-	 (((regs)->ARM_cpsr & PSR_T_BIT) >> (__ffs(PSR_T_BIT))))
+	(FIELD_GET(PSR_J_BIT, (regs)->ARM_cpsr) << 1 | \
+	 FIELD_GET(PSR_T_BIT, (regs)->ARM_cpsr))
 #else
 #define isa_mode(regs) 1 /* Thumb */
 #endif
-- 
2.34.1



From masahiroy at kernel.org  Thu Feb 15 05:55:25 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Thu, 15 Feb 2024 22:55:25 +0900
Subject: [PATCH] ARM: remove unneeded entry for CONFIG_FRAME_POINTER
Message-ID: <20240215135525.1909606-1-masahiroy@kernel.org>

This is no-op.

FRAME_POINTER is defined in lib/Kconfig.debug.

Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
---

KernelVersion: v6.8-rc1

 arch/arm/Kconfig.debug | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 5fbbac1b708b..7374483591f6 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -90,9 +90,6 @@ config BACKTRACE_VERBOSE
 	  In most cases, say N here, unless you are intending to debug the
 	  kernel and have access to the kernel binary image.
 
-config FRAME_POINTER
-	bool
-
 config DEBUG_USER
 	bool "Verbose user fault messages"
 	help
-- 
2.40.1



From srinivas.goud at amd.com  Thu Feb 15 05:59:33 2024
From: srinivas.goud at amd.com (Goud, Srinivas)
Date: Thu, 15 Feb 2024 13:59:33 +0000
Subject: [PATCH v8 0/3] Add ECC feature support to Tx and Rx FIFOs for
 Xilinx CAN Controller.
In-Reply-To: <20240213-xilinx_ecc-v8-0-8d75f8b80771@pengutronix.de>
References: <20240213-xilinx_ecc-v8-0-8d75f8b80771@pengutronix.de>
Message-ID: <PH8PR12MB6675AAAC5D7A86D2CAA382D6E14D2@PH8PR12MB6675.namprd12.prod.outlook.com>

Hi Marc,

>-----Original Message-----
>From: Marc Kleine-Budde <mkl at pengutronix.de>
>Sent: Tuesday, February 13, 2024 4:07 PM
>To: Appana Durga Kedareswara rao <appana.durga.rao at xilinx.com>; Naga
>Sureshkumar Relli <naga.sureshkumar.relli at xilinx.com>; Wolfgang Grandegger
><wg at grandegger.com>; Marc Kleine-Budde <mkl at pengutronix.de>; David S.
>Miller <davem at davemloft.net>; Eric Dumazet <edumazet at google.com>;
>Jakub Kicinski <kuba at kernel.org>; Paolo Abeni <pabeni at redhat.com>; Rob
>Herring <robh+dt at kernel.org>; Krzysztof Kozlowski
><krzysztof.kozlowski+dt at linaro.org>; Conor Dooley <conor+dt at kernel.org>;
>Simek, Michal <michal.simek at amd.com>
>Cc: linux-can at vger.kernel.org; netdev at vger.kernel.org;
>devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
>kernel at vger.kernel.org; Goud, Srinivas <srinivas.goud at amd.com>; Conor
>Dooley <conor.dooley at microchip.com>
>Subject: [PATCH v8 0/3] Add ECC feature support to Tx and Rx FIFOs for Xilinx
>CAN Controller.
>
>ECC is an IP configuration option where counter registers are added in IP for
>1bit/2bit ECC errors count and reset.
>
>Also driver reports 1bit/2bit ECC errors for FIFOs based on ECC error interrupts.
>
>Add xlnx,has-ecc optional property for Xilinx AXI CAN controller to support ECC
>if the ECC block is enabled in the HW.
>
>Add ethtool stats interface for getting all the ECC errors information.
>
>There is no public documentation for it available.
>
>Changes in v8:
>- Use u64_stats_sync instead of spinlock
>- Renamed stats strings: use "_" instead of "-"
>- Renamed stats strings: add "_errors" trailer
>- Renamed stats variables similar to stats strings
>
>Changes in v7:
>- Update with spinlock only for stats counters
>
>Changes in v6:
>- Update commit description
>
>Changes in v5:
>- Fix review comments
>- Change the sequence of updates the stats
>- Add get_strings and get_sset_count stats interface
>- Use u64 stats helper function
>
>Changes in v4:
>- Fix DT binding check warning
>- Update xlnx,has-ecc property description
>
>Changes in v3:
>- Update mailing list
>- Update commit description
>
>Changes in v2:
>- Address review comments
>- Add ethtool stats interface
>- Update commit description
>
>---
>Srinivas Goud (3):
>      dt-bindings: can: xilinx_can: Add 'xlnx,has-ecc' optional property
>      can: xilinx_can: Add ECC support
>      can: xilinx_can: Add ethtool stats interface for ECC errors
>
> .../devicetree/bindings/net/can/xilinx,can.yaml    |   5 +
> drivers/net/can/xilinx_can.c                       | 169 ++++++++++++++++++++-
> 2 files changed, 170 insertions(+), 4 deletions(-)
>---
>base-commit: a3522a2edb3faf8cb98d38c2a99f5967beef24e2
>change-id: 20240213-xilinx_ecc-8310f5556010
>
>Best regards,
>--
>Marc Kleine-Budde <mkl at pengutronix.de>
>

Thanks, tested with v8 changes, it is working fine.

Thanks,
Srinivas

From josua at solid-run.com  Thu Feb 15 06:04:17 2024
From: josua at solid-run.com (Josua Mayer)
Date: Thu, 15 Feb 2024 15:04:17 +0100
Subject: [PATCH v6 2/7] dt-bindings: rtc: abx80x: convert to yaml
In-Reply-To: <2024021220055301ade3d4@mail.local>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
 <20240212-add-am64-som-v6-2-b59edb2bc8c3@solid-run.com>
 <2024021220055301ade3d4@mail.local>
Message-ID: <48f04999-687e-41d5-a0c0-0cfed481dc50@solid-run.com>

Am 12.02.24 um 21:06 schrieb Alexandre Belloni:
> On 12/02/2024 18:38:09+0100, Josua Mayer wrote:
>> Convert the abracon abx80x rtc text bindings to dt-schema format.
>>
>> In addition to the text description reference generic interrupts
>> properties and add an example.
>>
>> Signed-off-by: Josua Mayer <josua at solid-run.com>
> Did something change since v6? If not, why didn't you collect the
> reviewed-by tag?
I forgot about seeing the tag by Krzysztof ... which is why I didn't 
collect it.
Nothing changed since v6, so this still valid:

Reviewed-by: Krzysztof Kozlowski<krzysztof.kozlowski at linaro.org>

>
>> ---
>>   .../devicetree/bindings/rtc/abracon,abx80x.txt     | 31 ---------
>>   .../devicetree/bindings/rtc/abracon,abx80x.yaml    | 79 ++++++++++++++++++++++
>>   2 files changed, 79 insertions(+), 31 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt b/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
>> deleted file mode 100644
>> index 2405e35a1bc0..000000000000
>> --- a/Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
>> +++ /dev/null
>> @@ -1,31 +0,0 @@
>> -Abracon ABX80X I2C ultra low power RTC/Alarm chip
>> -
>> -The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
>> -ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
>> -is the superset of ab180x.
>> -
>> -Required properties:
>> -
>> - - "compatible": should one of:
>> -        "abracon,abx80x"
>> -        "abracon,ab0801"
>> -        "abracon,ab0803"
>> -        "abracon,ab0804"
>> -        "abracon,ab0805"
>> -        "abracon,ab1801"
>> -        "abracon,ab1803"
>> -        "abracon,ab1804"
>> -        "abracon,ab1805"
>> -        "microcrystal,rv1805"
>> -	Using "abracon,abx80x" will enable chip autodetection.
>> - - "reg": I2C bus address of the device
>> -
>> -Optional properties:
>> -
>> -The abx804 and abx805 have a trickle charger that is able to charge the
>> -connected battery or supercap. Both the following properties have to be defined
>> -and valid to enable charging:
>> -
>> - - "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
>> - - "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
>> -                          resistor, the other values are in kOhm.
>> diff --git a/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
>> new file mode 100644
>> index 000000000000..58dbbca27deb
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/rtc/abracon,abx80x.yaml
>> @@ -0,0 +1,79 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/rtc/abracon,abx80x.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Abracon ABX80X I2C ultra low power RTC/Alarm chip
>> +
>> +maintainers:
>> +  - linux-rtc at vger.kernel.org
>> +
>> +allOf:
>> +  - $ref: rtc.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    description:
>> +      The wildcard 'abracon,abx80x' may be used to support a mix
>> +      of different abracon rtc`s. In this case the driver
>> +      must perform auto-detection from ID register.
>> +    enum:
>> +      - abracon,abx80x
>> +      - abracon,ab0801
>> +      - abracon,ab0803
>> +      - abracon,ab0804
>> +      - abracon,ab0805
>> +      - abracon,ab1801
>> +      - abracon,ab1803
>> +      - abracon,ab1804
>> +      - abracon,ab1805
>> +      - microcrystal,rv1805
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  abracon,tc-diode:
>> +    description:
>> +      Trickle-charge diode type.
>> +      Required to enable charging backup battery.
>> +
>> +      Supported are 'standard' diodes with a 0.6V drop
>> +      and 'schottky' diodes with a 0.3V drop.
>> +    $ref: /schemas/types.yaml#/definitions/string
>> +    enum:
>> +      - standard
>> +      - schottky
>> +
>> +  abracon,tc-resistor:
>> +    description:
>> +      Trickle-charge resistor value in kOhm.
>> +      Required to enable charging backup battery.
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    enum: [0, 3, 6, 11]
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/interrupt-controller/irq.h>
>> +
>> +    i2c {
>> +        #address-cells = <1>;
>> +        #size-cells = <0>;
>> +
>> +        rtc at 69 {
>> +            compatible = "abracon,abx80x";
>> +            reg = <0x69>;
>> +            abracon,tc-diode = "schottky";
>> +            abracon,tc-resistor = <3>;
>> +            interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
>> +        };
>> +    };
>>
>> -- 
>> 2.35.3
>>


From robh at kernel.org  Thu Feb 15 06:06:38 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 08:06:38 -0600
Subject: [PATCH 01/22] dt-bindings: gpio: Add binding for ChromeOS EC
 GPIO controller
In-Reply-To: <20240210070934.2549994-2-swboyd@chromium.org>
References: <20240210070934.2549994-1-swboyd@chromium.org>
 <20240210070934.2549994-2-swboyd@chromium.org>
Message-ID: <20240215140638.GA4162082-robh@kernel.org>

On Fri, Feb 09, 2024 at 11:09:12PM -0800, Stephen Boyd wrote:
> The ChromeOS embedded controller (EC) supports setting the state of
> GPIOs when the system is unlocked, and getting the state of GPIOs in all
> cases. The GPIOs are on the EC itself, so the EC acts similar to a GPIO
> expander. Add a binding to describe these GPIOs in DT so that other
> devices described in DT can read the GPIOs on the EC.
> 
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: Bartosz Golaszewski <brgl at bgdev.pl>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Lee Jones <lee at kernel.org>
> Cc: Benson Leung <bleung at chromium.org>
> Cc: Guenter Roeck <groeck at chromium.org>
> Cc: <linux-gpio at vger.kernel.org>
> Cc: <devicetree at vger.kernel.org>
> Cc: <chrome-platform at lists.linux.dev>
> Cc: Pin-yen Lin <treapking at chromium.org>
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>
> ---
>  .../bindings/gpio/google,cros-ec-gpio.yaml    | 49 +++++++++++++++++++
>  .../bindings/mfd/google,cros-ec.yaml          |  3 ++
>  2 files changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/google,cros-ec-gpio.yaml
> 
> diff --git a/Documentation/devicetree/bindings/gpio/google,cros-ec-gpio.yaml b/Documentation/devicetree/bindings/gpio/google,cros-ec-gpio.yaml
> new file mode 100644
> index 000000000000..a9f1d7784070
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/google,cros-ec-gpio.yaml
> @@ -0,0 +1,49 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/gpio/google,cros-ec-gpio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: GPIOs controlled by ChromeOS EC
> +
> +maintainers:
> +  - Stephen Boyd <swboyd at chromium.org>
> +
> +description:
> +  Google's ChromeOS EC has a gpio controller inside the Embedded Controller
> +  (EC) and controlled via a host-command interface. The node for this
> +  device should be under a cros-ec node like google,cros-ec-spi.

Why do we need a child node here? 

Rob


From afd at ti.com  Thu Feb 15 06:19:57 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 15 Feb 2024 08:19:57 -0600
Subject: [PATCH] arm64: dts: ti: k3-j721e: Fix mux-reg-masks in hbmc_mux
Message-ID: <20240215141957.13775-1-afd@ti.com>

Change offset in mux-reg-masks property for hbmc_mux node
since reg-mux property is used in compatible.

While here, update the reg region to include 4 bytes as this
is a 32bit register.

Fixes: 2765149273f4 ("mux: mmio: use reg property when parent device is not a syscon")
Suggested-by: Peter Rosin <peda at axentia.se>
Signed-off-by: Andrew Davis <afd at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
index 40caa86e600fe..4618b697fbc47 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
@@ -353,9 +353,9 @@ fss: bus at 47000000 {
 
 		hbmc_mux: mux-controller at 47000004 {
 			compatible = "reg-mux";
-			reg = <0x00 0x47000004 0x00 0x2>;
+			reg = <0x00 0x47000004 0x00 0x4>;
 			#mux-control-cells = <1>;
-			mux-reg-masks = <0x4 0x2>; /* HBMC select */
+			mux-reg-masks = <0x0 0x2>; /* HBMC select */
 		};
 
 		hbmc: hyperbus at 47034000 {
-- 
2.39.2



From afd at ti.com  Thu Feb 15 06:26:46 2024
From: afd at ti.com (Andrew Davis)
Date: Thu, 15 Feb 2024 08:26:46 -0600
Subject: [PATCH] arm64: dts: ti: k3-am654: Drop ti,syscon-rgmii-delay from
 ICSSG nodes
In-Reply-To: <20240215105407.2868266-1-danishanwar@ti.com>
References: <20240215105407.2868266-1-danishanwar@ti.com>
Message-ID: <e78406a7-189a-4847-8625-2a66dce818b5@ti.com>

On 2/15/24 4:54 AM, MD Danish Anwar wrote:
> Drop ti,syscon-rgmii-delay from ICSSG0, ICSSG1 and ICSSG2 node as this
> property is no longer used by ICSSG driver.
> 

I see a couple more instances in k3-am65-iot2050-common.dtsi.

Andrew

> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> ---
>   arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso | 2 --
>   arch/arm64/boot/dts/ti/k3-am654-idk.dtso    | 4 ----
>   2 files changed, 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso b/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
> index 0a6e75265ba9..bb0e29873df7 100644
> --- a/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
> +++ b/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
> @@ -68,7 +68,6 @@ icssg2_emac0: port at 0 {
>   				reg = <0>;
>   				phy-handle = <&icssg2_phy0>;
>   				phy-mode = "rgmii-id";
> -				ti,syscon-rgmii-delay = <&scm_conf 0x4120>;
>   				/* Filled in by bootloader */
>   				local-mac-address = [00 00 00 00 00 00];
>   			};
> @@ -76,7 +75,6 @@ icssg2_emac1: port at 1 {
>   				reg = <1>;
>   				phy-handle = <&icssg2_phy1>;
>   				phy-mode = "rgmii-id";
> -				ti,syscon-rgmii-delay = <&scm_conf 0x4124>;
>   				/* Filled in by bootloader */
>   				local-mac-address = [00 00 00 00 00 00];
>   			};
> diff --git a/arch/arm64/boot/dts/ti/k3-am654-idk.dtso b/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
> index 8bdb87fcbde0..d4bc80032587 100644
> --- a/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
> +++ b/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
> @@ -72,7 +72,6 @@ icssg0_emac0: port at 0 {
>   				reg = <0>;
>   				phy-handle = <&icssg0_phy0>;
>   				phy-mode = "rgmii-id";
> -				ti,syscon-rgmii-delay = <&scm_conf 0x4100>;
>   				/* Filled in by bootloader */
>   				local-mac-address = [00 00 00 00 00 00];
>   			};
> @@ -80,7 +79,6 @@ icssg0_emac1: port at 1 {
>   				reg = <1>;
>   				phy-handle = <&icssg0_phy1>;
>   				phy-mode = "rgmii-id";
> -				ti,syscon-rgmii-delay = <&scm_conf 0x4104>;
>   				/* Filled in by bootloader */
>   				local-mac-address = [00 00 00 00 00 00];
>   			};
> @@ -140,7 +138,6 @@ icssg1_emac0: port at 0 {
>   				reg = <0>;
>   				phy-handle = <&icssg1_phy0>;
>   				phy-mode = "rgmii-id";
> -				ti,syscon-rgmii-delay = <&scm_conf 0x4110>;
>   				/* Filled in by bootloader */
>   				local-mac-address = [00 00 00 00 00 00];
>   			};
> @@ -148,7 +145,6 @@ icssg1_emac1: port at 1 {
>   				reg = <1>;
>   				phy-handle = <&icssg1_phy1>;
>   				phy-mode = "rgmii-id";
> -				ti,syscon-rgmii-delay = <&scm_conf 0x4114>;
>   				/* Filled in by bootloader */
>   				local-mac-address = [00 00 00 00 00 00];
>   			};


From robh at kernel.org  Thu Feb 15 06:28:36 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 08:28:36 -0600
Subject: [PATCH v4 16/20] dt-bindings: crypto: meson: support new SoC's
In-Reply-To: <20240212135108.549755-17-avromanov@salutedevices.com>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <20240212135108.549755-17-avromanov@salutedevices.com>
Message-ID: <20240215142836.GA1186-robh@kernel.org>

On Mon, Feb 12, 2024 at 04:51:04PM +0300, Alexey Romanov wrote:
> Now crypto module available at G12A/G12B/S4/A1/SM1/AXG.
> 
> 1. Add new compatibles:
>   - amlogic,g12a-crypto
>   - amlogic,s4-crypto (uses g12a-crypto as fallback)
>   - amlogic,a1-crypto (uses g12a-crypto as fallback)
>   - amlogic,axg-crypto
> 
> 2. All SoC's, exclude GXL, doesn't take a clock input for
> Crypto IP. Make it required only for amlogic,gxl-crypto.
> 
> 3. All SoC's, exclude GXL, uses only one interrupt flow
> for Crypto IP.
> 
> 4. Add power-domains in schema.
> 
> Signed-off-by: Alexey Romanov <avromanov at salutedevices.com>
> ---
>  .../bindings/crypto/amlogic,gxl-crypto.yaml   | 43 ++++++++++++++++---
>  1 file changed, 36 insertions(+), 7 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
> index 948e11ebe4ee..41f0153d58c8 100644
> --- a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
> +++ b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
> @@ -11,20 +11,30 @@ maintainers:
>  
>  properties:
>    compatible:
> -    items:
> -      - const: amlogic,gxl-crypto
> +    oneOf:
> +      - items:
> +          - enum:
> +              - amlogic,a1-crypto
> +              - amlogic,s4-crypto
> +          - const: amlogic,g12a-crypto
> +      - enum:
> +          - amlogic,gxl-crypto
> +          - amlogic,axg-crypto
> +          - amlogic,g12a-crypto
>  
>    reg:
>      maxItems: 1
>  
>    interrupts:
> -    items:
> -      - description: Interrupt for flow 0
> -      - description: Interrupt for flow 1
> +    minItems: 1
> +    maxItems: 2

Just keep the descrptions here and add 'minItems: 1'. Then in the 
if/then schema, you only need minItems and maxItems to require 1 or 2 
interrupts.

>  
>    clocks:
>      maxItems: 1
>  
> +  power-domains:
> +    maxItems: 1
> +
>    clock-names:
>      const: blkmv
>  
> @@ -32,8 +42,27 @@ required:
>    - compatible
>    - reg
>    - interrupts
> -  - clocks
> -  - clock-names

New chips work without clocks? Cool!

Rob


From robh at kernel.org  Thu Feb 15 06:32:07 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 08:32:07 -0600
Subject: [PATCH v6 3/7] dt-bindings: iio: humidity: hdc20x0: add optional
 interrupts property
In-Reply-To: <20240212-add-am64-som-v6-3-b59edb2bc8c3@solid-run.com>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
 <20240212-add-am64-som-v6-3-b59edb2bc8c3@solid-run.com>
Message-ID: <170800752707.10493.10095025505089429224.robh@kernel.org>


On Mon, 12 Feb 2024 18:38:10 +0100, Josua Mayer wrote:
> HDC2010 and HDC2080 humidity sensors both have an interrupt / data-ready
> signal which can be used for signaling to the host.
> 
> Add binding for "interrupts" property so that boards wiring this signal
> may describe the connection.
> 
> Signed-off-by: Josua Mayer <josua at solid-run.com>
> ---
>  Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>



From robh at kernel.org  Thu Feb 15 06:32:33 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 08:32:33 -0600
Subject: [PATCH v6 4/7] dt-bindings: mtd: spi-nor: add optional
 interrupts property
In-Reply-To: <20240212-add-am64-som-v6-4-b59edb2bc8c3@solid-run.com>
References: <20240212-add-am64-som-v6-0-b59edb2bc8c3@solid-run.com>
 <20240212-add-am64-som-v6-4-b59edb2bc8c3@solid-run.com>
Message-ID: <170800755249.11056.3790121633736757728.robh@kernel.org>


On Mon, 12 Feb 2024 18:38:11 +0100, Josua Mayer wrote:
> Some spi flash memories have an interrupt signal which can be used for
> signalling on-chip events such as busy status or ecc errors to the host.
> 
> Add binding for "interrupts" property so that boards wiring this signal
> may describe the connection.
> 
> Signed-off-by: Josua Mayer <josua at solid-run.com>
> ---
>  Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>



From robh at kernel.org  Thu Feb 15 06:35:21 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 08:35:21 -0600
Subject: [PATCH v2 01/17] dt-bindings: pinctrl: fsl,imx6ul-pinctrl:
 convert to YAML
In-Reply-To: <20240213010347.1075251-2-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-2-sre@kernel.org>
Message-ID: <170800772112.14828.3515005867069429971.robh@kernel.org>


On Tue, 13 Feb 2024 02:00:50 +0100, Sebastian Reichel wrote:
> Convert i.MX6UL pinctrl bindings to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt   |  37 ------
>  .../bindings/pinctrl/fsl,imx6ul-pinctrl.yaml  | 116 ++++++++++++++++++
>  2 files changed, 116 insertions(+), 37 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From robh at kernel.org  Thu Feb 15 06:36:49 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 08:36:49 -0600
Subject: [PATCH v2 04/17] dt-bindings: input: touchscreen: fsl,imx6ul-tsc
 convert to YAML
In-Reply-To: <20240213010347.1075251-5-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-5-sre@kernel.org>
Message-ID: <170800780830.16408.1737410902557011444.robh@kernel.org>


On Tue, 13 Feb 2024 02:00:53 +0100, Sebastian Reichel wrote:
> Convert the i.MX6UL touchscreen DT binding to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../input/touchscreen/fsl,imx6ul-tsc.yaml     | 97 +++++++++++++++++++
>  .../bindings/input/touchscreen/imx6ul_tsc.txt | 38 --------
>  2 files changed, 97 insertions(+), 38 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
>  delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From eauger at redhat.com  Thu Feb 15 06:42:05 2024
From: eauger at redhat.com (Eric Auger)
Date: Thu, 15 Feb 2024 15:42:05 +0100
Subject: [PATCH v4 4/5] KVM: selftests: aarch64: Introduce
 pmu_event_filter_test
In-Reply-To: <ZbypAAFEHweTDUJK@linux.dev>
References: <20240202025659.5065-1-shahuang@redhat.com>
 <20240202025659.5065-5-shahuang@redhat.com> <ZbypAAFEHweTDUJK@linux.dev>
Message-ID: <a456cae7-037a-4e11-979b-a7bacc0fe850@redhat.com>

Hi Shaoqin,

On 2/2/24 09:34, Oliver Upton wrote:
> On Thu, Feb 01, 2024 at 09:56:53PM -0500, Shaoqin Huang wrote:
>> Introduce pmu_event_filter_test for arm64 platforms. The test configures
>> PMUv3 for a vCPU, and sets different pmu event filters for the vCPU, and
>> check if the guest can see those events which user allow and can't use
>> those events which use deny.
>>
>> This test refactor the create_vpmu_vm() and make it a wrapper for
>> __create_vpmu_vm(), which allows some extra init code before
>> KVM_ARM_VCPU_PMU_V3_INIT.
>>
>> And this test use the KVM_ARM_VCPU_PMU_V3_FILTER attribute to set the
>> pmu event filter in KVM. And choose to filter two common event
>> branches_retired and instructions_retired, and let the guest to check if
>> it see the right pmceid register.
>>
>> Signed-off-by: Shaoqin Huang <shahuang at redhat.com>
>> ---
>>  tools/testing/selftests/kvm/Makefile          |   1 +
>>  .../kvm/aarch64/pmu_event_filter_test.c       | 219 ++++++++++++++++++
>>  .../selftests/kvm/include/aarch64/vpmu.h      |   4 +
>>  .../testing/selftests/kvm/lib/aarch64/vpmu.c  |  14 +-
>>  4 files changed, 236 insertions(+), 2 deletions(-)
>>  create mode 100644 tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
>>
>> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
>> index 709a70b31ca2..733ec86a3385 100644
>> --- a/tools/testing/selftests/kvm/Makefile
>> +++ b/tools/testing/selftests/kvm/Makefile
>> @@ -148,6 +148,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
>>  TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
>>  TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
>>  TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
>> +TEST_GEN_PROGS_aarch64 += aarch64/pmu_event_filter_test
>>  TEST_GEN_PROGS_aarch64 += aarch64/psci_test
>>  TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs
>>  TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter
>> diff --git a/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
>> new file mode 100644
>> index 000000000000..d280382f362f
>> --- /dev/null
>> +++ b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
>> @@ -0,0 +1,219 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * pmu_event_filter_test - Test user limit pmu event for guest.
>> + *
>> + * Copyright (c) 2023 Red Hat, Inc.
>> + *
>> + * This test checks if the guest only see the limited pmu event that userspace
>> + * sets, if the guest can use those events which user allow, and if the guest
>> + * can't use those events which user deny.
>> + * This test runs only when KVM_CAP_ARM_PMU_V3, KVM_ARM_VCPU_PMU_V3_FILTER
>> + * is supported on the host.
>> + */
>> +#include <kvm_util.h>
>> +#include <processor.h>
>> +#include <vgic.h>
>> +#include <vpmu.h>
>> +#include <test_util.h>
>> +#include <perf/arm_pmuv3.h>
>> +
>> +struct pmce{
> 
> Missing whitespace before curly brace.
> 
> Also -- pmce is an odd name. Maybe common_event_ids or pmu_id_regs.
> 
>> +	uint64_t pmceid0;
>> +	uint64_t pmceid1;
>> +} supported_pmce, guest_pmce;
> 
> maybe "max_*" and "expected_*". It took me a bit to understand that
> guest_pmce feeds in your expected PMCEID values.
> 
>> +static struct vpmu_vm *vpmu_vm;
>> +
>> +#define FILTER_NR 10
>> +
>> +struct test_desc {
>> +	const char *name;
>> +	struct kvm_pmu_event_filter filter[FILTER_NR];
>> +};
>> +
>> +#define __DEFINE_FILTER(base, num, act)		\
>> +	((struct kvm_pmu_event_filter) {	\
>> +		.base_event	= base,		\
>> +		.nevents	= num,		\
>> +		.action		= act,		\
>> +	})
>> +
>> +#define DEFINE_FILTER(base, act) __DEFINE_FILTER(base, 1, act)
>> +
>> +#define EMPTY_FILTER	{ 0 }
>> +
>> +#define SW_INCR		0x0
>> +#define INST_RETIRED	0x8
>> +#define BR_RETIRED	0x21
> 
> These event numbers are already defined in tools/include/perf/arm_pmuv3.h,
> use those instead.
> 
>> +static void guest_code(void)
>> +{
>> +	uint64_t pmceid0 = read_sysreg(pmceid0_el0);
>> +	uint64_t pmceid1 = read_sysreg(pmceid1_el0);
>> +
>> +	GUEST_ASSERT_EQ(guest_pmce.pmceid0, pmceid0);
>> +	GUEST_ASSERT_EQ(guest_pmce.pmceid1, pmceid1);
>> +
>> +	GUEST_DONE();
>> +}
>> +
>> +static void guest_get_pmceid(void)
>> +{
>> +	supported_pmce.pmceid0 = read_sysreg(pmceid0_el0);
>> +	supported_pmce.pmceid1 = read_sysreg(pmceid1_el0);
>> +
>> +	GUEST_DONE();
>> +}
>> +
>> +static void pmu_event_filter_init(struct vpmu_vm *vm, void *arg)
> 
> Why are you obfuscating the pointer to the filter array?
> 
>> +{
>> +	struct kvm_device_attr attr = {
>> +		.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
>> +		.attr	= KVM_ARM_VCPU_PMU_V3_FILTER,
>> +	};
>> +	struct kvm_pmu_event_filter *filter = (struct kvm_pmu_event_filter *)arg;
>> +
>> +	while (filter && filter->nevents != 0) {
>> +		attr.addr = (uint64_t)filter;
>> +		vcpu_ioctl(vm->vcpu, KVM_SET_DEVICE_ATTR, &attr);
> 
> Again, kvm_device_attr_set() the right helper to use.
> 
>> +static void set_pmce(struct pmce *pmce, int action, int event)
>> +{
>> +	int base = 0;
>> +	uint64_t *pmceid = NULL;
>> +
>> +	if (event >= 0x4000) {
>> +		event -= 0x4000;
>> +		base = 32;
>> +	}
>> +
>> +	if (event >= 0 && event <= 0x1F) {
>> +		pmceid = &pmce->pmceid0;
>> +	} else if (event >= 0x20 && event <= 0x3F) {
>> +		event -= 0x20;
>> +		pmceid = &pmce->pmceid1;
>> +	} else {
>> +		return;
>> +	}
>> +
>> +	event += base;
>> +	if (action == KVM_PMU_EVENT_ALLOW)
>> +		*pmceid |= BIT(event);
>> +	else
>> +		*pmceid &= ~BIT(event);
>> +}
>> +
>> +static void prepare_guest_pmce(struct kvm_pmu_event_filter *filter)
>> +{
>> +	struct pmce pmce_mask = { ~0, ~0 };
>> +	bool first_filter = true;
>> +
>> +	while (filter && filter->nevents != 0) {
>> +		if (first_filter) {
>> +			if (filter->action == KVM_PMU_EVENT_ALLOW)
>> +				memset(&pmce_mask, 0, sizeof(pmce_mask));
>> +			first_filter = false;
>> +		}
>> +
>> +		set_pmce(&pmce_mask, filter->action, filter->base_event);
>> +		filter++;
>> +	}
>> +
>> +	guest_pmce.pmceid0 = supported_pmce.pmceid0 & pmce_mask.pmceid0;
>> +	guest_pmce.pmceid1 = supported_pmce.pmceid1 & pmce_mask.pmceid1;
>> +}
> 
> Why do you need to do this? Can't you tell the guests what events to
> expect and have it make sense of the PMCEID values it sees?
> 
> You could, for example, pass in a pointer to the test descriptor as an
> argument.
> 
>> +static void run_test(struct test_desc *t)
>> +{
>> +	pr_debug("Test: %s\n", t->name);
> 
> You may as well just pr_info() this thing.
> 
>> +	create_vpmu_vm_with_filter(guest_code, t->filter);
>> +	prepare_guest_pmce(t->filter);
>> +	sync_global_to_guest(vpmu_vm->vm, guest_pmce);
>> +
>> +	run_vcpu(vpmu_vm->vcpu);
>> +
>> +	destroy_vpmu_vm(vpmu_vm);
>> +}
>> +
>> +static struct test_desc tests[] = {
>> +	{"without_filter", { EMPTY_FILTER }},
>> +	{"member_allow_filter",
>> +	 {DEFINE_FILTER(SW_INCR, 0), DEFINE_FILTER(INST_RETIRED, 0),
>> +	  DEFINE_FILTER(BR_RETIRED, 0), EMPTY_FILTER}},
>> +	{"member_deny_filter",
>> +	 {DEFINE_FILTER(SW_INCR, 1), DEFINE_FILTER(INST_RETIRED, 1),
>> +	  DEFINE_FILTER(BR_RETIRED, 1), EMPTY_FILTER}},
>> +	{"not_member_deny_filter",
>> +	 {DEFINE_FILTER(SW_INCR, 1), EMPTY_FILTER}},
>> +	{"not_member_allow_filter",
>> +	 {DEFINE_FILTER(SW_INCR, 0), EMPTY_FILTER}},
from a strict uapi testing you are not testing
- "Cancelling" a filter by registering the opposite action for the same
range doesn't change the default action.
- Event 0 (SW_INCR)
- Filtering event 0x1E (CHAIN) has no effect either
- Filtering the cycle counter is possible using event 0x11 (CPU_CYCLES).

Documentation/virt/kvm/devices/vcpu.rst

Then it obviously depends on how much coverage of the API you want/can
afford to reach.

Eric

> 
> Why is the filter array special enough to get its own sentinel macro
> but...
> 
>> +	{ 0 }
> 
> ... the test descriptor array is okay to use a 'raw' initialization. My
> vote is to drop the macro, zero-initializing a struct in an array is an
> extremely common pattern in the kernel.
> 
> Also, these descriptors are dense and hard to read. Working with an
> example:
> 
> 	{
> 		.name = "member_allow_filter",
> 		.filter = {
> 			DEFINE_FILTER(SW_INCR, 0),
> 			DEFINE_FILTER(INST_RETIRED, 0),
> 			DEFINE_FILTER(BR_RETIRED, 0),
> 			{ 0 }
> 		},
> 	}
> 
> See how much more readable that is?
> 
>> +};
>> +
>> +static void for_each_test(void)
>> +{
>> +	struct test_desc *t;
>> +
>> +	for (t = &tests[0]; t->name; t++)
>> +		run_test(t);
>> +}
> 
> for_each_test() sounds like an iterator, but this is not. Call it
> run_tests()
> 
>> +static bool kvm_supports_pmu_event_filter(void)
>> +{
>> +	int r;
>> +
>> +	vpmu_vm = create_vpmu_vm(guest_code);
>> +
>> +	r = __kvm_has_device_attr(vpmu_vm->vcpu->fd, KVM_ARM_VCPU_PMU_V3_CTRL,
>> +				  KVM_ARM_VCPU_PMU_V3_FILTER);
>> +
>> +	destroy_vpmu_vm(vpmu_vm);
>> +	return !r;
>> +}
> 
> TBH, I don't really care much about the test probing for the event
> filter UAPI. It has been upstream for a while, and if folks are trying
> to run selftests at HEAD on an old kernel then that's their business.
> 
> The other prerequisites make more sense since they actually check if HW
> features are present.
> 
>> +static bool host_pmu_supports_events(void)
>> +{
>> +	vpmu_vm = create_vpmu_vm(guest_get_pmceid);
>> +
>> +	memset(&supported_pmce, 0, sizeof(supported_pmce));
>> +	sync_global_to_guest(vpmu_vm->vm, supported_pmce);
>> +	run_vcpu(vpmu_vm->vcpu);
>> +	sync_global_from_guest(vpmu_vm->vm, supported_pmce);
>> +	destroy_vpmu_vm(vpmu_vm);
>> +
>> +	return supported_pmce.pmceid0 & (BR_RETIRED | INST_RETIRED);
>> +}
> 
> This helper says its probing the host PMU, but you're actually firing up a
> VM to do it.
> 
> The events supported by a particular PMU instance are readily available
> in sysfs. Furthermore, you can tell KVM to select the exact host PMU
> instance you probe.
> 
>> diff --git a/tools/testing/selftests/kvm/lib/aarch64/vpmu.c b/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
>> index b3de8fdc555e..76ea03d607f1 100644
>> --- a/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
>> +++ b/tools/testing/selftests/kvm/lib/aarch64/vpmu.c
>> @@ -7,8 +7,9 @@
>>  #include <vpmu.h>
>>  #include <perf/arm_pmuv3.h>
>>  
>> -/* Create a VM that has one vCPU with PMUv3 configured. */
>> -struct vpmu_vm *create_vpmu_vm(void *guest_code)
>> +struct vpmu_vm *__create_vpmu_vm(void *guest_code,
>> +				 void (*init_pmu)(struct vpmu_vm *vm, void *arg),
>> +				 void *arg)
>>  {
>>  	struct kvm_vcpu_init init;
>>  	uint8_t pmuver;
>> @@ -50,12 +51,21 @@ struct vpmu_vm *create_vpmu_vm(void *guest_code)
>>  		    "Unexpected PMUVER (0x%x) on the vCPU with PMUv3", pmuver);
>>  
>>  	/* Initialize vPMU */
>> +	if (init_pmu)
>> +		init_pmu(vpmu_vm, arg);
>> +
>>  	vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &irq_attr);
>>  	vcpu_ioctl(vpmu_vm->vcpu, KVM_SET_DEVICE_ATTR, &init_attr);
>>  
>>  	return vpmu_vm;
>>  }
>>  
>> +/* Create a VM that has one vCPU with PMUv3 configured. */
>> +struct vpmu_vm *create_vpmu_vm(void *guest_code)
>> +{
>> +	return __create_vpmu_vm(guest_code, NULL, NULL);
>> +}
>> +
> 
> Ok. This completely proves my point in the other patch. You already need
> to refactor this helper to cram in what you're trying to do. Think of
> ways to move the code that is actually common into libraries and leave
> the rest to the tests themselves.
> 
> Some slight code duplication isn't the end of the world if it avoids
> churning libraries every time someone wants to add a widget.
> 

Eric



From dmitry.baryshkov at linaro.org  Thu Feb 15 06:42:00 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 15 Feb 2024 16:42:00 +0200
Subject: [PATCH RFC v3 3/4] spmi: pmic-arb: Make core resources acquiring
 a version operation
In-Reply-To: <Zc4SWIViTS0uf952@linaro.org>
References: <20240214-spmi-multi-master-support-v3-0-0bae0ef04faf@linaro.org>
 <20240214-spmi-multi-master-support-v3-3-0bae0ef04faf@linaro.org>
 <d9d8e86b-a499-49d1-90ad-6fae5b7dcbb7@linaro.org> <Zc0yXR/fC2OcObLB@linaro.org>
 <CAA8EJpq=kYeZfNbFtfQ_oLS0Xi4imyEGV+dDNO+h6LZfqmpxZg@mail.gmail.com> <Zc4SWIViTS0uf952@linaro.org>
Message-ID: <CAA8EJpqOd1Sz_538ZwhPh+AesVRBRmzMiQ0ntsvm4i5erKM-jA@mail.gmail.com>

On Thu, 15 Feb 2024 at 15:32, Abel Vesa <abel.vesa at linaro.org> wrote:
>
> On 24-02-15 11:30:23, Dmitry Baryshkov wrote:
> > On Wed, 14 Feb 2024 at 23:36, Abel Vesa <abel.vesa at linaro.org> wrote:
> > >
> > > On 24-02-14 22:18:33, Konrad Dybcio wrote:
> > > > On 14.02.2024 22:13, Abel Vesa wrote:
> > > > > Rather than setting up the core, obsrv and chnls in probe by using
> > > > > version specific conditionals, add a dedicated "get_core_resources"
> > > > > version specific op and move the acquiring in there.
> > > > >
> > > > > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > > > > ---
> > > > >  drivers/spmi/spmi-pmic-arb.c | 111 ++++++++++++++++++++++++++++++-------------
> > > > >  1 file changed, 78 insertions(+), 33 deletions(-)
> > > > >
> > > > > diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> > > > > index 23939c0d225f..489556467a4c 100644
> > > > > --- a/drivers/spmi/spmi-pmic-arb.c
> > > > > +++ b/drivers/spmi/spmi-pmic-arb.c
> > > > > @@ -203,6 +203,7 @@ struct spmi_pmic_arb {
> > > > >   */
> > > > >  struct pmic_arb_ver_ops {
> > > > >     const char *ver_str;
> > > > > +   int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
> > > > >     int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
> > > > >     int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
> > > > >     /* spmi commands (read_cmd, write_cmd, cmd) functionality */
> > > > > @@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
> > > > >     return 0;
> > > > >  }
> > > > >
> > > > > +static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
> > > > > +                                     void __iomem *core)
> > > > > +{
> > > > > +   struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> > > > > +
> > > > > +   pmic_arb->wr_base = core;
> > > > > +   pmic_arb->rd_base = core;
> > > > > +
> > > > > +   pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
> > > > > +
> > > > > +   return 0;
> > > > > +}
> > > > > +
> > > > >  static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
> > > > >  {
> > > > >     u32 *mapping_table;
> > > > > @@ -1063,6 +1077,41 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
> > > > >     return apid;
> > > > >  }
> > > > >
> > > > > +static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
> > > > > +{
> > > > > +   struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
> > > > > +   struct device *dev = &pdev->dev;
> > > > > +   struct resource *res;
> > > > > +
> > > > > +   res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > > >
> > > > It's no longer indented to deep, no need to keep such aggressive wrapping
> > > >
> > >
> > > The pmic_arb_get_obsrvr_chnls_v2 is used by both:
> > > pmic_arb_get_core_resources_v2
> > > pmic_arb_get_core_resources_v7
> > >
> > > > > +                                      "obsrvr");
> > > > > +   pmic_arb->rd_base = devm_ioremap(dev, res->start,
> > > > > +                                    resource_size(res));
> > > > > +   if (IS_ERR(pmic_arb->rd_base))
> > > > > +           return PTR_ERR(pmic_arb->rd_base);
> > > > > +
> > > > > +   res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > > > > +                                      "chnls");
> > > > > +   pmic_arb->wr_base = devm_ioremap(dev, res->start,
> > > > > +                                    resource_size(res));
> > > > > +   if (IS_ERR(pmic_arb->wr_base))
> > > > > +           return PTR_ERR(pmic_arb->wr_base);
> > > >
> > > > Could probably make it "devm_platform_get_and_ioremap_resource "
> > >
> > > The reason this needs to stay as is is because of reason explained by
> > > the following comment found in probe:
> > >
> > > /*
> > >  * Please don't replace this with devm_platform_ioremap_resource() or
> > >  * devm_ioremap_resource().  These both result in a call to
> > >  * devm_request_mem_region() which prevents multiple mappings of this
> > >  * register address range.  SoCs with PMIC arbiter v7 may define two
> > >  * arbiter devices, for the two physical SPMI interfaces, which  share
> > >  * some register address ranges (i.e. "core", "obsrvr", and "chnls").
> > >  * Ensure that both devices probe successfully by calling devm_ioremap()
> > >  * which does not result in a devm_request_mem_region() call.
> > >  */
> > >
> > > Even though, AFAICT, there is no platform that adds a second node for
> > > the second bus, currently, in mainline, we should probably allow the
> > > "legacy" approach to still work.
> >
> > If there were no DT files which used two SPMI devices, I think we
> > should drop this comment and use existing helpers. We must keep
> > compatibility with the existing DTs, not with the _possible_ device
> > trees.
>
> Sure.
>
> Should I drop the qcom,bus-id from the driver as well? It is optional
> after all.

I think so. Let's drop it completely. And for the new sub-devices you
perfectly know the bus ID.

-- 
With best wishes
Dmitry


From andrew at lunn.ch  Thu Feb 15 06:53:02 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Thu, 15 Feb 2024 15:53:02 +0100
Subject: [PATCH net] net: ti: icssg-prueth: Remove duplicate cleanup
 calls in emac_ndo_stop()
In-Reply-To: <ce2c5ee0-3bed-490e-ac57-58e849ec1eee@siemens.com>
References: <20240206152052.98217-1-diogo.ivo@siemens.com>
 <ce2c5ee0-3bed-490e-ac57-58e849ec1eee@siemens.com>
Message-ID: <3279544c-fbe9-446c-9218-4d2c59f30905@lunn.ch>

> Hello,
> 
> Gentle ping on this patch.

Gentle ping's don't work for netdev. Merging patches is pretty much
driver by patchwork, so it is good to look there and see the state of
the patch.

https://patchwork.kernel.org/project/netdevbpf/patch/20240206152052.98217-1-diogo.ivo at siemens.com/

This is marked as Changes Requested.

Looking at the discussion, it seemed to conclude this is a cleanup,
not a fix. Hence the two Fixes: probably want removing.

Please repost with them removed, and the Reviewed-by's added.

You should also set the patch subject to include [net-next] to
indicate which tree this patch is for:

https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html#netdev-faq

       Andrew


From robh at kernel.org  Thu Feb 15 06:55:20 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 08:55:20 -0600
Subject: [PATCH v2 06/17] dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add
 imx6
In-Reply-To: <20240213010347.1075251-7-sre@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-7-sre@kernel.org>
Message-ID: <20240215145520.GA20171-robh@kernel.org>

On Tue, Feb 13, 2024 at 02:00:55AM +0100, Sebastian Reichel wrote:
> Add compatibles used by different i.MX6 variants to the i.MX IOMUX
> Controller GPR binding.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml   | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
> index 1da1b758b4ae..8451cb4dd87c 100644
> --- a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
> +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
> @@ -17,7 +17,23 @@ properties:
>    compatible:
>      oneOf:
>        - items:
> -          - const: fsl,imx8mq-iomuxc-gpr
> +          - enum:
> +              - fsl,imx6q-iomuxc-gpr
> +              - fsl,imx8mq-iomuxc-gpr
> +          - const: syscon
> +          - const: simple-mfd
> +      - items:
> +          - enum:
> +              - fsl,imx6sl-iomuxc-gpr
> +              - fsl,imx6sll-iomuxc-gpr
> +              - fsl,imx6ul-iomuxc-gpr
> +          - const: fsl,imx6q-iomuxc-gpr
> +          - const: syscon

A bit odd that imx6q is a simple-mfd above, but not here. I suppose 
that could be valid if the variants here don't have sub-devices or they 
do, but have a dependency on the parent.

Acked-by: Rob Herring <robh at kernel.org>

> +      - items:
> +          - enum:
> +              - fsl,imx6sx-iomuxc-gpr
> +              - fsl,imx7d-iomuxc-gpr
> +          - const: fsl,imx6q-iomuxc-gpr
>            - const: syscon
>            - const: simple-mfd
>        - items:
> -- 
> 2.43.0
> 


From jgg at nvidia.com  Thu Feb 15 06:56:57 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 15 Feb 2024 10:56:57 -0400
Subject: [PATCH rc v2] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
Message-ID: <0-v2-7988c2682634+261-smmu_cd_atomic_jgg@nvidia.com>

If the SMMU is configured to use a two level CD table then
arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
GFP_KERNEL. Due to recent changes this is being done under a spinlock to
iterate over the device list - thus it will trigger a sleeping while
atomic warning:

  arm_smmu_sva_set_dev_pasid()
    mutex_lock(&sva_lock);
    __arm_smmu_sva_bind()
     arm_smmu_mmu_notifier_get()
      spin_lock_irqsave()
      arm_smmu_write_ctx_desc()
	arm_smmu_get_cd_ptr()
         arm_smmu_alloc_cd_leaf_table()
	  dmam_alloc_coherent(GFP_KERNEL)

This is a 64K high order allocation and really should not be done
atomically.

At the moment the rework of the SVA to follow the new API is half
finished. Recently the CD table memory was moved from the domain to the
master, however we have the confusing situation where the SVA code is
wrongly using the RID domains device's list to track which CD tables the
SVA is installed in.

Remove the logic to replicate the CD across all the domain's masters
during attach. We know which master and which CD table the PASID should be
installed in.

At the moment SVA is only invoked when dma-iommu.c is in control of the
RID translation, which means we have a single iommu_domain shared across
the entire group and that iommu_domain is not shared outside the group.

For PCI cases the core code also insists on singleton groups so there is
only ever one entry in the smmu_domain->domains list that is equal to the
master being passed in to arm_smmu_sva_set_dev_pasid().

Only non-PCI cases may have multi-device groups. However, the core code it
self will replicate the calls to arm_smmu_sva_set_dev_pasid() across the
entire group so we will still correctly install the CD into each group
members master.

Thus the loop here is fully redundant and can be removed.

Removing the loop allows arm_smmu_write_ctx_desc() to be called outside
the spinlock and thus is safe to use GFP_KERNEL.

Fixes: 24503148c545 ("iommu/arm-smmu-v3: Refactor write_ctx_desc")
Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
Closes: https://lore.kernel.org/all/4e25d161-0cf8-4050-9aa3-dfa21cd63e56 at moroto.mountain/
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c   | 29 +++++--------------
 1 file changed, 8 insertions(+), 21 deletions(-)

v2 - rewritten

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index 05722121f00e70..64ec3f0ed8ffe0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -288,14 +288,14 @@ static const struct mmu_notifier_ops arm_smmu_mmu_notifier_ops = {
 
 /* Allocate or get existing MMU notifier for this {domain, mm} pair */
 static struct arm_smmu_mmu_notifier *
-arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
+arm_smmu_mmu_notifier_get(struct arm_smmu_master *master, ioasid_t pasid,
 			  struct mm_struct *mm)
 {
 	int ret;
-	unsigned long flags;
 	struct arm_smmu_ctx_desc *cd;
 	struct arm_smmu_mmu_notifier *smmu_mn;
-	struct arm_smmu_master *master;
+	struct iommu_domain *domain = iommu_get_domain_for_dev(master->dev);
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 
 	list_for_each_entry(smmu_mn, &smmu_domain->mmu_notifiers, list) {
 		if (smmu_mn->mn.mm == mm) {
@@ -325,19 +325,7 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
 		goto err_free_cd;
 	}
 
-	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
-	list_for_each_entry(master, &smmu_domain->devices, domain_head) {
-		ret = arm_smmu_write_ctx_desc(master, mm_get_enqcmd_pasid(mm),
-					      cd);
-		if (ret) {
-			list_for_each_entry_from_reverse(
-				master, &smmu_domain->devices, domain_head)
-				arm_smmu_write_ctx_desc(
-					master, mm_get_enqcmd_pasid(mm), NULL);
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
+	ret = arm_smmu_write_ctx_desc(master, pasid, cd);
 	if (ret)
 		goto err_put_notifier;
 
@@ -381,13 +369,12 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
 	arm_smmu_free_shared_cd(cd);
 }
 
-static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
+static int __arm_smmu_sva_bind(struct device *dev, ioasid_t pasid,
+			       struct mm_struct *mm)
 {
 	int ret;
 	struct arm_smmu_bond *bond;
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
-	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
-	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 
 	if (!master || !master->sva_enabled)
 		return -ENODEV;
@@ -398,7 +385,7 @@ static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
 
 	bond->mm = mm;
 
-	bond->smmu_mn = arm_smmu_mmu_notifier_get(smmu_domain, mm);
+	bond->smmu_mn = arm_smmu_mmu_notifier_get(master, pasid, mm);
 	if (IS_ERR(bond->smmu_mn)) {
 		ret = PTR_ERR(bond->smmu_mn);
 		goto err_free_bond;
@@ -590,7 +577,7 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
 	struct mm_struct *mm = domain->mm;
 
 	mutex_lock(&sva_lock);
-	ret = __arm_smmu_sva_bind(dev, mm);
+	ret = __arm_smmu_sva_bind(dev, id, mm);
 	mutex_unlock(&sva_lock);
 
 	return ret;

base-commit: c76c50cd425e574df5a071cd7e1805d0764aabff
-- 
2.43.0



From dietmar.eggemann at arm.com  Thu Feb 15 06:57:34 2024
From: dietmar.eggemann at arm.com (Dietmar Eggemann)
Date: Thu, 15 Feb 2024 15:57:34 +0100
Subject: [PATCH 0/3] cpufreq: scmi: Add boost frequency support
In-Reply-To: <01b3d0ed-3fd3-86c6-7b0f-48d34a5d9ba8@quicinc.com>
References: <20240117110443.2060704-1-quic_sibis@quicinc.com>
 <20240123060827.a3vszziftj6pszt3@vireshk-i7> <Za-RtBrSxI-j4Jdx@bogus>
 <e968092a-dc2b-4351-9489-acf874bbc7b6@arm.com>
 <01b3d0ed-3fd3-86c6-7b0f-48d34a5d9ba8@quicinc.com>
Message-ID: <265e5f2c-9b45-420f-89b1-44369aeb8418@arm.com>

On 13/02/2024 08:35, Sibi Sankar wrote:
> 
> 
> On 1/31/24 20:37, Dietmar Eggemann wrote:
>> On 23/01/2024 11:15, Sudeep Holla wrote:
>>> On Tue, Jan 23, 2024 at 11:38:27AM +0530, Viresh Kumar wrote:
>>>> On 17-01-24, 16:34, Sibi Sankar wrote:

[...]

>> root at juno:/sys/devices/system/cpu/cpufreq# cat boost policy*/boost
>> 1
>> 0
>> 0
>>
>> root at juno:/sys/devices/system/cpu/cpufreq# cat
>> policy*/scaling_available_frequencies policy*/scaling_boost_frequencies
>> 450000 575000 700000
>> 450000 625000 800000
>> 775000 850000
>> 950000 1100000
>>
>> If I disable system-wide boost I see the correct influence on
>> 'cpufreq_pressure':
>>
>> root at juno:/sys/devices/system/cpu/cpufreq# echo 0 > boost
>>
>> [? 439.466682] cpufreq_update_pressure() cpu=1 cpufreq_pressure=280
>> [? 439.472797] cpufreq_update_pressure() cpu=2 cpufreq_pressure=280
>> [? 439.478889] cpufreq_update_pressure() cpu=0 cpufreq_pressure=79
>> [? 439.484852] cpufreq_update_pressure() cpu=3 cpufreq_pressure=79
>> [? 439.490843] cpufreq_update_pressure() cpu=4 cpufreq_pressure=79
>> [? 439.499621] cpufreq_update_pressure() cpu=5 cpufreq_pressure=79
>>
>> reflecting the max frequency change from '1100000 to 800000' on CPU1,2
>> and from '850000 to 700000' on CPU0,3-5.
>>
>> root at juno:/sys/devices/system/cpu/cpufreq# echo 1 > boost
>>
>> [ 2722.693113] cpufreq_update_pressure() cpu=1 cpufreq_pressure=0
>> [ 2722.699041] cpufreq_update_pressure() cpu=2 cpufreq_pressure=0
>> [ 2722.704962] cpufreq_update_pressure() cpu=0 cpufreq_pressure=0
>> [ 2722.710842] cpufreq_update_pressure() cpu=3 cpufreq_pressure=0
>> [ 2722.719644] cpufreq_update_pressure() cpu=4 cpufreq_pressure=0
>> [ 2722.728224] cpufreq_update_pressure() cpu=5 cpufreq_pressure=0
>>
>> What doesn't work for me is to disable boost per policy:
>>
>> root at juno:/sys/devices/system/cpu/cpufreq# echo 1 > boost
>> root at juno:/sys/devices/system/cpu/cpufreq# echo 0 > policy0/boost
>> root at juno:/sys/devices/system/cpu/cpufreq# echo 0 > policy1/boost
>>
>> Here I don't see 'cpufreq_pressure' changes.
>>
>> BTW, what's the use case you have in mind for this feature? Is it to cap
>> high OPPs for CPUs in a certain CPUfreq policy?
> 
> Yeah, that's exactly the use case for X1E. Boost frequencies defined in
> the SoC are achievable by only one CPU in a cluster i.e. either the
> other CPUs in the same cluster should be in low power mode or offline.
> So it's mostly for book keeping i.e. we wouldn't to intimate incorrectly
> that the CPUs are running at max possible frequency when it's actually
> running at a lower frequency.

I see.

What about the issue with the settings of the global and the per-policy
'boost' file?

On my Juno-r0 the initial boost values are:

(1) Initial setting:

root at juno:/sys/devices/system/cpu/cpufreq# cat boost policy*/boost
1
0
0

Should they not all be 1 ?


(2) Disabling system-wide boost

root at juno:/sys/devices/system/cpu/cpufreq# echo 0 > boost

Here I see 'cpufreq_pressure > 0' for all CPUs.


(3) Enabling system-wide boost

root at juno:/sys/devices/system/cpu/cpufreq# echo 1 > boost

And here 'cpufreq_pressure == 0' for all CPUs.


(4) Disabling boost for policy0.

root at juno:/sys/devices/system/cpu/cpufreq# echo 0 > policy0/boost

root at juno:/sys/devices/system/cpu/cpufreq# cat boost policy*/boost
1
0
1

Here nothing happened. But I was expecting to see 'cpufreq_pressure > 0'
for CPUs of policy0:

root at juno:/sys/devices/system/cpu/cpufreq# cat policy0/affected_cpus
0 3 4 5


From tglx at linutronix.de  Thu Feb 15 07:01:03 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Thu, 15 Feb 2024 16:01:03 +0100
Subject: [PATCH v12 04/25] genirq/irqdomain: Add DOMAIN_BUS_DEVICE_IMS
In-Reply-To: <86o7ci3puk.wl-maz@kernel.org>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-5-apatel@ventanamicro.com>
 <86o7ci3puk.wl-maz@kernel.org>
Message-ID: <87h6i9epqo.ffs@tglx>

On Thu, Feb 15 2024 at 11:54, Marc Zyngier wrote:
> On Sat, 27 Jan 2024 16:17:32 +0000,
> Anup Patel <apatel at ventanamicro.com> wrote:
>>  	DOMAIN_BUS_PCI_DEVICE_IMS,
>> +	DOMAIN_BUS_DEVICE_IMS,
>
> Only a personal taste, but since we keep calling it "device MSI",
> which it really is, I find it slightly odd to name the token
> "DEVICE_IMS".
>
> From what I understand, IMS is PCIe specific. Platform (and by
> extension device) MSI extends far beyond PCIe. So here, DEVICE_MSI
> would make a lot more sense and avoid confusion.

That's true, but I chose it intentionally because Interrupt Message
Store (IMS) is a (PCI) device specific way to store the message contrary
to PCI/MSI[-X] which has standardized storage.

So my thought was that this exactly reflects what the platform device
requires: device specific message store, aka DMS or DSMS :)

> But hey, I don't have much skin in this game, and I can probably
> mentally rotate the acronym...

I have no strong opinion about it though.

Thanks,

        tglx


From jpaulo.silvagoncalves at gmail.com  Thu Feb 15 07:05:59 2024
From: jpaulo.silvagoncalves at gmail.com (Joao Paulo Goncalves)
Date: Thu, 15 Feb 2024 12:05:59 -0300
Subject: [PATCH V8 00/12] soc: imx8mp: Add support for HDMI
In-Reply-To: <20240203165307.7806-1-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com>
Message-ID: <20240215150559.287571-1-jpaulo.silvagoncalves@gmail.com>

>The i.MX8M Plus has an HDMI controller, but it depends on two
>other systems, the Parallel Video Interface (PVI) and the
>HDMI PHY from Samsung. The LCDIF controller generates the display
>and routes it to the PVI which converts passes the parallel video
>to the HDMI bridge.  The HDMI system has a corresponding power
>domain controller whose driver was partially written, but the
>device tree for it was never applied, so some changes to the
>power domain should be harmless because they've not really been
>used yet.

>This series is adapted from multiple series from Lucas Stach with
>edits and suggestions from feedback from various series, but it
>since it's difficult to use and test them independently,
>I merged them into on unified series.  The version history is a
>bit ambiguous since different components were submitted at different
times and had different amount of retries.  In an effort to merge them
>I used the highest version attempt.

Tested-by: Joao Paulo Goncalves <joao.goncalves at toradex.com>

Tested on Toradex Verdin-iMX8MP.

Thanks!

Regards,
Joao Paulo Goncalves


From ville.syrjala at linux.intel.com  Thu Feb 15 07:09:05 2024
From: ville.syrjala at linux.intel.com (Ville =?iso-8859-1?Q?Syrj=E4l=E4?=)
Date: Thu, 15 Feb 2024 17:09:05 +0200
Subject: [PATCH v5 08/44] drm/connector: hdmi:
 Add Broadcast RGB property
In-Reply-To: <dti6zcuzszhut5m4g2bxiwfogwctfhktv2mwuqlij7wtvh3bny@ry4mxpiqidmt>
References: <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
 <ZcsqoPCJDjA5PJUF@intel.com>
 <dti6zcuzszhut5m4g2bxiwfogwctfhktv2mwuqlij7wtvh3bny@ry4mxpiqidmt>
Message-ID: <Zc4pEfVRItn0ZCXE@intel.com>

On Thu, Feb 15, 2024 at 11:53:17AM +0100, Maxime Ripard wrote:
> On Tue, Feb 13, 2024 at 10:38:56AM +0200, Ville Syrj?l? wrote:
> > On Mon, Feb 12, 2024 at 05:53:48PM +0100, Maxime Ripard wrote:
> > > On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> > > > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > > > > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > > > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > > > > Hi,
> > > > > > > > > > > 
> > > > > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > > > > >  /**
> > > > > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > > > > >   *
> > > > > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > + *      Full:
> > > > > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > 
> > > > > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > > > > different things being affected:
> > > > > > > > > > > > > 
> > > > > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > > > > 
> > > > > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > > > > 
> > > > > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > > > > signalling, what happens?
> > > > > > > > > > > > 
> > > > > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > > > > YCbCr?
> > > > > > > > > > > 
> > > > > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > > > > vc4 will follow the value of the property.
> > > > > > > > > > 
> > > > > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > > > > That should explain why it's only affecting RGB.
> > > > > > > > > 
> > > > > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > > > > itself.
> > > > > > > > > 
> > > > > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > > > > to enable it.
> > > > > > > > > 
> > > > > > > > > vc4 supports it.
> > > > > > > > 
> > > > > > > > Someone implemented it incorrectly then.
> > > > > > > 
> > > > > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > > > > document any of it, and when people try to clean things up they get told
> > > > > > > that we got it all wrong.
> > > > > > 
> > > > > > FWIW, this was an i915 property and if another driver uses the same
> > > > > > property name it must have the same behavior. Yes, it isn't standardized
> > > > > > and yes, it's not documented (hence this effort here) but it's still on
> > > > > > vc4 to make the property compatible.
> > > > > 
> > > > > How is it not compatible? It's a superset of what i915 provides, but
> > > > > it's strictly compatible with it.
> > > > 
> > > > No it is not.
> > > 
> > > The property is compatible with i915 interpretation of it, whether you
> > > like it or not. And that's what Sebastian was referring to.
> > > 
> > > > Eg. what happens if you set the thing to full range for RGB (which you
> > > > must on many broken monitors), and then the kernel automagically
> > > > switches to YCbCr (for whatever reason) but the monitor doesn't
> > > > support full range YCbCr? Answer: you get crap output.
> > > 
> > > And that part is just moving goalposts.
> > 
> > No. Allowing users to get correct colors with broken displays
> > is the sole reason why this property even exists.
> 
> HDMI 1.4, Section 6.6 - Video Quantization Ranges:
> 
>   If the sink?s EDID declares a selectable YCC Quantization Range
>   (QY=1), then it shall expect limited range pixel values if it receives
>   AVI YQ=0 and it shall expect full range pixel values if it receives
>   AVI YQ=1. For other values of YQ, the sink shall expect pixel values
>   with the default range for the transmitted video format.
> 
> So, the only concern you have is if the EDID has QY set to 1 but the
> monitor doesn't actually support it? If so, could we qualify the monitor
> as a "broken display" and thus would require that property to apply to
> YUV too?

Sinks that declare a selectable quantization range are not the
problem, or at least I don't recall ever seeing one that lied about
that. The problem is the sinks that don't have selectable quantization
range, and which implement the default rules incorrectly. The only way
to get correct colors on those is for the user to override the
quantization range manually.

Typically TVs get it mostly right (though I have at least one that
also expects limited range for 640x480 which is not correct), and 
many (perhaps even most?) computer displays get it wrong (as in
they always assume RGB to be full range).

We could in theory quirk those, but the quirk list would be enormous,
and fragile to maintain because the user can also shoot themselves in
the foot here by frobbing with the "black level"/etc. settings on the
display itself. So we'd surely end up with lots of false positives
on the quirk list.

-- 
Ville Syrj?l?
Intel


From robh at kernel.org  Thu Feb 15 07:09:15 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 09:09:15 -0600
Subject: [PATCH 1/4] dt-bindings: arm: rockchip: Correct vendor for
 Orange Pi RK3399 board
In-Reply-To: <20240214040731.3069111-2-tim@feathertop.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
 <20240214040731.3069111-2-tim@feathertop.org>
Message-ID: <170800975373.77965.10834715351049347685.robh@kernel.org>


On Wed, 14 Feb 2024 15:07:28 +1100, Tim Lunn wrote:
> The vendor for this board was incorrectly listed as Rockchip. Fix this
> now while they are not used anywhere, in the future they may be used by
> bootloader to select dts.
> 
> Update the vendor to Xunlong.
> 
> Signed-off-by: Tim Lunn <tim at feathertop.org>
> ---
> 
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From robh at kernel.org  Thu Feb 15 07:10:35 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 09:10:35 -0600
Subject: [PATCH 2/4] dt-bindings: arm: rockchip: Correct vendor for
 Banana Pi R2 Pro
In-Reply-To: <20240214040731.3069111-3-tim@feathertop.org>
References: <20240214040731.3069111-1-tim@feathertop.org>
 <20240214040731.3069111-3-tim@feathertop.org>
Message-ID: <170800983525.88947.3003525865973395499.robh@kernel.org>


On Wed, 14 Feb 2024 15:07:29 +1100, Tim Lunn wrote:
> The vendor for this board was incorrectly listed as Rockchip. Fix this
> now while they are not used anywhere, in the future they may be used by
> bootloader to select dts.
> 
> Update the vendor to Sinovoip.
> 
> Signed-off-by: Tim Lunn <tim at feathertop.org>
> ---
> 
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From diogo.ivo at siemens.com  Thu Feb 15 07:10:45 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Thu, 15 Feb 2024 15:10:45 +0000
Subject: [PATCH net] net: ti: icssg-prueth: Remove duplicate cleanup calls
 in emac_ndo_stop()
In-Reply-To: <3279544c-fbe9-446c-9218-4d2c59f30905@lunn.ch>
References: <20240206152052.98217-1-diogo.ivo@siemens.com>
 <ce2c5ee0-3bed-490e-ac57-58e849ec1eee@siemens.com>
 <3279544c-fbe9-446c-9218-4d2c59f30905@lunn.ch>
Message-ID: <c143cfbf-c474-42b8-adbb-13676e177d34@siemens.com>


On 2/15/24 14:53, Andrew Lunn wrote:
>> Hello,
>>
>> Gentle ping on this patch.
> Gentle ping's don't work for netdev. Merging patches is pretty much
> driver by patchwork, so it is good to look there and see the state of
> the patch.
>
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatchwork.kernel.org%2Fproject%2Fnetdevbpf%2Fpatch%2F20240206152052.98217-1-diogo.ivo%40siemens.com%2F&data=05%7C02%7Cdiogo.ivo%40siemens.com%7Cc6a5a844ef59437e85f308dc2e35cb4b%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C638436055786669669%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=CMjL%2Bkc9%2BOo0igLSnX4OzgxO3CGKP2m67afScU0pG0I%3D&reserved=0
>
> This is marked as Changes Requested.
>
> Looking at the discussion, it seemed to conclude this is a cleanup,
> not a fix. Hence the two Fixes: probably want removing.
>
> Please repost with them removed, and the Reviewed-by's added.
>
> You should also set the patch subject to include [net-next] to
> indicate which tree this patch is for:
>
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.kernel.org%2Fdoc%2Fhtml%2Flatest%2Fprocess%2Fmaintainer-netdev.html%23netdev-faq&data=05%7C02%7Cdiogo.ivo%40siemens.com%7Cc6a5a844ef59437e85f308dc2e35cb4b%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C638436055786678320%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=ZS2Gn%2F9kqM7UKL9VD8mSCXeegsx%2BXI6jvgW30XoqQ2M%3D&reserved=0
>
>         Andrew

Ok, thank you for the clarification!

I'll prepare the patch as requested.


Thanks,

Diogo



From thomas.richard at bootlin.com  Thu Feb 15 07:17:45 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:45 +0100
Subject: [PATCH v3 00/18] Add suspend to ram support for PCIe on J7200
Message-ID: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>

This add suspend to ram support for the PCIe (RC mode) on J7200 platform.

In RC mode, the reset pin for endpoints is managed by a gpio expander on a
i2c bus. This pin shall be managed in suspend_noirq() and resume_noirq().
The suspend/resume has been moved to suspend_noirq()/resume_noirq() for
pca953x (expander) and pinctrl-single.

To do i2c accesses during suspend_noirq/resume_noirq, we need to force the
wakeup of the i2c controller (which is autosuspended) during suspend
callback. 
It's the only way to wakeup the controller if it's autosuspended, as
runtime pm is disabled in suspend_noirq and resume_noirq.

The main change in this v3 is the removal of the probe boolean for the
functions wiz_clock_probe() and cdns_pcie_host_setup().
Their contents were split in multiple functions which are called in the
resume_noirq() callbacks.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
Changes in v3:
- pinctrl-single: split patch in two parts, a first patch to remove the
  dead code, a second to move suspend()/resume() callbacks to noirq.
- i2c-omap: add a comments above the suspend_noirq() callback.
- mux: now mux_chip_resume() try to restores all muxes, then return 0 if
  all is ok or the first failure.
- mmio: fix commit message.
- phy-j721e-wiz: add a patch to use dev_err_probe() instead of dev_err() in
  the wiz_clock_init() function.
- phy-j721e-wiz: remove probe boolean for the wiz_clock_init(), rename the
  function to wiz_clock_probe(), extract hardware configuration part in a
  new function wiz_clock_init().
- phy-cadence-torrent: use dev_err_probe() and fix commit messages
- pcie-cadence-host: remove probe boolean for the cdns_pcie_host_setup()
  function and extract the link setup part in a new function
  cdns_pcie_host_link_setup().
- pcie-cadence-host: make cdns_pcie_host_init() global.
- pci-j721e: use the cdns_pcie_host_link_setup() cdns_pcie_host_init()
  functions in the resume_noirq() callback.
- Link to v2: https://lore.kernel.org/r/20240102-j7200-pcie-s2r-v2-0-8e4f7d228ec2 at bootlin.com

Changes in v2:
- all: fix commits messages.
- all: use DEFINE_NOIRQ_DEV_PM_OPS and pm_sleep_ptr macros.
- all: remove useless #ifdef CONFIG_PM.
- pinctrl-single: drop dead code
- mux: add mux_chip_resume() function in mux core.
- mmio: resume sequence is now a call to mux_chip_resume().
- phy-cadence-torrent: fix typo in resume sequence (reset_control_assert()
  instead of reset_control_put()).
- phy-cadence-torrent: use PHY instead of phy.
- pci-j721e: do not shadow cdns_pcie_host_setup return code in resume
  sequence.
- pci-j721e: drop dead code.
- Link to v1: https://lore.kernel.org/r/20240102-j7200-pcie-s2r-v1-0-84e55da52400 at bootlin.com

---
Thomas Richard (15):
      gpio: pca953x: move suspend()/resume() to suspend_noirq()/resume_noirq()
      pinctrl: pinctrl-single: remove dead code in suspend() and resume() callbacks
      pinctrl: pinctrl-single: move suspend()/resume() callbacks to noirq
      i2c: omap: wakeup the controller during suspend() callback
      mux: add mux_chip_resume() function
      phy: ti: phy-j721e-wiz: use dev_err_probe() instead of dev_err()
      phy: ti: phy-j721e-wiz: split wiz_clock_init() function
      phy: ti: phy-j721e-wiz: add resume support
      phy: cadence-torrent: extract calls to clk_get from cdns_torrent_clk
      phy: cadence-torrent: register resets even if the phy is already configured
      phy: cadence-torrent: add already_configured to struct cdns_torrent_phy
      phy: cadence-torrent: remove noop_ops phy operations
      phy: cadence-torrent: add suspend and resume support
      PCI: cadence: extract link setup sequence from cdns_pcie_host_setup()
      PCI: cadence: set cdns_pcie_host_init() global

Th?o Lebrun (3):
      mux: mmio: add resume support
      PCI: j721e: add reset GPIO to struct j721e_pcie
      PCI: j721e: add suspend and resume support

 drivers/gpio/gpio-pca953x.c                        |   7 +-
 drivers/i2c/busses/i2c-omap.c                      |  22 ++++
 drivers/mux/core.c                                 |  30 +++++
 drivers/mux/mmio.c                                 |  12 ++
 drivers/pci/controller/cadence/pci-j721e.c         | 102 ++++++++++++++++-
 drivers/pci/controller/cadence/pcie-cadence-host.c |  44 +++++---
 drivers/pci/controller/cadence/pcie-cadence.h      |  12 ++
 drivers/phy/cadence/phy-cadence-torrent.c          | 121 +++++++++++++++------
 drivers/phy/ti/phy-j721e-wiz.c                     | 119 +++++++++++++-------
 drivers/pinctrl/pinctrl-single.c                   |  28 ++---
 include/linux/mux/driver.h                         |   1 +
 11 files changed, 380 insertions(+), 118 deletions(-)
---
base-commit: 00ff0f9ce40db8e64fe16c424a965fd7ab769c42
change-id: 20240102-j7200-pcie-s2r-ecb1a979e357

Best regards,
-- 
Thomas Richard <thomas.richard at bootlin.com>



From thomas.richard at bootlin.com  Thu Feb 15 07:17:46 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:46 +0100
Subject: [PATCH v3 01/18] gpio: pca953x: move suspend()/resume() to
 suspend_noirq()/resume_noirq()
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-1-5c2e4a3fac1f@bootlin.com>

Some IOs can be needed during suspend_noirq()/resume_noirq().
So move suspend()/resume() to noirq.

Reviewed-by: Andi Shyti <andi.shyti at kernel.org>
Acked-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko at gmail.com>
Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/gpio/gpio-pca953x.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 00ffa168e405..6e495fc67a93 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -1234,7 +1234,7 @@ static void pca953x_save_context(struct pca953x_chip *chip)
 	regcache_cache_only(chip->regmap, true);
 }
 
-static int pca953x_suspend(struct device *dev)
+static int pca953x_suspend_noirq(struct device *dev)
 {
 	struct pca953x_chip *chip = dev_get_drvdata(dev);
 
@@ -1248,7 +1248,7 @@ static int pca953x_suspend(struct device *dev)
 	return 0;
 }
 
-static int pca953x_resume(struct device *dev)
+static int pca953x_resume_noirq(struct device *dev)
 {
 	struct pca953x_chip *chip = dev_get_drvdata(dev);
 	int ret;
@@ -1268,7 +1268,8 @@ static int pca953x_resume(struct device *dev)
 	return ret;
 }
 
-static DEFINE_SIMPLE_DEV_PM_OPS(pca953x_pm_ops, pca953x_suspend, pca953x_resume);
+static DEFINE_NOIRQ_DEV_PM_OPS(pca953x_pm_ops,
+			       pca953x_suspend_noirq, pca953x_resume_noirq);
 
 /* convenience to stop overlong match-table lines */
 #define OF_653X(__nrgpio, __int) ((void *)(__nrgpio | PCAL653X_TYPE | __int))

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:47 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:47 +0100
Subject: [PATCH v3 02/18] pinctrl: pinctrl-single: remove dead code in
 suspend() and resume() callbacks
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-2-5c2e4a3fac1f@bootlin.com>

No need to check the pointer returned by platform_get_drvdata(), as
platform_set_drvdata() is called during the probe.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/pinctrl/pinctrl-single.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 19cc0db771a5..02eabd28d46e 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -1693,11 +1693,7 @@ static void pcs_restore_context(struct pcs_device *pcs)
 static int pinctrl_single_suspend(struct platform_device *pdev,
 					pm_message_t state)
 {
-	struct pcs_device *pcs;
-
-	pcs = platform_get_drvdata(pdev);
-	if (!pcs)
-		return -EINVAL;
+	struct pcs_device *pcs = platform_get_drvdata(pdev);
 
 	if (pcs->flags & PCS_CONTEXT_LOSS_OFF) {
 		int ret;
@@ -1712,11 +1708,7 @@ static int pinctrl_single_suspend(struct platform_device *pdev,
 
 static int pinctrl_single_resume(struct platform_device *pdev)
 {
-	struct pcs_device *pcs;
-
-	pcs = platform_get_drvdata(pdev);
-	if (!pcs)
-		return -EINVAL;
+	struct pcs_device *pcs = platform_get_drvdata(pdev);
 
 	if (pcs->flags & PCS_CONTEXT_LOSS_OFF)
 		pcs_restore_context(pcs);

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:48 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:48 +0100
Subject: [PATCH v3 03/18] pinctrl: pinctrl-single: move suspend()/resume()
 callbacks to noirq
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-3-5c2e4a3fac1f@bootlin.com>

The goal is to extend the active period of pinctrl.
Some devices may need active pinctrl after suspend() and/or before
resume().
So move suspend()/resume() to suspend_noirq()/resume_noirq() in order to
have active pinctrl until suspend_noirq() (included), and from
resume_noirq() (included).

The deprecated API has been removed to use the new one (dev_pm_ops struct).

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko at gmail.com>
Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/pinctrl/pinctrl-single.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 02eabd28d46e..0dd4b0e11adf 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -1625,7 +1625,6 @@ static int pcs_irq_init_chained_handler(struct pcs_device *pcs,
 	return 0;
 }
 
-#ifdef CONFIG_PM
 static int pcs_save_context(struct pcs_device *pcs)
 {
 	int i, mux_bytes;
@@ -1690,10 +1689,9 @@ static void pcs_restore_context(struct pcs_device *pcs)
 	}
 }
 
-static int pinctrl_single_suspend(struct platform_device *pdev,
-					pm_message_t state)
+static int pinctrl_single_suspend_noirq(struct device *dev)
 {
-	struct pcs_device *pcs = platform_get_drvdata(pdev);
+	struct pcs_device *pcs = dev_get_drvdata(dev);
 
 	if (pcs->flags & PCS_CONTEXT_LOSS_OFF) {
 		int ret;
@@ -1706,16 +1704,19 @@ static int pinctrl_single_suspend(struct platform_device *pdev,
 	return pinctrl_force_sleep(pcs->pctl);
 }
 
-static int pinctrl_single_resume(struct platform_device *pdev)
+static int pinctrl_single_resume_noirq(struct device *dev)
 {
-	struct pcs_device *pcs = platform_get_drvdata(pdev);
+	struct pcs_device *pcs = dev_get_drvdata(dev);
 
 	if (pcs->flags & PCS_CONTEXT_LOSS_OFF)
 		pcs_restore_context(pcs);
 
 	return pinctrl_force_default(pcs->pctl);
 }
-#endif
+
+static DEFINE_NOIRQ_DEV_PM_OPS(pinctrl_single_pm_ops,
+			       pinctrl_single_suspend_noirq,
+			       pinctrl_single_resume_noirq);
 
 /**
  * pcs_quirk_missing_pinctrl_cells - handle legacy binding
@@ -1978,11 +1979,8 @@ static struct platform_driver pcs_driver = {
 	.driver = {
 		.name		= DRIVER_NAME,
 		.of_match_table	= pcs_of_match,
+		.pm = pm_sleep_ptr(&pinctrl_single_pm_ops),
 	},
-#ifdef CONFIG_PM
-	.suspend = pinctrl_single_suspend,
-	.resume = pinctrl_single_resume,
-#endif
 };
 
 module_platform_driver(pcs_driver);

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:49 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:49 +0100
Subject: [PATCH v3 04/18] i2c: omap: wakeup the controller during suspend()
 callback
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-4-5c2e4a3fac1f@bootlin.com>

A device may need the controller up during suspend_noirq() or
resume_noirq().
But if the controller is autosuspended, there is no way to wakeup it during
suspend_noirq() or resume_noirq() because runtime pm is disabled at this
time.

The suspend() callback wakes up the controller, so it is available until
its suspend_noirq() callback (pm_runtime_force_suspend()).
During the resume, it's restored by resume_noirq() callback
(pm_runtime_force_resume()). Then resume() callback enables autosuspend.

So the controller is up during a little time slot in suspend and resume
sequences even if it's not used.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/i2c/busses/i2c-omap.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 42165ef57946..c11deb285114 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1575,9 +1575,31 @@ static int __maybe_unused omap_i2c_runtime_resume(struct device *dev)
 	return 0;
 }
 
+static int omap_i2c_suspend(struct device *dev)
+{
+	/*
+	 * If the controller is autosuspended, there is no way to wakeup it once
+	 * runtime pm is disabled (in suspend_late()).
+	 * But a device may need the controller up during suspend_noirq() or
+	 * resume_noirq().
+	 * Wakeup the controller while runtime pm is enabled, so it is available until
+	 * its suspend_noirq(), and from resume_noirq().
+	 */
+	return pm_runtime_resume_and_get(dev);
+}
+
+static int omap_i2c_resume(struct device *dev)
+{
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return 0;
+}
+
 static const struct dev_pm_ops omap_i2c_pm_ops = {
 	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
 				      pm_runtime_force_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(omap_i2c_suspend, omap_i2c_resume)
 	SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
 			   omap_i2c_runtime_resume, NULL)
 };

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:51 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:51 +0100
Subject: [PATCH v3 06/18] mux: mmio: add resume support
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-6-5c2e4a3fac1f@bootlin.com>

From: Th?o Lebrun <theo.lebrun at bootlin.com>

No need to save something during the suspend stage, as the mux core has an
internal cache to store the state of muxes.

This cache is used by mux_chip_resume() to restore all muxes.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/mux/mmio.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/mux/mmio.c b/drivers/mux/mmio.c
index fd1d121a584b..892ff4714b68 100644
--- a/drivers/mux/mmio.c
+++ b/drivers/mux/mmio.c
@@ -125,13 +125,25 @@ static int mux_mmio_probe(struct platform_device *pdev)
 
 	mux_chip->ops = &mux_mmio_ops;
 
+	dev_set_drvdata(dev, mux_chip);
+
 	return devm_mux_chip_register(dev, mux_chip);
 }
 
+static int mux_mmio_resume_noirq(struct device *dev)
+{
+	struct mux_chip *mux_chip = dev_get_drvdata(dev);
+
+	return mux_chip_resume(mux_chip);
+}
+
+static DEFINE_NOIRQ_DEV_PM_OPS(mux_mmio_pm_ops, NULL, mux_mmio_resume_noirq);
+
 static struct platform_driver mux_mmio_driver = {
 	.driver = {
 		.name = "mmio-mux",
 		.of_match_table	= mux_mmio_dt_ids,
+		.pm = pm_sleep_ptr(&mux_mmio_pm_ops),
 	},
 	.probe = mux_mmio_probe,
 };

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:50 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:50 +0100
Subject: [PATCH v3 05/18] mux: add mux_chip_resume() function
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-5-5c2e4a3fac1f@bootlin.com>

The mux_chip_resume() function restores a mux_chip using the cached state
of each mux.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/mux/core.c         | 30 ++++++++++++++++++++++++++++++
 include/linux/mux/driver.h |  1 +
 2 files changed, 31 insertions(+)

diff --git a/drivers/mux/core.c b/drivers/mux/core.c
index 775816112932..5db5a7698ad1 100644
--- a/drivers/mux/core.c
+++ b/drivers/mux/core.c
@@ -215,6 +215,36 @@ void mux_chip_free(struct mux_chip *mux_chip)
 }
 EXPORT_SYMBOL_GPL(mux_chip_free);
 
+/**
+ * mux_chip_resume() - restores the mux-chip state
+ * @mux_chip: The mux-chip to resume.
+ *
+ * Restores the mux-chip state.
+ *
+ * Return: Zero on success or a negative errno on error.
+ */
+int mux_chip_resume(struct mux_chip *mux_chip)
+{
+	int global_ret = 0;
+	int ret, i;
+
+	for (i = 0; i < mux_chip->controllers; ++i) {
+		struct mux_control *mux = &mux_chip->mux[i];
+
+		if (mux->cached_state == MUX_CACHE_UNKNOWN)
+			continue;
+
+		ret = mux_control_set(mux, mux->cached_state);
+		if (ret < 0) {
+			dev_err(&mux_chip->dev, "unable to restore state\n");
+			if (!global_ret)
+				global_ret = ret;
+		}
+	}
+	return global_ret;
+}
+EXPORT_SYMBOL_GPL(mux_chip_resume);
+
 static void devm_mux_chip_release(struct device *dev, void *res)
 {
 	struct mux_chip *mux_chip = *(struct mux_chip **)res;
diff --git a/include/linux/mux/driver.h b/include/linux/mux/driver.h
index 18824064f8c0..2a7e5ec5d540 100644
--- a/include/linux/mux/driver.h
+++ b/include/linux/mux/driver.h
@@ -88,6 +88,7 @@ struct mux_chip *mux_chip_alloc(struct device *dev,
 int mux_chip_register(struct mux_chip *mux_chip);
 void mux_chip_unregister(struct mux_chip *mux_chip);
 void mux_chip_free(struct mux_chip *mux_chip);
+int mux_chip_resume(struct mux_chip *mux_chip);
 
 struct mux_chip *devm_mux_chip_alloc(struct device *dev,
 				     unsigned int controllers,

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:52 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:52 +0100
Subject: [PATCH v3 07/18] phy: ti: phy-j721e-wiz: use dev_err_probe()
 instead of dev_err()
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-7-5c2e4a3fac1f@bootlin.com>

Use dev_err_probe() instead of dev_err() in wiz_clock_init() to simplify
the code and standardize the error output.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/phy/ti/phy-j721e-wiz.c | 39 ++++++++++++++++++---------------------
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index fc3cd98c60ff..ce8a99801a4c 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -1088,11 +1088,10 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
 	int i;
 
 	clk = devm_clk_get(dev, "core_ref_clk");
-	if (IS_ERR(clk)) {
-		dev_err(dev, "core_ref_clk clock not found\n");
-		ret = PTR_ERR(clk);
-		return ret;
-	}
+	if (IS_ERR(clk))
+		return dev_err_probe(dev, PTR_ERR(clk),
+				     "core_ref_clk clock not found\n");
+
 	wiz->input_clks[WIZ_CORE_REFCLK] = clk;
 
 	rate = clk_get_rate(clk);
@@ -1122,11 +1121,10 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
 
 	if (wiz->data->pma_cmn_refclk1_int_mode) {
 		clk = devm_clk_get(dev, "core_ref1_clk");
-		if (IS_ERR(clk)) {
-			dev_err(dev, "core_ref1_clk clock not found\n");
-			ret = PTR_ERR(clk);
-			return ret;
-		}
+		if (IS_ERR(clk))
+			return dev_err_probe(dev, PTR_ERR(clk),
+					     "core_ref1_clk clock not found\n");
+
 		wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
 
 		rate = clk_get_rate(clk);
@@ -1137,11 +1135,10 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
 	}
 
 	clk = devm_clk_get(dev, "ext_ref_clk");
-	if (IS_ERR(clk)) {
-		dev_err(dev, "ext_ref_clk clock not found\n");
-		ret = PTR_ERR(clk);
-		return ret;
-	}
+	if (IS_ERR(clk))
+		return dev_err_probe(dev, PTR_ERR(clk),
+				     "ext_ref_clk clock not found\n");
+
 	wiz->input_clks[WIZ_EXT_REFCLK] = clk;
 
 	rate = clk_get_rate(clk);
@@ -1157,7 +1154,7 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
 	case J721S2_WIZ_10G:
 		ret = wiz_clock_register(wiz);
 		if (ret)
-			dev_err(dev, "Failed to register wiz clocks\n");
+			dev_err_probe(dev, ret, "Failed to register wiz clocks\n");
 		return ret;
 	default:
 		break;
@@ -1175,8 +1172,8 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
 		ret = wiz_mux_of_clk_register(wiz, clk_node, wiz->mux_sel_field[i],
 					      clk_mux_sel[i].table);
 		if (ret) {
-			dev_err(dev, "Failed to register %s clock\n",
-				node_name);
+			dev_err_probe(dev, ret, "Failed to register %s clock\n",
+				      node_name);
 			of_node_put(clk_node);
 			goto err;
 		}
@@ -1188,16 +1185,16 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
 		node_name = clk_div_sel[i].node_name;
 		clk_node = of_get_child_by_name(node, node_name);
 		if (!clk_node) {
-			dev_err(dev, "Unable to get %s node\n", node_name);
 			ret = -EINVAL;
+			dev_err_probe(dev, ret, "Unable to get %s node\n", node_name);
 			goto err;
 		}
 
 		ret = wiz_div_clk_register(wiz, clk_node, wiz->div_sel_field[i],
 					   clk_div_sel[i].table);
 		if (ret) {
-			dev_err(dev, "Failed to register %s clock\n",
-				node_name);
+			dev_err_probe(dev, ret, "Failed to register %s clock\n",
+				      node_name);
 			of_node_put(clk_node);
 			goto err;
 		}

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:54 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:54 +0100
Subject: [PATCH v3 09/18] phy: ti: phy-j721e-wiz: add resume support
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-9-5c2e4a3fac1f@bootlin.com>

Add resume support.
It has been tested on J7200 SR1.0 and SR2.0.

Based on the work of Th?o Lebrun <theo.lebrun at bootlin.com>

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/phy/ti/phy-j721e-wiz.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index 45c5a4e9cd12..cde38182e34c 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -1660,12 +1660,41 @@ static void wiz_remove(struct platform_device *pdev)
 	pm_runtime_disable(dev);
 }
 
+static int wiz_resume_noirq(struct device *dev)
+{
+	struct device_node *node = dev->of_node;
+	struct wiz *wiz = dev_get_drvdata(dev);
+	int ret;
+
+	/* Enable supplemental Control override if available */
+	if (wiz->sup_legacy_clk_override)
+		regmap_field_write(wiz->sup_legacy_clk_override, 1);
+
+	wiz_clock_init(wiz);
+
+	ret = wiz_init(wiz);
+	if (ret) {
+		dev_err(dev, "WIZ initialization failed\n");
+		goto err_wiz_init;
+	}
+
+	return 0;
+
+err_wiz_init:
+	wiz_clock_cleanup(wiz, node);
+
+	return ret;
+}
+
+static DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, NULL, wiz_resume_noirq);
+
 static struct platform_driver wiz_driver = {
 	.probe		= wiz_probe,
 	.remove_new	= wiz_remove,
 	.driver		= {
 		.name	= "wiz",
 		.of_match_table = wiz_id_table,
+		.pm	= pm_sleep_ptr(&wiz_pm_ops),
 	},
 };
 module_platform_driver(wiz_driver);

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:53 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:53 +0100
Subject: [PATCH v3 08/18] phy: ti: phy-j721e-wiz: split wiz_clock_init()
 function
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-8-5c2e4a3fac1f@bootlin.com>

The wiz_clock_init() function mixes probe and hardware configuration.
Rename the wiz_clock_init() to wiz_clock_probe() and move the hardware
configuration part in a new function named wiz_clock_init().

This hardware configuration sequence must be called during the resume
stage of the driver.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/phy/ti/phy-j721e-wiz.c | 65 ++++++++++++++++++++++++------------------
 1 file changed, 37 insertions(+), 28 deletions(-)

diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index ce8a99801a4c..45c5a4e9cd12 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -1076,25 +1076,11 @@ static int wiz_clock_register(struct wiz *wiz)
 	return ret;
 }
 
-static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
+static void wiz_clock_init(struct wiz *wiz)
 {
-	const struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
-	struct device *dev = wiz->dev;
-	struct device_node *clk_node;
-	const char *node_name;
 	unsigned long rate;
-	struct clk *clk;
-	int ret;
-	int i;
-
-	clk = devm_clk_get(dev, "core_ref_clk");
-	if (IS_ERR(clk))
-		return dev_err_probe(dev, PTR_ERR(clk),
-				     "core_ref_clk clock not found\n");
-
-	wiz->input_clks[WIZ_CORE_REFCLK] = clk;
 
-	rate = clk_get_rate(clk);
+	rate = clk_get_rate(wiz->input_clks[WIZ_CORE_REFCLK]);
 	if (rate >= 100000000)
 		regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x1);
 	else
@@ -1119,6 +1105,39 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
 		break;
 	}
 
+	if (wiz->input_clks[WIZ_CORE_REFCLK1]) {
+		rate = clk_get_rate(wiz->input_clks[WIZ_CORE_REFCLK1]);
+		if (rate >= 100000000)
+			regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x1);
+		else
+			regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x3);
+
+	}
+
+	rate = clk_get_rate(wiz->input_clks[WIZ_EXT_REFCLK]);
+	if (rate >= 100000000)
+		regmap_field_write(wiz->pma_cmn_refclk_mode, 0x0);
+	else
+		regmap_field_write(wiz->pma_cmn_refclk_mode, 0x2);
+}
+
+static int wiz_clock_probe(struct wiz *wiz, struct device_node *node)
+{
+	const struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
+	struct device *dev = wiz->dev;
+	struct device_node *clk_node;
+	const char *node_name;
+	struct clk *clk;
+	int ret;
+	int i;
+
+	clk = devm_clk_get(dev, "core_ref_clk");
+	if (IS_ERR(clk))
+		return dev_err_probe(dev, PTR_ERR(clk),
+				     "core_ref_clk clock not found\n");
+
+	wiz->input_clks[WIZ_CORE_REFCLK] = clk;
+
 	if (wiz->data->pma_cmn_refclk1_int_mode) {
 		clk = devm_clk_get(dev, "core_ref1_clk");
 		if (IS_ERR(clk))
@@ -1126,12 +1145,6 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
 					     "core_ref1_clk clock not found\n");
 
 		wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
-
-		rate = clk_get_rate(clk);
-		if (rate >= 100000000)
-			regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x1);
-		else
-			regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x3);
 	}
 
 	clk = devm_clk_get(dev, "ext_ref_clk");
@@ -1141,11 +1154,7 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
 
 	wiz->input_clks[WIZ_EXT_REFCLK] = clk;
 
-	rate = clk_get_rate(clk);
-	if (rate >= 100000000)
-		regmap_field_write(wiz->pma_cmn_refclk_mode, 0x0);
-	else
-		regmap_field_write(wiz->pma_cmn_refclk_mode, 0x2);
+	wiz_clock_init(wiz);
 
 	switch (wiz->type) {
 	case AM64_WIZ_10G:
@@ -1589,7 +1598,7 @@ static int wiz_probe(struct platform_device *pdev)
 		goto err_get_sync;
 	}
 
-	ret = wiz_clock_init(wiz, node);
+	ret = wiz_clock_probe(wiz, node);
 	if (ret < 0) {
 		dev_warn(dev, "Failed to initialize clocks\n");
 		goto err_get_sync;

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:55 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:55 +0100
Subject: [PATCH v3 10/18] phy: cadence-torrent: extract calls to clk_get
 from cdns_torrent_clk
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-10-5c2e4a3fac1f@bootlin.com>

Extract calls to clk_get from cdns_torrent_clk into a separate function.
It needs to call cdns_torrent_clk at resume without looking up the clock.

Based on the work of Th?o Lebrun <theo.lebrun at bootlin.com>

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/phy/cadence/phy-cadence-torrent.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index a75c96385c57..803a76acf2fd 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -2681,18 +2681,21 @@ static int cdns_torrent_reset(struct cdns_torrent_phy *cdns_phy)
 	return 0;
 }
 
+static int cdns_torrent_of_get_clk(struct cdns_torrent_phy *cdns_phy)
+{
+	cdns_phy->clk = devm_clk_get(cdns_phy->dev, "refclk");
+	if (IS_ERR(cdns_phy->clk))
+		return dev_err_probe(cdns_phy->dev, PTR_ERR(cdns_phy->clk),
+				     "phy ref clock not found\n");
+
+	return 0;
+}
+
 static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)
 {
-	struct device *dev = cdns_phy->dev;
 	unsigned long ref_clk_rate;
 	int ret;
 
-	cdns_phy->clk = devm_clk_get(dev, "refclk");
-	if (IS_ERR(cdns_phy->clk)) {
-		dev_err(dev, "phy ref clock not found\n");
-		return PTR_ERR(cdns_phy->clk);
-	}
-
 	ret = clk_prepare_enable(cdns_phy->clk);
 	if (ret) {
 		dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
@@ -2776,6 +2779,10 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = cdns_torrent_of_get_clk(cdns_phy);
+	if (ret)
+		goto clk_cleanup;
+
 	regmap_field_read(cdns_phy->phy_pma_cmn_ctrl_1, &already_configured);
 
 	if (!already_configured) {

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:56 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:56 +0100
Subject: [PATCH v3 11/18] phy: cadence-torrent: register resets even if the
 phy is already configured
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-11-5c2e4a3fac1f@bootlin.com>

Resets are needed during suspend and resume stages.
So they shall be registered during the probe even the phy is already
initialized.

The function cdns_torrent_reset is renamed cdns_torrent_of_get_reset() to
make it clear.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/phy/cadence/phy-cadence-torrent.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index 803a76acf2fd..bba10ca0bfdd 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -2660,7 +2660,7 @@ static int cdns_torrent_clk_register(struct cdns_torrent_phy *cdns_phy)
 	return 0;
 }
 
-static int cdns_torrent_reset(struct cdns_torrent_phy *cdns_phy)
+static int cdns_torrent_of_get_reset(struct cdns_torrent_phy *cdns_phy)
 {
 	struct device *dev = cdns_phy->dev;
 
@@ -2779,6 +2779,10 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = cdns_torrent_of_get_reset(cdns_phy);
+	if (ret)
+		goto clk_cleanup;
+
 	ret = cdns_torrent_of_get_clk(cdns_phy);
 	if (ret)
 		goto clk_cleanup;
@@ -2786,10 +2790,6 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
 	regmap_field_read(cdns_phy->phy_pma_cmn_ctrl_1, &already_configured);
 
 	if (!already_configured) {
-		ret = cdns_torrent_reset(cdns_phy);
-		if (ret)
-			goto clk_cleanup;
-
 		ret = cdns_torrent_clk(cdns_phy);
 		if (ret)
 			goto clk_cleanup;

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:57 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:57 +0100
Subject: [PATCH v3 12/18] phy: cadence-torrent: add already_configured to
 struct cdns_torrent_phy
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-12-5c2e4a3fac1f@bootlin.com>

Add already_configured to struct cdns_torrent_phy, so it can be used at
differents stages.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/phy/cadence/phy-cadence-torrent.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index bba10ca0bfdd..b35fbc8a60e5 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -358,6 +358,7 @@ struct cdns_torrent_phy {
 	enum cdns_torrent_ref_clk ref_clk_rate;
 	struct cdns_torrent_inst phys[MAX_NUM_LANES];
 	int nsubnodes;
+	int already_configured;
 	const struct cdns_torrent_data *init_data;
 	struct regmap *regmap_common_cdb;
 	struct regmap *regmap_phy_pcs_common_cdb;
@@ -2740,7 +2741,6 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
 	struct device_node *child;
 	int ret, subnodes, node = 0, i;
 	u32 total_num_lanes = 0;
-	int already_configured;
 	u8 init_dp_regmap = 0;
 	u32 phy_type;
 
@@ -2787,9 +2787,9 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
 	if (ret)
 		goto clk_cleanup;
 
-	regmap_field_read(cdns_phy->phy_pma_cmn_ctrl_1, &already_configured);
+	regmap_field_read(cdns_phy->phy_pma_cmn_ctrl_1, &cdns_phy->already_configured);
 
-	if (!already_configured) {
+	if (!cdns_phy->already_configured) {
 		ret = cdns_torrent_clk(cdns_phy);
 		if (ret)
 			goto clk_cleanup;
@@ -2869,7 +2869,7 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
 		of_property_read_u32(child, "cdns,ssc-mode",
 				     &cdns_phy->phys[node].ssc_mode);
 
-		if (!already_configured)
+		if (!cdns_phy->already_configured)
 			gphy = devm_phy_create(dev, child, &cdns_torrent_phy_ops);
 		else
 			gphy = devm_phy_create(dev, child, &noop_ops);
@@ -2955,7 +2955,7 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
 		goto put_lnk_rst;
 	}
 
-	if (cdns_phy->nsubnodes > 1 && !already_configured) {
+	if (cdns_phy->nsubnodes > 1 && !cdns_phy->already_configured) {
 		ret = cdns_torrent_phy_configure_multilink(cdns_phy);
 		if (ret)
 			goto put_lnk_rst;

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:58 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:58 +0100
Subject: [PATCH v3 13/18] phy: cadence-torrent: remove noop_ops phy
 operations
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-13-5c2e4a3fac1f@bootlin.com>

Even if a PHY is already configured, the PHY operations are needed during
resume stage, as the PHY is in reset state.
The noop_ops PHY operations is removed to always have PHY operations.
The already_configured flag is checked at the begening of init, configure
and poweron operations to keep the already_configured behaviour.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/phy/cadence/phy-cadence-torrent.c | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index b35fbc8a60e5..52cadca4c07b 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -1593,6 +1593,9 @@ static int cdns_torrent_dp_configure(struct phy *phy,
 	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent);
 	int ret;
 
+	if (cdns_phy->already_configured)
+		return 0;
+
 	ret = cdns_torrent_dp_verify_config(inst, &opts->dp);
 	if (ret) {
 		dev_err(&phy->dev, "invalid params for phy configure\n");
@@ -1628,6 +1631,12 @@ static int cdns_torrent_phy_on(struct phy *phy)
 	u32 read_val;
 	int ret;
 
+	if (cdns_phy->already_configured) {
+		/* Give 5ms to 10ms delay for the PIPE clock to be stable */
+		usleep_range(5000, 10000);
+		return 0;
+	}
+
 	if (cdns_phy->nsubnodes == 1) {
 		/* Take the PHY lane group out of reset */
 		reset_control_deassert(inst->lnk_rst);
@@ -2306,6 +2315,9 @@ static int cdns_torrent_phy_init(struct phy *phy)
 	u32 num_regs;
 	int i, j;
 
+	if (cdns_phy->already_configured)
+		return 0;
+
 	if (cdns_phy->nsubnodes > 1) {
 		if (phy_type == TYPE_DP)
 			return cdns_torrent_dp_multilink_init(cdns_phy, inst, phy);
@@ -2443,19 +2455,6 @@ static const struct phy_ops cdns_torrent_phy_ops = {
 	.owner		= THIS_MODULE,
 };
 
-static int cdns_torrent_noop_phy_on(struct phy *phy)
-{
-	/* Give 5ms to 10ms delay for the PIPE clock to be stable */
-	usleep_range(5000, 10000);
-
-	return 0;
-}
-
-static const struct phy_ops noop_ops = {
-	.power_on	= cdns_torrent_noop_phy_on,
-	.owner		= THIS_MODULE,
-};
-
 static
 int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
 {
@@ -2869,10 +2868,7 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
 		of_property_read_u32(child, "cdns,ssc-mode",
 				     &cdns_phy->phys[node].ssc_mode);
 
-		if (!cdns_phy->already_configured)
-			gphy = devm_phy_create(dev, child, &cdns_torrent_phy_ops);
-		else
-			gphy = devm_phy_create(dev, child, &noop_ops);
+		gphy = devm_phy_create(dev, child, &cdns_torrent_phy_ops);
 		if (IS_ERR(gphy)) {
 			ret = PTR_ERR(gphy);
 			goto put_child;

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:17:59 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:17:59 +0100
Subject: [PATCH v3 14/18] phy: cadence-torrent: add suspend and resume
 support
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-14-5c2e4a3fac1f@bootlin.com>

Add suspend and resume support.

The already_configured flag is cleared during the suspend stage to force
the PHY initialization during the resume stage.

Based on the work of Th?o Lebrun <theo.lebrun at bootlin.com>

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/phy/cadence/phy-cadence-torrent.c | 54 +++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index 52cadca4c07b..f8945a11e7ca 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -3005,6 +3005,59 @@ static void cdns_torrent_phy_remove(struct platform_device *pdev)
 	cdns_torrent_clk_cleanup(cdns_phy);
 }
 
+static int cdns_torrent_phy_suspend_noirq(struct device *dev)
+{
+	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
+	int i;
+
+	reset_control_assert(cdns_phy->phy_rst);
+	reset_control_assert(cdns_phy->apb_rst);
+	for (i = 0; i < cdns_phy->nsubnodes; i++)
+		reset_control_assert(cdns_phy->phys[i].lnk_rst);
+
+	if (cdns_phy->already_configured)
+		cdns_phy->already_configured = 0;
+	else
+		clk_disable_unprepare(cdns_phy->clk);
+
+	return 0;
+}
+
+static int cdns_torrent_phy_resume_noirq(struct device *dev)
+{
+	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
+	int node = cdns_phy->nsubnodes;
+	int ret, i;
+
+	ret = cdns_torrent_clk(cdns_phy);
+	if (ret)
+		goto clk_cleanup;
+
+	/* Enable APB */
+	reset_control_deassert(cdns_phy->apb_rst);
+
+	if (cdns_phy->nsubnodes > 1) {
+		ret = cdns_torrent_phy_configure_multilink(cdns_phy);
+		if (ret)
+			goto put_lnk_rst;
+	}
+
+	return 0;
+
+put_lnk_rst:
+	for (i = 0; i < node; i++)
+		reset_control_assert(cdns_phy->phys[i].lnk_rst);
+	reset_control_assert(cdns_phy->apb_rst);
+	clk_disable_unprepare(cdns_phy->clk);
+clk_cleanup:
+	cdns_torrent_clk_cleanup(cdns_phy);
+	return ret;
+}
+
+static DEFINE_NOIRQ_DEV_PM_OPS(cdns_torrent_phy_pm_ops,
+			       cdns_torrent_phy_suspend_noirq,
+			       cdns_torrent_phy_resume_noirq);
+
 /* USB and DP link configuration */
 static struct cdns_reg_pairs usb_dp_link_cmn_regs[] = {
 	{0x0002, PHY_PLL_CFG},
@@ -4576,6 +4629,7 @@ static struct platform_driver cdns_torrent_phy_driver = {
 	.driver = {
 		.name	= "cdns-torrent-phy",
 		.of_match_table	= cdns_torrent_phy_of_match,
+		.pm	= pm_sleep_ptr(&cdns_torrent_phy_pm_ops),
 	}
 };
 module_platform_driver(cdns_torrent_phy_driver);

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:18:00 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:18:00 +0100
Subject: [PATCH v3 15/18] PCI: cadence: extract link setup sequence from
 cdns_pcie_host_setup()
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-15-5c2e4a3fac1f@bootlin.com>

The function cdns_pcie_host_setup() mixes probe structure and link setup.

The link setup must be done during the resume sequence. So extract it from
cdns_pcie_host_setup() and create a dedicated function.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/pci/controller/cadence/pcie-cadence-host.c | 39 ++++++++++++++--------
 drivers/pci/controller/cadence/pcie-cadence.h      |  6 ++++
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 5b14f7ee3c79..93d9922730af 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -497,6 +497,30 @@ static int cdns_pcie_host_init(struct device *dev,
 	return cdns_pcie_host_init_address_translation(rc);
 }
 
+int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	struct device *dev = rc->pcie.dev;
+	int ret;
+
+	if (rc->quirk_detect_quiet_flag)
+		cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
+
+	cdns_pcie_host_enable_ptm_response(pcie);
+
+	ret = cdns_pcie_start_link(pcie);
+	if (ret) {
+		dev_err(dev, "Failed to start link\n");
+		return ret;
+	}
+
+	ret = cdns_pcie_host_start_link(rc);
+	if (ret)
+		dev_dbg(dev, "PCIe link never came up\n");
+
+	return 0;
+}
+
 int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
 {
 	struct device *dev = rc->pcie.dev;
@@ -533,20 +557,9 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
 		return PTR_ERR(rc->cfg_base);
 	rc->cfg_res = res;
 
-	if (rc->quirk_detect_quiet_flag)
-		cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
-
-	cdns_pcie_host_enable_ptm_response(pcie);
-
-	ret = cdns_pcie_start_link(pcie);
-	if (ret) {
-		dev_err(dev, "Failed to start link\n");
-		return ret;
-	}
-
-	ret = cdns_pcie_host_start_link(rc);
+	ret = cdns_pcie_host_link_setup(rc);
 	if (ret)
-		dev_dbg(dev, "PCIe link never came up\n");
+		return ret;
 
 	for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
 		rc->avail_ib_bar[bar] = true;
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 373cb50fcd15..4c687aeb810e 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -515,10 +515,16 @@ static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
 }
 
 #ifdef CONFIG_PCIE_CADENCE_HOST
+int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc);
 int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
 void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
 			       int where);
 #else
+static inline int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
+{
+	return 0;
+}
+
 static inline int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
 {
 	return 0;

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:18:01 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:18:01 +0100
Subject: [PATCH v3 16/18] PCI: cadence: set cdns_pcie_host_init() global
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-16-5c2e4a3fac1f@bootlin.com>

During the resume sequence of the host, cdns_pcie_host_init() needs to be
called, so set it global.

The dev function parameter is removed, as it isn't used.

Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/pci/controller/cadence/pcie-cadence-host.c | 5 ++---
 drivers/pci/controller/cadence/pcie-cadence.h      | 6 ++++++
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 93d9922730af..8af95e9da7ce 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -485,8 +485,7 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
 	return cdns_pcie_host_map_dma_ranges(rc);
 }
 
-static int cdns_pcie_host_init(struct device *dev,
-			       struct cdns_pcie_rc *rc)
+int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
 {
 	int err;
 
@@ -564,7 +563,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
 	for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
 		rc->avail_ib_bar[bar] = true;
 
-	ret = cdns_pcie_host_init(dev, rc);
+	ret = cdns_pcie_host_init(rc);
 	if (ret)
 		return ret;
 
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 4c687aeb810e..d55dfd173f22 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -516,6 +516,7 @@ static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
 
 #ifdef CONFIG_PCIE_CADENCE_HOST
 int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc);
+int cdns_pcie_host_init(struct cdns_pcie_rc *rc);
 int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
 void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
 			       int where);
@@ -525,6 +526,11 @@ static inline int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
 	return 0;
 }
 
+static inline int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
+{
+	return 0;
+}
+
 static inline int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
 {
 	return 0;

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:18:02 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:18:02 +0100
Subject: [PATCH v3 17/18] PCI: j721e: add reset GPIO to struct j721e_pcie
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-17-5c2e4a3fac1f@bootlin.com>

From: Th?o Lebrun <theo.lebrun at bootlin.com>

Add reset GPIO to struct j721e_pcie, so it can be used at suspend and
resume stages.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 2c87e7728a65..9c588e79f5ac 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -54,6 +54,7 @@ struct j721e_pcie {
 	struct clk		*refclk;
 	u32			mode;
 	u32			num_lanes;
+	struct gpio_desc	*reset_gpio;
 	void __iomem		*user_cfg_base;
 	void __iomem		*intd_cfg_base;
 	u32			linkdown_irq_regfield;
@@ -359,7 +360,6 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 	struct j721e_pcie *pcie;
 	struct cdns_pcie_rc *rc = NULL;
 	struct cdns_pcie_ep *ep = NULL;
-	struct gpio_desc *gpiod;
 	void __iomem *base;
 	struct clk *clk;
 	u32 num_lanes;
@@ -468,9 +468,9 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 
 	switch (mode) {
 	case PCI_MODE_RC:
-		gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
-		if (IS_ERR(gpiod)) {
-			ret = PTR_ERR(gpiod);
+		pcie->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+		if (IS_ERR(pcie->reset_gpio)) {
+			ret = PTR_ERR(pcie->reset_gpio);
 			if (ret != -EPROBE_DEFER)
 				dev_err(dev, "Failed to get reset GPIO\n");
 			goto err_get_sync;
@@ -504,9 +504,9 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 		 * mode is selected while enabling the PHY. So deassert PERST#
 		 * after 100 us.
 		 */
-		if (gpiod) {
+		if (pcie->reset_gpio) {
 			usleep_range(100, 200);
-			gpiod_set_value_cansleep(gpiod, 1);
+			gpiod_set_value_cansleep(pcie->reset_gpio, 1);
 		}
 
 		ret = cdns_pcie_host_setup(rc);

-- 
2.39.2



From thomas.richard at bootlin.com  Thu Feb 15 07:18:03 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Thu, 15 Feb 2024 16:18:03 +0100
Subject: [PATCH v3 18/18] PCI: j721e: add suspend and resume support
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240102-j7200-pcie-s2r-v3-18-5c2e4a3fac1f@bootlin.com>

From: Th?o Lebrun <theo.lebrun at bootlin.com>

Add suspend and resume support. Only the rc mode is supported.

During the suspend stage PERST# is asserted, then deasserted during the
resume stage.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 90 ++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 9c588e79f5ac..cfa7ba237e1a 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -6,6 +6,7 @@
  * Author: Kishon Vijay Abraham I <kishon at ti.com>
  */
 
+#include <linux/clk-provider.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
@@ -18,10 +19,13 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
+#include <linux/container_of.h>
 
 #include "../../pci.h"
 #include "pcie-cadence.h"
 
+#define cdns_pcie_to_rc(p) container_of(p, struct cdns_pcie_rc, pcie)
+
 #define ENABLE_REG_SYS_2	0x108
 #define STATUS_REG_SYS_2	0x508
 #define STATUS_CLR_REG_SYS_2	0x708
@@ -554,6 +558,91 @@ static void j721e_pcie_remove(struct platform_device *pdev)
 	pm_runtime_disable(dev);
 }
 
+static int j721e_pcie_suspend_noirq(struct device *dev)
+{
+	struct j721e_pcie *pcie = dev_get_drvdata(dev);
+
+	if (pcie->mode == PCI_MODE_RC) {
+		gpiod_set_value_cansleep(pcie->reset_gpio, 0);
+		clk_disable_unprepare(pcie->refclk);
+	}
+
+	cdns_pcie_disable_phy(pcie->cdns_pcie);
+
+	return 0;
+}
+
+static int j721e_pcie_resume_noirq(struct device *dev)
+{
+	struct j721e_pcie *pcie = dev_get_drvdata(dev);
+	struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;
+	int ret;
+
+	ret = j721e_pcie_ctrl_init(pcie);
+	if (ret < 0) {
+		dev_err(dev, "j721e_pcie_ctrl_init failed\n");
+		return ret;
+	}
+
+	j721e_pcie_config_link_irq(pcie);
+
+	/*
+	 * This is not called explicitly in the probe, it is called by
+	 * cdns_pcie_init_phy.
+	 */
+	ret = cdns_pcie_enable_phy(pcie->cdns_pcie);
+	if (ret < 0) {
+		dev_err(dev, "cdns_pcie_enable_phy failed\n");
+		return -ENODEV;
+	}
+
+	if (pcie->mode == PCI_MODE_RC) {
+		struct cdns_pcie_rc *rc = cdns_pcie_to_rc(cdns_pcie);
+
+		ret = clk_prepare_enable(pcie->refclk);
+		if (ret < 0) {
+			dev_err(dev, "clk_prepare_enable failed\n");
+			return -ENODEV;
+		}
+
+		/*
+		 * "Power Sequencing and Reset Signal Timings" table in
+		 * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 3.0
+		 * indicates PERST# should be deasserted after minimum of 100us
+		 * once REFCLK is stable. The REFCLK to the connector in RC
+		 * mode is selected while enabling the PHY. So deassert PERST#
+		 * after 100 us.
+		 */
+		if (pcie->reset_gpio) {
+			usleep_range(100, 200);
+			gpiod_set_value_cansleep(pcie->reset_gpio, 1);
+		}
+
+		ret = cdns_pcie_host_link_setup(rc);
+		if (ret < 0) {
+			clk_disable_unprepare(pcie->refclk);
+			return ret;
+		}
+
+		/*
+		 * Reset internal status of BARs to force reinitialization in
+		 * cdns_pcie_host_init().
+		 */
+		for (enum cdns_pcie_rp_bar bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
+			rc->avail_ib_bar[bar] = true;
+
+		ret = cdns_pcie_host_init(rc);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static DEFINE_NOIRQ_DEV_PM_OPS(j721e_pcie_pm_ops,
+			       j721e_pcie_suspend_noirq,
+			       j721e_pcie_resume_noirq);
+
 static struct platform_driver j721e_pcie_driver = {
 	.probe  = j721e_pcie_probe,
 	.remove_new = j721e_pcie_remove,
@@ -561,6 +650,7 @@ static struct platform_driver j721e_pcie_driver = {
 		.name	= "j721e-pcie",
 		.of_match_table = of_j721e_pcie_match,
 		.suppress_bind_attrs = true,
+		.pm	= pm_sleep_ptr(&j721e_pcie_pm_ops),
 	},
 };
 builtin_platform_driver(j721e_pcie_driver);

-- 
2.39.2



From maz at kernel.org  Thu Feb 15 07:19:02 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 15 Feb 2024 15:19:02 +0000
Subject: [PATCH 2/2] arm64: cpufeatures: Only check for NV1 if NV is present
In-Reply-To: <Zc1wsKzAvooOvR-v@linux.dev>
References: <20240212144736.1933112-1-maz@kernel.org>
	<CGME20240212144758eucas1p1345ba6f2000c10a4b33f8575f0a8d22b@eucas1p1.samsung.com>
	<20240212144736.1933112-3-maz@kernel.org>
	<5b2d8fee-9d0f-48f7-b9ec-b86e95387a61@samsung.com>
	<86bk8k5ts3.wl-maz@kernel.org>
	<Zc1wsKzAvooOvR-v@linux.dev>
Message-ID: <86le7l4uxl.wl-maz@kernel.org>

On Thu, 15 Feb 2024 02:02:24 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Tue, Feb 13, 2024 at 02:21:48PM +0000, Marc Zyngier wrote:
> > From cd75279d3b6c387c13972b61c486a203d9652e97 Mon Sep 17 00:00:00 2001
> > From: Marc Zyngier <maz at kernel.org>
> > Date: Tue, 13 Feb 2024 13:37:57 +0000
> > Subject: [PATCH] arm64: cpufeatures: Fix FEAT_NV check when checking for
> >  FEAT_NV1
> > 
> > Using this_cpu_has_cap() has the potential to go wrong when
> > used system-wide on a preemptible kernel. Instead, use the
> > __system_matches_cap() helper when checking for FEAT_NV in the
> > FEAT_NV1 probing helper.
> > 
> > Fixes: 3673d01a2f55 ("arm64: cpufeatures: Only check for NV1 if NV is present")
> > Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> 
> b4 wasn't very happy with grabbing this patch in reply to a series
> (probably user error), but I've picked this up for kvmarm/next.
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git/commit/?id=9aa030cee1c45d6e962f6bf22ba63d4aff2b1644

Ah, sorry, I should have posted as a proper patch instead of an inline
patch. Thanks for picking it up despite that.

	M.

-- 
Without deviation from the norm, progress is not possible.


From diogo.ivo at siemens.com  Thu Feb 15 07:22:01 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Thu, 15 Feb 2024 15:22:01 +0000
Subject: [PATCH net-next v2] net: ti: icssg-prueth: Remove duplicate cleanup calls in emac_ndo_stop()
Message-ID: <20240215152203.431268-1-diogo.ivo@siemens.com>

Remove the duplicate calls to prueth_emac_stop() and
prueth_cleanup_tx_chns() in emac_ndo_stop().

Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
Reviewed-by: Roger Quadros <rogerq at kernel.org>
Reviewed-by: MD Danish Anwar <danishanwar at ti.com>
---
Changes in v2:
 - Removed Fixes: tags
 - Added Reviewed-by's

 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index 411898a4f38c..cf7b73f8f450 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -1489,9 +1489,6 @@ static int emac_ndo_stop(struct net_device *ndev)
 	/* Destroying the queued work in ndo_stop() */
 	cancel_delayed_work_sync(&emac->stats_work);
 
-	/* stop PRUs */
-	prueth_emac_stop(emac);
-
 	if (prueth->emacs_initialized == 1)
 		icss_iep_exit(emac->iep);
 
@@ -1502,7 +1499,6 @@ static int emac_ndo_stop(struct net_device *ndev)
 
 	free_irq(emac->rx_chns.irq[rx_flow], emac);
 	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
-	prueth_cleanup_tx_chns(emac);
 
 	prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows);
 	prueth_cleanup_tx_chns(emac);
-- 
2.43.1



From jpaulo.silvagoncalves at gmail.com  Thu Feb 15 07:23:04 2024
From: jpaulo.silvagoncalves at gmail.com (Joao Paulo Goncalves)
Date: Thu, 15 Feb 2024 12:23:04 -0300
Subject: [PATCH V4 0/6] soc: imx8mp: Finish support for HDMI
In-Reply-To: <20240210204606.11944-1-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
Message-ID: <20240215152304.307972-1-jpaulo.silvagoncalves@gmail.com>

>The i.MX8M Plus has an HDMI controller, which depends on several
>other systems.  The Parallel Video Interface (PVI) and the
>HDMI-TX are already in the Linux-Next staging area 20240209, but
>the HDMI PHY driver and several device trees updates are still needed.

>This series is adapted from multiple series from Lucas Stach with
>edits and suggestions from feedback from various attemps, but it
>since it's difficult to use and test them independently,
>I merged them into on unified series.  The version history is a
>bit ambiguous since different components were submitted at different
>times and had different amount of attempts.

>The previous attempt I did used the wrong starting point for the PHY,
>so this update includes a newer starting point with tags from that version
>and fixes from various people's feedback.  I hope I caught them all, but
>I apologize if I missed something. Any tags from the previous attempt I
>made were intentionally dropped, because of the significant change,
>but I kept tags from the newer version I grabbed from patchwork.

>Because several items from the last attempt were merged, this
>series is only focussed on adding the HDMI PHY driver, and enabling
>the power domain, irqsteer interrupt controller, and HDMI pipeline
>in the device tree. The version numbers are a bit strange since
>these all got pulled from various attempts with different versions,
>but I wanted to push them together as a series to complete the pending
>work.

Tested-by: Joao Paulo Goncalves <joao.goncalves at toradex.com> # Toradex Verdin iMX8MP

Thanks!

Regards,
Joao Paulo Goncalves


From andy at kernel.org  Thu Feb 15 07:27:53 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Thu, 15 Feb 2024 17:27:53 +0200
Subject: [PATCH v3 02/18] pinctrl: pinctrl-single: remove dead code in
 suspend() and resume() callbacks
In-Reply-To: <20240102-j7200-pcie-s2r-v3-2-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-2-5c2e4a3fac1f@bootlin.com>
Message-ID: <Zc4tedAhqYX3bQcw@smile.fi.intel.com>

On Thu, Feb 15, 2024 at 04:17:47PM +0100, Thomas Richard wrote:
> No need to check the pointer returned by platform_get_drvdata(), as
> platform_set_drvdata() is called during the probe.

This patch should go _after_ the next one, otherwise the commit message doesn't
tell full story and the code change bring a potential regression.

-- 
With Best Regards,
Andy Shevchenko




From maz at kernel.org  Thu Feb 15 07:29:35 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 15 Feb 2024 15:29:35 +0000
Subject: [GIT PULL] KVM/arm64 fixes for 6.8, take #2
Message-ID: <20240215152935.3093768-1-maz@kernel.org>

Hi Paolo,

Another week, another very small pull request. This time, the bug is
irritating enough that I want it fixed and backported right away. It
has only been found by inspection (thanks Will!), but once you've seen
it, you can unsee it.

If you haven't pulled the previous tag [1], you'll get both for free.

Please pull,

	M.

[1] https://lore.kernel.org/r/20240207144611.1128848-1-maz at kernel.org


The following changes since commit 42dfa94d802a48c871e2017cbf86153270c86632:

  KVM: arm64: Do not source virt/lib/Kconfig twice (2024-02-04 13:08:28 +0000)
are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-fixes-6.8-2

for you to fetch changes up to c60d847be7b8e69e419e02a2b3d19c2842a3c35d:

  KVM: arm64: Fix double-free following kvm_pgtable_stage2_free_unlinked() (2024-02-13 19:22:03 +0000)

----------------------------------------------------------------
KVM/arm64 fixes for 6.8, take #2

- Avoid dropping the page refcount twice when freeing an unlinked
  page-table subtree.

----------------------------------------------------------------
Will Deacon (1):
      KVM: arm64: Fix double-free following kvm_pgtable_stage2_free_unlinked()

 arch/arm64/kvm/hyp/pgtable.c | 2 --
 1 file changed, 2 deletions(-)


From andy at kernel.org  Thu Feb 15 07:29:55 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Thu, 15 Feb 2024 17:29:55 +0200
Subject: [PATCH v3 05/18] mux: add mux_chip_resume() function
In-Reply-To: <20240102-j7200-pcie-s2r-v3-5-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-5-5c2e4a3fac1f@bootlin.com>
Message-ID: <Zc4t82V9czlEqamL@smile.fi.intel.com>

On Thu, Feb 15, 2024 at 04:17:50PM +0100, Thomas Richard wrote:
> The mux_chip_resume() function restores a mux_chip using the cached state
> of each mux.

...

> +int mux_chip_resume(struct mux_chip *mux_chip)
> +{
> +	int global_ret = 0;
> +	int ret, i;
> +
> +	for (i = 0; i < mux_chip->controllers; ++i) {
> +		struct mux_control *mux = &mux_chip->mux[i];
> +
> +		if (mux->cached_state == MUX_CACHE_UNKNOWN)
> +			continue;
> +
> +		ret = mux_control_set(mux, mux->cached_state);
> +		if (ret < 0) {
> +			dev_err(&mux_chip->dev, "unable to restore state\n");
> +			if (!global_ret)
> +				global_ret = ret;

Hmm... This will record the first error and continue.

> +		}
> +	}
> +	return global_ret;

So here, we actually will get stale data in case there are > 1 failures.

> +}

-- 
With Best Regards,
Andy Shevchenko




From andy at kernel.org  Thu Feb 15 07:30:44 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Thu, 15 Feb 2024 17:30:44 +0200
Subject: [PATCH v3 04/18] i2c: omap: wakeup the controller during
 suspend() callback
In-Reply-To: <20240102-j7200-pcie-s2r-v3-4-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-4-5c2e4a3fac1f@bootlin.com>
Message-ID: <Zc4uJBUuBzpNgxDP@smile.fi.intel.com>

On Thu, Feb 15, 2024 at 04:17:49PM +0100, Thomas Richard wrote:
> A device may need the controller up during suspend_noirq() or
> resume_noirq().
> But if the controller is autosuspended, there is no way to wakeup it during
> suspend_noirq() or resume_noirq() because runtime pm is disabled at this
> time.
> 
> The suspend() callback wakes up the controller, so it is available until
> its suspend_noirq() callback (pm_runtime_force_suspend()).
> During the resume, it's restored by resume_noirq() callback
> (pm_runtime_force_resume()). Then resume() callback enables autosuspend.
> 
> So the controller is up during a little time slot in suspend and resume
> sequences even if it's not used.

...

> +	/*
> +	 * If the controller is autosuspended, there is no way to wakeup it once
> +	 * runtime pm is disabled (in suspend_late()).
> +	 * But a device may need the controller up during suspend_noirq() or
> +	 * resume_noirq().
> +	 * Wakeup the controller while runtime pm is enabled, so it is available until
> +	 * its suspend_noirq(), and from resume_noirq().
> +	 */

It's a bit random line lengths...
Can you repack this to be more condensed?

-- 
With Best Regards,
Andy Shevchenko




From andy at kernel.org  Thu Feb 15 07:33:32 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Thu, 15 Feb 2024 17:33:32 +0200
Subject: [PATCH v3 07/18] phy: ti: phy-j721e-wiz: use dev_err_probe()
 instead of dev_err()
In-Reply-To: <20240102-j7200-pcie-s2r-v3-7-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-7-5c2e4a3fac1f@bootlin.com>
Message-ID: <Zc4uzCsKgx67xI3P@smile.fi.intel.com>

On Thu, Feb 15, 2024 at 04:17:52PM +0100, Thomas Richard wrote:
> Use dev_err_probe() instead of dev_err() in wiz_clock_init() to simplify
> the code and standardize the error output.

...

>  		ret = wiz_clock_register(wiz);
>  		if (ret)
> -			dev_err(dev, "Failed to register wiz clocks\n");
> +			dev_err_probe(dev, ret, "Failed to register wiz clocks\n");
>  		return ret;

Maybe

		if (ret)
			return dev_err_probe(dev, ret, "Failed to register wiz clocks\n");

		return 0;

?

...

>  		if (!clk_node) {
> -			dev_err(dev, "Unable to get %s node\n", node_name);
>  			ret = -EINVAL;
> +			dev_err_probe(dev, ret, "Unable to get %s node\n", node_name);
>  			goto err;

			ret = dev_err_probe(..., -EINVAL, ...);

>  		}

-- 
With Best Regards,
Andy Shevchenko




From pstanner at redhat.com  Thu Feb 15 07:40:10 2024
From: pstanner at redhat.com (Philipp Stanner)
Date: Thu, 15 Feb 2024 16:40:10 +0100
Subject: [PATCH v3 00/18] Add suspend to ram support for PCIe on J7200
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <1b2ffe636a19faef87b9c48fee6d17bfb9f1a3bf.camel@redhat.com>

On Thu, 2024-02-15 at 16:17 +0100, Thomas Richard wrote:
> This add suspend to ram support for the PCIe (RC mode) on J7200
> platform.
> 
> In RC mode, the reset pin for endpoints is managed by a gpio expander
> on a
> i2c bus. This pin shall be managed in suspend_noirq() and
> resume_noirq().
> The suspend/resume has been moved to suspend_noirq()/resume_noirq()
> for
> pca953x (expander) and pinctrl-single.
> 
> To do i2c accesses during suspend_noirq/resume_noirq, we need to
> force the
> wakeup of the i2c controller (which is autosuspended) during suspend
> callback. 
> It's the only way to wakeup the controller if it's autosuspended, as
> runtime pm is disabled in suspend_noirq and resume_noirq.
> 
> The main change in this v3 is the removal of the probe boolean for
> the
> functions wiz_clock_probe() and cdns_pcie_host_setup().
> Their contents were split in multiple functions which are called in
> the
> resume_noirq() callbacks.
> 
> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
> ---
> Changes in v3:
> - pinctrl-single: split patch in two parts, a first patch to remove
> the
> ? dead code, a second to move suspend()/resume() callbacks to noirq.
> - i2c-omap: add a comments above the suspend_noirq() callback.
> - mux: now mux_chip_resume() try to restores all muxes, then return 0
> if
> ? all is ok or the first failure.
> - mmio: fix commit message.
> - phy-j721e-wiz: add a patch to use dev_err_probe() instead of
> dev_err() in
> ? the wiz_clock_init() function.
> - phy-j721e-wiz: remove probe boolean for the wiz_clock_init(),
> rename the
> ? function to wiz_clock_probe(), extract hardware configuration part
> in a
> ? new function wiz_clock_init().
> - phy-cadence-torrent: use dev_err_probe() and fix commit messages
> - pcie-cadence-host: remove probe boolean for the
> cdns_pcie_host_setup()
> ? function and extract the link setup part in a new function
> ? cdns_pcie_host_link_setup().
> - pcie-cadence-host: make cdns_pcie_host_init() global.
> - pci-j721e: use the cdns_pcie_host_link_setup()
> cdns_pcie_host_init()
> ? functions in the resume_noirq() callback.
> - Link to v2:
> https://lore.kernel.org/r/20240102-j7200-pcie-s2r-v2-0-8e4f7d228ec2 at bootlin.com
> 
> Changes in v2:
> - all: fix commits messages.
> - all: use DEFINE_NOIRQ_DEV_PM_OPS and pm_sleep_ptr macros.
> - all: remove useless #ifdef CONFIG_PM.
> - pinctrl-single: drop dead code
> - mux: add mux_chip_resume() function in mux core.
> - mmio: resume sequence is now a call to mux_chip_resume().
> - phy-cadence-torrent: fix typo in resume sequence
> (reset_control_assert()
> ? instead of reset_control_put()).
> - phy-cadence-torrent: use PHY instead of phy.
> - pci-j721e: do not shadow cdns_pcie_host_setup return code in resume
> ? sequence.
> - pci-j721e: drop dead code.
> - Link to v1:
> https://lore.kernel.org/r/20240102-j7200-pcie-s2r-v1-0-84e55da52400 at bootlin.com
> 
> ---
> Thomas Richard (15):
> ????? gpio: pca953x: move suspend()/resume() to
> suspend_noirq()/resume_noirq()
> ????? pinctrl: pinctrl-single: remove dead code in suspend() and
> resume() callbacks
> ????? pinctrl: pinctrl-single: move suspend()/resume() callbacks to
> noirq
> ????? i2c: omap: wakeup the controller during suspend() callback
> ????? mux: add mux_chip_resume() function
> ????? phy: ti: phy-j721e-wiz: use dev_err_probe() instead of
> dev_err()
> ????? phy: ti: phy-j721e-wiz: split wiz_clock_init() function
> ????? phy: ti: phy-j721e-wiz: add resume support
> ????? phy: cadence-torrent: extract calls to clk_get from
> cdns_torrent_clk
> ????? phy: cadence-torrent: register resets even if the phy is
> already configured
> ????? phy: cadence-torrent: add already_configured to struct
> cdns_torrent_phy
> ????? phy: cadence-torrent: remove noop_ops phy operations
> ????? phy: cadence-torrent: add suspend and resume support
> ????? PCI: cadence: extract link setup sequence from
> cdns_pcie_host_setup()
> ????? PCI: cadence: set cdns_pcie_host_init() global
> 
> Th?o Lebrun (3):
> ????? mux: mmio: add resume support
> ????? PCI: j721e: add reset GPIO to struct j721e_pcie
> ????? PCI: j721e: add suspend and resume support


For the PCI patches Bjorn is most likely going to ask you to adjust
them to PCI's common commit style; see here [1]

In particular, PCI (afaik) has no convention for naming subcomponents
such as j721e and the info following the : is written beginning with an
upper case, e.g.

PCI: Add suspend and resume support for j721e


Regards,
P.

[1] https://lore.kernel.org/linux-pci/20171026223701.GA25649 at bhelgaas-glaptop.roam.corp.google.com/


> 
> ?drivers/gpio/gpio-pca953x.c??????????????????????? |?? 7 +-
> ?drivers/i2c/busses/i2c-omap.c????????????????????? |? 22 ++++
> ?drivers/mux/core.c???????????????????????????????? |? 30 +++++
> ?drivers/mux/mmio.c???????????????????????????????? |? 12 ++
> ?drivers/pci/controller/cadence/pci-j721e.c???????? | 102
> ++++++++++++++++-
> ?drivers/pci/controller/cadence/pcie-cadence-host.c |? 44 +++++---
> ?drivers/pci/controller/cadence/pcie-cadence.h????? |? 12 ++
> ?drivers/phy/cadence/phy-cadence-torrent.c????????? | 121
> +++++++++++++++------
> ?drivers/phy/ti/phy-j721e-wiz.c???????????????????? | 119
> +++++++++++++-------
> ?drivers/pinctrl/pinctrl-single.c?????????????????? |? 28 ++---
> ?include/linux/mux/driver.h???????????????????????? |?? 1 +
> ?11 files changed, 380 insertions(+), 118 deletions(-)
> ---
> base-commit: 00ff0f9ce40db8e64fe16c424a965fd7ab769c42
> change-id: 20240102-j7200-pcie-s2r-ecb1a979e357
> 
> Best regards,



From ryan.roberts at arm.com  Thu Feb 15 07:40:59 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Thu, 15 Feb 2024 15:40:59 +0000
Subject: [PATCH v2] mm/filemap: Allow arch to request folio size for exec memory
Message-ID: <20240215154059.2863126-1-ryan.roberts@arm.com>

Change the readahead config so that if it is being requested for an
executable mapping, do a synchronous read of an arch-specified size in a
naturally aligned manner.

On arm64 if memory is physically contiguous and naturally aligned to the
"contpte" size, we can use contpte mappings, which improves utilization
of the TLB. When paired with the "multi-size THP" changes, this works
well to reduce dTLB pressure. However iTLB pressure is still high due to
executable mappings having a low liklihood of being in the required
folio size and mapping alignment, even when the filesystem supports
readahead into large folios (e.g. XFS).

The reason for the low liklihood is that the current readahead algorithm
starts with an order-2 folio and increases the folio order by 2 every
time the readahead mark is hit. But most executable memory is faulted in
fairly randomly and so the readahead mark is rarely hit and most
executable folios remain order-2. This is observed impirically and
confirmed from discussion with a gnu linker expert; in general, the
linker does nothing to group temporally accessed text together
spacially. Additionally, with the current read-around approach there are
no alignment guarrantees between the file and folio. This is
insufficient for arm64's contpte mapping requirement (order-4 for 4K
base pages).

So it seems reasonable to special-case the read(ahead) logic for
executable mappings. The trade-off is performance improvement (due to
more efficient storage of the translations in iTLB) vs potential read
amplification (due to reading too much data around the fault which won't
be used), and the latter is independent of base page size. I've chosen
64K folio size for arm64 which benefits both the 4K and 16K base page
size configs and shouldn't lead to any further read-amplification since
the old read-around path was (usually) reading blocks of 128K (with the
last 32K being async).

Performance Benchmarking
------------------------

The below shows kernel compilation and speedometer javascript benchmarks
on Ampere Altra arm64 system. (The contpte patch series is applied in
the baseline).

First, confirmation that this patch causes more memory to be contained
in 64K folios (this is for all file-backed memory so includes
non-executable too):

| File-backed folios      |   Speedometer   |  Kernel Compile |
| by size as percentage   |-----------------|-----------------|
| of all mapped file mem  | before |  after | before |  after |
|=========================|========|========|========|========|
|file-thp-aligned-16kB    |    45% |     9% |    46% |     7% |
|file-thp-aligned-32kB    |     2% |     0% |     3% |     1% |
|file-thp-aligned-64kB    |     3% |    63% |     5% |    80% |
|file-thp-aligned-128kB   |    11% |    11% |     0% |     0% |
|file-thp-unaligned-16kB  |     1% |     0% |     3% |     1% |
|file-thp-unaligned-128kB |     1% |     0% |     0% |     0% |
|file-thp-partial         |     0% |     0% |     0% |     0% |
|-------------------------|--------|--------|--------|--------|
|file-cont-aligned-64kB   |    16% |    75% |     5% |    80% |

The above shows that for both use cases, the amount of file memory
backed by 16K folios reduces and the amount backed by 64K folios
increases significantly. And the amount of memory that is contpte-mapped
significantly increases (last line).

And this is reflected in performance improvement:

Kernel Compilation (smaller is faster):
| kernel   |   real-time |   kern-time |   user-time |   peak memory |
|----------|-------------|-------------|-------------|---------------|
| before   |        0.0% |        0.0% |        0.0% |          0.0% |
| after    |       -1.6% |       -2.1% |       -1.7% |          0.0% |

Speedometer (bigger is faster):
| kernel   |   runs_per_min |   peak memory |
|----------|----------------|---------------|
| before   |           0.0% |          0.0% |
| after    |           1.3% |          1.0% |

Both benchmarks show a ~1.5% improvement once the patch is applied.

Alternatives
------------

I considered (and rejected for now - but I anticipate this patch will
stimulate discussion around what the best approach is) alternative
approaches:

  - Expose a global user-controlled knob to set the preferred folio
    size; this would move policy to user space and allow (e.g.) setting
    it to PMD-size for even better iTLB utilizaiton. But this would add
    ABI, and I prefer to start with the simplest approach first. It also
    has the downside that a change wouldn't apply to memory already in
    the page cache that is in active use (e.g. libc) so we don't get the
    same level of utilization as for something that is fixed from boot.

  - Add a per-vma attribute to allow user space to specify preferred
    folio size for memory faulted from the range. (we've talked about
    such a control in the context of mTHP). The dynamic loader would
    then be responsible for adding the annotations. Again this feels
    like something that could be added later if value was demonstrated.

  - Enhance MADV_COLLAPSE to collapse to THP sizes less than PMD-size.
    This would still require dynamic linker involvement, but would
    additionally neccessitate a copy and all memory in the range would
    be synchronously faulted in, adding to application load time. It
    would work for filesystems that don't support large folios though.

Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---

Hi All,

This applies on top of mm-unstable (157d6f218d89). But it requires the series at
[2] to realize the performance improvements (I'm hoping [2] will be added to
mm-unstable imminently).

I didn't get a huge amount of feedback from the RFC, except for Matthew
kind-of-implying that he agrees with the principle. Barry initially raised some
concerns about the potential for performance regression with filesystems that
don't support large folios, but I think he ended up coming around to Matthew's
view that this should be ok in principle.

So I'm trying my luck with a v2 with just one minor change that fixes a benign
bug. As per above I'm seeing performance improvement, so I'm keen to get this
in, but I'm willing to run other benchmarks if others have suggestions for what
to run.

Changes since v1 [1]
====================

 - Remove "void" from arch_wants_exec_folio_order() macro args list

[1] https://lore.kernel.org/linux-mm/20240111154106.3692206-1-ryan.roberts at arm.com/
[2] https://lore.kernel.org/linux-mm/20240215103205.2607016-1-ryan.roberts at arm.com/

Thanks,
Ryan


 arch/arm64/include/asm/pgtable.h | 12 ++++++++++++
 include/linux/pgtable.h          | 12 ++++++++++++
 mm/filemap.c                     | 19 +++++++++++++++++++
 3 files changed, 43 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 52d0b0a763f1..fa6365ce61a7 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1115,6 +1115,18 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
  */
 #define arch_wants_old_prefaulted_pte	cpu_has_hw_af

+/*
+ * Request exec memory is read into pagecache in at least 64K folios. The
+ * trade-off here is performance improvement due to storing translations more
+ * effciently in the iTLB vs the potential for read amplification due to reading
+ * data from disk that won't be used. The latter is independent of base page
+ * size, so we set a page-size independent block size of 64K. This size can be
+ * contpte-mapped when 4K base pages are in use (16 pages into 1 iTLB entry),
+ * and HPA can coalesce it (4 pages into 1 TLB entry) when 16K base pages are in
+ * use.
+ */
+#define arch_wants_exec_folio_order() ilog2(SZ_64K >> PAGE_SHIFT)
+
 static inline bool pud_sect_supported(void)
 {
 	return PAGE_SIZE == SZ_4K;
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index aab227e12493..6cdd145cbbb9 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -407,6 +407,18 @@ static inline bool arch_has_hw_pte_young(void)
 }
 #endif

+#ifndef arch_wants_exec_folio_order
+/*
+ * Returns preferred minimum folio order for executable file-backed memory. Must
+ * be in range [0, PMD_ORDER]. Negative value implies that the HW has no
+ * preference and mm will not special-case executable memory in the pagecache.
+ */
+static inline int arch_wants_exec_folio_order(void)
+{
+	return -1;
+}
+#endif
+
 #ifndef arch_check_zapped_pte
 static inline void arch_check_zapped_pte(struct vm_area_struct *vma,
 					 pte_t pte)
diff --git a/mm/filemap.c b/mm/filemap.c
index 142864338ca4..7954274de11c 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -3118,6 +3118,25 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 	}
 #endif

+	/*
+	 * Allow arch to request a preferred minimum folio order for executable
+	 * memory. This can often be beneficial to performance if (e.g.) arm64
+	 * can contpte-map the folio. Executable memory rarely benefits from
+	 * read-ahead anyway, due to its random access nature.
+	 */
+	if (vm_flags & VM_EXEC) {
+		int order = arch_wants_exec_folio_order();
+
+		if (order >= 0) {
+			fpin = maybe_unlock_mmap_for_io(vmf, fpin);
+			ra->size = 1UL << order;
+			ra->async_size = 0;
+			ractl._index &= ~((unsigned long)ra->size - 1);
+			page_cache_ra_order(&ractl, ra, order);
+			return fpin;
+		}
+	}
+
 	/* If we don't want any read-ahead, don't bother */
 	if (vm_flags & VM_RAND_READ)
 		return fpin;
--
2.25.1



From andy at kernel.org  Thu Feb 15 07:43:34 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Thu, 15 Feb 2024 17:43:34 +0200
Subject: [PATCH v3 08/18] phy: ti: phy-j721e-wiz: split wiz_clock_init()
 function
In-Reply-To: <20240102-j7200-pcie-s2r-v3-8-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-8-5c2e4a3fac1f@bootlin.com>
Message-ID: <Zc4xJtLl3zo_YrBC@smile.fi.intel.com>

On Thu, Feb 15, 2024 at 04:17:53PM +0100, Thomas Richard wrote:
> The wiz_clock_init() function mixes probe and hardware configuration.
> Rename the wiz_clock_init() to wiz_clock_probe() and move the hardware
> configuration part in a new function named wiz_clock_init().
> 
> This hardware configuration sequence must be called during the resume
> stage of the driver.

...

(Side note, as this can be done later)

>  	if (rate >= 100000000)

> +		if (rate >= 100000000)

> +	if (rate >= 100000000)

I would make local definition and use it, we may get the global one as there
are users.

#define HZ_PER_GHZ	1000000000UL

-- 
With Best Regards,
Andy Shevchenko




From andy at kernel.org  Thu Feb 15 07:45:28 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Thu, 15 Feb 2024 17:45:28 +0200
Subject: [PATCH v3 13/18] phy: cadence-torrent: remove noop_ops phy
 operations
In-Reply-To: <20240102-j7200-pcie-s2r-v3-13-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-13-5c2e4a3fac1f@bootlin.com>
Message-ID: <Zc4xmGNLrVrQEuwC@smile.fi.intel.com>

On Thu, Feb 15, 2024 at 04:17:58PM +0100, Thomas Richard wrote:
> Even if a PHY is already configured, the PHY operations are needed during
> resume stage, as the PHY is in reset state.
> The noop_ops PHY operations is removed to always have PHY operations.
> The already_configured flag is checked at the begening of init, configure
> and poweron operations to keep the already_configured behaviour.

...

> +	if (cdns_phy->already_configured) {
> +		/* Give 5ms to 10ms delay for the PIPE clock to be stable */
> +		usleep_range(5000, 10000);

fsleep() ?
(Yes, I see this is the original code, perhaps later in a separate change)

> +		return 0;
> +	}

-- 
With Best Regards,
Andy Shevchenko




From andy at kernel.org  Thu Feb 15 07:46:54 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Thu, 15 Feb 2024 17:46:54 +0200
Subject: [PATCH v3 14/18] phy: cadence-torrent: add suspend and resume
 support
In-Reply-To: <20240102-j7200-pcie-s2r-v3-14-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-14-5c2e4a3fac1f@bootlin.com>
Message-ID: <Zc4x7kvFfBI2sb_E@smile.fi.intel.com>

On Thu, Feb 15, 2024 at 04:17:59PM +0100, Thomas Richard wrote:
> Add suspend and resume support.
> 
> The already_configured flag is cleared during the suspend stage to force
> the PHY initialization during the resume stage.

> Based on the work of Th?o Lebrun <theo.lebrun at bootlin.com>

SoB/Co-developed-by ?

...

> +static int cdns_torrent_phy_suspend_noirq(struct device *dev)
> +{
> +	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
> +	int i;

Why signed?

> +	reset_control_assert(cdns_phy->phy_rst);
> +	reset_control_assert(cdns_phy->apb_rst);
> +	for (i = 0; i < cdns_phy->nsubnodes; i++)
> +		reset_control_assert(cdns_phy->phys[i].lnk_rst);
> +
> +	if (cdns_phy->already_configured)
> +		cdns_phy->already_configured = 0;
> +	else
> +		clk_disable_unprepare(cdns_phy->clk);
> +
> +	return 0;
> +}
> +
> +static int cdns_torrent_phy_resume_noirq(struct device *dev)
> +{
> +	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
> +	int node = cdns_phy->nsubnodes;
> +	int ret, i;

Ditto.

> +	ret = cdns_torrent_clk(cdns_phy);
> +	if (ret)
> +		goto clk_cleanup;
> +
> +	/* Enable APB */
> +	reset_control_deassert(cdns_phy->apb_rst);
> +
> +	if (cdns_phy->nsubnodes > 1) {
> +		ret = cdns_torrent_phy_configure_multilink(cdns_phy);
> +		if (ret)
> +			goto put_lnk_rst;
> +	}
> +
> +	return 0;
> +
> +put_lnk_rst:
> +	for (i = 0; i < node; i++)
> +		reset_control_assert(cdns_phy->phys[i].lnk_rst);
> +	reset_control_assert(cdns_phy->apb_rst);
> +	clk_disable_unprepare(cdns_phy->clk);
> +clk_cleanup:
> +	cdns_torrent_clk_cleanup(cdns_phy);
> +	return ret;
> +}

-- 
With Best Regards,
Andy Shevchenko




From andy at kernel.org  Thu Feb 15 07:51:09 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Thu, 15 Feb 2024 17:51:09 +0200
Subject: [PATCH v3 18/18] PCI: j721e: add suspend and resume support
In-Reply-To: <20240102-j7200-pcie-s2r-v3-18-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-18-5c2e4a3fac1f@bootlin.com>
Message-ID: <Zc4y7Tj2K2pTQ4HY@smile.fi.intel.com>

On Thu, Feb 15, 2024 at 04:18:03PM +0100, Thomas Richard wrote:
> From: Th?o Lebrun <theo.lebrun at bootlin.com>
> 
> Add suspend and resume support. Only the rc mode is supported.
> 
> During the suspend stage PERST# is asserted, then deasserted during the
> resume stage.

...

> +#include <linux/clk-provider.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/gpio/consumer.h>
> @@ -18,10 +19,13 @@
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/regmap.h>

> +#include <linux/container_of.h>

Unordered.

...

> +	ret = j721e_pcie_ctrl_init(pcie);
> +	if (ret < 0) {
> +		dev_err(dev, "j721e_pcie_ctrl_init failed\n");

Is there any guarantee this won't spam logs?

> +		return ret;
> +	}

...

> +	/*
> +	 * This is not called explicitly in the probe, it is called by
> +	 * cdns_pcie_init_phy.

cdns_pcie_init_phy()

> +	 */
> +	ret = cdns_pcie_enable_phy(pcie->cdns_pcie);
> +	if (ret < 0) {
> +		dev_err(dev, "cdns_pcie_enable_phy failed\n");
> +		return -ENODEV;

A potential log spammer?

> +	}

> +	if (pcie->mode == PCI_MODE_RC) {
> +		struct cdns_pcie_rc *rc = cdns_pcie_to_rc(cdns_pcie);
> +
> +		ret = clk_prepare_enable(pcie->refclk);
> +		if (ret < 0) {
> +			dev_err(dev, "clk_prepare_enable failed\n");

Ditto.

> +			return -ENODEV;

Why is the error code shadowed?

> +		}

...

> +		if (pcie->reset_gpio) {
> +			usleep_range(100, 200);

fsleep()

> +			gpiod_set_value_cansleep(pcie->reset_gpio, 1);
> +		}

> +		ret = cdns_pcie_host_link_setup(rc);
> +		if (ret < 0) {
> +			clk_disable_unprepare(pcie->refclk);
> +			return ret;
> +		}
> +
> +		/*
> +		 * Reset internal status of BARs to force reinitialization in
> +		 * cdns_pcie_host_init().
> +		 */
> +		for (enum cdns_pcie_rp_bar bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
> +			rc->avail_ib_bar[bar] = true;
> +
> +		ret = cdns_pcie_host_init(rc);
> +		if (ret)

No clock disabling?

> +			return ret;
> +	}


-- 
With Best Regards,
Andy Shevchenko




From rogerq at kernel.org  Thu Feb 15 07:57:45 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 15 Feb 2024 17:57:45 +0200
Subject: [PATCH] arm64: dts: ti: k3-am654: Drop ti,syscon-rgmii-delay from
 ICSSG nodes
In-Reply-To: <20240215105407.2868266-1-danishanwar@ti.com>
References: <20240215105407.2868266-1-danishanwar@ti.com>
Message-ID: <71adaabd-bb24-4181-9fdf-f7191e93edb5@kernel.org>



On 15/02/2024 12:54, MD Danish Anwar wrote:
> Drop ti,syscon-rgmii-delay from ICSSG0, ICSSG1 and ICSSG2 node as this
> property is no longer used by ICSSG driver.
> 
> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> ---
>  arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso | 2 --
>  arch/arm64/boot/dts/ti/k3-am654-idk.dtso    | 4 ----
>  2 files changed, 6 deletions(-)

What about the DT binding document?

-- 
cheers,
-roger


From jgg at nvidia.com  Thu Feb 15 08:01:35 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 15 Feb 2024 12:01:35 -0400
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <20240215134952.GA690@willie-the-truck>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240215134952.GA690@willie-the-truck>
Message-ID: <20240215160135.GL1088888@nvidia.com>

On Thu, Feb 15, 2024 at 01:49:53PM +0000, Will Deacon wrote:
> Hi Jason,
> 
> On Tue, Feb 06, 2024 at 11:12:38AM -0400, Jason Gunthorpe wrote:
> > As the comment in arm_smmu_write_strtab_ent() explains, this routine has
> > been limited to only work correctly in certain scenarios that the caller
> > must ensure. Generally the caller must put the STE into ABORT or BYPASS
> > before attempting to program it to something else.
> 
> This is looking pretty good now, but I have a few comments inline.

Ok

> > @@ -48,6 +48,21 @@ enum arm_smmu_msi_index {
> >  	ARM_SMMU_MAX_MSIS,
> >  };
> >  
> > +struct arm_smmu_entry_writer_ops;
> > +struct arm_smmu_entry_writer {
> > +	const struct arm_smmu_entry_writer_ops *ops;
> > +	struct arm_smmu_master *master;
> > +};
> > +
> > +struct arm_smmu_entry_writer_ops {
> > +	unsigned int num_entry_qwords;
> > +	__le64 v_bit;
> > +	void (*get_used)(const __le64 *entry, __le64 *used);
> > +	void (*sync)(struct arm_smmu_entry_writer *writer);
> > +};
> 
> Can we avoid the indirection for now, please? I'm sure we'll want it later
> when you extend this to CDs, but for the initial support it just makes it
> more difficult to follow the flow. Should be a trivial thing to drop, I
> hope.

We can.

> > +static void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
> >  {
> > +	unsigned int cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ent[0]));
> > +
> > +	used_bits[0] = cpu_to_le64(STRTAB_STE_0_V);
> > +	if (!(ent[0] & cpu_to_le64(STRTAB_STE_0_V)))
> > +		return;
> > +
> > +	/*
> > +	 * See 13.5 Summary of attribute/permission configuration fields for the
> > +	 * SHCFG behavior. It is only used for BYPASS, including S1DSS BYPASS,
> > +	 * and S2 only.
> > +	 */
> > +	if (cfg == STRTAB_STE_0_CFG_BYPASS ||
> > +	    cfg == STRTAB_STE_0_CFG_S2_TRANS ||
> > +	    (cfg == STRTAB_STE_0_CFG_S1_TRANS &&
> > +	     FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
> > +		     STRTAB_STE_1_S1DSS_BYPASS))
> > +		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_SHCFG);
> 
> Huh, SHCFG is really getting in the way here, isn't it? 

I wouldn't say that.. It is just a complicated bit of the spec. One of
the things we recently did was to audit all the cache settings and, at
least, we then realized that SHCFG was being subtly used by S2 as
well..

Not sure if that was intentional or if it was just missed from the
spec that the S2 uses the value too.

>From that perspective I view this layout of used to be valuable. It
forces the kind of reflection and rigor that I think is helpful. The
fact we found a thing to improve on by inspection is proof of this
worth to me.

> I think it also means we don't have a "hitless" transition from
> stage-2 translation -> bypass.

Hmm, I didn't notice that. The kunit passed:

[    0.511483] 1..1
[    0.511510]     KTAP version 1
[    0.511551]     # Subtest: arm-smmu-v3-kunit-test
[    0.511592]     # module: arm_smmu_v3_test
[    0.511594]     1..10
[    0.511910]     ok 1 arm_smmu_v3_write_ste_test_bypass_to_abort
[    0.512110]     ok 2 arm_smmu_v3_write_ste_test_abort_to_bypass
[    0.512386]     ok 3 arm_smmu_v3_write_ste_test_cdtable_to_abort
[    0.512631]     ok 4 arm_smmu_v3_write_ste_test_abort_to_cdtable
[    0.512874]     ok 5 arm_smmu_v3_write_ste_test_cdtable_to_bypass
[    0.513075]     ok 6 arm_smmu_v3_write_ste_test_bypass_to_cdtable
[    0.513275]     ok 7 arm_smmu_v3_write_ste_test_cdtable_s1dss_change
[    0.513466]     ok 8 arm_smmu_v3_write_ste_test_s1dssbypass_to_stebypass
[    0.513672]     ok 9 arm_smmu_v3_write_ste_test_stebypass_to_s1dssbypass
[    0.514148]     ok 10 arm_smmu_v3_write_ste_test_non_hitless

Which I see is because it did not test the S2 case...

> I'm inclined to leave it set to "use incoming" all the time; the
> only difference I can see is if you have stage-2 translation and a
> master emitting outer-shareable transactions, in which case they'd now
> be outer-shareable instead of inner-shareable, which I think is harmless.

Broadly it seems to me to make sense that the iommu would try to have
a consistent translation - that bypass and S2 use different
cachability doesn't seem great. But isn't the current S2 value of 0
"non-sharable"?

> Additionally, it looks like there's an existing buglet here in that we
> shouldn't set SHCFG if SMMU_IDR1.ATTR_TYPES_OVR == 0.

Ah because the spec says RES0.. I'll add these two into the pile of
random stuff in part 3

> > +	used_bits[0] |= cpu_to_le64(STRTAB_STE_0_CFG);
> > +	switch (cfg) {
> > +	case STRTAB_STE_0_CFG_ABORT:
> > +	case STRTAB_STE_0_CFG_BYPASS:
> > +		break;
> > +	case STRTAB_STE_0_CFG_S1_TRANS:
> > +		used_bits[0] |= cpu_to_le64(STRTAB_STE_0_S1FMT |
> > +					    STRTAB_STE_0_S1CTXPTR_MASK |
> > +					    STRTAB_STE_0_S1CDMAX);
> > +		used_bits[1] |=
> > +			cpu_to_le64(STRTAB_STE_1_S1DSS | STRTAB_STE_1_S1CIR |
> > +				    STRTAB_STE_1_S1COR | STRTAB_STE_1_S1CSH |
> > +				    STRTAB_STE_1_S1STALLD | STRTAB_STE_1_STRW);
> > +		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_EATS);
> > +		used_bits[2] |= cpu_to_le64(STRTAB_STE_2_S2VMID);
> > +		break;
> > +	case STRTAB_STE_0_CFG_S2_TRANS:
> > +		used_bits[1] |=
> > +			cpu_to_le64(STRTAB_STE_1_EATS);
> > +		used_bits[2] |=
> > +			cpu_to_le64(STRTAB_STE_2_S2VMID | STRTAB_STE_2_VTCR |
> > +				    STRTAB_STE_2_S2AA64 | STRTAB_STE_2_S2ENDI |
> > +				    STRTAB_STE_2_S2PTW | STRTAB_STE_2_S2R);
> > +		used_bits[3] |= cpu_to_le64(STRTAB_STE_3_S2TTB_MASK);
> > +		break;
> 
> With SHCFG fixed, can we go a step further with this and simply identify
> the live qwords directly, rather than on a field-by-field basis? I think
> we should be able to do the same "hitless" transitions you want with the
> coarser granularity.

Not naively, Michael's excellent unit test shows it.. My understanding
of your idea was roughly thus:

void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
{
	unsigned int cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ent[0]));

	used_bits[0] = U64_MAX;
	if (!(ent[0] & cpu_to_le64(STRTAB_STE_0_V)))
		return;

	/*
	 * See 13.5 Summary of attribute/permission configuration fields for the
	 * SHCFG behavior. It is only used for BYPASS, including S1DSS BYPASS,
	 * and S2 only.
	 */
	if (cfg == STRTAB_STE_0_CFG_BYPASS ||
	    cfg == STRTAB_STE_0_CFG_S2_TRANS ||
	    (cfg == STRTAB_STE_0_CFG_S1_TRANS &&
	     FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
		     STRTAB_STE_1_S1DSS_BYPASS))
		used_bits[1] |= U64_MAX;

	used_bits[0] |= U64_MAX;
	switch (cfg) {
	case STRTAB_STE_0_CFG_ABORT:
	case STRTAB_STE_0_CFG_BYPASS:
		break;
	case STRTAB_STE_0_CFG_S1_TRANS:
		used_bits[0] |= U64_MAX;
		used_bits[1] |= U64_MAX;
		used_bits[2] |= U64_MAX;
		break;
	case STRTAB_STE_0_CFG_NESTED:
		used_bits[0] |= U64_MAX;
		used_bits[1] |= U64_MAX;
		fallthrough;
	case STRTAB_STE_0_CFG_S2_TRANS:
		used_bits[1] |= U64_MAX;
		used_bits[2] |= U64_MAX;
		used_bits[3] |= U64_MAX;
		break;

	default:
		memset(used_bits, 0xFF, sizeof(struct arm_smmu_ste));
		WARN_ON(true);
	}
}

And the failures:

[    0.500676]     ok 1 arm_smmu_v3_write_ste_test_bypass_to_abort
[    0.500818]     ok 2 arm_smmu_v3_write_ste_test_abort_to_bypass
[    0.501014]     ok 3 arm_smmu_v3_write_ste_test_cdtable_to_abort
[    0.501197]     ok 4 arm_smmu_v3_write_ste_test_abort_to_cdtable
[    0.501340]     # arm_smmu_v3_write_ste_test_cdtable_to_bypass: EXPECTATION FAILED at drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c:128
[    0.501340]     Expected test_writer.invalid_entry_written == !hitless, but
[    0.501340]         test_writer.invalid_entry_written == 1 (0x1)
[    0.501340]         !hitless == 0 (0x0)
[    0.501489]     not ok 5 arm_smmu_v3_write_ste_test_cdtable_to_bypass
[    0.501787]     # arm_smmu_v3_write_ste_test_bypass_to_cdtable: EXPECTATION FAILED at drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c:128
[    0.501787]     Expected test_writer.invalid_entry_written == !hitless, but
[    0.501787]         test_writer.invalid_entry_written == 1 (0x1)
[    0.501787]         !hitless == 0 (0x0)
[    0.501931]     not ok 6 arm_smmu_v3_write_ste_test_bypass_to_cdtable
[    0.502274]     ok 7 arm_smmu_v3_write_ste_test_cdtable_s1dss_change
[    0.502397]     # arm_smmu_v3_write_ste_test_s1dssbypass_to_stebypass: EXPECTATION FAILED at drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c:128
[    0.502397]     Expected test_writer.invalid_entry_written == !hitless, but
[    0.502397]         test_writer.invalid_entry_written == 1 (0x1)
[    0.502397]         !hitless == 0 (0x0)
[    0.502473]     # arm_smmu_v3_write_ste_test_s1dssbypass_to_stebypass: EXPECTATION FAILED at drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c:129
[    0.502473]     Expected test_writer.num_syncs == num_syncs_expected, but
[    0.502473]         test_writer.num_syncs == 3 (0x3)
[    0.502473]         num_syncs_expected == 2 (0x2)
[    0.502784]     not ok 8 arm_smmu_v3_write_ste_test_s1dssbypass_to_stebypass
[    0.503073]     # arm_smmu_v3_write_ste_test_stebypass_to_s1dssbypass: EXPECTATION FAILED at drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c:128
[    0.503073]     Expected test_writer.invalid_entry_written == !hitless, but
[    0.503073]         test_writer.invalid_entry_written == 1 (0x1)
[    0.503073]         !hitless == 0 (0x0)
[    0.503176]     # arm_smmu_v3_write_ste_test_stebypass_to_s1dssbypass: EXPECTATION FAILED at drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c:129
[    0.503176]     Expected test_writer.num_syncs == num_syncs_expected, but
[    0.503176]         test_writer.num_syncs == 3 (0x3)
[    0.503176]         num_syncs_expected == 2 (0x2)
[    0.503464]     not ok 9 arm_smmu_v3_write_ste_test_stebypass_to_s1dssbypass
[    0.503807]     ok 10 arm_smmu_v3_write_ste_test_non_hitless

BYPASS -> S1 requires changing overlapping bits in qword 1. The
programming sequence would look like this:

start qw[1] = SHCFG_INCOMING
      qw[1] = SHCFG_INCOMING | S1DSS
      qw[0] = S1 mode
      qw[1] = S1DSS

The two states are sharing qw[1] and BYPASS ignores all of it except
SHCFG_INCOMING. Since bypass would have its qw[1] marked as used due
to the SHCFG there is no way to express that it is not looking at the
other bits.

We'd have to really start doing really hacky things like remove the
SHCFG as a used field entirely - but I think if you do that you break
the entire logic of the design and also go backwards to having
programming that only works if STEs are constructed in certain ways.

Thanks,
Jason


From helgaas at kernel.org  Thu Feb 15 08:01:57 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 15 Feb 2024 10:01:57 -0600
Subject: [PATCH V16 13/13] PCI: tegra: Add Tegra194 PCIe support
In-Reply-To: <17dadf66-055c-4796-a905-44e37b6fcfe3@nvidia.com>
Message-ID: <20240215160157.GA1291755@bhelgaas>

On Thu, Feb 15, 2024 at 04:55:47PM +0530, Vidya Sagar wrote:
> On 15-02-2024 00:42, Bjorn Helgaas wrote:
> > Hi Vidya, question about ancient history:
> > 
> > On Tue, Aug 13, 2019 at 05:06:27PM +0530, Vidya Sagar wrote:
> > > Add support for Synopsys DesignWare core IP based PCIe host controller
> > > present in Tegra194 SoC.
> > > ...
> > > +static int tegra_pcie_dw_host_init(struct pcie_port *pp)
> > > +{
> > > +     struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > +     struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
> > > +     u32 val, tmp, offset, speed;
> > > +
> > > +     tegra_pcie_prepare_host(pp);
> > > +
> > > +     if (dw_pcie_wait_for_link(pci)) {
> > > +             /*
> > > +              * There are some endpoints which can't get the link up if
> > > +              * root port has Data Link Feature (DLF) enabled.
> > > +              * Refer Spec rev 4.0 ver 1.0 sec 3.4.2 & 7.7.4 for more info
> > > +              * on Scaled Flow Control and DLF.
> > > +              * So, need to confirm that is indeed the case here and attempt
> > > +              * link up once again with DLF disabled.
> >
> > This comment suggests that there's an issue with *Endpoints*, not an
> > issue with the Root Port.  If so, it seems like this problem could
> > occur with all Root Ports, not just Tegra194.  Do you remember any
> > details about this?
> > 
> > I don't remember hearing about any similar issues, and this driver is
> > the only place PCI_EXT_CAP_ID_DLF is referenced, so maybe it is
> > actually something related to Tegra194?
>
> We noticed PCIe link-up issues with some endpoints. link-up at the physical
> layer level but NOT at the Data link layer level precisely. We further
> figured out that it is the DLFE DLLPs that the root port sends during the
> link up process which are causing the endpoints get confused and preventing
> them from sending the InitFC DLLPs leading to the link not being up at
> Data Link Layer level.

Do you happen to remember any of the endpoints that have issues?

Could save some painful debugging if we trip over this issue on other
systems.  We have seen a few cases where links wouldn't train at full
speed unless they trained at a lower speed first, e.g.,
imx6_pcie_start_link(), fu740_pcie_start_link().  I guess there are
probably lots of edge cases that can cause link failures.

Bjorn


From andy at kernel.org  Thu Feb 15 08:04:44 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Thu, 15 Feb 2024 18:04:44 +0200
Subject: [PATCH v3 17/18] PCI: j721e: add reset GPIO to struct j721e_pcie
In-Reply-To: <20240102-j7200-pcie-s2r-v3-17-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-17-5c2e4a3fac1f@bootlin.com>
Message-ID: <Zc42HIibtoXqLyEA@smile.fi.intel.com>

On Thu, Feb 15, 2024 at 04:18:02PM +0100, Thomas Richard wrote:
> From: Th?o Lebrun <theo.lebrun at bootlin.com>
> 
> Add reset GPIO to struct j721e_pcie, so it can be used at suspend and
> resume stages.

...

>  	case PCI_MODE_RC:
> -		gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> -		if (IS_ERR(gpiod)) {
> -			ret = PTR_ERR(gpiod);
> +		pcie->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> +		if (IS_ERR(pcie->reset_gpio)) {
> +			ret = PTR_ERR(pcie->reset_gpio);
>  			if (ret != -EPROBE_DEFER)
>  				dev_err(dev, "Failed to get reset GPIO\n");
>  			goto err_get_sync;
> @@ -504,9 +504,9 @@ static int j721e_pcie_probe(struct platform_device *pdev)
>  		 * mode is selected while enabling the PHY. So deassert PERST#
>  		 * after 100 us.
>  		 */
> -		if (gpiod) {
> +		if (pcie->reset_gpio) {
>  			usleep_range(100, 200);
> -			gpiod_set_value_cansleep(gpiod, 1);
> +			gpiod_set_value_cansleep(pcie->reset_gpio, 1);
>  		}

Instead of all this, just add one line assignment. Moreover, before or after
this patch refactor the code to use ret = dev_err_probe(...); pattern that
eliminates those deferral probe checks.


-- 
With Best Regards,
Andy Shevchenko




From sean.anderson at seco.com  Thu Feb 15 08:23:27 2024
From: sean.anderson at seco.com (Sean Anderson)
Date: Thu, 15 Feb 2024 11:23:27 -0500
Subject: [RESEND PATCH net v4 2/2] soc: fsl: qbman: Use raw spinlock for cgr_lock
In-Reply-To: <20240215162327.3663092-1-sean.anderson@seco.com>
References: <20240215162327.3663092-1-sean.anderson@seco.com>
Message-ID: <20240215162327.3663092-2-sean.anderson@seco.com>

cgr_lock may be locked with interrupts already disabled by
smp_call_function_single. As such, we must use a raw spinlock to avoid
problems on PREEMPT_RT kernels. Although this bug has existed for a
while, it was not apparent until commit ef2a8d5478b9 ("net: dpaa: Adjust
queue depth on rate change") which invokes smp_call_function_single via
qman_update_cgr_safe every time a link goes up or down.

Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
CC: stable at vger.kernel.org
Reported-by: Vladimir Oltean <vladimir.oltean at nxp.com>
Closes: https://lore.kernel.org/all/20230323153935.nofnjucqjqnz34ej at skbuf/
Reported-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
Closes: https://lore.kernel.org/linux-arm-kernel/87wmsyvclu.fsf at pengutronix.de/
Signed-off-by: Sean Anderson <sean.anderson at seco.com>
Reviewed-by: Camelia Groza <camelia.groza at nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean at nxp.com>

---

Changes in v4:
- Add a note about how raw spinlocks aren't quite right

Changes in v3:
- Change blamed commit to something more appropriate

 drivers/soc/fsl/qbman/qman.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 1bf1f1ea67f0..7e9074519ad2 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -991,7 +991,7 @@ struct qman_portal {
        /* linked-list of CSCN handlers. */
        struct list_head cgr_cbs;
        /* list lock */
-       spinlock_t cgr_lock;
+       raw_spinlock_t cgr_lock;
        struct work_struct congestion_work;
        struct work_struct mr_work;
        char irqname[MAX_IRQNAME];
@@ -1281,7 +1281,7 @@ static int qman_create_portal(struct qman_portal *portal,
                /* if the given mask is NULL, assume all CGRs can be seen */
                qman_cgrs_fill(&portal->cgrs[0]);
        INIT_LIST_HEAD(&portal->cgr_cbs);
-       spin_lock_init(&portal->cgr_lock);
+       raw_spin_lock_init(&portal->cgr_lock);
        INIT_WORK(&portal->congestion_work, qm_congestion_task);
        INIT_WORK(&portal->mr_work, qm_mr_process_task);
        portal->bits = 0;
@@ -1456,11 +1456,14 @@ static void qm_congestion_task(struct work_struct *work)
        union qm_mc_result *mcr;
        struct qman_cgr *cgr;

-       spin_lock_irq(&p->cgr_lock);
+       /*
+        * FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock!
+        */
+       raw_spin_lock_irq(&p->cgr_lock);
        qm_mc_start(&p->p);
        qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
        if (!qm_mc_result_timeout(&p->p, &mcr)) {
-               spin_unlock_irq(&p->cgr_lock);
+               raw_spin_unlock_irq(&p->cgr_lock);
                dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
                qman_p_irqsource_add(p, QM_PIRQ_CSCI);
                return;
@@ -1476,7 +1479,7 @@ static void qm_congestion_task(struct work_struct *work)
        list_for_each_entry(cgr, &p->cgr_cbs, node)
                if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
                        cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
-       spin_unlock_irq(&p->cgr_lock);
+       raw_spin_unlock_irq(&p->cgr_lock);
        qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 }

@@ -2440,7 +2443,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
        preempt_enable();

        cgr->chan = p->config->channel;
-       spin_lock_irq(&p->cgr_lock);
+       raw_spin_lock_irq(&p->cgr_lock);

        if (opts) {
                struct qm_mcc_initcgr local_opts = *opts;
@@ -2477,7 +2480,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
            qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
                cgr->cb(p, cgr, 1);
 out:
-       spin_unlock_irq(&p->cgr_lock);
+       raw_spin_unlock_irq(&p->cgr_lock);
        put_affine_portal();
        return ret;
 }
@@ -2512,7 +2515,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
                return -EINVAL;

        memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
-       spin_lock_irqsave(&p->cgr_lock, irqflags);
+       raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
        list_del(&cgr->node);
        /*
         * If there are no other CGR objects for this CGRID in the list,
@@ -2537,7 +2540,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
                /* add back to the list */
                list_add(&cgr->node, &p->cgr_cbs);
 release_lock:
-       spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+       raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
        put_affine_portal();
        return ret;
 }
@@ -2577,9 +2580,9 @@ static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
        if (!p)
                return -EINVAL;

-       spin_lock_irqsave(&p->cgr_lock, irqflags);
+       raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
        ret = qm_modify_cgr(cgr, 0, opts);
-       spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+       raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
        put_affine_portal();
        return ret;
 }
--
2.35.1.1320.gc452695387.dirty


[Embedded World 2024, SECO SpA]<https://www.messe-ticket.de/Nuernberg/embeddedworld2024/Register/ew24517689>


From sean.anderson at seco.com  Thu Feb 15 08:23:26 2024
From: sean.anderson at seco.com (Sean Anderson)
Date: Thu, 15 Feb 2024 11:23:26 -0500
Subject: [RESEND PATCH net v4 1/2] soc: fsl: qbman: Always disable interrupts when taking cgr_lock
Message-ID: <20240215162327.3663092-1-sean.anderson@seco.com>

smp_call_function_single disables IRQs when executing the callback. To
prevent deadlocks, we must disable IRQs when taking cgr_lock elsewhere.
This is already done by qman_update_cgr and qman_delete_cgr; fix the
other lockers.

Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
CC: stable at vger.kernel.org
Signed-off-by: Sean Anderson <sean.anderson at seco.com>
Reviewed-by: Camelia Groza <camelia.groza at nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
I got no response the first time I sent this, so I am resending to net.
This issue was introduced in a series which went through net, so I hope
it makes sense to take it via net.

[1] https://lore.kernel.org/linux-arm-kernel/20240108161904.2865093-1-sean.anderson at seco.com/

(no changes since v3)

Changes in v3:
- Change blamed commit to something more appropriate

Changes in v2:
- Fix one additional call to spin_unlock

 drivers/soc/fsl/qbman/qman.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 739e4eee6b75..1bf1f1ea67f0 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -1456,11 +1456,11 @@ static void qm_congestion_task(struct work_struct *work)
        union qm_mc_result *mcr;
        struct qman_cgr *cgr;

-       spin_lock(&p->cgr_lock);
+       spin_lock_irq(&p->cgr_lock);
        qm_mc_start(&p->p);
        qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
        if (!qm_mc_result_timeout(&p->p, &mcr)) {
-               spin_unlock(&p->cgr_lock);
+               spin_unlock_irq(&p->cgr_lock);
                dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
                qman_p_irqsource_add(p, QM_PIRQ_CSCI);
                return;
@@ -1476,7 +1476,7 @@ static void qm_congestion_task(struct work_struct *work)
        list_for_each_entry(cgr, &p->cgr_cbs, node)
                if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
                        cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
-       spin_unlock(&p->cgr_lock);
+       spin_unlock_irq(&p->cgr_lock);
        qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 }

@@ -2440,7 +2440,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
        preempt_enable();

        cgr->chan = p->config->channel;
-       spin_lock(&p->cgr_lock);
+       spin_lock_irq(&p->cgr_lock);

        if (opts) {
                struct qm_mcc_initcgr local_opts = *opts;
@@ -2477,7 +2477,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
            qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
                cgr->cb(p, cgr, 1);
 out:
-       spin_unlock(&p->cgr_lock);
+       spin_unlock_irq(&p->cgr_lock);
        put_affine_portal();
        return ret;
 }
--
2.35.1.1320.gc452695387.dirty


[Embedded World 2024, SECO SpA]<https://www.messe-ticket.de/Nuernberg/embeddedworld2024/Register/ew24517689>


From linux at armlinux.org.uk  Thu Feb 15 08:26:55 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 15 Feb 2024 16:26:55 +0000
Subject: [PATCH net-next v5 1/9] net: phylink: provide
 mac_get_pcs_neg_mode() function
In-Reply-To: <20240215030500.3067426-2-yong.liang.choong@linux.intel.com>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
 <20240215030500.3067426-2-yong.liang.choong@linux.intel.com>
Message-ID: <Zc47T/qv8Xg2SA21@shell.armlinux.org.uk>

On Thu, Feb 15, 2024 at 11:04:51AM +0800, Choong Yong Liang wrote:
> Phylink invokes the 'mac_get_pcs_neg_mode' function during interface mode
> switching and initial startup.
> 
> This function is optional; if 'phylink_pcs_neg_mode' fails to accurately
> reflect the current PCS negotiation mode, the MAC driver can determine the
> mode based on the interface mode, current link negotiation mode, and
> advertising link mode.
> 
> For instance, if the interface switches from 2500baseX to SGMII mode,
> and the current link mode is MLO_AN_PHY, calling 'phylink_pcs_neg_mode'
> would yield PHYLINK_PCS_NEG_OUTBAND. Since the MAC and PCS driver require
> PHYLINK_PCS_NEG_INBAND_ENABLED, the 'mac_get_pcs_neg_mode' function
> will calculate the mode based on the interface, current link negotiation
> mode, and advertising link mode, returning PHYLINK_PCS_NEG_OUTBAND to
> enable the PCS to configure the correct settings.

This paragraph doesn't make sense - at least to me. It first talks about
requiring PHYLINK_PCS_NEG_INBAND_ENABLED when in SGMII mode. On this:

1) are you sure that the hardware can't be programmed for the SGMII
symbol repititions? 

2) what happens if you're paired with a PHY (e.g. on a SFP module)
which uses SGMII but has no capability of providing the inband data?
(They do exist.) If your hardware truly does require inband data, it
is going to be fundamentally inoperative with these modules.

Next, you then talk about returning PHYLINK_PCS_NEG_OUTBAND for the
"correct settings". How does this relate to the first part where you
basically describe the problem as SGMII requring inband? Basically
the two don't follow.

How, from a design point of view, because this fundamentally allows
drivers to change how the system behaves, it will allow radically
different behaviours for the same parameters between different drivers.
I am opposed to that - I want to see a situation where we have uniform
behaviour for the same configuration, and where hardware doesn't
support something, we have some way to indicate that via some form
of capabilities.

The issue of whether 2500base-X has inband or not is a long standing
issue, and there are arguments (and hardware) that take totally
opposing views on this. There is hardware where 2500base-X inband
_must_ be used or the link doesn't come up. There is also hardware
where 2500base-X inband is not "supported" in documentation but works
in practice. There is also hardware where 2500base-X inband doesn't
work. The whole thing is a total mess (thanks IEEE 802.3 for not
getting on top of this early enough... and what's now stated in 802.3
for 2500base-X is now irrelevant because they were too late to the
party.)

I haven't been able to look at this issue over the last few weeks
because of being at a summit, and then suffering with flu and its
recovery. However, I have been working on how we can identify the
capabilities of the PCS and PHY w.r.t. inband support in various
interface modes, and how we can handle the result. That work is
ongoing (as and when I have a clear head from after-flu effects.)

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


From mwalle at kernel.org  Thu Feb 15 08:29:42 2024
From: mwalle at kernel.org (Michael Walle)
Date: Thu, 15 Feb 2024 17:29:42 +0100
Subject: [PATCH v2 3/3] arm64: dts: ti: Add support for TI J722S
 Evaluation Module
In-Reply-To: <40e15761-70b3-4343-a4b3-653bc4e6637e@ti.com>
References: <20240206100608.127702-1-vaishnav.a@ti.com>
 <20240206100608.127702-4-vaishnav.a@ti.com>
 <CZ386ITQ83KH.1KNOV5MXLXPBF@kernel.org>
 <45bd5618-2e22-4715-9724-92f1d4b84608@ti.com>
 <40e15761-70b3-4343-a4b3-653bc4e6637e@ti.com>
Message-ID: <CZ5SMYXNTTOP.3MZ8P9N5BY4SH@kernel.org>

Hi,

On Wed Feb 14, 2024 at 10:42 AM CET, Vignesh Raghavendra wrote:
> On 14/02/24 13:13, Vaishnav Achath wrote:
> > On 12/02/24 21:32, Michael Walle wrote:
> >> On Tue Feb 6, 2024 at 11:06 AM CET, Vaishnav Achath wrote:
> >>> +# Boards with J722s SoC
> >>> +dtb-$(CONFIG_ARCH_K3) += k3-j722s-evm.dtb
> >>
> >> I'm a bit confused by your names. What are the new/correct ones now?
> >> Some seem to use the amXX names and some the jXX ones. I've read [1]
> >> and it appears it was suggested to use the am67 names for the device
> >> trees. Esp. because there is already, am62, am64, am65, am68 and
> >> am69 in as names for the device trees.
> >>
> >> The TRM you've linked in the cover letter doesn't shed much light
> >> either. It just lists both.
> >>
> > 
> > Both names are correct, for other Jacinto devices J721S2 and J784S4, the
> > industrial variants (AM68, AM69 respectively) and those boards were
> > announced at a later point of time and since the automotive/J7 variants
> > were introduced first, the SoC dtsi and files have the J7XX names, for
> > AM62/AM64 there is no confusion in naming, in this case the initial TRM
> > itself mentions J722S and AM67 variants with similar capabilities, the
> > reasoning behind continuing with the J722S name is because the initial
> > support is being added for J722S EVM (the top marking on the SoC package
> > populated on the EVM say XJ722SAMW, this can be seen in the schematics
> > also), please let know if this clarifies the confusion.
> > 
>
> AM64,AM62x/A/P are from different product line (Sitara) and don't have
> any other aliases.
>
> On the other hand, Jacinto SoCs have both J7xx variant and AM6xx part
> numbers. Its being really unpredictable wrt when AM6xx variants of
> Jacinto devices come out. So as a general rule, we name the DTS files
> based on the name of the first device that comes out in the market which
> has consistently been J7xx.

Thanks for the explanation. I just noticed that any k3-am6[89]*
device trees will include the j7xx SoC dtsi. That would have been my
next question: Boards with the AMxx will have the "correct" name
k3-amNN-*.

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

From frank-w at public-files.de  Thu Feb 15 08:34:17 2024
From: frank-w at public-files.de (Frank Wunderlich)
Date: Thu, 15 Feb 2024 17:34:17 +0100
Subject: Aw: [PATCH v2] arm64: dts: mediatek: mt8186: bpi-r3: Convert to
 sugar syntax
In-Reply-To: <8c10c4bf701583d015506712ba9239dbc7547426.1708003159.git.geert+renesas@glider.be>
References: <8c10c4bf701583d015506712ba9239dbc7547426.1708003159.git.geert+renesas@glider.be>
Message-ID: <trinity-008b2d85-9629-4f03-92be-0b4027edea41-1708014857046@3c-app-gmx-bs43>

Hi

> Gesendet: Donnerstag, 15. Februar 2024 um 14:20 Uhr
> Von: "Geert Uytterhoeven" <geert+renesas at glider.be>
> Betreff: [PATCH v2] arm64: dts: mediatek: mt8186: bpi-r3: Convert to sugar syntax

should be mt7986, not mt8186 ;)

regards Frank


From tanmay.shah at amd.com  Thu Feb 15 08:45:21 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Thu, 15 Feb 2024 10:45:21 -0600
Subject: [PATCH v10 2/4] dt-bindings: remoteproc: add Tightly Coupled
 Memory (TCM) bindings
In-Reply-To: <135e3154-2a55-40ac-9ba9-2de00833b903@linaro.org>
References: <20240213175450.3097308-1-tanmay.shah@amd.com>
 <20240213175450.3097308-3-tanmay.shah@amd.com>
 <170785205177.2155555.1311787541370066483.robh@kernel.org>
 <b931a24c-f676-4ddb-bb7c-e7a509d5dd4b@amd.com>
 <135e3154-2a55-40ac-9ba9-2de00833b903@linaro.org>
Message-ID: <09b0768a-4534-420f-9774-50e250795dd7@amd.com>


On 2/15/24 3:06 AM, Krzysztof Kozlowski wrote:
> On 13/02/2024 21:37, Tanmay Shah wrote:
> > Hello,
> > 
> > Thanks for reviews please find my comments below.
> > 
> > On 2/13/24 1:20 PM, Rob Herring wrote:
> >> On Tue, 13 Feb 2024 09:54:48 -0800, Tanmay Shah wrote:
> >>> From: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
> >>>
> >>> Introduce bindings for TCM memory address space on AMD-xilinx Zynq
> >>> UltraScale+ platform. It will help in defining TCM in device-tree
> >>> and make it's access platform agnostic and data-driven.
> >>>
> >>> Tightly-coupled memories(TCMs) are low-latency memory that provides
> >>> predictable instruction execution and predictable data load/store
> >>> timing. Each Cortex-R5F processor contains two 64-bit wide 64 KB memory
> >>> banks on the ATCM and BTCM ports, for a total of 128 KB of memory.
> >>>
> >>> The TCM resources(reg, reg-names and power-domain) are documented for
> >>> each TCM in the R5 node. The reg and reg-names are made as required
> >>> properties as we don't want to hardcode TCM addresses for future
> >>> platforms and for zu+ legacy implementation will ensure that the
> >>> old dts w/o reg/reg-names works and stable ABI is maintained.
> >>>
> >>> It also extends the examples for TCM split and lockstep modes.
> >>>
> >>> Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
> >>> Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
> >>> ---
> >>>
> >>> Changes in v10:
> >>>   - modify number of "reg", "reg-names" and "power-domains" entries
> >>>     based on cluster mode
> >>>   - Add extra optional atcm and btcm in "reg" property for lockstep mode
> >>>   - Add "reg-names" for extra optional atcm and btcm for lockstep mode
> >>>   - Drop previous Ack as bindings has new change
> >>>
> >>> Changes in v9:
> >>>   - None
> >>> Changes in v8:
> >>>   - None
> >>> Changes in v7:
> >>>   - None
> >>> Changes in v6:
> >>>   - None
> >>> Changes in v5:
> >>>   - None
> >>>
> >>> Changes in v4:
> >>>   - Use address-cells and size-cells value 2
> >>>   - Modify ranges property as per new value of address-cells
> >>>     and size-cells
> >>>   - Modify child node "reg" property accordingly
> >>>   - Remove previous ack for further review
> >>>
> >>> v4 link: https://lore.kernel.org/all/20230829181900.2561194-2-tanmay.shah at amd.com/
> >>>
> >>>  .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 ++++++++++++++++--
> >>>  1 file changed, 170 insertions(+), 22 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:
> >> ./Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml:118:13: [warning] wrong indentation: expected 10 but found 12 (indentation)
> > Ack. I will fix this.
> > 
> > However, can I still get reviews on patch itself so if something else needs to be fixed I can fix in next revision as well.
>
> Sorry, I have too many patches to review to provide feedback on work
> which does not build/compile/test. First use automated tooling, like
> building a C code, to detect as many issues as possible then ask for
> reviewing. Not the other way around.

Ack. I will send new revision fixing the warning.

Thanks.


>
> Best regards,
> Krzysztof


From ulf.hansson at linaro.org  Thu Feb 15 08:47:22 2024
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Thu, 15 Feb 2024 17:47:22 +0100
Subject: [PATCH] mmc: host: replace 1st argument to struct device * for mmc_of_parse_clk_phase()
In-Reply-To: <20240215-mmc_phase-v1-1-f27644ee13e4@outlook.com>
References: <20240215-mmc_phase-v1-1-f27644ee13e4@outlook.com>
Message-ID: <CAPDyKFo9NpKSuBnrcOseuD-jDA64CMyRxpH-OUoozOQDYHj1mQ@mail.gmail.com>

On Thu, 15 Feb 2024 at 12:03, Yang Xiwen via B4 Relay
<devnull+forbidden405.outlook.com at kernel.org> wrote:
>
> From: Yang Xiwen <forbidden405 at outlook.com>
>
> Parsing dt usaully happens very early, sometimes even bofore struct
> mmc_host is allocated (e.g. dw_mci_probe() and dw_mci_parse_dt() in
> dw_mmc.c). Looking at the source of mmc_of_parse_clk_phase(), it's
> actually not mandatory to have a initialized mmc_host first, instead we
> can pass struct device * to it directly.
>
> Also fix the only current user (sdhci-of-aspeed.c).

Is there a problem? I don't see it, can please elaborate.

Kind regards
Uffe

>
> Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
> ---
>  drivers/mmc/core/host.c            | 4 +---
>  drivers/mmc/host/sdhci-of-aspeed.c | 2 +-
>  include/linux/mmc/host.h           | 2 +-
>  3 files changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index cf396e8f34e9..8b2844ac5dc5 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -234,10 +234,8 @@ static void mmc_of_parse_timing_phase(struct device *dev, const char *prop,
>  }
>
>  void
> -mmc_of_parse_clk_phase(struct mmc_host *host, struct mmc_clk_phase_map *map)
> +mmc_of_parse_clk_phase(struct device *dev, struct mmc_clk_phase_map *map)
>  {
> -       struct device *dev = host->parent;
> -
>         mmc_of_parse_timing_phase(dev, "clk-phase-legacy",
>                                   &map->phase[MMC_TIMING_LEGACY]);
>         mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs",
> diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
> index 42d54532cabe..430c1f90037b 100644
> --- a/drivers/mmc/host/sdhci-of-aspeed.c
> +++ b/drivers/mmc/host/sdhci-of-aspeed.c
> @@ -435,7 +435,7 @@ static int aspeed_sdhci_probe(struct platform_device *pdev)
>                 goto err_sdhci_add;
>
>         if (dev->phase_desc)
> -               mmc_of_parse_clk_phase(host->mmc, &dev->phase_map);
> +               mmc_of_parse_clk_phase(&pdev->dev, &dev->phase_map);
>
>         ret = sdhci_add_host(host);
>         if (ret)
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 2f445c651742..5894bf912f7b 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -539,7 +539,7 @@ struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra);
>  int mmc_add_host(struct mmc_host *);
>  void mmc_remove_host(struct mmc_host *);
>  void mmc_free_host(struct mmc_host *);
> -void mmc_of_parse_clk_phase(struct mmc_host *host,
> +void mmc_of_parse_clk_phase(struct device *dev,
>                             struct mmc_clk_phase_map *map);
>  int mmc_of_parse(struct mmc_host *host);
>  int mmc_of_parse_voltage(struct mmc_host *host, u32 *mask);
>
> ---
> base-commit: 9d64bf433c53cab2f48a3fff7a1f2a696bc5229a
> change-id: 20240215-mmc_phase-26e85511285d
>
> Best regards,
> --
> Yang Xiwen <forbidden405 at outlook.com>
>


From dan.carpenter at linaro.org  Thu Feb 15 08:52:24 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Thu, 15 Feb 2024 19:52:24 +0300
Subject: [PATCH net-next v2] net: ti: icssg-prueth: Remove duplicate
 cleanup calls in emac_ndo_stop()
In-Reply-To: <20240215152203.431268-1-diogo.ivo@siemens.com>
References: <20240215152203.431268-1-diogo.ivo@siemens.com>
Message-ID: <f9bd0e83-f3bd-4804-81ff-89923b42693b@moroto.mountain>

On Thu, Feb 15, 2024 at 03:22:01PM +0000, Diogo Ivo wrote:
> Remove the duplicate calls to prueth_emac_stop() and
> prueth_cleanup_tx_chns() in emac_ndo_stop().
> 
> Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
> Reviewed-by: Roger Quadros <rogerq at kernel.org>
> Reviewed-by: MD Danish Anwar <danishanwar at ti.com>
> ---
> Changes in v2:
>  - Removed Fixes: tags
>  - Added Reviewed-by's

Thanks!

Reviewed-by: Dan Carpenter <dan.carpenter at linaro.org>

regards,
dan carpenter



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:07 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:07 +0100
Subject: [PATCH 00/13] Add Mobileye EyeQ5 support to the Nomadik I2C
 controller & use hrtimers for timeouts
Message-ID: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>

Hi,

This series adds two tangent features to the Nomadik I2C controller:

 - Add a new compatible to support Mobileye EyeQ5 which uses the same IP
   block as Nomadik.

   It has two quirks to be handled:
    - The memory bus only supports 32-bit accesses. A writeb() is used
      which we avoid.
    - We must write a value into a shared register region (OLB, "Other
      Logic Block") depending on the I2C bus speed.

 - Allow xfer timeouts below one jiffy by using a workqueue and hrtimers
   instead of a completion.

   The situation to be addressed is:
    - Many devices on the same I2C bus.
    - One xfer to each device is sent at regular interval.
    - One device gets stuck and does not answer.
    - With long timeouts, following devices won't get their message. A
      shorter timeout ensures we can still talk to the following
      devices.

   This clashes a bit with the current i2c_adapter timeout field that
   stores a jiffies amount. We cannot rely on it and therefore we take
   a value from devicetree as a ?s value. If the timeout is less than a
   jiffy duration, we switch from standard jiffies timeout to
   hrtimers.

There is one patch targeting a hwmon dt-bindings file:
Documentation/devicetree/bindings/hwmon/lm75.yaml. The rest is touching
the I2C bus driver, its bindings and platform devicetrees.

About dependencies:
 - The series is based upon v6.8-rc4.
 - For testing on EyeQ5 hardware and devicetree patches, we need the
   base platform series from Gr?gory [0].
 - The last commit (adding DT phandles for resets), we need the syscon
   series [1] that provides the reset controller node.

I think there are discussions to be had about:

 - The handling of timeouts. Having a non-jiffy value is not driver
   specific. Should this change be done at the subsystem layer? The
   subsystem could even fetch the value from devicetree and auto-fill
   timeout, with a default given by the driver. Not many drivers seem
   to use the i2c_adapter timeout field from my quick grepping.

 - The DT prop for timeout. I've picked "timeout-usecs". Some drivers
   use vendor prefixes, but this is not vendor-specific and only a
   software implementation detail.

 - The shape of this series. Initially it was split in two. However I
   brought them together as they cannot be applied independently.
   Please tell me if a better approach is to be preferred.

Those are thoughts, I'm sure people will have feedback on this.

Have a nice day,
Th?o Lebrun

[0]: https://lore.kernel.org/lkml/20240205153503.574468-1-gregory.clement at bootlin.com/
[1]: https://lore.kernel.org/lkml/20240212-mbly-clk-v6-0-c46fa1f93839 at bootlin.com/

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
Th?o Lebrun (13):
      dt-bindings: i2c: nomadik: add timeout-usecs property bindings
      dt-bindings: i2c: nomadik: add mobileye,eyeq5-i2c bindings and example
      dt-bindings: hwmon: lm75: add label property
      i2c: nomadik: rename private struct pointers from dev to priv
      i2c: nomadik: simplify IRQ masking logic
      i2c: nomadik: use bitops helpers
      i2c: nomadik: support short xfer timeouts using waitqueue & hrtimer
      i2c: nomadik: replace jiffies by ktime for FIFO flushing timeout
      i2c: nomadik: fetch timeout-usecs property from devicetree
      i2c: nomadik: support Mobileye EyeQ5 I2C controller
      MIPS: mobileye: eyeq5: add 5 I2C controller nodes
      MIPS: mobileye: eyeq5: add evaluation board I2C temp sensor
      MIPS: mobileye: eyeq5: add resets to I2C controllers

 Documentation/devicetree/bindings/hwmon/lm75.yaml  |   4 +
 .../devicetree/bindings/i2c/st,nomadik-i2c.yaml    |  49 +-
 arch/mips/boot/dts/mobileye/eyeq5-epm5.dts         |   8 +
 arch/mips/boot/dts/mobileye/eyeq5.dtsi             |  75 +++
 drivers/i2c/busses/i2c-nomadik.c                   | 710 ++++++++++++---------
 5 files changed, 534 insertions(+), 312 deletions(-)
---
base-commit: d55aa725e32849f709b61eab3b7a50b810a71a84
change-id: 20231023-mbly-i2c-7c2fbbb1299f

Best regards,
-- 
Th?o Lebrun <theo.lebrun at bootlin.com>



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:09 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:09 +0100
Subject: [PATCH 02/13] dt-bindings: i2c: nomadik: add mobileye,eyeq5-i2c
 bindings and example
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>

Add EyeQ5 bindings to the existing Nomadik I2C dt-bindings. Add the two
EyeQ5-specific properties behind a conditional. Add an example for this
compatible.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 .../devicetree/bindings/i2c/st,nomadik-i2c.yaml    | 44 ++++++++++++++++++++--
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
index e6b95e3765ac..eaade14b6d4c 100644
--- a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
@@ -14,9 +14,6 @@ description: The Nomadik I2C host controller began its life in the ST
 maintainers:
   - Linus Walleij <linus.walleij at linaro.org>
 
-allOf:
-  - $ref: /schemas/i2c/i2c-controller.yaml#
-
 # Need a custom select here or 'arm,primecell' will match on lots of nodes
 select:
   properties:
@@ -24,6 +21,7 @@ select:
       contains:
         enum:
           - st,nomadik-i2c
+          - mobileye,eyeq5-i2c
   required:
     - compatible
 
@@ -39,6 +37,10 @@ properties:
           - const: stericsson,db8500-i2c
           - const: st,nomadik-i2c
           - const: arm,primecell
+      # The variant found on Mobileye EyeQ5
+      - items:
+          - const: mobileye,eyeq5-i2c
+          - const: arm,primecell
 
   reg:
     maxItems: 1
@@ -55,7 +57,7 @@ properties:
       - items:
           - const: mclk
           - const: apb_pclk
-      # Clock name in DB8500
+      # Clock name in DB8500 or EyeQ5
       - items:
           - const: i2cclk
           - const: apb_pclk
@@ -83,6 +85,25 @@ required:
 
 unevaluatedProperties: false
 
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: mobileye,eyeq5-i2c
+    then:
+      properties:
+        mobileye,olb:
+          $ref: /schemas/types.yaml#/definitions/phandle
+          description: A phandle to the OLB syscon.
+        mobileye,id:
+          $ref: /schemas/types.yaml#/definitions/uint32
+          description: Platform-wide controller ID (integer starting from zero).
+      required:
+        - mobileye,olb
+        - mobileye,id
+
 examples:
   - |
     #include <dt-bindings/interrupt-controller/irq.h>
@@ -116,5 +137,20 @@ examples:
       clocks = <&i2c0clk>, <&pclki2c0>;
       clock-names = "mclk", "apb_pclk";
     };
+  - |
+    #include <dt-bindings/interrupt-controller/mips-gic.h>
+    i2c at 300000 {
+      compatible = "mobileye,eyeq5-i2c", "arm,primecell";
+      reg = <0x300000 0x1000>;
+      interrupt-parent = <&gic>;
+      interrupts = <GIC_SHARED 1 IRQ_TYPE_LEVEL_HIGH>;
+      clock-frequency = <400000>;
+      #address-cells = <1>;
+      #size-cells = <0>;
+      clocks = <&i2c_ser_clk>, <&i2c_clk>;
+      clock-names = "i2cclk", "apb_pclk";
+      mobileye,olb = <&olb>;
+      mobileye,id = <0>;
+    };
 
 ...

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:08 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:08 +0100
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>

Expose I2C device timeout configuration from devicetree. Use ?s as time
unit and express it in the name.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
index 16024415a4a7..e6b95e3765ac 100644
--- a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
@@ -70,6 +70,10 @@ properties:
     minimum: 1
     maximum: 400000
 
+  timeout-usecs:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: Timeout on I2C xfers in ?s.
+
 required:
   - compatible
   - reg
@@ -98,6 +102,7 @@ examples:
       clock-names = "i2cclk", "apb_pclk";
       power-domains = <&pm_domains DOMAIN_VAPE>;
       resets = <&prcc_reset DB8500_PRCC_3 DB8500_PRCC_3_RESET_I2C0>;
+      timeout-usecs = <200000>;
     };
 
     i2c at 101f8000 {

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:10 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:10 +0100
Subject: [PATCH 03/13] dt-bindings: hwmon: lm75: add label property
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-3-19a336e91dca@bootlin.com>

Declare optional label devicetree property. Show usage in one example
with dummy name.

To: Jean Delvare <jdelvare at suse.com>
To: Guenter Roeck <linux at roeck-us.net>
Cc: <linux-hwmon at vger.kernel.org>
Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 Documentation/devicetree/bindings/hwmon/lm75.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/hwmon/lm75.yaml b/Documentation/devicetree/bindings/hwmon/lm75.yaml
index ed269e428a3d..5ca2c83b413d 100644
--- a/Documentation/devicetree/bindings/hwmon/lm75.yaml
+++ b/Documentation/devicetree/bindings/hwmon/lm75.yaml
@@ -52,6 +52,9 @@ properties:
   interrupts:
     maxItems: 1
 
+  label:
+    description: user-facing name of the hardware monitor
+
 required:
   - compatible
   - reg
@@ -83,6 +86,7 @@ examples:
         compatible = "st,stlm75";
         reg = <0x48>;
         vs-supply = <&vs>;
+        label = "CPU temp";
       };
     };
   - |

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:12 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:12 +0100
Subject: [PATCH 05/13] i2c: nomadik: simplify IRQ masking logic
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-5-19a336e91dca@bootlin.com>

IRQ_MASK and I2C_CLEAR_ALL_INTS are redundant. One masks the top three
bits off as reserved, the other one masks the reserved IRQs inside the
u32. Get rid of IRQ_MASK and only use the most restrictive mask.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/i2c/busses/i2c-nomadik.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index cd511c884f99..80bdf7e42613 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -94,9 +94,6 @@
 /* some bits in ICR are reserved */
 #define I2C_CLEAR_ALL_INTS	0x131f007f
 
-/* first three msb bits are reserved */
-#define IRQ_MASK(mask)		(mask & 0x1fffffff)
-
 /* maximum threshold value */
 #define MAX_I2C_FIFO_THRESHOLD	15
 
@@ -249,8 +246,7 @@ static int flush_i2c_fifo(struct nmk_i2c_dev *priv)
  */
 static void disable_all_interrupts(struct nmk_i2c_dev *priv)
 {
-	u32 mask = IRQ_MASK(0);
-	writel(mask, priv->virtbase + I2C_IMSCR);
+	writel(0, priv->virtbase + I2C_IMSCR);
 }
 
 /**
@@ -259,9 +255,7 @@ static void disable_all_interrupts(struct nmk_i2c_dev *priv)
  */
 static void clear_all_interrupts(struct nmk_i2c_dev *priv)
 {
-	u32 mask;
-	mask = IRQ_MASK(I2C_CLEAR_ALL_INTS);
-	writel(mask, priv->virtbase + I2C_ICR);
+	writel(I2C_CLEAR_ALL_INTS, priv->virtbase + I2C_ICR);
 }
 
 /**
@@ -468,7 +462,7 @@ static int read_i2c(struct nmk_i2c_dev *priv, u16 flags)
 	else
 		irq_mask |= I2C_IT_MTDWS;
 
-	irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
+	irq_mask &= I2C_CLEAR_ALL_INTS;
 
 	writel(readl(priv->virtbase + I2C_IMSCR) | irq_mask,
 	       priv->virtbase + I2C_IMSCR);
@@ -547,7 +541,7 @@ static int write_i2c(struct nmk_i2c_dev *priv, u16 flags)
 	else
 		irq_mask |= I2C_IT_MTDWS;
 
-	irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
+	irq_mask &= I2C_CLEAR_ALL_INTS;
 
 	writel(readl(priv->virtbase + I2C_IMSCR) | irq_mask,
 	       priv->virtbase + I2C_IMSCR);
@@ -703,8 +697,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
  */
 static int disable_interrupts(struct nmk_i2c_dev *priv, u32 irq)
 {
-	irq = IRQ_MASK(irq);
-	writel(readl(priv->virtbase + I2C_IMSCR) & ~(I2C_CLEAR_ALL_INTS & irq),
+	irq &= I2C_CLEAR_ALL_INTS;
+	writel(readl(priv->virtbase + I2C_IMSCR) & ~irq,
 	       priv->virtbase + I2C_IMSCR);
 	return 0;
 }

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:13 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:13 +0100
Subject: [PATCH 06/13] i2c: nomadik: use bitops helpers
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-6-19a336e91dca@bootlin.com>

Constant register bit fields are declared using hardcoded hex values;
replace them by calls to BIT() and GENMASK(). Replace custom GEN_MASK()
macro by the generic FIELD_PREP(). Replace manual bit manipulations by
the generic FIELD_GET() macro.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/i2c/busses/i2c-nomadik.c | 150 ++++++++++++++++++++-------------------
 1 file changed, 77 insertions(+), 73 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 80bdf7e42613..aa68ab402b10 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -9,6 +9,7 @@
  * Author: Srinidhi Kasagar <srinidhi.kasagar at stericsson.com>
  * Author: Sachin Verma <sachin.verma at st.com>
  */
+#include <linux/bitfield.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/amba/bus.h>
@@ -42,54 +43,59 @@
 #define I2C_ICR		(0x038)
 
 /* Control registers */
-#define I2C_CR_PE		(0x1 << 0)	/* Peripheral Enable */
-#define I2C_CR_OM		(0x3 << 1)	/* Operating mode */
-#define I2C_CR_SAM		(0x1 << 3)	/* Slave addressing mode */
-#define I2C_CR_SM		(0x3 << 4)	/* Speed mode */
-#define I2C_CR_SGCM		(0x1 << 6)	/* Slave general call mode */
-#define I2C_CR_FTX		(0x1 << 7)	/* Flush Transmit */
-#define I2C_CR_FRX		(0x1 << 8)	/* Flush Receive */
-#define I2C_CR_DMA_TX_EN	(0x1 << 9)	/* DMA Tx enable */
-#define I2C_CR_DMA_RX_EN	(0x1 << 10)	/* DMA Rx Enable */
-#define I2C_CR_DMA_SLE		(0x1 << 11)	/* DMA sync. logic enable */
-#define I2C_CR_LM		(0x1 << 12)	/* Loopback mode */
-#define I2C_CR_FON		(0x3 << 13)	/* Filtering on */
-#define I2C_CR_FS		(0x3 << 15)	/* Force stop enable */
+#define I2C_CR_PE		BIT(0)		/* Peripheral Enable */
+#define I2C_CR_OM		GENMASK(2, 1)	/* Operating mode */
+#define I2C_CR_SAM		BIT(3)		/* Slave addressing mode */
+#define I2C_CR_SM		GENMASK(5, 4)	/* Speed mode */
+#define I2C_CR_SGCM		BIT(6)		/* Slave general call mode */
+#define I2C_CR_FTX		BIT(7)		/* Flush Transmit */
+#define I2C_CR_FRX		BIT(8)		/* Flush Receive */
+#define I2C_CR_DMA_TX_EN	BIT(9)		/* DMA Tx enable */
+#define I2C_CR_DMA_RX_EN	BIT(10)		/* DMA Rx Enable */
+#define I2C_CR_DMA_SLE		BIT(11)		/* DMA sync. logic enable */
+#define I2C_CR_LM		BIT(12)		/* Loopback mode */
+#define I2C_CR_FON		GENMASK(14, 13)	/* Filtering on */
+#define I2C_CR_FS		GENMASK(16, 15)	/* Force stop enable */
+
+/* Slave control register (SCR) */
+#define I2C_SCR_SLSU		GENMASK(31, 16)	/* Slave data setup time */
 
 /* Master controller (MCR) register */
-#define I2C_MCR_OP		(0x1 << 0)	/* Operation */
-#define I2C_MCR_A7		(0x7f << 1)	/* 7-bit address */
-#define I2C_MCR_EA10		(0x7 << 8)	/* 10-bit Extended address */
-#define I2C_MCR_SB		(0x1 << 11)	/* Extended address */
-#define I2C_MCR_AM		(0x3 << 12)	/* Address type */
-#define I2C_MCR_STOP		(0x1 << 14)	/* Stop condition */
-#define I2C_MCR_LENGTH		(0x7ff << 15)	/* Transaction length */
+#define I2C_MCR_OP		BIT(0)		/* Operation */
+#define I2C_MCR_A7		GENMASK(7, 1)	/* 7-bit address */
+#define I2C_MCR_EA10		GENMASK(10, 8)	/* 10-bit Extended address */
+#define I2C_MCR_SB		BIT(11)		/* Extended address */
+#define I2C_MCR_AM		GENMASK(13, 12)	/* Address type */
+#define I2C_MCR_STOP		BIT(14)		/* Stop condition */
+#define I2C_MCR_LENGTH		GENMASK(25, 15)	/* Transaction length */
 
 /* Status register (SR) */
-#define I2C_SR_OP		(0x3 << 0)	/* Operation */
-#define I2C_SR_STATUS		(0x3 << 2)	/* controller status */
-#define I2C_SR_CAUSE		(0x7 << 4)	/* Abort cause */
-#define I2C_SR_TYPE		(0x3 << 7)	/* Receive type */
-#define I2C_SR_LENGTH		(0x7ff << 9)	/* Transfer length */
+#define I2C_SR_OP		GENMASK(1, 0)	/* Operation */
+#define I2C_SR_STATUS		GENMASK(3, 2)	/* controller status */
+#define I2C_SR_CAUSE		GENMASK(6, 4)	/* Abort cause */
+#define I2C_SR_TYPE		GENMASK(8, 7)	/* Receive type */
+#define I2C_SR_LENGTH		GENMASK(19, 9)	/* Transfer length */
+
+/* Baud-rate counter register (BRCR) */
+#define I2C_BRCR_BRCNT1		GENMASK(31, 16)	/* Baud-rate counter 1 */
+#define I2C_BRCR_BRCNT2		GENMASK(15, 0)	/* Baud-rate counter 2 */
 
 /* Interrupt mask set/clear (IMSCR) bits */
-#define I2C_IT_TXFE		(0x1 << 0)
-#define I2C_IT_TXFNE		(0x1 << 1)
-#define I2C_IT_TXFF		(0x1 << 2)
-#define I2C_IT_TXFOVR		(0x1 << 3)
-#define I2C_IT_RXFE		(0x1 << 4)
-#define I2C_IT_RXFNF		(0x1 << 5)
-#define I2C_IT_RXFF		(0x1 << 6)
-#define I2C_IT_RFSR		(0x1 << 16)
-#define I2C_IT_RFSE		(0x1 << 17)
-#define I2C_IT_WTSR		(0x1 << 18)
-#define I2C_IT_MTD		(0x1 << 19)
-#define I2C_IT_STD		(0x1 << 20)
-#define I2C_IT_MAL		(0x1 << 24)
-#define I2C_IT_BERR		(0x1 << 25)
-#define I2C_IT_MTDWS		(0x1 << 28)
-
-#define GEN_MASK(val, mask, sb)  (((val) << (sb)) & (mask))
+#define I2C_IT_TXFE		BIT(0)
+#define I2C_IT_TXFNE		BIT(1)
+#define I2C_IT_TXFF		BIT(2)
+#define I2C_IT_TXFOVR		BIT(3)
+#define I2C_IT_RXFE		BIT(4)
+#define I2C_IT_RXFNF		BIT(5)
+#define I2C_IT_RXFF		BIT(6)
+#define I2C_IT_RFSR		BIT(16)
+#define I2C_IT_RFSE		BIT(17)
+#define I2C_IT_WTSR		BIT(18)
+#define I2C_IT_MTD		BIT(19)
+#define I2C_IT_STD		BIT(20)
+#define I2C_IT_MAL		BIT(24)
+#define I2C_IT_BERR		BIT(25)
+#define I2C_IT_MTDWS		BIT(28)
 
 /* some bits in ICR are reserved */
 #define I2C_CLEAR_ALL_INTS	0x131f007f
@@ -284,7 +290,7 @@ static int init_hw(struct nmk_i2c_dev *priv)
 }
 
 /* enable peripheral, master mode operation */
-#define DEFAULT_I2C_REG_CR	((1 << 1) | I2C_CR_PE)
+#define DEFAULT_I2C_REG_CR	(FIELD_PREP(I2C_CR_OM, 0b01) | I2C_CR_PE)
 
 /**
  * load_i2c_mcr_reg() - load the MCR register
@@ -296,41 +302,42 @@ static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *priv, u16 flags)
 	u32 mcr = 0;
 	unsigned short slave_adr_3msb_bits;
 
-	mcr |= GEN_MASK(priv->cli.slave_adr, I2C_MCR_A7, 1);
+	mcr |= FIELD_PREP(I2C_MCR_A7, priv->cli.slave_adr);
 
 	if (unlikely(flags & I2C_M_TEN)) {
 		/* 10-bit address transaction */
-		mcr |= GEN_MASK(2, I2C_MCR_AM, 12);
+		mcr |= FIELD_PREP(I2C_MCR_AM, 2);
 		/*
 		 * Get the top 3 bits.
 		 * EA10 represents extended address in MCR. This includes
 		 * the extension (MSB bits) of the 7 bit address loaded
 		 * in A7
 		 */
-		slave_adr_3msb_bits = (priv->cli.slave_adr >> 7) & 0x7;
+		slave_adr_3msb_bits = FIELD_GET(GENMASK(9, 7),
+						priv->cli.slave_adr);
 
-		mcr |= GEN_MASK(slave_adr_3msb_bits, I2C_MCR_EA10, 8);
+		mcr |= FIELD_PREP(I2C_MCR_EA10, slave_adr_3msb_bits);
 	} else {
 		/* 7-bit address transaction */
-		mcr |= GEN_MASK(1, I2C_MCR_AM, 12);
+		mcr |= FIELD_PREP(I2C_MCR_AM, 1);
 	}
 
 	/* start byte procedure not applied */
-	mcr |= GEN_MASK(0, I2C_MCR_SB, 11);
+	mcr |= FIELD_PREP(I2C_MCR_SB, 0);
 
 	/* check the operation, master read/write? */
 	if (priv->cli.operation == I2C_WRITE)
-		mcr |= GEN_MASK(I2C_WRITE, I2C_MCR_OP, 0);
+		mcr |= FIELD_PREP(I2C_MCR_OP, I2C_WRITE);
 	else
-		mcr |= GEN_MASK(I2C_READ, I2C_MCR_OP, 0);
+		mcr |= FIELD_PREP(I2C_MCR_OP, I2C_READ);
 
 	/* stop or repeated start? */
 	if (priv->stop)
-		mcr |= GEN_MASK(1, I2C_MCR_STOP, 14);
+		mcr |= FIELD_PREP(I2C_MCR_STOP, 1);
 	else
-		mcr &= ~(GEN_MASK(1, I2C_MCR_STOP, 14));
+		mcr &= ~FIELD_PREP(I2C_MCR_STOP, 1);
 
-	mcr |= GEN_MASK(priv->cli.count, I2C_MCR_LENGTH, 15);
+	mcr |= FIELD_PREP(I2C_MCR_LENGTH, priv->cli.count);
 
 	return mcr;
 }
@@ -383,7 +390,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
 	slsu += 1;
 
 	dev_dbg(&priv->adev->dev, "calculated SLSU = %04x\n", slsu);
-	writel(slsu << 16, priv->virtbase + I2C_SCR);
+	writel(FIELD_PREP(I2C_SCR_SLSU, slsu), priv->virtbase + I2C_SCR);
 
 	/*
 	 * The spec says, in case of std. mode the divider is
@@ -399,8 +406,8 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
 	 * plus operation. Currently we do not supprt high speed mode
 	 * so set brcr1 to 0.
 	 */
-	brcr1 = 0 << 16;
-	brcr2 = (i2c_clk / (priv->clk_freq * div)) & 0xffff;
+	brcr1 = FIELD_PREP(I2C_BRCR_BRCNT1, 0);
+	brcr2 = FIELD_PREP(I2C_BRCR_BRCNT2, i2c_clk / (priv->clk_freq * div));
 
 	/* set the baud rate counter register */
 	writel((brcr1 | brcr2), priv->virtbase + I2C_BRCR);
@@ -414,12 +421,13 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
 	if (priv->sm > I2C_FREQ_MODE_FAST) {
 		dev_err(&priv->adev->dev,
 			"do not support this mode defaulting to std. mode\n");
-		brcr2 = i2c_clk / (I2C_MAX_STANDARD_MODE_FREQ * 2) & 0xffff;
+		brcr2 = FIELD_PREP(I2C_BRCR_BRCNT2,
+				   i2c_clk / (I2C_MAX_STANDARD_MODE_FREQ * 2));
 		writel((brcr1 | brcr2), priv->virtbase + I2C_BRCR);
-		writel(I2C_FREQ_MODE_STANDARD << 4,
-				priv->virtbase + I2C_CR);
+		writel(FIELD_PREP(I2C_CR_SM, I2C_FREQ_MODE_STANDARD),
+		       priv->virtbase + I2C_CR);
 	}
-	writel(priv->sm << 4, priv->virtbase + I2C_CR);
+	writel(FIELD_PREP(I2C_CR_SM, priv->sm), priv->virtbase + I2C_CR);
 
 	/* set the Tx and Rx FIFO threshold */
 	writel(priv->tft, priv->virtbase + I2C_TFTR);
@@ -583,13 +591,8 @@ static int nmk_i2c_xfer_one(struct nmk_i2c_dev *priv, u16 flags)
 		u32 cause;
 
 		i2c_sr = readl(priv->virtbase + I2C_SR);
-		/*
-		 * Check if the controller I2C operation status
-		 * is set to ABORT(11b).
-		 */
-		if (((i2c_sr >> 2) & 0x3) == 0x3) {
-			/* get the abort cause */
-			cause =	(i2c_sr >> 4) & 0x7;
+		if (FIELD_GET(I2C_SR_STATUS, i2c_sr) == I2C_ABORT) {
+			cause = FIELD_GET(I2C_SR_CAUSE, i2c_sr);
 			dev_err(&priv->adev->dev, "%s\n",
 				cause >= ARRAY_SIZE(abort_causes) ?
 				"unknown reason" :
@@ -730,7 +733,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 	misr = readl(priv->virtbase + I2C_MISR);
 
 	src = __ffs(misr);
-	switch ((1 << src)) {
+	switch (BIT(src)) {
 
 	/* Transmit FIFO nearly empty interrupt */
 	case I2C_IT_TXFNE:
@@ -824,15 +827,16 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 	 * during the transaction.
 	 */
 	case I2C_IT_BERR:
+	{
+		u32 sr = readl(priv->virtbase + I2C_SR);
 		priv->result = -EIO;
-		/* get the status */
-		if (((readl(priv->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT)
+		if (FIELD_GET(I2C_SR_STATUS, sr) == I2C_ABORT)
 			init_hw(priv);
 
 		i2c_set_bit(priv->virtbase + I2C_ICR, I2C_IT_BERR);
 		complete(&priv->xfer_complete);
-
-		break;
+	}
+	break;
 
 	/*
 	 * Tx FIFO overrun interrupt.

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:14 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:14 +0100
Subject: [PATCH 07/13] i2c: nomadik: support short xfer timeouts using
 waitqueue & hrtimer
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-7-19a336e91dca@bootlin.com>

Replace the completion by a waitqueue for synchronization from IRQ
handler to task. For short timeouts, use hrtimers, else use timers.
Usecase: avoid blocking the I2C bus for too long when an issue occurs.

The threshold picked is one jiffy: if timeout is below that, use
hrtimers. This threshold is NOT configurable.

Implement behavior but do NOT change fetching of timeout. This means the
timeout is unchanged (200ms) and the hrtimer case will never trigger.

A waitqueue is used because it supports both desired timeout approaches.
See wait_event_timeout() and wait_event_hrtimeout(). An atomic boolean
serves as synchronization condition.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/i2c/busses/i2c-nomadik.c | 70 +++++++++++++++++++++++++++-------------
 1 file changed, 48 insertions(+), 22 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index aa68ab402b10..e68b8e0d7919 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -162,10 +162,11 @@ struct i2c_nmk_client {
  * @clk_freq: clock frequency for the operation mode
  * @tft: Tx FIFO Threshold in bytes
  * @rft: Rx FIFO Threshold in bytes
- * @timeout: Slave response timeout (ms)
+ * @timeout_usecs: Slave response timeout
  * @sm: speed mode
  * @stop: stop condition.
- * @xfer_complete: acknowledge completion for a I2C message.
+ * @xfer_wq: xfer done wait queue.
+ * @xfer_done: xfer done boolean.
  * @result: controller propogated result.
  */
 struct nmk_i2c_dev {
@@ -179,10 +180,11 @@ struct nmk_i2c_dev {
 	u32				clk_freq;
 	unsigned char			tft;
 	unsigned char			rft;
-	int				timeout;
+	int				timeout_usecs;
 	enum i2c_freq_mode		sm;
 	int				stop;
-	struct completion		xfer_complete;
+	struct wait_queue_head		xfer_wq;
+	bool				xfer_done;
 	int				result;
 };
 
@@ -434,6 +436,22 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
 	writel(priv->rft, priv->virtbase + I2C_RFTR);
 }
 
+static bool nmk_i2c_wait_xfer_done(struct nmk_i2c_dev *priv)
+{
+	if (priv->timeout_usecs < jiffies_to_usecs(1)) {
+		unsigned long timeout_usecs = priv->timeout_usecs;
+		ktime_t timeout = ktime_set(0, timeout_usecs * NSEC_PER_USEC);
+
+		wait_event_hrtimeout(priv->xfer_wq, priv->xfer_done, timeout);
+	} else {
+		unsigned long timeout = usecs_to_jiffies(priv->timeout_usecs);
+
+		wait_event_timeout(priv->xfer_wq, priv->xfer_done, timeout);
+	}
+
+	return priv->xfer_done;
+}
+
 /**
  * read_i2c() - Read from I2C client device
  * @priv: private data of I2C Driver
@@ -445,9 +463,9 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
  */
 static int read_i2c(struct nmk_i2c_dev *priv, u16 flags)
 {
-	int status = 0;
 	u32 mcr, irq_mask;
-	unsigned long timeout;
+	int status = 0;
+	bool xfer_done;
 
 	mcr = load_i2c_mcr_reg(priv, flags);
 	writel(mcr, priv->virtbase + I2C_MCR);
@@ -459,7 +477,8 @@ static int read_i2c(struct nmk_i2c_dev *priv, u16 flags)
 	/* enable the controller */
 	i2c_set_bit(priv->virtbase + I2C_CR, I2C_CR_PE);
 
-	init_completion(&priv->xfer_complete);
+	init_waitqueue_head(&priv->xfer_wq);
+	priv->xfer_done = false;
 
 	/* enable interrupts by setting the mask */
 	irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF |
@@ -475,10 +494,9 @@ static int read_i2c(struct nmk_i2c_dev *priv, u16 flags)
 	writel(readl(priv->virtbase + I2C_IMSCR) | irq_mask,
 	       priv->virtbase + I2C_IMSCR);
 
-	timeout = wait_for_completion_timeout(
-		&priv->xfer_complete, priv->adap.timeout);
+	xfer_done = nmk_i2c_wait_xfer_done(priv);
 
-	if (timeout == 0) {
+	if (!xfer_done) {
 		/* Controller timed out */
 		dev_err(&priv->adev->dev, "read from slave 0x%x timed out\n",
 			priv->cli.slave_adr);
@@ -513,9 +531,9 @@ static void fill_tx_fifo(struct nmk_i2c_dev *priv, int no_bytes)
  */
 static int write_i2c(struct nmk_i2c_dev *priv, u16 flags)
 {
-	u32 status = 0;
 	u32 mcr, irq_mask;
-	unsigned long timeout;
+	u32 status = 0;
+	bool xfer_done;
 
 	mcr = load_i2c_mcr_reg(priv, flags);
 
@@ -528,7 +546,8 @@ static int write_i2c(struct nmk_i2c_dev *priv, u16 flags)
 	/* enable the controller */
 	i2c_set_bit(priv->virtbase + I2C_CR, I2C_CR_PE);
 
-	init_completion(&priv->xfer_complete);
+	init_waitqueue_head(&priv->xfer_wq);
+	priv->xfer_done = false;
 
 	/* enable interrupts by settings the masks */
 	irq_mask = (I2C_IT_TXFOVR | I2C_IT_MAL | I2C_IT_BERR);
@@ -554,10 +573,9 @@ static int write_i2c(struct nmk_i2c_dev *priv, u16 flags)
 	writel(readl(priv->virtbase + I2C_IMSCR) | irq_mask,
 	       priv->virtbase + I2C_IMSCR);
 
-	timeout = wait_for_completion_timeout(
-		&priv->xfer_complete, priv->adap.timeout);
+	xfer_done = nmk_i2c_wait_xfer_done(priv);
 
-	if (timeout == 0) {
+	if (!xfer_done) {
 		/* Controller timed out */
 		dev_err(&priv->adev->dev, "write to slave 0x%x timed out\n",
 			priv->cli.slave_adr);
@@ -807,7 +825,9 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 				priv->cli.count);
 			init_hw(priv);
 		}
-		complete(&priv->xfer_complete);
+		priv->xfer_done = true;
+		wake_up(&priv->xfer_wq);
+
 
 		break;
 
@@ -817,7 +837,9 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 		init_hw(priv);
 
 		i2c_set_bit(priv->virtbase + I2C_ICR, I2C_IT_MAL);
-		complete(&priv->xfer_complete);
+		priv->xfer_done = true;
+		wake_up(&priv->xfer_wq);
+
 
 		break;
 
@@ -834,7 +856,9 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 			init_hw(priv);
 
 		i2c_set_bit(priv->virtbase + I2C_ICR, I2C_IT_BERR);
-		complete(&priv->xfer_complete);
+		priv->xfer_done = true;
+		wake_up(&priv->xfer_wq);
+
 	}
 	break;
 
@@ -848,7 +872,9 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 		init_hw(priv);
 
 		dev_err(dev, "Tx Fifo Over run\n");
-		complete(&priv->xfer_complete);
+		priv->xfer_done = true;
+		wake_up(&priv->xfer_wq);
+
 
 		break;
 
@@ -949,7 +975,7 @@ static void nmk_i2c_of_probe(struct device_node *np,
 		priv->sm = I2C_FREQ_MODE_FAST;
 	priv->tft = 1; /* Tx FIFO threshold */
 	priv->rft = 8; /* Rx FIFO threshold */
-	priv->timeout = 200; /* Slave response timeout(ms) */
+	priv->timeout_usecs = 200 * USEC_PER_MSEC; /* Slave response timeout */
 }
 
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
@@ -1009,7 +1035,7 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 	adap->owner = THIS_MODULE;
 	adap->class = I2C_CLASS_DEPRECATED;
 	adap->algo = &nmk_i2c_algo;
-	adap->timeout = msecs_to_jiffies(priv->timeout);
+	adap->timeout = usecs_to_jiffies(priv->timeout_usecs);
 	snprintf(adap->name, sizeof(adap->name),
 		 "Nomadik I2C at %pR", &adev->res);
 

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:15 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:15 +0100
Subject: [PATCH 08/13] i2c: nomadik: replace jiffies by ktime for FIFO
 flushing timeout
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-8-19a336e91dca@bootlin.com>

The FIFO flush function uses a jiffies amount to detect timeouts as the
flushing is async. Replace with ktime to get more accurate precision
and support short timeouts.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/i2c/busses/i2c-nomadik.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index e68b8e0d7919..afd54999bbbb 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -219,8 +219,8 @@ static inline void i2c_clr_bit(void __iomem *reg, u32 mask)
 static int flush_i2c_fifo(struct nmk_i2c_dev *priv)
 {
 #define LOOP_ATTEMPTS 10
+	ktime_t timeout;
 	int i;
-	unsigned long timeout;
 
 	/*
 	 * flush the transmit and receive FIFO. The flushing
@@ -232,9 +232,9 @@ static int flush_i2c_fifo(struct nmk_i2c_dev *priv)
 	writel((I2C_CR_FTX | I2C_CR_FRX), priv->virtbase + I2C_CR);
 
 	for (i = 0; i < LOOP_ATTEMPTS; i++) {
-		timeout = jiffies + priv->adap.timeout;
+		timeout = ktime_add_us(ktime_get(), priv->timeout_usecs);
 
-		while (!time_after(jiffies, timeout)) {
+		while (ktime_after(timeout, ktime_get())) {
 			if ((readl(priv->virtbase + I2C_CR) &
 				(I2C_CR_FTX | I2C_CR_FRX)) == 0)
 				return 0;

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:16 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:16 +0100
Subject: [PATCH 09/13] i2c: nomadik: fetch timeout-usecs property from
 devicetree
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-9-19a336e91dca@bootlin.com>

Allow overriding the default timeout value (200ms) from devicetree,
using the timeout-usecs property.

The i2c_adapter->timeout field is an unaccurate jiffies amount;
i2c-nomadik uses hrtimers for timeouts below one jiffy.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/i2c/busses/i2c-nomadik.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index afd54999bbbb..23e12c570457 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -964,6 +964,8 @@ static const struct i2c_algorithm nmk_i2c_algo = {
 static void nmk_i2c_of_probe(struct device_node *np,
 			     struct nmk_i2c_dev *priv)
 {
+	u32 timeout_usecs;
+
 	/* Default to 100 kHz if no frequency is given in the node */
 	if (of_property_read_u32(np, "clock-frequency", &priv->clk_freq))
 		priv->clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
@@ -975,7 +977,12 @@ static void nmk_i2c_of_probe(struct device_node *np,
 		priv->sm = I2C_FREQ_MODE_FAST;
 	priv->tft = 1; /* Tx FIFO threshold */
 	priv->rft = 8; /* Rx FIFO threshold */
-	priv->timeout_usecs = 200 * USEC_PER_MSEC; /* Slave response timeout */
+
+	/* Slave response timeout */
+	if (!of_property_read_u32(np, "timeout-usecs", &timeout_usecs))
+		priv->timeout_usecs = timeout_usecs;
+	else
+		priv->timeout_usecs = 200 * USEC_PER_MSEC;
 }
 
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:11 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:11 +0100
Subject: [PATCH 04/13] i2c: nomadik: rename private struct pointers from
 dev to priv
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-4-19a336e91dca@bootlin.com>

Disambiguate the usage of dev as a variable name; it is usually best to
keep it reserved for struct device pointers. Avoid having multiple
names for the same struct pointer (previously: dev, nmk, nmk_i2c).

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/i2c/busses/i2c-nomadik.c | 428 +++++++++++++++++++--------------------
 1 file changed, 214 insertions(+), 214 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index b10574d42b7a..cd511c884f99 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -206,12 +206,12 @@ static inline void i2c_clr_bit(void __iomem *reg, u32 mask)
 
 /**
  * flush_i2c_fifo() - This function flushes the I2C FIFO
- * @dev: private data of I2C Driver
+ * @priv: private data of I2C Driver
  *
  * This function flushes the I2C Tx and Rx FIFOs. It returns
  * 0 on successful flushing of FIFO
  */
-static int flush_i2c_fifo(struct nmk_i2c_dev *dev)
+static int flush_i2c_fifo(struct nmk_i2c_dev *priv)
 {
 #define LOOP_ATTEMPTS 10
 	int i;
@@ -224,19 +224,19 @@ static int flush_i2c_fifo(struct nmk_i2c_dev *dev)
 	 * bits, until then no one must access Tx, Rx FIFO and
 	 * should poll on these bits waiting for the completion.
 	 */
-	writel((I2C_CR_FTX | I2C_CR_FRX), dev->virtbase + I2C_CR);
+	writel((I2C_CR_FTX | I2C_CR_FRX), priv->virtbase + I2C_CR);
 
 	for (i = 0; i < LOOP_ATTEMPTS; i++) {
-		timeout = jiffies + dev->adap.timeout;
+		timeout = jiffies + priv->adap.timeout;
 
 		while (!time_after(jiffies, timeout)) {
-			if ((readl(dev->virtbase + I2C_CR) &
+			if ((readl(priv->virtbase + I2C_CR) &
 				(I2C_CR_FTX | I2C_CR_FRX)) == 0)
-					return 0;
+				return 0;
 		}
 	}
 
-	dev_err(&dev->adev->dev,
+	dev_err(&priv->adev->dev,
 		"flushing operation timed out giving up after %d attempts",
 		LOOP_ATTEMPTS);
 
@@ -245,45 +245,45 @@ static int flush_i2c_fifo(struct nmk_i2c_dev *dev)
 
 /**
  * disable_all_interrupts() - Disable all interrupts of this I2c Bus
- * @dev: private data of I2C Driver
+ * @priv: private data of I2C Driver
  */
-static void disable_all_interrupts(struct nmk_i2c_dev *dev)
+static void disable_all_interrupts(struct nmk_i2c_dev *priv)
 {
 	u32 mask = IRQ_MASK(0);
-	writel(mask, dev->virtbase + I2C_IMSCR);
+	writel(mask, priv->virtbase + I2C_IMSCR);
 }
 
 /**
  * clear_all_interrupts() - Clear all interrupts of I2C Controller
- * @dev: private data of I2C Driver
+ * @priv: private data of I2C Driver
  */
-static void clear_all_interrupts(struct nmk_i2c_dev *dev)
+static void clear_all_interrupts(struct nmk_i2c_dev *priv)
 {
 	u32 mask;
 	mask = IRQ_MASK(I2C_CLEAR_ALL_INTS);
-	writel(mask, dev->virtbase + I2C_ICR);
+	writel(mask, priv->virtbase + I2C_ICR);
 }
 
 /**
  * init_hw() - initialize the I2C hardware
- * @dev: private data of I2C Driver
+ * @priv: private data of I2C Driver
  */
-static int init_hw(struct nmk_i2c_dev *dev)
+static int init_hw(struct nmk_i2c_dev *priv)
 {
 	int stat;
 
-	stat = flush_i2c_fifo(dev);
+	stat = flush_i2c_fifo(priv);
 	if (stat)
 		goto exit;
 
 	/* disable the controller */
-	i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
+	i2c_clr_bit(priv->virtbase + I2C_CR, I2C_CR_PE);
 
-	disable_all_interrupts(dev);
+	disable_all_interrupts(priv);
 
-	clear_all_interrupts(dev);
+	clear_all_interrupts(priv);
 
-	dev->cli.operation = I2C_NO_OPERATION;
+	priv->cli.operation = I2C_NO_OPERATION;
 
 exit:
 	return stat;
@@ -294,15 +294,15 @@ static int init_hw(struct nmk_i2c_dev *dev)
 
 /**
  * load_i2c_mcr_reg() - load the MCR register
- * @dev: private data of controller
+ * @priv: private data of controller
  * @flags: message flags
  */
-static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *dev, u16 flags)
+static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *priv, u16 flags)
 {
 	u32 mcr = 0;
 	unsigned short slave_adr_3msb_bits;
 
-	mcr |= GEN_MASK(dev->cli.slave_adr, I2C_MCR_A7, 1);
+	mcr |= GEN_MASK(priv->cli.slave_adr, I2C_MCR_A7, 1);
 
 	if (unlikely(flags & I2C_M_TEN)) {
 		/* 10-bit address transaction */
@@ -313,7 +313,7 @@ static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *dev, u16 flags)
 		 * the extension (MSB bits) of the 7 bit address loaded
 		 * in A7
 		 */
-		slave_adr_3msb_bits = (dev->cli.slave_adr >> 7) & 0x7;
+		slave_adr_3msb_bits = (priv->cli.slave_adr >> 7) & 0x7;
 
 		mcr |= GEN_MASK(slave_adr_3msb_bits, I2C_MCR_EA10, 8);
 	} else {
@@ -325,40 +325,40 @@ static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *dev, u16 flags)
 	mcr |= GEN_MASK(0, I2C_MCR_SB, 11);
 
 	/* check the operation, master read/write? */
-	if (dev->cli.operation == I2C_WRITE)
+	if (priv->cli.operation == I2C_WRITE)
 		mcr |= GEN_MASK(I2C_WRITE, I2C_MCR_OP, 0);
 	else
 		mcr |= GEN_MASK(I2C_READ, I2C_MCR_OP, 0);
 
 	/* stop or repeated start? */
-	if (dev->stop)
+	if (priv->stop)
 		mcr |= GEN_MASK(1, I2C_MCR_STOP, 14);
 	else
 		mcr &= ~(GEN_MASK(1, I2C_MCR_STOP, 14));
 
-	mcr |= GEN_MASK(dev->cli.count, I2C_MCR_LENGTH, 15);
+	mcr |= GEN_MASK(priv->cli.count, I2C_MCR_LENGTH, 15);
 
 	return mcr;
 }
 
 /**
  * setup_i2c_controller() - setup the controller
- * @dev: private data of controller
+ * @priv: private data of controller
  */
-static void setup_i2c_controller(struct nmk_i2c_dev *dev)
+static void setup_i2c_controller(struct nmk_i2c_dev *priv)
 {
 	u32 brcr1, brcr2;
 	u32 i2c_clk, div;
 	u32 ns;
 	u16 slsu;
 
-	writel(0x0, dev->virtbase + I2C_CR);
-	writel(0x0, dev->virtbase + I2C_HSMCR);
-	writel(0x0, dev->virtbase + I2C_TFTR);
-	writel(0x0, dev->virtbase + I2C_RFTR);
-	writel(0x0, dev->virtbase + I2C_DMAR);
+	writel(0x0, priv->virtbase + I2C_CR);
+	writel(0x0, priv->virtbase + I2C_HSMCR);
+	writel(0x0, priv->virtbase + I2C_TFTR);
+	writel(0x0, priv->virtbase + I2C_RFTR);
+	writel(0x0, priv->virtbase + I2C_DMAR);
 
-	i2c_clk = clk_get_rate(dev->clk);
+	i2c_clk = clk_get_rate(priv->clk);
 
 	/*
 	 * set the slsu:
@@ -373,7 +373,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
 	 * slsu = cycles / (1000000000 / f) + 1
 	 */
 	ns = DIV_ROUND_UP_ULL(1000000000ULL, i2c_clk);
-	switch (dev->sm) {
+	switch (priv->sm) {
 	case I2C_FREQ_MODE_FAST:
 	case I2C_FREQ_MODE_FAST_PLUS:
 		slsu = DIV_ROUND_UP(100, ns); /* Fast */
@@ -388,15 +388,15 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
 	}
 	slsu += 1;
 
-	dev_dbg(&dev->adev->dev, "calculated SLSU = %04x\n", slsu);
-	writel(slsu << 16, dev->virtbase + I2C_SCR);
+	dev_dbg(&priv->adev->dev, "calculated SLSU = %04x\n", slsu);
+	writel(slsu << 16, priv->virtbase + I2C_SCR);
 
 	/*
 	 * The spec says, in case of std. mode the divider is
 	 * 2 whereas it is 3 for fast and fastplus mode of
 	 * operation. TODO - high speed support.
 	 */
-	div = (dev->clk_freq > I2C_MAX_STANDARD_MODE_FREQ) ? 3 : 2;
+	div = (priv->clk_freq > I2C_MAX_STANDARD_MODE_FREQ) ? 3 : 2;
 
 	/*
 	 * generate the mask for baud rate counters. The controller
@@ -406,10 +406,10 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
 	 * so set brcr1 to 0.
 	 */
 	brcr1 = 0 << 16;
-	brcr2 = (i2c_clk/(dev->clk_freq * div)) & 0xffff;
+	brcr2 = (i2c_clk / (priv->clk_freq * div)) & 0xffff;
 
 	/* set the baud rate counter register */
-	writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
+	writel((brcr1 | brcr2), priv->virtbase + I2C_BRCR);
 
 	/*
 	 * set the speed mode. Currently we support
@@ -417,125 +417,124 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
 	 * TODO - support for fast mode plus (up to 1Mb/s)
 	 * and high speed (up to 3.4 Mb/s)
 	 */
-	if (dev->sm > I2C_FREQ_MODE_FAST) {
-		dev_err(&dev->adev->dev,
+	if (priv->sm > I2C_FREQ_MODE_FAST) {
+		dev_err(&priv->adev->dev,
 			"do not support this mode defaulting to std. mode\n");
 		brcr2 = i2c_clk / (I2C_MAX_STANDARD_MODE_FREQ * 2) & 0xffff;
-		writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
+		writel((brcr1 | brcr2), priv->virtbase + I2C_BRCR);
 		writel(I2C_FREQ_MODE_STANDARD << 4,
-				dev->virtbase + I2C_CR);
+				priv->virtbase + I2C_CR);
 	}
-	writel(dev->sm << 4, dev->virtbase + I2C_CR);
+	writel(priv->sm << 4, priv->virtbase + I2C_CR);
 
 	/* set the Tx and Rx FIFO threshold */
-	writel(dev->tft, dev->virtbase + I2C_TFTR);
-	writel(dev->rft, dev->virtbase + I2C_RFTR);
+	writel(priv->tft, priv->virtbase + I2C_TFTR);
+	writel(priv->rft, priv->virtbase + I2C_RFTR);
 }
 
 /**
  * read_i2c() - Read from I2C client device
- * @dev: private data of I2C Driver
+ * @priv: private data of I2C Driver
  * @flags: message flags
  *
  * This function reads from i2c client device when controller is in
  * master mode. There is a completion timeout. If there is no transfer
  * before timeout error is returned.
  */
-static int read_i2c(struct nmk_i2c_dev *dev, u16 flags)
+static int read_i2c(struct nmk_i2c_dev *priv, u16 flags)
 {
 	int status = 0;
 	u32 mcr, irq_mask;
 	unsigned long timeout;
 
-	mcr = load_i2c_mcr_reg(dev, flags);
-	writel(mcr, dev->virtbase + I2C_MCR);
+	mcr = load_i2c_mcr_reg(priv, flags);
+	writel(mcr, priv->virtbase + I2C_MCR);
 
 	/* load the current CR value */
-	writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
-			dev->virtbase + I2C_CR);
+	writel(readl(priv->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
+	       priv->virtbase + I2C_CR);
 
 	/* enable the controller */
-	i2c_set_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
+	i2c_set_bit(priv->virtbase + I2C_CR, I2C_CR_PE);
 
-	init_completion(&dev->xfer_complete);
+	init_completion(&priv->xfer_complete);
 
 	/* enable interrupts by setting the mask */
 	irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF |
 			I2C_IT_MAL | I2C_IT_BERR);
 
-	if (dev->stop || !dev->vendor->has_mtdws)
+	if (priv->stop || !priv->vendor->has_mtdws)
 		irq_mask |= I2C_IT_MTD;
 	else
 		irq_mask |= I2C_IT_MTDWS;
 
 	irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
 
-	writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
-			dev->virtbase + I2C_IMSCR);
+	writel(readl(priv->virtbase + I2C_IMSCR) | irq_mask,
+	       priv->virtbase + I2C_IMSCR);
 
 	timeout = wait_for_completion_timeout(
-		&dev->xfer_complete, dev->adap.timeout);
+		&priv->xfer_complete, priv->adap.timeout);
 
 	if (timeout == 0) {
 		/* Controller timed out */
-		dev_err(&dev->adev->dev, "read from slave 0x%x timed out\n",
-				dev->cli.slave_adr);
+		dev_err(&priv->adev->dev, "read from slave 0x%x timed out\n",
+			priv->cli.slave_adr);
 		status = -ETIMEDOUT;
 	}
 	return status;
 }
 
-static void fill_tx_fifo(struct nmk_i2c_dev *dev, int no_bytes)
+static void fill_tx_fifo(struct nmk_i2c_dev *priv, int no_bytes)
 {
 	int count;
 
 	for (count = (no_bytes - 2);
 			(count > 0) &&
-			(dev->cli.count != 0);
+			(priv->cli.count != 0);
 			count--) {
 		/* write to the Tx FIFO */
-		writeb(*dev->cli.buffer,
-			dev->virtbase + I2C_TFR);
-		dev->cli.buffer++;
-		dev->cli.count--;
-		dev->cli.xfer_bytes++;
+		writeb(*priv->cli.buffer, priv->virtbase + I2C_TFR);
+		priv->cli.buffer++;
+		priv->cli.count--;
+		priv->cli.xfer_bytes++;
 	}
 
 }
 
 /**
  * write_i2c() - Write data to I2C client.
- * @dev: private data of I2C Driver
+ * @priv: private data of I2C Driver
  * @flags: message flags
  *
  * This function writes data to I2C client
  */
-static int write_i2c(struct nmk_i2c_dev *dev, u16 flags)
+static int write_i2c(struct nmk_i2c_dev *priv, u16 flags)
 {
 	u32 status = 0;
 	u32 mcr, irq_mask;
 	unsigned long timeout;
 
-	mcr = load_i2c_mcr_reg(dev, flags);
+	mcr = load_i2c_mcr_reg(priv, flags);
 
-	writel(mcr, dev->virtbase + I2C_MCR);
+	writel(mcr, priv->virtbase + I2C_MCR);
 
 	/* load the current CR value */
-	writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
-			dev->virtbase + I2C_CR);
+	writel(readl(priv->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
+	       priv->virtbase + I2C_CR);
 
 	/* enable the controller */
-	i2c_set_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
+	i2c_set_bit(priv->virtbase + I2C_CR, I2C_CR_PE);
 
-	init_completion(&dev->xfer_complete);
+	init_completion(&priv->xfer_complete);
 
 	/* enable interrupts by settings the masks */
 	irq_mask = (I2C_IT_TXFOVR | I2C_IT_MAL | I2C_IT_BERR);
 
 	/* Fill the TX FIFO with transmit data */
-	fill_tx_fifo(dev, MAX_I2C_FIFO_THRESHOLD);
+	fill_tx_fifo(priv, MAX_I2C_FIFO_THRESHOLD);
 
-	if (dev->cli.count != 0)
+	if (priv->cli.count != 0)
 		irq_mask |= I2C_IT_TXFNE;
 
 	/*
@@ -543,23 +542,23 @@ static int write_i2c(struct nmk_i2c_dev *dev, u16 flags)
 	 * set the MTDWS bit (Master Transaction Done Without Stop)
 	 * to start repeated start operation
 	 */
-	if (dev->stop || !dev->vendor->has_mtdws)
+	if (priv->stop || !priv->vendor->has_mtdws)
 		irq_mask |= I2C_IT_MTD;
 	else
 		irq_mask |= I2C_IT_MTDWS;
 
 	irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
 
-	writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
-			dev->virtbase + I2C_IMSCR);
+	writel(readl(priv->virtbase + I2C_IMSCR) | irq_mask,
+	       priv->virtbase + I2C_IMSCR);
 
 	timeout = wait_for_completion_timeout(
-		&dev->xfer_complete, dev->adap.timeout);
+		&priv->xfer_complete, priv->adap.timeout);
 
 	if (timeout == 0) {
 		/* Controller timed out */
-		dev_err(&dev->adev->dev, "write to slave 0x%x timed out\n",
-				dev->cli.slave_adr);
+		dev_err(&priv->adev->dev, "write to slave 0x%x timed out\n",
+			priv->cli.slave_adr);
 		status = -ETIMEDOUT;
 	}
 
@@ -568,28 +567,28 @@ static int write_i2c(struct nmk_i2c_dev *dev, u16 flags)
 
 /**
  * nmk_i2c_xfer_one() - transmit a single I2C message
- * @dev: device with a message encoded into it
+ * @priv: device with a message encoded into it
  * @flags: message flags
  */
-static int nmk_i2c_xfer_one(struct nmk_i2c_dev *dev, u16 flags)
+static int nmk_i2c_xfer_one(struct nmk_i2c_dev *priv, u16 flags)
 {
 	int status;
 
 	if (flags & I2C_M_RD) {
 		/* read operation */
-		dev->cli.operation = I2C_READ;
-		status = read_i2c(dev, flags);
+		priv->cli.operation = I2C_READ;
+		status = read_i2c(priv, flags);
 	} else {
 		/* write operation */
-		dev->cli.operation = I2C_WRITE;
-		status = write_i2c(dev, flags);
+		priv->cli.operation = I2C_WRITE;
+		status = write_i2c(priv, flags);
 	}
 
-	if (status || (dev->result)) {
+	if (status || priv->result) {
 		u32 i2c_sr;
 		u32 cause;
 
-		i2c_sr = readl(dev->virtbase + I2C_SR);
+		i2c_sr = readl(priv->virtbase + I2C_SR);
 		/*
 		 * Check if the controller I2C operation status
 		 * is set to ABORT(11b).
@@ -597,15 +596,15 @@ static int nmk_i2c_xfer_one(struct nmk_i2c_dev *dev, u16 flags)
 		if (((i2c_sr >> 2) & 0x3) == 0x3) {
 			/* get the abort cause */
 			cause =	(i2c_sr >> 4) & 0x7;
-			dev_err(&dev->adev->dev, "%s\n",
+			dev_err(&priv->adev->dev, "%s\n",
 				cause >= ARRAY_SIZE(abort_causes) ?
 				"unknown reason" :
 				abort_causes[cause]);
 		}
 
-		(void) init_hw(dev);
+		init_hw(priv);
 
-		status = status ? status : dev->result;
+		status = status ? status : priv->result;
 	}
 
 	return status;
@@ -663,24 +662,24 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 {
 	int status = 0;
 	int i;
-	struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
+	struct nmk_i2c_dev *priv = i2c_get_adapdata(i2c_adap);
 	int j;
 
-	pm_runtime_get_sync(&dev->adev->dev);
+	pm_runtime_get_sync(&priv->adev->dev);
 
 	/* Attempt three times to send the message queue */
 	for (j = 0; j < 3; j++) {
 		/* setup the i2c controller */
-		setup_i2c_controller(dev);
+		setup_i2c_controller(priv);
 
 		for (i = 0; i < num_msgs; i++) {
-			dev->cli.slave_adr	= msgs[i].addr;
-			dev->cli.buffer		= msgs[i].buf;
-			dev->cli.count		= msgs[i].len;
-			dev->stop = (i < (num_msgs - 1)) ? 0 : 1;
-			dev->result = 0;
+			priv->cli.slave_adr	= msgs[i].addr;
+			priv->cli.buffer		= msgs[i].buf;
+			priv->cli.count		= msgs[i].len;
+			priv->stop = (i < (num_msgs - 1)) ? 0 : 1;
+			priv->result = 0;
 
-			status = nmk_i2c_xfer_one(dev, msgs[i].flags);
+			status = nmk_i2c_xfer_one(priv, msgs[i].flags);
 			if (status != 0)
 				break;
 		}
@@ -688,7 +687,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 			break;
 	}
 
-	pm_runtime_put_sync(&dev->adev->dev);
+	pm_runtime_put_sync(&priv->adev->dev);
 
 	/* return the no. messages processed */
 	if (status)
@@ -699,14 +698,14 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 
 /**
  * disable_interrupts() - disable the interrupts
- * @dev: private data of controller
+ * @priv: private data of controller
  * @irq: interrupt number
  */
-static int disable_interrupts(struct nmk_i2c_dev *dev, u32 irq)
+static int disable_interrupts(struct nmk_i2c_dev *priv, u32 irq)
 {
 	irq = IRQ_MASK(irq);
-	writel(readl(dev->virtbase + I2C_IMSCR) & ~(I2C_CLEAR_ALL_INTS & irq),
-			dev->virtbase + I2C_IMSCR);
+	writel(readl(priv->virtbase + I2C_IMSCR) & ~(I2C_CLEAR_ALL_INTS & irq),
+	       priv->virtbase + I2C_IMSCR);
 	return 0;
 }
 
@@ -723,17 +722,18 @@ static int disable_interrupts(struct nmk_i2c_dev *dev, u32 irq)
  */
 static irqreturn_t i2c_irq_handler(int irq, void *arg)
 {
-	struct nmk_i2c_dev *dev = arg;
+	struct nmk_i2c_dev *priv = arg;
+	struct device *dev = &priv->adev->dev;
 	u32 tft, rft;
 	u32 count;
 	u32 misr, src;
 
 	/* load Tx FIFO and Rx FIFO threshold values */
-	tft = readl(dev->virtbase + I2C_TFTR);
-	rft = readl(dev->virtbase + I2C_RFTR);
+	tft = readl(priv->virtbase + I2C_TFTR);
+	rft = readl(priv->virtbase + I2C_RFTR);
 
 	/* read interrupt status register */
-	misr = readl(dev->virtbase + I2C_MISR);
+	misr = readl(priv->virtbase + I2C_MISR);
 
 	src = __ffs(misr);
 	switch ((1 << src)) {
@@ -741,20 +741,20 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 	/* Transmit FIFO nearly empty interrupt */
 	case I2C_IT_TXFNE:
 	{
-		if (dev->cli.operation == I2C_READ) {
+		if (priv->cli.operation == I2C_READ) {
 			/*
 			 * in read operation why do we care for writing?
 			 * so disable the Transmit FIFO interrupt
 			 */
-			disable_interrupts(dev, I2C_IT_TXFNE);
+			disable_interrupts(priv, I2C_IT_TXFNE);
 		} else {
-			fill_tx_fifo(dev, (MAX_I2C_FIFO_THRESHOLD - tft));
+			fill_tx_fifo(priv, (MAX_I2C_FIFO_THRESHOLD - tft));
 			/*
 			 * if done, close the transfer by disabling the
 			 * corresponding TXFNE interrupt
 			 */
-			if (dev->cli.count == 0)
-				disable_interrupts(dev,	I2C_IT_TXFNE);
+			if (priv->cli.count == 0)
+				disable_interrupts(priv,	I2C_IT_TXFNE);
 		}
 	}
 	break;
@@ -768,60 +768,59 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 	case I2C_IT_RXFNF:
 		for (count = rft; count > 0; count--) {
 			/* Read the Rx FIFO */
-			*dev->cli.buffer = readb(dev->virtbase + I2C_RFR);
-			dev->cli.buffer++;
+			*priv->cli.buffer = readb(priv->virtbase + I2C_RFR);
+			priv->cli.buffer++;
 		}
-		dev->cli.count -= rft;
-		dev->cli.xfer_bytes += rft;
+		priv->cli.count -= rft;
+		priv->cli.xfer_bytes += rft;
 		break;
 
 	/* Rx FIFO full */
 	case I2C_IT_RXFF:
 		for (count = MAX_I2C_FIFO_THRESHOLD; count > 0; count--) {
-			*dev->cli.buffer = readb(dev->virtbase + I2C_RFR);
-			dev->cli.buffer++;
+			*priv->cli.buffer = readb(priv->virtbase + I2C_RFR);
+			priv->cli.buffer++;
 		}
-		dev->cli.count -= MAX_I2C_FIFO_THRESHOLD;
-		dev->cli.xfer_bytes += MAX_I2C_FIFO_THRESHOLD;
+		priv->cli.count -= MAX_I2C_FIFO_THRESHOLD;
+		priv->cli.xfer_bytes += MAX_I2C_FIFO_THRESHOLD;
 		break;
 
 	/* Master Transaction Done with/without stop */
 	case I2C_IT_MTD:
 	case I2C_IT_MTDWS:
-		if (dev->cli.operation == I2C_READ) {
-			while (!(readl(dev->virtbase + I2C_RISR)
+		if (priv->cli.operation == I2C_READ) {
+			while (!(readl(priv->virtbase + I2C_RISR)
 				 & I2C_IT_RXFE)) {
-				if (dev->cli.count == 0)
+				if (priv->cli.count == 0)
 					break;
-				*dev->cli.buffer =
-					readb(dev->virtbase + I2C_RFR);
-				dev->cli.buffer++;
-				dev->cli.count--;
-				dev->cli.xfer_bytes++;
+				*priv->cli.buffer =
+					readb(priv->virtbase + I2C_RFR);
+				priv->cli.buffer++;
+				priv->cli.count--;
+				priv->cli.xfer_bytes++;
 			}
 		}
 
-		disable_all_interrupts(dev);
-		clear_all_interrupts(dev);
+		disable_all_interrupts(priv);
+		clear_all_interrupts(priv);
 
-		if (dev->cli.count) {
-			dev->result = -EIO;
-			dev_err(&dev->adev->dev,
-				"%lu bytes still remain to be xfered\n",
-				dev->cli.count);
-			(void) init_hw(dev);
+		if (priv->cli.count) {
+			priv->result = -EIO;
+			dev_err(dev, "%lu bytes still remain to be xfered\n",
+				priv->cli.count);
+			init_hw(priv);
 		}
-		complete(&dev->xfer_complete);
+		complete(&priv->xfer_complete);
 
 		break;
 
 	/* Master Arbitration lost interrupt */
 	case I2C_IT_MAL:
-		dev->result = -EIO;
-		(void) init_hw(dev);
+		priv->result = -EIO;
+		init_hw(priv);
 
-		i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MAL);
-		complete(&dev->xfer_complete);
+		i2c_set_bit(priv->virtbase + I2C_ICR, I2C_IT_MAL);
+		complete(&priv->xfer_complete);
 
 		break;
 
@@ -831,13 +830,13 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 	 * during the transaction.
 	 */
 	case I2C_IT_BERR:
-		dev->result = -EIO;
+		priv->result = -EIO;
 		/* get the status */
-		if (((readl(dev->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT)
-			(void) init_hw(dev);
+		if (((readl(priv->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT)
+			init_hw(priv);
 
-		i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_BERR);
-		complete(&dev->xfer_complete);
+		i2c_set_bit(priv->virtbase + I2C_ICR, I2C_IT_BERR);
+		complete(&priv->xfer_complete);
 
 		break;
 
@@ -847,11 +846,11 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 	 * the Tx FIFO is full.
 	 */
 	case I2C_IT_TXFOVR:
-		dev->result = -EIO;
-		(void) init_hw(dev);
+		priv->result = -EIO;
+		init_hw(priv);
 
-		dev_err(&dev->adev->dev, "Tx Fifo Over run\n");
-		complete(&dev->xfer_complete);
+		dev_err(dev, "Tx Fifo Over run\n");
+		complete(&priv->xfer_complete);
 
 		break;
 
@@ -863,10 +862,10 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 	case I2C_IT_RFSE:
 	case I2C_IT_WTSR:
 	case I2C_IT_STD:
-		dev_err(&dev->adev->dev, "unhandled Interrupt\n");
+		dev_err(dev, "unhandled Interrupt\n");
 		break;
 	default:
-		dev_err(&dev->adev->dev, "spurious Interrupt..\n");
+		dev_err(dev, "spurious Interrupt..\n");
 		break;
 	}
 
@@ -893,9 +892,9 @@ static int nmk_i2c_resume_early(struct device *dev)
 static int nmk_i2c_runtime_suspend(struct device *dev)
 {
 	struct amba_device *adev = to_amba_device(dev);
-	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
+	struct nmk_i2c_dev *priv = amba_get_drvdata(adev);
 
-	clk_disable_unprepare(nmk_i2c->clk);
+	clk_disable_unprepare(priv->clk);
 	pinctrl_pm_select_idle_state(dev);
 	return 0;
 }
@@ -903,10 +902,10 @@ static int nmk_i2c_runtime_suspend(struct device *dev)
 static int nmk_i2c_runtime_resume(struct device *dev)
 {
 	struct amba_device *adev = to_amba_device(dev);
-	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
+	struct nmk_i2c_dev *priv = amba_get_drvdata(adev);
 	int ret;
 
-	ret = clk_prepare_enable(nmk_i2c->clk);
+	ret = clk_prepare_enable(priv->clk);
 	if (ret) {
 		dev_err(dev, "can't prepare_enable clock\n");
 		return ret;
@@ -914,9 +913,9 @@ static int nmk_i2c_runtime_resume(struct device *dev)
 
 	pinctrl_pm_select_default_state(dev);
 
-	ret = init_hw(nmk_i2c);
+	ret = init_hw(priv);
 	if (ret) {
-		clk_disable_unprepare(nmk_i2c->clk);
+		clk_disable_unprepare(priv->clk);
 		pinctrl_pm_select_idle_state(dev);
 	}
 
@@ -939,107 +938,108 @@ static const struct i2c_algorithm nmk_i2c_algo = {
 };
 
 static void nmk_i2c_of_probe(struct device_node *np,
-			     struct nmk_i2c_dev *nmk)
+			     struct nmk_i2c_dev *priv)
 {
 	/* Default to 100 kHz if no frequency is given in the node */
-	if (of_property_read_u32(np, "clock-frequency", &nmk->clk_freq))
-		nmk->clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
+	if (of_property_read_u32(np, "clock-frequency", &priv->clk_freq))
+		priv->clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
 
 	/* This driver only supports 'standard' and 'fast' modes of operation. */
-	if (nmk->clk_freq <= I2C_MAX_STANDARD_MODE_FREQ)
-		nmk->sm = I2C_FREQ_MODE_STANDARD;
+	if (priv->clk_freq <= I2C_MAX_STANDARD_MODE_FREQ)
+		priv->sm = I2C_FREQ_MODE_STANDARD;
 	else
-		nmk->sm = I2C_FREQ_MODE_FAST;
-	nmk->tft = 1; /* Tx FIFO threshold */
-	nmk->rft = 8; /* Rx FIFO threshold */
-	nmk->timeout = 200; /* Slave response timeout(ms) */
+		priv->sm = I2C_FREQ_MODE_FAST;
+	priv->tft = 1; /* Tx FIFO threshold */
+	priv->rft = 8; /* Rx FIFO threshold */
+	priv->timeout = 200; /* Slave response timeout(ms) */
 }
 
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret = 0;
+	struct nmk_i2c_dev *priv;
 	struct device_node *np = adev->dev.of_node;
-	struct nmk_i2c_dev	*dev;
+	struct device *dev = &adev->dev;
 	struct i2c_adapter *adap;
 	struct i2c_vendor_data *vendor = id->data;
 	u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1;
 
-	dev = devm_kzalloc(&adev->dev, sizeof(*dev), GFP_KERNEL);
-	if (!dev)
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
 		return -ENOMEM;
 
-	dev->vendor = vendor;
-	dev->adev = adev;
-	nmk_i2c_of_probe(np, dev);
+	priv->vendor = vendor;
+	priv->adev = adev;
+	nmk_i2c_of_probe(np, priv);
 
-	if (dev->tft > max_fifo_threshold) {
-		dev_warn(&adev->dev, "requested TX FIFO threshold %u, adjusted down to %u\n",
-			 dev->tft, max_fifo_threshold);
-		dev->tft = max_fifo_threshold;
+	if (priv->tft > max_fifo_threshold) {
+		dev_warn(dev, "requested TX FIFO threshold %u, adjusted down to %u\n",
+			 priv->tft, max_fifo_threshold);
+		priv->tft = max_fifo_threshold;
 	}
 
-	if (dev->rft > max_fifo_threshold) {
-		dev_warn(&adev->dev, "requested RX FIFO threshold %u, adjusted down to %u\n",
-			dev->rft, max_fifo_threshold);
-		dev->rft = max_fifo_threshold;
+	if (priv->rft > max_fifo_threshold) {
+		dev_warn(dev, "requested RX FIFO threshold %u, adjusted down to %u\n",
+			 priv->rft, max_fifo_threshold);
+		priv->rft = max_fifo_threshold;
 	}
 
-	amba_set_drvdata(adev, dev);
+	amba_set_drvdata(adev, priv);
 
-	dev->virtbase = devm_ioremap(&adev->dev, adev->res.start,
-				resource_size(&adev->res));
-	if (!dev->virtbase)
+	priv->virtbase = devm_ioremap(dev, adev->res.start,
+				      resource_size(&adev->res));
+	if (!priv->virtbase)
 		return -ENOMEM;
 
-	dev->irq = adev->irq[0];
-	ret = devm_request_irq(&adev->dev, dev->irq, i2c_irq_handler, 0,
-				DRIVER_NAME, dev);
+	priv->irq = adev->irq[0];
+	ret = devm_request_irq(dev, priv->irq, i2c_irq_handler, 0,
+			       DRIVER_NAME, priv);
 	if (ret)
-		return dev_err_probe(&adev->dev, ret,
-				     "cannot claim the irq %d\n", dev->irq);
+		return dev_err_probe(dev, ret,
+				     "cannot claim the irq %d\n", priv->irq);
 
-	dev->clk = devm_clk_get_enabled(&adev->dev, NULL);
-	if (IS_ERR(dev->clk))
-		return dev_err_probe(&adev->dev, PTR_ERR(dev->clk),
+	priv->clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(priv->clk))
+		return dev_err_probe(dev, PTR_ERR(priv->clk),
 				     "could enable i2c clock\n");
 
-	init_hw(dev);
+	init_hw(priv);
 
-	adap = &dev->adap;
+	adap = &priv->adap;
 	adap->dev.of_node = np;
-	adap->dev.parent = &adev->dev;
+	adap->dev.parent = dev;
 	adap->owner = THIS_MODULE;
 	adap->class = I2C_CLASS_DEPRECATED;
 	adap->algo = &nmk_i2c_algo;
-	adap->timeout = msecs_to_jiffies(dev->timeout);
+	adap->timeout = msecs_to_jiffies(priv->timeout);
 	snprintf(adap->name, sizeof(adap->name),
 		 "Nomadik I2C at %pR", &adev->res);
 
-	i2c_set_adapdata(adap, dev);
+	i2c_set_adapdata(adap, priv);
 
-	dev_info(&adev->dev,
+	dev_info(dev,
 		 "initialize %s on virtual base %p\n",
-		 adap->name, dev->virtbase);
+		 adap->name, priv->virtbase);
 
 	ret = i2c_add_adapter(adap);
 	if (ret)
 		return ret;
 
-	pm_runtime_put(&adev->dev);
+	pm_runtime_put(dev);
 
 	return 0;
 }
 
 static void nmk_i2c_remove(struct amba_device *adev)
 {
-	struct nmk_i2c_dev *dev = amba_get_drvdata(adev);
+	struct nmk_i2c_dev *priv = amba_get_drvdata(adev);
 
-	i2c_del_adapter(&dev->adap);
-	flush_i2c_fifo(dev);
-	disable_all_interrupts(dev);
-	clear_all_interrupts(dev);
+	i2c_del_adapter(&priv->adap);
+	flush_i2c_fifo(priv);
+	disable_all_interrupts(priv);
+	clear_all_interrupts(priv);
 	/* disable the controller */
-	i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
+	i2c_clr_bit(priv->virtbase + I2C_CR, I2C_CR_PE);
 }
 
 static struct i2c_vendor_data vendor_stn8815 = {

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:20 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:20 +0100
Subject: [PATCH 13/13] MIPS: mobileye: eyeq5: add resets to I2C controllers
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-13-19a336e91dca@bootlin.com>

Add resets properties to each I2C controller. This depends on the
reset-eyeq5 platform reset controller driver.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 arch/mips/boot/dts/mobileye/eyeq5.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
index d27e164f0fc1..c0842836fcc8 100644
--- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi
+++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
@@ -80,6 +80,7 @@ i2c0: i2c at 300000 {
 			#size-cells = <0>;
 			clocks = <&i2c_ser_clk>, <&i2c_clk>;
 			clock-names = "i2cclk", "apb_pclk";
+			resets = <&reset 0 13>;
 			mobileye,olb = <&olb>;
 			mobileye,id = <0>;
 		};
@@ -94,6 +95,7 @@ i2c1: i2c at 400000 {
 			#size-cells = <0>;
 			clocks = <&i2c_ser_clk>, <&i2c_clk>;
 			clock-names = "i2cclk", "apb_pclk";
+			resets = <&reset 0 14>;
 			mobileye,olb = <&olb>;
 			mobileye,id = <1>;
 		};
@@ -108,6 +110,7 @@ i2c2: i2c at 500000 {
 			#size-cells = <0>;
 			clocks = <&i2c_ser_clk>, <&i2c_clk>;
 			clock-names = "i2cclk", "apb_pclk";
+			resets = <&reset 0 15>;
 			mobileye,olb = <&olb>;
 			mobileye,id = <2>;
 		};
@@ -122,6 +125,7 @@ i2c3: i2c at 600000 {
 			#size-cells = <0>;
 			clocks = <&i2c_ser_clk>, <&i2c_clk>;
 			clock-names = "i2cclk", "apb_pclk";
+			resets = <&reset 0 16>;
 			mobileye,olb = <&olb>;
 			mobileye,id = <3>;
 		};
@@ -136,6 +140,7 @@ i2c4: i2c at 700000 {
 			#size-cells = <0>;
 			clocks = <&i2c_ser_clk>, <&i2c_clk>;
 			clock-names = "i2cclk", "apb_pclk";
+			resets = <&reset 0 17>;
 			mobileye,olb = <&olb>;
 			mobileye,id = <4>;
 		};

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:19 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:19 +0100
Subject: [PATCH 12/13] MIPS: mobileye: eyeq5: add evaluation board I2C temp
 sensor
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-12-19a336e91dca@bootlin.com>

Declare the temperature sensor on I2C bus 2. Its label is the schematics
identifier.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 arch/mips/boot/dts/mobileye/eyeq5-epm5.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts b/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
index 6898b2d8267d..1f8549acd40d 100644
--- a/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
+++ b/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
@@ -21,3 +21,11 @@ memory at 0 {
 		      <0x8 0x02000000 0x0 0x7E000000>;
 	};
 };
+
+&i2c2 {
+	tmp112 at 48 {
+		compatible = "ti,tmp112";
+		reg = <0x48>;
+		label = "U60";
+	};
+};

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:18 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:18 +0100
Subject: [PATCH 11/13] MIPS: mobileye: eyeq5: add 5 I2C controller nodes
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-11-19a336e91dca@bootlin.com>

Add the SoC I2C controller nodes to the platform devicetree. Use a
default bus frequency of 400kHz. They are AMBA devices that are matched
on PeriphID.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 arch/mips/boot/dts/mobileye/eyeq5.dtsi | 70 ++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
index 8d4f65ec912d..d27e164f0fc1 100644
--- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi
+++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
@@ -70,6 +70,76 @@ soc: soc {
 		ranges;
 		compatible = "simple-bus";
 
+		i2c0: i2c at 300000 {
+			compatible = "mobileye,eyeq5-i2c", "arm,primecell";
+			reg = <0 0x300000 0x0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 1 IRQ_TYPE_LEVEL_HIGH>;
+			clock-frequency = <400000>; /* Fast mode */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&i2c_ser_clk>, <&i2c_clk>;
+			clock-names = "i2cclk", "apb_pclk";
+			mobileye,olb = <&olb>;
+			mobileye,id = <0>;
+		};
+
+		i2c1: i2c at 400000 {
+			compatible = "mobileye,eyeq5-i2c", "arm,primecell";
+			reg = <0 0x400000 0x0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 2 IRQ_TYPE_LEVEL_HIGH>;
+			clock-frequency = <400000>; /* Fast mode */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&i2c_ser_clk>, <&i2c_clk>;
+			clock-names = "i2cclk", "apb_pclk";
+			mobileye,olb = <&olb>;
+			mobileye,id = <1>;
+		};
+
+		i2c2: i2c at 500000 {
+			compatible = "mobileye,eyeq5-i2c", "arm,primecell";
+			reg = <0 0x500000 0x0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>;
+			clock-frequency = <400000>; /* Fast mode */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&i2c_ser_clk>, <&i2c_clk>;
+			clock-names = "i2cclk", "apb_pclk";
+			mobileye,olb = <&olb>;
+			mobileye,id = <2>;
+		};
+
+		i2c3: i2c at 600000 {
+			compatible = "mobileye,eyeq5-i2c", "arm,primecell";
+			reg = <0 0x600000 0x0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>;
+			clock-frequency = <400000>; /* Fast mode */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&i2c_ser_clk>, <&i2c_clk>;
+			clock-names = "i2cclk", "apb_pclk";
+			mobileye,olb = <&olb>;
+			mobileye,id = <3>;
+		};
+
+		i2c4: i2c at 700000 {
+			compatible = "mobileye,eyeq5-i2c", "arm,primecell";
+			reg = <0 0x700000 0x0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 5 IRQ_TYPE_LEVEL_HIGH>;
+			clock-frequency = <400000>; /* Fast mode */
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&i2c_ser_clk>, <&i2c_clk>;
+			clock-names = "i2cclk", "apb_pclk";
+			mobileye,olb = <&olb>;
+			mobileye,id = <4>;
+		};
+
 		uart0: serial at 800000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0 0x800000 0x0 0x1000>;

-- 
2.43.1



From theo.lebrun at bootlin.com  Thu Feb 15 08:52:17 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 15 Feb 2024 17:52:17 +0100
Subject: [PATCH 10/13] i2c: nomadik: support Mobileye EyeQ5 I2C controller
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <20240215-mbly-i2c-v1-10-19a336e91dca@bootlin.com>

Add compatible for the integration of the same DB8500 IP block into the
Mobileye EyeQ5 platform. Two quirks are present:

 - The memory bus only supports 32-bit accesses. One writeb() is done to
   fill the Tx FIFO which we replace with a writel().

 - A register must be configured for the I2C speed mode; it is located
   in a shared register region called OLB. We access that memory region
   using a syscon & regmap that gets passed as a phandle (mobileye,olb).

   A two-bit enum per controller is written into the register; that
   requires us to know the global index of the I2C
   controller (mobileye,id).

We add #include <linux/mfd/syscon.h> and <linux/regmap.h> and sort
headers.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/i2c/busses/i2c-nomadik.c | 79 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 71 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 23e12c570457..eb076419dfa8 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -6,22 +6,30 @@
  * I2C master mode controller driver, used in Nomadik 8815
  * and Ux500 platforms.
  *
+ * The Mobileye EyeQ5 platform is also supported; it uses
+ * the same Ux500/DB8500 IP block with two quirks:
+ *  - The memory bus only supports 32-bit accesses.
+ *  - A register must be configured for the I2C speed mode;
+ *    it is located in a shared register region called OLB.
+ *
  * Author: Srinidhi Kasagar <srinidhi.kasagar at stericsson.com>
  * Author: Sachin Verma <sachin.verma at st.com>
  */
+#include <linux/amba/bus.h>
 #include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
 #include <linux/init.h>
-#include <linux/module.h>
-#include <linux/amba/bus.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/pm_runtime.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pinctrl/consumer.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "nmk-i2c"
 
@@ -110,6 +118,10 @@ enum i2c_freq_mode {
 	I2C_FREQ_MODE_FAST_PLUS,	/* up to 1 Mb/s */
 };
 
+/* Mobileye EyeQ5 offset into a shared register region (called OLB) */
+#define NMK_I2C_EYEQ5_OLB_IOCR2			0x0B8
+#define NMK_I2C_EYEQ5_OLB_IOCR2_SHIFT(id)	(4 + 2 * (id))
+
 /**
  * struct i2c_vendor_data - per-vendor variations
  * @has_mtdws: variant has the MTDWS bit
@@ -168,6 +180,7 @@ struct i2c_nmk_client {
  * @xfer_wq: xfer done wait queue.
  * @xfer_done: xfer done boolean.
  * @result: controller propogated result.
+ * @has_32b_bus: controller is on a bus that only supports 32-bit accesses.
  */
 struct nmk_i2c_dev {
 	struct i2c_vendor_data		*vendor;
@@ -186,6 +199,7 @@ struct nmk_i2c_dev {
 	struct wait_queue_head		xfer_wq;
 	bool				xfer_done;
 	int				result;
+	bool				has_32b_bus;
 };
 
 /* controller's abort causes */
@@ -514,7 +528,10 @@ static void fill_tx_fifo(struct nmk_i2c_dev *priv, int no_bytes)
 			(priv->cli.count != 0);
 			count--) {
 		/* write to the Tx FIFO */
-		writeb(*priv->cli.buffer, priv->virtbase + I2C_TFR);
+		if (priv->has_32b_bus)
+			writel(*priv->cli.buffer, priv->virtbase + I2C_TFR);
+		else
+			writeb(*priv->cli.buffer, priv->virtbase + I2C_TFR);
 		priv->cli.buffer++;
 		priv->cli.count--;
 		priv->cli.xfer_bytes++;
@@ -985,6 +1002,43 @@ static void nmk_i2c_of_probe(struct device_node *np,
 		priv->timeout_usecs = 200 * USEC_PER_MSEC;
 }
 
+static int nmk_i2c_eyeq5_probe(struct nmk_i2c_dev *priv)
+{
+	struct device *dev = &priv->adev->dev;
+	struct device_node *np = dev->of_node;
+	unsigned int shift, speed_mode;
+	struct regmap *olb;
+	int ret;
+	u32 id;
+
+	priv->has_32b_bus = true;
+
+	olb = syscon_regmap_lookup_by_phandle(np, "mobileye,olb");
+	if (IS_ERR_OR_NULL(olb)) {
+		if (!olb)
+			olb = ERR_PTR(-ENOENT);
+		return dev_err_probe(dev, PTR_ERR(olb),
+				     "failed OLB lookup: %lu\n", PTR_ERR(olb));
+	}
+
+	ret = of_property_read_u32(np, "mobileye,id", &id);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed ID lookup: %d\n", ret);
+
+	if (priv->clk_freq <= 400000)
+		speed_mode = 0b00;
+	else if (priv->clk_freq <= 1000000)
+		speed_mode = 0b01;
+	else
+		speed_mode = 0b10;
+
+	shift = NMK_I2C_EYEQ5_OLB_IOCR2_SHIFT(id);
+	regmap_update_bits(olb, NMK_I2C_EYEQ5_OLB_IOCR2,
+			   0b11 << shift, speed_mode << shift);
+
+	return 0;
+}
+
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret = 0;
@@ -1001,8 +1055,17 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 
 	priv->vendor = vendor;
 	priv->adev = adev;
+	priv->has_32b_bus = false;
 	nmk_i2c_of_probe(np, priv);
 
+	if (of_device_is_compatible(np, "mobileye,eyeq5-i2c")) {
+		ret = nmk_i2c_eyeq5_probe(priv);
+		if (ret) {
+			dev_info(dev, "%s: %d: %d\n", __func__, __LINE__, ret);
+			return ret;
+		}
+	}
+
 	if (priv->tft > max_fifo_threshold) {
 		dev_warn(dev, "requested TX FIFO threshold %u, adjusted down to %u\n",
 			 priv->tft, max_fifo_threshold);

-- 
2.43.1



From a0501179 at ti.com  Thu Feb 15 08:56:59 2024
From: a0501179 at ti.com (Anwar, Md Danish)
Date: Thu, 15 Feb 2024 22:26:59 +0530
Subject: [PATCH] arm64: dts: ti: k3-am654: Drop ti,syscon-rgmii-delay from
 ICSSG nodes
In-Reply-To: <71adaabd-bb24-4181-9fdf-f7191e93edb5@kernel.org>
References: <20240215105407.2868266-1-danishanwar@ti.com>
 <71adaabd-bb24-4181-9fdf-f7191e93edb5@kernel.org>
Message-ID: <4ef87f6c-caa8-45a8-8649-422806ec6eb2@ti.com>



On 2/15/2024 9:27 PM, Roger Quadros wrote:
> 
> 
> On 15/02/2024 12:54, MD Danish Anwar wrote:
>> Drop ti,syscon-rgmii-delay from ICSSG0, ICSSG1 and ICSSG2 node as this
>> property is no longer used by ICSSG driver.
>>
>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>> ---
>>  arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso | 2 --
>>  arch/arm64/boot/dts/ti/k3-am654-idk.dtso    | 4 ----
>>  2 files changed, 6 deletions(-)
> 
> What about the DT binding document?
> 

Now I am only removing the property from device tree. Once this proprty
is removed from all DTs, in the 6.9-rc-1 I will remove the binding as
well so that net people can merge that without getting any errors /
warnings.

-- 
Thanks and Regards,
Md Danish Anwar


From conor at kernel.org  Thu Feb 15 09:00:29 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 15 Feb 2024 17:00:29 +0000
Subject: [PATCH v2 1/6] dt-bindings: display/msm/gmu: Document Adreno 750
 GMU
In-Reply-To: <20240215-topic-sm8650-gpu-v2-1-6be0b4bf2e09@linaro.org>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
 <20240215-topic-sm8650-gpu-v2-1-6be0b4bf2e09@linaro.org>
Message-ID: <20240215-trout-written-9ba8c929f9a5@spud>

On Thu, Feb 15, 2024 at 10:20:23AM +0100, Neil Armstrong wrote:
> Document the Adreno 750 GMU found on the SM8650 platform.
> 
> Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
>  Documentation/devicetree/bindings/display/msm/gmu.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml b/Documentation/devicetree/bindings/display/msm/gmu.yaml
> index 4e1c25b42908..b3837368a260 100644
> --- a/Documentation/devicetree/bindings/display/msm/gmu.yaml
> +++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml
> @@ -224,6 +224,7 @@ allOf:
>              enum:
>                - qcom,adreno-gmu-730.1
>                - qcom,adreno-gmu-740.1
> +              - qcom,adreno-gmu-750.1
>      then:
>        properties:
>          reg:
> 
> -- 
> 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/20240215/ddd8bd09/attachment-0001.sig>

From conor at kernel.org  Thu Feb 15 09:03:04 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 15 Feb 2024 17:03:04 +0000
Subject: [PATCH v3 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <20240215091524.14732-3-mihai.sain@microchip.com>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
 <20240215091524.14732-3-mihai.sain@microchip.com>
Message-ID: <20240215-lustily-flick-69cb48b123c3@spud>

On Thu, Feb 15, 2024 at 11:15:23AM +0200, Mihai Sain wrote:
> Add flexcom 10 node for usage on the SAMA7G54 Curiosity board.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/sama7g5.dtsi | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> index 269e0a3ca269..c030b318985a 100644
> --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
> +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> @@ -958,6 +958,30 @@ i2c9: i2c at 600 {
>  			};
>  		};
>  
> +		flx10: flexcom at e2820000 {
> +			compatible = "atmel,sama5d2-flexcom";

My comment here was ignored:
https://lore.kernel.org/all/20240214-robe-pregnancy-a1b056c9fe14 at spud/

> +			reg = <0xe2820000 0x200>;
> +			clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0x0 0xe2820000 0x800>;
> +			status = "disabled";
> +
> +			i2c10: i2c at 600 {
> +				compatible = "microchip,sama7g5-i2c", "microchip,sam9x60-i2c";
> +				reg = <0x600 0x200>;
> +				interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +				clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
> +				atmel,fifo-size = <32>;
> +				dmas = <&dma0 AT91_XDMAC_DT_PERID(26)>,
> +					<&dma0 AT91_XDMAC_DT_PERID(25)>;
> +				dma-names = "tx", "rx";
> +				status = "disabled";
> +			};
> +		};
> +
>  		flx11: flexcom at e2824000 {
>  			compatible = "atmel,sama5d2-flexcom";
>  			reg = <0xe2824000 0x200>;
> -- 
> 2.43.0
> 
-------------- 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/20240215/7508f3eb/attachment.sig>

From helgaas at kernel.org  Thu Feb 15 09:06:05 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 15 Feb 2024 11:06:05 -0600
Subject: [PATCH v3 00/18] Add suspend to ram support for PCIe on J7200
In-Reply-To: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
Message-ID: <20240215170605.GA1294576@bhelgaas>

On Thu, Feb 15, 2024 at 04:17:45PM +0100, Thomas Richard wrote:
> This add suspend to ram support for the PCIe (RC mode) on J7200 platform.

>       PCI: cadence: extract link setup sequence from cdns_pcie_host_setup()
>       PCI: cadence: set cdns_pcie_host_init() global
>       PCI: j721e: add reset GPIO to struct j721e_pcie
>       PCI: j721e: add suspend and resume support

The drivers/pci/ subject line pattern is:

  PCI: <driver>: <Capitalized verb>

e.g.,

  PCI: cadence: Extract link setup sequence from cdns_pcie_host_setup()


From conor at kernel.org  Thu Feb 15 09:12:50 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 15 Feb 2024 17:12:50 +0000
Subject: =?utf-8?B?5Zue6KaG?= =?utf-8?Q?=3A?= [PATCH] Add eSPI device
 driver (flash channel)
In-Reply-To: <TYZPR06MB6640F82C539F0B17BCDCC55E914D2@TYZPR06MB6640.apcprd06.prod.outlook.com>
References: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
 <KL1PR06MB665234A65DB334B3BDF6AFA6914E2@KL1PR06MB6652.apcprd06.prod.outlook.com>
 <20240214-yoyo-platinum-dcd0e7e16a22@spud>
 <TYZPR06MB6640F82C539F0B17BCDCC55E914D2@TYZPR06MB6640.apcprd06.prod.outlook.com>
Message-ID: <20240215-probable-gimmick-83d5dcbc4729@spud>

On Thu, Feb 15, 2024 at 01:56:00AM +0000, ChiaWei Wang wrote:
> > 
> > On Wed, Feb 14, 2024 at 11:34:31AM +0000, ChiaWei Wang wrote:
> > > We appreciate that you are willing to help on the open source contribution.
> > > However, please co-work with Aspeed before submitting drivers of Aspeed
> > HW.
> > > Otherwise, a misleading driver on the community are going to bring tons of
> > customer issues to Aspeed.
> > 
> > It may not apply in this particular case as Aspeed did write the original driver
> > and it is polite to work with previous authors when respinning a patchset, but in
> > general there is no need to work with a hardware vendor before writing drivers
> > for their hardware.
> > 
> > Blocking a driver because that company might receive more support requests
> > is not the kernel's problem.
> 
> I agree with that and Aspeed will not refuse to support.
> 
> However, in this case, the authors, IBM, and Aspeed already have discussion (at least 4 times) before and foresee "issues" on practical eSPI SAFS use.
> If there is already a known issue of the driver, why ignoring the previous discussion and push it?
> A compromise is to ask for driver renaming to espi-mafs to avoid confusion.
> Otherwise we need to explain, again, why the driver does not fulfill the SAFS expectation.

To be clear, in case you misunderstood, I was making a general point and
not about this particular patchset.
-------------- 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/20240215/21edebee/attachment.sig>

From forbidden405 at outlook.com  Thu Feb 15 09:15:32 2024
From: forbidden405 at outlook.com (Yang Xiwen)
Date: Fri, 16 Feb 2024 01:15:32 +0800
Subject: [PATCH] mmc: host: replace 1st argument to struct device * for
 mmc_of_parse_clk_phase()
In-Reply-To: <CAPDyKFo9NpKSuBnrcOseuD-jDA64CMyRxpH-OUoozOQDYHj1mQ@mail.gmail.com>
References: <20240215-mmc_phase-v1-1-f27644ee13e4@outlook.com>
 <CAPDyKFo9NpKSuBnrcOseuD-jDA64CMyRxpH-OUoozOQDYHj1mQ@mail.gmail.com>
Message-ID: <SEZPR06MB6959FF28D99A99BA2524C9D4964D2@SEZPR06MB6959.apcprd06.prod.outlook.com>

On 2/16/2024 12:47 AM, Ulf Hansson wrote:
> On Thu, 15 Feb 2024 at 12:03, Yang Xiwen via B4 Relay
> <devnull+forbidden405.outlook.com at kernel.org> wrote:
>> From: Yang Xiwen <forbidden405 at outlook.com>
>>
>> Parsing dt usaully happens very early, sometimes even bofore struct
>> mmc_host is allocated (e.g. dw_mci_probe() and dw_mci_parse_dt() in
>> dw_mmc.c). Looking at the source of mmc_of_parse_clk_phase(), it's
>> actually not mandatory to have a initialized mmc_host first, instead we
>> can pass struct device * to it directly.
>>
>> Also fix the only current user (sdhci-of-aspeed.c).
> Is there a problem? I don't see it, can please elaborate.

My pleasure.

Just look into dw_mci_parse_dt() in dw_mmc.c, this function calls 
specific extension's .parse_dt() function. And this function is called 
very early even before struct mmc_host is allocated. Thus it'll be 
impossible to retrieve host->slot->dev right now since host->slot is 
still NULL. As a result, We are unable to call mmc_of_parse_clk_phase() 
in our own .parse_dt() because it needs an initialized struct mmc_host. 
But mmc_of_parse_clk_phase is intended to be invoked there since this is 
where the driver is supposed to parse dt. dw_mci_probe() allocates 
struct mmc_host and calls mmc_of_parse() very late(in 
dw_mci_init_slot()) and provides us no chance to insert our own dt 
parsing extensions after that.

The key is that mmc_of_parse_clk_phase() is a very simple function which 
only extracts a few dt props. It is supposed to be called early in the 
driver before struct mmc_host is allocated. Unlike mmc_of_parse() which 
fills in a lot of fields in struct mmc_host, it does not need this struct.

> Kind regards
> Uffe
>
>> Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
>> ---
>>   drivers/mmc/core/host.c            | 4 +---
>>   drivers/mmc/host/sdhci-of-aspeed.c | 2 +-
>>   include/linux/mmc/host.h           | 2 +-
>>   3 files changed, 3 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
>> index cf396e8f34e9..8b2844ac5dc5 100644
>> --- a/drivers/mmc/core/host.c
>> +++ b/drivers/mmc/core/host.c
>> @@ -234,10 +234,8 @@ static void mmc_of_parse_timing_phase(struct device *dev, const char *prop,
>>   }
>>
>>   void
>> -mmc_of_parse_clk_phase(struct mmc_host *host, struct mmc_clk_phase_map *map)
>> +mmc_of_parse_clk_phase(struct device *dev, struct mmc_clk_phase_map *map)
>>   {
>> -       struct device *dev = host->parent;
>> -
>>          mmc_of_parse_timing_phase(dev, "clk-phase-legacy",
>>                                    &map->phase[MMC_TIMING_LEGACY]);
>>          mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs",
>> diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
>> index 42d54532cabe..430c1f90037b 100644
>> --- a/drivers/mmc/host/sdhci-of-aspeed.c
>> +++ b/drivers/mmc/host/sdhci-of-aspeed.c
>> @@ -435,7 +435,7 @@ static int aspeed_sdhci_probe(struct platform_device *pdev)
>>                  goto err_sdhci_add;
>>
>>          if (dev->phase_desc)
>> -               mmc_of_parse_clk_phase(host->mmc, &dev->phase_map);
>> +               mmc_of_parse_clk_phase(&pdev->dev, &dev->phase_map);
>>
>>          ret = sdhci_add_host(host);
>>          if (ret)
>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>> index 2f445c651742..5894bf912f7b 100644
>> --- a/include/linux/mmc/host.h
>> +++ b/include/linux/mmc/host.h
>> @@ -539,7 +539,7 @@ struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra);
>>   int mmc_add_host(struct mmc_host *);
>>   void mmc_remove_host(struct mmc_host *);
>>   void mmc_free_host(struct mmc_host *);
>> -void mmc_of_parse_clk_phase(struct mmc_host *host,
>> +void mmc_of_parse_clk_phase(struct device *dev,
>>                              struct mmc_clk_phase_map *map);
>>   int mmc_of_parse(struct mmc_host *host);
>>   int mmc_of_parse_voltage(struct mmc_host *host, u32 *mask);
>>
>> ---
>> base-commit: 9d64bf433c53cab2f48a3fff7a1f2a696bc5229a
>> change-id: 20240215-mmc_phase-26e85511285d
>>
>> Best regards,
>> --
>> Yang Xiwen <forbidden405 at outlook.com>
>>

-- 
Regards,
Yang Xiwen



From andrew at lunn.ch  Thu Feb 15 09:23:43 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Thu, 15 Feb 2024 18:23:43 +0100
Subject: [PATCH] arm64: dts: ti: k3-am654: Drop ti,syscon-rgmii-delay
 from ICSSG nodes
In-Reply-To: <4ef87f6c-caa8-45a8-8649-422806ec6eb2@ti.com>
References: <20240215105407.2868266-1-danishanwar@ti.com>
 <71adaabd-bb24-4181-9fdf-f7191e93edb5@kernel.org>
 <4ef87f6c-caa8-45a8-8649-422806ec6eb2@ti.com>
Message-ID: <a0dc9fb7-2124-4f0d-a136-fc16a2301b0d@lunn.ch>

On Thu, Feb 15, 2024 at 10:26:59PM +0530, Anwar, Md Danish wrote:
> 
> 
> On 2/15/2024 9:27 PM, Roger Quadros wrote:
> > 
> > 
> > On 15/02/2024 12:54, MD Danish Anwar wrote:
> >> Drop ti,syscon-rgmii-delay from ICSSG0, ICSSG1 and ICSSG2 node as this
> >> property is no longer used by ICSSG driver.
> >>
> >> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
> >> ---
> >>  arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso | 2 --
> >>  arch/arm64/boot/dts/ti/k3-am654-idk.dtso    | 4 ----
> >>  2 files changed, 6 deletions(-)
> > 
> > What about the DT binding document?
> > 
> 
> Now I am only removing the property from device tree. Once this proprty
> is removed from all DTs, in the 6.9-rc-1 I will remove the binding as
> well so that net people can merge that without getting any errors /
> warnings.

Did the binding have the property as mandatory? If so you are probably
doing this the wrong way around. You should first modify the binding
to mark it as optional and deprecated. Then modify the .dts{i} files
to remove it.

   Andrew


From robin.murphy at arm.com  Thu Feb 15 09:27:09 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 15 Feb 2024 17:27:09 +0000
Subject: [PATCH v5 02/17] iommu/arm-smmu-v3: Consolidate the STE
 generation for abort/bypass
In-Reply-To: <2-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
References: <2-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <2ca7f64e-a9e3-4d47-b04f-726c86223fd6@arm.com>

On 06/02/2024 3:12 pm, Jason Gunthorpe wrote:
> This allows writing the flow of arm_smmu_write_strtab_ent() around abort
> and bypass domains more naturally.
> 
> Note that the core code no longer supplies NULL domains, though there is
> still a flow in the driver that end up in arm_smmu_write_strtab_ent() with
> NULL. A later patch will remove it.
> 
> Remove the duplicate calculation of the STE in arm_smmu_init_bypass_stes()
> and remove the force parameter. arm_smmu_rmr_install_bypass_ste() can now
> simply invoke arm_smmu_make_bypass_ste() directly.
> 
> Reviewed-by: Michael Shavit <mshavit at google.com>
> Reviewed-by: Nicolin Chen <nicolinc at nvidia.com>
> Reviewed-by: Mostafa Saleh <smostafa at google.com>
> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Tested-by: Moritz Fischer <moritzf at google.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 97 ++++++++++++---------
>   1 file changed, 55 insertions(+), 42 deletions(-)
> 
> 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 f0b915567cbcdc..6123e5ad95822c 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1498,6 +1498,24 @@ static void arm_smmu_write_ste(struct arm_smmu_master *master, u32 sid,
>   	}
>   }
>   
> +static void arm_smmu_make_abort_ste(struct arm_smmu_ste *target)
> +{
> +	memset(target, 0, sizeof(*target));
> +	target->data[0] = cpu_to_le64(
> +		STRTAB_STE_0_V |
> +		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT));
> +}
> +
> +static void arm_smmu_make_bypass_ste(struct arm_smmu_ste *target)
> +{
> +	memset(target, 0, sizeof(*target));
> +	target->data[0] = cpu_to_le64(
> +		STRTAB_STE_0_V |
> +		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS));
> +	target->data[1] = cpu_to_le64(
> +		FIELD_PREP(STRTAB_STE_1_SHCFG, STRTAB_STE_1_SHCFG_INCOMING));
> +}
> +
>   static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
>   				      struct arm_smmu_ste *dst)
>   {
> @@ -1508,37 +1526,31 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
>   	struct arm_smmu_domain *smmu_domain = master->domain;
>   	struct arm_smmu_ste target = {};
>   
> -	if (smmu_domain) {
> -		switch (smmu_domain->stage) {
> -		case ARM_SMMU_DOMAIN_S1:
> -			cd_table = &master->cd_table;
> -			break;
> -		case ARM_SMMU_DOMAIN_S2:
> -			s2_cfg = &smmu_domain->s2_cfg;
> -			break;
> -		default:
> -			break;
> -		}
> +	if (!smmu_domain) {
> +		if (disable_bypass)
> +			arm_smmu_make_abort_ste(&target);
> +		else
> +			arm_smmu_make_bypass_ste(&target);
> +		arm_smmu_write_ste(master, sid, dst, &target);
> +		return;
> +	}
> +
> +	switch (smmu_domain->stage) {
> +	case ARM_SMMU_DOMAIN_S1:
> +		cd_table = &master->cd_table;
> +		break;
> +	case ARM_SMMU_DOMAIN_S2:
> +		s2_cfg = &smmu_domain->s2_cfg;
> +		break;
> +	case ARM_SMMU_DOMAIN_BYPASS:
> +		arm_smmu_make_bypass_ste(&target);
> +		arm_smmu_write_ste(master, sid, dst, &target);
> +		return;
>   	}
>   
>   	/* Nuke the existing STE_0 value, as we're going to rewrite it */
>   	val = STRTAB_STE_0_V;
>   
> -	/* Bypass/fault */
> -	if (!smmu_domain || !(cd_table || s2_cfg)) {
> -		if (!smmu_domain && disable_bypass)
> -			val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT);
> -		else
> -			val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
> -
> -		target.data[0] = cpu_to_le64(val);
> -		target.data[1] = cpu_to_le64(FIELD_PREP(STRTAB_STE_1_SHCFG,
> -						STRTAB_STE_1_SHCFG_INCOMING));
> -		target.data[2] = 0; /* Nuke the VMID */
> -		arm_smmu_write_ste(master, sid, dst, &target);
> -		return;
> -	}
> -
>   	if (cd_table) {
>   		u64 strw = smmu->features & ARM_SMMU_FEAT_E2H ?
>   			STRTAB_STE_1_STRW_EL2 : STRTAB_STE_1_STRW_NSEL1;
> @@ -1583,22 +1595,20 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
>   	arm_smmu_write_ste(master, sid, dst, &target);
>   }
>   
> +/*
> + * This can safely directly manipulate the STE memory without a sync sequence
> + * because the STE table has not been installed in the SMMU yet.
> + */
>   static void arm_smmu_init_bypass_stes(struct arm_smmu_ste *strtab,

This name is long out-of-date - if we're refreshing this area, please 
rename to something relevant to what it actually does, e.g. 
s/bypass/initial/.

Although frankly I also think that at this point we should just get rid 
of the disable_bypass parameter altogether - it's been almost entirely 
meaningless since default domain support was added, and any tenuous 
cases for wanting inital STEs to be bypass should probably be using RMRs 
now anyway.

Thanks,
Robin.

> -				      unsigned int nent, bool force)
> +				      unsigned int nent)
>   {
>   	unsigned int i;
> -	u64 val = STRTAB_STE_0_V;
> -
> -	if (disable_bypass && !force)
> -		val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT);
> -	else
> -		val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
>   
>   	for (i = 0; i < nent; ++i) {
> -		strtab->data[0] = cpu_to_le64(val);
> -		strtab->data[1] = cpu_to_le64(FIELD_PREP(
> -			STRTAB_STE_1_SHCFG, STRTAB_STE_1_SHCFG_INCOMING));
> -		strtab->data[2] = 0;
> +		if (disable_bypass)
> +			arm_smmu_make_abort_ste(strtab);
> +		else
> +			arm_smmu_make_bypass_ste(strtab);
>   		strtab++;
>   	}
>   }
> @@ -1626,7 +1636,7 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
>   		return -ENOMEM;
>   	}
>   
> -	arm_smmu_init_bypass_stes(desc->l2ptr, 1 << STRTAB_SPLIT, false);
> +	arm_smmu_init_bypass_stes(desc->l2ptr, 1 << STRTAB_SPLIT);
>   	arm_smmu_write_strtab_l1_desc(strtab, desc);
>   	return 0;
>   }
> @@ -3245,7 +3255,7 @@ static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
>   	reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits);
>   	cfg->strtab_base_cfg = reg;
>   
> -	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents, false);
> +	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents);
>   	return 0;
>   }
>   
> @@ -3956,7 +3966,6 @@ static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
>   	iort_get_rmr_sids(dev_fwnode(smmu->dev), &rmr_list);
>   
>   	list_for_each_entry(e, &rmr_list, list) {
> -		struct arm_smmu_ste *step;
>   		struct iommu_iort_rmr_data *rmr;
>   		int ret, i;
>   
> @@ -3969,8 +3978,12 @@ static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
>   				continue;
>   			}
>   
> -			step = arm_smmu_get_step_for_sid(smmu, rmr->sids[i]);
> -			arm_smmu_init_bypass_stes(step, 1, true);
> +			/*
> +			 * STE table is not programmed to HW, see
> +			 * arm_smmu_init_bypass_stes()
> +			 */
> +			arm_smmu_make_bypass_ste(
> +				arm_smmu_get_step_for_sid(smmu, rmr->sids[i]));
>   		}
>   	}
>   


From jacob.e.keller at intel.com  Thu Feb 15 09:31:23 2024
From: jacob.e.keller at intel.com (Jacob Keller)
Date: Thu, 15 Feb 2024 09:31:23 -0800
Subject: [PATCH] net: stmmac: xgmac: fix initializer element is not
 constant error
In-Reply-To: <867da21e-7f30-4caf-9f78-260d426e4186@posteo.net>
References: <20240212154319.907447-1-shiftee@posteo.net>
 <44c29a45-86fa-4e41-b4b5-e69187f0712e@intel.com>
 <867da21e-7f30-4caf-9f78-260d426e4186@posteo.net>
Message-ID: <ff53b219-201d-4544-ab37-014286c299ae@intel.com>



On 2/14/2024 2:07 PM, Mark O'Donovan wrote:
> On 14/02/2024 20:31, Jacob Keller wrote:
>>
>>
>> On 2/12/2024 7:43 AM, Mark O'Donovan wrote:
>>> GCC prior to 8.x gives an "initializer element is not constant"
>>> error for the uses of dpp_tx_err in dwxgmac3_dma_dpp_errors.
>>> Newer compilers accept either version.
>>>
>>> More info here:
>>> https://lore.kernel.org/all/20240103-fix-bq24190_charger-vbus_desc-non-const-v1-1-115ddf798c70 at kernel.org
>>>
>>> Signed-off-by: Mark O'Donovan <shiftee at posteo.net>
>>> ---
>>
>> I'm not sure whether the Linux kernel project has an explicit cutoff for
>> what versions of GCC (or other compilers) are supported. GCC 8 was first
>> released in 2018.
>>
>> The fix provided here is fairly straight forward, and while I do think
>> the benefit of using builtin types vs using the macros is nice, I don't
>> see that as a strong enough reason to hold up supporting the older compiler.
>>
>> Reviewed-by: Jacob Keller <jacob.e.keller at intel.com>
>>
>>>   drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 4 ++--
>>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>>> index 323c57f03c93..c02c035b81c0 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
>>> @@ -830,8 +830,8 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
>>>   	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
>>>   };
>>>   
>>> -static const char * const dpp_rx_err = "Read Rx Descriptor Parity checker Error";
>>> -static const char * const dpp_tx_err = "Read Tx Descriptor Parity checker Error";
>>> +#define dpp_rx_err "Read Rx Descriptor Parity checker Error"
>>> +#define dpp_tx_err "Read Tx Descriptor Parity checker Error"
>>>   static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
>>>   	{ true, "TDPES0", dpp_tx_err },
>>>   	{ true, "TDPES1", dpp_tx_err },
>>>
>>> base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de
> 
> Thanks Jacob.
> 
> The minimum versions for compilers and other tools are documented here:
> https://www.kernel.org/doc/html/latest/process/changes.html
> 
> I am using a SLES 15 server to build, the first version of which came out in 2017.
> 
> Mark

Thanks for pointing this out, I failed to find it with grep. Useful to
have this as a reference.


From a0501179 at ti.com  Thu Feb 15 09:33:16 2024
From: a0501179 at ti.com (Anwar, Md Danish)
Date: Thu, 15 Feb 2024 23:03:16 +0530
Subject: [PATCH] arm64: dts: ti: k3-am654: Drop ti,syscon-rgmii-delay from
 ICSSG nodes
In-Reply-To: <a0dc9fb7-2124-4f0d-a136-fc16a2301b0d@lunn.ch>
References: <20240215105407.2868266-1-danishanwar@ti.com>
 <71adaabd-bb24-4181-9fdf-f7191e93edb5@kernel.org>
 <4ef87f6c-caa8-45a8-8649-422806ec6eb2@ti.com>
 <a0dc9fb7-2124-4f0d-a136-fc16a2301b0d@lunn.ch>
Message-ID: <7b99b3c2-d0dc-4092-9090-5b960ba12738@ti.com>



On 2/15/2024 10:53 PM, Andrew Lunn wrote:
> On Thu, Feb 15, 2024 at 10:26:59PM +0530, Anwar, Md Danish wrote:
>>
>>
>> On 2/15/2024 9:27 PM, Roger Quadros wrote:
>>>
>>>
>>> On 15/02/2024 12:54, MD Danish Anwar wrote:
>>>> Drop ti,syscon-rgmii-delay from ICSSG0, ICSSG1 and ICSSG2 node as this
>>>> property is no longer used by ICSSG driver.
>>>>
>>>> Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
>>>> ---
>>>>  arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso | 2 --
>>>>  arch/arm64/boot/dts/ti/k3-am654-idk.dtso    | 4 ----
>>>>  2 files changed, 6 deletions(-)
>>>
>>> What about the DT binding document?
>>>
>>
>> Now I am only removing the property from device tree. Once this proprty
>> is removed from all DTs, in the 6.9-rc-1 I will remove the binding as
>> well so that net people can merge that without getting any errors /
>> warnings.
> 
> Did the binding have the property as mandatory? If so you are probably
> doing this the wrong way around. You should first modify the binding
> to mark it as optional and deprecated. Then modify the .dts{i} files
> to remove it.
> 

No the binding is optional that is why I am removing this property from
DTs first.

>    Andrew

-- 
Thanks and Regards,
Md Danish Anwar


From dianders at chromium.org  Thu Feb 15 09:38:47 2024
From: dianders at chromium.org (Doug Anderson)
Date: Thu, 15 Feb 2024 09:38:47 -0800
Subject: [PATCH v2] arm64/sve: Lower the maximum allocation for the SVE
 ptrace regset
In-Reply-To: <170799768132.3746307.14703611184129999692.b4-ty@kernel.org>
References: <20240213-arm64-sve-ptrace-regset-size-v2-1-c7600ca74b9b@kernel.org>
 <170799768132.3746307.14703611184129999692.b4-ty@kernel.org>
Message-ID: <CAD=FV=WSi=9V-Oe5eq0J-Uew45cX9JfgB8me-Nw-iFRfXm59Xg@mail.gmail.com>

Hi,

On Thu, Feb 15, 2024 at 4:44?AM Will Deacon <will at kernel.org> wrote:
>
> On Tue, 13 Feb 2024 18:24:38 +0000, Mark Brown wrote:
> > Doug Anderson observed that ChromeOS crashes are being reported which
> > include failing allocations of order 7 during core dumps due to ptrace
> > allocating storage for regsets:
> >
> >   chrome: page allocation failure: order:7,
> >           mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
> >           nodemask=(null),cpuset=urgent,mems_allowed=0
> >    ...
> >   regset_get_alloc+0x1c/0x28
> >   elf_core_dump+0x3d8/0xd8c
> >   do_coredump+0xeb8/0x1378
> >
> > [...]
>
> Applied to arm64 (for-next/fixes), thanks!
>
> [1/1] arm64/sve: Lower the maximum allocation for the SVE ptrace regset
>       https://git.kernel.org/arm64/c/2813926261e4

Thanks!

A side note to anyone trying to backport this is that there's a hidden
dependency of commit f171f9e4097d ("arm64/fp: Make SVE and SME length
register definition match architecture"). Without that dependency then
backporting ${SUBJECT} patch is just a no-op. ...backporting the
hidden dependency ends up giving merge conflicts, so for the purposes
of picking this to our 5.15 or earlier branches I went back to just
making the #define be 16 again like it was in v1.

-Doug


From konrad.dybcio at linaro.org  Thu Feb 15 09:48:44 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Thu, 15 Feb 2024 18:48:44 +0100
Subject: [PATCH v2 4/6] drm/msm: add support for A750 GPU
In-Reply-To: <20240215-topic-sm8650-gpu-v2-4-6be0b4bf2e09@linaro.org>
References: <20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09@linaro.org>
 <20240215-topic-sm8650-gpu-v2-4-6be0b4bf2e09@linaro.org>
Message-ID: <7827ef92-e3af-49f6-b9ed-5bac0cbcc513@linaro.org>

On 15.02.2024 10:20, Neil Armstrong wrote:
> Add support for the A750 GPU found on the SM8650 platform
> 
> Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
> doesn't have an HWCFG block but a separate register set.
> 
> The A750 GPU info are added under the adreno_is_a750() macro and
> the ADRENO_7XX_GEN3 family id.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>

Konrad


From oleg at redhat.com  Thu Feb 15 09:50:11 2024
From: oleg at redhat.com (Oleg Nesterov)
Date: Thu, 15 Feb 2024 18:50:11 +0100
Subject: [PATCH v2] ARM: ptrace: Use bitfield helpers
In-Reply-To: <f73e6deb1bef9696661a62498ee5a56ac9a389ce.1708005130.git.geert+renesas@glider.be>
References: <f73e6deb1bef9696661a62498ee5a56ac9a389ce.1708005130.git.geert+renesas@glider.be>
Message-ID: <20240215174945.GA29299@redhat.com>

Sorry for the noise, can't resist...

I am replying only because I wasn't aware of bitfield.h and useful
helpers there.

Thank you ;)

On 02/15, Geert Uytterhoeven wrote:
>
>  #ifndef __ASSEMBLY__
> +#include <linux/bitfield.h>
>  #include <linux/types.h>
>
>  struct pt_regs {
> @@ -35,8 +36,8 @@ struct svc_pt_regs {
>
>  #ifndef CONFIG_CPU_V7M
>  #define isa_mode(regs) \
> -	((((regs)->ARM_cpsr & PSR_J_BIT) >> (__ffs(PSR_J_BIT) - 1)) | \
> -	 (((regs)->ARM_cpsr & PSR_T_BIT) >> (__ffs(PSR_T_BIT))))
> +	(FIELD_GET(PSR_J_BIT, (regs)->ARM_cpsr) << 1 | \
> +	 FIELD_GET(PSR_T_BIT, (regs)->ARM_cpsr))

Reviewed-by: Oleg Nesterov <oleg at redhat.com>



From catalin.marinas at arm.com  Thu Feb 15 10:06:33 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 15 Feb 2024 18:06:33 +0000
Subject: [PATCH v4 01/26] arm64: sysreg: Add missing ID_AA64ISAR[13]_EL1
 fields and variants
In-Reply-To: <20240214131827.2856277-2-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
 <20240214131827.2856277-2-maz@kernel.org>
Message-ID: <Zc5SqaxkjhLKR1o9@arm.com>

On Wed, Feb 14, 2024 at 01:18:02PM +0000, Marc Zyngier wrote:
> Despite having the control bits for FEAT_SPECRES and FEAT_PACM,
> the ID registers fields are either incomplete or missing.
> 
> Fix it.
> 
> Reviewed-by: Mark Brown <broonie at kernel.org>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

In case you need another ack on this patch:

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From eauger at redhat.com  Thu Feb 15 10:27:20 2024
From: eauger at redhat.com (Eric Auger)
Date: Thu, 15 Feb 2024 19:27:20 +0100
Subject: [PATCH v4 5/5] KVM: selftests: aarch64: Add invalid filter test
 in pmu_event_filter_test
In-Reply-To: <20240202025659.5065-6-shahuang@redhat.com>
References: <20240202025659.5065-1-shahuang@redhat.com>
 <20240202025659.5065-6-shahuang@redhat.com>
Message-ID: <94ae4343-487a-4782-8b15-6f1201eed882@redhat.com>

Hi Shaoqin,

On 2/2/24 03:56, Shaoqin Huang wrote:
> Add the invalid filter test includes sets the filter beyond the event
s/includes/which
> space and sets the invalid action to double check if the
> KVM_ARM_VCPU_PMU_V3_FILTER will return the expected error.
> 
> Signed-off-by: Shaoqin Huang <shahuang at redhat.com>
> ---
>  .../kvm/aarch64/pmu_event_filter_test.c       | 36 +++++++++++++++++++
>  1 file changed, 36 insertions(+)
> 
> diff --git a/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
> index d280382f362f..68e1f2003312 100644
> --- a/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
> +++ b/tools/testing/selftests/kvm/aarch64/pmu_event_filter_test.c
> @@ -7,6 +7,7 @@
>   * This test checks if the guest only see the limited pmu event that userspace
>   * sets, if the guest can use those events which user allow, and if the guest
>   * can't use those events which user deny.
> + * It also checks that setting invalid filter ranges return the expected error.
>   * This test runs only when KVM_CAP_ARM_PMU_V3, KVM_ARM_VCPU_PMU_V3_FILTER
>   * is supported on the host.
>   */
> @@ -183,6 +184,39 @@ static void for_each_test(void)
>  		run_test(t);
>  }
>  
> +static void set_invalid_filter(struct vpmu_vm *vm, void *arg)
> +{
> +	struct kvm_pmu_event_filter invalid;
> +	struct kvm_device_attr attr = {
> +		.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
> +		.attr	= KVM_ARM_VCPU_PMU_V3_FILTER,
> +		.addr	= (uint64_t)&invalid,
> +	};
> +	int ret = 0;
> +
> +	/* The max event number is (1 << 16), set a range largeer than it. */
in  practice it is 16b on ARMv8.1 and 10b on ARMv8.0 but obvioulsy the
check below works for both ;-)

larger typ
> +	invalid = __DEFINE_FILTER(BIT(15), BIT(15)+1, 0);
space between "+"
> +	ret = __vcpu_ioctl(vm->vcpu, KVM_SET_DEVICE_ATTR, &attr);
kvm_device_attr_set() as commented by Oliver
> +	TEST_ASSERT(ret && errno == EINVAL, "Set Invalid filter range "
> +		    "ret = %d, errno = %d (expected ret = -1, errno = EINVAL)",
> +		    ret, errno);
> +
> +	ret = 0;
> +
> +	/* Set the Invalid action. */
> +	invalid = __DEFINE_FILTER(0, 1, 3);
> +	ret = __vcpu_ioctl(vm->vcpu, KVM_SET_DEVICE_ATTR, &attr);
> +	TEST_ASSERT(ret && errno == EINVAL, "Set Invalid filter action "
> +		    "ret = %d, errno = %d (expected ret = -1, errno = EINVAL)",
> +		    ret, errno);
> +}
> +
> +static void test_invalid_filter(void)
> +{
> +	vpmu_vm = __create_vpmu_vm(guest_code, set_invalid_filter, NULL);
> +	destroy_vpmu_vm(vpmu_vm);
> +}
> +
>  static bool kvm_supports_pmu_event_filter(void)
>  {
>  	int r;
> @@ -216,4 +250,6 @@ int main(void)
>  	TEST_REQUIRE(host_pmu_supports_events());
>  
>  	for_each_test();
> +
> +	test_invalid_filter();
>  }
Thanks

Eric



From catalin.marinas at arm.com  Thu Feb 15 10:27:54 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 15 Feb 2024 18:27:54 +0000
Subject: [PATCH v6 04/18] arm64/mm: Convert pte_next_pfn() to
 pte_advance_pfn()
In-Reply-To: <20240215103205.2607016-5-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-5-ryan.roberts@arm.com>
Message-ID: <Zc5XqjvhaDkw4XdI@arm.com>

On Thu, Feb 15, 2024 at 10:31:51AM +0000, Ryan Roberts wrote:
> Core-mm needs to be able to advance the pfn by an arbitrary amount, so
> override the new pte_advance_pfn() API to do so.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Feb 15 10:34:00 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 15 Feb 2024 18:34:00 +0000
Subject: [PATCH v6 07/18] arm64/mm: Convert READ_ONCE(*ptep) to
 ptep_get(ptep)
In-Reply-To: <20240215103205.2607016-8-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-8-ryan.roberts@arm.com>
Message-ID: <Zc5ZGNaYp5dFND1_@arm.com>

On Thu, Feb 15, 2024 at 10:31:54AM +0000, Ryan Roberts wrote:
> There are a number of places in the arch code that read a pte by using
> the READ_ONCE() macro. Refactor these call sites to instead use the
> ptep_get() helper, which itself is a READ_ONCE(). Generated code should
> be the same.
> 
> This will benefit us when we shortly introduce the transparent contpte
> support. In this case, ptep_get() will become more complex so we now
> have all the code abstracted through it.
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Feb 15 10:34:25 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 15 Feb 2024 18:34:25 +0000
Subject: [PATCH v6 08/18] arm64/mm: Convert set_pte_at() to set_ptes(...,
 1)
In-Reply-To: <20240215103205.2607016-9-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-9-ryan.roberts@arm.com>
Message-ID: <Zc5ZMbMosSvI0rRm@arm.com>

On Thu, Feb 15, 2024 at 10:31:55AM +0000, Ryan Roberts wrote:
> Since set_ptes() was introduced, set_pte_at() has been implemented as a
> generic macro around set_ptes(..., 1). So this change should continue to
> generate the same code. However, making this change prepares us for the
> transparent contpte support. It means we can reroute set_ptes() to
> __set_ptes(). Since set_pte_at() is a generic macro, there will be no
> equivalent __set_pte_at() to reroute to.
> 
> Note that a couple of calls to set_pte_at() remain in the arch code.
> This is intentional, since those call sites are acting on behalf of
> core-mm and should continue to call into the public set_ptes() rather
> than the arch-private __set_ptes().
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Feb 15 10:35:07 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 15 Feb 2024 18:35:07 +0000
Subject: [PATCH v6 09/18] arm64/mm: Convert ptep_clear() to
 ptep_get_and_clear()
In-Reply-To: <20240215103205.2607016-10-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-10-ryan.roberts@arm.com>
Message-ID: <Zc5ZW8294PaNjstg@arm.com>

On Thu, Feb 15, 2024 at 10:31:56AM +0000, Ryan Roberts wrote:
> ptep_clear() is a generic wrapper around the arch-implemented
> ptep_get_and_clear(). We are about to convert ptep_get_and_clear() into
> a public version and private version (__ptep_get_and_clear()) to support
> the transparent contpte work. We won't have a private version of
> ptep_clear() so let's convert it to directly call ptep_get_and_clear().
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From krzysztof.kozlowski at linaro.org  Thu Feb 15 10:36:29 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 19:36:29 +0100
Subject: [PATCH v4 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <20240208161700.268570-2-peter.griffin@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org>
 <20240208161700.268570-2-peter.griffin@linaro.org>
Message-ID: <ab1f9285-73ba-4b69-8882-0cf08c508e28@linaro.org>

On 08/02/2024 17:16, Peter Griffin wrote:
> Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> security hardening reasons so that they are only write accessible in el3
> via an SMC call.
> 
> As most Exynos drivers that need to write PMU registers currently obtain a
> regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> is implemented in this driver using a custom regmap similar to syscon to
> handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> regmap like before. As regmaps abstract out the underlying register access
> changes to the leaf drivers are minimal.
> 
> A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> that currently use syscon_regmap_lookup_by_phandle(). This also handles
> deferred probing.

I found an issue, which needs new version, so I also found few more nits.

> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
> Changes since v3:
>  - Fix PMUALIVE_MASK
>  - Add TENSOR_ prefix
>  - clear SET_BITS bits on each loop iteration
>  - change set_bit to set_bits in func name
>  - Fix some alignment
>  - Add missing return on dev_err_probe
>  - Reduce indentation in loop
> 
> Changes since v2
>  - Add select REGMAP to Kconfig
>  - Add constant for SET/CLEAR bits
>  - Replace kerneldoc with one line comment
>  - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
>  - remove superfluous extern keyword
>  - dev_err_probe() on probe error
>  - shorten regmcfg name
>  - no compatibles inside probe, use match data
>  - don't mix declarations with/without initializations
>  - tensor_sec_reg_read() use mmio to avoid access restrictions
>  - Collect up Reviewed-by
>  - const for regmap_config structs
> ---
>  drivers/soc/samsung/Kconfig            |   1 +
>  drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
>  drivers/soc/samsung/exynos-pmu.h       |   1 +
>  include/linux/soc/samsung/exynos-pmu.h |  11 +-
>  4 files changed, 243 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 27ec99af77e3..1a5dfdc978dc 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -42,6 +42,7 @@ config EXYNOS_PMU
>  	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
>  	select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
>  	select MFD_CORE
> +	select REGMAP_MMIO
>  
>  # There is no need to enable these drivers for ARMv8
>  config EXYNOS_PMU_ARM_DRIVERS
> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> index 250537d7cfd6..b846e343fcdd 100644
> --- a/drivers/soc/samsung/exynos-pmu.c
> +++ b/drivers/soc/samsung/exynos-pmu.c
> @@ -5,6 +5,7 @@
>  //
>  // Exynos - CPU PMU(Power Management Unit) support
>  
> +#include <linux/arm-smccc.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/mfd/core.h>
> @@ -12,19 +13,132 @@
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/delay.h>
> +#include <linux/regmap.h>
>  
>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>  #include <linux/soc/samsung/exynos-pmu.h>
>  
>  #include "exynos-pmu.h"
>  
> +#define PMUALIVE_MASK			GENMASK(13, 0)
> +#define TENSOR_SET_BITS			(BIT(15) | BIT(14))
> +#define TENSOR_CLR_BITS			BIT(15)
> +#define TENSOR_SMC_PMU_SEC_REG		0x82000504
> +#define TENSOR_PMUREG_READ		0
> +#define TENSOR_PMUREG_WRITE		1
> +#define TENSOR_PMUREG_RMW		2
> +
>  struct exynos_pmu_context {
>  	struct device *dev;
>  	const struct exynos_pmu_data *pmu_data;
> +	struct regmap *pmureg;
>  };
>  
>  void __iomem *pmu_base_addr;
>  static struct exynos_pmu_context *pmu_context;
> +/* forward declaration */
> +static struct platform_driver exynos_pmu_driver;
> +
> +/*
> + * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
> + * from EL3, but are still read accessible. As Linux needs to write some of
> + * these registers, the following functions are provided and exposed via
> + * regmap.
> + *
> + * Note: This SMC interface is known to be implemented on gs101 and derivative
> + * SoCs.
> + */
> +
> +/* Write to a protected PMU register. */
> +static int tensor_sec_reg_write(void *base, unsigned int reg, unsigned int val)

Please use the same argument names in all these regmap functions as in
struct regmap_config, so base->context

> +{
> +	struct arm_smccc_res res;
> +	unsigned long pmu_base = (unsigned long)base;
> +
> +	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> +		      TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
> +
> +	/* returns -EINVAL if access isn't allowed or 0 */
> +	if (res.a0)
> +		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> +
> +	return (int)res.a0;
> +}
> +
> +/* Read/Modify/Write a protected PMU register. */
> +static int tensor_sec_reg_rmw(void *base, unsigned int reg,
> +			      unsigned int mask, unsigned int val)
> +{
> +	struct arm_smccc_res res;
> +	unsigned long pmu_base = (unsigned long)base;
> +
> +	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> +		      TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
> +
> +	/* returns -EINVAL if access isn't allowed or 0 */
> +	if (res.a0)
> +		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> +
> +	return (int)res.a0;
> +}
> +
> +/*
> + * Read a protected PMU register. All PMU registers can be read by Linux.
> + * Note: The SMC read register is not used, as only registers that can be
> + * written are readable via SMC.
> + */
> +static int tensor_sec_reg_read(void *base, unsigned int reg, unsigned int *val)
> +{
> +	*val = pmu_raw_readl(reg);
> +	return 0;
> +}
> +
> +/*
> + * For SoCs that have set/clear bit hardware this function can be used when
> + * the PMU register will be accessed by multiple masters.
> + *
> + * For example, to set bits 13:8 in PMU reg offset 0x3e80
> + * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00);
> + *
> + * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80
> + * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00);
> + */
> +static inline int tensor_set_bits_atomic(void *ctx, unsigned int offset,

Usual practice is to rely on compiler to inline, so let's drop the
keyword here.

> +					 u32 val, u32 mask)
> +{
> +	int ret;
> +	unsigned int i;
> +
> +	for (i = 0; i < 32; i++) {
> +		if (!(mask & BIT(i)))
> +			continue;
> +
> +		offset &= ~TENSOR_SET_BITS;
> +
> +		if (val & BIT(i))
> +			offset |= TENSOR_SET_BITS;
> +		else
> +			offset |= TENSOR_CLR_BITS;
> +
> +		ret = tensor_sec_reg_write(ctx, offset, i);
> +		if (ret)
> +			return ret;
> +	}
> +	return ret;
> +}
> +
> +static int tensor_sec_update_bits(void *ctx, unsigned int reg,
> +				  unsigned int mask, unsigned int val)
> +{
> +	/*
> +	 * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
> +	 * as the target registers can be accessed by multiple masters.
> +	 */
> +	if (reg > PMUALIVE_MASK)
> +		return tensor_sec_reg_rmw(ctx, reg, mask, val);
> +
> +	return tensor_set_bits_atomic(ctx, reg, val, mask);
> +}
>  
>  void pmu_raw_writel(u32 val, u32 offset)
>  {
> @@ -75,11 +189,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
>  #define exynos_pmu_data_arm_ptr(data)	NULL
>  #endif
>  
> +static const struct regmap_config regmap_smccfg = {
> +	.name = "pmu_regs",
> +	.reg_bits = 32,
> +	.reg_stride = 4,
> +	.val_bits = 32,
> +	.fast_io = true,
> +	.use_single_read = true,
> +	.use_single_write = true,
> +	.reg_read = tensor_sec_reg_read,
> +	.reg_write = tensor_sec_reg_write,
> +	.reg_update_bits = tensor_sec_update_bits,

> +};
> +
> +static const struct regmap_config regmap_mmiocfg = {
> +	.name = "pmu_regs",
> +	.reg_bits = 32,
> +	.reg_stride = 4,
> +	.val_bits = 32,
> +	.fast_io = true,
> +	.use_single_read = true,
> +	.use_single_write = true,
> +};
> +
> +static const struct exynos_pmu_data gs101_pmu_data = {
> +	.pmu_secure = true
> +};
> +
>  /*
>   * PMU platform driver and devicetree bindings.
>   */
>  static const struct of_device_id exynos_pmu_of_device_ids[] = {
>  	{
> +		.compatible = "google,gs101-pmu",
> +		.data = &gs101_pmu_data,
> +	}, {
>  		.compatible = "samsung,exynos3250-pmu",
>  		.data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
>  	}, {
> @@ -113,19 +257,73 @@ static const struct mfd_cell exynos_pmu_devs[] = {
>  	{ .name = "exynos-clkout", },
>  };
>  
> +/**
> + * exynos_get_pmu_regmap() - Obtain pmureg regmap
> + *
> + * Find the pmureg regmap previously configured in probe() and return regmap
> + * pointer.
> + *
> + * Return: A pointer to regmap if found or ERR_PTR error value.
> + */
>  struct regmap *exynos_get_pmu_regmap(void)
>  {
>  	struct device_node *np = of_find_matching_node(NULL,
>  						      exynos_pmu_of_device_ids);
>  	if (np)
> -		return syscon_node_to_regmap(np);
> +		return exynos_get_pmu_regmap_by_phandle(np, NULL);
>  	return ERR_PTR(-ENODEV);
>  }
>  EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
>  
> +/**
> + * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
> + * @np: Pointer to device's Device Tree node

A bit unusual naming... drop "Device Tree" anywhere here. This is:
"device node holding PMU phandle property"


> + * @property: Device Tree property name which references the pmu

Name of property holding a phandle value

> + *
> + * Find the pmureg regmap previously configured in probe() and return regmap
> + * pointer.
> + *
> + * Return: A pointer to regmap if found or ERR_PTR error value.
> + */
> +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> +						const char *property)

property -> propname

> +{
> +	struct device *dev;
> +	struct exynos_pmu_context *ctx;
> +	struct device_node *pmu_np;

Reversed christmass tree.

> +
> +	if (property)
> +		pmu_np = of_parse_phandle(np, property, 0);
> +	else
> +		pmu_np = np;
> +
> +	if (!pmu_np)
> +		return ERR_PTR(-ENODEV);
> +
> +	/*
> +	 * Determine if exynos-pmu device has probed and therefore regmap
> +	 * has been created and can be returned to the caller. Otherwise we
> +	 * return -EPROBE_DEFER.
> +	 */
> +	dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
> +					    (void *)pmu_np);
> +
> +	of_node_put(pmu_np);

You are dropping now referencen from np when property==NULL. This does
no look right.

> +	if (!dev)
> +		return ERR_PTR(-EPROBE_DEFER);
> +
> +	ctx = dev_get_drvdata(dev);
> +
> +	return ctx->pmureg;
> +}
> +EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
> +
>  static int exynos_pmu_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> +	struct regmap_config pmu_regmcfg;
> +	struct regmap *regmap;
> +	struct resource *res;
>  	int ret;
>  
>  	pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
> @@ -133,13 +331,42 @@ static int exynos_pmu_probe(struct platform_device *pdev)
>  		return PTR_ERR(pmu_base_addr);
>  
>  	pmu_context = devm_kzalloc(&pdev->dev,
> -			sizeof(struct exynos_pmu_context),
> -			GFP_KERNEL);
> +				   sizeof(struct exynos_pmu_context),
> +				   GFP_KERNEL);

Not related here. You could have separate patch for cleanups or just
skip such change.


>  	if (!pmu_context)
>  		return -ENOMEM;
> -	pmu_context->dev = dev;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -ENODEV;
> +

Best regards,
Krzysztof



From robin.murphy at arm.com  Thu Feb 15 10:42:37 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 15 Feb 2024 18:42:37 +0000
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <20240215160135.GL1088888@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240215134952.GA690@willie-the-truck> <20240215160135.GL1088888@nvidia.com>
Message-ID: <02fac0ab-07ac-448e-ae4e-26788ed4fce9@arm.com>

On 15/02/2024 4:01 pm, Jason Gunthorpe wrote:
> On Thu, Feb 15, 2024 at 01:49:53PM +0000, Will Deacon wrote:
>> Hi Jason,
>>
>> On Tue, Feb 06, 2024 at 11:12:38AM -0400, Jason Gunthorpe wrote:
>>> As the comment in arm_smmu_write_strtab_ent() explains, this routine has
>>> been limited to only work correctly in certain scenarios that the caller
>>> must ensure. Generally the caller must put the STE into ABORT or BYPASS
>>> before attempting to program it to something else.
>>
>> This is looking pretty good now, but I have a few comments inline.
> 
> Ok
> 
>>> @@ -48,6 +48,21 @@ enum arm_smmu_msi_index {
>>>   	ARM_SMMU_MAX_MSIS,
>>>   };
>>>   
>>> +struct arm_smmu_entry_writer_ops;
>>> +struct arm_smmu_entry_writer {
>>> +	const struct arm_smmu_entry_writer_ops *ops;
>>> +	struct arm_smmu_master *master;
>>> +};
>>> +
>>> +struct arm_smmu_entry_writer_ops {
>>> +	unsigned int num_entry_qwords;
>>> +	__le64 v_bit;
>>> +	void (*get_used)(const __le64 *entry, __le64 *used);
>>> +	void (*sync)(struct arm_smmu_entry_writer *writer);
>>> +};
>>
>> Can we avoid the indirection for now, please? I'm sure we'll want it later
>> when you extend this to CDs, but for the initial support it just makes it
>> more difficult to follow the flow. Should be a trivial thing to drop, I
>> hope.
> 
> We can.

Ack, the abstraction is really hard to follow, and much of that seems 
entirely self-inflicted in the amount of recalculating information which 
was in-context in a previous step but then thrown away. And as best I 
can tell I think it will still end up doing more CFGIs than needed.

Keeping a single monolithic check-and-update function will be *so* much 
easier to understand and maintain. As far as CDs go, anything we might 
reasonably want to change in a live CD is all in the first word so I 
don't see any value in attempting to generalise further on that side of 
things. Maybe arm_smmu_write_ctx_desc() could stand to be a bit 
prettier, but honestly I don't think it's too bad as-is.

>>> +static void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
>>>   {
>>> +	unsigned int cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ent[0]));
>>> +
>>> +	used_bits[0] = cpu_to_le64(STRTAB_STE_0_V);
>>> +	if (!(ent[0] & cpu_to_le64(STRTAB_STE_0_V)))
>>> +		return;
>>> +
>>> +	/*
>>> +	 * See 13.5 Summary of attribute/permission configuration fields for the
>>> +	 * SHCFG behavior. It is only used for BYPASS, including S1DSS BYPASS,
>>> +	 * and S2 only.
>>> +	 */
>>> +	if (cfg == STRTAB_STE_0_CFG_BYPASS ||
>>> +	    cfg == STRTAB_STE_0_CFG_S2_TRANS ||
>>> +	    (cfg == STRTAB_STE_0_CFG_S1_TRANS &&
>>> +	     FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
>>> +		     STRTAB_STE_1_S1DSS_BYPASS))
>>> +		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_SHCFG);
>>
>> Huh, SHCFG is really getting in the way here, isn't it?
> 
> I wouldn't say that.. It is just a complicated bit of the spec. One of
> the things we recently did was to audit all the cache settings and, at
> least, we then realized that SHCFG was being subtly used by S2 as
> well..

Yeah, that really shouldn't be subtle; incoming attributes are replaced 
by S1 translation, thus they are relevant to not-S1 configs.

I think it's likely to be significantly more straightforward to give up 
on the switch statement and jump straight into the more architectural 
paradigm at this level, e.g.

	// Stage 1
	if (cfg & BIT(0)) {
		...
	} else {
		...
	}
	// Stage 2
	if (cfg & BIT(1)) {
		...
	} else {
		...
	}

Thanks,
Robin.


From krzysztof.kozlowski at linaro.org  Thu Feb 15 10:44:53 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 15 Feb 2024 19:44:53 +0100
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <aamdttvdk3jmswvy3rw3debk3ouddkgjbs6xmixroe6kqakjw4@lnd5crcgoeyj>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
 <aamdttvdk3jmswvy3rw3debk3ouddkgjbs6xmixroe6kqakjw4@lnd5crcgoeyj>
Message-ID: <2e96c824-47e8-48bd-9e03-8c7390b02d24@linaro.org>

On 15/02/2024 11:02, Uwe Kleine-K?nig wrote:
> On Mon, Feb 12, 2024 at 11:23:02AM +0100, Krzysztof Kozlowski wrote:
>> On 08/02/2024 11:43, Lee Jones wrote:
>>> On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
>>>> Convert the atmel,hlcdc binding to DT schema format.
>>>>
>>>> Align clocks and clock-names properties to clearly indicate that the LCD
>>>> controller expects lvds_pll_clk when interfaced with the lvds display. This
>>>> alignment with the specific hardware requirements ensures accurate device tree
>>>> configuration for systems utilizing the HLCDC IP.
>>>>
>>>> [...]
>>>
>>> Applied, thanks!
>>>
>>> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
>>>       commit: cb946db1335b599ece363d33966bf653ed0fa58a
>>>
>>
>> Next is still failing.
> 
> Failing in the sense of dtbs_check, right?

No, bindings were failing. dt_binding_check. This must not fail, so kind
of bummer...


> 
>> Dharma,
>> You must explain and clearly mark dependencies between patches.
>>
>> Lee,
>> Can you pick up two previous patches as well?
> 
> I applied the pwm patch now. If Lee wants to pick up this one via his
> tree that would be fine for me, too. If that's the case please tell me,
> then I'll drop it from my for-next branch again. Feel free to add
> my Acked-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de> for patch
> #2 then.

At least next is happy.
> 

Best regards,
Krzysztof



From robin.murphy at arm.com  Thu Feb 15 11:01:59 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 15 Feb 2024 19:01:59 +0000
Subject: [PATCH v5 03/17] iommu/arm-smmu-v3: Move
 arm_smmu_rmr_install_bypass_ste()
In-Reply-To: <ZcuMx0w6MDWpkLne@google.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <3-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZcuMx0w6MDWpkLne@google.com>
Message-ID: <a9d10aaa-e6b1-44bd-8d7e-9e1abedf03d1@arm.com>

On 13/02/2024 3:37 pm, Mostafa Saleh wrote:
> Hi Jason,
> 
> On Tue, Feb 06, 2024 at 11:12:40AM -0400, Jason Gunthorpe wrote:
>> Logically arm_smmu_init_strtab() is the function that allocates and
>> populates the stream table with the initial value of the STEs. After this
>> function returns the stream table should be fully ready.
>>
>> arm_smmu_rmr_install_bypass_ste() adjusts the initial stream table to force
>> any SIDs that the FW says have IOMMU_RESV_DIRECT to use bypass. This
>> ensures there is no disruption to the identity mapping during boot.
>>
>> Put arm_smmu_rmr_install_bypass_ste() into arm_smmu_init_strtab(), it
>> already executes immediately after arm_smmu_init_strtab().
>>
>> No functional change intended.
> 
> I think arm_smmu_init_strtab is quite low level to abstract FW configuration in it.
> For example in KVM[1] we'd re-use a big part of this driver and rely on similar
> low-level functions. But no strong opinion.

Right, the fact that RMR handling is currently based on bypass STEs is 
an implementation detail; if we ever get round to doing the strict 
version with full-on temporary pagetables, that would obviously not 
belong in init_strtab, thus I would prefer to leave the "handle RMRs" 
step in its appropriate place in the higher-level flow regardless of how 
it happens to be named and implemented today.

Thanks,
Robin.

> 
> [1] https://lore.kernel.org/kvmarm/20230201125328.2186498-1-jean-philippe at linaro.org/
> 
> 
> Thanks,
> Mostafa
> 
>> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
>> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
>> Tested-by: Moritz Fischer <moritzf at google.com>
>> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
>> ---
>>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++---
>>   1 file changed, 5 insertions(+), 3 deletions(-)
>>
>> 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 6123e5ad95822c..2ab36dcf7c61f5 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -101,6 +101,8 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
>>   	{ 0, NULL},
>>   };
>>   
>> +static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu);
>> +
>>   static void parse_driver_options(struct arm_smmu_device *smmu)
>>   {
>>   	int i = 0;
>> @@ -3256,6 +3258,7 @@ static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
>>   	cfg->strtab_base_cfg = reg;
>>   
>>   	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents);
>> +
>>   	return 0;
>>   }
>>   
>> @@ -3279,6 +3282,8 @@ static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
>>   
>>   	ida_init(&smmu->vmid_map);
>>   
>> +	/* Check for RMRs and install bypass STEs if any */
>> +	arm_smmu_rmr_install_bypass_ste(smmu);
>>   	return 0;
>>   }
>>   
>> @@ -4073,9 +4078,6 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
>>   	/* Record our private device structure */
>>   	platform_set_drvdata(pdev, smmu);
>>   
>> -	/* Check for RMRs and install bypass STEs if any */
>> -	arm_smmu_rmr_install_bypass_ste(smmu);
>> -
>>   	/* Reset the device */
>>   	ret = arm_smmu_device_reset(smmu, bypass);
>>   	if (ret)
>> -- 
>> 2.43.0
>>


From vidyas at nvidia.com  Thu Feb 15 11:09:23 2024
From: vidyas at nvidia.com (Vidya Sagar)
Date: Fri, 16 Feb 2024 00:39:23 +0530
Subject: [PATCH V16 13/13] PCI: tegra: Add Tegra194 PCIe support
In-Reply-To: <20240215160157.GA1291755@bhelgaas>
References: <20240215160157.GA1291755@bhelgaas>
Message-ID: <77b41973-e021-471c-89ad-f8cb8752e278@nvidia.com>


On 15-02-2024 21:31, Bjorn Helgaas wrote:
> External email: Use caution opening links or attachments
>
>
> On Thu, Feb 15, 2024 at 04:55:47PM +0530, Vidya Sagar wrote:
>> On 15-02-2024 00:42, Bjorn Helgaas wrote:
>>> Hi Vidya, question about ancient history:
>>>
>>> On Tue, Aug 13, 2019 at 05:06:27PM +0530, Vidya Sagar wrote:
>>>> Add support for Synopsys DesignWare core IP based PCIe host controller
>>>> present in Tegra194 SoC.
>>>> ...
>>>> +static int tegra_pcie_dw_host_init(struct pcie_port *pp)
>>>> +{
>>>> +     struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>>>> +     struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
>>>> +     u32 val, tmp, offset, speed;
>>>> +
>>>> +     tegra_pcie_prepare_host(pp);
>>>> +
>>>> +     if (dw_pcie_wait_for_link(pci)) {
>>>> +             /*
>>>> +              * There are some endpoints which can't get the link up if
>>>> +              * root port has Data Link Feature (DLF) enabled.
>>>> +              * Refer Spec rev 4.0 ver 1.0 sec 3.4.2 & 7.7.4 for more info
>>>> +              * on Scaled Flow Control and DLF.
>>>> +              * So, need to confirm that is indeed the case here and attempt
>>>> +              * link up once again with DLF disabled.
>>> This comment suggests that there's an issue with *Endpoints*, not an
>>> issue with the Root Port.  If so, it seems like this problem could
>>> occur with all Root Ports, not just Tegra194.  Do you remember any
>>> details about this?
>>>
>>> I don't remember hearing about any similar issues, and this driver is
>>> the only place PCI_EXT_CAP_ID_DLF is referenced, so maybe it is
>>> actually something related to Tegra194?
>> We noticed PCIe link-up issues with some endpoints. link-up at the physical
>> layer level but NOT at the Data link layer level precisely. We further
>> figured out that it is the DLFE DLLPs that the root port sends during the
>> link up process which are causing the endpoints get confused and preventing
>> them from sending the InitFC DLLPs leading to the link not being up at
>> Data Link Layer level.
> Do you happen to remember any of the endpoints that have issues?
We observed this issue with an ASMedia USB controller card. Unfortunately,
I didn't keep a record of the Vendor-ID and Device-ID of that card.
>
> Could save some painful debugging if we trip over this issue on other
> systems.  We have seen a few cases where links wouldn't train at full
> speed unless they trained at a lower speed first, e.g.,
> imx6_pcie_start_link(), fu740_pcie_start_link().  I guess there are
> probably lots of edge cases that can cause link failures.
>
> Bjorn


From catalin.marinas at arm.com  Thu Feb 15 11:21:13 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 15 Feb 2024 19:21:13 +0000
Subject: [PATCH v6 10/18] arm64/mm: New ptep layer to manage contig bit
In-Reply-To: <20240215103205.2607016-11-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-11-ryan.roberts@arm.com>
Message-ID: <Zc5kKSViCq8_77NW@arm.com>

On Thu, Feb 15, 2024 at 10:31:57AM +0000, Ryan Roberts wrote:
> Create a new layer for the in-table PTE manipulation APIs. For now, The
> existing API is prefixed with double underscore to become the
> arch-private API and the public API is just a simple wrapper that calls
> the private API.
> 
> The public API implementation will subsequently be used to transparently
> manipulate the contiguous bit where appropriate. But since there are
> already some contig-aware users (e.g. hugetlb, kernel mapper), we must
> first ensure those users use the private API directly so that the future
> contig-bit manipulations in the public API do not interfere with those
> existing uses.
> 
> The following APIs are treated this way:
> 
>  - ptep_get
>  - set_pte
>  - set_ptes
>  - pte_clear
>  - ptep_get_and_clear
>  - ptep_test_and_clear_young
>  - ptep_clear_flush_young
>  - ptep_set_wrprotect
>  - ptep_set_access_flags
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From rafael at kernel.org  Thu Feb 15 11:22:29 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 15 Feb 2024 20:22:29 +0100
Subject: [PATCH RFC v4 02/15] ACPI: processor: Register all CPUs from acpi_processor_get_info()
In-Reply-To: <E1rVDmU-0027YP-Jz@rmk-PC.armlinux.org.uk>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk> <E1rVDmU-0027YP-Jz@rmk-PC.armlinux.org.uk>
Message-ID: <CAJZ5v0iiJpUWq5GMSnKFWQTzn_bdwoQz9m=hDaXNg4Lj_ePF4g@mail.gmail.com>

On Wed, Jan 31, 2024 at 5:50?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:
>
> From: James Morse <james.morse at arm.com>
>
> To allow ACPI to skip the call to arch_register_cpu() when the _STA
> value indicates the CPU can't be brought online right now, move the
> arch_register_cpu() call into acpi_processor_get_info().
>
> Systems can still be booted with 'acpi=off', or not include an
> ACPI description at all. For these, the CPUs continue to be
> registered by cpu_dev_register_generic().
>
> This moves the CPU register logic back to a subsys_initcall(),
> while the memory nodes will have been registered earlier.
>
> Signed-off-by: James Morse <james.morse at arm.com>
> Reviewed-by: Gavin Shan <gshan at redhat.com>
> Tested-by: Miguel Luis <miguel.luis at oracle.com>
> Tested-by: Vishnu Pajjuri <vishnu at os.amperecomputing.com>
> Tested-by: Jianyong Wu <jianyong.wu at arm.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
> Changes since RFC v2:
>  * Fixup comment in acpi_processor_get_info() (Gavin Shan)
>  * Add comment in cpu_dev_register_generic() (Gavin Shan)
> ---
>  drivers/acpi/acpi_processor.c | 12 ++++++++++++
>  drivers/base/cpu.c            |  6 +++++-
>  2 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> index cf7c1cca69dd..a68c475cdea5 100644
> --- a/drivers/acpi/acpi_processor.c
> +++ b/drivers/acpi/acpi_processor.c
> @@ -314,6 +314,18 @@ static int acpi_processor_get_info(struct acpi_device *device)
>                         cpufreq_add_device("acpi-cpufreq");
>         }
>
> +       /*
> +        * Register CPUs that are present. get_cpu_device() is used to skip
> +        * duplicate CPU descriptions from firmware.
> +        */
> +       if (!invalid_logical_cpuid(pr->id) && cpu_present(pr->id) &&
> +           !get_cpu_device(pr->id)) {
> +               int ret = arch_register_cpu(pr->id);
> +
> +               if (ret)
> +                       return ret;
> +       }
> +
>         /*
>          *  Extra Processor objects may be enumerated on MP systems with
>          *  less than the max # of CPUs. They should be ignored _iff

This is interesting, because right below there is the following code:

    if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
        int ret = acpi_processor_hotadd_init(pr);

        if (ret)
            return ret;
    }

and acpi_processor_hotadd_init() essentially calls arch_register_cpu()
with some extra things around it (more about that below).

I do realize that acpi_processor_hotadd_init() is defined under
CONFIG_ACPI_HOTPLUG_CPU, so for the sake of the argument let's
consider an architecture where CONFIG_ACPI_HOTPLUG_CPU is set.

So why are the two conditionals that almost contradict each other both
needed?  It looks like the new code could be combined with
acpi_processor_hotadd_init() to do the right thing in all cases.

Now, acpi_processor_hotadd_init() does some extra things that look
like they should be done by the new code too.

1. It checks invalid_phys_cpuid() which appears to be a good idea to me.

2. It uses locking around arch_register_cpu() which doesn't seem
unreasonable either.

3. It calls acpi_map_cpu() and I'm not sure why this is not done by
the new code.

The only thing that can be dropped from it is the _STA check AFAICS,
because acpi_processor_add() won't even be called if the CPU is not
present (and not enabled after the first patch).

So why does the code not do 1 - 3 above?

> diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
> index 47de0f140ba6..13d052bf13f4 100644
> --- a/drivers/base/cpu.c
> +++ b/drivers/base/cpu.c
> @@ -553,7 +553,11 @@ static void __init cpu_dev_register_generic(void)
>  {
>         int i, ret;
>
> -       if (!IS_ENABLED(CONFIG_GENERIC_CPU_DEVICES))
> +       /*
> +        * When ACPI is enabled, CPUs are registered via
> +        * acpi_processor_get_info().
> +        */
> +       if (!IS_ENABLED(CONFIG_GENERIC_CPU_DEVICES) || !acpi_disabled)
>                 return;

Honestly, this looks like a quick hack to me and it absolutely
requires an ACK from the x86 maintainers to go anywhere.

>
>         for_each_present_cpu(i) {
> --


From catalin.marinas at arm.com  Thu Feb 15 11:22:52 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 15 Feb 2024 19:22:52 +0000
Subject: [PATCH v6 11/18] arm64/mm: Split __flush_tlb_range() to elide
 trailing DSB
In-Reply-To: <20240215103205.2607016-12-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-12-ryan.roberts@arm.com>
Message-ID: <Zc5kjJlGnva6qJRt@arm.com>

On Thu, Feb 15, 2024 at 10:31:58AM +0000, Ryan Roberts wrote:
> Split __flush_tlb_range() into __flush_tlb_range_nosync() +
> __flush_tlb_range(), in the same way as the existing flush_tlb_page()
> arrangement. This allows calling __flush_tlb_range_nosync() to elide the
> trailing DSB. Forthcoming "contpte" code will take advantage of this
> when clearing the young bit from a contiguous range of ptes.
> 
> Ordering between dsb and mmu_notifier_arch_invalidate_secondary_tlbs()
> has changed, but now aligns with the ordering of __flush_tlb_page(). It
> has been discussed that __flush_tlb_page() may be wrong though.
> Regardless, both will be resolved separately if needed.
> 
> Reviewed-by: David Hildenbrand <david at redhat.com>
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From robh at kernel.org  Thu Feb 15 11:26:30 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 13:26:30 -0600
Subject: [PATCH 02/13] dt-bindings: i2c: nomadik: add
 mobileye,eyeq5-i2c bindings and example
In-Reply-To: <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>
Message-ID: <170802518884.600590.10776396012079314632.robh@kernel.org>


On Thu, 15 Feb 2024 17:52:09 +0100, Th?o Lebrun wrote:
> Add EyeQ5 bindings to the existing Nomadik I2C dt-bindings. Add the two
> EyeQ5-specific properties behind a conditional. Add an example for this
> compatible.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  .../devicetree/bindings/i2c/st,nomadik-i2c.yaml    | 44 ++++++++++++++++++++--
>  1 file changed, 40 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/dt-review-ci/linux/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.example.dtb: i2c at 300000: 'mobileye,id', 'mobileye,olb' do not match any of the regexes: '^#.*', '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*', '^(pinctrl-single|#pinctrl-single|PowerPC),.*', '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*', '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^100ask,.*', '^70mai,.*', '^8dev,.*', '^GEFanuc,.*', '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$', '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*', '^acbel,.*', '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*', '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^adieng,.*', '^advantech,.*', '^aeroflexgaisler,.*', '^aesop,.*', '^airoha,.*', '^al,.*', '^alcatel,.*', '^aldec,.*', '^alfa-network,.*', '^allegro
 ,.*', '^alliedvision,.*', '^allo,.*', '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*', '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*', '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^anbernic,.*', '^andestech,.*', '^anvo,.*', '^aosong,.*', '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arcom,.*', '^arctic,.*', '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^arrow,.*', '^artesyn,.*', '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asrock,.*', '^asus,.*', '^atheros,.*', '^atlas,.*', '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*', '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*', '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^belling,.*', '^bhf,.*', '^bigtreetech,.*', '^bitmain,.*', '^blutek,.*', '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bsh,.*', '^bticino,.*', '^buff
 alo,.*', '^bur,.*', '^bytedance,.*', '^calamp,.*', '^calaosystems,.*', '^calxeda,.*', '^canaan,.*', '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*', '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^chargebyte,.*', '^checkpoint,.*', '^chefree,.*', '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chongzhou,.*', '^chrontel,.*', '^chrp,.*', '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^clockwork,.*', '^cloos,.*', '^cloudengines,.*', '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coolpi,.*', '^coreriver,.*', '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*', '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^ctera,.*', '^ctu,.*', '^cubietech,.*', '^cui,.*', '^cypress,.*', '^cyx,.*', '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*', '^densitron,.*', '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*', '^digilent,.*', '^dimonoff,.*', '
 ^diodes,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*', '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^ds,.*', '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebbg,.*', '^ebs-systart,.*', '^ebv,.*', '^eckelmann,.*', '^edgeble,.*', '^edimax,.*', '^edt,.*', '^ees,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*', '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*', '^embedfire,.*', '^embest,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*', '^enclustra,.*', '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^engleder,.*', '^epcos,.*', '^epfl,.*', '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*', '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*', '^facebook,.*', '^fairphone,.*', '^faraday,.*', '^fascontek,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*', '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^
 freecom,.*', '^frida,.*', '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^fxtec,.*', '^galaxycore,.*', '^gardena,.*', '^gateway,.*', '^gateworks,.*', '^gcw,.*', '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^gemtek,.*', '^genesys,.*', '^geniatech,.*', '^giantec,.*', '^giantplus,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goldelico,.*', '^goodix,.*', '^google,.*', '^goramo,.*', '^gplus,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*', '^haochuangyi,.*', '^haoyu,.*', '^hardkernel,.*', '^hechuang,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*', '^hisi,.*', '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*', '^honeywell,.*', '^hoperun,.*', '^hp,.*', '^hpe,.*', '^hsg,.*', '^htc,.*', '^huawei,.*', '^hugsun,.*', '^hwacom,.*', '^hxt,.*', '^hycon,.*', '^hydis,.*', '^hynitron,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*', '^icplus,.*', '^idt,.*', '^ifi,.*', '^ilitek,.*', '^imagis,.*', '^img,.*', '^imi,.*', '^inanbo,
 .*', '^incircuit,.*', '^indiedroid,.*', '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^ingrasys,.*', '^injoinic,.*', '^innocomm,.*', '^innolux,.*', '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*', '^invensense,.*', '^inventec,.*', '^inversepath,.*', '^iom,.*', '^irondevice,.*', '^isee,.*', '^isil,.*', '^issi,.*', '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jadard,.*', '^jasonic,.*', '^jdi,.*', '^jedec,.*', '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^joz,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*', '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*', '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*', '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*', '^lattice,.*', '^lctech,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*', '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,
 .*', '^lineartechnology,.*', '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*', '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*', '^longcheer,.*', '^lontium,.*', '^loongmasses,.*', '^loongson,.*', '^lsi,.*', '^lunzn,.*', '^lwn,.*', '^lxa,.*', '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marantec,.*', '^marvell,.*', '^maxbotix,.*', '^maxim,.*', '^maxlinear,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*', '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*', '^mellanox,.*', '^memsensing,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*', '^methode,.*', '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*', '^microsys,.*', '^mikroe,.*', '^mikrotik,.*', '^milkv,.*', '^miniand,.*', '^minix,.*', '^miramems,.*', '^mitsubishi,.*', '^mitsumi,.*', '^mixel,.*', '^miyoo,.*', '^mntre,.*', '^modtronix,.*', '^moortec,.*', '^mosaixtech,.*', '^motorcomm,.*', '
 ^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*', '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*', '^mxic,.*', '^mxicy,.*', '^myir,.*', '^national,.*', '^nec,.*', '^neonode,.*', '^netgear,.*', '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*', '^newhaven,.*', '^newvision,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*', '^nokia,.*', '^nordic,.*', '^novatek,.*', '^novtech,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*', '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^ocs,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*', '^olpc,.*', '^oneplus,.*', '^onie,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^openailab,.*', '^opencores,.*', '^openembed,.*', '^openpandora,.*', '^openrisc,.*', '^option,.*', '^oranth,.*', '^orisetech,.*', '^ortustech,.*', '^osddisplays,.*', '^osmc,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*', '^ozzmaker,.*', '^panas
 onic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*', '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*', '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*', '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^polyhex,.*', '^portwell,.*', '^poslab,.*', '^pov,.*', '^powertip,.*', '^powervr,.*', '^powkiddy,.*', '^primux,.*', '^probox2,.*', '^prt,.*', '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*', '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^quanta,.*', '^radxa,.*', '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*', '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*', '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*', '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*', '^roseapplepi,.*', '^rve,.*', '^saef,.*', '^samsung,.*', '^samtec,.*', '^sanclo
 ud,.*', '^sandisk,.*', '^satoz,.*', '^sbs,.*', '^schindler,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*', '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sercomm,.*', '^sff,.*', '^sgd,.*', '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shift,.*', '^shimafuji,.*', '^shineworld,.*', '^shiratech,.*', '^si-en,.*', '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*', '^silabs,.*', '^silan,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*', '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*', '^sinowealth,.*', '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*', '^smartlabs,.*', '^smi,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*', '^solomon,.*', '^sony,.*', '^sophgo,.*', '^sourceparts,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*', '^square,.*', '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*'
 , '^starry,.*', '^startek,.*', '^starterkit,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*', '^storopack,.*', '^summit,.*', '^sunchip,.*', '^sundance,.*', '^sunplus,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*', '^synopsys,.*', '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*', '^team-source-display,.*', '^technexion,.*', '^technologic,.*', '^techstar,.*', '^techwell,.*', '^teejet,.*', '^teltonika,.*', '^tempo,.*', '^terasic,.*', '^tesla,.*', '^tfc,.*', '^thead,.*', '^thine,.*', '^thingyjp,.*', '^thundercomm,.*', '^thwc,.*', '^ti,.*', '^tianma,.*', '^tlm,.*', '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*', '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*', '^transpeed,.*', '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^turing,.*', '^tyan,.*', '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ufispace,.*', '^ugoos,.*', '^un
 iwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^usr,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*', '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^vertexcom,.*', '^via,.*', '^vialab,.*', '^vicor,.*', '^videostrong,.*', '^virtio,.*', '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*', '^vocore,.*', '^voipac,.*', '^vot,.*', '^vxt,.*', '^wanchanglong,.*', '^wand,.*', '^waveshare,.*', '^wd,.*', '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*', '^widora,.*', '^wiligear,.*', '^willsemi,.*', '^winbond,.*', '^wingtech,.*', '^winlink,.*', '^winstar,.*', '^wirelesstag,.*', '^wits,.*', '^wlf,.*', '^wm,.*', '^wobo,.*', '^x-powers,.*', '^xen,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*', '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*', '^yadro,.*', '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^yiming,.*', '^ylm,.*', '^yna,.*', '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,
 .*', '^zealz,.*', '^zeitec,.*', '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*', 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/vendor-prefixes.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240215-mbly-i2c-v1-2-19a336e91dca at bootlin.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From conor at kernel.org  Thu Feb 15 11:27:52 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 15 Feb 2024 19:27:52 +0000
Subject: [PATCH] dt-bindings: dma: convert atmel-dma.txt to YAML
In-Reply-To: <20240215-dmac-v1-1-8f1c6f031c98@microchip.com>
References: <20240215-dmac-v1-1-8f1c6f031c98@microchip.com>
Message-ID: <20240215-broken-emu-64a6dabc43e2@spud>

On Thu, Feb 15, 2024 at 04:15:44PM +0530, Durai Manickam KR wrote:
> Added a description, required properties and appropriate compatibles
> for all the SoCs that are supported by microchip.
> 
> Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
> ---
>  .../devicetree/bindings/dma/atmel-dma.txt          | 42 -------------
>  .../bindings/dma/microchip,at91-dma.yaml           | 71 ++++++++++++++++++++++
>  2 files changed, 71 insertions(+), 42 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/dma/atmel-dma.txt b/Documentation/devicetree/bindings/dma/atmel-dma.txt
> deleted file mode 100644
> index f69bcf5a6343..000000000000
> --- a/Documentation/devicetree/bindings/dma/atmel-dma.txt
> +++ /dev/null
> @@ -1,42 +0,0 @@
> -* Atmel Direct Memory Access Controller (DMA)
> -
> -Required properties:
> -- compatible: Should be "atmel,<chip>-dma".
> -- reg: Should contain DMA registers location and length.
> -- interrupts: Should contain DMA interrupt.
> -- #dma-cells: Must be <2>, used to represent the number of integer cells in
> -the dmas property of client devices.
> -
> -Example:
> -
> -dma0: dma at ffffec00 {
> -	compatible = "atmel,at91sam9g45-dma";
> -	reg = <0xffffec00 0x200>;
> -	interrupts = <21>;
> -	#dma-cells = <2>;
> -};
> -
> -DMA clients connected to the Atmel DMA controller must use the format
> -described in the dma.txt file, using a three-cell specifier for each channel:
> -a phandle plus two integer cells.
> -The three cells in order are:
> -
> -1. A phandle pointing to the DMA controller.
> -2. The memory interface (16 most significant bits), the peripheral interface
> -(16 less significant bits).
> -3. Parameters for the at91 DMA configuration register which are device
> -dependent:
> -  - bit 7-0: peripheral identifier for the hardware handshaking interface. The
> -  identifier can be different for tx and rx.
> -  - bit 11-8: FIFO configuration. 0 for half FIFO, 1 for ALAP, 2 for ASAP.
> -
> -Example:
> -
> -i2c0 at i2c@f8010000 {
> -	compatible = "atmel,at91sam9x5-i2c";
> -	reg = <0xf8010000 0x100>;
> -	interrupts = <9 4 6>;
> -	dmas = <&dma0 1 7>,
> -	       <&dma0 1 8>;
> -	dma-names = "tx", "rx";
> -};
> diff --git a/Documentation/devicetree/bindings/dma/microchip,at91-dma.yaml b/Documentation/devicetree/bindings/dma/microchip,at91-dma.yaml
> new file mode 100644
> index 000000000000..a0a582902e4d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/microchip,at91-dma.yaml

Filename matching the compatible please.

> @@ -0,0 +1,71 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/dma/microchip,at91-dma.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Atmel Direct Memory Access Controller (DMA)
> +
> +maintainers:
> +  - Ludovic Desroches <ludovic.desroches at microchip.com>
> +  - Tudor Ambarus <tudor.ambarus at linaro.org>
> +
> +description: |

The | is not needed.

> +  The Atmel Direct Memory Access Controller (DMAC) transfers data from a source
> +  peripheral to a destination peripheral over one or more AMBA buses. One channel
> +  is required for each source/destination pair. In the most basic configuration,
> +  the DMAC has one master interface and one channel. The master interface reads
> +  the data from a source and writes it to a destination. Two AMBA transfers are
> +  required for each DMAC data transfer. This is also known as a dual-access transfer.
> +  The DMAC is programmed via the APB interface.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - enum:
> +          - atmel,at91sam9g45-dma
> +          - atmel,at91sam9rl-dma
> +  reg:
> +    description: Should contain DMA registers location and length.

Drop the description from these common properties.

> +    maxItems: 1
> +
> +  interrupts:
> +    description: Should contain the DMA interrupts associated to the DMA channels.
> +    maxItems: 1
> +
> +  "#dma-cells":
> +    description:
> +      Must be <2>, used to represent the number of integer cells in the dmas
> +      property of client devices.

You've lost the description of how these cells work, which is somewhat
unique and needs to be preserved.
This is the only property that needs a description.

> +    const: 2
> +
> +  clocks:
> +    description: Should contain a clock specifier for each entry in clock-names.
> +    maxItems: 1
> +
> +  clock-names:
> +    description: Should contain the clock of the DMA controller.
> +    const: dma_clk

This is a new addition? You should call out in the commit message wat
you've added that was not in th text binding.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - "#dma-cells"
> +  - clocks
> +  - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    dma0: dma-controller at ffffec00 {

Drop the label, its not used.

Thanks,
Conor.

> +            compatible = "atmel,at91sam9g45-dma";
> +            reg = <0xffffec00 0x200>;
> +            interrupts = <21>;
> +            #dma-cells = <2>;
> +            clocks = <&pmc 2 20>;
> +            clock-names = "dma_clk";
> +    };
> +
> +...
> 
> ---
> base-commit: 7e90b5c295ec1e47c8ad865429f046970c549a66
> change-id: 20240214-dmac-5f48fd7f3b9d
> 
> Best regards,
> -- 
> Durai Manickam KR <durai.manickamkr at microchip.com>
> 
-------------- 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/20240215/c6bb389a/attachment.sig>

From fancer.lancer at gmail.com  Thu Feb 15 11:32:18 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 15 Feb 2024 22:32:18 +0300
Subject: [PATCH v9 1/4] serial: 8250: Add 8250 port clock update method
In-Reply-To: <ZczD7KPbeRnY4CFc@black.fi.intel.com>
References: <20200723003357.26897-1-Sergey.Semin@baikalelectronics.ru>
 <20200723003357.26897-2-Sergey.Semin@baikalelectronics.ru>
 <ZczD7KPbeRnY4CFc@black.fi.intel.com>
Message-ID: <raryiklwhctwxcfj3ulbnjcl32owagiccmxpwzmszlh3vm343y@h2ehupm7uiga>

Hi Andy,

On Wed, Feb 14, 2024 at 03:45:16PM +0200, Andy Shevchenko wrote:
> On Thu, Jul 23, 2020 at 03:33:54AM +0300, Serge Semin wrote:
> > Some platforms can be designed in a way so the UART port reference clock
> > might be asynchronously changed at some point. In Baikal-T1 SoC this may
> > happen due to the reference clock being shared between two UART ports, on
> > the Allwinner SoC the reference clock is derived from the CPU clock, so
> > any CPU frequency change should get to be known/reflected by/in the UART
> > controller as well. But it's not enough to just update the
> > uart_port->uartclk field of the corresponding UART port, the 8250
> > controller reference clock divisor should be altered so to preserve
> > current baud rate setting. All of these things is done in a coherent
> > way by calling the serial8250_update_uartclk() method provided in this
> > patch. Though note that it isn't supposed to be called from within the
> > UART port callbacks because the locks using to the protect the UART port
> > data are already taken in there.
> 
> ...
> 
> > +/*
> > + * Note in order to avoid the tty port mutex deadlock don't use the next method
> > + * within the uart port callbacks. Primarily it's supposed to be utilized to
> > + * handle a sudden reference clock rate change.
> > + */
> > +void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk)
> > +{
> > +	struct uart_8250_port *up = up_to_u8250p(port);
> > +	unsigned int baud, quot, frac = 0;
> > +	struct ktermios *termios;
> > +	unsigned long flags;
> > +
> > +	mutex_lock(&port->state->port.mutex);
> > +
> > +	if (port->uartclk == uartclk)
> > +		goto out_lock;
> > +
> > +	port->uartclk = uartclk;
> > +	termios = &port->state->port.tty->termios;
> > +
> > +	baud = serial8250_get_baud_rate(port, termios, NULL);
> > +	quot = serial8250_get_divisor(port, baud, &frac);
> > +
> > +	serial8250_rpm_get(up);
> > +	spin_lock_irqsave(&port->lock, flags);
> > +
> > +	uart_update_timeout(port, termios->c_cflag, baud);
> > +
> > +	serial8250_set_divisor(port, baud, quot, frac);
> > +	serial_port_out(port, UART_LCR, up->lcr);
> > +	serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
> > +
> > +	spin_unlock_irqrestore(&port->lock, flags);
> > +	serial8250_rpm_put(up);
> > +
> > +out_lock:
> > +	mutex_unlock(&port->state->port.mutex);
> 

> While looking for something else I have stumbled over this function.
> My Q is, since it has some duplications with
> serial8250_do_set_termios(), can we actually call the latter (or
> derevative that can be called in both) in the above code instead of
> duplicating some lines?
> 
> 	if (port UART clock has to be updated)
> 	  call (unlocked version of) serial8250_do_set_termios()
> 
> Serge, what do you think?

What an old thread you've digged out.)

Well, AFAIR I didn't create a common baud-rate/clock-update method
because the baud-rate change was just a two stages action:
1. calculate divisor+quot couple based on the new clock,
2. update the divisor+quot (+ update the timeout).
The first stage didn't need to have the IRQsafe lock being held and
the runtime-PM being enabled, meanwhile the later one needed those.
So unless the nested locking or try-lock-based pattern is implemented
each stage required dedicated function introduced, which would have
been an overkill for that. But even if I got to implement the
try-lock-based solution with a single function containing both stages
I still couldn't avoid having the serial8250_get_baud_rate() and
serial8250_get_divisor() methods executed in the atomic context, which
isn't required for them and which would needlessly pro-long the CPU
executing with the IRQs disabled. As you well know it's better to
speed up the atomic context execution as much as possible. 

Secondly I didn't know much about the tty/serial subsystem internals
back then. So I was afraid to break some parts I didn't aware of if
the baud-rate/ref-clock change code had some implicit dependencies
from the surrounding code and vice-versa (like the LCR DLAB flag
state).

Finally frankly it didn't seem like that much worth bothering about.
Basically AFAICS there were only four methods which invocation I
would have needed to move to a separate function:

serial8250_get_baud_rate();
serial8250_get_divisor();
// spin-lock
uart_update_timeout(port, termios->c_cflag, baud);
serial8250_set_divisor(port, baud, quot, frac);
// spin-unlock

So I decided to take a simplest and safest path, and created a
dedicated method for the just the ref-clock updates case leaving the
baud-rate change task implemented in the framework of the standard
serial8250_do_set_termios() method.


Regarding doing vise-versa and calling the serial8250_do_set_termios()
method from serial8250_update_uartclk() instead. To be honest I didn't
consider that option. That might work though, but AFAICS the
serial8250_do_set_termios() function will do much more than it's
required in case if the ref-clock has changed.

-Serge(y)

> 
> > +}
> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
> 


From conor at kernel.org  Thu Feb 15 11:34:39 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 15 Feb 2024 19:34:39 +0000
Subject: [PATCH] dt-bindings: dma: convert atmel-xdma.txt to YAML
In-Reply-To: <20240215-xdma-v1-1-1139960cf096@microchip.com>
References: <20240215-xdma-v1-1-1139960cf096@microchip.com>
Message-ID: <20240215-snowstorm-quack-fdb7f9c35c2e@spud>

On Thu, Feb 15, 2024 at 04:25:15PM +0530, Durai Manickam KR wrote:
> Added a description, required properties and appropriate compatibles
> for all the SoCs that are supported by microchip for the XDMAC.
> 
> Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
> ---
>  .../devicetree/bindings/dma/atmel-xdma.txt         | 54 ---------------
>  .../bindings/dma/microchip,at91-xdma.yaml          | 77 ++++++++++++++++++++++
>  2 files changed, 77 insertions(+), 54 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/dma/atmel-xdma.txt b/Documentation/devicetree/bindings/dma/atmel-xdma.txt
> deleted file mode 100644
> index 76d649b3a25d..000000000000
> --- a/Documentation/devicetree/bindings/dma/atmel-xdma.txt
> +++ /dev/null
> @@ -1,54 +0,0 @@
> -* Atmel Extensible Direct Memory Access Controller (XDMAC)
> -
> -* XDMA Controller

> -- interrupts: Should contain DMA interrupt.
> -- #dma-cells: Must be <1>, used to represent the number of integer cells in
> -the dmas property of client devices.
> -  - The 1st cell specifies the channel configuration register:
> -    - bit 13: SIF, source interface identifier, used to get the memory
> -    interface identifier,
> -    - bit 14: DIF, destination interface identifier, used to get the peripheral
> -    interface identifier,
> -    - bit 30-24: PERID, peripheral identifier.
> -
> -Example:
> -
> -dma1: dma-controller at f0004000 {
> -	compatible = "atmel,sama5d4-dma";
> -	reg = <0xf0004000 0x200>;
> -	interrupts = <50 4 0>;
> -	#dma-cells = <1>;
> -};
> -
> -
> -* DMA clients
> -DMA clients connected to the Atmel XDMA controller must use the format
> -described in the dma.txt file, using a one-cell specifier for each channel.
> -The two cells in order are:
> -1. A phandle pointing to the DMA controller.
> -2. Channel configuration register. Configurable fields are:
> -    - bit 13: SIF, source interface identifier, used to get the memory
> -    interface identifier,
> -    - bit 14: DIF, destination interface identifier, used to get the peripheral
> -    interface identifier,
> -  - bit 30-24: PERID, peripheral identifier.
> -
> -Example:
> -
> -i2c2: i2c at f8024000 {
> -	compatible = "atmel,at91sam9x5-i2c";
> -	reg = <0xf8024000 0x4000>;
> -	interrupts = <34 4 6>;
> -	dmas = <&dma1
> -		(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
> -		 | AT91_XDMAC_DT_PERID(6))>,
> -	       <&dma1
> -		(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
> -		| AT91_XDMAC_DT_PERID(7))>;
> -	dma-names = "tx", "rx";
> -};
> diff --git a/Documentation/devicetree/bindings/dma/microchip,at91-xdma.yaml b/Documentation/devicetree/bindings/dma/microchip,at91-xdma.yaml
> new file mode 100644
> index 000000000000..0bd79c7b5e6f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/microchip,at91-xdma.yaml
> @@ -0,0 +1,77 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/dma/microchip,at91-xdma.yaml#

Filename matching a compatible please.

> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Atmel Extensible Direct Memory Access Controller (XDMAC)
> +
> +maintainers:
> +  - Durai Manickam KR <durai.manickamkr at microchip.com>
> +
> +description: |

The | is not needed, you've no formatting to preserve.

> +  The Atmel Extensible Direct Memory Access Controller (XDMAC) performs peripheral
> +  data transfer and memory move operations over one or two bus ports through the
> +  unidirectional communication channel. Each channel is fully programmable and
> +  provides both peripheral or memory-to-memory transfers.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - enum:
> +          - atmel,sama5d4-dma
> +          - microchip,sama7g5-dma
> +          - microchip,sam9x7-dma

The text binding says:
> -- compatible: Should be "atmel,sama5d4-dma", "microchip,sam9x60-dma" or
> -  "microchip,sama7g5-dma" or
> -  "microchip,sam9x7-dma", "atmel,sama5d4-dma".
That's not what you have here at all.

> +      - items:
> +          - const: atmel,sama5d4-dma
> +          - const: microchip,sam9x60-dma

This looks backwards.

> +  reg:
> +    description: Should contain DMA registers location and length.
> +    maxItems: 1

Same comments here about descriptions for well known properties as the
other DMA controller.

> +
> +  interrupts:
> +    description: Should contain the DMA interrupts associated to the DMA channels.
> +    maxItems: 1
> +
> +  "#dma-cells":
> +    description: |
> +      Must be <1>, used to represent the number of integer cells in the dmas
> +      property of client device.
> +      -The 1st cell specifies the channel configuration register:
> +      -bit 13: SIF, source interface identifier, used to get the memory
> +               interface identifier,
> +      -bit 14: DIF, destination interface identifier, used to get the peripheral
> +               interface identifier,
> +      -bit 30-24: PERID, peripheral identifier.
> +    const: 1
> +
> +  clocks:
> +    description: Should contain a clock specifier for each entry in clock-names.
> +    maxItems: 1

And here about adding properties. Please explain in your commit message
where the new properties came from.

> +
> +  clock-names:
> +    description: Should contain the clock of the DMA controller.
> +    const: dma_clk
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - "#dma-cells"
> +  - clocks
> +  - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    dma0: dma-controller at f0004000 {

And same here about the label :)

Cheers,
Conor.

> +            compatible = "atmel,sama5d4-dma";
> +            reg = <0xffffec00 0x200>;
> +            interrupts = <50 4 0>;
> +            #dma-cells = <1>;
> +            clocks = <&pmc 2 20>;
> +            clock-names = "dma_clk";
> +    };
> +
> +...
> 
> ---
> base-commit: 8d3dea210042f54b952b481838c1e7dfc4ec751d
> change-id: 20240215-xdma-36e8bdbf8141
> 
> Best regards,
> -- 
> Durai Manickam KR <durai.manickamkr at microchip.com>
> 
-------------- 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/20240215/a3368862/attachment-0001.sig>

From andriy.shevchenko at linux.intel.com  Thu Feb 15 11:39:12 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 15 Feb 2024 21:39:12 +0200
Subject: [PATCH v9 1/4] serial: 8250: Add 8250 port clock update method
In-Reply-To: <raryiklwhctwxcfj3ulbnjcl32owagiccmxpwzmszlh3vm343y@h2ehupm7uiga>
References: <20200723003357.26897-1-Sergey.Semin@baikalelectronics.ru>
 <20200723003357.26897-2-Sergey.Semin@baikalelectronics.ru>
 <ZczD7KPbeRnY4CFc@black.fi.intel.com>
 <raryiklwhctwxcfj3ulbnjcl32owagiccmxpwzmszlh3vm343y@h2ehupm7uiga>
Message-ID: <Zc5oYJY6W_MCpwhN@smile.fi.intel.com>

On Thu, Feb 15, 2024 at 10:32:18PM +0300, Serge Semin wrote:
> On Wed, Feb 14, 2024 at 03:45:16PM +0200, Andy Shevchenko wrote:
> > On Thu, Jul 23, 2020 at 03:33:54AM +0300, Serge Semin wrote:
> > > Some platforms can be designed in a way so the UART port reference clock
> > > might be asynchronously changed at some point. In Baikal-T1 SoC this may
> > > happen due to the reference clock being shared between two UART ports, on
> > > the Allwinner SoC the reference clock is derived from the CPU clock, so
> > > any CPU frequency change should get to be known/reflected by/in the UART
> > > controller as well. But it's not enough to just update the
> > > uart_port->uartclk field of the corresponding UART port, the 8250
> > > controller reference clock divisor should be altered so to preserve
> > > current baud rate setting. All of these things is done in a coherent
> > > way by calling the serial8250_update_uartclk() method provided in this
> > > patch. Though note that it isn't supposed to be called from within the
> > > UART port callbacks because the locks using to the protect the UART port
> > > data are already taken in there.

...

> > > +/*
> > > + * Note in order to avoid the tty port mutex deadlock don't use the next method
> > > + * within the uart port callbacks. Primarily it's supposed to be utilized to
> > > + * handle a sudden reference clock rate change.
> > > + */
> > > +void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk)
> > > +{
> > > +	struct uart_8250_port *up = up_to_u8250p(port);
> > > +	unsigned int baud, quot, frac = 0;
> > > +	struct ktermios *termios;
> > > +	unsigned long flags;
> > > +
> > > +	mutex_lock(&port->state->port.mutex);
> > > +
> > > +	if (port->uartclk == uartclk)
> > > +		goto out_lock;
> > > +
> > > +	port->uartclk = uartclk;
> > > +	termios = &port->state->port.tty->termios;
> > > +
> > > +	baud = serial8250_get_baud_rate(port, termios, NULL);
> > > +	quot = serial8250_get_divisor(port, baud, &frac);
> > > +
> > > +	serial8250_rpm_get(up);
> > > +	spin_lock_irqsave(&port->lock, flags);
> > > +
> > > +	uart_update_timeout(port, termios->c_cflag, baud);
> > > +
> > > +	serial8250_set_divisor(port, baud, quot, frac);
> > > +	serial_port_out(port, UART_LCR, up->lcr);
> > > +	serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
> > > +
> > > +	spin_unlock_irqrestore(&port->lock, flags);
> > > +	serial8250_rpm_put(up);
> > > +
> > > +out_lock:
> > > +	mutex_unlock(&port->state->port.mutex);
> > 
> 
> > While looking for something else I have stumbled over this function.
> > My Q is, since it has some duplications with
> > serial8250_do_set_termios(), can we actually call the latter (or
> > derevative that can be called in both) in the above code instead of
> > duplicating some lines?
> > 
> > 	if (port UART clock has to be updated)
> > 	  call (unlocked version of) serial8250_do_set_termios()
> > 
> > Serge, what do you think?
> 
> What an old thread you've digged out.)

Indeed :-)

> Well, AFAIR I didn't create a common baud-rate/clock-update method
> because the baud-rate change was just a two stages action:
> 1. calculate divisor+quot couple based on the new clock,
> 2. update the divisor+quot (+ update the timeout).
> The first stage didn't need to have the IRQsafe lock being held and
> the runtime-PM being enabled, meanwhile the later one needed those.
> So unless the nested locking or try-lock-based pattern is implemented
> each stage required dedicated function introduced, which would have
> been an overkill for that. But even if I got to implement the
> try-lock-based solution with a single function containing both stages
> I still couldn't avoid having the serial8250_get_baud_rate() and
> serial8250_get_divisor() methods executed in the atomic context, which
> isn't required for them and which would needlessly pro-long the CPU
> executing with the IRQs disabled. As you well know it's better to
> speed up the atomic context execution as much as possible. 
> 
> Secondly I didn't know much about the tty/serial subsystem internals
> back then. So I was afraid to break some parts I didn't aware of if
> the baud-rate/ref-clock change code had some implicit dependencies
> from the surrounding code and vice-versa (like the LCR DLAB flag
> state).
> 
> Finally frankly it didn't seem like that much worth bothering about.
> Basically AFAICS there were only four methods which invocation I
> would have needed to move to a separate function:
> 
> serial8250_get_baud_rate();
> serial8250_get_divisor();
> // spin-lock
> uart_update_timeout(port, termios->c_cflag, baud);
> serial8250_set_divisor(port, baud, quot, frac);
> // spin-unlock
> 
> So I decided to take a simplest and safest path, and created a
> dedicated method for the just the ref-clock updates case leaving the
> baud-rate change task implemented in the framework of the standard
> serial8250_do_set_termios() method.
> 
> 
> Regarding doing vise-versa and calling the serial8250_do_set_termios()
> method from serial8250_update_uartclk() instead. To be honest I didn't
> consider that option. That might work though, but AFAICS the
> serial8250_do_set_termios() function will do much more than it's
> required in case if the ref-clock has changed.

My point here is that the idea behind clock change is most likely to be
followed up by ->set_termios(). Why to do it differently if it's the case?
And note, ->set_termios() can be called as many times as needed, so if nothing
changes in between it's also fine. But this makes intention much clearer.
Do you agree?

-- 
With Best Regards,
Andy Shevchenko




From charles.perry at savoirfairelinux.com  Thu Feb 15 11:42:13 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Thu, 15 Feb 2024 14:42:13 -0500 (EST)
Subject: [PATCH v3 2/5] dt-bindings: fpga: xlnx,fpga-slave-serial:
 rename gpios
In-Reply-To: <20240215133240.GA4061942-robh@kernel.org>
References: <20240207180142.79625-1-charles.perry@savoirfairelinux.com> <20240207180142.79625-3-charles.perry@savoirfairelinux.com> <20240215133240.GA4061942-robh@kernel.org>
Message-ID: <747282644.1027419.1708026133594.JavaMail.zimbra@savoirfairelinux.com>

On Feb 15, 2024, at 8:32 AM, Rob Herring robh at kernel.org wrote:
> On Wed, Feb 07, 2024 at 01:01:25PM -0500, Charles Perry wrote:
>> By convention, gpio consumer names should not contain underscores
>> (prog_b here) and shouldn't contain active low suffixes (-b here).
> 
> Yes, that is the preference, but we are stuck with supporting the old
> name. It is not worth it to carry both in the binding and kernel.
> 
> Rob

Ok, I'll go back to "prog_b", "init-b" and drop patch 2 and 3 for v4.

Regards,
Charles


From tglx at linutronix.de  Thu Feb 15 11:59:48 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Thu, 15 Feb 2024 20:59:48 +0100
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <CAK9=C2WsSSHgDF+7ruxx_QF0Lk+Dsx2F2Y-_NabnxrJ_qWhgGQ@mail.gmail.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <CAK9=C2Vwtj2gZg-P73yLMxu0rPXQ3YrRRuxq6HcpHMXgs-jHaw@mail.gmail.com>
 <87bk8ig6t2.ffs@tglx>
 <CAK9=C2WsSSHgDF+7ruxx_QF0Lk+Dsx2F2Y-_NabnxrJ_qWhgGQ@mail.gmail.com>
Message-ID: <87v86pcxcb.ffs@tglx>

Anup!

On Thu, Feb 15 2024 at 11:18, Anup Patel wrote:
> On Thu, Feb 15, 2024 at 1:24?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>> Thanks for picking this up and driving it forward!
>
> Thanks Thomas, I will be sending v13 of this series next week.
>
> For the time being, I will carry the 13 infrastructure patches in
> this series until they land in upstream Linux so that it is easier
> for people to try this series.

I pushed out the lot on top of 6.8-rc4 (no other changes) to

     git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/msi

with some minimal changes (DEVICE_IMS -> DEVICE_MSI, removal of an
unused interface).

I'm going over the rest of the series after I dealt with my other patch
backlog.

Thanks,

        tglx



From rafael at kernel.org  Thu Feb 15 12:10:39 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 15 Feb 2024 21:10:39 +0100
Subject: [PATCH RFC v4 01/15] ACPI: Only enumerate enabled (or functional)
 processor devices
In-Reply-To: <E1rVDmP-0027YJ-EW@rmk-PC.armlinux.org.uk>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk> <E1rVDmP-0027YJ-EW@rmk-PC.armlinux.org.uk>
Message-ID: <CAJZ5v0hY_LXp41WMVPhiLosPe7YVzF38Uz=EhmJqVwqFn==Upw@mail.gmail.com>

On Wed, Jan 31, 2024 at 5:49?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:
>
> From: James Morse <james.morse at arm.com>
>
> Today the ACPI enumeration code 'visits' all devices that are present.
>
> This is a problem for arm64, where CPUs are always present, but not
> always enabled. When a device-check occurs because the firmware-policy
> has changed and a CPU is now enabled, the following error occurs:
> | acpi ACPI0007:48: Enumeration failure
>
> This is ultimately because acpi_dev_ready_for_enumeration() returns
> true for a device that is not enabled. The ACPI Processor driver
> will not register such CPUs as they are not 'decoding their resources'.
>
> ACPI allows a device to be functional instead of maintaining the
> present and enabled bit, but we can't simply check the enabled bit
> for all devices since firmware can be buggy.
>
> If ACPI indicates that the device is present and enabled, then all well
> and good, we can enumate it. However, if the device is present and not
> enabled, then we also check whether the device is a processor device
> to limit the impact of this new check to just processor devices.
>
> This avoids enumerating present && functional processor devices that
> are not enabled.
>
> Signed-off-by: James Morse <james.morse at arm.com>
> Co-developed-by: Rafael J. Wysocki <rjw at rjwysocki.net>
> Tested-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
> Changes since RFC v2:
>  * Incorporate comment suggestion by Gavin Shan.
> Changes since RFC v3:
>  * Fixed "sert" typo.
> Changes since RFC v3 (smaller series):
>  * Restrict checking the enabled bit to processor devices, update
>    commit comments.
>  * Use Rafael's suggestion in
>    https://lore.kernel.org/r/5760569.DvuYhMxLoT at kreacher
>  * Updated with a fix - see:
>    https://lore.kernel.org/all/Zbe8WQRASx6D6RaG at shell.armlinux.org.uk/
> ---
>  drivers/acpi/acpi_processor.c | 11 +++++++++
>  drivers/acpi/device_pm.c      |  2 +-
>  drivers/acpi/device_sysfs.c   |  2 +-
>  drivers/acpi/internal.h       |  4 ++-
>  drivers/acpi/property.c       |  2 +-
>  drivers/acpi/scan.c           | 46 +++++++++++++++++++++++++++--------
>  6 files changed, 53 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> index 4fe2ef54088c..cf7c1cca69dd 100644
> --- a/drivers/acpi/acpi_processor.c
> +++ b/drivers/acpi/acpi_processor.c
> @@ -626,6 +626,17 @@ static struct acpi_scan_handler processor_handler = {
>         },
>  };
>
> +bool acpi_device_is_processor(const struct acpi_device *adev)
> +{
> +       if (adev->device_type == ACPI_BUS_TYPE_PROCESSOR)
> +               return true;
> +
> +       if (adev->device_type != ACPI_BUS_TYPE_DEVICE)
> +               return false;
> +
> +       return acpi_scan_check_handler(adev, &processor_handler);
> +}
> +
>  static int acpi_processor_container_attach(struct acpi_device *dev,
>                                            const struct acpi_device_id *id)
>  {
> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
> index 3b4d048c4941..e3c80f3b3b57 100644
> --- a/drivers/acpi/device_pm.c
> +++ b/drivers/acpi/device_pm.c
> @@ -313,7 +313,7 @@ int acpi_bus_init_power(struct acpi_device *device)
>                 return -EINVAL;
>
>         device->power.state = ACPI_STATE_UNKNOWN;
> -       if (!acpi_device_is_present(device)) {
> +       if (!acpi_dev_ready_for_enumeration(device)) {
>                 device->flags.initialized = false;
>                 return -ENXIO;
>         }
> diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c
> index 23373faa35ec..a0256d2493a7 100644
> --- a/drivers/acpi/device_sysfs.c
> +++ b/drivers/acpi/device_sysfs.c
> @@ -141,7 +141,7 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia
>         struct acpi_hardware_id *id;
>
>         /* Avoid unnecessarily loading modules for non present devices. */
> -       if (!acpi_device_is_present(acpi_dev))
> +       if (!acpi_dev_ready_for_enumeration(acpi_dev))
>                 return 0;
>
>         /*
> diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
> index 6588525c45ef..1bc8b6db60c5 100644
> --- a/drivers/acpi/internal.h
> +++ b/drivers/acpi/internal.h
> @@ -62,6 +62,8 @@ void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
>  int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler,
>                                        const char *hotplug_profile_name);
>  void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val);
> +bool acpi_scan_check_handler(const struct acpi_device *adev,
> +                            struct acpi_scan_handler *handler);
>
>  #ifdef CONFIG_DEBUG_FS
>  extern struct dentry *acpi_debugfs_dir;
> @@ -121,7 +123,6 @@ int acpi_device_setup_files(struct acpi_device *dev);
>  void acpi_device_remove_files(struct acpi_device *dev);
>  void acpi_device_add_finalize(struct acpi_device *device);
>  void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
> -bool acpi_device_is_present(const struct acpi_device *adev);
>  bool acpi_device_is_battery(struct acpi_device *adev);
>  bool acpi_device_is_first_physical_node(struct acpi_device *adev,
>                                         const struct device *dev);
> @@ -133,6 +134,7 @@ int acpi_bus_register_early_device(int type);
>  const struct acpi_device *acpi_companion_match(const struct device *dev);
>  int __acpi_device_uevent_modalias(const struct acpi_device *adev,
>                                   struct kobj_uevent_env *env);
> +bool acpi_device_is_processor(const struct acpi_device *adev);
>
>  /* --------------------------------------------------------------------------
>                                    Power Resource
> diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
> index a6ead5204046..9f8d54038770 100644
> --- a/drivers/acpi/property.c
> +++ b/drivers/acpi/property.c
> @@ -1486,7 +1486,7 @@ static bool acpi_fwnode_device_is_available(const struct fwnode_handle *fwnode)
>         if (!is_acpi_device_node(fwnode))
>                 return false;
>
> -       return acpi_device_is_present(to_acpi_device_node(fwnode));
> +       return acpi_dev_ready_for_enumeration(to_acpi_device_node(fwnode));
>  }
>
>  static const void *
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index e6ed1ba91e5c..fd2e8b3a5749 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -304,7 +304,7 @@ static int acpi_scan_device_check(struct acpi_device *adev)
>         int error;
>
>         acpi_bus_get_status(adev);
> -       if (acpi_device_is_present(adev)) {
> +       if (acpi_dev_ready_for_enumeration(adev)) {
>                 /*
>                  * This function is only called for device objects for which
>                  * matching scan handlers exist.  The only situation in which
> @@ -338,7 +338,7 @@ static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used)
>         int error;
>
>         acpi_bus_get_status(adev);
> -       if (!acpi_device_is_present(adev)) {
> +       if (!acpi_dev_ready_for_enumeration(adev)) {
>                 acpi_scan_device_not_enumerated(adev);
>                 return 0;
>         }
> @@ -1917,11 +1917,6 @@ static bool acpi_device_should_be_hidden(acpi_handle handle)
>         return true;
>  }
>
> -bool acpi_device_is_present(const struct acpi_device *adev)
> -{
> -       return adev->status.present || adev->status.functional;
> -}
> -
>  static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
>                                        const char *idstr,
>                                        const struct acpi_device_id **matchid)
> @@ -1942,6 +1937,18 @@ static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
>         return false;
>  }
>
> +bool acpi_scan_check_handler(const struct acpi_device *adev,
> +                            struct acpi_scan_handler *handler)
> +{
> +       struct acpi_hardware_id *hwid;
> +
> +       list_for_each_entry(hwid, &adev->pnp.ids, list)
> +               if (acpi_scan_handler_matching(handler, hwid->id, NULL))
> +                       return true;
> +
> +       return false;
> +}
> +
>  static struct acpi_scan_handler *acpi_scan_match_handler(const char *idstr,
>                                         const struct acpi_device_id **matchid)
>  {
> @@ -2405,16 +2412,35 @@ EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
>   * acpi_dev_ready_for_enumeration - Check if the ACPI device is ready for enumeration
>   * @device: Pointer to the &struct acpi_device to check
>   *
> - * Check if the device is present and has no unmet dependencies.
> + * Check if the device is functional or enabled and has no unmet dependencies.
>   *
> - * Return true if the device is ready for enumeratino. Otherwise, return false.
> + * Return true if the device is ready for enumeration. Otherwise, return false.
>   */
>  bool acpi_dev_ready_for_enumeration(const struct acpi_device *device)
>  {
>         if (device->flags.honor_deps && device->dep_unmet)
>                 return false;
>
> -       return acpi_device_is_present(device);
> +       /*
> +        * ACPI 6.5's 6.3.7 "_STA (Device Status)" allows firmware to return
> +        * (!present && functional) for certain types of devices that should be
> +        * enumerated. Note that the enabled bit should not be set unless the
> +        * present bit is set.
> +        *
> +        * However, limit this only to processor devices to reduce possible
> +        * regressions with firmware.
> +        */
> +       if (!device->status.present)
> +               return device->status.functional;
> +
> +       /*
> +        * Fast path - if enabled is set, avoid the more expensive test to
> +        * check whether this device is a processor.
> +        */
> +       if (device->status.enabled)
> +               return true;
> +
> +       return !acpi_device_is_processor(device);
>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
>
> --

I can queue this up for 6.9 as it looks like the rest of the series
will still need some work.  What do you think?


From robin.murphy at arm.com  Thu Feb 15 12:11:38 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 15 Feb 2024 20:11:38 +0000
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <02fac0ab-07ac-448e-ae4e-26788ed4fce9@arm.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240215134952.GA690@willie-the-truck> <20240215160135.GL1088888@nvidia.com>
 <02fac0ab-07ac-448e-ae4e-26788ed4fce9@arm.com>
Message-ID: <a0c62629-999f-4aa1-86c7-3104811f84d0@arm.com>

On 2024-02-15 6:42 pm, Robin Murphy wrote:
[...]
>>>> +static void arm_smmu_get_ste_used(const __le64 *ent, __le64 
>>>> *used_bits)
>>>> ? {
>>>> +??? unsigned int cfg = FIELD_GET(STRTAB_STE_0_CFG, 
>>>> le64_to_cpu(ent[0]));
>>>> +
>>>> +??? used_bits[0] = cpu_to_le64(STRTAB_STE_0_V);
>>>> +??? if (!(ent[0] & cpu_to_le64(STRTAB_STE_0_V)))
>>>> +??????? return;
>>>> +
>>>> +??? /*
>>>> +???? * See 13.5 Summary of attribute/permission configuration 
>>>> fields for the
>>>> +???? * SHCFG behavior. It is only used for BYPASS, including S1DSS 
>>>> BYPASS,
>>>> +???? * and S2 only.
>>>> +???? */
>>>> +??? if (cfg == STRTAB_STE_0_CFG_BYPASS ||
>>>> +??????? cfg == STRTAB_STE_0_CFG_S2_TRANS ||
>>>> +??????? (cfg == STRTAB_STE_0_CFG_S1_TRANS &&
>>>> +???????? FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
>>>> +???????????? STRTAB_STE_1_S1DSS_BYPASS))
>>>> +??????? used_bits[1] |= cpu_to_le64(STRTAB_STE_1_SHCFG);
>>>
>>> Huh, SHCFG is really getting in the way here, isn't it?
>>
>> I wouldn't say that.. It is just a complicated bit of the spec. One of
>> the things we recently did was to audit all the cache settings and, at
>> least, we then realized that SHCFG was being subtly used by S2 as
>> well..
> 
> Yeah, that really shouldn't be subtle; incoming attributes are replaced 
> by S1 translation, thus they are relevant to not-S1 configs.

That said, in this specific case I don't understand why we're worrying 
about SHCFG here at all - we're never going to make use of any value 
other than "use incoming" because we can't rely on it being implemented 
in the first place, and even if it is, we really don't want to start 
getting into the forced-coherency notion that the DMA layer can'#t 
understand and devicetree can't describe.

We're still unconditionally setting the "use incoming" value for MTCFG, 
ALLOCCFG, PRIVCFG and INSTCFG without checking them, so there's no logic 
in pretending SHCFG is any different from its peers simply because its 
encoding is slightly less convenient. If the micro-optimisation of not 
setting it when we know it's going to be ignored anyway starts getting 
in the way, just drop that.

Thanks,
Robin.


From umang.jain at ideasonboard.com  Thu Feb 15 12:44:33 2024
From: umang.jain at ideasonboard.com (Umang Jain)
Date: Fri, 16 Feb 2024 02:14:33 +0530
Subject: [PATCH 0/2] media: i2c: Add imx283 camera sensor driver
Message-ID: <20240215204436.9194-1-umang.jain@ideasonboard.com>

Add a v4l2 subdevice driver for the Sony IMX283 image sensor.
  
The IMX283 is a 20MP Diagonal 15.86 mm (Type 1) CMOS Image Sensor with
Square Pixel for Color Cameras.
    
The following features are supported:
- Manual exposure an gain control support
- vblank/hblank/link freq control support
- Test pattern support control
- Arbitrary horizontal and vertical cropping
- Supported resolution:
   - 5472x3648 @ 20fps (SRGGB12)
   - 5472x3648 @ 25fps (SRGGB10)
   - 2736x1824 @ 50fps (SRGGB12)

The driver is tested on mainline branch v6.8-rc2 on IMX8MP Debix-SOM-A.
Additional testing has been done on RPi5 with the downstream BSP.

In the driver, CENTERED_RECTANGLE macro is defined to center the crop
rectangle. Possibly that should be removed, and a V4L2 helper can be
introduced if more use cases are identified.

Kieran Bingham (1):
  media: i2c: Add imx283 camera sensor driver

Umang Jain (1):
  media: dt-bindings: media: Add bindings for IMX283

 .../bindings/media/i2c/sony,imx283.yaml       |  100 +
 MAINTAINERS                                   |    9 +
 drivers/media/i2c/Kconfig                     |   13 +
 drivers/media/i2c/Makefile                    |    1 +
 drivers/media/i2c/imx283.c                    | 1601 +++++++++++++++++
 5 files changed, 1724 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
 create mode 100644 drivers/media/i2c/imx283.c

-- 
2.43.0



From umang.jain at ideasonboard.com  Thu Feb 15 12:44:34 2024
From: umang.jain at ideasonboard.com (Umang Jain)
Date: Fri, 16 Feb 2024 02:14:34 +0530
Subject: [PATCH 1/2] media: dt-bindings: media: Add bindings for IMX283
In-Reply-To: <20240215204436.9194-1-umang.jain@ideasonboard.com>
References: <20240215204436.9194-1-umang.jain@ideasonboard.com>
Message-ID: <20240215204436.9194-2-umang.jain@ideasonboard.com>

- Add dt-bindings documentation for Sony IMX283 sensor driver
- Add MAINTAINERS entry for Sony IMX283 binding documentation

Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
---
 .../bindings/media/i2c/sony,imx283.yaml       | 100 ++++++++++++++++++
 MAINTAINERS                                   |   8 ++
 2 files changed, 108 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml

diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
new file mode 100644
index 000000000000..3cf46429b282
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024 Ideas on Board Oy
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/sony,imx283.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sony IMX283 Sensor
+
+maintainers:
+  - Kieran Bingham <kieran.bingham at ideasonboard.com>
+  - Umang Jain <umang.jain at ideasonboard.com>
+
+description:
+  IMX283 sensor is a Sony CMOS active pixel digital image sensor with an active
+  array size of 5472H x 3648V. It is programmable through I2C interface. The
+  I2C client address is fixed to 0x1a as per sensor data sheet. Image data is
+  sent through MIPI CSI-2.
+
+properties:
+  compatible:
+    const: sony,imx283
+  reg:
+    description: I2C address
+    maxItems: 1
+
+  assigned-clocks: true
+  assigned-clock-parents: true
+  assigned-clock-rates: true
+
+  clocks:
+    description: Clock frequency from 6 to 24 MHz.
+    maxItems: 1
+
+  vana-supply:
+    description: Analog power supply (2.9V)
+
+  vdig-supply:
+    description: Interface power supply (1.8V)
+
+  vddl-supply:
+    description: Digital power supply (1.2V)
+
+  port:
+    additionalProperties: false
+    $ref: /schemas/graph.yaml#/$defs/port-base
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          data-lanes: true
+          link-frequencies: true
+
+        required:
+          - data-lanes
+          - link-frequencies
+
+    required:
+      - endpoint
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        camera at 1a {
+            compatible = "sony,imx283";
+            reg = <0x1a>;
+            clocks = <&imx283_clk>;
+
+            assigned-clocks = <&imx283_clk>;
+            assigned-clock-parents = <&imx283_clk_parent>;
+            assigned-clock-rates = <12000000>;
+
+            vadd-supply = <&camera_vadd_2v9>;
+            vdd1-supply = <&camera_vdd1_1v8>;
+            vdd2-supply = <&camera_vdd2_1v2>;
+
+            port {
+                imx283: endpoint {
+                    remote-endpoint = <&cam>;
+                    data-lanes = <1 2 3 4>;
+                    link-frequencies = /bits/ 64 <360000000>;
+                };
+            };
+        };
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 8999497011a2..53df4b6e3260 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20366,6 +20366,14 @@ T:	git git://linuxtv.org/media_tree.git
 F:	Documentation/devicetree/bindings/media/i2c/sony,imx274.yaml
 F:	drivers/media/i2c/imx274.c
 
+SONY IMX283 SENSOR DRIVER
+M:	Kieran Bingham <kieran.bingham at ideasonboard.com>
+M:	Umang Jain <umang.jain at ideasonboard.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+T:	git git://linuxtv.org/media_tree.git
+F:	Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
+
 SONY IMX290 SENSOR DRIVER
 M:	Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
 L:	linux-media at vger.kernel.org
-- 
2.43.0



From umang.jain at ideasonboard.com  Thu Feb 15 12:44:35 2024
From: umang.jain at ideasonboard.com (Umang Jain)
Date: Fri, 16 Feb 2024 02:14:35 +0530
Subject: [PATCH 2/2] media: i2c: Add imx283 camera sensor driver
In-Reply-To: <20240215204436.9194-1-umang.jain@ideasonboard.com>
References: <20240215204436.9194-1-umang.jain@ideasonboard.com>
Message-ID: <20240215204436.9194-3-umang.jain@ideasonboard.com>

From: Kieran Bingham <kieran.bingham at ideasonboard.com>

Add a v4l2 subdevice driver for the Sony IMX283 image sensor.

The IMX283 is a 20MP Diagonal 15.86 mm (Type 1) CMOS Image Sensor with
Square Pixel for Color Cameras.

The following features are supported:
- Manual exposure an gain control support
- vblank/hblank/link freq control support
- Test pattern support control
- Arbitrary horizontal and vertical cropping
- Supported resolution:
  - 5472x3648 @ 20fps (SRGGB12)
  - 5472x3648 @ 25fps (SRGGB10)
  - 2736x1824 @ 50fps (SRGGB12)

Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
---
 MAINTAINERS                |    1 +
 drivers/media/i2c/Kconfig  |   13 +
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/imx283.c | 1601 ++++++++++++++++++++++++++++++++++++
 4 files changed, 1616 insertions(+)
 create mode 100644 drivers/media/i2c/imx283.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 53df4b6e3260..3826e5c5d746 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20373,6 +20373,7 @@ L:	linux-media at vger.kernel.org
 S:	Maintained
 T:	git git://linuxtv.org/media_tree.git
 F:	Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
+F:	drivers/media/i2c/imx283.c
 
 SONY IMX290 SENSOR DRIVER
 M:	Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 56f276b920ab..b798c55a2be5 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -153,6 +153,19 @@ config VIDEO_IMX274
 	  This is a V4L2 sensor driver for the Sony IMX274
 	  CMOS image sensor.
 
+config VIDEO_IMX283
+	tristate "Sony IMX283 sensor support"
+	depends on I2C && VIDEO_DEV
+	select MEDIA_CONTROLLER
+	select VIDEO_V4L2_SUBDEV_API
+	select V4L2_CCI_I2C
+	help
+	  This is a V4L2 sensor driver for the Sony IMX283
+	  CMOS image sensor.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called imx283.
+
 config VIDEO_IMX290
 	tristate "Sony IMX290 sensor support"
 	select REGMAP_I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index dfbe6448b549..0fbd81f9f420 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_VIDEO_IMX214) += imx214.o
 obj-$(CONFIG_VIDEO_IMX219) += imx219.o
 obj-$(CONFIG_VIDEO_IMX258) += imx258.o
 obj-$(CONFIG_VIDEO_IMX274) += imx274.o
+obj-$(CONFIG_VIDEO_IMX283) += imx283.o
 obj-$(CONFIG_VIDEO_IMX290) += imx290.o
 obj-$(CONFIG_VIDEO_IMX296) += imx296.o
 obj-$(CONFIG_VIDEO_IMX319) += imx319.o
diff --git a/drivers/media/i2c/imx283.c b/drivers/media/i2c/imx283.c
new file mode 100644
index 000000000000..52fafea18e7a
--- /dev/null
+++ b/drivers/media/i2c/imx283.c
@@ -0,0 +1,1601 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * V4L2 Support for the IMX283
+ *
+ * Diagonal 15.86 mm (Type 1) CMOS Image Sensor with Square Pixel for Color
+ * Cameras.
+ *
+ * Copyright (C) 2024 Ideas on Board Oy.
+ *
+ * Based on Sony IMX283 driver prepared by Will Whang
+ *
+ * Based on Sony imx477 camera driver
+ * Copyright (C) 2019-2020 Raspberry Pi (Trading) Ltd
+ */
+
+#include <asm/unaligned.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mediabus.h>
+
+/* Chip ID */
+#define IMX283_REG_CHIP_ID		CCI_REG8(0x3000)
+#define IMX283_CHIP_ID			0x0b	// Default power on state
+
+#define IMX283_REG_STANDBY		CCI_REG8(0x3000)
+#define   IMX283_ACTIVE			0
+#define   IMX283_STANDBY		BIT(0)
+#define   IMX283_STBLOGIC		BIT(1)
+#define   IMX283_STBMIPI		BIT(2)
+#define   IMX283_STBDV			BIT(3)
+#define   IMX283_SLEEP			BIT(4)
+
+#define IMX283_REG_CLAMP		CCI_REG8(0x3001)
+#define   IMX283_CLPSQRST		BIT(4)
+
+#define IMX283_REG_PLSTMG08		CCI_REG8(0x3003)
+#define   IMX283_PLSTMG08_VAL		0x77
+
+#define IMX283_REG_MDSEL1		CCI_REG8(0x3004)
+#define IMX283_REG_MDSEL2		CCI_REG8(0x3005)
+#define IMX283_REG_MDSEL3		CCI_REG8(0x3006)
+#define   IMX283_MDSEL3_VCROP_EN	BIT(5)
+#define IMX283_REG_MDSEL4		CCI_REG8(0x3007)
+#define   IMX283_MDSEL4_VCROP_EN	(BIT(4) | BIT(6))
+
+#define IMX283_REG_SVR			CCI_REG16_LE(0x3009)
+
+#define IMX283_REG_HTRIMMING		CCI_REG8(0x300b)
+#define   IMX283_MDVREV			BIT(0) /* VFLIP */
+#define   IMX283_HTRIMMING_EN		BIT(4)
+
+#define IMX283_REG_VWINPOS		CCI_REG16_LE(0x300f)
+#define IMX283_REG_VWIDCUT		CCI_REG16_LE(0x3011)
+
+#define IMX283_REG_MDSEL7		CCI_REG16_LE(0x3013)
+
+/* CSI Clock Configuration */
+#define IMX283_REG_TCLKPOST		CCI_REG8(0x3018)
+#define IMX283_REG_THSPREPARE		CCI_REG8(0x301a)
+#define IMX283_REG_THSZERO		CCI_REG8(0x301c)
+#define IMX283_REG_THSTRAIL		CCI_REG8(0x3020)
+#define IMX283_REG_TCLKPREPARE		CCI_REG8(0x3022)
+#define IMX283_REG_TCLKZERO		CCI_REG16_LE(0x3024)
+#define IMX283_REG_TLPX			CCI_REG8(0x3026)
+#define IMX283_REG_THSEXIT		CCI_REG8(0x3028)
+#define IMX283_REG_TCLKPRE		CCI_REG8(0x302a)
+
+#define IMX283_REG_Y_OUT_SIZE		CCI_REG16_LE(0x302f)
+#define IMX283_REG_WRITE_VSIZE		CCI_REG16_LE(0x3031)
+#define IMX283_REG_OB_SIZE_V		CCI_REG8(0x3033)
+
+/* HMAX internal HBLANK */
+#define IMX283_REG_HMAX			CCI_REG16_LE(0x3036)
+#define IMX283_HMAX_MAX			0xffff
+
+/* VMAX internal VBLANK */
+#define IMX283_REG_VMAX			CCI_REG24_LE(0x3038)
+#define   IMX283_VMAX_MAX		0xfffff
+
+/* SHR internal */
+#define IMX283_REG_SHR			CCI_REG16_LE(0x303b)
+#define   IMX283_SHR_MIN		11
+
+/*
+ * Analog gain control
+ *  Gain [dB] = -20log{(2048 - value [10:0]) /2048}
+ *  Range: 0dB to approximately +27dB
+ */
+#define IMX283_REG_ANALOG_GAIN		CCI_REG16_LE(0x3042)
+#define   IMX283_ANA_GAIN_MIN		0
+#define   IMX283_ANA_GAIN_MAX		1957
+#define   IMX283_ANA_GAIN_STEP		1
+#define   IMX283_ANA_GAIN_DEFAULT	0x0
+
+/*
+ * Digital gain control
+ *  Gain [dB] = value * 6
+ *  Range: 0dB to +18db
+ */
+#define IMX283_REG_DIGITAL_GAIN		CCI_REG8(0x3044)
+#define IMX283_DGTL_GAIN_MIN		0
+#define IMX283_DGTL_GAIN_MAX		3
+#define IMX283_DGTL_GAIN_DEFAULT	0
+#define IMX283_DGTL_GAIN_STEP		1
+
+#define IMX283_REG_HTRIMMING_START	CCI_REG16_LE(0x3058)
+#define IMX283_REG_HTRIMMING_END	CCI_REG16_LE(0x305a)
+
+#define IMX283_REG_MDSEL18		CCI_REG16_LE(0x30f6)
+
+/* Master Mode Operation Control */
+#define IMX283_REG_XMSTA		CCI_REG8(0x3105)
+#define   IMX283_XMSTA			BIT(0)
+
+#define IMX283_REG_SYNCDRV		CCI_REG8(0x3107)
+#define   IMX283_SYNCDRV_XHS_XVS	(0xa0 | 0x02)
+#define   IMX283_SYNCDRV_HIZ		(0xa0 | 0x03)
+
+/* PLL Standby */
+#define IMX283_REG_STBPL		CCI_REG8(0x320b)
+#define  IMX283_STBPL_NORMAL		0x00
+#define  IMX283_STBPL_STANDBY		0x03
+
+/* Input Frequency Setting */
+#define IMX283_REG_PLRD1		CCI_REG8(0x36c1)
+#define IMX283_REG_PLRD2		CCI_REG16_LE(0x36c2)
+#define IMX283_REG_PLRD3		CCI_REG8(0x36f7)
+#define IMX283_REG_PLRD4		CCI_REG8(0x36f8)
+
+#define IMX283_REG_PLSTMG02		CCI_REG8(0x36aa)
+#define   IMX283_PLSTMG02_VAL		0x00
+
+#define IMX283_REG_EBD_X_OUT_SIZE	CCI_REG16_LE(0x3a54)
+
+/* Test pattern generator */
+#define IMX283_REG_TPG_CTRL		CCI_REG8(0x3156)
+#define   IMX283_TPG_CTRL_CLKEN		BIT(0)
+#define   IMX283_TPG_CTRL_PATEN		BIT(4)
+
+#define IMX283_REG_TPG_PAT		CCI_REG8(0x3157)
+#define   IMX283_TPG_PAT_ALL_000	0x00
+#define   IMX283_TPG_PAT_ALL_FFF	0x01
+#define   IMX283_TPG_PAT_ALL_555	0x02
+#define   IMX283_TPG_PAT_ALL_AAA	0x03
+#define   IMX283_TPG_PAT_H_COLOR_BARS	0x0a
+#define   IMX283_TPG_PAT_V_COLOR_BARS	0x0b
+
+/* Exposure control */
+#define IMX283_EXPOSURE_MIN		52
+#define IMX283_EXPOSURE_STEP		1
+#define IMX283_EXPOSURE_DEFAULT		1000
+#define IMX283_EXPOSURE_MAX		49865
+
+/* Embedded metadata stream structure */
+#define IMX283_EMBEDDED_LINE_WIDTH 16384
+#define IMX283_NUM_EMBEDDED_LINES 1
+
+#define MHZ(x)				((x) * 1000 * 1000)
+#define IMAGE_PAD			0
+
+#define imx283_XCLR_MIN_DELAY_US	1000
+#define imx283_XCLR_DELAY_RANGE_US	1000
+
+/* IMX283 native and active pixel array size. */
+static const struct v4l2_rect imx283_native_area = {
+	.top = 0,
+	.left = 0,
+	.width = 5592,
+	.height = 3710,
+};
+
+static const struct v4l2_rect imx283_active_area = {
+	.top = 40,
+	.left = 108,
+	.width = 5472,
+	.height = 3648,
+};
+
+struct IMX283_reg_list {
+	unsigned int num_of_regs;
+	const struct cci_reg_sequence *regs;
+};
+
+/* Mode : resolution and related config values */
+struct imx283_mode {
+	unsigned int mode;
+
+	/* Bits per pixel */
+	unsigned int bpp;
+
+	/* Frame width */
+	unsigned int width;
+
+	/* Frame height */
+	unsigned int height;
+
+	/*
+	 * Minimum horizontal timing in pixel-units
+	 *
+	 * Note that HMAX is written in 72MHz units, and the datasheet assumes a
+	 * 720MHz link frequency. Convert datasheet values with the following:
+	 *
+	 * For 12 bpp modes (480Mbps) convert with:
+	 *   hmax = [hmax in 72MHz units] * 480 / 72
+	 *
+	 * For 10 bpp modes (576Mbps) convert with:
+	 *   hmax = [hmax in 72MHz units] * 576 / 72
+	 */
+	u64 min_hmax;
+
+	/* minimum V-timing in lines */
+	u64 min_vmax;
+
+	/* default H-timing */
+	u64 default_hmax;
+
+	/* default V-timing */
+	u64 default_vmax;
+
+	/* minimum SHR */
+	u64 min_shr;
+
+	/* Abritrary vertical cropping */
+	u32 veff;
+	u32 vst;
+	u32 vct;
+
+	/* Horizontal and vertical binning ratio */
+	u8 hbin_ratio;
+	u8 vbin_ratio;
+
+	/* Optical Blanking */
+	u32 horizontal_ob;
+	u32 vertical_ob;
+
+	/* Analog crop rectangle. */
+	struct v4l2_rect crop;
+};
+
+struct imx283_input_frequency {
+	unsigned int mhz;
+	unsigned int reg_count;
+	struct cci_reg_sequence regs[4];
+};
+
+static const struct imx283_input_frequency imx283_frequencies[] = {
+	{
+		.mhz = MHZ(6),
+		.reg_count = 4,
+		.regs = {
+			{ IMX283_REG_PLRD1, 0x00 },
+			{ IMX283_REG_PLRD2, 0x00f0 },
+			{ IMX283_REG_PLRD3, 0x00 },
+			{ IMX283_REG_PLRD4, 0xc0 },
+		},
+	},
+	{
+		.mhz = MHZ(12),
+		.reg_count = 4,
+		.regs = {
+			{ IMX283_REG_PLRD1, 0x01 },
+			{ IMX283_REG_PLRD2, 0x00f0 },
+			{ IMX283_REG_PLRD3, 0x01 },
+			{ IMX283_REG_PLRD4, 0xc0 },
+		},
+	},
+	{
+		.mhz = MHZ(18),
+		.reg_count = 4,
+		.regs = {
+			{ IMX283_REG_PLRD1, 0x01 },
+			{ IMX283_REG_PLRD2, 0x00a0 },
+			{ IMX283_REG_PLRD3, 0x01 },
+			{ IMX283_REG_PLRD4, 0x80 },
+		},
+	},
+	{
+		.mhz = MHZ(24),
+		.reg_count = 4,
+		.regs = {
+			{ IMX283_REG_PLRD1, 0x02 },
+			{ IMX283_REG_PLRD2, 0x00f0 },
+			{ IMX283_REG_PLRD3, 0x02 },
+			{ IMX283_REG_PLRD4, 0xc0 },
+		},
+	},
+};
+
+enum imx283_modes {
+	IMX283_MODE_0,
+	IMX283_MODE_1,
+	IMX283_MODE_1A,
+	IMX283_MODE_1S,
+	IMX283_MODE_2,
+	IMX283_MODE_2A,
+	IMX283_MODE_3,
+	IMX283_MODE_4,
+	IMX283_MODE_5,
+	IMX283_MODE_6,
+};
+
+struct imx283_readout_mode {
+	u64 mdsel1;
+	u64 mdsel2;
+	u64 mdsel3;
+	u64 mdsel4;
+};
+
+static const struct imx283_readout_mode imx283_readout_modes[] = {
+	/* All pixel scan modes */
+	[IMX283_MODE_0] = { 0x04, 0x03, 0x10, 0x00 }, /* 12 bit */
+	[IMX283_MODE_1] = { 0x04, 0x01, 0x00, 0x00 }, /* 10 bit */
+	[IMX283_MODE_1A] = { 0x04, 0x01, 0x20, 0x50 }, /* 10 bit */
+	[IMX283_MODE_1S] = { 0x04, 0x41, 0x20, 0x50 }, /* 10 bit */
+
+	/* Horizontal / Vertical 2/2-line binning */
+	[IMX283_MODE_2] = { 0x0d, 0x11, 0x50, 0x00 }, /* 12 bit */
+	[IMX283_MODE_2A] = { 0x0d, 0x11, 0x70, 0x50 }, /* 12 bit */
+
+	/* Horizontal / Vertical 3/3-line binning */
+	[IMX283_MODE_3] = { 0x1e, 0x18, 0x10, 0x00 }, /* 12 bit */
+
+	/* Veritcal 2/9 subsampling, horizontal 3 binning cropping */
+	[IMX283_MODE_4] = { 0x29, 0x18, 0x30, 0x50 }, /* 12 bit */
+
+	/* Vertical 2/19 subsampling binning, horizontal 3 binning */
+	[IMX283_MODE_5] = { 0x2d, 0x18, 0x10, 0x00 }, /* 12 bit */
+
+	/* Vertical 2 binning horizontal 2/4, subsampling 16:9 cropping */
+	[IMX283_MODE_6] = { 0x18, 0x21, 0x00, 0x09 }, /* 10 bit */
+};
+
+static const struct cci_reg_sequence mipi_data_rate_1440Mbps[] = {
+	/* The default register settings provide the 1440Mbps rate */
+	{ CCI_REG8(0x36c5), 0x00 }, /* Undocumented */
+	{ CCI_REG8(0x3ac4), 0x00 }, /* Undocumented */
+
+	{ CCI_REG8(0x320B), 0x00 }, /* STBPL */
+	{ CCI_REG8(0x3018), 0xa7 }, /* TCLKPOST */
+	{ CCI_REG8(0x301A), 0x6f }, /* THSPREPARE */
+	{ CCI_REG8(0x301C), 0x9f }, /* THSZERO */
+	{ CCI_REG8(0x301E), 0x5f }, /* THSTRAIL */
+	{ CCI_REG8(0x3020), 0x5f }, /* TCLKTRAIL */
+	{ CCI_REG8(0x3022), 0x6f }, /* TCLKPREPARE */
+	{ CCI_REG8(0x3024), 0x7f }, /* TCLKZERO[7:0] */
+	{ CCI_REG8(0x3025), 0x01 }, /* TCLKZERO[8] */
+	{ CCI_REG8(0x3026), 0x4f }, /* TLPX*/
+	{ CCI_REG8(0x3028), 0x47 }, /* THSEXIT */
+	{ CCI_REG8(0x302A), 0x07 }, /* TCKLPRE */
+	{ CCI_REG8(0x3104), 0x02 }, /* SYSMODE */
+};
+
+static const struct cci_reg_sequence mipi_data_rate_720Mbps[] = {
+	/* Undocumented Additions "For 720MBps" Setting */
+	{ CCI_REG8(0x36c5), 0x01 }, /* Undocumented */
+	{ CCI_REG8(0x3ac4), 0x01 }, /* Undocumented */
+
+	{ CCI_REG8(0x320B), 0x00 }, /* STBPL */
+	{ CCI_REG8(0x3018), 0x77 }, /* TCLKPOST */
+	{ CCI_REG8(0x301A), 0x37 }, /* THSPREPARE */
+	{ CCI_REG8(0x301C), 0x67 }, /* THSZERO */
+	{ CCI_REG8(0x301E), 0x37 }, /* THSTRAIL */
+	{ CCI_REG8(0x3020), 0x37 }, /* TCLKTRAIL */
+	{ CCI_REG8(0x3022), 0x37 }, /* TCLKPREPARE */
+	{ CCI_REG8(0x3024), 0xDF }, /* TCLKZERO[7:0] */
+	{ CCI_REG8(0x3025), 0x00 }, /* TCLKZERO[8] */
+	{ CCI_REG8(0x3026), 0x2F }, /* TLPX*/
+	{ CCI_REG8(0x3028), 0x47 }, /* THSEXIT */
+	{ CCI_REG8(0x302A), 0x0F }, /* TCKLPRE */
+	{ CCI_REG8(0x3104), 0x02 }, /* SYSMODE */
+};
+
+static const s64 link_frequencies[] = {
+	MHZ(720), /* 1440 Mbps lane data rate */
+	MHZ(360), /* 720 Mbps data lane rate */
+};
+
+static const struct IMX283_reg_list link_freq_reglist[] = {
+	{ /* MHZ(720)*/
+		.num_of_regs = ARRAY_SIZE(mipi_data_rate_1440Mbps),
+		.regs = mipi_data_rate_1440Mbps,
+	},
+	{ /* MHZ(360) */
+		.num_of_regs = ARRAY_SIZE(mipi_data_rate_720Mbps),
+		.regs = mipi_data_rate_720Mbps,
+	},
+};
+
+#define CENTERED_RECTANGLE(rect, _width, _height) \
+	{ \
+		.left = rect.left + ((rect.width - (_width)) / 2), \
+		.top = rect.top + ((rect.height - (_height)) / 2), \
+		.width = (_width), \
+		.height = (_height), \
+	}
+
+/* Mode configs */
+static const struct imx283_mode supported_modes_12bit[] = {
+	{
+		/* 20MPix 21.40 fps readout mode 0 */
+		.mode = IMX283_MODE_0,
+		.bpp = 12,
+		.width = 5472,
+		.height = 3648,
+		.min_hmax = 5914, /* 887 @ 480MHz/72MHz */
+		.min_vmax = 3793, /* Lines */
+
+		.veff = 3694,
+		.vst = 0,
+		.vct = 0,
+
+		.hbin_ratio = 1,
+		.vbin_ratio = 1,
+
+		/* 20.00 FPS */
+		.default_hmax = 6000, /* 900 @ 480MHz/72MHz */
+		.default_vmax = 4000,
+
+		.min_shr = 11,
+		.horizontal_ob = 96,
+		.vertical_ob = 16,
+		.crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
+	},
+	{
+		/*
+		 * Readout mode 2 : 2/2 binned mode (2736x1824)
+		 */
+		.mode = IMX283_MODE_2,
+		.bpp = 12,
+		.width = 2736,
+		.height = 1824,
+		.min_hmax = 1870, /* Pixels (362 * 360/72 + padding) */
+		.min_vmax = 3840, /* Lines */
+
+		/* 50.00 FPS */
+		.default_hmax = 1870, /* 362 @ 360MHz/72MHz */
+		.default_vmax = 3960,
+
+		.veff = 1824,
+		.vst = 0,
+		.vct = 0,
+
+		.hbin_ratio = 2,
+		.vbin_ratio = 2,
+
+		.min_shr = 12,
+		.horizontal_ob = 48,
+		.vertical_ob = 4,
+
+		.crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
+	},
+};
+
+static const struct imx283_mode supported_modes_10bit[] = {
+	{
+		/* 20MPix 25.48 fps readout mode 1 */
+		.mode = IMX283_MODE_1,
+		.bpp = 10,
+		.width = 5472,
+		.height = 3648,
+		.min_hmax = 5960, /* 745 @ 576MHz / 72MHz */
+		.min_vmax = 3793,
+
+		/* 25.00 FPS */
+		.default_hmax = 1500, /* 750 @ 576MHz / 72MHz */
+		.default_vmax = 3840,
+
+		.min_shr = 10,
+		.horizontal_ob = 96,
+		.vertical_ob = 16,
+		.crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
+	},
+};
+
+/*
+ * The supported mbus formats.
+ */
+static const u32 codes[] = {
+	/* 12-bit modes. */
+	MEDIA_BUS_FMT_SRGGB12_1X12,
+
+	/* 10-bit modes. */
+	MEDIA_BUS_FMT_SRGGB10_1X10,
+};
+
+/* regulator supplies */
+static const char *const imx283_supply_name[] = {
+	"vana", /* Analog (2.9V) supply */
+	"vdig", /* Supply Voltage 2 (1.8V) supply */
+	"vddl", /* Supply Voltage 3 (1.2V) supply */
+};
+
+
+struct imx283 {
+	struct device *dev;
+	struct regmap *cci;
+
+	const struct imx283_input_frequency *freq;
+
+	struct v4l2_subdev sd;
+	struct media_pad pad;
+
+	unsigned int fmt_code;
+
+	struct clk *xclk;
+
+	struct gpio_desc *reset_gpio;
+	struct regulator_bulk_data supplies[ARRAY_SIZE(imx283_supply_name)];
+
+	/* V4L2 Controls */
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *link_freq;
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *hblank;
+	struct v4l2_ctrl *vflip;
+
+	struct mutex mutex;
+
+	/* Current mode */
+	const struct imx283_mode *mode;
+
+	unsigned long link_freq_bitmap;
+
+	u16 hmax;
+	u32 vmax;
+};
+
+static inline struct imx283 *to_imx283(struct v4l2_subdev *_sd)
+{
+	return container_of(_sd, struct imx283, sd);
+}
+
+static inline void get_mode_table(unsigned int code,
+				  const struct imx283_mode **mode_list,
+				  unsigned int *num_modes)
+{
+	switch (code) {
+	/* 12-bit */
+	case MEDIA_BUS_FMT_SRGGB12_1X12:
+	case MEDIA_BUS_FMT_SGRBG12_1X12:
+	case MEDIA_BUS_FMT_SGBRG12_1X12:
+	case MEDIA_BUS_FMT_SBGGR12_1X12:
+		*mode_list = supported_modes_12bit;
+		*num_modes = ARRAY_SIZE(supported_modes_12bit);
+		break;
+	/* 10-bit */
+	case MEDIA_BUS_FMT_SRGGB10_1X10:
+	case MEDIA_BUS_FMT_SGRBG10_1X10:
+	case MEDIA_BUS_FMT_SGBRG10_1X10:
+	case MEDIA_BUS_FMT_SBGGR10_1X10:
+		*mode_list = supported_modes_10bit;
+		*num_modes = ARRAY_SIZE(supported_modes_10bit);
+		break;
+	default:
+		*mode_list = NULL;
+		*num_modes = 0;
+	}
+}
+
+/* Calculate the Pixel Rate based on the current mode */
+static u64 imx283_pixel_rate(struct imx283 *imx283)
+{
+	const struct imx283_mode *mode = imx283->mode;
+	unsigned int bpp = mode->bpp;
+
+	const unsigned int ddr = 2; /* Double Data Rate */
+	const unsigned int lanes = 4; /* Only 4 lane support */
+
+	u64 link_frequency = link_frequencies[__ffs(imx283->link_freq_bitmap)];
+	u64 pixel_rate = link_frequency * ddr * lanes / bpp;
+
+	return pixel_rate;
+}
+
+/* Convert from a variable pixel_rate to 72 MHz clock cycles */
+static u64 imx283_internal_clock(unsigned int pixel_rate, unsigned int pixels)
+{
+	/*
+	 * Determine the following operation without overflow:
+	 *    pixels * MHZ(72) / pixel_rate
+	 *
+	 * The internal clock at 72MHz and Pixel Rate (between 240 and 576MHz)
+	 * can easily overflow this calculation, so pre-divide to simplify.
+	 */
+	const u32 iclk_pre = MHZ(72) / 1000000;
+	const u32 pclk_pre = pixel_rate / 1000000;
+
+	return pixels * iclk_pre / pclk_pre;
+}
+
+/* Internal clock (72MHz) to Pixel Rate clock (Variable) */
+static u64 imx283_iclk_to_pix(unsigned int pixel_rate, unsigned int cycles)
+{
+	/*
+	 * Determine the following operation without overflow:
+	 *    cycles * pixel_rate / MHZ(72)
+	 *
+	 * The internal clock at 72MHz and Pixel Rate (between 240 and 576MHz)
+	 * can easily overflow this calculation, so pre-divide to simplify.
+	 */
+	const u32 iclk_pre = MHZ(72) / 1000000;
+	const u32 pclk_pre = pixel_rate / 1000000;
+
+	return cycles * pclk_pre / iclk_pre;
+}
+
+/* Determine the exposure based on current hmax, vmax and a given SHR */
+static u64 imx283_exposure(struct imx283 *imx283, u64 shr)
+{
+	u32 svr = 0; /* SVR feature is not currently supported */
+	u32 hmax = imx283->hmax;
+	u64 vmax = imx283->vmax;
+	u32 offset;
+	u64 numerator;
+
+	/* Number of clocks per internal offset period */
+	offset = imx283->mode->mode == IMX283_MODE_0 ? 209 : 157;
+	numerator = (vmax * (svr + 1) - shr) * hmax + offset;
+
+	do_div(numerator, hmax);
+	numerator = clamp_t(u32, numerator, 0, 0xFFFFFFFF);
+	return numerator;
+}
+
+static void imx283_exposure_limits(struct imx283 *imx283,
+				   u64 *min_exposure, u64 *max_exposure)
+{
+	u64 vmax = imx283->vmax;
+	u32 svr = 0; /* SVR feature is not currently supported */
+	u64 min_shr = imx283->mode->min_shr;
+	u64 max_shr = (svr + 1) * vmax - 4; /* Global Shutter is not supported */
+
+	max_shr = min_t(u64, max_shr, 0xFFFF);
+
+	*min_exposure = imx283_exposure(imx283, max_shr);
+	*max_exposure = imx283_exposure(imx283, min_shr);
+}
+
+/*
+ * Integration Time [s] = [{VMAX x (SVR + 1) ? (SHR)} x HMAX + offset]
+ *                      / (72 x 10^6)
+ */
+static u32 imx283_shr(struct imx283 *imx283, u32 exposure)
+{
+	u32 svr = 0; /* SVR feature is not currently supported */
+	u32 hmax = imx283->hmax;
+	u64 vmax = imx283->vmax;
+	u32 shr;
+	u64 temp;
+
+	/* Number of clocks per internal offset period */
+	u32 offset = imx283->mode->mode == IMX283_MODE_0 ? 209 : 157;
+
+	temp = ((u64)exposure * hmax - offset);
+	do_div(temp, hmax);
+	shr = (u32)(vmax * (svr + 1) - temp);
+
+	return shr;
+}
+
+static const char * const imx283_tpg_menu[] = {
+	"Disabled",
+	"All 000h",
+	"All FFFh",
+	"All 555h",
+	"All AAAh",
+	"Horizontal color bars",
+	"Vertical color bars",
+};
+
+static const int imx283_tpg_val[] = {
+	IMX283_TPG_PAT_ALL_000,
+	IMX283_TPG_PAT_ALL_000,
+	IMX283_TPG_PAT_ALL_FFF,
+	IMX283_TPG_PAT_ALL_555,
+	IMX283_TPG_PAT_ALL_AAA,
+	IMX283_TPG_PAT_H_COLOR_BARS,
+	IMX283_TPG_PAT_V_COLOR_BARS,
+};
+
+static int imx283_update_test_pattern(struct imx283 *imx283, u32 pattern_index)
+{
+	int ret;
+
+	if (pattern_index >= ARRAY_SIZE(imx283_tpg_val))
+		return -EINVAL;
+
+	if (pattern_index) {
+		ret = cci_write(imx283->cci, IMX283_REG_TPG_PAT,
+				imx283_tpg_val[pattern_index], NULL);
+		if (ret)
+			return ret;
+
+		ret = cci_write(imx283->cci, IMX283_REG_TPG_CTRL,
+				IMX283_TPG_CTRL_CLKEN | IMX283_TPG_CTRL_PATEN, NULL);
+	} else {
+		ret = cci_write(imx283->cci, IMX283_REG_TPG_CTRL, 0x00, NULL);
+	}
+
+	return ret;
+}
+
+static int imx283_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct imx283 *imx283 = container_of(ctrl->handler, struct imx283,
+					     ctrl_handler);
+	const struct imx283_mode *mode = imx283->mode;
+	u64 shr, pixel_rate;
+	int ret = 0;
+
+	/*
+	 * The VBLANK control may change the limits of usable exposure, so check
+	 * and adjust if necessary.
+	 */
+	if (ctrl->id == V4L2_CID_VBLANK) {
+		/* Honour the VBLANK limits when setting exposure. */
+		u64 current_exposure, max_exposure, min_exposure;
+
+		imx283->vmax = mode->height + ctrl->val;
+
+		imx283_exposure_limits(imx283, &min_exposure, &max_exposure);
+
+		current_exposure = imx283->exposure->val;
+		current_exposure = clamp_t(u32, current_exposure, min_exposure,
+					   max_exposure);
+
+		__v4l2_ctrl_modify_range(imx283->exposure, min_exposure,
+					 max_exposure, 1, current_exposure);
+	}
+
+	/*
+	 * Applying V4L2 control value only happens
+	 * when power is up for streaming
+	 */
+	if (pm_runtime_get_if_in_use(imx283->dev) == 0)
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		shr = imx283_shr(imx283, ctrl->val);
+		dev_dbg(imx283->dev, "V4L2_CID_EXPOSURE : %d - SHR: %lld\n",
+			ctrl->val, shr);
+		ret = cci_write(imx283->cci, IMX283_REG_SHR, shr, NULL);
+		break;
+
+	case V4L2_CID_HBLANK:
+		pixel_rate = imx283_pixel_rate(imx283);
+		imx283->hmax = imx283_internal_clock(pixel_rate, mode->width + ctrl->val);
+		dev_dbg(imx283->dev, "V4L2_CID_HBLANK : %d  HMAX : %d\n",
+			ctrl->val, imx283->hmax);
+		ret = cci_write(imx283->cci, IMX283_REG_HMAX, imx283->hmax, NULL);
+		break;
+
+	case V4L2_CID_VBLANK:
+		imx283->vmax = mode->height + ctrl->val;
+		dev_dbg(imx283->dev, "V4L2_CID_VBLANK : %d  VMAX : %d\n",
+			ctrl->val, imx283->vmax);
+		ret = cci_write(imx283->cci, IMX283_REG_VMAX, imx283->vmax, NULL);
+		break;
+
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = cci_write(imx283->cci, IMX283_REG_ANALOG_GAIN, ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_DIGITAL_GAIN:
+		ret = cci_write(imx283->cci, IMX283_REG_DIGITAL_GAIN, ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_VFLIP:
+		/*
+		 * VFLIP is managed by BIT(0) of IMX283_REG_HTRIMMING address, hence
+		 * both needed to be set simulatenously.
+		 */
+		if (ctrl->val) {
+			cci_write(imx283->cci, IMX283_REG_HTRIMMING,
+				  IMX283_HTRIMMING_EN | IMX283_MDVREV, &ret);
+		} else {
+			cci_write(imx283->cci, IMX283_REG_HTRIMMING,
+				  IMX283_HTRIMMING_EN, &ret);
+		}
+		break;
+
+	case V4L2_CID_TEST_PATTERN:
+		ret = imx283_update_test_pattern(imx283, ctrl->val);
+		break;
+
+	default:
+		dev_err(imx283->dev, "ctrl(id:0x%x, val:0x%x) is not handled\n",
+			ctrl->id, ctrl->val);
+		break;
+	}
+
+	pm_runtime_put(imx283->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops imx283_ctrl_ops = {
+	.s_ctrl = imx283_set_ctrl,
+};
+
+static int imx283_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= (ARRAY_SIZE(codes)))
+		return -EINVAL;
+
+	code->code = codes[code->index];
+
+	return 0;
+}
+
+static int imx283_enum_frame_size(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *sd_state,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	const struct imx283_mode *mode_list;
+	unsigned int num_modes;
+
+	get_mode_table(fse->code, &mode_list, &num_modes);
+
+	if (fse->index >= num_modes)
+		return -EINVAL;
+
+	fse->min_width = mode_list[fse->index].width;
+	fse->max_width = fse->min_width;
+	fse->min_height = mode_list[fse->index].height;
+	fse->max_height = fse->min_height;
+
+	return 0;
+}
+
+static void imx283_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
+{
+	fmt->colorspace = V4L2_COLORSPACE_RAW;
+	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);
+}
+
+static void imx283_update_image_pad_format(struct imx283 *imx283,
+					   const struct imx283_mode *mode,
+					   struct v4l2_mbus_framefmt *format)
+{
+	format->width = mode->width;
+	format->height = mode->height;
+	format->field = V4L2_FIELD_NONE;
+	imx283_reset_colorspace(format);
+}
+
+static int imx283_init_state(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state)
+{
+	struct imx283 *imx283 = to_imx283(sd);
+	struct v4l2_mbus_framefmt *format;
+	const struct imx283_mode *mode;
+	struct v4l2_rect *crop;
+
+	/* Initialize try_fmt */
+	format = v4l2_subdev_state_get_format(state, IMAGE_PAD);
+
+	mode = &supported_modes_12bit[0];
+	imx283->mode = mode;
+	format->code = MEDIA_BUS_FMT_SRGGB12_1X12;
+	imx283_update_image_pad_format(imx283, mode, format);
+
+	/* Initialize crop rectangle to mode default */
+	crop = v4l2_subdev_state_get_crop(state, IMAGE_PAD);
+	*crop = mode->crop;
+
+	return 0;
+}
+
+static void imx283_set_framing_limits(struct imx283 *imx283)
+{
+	const struct imx283_mode *mode = imx283->mode;
+	u64 pixel_rate = imx283_pixel_rate(imx283);
+	u64 min_hblank, max_hblank, def_hblank;
+
+	/*
+	 * Initialise hmax and vmax for exposure calculations
+	 */
+	imx283->hmax = imx283_internal_clock(pixel_rate, mode->default_hmax);
+	imx283->vmax = mode->default_vmax;
+
+	/*
+	 * Horizontal Blanking
+	 * Convert the HMAX_MAX (72MHz) to Pixel rate values for HBLANK_MAX
+	 */
+	min_hblank = mode->min_hmax - mode->width;
+	max_hblank = imx283_iclk_to_pix(pixel_rate, IMX283_HMAX_MAX) - mode->width;
+	def_hblank = mode->default_hmax - mode->width;
+	__v4l2_ctrl_modify_range(imx283->hblank, min_hblank, max_hblank, 1,
+				 def_hblank);
+	__v4l2_ctrl_s_ctrl(imx283->hblank, def_hblank);
+
+	/* Vertical Blanking */
+	__v4l2_ctrl_modify_range(imx283->vblank, mode->min_vmax - mode->height,
+				 IMX283_VMAX_MAX - mode->height, 1,
+				 mode->default_vmax - mode->height);
+	__v4l2_ctrl_s_ctrl(imx283->vblank, mode->default_vmax - mode->height);
+}
+
+static int imx283_set_pad_format(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_format *fmt)
+{
+	struct v4l2_mbus_framefmt *format;
+	const struct imx283_mode *mode;
+	struct imx283 *imx283 = to_imx283(sd);
+	const struct imx283_mode *mode_list;
+	unsigned int num_modes;
+
+	get_mode_table(fmt->format.code, &mode_list, &num_modes);
+
+	mode = v4l2_find_nearest_size(mode_list, num_modes, width, height,
+				      fmt->format.width, fmt->format.height);
+
+	imx283_update_image_pad_format(imx283, mode, &fmt->format);
+
+	format = v4l2_subdev_state_get_format(sd_state, 0);
+
+	if (imx283->mode == mode && format->code == fmt->format.code)
+		return 0;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		imx283->mode = mode;
+		imx283->fmt_code = fmt->format.code;
+		imx283_set_framing_limits(imx283);
+	}
+
+	*format = fmt->format;
+
+	return 0;
+}
+
+static int imx283_standby_cancel(struct imx283 *imx283)
+{
+	int ret = 0;
+	unsigned int link_freq_idx;
+
+	cci_write(imx283->cci, IMX283_REG_STANDBY,
+		  IMX283_STBLOGIC | IMX283_STBDV, &ret);
+
+	/* Configure PLL clocks based on the xclk */
+	cci_multi_reg_write(imx283->cci, imx283->freq->regs,
+			    imx283->freq->reg_count, &ret);
+
+	dev_dbg(imx283->dev, "Using clk freq %d MHz", imx283->freq->mhz / MHZ(1));
+
+	/* Initialise communication */
+	cci_write(imx283->cci, IMX283_REG_PLSTMG08, IMX283_PLSTMG08_VAL, &ret);
+	cci_write(imx283->cci, IMX283_REG_PLSTMG02, IMX283_PLSTMG02_VAL, &ret);
+
+	/* Enable PLL */
+	cci_write(imx283->cci, IMX283_REG_STBPL, IMX283_STBPL_NORMAL, &ret);
+
+	/* Configure the MIPI link speed */
+	link_freq_idx = __ffs(imx283->link_freq_bitmap);
+	cci_multi_reg_write(imx283->cci,
+			    link_freq_reglist[link_freq_idx].regs,
+			    link_freq_reglist[link_freq_idx].num_of_regs,
+			    &ret);
+
+	usleep_range(1000, 2000); /* 1st Stabilisation period of 1 ms or more */
+
+	/* Activate */
+	cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_ACTIVE, &ret);
+	usleep_range(19000, 20000); /* 2nd Stabilisation period of 19ms or more */
+
+	cci_write(imx283->cci, IMX283_REG_CLAMP, IMX283_CLPSQRST, &ret);
+	cci_write(imx283->cci, IMX283_REG_XMSTA, 0, &ret);
+	cci_write(imx283->cci, IMX283_REG_SYNCDRV, IMX283_SYNCDRV_XHS_XVS, &ret);
+
+	return ret;
+}
+
+/* Start streaming */
+static int imx283_start_streaming(struct imx283 *imx283,
+				  struct v4l2_subdev_state *state)
+{
+	const struct imx283_readout_mode *readout;
+	const struct imx283_mode *mode = imx283->mode;
+	u32 v_widcut;
+	s32 v_pos;
+	u32 write_v_size;
+	u32 y_out_size;
+	int ret;
+
+	ret = imx283_standby_cancel(imx283);
+	if (ret) {
+		dev_err(imx283->dev, "failed to cancel standby\n");
+		return ret;
+	}
+
+	/*
+	 * Set the readout mode registers.
+	 * MDSEL3 and MDSEL4 are updated to enable Arbitrary Vertical Cropping.
+	 */
+	readout = &imx283_readout_modes[imx283->mode->mode];
+	cci_write(imx283->cci, IMX283_REG_MDSEL1, readout->mdsel1, &ret);
+	cci_write(imx283->cci, IMX283_REG_MDSEL2, readout->mdsel2, &ret);
+	cci_write(imx283->cci, IMX283_REG_MDSEL3,
+		  readout->mdsel3 | IMX283_MDSEL3_VCROP_EN, &ret);
+	cci_write(imx283->cci, IMX283_REG_MDSEL4,
+		  readout->mdsel4 | IMX283_MDSEL4_VCROP_EN, &ret);
+
+	/* Mode 1S specific entries from the Readout Drive Mode Tables */
+	if (mode->mode == IMX283_MODE_1S) {
+		cci_write(imx283->cci, IMX283_REG_MDSEL7, 0x01, &ret);
+		cci_write(imx283->cci, IMX283_REG_MDSEL18, 0x1098, &ret);
+	}
+
+	if (ret) {
+		dev_err(imx283->dev, "%s failed to set readout\n", __func__);
+		return ret;
+	}
+
+	/* Initialise SVR. Unsupported for now - Always 0 */
+	cci_write(imx283->cci, IMX283_REG_SVR, 0x00, &ret);
+
+	dev_dbg(imx283->dev, "Mode: Size %d x %d\n", mode->width, mode->height);
+	dev_dbg(imx283->dev, "Analogue Crop (in the mode) %d,%d %dx%d\n",
+		mode->crop.left,
+		mode->crop.top,
+		mode->crop.width,
+		mode->crop.height);
+
+	y_out_size = mode->crop.height / mode->vbin_ratio;
+	write_v_size = y_out_size + mode->vertical_ob;
+	/*
+	 * cropping start position = (VWINPOS ? Vst) ? 2
+	 * cropping width = Veff ? (VWIDCUT ? Vct) ? 2
+	 */
+	v_pos = imx283->vflip->val ?
+		((-mode->crop.top / mode->vbin_ratio) / 2) + mode->vst :
+		((mode->crop.top / mode->vbin_ratio) / 2)  + mode->vst;
+	v_widcut = ((mode->veff - y_out_size) / 2) + mode->vct;
+
+	cci_write(imx283->cci, IMX283_REG_Y_OUT_SIZE, y_out_size, &ret);
+	cci_write(imx283->cci, IMX283_REG_WRITE_VSIZE, write_v_size, &ret);
+	cci_write(imx283->cci, IMX283_REG_VWIDCUT, v_widcut, &ret);
+	cci_write(imx283->cci, IMX283_REG_VWINPOS, v_pos, &ret);
+
+	cci_write(imx283->cci, IMX283_REG_OB_SIZE_V, mode->vertical_ob, &ret);
+
+	/* TODO: Validate mode->crop is fully contained within imx283_native_area */
+	cci_write(imx283->cci, IMX283_REG_HTRIMMING_START, mode->crop.left, &ret);
+	cci_write(imx283->cci, IMX283_REG_HTRIMMING_END,
+		  mode->crop.left + mode->crop.width, &ret);
+
+	/* Disable embedded data */
+	cci_write(imx283->cci, IMX283_REG_EBD_X_OUT_SIZE, 0, &ret);
+
+	/* Apply customized values from controls (HMAX/VMAX/SHR) */
+	ret =  __v4l2_ctrl_handler_setup(imx283->sd.ctrl_handler);
+
+	return ret;
+}
+
+/* Stop streaming */
+static void imx283_stop_streaming(struct imx283 *imx283)
+{
+	int ret;
+
+	ret = cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_STBLOGIC, NULL);
+	if (ret)
+		dev_err(imx283->dev, "%s failed to set stream\n", __func__);
+
+	pm_runtime_put(imx283->dev);
+}
+
+static int imx283_set_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct imx283 *imx283 = to_imx283(sd);
+	struct v4l2_subdev_state *state;
+	int ret = 0;
+
+	state = v4l2_subdev_lock_and_get_active_state(sd);
+
+	if (enable) {
+		ret = pm_runtime_get_sync(imx283->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(imx283->dev);
+			goto unlock;
+		}
+
+		/*
+		 * Apply default & customized values
+		 * and then start streaming.
+		 */
+		ret = imx283_start_streaming(imx283, state);
+		if (ret)
+			goto err_rpm_put;
+	} else {
+		imx283_stop_streaming(imx283);
+	}
+
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+
+err_rpm_put:
+	pm_runtime_put(imx283->dev);
+unlock:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+/* Power/clock management functions */
+static int imx283_power_on(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx283 *imx283 = to_imx283(sd);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(imx283_supply_name),
+				    imx283->supplies);
+	if (ret) {
+		dev_err(imx283->dev, "%s: failed to enable regulators\n",
+			__func__);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(imx283->xclk);
+	if (ret) {
+		dev_err(imx283->dev, "%s: failed to enable clock\n",
+			__func__);
+		goto reg_off;
+	}
+
+	gpiod_set_value_cansleep(imx283->reset_gpio, 1);
+
+	usleep_range(imx283_XCLR_MIN_DELAY_US,
+		     imx283_XCLR_MIN_DELAY_US + imx283_XCLR_DELAY_RANGE_US);
+
+	return 0;
+
+reg_off:
+	regulator_bulk_disable(ARRAY_SIZE(imx283_supply_name), imx283->supplies);
+	return ret;
+}
+
+static int imx283_power_off(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx283 *imx283 = to_imx283(sd);
+
+	gpiod_set_value_cansleep(imx283->reset_gpio, 0);
+	regulator_bulk_disable(ARRAY_SIZE(imx283_supply_name), imx283->supplies);
+	clk_disable_unprepare(imx283->xclk);
+
+	return 0;
+}
+
+static int imx283_get_regulators(struct imx283 *imx283)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(imx283_supply_name); i++)
+		imx283->supplies[i].supply = imx283_supply_name[i];
+
+	return devm_regulator_bulk_get(imx283->dev,
+				       ARRAY_SIZE(imx283_supply_name),
+				       imx283->supplies);
+}
+
+/* Verify chip ID */
+static int imx283_identify_module(struct imx283 *imx283)
+{
+	int ret;
+	u64 val;
+
+	ret = cci_read(imx283->cci, IMX283_REG_CHIP_ID, &val, NULL);
+	if (ret) {
+		dev_err(imx283->dev, "failed to read chip id %x, with error %d\n",
+			IMX283_CHIP_ID, ret);
+		return ret;
+	}
+
+	if (val != IMX283_CHIP_ID) {
+		dev_err(imx283->dev, "chip id mismatch: %x!=%llx\n",
+			IMX283_CHIP_ID, val);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int imx283_get_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *sd_state,
+				struct v4l2_subdev_selection *sel)
+{
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP: {
+		sel->r = *v4l2_subdev_state_get_crop(sd_state, 0);
+		return 0;
+	}
+
+	case V4L2_SEL_TGT_NATIVE_SIZE:
+		sel->r = imx283_native_area;
+		return 0;
+
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r = imx283_active_area;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static const struct v4l2_subdev_core_ops imx283_core_ops = {
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_video_ops imx283_video_ops = {
+	.s_stream = imx283_set_stream,
+};
+
+static const struct v4l2_subdev_pad_ops imx283_pad_ops = {
+	.enum_mbus_code = imx283_enum_mbus_code,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = imx283_set_pad_format,
+	.get_selection = imx283_get_selection,
+	.enum_frame_size = imx283_enum_frame_size,
+};
+
+static const struct v4l2_subdev_internal_ops imx283_internal_ops = {
+	.init_state = imx283_init_state,
+};
+
+static const struct v4l2_subdev_ops imx283_subdev_ops = {
+	.core = &imx283_core_ops,
+	.video = &imx283_video_ops,
+	.pad = &imx283_pad_ops,
+};
+
+/* Initialize control handlers */
+static int imx283_init_controls(struct imx283 *imx283)
+{
+	struct v4l2_ctrl_handler *ctrl_hdlr;
+	struct v4l2_fwnode_device_properties props;
+	const struct imx283_mode *mode = imx283->mode;
+	u64 min_hblank, max_hblank, def_hblank;
+	u64 pixel_rate;
+	int ret;
+
+	ctrl_hdlr = &imx283->ctrl_handler;
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16);
+	if (ret)
+		return ret;
+
+	/* Serialize controls with sensor device */
+	ctrl_hdlr->lock = &imx283->mutex;
+
+	/*
+	 * Create the controls here, but mode specific limits are setup
+	 * in the imx283_set_framing_limits() call below.
+	 */
+
+	/* By default, PIXEL_RATE is read only */
+	pixel_rate = imx283_pixel_rate(imx283);
+	imx283->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
+					       V4L2_CID_PIXEL_RATE, pixel_rate,
+					       pixel_rate, 1, pixel_rate);
+
+	imx283->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx283_ctrl_ops,
+						   V4L2_CID_LINK_FREQ,
+						   __fls(imx283->link_freq_bitmap),
+						   __ffs(imx283->link_freq_bitmap),
+						   link_frequencies);
+	if (imx283->link_freq)
+		imx283->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	/* Initialise vblank/hblank/exposure based on the current mode. */
+	imx283->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
+					   V4L2_CID_VBLANK,
+					   mode->min_vmax - mode->height,
+					   IMX283_VMAX_MAX, 1,
+					   mode->default_vmax - mode->height);
+
+	min_hblank = mode->min_hmax - mode->width;
+	max_hblank = imx283_iclk_to_pix(pixel_rate, IMX283_HMAX_MAX) - mode->width;
+	def_hblank = mode->default_hmax - mode->width;
+	imx283->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
+					   V4L2_CID_HBLANK, min_hblank, max_hblank,
+					   1, def_hblank);
+
+	imx283->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
+					     V4L2_CID_EXPOSURE,
+					     IMX283_EXPOSURE_MIN,
+					     IMX283_EXPOSURE_MAX,
+					     IMX283_EXPOSURE_STEP,
+					     IMX283_EXPOSURE_DEFAULT);
+
+	v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+			  IMX283_ANA_GAIN_MIN, IMX283_ANA_GAIN_MAX,
+			  IMX283_ANA_GAIN_STEP, IMX283_ANA_GAIN_DEFAULT);
+
+	v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
+			  IMX283_DGTL_GAIN_MIN, IMX283_DGTL_GAIN_MAX,
+			  IMX283_DGTL_GAIN_STEP, IMX283_DGTL_GAIN_DEFAULT);
+
+	imx283->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_VFLIP,
+					  0, 1, 1, 0);
+	if (imx283->vflip)
+		imx283->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+
+	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx283_ctrl_ops,
+				     V4L2_CID_TEST_PATTERN,
+				     ARRAY_SIZE(imx283_tpg_menu) - 1,
+				     0, 0, imx283_tpg_menu);
+
+	if (ctrl_hdlr->error) {
+		ret = ctrl_hdlr->error;
+		dev_err(imx283->dev, "%s control init failed (%d)\n",
+			__func__, ret);
+		goto error;
+	}
+
+	ret = v4l2_fwnode_device_parse(imx283->dev, &props);
+	if (ret)
+		goto error;
+
+	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx283_ctrl_ops,
+					      &props);
+	if (ret)
+		goto error;
+
+	imx283->sd.ctrl_handler = ctrl_hdlr;
+
+	mutex_lock(&imx283->mutex);
+
+	ret = __v4l2_ctrl_s_ctrl(imx283->link_freq,
+				 __ffs(imx283->link_freq_bitmap));
+	if (ret)
+		goto error;
+
+	/* Setup exposure and frame/line length limits. */
+	imx283_set_framing_limits(imx283);
+
+	mutex_unlock(&imx283->mutex);
+
+	return 0;
+
+error:
+	v4l2_ctrl_handler_free(ctrl_hdlr);
+
+	return ret;
+}
+
+static void imx283_free_controls(struct imx283 *imx283)
+{
+	v4l2_ctrl_handler_free(imx283->sd.ctrl_handler);
+}
+
+static const struct of_device_id imx283_dt_ids[] = {
+	{ .compatible = "sony,imx283", },
+	{ /* sentinel */ }
+};
+
+static int imx283_parse_endpoint(struct imx283 *imx283)
+{
+	struct fwnode_handle *fwnode = dev_fwnode(imx283->dev);
+	struct v4l2_fwnode_endpoint bus_cfg = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY
+	};
+	struct fwnode_handle *ep;
+	int ret;
+
+	if (!fwnode)
+		return -ENXIO;
+
+	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
+	if (!ep) {
+		dev_err(imx283->dev, "Failed to get next endpoint\n");
+		return -ENXIO;
+	}
+
+	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+	fwnode_handle_put(ep);
+	if (ret)
+		return ret;
+
+	if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
+		dev_err(imx283->dev,
+			"number of CSI2 data lanes %d is not supported\n",
+			bus_cfg.bus.mipi_csi2.num_data_lanes);
+		ret = -EINVAL;
+		goto done_endpoint_free;
+	}
+
+	ret = v4l2_link_freq_to_bitmap(imx283->dev, bus_cfg.link_frequencies,
+				       bus_cfg.nr_of_link_frequencies,
+				       link_frequencies, ARRAY_SIZE(link_frequencies),
+				       &imx283->link_freq_bitmap);
+
+done_endpoint_free:
+	v4l2_fwnode_endpoint_free(&bus_cfg);
+
+	return ret;
+};
+
+static int imx283_probe(struct i2c_client *client)
+{
+	struct imx283 *imx283;
+	int ret;
+	unsigned int i;
+	unsigned int xclk_freq;
+
+	imx283 = devm_kzalloc(&client->dev, sizeof(*imx283), GFP_KERNEL);
+	if (!imx283)
+		return -ENOMEM;
+
+	imx283->dev = &client->dev;
+
+	v4l2_i2c_subdev_init(&imx283->sd, client, &imx283_subdev_ops);
+
+	imx283->cci = devm_cci_regmap_init_i2c(client, 16);
+	if (IS_ERR(imx283->cci)) {
+		ret = PTR_ERR(imx283->cci);
+		dev_err(imx283->dev, "failed to initialize CCI: %d\n", ret);
+		return ret;
+	}
+
+	/* Get system clock (xclk) */
+	imx283->xclk = devm_clk_get(imx283->dev, NULL);
+	if (IS_ERR(imx283->xclk)) {
+		dev_err(imx283->dev, "failed to get xclk\n");
+		return PTR_ERR(imx283->xclk);
+	}
+
+	xclk_freq = clk_get_rate(imx283->xclk);
+	for (i = 0; i < ARRAY_SIZE(imx283_frequencies); i++) {
+		if (xclk_freq == imx283_frequencies[i].mhz) {
+			imx283->freq = &imx283_frequencies[i];
+			break;
+		}
+	}
+	if (!imx283->freq) {
+		dev_err(imx283->dev, "xclk frequency unsupported: %d Hz\n", xclk_freq);
+		return -EINVAL;
+	}
+
+	ret = imx283_get_regulators(imx283);
+	if (ret) {
+		dev_err(imx283->dev, "failed to get regulators\n");
+		return ret;
+	}
+
+	ret = imx283_parse_endpoint(imx283);
+	if (ret) {
+		dev_err(imx283->dev, "failed to parse endpoint configuration\n");
+		return ret;
+	}
+
+	/* Request optional enable pin */
+	imx283->reset_gpio = devm_gpiod_get_optional(imx283->dev, "reset",
+						     GPIOD_OUT_HIGH);
+
+	mutex_init(&imx283->mutex);
+
+	/*
+	 * The sensor must be powered for imx283_identify_module()
+	 * to be able to read the CHIP_ID register
+	 */
+	ret = imx283_power_on(imx283->dev);
+	if (ret)
+		return ret;
+
+	ret = imx283_identify_module(imx283);
+	if (ret)
+		goto error_power_off;
+
+	/* Initialize default format and mode to max resolution */
+	imx283->mode = &supported_modes_12bit[0];
+	imx283->fmt_code = MEDIA_BUS_FMT_SRGGB12_1X12;
+
+	/*
+	 * Enable runtime PM with autosuspend. As the device has been powered
+	 * manually, mark it as active, and increase the usage count without
+	 * resuming the device.
+	 */
+	pm_runtime_set_active(imx283->dev);
+	pm_runtime_get_noresume(imx283->dev);
+	pm_runtime_enable(imx283->dev);
+	pm_runtime_set_autosuspend_delay(imx283->dev, 1000);
+	pm_runtime_use_autosuspend(imx283->dev);
+
+	/* This needs the pm runtime to be registered. */
+	ret = imx283_init_controls(imx283);
+	if (ret)
+		goto error_pm;
+
+	/* Initialize subdev */
+	imx283->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+			    V4L2_SUBDEV_FL_HAS_EVENTS;
+	imx283->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	imx283->sd.internal_ops = &imx283_internal_ops;
+
+	/* Initialize source pads */
+	imx283->pad.flags = MEDIA_PAD_FL_SOURCE;
+
+	ret = media_entity_pads_init(&imx283->sd.entity, 1, &imx283->pad);
+	if (ret) {
+		dev_err(imx283->dev, "failed to init entity pads: %d\n", ret);
+		goto error_handler_free;
+	}
+
+	imx283->sd.state_lock = imx283->ctrl_handler.lock;
+	ret = v4l2_subdev_init_finalize(&imx283->sd);
+	if (ret < 0) {
+		dev_err(imx283->dev, "subdev init error: %d\n", ret);
+		goto error_media_entity;
+	}
+
+	ret = v4l2_async_register_subdev_sensor(&imx283->sd);
+	if (ret < 0) {
+		dev_err(imx283->dev, "failed to register sensor sub-device: %d\n", ret);
+		goto error_subdev_cleanup;
+	}
+
+	return 0;
+
+error_subdev_cleanup:
+	v4l2_subdev_cleanup(&imx283->sd);
+
+error_media_entity:
+	media_entity_cleanup(&imx283->sd.entity);
+
+error_handler_free:
+	imx283_free_controls(imx283);
+
+error_pm:
+	pm_runtime_disable(imx283->dev);
+	pm_runtime_set_suspended(imx283->dev);
+error_power_off:
+	imx283_power_off(imx283->dev);
+
+	return ret;
+}
+
+static void imx283_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct imx283 *imx283 = to_imx283(sd);
+
+	v4l2_async_unregister_subdev(sd);
+	v4l2_subdev_cleanup(&imx283->sd);
+	media_entity_cleanup(&sd->entity);
+	imx283_free_controls(imx283);
+
+	pm_runtime_disable(imx283->dev);
+	if (!pm_runtime_status_suspended(imx283->dev))
+		imx283_power_off(imx283->dev);
+	pm_runtime_set_suspended(imx283->dev);
+}
+
+MODULE_DEVICE_TABLE(of, imx283_dt_ids);
+
+static const struct dev_pm_ops imx283_pm_ops = {
+	SET_RUNTIME_PM_OPS(imx283_power_off, imx283_power_on, NULL)
+};
+
+static struct i2c_driver imx283_i2c_driver = {
+	.driver = {
+		.name = "imx283",
+		.of_match_table	= imx283_dt_ids,
+		.pm = &imx283_pm_ops,
+	},
+	.probe = imx283_probe,
+	.remove = imx283_remove,
+};
+
+module_i2c_driver(imx283_i2c_driver);
+
+MODULE_AUTHOR("Will Whang <will at willwhang.com>");
+MODULE_AUTHOR("Kieran Bingham <kieran.bingham at ideasonboard.com>");
+MODULE_AUTHOR("Umang Jain <umang.jain at ideasonboard.com>");
+MODULE_DESCRIPTION("Sony IMX283 Sensor Driver");
+MODULE_LICENSE("GPL");
-- 
2.43.0



From sre at kernel.org  Thu Feb 15 12:52:44 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Thu, 15 Feb 2024 21:52:44 +0100
Subject: [PATCH v2 06/17] dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add
 imx6
In-Reply-To: <20240215145520.GA20171-robh@kernel.org>
References: <20240213010347.1075251-1-sre@kernel.org>
 <20240213010347.1075251-7-sre@kernel.org>
 <20240215145520.GA20171-robh@kernel.org>
Message-ID: <vncxxpe4ts2nybyrrgqps44eyj3t2ss63ado2pqiycpponxyy4@mhp3egl4c27a>

Hi,

On Thu, Feb 15, 2024 at 08:55:20AM -0600, Rob Herring wrote:
> On Tue, Feb 13, 2024 at 02:00:55AM +0100, Sebastian Reichel wrote:
> > Add compatibles used by different i.MX6 variants to the i.MX IOMUX
> > Controller GPR binding.
> > 
> > Signed-off-by: Sebastian Reichel <sre at kernel.org>
> > ---
> >  .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml   | 18 +++++++++++++++++-
> >  1 file changed, 17 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
> > index 1da1b758b4ae..8451cb4dd87c 100644
> > --- a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
> > +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
> > @@ -17,7 +17,23 @@ properties:
> >    compatible:
> >      oneOf:
> >        - items:
> > -          - const: fsl,imx8mq-iomuxc-gpr
> > +          - enum:
> > +              - fsl,imx6q-iomuxc-gpr
> > +              - fsl,imx8mq-iomuxc-gpr
> > +          - const: syscon
> > +          - const: simple-mfd
> > +      - items:
> > +          - enum:
> > +              - fsl,imx6sl-iomuxc-gpr
> > +              - fsl,imx6sll-iomuxc-gpr
> > +              - fsl,imx6ul-iomuxc-gpr
> > +          - const: fsl,imx6q-iomuxc-gpr
> > +          - const: syscon
> 
> A bit odd that imx6q is a simple-mfd above, but not here. I suppose 
> that could be valid if the variants here don't have sub-devices or they 
> do, but have a dependency on the parent.

These do not have sub-nodes, while the other instances have.

> Acked-by: Rob Herring <robh at kernel.org>

Thanks,

-- Sebastian


From oliver.upton at linux.dev  Thu Feb 15 13:03:00 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Thu, 15 Feb 2024 21:03:00 +0000
Subject: [PATCH v4 00/26] KVM/arm64: VM configuration enforcement
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <Zc58BDf6X6lkYLz_@linux.dev>

On Wed, Feb 14, 2024 at 01:18:01PM +0000, Marc Zyngier wrote:
> This is the fourth version of this configurationm enforcement series
> after additional reviewing from Suzuki and Oliver. Many thanks to
> both.

I'm leaning towards applying the whole series, this is looking good. I'm
going to take it for a spin on a few machines, especially AmpereOne
to make sure that hack still works :)

-- 
Thanks,
Oliver


From u.kleine-koenig at pengutronix.de  Thu Feb 15 13:03:23 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Thu, 15 Feb 2024 22:03:23 +0100
Subject: [PATCH 00/13] irqchip: Convert to platform remove callback
 returning void
In-Reply-To: <cover.1703284359.git.u.kleine-koenig@pengutronix.de>
References: <cover.1703284359.git.u.kleine-koenig@pengutronix.de>
Message-ID: <knhwqxhouaiehmnnz5oxaxibhq7usokefztae4pplqypwuzgye@mke2irokres4>

Hello Thomas,

On Fri, Dec 22, 2023 at 11:50:31PM +0100, Uwe Kleine-K?nig wrote:
> this series converts all drivers below drivers/irqchip to use
> .remove_new(). See commit 5c5a7680e67b ("platform: Provide a remove
> callback that returns no value") for an extended explanation and the
> eventual goal. The TL;DR; is to make it harder for driver authors to
> leak resources.
> 
> The drivers touched here are all fine though and don't return early in
> .remove(). So all conversions in this series are trivial.

I'm still waiting for this series to go in (or get review feedback). Is
this still on your radar? You're the right maintainer to take this
series, aren't you?

The series still applies to today's next.

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/20240215/b82a352b/attachment.sig>

From u.kleine-koenig at pengutronix.de  Thu Feb 15 13:11:45 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Thu, 15 Feb 2024 22:11:45 +0100
Subject: [PATCH] ACPI: APEI: GHES: Convert to platform remove callback
 returning void
In-Reply-To: <tfmuzubr5p57qyv2pye72yzs6fjdyxubcqkmhih7ndddqcifgu@y4psjmr4rbz6>
References: <20231120173053.49597-1-u.kleine-koenig@pengutronix.de>
 <CAJZ5v0iW_B72o8EMbZaH_x2SOHOvqnieP8EsK2A6d93GRDYtBA@mail.gmail.com>
 <20231122174913.GFZV4/GUKci24sp1oj@fat_crate.local>
 <ix7bttqx32bv4hajg7szijtosi5vn43nxduun3fwevccjqrjhh@qrbjvcsuddoi>
 <tfmuzubr5p57qyv2pye72yzs6fjdyxubcqkmhih7ndddqcifgu@y4psjmr4rbz6>
Message-ID: <r2cobeovsufkoryiszm56gu2pwgevjxcoceg5am6j7va4r7su3@7arj7wav2d5q>

Hello,

On Wed, Jan 10, 2024 at 09:34:53AM +0100, Uwe Kleine-K?nig wrote:
> On Mon, Dec 18, 2023 at 09:47:10PM +0100, Uwe Kleine-K?nig wrote:
> > On Wed, Nov 22, 2023 at 06:49:13PM +0100, Borislav Petkov wrote:
> > > On Wed, Nov 22, 2023 at 04:25:30PM +0100, Rafael J. Wysocki wrote:
> > > > On Mon, Nov 20, 2023 at 6:31?PM Uwe Kleine-K?nig
> > > > <u.kleine-koenig at pengutronix.de> wrote:
> > > > >
> > > > > The .remove() callback for a platform driver returns an int which makes
> > > > > many driver authors wrongly assume it's possible to do error handling by
> > > > > returning an error code. However the value returned is ignored (apart
> > > > > from emitting a warning) and this typically results in resource leaks.
> > > > >
> > > > > To improve here there is a quest to make the remove callback return
> > > > > void. In the first step of this quest all drivers are converted to
> > > > > .remove_new(), which already returns void. Eventually after all drivers
> > > > > are converted, .remove_new() will be renamed to .remove().
> > > > >
> > > > > Instead of returning an error code, emit a better error message than the
> > > > > core. Apart from the improved error message this patch has no effects
> > > > > for the driver.
> > > > >
> > > > > Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> > > > > ---
> > > > > Hello,
> > > > >
> > > > > I tried to improve this driver before, see
> > > > >
> > > > >         https://lore.kernel.org/linux-acpi/CAJZ5v0ifb-wvyp0JRq_4c1L6vTi_qEeXJ6P=Pmmq_56xRL74_A at mail.gmail.com
> > > > >         https://lore.kernel.org/linux-arm-kernel/20221219221439.1681770-1-u.kleine-koenig at pengutronix.de
> > > > >         https://lore.kernel.org/linux-arm-kernel/20221220154447.12341-1-u.kleine-koenig at pengutronix.de
> > > > >
> > > > > but this didn't result in any patch being applied.
> > > > >
> > > > > I think it's inarguable that there is a problem that wants to be fixed.
> > > > > My tries to fix this problem fixxled out, so here comes a minimal change
> > > > > that just points out the problem and otherwise makes ghes_remove()
> > > > > return void without further side effects to allow me to continue my
> > > > > quest to make platform_driver remove callbacks return no error.
> > > > 
> > > > Tony, Boris, any objections against this patch?
> > > 
> > > SDEI is James. Moving him to To:
> > 
> > I wonder if you had a chance to look at this patch.
> > 
> > It doesn't change anything for the SDEI driver, the only effect is to
> > have one driver less using platform_driver's remove function.
> > 
> > Would be great if that patch made it in.
> 
> I guess it's to late for 6.8-rc1, but I wonder if this patch is still on
> your radar?

I'm a frustrated about this patch. It already missed two merge windows
while it's (IMHO) easy to understand that it doesn't change anything
relevant for the driver. (There is a resource leak in this driver, the
only difference my patch makes here is that it's more visible than
before that the leak is there.)

What must happen to make this patch go in?

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/20240215/0133c776/attachment.sig>

From jgg at nvidia.com  Thu Feb 15 13:17:39 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 15 Feb 2024 17:17:39 -0400
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <02fac0ab-07ac-448e-ae4e-26788ed4fce9@arm.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240215134952.GA690@willie-the-truck>
 <20240215160135.GL1088888@nvidia.com>
 <02fac0ab-07ac-448e-ae4e-26788ed4fce9@arm.com>
Message-ID: <20240215211739.GN1088888@nvidia.com>

On Thu, Feb 15, 2024 at 06:42:37PM +0000, Robin Murphy wrote:

> > > > @@ -48,6 +48,21 @@ enum arm_smmu_msi_index {
> > > >   	ARM_SMMU_MAX_MSIS,
> > > >   };
> > > > +struct arm_smmu_entry_writer_ops;
> > > > +struct arm_smmu_entry_writer {
> > > > +	const struct arm_smmu_entry_writer_ops *ops;
> > > > +	struct arm_smmu_master *master;
> > > > +};
> > > > +
> > > > +struct arm_smmu_entry_writer_ops {
> > > > +	unsigned int num_entry_qwords;
> > > > +	__le64 v_bit;
> > > > +	void (*get_used)(const __le64 *entry, __le64 *used);
> > > > +	void (*sync)(struct arm_smmu_entry_writer *writer);
> > > > +};
> > > 
> > > Can we avoid the indirection for now, please? I'm sure we'll want it later
> > > when you extend this to CDs, but for the initial support it just makes it
> > > more difficult to follow the flow. Should be a trivial thing to drop, I
> > > hope.
> > 
> > We can.
> 
> Ack, the abstraction is really hard to follow, and much of that
> seems entirely self-inflicted in the amount of recalculating
> information which was in-context in a previous step but then thrown
> away.

I'm not sure I understand this can you be more specific? I don't know
what we are throwing away that you see?

> And as best I can tell I think it will still end up doing more CFGIs
> than needed.

I think we've minimized the number of steps and Michael did check it,
even pushed tests for the popular scenarios into the kunit. He found a
case where it was not optimal and it was improved.

Mostafa asked about extra syncs, and you can read my reply explaining
why. We both agreed the sync's are necessary.

The only extra thing I know of is the zeroing of fields. Perhaps we
don't have to do this, but I think we should. Operating with the STE
in a known state seems like the conservative choice.

Regardless if you have a case in mind where there are extra steps lets
try it in the kunit and check.

This is not a performance path, so I wouldn't invest too much in this
question.

> Keeping a single monolithic check-and-update function will be *so* much
> easier to understand and maintain. 

The ops are used by the kunit test suite and I think the kunit is
valuable.

Further I've been looking at the AMD driver and it has the same
problem to solve for its DTE and can use this same solution.  Intel
also has > 128 bit structures too. I already drafted an exploration of
using this algorithm in AMD.

I see a someday future where we will move this to shared core code. In
which case the driver only provides the used and sync operation which
I think is a low driver burden for solving such a tricky shared
problem. There is some more shared complexity here on x86 which needs
to use 128 bit stores if the CPU supports those instructions.

IOW this approach is nice and valuable outside ARM. I would like to
move in a direction where we simply use this shared code for all
multi-qword HW descriptors. We've certainly invested enough in
building it and none of the three drivers have anything better.

> As far as CDs go, anything we might reasonably want to change in a
> live CD is all in the first word so I don't see any value in

Changing from a S1 -> S1 requires updating two qwords in the CD and
that requires the V=0 flow that the current arm_smmu_write_ctx_desc()
doesn't do. It is not that arm_smmu_write_ctx_desc() needs to be
prettier, it needs more functionality.

> > > > +static void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
> > > >   {
> > > > +	unsigned int cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ent[0]));
> > > > +
> > > > +	used_bits[0] = cpu_to_le64(STRTAB_STE_0_V);
> > > > +	if (!(ent[0] & cpu_to_le64(STRTAB_STE_0_V)))
> > > > +		return;
> > > > +
> > > > +	/*
> > > > +	 * See 13.5 Summary of attribute/permission configuration fields for the
> > > > +	 * SHCFG behavior. It is only used for BYPASS, including S1DSS BYPASS,
> > > > +	 * and S2 only.
> > > > +	 */
> > > > +	if (cfg == STRTAB_STE_0_CFG_BYPASS ||
> > > > +	    cfg == STRTAB_STE_0_CFG_S2_TRANS ||
> > > > +	    (cfg == STRTAB_STE_0_CFG_S1_TRANS &&
> > > > +	     FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
> > > > +		     STRTAB_STE_1_S1DSS_BYPASS))
> > > > +		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_SHCFG);
> > > > > > Huh, SHCFG is really getting in the way here, isn't it?
> > 
> > I wouldn't say that.. It is just a complicated bit of the spec. One of
> > the things we recently did was to audit all the cache settings and, at
> > least, we then realized that SHCFG was being subtly used by S2 as
> > well..
> 
> Yeah, that really shouldn't be subtle; incoming attributes are replaced by
> S1 translation, thus they are relevant to not-S1 configs.

That is a really nice way to summarize the spec! But my remark was
more about the code which isn't so obvious what value it intended to
have for SHCFG on the S2 case.

This doesn't really change anthing about this patch, we'd still have
the above hunk to accurately reflect the SHCFG usage, and we'd still
set SHCFG to 0 in S1 cases where it isn't used by HW, just like today.

> I think it's likely to be significantly more straightforward to give up on
> the switch statement and jump straight into the more architectural paradigm
> at this level, e.g.

I've thought about that, I can make effort to do this, the later
nesting change would probably look nicer in this style.

Thanks,
Jason


From jernej.skrabec at gmail.com  Thu Feb 15 13:18:05 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 15 Feb 2024 22:18:05 +0100
Subject: [PATCH v4 1/7] soc: sunxi: sram: export register 0 for THS on H616
In-Reply-To: <20240215012847.7d0eeda9@minigeek.lan>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
 <2172811.irdbgypaU6@jernej-laptop> <20240215012847.7d0eeda9@minigeek.lan>
Message-ID: <5752001.DvuYhMxLoT@jernej-laptop>

Dne ?etrtek, 15. februar 2024 ob 02:28:47 CET je Andre Przywara napisal(a):
> On Wed, 14 Feb 2024 21:29:30 +0100
> Jernej ?krabec <jernej.skrabec at gmail.com> wrote:
> 
> Hi Jernej,
> 
> thanks for having a look and the tags on the other patches!
> 
> > Dne petek, 09. februar 2024 ob 15:42:15 CET je Andre Przywara napisal(a):
> > > The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
> > > in the SRAM control block. If bit 16 is set (the reset value), the
> > > temperature readings of the THS are way off, leading to reports about
> > > 200C, at normal ambient temperatures. Clearing this bits brings the
> > > reported values down to reasonable ranges.
> > > The BSP code clears this bit in firmware (U-Boot), and has an explicit
> > > comment about this, but offers no real explanation.
> > > 
> > > Since we should not rely on firmware settings, allow other code (the THS
> > > driver) to access this register, by exporting it through the already
> > > existing regmap. This mimics what we already do for the LDO control and
> > > the EMAC register.  
> > 
> > Are you sure that this bit doesn't control actual SRAM region?
> 
> Pretty much so, yes: I did some experiments from U-Boot:
> I filled SRAM C with some pattern, then read this back. Then flipped bit
> 16, read again: same result. Then wrote something again and read it
> back: no change. In fact no bits at 0x3000000 had any effect on SRAM
> accessibility, only clearing bit 24 in 0x3000004 made the whole SRAM C
> (0x28000-0x47fff) go read-as-zero/write-ignore, from the CPU side.
> 
> I then triggered the THS device, to do temperature readings, but
> this didn't change a single byte in the SRAM regions, with or without
> bit 16 set. It only changed the returned values, at 0x50704c0.
> 
> So yes, I am pretty certain there is no SRAM region that gets switched.
> Even if we would want to claim there is: I wouldn't know which
> address values to put into the SRAM DT node.
> 
> So I guess it's another example of: oh, we have this spare bit here. Or
> it's some kind of chicken bit? I don't know, and I think the BSP code
> we have seen didn't offer an explanation as well.
> 

It would be nice to mention this in commit message.

> Cheers,
> Andre
> > 
> > Best regards,
> > Jernej
> > 
> > > 
> > > Since this bit is in the very same register as the actual SRAM switch,
> > > we need to change the regmap lock to the SRAM lock. Fortunately regmap
> > > has provisions for that, so we just need to hook in there.
> > > 
> > > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > > ---
> > >  drivers/soc/sunxi/sunxi_sram.c | 23 +++++++++++++++++++++++
> > >  1 file changed, 23 insertions(+)
> > > 
> > > diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
> > > index 4458b2e0562b0..71cdd1b257eeb 100644
> > > --- a/drivers/soc/sunxi/sunxi_sram.c
> > > +++ b/drivers/soc/sunxi/sunxi_sram.c
> > > @@ -287,6 +287,7 @@ EXPORT_SYMBOL(sunxi_sram_release);
> > >  struct sunxi_sramc_variant {
> > >  	int num_emac_clocks;
> > >  	bool has_ldo_ctrl;
> > > +	bool has_ths_offset;
> > >  };
> > >  
> > >  static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
> > > @@ -308,8 +309,10 @@ static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
> > >  
> > >  static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
> > >  	.num_emac_clocks = 2,
> > > +	.has_ths_offset = true,
> > >  };
> > >  
> > > +#define SUNXI_SRAM_THS_OFFSET_REG	0x0
> > >  #define SUNXI_SRAM_EMAC_CLOCK_REG	0x30
> > >  #define SUNXI_SYS_LDO_CTRL_REG		0x150
> > >  
> > > @@ -318,6 +321,8 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
> > >  {
> > >  	const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
> > >  
> > > +	if (reg == SUNXI_SRAM_THS_OFFSET_REG && variant->has_ths_offset)
> > > +		return true;
> > >  	if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG &&
> > >  	    reg <  SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
> > >  		return true;
> > > @@ -327,6 +332,21 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
> > >  	return false;
> > >  }
> > >  
> > > +

Nit: superfluous empty line.

Best regards,
Jernej

> > > +static void sunxi_sram_lock(void *_lock)
> > > +{
> > > +	spinlock_t *lock = _lock;
> > > +
> > > +	spin_lock(lock);
> > > +}
> > > +
> > > +static void sunxi_sram_unlock(void *_lock)
> > > +{
> > > +	spinlock_t *lock = _lock;
> > > +
> > > +	spin_unlock(lock);
> > > +}
> > > +
> > >  static struct regmap_config sunxi_sram_regmap_config = {
> > >  	.reg_bits       = 32,
> > >  	.val_bits       = 32,
> > > @@ -336,6 +356,9 @@ static struct regmap_config sunxi_sram_regmap_config = {
> > >  	/* other devices have no business accessing other registers */
> > >  	.readable_reg	= sunxi_sram_regmap_accessible_reg,
> > >  	.writeable_reg	= sunxi_sram_regmap_accessible_reg,
> > > +	.lock		= sunxi_sram_lock,
> > > +	.unlock		= sunxi_sram_unlock,
> > > +	.lock_arg	= &sram_lock,
> > >  };
> > >  
> > >  static int __init sunxi_sram_probe(struct platform_device *pdev)
> > >   
> > 
> > 
> > 
> > 
> > 
> 
> 






From jgg at nvidia.com  Thu Feb 15 13:18:39 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 15 Feb 2024 17:18:39 -0400
Subject: [PATCH v5 03/17] iommu/arm-smmu-v3: Move
 arm_smmu_rmr_install_bypass_ste()
In-Reply-To: <a9d10aaa-e6b1-44bd-8d7e-9e1abedf03d1@arm.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <3-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <ZcuMx0w6MDWpkLne@google.com>
 <a9d10aaa-e6b1-44bd-8d7e-9e1abedf03d1@arm.com>
Message-ID: <20240215211839.GO1088888@nvidia.com>

On Thu, Feb 15, 2024 at 07:01:59PM +0000, Robin Murphy wrote:
> On 13/02/2024 3:37 pm, Mostafa Saleh wrote:
> > Hi Jason,
> > 
> > On Tue, Feb 06, 2024 at 11:12:40AM -0400, Jason Gunthorpe wrote:
> > > Logically arm_smmu_init_strtab() is the function that allocates and
> > > populates the stream table with the initial value of the STEs. After this
> > > function returns the stream table should be fully ready.
> > > 
> > > arm_smmu_rmr_install_bypass_ste() adjusts the initial stream table to force
> > > any SIDs that the FW says have IOMMU_RESV_DIRECT to use bypass. This
> > > ensures there is no disruption to the identity mapping during boot.
> > > 
> > > Put arm_smmu_rmr_install_bypass_ste() into arm_smmu_init_strtab(), it
> > > already executes immediately after arm_smmu_init_strtab().
> > > 
> > > No functional change intended.
> > 
> > I think arm_smmu_init_strtab is quite low level to abstract FW configuration in it.
> > For example in KVM[1] we'd re-use a big part of this driver and rely on similar
> > low-level functions. But no strong opinion.
> 
> Right, the fact that RMR handling is currently based on bypass STEs is an
> implementation detail; if we ever get round to doing the strict version with
> full-on temporary pagetables, that would obviously not belong in
> init_strtab, thus I would prefer to leave the "handle RMRs" step in its
> appropriate place in the higher-level flow regardless of how it happens to
> be named and implemented today.

I will drop this patch

Jason


From jernej.skrabec at gmail.com  Thu Feb 15 13:24:54 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 15 Feb 2024 22:24:54 +0100
Subject: [PATCH v4 5/7] thermal: sun8i: add SRAM register access code
In-Reply-To: <20240209144221.3602382-6-andre.przywara@arm.com>
References: <20240209144221.3602382-1-andre.przywara@arm.com>
 <20240209144221.3602382-6-andre.przywara@arm.com>
Message-ID: <4543691.LvFx2qVVIh@jernej-laptop>

Dne petek, 09. februar 2024 ob 15:42:19 CET je Andre Przywara napisal(a):
> The Allwinner H616 SoC needs to clear a bit in one register in the SRAM
> controller, to report reasonable temperature values. On reset, bit 16 in
> register 0x3000000 is set, which leads to the driver reporting
> temperatures around 200C. Clearing this bit brings the values down to the
> expected range. The BSP code does a one-time write in U-Boot, with a
> comment just mentioning the effect on the THS, but offering no further
> explanation.
> 
> To not rely on firmware to set things up for us, add code that queries
> the SRAM controller device via a DT phandle link, then clear just this
> single bit.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  drivers/thermal/sun8i_thermal.c | 50 +++++++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
> index c919b0fd5e169..8a9d2bdc71ece 100644
> --- a/drivers/thermal/sun8i_thermal.c
> +++ b/drivers/thermal/sun8i_thermal.c
> @@ -15,6 +15,7 @@
>  #include <linux/module.h>
>  #include <linux/nvmem-consumer.h>
>  #include <linux/of.h>
> +#include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/regmap.h>
>  #include <linux/reset.h>
> @@ -66,6 +67,7 @@ struct tsensor {
>  struct ths_thermal_chip {
>  	bool            has_mod_clk;
>  	bool            has_bus_clk_reset;
> +	bool		needs_sram;
>  	int		sensor_num;
>  	int		offset;
>  	int		scale;
> @@ -83,6 +85,7 @@ struct ths_device {
>  	const struct ths_thermal_chip		*chip;
>  	struct device				*dev;
>  	struct regmap				*regmap;
> +	struct regmap_field			*sram_regmap_field;
>  	struct reset_control			*reset;
>  	struct clk				*bus_clk;
>  	struct clk                              *mod_clk;
> @@ -337,6 +340,34 @@ static void sun8i_ths_reset_control_assert(void *data)
>  	reset_control_assert(data);
>  }
>  
> +static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node)
> +{
> +	struct device_node *sram_node;
> +	struct platform_device *sram_pdev;
> +	struct regmap *regmap = NULL;
> +
> +	sram_node = of_parse_phandle(node, "allwinner,sram", 0);
> +	if (!sram_node)
> +		return ERR_PTR(-ENODEV);
> +
> +	sram_pdev = of_find_device_by_node(sram_node);
> +	if (!sram_pdev) {
> +		/* platform device might not be probed yet */
> +		regmap = ERR_PTR(-EPROBE_DEFER);
> +		goto out_put_node;
> +	}
> +
> +	/* If no regmap is found then the other device driver is at fault */
> +	regmap = dev_get_regmap(&sram_pdev->dev, NULL);
> +	if (!regmap)
> +		regmap = ERR_PTR(-EINVAL);
> +
> +	platform_device_put(sram_pdev);
> +out_put_node:
> +	of_node_put(sram_node);
> +	return regmap;
> +}
> +
>  static int sun8i_ths_resource_init(struct ths_device *tmdev)
>  {
>  	struct device *dev = tmdev->dev;
> @@ -381,6 +412,21 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev)
>  	if (ret)
>  		return ret;
>  
> +	if (tmdev->chip->needs_sram) {
> +		const struct reg_field sun8i_sram_reg_field =
> +			REG_FIELD(0x0, 16, 16);

What about global static constant for a field? Many drivers do so and code 
would be simpler.

Best regards,
Jernej

> +		struct regmap *regmap;
> +
> +		regmap = sun8i_ths_get_sram_regmap(dev->of_node);
> +		if (IS_ERR(regmap))
> +			return PTR_ERR(regmap);
> +		tmdev->sram_regmap_field = devm_regmap_field_alloc(dev,
> +						      regmap,
> +						      sun8i_sram_reg_field);
> +		if (IS_ERR(tmdev->sram_regmap_field))
> +			return PTR_ERR(tmdev->sram_regmap_field);
> +	}
> +
>  	ret = sun8i_ths_calibrate(tmdev);
>  	if (ret)
>  		return ret;
> @@ -427,6 +473,10 @@ static int sun50i_h6_thermal_init(struct ths_device *tmdev)
>  {
>  	int val;
>  
> +	/* The H616 needs to have a bit in the SRAM control register cleared. */
> +	if (tmdev->sram_regmap_field)
> +		regmap_field_write(tmdev->sram_regmap_field, 0);
> +
>  	/*
>  	 * The manual recommends an overall sample frequency of 50 KHz (20us,
>  	 * 480 cycles at 24 MHz), which provides plenty of time for both the
> 






From rafael at kernel.org  Thu Feb 15 13:25:01 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 15 Feb 2024 22:25:01 +0100
Subject: [PATCH] ACPI: APEI: GHES: Convert to platform remove callback
 returning void
In-Reply-To: <r2cobeovsufkoryiszm56gu2pwgevjxcoceg5am6j7va4r7su3@7arj7wav2d5q>
References: <20231120173053.49597-1-u.kleine-koenig@pengutronix.de>
 <CAJZ5v0iW_B72o8EMbZaH_x2SOHOvqnieP8EsK2A6d93GRDYtBA@mail.gmail.com>
 <20231122174913.GFZV4/GUKci24sp1oj@fat_crate.local> <ix7bttqx32bv4hajg7szijtosi5vn43nxduun3fwevccjqrjhh@qrbjvcsuddoi>
 <tfmuzubr5p57qyv2pye72yzs6fjdyxubcqkmhih7ndddqcifgu@y4psjmr4rbz6> <r2cobeovsufkoryiszm56gu2pwgevjxcoceg5am6j7va4r7su3@7arj7wav2d5q>
Message-ID: <CAJZ5v0jJX-6L9f_TLe-cv2MNnZVK7au=drbKCn-tEWEagY-9ZA@mail.gmail.com>

On Thu, Feb 15, 2024 at 10:11?PM Uwe Kleine-K?nig
<u.kleine-koenig at pengutronix.de> wrote:
>
> Hello,
>
> On Wed, Jan 10, 2024 at 09:34:53AM +0100, Uwe Kleine-K?nig wrote:
> > On Mon, Dec 18, 2023 at 09:47:10PM +0100, Uwe Kleine-K?nig wrote:
> > > On Wed, Nov 22, 2023 at 06:49:13PM +0100, Borislav Petkov wrote:
> > > > On Wed, Nov 22, 2023 at 04:25:30PM +0100, Rafael J. Wysocki wrote:
> > > > > On Mon, Nov 20, 2023 at 6:31?PM Uwe Kleine-K?nig
> > > > > <u.kleine-koenig at pengutronix.de> wrote:
> > > > > >
> > > > > > The .remove() callback for a platform driver returns an int which makes
> > > > > > many driver authors wrongly assume it's possible to do error handling by
> > > > > > returning an error code. However the value returned is ignored (apart
> > > > > > from emitting a warning) and this typically results in resource leaks.
> > > > > >
> > > > > > To improve here there is a quest to make the remove callback return
> > > > > > void. In the first step of this quest all drivers are converted to
> > > > > > .remove_new(), which already returns void. Eventually after all drivers
> > > > > > are converted, .remove_new() will be renamed to .remove().
> > > > > >
> > > > > > Instead of returning an error code, emit a better error message than the
> > > > > > core. Apart from the improved error message this patch has no effects
> > > > > > for the driver.
> > > > > >
> > > > > > Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> > > > > > ---
> > > > > > Hello,
> > > > > >
> > > > > > I tried to improve this driver before, see
> > > > > >
> > > > > >         https://lore.kernel.org/linux-acpi/CAJZ5v0ifb-wvyp0JRq_4c1L6vTi_qEeXJ6P=Pmmq_56xRL74_A at mail.gmail.com
> > > > > >         https://lore.kernel.org/linux-arm-kernel/20221219221439.1681770-1-u.kleine-koenig at pengutronix.de
> > > > > >         https://lore.kernel.org/linux-arm-kernel/20221220154447.12341-1-u.kleine-koenig at pengutronix.de
> > > > > >
> > > > > > but this didn't result in any patch being applied.
> > > > > >
> > > > > > I think it's inarguable that there is a problem that wants to be fixed.
> > > > > > My tries to fix this problem fixxled out, so here comes a minimal change
> > > > > > that just points out the problem and otherwise makes ghes_remove()
> > > > > > return void without further side effects to allow me to continue my
> > > > > > quest to make platform_driver remove callbacks return no error.
> > > > >
> > > > > Tony, Boris, any objections against this patch?
> > > >
> > > > SDEI is James. Moving him to To:
> > >
> > > I wonder if you had a chance to look at this patch.
> > >
> > > It doesn't change anything for the SDEI driver, the only effect is to
> > > have one driver less using platform_driver's remove function.
> > >
> > > Would be great if that patch made it in.
> >
> > I guess it's to late for 6.8-rc1, but I wonder if this patch is still on
> > your radar?
>
> I'm a frustrated about this patch. It already missed two merge windows
> while it's (IMHO) easy to understand that it doesn't change anything
> relevant for the driver. (There is a resource leak in this driver, the
> only difference my patch makes here is that it's more visible than
> before that the leak is there.)
>
> What must happen to make this patch go in?

Well, I will just have to take it without an ACK.

However, the lack of a (responsive) ARM reviewer for APEI/GHES needs
to be sorted out.

Thanks!


From sboyd at kernel.org  Thu Feb 15 13:57:39 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 15 Feb 2024 13:57:39 -0800
Subject: [PATCH v3 7/7] of: Add KUnit test to confirm DTB is loaded
In-Reply-To: <CAL_JsqLrRXdPZ+u9XG960V7sXECBi5Ko7BYdreftYz-O=Hwieg@mail.gmail.com>
References: <20240202195909.3458162-1-sboyd@kernel.org> <20240202195909.3458162-8-sboyd@kernel.org> <CABVgOS=A8BQ6HHpBKFqg-N10ckk2XYavaS-MPXvZ0wenrVm=1g@mail.gmail.com> <89892ecd6b1b043db58258705c32b02b.sboyd@kernel.org> <CAMuHMdUuP5Ya2gU3V_ET=Ji_+yx+jr7eCch5uDJSqvQN9jJM3g@mail.gmail.com> <2185a3cc3152a0b9a94b0c64353bc9a1.sboyd@kernel.org> <CAL_JsqLrRXdPZ+u9XG960V7sXECBi5Ko7BYdreftYz-O=Hwieg@mail.gmail.com>
Message-ID: <3e67766fa85be7dd865c5ec9dea1b53b.sboyd@kernel.org>

Quoting Rob Herring (2024-02-13 09:52:00)
> On Fri, Feb 9, 2024 at 8:59?PM Stephen Boyd <sboyd at kernel.org> wrote:
> >
> > ---8<---
> > diff --git a/init/main.c b/init/main.c
> > index e24b0780fdff..02f5cf8be6c1 100644
> > --- a/init/main.c
> > +++ b/init/main.c
> > @@ -97,6 +97,8 @@
> >  #include <linux/jump_label.h>
> >  #include <linux/kcsan.h>
> >  #include <linux/init_syscalls.h>
> > +#include <linux/of.h>
> > +#include <linux/of_fdt.h>
> >  #include <linux/stackdepot.h>
> >  #include <linux/randomize_kstack.h>
> >  #include <net/net_namespace.h>
> > @@ -895,6 +897,8 @@ void start_kernel(void)
> >         pr_notice("%s", linux_banner);
> >         early_security_init();
> >         setup_arch(&command_line);
> > +       if (!of_root)
> 
> of_root is another thing I'd like to remove direct access to. That
> check could be inside unflatten_device_tree().

Ok.

> 
> > +               unflatten_device_tree();
> 
> That's back to what Frank had essentially and I wanted to avoid.

Alright, fair enough.

> 
> I think I'd just disable the tests on the above arches and let them
> opt-in. I could be convinced otherwise though.
> 

Kunit folks would prefer to skip tests when dependencies aren't
satisfied. The OF_UNITTEST config already depends on !SPARC so perhaps
it's simplest to have tests skip if OF_EARLY_FLATREE=n. Then
OF_EARLY_FLATREE can be def_bool OF && !(SPARC || M68K || other arches).
The OF_UNITTEST config can depend on OF_EARLY_FLATREE instead of select
it then. This way new supporting architectures can remove themselves
from the def_bool line when they start calling unflatten_device_tree().


From martin.blumenstingl at googlemail.com  Thu Feb 15 14:00:02 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Thu, 15 Feb 2024 23:00:02 +0100
Subject: [PATCH v2] nvmem: meson-efuse: fix function pointer type mismatch
In-Reply-To: <20240213142831.3069049-1-jbrunet@baylibre.com>
References: <20240213142831.3069049-1-jbrunet@baylibre.com>
Message-ID: <CAFBinCCELS7ss0KBW+iHeevVWQzO4Sz6vTP4=E01u3+o73-HBw@mail.gmail.com>

On Tue, Feb 13, 2024 at 3:28?PM Jerome Brunet <jbrunet at baylibre.com> wrote:
>
> clang-16 warns about casting functions to incompatible types, as is done
> here to call clk_disable_unprepare:
>
> drivers/nvmem/meson-efuse.c:78:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>    78 |                                        (void(*)(void *))clk_disable_unprepare,
>
> The pattern of getting, enabling and setting a disable callback for a
> clock can be replaced with devm_clk_get_enabled(), which also fixes
> this warning.
>
> Fixes: 611fbca1c861 ("nvmem: meson-efuse: add peripheral clock")
> Reported-by: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>

Thanks Jerome!


From swboyd at chromium.org  Thu Feb 15 14:00:24 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Thu, 15 Feb 2024 14:00:24 -0800
Subject: [PATCH 01/22] dt-bindings: gpio: Add binding for ChromeOS EC GPIO controller
In-Reply-To: <20240215140638.GA4162082-robh@kernel.org>
References: <20240210070934.2549994-1-swboyd@chromium.org> <20240210070934.2549994-2-swboyd@chromium.org>
 <20240215140638.GA4162082-robh@kernel.org>
Message-ID: <CAE-0n51R307Tg7p9=GNFfUB2tE0o5JWBNpU=rX_HUe9ydSXW7A@mail.gmail.com>

Quoting Rob Herring (2024-02-15 06:06:38)
> On Fri, Feb 09, 2024 at 11:09:12PM -0800, Stephen Boyd wrote:
> > +
> > +description:
> > +  Google's ChromeOS EC has a gpio controller inside the Embedded Controller
> > +  (EC) and controlled via a host-command interface. The node for this
> > +  device should be under a cros-ec node like google,cros-ec-spi.
>
> Why do we need a child node here?
>

When in Rome... but I get your point. I will work on moving #gpio-cells
and gpio-controller into the cros-ec binding and populating some child
device from the mfd driver.


From martin.blumenstingl at googlemail.com  Thu Feb 15 14:04:42 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Thu, 15 Feb 2024 23:04:42 +0100
Subject: [PATCH] drm/meson: Don't remove bridges which are created by other drivers
Message-ID: <20240215220442.1343152-1-martin.blumenstingl@googlemail.com>

Stop calling drm_bridge_remove() for bridges allocated/managed by other
drivers in the remove paths of meson_encoder_{cvbs,dsi,hdmi}.
drm_bridge_remove() unregisters the bridge so it cannot be used
anymore. Doing so for bridges we don't own can lead to the video
pipeline not being able to come up after -EPROBE_DEFER of the VPU
because we're unregistering a bridge that's managed by another driver.
The other driver doesn't know that we have unregistered it's bridge
and on subsequent .probe() we're not able to find those bridges anymore
(since nobody re-creates them).

This fixes probe errors on Meson8b boards with the CVBS outputs enabled.

Fixes: 09847723c12f ("drm/meson: remove drm bridges at aggregate driver unbind time")
Fixes: 42dcf15f901c ("drm/meson: add DSI encoder")
Cc: stable at vger.kernel.org
Reported-by: Steve Morvai <stevemorvai at hotmail.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
This issue was reported by Steve off-list to me (thanks again for your
patience and sorry it took so long)!
The Meson8b VPU driver is not upstream, but the problematic code is.
Meaning: This issue can also appear on SoCs which are supported
upstream if the meson DRM driver probe has to be re-tried (with
-EPROBE_DEFER). That's why I chose to Cc the stable list.


 drivers/gpu/drm/meson/meson_encoder_cvbs.c | 1 -
 drivers/gpu/drm/meson/meson_encoder_dsi.c  | 1 -
 drivers/gpu/drm/meson/meson_encoder_hdmi.c | 1 -
 3 files changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
index 3f73b211fa8e..3407450435e2 100644
--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
@@ -294,6 +294,5 @@ void meson_encoder_cvbs_remove(struct meson_drm *priv)
 	if (priv->encoders[MESON_ENC_CVBS]) {
 		meson_encoder_cvbs = priv->encoders[MESON_ENC_CVBS];
 		drm_bridge_remove(&meson_encoder_cvbs->bridge);
-		drm_bridge_remove(meson_encoder_cvbs->next_bridge);
 	}
 }
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
index 3f93c70488ca..311b91630fbe 100644
--- a/drivers/gpu/drm/meson/meson_encoder_dsi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
@@ -168,6 +168,5 @@ void meson_encoder_dsi_remove(struct meson_drm *priv)
 	if (priv->encoders[MESON_ENC_DSI]) {
 		meson_encoder_dsi = priv->encoders[MESON_ENC_DSI];
 		drm_bridge_remove(&meson_encoder_dsi->bridge);
-		drm_bridge_remove(meson_encoder_dsi->next_bridge);
 	}
 }
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
index 25ea76558690..c4686568c9ca 100644
--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -474,6 +474,5 @@ void meson_encoder_hdmi_remove(struct meson_drm *priv)
 	if (priv->encoders[MESON_ENC_HDMI]) {
 		meson_encoder_hdmi = priv->encoders[MESON_ENC_HDMI];
 		drm_bridge_remove(&meson_encoder_hdmi->bridge);
-		drm_bridge_remove(meson_encoder_hdmi->next_bridge);
 	}
 }
-- 
2.43.2



From mo.c.weber at gmail.com  Thu Feb 15 14:06:47 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Thu, 15 Feb 2024 23:06:47 +0100
Subject: [PATCH] Staging: vc04_services: bcm2835-camera: fixed several brace coding style checks
Message-ID: <20240215220647.4096-1-mo.c.weber@gmail.com>

Fixed coding style checks raised by checkpatch

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 .../bcm2835-camera/bcm2835-camera.c           | 62 +++++++++----------
 1 file changed, 29 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index e6e89784d..1ef7a2118 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -350,12 +350,11 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
 			if (is_capturing(dev)) {
 				v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 					 "Grab another frame");
-				vchiq_mmal_port_parameter_set(
-					instance,
-					dev->capture.camera_port,
-					MMAL_PARAMETER_CAPTURE,
-					&dev->capture.frame_count,
-					sizeof(dev->capture.frame_count));
+				vchiq_mmal_port_parameter_set(instance,
+							      dev->capture.camera_port,
+							      MMAL_PARAMETER_CAPTURE,
+							      &dev->capture.frame_count,
+							      sizeof(dev->capture.frame_count));
 			}
 			if (vchiq_mmal_submit_buffer(instance, port,
 						     &buf->mmal))
@@ -406,12 +405,11 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
 	    is_capturing(dev)) {
 		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 			 "Grab another frame as buffer has EOS");
-		vchiq_mmal_port_parameter_set(
-			instance,
-			dev->capture.camera_port,
-			MMAL_PARAMETER_CAPTURE,
-			&dev->capture.frame_count,
-			sizeof(dev->capture.frame_count));
+		vchiq_mmal_port_parameter_set(instance,
+					      dev->capture.camera_port,
+					      MMAL_PARAMETER_CAPTURE,
+					      #N(#O(#O(#O(#O(&dev->capture.frame_count,
+					      sizeof(dev->capture.frame_count));
 	}
 }
 
@@ -420,11 +418,11 @@ static int enable_camera(struct bcm2835_mmal_dev *dev)
 	int ret;
 
 	if (!dev->camera_use_count) {
-		ret = vchiq_mmal_port_parameter_set(
-			dev->instance,
-			&dev->component[COMP_CAMERA]->control,
-			MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num,
-			sizeof(dev->camera_num));
+		ret = vchiq_mmal_port_parameter_set(dev->instance,
+						    &dev->component[COMP_CAMERA]->control,
+						    MMAL_PARAMETER_CAMERA_NUM,
+						    &dev->camera_num,
+						    **sizeof(dev->camera_num));
 		if (ret < 0) {
 			v4l2_err(&dev->v4l2_dev,
 				 "Failed setting camera num, ret %d\n", ret);
@@ -468,11 +466,11 @@ static int disable_camera(struct bcm2835_mmal_dev *dev)
 				 "Failed disabling camera, ret %d\n", ret);
 			return -EINVAL;
 		}
-		vchiq_mmal_port_parameter_set(
-			dev->instance,
-			&dev->component[COMP_CAMERA]->control,
-			MMAL_PARAMETER_CAMERA_NUM, &i,
-			sizeof(i));
+		vchiq_mmal_port_parameter_set(dev->instance,
+					      &dev->component[COMP_CAMERA]->control,
+					      MMAL_PARAMETER_CAMERA_NUM,
+					      &i,
+					      sizeof(i));
 	}
 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 		 "Camera refcount now %d\n", dev->camera_use_count);
@@ -786,9 +784,8 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on)
 			ret = vchiq_mmal_port_connect_tunnel(dev->instance, src,
 							     NULL);
 		if (ret >= 0)
-			ret = vchiq_mmal_component_disable(
-					dev->instance,
-					dev->component[COMP_PREVIEW]);
+			ret = vchiq_mmal_component_disable(dev->instance,
+							   dev->component[COMP_PREVIEW]);
 
 		disable_camera(dev);
 		return ret;
@@ -1006,7 +1003,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	return 0;
 }
 
-
 static int mmal_setup_video_component(struct bcm2835_mmal_dev *dev,
 				      struct v4l2_format *f)
 {
@@ -1042,8 +1038,8 @@ static int mmal_setup_video_component(struct bcm2835_mmal_dev *dev,
 
 	if (overlay_enabled) {
 		ret = vchiq_mmal_port_connect_tunnel(dev->instance,
-				preview_port,
-				&dev->component[COMP_PREVIEW]->input[0]);
+						     preview_port,
+						     &dev->component[COMP_PREVIEW]->input[0]);
 		if (ret)
 			return ret;
 
@@ -1720,11 +1716,11 @@ static int mmal_init(struct bcm2835_mmal_dev *dev)
 	{
 		unsigned int enable = 1;
 
-		vchiq_mmal_port_parameter_set(
-			dev->instance,
-			&dev->component[COMP_VIDEO_ENCODE]->control,
-			MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
-			&enable, sizeof(enable));
+		vchiq_mmal_port_parameter_set(dev->instance,
+					      &dev->component[COMP_VIDEO_ENCODE]->control,
+					      MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
+					      &enable,
+					      sizeof(enable));
 
 		vchiq_mmal_port_parameter_set(dev->instance,
 					      &dev->component[COMP_VIDEO_ENCODE]->control,
-- 
2.30.2



From akpm at linux-foundation.org  Thu Feb 15 14:48:49 2024
From: akpm at linux-foundation.org (Andrew Morton)
Date: Thu, 15 Feb 2024 14:48:49 -0800
Subject: [PATCH v2] mm/filemap: Allow arch to request folio size for
 exec memory
In-Reply-To: <20240215154059.2863126-1-ryan.roberts@arm.com>
References: <20240215154059.2863126-1-ryan.roberts@arm.com>
Message-ID: <20240215144849.aba06863acc08b8ded09a187@linux-foundation.org>

On Thu, 15 Feb 2024 15:40:59 +0000 Ryan Roberts <ryan.roberts at arm.com> wrote:

> Change the readahead config so that if it is being requested for an
> executable mapping, do a synchronous read of an arch-specified size in a
> naturally aligned manner.

Some nits:

> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -1115,6 +1115,18 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
>   */
>  #define arch_wants_old_prefaulted_pte	cpu_has_hw_af
> 
> +/*
> + * Request exec memory is read into pagecache in at least 64K folios. The
> + * trade-off here is performance improvement due to storing translations more
> + * effciently in the iTLB vs the potential for read amplification due to reading

"efficiently"

> + * data from disk that won't be used. The latter is independent of base page
> + * size, so we set a page-size independent block size of 64K. This size can be
> + * contpte-mapped when 4K base pages are in use (16 pages into 1 iTLB entry),
> + * and HPA can coalesce it (4 pages into 1 TLB entry) when 16K base pages are in
> + * use.
> + */
> +#define arch_wants_exec_folio_order() ilog2(SZ_64K >> PAGE_SHIFT)
> +

To my eye, "arch_wants_foo" and "arch_want_foo" are booleans.  Either
this arch wants a particular treatment or it does not want it.

I suggest a better name would be "arch_exec_folio_order".

>  static inline bool pud_sect_supported(void)
>  {
>  	return PAGE_SIZE == SZ_4K;
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index aab227e12493..6cdd145cbbb9 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -407,6 +407,18 @@ static inline bool arch_has_hw_pte_young(void)
>  }
>  #endif
> 
> +#ifndef arch_wants_exec_folio_order
> +/*
> + * Returns preferred minimum folio order for executable file-backed memory. Must
> + * be in range [0, PMD_ORDER]. Negative value implies that the HW has no
> + * preference and mm will not special-case executable memory in the pagecache.
> + */

I think this comment contains material which would be useful above the
other arch_wants_exec_folio_order() implementation - the "must be in
range" part.  So I suggest all this material be incorporated into a
single comment which describes arch_wants_exec_folio_order().  Then
this comment can be removed entirely.  Assume the reader knows to go
seek the other definition for the commentary.

> +static inline int arch_wants_exec_folio_order(void)
> +{
> +	return -1;
> +}
> +#endif
> +
>  #ifndef arch_check_zapped_pte
>  static inline void arch_check_zapped_pte(struct vm_area_struct *vma,
>  					 pte_t pte)
> diff --git a/mm/filemap.c b/mm/filemap.c
> index 142864338ca4..7954274de11c 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -3118,6 +3118,25 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
>  	}
>  #endif
> 
> +	/*
> +	 * Allow arch to request a preferred minimum folio order for executable
> +	 * memory. This can often be beneficial to performance if (e.g.) arm64
> +	 * can contpte-map the folio. Executable memory rarely benefits from
> +	 * read-ahead anyway, due to its random access nature.

"readahead"

> +	 */
> +	if (vm_flags & VM_EXEC) {
> +		int order = arch_wants_exec_folio_order();
> +
> +		if (order >= 0) {
> +			fpin = maybe_unlock_mmap_for_io(vmf, fpin);
> +			ra->size = 1UL << order;
> +			ra->async_size = 0;
> +			ractl._index &= ~((unsigned long)ra->size - 1);
> +			page_cache_ra_order(&ractl, ra, order);
> +			return fpin;
> +		}
> +	}
> +
>  	/* If we don't want any read-ahead, don't bother */
>  	if (vm_flags & VM_RAND_READ)
>  		return fpin;



From mo.c.weber at gmail.com  Thu Feb 15 14:52:49 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Thu, 15 Feb 2024 23:52:49 +0100
Subject: [PATCH 2/3] Staging: vc04_services: bcm2835-camera: fixed several brace coding style checks
Message-ID: <20240215225249.11010-1-mo.c.weber@gmail.com>

Fixed coding style checks raised by checkpatch

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 .../vc04_services/bcm2835-camera/controls.c        | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c
index 6bce45925..e670226f1 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
@@ -533,17 +533,15 @@ static int ctrl_set_image_effect(struct bcm2835_mmal_dev *dev,
 
 		control = &dev->component[COMP_CAMERA]->control;
 
-		ret = vchiq_mmal_port_parameter_set(
-				dev->instance, control,
-				MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
-				&imagefx, sizeof(imagefx));
+		ret = vchiq_mmal_port_parameter_set(dev->instance, control,
+						    MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
+						    &imagefx, sizeof(imagefx));
 		if (ret)
 			goto exit;
 
-		ret = vchiq_mmal_port_parameter_set(
-				dev->instance, control,
-				MMAL_PARAMETER_COLOUR_EFFECT,
-				&dev->colourfx, sizeof(dev->colourfx));
+		ret = vchiq_mmal_port_parameter_set(dev->instance, control,
+						    MMAL_PARAMETER_COLOUR_EFFECT,
+						    &dev->colourfx, sizeof(dev->colourfx));
 	}
 
 exit:
-- 
2.30.2



From boqun.feng at gmail.com  Thu Feb 15 14:53:28 2024
From: boqun.feng at gmail.com (Boqun Feng)
Date: Thu, 15 Feb 2024 14:53:28 -0800
Subject: [RFC] efi: Add ACPI_MEMORY_NVS into the linear map
In-Reply-To: <20240215225116.3435953-1-boqun.feng@gmail.com>
References: <20240215225116.3435953-1-boqun.feng@gmail.com>
Message-ID: <Zc6V6GnSQ_q1OAFC@boqun-archlinux>

(Cc the correct arm mailing list)

On Thu, Feb 15, 2024 at 02:51:06PM -0800, Boqun Feng wrote:
> Currently ACPI_MEMORY_NVS is omitted from the linear map, which causes
> a trouble with the following firmware memory region setup:
> 
> 	[..] efi:   0x0000dfd62000-0x0000dfd83fff [ACPI Reclaim|...]
> 	[..] efi:   0x0000dfd84000-0x0000dfd87fff [ACPI Mem NVS|...]
> 
> , on ARM64 with 64k page size, the whole 0x0000dfd80000-0x0000dfd8ffff
> range will be omitted from the the linear map due to 64k round-up. And
> a page fault happens when trying to access the ACPI_RECLAIM_MEMORY:
> 
> 	[...] Unable to handle kernel paging request at virtual address ffff0000dfd80000
> 
> To fix this, add ACPI_MEMORY_NVS into the linear map.
> 
> Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
> Cc: stable at vger.kernel.org # 5.15+
> ---
> We hit this in an ARM64 Hyper-V VM when using 64k page size, although
> this issue may also be fixed if the efi memory regions are all 64k
> aligned, but I don't find this memory region setup is invalid per UEFI
> spec, also I don't find that spec disallows ACPI_MEMORY_NVS to be mapped
> in the OS linear map, but if there is any better way or I'm reading the
> spec incorrectly, please let me know.
> 
> It's Cced stable since 5.15 because that's when Hyper-V ARM64 support is
> added, and Hyper-V is the only one that hits the problem so far.
> 
>  drivers/firmware/efi/efi-init.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
> index a00e07b853f2..9a1b9bc66d50 100644
> --- a/drivers/firmware/efi/efi-init.c
> +++ b/drivers/firmware/efi/efi-init.c
> @@ -139,6 +139,7 @@ static __init int is_usable_memory(efi_memory_desc_t *md)
>  	case EFI_LOADER_CODE:
>  	case EFI_LOADER_DATA:
>  	case EFI_ACPI_RECLAIM_MEMORY:
> +	case EFI_ACPI_MEMORY_NVS:
>  	case EFI_BOOT_SERVICES_CODE:
>  	case EFI_BOOT_SERVICES_DATA:
>  	case EFI_CONVENTIONAL_MEMORY:
> @@ -202,8 +203,12 @@ static __init void reserve_regions(void)
>  			if (!is_usable_memory(md))
>  				memblock_mark_nomap(paddr, size);
>  
> -			/* keep ACPI reclaim memory intact for kexec etc. */
> -			if (md->type == EFI_ACPI_RECLAIM_MEMORY)
> +			/*
> +			 * keep ACPI reclaim and NVS memory and intact for kexec
> +			 * etc.
> +			 */
> +			if (md->type == EFI_ACPI_RECLAIM_MEMORY ||
> +			    md->type == EFI_ACPI_MEMORY_NVS)
>  				memblock_reserve(paddr, size);
>  		}
>  	}
> -- 
> 2.43.0
> 


From eahariha at linux.microsoft.com  Thu Feb 15 14:53:36 2024
From: eahariha at linux.microsoft.com (Easwar Hariharan)
Date: Thu, 15 Feb 2024 14:53:36 -0800
Subject: [PATCH] arm64: Subscribe Microsoft Azure Cobalt 100 to ARM
 Neoverse N2 errata
In-Reply-To: <18b3ac3e-2bfc-4fce-9be4-3e75e487f9fc@linux.microsoft.com>
References: <20240212232909.2276378-1-eahariha@linux.microsoft.com>
 <ZcqtUxhqUbYoRH-G@linux.dev>
 <18b3ac3e-2bfc-4fce-9be4-3e75e487f9fc@linux.microsoft.com>
Message-ID: <b99a7196-011e-4f08-83ec-e63a690ab919@linux.microsoft.com>

On 2/13/2024 4:19 PM, Easwar Hariharan wrote:
> On 2/12/2024 3:44 PM, Oliver Upton wrote:
>> Hi Easwar,
>>
>> On Mon, Feb 12, 2024 at 11:29:06PM +0000, Easwar Hariharan wrote:
>>> Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft
>>> implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore
>>> suffers from all the same errata.
>>
>> Can you comment at all on where one might find this MIDR? That is, does
>> your hypervisor report the native MIDR of the implementation or does it
>> repaint it as an Arm Neoverse N2 (0x410FD490)?
> 
> We will check on the Microsoft hypervisor's plans, and get back to you.
> 
> Notwithstanding that, we do have baremetal use cases for Microsoft Azure Cobalt 100
> as well where this MIDR value will show through.
> 

<snip>

We checked in with our Microsoft hypervisor colleagues, and they do repaint the
Azure Cobalt 100 as an Arm Neoverse N2, but again, we do have baremetal use cases. 

Thanks,
Easwar



From mo.c.weber at gmail.com  Thu Feb 15 14:53:28 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Thu, 15 Feb 2024 23:53:28 +0100
Subject: [PATCH 3/3] Staging: vc04_services: interface: vchiq_arm: fixed several brace coding style checks/warnings
Message-ID: <20240215225328.11141-1-mo.c.weber@gmail.com>

Fixed code style checks raised by checkpatch

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 .../staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 6 +++---
 .../vc04_services/interface/vchiq_arm/vchiq_core.c        | 8 ++++----
 2 files changed, 7 insertions(+), 7 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 1579bd4e5..c59bea191 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -432,9 +432,9 @@ free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagel
 				head_bytes = actual;
 
 			memcpy_to_page(pages[0],
-				pagelist->offset,
-				fragments,
-				head_bytes);
+				       pagelist->offset,
+				       fragments,
+				       head_bytes);
 		}
 		if ((actual >= 0) && (head_bytes < actual) &&
 		    (tail_bytes != 0))
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
index 76c277781..5213f7c55 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -230,6 +230,7 @@ struct vchiq_service *handle_to_service(struct vchiq_instance *instance, unsigne
 
 	return rcu_dereference(instance->state->services[idx]);
 }
+
 struct vchiq_service *
 find_service_by_handle(struct vchiq_instance *instance, unsigned int handle)
 {
@@ -1192,7 +1193,6 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service,
 	header->size = size;
 	header->msgid = msgid;
 
-
 	svc_fourcc = service ? service->base.fourcc
 			     : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
 
@@ -1618,7 +1618,6 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
 		break;
 	}
 
-
 	svc_fourcc = service ? service->base.fourcc
 			     : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
 
@@ -1842,8 +1841,8 @@ parse_rx_slots(struct vchiq_state *state)
 			int rx_index;
 
 			WARN_ON(state->rx_pos & VCHIQ_SLOT_MASK);
-			rx_index = remote->slot_queue[
-				SLOT_QUEUE_INDEX_FROM_POS_MASKED(state->rx_pos)];
+			rx_index =
+				remote->slot_queue[SLOT_QUEUE_INDEX_FROM_POS_MASKED(state->rx_pos)];
 			state->rx_data = (char *)SLOT_DATA_FROM_INDEX(state,
 				rx_index);
 			state->rx_info = SLOT_INFO_FROM_INDEX(state, rx_index);
@@ -2177,6 +2176,7 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, s
 
 	for (i = 0; i < VCHIQ_MAX_SERVICES; i++) {
 		struct vchiq_service_quota *quota = &state->service_quotas[i];
+
 		init_completion(&quota->quota_event);
 	}
 
-- 
2.30.2



From sboyd at kernel.org  Thu Feb 15 15:12:12 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 15 Feb 2024 15:12:12 -0800
Subject: [PATCH] clk: constify the of_phandle_args argument of of_clk_provider
In-Reply-To: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
References: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
Message-ID: <38e7e80f61f7c67c984735cf55c3dfb3.sboyd@kernel.org>

Quoting Krzysztof Kozlowski (2024-02-08 08:37:10)
> None of the implementations of the get() and get_hw() callbacks of
> "struct of_clk_provider" modify the contents of received of_phandle_args
> pointer.  They treat it as read-only variable used to find the clock to
> return.  Make obvious that implementations are not supposed to modify
> the of_phandle_args, by making it a pointer to const.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---

This will almost certainly break the build once it is merged to
linux-next. What's your plan to merge this?


From colin.i.king at gmail.com  Thu Feb 15 15:29:44 2024
From: colin.i.king at gmail.com (Colin Ian King)
Date: Thu, 15 Feb 2024 23:29:44 +0000
Subject: [PATCH][next] serial: lpc32xx_hs: remove redundant check and assignment of hsu_rate
Message-ID: <20240215232944.2075789-1-colin.i.king@gmail.com>

Variable hsu_rate is being checked for an upper limit and is assigned
a value that is never read. The if statement and assignment are
redundant and can be removed.

Cleans up clang scan build warning:
drivers/tty/serial/lpc32xx_hs.c:237:3: warning: Value stored
to 'hsu_rate' is never read [deadcode.DeadStores]

Signed-off-by: Colin Ian King <colin.i.king at gmail.com>
---
 drivers/tty/serial/lpc32xx_hs.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c
index ec20329f0603..269efc5e2d51 100644
--- a/drivers/tty/serial/lpc32xx_hs.c
+++ b/drivers/tty/serial/lpc32xx_hs.c
@@ -233,8 +233,6 @@ static unsigned int __serial_get_clock_div(unsigned long uartclk,
 
 		hsu_rate++;
 	}
-	if (hsu_rate > 0xFF)
-		hsu_rate = 0xFF;
 
 	return goodrate;
 }
-- 
2.39.2



From ardb at kernel.org  Thu Feb 15 15:40:07 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 16 Feb 2024 00:40:07 +0100
Subject: [RFC] efi: Add ACPI_MEMORY_NVS into the linear map
In-Reply-To: <CAMj1kXF3L5SdeXDfd3uYSOz-oG7+J31pd3WtZJ+g9eGDHDdOxg@mail.gmail.com>
References: <20240215225116.3435953-1-boqun.feng@gmail.com> <CAMj1kXF3L5SdeXDfd3uYSOz-oG7+J31pd3WtZJ+g9eGDHDdOxg@mail.gmail.com>
Message-ID: <CAMj1kXGd8a-ZrSj4N=F9NZgAXcvNNHvF86aEs9smSwu66D85+Q@mail.gmail.com>

On Fri, 16 Feb 2024 at 00:21, Ard Biesheuvel <ardb at kernel.org> wrote:
>
> (cc Oliver)
>
> On Thu, 15 Feb 2024 at 23:51, Boqun Feng <boqun.feng at gmail.com> wrote:
> >
> > Currently ACPI_MEMORY_NVS is omitted from the linear map, which causes
> > a trouble with the following firmware memory region setup:
> >
> >         [..] efi:   0x0000dfd62000-0x0000dfd83fff [ACPI Reclaim|...]
> >         [..] efi:   0x0000dfd84000-0x0000dfd87fff [ACPI Mem NVS|...]
> >
>
> Which memory types were listed here?
>
> > , on ARM64 with 64k page size, the whole 0x0000dfd80000-0x0000dfd8ffff
> > range will be omitted from the the linear map due to 64k round-up. And
> > a page fault happens when trying to access the ACPI_RECLAIM_MEMORY:
> >
> >         [...] Unable to handle kernel paging request at virtual address ffff0000dfd80000
> >
>
> You trimmed all the useful information here. ACPI reclaim memory is
> reclaimable, but we don't actually do so in Linux. So this is not
> general purpose memory, it is used for a specific purpose, and the
> code that accesses it is assuming that it is accessible via the linear
> map. There are reason why this may not be the case, so the fix might
> be to use memremap() in the access instead.
>

Please try the below if the caller is already using memremap(). It
might misidentify the region because the start is in the linear map
but the end is not.


diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c
index 269f2f63ab7d..fef0281e223c 100644
--- a/arch/arm64/mm/ioremap.c
+++ b/arch/arm64/mm/ioremap.c
@@ -31,7 +31,6 @@ void __init early_ioremap_init(void)
 bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
                                 unsigned long flags)
 {
-       unsigned long pfn = PHYS_PFN(offset);
-
-       return pfn_is_map_memory(pfn);
+       return pfn_is_map_memory(PHYS_PFN(offset)) &&
+              pfn_is_map_memory(PHYS_PFN(offset + size - 1));
 }


From david at fromorbit.com  Thu Feb 15 16:04:00 2024
From: david at fromorbit.com (Dave Chinner)
Date: Fri, 16 Feb 2024 11:04:00 +1100
Subject: [PATCH v2] mm/filemap: Allow arch to request folio size for exec
 memory
In-Reply-To: <20240215154059.2863126-1-ryan.roberts@arm.com>
References: <20240215154059.2863126-1-ryan.roberts@arm.com>
Message-ID: <Zc6mcDlcnOZIjqGm@dread.disaster.area>

On Thu, Feb 15, 2024 at 03:40:59PM +0000, Ryan Roberts wrote:
> Change the readahead config so that if it is being requested for an
> executable mapping, do a synchronous read of an arch-specified size in a
> naturally aligned manner.
> 
> On arm64 if memory is physically contiguous and naturally aligned to the
> "contpte" size, we can use contpte mappings, which improves utilization
> of the TLB. When paired with the "multi-size THP" changes, this works
> well to reduce dTLB pressure. However iTLB pressure is still high due to
> executable mappings having a low liklihood of being in the required
> folio size and mapping alignment, even when the filesystem supports
> readahead into large folios (e.g. XFS).
> 
> The reason for the low liklihood is that the current readahead algorithm
> starts with an order-2 folio and increases the folio order by 2 every
> time the readahead mark is hit. But most executable memory is faulted in
> fairly randomly and so the readahead mark is rarely hit and most
> executable folios remain order-2.

Yup, this is a bug in the readahead code, and really has nothing to
do with executable files, mmap or the architecture.  We don't want
some magic new VM_EXEC min folio size per architecture thingy to be
set - we just want readahead to do the right thing.

Indeed, we are already adding a mapping minimum folio order
directive to the address space to allow for filesystem block sizes
greater than PAGE_SIZE. That's the generic mechanism that this
functionality requires. See here:

https://lore.kernel.org/linux-xfs/20240213093713.1753368-5-kernel at pankajraghav.com/

(Probably worth reading some of the other readahead mods in that
series and the discussion because readahead needs to ensure that it
fill entire high order folios in a single IO to avoid partial folio
up-to-date states from partial reads.)

IOWs, it seems to me that we could use this proposed generic mapping
min order functionality when mmap() is run and VM_EXEC is set to set
the min order to, say, 64kB. Then the readahead code would simply do
the right thing, as would all other reads and writes to that
mapping.

We could trigger this in the ->mmap() method of the filesystem so
that filesysetms that can use large folios can turn it on, whilst
other filesystems remain blissfully unaware of the functionality.
Filesystems could also do smarter things here, too. eg. enable PMD
alignment for large mapped files....

-Dave.
-- 
Dave Chinner
david at fromorbit.com


From samuel.holland at sifive.com  Thu Feb 15 16:08:12 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Thu, 15 Feb 2024 16:08:12 -0800
Subject: [PATCH v1 0/6] SiFive cache controller PMU drivers
Message-ID: <20240216000837.1868917-1-samuel.holland@sifive.com>

This patch series adds bindings and drivers for the Performance
Monitoring Units (PMUs) found in three SiFive cache controllers.

Composable Cache and Extensible Cache support system-wide profiling
with a single hardware instance. Private L2 Cache supports per-task
profiling with a separate hardware instance per core.

All three PMUs have a similar register interface and event encoding,
though the set of supported events is different. The Extensible Cache
additionally contains a pmCounterInhibit register which allows
atomically monitoring multiple counters.

All three of these cache controllers (with PMUs) have been integrated in
SoCs by our customers. However, as none of those SoCs have been publicly
announced yet, I cannot include SoC-specific compatible strings in this
version of the devicetree bindings.

This series is a follow-up to Eric Lin's series "[PATCH v2 0/3] Add
SiFive Private L2 cache and PMU driver":
https://lore.kernel.org/linux-riscv/20230720135125.21240-1-eric.lin at sifive.com/

Changes in v1:
 - Add back select: clause to binding
 - Make sifive,pl2cache1 the fallback for sifive,pl2cache0
 - Fix the order of the reg property declaration
 - Document the sifive,perfmon-counters property
 - Drop the non-PMU part of the PL2 cache driver, as the config register
   save/restore logic will be moved to M-mode
 - Add missing events to PL2 sets 2, 4, and 5
 - Use event_base and config_base to precompute register addresses
 - Check event validity earlier, in the .event_init hook
 - Implement .filter for systems where only some CPUs have a PL2
 - Only allocate percpu data when probing each PL2 instance
 - Reference count the `struct pmu` to fix unbind/bind crashes
 - Probe via DT since the PMU driver is now the only PL2 driver
 - Allow the driver to be built as a module

Eric Lin (4):
  drivers/perf: Add SiFive Composable Cache PMU driver
  dt-bindings: cache: Add SiFive Extensible Cache controller
  drivers/perf: Add SiFive Extensible Cache PMU driver
  dt-bindings: cache: Add SiFive Private L2 Cache controller

Greentime Hu (1):
  drivers/perf: Add SiFive Private L2 Cache PMU driver

Samuel Holland (1):
  dt-bindings: cache: Document the sifive,perfmon-counters property

 .../bindings/cache/sifive,ccache0.yaml        |   5 +
 .../cache/sifive,extensiblecache0.yaml        | 136 ++++
 .../bindings/cache/sifive,pl2cache0.yaml      |  81 ++
 drivers/perf/Kconfig                          |  29 +
 drivers/perf/Makefile                         |   3 +
 drivers/perf/sifive_ccache_pmu.c              | 577 ++++++++++++++
 drivers/perf/sifive_ecache_pmu.c              | 675 ++++++++++++++++
 drivers/perf/sifive_pl2_pmu.c                 | 748 ++++++++++++++++++
 include/linux/cpuhotplug.h                    |   2 +
 9 files changed, 2256 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/cache/sifive,extensiblecache0.yaml
 create mode 100644 Documentation/devicetree/bindings/cache/sifive,pl2cache0.yaml
 create mode 100644 drivers/perf/sifive_ccache_pmu.c
 create mode 100644 drivers/perf/sifive_ecache_pmu.c
 create mode 100644 drivers/perf/sifive_pl2_pmu.c

-- 
2.43.0



From samuel.holland at sifive.com  Thu Feb 15 16:08:13 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Thu, 15 Feb 2024 16:08:13 -0800
Subject: [PATCH v1 1/6] dt-bindings: cache: Document the sifive,perfmon-counters property
In-Reply-To: <20240216000837.1868917-1-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
Message-ID: <20240216000837.1868917-2-samuel.holland@sifive.com>

The SiFive Composable Cache controller contains an optional PMU with a
configurable number of event counters. Document a property which
describes the number of available counters.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 Documentation/devicetree/bindings/cache/sifive,ccache0.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml b/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml
index 7e8cebe21584..100eda4345de 100644
--- a/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml
+++ b/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml
@@ -81,6 +81,11 @@ properties:
       The reference to the reserved-memory for the L2 Loosely Integrated Memory region.
       The reserved memory node should be defined as per the bindings in reserved-memory.txt.
 
+  sifive,perfmon-counters:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+    description: Number of PMU counter registers
+
 allOf:
   - $ref: /schemas/cache-controller.yaml#
 
-- 
2.43.0



From samuel.holland at sifive.com  Thu Feb 15 16:08:14 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Thu, 15 Feb 2024 16:08:14 -0800
Subject: [PATCH v1 2/6] drivers/perf: Add SiFive Composable Cache PMU driver
In-Reply-To: <20240216000837.1868917-1-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
Message-ID: <20240216000837.1868917-3-samuel.holland@sifive.com>

From: Eric Lin <eric.lin at sifive.com>

Add a driver for the PMU found in the SiFive Composable Cache
controller. This PMU provides a configurable number of counters and a
variety of events. Events are grouped into sets. Each counter can count
events from only one set at a time; however, it can count any number of
events within that set simultaneously. The PMU hardware does not provide
an overflow interrupt or a way to atomically control groups of counters.

Some events can be filtered further by client ID (e.g. CPU or external
DMA master). That functionality is not supported by this driver.

This driver further assumes that a single Composable Cache instance is
shared by all CPUs in the system.

Example usage:

$ perf stat -a -e sifive_ccache_pmu/inner_acquire_block_btot/,
		  sifive_ccache_pmu/inner_acquire_block_hit/,
		  sifive_ccache_pmu/inner_acquire_block_ntob/ ls

 Performance counter stats for 'system wide':

               542      sifive_ccache_pmu/inner_acquire_block_btot/
             22081      sifive_ccache_pmu/inner_acquire_block_hit/
             22006      sifive_ccache_pmu/inner_acquire_block_ntob/

       0.064672432 seconds time elapsed

Example using numeric event selectors:

$ perf stat -a -e sifive_ccache_pmu/event=0x10001/,
		  sifive_ccache_pmu/event=0x2002/,
		  sifive_ccache_pmu/event=0x4001/ ls

 Performance counter stats for 'system wide':

               478      sifive_ccache_pmu/event=0x10001/
              4717      sifive_ccache_pmu/event=0x2002/
             44966      sifive_ccache_pmu/event=0x4001/

       0.111027326 seconds time elapsed

Signed-off-by: Eric Lin <eric.lin at sifive.com>
Co-developed-by: Samuel Holland <samuel.holland at sifive.com>
Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 drivers/perf/Kconfig             |   9 +
 drivers/perf/Makefile            |   1 +
 drivers/perf/sifive_ccache_pmu.c | 577 +++++++++++++++++++++++++++++++
 include/linux/cpuhotplug.h       |   1 +
 4 files changed, 588 insertions(+)
 create mode 100644 drivers/perf/sifive_ccache_pmu.c

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index ec6e0d9194a1..b4e4db7424b4 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -155,6 +155,15 @@ config QCOM_L3_PMU
 	   Adds the L3 cache PMU into the perf events subsystem for
 	   monitoring L3 cache events.
 
+config SIFIVE_CCACHE_PMU
+	tristate "SiFive Composable Cache PMU"
+	depends on RISCV || COMPILE_TEST
+	help
+	  Support for the Composable Cache performance monitoring unit (PMU) on
+	  SiFive platforms. The Composable Cache PMU provides up to 64 counters
+	  for measuring whole-system L2/L3 cache performance using the perf
+	  events subsystem.
+
 config THUNDERX2_PMU
 	tristate "Cavium ThunderX2 SoC PMU UNCORE"
 	depends on ARCH_THUNDER2 || COMPILE_TEST
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index a06338e3401c..51ef5f50ace4 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_QCOM_L3_PMU) += qcom_l3_pmu.o
 obj-$(CONFIG_RISCV_PMU) += riscv_pmu.o
 obj-$(CONFIG_RISCV_PMU_LEGACY) += riscv_pmu_legacy.o
 obj-$(CONFIG_RISCV_PMU_SBI) += riscv_pmu_sbi.o
+obj-$(CONFIG_SIFIVE_CCACHE_PMU) += sifive_ccache_pmu.o
 obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
diff --git a/drivers/perf/sifive_ccache_pmu.c b/drivers/perf/sifive_ccache_pmu.c
new file mode 100644
index 000000000000..8c9ef0d09f48
--- /dev/null
+++ b/drivers/perf/sifive_ccache_pmu.c
@@ -0,0 +1,577 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SiFive Composable Cache PMU driver
+ *
+ * Copyright (C) 2022-2024 SiFive, Inc.
+ * Copyright (C) Eric Lin <eric.lin at sifive.com>
+ *
+ */
+
+#include <linux/cpuhotplug.h>
+#include <linux/cpumask.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+
+#define CCACHE_SELECT_OFFSET		0x2000
+#define CCACHE_CLIENT_FILTER_OFFSET	0x2800
+#define CCACHE_COUNTER_OFFSET		0x3000
+
+#define CCACHE_PMU_MAX_COUNTERS		64
+
+struct sifive_ccache_pmu {
+	struct pmu			pmu;
+	struct hlist_node		node;
+	struct notifier_block		cpu_pm_nb;
+	void __iomem			*base;
+	DECLARE_BITMAP(used_mask, CCACHE_PMU_MAX_COUNTERS);
+	unsigned int			cpu;
+	int				n_counters;
+	struct perf_event		*events[] __counted_by(n_counters);
+};
+
+#define to_ccache_pmu(p) (container_of(p, struct sifive_ccache_pmu, pmu))
+
+#ifndef readq
+static inline u64 readq(void __iomem *addr)
+{
+	return readl(addr) | (((u64)readl(addr + 4)) << 32);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 v, void __iomem *addr)
+{
+	writel(lower_32_bits(v), addr);
+	writel(upper_32_bits(v), addr + 4);
+}
+#endif
+
+/*
+ * sysfs attributes
+ *
+ * We export:
+ * - cpumask, used by perf user space and other tools to know on which CPUs to create events
+ * - events, used by perf user space and other tools to create events symbolically, e.g.:
+ *     perf stat -a -e sifive_ccache_pmu/event=inner_put_partial_data_hit/ ls
+ *     perf stat -a -e sifive_ccache_pmu/event=0x101/ ls
+ * - formats, used by perf user space and other tools to configure events
+ */
+
+/* cpumask */
+static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sifive_ccache_pmu *ccache_pmu = dev_get_drvdata(dev);
+
+	if (ccache_pmu->cpu >= nr_cpu_ids)
+		return 0;
+
+	return sysfs_emit(buf, "%d\n", ccache_pmu->cpu);
+};
+
+static DEVICE_ATTR_RO(cpumask);
+
+static struct attribute *sifive_ccache_pmu_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL,
+};
+
+static const struct attribute_group sifive_ccache_pmu_cpumask_group = {
+	.attrs = sifive_ccache_pmu_cpumask_attrs,
+};
+
+/* events */
+static ssize_t sifive_ccache_pmu_event_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 sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
+}
+
+#define SET_EVENT_SELECT(_event, _set)	(BIT_ULL((_event) + 8) | (_set))
+#define CCACHE_PMU_EVENT_ATTR(_name, _event, _set) \
+	PMU_EVENT_ATTR_ID(_name, sifive_ccache_pmu_event_show, SET_EVENT_SELECT(_event, _set))
+
+enum ccache_pmu_event_set1 {
+	INNER_PUT_FULL_DATA = 0,
+	INNER_PUT_PARTIAL_DATA,
+	INNER_ATOMIC_DATA,
+	INNER_GET,
+	INNER_PREFETCH_READ,
+	INNER_PREFETCH_WRITE,
+	INNER_ACQUIRE_BLOCK_NTOB,
+	INNER_ACQUIRE_BLOCK_NTOT,
+	INNER_ACQUIRE_BLOCK_BTOT,
+	INNER_ACQUIRE_PERM_NTOT,
+	INNER_ACQUIRE_PERM_BTOT,
+	INNER_RELEASE_TTOB,
+	INNER_RELEASE_TTON,
+	INNER_RELEASE_BTON,
+	INNER_RELEASE_DATA_TTOB,
+	INNER_RELEASE_DATA_TTON,
+	INNER_RELEASE_DATA_BTON,
+	OUTER_PROBE_BLOCK_TOT,
+	OUTER_PROBE_BLOCK_TOB,
+	OUTER_PROBE_BLOCK_TON,
+	CCACHE_PMU_MAX_EVENT1_IDX
+};
+
+enum ccache_pmu_event_set2 {
+	INNER_PUT_FULL_DATA_HIT = 0,
+	INNER_PUT_PARTIAL_DATA_HIT,
+	INNER_ATOMIC_DATA_HIT,
+	INNER_GET_HIT,
+	INNER_PREFETCH_HIT,
+	INNER_ACQUIRE_BLOCK_HIT,
+	INNER_ACQUIRE_PERM_HIT,
+	INNER_RELEASE_HIT,
+	INNER_RELEASE_DATA_HIT,
+	OUTER_PROBE_HIT,
+	INNER_PUT_FULL_DATA_HIT_SHARED,
+	INNER_PUT_PARTIAL_DATA_HIT_SHARED,
+	INNER_ATOMIC_DATA_HIT_SHARED,
+	INNER_GET_HIT_SHARED,
+	INNER_PREFETCH_HIT_SHARED,
+	INNER_ACQUIRE_BLOCK_HIT_SHARED,
+	INNER_ACQUIRE_PERM_HIT_SHARED,
+	OUTER_PROBE_HIT_SHARED,
+	OUTER_PROBE_HIT_DIRTY,
+	CCACHE_PMU_MAX_EVENT2_IDX
+};
+
+enum ccache_pmu_event_set3 {
+	OUTER_ACQUIRE_BLOCK_NTOB_MISS = 0,
+	OUTER_ACQUIRE_BLOCK_NTOT_MISS,
+	OUTER_ACQUIRE_BLOCK_BTOT_MISS,
+	OUTER_ACQUIRE_PERM_NTOT_MISS,
+	OUTER_ACQUIRE_PERM_BTOT_MISS,
+	OUTER_RELEASE_TTOB_EVICTION,
+	OUTER_RELEASE_TTON_EVICTION,
+	OUTER_RELEASE_BTON_EVICTION,
+	OUTER_RELEASE_DATA_TTOB_NOT_APPLICABLE,
+	OUTER_RELEASE_DATA_TTON_DIRTY_EVICTION,
+	OUTER_RELEASE_DATA_BTON_NOT_APPLICABLE,
+	INNER_PROBE_BLOCK_TOT_CODE_MISS_HITS_OTHER_HARTS,
+	INNER_PROBE_BLOCK_TOB_LOAD_MISS_HITS_OTHER_HARTS,
+	INNER_PROBE_BLOCK_TON_STORE_MISS_HITS_OTHER_HARTS,
+	CCACHE_PMU_MAX_EVENT3_IDX
+};
+
+enum ccache_pmu_event_set4 {
+	INNER_HINT_HITS_INFLIGHT_MISS = 0,
+	CCACHE_PMU_MAX_EVENT4_IDX
+};
+
+static struct attribute *sifive_ccache_pmu_events[] = {
+	/*  pmEventSelect1 */
+	CCACHE_PMU_EVENT_ATTR(inner_put_full_data, INNER_PUT_FULL_DATA, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_put_partial_data, INNER_PUT_PARTIAL_DATA, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_atomic_data, INNER_ATOMIC_DATA, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_get, INNER_GET, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_prefetch_read, INNER_PREFETCH_READ, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_prefetch_write, INNER_PREFETCH_WRITE, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_acquire_block_ntob, INNER_ACQUIRE_BLOCK_NTOB, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_acquire_block_ntot, INNER_ACQUIRE_BLOCK_NTOT, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_acquire_block_btot, INNER_ACQUIRE_BLOCK_BTOT, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_acquire_perm_ntot, INNER_ACQUIRE_PERM_NTOT, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_acquire_perm_btot, INNER_ACQUIRE_PERM_BTOT, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_release_ttob, INNER_RELEASE_TTOB, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_release_tton, INNER_RELEASE_TTON, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_release_bton, INNER_RELEASE_BTON, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_release_data_ttob, INNER_RELEASE_DATA_TTOB, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_release_data_tton, INNER_RELEASE_DATA_TTON, 1),
+	CCACHE_PMU_EVENT_ATTR(inner_release_data_bton, INNER_RELEASE_DATA_BTON, 1),
+	CCACHE_PMU_EVENT_ATTR(outer_probe_block_tot, OUTER_PROBE_BLOCK_TOT, 1),
+	CCACHE_PMU_EVENT_ATTR(outer_probe_block_tob, OUTER_PROBE_BLOCK_TOB, 1),
+	CCACHE_PMU_EVENT_ATTR(outer_probe_block_ton, OUTER_PROBE_BLOCK_TON, 1),
+
+	/*  pmEventSelect2 */
+	CCACHE_PMU_EVENT_ATTR(inner_put_full_data_hit, INNER_PUT_FULL_DATA_HIT, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_put_partial_data_hit, INNER_PUT_PARTIAL_DATA_HIT, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_atomic_data_hit, INNER_ATOMIC_DATA_HIT, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_get_hit, INNER_GET_HIT, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_prefetch_hit, INNER_PREFETCH_HIT, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_acquire_block_hit, INNER_ACQUIRE_BLOCK_HIT, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_acquire_perm_hit, INNER_ACQUIRE_PERM_HIT, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_release_hit, INNER_RELEASE_HIT, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_release_data_hit, INNER_RELEASE_DATA_HIT, 2),
+	CCACHE_PMU_EVENT_ATTR(outer_probe_hit, OUTER_PROBE_HIT, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_put_full_data_hit_shared, INNER_PUT_FULL_DATA_HIT_SHARED, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_put_partial_data_hit_shared,
+			      INNER_PUT_PARTIAL_DATA_HIT_SHARED, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_atomic_data_hit_shared, INNER_ATOMIC_DATA_HIT_SHARED, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_get_hit_shared, INNER_GET_HIT_SHARED, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_prefetch_hit_shared, INNER_PREFETCH_HIT_SHARED, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_acquire_block_hit_shared, INNER_ACQUIRE_BLOCK_HIT_SHARED, 2),
+	CCACHE_PMU_EVENT_ATTR(inner_acquire_perm_hit_shared, INNER_ACQUIRE_PERM_HIT_SHARED, 2),
+	CCACHE_PMU_EVENT_ATTR(outer_probe_hit_shared, OUTER_PROBE_HIT_SHARED, 2),
+	CCACHE_PMU_EVENT_ATTR(outer_probe_hit_dirty, OUTER_PROBE_HIT_DIRTY, 2),
+
+	/*  pmEventSelect3 */
+	CCACHE_PMU_EVENT_ATTR(outer_acquire_block_ntob_miss, OUTER_ACQUIRE_BLOCK_NTOB_MISS, 3),
+	CCACHE_PMU_EVENT_ATTR(outer_acquire_block_ntot_miss, OUTER_ACQUIRE_BLOCK_NTOT_MISS, 3),
+	CCACHE_PMU_EVENT_ATTR(outer_acquire_block_btot_miss, OUTER_ACQUIRE_BLOCK_BTOT_MISS, 3),
+	CCACHE_PMU_EVENT_ATTR(outer_acquire_perm_ntot_miss, OUTER_ACQUIRE_PERM_NTOT_MISS, 3),
+	CCACHE_PMU_EVENT_ATTR(outer_acquire_perm_btot_miss, OUTER_ACQUIRE_PERM_BTOT_MISS, 3),
+	CCACHE_PMU_EVENT_ATTR(outer_release_ttob_eviction, OUTER_RELEASE_TTOB_EVICTION, 3),
+	CCACHE_PMU_EVENT_ATTR(outer_release_tton_eviction, OUTER_RELEASE_TTON_EVICTION, 3),
+	CCACHE_PMU_EVENT_ATTR(outer_release_bton_eviction, OUTER_RELEASE_BTON_EVICTION, 3),
+	CCACHE_PMU_EVENT_ATTR(outer_release_data_ttob_not_applicable,
+			      OUTER_RELEASE_DATA_TTOB_NOT_APPLICABLE, 3),
+	CCACHE_PMU_EVENT_ATTR(outer_release_data_tton_dirty_eviction,
+			      OUTER_RELEASE_DATA_TTON_DIRTY_EVICTION, 3),
+	CCACHE_PMU_EVENT_ATTR(outer_release_data_bton_not_applicable,
+			      OUTER_RELEASE_DATA_BTON_NOT_APPLICABLE, 3),
+	CCACHE_PMU_EVENT_ATTR(inner_probe_block_tot_code_miss_hits_other_harts,
+			      INNER_PROBE_BLOCK_TOT_CODE_MISS_HITS_OTHER_HARTS, 3),
+	CCACHE_PMU_EVENT_ATTR(inner_probe_block_tob_load_miss_hits_other_harts,
+			      INNER_PROBE_BLOCK_TOB_LOAD_MISS_HITS_OTHER_HARTS, 3),
+	CCACHE_PMU_EVENT_ATTR(inner_probe_block_ton_store_miss_hits_other_harts,
+			      INNER_PROBE_BLOCK_TON_STORE_MISS_HITS_OTHER_HARTS, 3),
+
+	/*  pm_event_select4 */
+	CCACHE_PMU_EVENT_ATTR(inner_hint_hits_inflight_miss, INNER_HINT_HITS_INFLIGHT_MISS, 4),
+	NULL
+};
+
+static struct attribute_group sifive_ccache_pmu_events_group = {
+	.name = "events",
+	.attrs = sifive_ccache_pmu_events,
+};
+
+/* formats */
+PMU_FORMAT_ATTR(event, "config:0-63");
+
+static struct attribute *sifive_ccache_pmu_formats[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group sifive_ccache_pmu_format_group = {
+	.name = "format",
+	.attrs = sifive_ccache_pmu_formats,
+};
+
+/*
+ * Per PMU device attribute groups
+ */
+
+static const struct attribute_group *sifive_ccache_pmu_attr_grps[] = {
+	&sifive_ccache_pmu_cpumask_group,
+	&sifive_ccache_pmu_events_group,
+	&sifive_ccache_pmu_format_group,
+	NULL,
+};
+
+/*
+ * Event Initialization
+ */
+
+static int sifive_ccache_pmu_event_init(struct perf_event *event)
+{
+	struct sifive_ccache_pmu *ccache_pmu = to_ccache_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u64 config = event->attr.config;
+	u64 ev_type = config >> 8;
+	u64 set = config & 0xff;
+
+	/* Check if this is a valid set and event */
+	switch (set) {
+	case 1:
+		if (ev_type >= BIT_ULL(CCACHE_PMU_MAX_EVENT1_IDX))
+			return -ENOENT;
+		break;
+	case 2:
+		if (ev_type >= BIT_ULL(CCACHE_PMU_MAX_EVENT2_IDX))
+			return -ENOENT;
+		break;
+	case 3:
+		if (ev_type >= BIT_ULL(CCACHE_PMU_MAX_EVENT3_IDX))
+			return -ENOENT;
+		break;
+	case 4:
+		if (ev_type >= BIT_ULL(CCACHE_PMU_MAX_EVENT4_IDX))
+			return -ENOENT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	/* Do not allocate the hardware counter yet */
+	hwc->idx = -1;
+	hwc->config = config;
+
+	event->cpu = ccache_pmu->cpu;
+
+	return 0;
+}
+
+/*
+ * pmu->read: read and update the counter
+ */
+static void sifive_ccache_pmu_read(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 prev_raw_count, new_raw_count;
+	u64 oldval;
+
+	do {
+		prev_raw_count = local64_read(&hwc->prev_count);
+		new_raw_count = readq((void *)hwc->event_base);
+
+		oldval = local64_cmpxchg(&hwc->prev_count, prev_raw_count, new_raw_count);
+	} while (oldval != prev_raw_count);
+
+	local64_add(new_raw_count - prev_raw_count, &event->count);
+}
+
+/*
+ * State transition functions:
+ *
+ * start()/stop() & add()/del()
+ */
+
+/*
+ * pmu->start: start the event
+ */
+static void sifive_ccache_pmu_start(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+		return;
+
+	hwc->state = 0;
+
+	/* Set initial value to 0 */
+	local64_set(&hwc->prev_count, 0);
+	writeq(0, (void *)hwc->event_base);
+
+	/* Enable this counter to count events */
+	writeq(hwc->config, (void *)hwc->config_base);
+}
+
+/*
+ * pmu->stop: stop the counter
+ */
+static void sifive_ccache_pmu_stop(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (hwc->state & PERF_HES_STOPPED)
+		return;
+
+	/* Disable this counter to count events */
+	writeq(0, (void *)hwc->config_base);
+	sifive_ccache_pmu_read(event);
+
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+}
+
+/*
+ * pmu->add: add the event to the PMU
+ */
+static int sifive_ccache_pmu_add(struct perf_event *event, int flags)
+{
+	struct sifive_ccache_pmu *ccache_pmu = to_ccache_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+
+	/* Find an available counter idx to use for this event */
+	do {
+		idx = find_first_zero_bit(ccache_pmu->used_mask, ccache_pmu->n_counters);
+		if (idx >= ccache_pmu->n_counters)
+			return -EAGAIN;
+	} while (test_and_set_bit(idx, ccache_pmu->used_mask));
+
+	hwc->config_base = (unsigned long)ccache_pmu->base + CCACHE_SELECT_OFFSET + 8 * idx;
+	hwc->event_base = (unsigned long)ccache_pmu->base + CCACHE_COUNTER_OFFSET + 8 * idx;
+	hwc->idx = idx;
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+
+	ccache_pmu->events[idx] = event;
+
+	if (flags & PERF_EF_START)
+		sifive_ccache_pmu_start(event, PERF_EF_RELOAD);
+
+	perf_event_update_userpage(event);
+
+	return 0;
+}
+
+/*
+ * pmu->del: delete the event from the PMU
+ */
+static void sifive_ccache_pmu_del(struct perf_event *event, int flags)
+{
+	struct sifive_ccache_pmu *ccache_pmu = to_ccache_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	/* Stop and release this counter */
+	sifive_ccache_pmu_stop(event, PERF_EF_UPDATE);
+
+	ccache_pmu->events[idx] = NULL;
+	clear_bit(idx, ccache_pmu->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+/*
+ * Driver initialization
+ */
+
+static void sifive_ccache_pmu_hw_init(const struct sifive_ccache_pmu *ccache_pmu)
+{
+	/* Disable the client filter (not supported by this driver) */
+	writeq(0, ccache_pmu->base + CCACHE_CLIENT_FILTER_OFFSET);
+}
+
+static int sifive_ccache_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct sifive_ccache_pmu *ccache_pmu =
+		hlist_entry_safe(node, struct sifive_ccache_pmu, node);
+
+	if (ccache_pmu->cpu >= nr_cpu_ids)
+		ccache_pmu->cpu = cpu;
+
+	return 0;
+}
+
+static int sifive_ccache_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct sifive_ccache_pmu *ccache_pmu =
+		hlist_entry_safe(node, struct sifive_ccache_pmu, node);
+
+	/* Do nothing if this CPU does not own the events */
+	if (cpu != ccache_pmu->cpu)
+		return 0;
+
+	/* Pick a random online CPU */
+	ccache_pmu->cpu = cpumask_any_but(cpu_online_mask, cpu);
+	if (ccache_pmu->cpu >= nr_cpu_ids)
+		return 0;
+
+	/* Migrate PMU events from this CPU to the target CPU */
+	perf_pmu_migrate_context(&ccache_pmu->pmu, cpu, ccache_pmu->cpu);
+
+	return 0;
+}
+
+static int sifive_ccache_pmu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct sifive_ccache_pmu *ccache_pmu;
+	u32 n_counters;
+	int ret;
+
+	/* Instances without a sifive,perfmon-counters property do not contain a PMU */
+	ret = device_property_read_u32(dev, "sifive,perfmon-counters", &n_counters);
+	if (ret || !n_counters)
+		return -ENODEV;
+
+	ccache_pmu = devm_kzalloc(dev, struct_size(ccache_pmu, events, n_counters), GFP_KERNEL);
+	if (!ccache_pmu)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, ccache_pmu);
+
+	ccache_pmu->pmu = (struct pmu) {
+		.parent		= dev,
+		.attr_groups	= sifive_ccache_pmu_attr_grps,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
+		.task_ctx_nr	= perf_invalid_context,
+		.event_init	= sifive_ccache_pmu_event_init,
+		.add		= sifive_ccache_pmu_add,
+		.del		= sifive_ccache_pmu_del,
+		.start		= sifive_ccache_pmu_start,
+		.stop		= sifive_ccache_pmu_stop,
+		.read		= sifive_ccache_pmu_read,
+	};
+	ccache_pmu->cpu = nr_cpu_ids;
+	ccache_pmu->n_counters = n_counters;
+
+	ccache_pmu->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(ccache_pmu->base))
+		return PTR_ERR(ccache_pmu->base);
+
+	sifive_ccache_pmu_hw_init(ccache_pmu);
+
+	ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE, &ccache_pmu->node);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to add CPU hotplug instance\n");
+
+	ret = perf_pmu_register(&ccache_pmu->pmu, "sifive_ccache_pmu", -1);
+	if (ret) {
+		dev_err_probe(dev, ret, "Failed to register PMU\n");
+		goto err_remove_instance;
+	}
+
+	return 0;
+
+err_remove_instance:
+	cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE, &ccache_pmu->node);
+
+	return ret;
+}
+
+static void sifive_ccache_pmu_remove(struct platform_device *pdev)
+{
+	struct sifive_ccache_pmu *ccache_pmu = platform_get_drvdata(pdev);
+
+	perf_pmu_unregister(&ccache_pmu->pmu);
+	cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE, &ccache_pmu->node);
+}
+
+static const struct of_device_id sifive_ccache_pmu_of_match[] = {
+	{ .compatible = "sifive,ccache0" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sifive_ccache_pmu_of_match);
+
+static struct platform_driver sifive_ccache_pmu_driver = {
+	.probe	= sifive_ccache_pmu_probe,
+	.remove_new	= sifive_ccache_pmu_remove,
+	.driver	= {
+		.name		= "sifive_ccache_pmu",
+		.of_match_table	= sifive_ccache_pmu_of_match,
+	},
+};
+
+static void __exit sifive_ccache_pmu_exit(void)
+{
+	platform_driver_unregister(&sifive_ccache_pmu_driver);
+	cpuhp_remove_multi_state(CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE);
+}
+module_exit(sifive_ccache_pmu_exit);
+
+static int __init sifive_ccache_pmu_init(void)
+{
+	int ret;
+
+	ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE,
+				      "perf/sifive/ccache:online",
+				      sifive_ccache_pmu_online_cpu,
+				      sifive_ccache_pmu_offline_cpu);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&sifive_ccache_pmu_driver);
+	if (ret)
+		goto err_remove_state;
+
+	return 0;
+
+err_remove_state:
+	cpuhp_remove_multi_state(CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE);
+
+	return ret;
+}
+module_init(sifive_ccache_pmu_init);
+
+MODULE_LICENSE("GPL");
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 172d0a743e5d..be6361fdc8ba 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -230,6 +230,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_POWERPC_TRACE_IMC_ONLINE,
 	CPUHP_AP_PERF_POWERPC_HV_24x7_ONLINE,
 	CPUHP_AP_PERF_POWERPC_HV_GPCI_ONLINE,
+	CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE,
 	CPUHP_AP_PERF_CSKY_ONLINE,
 	CPUHP_AP_WATCHDOG_ONLINE,
 	CPUHP_AP_WORKQUEUE_ONLINE,
-- 
2.43.0



From samuel.holland at sifive.com  Thu Feb 15 16:08:15 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Thu, 15 Feb 2024 16:08:15 -0800
Subject: [PATCH v1 3/6] dt-bindings: cache: Add SiFive Extensible Cache controller
In-Reply-To: <20240216000837.1868917-1-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
Message-ID: <20240216000837.1868917-4-samuel.holland@sifive.com>

From: Eric Lin <eric.lin at sifive.com>

Add YAML DT binding documentation for the SiFive Extensible Cache
controller. The Extensible Cache controller interleaves cache blocks
across a number of heterogeneous independently-programmed slices. Each
slice contains an MMIO interface for configuration, cache maintenance,
error reporting, and performance monitoring.

Signed-off-by: Eric Lin <eric.lin at sifive.com>
Co-developed-by: Samuel Holland <samuel.holland at sifive.com>
Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 .../cache/sifive,extensiblecache0.yaml        | 136 ++++++++++++++++++
 1 file changed, 136 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/cache/sifive,extensiblecache0.yaml

diff --git a/Documentation/devicetree/bindings/cache/sifive,extensiblecache0.yaml b/Documentation/devicetree/bindings/cache/sifive,extensiblecache0.yaml
new file mode 100644
index 000000000000..d027114dbdba
--- /dev/null
+++ b/Documentation/devicetree/bindings/cache/sifive,extensiblecache0.yaml
@@ -0,0 +1,136 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (C) 2023-2024 SiFive, Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cache/sifive,extensiblecache0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive Extensible Cache Controller
+
+maintainers:
+  - Eric Lin <eric.lin at sifive.com>
+
+description:
+  The SiFive Extensible Cache Controller provides a high-performance extensible
+  system (L2 or L3) cache. It is divided into several independent heterogeneous
+  slices, enabling a flexible topology and physical design.
+
+allOf:
+  - $ref: /schemas/cache-controller.yaml#
+
+select:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - sifive,extensiblecache0
+
+  required:
+    - compatible
+
+properties:
+  compatible:
+    items:
+      - const: sifive,extensiblecache0
+      - const: cache
+
+  "#address-cells": true
+  "#size-cells": true
+  ranges: true
+
+  interrupts:
+    maxItems: 1
+
+  cache-block-size:
+    const: 64
+
+  cache-level: true
+  cache-sets: true
+  cache-size: true
+  cache-unified: true
+
+patternProperties:
+  "^cache-controller@[0-9a-f]+$":
+    type: object
+    additionalProperties: false
+    properties:
+      reg:
+        maxItems: 1
+
+      cache-block-size:
+        const: 64
+
+      cache-sets: true
+      cache-size: true
+      cache-unified: true
+
+      sifive,bm-event-counters:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        default: 0
+        description: Number of bucket monitor registers in this slice
+
+      sifive,cache-ways:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: Number of ways in this slice (independent of cache size)
+
+      sifive,perfmon-counters:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        default: 0
+        description: Number of PMU counter registers in this slice
+
+    required:
+      - reg
+      - cache-block-size
+      - cache-sets
+      - cache-size
+      - cache-unified
+      - sifive,cache-ways
+
+required:
+  - compatible
+  - ranges
+  - interrupts
+  - cache-block-size
+  - cache-level
+  - cache-sets
+  - cache-size
+  - cache-unified
+
+additionalProperties: false
+
+examples:
+  - |
+    cache-controller at 30040000 {
+        compatible = "sifive,extensiblecache0", "cache";
+        ranges = <0x30040000 0x30040000 0x10000>;
+        interrupts = <0x4>;
+        cache-block-size = <0x40>;
+        cache-level = <3>;
+        cache-sets = <0x800>;
+        cache-size = <0x100000>;
+        cache-unified;
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        cache-controller at 30040000 {
+            reg = <0x30040000 0x4000>;
+            cache-block-size = <0x40>;
+            cache-sets = <0x400>;
+            cache-size = <0x80000>;
+            cache-unified;
+            sifive,bm-event-counters = <8>;
+            sifive,cache-ways = <9>;
+            sifive,perfmon-counters = <8>;
+        };
+
+        cache-controller at 30044000 {
+            reg = <0x30044000 0x4000>;
+            cache-block-size = <0x40>;
+            cache-sets = <0x400>;
+            cache-size = <0x80000>;
+            cache-unified;
+            sifive,bm-event-counters = <8>;
+            sifive,cache-ways = <9>;
+            sifive,perfmon-counters = <8>;
+        };
+    };
-- 
2.43.0



From samuel.holland at sifive.com  Thu Feb 15 16:08:16 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Thu, 15 Feb 2024 16:08:16 -0800
Subject: [PATCH v1 4/6] drivers/perf: Add SiFive Extensible Cache PMU driver
In-Reply-To: <20240216000837.1868917-1-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
Message-ID: <20240216000837.1868917-5-samuel.holland@sifive.com>

From: Eric Lin <eric.lin at sifive.com>

Add a driver for the PMU found in the SiFive Extensible Cache
controller. This PMU provides a configurable number of counters and a
variety of events. Events are grouped into sets. Each counter can count
events from only one set at a time; however, it can count any number of
events within that set simultaneously. The PMU hardware does not provide
an overflow interrupt.

The counter inhibit register is used to atomically start/stop/read a
group of counters so their values can be usefully compared.

Some events can be filtered further by client ID (e.g. CPU or external
DMA master). That functionality is not supported by this driver.

This driver further assumes that a single Extensible Cache instance is
shared by all CPUs in the system.

Example usage:

$ perf stat -e sifive_ecache_pmu/inner_rd_request/,
	       sifive_ecache_pmu/inner_wr_request/,
	       sifive_ecache_pmu/inner_rd_request_hit/,
	       sifive_ecache_pmu/inner_wr_request_hit/ ls

 Performance counter stats for 'system wide':

            148001      sifive_ecache_pmu/inner_rd_request/
            121064      sifive_ecache_pmu/inner_wr_request/
            113124      sifive_ecache_pmu/inner_rd_request_hit/
            120860      sifive_ecache_pmu/inner_wr_request_hit/

       0.010643962 seconds time elapsed

Example combining the read/write events together within each counter:

$ perf stat -e sifive_ecache_pmu/event=0x601/,
	       sifive_ecache_pmu/event=0xc001/ ls

 Performance counter stats for 'system wide':

            262619      sifive_ecache_pmu/event=0x601/
            224533      sifive_ecache_pmu/event=0xc001/

       0.009794808 seconds time elapsed

Signed-off-by: Eric Lin <eric.lin at sifive.com>
Co-developed-by: Samuel Holland <samuel.holland at sifive.com>
Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 drivers/perf/Kconfig             |  10 +
 drivers/perf/Makefile            |   1 +
 drivers/perf/sifive_ecache_pmu.c | 675 +++++++++++++++++++++++++++++++
 include/linux/cpuhotplug.h       |   1 +
 4 files changed, 687 insertions(+)
 create mode 100644 drivers/perf/sifive_ecache_pmu.c

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index b4e4db7424b4..8a3b2b88d8b5 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -164,6 +164,16 @@ config SIFIVE_CCACHE_PMU
 	  for measuring whole-system L2/L3 cache performance using the perf
 	  events subsystem.
 
+config SIFIVE_ECACHE_PMU
+	tristate "SiFive Extensible Cache PMU"
+	depends on RISCV || COMPILE_TEST
+	depends on OF
+	help
+	  Support for the Extensible Cache performance monitoring unit (PMU) on
+	  SiFive platforms. The Composable Cache PMU provides up to 8 counters
+	  for measuring whole-system L2/L3 cache performance using the perf
+	  events subsystem.
+
 config THUNDERX2_PMU
 	tristate "Cavium ThunderX2 SoC PMU UNCORE"
 	depends on ARCH_THUNDER2 || COMPILE_TEST
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 51ef5f50ace4..a51686b413f2 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_RISCV_PMU) += riscv_pmu.o
 obj-$(CONFIG_RISCV_PMU_LEGACY) += riscv_pmu_legacy.o
 obj-$(CONFIG_RISCV_PMU_SBI) += riscv_pmu_sbi.o
 obj-$(CONFIG_SIFIVE_CCACHE_PMU) += sifive_ccache_pmu.o
+obj-$(CONFIG_SIFIVE_ECACHE_PMU) += sifive_ecache_pmu.o
 obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
diff --git a/drivers/perf/sifive_ecache_pmu.c b/drivers/perf/sifive_ecache_pmu.c
new file mode 100644
index 000000000000..51b2fa3781c9
--- /dev/null
+++ b/drivers/perf/sifive_ecache_pmu.c
@@ -0,0 +1,675 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SiFive EC (Extensible Cache) PMU driver
+ *
+ * Copyright (C) 2023-2024 SiFive, Inc.
+ * Copyright (C) Eric Lin <eric.lin at sifive.com>
+ *
+ */
+
+#include <linux/cpuhotplug.h>
+#include <linux/cpumask.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+
+#define ECACHE_SELECT_OFFSET		0x2000
+#define ECACHE_CLIENT_FILTER_OFFSET	0x2200
+#define ECACHE_COUNTER_INHIBIT_OFFSET	0x2800
+#define ECACHE_COUNTER_OFFSET		0x3000
+
+#define ECACHE_PMU_MAX_COUNTERS		8
+
+struct sifive_ecache_pmu_slice {
+	void __iomem			*base;
+};
+
+struct sifive_ecache_pmu {
+	struct pmu			pmu;
+	struct hlist_node		node;
+	struct notifier_block		cpu_pm_nb;
+	struct perf_event		*events[ECACHE_PMU_MAX_COUNTERS];
+	DECLARE_BITMAP(used_mask, ECACHE_PMU_MAX_COUNTERS);
+	unsigned int			cpu;
+	unsigned int			txn_flags;
+	int				n_counters;
+	int				n_slices;
+	struct sifive_ecache_pmu_slice	slice[] __counted_by(n_slices);
+};
+
+#define to_ecache_pmu(p) (container_of(p, struct sifive_ecache_pmu, pmu))
+
+/* Store the counter mask for a group in the leader's extra_reg */
+#define event_group_mask(event) (event->group_leader->hw.extra_reg.config)
+
+#ifndef readq
+static inline u64 readq(void __iomem *addr)
+{
+	return readl(addr) | (((u64)readl(addr + 4)) << 32);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 v, void __iomem *addr)
+{
+	writel(lower_32_bits(v), addr);
+	writel(upper_32_bits(v), addr + 4);
+}
+#endif
+
+/*
+ * sysfs attributes
+ *
+ * We export:
+ * - cpumask, used by perf user space and other tools to know on which CPUs to create events
+ * - events, used by perf user space and other tools to create events symbolically, e.g.:
+ *     perf stat -a -e sifive_ecache_pmu/event=inner_put_partial_data_hit/ ls
+ *     perf stat -a -e sifive_ecache_pmu/event=0x101/ ls
+ * - formats, used by perf user space and other tools to configure events
+ */
+
+/* cpumask */
+static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sifive_ecache_pmu *ecache_pmu = dev_get_drvdata(dev);
+
+	if (ecache_pmu->cpu >= nr_cpu_ids)
+		return 0;
+
+	return sysfs_emit(buf, "%d\n", ecache_pmu->cpu);
+};
+
+static DEVICE_ATTR_RO(cpumask);
+
+static struct attribute *sifive_ecache_pmu_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL,
+};
+
+static const struct attribute_group sifive_ecache_pmu_cpumask_group = {
+	.attrs = sifive_ecache_pmu_cpumask_attrs,
+};
+
+/* events */
+static ssize_t sifive_ecache_pmu_event_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 sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
+}
+
+#define SET_EVENT_SELECT(_event, _set)	(BIT_ULL((_event) + 8) | (_set))
+#define ECACHE_PMU_EVENT_ATTR(_name, _event, _set) \
+	PMU_EVENT_ATTR_ID(_name, sifive_ecache_pmu_event_show, SET_EVENT_SELECT(_event, _set))
+
+enum ecache_pmu_event_set1 {
+	INNER_REQUEST = 0,
+	INNER_RD_REQUEST,
+	INNER_WR_REQUEST,
+	INNER_PF_REQUEST,
+	OUTER_PRB_REQUEST,
+	INNER_REQUEST_HIT,
+	INNER_RD_REQUEST_HIT,
+	INNER_WR_REQUEST_HIT,
+	INNER_PF_REQUEST_HIT,
+	OUTER_PRB_REQUEST_HIT,
+	INNER_REQUEST_HITPF,
+	INNER_RD_REQUEST_HITPF,
+	INNER_WR_REQUEST_HITPF,
+	INNER_PF_REQUEST_HITPF,
+	OUTER_PRB_REQUEST_HITPF,
+	INNER_REQUEST_MISS,
+	INNER_RD_REQUEST_MISS,
+	INNER_WR_REQUEST_MISS,
+	INNER_PF_REQUEST_MISS,
+	OUTER_PRB_REQUEST_MISS,
+	ECACHE_PMU_MAX_EVENT1_IDX
+};
+
+enum ecache_pmu_event_set2 {
+	OUTER_REQUEST = 0,
+	OUTER_RD_REQUEST,
+	OUTER_PUT_REQUEST,
+	OUTER_EV_REQUEST,
+	OUTER_PF_REQUEST,
+	INNER_PRB_REQUEST,
+	INNER_REQUEST_WCYC,
+	INNER_RD_REQUEST_WCYC,
+	INNER_WR_REQUEST_WCYC,
+	INNER_PF_REQUEST_WCYC,
+	OUTER_PRB_REQUEST_WCYC,
+	OUTER_REQUEST_WCYC,
+	OUTER_RD_REQUEST_WCYC,
+	OUTER_PUT_REQUEST_WCYC,
+	OUTER_EV_REQUEST_WCYC,
+	OUTER_PF_REQUEST_WCYC,
+	INNER_PRB_REQUEST_WCYC,
+	INNER_AG_WCYC,
+	INNER_AP_WCYC,
+	INNER_AH_WCYC,
+	INNER_BP_WCYC,
+	INNER_CP_WCYC,
+	INNER_CX_WCYC,
+	INNER_DG_WCYC,
+	INNER_DP_WCYC,
+	INNER_DX_WCYC,
+	INNER_EG_WCYC,
+	OUTER_AG_WCYC,
+	OUTER_AP_WCYC,
+	OUTER_AH_WCYC,
+	OUTER_BP_WCYC,
+	OUTER_CP_WCYC,
+	OUTER_CX_WCYC,
+	OUTER_DG_WCYC,
+	OUTER_DP_WCYC,
+	OUTER_DX_WCYC,
+	OUTER_EG_WCYC,
+	ECACHE_PMU_MAX_EVENT2_IDX
+};
+
+static struct attribute *sifive_ecache_pmu_events[] = {
+	/*  pmEventSelect1 */
+	ECACHE_PMU_EVENT_ATTR(inner_request, INNER_REQUEST, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_rd_request, INNER_RD_REQUEST, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_wr_request, INNER_WR_REQUEST, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_pf_request, INNER_PF_REQUEST, 1),
+	ECACHE_PMU_EVENT_ATTR(outer_prb_request, OUTER_PRB_REQUEST, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_request_hit, INNER_REQUEST_HIT,  1),
+	ECACHE_PMU_EVENT_ATTR(inner_rd_request_hit, INNER_RD_REQUEST_HIT, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_wr_request_hit, INNER_WR_REQUEST_HIT, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_pf_request_hit, INNER_PF_REQUEST_HIT, 1),
+	ECACHE_PMU_EVENT_ATTR(outer_prb_request_hit, OUTER_PRB_REQUEST_HIT, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_request_hitpf, INNER_REQUEST_HITPF,  1),
+	ECACHE_PMU_EVENT_ATTR(inner_rd_request_hitpf, INNER_RD_REQUEST_HITPF, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_wr_request_hitpf, INNER_WR_REQUEST_HITPF, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_pf_request_hitpf, INNER_PF_REQUEST_HITPF, 1),
+	ECACHE_PMU_EVENT_ATTR(outer_prb_request_hitpf, OUTER_PRB_REQUEST_HITPF, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_request_miss, INNER_REQUEST_MISS,  1),
+	ECACHE_PMU_EVENT_ATTR(inner_rd_request_miss, INNER_RD_REQUEST_MISS, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_wr_request_miss, INNER_WR_REQUEST_MISS, 1),
+	ECACHE_PMU_EVENT_ATTR(inner_pf_request_miss, INNER_PF_REQUEST_MISS, 1),
+	ECACHE_PMU_EVENT_ATTR(outer_prb_request_miss, OUTER_PRB_REQUEST_MISS, 1),
+
+	/*  pmEventSelect2 */
+	ECACHE_PMU_EVENT_ATTR(outer_request, OUTER_REQUEST, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_rd_request, OUTER_RD_REQUEST, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_put_request, OUTER_PUT_REQUEST, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_ev_request, OUTER_EV_REQUEST, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_pf_request, OUTER_PF_REQUEST, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_prb_request, INNER_PRB_REQUEST, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_request_wcyc, INNER_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_rd_request_wcyc, INNER_RD_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_wr_request_wcyc, INNER_WR_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_pf_request_wcyc, INNER_PF_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_prb_request_wcyc, OUTER_PRB_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_request_wcyc, OUTER_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_rd_request_wcyc, OUTER_RD_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_put_request_wcyc, OUTER_PUT_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_ev_request_wcyc, OUTER_EV_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_pf_request_wcyc, OUTER_PF_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_prb_request_wcyc, INNER_PRB_REQUEST_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_ag_wcyc, INNER_AG_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_ap_wcyc, INNER_AP_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_ah_wcyc, INNER_AH_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_bp_wcyc, INNER_BP_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_cp_wcyc, INNER_CP_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_cx_wcyc, INNER_CX_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_dg_wcyc, INNER_DG_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_dp_wcyc, INNER_DP_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_dx_wcyc, INNER_DX_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(inner_eg_wcyc, INNER_EG_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_ag_wcyc, OUTER_AG_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_ap_wcyc, OUTER_AP_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_ah_wcyc, OUTER_AH_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_bp_wcyc, OUTER_BP_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_cp_wcyc, OUTER_CP_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_cx_wcyc, OUTER_CX_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_dg_wcyc, OUTER_DG_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_dp_wcyc, OUTER_DP_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_dx_wcyc, OUTER_DX_WCYC, 2),
+	ECACHE_PMU_EVENT_ATTR(outer_eg_wcyc, OUTER_EG_WCYC, 2),
+	NULL
+};
+
+static struct attribute_group sifive_ecache_pmu_events_group = {
+	.name = "events",
+	.attrs = sifive_ecache_pmu_events,
+};
+
+/* formats */
+PMU_FORMAT_ATTR(event, "config:0-63");
+
+static struct attribute *sifive_ecache_pmu_formats[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group sifive_ecache_pmu_format_group = {
+	.name = "format",
+	.attrs = sifive_ecache_pmu_formats,
+};
+
+/*
+ * Per PMU device attribute groups
+ */
+
+static const struct attribute_group *sifive_ecache_pmu_attr_grps[] = {
+	&sifive_ecache_pmu_cpumask_group,
+	&sifive_ecache_pmu_events_group,
+	&sifive_ecache_pmu_format_group,
+	NULL,
+};
+
+/*
+ * Event Initialization
+ */
+
+static int sifive_ecache_pmu_event_init(struct perf_event *event)
+{
+	struct sifive_ecache_pmu *ecache_pmu = to_ecache_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u64 config = event->attr.config;
+	u64 ev_type = config >> 8;
+	u64 set = config & 0xff;
+
+	/* Check if this is a valid set and event */
+	switch (set) {
+	case 1:
+		if (ev_type >= BIT_ULL(ECACHE_PMU_MAX_EVENT1_IDX))
+			return -ENOENT;
+		break;
+	case 2:
+		if (ev_type >= BIT_ULL(ECACHE_PMU_MAX_EVENT2_IDX))
+			return -ENOENT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	/* Do not allocate the hardware counter yet */
+	hwc->idx = -1;
+	hwc->config = config;
+
+	event->cpu = ecache_pmu->cpu;
+
+	return 0;
+}
+
+/*
+ * Low-level functions: reading and writing counters
+ */
+
+static void configure_counter(const struct sifive_ecache_pmu *ecache_pmu,
+			      const struct hw_perf_event *hwc, u64 config)
+{
+	for (int i = 0; i < ecache_pmu->n_slices; i++) {
+		void __iomem *base = ecache_pmu->slice[i].base;
+
+		if (config)
+			writeq(0, base + hwc->event_base);
+		writeq(config, base + hwc->config_base);
+	}
+}
+
+static u64 read_counter(const struct sifive_ecache_pmu *ecache_pmu, const struct hw_perf_event *hwc)
+{
+	u64 value = 0;
+
+	for (int i = 0; i < ecache_pmu->n_slices; i++) {
+		void __iomem *base = ecache_pmu->slice[i].base;
+
+		value += readq(base + hwc->event_base);
+	}
+
+	return value;
+}
+
+static void write_inhibit(const struct sifive_ecache_pmu *ecache_pmu, u64 mask)
+{
+	u64 used_mask;
+
+	/* Inhibit all unused counters in addition to the provided mask */
+	bitmap_to_arr64(&used_mask, ecache_pmu->used_mask, ECACHE_PMU_MAX_COUNTERS);
+	mask |= ~used_mask;
+
+	for (int i = 0; i < ecache_pmu->n_slices; i++) {
+		void __iomem *base = ecache_pmu->slice[i].base;
+
+		writeq(mask, base + ECACHE_COUNTER_INHIBIT_OFFSET);
+	}
+}
+
+/*
+ * pmu->read: read and update the counter
+ */
+static void sifive_ecache_pmu_read(struct perf_event *event)
+{
+	struct sifive_ecache_pmu *ecache_pmu = to_ecache_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u64 prev_raw_count, new_raw_count;
+	u64 oldval;
+
+	/* Inhibit the entire group during a read transaction for atomicity */
+	if (ecache_pmu->txn_flags == PERF_PMU_TXN_READ && event->group_leader == event)
+		write_inhibit(ecache_pmu, event_group_mask(event));
+
+	do {
+		prev_raw_count = local64_read(&hwc->prev_count);
+		new_raw_count = read_counter(ecache_pmu, hwc);
+
+		oldval = local64_cmpxchg(&hwc->prev_count, prev_raw_count, new_raw_count);
+	} while (oldval != prev_raw_count);
+
+	local64_add(new_raw_count - prev_raw_count, &event->count);
+}
+
+/*
+ * State transition functions:
+ *
+ * start()/stop() & add()/del()
+ */
+
+/*
+ * pmu->start: start the event
+ */
+static void sifive_ecache_pmu_start(struct perf_event *event, int flags)
+{
+	struct sifive_ecache_pmu *ecache_pmu = to_ecache_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+		return;
+
+	hwc->state = 0;
+
+	/* Set initial value to 0 */
+	local64_set(&hwc->prev_count, 0);
+
+	/* Enable this counter to count events */
+	configure_counter(ecache_pmu, hwc, hwc->config);
+}
+
+/*
+ * pmu->stop: stop the counter
+ */
+static void sifive_ecache_pmu_stop(struct perf_event *event, int flags)
+{
+	struct sifive_ecache_pmu *ecache_pmu = to_ecache_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (hwc->state & PERF_HES_STOPPED)
+		return;
+
+	/* Disable this counter to count events */
+	configure_counter(ecache_pmu, hwc, 0);
+	sifive_ecache_pmu_read(event);
+
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+}
+
+/*
+ * pmu->add: add the event to the PMU
+ */
+static int sifive_ecache_pmu_add(struct perf_event *event, int flags)
+{
+	struct sifive_ecache_pmu *ecache_pmu = to_ecache_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+
+	/* Find an available counter idx to use for this event */
+	do {
+		idx = find_first_zero_bit(ecache_pmu->used_mask, ecache_pmu->n_counters);
+		if (idx >= ecache_pmu->n_counters)
+			return -EAGAIN;
+	} while (test_and_set_bit(idx, ecache_pmu->used_mask));
+
+	event_group_mask(event) |= BIT_ULL(idx);
+	hwc->config_base = ECACHE_SELECT_OFFSET + 8 * idx;
+	hwc->event_base = ECACHE_COUNTER_OFFSET + 8 * idx;
+	hwc->idx = idx;
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+
+	ecache_pmu->events[idx] = event;
+
+	if (flags & PERF_EF_START)
+		sifive_ecache_pmu_start(event, PERF_EF_RELOAD);
+
+	perf_event_update_userpage(event);
+
+	return 0;
+}
+
+/*
+ * pmu->del: delete the event from the PMU
+ */
+static void sifive_ecache_pmu_del(struct perf_event *event, int flags)
+{
+	struct sifive_ecache_pmu *ecache_pmu = to_ecache_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	/* Stop and release this counter */
+	sifive_ecache_pmu_stop(event, PERF_EF_UPDATE);
+
+	ecache_pmu->events[idx] = NULL;
+	clear_bit(idx, ecache_pmu->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+/*
+ * Transaction synchronization
+ */
+
+static void sifive_ecache_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
+{
+	struct sifive_ecache_pmu *ecache_pmu = to_ecache_pmu(pmu);
+
+	ecache_pmu->txn_flags = txn_flags;
+
+	/* Inhibit any counters that were deleted since the last transaction */
+	if (txn_flags == PERF_PMU_TXN_ADD)
+		write_inhibit(ecache_pmu, 0);
+}
+
+static int sifive_ecache_pmu_commit_txn(struct pmu *pmu)
+{
+	struct sifive_ecache_pmu *ecache_pmu = to_ecache_pmu(pmu);
+
+	ecache_pmu->txn_flags = 0;
+
+	/* Successful transaction: atomically uninhibit the counters in this group */
+	write_inhibit(ecache_pmu, 0);
+
+	return 0;
+}
+
+static void sifive_ecache_pmu_cancel_txn(struct pmu *pmu)
+{
+	struct sifive_ecache_pmu *ecache_pmu = to_ecache_pmu(pmu);
+
+	ecache_pmu->txn_flags = 0;
+
+	/* Failed transaction: leave the counters in this group inhibited */
+}
+
+/*
+ * Driver initialization
+ */
+
+static void sifive_ecache_pmu_hw_init(const struct sifive_ecache_pmu *ecache_pmu)
+{
+	for (int i = 0; i < ecache_pmu->n_slices; i++) {
+		void __iomem *base = ecache_pmu->slice[i].base;
+
+		/* Disable the client filter (not supported by this driver) */
+		writeq(0, base + ECACHE_CLIENT_FILTER_OFFSET);
+	}
+}
+
+static int sifive_ecache_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct sifive_ecache_pmu *ecache_pmu =
+		hlist_entry_safe(node, struct sifive_ecache_pmu, node);
+
+	if (ecache_pmu->cpu >= nr_cpu_ids)
+		ecache_pmu->cpu = cpu;
+
+	return 0;
+}
+
+static int sifive_ecache_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct sifive_ecache_pmu *ecache_pmu =
+		hlist_entry_safe(node, struct sifive_ecache_pmu, node);
+
+	/* Do nothing if this CPU does not own the events */
+	if (cpu != ecache_pmu->cpu)
+		return 0;
+
+	/* Pick a random online CPU */
+	ecache_pmu->cpu = cpumask_any_but(cpu_online_mask, cpu);
+	if (ecache_pmu->cpu >= nr_cpu_ids)
+		return 0;
+
+	/* Migrate PMU events from this CPU to the target CPU */
+	perf_pmu_migrate_context(&ecache_pmu->pmu, cpu, ecache_pmu->cpu);
+
+	return 0;
+}
+
+static int sifive_ecache_pmu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *ecache_node = dev_of_node(dev);
+	struct sifive_ecache_pmu *ecache_pmu;
+	struct device_node *slice_node;
+	u32 slice_counters;
+	int n_slices, ret;
+	int i = 0;
+
+	n_slices = of_get_available_child_count(ecache_node);
+	if (!n_slices)
+		return -ENODEV;
+
+	ecache_pmu = devm_kzalloc(dev, struct_size(ecache_pmu, slice, n_slices), GFP_KERNEL);
+	if (!ecache_pmu)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, ecache_pmu);
+
+	ecache_pmu->pmu = (struct pmu) {
+		.parent		= dev,
+		.attr_groups	= sifive_ecache_pmu_attr_grps,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
+		.task_ctx_nr	= perf_invalid_context,
+		.event_init	= sifive_ecache_pmu_event_init,
+		.add		= sifive_ecache_pmu_add,
+		.del		= sifive_ecache_pmu_del,
+		.start		= sifive_ecache_pmu_start,
+		.stop		= sifive_ecache_pmu_stop,
+		.read		= sifive_ecache_pmu_read,
+		.start_txn	= sifive_ecache_pmu_start_txn,
+		.commit_txn	= sifive_ecache_pmu_commit_txn,
+		.cancel_txn	= sifive_ecache_pmu_cancel_txn,
+	};
+	ecache_pmu->cpu = nr_cpu_ids;
+	ecache_pmu->n_counters = ECACHE_PMU_MAX_COUNTERS;
+	ecache_pmu->n_slices = n_slices;
+
+	for_each_available_child_of_node(ecache_node, slice_node) {
+		struct sifive_ecache_pmu_slice *slice = &ecache_pmu->slice[i++];
+
+		slice->base = devm_of_iomap(dev, slice_node, 0, NULL);
+		if (IS_ERR(slice->base))
+			return PTR_ERR(slice->base);
+
+		/* Get number of counters from slice node */
+		ret = of_property_read_u32(slice_node, "sifive,perfmon-counters", &slice_counters);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "Slice %pOF missing sifive,perfmon-counters property\n",
+					     slice_node);
+
+		ecache_pmu->n_counters = min_t(u32, slice_counters, ecache_pmu->n_counters);
+	}
+
+	sifive_ecache_pmu_hw_init(ecache_pmu);
+
+	ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_SIFIVE_ECACHE_ONLINE, &ecache_pmu->node);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to add CPU hotplug instance\n");
+
+	ret = perf_pmu_register(&ecache_pmu->pmu, "sifive_ecache_pmu", -1);
+	if (ret) {
+		dev_err_probe(dev, ret, "Failed to register PMU\n");
+		goto err_remove_instance;
+	}
+
+	return 0;
+
+err_remove_instance:
+	cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_SIFIVE_ECACHE_ONLINE, &ecache_pmu->node);
+
+	return ret;
+}
+
+static void sifive_ecache_pmu_remove(struct platform_device *pdev)
+{
+	struct sifive_ecache_pmu *ecache_pmu = platform_get_drvdata(pdev);
+
+	perf_pmu_unregister(&ecache_pmu->pmu);
+	cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_SIFIVE_ECACHE_ONLINE, &ecache_pmu->node);
+}
+
+static const struct of_device_id sifive_ecache_pmu_of_match[] = {
+	{ .compatible = "sifive,extensiblecache0" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sifive_ecache_pmu_of_match);
+
+static struct platform_driver sifive_ecache_pmu_driver = {
+	.probe	= sifive_ecache_pmu_probe,
+	.remove_new	= sifive_ecache_pmu_remove,
+	.driver	= {
+		.name		= "sifive_ecache_pmu",
+		.of_match_table	= sifive_ecache_pmu_of_match,
+	},
+};
+
+static void __exit sifive_ecache_pmu_exit(void)
+{
+	platform_driver_unregister(&sifive_ecache_pmu_driver);
+	cpuhp_remove_multi_state(CPUHP_AP_PERF_RISCV_SIFIVE_ECACHE_ONLINE);
+}
+module_exit(sifive_ecache_pmu_exit);
+
+static int __init sifive_ecache_pmu_init(void)
+{
+	int ret;
+
+	ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_RISCV_SIFIVE_ECACHE_ONLINE,
+				      "perf/sifive/ecache:online",
+				      sifive_ecache_pmu_online_cpu,
+				      sifive_ecache_pmu_offline_cpu);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&sifive_ecache_pmu_driver);
+	if (ret)
+		goto err_remove_state;
+
+	return 0;
+
+err_remove_state:
+	cpuhp_remove_multi_state(CPUHP_AP_PERF_RISCV_SIFIVE_ECACHE_ONLINE);
+
+	return ret;
+}
+module_init(sifive_ecache_pmu_init);
+
+MODULE_LICENSE("GPL");
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index be6361fdc8ba..55bd3a5e0033 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -231,6 +231,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_POWERPC_HV_24x7_ONLINE,
 	CPUHP_AP_PERF_POWERPC_HV_GPCI_ONLINE,
 	CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE,
+	CPUHP_AP_PERF_RISCV_SIFIVE_ECACHE_ONLINE,
 	CPUHP_AP_PERF_CSKY_ONLINE,
 	CPUHP_AP_WATCHDOG_ONLINE,
 	CPUHP_AP_WORKQUEUE_ONLINE,
-- 
2.43.0



From samuel.holland at sifive.com  Thu Feb 15 16:08:17 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Thu, 15 Feb 2024 16:08:17 -0800
Subject: [PATCH v1 5/6] dt-bindings: cache: Add SiFive Private L2 Cache controller
In-Reply-To: <20240216000837.1868917-1-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
Message-ID: <20240216000837.1868917-6-samuel.holland@sifive.com>

From: Eric Lin <eric.lin at sifive.com>

Add YAML DT binding documentation for the SiFive Private L2 Cache
controller. Some functionality and the corresponding register bits were
removed in the sifive,pl2cache1 version of the hardware, which creates
the unusual situation where the newer hardware's compatible string is
the fallback for the older one.

Signed-off-by: Eric Lin <eric.lin at sifive.com>
Co-developed-by: Samuel Holland <samuel.holland at sifive.com>
Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

Changes in v1:
 - Add back select: clause to binding
 - Make sifive,pl2cache1 the fallback for sifive,pl2cache0
 - Fix the order of the reg property declaration
 - Document the sifive,perfmon-counters property

 .../bindings/cache/sifive,pl2cache0.yaml      | 81 +++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/cache/sifive,pl2cache0.yaml

diff --git a/Documentation/devicetree/bindings/cache/sifive,pl2cache0.yaml b/Documentation/devicetree/bindings/cache/sifive,pl2cache0.yaml
new file mode 100644
index 000000000000..d89e2e5d0a97
--- /dev/null
+++ b/Documentation/devicetree/bindings/cache/sifive,pl2cache0.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (C) 2023-2024 SiFive, Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cache/sifive,pl2cache0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive Private L2 Cache Controller
+
+maintainers:
+  - Eric Lin <eric.lin at sifive.com>
+
+description:
+  The SiFive Private L2 Cache Controller is a per-core cache which communicates
+  with both the upstream L1 caches and downstream L3 cache or memory, enabling a
+  high-performance cache subsystem.
+
+allOf:
+  - $ref: /schemas/cache-controller.yaml#
+
+select:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - sifive,pl2cache1
+
+  required:
+    - compatible
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: sifive,pl2cache0
+          - const: sifive,pl2cache1
+          - const: cache
+      - items:
+          - const: sifive,pl2cache1
+          - const: cache
+
+  reg:
+    maxItems: 1
+
+  cache-block-size: true
+  cache-level: true
+  cache-sets: true
+  cache-size: true
+  cache-unified: true
+
+  next-level-cache: true
+
+  sifive,perfmon-counters:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+    description: Number of PMU counter registers
+
+required:
+  - compatible
+  - reg
+  - cache-block-size
+  - cache-level
+  - cache-sets
+  - cache-size
+  - cache-unified
+
+additionalProperties: false
+
+examples:
+  - |
+    cache-controller at 10104000 {
+        compatible = "sifive,pl2cache1", "cache";
+        reg = <0x10104000 0x4000>;
+        cache-block-size = <64>;
+        cache-level = <2>;
+        cache-sets = <512>;
+        cache-size = <262144>;
+        cache-unified;
+        next-level-cache = <&L4>;
+        sifive,perfmon-counters = <6>;
+    };
-- 
2.43.0



From samuel.holland at sifive.com  Thu Feb 15 16:08:18 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Thu, 15 Feb 2024 16:08:18 -0800
Subject: [PATCH v1 6/6] drivers/perf: Add SiFive Private L2 Cache PMU driver
In-Reply-To: <20240216000837.1868917-1-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
Message-ID: <20240216000837.1868917-7-samuel.holland@sifive.com>

From: Greentime Hu <greentime.hu at sifive.com>

Add a driver for the PMU found in the SiFive Private L2 Cache
controller. This PMU provides a configurable number of counters and a
variety of events. Events are grouped into sets. Each counter can count
events from only one set at a time; however, it can count any number of
events within that set simultaneously. The PMU hardware does not provide
an overflow interrupt or a way to atomically control groups of counters.

A separate Private L2 Cache instance exists for each core, so this
driver supports per-core and per-task profiling.

Some events can be filtered further by client ID (e.g. CPU or external
DMA master). That functionality is not supported by this driver.

Example usage:

$ perf stat -e sifive_pl2_pmu/inner_get/,sifive_pl2_pmu/outer_get/ ls

 Performance counter stats for 'ls':

             95041      sifive_pl2_pmu/inner_get/
                 3      sifive_pl2_pmu/outer_get/

       0.003971538 seconds time elapsed

       0.000000000 seconds user
       0.006315000 seconds sys

Example combining multiple events together within each counter:

$ perf stat -e sifive_pl2_pmu/event=0x301/,   # inner_put_*_data
	       sifive_pl2_pmu/event=0x303/ ls # outer_put_*_data

 Performance counter stats for 'ls':

              6828      sifive_pl2_pmu/event=0x301/
                11      sifive_pl2_pmu/event=0x303/

       0.005696538 seconds time elapsed

       0.000000000 seconds user
       0.006337000 seconds sys

Signed-off-by: Greentime Hu <greentime.hu at sifive.com>
Co-developed-by: Eric Lin <eric.lin at sifive.com>
Signed-off-by: Eric Lin <eric.lin at sifive.com>
Co-developed-by: Samuel Holland <samuel.holland at sifive.com>
Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

Changes in v1:
 - Add missing events to PL2 sets 2, 4, and 5
 - Use event_base and config_base to precompute register addresses
 - Check event validity earlier, in the .event_init hook
 - Implement .filter for systems where only some CPUs have a PL2
 - Only allocate percpu data when probing each PL2 instance
 - Reference count the `struct pmu` to fix unbind/bind crashes
 - Probe via DT since the PMU driver is now the only PL2 driver
 - Allow the driver to be built as a module

 drivers/perf/Kconfig          |  10 +
 drivers/perf/Makefile         |   1 +
 drivers/perf/sifive_pl2_pmu.c | 748 ++++++++++++++++++++++++++++++++++
 3 files changed, 759 insertions(+)
 create mode 100644 drivers/perf/sifive_pl2_pmu.c

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 8a3b2b88d8b5..bd5ebed8630b 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -174,6 +174,16 @@ config SIFIVE_ECACHE_PMU
 	  for measuring whole-system L2/L3 cache performance using the perf
 	  events subsystem.
 
+config SIFIVE_PL2_PMU
+	tristate "SiFive Private L2 Cache PMU"
+	depends on RISCV || COMPILE_TEST
+	depends on OF
+	help
+	  Support for the Private L2 Cache performance monitoring unit (PMU) on
+	  SiFive platforms. The Private L2 Cache PMU provides up to 64 counters
+	  for measuring per-program or per-hart L2 cache performance using the
+	  perf events subsystem.
+
 config THUNDERX2_PMU
 	tristate "Cavium ThunderX2 SoC PMU UNCORE"
 	depends on ARCH_THUNDER2 || COMPILE_TEST
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index a51686b413f2..d5501196dcd8 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_RISCV_PMU_LEGACY) += riscv_pmu_legacy.o
 obj-$(CONFIG_RISCV_PMU_SBI) += riscv_pmu_sbi.o
 obj-$(CONFIG_SIFIVE_CCACHE_PMU) += sifive_ccache_pmu.o
 obj-$(CONFIG_SIFIVE_ECACHE_PMU) += sifive_ecache_pmu.o
+obj-$(CONFIG_SIFIVE_PL2_PMU) += sifive_pl2_pmu.o
 obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
diff --git a/drivers/perf/sifive_pl2_pmu.c b/drivers/perf/sifive_pl2_pmu.c
new file mode 100644
index 000000000000..d0bbac0dec06
--- /dev/null
+++ b/drivers/perf/sifive_pl2_pmu.c
@@ -0,0 +1,748 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SiFive Private L2 Cache PMU driver
+ *
+ * Copyright (C) 2018-2024 SiFive, Inc.
+ */
+
+#include <linux/cpu_pm.h>
+#include <linux/cpumask.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+#include <linux/refcount.h>
+
+#define PL2_SELECT_OFFSET		0x2000
+#define PL2_CLIENT_FILTER_OFFSET	0x2800
+#define PL2_COUNTER_OFFSET		0x3000
+
+#define PL2_PMU_MAX_COUNTERS		64
+
+struct sifive_pl2_pmu_event {
+	void __iomem			*base;
+	DECLARE_BITMAP(used_mask, PL2_PMU_MAX_COUNTERS);
+	unsigned int			cpu;
+	int				n_counters;
+	struct perf_event		*events[] __counted_by(n_counters);
+};
+
+struct sifive_pl2_pmu {
+	struct pmu			pmu;
+	struct notifier_block		cpu_pm_nb;
+	refcount_t			refcount;
+	struct sifive_pl2_pmu_event	*__percpu *event;
+};
+
+#define to_pl2_pmu(p) (container_of(p, struct sifive_pl2_pmu, pmu))
+
+static DEFINE_MUTEX(g_mutex);
+static struct sifive_pl2_pmu *g_pl2_pmu;
+
+#ifndef readq
+static inline u64 readq(void __iomem *addr)
+{
+	return readl(addr) | (((u64)readl(addr + 4)) << 32);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 v, void __iomem *addr)
+{
+	writel(lower_32_bits(v), addr);
+	writel(upper_32_bits(v), addr + 4);
+}
+#endif
+
+/*
+ * sysfs attributes
+ *
+ * We export:
+ * - events, used by perf user space and other tools to create events symbolically, e.g.:
+ *     perf stat -a -e sifive_pl2_pmu/event=inner_put_partial_data_hit/ ls
+ *     perf stat -a -e sifive_pl2_pmu/event=0x101/ ls
+ * - formats, used by perf user space and other tools to configure events
+ */
+
+/* events */
+static ssize_t sifive_pl2_pmu_event_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 sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
+}
+
+#define SET_EVENT_SELECT(_event, _set)	(BIT_ULL((_event) + 8) | (_set))
+#define PL2_PMU_EVENT_ATTR(_name, _event, _set) \
+	PMU_EVENT_ATTR_ID(_name, sifive_pl2_pmu_event_show, SET_EVENT_SELECT(_event, _set))
+
+enum pl2_pmu_event_set1 {
+	INNER_PUT_FULL_DATA = 0,
+	INNER_PUT_PARTIAL_DATA,
+	INNER_ATOMIC_DATA,
+	INNER_GET,
+	INNER_PREFETCH_READ,
+	INNER_PREFETCH_WRITE,
+	INNER_ACQUIRE_BLOCK_NTOB,
+	INNER_ACQUIRE_BLOCK_NTOT,
+	INNER_ACQUIRE_BLOCK_BTOT,
+	INNER_ACQUIRE_PERM_NTOT,
+	INNER_ACQUIRE_PERM_BTOT,
+	INNER_RELEASE_TTOB,
+	INNER_RELEASE_TTON,
+	INNER_RELEASE_BTON,
+	INNER_RELEASE_DATA_TTOB,
+	INNER_RELEASE_DATA_TTON,
+	INNER_RELEASE_DATA_BTON,
+	INNER_RELEASE_DATA_TTOT,
+	INNER_PROBE_BLOCK_TOT,
+	INNER_PROBE_BLOCK_TOB,
+	INNER_PROBE_BLOCK_TON,
+	INNER_PROBE_PERM_TON,
+	INNER_PROBE_ACK_TTOB,
+	INNER_PROBE_ACK_TTON,
+	INNER_PROBE_ACK_BTON,
+	INNER_PROBE_ACK_TTOT,
+	INNER_PROBE_ACK_BTOB,
+	INNER_PROBE_ACK_NTON,
+	INNER_PROBE_ACK_DATA_TTOB,
+	INNER_PROBE_ACK_DATA_TTON,
+	INNER_PROBE_ACK_DATA_TTOT,
+	PL2_PMU_MAX_EVENT1_IDX
+};
+
+enum pl2_pmu_event_set2 {
+	INNER_PUT_FULL_DATA_HIT = 0,
+	INNER_PUT_PARTIAL_DATA_HIT,
+	INNER_ATOMIC_DATA_HIT,
+	INNER_GET_HIT,
+	INNER_PREFETCH_READ_HIT,
+	INNER_ACQUIRE_BLOCK_NTOB_HIT,
+	INNER_ACQUIRE_PERM_NTOT_HIT,
+	INNER_RELEASE_TTOB_HIT,
+	INNER_RELEASE_DATA_TTOB_HIT,
+	OUTER_PROBE_BLOCK_TOT_HIT,
+	INNER_PUT_FULL_DATA_HIT_SHARED,
+	INNER_PUT_PARTIAL_DATA_HIT_SHARED,
+	INNER_ATOMIC_DATA_HIT_SHARED,
+	INNER_GET_HIT_SHARED,
+	INNER_PREFETCH_READ_HIT_SHARED,
+	INNER_ACQUIRE_BLOCK_NTOB_HIT_SHARED,
+	INNER_ACQUIRE_PERM_NTOT_HIT_SHARED,
+	INNER_RELEASE_TTOB_HIT_SHARED,
+	INNER_RELEASE_DATA_TTOB_HIT_SHARED,
+	OUTER_PROBE_BLOCK_TOT_HIT_SHARED,
+	OUTER_PROBE_BLOCK_TOT_HIT_DIRTY,
+	PL2_PMU_MAX_EVENT2_IDX
+};
+
+enum pl2_pmu_event_set3 {
+	OUTER_PUT_FULL_DATA = 0,
+	OUTER_PUT_PARTIAL_DATA,
+	OUTER_ATOMIC_DATA,
+	OUTER_GET,
+	OUTER_PREFETCH_READ,
+	OUTER_PREFETCH_WRITE,
+	OUTER_ACQUIRE_BLOCK_NTOB,
+	OUTER_ACQUIRE_BLOCK_NTOT,
+	OUTER_ACQUIRE_BLOCK_BTOT,
+	OUTER_ACQUIRE_PERM_NTOT,
+	OUTER_ACQUIRE_PERM_BTOT,
+	OUTER_RELEARE_TTOB,
+	OUTER_RELEARE_TTON,
+	OUTER_RELEARE_BTON,
+	OUTER_RELEARE_DATA_TTOB,
+	OUTER_RELEARE_DATA_TTON,
+	OUTER_RELEARE_DATA_BTON,
+	OUTER_RELEARE_DATA_TTOT,
+	OUTER_PROBE_BLOCK_TOT,
+	OUTER_PROBE_BLOCK_TOB,
+	OUTER_PROBE_BLOCK_TON,
+	OUTER_PROBE_PERM_TON,
+	OUTER_PROBE_ACK_TTOB,
+	OUTER_PROBE_ACK_TTON,
+	OUTER_PROBE_ACK_BTON,
+	OUTER_PROBE_ACK_TTOT,
+	OUTER_PROBE_ACK_BTOB,
+	OUTER_PROBE_ACK_NTON,
+	OUTER_PROBE_ACK_DATA_TTOB,
+	OUTER_PROBE_ACK_DATA_TTON,
+	OUTER_PROBE_ACK_DATA_TTOT,
+	PL2_PMU_MAX_EVENT3_IDX
+};
+
+enum pl2_pmu_event_set4 {
+	INNER_HINT_HITS_MSHR = 0,
+	INNER_READ_HITS_MSHR,
+	INNER_WRITE_HITS_MSHR,
+	INNER_READ_REPLAY,
+	INNER_WRITE_REPLAY,
+	OUTER_PROBE_REPLAY,
+	REPLAY,
+	SLEEP_BY_MISS_QUEUE,
+	SLEEP_BY_EVICT_QUEUE,
+	SLEEP_FOR_BACK_PROBE,
+	SLEEP,
+	PL2_PMU_MAX_EVENT4_IDX
+};
+
+enum pl2_pmu_event_set5 {
+	READ_SLEEP_TIMER_EXPIRE = 0,
+	READ_OLDEST_TIMER_EXPIRE,
+	WRITE_SLEEP_TIMER_EXPIRE,
+	WRITE_OLDEST_TIMER_EXPIRE,
+	READ_SLEEP,
+	READ_DIR_UPDATE_WAKEUP,
+	READ_MISS_QUEUE_WAKEUP,
+	READ_EVICT_QUEUE_WAKEUP,
+	READ_SLEEP_TIMER_WAKEUP,
+	WRITE_SLEEP,
+	WRITE_DIR_UPDATE_WAKEUP,
+	WRITE_MISS_QUEUE_WAKEUP,
+	WRITE_EVICT_QUEUE_WAKEUP,
+	WRITE_SLEEP_TIMER_WAKEUP,
+	PL2_PMU_MAX_EVENT5_IDX
+};
+
+static struct attribute *sifive_pl2_pmu_events[] = {
+	PL2_PMU_EVENT_ATTR(inner_put_full_data, INNER_PUT_FULL_DATA, 1),
+	PL2_PMU_EVENT_ATTR(inner_put_partial_data, INNER_PUT_PARTIAL_DATA, 1),
+	PL2_PMU_EVENT_ATTR(inner_atomic_data, INNER_ATOMIC_DATA, 1),
+	PL2_PMU_EVENT_ATTR(inner_get, INNER_GET, 1),
+	PL2_PMU_EVENT_ATTR(inner_prefetch_read, INNER_PREFETCH_READ, 1),
+	PL2_PMU_EVENT_ATTR(inner_prefetch_write, INNER_PREFETCH_WRITE, 1),
+	PL2_PMU_EVENT_ATTR(inner_acquire_block_ntob, INNER_ACQUIRE_BLOCK_NTOB, 1),
+	PL2_PMU_EVENT_ATTR(inner_acquire_block_ntot, INNER_ACQUIRE_BLOCK_NTOT, 1),
+	PL2_PMU_EVENT_ATTR(inner_acquire_block_btot, INNER_ACQUIRE_BLOCK_BTOT, 1),
+	PL2_PMU_EVENT_ATTR(inner_acquire_perm_ntot, INNER_ACQUIRE_PERM_NTOT, 1),
+	PL2_PMU_EVENT_ATTR(inner_acquire_perm_btot, INNER_ACQUIRE_PERM_BTOT, 1),
+	PL2_PMU_EVENT_ATTR(inner_release_ttob, INNER_RELEASE_TTOB, 1),
+	PL2_PMU_EVENT_ATTR(inner_release_tton, INNER_RELEASE_TTON, 1),
+	PL2_PMU_EVENT_ATTR(inner_release_bton, INNER_RELEASE_BTON, 1),
+	PL2_PMU_EVENT_ATTR(inner_release_data_ttob, INNER_RELEASE_DATA_TTOB, 1),
+	PL2_PMU_EVENT_ATTR(inner_release_data_tton, INNER_RELEASE_DATA_TTON, 1),
+	PL2_PMU_EVENT_ATTR(inner_release_data_bton, INNER_RELEASE_DATA_BTON, 1),
+	PL2_PMU_EVENT_ATTR(inner_release_data_ttot, INNER_RELEASE_DATA_TTOT, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_block_tot, INNER_PROBE_BLOCK_TOT, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_block_tob, INNER_PROBE_BLOCK_TOB, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_block_ton, INNER_PROBE_BLOCK_TON, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_perm_ton, INNER_PROBE_PERM_TON, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_ack_ttob, INNER_PROBE_ACK_TTOB, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_ack_tton, INNER_PROBE_ACK_TTON, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_ack_bton, INNER_PROBE_ACK_BTON, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_ack_ttot, INNER_PROBE_ACK_TTOT, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_ack_btob, INNER_PROBE_ACK_BTOB, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_ack_nton, INNER_PROBE_ACK_NTON, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_ack_data_ttob, INNER_PROBE_ACK_DATA_TTOB, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_ack_data_tton, INNER_PROBE_ACK_DATA_TTON, 1),
+	PL2_PMU_EVENT_ATTR(inner_probe_ack_data_ttot, INNER_PROBE_ACK_DATA_TTOT, 1),
+
+	PL2_PMU_EVENT_ATTR(inner_put_full_data_hit, INNER_PUT_FULL_DATA_HIT, 2),
+	PL2_PMU_EVENT_ATTR(inner_put_partial_data_hit, INNER_PUT_PARTIAL_DATA_HIT, 2),
+	PL2_PMU_EVENT_ATTR(inner_atomic_data_hit, INNER_ATOMIC_DATA_HIT, 2),
+	PL2_PMU_EVENT_ATTR(inner_get_hit, INNER_GET_HIT, 2),
+	PL2_PMU_EVENT_ATTR(inner_prefetch_read_hit, INNER_PREFETCH_READ_HIT, 2),
+	PL2_PMU_EVENT_ATTR(inner_acquire_block_ntob_hit, INNER_ACQUIRE_BLOCK_NTOB_HIT, 2),
+	PL2_PMU_EVENT_ATTR(inner_acquire_perm_ntot_hit, INNER_ACQUIRE_PERM_NTOT_HIT, 2),
+	PL2_PMU_EVENT_ATTR(inner_release_ttob_hit, INNER_RELEASE_TTOB_HIT, 2),
+	PL2_PMU_EVENT_ATTR(inner_release_data_ttob_hit, INNER_RELEASE_DATA_TTOB_HIT, 2),
+	PL2_PMU_EVENT_ATTR(outer_probe_block_tot_hit, OUTER_PROBE_BLOCK_TOT_HIT, 2),
+	PL2_PMU_EVENT_ATTR(inner_put_full_data_hit_shared, INNER_PUT_FULL_DATA_HIT_SHARED, 2),
+	PL2_PMU_EVENT_ATTR(inner_put_partial_data_hit_shared, INNER_PUT_PARTIAL_DATA_HIT_SHARED, 2),
+	PL2_PMU_EVENT_ATTR(inner_atomic_data_hit_shared, INNER_ATOMIC_DATA_HIT_SHARED, 2),
+	PL2_PMU_EVENT_ATTR(inner_get_hit_shared, INNER_GET_HIT_SHARED, 2),
+	PL2_PMU_EVENT_ATTR(inner_prefetch_read_hit_shared, INNER_PREFETCH_READ_HIT_SHARED, 2),
+	PL2_PMU_EVENT_ATTR(inner_acquire_block_ntob_hit_shared,
+			   INNER_ACQUIRE_BLOCK_NTOB_HIT_SHARED, 2),
+	PL2_PMU_EVENT_ATTR(inner_acquire_perm_ntot_hit_shared,
+			   INNER_ACQUIRE_PERM_NTOT_HIT_SHARED, 2),
+	PL2_PMU_EVENT_ATTR(inner_release_ttob_hit_shared, INNER_RELEASE_TTOB_HIT_SHARED, 2),
+	PL2_PMU_EVENT_ATTR(inner_release_data_ttob_hit_shared,
+			   INNER_RELEASE_DATA_TTOB_HIT_SHARED, 2),
+	PL2_PMU_EVENT_ATTR(outer_probe_block_tot_hit_shared, OUTER_PROBE_BLOCK_TOT_HIT_SHARED, 2),
+	PL2_PMU_EVENT_ATTR(outer_probe_block_tot_hit_dirty, OUTER_PROBE_BLOCK_TOT_HIT_DIRTY, 2),
+
+	PL2_PMU_EVENT_ATTR(outer_put_full_data, OUTER_PUT_FULL_DATA, 3),
+	PL2_PMU_EVENT_ATTR(outer_put_partial_data, OUTER_PUT_PARTIAL_DATA, 3),
+	PL2_PMU_EVENT_ATTR(outer_atomic_data, OUTER_ATOMIC_DATA, 3),
+	PL2_PMU_EVENT_ATTR(outer_get, OUTER_GET, 3),
+	PL2_PMU_EVENT_ATTR(outer_prefetch_read, OUTER_PREFETCH_READ, 3),
+	PL2_PMU_EVENT_ATTR(outer_prefetch_write, OUTER_PREFETCH_WRITE, 3),
+	PL2_PMU_EVENT_ATTR(outer_acquire_block_ntob, OUTER_ACQUIRE_BLOCK_NTOB, 3),
+	PL2_PMU_EVENT_ATTR(outer_acquire_block_ntot, OUTER_ACQUIRE_BLOCK_NTOT, 3),
+	PL2_PMU_EVENT_ATTR(outer_acquire_block_btot, OUTER_ACQUIRE_BLOCK_BTOT, 3),
+	PL2_PMU_EVENT_ATTR(outer_acquire_perm_ntot, OUTER_ACQUIRE_PERM_NTOT, 3),
+	PL2_PMU_EVENT_ATTR(outer_acquire_perm_btot, OUTER_ACQUIRE_PERM_BTOT, 3),
+	PL2_PMU_EVENT_ATTR(outer_release_ttob, OUTER_RELEARE_TTOB, 3),
+	PL2_PMU_EVENT_ATTR(outer_release_tton, OUTER_RELEARE_TTON, 3),
+	PL2_PMU_EVENT_ATTR(outer_release_bton, OUTER_RELEARE_BTON, 3),
+	PL2_PMU_EVENT_ATTR(outer_release_data_ttob, OUTER_RELEARE_DATA_TTOB, 3),
+	PL2_PMU_EVENT_ATTR(outer_release_data_tton, OUTER_RELEARE_DATA_TTON, 3),
+	PL2_PMU_EVENT_ATTR(outer_release_data_bton, OUTER_RELEARE_DATA_BTON, 3),
+	PL2_PMU_EVENT_ATTR(outer_release_data_ttot, OUTER_RELEARE_DATA_TTOT, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_block_tot, OUTER_PROBE_BLOCK_TOT, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_block_tob, OUTER_PROBE_BLOCK_TOB, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_block_ton, OUTER_PROBE_BLOCK_TON, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_perm_ton, OUTER_PROBE_PERM_TON, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_ack_ttob, OUTER_PROBE_ACK_TTOB, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_ack_tton, OUTER_PROBE_ACK_TTON, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_ack_bton, OUTER_PROBE_ACK_BTON, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_ack_ttot, OUTER_PROBE_ACK_TTOT, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_ack_btob, OUTER_PROBE_ACK_BTOB, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_ack_nton, OUTER_PROBE_ACK_NTON, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_ack_data_ttob, OUTER_PROBE_ACK_DATA_TTOB, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_ack_data_tton, OUTER_PROBE_ACK_DATA_TTON, 3),
+	PL2_PMU_EVENT_ATTR(outer_probe_ack_data_ttot, OUTER_PROBE_ACK_DATA_TTOT, 3),
+
+	PL2_PMU_EVENT_ATTR(inner_hint_hits_mshr, INNER_HINT_HITS_MSHR, 4),
+	PL2_PMU_EVENT_ATTR(inner_read_hits_mshr, INNER_READ_HITS_MSHR, 4),
+	PL2_PMU_EVENT_ATTR(inner_write_hits_mshr, INNER_WRITE_HITS_MSHR, 4),
+	PL2_PMU_EVENT_ATTR(inner_read_replay, INNER_READ_REPLAY, 4),
+	PL2_PMU_EVENT_ATTR(inner_write_replay, INNER_WRITE_REPLAY, 4),
+	PL2_PMU_EVENT_ATTR(outer_probe_replay, OUTER_PROBE_REPLAY, 4),
+	PL2_PMU_EVENT_ATTR(replay, REPLAY, 4),
+	PL2_PMU_EVENT_ATTR(sleep_by_miss_queue, SLEEP_BY_MISS_QUEUE, 4),
+	PL2_PMU_EVENT_ATTR(sleep_by_evict_queue, SLEEP_BY_EVICT_QUEUE, 4),
+	PL2_PMU_EVENT_ATTR(sleep_for_back_probe, SLEEP_FOR_BACK_PROBE, 4),
+	PL2_PMU_EVENT_ATTR(sleep, SLEEP, 4),
+
+	PL2_PMU_EVENT_ATTR(read_sleep_timer_expire, READ_SLEEP_TIMER_EXPIRE, 5),
+	PL2_PMU_EVENT_ATTR(read_oldest_timer_expire, READ_OLDEST_TIMER_EXPIRE, 5),
+	PL2_PMU_EVENT_ATTR(write_sleep_timer_expire, WRITE_SLEEP_TIMER_EXPIRE, 5),
+	PL2_PMU_EVENT_ATTR(write_oldest_timer_expire, WRITE_OLDEST_TIMER_EXPIRE, 5),
+	PL2_PMU_EVENT_ATTR(read_sleep, READ_SLEEP, 5),
+	PL2_PMU_EVENT_ATTR(read_dir_update_wakeup, READ_DIR_UPDATE_WAKEUP, 5),
+	PL2_PMU_EVENT_ATTR(read_miss_queue_wakeup, READ_MISS_QUEUE_WAKEUP, 5),
+	PL2_PMU_EVENT_ATTR(read_evict_queue_wakeup, READ_EVICT_QUEUE_WAKEUP, 5),
+	PL2_PMU_EVENT_ATTR(read_sleep_timer_wakeup, READ_SLEEP_TIMER_WAKEUP, 5),
+	PL2_PMU_EVENT_ATTR(write_sleep, WRITE_SLEEP, 5),
+	PL2_PMU_EVENT_ATTR(write_dir_update_wakeup, WRITE_DIR_UPDATE_WAKEUP, 5),
+	PL2_PMU_EVENT_ATTR(write_miss_queue_wakeup, WRITE_MISS_QUEUE_WAKEUP, 5),
+	PL2_PMU_EVENT_ATTR(write_evict_queue_wakeup, WRITE_EVICT_QUEUE_WAKEUP, 5),
+	PL2_PMU_EVENT_ATTR(write_sleep_timer_wakeup, WRITE_SLEEP_TIMER_WAKEUP, 5),
+	NULL
+};
+
+static struct attribute_group sifive_pl2_pmu_events_group = {
+	.name = "events",
+	.attrs = sifive_pl2_pmu_events,
+};
+
+/* formats */
+PMU_FORMAT_ATTR(event, "config:0-63");
+
+static struct attribute *sifive_pl2_pmu_formats[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group sifive_pl2_pmu_format_group = {
+	.name = "format",
+	.attrs = sifive_pl2_pmu_formats,
+};
+
+/*
+ * Per PMU device attribute groups
+ */
+
+static const struct attribute_group *sifive_pl2_pmu_attr_grps[] = {
+	&sifive_pl2_pmu_events_group,
+	&sifive_pl2_pmu_format_group,
+	NULL,
+};
+
+/*
+ * Event Initialization
+ */
+
+static int sifive_pl2_pmu_event_init(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 config = event->attr.config;
+	u64 ev_type = config >> 8;
+	u64 set = config & 0xff;
+
+	/* Check if this is a valid set and event */
+	switch (set) {
+	case 1:
+		if (ev_type >= BIT_ULL(PL2_PMU_MAX_EVENT1_IDX))
+			return -ENOENT;
+		break;
+	case 2:
+		if (ev_type >= BIT_ULL(PL2_PMU_MAX_EVENT2_IDX))
+			return -ENOENT;
+		break;
+	case 3:
+		if (ev_type >= BIT_ULL(PL2_PMU_MAX_EVENT3_IDX))
+			return -ENOENT;
+		break;
+	case 4:
+		if (ev_type >= BIT_ULL(PL2_PMU_MAX_EVENT4_IDX))
+			return -ENOENT;
+		break;
+	case 5:
+		if (ev_type >= BIT_ULL(PL2_PMU_MAX_EVENT5_IDX))
+			return -ENOENT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	/* Do not allocate the hardware counter yet */
+	hwc->idx = -1;
+	hwc->config = config;
+
+	return 0;
+}
+
+/*
+ * pmu->read: read and update the counter
+ */
+static void sifive_pl2_pmu_read(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 prev_raw_count, new_raw_count;
+	u64 oldval;
+
+	do {
+		prev_raw_count = local64_read(&hwc->prev_count);
+		new_raw_count = readq((void *)hwc->event_base);
+
+		oldval = local64_cmpxchg(&hwc->prev_count, prev_raw_count, new_raw_count);
+	} while (oldval != prev_raw_count);
+
+	local64_add(new_raw_count - prev_raw_count, &event->count);
+}
+
+/*
+ * State transition functions:
+ *
+ * start()/stop() & add()/del()
+ */
+
+/*
+ * pmu->start: start the event
+ */
+static void sifive_pl2_pmu_start(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+		return;
+
+	hwc->state = 0;
+
+	/* Set initial value to 0 */
+	local64_set(&hwc->prev_count, 0);
+	writeq(0, (void *)hwc->event_base);
+
+	/* Enable this counter to count events */
+	writeq(hwc->config, (void *)hwc->config_base);
+}
+
+/*
+ * pmu->stop: stop the counter
+ */
+static void sifive_pl2_pmu_stop(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (hwc->state & PERF_HES_STOPPED)
+		return;
+
+	/* Disable this counter to count events */
+	writeq(0, (void *)hwc->config_base);
+	sifive_pl2_pmu_read(event);
+
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+}
+
+/*
+ * pmu->add: add the event to the PMU
+ */
+static int sifive_pl2_pmu_add(struct perf_event *event, int flags)
+{
+	struct sifive_pl2_pmu *pl2_pmu = to_pl2_pmu(event->pmu);
+	struct sifive_pl2_pmu_event *ptr = *this_cpu_ptr(pl2_pmu->event);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+
+	/* Find an available counter idx to use for this event */
+	do {
+		idx = find_first_zero_bit(ptr->used_mask, ptr->n_counters);
+		if (idx >= ptr->n_counters)
+			return -EAGAIN;
+	} while (test_and_set_bit(idx, ptr->used_mask));
+
+	hwc->config_base = (unsigned long)ptr->base + PL2_SELECT_OFFSET + 8 * idx;
+	hwc->event_base = (unsigned long)ptr->base + PL2_COUNTER_OFFSET + 8 * idx;
+	hwc->idx = idx;
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+
+	ptr->events[idx] = event;
+
+	if (flags & PERF_EF_START)
+		sifive_pl2_pmu_start(event, PERF_EF_RELOAD);
+
+	perf_event_update_userpage(event);
+
+	return 0;
+}
+
+/*
+ * pmu->del: delete the event from the PMU
+ */
+static void sifive_pl2_pmu_del(struct perf_event *event, int flags)
+{
+	struct sifive_pl2_pmu *pl2_pmu = to_pl2_pmu(event->pmu);
+	struct sifive_pl2_pmu_event *ptr = *this_cpu_ptr(pl2_pmu->event);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	/* Stop and release this counter */
+	sifive_pl2_pmu_stop(event, PERF_EF_UPDATE);
+
+	ptr->events[idx] = NULL;
+	clear_bit(idx, ptr->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+/*
+ * pmu->filter: check if the PMU can be used with a CPU
+ */
+static bool sifive_pl2_pmu_filter(struct pmu *pmu, int cpu)
+{
+	struct sifive_pl2_pmu *pl2_pmu = to_pl2_pmu(pmu);
+	struct sifive_pl2_pmu_event *ptr = *this_cpu_ptr(pl2_pmu->event);
+
+	/* Filter out CPUs with no PL2 instance (no percpu data allocated) */
+	return !ptr;
+}
+
+/*
+ * Driver initialization
+ */
+
+static void sifive_pl2_pmu_hw_init(const struct sifive_pl2_pmu_event *ptr)
+{
+	/* Disable the client filter (not supported by this driver) */
+	writeq(0, ptr->base + PL2_CLIENT_FILTER_OFFSET);
+}
+
+static int sifive_pl2_pmu_pm_notify(struct notifier_block *nb, unsigned long cmd, void *v)
+{
+	struct sifive_pl2_pmu *pl2_pmu = container_of(nb, struct sifive_pl2_pmu, cpu_pm_nb);
+	struct sifive_pl2_pmu_event *ptr = *this_cpu_ptr(pl2_pmu->event);
+	struct perf_event *event;
+
+	if (!ptr || bitmap_empty(ptr->used_mask, PL2_PMU_MAX_COUNTERS))
+		return NOTIFY_OK;
+
+	for (int idx = 0; idx < ptr->n_counters; idx++) {
+		event = ptr->events[idx];
+		if (!event)
+			continue;
+
+		switch (cmd) {
+		case CPU_PM_ENTER:
+			/* Stop and update the counter */
+			sifive_pl2_pmu_stop(event, PERF_EF_UPDATE);
+			break;
+		case CPU_PM_ENTER_FAILED:
+		case CPU_PM_EXIT:
+			/* Restore and enable the counter */
+			sifive_pl2_pmu_start(event, PERF_EF_RELOAD);
+			break;
+		default:
+			break;
+		}
+	}
+
+	return NOTIFY_OK;
+}
+
+static int sifive_pl2_pmu_pm_register(struct sifive_pl2_pmu *pl2_pmu)
+{
+	if (!IS_ENABLED(CONFIG_CPU_PM))
+		return 0;
+
+	pl2_pmu->cpu_pm_nb.notifier_call = sifive_pl2_pmu_pm_notify;
+	return cpu_pm_register_notifier(&pl2_pmu->cpu_pm_nb);
+}
+
+static void sifive_pl2_pmu_pm_unregister(struct sifive_pl2_pmu *pl2_pmu)
+{
+	if (!IS_ENABLED(CONFIG_CPU_PM))
+		return;
+
+	cpu_pm_unregister_notifier(&pl2_pmu->cpu_pm_nb);
+}
+
+static struct sifive_pl2_pmu *sifive_pl2_pmu_get(void)
+{
+	struct sifive_pl2_pmu *pl2_pmu;
+	int ret;
+
+	guard(mutex)(&g_mutex);
+
+	pl2_pmu = g_pl2_pmu;
+	if (pl2_pmu) {
+		refcount_inc(&pl2_pmu->refcount);
+		return pl2_pmu;
+	}
+
+	pl2_pmu = kzalloc(sizeof(*pl2_pmu), GFP_KERNEL);
+	if (!pl2_pmu)
+		return ERR_PTR(-ENOMEM);
+
+	pl2_pmu->pmu = (struct pmu) {
+		.attr_groups	= sifive_pl2_pmu_attr_grps,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
+		.task_ctx_nr	= perf_sw_context,
+		.event_init	= sifive_pl2_pmu_event_init,
+		.add		= sifive_pl2_pmu_add,
+		.del		= sifive_pl2_pmu_del,
+		.start		= sifive_pl2_pmu_start,
+		.stop		= sifive_pl2_pmu_stop,
+		.read		= sifive_pl2_pmu_read,
+		.filter		= sifive_pl2_pmu_filter,
+	};
+
+	refcount_set(&pl2_pmu->refcount, 1);
+
+	pl2_pmu->event = alloc_percpu(typeof(*pl2_pmu->event));
+	if (!pl2_pmu->event) {
+		ret = -ENOMEM;
+		goto err_free;
+	}
+
+	ret = sifive_pl2_pmu_pm_register(pl2_pmu);
+	if (ret)
+		goto err_free_percpu;
+
+	ret = perf_pmu_register(&pl2_pmu->pmu, "sifive_pl2_pmu", -1);
+	if (ret) {
+		pr_err("%s: Failed to register PMU: %d\n", __func__, ret);
+		goto err_unregister_pm;
+	}
+
+	g_pl2_pmu = pl2_pmu;
+
+	return pl2_pmu;
+
+err_unregister_pm:
+	sifive_pl2_pmu_pm_unregister(pl2_pmu);
+err_free_percpu:
+	free_percpu(pl2_pmu->event);
+err_free:
+	kfree(pl2_pmu);
+
+	return ERR_PTR(ret);
+}
+
+static void sifive_pl2_pmu_put(void)
+{
+	struct sifive_pl2_pmu *pl2_pmu;
+
+	guard(mutex)(&g_mutex);
+
+	pl2_pmu = g_pl2_pmu;
+	if (!refcount_dec_and_test(&pl2_pmu->refcount))
+		return;
+
+	g_pl2_pmu = NULL;
+	perf_pmu_unregister(&pl2_pmu->pmu);
+	sifive_pl2_pmu_pm_unregister(pl2_pmu);
+	free_percpu(pl2_pmu->event);
+	kfree(pl2_pmu);
+}
+
+static int sifive_pl2_pmu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev_of_node(dev);
+	struct sifive_pl2_pmu_event *ptr;
+	struct sifive_pl2_pmu *pl2_pmu;
+	unsigned int cpu;
+	u32 n_counters;
+	int ret;
+
+	/* Instances without a sifive,perfmon-counters property do not contain a PMU */
+	ret = of_property_read_u32(np, "sifive,perfmon-counters", &n_counters);
+	if (ret || !n_counters)
+		return -ENODEV;
+
+	/* Determine the CPU affinity of this PL2 instance */
+	for_each_possible_cpu(cpu) {
+		struct device_node *cache_node, *cpu_node;
+
+		cpu_node = of_cpu_device_node_get(cpu);
+		if (!cpu_node)
+			continue;
+
+		cache_node = of_parse_phandle(cpu_node, "next-level-cache", 0);
+		of_node_put(cpu_node);
+		if (!cache_node)
+			continue;
+
+		of_node_put(cache_node);
+		if (cache_node == np)
+			break;
+	}
+	if (cpu >= nr_cpu_ids)
+		return -ENODEV;
+
+	ptr = devm_kzalloc(dev, struct_size(ptr, events, n_counters), GFP_KERNEL);
+	if (!ptr)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, ptr);
+
+	ptr->cpu = cpu;
+	ptr->n_counters = n_counters;
+
+	ptr->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(ptr->base))
+		return PTR_ERR(ptr->base);
+
+	sifive_pl2_pmu_hw_init(ptr);
+
+	pl2_pmu = sifive_pl2_pmu_get();
+	if (IS_ERR(pl2_pmu))
+		return PTR_ERR(pl2_pmu);
+
+	*per_cpu_ptr(pl2_pmu->event, cpu) = ptr;
+
+	return 0;
+}
+
+static void sifive_pl2_pmu_remove(struct platform_device *pdev)
+{
+	struct sifive_pl2_pmu_event *ptr = platform_get_drvdata(pdev);
+
+	*per_cpu_ptr(g_pl2_pmu->event, ptr->cpu) = NULL;
+	sifive_pl2_pmu_put();
+}
+
+static const struct of_device_id sifve_pl2_pmu_of_match[] = {
+	{ .compatible = "sifive,pl2cache1" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sifve_pl2_pmu_of_match);
+
+static struct platform_driver sifive_pl2_pmu_driver = {
+	.probe	= sifive_pl2_pmu_probe,
+	.remove_new	= sifive_pl2_pmu_remove,
+	.driver	= {
+		.name		= "sifive_pl2_pmu",
+		.of_match_table	= sifve_pl2_pmu_of_match,
+	},
+};
+module_platform_driver(sifive_pl2_pmu_driver);
+
+MODULE_LICENSE("GPL");
-- 
2.43.0



From andrii.nakryiko at gmail.com  Thu Feb 15 16:12:28 2024
From: andrii.nakryiko at gmail.com (Andrii Nakryiko)
Date: Thu, 15 Feb 2024 16:12:28 -0800
Subject: [RESEND PATCH v5 2/4] perf/bpf: Remove unneeded uses_default_overflow_handler.
In-Reply-To: <20240214173950.18570-3-khuey@kylehuey.com>
References: <20240214173950.18570-1-khuey@kylehuey.com> <20240214173950.18570-3-khuey@kylehuey.com>
Message-ID: <CAEf4BzZM6gDH4_X86p0WhiLHY-m89c_8Km-a=dYGGc+7fUCrMg@mail.gmail.com>

On Wed, Feb 14, 2024 at 9:40?AM Kyle Huey <me at kylehuey.com> wrote:
>
> Now that struct perf_event's orig_overflow_handler is gone, there's no need
> for the functions and macros to support looking past overflow_handler to
> orig_overflow_handler.
>
> This patch is solely a refactoring and results in no behavior change.
>
> Signed-off-by: Kyle Huey <khuey at kylehuey.com>
> Acked-by: Will Deacon <will at kernel.org>
> Acked-by: Song Liu <song at kernel.org>
> Acked-by: Jiri Olsa <jolsa at kernel.org>
> ---

oh, never mind what I said in the first patch about this :)

Acked-by: Andrii Nakryiko <andrii at kernel.org>

>  arch/arm/kernel/hw_breakpoint.c   |  8 ++++----
>  arch/arm64/kernel/hw_breakpoint.c |  4 ++--
>  include/linux/perf_event.h        | 16 ++--------------
>  3 files changed, 8 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
> index dc0fb7a81371..054e9199f30d 100644
> --- a/arch/arm/kernel/hw_breakpoint.c
> +++ b/arch/arm/kernel/hw_breakpoint.c
> @@ -626,7 +626,7 @@ int hw_breakpoint_arch_parse(struct perf_event *bp,
>         hw->address &= ~alignment_mask;
>         hw->ctrl.len <<= offset;
>
> -       if (uses_default_overflow_handler(bp)) {
> +       if (is_default_overflow_handler(bp)) {
>                 /*
>                  * Mismatch breakpoints are required for single-stepping
>                  * breakpoints.
> @@ -798,7 +798,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
>                  * Otherwise, insert a temporary mismatch breakpoint so that
>                  * we can single-step over the watchpoint trigger.
>                  */
> -               if (!uses_default_overflow_handler(wp))
> +               if (!is_default_overflow_handler(wp))
>                         continue;
>  step:
>                 enable_single_step(wp, instruction_pointer(regs));
> @@ -811,7 +811,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
>                 info->trigger = addr;
>                 pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
>                 perf_bp_event(wp, regs);
> -               if (uses_default_overflow_handler(wp))
> +               if (is_default_overflow_handler(wp))
>                         enable_single_step(wp, instruction_pointer(regs));
>         }
>
> @@ -886,7 +886,7 @@ static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs)
>                         info->trigger = addr;
>                         pr_debug("breakpoint fired: address = 0x%x\n", addr);
>                         perf_bp_event(bp, regs);
> -                       if (uses_default_overflow_handler(bp))
> +                       if (is_default_overflow_handler(bp))
>                                 enable_single_step(bp, addr);
>                         goto unlock;
>                 }
> diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
> index 35225632d70a..db2a1861bb97 100644
> --- a/arch/arm64/kernel/hw_breakpoint.c
> +++ b/arch/arm64/kernel/hw_breakpoint.c
> @@ -654,7 +654,7 @@ static int breakpoint_handler(unsigned long unused, unsigned long esr,
>                 perf_bp_event(bp, regs);
>
>                 /* Do we need to handle the stepping? */
> -               if (uses_default_overflow_handler(bp))
> +               if (is_default_overflow_handler(bp))
>                         step = 1;
>  unlock:
>                 rcu_read_unlock();
> @@ -733,7 +733,7 @@ static u64 get_distance_from_watchpoint(unsigned long addr, u64 val,
>  static int watchpoint_report(struct perf_event *wp, unsigned long addr,
>                              struct pt_regs *regs)
>  {
> -       int step = uses_default_overflow_handler(wp);
> +       int step = is_default_overflow_handler(wp);
>         struct arch_hw_breakpoint *info = counter_arch_bp(wp);
>
>         info->trigger = addr;
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index c7f54fd74d89..c8bd5bb6610c 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -1341,8 +1341,9 @@ extern int perf_event_output(struct perf_event *event,
>                              struct pt_regs *regs);
>
>  static inline bool
> -__is_default_overflow_handler(perf_overflow_handler_t overflow_handler)
> +is_default_overflow_handler(struct perf_event *event)
>  {
> +       perf_overflow_handler_t overflow_handler = event->overflow_handler;
>         if (likely(overflow_handler == perf_event_output_forward))
>                 return true;
>         if (unlikely(overflow_handler == perf_event_output_backward))
> @@ -1350,19 +1351,6 @@ __is_default_overflow_handler(perf_overflow_handler_t overflow_handler)
>         return false;
>  }
>
> -#define is_default_overflow_handler(event) \
> -       __is_default_overflow_handler((event)->overflow_handler)
> -
> -#ifdef CONFIG_BPF_SYSCALL
> -static inline bool uses_default_overflow_handler(struct perf_event *event)
> -{
> -       return is_default_overflow_handler(event);
> -}
> -#else
> -#define uses_default_overflow_handler(event) \
> -       is_default_overflow_handler(event)
> -#endif
> -
>  extern void
>  perf_event_header__init_id(struct perf_event_header *header,
>                            struct perf_sample_data *data,
> --
> 2.34.1
>


From andrew at codeconstruct.com.au  Thu Feb 15 16:17:36 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Fri, 16 Feb 2024 10:47:36 +1030
Subject: [PATCH] mmc: host: replace 1st argument to struct device * for
 mmc_of_parse_clk_phase()
In-Reply-To: <20240215-mmc_phase-v1-1-f27644ee13e4@outlook.com>
References: <20240215-mmc_phase-v1-1-f27644ee13e4@outlook.com>
Message-ID: <ae876e697ba16ba2925ec217c6b4e3d8ffea4ab3.camel@codeconstruct.com.au>

On Thu, 2024-02-15 at 19:03 +0800, Yang Xiwen via B4 Relay wrote:
> From: Yang Xiwen <forbidden405 at outlook.com>
> 
> Parsing dt usaully happens very early, sometimes even bofore struct
> mmc_host is allocated (e.g. dw_mci_probe() and dw_mci_parse_dt() in
> dw_mmc.c). Looking at the source of mmc_of_parse_clk_phase(), it's
> actually not mandatory to have a initialized mmc_host first, instead we
> can pass struct device * to it directly.
> 
> Also fix the only current user (sdhci-of-aspeed.c).
> 
> Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
> ---
>  drivers/mmc/core/host.c            | 4 +---
>  drivers/mmc/host/sdhci-of-aspeed.c | 2 +-

So I think I wrote the mmc_of_parse_clk_phase() prototype with `struct
mmc_host *` simply because mmc_of_parse() took `struct mmc_host *`.

I'll defer to Ulf for whether what you're proposing is desirable, but
in terms of the impact on the Aspeed driver it seems okay.

Acked-by: Andrew Jeffery <andrew at codeconstruct.com.au>


From willy at infradead.org  Thu Feb 15 16:57:51 2024
From: willy at infradead.org (Matthew Wilcox)
Date: Fri, 16 Feb 2024 00:57:51 +0000
Subject: [PATCH v2] mm/filemap: Allow arch to request folio size for exec
 memory
In-Reply-To: <Zc6mcDlcnOZIjqGm@dread.disaster.area>
References: <20240215154059.2863126-1-ryan.roberts@arm.com>
 <Zc6mcDlcnOZIjqGm@dread.disaster.area>
Message-ID: <Zc6zD4zfsrkRlHe6@casper.infradead.org>

On Fri, Feb 16, 2024 at 11:04:00AM +1100, Dave Chinner wrote:
> > The reason for the low liklihood is that the current readahead algorithm
> > starts with an order-2 folio and increases the folio order by 2 every
> > time the readahead mark is hit. But most executable memory is faulted in
> > fairly randomly and so the readahead mark is rarely hit and most
> > executable folios remain order-2.
> 
> Yup, this is a bug in the readahead code, and really has nothing to
> do with executable files, mmap or the architecture.  We don't want
> some magic new VM_EXEC min folio size per architecture thingy to be
> set - we just want readahead to do the right thing.
> 
> Indeed, we are already adding a mapping minimum folio order
> directive to the address space to allow for filesystem block sizes
> greater than PAGE_SIZE. That's the generic mechanism that this
> functionality requires. See here:
> 
> https://lore.kernel.org/linux-xfs/20240213093713.1753368-5-kernel at pankajraghav.com/
> 
> (Probably worth reading some of the other readahead mods in that
> series and the discussion because readahead needs to ensure that it
> fill entire high order folios in a single IO to avoid partial folio
> up-to-date states from partial reads.)
> 
> IOWs, it seems to me that we could use this proposed generic mapping
> min order functionality when mmap() is run and VM_EXEC is set to set
> the min order to, say, 64kB. Then the readahead code would simply do
> the right thing, as would all other reads and writes to that
> mapping.
> 
> We could trigger this in the ->mmap() method of the filesystem so
> that filesysetms that can use large folios can turn it on, whilst
> other filesystems remain blissfully unaware of the functionality.
> Filesystems could also do smarter things here, too. eg. enable PMD
> alignment for large mapped files....

We already enable PMD alignment for large mapped files (which caused
some shrieking from those who believe that ASLR continues to offer
worthwhile protection), commit efa7df3e3bb5.

My problem with your minimum order proposal is that it would be a
hard failure if we couldn't get an order-4 folio.  I think we'd do
better to set the ra_state parameters to 64KiB at mmap time (and I
think that's better done in the MM, not in each FS)


From olteanv at gmail.com  Thu Feb 15 17:24:45 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Fri, 16 Feb 2024 03:24:45 +0200
Subject: [PATCH net RFC] net: dsa: mt7530: fix link-local frames that
 ingress vlan filtering ports
In-Reply-To: <20240201232619.nsmm7lvafuem2gou@skbuf>
References: <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
 <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
 <20240201232619.nsmm7lvafuem2gou@skbuf>
Message-ID: <20240216012445.em247rxfjnyufwm5@skbuf>

On Fri, Feb 02, 2024 at 01:26:19AM +0200, Vladimir Oltean wrote:
> On Thu, Feb 01, 2024 at 10:13:39PM +0300, Ar?n? ?NAL via B4 Relay wrote:
> > One remaining limitation is that the ingress port must have a PVID assigned
> > to it for the frame to be trapped to the CPU port. A PVID is set by default
> > on vlan aware and vlan unaware ports. However, when the network interface
> > that pertains to the ingress port is attached to a vlan_filtering enabled
> > bridge, the user can remove the PVID assignment from it which would prevent
> > the link-local frames from being trapped to the CPU port.
> > 
> > Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> > ---
> > I couldn't figure out a way to bypass VLAN table lookup for link-local
> > frames to directly trap them to the CPU port. The CPU port is hardcoded for
> > MT7530. For MT7531 and the switch on the MT7988 SoC, it depends on the port
> > matrix to choose the CPU port to trap the frames to. Port matrix and VLAN
> > table seem to go hand in hand so I don't know if this would even be
> > possible.
> > 
> > If possible to implement, link-local frames must not be influenced by the
> > VLAN table. They must always be trapped to the CPU port, and trapped
> > untagged.
> 
> Isn't this, in effect, what the "Leaky VLAN Enable" bit does?

Hm? Any news on this? I suppose this was the reason for submitting the
otherwise ok patch as RFC?


From olteanv at gmail.com  Thu Feb 15 17:34:39 2024
From: olteanv at gmail.com (Vladimir Oltean)
Date: Fri, 16 Feb 2024 03:34:39 +0200
Subject: [PATCH netnext 0/8] MT7530 DSA Subdriver Improvements Act III
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
Message-ID: <20240216013439.dq7s5hp74mjahy4d@skbuf>

On Thu, Feb 08, 2024 at 08:51:28AM +0300, Ar?n? ?NAL via B4 Relay wrote:
> Hello!
> 
> This is the third patch series with the goal of simplifying the MT7530 DSA
> subdriver and improving support for MT7530, MT7531, and the switch on the
> MT7988 SoC.

There was an automation failure, you used the name "netnext" in the
subject prefix and patchwork reacted with "Patch does not apply to net"...

Please resend to get some build testing. I gave a quick look over the
patches and I didn't see anything obviously objectionable.


From ck.hu at mediatek.com  Thu Feb 15 17:36:20 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 16 Feb 2024 01:36:20 +0000
Subject: [PATCH 2/9] soc: mediatek: cmdq: Add parameter shift_pa to
 cmdq_pkt_jump()
In-Reply-To: <21d17701-e40b-49c5-bf16-5e70a6daa2c4@collabora.com>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
	 <20240215004931.3808-3-chunkuang.hu@kernel.org>
	 <21d17701-e40b-49c5-bf16-5e70a6daa2c4@collabora.com>
Message-ID: <6fd1a8684139d124b76743f267ad1bbb8406c56b.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-02-15 at 11:40 +0100, AngeloGioacchino Del Regno wrote:
> Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> > In original design, cmdq_pkt_jump() call cmdq_get_shift_pa() every
> > time to get shift_pa. But the shift_pa is constant value for each
> > SoC, so client driver just need to call cmdq_get_shift_pa() once
> > and pass shift_pa to cmdq_pkt_jump() to prevent frequent function
> > call.
> > 
> 
> As far as I understand, the CMDQ supports both relative and absolute
> jumps, right?
> 
> Here's my proposal:
>   - Add a new function cmdq_pkt_jump_rel() or
> cmdq_pkt_jump_relative()
>     * note: I prefer "rel", as maybe in a future we'll get a jump_abs
> function? :-)
>   - Don't touch the cmdq_pkt_jump() function for one cycle
>     - Migrate mediatek-drm to use cmdq_pkt_jump_rel()
>   - Remove cmdq_pkt_jump() in the next cycle.
> 
> What do you think?

Good idea. I would create cmdq_pkt_jump_abs() to replace
cmdq_pkt_jump() and fix the wrong definition of CMDQ_JUMP_RELATIVE as:

#define CMDQ_JUMP_RELATIVE 0
#define CMDQ_JUMP_ABSOLUTE 1

Regards,
CK

> 
> Regards,
> Angelo
> 
> > Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> > ---
> >   drivers/soc/mediatek/mtk-cmdq-helper.c | 5 ++---
> >   include/linux/soc/mediatek/mtk-cmdq.h  | 6 ++++--
> >   2 files changed, 6 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index 67e17974d1e6..ed4ef95adf5b 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -348,14 +348,13 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16
> > reg_idx, u32 value)
> >   }
> >   EXPORT_SYMBOL(cmdq_pkt_assign);
> >   
> > -int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
> > +int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8
> > shift_pa)
> >   {
> >   	struct cmdq_instruction inst = {};
> >   
> >   	inst.op = CMDQ_CODE_JUMP;
> >   	inst.offset = CMDQ_JUMP_RELATIVE;
> > -	inst.value = addr >>
> > -		cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)-
> > >chan);
> > +	inst.value = addr >> shift_pa;
> >   	return cmdq_pkt_append_command(pkt, inst);
> >   }
> >   EXPORT_SYMBOL(cmdq_pkt_jump);
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 6c42d817d368..6215191a328d 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -238,10 +238,12 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16
> > reg_idx, u32 value);
> >    *		     a physical address which should contains
> > more instruction.
> >    * @pkt:        the CMDQ packet
> >    * @addr:       physical address of target instruction buffer
> > + * @shift_pa:	shift bits of physical address in CMDQ
> > instruction. This value
> > + *		is got by cmdq_get_shift_pa().
> >    *
> >    * Return: 0 for success; else the error code is returned
> >    */
> > -int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
> > +int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8
> > shift_pa);
> >   
> >   /**
> >    * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
> > @@ -339,7 +341,7 @@ static inline int cmdq_pkt_assign(struct
> > cmdq_pkt *pkt, u16 reg_idx, u32 value)
> >   	return -EINVAL;
> >   }
> >   
> > -static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t
> > addr)
> > +static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t
> > addr, u8 shift_pa)
> >   {
> >   	return -EINVAL;
> >   }
> 
> 
> 
> 

From ck.hu at mediatek.com  Thu Feb 15 17:39:35 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 16 Feb 2024 01:39:35 +0000
Subject: [PATCH 4/9] soc: mediatek: cmdq: Add cmdq_pkt_nop() helper
 function
In-Reply-To: <680fcb9a-d7e2-4a15-877e-09c01024ed53@collabora.com>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
	 <20240215004931.3808-5-chunkuang.hu@kernel.org>
	 <680fcb9a-d7e2-4a15-877e-09c01024ed53@collabora.com>
Message-ID: <830cde86af0df89f3331ff89e2b04e51f27cfd1c.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-02-15 at 11:40 +0100, AngeloGioacchino Del Regno wrote:
> Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> > cmdq_pkt_nop() append nop command to the packet. nop command ask
> > GCE to do no operation.
> > 
> > Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> > ---
> >   drivers/soc/mediatek/mtk-cmdq-helper.c | 11 +++++++++++
> >   include/linux/soc/mediatek/mtk-cmdq.h  | 16 ++++++++++++++++
> >   2 files changed, 27 insertions(+)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index e982997117c2..1be950b4ec7f 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -369,6 +369,17 @@ int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
> >   }
> >   EXPORT_SYMBOL(cmdq_pkt_eoc);
> >   
> > +int cmdq_pkt_nop(struct cmdq_pkt *pkt, u8 shift_pa)
> > +{
> > +	struct cmdq_instruction inst = { {0} };
> > +
> > +	/* Jumping to next instruction is equal to no operation */
> > +	inst.op = CMDQ_CODE_JUMP;
> > +	inst.value = CMDQ_INST_SIZE >> shift_pa;
> > +	return cmdq_pkt_append_command(pkt, inst);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_nop);
> > +
> >   int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> >   {
> >   	struct cmdq_instruction inst = { {0} };
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index a67f719dec0b..8179ba5238f9 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -255,6 +255,17 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt,
> > dma_addr_t addr, u8 shift_pa);
> >    */
> >   int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
> >   
> > +/**
> > + * cmdq_pkt_nop() - Append nop command to the CMDQ packet, ask GCE
> > + *		    to do no operation.
> 
>   * cmdq_pkt_nop() - Append No-Operation (NOP) command to a CMDQ
> packet
> 
> After which...
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> 
> 

Because I would create cmdq_pkt_jump_abs(), I think cmdq_pkt_nop() is a
special case of cmdq_pkt_jump_rel(), so I would change cmdq_pkt_nop()
to cmdq_pkt_jump_rel() for general use.

Regards,
CK

> 

From hj96.nam at samsung.com  Thu Feb 15 17:45:22 2024
From: hj96.nam at samsung.com (hj96.nam at samsung.com)
Date: Fri, 16 Feb 2024 10:45:22 +0900
Subject: [PATCH v3] perf: CXL: fix CPMU filter value mask length
References: <CGME20240216014507epcas2p41686c0ccb1fa73715499e45bbbc7d7e9@epcas2p4.samsung.com>
Message-ID: <20240216014522.32321-1-hj96.nam@samsung.com>

From: Hojin Nam <hj96.nam at samsung.com>

CPMU filter value is described as 4B length in CXL r3.0 8.2.7.2.2.
However, it is used as 2B length in code and comments.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Hojin Nam <hj96.nam at samsung.com>
---

Hi Will,
Sorry, I think whitespace-damage occurred while sending the patch.
I returned space to tab in the code below line 642, thank you!

Changes since v2:
- Return damaged whitespace to tabs (Will)

Changes since v1:
- Remove Fixes tag (Jonathan)
- Repair broken sign off (Jonathan)

 drivers/perf/cxl_pmu.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/perf/cxl_pmu.c b/drivers/perf/cxl_pmu.c
index 365d964b0f6a..ca5e92f28b4a 100644
--- a/drivers/perf/cxl_pmu.c
+++ b/drivers/perf/cxl_pmu.c
@@ -59,7 +59,7 @@
 #define   CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK	GENMASK_ULL(63, 59)
 
 #define CXL_PMU_FILTER_CFG_REG(n, f)	(0x400 + 4 * ((f) + (n) * 8))
-#define   CXL_PMU_FILTER_CFG_VALUE_MSK			GENMASK(15, 0)
+#define   CXL_PMU_FILTER_CFG_VALUE_MSK			GENMASK(31, 0)
 
 #define CXL_PMU_COUNTER_REG(n)		(0xc00 + 8 * (n))
 
@@ -314,9 +314,9 @@ static bool cxl_pmu_config1_get_edge(struct perf_event *event)
 }
 
 /*
- * CPMU specification allows for 8 filters, each with a 16 bit value...
- * So we need to find 8x16bits to store it in.
- * As the value used for disable is 0xffff, a separate enable switch
+ * CPMU specification allows for 8 filters, each with a 32 bit value...
+ * So we need to find 8x32bits to store it in.
+ * As the value used for disable is 0xffff_ffff, a separate enable switch
  * is needed.
  */
 
@@ -642,7 +642,7 @@ static void cxl_pmu_event_start(struct perf_event *event, int flags)
 		if (cxl_pmu_config1_hdm_filter_en(event))
 			cfg = cxl_pmu_config2_get_hdm_decoder(event);
 		else
-			cfg = GENMASK(15, 0); /* No filtering if 0xFFFF_FFFF */
+			cfg = GENMASK(31, 0); /* No filtering if 0xFFFF_FFFF */
 		writeq(cfg, base + CXL_PMU_FILTER_CFG_REG(hwc->idx, 0));
 	}
 
-- 
2.34.1



From Shawn.Sung at mediatek.com  Thu Feb 15 18:03:04 2024
From: Shawn.Sung at mediatek.com (=?utf-8?B?U2hhd24gU3VuZyAo5a6L5a2d6KyZKQ==?=)
Date: Fri, 16 Feb 2024 02:03:04 +0000
Subject: [PATCH v5 06/13] drm/mediatek: Turn off the layers with zero
 width or height
In-Reply-To: <1fdf2c07-8240-4711-a708-b555932dabc6@collabora.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
	 <20240215101119.12629-7-shawn.sung@mediatek.com>
	 <1fdf2c07-8240-4711-a708-b555932dabc6@collabora.com>
Message-ID: <6d1a5fe3577f8fe23f4fadd3bcdfb004c928b4b0.camel@mediatek.com>

On Thu, 2024-02-15 at 11:45 +0100, AngeloGioacchino Del Regno wrote:
> Il 15/02/24 11:11, Hsiao Chien Sung ha scritto:
> > We found that IGT (Intel GPU Tool) will try to commit layers with
> > zero width or height and lead to undefined behaviors in hardware.
> > Disable the layers in such a situation.
> > 
> > Fixes: 777b7bc86a0a3 ("drm/mediatek: Add ovl_adaptor support for
> > MT8195")
> > Fixes: fa97fe71f6f93 ("drm/mediatek: Add ETHDR support for MT8195")
> > 
> > Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> 
> This commit should be sent separately from this series, as it is
> fixing things
> that are not related just to IGT, but also to corner cases in regular
> non-testing
> usecases.
> 
> In any case, it's not mandatory as that depends on what the
> maintainer prefers,
> so it's CK's call anyway.
> 
> Besides that,
> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>

Got it. Will discuss this with CK.

This bug is found when running IGT test while one of the test item
commits a layer with zero width and cuase the device to freeze.


From robh at kernel.org  Thu Feb 15 18:09:21 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 20:09:21 -0600
Subject: [PATCH 1/2] media: dt-bindings: media: Add bindings for IMX283
In-Reply-To: <20240215204436.9194-2-umang.jain@ideasonboard.com>
References: <20240215204436.9194-1-umang.jain@ideasonboard.com>
 <20240215204436.9194-2-umang.jain@ideasonboard.com>
Message-ID: <170804935906.836524.16563023693485203536.robh@kernel.org>


On Fri, 16 Feb 2024 02:14:34 +0530, Umang Jain wrote:
> - Add dt-bindings documentation for Sony IMX283 sensor driver
> - Add MAINTAINERS entry for Sony IMX283 binding documentation
> 
> Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
> ---
>  .../bindings/media/i2c/sony,imx283.yaml       | 100 ++++++++++++++++++
>  MAINTAINERS                                   |   8 ++
>  2 files changed, 108 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx283.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/dt-review-ci/linux/Documentation/devicetree/bindings/media/i2c/sony,imx283.example.dtb: camera at 1a: 'vadd-supply', 'vdd1-supply', 'vdd2-supply' do not match any of the regexes: 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/media/i2c/sony,imx283.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240215204436.9194-2-umang.jain at ideasonboard.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From Shawn.Sung at mediatek.com  Thu Feb 15 18:16:58 2024
From: Shawn.Sung at mediatek.com (=?utf-8?B?U2hhd24gU3VuZyAo5a6L5a2d6KyZKQ==?=)
Date: Fri, 16 Feb 2024 02:16:58 +0000
Subject: [PATCH v5 10/13] drm/mediatek: Support CRC in display driver
In-Reply-To: <44529502-250b-4c8a-94c3-2c481d1385cf@collabora.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
	 <20240215101119.12629-11-shawn.sung@mediatek.com>
	 <44529502-250b-4c8a-94c3-2c481d1385cf@collabora.com>
Message-ID: <56eec57c795bdea59baac3ad3d25e015d4c596c3.camel@mediatek.com>

Hi Angelo,

On Thu, 2024-02-15 at 12:06 +0100, AngeloGioacchino Del Regno wrote:
> Il 15/02/24 11:11, Hsiao Chien Sung ha scritto:
> > Register CRC related function pointers to support
> > CRC retrieval.
> > 
> > Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 239
> > ++++++++++++++++++++
> >   drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |  39 ++++
> >   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   3 +
> >   3 files changed, 281 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index 14cf75fa217f9..6cb1ed419dee7 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -68,6 +68,9 @@ struct mtk_drm_crtc {
> >   	/* lock for display hardware access */
> >   	struct mutex			hw_lock;
> >   	bool				config_updating;
> > +
> > +	struct mtk_ddp_comp		*crc_provider;
> > +	unsigned int			frames;
> >   };
> >   
> >   struct mtk_crtc_state {
> > @@ -635,6 +638,14 @@ static void mtk_crtc_ddp_irq(void *data)
> >   	struct drm_crtc *crtc = data;
> >   	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> >   	struct mtk_drm_private *priv = crtc->dev->dev_private;
> > +	struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
> > +
> > +	/*
> > +	 * crc providers should make sure the crc is always correct
> > +	 * by resetting it in .crc_read()
> > +	 */
> > +	if (crtc->crc.opened)
> > +		comp->funcs->crc_read(comp->dev);
> >   
> >   #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> >   	if (!priv->data->shadow_register && !mtk_crtc-
> > >cmdq_client.chan)
> > @@ -646,6 +657,24 @@ static void mtk_crtc_ddp_irq(void *data)
> >   	if (!priv->data->shadow_register)
> >   		mtk_crtc_ddp_config(crtc, NULL);
> >   #endif
> > +
> > +	/*
> > +	 * drm_crtc_add_crc_entry() could take more than 50ms to finish
> > +	 * put it at the end of the isr
> > +	 */
> > +	if (crtc->crc.opened) {
> > +		/*
> > +		 * skip the first crc because the first frame is
> > configured by
> > +		 * mtk_crtc_ddp_hw_init() when atomic enable
> > +		 */
> > +		if (++mtk_crtc->frames > 1) {
> > +			drm_crtc_add_crc_entry(crtc, true,
> > +					       drm_crtc_vblank_count(cr
> > tc),
> > +					       comp->funcs-
> > >crc_entry(comp->dev));
> > +		}
> > +	} else {
> > +		mtk_crtc->frames = 0;
> > +	}
> >   	mtk_drm_finish_page_flip(mtk_crtc);
> >   }
> >   
> > @@ -704,6 +733,40 @@ static void mtk_drm_crtc_update_output(struct
> > drm_crtc *crtc,
> >   	}
> >   }
> >   
> > +static int mtk_drm_crtc_set_crc_source(struct drm_crtc *crtc,
> > const char *src)
> > +{
> > +	if (src && strcmp(src, "auto") != 0) {
> > +		DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
> > +			  __func__, drm_crtc_index(crtc), src);
> > +		return -EINVAL;
> > +	}
> > +	return 0;
> > +}
> > +
> > +static int mtk_drm_crtc_verify_crc_source(struct drm_crtc *crtc,
> > +					  const char *src,
> > +					  size_t *cnt)
> > +{
> > +	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> > +	struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
> > +
> > +	if (!comp) {
> > +		DRM_ERROR("%s(crtc-%d): no crc provider\n",
> > +			  __func__, drm_crtc_index(crtc));
> > +		return -ENOENT;
> > +	}
> > +
> > +	if (src && strcmp(src, "auto") != 0) {
> > +		DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
> > +			  __func__, drm_crtc_index(crtc), src);
> > +		return -EINVAL;
> > +	}
> > +
> > +	*cnt = comp->funcs->crc_cnt(comp->dev);
> > +
> > +	return 0;
> > +}
> > +
> >   int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct
> > drm_plane *plane,
> >   			     struct mtk_plane_state *state)
> >   {
> > @@ -841,6 +904,8 @@ static const struct drm_crtc_funcs
> > mtk_crtc_funcs = {
> >   	.atomic_destroy_state	= mtk_drm_crtc_destroy_state,
> >   	.enable_vblank		= mtk_drm_crtc_enable_vblank,
> >   	.disable_vblank		= mtk_drm_crtc_disable_vblank,
> > +	.set_crc_source		= mtk_drm_crtc_set_crc_source,
> > +	.verify_crc_source	= mtk_drm_crtc_verify_crc_source,
> >   };
> >   
> >   static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs =
> > {
> > @@ -1033,6 +1098,11 @@ int mtk_drm_crtc_create(struct drm_device
> > *drm_dev,
> >   
> >   			if (comp->funcs->ctm_set)
> >   				has_ctm = true;
> > +
> > +			if (comp->funcs->crc_cnt &&
> > +			    comp->funcs->crc_entry &&
> > +			    comp->funcs->crc_read)
> > +				mtk_crtc->crc_provider = comp;
> >   		}
> >   
> >   		mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq,
> > @@ -1137,3 +1207,172 @@ int mtk_drm_crtc_create(struct drm_device
> > *drm_dev,
> >   
> >   	return 0;
> >   }
> > +
> > +void mtk_drm_crc_init(struct mtk_drm_crc *crc,
> > +		      const u32 *crc_offset_table, size_t crc_count,
> > +		      u32 reset_offset, u32 reset_mask)
> > +{
> > +	crc->ofs = crc_offset_table;
> > +	crc->cnt = crc_count;
> > +	crc->rst_ofs = reset_offset;
> > +	crc->rst_msk = reset_mask;
> > +	crc->va = kcalloc(crc->cnt, sizeof(*crc->va), GFP_KERNEL);
> > +	if (!crc->va) {
> > +		DRM_ERROR("failed to allocate memory for crc\n");
> > +		crc->cnt = 0;
> > +	}
> > +}
> > +
> > +void mtk_drm_crc_read(struct mtk_drm_crc *crc, void __iomem *reg)
> > +{
> 
> 	u32 n; goes here
> 
> > +	if (!crc->cnt || !crc->ofs || !crc->va)
> > +		return;
> > +
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +	/* sync to see the most up-to-date copy of the DMA buffer */
> > +	dma_sync_single_for_cpu(crc->cmdq_client.chan->mbox->dev,
> > +				crc->pa, crc->cnt * sizeof(*crc->va),
> > +				DMA_FROM_DEVICE);
> > +#else
> > +	/* read crc with cpu for the platforms without cmdq */
> > +	{
> 
> then you don't need the braces.
> 
> Regards,
> Angelo
> 

The variable n is placed within the braces because when CONFIG_MTK_CMDQ
is defined, the variable is not being used and causes a build error.

This is a workaround in order to have only one #if macro in that
function for a more clean code.

Thanks,
Shawn



From Shawn.Sung at mediatek.com  Thu Feb 15 18:17:48 2024
From: Shawn.Sung at mediatek.com (=?utf-8?B?U2hhd24gU3VuZyAo5a6L5a2d6KyZKQ==?=)
Date: Fri, 16 Feb 2024 02:17:48 +0000
Subject: [PATCH v5 08/13] drm/mediatek: Support alpha blending in OVL
In-Reply-To: <7664fece-c29a-4374-a59c-4ce8fe831494@collabora.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
	 <20240215101119.12629-9-shawn.sung@mediatek.com>
	 <7664fece-c29a-4374-a59c-4ce8fe831494@collabora.com>
Message-ID: <111ddf7030051aa71d1283bd2eb4f23718eb8a9c.camel@mediatek.com>

Hi Angelo,

On Thu, 2024-02-15 at 12:02 +0100, AngeloGioacchino Del Regno wrote:
> Il 15/02/24 11:11, Hsiao Chien Sung ha scritto:
> > Support "Pre-multiplied" and "None" blend mode on MediaTek's chips.
> > Before this patch, only the "Coverage" mode is supported.
> > 
> > Please refer to the description of the commit
> > "drm/mediatek: Support alpha blending in display driver"
> > for more information.
> > 
> > Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 83
> > +++++++++++++++++++++----
> >   1 file changed, 72 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > index c42fce38a35eb..98c989fddcc08 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > @@ -39,6 +39,7 @@
> >   #define DISP_REG_OVL_PITCH_MSB(n)		(0x0040 + 0x20 * (n))
> >   #define OVL_PITCH_MSB_2ND_SUBBUF			BIT(16)
> >   #define DISP_REG_OVL_PITCH(n)			(0x0044 + 0x20
> > * (n))
> > +#define OVL_CONST_BLEND					BIT(28)
> >   #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
> >   #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
> >   #define DISP_REG_OVL_ADDR_MT2701		0x0040
> > @@ -52,13 +53,16 @@
> >   #define GMC_THRESHOLD_HIGH	((1 << GMC_THRESHOLD_BITS) / 4)
> >   #define GMC_THRESHOLD_LOW	((1 << GMC_THRESHOLD_BITS) / 8)
> >   
> > +#define OVL_CON_CLRFMT_MAN	BIT(23)
> >   #define OVL_CON_BYTE_SWAP	BIT(24)
> > -#define OVL_CON_MTX_YUV_TO_RGB	(6 << 16)
> > +#define OVL_CON_RGB_SWAP	BIT(25)
> >   #define OVL_CON_CLRFMT_RGB	(1 << 12)
> >   #define OVL_CON_CLRFMT_RGBA8888	(2 << 12)
> >   #define OVL_CON_CLRFMT_ARGB8888	(3 << 12)
> >   #define OVL_CON_CLRFMT_UYVY	(4 << 12)
> >   #define OVL_CON_CLRFMT_YUYV	(5 << 12)
> > +#define OVL_CON_MTX_YUV_TO_RGB	(6 << 16)
> > +#define OVL_CON_CLRFMT_PARGB8888	(OVL_CON_CLRFMT_ARGB8888 |
> > OVL_CON_CLRFMT_MAN)
> >   #define OVL_CON_CLRFMT_RGB565(ovl)	((ovl)->data-
> > >fmt_rgb565_is_0 ? \
> >   					0 : OVL_CON_CLRFMT_RGB)
> >   #define OVL_CON_CLRFMT_RGB888(ovl)	((ovl)->data-
> > >fmt_rgb565_is_0 ? \
> > @@ -72,6 +76,22 @@
> >   #define	OVL_CON_VIRT_FLIP	BIT(9)
> >   #define	OVL_CON_HORZ_FLIP	BIT(10)
> >   
> > +static inline bool is_10bit_rgb(u32 fmt)
> > +{
> > +	switch (fmt) {
> > +	case DRM_FORMAT_XRGB2101010:
> > +	case DRM_FORMAT_ARGB2101010:
> > +	case DRM_FORMAT_RGBX1010102:
> > +	case DRM_FORMAT_RGBA1010102:
> > +	case DRM_FORMAT_XBGR2101010:
> > +	case DRM_FORMAT_ABGR2101010:
> > +	case DRM_FORMAT_BGRX1010102:
> > +	case DRM_FORMAT_BGRA1010102:
> > +		return true;
> > +	}
> > +	return false;
> > +}
> > +
> >   static const u32 mt8173_formats[] = {
> >   	DRM_FORMAT_XRGB8888,
> >   	DRM_FORMAT_ARGB8888,
> > @@ -89,12 +109,20 @@ static const u32 mt8173_formats[] = {
> >   static const u32 mt8195_formats[] = {
> >   	DRM_FORMAT_XRGB8888,
> >   	DRM_FORMAT_ARGB8888,
> > +	DRM_FORMAT_XRGB2101010,
> >   	DRM_FORMAT_ARGB2101010,
> >   	DRM_FORMAT_BGRX8888,
> >   	DRM_FORMAT_BGRA8888,
> > +	DRM_FORMAT_BGRX1010102,
> >   	DRM_FORMAT_BGRA1010102,
> >   	DRM_FORMAT_ABGR8888,
> >   	DRM_FORMAT_XBGR8888,
> > +	DRM_FORMAT_XBGR2101010,
> > +	DRM_FORMAT_ABGR2101010,
> > +	DRM_FORMAT_RGBX8888,
> > +	DRM_FORMAT_RGBA8888,
> > +	DRM_FORMAT_RGBX1010102,
> > +	DRM_FORMAT_RGBA1010102,
> >   	DRM_FORMAT_RGB888,
> >   	DRM_FORMAT_BGR888,
> >   	DRM_FORMAT_RGB565,
> > @@ -254,9 +282,7 @@ static void mtk_ovl_set_bit_depth(struct device
> > *dev, int idx, u32 format,
> >   	reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
> >   	reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
> >   
> > -	if (format == DRM_FORMAT_RGBA1010102 ||
> > -	    format == DRM_FORMAT_BGRA1010102 ||
> > -	    format == DRM_FORMAT_ARGB2101010)
> > +	if (is_10bit_rgb(format))
> >   		bit_depth = OVL_CON_CLRFMT_10_BIT;
> >   
> >   	reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
> > @@ -274,7 +300,13 @@ void mtk_ovl_config(struct device *dev,
> > unsigned int w,
> >   	if (w != 0 && h != 0)
> >   		mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl-
> > >cmdq_reg, ovl->regs,
> >   				      DISP_REG_OVL_ROI_SIZE);
> > -	mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, 
> > DISP_REG_OVL_ROI_BGCLR);
> > +
> > +	/*
> > +	 * The background color should be opaque black (ARGB),
> > +	 * otherwise there will be no effect with alpha blend
> > +	 */
> > +	mtk_ddp_write_relaxed(cmdq_pkt, 0xff000000, &ovl->cmdq_reg,
> > +			      ovl->regs, DISP_REG_OVL_ROI_BGCLR);
> 
> Multiple (all of?) OVL color registers, like{L0-3,EL0-
> 2}_YUV1BIT_COLOR(x),
> ROI_BGCLR, L{0-3}_CLR and others do follow this exact layout:
> 
> #define OVL_COLOR_ALPHA				GENMASK(31, 24)
> #define OVL_COLOR_GREEN				GENMASK(23, 16)
> #define OVL_COLOR_RED				GENMASK(15, 8)
> #define OVL_COLOR_BLUE				GENMASK(7, 0)
> 
> ...so we can define those as they're valid for multiple registers,
> and then
> we can use the definition instead of an apparently random value.

Got it. Will modify it in the next version.

> 
> /*
>   * The background color should be opaque black (ARGB),
>   * otherwise there will be no effect with alpha blend
>   */
> mtk_ddp_write_relaxed(cmdq_pkt, OVL_COLOR_ALPHA, &ovl->cmdq_reg,
> 		      ovl->regs, DISP_REG_OVL_ROI_BGCLR);
> 
> Everything else looks ok.
> 
> Regards,
> Angelo
> 

Thanks,
Shawn

From robh at kernel.org  Thu Feb 15 18:22:27 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 20:22:27 -0600
Subject: [PATCH 02/13] dt-bindings: i2c: nomadik: add mobileye,eyeq5-i2c
 bindings and example
In-Reply-To: <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>
Message-ID: <20240216022227.GA850600-robh@kernel.org>

On Thu, Feb 15, 2024 at 05:52:09PM +0100, Th?o Lebrun wrote:
> Add EyeQ5 bindings to the existing Nomadik I2C dt-bindings. Add the two
> EyeQ5-specific properties behind a conditional. Add an example for this
> compatible.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  .../devicetree/bindings/i2c/st,nomadik-i2c.yaml    | 44 ++++++++++++++++++++--
>  1 file changed, 40 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
> index e6b95e3765ac..eaade14b6d4c 100644
> --- a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
> +++ b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
> @@ -14,9 +14,6 @@ description: The Nomadik I2C host controller began its life in the ST
>  maintainers:
>    - Linus Walleij <linus.walleij at linaro.org>
>  
> -allOf:
> -  - $ref: /schemas/i2c/i2c-controller.yaml#
> -
>  # Need a custom select here or 'arm,primecell' will match on lots of nodes
>  select:
>    properties:
> @@ -24,6 +21,7 @@ select:
>        contains:
>          enum:
>            - st,nomadik-i2c
> +          - mobileye,eyeq5-i2c
>    required:
>      - compatible
>  
> @@ -39,6 +37,10 @@ properties:
>            - const: stericsson,db8500-i2c
>            - const: st,nomadik-i2c
>            - const: arm,primecell
> +      # The variant found on Mobileye EyeQ5
> +      - items:
> +          - const: mobileye,eyeq5-i2c
> +          - const: arm,primecell
>  
>    reg:
>      maxItems: 1
> @@ -55,7 +57,7 @@ properties:
>        - items:
>            - const: mclk
>            - const: apb_pclk
> -      # Clock name in DB8500
> +      # Clock name in DB8500 or EyeQ5
>        - items:
>            - const: i2cclk
>            - const: apb_pclk
> @@ -83,6 +85,25 @@ required:
>  
>  unevaluatedProperties: false
>  
> +allOf:
> +  - $ref: /schemas/i2c/i2c-controller.yaml#
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: mobileye,eyeq5-i2c
> +    then:
> +      properties:
> +        mobileye,olb:
> +          $ref: /schemas/types.yaml#/definitions/phandle
> +          description: A phandle to the OLB syscon.

Define properties at the top-level and then restrict them in if/then 
schemas.

> +        mobileye,id:
> +          $ref: /schemas/types.yaml#/definitions/uint32
> +          description: Platform-wide controller ID (integer starting from zero).

instance indexes are a NAK. You can use i2cN aliases if you must.

Why do you need it? To access OLB? If so, add cell args to the OLB 
phandle instead.

Rob


From robh at kernel.org  Thu Feb 15 18:27:04 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 15 Feb 2024 20:27:04 -0600
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>
Message-ID: <20240216022704.GB850600-robh@kernel.org>

On Thu, Feb 15, 2024 at 05:52:08PM +0100, Th?o Lebrun wrote:
> Expose I2C device timeout configuration from devicetree. Use ?s as time
> unit and express it in the name.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
> index 16024415a4a7..e6b95e3765ac 100644
> --- a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
> +++ b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
> @@ -70,6 +70,10 @@ properties:
>      minimum: 1
>      maximum: 400000
>  
> +  timeout-usecs:

Use standard unit suffixes.

We already have at least 2 device specific timeout properties. This one 
should be common. That means you need to add it to i2c-controller.yaml 
in dtschema. GH PR or patch to devicetree-spec list is fine.

Rob


From ck.hu at mediatek.com  Thu Feb 15 18:11:16 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 16 Feb 2024 02:11:16 +0000
Subject: [PATCH 1/9] soc: mediatek: cmdq: Remove unused helper funciton
In-Reply-To: <c87af05e-9017-4806-88b1-7aa65f2b7070@collabora.com>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
	 <20240215004931.3808-2-chunkuang.hu@kernel.org>
	 <c87af05e-9017-4806-88b1-7aa65f2b7070@collabora.com>
Message-ID: <724be11a24799e2a4a97bfb5b8f2ba0173f00141.camel@mediatek.com>

Hi, Angelo:

On Thu, 2024-02-15 at 11:40 +0100, AngeloGioacchino Del Regno wrote:
> Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> > cmdq_pkt_create(), cmdq_pkt_destroy(), and cmdq_pkt_flush_async()
> > are not used by all client drivers (MediaTek drm driver and
> > MediaTek mdp3 driver),
> > 
> 
> Hello CK,
> 
> We can technically force the hand to say that this is true - but only
> because
> these two functions are copy-pasted in both mediatek-drm and MDP3
> drivers with
> no meaningful changes, as in, the only change is that `pkt` is
> supposed to be
> preallocated in both of the variants, while the one in mtk-cmdq-
> helper allocates
> it on its own.
> 
> Code duplication is something that we want to avoid, not something
> that we want
> to embrace: removing those functions from cmdq-helper with the plan
> to keep
> duplicating them in each MediaTek driver that uses CMDQ packets is
> plain wrong.
> 
> This - especially because I'm sure that we will see yet another copy-
> paste of
> those two functions in a future ISP driver, bringing the duplication
> count to
> 3 (or actually, 3 by 2 functions = 6 times).
> 
> On the other hand, removing the cmdq_pkt_flush_async() function is
> something
> that I *do* support, as it's only doing two simple calls that are not
> even
> specific to cmdq, but more like "generic stuff".
> 
> In short, as it is right now, this is a NACK - but if you change this
> commit to
> remove only cmdq_pkt_flush_async() I would agree.
> 
> The right thing to do is to remove the duplicated functions:
>   - mtk_drm_cmdq_pkt_create()
>   - mtk_drm_cmdq_pkt_destroy()
>   - mdp_cmdq_pkt_create()
>   - mdp_cmdq_pkt_destroy()
> 
> ...and migrate both drivers to use the common cmdq helper code
> instea, but that's
> something that can come later.
> 
> For now, you can simply perform the ->cl removal on all duplicated
> functions, then
> we can migrate them all to the common helper, removing duplication
> all along.

OK, I would refine cmdq_pkt_create()/cmdq_pkt_destroy() and let client
driver use these common functions.

Regards,
CK

> 
> Regards,
> Angelo
> 
> > Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> > ---
> >   drivers/soc/mediatek/mtk-cmdq-helper.c | 59 -------------------
> > -------
> >   include/linux/soc/mediatek/mtk-cmdq.h  | 40 -----------------
> >   2 files changed, 99 deletions(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index b0cd071c4719..67e17974d1e6 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -105,50 +105,6 @@ void cmdq_mbox_destroy(struct cmdq_client
> > *client)
> >   }
> >   EXPORT_SYMBOL(cmdq_mbox_destroy);
> >   
> > -struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client,
> > size_t size)
> > -{
> > -	struct cmdq_pkt *pkt;
> > -	struct device *dev;
> > -	dma_addr_t dma_addr;
> > -
> > -	pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
> > -	if (!pkt)
> > -		return ERR_PTR(-ENOMEM);
> > -	pkt->va_base = kzalloc(size, GFP_KERNEL);
> > -	if (!pkt->va_base) {
> > -		kfree(pkt);
> > -		return ERR_PTR(-ENOMEM);
> > -	}
> > -	pkt->buf_size = size;
> > -	pkt->cl = (void *)client;
> > -
> > -	dev = client->chan->mbox->dev;
> > -	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
> > -				  DMA_TO_DEVICE);
> > -	if (dma_mapping_error(dev, dma_addr)) {
> > -		dev_err(dev, "dma map failed, size=%u\n",
> > (u32)(u64)size);
> > -		kfree(pkt->va_base);
> > -		kfree(pkt);
> > -		return ERR_PTR(-ENOMEM);
> > -	}
> > -
> > -	pkt->pa_base = dma_addr;
> > -
> > -	return pkt;
> > -}
> > -EXPORT_SYMBOL(cmdq_pkt_create);
> > -
> > -void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
> > -{
> > -	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
> > -
> > -	dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt-
> > >buf_size,
> > -			 DMA_TO_DEVICE);
> > -	kfree(pkt->va_base);
> > -	kfree(pkt);
> > -}
> > -EXPORT_SYMBOL(cmdq_pkt_destroy);
> > -
> >   static int cmdq_pkt_append_command(struct cmdq_pkt *pkt,
> >   				   struct cmdq_instruction inst)
> >   {
> > @@ -426,19 +382,4 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> >   }
> >   EXPORT_SYMBOL(cmdq_pkt_finalize);
> >   
> > -int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
> > -{
> > -	int err;
> > -	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
> > -
> > -	err = mbox_send_message(client->chan, pkt);
> > -	if (err < 0)
> > -		return err;
> > -	/* We can send next packet immediately, so just call txdone. */
> > -	mbox_client_txdone(client->chan, 0);
> > -
> > -	return 0;
> > -}
> > -EXPORT_SYMBOL(cmdq_pkt_flush_async);
> > -
> >   MODULE_LICENSE("GPL v2");
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 649955d2cf5c..6c42d817d368 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -59,21 +59,6 @@ struct cmdq_client *cmdq_mbox_create(struct
> > device *dev, int index);
> >    */
> >   void cmdq_mbox_destroy(struct cmdq_client *client);
> >   
> > -/**
> > - * cmdq_pkt_create() - create a CMDQ packet
> > - * @client:	the CMDQ mailbox client
> > - * @size:	required CMDQ buffer size
> > - *
> > - * Return: CMDQ packet pointer
> > - */
> > -struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client,
> > size_t size);
> > -
> > -/**
> > - * cmdq_pkt_destroy() - destroy the CMDQ packet
> > - * @pkt:	the CMDQ packet
> > - */
> > -void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
> > -
> >   /**
> >    * cmdq_pkt_write() - append write command to the CMDQ packet
> >    * @pkt:	the CMDQ packet
> > @@ -266,19 +251,6 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt,
> > dma_addr_t addr);
> >    */
> >   int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
> >   
> > -/**
> > - * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute
> > the CMDQ
> > - *                          packet and call back at the end of
> > done packet
> > - * @pkt:	the CMDQ packet
> > - *
> > - * Return: 0 for success; else the error code is returned
> > - *
> > - * Trigger CMDQ to asynchronously execute the CMDQ packet and call
> > back
> > - * at the end of done packet. Note that this is an ASYNC function.
> > When the
> > - * function returned, it may or may not be finished.
> > - */
> > -int cmdq_pkt_flush_async(struct cmdq_pkt *pkt);
> > -
> >   #else /* IS_ENABLED(CONFIG_MTK_CMDQ) */
> >   
> >   static inline int cmdq_dev_get_client_reg(struct device *dev,
> > @@ -294,13 +266,6 @@ static inline struct cmdq_client
> > *cmdq_mbox_create(struct device *dev, int index
> >   
> >   static inline void cmdq_mbox_destroy(struct cmdq_client *client)
> > { }
> >   
> > -static inline  struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client
> > *client, size_t size)
> > -{
> > -	return ERR_PTR(-EINVAL);
> > -}
> > -
> > -static inline void cmdq_pkt_destroy(struct cmdq_pkt *pkt) { }
> > -
> >   static inline int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys,
> > u16 offset, u32 value)
> >   {
> >   	return -ENOENT;
> > @@ -384,11 +349,6 @@ static inline int cmdq_pkt_finalize(struct
> > cmdq_pkt *pkt)
> >   	return -EINVAL;
> >   }
> >   
> > -static inline int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
> > -{
> > -	return -EINVAL;
> > -}
> > -
> >   #endif /* IS_ENABLED(CONFIG_MTK_CMDQ) */
> >   
> >   #endif	/* __MTK_CMDQ_H__ */
> 
> 

From s-vadapalli at ti.com  Thu Feb 15 20:56:01 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Fri, 16 Feb 2024 10:26:01 +0530
Subject: [PATCH v5] arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in
 serdes_ln_ctrl
In-Reply-To: <af73545a-1746-4e14-a3f2-772d72e6ff97@ti.com>
References: <20240213080348.248916-1-s-vadapalli@ti.com>
 <1be60db1-f292-1074-5898-801380e1fb22@axentia.se>
 <af73545a-1746-4e14-a3f2-772d72e6ff97@ti.com>
Message-ID: <4abe2bde-1171-4b77-b7bc-49491792a721@ti.com>

On 24/02/13 11:08AM, Andrew Davis wrote:
> On 2/13/24 3:19 AM, Peter Rosin wrote:
> > Hi!
> > 
> > 2024-02-13 at 09:03, Siddharth Vadapalli wrote:
> > > From: Chintan Vankar <c-vankar at ti.com>
> > > 
> > > Change offset in mux-reg-masks property for serdes_ln_ctrl node
> > > since reg-mux property is used in compatible.
> > > 
> > > Fixes: 2765149273f4 ("mux: mmio: use reg property when parent device is not a syscon")
> > > Signed-off-by: Chintan Vankar <c-vankar at ti.com>
> > > Acked-by: Andrew Davis <afd at ti.com>
> > > Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
> > > ---
...

> > > +			mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */
> > > +					<0x8 0x3>, <0xc 0x3>, /* SERDES0 lane2/3 select */
> > > +					<0x10 0x3>, <0x14 0x3>, /* SERDES1 lane0/1 select */
> > > +					<0x18 0x3>, <0x1c 0x3>, /* SERDES1 lane2/3 select */
> > > +					<0x20 0x3>, <0x24 0x3>, /* SERDES2 lane0/1 select */
> > > +					<0x28 0x3>, <0x2c 0x3>; /* SERDES2 lane2/3 select */
> > >   			idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>,
> > >   				      <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
> > >   				      <J784S4_SERDES0_LANE2_IP3_UNUSED>,
> > 
> > Ouch. I suspect there is a similar problem in
> > arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi:
> > 
> > 
> > 	fss: bus at 47000000 {
> > 		compatible = "simple-bus";
> > 		reg = <0x0 0x47000000 0x0 0x100>;
> > 		#address-cells = <2>;
> > 		#size-cells = <2>;
> > 		ranges;
> > 
> > 		hbmc_mux: mux-controller at 47000004 {
> > 			compatible = "reg-mux";
> > 			reg = <0x00 0x47000004 0x00 0x2>;
> > 			#mux-control-cells = <1>;
> > -			mux-reg-masks = <0x4 0x2>; /* HBMC select */
> > +			mux-reg-masks = <0x0 0x2>; /* HBMC select */
> > 		};
> > 
> > Who knows what non-upstreamed devices and devicetrees are affected?
> > I guess we need to revert 2765149273f4 ("mux: mmio: use reg property
> > when parent device is not a syscon") unless someone sees a sane way
> > to fix this.
> 
> There are only two in-tree nodes with "reg-mux" with a reg property: the
> one this patch fixes, and the hbmc_mux you point out, both in TI devices.
> I'd say it is safe to assume we are the only users, and our non-upstreamed
> DTs depend on that patch, reverting it would cause more issues for
> out-of-tree users than just fixing the two broken nodes above.

Peter,

Is it alright for this patch to be merged, given Andrew's response above?
The problem with "hbmc_mux" node that you pointed out above could be fixed
by another patch. Please let me know.

Regards,
Siddharth.


From vigneshr at ti.com  Thu Feb 15 21:36:05 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Fri, 16 Feb 2024 11:06:05 +0530
Subject: [PATCH v4 2/2] arm64: dts: ti: Add common1 register space for
 AM62x, AM62A & AM65x SoCs
In-Reply-To: <20240215115516.3157909-3-devarsht@ti.com>
References: <20240215115516.3157909-1-devarsht@ti.com>
 <20240215115516.3157909-3-devarsht@ti.com>
Message-ID: <d2b6dcda-cd22-4163-bdf5-2bc4b8e276ea@ti.com>



On 15/02/24 17:25, Devarsh Thakkar wrote:
> This adds common1 register space for AM62x, AM62A and AM65x SoC's which are
> using TI's Keystone display hardware and supporting it as described in
> Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> 
> Fixes: 3618811657b3 ("arm64: dts: ti: k3-am62a-main: Add node for Display SubSystem (DSS)")
> Fixes: 8ccc1073c7bb ("arm64: dts: ti: k3-am62-main: Add node for DSS")
> Fixes: fc539b90eda2 ("arm64: dts: ti: am654: Add DSS node")

This doesn't work. Patch wont apply cleanly to kernels before before
AM62A was introduced.

Please split this into 3 patches, one per SoC with appropriate Fixes: tag.

> Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
> Reviewed-by: Aradhya Bhatia <a-bhatia1 at ti.com>
> ---
> V2: Add common1 region for AM62A SoC too
> V3: Add Fixes tag
> V4: Add Reviewed-by
> ---
>  arch/arm64/boot/dts/ti/k3-am62-main.dtsi  | 5 +++--
>  arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 5 +++--
>  arch/arm64/boot/dts/ti/k3-am65-main.dtsi  | 5 +++--
>  3 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> index fe0cc4a9a501..8cee4d94cdd3 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
> @@ -779,9 +779,10 @@ dss: dss at 30200000 {
>  		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
>  		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
>  		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
> -		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
> +		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
> +		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
>  		reg-names = "common", "vidl1", "vid",
> -			    "ovr1", "ovr2", "vp1", "vp2";
> +			    "ovr1", "ovr2", "vp1", "vp2", "common1";
>  		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&k3_clks 186 6>,
>  			 <&dss_vp1_clk>,
> diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> index 972971159a62..f475daea548e 100644
> --- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
> @@ -994,9 +994,10 @@ dss: dss at 30200000 {
>  		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
>  		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
>  		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Tied OFF in the SoC */
> -		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
> +		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
> +		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
>  		reg-names = "common", "vidl1", "vid",
> -			    "ovr1", "ovr2", "vp1", "vp2";
> +			    "ovr1", "ovr2", "vp1", "vp2", "common1";
>  		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&k3_clks 186 6>,
>  			 <&k3_clks 186 0>,
> diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> index 07010d31350e..ff857117d719 100644
> --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> @@ -991,9 +991,10 @@ dss: dss at 4a00000 {
>  		      <0x0 0x04a07000 0x0 0x1000>, /* ovr1 */
>  		      <0x0 0x04a08000 0x0 0x1000>, /* ovr2 */
>  		      <0x0 0x04a0a000 0x0 0x1000>, /* vp1 */
> -		      <0x0 0x04a0b000 0x0 0x1000>; /* vp2 */
> +		      <0x0 0x04a0b000 0x0 0x1000>, /* vp2 */
> +		      <0x0 0x04a01000 0x0 0x1000>; /* common1 */
>  		reg-names = "common", "vidl1", "vid",
> -			"ovr1", "ovr2", "vp1", "vp2";
> +			"ovr1", "ovr2", "vp1", "vp2", "common1";
>  
>  		ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
>  

-- 
Regards
Vignesh


From vkoul at kernel.org  Thu Feb 15 22:02:31 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 16 Feb 2024 11:32:31 +0530
Subject: [PATCH v3 08/18] phy: ti: phy-j721e-wiz: split wiz_clock_init()
 function
In-Reply-To: <Zc4xJtLl3zo_YrBC@smile.fi.intel.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-8-5c2e4a3fac1f@bootlin.com>
 <Zc4xJtLl3zo_YrBC@smile.fi.intel.com>
Message-ID: <Zc76d4B4hjTC3xum@matsya>

On 15-02-24, 17:43, Andy Shevchenko wrote:
> On Thu, Feb 15, 2024 at 04:17:53PM +0100, Thomas Richard wrote:
> > The wiz_clock_init() function mixes probe and hardware configuration.
> > Rename the wiz_clock_init() to wiz_clock_probe() and move the hardware
> > configuration part in a new function named wiz_clock_init().
> > 
> > This hardware configuration sequence must be called during the resume
> > stage of the driver.
> 
> ...
> 
> (Side note, as this can be done later)
> 
> >  	if (rate >= 100000000)
> 
> > +		if (rate >= 100000000)
> 
> > +	if (rate >= 100000000)
> 
> I would make local definition and use it, we may get the global one as there
> are users.
> 
> #define HZ_PER_GHZ	1000000000UL

Better to define as:
#define HZ_PER_GHZ 1 * GIGA

-- 
~Vinod


From vkoul at kernel.org  Thu Feb 15 22:11:56 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 16 Feb 2024 11:41:56 +0530
Subject: [PATCH V4 2/6] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240210204606.11944-3-aford173@gmail.com>
References: <20240210204606.11944-1-aford173@gmail.com>
 <20240210204606.11944-3-aford173@gmail.com>
Message-ID: <Zc78rFPkGtTMauYh@matsya>

On 10-02-24, 14:45, Adam Ford wrote:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the driver for the Samsung HDMI PHY found on the
> i.MX8MP SoC. Based on downstream implementation from
> Sandor Yu <Sandor.yu at nxp.com>.  According to the TRM, the PHY
> receives parallel data from the link and serializes it.  It
> also sets the PLL clock needed for the TX serializer.
> 
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v2)
> Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
> Co-developed-by: Marco Felsch <m.felsch at pengutronix.de>
> Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> # Kontron BL
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> ---
> V4:
> - I (Adam) added a comment in the code for clarifcation
>   based on questions from Luca concerning a difference
>   between the code and the ref manual.
> - Fixed the GENMASK on REG14
> - Expanded the commit message briefly describing
>   a bit more of what this driver does.
> - Removed some unnecessary include files.
> 
> v3:
> - use GENMASK/FIELD_PREP
> - lowercase hex values
> - correct coding style
> v2:
> - use DEFINE_RUNTIME_DEV_PM_OPS
> ---
>  drivers/phy/freescale/Kconfig                |   6 +
>  drivers/phy/freescale/Makefile               |   1 +
>  drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 721 +++++++++++++++++++
>  3 files changed, 728 insertions(+)
>  create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> 
> diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> index 853958fb2c06..5c2b73042dfc 100644
> --- a/drivers/phy/freescale/Kconfig
> +++ b/drivers/phy/freescale/Kconfig
> @@ -35,6 +35,12 @@ config PHY_FSL_IMX8M_PCIE
>  	  Enable this to add support for the PCIE PHY as found on
>  	  i.MX8M family of SOCs.
>  
> +config PHY_FSL_SAMSUNG_HDMI_PHY
> +	tristate "Samsung HDMI PHY support"
> +	depends on OF && HAS_IOMEM
> +	help
> +	  Enable this to add support for the Samsung HDMI PHY in i.MX8MP.
> +
>  endif
>  
>  config PHY_FSL_LYNX_28G
> diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
> index cedb328bc4d2..c4386bfdb853 100644
> --- a/drivers/phy/freescale/Makefile
> +++ b/drivers/phy/freescale/Makefile
> @@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
>  obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
>  obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)	+= phy-fsl-imx8m-pcie.o
>  obj-$(CONFIG_PHY_FSL_LYNX_28G)		+= phy-fsl-lynx-28g.o
> +obj-$(CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY)	+= phy-fsl-samsung-hdmi.o
> diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> new file mode 100644
> index 000000000000..91cf8e4668b2
> --- /dev/null
> +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
> @@ -0,0 +1,721 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2020 NXP
> + * Copyright 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>

Do you need both of these headers?

> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>

same here

> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +
> +#define PHY_REG_00		0x00
> +#define PHY_REG_01		0x04
> +#define PHY_REG_02		0x08
> +#define PHY_REG_08		0x20
> +#define PHY_REG_09		0x24
> +#define PHY_REG_10		0x28
> +#define PHY_REG_11		0x2c
> +
> +#define PHY_REG_12		0x30
> +#define  REG12_CK_DIV_MASK	GENMASK(5, 4)
> +
> +#define PHY_REG_13		0x34
> +#define  REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
> +
> +#define PHY_REG_14		0x38
> +#define  REG14_TOL_MASK		GENMASK(7, 4)
> +#define  REG14_RP_CODE_MASK	GENMASK(3, 1)
> +#define  REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
> +
> +#define PHY_REG_15		0x3c
> +#define PHY_REG_16		0x40
> +#define PHY_REG_17		0x44
> +#define PHY_REG_18		0x48
> +#define PHY_REG_19		0x4c
> +#define PHY_REG_20		0x50
> +
> +#define PHY_REG_21		0x54
> +#define  REG21_SEL_TX_CK_INV	BIT(7)
> +#define  REG21_PMS_S_MASK	GENMASK(3, 0)
> +
> +#define PHY_REG_22		0x58
> +#define PHY_REG_23		0x5c
> +#define PHY_REG_24		0x60
> +#define PHY_REG_25		0x64
> +#define PHY_REG_26		0x68
> +#define PHY_REG_27		0x6c
> +#define PHY_REG_28		0x70
> +#define PHY_REG_29		0x74
> +#define PHY_REG_30		0x78
> +#define PHY_REG_31		0x7c
> +#define PHY_REG_32		0x80
> +
> +/*
> + * REG33 does not match the ref manual. According to Sandor Yu from NXP,
> + * "There is a doc issue on the i.MX8MP latest RM"
> + * REG33 is being used per guidance from Sandor
> + */
> +
> +#define PHY_REG_33		0x84
> +#define  REG33_MODE_SET_DONE	BIT(7)
> +#define  REG33_FIX_DA		BIT(1)
> +
> +#define PHY_REG_34		0x88
> +#define  REG34_PHY_READY	BIT(7)
> +#define  REG34_PLL_LOCK		BIT(6)
> +#define  REG34_PHY_CLK_READY	BIT(5)
> +
> +#define PHY_REG_35		0x8c
> +#define PHY_REG_36		0x90
> +#define PHY_REG_37		0x94
> +#define PHY_REG_38		0x98
> +#define PHY_REG_39		0x9c
> +#define PHY_REG_40		0xa0
> +#define PHY_REG_41		0xa4
> +#define PHY_REG_42		0xa8
> +#define PHY_REG_43		0xac
> +#define PHY_REG_44		0xb0
> +#define PHY_REG_45		0xb4
> +#define PHY_REG_46		0xb8
> +#define PHY_REG_47		0xbc
> +
> +#define PHY_PLL_DIV_REGS_NUM 6
> +
> +struct phy_config {
> +	u32	pixclk;
> +	u8	pll_div_regs[PHY_PLL_DIV_REGS_NUM];
> +};
> +
> +const struct phy_config phy_pll_cfg[] = {
> +	{
> +		.pixclk = 22250000,
> +		.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 23750000,
> +		.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 24000000,
> +		.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 24024000,
> +		.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 25175000,
> +		.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 25200000,
> +		.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 26750000,
> +		.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 27000000,
> +		.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 27027000,
> +		.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 29500000,
> +		.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 30750000,
> +		.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
> +	}, {
> +		.pixclk = 30888000,
> +		.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
> +	}, {
> +		.pixclk = 33750000,
> +		.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 35000000,
> +		.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 36000000,
> +		.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 36036000,
> +		.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 40000000,
> +		.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 43200000,
> +		.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 43243200,
> +		.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 44500000,
> +		.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
> +	}, {
> +		.pixclk = 47000000,
> +		.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 47500000,
> +		.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 50349650,
> +		.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 50400000,
> +		.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 53250000,
> +		.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
> +	}, {
> +		.pixclk = 53500000,
> +		.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 54000000,
> +		.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 54054000,
> +		.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 59000000,
> +		.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 59340659,
> +		.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
> +	}, {
> +		.pixclk = 59400000,
> +		.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 61500000,
> +		.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
> +	}, {
> +		.pixclk = 63500000,
> +		.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 67500000,
> +		.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 70000000,
> +		.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 72000000,
> +		.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 72072000,
> +		.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 74176000,
> +		.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
> +	}, {
> +		.pixclk = 74250000,
> +		.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
> +	}, {
> +		.pixclk = 78500000,
> +		.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 80000000,
> +		.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 82000000,
> +		.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
> +	}, {
> +		.pixclk = 82500000,
> +		.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
> +	}, {
> +		.pixclk = 89000000,
> +		.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 90000000,
> +		.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 94000000,
> +		.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 95000000,
> +		.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 98901099,
> +		.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
> +	}, {
> +		.pixclk = 99000000,
> +		.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
> +	}, {
> +		.pixclk = 100699300,
> +		.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 100800000,
> +		.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 102500000,
> +		.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
> +	}, {
> +		.pixclk = 104750000,
> +		.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
> +	}, {
> +		.pixclk = 106500000,
> +		.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
> +	}, {
> +		.pixclk = 107000000,
> +		.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 108000000,
> +		.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 108108000,
> +		.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 118000000,
> +		.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 118800000,
> +		.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 123000000,
> +		.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
> +	}, {
> +		.pixclk = 127000000,
> +		.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 135000000,
> +		.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 135580000,
> +		.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
> +	}, {
> +		.pixclk = 137520000,
> +		.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
> +	}, {
> +		.pixclk = 138750000,
> +		.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
> +	}, {
> +		.pixclk = 140000000,
> +		.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 144000000,
> +		.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 148352000,
> +		.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
> +	}, {
> +		.pixclk = 148500000,
> +		.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
> +	}, {
> +		.pixclk = 154000000,
> +		.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
> +	}, {
> +		.pixclk = 157000000,
> +		.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 160000000,
> +		.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 162000000,
> +		.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
> +	}, {
> +		.pixclk = 164000000,
> +		.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
> +	}, {
> +		.pixclk = 165000000,
> +		.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
> +	}, {
> +		.pixclk = 180000000,
> +		.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 185625000,
> +		.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 188000000,
> +		.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 198000000,
> +		.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
> +	}, {
> +		.pixclk = 205000000,
> +		.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
> +	}, {
> +		.pixclk = 209500000,
> +		.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
> +	}, {
> +		.pixclk = 213000000,
> +		.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
> +	}, {
> +		.pixclk = 216000000,
> +		.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 216216000,
> +		.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 237600000,
> +		.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 254000000,
> +		.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
> +	}, {
> +		.pixclk = 277500000,
> +		.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
> +	}, {
> +		.pixclk = 288000000,
> +		.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
> +	}, {
> +		.pixclk = 297000000,
> +		.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
> +	},
> +};
> +
> +struct reg_settings {
> +	u8 reg;
> +	u8 val;
> +};
> +
> +const struct reg_settings common_phy_cfg[] = {
> +	{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
> +	{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
> +	{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
> +	/* REG12 pixclk specific */
> +	/* REG13 pixclk specific */
> +	/* REG14 pixclk specific */
> +	{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
> +	{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
> +	{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
> +	/* REG21 pixclk specific */
> +	{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
> +	{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
> +	{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
> +	{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
> +	{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
> +	{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
> +	{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
> +	{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
> +	{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
> +	{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
> +	{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
> +	{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
> +	{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
> +};
> +
> +struct fsl_samsung_hdmi_phy {
> +	struct device *dev;
> +	void __iomem *regs;
> +	struct clk *apbclk;
> +	struct clk *refclk;
> +
> +	/* clk provider */
> +	struct clk_hw hw;
> +	const struct phy_config *cur_cfg;
> +};
> +
> +static inline struct fsl_samsung_hdmi_phy *
> +to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
> +{
> +	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
> +}
> +
> +static void
> +fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
> +				      const struct phy_config *cfg)
> +{
> +	u8 div;

this would lead to static checkers complaining that div can be used
uninitialized, there is no default in the switch below to handle that, so
better to initialize this to 0 here

> +
> +	switch (cfg->pixclk) {
> +	case  22250000 ...  33750000:
> +		div = 0xf;
> +		break;
> +	case  35000000 ...  40000000:
> +		div = 0xb;
> +		break;
> +	case  43200000 ...  47500000:
> +		div = 0x9;
> +		break;
> +	case  50349650 ...  63500000:
> +		div = 0x7;
> +		break;
> +	case  67500000 ...  90000000:
> +		div = 0x5;
> +		break;
> +	case  94000000 ... 148500000:
> +		div = 0x3;
> +		break;
> +	case 154000000 ... 297000000:
> +		div = 0x1;
> +		break;
> +	}
> +
> +	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
> +	       phy->regs + PHY_REG_21);
> +}
> +
> +static void
> +fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
> +					    const struct phy_config *cfg)
> +{
> +	u32 pclk = cfg->pixclk;
> +	u32 fld_tg_code;
> +	u32 pclk_khz;
> +	u8 div;

this might suffer from same issue

> +
> +	switch (cfg->pixclk) {
> +	case  22250000 ...  47500000:
> +		div = 1;
> +		break;
> +	case  50349650 ...  99000000:
> +		div = 2;
> +		break;
> +	case 100699300 ... 198000000:
> +		div = 4;
> +		break;
> +	case 205000000 ... 297000000:
> +		div = 8;
> +		break;
> +	}
> +
> +	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
> +
> +	/*
> +	 * Calculation for the frequency lock detector target code (fld_tg_code)
> +	 * is based on reference manual register description of PHY_REG13
> +	 * (13.10.3.1.14.2):
> +	 *   1st) Calculate int_pllclk which is determinded by FLD_CK_DIV
> +	 *   2nd) Increase resolution to avoid rounding issues
> +	 *   3th) Do the div (256 / Freq. of int_pllclk) * 24
> +	 *   4th) Reduce the resolution and always round up since the NXP
> +	 *        settings rounding up always too. TODO: Check if that is
> +	 *        correct.
> +	 */
> +	pclk /= div;
> +	pclk_khz = pclk / 1000;
> +	fld_tg_code = 256 * 1000 * 1000 / pclk_khz * 24;
> +	fld_tg_code = DIV_ROUND_UP(fld_tg_code, 1000);
> +
> +	/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
> +	writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
> +	       phy->regs + PHY_REG_13);
> +	writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
> +	       FIELD_PREP(REG14_RP_CODE_MASK, 2) |
> +	       FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
> +	       phy->regs + PHY_REG_14);
> +}
> +
> +static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
> +					  const struct phy_config *cfg)
> +{
> +	int i, ret;
> +	u8 val;
> +
> +	/* HDMI PHY init */
> +	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
> +
> +	/* common PHY registers */
> +	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
> +		writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
> +
> +	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
> +	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
> +		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
> +
> +	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
> +	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
> +
> +	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
> +
> +	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
> +				 val & REG34_PLL_LOCK, 50, 20000);
> +	if (ret)
> +		dev_err(phy->dev, "PLL failed to lock\n");
> +
> +	return ret;
> +}
> +
> +static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
> +					 unsigned long parent_rate)
> +{
> +	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
> +
> +	if (!phy->cur_cfg)
> +		return 74250000;
> +
> +	return phy->cur_cfg->pixclk;
> +}
> +
> +static long phy_clk_round_rate(struct clk_hw *hw,
> +			       unsigned long rate, unsigned long *parent_rate)
> +{
> +	int i;
> +
> +	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> +		if (phy_pll_cfg[i].pixclk <= rate)
> +			return phy_pll_cfg[i].pixclk;
> +
> +	return -EINVAL;
> +}
> +
> +static int phy_clk_set_rate(struct clk_hw *hw,
> +			    unsigned long rate, unsigned long parent_rate)
> +{
> +	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
> +	int i;
> +
> +	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
> +		if (phy_pll_cfg[i].pixclk <= rate)
> +			break;
> +
> +	if (i < 0)
> +		return -EINVAL;
> +
> +	phy->cur_cfg = &phy_pll_cfg[i];
> +
> +	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> +}
> +
> +static const struct clk_ops phy_clk_ops = {
> +	.recalc_rate = phy_clk_recalc_rate,
> +	.round_rate = phy_clk_round_rate,
> +	.set_rate = phy_clk_set_rate,
> +};
> +
> +static int phy_clk_register(struct fsl_samsung_hdmi_phy *phy)
> +{
> +	struct device *dev = phy->dev;
> +	struct device_node *np = dev->of_node;
> +	struct clk_init_data init;
> +	const char *parent_name;
> +	struct clk *phyclk;
> +	int ret;
> +
> +	parent_name = __clk_get_name(phy->refclk);
> +
> +	init.parent_names = &parent_name;
> +	init.num_parents = 1;
> +	init.flags = 0;
> +	init.name = "hdmi_pclk";
> +	init.ops = &phy_clk_ops;
> +
> +	phy->hw.init = &init;
> +
> +	phyclk = devm_clk_register(dev, &phy->hw);
> +	if (IS_ERR(phyclk))
> +		return dev_err_probe(dev, PTR_ERR(phyclk),
> +				     "failed to register clock\n");
> +
> +	ret = of_clk_add_provider(np, of_clk_src_simple_get, phyclk);
> +	if (ret)
> +		return dev_err_probe(dev, ret,
> +				     "failed to register clock provider\n");
> +
> +	return 0;
> +}
> +
> +static int fsl_samsung_hdmi_phy_probe(struct platform_device *pdev)
> +{
> +	struct fsl_samsung_hdmi_phy *phy;
> +	int ret;
> +
> +	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
> +	if (!phy)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, phy);
> +	phy->dev = &pdev->dev;
> +
> +	phy->regs = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(phy->regs))
> +		return PTR_ERR(phy->regs);
> +
> +	phy->apbclk = devm_clk_get(phy->dev, "apb");
> +	if (IS_ERR(phy->apbclk))
> +		return dev_err_probe(phy->dev, PTR_ERR(phy->apbclk),
> +				     "failed to get apb clk\n");
> +
> +	phy->refclk = devm_clk_get(phy->dev, "ref");
> +	if (IS_ERR(phy->refclk))
> +		return dev_err_probe(phy->dev, PTR_ERR(phy->refclk),
> +				     "failed to get ref clk\n");
> +
> +	ret = clk_prepare_enable(phy->apbclk);
> +	if (ret) {
> +		dev_err(phy->dev, "failed to enable apbclk\n");
> +		return ret;
> +	}
> +
> +	pm_runtime_get_noresume(phy->dev);
> +	pm_runtime_set_active(phy->dev);
> +	pm_runtime_enable(phy->dev);
> +
> +	ret = phy_clk_register(phy);
> +	if (ret) {
> +		dev_err(&pdev->dev, "register clk failed\n");
> +		goto register_clk_failed;
> +	}
> +
> +	pm_runtime_put(phy->dev);
> +
> +	return 0;
> +
> +register_clk_failed:
> +	clk_disable_unprepare(phy->apbclk);
> +
> +	return ret;
> +}
> +
> +static int fsl_samsung_hdmi_phy_remove(struct platform_device *pdev)
> +{
> +	of_clk_del_provider(pdev->dev.of_node);
> +
> +	return 0;
> +}
> +
> +static int fsl_samsung_hdmi_phy_suspend(struct device *dev)

annotate these with __maybe_unused please, when PM is disabled we get
warning about unused symbols

> +{
> +	struct fsl_samsung_hdmi_phy *phy = dev_get_drvdata(dev);
> +
> +	clk_disable_unprepare(phy->apbclk);
> +
> +	return 0;
> +}
> +
> +static int fsl_samsung_hdmi_phy_resume(struct device *dev)
> +{
> +	struct fsl_samsung_hdmi_phy *phy = dev_get_drvdata(dev);
> +	int ret = 0;
> +
> +	ret = clk_prepare_enable(phy->apbclk);
> +	if (ret) {
> +		dev_err(phy->dev, "failed to enable apbclk\n");
> +		return ret;
> +	}
> +
> +	if (phy->cur_cfg)
> +		ret = fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
> +
> +	return ret;
> +
> +}
> +
> +static DEFINE_RUNTIME_DEV_PM_OPS(fsl_samsung_hdmi_phy_pm_ops,
> +				 fsl_samsung_hdmi_phy_suspend,
> +				 fsl_samsung_hdmi_phy_resume, NULL);
> +
> +static const struct of_device_id fsl_samsung_hdmi_phy_of_match[] = {
> +	{
> +		.compatible = "fsl,imx8mp-hdmi-phy",
> +	}, {
> +		/* sentinel */
> +	}
> +};
> +MODULE_DEVICE_TABLE(of, fsl_samsung_hdmi_phy_of_match);
> +
> +static struct platform_driver fsl_samsung_hdmi_phy_driver = {
> +	.probe  = fsl_samsung_hdmi_phy_probe,
> +	.remove = fsl_samsung_hdmi_phy_remove,
> +	.driver = {
> +		.name = "fsl-samsung-hdmi-phy",
> +		.of_match_table = fsl_samsung_hdmi_phy_of_match,
> +		.pm = pm_ptr(&fsl_samsung_hdmi_phy_pm_ops),
> +	},
> +};
> +module_platform_driver(fsl_samsung_hdmi_phy_driver);
> +
> +MODULE_AUTHOR("Sandor Yu <Sandor.yu at nxp.com>");
> +MODULE_DESCRIPTION("SAMSUNG HDMI 2.0 Transmitter PHY Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.43.0

-- 
~Vinod


From Moudy.Ho at mediatek.com  Thu Feb 15 22:20:54 2024
From: Moudy.Ho at mediatek.com (=?utf-8?B?TW91ZHkgSG8gKOS9leWul+WOnyk=?=)
Date: Fri, 16 Feb 2024 06:20:54 +0000
Subject: [PATCH 6/9] media: platform: mtk-mdp3: drop calling
 cmdq_pkt_finalize()
In-Reply-To: <4dcfaf49-aaac-4980-a149-02fec3109f31@collabora.com>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
	 <20240215004931.3808-7-chunkuang.hu@kernel.org>
	 <4dcfaf49-aaac-4980-a149-02fec3109f31@collabora.com>
Message-ID: <af4bfdd52f0ca022730aedcb456bb1a0b105ae3e.camel@mediatek.com>

On Thu, 2024-02-15 at 11:29 +0100, AngeloGioacchino Del Regno wrote:
> Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> > Because client driver has the information of struct cmdq_client, so
> > it's not necessary to store struct cmdq_client in struct cmdq_pkt.
> > cmdq_pkt_finalize() use struct cmdq_client in struct cmdq_pkt, so
> > it's
> > going to be abandoned. Therefore, use cmdq_pkt_eoc() and
> > cmdq_pkt_nop()
> > to replace cmdq_pkt_finalize().
> 
> No, it's not because cmdq_pkt_finalize() has cmdq_client, but because
> we want
> finer grain control over the CMDQ packets, as not all cases require
> the NOP
> packet to be appended after EOC.
> 
> Besides, honestly I'm not even sure if the NOP is always required in
> MDP3, so...
> 
> ...Moudy, you know the MDP3 way better than anyone else - can you
> please
> check if NOP is actually needed here?
> 
> Thanks!
> Angelo
> 

Hi Angelo,

After confirming with the hardware designer and performing the video
playback test, it was discovered that MDP3 is capable of excluding the
NOP(jump) instruction.

Sincerely,
Moudy
> > 
> > Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> > ---
> >   drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 3 ++-
> >   drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c | 2 ++
> >   drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h | 1 +
> >   3 files changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
> > b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
> > index 6adac857a477..a420d492d879 100644
> > --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
> > +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
> > @@ -471,7 +471,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct
> > mdp_cmdq_param *param)
> >   		dev_err(dev, "mdp_path_config error\n");
> >   		goto err_free_path;
> >   	}
> > -	cmdq_pkt_finalize(&cmd->pkt);
> > +	cmdq_pkt_eoc(&cmd->pkt);
> > +	cmdq_pkt_nop(&cmd->pkt, mdp->cmdq_shift_pa);
> >   
> >   	for (i = 0; i < num_comp; i++)
> >   		memcpy(&comps[i], path->comps[i].comp,
> > diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
> > b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
> > index 94f4ed78523b..2214744c937c 100644
> > --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
> > +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
> > @@ -231,6 +231,8 @@ static int mdp_probe(struct platform_device
> > *pdev)
> >   		goto err_put_scp;
> >   	}
> >   
> > +	mdp->cmdq_shift_pa = cmdq_get_shift_pa(mdp->cmdq_clt->chan);
> > +
> >   	init_waitqueue_head(&mdp->callback_wq);
> >   	ida_init(&mdp->mdp_ida);
> >   	platform_set_drvdata(pdev, mdp);
> > diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
> > b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
> > index 7e21d226ceb8..ed61e0bb69ee 100644
> > --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
> > +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
> > @@ -83,6 +83,7 @@ struct mdp_dev {
> >   	u32					id_count;
> >   	struct ida				mdp_ida;
> >   	struct cmdq_client			*cmdq_clt;
> > +	u8					cmdq_shift_pa;
> >   	wait_queue_head_t			callback_wq;
> >   
> >   	struct v4l2_device			v4l2_dev;
> 
> 

From devarsht at ti.com  Thu Feb 15 22:24:26 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Fri, 16 Feb 2024 11:54:26 +0530
Subject: [PATCH v5 4/4] arm64: dts: ti: Add common1 register space for AM62A SoC
In-Reply-To: <20240216062426.4170528-1-devarsht@ti.com>
References: <20240216062426.4170528-1-devarsht@ti.com>
Message-ID: <20240216062426.4170528-5-devarsht@ti.com>

This adds common1 register space for AM62A SoC which is using TI's Keystone
display hardware and supporting it as described in
Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml

Fixes: 3618811657b3 ("arm64: dts: ti: k3-am62a-main: Add node for Display SubSystem (DSS)")
Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
---
V1->V4 :
- No change (this was part of "arm64: dts: ti: Add common1 register
  space for AM62x, AM62A & AM65x SoCs )

V5 :
- Split this as a separate patch from "arm64: dts: ti: Add common1
  register space for AM62x, AM62A & AM65x SoCs"
- Remove Reviewed-By tag as this is split from older revision
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index 2749533cf4fd..dbdd6bec4667 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -994,9 +994,10 @@ dss: dss at 30200000 {
 		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
 		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
 		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Tied OFF in the SoC */
-		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			    "ovr1", "ovr2", "vp1", "vp2";
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
 		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 186 6>,
 			 <&k3_clks 186 0>,
-- 
2.34.1



From devarsht at ti.com  Thu Feb 15 22:24:22 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Fri, 16 Feb 2024 11:54:22 +0530
Subject: [PATCH v5 0/4] Add common1 region for AM62, AM62A & AM65x
Message-ID: <20240216062426.4170528-1-devarsht@ti.com>

This adds DSS common1 region for respective SoCs supporting it.

Changelog:
V2 : Remove do-not-merge tag and add am62a dss common1 reion
V3 : Add Fixes tag to each commit
V4 : Add Reviewed-by tag and AM62A SoC TRM Link
V5 : Split dts patch to separate patches for each SoC

Devarsh Thakkar (4):
  dt-bindings: display: ti,am65x-dss: Add support for common1 region
  arm64: dts: ti: Add common1 register space for AM65x SoC
  arm64: dts: ti: Add common1 register space for AM62x SoC
  arm64: dts: ti: Add common1 register space for AM62A SoC

 .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi                   | 5 +++--
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi                  | 5 +++--
 arch/arm64/boot/dts/ti/k3-am65-main.dtsi                   | 5 +++--
 4 files changed, 14 insertions(+), 8 deletions(-)

-- 
2.34.1



From devarsht at ti.com  Thu Feb 15 22:24:24 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Fri, 16 Feb 2024 11:54:24 +0530
Subject: [PATCH v5 2/4] arm64: dts: ti: Add common1 register space for AM65x SoC
In-Reply-To: <20240216062426.4170528-1-devarsht@ti.com>
References: <20240216062426.4170528-1-devarsht@ti.com>
Message-ID: <20240216062426.4170528-3-devarsht@ti.com>

This adds common1 register space for AM65x SoC which is using TI's Keystone
display hardware and supporting it as described in
Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml

Fixes: fc539b90eda2 ("arm64: dts: ti: am654: Add DSS node")
Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
---
V1->V4 :
- No change (this was part of "arm64: dts: ti: Add common1 register
  space for AM62x, AM62A & AM65x SoCs )

V5 :
- Split this as a separate patch from "arm64: dts: ti: Add common1
  register space for AM62x, AM62A & AM65x SoCs"
- Remove Reviewed-By tag as patch is split now
---
 arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index 07010d31350e..ff857117d719 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -991,9 +991,10 @@ dss: dss at 4a00000 {
 		      <0x0 0x04a07000 0x0 0x1000>, /* ovr1 */
 		      <0x0 0x04a08000 0x0 0x1000>, /* ovr2 */
 		      <0x0 0x04a0a000 0x0 0x1000>, /* vp1 */
-		      <0x0 0x04a0b000 0x0 0x1000>; /* vp2 */
+		      <0x0 0x04a0b000 0x0 0x1000>, /* vp2 */
+		      <0x0 0x04a01000 0x0 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			"ovr1", "ovr2", "vp1", "vp2";
+			"ovr1", "ovr2", "vp1", "vp2", "common1";
 
 		ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
 
-- 
2.34.1



From devarsht at ti.com  Thu Feb 15 22:24:23 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Fri, 16 Feb 2024 11:54:23 +0530
Subject: [PATCH v5 1/4] dt-bindings: display: ti,am65x-dss: Add support for common1 region
In-Reply-To: <20240216062426.4170528-1-devarsht@ti.com>
References: <20240216062426.4170528-1-devarsht@ti.com>
Message-ID: <20240216062426.4170528-2-devarsht@ti.com>

TI keystone display subsystem present in AM65, AM62 and AM62A SoC support
two separate register spaces namely "common" and "common1" which can be
used by two separate hosts to program the display controller as described
in respective Technical Reference Manuals [1].

The common1 register space has similar set of configuration registers as
supported in common register space except the global configuration
registers which are exclusive to common region.

This adds binding for "common1" register region too as supported by the
hardware.

[1]:
AM62x TRM:
https://www.ti.com/lit/pdf/spruiv7 (Section 14.8.9.1 DSS Registers)

AM65x TRM:
https://www.ti.com/lit/pdf/spruid7 (Section 12.6.5 DSS Registers)

AM62A TRM:
https://www.ti.com/lit/pdf/spruj16 (Section 14.9.9 Display Subsystem Registers)

Fixes: 2d8730f1021f ("dt-bindings: display: ti,am65x-dss: Add dt-schema yaml binding")
Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
Reviewed-by: Aradhya Bhatia <a-bhatia1 at ti.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
V2: Add Acked-by tag
V3: Add Fixes tag
V4: Add Reviewed-by and AM62A TRM link
V5: No change
---
 .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
index b6767ef0d24d..55e3e490d0e6 100644
--- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
+++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
@@ -37,6 +37,7 @@ properties:
       - description: OVR2 overlay manager for vp2
       - description: VP1 video port 1
       - description: VP2 video port 2
+      - description: common1 DSS register area
 
   reg-names:
     items:
@@ -47,6 +48,7 @@ properties:
       - const: ovr2
       - const: vp1
       - const: vp2
+      - const: common1
 
   clocks:
     items:
@@ -147,9 +149,10 @@ examples:
                     <0x04a07000 0x1000>, /* ovr1 */
                     <0x04a08000 0x1000>, /* ovr2 */
                     <0x04a0a000 0x1000>, /* vp1 */
-                    <0x04a0b000 0x1000>; /* vp2 */
+                    <0x04a0b000 0x1000>, /* vp2 */
+                    <0x04a01000 0x1000>; /* common1 */
             reg-names = "common", "vidl1", "vid",
-                    "ovr1", "ovr2", "vp1", "vp2";
+                    "ovr1", "ovr2", "vp1", "vp2", "common1";
             ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
             power-domains = <&k3_pds 67 TI_SCI_PD_EXCLUSIVE>;
             clocks =        <&k3_clks 67 1>,
-- 
2.34.1



From devarsht at ti.com  Thu Feb 15 22:24:25 2024
From: devarsht at ti.com (Devarsh Thakkar)
Date: Fri, 16 Feb 2024 11:54:25 +0530
Subject: [PATCH v5 3/4] arm64: dts: ti: Add common1 register space for AM62x SoC
In-Reply-To: <20240216062426.4170528-1-devarsht@ti.com>
References: <20240216062426.4170528-1-devarsht@ti.com>
Message-ID: <20240216062426.4170528-4-devarsht@ti.com>

This adds common1 register space for AM62x SoC which is using TI's Keystone
display hardware and supporting it as described in
Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml

Fixes: 8ccc1073c7bb ("arm64: dts: ti: k3-am62-main: Add node for DSS")
Signed-off-by: Devarsh Thakkar <devarsht at ti.com>
---
V1->V4 :
- No change (this was part of "arm64: dts: ti: Add common1 register
  space for AM62x, AM62A & AM65x SoCs )

V5 :
- Split this as a separate patch from "arm64: dts: ti: Add common1
  register space for AM62x, AM62A & AM65x SoCs"
- Remove Reviewed-By tag as patch is split now
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index fe0cc4a9a501..8cee4d94cdd3 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -779,9 +779,10 @@ dss: dss at 30200000 {
 		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
 		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
 		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
-		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			    "ovr1", "ovr2", "vp1", "vp2";
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
 		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 186 6>,
 			 <&dss_vp1_clk>,
-- 
2.34.1



From vigneshr at ti.com  Thu Feb 15 22:30:59 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Fri, 16 Feb 2024 12:00:59 +0530
Subject: [PATCH v3 0/7] arm64: dts: iot2050: Add support for new SM variant
In-Reply-To: <cover.1707463401.git.jan.kiszka@siemens.com>
References: <cover.1707463401.git.jan.kiszka@siemens.com>
Message-ID: <170806504067.3877215.4593036714741774948.b4-ty@ti.com>

Hi Jan Kiszka,

On Fri, 09 Feb 2024 08:23:14 +0100, Jan Kiszka wrote:
> Changes in v3:
>  - rebased
> 
> Changes in v2:
>  - LED improvements
>  - factor out DP and USB3 dtsi files
>  - fix subject of last patch
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/7] dt-bindings: arm: ti: Add binding for Siemens IOT2050 SM variant
      commit: 2a99c7792a0cf4f1df1362f43f319af509c05bd8
[2/7] arm64: dts: ti: iot2050: Disable R5 lockstep for all PG2 boards
      commit: 93abe383bfd35357b3319a2430afb7826324337d
[3/7] arm64: dts: ti: iot2050: Factor out arduino connector bits
      commit: 1ef134a43213360aeef8f5508b5760bf0cf73280
[4/7] arm64: dts: ti: iot2050: Factor out enabling of USB3 support
      commit: f1a024f76db0167987fb9b53d4ae5483c118ead7
[5/7] arm64: dts: ti: iot2050: Factor out DP related bits
      commit: f2c6d71e4728528b031d6e93b97a5c21018efa70
[6/7] arm64: dts: ti: iot2050: Annotate LED nodes
      commit: 5adf911c7067d3d76d85cc33fd60e201ce43d89d
[7/7] arm64: dts: ti: iot2050: Support IOT2050-SM variant
      commit: 8829fe97f1b505acd63f25e4f36bc90957b24c29

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Thu Feb 15 22:31:29 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Fri, 16 Feb 2024 12:01:29 +0530
Subject: [PATCH v2 0/3] arm64: dts: ti: Introduce J722S SoC and EVM
In-Reply-To: <20240206100608.127702-1-vaishnav.a@ti.com>
References: <20240206100608.127702-1-vaishnav.a@ti.com>
Message-ID: <170806504068.3877215.8092202742138440785.b4-ty@ti.com>

Hi Vaishnav Achath,

On Tue, 06 Feb 2024 15:36:05 +0530, Vaishnav Achath wrote:
> This series adds basic support for J722S family of SoCs. Also add
> J722S EVM support with basic peripheral like MMC and UART.
> 
> TRM: https://www.ti.com/lit/zip/sprujb3
> EVM Schematics: https://www.ti.com/lit/zip/sprr495
> 
> Bootlog (6.8.0-rc3-next-20240206):
> https://gist.github.com/vaishnavachath/23d859925277df9ccd628190e7c23371
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/3] dt-bindings: arm: ti: Add bindings for J722S SoCs
      commit: de82585f62e08283572d385d0cd6b57893a99d1c
[2/3] arm64: dts: ti: Introduce J722S family of SoCs
      commit: ea55b9335ad81e32f2833c71b2dcb591792e54dd
[3/3] arm64: dts: ti: Add support for TI J722S Evaluation Module
      commit: 2f277dbe1a4ac40b1157ba3b2914d39f4040bbed

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From Mihai.Sain at microchip.com  Thu Feb 15 22:58:10 2024
From: Mihai.Sain at microchip.com (Mihai.Sain at microchip.com)
Date: Fri, 16 Feb 2024 06:58:10 +0000
Subject: [PATCH v3 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <20240215-lustily-flick-69cb48b123c3@spud>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
 <20240215091524.14732-3-mihai.sain@microchip.com>
 <20240215-lustily-flick-69cb48b123c3@spud>
Message-ID: <PH8PR11MB6804E9353A8EEBD2B829D8B3824C2@PH8PR11MB6804.namprd11.prod.outlook.com>

> diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> index 269e0a3ca269..c030b318985a 100644
> --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
> +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> @@ -958,6 +958,30 @@ i2c9: i2c at 600 {
>  			};
>  		};
>  
> +		flx10: flexcom at e2820000 {
> +			compatible = "atmel,sama5d2-flexcom";

My comment here was ignored:
https://lore.kernel.org/all/20240214-robe-pregnancy-a1b056c9fe14 at spud/

The SAMA7G5 has the same flexcom controller as SAMA5D2 MPU.

https://github.com/torvalds/linux/blob/master/drivers/mfd/atmel-flexcom.c#L83
https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt#L8

From s-vadapalli at ti.com  Thu Feb 15 22:59:26 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Fri, 16 Feb 2024 12:29:26 +0530
Subject: [PATCH] MAINTAINERS: PCI: TI DRA7XX/J721E: Add Siddharth Vadapalli as a reviewer
Message-ID: <20240216065926.473805-1-s-vadapalli@ti.com>

Since I have been contributing to the driver for a while and wish to help
with the review process, add myself as a reviewer.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index cd7980e5b1ad..7d6a60002fc1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16976,6 +16976,7 @@ F:	drivers/pci/controller/dwc/*designware*
 
 PCI DRIVER FOR TI DRA7XX/J721E
 M:	Vignesh Raghavendra <vigneshr at ti.com>
+R:	Siddharth Vadapalli <s-vadapalli at ti.com>
 L:	linux-omap at vger.kernel.org
 L:	linux-pci at vger.kernel.org
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
-- 
2.34.1



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:44 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:44 +0000
Subject: [PATCH v3 01/12] spi: dt-bindings: introduce FIFO depth properties
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-2-tudor.ambarus@linaro.org>

There are SPI IPs that can be configured by the integrator with a
specific FIFO depth depending on the system's capabilities. For example,
the samsung USI SPI IP can be configured by the integrator with a TX/RX
FIFO from 8 byte to 256 bytes.

Introduce the ``fifo-depth`` property for such instances of IPs where the
same FIFO depth is used for both RX and TX. Introduce ``rx-fifo-depth``
and ``tx-fifo-depth`` properties for cases where the RX FIFO depth is
different from the TX FIFO depth.

Make the dedicated RX/TX properties dependent on each other and mutual
exclusive with the other.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 .../bindings/spi/spi-controller.yaml          | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml
index 524f6fe8c27b..093150c0cb87 100644
--- a/Documentation/devicetree/bindings/spi/spi-controller.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml
@@ -69,6 +69,21 @@ properties:
          Should be generally avoided and be replaced by
          spi-cs-high + ACTIVE_HIGH.
 
+  fifo-depth:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Size of the RX and TX data FIFOs in bytes.
+
+  rx-fifo-depth:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Size of the RX data FIFO in bytes.
+
+  tx-fifo-depth:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Size of the TX data FIFO in bytes.
+
   num-cs:
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
@@ -116,6 +131,10 @@ patternProperties:
       - compatible
       - reg
 
+dependencies:
+  rx-fifo-depth: [ tx-fifo-depth ]
+  tx-fifo-depth: [ rx-fifo-depth ]
+
 allOf:
   - if:
       not:
@@ -129,6 +148,14 @@ allOf:
       properties:
         "#address-cells":
           const: 0
+  - not:
+      required:
+        - fifo-depth
+        - rx-fifo-depth
+  - not:
+      required:
+        - fifo-depth
+        - tx-fifo-depth
 
 additionalProperties: true
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:43 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:43 +0000
Subject: [PATCH v3 00/12] spi: s3c64xx: remove OF alias ID dependency
Message-ID: <20240216070555.2483977-1-tudor.ambarus@linaro.org>

The driver was wrong as it assumed that the alias values in devicetree
have a particular meaning in identifying instances. This immediately
breaks when there is a dtb file that does not use the same alias values,
e.g. because it only needs some of the SPI ports.

Tested gs101 SPI with spi-loopback-test, all went fine. I updated
exynos850 as it uses the same USI.SPI_VERSION as gs101. Maybe Sam can
test exynos850, if not, we can drop that patch (12/12).

v3:
- fix indentation in dt-bindings
- collect Rob's R-b

v2:
- update bindings to consider the asymmetric case where the RX FIFO
  depth can differ from the TX FIFO depth
- update commit message in patch 11/12 to describe the GS101 change
  (I was wrongly mentioning exynos 850). 

Tudor Ambarus (12):
  spi: dt-bindings: introduce FIFO depth properties
  spi: s3c64xx: define a magic value
  spi: s3c64xx: allow full FIFO masks
  spi: s3c64xx: determine the fifo depth only once
  spi: s3c64xx: retrieve the FIFO depth from the device tree
  spi: s3c64xx: allow FIFO depth to be determined from the compatible
  spi: s3c64xx: let the SPI core determine the bus number
  spi: s3c64xx: introduce s3c64xx_spi_set_port_id()
  spi: s3c64xx: get rid of the OF alias ID dependency
  spi: s3c64xx: deprecate fifo_lvl_mask, rx_lvl_offset and port_id
  spi: s3c64xx: switch gs101 to new port config data
  spi: s3c64xx: switch exynos850 to new port config data

 .../bindings/spi/spi-controller.yaml          |  27 ++++
 drivers/spi/spi-s3c64xx.c                     | 142 ++++++++++++++----
 2 files changed, 138 insertions(+), 31 deletions(-)

-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:46 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:46 +0000
Subject: [PATCH v3 03/12] spi: s3c64xx: allow full FIFO masks
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-4-tudor.ambarus@linaro.org>

The driver is wrong because is using partial register field masks for the
SPI_STATUS.{RX, TX}_FIFO_LVL register fields.

We see s3c64xx_spi_port_config.fifo_lvl_mask with different values for
different instances of the same IP. Take s5pv210_spi_port_config for
example, it defines:
	.fifo_lvl_mask  = { 0x1ff, 0x7F },

fifo_lvl_mask is used to determine the FIFO depth of the instance of the
IP. In this case, the integrator uses a 256 bytes FIFO for the first SPI
instance of the IP, and a 64 bytes FIFO for the second instance. While
the first mask reflects the SPI_STATUS.{RX, TX}_FIFO_LVL register
fields, the second one is two bits short. Using partial field masks is
misleading and can hide problems of the driver's logic.

Allow platforms to specify the full FIFO mask, regardless of the FIFO
depth.

Introduce {rx, tx}_fifomask to represent the SPI_STATUS.{RX, TX}_FIFO_LVL
register fields. It's a shifted mask defining the field's length and
position. We'll be able to deprecate the use of @rx_lvl_offset, as the
shift value can be determined from the mask. The existing compatibles
shall start using {rx, tx}_fifomask so that they use the full field mask
and to avoid shifting the mask to position, and then shifting it back to
zero in the {TX, RX}_FIFO_LVL macros.

@rx_lvl_offset will be deprecated in a further patch, after we have the
infrastructure to deprecate @fifo_lvl_mask as well.

No functional change intended.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 40 +++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 6ff3b25b6feb..338ca3f03ea5 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -3,6 +3,7 @@
 // Copyright (c) 2009 Samsung Electronics Co., Ltd.
 //      Jaswinder Singh <jassi.brar at samsung.com>
 
+#include <linux/bitops.h>
 #include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
@@ -109,10 +110,10 @@
 #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
 #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \
 				(1 << (i)->port_conf->tx_st_done)) ? 1 : 0)
-#define TX_FIFO_LVL(v, i) (((v) >> S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT) &	\
-			   FIFO_LVL_MASK(i))
-#define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \
-					FIFO_LVL_MASK(i))
+#define TX_FIFO_LVL(v, sdd)	(((v) & (sdd)->tx_fifomask) >>		\
+				 __ffs((sdd)->tx_fifomask))
+#define RX_FIFO_LVL(v, sdd)	(((v) & (sdd)->rx_fifomask) >>		\
+				 __ffs((sdd)->rx_fifomask))
 #define FIFO_DEPTH(i) ((FIFO_LVL_MASK(i) >> 1) + 1)
 
 #define S3C64XX_SPI_MAX_TRAILCNT	0x3ff
@@ -136,6 +137,10 @@ struct s3c64xx_spi_dma_data {
  * struct s3c64xx_spi_port_config - SPI Controller hardware info
  * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
  * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
+ * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
+ * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
  * @tx_st_done: Bit offset of TX_DONE bit in SPI_STATUS regiter.
  * @clk_div: Internal clock divider
  * @quirks: Bitmask of known quirks
@@ -154,6 +159,8 @@ struct s3c64xx_spi_dma_data {
 struct s3c64xx_spi_port_config {
 	int	fifo_lvl_mask[MAX_SPI_PORTS];
 	int	rx_lvl_offset;
+	u32	rx_fifomask;
+	u32	tx_fifomask;
 	int	tx_st_done;
 	int	quirks;
 	int	clk_div;
@@ -184,6 +191,10 @@ struct s3c64xx_spi_port_config {
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
  * @port_conf: Local SPI port configuration data
  * @port_id: Port identification number
+ * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
+ * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
+ *               length and position.
  */
 struct s3c64xx_spi_driver_data {
 	void __iomem                    *regs;
@@ -203,6 +214,8 @@ struct s3c64xx_spi_driver_data {
 	struct s3c64xx_spi_dma_data	tx_dma;
 	const struct s3c64xx_spi_port_config	*port_conf;
 	unsigned int			port_id;
+	u32				rx_fifomask;
+	u32				tx_fifomask;
 };
 
 static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd)
@@ -1183,6 +1196,23 @@ static inline const struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
 	return (const struct s3c64xx_spi_port_config *)platform_get_device_id(pdev)->driver_data;
 }
 
+static void s3c64xx_spi_set_fifomask(struct s3c64xx_spi_driver_data *sdd)
+{
+	const struct s3c64xx_spi_port_config *port_conf = sdd->port_conf;
+
+	if (port_conf->rx_fifomask)
+		sdd->rx_fifomask = port_conf->rx_fifomask;
+	else
+		sdd->rx_fifomask = FIFO_LVL_MASK(sdd) <<
+			port_conf->rx_lvl_offset;
+
+	if (port_conf->tx_fifomask)
+		sdd->tx_fifomask = port_conf->tx_fifomask;
+	else
+		sdd->tx_fifomask = FIFO_LVL_MASK(sdd) <<
+			S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT;
+}
+
 static int s3c64xx_spi_probe(struct platform_device *pdev)
 {
 	struct resource	*mem_res;
@@ -1231,6 +1261,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
+	s3c64xx_spi_set_fifomask(sdd);
+
 	sdd->cur_bpw = 8;
 
 	sdd->tx_dma.direction = DMA_MEM_TO_DEV;
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:45 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:45 +0000
Subject: [PATCH v3 02/12] spi: s3c64xx: define a magic value
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-3-tudor.ambarus@linaro.org>

Define a magic value, it will be used in the next patch as well.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 6f29dca68491..6ff3b25b6feb 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -78,6 +78,7 @@
 #define S3C64XX_SPI_INT_RX_FIFORDY_EN		(1<<1)
 #define S3C64XX_SPI_INT_TX_FIFORDY_EN		(1<<0)
 
+#define S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT	6
 #define S3C64XX_SPI_ST_RX_OVERRUN_ERR		(1<<5)
 #define S3C64XX_SPI_ST_RX_UNDERRUN_ERR		(1<<4)
 #define S3C64XX_SPI_ST_TX_OVERRUN_ERR		(1<<3)
@@ -108,7 +109,8 @@
 #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
 #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \
 				(1 << (i)->port_conf->tx_st_done)) ? 1 : 0)
-#define TX_FIFO_LVL(v, i) (((v) >> 6) & FIFO_LVL_MASK(i))
+#define TX_FIFO_LVL(v, i) (((v) >> S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT) &	\
+			   FIFO_LVL_MASK(i))
 #define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \
 					FIFO_LVL_MASK(i))
 #define FIFO_DEPTH(i) ((FIFO_LVL_MASK(i) >> 1) + 1)
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:47 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:47 +0000
Subject: [PATCH v3 04/12] spi: s3c64xx: determine the fifo depth only once
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-5-tudor.ambarus@linaro.org>

Determine the FIFO depth only once, at probe time.
``sdd->fifo_depth`` can be set later on with the FIFO depth
specified in the device tree.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 338ca3f03ea5..72572e23cde5 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -191,6 +191,7 @@ struct s3c64xx_spi_port_config {
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
  * @port_conf: Local SPI port configuration data
  * @port_id: Port identification number
+ * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
  * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
@@ -214,6 +215,7 @@ struct s3c64xx_spi_driver_data {
 	struct s3c64xx_spi_dma_data	tx_dma;
 	const struct s3c64xx_spi_port_config	*port_conf;
 	unsigned int			port_id;
+	unsigned int			fifo_depth;
 	u32				rx_fifomask;
 	u32				tx_fifomask;
 };
@@ -424,7 +426,7 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
 	struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
 
 	if (sdd->rx_dma.ch && sdd->tx_dma.ch)
-		return xfer->len > FIFO_DEPTH(sdd);
+		return xfer->len > sdd->fifo_depth;
 
 	return false;
 }
@@ -548,7 +550,7 @@ static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,
 	void __iomem *regs = sdd->regs;
 	unsigned long val = 1;
 	u32 status;
-	u32 max_fifo = FIFO_DEPTH(sdd);
+	u32 max_fifo = sdd->fifo_depth;
 
 	if (timeout_ms)
 		val = msecs_to_loops(timeout_ms);
@@ -655,7 +657,7 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
 	 * For any size less than the fifo size the below code is
 	 * executed atleast once.
 	 */
-	loops = xfer->len / FIFO_DEPTH(sdd);
+	loops = xfer->len / sdd->fifo_depth;
 	buf = xfer->rx_buf;
 	do {
 		/* wait for data to be received in the fifo */
@@ -792,7 +794,7 @@ static int s3c64xx_spi_transfer_one(struct spi_controller *host,
 				    struct spi_transfer *xfer)
 {
 	struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host);
-	const unsigned int fifo_len = FIFO_DEPTH(sdd);
+	const unsigned int fifo_len = sdd->fifo_depth;
 	const void *tx_buf = NULL;
 	void *rx_buf = NULL;
 	int target_len = 0, origin_len = 0;
@@ -1261,6 +1263,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
+	sdd->fifo_depth = FIFO_DEPTH(sdd);
+
 	s3c64xx_spi_set_fifomask(sdd);
 
 	sdd->cur_bpw = 8;
@@ -1352,7 +1356,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Targets attached\n",
 					sdd->port_id, host->num_chipselect);
 	dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\n",
-					mem_res, FIFO_DEPTH(sdd));
+		mem_res, sdd->fifo_depth);
 
 	pm_runtime_mark_last_busy(&pdev->dev);
 	pm_runtime_put_autosuspend(&pdev->dev);
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:48 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:48 +0000
Subject: [PATCH v3 05/12] spi: s3c64xx: retrieve the FIFO depth from the device tree
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-6-tudor.ambarus@linaro.org>

There are SoCs that configure different FIFO depths for their instances
of the SPI IP. See the fifo_lvl_mask defined for exynos4_spi_port_config
for example:
        .fifo_lvl_mask  = { 0x1ff, 0x7F, 0x7F },
The first instance of the IP is configured with 256 bytes FIFOs, whereas
the last two are configured with 64 bytes FIFOs.

Instead of mangling with the .fifo_lvl_mask and its dependency of the DT
alias ID, allow such SoCs to determine the FIFO depth via the
``fifo-depth`` DT property.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 72572e23cde5..b1c63f75021d 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1263,7 +1263,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
-	sdd->fifo_depth = FIFO_DEPTH(sdd);
+	if (of_property_read_u32(pdev->dev.of_node, "fifo-depth",
+				 &sdd->fifo_depth))
+		sdd->fifo_depth = FIFO_DEPTH(sdd);
 
 	s3c64xx_spi_set_fifomask(sdd);
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:50 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:50 +0000
Subject: [PATCH v3 07/12] spi: s3c64xx: let the SPI core determine the bus number
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-8-tudor.ambarus@linaro.org>

Let the core determine the bus number, either by getting the alias ID
(as the driver forces now), or by allocating a dynamic bus number when
the alias is absent. Prepare the driver to allow dt aliases to be
absent.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 68f95c04d092..ac47755beb02 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1279,7 +1279,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	sdd->rx_dma.direction = DMA_DEV_TO_MEM;
 
 	host->dev.of_node = pdev->dev.of_node;
-	host->bus_num = sdd->port_id;
+	host->bus_num = -1;
 	host->setup = s3c64xx_spi_setup;
 	host->cleanup = s3c64xx_spi_cleanup;
 	host->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
@@ -1360,7 +1360,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	}
 
 	dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Targets attached\n",
-					sdd->port_id, host->num_chipselect);
+		host->bus_num, host->num_chipselect);
 	dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\n",
 		mem_res, sdd->fifo_depth);
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:49 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:49 +0000
Subject: [PATCH v3 06/12] spi: s3c64xx: allow FIFO depth to be determined from the compatible
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-7-tudor.ambarus@linaro.org>

There are SoCs that use the same FIFO depth for all the instances of the
SPI IP. See the fifo_lvl_mask defined for gs101 for example:
    .fifo_lvl_mask  = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
                        0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},

Instead of specifying the FIFO depth with the same value for all 16
nodes in this case, allow such SoCs to infer the FIFO depth from the
compatible. There are other SoCs than can benefit of this, see:
{gs101, fsd, exynos850, s3c641, s3c2443}_spi_port_config.

The FIFO depth inferred from the compatible has a higher precedence than
the one that might be specified via device tree, the driver shall know
better.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index b1c63f75021d..68f95c04d092 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -137,6 +137,7 @@ struct s3c64xx_spi_dma_data {
  * struct s3c64xx_spi_port_config - SPI Controller hardware info
  * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
  * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
+ * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
  * @tx_fifomask: SPI_STATUS.TX_FIFO_LVL mask. Shifted mask defining the field's
@@ -159,6 +160,7 @@ struct s3c64xx_spi_dma_data {
 struct s3c64xx_spi_port_config {
 	int	fifo_lvl_mask[MAX_SPI_PORTS];
 	int	rx_lvl_offset;
+	unsigned int fifo_depth;
 	u32	rx_fifomask;
 	u32	tx_fifomask;
 	int	tx_st_done;
@@ -1263,8 +1265,10 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 		sdd->port_id = pdev->id;
 	}
 
-	if (of_property_read_u32(pdev->dev.of_node, "fifo-depth",
-				 &sdd->fifo_depth))
+	if (sdd->port_conf->fifo_depth)
+		sdd->fifo_depth = sdd->port_conf->fifo_depth;
+	else if (of_property_read_u32(pdev->dev.of_node, "fifo-depth",
+				      &sdd->fifo_depth))
 		sdd->fifo_depth = FIFO_DEPTH(sdd);
 
 	s3c64xx_spi_set_fifomask(sdd);
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:51 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:51 +0000
Subject: [PATCH v3 08/12] spi: s3c64xx: introduce s3c64xx_spi_set_port_id()
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-9-tudor.ambarus@linaro.org>

Prepare driver to get rid of the of alias ID dependency. Split the
port_id logic into a dedicated method.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index ac47755beb02..40de325bd094 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1200,6 +1200,27 @@ static inline const struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
 	return (const struct s3c64xx_spi_port_config *)platform_get_device_id(pdev)->driver_data;
 }
 
+static int s3c64xx_spi_set_port_id(struct platform_device *pdev,
+				   struct s3c64xx_spi_driver_data *sdd)
+{
+	int ret;
+
+	if (pdev->dev.of_node) {
+		ret = of_alias_get_id(pdev->dev.of_node, "spi");
+		if (ret < 0)
+			return dev_err_probe(&pdev->dev, ret,
+					     "Failed to get alias id\n");
+		sdd->port_id = ret;
+	} else {
+		if (pdev->id < 0)
+			return dev_err_probe(&pdev->dev, -EINVAL,
+					     "Negative platform ID is not allowed\n");
+		sdd->port_id = pdev->id;
+	}
+
+	return 0;
+}
+
 static void s3c64xx_spi_set_fifomask(struct s3c64xx_spi_driver_data *sdd)
 {
 	const struct s3c64xx_spi_port_config *port_conf = sdd->port_conf;
@@ -1252,18 +1273,10 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	sdd->host = host;
 	sdd->cntrlr_info = sci;
 	sdd->pdev = pdev;
-	if (pdev->dev.of_node) {
-		ret = of_alias_get_id(pdev->dev.of_node, "spi");
-		if (ret < 0)
-			return dev_err_probe(&pdev->dev, ret,
-					     "Failed to get alias id\n");
-		sdd->port_id = ret;
-	} else {
-		if (pdev->id < 0)
-			return dev_err_probe(&pdev->dev, -EINVAL,
-					     "Negative platform ID is not allowed\n");
-		sdd->port_id = pdev->id;
-	}
+
+	ret = s3c64xx_spi_set_port_id(pdev, sdd);
+	if (ret)
+		return ret;
 
 	if (sdd->port_conf->fifo_depth)
 		sdd->fifo_depth = sdd->port_conf->fifo_depth;
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:52 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:52 +0000
Subject: [PATCH v3 09/12] spi: s3c64xx: get rid of the OF alias ID dependency
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-10-tudor.ambarus@linaro.org>

Compatibles that set ``port_conf->{rx, tx}_fifomask`` are now safe to
get rid of the OF alias ID dependency. Let the driver probe even without
the alias for these.

With this we also protect the FIFO_LVL_MASK calls from
s3c64xx_spi_set_fifomask().

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 40de325bd094..d2d1c9767145 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1203,8 +1203,12 @@ static inline const struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
 static int s3c64xx_spi_set_port_id(struct platform_device *pdev,
 				   struct s3c64xx_spi_driver_data *sdd)
 {
+	const struct s3c64xx_spi_port_config *port_conf = sdd->port_conf;
 	int ret;
 
+	if (port_conf->rx_fifomask && port_conf->tx_fifomask)
+		return 0;
+
 	if (pdev->dev.of_node) {
 		ret = of_alias_get_id(pdev->dev.of_node, "spi");
 		if (ret < 0)
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:53 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:53 +0000
Subject: [PATCH v3 10/12] spi: s3c64xx: deprecate fifo_lvl_mask, rx_lvl_offset and port_id
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-11-tudor.ambarus@linaro.org>

Deprecate fifo_lvl_mask, rx_lvl_offset and port_id. One shall use
{rx, tx}_fifomask instead. Add messages to each port configuration.

Suggested-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index d2d1c9767145..128f4a7c4bd9 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -135,8 +135,8 @@ struct s3c64xx_spi_dma_data {
 
 /**
  * struct s3c64xx_spi_port_config - SPI Controller hardware info
- * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
- * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
+ * @fifo_lvl_mask: [DEPRECATED] use @{rx, tx}_fifomask instead.
+ * @rx_lvl_offset: [DEPRECATED] use @{rx,tx}_fifomask instead.
  * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
@@ -192,7 +192,7 @@ struct s3c64xx_spi_port_config {
  * @rx_dma: Local receive DMA data (e.g. chan and direction)
  * @tx_dma: Local transmit DMA data (e.g. chan and direction)
  * @port_conf: Local SPI port configuration data
- * @port_id: Port identification number
+ * @port_id: [DEPRECATED] use @{rx,tx}_fifomask instead.
  * @fifo_depth: depth of the FIFO.
  * @rx_fifomask: SPI_STATUS.RX_FIFO_LVL mask. Shifted mask defining the field's
  *               length and position.
@@ -1508,7 +1508,9 @@ static const struct dev_pm_ops s3c64xx_spi_pm = {
 };
 
 static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 13,
 	.tx_st_done	= 21,
 	.clk_div	= 2,
@@ -1516,14 +1518,18 @@ static const struct s3c64xx_spi_port_config s3c2443_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config s3c6410_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7F },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 13,
 	.tx_st_done	= 21,
 	.clk_div	= 2,
 };
 
 static const struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7F },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1531,7 +1537,9 @@ static const struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos4_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7F, 0x7F },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1541,7 +1549,9 @@ static const struct s3c64xx_spi_port_config exynos4_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos7_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7F, 0x7F, 0x7F, 0x7F, 0x1ff},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1551,7 +1561,9 @@ static const struct s3c64xx_spi_port_config exynos7_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1562,7 +1574,9 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos850_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f },
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
@@ -1573,8 +1587,10 @@ static const struct s3c64xx_spi_port_config exynos850_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynosautov9_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x1ff, 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff, 0x7f,
 			    0x7f, 0x7f, 0x7f, 0x7f},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
@@ -1586,7 +1602,9 @@ static const struct s3c64xx_spi_port_config exynosautov9_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 2,
@@ -1597,8 +1615,10 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
+	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
 	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
 			    0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
 	.rx_lvl_offset	= 15,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:54 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:54 +0000
Subject: [PATCH v3 11/12] spi: s3c64xx: switch gs101 to new port config data
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-12-tudor.ambarus@linaro.org>

Drop the fifo_lvl_mask and rx_lvl_offset and switch to the new port
config data.

Advantages of the change:
- drop dependency on the OF alias ID.
- FIFO depth is inferred from the compatible. GS101 integrates 16 SPI
  IPs, all with 64 bytes FIFO depths.
- use full mask for SPI_STATUS.{RX, TX}_FIFO_LVL fields. Using partial
  masks is misleading and can hide problems of the driver logic.

S3C64XX_SPI_ST_TX_FIFO_RDY_V2 was defined based on the USI's
SPI_VERSION.USI_IP_VERSION register field, which has value 2 at reset.

MAX_SPI_PORTS is updated to reflect the maximum number of ports for the
rest of the compatibles.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 128f4a7c4bd9..784786407d2e 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -20,7 +20,7 @@
 #include <linux/spi/spi.h>
 #include <linux/types.h>
 
-#define MAX_SPI_PORTS		16
+#define MAX_SPI_PORTS		12
 #define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1)
 #define AUTOSUSPEND_TIMEOUT	2000
 
@@ -79,6 +79,8 @@
 #define S3C64XX_SPI_INT_RX_FIFORDY_EN		(1<<1)
 #define S3C64XX_SPI_INT_TX_FIFORDY_EN		(1<<0)
 
+#define S3C64XX_SPI_ST_RX_FIFO_RDY_V2		GENMASK(23, 15)
+#define S3C64XX_SPI_ST_TX_FIFO_RDY_V2		GENMASK(14, 6)
 #define S3C64XX_SPI_ST_TX_FIFO_LVL_SHIFT	6
 #define S3C64XX_SPI_ST_RX_OVERRUN_ERR		(1<<5)
 #define S3C64XX_SPI_ST_RX_UNDERRUN_ERR		(1<<4)
@@ -1615,11 +1617,9 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
-	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
-	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-			    0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
-	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
-	.rx_lvl_offset	= 15,
+	.fifo_depth	= 64,
+	.rx_fifomask	= S3C64XX_SPI_ST_RX_FIFO_RDY_V2,
+	.tx_fifomask	= S3C64XX_SPI_ST_TX_FIFO_RDY_V2,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
 	.high_speed	= true,
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Thu Feb 15 23:05:55 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 07:05:55 +0000
Subject: [PATCH v3 12/12] spi: s3c64xx: switch exynos850 to new port config data
In-Reply-To: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
Message-ID: <20240216070555.2483977-13-tudor.ambarus@linaro.org>

Exynos850 has the same version of USI SPI (v2.1) as GS101.
Drop the fifo_lvl_mask and rx_lvl_offset and switch to the new port
config data.

Backward compatibility with DT is not broken because when alises are
set:
- the SPI core will set the bus number according to the alias ID
- the FIFO depth is always the same size for exynos850 (64 bytes) no
  matter the alias ID number.

Advantages of the change:
- drop dependency on the OF alias ID.
- FIFO depth is inferred from the compatible. Exynos850 integrates 3 SPI
  IPs, all with 64 bytes FIFO depths.
- use full mask for SPI_STATUS.{RX, TX}_FIFO_LVL fields. Using partial
  masks is misleading and can hide problems of the driver logic.

Just compiled tested.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 784786407d2e..9fcbe040cb2f 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1576,10 +1576,9 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
 };
 
 static const struct s3c64xx_spi_port_config exynos850_spi_port_config = {
-	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
-	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f },
-	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
-	.rx_lvl_offset	= 15,
+	.fifo_depth	= 64,
+	.rx_fifomask	= S3C64XX_SPI_ST_RX_FIFO_RDY_V2,
+	.tx_fifomask	= S3C64XX_SPI_ST_TX_FIFO_RDY_V2,
 	.tx_st_done	= 25,
 	.clk_div	= 4,
 	.high_speed	= true,
-- 
2.44.0.rc0.258.g7320e95886-goog



From alexander.stein at ew.tq-group.com  Thu Feb 15 23:07:31 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 16 Feb 2024 08:07:31 +0100
Subject: [PATCH v13 4/7] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <5bd01470cf971e2385ecd169c3d5ac659a020973.1707040881.git.Sandor.yu@nxp.com>
References: <cover.1707040881.git.Sandor.yu@nxp.com> <5bd01470cf971e2385ecd169c3d5ac659a020973.1707040881.git.Sandor.yu@nxp.com>
Message-ID: <3549548.iIbC2pHGDl@steina-w>

Hi Sandor,

thanks for the update.

Am Sonntag, 4. Februar 2024, 11:21:49 CET schrieb Sandor Yu:
> Add a new DRM DisplayPort and HDMI bridge driver for Candence MHDP8501
> used in i.MX8MQ SOC. MHDP8501 could support HDMI or DisplayPort
> standards according embedded Firmware running in the uCPU.
> 
> For iMX8MQ SOC, the DisplayPort/HDMI FW was loaded and activated by
> SOC's ROM code. Bootload binary included respective specific firmware
> is required.
> 
> Driver will check display connector type and
> then load the corresponding driver.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> ---
> v12->v13:
> - Explicitly include linux/platform_device.h for cdns-mhdp8501-core.c
> - Fix build warning
> - Order bit bpc and color_space in descending shit.
> 
> v11->v12:
> - Replace DRM_INFO with dev_info or dev_warn.
> - Replace DRM_ERROR with dev_err.
> - Return ret when cdns_mhdp_dpcd_read failed in function
> cdns_dp_aux_transferi(). - Remove unused parmeter in function
> cdns_dp_get_msa_misc
>   and use two separate variables for color space and bpc.
> - Add year 2024 to copyright.
> 
>  drivers/gpu/drm/bridge/cadence/Kconfig        |  16 +
>  drivers/gpu/drm/bridge/cadence/Makefile       |   2 +
>  .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 316 ++++++++
>  .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 365 +++++++++
>  .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 699 ++++++++++++++++++
>  .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 679 +++++++++++++++++
>  6 files changed, 2077 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> 
> [snip]
> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c new file mode 100644
> index 0000000000000..0117cddb85694
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> @@ -0,0 +1,699 @@
> [snip]
> +
> +const struct drm_bridge_funcs cdns_dp_bridge_funcs = {
> +	.attach = cdns_dp_bridge_attach,
> +	.detect = cdns_dp_bridge_detect,
> +	.get_edid = cdns_dp_bridge_get_edid,

Please note that with commits d807ad80d811b ("drm/bridge: add ->edid_read hook 
and drm_bridge_edid_read()") and 27b8f91c08d99 ("drm/bridge: remove ->get_edid 
callback") the API has slightly changed meanwhile.

> +	.mode_valid = cdns_dp_bridge_mode_valid,
> +	.atomic_enable = cdns_dp_bridge_atomic_enable,
> +	.atomic_disable = cdns_dp_bridge_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,
> +};
> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c new file mode 100644
> index 0000000000000..e6ed13b9f9ca3
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> @@ -0,0 +1,679 @@
> [snip]
> +
> +const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
> +	.attach = cdns_hdmi_bridge_attach,
> +	.detect = cdns_hdmi_bridge_detect,
> +	.get_edid = cdns_hdmi_bridge_get_edid,

Please note that with commits d807ad80d811b ("drm/bridge: add ->edid_read hook 
and drm_bridge_edid_read()") and 27b8f91c08d99 ("drm/bridge: remove ->get_edid 
callback") the API has slightly changed meanwhile.

> +	.mode_valid = cdns_hdmi_bridge_mode_valid,
> +	.mode_fixup = cdns_hdmi_bridge_mode_fixup,
> +	.atomic_enable = cdns_hdmi_bridge_atomic_enable,
> +	.atomic_disable = cdns_hdmi_bridge_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,
> +};

Please rebase your patch series, thanks.

Best regards,
Alexander
-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From krzysztof.kozlowski at linaro.org  Thu Feb 15 23:12:29 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 08:12:29 +0100
Subject: [PATCH] clk: constify the of_phandle_args argument of
 of_clk_provider
In-Reply-To: <38e7e80f61f7c67c984735cf55c3dfb3.sboyd@kernel.org>
References: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
 <38e7e80f61f7c67c984735cf55c3dfb3.sboyd@kernel.org>
Message-ID: <02461595-16b3-4fea-a029-54190e10e6f5@linaro.org>

On 16/02/2024 00:12, Stephen Boyd wrote:
> Quoting Krzysztof Kozlowski (2024-02-08 08:37:10)
>> None of the implementations of the get() and get_hw() callbacks of
>> "struct of_clk_provider" modify the contents of received of_phandle_args
>> pointer.  They treat it as read-only variable used to find the clock to
>> return.  Make obvious that implementations are not supposed to modify
>> the of_phandle_args, by making it a pointer to const.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>> ---
> 
> This will almost certainly break the build once it is merged to
> linux-next. What's your plan to merge this?

First problem is that it might not apply... I prepared it on next to be
sure all subsystems are updated.

The idea is to get reviews and acks and then:
1. Maybe it applies cleanly to your tree meaning there will be no
conflicts with other trees,
2. If not, then I can keep rebasing it and it should be applied after rc1.



Best regards,
Krzysztof



From thomas.richard at bootlin.com  Thu Feb 15 23:36:41 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Fri, 16 Feb 2024 08:36:41 +0100
Subject: [PATCH v3 14/18] phy: cadence-torrent: add suspend and resume
 support
In-Reply-To: <Zc4x7kvFfBI2sb_E@smile.fi.intel.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-14-5c2e4a3fac1f@bootlin.com>
 <Zc4x7kvFfBI2sb_E@smile.fi.intel.com>
Message-ID: <e009fda0-3dd1-4834-8dce-73756c1e32f6@bootlin.com>

On 2/15/24 16:46, Andy Shevchenko wrote:
>> +static int cdns_torrent_phy_suspend_noirq(struct device *dev)
>> +{
>> +	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
>> +	int i;
> 
> Why signed?

In the for loop below, the i variable is compared to
cdns_phy->nsubnodes, which is an int.

https://elixir.bootlin.com/linux/latest/source/drivers/phy/cadence/phy-cadence-torrent.c#L360

> 
>> +	reset_control_assert(cdns_phy->phy_rst);
>> +	reset_control_assert(cdns_phy->apb_rst);
>> +	for (i = 0; i < cdns_phy->nsubnodes; i++)
>> +		reset_control_assert(cdns_phy->phys[i].lnk_rst);
>> +
>> +	if (cdns_phy->already_configured)
>> +		cdns_phy->already_configured = 0;
>> +	else
>> +		clk_disable_unprepare(cdns_phy->clk);
>> +
>> +	return 0;
>> +}
>> +
>> +static int cdns_torrent_phy_resume_noirq(struct device *dev)
>> +{
>> +	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
>> +	int node = cdns_phy->nsubnodes;
>> +	int ret, i;
> 
> Ditto>

Same reason

>> +	ret = cdns_torrent_clk(cdns_phy);
>> +	if (ret)
>> +		goto clk_cleanup;
>> +
>> +	/* Enable APB */
>> +	reset_control_deassert(cdns_phy->apb_rst);
>> +
>> +	if (cdns_phy->nsubnodes > 1) {
>> +		ret = cdns_torrent_phy_configure_multilink(cdns_phy);
>> +		if (ret)
>> +			goto put_lnk_rst;
>> +	}
>> +
>> +	return 0;
>> +
>> +put_lnk_rst:
>> +	for (i = 0; i < node; i++)
>> +		reset_control_assert(cdns_phy->phys[i].lnk_rst);
>> +	reset_control_assert(cdns_phy->apb_rst);
>> +	clk_disable_unprepare(cdns_phy->clk);
>> +clk_cleanup:
>> +	cdns_torrent_clk_cleanup(cdns_phy);
>> +	return ret;
>> +}
> 
-- 
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From krzysztof.kozlowski at linaro.org  Thu Feb 15 23:41:50 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 08:41:50 +0100
Subject: [PATCH 03/13] dt-bindings: hwmon: lm75: add label property
In-Reply-To: <20240215-mbly-i2c-v1-3-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-3-19a336e91dca@bootlin.com>
Message-ID: <3e541dd7-90d8-43d1-a5b5-260828ac2a86@linaro.org>

On 15/02/2024 17:52, Th?o Lebrun wrote:
> Declare optional label devicetree property. Show usage in one example
> with dummy name.
> 
> To: Jean Delvare <jdelvare at suse.com>
> To: Guenter Roeck <linux at roeck-us.net>
> Cc: <linux-hwmon at vger.kernel.org>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From lkp at intel.com  Thu Feb 15 23:41:17 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 16 Feb 2024 15:41:17 +0800
Subject: [PATCH v2 01/12] spi: dt-bindings: introduce FIFO depth
 properties
In-Reply-To: <20240212140331.915498-2-tudor.ambarus@linaro.org>
References: <20240212140331.915498-2-tudor.ambarus@linaro.org>
Message-ID: <202402161543.5JdIODY4-lkp@intel.com>

Hi Tudor,

kernel test robot noticed the following build warnings:

[auto build test WARNING on broonie-spi/for-next]
[also build test WARNING on robh/for-next linus/master v6.8-rc4 next-20240216]
[cannot apply to krzk/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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Tudor-Ambarus/spi-dt-bindings-introduce-FIFO-depth-properties/20240212-221427
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
patch link:    https://lore.kernel.org/r/20240212140331.915498-2-tudor.ambarus%40linaro.org
patch subject: [PATCH v2 01/12] spi: dt-bindings: introduce FIFO depth properties
compiler: loongarch64-linux-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20240216/202402161543.5JdIODY4-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402161543.5JdIODY4-lkp at intel.com/

dtcheck warnings: (new ones prefixed by >>)
>> Documentation/devicetree/bindings/spi/spi-controller.yaml:152:9: [warning] wrong indentation: expected 6 but found 8 (indentation)
   Documentation/devicetree/bindings/spi/spi-controller.yaml:156:9: [warning] wrong indentation: expected 6 but found 8 (indentation)

vim +152 Documentation/devicetree/bindings/spi/spi-controller.yaml

     8	
     9	maintainers:
    10	  - Mark Brown <broonie at kernel.org>
    11	
    12	description: |
    13	  SPI busses can be described with a node for the SPI controller device
    14	  and a set of child nodes for each SPI slave on the bus. The system SPI
    15	  controller may be described for use in SPI master mode or in SPI slave mode,
    16	  but not for both at the same time.
    17	
    18	properties:
    19	  $nodename:
    20	    pattern: "^spi(@.*|-([0-9]|[1-9][0-9]+))?$"
    21	
    22	  "#address-cells":
    23	    enum: [0, 1]
    24	
    25	  "#size-cells":
    26	    const: 0
    27	
    28	  cs-gpios:
    29	    description: |
    30	      GPIOs used as chip selects.
    31	      If that property is used, the number of chip selects will be
    32	      increased automatically with max(cs-gpios, hardware chip selects).
    33	
    34	      So if, for example, the controller has 4 CS lines, and the
    35	      cs-gpios looks like this
    36	        cs-gpios = <&gpio1 0 0>, <0>, <&gpio1 1 0>, <&gpio1 2 0>;
    37	
    38	      Then it should be configured so that num_chipselect = 4, with
    39	      the following mapping
    40	        cs0 : &gpio1 0 0
    41	        cs1 : native
    42	        cs2 : &gpio1 1 0
    43	        cs3 : &gpio1 2 0
    44	
    45	      The second flag of a gpio descriptor can be GPIO_ACTIVE_HIGH (0)
    46	      or GPIO_ACTIVE_LOW(1). Legacy device trees often use 0.
    47	
    48	      There is a special rule set for combining the second flag of an
    49	      cs-gpio with the optional spi-cs-high flag for SPI slaves.
    50	
    51	      Each table entry defines how the CS pin is to be physically
    52	      driven (not considering potential gpio inversions by pinmux):
    53	
    54	      device node     | cs-gpio       | CS pin state active | Note
    55	      ================+===============+=====================+=====
    56	      spi-cs-high     | -             | H                   |
    57	      -               | -             | L                   |
    58	      spi-cs-high     | ACTIVE_HIGH   | H                   |
    59	      -               | ACTIVE_HIGH   | L                   | 1
    60	      spi-cs-high     | ACTIVE_LOW    | H                   | 2
    61	      -               | ACTIVE_LOW    | L                   |
    62	
    63	      Notes:
    64	      1) Should print a warning about polarity inversion.
    65	         Here it would be wise to avoid and define the gpio as
    66	         ACTIVE_LOW.
    67	      2) Should print a warning about polarity inversion
    68	         because ACTIVE_LOW is overridden by spi-cs-high.
    69	         Should be generally avoided and be replaced by
    70	         spi-cs-high + ACTIVE_HIGH.
    71	
    72	  fifo-depth:
    73	    $ref: /schemas/types.yaml#/definitions/uint32
    74	    description:
    75	      Size of the RX and TX data FIFOs in bytes.
    76	
    77	  rx-fifo-depth:
    78	    $ref: /schemas/types.yaml#/definitions/uint32
    79	    description:
    80	      Size of the RX data FIFO in bytes.
    81	
    82	  tx-fifo-depth:
    83	    $ref: /schemas/types.yaml#/definitions/uint32
    84	    description:
    85	      Size of the TX data FIFO in bytes.
    86	
    87	  num-cs:
    88	    $ref: /schemas/types.yaml#/definitions/uint32
    89	    description:
    90	      Total number of chip selects.
    91	
    92	  spi-slave:
    93	    $ref: /schemas/types.yaml#/definitions/flag
    94	    description:
    95	      The SPI controller acts as a slave, instead of a master.
    96	
    97	  slave:
    98	    type: object
    99	
   100	    properties:
   101	      compatible:
   102	        description:
   103	          Compatible of the SPI device.
   104	
   105	    required:
   106	      - compatible
   107	
   108	patternProperties:
   109	  "^.*@[0-9a-f]+$":
   110	    type: object
   111	    $ref: spi-peripheral-props.yaml
   112	    additionalProperties: true
   113	
   114	    properties:
   115	      spi-3wire:
   116	        $ref: /schemas/types.yaml#/definitions/flag
   117	        description:
   118	          The device requires 3-wire mode.
   119	
   120	      spi-cpha:
   121	        $ref: /schemas/types.yaml#/definitions/flag
   122	        description:
   123	          The device requires shifted clock phase (CPHA) mode.
   124	
   125	      spi-cpol:
   126	        $ref: /schemas/types.yaml#/definitions/flag
   127	        description:
   128	          The device requires inverse clock polarity (CPOL) mode.
   129	
   130	    required:
   131	      - compatible
   132	      - reg
   133	
   134	dependencies:
   135	  rx-fifo-depth: [ tx-fifo-depth ]
   136	  tx-fifo-depth: [ rx-fifo-depth ]
   137	
   138	allOf:
   139	  - if:
   140	      not:
   141	        required:
   142	          - spi-slave
   143	    then:
   144	      properties:
   145	        "#address-cells":
   146	          const: 1
   147	    else:
   148	      properties:
   149	        "#address-cells":
   150	          const: 0
   151	  - not:
 > 152	        required:
   153	          - fifo-depth
   154	          - rx-fifo-depth
   155	  - not:
   156	        required:
   157	          - fifo-depth
   158	          - tx-fifo-depth
   159	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From ddrokosov at salutedevices.com  Thu Feb 15 23:47:16 2024
From: ddrokosov at salutedevices.com (Dmitry Rokosov)
Date: Fri, 16 Feb 2024 10:47:16 +0300
Subject: [DMARC error][DKIM error] [PATCH 0/5] soc: amlogic: add new
 meson-gx-socinfo-sm driver
In-Reply-To: <20231122125643.1717160-1-adeep@lexina.in>
References: <20231122125643.1717160-1-adeep@lexina.in>
Message-ID: <20240216074716.a33hrvl5xnpm7aep@CAB-WSD-L081021>

Hello Neil,

May I put in my two cents on this patch series?

There appears to be a misunderstanding regarding the terminology used.
Allow me to clarify my perspective.

The original Amlogic chipid has the following format:

    4 bytes      12 bytes
    +-------+-------------------+
    |       |                   |
    | CPUID | SOC SERIAL NUMBER |
    |       |                   |
    +-------+-------------------+
    0                          15


In the current uboot [1] and kernel [2] upstream, only the SOC SERIAL
NUMBER bytes are read from efuse OTP storage (and it isn't swapped, as
Amlogic reference code does [3]). We refer to these bytes as "serial".

The original chipid value is utilized in several algorithms (for
example, in the Amlogic boot protocols), making it crucial to have the
ability to read the original chipid value as intended by the vendor.

In my opinion, we should align our naming terminology as follows:
    - "chipid" - Represents the complete Amlogic SoC ID, includes
                 "cpuid" and "serial"
    - "serial" - 12 byte unique SoC number, identifying particular die

We strongly believe that this patch series is essential and are highly interested in seeing it applied to the upstream linux-amlogic, for the following reasons:
    - We use chipid for device identification in our boards
    - The Amlogic boot protocols utilize the full version of chipid
      (ADNL, Optimus). As I mentioned in the IRC, we are preparing a
      patch series for uboot incorporating them.
    - in OPTEE: for generation of SSK (Secure Storage Key) [4]
    - RPMB: for generation of RPMB key, further provisioned into RPMB
      controller (thus particular SoC is bound to particular eMMC

Therefore, I propose that we rename "soc_id" in the Viacheslav patch
series to "chipid" and subsequently port this patch series to uboot.

What are your thoughts on this matter?

Links:
[1] - https://elixir.bootlin.com/u-boot/v2024.01/source/arch/arm/mach-meson/sm.c#L84
[2] - https://elixir.bootlin.com/linux/v6.7.4/source/drivers/firmware/meson/meson_sm.c#L268
[3] - https://github.com/CoreELEC/u-boot/blob/3efc85a8370796bcec3bcadcdecec9aed973f4a9/arch/arm/mach-meson/g12a/bl31_apis.c#L398-L417
[4] - https://github.com/OP-TEE/optee_os/blob/5df2a985b2ffd0b6f1107f12ca2a88203bf31328/core/tee/tee_fs_key_manager.c#L152

On Wed, Nov 22, 2023 at 03:56:38PM +0300, Viacheslav Bocharov wrote:
> The Amlogic Meson SoC Secure Monitor implements a call to retrieve an
> unique SoC ID starting from the GX Family and all new families.
> But GX-family chips (e.g. GXB, GXL and newer) supports also 128-bit
> chip ID. 128-bit chip ID consists 32-bit SoC version and 96-bit OTP data.
> 
> This is the second attempt to publish data from the Amlogic secure monitor
> chipid call. After discussions with Neil Armstrong, it was decided to
> publish the chipid call results through the soc driver. Since
> soc_device_match cannot wait for the soc driver to load, and the secure
> monitor calls in turn depend on the sm driver, it was necessary to create
> a new driver rather than expand an existing one.
> 
> In the patches, in addition to writing the driver:
> - convert commonly used structures and functions of the meson-gx-socinfo
> driver to a header file.
> - transfer the chipid sm call constants to a header file (perhaps they
> need renaming?).
> - add secure-monitor references for amlogic,meson-gx-ao-secure sections
> in dts files of the a1, axg, g12, gx families.
> 
> Viacheslav Bocharov (5):
>   soc: amlogic: meson-gx-socinfo: move common code to header file
>   soc: amlogic: meson-gx-socinfo: move common code to exported function
>   firmware: meson_sm: move common definitions to header file
>   soc: amlogic: Add Amlogic secure-monitor SoC Information driver
>   arm64: dts: meson: add dts links to secure-monitor for soc driver in
>     a1, axg, gx, g12
> 
>  arch/arm64/boot/dts/amlogic/meson-a1.dtsi     |   1 +
>  arch/arm64/boot/dts/amlogic/meson-axg.dtsi    |   1 +
>  .../boot/dts/amlogic/meson-g12-common.dtsi    |   1 +
>  arch/arm64/boot/dts/amlogic/meson-gx.dtsi     |   1 +
>  drivers/firmware/meson/meson_sm.c             |   4 -
>  drivers/soc/amlogic/Kconfig                   |  10 +
>  drivers/soc/amlogic/Makefile                  |   1 +
>  .../soc/amlogic/meson-gx-socinfo-internal.h   | 102 ++++++++++
>  drivers/soc/amlogic/meson-gx-socinfo-sm.c     | 178 ++++++++++++++++++
>  drivers/soc/amlogic/meson-gx-socinfo.c        | 106 ++---------
>  include/linux/firmware/meson/meson_sm.h       |   4 +
>  11 files changed, 317 insertions(+), 92 deletions(-)
>  create mode 100644 drivers/soc/amlogic/meson-gx-socinfo-internal.h
>  create mode 100644 drivers/soc/amlogic/meson-gx-socinfo-sm.c
> 
> -- 
> 2.34.1
> 
> 
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic

-- 
Thank you,
Dmitry


From thomas.richard at bootlin.com  Thu Feb 15 23:52:17 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Fri, 16 Feb 2024 08:52:17 +0100
Subject: [PATCH v3 05/18] mux: add mux_chip_resume() function
In-Reply-To: <Zc4t82V9czlEqamL@smile.fi.intel.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-5-5c2e4a3fac1f@bootlin.com>
 <Zc4t82V9czlEqamL@smile.fi.intel.com>
Message-ID: <f1d2c9b0-238d-4b09-8212-62e00a2192b2@bootlin.com>

On 2/15/24 16:29, Andy Shevchenko wrote:
> On Thu, Feb 15, 2024 at 04:17:50PM +0100, Thomas Richard wrote:
>> The mux_chip_resume() function restores a mux_chip using the cached state
>> of each mux.
> 
> ...
> 
>> +int mux_chip_resume(struct mux_chip *mux_chip)
>> +{
>> +	int global_ret = 0;
>> +	int ret, i;
>> +
>> +	for (i = 0; i < mux_chip->controllers; ++i) {
>> +		struct mux_control *mux = &mux_chip->mux[i];
>> +
>> +		if (mux->cached_state == MUX_CACHE_UNKNOWN)
>> +			continue;
>> +
>> +		ret = mux_control_set(mux, mux->cached_state);
>> +		if (ret < 0) {
>> +			dev_err(&mux_chip->dev, "unable to restore state\n");
>> +			if (!global_ret)
>> +				global_ret = ret;
> 
> Hmm... This will record the first error and continue.

In the v2 we talked about this with Peter Rosin.

In fact, in the v1 (mux_chip_resume() didn't exists yet, everything was
done in the mmio driver) I had the same behavior: try to restore all
muxes and in case of error restore the first one.

I don't know what is the right solution. I just restored the behavior I
had in v1.

> 
>> +		}
>> +	}
>> +	return global_ret;
> 
> So here, we actually will get stale data in case there are > 1 failures.

Yes, indeed. But we will have an error message for each failure.

> 
>> +}
> 
-- 
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From angelogioacchino.delregno at collabora.com  Thu Feb 15 23:56:08 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 16 Feb 2024 08:56:08 +0100
Subject: [PATCH 6/9] media: platform: mtk-mdp3: drop calling
 cmdq_pkt_finalize()
In-Reply-To: <af4bfdd52f0ca022730aedcb456bb1a0b105ae3e.camel@mediatek.com>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
 <20240215004931.3808-7-chunkuang.hu@kernel.org>
 <4dcfaf49-aaac-4980-a149-02fec3109f31@collabora.com>
 <af4bfdd52f0ca022730aedcb456bb1a0b105ae3e.camel@mediatek.com>
Message-ID: <b3c384b6-7c8f-4428-a62e-1036b78217cf@collabora.com>

Il 16/02/24 07:20, Moudy Ho (???) ha scritto:
> On Thu, 2024-02-15 at 11:29 +0100, AngeloGioacchino Del Regno wrote:
>> Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
>>> Because client driver has the information of struct cmdq_client, so
>>> it's not necessary to store struct cmdq_client in struct cmdq_pkt.
>>> cmdq_pkt_finalize() use struct cmdq_client in struct cmdq_pkt, so
>>> it's
>>> going to be abandoned. Therefore, use cmdq_pkt_eoc() and
>>> cmdq_pkt_nop()
>>> to replace cmdq_pkt_finalize().
>>
>> No, it's not because cmdq_pkt_finalize() has cmdq_client, but because
>> we want
>> finer grain control over the CMDQ packets, as not all cases require
>> the NOP
>> packet to be appended after EOC.
>>
>> Besides, honestly I'm not even sure if the NOP is always required in
>> MDP3, so...
>>
>> ...Moudy, you know the MDP3 way better than anyone else - can you
>> please
>> check if NOP is actually needed here?
>>
>> Thanks!
>> Angelo
>>
> 
> Hi Angelo,
> 
> After confirming with the hardware designer and performing the video
> playback test, it was discovered that MDP3 is capable of excluding the
> NOP(jump) instruction.
> 

Thank you for this extremely fast clarification.

Cheers,
Angelo

> Sincerely,
> Moudy
>>>
>>> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
>>> ---
>>>    drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 3 ++-
>>>    drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c | 2 ++
>>>    drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h | 1 +
>>>    3 files changed, 5 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
>>> b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
>>> index 6adac857a477..a420d492d879 100644
>>> --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
>>> +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
>>> @@ -471,7 +471,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct
>>> mdp_cmdq_param *param)
>>>    		dev_err(dev, "mdp_path_config error\n");
>>>    		goto err_free_path;
>>>    	}
>>> -	cmdq_pkt_finalize(&cmd->pkt);
>>> +	cmdq_pkt_eoc(&cmd->pkt);
>>> +	cmdq_pkt_nop(&cmd->pkt, mdp->cmdq_shift_pa);
>>>    
>>>    	for (i = 0; i < num_comp; i++)
>>>    		memcpy(&comps[i], path->comps[i].comp,
>>> diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
>>> b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
>>> index 94f4ed78523b..2214744c937c 100644
>>> --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
>>> +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
>>> @@ -231,6 +231,8 @@ static int mdp_probe(struct platform_device
>>> *pdev)
>>>    		goto err_put_scp;
>>>    	}
>>>    
>>> +	mdp->cmdq_shift_pa = cmdq_get_shift_pa(mdp->cmdq_clt->chan);
>>> +
>>>    	init_waitqueue_head(&mdp->callback_wq);
>>>    	ida_init(&mdp->mdp_ida);
>>>    	platform_set_drvdata(pdev, mdp);
>>> diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
>>> b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
>>> index 7e21d226ceb8..ed61e0bb69ee 100644
>>> --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
>>> +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
>>> @@ -83,6 +83,7 @@ struct mdp_dev {
>>>    	u32					id_count;
>>>    	struct ida				mdp_ida;
>>>    	struct cmdq_client			*cmdq_clt;
>>> +	u8					cmdq_shift_pa;
>>>    	wait_queue_head_t			callback_wq;
>>>    
>>>    	struct v4l2_device			v4l2_dev;
>>
>>





From alexandre.belloni at bootlin.com  Thu Feb 15 23:56:09 2024
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Fri, 16 Feb 2024 08:56:09 +0100
Subject: [PATCH v3 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <PH8PR11MB6804E9353A8EEBD2B829D8B3824C2@PH8PR11MB6804.namprd11.prod.outlook.com>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
 <20240215091524.14732-3-mihai.sain@microchip.com>
 <20240215-lustily-flick-69cb48b123c3@spud>
 <PH8PR11MB6804E9353A8EEBD2B829D8B3824C2@PH8PR11MB6804.namprd11.prod.outlook.com>
Message-ID: <20240216075609e58aeee4@mail.local>

On 16/02/2024 06:58:10+0000, Mihai.Sain at microchip.com wrote:
> > diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> > index 269e0a3ca269..c030b318985a 100644
> > --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
> > +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> > @@ -958,6 +958,30 @@ i2c9: i2c at 600 {
> >  			};
> >  		};
> >  
> > +		flx10: flexcom at e2820000 {
> > +			compatible = "atmel,sama5d2-flexcom";
> 
> My comment here was ignored:
> https://lore.kernel.org/all/20240214-robe-pregnancy-a1b056c9fe14 at spud/
> 
> The SAMA7G5 has the same flexcom controller as SAMA5D2 MPU.
> 

Still, it needs its own compatible plus a fallback to
atmel,sama5d2-flexcom

> https://github.com/torvalds/linux/blob/master/drivers/mfd/atmel-flexcom.c#L83
> https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt#L8

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From krzysztof.kozlowski at linaro.org  Thu Feb 15 23:59:11 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 08:59:11 +0100
Subject: [PATCH 12/13] MIPS: mobileye: eyeq5: add evaluation board I2C
 temp sensor
In-Reply-To: <20240215-mbly-i2c-v1-12-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-12-19a336e91dca@bootlin.com>
Message-ID: <42b16256-0dcb-4065-bdd1-a27b33f169e2@linaro.org>

On 15/02/2024 17:52, Th?o Lebrun wrote:
> Declare the temperature sensor on I2C bus 2. Its label is the schematics
> identifier.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  arch/mips/boot/dts/mobileye/eyeq5-epm5.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts b/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
> index 6898b2d8267d..1f8549acd40d 100644
> --- a/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
> +++ b/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
> @@ -21,3 +21,11 @@ memory at 0 {
>  		      <0x8 0x02000000 0x0 0x7E000000>;
>  	};
>  };
> +
> +&i2c2 {
> +	tmp112 at 48 {

Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation


temperature-sensor, power-sensor etc.

Best regards,
Krzysztof



From thomas.richard at bootlin.com  Thu Feb 15 23:59:47 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Fri, 16 Feb 2024 08:59:47 +0100
Subject: [PATCH v3 02/18] pinctrl: pinctrl-single: remove dead code in
 suspend() and resume() callbacks
In-Reply-To: <Zc4tedAhqYX3bQcw@smile.fi.intel.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-2-5c2e4a3fac1f@bootlin.com>
 <Zc4tedAhqYX3bQcw@smile.fi.intel.com>
Message-ID: <78add459-a96a-46c6-83ff-e2657d4d3db4@bootlin.com>

On 2/15/24 16:27, Andy Shevchenko wrote:
> On Thu, Feb 15, 2024 at 04:17:47PM +0100, Thomas Richard wrote:
>> No need to check the pointer returned by platform_get_drvdata(), as
>> platform_set_drvdata() is called during the probe.
> 
> This patch should go _after_ the next one, otherwise the commit message doesn't
> tell full story and the code change bring a potential regression.
> 

Hello Andy,

I'm ok to move this patch after the next one.
But for my understanding, could you explain me why changing the order is
important in this case ?

Regards,

-- 
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From krzysztof.kozlowski at linaro.org  Thu Feb 15 23:59:59 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 08:59:59 +0100
Subject: [PATCH 13/13] MIPS: mobileye: eyeq5: add resets to I2C
 controllers
In-Reply-To: <20240215-mbly-i2c-v1-13-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-13-19a336e91dca@bootlin.com>
Message-ID: <42b7e3bb-a152-4ded-91f3-fb8043a7f413@linaro.org>

On 15/02/2024 17:52, Th?o Lebrun wrote:
> Add resets properties to each I2C controller. This depends on the
> reset-eyeq5 platform reset controller driver.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---

This should be squashed with previous patch adding i2c controllers.
Don't add incomplete nodes just to fix them in next patch.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb 16 00:00:43 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 09:00:43 +0100
Subject: [PATCH 03/13] dt-bindings: hwmon: lm75: add label property
In-Reply-To: <3e541dd7-90d8-43d1-a5b5-260828ac2a86@linaro.org>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-3-19a336e91dca@bootlin.com>
 <3e541dd7-90d8-43d1-a5b5-260828ac2a86@linaro.org>
Message-ID: <ebd2be9f-fbad-4295-b74d-35647d08ee76@linaro.org>

On 16/02/2024 08:41, Krzysztof Kozlowski wrote:
> On 15/02/2024 17:52, Th?o Lebrun wrote:
>> Declare optional label devicetree property. Show usage in one example
>> with dummy name.
>>
>> To: Jean Delvare <jdelvare at suse.com>
>> To: Guenter Roeck <linux at roeck-us.net>
>> Cc: <linux-hwmon at vger.kernel.org>
>> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
>> ---
> 
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 

Although you might need to re-work this patch if this gets accepted:

https://lore.kernel.org/linux-devicetree/20240216-dt-bindings-hwmon-common-v1-0-3c2c24ff1260 at linaro.org/T/#m341d8f47ca5badd2637cd662fb331f144e16a54c

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb 16 00:03:49 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 09:03:49 +0100
Subject: [PATCH 1/2] media: dt-bindings: media: Add bindings for IMX283
In-Reply-To: <20240215204436.9194-2-umang.jain@ideasonboard.com>
References: <20240215204436.9194-1-umang.jain@ideasonboard.com>
 <20240215204436.9194-2-umang.jain@ideasonboard.com>
Message-ID: <55d41858-b567-4e23-8d84-3af81b52d018@linaro.org>

On 15/02/2024 21:44, Umang Jain wrote:
> - Add dt-bindings documentation for Sony IMX283 sensor driver
> - Add MAINTAINERS entry for Sony IMX283 binding documentation
> 
> Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
> ---

Due to lack of testing limited review.

>  .../bindings/media/i2c/sony,imx283.yaml       | 100 ++++++++++++++++++
>  MAINTAINERS                                   |   8 ++
>  2 files changed, 108 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
> new file mode 100644
> index 000000000000..3cf46429b282
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
> @@ -0,0 +1,100 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (C) 2024 Ideas on Board Oy
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/i2c/sony,imx283.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Sony IMX283 Sensor
> +
> +maintainers:
> +  - Kieran Bingham <kieran.bingham at ideasonboard.com>
> +  - Umang Jain <umang.jain at ideasonboard.com>
> +
> +description:
> +  IMX283 sensor is a Sony CMOS active pixel digital image sensor with an active
> +  array size of 5472H x 3648V. It is programmable through I2C interface. The
> +  I2C client address is fixed to 0x1a as per sensor data sheet. Image data is
> +  sent through MIPI CSI-2.
> +
> +properties:
> +  compatible:
> +    const: sony,imx283

Blank line

> +  reg:
> +    description: I2C address

Drop description

> +    maxItems: 1
> +
> +  assigned-clocks: true
> +  assigned-clock-parents: true
> +  assigned-clock-rates: true

Drop all three, not really needed, just mention them in example.

> +
> +  clocks:
> +    description: Clock frequency from 6 to 24 MHz.
> +    maxItems: 1
> +
> +  vana-supply:
> +    description: Analog power supply (2.9V)
> +
> +  vdig-supply:
> +    description: Interface power supply (1.8V)
> +
> +  vddl-supply:
> +    description: Digital power supply (1.2V)
> +
> +  port:
> +    additionalProperties: false
> +    $ref: /schemas/graph.yaml#/$defs/port-base

Please reverse above lines, first ref, then additionalprops.

> +
> +    properties:
> +      endpoint:
> +        $ref: /schemas/media/video-interfaces.yaml#
> +        unevaluatedProperties: false

Ditto

> +
> +        properties:
> +          data-lanes: true

Provide constraints - which lanes/how many.

> +          link-frequencies: true
> +
> +        required:
> +          - data-lanes
> +          - link-frequencies
> +
> +    required:
> +      - endpoint
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - port
> +
> +additionalProperties: false
> +

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb 16 00:07:00 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 09:07:00 +0100
Subject: [PATCH 2/2] media: i2c: Add imx283 camera sensor driver
In-Reply-To: <20240215204436.9194-3-umang.jain@ideasonboard.com>
References: <20240215204436.9194-1-umang.jain@ideasonboard.com>
 <20240215204436.9194-3-umang.jain@ideasonboard.com>
Message-ID: <668dafa8-b537-4fd1-94c6-d1bda732c410@linaro.org>

On 15/02/2024 21:44, Umang Jain wrote:
> From: Kieran Bingham <kieran.bingham at ideasonboard.com>
> 
> Add a v4l2 subdevice driver for the Sony IMX283 image sensor.
> 
> The IMX283 is a 20MP Diagonal 15.86 mm (Type 1) CMOS Image Sensor with
> Square Pixel for Color Cameras.
> 

...

> +
> +static int imx283_power_off(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct imx283 *imx283 = to_imx283(sd);
> +
> +	gpiod_set_value_cansleep(imx283->reset_gpio, 0);

That's odd. It is reset GPIO, so 0 means deassert means "stop resetting
device". You have wrong handling of the GPIO.

> +	regulator_bulk_disable(ARRAY_SIZE(imx283_supply_name), imx283->supplies);
> +	clk_disable_unprepare(imx283->xclk);
> +
> +	return 0;
> +}
> +
> +static int imx283_get_regulators(struct imx283 *imx283)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(imx283_supply_name); i++)
> +		imx283->supplies[i].supply = imx283_supply_name[i];
> +
> +	return devm_regulator_bulk_get(imx283->dev,
> +				       ARRAY_SIZE(imx283_supply_name),
> +				       imx283->supplies);
> +}

...

> +static const struct of_device_id imx283_dt_ids[] = {
> +	{ .compatible = "sony,imx283", },
> +	{ /* sentinel */ }
> +};

This goes next to driver structure. You also miss module device table.

> +
> +static int imx283_parse_endpoint(struct imx283 *imx283)
> +{
> +	struct fwnode_handle *fwnode = dev_fwnode(imx283->dev);
> +	struct v4l2_fwnode_endpoint bus_cfg = {
> +		.bus_type = V4L2_MBUS_CSI2_DPHY
> +	};
> +	struct fwnode_handle *ep;
> +	int ret;
> +
> +	if (!fwnode)
> +		return -ENXIO;
> +
> +	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> +	if (!ep) {
> +		dev_err(imx283->dev, "Failed to get next endpoint\n");
> +		return -ENXIO;
> +	}
> +
> +	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> +	fwnode_handle_put(ep);
> +	if (ret)
> +		return ret;
> +
> +	if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
> +		dev_err(imx283->dev,
> +			"number of CSI2 data lanes %d is not supported\n",
> +			bus_cfg.bus.mipi_csi2.num_data_lanes);
> +		ret = -EINVAL;
> +		goto done_endpoint_free;
> +	}
> +
> +	ret = v4l2_link_freq_to_bitmap(imx283->dev, bus_cfg.link_frequencies,
> +				       bus_cfg.nr_of_link_frequencies,
> +				       link_frequencies, ARRAY_SIZE(link_frequencies),
> +				       &imx283->link_freq_bitmap);
> +
> +done_endpoint_free:
> +	v4l2_fwnode_endpoint_free(&bus_cfg);
> +
> +	return ret;
> +};
> +
> +static int imx283_probe(struct i2c_client *client)
> +{
> +	struct imx283 *imx283;
> +	int ret;
> +	unsigned int i;
> +	unsigned int xclk_freq;
> +
> +	imx283 = devm_kzalloc(&client->dev, sizeof(*imx283), GFP_KERNEL);
> +	if (!imx283)
> +		return -ENOMEM;
> +
> +	imx283->dev = &client->dev;
> +
> +	v4l2_i2c_subdev_init(&imx283->sd, client, &imx283_subdev_ops);
> +
> +	imx283->cci = devm_cci_regmap_init_i2c(client, 16);
> +	if (IS_ERR(imx283->cci)) {
> +		ret = PTR_ERR(imx283->cci);
> +		dev_err(imx283->dev, "failed to initialize CCI: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* Get system clock (xclk) */
> +	imx283->xclk = devm_clk_get(imx283->dev, NULL);
> +	if (IS_ERR(imx283->xclk)) {
> +		dev_err(imx283->dev, "failed to get xclk\n");

Syntax is: return dev_err_probe()

> +		return PTR_ERR(imx283->xclk);
> +	}
> +
> +	xclk_freq = clk_get_rate(imx283->xclk);
> +	for (i = 0; i < ARRAY_SIZE(imx283_frequencies); i++) {
> +		if (xclk_freq == imx283_frequencies[i].mhz) {
> +			imx283->freq = &imx283_frequencies[i];
> +			break;
> +		}
> +	}
> +	if (!imx283->freq) {
> +		dev_err(imx283->dev, "xclk frequency unsupported: %d Hz\n", xclk_freq);
> +		return -EINVAL;
> +	}
> +
> +	ret = imx283_get_regulators(imx283);
> +	if (ret) {
> +		dev_err(imx283->dev, "failed to get regulators\n");
> +		return ret;

return dev_err_probe()

> +	}
> +
> +	ret = imx283_parse_endpoint(imx283);
> +	if (ret) {
> +		dev_err(imx283->dev, "failed to parse endpoint configuration\n");
> +		return ret;
> +	}
> +
> +	/* Request optional enable pin */
> +	imx283->reset_gpio = devm_gpiod_get_optional(imx283->dev, "reset",
> +						     GPIOD_OUT_HIGH);

No, that's not allowed in your binding. Don't add undocumented properties.

> +
> +	mutex_init(&imx283->mutex);
> +
> +	/*
> +	 * The sensor must be powered for imx283_identify_module()
> +	 * to be able to read the CHIP_ID register
> +	 */
> +	ret = imx283_power_on(imx283->dev);
> +	if (ret)
> +		return ret;
> +


Best regards,
Krzysztof



From claudiu.beznea at tuxon.dev  Fri Feb 16 00:24:13 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Fri, 16 Feb 2024 10:24:13 +0200
Subject: [PATCH v3 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <20240216075609e58aeee4@mail.local>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
 <20240215091524.14732-3-mihai.sain@microchip.com>
 <20240215-lustily-flick-69cb48b123c3@spud>
 <PH8PR11MB6804E9353A8EEBD2B829D8B3824C2@PH8PR11MB6804.namprd11.prod.outlook.com>
 <20240216075609e58aeee4@mail.local>
Message-ID: <cfafd563-1387-4775-bcb0-434ce3774827@tuxon.dev>



On 16.02.2024 09:56, Alexandre Belloni wrote:
> On 16/02/2024 06:58:10+0000, Mihai.Sain at microchip.com wrote:
>>> diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
>>> index 269e0a3ca269..c030b318985a 100644
>>> --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
>>> +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
>>> @@ -958,6 +958,30 @@ i2c9: i2c at 600 {
>>>  			};
>>>  		};
>>>  
>>> +		flx10: flexcom at e2820000 {
>>> +			compatible = "atmel,sama5d2-flexcom";
>>
>> My comment here was ignored:
>> https://lore.kernel.org/all/20240214-robe-pregnancy-a1b056c9fe14 at spud/
>>
>> The SAMA7G5 has the same flexcom controller as SAMA5D2 MPU.
>>
> 
> Still, it needs its own compatible plus a fallback to
> atmel,sama5d2-flexcom

I agree with this. Though, flexcom documentation is subject to YAML
conversion (a patch has been re-posted these days [1] and *maybe* it will
be integrated this time). And there are multiple SoC DTs that need to be
updated with their own flexcom compatible (lan966x, sam9x60, sama7g5).

To avoid conflicting with the work at [1] and postponing this series we may
do the update after the [1] is done.

Let me know your thoughts. Either way is fine by me.

Thank you,
Claudiu Beznea

[1]
https://patchwork.kernel.org/project/linux-arm-kernel/patch/20240214-sama5d2-flexcom-yaml-v1-1-5dedd0eba08e at microchip.com/

> 
>> https://github.com/torvalds/linux/blob/master/drivers/mfd/atmel-flexcom.c#L83
>> https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt#L8
> 


From u.kleine-koenig at pengutronix.de  Fri Feb 16 00:43:47 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Fri, 16 Feb 2024 09:43:47 +0100
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <2e96c824-47e8-48bd-9e03-8c7390b02d24@linaro.org>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
 <aamdttvdk3jmswvy3rw3debk3ouddkgjbs6xmixroe6kqakjw4@lnd5crcgoeyj>
 <2e96c824-47e8-48bd-9e03-8c7390b02d24@linaro.org>
Message-ID: <wkqqowh6ivn35d24n5ngdqno77wl7onrkdh43winac7bg7oekf@ykwhxujb4cjq>

Hello Krzysztof,

On Thu, Feb 15, 2024 at 07:44:53PM +0100, Krzysztof Kozlowski wrote:
> On 15/02/2024 11:02, Uwe Kleine-K?nig wrote:
> > On Mon, Feb 12, 2024 at 11:23:02AM +0100, Krzysztof Kozlowski wrote:
> >> On 08/02/2024 11:43, Lee Jones wrote:
> >>> Applied, thanks!
> >>>
> >>> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
> >>>       commit: cb946db1335b599ece363d33966bf653ed0fa58a
> >>>
> >>
> >> Next is still failing.
> > 
> > Failing in the sense of dtbs_check, right?
> 
> No, bindings were failing. dt_binding_check. This must not fail, so kind
> of bummer...
> 
> >> Dharma,
> >> You must explain and clearly mark dependencies between patches.
> >>
> >> Lee,
> >> Can you pick up two previous patches as well?
> > 
> > I applied the pwm patch now. If Lee wants to pick up this one via his
> > tree that would be fine for me, too. If that's the case please tell me,
> > then I'll drop it from my for-next branch again. Feel free to add
> > my Acked-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de> for patch
> > #2 then.
> 
> At least next is happy.

The pwm binding is in next now (as
0fa319a1427f7c8d0af4c255316624f7e6f649a0) but dt_binding_check still
tells me (among others):

	Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml:
	Error in referenced schema matching $id: http://devicetree.org/schemas/display/atmel/atmel,hlcdc-display-controller.yaml

This is what you meant, right? This goes away as soon as the first patch
(dt-bindings: display: convert Atmel's HLCDC to DT schema) is applied,
too. So next isn't completely happy yet.

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/20240216/2ac076b3/attachment.sig>

From yoshihiro.shimoda.uh at renesas.com  Fri Feb 16 00:47:04 2024
From: yoshihiro.shimoda.uh at renesas.com (Yoshihiro Shimoda)
Date: Fri, 16 Feb 2024 08:47:04 +0000
Subject: [PATCH] irqchip/gic-v3-its: Workaround Renesas R-Car GICv3 ITS
In-Reply-To: <865xyr5n3s.wl-maz@kernel.org>
References: <20240214052050.1966439-1-yoshihiro.shimoda.uh@renesas.com>
 <865xyr5n3s.wl-maz@kernel.org>
Message-ID: <OSZPR01MB86117352CF6EAB68ACBFF791D84C2@OSZPR01MB8611.jpnprd01.prod.outlook.com>

Hi Marc,

Thank you for your review!

> From: Marc Zyngier, Sent: Wednesday, February 14, 2024 7:58 PM
> 
> [+ Geert, who deals with Renesas SoCs on a daily basis]
> 
> Hi Yoshihiro,
> 
> On Wed, 14 Feb 2024 05:20:50 +0000,
> Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com> wrote:
> >
> > The GICv3 ITS on Renesas R-Car has limitations:
> >  - It can access lower 32-bits memory area only.
> >  - It cannot use Sharable/cache attributes.
> >
> > So, set ITS_FLAGS_FORCE_NON_SHAREABLE flag, and set GFP_DMA to all
> > memory allocation APIs for getting lower 32-bits memory area on
> > the R-Car. Note that GFP_DMA32 cannot work correctly because
> > the environment doens't have DMA32 zone like below:
> 
> nit: doesn't

Oops. I'll fix it.

> >
> > [    0.000000] Zone ranges:
> > [    0.000000]   DMA      [mem 0x0000000048000000-0x00000000ffffffff]
> > [    0.000000]   DMA32    empty
> > [    0.000000]   Normal   [mem 0x0000000100000000-0x00000004ffffffff]
> 
> Unfortunately, none of that is a universal truth. The way DMA and
> DMA32 are expressed is pretty variable. See this for example:
> 
> https://lore.kernel.org/all/cover.1703683642.git.baruch at tkos.co.il/
> 
> So I can't see how you can reliably rely on this layout. It may work
> today on your platform, but I wouldn't take this as a guarantee.

So, IIUC, I should use DMA API for it instead.

> >
> > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
> > ---
> >  arch/arm64/Kconfig               |  9 +++++
> >  drivers/irqchip/irq-gic-v3-its.c | 59 +++++++++++++++++++++-----------
> >  2 files changed, 48 insertions(+), 20 deletions(-)
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index c1a16a9dae72..49fe3006e142 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -1250,6 +1250,15 @@ config SOCIONEXT_SYNQUACER_PREITS
> >
> >  	  If unsure, say Y.
> >
> > +config RENESAS_RCAR_GIC_ITS
> > +	bool "Renesas R-Car: Workaround for GICv3 ITS"
> > +	default n
> > +	help
> > +	  Renesas R-Car Gen4 SoCs has a limitation about GICv3 ITS which can
> > +	  access lower 32-bits memory address range only.
> > +
> > +	  If unsure, say Y.
> 
> Either this should be 'default y', or you should drop this last line.
> Being 'default n' and saying 'if you don't know, say y' is
> counterproductive.

I got it. I'll fix it.

> Also:
> 
> - This must carry an official erratum number
> 
> - You must document it in Documentation/arch/arm64/silicon-errata.rst

I got it.

> > +
> >  endmenu # "ARM errata workarounds via the alternatives framework"
> >
> >  choice
> > diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> > index d097001c1e3e..e0e672b561b9 100644
> > --- a/drivers/irqchip/irq-gic-v3-its.c
> > +++ b/drivers/irqchip/irq-gic-v3-its.c
> > @@ -186,6 +186,7 @@ static LIST_HEAD(its_nodes);
> >  static DEFINE_RAW_SPINLOCK(its_lock);
> >  static struct rdists *gic_rdists;
> >  static struct irq_domain *its_parent;
> > +static gfp_t its_gfp_quirk;
> 
> Why is that global? Why isn't this computed on a per-ITS basis? Since
> you are introducing a generic mechanism here, you shouldn't assume
> that all ITSs are subjected to the same issue.

Since some functions doesn't have struct its_node, I think adding the argument
makes complex the code.  I'll avoid to use a global value somehow.

> >
> >  static unsigned long its_list_map;
> >  static u16 vmovp_seq_num;
> > @@ -1846,7 +1847,7 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
> >  		struct its_vlpi_map *maps;
> >
> >  		maps = kcalloc(its_dev->event_map.nr_lpis, sizeof(*maps),
> > -			       GFP_ATOMIC);
> > +			       GFP_ATOMIC | its_gfp_quirk);
> 
> This data structure is never exposed to the GIC. Why do we need to
> constraint this allocation?

I'm sorry, I didn't understand that. I'll drop this.

> >  		if (!maps) {
> >  			ret = -ENOMEM;
> >  			goto out;
> > @@ -2044,7 +2045,7 @@ static struct lpi_range *mk_lpi_range(u32 base, u32 span)
> >  {
> >  	struct lpi_range *range;
> >
> > -	range = kmalloc(sizeof(*range), GFP_KERNEL);
> > +	range = kmalloc(sizeof(*range), GFP_KERNEL | its_gfp_quirk);
> 
> Same thing.

I'll drop this.

> >  	if (range) {
> >  		range->base_id = base;
> >  		range->span = span;
> > @@ -2169,7 +2170,7 @@ static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids)
> >  	if (err)
> >  		goto out;
> >
> > -	bitmap = bitmap_zalloc(nr_irqs, GFP_ATOMIC);
> > +	bitmap = bitmap_zalloc(nr_irqs, GFP_ATOMIC | its_gfp_quirk);
> 
> Same thing.

I'll drop this.

> >  	if (!bitmap)
> >  		goto out;
> >
> > @@ -2201,7 +2202,7 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags)
> >  {
> >  	struct page *prop_page;
> >
> > -	prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
> > +	prop_page = alloc_pages(gfp_flags | its_gfp_quirk, get_order(LPI_PROPBASE_SZ));
> 
> This only affects the redistributors. Why should we constraint it?

To be honest, I don't know why, but this is required on my environment.
Otherwise, the MSI interrupt never happens.
Anyway, I should have learned the hardware bug in detail...

> >  	if (!prop_page)
> >  		return NULL;
> >
> > @@ -2335,7 +2336,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
> >  		order = get_order(GITS_BASER_PAGES_MAX * psz);
> >  	}
> >
> > -	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
> > +	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO | its_gfp_quirk, order);
> >  	if (!page)
> >  		return -ENOMEM;
> >
> > @@ -2808,7 +2809,7 @@ static bool allocate_vpe_l2_table(int cpu, u32 id)
> >
> >  	/* Allocate memory for 2nd level table */
> >  	if (!table[idx]) {
> > -		page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(psz));
> > +		page = alloc_pages(GFP_KERNEL | __GFP_ZERO | its_gfp_quirk, get_order(psz));
> >  		if (!page)
> >  			return false;
> >
> > @@ -2860,7 +2861,7 @@ static int allocate_vpe_l1_table(void)
> >  	if (val & GICR_VPROPBASER_4_1_VALID)
> >  		goto out;
> >
> > -	gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_ATOMIC);
> > +	gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_ATOMIC | its_gfp_quirk);
> 
> This is a cpumask allocation, not exposed to the GIC. What is the
> reason for constraining it?

I'm sorry, I didn't understand the specification.
I'll drop this.

> >  	if (!gic_data_rdist()->vpe_table_mask)
> >  		return -ENOMEM;
> >
> > @@ -2927,7 +2928,7 @@ static int allocate_vpe_l1_table(void)
> >
> >  	pr_debug("np = %d, npg = %lld, psz = %d, epp = %d, esz = %d\n",
> >  		 np, npg, psz, epp, esz);
> > -	page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, get_order(np * PAGE_SIZE));
> > +	page = alloc_pages(GFP_ATOMIC | __GFP_ZERO | its_gfp_quirk, get_order(np * PAGE_SIZE));
> >  	if (!page)
> >  		return -ENOMEM;
> >
> > @@ -2957,7 +2958,7 @@ static int its_alloc_collections(struct its_node *its)
> >  	int i;
> >
> >  	its->collections = kcalloc(nr_cpu_ids, sizeof(*its->collections),
> > -				   GFP_KERNEL);
> > +				   GFP_KERNEL | its_gfp_quirk);
> 
> Same thing.

I'll drop this.

> >  	if (!its->collections)
> >  		return -ENOMEM;
> >
> > @@ -2971,7 +2972,7 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags)
> >  {
> >  	struct page *pend_page;
> >
> > -	pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
> > +	pend_page = alloc_pages(gfp_flags | __GFP_ZERO | its_gfp_quirk,
> >  				get_order(LPI_PENDBASE_SZ));
> 
> This is a redistributor-private allocation. If it is the ITSs that are
> affected by this bug, why are the pending tables constrained?

Thank you for the comment. This is not needed on my environment.
So, I'll drop it.

> >  	if (!pend_page)
> >  		return NULL;
> > @@ -3319,7 +3320,7 @@ static bool its_alloc_table_entry(struct its_node *its,
> >
> >  	/* Allocate memory for 2nd level table */
> >  	if (!table[idx]) {
> > -		page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
> > +		page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO | its_gfp_quirk,
> >  					get_order(baser->psz));
> >  		if (!page)
> >  			return false;
> > @@ -3415,7 +3416,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
> >  	if (WARN_ON(!is_power_of_2(nvecs)))
> >  		nvecs = roundup_pow_of_two(nvecs);
> >
> > -	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> > +	dev = kzalloc(sizeof(*dev), GFP_KERNEL | its_gfp_quirk);
> >  	/*
> >  	 * Even if the device wants a single LPI, the ITT must be
> >  	 * sized as a power of two (and you need at least one bit...).
> > @@ -3423,14 +3424,14 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
> >  	nr_ites = max(2, nvecs);
> >  	sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1);
> >  	sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
> > -	itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node);
> > +	itt = kzalloc_node(sz, GFP_KERNEL | its_gfp_quirk, its->numa_node);
> >  	if (alloc_lpis) {
> >  		lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis);
> >  		if (lpi_map)
> >  			col_map = kcalloc(nr_lpis, sizeof(*col_map),
> > -					  GFP_KERNEL);
> > +					  GFP_KERNEL | its_gfp_quirk);
> 
> This is kernel-private memory, not visible by the GIC.

I'll drop this.

> >  	} else {
> > -		col_map = kcalloc(nr_ites, sizeof(*col_map), GFP_KERNEL);
> > +		col_map = kcalloc(nr_ites, sizeof(*col_map), GFP_KERNEL | its_gfp_quirk);
> 
> Same thing.

I'll drop this.

> >  		nr_lpis = 0;
> >  		lpi_base = 0;
> >  	}
> > @@ -4754,6 +4755,16 @@ static bool __maybe_unused its_enable_rk3588001(void *data)
> >  	return true;
> >  }
> >
> > +static bool __maybe_unused its_enable_renesas_rcar_gic_its(void *data)
> > +{
> > +	struct its_node *its = data;
> > +
> > +	its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE;
> > +	its_gfp_quirk = GFP_DMA;
> > +
> > +	return true;
> > +}
> > +
> >  static bool its_set_non_coherent(void *data)
> >  {
> >  	struct its_node *its = data;
> > @@ -4815,6 +4826,14 @@ static const struct gic_quirk its_quirks[] = {
> >  		.mask   = 0xffffffff,
> >  		.init   = its_enable_rk3588001,
> >  	},
> > +#endif
> > +#ifdef CONFIG_RENESAS_RCAR_GIC_ITS
> > +	{
> > +		.desc   = "ITS: Renesas R-Car Gen4 GICv3 ITS",
> > +		.iidr   = 0x0201743b,
> > +		.mask   = 0xffffffff,
> > +		.init   = its_enable_renesas_rcar_gic_its,
> > +	},
> 
> Huh. This describes a GIC600 implemented by ARM. Which means your are
> actively forcing your quirk on *every* implementations, including
> those that are not affected by this hardware issue. Definitely not
> acceptable.

I understood it. I'll add a condition like its_enable_rk3588001() to
affect this quirk for my environment only. I believe that such adding
condition is acceptable because the CONFIG_ROCKCHIP_ERRATUM_3588001
is the same iidr value of my environment.

> >  #endif
> >  	{
> >  		.desc   = "ITS: non-coherent attribute",
> > @@ -4974,7 +4993,7 @@ static int its_init_domain(struct its_node *its)
> >  	struct irq_domain *inner_domain;
> >  	struct msi_domain_info *info;
> >
> > -	info = kzalloc(sizeof(*info), GFP_KERNEL);
> > +	info = kzalloc(sizeof(*info), GFP_KERNEL | its_gfp_quirk);
> 
> Kernel memory only.

I'll drop it.

> >  	if (!info)
> >  		return -ENOMEM;
> >
> > @@ -5011,7 +5030,7 @@ static int its_init_vpe_domain(void)
> >
> >  	entries = roundup_pow_of_two(nr_cpu_ids);
> >  	vpe_proxy.vpes = kcalloc(entries, sizeof(*vpe_proxy.vpes),
> > -				 GFP_KERNEL);
> > +				 GFP_KERNEL | its_gfp_quirk);
> >  	if (!vpe_proxy.vpes)
> >  		return -ENOMEM;
> >
> > @@ -5108,7 +5127,7 @@ static int __init its_probe_one(struct its_node *its)
> >  		}
> >  	}
> >
> > -	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
> > +	page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO | its_gfp_quirk,
> >  				get_order(ITS_CMD_QUEUE_SZ));
> >  	if (!page) {
> >  		err = -ENOMEM;
> > @@ -5352,7 +5371,7 @@ static struct its_node __init *its_node_init(struct resource *res,
> >
> >  	pr_info("ITS %pR\n", res);
> >
> > -	its = kzalloc(sizeof(*its), GFP_KERNEL);
> > +	its = kzalloc(sizeof(*its), GFP_KERNEL | its_gfp_quirk);
> 
> Kernel memory only.

I'll drop it.

> >  	if (!its)
> >  		goto out_unmap;
> >
> > @@ -5520,7 +5539,7 @@ static void __init acpi_table_parse_srat_its(void)
> >  		return;
> >
> >  	its_srat_maps = kmalloc_array(count, sizeof(struct its_srat_map),
> > -				      GFP_KERNEL);
> > +				      GFP_KERNEL | its_gfp_quirk);
> 
> Kernel memory only.

I'll drop it.

> >  	if (!its_srat_maps)
> >  		return;
> >
> 
> I suggest that you start reading the architecture spec and understand
> what is the memory that is accessible by the GIC, because at least
> half of this patch is completely unnecessary.
> 
> You also need to be clear about what is affected by this bug: ITS
> only? or also the RDs?  If both are affected, they need to be handled
> separately.
> 
> In any case, you must not assume that all ITSs in a system are
> subjected to this bug, which means that you must have per-ITS tracking
> of the GFP flags.
> 
> Finally, the DMA story itself needs to be sorted out, because you are
> relying on something that is incredibly fragile.

Thank you very much for your suggestion. I'll learn the architecture spec
and reconsider the implementation, especially DMA related.

Best regards,
Yoshihiro Shimoda

> HTH,
> 
> 	M.
> 
> --
> Without deviation from the norm, progress is not possible.


From tomi.valkeinen at ideasonboard.com  Fri Feb 16 00:49:46 2024
From: tomi.valkeinen at ideasonboard.com (Tomi Valkeinen)
Date: Fri, 16 Feb 2024 10:49:46 +0200
Subject: [PATCH v5 0/4] Add common1 region for AM62, AM62A & AM65x
In-Reply-To: <20240216062426.4170528-1-devarsht@ti.com>
References: <20240216062426.4170528-1-devarsht@ti.com>
Message-ID: <151e6597-e591-4c7f-a702-fb539c3e38d6@ideasonboard.com>

On 16/02/2024 08:24, Devarsh Thakkar wrote:
> This adds DSS common1 region for respective SoCs supporting it.
> 
> Changelog:
> V2 : Remove do-not-merge tag and add am62a dss common1 reion
> V3 : Add Fixes tag to each commit
> V4 : Add Reviewed-by tag and AM62A SoC TRM Link
> V5 : Split dts patch to separate patches for each SoC
> 
> Devarsh Thakkar (4):
>    dt-bindings: display: ti,am65x-dss: Add support for common1 region
>    arm64: dts: ti: Add common1 register space for AM65x SoC
>    arm64: dts: ti: Add common1 register space for AM62x SoC
>    arm64: dts: ti: Add common1 register space for AM62A SoC
> 
>   .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
>   arch/arm64/boot/dts/ti/k3-am62-main.dtsi                   | 5 +++--
>   arch/arm64/boot/dts/ti/k3-am62a-main.dtsi                  | 5 +++--
>   arch/arm64/boot/dts/ti/k3-am65-main.dtsi                   | 5 +++--
>   4 files changed, 14 insertions(+), 8 deletions(-)
> 

For the series:

Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>

  Tomi



From michal.simek at amd.com  Fri Feb 16 00:51:59 2024
From: michal.simek at amd.com (Michal Simek)
Date: Fri, 16 Feb 2024 09:51:59 +0100
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
Message-ID: <94726c90ff519185767475f672d70311472ea925.1708073513.git.michal.simek@amd.com>

RTC has its own power domain on Xilinx Versal SOC that's why describe it as
optional property.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml b/Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml
index d1f5eb996dba..838c3ce494de 100644
--- a/Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml
@@ -48,6 +48,9 @@ properties:
     default: 0x198233
     deprecated: true
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
-- 
2.36.1



From u.kleine-koenig at pengutronix.de  Fri Feb 16 00:56:51 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Fri, 16 Feb 2024 09:56:51 +0100
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible
 for MT7988
In-Reply-To: <e957b044-fe84-4b72-bdf1-cbc40c722019@collabora.com>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <20240213-resource-evaluator-0754cfd5882d@spud>
 <d4391868-ddcd-4f66-b539-28d245fa83df@gmail.com>
 <e957b044-fe84-4b72-bdf1-cbc40c722019@collabora.com>
Message-ID: <crisnlcmsylgjbyikwj4it5oee46lrcneegt35rkh7f7irpjt4@au5h4owkl4s3>

Hello,

On Wed, Feb 14, 2024 at 10:27:54AM +0100, AngeloGioacchino Del Regno wrote:
> Il 14/02/24 07:34, Rafa? Mi?ecki ha scritto:
> > On 13.02.2024 19:18, Conor Dooley wrote:
> > > On Tue, Feb 13, 2024 at 05:46:32PM +0100, Rafa? Mi?ecki wrote:
> > > > From: Rafa? Mi?ecki <rafal at milecki.pl>
> > > > 
> > > > MT7988 has on-SoC controller that can control up to 8 PWMs.
> > > 
> > > I see a binding and a dts patch, but no driver patch, how come?
> > 
> > I believe that to avoid cross-trees patchsets (which are sometimes
> > tricky for maintainers) there are two ways of submiting such changes:
> > 1. dt-binding + driver; then (separately) DTS
> > 2. dt-binding + DTS; then (separately) driver
> > 
> > I chose later in this case as my personal priority right now is to deal
> > with all MediaTek DTS files.
> > 
> > Is that wrong or unacceptable?
> > 
> 
> It's not wrong but it's partially unacceptable, at least on my side.
> 
> In my opinion (and I believe many do agree with me), sending the binding along
> with the driver is the right choice, and if you also want to include the dts
> that is also appreciated: series can go through multiple maintainers applying
> subsets - it's ok to do.

Just to put in my 2 ?:
My preference is to not avoid cross-trees patchsets and put all three
patches in a single series. This combines the advantages of 1. and 2.
Given this happens often enough this is something that the maintainers
are used to handle just fine, so the cross-tree issue isn't problematic
most of the time. The conflicts that sometimes arise with cross-tree
patches aren't bad enough to out-weight having binding, driver and dts
changes all together.

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/20240216/cca099c2/attachment.sig>

From s-vadapalli at ti.com  Fri Feb 16 01:04:39 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Fri, 16 Feb 2024 14:34:39 +0530
Subject: [PATCH v3 08/18] phy: ti: phy-j721e-wiz: split wiz_clock_init()
 function
In-Reply-To: <Zc76d4B4hjTC3xum@matsya>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-8-5c2e4a3fac1f@bootlin.com>
 <Zc4xJtLl3zo_YrBC@smile.fi.intel.com>
 <Zc76d4B4hjTC3xum@matsya>
Message-ID: <14429802-b4d8-4a3e-88ea-a9fc55d2251c@ti.com>

On 24/02/16 11:32AM, Vinod Koul wrote:
> On 15-02-24, 17:43, Andy Shevchenko wrote:
> > On Thu, Feb 15, 2024 at 04:17:53PM +0100, Thomas Richard wrote:
> > > The wiz_clock_init() function mixes probe and hardware configuration.
> > > Rename the wiz_clock_init() to wiz_clock_probe() and move the hardware
> > > configuration part in a new function named wiz_clock_init().
> > > 
> > > This hardware configuration sequence must be called during the resume
> > > stage of the driver.
> > 
> > ...
> > 
> > (Side note, as this can be done later)
> > 
> > >  	if (rate >= 100000000)
> > 
> > > +		if (rate >= 100000000)
> > 
> > > +	if (rate >= 100000000)
> > 
> > I would make local definition and use it, we may get the global one as there
> > are users.
> > 
> > #define HZ_PER_GHZ	1000000000UL
> 
> Better to define as:
> #define HZ_PER_GHZ 1 * GIGA

The variable "rate" is being compared against 100 MHz and not 1 GHz.
The driver already has the following macros defined:
#define REF_CLK_19_2MHZ         19200000
#define REF_CLK_25MHZ           25000000
#define REF_CLK_100MHZ          100000000
#define REF_CLK_156_25MHZ       156250000

So would it be acceptable to change it to:
	if (rate >= REF_CLK_100MHZ)
instead?

Regards,
Siddharth.


From alexander.stein at ew.tq-group.com  Fri Feb 16 01:05:26 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 16 Feb 2024 10:05:26 +0100
Subject: [PATCH V8 09/12] dt-bindings: display: imx: add binding for i.MX8MP HDMI TX
In-Reply-To: <20240203165307.7806-10-aford173@gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com> <20240203165307.7806-10-aford173@gmail.com>
Message-ID: <5916132.MhkbZ0Pkbq@steina-w>

Hi all,

Am Samstag, 3. Februar 2024, 17:52:49 CET schrieb Adam Ford:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> The HDMI TX controller on the i.MX8MP SoC is a Synopsys designware IP
> core with a little bit of SoC integration around it.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 
> ---
> V3:  Change name and location to better idenfity as a bridge and
>      HDMI 2.0a transmitter
> 
>      Fix typos and feedback from Rob and added ports.
> ---
>  .../display/bridge/fsl,imx8mp-hdmi-tx.yaml    | 102 ++++++++++++++++++
>  1 file changed, 102 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> 
> diff --git
> a/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> new file mode 100644
> index 000000000000..3791c9f4ebab
> --- /dev/null
> +++
> b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> @@ -0,0 +1,102 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/bridge/fsl,imx8mp-hdmi-tx.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX8MP DWC HDMI TX Encoder
> +
> +maintainers:
> +  - Lucas Stach <l.stach at pengutronix.de>
> +
> +description:
> +  The i.MX8MP HDMI transmitter is a Synopsys DesignWare
> +  HDMI 2.0a TX controller IP.
> +
> +allOf:
> +  - $ref: /schemas/display/bridge/synopsys,dw-hdmi.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - fsl,imx8mp-hdmi-tx
> +
> +  reg-io-width:
> +    const: 1
> +
> +  clocks:
> +    maxItems: 4
> +
> +  clock-names:
> +    items:
> +      - const: iahb
> +      - const: isfr
> +      - const: cec
> +      - const: pix
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Parallel RGB input port
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: HDMI output port
> +
> +    required:
> +      - port at 0
> +      - port at 1

Is this really correct that port at 1 is required? AFAICS this host already 
supports HPD and DDC by itself, so there is no need for a dedicated HDMI 
connector.
With the current state of the drivers this output port is completely ignored 
anyway. Yet it works for a lot of people.

Best regards,
Alexander

> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - interrupts
> +  - power-domains
> +  - ports
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/imx8mp-clock.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/power/imx8mp-power.h>
> +
> +    hdmi at 32fd8000 {
> +        compatible = "fsl,imx8mp-hdmi-tx";
> +        reg = <0x32fd8000 0x7eff>;
> +        interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
> +        clocks = <&clk IMX8MP_CLK_HDMI_APB>,
> +                 <&clk IMX8MP_CLK_HDMI_REF_266M>,
> +                 <&clk IMX8MP_CLK_32K>,
> +                 <&hdmi_tx_phy>;
> +        clock-names = "iahb", "isfr", "cec", "pix";
> +        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
> +        reg-io-width = <1>;
> +        ports {
> +           #address-cells = <1>;
> +           #size-cells = <0>;
> +           port at 0 {
> +             reg = <0>;
> +
> +             hdmi_tx_from_pvi: endpoint {
> +               remote-endpoint = <&pvi_to_hdmi_tx>;
> +             };
> +          };
> +
> +          port at 1 {
> +            reg = <1>;
> +              hdmi_tx_out: endpoint {
> +                remote-endpoint = <&hdmi0_con>;
> +              };
> +          };
> +        };
> +    };


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From theo.lebrun at bootlin.com  Fri Feb 16 01:05:33 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 16 Feb 2024 10:05:33 +0100
Subject: [PATCH 13/13] MIPS: mobileye: eyeq5: add resets to I2C
 controllers
In-Reply-To: <42b7e3bb-a152-4ded-91f3-fb8043a7f413@linaro.org>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-13-19a336e91dca@bootlin.com>
 <42b7e3bb-a152-4ded-91f3-fb8043a7f413@linaro.org>
Message-ID: <CZ6DTGBC02P7.1RHCB4E64N88A@bootlin.com>

Hello,

On Fri Feb 16, 2024 at 8:59 AM CET, Krzysztof Kozlowski wrote:
> On 15/02/2024 17:52, Th?o Lebrun wrote:
> > Add resets properties to each I2C controller. This depends on the
> > reset-eyeq5 platform reset controller driver.
> > 
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> > ---
>
> This should be squashed with previous patch adding i2c controllers.
> Don't add incomplete nodes just to fix them in next patch.

The goal was to isolate reset phandles to a single patch. The series
with this patch dropped works because resets in their default state are
deasserted, so this isn't a fix. And it allows testing the series on
hardware with only the base platform series, which I found useful.

Noted, I'll be squashed for next revision.

Regards,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From krzysztof.kozlowski at linaro.org  Fri Feb 16 01:07:12 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 10:07:12 +0100
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible for
 MT7988
In-Reply-To: <d4391868-ddcd-4f66-b539-28d245fa83df@gmail.com>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <20240213-resource-evaluator-0754cfd5882d@spud>
 <d4391868-ddcd-4f66-b539-28d245fa83df@gmail.com>
Message-ID: <23c7fee5-ed66-436b-bb1e-ca4cdc8d0a66@linaro.org>

On 14/02/2024 07:34, Rafa? Mi?ecki wrote:
> On 13.02.2024 19:18, Conor Dooley wrote:
>> On Tue, Feb 13, 2024 at 05:46:32PM +0100, Rafa? Mi?ecki wrote:
>>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>>
>>> MT7988 has on-SoC controller that can control up to 8 PWMs.
>>
>> I see a binding and a dts patch, but no driver patch, how come?
> 
> I believe that to avoid cross-trees patchsets (which are sometimes
> tricky for maintainers) there are two ways of submiting such changes:
> 1. dt-binding + driver; then (separately) DTS
> 2. dt-binding + DTS; then (separately) driver
> 
> I chose later in this case as my personal priority right now is to deal
> with all MediaTek DTS files.
> 
> Is that wrong or unacceptable?

That was explained many, many times. For cases like driver+bindings+DTS,
bindings go via driver subsystem, so they should be posted with driver
patches.

Feel free to include DTS at the end of series, unless you send to Greg
or netdev.
Better, also required for Greg and netdev, is to send DTS separately
with lore links to the bindings.

Best regards,
Krzysztof



From jpanis at baylibre.com  Fri Feb 16 01:08:03 2024
From: jpanis at baylibre.com (Julien Panis)
Date: Fri, 16 Feb 2024 10:08:03 +0100
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI
 TPS65224 PMIC
In-Reply-To: <20240214-depraved-unfunded-3f0b3d6bf3e2@spud>
References: <20240209-blitz-fidgety-78469aa80d6d@spud>
 <20240214093106.86483-1-bhargav.r@ltts.com>
 <20240214-galley-dweller-1e9872229d80@spud> <7hil2r5556.fsf@baylibre.com>
 <20240214-depraved-unfunded-3f0b3d6bf3e2@spud>
Message-ID: <e13627e2-9d8f-437d-afe4-d8bfcade2f6a@baylibre.com>

On 2/14/24 18:45, Conor Dooley wrote:
> On Wed, Feb 14, 2024 at 09:26:13AM -0800, Kevin Hilman wrote:
>> Conor Dooley <conor at kernel.org> writes:
>>> On Wed, Feb 14, 2024 at 03:01:06PM +0530, Bhargav Raviprakash wrote:
>>>> On Fri 2/9/2024 10:41 PM, Conor Dooley wrote:
>>>>> On Thu, Feb 08, 2024 at 04:23:33PM +0530, Bhargav Raviprakash wrote:
>>>>>> TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
>>>>>> regulators, it includes additional features like GPIOs, watchdog, ESMs
>>>>>> (Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
>>>>>> managing the state of the device.
>>>>>> TPS6594 and TPS65224 have significant functional overlap.
>>>>> What does "significant functional overlap" mean? Does one implement a
>>>>> compatible subset of the other? I assume the answer is no, given there
>>>>> seems to be some core looking registers at different addresses.
>>>> The intention behind ?significant functional overlap? was meant to
>>>> indicate a lot of the features between TPS6594 and TPS65224 overlap,
>>>> while there are some features specific to TPS65224.
>>>> There is compatibility between the PMIC register maps, I2C, PFSM,
>>>> and other drivers even though there are some core registers at
>>>> different addresses.
>>>>
>>>> Would it be more appropriate to say the 2 devices are compatible and have
>>>> sufficient feature overlap rather than significant functional overlap?
>>> If core registers are at different addresses, then it is unlikely that
>>> these devices are compatible.
>> That's not necessarily true.  Hardware designers can sometimes be
>> creative. :)
> Hence "unlikely" in my mail :)

For tps6594 and tps65224, some core registers are at different adresses
indeed, but the code is the same for both MFD I2C/SPI entry points. As an
example, the way CRC is enabled is exactly the same, even if the bit that
must be set belongs to different registers. tps65224 has more resources and
it's as if HW designers had had to re-organize the way bits are distributed
among the registers (due to a lack of space, so to speak).

That said, if we consider that these devices are not compatible, what does it
imply concretely for the next version ? Does that mean that:
1) Only a new binding must be created, even if MFD drivers and most of child
drivers will be re-used ? (then the binding would simply be duplicated, but
the drivers would not)
2) A new binding and new MFD drivers must be created, even if most of child
drivers will be re-used ? (then the binding and MFD drivers would simply be
duplicated, but the child drivers would not)
3) A new binding and new drivers (MFD and child devices) must be created ?
4) Anything else ?

@Conor: I understand that it's not your problem. Anybody can answer, I just
try to make things clear for the next version. :)

Julien

>
>>> In this context, compatible means that existing software intended for
>>> the 6594 would run without modification on the 65224, although maybe
>>> only supporting a subset of features.  If that's not the case, then
>>> the devices are not compatible.
>> Compatible is a fuzzy term... so we need to get into the gray area.
>>
>> What's going on here is that this new part is derivative in many
>> signifcant (but not all) ways from an existing similar part.  When
>> writing drivers for new, derivative parts, there's always a choice
>> between 1) extending the existing driver (using a new compatible string
>> & match table for the diffs) or 2) creating a new driver which will have
>> a bunch of duplicated code.
>>
>> The first verion of this series[1] took the 2nd approach, but due to the
>> significant functional (and feature) overlap, the recommendation was
>> instead to take the "reuse" path to avoid signficant amounts of
>> duplicated code.
>>
>> Of course, it's possible that while going down the "reuse" path, there
>> may be a point where creating a separate driver for some aspects might
>> make sense, but that needs to be justified.  Based on a quick glance of
>> what I see in this series so far (I have not done a detailed review),
>> the differences with the new device look to me like they can be handled
>> with chip-specific data in a match table.
> This is all nice information, but not really relevant here - this is a
> binding patch, not a driver one & the conversation stemmed from me
> making sure that a fallback compatible was not suitable. Whether or not
> there are multiple drivers or not is someone else's problem!
>
> Thanks,
> Conor.



From maz at kernel.org  Fri Feb 16 01:11:03 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 16 Feb 2024 09:11:03 +0000
Subject: [PATCH] irqchip/gic-v3-its: Workaround Renesas R-Car GICv3 ITS
In-Reply-To: <OSZPR01MB86117352CF6EAB68ACBFF791D84C2@OSZPR01MB8611.jpnprd01.prod.outlook.com>
References: <20240214052050.1966439-1-yoshihiro.shimoda.uh@renesas.com>
	<865xyr5n3s.wl-maz@kernel.org>
	<OSZPR01MB86117352CF6EAB68ACBFF791D84C2@OSZPR01MB8611.jpnprd01.prod.outlook.com>
Message-ID: <86il2o4vvc.wl-maz@kernel.org>

On Fri, 16 Feb 2024 08:47:04 +0000,
Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com> wrote:
> 
> Hi Marc,
> 
> Thank you for your review!
> 
> > > @@ -2201,7 +2202,7 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags)
> > >  {
> > >  	struct page *prop_page;
> > >
> > > -	prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
> > > +	prop_page = alloc_pages(gfp_flags | its_gfp_quirk, get_order(LPI_PROPBASE_SZ));
> > 
> > This only affects the redistributors. Why should we constraint it?
> 
> To be honest, I don't know why, but this is required on my environment.
> Otherwise, the MSI interrupt never happens.
> Anyway, I should have learned the hardware bug in detail...

So the redistributors are also affected by this bug, which makes sense
given the monolithic nature of GIC600.

This should be handled as a separate allocation constraints (i.e. not
using your ITS-specific GFP quirk).

[...]

> > > @@ -2971,7 +2972,7 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags)
> > >  {
> > >  	struct page *pend_page;
> > >
> > > -	pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
> > > +	pend_page = alloc_pages(gfp_flags | __GFP_ZERO | its_gfp_quirk,
> > >  				get_order(LPI_PENDBASE_SZ));
> > 
> > This is a redistributor-private allocation. If it is the ITSs that are
> > affected by this bug, why are the pending tables constrained?
> 
> Thank you for the comment. This is not needed on my environment.
> So, I'll drop it.

If GICR_PROPBASER needs to be in the low 4GB, it is likely that
GICR_PENDBASER has the same constraint. It is just that the GIC600
caches are big enough that evictions are rare, and that you don't see
a problem. But it is still very likely to exist.

[...]

> > I suggest that you start reading the architecture spec and understand
> > what is the memory that is accessible by the GIC, because at least
> > half of this patch is completely unnecessary.
> > 
> > You also need to be clear about what is affected by this bug: ITS
> > only? or also the RDs?  If both are affected, they need to be handled
> > separately.
> > 
> > In any case, you must not assume that all ITSs in a system are
> > subjected to this bug, which means that you must have per-ITS tracking
> > of the GFP flags.
> > 
> > Finally, the DMA story itself needs to be sorted out, because you are
> > relying on something that is incredibly fragile.
> 
> Thank you very much for your suggestion. I'll learn the architecture spec
> and reconsider the implementation, especially DMA related.

Using the DMA allocator is an interesting prospect. The only issue
with that is that the ITS isn't currently represented as a device,
which the DMA allocator requires IIRC. You will either have to plumb
something in a low-level allocator, or convert the ITS code to
implement a platform device. The latter won't be fun.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From theo.lebrun at bootlin.com  Fri Feb 16 01:16:54 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 16 Feb 2024 10:16:54 +0100
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <20240216022704.GB850600-robh@kernel.org>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>
 <20240216022704.GB850600-robh@kernel.org>
Message-ID: <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>

Hello,

On Fri Feb 16, 2024 at 3:27 AM CET, Rob Herring wrote:
> On Thu, Feb 15, 2024 at 05:52:08PM +0100, Th?o Lebrun wrote:
> > Expose I2C device timeout configuration from devicetree. Use ?s as time
> > unit and express it in the name.
> > 
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> > ---
> >  Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
> > index 16024415a4a7..e6b95e3765ac 100644
> > --- a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
> > +++ b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
> > @@ -70,6 +70,10 @@ properties:
> >      minimum: 1
> >      maximum: 400000
> >  
> > +  timeout-usecs:
>
> Use standard unit suffixes.
>
> We already have at least 2 device specific timeout properties. This one 
> should be common. That means you need to add it to i2c-controller.yaml 
> in dtschema. GH PR or patch to devicetree-spec list is fine.

i2c-mpc (fsl,timeout) and i2c-gpio (i2c-gpio,timeout-ms). I agree this
prop has no reason to be compatible-specific.

Feedback from dt-bindings and I2C host maintainers would be useful: what
should the property be named? Having the unit makes it self-descriptive,
which sounds like a good idea to me. timeout-usecs, timeout-us, another
option?

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From krzysztof.kozlowski at linaro.org  Fri Feb 16 01:17:05 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 10:17:05 +0100
Subject: [PATCH 13/13] MIPS: mobileye: eyeq5: add resets to I2C
 controllers
In-Reply-To: <CZ6DTGBC02P7.1RHCB4E64N88A@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-13-19a336e91dca@bootlin.com>
 <42b7e3bb-a152-4ded-91f3-fb8043a7f413@linaro.org>
 <CZ6DTGBC02P7.1RHCB4E64N88A@bootlin.com>
Message-ID: <c478bb6f-49b8-4251-99e9-46b4c9510953@linaro.org>

On 16/02/2024 10:05, Th?o Lebrun wrote:
> Hello,
> 
> On Fri Feb 16, 2024 at 8:59 AM CET, Krzysztof Kozlowski wrote:
>> On 15/02/2024 17:52, Th?o Lebrun wrote:
>>> Add resets properties to each I2C controller. This depends on the
>>> reset-eyeq5 platform reset controller driver.
>>>
>>> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
>>> ---
>>
>> This should be squashed with previous patch adding i2c controllers.
>> Don't add incomplete nodes just to fix them in next patch.
> 
> The goal was to isolate reset phandles to a single patch. The series

That was what you did, not the goal. If that's the goal, then it is
clearly wrong.

> with this patch dropped works because resets in their default state are
> deasserted, so this isn't a fix. And it allows testing the series on
> hardware with only the base platform series, which I found useful.

Series or half-of-series? Anyway, commits must be logical chunks, so one
chunk is to add I2C controllers, not "part of I2C controllers". DTS is
also independent of drivers (and it will go via different trees!), so
whatever dependency you think of, it does not exist.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb 16 01:17:46 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 10:17:46 +0100
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>
 <20240216022704.GB850600-robh@kernel.org>
 <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>
Message-ID: <60b568a1-6dc9-4116-af95-bfaaca61677b@linaro.org>

On 16/02/2024 10:16, Th?o Lebrun wrote:
> Hello,
> 
> On Fri Feb 16, 2024 at 3:27 AM CET, Rob Herring wrote:
>> On Thu, Feb 15, 2024 at 05:52:08PM +0100, Th?o Lebrun wrote:
>>> Expose I2C device timeout configuration from devicetree. Use ?s as time
>>> unit and express it in the name.
>>>
>>> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
>>> ---
>>>  Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml | 5 +++++
>>>  1 file changed, 5 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
>>> index 16024415a4a7..e6b95e3765ac 100644
>>> --- a/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
>>> +++ b/Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
>>> @@ -70,6 +70,10 @@ properties:
>>>      minimum: 1
>>>      maximum: 400000
>>>  
>>> +  timeout-usecs:
>>
>> Use standard unit suffixes.
>>
>> We already have at least 2 device specific timeout properties. This one 
>> should be common. That means you need to add it to i2c-controller.yaml 
>> in dtschema. GH PR or patch to devicetree-spec list is fine.
> 
> i2c-mpc (fsl,timeout) and i2c-gpio (i2c-gpio,timeout-ms). I agree this
> prop has no reason to be compatible-specific.
> 
> Feedback from dt-bindings and I2C host maintainers would be useful: what
> should the property be named? Having the unit makes it self-descriptive,
> which sounds like a good idea to me. timeout-usecs, timeout-us, another
> option?

It must have an unit. That's not negotiable for new properties.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb 16 01:19:30 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 10:19:30 +0100
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
In-Reply-To: <94726c90ff519185767475f672d70311472ea925.1708073513.git.michal.simek@amd.com>
References: <94726c90ff519185767475f672d70311472ea925.1708073513.git.michal.simek@amd.com>
Message-ID: <5a81f16b-8ece-4263-b424-4dd6cd6e386f@linaro.org>

On 16/02/2024 09:51, Michal Simek wrote:
> RTC has its own power domain on Xilinx Versal SOC that's why describe it as
> optional property.
> 
> Signed-off-by: Michal Simek <michal.simek at amd.com>
> ---
> 
>  Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 

But Versal is not described in this binding, is it? I see only one
compatible.

Best regards,
Krzysztof



From sakari.ailus at linux.intel.com  Fri Feb 16 01:21:27 2024
From: sakari.ailus at linux.intel.com (Sakari Ailus)
Date: Fri, 16 Feb 2024 09:21:27 +0000
Subject: [PATCH 2/2] media: i2c: Add imx283 camera sensor driver
In-Reply-To: <20240215204436.9194-3-umang.jain@ideasonboard.com>
References: <20240215204436.9194-1-umang.jain@ideasonboard.com>
 <20240215204436.9194-3-umang.jain@ideasonboard.com>
Message-ID: <Zc8pF-27TRTgzVyk@kekkonen.localdomain>

Hi Umang,

On Fri, Feb 16, 2024 at 02:14:35AM +0530, Umang Jain wrote:
> From: Kieran Bingham <kieran.bingham at ideasonboard.com>
> 
> Add a v4l2 subdevice driver for the Sony IMX283 image sensor.
> 
> The IMX283 is a 20MP Diagonal 15.86 mm (Type 1) CMOS Image Sensor with
> Square Pixel for Color Cameras.
> 
> The following features are supported:
> - Manual exposure an gain control support
> - vblank/hblank/link freq control support
> - Test pattern support control
> - Arbitrary horizontal and vertical cropping
> - Supported resolution:
>   - 5472x3648 @ 20fps (SRGGB12)
>   - 5472x3648 @ 25fps (SRGGB10)
>   - 2736x1824 @ 50fps (SRGGB12)
> 
> Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
> ---
>  MAINTAINERS                |    1 +
>  drivers/media/i2c/Kconfig  |   13 +
>  drivers/media/i2c/Makefile |    1 +
>  drivers/media/i2c/imx283.c | 1601 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 1616 insertions(+)
>  create mode 100644 drivers/media/i2c/imx283.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 53df4b6e3260..3826e5c5d746 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -20373,6 +20373,7 @@ L:	linux-media at vger.kernel.org
>  S:	Maintained
>  T:	git git://linuxtv.org/media_tree.git
>  F:	Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
> +F:	drivers/media/i2c/imx283.c
>  
>  SONY IMX290 SENSOR DRIVER
>  M:	Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 56f276b920ab..b798c55a2be5 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -153,6 +153,19 @@ config VIDEO_IMX274
>  	  This is a V4L2 sensor driver for the Sony IMX274
>  	  CMOS image sensor.
>  
> +config VIDEO_IMX283
> +	tristate "Sony IMX283 sensor support"
> +	depends on I2C && VIDEO_DEV

This is already given.

> +	select MEDIA_CONTROLLER
> +	select VIDEO_V4L2_SUBDEV_API

Both are already selected, no need to do this per driver.

> +	select V4L2_CCI_I2C
> +	help
> +	  This is a V4L2 sensor driver for the Sony IMX283
> +	  CMOS image sensor.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called imx283.
> +
>  config VIDEO_IMX290
>  	tristate "Sony IMX290 sensor support"
>  	select REGMAP_I2C
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index dfbe6448b549..0fbd81f9f420 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -48,6 +48,7 @@ obj-$(CONFIG_VIDEO_IMX214) += imx214.o
>  obj-$(CONFIG_VIDEO_IMX219) += imx219.o
>  obj-$(CONFIG_VIDEO_IMX258) += imx258.o
>  obj-$(CONFIG_VIDEO_IMX274) += imx274.o
> +obj-$(CONFIG_VIDEO_IMX283) += imx283.o
>  obj-$(CONFIG_VIDEO_IMX290) += imx290.o
>  obj-$(CONFIG_VIDEO_IMX296) += imx296.o
>  obj-$(CONFIG_VIDEO_IMX319) += imx319.o
> diff --git a/drivers/media/i2c/imx283.c b/drivers/media/i2c/imx283.c
> new file mode 100644
> index 000000000000..52fafea18e7a
> --- /dev/null
> +++ b/drivers/media/i2c/imx283.c
> @@ -0,0 +1,1601 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * V4L2 Support for the IMX283
> + *
> + * Diagonal 15.86 mm (Type 1) CMOS Image Sensor with Square Pixel for Color
> + * Cameras.
> + *
> + * Copyright (C) 2024 Ideas on Board Oy.
> + *
> + * Based on Sony IMX283 driver prepared by Will Whang
> + *
> + * Based on Sony imx477 camera driver
> + * Copyright (C) 2019-2020 Raspberry Pi (Trading) Ltd
> + */
> +
> +#include <asm/unaligned.h>

Do you still need this?

> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +#include <media/v4l2-cci.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-event.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-mediabus.h>
> +
> +/* Chip ID */
> +#define IMX283_REG_CHIP_ID		CCI_REG8(0x3000)
> +#define IMX283_CHIP_ID			0x0b	// Default power on state
> +
> +#define IMX283_REG_STANDBY		CCI_REG8(0x3000)
> +#define   IMX283_ACTIVE			0
> +#define   IMX283_STANDBY		BIT(0)
> +#define   IMX283_STBLOGIC		BIT(1)
> +#define   IMX283_STBMIPI		BIT(2)
> +#define   IMX283_STBDV			BIT(3)
> +#define   IMX283_SLEEP			BIT(4)
> +
> +#define IMX283_REG_CLAMP		CCI_REG8(0x3001)
> +#define   IMX283_CLPSQRST		BIT(4)
> +
> +#define IMX283_REG_PLSTMG08		CCI_REG8(0x3003)
> +#define   IMX283_PLSTMG08_VAL		0x77
> +
> +#define IMX283_REG_MDSEL1		CCI_REG8(0x3004)
> +#define IMX283_REG_MDSEL2		CCI_REG8(0x3005)
> +#define IMX283_REG_MDSEL3		CCI_REG8(0x3006)
> +#define   IMX283_MDSEL3_VCROP_EN	BIT(5)
> +#define IMX283_REG_MDSEL4		CCI_REG8(0x3007)
> +#define   IMX283_MDSEL4_VCROP_EN	(BIT(4) | BIT(6))
> +
> +#define IMX283_REG_SVR			CCI_REG16_LE(0x3009)
> +
> +#define IMX283_REG_HTRIMMING		CCI_REG8(0x300b)
> +#define   IMX283_MDVREV			BIT(0) /* VFLIP */
> +#define   IMX283_HTRIMMING_EN		BIT(4)
> +
> +#define IMX283_REG_VWINPOS		CCI_REG16_LE(0x300f)
> +#define IMX283_REG_VWIDCUT		CCI_REG16_LE(0x3011)
> +
> +#define IMX283_REG_MDSEL7		CCI_REG16_LE(0x3013)
> +
> +/* CSI Clock Configuration */
> +#define IMX283_REG_TCLKPOST		CCI_REG8(0x3018)
> +#define IMX283_REG_THSPREPARE		CCI_REG8(0x301a)
> +#define IMX283_REG_THSZERO		CCI_REG8(0x301c)
> +#define IMX283_REG_THSTRAIL		CCI_REG8(0x3020)
> +#define IMX283_REG_TCLKPREPARE		CCI_REG8(0x3022)
> +#define IMX283_REG_TCLKZERO		CCI_REG16_LE(0x3024)
> +#define IMX283_REG_TLPX			CCI_REG8(0x3026)
> +#define IMX283_REG_THSEXIT		CCI_REG8(0x3028)
> +#define IMX283_REG_TCLKPRE		CCI_REG8(0x302a)
> +
> +#define IMX283_REG_Y_OUT_SIZE		CCI_REG16_LE(0x302f)
> +#define IMX283_REG_WRITE_VSIZE		CCI_REG16_LE(0x3031)
> +#define IMX283_REG_OB_SIZE_V		CCI_REG8(0x3033)
> +
> +/* HMAX internal HBLANK */
> +#define IMX283_REG_HMAX			CCI_REG16_LE(0x3036)
> +#define IMX283_HMAX_MAX			0xffff
> +
> +/* VMAX internal VBLANK */
> +#define IMX283_REG_VMAX			CCI_REG24_LE(0x3038)
> +#define   IMX283_VMAX_MAX		0xfffff
> +
> +/* SHR internal */
> +#define IMX283_REG_SHR			CCI_REG16_LE(0x303b)
> +#define   IMX283_SHR_MIN		11
> +
> +/*
> + * Analog gain control
> + *  Gain [dB] = -20log{(2048 - value [10:0]) /2048}
> + *  Range: 0dB to approximately +27dB
> + */
> +#define IMX283_REG_ANALOG_GAIN		CCI_REG16_LE(0x3042)
> +#define   IMX283_ANA_GAIN_MIN		0
> +#define   IMX283_ANA_GAIN_MAX		1957
> +#define   IMX283_ANA_GAIN_STEP		1
> +#define   IMX283_ANA_GAIN_DEFAULT	0x0
> +
> +/*
> + * Digital gain control
> + *  Gain [dB] = value * 6
> + *  Range: 0dB to +18db
> + */
> +#define IMX283_REG_DIGITAL_GAIN		CCI_REG8(0x3044)
> +#define IMX283_DGTL_GAIN_MIN		0
> +#define IMX283_DGTL_GAIN_MAX		3
> +#define IMX283_DGTL_GAIN_DEFAULT	0
> +#define IMX283_DGTL_GAIN_STEP		1
> +
> +#define IMX283_REG_HTRIMMING_START	CCI_REG16_LE(0x3058)
> +#define IMX283_REG_HTRIMMING_END	CCI_REG16_LE(0x305a)
> +
> +#define IMX283_REG_MDSEL18		CCI_REG16_LE(0x30f6)
> +
> +/* Master Mode Operation Control */
> +#define IMX283_REG_XMSTA		CCI_REG8(0x3105)
> +#define   IMX283_XMSTA			BIT(0)
> +
> +#define IMX283_REG_SYNCDRV		CCI_REG8(0x3107)
> +#define   IMX283_SYNCDRV_XHS_XVS	(0xa0 | 0x02)
> +#define   IMX283_SYNCDRV_HIZ		(0xa0 | 0x03)
> +
> +/* PLL Standby */
> +#define IMX283_REG_STBPL		CCI_REG8(0x320b)
> +#define  IMX283_STBPL_NORMAL		0x00
> +#define  IMX283_STBPL_STANDBY		0x03
> +
> +/* Input Frequency Setting */
> +#define IMX283_REG_PLRD1		CCI_REG8(0x36c1)
> +#define IMX283_REG_PLRD2		CCI_REG16_LE(0x36c2)
> +#define IMX283_REG_PLRD3		CCI_REG8(0x36f7)
> +#define IMX283_REG_PLRD4		CCI_REG8(0x36f8)
> +
> +#define IMX283_REG_PLSTMG02		CCI_REG8(0x36aa)
> +#define   IMX283_PLSTMG02_VAL		0x00
> +
> +#define IMX283_REG_EBD_X_OUT_SIZE	CCI_REG16_LE(0x3a54)
> +
> +/* Test pattern generator */
> +#define IMX283_REG_TPG_CTRL		CCI_REG8(0x3156)
> +#define   IMX283_TPG_CTRL_CLKEN		BIT(0)
> +#define   IMX283_TPG_CTRL_PATEN		BIT(4)
> +
> +#define IMX283_REG_TPG_PAT		CCI_REG8(0x3157)
> +#define   IMX283_TPG_PAT_ALL_000	0x00
> +#define   IMX283_TPG_PAT_ALL_FFF	0x01
> +#define   IMX283_TPG_PAT_ALL_555	0x02
> +#define   IMX283_TPG_PAT_ALL_AAA	0x03
> +#define   IMX283_TPG_PAT_H_COLOR_BARS	0x0a
> +#define   IMX283_TPG_PAT_V_COLOR_BARS	0x0b
> +
> +/* Exposure control */
> +#define IMX283_EXPOSURE_MIN		52
> +#define IMX283_EXPOSURE_STEP		1
> +#define IMX283_EXPOSURE_DEFAULT		1000
> +#define IMX283_EXPOSURE_MAX		49865
> +
> +/* Embedded metadata stream structure */
> +#define IMX283_EMBEDDED_LINE_WIDTH 16384
> +#define IMX283_NUM_EMBEDDED_LINES 1
> +
> +#define MHZ(x)				((x) * 1000 * 1000)

We have MEGA in linux/units.h. Could you use that instead of defining your
own?

> +#define IMAGE_PAD			0
> +
> +#define imx283_XCLR_MIN_DELAY_US	1000
> +#define imx283_XCLR_DELAY_RANGE_US	1000
> +
> +/* IMX283 native and active pixel array size. */
> +static const struct v4l2_rect imx283_native_area = {
> +	.top = 0,
> +	.left = 0,
> +	.width = 5592,
> +	.height = 3710,
> +};
> +
> +static const struct v4l2_rect imx283_active_area = {
> +	.top = 40,
> +	.left = 108,
> +	.width = 5472,
> +	.height = 3648,
> +};
> +
> +struct IMX283_reg_list {
> +	unsigned int num_of_regs;
> +	const struct cci_reg_sequence *regs;
> +};
> +
> +/* Mode : resolution and related config values */
> +struct imx283_mode {
> +	unsigned int mode;
> +
> +	/* Bits per pixel */
> +	unsigned int bpp;
> +
> +	/* Frame width */
> +	unsigned int width;
> +
> +	/* Frame height */
> +	unsigned int height;
> +
> +	/*
> +	 * Minimum horizontal timing in pixel-units
> +	 *
> +	 * Note that HMAX is written in 72MHz units, and the datasheet assumes a
> +	 * 720MHz link frequency. Convert datasheet values with the following:
> +	 *
> +	 * For 12 bpp modes (480Mbps) convert with:
> +	 *   hmax = [hmax in 72MHz units] * 480 / 72
> +	 *
> +	 * For 10 bpp modes (576Mbps) convert with:
> +	 *   hmax = [hmax in 72MHz units] * 576 / 72
> +	 */
> +	u64 min_hmax;
> +
> +	/* minimum V-timing in lines */
> +	u64 min_vmax;
> +
> +	/* default H-timing */
> +	u64 default_hmax;
> +
> +	/* default V-timing */
> +	u64 default_vmax;
> +
> +	/* minimum SHR */
> +	u64 min_shr;
> +

Why are all these 64-bit numbers?

> +	/* Abritrary vertical cropping */
> +	u32 veff;
> +	u32 vst;
> +	u32 vct;
> +
> +	/* Horizontal and vertical binning ratio */
> +	u8 hbin_ratio;
> +	u8 vbin_ratio;
> +
> +	/* Optical Blanking */
> +	u32 horizontal_ob;
> +	u32 vertical_ob;
> +
> +	/* Analog crop rectangle. */
> +	struct v4l2_rect crop;
> +};
> +
> +struct imx283_input_frequency {
> +	unsigned int mhz;
> +	unsigned int reg_count;
> +	struct cci_reg_sequence regs[4];
> +};
> +
> +static const struct imx283_input_frequency imx283_frequencies[] = {
> +	{
> +		.mhz = MHZ(6),
> +		.reg_count = 4,
> +		.regs = {
> +			{ IMX283_REG_PLRD1, 0x00 },
> +			{ IMX283_REG_PLRD2, 0x00f0 },
> +			{ IMX283_REG_PLRD3, 0x00 },
> +			{ IMX283_REG_PLRD4, 0xc0 },
> +		},
> +	},
> +	{
> +		.mhz = MHZ(12),
> +		.reg_count = 4,
> +		.regs = {
> +			{ IMX283_REG_PLRD1, 0x01 },
> +			{ IMX283_REG_PLRD2, 0x00f0 },
> +			{ IMX283_REG_PLRD3, 0x01 },
> +			{ IMX283_REG_PLRD4, 0xc0 },
> +		},
> +	},
> +	{
> +		.mhz = MHZ(18),
> +		.reg_count = 4,
> +		.regs = {
> +			{ IMX283_REG_PLRD1, 0x01 },
> +			{ IMX283_REG_PLRD2, 0x00a0 },
> +			{ IMX283_REG_PLRD3, 0x01 },
> +			{ IMX283_REG_PLRD4, 0x80 },
> +		},
> +	},
> +	{
> +		.mhz = MHZ(24),
> +		.reg_count = 4,
> +		.regs = {
> +			{ IMX283_REG_PLRD1, 0x02 },
> +			{ IMX283_REG_PLRD2, 0x00f0 },
> +			{ IMX283_REG_PLRD3, 0x02 },
> +			{ IMX283_REG_PLRD4, 0xc0 },
> +		},
> +	},
> +};
> +
> +enum imx283_modes {
> +	IMX283_MODE_0,
> +	IMX283_MODE_1,
> +	IMX283_MODE_1A,
> +	IMX283_MODE_1S,
> +	IMX283_MODE_2,
> +	IMX283_MODE_2A,
> +	IMX283_MODE_3,
> +	IMX283_MODE_4,
> +	IMX283_MODE_5,
> +	IMX283_MODE_6,
> +};
> +
> +struct imx283_readout_mode {
> +	u64 mdsel1;
> +	u64 mdsel2;
> +	u64 mdsel3;
> +	u64 mdsel4;
> +};
> +
> +static const struct imx283_readout_mode imx283_readout_modes[] = {
> +	/* All pixel scan modes */
> +	[IMX283_MODE_0] = { 0x04, 0x03, 0x10, 0x00 }, /* 12 bit */
> +	[IMX283_MODE_1] = { 0x04, 0x01, 0x00, 0x00 }, /* 10 bit */
> +	[IMX283_MODE_1A] = { 0x04, 0x01, 0x20, 0x50 }, /* 10 bit */
> +	[IMX283_MODE_1S] = { 0x04, 0x41, 0x20, 0x50 }, /* 10 bit */
> +
> +	/* Horizontal / Vertical 2/2-line binning */
> +	[IMX283_MODE_2] = { 0x0d, 0x11, 0x50, 0x00 }, /* 12 bit */
> +	[IMX283_MODE_2A] = { 0x0d, 0x11, 0x70, 0x50 }, /* 12 bit */
> +
> +	/* Horizontal / Vertical 3/3-line binning */
> +	[IMX283_MODE_3] = { 0x1e, 0x18, 0x10, 0x00 }, /* 12 bit */
> +
> +	/* Veritcal 2/9 subsampling, horizontal 3 binning cropping */
> +	[IMX283_MODE_4] = { 0x29, 0x18, 0x30, 0x50 }, /* 12 bit */
> +
> +	/* Vertical 2/19 subsampling binning, horizontal 3 binning */
> +	[IMX283_MODE_5] = { 0x2d, 0x18, 0x10, 0x00 }, /* 12 bit */
> +
> +	/* Vertical 2 binning horizontal 2/4, subsampling 16:9 cropping */
> +	[IMX283_MODE_6] = { 0x18, 0x21, 0x00, 0x09 }, /* 10 bit */
> +};
> +
> +static const struct cci_reg_sequence mipi_data_rate_1440Mbps[] = {
> +	/* The default register settings provide the 1440Mbps rate */
> +	{ CCI_REG8(0x36c5), 0x00 }, /* Undocumented */
> +	{ CCI_REG8(0x3ac4), 0x00 }, /* Undocumented */
> +
> +	{ CCI_REG8(0x320B), 0x00 }, /* STBPL */
> +	{ CCI_REG8(0x3018), 0xa7 }, /* TCLKPOST */
> +	{ CCI_REG8(0x301A), 0x6f }, /* THSPREPARE */
> +	{ CCI_REG8(0x301C), 0x9f }, /* THSZERO */
> +	{ CCI_REG8(0x301E), 0x5f }, /* THSTRAIL */
> +	{ CCI_REG8(0x3020), 0x5f }, /* TCLKTRAIL */
> +	{ CCI_REG8(0x3022), 0x6f }, /* TCLKPREPARE */
> +	{ CCI_REG8(0x3024), 0x7f }, /* TCLKZERO[7:0] */
> +	{ CCI_REG8(0x3025), 0x01 }, /* TCLKZERO[8] */
> +	{ CCI_REG8(0x3026), 0x4f }, /* TLPX*/
> +	{ CCI_REG8(0x3028), 0x47 }, /* THSEXIT */
> +	{ CCI_REG8(0x302A), 0x07 }, /* TCKLPRE */
> +	{ CCI_REG8(0x3104), 0x02 }, /* SYSMODE */
> +};
> +
> +static const struct cci_reg_sequence mipi_data_rate_720Mbps[] = {
> +	/* Undocumented Additions "For 720MBps" Setting */
> +	{ CCI_REG8(0x36c5), 0x01 }, /* Undocumented */
> +	{ CCI_REG8(0x3ac4), 0x01 }, /* Undocumented */
> +
> +	{ CCI_REG8(0x320B), 0x00 }, /* STBPL */
> +	{ CCI_REG8(0x3018), 0x77 }, /* TCLKPOST */
> +	{ CCI_REG8(0x301A), 0x37 }, /* THSPREPARE */
> +	{ CCI_REG8(0x301C), 0x67 }, /* THSZERO */
> +	{ CCI_REG8(0x301E), 0x37 }, /* THSTRAIL */
> +	{ CCI_REG8(0x3020), 0x37 }, /* TCLKTRAIL */
> +	{ CCI_REG8(0x3022), 0x37 }, /* TCLKPREPARE */
> +	{ CCI_REG8(0x3024), 0xDF }, /* TCLKZERO[7:0] */
> +	{ CCI_REG8(0x3025), 0x00 }, /* TCLKZERO[8] */
> +	{ CCI_REG8(0x3026), 0x2F }, /* TLPX*/
> +	{ CCI_REG8(0x3028), 0x47 }, /* THSEXIT */
> +	{ CCI_REG8(0x302A), 0x0F }, /* TCKLPRE */
> +	{ CCI_REG8(0x3104), 0x02 }, /* SYSMODE */
> +};
> +
> +static const s64 link_frequencies[] = {
> +	MHZ(720), /* 1440 Mbps lane data rate */
> +	MHZ(360), /* 720 Mbps data lane rate */
> +};
> +
> +static const struct IMX283_reg_list link_freq_reglist[] = {
> +	{ /* MHZ(720)*/

Missing space before '*'.

> +		.num_of_regs = ARRAY_SIZE(mipi_data_rate_1440Mbps),
> +		.regs = mipi_data_rate_1440Mbps,
> +	},
> +	{ /* MHZ(360) */
> +		.num_of_regs = ARRAY_SIZE(mipi_data_rate_720Mbps),
> +		.regs = mipi_data_rate_720Mbps,
> +	},
> +};
> +
> +#define CENTERED_RECTANGLE(rect, _width, _height) \
> +	{ \
> +		.left = rect.left + ((rect.width - (_width)) / 2), \
> +		.top = rect.top + ((rect.height - (_height)) / 2), \
> +		.width = (_width), \
> +		.height = (_height), \

Please align the backslashes to the same column.

> +	}
> +
> +/* Mode configs */
> +static const struct imx283_mode supported_modes_12bit[] = {
> +	{
> +		/* 20MPix 21.40 fps readout mode 0 */
> +		.mode = IMX283_MODE_0,
> +		.bpp = 12,
> +		.width = 5472,
> +		.height = 3648,
> +		.min_hmax = 5914, /* 887 @ 480MHz/72MHz */
> +		.min_vmax = 3793, /* Lines */
> +
> +		.veff = 3694,
> +		.vst = 0,
> +		.vct = 0,
> +
> +		.hbin_ratio = 1,
> +		.vbin_ratio = 1,
> +
> +		/* 20.00 FPS */
> +		.default_hmax = 6000, /* 900 @ 480MHz/72MHz */
> +		.default_vmax = 4000,
> +
> +		.min_shr = 11,
> +		.horizontal_ob = 96,
> +		.vertical_ob = 16,
> +		.crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
> +	},
> +	{
> +		/*
> +		 * Readout mode 2 : 2/2 binned mode (2736x1824)
> +		 */
> +		.mode = IMX283_MODE_2,
> +		.bpp = 12,
> +		.width = 2736,
> +		.height = 1824,
> +		.min_hmax = 1870, /* Pixels (362 * 360/72 + padding) */
> +		.min_vmax = 3840, /* Lines */
> +
> +		/* 50.00 FPS */
> +		.default_hmax = 1870, /* 362 @ 360MHz/72MHz */
> +		.default_vmax = 3960,
> +
> +		.veff = 1824,
> +		.vst = 0,
> +		.vct = 0,
> +
> +		.hbin_ratio = 2,
> +		.vbin_ratio = 2,
> +
> +		.min_shr = 12,
> +		.horizontal_ob = 48,
> +		.vertical_ob = 4,
> +
> +		.crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
> +	},
> +};
> +
> +static const struct imx283_mode supported_modes_10bit[] = {
> +	{
> +		/* 20MPix 25.48 fps readout mode 1 */
> +		.mode = IMX283_MODE_1,
> +		.bpp = 10,
> +		.width = 5472,
> +		.height = 3648,
> +		.min_hmax = 5960, /* 745 @ 576MHz / 72MHz */
> +		.min_vmax = 3793,
> +
> +		/* 25.00 FPS */
> +		.default_hmax = 1500, /* 750 @ 576MHz / 72MHz */
> +		.default_vmax = 3840,
> +
> +		.min_shr = 10,
> +		.horizontal_ob = 96,
> +		.vertical_ob = 16,
> +		.crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
> +	},
> +};
> +
> +/*
> + * The supported mbus formats.
> + */
> +static const u32 codes[] = {
> +	/* 12-bit modes. */
> +	MEDIA_BUS_FMT_SRGGB12_1X12,
> +
> +	/* 10-bit modes. */

I'd say the three comments are redundant.

> +	MEDIA_BUS_FMT_SRGGB10_1X10,
> +};
> +
> +/* regulator supplies */
> +static const char *const imx283_supply_name[] = {
> +	"vana", /* Analog (2.9V) supply */
> +	"vdig", /* Supply Voltage 2 (1.8V) supply */
> +	"vddl", /* Supply Voltage 3 (1.2V) supply */
> +};
> +
> +
> +struct imx283 {
> +	struct device *dev;
> +	struct regmap *cci;
> +
> +	const struct imx283_input_frequency *freq;
> +
> +	struct v4l2_subdev sd;
> +	struct media_pad pad;
> +
> +	unsigned int fmt_code;
> +
> +	struct clk *xclk;
> +
> +	struct gpio_desc *reset_gpio;
> +	struct regulator_bulk_data supplies[ARRAY_SIZE(imx283_supply_name)];
> +
> +	/* V4L2 Controls */
> +	struct v4l2_ctrl_handler ctrl_handler;
> +	struct v4l2_ctrl *pixel_rate;
> +	struct v4l2_ctrl *link_freq;
> +	struct v4l2_ctrl *exposure;
> +	struct v4l2_ctrl *vblank;
> +	struct v4l2_ctrl *hblank;
> +	struct v4l2_ctrl *vflip;

Please store pointers only to controls you need to access outside the
control handler's callbacks.

> +
> +	struct mutex mutex;
> +
> +	/* Current mode */
> +	const struct imx283_mode *mode;
> +
> +	unsigned long link_freq_bitmap;
> +
> +	u16 hmax;
> +	u32 vmax;
> +};
> +
> +static inline struct imx283 *to_imx283(struct v4l2_subdev *_sd)
> +{
> +	return container_of(_sd, struct imx283, sd);
> +}
> +
> +static inline void get_mode_table(unsigned int code,
> +				  const struct imx283_mode **mode_list,
> +				  unsigned int *num_modes)
> +{
> +	switch (code) {
> +	/* 12-bit */
> +	case MEDIA_BUS_FMT_SRGGB12_1X12:
> +	case MEDIA_BUS_FMT_SGRBG12_1X12:
> +	case MEDIA_BUS_FMT_SGBRG12_1X12:
> +	case MEDIA_BUS_FMT_SBGGR12_1X12:
> +		*mode_list = supported_modes_12bit;
> +		*num_modes = ARRAY_SIZE(supported_modes_12bit);
> +		break;
> +	/* 10-bit */

These two comments seem redudant, too.

> +	case MEDIA_BUS_FMT_SRGGB10_1X10:
> +	case MEDIA_BUS_FMT_SGRBG10_1X10:
> +	case MEDIA_BUS_FMT_SGBRG10_1X10:
> +	case MEDIA_BUS_FMT_SBGGR10_1X10:
> +		*mode_list = supported_modes_10bit;
> +		*num_modes = ARRAY_SIZE(supported_modes_10bit);
> +		break;
> +	default:
> +		*mode_list = NULL;
> +		*num_modes = 0;
> +	}
> +}
> +
> +/* Calculate the Pixel Rate based on the current mode */
> +static u64 imx283_pixel_rate(struct imx283 *imx283)
> +{
> +	const struct imx283_mode *mode = imx283->mode;
> +	unsigned int bpp = mode->bpp;
> +
> +	const unsigned int ddr = 2; /* Double Data Rate */
> +	const unsigned int lanes = 4; /* Only 4 lane support */
> +

Extra newlines.

> +	u64 link_frequency = link_frequencies[__ffs(imx283->link_freq_bitmap)];
> +	u64 pixel_rate = link_frequency * ddr * lanes / bpp;

	return ...;

> +
> +	return pixel_rate;
> +}
> +
> +/* Convert from a variable pixel_rate to 72 MHz clock cycles */
> +static u64 imx283_internal_clock(unsigned int pixel_rate, unsigned int pixels)
> +{
> +	/*
> +	 * Determine the following operation without overflow:
> +	 *    pixels * MHZ(72) / pixel_rate
> +	 *
> +	 * The internal clock at 72MHz and Pixel Rate (between 240 and 576MHz)
> +	 * can easily overflow this calculation, so pre-divide to simplify.
> +	 */
> +	const u32 iclk_pre = MHZ(72) / 1000000;
> +	const u32 pclk_pre = pixel_rate / 1000000;
> +
> +	return pixels * iclk_pre / pclk_pre;
> +}
> +
> +/* Internal clock (72MHz) to Pixel Rate clock (Variable) */
> +static u64 imx283_iclk_to_pix(unsigned int pixel_rate, unsigned int cycles)
> +{
> +	/*
> +	 * Determine the following operation without overflow:
> +	 *    cycles * pixel_rate / MHZ(72)
> +	 *
> +	 * The internal clock at 72MHz and Pixel Rate (between 240 and 576MHz)
> +	 * can easily overflow this calculation, so pre-divide to simplify.
> +	 */
> +	const u32 iclk_pre = MHZ(72) / 1000000;
> +	const u32 pclk_pre = pixel_rate / 1000000;
> +
> +	return cycles * pclk_pre / iclk_pre;
> +}
> +
> +/* Determine the exposure based on current hmax, vmax and a given SHR */
> +static u64 imx283_exposure(struct imx283 *imx283, u64 shr)
> +{
> +	u32 svr = 0; /* SVR feature is not currently supported */
> +	u32 hmax = imx283->hmax;
> +	u64 vmax = imx283->vmax;
> +	u32 offset;
> +	u64 numerator;
> +
> +	/* Number of clocks per internal offset period */
> +	offset = imx283->mode->mode == IMX283_MODE_0 ? 209 : 157;
> +	numerator = (vmax * (svr + 1) - shr) * hmax + offset;
> +
> +	do_div(numerator, hmax);
> +	numerator = clamp_t(u32, numerator, 0, 0xFFFFFFFF);
> +	return numerator;
> +}
> +
> +static void imx283_exposure_limits(struct imx283 *imx283,
> +				   u64 *min_exposure, u64 *max_exposure)
> +{
> +	u64 vmax = imx283->vmax;
> +	u32 svr = 0; /* SVR feature is not currently supported */
> +	u64 min_shr = imx283->mode->min_shr;
> +	u64 max_shr = (svr + 1) * vmax - 4; /* Global Shutter is not supported */
> +
> +	max_shr = min_t(u64, max_shr, 0xFFFF);
> +
> +	*min_exposure = imx283_exposure(imx283, max_shr);
> +	*max_exposure = imx283_exposure(imx283, min_shr);
> +}
> +
> +/*
> + * Integration Time [s] = [{VMAX x (SVR + 1) ? (SHR)} x HMAX + offset]
> + *                      / (72 x 10^6)
> + */
> +static u32 imx283_shr(struct imx283 *imx283, u32 exposure)
> +{
> +	u32 svr = 0; /* SVR feature is not currently supported */
> +	u32 hmax = imx283->hmax;
> +	u64 vmax = imx283->vmax;
> +	u32 shr;
> +	u64 temp;
> +
> +	/* Number of clocks per internal offset period */
> +	u32 offset = imx283->mode->mode == IMX283_MODE_0 ? 209 : 157;
> +
> +	temp = ((u64)exposure * hmax - offset);
> +	do_div(temp, hmax);
> +	shr = (u32)(vmax * (svr + 1) - temp);
> +
> +	return shr;
> +}
> +
> +static const char * const imx283_tpg_menu[] = {
> +	"Disabled",
> +	"All 000h",
> +	"All FFFh",
> +	"All 555h",
> +	"All AAAh",
> +	"Horizontal color bars",
> +	"Vertical color bars",
> +};
> +
> +static const int imx283_tpg_val[] = {
> +	IMX283_TPG_PAT_ALL_000,
> +	IMX283_TPG_PAT_ALL_000,
> +	IMX283_TPG_PAT_ALL_FFF,
> +	IMX283_TPG_PAT_ALL_555,
> +	IMX283_TPG_PAT_ALL_AAA,
> +	IMX283_TPG_PAT_H_COLOR_BARS,
> +	IMX283_TPG_PAT_V_COLOR_BARS,
> +};
> +
> +static int imx283_update_test_pattern(struct imx283 *imx283, u32 pattern_index)
> +{
> +	int ret;
> +
> +	if (pattern_index >= ARRAY_SIZE(imx283_tpg_val))
> +		return -EINVAL;
> +
> +	if (pattern_index) {
> +		ret = cci_write(imx283->cci, IMX283_REG_TPG_PAT,
> +				imx283_tpg_val[pattern_index], NULL);
> +		if (ret)
> +			return ret;
> +
> +		ret = cci_write(imx283->cci, IMX283_REG_TPG_CTRL,
> +				IMX283_TPG_CTRL_CLKEN | IMX283_TPG_CTRL_PATEN, NULL);
> +	} else {
> +		ret = cci_write(imx283->cci, IMX283_REG_TPG_CTRL, 0x00, NULL);
> +	}
> +
> +	return ret;
> +}
> +
> +static int imx283_set_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	struct imx283 *imx283 = container_of(ctrl->handler, struct imx283,
> +					     ctrl_handler);
> +	const struct imx283_mode *mode = imx283->mode;
> +	u64 shr, pixel_rate;
> +	int ret = 0;
> +
> +	/*
> +	 * The VBLANK control may change the limits of usable exposure, so check
> +	 * and adjust if necessary.
> +	 */
> +	if (ctrl->id == V4L2_CID_VBLANK) {
> +		/* Honour the VBLANK limits when setting exposure. */
> +		u64 current_exposure, max_exposure, min_exposure;
> +
> +		imx283->vmax = mode->height + ctrl->val;
> +
> +		imx283_exposure_limits(imx283, &min_exposure, &max_exposure);
> +
> +		current_exposure = imx283->exposure->val;
> +		current_exposure = clamp_t(u32, current_exposure, min_exposure,
> +					   max_exposure);
> +
> +		__v4l2_ctrl_modify_range(imx283->exposure, min_exposure,
> +					 max_exposure, 1, current_exposure);
> +	}
> +
> +	/*
> +	 * Applying V4L2 control value only happens
> +	 * when power is up for streaming
> +	 */
> +	if (pm_runtime_get_if_in_use(imx283->dev) == 0)

As you're using autosuspend, you should use the if_active variant here.

> +		return 0;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_EXPOSURE:
> +		shr = imx283_shr(imx283, ctrl->val);
> +		dev_dbg(imx283->dev, "V4L2_CID_EXPOSURE : %d - SHR: %lld\n",
> +			ctrl->val, shr);
> +		ret = cci_write(imx283->cci, IMX283_REG_SHR, shr, NULL);
> +		break;
> +
> +	case V4L2_CID_HBLANK:
> +		pixel_rate = imx283_pixel_rate(imx283);
> +		imx283->hmax = imx283_internal_clock(pixel_rate, mode->width + ctrl->val);
> +		dev_dbg(imx283->dev, "V4L2_CID_HBLANK : %d  HMAX : %d\n",
> +			ctrl->val, imx283->hmax);
> +		ret = cci_write(imx283->cci, IMX283_REG_HMAX, imx283->hmax, NULL);
> +		break;
> +
> +	case V4L2_CID_VBLANK:
> +		imx283->vmax = mode->height + ctrl->val;
> +		dev_dbg(imx283->dev, "V4L2_CID_VBLANK : %d  VMAX : %d\n",
> +			ctrl->val, imx283->vmax);
> +		ret = cci_write(imx283->cci, IMX283_REG_VMAX, imx283->vmax, NULL);
> +		break;
> +
> +	case V4L2_CID_ANALOGUE_GAIN:
> +		ret = cci_write(imx283->cci, IMX283_REG_ANALOG_GAIN, ctrl->val, NULL);
> +		break;
> +
> +	case V4L2_CID_DIGITAL_GAIN:
> +		ret = cci_write(imx283->cci, IMX283_REG_DIGITAL_GAIN, ctrl->val, NULL);
> +		break;
> +
> +	case V4L2_CID_VFLIP:
> +		/*
> +		 * VFLIP is managed by BIT(0) of IMX283_REG_HTRIMMING address, hence
> +		 * both needed to be set simulatenously.
> +		 */
> +		if (ctrl->val) {
> +			cci_write(imx283->cci, IMX283_REG_HTRIMMING,
> +				  IMX283_HTRIMMING_EN | IMX283_MDVREV, &ret);
> +		} else {
> +			cci_write(imx283->cci, IMX283_REG_HTRIMMING,
> +				  IMX283_HTRIMMING_EN, &ret);
> +		}
> +		break;
> +
> +	case V4L2_CID_TEST_PATTERN:
> +		ret = imx283_update_test_pattern(imx283, ctrl->val);
> +		break;
> +
> +	default:
> +		dev_err(imx283->dev, "ctrl(id:0x%x, val:0x%x) is not handled\n",
> +			ctrl->id, ctrl->val);
> +		break;
> +	}
> +
> +	pm_runtime_put(imx283->dev);
> +
> +	return ret;
> +}
> +
> +static const struct v4l2_ctrl_ops imx283_ctrl_ops = {
> +	.s_ctrl = imx283_set_ctrl,
> +};
> +
> +static int imx283_enum_mbus_code(struct v4l2_subdev *sd,
> +				 struct v4l2_subdev_state *sd_state,
> +				 struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	if (code->index >= (ARRAY_SIZE(codes)))

Extra parentheses.

> +		return -EINVAL;
> +
> +	code->code = codes[code->index];
> +
> +	return 0;
> +}
> +
> +static int imx283_enum_frame_size(struct v4l2_subdev *sd,
> +				  struct v4l2_subdev_state *sd_state,
> +				  struct v4l2_subdev_frame_size_enum *fse)
> +{
> +	const struct imx283_mode *mode_list;
> +	unsigned int num_modes;
> +
> +	get_mode_table(fse->code, &mode_list, &num_modes);
> +
> +	if (fse->index >= num_modes)
> +		return -EINVAL;
> +
> +	fse->min_width = mode_list[fse->index].width;
> +	fse->max_width = fse->min_width;
> +	fse->min_height = mode_list[fse->index].height;
> +	fse->max_height = fse->min_height;
> +
> +	return 0;
> +}
> +
> +static void imx283_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
> +{
> +	fmt->colorspace = V4L2_COLORSPACE_RAW;
> +	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);
> +}
> +
> +static void imx283_update_image_pad_format(struct imx283 *imx283,
> +					   const struct imx283_mode *mode,
> +					   struct v4l2_mbus_framefmt *format)
> +{
> +	format->width = mode->width;
> +	format->height = mode->height;
> +	format->field = V4L2_FIELD_NONE;
> +	imx283_reset_colorspace(format);
> +}
> +
> +static int imx283_init_state(struct v4l2_subdev *sd,
> +			     struct v4l2_subdev_state *state)
> +{
> +	struct imx283 *imx283 = to_imx283(sd);
> +	struct v4l2_mbus_framefmt *format;
> +	const struct imx283_mode *mode;
> +	struct v4l2_rect *crop;
> +
> +	/* Initialize try_fmt */
> +	format = v4l2_subdev_state_get_format(state, IMAGE_PAD);
> +
> +	mode = &supported_modes_12bit[0];
> +	imx283->mode = mode;
> +	format->code = MEDIA_BUS_FMT_SRGGB12_1X12;
> +	imx283_update_image_pad_format(imx283, mode, format);
> +
> +	/* Initialize crop rectangle to mode default */
> +	crop = v4l2_subdev_state_get_crop(state, IMAGE_PAD);
> +	*crop = mode->crop;
> +
> +	return 0;
> +}
> +
> +static void imx283_set_framing_limits(struct imx283 *imx283)
> +{
> +	const struct imx283_mode *mode = imx283->mode;
> +	u64 pixel_rate = imx283_pixel_rate(imx283);
> +	u64 min_hblank, max_hblank, def_hblank;
> +
> +	/*
> +	 * Initialise hmax and vmax for exposure calculations
> +	 */

	/* Single-line comment */

> +	imx283->hmax = imx283_internal_clock(pixel_rate, mode->default_hmax);
> +	imx283->vmax = mode->default_vmax;
> +
> +	/*
> +	 * Horizontal Blanking
> +	 * Convert the HMAX_MAX (72MHz) to Pixel rate values for HBLANK_MAX
> +	 */
> +	min_hblank = mode->min_hmax - mode->width;
> +	max_hblank = imx283_iclk_to_pix(pixel_rate, IMX283_HMAX_MAX) - mode->width;
> +	def_hblank = mode->default_hmax - mode->width;
> +	__v4l2_ctrl_modify_range(imx283->hblank, min_hblank, max_hblank, 1,
> +				 def_hblank);
> +	__v4l2_ctrl_s_ctrl(imx283->hblank, def_hblank);
> +
> +	/* Vertical Blanking */
> +	__v4l2_ctrl_modify_range(imx283->vblank, mode->min_vmax - mode->height,
> +				 IMX283_VMAX_MAX - mode->height, 1,
> +				 mode->default_vmax - mode->height);
> +	__v4l2_ctrl_s_ctrl(imx283->vblank, mode->default_vmax - mode->height);
> +}
> +
> +static int imx283_set_pad_format(struct v4l2_subdev *sd,
> +				 struct v4l2_subdev_state *sd_state,
> +				 struct v4l2_subdev_format *fmt)
> +{
> +	struct v4l2_mbus_framefmt *format;
> +	const struct imx283_mode *mode;
> +	struct imx283 *imx283 = to_imx283(sd);
> +	const struct imx283_mode *mode_list;
> +	unsigned int num_modes;
> +
> +	get_mode_table(fmt->format.code, &mode_list, &num_modes);
> +
> +	mode = v4l2_find_nearest_size(mode_list, num_modes, width, height,
> +				      fmt->format.width, fmt->format.height);
> +
> +	imx283_update_image_pad_format(imx283, mode, &fmt->format);
> +
> +	format = v4l2_subdev_state_get_format(sd_state, 0);
> +
> +	if (imx283->mode == mode && format->code == fmt->format.code)
> +		return 0;
> +
> +	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
> +		imx283->mode = mode;
> +		imx283->fmt_code = fmt->format.code;

The code is available in sub-device state.

> +		imx283_set_framing_limits(imx283);
> +	}
> +
> +	*format = fmt->format;
> +
> +	return 0;
> +}
> +
> +static int imx283_standby_cancel(struct imx283 *imx283)
> +{
> +	int ret = 0;
> +	unsigned int link_freq_idx;

Please declare ret as last.

> +
> +	cci_write(imx283->cci, IMX283_REG_STANDBY,
> +		  IMX283_STBLOGIC | IMX283_STBDV, &ret);
> +
> +	/* Configure PLL clocks based on the xclk */
> +	cci_multi_reg_write(imx283->cci, imx283->freq->regs,
> +			    imx283->freq->reg_count, &ret);
> +
> +	dev_dbg(imx283->dev, "Using clk freq %d MHz", imx283->freq->mhz / MHZ(1));
> +
> +	/* Initialise communication */
> +	cci_write(imx283->cci, IMX283_REG_PLSTMG08, IMX283_PLSTMG08_VAL, &ret);
> +	cci_write(imx283->cci, IMX283_REG_PLSTMG02, IMX283_PLSTMG02_VAL, &ret);
> +
> +	/* Enable PLL */
> +	cci_write(imx283->cci, IMX283_REG_STBPL, IMX283_STBPL_NORMAL, &ret);
> +
> +	/* Configure the MIPI link speed */
> +	link_freq_idx = __ffs(imx283->link_freq_bitmap);
> +	cci_multi_reg_write(imx283->cci,
> +			    link_freq_reglist[link_freq_idx].regs,
> +			    link_freq_reglist[link_freq_idx].num_of_regs,
> +			    &ret);
> +
> +	usleep_range(1000, 2000); /* 1st Stabilisation period of 1 ms or more */
> +
> +	/* Activate */
> +	cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_ACTIVE, &ret);
> +	usleep_range(19000, 20000); /* 2nd Stabilisation period of 19ms or more */
> +
> +	cci_write(imx283->cci, IMX283_REG_CLAMP, IMX283_CLPSQRST, &ret);
> +	cci_write(imx283->cci, IMX283_REG_XMSTA, 0, &ret);
> +	cci_write(imx283->cci, IMX283_REG_SYNCDRV, IMX283_SYNCDRV_XHS_XVS, &ret);
> +
> +	return ret;
> +}
> +
> +/* Start streaming */
> +static int imx283_start_streaming(struct imx283 *imx283,
> +				  struct v4l2_subdev_state *state)
> +{
> +	const struct imx283_readout_mode *readout;
> +	const struct imx283_mode *mode = imx283->mode;
> +	u32 v_widcut;
> +	s32 v_pos;
> +	u32 write_v_size;
> +	u32 y_out_size;
> +	int ret;
> +
> +	ret = imx283_standby_cancel(imx283);
> +	if (ret) {
> +		dev_err(imx283->dev, "failed to cancel standby\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * Set the readout mode registers.
> +	 * MDSEL3 and MDSEL4 are updated to enable Arbitrary Vertical Cropping.
> +	 */
> +	readout = &imx283_readout_modes[imx283->mode->mode];
> +	cci_write(imx283->cci, IMX283_REG_MDSEL1, readout->mdsel1, &ret);
> +	cci_write(imx283->cci, IMX283_REG_MDSEL2, readout->mdsel2, &ret);
> +	cci_write(imx283->cci, IMX283_REG_MDSEL3,
> +		  readout->mdsel3 | IMX283_MDSEL3_VCROP_EN, &ret);
> +	cci_write(imx283->cci, IMX283_REG_MDSEL4,
> +		  readout->mdsel4 | IMX283_MDSEL4_VCROP_EN, &ret);
> +
> +	/* Mode 1S specific entries from the Readout Drive Mode Tables */
> +	if (mode->mode == IMX283_MODE_1S) {
> +		cci_write(imx283->cci, IMX283_REG_MDSEL7, 0x01, &ret);
> +		cci_write(imx283->cci, IMX283_REG_MDSEL18, 0x1098, &ret);
> +	}
> +
> +	if (ret) {
> +		dev_err(imx283->dev, "%s failed to set readout\n", __func__);
> +		return ret;
> +	}
> +
> +	/* Initialise SVR. Unsupported for now - Always 0 */
> +	cci_write(imx283->cci, IMX283_REG_SVR, 0x00, &ret);
> +
> +	dev_dbg(imx283->dev, "Mode: Size %d x %d\n", mode->width, mode->height);
> +	dev_dbg(imx283->dev, "Analogue Crop (in the mode) %d,%d %dx%d\n",
> +		mode->crop.left,
> +		mode->crop.top,
> +		mode->crop.width,
> +		mode->crop.height);
> +
> +	y_out_size = mode->crop.height / mode->vbin_ratio;
> +	write_v_size = y_out_size + mode->vertical_ob;
> +	/*
> +	 * cropping start position = (VWINPOS ? Vst) ? 2
> +	 * cropping width = Veff ? (VWIDCUT ? Vct) ? 2
> +	 */
> +	v_pos = imx283->vflip->val ?
> +		((-mode->crop.top / mode->vbin_ratio) / 2) + mode->vst :
> +		((mode->crop.top / mode->vbin_ratio) / 2)  + mode->vst;
> +	v_widcut = ((mode->veff - y_out_size) / 2) + mode->vct;
> +
> +	cci_write(imx283->cci, IMX283_REG_Y_OUT_SIZE, y_out_size, &ret);
> +	cci_write(imx283->cci, IMX283_REG_WRITE_VSIZE, write_v_size, &ret);
> +	cci_write(imx283->cci, IMX283_REG_VWIDCUT, v_widcut, &ret);
> +	cci_write(imx283->cci, IMX283_REG_VWINPOS, v_pos, &ret);
> +
> +	cci_write(imx283->cci, IMX283_REG_OB_SIZE_V, mode->vertical_ob, &ret);
> +
> +	/* TODO: Validate mode->crop is fully contained within imx283_native_area */
> +	cci_write(imx283->cci, IMX283_REG_HTRIMMING_START, mode->crop.left, &ret);
> +	cci_write(imx283->cci, IMX283_REG_HTRIMMING_END,
> +		  mode->crop.left + mode->crop.width, &ret);
> +
> +	/* Disable embedded data */
> +	cci_write(imx283->cci, IMX283_REG_EBD_X_OUT_SIZE, 0, &ret);
> +
> +	/* Apply customized values from controls (HMAX/VMAX/SHR) */
> +	ret =  __v4l2_ctrl_handler_setup(imx283->sd.ctrl_handler);

	return ...;

What does actually start streaming on the sensor here?

Shouldn't the control handler's setup be called before that (and much of
what happens previous to that)?

> +
> +	return ret;
> +}
> +
> +/* Stop streaming */
> +static void imx283_stop_streaming(struct imx283 *imx283)
> +{
> +	int ret;
> +
> +	ret = cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_STBLOGIC, NULL);
> +	if (ret)
> +		dev_err(imx283->dev, "%s failed to set stream\n", __func__);
> +
> +	pm_runtime_put(imx283->dev);
> +}
> +
> +static int imx283_set_stream(struct v4l2_subdev *sd, int enable)
> +{
> +	struct imx283 *imx283 = to_imx283(sd);
> +	struct v4l2_subdev_state *state;
> +	int ret = 0;
> +
> +	state = v4l2_subdev_lock_and_get_active_state(sd);
> +
> +	if (enable) {
> +		ret = pm_runtime_get_sync(imx283->dev);
> +		if (ret < 0) {
> +			pm_runtime_put_noidle(imx283->dev);
> +			goto unlock;
> +		}
> +
> +		/*
> +		 * Apply default & customized values
> +		 * and then start streaming.
> +		 */
> +		ret = imx283_start_streaming(imx283, state);
> +		if (ret)
> +			goto err_rpm_put;
> +	} else {
> +		imx283_stop_streaming(imx283);
> +	}
> +
> +	v4l2_subdev_unlock_state(state);
> +
> +	return ret;
> +
> +err_rpm_put:
> +	pm_runtime_put(imx283->dev);
> +unlock:
> +	v4l2_subdev_unlock_state(state);
> +
> +	return ret;
> +}
> +
> +/* Power/clock management functions */
> +static int imx283_power_on(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct imx283 *imx283 = to_imx283(sd);
> +	int ret;
> +
> +	ret = regulator_bulk_enable(ARRAY_SIZE(imx283_supply_name),
> +				    imx283->supplies);
> +	if (ret) {
> +		dev_err(imx283->dev, "%s: failed to enable regulators\n",
> +			__func__);
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(imx283->xclk);
> +	if (ret) {
> +		dev_err(imx283->dev, "%s: failed to enable clock\n",
> +			__func__);
> +		goto reg_off;
> +	}
> +
> +	gpiod_set_value_cansleep(imx283->reset_gpio, 1);
> +
> +	usleep_range(imx283_XCLR_MIN_DELAY_US,
> +		     imx283_XCLR_MIN_DELAY_US + imx283_XCLR_DELAY_RANGE_US);
> +
> +	return 0;
> +
> +reg_off:
> +	regulator_bulk_disable(ARRAY_SIZE(imx283_supply_name), imx283->supplies);
> +	return ret;
> +}
> +
> +static int imx283_power_off(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct imx283 *imx283 = to_imx283(sd);
> +
> +	gpiod_set_value_cansleep(imx283->reset_gpio, 0);
> +	regulator_bulk_disable(ARRAY_SIZE(imx283_supply_name), imx283->supplies);
> +	clk_disable_unprepare(imx283->xclk);
> +
> +	return 0;
> +}
> +
> +static int imx283_get_regulators(struct imx283 *imx283)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(imx283_supply_name); i++)
> +		imx283->supplies[i].supply = imx283_supply_name[i];
> +
> +	return devm_regulator_bulk_get(imx283->dev,
> +				       ARRAY_SIZE(imx283_supply_name),
> +				       imx283->supplies);
> +}
> +
> +/* Verify chip ID */
> +static int imx283_identify_module(struct imx283 *imx283)
> +{
> +	int ret;
> +	u64 val;
> +
> +	ret = cci_read(imx283->cci, IMX283_REG_CHIP_ID, &val, NULL);
> +	if (ret) {
> +		dev_err(imx283->dev, "failed to read chip id %x, with error %d\n",
> +			IMX283_CHIP_ID, ret);
> +		return ret;
> +	}
> +
> +	if (val != IMX283_CHIP_ID) {
> +		dev_err(imx283->dev, "chip id mismatch: %x!=%llx\n",
> +			IMX283_CHIP_ID, val);
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static int imx283_get_selection(struct v4l2_subdev *sd,
> +				struct v4l2_subdev_state *sd_state,
> +				struct v4l2_subdev_selection *sel)
> +{
> +	switch (sel->target) {
> +	case V4L2_SEL_TGT_CROP: {
> +		sel->r = *v4l2_subdev_state_get_crop(sd_state, 0);
> +		return 0;
> +	}
> +
> +	case V4L2_SEL_TGT_NATIVE_SIZE:
> +		sel->r = imx283_native_area;
> +		return 0;
> +
> +	case V4L2_SEL_TGT_CROP_DEFAULT:
> +	case V4L2_SEL_TGT_CROP_BOUNDS:
> +		sel->r = imx283_active_area;
> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct v4l2_subdev_core_ops imx283_core_ops = {
> +	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> +	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
> +};
> +
> +static const struct v4l2_subdev_video_ops imx283_video_ops = {
> +	.s_stream = imx283_set_stream,
> +};
> +
> +static const struct v4l2_subdev_pad_ops imx283_pad_ops = {
> +	.enum_mbus_code = imx283_enum_mbus_code,
> +	.get_fmt = v4l2_subdev_get_fmt,
> +	.set_fmt = imx283_set_pad_format,
> +	.get_selection = imx283_get_selection,
> +	.enum_frame_size = imx283_enum_frame_size,
> +};
> +
> +static const struct v4l2_subdev_internal_ops imx283_internal_ops = {
> +	.init_state = imx283_init_state,
> +};
> +
> +static const struct v4l2_subdev_ops imx283_subdev_ops = {
> +	.core = &imx283_core_ops,
> +	.video = &imx283_video_ops,
> +	.pad = &imx283_pad_ops,
> +};
> +
> +/* Initialize control handlers */
> +static int imx283_init_controls(struct imx283 *imx283)
> +{
> +	struct v4l2_ctrl_handler *ctrl_hdlr;
> +	struct v4l2_fwnode_device_properties props;
> +	const struct imx283_mode *mode = imx283->mode;
> +	u64 min_hblank, max_hblank, def_hblank;
> +	u64 pixel_rate;
> +	int ret;
> +
> +	ctrl_hdlr = &imx283->ctrl_handler;
> +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16);
> +	if (ret)
> +		return ret;
> +
> +	/* Serialize controls with sensor device */
> +	ctrl_hdlr->lock = &imx283->mutex;
> +
> +	/*
> +	 * Create the controls here, but mode specific limits are setup
> +	 * in the imx283_set_framing_limits() call below.
> +	 */
> +
> +	/* By default, PIXEL_RATE is read only */
> +	pixel_rate = imx283_pixel_rate(imx283);
> +	imx283->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
> +					       V4L2_CID_PIXEL_RATE, pixel_rate,
> +					       pixel_rate, 1, pixel_rate);
> +
> +	imx283->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx283_ctrl_ops,
> +						   V4L2_CID_LINK_FREQ,
> +						   __fls(imx283->link_freq_bitmap),
> +						   __ffs(imx283->link_freq_bitmap),
> +						   link_frequencies);
> +	if (imx283->link_freq)
> +		imx283->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> +	/* Initialise vblank/hblank/exposure based on the current mode. */
> +	imx283->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
> +					   V4L2_CID_VBLANK,
> +					   mode->min_vmax - mode->height,
> +					   IMX283_VMAX_MAX, 1,
> +					   mode->default_vmax - mode->height);
> +
> +	min_hblank = mode->min_hmax - mode->width;
> +	max_hblank = imx283_iclk_to_pix(pixel_rate, IMX283_HMAX_MAX) - mode->width;
> +	def_hblank = mode->default_hmax - mode->width;
> +	imx283->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
> +					   V4L2_CID_HBLANK, min_hblank, max_hblank,
> +					   1, def_hblank);
> +
> +	imx283->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
> +					     V4L2_CID_EXPOSURE,
> +					     IMX283_EXPOSURE_MIN,
> +					     IMX283_EXPOSURE_MAX,
> +					     IMX283_EXPOSURE_STEP,
> +					     IMX283_EXPOSURE_DEFAULT);
> +
> +	v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
> +			  IMX283_ANA_GAIN_MIN, IMX283_ANA_GAIN_MAX,
> +			  IMX283_ANA_GAIN_STEP, IMX283_ANA_GAIN_DEFAULT);
> +
> +	v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
> +			  IMX283_DGTL_GAIN_MIN, IMX283_DGTL_GAIN_MAX,
> +			  IMX283_DGTL_GAIN_STEP, IMX283_DGTL_GAIN_DEFAULT);
> +
> +	imx283->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_VFLIP,
> +					  0, 1, 1, 0);
> +	if (imx283->vflip)
> +		imx283->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
> +
> +	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx283_ctrl_ops,
> +				     V4L2_CID_TEST_PATTERN,
> +				     ARRAY_SIZE(imx283_tpg_menu) - 1,
> +				     0, 0, imx283_tpg_menu);
> +
> +	if (ctrl_hdlr->error) {
> +		ret = ctrl_hdlr->error;
> +		dev_err(imx283->dev, "%s control init failed (%d)\n",
> +			__func__, ret);
> +		goto error;
> +	}
> +
> +	ret = v4l2_fwnode_device_parse(imx283->dev, &props);
> +	if (ret)
> +		goto error;
> +
> +	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx283_ctrl_ops,
> +					      &props);
> +	if (ret)
> +		goto error;
> +
> +	imx283->sd.ctrl_handler = ctrl_hdlr;
> +
> +	mutex_lock(&imx283->mutex);
> +
> +	ret = __v4l2_ctrl_s_ctrl(imx283->link_freq,
> +				 __ffs(imx283->link_freq_bitmap));

Is this needed? The default is already set when creating the control.

> +	if (ret)
> +		goto error;
> +
> +	/* Setup exposure and frame/line length limits. */
> +	imx283_set_framing_limits(imx283);
> +
> +	mutex_unlock(&imx283->mutex);
> +
> +	return 0;
> +
> +error:
> +	v4l2_ctrl_handler_free(ctrl_hdlr);
> +
> +	return ret;
> +}
> +
> +static void imx283_free_controls(struct imx283 *imx283)
> +{
> +	v4l2_ctrl_handler_free(imx283->sd.ctrl_handler);

You could call v4l2_ctrl_handler_free() directly.

> +}
> +
> +static const struct of_device_id imx283_dt_ids[] = {
> +	{ .compatible = "sony,imx283", },
> +	{ /* sentinel */ }
> +};
> +
> +static int imx283_parse_endpoint(struct imx283 *imx283)
> +{
> +	struct fwnode_handle *fwnode = dev_fwnode(imx283->dev);
> +	struct v4l2_fwnode_endpoint bus_cfg = {
> +		.bus_type = V4L2_MBUS_CSI2_DPHY
> +	};
> +	struct fwnode_handle *ep;
> +	int ret;
> +
> +	if (!fwnode)
> +		return -ENXIO;
> +
> +	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> +	if (!ep) {
> +		dev_err(imx283->dev, "Failed to get next endpoint\n");
> +		return -ENXIO;
> +	}
> +
> +	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> +	fwnode_handle_put(ep);
> +	if (ret)
> +		return ret;
> +
> +	if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
> +		dev_err(imx283->dev,
> +			"number of CSI2 data lanes %d is not supported\n",
> +			bus_cfg.bus.mipi_csi2.num_data_lanes);
> +		ret = -EINVAL;
> +		goto done_endpoint_free;
> +	}
> +
> +	ret = v4l2_link_freq_to_bitmap(imx283->dev, bus_cfg.link_frequencies,
> +				       bus_cfg.nr_of_link_frequencies,
> +				       link_frequencies, ARRAY_SIZE(link_frequencies),
> +				       &imx283->link_freq_bitmap);
> +
> +done_endpoint_free:
> +	v4l2_fwnode_endpoint_free(&bus_cfg);
> +
> +	return ret;
> +};
> +
> +static int imx283_probe(struct i2c_client *client)
> +{
> +	struct imx283 *imx283;
> +	int ret;

Please declare ret as last.

> +	unsigned int i;
> +	unsigned int xclk_freq;
> +
> +	imx283 = devm_kzalloc(&client->dev, sizeof(*imx283), GFP_KERNEL);
> +	if (!imx283)
> +		return -ENOMEM;
> +
> +	imx283->dev = &client->dev;
> +
> +	v4l2_i2c_subdev_init(&imx283->sd, client, &imx283_subdev_ops);
> +
> +	imx283->cci = devm_cci_regmap_init_i2c(client, 16);
> +	if (IS_ERR(imx283->cci)) {
> +		ret = PTR_ERR(imx283->cci);
> +		dev_err(imx283->dev, "failed to initialize CCI: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* Get system clock (xclk) */
> +	imx283->xclk = devm_clk_get(imx283->dev, NULL);
> +	if (IS_ERR(imx283->xclk)) {
> +		dev_err(imx283->dev, "failed to get xclk\n");
> +		return PTR_ERR(imx283->xclk);
> +	}
> +
> +	xclk_freq = clk_get_rate(imx283->xclk);
> +	for (i = 0; i < ARRAY_SIZE(imx283_frequencies); i++) {
> +		if (xclk_freq == imx283_frequencies[i].mhz) {
> +			imx283->freq = &imx283_frequencies[i];
> +			break;
> +		}
> +	}
> +	if (!imx283->freq) {
> +		dev_err(imx283->dev, "xclk frequency unsupported: %d Hz\n", xclk_freq);

You could also pick the closest value and warn about it, these aren't
always exactly what's expected. Up to you.

> +		return -EINVAL;
> +	}
> +
> +	ret = imx283_get_regulators(imx283);
> +	if (ret) {
> +		dev_err(imx283->dev, "failed to get regulators\n");
> +		return ret;
> +	}
> +
> +	ret = imx283_parse_endpoint(imx283);
> +	if (ret) {
> +		dev_err(imx283->dev, "failed to parse endpoint configuration\n");
> +		return ret;
> +	}
> +
> +	/* Request optional enable pin */
> +	imx283->reset_gpio = devm_gpiod_get_optional(imx283->dev, "reset",
> +						     GPIOD_OUT_HIGH);
> +
> +	mutex_init(&imx283->mutex);
> +
> +	/*
> +	 * The sensor must be powered for imx283_identify_module()
> +	 * to be able to read the CHIP_ID register
> +	 */
> +	ret = imx283_power_on(imx283->dev);
> +	if (ret)

mutex_destroy() is missing on this code path (and elsewhere, too).

> +		return ret;
> +
> +	ret = imx283_identify_module(imx283);
> +	if (ret)
> +		goto error_power_off;
> +
> +	/* Initialize default format and mode to max resolution */
> +	imx283->mode = &supported_modes_12bit[0];
> +	imx283->fmt_code = MEDIA_BUS_FMT_SRGGB12_1X12;
> +
> +	/*
> +	 * Enable runtime PM with autosuspend. As the device has been powered
> +	 * manually, mark it as active, and increase the usage count without
> +	 * resuming the device.
> +	 */
> +	pm_runtime_set_active(imx283->dev);
> +	pm_runtime_get_noresume(imx283->dev);
> +	pm_runtime_enable(imx283->dev);
> +	pm_runtime_set_autosuspend_delay(imx283->dev, 1000);
> +	pm_runtime_use_autosuspend(imx283->dev);
> +
> +	/* This needs the pm runtime to be registered. */
> +	ret = imx283_init_controls(imx283);
> +	if (ret)
> +		goto error_pm;
> +
> +	/* Initialize subdev */
> +	imx283->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> +			    V4L2_SUBDEV_FL_HAS_EVENTS;
> +	imx283->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +	imx283->sd.internal_ops = &imx283_internal_ops;
> +
> +	/* Initialize source pads */
> +	imx283->pad.flags = MEDIA_PAD_FL_SOURCE;
> +
> +	ret = media_entity_pads_init(&imx283->sd.entity, 1, &imx283->pad);
> +	if (ret) {
> +		dev_err(imx283->dev, "failed to init entity pads: %d\n", ret);
> +		goto error_handler_free;
> +	}
> +
> +	imx283->sd.state_lock = imx283->ctrl_handler.lock;
> +	ret = v4l2_subdev_init_finalize(&imx283->sd);
> +	if (ret < 0) {
> +		dev_err(imx283->dev, "subdev init error: %d\n", ret);
> +		goto error_media_entity;
> +	}
> +
> +	ret = v4l2_async_register_subdev_sensor(&imx283->sd);
> +	if (ret < 0) {
> +		dev_err(imx283->dev, "failed to register sensor sub-device: %d\n", ret);
> +		goto error_subdev_cleanup;
> +	}
> +
> +	return 0;
> +
> +error_subdev_cleanup:
> +	v4l2_subdev_cleanup(&imx283->sd);
> +
> +error_media_entity:
> +	media_entity_cleanup(&imx283->sd.entity);
> +
> +error_handler_free:
> +	imx283_free_controls(imx283);
> +
> +error_pm:
> +	pm_runtime_disable(imx283->dev);
> +	pm_runtime_set_suspended(imx283->dev);
> +error_power_off:
> +	imx283_power_off(imx283->dev);
> +
> +	return ret;
> +}
> +
> +static void imx283_remove(struct i2c_client *client)
> +{
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct imx283 *imx283 = to_imx283(sd);
> +
> +	v4l2_async_unregister_subdev(sd);
> +	v4l2_subdev_cleanup(&imx283->sd);
> +	media_entity_cleanup(&sd->entity);
> +	imx283_free_controls(imx283);
> +
> +	pm_runtime_disable(imx283->dev);
> +	if (!pm_runtime_status_suspended(imx283->dev))
> +		imx283_power_off(imx283->dev);
> +	pm_runtime_set_suspended(imx283->dev);
> +}
> +
> +MODULE_DEVICE_TABLE(of, imx283_dt_ids);
> +
> +static const struct dev_pm_ops imx283_pm_ops = {
> +	SET_RUNTIME_PM_OPS(imx283_power_off, imx283_power_on, NULL)
> +};
> +
> +static struct i2c_driver imx283_i2c_driver = {
> +	.driver = {
> +		.name = "imx283",
> +		.of_match_table	= imx283_dt_ids,
> +		.pm = &imx283_pm_ops,
> +	},
> +	.probe = imx283_probe,
> +	.remove = imx283_remove,
> +};
> +
> +module_i2c_driver(imx283_i2c_driver);
> +
> +MODULE_AUTHOR("Will Whang <will at willwhang.com>");
> +MODULE_AUTHOR("Kieran Bingham <kieran.bingham at ideasonboard.com>");
> +MODULE_AUTHOR("Umang Jain <umang.jain at ideasonboard.com>");
> +MODULE_DESCRIPTION("Sony IMX283 Sensor Driver");
> +MODULE_LICENSE("GPL");

-- 
Kind regards,

Sakari Ailus


From sakari.ailus at linux.intel.com  Fri Feb 16 01:23:50 2024
From: sakari.ailus at linux.intel.com (Sakari Ailus)
Date: Fri, 16 Feb 2024 09:23:50 +0000
Subject: [PATCH 1/2] media: dt-bindings: media: Add bindings for IMX283
In-Reply-To: <55d41858-b567-4e23-8d84-3af81b52d018@linaro.org>
References: <20240215204436.9194-1-umang.jain@ideasonboard.com>
 <20240215204436.9194-2-umang.jain@ideasonboard.com>
 <55d41858-b567-4e23-8d84-3af81b52d018@linaro.org>
Message-ID: <Zc8ppr4mE8ZgVNUs@kekkonen.localdomain>

Hi Krzysztof, Umang,

On Fri, Feb 16, 2024 at 09:03:49AM +0100, Krzysztof Kozlowski wrote:
> > +        properties:
> > +          data-lanes: true
> 
> Provide constraints - which lanes/how many.

Very probably only the number matters on this device. Therefore minimum and
maximum should suffice. (Or an enum. 3 is probably an invalid number of
lanes here, too.)

-- 
Kind regards,

Sakari Ailus


From adrian.hunter at intel.com  Fri Feb 16 01:31:28 2024
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Fri, 16 Feb 2024 11:31:28 +0200
Subject: [PATCH V6] perf/core: Add aux_pause, aux_resume, aux_start_paused
In-Reply-To: <05ac66fc-ddda-46ff-b08d-c15943c16bc1@intel.com>
References: <05ac66fc-ddda-46ff-b08d-c15943c16bc1@intel.com>
Message-ID: <20240216093128.77452-1-adrian.hunter@intel.com>

Hardware traces, such as instruction traces, can produce a vast amount of
trace data, so being able to reduce tracing to more specific circumstances
can be useful.

The ability to pause or resume tracing when another event happens, can do
that.

Add ability for an event to "pause" or "resume" AUX area tracing.

Add aux_pause bit to perf_event_attr to indicate that, if the event
happens, the associated AUX area tracing should be paused. Ditto
aux_resume. Do not allow aux_pause and aux_resume to be set together.

Add aux_start_paused bit to perf_event_attr to indicate to an AUX area
event that it should start in a "paused" state.

Add aux_paused to struct perf_event for AUX area events to keep track of
the "paused" state. aux_paused is initialized to aux_start_paused.

Add PERF_EF_PAUSE and PERF_EF_RESUME modes for ->stop() and ->start()
callbacks. Call as needed, during __perf_event_output(). Add
aux_in_pause_resume to struct perf_buffer to prevent races with the NMI
handler. Pause/resume in NMI context will miss out if it coincides with
another pause/resume.

To use aux_pause or aux_resume, an event must be in a group with the AUX
area event as the group leader.

Example (requires Intel PT and tools patches also):

 $ perf record --kcore -e intel_pt/aux-action=start-paused/k,syscalls:sys_enter_newuname/aux-action=resume/,syscalls:sys_exit_newuname/aux-action=pause/ uname
 Linux
 [ perf record: Woken up 1 times to write data ]
 [ perf record: Captured and wrote 0.043 MB perf.data ]
 $ perf script --call-trace
 uname   30805 [000] 24001.058782799: name: 0x7ffc9c1865b0
 uname   30805 [000] 24001.058784424:  psb offs: 0
 uname   30805 [000] 24001.058784424:  cbr: 39 freq: 3904 MHz (139%)
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])        debug_smp_processor_id
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])        __x64_sys_newuname
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])            down_read
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                __cond_resched
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                preempt_count_add
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                    in_lock_functions
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                preempt_count_sub
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])            up_read
 uname   30805 [000] 24001.058784629: ([kernel.kallsyms])                preempt_count_add
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                    in_lock_functions
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                preempt_count_sub
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])            _copy_to_user
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])        syscall_exit_to_user_mode
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])            syscall_exit_work
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                perf_syscall_exit
 uname   30805 [000] 24001.058784838: ([kernel.kallsyms])                    debug_smp_processor_id
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                    perf_trace_buf_alloc
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        perf_swevent_get_recursion_context
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            debug_smp_processor_id
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        debug_smp_processor_id
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                    perf_tp_event
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        perf_trace_buf_update
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            tracing_gen_ctx_irq_test
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                        perf_swevent_event
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            __perf_event_account_interrupt
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                __this_cpu_preempt_check
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                            perf_event_output_forward
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                perf_event_aux_pause
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                    ring_buffer_get
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                        __rcu_read_lock
 uname   30805 [000] 24001.058785046: ([kernel.kallsyms])                                        __rcu_read_unlock
 uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                    pt_event_stop
 uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                        debug_smp_processor_id
 uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                        debug_smp_processor_id
 uname   30805 [000] 24001.058785254: ([kernel.kallsyms])                                        native_write_msr
 uname   30805 [000] 24001.058785463: ([kernel.kallsyms])                                        native_write_msr
 uname   30805 [000] 24001.058785639: 0x0

Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Acked-by: James Clark <james.clark at arm.com>
---


Changes in V6:
	Removed READ/WRITE_ONCEfrom __perf_event_aux_pause()
	Expanded comment about guarding against NMI

Changes in V5:
	Added James' Ack

Changes in V4:
	Rename aux_output_cfg -> aux_action
	Reorder aux_action bits from:
		aux_pause, aux_resume, aux_start_paused
	to:
		aux_start_paused, aux_pause, aux_resume
	Fix aux_action bits __u64 -> __u32


 include/linux/perf_event.h      | 15 +++++++
 include/uapi/linux/perf_event.h | 11 ++++-
 kernel/events/core.c            | 76 +++++++++++++++++++++++++++++++--
 kernel/events/internal.h        |  1 +
 4 files changed, 99 insertions(+), 4 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index d2a15c0c6f8a..6c1600b9bdb3 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -291,6 +291,7 @@ struct perf_event_pmu_context;
 #define PERF_PMU_CAP_NO_EXCLUDE			0x0040
 #define PERF_PMU_CAP_AUX_OUTPUT			0x0080
 #define PERF_PMU_CAP_EXTENDED_HW_TYPE		0x0100
+#define PERF_PMU_CAP_AUX_PAUSE			0x0200
 
 struct perf_output_handle;
 
@@ -363,6 +364,8 @@ struct pmu {
 #define PERF_EF_START	0x01		/* start the counter when adding    */
 #define PERF_EF_RELOAD	0x02		/* reload the counter when starting */
 #define PERF_EF_UPDATE	0x04		/* update the counter when stopping */
+#define PERF_EF_PAUSE	0x08		/* AUX area event, pause tracing */
+#define PERF_EF_RESUME	0x10		/* AUX area event, resume tracing */
 
 	/*
 	 * Adds/Removes a counter to/from the PMU, can be done inside a
@@ -402,6 +405,15 @@ struct pmu {
 	 *
 	 * ->start() with PERF_EF_RELOAD will reprogram the counter
 	 *  value, must be preceded by a ->stop() with PERF_EF_UPDATE.
+	 *
+	 * ->stop() with PERF_EF_PAUSE will stop as simply as possible. Will not
+	 * overlap another ->stop() with PERF_EF_PAUSE nor ->start() with
+	 * PERF_EF_RESUME.
+	 *
+	 * ->start() with PERF_EF_RESUME will start as simply as possible but
+	 * only if the counter is not otherwise stopped. Will not overlap
+	 * another ->start() with PERF_EF_RESUME nor ->stop() with
+	 * PERF_EF_PAUSE.
 	 */
 	void (*start)			(struct perf_event *event, int flags);
 	void (*stop)			(struct perf_event *event, int flags);
@@ -798,6 +810,9 @@ struct perf_event {
 	/* for aux_output events */
 	struct perf_event		*aux_event;
 
+	/* for AUX area events */
+	unsigned int			aux_paused;
+
 	void (*destroy)(struct perf_event *);
 	struct rcu_head			rcu_head;
 
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 3a64499b0f5d..0c557f0a17b3 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -511,7 +511,16 @@ struct perf_event_attr {
 	__u16	sample_max_stack;
 	__u16	__reserved_2;
 	__u32	aux_sample_size;
-	__u32	__reserved_3;
+
+	union {
+		__u32	aux_action;
+		struct {
+			__u32	aux_start_paused :  1, /* start AUX area tracing paused */
+				aux_pause        :  1, /* on overflow, pause AUX area tracing */
+				aux_resume       :  1, /* on overflow, resume AUX area tracing */
+				__reserved_3     : 29;
+		};
+	};
 
 	/*
 	 * User provided data if sigtrap=1, passed back to user via
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f0f0f71213a1..c7ed4e64f1d8 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -2097,7 +2097,8 @@ static void perf_put_aux_event(struct perf_event *event)
 
 static bool perf_need_aux_event(struct perf_event *event)
 {
-	return !!event->attr.aux_output || !!event->attr.aux_sample_size;
+	return event->attr.aux_output || event->attr.aux_sample_size ||
+	       event->attr.aux_pause || event->attr.aux_resume;
 }
 
 static int perf_get_aux_event(struct perf_event *event,
@@ -2122,6 +2123,10 @@ static int perf_get_aux_event(struct perf_event *event,
 	    !perf_aux_output_match(event, group_leader))
 		return 0;
 
+	if ((event->attr.aux_pause || event->attr.aux_resume) &&
+	    !(group_leader->pmu->capabilities & PERF_PMU_CAP_AUX_PAUSE))
+		return 0;
+
 	if (event->attr.aux_sample_size && !group_leader->pmu->snapshot_aux)
 		return 0;
 
@@ -7854,6 +7859,51 @@ void perf_prepare_header(struct perf_event_header *header,
 	WARN_ON_ONCE(header->size & 7);
 }
 
+static void __perf_event_aux_pause(struct perf_event *event, bool pause)
+{
+	if (pause) {
+		if (!event->aux_paused) {
+			event->aux_paused = 1;
+			event->pmu->stop(event, PERF_EF_PAUSE);
+		}
+	} else {
+		if (event->aux_paused) {
+			event->aux_paused = 0;
+			event->pmu->start(event, PERF_EF_RESUME);
+		}
+	}
+}
+
+static void perf_event_aux_pause(struct perf_event *event, bool pause)
+{
+	struct perf_buffer *rb;
+	unsigned long flags;
+
+	if (WARN_ON_ONCE(!event))
+		return;
+
+	rb = ring_buffer_get(event);
+	if (!rb)
+		return;
+
+	local_irq_save(flags);
+	/*
+	 * Guard against NMI, NMI loses here. The critical setion is demarked by
+	 * rb->aux_in_pause_resume == 1. An NMI in the critical section will not
+	 * process a pause/resume.
+	 */
+	if (READ_ONCE(rb->aux_in_pause_resume))
+		goto out_restore;
+	WRITE_ONCE(rb->aux_in_pause_resume, 1);
+	barrier();
+	__perf_event_aux_pause(event, pause);
+	barrier();
+	WRITE_ONCE(rb->aux_in_pause_resume, 0);
+out_restore:
+	local_irq_restore(flags);
+	ring_buffer_put(rb);
+}
+
 static __always_inline int
 __perf_event_output(struct perf_event *event,
 		    struct perf_sample_data *data,
@@ -7867,6 +7917,9 @@ __perf_event_output(struct perf_event *event,
 	struct perf_event_header header;
 	int err;
 
+	if (event->attr.aux_pause)
+		perf_event_aux_pause(event->aux_event, true);
+
 	/* protect the callchain buffers */
 	rcu_read_lock();
 
@@ -7883,6 +7936,10 @@ __perf_event_output(struct perf_event *event,
 
 exit:
 	rcu_read_unlock();
+
+	if (event->attr.aux_resume)
+		perf_event_aux_pause(event->aux_event, false);
+
 	return err;
 }
 
@@ -12036,10 +12093,23 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
 	}
 
 	if (event->attr.aux_output &&
-	    !(pmu->capabilities & PERF_PMU_CAP_AUX_OUTPUT)) {
+	    (!(pmu->capabilities & PERF_PMU_CAP_AUX_OUTPUT) ||
+	     event->attr.aux_pause || event->attr.aux_resume)) {
+		err = -EOPNOTSUPP;
+		goto err_pmu;
+	}
+
+	if (event->attr.aux_pause && event->attr.aux_resume) {
+		err = -EINVAL;
+		goto err_pmu;
+	}
+
+	if (event->attr.aux_start_paused &&
+	    !(pmu->capabilities & PERF_PMU_CAP_AUX_PAUSE)) {
 		err = -EOPNOTSUPP;
 		goto err_pmu;
 	}
+	event->aux_paused = event->attr.aux_start_paused;
 
 	if (cgroup_fd != -1) {
 		err = perf_cgroup_connect(cgroup_fd, event, attr, group_leader);
@@ -12836,7 +12906,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
 	 * Grouping is not supported for kernel events, neither is 'AUX',
 	 * make sure the caller's intentions are adjusted.
 	 */
-	if (attr->aux_output)
+	if (attr->aux_output || attr->aux_action)
 		return ERR_PTR(-EINVAL);
 
 	event = perf_event_alloc(attr, cpu, task, NULL, NULL,
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index 5150d5f84c03..3320f78117dc 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -51,6 +51,7 @@ struct perf_buffer {
 	void				(*free_aux)(void *);
 	refcount_t			aux_refcount;
 	int				aux_in_sampling;
+	int				aux_in_pause_resume;
 	void				**aux_pages;
 	void				*aux_priv;
 
-- 
2.34.1



From s-vadapalli at ti.com  Fri Feb 16 01:34:11 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Fri, 16 Feb 2024 15:04:11 +0530
Subject: [PATCH v3 15/18] PCI: cadence: extract link setup sequence from
 cdns_pcie_host_setup()
In-Reply-To: <20240102-j7200-pcie-s2r-v3-15-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-15-5c2e4a3fac1f@bootlin.com>
Message-ID: <72300ba5-1db2-4bbb-a797-d1b547001ddb@ti.com>

On 24/02/15 04:18PM, Thomas Richard wrote:
> The function cdns_pcie_host_setup() mixes probe structure and link setup.
> 
> The link setup must be done during the resume sequence. So extract it from
> cdns_pcie_host_setup() and create a dedicated function.
> 
> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>

LGTM.

Reviewed-by: Siddharth Vadapalli <s-vadapalli at ti.com>

Regards,
Siddharth.

> ---
>  drivers/pci/controller/cadence/pcie-cadence-host.c | 39 ++++++++++++++--------
>  drivers/pci/controller/cadence/pcie-cadence.h      |  6 ++++
>  2 files changed, 32 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
> index 5b14f7ee3c79..93d9922730af 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence-host.c
> +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
> @@ -497,6 +497,30 @@ static int cdns_pcie_host_init(struct device *dev,
>  	return cdns_pcie_host_init_address_translation(rc);
>  }
>  
> +int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
> +{
> +	struct cdns_pcie *pcie = &rc->pcie;
> +	struct device *dev = rc->pcie.dev;
> +	int ret;
> +
> +	if (rc->quirk_detect_quiet_flag)
> +		cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
> +
> +	cdns_pcie_host_enable_ptm_response(pcie);
> +
> +	ret = cdns_pcie_start_link(pcie);
> +	if (ret) {
> +		dev_err(dev, "Failed to start link\n");
> +		return ret;
> +	}
> +
> +	ret = cdns_pcie_host_start_link(rc);
> +	if (ret)
> +		dev_dbg(dev, "PCIe link never came up\n");
> +
> +	return 0;
> +}
> +
>  int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
>  {
>  	struct device *dev = rc->pcie.dev;
> @@ -533,20 +557,9 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
>  		return PTR_ERR(rc->cfg_base);
>  	rc->cfg_res = res;
>  
> -	if (rc->quirk_detect_quiet_flag)
> -		cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
> -
> -	cdns_pcie_host_enable_ptm_response(pcie);
> -
> -	ret = cdns_pcie_start_link(pcie);
> -	if (ret) {
> -		dev_err(dev, "Failed to start link\n");
> -		return ret;
> -	}
> -
> -	ret = cdns_pcie_host_start_link(rc);
> +	ret = cdns_pcie_host_link_setup(rc);
>  	if (ret)
> -		dev_dbg(dev, "PCIe link never came up\n");
> +		return ret;
>  
>  	for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
>  		rc->avail_ib_bar[bar] = true;
> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
> index 373cb50fcd15..4c687aeb810e 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence.h
> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
> @@ -515,10 +515,16 @@ static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
>  }
>  
>  #ifdef CONFIG_PCIE_CADENCE_HOST
> +int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc);
>  int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
>  void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
>  			       int where);
>  #else
> +static inline int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
> +{
> +	return 0;
> +}
> +
>  static inline int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
>  {
>  	return 0;
> 
> -- 
> 2.39.2
> 
> 


From conor.dooley at microchip.com  Fri Feb 16 01:35:42 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Fri, 16 Feb 2024 09:35:42 +0000
Subject: [PATCH v3 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <cfafd563-1387-4775-bcb0-434ce3774827@tuxon.dev>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
 <20240215091524.14732-3-mihai.sain@microchip.com>
 <20240215-lustily-flick-69cb48b123c3@spud>
 <PH8PR11MB6804E9353A8EEBD2B829D8B3824C2@PH8PR11MB6804.namprd11.prod.outlook.com>
 <20240216075609e58aeee4@mail.local>
 <cfafd563-1387-4775-bcb0-434ce3774827@tuxon.dev>
Message-ID: <20240216-eleven-exposure-dde558e63aaf@wendy>

On Fri, Feb 16, 2024 at 10:24:13AM +0200, claudiu beznea wrote:
> On 16.02.2024 09:56, Alexandre Belloni wrote:
> > On 16/02/2024 06:58:10+0000, Mihai.Sain at microchip.com wrote:
> >>> diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> >>> index 269e0a3ca269..c030b318985a 100644
> >>> --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
> >>> +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> >>> @@ -958,6 +958,30 @@ i2c9: i2c at 600 {
> >>>  			};
> >>>  		};
> >>>  
> >>> +		flx10: flexcom at e2820000 {
> >>> +			compatible = "atmel,sama5d2-flexcom";
> >>
> >> My comment here was ignored:
> >> https://lore.kernel.org/all/20240214-robe-pregnancy-a1b056c9fe14 at spud/
> >>
> >> The SAMA7G5 has the same flexcom controller as SAMA5D2 MPU.
> >>
> > 
> > Still, it needs its own compatible plus a fallback to
> > atmel,sama5d2-flexcom
> 
> I agree with this. Though, flexcom documentation is subject to YAML
> conversion (a patch has been re-posted these days [1] and *maybe* it will
> be integrated this time). And there are multiple SoC DTs that need to be
> updated with their own flexcom compatible (lan966x, sam9x60, sama7g5).
> 
> To avoid conflicting with the work at [1] and postponing this series we may
> do the update after the [1] is done.
> 
> Let me know your thoughts. Either way is fine by me.

I'd be inclined to say that if we are gonna take a shortcut here, then
this patch should add a specific compatible so that when the yaml
conversion goes through you'll get a warning about this being
undocumented rather than silence.

A resend on the flexcom patch is required though, the rebase was not
done correctly, so maybe Balakrishnan could "atmel,sama7g5-flexcom"
add with a fallback to "atmel,sama5d2-flexcom" while they're fixing
it up?

Cheers,
Conor.
-------------- 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/20240216/a443fc97/attachment.sig>

From laurent.pinchart at ideasonboard.com  Fri Feb 16 01:37:00 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 16 Feb 2024 11:37:00 +0200
Subject: [PATCH V8 09/12] dt-bindings: display: imx: add binding for
 i.MX8MP HDMI TX
In-Reply-To: <5916132.MhkbZ0Pkbq@steina-w>
References: <20240203165307.7806-1-aford173@gmail.com>
 <20240203165307.7806-10-aford173@gmail.com>
 <5916132.MhkbZ0Pkbq@steina-w>
Message-ID: <20240216093700.GA10584@pendragon.ideasonboard.com>

On Fri, Feb 16, 2024 at 10:05:26AM +0100, Alexander Stein wrote:
> Hi all,
> 
> Am Samstag, 3. Februar 2024, 17:52:49 CET schrieb Adam Ford:
> > From: Lucas Stach <l.stach at pengutronix.de>
> > 
> > The HDMI TX controller on the i.MX8MP SoC is a Synopsys designware IP
> > core with a little bit of SoC integration around it.
> > 
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
> > 
> > ---
> > V3:  Change name and location to better idenfity as a bridge and
> >      HDMI 2.0a transmitter
> > 
> >      Fix typos and feedback from Rob and added ports.
> > ---
> >  .../display/bridge/fsl,imx8mp-hdmi-tx.yaml    | 102 ++++++++++++++++++
> >  1 file changed, 102 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> > b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> > new file mode 100644
> > index 000000000000..3791c9f4ebab
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> > @@ -0,0 +1,102 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/display/bridge/fsl,imx8mp-hdmi-tx.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Freescale i.MX8MP DWC HDMI TX Encoder
> > +
> > +maintainers:
> > +  - Lucas Stach <l.stach at pengutronix.de>
> > +
> > +description:
> > +  The i.MX8MP HDMI transmitter is a Synopsys DesignWare
> > +  HDMI 2.0a TX controller IP.
> > +
> > +allOf:
> > +  - $ref: /schemas/display/bridge/synopsys,dw-hdmi.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - fsl,imx8mp-hdmi-tx
> > +
> > +  reg-io-width:
> > +    const: 1
> > +
> > +  clocks:
> > +    maxItems: 4
> > +
> > +  clock-names:
> > +    items:
> > +      - const: iahb
> > +      - const: isfr
> > +      - const: cec
> > +      - const: pix
> > +
> > +  power-domains:
> > +    maxItems: 1
> > +
> > +  ports:
> > +    $ref: /schemas/graph.yaml#/properties/ports
> > +
> > +    properties:
> > +      port at 0:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: Parallel RGB input port
> > +
> > +      port at 1:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: HDMI output port
> > +
> > +    required:
> > +      - port at 0
> > +      - port at 1
> 
> Is this really correct that port at 1 is required? AFAICS this host already 
> supports HPD and DDC by itself, so there is no need for a dedicated HDMI 
> connector.

The chip has an HDMI output, so there's an output port.

> With the current state of the drivers this output port is completely ignored 
> anyway. Yet it works for a lot of people.

DT bindings describe the hardware. From a DT point of view, tt's fine
for drivers to ignore the port (that may or may not be true from a DRM
point of view, but that's a separate discussion).

> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - clocks
> > +  - clock-names
> > +  - interrupts
> > +  - power-domains
> > +  - ports
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/imx8mp-clock.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/power/imx8mp-power.h>
> > +
> > +    hdmi at 32fd8000 {
> > +        compatible = "fsl,imx8mp-hdmi-tx";
> > +        reg = <0x32fd8000 0x7eff>;
> > +        interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
> > +        clocks = <&clk IMX8MP_CLK_HDMI_APB>,
> > +                 <&clk IMX8MP_CLK_HDMI_REF_266M>,
> > +                 <&clk IMX8MP_CLK_32K>,
> > +                 <&hdmi_tx_phy>;
> > +        clock-names = "iahb", "isfr", "cec", "pix";
> > +        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
> > +        reg-io-width = <1>;
> > +        ports {
> > +           #address-cells = <1>;
> > +           #size-cells = <0>;
> > +           port at 0 {
> > +             reg = <0>;
> > +
> > +             hdmi_tx_from_pvi: endpoint {
> > +               remote-endpoint = <&pvi_to_hdmi_tx>;
> > +             };
> > +          };
> > +
> > +          port at 1 {
> > +            reg = <1>;
> > +              hdmi_tx_out: endpoint {
> > +                remote-endpoint = <&hdmi0_con>;
> > +              };
> > +          };
> > +        };
> > +    };

-- 
Regards,

Laurent Pinchart


From s-vadapalli at ti.com  Fri Feb 16 01:38:02 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Fri, 16 Feb 2024 15:08:02 +0530
Subject: [PATCH v3 16/18] PCI: cadence: set cdns_pcie_host_init() global
In-Reply-To: <20240102-j7200-pcie-s2r-v3-16-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-16-5c2e4a3fac1f@bootlin.com>
Message-ID: <fd7315fe-bb3d-444d-a5d3-9f91dc88f105@ti.com>

On 24/02/15 04:18PM, Thomas Richard wrote:
> During the resume sequence of the host, cdns_pcie_host_init() needs to be
> called, so set it global.
> 
> The dev function parameter is removed, as it isn't used.
> 
> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>

Reviewed-by: Siddharth Vadapalli <s-vadapalli at ti.com>

Regards,
Siddharth.

> ---
>  drivers/pci/controller/cadence/pcie-cadence-host.c | 5 ++---
>  drivers/pci/controller/cadence/pcie-cadence.h      | 6 ++++++
>  2 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
> index 93d9922730af..8af95e9da7ce 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence-host.c
> +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
> @@ -485,8 +485,7 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
>  	return cdns_pcie_host_map_dma_ranges(rc);
>  }
>  
> -static int cdns_pcie_host_init(struct device *dev,
> -			       struct cdns_pcie_rc *rc)
> +int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
>  {
>  	int err;
>  
> @@ -564,7 +563,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
>  	for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
>  		rc->avail_ib_bar[bar] = true;
>  
> -	ret = cdns_pcie_host_init(dev, rc);
> +	ret = cdns_pcie_host_init(rc);
>  	if (ret)
>  		return ret;
>  
> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
> index 4c687aeb810e..d55dfd173f22 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence.h
> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
> @@ -516,6 +516,7 @@ static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
>  
>  #ifdef CONFIG_PCIE_CADENCE_HOST
>  int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc);
> +int cdns_pcie_host_init(struct cdns_pcie_rc *rc);
>  int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
>  void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
>  			       int where);
> @@ -525,6 +526,11 @@ static inline int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)
>  	return 0;
>  }
>  
> +static inline int cdns_pcie_host_init(struct cdns_pcie_rc *rc)
> +{
> +	return 0;
> +}
> +
>  static inline int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
>  {
>  	return 0;
> 
> -- 
> 2.39.2
> 
> 


From ck.hu at mediatek.com  Fri Feb 16 01:38:47 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 16 Feb 2024 09:38:47 +0000
Subject: [PATCH v2 1/1] drm/mediatek: Filter modes according to hardware
 capability
In-Reply-To: <20240207021510.24035-2-shawn.sung@mediatek.com>
References: <20240207021510.24035-1-shawn.sung@mediatek.com>
	 <20240207021510.24035-2-shawn.sung@mediatek.com>
Message-ID: <d8bb9f158e03c41d2278545e1a5ef657943f7be4.camel@mediatek.com>

Hi, Hsiao-chien:

On Wed, 2024-02-07 at 10:15 +0800, Hsiao Chien Sung wrote:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> We found a stability issue on MT8188 when connecting an external
> monitor
> in 2560x1440 at 144Hz mode. Checked with the designer, there is a
> function
> called "prefetch" which is working during VBP (triggered by VSYNC).
> If the duration of VBP is too short, the throughput requirement could
> increase more than 3 times and lead to stability issues.
> 
> The mode settings that VDOSYS supports are mainly affected by clock
> rate and throughput, display driver should filter these settings
> according to the SoC's limitation to avoid unstable conditions.
> 
> Since currently the mode filter is only available on MT8195 and
> MT8188
> and they share the same compatible name, the reference number (8250)
> is hard coded instead of in the driver data.
> 
> Signed-off-by: Hsiao Chien Sung <
> shawn.sung at mediatek.corp-partner.google.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  4 ++
>  drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 56
> +++++++++++++++++++
>  .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 17 ++++++
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 17 ++++++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  1 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   | 12 ++++
>  6 files changed, 107 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index eb738f14f09e3..4a5661334fb1a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -72,6 +72,8 @@ void mtk_merge_advance_config(struct device *dev,
> unsigned int l_w, unsigned int
>  			      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);
> +enum drm_mode_status mtk_merge_mode_valid(struct device *dev,
> +					  const struct drm_display_mode
> *mode);
>  
>  void mtk_ovl_bgclr_in_on(struct device *dev);
>  void mtk_ovl_bgclr_in_off(struct device *dev);
> @@ -130,6 +132,8 @@ unsigned int mtk_ovl_adaptor_layer_nr(struct
> device *dev);
>  struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev);
>  const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
>  size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
> +enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
> +						const struct
> drm_display_mode *mode);
>  
>  void mtk_rdma_bypass_shadow(struct device *dev);
>  int mtk_rdma_clk_enable(struct device *dev);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> index c19fb1836034d..6b065ee254455 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> @@ -223,6 +223,62 @@ void mtk_merge_clk_disable(struct device *dev)
>  	clk_disable_unprepare(priv->clk);
>  }
>  
> +enum drm_mode_status mtk_merge_mode_valid(struct device *dev,
> +					  const struct drm_display_mode
> *mode)
> +{
> +	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> +	unsigned long rate = 0;
> +
> +	rate = clk_get_rate(priv->clk);
> +
> +	/* Convert to KHz and round the number */
> +	rate = (rate + 500) / 1000;
> +
> +	if (rate && mode->clock > rate) {
> +		dev_dbg(dev, "invalid clock: %d (>%lu)\n", mode->clock, 
> rate);
> +		return MODE_CLOCK_HIGH;
> +	}
> +
> +	/*
> +	 * Measure the bandwidth requirement of hardware prefetch (per
> frame)
> +	 *
> +	 * let N = prefetch buffer size in lines
> +	 *         (ex. N=3, then prefetch buffer size = 3 lines)
> +	 *
> +	 * prefetch size = htotal * N (pixels)
> +	 * time per line = 1 / fps / vtotal (seconds)
> +	 * duration      = vbp * time per line
> +	 *               = vbp / fps / vtotal
> +	 *
> +	 * data rate = prefetch size / duration
> +	 *           = htotal * N / (vbp / fps / vtotal)
> +	 *           = htotal * vtotal * fps * N / vbp
> +	 *           = clk * N / vbp (pixels per second)
> +	 *
> +	 * Say 4K60 (CAE-861) is the maximum mode supported by the SoC
> +	 * data rate = 594000K * N / 72 = 8250 (standard)
> +	 * (remove K*N because of the same unit)

Is N constant? For example, when 4K, N=3. When 2560x1440, N is still 3?
I think the buffer size is constant, if N is still 3 when 2560x1440,
the buffer is not full and some space is wasted.

Regards,
CK

> +	 *
> +	 * For 2560x1440 at 144 (clk=583600K, vbp=17):
> +	 * rate = 583600 / 17 ~= 34329 > 8250 (NG)
> +	 *
> +	 * For 2560x1440 at 120 (clk=497760K, vbp=77):
> +	 * rate = 497760 / 77 ~= 6464 < 8250 (OK)
> +	 *
> +	 * Bandwidth requirement of hardware prefetch increases
> significantly
> +	 * when the VBP decreases (more than 4x in this example).
> +	 */
> +	rate = mode->clock / (mode->vtotal - mode->vsync_end);
> +
> +	if (rate > 8250) {
> +		dev_dbg(dev, "invalid rate: %lu (>8250): " DRM_MODE_FMT
> "\n",
> +			rate, DRM_MODE_ARG(mode));
> +		return MODE_BAD;
> +	}
> +
> +	return MODE_OK;
> +}
> +
>  static int mtk_disp_merge_bind(struct device *dev, struct device
> *master,
>  			       void *data)
>  {
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> index 10d23e76acaa9..6d4334955e3d3 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> @@ -88,6 +88,7 @@ static const struct mtk_ddp_comp_funcs ethdr = {
>  static const struct mtk_ddp_comp_funcs merge = {
>  	.clk_enable = mtk_merge_clk_enable,
>  	.clk_disable = mtk_merge_clk_disable,
> +	.mode_valid = mtk_merge_mode_valid,
>  };
>  
>  static const struct mtk_ddp_comp_funcs padding = {
> @@ -341,6 +342,22 @@ void mtk_ovl_adaptor_clk_disable(struct device
> *dev)
>  	}
>  }
>  
> +enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
> +						const struct
> drm_display_mode *mode)
> +
> +{
> +	int i;
> +	struct mtk_disp_ovl_adaptor *ovl_adaptor =
> dev_get_drvdata(dev);
> +
> +	for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
> +		dev = ovl_adaptor->ovl_adaptor_comp[i];
> +		if (!dev || !comp_matches[i].funcs->mode_valid)
> +			continue;
> +		return comp_matches[i].funcs->mode_valid(dev, mode);
> +	}
> +	return MODE_OK;
> +}
> +
>  unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev)
>  {
>  	return MTK_OVL_ADAPTOR_LAYER_NUM;
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 1dac8d0fbc669..14cf75fa217f9 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -212,6 +212,22 @@ static void mtk_drm_crtc_destroy_state(struct
> drm_crtc *crtc,
>  	kfree(to_mtk_crtc_state(state));
>  }
>  
> +static enum drm_mode_status
> +mtk_drm_crtc_mode_valid(struct drm_crtc *crtc,
> +			const struct drm_display_mode *mode)
> +{
> +	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> +	enum drm_mode_status status = MODE_OK;
> +	int i;
> +
> +	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
> +		status = mtk_ddp_comp_mode_valid(mtk_crtc->ddp_comp[i], 
> mode);
> +		if (status != MODE_OK)
> +			break;
> +	}
> +	return status;
> +}
> +
>  static bool mtk_drm_crtc_mode_fixup(struct drm_crtc *crtc,
>  				    const struct drm_display_mode
> *mode,
>  				    struct drm_display_mode
> *adjusted_mode)
> @@ -830,6 +846,7 @@ static const struct drm_crtc_funcs mtk_crtc_funcs
> = {
>  static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
>  	.mode_fixup	= mtk_drm_crtc_mode_fixup,
>  	.mode_set_nofb	= mtk_drm_crtc_mode_set_nofb,
> +	.mode_valid	= mtk_drm_crtc_mode_valid,
>  	.atomic_begin	= mtk_drm_crtc_atomic_begin,
>  	.atomic_flush	= mtk_drm_crtc_atomic_flush,
>  	.atomic_enable	= mtk_drm_crtc_atomic_enable,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 9633e860cc3ce..94590227c56a9 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -416,6 +416,7 @@ static const struct mtk_ddp_comp_funcs
> ddp_ovl_adaptor = {
>  	.remove = mtk_ovl_adaptor_remove_comp,
>  	.get_formats = mtk_ovl_adaptor_get_formats,
>  	.get_num_formats = mtk_ovl_adaptor_get_num_formats,
> +	.mode_valid = mtk_ovl_adaptor_mode_valid,
>  };
>  
>  static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] =
> {
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index f8c7e8d8ddc12..215b7234ff13c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -12,6 +12,8 @@
>  #include <linux/soc/mediatek/mtk-mmsys.h>
>  #include <linux/soc/mediatek/mtk-mutex.h>
>  
> +#include <drm/drm_modes.h>
> +
>  struct device;
>  struct device_node;
>  struct drm_crtc;
> @@ -84,6 +86,7 @@ struct mtk_ddp_comp_funcs {
>  	void (*add)(struct device *dev, struct mtk_mutex *mutex);
>  	void (*remove)(struct device *dev, struct mtk_mutex *mutex);
>  	unsigned int (*encoder_index)(struct device *dev);
> +	enum drm_mode_status (*mode_valid)(struct device *dev, const
> struct drm_display_mode *mode);
>  };
>  
>  struct mtk_ddp_comp {
> @@ -125,6 +128,15 @@ static inline void
> mtk_ddp_comp_clk_disable(struct mtk_ddp_comp *comp)
>  		comp->funcs->clk_disable(comp->dev);
>  }
>  
> +static inline
> +enum drm_mode_status mtk_ddp_comp_mode_valid(struct mtk_ddp_comp
> *comp,
> +					     const struct
> drm_display_mode *mode)
> +{
> +	if (comp && comp->funcs && comp->funcs->mode_valid)
> +		return comp->funcs->mode_valid(comp->dev, mode);
> +	return MODE_OK;
> +}
> +
>  static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
>  				       unsigned int w, unsigned int h,
>  				       unsigned int vrefresh, unsigned
> int bpc,

From michal.simek at amd.com  Fri Feb 16 01:42:29 2024
From: michal.simek at amd.com (Michal Simek)
Date: Fri, 16 Feb 2024 10:42:29 +0100
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
In-Reply-To: <5a81f16b-8ece-4263-b424-4dd6cd6e386f@linaro.org>
References: <94726c90ff519185767475f672d70311472ea925.1708073513.git.michal.simek@amd.com>
 <5a81f16b-8ece-4263-b424-4dd6cd6e386f@linaro.org>
Message-ID: <ed59671f-6e0b-45a2-bae7-38f7b4b7e625@amd.com>



On 2/16/24 10:19, Krzysztof Kozlowski wrote:
> On 16/02/2024 09:51, Michal Simek wrote:
>> RTC has its own power domain on Xilinx Versal SOC that's why describe it as
>> optional property.
>>
>> Signed-off-by: Michal Simek <michal.simek at amd.com>
>> ---
>>
>>   Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml | 3 +++
>>   1 file changed, 3 insertions(+)
>>
> 
> But Versal is not described in this binding, is it? I see only one
> compatible.

It is the same IP only as is on zynqmp with own power rail.

Pretty much with different firmware interface on zynqmp you can describe it too 
(and doesn't really matter if it is separated in HW or common for more IPs).

Thanks,
Michal


From antonio.borneo at foss.st.com  Fri Feb 16 01:47:46 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:46 +0100
Subject: [PATCH 01/12] irqchip/stm32-exti: Fix minor indentation issue
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-2-antonio.borneo@foss.st.com>

Use only TAB for indentation, removing a leading space.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
Fixes: 046a6ee2343b ("irqchip: Bulk conversion to generic_handle_domain_irq()")
---
 drivers/irqchip/irq-stm32-exti.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 971240e2e31b..69982f21126a 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -322,7 +322,7 @@ static void stm32_irq_handler(struct irq_desc *desc)
 		while ((pending = stm32_exti_pending(gc))) {
 			for_each_set_bit(n, &pending, IRQS_PER_BANK)
 				generic_handle_domain_irq(domain, irq_base + n);
- 		}
+		}
 	}
 
 	chained_irq_exit(chip, desc);
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:48 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:48 +0100
Subject: [PATCH 03/12] irqchip/stm32-exti: Map interrupts through interrupt nexus node
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-4-antonio.borneo@foss.st.com>

The mapping of EXTI interrupts to its parent interrupt controller
is both SoC and instance dependent.
The current implementation requires adding a new table to the
driver's code and a new compatible for each new EXTI instance.

Check for the presence of the optional interrupt nexus child node
and use its property 'interrup-map' to map EXTI interrupts to the
parent's interrupts.

For old DT's without the optional nexus child node, the driver's
behavior is unchanged, thus keeps backward compatibility.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
---
 drivers/irqchip/irq-stm32-exti.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 69982f21126a..95bb3dd10b2c 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -61,6 +61,7 @@ struct stm32_exti_host_data {
 	struct stm32_exti_chip_data *chips_data;
 	const struct stm32_exti_drv_data *drv_data;
 	struct hwspinlock *hwlock;
+	struct device_node *irq_map_node;
 };
 
 static struct stm32_exti_host_data *stm32_host_data;
@@ -713,8 +714,9 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm,
 	u8 desc_irq;
 	struct irq_fwspec *fwspec = data;
 	struct irq_fwspec p_fwspec;
+	struct of_phandle_args out_irq;
 	irq_hw_number_t hwirq;
-	int bank;
+	int bank, ret;
 	u32 event_trg;
 	struct irq_chip *chip;
 
@@ -731,6 +733,25 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm,
 
 	irq_domain_set_hwirq_and_chip(dm, virq, hwirq, chip, chip_data);
 
+	if (host_data->irq_map_node) {
+		out_irq.np = host_data->irq_map_node;
+		out_irq.args_count = 2;
+		out_irq.args[0] = fwspec->param[0];
+		out_irq.args[1] = fwspec->param[1];
+
+		ret = of_irq_parse_raw(NULL, &out_irq);
+		if (ret)
+			return ret;
+		/* we only support one parent, so far */
+		if (of_node_to_fwnode(out_irq.np) != dm->parent->fwnode)
+			return -EINVAL;
+
+		of_phandle_args_to_fwspec(out_irq.np, out_irq.args,
+					  out_irq.args_count, &p_fwspec);
+
+		return irq_domain_alloc_irqs_parent(dm, virq, 1, &p_fwspec);
+	}
+
 	if (!host_data->drv_data->desc_irqs)
 		return -EINVAL;
 
@@ -908,7 +929,7 @@ static int stm32_exti_probe(struct platform_device *pdev)
 {
 	int ret, i;
 	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
+	struct device_node *child, *np = dev->of_node;
 	struct irq_domain *parent_domain, *domain;
 	struct stm32_exti_host_data *host_data;
 	const struct stm32_exti_drv_data *drv_data;
@@ -976,6 +997,10 @@ static int stm32_exti_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	child = of_get_child_by_name(np, "exti-interrupt-map");
+	if (child && of_property_read_bool(child, "interrupt-map"))
+		host_data->irq_map_node = child;
+
 	stm32_exti_h_syscore_init(host_data);
 
 	return 0;
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:45 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:45 +0100
Subject: [PATCH 00/12] irqchip/stm32-exti: add irq-map and STM32MP25 support
Message-ID: <20240216094758.916722-1-antonio.borneo@foss.st.com>

This series adds support for STM32MP25 to stm32-exti driver.
The STM32MP25 includes two instances of the EXTI irq controller,
each mapping their EXTI events to different GIC irq sets.

In the current driver code, the mapping between events and irqs
would require adding to the driver two new compatibles and two
new mapping tables for this new SoC. This way of working starts
showing it's limits; it doesn't scale and is not flexible.

This series introduces an optional nexus child node to the EXTI
DT node. The nexus node provides the mapping between events and
irqs through the standard "interrupt-map" property, thus moving
in the DT the description of the HW connections between the EXTI
and the GIC.
Being the nexus child node optional, it guarantees the backward
compatibility with all the existing DT for STM32MP1xx.
Nevertheless the series updates and uniforms the existing DT by
adding to them the nexus child node too.

The DT node for the GIC of STM32MP25 is already upstream with:
	#address-cells = <1>;
This value needs to be updated to <2> because the SoC uses 64 bit
addressing and the v2m child node of GIC requires 64 bit address
too.
This minor change to the GIC property "#address-cells" impacts
the contents of the "interrupt-map" property.
This series also anticipates the addition of the v2m child node
to the GIC, thus avoiding any further rework.


Antonio Borneo (11):
  irqchip/stm32-exti: Fix minor indentation issue
  dt-bindings: interrupt-controller: stm32-exti: Add irq nexus child
    node
  irqchip/stm32-exti: Map interrupts through interrupt nexus node
  irqchip/stm32-exti: Convert driver to standard PM
  irqchip/stm32-exti: Skip secure events
  irqchip/stm32-exti: Mark events reserved with RIF configuration check
  arm64: Kconfig.platforms: Enable STM32_EXTI for ARCH_STM32
  ARM: dts: stm32: Use exti interrupt-map on stm32mp151
  ARM: dts: stm32: Use exti interrupt-map on stm32mp131
  arm64: dts: st: Add exti1 and exti2 nodes on stm32mp251
  arm64: dts: st: Add interrupt parent to pinctrl on stm32mp251

Christian Bruel (1):
  arm64: dts: st: Add v2m to GIC node on stm32mp251

 .../interrupt-controller/st,stm32-exti.yaml   |  42 ++++-
 arch/arm/boot/dts/st/stm32mp131.dtsi          |  49 +++++-
 arch/arm/boot/dts/st/stm32mp151.dtsi          |  51 ++++++
 arch/arm64/Kconfig.platforms                  |   1 +
 arch/arm64/boot/dts/st/stm32mp251.dtsi        | 154 +++++++++++++++++-
 drivers/irqchip/irq-stm32-exti.c              | 148 ++++++++++++-----
 6 files changed, 397 insertions(+), 48 deletions(-)


base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:49 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:49 +0100
Subject: [PATCH 04/12] irqchip/stm32-exti: Convert driver to standard PM
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-5-antonio.borneo@foss.st.com>

All driver's dependencies for suspend/resume have been fixed long
ago. There are no more reasons to use syscore PM for the part of
this driver related to Cortex-A MPU.

Switch to standard PM using NOIRQ_SYSTEM_SLEEP_PM_OPS, so all the
registers of the interrupt controller get resumed before any irq
gets enabled.

A side effect of this change is to drop the only global variable
'stm32_host_data', used to keep the driver's data for syscore_ops.
This makes the driver ready to support multiple EXTI instances.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
---
 drivers/irqchip/irq-stm32-exti.c | 58 ++++++++++----------------------
 1 file changed, 17 insertions(+), 41 deletions(-)

diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 95bb3dd10b2c..de18cddf6b88 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -19,7 +19,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
-#include <linux/syscore_ops.h>
+#include <linux/pm.h>
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
@@ -64,8 +64,6 @@ struct stm32_exti_host_data {
 	struct device_node *irq_map_node;
 };
 
-static struct stm32_exti_host_data *stm32_host_data;
-
 static const struct stm32_exti_bank stm32f4xx_exti_b1 = {
 	.imr_ofst	= 0x00,
 	.emr_ofst	= 0x04,
@@ -622,50 +620,32 @@ static int stm32_exti_h_set_affinity(struct irq_data *d,
 	return IRQ_SET_MASK_OK_DONE;
 }
 
-static int __maybe_unused stm32_exti_h_suspend(void)
+static int stm32_exti_h_suspend(struct device *dev)
 {
+	struct stm32_exti_host_data *host_data = dev_get_drvdata(dev);
 	struct stm32_exti_chip_data *chip_data;
 	int i;
 
-	for (i = 0; i < stm32_host_data->drv_data->bank_nr; i++) {
-		chip_data = &stm32_host_data->chips_data[i];
-		raw_spin_lock(&chip_data->rlock);
+	for (i = 0; i < host_data->drv_data->bank_nr; i++) {
+		chip_data = &host_data->chips_data[i];
 		stm32_chip_suspend(chip_data, chip_data->wake_active);
-		raw_spin_unlock(&chip_data->rlock);
 	}
 
 	return 0;
 }
 
-static void __maybe_unused stm32_exti_h_resume(void)
+static int stm32_exti_h_resume(struct device *dev)
 {
+	struct stm32_exti_host_data *host_data = dev_get_drvdata(dev);
 	struct stm32_exti_chip_data *chip_data;
 	int i;
 
-	for (i = 0; i < stm32_host_data->drv_data->bank_nr; i++) {
-		chip_data = &stm32_host_data->chips_data[i];
-		raw_spin_lock(&chip_data->rlock);
+	for (i = 0; i < host_data->drv_data->bank_nr; i++) {
+		chip_data = &host_data->chips_data[i];
 		stm32_chip_resume(chip_data, chip_data->mask_cache);
-		raw_spin_unlock(&chip_data->rlock);
 	}
-}
 
-static struct syscore_ops stm32_exti_h_syscore_ops = {
-#ifdef CONFIG_PM_SLEEP
-	.suspend	= stm32_exti_h_suspend,
-	.resume		= stm32_exti_h_resume,
-#endif
-};
-
-static void stm32_exti_h_syscore_init(struct stm32_exti_host_data *host_data)
-{
-	stm32_host_data = host_data;
-	register_syscore_ops(&stm32_exti_h_syscore_ops);
-}
-
-static void stm32_exti_h_syscore_deinit(void)
-{
-	unregister_syscore_ops(&stm32_exti_h_syscore_ops);
+	return 0;
 }
 
 static int stm32_exti_h_retrigger(struct irq_data *d)
@@ -792,8 +772,6 @@ stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd,
 		goto free_chips_data;
 	}
 
-	stm32_host_data = host_data;
-
 	return host_data;
 
 free_chips_data:
@@ -919,12 +897,6 @@ static void stm32_exti_remove_irq(void *data)
 	irq_domain_remove(domain);
 }
 
-static int stm32_exti_remove(struct platform_device *pdev)
-{
-	stm32_exti_h_syscore_deinit();
-	return 0;
-}
-
 static int stm32_exti_probe(struct platform_device *pdev)
 {
 	int ret, i;
@@ -938,6 +910,8 @@ static int stm32_exti_probe(struct platform_device *pdev)
 	if (!host_data)
 		return -ENOMEM;
 
+	dev_set_drvdata(dev, host_data);
+
 	/* check for optional hwspinlock which may be not available yet */
 	ret = of_hwspin_lock_get_id(np, 0);
 	if (ret == -EPROBE_DEFER)
@@ -1001,8 +975,6 @@ static int stm32_exti_probe(struct platform_device *pdev)
 	if (child && of_property_read_bool(child, "interrupt-map"))
 		host_data->irq_map_node = child;
 
-	stm32_exti_h_syscore_init(host_data);
-
 	return 0;
 }
 
@@ -1014,12 +986,16 @@ static const struct of_device_id stm32_exti_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, stm32_exti_ids);
 
+static const struct dev_pm_ops stm32_exti_dev_pm_ops = {
+	NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_exti_h_suspend, stm32_exti_h_resume)
+};
+
 static struct platform_driver stm32_exti_driver = {
 	.probe		= stm32_exti_probe,
-	.remove		= stm32_exti_remove,
 	.driver		= {
 		.name	= "stm32_exti",
 		.of_match_table = stm32_exti_ids,
+		.pm	= &stm32_exti_dev_pm_ops,
 	},
 };
 
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:47 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:47 +0100
Subject: [PATCH 02/12] dt-bindings: interrupt-controller: stm32-exti: Add irq nexus child node
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-3-antonio.borneo@foss.st.com>

The mapping of EXTI interrupts to its parent interrupt controller
is both SoC and instance dependent.
The current implementation requires adding a new table to the
driver's code and a new compatible for each new EXTI instance.

Add to the binding an interrupt nexus child node that will be
used on the new EXTI instances and can be optionally used on the
existing instances.
The property 'interrupt-map' in the nexus node maps each EXTI
interrupt to the parent interrupt.
Align #address-cells and #interrupt-cells between the EXTI node
and its nexus node.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
---
 .../interrupt-controller/st,stm32-exti.yaml   | 42 ++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
index 00c10a8258f1..1a4cf9537b9e 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
@@ -26,6 +26,9 @@ properties:
   "#interrupt-cells":
     const: 2
 
+  "#address-cells":
+    const: 0
+
   reg:
     maxItems: 1
 
@@ -42,6 +45,24 @@ properties:
     description:
       Interrupts references to primary interrupt controller
 
+  exti-interrupt-map:
+    type: object
+    properties:
+      interrupt-map: true
+
+      interrupt-map-mask: true
+
+      "#interrupt-cells":
+        const: 2
+
+      "#address-cells":
+        const: 0
+
+    required:
+      - interrupt-map
+      - "#interrupt-cells"
+      - "#address-cells"
+
 required:
   - "#interrupt-cells"
   - compatible
@@ -89,8 +110,27 @@ examples:
         reg = <0x5000d000 0x400>;
     };
 
+  - |
     //Example 2
-    exti2: interrupt-controller at 40013c00 {
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    exti2: interrupt-controller at 5000d000 {
+        compatible = "st,stm32mp1-exti", "syscon";
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        reg = <0x5000d000 0x400>;
+        exti-interrupt-map {
+            #address-cells = <0>;
+            #interrupt-cells = <2>;
+            interrupt-map-mask = <0xffffffff 0>;
+            interrupt-map =
+                <0 0 &intc GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+                <3 0 &intc GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+        };
+    };
+
+  - |
+    //Example 3
+    exti3: interrupt-controller at 40013c00 {
         compatible = "st,stm32-exti";
         interrupt-controller;
         #interrupt-cells = <2>;
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:50 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:50 +0100
Subject: [PATCH 05/12] irqchip/stm32-exti: Skip secure events
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-6-antonio.borneo@foss.st.com>

Secure OS can reserve some EXTI event, marking them as "secure" by
setting the corresponding bit in register SECCFGR (aka TZENR).
These events cannot be used by Linux.

Read the list of reserved events and check it during irq domain
allocation.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
---
 drivers/irqchip/irq-stm32-exti.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index de18cddf6b88..85a40e07fbc3 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -36,6 +36,7 @@ struct stm32_exti_bank {
 	u32 rpr_ofst;
 	u32 fpr_ofst;
 	u32 trg_ofst;
+	u32 seccfgr_ofst;
 };
 
 #define UNDEF_REG ~0
@@ -54,10 +55,12 @@ struct stm32_exti_chip_data {
 	u32 mask_cache;
 	u32 rtsr_cache;
 	u32 ftsr_cache;
+	u32 event_reserved;
 };
 
 struct stm32_exti_host_data {
 	void __iomem *base;
+	struct device *dev;
 	struct stm32_exti_chip_data *chips_data;
 	const struct stm32_exti_drv_data *drv_data;
 	struct hwspinlock *hwlock;
@@ -73,6 +76,7 @@ static const struct stm32_exti_bank stm32f4xx_exti_b1 = {
 	.rpr_ofst	= 0x14,
 	.fpr_ofst	= UNDEF_REG,
 	.trg_ofst	= UNDEF_REG,
+	.seccfgr_ofst	= UNDEF_REG,
 };
 
 static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = {
@@ -93,6 +97,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b1 = {
 	.rpr_ofst	= 0x88,
 	.fpr_ofst	= UNDEF_REG,
 	.trg_ofst	= UNDEF_REG,
+	.seccfgr_ofst	= UNDEF_REG,
 };
 
 static const struct stm32_exti_bank stm32h7xx_exti_b2 = {
@@ -104,6 +109,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b2 = {
 	.rpr_ofst	= 0x98,
 	.fpr_ofst	= UNDEF_REG,
 	.trg_ofst	= UNDEF_REG,
+	.seccfgr_ofst	= UNDEF_REG,
 };
 
 static const struct stm32_exti_bank stm32h7xx_exti_b3 = {
@@ -115,6 +121,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b3 = {
 	.rpr_ofst	= 0xA8,
 	.fpr_ofst	= UNDEF_REG,
 	.trg_ofst	= UNDEF_REG,
+	.seccfgr_ofst	= UNDEF_REG,
 };
 
 static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
@@ -137,6 +144,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b1 = {
 	.rpr_ofst	= 0x0C,
 	.fpr_ofst	= 0x10,
 	.trg_ofst	= 0x3EC,
+	.seccfgr_ofst	= 0x14,
 };
 
 static const struct stm32_exti_bank stm32mp1_exti_b2 = {
@@ -148,6 +156,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b2 = {
 	.rpr_ofst	= 0x2C,
 	.fpr_ofst	= 0x30,
 	.trg_ofst	= 0x3E8,
+	.seccfgr_ofst	= 0x34,
 };
 
 static const struct stm32_exti_bank stm32mp1_exti_b3 = {
@@ -159,6 +168,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b3 = {
 	.rpr_ofst	= 0x4C,
 	.fpr_ofst	= 0x50,
 	.trg_ofst	= 0x3E4,
+	.seccfgr_ofst	= 0x54,
 };
 
 static const struct stm32_exti_bank *stm32mp1_exti_banks[] = {
@@ -707,6 +717,12 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm,
 	bank  = hwirq / IRQS_PER_BANK;
 	chip_data = &host_data->chips_data[bank];
 
+	/* Check if event is reserved (Secure) */
+	if (chip_data->event_reserved & BIT(hwirq % IRQS_PER_BANK)) {
+		dev_err(host_data->dev, "event %lu is reserved, secure\n", hwirq);
+		return -EPERM;
+	}
+
 	event_trg = readl_relaxed(host_data->base + chip_data->reg_bank->trg_ofst);
 	chip = (event_trg & BIT(hwirq % IRQS_PER_BANK)) ?
 	       &stm32_exti_h_chip : &stm32_exti_h_chip_direct;
@@ -806,6 +822,10 @@ stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data,
 	if (stm32_bank->emr_ofst != UNDEF_REG)
 		writel_relaxed(0, base + stm32_bank->emr_ofst);
 
+	/* reserve Secure events */
+	if (stm32_bank->seccfgr_ofst != UNDEF_REG)
+		chip_data->event_reserved = readl_relaxed(base + stm32_bank->seccfgr_ofst);
+
 	pr_info("%pOF: bank%d\n", node, bank_idx);
 
 	return chip_data;
@@ -911,6 +931,7 @@ static int stm32_exti_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	dev_set_drvdata(dev, host_data);
+	host_data->dev = dev;
 
 	/* check for optional hwspinlock which may be not available yet */
 	ret = of_hwspin_lock_get_id(np, 0);
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:52 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:52 +0100
Subject: [PATCH 07/12] arm64: Kconfig.platforms: Enable STM32_EXTI for ARCH_STM32
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-8-antonio.borneo@foss.st.com>

ARCH_STM32 needs to use STM32 EXTI interrupt controller for GPIO
and wakeup interrupts.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 24335565bad5..19bf58a9d5e1 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -302,6 +302,7 @@ config ARCH_STM32
 	select GPIOLIB
 	select PINCTRL
 	select PINCTRL_STM32MP257
+	select STM32_EXTI
 	select ARM_SMC_MBOX
 	select ARM_SCMI_PROTOCOL
 	select COMMON_CLK_SCMI
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:51 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:51 +0100
Subject: [PATCH 06/12] irqchip/stm32-exti: Mark events reserved with RIF configuration check
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-7-antonio.borneo@foss.st.com>

EXTI events availability depends on Resource Isolation Framework
(RIF) configuration.
RIF grants access to buses with Compartment ID (CID) filtering,
secure and privilege level. It also assigns EXTI events to one or
several processors (CID, Secure, Privilege).

EXTI events used by Linux must be CID-filtered (EnCIDCFGR.CFEN=1)
and statically assigned to CID1 (EnCIDCFR.CID=CID1).
EXTI events not filling these conditions are marked as reserved
and can't be used by Linux.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
---
 drivers/irqchip/irq-stm32-exti.c | 40 ++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 85a40e07fbc3..68af5fe4764b 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -23,9 +23,22 @@
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-#define IRQS_PER_BANK 32
+#define IRQS_PER_BANK			32
 
-#define HWSPNLCK_TIMEOUT	1000 /* usec */
+#define HWSPNLCK_TIMEOUT		1000 /* usec */
+
+#define EXTI_EnCIDCFGR(n)		(0x180 + (n) * 4)
+#define EXTI_HWCFGR1			0x3f0
+
+/* Register: EXTI_EnCIDCFGR(n) */
+#define EXTI_CIDCFGR_CFEN_MASK		BIT(0)
+#define EXTI_CIDCFGR_CID_MASK		GENMASK(6, 4)
+#define EXTI_CIDCFGR_CID_SHIFT		4
+
+/* Register: EXTI_HWCFGR1 */
+#define EXTI_HWCFGR1_CIDWIDTH_MASK	GENMASK(27, 24)
+
+#define EXTI_CID1			1
 
 struct stm32_exti_bank {
 	u32 imr_ofst;
@@ -910,6 +923,27 @@ static const struct irq_domain_ops stm32_exti_h_domain_ops = {
 	.xlate = irq_domain_xlate_twocell,
 };
 
+static void stm32_exti_check_rif(struct stm32_exti_host_data *host_data)
+{
+	u32 cid, cidcfgr, hwcfgr1;
+	unsigned int bank, i, event;
+
+	/* quit on CID not supported */
+	hwcfgr1 = readl_relaxed(host_data->base + EXTI_HWCFGR1);
+	if ((hwcfgr1 & EXTI_HWCFGR1_CIDWIDTH_MASK) == 0)
+		return;
+
+	for (bank = 0; bank < host_data->drv_data->bank_nr; bank++) {
+		for (i = 0; i < IRQS_PER_BANK; i++) {
+			event = bank * IRQS_PER_BANK + i;
+			cidcfgr = readl_relaxed(host_data->base + EXTI_EnCIDCFGR(event));
+			cid = (cidcfgr & EXTI_CIDCFGR_CID_MASK) >> EXTI_CIDCFGR_CID_SHIFT;
+			if ((cidcfgr & EXTI_CIDCFGR_CFEN_MASK) && cid != EXTI_CID1)
+				host_data->chips_data[bank].event_reserved |= BIT(i);
+		}
+	}
+}
+
 static void stm32_exti_remove_irq(void *data)
 {
 	struct irq_domain *domain = data;
@@ -972,6 +1006,8 @@ static int stm32_exti_probe(struct platform_device *pdev)
 	for (i = 0; i < drv_data->bank_nr; i++)
 		stm32_exti_chip_init(host_data, i, np);
 
+	stm32_exti_check_rif(host_data);
+
 	parent_domain = irq_find_host(of_irq_find_parent(np));
 	if (!parent_domain) {
 		dev_err(dev, "GIC interrupt-parent not found\n");
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:54 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:54 +0100
Subject: [PATCH 09/12] ARM: dts: stm32: Use exti interrupt-map on stm32mp131
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-10-antonio.borneo@foss.st.com>

Stop using the internal table of the exti driver and use the more
flexible interrupt-map feature in DT.
By switching away from using the internal table, there is no need
anymore to use the specific compatible "st,stm32mp13-exti", which
was introduced to select the proper internal table.

Convert the driver table to interrupt-map property.
Switch the compatible string to the generic "st,stm32mp1-exti", in
place of the specific "st,stm32mp13-exti".

Older DT using compatible "st,stm32mp13-exti" will still work as
the driver remains backward compatible.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp131.dtsi | 49 +++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/st/stm32mp131.dtsi b/arch/arm/boot/dts/st/stm32mp131.dtsi
index b04d24c939c3..14bd1c9bedd9 100644
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -1093,10 +1093,57 @@ rcc: rcc at 50000000 {
 		};
 
 		exti: interrupt-controller at 5000d000 {
-			compatible = "st,stm32mp13-exti", "syscon";
+			compatible = "st,stm32mp1-exti", "syscon";
 			interrupt-controller;
 			#interrupt-cells = <2>;
+			#address-cells = <0>;
 			reg = <0x5000d000 0x400>;
+
+			exti-interrupt-map {
+				#address-cells = <0>;
+				#interrupt-cells = <2>;
+				interrupt-map-mask = <0xffffffff 0>;
+				interrupt-map =
+					<0  0 &intc GIC_SPI 6   IRQ_TYPE_LEVEL_HIGH>,
+					<1  0 &intc GIC_SPI 7   IRQ_TYPE_LEVEL_HIGH>,
+					<2  0 &intc GIC_SPI 8   IRQ_TYPE_LEVEL_HIGH>,
+					<3  0 &intc GIC_SPI 9   IRQ_TYPE_LEVEL_HIGH>,
+					<4  0 &intc GIC_SPI 10  IRQ_TYPE_LEVEL_HIGH>,
+					<5  0 &intc GIC_SPI 24  IRQ_TYPE_LEVEL_HIGH>,
+					<6  0 &intc GIC_SPI 65  IRQ_TYPE_LEVEL_HIGH>,
+					<7  0 &intc GIC_SPI 66  IRQ_TYPE_LEVEL_HIGH>,
+					<8  0 &intc GIC_SPI 67  IRQ_TYPE_LEVEL_HIGH>,
+					<9  0 &intc GIC_SPI 68  IRQ_TYPE_LEVEL_HIGH>,
+					<10 0 &intc GIC_SPI 41  IRQ_TYPE_LEVEL_HIGH>,
+					<11 0 &intc GIC_SPI 43  IRQ_TYPE_LEVEL_HIGH>,
+					<12 0 &intc GIC_SPI 77  IRQ_TYPE_LEVEL_HIGH>,
+					<13 0 &intc GIC_SPI 78  IRQ_TYPE_LEVEL_HIGH>,
+					<14 0 &intc GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+					<15 0 &intc GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+					<16 0 &intc GIC_SPI 1   IRQ_TYPE_LEVEL_HIGH>,
+					<19 0 &intc GIC_SPI 3   IRQ_TYPE_LEVEL_HIGH>,
+					<21 0 &intc GIC_SPI 32  IRQ_TYPE_LEVEL_HIGH>,
+					<22 0 &intc GIC_SPI 34  IRQ_TYPE_LEVEL_HIGH>,
+					<23 0 &intc GIC_SPI 73  IRQ_TYPE_LEVEL_HIGH>,
+					<24 0 &intc GIC_SPI 93  IRQ_TYPE_LEVEL_HIGH>,
+					<25 0 &intc GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+					<26 0 &intc GIC_SPI 38  IRQ_TYPE_LEVEL_HIGH>,
+					<27 0 &intc GIC_SPI 39  IRQ_TYPE_LEVEL_HIGH>,
+					<28 0 &intc GIC_SPI 40  IRQ_TYPE_LEVEL_HIGH>,
+					<29 0 &intc GIC_SPI 72  IRQ_TYPE_LEVEL_HIGH>,
+					<30 0 &intc GIC_SPI 53  IRQ_TYPE_LEVEL_HIGH>,
+					<31 0 &intc GIC_SPI 54  IRQ_TYPE_LEVEL_HIGH>,
+					<32 0 &intc GIC_SPI 83  IRQ_TYPE_LEVEL_HIGH>,
+					<33 0 &intc GIC_SPI 84  IRQ_TYPE_LEVEL_HIGH>,
+					<44 0 &intc GIC_SPI 96  IRQ_TYPE_LEVEL_HIGH>,
+					<47 0 &intc GIC_SPI 92  IRQ_TYPE_LEVEL_HIGH>,
+					<48 0 &intc GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+					<50 0 &intc GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+					<52 0 &intc GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+					<53 0 &intc GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+					<68 0 &intc GIC_SPI 63  IRQ_TYPE_LEVEL_HIGH>,
+					<70 0 &intc GIC_SPI 98  IRQ_TYPE_LEVEL_HIGH>;
+			};
 		};
 
 		syscfg: syscon at 50020000 {
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:53 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:53 +0100
Subject: [PATCH 08/12] ARM: dts: stm32: Use exti interrupt-map on stm32mp151
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-9-antonio.borneo@foss.st.com>

Stop using the internal table of the exti driver and use the more
flexible interrupt-map feature in DT.

Convert the driver's table for stm32mp151 to the interrupt-map
property in DT.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp151.dtsi | 51 ++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp151.dtsi b/arch/arm/boot/dts/st/stm32mp151.dtsi
index fa4cbd312e5a..33c460cacb04 100644
--- a/arch/arm/boot/dts/st/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp151.dtsi
@@ -1223,7 +1223,58 @@ exti: interrupt-controller at 5000d000 {
 			compatible = "st,stm32mp1-exti", "syscon";
 			interrupt-controller;
 			#interrupt-cells = <2>;
+			#address-cells = <0>;
 			reg = <0x5000d000 0x400>;
+
+			exti-interrupt-map {
+				#address-cells = <0>;
+				#interrupt-cells = <2>;
+				interrupt-map-mask = <0xffffffff 0>;
+				interrupt-map =
+					<0  0 &intc GIC_SPI 6   IRQ_TYPE_LEVEL_HIGH>,
+					<1  0 &intc GIC_SPI 7   IRQ_TYPE_LEVEL_HIGH>,
+					<2  0 &intc GIC_SPI 8   IRQ_TYPE_LEVEL_HIGH>,
+					<3  0 &intc GIC_SPI 9   IRQ_TYPE_LEVEL_HIGH>,
+					<4  0 &intc GIC_SPI 10  IRQ_TYPE_LEVEL_HIGH>,
+					<5  0 &intc GIC_SPI 23  IRQ_TYPE_LEVEL_HIGH>,
+					<6  0 &intc GIC_SPI 64  IRQ_TYPE_LEVEL_HIGH>,
+					<7  0 &intc GIC_SPI 65  IRQ_TYPE_LEVEL_HIGH>,
+					<8  0 &intc GIC_SPI 66  IRQ_TYPE_LEVEL_HIGH>,
+					<9  0 &intc GIC_SPI 67  IRQ_TYPE_LEVEL_HIGH>,
+					<10 0 &intc GIC_SPI 40  IRQ_TYPE_LEVEL_HIGH>,
+					<11 0 &intc GIC_SPI 42  IRQ_TYPE_LEVEL_HIGH>,
+					<12 0 &intc GIC_SPI 76  IRQ_TYPE_LEVEL_HIGH>,
+					<13 0 &intc GIC_SPI 77  IRQ_TYPE_LEVEL_HIGH>,
+					<14 0 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+					<15 0 &intc GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+					<16 0 &intc GIC_SPI 1   IRQ_TYPE_LEVEL_HIGH>,
+					<19 0 &intc GIC_SPI 3   IRQ_TYPE_LEVEL_HIGH>,
+					<21 0 &intc GIC_SPI 31  IRQ_TYPE_LEVEL_HIGH>,
+					<22 0 &intc GIC_SPI 33  IRQ_TYPE_LEVEL_HIGH>,
+					<23 0 &intc GIC_SPI 72  IRQ_TYPE_LEVEL_HIGH>,
+					<24 0 &intc GIC_SPI 95  IRQ_TYPE_LEVEL_HIGH>,
+					<25 0 &intc GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+					<26 0 &intc GIC_SPI 37  IRQ_TYPE_LEVEL_HIGH>,
+					<27 0 &intc GIC_SPI 38  IRQ_TYPE_LEVEL_HIGH>,
+					<28 0 &intc GIC_SPI 39  IRQ_TYPE_LEVEL_HIGH>,
+					<29 0 &intc GIC_SPI 71  IRQ_TYPE_LEVEL_HIGH>,
+					<30 0 &intc GIC_SPI 52  IRQ_TYPE_LEVEL_HIGH>,
+					<31 0 &intc GIC_SPI 53  IRQ_TYPE_LEVEL_HIGH>,
+					<32 0 &intc GIC_SPI 82  IRQ_TYPE_LEVEL_HIGH>,
+					<33 0 &intc GIC_SPI 83  IRQ_TYPE_LEVEL_HIGH>,
+					<46 0 &intc GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+					<47 0 &intc GIC_SPI 93  IRQ_TYPE_LEVEL_HIGH>,
+					<48 0 &intc GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+					<50 0 &intc GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+					<52 0 &intc GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+					<53 0 &intc GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+					<54 0 &intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+					<61 0 &intc GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+					<65 0 &intc GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+					<68 0 &intc GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+					<70 0 &intc GIC_SPI 62  IRQ_TYPE_LEVEL_HIGH>,
+					<73 0 &intc GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+			};
 		};
 
 		syscfg: syscon at 50020000 {
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:57 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:57 +0100
Subject: [PATCH 12/12] arm64: dts: st: Add interrupt parent to pinctrl on stm32mp251
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-13-antonio.borneo@foss.st.com>

Add exti1 as interrupt parent for the two pin controllers.
Add the additional required property st,syscfg.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 4253f5bcd000..6d46450afd4d 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -254,6 +254,8 @@ pinctrl: pinctrl at 44240000 {
 			#size-cells = <1>;
 			compatible = "st,stm32mp257-pinctrl";
 			ranges = <0 0x44240000 0xa0400>;
+			interrupt-parent = <&exti1>;
+			st,syscfg = <&exti1 0x60 0xff>;
 			pins-are-numbered;
 
 			gpioa: gpio at 44240000 {
@@ -383,6 +385,8 @@ pinctrl_z: pinctrl at 46200000 {
 			#size-cells = <1>;
 			compatible = "st,stm32mp257-z-pinctrl";
 			ranges = <0 0x46200000 0x400>;
+			interrupt-parent = <&exti1>;
+			st,syscfg = <&exti1 0x60 0xff>;
 			pins-are-numbered;
 
 			gpioz: gpio at 46200000 {
-- 
2.34.1



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:56 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:56 +0100
Subject: [PATCH 11/12] arm64: dts: st: Add exti1 and exti2 nodes on stm32mp251
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-12-antonio.borneo@foss.st.com>

Update the device-tree stm32mp251.dtsi by adding the nodes for
exti1 and exti2 interrupt controllers.

Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 140 +++++++++++++++++++++++++
 1 file changed, 140 insertions(+)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 5c9095382cc7..4253f5bcd000 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -164,6 +164,86 @@ package_otp at 1e8 {
 			};
 		};
 
+		exti1: interrupt-controller at 44220000 {
+			compatible = "st,stm32mp1-exti", "syscon";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			#address-cells = <0>;
+			reg = <0x44220000 0x400>;
+
+			exti-interrupt-map {
+				#address-cells = <0>;
+				#interrupt-cells = <2>;
+				interrupt-map-mask = <0xffffffff 0>;
+				interrupt-map =
+					<0  0 &intc 0 0 GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
+					<1  0 &intc 0 0 GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>,
+					<2  0 &intc 0 0 GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>,
+					<3  0 &intc 0 0 GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>,
+					<4  0 &intc 0 0 GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>,
+					<5  0 &intc 0 0 GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
+					<6  0 &intc 0 0 GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+					<7  0 &intc 0 0 GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
+					<8  0 &intc 0 0 GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
+					<9  0 &intc 0 0 GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
+					<10 0 &intc 0 0 GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
+					<11 0 &intc 0 0 GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+					<12 0 &intc 0 0 GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+					<13 0 &intc 0 0 GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+					<14 0 &intc 0 0 GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+					<15 0 &intc 0 0 GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+					<16 0 &intc 0 0 GIC_SPI 0   IRQ_TYPE_LEVEL_HIGH>,
+					<17 0 &intc 0 0 GIC_SPI 1   IRQ_TYPE_LEVEL_HIGH>,
+					<18 0 &intc 0 0 GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+					<19 0 &intc 0 0 GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
+					<21 0 &intc 0 0 GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+					<22 0 &intc 0 0 GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+					<23 0 &intc 0 0 GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+					<24 0 &intc 0 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
+					<25 0 &intc 0 0 GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+					<26 0 &intc 0 0 GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+					<27 0 &intc 0 0 GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+					<28 0 &intc 0 0 GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+					<29 0 &intc 0 0 GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+					<30 0 &intc 0 0 GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+					<31 0 &intc 0 0 GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+					<32 0 &intc 0 0 GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+					<33 0 &intc 0 0 GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+					<34 0 &intc 0 0 GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+					<36 0 &intc 0 0 GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+					<37 0 &intc 0 0 GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+					<38 0 &intc 0 0 GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+					<39 0 &intc 0 0 GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+					<40 0 &intc 0 0 GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+					<41 0 &intc 0 0 GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
+					<42 0 &intc 0 0 GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+					<43 0 &intc 0 0 GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
+					<44 0 &intc 0 0 GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+					<45 0 &intc 0 0 GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>,
+					<46 0 &intc 0 0 GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
+					<47 0 &intc 0 0 GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>,
+					<48 0 &intc 0 0 GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
+					<49 0 &intc 0 0 GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
+					<50 0 &intc 0 0 GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
+					<59 0 &intc 0 0 GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
+					<61 0 &intc 0 0 GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
+					<64 0 &intc 0 0 GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
+					<67 0 &intc 0 0 GIC_SPI 10  IRQ_TYPE_LEVEL_HIGH>,
+					<68 0 &intc 0 0 GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					<70 0 &intc 0 0 GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+					<72 0 &intc 0 0 GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>,
+					<73 0 &intc 0 0 GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>,
+					<74 0 &intc 0 0 GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+					<75 0 &intc 0 0 GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+					<76 0 &intc 0 0 GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+					<77 0 &intc 0 0 GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>,
+					<78 0 &intc 0 0 GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
+					<79 0 &intc 0 0 GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>,
+					<83 0 &intc 0 0 GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
+					<84 0 &intc 0 0 GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>;
+			};
+		};
+
 		syscfg: syscon at 44230000 {
 			compatible = "st,stm32mp25-syscfg", "syscon";
 			reg = <0x44230000 0x10000>;
@@ -318,5 +398,65 @@ gpioz: gpio at 46200000 {
 			};
 
 		};
+
+		exti2: interrupt-controller at 46230000 {
+			compatible = "st,stm32mp1-exti", "syscon";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			#address-cells = <0>;
+			reg = <0x46230000 0x400>;
+
+			exti-interrupt-map {
+				#address-cells = <0>;
+				#interrupt-cells = <2>;
+				interrupt-map-mask = <0xffffffff 0>;
+				interrupt-map =
+					<0  0 &intc 0 0 GIC_SPI 17  IRQ_TYPE_LEVEL_HIGH>,
+					<1  0 &intc 0 0 GIC_SPI 18  IRQ_TYPE_LEVEL_HIGH>,
+					<2  0 &intc 0 0 GIC_SPI 19  IRQ_TYPE_LEVEL_HIGH>,
+					<3  0 &intc 0 0 GIC_SPI 20  IRQ_TYPE_LEVEL_HIGH>,
+					<4  0 &intc 0 0 GIC_SPI 21  IRQ_TYPE_LEVEL_HIGH>,
+					<5  0 &intc 0 0 GIC_SPI 22  IRQ_TYPE_LEVEL_HIGH>,
+					<6  0 &intc 0 0 GIC_SPI 23  IRQ_TYPE_LEVEL_HIGH>,
+					<7  0 &intc 0 0 GIC_SPI 24  IRQ_TYPE_LEVEL_HIGH>,
+					<8  0 &intc 0 0 GIC_SPI 25  IRQ_TYPE_LEVEL_HIGH>,
+					<9  0 &intc 0 0 GIC_SPI 26  IRQ_TYPE_LEVEL_HIGH>,
+					<10 0 &intc 0 0 GIC_SPI 27  IRQ_TYPE_LEVEL_HIGH>,
+					<11 0 &intc 0 0 GIC_SPI 28  IRQ_TYPE_LEVEL_HIGH>,
+					<12 0 &intc 0 0 GIC_SPI 29  IRQ_TYPE_LEVEL_HIGH>,
+					<13 0 &intc 0 0 GIC_SPI 30  IRQ_TYPE_LEVEL_HIGH>,
+					<14 0 &intc 0 0 GIC_SPI 31  IRQ_TYPE_LEVEL_HIGH>,
+					<15 0 &intc 0 0 GIC_SPI 32  IRQ_TYPE_LEVEL_HIGH>,
+					<16 0 &intc 0 0 GIC_SPI 12  IRQ_TYPE_LEVEL_HIGH>,
+					<17 0 &intc 0 0 GIC_SPI 13  IRQ_TYPE_LEVEL_HIGH>,
+					<21 0 &intc 0 0 GIC_SPI 14  IRQ_TYPE_LEVEL_HIGH>,
+					<22 0 &intc 0 0 GIC_SPI 15  IRQ_TYPE_LEVEL_HIGH>,
+					<25 0 &intc 0 0 GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
+					<26 0 &intc 0 0 GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+					<27 0 &intc 0 0 GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
+					<29 0 &intc 0 0 GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
+					<30 0 &intc 0 0 GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
+					<31 0 &intc 0 0 GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+					<33 0 &intc 0 0 GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>,
+					<34 0 &intc 0 0 GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>,
+					<37 0 &intc 0 0 GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>,
+					<40 0 &intc 0 0 GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
+					<43 0 &intc 0 0 GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
+					<46 0 &intc 0 0 GIC_SPI 11  IRQ_TYPE_LEVEL_HIGH>,
+					<48 0 &intc 0 0 GIC_SPI 5   IRQ_TYPE_LEVEL_HIGH>,
+					<49 0 &intc 0 0 GIC_SPI 4   IRQ_TYPE_LEVEL_HIGH>,
+					<50 0 &intc 0 0 GIC_SPI 6   IRQ_TYPE_LEVEL_HIGH>,
+					<51 0 &intc 0 0 GIC_SPI 7   IRQ_TYPE_LEVEL_HIGH>,
+					<52 0 &intc 0 0 GIC_SPI 2   IRQ_TYPE_LEVEL_HIGH>,
+					<53 0 &intc 0 0 GIC_SPI 3   IRQ_TYPE_LEVEL_HIGH>,
+					<61 0 &intc 0 0 GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
+					<62 0 &intc 0 0 GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
+					<64 0 &intc 0 0 GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>,
+					<65 0 &intc 0 0 GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>,
+					<66 0 &intc 0 0 GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>,
+					<67 0 &intc 0 0 GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+					<70 0 &intc 0 0 GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>;
+			};
+		};
 	};
 };
-- 
2.34.1



From shreeya.patel at collabora.com  Fri Feb 16 01:49:18 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Fri, 16 Feb 2024 15:19:18 +0530
Subject: [PATCH 0/4] Add Synopsys DesignWare HDMI RX Controller
Message-ID: <20240216094922.257674-1-shreeya.patel@collabora.com>

This series implements support for the Synopsys DesignWare
HDMI RX Controller, being compliant with standard HDMI 1.4b
and HDMI 2.0.

Features that are currently supported by the HDMI RX driver
have been tested on rock5b board using a HDMI to micro-HDMI cable.
It is recommended to use a good quality cable as there were
multiple issues seen during testing the driver.

Please note the below information :-
* This patch series depends on series from Sebastian [0] about
improving GATE_LINK support.
* While testing the driver on rock5b we noticed that the binary BL31
from Rockchip contains some unknown code to get the HDMI-RX PHY
access working. With TF-A BL31, the HDMI-RX PHY doesn't work as
expected since there are no interrupts seen for rk_hdmirx-hdmi
leading to some failures in the driver [1].

[0] https://lore.kernel.org/all/20240126182919.48402-1-sebastian.reichel at collabora.com/
[1] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/trusted-firmware-a/-/issues/1

To test the HDMI RX Controller driver, following example commands can be used :-

root at debian-rockchip-rock5b-rk3588:~# v4l2-ctl --verbose -d /dev/video0 \
--set-fmt-video=width=1920,height=1080,pixelformat='BGR3' --stream-mmap=4 \
--stream-skip=3 --stream-count=100 --stream-to=/home/hdmiin4k.raw --stream-poll

root at debian-rockchip-rock5b-rk3588:~# ffmpeg -f rawvideo -vcodec rawvideo \
-s 1920x1080 -r 60 -pix_fmt bgr24 -i /home/hdmiin4k.raw output.mkv


Following is the v4l2-compliance test result :-

root at debian-rockchip-rock5b-rk3588:~# v4l2-compliance -d /dev/video0
v4l2-compliance 1.27.0-5174, 64 bits, 64-bit time_t
v4l2-compliance SHA: d700deb14368 2024-01-18 12:19:05

Compliance test for snps_hdmirx device /dev/video0:

Driver Info:
        Driver name      : snps_hdmirx
        Card type        : snps_hdmirx
        Bus info         : platform: snps_hdmirx
        Driver version   : 6.8.0
        Capabilities     : 0x84201000
                Video Capture Multiplanar
                Streaming
                Extended Pix Format
                Device Capabilities
        Device Caps      : 0x04201000
                Video Capture Multiplanar
                Streaming
                Extended Pix Format

Required ioctls:
        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

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
        test VIDIOC_G/S_AUDIO: OK (Not Supported)
        Inputs: 1 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
        test VIDIOC_DV_TIMINGS_CAP: OK
        test VIDIOC_G/S_EDID: OK

Control ioctls (Input 0):
        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: 2 Private Controls: 0

Format ioctls (Input 0):
        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 (Not Supported)
        test Composing: OK (Not Supported)
        test Scaling: OK (Not Supported)

Codec ioctls (Input 0):
        test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
        test VIDIOC_G_ENC_INDEX: OK (Not Supported)
        test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls (Input 0):
        test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
        test CREATE_BUFS maximum buffers: OK
        test VIDIOC_EXPBUF: OK
        test Requests: OK (Not Supported)

Total for snps_hdmirx device /dev/video0: 46, Succeeded: 46, Failed: 0, Warnings: 0

Shreeya Patel (4):
  clk: rockchip: rst-rk3588: Add BIU reset
  dt-bindings: media: Document bindings for HDMI RX Controller
  arm64: dts: rockchip: Add device tree support for HDMI RX Controller
  media: platform: synopsys: Add support for hdmi input driver

 .../bindings/media/snps,dw-hdmi-rx.yaml       |  128 +
 .../boot/dts/rockchip/rk3588-pinctrl.dtsi     |   41 +
 arch/arm64/boot/dts/rockchip/rk3588.dtsi      |   50 +
 drivers/clk/rockchip/rst-rk3588.c             |    1 +
 drivers/media/platform/Kconfig                |    1 +
 drivers/media/platform/Makefile               |    1 +
 drivers/media/platform/synopsys/Kconfig       |    3 +
 drivers/media/platform/synopsys/Makefile      |    2 +
 .../media/platform/synopsys/hdmirx/Kconfig    |   18 +
 .../media/platform/synopsys/hdmirx/Makefile   |    4 +
 .../platform/synopsys/hdmirx/snps_hdmirx.c    | 2856 +++++++++++++++++
 .../platform/synopsys/hdmirx/snps_hdmirx.h    |  394 +++
 .../synopsys/hdmirx/snps_hdmirx_cec.c         |  289 ++
 .../synopsys/hdmirx/snps_hdmirx_cec.h         |   46 +
 .../dt-bindings/reset/rockchip,rk3588-cru.h   |    2 +
 15 files changed, 3836 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
 create mode 100644 drivers/media/platform/synopsys/Kconfig
 create mode 100644 drivers/media/platform/synopsys/Makefile
 create mode 100644 drivers/media/platform/synopsys/hdmirx/Kconfig
 create mode 100644 drivers/media/platform/synopsys/hdmirx/Makefile
 create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
 create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
 create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.c
 create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.h

-- 
2.39.2



From antonio.borneo at foss.st.com  Fri Feb 16 01:47:55 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 16 Feb 2024 10:47:55 +0100
Subject: [PATCH 10/12] arm64: dts: st: Add v2m to GIC node on stm32mp251
In-Reply-To: <20240216094758.916722-1-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
Message-ID: <20240216094758.916722-11-antonio.borneo@foss.st.com>

From: Christian Bruel <christian.bruel at foss.st.com>

The GIC of STM32MP25 includes v2m extension for PCIEe MSI support.

Add the v2m sub-node to the GIC interrupt controller and adapt the
other properties accordingly.

Signed-off-by: Christian Bruel <christian.bruel at foss.st.com>
Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp251.dtsi | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 96859d098ef8..5c9095382cc7 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -81,12 +81,20 @@ scmi_reset: protocol at 16 {
 	intc: interrupt-controller at 4ac00000 {
 		compatible = "arm,cortex-a7-gic";
 		#interrupt-cells = <3>;
-		#address-cells = <1>;
+		#address-cells = <2>;
+		#size-cells = <2>;
 		interrupt-controller;
 		reg = <0x0 0x4ac10000 0x0 0x1000>,
 		      <0x0 0x4ac20000 0x0 0x2000>,
 		      <0x0 0x4ac40000 0x0 0x2000>,
 		      <0x0 0x4ac60000 0x0 0x2000>;
+		ranges;
+
+		v2m0: v2m at 48090000 {
+			compatible = "arm,gic-v2m-frame";
+			reg = <0x0 0x48090000 0x0 0x1000>;
+			msi-controller;
+		};
 	};
 
 	psci {
-- 
2.34.1



From shreeya.patel at collabora.com  Fri Feb 16 01:49:19 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Fri, 16 Feb 2024 15:19:19 +0530
Subject: [PATCH 1/4] clk: rockchip: rst-rk3588: Add BIU reset
In-Reply-To: <20240216094922.257674-1-shreeya.patel@collabora.com>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
Message-ID: <20240216094922.257674-2-shreeya.patel@collabora.com>

Export hdmirx_biu soft reset id which is required by the hdmirx controller.

Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
---
 drivers/clk/rockchip/rst-rk3588.c               | 1 +
 include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/clk/rockchip/rst-rk3588.c b/drivers/clk/rockchip/rst-rk3588.c
index e855bb8d5413..c4ebc01f1c9c 100644
--- a/drivers/clk/rockchip/rst-rk3588.c
+++ b/drivers/clk/rockchip/rst-rk3588.c
@@ -577,6 +577,7 @@ static const int rk3588_register_offset[] = {
 
 	/* SOFTRST_CON59 */
 	RK3588_CRU_RESET_OFFSET(SRST_A_HDCP1_BIU, 59, 6),
+	RK3588_CRU_RESET_OFFSET(SRST_A_HDMIRX_BIU, 59, 7),
 	RK3588_CRU_RESET_OFFSET(SRST_A_VO1_BIU, 59, 8),
 	RK3588_CRU_RESET_OFFSET(SRST_H_VOP1_BIU, 59, 9),
 	RK3588_CRU_RESET_OFFSET(SRST_H_VOP1_S_BIU, 59, 10),
diff --git a/include/dt-bindings/reset/rockchip,rk3588-cru.h b/include/dt-bindings/reset/rockchip,rk3588-cru.h
index d4264db2a07f..e2fe4bd5f7f0 100644
--- a/include/dt-bindings/reset/rockchip,rk3588-cru.h
+++ b/include/dt-bindings/reset/rockchip,rk3588-cru.h
@@ -751,4 +751,6 @@
 #define SRST_P_TRNG_CHK			658
 #define SRST_TRNG_S			659
 
+#define SRST_A_HDMIRX_BIU		660
+
 #endif
-- 
2.39.2



From shreeya.patel at collabora.com  Fri Feb 16 01:49:20 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Fri, 16 Feb 2024 15:19:20 +0530
Subject: [PATCH 2/4] dt-bindings: media: Document bindings for HDMI RX Controller
In-Reply-To: <20240216094922.257674-1-shreeya.patel@collabora.com>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
Message-ID: <20240216094922.257674-3-shreeya.patel@collabora.com>

Document bindings for the Synopsys DesignWare HDMI RX Controller.

Reviewed-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
---
 .../bindings/media/snps,dw-hdmi-rx.yaml       | 128 ++++++++++++++++++
 1 file changed, 128 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml

diff --git a/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
new file mode 100644
index 000000000000..a70d96b548ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
@@ -0,0 +1,128 @@
+# SPDX-License-Identifier: (GPL-3.0 OR BSD-2-Clause)
+# Device Tree bindings for Synopsys DesignWare HDMI RX Controller
+
+---
+$id: http://devicetree.org/schemas/media/snps,dw-hdmi-rx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Synopsys DesignWare HDMI RX Controller
+
+maintainers:
+  - Shreeya Patel <shreeya.patel at collabora.com>
+
+properties:
+  compatible:
+    items:
+      - const: rockchip,rk3588-hdmirx-ctrler
+      - const: snps,dw-hdmi-rx
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: cec
+      - const: hdmi
+      - const: dma
+
+  clocks:
+    maxItems: 7
+
+  clock-names:
+    items:
+      - const: aclk
+      - const: audio
+      - const: cr_para
+      - const: pclk
+      - const: ref
+      - const: hclk_s_hdmirx
+      - const: hclk_vo1
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 4
+
+  reset-names:
+    items:
+      - const: rst_a
+      - const: rst_p
+      - const: rst_ref
+      - const: rst_biu
+
+  pinctrl-names:
+    const: default
+
+  memory-region:
+    maxItems: 1
+
+  hdmirx-5v-detection-gpios:
+    description: GPIO specifier for 5V detection.
+    maxItems: 1
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the GRF register.
+
+  rockchip,vo1_grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the VO1 GRF register.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - clocks
+  - clock-names
+  - power-domains
+  - resets
+  - pinctrl-0
+  - pinctrl-names
+  - hdmirx-5v-detection-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/rk3588-power.h>
+    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+    hdmirx_ctrler: hdmirx-controller at fdee0000 {
+      compatible = "rockchip,rk3588-hdmirx-ctrler", "snps,dw-hdmi-rx";
+      reg = <0x0 0xfdee0000 0x0 0x6000>;
+      interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>,
+                   <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH 0>,
+                   <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH 0>;
+      interrupt-names = "cec", "hdmi", "dma";
+      clocks = <&cru ACLK_HDMIRX>,
+               <&cru CLK_HDMIRX_AUD>,
+               <&cru CLK_CR_PARA>,
+               <&cru PCLK_HDMIRX>,
+               <&cru CLK_HDMIRX_REF>,
+               <&cru PCLK_S_HDMIRX>,
+               <&cru HCLK_VO1>;
+      clock-names = "aclk",
+                    "audio",
+                    "cr_para",
+                    "pclk",
+                    "ref",
+                    "hclk_s_hdmirx",
+                    "hclk_vo1";
+      power-domains = <&power RK3588_PD_VO1>;
+      resets = <&cru SRST_A_HDMIRX>, <&cru SRST_P_HDMIRX>,
+               <&cru SRST_HDMIRX_REF>, <&cru SRST_A_HDMIRX_BIU>;
+      reset-names = "rst_a", "rst_p", "rst_ref", "rst_biu";
+      pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin &hdmim1_rx_scl &hdmim1_rx_sda &hdmirx_5v_detection>;
+      pinctrl-names = "default";
+      memory-region = <&hdmirx_cma>;
+      hdmirx-5v-detection-gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_LOW>;
+    };
-- 
2.39.2



From shreeya.patel at collabora.com  Fri Feb 16 01:49:21 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Fri, 16 Feb 2024 15:19:21 +0530
Subject: [PATCH 3/4] arm64: dts: rockchip: Add device tree support for HDMI RX Controller
In-Reply-To: <20240216094922.257674-1-shreeya.patel@collabora.com>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
Message-ID: <20240216094922.257674-4-shreeya.patel@collabora.com>

Add device tree support for Synopsys DesignWare HDMI RX
Controller.

Signed-off-by: Dingxian Wen <shawn.wen at rock-chips.com>
Co-developed-by: Shreeya Patel <shreeya.patel at collabora.com>
Reviewed-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
Tested-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
---
 .../boot/dts/rockchip/rk3588-pinctrl.dtsi     | 41 +++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3588.dtsi      | 50 +++++++++++++++++++
 2 files changed, 91 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-pinctrl.dtsi
index 244c66faa161..4fbe194d96b1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-pinctrl.dtsi
@@ -169,6 +169,47 @@ hdmim0_tx1_sda: hdmim0-tx1-sda {
 				/* hdmim0_tx1_sda */
 				<2 RK_PB4 4 &pcfg_pull_none>;
 		};
+
+		/omit-if-no-ref/
+		hdmim1_rx: hdmim1-rx {
+			rockchip,pins =
+				/* hdmim1_rx_cec */
+				<3 RK_PD1 5 &pcfg_pull_none>,
+				/* hdmim1_rx_scl */
+				<3 RK_PD2 5 &pcfg_pull_none_smt>,
+				/* hdmim1_rx_sda */
+				<3 RK_PD3 5 &pcfg_pull_none_smt>,
+				/* hdmim1_rx_hpdin */
+				<3 RK_PD4 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_rx_cec: hdmim1-rx-cec {
+			rockchip,pins =
+				/* hdmim1_rx_cec */
+				<3 RK_PD1 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_rx_hpdin: hdmim1-rx-hpdin {
+			rockchip,pins =
+				/* hdmim1_rx_hpdin */
+				<3 RK_PD4 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_rx_scl: hdmim1-rx-scl {
+			rockchip,pins =
+				/* hdmim1_rx_scl */
+				<3 RK_PD2 5 &pcfg_pull_none>;
+		};
+
+		/omit-if-no-ref/
+		hdmim1_rx_sda: hdmim1-rx-sda {
+			rockchip,pins =
+				/* hdmim1_rx_sda */
+				<3 RK_PD3 5 &pcfg_pull_none>;
+		};
 	};
 
 	i2c0 {
diff --git a/arch/arm64/boot/dts/rockchip/rk3588.dtsi b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
index 5519c1430cb7..8138b6ee388f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
@@ -7,6 +7,24 @@
 #include "rk3588-pinctrl.dtsi"
 
 / {
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		/*
+		 * The 4k HDMI capture controller works only with 32bit
+		 * phys addresses and doesn't support IOMMU. HDMI RX CMA
+		 * must be reserved below 4GB.
+		 */
+		hdmirx_cma: hdmirx_cma {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x0 0x0 0xffffffff>;
+			size = <0x0 (160 * 0x100000)>; /* 160MiB */
+			no-map;
+			status = "disabled";
+		};
+	};
+
 	pcie30_phy_grf: syscon at fd5b8000 {
 		compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon";
 		reg = <0x0 0xfd5b8000 0x0 0x10000>;
@@ -85,6 +103,38 @@ i2s10_8ch: i2s at fde00000 {
 		status = "disabled";
 	};
 
+	hdmirx_ctrler: hdmirx-controller at fdee0000 {
+		compatible = "rockchip,rk3588-hdmirx-ctrler", "snps,dw-hdmi-rx";
+		reg = <0x0 0xfdee0000 0x0 0x6000>;
+		power-domains = <&power RK3588_PD_VO1>;
+		rockchip,grf = <&sys_grf>;
+		rockchip,vo1_grf = <&vo1_grf>;
+		interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "cec", "hdmi", "dma";
+		clocks = <&cru ACLK_HDMIRX>,
+			 <&cru CLK_HDMIRX_AUD>,
+			 <&cru CLK_CR_PARA>,
+			 <&cru PCLK_HDMIRX>,
+			 <&cru CLK_HDMIRX_REF>,
+			 <&cru PCLK_S_HDMIRX>,
+			 <&cru HCLK_VO1>;
+		clock-names = "aclk",
+			      "audio",
+			      "cr_para",
+			      "pclk",
+			      "ref",
+			      "hclk_s_hdmirx",
+			      "hclk_vo1";
+		resets = <&cru SRST_A_HDMIRX>, <&cru SRST_P_HDMIRX>,
+			 <&cru SRST_HDMIRX_REF>, <&cru SRST_A_HDMIRX_BIU>;
+		reset-names = "rst_a", "rst_p", "rst_ref", "rst_biu";
+		pinctrl-0 = <&hdmim1_rx>;
+		pinctrl-names = "default";
+		status = "disabled";
+	};
+
 	pcie3x4: pcie at fe150000 {
 		compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
 		#address-cells = <3>;
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:47 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:47 +0900
Subject: [PATCH v12 01/12] media: rkisp1: Add and use rkisp1_has_feature() macro
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-2-paul.elder@ideasonboard.com>

From: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Simplify feature tests with a macro that shortens lines.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 .../media/platform/rockchip/rkisp1/rkisp1-common.h   |  3 +++
 drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c  | 12 ++++++------
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index b757f75edecf..be6cb42776b0 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -119,6 +119,9 @@ enum rkisp1_feature {
 	RKISP1_FEATURE_MIPI_CSI2 = BIT(0),
 };
 
+#define rkisp1_has_feature(rkisp1, feature) \
+	((rkisp1)->info->features & RKISP1_FEATURE_##feature)
+
 /*
  * struct rkisp1_info - Model-specific ISP Information
  *
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index 73cf08a74011..fd35fe76413a 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -207,7 +207,7 @@ static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1)
 		switch (reg) {
 		case 0:
 			/* MIPI CSI-2 port */
-			if (!(rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)) {
+			if (!rkisp1_has_feature(rkisp1, MIPI_CSI2)) {
 				dev_err(rkisp1->dev,
 					"internal CSI must be available for port 0\n");
 				ret = -EINVAL;
@@ -361,7 +361,7 @@ static int rkisp1_create_links(struct rkisp1_device *rkisp1)
 	unsigned int i;
 	int ret;
 
-	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
+	if (rkisp1_has_feature(rkisp1, MIPI_CSI2)) {
 		/* Link the CSI receiver to the ISP. */
 		ret = media_create_pad_link(&rkisp1->csi.sd.entity,
 					    RKISP1_CSI_PAD_SRC,
@@ -413,7 +413,7 @@ static int rkisp1_create_links(struct rkisp1_device *rkisp1)
 
 static void rkisp1_entities_unregister(struct rkisp1_device *rkisp1)
 {
-	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
+	if (rkisp1_has_feature(rkisp1, MIPI_CSI2))
 		rkisp1_csi_unregister(rkisp1);
 	rkisp1_params_unregister(rkisp1);
 	rkisp1_stats_unregister(rkisp1);
@@ -446,7 +446,7 @@ static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
 	if (ret)
 		goto error;
 
-	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
+	if (rkisp1_has_feature(rkisp1, MIPI_CSI2)) {
 		ret = rkisp1_csi_register(rkisp1);
 		if (ret)
 			goto error;
@@ -650,7 +650,7 @@ static int rkisp1_probe(struct platform_device *pdev)
 err_unreg_entities:
 	rkisp1_entities_unregister(rkisp1);
 err_cleanup_csi:
-	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
+	if (rkisp1_has_feature(rkisp1, MIPI_CSI2))
 		rkisp1_csi_cleanup(rkisp1);
 err_unreg_media_dev:
 	media_device_unregister(&rkisp1->media_dev);
@@ -671,7 +671,7 @@ static void rkisp1_remove(struct platform_device *pdev)
 	v4l2_async_nf_cleanup(&rkisp1->notifier);
 
 	rkisp1_entities_unregister(rkisp1);
-	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
+	if (rkisp1_has_feature(rkisp1, MIPI_CSI2))
 		rkisp1_csi_cleanup(rkisp1);
 	rkisp1_debug_cleanup(rkisp1);
 
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:48 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:48 +0900
Subject: [PATCH v12 02/12] media: rkisp1: Support setting memory stride for main path
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-3-paul.elder@ideasonboard.com>

Some versions of the ISP supported by the rkisp1 driver, such as the ISP
in the i.MX8MP, implement configurable memory stride for the main path
the same way as already implemented by the driver for the self path.
Support this feature by adding a main stride feature flag and program
the corresponding registers accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
Changes since v3:

- Implement memory stride support
- Squash patch that adds register bits definitions
- Reword the commit message

Changes since v2:

- Document the RKISP1_FEATURE_MAIN_STRIDE bit
- Use the rkisp1_has_feature() macro
---
 .../platform/rockchip/rkisp1/rkisp1-capture.c | 34 ++++++++++++-------
 .../platform/rockchip/rkisp1/rkisp1-common.h  |  6 ++--
 .../platform/rockchip/rkisp1/rkisp1-regs.h    | 27 +++++++++++++++
 3 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
index c381c22135a2..83a968487f24 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
@@ -442,6 +442,14 @@ static void rkisp1_mp_config(struct rkisp1_capture *cap)
 	rkisp1_write(rkisp1, cap->config->mi.cr_size_init,
 		     rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR));
 
+	if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
+		rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_LLENGTH, cap->stride);
+		rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_PIC_WIDTH, pixm->width);
+		rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_PIC_HEIGHT, pixm->height);
+		rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_PIC_SIZE,
+			     cap->stride * pixm->height);
+	}
+
 	rkisp1_irq_frame_end_enable(cap);
 
 	/* set uv swapping for semiplanar formats */
@@ -479,11 +487,11 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap)
 	rkisp1_write(rkisp1, cap->config->mi.cr_size_init,
 		     rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR));
 
-	rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_LLENGTH, cap->sp_y_stride);
+	rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_LLENGTH, cap->stride);
 	rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_PIC_WIDTH, pixm->width);
 	rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_PIC_HEIGHT, pixm->height);
 	rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_PIC_SIZE,
-		     cap->sp_y_stride * pixm->height);
+		     cap->stride * pixm->height);
 
 	rkisp1_irq_frame_end_enable(cap);
 
@@ -1095,8 +1103,8 @@ static const struct vb2_ops rkisp1_vb2_ops = {
  */
 
 static const struct v4l2_format_info *
-rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
-		   enum rkisp1_stream_id id)
+rkisp1_fill_pixfmt(const struct rkisp1_capture *cap,
+		   struct v4l2_pix_format_mplane *pixm)
 {
 	struct v4l2_plane_pix_format *plane_y = &pixm->plane_fmt[0];
 	const struct v4l2_format_info *info;
@@ -1109,10 +1117,13 @@ rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
 
 	/*
 	 * The SP supports custom strides, expressed as a number of pixels for
-	 * the Y plane. Clamp the stride to a reasonable value to avoid integer
-	 * overflows when calculating the bytesperline and sizeimage values.
+	 * the Y plane, and so does the MP in ISP versions that have the
+	 * MAIN_STRIDE feature. Clamp the stride to a reasonable value to avoid
+	 * integer overflows when calculating the bytesperline and sizeimage
+	 * values.
 	 */
-	if (id == RKISP1_SELFPATH)
+	if (cap->id == RKISP1_SELFPATH ||
+	    rkisp1_has_feature(cap->rkisp1, MAIN_STRIDE))
 		stride = clamp(DIV_ROUND_UP(plane_y->bytesperline, info->bpp[0]),
 			       pixm->width, 65536U);
 	else
@@ -1187,7 +1198,7 @@ static void rkisp1_try_fmt(const struct rkisp1_capture *cap,
 	pixm->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
 	pixm->quantization = V4L2_QUANTIZATION_DEFAULT;
 
-	info = rkisp1_fill_pixfmt(pixm, cap->id);
+	info = rkisp1_fill_pixfmt(cap, pixm);
 
 	if (fmt_cfg)
 		*fmt_cfg = fmt;
@@ -1199,12 +1210,9 @@ static void rkisp1_set_fmt(struct rkisp1_capture *cap,
 			   struct v4l2_pix_format_mplane *pixm)
 {
 	rkisp1_try_fmt(cap, pixm, &cap->pix.cfg, &cap->pix.info);
-	cap->pix.fmt = *pixm;
 
-	/* SP supports custom stride in number of pixels of the Y plane */
-	if (cap->id == RKISP1_SELFPATH)
-		cap->sp_y_stride = pixm->plane_fmt[0].bytesperline /
-				   cap->pix.info->bpp[0];
+	cap->pix.fmt = *pixm;
+	cap->stride = pixm->plane_fmt[0].bytesperline / cap->pix.info->bpp[0];
 }
 
 static int rkisp1_try_fmt_vid_cap_mplane(struct file *file, void *fh,
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index be6cb42776b0..6a811b7ef1b9 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -110,6 +110,7 @@ enum rkisp1_isp_pad {
  * enum rkisp1_feature - ISP features
  *
  * @RKISP1_FEATURE_MIPI_CSI2: The ISP has an internal MIPI CSI-2 receiver
+ * @RKISP1_FEATURE_MAIN_STRIDE: The ISP supports configurable stride on the main path
  *
  * The ISP features are stored in a bitmask in &rkisp1_info.features and allow
  * the driver to implement support for features present in some ISP versions
@@ -117,6 +118,7 @@ enum rkisp1_isp_pad {
  */
 enum rkisp1_feature {
 	RKISP1_FEATURE_MIPI_CSI2 = BIT(0),
+	RKISP1_FEATURE_MAIN_STRIDE = BIT(1),
 };
 
 #define rkisp1_has_feature(rkisp1, feature) \
@@ -266,7 +268,7 @@ struct rkisp1_device;
  *		  handler to stop the streaming by waiting on the 'done' wait queue.
  *		  If the irq handler is not called, the stream is stopped by the callback
  *		  after timeout.
- * @sp_y_stride:  the selfpath allows to configure a y stride that is longer than the image width.
+ * @stride:       the line stride for the first plane, in pixel units
  * @buf.lock:	  lock to protect buf.queue
  * @buf.queue:	  queued buffer list
  * @buf.dummy:	  dummy space to store dropped data
@@ -287,7 +289,7 @@ struct rkisp1_capture {
 	bool is_streaming;
 	bool is_stopping;
 	wait_queue_head_t done;
-	unsigned int sp_y_stride;
+	unsigned int stride;
 	struct {
 		/* protects queue, curr and next */
 		spinlock_t lock;
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
index bea69a0d766a..3b19c8411360 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
@@ -207,6 +207,24 @@
 #define RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP	BIT(1)
 #define RKISP1_CIF_MI_XTD_FMT_CTRL_DMA_CB_CR_SWAP	BIT(2)
 
+/* MI_OUTPUT_ALIGN_FORMAT */
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_LSB_ALIGNMENT			BIT(0)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES		BIT(1)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_WORDS		BIT(2)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_DWORDS		BIT(3)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_BYTES		BIT(4)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_WORDS		BIT(5)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_DWORDS		BIT(6)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_DMA_BYTE_SWAP_BYTES		BIT(7)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_DMA_BYTE_SWAP_WORDS		BIT(8)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_DMA_BYTE_SWAP_DWORDS		BIT(9)
+
+/* MI_MP_OUTPUT_FIFO_SIZE */
+#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_FULL	(0 << 0)
+#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_HALF	(1 << 0)
+#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_QUARTER	(2 << 0)
+#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_EIGHT	(3 << 0)
+
 /* VI_CCL */
 #define RKISP1_CIF_CCL_CIF_CLK_DIS			BIT(2)
 /* VI_ISP_CLK_CTRL */
@@ -1000,6 +1018,15 @@
 #define RKISP1_CIF_MI_SP_CB_BASE_AD_INIT2	(RKISP1_CIF_MI_BASE + 0x00000140)
 #define RKISP1_CIF_MI_SP_CR_BASE_AD_INIT2	(RKISP1_CIF_MI_BASE + 0x00000144)
 #define RKISP1_CIF_MI_XTD_FORMAT_CTRL		(RKISP1_CIF_MI_BASE + 0x00000148)
+#define RKISP1_CIF_MI_MP_HANDSHAKE_0		(RKISP1_CIF_MI_BASE + 0x0000014C)
+#define RKISP1_CIF_MI_MP_Y_LLENGTH		(RKISP1_CIF_MI_BASE + 0x00000150)
+#define RKISP1_CIF_MI_MP_Y_SLICE_OFFSET		(RKISP1_CIF_MI_BASE + 0x00000154)
+#define RKISP1_CIF_MI_MP_C_SLICE_OFFSET		(RKISP1_CIF_MI_BASE + 0x00000158)
+#define RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT	(RKISP1_CIF_MI_BASE + 0x0000015C)
+#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE	(RKISP1_CIF_MI_BASE + 0x00000160)
+#define RKISP1_CIF_MI_MP_Y_PIC_WIDTH		(RKISP1_CIF_MI_BASE + 0x00000164)
+#define RKISP1_CIF_MI_MP_Y_PIC_HEIGHT		(RKISP1_CIF_MI_BASE + 0x00000168)
+#define RKISP1_CIF_MI_MP_Y_PIC_SIZE		(RKISP1_CIF_MI_BASE + 0x0000016C)
 
 #define RKISP1_CIF_SMIA_BASE			0x00001a00
 #define RKISP1_CIF_SMIA_CTRL			(RKISP1_CIF_SMIA_BASE + 0x00000000)
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:49 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:49 +0900
Subject: [PATCH v12 03/12] media: rkisp1: Support devices lacking self path
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-4-paul.elder@ideasonboard.com>

Some versions of the ISP supported by the rkisp1 driver, such as the ISP
in the i.MX8MP, lack the self path. Support those ISP versions by adding
a self path feature flag, and massage the rest of the driver to support
the lack of a self path.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
Changes since v3:

- Document the feature bit
- Reorder commit

Changes since v2:

- Simplify rkisp1_path_count()
- Use the rkisp1_has_feature() macro
---
 .../platform/rockchip/rkisp1/rkisp1-capture.c     |  9 ++++++---
 .../platform/rockchip/rkisp1/rkisp1-common.h      | 15 +++++++++++++++
 .../media/platform/rockchip/rkisp1/rkisp1-dev.c   |  9 ++++++---
 .../platform/rockchip/rkisp1/rkisp1-resizer.c     |  6 ++++--
 4 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
index 83a968487f24..ca95f62822fa 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
@@ -730,6 +730,7 @@ irqreturn_t rkisp1_capture_isr(int irq, void *ctx)
 {
 	struct device *dev = ctx;
 	struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
+	unsigned int dev_count = rkisp1_path_count(rkisp1);
 	unsigned int i;
 	u32 status;
 
@@ -742,7 +743,7 @@ irqreturn_t rkisp1_capture_isr(int irq, void *ctx)
 
 	rkisp1_write(rkisp1, RKISP1_CIF_MI_ICR, status);
 
-	for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) {
+	for (i = 0; i < dev_count; ++i) {
 		struct rkisp1_capture *cap = &rkisp1->capture_devs[i];
 
 		if (!(status & RKISP1_CIF_MI_FRAME(cap)))
@@ -899,6 +900,7 @@ static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
 {
 	struct rkisp1_device *rkisp1 = cap->rkisp1;
 	struct rkisp1_capture *other = &rkisp1->capture_devs[cap->id ^ 1];
+	bool has_self_path = rkisp1_has_feature(rkisp1, SELF_PATH);
 
 	cap->ops->set_data_path(cap);
 	cap->ops->config(cap);
@@ -916,7 +918,7 @@ static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
 	 * This's also required because the second FE maybe corrupt
 	 * especially when run at 120fps.
 	 */
-	if (!other->is_streaming) {
+	if (!has_self_path || !other->is_streaming) {
 		/* force cfg update */
 		rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT,
 			     RKISP1_CIF_MI_INIT_SOFT_UPD);
@@ -1509,10 +1511,11 @@ rkisp1_capture_init(struct rkisp1_device *rkisp1, enum rkisp1_stream_id id)
 
 int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1)
 {
+	unsigned int dev_count = rkisp1_path_count(rkisp1);
 	unsigned int i;
 	int ret;
 
-	for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); i++) {
+	for (i = 0; i < dev_count; i++) {
 		struct rkisp1_capture *cap = &rkisp1->capture_devs[i];
 
 		rkisp1_capture_init(rkisp1, i);
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index 6a811b7ef1b9..f7c251f79aa9 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -111,6 +111,7 @@ enum rkisp1_isp_pad {
  *
  * @RKISP1_FEATURE_MIPI_CSI2: The ISP has an internal MIPI CSI-2 receiver
  * @RKISP1_FEATURE_MAIN_STRIDE: The ISP supports configurable stride on the main path
+ * @RKISP1_FEATURE_SELF_PATH: The ISP has a self path
  *
  * The ISP features are stored in a bitmask in &rkisp1_info.features and allow
  * the driver to implement support for features present in some ISP versions
@@ -119,6 +120,7 @@ enum rkisp1_isp_pad {
 enum rkisp1_feature {
 	RKISP1_FEATURE_MIPI_CSI2 = BIT(0),
 	RKISP1_FEATURE_MAIN_STRIDE = BIT(1),
+	RKISP1_FEATURE_SELF_PATH = BIT(2),
 };
 
 #define rkisp1_has_feature(rkisp1, feature) \
@@ -531,6 +533,19 @@ int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
  */
 const struct rkisp1_mbus_info *rkisp1_mbus_info_get_by_index(unsigned int index);
 
+/*
+ * rkisp1_path_count - Return the number of paths supported by the device
+ *
+ * Some devices only have a main path, while other device have both a main path
+ * and a self path. This function returns the number of paths that this device
+ * has, based on the feature flags. It should be used insted of checking
+ * ARRAY_SIZE of capture_devs/resizer_devs.
+ */
+static inline unsigned int rkisp1_path_count(struct rkisp1_device *rkisp1)
+{
+	return rkisp1_has_feature(rkisp1, SELF_PATH) ? 2 : 1;
+}
+
 /*
  * rkisp1_sd_adjust_crop_rect - adjust a rectangle to fit into another rectangle.
  *
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index fd35fe76413a..f48a21985b18 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -358,6 +358,7 @@ static const struct dev_pm_ops rkisp1_pm_ops = {
 
 static int rkisp1_create_links(struct rkisp1_device *rkisp1)
 {
+	unsigned int dev_count = rkisp1_path_count(rkisp1);
 	unsigned int i;
 	int ret;
 
@@ -373,7 +374,7 @@ static int rkisp1_create_links(struct rkisp1_device *rkisp1)
 	}
 
 	/* create ISP->RSZ->CAP links */
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < dev_count; i++) {
 		struct media_entity *resizer =
 			&rkisp1->resizer_devs[i].sd.entity;
 		struct media_entity *capture =
@@ -505,7 +506,8 @@ static const struct rkisp1_info px30_isp_info = {
 	.isrs = px30_isp_isrs,
 	.isr_size = ARRAY_SIZE(px30_isp_isrs),
 	.isp_ver = RKISP1_V12,
-	.features = RKISP1_FEATURE_MIPI_CSI2,
+	.features = RKISP1_FEATURE_MIPI_CSI2
+		  | RKISP1_FEATURE_SELF_PATH,
 };
 
 static const char * const rk3399_isp_clks[] = {
@@ -524,7 +526,8 @@ static const struct rkisp1_info rk3399_isp_info = {
 	.isrs = rk3399_isp_isrs,
 	.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
 	.isp_ver = RKISP1_V10,
-	.features = RKISP1_FEATURE_MIPI_CSI2,
+	.features = RKISP1_FEATURE_MIPI_CSI2
+		  | RKISP1_FEATURE_SELF_PATH,
 };
 
 static const struct of_device_id rkisp1_of_match[] = {
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
index a8e377701302..dd77a31e6014 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
@@ -631,6 +631,7 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
 	struct rkisp1_device *rkisp1 = rsz->rkisp1;
 	struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1];
 	enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC;
+	bool has_self_path = rkisp1_has_feature(rkisp1, SELF_PATH);
 	struct v4l2_subdev_state *sd_state;
 
 	if (!enable) {
@@ -639,7 +640,7 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
 		return 0;
 	}
 
-	if (other->is_streaming)
+	if (has_self_path && other->is_streaming)
 		when = RKISP1_SHADOW_REGS_ASYNC;
 
 	sd_state = v4l2_subdev_lock_and_get_active_state(sd);
@@ -731,10 +732,11 @@ static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
 
 int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
 {
+	unsigned int dev_count = rkisp1_path_count(rkisp1);
 	unsigned int i;
 	int ret;
 
-	for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
+	for (i = 0; i < dev_count; i++) {
 		struct rkisp1_resizer *rsz = &rkisp1->resizer_devs[i];
 
 		rsz->rkisp1 = rkisp1;
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:50 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:50 +0900
Subject: [PATCH v12 04/12] media: rkisp1: Support devices lacking dual crop
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-5-paul.elder@ideasonboard.com>

Some versions of the ISP supported by the rkisp1 driver, such as the ISP
in the i.MX8MP, lack the dual crop registers and don't support cropping
at the resizer input. They instead rely on cropping in the Image
Stabilization module, at the output of the ISP, to modify the resizer
input size and implement digital zoom.

Add a dual crop feature flag to distinguish the versions of the ISP that
support dual crop from those that don't, and make sure that the sink
crop is set to the sink format when dual crop is not supported.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
Changes in v12:
- Remove mention of moving resizer input crop to image stabilizer from
  commit message
- Make sure the sink crop is set to the sink format when dual crop is
  not supported
---
 .../media/platform/rockchip/rkisp1/rkisp1-common.h    |  2 ++
 drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c   |  6 ++++--
 .../media/platform/rockchip/rkisp1/rkisp1-resizer.c   | 11 +++++++----
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index f7c251f79aa9..219d4a2547aa 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -112,6 +112,7 @@ enum rkisp1_isp_pad {
  * @RKISP1_FEATURE_MIPI_CSI2: The ISP has an internal MIPI CSI-2 receiver
  * @RKISP1_FEATURE_MAIN_STRIDE: The ISP supports configurable stride on the main path
  * @RKISP1_FEATURE_SELF_PATH: The ISP has a self path
+ * @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the resizer input
  *
  * The ISP features are stored in a bitmask in &rkisp1_info.features and allow
  * the driver to implement support for features present in some ISP versions
@@ -121,6 +122,7 @@ enum rkisp1_feature {
 	RKISP1_FEATURE_MIPI_CSI2 = BIT(0),
 	RKISP1_FEATURE_MAIN_STRIDE = BIT(1),
 	RKISP1_FEATURE_SELF_PATH = BIT(2),
+	RKISP1_FEATURE_DUAL_CROP = BIT(3),
 };
 
 #define rkisp1_has_feature(rkisp1, feature) \
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index f48a21985b18..2e40c376cab5 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -507,7 +507,8 @@ static const struct rkisp1_info px30_isp_info = {
 	.isr_size = ARRAY_SIZE(px30_isp_isrs),
 	.isp_ver = RKISP1_V12,
 	.features = RKISP1_FEATURE_MIPI_CSI2
-		  | RKISP1_FEATURE_SELF_PATH,
+		  | RKISP1_FEATURE_SELF_PATH
+		  | RKISP1_FEATURE_DUAL_CROP,
 };
 
 static const char * const rk3399_isp_clks[] = {
@@ -527,7 +528,8 @@ static const struct rkisp1_info rk3399_isp_info = {
 	.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
 	.isp_ver = RKISP1_V10,
 	.features = RKISP1_FEATURE_MIPI_CSI2
-		  | RKISP1_FEATURE_SELF_PATH,
+		  | RKISP1_FEATURE_SELF_PATH
+		  | RKISP1_FEATURE_DUAL_CROP,
 };
 
 static const struct of_device_id rkisp1_of_match[] = {
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
index dd77a31e6014..755d319b568e 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
@@ -447,8 +447,9 @@ static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
 	/* Not crop for MP bayer raw data */
 	mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
 
-	if (rsz->id == RKISP1_MAINPATH &&
-	    mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+	if ((rsz->id == RKISP1_MAINPATH &&
+	     mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) ||
+	    !rkisp1_has_feature(rsz->rkisp1, DUAL_CROP)) {
 		sink_crop->left = 0;
 		sink_crop->top = 0;
 		sink_crop->width = sink_fmt->width;
@@ -635,7 +636,8 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
 	struct v4l2_subdev_state *sd_state;
 
 	if (!enable) {
-		rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
+		if (rkisp1_has_feature(rkisp1, DUAL_CROP))
+			rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
 		rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
 		return 0;
 	}
@@ -646,7 +648,8 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
 	sd_state = v4l2_subdev_lock_and_get_active_state(sd);
 
 	rkisp1_rsz_config(rsz, sd_state, when);
-	rkisp1_dcrop_config(rsz, sd_state);
+	if (rkisp1_has_feature(rkisp1, DUAL_CROP))
+		rkisp1_dcrop_config(rsz, sd_state);
 
 	v4l2_subdev_unlock_state(sd_state);
 
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:51 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:51 +0900
Subject: [PATCH v12 05/12] dt-bindings: media: rkisp1: Add i.MX8MP ISP to compatible
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-6-paul.elder@ideasonboard.com>

The i.MX8MP ISP is compatbile with the rkisp1 driver. Add it to the list
of compatible strings. While at it, expand on the description of the
clocks to make it clear which clock in the i.MX8MP ISP they map to,
based on the names from the datasheet.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Adam Ford <aford173 at gmail.com>
---
Changes since v1:

- Add fsl,blk-ctrl property
- Make iommus, phys and phy-names conditional on compatible
---
 .../bindings/media/rockchip-isp1.yaml         | 37 ++++++++++++++++---
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml
index afcaa427d48b..6be00aca4181 100644
--- a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml
@@ -16,6 +16,7 @@ description: |
 properties:
   compatible:
     enum:
+      - fsl,imx8mp-isp
       - rockchip,px30-cif-isp
       - rockchip,rk3399-cif-isp
 
@@ -36,9 +37,9 @@ properties:
     minItems: 3
     items:
       # isp0 and isp1
-      - description: ISP clock
-      - description: ISP AXI clock
-      - description: ISP AHB clock
+      - description: ISP clock (for imx8mp, clk)
+      - description: ISP AXI clock (for imx8mp, m_hclk)
+      - description: ISP AHB clock (for imx8mp, hclk)
       # only for isp1
       - description: ISP Pixel clock
 
@@ -52,6 +53,13 @@ properties:
       # only for isp1
       - const: pclk
 
+  fsl,blk-ctrl:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+    description:
+      A phandle to the media block control for the ISP, followed by a cell
+      containing the index of the gasket.
+
   iommus:
     maxItems: 1
 
@@ -113,9 +121,6 @@ required:
   - interrupts
   - clocks
   - clock-names
-  - iommus
-  - phys
-  - phy-names
   - power-domains
   - ports
 
@@ -143,6 +148,26 @@ allOf:
       required:
         - interrupt-names
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx8mp-isp
+    then:
+      properties:
+        iommus: false
+        phys: false
+        phy-names: false
+      required:
+        - fsl,blk-ctrl
+    else:
+      properties:
+        fsl,blk-ctrl: false
+      required:
+        - iommus
+        - phys
+        - phy-names
+
 additionalProperties: false
 
 examples:
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:53 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:53 +0900
Subject: [PATCH v12 07/12] media: rkisp1: Configure gasket on i.MX8MP
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-8-paul.elder@ideasonboard.com>

From: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

The i.MX8MP has a gasket between the CSI-2 receiver and the ISP.
Configure and enable it when starting the ISP, and disable it when
stopping.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 .../platform/rockchip/rkisp1/rkisp1-common.h  |   5 +
 .../platform/rockchip/rkisp1/rkisp1-dev.c     |  16 +++
 .../platform/rockchip/rkisp1/rkisp1-isp.c     | 131 +++++++++++++++++-
 3 files changed, 149 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index 219d4a2547aa..69940014d597 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -24,6 +24,7 @@
 #include "rkisp1-regs.h"
 
 struct dentry;
+struct regmap;
 
 /*
  * flags on the 'direction' field in struct rkisp1_mbus_info' that indicate
@@ -444,6 +445,8 @@ struct rkisp1_debug {
  * @dev:	   a pointer to the struct device
  * @clk_size:	   number of clocks
  * @clks:	   array of clocks
+ * @gasket:	   the gasket - i.MX8MP only
+ * @gasket_id:	   the gasket ID (0 or 1) - i.MX8MP only
  * @v4l2_dev:	   v4l2_device variable
  * @media_dev:	   media_device variable
  * @notifier:	   a notifier to register on the v4l2-async API to be notified on the sensor
@@ -466,6 +469,8 @@ struct rkisp1_device {
 	struct device *dev;
 	unsigned int clk_size;
 	struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK];
+	struct regmap *gasket;
+	unsigned int gasket_id;
 	struct v4l2_device v4l2_dev;
 	struct media_device media_dev;
 	struct v4l2_async_notifier notifier;
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index 2e40c376cab5..d0a3a13d9dd7 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -10,6 +10,7 @@
 
 #include <linux/clk.h>
 #include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_graph.h>
@@ -601,6 +602,21 @@ static int rkisp1_probe(struct platform_device *pdev)
 		return ret;
 	rkisp1->clk_size = info->clk_size;
 
+	if (info->isp_ver == RKISP1_V_IMX8MP) {
+		unsigned int id;
+
+		rkisp1->gasket = syscon_regmap_lookup_by_phandle_args(dev->of_node,
+								      "fsl,blk-ctrl",
+								      1, &id);
+		if (IS_ERR(rkisp1->gasket)) {
+			ret = PTR_ERR(rkisp1->gasket);
+			dev_err(dev, "failed to get gasket: %d\n", ret);
+			return ret;
+		}
+
+		rkisp1->gasket_id = id;
+	}
+
 	pm_runtime_enable(&pdev->dev);
 
 	ret = pm_runtime_resume_and_get(&pdev->dev);
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
index 78a1f7a1499b..e45a213baf49 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
@@ -10,6 +10,7 @@
 
 #include <linux/iopoll.h>
 #include <linux/pm_runtime.h>
+#include <linux/regmap.h>
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
 
@@ -53,6 +54,115 @@
  * +---------------------------------------------------------+
  */
 
+/* -----------------------------------------------------------------------------
+ * Media block control (i.MX8MP only)
+ */
+
+#define ISP_DEWARP_CONTROL				0x0138
+
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_HS_POLARITY	BIT(22)
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_RISING	(0 << 20)
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_NEGATIVE	(1 << 20)
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_POSITIVE	(2 << 20)
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_FALLING	(3 << 20)
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_MASK	GENMASK(21, 20)
+#define ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE	BIT(19)
+#define ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE(dt)	((dt) << 13)
+#define ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK	GENMASK(18, 13)
+
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY	BIT(12)
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_RISING	(0 << 10)
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_NEGATIVE	(1 << 10)
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_POSITIVE	(2 << 10)
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_FALLING	(3 << 10)
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_MASK	GENMASK(11, 10)
+#define ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE	BIT(9)
+#define ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE(dt)	((dt) << 3)
+#define ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK	GENMASK(8, 3)
+
+#define ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE		BIT(1)
+#define ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE		BIT(0)
+
+static int rkisp1_gasket_enable(struct rkisp1_device *rkisp1,
+				struct media_pad *source)
+{
+	struct v4l2_subdev *source_sd;
+	struct v4l2_mbus_frame_desc fd;
+	unsigned int dt;
+	u32 mask;
+	u32 val;
+	int ret;
+
+	/*
+	 * Configure and enable the gasket with the CSI-2 data type. Set the
+	 * vsync polarity as active high, as that is what the ISP is configured
+	 * to expect in ISP_ACQ_PROP. Enable left justification, as the i.MX8MP
+	 * ISP has a 16-bit wide input and expects data to be left-aligned.
+	 */
+
+	source_sd = media_entity_to_v4l2_subdev(source->entity);
+	ret = v4l2_subdev_call(source_sd, pad, get_frame_desc,
+			       source->index, &fd);
+	if (ret) {
+		dev_err(rkisp1->dev,
+			"failed to get frame descriptor from '%s':%u: %d\n",
+			source_sd->name, 0, ret);
+		return ret;
+	}
+
+	if (fd.num_entries != 1) {
+		dev_err(rkisp1->dev, "invalid frame descriptor for '%s':%u\n",
+			source_sd->name, 0);
+		return -EINVAL;
+	}
+
+	dt = fd.entry[0].bus.csi2.dt;
+
+	if (rkisp1->gasket_id == 0) {
+		mask = ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY
+		     | ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_MASK
+		     | ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
+		     | ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK
+		     | ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
+		val = ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_POSITIVE
+		    | ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
+		    | ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE(dt);
+	} else {
+		mask = ISP_DEWARP_CONTROL_MIPI_CSI2_HS_POLARITY
+		     | ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_MASK
+		     | ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
+		     | ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK
+		     | ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
+		val = ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_POSITIVE
+		    | ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
+		    | ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE(dt);
+	}
+
+	regmap_update_bits(rkisp1->gasket, ISP_DEWARP_CONTROL, mask, val);
+
+	return 0;
+}
+
+static void rkisp1_gasket_disable(struct rkisp1_device *rkisp1)
+{
+	u32 mask;
+	u32 val;
+
+	if (rkisp1->gasket_id == 1) {
+		mask = ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
+		     | ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK
+		     | ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
+		val = ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
+	} else {
+		mask = ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
+		     | ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK
+		     | ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
+		val = ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
+	}
+
+	regmap_update_bits(rkisp1->gasket, ISP_DEWARP_CONTROL, mask, val);
+}
+
 /* ----------------------------------------------------------------------------
  * Camera Interface registers configurations
  */
@@ -291,6 +401,9 @@ static void rkisp1_isp_stop(struct rkisp1_isp *isp)
 		     RKISP1_CIF_VI_IRCL_MIPI_SW_RST |
 		     RKISP1_CIF_VI_IRCL_ISP_SW_RST);
 	rkisp1_write(rkisp1, RKISP1_CIF_VI_IRCL, 0x0);
+
+	if (rkisp1->info->isp_ver == RKISP1_V_IMX8MP)
+		rkisp1_gasket_disable(rkisp1);
 }
 
 static void rkisp1_config_clk(struct rkisp1_isp *isp)
@@ -315,16 +428,24 @@ static void rkisp1_config_clk(struct rkisp1_isp *isp)
 	}
 }
 
-static void rkisp1_isp_start(struct rkisp1_isp *isp,
-			     struct v4l2_subdev_state *sd_state)
+static int rkisp1_isp_start(struct rkisp1_isp *isp,
+			    struct v4l2_subdev_state *sd_state,
+			    struct media_pad *source)
 {
 	struct rkisp1_device *rkisp1 = isp->rkisp1;
 	const struct v4l2_mbus_framefmt *src_fmt;
 	const struct rkisp1_mbus_info *src_info;
 	u32 val;
+	int ret;
 
 	rkisp1_config_clk(isp);
 
+	if (rkisp1->info->isp_ver == RKISP1_V_IMX8MP) {
+		ret = rkisp1_gasket_enable(rkisp1, source);
+		if (ret)
+			return ret;
+	}
+
 	/* Activate ISP */
 	val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
 	val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD |
@@ -338,6 +459,8 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp,
 
 	if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER)
 		rkisp1_params_post_configure(&rkisp1->params);
+
+	return 0;
 }
 
 /* ----------------------------------------------------------------------------
@@ -848,7 +971,9 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
 	if (ret)
 		goto out_unlock;
 
-	rkisp1_isp_start(isp, sd_state);
+	ret = rkisp1_isp_start(isp, sd_state, source_pad);
+	if (ret)
+		goto out_unlock;
 
 	ret = v4l2_subdev_call(rkisp1->source, video, s_stream, true);
 	if (ret) {
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:54 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:54 +0900
Subject: [PATCH v12 08/12] media: rkisp1: Support i.MX8MP's 34-bit DMA
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-9-paul.elder@ideasonboard.com>

On the ISP that is integrated in the i.MX8MP, DMA addresses have been
extended to 34 bits, with the 32 MSBs stored in the DMA address
registers and the 2 LSBs set to 0.

To support this:
- Shift the addresses to the right by 2 when writing to registers
- Set the dma mask to 34 bits
- Use dma_addr_t instead of u32 when storing the addresses

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
Changes since v5:

- Improve the commit message

Changes since v4:

- Squash in fix from Tomi:
  - https://gitlab.com/ideasonboard/nxp/linux/-/commit/d6477fe673b1c0d05d12ae21d8db9a03b07e7fea

Changes since v2:

- Document the RKISP1_FEATURE_DMA_34BIT bit
- Use the rkisp1_has_feature() macro
---
 .../platform/rockchip/rkisp1/rkisp1-capture.c | 20 ++++++++++---------
 .../platform/rockchip/rkisp1/rkisp1-common.h  |  4 +++-
 .../platform/rockchip/rkisp1/rkisp1-dev.c     |  8 ++++++++
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
index ca95f62822fa..1ee7639c42b7 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
@@ -648,11 +648,13 @@ static void rkisp1_dummy_buf_destroy(struct rkisp1_capture *cap)
 
 static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
 {
+	u8 shift = rkisp1_has_feature(cap->rkisp1, DMA_34BIT) ? 2 : 0;
+
 	cap->buf.curr = cap->buf.next;
 	cap->buf.next = NULL;
 
 	if (!list_empty(&cap->buf.queue)) {
-		u32 *buff_addr;
+		dma_addr_t *buff_addr;
 
 		cap->buf.next = list_first_entry(&cap->buf.queue, struct rkisp1_buffer, queue);
 		list_del(&cap->buf.next->queue);
@@ -660,7 +662,7 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
 		buff_addr = cap->buf.next->buff_addr;
 
 		rkisp1_write(cap->rkisp1, cap->config->mi.y_base_ad_init,
-			     buff_addr[RKISP1_PLANE_Y]);
+			     buff_addr[RKISP1_PLANE_Y] >> shift);
 		/*
 		 * In order to support grey format we capture
 		 * YUV422 planar format from the camera and
@@ -669,17 +671,17 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
 		if (cap->pix.cfg->fourcc == V4L2_PIX_FMT_GREY) {
 			rkisp1_write(cap->rkisp1,
 				     cap->config->mi.cb_base_ad_init,
-				     cap->buf.dummy.dma_addr);
+				     cap->buf.dummy.dma_addr >> shift);
 			rkisp1_write(cap->rkisp1,
 				     cap->config->mi.cr_base_ad_init,
-				     cap->buf.dummy.dma_addr);
+				     cap->buf.dummy.dma_addr >> shift);
 		} else {
 			rkisp1_write(cap->rkisp1,
 				     cap->config->mi.cb_base_ad_init,
-				     buff_addr[RKISP1_PLANE_CB]);
+				     buff_addr[RKISP1_PLANE_CB] >> shift);
 			rkisp1_write(cap->rkisp1,
 				     cap->config->mi.cr_base_ad_init,
-				     buff_addr[RKISP1_PLANE_CR]);
+				     buff_addr[RKISP1_PLANE_CR] >> shift);
 		}
 	} else {
 		/*
@@ -687,11 +689,11 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
 		 * throw data if there is no available buffer.
 		 */
 		rkisp1_write(cap->rkisp1, cap->config->mi.y_base_ad_init,
-			     cap->buf.dummy.dma_addr);
+			     cap->buf.dummy.dma_addr >> shift);
 		rkisp1_write(cap->rkisp1, cap->config->mi.cb_base_ad_init,
-			     cap->buf.dummy.dma_addr);
+			     cap->buf.dummy.dma_addr >> shift);
 		rkisp1_write(cap->rkisp1, cap->config->mi.cr_base_ad_init,
-			     cap->buf.dummy.dma_addr);
+			     cap->buf.dummy.dma_addr >> shift);
 	}
 
 	/* Set plane offsets */
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index 69940014d597..26573f6ae575 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -114,6 +114,7 @@ enum rkisp1_isp_pad {
  * @RKISP1_FEATURE_MAIN_STRIDE: The ISP supports configurable stride on the main path
  * @RKISP1_FEATURE_SELF_PATH: The ISP has a self path
  * @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the resizer input
+ * @RKISP1_FEATURE_DMA_34BIT: The ISP uses 34-bit DMA addresses
  *
  * The ISP features are stored in a bitmask in &rkisp1_info.features and allow
  * the driver to implement support for features present in some ISP versions
@@ -124,6 +125,7 @@ enum rkisp1_feature {
 	RKISP1_FEATURE_MAIN_STRIDE = BIT(1),
 	RKISP1_FEATURE_SELF_PATH = BIT(2),
 	RKISP1_FEATURE_DUAL_CROP = BIT(3),
+	RKISP1_FEATURE_DMA_34BIT = BIT(4),
 };
 
 #define rkisp1_has_feature(rkisp1, feature) \
@@ -239,7 +241,7 @@ struct rkisp1_vdev_node {
 struct rkisp1_buffer {
 	struct vb2_v4l2_buffer vb;
 	struct list_head queue;
-	u32 buff_addr[VIDEO_MAX_PLANES];
+	dma_addr_t buff_addr[VIDEO_MAX_PLANES];
 };
 
 /*
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index d0a3a13d9dd7..54a62487a4e8 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -552,6 +552,7 @@ static int rkisp1_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct rkisp1_device *rkisp1;
 	struct v4l2_device *v4l2_dev;
+	unsigned long long dma_mask;
 	unsigned int i;
 	int ret, irq;
 	u32 cif_id;
@@ -566,6 +567,13 @@ static int rkisp1_probe(struct platform_device *pdev)
 	dev_set_drvdata(dev, rkisp1);
 	rkisp1->dev = dev;
 
+	dma_mask = rkisp1_has_feature(rkisp1, DMA_34BIT) ? DMA_BIT_MASK(34) :
+							   DMA_BIT_MASK(32);
+
+	ret = dma_set_mask_and_coherent(dev, dma_mask);
+	if (ret)
+		return ret;
+
 	mutex_init(&rkisp1->stream_lock);
 
 	rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:56 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:56 +0900
Subject: [PATCH v12 10/12] media: rkisp1: Add UYVY as an output format
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-11-paul.elder@ideasonboard.com>

Add support for UYVY as an output format. The uv_swap bit in the
MI_XTD_FORMAT_CTRL register that is used for the NV formats does not
work for packed YUV formats. Thus, UYVY support is implemented via
byte-swapping. This method clearly does not work for implementing
support for YVYU and VYUY.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Adam Ford <aford173 at gmail.com>

---
Changes in v12:
- replace MI_OUTPUT_FORMAT feature flag with MAIN_STRIDE
---
 .../platform/rockchip/rkisp1/rkisp1-capture.c | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
index 99375e08b503..64b1d1104e20 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
@@ -97,6 +97,12 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+	}, {
+		.fourcc = V4L2_PIX_FMT_UYVY,
+		.uv_swap = 0,
+		.yc_swap = 1,
+		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
+		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_YUV422P,
 		.uv_swap = 0,
@@ -231,6 +237,13 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
 		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+	}, {
+		.fourcc = V4L2_PIX_FMT_UYVY,
+		.uv_swap = 0,
+		.yc_swap = 1,
+		.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
+		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_YUV422P,
 		.uv_swap = 0,
@@ -464,6 +477,20 @@ static void rkisp1_mp_config(struct rkisp1_capture *cap)
 		rkisp1_write(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL, reg);
 	}
 
+	/*
+	 * U/V swapping with the MI_XTD_FORMAT_CTRL register only works for
+	 * NV12/NV21 and NV16/NV61, so instead use byte swap to support UYVY.
+	 * YVYU and VYUY cannot be supported with this method.
+	 */
+	if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
+		reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
+		if (cap->pix.cfg->yc_swap)
+			reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
+		else
+			reg &= ~RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
+		rkisp1_write(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT, reg);
+	}
+
 	rkisp1_mi_config_ctrl(cap);
 
 	reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
@@ -507,6 +534,20 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap)
 		rkisp1_write(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL, reg);
 	}
 
+	/*
+	 * U/V swapping with the MI_XTD_FORMAT_CTRL register only works for
+	 * NV12/NV21 and NV16/NV61, so instead use byte swap to support UYVY.
+	 * YVYU and VYUY cannot be supported with this method.
+	 */
+	if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
+		reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
+		if (cap->pix.cfg->yc_swap)
+			reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_BYTES;
+		else
+			reg &= ~RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_BYTES;
+		rkisp1_write(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT, reg);
+	}
+
 	rkisp1_mi_config_ctrl(cap);
 
 	mi_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:57 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:57 +0900
Subject: [PATCH v12 11/12] media: rkisp1: Fix endianness on raw streams on i.MX8MP
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-12-paul.elder@ideasonboard.com>

The i.MX8MP has extra register fields in the memory interface control
register for setting the output format, which work with the output
alignment format register for byte-swapping and LSB/MSB alignment.

With processed and 8-bit raw streams, it doesn't cause any problems to
not set these, but with raw streams of higher bit depth the endianness
is swapped and the data is not aligned properly.

Add support for settings these registers and plumb them in to fix this.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
---
Changes in v12:
- replace MP_OUTPUT_FORMAT feature flag with MAIN_STRIDE

New in v6
---
 .../platform/rockchip/rkisp1/rkisp1-capture.c | 93 ++++++++++++++-----
 .../platform/rockchip/rkisp1/rkisp1-regs.h    |  8 ++
 2 files changed, 78 insertions(+), 23 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
index 64b1d1104e20..28a99b31581b 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
@@ -48,16 +48,20 @@ enum rkisp1_plane {
  * @fmt_type: helper filed for pixel format
  * @uv_swap: if cb cr swapped, for yuv
  * @yc_swap: if y and cb/cr swapped, for yuv
+ * @byte_swap: if byte pairs are swapped, for raw
  * @write_format: defines how YCbCr self picture data is written to memory
- * @output_format: defines sp output format
+ * @output_format_mp: defines mp output format
+ * @output_format_sp: defines sp output format
  * @mbus: the mbus code on the src resizer pad that matches the pixel format
  */
 struct rkisp1_capture_fmt_cfg {
 	u32 fourcc;
 	u32 uv_swap : 1;
 	u32 yc_swap : 1;
+	u32 byte_swap : 1;
 	u32 write_format;
-	u32 output_format;
+	u32 output_format_mp;
+	u32 output_format_sp;
 	u32 mbus;
 };
 
@@ -96,42 +100,50 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
 		.fourcc = V4L2_PIX_FMT_YUYV,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_UYVY,
 		.uv_swap = 0,
 		.yc_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_YUV422P,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV16,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV61,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV16M,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV61M,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_YVU422M,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	},
 	/* yuv400 */
@@ -139,6 +151,7 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
 		.fourcc = V4L2_PIX_FMT_GREY,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	},
 	/* yuv420 */
@@ -146,81 +159,107 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
 		.fourcc = V4L2_PIX_FMT_NV21,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV12,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV21M,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV12M,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_YUV420,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_YVU420,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	},
 	/* raw */
 	{
 		.fourcc = V4L2_PIX_FMT_SRGGB8,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
 		.mbus = MEDIA_BUS_FMT_SRGGB8_1X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SGRBG8,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
 		.mbus = MEDIA_BUS_FMT_SGRBG8_1X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SGBRG8,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
 		.mbus = MEDIA_BUS_FMT_SGBRG8_1X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SBGGR8,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
 		.mbus = MEDIA_BUS_FMT_SBGGR8_1X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SRGGB10,
+		.byte_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
 		.mbus = MEDIA_BUS_FMT_SRGGB10_1X10,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SGRBG10,
+		.byte_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
 		.mbus = MEDIA_BUS_FMT_SGRBG10_1X10,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SGBRG10,
+		.byte_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
 		.mbus = MEDIA_BUS_FMT_SGBRG10_1X10,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SBGGR10,
+		.byte_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
 		.mbus = MEDIA_BUS_FMT_SBGGR10_1X10,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SRGGB12,
+		.byte_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
 		.mbus = MEDIA_BUS_FMT_SRGGB12_1X12,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SGRBG12,
+		.byte_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
 		.mbus = MEDIA_BUS_FMT_SGRBG12_1X12,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SGBRG12,
+		.byte_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
 		.mbus = MEDIA_BUS_FMT_SGBRG12_1X12,
 	}, {
 		.fourcc = V4L2_PIX_FMT_SBGGR12,
+		.byte_swap = 1,
 		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
 		.mbus = MEDIA_BUS_FMT_SBGGR12_1X12,
 	},
 };
@@ -235,50 +274,50 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
 		.fourcc = V4L2_PIX_FMT_YUYV,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_UYVY,
 		.uv_swap = 0,
 		.yc_swap = 1,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_YUV422P,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV16,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV61,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV16M,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV61M,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_YVU422M,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	},
 	/* yuv400 */
@@ -286,19 +325,19 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
 		.fourcc = V4L2_PIX_FMT_GREY,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	},
 	/* rgb */
 	{
 		.fourcc = V4L2_PIX_FMT_XBGR32,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_RGB565,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
 		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
 	},
 	/* yuv420 */
@@ -306,37 +345,37 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
 		.fourcc = V4L2_PIX_FMT_NV21,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV12,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV21M,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_NV12M,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_YUV420,
 		.uv_swap = 0,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	}, {
 		.fourcc = V4L2_PIX_FMT_YVU420,
 		.uv_swap = 1,
 		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
 		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
 	},
 };
@@ -484,10 +523,12 @@ static void rkisp1_mp_config(struct rkisp1_capture *cap)
 	 */
 	if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
 		reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
-		if (cap->pix.cfg->yc_swap)
+		if (cap->pix.cfg->yc_swap || cap->pix.cfg->byte_swap)
 			reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
 		else
 			reg &= ~RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
+
+		reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_LSB_ALIGNMENT;
 		rkisp1_write(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT, reg);
 	}
 
@@ -554,7 +595,7 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap)
 	mi_ctrl &= ~RKISP1_MI_CTRL_SP_FMT_MASK;
 	mi_ctrl |= cap->pix.cfg->write_format |
 		   RKISP1_MI_CTRL_SP_INPUT_YUV422 |
-		   cap->pix.cfg->output_format |
+		   cap->pix.cfg->output_format_sp |
 		   RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE;
 	rkisp1_write(rkisp1, RKISP1_CIF_MI_CTRL, mi_ctrl);
 }
@@ -946,6 +987,7 @@ static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
 	struct rkisp1_device *rkisp1 = cap->rkisp1;
 	struct rkisp1_capture *other = &rkisp1->capture_devs[cap->id ^ 1];
 	bool has_self_path = rkisp1_has_feature(rkisp1, SELF_PATH);
+	u32 reg;
 
 	cap->ops->set_data_path(cap);
 	cap->ops->config(cap);
@@ -965,8 +1007,13 @@ static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
 	 */
 	if (!has_self_path || !other->is_streaming) {
 		/* force cfg update */
-		rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT,
-			     RKISP1_CIF_MI_INIT_SOFT_UPD);
+		reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_INIT);
+
+		if (rkisp1_has_feature(rkisp1, MAIN_STRIDE))
+			reg |= cap->pix.cfg->output_format_mp;
+
+		reg |= RKISP1_CIF_MI_INIT_SOFT_UPD;
+		rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT, reg);
 		rkisp1_set_next_buf(cap);
 	}
 	spin_unlock_irq(&cap->buf.lock);
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
index 3b19c8411360..762243016f05 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
@@ -144,6 +144,14 @@
 /* MI_INIT */
 #define RKISP1_CIF_MI_INIT_SKIP				BIT(2)
 #define RKISP1_CIF_MI_INIT_SOFT_UPD			BIT(4)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400		(0 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420		(1 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422		(2 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV444		(3 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12		(4 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8		(5 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_JPEG		(6 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10		(7 << 5)
 
 /* MI_CTRL_SHD */
 #define RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED		BIT(0)
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:55 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:55 +0900
Subject: [PATCH v12 09/12] media: rkisp1: Add YC swap capability
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-10-paul.elder@ideasonboard.com>

The ISP version in the i.MX8MP has an MI_OUTPUT_ALIGN_FORMAT register
that the rk3399 does not have. This register allows swapping bytes,
which can be used to implement UYVY from YUYV.

Add a flag to the format info in the list of formats supported by the
capture v4l2 devices, and update enum_fmt and s_fmt to take it into
account.

To signify the presence of this feature, reuse the MAIN_STRIDE feature
flag, as it is very likely that any ISP version that supports one of
these two features will also support the other.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Adam Ford <aford173 at gmail.com>

---
Changes in v12:
- replace MI_OUTPUT_ALIGN feature flag with MAIN_STRIDE
---
 .../platform/rockchip/rkisp1/rkisp1-capture.c | 26 ++++++++++++++-----
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
index 1ee7639c42b7..99375e08b503 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
@@ -47,13 +47,15 @@ enum rkisp1_plane {
  * @fourcc: pixel format
  * @fmt_type: helper filed for pixel format
  * @uv_swap: if cb cr swapped, for yuv
+ * @yc_swap: if y and cb/cr swapped, for yuv
  * @write_format: defines how YCbCr self picture data is written to memory
  * @output_format: defines sp output format
  * @mbus: the mbus code on the src resizer pad that matches the pixel format
  */
 struct rkisp1_capture_fmt_cfg {
 	u32 fourcc;
-	u8 uv_swap;
+	u32 uv_swap : 1;
+	u32 yc_swap : 1;
 	u32 write_format;
 	u32 output_format;
 	u32 mbus;
@@ -1162,10 +1164,14 @@ rkisp1_fill_pixfmt(const struct rkisp1_capture *cap,
 static const struct rkisp1_capture_fmt_cfg *
 rkisp1_find_fmt_cfg(const struct rkisp1_capture *cap, const u32 pixelfmt)
 {
+	bool yc_swap_support = rkisp1_has_feature(cap->rkisp1, MAIN_STRIDE);
 	unsigned int i;
 
 	for (i = 0; i < cap->config->fmt_size; i++) {
-		if (cap->config->fmts[i].fourcc == pixelfmt)
+		const struct rkisp1_capture_fmt_cfg *fmt = &cap->config->fmts[i];
+
+		if (fmt->fourcc == pixelfmt &&
+		    (!fmt->yc_swap || yc_swap_support))
 			return &cap->config->fmts[i];
 	}
 	return NULL;
@@ -1234,23 +1240,29 @@ static int rkisp1_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
 {
 	struct rkisp1_capture *cap = video_drvdata(file);
 	const struct rkisp1_capture_fmt_cfg *fmt = NULL;
+	bool yc_swap_support = rkisp1_has_feature(cap->rkisp1, MAIN_STRIDE);
 	unsigned int i, n = 0;
 
-	if (!f->mbus_code) {
-		if (f->index >= cap->config->fmt_size)
-			return -EINVAL;
+	if (f->index >= cap->config->fmt_size)
+		return -EINVAL;
 
+	if (!f->mbus_code && yc_swap_support) {
 		fmt = &cap->config->fmts[f->index];
 		f->pixelformat = fmt->fourcc;
 		return 0;
 	}
 
 	for (i = 0; i < cap->config->fmt_size; i++) {
-		if (cap->config->fmts[i].mbus != f->mbus_code)
+		fmt = &cap->config->fmts[i];
+
+		if (f->mbus_code && fmt->mbus != f->mbus_code)
+			continue;
+
+		if (!yc_swap_support && fmt->yc_swap)
 			continue;
 
 		if (n++ == f->index) {
-			f->pixelformat = cap->config->fmts[i].fourcc;
+			f->pixelformat = fmt->fourcc;
 			return 0;
 		}
 	}
-- 
2.39.2



From paul.elder at ideasonboard.com  Fri Feb 16 01:54:58 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Fri, 16 Feb 2024 18:54:58 +0900
Subject: [PATCH v12 12/12] media: rkisp1: Add match data for i.MX8MP ISP
In-Reply-To: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
Message-ID: <20240216095458.2919694-13-paul.elder@ideasonboard.com>

Add match data to the rkisp1 driver to match the i.MX8MP ISP.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
Changes in v12:
- move out adding the version enum
---
 .../platform/rockchip/rkisp1/rkisp1-dev.c     | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index 54a62487a4e8..a6b47f0af467 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -533,6 +533,26 @@ static const struct rkisp1_info rk3399_isp_info = {
 		  | RKISP1_FEATURE_DUAL_CROP,
 };
 
+static const char * const imx8mp_isp_clks[] = {
+	"isp",
+	"hclk",
+	"aclk",
+};
+
+static const struct rkisp1_isr_data imx8mp_isp_isrs[] = {
+	{ NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) },
+};
+
+static const struct rkisp1_info imx8mp_isp_info = {
+	.clks = imx8mp_isp_clks,
+	.clk_size = ARRAY_SIZE(imx8mp_isp_clks),
+	.isrs = imx8mp_isp_isrs,
+	.isr_size = ARRAY_SIZE(imx8mp_isp_isrs),
+	.isp_ver = RKISP1_V_IMX8MP,
+	.features = RKISP1_FEATURE_MAIN_STRIDE
+		  | RKISP1_FEATURE_DMA_34BIT,
+};
+
 static const struct of_device_id rkisp1_of_match[] = {
 	{
 		.compatible = "rockchip,px30-cif-isp",
@@ -542,6 +562,10 @@ static const struct of_device_id rkisp1_of_match[] = {
 		.compatible = "rockchip,rk3399-cif-isp",
 		.data = &rk3399_isp_info,
 	},
+	{
+		.compatible = "fsl,imx8mp-isp",
+		.data = &imx8mp_isp_info,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, rkisp1_of_match);
-- 
2.39.2



From krzysztof.kozlowski at linaro.org  Fri Feb 16 02:01:52 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 11:01:52 +0100
Subject: [PATCH 2/4] dt-bindings: media: Document bindings for HDMI RX
 Controller
In-Reply-To: <20240216094922.257674-3-shreeya.patel@collabora.com>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
 <20240216094922.257674-3-shreeya.patel@collabora.com>
Message-ID: <fd3b7ab7-3702-412f-947a-95396dbe1f4c@linaro.org>

On 16/02/2024 10:49, Shreeya Patel wrote:
> Document bindings for the Synopsys DesignWare HDMI RX Controller.
> 
> Reviewed-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
> Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>

A nit, subject: drop second/last, redundant "bindings for". The
"dt-bindings" prefix is already stating that these are bindings.
See also:
https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18

> ---
>  .../bindings/media/snps,dw-hdmi-rx.yaml       | 128 ++++++++++++++++++
>  1 file changed, 128 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
> new file mode 100644
> index 000000000000..a70d96b548ee
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
> @@ -0,0 +1,128 @@
> +# SPDX-License-Identifier: (GPL-3.0 OR BSD-2-Clause)

Use license checkpatch tells you.

> +# Device Tree bindings for Synopsys DesignWare HDMI RX Controller
> +
> +---
> +$id: http://devicetree.org/schemas/media/snps,dw-hdmi-rx.yaml#

Why this is a media, not display? Does RX means input? Lack of hardware
description does not help?


> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Synopsys DesignWare HDMI RX Controller
> +
> +maintainers:
> +  - Shreeya Patel <shreeya.patel at collabora.com>
> +

description:

> +properties:
> +  compatible:
> +    items:
> +      - const: rockchip,rk3588-hdmirx-ctrler
> +      - const: snps,dw-hdmi-rx
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 3
> +
> +  interrupt-names:
> +    items:
> +      - const: cec
> +      - const: hdmi
> +      - const: dma
> +
> +  clocks:
> +    maxItems: 7
> +
> +  clock-names:
> +    items:
> +      - const: aclk
> +      - const: audio
> +      - const: cr_para
> +      - const: pclk
> +      - const: ref
> +      - const: hclk_s_hdmirx
> +      - const: hclk_vo1
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 4
> +
> +  reset-names:
> +    items:
> +      - const: rst_a
> +      - const: rst_p
> +      - const: rst_ref
> +      - const: rst_biu

Drop rest_ prefix

> +
> +  pinctrl-names:
> +    const: default

Drop

> +
> +  memory-region:
> +    maxItems: 1
> +
> +  hdmirx-5v-detection-gpios:
> +    description: GPIO specifier for 5V detection.

Detection of what? Isn't this HPD?

> +    maxItems: 1
> +
> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the syscon node for the GRF register.

Instead describe what for. Basically 80% of your description is
redundant and only "GRF register" brings some information.


> +
> +  rockchip,vo1_grf:

No underscores.

> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the syscon node for the VO1 GRF register.

Same problem.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - interrupt-names
> +  - clocks
> +  - clock-names
> +  - power-domains
> +  - resets
> +  - pinctrl-0
> +  - pinctrl-names

Why? Drop.

> +  - hdmirx-5v-detection-gpios
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/power/rk3588-power.h>
> +    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
> +    hdmirx_ctrler: hdmirx-controller at fdee0000 {

What is hdmirx-controller? Isn't this just hdmi@?

Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation


> +      compatible = "rockchip,rk3588-hdmirx-ctrler", "snps,dw-hdmi-rx";
> +      reg = <0x0 0xfdee0000 0x0 0x6000>;
> +      interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>,
> +                   <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH 0>,
> +                   <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH 0>;



Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb 16 02:03:04 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 11:03:04 +0100
Subject: [PATCH 1/4] clk: rockchip: rst-rk3588: Add BIU reset
In-Reply-To: <20240216094922.257674-2-shreeya.patel@collabora.com>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
 <20240216094922.257674-2-shreeya.patel@collabora.com>
Message-ID: <237e690a-2f49-4046-b054-3a878eed6748@linaro.org>

On 16/02/2024 10:49, Shreeya Patel wrote:
> Export hdmirx_biu soft reset id which is required by the hdmirx controller.
> 
> Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
> ---
>  drivers/clk/rockchip/rst-rk3588.c               | 1 +
>  include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++

Please run scripts/checkpatch.pl and fix reported warnings. Some
warnings can be ignored, but the code here looks like it needs a fix.
Feel free to get in touch if the warning is not clear.

Please do internal review. The internal Collabora review would tell you:
YOU MUST run checkpatch. Then you see errors, so why do you send patch
with errors to the mailing list?

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Fri Feb 16 02:04:31 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 11:04:31 +0100
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <wkqqowh6ivn35d24n5ngdqno77wl7onrkdh43winac7bg7oekf@ykwhxujb4cjq>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
 <aamdttvdk3jmswvy3rw3debk3ouddkgjbs6xmixroe6kqakjw4@lnd5crcgoeyj>
 <2e96c824-47e8-48bd-9e03-8c7390b02d24@linaro.org>
 <wkqqowh6ivn35d24n5ngdqno77wl7onrkdh43winac7bg7oekf@ykwhxujb4cjq>
Message-ID: <83b7b8ca-0a10-4271-8ef9-20094e05f23e@linaro.org>

On 16/02/2024 09:43, Uwe Kleine-K?nig wrote:
>>> I applied the pwm patch now. If Lee wants to pick up this one via his
>>> tree that would be fine for me, too. If that's the case please tell me,
>>> then I'll drop it from my for-next branch again. Feel free to add
>>> my Acked-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de> for patch
>>> #2 then.
>>
>> At least next is happy.
> 
> The pwm binding is in next now (as
> 0fa319a1427f7c8d0af4c255316624f7e6f649a0) but dt_binding_check still
> tells me (among others):
> 
> 	Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml:
> 	Error in referenced schema matching $id: http://devicetree.org/schemas/display/atmel/atmel,hlcdc-display-controller.yaml
> 
> This is what you meant, right? This goes away as soon as the first patch

Yeah, apparently there was more than one dependency.

> (dt-bindings: display: convert Atmel's HLCDC to DT schema) is applied,
> too. So next isn't completely happy yet.

Sigh...

Best regards,
Krzysztof



From conor.dooley at microchip.com  Fri Feb 16 02:05:04 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Fri, 16 Feb 2024 10:05:04 +0000
Subject: [PATCH v1 0/6] SiFive cache controller PMU drivers
In-Reply-To: <20240216000837.1868917-1-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
Message-ID: <20240216-shopping-unnoticed-e73e72a0e849@wendy>

On Thu, Feb 15, 2024 at 04:08:12PM -0800, Samuel Holland wrote:

> All three of these cache controllers (with PMUs) have been integrated in
> SoCs by our customers. However, as none of those SoCs have been publicly
> announced yet, I cannot include SoC-specific compatible strings in this
> version of the devicetree bindings.

And I don't want to apply any of those dt-binding patches until then.
Stuff like "sifive,perfmon-counters" seems like a property that would
go away with a device-specific compatible, at least for the ccache.
-------------- 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/20240216/15d61e0c/attachment.sig>

From geert+renesas at glider.be  Fri Feb 16 00:54:25 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 16 Feb 2024 09:54:25 +0100
Subject: [PATCH v3] arm64: dts: mediatek: mt7986a: bpi-r3: Convert to sugar syntax
Message-ID: <1c9d161e5d519080321bb500e2898c5d100250e6.1708073597.git.geert+renesas@glider.be>

Overlay syntactic sugar for generating target-path fragments is
supported by the version of dtc supplied with the kernel since commit
50aafd60898a8b3e ("scripts/dtc: Update to upstream version
v1.4.6-21-g84e414b0b5bc").  Hence convert the Bananapi R3 overlay
devicetree source files to sugar syntax, improving readability.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
No changes in generated dtbo.

v3:
  - Fix SoC part number,

v2:
  - Rebase on top of commit e630c7b0b6a69f66 ("arm64: dts: mediatek:
    replace underscores in node names") in next-20240215 and later.
---
 .../mt7986a-bananapi-bpi-r3-emmc.dtso         | 28 +++---
 .../mt7986a-bananapi-bpi-r3-nand.dtso         | 74 ++++++++-------
 .../mediatek/mt7986a-bananapi-bpi-r3-nor.dtso | 90 +++++++++----------
 .../mediatek/mt7986a-bananapi-bpi-r3-sd.dtso  | 16 ++--
 4 files changed, 98 insertions(+), 110 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
index 779dc6782bb1986f..047a8388811eb9c0 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
@@ -9,21 +9,17 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-
-	fragment at 0 {
-		target-path = "/soc/mmc at 11230000";
-		__overlay__ {
-			bus-width = <8>;
-			max-frequency = <200000000>;
-			cap-mmc-highspeed;
-			mmc-hs200-1_8v;
-			mmc-hs400-1_8v;
-			hs400-ds-delay = <0x14014>;
-			non-removable;
-			no-sd;
-			no-sdio;
-			status = "okay";
-		};
-	};
 };
 
+&{/soc/mmc at 11230000} {
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	hs400-ds-delay = <0x14014>;
+	non-removable;
+	no-sd;
+	no-sdio;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
index 543c13385d6e3f82..12ec15e3188de082 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
@@ -9,46 +9,44 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
+};
+
+&{/soc/spi at 1100a000} {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	spi_nand: flash at 0 {
+		compatible = "spi-nand";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		spi-tx-buswidth = <4>;
+		spi-rx-buswidth = <4>;
 
-	fragment at 0 {
-		target-path = "/soc/spi at 1100a000";
-		__overlay__ {
+		partitions {
+			compatible = "fixed-partitions";
 			#address-cells = <1>;
-			#size-cells = <0>;
-			spi_nand: flash at 0 {
-				compatible = "spi-nand";
-				reg = <0>;
-				spi-max-frequency = <10000000>;
-				spi-tx-buswidth = <4>;
-				spi-rx-buswidth = <4>;
-
-				partitions {
-					compatible = "fixed-partitions";
-					#address-cells = <1>;
-					#size-cells = <1>;
-
-					partition at 0 {
-						label = "bl2";
-						reg = <0x0 0x100000>;
-						read-only;
-					};
-
-					partition at 100000 {
-						label = "reserved";
-						reg = <0x100000 0x280000>;
-					};
-
-					partition at 380000 {
-						label = "fip";
-						reg = <0x380000 0x200000>;
-						read-only;
-					};
-
-					partition at 580000 {
-						label = "ubi";
-						reg = <0x580000 0x7a80000>;
-					};
-				};
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "bl2";
+				reg = <0x0 0x100000>;
+				read-only;
+			};
+
+			partition at 100000 {
+				label = "reserved";
+				reg = <0x100000 0x280000>;
+			};
+
+			partition at 380000 {
+				label = "fip";
+				reg = <0x380000 0x200000>;
+				read-only;
+			};
+
+			partition at 580000 {
+				label = "ubi";
+				reg = <0x580000 0x7a80000>;
 			};
 		};
 	};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
index e48881be4ed60c98..6a0d529b54aca5bd 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
@@ -9,54 +9,52 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
+};
+
+&{/soc/spi at 1100a000} {
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-	fragment at 0 {
-		target-path = "/soc/spi at 1100a000";
-		__overlay__ {
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
 			#address-cells = <1>;
-			#size-cells = <0>;
-			flash at 0 {
-				compatible = "jedec,spi-nor";
-				reg = <0>;
-				spi-max-frequency = <10000000>;
-
-				partitions {
-					compatible = "fixed-partitions";
-					#address-cells = <1>;
-					#size-cells = <1>;
-
-					partition at 0 {
-						label = "bl2";
-						reg = <0x0 0x40000>;
-						read-only;
-					};
-
-					partition at 40000 {
-						label = "u-boot-env";
-						reg = <0x40000 0x40000>;
-					};
-
-					partition at 80000 {
-						label = "reserved2";
-						reg = <0x80000 0x80000>;
-					};
-
-					partition at 100000 {
-						label = "fip";
-						reg = <0x100000 0x80000>;
-						read-only;
-					};
-
-					partition at 180000 {
-						label = "recovery";
-						reg = <0x180000 0xa80000>;
-					};
-
-					partition at c00000 {
-						label = "fit";
-						reg = <0xc00000 0x1400000>;
-					};
-				};
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "bl2";
+				reg = <0x0 0x40000>;
+				read-only;
+			};
+
+			partition at 40000 {
+				label = "u-boot-env";
+				reg = <0x40000 0x40000>;
+			};
+
+			partition at 80000 {
+				label = "reserved2";
+				reg = <0x80000 0x80000>;
+			};
+
+			partition at 100000 {
+				label = "fip";
+				reg = <0x100000 0x80000>;
+				read-only;
+			};
+
+			partition at 180000 {
+				label = "recovery";
+				reg = <0x180000 0xa80000>;
+			};
+
+			partition at c00000 {
+				label = "fit";
+				reg = <0xc00000 0x1400000>;
 			};
 		};
 	};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
index f623bce075ce6ea4..d9e01967acc471b8 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
@@ -9,15 +9,11 @@
 
 / {
 	compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-
-	fragment at 0 {
-		target-path = "/soc/mmc at 11230000";
-		__overlay__ {
-			bus-width = <4>;
-			max-frequency = <52000000>;
-			cap-sd-highspeed;
-			status = "okay";
-		};
-	};
 };
 
+&{/soc/mmc at 11230000} {
+	bus-width = <4>;
+	max-frequency = <52000000>;
+	cap-sd-highspeed;
+	status = "okay";
+};
-- 
2.34.1



From a-bhatia1 at ti.com  Fri Feb 16 02:07:29 2024
From: a-bhatia1 at ti.com (Aradhya Bhatia)
Date: Fri, 16 Feb 2024 15:37:29 +0530
Subject: [PATCH v5 0/4] Add common1 region for AM62, AM62A & AM65x
In-Reply-To: <20240216062426.4170528-1-devarsht@ti.com>
References: <20240216062426.4170528-1-devarsht@ti.com>
Message-ID: <8a481b57-d55a-44e3-a38e-8dbad3cc79a8@ti.com>



On 16-Feb-24 11:54, Devarsh Thakkar wrote:
> This adds DSS common1 region for respective SoCs supporting it.
> 
> Changelog:
> V2 : Remove do-not-merge tag and add am62a dss common1 reion
> V3 : Add Fixes tag to each commit
> V4 : Add Reviewed-by tag and AM62A SoC TRM Link
> V5 : Split dts patch to separate patches for each SoC
> 
> Devarsh Thakkar (4):
>   dt-bindings: display: ti,am65x-dss: Add support for common1 region
>   arm64: dts: ti: Add common1 register space for AM65x SoC
>   arm64: dts: ti: Add common1 register space for AM62x SoC
>   arm64: dts: ti: Add common1 register space for AM62A SoC

For the series,

Reviewed-by: Aradhya Bhatia <a-bhatia1 at ti.com>

Regards
Aradhya


> 
>  .../devicetree/bindings/display/ti/ti,am65x-dss.yaml       | 7 +++++--
>  arch/arm64/boot/dts/ti/k3-am62-main.dtsi                   | 5 +++--
>  arch/arm64/boot/dts/ti/k3-am62a-main.dtsi                  | 5 +++--
>  arch/arm64/boot/dts/ti/k3-am65-main.dtsi                   | 5 +++--
>  4 files changed, 14 insertions(+), 8 deletions(-)
> 


From macpaul.lin at mediatek.com  Fri Feb 16 01:57:51 2024
From: macpaul.lin at mediatek.com (Macpaul Lin)
Date: Fri, 16 Feb 2024 17:57:51 +0800
Subject: [PATCH] arm64: dts: mediatek: mt8395-genio-1200-evk: add u3port1 for xhci1
Message-ID: <20240216095751.4937-1-macpaul.lin@mediatek.com>

This patch fixes an issue where xhci1 was not functioning properly because
the state and PHY settings were incorrect.

The introduction of the 'force-mode' property in the phy-mtk-tphy driver
allows for the correct initialization of xhci1 by updating the Device Tree
settings accordingly.

The necessary fixup which added support for the 'force-mode' switch in the
phy-mtk-tphy driver.
commit 9b27303003f5 ("phy: mediatek: tphy: add support force phy mode switch")
Link: https://lore.kernel.org/r/20231211025624.28991-2-chunfeng.yun at mediatek.com

Prior to this fix, the system would exhibit the following probe failure messages
for xhci1:
  xhci-mtk 11290000.usb: supply vbus not found, using dummy regulator
  xhci-mtk 11290000.usb: uwk - reg:0x400, version:104
  xhci-mtk 11290000.usb: xHCI Host Controller
  xhci-mtk 11290000.usb: new USB bus registered, assigned bus number 5
  xhci-mtk 11290000.usb: clocks are not stable (0x1003d0f)
  xhci-mtk 11290000.usb: can't setup: -110
  xhci-mtk 11290000.usb: USB bus 5 deregistered
  xhci-mtk: probe of 11290000.usb failed with error -110

With the application of this dts fixup, the aforementioned initialization errors
are resolved and xhci1 is working.

Signed-off-by: Macpaul Lin <macpaul.lin at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
index 7fc515a07c65..e0b9f2615c11 100644
--- a/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
@@ -854,6 +854,10 @@
 
 &u3phy1 {
 	status = "okay";
+
+	u3port1: usb-phy at 700 {
+		mediatek,force-mode;
+	};
 };
 
 &u3phy2 {
@@ -885,6 +889,8 @@
 };
 
 &xhci1 {
+	phys = <&u2port1 PHY_TYPE_USB2>,
+	       <&u3port1 PHY_TYPE_USB3>;
 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
 	status = "okay";
 };
-- 
2.18.0



From theo.lebrun at bootlin.com  Fri Feb 16 02:18:22 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 16 Feb 2024 11:18:22 +0100
Subject: [PATCH 02/13] dt-bindings: i2c: nomadik: add mobileye,eyeq5-i2c
 bindings and example
In-Reply-To: <20240216022227.GA850600-robh@kernel.org>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>
 <20240216022227.GA850600-robh@kernel.org>
Message-ID: <CZ6FD7EHIJDT.32IEDVT9FG2GP@bootlin.com>

Hello,

On Fri Feb 16, 2024 at 3:22 AM CET, Rob Herring wrote:
> On Thu, Feb 15, 2024 at 05:52:09PM +0100, Th?o Lebrun wrote:
> > Add EyeQ5 bindings to the existing Nomadik I2C dt-bindings. Add the two
> > EyeQ5-specific properties behind a conditional. Add an example for this
> > compatible.

[...]

> > +allOf:
> > +  - $ref: /schemas/i2c/i2c-controller.yaml#
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: mobileye,eyeq5-i2c
> > +    then:
> > +      properties:
> > +        mobileye,olb:
> > +          $ref: /schemas/types.yaml#/definitions/phandle
> > +          description: A phandle to the OLB syscon.
>
> Define properties at the top-level and then restrict them in if/then 
> schemas.

Noted, thanks.

> > +        mobileye,id:
> > +          $ref: /schemas/types.yaml#/definitions/uint32
> > +          description: Platform-wide controller ID (integer starting from zero).
>
> instance indexes are a NAK. You can use i2cN aliases if you must.
>
> Why do you need it? To access OLB? If so, add cell args to the OLB 
> phandle instead.

Why we do what we do: I2C controller must write a 2 bit value depending
on the bus speed. All I2C controllers write into the same register.
Index is used to compute the shift.

mobileye,olb is a phandle to a syscon. I'll be using i2cN aliases I
guess.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From zev at bewilderbeest.net  Fri Feb 16 02:20:37 2024
From: zev at bewilderbeest.net (Zev Weiss)
Date: Fri, 16 Feb 2024 02:20:37 -0800
Subject: [PATCH] Add eSPI device driver (flash channel)
In-Reply-To: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
References: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
Message-ID: <f63c3077-f8cc-4f05-92ef-9b2303b181f4@hatter.bewilderbeest.net>

On Tue, Feb 13, 2024 at 06:36:08AM PST, Manojkiran Eda wrote:
>This patch adds the driver support for the eSPI controller of
>Aspeed 5/6th generation SoCs. This controller is a slave device
>communicating with a master over Enhanced Serial Peripheral
>Interface (eSPI).
>
>eSPI supports 4 channels, namely peripheral, virtual wire,
>out-of-band, and flash, and operates at max frequency of 66MHz.
>
>But at the moment, this patch set only supports the flash channel.
>
>Signed-off-by: Manojkiran Eda <manojkiran.eda at gmail.com>

Hi Manojkiran,

Glad to see this progressing again!  It sounds like there may still be 
some open questions regarding the approach, and as others have noted 
there are things included here that should be split out into separate 
patches.

I did try it out in its current form though, and encountered a few 
problems...

Firstly, the calls to dev_notice() all appear to be missing the struct 
device * as their first argument and hence don't compile (I hacked 
around this to get it to build).

Second, the device-tree updates only include aspeed-g6.dtsi, so I 
manually imported the corresponding aspeed-g5.dtsi change from the last 
version Chia-Wei posted [1] and used that for the AST2500 system I need 
eSPI support on.

[1] https://lore.kernel.org/linux-arm-kernel/20220516005412.4844-1-chiawei_wang at aspeedtech.com/

And finally, after making the above changes and running it I got the 
following during boot:

[    0.288079] aspeed-espi-ctrl 1e6ee000.espi-ctrl: something went wrong
[    0.288120] aspeed-espi-ctrl 1e6ee000.espi-ctrl: failed to allocate flash channel

I'm not sure if there's some change in this new version such that the 
dtsi patch I imported from the old one no longer works, but if nothing 
else it might at least suggest that the error messages could be made a 
bit more informative.


Thanks,
Zev



From theo.lebrun at bootlin.com  Fri Feb 16 02:22:52 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 16 Feb 2024 11:22:52 +0100
Subject: [PATCH 03/13] dt-bindings: hwmon: lm75: add label property
In-Reply-To: <ebd2be9f-fbad-4295-b74d-35647d08ee76@linaro.org>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-3-19a336e91dca@bootlin.com>
 <3e541dd7-90d8-43d1-a5b5-260828ac2a86@linaro.org>
 <ebd2be9f-fbad-4295-b74d-35647d08ee76@linaro.org>
Message-ID: <CZ6FGNCLDNBQ.1ZTPRHJ71KRJK@bootlin.com>

Hello,

On Fri Feb 16, 2024 at 9:00 AM CET, Krzysztof Kozlowski wrote:
> On 16/02/2024 08:41, Krzysztof Kozlowski wrote:
> > On 15/02/2024 17:52, Th?o Lebrun wrote:
> >> Declare optional label devicetree property. Show usage in one example
> >> with dummy name.
> >>
> >> To: Jean Delvare <jdelvare at suse.com>
> >> To: Guenter Roeck <linux at roeck-us.net>
> >> Cc: <linux-hwmon at vger.kernel.org>
> >> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> >> ---
> > 
> > 
> > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> > 
>
> Although you might need to re-work this patch if this gets accepted:
>
> https://lore.kernel.org/linux-devicetree/20240216-dt-bindings-hwmon-common-v1-0-3c2c24ff1260 at linaro.org/T/#m341d8f47ca5badd2637cd662fb331f144e16a54c

Cool that this is made generic. Do not hesitate to Cc me in follow-ups.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From theo.lebrun at bootlin.com  Fri Feb 16 02:26:05 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 16 Feb 2024 11:26:05 +0100
Subject: [PATCH 13/13] MIPS: mobileye: eyeq5: add resets to I2C
 controllers
In-Reply-To: <c478bb6f-49b8-4251-99e9-46b4c9510953@linaro.org>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-13-19a336e91dca@bootlin.com>
 <42b7e3bb-a152-4ded-91f3-fb8043a7f413@linaro.org>
 <CZ6DTGBC02P7.1RHCB4E64N88A@bootlin.com>
 <c478bb6f-49b8-4251-99e9-46b4c9510953@linaro.org>
Message-ID: <CZ6FJ3Z78VWO.242BXKNE6RCUV@bootlin.com>

Hello,

On Fri Feb 16, 2024 at 10:17 AM CET, Krzysztof Kozlowski wrote:
> On 16/02/2024 10:05, Th?o Lebrun wrote:
> > Hello,
> > 
> > On Fri Feb 16, 2024 at 8:59 AM CET, Krzysztof Kozlowski wrote:
> >> On 15/02/2024 17:52, Th?o Lebrun wrote:
> >>> Add resets properties to each I2C controller. This depends on the
> >>> reset-eyeq5 platform reset controller driver.
> >>>
> >>> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> >>> ---
> >>
> >> This should be squashed with previous patch adding i2c controllers.
> >> Don't add incomplete nodes just to fix them in next patch.
> > 
> > The goal was to isolate reset phandles to a single patch. The series
>
> That was what you did, not the goal. If that's the goal, then it is
> clearly wrong.
>
> > with this patch dropped works because resets in their default state are
> > deasserted, so this isn't a fix. And it allows testing the series on
> > hardware with only the base platform series, which I found useful.
>
> Series or half-of-series? Anyway, commits must be logical chunks, so one
> chunk is to add I2C controllers, not "part of I2C controllers". DTS is
> also independent of drivers (and it will go via different trees!), so
> whatever dependency you think of, it does not exist.

My reasoning was focused on my point-of-view as a contributor and tester
of the series. Your explanation makes sense; I had never thought this
through from the maintainer's POV.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From alexander.stein at ew.tq-group.com  Fri Feb 16 02:28:36 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 16 Feb 2024 11:28:36 +0100
Subject: [PATCH v12 11/12] media: rkisp1: Fix endianness on raw streams on i.MX8MP
In-Reply-To: <20240216095458.2919694-12-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com> <20240216095458.2919694-12-paul.elder@ideasonboard.com>
Message-ID: <1980499.usQuhbGJ8B@steina-w>

Hi Paul,

thanks for updating this.

Am Freitag, 16. Februar 2024, 10:54:57 CET schrieb Paul Elder:
> The i.MX8MP has extra register fields in the memory interface control
> register for setting the output format, which work with the output
> alignment format register for byte-swapping and LSB/MSB alignment.
> 
> With processed and 8-bit raw streams, it doesn't cause any problems to
> not set these, but with raw streams of higher bit depth the endianness
> is swapped and the data is not aligned properly.
> 
> Add support for settings these registers and plumb them in to fix this.
> 
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> ---
> Changes in v12:
> - replace MP_OUTPUT_FORMAT feature flag with MAIN_STRIDE
> 
> New in v6
> ---
>  .../platform/rockchip/rkisp1/rkisp1-capture.c | 93 ++++++++++++++-----
>  .../platform/rockchip/rkisp1/rkisp1-regs.h    |  8 ++
>  2 files changed, 78 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c index
> 64b1d1104e20..28a99b31581b 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> @@ -48,16 +48,20 @@ enum rkisp1_plane {
>   * @fmt_type: helper filed for pixel format
>   * @uv_swap: if cb cr swapped, for yuv
>   * @yc_swap: if y and cb/cr swapped, for yuv
> + * @byte_swap: if byte pairs are swapped, for raw
>   * @write_format: defines how YCbCr self picture data is written to memory
> - * @output_format: defines sp output format
> + * @output_format_mp: defines mp output format
> + * @output_format_sp: defines sp output format
>   * @mbus: the mbus code on the src resizer pad that matches the pixel
> format */
>  struct rkisp1_capture_fmt_cfg {
>  	u32 fourcc;
>  	u32 uv_swap : 1;
>  	u32 yc_swap : 1;
> +	u32 byte_swap : 1;
>  	u32 write_format;
> -	u32 output_format;
> +	u32 output_format_mp;
> +	u32 output_format_sp;
>  	u32 mbus;
>  };
> 
> @@ -96,42 +100,50 @@ static const struct rkisp1_capture_fmt_cfg
> rkisp1_mp_fmts[] = { .fourcc = V4L2_PIX_FMT_YUYV,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_UYVY,
>  		.uv_swap = 0,
>  		.yc_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YUV422P,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV16,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV61,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV16M,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV61M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YVU422M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	},
>  	/* yuv400 */
> @@ -139,6 +151,7 @@ static const struct rkisp1_capture_fmt_cfg
> rkisp1_mp_fmts[] = { .fourcc = V4L2_PIX_FMT_GREY,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	},
>  	/* yuv420 */
> @@ -146,81 +159,107 @@ static const struct rkisp1_capture_fmt_cfg
> rkisp1_mp_fmts[] = { .fourcc = V4L2_PIX_FMT_NV21,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV12,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV21M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV12M,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YUV420,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YVU420,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	},
>  	/* raw */
>  	{
>  		.fourcc = V4L2_PIX_FMT_SRGGB8,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
>  		.mbus = MEDIA_BUS_FMT_SRGGB8_1X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGRBG8,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
>  		.mbus = MEDIA_BUS_FMT_SGRBG8_1X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGBRG8,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
>  		.mbus = MEDIA_BUS_FMT_SGBRG8_1X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SBGGR8,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
>  		.mbus = MEDIA_BUS_FMT_SBGGR8_1X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SRGGB10,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
>  		.mbus = MEDIA_BUS_FMT_SRGGB10_1X10,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGRBG10,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
>  		.mbus = MEDIA_BUS_FMT_SGRBG10_1X10,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGBRG10,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
>  		.mbus = MEDIA_BUS_FMT_SGBRG10_1X10,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SBGGR10,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
>  		.mbus = MEDIA_BUS_FMT_SBGGR10_1X10,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SRGGB12,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
>  		.mbus = MEDIA_BUS_FMT_SRGGB12_1X12,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGRBG12,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
>  		.mbus = MEDIA_BUS_FMT_SGRBG12_1X12,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SGBRG12,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
>  		.mbus = MEDIA_BUS_FMT_SGBRG12_1X12,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_SBGGR12,
> +		.byte_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
>  		.mbus = MEDIA_BUS_FMT_SBGGR12_1X12,
>  	},
>  };
> @@ -235,50 +274,50 @@ static const struct rkisp1_capture_fmt_cfg
> rkisp1_sp_fmts[] = { .fourcc = V4L2_PIX_FMT_YUYV,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_UYVY,
>  		.uv_swap = 0,
>  		.yc_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YUV422P,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV16,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV61,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV16M,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV61M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YVU422M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	},
>  	/* yuv400 */
> @@ -286,19 +325,19 @@ static const struct rkisp1_capture_fmt_cfg
> rkisp1_sp_fmts[] = { .fourcc = V4L2_PIX_FMT_GREY,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	},
>  	/* rgb */
>  	{
>  		.fourcc = V4L2_PIX_FMT_XBGR32,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_RGB565,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
>  	},
>  	/* yuv420 */
> @@ -306,37 +345,37 @@ static const struct rkisp1_capture_fmt_cfg
> rkisp1_sp_fmts[] = { .fourcc = V4L2_PIX_FMT_NV21,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV12,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV21M,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_NV12M,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YUV420,
>  		.uv_swap = 0,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	}, {
>  		.fourcc = V4L2_PIX_FMT_YVU420,
>  		.uv_swap = 1,
>  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
>  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
>  	},
>  };
> @@ -484,10 +523,12 @@ static void rkisp1_mp_config(struct rkisp1_capture
> *cap) */
>  	if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
>  		reg = rkisp1_read(rkisp1, 
RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
> -		if (cap->pix.cfg->yc_swap)
> +		if (cap->pix.cfg->yc_swap || cap->pix.cfg->byte_swap)
>  			reg |= 
RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
>  		else
>  			reg &= 
~RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
> +
> +		reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_LSB_ALIGNMENT;
>  		rkisp1_write(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT, 
reg);
>  	}
> 
> @@ -554,7 +595,7 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap)
> mi_ctrl &= ~RKISP1_MI_CTRL_SP_FMT_MASK;
>  	mi_ctrl |= cap->pix.cfg->write_format |
>  		   RKISP1_MI_CTRL_SP_INPUT_YUV422 |
> -		   cap->pix.cfg->output_format |
> +		   cap->pix.cfg->output_format_sp |
>  		   RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE;
>  	rkisp1_write(rkisp1, RKISP1_CIF_MI_CTRL, mi_ctrl);
>  }
> @@ -946,6 +987,7 @@ static void rkisp1_cap_stream_enable(struct
> rkisp1_capture *cap) struct rkisp1_device *rkisp1 = cap->rkisp1;
>  	struct rkisp1_capture *other = &rkisp1->capture_devs[cap->id ^ 1];
>  	bool has_self_path = rkisp1_has_feature(rkisp1, SELF_PATH);
> +	u32 reg;
> 
>  	cap->ops->set_data_path(cap);
>  	cap->ops->config(cap);
> @@ -965,8 +1007,13 @@ static void rkisp1_cap_stream_enable(struct
> rkisp1_capture *cap) */
>  	if (!has_self_path || !other->is_streaming) {
>  		/* force cfg update */
> -		rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT,
> -			     RKISP1_CIF_MI_INIT_SOFT_UPD);
> +		reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_INIT);
> +
> +		if (rkisp1_has_feature(rkisp1, MAIN_STRIDE))
> +			reg |= cap->pix.cfg->output_format_mp;

I don't have any documents regarding that ISP, but shouldn't you clear the 
bits for output_format_mp before OR'ing the new ones on top?

Best regards,
Alexander

> +
> +		reg |= RKISP1_CIF_MI_INIT_SOFT_UPD;
> +		rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT, reg);
>  		rkisp1_set_next_buf(cap);
>  	}
>  	spin_unlock_irq(&cap->buf.lock);
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h index
> 3b19c8411360..762243016f05 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> @@ -144,6 +144,14 @@
>  /* MI_INIT */
>  #define RKISP1_CIF_MI_INIT_SKIP				BIT(2)
>  #define RKISP1_CIF_MI_INIT_SOFT_UPD			BIT(4)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400		(0 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420		(1 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422		(2 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV444		(3 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12		(4 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8		(5 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_JPEG		(6 << 5)
> +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10		(7 << 5)
> 
>  /* MI_CTRL_SHD */
>  #define RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED		BIT(0)


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From alexander.stein at ew.tq-group.com  Fri Feb 16 02:31:46 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 16 Feb 2024 11:31:46 +0100
Subject: [PATCH v12 08/12] media: rkisp1: Support i.MX8MP's 34-bit DMA
In-Reply-To: <20240216095458.2919694-9-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com> <20240216095458.2919694-9-paul.elder@ideasonboard.com>
Message-ID: <1884916.CQOukoFCf9@steina-w>

Hi Paul,

thanks for the update.

Am Freitag, 16. Februar 2024, 10:54:54 CET schrieb Paul Elder:
> On the ISP that is integrated in the i.MX8MP, DMA addresses have been
> extended to 34 bits, with the 32 MSBs stored in the DMA address
> registers and the 2 LSBs set to 0.
> 
> To support this:
> - Shift the addresses to the right by 2 when writing to registers
> - Set the dma mask to 34 bits
> - Use dma_addr_t instead of u32 when storing the addresses
> 
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Tested-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
> Changes since v5:
> 
> - Improve the commit message
> 
> Changes since v4:
> 
> - Squash in fix from Tomi:
>   -
> https://gitlab.com/ideasonboard/nxp/linux/-/commit/d6477fe673b1c0d05d12ae21
> d8db9a03b07e7fea
> 
> Changes since v2:
> 
> - Document the RKISP1_FEATURE_DMA_34BIT bit
> - Use the rkisp1_has_feature() macro
> ---
>  .../platform/rockchip/rkisp1/rkisp1-capture.c | 20 ++++++++++---------
>  .../platform/rockchip/rkisp1/rkisp1-common.h  |  4 +++-
>  .../platform/rockchip/rkisp1/rkisp1-dev.c     |  8 ++++++++
>  3 files changed, 22 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c index
> ca95f62822fa..1ee7639c42b7 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> @@ -648,11 +648,13 @@ static void rkisp1_dummy_buf_destroy(struct
> rkisp1_capture *cap)
> 
>  static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
>  {
> +	u8 shift = rkisp1_has_feature(cap->rkisp1, DMA_34BIT) ? 2 : 0;
> +
>  	cap->buf.curr = cap->buf.next;
>  	cap->buf.next = NULL;
> 
>  	if (!list_empty(&cap->buf.queue)) {
> -		u32 *buff_addr;
> +		dma_addr_t *buff_addr;
> 
>  		cap->buf.next = list_first_entry(&cap->buf.queue, struct 
rkisp1_buffer,
> queue); list_del(&cap->buf.next->queue);
> @@ -660,7 +662,7 @@ static void rkisp1_set_next_buf(struct rkisp1_capture
> *cap) buff_addr = cap->buf.next->buff_addr;
> 
>  		rkisp1_write(cap->rkisp1, cap->config->mi.y_base_ad_init,
> -			     buff_addr[RKISP1_PLANE_Y]);
> +			     buff_addr[RKISP1_PLANE_Y] >> shift);
>  		/*
>  		 * In order to support grey format we capture
>  		 * YUV422 planar format from the camera and
> @@ -669,17 +671,17 @@ static void rkisp1_set_next_buf(struct rkisp1_capture
> *cap) if (cap->pix.cfg->fourcc == V4L2_PIX_FMT_GREY) {
>  			rkisp1_write(cap->rkisp1,
>  				     cap->config->mi.cb_base_ad_init,
> -				     cap->buf.dummy.dma_addr);
> +				     cap->buf.dummy.dma_addr >> 
shift);
>  			rkisp1_write(cap->rkisp1,
>  				     cap->config->mi.cr_base_ad_init,
> -				     cap->buf.dummy.dma_addr);
> +				     cap->buf.dummy.dma_addr >> 
shift);
>  		} else {
>  			rkisp1_write(cap->rkisp1,
>  				     cap->config->mi.cb_base_ad_init,
> -				     buff_addr[RKISP1_PLANE_CB]);
> +				     buff_addr[RKISP1_PLANE_CB] >> 
shift);
>  			rkisp1_write(cap->rkisp1,
>  				     cap->config->mi.cr_base_ad_init,
> -				     buff_addr[RKISP1_PLANE_CR]);
> +				     buff_addr[RKISP1_PLANE_CR] >> 
shift);
>  		}
>  	} else {
>  		/*
> @@ -687,11 +689,11 @@ static void rkisp1_set_next_buf(struct rkisp1_capture
> *cap) * throw data if there is no available buffer.
>  		 */
>  		rkisp1_write(cap->rkisp1, cap->config->mi.y_base_ad_init,
> -			     cap->buf.dummy.dma_addr);
> +			     cap->buf.dummy.dma_addr >> shift);
>  		rkisp1_write(cap->rkisp1, cap->config->mi.cb_base_ad_init,
> -			     cap->buf.dummy.dma_addr);
> +			     cap->buf.dummy.dma_addr >> shift);
>  		rkisp1_write(cap->rkisp1, cap->config->mi.cr_base_ad_init,
> -			     cap->buf.dummy.dma_addr);
> +			     cap->buf.dummy.dma_addr >> shift);
>  	}
> 
>  	/* Set plane offsets */
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index
> 69940014d597..26573f6ae575 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> @@ -114,6 +114,7 @@ enum rkisp1_isp_pad {
>   * @RKISP1_FEATURE_MAIN_STRIDE: The ISP supports configurable stride on the
> main path * @RKISP1_FEATURE_SELF_PATH: The ISP has a self path
>   * @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the
> resizer input + * @RKISP1_FEATURE_DMA_34BIT: The ISP uses 34-bit DMA
> addresses
>   *
>   * The ISP features are stored in a bitmask in &rkisp1_info.features and
> allow * the driver to implement support for features present in some ISP
> versions @@ -124,6 +125,7 @@ enum rkisp1_feature {
>  	RKISP1_FEATURE_MAIN_STRIDE = BIT(1),
>  	RKISP1_FEATURE_SELF_PATH = BIT(2),
>  	RKISP1_FEATURE_DUAL_CROP = BIT(3),
> +	RKISP1_FEATURE_DMA_34BIT = BIT(4),
>  };
> 
>  #define rkisp1_has_feature(rkisp1, feature) \
> @@ -239,7 +241,7 @@ struct rkisp1_vdev_node {
>  struct rkisp1_buffer {
>  	struct vb2_v4l2_buffer vb;
>  	struct list_head queue;
> -	u32 buff_addr[VIDEO_MAX_PLANES];
> +	dma_addr_t buff_addr[VIDEO_MAX_PLANES];
>  };
> 
>  /*
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index
> d0a3a13d9dd7..54a62487a4e8 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> @@ -552,6 +552,7 @@ static int rkisp1_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct rkisp1_device *rkisp1;
>  	struct v4l2_device *v4l2_dev;
> +	unsigned long long dma_mask;

The signature for dma_set_mask_and_coherent() uses u64 for the mask, so I 
would use the same type here as well.

Best regards,
Alexander

>  	unsigned int i;
>  	int ret, irq;
>  	u32 cif_id;
> @@ -566,6 +567,13 @@ static int rkisp1_probe(struct platform_device *pdev)
>  	dev_set_drvdata(dev, rkisp1);
>  	rkisp1->dev = dev;
> 
> +	dma_mask = rkisp1_has_feature(rkisp1, DMA_34BIT) ? DMA_BIT_MASK(34) 
:
> +							   
DMA_BIT_MASK(32);
> +
> +	ret = dma_set_mask_and_coherent(dev, dma_mask);
> +	if (ret)
> +		return ret;
> +
>  	mutex_init(&rkisp1->stream_lock);
> 
>  	rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From krzysztof.kozlowski at linaro.org  Fri Feb 16 02:33:01 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 11:33:01 +0100
Subject: [PATCH 02/13] dt-bindings: i2c: nomadik: add mobileye,eyeq5-i2c
 bindings and example
In-Reply-To: <CZ6FD7EHIJDT.32IEDVT9FG2GP@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>
 <20240216022227.GA850600-robh@kernel.org>
 <CZ6FD7EHIJDT.32IEDVT9FG2GP@bootlin.com>
Message-ID: <6effca50-29a4-43b9-86eb-310bd4e08e5c@linaro.org>

On 16/02/2024 11:18, Th?o Lebrun wrote:
> 
>>> +        mobileye,id:
>>> +          $ref: /schemas/types.yaml#/definitions/uint32
>>> +          description: Platform-wide controller ID (integer starting from zero).
>>
>> instance indexes are a NAK. You can use i2cN aliases if you must.
>>
>> Why do you need it? To access OLB? If so, add cell args to the OLB 
>> phandle instead.
> 
> Why we do what we do: I2C controller must write a 2 bit value depending
> on the bus speed. All I2C controllers write into the same register.

Which register?  Your devices do not share IO address space.

> Index is used to compute the shift.
> 
> mobileye,olb is a phandle to a syscon. I'll be using i2cN aliases I
> guess.
> 
> Thanks,
> 
> --
> Th?o Lebrun, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

Best regards,
Krzysztof



From theo.lebrun at bootlin.com  Fri Feb 16 02:40:50 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 16 Feb 2024 11:40:50 +0100
Subject: [PATCH 02/13] dt-bindings: i2c: nomadik: add mobileye,eyeq5-i2c
 bindings and example
In-Reply-To: <6effca50-29a4-43b9-86eb-310bd4e08e5c@linaro.org>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>
 <20240216022227.GA850600-robh@kernel.org>
 <CZ6FD7EHIJDT.32IEDVT9FG2GP@bootlin.com>
 <6effca50-29a4-43b9-86eb-310bd4e08e5c@linaro.org>
Message-ID: <CZ6FUECKEX2B.36QWZZA5EYPI@bootlin.com>

Hello,

On Fri Feb 16, 2024 at 11:33 AM CET, Krzysztof Kozlowski wrote:
> On 16/02/2024 11:18, Th?o Lebrun wrote:
> > 
> >>> +        mobileye,id:
> >>> +          $ref: /schemas/types.yaml#/definitions/uint32
> >>> +          description: Platform-wide controller ID (integer starting from zero).
> >>
> >> instance indexes are a NAK. You can use i2cN aliases if you must.
> >>
> >> Why do you need it? To access OLB? If so, add cell args to the OLB 
> >> phandle instead.
> > 
> > Why we do what we do: I2C controller must write a 2 bit value depending
> > on the bus speed. All I2C controllers write into the same register.
>
> Which register?  Your devices do not share IO address space.

mobileye,olb is a prop with a phandle to a syscon. That syscon contains
the register we are interested in.

The Linux code side of things is in the following patch. We use
syscon_regmap_lookup_by_phandle().

   [PATCH 10/13] i2c: nomadik: support Mobileye EyeQ5 I2C controller
   https://lore.kernel.org/lkml/20240215-mbly-i2c-v1-10-19a336e91dca at bootlin.com/

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From theo.lebrun at bootlin.com  Fri Feb 16 02:43:00 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 16 Feb 2024 11:43:00 +0100
Subject: [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from
 drivers/pinctrl/nomadik/
In-Reply-To: <e031566a85ae0da0ee71dffba5d87c6414ef83e1.camel@pengutronix.de>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>
 <e031566a85ae0da0ee71dffba5d87c6414ef83e1.camel@pengutronix.de>
Message-ID: <CZ6FW2H4BPEL.D5W7U5H7THDH@bootlin.com>

Hello,

On Thu Feb 15, 2024 at 11:03 AM CET, Philipp Zabel wrote:
> On Mi, 2024-02-14 at 17:23 +0100, Th?o Lebrun wrote:
> [...]
> > diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
> > new file mode 100644
> > index 000000000000..e39477e1a58f
> > --- /dev/null
> > +++ b/drivers/gpio/gpio-nomadik.c
> > @@ -0,0 +1,660 @@
> [...]
> > +static int nmk_gpio_probe(struct platform_device *dev)
> > +{
> [...]
> > +	ret = gpiochip_add_data(chip, nmk_chip);
>
> Use devm_gpiochip_add_data() to cleanup on unbind, before nmk_chip goes
> away. Or make the driver un-unbindable via suppress_bind_attrs. In that
> case you could drop devm_ prefixes everywhere for consistency.

Disabling unbind sounds like the best option. Will do so in next
revision, in a separate patch to keep this one as close of a copy-paste
as possible.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From francesco at dolcini.it  Fri Feb 16 02:42:55 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Fri, 16 Feb 2024 11:42:55 +0100
Subject: [PATCH v1] ARM: dts: imx7: remove DSI port endpoints
Message-ID: <20240216104255.21052-1-francesco@dolcini.it>

From: Francesco Dolcini <francesco.dolcini at toradex.com>

This fixes the display not working on colibri imx7, the driver fails to
load with the following error:

  mxsfb 30730000.lcdif: error -ENODEV: Cannot connect bridge

NXP i.MX7 LCDIF is connected to both the Parallel LCD Display and to a
MIPI DSI IP block, currently it's not possible to describe the
connection to both.

Remove the port endpoint from the SOC dtsi to prevent regressions, this
would need to be defined on the board DTS.

Reported-by: Hiago De Franco <hiagofranco at gmail.com>
Closes: https://lore.kernel.org/r/34yzygh3mbwpqr2re7nxmhyxy3s7qmqy4vhxvoyxnoguktriur at z66m7gvpqlia/
Fixes: edbbae7fba49 ("ARM: dts: imx7: add MIPI-DSI support")
Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
---
 arch/arm/boot/dts/nxp/imx/imx7s.dtsi | 26 --------------------------
 1 file changed, 26 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
index ebf7befcc11e..9c81c6baa2d3 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7s.dtsi
@@ -834,16 +834,6 @@ lcdif: lcdif at 30730000 {
 					<&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>;
 				clock-names = "pix", "axi";
 				status = "disabled";
-
-				port {
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					lcdif_out_mipi_dsi: endpoint at 0 {
-						reg = <0>;
-						remote-endpoint = <&mipi_dsi_in_lcdif>;
-					};
-				};
 			};
 
 			mipi_csi: mipi-csi at 30750000 {
@@ -895,22 +885,6 @@ mipi_dsi: dsi at 30760000 {
 				samsung,esc-clock-frequency = <20000000>;
 				samsung,pll-clock-frequency = <24000000>;
 				status = "disabled";
-
-				ports {
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					port at 0 {
-						reg = <0>;
-						#address-cells = <1>;
-						#size-cells = <0>;
-
-						mipi_dsi_in_lcdif: endpoint at 0 {
-							reg = <0>;
-							remote-endpoint = <&lcdif_out_mipi_dsi>;
-						};
-					};
-				};
 			};
 		};
 
-- 
2.39.2



From theo.lebrun at bootlin.com  Fri Feb 16 02:46:36 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 16 Feb 2024 11:46:36 +0100
Subject: [PATCH 19/23] gpio: nomadik: grab optional reset control and
 deassert it at probe
In-Reply-To: <d51dbac55d3677031bfab8bfe959f7b556b1c373.camel@pengutronix.de>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-19-f88c0ccf372b@bootlin.com>
 <d51dbac55d3677031bfab8bfe959f7b556b1c373.camel@pengutronix.de>
Message-ID: <CZ6FYTJD4L6Q.171I9ZOL1S965@bootlin.com>

Hello,

On Thu Feb 15, 2024 at 11:19 AM CET, Philipp Zabel wrote:
> On Mi, 2024-02-14 at 17:24 +0100, Th?o Lebrun wrote:
> > Fetch a reference to the optional shared reset control and deassert it
> > if it exists.
> > 
> > Optional because not all platforms that use this driver have a reset
> > attached to the reset block. Shared because some platforms that use the
> > reset (at least Mobileye EyeQ5) share the reset across banks.
> > 
> > Do not keep a reference to the reset control as it is not needed
> > afterwards; the driver does not handle suspend, does not use runtime PM
> > and does not register a remove callback.
>
> I suppose you don't care that the reset is only ever deasserted once
> and never asserted again on this hardware, but for shared reset
> controls the expectation is that deassert/assert calls are balanced:
>
> https://docs.kernel.org/driver-api/reset.html?highlight=balanced#assertion-and-deassertion
>
> So maybe this warrants a comment in the code. Or do you mean to
> suppress unbind via suppress_bind_attrs to explain away any missing
> cleanup?

Those resets are shared only across GPIO banks which have no reason to
be unbind-able. I'll add a comment and disable unbind.

> > The operation is done in nmk_gpio_populate_chip(). This function is
> > called by either gpio-nomadik or pinctrl-nomadik, whoever comes first.
> > This is here for historic reasons and could probably be removed now; it
> > seems gpio-ranges enforces the ordering to be pinctrl-first. It is not
> > the topic of the present patch however.
> > 
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> > ---
> >  drivers/gpio/gpio-nomadik.c | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> > 
> > diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
> > index 21bb6d6363fc..b623c093b54d 100644
> > --- a/drivers/gpio/gpio-nomadik.c
> > +++ b/drivers/gpio/gpio-nomadik.c
> > @@ -513,12 +513,14 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
> >  {
> >  	struct nmk_gpio_chip *nmk_chip;
> >  	struct platform_device *gpio_pdev;
> > +	struct reset_control *reset;
> >  	struct gpio_chip *chip;
> >  	struct resource *res;
> >  	struct clk *clk;
> >  	void __iomem *base;
> >  	uintptr_t flags;
> >  	u32 id, ngpio;
> > +	int ret;
> >  
> >  	gpio_pdev = of_find_device_by_node(np);
> >  	if (!gpio_pdev) {
> > @@ -576,6 +578,19 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
> >  	clk_prepare(clk);
> >  	nmk_chip->clk = clk;
> >  
> > +	reset = devm_reset_control_get_optional_shared(&gpio_pdev->dev, NULL);
> > +	if (IS_ERR(reset)) {
> > +		dev_err(&pdev->dev, "failed getting reset control: %ld\n",
> > +			PTR_ERR(reset));
> > +		return ERR_CAST(reset);
>
> Consider using dev_err_probe() here.

Makes sense, will do so for next revision.

Thanks for the review Philipp,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From arinc.unal at arinc9.com  Fri Feb 16 02:47:17 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Fri, 16 Feb 2024 13:47:17 +0300
Subject: [PATCH net RFC] net: dsa: mt7530: fix link-local frames that
 ingress vlan filtering ports
In-Reply-To: <20240216012445.em247rxfjnyufwm5@skbuf>
References: <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
 <65bbf40d.170a0220.a87f4.becdSMTPIN_ADDED_BROKEN@mx.google.com>
 <20240201232619.nsmm7lvafuem2gou@skbuf>
 <20240216012445.em247rxfjnyufwm5@skbuf>
Message-ID: <af66e632-071f-4c39-ab38-62782e6eff05@arinc9.com>

On 16.02.2024 04:24, Vladimir Oltean wrote:
> On Fri, Feb 02, 2024 at 01:26:19AM +0200, Vladimir Oltean wrote:
>> On Thu, Feb 01, 2024 at 10:13:39PM +0300, Ar?n? ?NAL via B4 Relay wrote:
>>> One remaining limitation is that the ingress port must have a PVID assigned
>>> to it for the frame to be trapped to the CPU port. A PVID is set by default
>>> on vlan aware and vlan unaware ports. However, when the network interface
>>> that pertains to the ingress port is attached to a vlan_filtering enabled
>>> bridge, the user can remove the PVID assignment from it which would prevent
>>> the link-local frames from being trapped to the CPU port.
>>>
>>> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
>>> ---
>>> I couldn't figure out a way to bypass VLAN table lookup for link-local
>>> frames to directly trap them to the CPU port. The CPU port is hardcoded for
>>> MT7530. For MT7531 and the switch on the MT7988 SoC, it depends on the port
>>> matrix to choose the CPU port to trap the frames to. Port matrix and VLAN
>>> table seem to go hand in hand so I don't know if this would even be
>>> possible.
>>>
>>> If possible to implement, link-local frames must not be influenced by the
>>> VLAN table. They must always be trapped to the CPU port, and trapped
>>> untagged.
>>
>> Isn't this, in effect, what the "Leaky VLAN Enable" bit does?
> 
> Hm? Any news on this? I suppose this was the reason for submitting the
> otherwise ok patch as RFC?

I was just finalising my response. I wanted to study the switch a little
bit so that I could give a better response than "the leaky VLAN option
doesn't do anything :/".

 From what I understand, with the leaky VLAN option enabled, the frame won't
possibly be dropped at the VLAN table lookup procedure. This is useless in
this case because with commit ("net: dsa: mt7530: drop untagged frames on
VLAN-aware ports without PVID"), PVC.ACC_FRM of port without PVID set on
software is set to TAGGED to prevent untagged frames ingressing through
this port from being forwarded. So what we need instead is to allow
untagged frames to be forwarded.

With PVC.ACC_FRM set to ALL, all VLAN-untagged frames will be forwarded
[1]. With that, we need to configure the switch in a way that only the
link-local frames will be forwarded. I have yet to find a way to achieve
this.

Before that, here's how I think the switching procedure works.

VLAN-tagged/VLAN-untagged frame ingresses through port

1. Address Table Learning

    The switch will add an entry to the MAC address table; the source
    address as ADDRESS, the ingress port as PORT / FILTER, [if tagged
    frame and PVC.VLAN_ATTR = USER: VID on the VLAN tag; if untagged frame
    (and PVC.VLAN_ATTR = USER or TRANSPARENT), or PVC.VLAN_ATTR =
    TRANSPARENT (and untagged or tagged frame): PPBV1.G0_PORT_VID] as CVID.

2. Address Table Lookup Procedure

    For unicast frame type, the switch will look up the destination address
    as ADDRESS on the MAC address table. If the destination address does not
    match a MAC address table entry, the ports set on MFC.UNU_FFP will be
    the forwardable ports.

    For broadcast frame type, the ports set on MFC.BC_FFP will be the
    forwardable ports.

    For non-IP-multicast multicast frame type, the ports set on MFC.UNM_FFP
    will be the forwardable ports.

3. If PVC.ACC_FRM is set to TAGGED, the switch will drop VLAN-untagged
    frames.

4. If PCR.PORT_VLAN is set to PORT_MATRIX mode, skip to step 6.

5. VLAN Table Lookup Procedure

    The switch will look up the VID on the VLAN table. If the frame is
    VLAN-untagged, the VID will be PPBV1.G0_PORT_VID of the ingress port. If
    entry with the VID does not exist on the VLAN table entry, on SECURITY
    and CHECK modes, the switch will drop the frame. On FALLBACK mode, the
    switch won't drop the frame.

    The switch will look up the ingress port on PORT_MEM on the VLAN table
    entry that matches the VID. If the ingress port is not set on PORT_MEM,
    on SECURITY mode, the switch will drop the frame. On FALLBACK and CHECK
    modes, the switch won't drop the frame.

6. The switch will look up the ports set on PCR.PORT_MATRIX to narrow down
    the ports to forward the frame to. The ingress port will be excluded.

7. VLAN Tag Egress Procedure

    The EG_TAG bit for frames:

    PPPoE Discovery_ARP/RARP: PPP_EG_TAG and ARP_EG_TAG in the APC register.
    IGMP_MLD: IGMP_EG_TAG and MLD_EG_TAG in the IMC register.
    BPDU and PAE: BPDU_EG_TAG and PAE_EG_TAG in the BPC register.
    REV_01 and REV_02: R01_EG_TAG and R02_EG_TAG in the RGAC1 register.
    REV_03 and REV_0E: R03_EG_TAG and R0E_EG_TAG in the RGAC2 register.
    REV_10 and REV_20: R10_EG_TAG and R20_EG_TAG in the RGAC3 register.
    REV_21 and REV_UN: R21_EG_TAG and RUN_EG_TAG in the RGAC4 register.

    For other frames, one of these options set the earliest in this order
    will apply to the frame:

    EG_TAG in the address table.
    EG_TAG in the PVC register.
    EG_CON and EG_TAG per port in the VLAN table.
    EG_TAG in the PCR register.

Frame egresses through port(s)

Clarifications:

- MAC SA of untagged frames are learned even with PVC.ACC_FRM of the
   ingress port set to TAGGED. That's why the 3rd step comes after the 1st
   step. Untagged frames are still dropped with PCR.PORT_VLAN of the ingress
   port set to PORT_MATRIX mode. That's why the 3rd step comes before the
   4th step. I can't prove untagged frames are dropped before address table
   lookup.

- IP multicast frames are looked up on "Destination IP Address Table", and
   "Source IP Address Table" if IGMPv3/MLDv2. I haven't studied these yet so
   I didn't explain processing IP multicast frames.

With VLAN-untagged frames forwarded, frames will leak to non-ingress ports
[2].

We can at least egress non-link-local frames tagged [3]. As stated above,
PVC_EG_TAG does not apply to link-local frames.

If we could disable unicast frame forwarding completely, and unknown
(broadcast, multicast) frame flooding for frames with certain VID, we could
set PVID to 4095 when there's no PVID on software, and disable them for VID
4095 frames. I don't believe this operation exists on this switch IP.

In conclusion, these are the options:
- Let frames tagged with VID 0 leak to non-ingress ports for the benefit
   of always trapping link-local frames.
- Find a way to prevent the leaks.
- Keep disallowing untagged frames from being forwarded, link-local frames
   won't always be trapped.

I would love your input as someone who has much more experience than I do.

[1]
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index eab1f52e7eb3..1e160b6eb035 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1699,11 +1699,6 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
  		/* This VLAN is overwritten without PVID, so unset it */
  		priv->ports[port].pvid = G0_PORT_VID_DEF;
  
-		/* Only accept tagged frames if the port is VLAN-aware */
-		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
-			mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
-				   MT7530_VLAN_ACC_TAGGED);
-
  		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
  			   G0_PORT_VID_DEF);
  	}

With this and the commands below, link-local frames will be trapped to the
CPU port.

ip l add br0 type bridge vlan_filtering 1 && \
ip l set lan1 master br0 && \
ip l set br0 up && \
ip l set lan1 up && \
bridge v a vid 1 dev lan1 && \
tcpdump -X -i eth0

[2]
Enabled ports: P0-P4 as user & P6 as CPU

On VLAN filtering bridge: P0, P1
On VID 0:                 P0, P1 (no PVID on software)
                           P2, P3, P4 (standalone)
                           P6 (CPU port)

Address table:
PORT / FILTER of VID 0 entry ADDRESS PC0: 00000001 (destination port is P0)
PORT / FILTER of VID 0 entry ADDRESS PC1: 00000010 (destination port is P1)
[...]
PORT / FILTER of VID 0 entry ADDRESS SoC: 01000000 (destination port is P6)

VLAN table:
PORT_MEM of VID 0 entry: 01011111

P0 & P1 registers:
PVC.ACC_FRM = ALL
PPBV1.G0_PORT_VID = 0
PCR.PORT_VLAN = SECURITY
PVC.VLAN_ATTR = USER
PCR.PORT_MATRIX = 01000011

VLAN egress configuration:
EG_TAG of VID 0 address table entry ADDRESS PC0 & PC1 = SYSTEM_DEFAULT
P0 & P1 PVC.EG_TAG = SYSTEM_DEFAULT
EG_CON/[EG_TAG per port] of VID 0 VLAN table entry = EG_TAG (TAGGED for P0
& P1, STACK for P6)
P0 & P1 PCR.EG_TAG = SYSTEM_DEFAULT

Global registers:
MFC.BC_FFP =  01011111
MFC.UNU_FFP = 01011111

Broadcast untagged frame ingresses through P0:
1. An entry is added to the MAC address table. P0 as destination port, 0 as
    CVID.
2. MFC.BC_FFP is used to set the forwardable ports, 01011111.
3. Untagged frame is allowed.
4. VLAN table is not skipped.
5. VLAN table entry with 0 as VID exists, the frame is allowed. Ingress
    port is set on PORT_MEM, the frame is allowed.
6. Bitwise AND with PCR.PORT_MATRIX results in 01000011. Bitwise AND with
    ~00000001 (ingress port) results in 01000010. Frame egresses through P1
    & P6.
7. EG_TAG per port of VID 0 VLAN table entry applies. Frame eggresses
    tagged through P1, stacked through P6.

Unicast untagged frame with destination address PC1 ingresses through P0:
1. An entry is added to the MAC address table. P0 as destination port, 0 as
    CVID.
2. Destination address matches an entry. PORT / FILTER of the matching
    entry is used to set the forwardable ports, 00000010.
3. Untagged frame is allowed.
4. VLAN table is not skipped.
5. VLAN table entry with 0 as VID exists, the frame is allowed. Ingress
    port is set on PORT_MEM, the frame is allowed.
6. Bitwise AND with PCR.PORT_MATRIX results in 00000010. Bitwise AND with
    ~00000001 (ingress port) results in 00000010. Frame egresses through P1.
7. EG_TAG per port of VID 0 VLAN table entry applies. Frame eggresses
    tagged.

Unicast untagged frame with unknown destination address ingresses through
P0:
1. An entry is added to the MAC address table. P0 as destination port, 0 as
    CVID.
2. Destination address doesn't match an entry. MFC.UNU_FFP is used to set
    the forwardable ports, 01011111.
3. Untagged frame is allowed.
4. VLAN table is not skipped.
5. VLAN table entry with 0 as VID exists, the frame is allowed. Ingress
    port is set on PORT_MEM, the frame is allowed.
6. Bitwise AND with PCR.PORT_MATRIX results in 01000011. Bitwise AND with
    ~00000001 (ingress port) results in 01000010. Frame egresses through P1
    & P6.
7. EG_TAG per port of VID 0 VLAN table entry applies. Frame eggresses
    tagged through P1, stacked through P6.

[3]
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index eab1f52e7eb3..2c7c5eaba4b6 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1699,10 +1699,10 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
  		/* This VLAN is overwritten without PVID, so unset it */
  		priv->ports[port].pvid = G0_PORT_VID_DEF;
  
-		/* Only accept tagged frames if the port is VLAN-aware */
+		/* Egress leaks tagged */
  		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
-			mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
-				   MT7530_VLAN_ACC_TAGGED);
+			mt7530_rmw(priv, MT7530_PVC_P(port), PVC_EG_TAG_MASK,
+				   PVC_EG_TAG(MT7530_VLAN_EG_TAGGED));
  
  		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
  			   G0_PORT_VID_DEF);
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 3ef9ed0163a1..5ff9a30ef4de 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -259,6 +259,7 @@ enum mt7530_port_mode {
  enum mt7530_vlan_port_eg_tag {
  	MT7530_VLAN_EG_DISABLED = 0,
  	MT7530_VLAN_EG_CONSISTENT = 1,
+	MT7530_VLAN_EG_TAGGED = 6,
  };
  
  enum mt7530_vlan_port_attr {

Ar?n?


From s-vadapalli at ti.com  Fri Feb 16 02:48:26 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Fri, 16 Feb 2024 16:18:26 +0530
Subject: [PATCH v3 18/18] PCI: j721e: add suspend and resume support
In-Reply-To: <20240102-j7200-pcie-s2r-v3-18-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-18-5c2e4a3fac1f@bootlin.com>
Message-ID: <aa791703-81d8-420c-ba35-c8fd08bc3f07@ti.com>

On 24/02/15 04:18PM, Thomas Richard wrote:
> From: Th?o Lebrun <theo.lebrun at bootlin.com>
> 
> Add suspend and resume support. Only the rc mode is supported.
> 
> During the suspend stage PERST# is asserted, then deasserted during the
> resume stage.

Wouldn't this imply that the Endpoint device will be reset and therefore
lose context? Or is it expected that the driver corresponding to the
Endpoint Function in Linux will restore the state on resume, post reset?

Regards,
Siddharth.


From ryan.roberts at arm.com  Fri Feb 16 02:59:25 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri, 16 Feb 2024 10:59:25 +0000
Subject: [PATCH v2] mm/filemap: Allow arch to request folio size for exec
 memory
In-Reply-To: <20240215144849.aba06863acc08b8ded09a187@linux-foundation.org>
References: <20240215154059.2863126-1-ryan.roberts@arm.com>
 <20240215144849.aba06863acc08b8ded09a187@linux-foundation.org>
Message-ID: <af3a7c1f-f054-47b8-b257-d11e877631e9@arm.com>

On 15/02/2024 22:48, Andrew Morton wrote:
> On Thu, 15 Feb 2024 15:40:59 +0000 Ryan Roberts <ryan.roberts at arm.com> wrote:
> 
>> Change the readahead config so that if it is being requested for an
>> executable mapping, do a synchronous read of an arch-specified size in a
>> naturally aligned manner.
> 
> Some nits:

Thanks for taking a look, Andrew!

> 
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -1115,6 +1115,18 @@ static inline void update_mmu_cache_range(struct vm_fault *vmf,
>>   */
>>  #define arch_wants_old_prefaulted_pte	cpu_has_hw_af
>>
>> +/*
>> + * Request exec memory is read into pagecache in at least 64K folios. The
>> + * trade-off here is performance improvement due to storing translations more
>> + * effciently in the iTLB vs the potential for read amplification due to reading
> 
> "efficiently"

ACK; will fix if there is a v3

> 
>> + * data from disk that won't be used. The latter is independent of base page
>> + * size, so we set a page-size independent block size of 64K. This size can be
>> + * contpte-mapped when 4K base pages are in use (16 pages into 1 iTLB entry),
>> + * and HPA can coalesce it (4 pages into 1 TLB entry) when 16K base pages are in
>> + * use.
>> + */
>> +#define arch_wants_exec_folio_order() ilog2(SZ_64K >> PAGE_SHIFT)
>> +
> 
> To my eye, "arch_wants_foo" and "arch_want_foo" are booleans.  Either
> this arch wants a particular treatment or it does not want it.
> 
> I suggest a better name would be "arch_exec_folio_order".

ACK; will fix if there is a v3

> 
>>  static inline bool pud_sect_supported(void)
>>  {
>>  	return PAGE_SIZE == SZ_4K;
>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>> index aab227e12493..6cdd145cbbb9 100644
>> --- a/include/linux/pgtable.h
>> +++ b/include/linux/pgtable.h
>> @@ -407,6 +407,18 @@ static inline bool arch_has_hw_pte_young(void)
>>  }
>>  #endif
>>
>> +#ifndef arch_wants_exec_folio_order
>> +/*
>> + * Returns preferred minimum folio order for executable file-backed memory. Must
>> + * be in range [0, PMD_ORDER]. Negative value implies that the HW has no
>> + * preference and mm will not special-case executable memory in the pagecache.
>> + */
> 
> I think this comment contains material which would be useful above the
> other arch_wants_exec_folio_order() implementation - the "must be in
> range" part.  So I suggest all this material be incorporated into a
> single comment which describes arch_wants_exec_folio_order().  Then
> this comment can be removed entirely.  Assume the reader knows to go
> seek the other definition for the commentary.

Hmm... The approach I've been taking for other arch-overridable helpers is to
put the API spec against the default implementation (i.e. here) then put
comments about the specific implementation against the override. If anything I
would prefer to formalize this comment into proper doc header comment and leave
it here (see for example set_ptes(), and in recent patches now in mm-unstable;
get_and_clear_full_ptes(), wrprotect_ptes(), etc).

I'll move all of this to the arm64 code if you really think that's the right
approach, but that's not my personal preference.

Thanks,
Ryan

> 
>> +static inline int arch_wants_exec_folio_order(void)
>> +{
>> +	return -1;
>> +}
>> +#endif
>> +
>>  #ifndef arch_check_zapped_pte
>>  static inline void arch_check_zapped_pte(struct vm_area_struct *vma,
>>  					 pte_t pte)
>> diff --git a/mm/filemap.c b/mm/filemap.c
>> index 142864338ca4..7954274de11c 100644
>> --- a/mm/filemap.c
>> +++ b/mm/filemap.c
>> @@ -3118,6 +3118,25 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
>>  	}
>>  #endif
>>
>> +	/*
>> +	 * Allow arch to request a preferred minimum folio order for executable
>> +	 * memory. This can often be beneficial to performance if (e.g.) arm64
>> +	 * can contpte-map the folio. Executable memory rarely benefits from
>> +	 * read-ahead anyway, due to its random access nature.
> 
> "readahead"
> 
>> +	 */
>> +	if (vm_flags & VM_EXEC) {
>> +		int order = arch_wants_exec_folio_order();
>> +
>> +		if (order >= 0) {
>> +			fpin = maybe_unlock_mmap_for_io(vmf, fpin);
>> +			ra->size = 1UL << order;
>> +			ra->async_size = 0;
>> +			ractl._index &= ~((unsigned long)ra->size - 1);
>> +			page_cache_ra_order(&ractl, ra, order);
>> +			return fpin;
>> +		}
>> +	}
>> +
>>  	/* If we don't want any read-ahead, don't bother */
>>  	if (vm_flags & VM_RAND_READ)
>>  		return fpin;
> 



From arinc.unal at arinc9.com  Fri Feb 16 03:01:02 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Fri, 16 Feb 2024 14:01:02 +0300
Subject: [PATCH netnext 0/8] MT7530 DSA Subdriver Improvements Act III
In-Reply-To: <20240216013439.dq7s5hp74mjahy4d@skbuf>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
 <20240216013439.dq7s5hp74mjahy4d@skbuf>
Message-ID: <c90958ef-f581-4c1b-86c2-ea71e89fbb65@arinc9.com>

On 16.02.2024 04:34, Vladimir Oltean wrote:
> On Thu, Feb 08, 2024 at 08:51:28AM +0300, Ar?n? ?NAL via B4 Relay wrote:
>> Hello!
>>
>> This is the third patch series with the goal of simplifying the MT7530 DSA
>> subdriver and improving support for MT7530, MT7531, and the switch on the
>> MT7988 SoC.
> 
> There was an automation failure, you used the name "netnext" in the
> subject prefix and patchwork reacted with "Patch does not apply to net"...
> 
> Please resend to get some build testing. I gave a quick look over the
> patches and I didn't see anything obviously objectionable.

Ok then.

Ar?n?


From neil.armstrong at linaro.org  Fri Feb 16 03:03:47 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 16 Feb 2024 12:03:47 +0100
Subject: [PATCH v3 0/7] drm/msm: Add support for the A750 GPU found on the
 SM8650 platform
Message-ID: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>

Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
doesn't have an HWCFG block but a separate register set.

The missing registers are added in the a6xx.xml.h file that would
require a subsequent sync and the non-existent hwcfg is handled
in a6xx_set_hwcg().

The A750 GPU info are added under the adreno_is_a750() macro and
the ADRENO_7XX_GEN3 family id.

This adds:
- the GMU and SMMU bindings
- DRM driver changes
- DT nodes

Dependencies: None

Tested using Mesa's !26934 Merge Request [0] on the SM8650-QRD
and with kmscube & vkcube to test basic rendering.

[0] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26934

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
Changes in v3:
- Fixed smmu bindings if condition for GMU smmu
- Collected reviews
- Link to v2: https://lore.kernel.org/r/20240215-topic-sm8650-gpu-v2-0-6be0b4bf2e09 at linaro.org

Changes in v2:
- Added separate a6xx.xml.h sync from https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27576
- Collected review tags
- Inlined skip_programming
- Use A7XX_RBBM_CGC_P2S_STATUS_TXDONE instead of BIT(0)
- Drop now useless placeholder comment
- Removed interconnect properties
- Rebased on current linux-next
- Link to v1: https://lore.kernel.org/r/20240212-topic-sm8650-gpu-v1-0-708a40b747b5 at linaro.org

---
Neil Armstrong (7):
      dt-bindings: display/msm/gmu: Document Adreno 750 GMU
      dt-bindings: arm-smmu: fix SM8[45]50 GPU SMMU if condition
      dt-bindings: arm-smmu: Document SM8650 GPU SMMU
      drm/msm/a6xx: Add missing regs for A750
      drm/msm: add support for A750 GPU
      arm64: dts: qcom: sm8650: add GPU nodes
      arm64: dts: qcom: sm8650-qrd: enable GPU

 .../devicetree/bindings/display/msm/gmu.yaml       |   1 +
 .../devicetree/bindings/iommu/arm,smmu.yaml        |  17 ++-
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts            |   8 +
 arch/arm64/boot/dts/qcom/sm8650.dtsi               | 166 +++++++++++++++++++++
 drivers/gpu/drm/msm/adreno/a6xx.xml.h              |   9 ++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c              |   2 +
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c              |  28 +++-
 drivers/gpu/drm/msm/adreno/adreno_device.c         |  14 ++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h            |  10 +-
 9 files changed, 247 insertions(+), 8 deletions(-)
---
base-commit: 2c3b09aac00d7835023bbc4473ee06696be64fa8
change-id: 20240208-topic-sm8650-gpu-489d5e2c2b17

Best regards,
-- 
Neil Armstrong <neil.armstrong at linaro.org>



From neil.armstrong at linaro.org  Fri Feb 16 03:03:48 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 16 Feb 2024 12:03:48 +0100
Subject: [PATCH v3 1/7] dt-bindings: display/msm/gmu: Document Adreno 750
 GMU
In-Reply-To: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
References: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
Message-ID: <20240216-topic-sm8650-gpu-v3-1-eb1f4b86d8d3@linaro.org>

Document the Adreno 750 GMU found on the SM8650 platform.

Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 Documentation/devicetree/bindings/display/msm/gmu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml b/Documentation/devicetree/bindings/display/msm/gmu.yaml
index 4e1c25b42908..b3837368a260 100644
--- a/Documentation/devicetree/bindings/display/msm/gmu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml
@@ -224,6 +224,7 @@ allOf:
             enum:
               - qcom,adreno-gmu-730.1
               - qcom,adreno-gmu-740.1
+              - qcom,adreno-gmu-750.1
     then:
       properties:
         reg:

-- 
2.34.1



From neil.armstrong at linaro.org  Fri Feb 16 03:03:49 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 16 Feb 2024 12:03:49 +0100
Subject: [PATCH v3 2/7] dt-bindings: arm-smmu: fix SM8[45]50 GPU SMMU if
 condition
In-Reply-To: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
References: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
Message-ID: <20240216-topic-sm8650-gpu-v3-2-eb1f4b86d8d3@linaro.org>

The if condition for the SM8[45]50 GPU SMMU is too large,
add the other compatible strings to the condition to only
allow the clocks for the GPU SMMU nodes.

Fixes: 4fff78dc2490 ("dt-bindings: arm-smmu: Document SM8[45]50 GPU SMMU")
Suggested-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index a4042ae24770..38c48131e6e7 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -484,7 +484,12 @@ allOf:
   - if:
       properties:
         compatible:
-          const: qcom,sm8450-smmu-500
+          items:
+            - const: qcom,sm8450-smmu-500
+            - const: qcom,adreno-smmu
+            - const: qcom,smmu-500
+            - const: arm,mmu-500
+
     then:
       properties:
         clock-names:
@@ -508,7 +513,11 @@ allOf:
   - if:
       properties:
         compatible:
-          const: qcom,sm8550-smmu-500
+          items:
+            - const: qcom,sm8550-smmu-500
+            - const: qcom,adreno-smmu
+            - const: qcom,smmu-500
+            - const: arm,mmu-500
     then:
       properties:
         clock-names:

-- 
2.34.1



From neil.armstrong at linaro.org  Fri Feb 16 03:03:50 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 16 Feb 2024 12:03:50 +0100
Subject: [PATCH v3 3/7] dt-bindings: arm-smmu: Document SM8650 GPU SMMU
In-Reply-To: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
References: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
Message-ID: <20240216-topic-sm8650-gpu-v3-3-eb1f4b86d8d3@linaro.org>

Document the GPU SMMU found on the SM8650 platform.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index 38c48131e6e7..740631782540 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -93,6 +93,7 @@ properties:
               - qcom,sm8350-smmu-500
               - qcom,sm8450-smmu-500
               - qcom,sm8550-smmu-500
+              - qcom,sm8650-smmu-500
           - const: qcom,adreno-smmu
           - const: qcom,smmu-500
           - const: arm,mmu-500
@@ -514,7 +515,9 @@ allOf:
       properties:
         compatible:
           items:
-            - const: qcom,sm8550-smmu-500
+            - enum:
+                - qcom,sm8550-smmu-500
+                - qcom,sm8650-smmu-500
             - const: qcom,adreno-smmu
             - const: qcom,smmu-500
             - const: arm,mmu-500
@@ -553,7 +556,6 @@ allOf:
               - qcom,sdx65-smmu-500
               - qcom,sm6350-smmu-500
               - qcom,sm6375-smmu-500
-              - qcom,sm8650-smmu-500
               - qcom,x1e80100-smmu-500
     then:
       properties:

-- 
2.34.1



From neil.armstrong at linaro.org  Fri Feb 16 03:03:51 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 16 Feb 2024 12:03:51 +0100
Subject: [PATCH v3 4/7] drm/msm/a6xx: Add missing regs for A750
In-Reply-To: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
References: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
Message-ID: <20240216-topic-sm8650-gpu-v3-4-eb1f4b86d8d3@linaro.org>

Sync missing regs for A750 clock gating control related registers
from Mesa a6xx.xml.h generated file.

Those registers were added in the !27576 merge request [1].

[1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27576

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/gpu/drm/msm/adreno/a6xx.xml.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
index 863b5e3b0e67..58877464692a 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
@@ -1725,6 +1725,8 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00
 
 #define REG_A6XX_RBBM_BLOCK_SW_RESET_CMD2			0x00000046
 
+#define REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL				0x000000ad
+
 #define REG_A6XX_RBBM_CLOCK_CNTL				0x000000ae
 
 #define REG_A6XX_RBBM_CLOCK_CNTL_SP0				0x000000b0
@@ -1939,12 +1941,19 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00
 
 #define REG_A6XX_RBBM_CLOCK_HYST_HLSQ				0x0000011d
 
+#define REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD			0x0000011e
+
+#define REG_A7XX_RBBM_CGC_P2S_TRIG_CMD				0x0000011f
+
 #define REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE			0x00000120
 
 #define REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE			0x00000121
 
 #define REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE			0x00000122
 
+#define REG_A7XX_RBBM_CGC_P2S_STATUS				0x00000122
+#define A7XX_RBBM_CGC_P2S_STATUS_TXDONE				0x00000001
+
 #define REG_A7XX_RBBM_CLOCK_HYST2_VFD				0x0000012f
 
 #define REG_A6XX_RBBM_LPAC_GBIF_CLIENT_QOS_CNTL			0x000005ff

-- 
2.34.1



From neil.armstrong at linaro.org  Fri Feb 16 03:03:52 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 16 Feb 2024 12:03:52 +0100
Subject: [PATCH v3 5/7] drm/msm: add support for A750 GPU
In-Reply-To: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
References: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
Message-ID: <20240216-topic-sm8650-gpu-v3-5-eb1f4b86d8d3@linaro.org>

Add support for the A750 GPU found on the SM8650 platform

Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
doesn't have an HWCFG block but a separate register set.

The A750 GPU info are added under the adreno_is_a750() macro and
the ADRENO_7XX_GEN3 family id.

Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>
Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c      |  2 ++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c      | 28 +++++++++++++++++++++++++---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++++++++++++++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h    | 10 ++++++++--
 4 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 8c4900444b2c..325881d8ff08 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -842,6 +842,8 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
 		 */
 		if (adreno_is_a740(adreno_gpu))
 			chipid_min = 2;
+		else if (adreno_is_a750(adreno_gpu))
+			chipid_min = 9;
 		else
 			return -EINVAL;
 
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c9c55e2ea584..475b601a48ee 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -961,7 +961,7 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 	unsigned int i;
 	u32 val, clock_cntl_on, cgc_mode;
 
-	if (!adreno_gpu->info->hwcg)
+	if (!(adreno_gpu->info->hwcg || adreno_is_a7xx(adreno_gpu)))
 		return;
 
 	if (adreno_is_a630(adreno_gpu))
@@ -982,6 +982,25 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 			  state ? 0x5555 : 0);
 	}
 
+	if (!adreno_gpu->info->hwcg) {
+		gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
+		gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
+
+		if (state) {
+			gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
+
+			if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
+					     val & A7XX_RBBM_CGC_P2S_STATUS_TXDONE, 1, 10)) {
+				dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
+				return;
+			}
+
+			gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
+		}
+
+		return;
+	}
+
 	val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
 
 	/* Don't re-program the registers if they are already correct */
@@ -1239,7 +1258,9 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu)
 		count = ARRAY_SIZE(a660_protect);
 		count_max = 48;
 		BUILD_BUG_ON(ARRAY_SIZE(a660_protect) > 48);
-	} else if (adreno_is_a730(adreno_gpu) || adreno_is_a740(adreno_gpu)) {
+	} else if (adreno_is_a730(adreno_gpu) ||
+		   adreno_is_a740(adreno_gpu) ||
+		   adreno_is_a750(adreno_gpu)) {
 		regs = a730_protect;
 		count = ARRAY_SIZE(a730_protect);
 		count_max = 48;
@@ -2880,7 +2901,8 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
 
 	/* gpu->info only gets assigned in adreno_gpu_init() */
 	is_a7xx = config->info->family == ADRENO_7XX_GEN1 ||
-		  config->info->family == ADRENO_7XX_GEN2;
+		  config->info->family == ADRENO_7XX_GEN2 ||
+		  config->info->family == ADRENO_7XX_GEN3;
 
 	a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 2ce7d7b1690d..e2582c91d7e7 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -522,6 +522,20 @@ static const struct adreno_info gpulist[] = {
 		.zapfw = "a740_zap.mdt",
 		.hwcg = a740_hwcg,
 		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */
+		.family = ADRENO_7XX_GEN3,
+		.fw = {
+			[ADRENO_FW_SQE] = "gen70900_sqe.fw",
+			[ADRENO_FW_GMU] = "gmu_gen70900.bin",
+		},
+		.gmem = 3 * SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "gen70900_zap.mbn",
+		.address_space_size = SZ_16G,
 	},
 };
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index bc14df96feb0..9e9415df2cea 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -48,6 +48,7 @@ enum adreno_family {
 	ADRENO_6XX_GEN4,  /* a660 family */
 	ADRENO_7XX_GEN1,  /* a730 family */
 	ADRENO_7XX_GEN2,  /* a740 family */
+	ADRENO_7XX_GEN3,  /* a750 family */
 };
 
 #define ADRENO_QUIRK_TWO_PASS_USE_WFI		BIT(0)
@@ -423,12 +424,17 @@ static inline int adreno_is_a740(struct adreno_gpu *gpu)
 	return gpu->info->chip_ids[0] == 0x43050a01;
 }
 
-/* Placeholder to make future diffs smaller */
+static inline int adreno_is_a750(struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x43051401;
+}
+
 static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
 {
 	if (WARN_ON_ONCE(!gpu->info))
 		return false;
-	return gpu->info->family == ADRENO_7XX_GEN2;
+	return gpu->info->family == ADRENO_7XX_GEN2 ||
+	       gpu->info->family == ADRENO_7XX_GEN3;
 }
 
 static inline int adreno_is_a7xx(struct adreno_gpu *gpu)

-- 
2.34.1



From neil.armstrong at linaro.org  Fri Feb 16 03:03:53 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 16 Feb 2024 12:03:53 +0100
Subject: [PATCH v3 6/7] arm64: dts: qcom: sm8650: add GPU nodes
In-Reply-To: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
References: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
Message-ID: <20240216-topic-sm8650-gpu-v3-6-eb1f4b86d8d3@linaro.org>

Add GPU nodes for the SM8650 platform.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/boot/dts/qcom/sm8650.dtsi | 166 +++++++++++++++++++++++++++++++++++
 1 file changed, 166 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
index 62e6ae93a9a8..27dcef27b6ad 100644
--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -2589,6 +2589,128 @@ tcsr: clock-controller at 1fc0000 {
 			#reset-cells = <1>;
 		};
 
+		gpu: gpu at 3d00000 {
+			compatible = "qcom,adreno-43051401", "qcom,adreno";
+			reg = <0x0 0x03d00000 0x0 0x40000>,
+			      <0x0 0x03d9e000 0x0 0x1000>,
+			      <0x0 0x03d61000 0x0 0x800>;
+			reg-names = "kgsl_3d0_reg_memory",
+				    "cx_mem",
+				    "cx_dbgc";
+
+			interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+
+			iommus = <&adreno_smmu 0 0x0>,
+				 <&adreno_smmu 1 0x0>;
+
+			operating-points-v2 = <&gpu_opp_table>;
+
+			qcom,gmu = <&gmu>;
+
+			status = "disabled";
+
+			zap-shader {
+				memory-region = <&gpu_micro_code_mem>;
+			};
+
+			/* Speedbin needs more work on A740+, keep only lower freqs */
+			gpu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-680000000 {
+					opp-hz = /bits/ 64 <680000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+				};
+
+				opp-629000000 {
+					opp-hz = /bits/ 64 <629000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+				};
+
+				opp-578000000 {
+					opp-hz = /bits/ 64 <578000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+				};
+
+				opp-500000000 {
+					opp-hz = /bits/ 64 <500000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+				};
+
+				opp-422000000 {
+					opp-hz = /bits/ 64 <422000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+				};
+
+				opp-366000000 {
+					opp-hz = /bits/ 64 <366000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+				};
+
+				opp-310000000 {
+					opp-hz = /bits/ 64 <310000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+				};
+
+				opp-231000000 {
+					opp-hz = /bits/ 64 <231000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+				};
+			};
+		};
+
+		gmu: gmu at 3d6a000 {
+			compatible = "qcom,adreno-gmu-750.1", "qcom,adreno-gmu";
+			reg = <0x0 0x03d6a000 0x0 0x35000>,
+			      <0x0 0x03d50000 0x0 0x10000>,
+			      <0x0 0x0b280000 0x0 0x10000>;
+			reg-names = "gmu", "rscc", "gmu_pdc";
+
+			interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hfi", "gmu";
+
+			clocks = <&gpucc GPU_CC_AHB_CLK>,
+				 <&gpucc GPU_CC_CX_GMU_CLK>,
+				 <&gpucc GPU_CC_CXO_CLK>,
+				 <&gcc GCC_DDRSS_GPU_AXI_CLK>,
+				 <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gpucc GPU_CC_HUB_CX_INT_CLK>,
+				 <&gpucc GPU_CC_DEMET_CLK>;
+			clock-names = "ahb",
+				      "gmu",
+				      "cxo",
+				      "axi",
+				      "memnoc",
+				      "hub",
+				      "demet";
+
+			power-domains = <&gpucc GPU_CX_GDSC>,
+					<&gpucc GPU_GX_GDSC>;
+			power-domain-names = "cx",
+					     "gx";
+
+			iommus = <&adreno_smmu 5 0x0>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			operating-points-v2 = <&gmu_opp_table>;
+
+			gmu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-625000000 {
+					opp-hz = /bits/ 64 <625000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+				};
+
+				opp-260000000 {
+					opp-hz = /bits/ 64 <260000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+				};
+			};
+		};
+
 		gpucc: clock-controller at 3d90000 {
 			compatible = "qcom,sm8650-gpucc";
 			reg = <0 0x03d90000 0 0xa000>;
@@ -2602,6 +2724,50 @@ gpucc: clock-controller at 3d90000 {
 			#power-domain-cells = <1>;
 		};
 
+		adreno_smmu: iommu at 3da0000 {
+			compatible = "qcom,sm8650-smmu-500", "qcom,adreno-smmu",
+				     "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x03da0000 0x0 0x40000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <1>;
+			interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 659 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 661 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 664 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 668 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 699 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+				 <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+				 <&gpucc GPU_CC_AHB_CLK>;
+			clock-names = "hlos",
+				      "bus",
+				      "iface",
+				      "ahb";
+			power-domains = <&gpucc GPU_CX_GDSC>;
+			dma-coherent;
+		};
+
 		ipa: ipa at 3f40000 {
 			compatible = "qcom,sm8650-ipa", "qcom,sm8550-ipa";
 

-- 
2.34.1



From neil.armstrong at linaro.org  Fri Feb 16 03:03:54 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 16 Feb 2024 12:03:54 +0100
Subject: [PATCH v3 7/7] arm64: dts: qcom: sm8650-qrd: enable GPU
In-Reply-To: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
References: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
Message-ID: <20240216-topic-sm8650-gpu-v3-7-eb1f4b86d8d3@linaro.org>

Add path of the GPU firmware for the SM8650-QRD board

Reviewed-by: Konrad Dybcio <konrad.dybcio at linaro.org>
Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
index b07cac2e5bc8..dc91f0bf4b8c 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
@@ -766,6 +766,14 @@ &ipa {
 	status = "okay";
 };
 
+&gpu {
+	status = "okay";
+
+	zap-shader {
+		firmware-name = "qcom/sm8650/gen70900_zap.mbn";
+	};
+};
+
 &lpass_tlmm {
 	spkr_1_sd_n_active: spkr-1-sd-n-active-state {
 		pins = "gpio21";

-- 
2.34.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb 16 03:05:29 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 16 Feb 2024 14:05:29 +0300
Subject: [PATCH net-next v2 1/8] net: dsa: mt7530: remove .mac_port_config
 for MT7988 and make it optional
In-Reply-To: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
References: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
Message-ID: <20240216-for-netnext-mt7530-improvements-3-v2-1-094cae3ff23b@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

For the switch on the MT7988 SoC, the mac_port_config member for ID_MT7988
in mt753x_table is not needed as the interfaces of all MACs are already
handled on mt7988_mac_port_get_caps().

Therefore, remove the mac_port_config member from ID_MT7988 in
mt753x_table. Before calling priv->info->mac_port_config(), if there's no
mac_port_config member in mt753x_table, exit mt753x_mac_config()
successfully.

Remove calling priv->info->mac_port_config() from the sanity check as the
sanity check requires a pointer to a mac_port_config function to be
non-NULL. This will fail for MT7988 as mac_port_config won't be a member of
its info table.

Co-developed-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
---
 drivers/net/dsa/mt7530.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 03d966fa67b2..94d4b2c87799 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2655,17 +2655,6 @@ static bool mt753x_is_mac_port(u32 port)
 	return (port == 5 || port == 6);
 }
 
-static int
-mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-		  phy_interface_t interface)
-{
-	if (dsa_is_cpu_port(ds, port) &&
-	    interface == PHY_INTERFACE_MODE_INTERNAL)
-		return 0;
-
-	return -EINVAL;
-}
-
 static int
 mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
@@ -2706,6 +2695,9 @@ mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 {
 	struct mt7530_priv *priv = ds->priv;
 
+	if (!priv->info->mac_port_config)
+		return 0;
+
 	return priv->info->mac_port_config(ds, port, mode, state->interface);
 }
 
@@ -3169,7 +3161,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
 		.cpu_port_config = mt7988_cpu_port_config,
 		.mac_port_get_caps = mt7988_mac_port_get_caps,
-		.mac_port_config = mt7988_mac_config,
 	},
 };
 EXPORT_SYMBOL_GPL(mt753x_table);
@@ -3197,8 +3188,7 @@ mt7530_probe_common(struct mt7530_priv *priv)
 	 * properly.
 	 */
 	if (!priv->info->sw_setup || !priv->info->phy_read_c22 ||
-	    !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps ||
-	    !priv->info->mac_port_config)
+	    !priv->info->phy_write_c22 || !priv->info->mac_port_get_caps)
 		return -EINVAL;
 
 	priv->id = priv->info->id;

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb 16 03:05:28 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 16 Feb 2024 14:05:28 +0300
Subject: [PATCH net-next v2 0/8] MT7530 DSA Subdriver Improvements Act III
Message-ID: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>

Hello!

This is the third patch series with the goal of simplifying the MT7530 DSA
subdriver and improving support for MT7530, MT7531, and the switch on the
MT7988 SoC.

I have done a simple ping test to confirm basic communication on all switch
ports on MCM and standalone MT7530, and MT7531 switch with this patch
series applied.

MT7621 Unielec, MCM MT7530:

rgmii-only-gmac0-mt7621-unielec-u7621-06-16m.dtb
gmac0-and-gmac1-mt7621-unielec-u7621-06-16m.dtb

tftpboot 0x80008000 mips-uzImage.bin; tftpboot 0x83000000 mips-rootfs.cpio.uboot; tftpboot 0x83f00000 $dtb; bootm 0x80008000 0x83000000 0x83f00000

MT7622 Bananapi, MT7531:

gmac0-and-gmac1-mt7622-bananapi-bpi-r64.dtb

tftpboot 0x40000000 arm64-Image; tftpboot 0x45000000 arm64-rootfs.cpio.uboot; tftpboot 0x4a000000 $dtb; booti 0x40000000 0x45000000 0x4a000000

MT7623 Bananapi, standalone MT7530:

rgmii-only-gmac0-mt7623n-bananapi-bpi-r2.dtb
gmac0-and-gmac1-mt7623n-bananapi-bpi-r2.dtb

tftpboot 0x80008000 arm-zImage; tftpboot 0x83000000 arm-rootfs.cpio.uboot; tftpboot 0x83f00000 $dtb; bootz 0x80008000 0x83000000 0x83f00000

This patch series is the continuation of the patch series linked below.

https://lore.kernel.org/r/20230522121532.86610-1-arinc.unal at arinc9.com

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
Changes in v2:
- Patch 8
  - Use a single mt7530_rmw() instead of two mt7530_clear() and
    mt7530_set() commands.
- Link to v1: https://lore.kernel.org/r/20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca at arinc9.com

---
Ar?n? ?NAL (8):
      net: dsa: mt7530: remove .mac_port_config for MT7988 and make it optional
      net: dsa: mt7530: set interrupt register only for MT7530
      net: dsa: mt7530: do not use SW_PHY_RST to reset MT7531 switch
      net: dsa: mt7530: get rid of useless error returns on phylink code path
      net: dsa: mt7530: get rid of priv->info->cpu_port_config()
      net: dsa: mt7530: get rid of mt753x_mac_config()
      net: dsa: mt7530: put initialising PCS devices code back to original order
      net: dsa: mt7530: simplify link operations and force link down on all ports

 drivers/net/dsa/mt7530.c | 259 ++++++++---------------------------------------
 drivers/net/dsa/mt7530.h |  19 +---
 2 files changed, 47 insertions(+), 231 deletions(-)
---
base-commit: b6b614558ed5b2ca50edacc0f2fbf5f52158c86c
change-id: 20240131-for-netnext-mt7530-improvements-3-a8ac49d4f7c2

Best regards,
-- 
Ar?n? ?NAL <arinc.unal at arinc9.com>



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb 16 03:05:33 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 16 Feb 2024 14:05:33 +0300
Subject: [PATCH net-next v2 5/8] net: dsa: mt7530: get rid of
 priv->info->cpu_port_config()
In-Reply-To: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
References: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
Message-ID: <20240216-for-netnext-mt7530-improvements-3-v2-5-094cae3ff23b@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

priv->info->cpu_port_config() is used for MT7531 and the switch on the
MT7988 SoC. It sets up the ports described as a CPU port earlier than the
phylink code path would do.

This function is useless as:
- Configuring the MACs can be done from the phylink_mac_config code path
  instead.
- All the link configuration it does on the CPU ports are later undone with
  the port_enable, phylink_mac_config, and then phylink_mac_link_up code
  path [1].

priv->p5_interface and priv->p6_interface were being used to prevent
configuring the MACs from the phylink_mac_config code path. Remove them now
that they hold no purpose.

Remove priv->info->cpu_port_config(). On mt753x_phylink_mac_config, switch
to if statements to simplify the code.

Remove the overwriting of the speed and duplex interfaces for certain
interface modes. Phylink already provides the speed and duplex variables
with proper values. Phylink already sets the max speed of TRGMII to
SPEED_1000. Add SPEED_2500 for PHY_INTERFACE_MODE_2500BASEX to where the
speed and EEE bits are set instead.

On the switch on the MT7988 SoC, PHY_INTERFACE_MODE_INTERNAL is being used
to describe the interface mode of the 10G MAC, which is of port 6. On
mt7988_cpu_port_config() PMCR_FORCE_SPEED_1000 was set via the
PMCR_CPU_PORT_SETTING() mask. Add SPEED_10000 case to where the speed bits
are set to cover this. No need to add it to where the EEE bits are set as
the "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version)
v0.1" document shows that these bits don't exist on the MT7530_PMCR_P(6)
register.

Remove the definition of PMCR_CPU_PORT_SETTING() now that it holds no
purpose.

Change mt753x_cpu_port_enable() to void now that there're no error cases
left.

Link: https://lore.kernel.org/netdev/ZHy2jQLesdYFMQtO at shell.armlinux.org.uk/ [1]
Suggested-by: Russell King (Oracle) <linux at armlinux.org.uk>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 114 +++--------------------------------------------
 drivers/net/dsa/mt7530.h |  11 -----
 2 files changed, 7 insertions(+), 118 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index c069bf273733..80b65f064310 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -966,18 +966,10 @@ mt753x_trap_frames(struct mt7530_priv *priv)
 		   MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY));
 }
 
-static int
+static void
 mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
 {
 	struct mt7530_priv *priv = ds->priv;
-	int ret;
-
-	/* Setup max capability of CPU port at first */
-	if (priv->info->cpu_port_config) {
-		ret = priv->info->cpu_port_config(ds, port);
-		if (ret)
-			return ret;
-	}
 
 	/* Enable Mediatek header mode on the cpu port */
 	mt7530_write(priv, MT7530_PVC_P(port),
@@ -1003,8 +995,6 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
 	/* Set to fallback mode for independent VLAN learning */
 	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
 		   MT7530_PORT_FALLBACK_MODE);
-
-	return 0;
 }
 
 static int
@@ -2261,8 +2251,6 @@ mt7530_setup(struct dsa_switch *ds)
 	val |= MHWTRAP_MANUAL;
 	mt7530_write(priv, MT7530_MHWTRAP, val);
 
-	priv->p6_interface = PHY_INTERFACE_MODE_NA;
-
 	mt753x_trap_frames(priv);
 
 	/* Enable and reset MIB counters */
@@ -2277,9 +2265,7 @@ mt7530_setup(struct dsa_switch *ds)
 		mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
 
 		if (dsa_is_cpu_port(ds, i)) {
-			ret = mt753x_cpu_port_enable(ds, i);
-			if (ret)
-				return ret;
+			mt753x_cpu_port_enable(ds, i);
 		} else {
 			mt7530_port_disable(ds, i);
 
@@ -2383,9 +2369,7 @@ mt7531_setup_common(struct dsa_switch *ds)
 		mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
 
 		if (dsa_is_cpu_port(ds, i)) {
-			ret = mt753x_cpu_port_enable(ds, i);
-			if (ret)
-				return ret;
+			mt753x_cpu_port_enable(ds, i);
 		} else {
 			mt7530_port_disable(ds, i);
 
@@ -2474,10 +2458,6 @@ mt7531_setup(struct dsa_switch *ds)
 	mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
 		   MT7531_GPIO0_INTERRUPT);
 
-	/* Let phylink decide the interface later. */
-	priv->p5_interface = PHY_INTERFACE_MODE_NA;
-	priv->p6_interface = PHY_INTERFACE_MODE_NA;
-
 	/* Enable PHY core PLL, since phy_device has not yet been created
 	 * provided for phy_[read,write]_mmd_indirect is called, we provide
 	 * our own mt7531_ind_mmd_phy_[read,write] to complete this
@@ -2689,26 +2669,9 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 	struct mt7530_priv *priv = ds->priv;
 	u32 mcr_cur, mcr_new;
 
-	switch (port) {
-	case 5:
-		if (priv->p5_interface == state->interface)
-			break;
-
+	if (port == 5 || port == 6)
 		mt753x_mac_config(ds, port, mode, state);
 
-		if (priv->p5_intf_sel != P5_DISABLED)
-			priv->p5_interface = state->interface;
-		break;
-	case 6:
-		if (priv->p6_interface == state->interface)
-			break;
-
-		mt753x_mac_config(ds, port, mode, state);
-
-		priv->p6_interface = state->interface;
-		break;
-	}
-
 	mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
 	mcr_new = mcr_cur;
 	mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
@@ -2744,17 +2707,10 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
 
 	mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
 
-	/* MT753x MAC works in 1G full duplex mode for all up-clocked
-	 * variants.
-	 */
-	if (interface == PHY_INTERFACE_MODE_TRGMII ||
-	    (phy_interface_mode_is_8023z(interface))) {
-		speed = SPEED_1000;
-		duplex = DUPLEX_FULL;
-	}
-
 	switch (speed) {
 	case SPEED_1000:
+	case SPEED_2500:
+	case SPEED_10000:
 		mcr |= PMCR_FORCE_SPEED_1000;
 		break;
 	case SPEED_100:
@@ -2772,6 +2728,7 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
 	if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) {
 		switch (speed) {
 		case SPEED_1000:
+		case SPEED_2500:
 			mcr |= PMCR_FORCE_EEE1G;
 			break;
 		case SPEED_100:
@@ -2783,61 +2740,6 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
 	mt7530_set(priv, MT7530_PMCR_P(port), mcr);
 }
 
-static int
-mt7531_cpu_port_config(struct dsa_switch *ds, int port)
-{
-	struct mt7530_priv *priv = ds->priv;
-	phy_interface_t interface;
-	int speed;
-
-	switch (port) {
-	case 5:
-		if (!priv->p5_sgmii)
-			interface = PHY_INTERFACE_MODE_RGMII;
-		else
-			interface = PHY_INTERFACE_MODE_2500BASEX;
-
-		priv->p5_interface = interface;
-		break;
-	case 6:
-		interface = PHY_INTERFACE_MODE_2500BASEX;
-
-		priv->p6_interface = interface;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (interface == PHY_INTERFACE_MODE_2500BASEX)
-		speed = SPEED_2500;
-	else
-		speed = SPEED_1000;
-
-	mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
-
-	mt7530_write(priv, MT7530_PMCR_P(port),
-		     PMCR_CPU_PORT_SETTING(priv->id));
-	mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
-				   speed, DUPLEX_FULL, true, true);
-
-	return 0;
-}
-
-static int
-mt7988_cpu_port_config(struct dsa_switch *ds, int port)
-{
-	struct mt7530_priv *priv = ds->priv;
-
-	mt7530_write(priv, MT7530_PMCR_P(port),
-		     PMCR_CPU_PORT_SETTING(priv->id));
-
-	mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED,
-				   PHY_INTERFACE_MODE_INTERNAL, NULL,
-				   SPEED_10000, DUPLEX_FULL, true, true);
-
-	return 0;
-}
-
 static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
 				    struct phylink_config *config)
 {
@@ -3096,7 +2998,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7531_ind_c22_phy_write,
 		.phy_read_c45 = mt7531_ind_c45_phy_read,
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
-		.cpu_port_config = mt7531_cpu_port_config,
 		.mac_port_get_caps = mt7531_mac_port_get_caps,
 		.mac_port_config = mt7531_mac_config,
 	},
@@ -3108,7 +3009,6 @@ const struct mt753x_info mt753x_table[] = {
 		.phy_write_c22 = mt7531_ind_c22_phy_write,
 		.phy_read_c45 = mt7531_ind_c45_phy_read,
 		.phy_write_c45 = mt7531_ind_c45_phy_write,
-		.cpu_port_config = mt7988_cpu_port_config,
 		.mac_port_get_caps = mt7988_mac_port_get_caps,
 	},
 };
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index b1665de7f640..8a8144868eaa 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -311,13 +311,6 @@ enum mt7530_vlan_port_acc_frm {
 					 PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
 					 PMCR_FORCE_FDX | PMCR_FORCE_LNK | \
 					 PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100)
-#define  PMCR_CPU_PORT_SETTING(id)	(PMCR_FORCE_MODE_ID((id)) | \
-					 PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
-					 PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \
-					 PMCR_TX_EN | PMCR_RX_EN | \
-					 PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
-					 PMCR_FORCE_SPEED_1000 | \
-					 PMCR_FORCE_FDX | PMCR_FORCE_LNK)
 
 #define MT7530_PMEEECR_P(x)		(0x3004 + (x) * 0x100)
 #define  WAKEUP_TIME_1000(x)		(((x) & 0xFF) << 24)
@@ -724,7 +717,6 @@ struct mt753x_info {
 			    int regnum);
 	int (*phy_write_c45)(struct mt7530_priv *priv, int port, int devad,
 			     int regnum, u16 val);
-	int (*cpu_port_config)(struct dsa_switch *ds, int port);
 	void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
 				  struct phylink_config *config);
 	void (*mac_port_validate)(struct dsa_switch *ds, int port,
@@ -750,7 +742,6 @@ struct mt753x_info {
  * @ports:		Holding the state among ports
  * @reg_mutex:		The lock for protecting among process accessing
  *			registers
- * @p6_interface	Holding the current port 6 interface
  * @p5_intf_sel:	Holding the current port 5 interface select
  * @p5_sgmii:		Flag for distinguishing if port 5 of the MT7531 switch
  *			has got SGMII
@@ -772,8 +763,6 @@ struct mt7530_priv {
 	const struct mt753x_info *info;
 	unsigned int		id;
 	bool			mcm;
-	phy_interface_t		p6_interface;
-	phy_interface_t		p5_interface;
 	enum p5_interface_select p5_intf_sel;
 	bool			p5_sgmii;
 	u8			mirror_rx;

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb 16 03:05:35 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 16 Feb 2024 14:05:35 +0300
Subject: [PATCH net-next v2 7/8] net: dsa: mt7530: put initialising PCS
 devices code back to original order
In-Reply-To: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
References: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
Message-ID: <20240216-for-netnext-mt7530-improvements-3-v2-7-094cae3ff23b@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

The commit fae463084032 ("net: dsa: mt753x: fix pcs conversion regression")
fixes regression caused by cpu_port_config manually calling phylink
operations. cpu_port_config was deemed useless and was removed. Therefore,
put initialising PCS devices code back to its original order.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index e353c03dd1db..5c8ad41ce8cd 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2812,17 +2812,9 @@ static int
 mt753x_setup(struct dsa_switch *ds)
 {
 	struct mt7530_priv *priv = ds->priv;
-	int i, ret;
-
-	/* Initialise the PCS devices */
-	for (i = 0; i < priv->ds->num_ports; i++) {
-		priv->pcs[i].pcs.ops = priv->info->pcs_ops;
-		priv->pcs[i].pcs.neg_mode = true;
-		priv->pcs[i].priv = priv;
-		priv->pcs[i].port = i;
-	}
+	int ret = priv->info->sw_setup(ds);
+	int i;
 
-	ret = priv->info->sw_setup(ds);
 	if (ret)
 		return ret;
 
@@ -2834,6 +2826,14 @@ mt753x_setup(struct dsa_switch *ds)
 	if (ret && priv->irq)
 		mt7530_free_irq_common(priv);
 
+	/* Initialise the PCS devices */
+	for (i = 0; i < priv->ds->num_ports; i++) {
+		priv->pcs[i].pcs.ops = priv->info->pcs_ops;
+		priv->pcs[i].pcs.neg_mode = true;
+		priv->pcs[i].priv = priv;
+		priv->pcs[i].port = i;
+	}
+
 	if (priv->create_sgmii) {
 		ret = priv->create_sgmii(priv);
 		if (ret && priv->irq)

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb 16 03:05:36 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 16 Feb 2024 14:05:36 +0300
Subject: [PATCH net-next v2 8/8] net: dsa: mt7530: simplify link operations
 and force link down on all ports
In-Reply-To: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
References: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
Message-ID: <20240216-for-netnext-mt7530-improvements-3-v2-8-094cae3ff23b@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

Currently, the link operations for switch MACs are scattered across
port_enable, port_disable, phylink_mac_config, phylink_mac_link_up, and
phylink_mac_link_down.

port_enable and port_disable clears the link settings. Move that to
mt7530_setup() and mt7531_setup_common() which set up the switches. This
way, the link settings are cleared on all ports at setup, and then only
once with phylink_mac_link_down() when a link goes down.

Enable force mode at setup to apply the force part of the link settings.
This ensures that only active ports will have their link up.

Now that the bit for setting the port on force mode is done on
mt7530_setup() and mt7531_setup_common(), get rid of PMCR_FORCE_MODE_ID()
which helped determine which bit to use for the switch model.

The "MT7621 Giga Switch Programming Guide v0.3", "MT7531 Reference Manual
for Development Board v1.0", and "MT7988A Wi-Fi 7 Generation Router
Platform: Datasheet (Open Version) v0.1" documents show that these bits are
enabled at reset:

PMCR_IFG_XMIT(1) (not part of PMCR_LINK_SETTINGS_MASK)
PMCR_MAC_MODE (not part of PMCR_LINK_SETTINGS_MASK)
PMCR_TX_EN
PMCR_RX_EN
PMCR_BACKOFF_EN (not part of PMCR_LINK_SETTINGS_MASK)
PMCR_BACKPR_EN (not part of PMCR_LINK_SETTINGS_MASK)
PMCR_TX_FC_EN
PMCR_RX_FC_EN

These bits also don't exist on the MT7530_PMCR_P(6) register of the switch
on the MT7988 SoC:

PMCR_IFG_XMIT()
PMCR_MAC_MODE
PMCR_BACKOFF_EN
PMCR_BACKPR_EN

Remove the setting of the bits not part of PMCR_LINK_SETTINGS_MASK on
phylink_mac_config as they're already set.

Suggested-by: Vladimir Oltean <olteanv at gmail.com>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 26 +++++++++++++-------------
 drivers/net/dsa/mt7530.h |  2 --
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 5c8ad41ce8cd..1ae11b180d54 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1018,7 +1018,6 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
 	priv->ports[port].enable = true;
 	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
 		   priv->ports[port].pm);
-	mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
 
 	mutex_unlock(&priv->reg_mutex);
 
@@ -1038,7 +1037,6 @@ mt7530_port_disable(struct dsa_switch *ds, int port)
 	priv->ports[port].enable = false;
 	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
 		   PCR_MATRIX_CLR);
-	mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
 
 	mutex_unlock(&priv->reg_mutex);
 }
@@ -2257,6 +2255,12 @@ mt7530_setup(struct dsa_switch *ds)
 	mt7530_mib_reset(ds);
 
 	for (i = 0; i < MT7530_NUM_PORTS; i++) {
+		/* Clear link settings and enable force mode to force link down
+		 * on all ports until they're enabled later.
+		 */
+		mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
+			   PMCR_FORCE_MODE, PMCR_FORCE_MODE);
+
 		/* Disable forwarding by default on all ports */
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
@@ -2359,6 +2363,12 @@ mt7531_setup_common(struct dsa_switch *ds)
 		     UNU_FFP_MASK);
 
 	for (i = 0; i < MT7530_NUM_PORTS; i++) {
+		/* Clear link settings and enable force mode to force link down
+		 * on all ports until they're enabled later.
+		 */
+		mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK |
+			   MT7531_FORCE_MODE, MT7531_FORCE_MODE);
+
 		/* Disable forwarding by default on all ports */
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
@@ -2657,23 +2667,13 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 			  const struct phylink_link_state *state)
 {
 	struct mt7530_priv *priv = ds->priv;
-	u32 mcr_cur, mcr_new;
 
 	if ((port == 5 || port == 6) && priv->info->mac_port_config)
 		priv->info->mac_port_config(ds, port, mode, state->interface);
 
-	mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
-	mcr_new = mcr_cur;
-	mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
-	mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
-		   PMCR_BACKPR_EN | PMCR_FORCE_MODE_ID(priv->id);
-
 	/* Are we connected to external phy */
 	if (port == 5 && dsa_is_user_port(ds, 5))
-		mcr_new |= PMCR_EXT_PHY;
-
-	if (mcr_new != mcr_cur)
-		mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
+		mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
 }
 
 static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 8a8144868eaa..a71166e0a7fc 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -304,8 +304,6 @@ enum mt7530_vlan_port_acc_frm {
 					 MT7531_FORCE_DPX | \
 					 MT7531_FORCE_RX_FC | \
 					 MT7531_FORCE_TX_FC)
-#define  PMCR_FORCE_MODE_ID(id)		((((id) == ID_MT7531) || ((id) == ID_MT7988)) ?	\
-					 MT7531_FORCE_MODE : PMCR_FORCE_MODE)
 #define  PMCR_LINK_SETTINGS_MASK	(PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
 					 PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
 					 PMCR_TX_FC_EN | PMCR_RX_FC_EN | \

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb 16 03:05:30 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 16 Feb 2024 14:05:30 +0300
Subject: [PATCH net-next v2 2/8] net: dsa: mt7530: set interrupt register
 only for MT7530
In-Reply-To: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
References: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
Message-ID: <20240216-for-netnext-mt7530-improvements-3-v2-2-094cae3ff23b@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

Setting this register related to interrupts is only needed for the MT7530
switch. Make an exclusive check to ensure this.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Acked-by: Daniel Golle <daniel at makrotopia.org>
Tested-by: Daniel Golle <daniel at makrotopia.org>
---
 drivers/net/dsa/mt7530.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 94d4b2c87799..5cfd303b773f 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2055,7 +2055,7 @@ mt7530_setup_irq(struct mt7530_priv *priv)
 	}
 
 	/* This register must be set for MT7530 to properly fire interrupts */
-	if (priv->id != ID_MT7531)
+	if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
 		mt7530_set(priv, MT7530_TOP_SIG_CTRL, TOP_SIG_CTRL_NORMAL);
 
 	ret = request_threaded_irq(priv->irq, NULL, mt7530_irq_thread_fn,

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb 16 03:05:31 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 16 Feb 2024 14:05:31 +0300
Subject: [PATCH net-next v2 3/8] net: dsa: mt7530: do not use SW_PHY_RST to
 reset MT7531 switch
In-Reply-To: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
References: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
Message-ID: <20240216-for-netnext-mt7530-improvements-3-v2-3-094cae3ff23b@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

According to the document MT7531 Reference Manual for Development Board
v1.0, the SW_PHY_RST bit on the SYS_CTRL register doesn't exist for
MT7531. This is likely why forcing link down on all ports is necessary for
MT7531.

Therefore, do not set SW_PHY_RST on mt7531_setup().

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 5cfd303b773f..296711fd5c43 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2451,14 +2451,12 @@ mt7531_setup(struct dsa_switch *ds)
 	val = mt7530_read(priv, MT7531_TOP_SIG_SR);
 	priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
 
-	/* all MACs must be forced link-down before sw reset */
+	/* Force link down on all ports before internal reset */
 	for (i = 0; i < MT7530_NUM_PORTS; i++)
 		mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK);
 
 	/* Reset the switch through internal reset */
-	mt7530_write(priv, MT7530_SYS_CTRL,
-		     SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
-		     SYS_CTRL_REG_RST);
+	mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
 
 	if (!priv->p5_sgmii) {
 		mt7531_pll_setup(priv);

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb 16 03:05:34 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 16 Feb 2024 14:05:34 +0300
Subject: [PATCH net-next v2 6/8] net: dsa: mt7530: get rid of
 mt753x_mac_config()
In-Reply-To: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
References: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
Message-ID: <20240216-for-netnext-mt7530-improvements-3-v2-6-094cae3ff23b@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

There is no need for a separate function to call
priv->info->mac_port_config(). Call it from mt753x_phylink_mac_config()
instead and remove mt753x_mac_config().

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 80b65f064310..e353c03dd1db 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2634,16 +2634,6 @@ mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 	}
 }
 
-static void
-mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
-		  const struct phylink_link_state *state)
-{
-	struct mt7530_priv *priv = ds->priv;
-
-	if (priv->info->mac_port_config)
-		priv->info->mac_port_config(ds, port, mode, state->interface);
-}
-
 static struct phylink_pcs *
 mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
 			      phy_interface_t interface)
@@ -2669,8 +2659,8 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 	struct mt7530_priv *priv = ds->priv;
 	u32 mcr_cur, mcr_new;
 
-	if (port == 5 || port == 6)
-		mt753x_mac_config(ds, port, mode, state);
+	if ((port == 5 || port == 6) && priv->info->mac_port_config)
+		priv->info->mac_port_config(ds, port, mode, state->interface);
 
 	mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
 	mcr_new = mcr_cur;

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Fri Feb 16 03:05:32 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Fri, 16 Feb 2024 14:05:32 +0300
Subject: [PATCH net-next v2 4/8] net: dsa: mt7530: get rid of useless error
 returns on phylink code path
In-Reply-To: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
References: <20240216-for-netnext-mt7530-improvements-3-v2-0-094cae3ff23b@arinc9.com>
Message-ID: <20240216-for-netnext-mt7530-improvements-3-v2-4-094cae3ff23b@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

Remove error returns on the cases where they are already handled with the
function the mac_port_get_caps member in mt753x_table points to.

mt7531_mac_config() is also called from mt7531_cpu_port_config() outside of
phylink but the port and interface modes are already handled there.

Change the functions and the mac_port_config function pointer to void now
that there're no error returns anymore.

Remove mt753x_is_mac_port() that used to help the said error returns.

On mt7531_mac_config(), switch to if statements to simplify the code.

Remove internal phy cases from mt753x_phylink_mac_config(), there is no
need to check the interface mode as that's already handled with the
function the mac_port_get_caps member in mt753x_table points to.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Acked-by: Daniel Golle <daniel at makrotopia.org>
Tested-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 drivers/net/dsa/mt7530.c | 81 ++++++++++--------------------------------------
 drivers/net/dsa/mt7530.h |  6 ++--
 2 files changed, 19 insertions(+), 68 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 296711fd5c43..c069bf273733 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2587,7 +2587,7 @@ static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
 	}
 }
 
-static int
+static void
 mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
 {
@@ -2597,22 +2597,14 @@ mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		mt7530_setup_port5(priv->ds, interface);
 	else if (port == 6)
 		mt7530_setup_port6(priv->ds, interface);
-
-	return 0;
 }
 
-static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
-			      phy_interface_t interface,
-			      struct phy_device *phydev)
+static void mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
+			       phy_interface_t interface,
+			       struct phy_device *phydev)
 {
 	u32 val;
 
-	if (priv->p5_sgmii) {
-		dev_err(priv->dev, "RGMII mode is not available for port %d\n",
-			port);
-		return -EINVAL;
-	}
-
 	val = mt7530_read(priv, MT7531_CLKGEN_CTRL);
 	val |= GP_CLK_EN;
 	val &= ~GP_MODE_MASK;
@@ -2640,20 +2632,14 @@ static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
 		case PHY_INTERFACE_MODE_RGMII_ID:
 			break;
 		default:
-			return -EINVAL;
+			break;
 		}
 	}
-	mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
-
-	return 0;
-}
 
-static bool mt753x_is_mac_port(u32 port)
-{
-	return (port == 5 || port == 6);
+	mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
 }
 
-static int
+static void
 mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  phy_interface_t interface)
 {
@@ -2661,42 +2647,21 @@ mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 	struct phy_device *phydev;
 	struct dsa_port *dp;
 
-	if (!mt753x_is_mac_port(port)) {
-		dev_err(priv->dev, "port %d is not a MAC port\n", port);
-		return -EINVAL;
-	}
-
-	switch (interface) {
-	case PHY_INTERFACE_MODE_RGMII:
-	case PHY_INTERFACE_MODE_RGMII_ID:
-	case PHY_INTERFACE_MODE_RGMII_RXID:
-	case PHY_INTERFACE_MODE_RGMII_TXID:
+	if (phy_interface_mode_is_rgmii(interface)) {
 		dp = dsa_to_port(ds, port);
 		phydev = dp->user->phydev;
-		return mt7531_rgmii_setup(priv, port, interface, phydev);
-	case PHY_INTERFACE_MODE_SGMII:
-	case PHY_INTERFACE_MODE_NA:
-	case PHY_INTERFACE_MODE_1000BASEX:
-	case PHY_INTERFACE_MODE_2500BASEX:
-		/* handled in SGMII PCS driver */
-		return 0;
-	default:
-		return -EINVAL;
+		mt7531_rgmii_setup(priv, port, interface, phydev);
 	}
-
-	return -EINVAL;
 }
 
-static int
+static void
 mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		  const struct phylink_link_state *state)
 {
 	struct mt7530_priv *priv = ds->priv;
 
-	if (!priv->info->mac_port_config)
-		return 0;
-
-	return priv->info->mac_port_config(ds, port, mode, state->interface);
+	if (priv->info->mac_port_config)
+		priv->info->mac_port_config(ds, port, mode, state->interface);
 }
 
 static struct phylink_pcs *
@@ -2725,17 +2690,11 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 	u32 mcr_cur, mcr_new;
 
 	switch (port) {
-	case 0 ... 4:
-		if (state->interface != PHY_INTERFACE_MODE_GMII &&
-		    state->interface != PHY_INTERFACE_MODE_INTERNAL)
-			goto unsupported;
-		break;
 	case 5:
 		if (priv->p5_interface == state->interface)
 			break;
 
-		if (mt753x_mac_config(ds, port, mode, state) < 0)
-			goto unsupported;
+		mt753x_mac_config(ds, port, mode, state);
 
 		if (priv->p5_intf_sel != P5_DISABLED)
 			priv->p5_interface = state->interface;
@@ -2744,16 +2703,10 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
 		if (priv->p6_interface == state->interface)
 			break;
 
-		if (mt753x_mac_config(ds, port, mode, state) < 0)
-			goto unsupported;
+		mt753x_mac_config(ds, port, mode, state);
 
 		priv->p6_interface = state->interface;
 		break;
-	default:
-unsupported:
-		dev_err(ds->dev, "%s: unsupported %s port: %i\n",
-			__func__, phy_modes(state->interface), port);
-		return;
 	}
 
 	mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
@@ -2836,7 +2789,6 @@ mt7531_cpu_port_config(struct dsa_switch *ds, int port)
 	struct mt7530_priv *priv = ds->priv;
 	phy_interface_t interface;
 	int speed;
-	int ret;
 
 	switch (port) {
 	case 5:
@@ -2861,9 +2813,8 @@ mt7531_cpu_port_config(struct dsa_switch *ds, int port)
 	else
 		speed = SPEED_1000;
 
-	ret = mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
-	if (ret)
-		return ret;
+	mt7531_mac_config(ds, port, MLO_AN_FIXED, interface);
+
 	mt7530_write(priv, MT7530_PMCR_P(port),
 		     PMCR_CPU_PORT_SETTING(priv->id));
 	mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 26a6d2160c08..b1665de7f640 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -730,9 +730,9 @@ struct mt753x_info {
 	void (*mac_port_validate)(struct dsa_switch *ds, int port,
 				  phy_interface_t interface,
 				  unsigned long *supported);
-	int (*mac_port_config)(struct dsa_switch *ds, int port,
-			       unsigned int mode,
-			       phy_interface_t interface);
+	void (*mac_port_config)(struct dsa_switch *ds, int port,
+				unsigned int mode,
+				phy_interface_t interface);
 };
 
 /* struct mt7530_priv -	This is the main data structure for holding the state

-- 
2.40.1



From thierry.reding at gmail.com  Fri Feb 16 03:06:00 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 16 Feb 2024 12:06:00 +0100
Subject: [PATCH] arm64: tegra: Set the correct PHY mode for MGBE
In-Reply-To: <20240202100812.866143-1-thierry.reding@gmail.com>
References: <20240202100812.866143-1-thierry.reding@gmail.com>
Message-ID: <170808154582.192868.9388966698624134440.b4-ty@nvidia.com>

From: Thierry Reding <treding at nvidia.com>


On Fri, 02 Feb 2024 11:08:12 +0100, Thierry Reding wrote:
> The PHY is configured in 10GBASE-R, so make sure to reflect that in DT.
> 
> 

Applied, thanks!

[1/1] arm64: tegra: Set the correct PHY mode for MGBE
      commit: 4c892121d43bc2b45896ca207b54f39a8fa6b852

Best regards,
-- 
Thierry Reding <treding at nvidia.com>


From theo.lebrun at bootlin.com  Fri Feb 16 03:09:17 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 16 Feb 2024 12:09:17 +0100
Subject: [PATCH v3 18/18] PCI: j721e: add suspend and resume support
In-Reply-To: <aa791703-81d8-420c-ba35-c8fd08bc3f07@ti.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-18-5c2e4a3fac1f@bootlin.com>
 <aa791703-81d8-420c-ba35-c8fd08bc3f07@ti.com>
Message-ID: <CZ6GG6OQUJTX.2OM5TC9YLOAXV@bootlin.com>

Hello,

On Fri Feb 16, 2024 at 11:48 AM CET, Siddharth Vadapalli wrote:
> On 24/02/15 04:18PM, Thomas Richard wrote:
> > From: Th?o Lebrun <theo.lebrun at bootlin.com>
> > 
> > Add suspend and resume support. Only the rc mode is supported.
> > 
> > During the suspend stage PERST# is asserted, then deasserted during the
> > resume stage.
>
> Wouldn't this imply that the Endpoint device will be reset and therefore
> lose context? Or is it expected that the driver corresponding to the
> Endpoint Function in Linux will restore the state on resume, post reset?

This does imply exactly that. Endpoint driver must be able to restore
context anyway, as system-wide suspend could mean lost power to PCI RC
controller (eg suspend-to-RAM) or PCI rails (dependent on hardware).

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From s-vadapalli at ti.com  Fri Feb 16 03:16:32 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Fri, 16 Feb 2024 16:46:32 +0530
Subject: [PATCH v3 18/18] PCI: j721e: add suspend and resume support
In-Reply-To: <CZ6GG6OQUJTX.2OM5TC9YLOAXV@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-18-5c2e4a3fac1f@bootlin.com>
 <aa791703-81d8-420c-ba35-c8fd08bc3f07@ti.com>
 <CZ6GG6OQUJTX.2OM5TC9YLOAXV@bootlin.com>
Message-ID: <8d47e1d0-69a3-475e-8dd8-64514872e026@ti.com>

On 24/02/16 12:09PM, Th?o Lebrun wrote:
> Hello,
> 
> On Fri Feb 16, 2024 at 11:48 AM CET, Siddharth Vadapalli wrote:
> > On 24/02/15 04:18PM, Thomas Richard wrote:
> > > From: Th?o Lebrun <theo.lebrun at bootlin.com>
> > > 
> > > Add suspend and resume support. Only the rc mode is supported.
> > > 
> > > During the suspend stage PERST# is asserted, then deasserted during the
> > > resume stage.
> >
> > Wouldn't this imply that the Endpoint device will be reset and therefore
> > lose context? Or is it expected that the driver corresponding to the
> > Endpoint Function in Linux will restore the state on resume, post reset?
> 
> This does imply exactly that. Endpoint driver must be able to restore
> context anyway, as system-wide suspend could mean lost power to PCI RC
> controller (eg suspend-to-RAM) or PCI rails (dependent on hardware).

Thank you for confirming.

Regards,
Siddharth.


From ryan.roberts at arm.com  Fri Feb 16 03:18:27 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri, 16 Feb 2024 11:18:27 +0000
Subject: [PATCH v2] mm/filemap: Allow arch to request folio size for exec
 memory
In-Reply-To: <Zc6mcDlcnOZIjqGm@dread.disaster.area>
References: <20240215154059.2863126-1-ryan.roberts@arm.com>
 <Zc6mcDlcnOZIjqGm@dread.disaster.area>
Message-ID: <58a67051-6d61-4d16-b073-266522907e05@arm.com>

Hi Dave,

Thanks for taking a look at this! Some comments below...

On 16/02/2024 00:04, Dave Chinner wrote:
> On Thu, Feb 15, 2024 at 03:40:59PM +0000, Ryan Roberts wrote:
>> Change the readahead config so that if it is being requested for an
>> executable mapping, do a synchronous read of an arch-specified size in a
>> naturally aligned manner.
>>
>> On arm64 if memory is physically contiguous and naturally aligned to the
>> "contpte" size, we can use contpte mappings, which improves utilization
>> of the TLB. When paired with the "multi-size THP" changes, this works
>> well to reduce dTLB pressure. However iTLB pressure is still high due to
>> executable mappings having a low liklihood of being in the required
>> folio size and mapping alignment, even when the filesystem supports
>> readahead into large folios (e.g. XFS).
>>
>> The reason for the low liklihood is that the current readahead algorithm
>> starts with an order-2 folio and increases the folio order by 2 every
>> time the readahead mark is hit. But most executable memory is faulted in
>> fairly randomly and so the readahead mark is rarely hit and most
>> executable folios remain order-2.
> 
> Yup, this is a bug in the readahead code, and really has nothing to
> do with executable files, mmap or the architecture.  We don't want
> some magic new VM_EXEC min folio size per architecture thingy to be
> set - we just want readahead to do the right thing.

It sounds like we agree that there is a bug but we don't agree on what the bug
is? My view is that executable segments are accessed in a ~random manner and
therefore readahead (as currently configured) is not very useful. But data may
well be accessed more sequentially and therefore readahead is useful. Given both
data and text can come from the same file, I don't think this can just be a
mapping setting? (my understanding is that there is one "mapping" for the whole
file?) So we need to look to VM_EXEC for that decision.

> 
> Indeed, we are already adding a mapping minimum folio order
> directive to the address space to allow for filesystem block sizes
> greater than PAGE_SIZE. That's the generic mechanism that this
> functionality requires. See here:
> 
> https://lore.kernel.org/linux-xfs/20240213093713.1753368-5-kernel at pankajraghav.com/

Great, I'm vaguely aware of this work, but haven't looked in detail. I'll go
read it. But from your brief description, IIUC, this applies to the whole file,
and is a constraint put in place by the filesystem? Applying to the whole file
may make sense - that means more opportunity for contpte mappings for data pages
too, although I guess this adds more scope for write amplificaiton because data
tends to be writable, and text isn't. But for my use case, its not a hard
constraint, its just a preference which can improve performance. And the
filesystem is the wrong place to make the decision; its the arch that knows
about the performacne opportunities with different block mapping sizes.

As a side note, concerns have been expressed about the possibility of physical
memory fragmentation becoming problematic, meaning we degrade back to small
folios over time with my mTHP work. The intuituon is that if the whole system is
using a few folio sizes in ~equal quantities then we might be ok, but I don't
have any data yet. Do you have any data on fragmentation? I guess this could be
more concerning for your use case?

> 
> (Probably worth reading some of the other readahead mods in that
> series and the discussion because readahead needs to ensure that it
> fill entire high order folios in a single IO to avoid partial folio
> up-to-date states from partial reads.)
> 
> IOWs, it seems to me that we could use this proposed generic mapping
> min order functionality when mmap() is run and VM_EXEC is set to set
> the min order to, say, 64kB. Then the readahead code would simply do
> the right thing, as would all other reads and writes to that
> mapping.

Ahh yes, hooking into your new logic to set a min order based on VM_EXEC sounds
perfect...

> 
> We could trigger this in the ->mmap() method of the filesystem so
> that filesysetms that can use large folios can turn it on, whilst
> other filesystems remain blissfully unaware of the functionality.
> Filesystems could also do smarter things here, too. eg. enable PMD
> alignment for large mapped files....

...but I don't think the filesystem is the right place. The size preference
should be driven by arch IMHO.

Thanks,
Ryan

> 
> -Dave.



From mani at kernel.org  Fri Feb 16 03:19:08 2024
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Fri, 16 Feb 2024 16:49:08 +0530
Subject: [PATCH 1/2] PCI: endpoint: Clean up hardware description for BARs
In-Reply-To: <20240210012634.600301-2-cassel@kernel.org>
References: <20240210012634.600301-1-cassel@kernel.org>
 <20240210012634.600301-2-cassel@kernel.org>
Message-ID: <20240216111908.GC2559@thinkpad>

On Sat, Feb 10, 2024 at 02:26:25AM +0100, Niklas Cassel wrote:
> The hardware description for BARs is scattered in many different variables
> in pci_epc_features. Some of these things are mutually exclusive, so it
> can create confusion over which variable that has precedence over another.
> 
> Improve the situation by creating a struct pci_epc_bar_desc, and a new
> enum pci_epc_bar_type, and convert the endpoint controller drivers to use
> this more well defined format.
> 
> Signed-off-by: Niklas Cassel <cassel at kernel.org>
> ---
>  drivers/pci/controller/dwc/pci-imx6.c         |  3 +-
>  drivers/pci/controller/dwc/pci-keystone.c     | 12 +++----
>  .../pci/controller/dwc/pci-layerscape-ep.c    |  5 ++-
>  drivers/pci/controller/dwc/pcie-keembay.c     |  8 +++--
>  drivers/pci/controller/dwc/pcie-rcar-gen4.c   |  4 ++-
>  drivers/pci/controller/dwc/pcie-tegra194.c    | 10 ++++--
>  drivers/pci/controller/dwc/pcie-uniphier-ep.c | 15 ++++++--
>  drivers/pci/controller/pcie-rcar-ep.c         | 14 +++++---
>  drivers/pci/endpoint/functions/pci-epf-ntb.c  |  4 +--
>  drivers/pci/endpoint/functions/pci-epf-test.c |  8 ++---
>  drivers/pci/endpoint/functions/pci-epf-vntb.c |  2 +-
>  drivers/pci/endpoint/pci-epc-core.c           | 32 +++++++++--------
>  drivers/pci/endpoint/pci-epf-core.c           | 15 ++++----
>  include/linux/pci-epc.h                       | 34 +++++++++++++++----
>  14 files changed, 108 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index dc2c036ab28c..47a9a96484ed 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -1081,7 +1081,8 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
>  	.msix_capable = false,
> -	.reserved_bar = 1 << BAR_1 | 1 << BAR_3,
> +	.bar[BAR_1] = { .type = BAR_RESERVED, },
> +	.bar[BAR_3] = { .type = BAR_RESERVED, },
>  	.align = SZ_64K,
>  };
>  
> diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
> index c0c62533a3f1..b2b93b4fa82d 100644
> --- a/drivers/pci/controller/dwc/pci-keystone.c
> +++ b/drivers/pci/controller/dwc/pci-keystone.c
> @@ -924,12 +924,12 @@ static const struct pci_epc_features ks_pcie_am654_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
>  	.msix_capable = true,
> -	.reserved_bar = 1 << BAR_0 | 1 << BAR_1,
> -	.bar_fixed_64bit = 1 << BAR_0,
> -	.bar_fixed_size[2] = SZ_1M,
> -	.bar_fixed_size[3] = SZ_64K,
> -	.bar_fixed_size[4] = 256,
> -	.bar_fixed_size[5] = SZ_1M,
> +	.bar[BAR_0] = { .type = BAR_RESERVED, .only_64bit = true, },
> +	.bar[BAR_1] = { .type = BAR_RESERVED, },
> +	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
> +	.bar[BAR_3] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
> +	.bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256, },
> +	.bar[BAR_5] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
>  	.align = SZ_1M,
>  };
>  
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index 2e398494e7c0..1f6ee1460ec2 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -250,7 +250,10 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
>  	pci->dev = dev;
>  	pci->ops = pcie->drvdata->dw_pcie_ops;
>  
> -	ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
> +	ls_epc->bar[BAR_2].only_64bit = true;
> +	ls_epc->bar[BAR_3].type = BAR_RESERVED;

BAR_3 and BAR_4 were not reserved previously.

> +	ls_epc->bar[BAR_4].only_64bit = true;
> +	ls_epc->bar[BAR_5].type = BAR_RESERVED;
>  	ls_epc->linkup_notifier = true;
>  
>  	pcie->pci = pci;
> diff --git a/drivers/pci/controller/dwc/pcie-keembay.c b/drivers/pci/controller/dwc/pcie-keembay.c
> index 208d3b0ba196..5e8e54f597dd 100644
> --- a/drivers/pci/controller/dwc/pcie-keembay.c
> +++ b/drivers/pci/controller/dwc/pcie-keembay.c
> @@ -312,8 +312,12 @@ static const struct pci_epc_features keembay_pcie_epc_features = {
>  	.linkup_notifier	= false,
>  	.msi_capable		= true,
>  	.msix_capable		= true,
> -	.reserved_bar		= BIT(BAR_1) | BIT(BAR_3) | BIT(BAR_5),
> -	.bar_fixed_64bit	= BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
> +	.bar[BAR_0]		= { .only_64bit = true, },
> +	.bar[BAR_1]		= { .type = BAR_RESERVED, },
> +	.bar[BAR_2]		= { .only_64bit = true, },
> +	.bar[BAR_3]		= { .type = BAR_RESERVED, },
> +	.bar[BAR_4]		= { .only_64bit = true, },
> +	.bar[BAR_5]		= { .type = BAR_RESERVED, },
>  	.align			= SZ_16K,
>  };
>  
> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> index e9166619b1f9..0be760ed420b 100644
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> @@ -383,7 +383,9 @@ static const struct pci_epc_features rcar_gen4_pcie_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
>  	.msix_capable = false,
> -	.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
> +	.bar[BAR_1] = { .type = BAR_RESERVED, },
> +	.bar[BAR_3] = { .type = BAR_RESERVED, },
> +	.bar[BAR_5] = { .type = BAR_RESERVED, },
>  	.align = SZ_1M,
>  };
>  
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 7afa9e9aabe2..1f7b662cb8e1 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -2007,9 +2007,13 @@ static const struct pci_epc_features tegra_pcie_epc_features = {
>  	.core_init_notifier = true,
>  	.msi_capable = false,
>  	.msix_capable = false,
> -	.reserved_bar = 1 << BAR_2 | 1 << BAR_3 | 1 << BAR_4 | 1 << BAR_5,
> -	.bar_fixed_64bit = 1 << BAR_0,
> -	.bar_fixed_size[0] = SZ_1M,
> +	.bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = SZ_1M,
> +			.only_64bit = true, },
> +	.bar[BAR_1] = { .type = BAR_RESERVED, },

Same, BAR_1 was not reserved.

> +	.bar[BAR_2] = { .type = BAR_RESERVED, },
> +	.bar[BAR_3] = { .type = BAR_RESERVED, },
> +	.bar[BAR_4] = { .type = BAR_RESERVED, },
> +	.bar[BAR_5] = { .type = BAR_RESERVED, },
>  };
>  
>  static const struct pci_epc_features*
> diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
> index 3fced0d3e851..265f65fc673f 100644
> --- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
> @@ -411,8 +411,12 @@ static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = {
>  		.msi_capable = true,
>  		.msix_capable = false,
>  		.align = 1 << 16,
> -		.bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
> -		.reserved_bar =  BIT(BAR_4),
> +		.bar[BAR_0] = { .only_64bit = true, },
> +		.bar[BAR_1] = { .type = BAR_RESERVED, },

Same as above.

> +		.bar[BAR_2] = { .only_64bit = true, },
> +		.bar[BAR_3] = { .type = BAR_RESERVED, },
> +		.bar[BAR_4] = { .type = BAR_RESERVED, .only_64bit = true, },
> +		.bar[BAR_5] = { .type = BAR_RESERVED, },
>  	},
>  };
>  
> @@ -425,7 +429,12 @@ static const struct uniphier_pcie_ep_soc_data uniphier_nx1_data = {
>  		.msi_capable = true,
>  		.msix_capable = false,
>  		.align = 1 << 12,
> -		.bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
> +		.bar[BAR_0] = { .only_64bit = true, },
> +		.bar[BAR_1] = { .type = BAR_RESERVED, },

Same as above.

- Mani

-- 
????????? ????????


From thierry.reding at gmail.com  Fri Feb 16 03:23:36 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 16 Feb 2024 12:23:36 +0100
Subject: [PATCH] clk: constify the of_phandle_args argument of
 of_clk_provider
In-Reply-To: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
References: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CZ6GR5BWC80N.36XRBM33WF8MW@gmail.com>

On Thu Feb 8, 2024 at 5:37 PM CET, Krzysztof Kozlowski wrote:
[...]
>  drivers/clk/tegra/clk-bpmp.c                  |  2 +-
>  drivers/clk/tegra/clk-tegra124.c              |  2 +-
>  drivers/clk/tegra/clk-tegra20.c               |  2 +-
>  drivers/clk/tegra/clk-tegra30.c               |  2 +-
[...]

Acked-by: Thierry Reding <treding at nvidia.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/20240216/2bf1ba72/attachment-0001.sig>

From mani at kernel.org  Fri Feb 16 03:25:31 2024
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Fri, 16 Feb 2024 16:55:31 +0530
Subject: [PATCH 1/2] PCI: endpoint: Clean up hardware description for BARs
In-Reply-To: <20240216111908.GC2559@thinkpad>
References: <20240210012634.600301-1-cassel@kernel.org>
 <20240210012634.600301-2-cassel@kernel.org>
 <20240216111908.GC2559@thinkpad>
Message-ID: <20240216112531.GD2559@thinkpad>

On Fri, Feb 16, 2024 at 04:49:08PM +0530, Manivannan Sadhasivam wrote:
> On Sat, Feb 10, 2024 at 02:26:25AM +0100, Niklas Cassel wrote:
> > The hardware description for BARs is scattered in many different variables
> > in pci_epc_features. Some of these things are mutually exclusive, so it
> > can create confusion over which variable that has precedence over another.
> > 
> > Improve the situation by creating a struct pci_epc_bar_desc, and a new
> > enum pci_epc_bar_type, and convert the endpoint controller drivers to use
> > this more well defined format.
> > 
> > Signed-off-by: Niklas Cassel <cassel at kernel.org>
> > ---
> >  drivers/pci/controller/dwc/pci-imx6.c         |  3 +-
> >  drivers/pci/controller/dwc/pci-keystone.c     | 12 +++----
> >  .../pci/controller/dwc/pci-layerscape-ep.c    |  5 ++-
> >  drivers/pci/controller/dwc/pcie-keembay.c     |  8 +++--
> >  drivers/pci/controller/dwc/pcie-rcar-gen4.c   |  4 ++-
> >  drivers/pci/controller/dwc/pcie-tegra194.c    | 10 ++++--
> >  drivers/pci/controller/dwc/pcie-uniphier-ep.c | 15 ++++++--
> >  drivers/pci/controller/pcie-rcar-ep.c         | 14 +++++---
> >  drivers/pci/endpoint/functions/pci-epf-ntb.c  |  4 +--
> >  drivers/pci/endpoint/functions/pci-epf-test.c |  8 ++---
> >  drivers/pci/endpoint/functions/pci-epf-vntb.c |  2 +-
> >  drivers/pci/endpoint/pci-epc-core.c           | 32 +++++++++--------
> >  drivers/pci/endpoint/pci-epf-core.c           | 15 ++++----
> >  include/linux/pci-epc.h                       | 34 +++++++++++++++----
> >  14 files changed, 108 insertions(+), 58 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> > index dc2c036ab28c..47a9a96484ed 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -1081,7 +1081,8 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
> >  	.linkup_notifier = false,
> >  	.msi_capable = true,
> >  	.msix_capable = false,
> > -	.reserved_bar = 1 << BAR_1 | 1 << BAR_3,
> > +	.bar[BAR_1] = { .type = BAR_RESERVED, },
> > +	.bar[BAR_3] = { .type = BAR_RESERVED, },
> >  	.align = SZ_64K,
> >  };
> >  
> > diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
> > index c0c62533a3f1..b2b93b4fa82d 100644
> > --- a/drivers/pci/controller/dwc/pci-keystone.c
> > +++ b/drivers/pci/controller/dwc/pci-keystone.c
> > @@ -924,12 +924,12 @@ static const struct pci_epc_features ks_pcie_am654_epc_features = {
> >  	.linkup_notifier = false,
> >  	.msi_capable = true,
> >  	.msix_capable = true,
> > -	.reserved_bar = 1 << BAR_0 | 1 << BAR_1,
> > -	.bar_fixed_64bit = 1 << BAR_0,
> > -	.bar_fixed_size[2] = SZ_1M,
> > -	.bar_fixed_size[3] = SZ_64K,
> > -	.bar_fixed_size[4] = 256,
> > -	.bar_fixed_size[5] = SZ_1M,
> > +	.bar[BAR_0] = { .type = BAR_RESERVED, .only_64bit = true, },
> > +	.bar[BAR_1] = { .type = BAR_RESERVED, },
> > +	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
> > +	.bar[BAR_3] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
> > +	.bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256, },
> > +	.bar[BAR_5] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
> >  	.align = SZ_1M,
> >  };
> >  
> > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > index 2e398494e7c0..1f6ee1460ec2 100644
> > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > @@ -250,7 +250,10 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
> >  	pci->dev = dev;
> >  	pci->ops = pcie->drvdata->dw_pcie_ops;
> >  
> > -	ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
> > +	ls_epc->bar[BAR_2].only_64bit = true;
> > +	ls_epc->bar[BAR_3].type = BAR_RESERVED;
> 
> BAR_3 and BAR_4 were not reserved previously.
> 

Okay, looking at patch 2 makes it clear why you have marked it as such. But it
should've been mentioned in the commit message.

- Mani

-- 
????????? ????????


From krzysztof.kozlowski at linaro.org  Fri Feb 16 03:26:12 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 12:26:12 +0100
Subject: [PATCH 1/3] dt-bindings: i3c: drop "master" node name suffix
In-Reply-To: <20240117075618.81932-1-krzysztof.kozlowski@linaro.org>
References: <20240117075618.81932-1-krzysztof.kozlowski@linaro.org>
Message-ID: <00d6a0d5-6787-4777-8fb2-dcad4304a724@linaro.org>

On 17/01/2024 08:56, Krzysztof Kozlowski wrote:
> Drop the requirement of "-master" suffix in node names because:
> 1. "Master" word is discouraged and MIPI Alliance renamed it to
>    "Controller".
> 2. Some devices can operate in Controller (Master) or Target mode, thus
>    the name is not accurate in such cases.
> 3. Other buses, like I2C controllers, use simple "i2c".
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---

Rob, can you pick this one up? It seems Alexandre did not take it.

Best regards,
Krzysztof



From mani at kernel.org  Fri Feb 16 03:28:08 2024
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Fri, 16 Feb 2024 16:58:08 +0530
Subject: [PATCH 2/2] PCI: endpoint: Drop only_64bit on reserved BARs
In-Reply-To: <20240210012634.600301-3-cassel@kernel.org>
References: <20240210012634.600301-1-cassel@kernel.org>
 <20240210012634.600301-3-cassel@kernel.org>
Message-ID: <20240216112808.GE2559@thinkpad>

On Sat, Feb 10, 2024 at 02:26:26AM +0100, Niklas Cassel wrote:
> The definition of a reserved BAR is that EPF drivers should not touch
> them.
> 
> The definition of only_64bit is that the EPF driver must configure this
> BAR as 64-bit. (An EPF driver is not allowed to choose if this BAR should
> be configured as 32-bit or 64-bit.)
> 
> Thus, it does not make sense to put only_64bit of a BAR that EPF drivers
> are not allow to touch.
> 
> Drop the only_64bit property from hardware descriptions that are of type
> reserved BAR.
> 
> Signed-off-by: Niklas Cassel <cassel at kernel.org>

One nitpick below. With that addressed,

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

> ---
>  drivers/pci/controller/dwc/pci-keystone.c     | 2 +-
>  drivers/pci/controller/dwc/pcie-uniphier-ep.c | 2 +-
>  drivers/pci/endpoint/pci-epc-core.c           | 7 -------
>  include/linux/pci-epc.h                       | 4 ++++
>  4 files changed, 6 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
> index b2b93b4fa82d..844de4418724 100644
> --- a/drivers/pci/controller/dwc/pci-keystone.c
> +++ b/drivers/pci/controller/dwc/pci-keystone.c
> @@ -924,7 +924,7 @@ static const struct pci_epc_features ks_pcie_am654_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
>  	.msix_capable = true,
> -	.bar[BAR_0] = { .type = BAR_RESERVED, .only_64bit = true, },
> +	.bar[BAR_0] = { .type = BAR_RESERVED, },
>  	.bar[BAR_1] = { .type = BAR_RESERVED, },
>  	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
>  	.bar[BAR_3] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
> diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
> index 265f65fc673f..639bc2e12476 100644
> --- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
> @@ -415,7 +415,7 @@ static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = {
>  		.bar[BAR_1] = { .type = BAR_RESERVED, },
>  		.bar[BAR_2] = { .only_64bit = true, },
>  		.bar[BAR_3] = { .type = BAR_RESERVED, },
> -		.bar[BAR_4] = { .type = BAR_RESERVED, .only_64bit = true, },
> +		.bar[BAR_4] = { .type = BAR_RESERVED, },
>  		.bar[BAR_5] = { .type = BAR_RESERVED, },
>  	},
>  };
> diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
> index 7fe8f4336765..da3fc0795b0b 100644
> --- a/drivers/pci/endpoint/pci-epc-core.c
> +++ b/drivers/pci/endpoint/pci-epc-core.c
> @@ -120,13 +120,6 @@ enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
>  		/* If the BAR is not reserved, return it. */
>  		if (epc_features->bar[i].type != BAR_RESERVED)
>  			return i;
> -
> -		/*
> -		 * If the BAR is reserved, and marked as 64-bit only, then the
> -		 * succeeding BAR is also reserved.
> -		 */
> -		if (epc_features->bar[i].only_64bit)
> -			i++;
>  	}
>  
>  	return NO_BAR;
> diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
> index 4ccb4f4f3883..bb9c4dfcea93 100644
> --- a/include/linux/pci-epc.h
> +++ b/include/linux/pci-epc.h
> @@ -164,6 +164,10 @@ enum pci_epc_bar_type {
>   *		should be configured as 32-bit or 64-bit, the EPF driver must
>   *		configure this BAR as 64-bit. Additionally, the BAR succeeding
>   *		this BAR must be set to type BAR_RESERVED.
> + *
> + *		only_64bit should not be set on a BAR of type BAR_RESERVED.
> + *		(If BARx is a 64-bit BAR that an EPF driver is not allowed to
> + *		touch, then you must set both BARx and BARx+1 as BAR_RESERVED.)

"then both BARx and BARx+1 must be set to type BAR_RESERVED."

- Mani

-- 
????????? ????????


From robh at kernel.org  Fri Feb 16 03:30:38 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 16 Feb 2024 05:30:38 -0600
Subject: [PATCH 2/4] dt-bindings: media: Document bindings for HDMI RX
 Controller
In-Reply-To: <20240216094922.257674-3-shreeya.patel@collabora.com>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
 <20240216094922.257674-3-shreeya.patel@collabora.com>
Message-ID: <170808303721.2162868.14811382528537445786.robh@kernel.org>


On Fri, 16 Feb 2024 15:19:20 +0530, Shreeya Patel wrote:
> Document bindings for the Synopsys DesignWare HDMI RX Controller.
> 
> Reviewed-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
> Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
> ---
>  .../bindings/media/snps,dw-hdmi-rx.yaml       | 128 ++++++++++++++++++
>  1 file changed, 128 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.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/snps,dw-hdmi-rx.example.dts:57.47-48 syntax error
FATAL ERROR: Unable to parse input tree
make[2]: *** [scripts/Makefile.lib:419: Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.example.dtb] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1428: dt_binding_check] Error 2
make: *** [Makefile:240: __sub-make] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240216094922.257674-3-shreeya.patel at collabora.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From aford173 at gmail.com  Fri Feb 16 03:31:12 2024
From: aford173 at gmail.com (Adam Ford)
Date: Fri, 16 Feb 2024 05:31:12 -0600
Subject: [PATCH V8 09/12] dt-bindings: display: imx: add binding for
 i.MX8MP HDMI TX
In-Reply-To: <5916132.MhkbZ0Pkbq@steina-w>
References: <20240203165307.7806-1-aford173@gmail.com> <20240203165307.7806-10-aford173@gmail.com>
 <5916132.MhkbZ0Pkbq@steina-w>
Message-ID: <CAHCN7x+80iw0PWa4F4dMA=3RRaChNEO534LPACXd6FK0ndAHpw@mail.gmail.com>

On Fri, Feb 16, 2024 at 3:05?AM Alexander Stein
<alexander.stein at ew.tq-group.com> wrote:
>
> Hi all,
>
> Am Samstag, 3. Februar 2024, 17:52:49 CET schrieb Adam Ford:
> > From: Lucas Stach <l.stach at pengutronix.de>
> >
> > The HDMI TX controller on the i.MX8MP SoC is a Synopsys designware IP
> > core with a little bit of SoC integration around it.
> >
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
> >
> > ---
> > V3:  Change name and location to better idenfity as a bridge and
> >      HDMI 2.0a transmitter
> >
> >      Fix typos and feedback from Rob and added ports.
> > ---
> >  .../display/bridge/fsl,imx8mp-hdmi-tx.yaml    | 102 ++++++++++++++++++
> >  1 file changed, 102 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> >
> > diff --git
> > a/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> > b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> > new file mode 100644
> > index 000000000000..3791c9f4ebab
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> > @@ -0,0 +1,102 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/display/bridge/fsl,imx8mp-hdmi-tx.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Freescale i.MX8MP DWC HDMI TX Encoder
> > +
> > +maintainers:
> > +  - Lucas Stach <l.stach at pengutronix.de>
> > +
> > +description:
> > +  The i.MX8MP HDMI transmitter is a Synopsys DesignWare
> > +  HDMI 2.0a TX controller IP.
> > +
> > +allOf:
> > +  - $ref: /schemas/display/bridge/synopsys,dw-hdmi.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - fsl,imx8mp-hdmi-tx
> > +
> > +  reg-io-width:
> > +    const: 1
> > +
> > +  clocks:
> > +    maxItems: 4
> > +
> > +  clock-names:
> > +    items:
> > +      - const: iahb
> > +      - const: isfr
> > +      - const: cec
> > +      - const: pix
> > +
> > +  power-domains:
> > +    maxItems: 1
> > +
> > +  ports:
> > +    $ref: /schemas/graph.yaml#/properties/ports
> > +
> > +    properties:
> > +      port at 0:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: Parallel RGB input port
> > +
> > +      port at 1:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: HDMI output port
> > +
> > +    required:
> > +      - port at 0
> > +      - port at 1
>
> Is this really correct that port at 1 is required? AFAICS this host already
> supports HPD and DDC by itself, so there is no need for a dedicated HDMI
> connector.
> With the current state of the drivers this output port is completely ignored
> anyway. Yet it works for a lot of people.

One of the feedback responses Lucas got was that it was missing the
reference to the HDMI connector, so I added it as a response to that
feedback.  I have tried device trees with and without it, and it
doesn't impact anything, but It seems like there may be a requirement
for it.

adam
>
> Best regards,
> Alexander
>
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - clocks
> > +  - clock-names
> > +  - interrupts
> > +  - power-domains
> > +  - ports
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/imx8mp-clock.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/power/imx8mp-power.h>
> > +
> > +    hdmi at 32fd8000 {
> > +        compatible = "fsl,imx8mp-hdmi-tx";
> > +        reg = <0x32fd8000 0x7eff>;
> > +        interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
> > +        clocks = <&clk IMX8MP_CLK_HDMI_APB>,
> > +                 <&clk IMX8MP_CLK_HDMI_REF_266M>,
> > +                 <&clk IMX8MP_CLK_32K>,
> > +                 <&hdmi_tx_phy>;
> > +        clock-names = "iahb", "isfr", "cec", "pix";
> > +        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
> > +        reg-io-width = <1>;
> > +        ports {
> > +           #address-cells = <1>;
> > +           #size-cells = <0>;
> > +           port at 0 {
> > +             reg = <0>;
> > +
> > +             hdmi_tx_from_pvi: endpoint {
> > +               remote-endpoint = <&pvi_to_hdmi_tx>;
> > +             };
> > +          };
> > +
> > +          port at 1 {
> > +            reg = <1>;
> > +              hdmi_tx_out: endpoint {
> > +                remote-endpoint = <&hdmi0_con>;
> > +              };
> > +          };
> > +        };
> > +    };
>
>
> --
> TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht M?nchen, HRB 105018
> Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> http://www.tq-group.com/
>
>


From manivannan.sadhasivam at linaro.org  Fri Feb 16 03:31:47 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Fri, 16 Feb 2024 17:01:47 +0530
Subject: [PATCH v5 1/2] clk: Provide managed helper to get and enable
 bulk clocks
In-Reply-To: <20240213132751.46813-2-shradha.t@samsung.com>
References: <20240213132751.46813-1-shradha.t@samsung.com>
 <CGME20240213132806epcas5p43e394aea91c61797a8cc3a901e0cf574@epcas5p4.samsung.com>
 <20240213132751.46813-2-shradha.t@samsung.com>
Message-ID: <20240216113147.GF2559@thinkpad>

On Tue, Feb 13, 2024 at 06:57:50PM +0530, Shradha Todi wrote:
> Provide a managed devm_clk_bulk* wrapper to get and enable all
> bulk clocks in order to simplify drivers that keeps all clocks
> enabled for the time of driver operation.
> 
> Suggested-by: Marek Szyprowski <m.szyprowski at samsung.com>
> Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
> Signed-off-by: Shradha Todi <shradha.t at samsung.com>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

- Mani

> ---
>  drivers/clk/clk-devres.c | 40 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/clk.h      | 23 +++++++++++++++++++++++
>  2 files changed, 63 insertions(+)
> 
> diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
> index 4fb4fd4b06bd..cbbd2cc339c3 100644
> --- a/drivers/clk/clk-devres.c
> +++ b/drivers/clk/clk-devres.c
> @@ -182,6 +182,46 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
>  }
>  EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all);
>  
> +static void devm_clk_bulk_release_all_enable(struct device *dev, void *res)
> +{
> +	struct clk_bulk_devres *devres = res;
> +
> +	clk_bulk_disable_unprepare(devres->num_clks, devres->clks);
> +	clk_bulk_put_all(devres->num_clks, devres->clks);
> +}
> +
> +int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
> +					      struct clk_bulk_data **clks)
> +{
> +	struct clk_bulk_devres *devres;
> +	int ret;
> +
> +	devres = devres_alloc(devm_clk_bulk_release_all_enable,
> +			      sizeof(*devres), GFP_KERNEL);
> +	if (!devres)
> +		return -ENOMEM;
> +
> +	ret = clk_bulk_get_all(dev, &devres->clks);
> +	if (ret > 0) {
> +		*clks = devres->clks;
> +		devres->num_clks = ret;
> +	} else {
> +		devres_free(devres);
> +		return ret;
> +	}
> +
> +	ret = clk_bulk_prepare_enable(devres->num_clks, *clks);
> +	if (!ret) {
> +		devres_add(dev, devres);
> +	} else {
> +		clk_bulk_put_all(devres->num_clks, devres->clks);
> +		devres_free(devres);
> +	}
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enable);
> +
>  static int devm_clk_match(struct device *dev, void *res, void *data)
>  {
>  	struct clk **c = res;
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 1ef013324237..85a9330d5a5a 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -438,6 +438,22 @@ int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks,
>  int __must_check devm_clk_bulk_get_all(struct device *dev,
>  				       struct clk_bulk_data **clks);
>  
> +/**
> + * devm_clk_bulk_get_all_enable - Get and enable all clocks of the consumer (managed)
> + * @dev: device for clock "consumer"
> + * @clks: pointer to the clk_bulk_data table of consumer
> + *
> + * Returns success (0) or negative errno.
> + *
> + * This helper function allows drivers to get all clocks of the
> + * consumer and enables them in one operation with management.
> + * The clks will automatically be disabled and freed when the device
> + * is unbound.
> + */
> +
> +int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
> +					      struct clk_bulk_data **clks);
> +
>  /**
>   * devm_clk_get - lookup and obtain a managed reference to a clock producer.
>   * @dev: device for clock "consumer"
> @@ -960,6 +976,13 @@ static inline int __must_check devm_clk_bulk_get_all(struct device *dev,
>  	return 0;
>  }
>  
> +static inline int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
> +						struct clk_bulk_data **clks)
> +{
> +
> +	return 0;
> +}
> +
>  static inline struct clk *devm_get_clk_from_child(struct device *dev,
>  				struct device_node *np, const char *con_id)
>  {
> -- 
> 2.17.1
> 

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Fri Feb 16 03:33:47 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Fri, 16 Feb 2024 17:03:47 +0530
Subject: [PATCH v5 1/2] clk: Provide managed helper to get and enable
 bulk clocks
In-Reply-To: <20240216113147.GF2559@thinkpad>
References: <20240213132751.46813-1-shradha.t@samsung.com>
 <CGME20240213132806epcas5p43e394aea91c61797a8cc3a901e0cf574@epcas5p4.samsung.com>
 <20240213132751.46813-2-shradha.t@samsung.com>
 <20240216113147.GF2559@thinkpad>
Message-ID: <20240216113347.GG2559@thinkpad>

On Fri, Feb 16, 2024 at 05:01:47PM +0530, Manivannan Sadhasivam wrote:
> On Tue, Feb 13, 2024 at 06:57:50PM +0530, Shradha Todi wrote:
> > Provide a managed devm_clk_bulk* wrapper to get and enable all
> > bulk clocks in order to simplify drivers that keeps all clocks
> > enabled for the time of driver operation.
> > 
> > Suggested-by: Marek Szyprowski <m.szyprowski at samsung.com>
> > Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
> > Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> 
> - Mani
> 
> > ---
> >  drivers/clk/clk-devres.c | 40 ++++++++++++++++++++++++++++++++++++++++
> >  include/linux/clk.h      | 23 +++++++++++++++++++++++
> >  2 files changed, 63 insertions(+)
> > 

[...]

> > diff --git a/include/linux/clk.h b/include/linux/clk.h
> > index 1ef013324237..85a9330d5a5a 100644
> > --- a/include/linux/clk.h
> > +++ b/include/linux/clk.h
> > @@ -438,6 +438,22 @@ int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks,
> >  int __must_check devm_clk_bulk_get_all(struct device *dev,
> >  				       struct clk_bulk_data **clks);
> >  
> > +/**
> > + * devm_clk_bulk_get_all_enable - Get and enable all clocks of the consumer (managed)
> > + * @dev: device for clock "consumer"
> > + * @clks: pointer to the clk_bulk_data table of consumer
> > + *
> > + * Returns success (0) or negative errno.
> > + *
> > + * This helper function allows drivers to get all clocks of the
> > + * consumer and enables them in one operation with management.
> > + * The clks will automatically be disabled and freed when the device
> > + * is unbound.
> > + */
> > +
> > +int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
> > +					      struct clk_bulk_data **clks);
> > +
> >  /**
> >   * devm_clk_get - lookup and obtain a managed reference to a clock producer.
> >   * @dev: device for clock "consumer"
> > @@ -960,6 +976,13 @@ static inline int __must_check devm_clk_bulk_get_all(struct device *dev,
> >  	return 0;
> >  }
> >  
> > +static inline int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
> > +						struct clk_bulk_data **clks)
> > +{
> > +

Just noticed this extra newline after sending my r-b tag. Please remove it in
next iteration.

- Mani

-- 
????????? ????????


From apatel at ventanamicro.com  Fri Feb 16 03:33:51 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Fri, 16 Feb 2024 17:03:51 +0530
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <ZcSoqkexSipQsrLZ@andrea>
References: <20240127161753.114685-1-apatel@ventanamicro.com> <ZcSoqkexSipQsrLZ@andrea>
Message-ID: <CAK9=C2XOnVeosVugF0sOFHuuFExVDBajLpV_b3Z4iFBW0Ke+aA@mail.gmail.com>

Hi Andrea,

On Thu, Feb 8, 2024 at 3:40?PM Andrea Parri <parri.andrea at gmail.com> wrote:
>
> Hi Anup,
>
> I understand that some refactoring is in progress, but I don't see the
> report below; adding it here hoping that it can be useful towards v13.
> (Unfortunately, I didn't have enough time to debug this yet...)
>
>
> >   irqchip/sifive-plic: Convert PLIC driver into a platform driver
>
> I'm seeing the following LOCKDEP warning with this series, bisected to
> the commit above.  This is a defconfig + PROVE_LOCKING=y build, booted
> using -machine virt,aia=none.
>
> [    0.953473] ========================================================
> [    0.953704] WARNING: possible irq lock inversion dependency detected
> [    0.953955] 6.8.0-rc1-00039-gd9b9d6eb987f #1122 Not tainted
> [    0.954224] --------------------------------------------------------
> [    0.954444] swapper/0/0 just changed the state of lock:
> [    0.954664] ffffaf808109d0c8 (&irq_desc_lock_class){-...}-{2:2}, at: handle_fasteoi_irq+0x24/0x1da
> [    0.955699] but this lock took another, HARDIRQ-unsafe lock in the past:
> [    0.955942]  (&handler->enable_lock){+.+.}-{2:2}
> [    0.955974]
>
>                and interrupts could create inverse lock ordering between them.
>
> [    0.956507]
>                other info that might help us debug this:
> [    0.956775]  Possible interrupt unsafe locking scenario:
>
> [    0.956998]        CPU0                    CPU1
> [    0.957247]        ----                    ----
> [    0.957439]   lock(&handler->enable_lock);
> [    0.957607]                                local_irq_disable();
> [    0.957793]                                lock(&irq_desc_lock_class);
> [    0.958021]                                lock(&handler->enable_lock);
> [    0.958246]   <Interrupt>
> [    0.958342]     lock(&irq_desc_lock_class);
> [    0.958501]
>                 *** DEADLOCK ***

I was able to reproduce this warning.

Further digging, it turns out the locking safety issue existed
before PLIC was converted into platform driver but was never
caught by the lock dependency because previously it was
being probed very early using IRQCHIP_DECLARE().

I will include a separate patch in v13 to fix this warning.

Thanks,
Anup



>
> [    0.958715] no locks held by swapper/0/0.
> [    0.958870]
>                the shortest dependencies between 2nd lock and 1st lock:
> [    0.959152]  -> (&handler->enable_lock){+.+.}-{2:2} {
> [    0.959372]     HARDIRQ-ON-W at:
> [    0.959522]                       __lock_acquire+0x884/0x1f5c
> [    0.959745]                       lock_acquire+0xf0/0x292
> [    0.959913]                       _raw_spin_lock+0x2c/0x40
> [    0.960090]                       plic_probe+0x322/0x65c
> [    0.960257]                       platform_probe+0x4e/0x92
> [    0.960432]                       really_probe+0x82/0x210
> [    0.960598]                       __driver_probe_device+0x5c/0xd0
> [    0.960784]                       driver_probe_device+0x2c/0xb0
> [    0.960964]                       __driver_attach+0x72/0x10a
> [    0.961151]                       bus_for_each_dev+0x60/0xac
> [    0.961330]                       driver_attach+0x1a/0x22
> [    0.961496]                       bus_add_driver+0xd4/0x19e
> [    0.961666]                       driver_register+0x3e/0xd8
> [    0.961835]                       __platform_driver_register+0x1c/0x24
> [    0.962030]                       plic_driver_init+0x1a/0x22
> [    0.962201]                       do_one_initcall+0x80/0x268
> [    0.962371]                       kernel_init_freeable+0x296/0x300
> [    0.962554]                       kernel_init+0x1e/0x10a
> [    0.962713]                       ret_from_fork+0xe/0x1c
> [    0.962884]     SOFTIRQ-ON-W at:
> [    0.962994]                       __lock_acquire+0x89e/0x1f5c
> [    0.963169]                       lock_acquire+0xf0/0x292
> [    0.963336]                       _raw_spin_lock+0x2c/0x40
> [    0.963497]                       plic_probe+0x322/0x65c
> [    0.963664]                       platform_probe+0x4e/0x92
> [    0.963849]                       really_probe+0x82/0x210
> [    0.964054]                       __driver_probe_device+0x5c/0xd0
> [    0.964255]                       driver_probe_device+0x2c/0xb0
> [    0.964428]                       __driver_attach+0x72/0x10a
> [    0.964603]                       bus_for_each_dev+0x60/0xac
> [    0.964777]                       driver_attach+0x1a/0x22
> [    0.964943]                       bus_add_driver+0xd4/0x19e
> [    0.965343]                       driver_register+0x3e/0xd8
> [    0.965527]                       __platform_driver_register+0x1c/0x24
> [    0.965732]                       plic_driver_init+0x1a/0x22
> [    0.965908]                       do_one_initcall+0x80/0x268
> [    0.966078]                       kernel_init_freeable+0x296/0x300
> [    0.966268]                       kernel_init+0x1e/0x10a
> [    0.966436]                       ret_from_fork+0xe/0x1c
> [    0.966599]     INITIAL USE at:
> [    0.966716]                      __lock_acquire+0x3fc/0x1f5c
> [    0.966891]                      lock_acquire+0xf0/0x292
> [    0.967048]                      _raw_spin_lock+0x2c/0x40
> [    0.967206]                      plic_probe+0x322/0x65c
> [    0.967360]                      platform_probe+0x4e/0x92
> [    0.967522]                      really_probe+0x82/0x210
> [    0.967678]                      __driver_probe_device+0x5c/0xd0
> [    0.967853]                      driver_probe_device+0x2c/0xb0
> [    0.968025]                      __driver_attach+0x72/0x10a
> [    0.968185]                      bus_for_each_dev+0x60/0xac
> [    0.968348]                      driver_attach+0x1a/0x22
> [    0.968513]                      bus_add_driver+0xd4/0x19e
> [    0.968678]                      driver_register+0x3e/0xd8
> [    0.968839]                      __platform_driver_register+0x1c/0x24
> [    0.969035]                      plic_driver_init+0x1a/0x22
> [    0.969239]                      do_one_initcall+0x80/0x268
> [    0.969431]                      kernel_init_freeable+0x296/0x300
> [    0.969610]                      kernel_init+0x1e/0x10a
> [    0.969766]                      ret_from_fork+0xe/0x1c
> [    0.969936]   }
> [    0.970010]   ... key      at: [<ffffffff824f4138>] __key.2+0x0/0x10
> [    0.970224]   ... acquired at:
> [    0.970353]    lock_acquire+0xf0/0x292
> [    0.970482]    _raw_spin_lock+0x2c/0x40
> [    0.970609]    plic_irq_enable+0x7e/0x140
> [    0.970739]    irq_enable+0x2c/0x60
> [    0.970882]    __irq_startup+0x58/0x60
> [    0.971008]    irq_startup+0x5e/0x13c
> [    0.971126]    __setup_irq+0x4de/0x5da
> [    0.971248]    request_threaded_irq+0xcc/0x12e
> [    0.971394]    vm_find_vqs+0x62/0x50a
> [    0.971518]    probe_common+0xfe/0x1d2
> [    0.971635]    virtrng_probe+0xc/0x14
> [    0.971751]    virtio_dev_probe+0x154/0x1fc
> [    0.971878]    really_probe+0x82/0x210
> [    0.972008]    __driver_probe_device+0x5c/0xd0
> [    0.972147]    driver_probe_device+0x2c/0xb0
> [    0.972280]    __driver_attach+0x72/0x10a
> [    0.972407]    bus_for_each_dev+0x60/0xac
> [    0.972540]    driver_attach+0x1a/0x22
> [    0.972656]    bus_add_driver+0xd4/0x19e
> [    0.972777]    driver_register+0x3e/0xd8
> [    0.972896]    register_virtio_driver+0x1c/0x2a
> [    0.973049]    virtio_rng_driver_init+0x18/0x20
> [    0.973236]    do_one_initcall+0x80/0x268
> [    0.973399]    kernel_init_freeable+0x296/0x300
> [    0.973540]    kernel_init+0x1e/0x10a
> [    0.973658]    ret_from_fork+0xe/0x1c
>
> [    0.973858] -> (&irq_desc_lock_class){-...}-{2:2} {
> [    0.974036]    IN-HARDIRQ-W at:
> [    0.974142]                     __lock_acquire+0xa82/0x1f5c
> [    0.974309]                     lock_acquire+0xf0/0x292
> [    0.974467]                     _raw_spin_lock+0x2c/0x40
> [    0.974625]                     handle_fasteoi_irq+0x24/0x1da
> [    0.974794]                     generic_handle_domain_irq+0x1c/0x2a
> [    0.974982]                     plic_handle_irq+0x7e/0xf0
> [    0.975143]                     generic_handle_domain_irq+0x1c/0x2a
> [    0.975329]                     riscv_intc_irq+0x2e/0x46
> [    0.975488]                     handle_riscv_irq+0x4a/0x74
> [    0.975652]                     call_on_irq_stack+0x32/0x40
> [    0.975817]    INITIAL USE at:
> [    0.975923]                    __lock_acquire+0x3fc/0x1f5c
> [    0.976087]                    lock_acquire+0xf0/0x292
> [    0.976244]                    _raw_spin_lock_irqsave+0x3a/0x64
> [    0.976423]                    __irq_get_desc_lock+0x5a/0x84
> [    0.976594]                    irq_modify_status+0x2a/0x106
> [    0.976764]                    irq_set_percpu_devid+0x62/0x78
> [    0.976939]                    riscv_intc_domain_map+0x1e/0x54
> [    0.977133]                    irq_domain_associate_locked+0x42/0xe4
> [    0.977363]                    irq_create_mapping_affinity+0x98/0xd4
> [    0.977570]                    sbi_ipi_init+0x70/0x142
> [    0.977744]                    init_IRQ+0xfe/0x11a
> [    0.977906]                    start_kernel+0x4ae/0x790
> [    0.978082]  }
> [    0.978151]  ... key      at: [<ffffffff824bbee0>] irq_desc_lock_class+0x0/0x10
> [    0.978389]  ... acquired at:
> [    0.978494]    mark_lock+0x3fe/0x8c2
> [    0.978624]    __lock_acquire+0xa82/0x1f5c
> [    0.978766]    lock_acquire+0xf0/0x292
> [    0.978897]    _raw_spin_lock+0x2c/0x40
> [    0.979029]    handle_fasteoi_irq+0x24/0x1da
> [    0.979171]    generic_handle_domain_irq+0x1c/0x2a
> [    0.979326]    plic_handle_irq+0x7e/0xf0
> [    0.979460]    generic_handle_domain_irq+0x1c/0x2a
> [    0.979618]    riscv_intc_irq+0x2e/0x46
> [    0.979751]    handle_riscv_irq+0x4a/0x74
> [    0.979888]    call_on_irq_stack+0x32/0x40
>
> [    0.980110]
>                stack backtrace:
> [    0.980358] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.8.0-rc1-00039-gd9b9d6eb987f #1122
> [    0.980662] Hardware name: riscv-virtio,qemu (DT)
> [    0.980913] Call Trace:
> [    0.981042] [<ffffffff80007198>] dump_backtrace+0x1c/0x24
> [    0.981246] [<ffffffff80ae020a>] show_stack+0x2c/0x38
> [    0.981456] [<ffffffff80aedac4>] dump_stack_lvl+0x5a/0x7c
> [    0.981648] [<ffffffff80aedafa>] dump_stack+0x14/0x1c
> [    0.981813] [<ffffffff80ae17a4>] print_irq_inversion_bug.part.0+0x162/0x176
> [    0.982031] [<ffffffff8007c6e6>] mark_lock+0x3fe/0x8c2
> [    0.982198] [<ffffffff8007d888>] __lock_acquire+0xa82/0x1f5c
> [    0.982377] [<ffffffff8007f59e>] lock_acquire+0xf0/0x292
> [    0.982549] [<ffffffff80af9962>] _raw_spin_lock+0x2c/0x40
> [    0.982721] [<ffffffff8008f3fe>] handle_fasteoi_irq+0x24/0x1da
> [    0.982904] [<ffffffff8008a4a4>] generic_handle_domain_irq+0x1c/0x2a
> [    0.983112] [<ffffffff80581dc0>] plic_handle_irq+0x7e/0xf0
> [    0.983293] [<ffffffff8008a4a4>] generic_handle_domain_irq+0x1c/0x2a
> [    0.983495] [<ffffffff8057fb1a>] riscv_intc_irq+0x2e/0x46
> [    0.983671] [<ffffffff80aedb4c>] handle_riscv_irq+0x4a/0x74
> [    0.983856] [<ffffffff80afa756>] call_on_irq_stack+0x32/0x40
>
>
> When I switch to -machine virt,aia=aplic-imsic (same config as above), I
> get:
>
> [    0.971406] ============================================
> [    0.971439] WARNING: possible recursive locking detected
> [    0.971497] 6.8.0-rc1-00039-gd9b9d6eb987f #1122 Not tainted
> [    0.971583] --------------------------------------------
> [    0.971612] swapper/0/1 is trying to acquire lock:
> [    0.971662] ffffaf83fefa8e78 (&lpriv->ids_lock){-...}-{2:2}, at: imsic_vector_move+0x92/0x146
> [    0.971927]
>                but task is already holding lock:
> [    0.971975] ffffaf83fef6ee78 (&lpriv->ids_lock){-...}-{2:2}, at: imsic_vector_move+0x86/0x146
> [    0.972045]
>                other info that might help us debug this:
> [    0.972085]  Possible unsafe locking scenario:
>
> [    0.972114]        CPU0
> [    0.972133]        ----
> [    0.972153]   lock(&lpriv->ids_lock);
> [    0.972191]   lock(&lpriv->ids_lock);
> [    0.972228]
>                 *** DEADLOCK ***
>
> [    0.972258]  May be due to missing lock nesting notation
>
> [    0.972306] 6 locks held by swapper/0/1:
> [    0.972338]  #0: ffffaf8081f65970 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x6a/0x10a
> [    0.972413]  #1: ffffaf808217c240 (&desc->request_mutex){+.+.}-{3:3}, at: __setup_irq+0xa2/0x5da
> [    0.972492]  #2: ffffaf808217c0c8 (&irq_desc_lock_class){....}-{2:2}, at: __setup_irq+0xbe/0x5da
> [    0.972555]  #3: ffffffff81892ac0 (mask_lock){....}-{2:2}, at: irq_setup_affinity+0x38/0xc6
> [    0.972617]  #4: ffffffff81892a80 (tmp_mask_lock){....}-{2:2}, at: irq_do_set_affinity+0x3a/0x164
> [    0.972681]  #5: ffffaf83fef6ee78 (&lpriv->ids_lock){-...}-{2:2}, at: imsic_vector_move+0x86/0x146
> [    0.972753]
>                stack backtrace:
> [    0.972852] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc1-00039-gd9b9d6eb987f #1122
> [    0.972900] Hardware name: riscv-virtio,qemu (DT)
> [    0.972987] Call Trace:
> [    0.973019] [<ffffffff80007198>] dump_backtrace+0x1c/0x24
> [    0.973054] [<ffffffff80ae020a>] show_stack+0x2c/0x38
> [    0.973083] [<ffffffff80aedac4>] dump_stack_lvl+0x5a/0x7c
> [    0.973112] [<ffffffff80aedafa>] dump_stack+0x14/0x1c
> [    0.973139] [<ffffffff8007ad5e>] print_deadlock_bug+0x282/0x328
> [    0.973168] [<ffffffff8007e15c>] __lock_acquire+0x1356/0x1f5c
> [    0.973198] [<ffffffff8007f59e>] lock_acquire+0xf0/0x292
> [    0.973225] [<ffffffff80af9adc>] _raw_spin_lock_irqsave+0x3a/0x64
> [    0.973255] [<ffffffff80581210>] imsic_vector_move+0x92/0x146
> [    0.973285] [<ffffffff80581a04>] imsic_irq_set_affinity+0x8e/0xc6
> [    0.973315] [<ffffffff8008c86a>] irq_do_set_affinity+0x142/0x164
> [    0.973345] [<ffffffff8008cc22>] irq_setup_affinity+0x68/0xc6
> [    0.973374] [<ffffffff8008fa82>] irq_startup+0x72/0x13c
> [    0.973401] [<ffffffff8008d40c>] __setup_irq+0x4de/0x5da
> [    0.973430] [<ffffffff8008d5d4>] request_threaded_irq+0xcc/0x12e
> [    0.973460] [<ffffffff806346d8>] vp_find_vqs_msix+0x114/0x376
> [    0.973491] [<ffffffff80634970>] vp_find_vqs+0x36/0x136
> [    0.973518] [<ffffffff80633280>] vp_modern_find_vqs+0x16/0x4e
> [    0.973547] [<ffffffff80ab31f8>] p9_virtio_probe+0x8e/0x31c
> [    0.973576] [<ffffffff8062d982>] virtio_dev_probe+0x154/0x1fc
> [    0.973605] [<ffffffff80693738>] really_probe+0x82/0x210
> [    0.973632] [<ffffffff80693922>] __driver_probe_device+0x5c/0xd0
> [    0.973661] [<ffffffff806939c2>] driver_probe_device+0x2c/0xb0
> [    0.973690] [<ffffffff80693b46>] __driver_attach+0x72/0x10a
> [    0.973718] [<ffffffff8069191a>] bus_for_each_dev+0x60/0xac
> [    0.973746] [<ffffffff80693164>] driver_attach+0x1a/0x22
> [    0.973773] [<ffffffff80692ade>] bus_add_driver+0xd4/0x19e
> [    0.973801] [<ffffffff8069487e>] driver_register+0x3e/0xd8
> [    0.973829] [<ffffffff8062d1ce>] register_virtio_driver+0x1c/0x2a
> [    0.973858] [<ffffffff80c3da52>] p9_virtio_init+0x36/0x56
> [    0.973887] [<ffffffff800028fe>] do_one_initcall+0x80/0x268
> [    0.973915] [<ffffffff80c01144>] kernel_init_freeable+0x296/0x300
> [    0.973944] [<ffffffff80af05dc>] kernel_init+0x1e/0x10a
> [    0.973972] [<ffffffff80afa716>] ret_from_fork+0xe/0x1c
>
>
> FWIW, the full Qemu command I used was as follows:
>
>         sudo /home/andrea/Downloads/qemu/build/qemu-system-riscv64 \
>                 -append "root=/dev/root rw rootfstype=9p rootflags=version=9p2000.L,trans=virtio,cache=mmap,access=any raid=noautodetect security=none loglevel=7" \
>                 -cpu rv64,sv57=off,svadu=off,svnapot=off \
>                 -device virtio-net-device,netdev=net0 \
>                 -device virtio-rng-device,rng=rng0 \
>                 -device virtio-9p-pci,fsdev=root,mount_tag=/dev/root \
>                 -fsdev local,id=root,path=/home/andrea/Downloads/jammy/,security_model=none \
>                 -kernel /home/andrea/linux/arch/riscv/boot/Image \
>                 -m 16G \
>                 -machine virt,aia=<either "none" or "aplic-imsic"> \
>                 -monitor telnet:127.0.0.1:55555,server,nowait \
>                 -netdev user,id=net0,host=10.0.2.10,hostfwd=tcp::10022-:22 \
>                 -nographic \
>                 -object rng-random,filename=/dev/urandom,id=rng0 \
>                 -serial mon:stdio \
>                 -smp 5
>
>
>   Andrea


From alexander.stein at ew.tq-group.com  Fri Feb 16 03:42:49 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 16 Feb 2024 12:42:49 +0100
Subject: [PATCH V8 09/12] dt-bindings: display: imx: add binding for i.MX8MP HDMI TX
In-Reply-To: <CAHCN7x+80iw0PWa4F4dMA=3RRaChNEO534LPACXd6FK0ndAHpw@mail.gmail.com>
References: <20240203165307.7806-1-aford173@gmail.com> <5916132.MhkbZ0Pkbq@steina-w> <CAHCN7x+80iw0PWa4F4dMA=3RRaChNEO534LPACXd6FK0ndAHpw@mail.gmail.com>
Message-ID: <2184519.Mh6RI2rZIc@steina-w>

Am Freitag, 16. Februar 2024, 12:31:12 CET schrieb Adam Ford:
> On Fri, Feb 16, 2024 at 3:05?AM Alexander Stein
> 
> <alexander.stein at ew.tq-group.com> wrote:
> > Hi all,
> > 
> > Am Samstag, 3. Februar 2024, 17:52:49 CET schrieb Adam Ford:
> > > From: Lucas Stach <l.stach at pengutronix.de>
> > > 
> > > The HDMI TX controller on the i.MX8MP SoC is a Synopsys designware IP
> > > core with a little bit of SoC integration around it.
> > > 
> > > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > > Signed-off-by: Adam Ford <aford173 at gmail.com>
> > > 
> > > ---
> > > V3:  Change name and location to better idenfity as a bridge and
> > > 
> > >      HDMI 2.0a transmitter
> > >      
> > >      Fix typos and feedback from Rob and added ports.
> > > 
> > > ---
> > > 
> > >  .../display/bridge/fsl,imx8mp-hdmi-tx.yaml    | 102 ++++++++++++++++++
> > >  1 file changed, 102 insertions(+)
> > >  create mode 100644
> > > 
> > > Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.yaml
> > > 
> > > diff --git
> > > a/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.ya
> > > ml
> > > b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.ya
> > > ml
> > > new file mode 100644
> > > index 000000000000..3791c9f4ebab
> > > --- /dev/null
> > > +++
> > > b/Documentation/devicetree/bindings/display/bridge/fsl,imx8mp-hdmi-tx.ya
> > > ml
> > > @@ -0,0 +1,102 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id:
> > > http://devicetree.org/schemas/display/bridge/fsl,imx8mp-hdmi-tx.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Freescale i.MX8MP DWC HDMI TX Encoder
> > > +
> > > +maintainers:
> > > +  - Lucas Stach <l.stach at pengutronix.de>
> > > +
> > > +description:
> > > +  The i.MX8MP HDMI transmitter is a Synopsys DesignWare
> > > +  HDMI 2.0a TX controller IP.
> > > +
> > > +allOf:
> > > +  - $ref: /schemas/display/bridge/synopsys,dw-hdmi.yaml#
> > > +
> > > +properties:
> > > +  compatible:
> > > +    enum:
> > > +      - fsl,imx8mp-hdmi-tx
> > > +
> > > +  reg-io-width:
> > > +    const: 1
> > > +
> > > +  clocks:
> > > +    maxItems: 4
> > > +
> > > +  clock-names:
> > > +    items:
> > > +      - const: iahb
> > > +      - const: isfr
> > > +      - const: cec
> > > +      - const: pix
> > > +
> > > +  power-domains:
> > > +    maxItems: 1
> > > +
> > > +  ports:
> > > +    $ref: /schemas/graph.yaml#/properties/ports
> > > +
> > > +    properties:
> > > +      port at 0:
> > > +        $ref: /schemas/graph.yaml#/properties/port
> > > +        description: Parallel RGB input port
> > > +
> > > +      port at 1:
> > > +        $ref: /schemas/graph.yaml#/properties/port
> > > +        description: HDMI output port
> > > +
> > > +    required:
> > > +      - port at 0
> > > +      - port at 1
> > 
> > Is this really correct that port at 1 is required? AFAICS this host already
> > supports HPD and DDC by itself, so there is no need for a dedicated HDMI
> > connector.
> > With the current state of the drivers this output port is completely
> > ignored anyway. Yet it works for a lot of people.
> 
> One of the feedback responses Lucas got was that it was missing the
> reference to the HDMI connector, so I added it as a response to that
> feedback.  I have tried device trees with and without it, and it
> doesn't impact anything, but It seems like there may be a requirement
> for it.

Yes, I noticed as well. A specified connector is completely ignored.
One reason is that dw_hdmi_plat_data.output_port is unsed in drivers/gpu/drm/
bridge/imx/imx8mp-hdmi-tx.c. Another one is that without 
DRM_BRIDGE_ATTACH_NO_CONNECTOR support in drivers/gpu/drm/mxsfb/lcdif_drv.c 
nothing changes.

Best regards,
Alexander

> adam
> 
> > Best regards,
> > Alexander
> > 
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - clocks
> > > +  - clock-names
> > > +  - interrupts
> > > +  - power-domains
> > > +  - ports
> > > +
> > > +unevaluatedProperties: false
> > > +
> > > +examples:
> > > +  - |
> > > +    #include <dt-bindings/clock/imx8mp-clock.h>
> > > +    #include <dt-bindings/interrupt-controller/irq.h>
> > > +    #include <dt-bindings/power/imx8mp-power.h>
> > > +
> > > +    hdmi at 32fd8000 {
> > > +        compatible = "fsl,imx8mp-hdmi-tx";
> > > +        reg = <0x32fd8000 0x7eff>;
> > > +        interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
> > > +        clocks = <&clk IMX8MP_CLK_HDMI_APB>,
> > > +                 <&clk IMX8MP_CLK_HDMI_REF_266M>,
> > > +                 <&clk IMX8MP_CLK_32K>,
> > > +                 <&hdmi_tx_phy>;
> > > +        clock-names = "iahb", "isfr", "cec", "pix";
> > > +        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
> > > +        reg-io-width = <1>;
> > > +        ports {
> > > +           #address-cells = <1>;
> > > +           #size-cells = <0>;
> > > +           port at 0 {
> > > +             reg = <0>;
> > > +
> > > +             hdmi_tx_from_pvi: endpoint {
> > > +               remote-endpoint = <&pvi_to_hdmi_tx>;
> > > +             };
> > > +          };
> > > +
> > > +          port at 1 {
> > > +            reg = <1>;
> > > +              hdmi_tx_out: endpoint {
> > > +                remote-endpoint = <&hdmi0_con>;
> > > +              };
> > > +          };
> > > +        };
> > > +    };
> > 
> > --
> > TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> > Amtsgericht M?nchen, HRB 105018
> > Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> > http://www.tq-group.com/


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From geert at linux-m68k.org  Fri Feb 16 03:46:48 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 16 Feb 2024 12:46:48 +0100
Subject: [PATCH] clk: constify the of_phandle_args argument of of_clk_provider
In-Reply-To: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
References: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CAMuHMdXzObEqExtJZpUpXLfCWB5fW9ZhekbbotcxcMrN+uj0Ag@mail.gmail.com>

On Thu, Feb 8, 2024 at 5:37?PM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
> None of the implementations of the get() and get_hw() callbacks of
> "struct of_clk_provider" modify the contents of received of_phandle_args
> pointer.  They treat it as read-only variable used to find the clock to
> return.  Make obvious that implementations are not supposed to modify
> the of_phandle_args, by making it a pointer to const.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

>  drivers/clk/renesas/r9a06g032-clocks.c        |  2 +-
>  drivers/clk/renesas/renesas-cpg-mssr.c        |  2 +-
>  drivers/clk/renesas/rzg2l-cpg.c               |  2 +-

Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

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 conor.dooley at microchip.com  Fri Feb 16 03:47:03 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Fri, 16 Feb 2024 11:47:03 +0000
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI
 TPS65224 PMIC
In-Reply-To: <e13627e2-9d8f-437d-afe4-d8bfcade2f6a@baylibre.com>
References: <20240209-blitz-fidgety-78469aa80d6d@spud>
 <20240214093106.86483-1-bhargav.r@ltts.com>
 <20240214-galley-dweller-1e9872229d80@spud>
 <7hil2r5556.fsf@baylibre.com>
 <20240214-depraved-unfunded-3f0b3d6bf3e2@spud>
 <e13627e2-9d8f-437d-afe4-d8bfcade2f6a@baylibre.com>
Message-ID: <20240216-chimp-endowment-e4c241e8e466@wendy>

On Fri, Feb 16, 2024 at 10:08:03AM +0100, Julien Panis wrote:
> On 2/14/24 18:45, Conor Dooley wrote:
> > On Wed, Feb 14, 2024 at 09:26:13AM -0800, Kevin Hilman wrote:
> > > Conor Dooley <conor at kernel.org> writes:
> > > > On Wed, Feb 14, 2024 at 03:01:06PM +0530, Bhargav Raviprakash wrote:
> > > > > On Fri 2/9/2024 10:41 PM, Conor Dooley wrote:
> > > > > > On Thu, Feb 08, 2024 at 04:23:33PM +0530, Bhargav Raviprakash wrote:
> > > > > > > TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
> > > > > > > regulators, it includes additional features like GPIOs, watchdog, ESMs
> > > > > > > (Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
> > > > > > > managing the state of the device.
> > > > > > > TPS6594 and TPS65224 have significant functional overlap.
> > > > > > What does "significant functional overlap" mean? Does one implement a
> > > > > > compatible subset of the other? I assume the answer is no, given there
> > > > > > seems to be some core looking registers at different addresses.
> > > > > The intention behind ?significant functional overlap? was meant to
> > > > > indicate a lot of the features between TPS6594 and TPS65224 overlap,
> > > > > while there are some features specific to TPS65224.
> > > > > There is compatibility between the PMIC register maps, I2C, PFSM,
> > > > > and other drivers even though there are some core registers at
> > > > > different addresses.
> > > > > 
> > > > > Would it be more appropriate to say the 2 devices are compatible and have
> > > > > sufficient feature overlap rather than significant functional overlap?
> > > > If core registers are at different addresses, then it is unlikely that
> > > > these devices are compatible.
> > > That's not necessarily true.  Hardware designers can sometimes be
> > > creative. :)
> > Hence "unlikely" in my mail :)
> 
> For tps6594 and tps65224, some core registers are at different adresses
> indeed, but the code is the same for both MFD I2C/SPI entry points. As an
> example, the way CRC is enabled is exactly the same, even if the bit that
> must be set belongs to different registers. tps65224 has more resources and
> it's as if HW designers had had to re-organize the way bits are distributed
> among the registers (due to a lack of space, so to speak).
> 
> That said, if we consider that these devices are not compatible, what does it
> imply concretely for the next version ? Does that mean that:
> 1) Only a new binding must be created, even if MFD drivers and most of child
> drivers will be re-used ? (then the binding would simply be duplicated, but
> the drivers would not)
> 2) A new binding and new MFD drivers must be created, even if most of child
> drivers will be re-used ? (then the binding and MFD drivers would simply be
> duplicated, but the child drivers would not)
> 3) A new binding and new drivers (MFD and child devices) must be created ?
> 4) Anything else ?

If they're not compatible the next version of this patch does not need
to change, so option 4 I guess.


-------------- 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/20240216/f4796d06/attachment.sig>

From conor.dooley at microchip.com  Fri Feb 16 03:47:41 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Fri, 16 Feb 2024 11:47:41 +0000
Subject: [RESEND PATCH v1 03/13] dt-bindings: mfd: ti,tps6594: Add TI
 TPS65224 PMIC
In-Reply-To: <20240208105343.1212902-4-bhargav.r@ltts.com>
References: <20240208105343.1212902-1-bhargav.r@ltts.com>
 <20240208105343.1212902-4-bhargav.r@ltts.com>
Message-ID: <20240216-prefix-shortly-74105965f88c@wendy>

On Thu, Feb 08, 2024 at 04:23:33PM +0530, Bhargav Raviprakash wrote:
> TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
> regulators, it includes additional features like GPIOs, watchdog, ESMs
> (Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
> managing the state of the device.

> TPS6594 and TPS65224 have significant functional overlap.

With this updated to mention what makes the devices incompatible,
Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> 
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> ---
>  Documentation/devicetree/bindings/mfd/ti,tps6594.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
> index 9d43376be..6341b6070 100644
> --- a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
> +++ b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
> @@ -21,6 +21,7 @@ properties:
>        - ti,lp8764-q1
>        - ti,tps6593-q1
>        - ti,tps6594-q1
> +      - ti,tps65224-q1
>  
>    reg:
>      description: I2C slave address or SPI chip select number.
> -- 
> 2.25.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/20240216/9fa7bc05/attachment.sig>

From smostafa at google.com  Fri Feb 16 03:55:21 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Fri, 16 Feb 2024 11:55:21 +0000
Subject: [RFC PATCH 03/45] iommu/io-pgtable: Move fmt into io_pgtable_cfg
In-Reply-To: <20230201125328.2186498-4-jean-philippe@linaro.org>
References: <20230201125328.2186498-1-jean-philippe@linaro.org>
 <20230201125328.2186498-4-jean-philippe@linaro.org>
Message-ID: <Zc9NKU18_uF4XHWY@google.com>

Hi Jean,

On Wed, Feb 01, 2023 at 12:52:47PM +0000, Jean-Philippe Brucker wrote:
> When passing the I/O pagetable configuration around and adding new
> operations, it will be slightly more convenient to have fmt be part of
> the config structure rather than a separate parameter.
> 
> Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
> ---
>  include/linux/io-pgtable.h                  |  8 +++----
>  drivers/gpu/drm/msm/msm_iommu.c             |  3 +--
>  drivers/gpu/drm/panfrost/panfrost_mmu.c     |  4 ++--
>  drivers/iommu/amd/iommu.c                   |  3 ++-
>  drivers/iommu/apple-dart.c                  |  4 ++--
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  3 ++-
>  drivers/iommu/arm/arm-smmu/arm-smmu.c       |  3 ++-
>  drivers/iommu/arm/arm-smmu/qcom_iommu.c     |  3 ++-
>  drivers/iommu/io-pgtable-arm-common.c       | 26 ++++++++++-----------
>  drivers/iommu/io-pgtable-arm-v7s.c          |  3 ++-
>  drivers/iommu/io-pgtable-arm.c              |  3 ++-
>  drivers/iommu/io-pgtable-dart.c             |  8 +++----
>  drivers/iommu/io-pgtable.c                  | 10 ++++----
>  drivers/iommu/ipmmu-vmsa.c                  |  4 ++--
>  drivers/iommu/msm_iommu.c                   |  3 ++-
>  drivers/iommu/mtk_iommu.c                   |  3 ++-
>  16 files changed, 47 insertions(+), 44 deletions(-)
> 
> diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
> index 1b7a44b35616..1b0c26241a78 100644
> --- a/include/linux/io-pgtable.h
> +++ b/include/linux/io-pgtable.h
> @@ -49,6 +49,7 @@ struct iommu_flush_ops {
>  /**
>   * struct io_pgtable_cfg - Configuration data for a set of page tables.
>   *
> + * @fmt	           Format used for these page tables
>   * @quirks:        A bitmap of hardware quirks that require some special
>   *                 action by the low-level page table allocator.
>   * @pgsize_bitmap: A bitmap of page sizes supported by this set of page
> @@ -62,6 +63,7 @@ struct iommu_flush_ops {
>   *                 page table walker.
>   */
>  struct io_pgtable_cfg {
> +	enum io_pgtable_fmt		fmt;
>  	/*
>  	 * IO_PGTABLE_QUIRK_ARM_NS: (ARM formats) Set NS and NSTABLE bits in
>  	 *	stage 1 PTEs, for hardware which insists on validating them
> @@ -171,15 +173,13 @@ struct io_pgtable_ops {
>  /**
>   * alloc_io_pgtable_ops() - Allocate a page table allocator for use by an IOMMU.
>   *
> - * @fmt:    The page table format.
>   * @cfg:    The page table configuration. This will be modified to represent
>   *          the configuration actually provided by the allocator (e.g. the
>   *          pgsize_bitmap may be restricted).
>   * @cookie: An opaque token provided by the IOMMU driver and passed back to
>   *          the callback routines in cfg->tlb.
>   */
> -struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
> -					    struct io_pgtable_cfg *cfg,
> +struct io_pgtable_ops *alloc_io_pgtable_ops(struct io_pgtable_cfg *cfg,
>  					    void *cookie);
>  
>  /**
> @@ -199,14 +199,12 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops);
>  /**
>   * struct io_pgtable - Internal structure describing a set of page tables.
>   *
> - * @fmt:    The page table format.
>   * @cookie: An opaque token provided by the IOMMU driver and passed back to
>   *          any callback routines.
>   * @cfg:    A copy of the page table configuration.
>   * @ops:    The page table operations in use for this set of page tables.
>   */
>  struct io_pgtable {
> -	enum io_pgtable_fmt	fmt;
>  	void			*cookie;
>  	struct io_pgtable_cfg	cfg;
>  	struct io_pgtable_ops	ops;
> diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
> index c2507582ecf3..e9c6f281e3dd 100644
> --- a/drivers/gpu/drm/msm/msm_iommu.c
> +++ b/drivers/gpu/drm/msm/msm_iommu.c
> @@ -258,8 +258,7 @@ struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent)
>  	ttbr0_cfg.quirks &= ~IO_PGTABLE_QUIRK_ARM_TTBR1;
>  	ttbr0_cfg.tlb = &null_tlb_ops;
>  
> -	pagetable->pgtbl_ops = alloc_io_pgtable_ops(ARM_64_LPAE_S1,
> -		&ttbr0_cfg, iommu->domain);
This seems to miss:
+	ttbr0_cfg.fmt = ARM_64_LPAE_S1;
> +	pagetable->pgtbl_ops = alloc_io_pgtable_ops(&ttbr0_cfg, iommu->domain);
>  
>  	if (!pagetable->pgtbl_ops) {
>  		kfree(pagetable);
> diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> index 4e83a1891f3e..31bdb5d46244 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
> @@ -622,6 +622,7 @@ struct panfrost_mmu *panfrost_mmu_ctx_create(struct panfrost_device *pfdev)
>  	mmu->as = -1;
>  
>  	mmu->pgtbl_cfg = (struct io_pgtable_cfg) {
> +		.fmt		= ARM_MALI_LPAE,
>  		.pgsize_bitmap	= SZ_4K | SZ_2M,
>  		.ias		= FIELD_GET(0xff, pfdev->features.mmu_features),
>  		.oas		= FIELD_GET(0xff00, pfdev->features.mmu_features),
> @@ -630,8 +631,7 @@ struct panfrost_mmu *panfrost_mmu_ctx_create(struct panfrost_device *pfdev)
>  		.iommu_dev	= pfdev->dev,
>  	};
>  
> -	mmu->pgtbl_ops = alloc_io_pgtable_ops(ARM_MALI_LPAE, &mmu->pgtbl_cfg,
> -					      mmu);
> +	mmu->pgtbl_ops = alloc_io_pgtable_ops(&mmu->pgtbl_cfg, mmu);
>  	if (!mmu->pgtbl_ops) {
>  		kfree(mmu);
>  		return ERR_PTR(-EINVAL);
> diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
> index cbeaab55c0db..7efb6b467041 100644
> --- a/drivers/iommu/amd/iommu.c
> +++ b/drivers/iommu/amd/iommu.c
> @@ -2072,7 +2072,8 @@ static struct protection_domain *protection_domain_alloc(unsigned int type)
>  	if (ret)
>  		goto out_err;
>  
> -	pgtbl_ops = alloc_io_pgtable_ops(pgtable, &domain->iop.pgtbl_cfg, domain);
> +	domain->iop.pgtbl_cfg.fmt = pgtable;
> +	pgtbl_ops = alloc_io_pgtable_ops(&domain->iop.pgtbl_cfg, domain);
>  	if (!pgtbl_ops) {
>  		domain_id_free(domain->id);
>  		goto out_err;
> diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
> index 4f4a323be0d0..571f948add7c 100644
> --- a/drivers/iommu/apple-dart.c
> +++ b/drivers/iommu/apple-dart.c
> @@ -427,6 +427,7 @@ static int apple_dart_finalize_domain(struct iommu_domain *domain,
>  	}
>  
>  	pgtbl_cfg = (struct io_pgtable_cfg){
> +		.fmt = dart->hw->fmt,
>  		.pgsize_bitmap = dart->pgsize,
>  		.ias = 32,
>  		.oas = dart->hw->oas,
> @@ -434,8 +435,7 @@ static int apple_dart_finalize_domain(struct iommu_domain *domain,
>  		.iommu_dev = dart->dev,
>  	};
>  
> -	dart_domain->pgtbl_ops =
> -		alloc_io_pgtable_ops(dart->hw->fmt, &pgtbl_cfg, domain);
> +	dart_domain->pgtbl_ops = alloc_io_pgtable_ops(&pgtbl_cfg, domain);
>  	if (!dart_domain->pgtbl_ops) {
>  		ret = -ENOMEM;
>  		goto done;
> 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 ab160198edd6..c033b23ca4b2 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2209,6 +2209,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain,
>  	}
>  
>  	pgtbl_cfg = (struct io_pgtable_cfg) {
> +		.fmt		= fmt,
>  		.pgsize_bitmap	= smmu->pgsize_bitmap,
>  		.ias		= ias,
>  		.oas		= oas,
> @@ -2217,7 +2218,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain,
>  		.iommu_dev	= smmu->dev,
>  	};
>  
> -	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
> +	pgtbl_ops = alloc_io_pgtable_ops(&pgtbl_cfg, smmu_domain);
>  	if (!pgtbl_ops)
>  		return -ENOMEM;
>  
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index 719fbca1fe52..f230d2ce977a 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -747,6 +747,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
>  		cfg->asid = cfg->cbndx;
>  
>  	pgtbl_cfg = (struct io_pgtable_cfg) {
> +		.fmt		= fmt,
>  		.pgsize_bitmap	= smmu->pgsize_bitmap,
>  		.ias		= ias,
>  		.oas		= oas,
> @@ -764,7 +765,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
>  	if (smmu_domain->pgtbl_quirks)
>  		pgtbl_cfg.quirks |= smmu_domain->pgtbl_quirks;
>  
> -	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
> +	pgtbl_ops = alloc_io_pgtable_ops(&pgtbl_cfg, smmu_domain);
>  	if (!pgtbl_ops) {
>  		ret = -ENOMEM;
>  		goto out_clear_smmu;
> diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> index 270c3d9128ba..65eb8bdcbe50 100644
> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> @@ -239,6 +239,7 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
>  		goto out_unlock;
>  
>  	pgtbl_cfg = (struct io_pgtable_cfg) {
> +		.fmt		= ARM_32_LPAE_S1,
>  		.pgsize_bitmap	= qcom_iommu_ops.pgsize_bitmap,
>  		.ias		= 32,
>  		.oas		= 40,
> @@ -249,7 +250,7 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
>  	qcom_domain->iommu = qcom_iommu;
>  	qcom_domain->fwspec = fwspec;
>  
> -	pgtbl_ops = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &pgtbl_cfg, qcom_domain);
> +	pgtbl_ops = alloc_io_pgtable_ops(&pgtbl_cfg, qcom_domain);
>  	if (!pgtbl_ops) {
>  		dev_err(qcom_iommu->dev, "failed to allocate pagetable ops\n");
>  		ret = -ENOMEM;
> diff --git a/drivers/iommu/io-pgtable-arm-common.c b/drivers/iommu/io-pgtable-arm-common.c
> index 7340b5096499..4b3a9ce806ea 100644
> --- a/drivers/iommu/io-pgtable-arm-common.c
> +++ b/drivers/iommu/io-pgtable-arm-common.c
> @@ -62,7 +62,7 @@ static void __arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
>  	size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
>  	int i;
>  
> -	if (data->iop.fmt != ARM_MALI_LPAE && lvl == ARM_LPAE_MAX_LEVELS - 1)
> +	if (data->iop.cfg.fmt != ARM_MALI_LPAE && lvl == ARM_LPAE_MAX_LEVELS - 1)
>  		pte |= ARM_LPAE_PTE_TYPE_PAGE;
>  	else
>  		pte |= ARM_LPAE_PTE_TYPE_BLOCK;
> @@ -82,7 +82,7 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
>  	int i;
>  
>  	for (i = 0; i < num_entries; i++)
> -		if (iopte_leaf(ptep[i], lvl, data->iop.fmt)) {
> +		if (iopte_leaf(ptep[i], lvl, data->iop.cfg.fmt)) {
>  			/* We require an unmap first */
>  			WARN_ON(!selftest_running);
>  			return -EEXIST;
> @@ -183,7 +183,7 @@ int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
>  		__arm_lpae_sync_pte(ptep, 1, cfg);
>  	}
>  
> -	if (pte && !iopte_leaf(pte, lvl, data->iop.fmt)) {
> +	if (pte && !iopte_leaf(pte, lvl, data->iop.cfg.fmt)) {
>  		cptep = iopte_deref(pte, data);
>  	} else if (pte) {
>  		/* We require an unmap first */
> @@ -201,8 +201,8 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
>  {
>  	arm_lpae_iopte pte;
>  
> -	if (data->iop.fmt == ARM_64_LPAE_S1 ||
> -	    data->iop.fmt == ARM_32_LPAE_S1) {
> +	if (data->iop.cfg.fmt == ARM_64_LPAE_S1 ||
> +	    data->iop.cfg.fmt == ARM_32_LPAE_S1) {
>  		pte = ARM_LPAE_PTE_nG;
>  		if (!(prot & IOMMU_WRITE) && (prot & IOMMU_READ))
>  			pte |= ARM_LPAE_PTE_AP_RDONLY;
> @@ -220,8 +220,8 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
>  	 * Note that this logic is structured to accommodate Mali LPAE
>  	 * having stage-1-like attributes but stage-2-like permissions.
>  	 */
> -	if (data->iop.fmt == ARM_64_LPAE_S2 ||
> -	    data->iop.fmt == ARM_32_LPAE_S2) {
> +	if (data->iop.cfg.fmt == ARM_64_LPAE_S2 ||
> +	    data->iop.cfg.fmt == ARM_32_LPAE_S2) {
>  		if (prot & IOMMU_MMIO)
>  			pte |= ARM_LPAE_PTE_MEMATTR_DEV;
>  		else if (prot & IOMMU_CACHE)
> @@ -243,7 +243,7 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
>  	 * "outside the GPU" (i.e. either the Inner or System domain in CPU
>  	 * terms, depending on coherency).
>  	 */
> -	if (prot & IOMMU_CACHE && data->iop.fmt != ARM_MALI_LPAE)
> +	if (prot & IOMMU_CACHE && data->iop.cfg.fmt != ARM_MALI_LPAE)
>  		pte |= ARM_LPAE_PTE_SH_IS;
>  	else
>  		pte |= ARM_LPAE_PTE_SH_OS;
> @@ -254,7 +254,7 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
>  	if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)
>  		pte |= ARM_LPAE_PTE_NS;
>  
> -	if (data->iop.fmt != ARM_MALI_LPAE)
> +	if (data->iop.cfg.fmt != ARM_MALI_LPAE)
>  		pte |= ARM_LPAE_PTE_AF;
>  
>  	return pte;
> @@ -317,7 +317,7 @@ void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
>  	while (ptep != end) {
>  		arm_lpae_iopte pte = *ptep++;
>  
> -		if (!pte || iopte_leaf(pte, lvl, data->iop.fmt))
> +		if (!pte || iopte_leaf(pte, lvl, data->iop.cfg.fmt))
>  			continue;
>  
>  		__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
> @@ -417,7 +417,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
>  
>  			__arm_lpae_clear_pte(ptep, &iop->cfg);
>  
> -			if (!iopte_leaf(pte, lvl, iop->fmt)) {
> +			if (!iopte_leaf(pte, lvl, iop->cfg.fmt)) {
>  				/* Also flush any partial walks */
>  				io_pgtable_tlb_flush_walk(iop, iova + i * size, size,
>  							  ARM_LPAE_GRANULE(data));
> @@ -431,7 +431,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
>  		}
>  
>  		return i * size;
> -	} else if (iopte_leaf(pte, lvl, iop->fmt)) {
> +	} else if (iopte_leaf(pte, lvl, iop->cfg.fmt)) {
>  		/*
>  		 * Insert a table at the next level to map the old region,
>  		 * minus the part we want to unmap
> @@ -487,7 +487,7 @@ phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
>  			return 0;
>  
>  		/* Leaf entry? */
> -		if (iopte_leaf(pte, lvl, data->iop.fmt))
> +		if (iopte_leaf(pte, lvl, data->iop.cfg.fmt))
>  			goto found_translation;
>  
>  		/* Take it to the next level */
> diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
> index 75f244a3e12d..278b4299d757 100644
> --- a/drivers/iommu/io-pgtable-arm-v7s.c
> +++ b/drivers/iommu/io-pgtable-arm-v7s.c
> @@ -930,6 +930,7 @@ static int __init arm_v7s_do_selftests(void)
>  {
>  	struct io_pgtable_ops *ops;
>  	struct io_pgtable_cfg cfg = {
> +		.fmt = ARM_V7S,
>  		.tlb = &dummy_tlb_ops,
>  		.oas = 32,
>  		.ias = 32,
> @@ -945,7 +946,7 @@ static int __init arm_v7s_do_selftests(void)
>  
>  	cfg_cookie = &cfg;
>  
> -	ops = alloc_io_pgtable_ops(ARM_V7S, &cfg, &cfg);
> +	ops = alloc_io_pgtable_ops(&cfg, &cfg);
>  	if (!ops) {
>  		pr_err("selftest: failed to allocate io pgtable ops\n");
>  		return -EINVAL;
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index b2b188bb86b3..b76b903400de 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -319,7 +319,8 @@ static int __init arm_lpae_run_tests(struct io_pgtable_cfg *cfg)
>  
>  	for (i = 0; i < ARRAY_SIZE(fmts); ++i) {
>  		cfg_cookie = cfg;
> -		ops = alloc_io_pgtable_ops(fmts[i], cfg, cfg);
> +		cfg->fmt = fmts[i];
> +		ops = alloc_io_pgtable_ops(cfg, cfg);
>  		if (!ops) {
>  			pr_err("selftest: failed to allocate io pgtable ops\n");
>  			return -ENOMEM;
> diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c
> index 74b1ef2b96be..f981b25d8c98 100644
> --- a/drivers/iommu/io-pgtable-dart.c
> +++ b/drivers/iommu/io-pgtable-dart.c
> @@ -81,7 +81,7 @@ static dart_iopte paddr_to_iopte(phys_addr_t paddr,
>  {
>  	dart_iopte pte;
>  
> -	if (data->iop.fmt == APPLE_DART)
> +	if (data->iop.cfg.fmt == APPLE_DART)
>  		return paddr & APPLE_DART1_PADDR_MASK;
>  
>  	/* format is APPLE_DART2 */
> @@ -96,7 +96,7 @@ static phys_addr_t iopte_to_paddr(dart_iopte pte,
>  {
>  	u64 paddr;
>  
> -	if (data->iop.fmt == APPLE_DART)
> +	if (data->iop.cfg.fmt == APPLE_DART)
>  		return pte & APPLE_DART1_PADDR_MASK;
>  
>  	/* format is APPLE_DART2 */
> @@ -215,13 +215,13 @@ static dart_iopte dart_prot_to_pte(struct dart_io_pgtable *data,
>  {
>  	dart_iopte pte = 0;
>  
> -	if (data->iop.fmt == APPLE_DART) {
> +	if (data->iop.cfg.fmt == APPLE_DART) {
>  		if (!(prot & IOMMU_WRITE))
>  			pte |= APPLE_DART1_PTE_PROT_NO_WRITE;
>  		if (!(prot & IOMMU_READ))
>  			pte |= APPLE_DART1_PTE_PROT_NO_READ;
>  	}
> -	if (data->iop.fmt == APPLE_DART2) {
> +	if (data->iop.cfg.fmt == APPLE_DART2) {
>  		if (!(prot & IOMMU_WRITE))
>  			pte |= APPLE_DART2_PTE_PROT_NO_WRITE;
>  		if (!(prot & IOMMU_READ))
> diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c
> index b843fcd365d2..79e459f95012 100644
> --- a/drivers/iommu/io-pgtable.c
> +++ b/drivers/iommu/io-pgtable.c
> @@ -34,17 +34,16 @@ io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = {
>  #endif
>  };
>  
> -struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
> -					    struct io_pgtable_cfg *cfg,
> +struct io_pgtable_ops *alloc_io_pgtable_ops(struct io_pgtable_cfg *cfg,
>  					    void *cookie)
>  {
>  	struct io_pgtable *iop;
>  	const struct io_pgtable_init_fns *fns;
>  
> -	if (fmt >= IO_PGTABLE_NUM_FMTS)
> +	if (cfg->fmt >= IO_PGTABLE_NUM_FMTS)
>  		return NULL;
>  
> -	fns = io_pgtable_init_table[fmt];
> +	fns = io_pgtable_init_table[cfg->fmt];
>  	if (!fns)
>  		return NULL;
>  
> @@ -52,7 +51,6 @@ struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
>  	if (!iop)
>  		return NULL;
>  
> -	iop->fmt	= fmt;
>  	iop->cookie	= cookie;
>  	iop->cfg	= *cfg;
>  
> @@ -73,6 +71,6 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops)
>  
>  	iop = io_pgtable_ops_to_pgtable(ops);
>  	io_pgtable_tlb_flush_all(iop);
> -	io_pgtable_init_table[iop->fmt]->free(iop);
> +	io_pgtable_init_table[iop->cfg.fmt]->free(iop);
>  }
>  EXPORT_SYMBOL_GPL(free_io_pgtable_ops);
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index a003bd5fc65c..4a1927489635 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -447,6 +447,7 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain)
>  	 */
>  	domain->cfg.coherent_walk = false;
>  	domain->cfg.iommu_dev = domain->mmu->root->dev;
> +	domain->cfg.fmt = ARM_32_LPAE_S1;
>  
>  	/*
>  	 * Find an unused context.
> @@ -457,8 +458,7 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain)
>  
>  	domain->context_id = ret;
>  
> -	domain->iop = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &domain->cfg,
> -					   domain);
> +	domain->iop = alloc_io_pgtable_ops(&domain->cfg, domain);
>  	if (!domain->iop) {
>  		ipmmu_domain_free_context(domain->mmu->root,
>  					  domain->context_id);
> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
> index c60624910872..2c05a84ec1bf 100644
> --- a/drivers/iommu/msm_iommu.c
> +++ b/drivers/iommu/msm_iommu.c
> @@ -342,6 +342,7 @@ static int msm_iommu_domain_config(struct msm_priv *priv)
>  	spin_lock_init(&priv->pgtlock);
>  
>  	priv->cfg = (struct io_pgtable_cfg) {
> +		.fmt = ARM_V7S,
>  		.pgsize_bitmap = msm_iommu_ops.pgsize_bitmap,
>  		.ias = 32,
>  		.oas = 32,
> @@ -349,7 +350,7 @@ static int msm_iommu_domain_config(struct msm_priv *priv)
>  		.iommu_dev = priv->dev,
>  	};
>  
> -	priv->iop = alloc_io_pgtable_ops(ARM_V7S, &priv->cfg, priv);
> +	priv->iop = alloc_io_pgtable_ops(&priv->cfg, priv);
>  	if (!priv->iop) {
>  		dev_err(priv->dev, "Failed to allocate pgtable\n");
>  		return -EINVAL;
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 2badd6acfb23..0d754d94ae52 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -598,6 +598,7 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
>  	}
>  
>  	dom->cfg = (struct io_pgtable_cfg) {
> +		.fmt = ARM_V7S,
>  		.quirks = IO_PGTABLE_QUIRK_ARM_NS |
>  			IO_PGTABLE_QUIRK_NO_PERMS |
>  			IO_PGTABLE_QUIRK_ARM_MTK_EXT,
> @@ -614,7 +615,7 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
>  	else
>  		dom->cfg.oas = 35;
>  
> -	dom->iop = alloc_io_pgtable_ops(ARM_V7S, &dom->cfg, data);
> +	dom->iop = alloc_io_pgtable_ops(&dom->cfg, data);
>  	if (!dom->iop) {
>  		dev_err(data->dev, "Failed to alloc io pgtable\n");
>  		return -ENOMEM;
> -- 
> 2.39.0
> 
Thanks,
Mostafa


From vkoul at kernel.org  Fri Feb 16 03:58:02 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 16 Feb 2024 17:28:02 +0530
Subject: [PATCH v4 0/2] Add support for RK3588 HDMI/eDP Combo PHY
In-Reply-To: <20240214-phy-hdptx-v4-0-e7974f46c1a7@collabora.com>
References: <20240214-phy-hdptx-v4-0-e7974f46c1a7@collabora.com>
Message-ID: <170808468224.352706.3107795890372449699.b4-ty@kernel.org>


On Wed, 14 Feb 2024 13:45:35 +0200, Cristian Ciocaltea wrote:
> Add driver and bindings to add initial support the Rockchip HDMI/eDP TX
> Combo PHY found on RK3588 SoC.
> 
> The PHY is based on a Samsung IP block and supports HDMI 2.1 TMDS, FRL
> and eDP links.
> 
> Please note that currently only the TMDS related functionality has been
> implemented.  This has been tested on Radxa ROCK 5B and Rockchip EVB1
> boards.
> 
> [...]

Applied, thanks!

[1/2] dt-bindings: phy: Add Rockchip HDMI/eDP Combo PHY schema
      commit: 3312a0e8f64ec68db695224fcc7457e7292426eb
[2/2] phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver
      commit: 553be2830c5f33308483e8118de748a2c69fe593

Best regards,
-- 
~Vinod




From will at kernel.org  Fri Feb 16 03:58:20 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 16 Feb 2024 11:58:20 +0000
Subject: [GIT PULL] arm64 fixes for -rc5
Message-ID: <20240216115819.GA1804@willie-the-truck>

Hi Linus,

Please pull these arm64 fixes for -rc5. It's a little busier than normal,
but it's still not a lot of code and things seem fairly quiet in general.

Summary in the tag.

Cheers,

Will

--->8

The following changes since commit 54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478:

  Linux 6.8-rc3 (2024-02-04 12:20:36 +0000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

for you to fetch changes up to 2813926261e436d33bc74486b51cce60b76edf78:

  arm64/sve: Lower the maximum allocation for the SVE ptrace regset (2024-02-15 11:48:00 +0000)

----------------------------------------------------------------
arm64 fixes for -rc5

- Fix allocation failure during SVE coredumps

- Fix handling of SVE context on signal delivery

- Enable Neoverse N2 CPU errata workarounds for Microsoft's
  "Azure Cobalt 100" clone

- Work around CMN PMU erratum in AmpereOneX implementation

- Fix typo in CXL PMU event definition

- Fix jump label asm constraints

----------------------------------------------------------------
Easwar Hariharan (1):
      arm64: Subscribe Microsoft Azure Cobalt 100 to ARM Neoverse N2 errata

Fangrui Song (1):
      arm64: jump_label: use constraints "Si" instead of "i"

Hojin Nam (1):
      perf: CXL: fix mismatched cpmu event opcode

Ilkka Koskinen (1):
      perf/arm-cmn: Workaround AmpereOneX errata AC04_MESH_1 (incorrect child count)

Mark Brown (2):
      arm64/signal: Don't assume that TIF_SVE means we saved SVE state
      arm64/sve: Lower the maximum allocation for the SVE ptrace regset

Seongsu Park (1):
      arm64: fix typo in comments

 Documentation/arch/arm64/silicon-errata.rst |  7 +++++++
 arch/arm64/include/asm/cpufeature.h         |  2 +-
 arch/arm64/include/asm/cputype.h            |  4 ++++
 arch/arm64/include/asm/fpsimd.h             | 12 ++++++------
 arch/arm64/include/asm/jump_label.h         | 12 ++++++++----
 arch/arm64/kernel/cpu_errata.c              |  3 +++
 arch/arm64/kernel/fpsimd.c                  |  2 +-
 arch/arm64/kernel/ptrace.c                  |  3 ++-
 arch/arm64/kernel/signal.c                  |  4 ++--
 drivers/perf/arm-cmn.c                      | 11 +++++++++++
 drivers/perf/cxl_pmu.c                      |  2 +-
 11 files changed, 46 insertions(+), 16 deletions(-)


From smostafa at google.com  Fri Feb 16 03:59:26 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Fri, 16 Feb 2024 11:59:26 +0000
Subject: [RFC PATCH 20/45] KVM: arm64: iommu: Add map() and unmap()
 operations
In-Reply-To: <20230201125328.2186498-21-jean-philippe@linaro.org>
References: <20230201125328.2186498-1-jean-philippe@linaro.org>
 <20230201125328.2186498-21-jean-philippe@linaro.org>
Message-ID: <Zc9OHq2NO3X7DsSO@google.com>

Hi Jean,

On Wed, Feb 01, 2023 at 12:53:04PM +0000, Jean-Philippe Brucker wrote:
> Handle map() and unmap() hypercalls by calling the io-pgtable library.
> 
> Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
> ---
>  arch/arm64/kvm/hyp/nvhe/iommu/iommu.c | 144 ++++++++++++++++++++++++++
>  1 file changed, 144 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
> index 7404ea77ed9f..0550e7bdf179 100644
> --- a/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
> +++ b/arch/arm64/kvm/hyp/nvhe/iommu/iommu.c
> @@ -183,6 +183,150 @@ int kvm_iommu_detach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
>  	return ret;
>  }
>  
> +static int __kvm_iommu_unmap_pages(struct io_pgtable *iopt, unsigned long iova,
> +				   size_t pgsize, size_t pgcount)
> +{
> +	int ret;
> +	size_t unmapped;
> +	phys_addr_t paddr;
> +	size_t total_unmapped = 0;
> +	size_t size = pgsize * pgcount;
> +
> +	while (total_unmapped < size) {
> +		paddr = iopt_iova_to_phys(iopt, iova);
> +		if (paddr == 0)
> +			return -EINVAL;
> +
> +		/*
> +		 * One page/block at a time, because the range provided may not
> +		 * be physically contiguous, and we need to unshare all physical
> +		 * pages.
> +		 */
> +		unmapped = iopt_unmap_pages(iopt, iova, pgsize, 1, NULL);
> +		if (!unmapped)
> +			return -EINVAL;
> +
> +		ret = __pkvm_host_unshare_dma(paddr, pgsize);
> +		if (ret)
> +			return ret;
> +
> +		iova += unmapped;
> +		pgcount -= unmapped / pgsize;
> +		total_unmapped += unmapped;
> +	}
> +
> +	return 0;
> +}
> +
> +#define IOMMU_PROT_MASK (IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE |\
> +			 IOMMU_NOEXEC | IOMMU_MMIO)
Is there a reason IOMMU_PRIV is not allowed?
> +
> +int kvm_iommu_map_pages(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
> +			unsigned long iova, phys_addr_t paddr, size_t pgsize,
> +			size_t pgcount, int prot)
> +{
> +	size_t size;
> +	size_t granule;
> +	int ret = -EINVAL;
> +	size_t mapped = 0;
> +	struct io_pgtable iopt;
> +	struct kvm_hyp_iommu *iommu;
> +	size_t pgcount_orig = pgcount;
> +	unsigned long iova_orig = iova;
> +	struct kvm_hyp_iommu_domain *domain;
> +
> +	if (prot & ~IOMMU_PROT_MASK)
> +		return -EINVAL;
> +
> +	if (__builtin_mul_overflow(pgsize, pgcount, &size) ||
> +	    iova + size < iova || paddr + size < paddr)
> +		return -EOVERFLOW;
> +
> +	hyp_spin_lock(&iommu_lock);
> +
> +	domain = handle_to_domain(iommu_id, domain_id, &iommu);
> +	if (!domain)
> +		goto err_unlock;
> +
> +	granule = 1 << __ffs(iommu->pgtable->cfg.pgsize_bitmap);
> +	if (!IS_ALIGNED(iova | paddr | pgsize, granule))
> +		goto err_unlock;
> +
> +	ret = __pkvm_host_share_dma(paddr, size, !(prot & IOMMU_MMIO));
> +	if (ret)
> +		goto err_unlock;
> +
> +	iopt = domain_to_iopt(iommu, domain, domain_id);
> +	while (pgcount) {
> +		ret = iopt_map_pages(&iopt, iova, paddr, pgsize, pgcount, prot,
> +				     0, &mapped);
> +		WARN_ON(!IS_ALIGNED(mapped, pgsize));
> +		pgcount -= mapped / pgsize;
> +		if (ret)
> +			goto err_unmap;
> +		iova += mapped;
> +		paddr += mapped;
> +	}
> +
> +	hyp_spin_unlock(&iommu_lock);
> +	return 0;
> +
> +err_unmap:
> +	__kvm_iommu_unmap_pages(&iopt, iova_orig, pgsize, pgcount_orig - pgcount);
> +err_unlock:
> +	hyp_spin_unlock(&iommu_lock);
> +	return ret;
> +}
> +
> +int kvm_iommu_unmap_pages(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
> +			  unsigned long iova, size_t pgsize, size_t pgcount)
> +{
> +	size_t size;
> +	size_t granule;
> +	int ret = -EINVAL;
> +	struct io_pgtable iopt;
> +	struct kvm_hyp_iommu *iommu;
> +	struct kvm_hyp_iommu_domain *domain;
> +
> +	if (__builtin_mul_overflow(pgsize, pgcount, &size) ||
> +	    iova + size < iova)
> +		return -EOVERFLOW;
> +
> +	hyp_spin_lock(&iommu_lock);
> +	domain = handle_to_domain(iommu_id, domain_id, &iommu);
> +	if (!domain)
> +		goto out_unlock;
> +
> +	granule = 1 << __ffs(iommu->pgtable->cfg.pgsize_bitmap);
> +	if (!IS_ALIGNED(iova | pgsize, granule))
> +		goto out_unlock;
> +
> +	iopt = domain_to_iopt(iommu, domain, domain_id);
> +	ret = __kvm_iommu_unmap_pages(&iopt, iova, pgsize, pgcount);
> +out_unlock:
> +	hyp_spin_unlock(&iommu_lock);
> +	return ret;
> +}
> +
> +phys_addr_t kvm_iommu_iova_to_phys(pkvm_handle_t iommu_id,
> +				   pkvm_handle_t domain_id, unsigned long iova)
> +{
> +	phys_addr_t phys = 0;
> +	struct io_pgtable iopt;
> +	struct kvm_hyp_iommu *iommu;
> +	struct kvm_hyp_iommu_domain *domain;
> +
> +	hyp_spin_lock(&iommu_lock);
> +	domain = handle_to_domain(iommu_id, domain_id, &iommu);
> +	if (domain) {
> +		iopt = domain_to_iopt(iommu, domain, domain_id);
> +
> +		phys = iopt_iova_to_phys(&iopt, iova);
> +	}
> +	hyp_spin_unlock(&iommu_lock);
> +	return phys;
> +}
> +
>  int kvm_iommu_init_device(struct kvm_hyp_iommu *iommu)
>  {
>  	void *domains;
> -- 
> 2.39.0
>
Thanks,
Mostafa


From patchwork-bot+netdevbpf at kernel.org  Fri Feb 16 04:00:26 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 16 Feb 2024 12:00:26 +0000
Subject: [PATCH net-next v2] net: ti: icssg-prueth: Remove duplicate cleanup
 calls in emac_ndo_stop()
In-Reply-To: <20240215152203.431268-1-diogo.ivo@siemens.com>
References: <20240215152203.431268-1-diogo.ivo@siemens.com>
Message-ID: <170808482698.6309.10803815782224916695.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by David S. Miller <davem at davemloft.net>:

On Thu, 15 Feb 2024 15:22:01 +0000 you wrote:
> Remove the duplicate calls to prueth_emac_stop() and
> prueth_cleanup_tx_chns() in emac_ndo_stop().
> 
> Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
> Reviewed-by: Roger Quadros <rogerq at kernel.org>
> Reviewed-by: MD Danish Anwar <danishanwar at ti.com>
> 
> [...]

Here is the summary with links:
  - [net-next,v2] net: ti: icssg-prueth: Remove duplicate cleanup calls in emac_ndo_stop()
    https://git.kernel.org/netdev/net-next/c/1d085e9ce384

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From smostafa at google.com  Fri Feb 16 04:03:41 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Fri, 16 Feb 2024 12:03:41 +0000
Subject: [RFC PATCH 30/45] iommu/arm-smmu-v3: Move queue and table
 allocation to arm-smmu-v3-common.c
In-Reply-To: <20230201125328.2186498-31-jean-philippe@linaro.org>
References: <20230201125328.2186498-1-jean-philippe@linaro.org>
 <20230201125328.2186498-31-jean-philippe@linaro.org>
Message-ID: <Zc9PHXEn3IKFlzXZ@google.com>

Hi Jean,

On Wed, Feb 01, 2023 at 12:53:14PM +0000, Jean-Philippe Brucker wrote:
> Move more code to arm-smmu-v3-common.c, so that the KVM driver can reuse
> it.
> 
> Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |   8 +
>  .../arm/arm-smmu-v3/arm-smmu-v3-common.c      | 190 ++++++++++++++++
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 215 ++----------------
>  3 files changed, 219 insertions(+), 194 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index 59e8101d4ff5..8ab84282f62a 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -277,6 +277,14 @@ bool arm_smmu_capable(struct device *dev, enum iommu_cap cap);
>  struct iommu_group *arm_smmu_device_group(struct device *dev);
>  int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args);
>  int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu);
> +int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
> +			    struct arm_smmu_queue *q,
> +			    void __iomem *page,
> +			    unsigned long prod_off,
> +			    unsigned long cons_off,
> +			    size_t dwords, const char *name);
> +int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid);
I see this is not used by the KVM driver, so it is not needed in the
common file?

> +int arm_smmu_init_strtab(struct arm_smmu_device *smmu);
>  
>  int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
>  			    struct arm_smmu_ctx_desc *cd);
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-common.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-common.c
> index 5e43329c0826..9226971b6e53 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-common.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-common.c
> @@ -294,3 +294,193 @@ int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
>  {
>  	return iommu_fwspec_add_ids(dev, args->args, 1);
>  }
> +
> +int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
> +			    struct arm_smmu_queue *q,
> +			    void __iomem *page,
> +			    unsigned long prod_off,
> +			    unsigned long cons_off,
> +			    size_t dwords, const char *name)
> +{
> +	size_t qsz;
> +
> +	do {
> +		qsz = ((1 << q->llq.max_n_shift) * dwords) << 3;
> +		q->base = dmam_alloc_coherent(smmu->dev, qsz, &q->base_dma,
> +					      GFP_KERNEL);
> +		if (q->base || qsz < PAGE_SIZE)
> +			break;
> +
> +		q->llq.max_n_shift--;
> +	} while (1);
> +
> +	if (!q->base) {
> +		dev_err(smmu->dev,
> +			"failed to allocate queue (0x%zx bytes) for %s\n",
> +			qsz, name);
> +		return -ENOMEM;
> +	}
> +
> +	if (!WARN_ON(q->base_dma & (qsz - 1))) {
> +		dev_info(smmu->dev, "allocated %u entries for %s\n",
> +			 1 << q->llq.max_n_shift, name);
> +	}
> +
> +	q->prod_reg	= page + prod_off;
> +	q->cons_reg	= page + cons_off;
> +	q->ent_dwords	= dwords;
> +
> +	q->q_base  = Q_BASE_RWA;
> +	q->q_base |= q->base_dma & Q_BASE_ADDR_MASK;
> +	q->q_base |= FIELD_PREP(Q_BASE_LOG2SIZE, q->llq.max_n_shift);
> +
> +	q->llq.prod = q->llq.cons = 0;
> +	return 0;
> +}
> +
> +/* Stream table initialization functions */
> +static void
> +arm_smmu_write_strtab_l1_desc(__le64 *dst, struct arm_smmu_strtab_l1_desc *desc)
> +{
> +	u64 val = 0;
> +
> +	val |= FIELD_PREP(STRTAB_L1_DESC_SPAN, desc->span);
> +	val |= desc->l2ptr_dma & STRTAB_L1_DESC_L2PTR_MASK;
> +
> +	/* Ensure the SMMU sees a zeroed table after reading this pointer */
> +	WRITE_ONCE(*dst, cpu_to_le64(val));
> +}
> +
> +int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
> +{
> +	size_t size;
> +	void *strtab;
> +	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> +	struct arm_smmu_strtab_l1_desc *desc = &cfg->l1_desc[sid >> STRTAB_SPLIT];
> +
> +	if (desc->l2ptr)
> +		return 0;
> +
> +	size = 1 << (STRTAB_SPLIT + ilog2(STRTAB_STE_DWORDS) + 3);
> +	strtab = &cfg->strtab[(sid >> STRTAB_SPLIT) * STRTAB_L1_DESC_DWORDS];
> +
> +	desc->span = STRTAB_SPLIT + 1;
> +	desc->l2ptr = dmam_alloc_coherent(smmu->dev, size, &desc->l2ptr_dma,
> +					  GFP_KERNEL);
> +	if (!desc->l2ptr) {
> +		dev_err(smmu->dev,
> +			"failed to allocate l2 stream table for SID %u\n",
> +			sid);
> +		return -ENOMEM;
> +	}
> +
> +	arm_smmu_write_strtab_l1_desc(strtab, desc);
> +	return 0;
> +}
> +
> +static int arm_smmu_init_l1_strtab(struct arm_smmu_device *smmu)
> +{
> +	unsigned int i;
> +	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> +	void *strtab = smmu->strtab_cfg.strtab;
> +
> +	cfg->l1_desc = devm_kcalloc(smmu->dev, cfg->num_l1_ents,
> +				    sizeof(*cfg->l1_desc), GFP_KERNEL);
> +	if (!cfg->l1_desc)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < cfg->num_l1_ents; ++i) {
> +		arm_smmu_write_strtab_l1_desc(strtab, &cfg->l1_desc[i]);
> +		strtab += STRTAB_L1_DESC_DWORDS << 3;
> +	}
> +
> +	return 0;
> +}
> +
> +static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
> +{
> +	void *strtab;
> +	u64 reg;
> +	u32 size, l1size;
> +	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> +
> +	/* Calculate the L1 size, capped to the SIDSIZE. */
> +	size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3);
> +	size = min(size, smmu->sid_bits - STRTAB_SPLIT);
> +	cfg->num_l1_ents = 1 << size;
> +
> +	size += STRTAB_SPLIT;
> +	if (size < smmu->sid_bits)
> +		dev_warn(smmu->dev,
> +			 "2-level strtab only covers %u/%u bits of SID\n",
> +			 size, smmu->sid_bits);
> +
> +	l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
> +	strtab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
> +				     GFP_KERNEL);
> +	if (!strtab) {
> +		dev_err(smmu->dev,
> +			"failed to allocate l1 stream table (%u bytes)\n",
> +			l1size);
> +		return -ENOMEM;
> +	}
> +	cfg->strtab = strtab;
> +
> +	/* Configure strtab_base_cfg for 2 levels */
> +	reg  = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_2LVL);
> +	reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, size);
> +	reg |= FIELD_PREP(STRTAB_BASE_CFG_SPLIT, STRTAB_SPLIT);
> +	cfg->strtab_base_cfg = reg;
> +
> +	return arm_smmu_init_l1_strtab(smmu);
> +}
> +
> +static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
> +{
> +	void *strtab;
> +	u64 reg;
> +	u32 size;
> +	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> +
> +	size = (1 << smmu->sid_bits) * (STRTAB_STE_DWORDS << 3);
> +	strtab = dmam_alloc_coherent(smmu->dev, size, &cfg->strtab_dma,
> +				     GFP_KERNEL);
> +	if (!strtab) {
> +		dev_err(smmu->dev,
> +			"failed to allocate linear stream table (%u bytes)\n",
> +			size);
> +		return -ENOMEM;
> +	}
> +	cfg->strtab = strtab;
> +	cfg->num_l1_ents = 1 << smmu->sid_bits;
> +
> +	/* Configure strtab_base_cfg for a linear table covering all SIDs */
> +	reg  = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_LINEAR);
> +	reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits);
> +	cfg->strtab_base_cfg = reg;
> +
> +	return 0;
> +}
> +
> +int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
> +{
> +	u64 reg;
> +	int ret;
> +
> +	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
> +		ret = arm_smmu_init_strtab_2lvl(smmu);
> +	else
> +		ret = arm_smmu_init_strtab_linear(smmu);
> +
> +	if (ret)
> +		return ret;
> +
> +	/* Set the strtab base address */
> +	reg  = smmu->strtab_cfg.strtab_dma & STRTAB_BASE_ADDR_MASK;
> +	reg |= STRTAB_BASE_RA;
> +	smmu->strtab_cfg.strtab_base = reg;
> +
> +	/* Allocate the first VMID for stage-2 bypass STEs */
> +	set_bit(0, smmu->vmid_map);
> +	return 0;
> +}
> 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 08fd79f66d29..2baaf064a324 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1209,18 +1209,6 @@ bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd)
>  }
>  
>  /* Stream table manipulation functions */
> -static void
> -arm_smmu_write_strtab_l1_desc(__le64 *dst, struct arm_smmu_strtab_l1_desc *desc)
> -{
> -	u64 val = 0;
> -
> -	val |= FIELD_PREP(STRTAB_L1_DESC_SPAN, desc->span);
> -	val |= desc->l2ptr_dma & STRTAB_L1_DESC_L2PTR_MASK;
> -
> -	/* See comment in arm_smmu_write_ctx_desc() */
> -	WRITE_ONCE(*dst, cpu_to_le64(val));
> -}
> -
>  static void arm_smmu_sync_ste_for_sid(struct arm_smmu_device *smmu, u32 sid)
>  {
>  	struct arm_smmu_cmdq_ent cmd = {
> @@ -1395,34 +1383,6 @@ static void arm_smmu_init_bypass_stes(__le64 *strtab, unsigned int nent, bool fo
>  	}
>  }
>  
> -static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
> -{
> -	size_t size;
> -	void *strtab;
> -	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> -	struct arm_smmu_strtab_l1_desc *desc = &cfg->l1_desc[sid >> STRTAB_SPLIT];
> -
> -	if (desc->l2ptr)
> -		return 0;
> -
> -	size = 1 << (STRTAB_SPLIT + ilog2(STRTAB_STE_DWORDS) + 3);
> -	strtab = &cfg->strtab[(sid >> STRTAB_SPLIT) * STRTAB_L1_DESC_DWORDS];
> -
> -	desc->span = STRTAB_SPLIT + 1;
> -	desc->l2ptr = dmam_alloc_coherent(smmu->dev, size, &desc->l2ptr_dma,
> -					  GFP_KERNEL);
> -	if (!desc->l2ptr) {
> -		dev_err(smmu->dev,
> -			"failed to allocate l2 stream table for SID %u\n",
> -			sid);
> -		return -ENOMEM;
> -	}
> -
> -	arm_smmu_init_bypass_stes(desc->l2ptr, 1 << STRTAB_SPLIT, false);
> -	arm_smmu_write_strtab_l1_desc(strtab, desc);
> -	return 0;
> -}
> -
>  static struct arm_smmu_master *
>  arm_smmu_find_master(struct arm_smmu_device *smmu, u32 sid)
>  {
> @@ -2515,13 +2475,24 @@ static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
>  
>  static int arm_smmu_init_sid_strtab(struct arm_smmu_device *smmu, u32 sid)
>  {
> +	int ret;
> +
>  	/* Check the SIDs are in range of the SMMU and our stream table */
>  	if (!arm_smmu_sid_in_range(smmu, sid))
>  		return -ERANGE;
>  
>  	/* Ensure l2 strtab is initialised */
> -	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
> -		return arm_smmu_init_l2_strtab(smmu, sid);
> +	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
> +		struct arm_smmu_strtab_l1_desc *desc;
> +
> +		ret = arm_smmu_init_l2_strtab(smmu, sid);
> +		if (ret)
> +			return ret;
> +
> +		desc = &smmu->strtab_cfg.l1_desc[sid >> STRTAB_SPLIT];
> +		arm_smmu_init_bypass_stes(desc->l2ptr, 1 << STRTAB_SPLIT,
> +					  false);
> +	}
>  
>  	return 0;
>  }
> @@ -2821,49 +2792,6 @@ static struct iommu_ops arm_smmu_ops = {
>  };
>  
>  /* Probing and initialisation functions */
> -static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
> -				   struct arm_smmu_queue *q,
> -				   void __iomem *page,
> -				   unsigned long prod_off,
> -				   unsigned long cons_off,
> -				   size_t dwords, const char *name)
> -{
> -	size_t qsz;
> -
> -	do {
> -		qsz = ((1 << q->llq.max_n_shift) * dwords) << 3;
> -		q->base = dmam_alloc_coherent(smmu->dev, qsz, &q->base_dma,
> -					      GFP_KERNEL);
> -		if (q->base || qsz < PAGE_SIZE)
> -			break;
> -
> -		q->llq.max_n_shift--;
> -	} while (1);
> -
> -	if (!q->base) {
> -		dev_err(smmu->dev,
> -			"failed to allocate queue (0x%zx bytes) for %s\n",
> -			qsz, name);
> -		return -ENOMEM;
> -	}
> -
> -	if (!WARN_ON(q->base_dma & (qsz - 1))) {
> -		dev_info(smmu->dev, "allocated %u entries for %s\n",
> -			 1 << q->llq.max_n_shift, name);
> -	}
> -
> -	q->prod_reg	= page + prod_off;
> -	q->cons_reg	= page + cons_off;
> -	q->ent_dwords	= dwords;
> -
> -	q->q_base  = Q_BASE_RWA;
> -	q->q_base |= q->base_dma & Q_BASE_ADDR_MASK;
> -	q->q_base |= FIELD_PREP(Q_BASE_LOG2SIZE, q->llq.max_n_shift);
> -
> -	q->llq.prod = q->llq.cons = 0;
> -	return 0;
> -}
> -
>  static int arm_smmu_cmdq_init(struct arm_smmu_device *smmu)
>  {
>  	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
> @@ -2918,114 +2846,6 @@ static int arm_smmu_init_queues(struct arm_smmu_device *smmu)
>  				       PRIQ_ENT_DWORDS, "priq");
>  }
>  
> -static int arm_smmu_init_l1_strtab(struct arm_smmu_device *smmu)
> -{
> -	unsigned int i;
> -	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> -	void *strtab = smmu->strtab_cfg.strtab;
> -
> -	cfg->l1_desc = devm_kcalloc(smmu->dev, cfg->num_l1_ents,
> -				    sizeof(*cfg->l1_desc), GFP_KERNEL);
> -	if (!cfg->l1_desc)
> -		return -ENOMEM;
> -
> -	for (i = 0; i < cfg->num_l1_ents; ++i) {
> -		arm_smmu_write_strtab_l1_desc(strtab, &cfg->l1_desc[i]);
> -		strtab += STRTAB_L1_DESC_DWORDS << 3;
> -	}
> -
> -	return 0;
> -}
> -
> -static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
> -{
> -	void *strtab;
> -	u64 reg;
> -	u32 size, l1size;
> -	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> -
> -	/* Calculate the L1 size, capped to the SIDSIZE. */
> -	size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3);
> -	size = min(size, smmu->sid_bits - STRTAB_SPLIT);
> -	cfg->num_l1_ents = 1 << size;
> -
> -	size += STRTAB_SPLIT;
> -	if (size < smmu->sid_bits)
> -		dev_warn(smmu->dev,
> -			 "2-level strtab only covers %u/%u bits of SID\n",
> -			 size, smmu->sid_bits);
> -
> -	l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
> -	strtab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
> -				     GFP_KERNEL);
> -	if (!strtab) {
> -		dev_err(smmu->dev,
> -			"failed to allocate l1 stream table (%u bytes)\n",
> -			l1size);
> -		return -ENOMEM;
> -	}
> -	cfg->strtab = strtab;
> -
> -	/* Configure strtab_base_cfg for 2 levels */
> -	reg  = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_2LVL);
> -	reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, size);
> -	reg |= FIELD_PREP(STRTAB_BASE_CFG_SPLIT, STRTAB_SPLIT);
> -	cfg->strtab_base_cfg = reg;
> -
> -	return arm_smmu_init_l1_strtab(smmu);
> -}
> -
> -static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
> -{
> -	void *strtab;
> -	u64 reg;
> -	u32 size;
> -	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> -
> -	size = (1 << smmu->sid_bits) * (STRTAB_STE_DWORDS << 3);
> -	strtab = dmam_alloc_coherent(smmu->dev, size, &cfg->strtab_dma,
> -				     GFP_KERNEL);
> -	if (!strtab) {
> -		dev_err(smmu->dev,
> -			"failed to allocate linear stream table (%u bytes)\n",
> -			size);
> -		return -ENOMEM;
> -	}
> -	cfg->strtab = strtab;
> -	cfg->num_l1_ents = 1 << smmu->sid_bits;
> -
> -	/* Configure strtab_base_cfg for a linear table covering all SIDs */
> -	reg  = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_LINEAR);
> -	reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits);
> -	cfg->strtab_base_cfg = reg;
> -
> -	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents, false);
> -	return 0;
> -}
> -
> -static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
> -{
> -	u64 reg;
> -	int ret;
> -
> -	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
> -		ret = arm_smmu_init_strtab_2lvl(smmu);
> -	else
> -		ret = arm_smmu_init_strtab_linear(smmu);
> -
> -	if (ret)
> -		return ret;
> -
> -	/* Set the strtab base address */
> -	reg  = smmu->strtab_cfg.strtab_dma & STRTAB_BASE_ADDR_MASK;
> -	reg |= STRTAB_BASE_RA;
> -	smmu->strtab_cfg.strtab_base = reg;
> -
> -	/* Allocate the first VMID for stage-2 bypass STEs */
> -	set_bit(0, smmu->vmid_map);
> -	return 0;
> -}
> -
>  static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
>  {
>  	int ret;
> @@ -3037,7 +2857,14 @@ static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
>  	if (ret)
>  		return ret;
>  
> -	return arm_smmu_init_strtab(smmu);
> +	ret = arm_smmu_init_strtab(smmu);
> +	if (ret)
> +		return ret;
> +
> +	if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB))
> +		arm_smmu_init_bypass_stes(smmu->strtab_cfg.strtab,
> +					  smmu->strtab_cfg.num_l1_ents, false);
> +	return 0;
>  }
>  
>  static void arm_smmu_free_msis(void *data)
> -- 
> 2.39.0
>
Thanks,
Mostafa


From tommy_huang at aspeedtech.com  Fri Feb 16 04:04:55 2024
From: tommy_huang at aspeedtech.com (Tommy Huang)
Date: Fri, 16 Feb 2024 20:04:55 +0800
Subject: [PATCH] i2c: aspeed: Fix the dummy irq expected print
Message-ID: <20240216120455.4138642-1-tommy_huang@aspeedtech.com>

When the i2c error condition occurred and master state was not idle,
the master irq function will goto complete state without any other
interrupt handling. It would cause dummy irq expected print. Under
this condition, assign the irq_status into irq_handle.

Signed-off-by: Tommy Huang <tommy_huang at aspeedtech.com>
---
 drivers/i2c/busses/i2c-aspeed.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 5511fd46a65e..ce8c4846b7fa 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -445,6 +445,7 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
 			irq_status);
 		irq_handled |= (irq_status & ASPEED_I2CD_INTR_MASTER_ERRORS);
 		if (bus->master_state != ASPEED_I2C_MASTER_INACTIVE) {
+			irq_handled = irq_status;
 			bus->cmd_err = ret;
 			bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
 			goto out_complete;
-- 
2.25.1



From will at kernel.org  Fri Feb 16 04:05:12 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 16 Feb 2024 12:05:12 +0000
Subject: [PATCH rc v2] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <0-v2-7988c2682634+261-smmu_cd_atomic_jgg@nvidia.com>
References: <0-v2-7988c2682634+261-smmu_cd_atomic_jgg@nvidia.com>
Message-ID: <20240216120512.GA1841@willie-the-truck>

On Thu, Feb 15, 2024 at 10:56:57AM -0400, Jason Gunthorpe wrote:
> If the SMMU is configured to use a two level CD table then
> arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
> GFP_KERNEL. Due to recent changes this is being done under a spinlock to
> iterate over the device list - thus it will trigger a sleeping while
> atomic warning:
> 
>   arm_smmu_sva_set_dev_pasid()
>     mutex_lock(&sva_lock);
>     __arm_smmu_sva_bind()
>      arm_smmu_mmu_notifier_get()
>       spin_lock_irqsave()
>       arm_smmu_write_ctx_desc()
> 	arm_smmu_get_cd_ptr()
>          arm_smmu_alloc_cd_leaf_table()
> 	  dmam_alloc_coherent(GFP_KERNEL)
> 
> This is a 64K high order allocation and really should not be done
> atomically.
> 
> At the moment the rework of the SVA to follow the new API is half
> finished. Recently the CD table memory was moved from the domain to the
> master, however we have the confusing situation where the SVA code is
> wrongly using the RID domains device's list to track which CD tables the
> SVA is installed in.
> 
> Remove the logic to replicate the CD across all the domain's masters
> during attach. We know which master and which CD table the PASID should be
> installed in.
> 
> At the moment SVA is only invoked when dma-iommu.c is in control of the
> RID translation, which means we have a single iommu_domain shared across
> the entire group and that iommu_domain is not shared outside the group.
> 
> For PCI cases the core code also insists on singleton groups so there is
> only ever one entry in the smmu_domain->domains list that is equal to the
> master being passed in to arm_smmu_sva_set_dev_pasid().
> 
> Only non-PCI cases may have multi-device groups. However, the core code it
> self will replicate the calls to arm_smmu_sva_set_dev_pasid() across the
> entire group so we will still correctly install the CD into each group
> members master.

Are you sure about this paragraph? arm_smmu_mmu_notifier_get() will return
early if it finds an existing notifier in the 'mmu_notifiers' list for the
domain, so I don't think we'll actually get as far as installing the CD,
will we?

Will


From tony at atomide.com  Fri Feb 16 04:08:33 2024
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 16 Feb 2024 14:08:33 +0200
Subject: 6.7 regression: platform 4809c000.mmc: deferred probe pending
In-Reply-To: <2024021516-stricken-bubble-bf8d@gregkh>
References: <mvmcyt13idm.fsf@suse.de>
 <c92385d2-1909-43a8-aea8-cd9a8687a898@leemhuis.info>
 <20240215094640.GS52537@atomide.com>
 <mvmeddeyqb8.fsf@suse.de>
 <2024021516-stricken-bubble-bf8d@gregkh>
Message-ID: <20240216120833.GT52537@atomide.com>

* Greg KH <gregkh at linuxfoundation.org> [240215 11:16]:
> On Thu, Feb 15, 2024 at 11:28:27AM +0100, Andreas Schwab wrote:
> > On Feb 15 2024, Tony Lindgren wrote:
> > 
> > > There was a regression recently with the PMIC which would cause NFSroot
> > > on devices to keep working but may have affected MMC. Please check that
> > > commit 7a29fa05aeca ("mfd: twl6030-irq: Revert to use of_match_device()")
> > > is applied.
> > 
> > That commit hasn't hit stable yet.  Maybe it's because it references a
> > non-existant commit id (1e0c866887f4 instead of 830fafce06e6).
> 
> Yeah, our tools can't do about a commit that does not have a cc: stable@
> tag in it AND the only commit it does reference is not one actually in
> the tree at all.
> 
> An impossible task for us here, please ask stable at vger.kernel.org to
> take the commit if this is needed, and let us know how far back it
> should go.

Andreas, did commit 7a29fa05aeca solve the issue? If so please send
and email to the stable list.

Regards,

Tony


From schnelle at linux.ibm.com  Fri Feb 16 04:09:10 2024
From: schnelle at linux.ibm.com (Niklas Schnelle)
Date: Fri, 16 Feb 2024 13:09:10 +0100
Subject: [PATCH rdma-next 1/2] arm64/io: add memcpy_toio_64
In-Reply-To: <071e2d2e301769d523dd613e77c6541a61bd496b.camel@linux.ibm.com>
References: <b3250b9a9af2f29ee3d06830746fb6e8ac49271d.camel@linux.ibm.com>
	 <20231124160627.GH436702@nvidia.com>
	 <637dcc4d69c380bd939dfdd1b14a5c82c2ddfaa4.camel@linux.ibm.com>
	 <20231127175115.GC1165737@nvidia.com>
	 <002043477bba726f7dfb38573bf33990e38e3a51.camel@linux.ibm.com>
	 <20240116173330.GA980613@nvidia.com>
	 <ddd56db15bd2c87073a2f839e06cdb80d693272c.camel@linux.ibm.com>
	 <20240117132613.GH734935@nvidia.com> <20240117175518.GJ734935@nvidia.com>
	 <8e043042f425b4c574d1d3c3ed686253c8cd3517.camel@linux.ibm.com>
	 <20240118140039.GL734935@nvidia.com>
	 <071e2d2e301769d523dd613e77c6541a61bd496b.camel@linux.ibm.com>
Message-ID: <e1a6dcb9ccf1b5401fc0178ac2d700be9d8ce564.camel@linux.ibm.com>

On Thu, 2024-01-18 at 16:59 +0100, Niklas Schnelle wrote:
> On Thu, 2024-01-18 at 10:00 -0400, Jason Gunthorpe wrote:
> > On Thu, Jan 18, 2024 at 02:46:40PM +0100, Niklas Schnelle wrote:
> > 
> > > Yes, we need zpci_memcpy_toio(to, from, count * 8) since our count is
> > > in bytes like for memcpy_toio().
> > 
> > https://github.com/jgunthorpe/linux/commits/mlx5_wc/
> > 
> > Jason
> > 
> 
> Thanks, the s390 patches:
> 
> 
> s390: Implement __iowrite32_copy() 
> s390: Use the correct count for __iowrite64_copy() 
> s390: Stop using weak symbols for __iowrite64_copy() 
> 
> Look good to me. I.e. you may add my.
> 
> Acked-by Niklas Schnelle <schnelle at linux.ibm.com>
> 
> I did test your patches too and by accident confirmed again that these
> do need commit 80df7d6af7f6 ("s390/pci: fix max size calculation in
> zpci_memcpy_toio()") from the s390 feature branch to get the mlx5
> driver to detect Write-Combining as supported. Note, as far as I know
> Alexander Gordeev is targeting that one for v6.8-rc2 since we had quite
> a few changes for v6.8-rc1.
> 
> Thanks,
> Niklas
> 


Hi Jason,

Since I haven't seen a new version of this yet I was just wondering
what the current plan is. If this is somewhat stuck would you be
willing to send the "s390: Use the correct count for
__iowrite64_copy()" patch separately, preferably with "s390/pci:"
prefix?

Thanks,
Niklas


From smostafa at google.com  Fri Feb 16 04:11:48 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Fri, 16 Feb 2024 12:11:48 +0000
Subject: [RFC PATCH 27/45] KVM: arm64: smmu-v3: Setup domains and page
 table configuration
In-Reply-To: <20240123195053.GC40099@myrica>
References: <20230201125328.2186498-1-jean-philippe@linaro.org>
 <20230201125328.2186498-28-jean-philippe@linaro.org> <CAFgf54pysSxKHcJVP6=dWPxmS3qi=eEMNQMF7SPiaiaeA-Kc_g@mail.gmail.com>
 <20240123195053.GC40099@myrica>
Message-ID: <CAFgf54r3nNez_Rp0xOYWcTKvO9tcx313Q5-_dotT341qQOHm1w@mail.gmail.com>

On Tue, Jan 23, 2024 at 7:50?PM Jean-Philippe Brucker
<jean-philippe at linaro.org> wrote:
>
> On Mon, Jan 15, 2024 at 02:34:12PM +0000, Mostafa Saleh wrote:
> > > +static void smmu_tlb_inv_range(struct kvm_iommu_tlb_cookie *data,
> > > +                              unsigned long iova, size_t size, size_t granule,
> > > +                              bool leaf)
> > > +{
> > > +       struct hyp_arm_smmu_v3_device *smmu = to_smmu(data->iommu);
> > > +       unsigned long end = iova + size;
> > > +       struct arm_smmu_cmdq_ent cmd = {
> > > +               .opcode = CMDQ_OP_TLBI_S2_IPA,
> > > +               .tlbi.vmid = data->domain_id,
> > > +               .tlbi.leaf = leaf,
> > > +       };
> > > +
> > > +       /*
> > > +        * There are no mappings at high addresses since we don't use TTB1, so
> > > +        * no overflow possible.
> > > +        */
> > > +       BUG_ON(end < iova);
> > > +
> > > +       while (iova < end) {
> > > +               cmd.tlbi.addr = iova;
> > > +               WARN_ON(smmu_send_cmd(smmu, &cmd));
> >
> > This would issue a sync command between each range, which is not needed,
> > maybe we can build the command first and then issue the sync, similar
> > to what the upstream driver does, what do you think?
>
> Yes, moving the sync out of the loop would be better. To keep things
> simple I'd just replace this with smmu_add_cmd() and add a smmu_sync_cmd()
> at the end, but maybe some implementations won't consume the TLBI itself
> fast enough, and we need to build a command list in software. Do you think
> smmu_add_cmd() is sufficient here?

Replacing this with smmu_add_cmd makes sense.
We only poll the queue at SYNC, which is the last command, so it
doesn't matter the pace
of the TLBI consumption I believe?

One advantage of building the command list first, is that we also
avoid MMIO access for the queue which can be slow.

Thanks,
Mostafa


From smostafa at google.com  Fri Feb 16 04:19:01 2024
From: smostafa at google.com (Mostafa Saleh)
Date: Fri, 16 Feb 2024 12:19:01 +0000
Subject: [RFC PATCH 24/45] KVM: arm64: smmu-v3: Setup stream table
In-Reply-To: <20240123194530.GA40099@myrica>
References: <20230201125328.2186498-1-jean-philippe@linaro.org>
 <20230201125328.2186498-25-jean-philippe@linaro.org> <CAFgf54qcTAru0Nvy1wH_tJMadOSW7Y3zEip5RTm+mtSa54Bymg@mail.gmail.com>
 <20240123194530.GA40099@myrica>
Message-ID: <CAFgf54pAtSLWjaqhZShxzKkOLWFkjXmsmMk1P0TdXOUWhn00sg@mail.gmail.com>

On Tue, Jan 23, 2024 at 7:45?PM Jean-Philippe Brucker
<jean-philippe at linaro.org> wrote:
>
> Hi Mostafa,
>
> On Tue, Jan 16, 2024 at 08:59:41AM +0000, Mostafa Saleh wrote:
> > > +__maybe_unused
> > > +static int smmu_sync_ste(struct hyp_arm_smmu_v3_device *smmu, u32 sid)
> > > +{
> > > +       struct arm_smmu_cmdq_ent cmd = {
> > > +               .opcode = CMDQ_OP_CFGI_STE,
> > > +               .cfgi.sid = sid,
> > > +               .cfgi.leaf = true,
> > > +       };
> > > +
> > > +       return smmu_send_cmd(smmu, &cmd);
> > > +}
> > > +
> > I see the page tables are properly configured for ARM_SMMU_FEAT_COHERENCY but no
> > handling for the STE or CMDQ, I believe here we should have something as:
> > if (!(smmu->features & ARM_SMMU_FEAT_COHERENCY))
> >         kvm_flush_dcache_to_poc(step, STRTAB_STE_DWORDS << 3);
> >
> > Similarly in "smmu_add_cmd" for the command queue. Or use NC mapping
> > (which doesn't exist
> > upstream as far as I can see)
>
> Right, the host driver seems to do this. If I'm following correctly we end
> up with dma_direct_alloc() calling pgprot_dmacoherent() and get
> MT_NORMAL_NC, when the SMMU is declared non-coherent in DT/IORT.
>
> So we'd get mismatched attributes if hyp is then mapping these structures
> cacheable, but I don't remember how that works exactly. Might be fine
> since host donates the pages to hyp and we'd have a cache flush in
> between. I'll have to read up on that.

I guess that is not enough, as the hypervisor writes the STE/CMDQ at any time.

> Regardless, mapping NC seems cleaner, more readable. I'll see if I can add
> that attribute to kvm_pgtable_hyp_map().

There is a patch for that already in Android
https://android.googlesource.com/kernel/common/+/636c912401dec4d178f6cdf6073f546b15828cf7%5E%21/#F0

But I a guess as beginning CMO is enough, I have this POC for it
https://android-kvm.googlesource.com/linux/+/193b027de376317eb8daa4eb207badaa1d6fda4a%5E%21/#F0

Thanks,
Mostafa


From catalin.marinas at arm.com  Fri Feb 16 04:25:39 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 16 Feb 2024 12:25:39 +0000
Subject: [PATCH v6 12/18] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <20240215103205.2607016-13-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-13-ryan.roberts@arm.com>
Message-ID: <Zc9UQy-mtYAzNWm2@arm.com>

On Thu, Feb 15, 2024 at 10:31:59AM +0000, Ryan Roberts wrote:
>  arch/arm64/mm/contpte.c          | 285 +++++++++++++++++++++++++++++++

Nitpick: I think most symbols in contpte.c can be EXPORT_SYMBOL_GPL().
We don't expect them to be used by random out of tree modules. In fact,
do we expect them to end up in modules at all? Most seem to be called
from the core mm code.

> +#define ptep_get_lockless ptep_get_lockless
> +static inline pte_t ptep_get_lockless(pte_t *ptep)
> +{
> +	pte_t pte = __ptep_get(ptep);
> +
> +	if (likely(!pte_valid_cont(pte)))
> +		return pte;
> +
> +	return contpte_ptep_get_lockless(ptep);
> +}
[...]
> +pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
> +{
> +	/*
> +	 * Gather access/dirty bits, which may be populated in any of the ptes
> +	 * of the contig range. We may not be holding the PTL, so any contiguous
> +	 * range may be unfolded/modified/refolded under our feet. Therefore we
> +	 * ensure we read a _consistent_ contpte range by checking that all ptes
> +	 * in the range are valid and have CONT_PTE set, that all pfns are
> +	 * contiguous and that all pgprots are the same (ignoring access/dirty).
> +	 * If we find a pte that is not consistent, then we must be racing with
> +	 * an update so start again. If the target pte does not have CONT_PTE
> +	 * set then that is considered consistent on its own because it is not
> +	 * part of a contpte range.
> +*/

I can't get my head around this lockless API. Maybe it works fine (and
may have been discussed already) but we should document what the races
are, why it works, what the memory ordering requirements are. For
example, the generic (well, x86 PAE) ptep_get_lockless() only needs to
ensure that the low/high 32 bits of a pte are consistent and there are
some ordering rules on how these are updated.

Does the arm64 implementation only need to be correct w.r.t. the
access/dirty bits? Since we can read orig_ptep atomically, I assume the
only other updates from unfolding would set the dirty/access bits.

> +
> +	pgprot_t orig_prot;
> +	unsigned long pfn;
> +	pte_t orig_pte;
> +	pgprot_t prot;
> +	pte_t *ptep;
> +	pte_t pte;
> +	int i;
> +
> +retry:
> +	orig_pte = __ptep_get(orig_ptep);
> +
> +	if (!pte_valid_cont(orig_pte))
> +		return orig_pte;
> +
> +	orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
> +	ptep = contpte_align_down(orig_ptep);
> +	pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
> +
> +	for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
> +		pte = __ptep_get(ptep);
> +		prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));

We don't have any ordering guarantees in how the ptes in this range are
read or written in the contpte_set_ptes() and the fold/unfold functions.
We might not need them given all the other checks below but it's worth
adding a comment.

> +
> +		if (!pte_valid_cont(pte) ||
> +		   pte_pfn(pte) != pfn ||
> +		   pgprot_val(prot) != pgprot_val(orig_prot))
> +			goto retry;

I think this also needs some comment. I get the !pte_valid_cont() check
to attempt retrying when racing with unfolding. Are the other checks
needed to detect re-folding with different protection or pfn?

> +
> +		if (pte_dirty(pte))
> +			orig_pte = pte_mkdirty(orig_pte);
> +
> +		if (pte_young(pte))
> +			orig_pte = pte_mkyoung(orig_pte);
> +	}

After writing the comments above, I think I figured out that the whole
point of this loop is to check that the ptes in the contig range are
still consistent and the only variation allowed is the dirty/young
state to be passed to the orig_pte returned. The original pte may have
been updated by the time this loop finishes but I don't think it
matters, it wouldn't be any different than reading a single pte and
returning it while it is being updated.

If you can make this easier to parse (in a few years time) with an
additional patch adding some more comments, that would be great. For
this patch:

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>

-- 
Catalin


From catalin.marinas at arm.com  Fri Feb 16 04:30:12 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 16 Feb 2024 12:30:12 +0000
Subject: [PATCH v6 13/18] arm64/mm: Implement new wrprotect_ptes() batch
 API
In-Reply-To: <20240215103205.2607016-14-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-14-ryan.roberts@arm.com>
Message-ID: <Zc9VVC4cSFcYzgCZ@arm.com>

On Thu, Feb 15, 2024 at 10:32:00AM +0000, Ryan Roberts wrote:
> Optimize the contpte implementation to fix some of the fork performance
> regression introduced by the initial contpte commit. Subsequent patches
> will solve it entirely.
> 
> During fork(), any private memory in the parent must be write-protected.
> Previously this was done 1 PTE at a time. But the core-mm supports
> batched wrprotect via the new wrprotect_ptes() API. So let's implement
> that API and for fully covered contpte mappings, we no longer need to
> unfold the contpte. This has 2 benefits:
> 
>   - reduced unfolding, reduces the number of tlbis that must be issued.
>   - The memory remains contpte-mapped ("folded") in the parent, so it
>     continues to benefit from the more efficient use of the TLB after
>     the fork.
> 
> The optimization to wrprotect a whole contpte block without unfolding is
> possible thanks to the tightening of the Arm ARM in respect to the
> definition and behaviour when 'Misprogramming the Contiguous bit'. See
> section D21194 at https://developer.arm.com/documentation/102105/ja-07/
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Fri Feb 16 04:30:48 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 16 Feb 2024 12:30:48 +0000
Subject: [PATCH v6 14/18] arm64/mm: Implement new
 [get_and_]clear_full_ptes() batch APIs
In-Reply-To: <20240215103205.2607016-15-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-15-ryan.roberts@arm.com>
Message-ID: <Zc9VeMJpdpJG9LsH@arm.com>

On Thu, Feb 15, 2024 at 10:32:01AM +0000, Ryan Roberts wrote:
> Optimize the contpte implementation to fix some of the
> exit/munmap/dontneed performance regression introduced by the initial
> contpte commit. Subsequent patches will solve it entirely.
> 
> During exit(), munmap() or madvise(MADV_DONTNEED), mappings must be
> cleared. Previously this was done 1 PTE at a time. But the core-mm
> supports batched clear via the new [get_and_]clear_full_ptes() APIs. So
> let's implement those APIs and for fully covered contpte mappings, we no
> longer need to unfold the contpte. This significantly reduces unfolding
> operations, reducing the number of tlbis that must be issued.
> 
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Fri Feb 16 04:34:02 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 16 Feb 2024 12:34:02 +0000
Subject: [PATCH v6 16/18] arm64/mm: Implement pte_batch_hint()
In-Reply-To: <20240215103205.2607016-17-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-17-ryan.roberts@arm.com>
Message-ID: <Zc9WOmh-uYRajvGp@arm.com>

On Thu, Feb 15, 2024 at 10:32:03AM +0000, Ryan Roberts wrote:
> When core code iterates over a range of ptes and calls ptep_get() for
> each of them, if the range happens to cover contpte mappings, the number
> of pte reads becomes amplified by a factor of the number of PTEs in a
> contpte block. This is because for each call to ptep_get(), the
> implementation must read all of the ptes in the contpte block to which
> it belongs to gather the access and dirty bits.
> 
> This causes a hotspot for fork(), as well as operations that unmap
> memory such as munmap(), exit and madvise(MADV_DONTNEED). Fortunately we
> can fix this by implementing pte_batch_hint() which allows their
> iterators to skip getting the contpte tail ptes when gathering the batch
> of ptes to operate on. This results in the number of PTE reads returning
> to 1 per pte.
> 
> Acked-by: Mark Rutland <mark.rutland at arm.com>
> Reviewed-by: David Hildenbrand <david at redhat.com>
> Tested-by: John Hubbard <jhubbard at nvidia.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Fri Feb 16 04:34:23 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 16 Feb 2024 12:34:23 +0000
Subject: [PATCH v6 17/18] arm64/mm: __always_inline to improve fork() perf
In-Reply-To: <20240215103205.2607016-18-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-18-ryan.roberts@arm.com>
Message-ID: <Zc9WT8Wit4HkIsD2@arm.com>

On Thu, Feb 15, 2024 at 10:32:04AM +0000, Ryan Roberts wrote:
> As set_ptes() and wrprotect_ptes() become a bit more complex, the
> compiler may choose not to inline them. But this is critical for fork()
> performance. So mark the functions, along with contpte_try_unfold()
> which is called by them, as __always_inline. This is worth ~1% on the
> fork() microbenchmark with order-0 folios (the common case).
> 
> Acked-by: Mark Rutland <mark.rutland at arm.com>
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From vkoul at kernel.org  Fri Feb 16 04:35:03 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 16 Feb 2024 18:05:03 +0530
Subject: [PATCH] dt-bindings: dma: convert MediaTek High-Speed
 controller to the json-schema
In-Reply-To: <20240213063919.20196-1-zajec5@gmail.com>
References: <20240213063919.20196-1-zajec5@gmail.com>
Message-ID: <170808690375.369652.1439304081643409723.b4-ty@kernel.org>


On Tue, 13 Feb 2024 07:39:19 +0100, Rafa? Mi?ecki wrote:
> This helps validating DTS files. Introduced changes:
> 1. Adjusted "reg" in example
> 2. Added includes to example
> 
> 

Applied, thanks!

[1/1] dt-bindings: dma: convert MediaTek High-Speed controller to the json-schema
      commit: fa3400504824944ec04bd3f236fd5ac57c099fd5

Best regards,
-- 
~Vinod




From catalin.marinas at arm.com  Fri Feb 16 04:35:03 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 16 Feb 2024 12:35:03 +0000
Subject: [PATCH v6 18/18] arm64/mm: Automatically fold contpte mappings
In-Reply-To: <20240215103205.2607016-19-ryan.roberts@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-19-ryan.roberts@arm.com>
Message-ID: <Zc9Wd0N03pPY5Nq5@arm.com>

On Thu, Feb 15, 2024 at 10:32:05AM +0000, Ryan Roberts wrote:
> There are situations where a change to a single PTE could cause the
> contpte block in which it resides to become foldable (i.e. could be
> repainted with the contiguous bit). Such situations arise, for example,
> when user space temporarily changes protections, via mprotect, for
> individual pages, such can be the case for certain garbage collectors.
> 
> We would like to detect when such a PTE change occurs. However this can
> be expensive due to the amount of checking required. Therefore only
> perform the checks when an indiviual PTE is modified via mprotect
> (ptep_modify_prot_commit() -> set_pte_at() -> set_ptes(nr=1)) and only
> when we are setting the final PTE in a contpte-aligned block.
> 
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From jgg at nvidia.com  Fri Feb 16 04:36:06 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 16 Feb 2024 08:36:06 -0400
Subject: [PATCH rc v2] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240216120512.GA1841@willie-the-truck>
References: <0-v2-7988c2682634+261-smmu_cd_atomic_jgg@nvidia.com>
 <20240216120512.GA1841@willie-the-truck>
Message-ID: <20240216123606.GA13330@nvidia.com>

On Fri, Feb 16, 2024 at 12:05:12PM +0000, Will Deacon wrote:
> On Thu, Feb 15, 2024 at 10:56:57AM -0400, Jason Gunthorpe wrote:
> > If the SMMU is configured to use a two level CD table then
> > arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
> > GFP_KERNEL. Due to recent changes this is being done under a spinlock to
> > iterate over the device list - thus it will trigger a sleeping while
> > atomic warning:
> > 
> >   arm_smmu_sva_set_dev_pasid()
> >     mutex_lock(&sva_lock);
> >     __arm_smmu_sva_bind()
> >      arm_smmu_mmu_notifier_get()
> >       spin_lock_irqsave()
> >       arm_smmu_write_ctx_desc()
> > 	arm_smmu_get_cd_ptr()
> >          arm_smmu_alloc_cd_leaf_table()
> > 	  dmam_alloc_coherent(GFP_KERNEL)
> > 
> > This is a 64K high order allocation and really should not be done
> > atomically.
> > 
> > At the moment the rework of the SVA to follow the new API is half
> > finished. Recently the CD table memory was moved from the domain to the
> > master, however we have the confusing situation where the SVA code is
> > wrongly using the RID domains device's list to track which CD tables the
> > SVA is installed in.
> > 
> > Remove the logic to replicate the CD across all the domain's masters
> > during attach. We know which master and which CD table the PASID should be
> > installed in.
> > 
> > At the moment SVA is only invoked when dma-iommu.c is in control of the
> > RID translation, which means we have a single iommu_domain shared across
> > the entire group and that iommu_domain is not shared outside the group.
> > 
> > For PCI cases the core code also insists on singleton groups so there is
> > only ever one entry in the smmu_domain->domains list that is equal to the
> > master being passed in to arm_smmu_sva_set_dev_pasid().
> > 
> > Only non-PCI cases may have multi-device groups. However, the core code it
> > self will replicate the calls to arm_smmu_sva_set_dev_pasid() across the
> > entire group so we will still correctly install the CD into each group
> > members master.
> 
> Are you sure about this paragraph? arm_smmu_mmu_notifier_get() will return
> early if it finds an existing notifier in the 'mmu_notifiers' list for the
> domain, so I don't think we'll actually get as far as installing the CD,
> will we?

I think the paragraph is the right analysis, the code just isn't
listening very well..

Lifting up the arm_smmu_write_ctx_desc() into the caller will fix it.

Also Michael should look at it (I recall we talked about this once)
and Nicolin should test it.

BTW, I have no idea if non-PCI cases exists, everyone I know is doing
PCI SVA.

Jason


From jgg at nvidia.com  Fri Feb 16 04:39:03 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 16 Feb 2024 08:39:03 -0400
Subject: [PATCH rdma-next 1/2] arm64/io: add memcpy_toio_64
In-Reply-To: <e1a6dcb9ccf1b5401fc0178ac2d700be9d8ce564.camel@linux.ibm.com>
References: <20231127175115.GC1165737@nvidia.com>
 <002043477bba726f7dfb38573bf33990e38e3a51.camel@linux.ibm.com>
 <20240116173330.GA980613@nvidia.com>
 <ddd56db15bd2c87073a2f839e06cdb80d693272c.camel@linux.ibm.com>
 <20240117132613.GH734935@nvidia.com>
 <20240117175518.GJ734935@nvidia.com>
 <8e043042f425b4c574d1d3c3ed686253c8cd3517.camel@linux.ibm.com>
 <20240118140039.GL734935@nvidia.com>
 <071e2d2e301769d523dd613e77c6541a61bd496b.camel@linux.ibm.com>
 <e1a6dcb9ccf1b5401fc0178ac2d700be9d8ce564.camel@linux.ibm.com>
Message-ID: <20240216123903.GB13330@nvidia.com>

On Fri, Feb 16, 2024 at 01:09:10PM +0100, Niklas Schnelle wrote:
> On Thu, 2024-01-18 at 16:59 +0100, Niklas Schnelle wrote:
> > On Thu, 2024-01-18 at 10:00 -0400, Jason Gunthorpe wrote:
> > > On Thu, Jan 18, 2024 at 02:46:40PM +0100, Niklas Schnelle wrote:
> > > 
> > > > Yes, we need zpci_memcpy_toio(to, from, count * 8) since our count is
> > > > in bytes like for memcpy_toio().
> > > 
> > > https://github.com/jgunthorpe/linux/commits/mlx5_wc/
> > > 
> > > Jason
> > > 
> > 
> > Thanks, the s390 patches:
> > 
> > 
> > s390: Implement __iowrite32_copy() 
> > s390: Use the correct count for __iowrite64_copy() 
> > s390: Stop using weak symbols for __iowrite64_copy() 
> > 
> > Look good to me. I.e. you may add my.
> > 
> > Acked-by Niklas Schnelle <schnelle at linux.ibm.com>
> > 
> > I did test your patches too and by accident confirmed again that these
> > do need commit 80df7d6af7f6 ("s390/pci: fix max size calculation in
> > zpci_memcpy_toio()") from the s390 feature branch to get the mlx5
> > driver to detect Write-Combining as supported. Note, as far as I know
> > Alexander Gordeev is targeting that one for v6.8-rc2 since we had quite
> > a few changes for v6.8-rc1.
> 
> Since I haven't seen a new version of this yet I was just wondering
> what the current plan is. If this is somewhat stuck would you be
> willing to send the "s390: Use the correct count for
> __iowrite64_copy()" patch separately, preferably with "s390/pci:"
> prefix?

I have been waiting for test cycles on the right ARM64 system and it
is taking a long time :(

I'll send your bit so you can take it to -rc

Thanks,
Jason


From rohit.visavalia at amd.com  Fri Feb 16 04:40:43 2024
From: rohit.visavalia at amd.com (Rohit Visavalia)
Date: Fri, 16 Feb 2024 04:40:43 -0800
Subject: [PATCH] drm: xlnx: dp: Reset DisplayPort IP
Message-ID: <20240216124043.1226713-1-rohit.visavalia@amd.com>

Assert DisplayPort reset signal before deasserting,
it is to clear out any registers programmed before booting kernel.

Signed-off-by: Rohit Visavalia <rohit.visavalia at amd.com>
---
 drivers/gpu/drm/xlnx/zynqmp_dp.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index 1846c4971fd8..5a40aa1d4283 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -1714,6 +1714,10 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub)
 		goto err_free;
 	}
 
+	ret = zynqmp_dp_reset(dp, true);
+	if (ret < 0)
+		return ret;
+
 	ret = zynqmp_dp_reset(dp, false);
 	if (ret < 0)
 		goto err_free;
-- 
2.25.1



From shreeya.patel at collabora.com  Fri Feb 16 04:48:10 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Fri, 16 Feb 2024 12:48:10 +0000
Subject: =?utf-8?q?Re=3A?= [PATCH 1/4] =?utf-8?q?clk=3A?==?utf-8?q?_rockchip=3A?=
 =?utf-8?q?_rst-rk3588=3A?= Add BIU reset
In-Reply-To: <237e690a-2f49-4046-b054-3a878eed6748@linaro.org>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
 <20240216094922.257674-2-shreeya.patel@collabora.com> <237e690a-2f49-4046-b054-3a878eed6748@linaro.org>
Message-ID: <30d2-65cf5980-3-2ec9f500@242931553>

On Friday, February 16, 2024 15:33 IST, Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:

> On 16/02/2024 10:49, Shreeya Patel wrote:
> > Export hdmirx_biu soft reset id which is required by the hdmirx controller.
> > 
> > Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
> > ---
> >  drivers/clk/rockchip/rst-rk3588.c               | 1 +
> >  include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++
> 
> Please run scripts/checkpatch.pl and fix reported warnings. Some
> warnings can be ignored, but the code here looks like it needs a fix.
> Feel free to get in touch if the warning is not clear.
> 
> Please do internal review. The internal Collabora review would tell you:
> YOU MUST run checkpatch. Then you see errors, so why do you send patch
> with errors to the mailing list?
> 

I am sorry but what errors are you talking about?
I don't see any errors reported by checkpatch :-

shreeya at shreeya:~/collabora/rd/rockchip/torvalds$ ./scripts/checkpatch.pl hdmirx/0001-clk-rockchip-rst-rk3588-Add-BIU-reset.patch
WARNING: DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst

total: 0 errors, 1 warnings, 13 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

hdmirx-v1-1602/0001-clk-rockchip-rst-rk3588-Add-BIU-reset.patch has style problems, please review.

I see the above warning but that looks like a false positive to me.

> Best regards,
> Krzysztof
> 
> _______________________________________________
> Kernel mailing list -- kernel at mailman.collabora.com
> To unsubscribe send an email to kernel-leave at mailman.collabora.com
> This list is managed by https://mailman.collabora.com



From e.orlova at ispras.ru  Fri Feb 16 04:50:40 2024
From: e.orlova at ispras.ru (Katya Orlova)
Date: Fri, 16 Feb 2024 15:50:40 +0300
Subject: [PATCH v4] drm/stm: Avoid use-after-free issues with crtc and plane
In-Reply-To: <20240122111128.10852-1-e.orlova@ispras.ru>
Message-ID: <20240216125040.8968-1-e.orlova@ispras.ru>

ltdc_load() calls functions drm_crtc_init_with_planes(),
drm_universal_plane_init() and drm_encoder_init(). These functions
should not be called with parameters allocated with devm_kzalloc()
to avoid use-after-free issues [1].

Use allocations managed by the DRM framework.

Found by Linux Verification Center (linuxtesting.org).

[1]
https://lore.kernel.org/lkml/u366i76e3qhh3ra5oxrtngjtm2u5lterkekcz6y2jkndhuxzli at diujon4h7qwb/

Signed-off-by: Katya Orlova <e.orlova at ispras.ru>
---
v4: rebase on the drm-misc
v3: style problems
v2: use allocations managed by the DRM as
Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com> suggested.
Also add a fix for encoder.
 drivers/gpu/drm/stm/drv.c  |  3 +-
 drivers/gpu/drm/stm/ltdc.c | 73 ++++++++++----------------------------
 2 files changed, 20 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index e8523abef27a..152bec2c0238 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -25,6 +25,7 @@
 #include <drm/drm_module.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
+#include <drm/drm_managed.h>
 
 #include "ltdc.h"
 
@@ -75,7 +76,7 @@ static int drv_load(struct drm_device *ddev)
 
 	DRM_DEBUG("%s\n", __func__);
 
-	ldev = devm_kzalloc(ddev->dev, sizeof(*ldev), GFP_KERNEL);
+	ldev = drmm_kzalloc(ddev, sizeof(*ldev), GFP_KERNEL);
 	if (!ldev)
 		return -ENOMEM;
 
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 5576fdae4962..eeaabb4e10d3 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -36,6 +36,7 @@
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_simple_kms_helper.h>
 #include <drm/drm_vblank.h>
+#include <drm/drm_managed.h>
 
 #include <video/videomode.h>
 
@@ -1199,7 +1200,6 @@ static void ltdc_crtc_atomic_print_state(struct drm_printer *p,
 }
 
 static const struct drm_crtc_funcs ltdc_crtc_funcs = {
-	.destroy = drm_crtc_cleanup,
 	.set_config = drm_atomic_helper_set_config,
 	.page_flip = drm_atomic_helper_page_flip,
 	.reset = drm_atomic_helper_crtc_reset,
@@ -1212,7 +1212,6 @@ static const struct drm_crtc_funcs ltdc_crtc_funcs = {
 };
 
 static const struct drm_crtc_funcs ltdc_crtc_with_crc_support_funcs = {
-	.destroy = drm_crtc_cleanup,
 	.set_config = drm_atomic_helper_set_config,
 	.page_flip = drm_atomic_helper_page_flip,
 	.reset = drm_atomic_helper_crtc_reset,
@@ -1545,7 +1544,6 @@ static void ltdc_plane_atomic_print_state(struct drm_printer *p,
 static const struct drm_plane_funcs ltdc_plane_funcs = {
 	.update_plane = drm_atomic_helper_update_plane,
 	.disable_plane = drm_atomic_helper_disable_plane,
-	.destroy = drm_plane_cleanup,
 	.reset = drm_atomic_helper_plane_reset,
 	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -1572,7 +1570,6 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
 	const u64 *modifiers = ltdc_format_modifiers;
 	u32 lofs = index * LAY_OFS;
 	u32 val;
-	int ret;
 
 	/* Allocate the biggest size according to supported color formats */
 	formats = devm_kzalloc(dev, (ldev->caps.pix_fmt_nb +
@@ -1613,14 +1610,10 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
 		}
 	}
 
-	plane = devm_kzalloc(dev, sizeof(*plane), GFP_KERNEL);
-	if (!plane)
-		return NULL;
-
-	ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
-				       &ltdc_plane_funcs, formats, nb_fmt,
-				       modifiers, type, NULL);
-	if (ret < 0)
+	plane = drmm_universal_plane_alloc(ddev, struct drm_plane, dev,
+					   possible_crtcs, &ltdc_plane_funcs, formats,
+					   nb_fmt, modifiers, type, NULL);
+	if (IS_ERR(plane))
 		return NULL;
 
 	if (ldev->caps.ycbcr_input) {
@@ -1643,15 +1636,6 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
 	return plane;
 }
 
-static void ltdc_plane_destroy_all(struct drm_device *ddev)
-{
-	struct drm_plane *plane, *plane_temp;
-
-	list_for_each_entry_safe(plane, plane_temp,
-				 &ddev->mode_config.plane_list, head)
-		drm_plane_cleanup(plane);
-}
-
 static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
 {
 	struct ltdc_device *ldev = ddev->dev_private;
@@ -1677,14 +1661,14 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
 
 	/* Init CRTC according to its hardware features */
 	if (ldev->caps.crc)
-		ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
-						&ltdc_crtc_with_crc_support_funcs, NULL);
+		ret = drmm_crtc_init_with_planes(ddev, crtc, primary, NULL,
+						 &ltdc_crtc_with_crc_support_funcs, NULL);
 	else
-		ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
-						&ltdc_crtc_funcs, NULL);
+		ret = drmm_crtc_init_with_planes(ddev, crtc, primary, NULL,
+						 &ltdc_crtc_funcs, NULL);
 	if (ret) {
 		DRM_ERROR("Can not initialize CRTC\n");
-		goto cleanup;
+		return ret;
 	}
 
 	drm_crtc_helper_add(crtc, &ltdc_crtc_helper_funcs);
@@ -1698,9 +1682,8 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
 	for (i = 1; i < ldev->caps.nb_layers; i++) {
 		overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY, i);
 		if (!overlay) {
-			ret = -ENOMEM;
 			DRM_ERROR("Can not create overlay plane %d\n", i);
-			goto cleanup;
+			return -ENOMEM;
 		}
 		if (ldev->caps.dynamic_zorder)
 			drm_plane_create_zpos_property(overlay, i, 0, ldev->caps.nb_layers - 1);
@@ -1713,10 +1696,6 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
 	}
 
 	return 0;
-
-cleanup:
-	ltdc_plane_destroy_all(ddev);
-	return ret;
 }
 
 static void ltdc_encoder_disable(struct drm_encoder *encoder)
@@ -1776,23 +1755,19 @@ static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge)
 	struct drm_encoder *encoder;
 	int ret;
 
-	encoder = devm_kzalloc(ddev->dev, sizeof(*encoder), GFP_KERNEL);
-	if (!encoder)
-		return -ENOMEM;
+	encoder = drmm_simple_encoder_alloc(ddev, struct drm_encoder, dev,
+					    DRM_MODE_ENCODER_DPI);
+	if (IS_ERR(encoder))
+		return PTR_ERR(encoder);
 
 	encoder->possible_crtcs = CRTC_MASK;
 	encoder->possible_clones = 0;	/* No cloning support */
 
-	drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI);
-
 	drm_encoder_helper_add(encoder, &ltdc_encoder_helper_funcs);
 
 	ret = drm_bridge_attach(encoder, bridge, NULL, 0);
-	if (ret) {
-		if (ret != -EPROBE_DEFER)
-			drm_encoder_cleanup(encoder);
+	if (ret)
 		return ret;
-	}
 
 	DRM_DEBUG_DRIVER("Bridge encoder:%d created\n", encoder->base.id);
 
@@ -1962,8 +1937,7 @@ int ltdc_load(struct drm_device *ddev)
 			goto err;
 
 		if (panel) {
-			bridge = drm_panel_bridge_add_typed(panel,
-							    DRM_MODE_CONNECTOR_DPI);
+			bridge = drmm_panel_bridge_add(ddev, panel);
 			if (IS_ERR(bridge)) {
 				DRM_ERROR("panel-bridge endpoint %d\n", i);
 				ret = PTR_ERR(bridge);
@@ -2045,7 +2019,7 @@ int ltdc_load(struct drm_device *ddev)
 		}
 	}
 
-	crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
+	crtc = drmm_kzalloc(ddev, sizeof(*crtc), GFP_KERNEL);
 	if (!crtc) {
 		DRM_ERROR("Failed to allocate crtc\n");
 		ret = -ENOMEM;
@@ -2072,9 +2046,6 @@ int ltdc_load(struct drm_device *ddev)
 
 	return 0;
 err:
-	for (i = 0; i < nb_endpoints; i++)
-		drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i);
-
 	clk_disable_unprepare(ldev->pixel_clk);
 
 	return ret;
@@ -2082,16 +2053,8 @@ int ltdc_load(struct drm_device *ddev)
 
 void ltdc_unload(struct drm_device *ddev)
 {
-	struct device *dev = ddev->dev;
-	int nb_endpoints, i;
-
 	DRM_DEBUG_DRIVER("\n");
 
-	nb_endpoints = of_graph_get_endpoint_count(dev->of_node);
-
-	for (i = 0; i < nb_endpoints; i++)
-		drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i);
-
 	pm_runtime_disable(ddev->dev);
 }
 
-- 
2.30.2



From ryan.roberts at arm.com  Fri Feb 16 04:53:43 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Fri, 16 Feb 2024 12:53:43 +0000
Subject: [PATCH v6 12/18] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <Zc9UQy-mtYAzNWm2@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-13-ryan.roberts@arm.com> <Zc9UQy-mtYAzNWm2@arm.com>
Message-ID: <892caa6a-e4fe-4009-aa33-0570526961c5@arm.com>

Hi Catalin,

Thanks for the review! Comments below...


On 16/02/2024 12:25, Catalin Marinas wrote:
> On Thu, Feb 15, 2024 at 10:31:59AM +0000, Ryan Roberts wrote:
>>  arch/arm64/mm/contpte.c          | 285 +++++++++++++++++++++++++++++++
> 
> Nitpick: I think most symbols in contpte.c can be EXPORT_SYMBOL_GPL().
> We don't expect them to be used by random out of tree modules. In fact,
> do we expect them to end up in modules at all? Most seem to be called
> from the core mm code.

The problem is that the contpte_* symbols are called from the ptep_* inline
functions. So where those inlines are called from modules, we need to make sure
the contpte_* symbols are available.

John Hubbard originally reported this problem against v1 and I enumerated all
the drivers that call into the ptep_* inlines here:
https://lore.kernel.org/linux-arm-kernel/b994ff89-1a1f-26ca-9479-b08c77f94be8 at arm.com/#t

So they definitely need to be exported. Perhaps we can tighten it to
EXPORT_SYMBOL_GPL(), but I was being cautious as I didn't want to break anything
out-of-tree. I'm not sure what the normal policy is? arm64 seems to use ~equal
amounts of both.

> 
>> +#define ptep_get_lockless ptep_get_lockless
>> +static inline pte_t ptep_get_lockless(pte_t *ptep)
>> +{
>> +	pte_t pte = __ptep_get(ptep);
>> +
>> +	if (likely(!pte_valid_cont(pte)))
>> +		return pte;
>> +
>> +	return contpte_ptep_get_lockless(ptep);
>> +}
> [...]
>> +pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
>> +{
>> +	/*
>> +	 * Gather access/dirty bits, which may be populated in any of the ptes
>> +	 * of the contig range. We may not be holding the PTL, so any contiguous
>> +	 * range may be unfolded/modified/refolded under our feet. Therefore we
>> +	 * ensure we read a _consistent_ contpte range by checking that all ptes
>> +	 * in the range are valid and have CONT_PTE set, that all pfns are
>> +	 * contiguous and that all pgprots are the same (ignoring access/dirty).
>> +	 * If we find a pte that is not consistent, then we must be racing with
>> +	 * an update so start again. If the target pte does not have CONT_PTE
>> +	 * set then that is considered consistent on its own because it is not
>> +	 * part of a contpte range.
>> +*/
> 
> I can't get my head around this lockless API. Maybe it works fine (and
> may have been discussed already) but we should document what the races
> are, why it works, what the memory ordering requirements are. For
> example, the generic (well, x86 PAE) ptep_get_lockless() only needs to
> ensure that the low/high 32 bits of a pte are consistent and there are
> some ordering rules on how these are updated.
> 
> Does the arm64 implementation only need to be correct w.r.t. the
> access/dirty bits? Since we can read orig_ptep atomically, I assume the
> only other updates from unfolding would set the dirty/access bits.
> 
>> +
>> +	pgprot_t orig_prot;
>> +	unsigned long pfn;
>> +	pte_t orig_pte;
>> +	pgprot_t prot;
>> +	pte_t *ptep;
>> +	pte_t pte;
>> +	int i;
>> +
>> +retry:
>> +	orig_pte = __ptep_get(orig_ptep);
>> +
>> +	if (!pte_valid_cont(orig_pte))
>> +		return orig_pte;
>> +
>> +	orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
>> +	ptep = contpte_align_down(orig_ptep);
>> +	pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
>> +
>> +	for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
>> +		pte = __ptep_get(ptep);
>> +		prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
> 
> We don't have any ordering guarantees in how the ptes in this range are
> read or written in the contpte_set_ptes() and the fold/unfold functions.
> We might not need them given all the other checks below but it's worth
> adding a comment.
> 
>> +
>> +		if (!pte_valid_cont(pte) ||
>> +		   pte_pfn(pte) != pfn ||
>> +		   pgprot_val(prot) != pgprot_val(orig_prot))
>> +			goto retry;
> 
> I think this also needs some comment. I get the !pte_valid_cont() check
> to attempt retrying when racing with unfolding. Are the other checks
> needed to detect re-folding with different protection or pfn?
> 
>> +
>> +		if (pte_dirty(pte))
>> +			orig_pte = pte_mkdirty(orig_pte);
>> +
>> +		if (pte_young(pte))
>> +			orig_pte = pte_mkyoung(orig_pte);
>> +	}
> 
> After writing the comments above, I think I figured out that the whole
> point of this loop is to check that the ptes in the contig range are
> still consistent and the only variation allowed is the dirty/young
> state to be passed to the orig_pte returned. The original pte may have
> been updated by the time this loop finishes but I don't think it
> matters, it wouldn't be any different than reading a single pte and
> returning it while it is being updated.

Correct. The pte can be updated at any time, before after or during the reads.
That was always the case. But now we have to cope with a whole contpte block
being repainted while we are reading it. So we are just checking to make sure
that all the ptes that we read from the contpte block are consistent with
eachother and therefore we can trust that the access/dirty bits we gathered are
consistent.


> 
> If you can make this easier to parse (in a few years time) with an
> additional patch adding some more comments, that would be great. For
> this patch:

I already have a big block comment at the top, which was trying to explain it.
Clearly not well enough though. I'll add more comments as a follow up patch when
I get back from holiday.

> 
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>

Thanks!

> 



From dan.scally at ideasonboard.com  Fri Feb 16 05:09:15 2024
From: dan.scally at ideasonboard.com (Dan Scally)
Date: Fri, 16 Feb 2024 13:09:15 +0000
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240215110205.GD7873@pendragon.ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <20240214142825.GA7873@pendragon.ideasonboard.com>
 <20240214-velcro-pushy-0cbd18b23361@spud>
 <20240215110205.GD7873@pendragon.ideasonboard.com>
Message-ID: <e06b0792-187d-454b-aa62-d9c1e797df17@ideasonboard.com>

Hi both

On 15/02/2024 11:02, Laurent Pinchart wrote:
> On Wed, Feb 14, 2024 at 05:37:17PM +0000, Conor Dooley wrote:
>> On Wed, Feb 14, 2024 at 04:28:25PM +0200, Laurent Pinchart wrote:
>>> On Wed, Feb 14, 2024 at 02:19:03PM +0000, Daniel Scally wrote:
>>>> Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
>>>>
>>>> Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
>>>> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
>>>> ---
>>>> Changes in v2:
>>>>
>>>> 	- Added clocks information
>>>> 	- Fixed the warnings raised by Rob
>>>>
>>>>   .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
>>>>   1 file changed, 77 insertions(+)
>>>>   create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
>>>> new file mode 100644
>>>> index 000000000000..30038cfec3a4
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
>>>> @@ -0,0 +1,77 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: ARM Mali-C55 Image Signal Processor
>>>> +
>>>> +maintainers:
>>>> +  - Daniel Scally <dan.scally at ideasonboard.com>
>>>> +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    const: arm,mali-c55
>>>> +
>>>> +  reg:
>>>> +    maxItems: 1
>>>> +
>>>> +  interrupts:
>>>> +    maxItems: 1
>>>> +
>>>> +  clocks:
>>>> +    items:
>>>> +      - description: ISP video clock
>>> I wonder if we need this clock. Granted, it's an input clock to the ISP,
>>> but it's part of the input video bus. I don't expect anyone would ever
>>> need to control it manually, it should be provided by the video source
>>> automatically.
>> I'd say that if there's a clock controller providing this clock, even if
>> it is implicit in the video feed it's good to have here. Being able to
>> increment the refcount on that clock would be good, even if you don't
>> actually control it manually?
> I don't expect there would be a clock controller to directly reference
> in most cases. It depends a bit on where the clock domain crossing
> between the source (often a CSI-2 receiver) and the ISP is. If it's
> implemented in glue logic bundled with the ISP, which wouldn't be
> described in DT as a separate node, then there's a higher chance we'll
> have a clock controller for vclk. If it's implemented in the source,
> vclk will just come from the source, which won't be listed as a clock
> controller.
>
> One option would be to make this clock optional, by moving it to the end
> of the clocks list, and setting
>
> 	minItems: 2
> 	maxItems: 3
>
>>>> +      - description: ISP AXI clock
>>>> +      - description: ISP AHB-lite clock
>>> These two other clocks look good to me.
>>>
>>>> +
>>>> +  clock-names:
>>>> +    items:
>>>> +      - const: vclk
>>>> +      - const: aclk
>>>> +      - const: hclk
>> Why not "video" "axi" "ahb-lite"? There's 3 useful letters between the
>> tree clock names you've provided - they're all clocks, so having "clk"
>> in them is just noise :)
> As far as I understand, the names proposed by Dan come directly from the
> IP core documentation.


This is the case, but I do take Conor's point that more descriptive names might be nicer - if I'm 
honest I just didn't think about it particularly given "Xclk" is such a common name for them 
already, but having been poked into thinking about it I do agree.

>


From u.kleine-koenig at pengutronix.de  Fri Feb 16 05:10:35 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Fri, 16 Feb 2024 14:10:35 +0100
Subject: [PATCH 1/2] dt-bindings: pwm: mediatek,mt2712: add compatible
 for MT7988
In-Reply-To: <2dac95be-b23a-4c42-ac67-241100c7a51b@linaro.org>
References: <20240213164633.25447-1-zajec5@gmail.com>
 <onnokyq7ciza7i7jzc74cun2khpst5iocuccks2cm433ux3za3@dou4oacrvuxj>
 <2dac95be-b23a-4c42-ac67-241100c7a51b@linaro.org>
Message-ID: <45i5wid2fcf3lyucfferraolnxmdwoulz35js7biuhitiy576j@l3pslrkeehvu>

On Wed, Feb 14, 2024 at 10:05:47AM +0100, Krzysztof Kozlowski wrote:
> On 13/02/2024 18:48, Uwe Kleine-K?nig wrote:
> > Hello Rafa?,
> > 
> > On Tue, Feb 13, 2024 at 05:46:32PM +0100, Rafa? Mi?ecki wrote:
> >> From: Rafa? Mi?ecki <rafal at milecki.pl>
> >>
> >> MT7988 has on-SoC controller that can control up to 8 PWMs.
> >>
> >> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> > 
> > please make sure that the email address used for sending the patch
> > matches the Signed-off-by line.
> > 
> > (It depends on the pickyness of the relevant maintainer if that is a
> > stopper or not.)
> 
> Does not have to... It must match From field which is correct here.

Rafa?'s Signed-off matches the author, but not the sender. Together with
"the Signed-off-by: must always be that of the developer submitting the
patch." (from Documentation/process/submitting-patches.rst) I'd say it's
reasonable to request that there is a sign-off with the email matching
the sender. In my understanding the Sign-off line by the author isn't
really required because the sender can vouch for the author. Of course
this is a somewhat artificial discussion if the sender is the same
person as the author and only the email addresses differ. So this about
the strictness of the applying maintainer.

FTR:

	$  curl -s https://lore.kernel.org/linux-pwm/20240213164633.25447-1-zajec5 at gmail.com/raw | grep -E '^(From|Signed-off-by):'
	From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5 at gmail.com>
	From: Rafa? Mi?ecki <rafal at milecki.pl>
	Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

the first From: is the sender, the second the author.

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/20240216/6e9b430c/attachment.sig>

From lkp at intel.com  Fri Feb 16 05:12:06 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 16 Feb 2024 21:12:06 +0800
Subject: [PATCH v5 2/3] drm/stm: lvds: add new STM32 LVDS Display
 Interface Transmitter driver
In-Reply-To: <20240206-lvds-v5-2-bd16797b0f09@foss.st.com>
References: <20240206-lvds-v5-2-bd16797b0f09@foss.st.com>
Message-ID: <202402162038.HP7VzIHX-lkp@intel.com>

Hi Raphael,

kernel test robot noticed the following build warnings:

[auto build test WARNING on bb3bc3eac316b7c388733e625cc2343131b69dee]

url:    https://github.com/intel-lab-lkp/linux/commits/Raphael-Gallais-Pou/dt-bindings-display-add-STM32-LVDS-device/20240206-194740
base:   bb3bc3eac316b7c388733e625cc2343131b69dee
patch link:    https://lore.kernel.org/r/20240206-lvds-v5-2-bd16797b0f09%40foss.st.com
patch subject: [PATCH v5 2/3] drm/stm: lvds: add new STM32 LVDS Display Interface Transmitter driver
config: arm-randconfig-r132-20240214 (https://download.01.org/0day-ci/archive/20240216/202402162038.HP7VzIHX-lkp at intel.com/config)
compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project.git 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a)
reproduce: (https://download.01.org/0day-ci/archive/20240216/202402162038.HP7VzIHX-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402162038.HP7VzIHX-lkp at intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/gpu/drm/stm/lvds.c:318:17: sparse: sparse: symbol 'lvds_bitmap_jeida_rgb888' was not declared. Should it be static?
>> drivers/gpu/drm/stm/lvds.c:335:17: sparse: sparse: symbol 'lvds_bitmap_vesa_rgb888' was not declared. Should it be static?
   drivers/gpu/drm/stm/lvds.c: note: in included file (through include/linux/mmzone.h, include/linux/gfp.h, include/linux/stackdepot.h, ...):
   include/linux/page-flags.h:242:46: sparse: sparse: self-comparison always evaluates to false

vim +/lvds_bitmap_jeida_rgb888 +318 drivers/gpu/drm/stm/lvds.c

   308	
   309	/*
   310	 * Expected JEIDA-RGB888 data to be sent in LSB format
   311	 *	    bit6 ............................bit0
   312	 * CHAN0   {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE}
   313	 * CHAN1   {G2,  R7,  R6,   R5,   R4,   R3,  R2}
   314	 * CHAN2   {B3,  B2,  G7,   G6,   G5,   G4,  G3}
   315	 * CHAN3   {DE,  VS,  HS,   B7,   B6,   B5,  B4}
   316	 * CHAN4   {CE,  B1,  B0,   G1,   G0,   R1,  R0}
   317	 */
 > 318	enum lvds_pixel lvds_bitmap_jeida_rgb888[5][7] = {
   319		{ PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE },
   320		{ PIX_G_2, PIX_R_7, PIX_R_6, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2 },
   321		{ PIX_B_3, PIX_B_2, PIX_G_7, PIX_G_6, PIX_G_5, PIX_G_4, PIX_G_3 },
   322		{ PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_7, PIX_B_6, PIX_B_5, PIX_B_4 },
   323		{ PIX_C_E, PIX_B_1, PIX_B_0, PIX_G_1, PIX_G_0, PIX_R_1, PIX_R_0 }
   324	};
   325	
   326	/*
   327	 * Expected VESA-RGB888 data to be sent in LSB format
   328	 *	    bit6 ............................bit0
   329	 * CHAN0   {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE}
   330	 * CHAN1   {G0,  R5,  R4,   R3,   R2,   R1,  R0}
   331	 * CHAN2   {B1,  B0,  G5,   G4,   G3,   G2,  G1}
   332	 * CHAN3   {DE,  VS,  HS,   B5,   B4,   B3,  B2}
   333	 * CHAN4   {CE,  B7,  B6,   G7,   G6,   R7,  R6}
   334	 */
 > 335	enum lvds_pixel lvds_bitmap_vesa_rgb888[5][7] = {
   336		{ PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE },
   337		{ PIX_G_0, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2, PIX_R_1, PIX_R_0 },
   338		{ PIX_B_1, PIX_B_0, PIX_G_5, PIX_G_4, PIX_G_3, PIX_G_2, PIX_G_1 },
   339		{ PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_5, PIX_B_4, PIX_B_3, PIX_B_2 },
   340		{ PIX_C_E, PIX_B_7, PIX_B_6, PIX_G_7, PIX_G_6, PIX_R_7, PIX_R_6 }
   341	};
   342	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From mkl at pengutronix.de  Fri Feb 16 05:19:57 2024
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Fri, 16 Feb 2024 14:19:57 +0100
Subject: [PATCH v8 0/3] Add ECC feature support to Tx and Rx FIFOs
 for Xilinx CAN Controller.
In-Reply-To: <PH8PR12MB6675AAAC5D7A86D2CAA382D6E14D2@PH8PR12MB6675.namprd12.prod.outlook.com>
References: <20240213-xilinx_ecc-v8-0-8d75f8b80771@pengutronix.de>
 <PH8PR12MB6675AAAC5D7A86D2CAA382D6E14D2@PH8PR12MB6675.namprd12.prod.outlook.com>
Message-ID: <20240216-grapple-unwind-ee92af7b4b1d-mkl@pengutronix.de>

On 15.02.2024 13:59:33, Goud, Srinivas wrote:
> Thanks, tested with v8 changes, it is working fine.

Thanks for testing,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
-------------- 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/20240216/5a951588/attachment.sig>

From laurent.pinchart at ideasonboard.com  Fri Feb 16 05:27:55 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 16 Feb 2024 15:27:55 +0200
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <e06b0792-187d-454b-aa62-d9c1e797df17@ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <20240214142825.GA7873@pendragon.ideasonboard.com>
 <20240214-velcro-pushy-0cbd18b23361@spud>
 <20240215110205.GD7873@pendragon.ideasonboard.com>
 <e06b0792-187d-454b-aa62-d9c1e797df17@ideasonboard.com>
Message-ID: <20240216132755.GA20376@pendragon.ideasonboard.com>

On Fri, Feb 16, 2024 at 01:09:15PM +0000, Daniel Scally wrote:
> On 15/02/2024 11:02, Laurent Pinchart wrote:
> > On Wed, Feb 14, 2024 at 05:37:17PM +0000, Conor Dooley wrote:
> >> On Wed, Feb 14, 2024 at 04:28:25PM +0200, Laurent Pinchart wrote:
> >>> On Wed, Feb 14, 2024 at 02:19:03PM +0000, Daniel Scally wrote:
> >>>> Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
> >>>>
> >>>> Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> >>>> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> >>>> ---
> >>>> Changes in v2:
> >>>>
> >>>> 	- Added clocks information
> >>>> 	- Fixed the warnings raised by Rob
> >>>>
> >>>>   .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
> >>>>   1 file changed, 77 insertions(+)
> >>>>   create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> >>>> new file mode 100644
> >>>> index 000000000000..30038cfec3a4
> >>>> --- /dev/null
> >>>> +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> >>>> @@ -0,0 +1,77 @@
> >>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >>>> +%YAML 1.2
> >>>> +---
> >>>> +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
> >>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >>>> +
> >>>> +title: ARM Mali-C55 Image Signal Processor
> >>>> +
> >>>> +maintainers:
> >>>> +  - Daniel Scally <dan.scally at ideasonboard.com>
> >>>> +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> >>>> +
> >>>> +properties:
> >>>> +  compatible:
> >>>> +    const: arm,mali-c55
> >>>> +
> >>>> +  reg:
> >>>> +    maxItems: 1
> >>>> +
> >>>> +  interrupts:
> >>>> +    maxItems: 1
> >>>> +
> >>>> +  clocks:
> >>>> +    items:
> >>>> +      - description: ISP video clock
> >>>
> >>> I wonder if we need this clock. Granted, it's an input clock to the ISP,
> >>> but it's part of the input video bus. I don't expect anyone would ever
> >>> need to control it manually, it should be provided by the video source
> >>> automatically.
> >>
> >> I'd say that if there's a clock controller providing this clock, even if
> >> it is implicit in the video feed it's good to have here. Being able to
> >> increment the refcount on that clock would be good, even if you don't
> >> actually control it manually?
> >
> > I don't expect there would be a clock controller to directly reference
> > in most cases. It depends a bit on where the clock domain crossing
> > between the source (often a CSI-2 receiver) and the ISP is. If it's
> > implemented in glue logic bundled with the ISP, which wouldn't be
> > described in DT as a separate node, then there's a higher chance we'll
> > have a clock controller for vclk. If it's implemented in the source,
> > vclk will just come from the source, which won't be listed as a clock
> > controller.
> >
> > One option would be to make this clock optional, by moving it to the end
> > of the clocks list, and setting
> >
> > 	minItems: 2
> > 	maxItems: 3
> >
> >>>> +      - description: ISP AXI clock
> >>>> +      - description: ISP AHB-lite clock
> >>>
> >>> These two other clocks look good to me.
> >>>
> >>>> +
> >>>> +  clock-names:
> >>>> +    items:
> >>>> +      - const: vclk
> >>>> +      - const: aclk
> >>>> +      - const: hclk
> >>
> >> Why not "video" "axi" "ahb-lite"? There's 3 useful letters between the
> >> tree clock names you've provided - they're all clocks, so having "clk"
> >> in them is just noise :)
> >
> > As far as I understand, the names proposed by Dan come directly from the
> > IP core documentation.
> 
> This is the case, but I do take Conor's point that more descriptive names might be nicer - if I'm 
> honest I just didn't think about it particularly given "Xclk" is such a common name for them 
> already, but having been poked into thinking about it I do agree.

Isn't the usual practice in DT bindings is to name GPIOs, clocks and reset
signals based on the hardware documentation ?

-- 
Regards,

Laurent Pinchart


From cassel at kernel.org  Fri Feb 16 05:45:13 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Fri, 16 Feb 2024 14:45:13 +0100
Subject: [PATCH v2 0/2] PCI endpoint BAR hardware description cleanup
Message-ID: <20240216134524.1142149-1-cassel@kernel.org>

The series is based on top of:
https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=endpoint


Hello all,

This series cleans up the hardware description for PCI endpoint BARs.

The problems with the existing hardware description:
-The documentation is lackluster.
-Some of the names are confusingly similar, e.g. fixed_64bit and
 fixed_size, even though these are for completely unrelated things.
-The way that the BARs are defined in the endpoint controller drivers
 is messy, because the left hand side is not a BAR, so you can mark a
 BAR as e.g. both fixed size and reserved.

This series tries to address all the problems above.

Personally, I think that the code is more readable, both the endpoint
controller drivers, but also pci-epc-core.c.

(I will be sending out a patch series that adds BAR_RESIZABLE to enum
pci_epc_bar_type in the coming week.)


Kind regards,
Niklas


Changes since V1:
-Picked up tags from Kishon and Mani.
-Improved commit message for patch 1/2 as suggested by Mani.
-Improved kdoc in patch 2/2 as suggested by Mani.


Niklas Cassel (2):
  PCI: endpoint: Clean up hardware description for BARs
  PCI: endpoint: Drop only_64bit on reserved BARs

 drivers/pci/controller/dwc/pci-imx6.c         |  3 +-
 drivers/pci/controller/dwc/pci-keystone.c     | 12 +++---
 .../pci/controller/dwc/pci-layerscape-ep.c    |  5 ++-
 drivers/pci/controller/dwc/pcie-keembay.c     |  8 +++-
 drivers/pci/controller/dwc/pcie-rcar-gen4.c   |  4 +-
 drivers/pci/controller/dwc/pcie-tegra194.c    | 10 +++--
 drivers/pci/controller/dwc/pcie-uniphier-ep.c | 15 +++++--
 drivers/pci/controller/pcie-rcar-ep.c         | 14 ++++---
 drivers/pci/endpoint/functions/pci-epf-ntb.c  |  4 +-
 drivers/pci/endpoint/functions/pci-epf-test.c |  8 ++--
 drivers/pci/endpoint/functions/pci-epf-vntb.c |  2 +-
 drivers/pci/endpoint/pci-epc-core.c           | 25 +++++-------
 drivers/pci/endpoint/pci-epf-core.c           | 15 +++----
 include/linux/pci-epc.h                       | 39 ++++++++++++++++---
 14 files changed, 106 insertions(+), 58 deletions(-)

-- 
2.43.1



From cassel at kernel.org  Fri Feb 16 05:45:14 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Fri, 16 Feb 2024 14:45:14 +0100
Subject: [PATCH v2 1/2] PCI: endpoint: Clean up hardware description for BARs
In-Reply-To: <20240216134524.1142149-1-cassel@kernel.org>
References: <20240216134524.1142149-1-cassel@kernel.org>
Message-ID: <20240216134524.1142149-2-cassel@kernel.org>

The hardware description for BARs is scattered in many different variables
in pci_epc_features. Some of these things are mutually exclusive, so it
can create confusion over which variable that has precedence over another.

Improve the situation by creating a struct pci_epc_bar_desc, and a new
enum pci_epc_bar_type, and convert the endpoint controller drivers to use
this more well defined format.

Additionally, some endpoint controller drivers mark the BAR succeeding a
"64-bit only BAR" as reserved, while some do not. By definition, a 64-bit
BAR uses the succeeding BAR for the upper 32-bits, so an EPF driver cannot
use a BAR succeeding a 64-bit BAR. Ensure that all endpoint controller
drivers are uniform, and actually describe a reserved BAR as reserved.

Signed-off-by: Niklas Cassel <cassel at kernel.org>
Reviewed-by: Kishon Vijay Abraham I <kishon at kernel.org>
---
 drivers/pci/controller/dwc/pci-imx6.c         |  3 +-
 drivers/pci/controller/dwc/pci-keystone.c     | 12 +++----
 .../pci/controller/dwc/pci-layerscape-ep.c    |  5 ++-
 drivers/pci/controller/dwc/pcie-keembay.c     |  8 +++--
 drivers/pci/controller/dwc/pcie-rcar-gen4.c   |  4 ++-
 drivers/pci/controller/dwc/pcie-tegra194.c    | 10 ++++--
 drivers/pci/controller/dwc/pcie-uniphier-ep.c | 15 ++++++--
 drivers/pci/controller/pcie-rcar-ep.c         | 14 +++++---
 drivers/pci/endpoint/functions/pci-epf-ntb.c  |  4 +--
 drivers/pci/endpoint/functions/pci-epf-test.c |  8 ++---
 drivers/pci/endpoint/functions/pci-epf-vntb.c |  2 +-
 drivers/pci/endpoint/pci-epc-core.c           | 32 +++++++++--------
 drivers/pci/endpoint/pci-epf-core.c           | 15 ++++----
 include/linux/pci-epc.h                       | 34 +++++++++++++++----
 14 files changed, 108 insertions(+), 58 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index dc2c036ab28c..47a9a96484ed 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1081,7 +1081,8 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
 	.msix_capable = false,
-	.reserved_bar = 1 << BAR_1 | 1 << BAR_3,
+	.bar[BAR_1] = { .type = BAR_RESERVED, },
+	.bar[BAR_3] = { .type = BAR_RESERVED, },
 	.align = SZ_64K,
 };
 
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index c0c62533a3f1..b2b93b4fa82d 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -924,12 +924,12 @@ static const struct pci_epc_features ks_pcie_am654_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
 	.msix_capable = true,
-	.reserved_bar = 1 << BAR_0 | 1 << BAR_1,
-	.bar_fixed_64bit = 1 << BAR_0,
-	.bar_fixed_size[2] = SZ_1M,
-	.bar_fixed_size[3] = SZ_64K,
-	.bar_fixed_size[4] = 256,
-	.bar_fixed_size[5] = SZ_1M,
+	.bar[BAR_0] = { .type = BAR_RESERVED, .only_64bit = true, },
+	.bar[BAR_1] = { .type = BAR_RESERVED, },
+	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
+	.bar[BAR_3] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
+	.bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256, },
+	.bar[BAR_5] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
 	.align = SZ_1M,
 };
 
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index 2e398494e7c0..1f6ee1460ec2 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -250,7 +250,10 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
 	pci->dev = dev;
 	pci->ops = pcie->drvdata->dw_pcie_ops;
 
-	ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
+	ls_epc->bar[BAR_2].only_64bit = true;
+	ls_epc->bar[BAR_3].type = BAR_RESERVED;
+	ls_epc->bar[BAR_4].only_64bit = true;
+	ls_epc->bar[BAR_5].type = BAR_RESERVED;
 	ls_epc->linkup_notifier = true;
 
 	pcie->pci = pci;
diff --git a/drivers/pci/controller/dwc/pcie-keembay.c b/drivers/pci/controller/dwc/pcie-keembay.c
index 208d3b0ba196..5e8e54f597dd 100644
--- a/drivers/pci/controller/dwc/pcie-keembay.c
+++ b/drivers/pci/controller/dwc/pcie-keembay.c
@@ -312,8 +312,12 @@ static const struct pci_epc_features keembay_pcie_epc_features = {
 	.linkup_notifier	= false,
 	.msi_capable		= true,
 	.msix_capable		= true,
-	.reserved_bar		= BIT(BAR_1) | BIT(BAR_3) | BIT(BAR_5),
-	.bar_fixed_64bit	= BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
+	.bar[BAR_0]		= { .only_64bit = true, },
+	.bar[BAR_1]		= { .type = BAR_RESERVED, },
+	.bar[BAR_2]		= { .only_64bit = true, },
+	.bar[BAR_3]		= { .type = BAR_RESERVED, },
+	.bar[BAR_4]		= { .only_64bit = true, },
+	.bar[BAR_5]		= { .type = BAR_RESERVED, },
 	.align			= SZ_16K,
 };
 
diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index e9166619b1f9..0be760ed420b 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -383,7 +383,9 @@ static const struct pci_epc_features rcar_gen4_pcie_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
 	.msix_capable = false,
-	.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
+	.bar[BAR_1] = { .type = BAR_RESERVED, },
+	.bar[BAR_3] = { .type = BAR_RESERVED, },
+	.bar[BAR_5] = { .type = BAR_RESERVED, },
 	.align = SZ_1M,
 };
 
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 7afa9e9aabe2..1f7b662cb8e1 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -2007,9 +2007,13 @@ static const struct pci_epc_features tegra_pcie_epc_features = {
 	.core_init_notifier = true,
 	.msi_capable = false,
 	.msix_capable = false,
-	.reserved_bar = 1 << BAR_2 | 1 << BAR_3 | 1 << BAR_4 | 1 << BAR_5,
-	.bar_fixed_64bit = 1 << BAR_0,
-	.bar_fixed_size[0] = SZ_1M,
+	.bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = SZ_1M,
+			.only_64bit = true, },
+	.bar[BAR_1] = { .type = BAR_RESERVED, },
+	.bar[BAR_2] = { .type = BAR_RESERVED, },
+	.bar[BAR_3] = { .type = BAR_RESERVED, },
+	.bar[BAR_4] = { .type = BAR_RESERVED, },
+	.bar[BAR_5] = { .type = BAR_RESERVED, },
 };
 
 static const struct pci_epc_features*
diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
index 3fced0d3e851..265f65fc673f 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
@@ -411,8 +411,12 @@ static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = {
 		.msi_capable = true,
 		.msix_capable = false,
 		.align = 1 << 16,
-		.bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
-		.reserved_bar =  BIT(BAR_4),
+		.bar[BAR_0] = { .only_64bit = true, },
+		.bar[BAR_1] = { .type = BAR_RESERVED, },
+		.bar[BAR_2] = { .only_64bit = true, },
+		.bar[BAR_3] = { .type = BAR_RESERVED, },
+		.bar[BAR_4] = { .type = BAR_RESERVED, .only_64bit = true, },
+		.bar[BAR_5] = { .type = BAR_RESERVED, },
 	},
 };
 
@@ -425,7 +429,12 @@ static const struct uniphier_pcie_ep_soc_data uniphier_nx1_data = {
 		.msi_capable = true,
 		.msix_capable = false,
 		.align = 1 << 12,
-		.bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
+		.bar[BAR_0] = { .only_64bit = true, },
+		.bar[BAR_1] = { .type = BAR_RESERVED, },
+		.bar[BAR_2] = { .only_64bit = true, },
+		.bar[BAR_3] = { .type = BAR_RESERVED, },
+		.bar[BAR_4] = { .only_64bit = true, },
+		.bar[BAR_5] = { .type = BAR_RESERVED, },
 	},
 };
 
diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c
index e6909271def7..05967c6c0b42 100644
--- a/drivers/pci/controller/pcie-rcar-ep.c
+++ b/drivers/pci/controller/pcie-rcar-ep.c
@@ -440,11 +440,15 @@ static const struct pci_epc_features rcar_pcie_epc_features = {
 	.msi_capable = true,
 	.msix_capable = false,
 	/* use 64-bit BARs so mark BAR[1,3,5] as reserved */
-	.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
-	.bar_fixed_64bit = 1 << BAR_0 | 1 << BAR_2 | 1 << BAR_4,
-	.bar_fixed_size[0] = 128,
-	.bar_fixed_size[2] = 256,
-	.bar_fixed_size[4] = 256,
+	.bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = 128,
+			.only_64bit = true, },
+	.bar[BAR_1] = { .type = BAR_RESERVED, },
+	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = 256,
+			.only_64bit = true, },
+	.bar[BAR_3] = { .type = BAR_RESERVED, },
+	.bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256,
+			.only_64bit = true, },
+	.bar[BAR_5] = { .type = BAR_RESERVED, },
 };
 
 static const struct pci_epc_features*
diff --git a/drivers/pci/endpoint/functions/pci-epf-ntb.c b/drivers/pci/endpoint/functions/pci-epf-ntb.c
index 43cd309ce22f..e01a98e74d21 100644
--- a/drivers/pci/endpoint/functions/pci-epf-ntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-ntb.c
@@ -1012,13 +1012,13 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb,
 
 	epc_features = ntb_epc->epc_features;
 	barno = ntb_epc->epf_ntb_bar[BAR_CONFIG];
-	size = epc_features->bar_fixed_size[barno];
+	size = epc_features->bar[barno].fixed_size;
 	align = epc_features->align;
 
 	peer_ntb_epc = ntb->epc[!type];
 	peer_epc_features = peer_ntb_epc->epc_features;
 	peer_barno = ntb_epc->epf_ntb_bar[BAR_PEER_SPAD];
-	peer_size = peer_epc_features->bar_fixed_size[peer_barno];
+	peer_size = peer_epc_features->bar[peer_barno].fixed_size;
 
 	/* Check if epc_features is populated incorrectly */
 	if ((!IS_ALIGNED(size, align)))
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 981894e40681..cd4ffb39dcdc 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -729,7 +729,7 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
 		 */
 		add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
 
-		if (!!(epc_features->reserved_bar & (1 << bar)))
+		if (epc_features->bar[bar].type == BAR_RESERVED)
 			continue;
 
 		ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no,
@@ -856,7 +856,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
 		if (bar == test_reg_bar)
 			continue;
 
-		if (!!(epc_features->reserved_bar & (1 << bar)))
+		if (epc_features->bar[bar].type == BAR_RESERVED)
 			continue;
 
 		base = pci_epf_alloc_space(epf, bar_size[bar], bar,
@@ -874,13 +874,11 @@ static void pci_epf_configure_bar(struct pci_epf *epf,
 				  const struct pci_epc_features *epc_features)
 {
 	struct pci_epf_bar *epf_bar;
-	bool bar_fixed_64bit;
 	int i;
 
 	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
 		epf_bar = &epf->bar[i];
-		bar_fixed_64bit = !!(epc_features->bar_fixed_64bit & (1 << i));
-		if (bar_fixed_64bit)
+		if (epc_features->bar[i].only_64bit)
 			epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
 	}
 }
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index 0675929fc529..8e779eecd62d 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -422,7 +422,7 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb)
 								epf->func_no,
 								epf->vfunc_no);
 	barno = ntb->epf_ntb_bar[BAR_CONFIG];
-	size = epc_features->bar_fixed_size[barno];
+	size = epc_features->bar[barno].fixed_size;
 	align = epc_features->align;
 
 	if ((!IS_ALIGNED(size, align)))
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index dcd4e66430c1..7fe8f4336765 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -87,7 +87,7 @@ EXPORT_SYMBOL_GPL(pci_epc_get);
  * @epc_features: pci_epc_features structure that holds the reserved bar bitmap
  *
  * Invoke to get the first unreserved BAR that can be used by the endpoint
- * function. For any incorrect value in reserved_bar return '0'.
+ * function.
  */
 enum pci_barno
 pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features)
@@ -102,32 +102,34 @@ EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
  * @bar: the starting BAR number from where unreserved BAR should be searched
  *
  * Invoke to get the next unreserved BAR starting from @bar that can be used
- * for endpoint function. For any incorrect value in reserved_bar return '0'.
+ * for endpoint function.
  */
 enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
 					 *epc_features, enum pci_barno bar)
 {
-	unsigned long free_bar;
+	int i;
 
 	if (!epc_features)
 		return BAR_0;
 
 	/* If 'bar - 1' is a 64-bit BAR, move to the next BAR */
-	if ((epc_features->bar_fixed_64bit << 1) & 1 << bar)
+	if (bar > 0 && epc_features->bar[bar - 1].only_64bit)
 		bar++;
 
-	/* Find if the reserved BAR is also a 64-bit BAR */
-	free_bar = epc_features->reserved_bar & epc_features->bar_fixed_64bit;
-
-	/* Set the adjacent bit if the reserved BAR is also a 64-bit BAR */
-	free_bar <<= 1;
-	free_bar |= epc_features->reserved_bar;
-
-	free_bar = find_next_zero_bit(&free_bar, 6, bar);
-	if (free_bar > 5)
-		return NO_BAR;
+	for (i = bar; i < PCI_STD_NUM_BARS; i++) {
+		/* If the BAR is not reserved, return it. */
+		if (epc_features->bar[i].type != BAR_RESERVED)
+			return i;
+
+		/*
+		 * If the BAR is reserved, and marked as 64-bit only, then the
+		 * succeeding BAR is also reserved.
+		 */
+		if (epc_features->bar[i].only_64bit)
+			i++;
+	}
 
-	return free_bar;
+	return NO_BAR;
 }
 EXPORT_SYMBOL_GPL(pci_epc_get_next_free_bar);
 
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index f2b4d34454c4..0a28a0b0911b 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -260,7 +260,7 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
 			  const struct pci_epc_features *epc_features,
 			  enum pci_epc_interface_type type)
 {
-	u64 bar_fixed_size = epc_features->bar_fixed_size[bar];
+	u64 bar_fixed_size = epc_features->bar[bar].fixed_size;
 	size_t align = epc_features->align;
 	struct pci_epf_bar *epf_bar;
 	dma_addr_t phys_addr;
@@ -271,13 +271,14 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
 	if (size < 128)
 		size = 128;
 
-	if (bar_fixed_size && size > bar_fixed_size) {
-		dev_err(&epf->dev, "requested BAR size is larger than fixed size\n");
-		return NULL;
-	}
-
-	if (bar_fixed_size)
+	if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) {
+		if (size > bar_fixed_size) {
+			dev_err(&epf->dev,
+				"requested BAR size is larger than fixed size\n");
+			return NULL;
+		}
 		size = bar_fixed_size;
+	}
 
 	if (align)
 		size = ALIGN(size, align);
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 40ea18f5aa02..4ccb4f4f3883 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -145,6 +145,32 @@ struct pci_epc {
 	unsigned long			function_num_map;
 };
 
+/**
+ * @BAR_PROGRAMMABLE: The BAR mask can be configured by the EPC.
+ * @BAR_FIXED: The BAR mask is fixed by the hardware.
+ * @BAR_RESERVED: The BAR should not be touched by an EPF driver.
+ */
+enum pci_epc_bar_type {
+	BAR_PROGRAMMABLE = 0,
+	BAR_FIXED,
+	BAR_RESERVED,
+};
+
+/**
+ * struct pci_epc_bar_desc - hardware description for a BAR
+ * @type: the type of the BAR
+ * @fixed_size: the fixed size, only applicable if type is BAR_FIXED_MASK.
+ * @only_64bit: if true, an EPF driver is not allowed to choose if this BAR
+ *		should be configured as 32-bit or 64-bit, the EPF driver must
+ *		configure this BAR as 64-bit. Additionally, the BAR succeeding
+ *		this BAR must be set to type BAR_RESERVED.
+ */
+struct pci_epc_bar_desc {
+	enum pci_epc_bar_type type;
+	u64 fixed_size;
+	bool only_64bit;
+};
+
 /**
  * struct pci_epc_features - features supported by a EPC device per function
  * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up
@@ -152,9 +178,7 @@ struct pci_epc {
  *			for initialization
  * @msi_capable: indicate if the endpoint function has MSI capability
  * @msix_capable: indicate if the endpoint function has MSI-X capability
- * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver
- * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs
- * @bar_fixed_size: Array specifying the size supported by each BAR
+ * @bar: array specifying the hardware description for each BAR
  * @align: alignment size required for BAR buffer allocation
  */
 struct pci_epc_features {
@@ -162,9 +186,7 @@ struct pci_epc_features {
 	unsigned int	core_init_notifier : 1;
 	unsigned int	msi_capable : 1;
 	unsigned int	msix_capable : 1;
-	u8	reserved_bar;
-	u8	bar_fixed_64bit;
-	u64	bar_fixed_size[PCI_STD_NUM_BARS];
+	struct	pci_epc_bar_desc bar[PCI_STD_NUM_BARS];
 	size_t	align;
 };
 
-- 
2.43.1



From cassel at kernel.org  Fri Feb 16 05:45:15 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Fri, 16 Feb 2024 14:45:15 +0100
Subject: [PATCH v2 2/2] PCI: endpoint: Drop only_64bit on reserved BARs
In-Reply-To: <20240216134524.1142149-1-cassel@kernel.org>
References: <20240216134524.1142149-1-cassel@kernel.org>
Message-ID: <20240216134524.1142149-3-cassel@kernel.org>

The definition of a reserved BAR is that EPF drivers should not touch
them.

The definition of only_64bit is that the EPF driver must configure this
BAR as 64-bit. (An EPF driver is not allowed to choose if this BAR should
be configured as 32-bit or 64-bit.)

Thus, it does not make sense to put only_64bit of a BAR that EPF drivers
are not allow to touch.

Drop the only_64bit property from hardware descriptions that are of type
reserved BAR.

Signed-off-by: Niklas Cassel <cassel at kernel.org>
Reviewed-by: Kishon Vijay Abraham I <kishon at kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pci-keystone.c     | 2 +-
 drivers/pci/controller/dwc/pcie-uniphier-ep.c | 2 +-
 drivers/pci/endpoint/pci-epc-core.c           | 7 -------
 include/linux/pci-epc.h                       | 5 +++++
 4 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index b2b93b4fa82d..844de4418724 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -924,7 +924,7 @@ static const struct pci_epc_features ks_pcie_am654_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
 	.msix_capable = true,
-	.bar[BAR_0] = { .type = BAR_RESERVED, .only_64bit = true, },
+	.bar[BAR_0] = { .type = BAR_RESERVED, },
 	.bar[BAR_1] = { .type = BAR_RESERVED, },
 	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
 	.bar[BAR_3] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
index 265f65fc673f..639bc2e12476 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
@@ -415,7 +415,7 @@ static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = {
 		.bar[BAR_1] = { .type = BAR_RESERVED, },
 		.bar[BAR_2] = { .only_64bit = true, },
 		.bar[BAR_3] = { .type = BAR_RESERVED, },
-		.bar[BAR_4] = { .type = BAR_RESERVED, .only_64bit = true, },
+		.bar[BAR_4] = { .type = BAR_RESERVED, },
 		.bar[BAR_5] = { .type = BAR_RESERVED, },
 	},
 };
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 7fe8f4336765..da3fc0795b0b 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -120,13 +120,6 @@ enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
 		/* If the BAR is not reserved, return it. */
 		if (epc_features->bar[i].type != BAR_RESERVED)
 			return i;
-
-		/*
-		 * If the BAR is reserved, and marked as 64-bit only, then the
-		 * succeeding BAR is also reserved.
-		 */
-		if (epc_features->bar[i].only_64bit)
-			i++;
 	}
 
 	return NO_BAR;
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 4ccb4f4f3883..cc2f70d061c8 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -164,6 +164,11 @@ enum pci_epc_bar_type {
  *		should be configured as 32-bit or 64-bit, the EPF driver must
  *		configure this BAR as 64-bit. Additionally, the BAR succeeding
  *		this BAR must be set to type BAR_RESERVED.
+ *
+ *		only_64bit should not be set on a BAR of type BAR_RESERVED.
+ *		(If BARx is a 64-bit BAR that an EPF driver is not allowed to
+ *		touch, then both BARx and BARx+1 must be set to type
+ *		BAR_RESERVED.)
  */
 struct pci_epc_bar_desc {
 	enum pci_epc_bar_type type;
-- 
2.43.1



From krzysztof.kozlowski at linaro.org  Fri Feb 16 05:52:36 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 14:52:36 +0100
Subject: [PATCH] interconnect: constify of_phandle_args in xlate
Message-ID: <20240216135236.129878-1-krzysztof.kozlowski@linaro.org>

The xlate callbacks are supposed to translate of_phandle_args to proper
provider without modifying the of_phandle_args.  Make the argument
pointer to const for code safety and readability.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 drivers/gpio/gpiolib-of.c              |  2 +-
 drivers/interconnect/core.c            |  4 ++--
 drivers/interconnect/qcom/icc-common.c |  3 ++-
 drivers/interconnect/qcom/icc-common.h |  3 ++-
 drivers/interconnect/samsung/exynos.c  |  2 +-
 drivers/memory/tegra/mc.c              |  2 +-
 drivers/memory/tegra/tegra124-emc.c    |  2 +-
 drivers/memory/tegra/tegra124.c        |  2 +-
 drivers/memory/tegra/tegra186-emc.c    |  2 +-
 drivers/memory/tegra/tegra20-emc.c     |  2 +-
 drivers/memory/tegra/tegra20.c         |  2 +-
 drivers/memory/tegra/tegra30-emc.c     |  2 +-
 drivers/memory/tegra/tegra30.c         |  2 +-
 include/linux/interconnect-provider.h  | 11 ++++++-----
 include/soc/tegra/mc.h                 |  7 ++++---
 15 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 35d717fd393f..708b0d51f4b7 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -129,7 +129,7 @@ static int of_gpiochip_match_node_and_xlate(struct gpio_chip *chip,
 }
 
 static struct gpio_device *
-of_find_gpio_device_by_xlate(struct of_phandle_args *gpiospec)
+of_find_gpio_device_by_xlate(const struct of_phandle_args *gpiospec)
 {
 	return gpio_device_find(gpiospec, of_gpiochip_match_node_and_xlate);
 }
diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
index 50bac2d79d9b..5d1010cafed8 100644
--- a/drivers/interconnect/core.c
+++ b/drivers/interconnect/core.c
@@ -343,7 +343,7 @@ EXPORT_SYMBOL_GPL(icc_std_aggregate);
  * an array of icc nodes specified in the icc_onecell_data struct when
  * registering the provider.
  */
-struct icc_node *of_icc_xlate_onecell(struct of_phandle_args *spec,
+struct icc_node *of_icc_xlate_onecell(const struct of_phandle_args *spec,
 				      void *data)
 {
 	struct icc_onecell_data *icc_data = data;
@@ -368,7 +368,7 @@ EXPORT_SYMBOL_GPL(of_icc_xlate_onecell);
  * Returns a valid pointer to struct icc_node_data on success or ERR_PTR()
  * on failure.
  */
-struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec)
+struct icc_node_data *of_icc_get_from_provider(const struct of_phandle_args *spec)
 {
 	struct icc_node *node = ERR_PTR(-EPROBE_DEFER);
 	struct icc_node_data *data = NULL;
diff --git a/drivers/interconnect/qcom/icc-common.c b/drivers/interconnect/qcom/icc-common.c
index f27f4fdc4531..9b9ee113f172 100644
--- a/drivers/interconnect/qcom/icc-common.c
+++ b/drivers/interconnect/qcom/icc-common.c
@@ -9,7 +9,8 @@
 
 #include "icc-common.h"
 
-struct icc_node_data *qcom_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+struct icc_node_data *qcom_icc_xlate_extended(const struct of_phandle_args *spec,
+					      void *data)
 {
 	struct icc_node_data *ndata;
 	struct icc_node *node;
diff --git a/drivers/interconnect/qcom/icc-common.h b/drivers/interconnect/qcom/icc-common.h
index 33bb2c38dff3..21c39b163948 100644
--- a/drivers/interconnect/qcom/icc-common.h
+++ b/drivers/interconnect/qcom/icc-common.h
@@ -8,6 +8,7 @@
 
 #include <linux/interconnect-provider.h>
 
-struct icc_node_data *qcom_icc_xlate_extended(struct of_phandle_args *spec, void *data);
+struct icc_node_data *qcom_icc_xlate_extended(const struct of_phandle_args *spec,
+					      void *data);
 
 #endif
diff --git a/drivers/interconnect/samsung/exynos.c b/drivers/interconnect/samsung/exynos.c
index 1ba14cb45d5a..c9e5361e17c5 100644
--- a/drivers/interconnect/samsung/exynos.c
+++ b/drivers/interconnect/samsung/exynos.c
@@ -82,7 +82,7 @@ static int exynos_generic_icc_set(struct icc_node *src, struct icc_node *dst)
 	return 0;
 }
 
-static struct icc_node *exynos_generic_icc_xlate(struct of_phandle_args *spec,
+static struct icc_node *exynos_generic_icc_xlate(const struct of_phandle_args *spec,
 						 void *data)
 {
 	struct exynos_icc_priv *priv = data;
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index a083921a8968..224b488794e5 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -755,7 +755,7 @@ const char *const tegra_mc_error_names[8] = {
 	[6] = "SMMU translation error",
 };
 
-struct icc_node *tegra_mc_icc_xlate(struct of_phandle_args *spec, void *data)
+struct icc_node *tegra_mc_icc_xlate(const struct of_phandle_args *spec, void *data)
 {
 	struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
 	struct icc_node *node;
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 00ed2b6a0d1b..47c0c19e13fd 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -1285,7 +1285,7 @@ to_tegra_emc_provider(struct icc_provider *provider)
 }
 
 static struct icc_node_data *
-emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct icc_provider *provider = data;
 	struct icc_node_data *ndata;
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index 470b7dbab2c2..9d7393e19f12 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -1170,7 +1170,7 @@ static int tegra124_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
 }
 
 static struct icc_node_data *
-tegra124_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+tegra124_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
 	const struct tegra_mc_client *client;
diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c
index fcd4aea48bda..57d9ae12fcfe 100644
--- a/drivers/memory/tegra/tegra186-emc.c
+++ b/drivers/memory/tegra/tegra186-emc.c
@@ -236,7 +236,7 @@ static int tegra_emc_icc_set_bw(struct icc_node *src, struct icc_node *dst)
 }
 
 static struct icc_node *
-tegra_emc_of_icc_xlate(struct of_phandle_args *spec, void *data)
+tegra_emc_of_icc_xlate(const struct of_phandle_args *spec, void *data)
 {
 	struct icc_provider *provider = data;
 	struct icc_node *node;
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index fd595c851a27..97cf59523b0b 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -950,7 +950,7 @@ to_tegra_emc_provider(struct icc_provider *provider)
 }
 
 static struct icc_node_data *
-emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct icc_provider *provider = data;
 	struct icc_node_data *ndata;
diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
index aa4b97d5e732..a3022e715dee 100644
--- a/drivers/memory/tegra/tegra20.c
+++ b/drivers/memory/tegra/tegra20.c
@@ -390,7 +390,7 @@ static int tegra20_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
 }
 
 static struct icc_node_data *
-tegra20_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+tegra20_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
 	unsigned int i, idx = spec->args[0];
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 9eae25c57ec6..d7b0a23c2d7d 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -1468,7 +1468,7 @@ to_tegra_emc_provider(struct icc_provider *provider)
 }
 
 static struct icc_node_data *
-emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct icc_provider *provider = data;
 	struct icc_node_data *ndata;
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index 06f8b35e0a14..d3e685c8431f 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -1332,7 +1332,7 @@ static int tegra30_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
 }
 
 static struct icc_node_data *
-tegra30_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+tegra30_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
 	const struct tegra_mc_client *client;
diff --git a/include/linux/interconnect-provider.h b/include/linux/interconnect-provider.h
index 7ba183f221f1..f5aef8784692 100644
--- a/include/linux/interconnect-provider.h
+++ b/include/linux/interconnect-provider.h
@@ -36,7 +36,7 @@ struct icc_onecell_data {
 	struct icc_node *nodes[] __counted_by(num_nodes);
 };
 
-struct icc_node *of_icc_xlate_onecell(struct of_phandle_args *spec,
+struct icc_node *of_icc_xlate_onecell(const struct of_phandle_args *spec,
 				      void *data);
 
 /**
@@ -65,8 +65,9 @@ struct icc_provider {
 			 u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
 	void (*pre_aggregate)(struct icc_node *node);
 	int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);
-	struct icc_node* (*xlate)(struct of_phandle_args *spec, void *data);
-	struct icc_node_data* (*xlate_extended)(struct of_phandle_args *spec, void *data);
+	struct icc_node* (*xlate)(const struct of_phandle_args *spec, void *data);
+	struct icc_node_data* (*xlate_extended)(const struct of_phandle_args *spec,
+						void *data);
 	struct device		*dev;
 	int			users;
 	bool			inter_set;
@@ -124,7 +125,7 @@ int icc_nodes_remove(struct icc_provider *provider);
 void icc_provider_init(struct icc_provider *provider);
 int icc_provider_register(struct icc_provider *provider);
 void icc_provider_deregister(struct icc_provider *provider);
-struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec);
+struct icc_node_data *of_icc_get_from_provider(const struct of_phandle_args *spec);
 void icc_sync_state(struct device *dev);
 
 #else
@@ -171,7 +172,7 @@ static inline int icc_provider_register(struct icc_provider *provider)
 
 static inline void icc_provider_deregister(struct icc_provider *provider) { }
 
-static inline struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec)
+static inline struct icc_node_data *of_icc_get_from_provider(const struct of_phandle_args *spec)
 {
 	return ERR_PTR(-ENOTSUPP);
 }
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index af1d73a7f0cd..6ee4c59db620 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -146,13 +146,14 @@ struct tegra_mc_icc_ops {
 	int (*set)(struct icc_node *src, struct icc_node *dst);
 	int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw,
 			 u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
-	struct icc_node* (*xlate)(struct of_phandle_args *spec, void *data);
-	struct icc_node_data *(*xlate_extended)(struct of_phandle_args *spec,
+	struct icc_node* (*xlate)(const struct of_phandle_args *spec, void *data);
+	struct icc_node_data *(*xlate_extended)(const struct of_phandle_args *spec,
 						void *data);
 	int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);
 };
 
-struct icc_node *tegra_mc_icc_xlate(struct of_phandle_args *spec, void *data);
+struct icc_node *tegra_mc_icc_xlate(const struct of_phandle_args *spec,
+				    void *data);
 extern const struct tegra_mc_icc_ops tegra_mc_icc_ops;
 
 struct tegra_mc_ops {
-- 
2.34.1



From vaishnav.a at ti.com  Fri Feb 16 05:55:32 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Fri, 16 Feb 2024 19:25:32 +0530
Subject: [PATCH 1/2] arm64: dts: ti: k3-j722s-evm: Enable CPSW3G RGMII1
In-Reply-To: <20240216135533.904130-1-vaishnav.a@ti.com>
References: <20240216135533.904130-1-vaishnav.a@ti.com>
Message-ID: <20240216135533.904130-2-vaishnav.a@ti.com>

From: Siddharth Vadapalli <s-vadapalli at ti.com>

Enable MAC Port 1 of CPSW3G instance of CPSW Ethernet Switch in
RGMII-RXID mode of operation. Port 2 is not connected on the EVM,
thus keep it disabled.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 53 +++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
index b4f2fee53a97..9e12a6e9111f 100644
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
@@ -8,6 +8,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/net/ti-dp83867.h>
 #include "k3-j722s.dtsi"
 
 / {
@@ -160,6 +161,58 @@ J722S_IOPAD(0x0240, PIN_INPUT, 0) /* (B24) MMC1_SDCD */
 		>;
 		bootph-all;
 	};
+
+	mdio_pins_default: mdio-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AC24) MDIO0_MDC */
+			J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) MDIO0_MDIO */
+		>;
+	};
+
+	rgmii1_pins_default: rgmii1-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x014c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */
+			J722S_IOPAD(0x0150, PIN_INPUT, 0) /* (AD27) RGMII1_RD1 */
+			J722S_IOPAD(0x0154, PIN_INPUT, 0) /* (AE24) RGMII1_RD2 */
+			J722S_IOPAD(0x0158, PIN_INPUT, 0) /* (AE26) RGMII1_RD3 */
+			J722S_IOPAD(0x0148, PIN_INPUT, 0) /* (AE27) RGMII1_RXC */
+			J722S_IOPAD(0x0144, PIN_INPUT, 0) /* (AD23) RGMII1_RX_CTL */
+			J722S_IOPAD(0x0134, PIN_OUTPUT, 0) /* (AF27) RGMII1_TD0 */
+			J722S_IOPAD(0x0138, PIN_OUTPUT, 0) /* (AE23) RGMII1_TD1 */
+			J722S_IOPAD(0x013c, PIN_OUTPUT, 0) /* (AG25) RGMII1_TD2 */
+			J722S_IOPAD(0x0140, PIN_OUTPUT, 0) /* (AF24) RGMII1_TD3 */
+			J722S_IOPAD(0x0130, PIN_OUTPUT, 0) /* (AG26) RGMII1_TXC */
+			J722S_IOPAD(0x012c, PIN_OUTPUT, 0) /* (AF25) RGMII1_TX_CTL */
+		>;
+	};
+};
+
+&cpsw3g {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins_default>;
+};
+
+&cpsw3g_mdio {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio_pins_default>;
+
+	cpsw3g_phy0: ethernet-phy at 0 {
+		reg = <0>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,min-output-impedance;
+	};
+};
+
+&cpsw_port1 {
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&cpsw3g_phy0>;
+};
+
+&cpsw_port2 {
+	status = "disabled";
 };
 
 &main_gpio1 {
-- 
2.34.1



From vaishnav.a at ti.com  Fri Feb 16 05:55:33 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Fri, 16 Feb 2024 19:25:33 +0530
Subject: [PATCH 2/2] arm64: dts: ti: k3-j722s-evm: Enable OSPI NOR support
In-Reply-To: <20240216135533.904130-1-vaishnav.a@ti.com>
References: <20240216135533.904130-1-vaishnav.a@ti.com>
Message-ID: <20240216135533.904130-3-vaishnav.a@ti.com>

J722S EVM has S28HS512T 64 MiB Octal SPI NOR flash connected
to the OSPI interface, add support for the flash and describe
the partition information as per bootloader.

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 79 +++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
index 9e12a6e9111f..b1c6499c0c9d 100644
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
@@ -169,6 +169,23 @@ J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) MDIO0_MDIO */
 		>;
 	};
 
+	ospi0_pins_default: ospi0-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0000, PIN_OUTPUT, 0) /* (P23) OSPI0_CLK */
+			J722S_IOPAD(0x002c, PIN_OUTPUT, 0) /* (M25) OSPI0_CSn0 */
+			J722S_IOPAD(0x000c, PIN_INPUT, 0) /* (L25) OSPI0_D0 */
+			J722S_IOPAD(0x0010, PIN_INPUT, 0) /* (N24) OSPI0_D1 */
+			J722S_IOPAD(0x0014, PIN_INPUT, 0) /* (N25) OSPI0_D2 */
+			J722S_IOPAD(0x0018, PIN_INPUT, 0) /* (M24) OSPI0_D3 */
+			J722S_IOPAD(0x001c, PIN_INPUT, 0) /* (N21) OSPI0_D4 */
+			J722S_IOPAD(0x0020, PIN_INPUT, 0) /* (N22) OSPI0_D5 */
+			J722S_IOPAD(0x0024, PIN_INPUT, 0) /* (P21) OSPI0_D6 */
+			J722S_IOPAD(0x0028, PIN_INPUT, 0) /* (N20) OSPI0_D7 */
+			J722S_IOPAD(0x0008, PIN_INPUT, 0) /* (P22) OSPI0_DQS */
+		>;
+		bootph-all;
+	};
+
 	rgmii1_pins_default: rgmii1-default-pins {
 		pinctrl-single,pins = <
 			J722S_IOPAD(0x014c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */
@@ -290,6 +307,68 @@ exp1: gpio at 23 {
 	};
 };
 
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_pins_default>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <4>;
+		bootph-all;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "ospi.tiboot3";
+				reg = <0x00 0x80000>;
+			};
+
+			partition at 80000 {
+				label = "ospi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition at 280000 {
+				label = "ospi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition at 680000 {
+				label = "ospi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition at 6c0000 {
+				label = "ospi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition at 800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition at 3fc0000 {
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+
+};
+
 &sdhci1 {
 	/* SD/MMC */
 	vmmc-supply = <&vdd_mmc1>;
-- 
2.34.1



From vaishnav.a at ti.com  Fri Feb 16 05:55:31 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Fri, 16 Feb 2024 19:25:31 +0530
Subject: [PATCH 0/2] Add OSPI and Ethernet support on J722S EVM
Message-ID: <20240216135533.904130-1-vaishnav.a@ti.com>

Hi,

This series adds support for Ethernet and OSPI NOR flash on J722S EVM.

EVM Schematics are available at:
	https://www.ti.com/lit/zip/sprr495

Test log (6.8.0-rc4-next-20240216):
  https://gist.github.com/vaishnavachath/b04e3be90af4cdec59fb0d9cc72441b9

For those interested, more details about this SoC can be found in the
Technical Reference Manual here:
            https://www.ti.com/lit/zip/sprujb3

Thanks and Regards,
Vaishnav

Siddharth Vadapalli (1):
  arm64: dts: ti: k3-j722s-evm: Enable CPSW3G RGMII1

Vaishnav Achath (1):
  arm64: dts: ti: k3-j722s-evm: Enable OSPI NOR support

 arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 132 ++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

-- 
2.34.1



From konrad.dybcio at linaro.org  Fri Feb 16 05:55:58 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 16 Feb 2024 14:55:58 +0100
Subject: [PATCH] interconnect: constify of_phandle_args in xlate
In-Reply-To: <20240216135236.129878-1-krzysztof.kozlowski@linaro.org>
References: <20240216135236.129878-1-krzysztof.kozlowski@linaro.org>
Message-ID: <488cc7dc-f45a-4c9e-b572-e4a6b3202e3e@linaro.org>

On 16.02.2024 14:52, Krzysztof Kozlowski wrote:
> The xlate callbacks are supposed to translate of_phandle_args to proper
> provider without modifying the of_phandle_args.  Make the argument
> pointer to const for code safety and readability.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>  drivers/gpio/gpiolib-of.c              |  2 +-
>  drivers/interconnect/core.c            |  4 ++--
>  drivers/interconnect/qcom/icc-common.c |  3 ++-
>  drivers/interconnect/qcom/icc-common.h |  3 ++-
>  drivers/interconnect/samsung/exynos.c  |  2 +-
>  drivers/memory/tegra/mc.c              |  2 +-
>  drivers/memory/tegra/tegra124-emc.c    |  2 +-
>  drivers/memory/tegra/tegra124.c        |  2 +-
>  drivers/memory/tegra/tegra186-emc.c    |  2 +-
>  drivers/memory/tegra/tegra20-emc.c     |  2 +-
>  drivers/memory/tegra/tegra20.c         |  2 +-
>  drivers/memory/tegra/tegra30-emc.c     |  2 +-
>  drivers/memory/tegra/tegra30.c         |  2 +-
>  include/linux/interconnect-provider.h  | 11 ++++++-----
>  include/soc/tegra/mc.h                 |  7 ++++---

Ended up being a bit wider than just icc..

Looks sane apart from that

Konrad


From konrad.dybcio at linaro.org  Fri Feb 16 05:56:21 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 16 Feb 2024 14:56:21 +0100
Subject: [PATCH] interconnect: constify of_phandle_args in xlate
In-Reply-To: <20240216135236.129878-1-krzysztof.kozlowski@linaro.org>
References: <20240216135236.129878-1-krzysztof.kozlowski@linaro.org>
Message-ID: <84adc2ac-db49-4358-a079-6991c6770a73@linaro.org>

On 16.02.2024 14:52, Krzysztof Kozlowski wrote:
> The xlate callbacks are supposed to translate of_phandle_args to proper
> provider without modifying the of_phandle_args.  Make the argument
> pointer to const for code safety and readability.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---

Acked-by: Konrad Dybcio <konrad.dybcio at linaro.org>

Konrad


From krzysztof.kozlowski at linaro.org  Fri Feb 16 05:59:33 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 14:59:33 +0100
Subject: [PATCH] interconnect: constify of_phandle_args in xlate
In-Reply-To: <488cc7dc-f45a-4c9e-b572-e4a6b3202e3e@linaro.org>
References: <20240216135236.129878-1-krzysztof.kozlowski@linaro.org>
 <488cc7dc-f45a-4c9e-b572-e4a6b3202e3e@linaro.org>
Message-ID: <41e371f1-96f4-45c0-9f65-81ed6924b325@linaro.org>

On 16/02/2024 14:55, Konrad Dybcio wrote:
> On 16.02.2024 14:52, Krzysztof Kozlowski wrote:
>> The xlate callbacks are supposed to translate of_phandle_args to proper
>> provider without modifying the of_phandle_args.  Make the argument
>> pointer to const for code safety and readability.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>> ---
>>  drivers/gpio/gpiolib-of.c              |  2 +-
>>  drivers/interconnect/core.c            |  4 ++--
>>  drivers/interconnect/qcom/icc-common.c |  3 ++-
>>  drivers/interconnect/qcom/icc-common.h |  3 ++-
>>  drivers/interconnect/samsung/exynos.c  |  2 +-
>>  drivers/memory/tegra/mc.c              |  2 +-
>>  drivers/memory/tegra/tegra124-emc.c    |  2 +-
>>  drivers/memory/tegra/tegra124.c        |  2 +-
>>  drivers/memory/tegra/tegra186-emc.c    |  2 +-
>>  drivers/memory/tegra/tegra20-emc.c     |  2 +-
>>  drivers/memory/tegra/tegra20.c         |  2 +-
>>  drivers/memory/tegra/tegra30-emc.c     |  2 +-
>>  drivers/memory/tegra/tegra30.c         |  2 +-
>>  include/linux/interconnect-provider.h  | 11 ++++++-----
>>  include/soc/tegra/mc.h                 |  7 ++++---
> 
> Ended up being a bit wider than just icc..
> 
> Looks sane apart from that

Tegra memory controllers are also interconnect providers, so two subsystems.

This patch should go via interconnect tree.

Best regards,
Krzysztof



From tudor.ambarus at linaro.org  Fri Feb 16 06:04:42 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 14:04:42 +0000
Subject: [PATCH v2 0/7] ARM: dts: samsung: specify the SPI FIFO depth
Message-ID: <20240216140449.2564625-1-tudor.ambarus@linaro.org>

Bindings patch sent but not yet integrated:
https://lore.kernel.org/linux-spi/20240216070555.2483977-2-tudor.ambarus at linaro.org/

Up to now the SPI alias was used as an index into an array defined in
the SPI driver to determine the SPI FIFO depth. Drop the dependency on
the SPI alias and specify the SPI FIFO depth directly into the SPI node.

Update all the device trees that have instances of the SPI IP with
different FIFO depths.

For the SoCs where all the SPI instances have the same FIFO depth (like
gs101 and exynos850), the FIFO depth is inferred from the compatible.
Similar SoCs shall do the same.

v2:
- use "fifo-depth" property (instead of "samsung,spi-fifosize")
- update commit messages
- reorder patches. Last is using common sense for determining the FIFO
  depth. The nodes are not enabled in any device tree, thus upstream
  will be fine even if comon sense fails. I guess we can update the
  device tree later on if needed. Or we can just drop the last patch. 

v1:
https://lore.kernel.org/linux-spi/20240125151630.753318-1-tudor.ambarus at linaro.org/

Tudor Ambarus (7):
  ARM: dts: samsung: exynos3250: specify the SPI FIFO depth
  ARM: dts: samsung: exynos4: specify the SPI FIFO depth
  ARM: dts: samsung: exynos5250: specify the SPI FIFO depth
  ARM: dts: samsung: exynos5420: specify the SPI FIFO depth
  ARM: dts: samsung: exynos5433: specify the SPI FIFO depth
  ARM: dts: samsung: exynosautov9: specify the SPI FIFO depth
  ARM: dts: samsung: s5pv210: specify the SPI FIFO depth

 arch/arm/boot/dts/samsung/exynos3250.dtsi    |  2 ++
 arch/arm/boot/dts/samsung/exynos4.dtsi       |  3 +++
 arch/arm/boot/dts/samsung/exynos5250.dtsi    |  3 +++
 arch/arm/boot/dts/samsung/exynos5420.dtsi    |  3 +++
 arch/arm/boot/dts/samsung/s5pv210.dtsi       |  2 ++
 arch/arm64/boot/dts/exynos/exynos5433.dtsi   |  5 +++++
 arch/arm64/boot/dts/exynos/exynosautov9.dtsi | 12 ++++++++++++
 7 files changed, 30 insertions(+)

-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Fri Feb 16 06:04:43 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 14:04:43 +0000
Subject: [PATCH v2 1/7] ARM: dts: samsung: exynos3250: specify the SPI FIFO depth
In-Reply-To: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
References: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
Message-ID: <20240216140449.2564625-2-tudor.ambarus@linaro.org>

Up to now the SPI alias was used as an index into an array defined in
the SPI driver to determine the SPI FIFO depth. Drop the dependency on
the SPI alias and specify the SPI FIFO depth directly into the SPI node.

exynos3250.dtsi defines the following aliases:
	spi0 = &spi_0;
	spi1 = &spi_1;
spi-s3c64xx.c driver defines the following fifo_lvl_mask for the
"samsung,exynos4210-spi" compatible:
	.fifo_lvl_mask  = { 0x1ff, 0x7F, 0x7F },
Thus spi0 was considered having a 256 byte FIFO depth, and spi1 a 64
byte FIFO depth. Update device tree with these FIFO depths. No
functional change expected.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm/boot/dts/samsung/exynos3250.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/samsung/exynos3250.dtsi b/arch/arm/boot/dts/samsung/exynos3250.dtsi
index 3f1015edab43..b6c3826a9424 100644
--- a/arch/arm/boot/dts/samsung/exynos3250.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos3250.dtsi
@@ -826,6 +826,7 @@ spi_0: spi at 13920000 {
 			samsung,spi-src-clk = <0>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi0_bus>;
+			fifo-depth = <256>;
 			status = "disabled";
 		};
 
@@ -842,6 +843,7 @@ spi_1: spi at 13930000 {
 			samsung,spi-src-clk = <0>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi1_bus>;
+			fifo-depth = <64>;
 			status = "disabled";
 		};
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Fri Feb 16 06:04:44 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 14:04:44 +0000
Subject: [PATCH v2 2/7] ARM: dts: samsung: exynos4: specify the SPI FIFO depth
In-Reply-To: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
References: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
Message-ID: <20240216140449.2564625-3-tudor.ambarus@linaro.org>

Up to now the SPI alias was used as an index into an array defined in
the SPI driver to determine the SPI FIFO depth. Drop the dependency on
the SPI alias and specify the SPI FIFO depth directly into the SPI node.

exynos4.dtsi defines the following SPI aliases:
	spi0 = &spi_0;
	spi1 = &spi_1;
	spi2 = &spi_2;
spi-s3c64xx.c driver defines the following fifo_lvl_mask for the
"samsung,exynos4210-spi" compatible:
	.fifo_lvl_mask  = { 0x1ff, 0x7F, 0x7F },
Thus spi0 was considered having a 256 byte FIFO depth, and spi1 and spi2
having 64 byte FIFO depth each. Update device tree with these FIFO depths.
No functional change expected.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm/boot/dts/samsung/exynos4.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/samsung/exynos4.dtsi b/arch/arm/boot/dts/samsung/exynos4.dtsi
index 7f981b5c0d64..ed47d0ce04e1 100644
--- a/arch/arm/boot/dts/samsung/exynos4.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4.dtsi
@@ -621,6 +621,7 @@ spi_0: spi at 13920000 {
 			clock-names = "spi", "spi_busclk0";
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi0_bus>;
+			fifo-depth = <256>;
 			status = "disabled";
 		};
 
@@ -636,6 +637,7 @@ spi_1: spi at 13930000 {
 			clock-names = "spi", "spi_busclk0";
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi1_bus>;
+			fifo-depth = <64>;
 			status = "disabled";
 		};
 
@@ -651,6 +653,7 @@ spi_2: spi at 13940000 {
 			clock-names = "spi", "spi_busclk0";
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi2_bus>;
+			fifo-depth = <64>;
 			status = "disabled";
 		};
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Fri Feb 16 06:04:45 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 14:04:45 +0000
Subject: [PATCH v2 3/7] ARM: dts: samsung: exynos5250: specify the SPI FIFO depth
In-Reply-To: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
References: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
Message-ID: <20240216140449.2564625-4-tudor.ambarus@linaro.org>

Up to now the SPI alias was used as an index into an array defined in
the SPI driver to determine the SPI FIFO depth. Drop the dependency on
the SPI alias and specify the SPI FIFO depth directly into the SPI node.

exynos5250.dtsi defines the following aliases:
	spi0 = &spi_0;
	spi1 = &spi_1;
	spi2 = &spi_2;
spi-s3c64xx.c driver defines the following fifo_lvl_mask for the
"samsung,exynos4210-spi" compatible:
	.fifo_lvl_mask  = { 0x1ff, 0x7F, 0x7F },
Thus spi0 was considered having a 256 byte FIFO depth, and spi1 and spi2
having 64 byte FIFO depth each. Update device tree with these FIFO depths.
No functional change expected.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm/boot/dts/samsung/exynos5250.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/samsung/exynos5250.dtsi b/arch/arm/boot/dts/samsung/exynos5250.dtsi
index 99c84bebf25a..b9e7c4938818 100644
--- a/arch/arm/boot/dts/samsung/exynos5250.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos5250.dtsi
@@ -511,6 +511,7 @@ spi_0: spi at 12d20000 {
 			clock-names = "spi", "spi_busclk0";
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi0_bus>;
+			fifo-depth = <256>;
 		};
 
 		spi_1: spi at 12d30000 {
@@ -526,6 +527,7 @@ spi_1: spi at 12d30000 {
 			clock-names = "spi", "spi_busclk0";
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi1_bus>;
+			fifo-depth = <64>;
 		};
 
 		spi_2: spi at 12d40000 {
@@ -541,6 +543,7 @@ spi_2: spi at 12d40000 {
 			clock-names = "spi", "spi_busclk0";
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi2_bus>;
+			fifo-depth = <64>;
 		};
 
 		mmc_0: mmc at 12200000 {
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Fri Feb 16 06:04:46 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 14:04:46 +0000
Subject: [PATCH v2 4/7] ARM: dts: samsung: exynos5420: specify the SPI FIFO depth
In-Reply-To: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
References: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
Message-ID: <20240216140449.2564625-5-tudor.ambarus@linaro.org>

Up to now the SPI alias was used as an index into an array defined in
the SPI driver to determine the SPI FIFO depth. Drop the dependency on
the SPI alias and specify the SPI FIFO depth directly into the SPI node.

exynos5420.dtsi defines the following aliases:
	spi0 = &spi_0;
	spi1 = &spi_1;
	spi2 = &spi_2;
spi-s3c64xx.c driver defines the following fifo_lvl_mask for the
"samsung,exynos4210-spi" compatible:
	.fifo_lvl_mask  = { 0x1ff, 0x7F, 0x7F },
Thus spi0 was considered having a 256 byte FIFO depth, and spi1 and spi2
having 64 byte FIFO depth each. Update device tree with these FIFO depths.
No functional change expected.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm/boot/dts/samsung/exynos5420.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/samsung/exynos5420.dtsi b/arch/arm/boot/dts/samsung/exynos5420.dtsi
index 25ed90374679..196c6d04675a 100644
--- a/arch/arm/boot/dts/samsung/exynos5420.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos5420.dtsi
@@ -658,6 +658,7 @@ spi_0: spi at 12d20000 {
 			pinctrl-0 = <&spi0_bus>;
 			clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
 			clock-names = "spi", "spi_busclk0";
+			fifo-depth = <256>;
 			status = "disabled";
 		};
 
@@ -674,6 +675,7 @@ spi_1: spi at 12d30000 {
 			pinctrl-0 = <&spi1_bus>;
 			clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
 			clock-names = "spi", "spi_busclk0";
+			fifo-depth = <64>;
 			status = "disabled";
 		};
 
@@ -690,6 +692,7 @@ spi_2: spi at 12d40000 {
 			pinctrl-0 = <&spi2_bus>;
 			clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
 			clock-names = "spi", "spi_busclk0";
+			fifo-depth = <64>;
 			status = "disabled";
 		};
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Fri Feb 16 06:04:47 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 14:04:47 +0000
Subject: [PATCH v2 5/7] ARM: dts: samsung: exynos5433: specify the SPI FIFO depth
In-Reply-To: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
References: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
Message-ID: <20240216140449.2564625-6-tudor.ambarus@linaro.org>

Up to now the SPI alias was used as an index into an array defined in
the SPI driver to determine the SPI FIFO depthj Drop the dependency on
the SPI alias and specify the SPI FIFO depth directly into the SPI node.

The FIFO depth were determined based on the SPI aliases that are defined
in exynos5433-tm2-common.dtsi:
	spi0 = &spi_0;
	spi1 = &spi_1;
	spi2 = &spi_2;
	spi3 = &spi_3;
	spi4 = &spi_4;
spi-s3c64xx.c driver defines the following fifo_lvl_mask for the
"samsung,exynos5433-spi" compatible:
	.fifo_lvl_mask  = { 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff},
Thus spi{0, 4} were considered having 256 byte FIFO depths, and
spi{1, 2, 3} having 64 byte FIFO depths. Update device tree with these
FIFO depths. No functional change expected.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/exynos5433.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index 7fbbec04bff0..0b9053b9b2b5 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -1468,6 +1468,7 @@ spi_0: spi at 14d20000 {
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi0_bus>;
 			num-cs = <1>;
+			fifo-depth = <256>;
 			status = "disabled";
 		};
 
@@ -1487,6 +1488,7 @@ spi_1: spi at 14d30000 {
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi1_bus>;
 			num-cs = <1>;
+			fifo-depth = <64>;
 			status = "disabled";
 		};
 
@@ -1506,6 +1508,7 @@ spi_2: spi at 14d40000 {
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi2_bus>;
 			num-cs = <1>;
+			fifo-depth = <64>;
 			status = "disabled";
 		};
 
@@ -1525,6 +1528,7 @@ spi_3: spi at 14d50000 {
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi3_bus>;
 			num-cs = <1>;
+			fifo-depth = <64>;
 			status = "disabled";
 		};
 
@@ -1544,6 +1548,7 @@ spi_4: spi at 14d00000 {
 			pinctrl-names = "default";
 			pinctrl-0 = <&spi4_bus>;
 			num-cs = <1>;
+			fifo-depth = <64>;
 			status = "disabled";
 		};
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Fri Feb 16 06:04:48 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 14:04:48 +0000
Subject: [PATCH v2 6/7] ARM: dts: samsung: exynosautov9: specify the SPI FIFO depth
In-Reply-To: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
References: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
Message-ID: <20240216140449.2564625-7-tudor.ambarus@linaro.org>

Up to now the SPI alias was used as an index into an array defined in
the SPI driver to determine the SPI FIFO depth. Drop the dependency on
the SPI alias and specify the SPI FIFO depth directly into the SPI node.

There are no SPI aliases defined, thus the FIFO depth was determined by
matching the FIFO depth of the I2C node of the same USI parent.
No functional change expected.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm64/boot/dts/exynos/exynosautov9.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynosautov9.dtsi b/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
index c871a2f49fda..0248329da49a 100644
--- a/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
@@ -435,6 +435,7 @@ spi_0: spi at 10300000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <256>;
 				status = "disabled";
 			};
 
@@ -526,6 +527,7 @@ spi_1: spi at 10320000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <256>;
 				status = "disabled";
 			};
 
@@ -617,6 +619,7 @@ spi_2: spi at 10340000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <64>;
 				status = "disabled";
 			};
 
@@ -708,6 +711,7 @@ spi_3: spi at 10360000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <64>;
 				status = "disabled";
 			};
 
@@ -799,6 +803,7 @@ spi_4: spi at 10380000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <64>;
 				status = "disabled";
 			};
 
@@ -890,6 +895,7 @@ spi_5: spi at 103a0000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <64>;
 				status = "disabled";
 			};
 
@@ -981,6 +987,7 @@ spi_6: spi at 10900000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <256>;
 				status = "disabled";
 			};
 
@@ -1072,6 +1079,7 @@ spi_7: spi at 10920000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <64>;
 				status = "disabled";
 			};
 
@@ -1163,6 +1171,7 @@ spi_8: spi at 10940000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <64>;
 				status = "disabled";
 			};
 
@@ -1254,6 +1263,7 @@ spi_9: spi at 10960000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <64>;
 				status = "disabled";
 			};
 
@@ -1345,6 +1355,7 @@ spi_10: spi at 10980000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <64>;
 				status = "disabled";
 			};
 
@@ -1434,6 +1445,7 @@ spi_11: spi at 109a0000 {
 				num-cs = <1>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				fifo-depth = <64>;
 				status = "disabled";
 			};
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From tudor.ambarus at linaro.org  Fri Feb 16 06:04:49 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 16 Feb 2024 14:04:49 +0000
Subject: [PATCH v2 7/7] ARM: dts: samsung: s5pv210: specify the SPI FIFO depth
In-Reply-To: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
References: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
Message-ID: <20240216140449.2564625-8-tudor.ambarus@linaro.org>

Up to now the SPI alias was used as an index into an array defined in
the SPI driver to determine the SPI FIFO depth. Drop the dependency on
the SPI alias and specify the SPI FIFO depth directly into the SPI node.

The SPI nodes defined in s5pv210.dtsi are not enabled in any board file.
No SPI aliases are defined, thus choose the FIFO depth using common
sense: index 0 of the array for spi0, and index 1 for spi1.
No functional change expected.

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
 arch/arm/boot/dts/samsung/s5pv210.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/samsung/s5pv210.dtsi b/arch/arm/boot/dts/samsung/s5pv210.dtsi
index ed560c9a3aa1..3eba870db73f 100644
--- a/arch/arm/boot/dts/samsung/s5pv210.dtsi
+++ b/arch/arm/boot/dts/samsung/s5pv210.dtsi
@@ -161,6 +161,7 @@ spi0: spi at e1300000 {
 			pinctrl-0 = <&spi0_bus>;
 			#address-cells = <1>;
 			#size-cells = <0>;
+			fifo-depth = <256>;
 			status = "disabled";
 		};
 
@@ -177,6 +178,7 @@ spi1: spi at e1400000 {
 			pinctrl-0 = <&spi1_bus>;
 			#address-cells = <1>;
 			#size-cells = <0>;
+			fifo-depth = <64>;
 			status = "disabled";
 		};
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From joro at 8bytes.org  Fri Feb 16 06:18:39 2024
From: joro at 8bytes.org (Joerg Roedel)
Date: Fri, 16 Feb 2024 15:18:39 +0100
Subject: [PATCH] iommu/mtk_iommu: Use devm_kcalloc() instead of
 devm_kzalloc()
In-Reply-To: <20240211182250.12656-1-erick.archer@gmx.com>
References: <20240211182250.12656-1-erick.archer@gmx.com>
Message-ID: <Zc9uv4smFRfzf_mY@8bytes.org>

On Sun, Feb 11, 2024 at 07:22:50PM +0100, Erick Archer wrote:
> Link: https://github.com/KSPP/linux/issues/162 [1]
> Link: https://www.kernel.org/doc/html/next/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [2]
> Signed-off-by: Erick Archer <erick.archer at gmx.com>
> ---
>  drivers/iommu/mtk_iommu.c    | 2 +-
>  drivers/iommu/mtk_iommu_v1.c | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)

Applied, thanks.


From krzysztof.kozlowski at linaro.org  Fri Feb 16 06:40:25 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 15:40:25 +0100
Subject: [PATCH 2/4] iommu: constify of_phandle_args in xlate
In-Reply-To: <20240216144027.185959-1-krzysztof.kozlowski@linaro.org>
References: <20240216144027.185959-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240216144027.185959-2-krzysztof.kozlowski@linaro.org>

The xlate callbacks are supposed to translate of_phandle_args to proper
provider without modifying the of_phandle_args.  Make the argument
pointer to const for code safety and readability.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 drivers/iommu/apple-dart.c                  | 3 ++-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 3 ++-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 3 ++-
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     | 3 ++-
 drivers/iommu/exynos-iommu.c                | 2 +-
 drivers/iommu/iommu.c                       | 2 +-
 drivers/iommu/ipmmu-vmsa.c                  | 4 ++--
 drivers/iommu/msm_iommu.c                   | 4 ++--
 drivers/iommu/mtk_iommu.c                   | 3 ++-
 drivers/iommu/mtk_iommu_v1.c                | 3 ++-
 drivers/iommu/rockchip-iommu.c              | 2 +-
 drivers/iommu/sprd-iommu.c                  | 3 ++-
 drivers/iommu/sun50i-iommu.c                | 2 +-
 drivers/iommu/tegra-smmu.c                  | 4 ++--
 drivers/iommu/virtio-iommu.c                | 3 ++-
 include/linux/iommu.h                       | 4 ++--
 16 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index ef3ee95706da..eb1e62cd499a 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -779,7 +779,8 @@ static void apple_dart_domain_free(struct iommu_domain *domain)
 	kfree(dart_domain);
 }
 
-static int apple_dart_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int apple_dart_of_xlate(struct device *dev,
+			       const struct of_phandle_args *args)
 {
 	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
 	struct platform_device *iommu_pdev = of_find_device_by_node(args->np);
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 0ffb1cf17e0b..4434d6a2fc2f 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2739,7 +2739,8 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate(struct device *dev,
+			     const struct of_phandle_args *args)
 {
 	return iommu_fwspec_add_ids(dev, args->args, 1);
 }
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 68b6bc5e7c71..8e5e4ab5fad3 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1551,7 +1551,8 @@ static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
 	return ret;
 }
 
-static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int arm_smmu_of_xlate(struct device *dev,
+			     const struct of_phandle_args *args)
 {
 	u32 mask, fwid = 0;
 
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 17a1c163fef6..e079bb7a993e 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -546,7 +546,8 @@ static struct iommu_device *qcom_iommu_probe_device(struct device *dev)
 	return &qcom_iommu->iommu;
 }
 
-static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int qcom_iommu_of_xlate(struct device *dev,
+			       const struct of_phandle_args *args)
 {
 	struct qcom_iommu_dev *qcom_iommu;
 	struct platform_device *iommu_pdev;
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 2c6e9094f1e9..d98c9161948a 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1431,7 +1431,7 @@ static void exynos_iommu_release_device(struct device *dev)
 }
 
 static int exynos_iommu_of_xlate(struct device *dev,
-				 struct of_phandle_args *spec)
+				 const struct of_phandle_args *spec)
 {
 	struct platform_device *sysmmu = of_find_device_by_node(spec->np);
 	struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 170329a085b8..26a31ba4f72d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3038,7 +3038,7 @@ void iommu_fwspec_free(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_free);
 
-int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+int iommu_fwspec_add_ids(struct device *dev, const u32 *ids, int num_ids)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	int i, new_num;
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index ace1fc4bd34b..cd7219319c8b 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -709,7 +709,7 @@ static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain,
 }
 
 static int ipmmu_init_platform_device(struct device *dev,
-				      struct of_phandle_args *args)
+				      const struct of_phandle_args *args)
 {
 	struct platform_device *ipmmu_pdev;
 
@@ -773,7 +773,7 @@ static bool ipmmu_device_is_allowed(struct device *dev)
 }
 
 static int ipmmu_of_xlate(struct device *dev,
-			  struct of_phandle_args *spec)
+			  const struct of_phandle_args *spec)
 {
 	if (!ipmmu_device_is_allowed(dev))
 		return -ENODEV;
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 67124f4228b1..d4c0f2ad184b 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -588,7 +588,7 @@ static void print_ctx_regs(void __iomem *base, int ctx)
 
 static int insert_iommu_master(struct device *dev,
 				struct msm_iommu_dev **iommu,
-				struct of_phandle_args *spec)
+				const struct of_phandle_args *spec)
 {
 	struct msm_iommu_ctx_dev *master = dev_iommu_priv_get(dev);
 	int sid;
@@ -616,7 +616,7 @@ static int insert_iommu_master(struct device *dev,
 }
 
 static int qcom_iommu_of_xlate(struct device *dev,
-			       struct of_phandle_args *spec)
+			       const struct of_phandle_args *spec)
 {
 	struct msm_iommu_dev *iommu = NULL, *iter;
 	unsigned long flags;
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 7abe9e85a570..955de8fb7732 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -957,7 +957,8 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 	return group;
 }
 
-static int mtk_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int mtk_iommu_of_xlate(struct device *dev,
+			      const struct of_phandle_args *args)
 {
 	struct platform_device *m4updev;
 
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 25b41222abae..ae16d8238d84 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -398,7 +398,8 @@ 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_v1_create_mapping(struct device *dev, struct of_phandle_args *args)
+static int mtk_iommu_v1_create_mapping(struct device *dev,
+				       const struct of_phandle_args *args)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	struct mtk_iommu_v1_data *data;
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 2685861c0a12..da79d9f4cf63 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1140,7 +1140,7 @@ static void rk_iommu_release_device(struct device *dev)
 }
 
 static int rk_iommu_of_xlate(struct device *dev,
-			     struct of_phandle_args *args)
+			     const struct of_phandle_args *args)
 {
 	struct platform_device *iommu_dev;
 	struct rk_iommudata *data;
diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
index 537359f10997..ba53571a8239 100644
--- a/drivers/iommu/sprd-iommu.c
+++ b/drivers/iommu/sprd-iommu.c
@@ -390,7 +390,8 @@ static struct iommu_device *sprd_iommu_probe_device(struct device *dev)
 	return &sdev->iommu;
 }
 
-static int sprd_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int sprd_iommu_of_xlate(struct device *dev,
+			       const struct of_phandle_args *args)
 {
 	struct platform_device *pdev;
 
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index 41484a5a399b..decd52cba998 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -819,7 +819,7 @@ static struct iommu_device *sun50i_iommu_probe_device(struct device *dev)
 }
 
 static int sun50i_iommu_of_xlate(struct device *dev,
-				 struct of_phandle_args *args)
+				 const struct of_phandle_args *args)
 {
 	struct platform_device *iommu_pdev = of_find_device_by_node(args->np);
 	unsigned id = args->args[0];
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 310871728ab4..14e525bd0d9b 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -830,7 +830,7 @@ static struct tegra_smmu *tegra_smmu_find(struct device_node *np)
 }
 
 static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev,
-				struct of_phandle_args *args)
+				const struct of_phandle_args *args)
 {
 	const struct iommu_ops *ops = smmu->iommu.ops;
 	int err;
@@ -959,7 +959,7 @@ static struct iommu_group *tegra_smmu_device_group(struct device *dev)
 }
 
 static int tegra_smmu_of_xlate(struct device *dev,
-			       struct of_phandle_args *args)
+			       const struct of_phandle_args *args)
 {
 	struct platform_device *iommu_pdev = of_find_device_by_node(args->np);
 	struct tegra_mc *mc = platform_get_drvdata(iommu_pdev);
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 34db37fd9675..04048f64a2c0 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1051,7 +1051,8 @@ static struct iommu_group *viommu_device_group(struct device *dev)
 		return generic_device_group(dev);
 }
 
-static int viommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+static int viommu_of_xlate(struct device *dev,
+			   const struct of_phandle_args *args)
 {
 	return iommu_fwspec_add_ids(dev, args->args, 1);
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 1ea2a820e1eb..600fc6e6f308 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -468,7 +468,7 @@ struct iommu_ops {
 	/* Request/Free a list of reserved regions for a device */
 	void (*get_resv_regions)(struct device *dev, struct list_head *list);
 
-	int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
+	int (*of_xlate)(struct device *dev, const struct of_phandle_args *args);
 	bool (*is_attach_deferred)(struct device *dev);
 
 	/* Per device IOMMU features */
@@ -902,7 +902,7 @@ struct iommu_mm_data {
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
 void iommu_fwspec_free(struct device *dev);
-int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
+int iommu_fwspec_add_ids(struct device *dev, const u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Fri Feb 16 06:40:24 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 15:40:24 +0100
Subject: [PATCH 1/4] iommu: constify pointer to bus_type
Message-ID: <20240216144027.185959-1-krzysztof.kozlowski@linaro.org>

Make pointer to bus_type a pointer to const for code safety.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 drivers/iommu/iommu-priv.h | 5 +++--
 drivers/iommu/iommu.c      | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/iommu-priv.h b/drivers/iommu/iommu-priv.h
index 2024a2313348..5f731d994803 100644
--- a/drivers/iommu/iommu-priv.h
+++ b/drivers/iommu/iommu-priv.h
@@ -21,10 +21,11 @@ int iommu_group_replace_domain(struct iommu_group *group,
 			       struct iommu_domain *new_domain);
 
 int iommu_device_register_bus(struct iommu_device *iommu,
-			      const struct iommu_ops *ops, struct bus_type *bus,
+			      const struct iommu_ops *ops,
+			      const struct bus_type *bus,
 			      struct notifier_block *nb);
 void iommu_device_unregister_bus(struct iommu_device *iommu,
-				 struct bus_type *bus,
+				 const struct bus_type *bus,
 				 struct notifier_block *nb);
 
 #endif /* __LINUX_IOMMU_PRIV_H */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d14413916f93..170329a085b8 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -291,7 +291,7 @@ EXPORT_SYMBOL_GPL(iommu_device_unregister);
 
 #if IS_ENABLED(CONFIG_IOMMUFD_TEST)
 void iommu_device_unregister_bus(struct iommu_device *iommu,
-				 struct bus_type *bus,
+				 const struct bus_type *bus,
 				 struct notifier_block *nb)
 {
 	bus_unregister_notifier(bus, nb);
@@ -305,7 +305,8 @@ EXPORT_SYMBOL_GPL(iommu_device_unregister_bus);
  * some memory to hold a notifier_block.
  */
 int iommu_device_register_bus(struct iommu_device *iommu,
-			      const struct iommu_ops *ops, struct bus_type *bus,
+			      const struct iommu_ops *ops,
+			      const struct bus_type *bus,
 			      struct notifier_block *nb)
 {
 	int err;
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Fri Feb 16 06:40:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 15:40:26 +0100
Subject: [PATCH 3/4] iommu: constify fwnode in iommu_ops_from_fwnode()
In-Reply-To: <20240216144027.185959-1-krzysztof.kozlowski@linaro.org>
References: <20240216144027.185959-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240216144027.185959-3-krzysztof.kozlowski@linaro.org>

Make pointer to fwnode_handle a pointer to const for code safety.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 drivers/iommu/iommu.c | 2 +-
 include/linux/iommu.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 26a31ba4f72d..a1f9bb8fa041 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2987,7 +2987,7 @@ bool iommu_default_passthrough(void)
 }
 EXPORT_SYMBOL_GPL(iommu_default_passthrough);
 
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
+const struct iommu_ops *iommu_ops_from_fwnode(const struct fwnode_handle *fwnode)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_device *iommu;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 600fc6e6f308..269ef0af7f20 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -903,7 +903,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
 		      const struct iommu_ops *ops);
 void iommu_fwspec_free(struct device *dev);
 int iommu_fwspec_add_ids(struct device *dev, const u32 *ids, int num_ids);
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
+const struct iommu_ops *iommu_ops_from_fwnode(const struct fwnode_handle *fwnode);
 
 static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 {
@@ -1253,7 +1253,7 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
 }
 
 static inline
-const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
+const struct iommu_ops *iommu_ops_from_fwnode(const struct fwnode_handle *fwnode)
 {
 	return NULL;
 }
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Fri Feb 16 06:40:27 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 16 Feb 2024 15:40:27 +0100
Subject: [PATCH 4/4] iommu: re-use local fwnode variable in iommu_ops_from_fwnode()
In-Reply-To: <20240216144027.185959-1-krzysztof.kozlowski@linaro.org>
References: <20240216144027.185959-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240216144027.185959-4-krzysztof.kozlowski@linaro.org>

iommu_ops_from_fwnode() stores &iommu_spec->np->fwnode in local
variable, so use it to simplify the code (iommu_spec is not changed
between these dereferences).

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 drivers/iommu/of_iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 719652b60840..3afe0b48a48d 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -29,7 +29,7 @@ static int of_iommu_xlate(struct device *dev,
 	    !of_device_is_available(iommu_spec->np))
 		return -ENODEV;
 
-	ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
+	ret = iommu_fwspec_init(dev, fwnode, ops);
 	if (ret)
 		return ret;
 	/*
-- 
2.34.1



From dan.scally at ideasonboard.com  Fri Feb 16 06:45:31 2024
From: dan.scally at ideasonboard.com (Dan Scally)
Date: Fri, 16 Feb 2024 14:45:31 +0000
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240216132755.GA20376@pendragon.ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <20240214142825.GA7873@pendragon.ideasonboard.com>
 <20240214-velcro-pushy-0cbd18b23361@spud>
 <20240215110205.GD7873@pendragon.ideasonboard.com>
 <e06b0792-187d-454b-aa62-d9c1e797df17@ideasonboard.com>
 <20240216132755.GA20376@pendragon.ideasonboard.com>
Message-ID: <f5e63a8b-fb6c-449f-8ec3-26aed5b11b95@ideasonboard.com>


On 16/02/2024 13:27, Laurent Pinchart wrote:
> On Fri, Feb 16, 2024 at 01:09:15PM +0000, Daniel Scally wrote:
>> On 15/02/2024 11:02, Laurent Pinchart wrote:
>>> On Wed, Feb 14, 2024 at 05:37:17PM +0000, Conor Dooley wrote:
>>>> On Wed, Feb 14, 2024 at 04:28:25PM +0200, Laurent Pinchart wrote:
>>>>> On Wed, Feb 14, 2024 at 02:19:03PM +0000, Daniel Scally wrote:
>>>>>> Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
>>>>>>
>>>>>> Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
>>>>>> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
>>>>>> ---
>>>>>> Changes in v2:
>>>>>>
>>>>>> 	- Added clocks information
>>>>>> 	- Fixed the warnings raised by Rob
>>>>>>
>>>>>>    .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
>>>>>>    1 file changed, 77 insertions(+)
>>>>>>    create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
>>>>>> new file mode 100644
>>>>>> index 000000000000..30038cfec3a4
>>>>>> --- /dev/null
>>>>>> +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
>>>>>> @@ -0,0 +1,77 @@
>>>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>>>> +%YAML 1.2
>>>>>> +---
>>>>>> +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
>>>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>>>> +
>>>>>> +title: ARM Mali-C55 Image Signal Processor
>>>>>> +
>>>>>> +maintainers:
>>>>>> +  - Daniel Scally <dan.scally at ideasonboard.com>
>>>>>> +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
>>>>>> +
>>>>>> +properties:
>>>>>> +  compatible:
>>>>>> +    const: arm,mali-c55
>>>>>> +
>>>>>> +  reg:
>>>>>> +    maxItems: 1
>>>>>> +
>>>>>> +  interrupts:
>>>>>> +    maxItems: 1
>>>>>> +
>>>>>> +  clocks:
>>>>>> +    items:
>>>>>> +      - description: ISP video clock
>>>>> I wonder if we need this clock. Granted, it's an input clock to the ISP,
>>>>> but it's part of the input video bus. I don't expect anyone would ever
>>>>> need to control it manually, it should be provided by the video source
>>>>> automatically.
>>>> I'd say that if there's a clock controller providing this clock, even if
>>>> it is implicit in the video feed it's good to have here. Being able to
>>>> increment the refcount on that clock would be good, even if you don't
>>>> actually control it manually?
>>> I don't expect there would be a clock controller to directly reference
>>> in most cases. It depends a bit on where the clock domain crossing
>>> between the source (often a CSI-2 receiver) and the ISP is. If it's
>>> implemented in glue logic bundled with the ISP, which wouldn't be
>>> described in DT as a separate node, then there's a higher chance we'll
>>> have a clock controller for vclk. If it's implemented in the source,
>>> vclk will just come from the source, which won't be listed as a clock
>>> controller.
>>>
>>> One option would be to make this clock optional, by moving it to the end
>>> of the clocks list, and setting
>>>
>>> 	minItems: 2
>>> 	maxItems: 3
>>>
>>>>>> +      - description: ISP AXI clock
>>>>>> +      - description: ISP AHB-lite clock
>>>>> These two other clocks look good to me.
>>>>>
>>>>>> +
>>>>>> +  clock-names:
>>>>>> +    items:
>>>>>> +      - const: vclk
>>>>>> +      - const: aclk
>>>>>> +      - const: hclk
>>>> Why not "video" "axi" "ahb-lite"? There's 3 useful letters between the
>>>> tree clock names you've provided - they're all clocks, so having "clk"
>>>> in them is just noise :)
>>> As far as I understand, the names proposed by Dan come directly from the
>>> IP core documentation.
>> This is the case, but I do take Conor's point that more descriptive names might be nicer - if I'm
>> honest I just didn't think about it particularly given "Xclk" is such a common name for them
>> already, but having been poked into thinking about it I do agree.
> Isn't the usual practice in DT bindings is to name GPIOs, clocks and reset
> signals based on the hardware documentation ?


Ah - I don't know honestly. If that's so then yeah - these are the names the documentation prescribes.

>


From andy at kernel.org  Fri Feb 16 06:56:22 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Fri, 16 Feb 2024 16:56:22 +0200
Subject: [PATCH v3 08/18] phy: ti: phy-j721e-wiz: split wiz_clock_init()
 function
In-Reply-To: <Zc76d4B4hjTC3xum@matsya>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-8-5c2e4a3fac1f@bootlin.com>
 <Zc4xJtLl3zo_YrBC@smile.fi.intel.com>
 <Zc76d4B4hjTC3xum@matsya>
Message-ID: <Zc93lnpGK8PGKbb-@smile.fi.intel.com>

On Fri, Feb 16, 2024 at 11:32:31AM +0530, Vinod Koul wrote:
> On 15-02-24, 17:43, Andy Shevchenko wrote:
> > On Thu, Feb 15, 2024 at 04:17:53PM +0100, Thomas Richard wrote:

...

> > (Side note, as this can be done later)
> > 
> > >  	if (rate >= 100000000)
> > 
> > > +		if (rate >= 100000000)
> > 
> > > +	if (rate >= 100000000)
> > 
> > I would make local definition and use it, we may get the global one as there
> > are users.
> > 
> > #define HZ_PER_GHZ	1000000000UL
> 
> Better to define as:
> #define HZ_PER_GHZ 1 * GIGA

(with parentheses)

Maybe here, but when it appears in units.h it will be defined as I wrote
to be aligned with the rest of definitions.

-- 
With Best Regards,
Andy Shevchenko




From manivannan.sadhasivam at linaro.org  Fri Feb 16 06:59:50 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Fri, 16 Feb 2024 20:29:50 +0530
Subject: [PATCH v2 1/2] PCI: endpoint: Clean up hardware description for
 BARs
In-Reply-To: <20240216134524.1142149-2-cassel@kernel.org>
References: <20240216134524.1142149-1-cassel@kernel.org>
 <20240216134524.1142149-2-cassel@kernel.org>
Message-ID: <20240216145950.GB39963@thinkpad>

On Fri, Feb 16, 2024 at 02:45:14PM +0100, Niklas Cassel wrote:
> The hardware description for BARs is scattered in many different variables
> in pci_epc_features. Some of these things are mutually exclusive, so it
> can create confusion over which variable that has precedence over another.
> 
> Improve the situation by creating a struct pci_epc_bar_desc, and a new
> enum pci_epc_bar_type, and convert the endpoint controller drivers to use
> this more well defined format.
> 
> Additionally, some endpoint controller drivers mark the BAR succeeding a
> "64-bit only BAR" as reserved, while some do not. By definition, a 64-bit
> BAR uses the succeeding BAR for the upper 32-bits, so an EPF driver cannot
> use a BAR succeeding a 64-bit BAR. Ensure that all endpoint controller
> drivers are uniform, and actually describe a reserved BAR as reserved.
> 
> Signed-off-by: Niklas Cassel <cassel at kernel.org>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>

- Mani

> Reviewed-by: Kishon Vijay Abraham I <kishon at kernel.org>
> ---
>  drivers/pci/controller/dwc/pci-imx6.c         |  3 +-
>  drivers/pci/controller/dwc/pci-keystone.c     | 12 +++----
>  .../pci/controller/dwc/pci-layerscape-ep.c    |  5 ++-
>  drivers/pci/controller/dwc/pcie-keembay.c     |  8 +++--
>  drivers/pci/controller/dwc/pcie-rcar-gen4.c   |  4 ++-
>  drivers/pci/controller/dwc/pcie-tegra194.c    | 10 ++++--
>  drivers/pci/controller/dwc/pcie-uniphier-ep.c | 15 ++++++--
>  drivers/pci/controller/pcie-rcar-ep.c         | 14 +++++---
>  drivers/pci/endpoint/functions/pci-epf-ntb.c  |  4 +--
>  drivers/pci/endpoint/functions/pci-epf-test.c |  8 ++---
>  drivers/pci/endpoint/functions/pci-epf-vntb.c |  2 +-
>  drivers/pci/endpoint/pci-epc-core.c           | 32 +++++++++--------
>  drivers/pci/endpoint/pci-epf-core.c           | 15 ++++----
>  include/linux/pci-epc.h                       | 34 +++++++++++++++----
>  14 files changed, 108 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index dc2c036ab28c..47a9a96484ed 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -1081,7 +1081,8 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
>  	.msix_capable = false,
> -	.reserved_bar = 1 << BAR_1 | 1 << BAR_3,
> +	.bar[BAR_1] = { .type = BAR_RESERVED, },
> +	.bar[BAR_3] = { .type = BAR_RESERVED, },
>  	.align = SZ_64K,
>  };
>  
> diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
> index c0c62533a3f1..b2b93b4fa82d 100644
> --- a/drivers/pci/controller/dwc/pci-keystone.c
> +++ b/drivers/pci/controller/dwc/pci-keystone.c
> @@ -924,12 +924,12 @@ static const struct pci_epc_features ks_pcie_am654_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
>  	.msix_capable = true,
> -	.reserved_bar = 1 << BAR_0 | 1 << BAR_1,
> -	.bar_fixed_64bit = 1 << BAR_0,
> -	.bar_fixed_size[2] = SZ_1M,
> -	.bar_fixed_size[3] = SZ_64K,
> -	.bar_fixed_size[4] = 256,
> -	.bar_fixed_size[5] = SZ_1M,
> +	.bar[BAR_0] = { .type = BAR_RESERVED, .only_64bit = true, },
> +	.bar[BAR_1] = { .type = BAR_RESERVED, },
> +	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
> +	.bar[BAR_3] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
> +	.bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256, },
> +	.bar[BAR_5] = { .type = BAR_FIXED, .fixed_size = SZ_1M, },
>  	.align = SZ_1M,
>  };
>  
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index 2e398494e7c0..1f6ee1460ec2 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -250,7 +250,10 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
>  	pci->dev = dev;
>  	pci->ops = pcie->drvdata->dw_pcie_ops;
>  
> -	ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
> +	ls_epc->bar[BAR_2].only_64bit = true;
> +	ls_epc->bar[BAR_3].type = BAR_RESERVED;
> +	ls_epc->bar[BAR_4].only_64bit = true;
> +	ls_epc->bar[BAR_5].type = BAR_RESERVED;
>  	ls_epc->linkup_notifier = true;
>  
>  	pcie->pci = pci;
> diff --git a/drivers/pci/controller/dwc/pcie-keembay.c b/drivers/pci/controller/dwc/pcie-keembay.c
> index 208d3b0ba196..5e8e54f597dd 100644
> --- a/drivers/pci/controller/dwc/pcie-keembay.c
> +++ b/drivers/pci/controller/dwc/pcie-keembay.c
> @@ -312,8 +312,12 @@ static const struct pci_epc_features keembay_pcie_epc_features = {
>  	.linkup_notifier	= false,
>  	.msi_capable		= true,
>  	.msix_capable		= true,
> -	.reserved_bar		= BIT(BAR_1) | BIT(BAR_3) | BIT(BAR_5),
> -	.bar_fixed_64bit	= BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
> +	.bar[BAR_0]		= { .only_64bit = true, },
> +	.bar[BAR_1]		= { .type = BAR_RESERVED, },
> +	.bar[BAR_2]		= { .only_64bit = true, },
> +	.bar[BAR_3]		= { .type = BAR_RESERVED, },
> +	.bar[BAR_4]		= { .only_64bit = true, },
> +	.bar[BAR_5]		= { .type = BAR_RESERVED, },
>  	.align			= SZ_16K,
>  };
>  
> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> index e9166619b1f9..0be760ed420b 100644
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> @@ -383,7 +383,9 @@ static const struct pci_epc_features rcar_gen4_pcie_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
>  	.msix_capable = false,
> -	.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
> +	.bar[BAR_1] = { .type = BAR_RESERVED, },
> +	.bar[BAR_3] = { .type = BAR_RESERVED, },
> +	.bar[BAR_5] = { .type = BAR_RESERVED, },
>  	.align = SZ_1M,
>  };
>  
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 7afa9e9aabe2..1f7b662cb8e1 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -2007,9 +2007,13 @@ static const struct pci_epc_features tegra_pcie_epc_features = {
>  	.core_init_notifier = true,
>  	.msi_capable = false,
>  	.msix_capable = false,
> -	.reserved_bar = 1 << BAR_2 | 1 << BAR_3 | 1 << BAR_4 | 1 << BAR_5,
> -	.bar_fixed_64bit = 1 << BAR_0,
> -	.bar_fixed_size[0] = SZ_1M,
> +	.bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = SZ_1M,
> +			.only_64bit = true, },
> +	.bar[BAR_1] = { .type = BAR_RESERVED, },
> +	.bar[BAR_2] = { .type = BAR_RESERVED, },
> +	.bar[BAR_3] = { .type = BAR_RESERVED, },
> +	.bar[BAR_4] = { .type = BAR_RESERVED, },
> +	.bar[BAR_5] = { .type = BAR_RESERVED, },
>  };
>  
>  static const struct pci_epc_features*
> diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
> index 3fced0d3e851..265f65fc673f 100644
> --- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
> @@ -411,8 +411,12 @@ static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = {
>  		.msi_capable = true,
>  		.msix_capable = false,
>  		.align = 1 << 16,
> -		.bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
> -		.reserved_bar =  BIT(BAR_4),
> +		.bar[BAR_0] = { .only_64bit = true, },
> +		.bar[BAR_1] = { .type = BAR_RESERVED, },
> +		.bar[BAR_2] = { .only_64bit = true, },
> +		.bar[BAR_3] = { .type = BAR_RESERVED, },
> +		.bar[BAR_4] = { .type = BAR_RESERVED, .only_64bit = true, },
> +		.bar[BAR_5] = { .type = BAR_RESERVED, },
>  	},
>  };
>  
> @@ -425,7 +429,12 @@ static const struct uniphier_pcie_ep_soc_data uniphier_nx1_data = {
>  		.msi_capable = true,
>  		.msix_capable = false,
>  		.align = 1 << 12,
> -		.bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4),
> +		.bar[BAR_0] = { .only_64bit = true, },
> +		.bar[BAR_1] = { .type = BAR_RESERVED, },
> +		.bar[BAR_2] = { .only_64bit = true, },
> +		.bar[BAR_3] = { .type = BAR_RESERVED, },
> +		.bar[BAR_4] = { .only_64bit = true, },
> +		.bar[BAR_5] = { .type = BAR_RESERVED, },
>  	},
>  };
>  
> diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c
> index e6909271def7..05967c6c0b42 100644
> --- a/drivers/pci/controller/pcie-rcar-ep.c
> +++ b/drivers/pci/controller/pcie-rcar-ep.c
> @@ -440,11 +440,15 @@ static const struct pci_epc_features rcar_pcie_epc_features = {
>  	.msi_capable = true,
>  	.msix_capable = false,
>  	/* use 64-bit BARs so mark BAR[1,3,5] as reserved */
> -	.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
> -	.bar_fixed_64bit = 1 << BAR_0 | 1 << BAR_2 | 1 << BAR_4,
> -	.bar_fixed_size[0] = 128,
> -	.bar_fixed_size[2] = 256,
> -	.bar_fixed_size[4] = 256,
> +	.bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = 128,
> +			.only_64bit = true, },
> +	.bar[BAR_1] = { .type = BAR_RESERVED, },
> +	.bar[BAR_2] = { .type = BAR_FIXED, .fixed_size = 256,
> +			.only_64bit = true, },
> +	.bar[BAR_3] = { .type = BAR_RESERVED, },
> +	.bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256,
> +			.only_64bit = true, },
> +	.bar[BAR_5] = { .type = BAR_RESERVED, },
>  };
>  
>  static const struct pci_epc_features*
> diff --git a/drivers/pci/endpoint/functions/pci-epf-ntb.c b/drivers/pci/endpoint/functions/pci-epf-ntb.c
> index 43cd309ce22f..e01a98e74d21 100644
> --- a/drivers/pci/endpoint/functions/pci-epf-ntb.c
> +++ b/drivers/pci/endpoint/functions/pci-epf-ntb.c
> @@ -1012,13 +1012,13 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb,
>  
>  	epc_features = ntb_epc->epc_features;
>  	barno = ntb_epc->epf_ntb_bar[BAR_CONFIG];
> -	size = epc_features->bar_fixed_size[barno];
> +	size = epc_features->bar[barno].fixed_size;
>  	align = epc_features->align;
>  
>  	peer_ntb_epc = ntb->epc[!type];
>  	peer_epc_features = peer_ntb_epc->epc_features;
>  	peer_barno = ntb_epc->epf_ntb_bar[BAR_PEER_SPAD];
> -	peer_size = peer_epc_features->bar_fixed_size[peer_barno];
> +	peer_size = peer_epc_features->bar[peer_barno].fixed_size;
>  
>  	/* Check if epc_features is populated incorrectly */
>  	if ((!IS_ALIGNED(size, align)))
> diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
> index 981894e40681..cd4ffb39dcdc 100644
> --- a/drivers/pci/endpoint/functions/pci-epf-test.c
> +++ b/drivers/pci/endpoint/functions/pci-epf-test.c
> @@ -729,7 +729,7 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
>  		 */
>  		add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
>  
> -		if (!!(epc_features->reserved_bar & (1 << bar)))
> +		if (epc_features->bar[bar].type == BAR_RESERVED)
>  			continue;
>  
>  		ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no,
> @@ -856,7 +856,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
>  		if (bar == test_reg_bar)
>  			continue;
>  
> -		if (!!(epc_features->reserved_bar & (1 << bar)))
> +		if (epc_features->bar[bar].type == BAR_RESERVED)
>  			continue;
>  
>  		base = pci_epf_alloc_space(epf, bar_size[bar], bar,
> @@ -874,13 +874,11 @@ static void pci_epf_configure_bar(struct pci_epf *epf,
>  				  const struct pci_epc_features *epc_features)
>  {
>  	struct pci_epf_bar *epf_bar;
> -	bool bar_fixed_64bit;
>  	int i;
>  
>  	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
>  		epf_bar = &epf->bar[i];
> -		bar_fixed_64bit = !!(epc_features->bar_fixed_64bit & (1 << i));
> -		if (bar_fixed_64bit)
> +		if (epc_features->bar[i].only_64bit)
>  			epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
>  	}
>  }
> diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> index 0675929fc529..8e779eecd62d 100644
> --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
> +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> @@ -422,7 +422,7 @@ static int epf_ntb_config_spad_bar_alloc(struct epf_ntb *ntb)
>  								epf->func_no,
>  								epf->vfunc_no);
>  	barno = ntb->epf_ntb_bar[BAR_CONFIG];
> -	size = epc_features->bar_fixed_size[barno];
> +	size = epc_features->bar[barno].fixed_size;
>  	align = epc_features->align;
>  
>  	if ((!IS_ALIGNED(size, align)))
> diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
> index dcd4e66430c1..7fe8f4336765 100644
> --- a/drivers/pci/endpoint/pci-epc-core.c
> +++ b/drivers/pci/endpoint/pci-epc-core.c
> @@ -87,7 +87,7 @@ EXPORT_SYMBOL_GPL(pci_epc_get);
>   * @epc_features: pci_epc_features structure that holds the reserved bar bitmap
>   *
>   * Invoke to get the first unreserved BAR that can be used by the endpoint
> - * function. For any incorrect value in reserved_bar return '0'.
> + * function.
>   */
>  enum pci_barno
>  pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features)
> @@ -102,32 +102,34 @@ EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
>   * @bar: the starting BAR number from where unreserved BAR should be searched
>   *
>   * Invoke to get the next unreserved BAR starting from @bar that can be used
> - * for endpoint function. For any incorrect value in reserved_bar return '0'.
> + * for endpoint function.
>   */
>  enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
>  					 *epc_features, enum pci_barno bar)
>  {
> -	unsigned long free_bar;
> +	int i;
>  
>  	if (!epc_features)
>  		return BAR_0;
>  
>  	/* If 'bar - 1' is a 64-bit BAR, move to the next BAR */
> -	if ((epc_features->bar_fixed_64bit << 1) & 1 << bar)
> +	if (bar > 0 && epc_features->bar[bar - 1].only_64bit)
>  		bar++;
>  
> -	/* Find if the reserved BAR is also a 64-bit BAR */
> -	free_bar = epc_features->reserved_bar & epc_features->bar_fixed_64bit;
> -
> -	/* Set the adjacent bit if the reserved BAR is also a 64-bit BAR */
> -	free_bar <<= 1;
> -	free_bar |= epc_features->reserved_bar;
> -
> -	free_bar = find_next_zero_bit(&free_bar, 6, bar);
> -	if (free_bar > 5)
> -		return NO_BAR;
> +	for (i = bar; i < PCI_STD_NUM_BARS; i++) {
> +		/* If the BAR is not reserved, return it. */
> +		if (epc_features->bar[i].type != BAR_RESERVED)
> +			return i;
> +
> +		/*
> +		 * If the BAR is reserved, and marked as 64-bit only, then the
> +		 * succeeding BAR is also reserved.
> +		 */
> +		if (epc_features->bar[i].only_64bit)
> +			i++;
> +	}
>  
> -	return free_bar;
> +	return NO_BAR;
>  }
>  EXPORT_SYMBOL_GPL(pci_epc_get_next_free_bar);
>  
> diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
> index f2b4d34454c4..0a28a0b0911b 100644
> --- a/drivers/pci/endpoint/pci-epf-core.c
> +++ b/drivers/pci/endpoint/pci-epf-core.c
> @@ -260,7 +260,7 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
>  			  const struct pci_epc_features *epc_features,
>  			  enum pci_epc_interface_type type)
>  {
> -	u64 bar_fixed_size = epc_features->bar_fixed_size[bar];
> +	u64 bar_fixed_size = epc_features->bar[bar].fixed_size;
>  	size_t align = epc_features->align;
>  	struct pci_epf_bar *epf_bar;
>  	dma_addr_t phys_addr;
> @@ -271,13 +271,14 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
>  	if (size < 128)
>  		size = 128;
>  
> -	if (bar_fixed_size && size > bar_fixed_size) {
> -		dev_err(&epf->dev, "requested BAR size is larger than fixed size\n");
> -		return NULL;
> -	}
> -
> -	if (bar_fixed_size)
> +	if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) {
> +		if (size > bar_fixed_size) {
> +			dev_err(&epf->dev,
> +				"requested BAR size is larger than fixed size\n");
> +			return NULL;
> +		}
>  		size = bar_fixed_size;
> +	}
>  
>  	if (align)
>  		size = ALIGN(size, align);
> diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
> index 40ea18f5aa02..4ccb4f4f3883 100644
> --- a/include/linux/pci-epc.h
> +++ b/include/linux/pci-epc.h
> @@ -145,6 +145,32 @@ struct pci_epc {
>  	unsigned long			function_num_map;
>  };
>  
> +/**
> + * @BAR_PROGRAMMABLE: The BAR mask can be configured by the EPC.
> + * @BAR_FIXED: The BAR mask is fixed by the hardware.
> + * @BAR_RESERVED: The BAR should not be touched by an EPF driver.
> + */
> +enum pci_epc_bar_type {
> +	BAR_PROGRAMMABLE = 0,
> +	BAR_FIXED,
> +	BAR_RESERVED,
> +};
> +
> +/**
> + * struct pci_epc_bar_desc - hardware description for a BAR
> + * @type: the type of the BAR
> + * @fixed_size: the fixed size, only applicable if type is BAR_FIXED_MASK.
> + * @only_64bit: if true, an EPF driver is not allowed to choose if this BAR
> + *		should be configured as 32-bit or 64-bit, the EPF driver must
> + *		configure this BAR as 64-bit. Additionally, the BAR succeeding
> + *		this BAR must be set to type BAR_RESERVED.
> + */
> +struct pci_epc_bar_desc {
> +	enum pci_epc_bar_type type;
> +	u64 fixed_size;
> +	bool only_64bit;
> +};
> +
>  /**
>   * struct pci_epc_features - features supported by a EPC device per function
>   * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up
> @@ -152,9 +178,7 @@ struct pci_epc {
>   *			for initialization
>   * @msi_capable: indicate if the endpoint function has MSI capability
>   * @msix_capable: indicate if the endpoint function has MSI-X capability
> - * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver
> - * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs
> - * @bar_fixed_size: Array specifying the size supported by each BAR
> + * @bar: array specifying the hardware description for each BAR
>   * @align: alignment size required for BAR buffer allocation
>   */
>  struct pci_epc_features {
> @@ -162,9 +186,7 @@ struct pci_epc_features {
>  	unsigned int	core_init_notifier : 1;
>  	unsigned int	msi_capable : 1;
>  	unsigned int	msix_capable : 1;
> -	u8	reserved_bar;
> -	u8	bar_fixed_64bit;
> -	u64	bar_fixed_size[PCI_STD_NUM_BARS];
> +	struct	pci_epc_bar_desc bar[PCI_STD_NUM_BARS];
>  	size_t	align;
>  };
>  
> -- 
> 2.43.1
> 

-- 
????????? ????????


From manivannan.sadhasivam at linaro.org  Fri Feb 16 07:02:08 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Fri, 16 Feb 2024 20:32:08 +0530
Subject: [PATCH v2 0/2] PCI endpoint BAR hardware description cleanup
In-Reply-To: <20240216134524.1142149-1-cassel@kernel.org>
References: <20240216134524.1142149-1-cassel@kernel.org>
Message-ID: <20240216150208.GC39963@thinkpad>

On Fri, Feb 16, 2024 at 02:45:13PM +0100, Niklas Cassel wrote:
> The series is based on top of:
> https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=endpoint
> 
> 
> Hello all,
> 
> This series cleans up the hardware description for PCI endpoint BARs.
> 
> The problems with the existing hardware description:
> -The documentation is lackluster.
> -Some of the names are confusingly similar, e.g. fixed_64bit and
>  fixed_size, even though these are for completely unrelated things.
> -The way that the BARs are defined in the endpoint controller drivers
>  is messy, because the left hand side is not a BAR, so you can mark a
>  BAR as e.g. both fixed size and reserved.
> 
> This series tries to address all the problems above.
> 
> Personally, I think that the code is more readable, both the endpoint
> controller drivers, but also pci-epc-core.c.
> 
> (I will be sending out a patch series that adds BAR_RESIZABLE to enum
> pci_epc_bar_type in the coming week.)
> 

Applied to pci/endpoint!

- Mani

> 
> Kind regards,
> Niklas
> 
> 
> Changes since V1:
> -Picked up tags from Kishon and Mani.
> -Improved commit message for patch 1/2 as suggested by Mani.
> -Improved kdoc in patch 2/2 as suggested by Mani.
> 
> 
> Niklas Cassel (2):
>   PCI: endpoint: Clean up hardware description for BARs
>   PCI: endpoint: Drop only_64bit on reserved BARs
> 
>  drivers/pci/controller/dwc/pci-imx6.c         |  3 +-
>  drivers/pci/controller/dwc/pci-keystone.c     | 12 +++---
>  .../pci/controller/dwc/pci-layerscape-ep.c    |  5 ++-
>  drivers/pci/controller/dwc/pcie-keembay.c     |  8 +++-
>  drivers/pci/controller/dwc/pcie-rcar-gen4.c   |  4 +-
>  drivers/pci/controller/dwc/pcie-tegra194.c    | 10 +++--
>  drivers/pci/controller/dwc/pcie-uniphier-ep.c | 15 +++++--
>  drivers/pci/controller/pcie-rcar-ep.c         | 14 ++++---
>  drivers/pci/endpoint/functions/pci-epf-ntb.c  |  4 +-
>  drivers/pci/endpoint/functions/pci-epf-test.c |  8 ++--
>  drivers/pci/endpoint/functions/pci-epf-vntb.c |  2 +-
>  drivers/pci/endpoint/pci-epc-core.c           | 25 +++++-------
>  drivers/pci/endpoint/pci-epf-core.c           | 15 +++----
>  include/linux/pci-epc.h                       | 39 ++++++++++++++++---
>  14 files changed, 106 insertions(+), 58 deletions(-)
> 
> -- 
> 2.43.1
> 

-- 
????????? ????????


From andy at kernel.org  Fri Feb 16 07:03:37 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Fri, 16 Feb 2024 17:03:37 +0200
Subject: [PATCH v3 08/18] phy: ti: phy-j721e-wiz: split wiz_clock_init()
 function
In-Reply-To: <14429802-b4d8-4a3e-88ea-a9fc55d2251c@ti.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-8-5c2e4a3fac1f@bootlin.com>
 <Zc4xJtLl3zo_YrBC@smile.fi.intel.com>
 <Zc76d4B4hjTC3xum@matsya>
 <14429802-b4d8-4a3e-88ea-a9fc55d2251c@ti.com>
Message-ID: <Zc95SWxtfSQs0a0-@smile.fi.intel.com>

On Fri, Feb 16, 2024 at 02:34:39PM +0530, Siddharth Vadapalli wrote:
> On 24/02/16 11:32AM, Vinod Koul wrote:
> > On 15-02-24, 17:43, Andy Shevchenko wrote:
> > > On Thu, Feb 15, 2024 at 04:17:53PM +0100, Thomas Richard wrote:

...

> > > (Side note, as this can be done later)
> > > 
> > > >  	if (rate >= 100000000)
> > > 
> > > > +		if (rate >= 100000000)
> > > 
> > > > +	if (rate >= 100000000)
> > > 
> > > I would make local definition and use it, we may get the global one as there
> > > are users.
> > > 
> > > #define HZ_PER_GHZ	1000000000UL
> > 
> > Better to define as:
> > #define HZ_PER_GHZ 1 * GIGA
> 
> The variable "rate" is being compared against 100 MHz and not 1 GHz.

Extremely good point why constant definitions are better (to avoid missing
or extra 0, etc)!

> The driver already has the following macros defined:
> #define REF_CLK_19_2MHZ         19200000
> #define REF_CLK_25MHZ           25000000
> #define REF_CLK_100MHZ          100000000
> #define REF_CLK_156_25MHZ       156250000
> 
> So would it be acceptable to change it to:
> 	if (rate >= REF_CLK_100MHZ)
> instead?

Sounds like a good idea to me.

-- 
With Best Regards,
Andy Shevchenko




From andy at kernel.org  Fri Feb 16 07:07:21 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Fri, 16 Feb 2024 17:07:21 +0200
Subject: [PATCH v3 05/18] mux: add mux_chip_resume() function
In-Reply-To: <f1d2c9b0-238d-4b09-8212-62e00a2192b2@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-5-5c2e4a3fac1f@bootlin.com>
 <Zc4t82V9czlEqamL@smile.fi.intel.com>
 <f1d2c9b0-238d-4b09-8212-62e00a2192b2@bootlin.com>
Message-ID: <Zc96Ke_iG_bHIvkP@smile.fi.intel.com>

On Fri, Feb 16, 2024 at 08:52:17AM +0100, Thomas Richard wrote:
> On 2/15/24 16:29, Andy Shevchenko wrote:
> > On Thu, Feb 15, 2024 at 04:17:50PM +0100, Thomas Richard wrote:

...

> >> +int mux_chip_resume(struct mux_chip *mux_chip)
> >> +{
> >> +	int global_ret = 0;
> >> +	int ret, i;
> >> +
> >> +	for (i = 0; i < mux_chip->controllers; ++i) {
> >> +		struct mux_control *mux = &mux_chip->mux[i];
> >> +
> >> +		if (mux->cached_state == MUX_CACHE_UNKNOWN)
> >> +			continue;
> >> +
> >> +		ret = mux_control_set(mux, mux->cached_state);
> >> +		if (ret < 0) {
> >> +			dev_err(&mux_chip->dev, "unable to restore state\n");
> >> +			if (!global_ret)
> >> +				global_ret = ret;
> > 
> > Hmm... This will record the first error and continue.
> 
> In the v2 we talked about this with Peter Rosin.
> 
> In fact, in the v1 (mux_chip_resume() didn't exists yet, everything was
> done in the mmio driver) I had the same behavior: try to restore all
> muxes and in case of error restore the first one.
> 
> I don't know what is the right solution. I just restored the behavior I
> had in v1.

Okay, I believe you know what you are doing, folks. But to me this approach
sounds at bare minimum "unusual". Because the failures here are not fatal
and recording the first one may or may not make sense and it's so fragile
as it completely implementation-dependent.

> >> +		}
> >> +	}
> >> +	return global_ret;
> > 
> > So here, we actually will get stale data in case there are > 1 failures.
> 
> Yes, indeed. But we will have an error message for each failure.

Which is also problematic. PM calls may easily spam the logs and outshadow
really important messages (like oopses).

-- 
With Best Regards,
Andy Shevchenko




From andy at kernel.org  Fri Feb 16 07:08:37 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Fri, 16 Feb 2024 17:08:37 +0200
Subject: [PATCH v3 02/18] pinctrl: pinctrl-single: remove dead code in
 suspend() and resume() callbacks
In-Reply-To: <78add459-a96a-46c6-83ff-e2657d4d3db4@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-2-5c2e4a3fac1f@bootlin.com>
 <Zc4tedAhqYX3bQcw@smile.fi.intel.com>
 <78add459-a96a-46c6-83ff-e2657d4d3db4@bootlin.com>
Message-ID: <Zc96dSff5Y-dufrJ@smile.fi.intel.com>

On Fri, Feb 16, 2024 at 08:59:47AM +0100, Thomas Richard wrote:
> On 2/15/24 16:27, Andy Shevchenko wrote:
> > On Thu, Feb 15, 2024 at 04:17:47PM +0100, Thomas Richard wrote:
> >> No need to check the pointer returned by platform_get_drvdata(), as
> >> platform_set_drvdata() is called during the probe.
> > 
> > This patch should go _after_ the next one, otherwise the commit message doesn't
> > tell full story and the code change bring a potential regression.
> 
> Hello Andy,
> 
> I'm ok to move this patch after the next one.
> But for my understanding, could you explain me why changing the order is
> important in this case ?

Old PM calls obviously can be called in different circumstances and these
checks are important.

Just squash these two patches to avoid additional churn and we are done.

-- 
With Best Regards,
Andy Shevchenko




From afd at ti.com  Fri Feb 16 07:08:31 2024
From: afd at ti.com (Andrew Davis)
Date: Fri, 16 Feb 2024 09:08:31 -0600
Subject: [PATCH v5] arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in
 serdes_ln_ctrl
In-Reply-To: <4abe2bde-1171-4b77-b7bc-49491792a721@ti.com>
References: <20240213080348.248916-1-s-vadapalli@ti.com>
 <1be60db1-f292-1074-5898-801380e1fb22@axentia.se>
 <af73545a-1746-4e14-a3f2-772d72e6ff97@ti.com>
 <4abe2bde-1171-4b77-b7bc-49491792a721@ti.com>
Message-ID: <d3ca964c-7fdd-4ed6-8f9c-348d21e5666c@ti.com>

On 2/15/24 10:56 PM, Siddharth Vadapalli wrote:
> On 24/02/13 11:08AM, Andrew Davis wrote:
>> On 2/13/24 3:19 AM, Peter Rosin wrote:
>>> Hi!
>>>
>>> 2024-02-13 at 09:03, Siddharth Vadapalli wrote:
>>>> From: Chintan Vankar <c-vankar at ti.com>
>>>>
>>>> Change offset in mux-reg-masks property for serdes_ln_ctrl node
>>>> since reg-mux property is used in compatible.
>>>>
>>>> Fixes: 2765149273f4 ("mux: mmio: use reg property when parent device is not a syscon")
>>>> Signed-off-by: Chintan Vankar <c-vankar at ti.com>
>>>> Acked-by: Andrew Davis <afd at ti.com>
>>>> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
>>>> ---
> ...
> 
>>>> +			mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */
>>>> +					<0x8 0x3>, <0xc 0x3>, /* SERDES0 lane2/3 select */
>>>> +					<0x10 0x3>, <0x14 0x3>, /* SERDES1 lane0/1 select */
>>>> +					<0x18 0x3>, <0x1c 0x3>, /* SERDES1 lane2/3 select */
>>>> +					<0x20 0x3>, <0x24 0x3>, /* SERDES2 lane0/1 select */
>>>> +					<0x28 0x3>, <0x2c 0x3>; /* SERDES2 lane2/3 select */
>>>>    			idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>,
>>>>    				      <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
>>>>    				      <J784S4_SERDES0_LANE2_IP3_UNUSED>,
>>>
>>> Ouch. I suspect there is a similar problem in
>>> arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi:
>>>
>>>
>>> 	fss: bus at 47000000 {
>>> 		compatible = "simple-bus";
>>> 		reg = <0x0 0x47000000 0x0 0x100>;
>>> 		#address-cells = <2>;
>>> 		#size-cells = <2>;
>>> 		ranges;
>>>
>>> 		hbmc_mux: mux-controller at 47000004 {
>>> 			compatible = "reg-mux";
>>> 			reg = <0x00 0x47000004 0x00 0x2>;
>>> 			#mux-control-cells = <1>;
>>> -			mux-reg-masks = <0x4 0x2>; /* HBMC select */
>>> +			mux-reg-masks = <0x0 0x2>; /* HBMC select */
>>> 		};
>>>
>>> Who knows what non-upstreamed devices and devicetrees are affected?
>>> I guess we need to revert 2765149273f4 ("mux: mmio: use reg property
>>> when parent device is not a syscon") unless someone sees a sane way
>>> to fix this.
>>
>> There are only two in-tree nodes with "reg-mux" with a reg property: the
>> one this patch fixes, and the hbmc_mux you point out, both in TI devices.
>> I'd say it is safe to assume we are the only users, and our non-upstreamed
>> DTs depend on that patch, reverting it would cause more issues for
>> out-of-tree users than just fixing the two broken nodes above.
> 
> Peter,
> 
> Is it alright for this patch to be merged, given Andrew's response above?
> The problem with "hbmc_mux" node that you pointed out above could be fixed
> by another patch. Please let me know.

The hbmc_mux fix is now also posted:

https://lore.kernel.org/linux-arm-kernel/20240215141957.13775-1-afd at ti.com/

Andrew

> 
> Regards,
> Siddharth.


From kieran.bingham at ideasonboard.com  Fri Feb 16 07:13:57 2024
From: kieran.bingham at ideasonboard.com (Kieran Bingham)
Date: Fri, 16 Feb 2024 15:13:57 +0000
Subject: [PATCH 1/2] media: dt-bindings: media: Add bindings for IMX283
In-Reply-To: <Zc8ppr4mE8ZgVNUs@kekkonen.localdomain>
References: <20240215204436.9194-1-umang.jain@ideasonboard.com> <20240215204436.9194-2-umang.jain@ideasonboard.com> <55d41858-b567-4e23-8d84-3af81b52d018@linaro.org> <Zc8ppr4mE8ZgVNUs@kekkonen.localdomain>
Message-ID: <170809643706.2629073.1807694963113475412@ping.linuxembedded.co.uk>

Quoting Sakari Ailus (2024-02-16 09:23:50)
> Hi Krzysztof, Umang,
> 
> On Fri, Feb 16, 2024 at 09:03:49AM +0100, Krzysztof Kozlowski wrote:
> > > +        properties:
> > > +          data-lanes: true
> > 
> > Provide constraints - which lanes/how many.
> 
> Very probably only the number matters on this device. Therefore minimum and
> maximum should suffice. (Or an enum. 3 is probably an invalid number of
> lanes here, too.)

I think we can only support 4 lanes here. I heard rumour that it 'might'
be possible to support 2 lanes, but I haven't seen any documentation for
that and I don't think it's likely expected to be supported.

--
Kieran

> 
> -- 
> Kind regards,
> 
> Sakari Ailus
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From quic_kathirav at quicinc.com  Fri Feb 16 07:22:44 2024
From: quic_kathirav at quicinc.com (Kathiravan Thirumoorthy)
Date: Fri, 16 Feb 2024 20:52:44 +0530
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com>
 <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
 <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
Message-ID: <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com>



On 2/14/2024 8:14 PM, Andrew Lunn wrote:
> On Wed, Feb 14, 2024 at 02:49:41PM +0530, Kathiravan Thirumoorthy wrote:
>>
>>
>> On 1/26/2024 1:35 AM, Andrew Lunn wrote:
>>> On Mon, Jan 22, 2024 at 11:26:58AM +0530, Kathiravan Thirumoorthy wrote:
>>>> gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk are
>>>> enabled by default and it's RCG is properly configured by bootloader.
>>>
>>> Which bootloader? Mainline barebox?
>>
>>
>> Thanks for taking time to review the patches. I couldn't get time to respond
>> back, sorry for the delay.
>>
>> I was referring to the U-boot which is delivered as part of the QSDK. I will
>> call it out explicitly in the next patch.
> 
> I've never used QSDK u-boot, so i can only make comments based on my
> experience with other vendors build of u-boot. That experience is, its
> broken for my use cases, and i try to replace it as soon as possible
> with upstream.
> 
> I generally want to TFTP boot the kernel and the DT blob. Sometimes
> vendor u-boot has networking disabled. Or the TFTP client is
> missing. If it is there, the IP addresses are fixed, and i don't want
> to modify my network to make it compatible with the vendor
> requirements. If the IP addresses can be configured, sometimes there
> is no FLASH support so its not possible to actually write the
> configuration to FLASH so that it does the right thing on reboot
> etc...
> 
> Often the vendor u-boot is a black box, no sources. Can you give me a
> git URL for the u-boot in QSDK? If the sources are open, i could at
> least rebuild it with everything turned on.


You can get the source at 
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016/-/tree/NHSS.QSDK.12.2?ref_type=heads

You should be able to TFTP the images, write into the flash and 
configure the IP and so on...


> 
> But still, it is better that Linux makes no assumptions about what the
> boot loader has done. That makes it much easier to change the
> bootloader.
> 
>>>> Some of the NSS clocks needs these clocks to be enabled. To avoid
>>>> these clocks being disabled by clock framework, drop these entries
>>>> from the clock table and enable it in the driver probe itself.
>>>
>>> If they are critical clocks, i would expect a device to reference
>>> them. The CCF only disabled unused clocks in late_initcall_sync(),
>>> which means all drivers should of probed and taken a reference on any
>>> clocks they require.
>>
>>
>> Some of the NSSCC clocks are enabled by bootloaders and CCF disables the
>> same (because currently there are no consumers for these clocks available in
>> the tree. These clocks are consumed by the Networking drivers which are
>> being upstreamed).
> 
> If there is no network drivers, you don't need clocks to the
> networking hardware. So CCF turning them off seems correct.


Yeah agree with your comments.

QSDK's u-boot enables the network support, so the required NSSCC clocks 
are turned ON and left it in ON state. CCF tries to disables the unused 
NSSCC clocks but system goes for reboot.


Reason being, to access the NSSCC clocks, these GCC clocks 
(gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk)
should be turned ON. But CCF disables these clocks as well due to the 
lack of consumer.


> 
> Once you have actual drivers, this should solve itself, the drivers
> will consume the clocks.


Given that, NSSCC is being built as module, there is no issue in booting 
the kernel. But if you do insmod of the nsscc-ipq5332.ko, system will 
reset.

Without the networking drivers, there is no need to install this module. 
And as you stated, once the drivers are available, there will be no issues.

So can I explain the shortcomings of installing this module without the 
networking drivers in cover letter and drop this patch all together?



> 
>> However looking back, gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk,
>> gcc_nssnoc_nsscc_clk are consumed by the networking drivers only. So is it
>> okay to drop these clocks from the GCC driver and add it back once the
>> actual consumer needs it?
> 
> But why should you remove them. If nothing is using them, they should
> be turned off.
> 
>     Andrew


From jesper.nilsson at axis.com  Fri Feb 16 07:24:21 2024
From: jesper.nilsson at axis.com (Jesper Nilsson)
Date: Fri, 16 Feb 2024 16:24:21 +0100
Subject: [PATCH] net: stmmac: mmc_core: Assign, don't add interrupt
 registers
Message-ID: <20240216-stmmac_stats-v1-1-7065fa4613f8@axis.com>

The MMC IPC interrupt status and interrupt mask registers are of
little use as Ethernet statistics, but incrementing counters
based on the current interrupt and interrupt mask registers
makes them worse than useless.

For example, if the interrupt mask is set to 0x08420842,
the current code will increment by that amount each iteration,
leading to the following sequence of nonsense:

mmc_rx_ipc_intr_mask: 969816526
mmc_rx_ipc_intr_mask: 1108361744

Change the increment to a straight assignment to make the
statistics at least nominally useful.

Signed-off-by: Jesper Nilsson <jesper.nilsson at axis.com>
---
 drivers/net/ethernet/stmicro/stmmac/mmc_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
index 6a7c1d325c46..6051a22b3cec 100644
--- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
@@ -280,8 +280,8 @@ static void dwmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc)
 	mmc->mmc_rx_vlan_frames_gb += readl(mmcaddr + MMC_RX_VLAN_FRAMES_GB);
 	mmc->mmc_rx_watchdog_error += readl(mmcaddr + MMC_RX_WATCHDOG_ERROR);
 	/* IPC */
-	mmc->mmc_rx_ipc_intr_mask += readl(mmcaddr + MMC_RX_IPC_INTR_MASK);
-	mmc->mmc_rx_ipc_intr += readl(mmcaddr + MMC_RX_IPC_INTR);
+	mmc->mmc_rx_ipc_intr_mask = readl(mmcaddr + MMC_RX_IPC_INTR_MASK);
+	mmc->mmc_rx_ipc_intr = readl(mmcaddr + MMC_RX_IPC_INTR);
 	/* IPv4 */
 	mmc->mmc_rx_ipv4_gd += readl(mmcaddr + MMC_RX_IPV4_GD);
 	mmc->mmc_rx_ipv4_hderr += readl(mmcaddr + MMC_RX_IPV4_HDERR);

---
base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
change-id: 20240216-stmmac_stats-e3561d460d0e

Best regards,
-- 

/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson at axis.com



From ptyadav at amazon.de  Fri Feb 16 07:29:43 2024
From: ptyadav at amazon.de (Pratyush Yadav)
Date: Fri, 16 Feb 2024 16:29:43 +0100
Subject: [PATCH v3 00/17] kexec: Allow preservation of ftrace buffers
In-Reply-To: <20240117144704.602-1-graf@amazon.com> (Alexander Graf's message
	of "Wed, 17 Jan 2024 14:46:47 +0000")
References: <20240117144704.602-1-graf@amazon.com>
Message-ID: <mafs0zfw08m1k.fsf@amazon.de>

Hi Alex,

On Wed, Jan 17 2024, Alexander Graf wrote:

> Kexec today considers itself purely a boot loader: When we enter the new
> kernel, any state the previous kernel left behind is irrelevant and the
> new kernel reinitializes the system.
>
> However, there are use cases where this mode of operation is not what we
> actually want. In virtualization hosts for example, we want to use kexec
> to update the host kernel while virtual machine memory stays untouched.
> When we add device assignment to the mix, we also need to ensure that
> IOMMU and VFIO states are untouched. If we add PCIe peer to peer DMA, we
> need to do the same for the PCI subsystem. If we want to kexec while an
> SEV-SNP enabled virtual machine is running, we need to preserve the VM
> context pages and physical memory. See James' and my Linux Plumbers
> Conference 2023 presentation for details:

I am working on handing userspace pages across kexec. This can be useful
for applications with large in-memory state that can be time consuming
to rebuild. If they can hand over their state over kexec, it allows for
kernel upgrades with lower downtime. As a part of this problem, I have
been looking at plugging all of this into CRIU [0] so I don't have to
modify the applications to use this feature. I can just use CRIU to do
the checkpoint and restore quickly over kexec.

I hacked together some patches for this (which are not yet polished
enough to publish) and ended up implementing something like KHO in a
much more crude way. I have since refactored my patches to use KHO and I
find it quite useful. So thanks for working on this :-)

It was easy enough to get KHO working with my patches though I had to
look into your ftrace patches to get the whole picture. The
documentation can be improved to show how it can be used from the
driver/subsystem perspective. For example, I had to read your ftrace
patches to figure out I should use kho_get_fdt(), or that I should
register a notifier via kho_register_notifier(). I would be happy to
contribute some documentation improvements.

Have you done any analysis on the performance or memory overhead? If
yes, it would be nice to look at some data. I have some concerns with
performance and memory overhead, especially for more fragmented memory
but I don't yet have numbers to present you.

[0] https://github.com/checkpoint-restore/criu

>
>   https://lpc.events/event/17/contributions/1485/
>
> To start us on the journey to support all the use cases above, this
> patch implements basic infrastructure to allow hand over of kernel state
> across kexec (Kexec HandOver, aka KHO). As example target, we use ftrace:
> With this patch set applied, you can read ftrace records from the
> pre-kexec environment in your post-kexec one. This creates a very powerful
> debugging and performance analysis tool for kexec. It's also slightly
> easier to reason about than full blown VFIO state preservation.
>
> == Alternatives ==
>
> There are alternative approaches to (parts of) the problems above:
>
>   * Memory Pools [1] - preallocated persistent memory region + allocator
>   * PRMEM [2] - resizable persistent memory regions with fixed metadata
>                 pointer on the kernel command line + allocator
>   * Pkernfs [3] - preallocated file system for in-kernel data with fixed
>                   address location on the kernel command line
>   * PKRAM [4] - handover of user space pages using a fixed metadata page
>                 specified via command line

FYI, you forgot to paste the links in v3 but I can find them from v2.

>From all these options, PKRAM seems somewhat useful for my use case but
with CRIU it would need to copy all the application pages to the PKRAM
FS and would need at least as much free memory as application memory.

Instead, I have built a simple system that gives an API to userspace to
hand over its pages and to request them back. It then keeps track of the
PID and PA -> VA mappings (essentially a page table). This lets me keep
the pages in-place and avoid needing lots of free memory or expensive
copying. KHO plays a crucial role there in handing those pages and page
tables across to the next kernel.

The FDT format works fairly well for my use case. Since page tables are
a stable data structure, I don't need to worry about their format
changing between kernel versions and can directly pass them through.
This might not be true for many other data structures so subsystems
using those either need to serialize them to FDT or invent their own
serialization formats.

I also wonder how the "mem" array will work for more fragmented
allocations. It might grow very large with lots of scattered elements. I
wonder how both KHO's parsing and memblock will behave in this case. I
have not yet tried stressing it so I can't say for myself.

>
> All of the approaches above fundamentally have the same problem: They
> require the administrator to explicitly carve out a physical memory
> location because they have no mechanism outside of the kernel command
> line to pass data (including memory reservations) between kexec'ing
> kernels.
>
> KHO provides that base foundation. We will determine later whether we
> still need any of the approaches above for fast bulk memory handover of for
> example IOMMU page tables. But IMHO they would all be users of KHO, with
> KHO providing the foundational primitive to pass metadata and bulk memory
> reservations as well as provide easy versioning for data.
>
> == Overview ==
>
> We introduce a metadata file that the kernels pass between each other. How
> they pass it is architecture specific. The file's format is a Flattened
> Device Tree (fdt) which has a generator and parser already included in
> Linux. When the root user enables KHO through /sys/kernel/kho/active, the
> kernel invokes callbacks to every driver that supports KHO to serialize
> its state. When the actual kexec happens, the fdt is part of the image
> set that we boot into. In addition, we keep a "scratch region" available
> for kexec: A physically contiguous memory region that is guaranteed to
> not have any memory that KHO would preserve.  The new kernel bootstraps
> itself using the scratch region and sets all handed over memory as in use.
> When drivers initialize that support KHO, they introspect the fdt and
> recover their state from it. This includes memory reservations, where the
> driver can either discard or claim reservations.
>
> == Limitations ==
>
> I currently only implemented file based kexec. The kernel interfaces
> in the patch set are already in place to support user space kexec as well,
> but I have not implemented it yet inside kexec tools.
>
> == How to Use ==
>
> To use the code, please boot the kernel with the "kho_scratch=" command
> line parameter set: "kho_scratch=512M". KHO requires a scratch region.
>
> Make sure to fill ftrace with contents that you want to observe after
> kexec.  Then, before you invoke file based "kexec -l", activate KHO:
>
>   # echo 1 > /sys/kernel/kho/active
>   # kexec -l Image --initrd=initrd -s
>   # kexec -e
>
> The new kernel will boot up and contain the previous kernel's trace
> buffers in /sys/kernel/debug/tracing/trace.
>
[...]

Overall, I think KHO is quite useful and I would be happy to see it
evolve and eventually make it into the kernel. It would certainly make
my life a lot easier.

Since I have used it in my patches, I have done some basic testing for
it. Nothing fancy, just handed a few pages across. It works as
advertised. For that,

Tested-by: Pratyush Yadav <ptyadav at amazon.de>

-- 
Regards,
Pratyush Yadav



Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879





From tglx at linutronix.de  Fri Feb 16 07:33:23 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 16 Feb 2024 16:33:23 +0100
Subject: [PATCH v12 14/25] irqchip/sifive-plic: Convert PLIC driver into
 a platform driver
In-Reply-To: <20240127161753.114685-15-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-15-apatel@ventanamicro.com>
Message-ID: <87jzn4ctks.ffs@tglx>

On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> +	priv->irqdomain = irq_domain_create_linear(dev->fwnode, nr_irqs + 1,
> +						   &plic_irqdomain_ops, priv);
> +	if (WARN_ON(!priv->irqdomain))
> +		return -ENOMEM;

While some of the stuff is cleaned up by devm, the error handling in
this code looks pretty fragile as it leaves initialized contexts,
hardware state, chained handlers etc. around.

The question is whether the system can actually boot or work at all if
any of this fails.

> +
>  	/*
>  	 * We can have multiple PLIC instances so setup cpuhp state
> -	 * and register syscore operations only when context handler
> -	 * for current/boot CPU is present.
> +	 * and register syscore operations only after context handlers
> +	 * of all online CPUs are initialized.
>  	 */
> -	handler = this_cpu_ptr(&plic_handlers);
> -	if (handler->present && !plic_cpuhp_setup_done) {
> +	cpuhp_setup = true;
> +	for_each_online_cpu(cpu) {
> +		handler = per_cpu_ptr(&plic_handlers, cpu);
> +		if (!handler->present) {
> +			cpuhp_setup = false;
> +			break;
> +		}
> +	}
> +	if (cpuhp_setup) {
>  		cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
>  				  "irqchip/sifive/plic:starting",
>  				  plic_starting_cpu, plic_dying_cpu);
>  		register_syscore_ops(&plic_irq_syscore_ops);
> -		plic_cpuhp_setup_done = true;

I don't think that removing the setup protection is correct.

Assume you have maxcpus=N on the kernel command line, then the above
for_each_online_cpu() loop would result in cpuhp_setup == true when the
instances for the not onlined CPUs are set up, no?

Thanks,

        tglx


From ptyadav at amazon.de  Fri Feb 16 07:36:05 2024
From: ptyadav at amazon.de (Pratyush Yadav)
Date: Fri, 16 Feb 2024 16:36:05 +0100
Subject: [PATCH v3 11/17] tracing: Introduce kho serialization
In-Reply-To: <20240117144704.602-12-graf@amazon.com> (Alexander Graf's message
	of "Wed, 17 Jan 2024 14:46:58 +0000")
References: <20240117144704.602-1-graf@amazon.com>
	<20240117144704.602-12-graf@amazon.com>
Message-ID: <mafs0sf1s8lqy.fsf@amazon.de>

Hi,

On Wed, Jan 17 2024, Alexander Graf wrote:

> We want to be able to transfer ftrace state from one kernel to the next.
> To start off with, let's establish all the boiler plate to get a write
> hook when KHO wants to serialize and fill out basic data.
>
> Follow-up patches will fill in serialization of ring buffers and events.
>
> Signed-off-by: Alexander Graf <graf at amazon.com>
>
> ---
>
> v1 -> v2:
>
>   - Remove ifdefs
> ---
>  kernel/trace/trace.c | 47 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index a0defe156b57..9a0d96975c9c 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -32,6 +32,7 @@
>  #include <linux/percpu.h>
>  #include <linux/splice.h>
>  #include <linux/kdebug.h>
> +#include <linux/kexec.h>
>  #include <linux/string.h>
>  #include <linux/mount.h>
>  #include <linux/rwsem.h>
> @@ -866,6 +867,8 @@ static struct tracer		*trace_types __read_mostly;
>   */
>  DEFINE_MUTEX(trace_types_lock);
>
> +static bool trace_in_kho;
> +
>  /*
>   * serialize the access of the ring buffer
>   *
> @@ -10574,12 +10577,56 @@ void __init early_trace_init(void)
>  	init_events();
>  }
>
> +static int trace_kho_notifier(struct notifier_block *self,
> +			      unsigned long cmd,
> +			      void *v)
> +{
> +	const char compatible[] = "ftrace-v1";
> +	void *fdt = v;
> +	int err = 0;
> +
> +	switch (cmd) {
> +	case KEXEC_KHO_ABORT:
> +		if (trace_in_kho)
> +			mutex_unlock(&trace_types_lock);
> +		trace_in_kho = false;
> +		return NOTIFY_DONE;
> +	case KEXEC_KHO_DUMP:
> +		/* Handled below */
> +		break;
> +	default:
> +		return NOTIFY_BAD;
> +	}
> +
> +	if (unlikely(tracing_disabled))
> +		return NOTIFY_DONE;
> +
> +	err |= fdt_begin_node(fdt, "ftrace");
> +	err |= fdt_property(fdt, "compatible", compatible, sizeof(compatible));
> +	err |= fdt_end_node(fdt);
> +
> +	if (!err) {
> +		/* Hold all future allocations */
> +		mutex_lock(&trace_types_lock);

Say I do "echo 1 | tee /sys/kernel/kho/active". Then the lock is held by
tee, which exits. Then I later I do "echo 0 | tee
/sys/kernel/kho/active". This time another tee task unlocks the lock. So
it is not being unlocked by the same task that locked it. The comment
above mutex_lock() definition says:

    The mutex must later on be released by the same task that acquired
    it. Recursive locking is not allowed. The task may not exit without
    first unlocking the mutex.

I tested your code and it happens to work because the unlock always
happened to take the fast path which does not sanity-check the owner.
Still, this is not the correct thing to do.

> +		trace_in_kho = true;
> +	}
> +
> +	return err ? NOTIFY_BAD : NOTIFY_DONE;
> +}
> +
> +static struct notifier_block trace_kho_nb = {
> +	.notifier_call = trace_kho_notifier,
> +};
> +
>  void __init trace_init(void)
>  {
>  	trace_event_init();
>
>  	if (boot_instance_index)
>  		enable_instances();
> +
> +	if (IS_ENABLED(CONFIG_FTRACE_KHO))
> +		register_kho_notifier(&trace_kho_nb);
>  }
>
>  __init static void clear_boot_tracer(void)

--
Regards,
Pratyush Yadav



Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879





From ptyadav at amazon.de  Fri Feb 16 07:37:49 2024
From: ptyadav at amazon.de (Pratyush Yadav)
Date: Fri, 16 Feb 2024 16:37:49 +0100
Subject: [PATCH v3 05/17] kexec: Add KHO support to kexec file loads
In-Reply-To: <20240117144704.602-6-graf@amazon.com> (Alexander Graf's message
	of "Wed, 17 Jan 2024 14:46:52 +0000")
References: <20240117144704.602-1-graf@amazon.com>
	<20240117144704.602-6-graf@amazon.com>
Message-ID: <mafs0le7k8lo2.fsf@amazon.de>

Hi,

On Wed, Jan 17 2024, Alexander Graf wrote:

> Kexec has 2 modes: A user space driven mode and a kernel driven mode.
> For the kernel driven mode, kernel code determines the physical
> addresses of all target buffers that the payload gets copied into.
>
> With KHO, we can only safely copy payloads into the "scratch area".
> Teach the kexec file loader about it, so it only allocates for that
> area. In addition, enlighten it with support to ask the KHO subsystem
> for its respective payloads to copy into target memory. Also teach the
> KHO subsystem how to fill the images for file loads.

This patch causes compilation failures when CONFIG_KEXEC_FILE is not
enabled. I am not listing them all here since there are a bunch. You can
try disabling it and see them for yourself.

Since Documentation/kho/usage.rst says:

    It is important that you use the ``-s`` parameter to use the
    in-kernel kexec file loader, as user space kexec tooling currently
    has no support for KHO with the user space based file loader.

you can just make CONFIG_KEXEC_FILE a dependency for CONFIG_KEXEC_KHO to
get rid of these errors.

Or, if you foresee wanting to use the user space tooling to use KHO as
well then you should refactor your code to work with the option enabled
and disabled.

>
> Signed-off-by: Alexander Graf <graf at amazon.com>
[...]

--
Regards,
Pratyush Yadav



Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879





From linux at armlinux.org.uk  Fri Feb 16 07:43:30 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 16 Feb 2024 15:43:30 +0000
Subject: [PATCH netnext 8/8] net: dsa: mt7530: simplify link operations
 and force link down on all ports
In-Reply-To: <20240208-for-netnext-mt7530-improvements-3-v1-8-d7c1cfd502ca@arinc9.com>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
 <20240208-for-netnext-mt7530-improvements-3-v1-8-d7c1cfd502ca@arinc9.com>
Message-ID: <Zc+ConfebmQdpCOF@shell.armlinux.org.uk>

On Thu, Feb 08, 2024 at 08:51:36AM +0300, Ar?n? ?NAL via B4 Relay wrote:
> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
> 
> Currently, the link operations for switch MACs are scattered across
> port_enable, port_disable, phylink_mac_config, phylink_mac_link_up, and
> phylink_mac_link_down.
> 
> port_enable and port_disable clears the link settings. Move that to
> mt7530_setup() and mt7531_setup_common() which set up the switches. This
> way, the link settings are cleared on all ports at setup, and then only
> once with phylink_mac_link_down() when a link goes down.
> 
> Enable force mode at setup to apply the force part of the link settings.
> This ensures that only active ports will have their link up.

I think we may have a different interpretation of what phylink's
mac_link_down() and mac_link_up() are supposed to be doing here.
Of course, you have read the documentation of these methods so are
fully aware of what they're supposed to do. So you are aware that
when inband mode is being used, forcing the link down may be
counter-productive depending on how the hardware works.

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


From ptyadav at amazon.de  Fri Feb 16 07:57:09 2024
From: ptyadav at amazon.de (Pratyush Yadav)
Date: Fri, 16 Feb 2024 16:57:09 +0100
Subject: [PATCH v3 04/17] kexec: Add KHO parsing support
In-Reply-To: <20240117144704.602-5-graf@amazon.com> (Alexander Graf's message
	of "Wed, 17 Jan 2024 14:46:51 +0000")
References: <20240117144704.602-1-graf@amazon.com>
	<20240117144704.602-5-graf@amazon.com>
Message-ID: <mafs0eddc8kru.fsf@amazon.de>

Hi,

On Wed, Jan 17 2024, Alexander Graf wrote:

> When we have a KHO kexec, we get a device tree, mem cache and scratch
> region to populate the state of the system. Provide helper functions
> that allow architecture code to easily handle memory reservations based
> on them and give device drivers visibility into the KHO DT and memory
> reservations so they can recover their own state.
>
> Signed-off-by: Alexander Graf <graf at amazon.com>
>
> ---
>
[...]
> +/**
> + * kho_return_mem - Notify the kernel that initially reserved memory is no
> + * longer needed. When the last consumer of a page returns their mem, kho
> + * returns the page to the buddy allocator as free page.
> + */
> +void kho_return_mem(const struct kho_mem *mem)
> +{
> +	uint64_t start_pfn, end_pfn, pfn;
> +
> +	start_pfn = PFN_DOWN(mem->addr);
> +	end_pfn = PFN_UP(mem->addr + mem->len);
> +
> +	for (pfn = start_pfn; pfn < end_pfn; pfn++)
> +		kho_return_pfn(pfn);
> +}
> +EXPORT_SYMBOL_GPL(kho_return_mem);
> +
> +static void kho_claim_pfn(ulong pfn)
> +{
> +	struct page *page = pfn_to_page(pfn);
> +
> +	WARN_ON(!page);
> +	if (WARN_ON(page_count(page) != 1))
> +		pr_err("Claimed non kho pfn %lx", pfn);

You do sanity checks but then never actually change anything on the
page. kho_claim_mem()'s documentation says: "This function removes the
reserved state for all pages that the mem spans". So this function
should at the very least call ClearPageReserved().

Also, checking the page count is a very rough heuristic. There can be
other non-KHO pages with page count == 1. Do you think it would make
more sense to use one of the private pageflags bits to mark a page
KHO-owned? If not, shouldn't you at least also check if the page is
reserved?

> +}
> +
> +/**
> + * kho_claim_mem - Notify the kernel that a handed over memory range is now in
> + * use by a kernel subsystem and considered an allocated page. This function
> + * removes the reserved state for all pages that the mem spans.
> + */
> +void *kho_claim_mem(const struct kho_mem *mem)
> +{
> +	u64 start_pfn, end_pfn, pfn;
> +	void *va = __va(mem->addr);
> +
> +	start_pfn = PFN_DOWN(mem->addr);
> +	end_pfn = PFN_UP(mem->addr + mem->len);
> +
> +	for (pfn = start_pfn; pfn < end_pfn; pfn++)
> +		kho_claim_pfn(pfn);
> +
> +	return va;
> +}
> +EXPORT_SYMBOL_GPL(kho_claim_mem);
> +
[...]

--
Regards,
Pratyush Yadav



Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879





From dmitry.baryshkov at linaro.org  Fri Feb 16 08:26:31 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 16 Feb 2024 18:26:31 +0200
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com> <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com> <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
 <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com>
Message-ID: <CAA8EJppe6aNf2WJ5BvaX8SPTbuaEwzRm74F8QKyFtbmnGQt=1w@mail.gmail.com>

On Fri, 16 Feb 2024 at 17:33, Kathiravan Thirumoorthy
<quic_kathirav at quicinc.com> wrote:
>
>
>
> On 2/14/2024 8:14 PM, Andrew Lunn wrote:
> > On Wed, Feb 14, 2024 at 02:49:41PM +0530, Kathiravan Thirumoorthy wrote:
> >>
> >>
> >> On 1/26/2024 1:35 AM, Andrew Lunn wrote:
> >>> On Mon, Jan 22, 2024 at 11:26:58AM +0530, Kathiravan Thirumoorthy wrote:
> >>>> gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk are
> >>>> enabled by default and it's RCG is properly configured by bootloader.
> >>>
> >>> Which bootloader? Mainline barebox?
> >>
> >>
> >> Thanks for taking time to review the patches. I couldn't get time to respond
> >> back, sorry for the delay.
> >>
> >> I was referring to the U-boot which is delivered as part of the QSDK. I will
> >> call it out explicitly in the next patch.
> >
> > I've never used QSDK u-boot, so i can only make comments based on my
> > experience with other vendors build of u-boot. That experience is, its
> > broken for my use cases, and i try to replace it as soon as possible
> > with upstream.
> >
> > I generally want to TFTP boot the kernel and the DT blob. Sometimes
> > vendor u-boot has networking disabled. Or the TFTP client is
> > missing. If it is there, the IP addresses are fixed, and i don't want
> > to modify my network to make it compatible with the vendor
> > requirements. If the IP addresses can be configured, sometimes there
> > is no FLASH support so its not possible to actually write the
> > configuration to FLASH so that it does the right thing on reboot
> > etc...
> >
> > Often the vendor u-boot is a black box, no sources. Can you give me a
> > git URL for the u-boot in QSDK? If the sources are open, i could at
> > least rebuild it with everything turned on.
>
>
> You can get the source at
> https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016/-/tree/NHSS.QSDK.12.2?ref_type=heads
>
> You should be able to TFTP the images, write into the flash and
> configure the IP and so on...
>
>
> >
> > But still, it is better that Linux makes no assumptions about what the
> > boot loader has done. That makes it much easier to change the
> > bootloader.
> >
> >>>> Some of the NSS clocks needs these clocks to be enabled. To avoid
> >>>> these clocks being disabled by clock framework, drop these entries
> >>>> from the clock table and enable it in the driver probe itself.
> >>>
> >>> If they are critical clocks, i would expect a device to reference
> >>> them. The CCF only disabled unused clocks in late_initcall_sync(),
> >>> which means all drivers should of probed and taken a reference on any
> >>> clocks they require.
> >>
> >>
> >> Some of the NSSCC clocks are enabled by bootloaders and CCF disables the
> >> same (because currently there are no consumers for these clocks available in
> >> the tree. These clocks are consumed by the Networking drivers which are
> >> being upstreamed).
> >
> > If there is no network drivers, you don't need clocks to the
> > networking hardware. So CCF turning them off seems correct.
>
>
> Yeah agree with your comments.
>
> QSDK's u-boot enables the network support, so the required NSSCC clocks
> are turned ON and left it in ON state. CCF tries to disables the unused
> NSSCC clocks but system goes for reboot.
>
>
> Reason being, to access the NSSCC clocks, these GCC clocks
> (gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk)
> should be turned ON. But CCF disables these clocks as well due to the
> lack of consumer.

This means that NSSCC is also a consumer of those clocks. Please fix
both DT and nsscc driver to handle NSSNOC clocks.

> > Once you have actual drivers, this should solve itself, the drivers
> > will consume the clocks.
>
>
> Given that, NSSCC is being built as module, there is no issue in booting
> the kernel. But if you do insmod of the nsscc-ipq5332.ko, system will
> reset.
>
> Without the networking drivers, there is no need to install this module.
> And as you stated, once the drivers are available, there will be no issues.
>
> So can I explain the shortcomings of installing this module without the
> networking drivers in cover letter and drop this patch all together?

No. Using allyesconfig or allmodconfig and installing the full modules
set should work.

> >> However looking back, gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk,
> >> gcc_nssnoc_nsscc_clk are consumed by the networking drivers only. So is it
> >> okay to drop these clocks from the GCC driver and add it back once the
> >> actual consumer needs it?
> >
> > But why should you remove them. If nothing is using them, they should
> > be turned off.
> >
> >     Andrew
>


-- 
With best wishes
Dmitry


From will at kernel.org  Fri Feb 16 08:28:47 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 16 Feb 2024 16:28:47 +0000
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <a0c62629-999f-4aa1-86c7-3104811f84d0@arm.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240215134952.GA690@willie-the-truck>
 <20240215160135.GL1088888@nvidia.com>
 <02fac0ab-07ac-448e-ae4e-26788ed4fce9@arm.com>
 <a0c62629-999f-4aa1-86c7-3104811f84d0@arm.com>
Message-ID: <20240216162847.GA2292@willie-the-truck>

On Thu, Feb 15, 2024 at 08:11:38PM +0000, Robin Murphy wrote:
> On 2024-02-15 6:42 pm, Robin Murphy wrote:
> [...]
> > > > > +static void arm_smmu_get_ste_used(const __le64 *ent, __le64
> > > > > *used_bits)
> > > > > ? {
> > > > > +??? unsigned int cfg = FIELD_GET(STRTAB_STE_0_CFG,
> > > > > le64_to_cpu(ent[0]));
> > > > > +
> > > > > +??? used_bits[0] = cpu_to_le64(STRTAB_STE_0_V);
> > > > > +??? if (!(ent[0] & cpu_to_le64(STRTAB_STE_0_V)))
> > > > > +??????? return;
> > > > > +
> > > > > +??? /*
> > > > > +???? * See 13.5 Summary of attribute/permission
> > > > > configuration fields for the
> > > > > +???? * SHCFG behavior. It is only used for BYPASS,
> > > > > including S1DSS BYPASS,
> > > > > +???? * and S2 only.
> > > > > +???? */
> > > > > +??? if (cfg == STRTAB_STE_0_CFG_BYPASS ||
> > > > > +??????? cfg == STRTAB_STE_0_CFG_S2_TRANS ||
> > > > > +??????? (cfg == STRTAB_STE_0_CFG_S1_TRANS &&
> > > > > +???????? FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
> > > > > +???????????? STRTAB_STE_1_S1DSS_BYPASS))
> > > > > +??????? used_bits[1] |= cpu_to_le64(STRTAB_STE_1_SHCFG);
> > > > 
> > > > Huh, SHCFG is really getting in the way here, isn't it?
> > > 
> > > I wouldn't say that.. It is just a complicated bit of the spec. One of
> > > the things we recently did was to audit all the cache settings and, at
> > > least, we then realized that SHCFG was being subtly used by S2 as
> > > well..
> > 
> > Yeah, that really shouldn't be subtle; incoming attributes are replaced
> > by S1 translation, thus they are relevant to not-S1 configs.
> 
> That said, in this specific case I don't understand why we're worrying about
> SHCFG here at all - we're never going to make use of any value other than
> "use incoming" because we can't rely on it being implemented in the first
> place, and even if it is, we really don't want to start getting into the
> forced-coherency notion that the DMA layer can'#t understand and devicetree
> can't describe.

Yup, that's exactly what I'm thinking. We currently set it to NSH when
translation is enabled, so that the stage-2 shareability is effectively
an override. However, the device is either coherent, or it isn't, and so
we should just leave this always set to "use incoming" in my opinion,
which means we no longer need to care about qword 1 for the bypass case.

Will


From arnd at kernel.org  Fri Feb 16 08:32:53 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Fri, 16 Feb 2024 17:32:53 +0100
Subject: [PATCH] firmware: arm_scmi: avoid returning uninialized data
Message-ID: <20240216163259.1927967-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Clang notices that there is a code path through
scmi_powercap_notify_supported() that returns an
undefined value:

drivers/firmware/arm_scmi/powercap.c:821:11: error: variable 'supported' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
  821 |         else if (evt_id == SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED)
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/firmware/arm_scmi/powercap.c:824:9: note: uninitialized use occurs here
  824 |         return supported;
      |                ^~~~~~~~~
drivers/firmware/arm_scmi/powercap.c:821:7: note: remove the 'if' if its condition is always true
  821 |         else if (evt_id == SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED)
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  822 |                 supported = dom_info->notify_powercap_measurement_change;
drivers/firmware/arm_scmi/powercap.c:811:16: note: initialize the variable 'supported' to silence this warning
  811 |         bool supported;
      |                       ^

Return 'false' here, which is probably what was intended.

Fixes: c92a75fe84ce ("firmware: arm_scmi: Implement Powercap .is_notify_supported callback")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/firmware/arm_scmi/powercap.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/firmware/arm_scmi/powercap.c b/drivers/firmware/arm_scmi/powercap.c
index aae91f47303e..8ee3be8776b0 100644
--- a/drivers/firmware/arm_scmi/powercap.c
+++ b/drivers/firmware/arm_scmi/powercap.c
@@ -820,6 +820,8 @@ scmi_powercap_notify_supported(const struct scmi_protocol_handle *ph,
 		supported = dom_info->notify_powercap_cap_change;
 	else if (evt_id == SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED)
 		supported = dom_info->notify_powercap_measurement_change;
+	else
+		supported = false;
 
 	return supported;
 }
-- 
2.39.2



From mwalle at kernel.org  Fri Feb 16 08:34:05 2024
From: mwalle at kernel.org (Michael Walle)
Date: Fri, 16 Feb 2024 17:34:05 +0100
Subject: [PATCH 1/2] dt-bindings: arm64: mediatek: add Kontron 3.5"-SBC-i1200
Message-ID: <20240216163406.1050929-1-mwalle@kernel.org>

Add the compatible string for the Kontron 3.5"-SBC-i1200 single board
computer.

Signed-off-by: Michael Walle <mwalle at kernel.org>
---
 Documentation/devicetree/bindings/arm/mediatek.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 09f9ffd3ff7b..32896f91ea38 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -357,6 +357,12 @@ properties:
               - radxa,nio-12l
           - const: mediatek,mt8395
           - const: mediatek,mt8195
+      - description: Kontron 3.5"-SBC-i1200
+        items:
+          - enum:
+              - kontron,3-5-sbc-i1200
+          - const: mediatek,mt8395
+          - const: mediatek,mt8195
       - items:
           - enum:
               - mediatek,mt8516-pumpkin
-- 
2.39.2



From mwalle at kernel.org  Fri Feb 16 08:34:06 2024
From: mwalle at kernel.org (Michael Walle)
Date: Fri, 16 Feb 2024 17:34:06 +0100
Subject: [PATCH 2/2] arm64: dts: mediatek: add Kontron 3.5"-SBC-i1200
In-Reply-To: <20240216163406.1050929-1-mwalle@kernel.org>
References: <20240216163406.1050929-1-mwalle@kernel.org>
Message-ID: <20240216163406.1050929-2-mwalle@kernel.org>

Add basic support for the Kontron 3.5" single board computer featuring a
Mediatek i1200 SoC (MT8395/MT8195).

Signed-off-by: Michael Walle <mwalle at kernel.org>
---
 arch/arm64/boot/dts/mediatek/Makefile         |    1 +
 .../mediatek/mt8395-kontron-3-5-sbc-i1200.dts | 1091 +++++++++++++++++
 2 files changed, 1092 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 37b4ca3a87c9..697b6b5de3cb 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -76,5 +76,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-kontron-3-5-sbc-i1200.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts b/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
new file mode 100644
index 000000000000..0c634bc8776c
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
@@ -0,0 +1,1091 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2024 Kontron Europe GmbH
+ *
+ * Author: Michael Walle <mwalle at kernel.org>
+ */
+/dts-v1/;
+
+#include "mt8195.dtsi"
+#include "mt6359.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
+#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+	model = "Kontron 3.5\"-SBC-i1200";
+	compatible = "kontron,3-5-sbc-i1200", "mediatek,mt8395", "mediatek,mt8195";
+
+	aliases {
+		mmc0 = &mmc0;
+		mmc1 = &mmc1;
+		serial0 = &uart1;
+		serial1 = &uart2;
+		serial2 = &uart3;
+		serial3 = &uart4;
+		serial4 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	firmware {
+		optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_keys_pins>;
+
+		key-0 {
+			gpios = <&pio 106 GPIO_ACTIVE_LOW>;
+			label = "volume_up";
+			linux,code = <KEY_VOLUMEUP>;
+			wakeup-source;
+			debounce-interval = <15>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins>;
+
+		led-0 {
+			gpios = <&pio 107 GPIO_ACTIVE_HIGH>;
+			default-state = "keep";
+			function = LED_FUNCTION_POWER;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+	};
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0x0 0x80000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/*
+		 * 12 MiB reserved for OP-TEE (BL32)
+		 * +-----------------------+ 0x43e0_0000
+		 * |      SHMEM 2MiB       |
+		 * +-----------------------+ 0x43c0_0000
+		 * |        | TA_RAM  8MiB |
+		 * + TZDRAM +--------------+ 0x4340_0000
+		 * |        | TEE_RAM 2MiB |
+		 * +-----------------------+ 0x4320_0000
+		 */
+		optee_reserved: optee at 43200000 {
+			no-map;
+			reg = <0 0x43200000 0 0x00c00000>;
+		};
+
+		scp_mem: memory at 50000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x50000000 0 0x2900000>;
+			no-map;
+		};
+
+		vpu_mem: memory at 53000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x53000000 0 0x1400000>; /* 20 MB */
+		};
+
+		/* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+		bl31_secmon_mem: memory at 54600000 {
+			no-map;
+			reg = <0 0x54600000 0x0 0x200000>;
+		};
+
+		snd_dma_mem: memory at 60000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x60000000 0 0x1100000>;
+			no-map;
+		};
+
+		apu_mem: memory at 62000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x62000000 0 0x1400000>; /* 20 MB */
+		};
+	};
+
+	thermal_sensor0: thermal-sensor-0 {
+		compatible = "generic-adc-thermal";
+		#thermal-sensor-cells = <0>;
+		io-channels = <&auxadc 0>;
+		io-channel-names = "sensor-channel";
+		temperature-lookup-table = <(-25000) 1474
+					    (-20000) 1374
+					    (-15000) 1260
+					    (-10000) 1134
+					     (-5000) 1004
+						   0 874
+						5000 750
+					       10000 635
+					       15000 532
+					       20000 443
+					       25000 367
+					       30000 303
+					       35000 250
+					       40000 206
+					       45000 170
+					       50000 141
+					       55000 117
+					       60000 97
+					       65000 81
+					       70000 68
+					       75000 57
+					       80000 48
+					       85000 41
+					       90000 35
+					       95000 30
+					      100000 25
+					      105000 22
+					      110000 19
+					      115000 16
+					      120000 14
+					      125000 12
+					      130000 10
+					      135000 9
+					      140000 8
+					      145000 7
+					      150000 6>;
+	};
+
+	thermal_sensor1: thermal-sensor-1 {
+		compatible = "generic-adc-thermal";
+		#thermal-sensor-cells = <0>;
+		io-channels = <&auxadc 1>;
+		io-channel-names = "sensor-channel";
+		temperature-lookup-table = <(-25000) 1474
+					    (-20000) 1374
+					    (-15000) 1260
+					    (-10000) 1134
+					     (-5000) 1004
+						   0 874
+						5000 750
+					       10000 635
+					       15000 532
+					       20000 443
+					       25000 367
+					       30000 303
+					       35000 250
+					       40000 206
+					       45000 170
+					       50000 141
+					       55000 117
+					       60000 97
+					       65000 81
+					       70000 68
+					       75000 57
+					       80000 48
+					       85000 41
+					       90000 35
+					       95000 30
+					      100000 25
+					      105000 22
+					      110000 19
+					      115000 16
+					      120000 14
+					      125000 12
+					      130000 10
+					      135000 9
+					      140000 8
+					      145000 7
+					      150000 6>;
+	};
+
+	thermal_sensor2: thermal-sensor-2 {
+		compatible = "generic-adc-thermal";
+		#thermal-sensor-cells = <0>;
+		io-channels = <&auxadc 2>;
+		io-channel-names = "sensor-channel";
+		temperature-lookup-table = <(-25000) 1474
+					    (-20000) 1374
+					    (-15000) 1260
+					    (-10000) 1134
+					     (-5000) 1004
+						   0 874
+						5000 750
+					       10000 635
+					       15000 532
+					       20000 443
+					       25000 367
+					       30000 303
+					       35000 250
+					       40000 206
+					       45000 170
+					       50000 141
+					       55000 117
+					       60000 97
+					       65000 81
+					       70000 68
+					       75000 57
+					       80000 48
+					       85000 41
+					       90000 35
+					       95000 30
+					      100000 25
+					      105000 22
+					      110000 19
+					      115000 16
+					      120000 14
+					      125000 12
+					      130000 10
+					      135000 9
+					      140000 8
+					      145000 7
+					      150000 6>;
+	};
+};
+
+&auxadc {
+	status = "okay";
+};
+
+&eth {
+	phy-mode ="rgmii-id";
+	phy-handle = <&ethernet_phy0>;
+	snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>;
+	snps,reset-delays-us = <0 10000 80000>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&eth_default_pins>;
+	pinctrl-1 = <&eth_sleep_pins>;
+	status = "okay";
+
+	mdio {
+		ethernet_phy0: ethernet-phy at 1 {
+			reg = <0x1>;
+			interrupts-extended = <&pio 94 IRQ_TYPE_LEVEL_LOW>;
+		};
+	};
+};
+
+&gpu {
+	status = "okay";
+	mali-supply = <&mt6315_7_vbuck1>;
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_pins>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&i2c4 {
+	clock-frequency = <100000>;
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&i2c6 {
+	clock-frequency = <400000>;
+	pinctrl-0 = <&i2c6_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	mt6360: pmic at 34 {
+		compatible = "mediatek,mt6360";
+		reg = <0x34>;
+		interrupt-controller;
+		interrupts-extended = <&pio 101 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-names = "IRQB";
+
+		charger {
+			compatible = "mediatek,mt6360-chg";
+			richtek,vinovp-microvolt = <14500000>;
+
+			otg_vbus_regulator: usb-otg-vbus-regulator {
+				regulator-compatible = "usb-otg-vbus";
+				regulator-name = "usb-otg-vbus";
+				regulator-min-microvolt = <4425000>;
+				regulator-max-microvolt = <5825000>;
+			};
+		};
+
+		regulator {
+			compatible = "mediatek,mt6360-regulator";
+			LDO_VIN3-supply = <&mt6360_buck2>;
+
+			mt6360_buck1: buck1 {
+				regulator-compatible = "BUCK1";
+				regulator-name = "mt6360,buck1";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP
+							   MT6360_OPMODE_ULP>;
+				regulator-always-on;
+			};
+
+			mt6360_buck2: buck2 {
+				regulator-compatible = "BUCK2";
+				regulator-name = "mt6360,buck2";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP
+							   MT6360_OPMODE_ULP>;
+				regulator-always-on;
+			};
+
+			mt6360_ldo1: ldo1 {
+				regulator-compatible = "LDO1";
+				regulator-name = "mt6360,ldo1";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo2: ldo2 {
+				regulator-compatible = "LDO2";
+				regulator-name = "mt6360,ldo2";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo3: ldo3 {
+				regulator-compatible = "LDO3";
+				regulator-name = "mt6360,ldo3";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo5: ldo5 {
+				regulator-compatible = "LDO5";
+				regulator-name = "mt6360,ldo5";
+				regulator-min-microvolt = <2700000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo6: ldo6 {
+				regulator-compatible = "LDO6";
+				regulator-name = "mt6360,ldo6";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo7: ldo7 {
+				regulator-compatible = "LDO7";
+				regulator-name = "mt6360,ldo7";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_default_pins>;
+	pinctrl-1 = <&mmc0_uhs_pins>;
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	cap-mmc-hw-reset;
+	no-sdio;
+	no-sd;
+	hs400-ds-delay = <0x14c11>;
+	vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
+	vqmmc-supply = <&mt6359_vufs_ldo_reg>;
+	non-removable;
+	status = "okay";
+};
+
+&mmc1 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc1_default_pins>;
+	pinctrl-1 = <&mmc1_uhs_pins>;
+	cd-gpios = <&pio 129 GPIO_ACTIVE_LOW>;
+	bus-width = <4>;
+	max-frequency = <200000000>;
+	cap-sd-highspeed;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&mt6360_ldo5>;
+	vqmmc-supply = <&mt6360_ldo3>;
+	status = "okay";
+};
+
+&mt6359_vbbck_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vcore_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vgpu11_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vproc1_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vproc2_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vpu_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vrf12_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vsram_md_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vsram_others_ldo_reg {
+	regulator-always-on;
+};
+
+&nor_flash {
+	pinctrl-names = "default";
+	pinctrl-0 = <&nor_pins_default>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+		spi-rx-bus-width = <2>;
+		spi-tx-bus-width = <2>;
+	};
+};
+
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_pins_default>;
+	status = "okay";
+};
+
+&pcie1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_pins_default>;
+	status = "okay";
+};
+
+&pciephy {
+	status = "okay";
+};
+
+&pio {
+	eth_default_pins: eth-default-pins {
+		pins-txd {
+			pinmux = <PINMUX_GPIO77__FUNC_GBE_TXD3>,
+				 <PINMUX_GPIO78__FUNC_GBE_TXD2>,
+				 <PINMUX_GPIO79__FUNC_GBE_TXD1>,
+				 <PINMUX_GPIO80__FUNC_GBE_TXD0>;
+			drive-strength = <MTK_DRIVE_8mA>;
+		};
+
+		pins-rxd {
+			pinmux = <PINMUX_GPIO81__FUNC_GBE_RXD3>,
+				 <PINMUX_GPIO82__FUNC_GBE_RXD2>,
+				 <PINMUX_GPIO83__FUNC_GBE_RXD1>,
+				 <PINMUX_GPIO84__FUNC_GBE_RXD0>;
+		};
+
+		pins-cc {
+			pinmux = <PINMUX_GPIO85__FUNC_GBE_TXC>,
+				 <PINMUX_GPIO86__FUNC_GBE_RXC>,
+				 <PINMUX_GPIO87__FUNC_GBE_RXDV>,
+				 <PINMUX_GPIO88__FUNC_GBE_TXEN>;
+			drive-strength = <MTK_DRIVE_8mA>;
+		};
+
+		pins-mdio {
+			pinmux = <PINMUX_GPIO89__FUNC_GBE_MDC>,
+				 <PINMUX_GPIO90__FUNC_GBE_MDIO>;
+			input-enable;
+		};
+
+		pins-power {
+			pinmux = <PINMUX_GPIO91__FUNC_GPIO91>,
+				 <PINMUX_GPIO92__FUNC_GPIO92>;
+			output-high;
+		};
+
+		pins-reset {
+			pinmux = <PINMUX_GPIO93__FUNC_GPIO93>;
+			output-high;
+		};
+
+		pins-interrupt {
+			pinmux = <PINMUX_GPIO94__FUNC_GPIO94>;
+			input-enable;
+		};
+	};
+
+	eth_sleep_pins: eth-sleep-pins {
+		pins-txd {
+			pinmux = <PINMUX_GPIO77__FUNC_GPIO77>,
+				 <PINMUX_GPIO78__FUNC_GPIO78>,
+				 <PINMUX_GPIO79__FUNC_GPIO79>,
+				 <PINMUX_GPIO80__FUNC_GPIO80>;
+		};
+		pins-cc {
+			pinmux = <PINMUX_GPIO85__FUNC_GPIO85>,
+				 <PINMUX_GPIO88__FUNC_GPIO88>,
+				 <PINMUX_GPIO87__FUNC_GPIO87>,
+				 <PINMUX_GPIO86__FUNC_GPIO86>;
+		};
+		pins-rxd {
+			pinmux = <PINMUX_GPIO81__FUNC_GPIO81>,
+				 <PINMUX_GPIO82__FUNC_GPIO82>,
+				 <PINMUX_GPIO83__FUNC_GPIO83>,
+				 <PINMUX_GPIO84__FUNC_GPIO84>;
+		};
+		pins-mdio {
+			pinmux = <PINMUX_GPIO89__FUNC_GPIO89>,
+				 <PINMUX_GPIO90__FUNC_GPIO90>;
+			input-disable;
+			bias-disable;
+		};
+	};
+
+	gpio_keys_pins: gpio-keys-pins {
+		pins {
+			pinmux = <PINMUX_GPIO106__FUNC_GPIO106>;
+			input-enable;
+		};
+	};
+
+	i2c2_pins: i2c2-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
+				 <PINMUX_GPIO13__FUNC_SCL2>;
+			bias-pull-up;
+		};
+	};
+
+	i2c3_pins: i2c3-pins {
+		pins {
+			pinmux = <PINMUX_GPIO14__FUNC_SDA3>,
+				 <PINMUX_GPIO15__FUNC_SCL3>;
+			bias-pull-up;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		pins {
+			pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
+				 <PINMUX_GPIO17__FUNC_SCL4>;
+			bias-pull-up;
+		};
+	};
+
+	i2c6_pins: i2c6-pins {
+		pins {
+			pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
+				 <PINMUX_GPIO26__FUNC_SCL6>;
+			bias-pull-up;
+		};
+	};
+
+	mmc0_default_pins: mmc0-default-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+				 <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+				 <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+				 <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+				 <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+				 <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+				 <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+				 <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+				 <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins-rst {
+			pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	mmc0_uhs_pins: mmc0-uhs-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+				 <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+				 <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+				 <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+				 <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+				 <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+				 <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+				 <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+				 <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins-ds {
+			pinmux = <PINMUX_GPIO127__FUNC_MSDC0_DSL>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-rst {
+			pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	mmc1_default_pins: mmc1-default-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
+				 <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
+				 <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
+				 <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
+				 <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins-insert {
+			pinmux = <PINMUX_GPIO129__FUNC_GPIO129>;
+			bias-pull-up;
+		};
+	};
+
+	mmc1_uhs_pins: mmc1-uhs-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
+				 <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
+				 <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
+				 <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
+				 <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	nor_pins_default: nor-default-pins {
+		pins-ck-io {
+			pinmux = <PINMUX_GPIO142__FUNC_SPINOR_IO0>,
+				 <PINMUX_GPIO141__FUNC_SPINOR_CK>,
+				 <PINMUX_GPIO143__FUNC_SPINOR_IO1>;
+			drive-strength = <6>;
+			bias-pull-down;
+		};
+
+		pins-cs {
+			pinmux = <PINMUX_GPIO140__FUNC_SPINOR_CS>;
+			drive-strength = <6>;
+			bias-pull-up;
+		};
+	};
+
+	pcie0_pins_default: pcie0-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO19__FUNC_WAKEN>,
+				 <PINMUX_GPIO20__FUNC_PERSTN>,
+				 <PINMUX_GPIO21__FUNC_CLKREQN>;
+			bias-pull-up;
+		};
+	};
+
+	pcie1_pins_default: pcie1-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO0__FUNC_PERSTN_1>,
+				 <PINMUX_GPIO1__FUNC_CLKREQN_1>,
+				 <PINMUX_GPIO2__FUNC_WAKEN_1>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	led_pins: led-pins {
+		pins-power-en {
+			pinmux = <PINMUX_GPIO107__FUNC_GPIO107>;
+			output-high;
+		};
+	};
+
+	spi0_pins: spi0-default-pins {
+		pins-cs-mosi-clk {
+			pinmux = <PINMUX_GPIO132__FUNC_SPIM0_CSB>,
+				 <PINMUX_GPIO134__FUNC_SPIM0_MO>,
+				 <PINMUX_GPIO133__FUNC_SPIM0_CLK>;
+			bias-disable;
+		};
+
+		pins-miso {
+			pinmux = <PINMUX_GPIO135__FUNC_SPIM0_MI>;
+			bias-pull-down;
+		};
+	};
+
+	spi1_pins: spi1-default-pins {
+		pins-cs-mosi-clk {
+			pinmux = <PINMUX_GPIO136__FUNC_SPIM1_CSB>,
+				 <PINMUX_GPIO138__FUNC_SPIM1_MO>,
+				 <PINMUX_GPIO137__FUNC_SPIM1_CLK>;
+			bias-disable;
+		};
+
+		pins-miso {
+			pinmux = <PINMUX_GPIO139__FUNC_SPIM1_MI>;
+			bias-pull-down;
+		};
+	};
+
+	uart0_pins: uart0-pins {
+		pins_rx {
+			pinmux = <PINMUX_GPIO99__FUNC_URXD0>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins_tx {
+			pinmux = <PINMUX_GPIO98__FUNC_UTXD0>;
+		};
+	};
+
+	uart1_pins: uart1-pins {
+		pins_rx {
+			pinmux = <PINMUX_GPIO103__FUNC_URXD1>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins_tx {
+			pinmux = <PINMUX_GPIO102__FUNC_UTXD1>;
+		};
+
+		pins_rts {
+			pinmux = <PINMUX_GPIO100__FUNC_URTS1>;
+			output-enable;
+		};
+
+		pins_cts {
+			pinmux = <PINMUX_GPIO101__FUNC_UCTS1>;
+			input-enable;
+		};
+	};
+
+	uart2_pins: uart2-pins {
+		pins_rx {
+			pinmux = <PINMUX_GPIO68__FUNC_URXD2>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins_tx {
+			pinmux = <PINMUX_GPIO67__FUNC_UTXD2>;
+		};
+
+		pins_rts {
+			pinmux = <PINMUX_GPIO66__FUNC_URTS2>;
+			output-enable;
+		};
+
+		pins_cts {
+			pinmux = <PINMUX_GPIO65__FUNC_UCTS2>;
+			input-enable;
+		};
+	};
+
+	uart3_pins: uart3-pins {
+		pins_rx {
+			pinmux = <PINMUX_GPIO5__FUNC_URXD3>;
+			input-enable;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins_tx {
+			pinmux = <PINMUX_GPIO4__FUNC_UTXD3>;
+		};
+	};
+
+	uart4_pins: uart4-pins {
+		pins_rx {
+			pinmux = <PINMUX_GPIO7__FUNC_URXD4>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins_tx {
+			pinmux = <PINMUX_GPIO6__FUNC_UTXD4>;
+		};
+	};
+};
+
+&pmic {
+	interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&scp {
+	memory-region = <&scp_mem>;
+	status = "okay";
+};
+
+&spmi {
+	#address-cells = <2>;
+	#size-cells = <0>;
+
+	mt6315 at 6 {
+		compatible = "mediatek,mt6315-regulator";
+		reg = <0x6 SPMI_USID>;
+
+		regulators {
+			mt6315_6_vbuck1: vbuck1 {
+				regulator-compatible = "vbuck1";
+				regulator-name = "Vbcpu";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1193750>;
+				regulator-enable-ramp-delay = <256>;
+				regulator-ramp-delay = <6250>;
+				regulator-allowed-modes = <0 1 2>;
+				regulator-always-on;
+			};
+		};
+	};
+
+	mt6315 at 7 {
+		compatible = "mediatek,mt6315-regulator";
+		reg = <0x7 SPMI_USID>;
+
+		regulators {
+			mt6315_7_vbuck1: vbuck1 {
+				regulator-compatible = "vbuck1";
+				regulator-name = "Vgpu";
+				regulator-min-microvolt = <625000>;
+				regulator-max-microvolt = <1193750>;
+				regulator-enable-ramp-delay = <256>;
+				regulator-ramp-delay = <6250>;
+				regulator-allowed-modes = <0 1 2>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_pins>;
+	mediatek,pad-select = <0>;
+	status = "okay";
+
+	tpm: tpm at 0 {
+		compatible = "infineon,slb9670";
+		reg = <0>;
+		spi-max-frequency = <18500000>;
+	};
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_pins>;
+	mediatek,pad-select = <0>;
+	status = "okay";
+};
+
+&thermal_zones {
+	board0-thermal {
+		polling-delay = <1000>; /* milliseconds */
+		polling-delay-passive = <0>; /* milliseconds */
+		thermal-sensors = <&thermal_sensor0>;
+
+		trips {
+			trip-alert {
+				temperature = <85000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			trip-crit {
+				temperature = <95000>;
+				hysteresis = <2000>;
+				type = "critical";
+			};
+		};
+	};
+
+	board1-thermal {
+		polling-delay = <1000>; /* milliseconds */
+		polling-delay-passive = <0>; /* milliseconds */
+		thermal-sensors = <&thermal_sensor1>;
+
+		trips {
+			trip-alert {
+				temperature = <75000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			trip-crit {
+				temperature = <85000>;
+				hysteresis = <2000>;
+				type = "critical";
+			};
+		};
+	};
+
+	board2-thermal {
+		polling-delay = <1000>; /* milliseconds */
+		polling-delay-passive = <0>; /* milliseconds */
+		thermal-sensors = <&thermal_sensor2>;
+
+		trips {
+			trip-alert {
+				temperature = <75000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			trip-crit {
+				temperature = <85000>;
+				hysteresis = <2000>;
+				type = "critical";
+			};
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+	status = "okay";
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins>;
+	status = "okay";
+};
+
+/* USB3 */
+&u3phy0 {
+	status = "okay";
+};
+
+/* PCIe1/USB2 */
+&u3phy1 {
+	status = "okay";
+};
+
+/* USB2 */
+&u3phy2 {
+	status = "okay";
+};
+
+/* USB2 */
+&u3phy3 {
+	status = "okay";
+};
+
+/* USB3 front port */
+&xhci0 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	vbus-supply = <&otg_vbus_regulator>;
+	status = "okay";
+};
+
+/* USB2 M.2 Key-B */
+&xhci1 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	mediatek,u3p-dis-msk = <0x01>;
+	status = "okay";
+};
+
+/* USB2 M.2 Key-E */
+&xhci2 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	status = "okay";
+};
+
+/* USB2 to on-board usb hub */
+&xhci3 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	status = "okay";
+};
-- 
2.39.2



From jan.kiszka at siemens.com  Fri Feb 16 08:48:51 2024
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Fri, 16 Feb 2024 17:48:51 +0100
Subject: [PATCH] arm64: dts: ti: Add reserved memory for watchdog
In-Reply-To: <20240117060654.109424-1-huaqian.li@siemens.com>
References: <20240117060654.109424-1-huaqian.li@siemens.com>
Message-ID: <c6a3fc6a-d21e-4b76-bfc0-82de2f729ad7@siemens.com>

On 17.01.24 07:06, huaqian.li at siemens.com wrote:
> From: Li Hua Qian <huaqian.li at siemens.com>
> 
> This patch adds a reserved memory for the TI AM65X platform watchdog
> to reserve the specific info, triggering the watchdog reset in last
> boot, to know if the board reboot is due to a watchdog reset.
> 
> Signed-off-by: Li Hua Qian <huaqian.li at siemens.com>
> ---
> The driver and binding have hit the master, which could be found in the
> following link.
> - watchdog:rit_wdt: Add support for WDIOF_CARDRESET
> - dt-bindings: watchdog: ti,rti-wdt: Add support for WDIOF_CARDRESET
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=29057cc5bddc785ea0a11534d7ad2546fa0872d3
> 
>  arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> 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 61a634afaa4f..88321799d468 100644
> --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
> @@ -75,6 +75,12 @@ rtos_ipc_memory_region: ipc-memories at a2000000 {
>  			alignment = <0x1000>;
>  			no-map;
>  		};
> +
> +		/* To reserve the power-on(PON) reason for watchdog reset */
> +		wdt_reset_memory_region: wdt-memory at a2200000 {
> +			reg = <0x00 0xa2200000 0x00 0x1000>;
> +			no-map;
> +		};
>  	};
>  
>  	leds {
> @@ -1427,6 +1433,10 @@ &mcu_r5fss0_core1 {
>  	mboxes = <&mailbox0_cluster1>, <&mbox_mcu_r5fss0_core1>;
>  };
>  
> +&mcu_rti1 {
> +	memory-region = <&wdt_reset_memory_region>;
> +};
> +
>  &icssg0_mdio {
>  	status = "okay";
>  	pinctrl-names = "default";

Is this not forgotten (now that my IOT2050 series was merged)?

Thanks,
Jan

-- 
Siemens AG, Technology
Linux Expert Center



From vishal.sagar at amd.com  Fri Feb 16 08:55:02 2024
From: vishal.sagar at amd.com (Sagar, Vishal)
Date: Fri, 16 Feb 2024 16:55:02 +0000
Subject: [PATCH] drm: xlnx: dp: Reset DisplayPort IP
In-Reply-To: <20240216124043.1226713-1-rohit.visavalia@amd.com>
References: <20240216124043.1226713-1-rohit.visavalia@amd.com>
Message-ID: <BL1PR12MB59699BE91130AD94A8DC6E7D9C4C2@BL1PR12MB5969.namprd12.prod.outlook.com>

[AMD Official Use Only - General]

Hi Rohit,

Thanks for the patch.

> -----Original Message-----
> From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
> Rohit Visavalia
> Sent: Friday, February 16, 2024 1:41 PM
> To: gregkh at linuxfoundation.org; laurent.pinchart at ideasonboard.com;
> maarten.lankhorst at linux.intel.com; mripard at kernel.org;
> tzimmermann at suse.de; airlied at gmail.com; daniel at ffwll.ch; Simek, Michal
> <michal.simek at amd.com>; dri-devel at lists.freedesktop.org; linux-arm-
> kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Subject: [PATCH] drm: xlnx: dp: Reset DisplayPort IP
>
> Assert DisplayPort reset signal before deasserting,
> it is to clear out any registers programmed before booting kernel.
>
> Signed-off-by: Rohit Visavalia <rohit.visavalia at amd.com>
> ---
>  drivers/gpu/drm/xlnx/zynqmp_dp.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index 1846c4971fd8..5a40aa1d4283 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -1714,6 +1714,10 @@ int zynqmp_dp_probe(struct zynqmp_dpsub
> *dpsub)
>               goto err_free;
>       }
>
> +     ret = zynqmp_dp_reset(dp, true);
> +     if (ret < 0)
> +             return ret;
> +
>       ret = zynqmp_dp_reset(dp, false);
>       if (ret < 0)
>               goto err_free;
> --
> 2.25.1

This looks good to me.

Reviewed-by: Vishal Sagar<vishal.sagar at amd.com>

Regards
Vishal Sagar


From catalin.marinas at arm.com  Fri Feb 16 08:56:10 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 16 Feb 2024 16:56:10 +0000
Subject: [PATCH v6 12/18] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <892caa6a-e4fe-4009-aa33-0570526961c5@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-13-ryan.roberts@arm.com>
 <Zc9UQy-mtYAzNWm2@arm.com>
 <892caa6a-e4fe-4009-aa33-0570526961c5@arm.com>
Message-ID: <Zc-Tqqfksho3BHmU@arm.com>

On Fri, Feb 16, 2024 at 12:53:43PM +0000, Ryan Roberts wrote:
> On 16/02/2024 12:25, Catalin Marinas wrote:
> > On Thu, Feb 15, 2024 at 10:31:59AM +0000, Ryan Roberts wrote:
> >>  arch/arm64/mm/contpte.c          | 285 +++++++++++++++++++++++++++++++
> > 
> > Nitpick: I think most symbols in contpte.c can be EXPORT_SYMBOL_GPL().
> > We don't expect them to be used by random out of tree modules. In fact,
> > do we expect them to end up in modules at all? Most seem to be called
> > from the core mm code.
> 
> The problem is that the contpte_* symbols are called from the ptep_* inline
> functions. So where those inlines are called from modules, we need to make sure
> the contpte_* symbols are available.
> 
> John Hubbard originally reported this problem against v1 and I enumerated all
> the drivers that call into the ptep_* inlines here:
> https://lore.kernel.org/linux-arm-kernel/b994ff89-1a1f-26ca-9479-b08c77f94be8 at arm.com/#t
> 
> So they definitely need to be exported. Perhaps we can tighten it to
> EXPORT_SYMBOL_GPL(), but I was being cautious as I didn't want to break anything
> out-of-tree. I'm not sure what the normal policy is? arm64 seems to use ~equal
> amounts of both.

I don't think we are consistent here. For example set_pte_at() can't be
called from non-GPL modules because of __sync_icache_dcache. OTOH, such
driver is probably doing something dodgy. Same with
apply_to_page_range(), it's GPL-only (called from i915).

Let's see if others have any view over the next week or so, otherwise
I'd go for _GPL and relax it later if someone has a good use-case (can
be a patch on top adding _GPL).

> > If you can make this easier to parse (in a few years time) with an
> > additional patch adding some more comments, that would be great. For
> > this patch:
> 
> I already have a big block comment at the top, which was trying to explain it.
> Clearly not well enough though. I'll add more comments as a follow up patch when
> I get back from holiday.

I read that comment but it wasn't immediately obvious what the atomicity
requirements are - basically we require a single PTE to be atomically
read (which it is), the rest is the dirty/young state being added on
top. I guess a sentence along these lines would do.

Enjoy your holiday!

-- 
Catalin


From pbonzini at redhat.com  Fri Feb 16 09:02:42 2024
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Fri, 16 Feb 2024 18:02:42 +0100
Subject: [GIT PULL] KVM/arm64 fixes for 6.8, take #2
In-Reply-To: <20240215152935.3093768-1-maz@kernel.org>
References: <20240215152935.3093768-1-maz@kernel.org>
Message-ID: <CABgObfZAr77NxyoMCih1+hVQ9=Usu9p+yqkoqdCBQSuWwPvv1Q@mail.gmail.com>

On Thu, Feb 15, 2024 at 4:29?PM Marc Zyngier <maz at kernel.org> wrote:
>
> Hi Paolo,
>
> Another week, another very small pull request. This time, the bug is
> irritating enough that I want it fixed and backported right away. It
> has only been found by inspection (thanks Will!), but once you've seen
> it, you can unsee it.
>
> If you haven't pulled the previous tag [1], you'll get both for free.
>
> Please pull,

Pulled, thanks.

Paolo

>         M.
>
> [1] https://lore.kernel.org/r/20240207144611.1128848-1-maz at kernel.org
>
>
> The following changes since commit 42dfa94d802a48c871e2017cbf86153270c86632:
>
>   KVM: arm64: Do not source virt/lib/Kconfig twice (2024-02-04 13:08:28 +0000)
> are available in the Git repository at:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-fixes-6.8-2
>
> for you to fetch changes up to c60d847be7b8e69e419e02a2b3d19c2842a3c35d:
>
>   KVM: arm64: Fix double-free following kvm_pgtable_stage2_free_unlinked() (2024-02-13 19:22:03 +0000)
>
> ----------------------------------------------------------------
> KVM/arm64 fixes for 6.8, take #2
>
> - Avoid dropping the page refcount twice when freeing an unlinked
>   page-table subtree.
>
> ----------------------------------------------------------------
> Will Deacon (1):
>       KVM: arm64: Fix double-free following kvm_pgtable_stage2_free_unlinked()
>
>  arch/arm64/kvm/hyp/pgtable.c | 2 --
>  1 file changed, 2 deletions(-)
>



From daniel at ffwll.ch  Fri Feb 16 09:04:43 2024
From: daniel at ffwll.ch (Daniel Vetter)
Date: Fri, 16 Feb 2024 18:04:43 +0100
Subject: [PATCH v5 10/13] drm/mediatek: Support CRC in display driver
In-Reply-To: <20240215101119.12629-11-shawn.sung@mediatek.com>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
 <20240215101119.12629-11-shawn.sung@mediatek.com>
Message-ID: <Zc-Vq2MeG9X37JJe@phenom.ffwll.local>

On Thu, Feb 15, 2024 at 06:11:16PM +0800, Hsiao Chien Sung wrote:
> Register CRC related function pointers to support
> CRC retrieval.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 239 ++++++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |  39 ++++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   3 +
>  3 files changed, 281 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 14cf75fa217f9..6cb1ed419dee7 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -68,6 +68,9 @@ struct mtk_drm_crtc {
>  	/* lock for display hardware access */
>  	struct mutex			hw_lock;
>  	bool				config_updating;
> +
> +	struct mtk_ddp_comp		*crc_provider;
> +	unsigned int			frames;
>  };
>  
>  struct mtk_crtc_state {
> @@ -635,6 +638,14 @@ static void mtk_crtc_ddp_irq(void *data)
>  	struct drm_crtc *crtc = data;
>  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
>  	struct mtk_drm_private *priv = crtc->dev->dev_private;
> +	struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
> +
> +	/*
> +	 * crc providers should make sure the crc is always correct
> +	 * by resetting it in .crc_read()
> +	 */
> +	if (crtc->crc.opened)
> +		comp->funcs->crc_read(comp->dev);
>  
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
>  	if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
> @@ -646,6 +657,24 @@ static void mtk_crtc_ddp_irq(void *data)
>  	if (!priv->data->shadow_register)
>  		mtk_crtc_ddp_config(crtc, NULL);
>  #endif
> +
> +	/*
> +	 * drm_crtc_add_crc_entry() could take more than 50ms to finish
> +	 * put it at the end of the isr
> +	 */

Uh this looks really scary, especially since you put this before the call
to drm_crtc_handle_vblank in the function below, which really shouldn't be
unecessarily delayed (because that's the one that takes the vblank
timestamp).

This sounds like the perfect application for a vblank worker though, so
you please look into drm_vblank_work.h. And if that is not useable due to
hardware constraint, then please explain in a comment here and in the
commit message why you cannot use that and have to roll your own. vblank
work really should be your first choice here, because:
- it's designed for expensive vblank work
- it gives you all the flush/cancel_sync functions you need for disabling
  crc again, and in a race-free implementation. Much better to use common
  code than to reinvent synchronization wheels in drivers :-)

> +	if (crtc->crc.opened) {

Because this is probably not race-free, so we need something solid here.

Cheers, Sima


> +		/*
> +		 * skip the first crc because the first frame is configured by
> +		 * mtk_crtc_ddp_hw_init() when atomic enable
> +		 */
> +		if (++mtk_crtc->frames > 1) {
> +			drm_crtc_add_crc_entry(crtc, true,
> +					       drm_crtc_vblank_count(crtc),
> +					       comp->funcs->crc_entry(comp->dev));
> +		}
> +	} else {
> +		mtk_crtc->frames = 0;
> +	}
>  	mtk_drm_finish_page_flip(mtk_crtc);
>  }
>  
> @@ -704,6 +733,40 @@ static void mtk_drm_crtc_update_output(struct drm_crtc *crtc,
>  	}
>  }
>  
> +static int mtk_drm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src)
> +{
> +	if (src && strcmp(src, "auto") != 0) {
> +		DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
> +			  __func__, drm_crtc_index(crtc), src);
> +		return -EINVAL;
> +	}
> +	return 0;
> +}
> +
> +static int mtk_drm_crtc_verify_crc_source(struct drm_crtc *crtc,
> +					  const char *src,
> +					  size_t *cnt)
> +{
> +	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> +	struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
> +
> +	if (!comp) {
> +		DRM_ERROR("%s(crtc-%d): no crc provider\n",
> +			  __func__, drm_crtc_index(crtc));
> +		return -ENOENT;
> +	}
> +
> +	if (src && strcmp(src, "auto") != 0) {
> +		DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
> +			  __func__, drm_crtc_index(crtc), src);
> +		return -EINVAL;
> +	}
> +
> +	*cnt = comp->funcs->crc_cnt(comp->dev);
> +
> +	return 0;
> +}
> +
>  int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
>  			     struct mtk_plane_state *state)
>  {
> @@ -841,6 +904,8 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
>  	.atomic_destroy_state	= mtk_drm_crtc_destroy_state,
>  	.enable_vblank		= mtk_drm_crtc_enable_vblank,
>  	.disable_vblank		= mtk_drm_crtc_disable_vblank,
> +	.set_crc_source		= mtk_drm_crtc_set_crc_source,
> +	.verify_crc_source	= mtk_drm_crtc_verify_crc_source,
>  };
>  
>  static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
> @@ -1033,6 +1098,11 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>  
>  			if (comp->funcs->ctm_set)
>  				has_ctm = true;
> +
> +			if (comp->funcs->crc_cnt &&
> +			    comp->funcs->crc_entry &&
> +			    comp->funcs->crc_read)
> +				mtk_crtc->crc_provider = comp;
>  		}
>  
>  		mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq,
> @@ -1137,3 +1207,172 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>  
>  	return 0;
>  }
> +
> +void mtk_drm_crc_init(struct mtk_drm_crc *crc,
> +		      const u32 *crc_offset_table, size_t crc_count,
> +		      u32 reset_offset, u32 reset_mask)
> +{
> +	crc->ofs = crc_offset_table;
> +	crc->cnt = crc_count;
> +	crc->rst_ofs = reset_offset;
> +	crc->rst_msk = reset_mask;
> +	crc->va = kcalloc(crc->cnt, sizeof(*crc->va), GFP_KERNEL);
> +	if (!crc->va) {
> +		DRM_ERROR("failed to allocate memory for crc\n");
> +		crc->cnt = 0;
> +	}
> +}
> +
> +void mtk_drm_crc_read(struct mtk_drm_crc *crc, void __iomem *reg)
> +{
> +	if (!crc->cnt || !crc->ofs || !crc->va)
> +		return;
> +
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	/* sync to see the most up-to-date copy of the DMA buffer */
> +	dma_sync_single_for_cpu(crc->cmdq_client.chan->mbox->dev,
> +				crc->pa, crc->cnt * sizeof(*crc->va),
> +				DMA_FROM_DEVICE);
> +#else
> +	/* read crc with cpu for the platforms without cmdq */
> +	{
> +		u32 n;
> +
> +		for (n = 0; n < crc->cnt; n++)
> +			crc->va[n] = readl(reg + crc->ofs[n]);
> +
> +		n = readl(reg + crc->rst_ofs);
> +
> +		/* pull reset bit */
> +		n |= crc->rst_msk;
> +		writel(n, reg + crc->rst_ofs);
> +
> +		/* release reset bit */
> +		n &= ~crc->rst_msk;
> +		writel(n, reg + crc->rst_ofs);
> +	}
> +#endif
> +}
> +
> +void mtk_drm_crc_destroy(struct mtk_drm_crc *crc)
> +{
> +	if (!crc->cnt)
> +		return;
> +
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	if (crc->pa) {
> +		dma_unmap_single(crc->cmdq_client.chan->mbox->dev,
> +				 crc->pa, crc->cnt * sizeof(*crc->va),
> +				 DMA_TO_DEVICE);
> +		crc->pa = 0;
> +	}
> +	if (crc->cmdq_client.chan) {
> +		mtk_drm_cmdq_pkt_destroy(&crc->cmdq_handle);
> +		mbox_free_channel(crc->cmdq_client.chan);
> +		crc->cmdq_client.chan = NULL;
> +	}
> +#endif
> +	kfree(crc->va);
> +	crc->va = NULL;
> +	crc->cnt = 0;
> +}
> +
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +void mtk_drm_crc_cmdq_create(struct device *dev, struct mtk_drm_crc *crc)
> +{
> +	int i;
> +
> +	if (!crc->cnt) {
> +		dev_warn(dev, "%s: not support\n", __func__);
> +		goto cleanup;
> +	}
> +
> +	if (!crc->ofs) {
> +		dev_warn(dev, "%s: not defined\n", __func__);
> +		goto cleanup;
> +	}
> +
> +	crc->cmdq_client.client.dev = dev;
> +	crc->cmdq_client.client.tx_block = false;
> +	crc->cmdq_client.client.knows_txdone = true;
> +	crc->cmdq_client.client.rx_callback = NULL;
> +	crc->cmdq_client.chan = mbox_request_channel(&crc->cmdq_client.client, 0);
> +	if (IS_ERR(crc->cmdq_client.chan)) {
> +		dev_warn(dev, "%s: failed to create mailbox client\n", __func__);
> +		crc->cmdq_client.chan = NULL;
> +		goto cleanup;
> +	}
> +
> +	if (mtk_drm_cmdq_pkt_create(&crc->cmdq_client, &crc->cmdq_handle, PAGE_SIZE)) {
> +		dev_warn(dev, "%s: failed to create cmdq packet\n", __func__);
> +		goto cleanup;
> +	}
> +
> +	if (!crc->va) {
> +		dev_warn(dev, "%s: no memory\n", __func__);
> +		goto cleanup;
> +	}
> +
> +	/* map the entry to get a dma address for cmdq to store the crc */
> +	crc->pa = dma_map_single(crc->cmdq_client.chan->mbox->dev,
> +				 crc->va, crc->cnt * sizeof(*crc->va),
> +				 DMA_FROM_DEVICE);
> +
> +	if (dma_mapping_error(crc->cmdq_client.chan->mbox->dev, crc->pa)) {
> +		dev_err(dev, "%s: failed to map dma\n", __func__);
> +		goto cleanup;
> +	}
> +
> +	if (crc->cmdq_event)
> +		cmdq_pkt_wfe(&crc->cmdq_handle, crc->cmdq_event, true);
> +
> +	for (i = 0; i < crc->cnt; i++) {
> +		/* put crc to spr1 register */
> +		cmdq_pkt_read_s(&crc->cmdq_handle, crc->cmdq_reg->subsys,
> +				crc->cmdq_reg->offset + crc->ofs[i],
> +				CMDQ_THR_SPR_IDX1);
> +
> +		/* copy spr1 register to physical address of the crc */
> +		cmdq_pkt_assign(&crc->cmdq_handle, CMDQ_THR_SPR_IDX0,
> +				CMDQ_ADDR_HIGH(crc->pa + i * sizeof(*crc->va)));
> +		cmdq_pkt_write_s(&crc->cmdq_handle, CMDQ_THR_SPR_IDX0,
> +				 CMDQ_ADDR_LOW(crc->pa + i * sizeof(*crc->va)),
> +				 CMDQ_THR_SPR_IDX1);
> +	}
> +	/* reset crc */
> +	mtk_ddp_write_mask(&crc->cmdq_handle, ~0, crc->cmdq_reg, 0,
> +			   crc->rst_ofs, crc->rst_msk);
> +
> +	/* clear reset bit */
> +	mtk_ddp_write_mask(&crc->cmdq_handle, 0, crc->cmdq_reg, 0,
> +			   crc->rst_ofs, crc->rst_msk);
> +
> +	/* jump to head of the cmdq packet */
> +	cmdq_pkt_jump(&crc->cmdq_handle, crc->cmdq_handle.pa_base);
> +
> +	return;
> +cleanup:
> +	mtk_drm_crc_destroy(crc);
> +}
> +
> +void mtk_drm_crc_cmdq_start(struct mtk_drm_crc *crc)
> +{
> +	if (!crc->cmdq_client.chan)
> +		return;
> +
> +	dma_sync_single_for_device(crc->cmdq_client.chan->mbox->dev,
> +				   crc->cmdq_handle.pa_base,
> +				   crc->cmdq_handle.cmd_buf_size,
> +				   DMA_TO_DEVICE);
> +	mbox_send_message(crc->cmdq_client.chan, &crc->cmdq_handle);
> +	mbox_client_txdone(crc->cmdq_client.chan, 0);
> +}
> +
> +void mtk_drm_crc_cmdq_stop(struct mtk_drm_crc *crc)
> +{
> +	if (!crc->cmdq_client.chan)
> +		return;
> +
> +	mbox_flush(crc->cmdq_client.chan, 2000);
> +}
> +#endif
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> index 3c224595fa714..0683ec4bc26f6 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> @@ -15,6 +15,45 @@
>  #define MTK_MAX_BPC	10
>  #define MTK_MIN_BPC	3
>  
> +/**
> + * struct mtk_drm_crc - crc related information
> + * @ofs: register offset of crc
> + * @rst_ofs: register offset of crc reset
> + * @rst_msk: register mask of crc reset
> + * @cnt: count of crc
> + * @va: pointer to the start of crc array
> + * @pa: physical address of the crc for gce to access
> + * @cmdq_event: the event to trigger the cmdq
> + * @cmdq_reg: address of the register that cmdq is going to access
> + * @cmdq_client: handler to control cmdq (mbox channel, thread ...etc.)
> + * @cmdq_handle: cmdq packet to store the commands
> + */
> +struct mtk_drm_crc {
> +	const u32 *ofs;
> +	u32 rst_ofs;
> +	u32 rst_msk;
> +	size_t cnt;
> +	u32 *va;
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	dma_addr_t pa;
> +	u32 cmdq_event;
> +	struct cmdq_client_reg *cmdq_reg;
> +	struct cmdq_client cmdq_client;
> +	struct cmdq_pkt cmdq_handle;
> +#endif
> +};
> +
> +void mtk_drm_crc_init(struct mtk_drm_crc *crc,
> +		      const u32 *crc_offset_table, size_t crc_count,
> +		      u32 reset_offset, u32 reset_mask);
> +void mtk_drm_crc_read(struct mtk_drm_crc *crc, void __iomem *reg);
> +void mtk_drm_crc_destroy(struct mtk_drm_crc *crc);
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +void mtk_drm_crc_cmdq_create(struct device *dev, struct mtk_drm_crc *crc);
> +void mtk_drm_crc_cmdq_start(struct mtk_drm_crc *crc);
> +void mtk_drm_crc_cmdq_stop(struct mtk_drm_crc *crc);
> +#endif
> +
>  void mtk_drm_crtc_commit(struct drm_crtc *crtc);
>  int mtk_drm_crtc_create(struct drm_device *drm_dev,
>  			const unsigned int *path,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 215b7234ff13c..231017470607e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -87,6 +87,9 @@ struct mtk_ddp_comp_funcs {
>  	void (*remove)(struct device *dev, struct mtk_mutex *mutex);
>  	unsigned int (*encoder_index)(struct device *dev);
>  	enum drm_mode_status (*mode_valid)(struct device *dev, const struct drm_display_mode *mode);
> +	size_t (*crc_cnt)(struct device *dev);
> +	u32 *(*crc_entry)(struct device *dev);
> +	void (*crc_read)(struct device *dev);
>  };
>  
>  struct mtk_ddp_comp {
> -- 
> 2.18.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From nm at ti.com  Fri Feb 16 09:09:30 2024
From: nm at ti.com (Nishanth Menon)
Date: Fri, 16 Feb 2024 11:09:30 -0600
Subject: [PATCH v4] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240213082640.457316-1-u-kumar1@ti.com>
References: <20240213082640.457316-1-u-kumar1@ti.com>
Message-ID: <20240216170930.cp5rg2iieaqogrwa@selected>

On 13:56-20240213, Udit Kumar wrote:
> Most of clocks and their parents are defined in contiguous range,
> But in few cases, there is gap in clock numbers[0].
> Driver assumes clocks to be in contiguous range, and add their clock
> ids incrementally.
> 
> New firmware started returning error while calling get_freq and is_on
> API for non-available clock ids.
> 
> In this fix, driver checks and adds only valid clock ids.
> 
> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> Section Clocks for NAVSS0_CPTS_0 Device, clock id 12-15 not present.
> 
> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
> ---
> Changelog
> Changes in v4
> - Added only incremental chanegs as per v3 discussion
> - Updated commit message
> - v3 was Reviewed-by, Dropping Reviewed-by as logic is changed
> Link to v3
> https://lore.kernel.org/all/20240207091100.4001428-1-u-kumar1 at ti.com/ 
> 
> Changes in v3
> - instead of get_freq, is_auto API is used to check validilty of clock
> - Address comments of v2, to have preindex increment
> Link to v2 https://lore.kernel.org/all/20240206104357.3803517-1-u-kumar1 at ti.com/
> 
> Changes in v2
> - Updated commit message
> - Simplified logic for valid clock id
> link to v1 https://lore.kernel.org/all/20240205044557.3340848-1-u-kumar1 at ti.com/
> 
> 
> P.S
> Firmawre returns total num_parents count including non available ids.
> For above device id NAVSS0_CPTS_0, number of parents clocks are 16
> i.e from id 2 to 17. But out of these ids few are not valid.
> So driver adds only valid clock ids out ot total.
> 
> Original logs
> https://gist.github.com/uditkumarti/de4b36b21247fb36725ad909ce4812f6#file-original-logs
> Line 2630 for error
> 
> Logs with fix v4
> https://gist.github.com/uditkumarti/f25482a5e18e918010b790cffb39f572
> Line 2640
> 
> 
>  drivers/clk/keystone/sci-clk.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> index 35fe197dd303..eb2ef44869b2 100644
> --- a/drivers/clk/keystone/sci-clk.c
> +++ b/drivers/clk/keystone/sci-clk.c
> @@ -516,6 +516,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  	struct sci_clk *sci_clk, *prev;
>  	int num_clks = 0;
>  	int num_parents;
> +	bool state;
>  	int clk_id;
>  	const char * const clk_names[] = {
>  		"clocks", "assigned-clocks", "assigned-clock-parents", NULL
> @@ -586,6 +587,15 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
>  				clk_id = args.args[1] + 1;
>  
>  				while (num_parents--) {
> +					/* Check if this clock id is valid */
> +					ret = provider->ops->is_auto(provider->sci,
> +						sci_clk->dev_id, clk_id, &state);
> +
> +					if (ret) {
> +						clk_id++;
> +						continue;
> +					}
> +


Thanks. This makes more sense.

Reviewed-by: Nishanth Menon <nm at ti.com>
>  					sci_clk = devm_kzalloc(dev,
>  							       sizeof(*sci_clk),
>  							       GFP_KERNEL);
> -- 
> 2.34.1
> 

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From anup at brainfault.org  Fri Feb 16 09:11:20 2024
From: anup at brainfault.org (Anup Patel)
Date: Fri, 16 Feb 2024 22:41:20 +0530
Subject: [PATCH v12 14/25] irqchip/sifive-plic: Convert PLIC driver into a
 platform driver
In-Reply-To: <87jzn4ctks.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-15-apatel@ventanamicro.com> <87jzn4ctks.ffs@tglx>
Message-ID: <CAAhSdy2aeyJBcMVre12jGwU52oP9Z=1emB-bcYxygdR3QhP+6w@mail.gmail.com>

On Fri, Feb 16, 2024 at 9:03?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> > +     priv->irqdomain = irq_domain_create_linear(dev->fwnode, nr_irqs + 1,
> > +                                                &plic_irqdomain_ops, priv);
> > +     if (WARN_ON(!priv->irqdomain))
> > +             return -ENOMEM;
>
> While some of the stuff is cleaned up by devm, the error handling in
> this code looks pretty fragile as it leaves initialized contexts,
> hardware state, chained handlers etc. around.

Sure, let me try to improve the error handling.

>
> The question is whether the system can actually boot or work at all if
> any of this fails.

On platforms with PLIC, the PLIC only manages wired interrupts
whereas IPIs are provided through SBI (firmware interface) so a
system can actually continue and boot further without PLIC.

In fact, we do have a synthetic platform (namely QEMU spike)
where there is no PLIC instance and Linux boots using SBI based
polling console.

>
> > +
> >       /*
> >        * We can have multiple PLIC instances so setup cpuhp state
> > -      * and register syscore operations only when context handler
> > -      * for current/boot CPU is present.
> > +      * and register syscore operations only after context handlers
> > +      * of all online CPUs are initialized.
> >        */
> > -     handler = this_cpu_ptr(&plic_handlers);
> > -     if (handler->present && !plic_cpuhp_setup_done) {
> > +     cpuhp_setup = true;
> > +     for_each_online_cpu(cpu) {
> > +             handler = per_cpu_ptr(&plic_handlers, cpu);
> > +             if (!handler->present) {
> > +                     cpuhp_setup = false;
> > +                     break;
> > +             }
> > +     }
> > +     if (cpuhp_setup) {
> >               cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
> >                                 "irqchip/sifive/plic:starting",
> >                                 plic_starting_cpu, plic_dying_cpu);
> >               register_syscore_ops(&plic_irq_syscore_ops);
> > -             plic_cpuhp_setup_done = true;
>
> I don't think that removing the setup protection is correct.
>
> Assume you have maxcpus=N on the kernel command line, then the above
> for_each_online_cpu() loop would result in cpuhp_setup == true when the
> instances for the not onlined CPUs are set up, no?

A platform can have multiple PLIC instances where each PLIC
instance targets a subset of HARTs (or CPUs).

Previously (before this patch), we were probing PLIC very early so on
a platform with multiple PLIC instances, we need to ensure that cpuhp
setup is done only after PLIC context associated with boot CPU is
initialized hence the plic_cpuhp_setup_done check.

This patch converts PLIC driver into a platform driver so now PLIC
instances are probed after all available CPUs are brought-up. In this
case, the cpuhp setup must be done only after PLIC context of all
available CPUs are initialized otherwise some of the CPUs crash
in plic_starting_cpu() due to lack of PLIC context initialization.

Regards,
Anup


From jgg at nvidia.com  Fri Feb 16 09:12:17 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 16 Feb 2024 13:12:17 -0400
Subject: [PATCH v5 04/17] iommu/arm-smmu-v3: Move the STE generation for
 S1 and S2 domains into functions
In-Reply-To: <4-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <4-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
Message-ID: <20240216171217.GA102281@nvidia.com>

On Tue, Feb 06, 2024 at 11:12:41AM -0400, Jason Gunthorpe wrote:
> +static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
> +					struct arm_smmu_master *master,
> +					struct arm_smmu_domain *smmu_domain)
> +{
> +	struct arm_smmu_s2_cfg *s2_cfg = &smmu_domain->s2_cfg;
> +
> +	memset(target, 0, sizeof(*target));
> +	target->data[0] = cpu_to_le64(
> +		STRTAB_STE_0_V |
> +		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS));
> +
> +	target->data[1] = cpu_to_le64(
> +		FIELD_PREP(STRTAB_STE_1_EATS,
> +			   master->ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0) |
> +		FIELD_PREP(STRTAB_STE_1_SHCFG,
> +			   STRTAB_STE_1_SHCFG_NON_SHARABLE));

Just so we are on the same page.. The above NON_SHARABLE is a mistake
here since v1.

It is hard to follow arm_smmu_write_strtab_ent() so we all missed that
the S2 ends up re-using the qword[1] that was installed by the
bypass/abort STE that has to be in place prior to installing the S2.

Only the S1 path sets SHCFG to 0 because the HW doesn't use it due to
the current driver not using S1DSS.

Jason


From f.fainelli at gmail.com  Fri Feb 16 09:13:51 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Fri, 16 Feb 2024 09:13:51 -0800
Subject: [PATCH] net: stmmac: mmc_core: Assign, don't add interrupt
 registers
In-Reply-To: <20240216-stmmac_stats-v1-1-7065fa4613f8@axis.com>
References: <20240216-stmmac_stats-v1-1-7065fa4613f8@axis.com>
Message-ID: <61bdd802-abe4-4544-8e48-9493a6bb99c8@gmail.com>

On 2/16/24 07:24, Jesper Nilsson wrote:
> The MMC IPC interrupt status and interrupt mask registers are of
> little use as Ethernet statistics, but incrementing counters
> based on the current interrupt and interrupt mask registers
> makes them worse than useless.
> 
> For example, if the interrupt mask is set to 0x08420842,
> the current code will increment by that amount each iteration,
> leading to the following sequence of nonsense:
> 
> mmc_rx_ipc_intr_mask: 969816526
> mmc_rx_ipc_intr_mask: 1108361744
> 
> Change the increment to a straight assignment to make the
> statistics at least nominally useful.
> 
> Signed-off-by: Jesper Nilsson <jesper.nilsson at axis.com>
> ---
>   drivers/net/ethernet/stmicro/stmmac/mmc_core.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
> index 6a7c1d325c46..6051a22b3cec 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
> @@ -280,8 +280,8 @@ static void dwmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc)
>   	mmc->mmc_rx_vlan_frames_gb += readl(mmcaddr + MMC_RX_VLAN_FRAMES_GB);
>   	mmc->mmc_rx_watchdog_error += readl(mmcaddr + MMC_RX_WATCHDOG_ERROR);
>   	/* IPC */
> -	mmc->mmc_rx_ipc_intr_mask += readl(mmcaddr + MMC_RX_IPC_INTR_MASK);
> -	mmc->mmc_rx_ipc_intr += readl(mmcaddr + MMC_RX_IPC_INTR);
> +	mmc->mmc_rx_ipc_intr_mask = readl(mmcaddr + MMC_RX_IPC_INTR_MASK);
> +	mmc->mmc_rx_ipc_intr = readl(mmcaddr + MMC_RX_IPC_INTR);

So in premise I agree with the patch, that incrementing those is not the 
right way to go about them. However these registers are currently 
provided as part of the statistics set, but they should instead be 
accessed via the register dumping method.

In either case you will get at best a snapshot of those two registers at 
any given time and I suppose this can help diagnose a stuck RX 
condition, but not much more than that.
-- 
Florian



From andrew at lunn.ch  Fri Feb 16 09:16:51 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 16 Feb 2024 18:16:51 +0100
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com>
 <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
 <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
 <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com>
Message-ID: <9638a213-76a5-4a72-b6b2-018ae50305be@lunn.ch>

> You can get the source at https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016/-/tree/NHSS.QSDK.12.2?ref_type=heads

Cool, thanks. But is it really u-boot from 2016?

> Yeah agree with your comments.
> 
> QSDK's u-boot enables the network support, so the required NSSCC clocks are
> turned ON and left it in ON state. CCF tries to disables the unused NSSCC
> clocks but system goes for reboot.
> 
> Reason being, to access the NSSCC clocks, these GCC clocks
> (gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk)
> should be turned ON. But CCF disables these clocks as well due to the lack
> of consumer.

So there is your solution, make NSSCC a consumer of the clocks it
actually consumes. If it needs these clocks, it should get and enable
them.

	Andrew


From daniel at ffwll.ch  Fri Feb 16 09:17:41 2024
From: daniel at ffwll.ch (Daniel Vetter)
Date: Fri, 16 Feb 2024 18:17:41 +0100
Subject: [PATCH v5 10/13] drm/mediatek: Support CRC in display driver
In-Reply-To: <Zc-Vq2MeG9X37JJe@phenom.ffwll.local>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
 <20240215101119.12629-11-shawn.sung@mediatek.com>
 <Zc-Vq2MeG9X37JJe@phenom.ffwll.local>
Message-ID: <Zc-YtaJV1-EMiJoC@phenom.ffwll.local>

On Fri, Feb 16, 2024 at 06:04:43PM +0100, Daniel Vetter wrote:
> On Thu, Feb 15, 2024 at 06:11:16PM +0800, Hsiao Chien Sung wrote:
> > Register CRC related function pointers to support
> > CRC retrieval.
> > 
> > Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 239 ++++++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |  39 ++++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   3 +
> >  3 files changed, 281 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index 14cf75fa217f9..6cb1ed419dee7 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -68,6 +68,9 @@ struct mtk_drm_crtc {
> >  	/* lock for display hardware access */
> >  	struct mutex			hw_lock;
> >  	bool				config_updating;
> > +
> > +	struct mtk_ddp_comp		*crc_provider;
> > +	unsigned int			frames;
> >  };
> >  
> >  struct mtk_crtc_state {
> > @@ -635,6 +638,14 @@ static void mtk_crtc_ddp_irq(void *data)
> >  	struct drm_crtc *crtc = data;
> >  	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> >  	struct mtk_drm_private *priv = crtc->dev->dev_private;
> > +	struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
> > +
> > +	/*
> > +	 * crc providers should make sure the crc is always correct
> > +	 * by resetting it in .crc_read()
> > +	 */
> > +	if (crtc->crc.opened)
> > +		comp->funcs->crc_read(comp->dev);
> >  
> >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> >  	if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
> > @@ -646,6 +657,24 @@ static void mtk_crtc_ddp_irq(void *data)
> >  	if (!priv->data->shadow_register)
> >  		mtk_crtc_ddp_config(crtc, NULL);
> >  #endif
> > +
> > +	/*
> > +	 * drm_crtc_add_crc_entry() could take more than 50ms to finish
> > +	 * put it at the end of the isr
> > +	 */
> 
> Uh this looks really scary, especially since you put this before the call
> to drm_crtc_handle_vblank in the function below, which really shouldn't be
> unecessarily delayed (because that's the one that takes the vblank
> timestamp).
> 
> This sounds like the perfect application for a vblank worker though, so
> you please look into drm_vblank_work.h. And if that is not useable due to
> hardware constraint, then please explain in a comment here and in the
> commit message why you cannot use that and have to roll your own. vblank
> work really should be your first choice here, because:
> - it's designed for expensive vblank work
> - it gives you all the flush/cancel_sync functions you need for disabling
>   crc again, and in a race-free implementation. Much better to use common
>   code than to reinvent synchronization wheels in drivers :-)
> 
> > +	if (crtc->crc.opened) {
> 
> Because this is probably not race-free, so we need something solid here.

Since it's maybe a bit tricky to see how to use drm_vblank_work:

- in your crtc initialization you also need to setup the crc work with
  drm_vblank_work_init().
- Your mtk_drm_crtc_set_sourc needs to actually enable the crc by calling
  drm_vblank_work_schedule for current vblank + 1, so that it immediately
  starts
- your vblank worker itself needs to again re-arm itself with
  drm_vblank_work_schedule, again for the very next vblank
- then your set_source also needs to handle the case where you disable the
  crc again (source == NULL) by calling drm_vblank_work_cancel_sync
- also you probably need to call drm_vblank_work_flush when shutting down
  the crtc, or you might have use-after-free issues on driver unload.
  Could probably also just put that in your crtc release function.

No changes to your interrupt handler needed, and also definitely no
digging around in drm_crtc->crc data structure without locking - that's
entirely internal to the common crc code and drivers must never look
into it.

Cheers, Sima

> 
> 
> > +		/*
> > +		 * skip the first crc because the first frame is configured by
> > +		 * mtk_crtc_ddp_hw_init() when atomic enable
> > +		 */
> > +		if (++mtk_crtc->frames > 1) {
> > +			drm_crtc_add_crc_entry(crtc, true,
> > +					       drm_crtc_vblank_count(crtc),
> > +					       comp->funcs->crc_entry(comp->dev));
> > +		}
> > +	} else {
> > +		mtk_crtc->frames = 0;
> > +	}
> >  	mtk_drm_finish_page_flip(mtk_crtc);
> >  }
> >  
> > @@ -704,6 +733,40 @@ static void mtk_drm_crtc_update_output(struct drm_crtc *crtc,
> >  	}
> >  }
> >  
> > +static int mtk_drm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src)
> > +{
> > +	if (src && strcmp(src, "auto") != 0) {
> > +		DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
> > +			  __func__, drm_crtc_index(crtc), src);
> > +		return -EINVAL;
> > +	}
> > +	return 0;
> > +}
> > +
> > +static int mtk_drm_crtc_verify_crc_source(struct drm_crtc *crtc,
> > +					  const char *src,
> > +					  size_t *cnt)
> > +{
> > +	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> > +	struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
> > +
> > +	if (!comp) {
> > +		DRM_ERROR("%s(crtc-%d): no crc provider\n",
> > +			  __func__, drm_crtc_index(crtc));
> > +		return -ENOENT;
> > +	}
> > +
> > +	if (src && strcmp(src, "auto") != 0) {
> > +		DRM_ERROR("%s(crtc-%d): unknown source '%s'\n",
> > +			  __func__, drm_crtc_index(crtc), src);
> > +		return -EINVAL;
> > +	}
> > +
> > +	*cnt = comp->funcs->crc_cnt(comp->dev);
> > +
> > +	return 0;
> > +}
> > +
> >  int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
> >  			     struct mtk_plane_state *state)
> >  {
> > @@ -841,6 +904,8 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
> >  	.atomic_destroy_state	= mtk_drm_crtc_destroy_state,
> >  	.enable_vblank		= mtk_drm_crtc_enable_vblank,
> >  	.disable_vblank		= mtk_drm_crtc_disable_vblank,
> > +	.set_crc_source		= mtk_drm_crtc_set_crc_source,
> > +	.verify_crc_source	= mtk_drm_crtc_verify_crc_source,
> >  };
> >  
> >  static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
> > @@ -1033,6 +1098,11 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
> >  
> >  			if (comp->funcs->ctm_set)
> >  				has_ctm = true;
> > +
> > +			if (comp->funcs->crc_cnt &&
> > +			    comp->funcs->crc_entry &&
> > +			    comp->funcs->crc_read)
> > +				mtk_crtc->crc_provider = comp;
> >  		}
> >  
> >  		mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq,
> > @@ -1137,3 +1207,172 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
> >  
> >  	return 0;
> >  }
> > +
> > +void mtk_drm_crc_init(struct mtk_drm_crc *crc,
> > +		      const u32 *crc_offset_table, size_t crc_count,
> > +		      u32 reset_offset, u32 reset_mask)
> > +{
> > +	crc->ofs = crc_offset_table;
> > +	crc->cnt = crc_count;
> > +	crc->rst_ofs = reset_offset;
> > +	crc->rst_msk = reset_mask;
> > +	crc->va = kcalloc(crc->cnt, sizeof(*crc->va), GFP_KERNEL);
> > +	if (!crc->va) {
> > +		DRM_ERROR("failed to allocate memory for crc\n");
> > +		crc->cnt = 0;
> > +	}
> > +}
> > +
> > +void mtk_drm_crc_read(struct mtk_drm_crc *crc, void __iomem *reg)
> > +{
> > +	if (!crc->cnt || !crc->ofs || !crc->va)
> > +		return;
> > +
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +	/* sync to see the most up-to-date copy of the DMA buffer */
> > +	dma_sync_single_for_cpu(crc->cmdq_client.chan->mbox->dev,
> > +				crc->pa, crc->cnt * sizeof(*crc->va),
> > +				DMA_FROM_DEVICE);
> > +#else
> > +	/* read crc with cpu for the platforms without cmdq */
> > +	{
> > +		u32 n;
> > +
> > +		for (n = 0; n < crc->cnt; n++)
> > +			crc->va[n] = readl(reg + crc->ofs[n]);
> > +
> > +		n = readl(reg + crc->rst_ofs);
> > +
> > +		/* pull reset bit */
> > +		n |= crc->rst_msk;
> > +		writel(n, reg + crc->rst_ofs);
> > +
> > +		/* release reset bit */
> > +		n &= ~crc->rst_msk;
> > +		writel(n, reg + crc->rst_ofs);
> > +	}
> > +#endif
> > +}
> > +
> > +void mtk_drm_crc_destroy(struct mtk_drm_crc *crc)
> > +{
> > +	if (!crc->cnt)
> > +		return;
> > +
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +	if (crc->pa) {
> > +		dma_unmap_single(crc->cmdq_client.chan->mbox->dev,
> > +				 crc->pa, crc->cnt * sizeof(*crc->va),
> > +				 DMA_TO_DEVICE);
> > +		crc->pa = 0;
> > +	}
> > +	if (crc->cmdq_client.chan) {
> > +		mtk_drm_cmdq_pkt_destroy(&crc->cmdq_handle);
> > +		mbox_free_channel(crc->cmdq_client.chan);
> > +		crc->cmdq_client.chan = NULL;
> > +	}
> > +#endif
> > +	kfree(crc->va);
> > +	crc->va = NULL;
> > +	crc->cnt = 0;
> > +}
> > +
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +void mtk_drm_crc_cmdq_create(struct device *dev, struct mtk_drm_crc *crc)
> > +{
> > +	int i;
> > +
> > +	if (!crc->cnt) {
> > +		dev_warn(dev, "%s: not support\n", __func__);
> > +		goto cleanup;
> > +	}
> > +
> > +	if (!crc->ofs) {
> > +		dev_warn(dev, "%s: not defined\n", __func__);
> > +		goto cleanup;
> > +	}
> > +
> > +	crc->cmdq_client.client.dev = dev;
> > +	crc->cmdq_client.client.tx_block = false;
> > +	crc->cmdq_client.client.knows_txdone = true;
> > +	crc->cmdq_client.client.rx_callback = NULL;
> > +	crc->cmdq_client.chan = mbox_request_channel(&crc->cmdq_client.client, 0);
> > +	if (IS_ERR(crc->cmdq_client.chan)) {
> > +		dev_warn(dev, "%s: failed to create mailbox client\n", __func__);
> > +		crc->cmdq_client.chan = NULL;
> > +		goto cleanup;
> > +	}
> > +
> > +	if (mtk_drm_cmdq_pkt_create(&crc->cmdq_client, &crc->cmdq_handle, PAGE_SIZE)) {
> > +		dev_warn(dev, "%s: failed to create cmdq packet\n", __func__);
> > +		goto cleanup;
> > +	}
> > +
> > +	if (!crc->va) {
> > +		dev_warn(dev, "%s: no memory\n", __func__);
> > +		goto cleanup;
> > +	}
> > +
> > +	/* map the entry to get a dma address for cmdq to store the crc */
> > +	crc->pa = dma_map_single(crc->cmdq_client.chan->mbox->dev,
> > +				 crc->va, crc->cnt * sizeof(*crc->va),
> > +				 DMA_FROM_DEVICE);
> > +
> > +	if (dma_mapping_error(crc->cmdq_client.chan->mbox->dev, crc->pa)) {
> > +		dev_err(dev, "%s: failed to map dma\n", __func__);
> > +		goto cleanup;
> > +	}
> > +
> > +	if (crc->cmdq_event)
> > +		cmdq_pkt_wfe(&crc->cmdq_handle, crc->cmdq_event, true);
> > +
> > +	for (i = 0; i < crc->cnt; i++) {
> > +		/* put crc to spr1 register */
> > +		cmdq_pkt_read_s(&crc->cmdq_handle, crc->cmdq_reg->subsys,
> > +				crc->cmdq_reg->offset + crc->ofs[i],
> > +				CMDQ_THR_SPR_IDX1);
> > +
> > +		/* copy spr1 register to physical address of the crc */
> > +		cmdq_pkt_assign(&crc->cmdq_handle, CMDQ_THR_SPR_IDX0,
> > +				CMDQ_ADDR_HIGH(crc->pa + i * sizeof(*crc->va)));
> > +		cmdq_pkt_write_s(&crc->cmdq_handle, CMDQ_THR_SPR_IDX0,
> > +				 CMDQ_ADDR_LOW(crc->pa + i * sizeof(*crc->va)),
> > +				 CMDQ_THR_SPR_IDX1);
> > +	}
> > +	/* reset crc */
> > +	mtk_ddp_write_mask(&crc->cmdq_handle, ~0, crc->cmdq_reg, 0,
> > +			   crc->rst_ofs, crc->rst_msk);
> > +
> > +	/* clear reset bit */
> > +	mtk_ddp_write_mask(&crc->cmdq_handle, 0, crc->cmdq_reg, 0,
> > +			   crc->rst_ofs, crc->rst_msk);
> > +
> > +	/* jump to head of the cmdq packet */
> > +	cmdq_pkt_jump(&crc->cmdq_handle, crc->cmdq_handle.pa_base);
> > +
> > +	return;
> > +cleanup:
> > +	mtk_drm_crc_destroy(crc);
> > +}
> > +
> > +void mtk_drm_crc_cmdq_start(struct mtk_drm_crc *crc)
> > +{
> > +	if (!crc->cmdq_client.chan)
> > +		return;
> > +
> > +	dma_sync_single_for_device(crc->cmdq_client.chan->mbox->dev,
> > +				   crc->cmdq_handle.pa_base,
> > +				   crc->cmdq_handle.cmd_buf_size,
> > +				   DMA_TO_DEVICE);
> > +	mbox_send_message(crc->cmdq_client.chan, &crc->cmdq_handle);
> > +	mbox_client_txdone(crc->cmdq_client.chan, 0);
> > +}
> > +
> > +void mtk_drm_crc_cmdq_stop(struct mtk_drm_crc *crc)
> > +{
> > +	if (!crc->cmdq_client.chan)
> > +		return;
> > +
> > +	mbox_flush(crc->cmdq_client.chan, 2000);
> > +}
> > +#endif
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> > index 3c224595fa714..0683ec4bc26f6 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> > @@ -15,6 +15,45 @@
> >  #define MTK_MAX_BPC	10
> >  #define MTK_MIN_BPC	3
> >  
> > +/**
> > + * struct mtk_drm_crc - crc related information
> > + * @ofs: register offset of crc
> > + * @rst_ofs: register offset of crc reset
> > + * @rst_msk: register mask of crc reset
> > + * @cnt: count of crc
> > + * @va: pointer to the start of crc array
> > + * @pa: physical address of the crc for gce to access
> > + * @cmdq_event: the event to trigger the cmdq
> > + * @cmdq_reg: address of the register that cmdq is going to access
> > + * @cmdq_client: handler to control cmdq (mbox channel, thread ...etc.)
> > + * @cmdq_handle: cmdq packet to store the commands
> > + */
> > +struct mtk_drm_crc {
> > +	const u32 *ofs;
> > +	u32 rst_ofs;
> > +	u32 rst_msk;
> > +	size_t cnt;
> > +	u32 *va;
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +	dma_addr_t pa;
> > +	u32 cmdq_event;
> > +	struct cmdq_client_reg *cmdq_reg;
> > +	struct cmdq_client cmdq_client;
> > +	struct cmdq_pkt cmdq_handle;
> > +#endif
> > +};
> > +
> > +void mtk_drm_crc_init(struct mtk_drm_crc *crc,
> > +		      const u32 *crc_offset_table, size_t crc_count,
> > +		      u32 reset_offset, u32 reset_mask);
> > +void mtk_drm_crc_read(struct mtk_drm_crc *crc, void __iomem *reg);
> > +void mtk_drm_crc_destroy(struct mtk_drm_crc *crc);
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +void mtk_drm_crc_cmdq_create(struct device *dev, struct mtk_drm_crc *crc);
> > +void mtk_drm_crc_cmdq_start(struct mtk_drm_crc *crc);
> > +void mtk_drm_crc_cmdq_stop(struct mtk_drm_crc *crc);
> > +#endif
> > +
> >  void mtk_drm_crtc_commit(struct drm_crtc *crtc);
> >  int mtk_drm_crtc_create(struct drm_device *drm_dev,
> >  			const unsigned int *path,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index 215b7234ff13c..231017470607e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -87,6 +87,9 @@ struct mtk_ddp_comp_funcs {
> >  	void (*remove)(struct device *dev, struct mtk_mutex *mutex);
> >  	unsigned int (*encoder_index)(struct device *dev);
> >  	enum drm_mode_status (*mode_valid)(struct device *dev, const struct drm_display_mode *mode);
> > +	size_t (*crc_cnt)(struct device *dev);
> > +	u32 *(*crc_entry)(struct device *dev);
> > +	void (*crc_read)(struct device *dev);
> >  };
> >  
> >  struct mtk_ddp_comp {
> > -- 
> > 2.18.0
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From fancer.lancer at gmail.com  Fri Feb 16 09:19:37 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Fri, 16 Feb 2024 20:19:37 +0300
Subject: [PATCH v9 1/4] serial: 8250: Add 8250 port clock update method
In-Reply-To: <Zc5oYJY6W_MCpwhN@smile.fi.intel.com>
References: <20200723003357.26897-1-Sergey.Semin@baikalelectronics.ru>
 <20200723003357.26897-2-Sergey.Semin@baikalelectronics.ru>
 <ZczD7KPbeRnY4CFc@black.fi.intel.com>
 <raryiklwhctwxcfj3ulbnjcl32owagiccmxpwzmszlh3vm343y@h2ehupm7uiga>
 <Zc5oYJY6W_MCpwhN@smile.fi.intel.com>
Message-ID: <ow5mvkxa4g7mub3faiytsij4cyaaralcbzyn675jny5355han7@azw65mhkpwjz>

On Thu, Feb 15, 2024 at 09:39:12PM +0200, Andy Shevchenko wrote:
> On Thu, Feb 15, 2024 at 10:32:18PM +0300, Serge Semin wrote:
> > On Wed, Feb 14, 2024 at 03:45:16PM +0200, Andy Shevchenko wrote:
> > > On Thu, Jul 23, 2020 at 03:33:54AM +0300, Serge Semin wrote:
> > > > Some platforms can be designed in a way so the UART port reference clock
> > > > might be asynchronously changed at some point. In Baikal-T1 SoC this may
> > > > happen due to the reference clock being shared between two UART ports, on
> > > > the Allwinner SoC the reference clock is derived from the CPU clock, so
> > > > any CPU frequency change should get to be known/reflected by/in the UART
> > > > controller as well. But it's not enough to just update the
> > > > uart_port->uartclk field of the corresponding UART port, the 8250
> > > > controller reference clock divisor should be altered so to preserve
> > > > current baud rate setting. All of these things is done in a coherent
> > > > way by calling the serial8250_update_uartclk() method provided in this
> > > > patch. Though note that it isn't supposed to be called from within the
> > > > UART port callbacks because the locks using to the protect the UART port
> > > > data are already taken in there.
> 
> ...
> 
> > > > +/*
> > > > + * Note in order to avoid the tty port mutex deadlock don't use the next method
> > > > + * within the uart port callbacks. Primarily it's supposed to be utilized to
> > > > + * handle a sudden reference clock rate change.
> > > > + */
> > > > +void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk)
> > > > +{
> > > > +	struct uart_8250_port *up = up_to_u8250p(port);
> > > > +	unsigned int baud, quot, frac = 0;
> > > > +	struct ktermios *termios;
> > > > +	unsigned long flags;
> > > > +
> > > > +	mutex_lock(&port->state->port.mutex);
> > > > +
> > > > +	if (port->uartclk == uartclk)
> > > > +		goto out_lock;
> > > > +
> > > > +	port->uartclk = uartclk;
> > > > +	termios = &port->state->port.tty->termios;
> > > > +
> > > > +	baud = serial8250_get_baud_rate(port, termios, NULL);
> > > > +	quot = serial8250_get_divisor(port, baud, &frac);
> > > > +
> > > > +	serial8250_rpm_get(up);
> > > > +	spin_lock_irqsave(&port->lock, flags);
> > > > +
> > > > +	uart_update_timeout(port, termios->c_cflag, baud);
> > > > +
> > > > +	serial8250_set_divisor(port, baud, quot, frac);
> > > > +	serial_port_out(port, UART_LCR, up->lcr);
> > > > +	serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
> > > > +
> > > > +	spin_unlock_irqrestore(&port->lock, flags);
> > > > +	serial8250_rpm_put(up);
> > > > +
> > > > +out_lock:
> > > > +	mutex_unlock(&port->state->port.mutex);
> > > 
> > 
> > > While looking for something else I have stumbled over this function.
> > > My Q is, since it has some duplications with
> > > serial8250_do_set_termios(), can we actually call the latter (or
> > > derevative that can be called in both) in the above code instead of
> > > duplicating some lines?
> > > 
> > > 	if (port UART clock has to be updated)
> > > 	  call (unlocked version of) serial8250_do_set_termios()
> > > 
> > > Serge, what do you think?
> > 
> > What an old thread you've digged out.)
> 
> Indeed :-)
> 
> > Well, AFAIR I didn't create a common baud-rate/clock-update method
> > because the baud-rate change was just a two stages action:
> > 1. calculate divisor+quot couple based on the new clock,
> > 2. update the divisor+quot (+ update the timeout).
> > The first stage didn't need to have the IRQsafe lock being held and
> > the runtime-PM being enabled, meanwhile the later one needed those.
> > So unless the nested locking or try-lock-based pattern is implemented
> > each stage required dedicated function introduced, which would have
> > been an overkill for that. But even if I got to implement the
> > try-lock-based solution with a single function containing both stages
> > I still couldn't avoid having the serial8250_get_baud_rate() and
> > serial8250_get_divisor() methods executed in the atomic context, which
> > isn't required for them and which would needlessly pro-long the CPU
> > executing with the IRQs disabled. As you well know it's better to
> > speed up the atomic context execution as much as possible. 
> > 
> > Secondly I didn't know much about the tty/serial subsystem internals
> > back then. So I was afraid to break some parts I didn't aware of if
> > the baud-rate/ref-clock change code had some implicit dependencies
> > from the surrounding code and vice-versa (like the LCR DLAB flag
> > state).
> > 
> > Finally frankly it didn't seem like that much worth bothering about.
> > Basically AFAICS there were only four methods which invocation I
> > would have needed to move to a separate function:
> > 
> > serial8250_get_baud_rate();
> > serial8250_get_divisor();
> > // spin-lock
> > uart_update_timeout(port, termios->c_cflag, baud);
> > serial8250_set_divisor(port, baud, quot, frac);
> > // spin-unlock
> > 
> > So I decided to take a simplest and safest path, and created a
> > dedicated method for the just the ref-clock updates case leaving the
> > baud-rate change task implemented in the framework of the standard
> > serial8250_do_set_termios() method.
> > 
> > 
> > Regarding doing vise-versa and calling the serial8250_do_set_termios()
> > method from serial8250_update_uartclk() instead. To be honest I didn't
> > consider that option. That might work though, but AFAICS the
> > serial8250_do_set_termios() function will do much more than it's
> > required in case if the ref-clock has changed.
> 

> My point here is that the idea behind clock change is most likely to be
> followed up by ->set_termios(). Why to do it differently if it's the case?

Not always. IIUC what you say is just a one path of the code executed
within the chain:

dw8250_set_termios()->dw8250_do_set_termios()->serial8250_do_set_termios()

But another code-path will be taken if the DW UART port
ref-clock is suddenly and asynchronously changed. In that case the
driver is notified by means of the dw8250_clk_notifier_cb() callback,
which doesn't need the entire set_termios() callback execution but
only what is defined in the serial8250_update_uartclk() method:

dw8250_clk_notifier_cb()
+-> worker:: dw8250_clk_work_cb()->serial8250_update_uartclk().

> And note, ->set_termios() can be called as many times as needed, so if nothing
> changes in between it's also fine. But this makes intention much clearer.
> Do you agree?

If what you suggest is to replace the serial8250_update_uartclk() body
with a direct uart_port::set_termios() invocation then I don't find it
being much clearer really. The serial8250_update_uartclk() is
currently specialized on doing one thing: adjusting the divider in
case of the UART-clock change. If instead the entire
serial8250_set_termios() method is called then for a reader it won't
be easy to understand what is really required for a 8250 serial port
to perceive the ref-clock change. But from the maintainability point
of view I guess that it might be safer to just call
serial8250_set_termios() indeed, since among the other things the
later method implies the divider update too. Thus the maintainer won't
need to support the two clock divider update implementations. From
that perspective I agree, directly calling serial8250_set_termios()
might be more suitable despite of it' doing more than required.

-Serge(y)

> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
> 


From cristian.marussi at arm.com  Fri Feb 16 09:21:02 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Fri, 16 Feb 2024 17:21:02 +0000
Subject: [PATCH] firmware: arm_scmi: avoid returning uninialized data
In-Reply-To: <20240216163259.1927967-1-arnd@kernel.org>
References: <20240216163259.1927967-1-arnd@kernel.org>
Message-ID: <Zc-ZfgVbAvAZVrPu@pluto>

On Fri, Feb 16, 2024 at 05:32:53PM +0100, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> Clang notices that there is a code path through
> scmi_powercap_notify_supported() that returns an
> undefined value:
> 

Hi Arnd,

> drivers/firmware/arm_scmi/powercap.c:821:11: error: variable 'supported' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
>   821 |         else if (evt_id == SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED)
>       |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/firmware/arm_scmi/powercap.c:824:9: note: uninitialized use occurs here
>   824 |         return supported;
>       |                ^~~~~~~~~
> drivers/firmware/arm_scmi/powercap.c:821:7: note: remove the 'if' if its condition is always true
>   821 |         else if (evt_id == SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED)
>       |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>   822 |                 supported = dom_info->notify_powercap_measurement_change;
> drivers/firmware/arm_scmi/powercap.c:811:16: note: initialize the variable 'supported' to silence this warning
>   811 |         bool supported;
>       |                       ^
> 
> Return 'false' here, which is probably what was intended.
> 
> Fixes: c92a75fe84ce ("firmware: arm_scmi: Implement Powercap .is_notify_supported callback")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

thanks for looking at this, this series that I've just posted is still
to be reviewd at all, so I would expect issues :D...BUT in this case I
dont think that the clang report is valid since, inside the culprit
function scmi_powercap_notify_supported(), a few lines before the
reported usage of unitialized data there is a check (@line 816) on the
'bounds' of evt_id itself

	if (evt_id >= ARRAY_SIZE(evt_2_cmd) || src_id >= pi->num_domains)
		return false;

so basically the mentioned if/else WILL be evaluated in some of its
branches for sure and supported wont be uninitialized.

Indeed, I removed from here (and from all the series) the explicit
initialization at definition time right before posting the series.

Having saidm that...maybe it is just brain-dead this approach of mine
since it is able to fool clang & friends...I would add bACK an explicit
initialization of supported all across this series in V2, if this
sounds good to you.

Thanks,
Cristian


> ---
>  drivers/firmware/arm_scmi/powercap.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/firmware/arm_scmi/powercap.c b/drivers/firmware/arm_scmi/powercap.c
> index aae91f47303e..8ee3be8776b0 100644
> --- a/drivers/firmware/arm_scmi/powercap.c
> +++ b/drivers/firmware/arm_scmi/powercap.c
> @@ -820,6 +820,8 @@ scmi_powercap_notify_supported(const struct scmi_protocol_handle *ph,
>  		supported = dom_info->notify_powercap_cap_change;
>  	else if (evt_id == SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED)
>  		supported = dom_info->notify_powercap_measurement_change;
> +	else
> +		supported = false;
>  
>  	return supported;
>  }
> -- 
> 2.39.2
> 


From arinc.unal at arinc9.com  Fri Feb 16 09:23:01 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Fri, 16 Feb 2024 20:23:01 +0300
Subject: [PATCH netnext 8/8] net: dsa: mt7530: simplify link operations
 and force link down on all ports
In-Reply-To: <Zc+ConfebmQdpCOF@shell.armlinux.org.uk>
References: <20240208-for-netnext-mt7530-improvements-3-v1-0-d7c1cfd502ca@arinc9.com>
 <20240208-for-netnext-mt7530-improvements-3-v1-8-d7c1cfd502ca@arinc9.com>
 <Zc+ConfebmQdpCOF@shell.armlinux.org.uk>
Message-ID: <c8393e61-7c44-4aca-acce-10b5f6b34fdd@arinc9.com>

On 16.02.2024 18:43, Russell King (Oracle) wrote:
> On Thu, Feb 08, 2024 at 08:51:36AM +0300, Ar?n? ?NAL via B4 Relay wrote:
>> From: Ar?n? ?NAL <arinc.unal at arinc9.com>
>>
>> Currently, the link operations for switch MACs are scattered across
>> port_enable, port_disable, phylink_mac_config, phylink_mac_link_up, and
>> phylink_mac_link_down.
>>
>> port_enable and port_disable clears the link settings. Move that to
>> mt7530_setup() and mt7531_setup_common() which set up the switches. This
>> way, the link settings are cleared on all ports at setup, and then only
>> once with phylink_mac_link_down() when a link goes down.
>>
>> Enable force mode at setup to apply the force part of the link settings.
>> This ensures that only active ports will have their link up.
> 
> I think we may have a different interpretation of what phylink's
> mac_link_down() and mac_link_up() are supposed to be doing here.
> Of course, you have read the documentation of these methods so are
> fully aware of what they're supposed to do. So you are aware that
> when inband mode is being used, forcing the link down may be
> counter-productive depending on how the hardware works.

No, I haven't read the documentation [1] until your response here. My patch
here doesn't touch mt753x_phylink_mac_link_down(), it is already the case
with the driver that falls short of not forcing link down when inband mode
is being used.

That said, what I explain on the patch log does not properly describe the
driver behaviour. This should explain it correctly:

Enable force mode at setup to apply the force part of the link settings.
This ensures that the ports that were never active will have their link
down.

I could, in the future, study this thoroughly to make the driver fully
conform to the documentation.

[1] https://docs.kernel.org/networking/kapi.html#phylink

Ar?n?


From catalin.marinas at arm.com  Fri Feb 16 09:35:34 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 16 Feb 2024 17:35:34 +0000
Subject: [PATCH v8 00/43] arm64: Add support for LPA2 and WXN at stage 1
In-Reply-To: <20240214122845.2033971-45-ardb+git@google.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
Message-ID: <170810439864.589251.1526990737780573683.b4-ty@arm.com>

On Wed, 14 Feb 2024 13:28:46 +0100, Ard Biesheuvel wrote:
> This v8 covers the remaining changes that implement support for LPA2 and
> WXN at stage 1, now that some of the prerequisites are in place.
> 
> v4: https://lore.kernel.org/r/20230912141549.278777-63-ardb at google.com/
> v5: https://lore.kernel.org/r/20231124101840.944737-41-ardb at google.com/
> v6: https://lore.kernel.org/r/20231129111555.3594833-43-ardb at google.com/
> v7: https://lore.kernel.org/r/20240123145258.1462979-52-ardb%2Bgit%40google.com/
> 
> [...]

I queued this series via the arm64 tree (for-next/stage1-lpa2). I tried
a couple of releases ago but for some reason my tests started failing at
it was very close to the merging window, so dropped. This time around,
if anything goes wrong, we have a bit of time to fix (it might as well
have been my test scripts and nothing to do with these patches).

The last patch introducing WXN has ABI implications but it's default
off. I think we should keep the patch as certain markets will likely
turn it on.

Surprisingly, there are no conflicts with Ryan's contpte series AFAICT
(I did a merge locally).

Thanks.

[01/43] arm64: kernel: Manage absolute relocations in code built under pi/
        https://git.kernel.org/arm64/c/48157aa39286
[02/43] arm64: kernel: Don't rely on objcopy to make code under pi/ __init
        https://git.kernel.org/arm64/c/a86aa72eb3b0
[03/43] arm64: head: move relocation handling to C code
        https://git.kernel.org/arm64/c/734958ef0b54
[04/43] arm64: idreg-override: Move to early mini C runtime
        https://git.kernel.org/arm64/c/e223a4491255
[05/43] arm64: kernel: Remove early fdt remap code
        https://git.kernel.org/arm64/c/9c4cd2a7d12c
[06/43] arm64: head: Clear BSS and the kernel page tables in one go
        https://git.kernel.org/arm64/c/aa99aad798a8
[07/43] arm64: Move feature overrides into the BSS section
        https://git.kernel.org/arm64/c/30687dec5ed5
[08/43] arm64: head: Run feature override detection before mapping the kernel
        https://git.kernel.org/arm64/c/dcfe969a6419
[09/43] arm64: head: move dynamic shadow call stack patching into early C runtime
        https://git.kernel.org/arm64/c/8a6e40e1f68e
[10/43] arm64: cpufeature: Add helper to test for CPU feature overrides
        https://git.kernel.org/arm64/c/35876f35f482
[11/43] arm64: kaslr: Use feature override instead of parsing the cmdline again
        https://git.kernel.org/arm64/c/af73b9a2dd39
[12/43] arm64: idreg-override: Create a pseudo feature for rodata=off
        https://git.kernel.org/arm64/c/9ddd9baa42a0
[13/43] arm64: Add helpers to probe local CPU for PAC and BTI support
        https://git.kernel.org/arm64/c/a669c6a49356
[14/43] arm64: head: allocate more pages for the kernel mapping
        https://git.kernel.org/arm64/c/8d47b8e5c74a
[15/43] arm64: head: move memstart_offset_seed handling to C code
        https://git.kernel.org/arm64/c/aa6a52b2470c
[16/43] arm64: mm: Make kaslr_requires_kpti() a static inline
        https://git.kernel.org/arm64/c/293d865f0af5
[17/43] arm64: mmu: Make __cpu_replace_ttbr1() out of line
        https://git.kernel.org/arm64/c/82ca151da7d5
[18/43] arm64: head: Move early kernel mapping routines into C code
        https://git.kernel.org/arm64/c/97a6f43bb049
[19/43] arm64: mm: Use 48-bit virtual addressing for the permanent ID map
        https://git.kernel.org/arm64/c/e6128a8e523c
[20/43] arm64: pgtable: Decouple PGDIR size macros from PGD/PUD/PMD levels
        https://git.kernel.org/arm64/c/34b98e55f684
[21/43] arm64: kernel: Create initial ID map from C code
        https://git.kernel.org/arm64/c/84b04d3e6bdb
[22/43] arm64: mm: avoid fixmap for early swapper_pg_dir updates
        https://git.kernel.org/arm64/c/567a70c181df
[23/43] arm64: mm: omit redundant remap of kernel image
        https://git.kernel.org/arm64/c/ba5b0333a847
[24/43] arm64: Revert "mm: provide idmap pointer to cpu_replace_ttbr1()"
        https://git.kernel.org/arm64/c/e0f92f0d1b51
[25/43] arm64: mm: Handle LVA support as a CPU feature
        https://git.kernel.org/arm64/c/9cce9c6c2c3b
[26/43] arm64: mm: Add feature override support for LVA
        https://git.kernel.org/arm64/c/68aec33f8f5a
[27/43] arm64: Avoid #define'ing PTE_MAYBE_NG to 0x0 for asm use
        https://git.kernel.org/arm64/c/60d043c10176
[28/43] arm64: Add ESR decoding for exceptions involving translation level -1
        https://git.kernel.org/arm64/c/7ac8d5b2423c
[29/43] arm64: mm: Wire up TCR.DS bit to PTE shareability fields
        https://git.kernel.org/arm64/c/db95ea787bd1
[30/43] arm64: mm: Add LPA2 support to phys<->pte conversion routines
        https://git.kernel.org/arm64/c/925a0eb48044
[31/43] arm64: mm: Add definitions to support 5 levels of paging
        https://git.kernel.org/arm64/c/a6bbf5d4d9d1
[32/43] arm64: mm: add LPA2 and 5 level paging support to G-to-nG conversion
        https://git.kernel.org/arm64/c/2b6c8f96cc47
[33/43] arm64: Enable LPA2 at boot if supported by the system
        https://git.kernel.org/arm64/c/9684ec186f8f
[34/43] arm64: mm: Add 5 level paging support to fixmap and swapper handling
        https://git.kernel.org/arm64/c/6ed8a3a094b4
[35/43] arm64: kasan: Reduce minimum shadow alignment and enable 5 level paging
        https://git.kernel.org/arm64/c/0383808e4d99
[36/43] arm64: mm: Add support for folding PUDs at runtime
        https://git.kernel.org/arm64/c/0dd4f60a2c76
[37/43] arm64: ptdump: Disregard unaddressable VA space
        https://git.kernel.org/arm64/c/16f22981b6d7
[38/43] arm64: ptdump: Deal with translation levels folded at runtime
        https://git.kernel.org/arm64/c/d40900fcb397
[39/43] arm64: kvm: avoid CONFIG_PGTABLE_LEVELS for runtime levels
        https://git.kernel.org/arm64/c/95e059b5db60
[40/43] arm64: Enable 52-bit virtual addressing for 4k and 16k granule configs
        https://git.kernel.org/arm64/c/352b0395b505
[41/43] arm64: defconfig: Enable LPA2 support
        https://git.kernel.org/arm64/c/5d101654226d
[42/43] mm: add arch hook to validate mmap() prot flags
        https://git.kernel.org/arm64/c/cb1a393c40ee
[43/43] arm64: mm: add support for WXN memory translation attribute
        https://git.kernel.org/arm64/c/50e3ed0f93f4

-- 
Catalin



From will at kernel.org  Fri Feb 16 09:39:22 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 16 Feb 2024 17:39:22 +0000
Subject: [PATCH v5 04/17] iommu/arm-smmu-v3: Move the STE generation for
 S1 and S2 domains into functions
In-Reply-To: <20240216171217.GA102281@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <4-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240216171217.GA102281@nvidia.com>
Message-ID: <20240216173921.GA2374@willie-the-truck>

On Fri, Feb 16, 2024 at 01:12:17PM -0400, Jason Gunthorpe wrote:
> On Tue, Feb 06, 2024 at 11:12:41AM -0400, Jason Gunthorpe wrote:
> > +static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
> > +					struct arm_smmu_master *master,
> > +					struct arm_smmu_domain *smmu_domain)
> > +{
> > +	struct arm_smmu_s2_cfg *s2_cfg = &smmu_domain->s2_cfg;
> > +
> > +	memset(target, 0, sizeof(*target));
> > +	target->data[0] = cpu_to_le64(
> > +		STRTAB_STE_0_V |
> > +		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS));
> > +
> > +	target->data[1] = cpu_to_le64(
> > +		FIELD_PREP(STRTAB_STE_1_EATS,
> > +			   master->ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0) |
> > +		FIELD_PREP(STRTAB_STE_1_SHCFG,
> > +			   STRTAB_STE_1_SHCFG_NON_SHARABLE));
> 
> Just so we are on the same page.. The above NON_SHARABLE is a mistake
> here since v1.
> 
> It is hard to follow arm_smmu_write_strtab_ent() so we all missed that
> the S2 ends up re-using the qword[1] that was installed by the
> bypass/abort STE that has to be in place prior to installing the S2.

Ah! I thought you were inheriting the existing behaviour, but yeah, it's
a straight-up bug which I think just makes life a little more difficult
than it needs to be. If we can keep SHCFG as "use incoming" in all
configurations, then I do think we can move to a per-qword rather than a
per-field approach, as mentioned in the other part of the thread. I'll
try to make some time next week to play with it.

Will


From jgg at nvidia.com  Fri Feb 16 09:58:21 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 16 Feb 2024 13:58:21 -0400
Subject: [PATCH v5 04/17] iommu/arm-smmu-v3: Move the STE generation for
 S1 and S2 domains into functions
In-Reply-To: <20240216173921.GA2374@willie-the-truck>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <4-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240216171217.GA102281@nvidia.com>
 <20240216173921.GA2374@willie-the-truck>
Message-ID: <20240216175821.GF13330@nvidia.com>

On Fri, Feb 16, 2024 at 05:39:22PM +0000, Will Deacon wrote:
> On Fri, Feb 16, 2024 at 01:12:17PM -0400, Jason Gunthorpe wrote:
> > On Tue, Feb 06, 2024 at 11:12:41AM -0400, Jason Gunthorpe wrote:
> > > +static void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
> > > +					struct arm_smmu_master *master,
> > > +					struct arm_smmu_domain *smmu_domain)
> > > +{
> > > +	struct arm_smmu_s2_cfg *s2_cfg = &smmu_domain->s2_cfg;
> > > +
> > > +	memset(target, 0, sizeof(*target));
> > > +	target->data[0] = cpu_to_le64(
> > > +		STRTAB_STE_0_V |
> > > +		FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S2_TRANS));
> > > +
> > > +	target->data[1] = cpu_to_le64(
> > > +		FIELD_PREP(STRTAB_STE_1_EATS,
> > > +			   master->ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0) |
> > > +		FIELD_PREP(STRTAB_STE_1_SHCFG,
> > > +			   STRTAB_STE_1_SHCFG_NON_SHARABLE));
> > 
> > Just so we are on the same page.. The above NON_SHARABLE is a mistake
> > here since v1.
> > 
> > It is hard to follow arm_smmu_write_strtab_ent() so we all missed that
> > the S2 ends up re-using the qword[1] that was installed by the
> > bypass/abort STE that has to be in place prior to installing the S2.
> 
> Ah! I thought you were inheriting the existing behaviour, but yeah,

Yeah, so did I..

> it's a straight-up bug which I think just makes life a little more
> difficult than it needs to be. If we can keep SHCFG as "use
> incoming" in all configurations, then I do think we can move to a
> per-qword rather than a per-field approach, as mentioned in the
> other part of the thread. I'll try to make some time next week to
> play with it.

I'm sure you can make per-qword work. I think it will be worse code
though because doing so will have to compromise some of the
underpinning logical principles:

 - Used bits reflects actual HW behavior and flows from the
   spec's IGNORED/etc language
 - Make STE functions set the bits that the HW uses and no extra bits
 - The make STE functions create a complete STE

I already tried the naive version where none of the above are
compromised and it does not work. Someone else may have an idea. IMHO
this is really not a valuable avenue to use all of our limited time
on.

I'm getting the existings remarks typed in, it is already turning into
some work, but if you feel strongly please come next week with exactly
you will accept and I will ensure whatever it is gets done if you will
commit to merge it. Even if we have to toss out Michael's version too.

I can always bring back this version for some future shared code
thing.

Thanks,
Jason


From conor at kernel.org  Fri Feb 16 10:04:07 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 16 Feb 2024 18:04:07 +0000
Subject: [PATCH 1/2] dt-bindings: arm64: mediatek: add Kontron
 3.5"-SBC-i1200
In-Reply-To: <20240216163406.1050929-1-mwalle@kernel.org>
References: <20240216163406.1050929-1-mwalle@kernel.org>
Message-ID: <20240216-unsettled-polygraph-e55f7f2dba90@spud>

On Fri, Feb 16, 2024 at 05:34:05PM +0100, Michael Walle wrote:
> Add the compatible string for the Kontron 3.5"-SBC-i1200 single board
> computer.
> 
> Signed-off-by: Michael Walle <mwalle at kernel.org>
> ---
>  Documentation/devicetree/bindings/arm/mediatek.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
> index 09f9ffd3ff7b..32896f91ea38 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
> @@ -357,6 +357,12 @@ properties:
>                - radxa,nio-12l
>            - const: mediatek,mt8395
>            - const: mediatek,mt8195
> +      - description: Kontron 3.5"-SBC-i1200
> +        items:
> +          - enum:
> +              - kontron,3-5-sbc-i1200

This is a specific SBC, why the enum?

> +          - const: mediatek,mt8395
> +          - const: mediatek,mt8195
>        - items:
>            - enum:
>                - mediatek,mt8516-pumpkin
> -- 
> 2.39.2
> 
-------------- 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/20240216/315cfb6d/attachment.sig>

From ardb at kernel.org  Fri Feb 16 10:23:18 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 16 Feb 2024 19:23:18 +0100
Subject: [PATCH v8 00/43] arm64: Add support for LPA2 and WXN at stage 1
In-Reply-To: <170810439864.589251.1526990737780573683.b4-ty@arm.com>
References: <20240214122845.2033971-45-ardb+git@google.com> <170810439864.589251.1526990737780573683.b4-ty@arm.com>
Message-ID: <CAMj1kXEupLLE+xZaGygAJ0pOG8dm9Ov_7efWfK4af5JPgfZZfg@mail.gmail.com>

On Fri, 16 Feb 2024 at 18:35, Catalin Marinas <catalin.marinas at arm.com> wrote:
>
> On Wed, 14 Feb 2024 13:28:46 +0100, Ard Biesheuvel wrote:
> > This v8 covers the remaining changes that implement support for LPA2 and
> > WXN at stage 1, now that some of the prerequisites are in place.
> >
> > v4: https://lore.kernel.org/r/20230912141549.278777-63-ardb at google.com/
> > v5: https://lore.kernel.org/r/20231124101840.944737-41-ardb at google.com/
> > v6: https://lore.kernel.org/r/20231129111555.3594833-43-ardb at google.com/
> > v7: https://lore.kernel.org/r/20240123145258.1462979-52-ardb%2Bgit%40google.com/
> >
> > [...]
>
> I queued this series via the arm64 tree (for-next/stage1-lpa2). I tried
> a couple of releases ago but for some reason my tests started failing at
> it was very close to the merging window, so dropped. This time around,
> if anything goes wrong, we have a bit of time to fix (it might as well
> have been my test scripts and nothing to do with these patches).
>
> The last patch introducing WXN has ABI implications but it's default
> off. I think we should keep the patch as certain markets will likely
> turn it on.
>
> Surprisingly, there are no conflicts with Ryan's contpte series AFAICT
> (I did a merge locally).
>

No *lexical* conflicts, right? :-)

I built for-next/core with 16k pages/52-bits, and ended up with the
splat below. Unfortunately, it is intermittent, and I haven't been
able to reproduce it, so I have no idea whether it is my code, Ryan's
code or an inadvertent interaction between the two. (Or perhaps some
other code in the tree)

I did build with WXN enabled in this case, but it seems unlikely that
that plays a role here.






[    0.392768] Unable to handle kernel write to read-only memory at
virtual address ffffe6d037873360
[    0.393314] Mem abort info:
[    0.393480]   ESR = 0x000000009600004f
[    0.393702]   EC = 0x25: DABT (current EL), IL = 32 bits
[    0.394089]   SET = 0, FnV = 0
[    0.394272]   EA = 0, S1PTW = 0
[    0.394458]   FSC = 0x0f: level 3 permission fault
[    0.394741] Data abort info:
[    0.394915]   ISV = 0, ISS = 0x0000004f, ISS2 = 0x00000000
[    0.395239]   CM = 0, WnR = 1, TnD = 0, TagAccess = 0
[    0.395602]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[    0.396152] swapper pgtable: 16k pages, 47-bit VAs, pgdp=00000000c8870000
[    0.396844] [ffffe6d037873360] pgd=0000000000000000,
p4d=0000000000000000, pud=10000000c9034003, pmd=10000000c903c003,
pte=00600000c8870783
[    0.398172] Internal error: Oops: 000000009600004f [#1] PREEMPT SMP
[    0.398833] Modules linked in:
[    0.399147] CPU: 3 PID: 1 Comm: systemd Not tainted 6.8.0-rc3+ #28
[    0.399774] Hardware name: QEMU KVM Virtual Machine, BIOS unknown 2/2/2022
[    0.400464] pstate: 61400005 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
[    0.401176] pc : __pmd_alloc+0x164/0x1f4
[    0.401579] lr : __pmd_alloc+0xac/0x1f4
[    0.402117] sp : ffffc0008007b960
[    0.402672] x29: ffffc0008007b960 x28: ffffe6cfe1844000 x27: 0000000000002cc2
[    0.403833] x26: 0000000002000000 x25: ffffe6d037873360 x24: ffffe6cfe17f8000
[    0.404990] x23: ffff8ebf40fd4000 x22: ffffe6d037b83c80 x21: ffffe6d037b83c80
[    0.406177] x20: ffffe6d037873360 x19: ffffe6d037b83d1c x18: 000000000000cda8
[    0.407381] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
[    0.408455] x14: 0000000000001b00 x13: dead000000000122 x12: 0000000000000000
[    0.409179] x11: 0000000000000015 x10: 1000000000000003 x9 : 1000000000000003
[    0.409939] x8 : 1000000100fd4003 x7 : 0000000000000000 x6 : ffffc0008007ba50
[    0.410670] x5 : ffff8ebf7f9bb9e0 x4 : ffff8ebf7f9bb9c0 x3 : 0000000000000901
[    0.411394] x2 : 0000000000000001 x1 : 0000000000000000 x0 : ffffe6d037b83d1c
[    0.412204] Call trace:
[    0.412426]  __pmd_alloc+0x164/0x1f4
[    0.412736]  vmap_pages_pud_range+0x160/0x244
[    0.413122]  __vmap_pages_range_noflush+0xb0/0x218
[    0.413531]  __vmalloc_area_node+0x4b8/0x5c0
[    0.413897]  __vmalloc_node_range+0x124/0x218
[    0.414276]  module_alloc+0x118/0x170
[    0.414589]  load_module+0xd5c/0x133c
[    0.414898]  __arm64_sys_finit_module+0x21c/0x2c0
[    0.415292]  invoke_syscall+0x48/0xd8
[    0.415623]  do_el0_svc+0x7c/0xa8
[    0.415937]  el0_svc+0x34/0x78
[    0.416210]  el0t_64_sync_handler+0x84/0xfc
[    0.416589]  el0t_64_sync+0x190/0x194
[    0.416910] Code: 9278a508 aa090108 f9000fa8 f9400fa8 (f9000288)
[    0.417432] ---[ end trace 0000000000000000 ]---
[    0.417861] note: systemd[1] exited with preempt_count 1
[    0.418237] Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0000000b
[    0.418765] SMP: stopping secondary CPUs
[    0.419061] Kernel Offset: 0x26cfb5c90000 from 0xffffc00080000000
[    0.419517] PHYS_OFFSET: 0xfff07141c0000000
[    0.419820] CPU features: 0x0,00000000,a0044d4a,33ce7727
[    0.420214] Memory Limit: none
[    0.420439] ---[ end Kernel panic - not syncing: Attempted to kill
init! exitcode=0x0000000b ]---


From fancer.lancer at gmail.com  Fri Feb 16 10:24:01 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Fri, 16 Feb 2024 21:24:01 +0300
Subject: [PATCH] net: stmmac: mmc_core: Assign, don't add interrupt
 registers
In-Reply-To: <61bdd802-abe4-4544-8e48-9493a6bb99c8@gmail.com>
References: <20240216-stmmac_stats-v1-1-7065fa4613f8@axis.com>
 <61bdd802-abe4-4544-8e48-9493a6bb99c8@gmail.com>
Message-ID: <53fctveh4pl3c5wys37c2wcpbsxr7tggw3d3y5eudgrbvr2vdl@fbqc2meg5yv3>

On Fri, Feb 16, 2024 at 09:13:51AM -0800, Florian Fainelli wrote:
> On 2/16/24 07:24, Jesper Nilsson wrote:
> > The MMC IPC interrupt status and interrupt mask registers are of
> > little use as Ethernet statistics, but incrementing counters
> > based on the current interrupt and interrupt mask registers
> > makes them worse than useless.
> > 
> > For example, if the interrupt mask is set to 0x08420842,
> > the current code will increment by that amount each iteration,
> > leading to the following sequence of nonsense:
> > 
> > mmc_rx_ipc_intr_mask: 969816526
> > mmc_rx_ipc_intr_mask: 1108361744
> > 
> > Change the increment to a straight assignment to make the
> > statistics at least nominally useful.
> > 
> > Signed-off-by: Jesper Nilsson <jesper.nilsson at axis.com>
> > ---
> >   drivers/net/ethernet/stmicro/stmmac/mmc_core.c | 4 ++--
> >   1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
> > index 6a7c1d325c46..6051a22b3cec 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
> > @@ -280,8 +280,8 @@ static void dwmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc)
> >   	mmc->mmc_rx_vlan_frames_gb += readl(mmcaddr + MMC_RX_VLAN_FRAMES_GB);
> >   	mmc->mmc_rx_watchdog_error += readl(mmcaddr + MMC_RX_WATCHDOG_ERROR);
> >   	/* IPC */
> > -	mmc->mmc_rx_ipc_intr_mask += readl(mmcaddr + MMC_RX_IPC_INTR_MASK);
> > -	mmc->mmc_rx_ipc_intr += readl(mmcaddr + MMC_RX_IPC_INTR);
> > +	mmc->mmc_rx_ipc_intr_mask = readl(mmcaddr + MMC_RX_IPC_INTR_MASK);
> > +	mmc->mmc_rx_ipc_intr = readl(mmcaddr + MMC_RX_IPC_INTR);
> 

> So in premise I agree with the patch, that incrementing those is not the
> right way to go about them. However these registers are currently provided
> as part of the statistics set, but they should instead be accessed via the
> register dumping method.
> 
> In either case you will get at best a snapshot of those two registers at any
> given time and I suppose this can help diagnose a stuck RX condition, but
> not much more than that.

Could you please clarify why do those CSRs state need to be exposed in
the statistics anyway? Who would need such information really?
Wouldn't that be better to just drop the
stmmac_counters::{mmc_rx_ipc_intr_mask,mmc_rx_ipc_intr}
fields? Is it because of the statistics nodes are a kind of kernel
ABI? Even in that case I don't see much reason to support something
that has been absolutely useless so far seeing the nodes currently
returning basically some random values.

-Serge(y)

> -- 
> Florian
> 
> 


From fancer.lancer at gmail.com  Fri Feb 16 10:39:57 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Fri, 16 Feb 2024 21:39:57 +0300
Subject: [PATCH net v2] net: stmmac: Fix incorrect dereference in
 interrupt handlers
In-Reply-To: <20240214092718.331891-1-p.sakharov@ispras.ru>
References: <20240206150704.GD1104779@kernel.org>
 <20240214092718.331891-1-p.sakharov@ispras.ru>
Message-ID: <52l2oudptsknq7tkorvz6o3h2t2gzstkk34oorks3eul5k22br@kqm674m5cwyy>

On Wed, Feb 14, 2024 at 12:27:17PM +0300, Pavel Sakharov wrote:
> If 'dev' or 'data' is NULL, the 'priv' variable has an incorrect address
> when dereferencing calling netdev_err().
> 
> Since we get as 'dev_id' or 'data' what was passed as the 'dev' argument
> to request_irq() during interrupt initialization (that is, the net_device
> and rx/tx queue pointers initialized at the time of the call) and since
> there are usually no checks for the 'dev_id' argument in such handlers
> in other drivers, remove these checks from the handlers in stmmac driver.
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.

LGTM. Thanks!

Reviewed-by: Serge Semin <fancer.lancer at gmail.com>

-Serge(y)

> 
> Fixes: 8532f613bc78 ("net: stmmac: introduce MSI Interrupt routines for mac, safety, RX & TX")
> Signed-off-by: Pavel Sakharov <p.sakharov at ispras.ru>
> ---
> v2: Drop the second argument checks in the handlers as suggested by Serge Semin <fancer.lancer at gmail.com>.
> 
>  .../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 -------------------
>  1 file changed, 20 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 75d029704503..e80d77bd9f1f 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -6059,11 +6059,6 @@ static irqreturn_t stmmac_mac_interrupt(int irq, void *dev_id)
>  	struct net_device *dev = (struct net_device *)dev_id;
>  	struct stmmac_priv *priv = netdev_priv(dev);
>  
> -	if (unlikely(!dev)) {
> -		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
> -		return IRQ_NONE;
> -	}
> -
>  	/* Check if adapter is up */
>  	if (test_bit(STMMAC_DOWN, &priv->state))
>  		return IRQ_HANDLED;
> @@ -6079,11 +6074,6 @@ static irqreturn_t stmmac_safety_interrupt(int irq, void *dev_id)
>  	struct net_device *dev = (struct net_device *)dev_id;
>  	struct stmmac_priv *priv = netdev_priv(dev);
>  
> -	if (unlikely(!dev)) {
> -		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
> -		return IRQ_NONE;
> -	}
> -
>  	/* Check if adapter is up */
>  	if (test_bit(STMMAC_DOWN, &priv->state))
>  		return IRQ_HANDLED;
> @@ -6105,11 +6095,6 @@ static irqreturn_t stmmac_msi_intr_tx(int irq, void *data)
>  	dma_conf = container_of(tx_q, struct stmmac_dma_conf, tx_queue[chan]);
>  	priv = container_of(dma_conf, struct stmmac_priv, dma_conf);
>  
> -	if (unlikely(!data)) {
> -		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
> -		return IRQ_NONE;
> -	}
> -
>  	/* Check if adapter is up */
>  	if (test_bit(STMMAC_DOWN, &priv->state))
>  		return IRQ_HANDLED;
> @@ -6136,11 +6121,6 @@ static irqreturn_t stmmac_msi_intr_rx(int irq, void *data)
>  	dma_conf = container_of(rx_q, struct stmmac_dma_conf, rx_queue[chan]);
>  	priv = container_of(dma_conf, struct stmmac_priv, dma_conf);
>  
> -	if (unlikely(!data)) {
> -		netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__);
> -		return IRQ_NONE;
> -	}
> -
>  	/* Check if adapter is up */
>  	if (test_bit(STMMAC_DOWN, &priv->state))
>  		return IRQ_HANDLED;
> -- 
> 2.43.0
> 


From tglx at linutronix.de  Fri Feb 16 10:40:47 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 16 Feb 2024 19:40:47 +0100
Subject: [PATCH v12 18/25] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <20240127161753.114685-19-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-19-apatel@ventanamicro.com>
Message-ID: <87h6i8ckwg.ffs@tglx>

On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> +
> +#ifdef CONFIG_SMP
> +static irqreturn_t imsic_local_sync_handler(int irq, void *data)
> +{
> +	imsic_local_sync();
> +	return IRQ_HANDLED;
> +}
> +
> +static void imsic_ipi_send(unsigned int cpu)
> +{
> +	struct imsic_local_config *local =
> +				per_cpu_ptr(imsic->global.local, cpu);

Let it stick out. We switched to line length 100 quite some time
ago. Applies to the rest of the series too.

> +	writel_relaxed(IMSIC_IPI_ID, local->msi_va);
> +}
> +
> +static void imsic_ipi_starting_cpu(void)
> +{
> +	/* Enable IPIs for current CPU. */
> +	__imsic_id_set_enable(IMSIC_IPI_ID);
> +
> +	/* Enable virtual IPI used for IMSIC ID synchronization */
> +	enable_percpu_irq(imsic->ipi_virq, 0);
> +}
> +
> +static void imsic_ipi_dying_cpu(void)
> +{
> +	/*
> +	 * Disable virtual IPI used for IMSIC ID synchronization so
> +	 * that we don't receive ID synchronization requests.
> +	 */
> +	disable_percpu_irq(imsic->ipi_virq);

Shouldn't this disable the hardware too, i.e.

          __imsic_id_clear_enable()

?

> +}
> +
> +static int __init imsic_ipi_domain_init(void)
> +{
> +	int virq;
> +
> +	/* Create IMSIC IPI multiplexing */
> +	virq = ipi_mux_create(IMSIC_NR_IPI, imsic_ipi_send);
> +	if (virq <= 0)
> +		return (virq < 0) ? virq : -ENOMEM;
> +	imsic->ipi_virq = virq;
> +
> +	/* First vIRQ is used for IMSIC ID synchronization */
> +	virq = request_percpu_irq(imsic->ipi_virq, imsic_local_sync_handler,
> +				  "riscv-imsic-lsync", imsic->global.local);
> +	if (virq)
> +		return virq;

Please use a separate 'ret' variable. I had to read this 3 times to make
sense of it.

> +	irq_set_status_flags(imsic->ipi_virq, IRQ_HIDDEN);
> +	imsic->ipi_lsync_desc = irq_to_desc(imsic->ipi_virq);

What's so special about this particular IPI that it can't be handled
like all the other IPIs?

> +static int __init imsic_early_probe(struct fwnode_handle *fwnode)
> +{
> +	int rc;
> +	struct irq_domain *domain;

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations

> +
> +	/* Find parent domain and register chained handler */
> +	domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(),
> +					  DOMAIN_BUS_ANY);
> +	if (!domain) {
> +		pr_err("%pfwP: Failed to find INTC domain\n", fwnode);
> +		return -ENOENT;
> +	}
> +	imsic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
> +	if (!imsic_parent_irq) {
> +		pr_err("%pfwP: Failed to create INTC mapping\n", fwnode);
> +		return -ENOENT;
> +	}
> +	irq_set_chained_handler(imsic_parent_irq, imsic_handle_irq);
> +
> +	/* Initialize IPI domain */
> +	rc = imsic_ipi_domain_init();
> +	if (rc) {
> +		pr_err("%pfwP: Failed to initialize IPI domain\n", fwnode);
> +		return rc;

Leaves the chained handler around and enabled.

> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> +
> +#define imsic_csr_write(__c, __v)		\
> +do {						\
> +	csr_write(CSR_ISELECT, __c);		\
> +	csr_write(CSR_IREG, __v);		\
> +} while (0)

Any reason why these macros can't be inlines?

> +const struct imsic_global_config *imsic_get_global_config(void)
> +{
> +	return imsic ? &imsic->global : NULL;
> +}
> +EXPORT_SYMBOL_GPL(imsic_get_global_config);

Why is this exported?

> +#define __imsic_id_read_clear_enabled(__id)		\
> +	__imsic_eix_read_clear((__id), false)
> +#define __imsic_id_read_clear_pending(__id)		\
> +	__imsic_eix_read_clear((__id), true)

Please use inlines.

> +void __imsic_eix_update(unsigned long base_id,
> +			unsigned long num_id, bool pend, bool val)
> +{
> +	unsigned long i, isel, ireg;
> +	unsigned long id = base_id, last_id = base_id + num_id;
> +
> +	while (id < last_id) {
> +		isel = id / BITS_PER_LONG;
> +		isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
> +		isel += (pend) ? IMSIC_EIP0 : IMSIC_EIE0;
> +
> +		ireg = 0;
> +		for (i = id & (__riscv_xlen - 1);
> +		     (id < last_id) && (i < __riscv_xlen); i++) {
> +			ireg |= BIT(i);
> +			id++;
> +		}

This lacks a comment what this is doing.

> +
> +		/*
> +		 * The IMSIC EIEx and EIPx registers are indirectly
> +		 * accessed via using ISELECT and IREG CSRs so we
> +		 * need to access these CSRs without getting preempted.
> +		 *
> +		 * All existing users of this function call this
> +		 * function with local IRQs disabled so we don't
> +		 * need to do anything special here.
> +		 */
> +		if (val)
> +			imsic_csr_set(isel, ireg);
> +		else
> +			imsic_csr_clear(isel, ireg);
> +	}
> +}
> +
> +void imsic_local_sync(void)
> +{
> +	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> +	struct imsic_local_config *mlocal;
> +	struct imsic_vector *mvec;
> +	unsigned long flags;
> +	int i;
> +
> +	raw_spin_lock_irqsave(&lpriv->ids_lock, flags);
> +	for (i = 1; i <= imsic->global.nr_ids; i++) {
> +		if (i == IMSIC_IPI_ID)
> +			continue;
> +
> +		if (test_bit(i, lpriv->ids_enabled_bitmap))
> +			__imsic_id_set_enable(i);
> +		else
> +			__imsic_id_clear_enable(i);
> +
> +		mvec = lpriv->ids_move[i];
> +		lpriv->ids_move[i] = NULL;
> +		if (mvec) {
> +			if (__imsic_id_read_clear_pending(i)) {
> +				mlocal = per_cpu_ptr(imsic->global.local,
> +						     mvec->cpu);
> +				writel_relaxed(mvec->local_id, mlocal->msi_va);
> +			}
> +
> +			imsic_vector_free(&lpriv->vectors[i]);
> +		}

Again an uncommented piece of magic which you will have forgotten what
it does 3 month down the road :)

> +
> +	}
> +	raw_spin_unlock_irqrestore(&lpriv->ids_lock, flags);
> +}
> +
> +void imsic_local_delivery(bool enable)
> +{
> +	if (enable) {
> +		imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
> +		imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
> +		return;
> +	}
> +
> +	imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
> +	imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
> +}
> +
> +#ifdef CONFIG_SMP
> +static void imsic_remote_sync(unsigned int cpu)
> +{
> +	/*
> +	 * We simply inject ID synchronization IPI to a target CPU
> +	 * if it is not same as the current CPU. The ipi_send_mask()
> +	 * implementation of IPI mux will inject ID synchronization
> +	 * IPI only for CPUs that have enabled it so offline CPUs
> +	 * won't receive IPI. An offline CPU will unconditionally
> +	 * synchronize IDs through imsic_starting_cpu() when the
> +	 * CPU is brought up.
> +	 */
> +	if (cpu_online(cpu)) {
> +		if (cpu != smp_processor_id())
> +			__ipi_send_mask(imsic->ipi_lsync_desc, cpumask_of(cpu));

Still wondering why this can't use the regular API. There might be a
reason, but then it wants to be documented.

> +		else
> +			imsic_local_sync();
> +	}
> +}
> +#else
> +static inline void imsic_remote_sync(unsigned int cpu)
> +{
> +	imsic_local_sync();
> +}
> +#endif
> +
> +void imsic_vector_mask(struct imsic_vector *vec)
> +{
> +	struct imsic_local_priv *lpriv;
> +	unsigned long flags;
> +
> +	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> +	if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> +		return;
> +
> +	raw_spin_lock_irqsave(&lpriv->ids_lock, flags);

AFAICT, this is used from an irqchip callback:

static void imsic_irq_mask(struct irq_data *d)
{
        imsic_vector_mask(irq_data_get_irq_chip_data(d));
}

So no need to use irqsave() here. Those callbacks run always with
interrupts disabled when called from the core.

> +void imsic_vector_move(struct imsic_vector *old_vec,
> +			struct imsic_vector *new_vec)
> +{
> +	struct imsic_local_priv *old_lpriv, *new_lpriv;
> +	unsigned long flags, flags1;
> +
> +	if (WARN_ON(old_vec->cpu == new_vec->cpu))
> +		return;
> +
> +	old_lpriv = per_cpu_ptr(imsic->lpriv, old_vec->cpu);
> +	if (WARN_ON(&old_lpriv->vectors[old_vec->local_id] != old_vec))
> +		return;
> +
> +	new_lpriv = per_cpu_ptr(imsic->lpriv, new_vec->cpu);
> +	if (WARN_ON(&new_lpriv->vectors[new_vec->local_id] != new_vec))
> +		return;
> +
> +	raw_spin_lock_irqsave(&old_lpriv->ids_lock, flags);
> +	raw_spin_lock_irqsave(&new_lpriv->ids_lock, flags1);

Lockdep should yell at you for this, rightfully so. And not only because
of the missing nested() annotation.

Assume there are two CPUs setting affinity for two different interrupts.

CPU0 moves an interrupt to CPU1 and CPU1 moves another interrupt to
CPU0. The resulting lock order is:

CPU0                     CPU1
lock(lpriv[CPU0]);       lock(lpriv[CPU1]);
lock(lpriv[CPU1]);       lock(lpriv[CPU0]);

a classic ABBA deadlock.

You need to take those locks always in the same order. Look at
double_raw_lock() in kernel/sched/sched.h.

> +	/* Unmask the new vector entry */
> +	if (test_bit(old_vec->local_id, old_lpriv->ids_enabled_bitmap))
> +		bitmap_set(new_lpriv->ids_enabled_bitmap,
> +			   new_vec->local_id, 1);

Either make that one line or please add brackets. See:

  https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#bracket-rules

> +static int __init imsic_local_init(void)
> +{
> +	struct imsic_global_config *global = &imsic->global;
> +	struct imsic_local_priv *lpriv;
> +	struct imsic_vector *vec;
> +	int cpu, i;
> +
> +	/* Allocate per-CPU private state */
> +	imsic->lpriv = alloc_percpu(typeof(*(imsic->lpriv)));
> +	if (!imsic->lpriv)
> +		return -ENOMEM;
> +
> +	/* Setup per-CPU private state */
> +	for_each_possible_cpu(cpu) {
> +		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> +
> +		raw_spin_lock_init(&lpriv->ids_lock);
> +
> +		/* Allocate enabled bitmap */
> +		lpriv->ids_enabled_bitmap = bitmap_zalloc(global->nr_ids + 1,
> +							  GFP_KERNEL);
> +		if (!lpriv->ids_enabled_bitmap) {
> +			imsic_local_cleanup();
> +			return -ENOMEM;
> +		}
> +
> +		/* Allocate move array */
> +		lpriv->ids_move = kcalloc(global->nr_ids + 1,
> +					sizeof(*lpriv->ids_move), GFP_KERNEL);
> +		if (!lpriv->ids_move) {
> +			imsic_local_cleanup();
> +			return -ENOMEM;
> +		}
> +
> +		/* Allocate vector array */
> +		lpriv->vectors = kcalloc(global->nr_ids + 1,
> +					 sizeof(*lpriv->vectors), GFP_KERNEL);
> +		if (!lpriv->vectors) {
> +			imsic_local_cleanup();
> +			return -ENOMEM;

Third instance of the same pattern. goto cleanup; perhaps?

> +struct imsic_vector *imsic_vector_alloc(unsigned int hwirq,
> +					const struct cpumask *mask)
> +{
> +	struct imsic_vector *vec = NULL;
> +	struct imsic_local_priv *lpriv;
> +	unsigned long flags;
> +	unsigned int cpu;
> +	int local_id;
> +
> +	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> +	local_id = irq_matrix_alloc(imsic->matrix, mask, false, &cpu);
> +	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> +	if (local_id < 0)
> +		return NULL;
> +
> +	lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> +	vec = &lpriv->vectors[local_id];
> +	vec->hwirq = hwirq;
> +
> +	return vec;
> +}

...

> +int imsic_hwirq_alloc(void)
> +{
> +	int ret;
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&imsic->hwirqs_lock, flags);
> +	ret = bitmap_find_free_region(imsic->hwirqs_used_bitmap,
> +				      imsic->nr_hwirqs, 0);
> +	raw_spin_unlock_irqrestore(&imsic->hwirqs_lock, flags);
> +
> +	return ret;
> +}

This part is just to create a unique hwirq number, right?

> +
> +	/* Find number of guest index bits in MSI address */
> +	rc = of_property_read_u32(to_of_node(fwnode),
> +				  "riscv,guest-index-bits",
> +				  &global->guest_index_bits);
> +	if (rc)
> +		global->guest_index_bits = 0;

So here you get the index bits, but then 50 lines further down you do
sanity checking. Wouldn't it make sense to do that right here?

Same for the other bits.

> +
> +/*
> + * The IMSIC driver uses 1 IPI for ID synchronization and
> + * arch/riscv/kernel/smp.c require 6 IPIs so we fix the
> + * total number of IPIs to 8.
> + */
> +#define IMSIC_IPI_ID				1
> +#define IMSIC_NR_IPI				8
> +
> +struct imsic_vector {
> +	/* Fixed details of the vector */
> +	unsigned int cpu;
> +	unsigned int local_id;
> +	/* Details saved by driver in the vector */
> +	unsigned int hwirq;
> +};
> +
> +struct imsic_local_priv {
> +	/* Local state of interrupt identities */
> +	raw_spinlock_t ids_lock;
> +	unsigned long *ids_enabled_bitmap;
> +	struct imsic_vector **ids_move;
> +
> +	/* Local vector table */
> +	struct imsic_vector *vectors;

Please make those structs tabular:

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#struct-declarations-and-initializers

> +void __imsic_eix_update(unsigned long base_id,
> +			unsigned long num_id, bool pend, bool val);
> +
> +#define __imsic_id_set_enable(__id)		\
> +	__imsic_eix_update((__id), 1, false, true)
> +#define __imsic_id_clear_enable(__id)	\
> +	__imsic_eix_update((__id), 1, false, false)

inlines please.

Thanks,

        tglx


From pr-tracker-bot at kernel.org  Fri Feb 16 10:52:04 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 16 Feb 2024 18:52:04 +0000
Subject: [GIT PULL] arm64 fixes for -rc5
In-Reply-To: <20240216115819.GA1804@willie-the-truck>
References: <20240216115819.GA1804@willie-the-truck>
Message-ID: <170810952406.23532.1437982823384303516.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 16 Feb 2024 11:58:20 +0000:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/3f3f64cb60eef5bf3a787573cd05803171eb99ec

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From justinstitt at google.com  Fri Feb 16 10:58:58 2024
From: justinstitt at google.com (Justin Stitt)
Date: Fri, 16 Feb 2024 10:58:58 -0800
Subject: [PATCH v2] nvmem: meson-efuse: fix function pointer type mismatch
In-Reply-To: <20240213142831.3069049-1-jbrunet@baylibre.com>
References: <20240213142831.3069049-1-jbrunet@baylibre.com>
Message-ID: <CAFhGd8oQ5jh21U4SG3aN5eZJ5h+Ywk4WLFa0yPz8bquFmA1mag@mail.gmail.com>

Hi,

On Tue, Feb 13, 2024 at 6:28?AM Jerome Brunet <jbrunet at baylibre.com> wrote:
>
> clang-16 warns about casting functions to incompatible types, as is done
> here to call clk_disable_unprepare:
>
> drivers/nvmem/meson-efuse.c:78:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>    78 |                                        (void(*)(void *))clk_disable_unprepare,
>
> The pattern of getting, enabling and setting a disable callback for a
> clock can be replaced with devm_clk_get_enabled(), which also fixes
> this warning.
>
> Fixes: 611fbca1c861 ("nvmem: meson-efuse: add peripheral clock")
> Reported-by: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
>  drivers/nvmem/meson-efuse.c | 25 +++----------------------

I love negative diffs                                    ^^^^^^^^^^^^^^^

>  1 file changed, 3 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
> index b922df99f9bc..33678d0af2c2 100644
> --- a/drivers/nvmem/meson-efuse.c
> +++ b/drivers/nvmem/meson-efuse.c
> @@ -47,7 +47,6 @@ static int meson_efuse_probe(struct platform_device *pdev)
>         struct nvmem_config *econfig;
>         struct clk *clk;
>         unsigned int size;
> -       int ret;
>
>         sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
>         if (!sm_np) {
> @@ -60,27 +59,9 @@ static int meson_efuse_probe(struct platform_device *pdev)
>         if (!fw)
>                 return -EPROBE_DEFER;
>
> -       clk = devm_clk_get(dev, NULL);
> -       if (IS_ERR(clk)) {
> -               ret = PTR_ERR(clk);
> -               if (ret != -EPROBE_DEFER)
> -                       dev_err(dev, "failed to get efuse gate");
> -               return ret;
> -       }
> -
> -       ret = clk_prepare_enable(clk);
> -       if (ret) {
> -               dev_err(dev, "failed to enable gate");
> -               return ret;
> -       }
> -
> -       ret = devm_add_action_or_reset(dev,
> -                                      (void(*)(void *))clk_disable_unprepare,
> -                                      clk);
> -       if (ret) {
> -               dev_err(dev, "failed to add disable callback");
> -               return ret;
> -       }
> +       clk = devm_clk_get_enabled(dev, NULL);
> +       if (IS_ERR(clk))
> +               return dev_err_probe(dev, PTR_ERR(clk), "failed to get efuse gate");

Wow, this simplified nicely and doesn't make any new helpers (like
Arnd's version).

Reviewed-by: Justin Stitt <justinstitt at google.com>

>
>         if (meson_sm_call(fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
>                 dev_err(dev, "failed to get max user");
> --
> 2.43.0
>

Thanks
Justin


From megi at xff.cz  Fri Feb 16 11:04:23 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Fri, 16 Feb 2024 20:04:23 +0100
Subject: [PATCH 0/3] Move blender setup from individual planes to crtc commit in sun4i-drm
Message-ID: <20240216190430.1374132-1-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

This series refactors blender setup from individual planes to a common
place where it can be performed at once and is easier to reason about.

In the process this fixes a few bugs that allowed blender pipes to be
disabled while corresponding DRM planes were requested to be enabled.

Please take a look. :)

Thank you very much,
	Ond?ej Jirman

Ondrej Jirman (3):
  drm/sun4i: Unify sun8i_*_layer structs
  drm/sun4i: Add more parameters to sunxi_engine commit callback
  drm/sun4i: Fix layer zpos change/atomic modesetting

 drivers/gpu/drm/sun4i/sun4i_backend.c  |  4 +-
 drivers/gpu/drm/sun4i/sun4i_crtc.c     |  2 +-
 drivers/gpu/drm/sun4i/sun8i_mixer.c    | 82 +++++++++++++++++++++++-
 drivers/gpu/drm/sun4i/sun8i_mixer.h    | 20 ++++++
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 85 +++----------------------
 drivers/gpu/drm/sun4i/sun8i_ui_layer.h | 20 ++----
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 86 +++-----------------------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.h | 20 ++----
 drivers/gpu/drm/sun4i/sunxi_engine.h   | 13 +++-
 9 files changed, 137 insertions(+), 195 deletions(-)

-- 
2.43.0



From megi at xff.cz  Fri Feb 16 11:04:26 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Fri, 16 Feb 2024 20:04:26 +0100
Subject: [PATCH 3/3] drm/sun4i: Fix layer zpos change/atomic modesetting
In-Reply-To: <20240216190430.1374132-1-megi@xff.cz>
References: <20240216190430.1374132-1-megi@xff.cz>
Message-ID: <20240216190430.1374132-4-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

Identical configurations of planes can lead to different (and wrong)
layer -> pipe routing at HW level, depending on the order of atomic
plane changes.

For example:

- Layer 1 is configured to zpos 0 and thus uses pipe 0. No other layer
  is enabled. This is a typical situation at boot.

- When a compositor takes over and layer 3 is enabled,
  sun8i_ui_layer_enable() will get called with old_zpos=0 zpos=1, which
  will lead to incorrect disabling of pipe 0 and enabling of pipe 1.

What happens is that sun8i_ui_layer_enable() function may disable
blender pipes even if it is no longer assigned to its layer.

To correct this, move the routing setup out of individual plane's
atomic_update into crtc's atomic_update, where it can be calculated
and updated all at once.

Remove the atomic_disable callback because it is no longer needed.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c    | 73 +++++++++++++++++++++++++
 drivers/gpu/drm/sun4i/sun8i_mixer.h    |  6 +++
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 73 +------------------------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 74 +-------------------------
 4 files changed, 83 insertions(+), 143 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index bdeb9b80e038..21331d4ffe01 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -250,12 +250,85 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format)
 	return -EINVAL;
 }
 
+static void sun8i_layer_enable(struct sun8i_layer *layer, bool enable)
+{
+	u32 ch_base = sun8i_channel_base(layer->mixer, layer->channel);
+	u32 val, reg, mask;
+
+	if (layer->type == SUN8I_LAYER_TYPE_UI) {
+		val = enable ? SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN : 0;
+		mask = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN;
+		reg = SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, layer->overlay);
+	} else {
+		val = enable ? SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN : 0;
+		mask = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN;
+		reg = SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, layer->overlay);
+	}
+
+	regmap_update_bits(layer->mixer->engine.regs, reg, mask, val);
+}
+
 static void sun8i_mixer_commit(struct sunxi_engine *engine,
 			       struct drm_crtc *crtc,
 			       struct drm_atomic_state *state)
 {
+	struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
+	u32 bld_base = sun8i_blender_base(mixer);
+	struct drm_plane_state *plane_state;
+	struct drm_plane *plane;
+	u32 route = 0, pipe_en = 0;
+
 	DRM_DEBUG_DRIVER("Committing changes\n");
 
+	drm_for_each_plane(plane, state->dev) {
+		struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
+		bool enable;
+		int zpos;
+
+		if (!(plane->possible_crtcs & drm_crtc_mask(crtc)) || layer->mixer != mixer)
+			continue;
+
+		plane_state = drm_atomic_get_new_plane_state(state, plane);
+		if (!plane_state)
+			plane_state = plane->state;
+
+		enable = plane_state->crtc && plane_state->visible;
+		zpos = plane_state->normalized_zpos;
+
+		DRM_DEBUG_DRIVER("  plane %d: chan=%d ovl=%d en=%d zpos=%d\n",
+				 plane->base.id, layer->channel, layer->overlay,
+				 enable, zpos);
+
+		/*
+		 * We always update the layer enable bit, because it can clear
+		 * spontaneously for unknown reasons.
+		 */
+		sun8i_layer_enable(layer, enable);
+
+		if (!enable)
+			continue;
+
+		/* Route layer to pipe based on zpos */
+		route |= layer->channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
+		pipe_en |= SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
+	}
+
+	regmap_update_bits(mixer->engine.regs,
+			   SUN8I_MIXER_BLEND_ROUTE(bld_base),
+			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(0) |
+			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(1) |
+			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(2) |
+			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(3),
+			   route);
+
+	regmap_update_bits(mixer->engine.regs,
+			   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(0) |
+			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(1) |
+			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(2) |
+			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(3),
+			   pipe_en);
+
 	regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF,
 		     SUN8I_MIXER_GLOBAL_DBUFF_ENABLE);
 }
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 5a610ee30301..d7898c9c9cc0 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -186,9 +186,15 @@ struct sun8i_mixer {
 	struct clk			*mod_clk;
 };
 
+enum {
+	SUN8I_LAYER_TYPE_UI,
+	SUN8I_LAYER_TYPE_VI,
+};
+
 struct sun8i_layer {
 	struct drm_plane	plane;
 	struct sun8i_mixer	*mixer;
+	int			type;
 	int			channel;
 	int			overlay;
 };
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index 248fbb606ede..b90e5edef4e8 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -24,55 +24,6 @@
 #include "sun8i_ui_layer.h"
 #include "sun8i_ui_scaler.h"
 
-static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
-				  int overlay, bool enable, unsigned int zpos,
-				  unsigned int old_zpos)
-{
-	u32 val, bld_base, ch_base;
-
-	bld_base = sun8i_blender_base(mixer);
-	ch_base = sun8i_channel_base(mixer, channel);
-
-	DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n",
-			 enable ? "En" : "Dis", channel, overlay);
-
-	if (enable)
-		val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN;
-	else
-		val = 0;
-
-	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
-			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
-
-	if (!enable || zpos != old_zpos) {
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
-				   SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
-				   0);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
-				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
-				   0);
-	}
-
-	if (enable) {
-		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
-				   val, val);
-
-		val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
-				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
-				   val);
-	}
-}
-
 static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
 					int overlay, struct drm_plane *plane)
 {
@@ -259,36 +210,18 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
 						   true, true);
 }
 
-static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane,
-					  struct drm_atomic_state *state)
-{
-	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
-									   plane);
-	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
-	unsigned int old_zpos = old_state->normalized_zpos;
-	struct sun8i_mixer *mixer = layer->mixer;
-
-	sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay, false, 0,
-			      old_zpos);
-}
 
 static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
 					 struct drm_atomic_state *state)
 {
-	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
-									   plane);
 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
 									   plane);
 	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	unsigned int zpos = new_state->normalized_zpos;
-	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
 
-	if (!new_state->visible) {
-		sun8i_ui_layer_enable(mixer, layer->channel,
-				      layer->overlay, false, 0, old_zpos);
+	if (!new_state->crtc || !new_state->visible)
 		return;
-	}
 
 	sun8i_ui_layer_update_coord(mixer, layer->channel,
 				    layer->overlay, plane, zpos);
@@ -298,13 +231,10 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
 				      layer->overlay, plane);
 	sun8i_ui_layer_update_buffer(mixer, layer->channel,
 				     layer->overlay, plane);
-	sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay,
-			      true, zpos, old_zpos);
 }
 
 static const struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = {
 	.atomic_check	= sun8i_ui_layer_atomic_check,
-	.atomic_disable	= sun8i_ui_layer_atomic_disable,
 	.atomic_update	= sun8i_ui_layer_atomic_update,
 };
 
@@ -390,6 +320,7 @@ struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
 
 	drm_plane_helper_add(&layer->plane, &sun8i_ui_layer_helper_funcs);
 	layer->mixer = mixer;
+	layer->type = SUN8I_LAYER_TYPE_UI;
 	layer->channel = channel;
 	layer->overlay = 0;
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index 0c0f1ac80517..9c09d9c08496 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -18,55 +18,6 @@
 #include "sun8i_vi_layer.h"
 #include "sun8i_vi_scaler.h"
 
-static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
-				  int overlay, bool enable, unsigned int zpos,
-				  unsigned int old_zpos)
-{
-	u32 val, bld_base, ch_base;
-
-	bld_base = sun8i_blender_base(mixer);
-	ch_base = sun8i_channel_base(mixer, channel);
-
-	DRM_DEBUG_DRIVER("%sabling VI channel %d overlay %d\n",
-			 enable ? "En" : "Dis", channel, overlay);
-
-	if (enable)
-		val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN;
-	else
-		val = 0;
-
-	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
-			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN, val);
-
-	if (!enable || zpos != old_zpos) {
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
-				   SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
-				   0);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
-				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
-				   0);
-	}
-
-	if (enable) {
-		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
-				   val, val);
-
-		val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
-				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
-				   val);
-	}
-}
-
 static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
 					int overlay, struct drm_plane *plane)
 {
@@ -393,36 +344,17 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
 						   true, true);
 }
 
-static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane,
-					  struct drm_atomic_state *state)
-{
-	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
-									   plane);
-	struct sun8i_layer *layer = plane_to_sun8i_vi_layer(plane);
-	unsigned int old_zpos = old_state->normalized_zpos;
-	struct sun8i_mixer *mixer = layer->mixer;
-
-	sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay, false, 0,
-			      old_zpos);
-}
-
 static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
 					 struct drm_atomic_state *state)
 {
-	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
-									   plane);
 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
 									   plane);
 	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	unsigned int zpos = new_state->normalized_zpos;
-	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
 
-	if (!new_state->visible) {
-		sun8i_vi_layer_enable(mixer, layer->channel,
-				      layer->overlay, false, 0, old_zpos);
+	if (!new_state->crtc || !new_state->visible)
 		return;
-	}
 
 	sun8i_vi_layer_update_coord(mixer, layer->channel,
 				    layer->overlay, plane, zpos);
@@ -432,13 +364,10 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
 				      layer->overlay, plane);
 	sun8i_vi_layer_update_buffer(mixer, layer->channel,
 				     layer->overlay, plane);
-	sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay,
-			      true, zpos, old_zpos);
 }
 
 static const struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = {
 	.atomic_check	= sun8i_vi_layer_atomic_check,
-	.atomic_disable	= sun8i_vi_layer_atomic_disable,
 	.atomic_update	= sun8i_vi_layer_atomic_update,
 };
 
@@ -613,6 +542,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
 
 	drm_plane_helper_add(&layer->plane, &sun8i_vi_layer_helper_funcs);
 	layer->mixer = mixer;
+	layer->type = SUN8I_LAYER_TYPE_VI;
 	layer->channel = index;
 	layer->overlay = 0;
 
-- 
2.43.0



From megi at xff.cz  Fri Feb 16 11:04:24 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Fri, 16 Feb 2024 20:04:24 +0100
Subject: [PATCH 1/3] drm/sun4i: Unify sun8i_*_layer structs
In-Reply-To: <20240216190430.1374132-1-megi@xff.cz>
References: <20240216190430.1374132-1-megi@xff.cz>
Message-ID: <20240216190430.1374132-2-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

These structs are identical, use a single struct to represent private
data for the DRM plane. This is a preparation for configuring layer
routing from the CRTC (mixer) instead of current approach of setting
up routing from individual layer's atomic_update callback.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c    |  4 ++--
 drivers/gpu/drm/sun4i/sun8i_mixer.h    | 14 ++++++++++++++
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 14 +++++++-------
 drivers/gpu/drm/sun4i/sun8i_ui_layer.h | 20 ++++----------------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 14 +++++++-------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.h | 20 ++++----------------
 6 files changed, 38 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 01382860aaee..1e681314e379 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -271,7 +271,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
 		return ERR_PTR(-ENOMEM);
 
 	for (i = 0; i < mixer->cfg->vi_num; i++) {
-		struct sun8i_vi_layer *layer;
+		struct sun8i_layer *layer;
 
 		layer = sun8i_vi_layer_init_one(drm, mixer, i);
 		if (IS_ERR(layer)) {
@@ -284,7 +284,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
 	}
 
 	for (i = 0; i < mixer->cfg->ui_num; i++) {
-		struct sun8i_ui_layer *layer;
+		struct sun8i_layer *layer;
 
 		layer = sun8i_ui_layer_init_one(drm, mixer, i);
 		if (IS_ERR(layer)) {
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 85c94884fb9a..5a610ee30301 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -9,6 +9,7 @@
 #include <linux/clk.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
+#include <drm/drm_plane.h>
 
 #include "sunxi_engine.h"
 
@@ -185,6 +186,19 @@ struct sun8i_mixer {
 	struct clk			*mod_clk;
 };
 
+struct sun8i_layer {
+	struct drm_plane	plane;
+	struct sun8i_mixer	*mixer;
+	int			channel;
+	int			overlay;
+};
+
+static inline struct sun8i_layer *
+plane_to_sun8i_layer(struct drm_plane *plane)
+{
+	return container_of(plane, struct sun8i_layer, plane);
+}
+
 static inline struct sun8i_mixer *
 engine_to_sun8i_mixer(struct sunxi_engine *engine)
 {
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index ca75ca0835a6..248fbb606ede 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -232,7 +232,7 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
 {
 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 										 plane);
-	struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	struct drm_crtc *crtc = new_plane_state->crtc;
 	struct drm_crtc_state *crtc_state;
 	int min_scale, max_scale;
@@ -264,7 +264,7 @@ static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane,
 {
 	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
 									   plane);
-	struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
 
@@ -279,7 +279,7 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
 									   plane);
 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
 									   plane);
-	struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	unsigned int zpos = new_state->normalized_zpos;
 	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
@@ -345,13 +345,13 @@ static const uint64_t sun8i_layer_modifiers[] = {
 	DRM_FORMAT_MOD_INVALID
 };
 
-struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
-					       struct sun8i_mixer *mixer,
-					       int index)
+struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
+					    struct sun8i_mixer *mixer,
+					    int index)
 {
 	enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY;
 	int channel = mixer->cfg->vi_num + index;
-	struct sun8i_ui_layer *layer;
+	struct sun8i_layer *layer;
 	unsigned int plane_cnt;
 	int ret;
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
index e3e32ee1178d..83892f6ff211 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
@@ -47,21 +47,9 @@
 #define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_COMBINED	((2) << 1)
 
 struct sun8i_mixer;
+struct sun8i_layer;
 
-struct sun8i_ui_layer {
-	struct drm_plane	plane;
-	struct sun8i_mixer	*mixer;
-	int			channel;
-	int			overlay;
-};
-
-static inline struct sun8i_ui_layer *
-plane_to_sun8i_ui_layer(struct drm_plane *plane)
-{
-	return container_of(plane, struct sun8i_ui_layer, plane);
-}
-
-struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
-					       struct sun8i_mixer *mixer,
-					       int index);
+struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
+					    struct sun8i_mixer *mixer,
+					    int index);
 #endif /* _SUN8I_UI_LAYER_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index f9c0a56d3a14..0c0f1ac80517 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -366,7 +366,7 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
 {
 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 										 plane);
-	struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	struct drm_crtc *crtc = new_plane_state->crtc;
 	struct drm_crtc_state *crtc_state;
 	int min_scale, max_scale;
@@ -398,7 +398,7 @@ static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane,
 {
 	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
 									   plane);
-	struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_vi_layer(plane);
 	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
 
@@ -413,7 +413,7 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
 									   plane);
 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
 									   plane);
-	struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	unsigned int zpos = new_state->normalized_zpos;
 	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
@@ -539,14 +539,14 @@ static const uint64_t sun8i_layer_modifiers[] = {
 	DRM_FORMAT_MOD_INVALID
 };
 
-struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
-					       struct sun8i_mixer *mixer,
-					       int index)
+struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
+					    struct sun8i_mixer *mixer,
+					    int index)
 {
 	enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY;
 	u32 supported_encodings, supported_ranges;
 	unsigned int plane_cnt, format_count;
-	struct sun8i_vi_layer *layer;
+	struct sun8i_layer *layer;
 	const u32 *formats;
 	int ret;
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
index 48c399e1c86d..655440cdc78f 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
@@ -52,21 +52,9 @@
 #define SUN8I_MIXER_CHAN_VI_DS_M(x)			((x) << 0)
 
 struct sun8i_mixer;
+struct sun8i_layer;
 
-struct sun8i_vi_layer {
-	struct drm_plane	plane;
-	struct sun8i_mixer	*mixer;
-	int			channel;
-	int			overlay;
-};
-
-static inline struct sun8i_vi_layer *
-plane_to_sun8i_vi_layer(struct drm_plane *plane)
-{
-	return container_of(plane, struct sun8i_vi_layer, plane);
-}
-
-struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
-					       struct sun8i_mixer *mixer,
-					       int index);
+struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
+					    struct sun8i_mixer *mixer,
+					    int index);
 #endif /* _SUN8I_VI_LAYER_H_ */
-- 
2.43.0



From megi at xff.cz  Fri Feb 16 11:04:25 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Fri, 16 Feb 2024 20:04:25 +0100
Subject: [PATCH 2/3] drm/sun4i: Add more parameters to sunxi_engine commit callback
In-Reply-To: <20240216190430.1374132-1-megi@xff.cz>
References: <20240216190430.1374132-1-megi@xff.cz>
Message-ID: <20240216190430.1374132-3-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

These will be needed later on when we move layer configuration to
crtc update.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 drivers/gpu/drm/sun4i/sun4i_backend.c |  4 +++-
 drivers/gpu/drm/sun4i/sun4i_crtc.c    |  2 +-
 drivers/gpu/drm/sun4i/sun8i_mixer.c   |  5 ++++-
 drivers/gpu/drm/sun4i/sunxi_engine.h  | 13 ++++++++++---
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index 335fd0edb904..e89eb96d3131 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -69,7 +69,9 @@ static void sun4i_backend_disable_color_correction(struct sunxi_engine *engine)
 			   SUN4I_BACKEND_OCCTL_ENABLE, 0);
 }
 
-static void sun4i_backend_commit(struct sunxi_engine *engine)
+static void sun4i_backend_commit(struct sunxi_engine *engine,
+				 struct drm_crtc *crtc,
+				 struct drm_atomic_state *state)
 {
 	DRM_DEBUG_DRIVER("Committing changes\n");
 
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
index c06d7cd45388..18e74047b0f5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
@@ -91,7 +91,7 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
 
 	DRM_DEBUG_DRIVER("Committing plane changes\n");
 
-	sunxi_engine_commit(scrtc->engine);
+	sunxi_engine_commit(scrtc->engine, crtc, state);
 
 	if (event) {
 		crtc->state->event = NULL;
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 1e681314e379..bdeb9b80e038 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 
+#include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_framebuffer.h>
@@ -249,7 +250,9 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format)
 	return -EINVAL;
 }
 
-static void sun8i_mixer_commit(struct sunxi_engine *engine)
+static void sun8i_mixer_commit(struct sunxi_engine *engine,
+			       struct drm_crtc *crtc,
+			       struct drm_atomic_state *state)
 {
 	DRM_DEBUG_DRIVER("Committing changes\n");
 
diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h
index ec8cf9b2bda4..ec0c4932f15c 100644
--- a/drivers/gpu/drm/sun4i/sunxi_engine.h
+++ b/drivers/gpu/drm/sun4i/sunxi_engine.h
@@ -7,6 +7,7 @@
 #define _SUNXI_ENGINE_H_
 
 struct drm_plane;
+struct drm_crtc;
 struct drm_device;
 struct drm_crtc_state;
 struct drm_display_mode;
@@ -59,7 +60,9 @@ struct sunxi_engine_ops {
 	 *
 	 * This function is optional.
 	 */
-	void (*commit)(struct sunxi_engine *engine);
+	void (*commit)(struct sunxi_engine *engine,
+		       struct drm_crtc *crtc,
+		       struct drm_atomic_state *state);
 
 	/**
 	 * @layers_init:
@@ -144,12 +147,16 @@ struct sunxi_engine {
 /**
  * sunxi_engine_commit() - commit all changes of the engine
  * @engine:	pointer to the engine
+ * @crtc:	pointer to crtc the engine is associated with
+ * @state:	atomic state
  */
 static inline void
-sunxi_engine_commit(struct sunxi_engine *engine)
+sunxi_engine_commit(struct sunxi_engine *engine,
+		    struct drm_crtc *crtc,
+		    struct drm_atomic_state *state)
 {
 	if (engine->ops && engine->ops->commit)
-		engine->ops->commit(engine);
+		engine->ops->commit(engine, crtc, state);
 }
 
 /**
-- 
2.43.0



From conor at kernel.org  Fri Feb 16 11:07:58 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 16 Feb 2024 19:07:58 +0000
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <f5e63a8b-fb6c-449f-8ec3-26aed5b11b95@ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <20240214142825.GA7873@pendragon.ideasonboard.com>
 <20240214-velcro-pushy-0cbd18b23361@spud>
 <20240215110205.GD7873@pendragon.ideasonboard.com>
 <e06b0792-187d-454b-aa62-d9c1e797df17@ideasonboard.com>
 <20240216132755.GA20376@pendragon.ideasonboard.com>
 <f5e63a8b-fb6c-449f-8ec3-26aed5b11b95@ideasonboard.com>
Message-ID: <20240216-caboose-poison-3052a4bb9eaf@spud>

On Fri, Feb 16, 2024 at 02:45:31PM +0000, Dan Scally wrote:

> > > > > > > +      - description: ISP AXI clock
> > > > > > > +      - description: ISP AHB-lite clock
> > > > > > These two other clocks look good to me.
> > > > > > 
> > > > > > > +
> > > > > > > +  clock-names:
> > > > > > > +    items:
> > > > > > > +      - const: vclk
> > > > > > > +      - const: aclk
> > > > > > > +      - const: hclk
> > > > > Why not "video" "axi" "ahb-lite"? There's 3 useful letters between the
> > > > > tree clock names you've provided - they're all clocks, so having "clk"
> > > > > in them is just noise :)
> > > > As far as I understand, the names proposed by Dan come directly from the
> > > > IP core documentation.
> > > This is the case, but I do take Conor's point that more descriptive names might be nicer - if I'm
> > > honest I just didn't think about it particularly given "Xclk" is such a common name for them
> > > already, but having been poked into thinking about it I do agree.
> > Isn't the usual practice in DT bindings is to name GPIOs, clocks and reset
> > signals based on the hardware documentation ?
> 
> 
> Ah - I don't know honestly. If that's so then yeah - these are the names the documentation prescribes.

If a direct doc match is what you're going for, then sure, keep it.
-------------- 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/20240216/33a0f5f3/attachment.sig>

From Frank.li at nxp.com  Fri Feb 16 11:22:58 2024
From: Frank.li at nxp.com (Frank Li)
Date: Fri, 16 Feb 2024 14:22:58 -0500
Subject: [PATCH v2 2/4] dt-bindings: net: fec: add iommus property
In-Reply-To: <49dbd0a2-a4b9-4c05-bb10-44f267672374@linaro.org>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240201-8qm_smmu-v2-2-3d12a80201a3@nxp.com>
 <49dbd0a2-a4b9-4c05-bb10-44f267672374@linaro.org>
Message-ID: <Zc+2EitZrVzLsA03@lizhi-Precision-Tower-5810>

On Fri, Feb 02, 2024 at 09:23:37AM +0100, Krzysztof Kozlowski wrote:
> On 01/02/2024 21:22, Frank Li wrote:
> > iMX8QM have iommu. Add proerty 'iommus'.
> > 
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> 
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Other 3 patches already been linux-next. Who will pick this one?

Frank

> 
> Best regards,
> Krzysztof
> 


From nicolas at ndufresne.ca  Fri Feb 16 11:29:55 2024
From: nicolas at ndufresne.ca (Nicolas Dufresne)
Date: Fri, 16 Feb 2024 14:29:55 -0500
Subject: [PATCH 1/4] clk: rockchip: rst-rk3588: Add BIU reset
In-Reply-To: <237e690a-2f49-4046-b054-3a878eed6748@linaro.org>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
	 <20240216094922.257674-2-shreeya.patel@collabora.com>
	 <237e690a-2f49-4046-b054-3a878eed6748@linaro.org>
Message-ID: <8d68a49a35799d1686d9b674ce4edfd91c68850b.camel@ndufresne.ca>

Le vendredi 16 f?vrier 2024 ? 11:03 +0100, Krzysztof Kozlowski a ?crit?:
> On 16/02/2024 10:49, Shreeya Patel wrote:
> > Export hdmirx_biu soft reset id which is required by the hdmirx controller.
> > 
> > Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
> > ---
> >  drivers/clk/rockchip/rst-rk3588.c               | 1 +
> >  include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++
> 
> Please run scripts/checkpatch.pl and fix reported warnings. Some
> warnings can be ignored, but the code here looks like it needs a fix.
> Feel free to get in touch if the warning is not clear.
> 
> Please do internal review. The internal Collabora review would tell you:
> YOU MUST run checkpatch. Then you see errors, so why do you send patch
> with errors to the mailing list?

Mistakes helps you learn. Meanwhile, I've triggered our temporary CI which
hopefully will catch this and some more for a better v2. Shreeya, I don't think
this includes any DT automated checks, this is on you.

https://gitlab.collabora.com/linux/build-scripts/-/pipelines/85935

> 
> Best regards,
> Krzysztof
> 
> 



From conor at kernel.org  Fri Feb 16 11:45:21 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 16 Feb 2024 19:45:21 +0000
Subject: [PATCH v3 01/12] spi: dt-bindings: introduce FIFO depth
 properties
In-Reply-To: <20240216070555.2483977-2-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
 <20240216070555.2483977-2-tudor.ambarus@linaro.org>
Message-ID: <20240216-malt-alumni-4939546e1e2c@spud>

On Fri, Feb 16, 2024 at 07:05:44AM +0000, Tudor Ambarus wrote:
> There are SPI IPs that can be configured by the integrator with a
> specific FIFO depth depending on the system's capabilities. For example,
> the samsung USI SPI IP can be configured by the integrator with a TX/RX
> FIFO from 8 byte to 256 bytes.
> 
> Introduce the ``fifo-depth`` property for such instances of IPs where the
> same FIFO depth is used for both RX and TX. Introduce ``rx-fifo-depth``
> and ``tx-fifo-depth`` properties for cases where the RX FIFO depth is
> different from the TX FIFO depth.
> 
> Make the dedicated RX/TX properties dependent on each other and mutual
> exclusive with the other.
> 
> Reviewed-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
>  .../bindings/spi/spi-controller.yaml          | 27 +++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml
> index 524f6fe8c27b..093150c0cb87 100644
> --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml
> +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml
> @@ -69,6 +69,21 @@ properties:
>           Should be generally avoided and be replaced by
>           spi-cs-high + ACTIVE_HIGH.
>  
> +  fifo-depth:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Size of the RX and TX data FIFOs in bytes.
> +
> +  rx-fifo-depth:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Size of the RX data FIFO in bytes.
> +
> +  tx-fifo-depth:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Size of the TX data FIFO in bytes.
> +
>    num-cs:
>      $ref: /schemas/types.yaml#/definitions/uint32
>      description:
> @@ -116,6 +131,10 @@ patternProperties:
>        - compatible
>        - reg
>  
> +dependencies:
> +  rx-fifo-depth: [ tx-fifo-depth ]
> +  tx-fifo-depth: [ rx-fifo-depth ]
> +
>  allOf:
>    - if:
>        not:
> @@ -129,6 +148,14 @@ allOf:
>        properties:
>          "#address-cells":
>            const: 0
> +  - not:
> +      required:
> +        - fifo-depth
> +        - rx-fifo-depth
> +  - not:
> +      required:
> +        - fifo-depth
> +        - tx-fifo-depth
>  
>  additionalProperties: true
>  
> -- 
> 2.44.0.rc0.258.g7320e95886-goog
> 
-------------- 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/20240216/95824df8/attachment-0001.sig>

From jhubbard at nvidia.com  Fri Feb 16 11:54:00 2024
From: jhubbard at nvidia.com (John Hubbard)
Date: Fri, 16 Feb 2024 11:54:00 -0800
Subject: [PATCH v6 12/18] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <Zc-Tqqfksho3BHmU@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-13-ryan.roberts@arm.com> <Zc9UQy-mtYAzNWm2@arm.com>
 <892caa6a-e4fe-4009-aa33-0570526961c5@arm.com> <Zc-Tqqfksho3BHmU@arm.com>
Message-ID: <f9fc2b31-11cb-4969-8961-9c89fea41b74@nvidia.com>

On 2/16/24 08:56, Catalin Marinas wrote:
...
>> The problem is that the contpte_* symbols are called from the ptep_* inline
>> functions. So where those inlines are called from modules, we need to make sure
>> the contpte_* symbols are available.
>>
>> John Hubbard originally reported this problem against v1 and I enumerated all
>> the drivers that call into the ptep_* inlines here:
>> https://lore.kernel.org/linux-arm-kernel/b994ff89-1a1f-26ca-9479-b08c77f94be8 at arm.com/#t
>>
>> So they definitely need to be exported. Perhaps we can tighten it to

Yes. Let's keep the in-tree modules working.

>> EXPORT_SYMBOL_GPL(), but I was being cautious as I didn't want to break anything
>> out-of-tree. I'm not sure what the normal policy is? arm64 seems to use ~equal
>> amounts of both.

EXPORT_SYMBOL_GPL() seems appropriate and low risk. As Catalin says below,
these really are deeply core mm routines, and any module operating at this
level is not going to be able to survive on EXPORT_SYMBOL alone, IMHO.

Now, if only I could find an out of tree module to test that claim on... :)


> I don't think we are consistent here. For example set_pte_at() can't be
> called from non-GPL modules because of __sync_icache_dcache. OTOH, such
> driver is probably doing something dodgy. Same with
> apply_to_page_range(), it's GPL-only (called from i915).
> 
> Let's see if others have any view over the next week or so, otherwise
> I'd go for _GPL and relax it later if someone has a good use-case (can
> be a patch on top adding _GPL).

I think going directly to _GPL for these is fine, actually.


thanks,
-- 
John Hubbard
NVIDIA



From tglx at linutronix.de  Fri Feb 16 12:12:08 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 16 Feb 2024 21:12:08 +0100
Subject: [PATCH v12 19/25] irqchip/riscv-imsic: Add device MSI domain
 support for platform devices
In-Reply-To: <20240127161753.114685-20-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-20-apatel@ventanamicro.com>
Message-ID: <87eddccgo7.ffs@tglx>

On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> +static int imsic_cpu_page_phys(unsigned int cpu,
> +			       unsigned int guest_index,
> +			       phys_addr_t *out_msi_pa)
> +{
> +	struct imsic_global_config *global;
> +	struct imsic_local_config *local;
> +
> +	global = &imsic->global;
> +	local = per_cpu_ptr(global->local, cpu);
> +
> +	if (BIT(global->guest_index_bits) <= guest_index)
> +		return -EINVAL;

As the callsite does not care about the return value, just make this
function boolean and return true on success.

> +	if (out_msi_pa)
> +		*out_msi_pa = local->msi_pa +
> +			      (guest_index * IMSIC_MMIO_PAGE_SZ);
> +
> +	return 0;
> +}
> +
> +static void imsic_irq_mask(struct irq_data *d)
> +{
> +	imsic_vector_mask(irq_data_get_irq_chip_data(d));
> +}
> +
> +static void imsic_irq_unmask(struct irq_data *d)
> +{
> +	imsic_vector_unmask(irq_data_get_irq_chip_data(d));
> +}
> +
> +static int imsic_irq_retrigger(struct irq_data *d)
> +{
> +	struct imsic_vector *vec = irq_data_get_irq_chip_data(d);
> +	struct imsic_local_config *local;
> +
> +	if (WARN_ON(vec == NULL))
> +		return -ENOENT;
> +
> +	local = per_cpu_ptr(imsic->global.local, vec->cpu);
> +	writel(vec->local_id, local->msi_va);
> +	return 0;
> +}
> +
> +static void imsic_irq_compose_vector_msg(struct imsic_vector *vec,
> +					 struct msi_msg *msg)
> +{
> +	phys_addr_t msi_addr;
> +	int err;
> +
> +	if (WARN_ON(vec == NULL))
> +		return;
> +
> +	err = imsic_cpu_page_phys(vec->cpu, 0, &msi_addr);
> +	if (WARN_ON(err))
> +		return;

	if (WARN_ON(!imsic_cpu_page_phys(...)))
        	return
Hmm?

> +
> +	msg->address_hi = upper_32_bits(msi_addr);
> +	msg->address_lo = lower_32_bits(msi_addr);
> +	msg->data = vec->local_id;
> +}
> +
> +static void imsic_irq_compose_msg(struct irq_data *d, struct msi_msg *msg)
> +{
> +	imsic_irq_compose_vector_msg(irq_data_get_irq_chip_data(d), msg);
> +}
> +
> +#ifdef CONFIG_SMP
> +static void imsic_msi_update_msg(struct irq_data *d, struct imsic_vector *vec)
> +{
> +	struct msi_msg msg[2] = { [1] = { }, };
> +
> +	imsic_irq_compose_vector_msg(vec, msg);
> +	irq_data_get_irq_chip(d)->irq_write_msi_msg(d, msg);
> +}
> +
> +static int imsic_irq_set_affinity(struct irq_data *d,
> +				  const struct cpumask *mask_val,
> +				  bool force)
> +{
> +	struct imsic_vector *old_vec, *new_vec;
> +	struct irq_data *pd = d->parent_data;
> +
> +	old_vec = irq_data_get_irq_chip_data(pd);
> +	if (WARN_ON(old_vec == NULL))
> +		return -ENOENT;
> +
> +	/* Get a new vector on the desired set of CPUs */
> +	new_vec = imsic_vector_alloc(old_vec->hwirq, mask_val);
> +	if (!new_vec)
> +		return -ENOSPC;
> +
> +	/* If old vector belongs to the desired CPU then do nothing */
> +	if (old_vec->cpu == new_vec->cpu) {
> +		imsic_vector_free(new_vec);
> +		return IRQ_SET_MASK_OK_DONE;
> +	}

You can spare that exercise by checking it before the allocation:

        if (cpumask_test_cpu(old_vec->cpu, mask_val))
		return IRQ_SET_MASK_OK_DONE;

> +
> +	/* Point device to the new vector */
> +	imsic_msi_update_msg(d, new_vec);

> +static int imsic_irq_domain_alloc(struct irq_domain *domain,
> +				  unsigned int virq, unsigned int nr_irqs,
> +				  void *args)
> +{
> +	struct imsic_vector *vec;
> +	int hwirq;
> +
> +	/* Legacy-MSI or multi-MSI not supported yet. */

What's legacy MSI in that context?

> +	if (nr_irqs > 1)
> +		return -ENOTSUPP;
> +
> +	hwirq = imsic_hwirq_alloc();
> +	if (hwirq < 0)
> +		return hwirq;
> +
> +	vec = imsic_vector_alloc(hwirq, cpu_online_mask);
> +	if (!vec) {
> +		imsic_hwirq_free(hwirq);
> +		return -ENOSPC;
> +	}
> +
> +	irq_domain_set_info(domain, virq, hwirq,
> +			    &imsic_irq_base_chip, vec,
> +			    handle_simple_irq, NULL, NULL);
> +	irq_set_noprobe(virq);
> +	irq_set_affinity(virq, cpu_online_mask);
> +
> +	/*
> +	 * IMSIC does not implement irq_disable() so Linux interrupt
> +	 * subsystem will take a lazy approach for disabling an IMSIC
> +	 * interrupt. This means IMSIC interrupts are left unmasked
> +	 * upon system suspend and interrupts are not processed
> +	 * immediately upon system wake up. To tackle this, we disable
> +	 * the lazy approach for all IMSIC interrupts.

Why? Lazy works perfectly fine even w/o an irq_disable() callback.

> +	 */
> +	irq_set_status_flags(virq, IRQ_DISABLE_UNLAZY);

> +
> +#define MATCH_PLATFORM_MSI		BIT(DOMAIN_BUS_PLATFORM_MSI)

You really love macro indirections :)

> +static const struct msi_parent_ops imsic_msi_parent_ops = {
> +	.supported_flags	= MSI_GENERIC_FLAGS_MASK,
> +	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
> +				  MSI_FLAG_USE_DEF_CHIP_OPS,
> +	.bus_select_token	= DOMAIN_BUS_NEXUS,
> +	.bus_select_mask	= MATCH_PLATFORM_MSI,
> +	.init_dev_msi_info	= imsic_init_dev_msi_info,
> +};
> +
> +int imsic_irqdomain_init(void)
> +{
> +	struct imsic_global_config *global;
> +
> +	if (!imsic || !imsic->fwnode) {
> +		pr_err("early driver not probed\n");
> +		return -ENODEV;
> +	}
> +
> +	if (imsic->base_domain) {
> +		pr_err("%pfwP: irq domain already created\n", imsic->fwnode);
> +		return -ENODEV;
> +	}
> +
> +	global = &imsic->global;

Please move that assignment down to the usage site. Here it's just a
distraction.

> +	/* Create Base IRQ domain */
> +	imsic->base_domain = irq_domain_create_tree(imsic->fwnode,
> +					&imsic_base_domain_ops, imsic);
> +	if (!imsic->base_domain) {
> +		pr_err("%pfwP: failed to create IMSIC base domain\n",
> +			imsic->fwnode);
> +		return -ENOMEM;
> +	}
> +	imsic->base_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
> +	imsic->base_domain->msi_parent_ops = &imsic_msi_parent_ops;

Thanks,

        tglx


From tglx at linutronix.de  Fri Feb 16 12:14:40 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 16 Feb 2024 21:14:40 +0100
Subject: [PATCH v12 20/25] irqchip/riscv-imsic: Add device MSI domain
 support for PCI devices
In-Reply-To: <20240127161753.114685-21-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-21-apatel@ventanamicro.com>
Message-ID: <87bk8gcgjz.ffs@tglx>

On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> +#ifdef CONFIG_RISCV_IMSIC_PCI
> +
> +static void imsic_pci_mask_irq(struct irq_data *d)
> +{
> +	pci_msi_mask_irq(d);
> +	irq_chip_mask_parent(d);
> +}
> +
> +static void imsic_pci_unmask_irq(struct irq_data *d)
> +{
> +	pci_msi_unmask_irq(d);
> +	irq_chip_unmask_parent(d);

That's asymmetric vs. mask().  

Thanks,

        tglx


From arnd at arndb.de  Fri Feb 16 12:19:02 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 16 Feb 2024 21:19:02 +0100
Subject: [PATCH] firmware: arm_scmi: avoid returning uninialized data
In-Reply-To: <Zc-ZfgVbAvAZVrPu@pluto>
References: <20240216163259.1927967-1-arnd@kernel.org>
 <Zc-ZfgVbAvAZVrPu@pluto>
Message-ID: <e880e5c4-143c-4c51-adc5-e517f319579e@app.fastmail.com>

On Fri, Feb 16, 2024, at 18:21, Cristian Marussi wrote:
> On Fri, Feb 16, 2024 at 05:32:53PM +0100, Arnd Bergmann wrote:
>> From: Arnd Bergmann <arnd at arndb.de>
>> 
>> Clang notices that there is a code path through
>> scmi_powercap_notify_supported() that returns an
>> undefined value:
>> 
>
> thanks for looking at this, this series that I've just posted is still
> to be reviewd at all, so I would expect issues :D...BUT in this case I
> dont think that the clang report is valid since, inside the culprit
> function scmi_powercap_notify_supported(), a few lines before the
> reported usage of unitialized data there is a check (@line 816) on the
> 'bounds' of evt_id itself
>
> 	if (evt_id >= ARRAY_SIZE(evt_2_cmd) || src_id >= pi->num_domains)
> 		return false;
>
> so basically the mentioned if/else WILL be evaluated in some of its
> branches for sure and supported wont be uninitialized.
>
> Indeed, I removed from here (and from all the series) the explicit
> initialization at definition time right before posting the series.
>
> Having saidm that...maybe it is just brain-dead this approach of mine
> since it is able to fool clang & friends...I would add bACK an explicit
> initialization of supported all across this series in V2, if this
> sounds good to you.

I'm fine with any solution that avoids the warning. I usually
prefer the explicit assignment where it's needed over having
it as part of the declaration, and in this case I would
probably pick a switch/case of a set of if/else fi/else
blocks

     Arnd


From tglx at linutronix.de  Fri Feb 16 12:22:13 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 16 Feb 2024 21:22:13 +0100
Subject: [PATCH v12 14/25] irqchip/sifive-plic: Convert PLIC driver into
 a platform driver
In-Reply-To: <CAAhSdy2aeyJBcMVre12jGwU52oP9Z=1emB-bcYxygdR3QhP+6w@mail.gmail.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-15-apatel@ventanamicro.com> <87jzn4ctks.ffs@tglx>
 <CAAhSdy2aeyJBcMVre12jGwU52oP9Z=1emB-bcYxygdR3QhP+6w@mail.gmail.com>
Message-ID: <878r3kcg7e.ffs@tglx>

On Fri, Feb 16 2024 at 22:41, Anup Patel wrote:
> On Fri, Feb 16, 2024 at 9:03?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>> I don't think that removing the setup protection is correct.
>>
>> Assume you have maxcpus=N on the kernel command line, then the above
>> for_each_online_cpu() loop would result in cpuhp_setup == true when the
>> instances for the not onlined CPUs are set up, no?
>
> A platform can have multiple PLIC instances where each PLIC
> instance targets a subset of HARTs (or CPUs).
>
> Previously (before this patch), we were probing PLIC very early so on
> a platform with multiple PLIC instances, we need to ensure that cpuhp
> setup is done only after PLIC context associated with boot CPU is
> initialized hence the plic_cpuhp_setup_done check.
>
> This patch converts PLIC driver into a platform driver so now PLIC
> instances are probed after all available CPUs are brought-up. In this
> case, the cpuhp setup must be done only after PLIC context of all
> available CPUs are initialized otherwise some of the CPUs crash
> in plic_starting_cpu() due to lack of PLIC context initialization.

You're missing the point.

Assume you have 8 CPUs and 2 PLIC instances one for CPU0-3 and one for
CPU4-7.

Add "maxcpus=4" on the kernel command line, then only the first 4 CPUs
are brought up.

So at probe time cpu_online_mask has bit 0,1,2,3 set.

When the first PLIC it probed the loop which checks the context for each
online CPU will not clear cpuhp_setup and the hotplug state is installed.

Now the second PLIC is probed (the one for the offline CPUs 4-7) and the
loop will again not clear cpuhp_setup and it tries to install the state
again, no?

Thanks,

        tglx


From brgl at bgdev.pl  Fri Feb 16 12:32:02 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:02 +0100
Subject: [PATCH v5 05/18] dt-bindings: new: wireless: qcom,ath11k: describe the ath11k on QCA6390
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-6-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Add a PCI compatible for the ATH11K module on QCA6390 and describe the
power inputs from the PMU that it consumes.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../net/wireless/qcom,ath11k-pci.yaml         | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml
index 817f02a8b481..8530f01df6d9 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml
@@ -16,6 +16,7 @@ description: |
 properties:
   compatible:
     enum:
+      - pci17cb,1101  # QCA6390
       - pci17cb,1103  # WCN6855
 
   reg:
@@ -27,6 +28,33 @@ properties:
       string to uniquely identify variant of the calibration data for designs
       with colliding bus and device ids
 
+  vddrfacmn-supply:
+    description: VDD_RFA_CMN supply regulator handle
+
+  vddaon-supply:
+    description: VDD_AON supply regulator handle
+
+  vddwlcx-supply:
+    description: VDD_WL_CX supply regulator handle
+
+  vddwlmx-supply:
+    description: VDD_WL_MX supply regulator handle
+
+  vddrfa0p8-supply:
+    description: VDD_RFA_0P8 supply regulator handle
+
+  vddrfa1p2-supply:
+    description: VDD_RFA_1P2 supply regulator handle
+
+  vddrfa1p7-supply:
+    description: VDD_RFA_1P7 supply regulator handle
+
+  vddpcie0p9-supply:
+    description: VDD_PCIE_0P9 supply regulator handle
+
+  vddpcie1p8-supply:
+    description: VDD_PCIE_1P8 supply regulator handle
+
 required:
   - compatible
   - reg
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:01 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:01 +0100
Subject: [PATCH v5 04/18] dt-bindings: net: bluetooth: qualcomm: describe regulators for QCA6390
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-5-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

QCA6390 has a compatible listed in the bindings but is missing the
regulators description. Add the missing supply property and list the
required ones in the allOf section.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../net/bluetooth/qualcomm-bluetooth.yaml       | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/bluetooth/qualcomm-bluetooth.yaml b/Documentation/devicetree/bindings/net/bluetooth/qualcomm-bluetooth.yaml
index eba2f3026ab0..702d04cdb247 100644
--- a/Documentation/devicetree/bindings/net/bluetooth/qualcomm-bluetooth.yaml
+++ b/Documentation/devicetree/bindings/net/bluetooth/qualcomm-bluetooth.yaml
@@ -62,6 +62,9 @@ properties:
   vdddig-supply:
     description: VDD_DIG supply regulator handle
 
+  vddbtcmx-supply:
+    description: VDD_BT_CMX supply regulator handle
+
   vddbtcxmx-supply:
     description: VDD_BT_CXMX supply regulator handle
 
@@ -180,6 +183,20 @@ allOf:
         - vddrfa0p8-supply
         - vddrfa1p2-supply
         - vddrfa1p9-supply
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,qca6390-bt
+    then:
+      required:
+        - vddrfacmn-supply
+        - vddaon-supply
+        - vddbtcmx-supply
+        - vddrfa0p8-supply
+        - vddrfa1p2-supply
+        - vddrfa1p7-supply
 
 examples:
   - |
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:00 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:00 +0100
Subject: [PATCH v5 03/18] dt-bindings: regulator: describe the PMU module of the QCA6390 package
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-4-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

The QCA6390 package contains discreet modules for WLAN and Bluetooth. They
are powered by the Power Management Unit (PMU) that takes inputs from the
host and provides LDO outputs. This document describes this module.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../bindings/regulator/qcom,qca6390-pmu.yaml  | 166 ++++++++++++++++++
 1 file changed, 166 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml

diff --git a/Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml b/Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml
new file mode 100644
index 000000000000..b71fa782fc63
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml
@@ -0,0 +1,166 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/qcom,qca6390-pmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. QCA6390 PMU Regulators
+
+maintainers:
+  - Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
+
+description:
+  The QCA6390 package contains discreet modules for WLAN and Bluetooth. They
+  are powered by the Power Management Unit (PMU) that takes inputs from the
+  host and provides LDO outputs. This document describes this module.
+
+properties:
+  compatible:
+    const: qcom,qca6390-pmu
+
+  vddaon-supply:
+    description: VDD_AON supply regulator handle
+
+  vddpmu-supply:
+    description: VDD_PMU supply regulator handle
+
+  vddrfa0p95-supply:
+    description: VDD_RFA_0P95 supply regulator handle
+
+  vddrfa1p3-supply:
+    description: VDD_RFA_1P3 supply regulator handle
+
+  vddrfa1p9-supply:
+    description: VDD_RFA_1P9 supply regulator handle
+
+  vddpcie1p3-supply:
+    description: VDD_PCIE_1P3 supply regulator handle<S-Del>
+
+  vddpcie1p9-supply:
+    description: VDD_PCIE_1P9 supply regulator handle
+
+  vddio-supply:
+    description: VDD_IO supply regulator handle
+
+  wlan-enable-gpios:
+    maxItems: 1
+    description:
+      GPIO line enabling the ATH11K WLAN module supplied by the PMU
+
+  bt-enable-gpios:
+    maxItems: 1
+    description:
+      GPIO line enabling the ATH11K Bluetooth module supplied by the PMU
+
+  regulators:
+    type: object
+    description:
+      LDO outputs of the PMU
+
+    patternProperties:
+      "^ldo[0-9]$":
+        $ref: regulator.yaml#
+        type: object
+        unevaluatedProperties: false
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - vddaon-supply
+  - vddpmu-supply
+  - vddrfa0p95-supply
+  - vddrfa1p3-supply
+  - vddrfa1p9-supply
+  - vddpcie1p3-supply
+  - vddpcie1p9-supply
+  - vddio-supply
+  - wlan-enable-gpios
+  - bt-enable-gpios
+  - regulators
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    pmu {
+        compatible = "qcom,qca6390-pmu";
+
+        pinctrl-names = "default";
+        pinctrl-0 = <&bt_en_state>, <&wlan_en_state>;
+
+        vddaon-supply = <&vreg_s6a_0p95>;
+        vddpmu-supply = <&vreg_s2f_0p95>;
+        vddrfa0p95-supply = <&vreg_s2f_0p95>;
+        vddrfa1p3-supply = <&vreg_s8c_1p3>;
+        vddrfa1p9-supply = <&vreg_s5a_1p9>;
+        vddpcie1p3-supply = <&vreg_s8c_1p3>;
+        vddpcie1p9-supply = <&vreg_s5a_1p9>;
+        vddio-supply = <&vreg_s4a_1p8>;
+
+        wlan-enable-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
+        bt-enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+
+        regulators {
+            vreg_pmu_rfa_cmn: ldo0 {
+                regulator-name = "vreg_pmu_rfa_cmn";
+                regulator-min-microvolt = <760000>;
+                regulator-max-microvolt = <840000>;
+            };
+
+            vreg_pmu_aon_0p59: ldo1 {
+                regulator-name = "vreg_pmu_aon_0p59";
+                regulator-min-microvolt = <540000>;
+                regulator-max-microvolt = <840000>;
+            };
+
+            vreg_pmu_wlcx_0p8: ldo2 {
+                regulator-name = "vreg_pmu_wlcx_0p8";
+                regulator-min-microvolt = <760000>;
+                regulator-max-microvolt = <840000>;
+            };
+
+            vreg_pmu_wlmx_0p85: ldo3 {
+                regulator-name = "vreg_pmu_wlmx_0p85";
+                regulator-min-microvolt = <810000>;
+                regulator-max-microvolt = <890000>;
+            };
+
+            vreg_pmu_btcmx_0p85: ldo4 {
+                regulator-name = "vreg_pmu_btcmx_0p85";
+                regulator-min-microvolt = <810000>;
+                regulator-max-microvolt = <890000>;
+            };
+
+            vreg_pmu_rfa_0p8: ldo5 {
+                regulator-name = "vreg_pmu_rfa_0p8";
+                regulator-min-microvolt = <760000>;
+                regulator-max-microvolt = <840000>;
+            };
+
+            vreg_pmu_rfa_1p2: ldo6 {
+                regulator-name = "vreg_pmu_rfa_1p2";
+                regulator-min-microvolt = <1187000>;
+                regulator-max-microvolt = <1313000>;
+            };
+
+            vreg_pmu_rfa_1p7: ldo7 {
+                regulator-name = "vreg_pmu_rfa_1p7";
+                regulator-min-microvolt = <1710000>;
+                regulator-max-microvolt = <1890000>;
+            };
+
+            vreg_pmu_pcie_0p9: ldo8 {
+                regulator-name = "vreg_pmu_pcie_0p9";
+                regulator-min-microvolt = <870000>;
+                regulator-max-microvolt = <970000>;
+            };
+
+            vreg_pmu_pcie_1p8: ldo9 {
+                regulator-name = "vreg_pmu_pcie_1p8";
+                regulator-min-microvolt = <1710000>;
+                regulator-max-microvolt = <1890000>;
+            };
+        };
+    };
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:31:57 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:31:57 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and add first users
Message-ID: <20240216203215.40870-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

First, I'd like to apologize for the somewhat chaotic previous iterations
of this series and improper versioning which was rightfully pointed out
to me. I figured that the scope changed so much that it didn't make sense
to consider previous submissions part of the same series as the original
RFC but others thought otherwise so this one becomes v5 and I'll keep the
versioning going forward.

This is the summary of the work so far:

v1: Original RFC:

https://lore.kernel.org/lkml/20240104130123.37115-1-brgl at bgdev.pl/T/

v2: First real patch series (should have been PATCH v2) adding what I
    referred to back then as PCI power sequencing:

https://lore.kernel.org/linux-arm-kernel/2024021413-grumbling-unlivable-c145 at gregkh/T/

v3: RFC for the DT representation of the PMU supplying the WLAN and BT
    modules inside the QCA6391 package (was largely separate from the
    series but probably should have been called PATCH or RFC v3):

https://lore.kernel.org/all/CAMRc=Mc+GNoi57eTQg71DXkQKjdaoAmCpB=h2ndEpGnmdhVV-Q at mail.gmail.com/T/

v4: Second attempt at the full series with changed scope (introduction of
    the pwrseq subsystem, should have been RFC v4)

https://lore.kernel.org/lkml/20240201155532.49707-1-brgl at bgdev.pl/T/

===

With that out of the way, I'd like to get down to explaining the two
problems I'm trying to solve.

Problem statement #1: Dynamic bus chicken-and-egg problem.

Certain on-board PCI devices need to be powered up before they are can be
detected but their PCI drivers won't get bound until the device is
powered-up so enabling the relevant resources in the PCI device driver
itself is impossible.

Problem statement #2: Sharing inter-dependent resources between devices.

Certain devices that use separate drivers (often on different busses)
share resources (regulators, clocks, etc.). Typically these resources
are reference-counted but in some cases there are additional interactions
between them to consider, for example specific power-up sequence timings.

===

The reason for tackling both of these problems in a single series is the
fact the the platform I'm working on - Qualcomm RB5 - deals with both and
both need to be addressed in order to enable WLAN and Bluetooth support
upstream.

The on-board WLAN/BT package - QCA6391 - has a Power Management Unit that
takes inputs from the host and exposes LDO outputs consumed by the BT and
WLAN modules which can be powered-up and down independently. However
a delay of 100ms must be respected between enabling the BT- and
WLAN-enable GPIOs[*].

===

This series is logically split into several sections. I'll go
patch-by-patch and explain each step.

Patch 1/18:

This is a commit taken from the list by Jonathan Cameron that adds
a __free() helper for OF nodes. Not strictly related to the series but
until said commit ends in next, I need to carry it with this series.

Patch 2/18:

This enables the ath12k PCI module in arm64 defconfig as Qualcomm sm8650
and sm8550 reference platforms use it in the WCN7850 module.

Patches 3/18-6/18:

These contain all relevant DT bindings changes. We add new documents for
the QCA6390 PMU and ATH12K devices as well as extend the bindings for the
Qualcomm Bluetooth and ATH11K modules with regulators used by them in
QCA6390.

Patches 7/18-9/18:

These contain changes to device-tree sources for the three platforms we
work with in this series. As the WCN7850 module doesn't require any
specific timings introducing dependencies between the Bluetooth and WLAN
modules, while the QCA6390 does, we take two different approaches to how
me model them in DT.

For WCN7850 we hide the existence of the PMU as modeling it is simply not
necessary. The BT and WLAN devices on the device-tree are represented as
consuming the inputs (relevant to the functionality of each) of the PMU
directly.

For QCA6390 on RB5 we add the PMU node as a platform device. It consumes
regulators and GPIOs from the host and exposed regulators consumer in turn
by the BT and WLAN modules. This represents the internal structure of the
package.

Patches 10/18-14/18:

These contain the bulk of the PCI changes for this series. We introduce
a simple framework for powering up PCI devices before detecting them on
the bus and the first user of this library in the form of the WCN7850 PCI
power control driver.

The general approach is as follows: PCI devices that need special
treatment before they can be powered up, scanned and bound to their PCI
drivers must be described on the device-tree as child nodes of the PCI
port node. These devices will be instantiated on the platform bus. They
will in fact be generic platform devices with the compatible of the form
used for PCI devices already upstream ("pci<vendor ID>,<device ID">). We
add a new directory under drivers/pci/pwrctl/ that contains PCI pwrctl
drivers. These drivers are platform drivers that will now be matched
against the devices instantiated from port children just like any other
platform pairs.

Both the power control platform device *AND* the associated PCI device
reuse the same OF node and have access to the same properties. The goal
of the platform driver is to request and bring up any required resources
and let the pwrctl framework know that it's now OK to rescan the bus and
detect the devices. When the device is bound, we are notified about it
by the PCI bus notifier event and can establish a device link between the
power control device and the PCI device so that any future extension for
power-management will already be able to work with the correct hierachy.

The reusing of the OF node is the reason for the small changes to the PCI
OF core: as the bootloader can possibly leave the relevant regulators on
before booting linux, the PCI device can be detected before its platform
abstraction is probed. In this case, we find that device first and mark
its OF node as reused. The pwrctl framework handles the opposite case
(when the PCI device is detected only after the platform driver
successfully enabled it).

Patches 15/18-16/18:

These add a relatively simple power sequencing subsystem and the first
driver using it: the pwrseq module for the QCA6390 PMU.

For the record: Bjorn suggested a different solution: a regulator driver
that would - based on which regulators are enabled by a consumer - enable
relevant resources (drive the enable GPIOs) while respecting the
HW-specific delays. This would however require significant and yet
unprecised changed to the regulator subsystem as well as be an abuse of
the regulator provider API akin to using the reset framework for power
sequencing as proposed before.

Instead I'm proposing to add a subsystem that allows different devices to
use a shared power sequence split into consumer-specific as well as
common "units".

A power sequence provider driver registers a set of units with pwrseq
core. Each unit can be enabled and disabled and contains an optional list
of other units which must be enabled before it itself can be. A unit
represents a discreet chunk of the power sequence.

It also registers a list of targets: a target is an abstraction wrapping
a unit which allows consumers to tell pwrseq which unit they want to
reach. Real-life example is the driver we're adding here: there's a set
of common regulators, two PCIe-specific ones and two enable GPIOs: one
for Bluetooth and one for WLAN.

The Bluetooth driver requests a descriptor to the power sequencer and
names the target it wants to reach:

    pwrseq = devm_pwrseq_get(dev, "bluetooth");

The pwrseq core then knows that when the driver calls:

    pwrseq_power_on(pwrseq);

It must enable the "bluetooth-enable" unit but it depends on the
"regulators-common" unit so this one is enabled first. The provider
driver is also in charge of assuring an appropriate delay between
enabling the BT and WLAN enable GPIOs. The WLAN-specific resources are
handled by the "wlan-enable" unit and so are not enabled until the WLAN
driver requests the "wlan" target to be powered on.

Another thing worth discussing is the way we associate the consumer with
the relevant power sequencer. DT maintainers have expressed a discontent
with the existing mmc pwrseq bindings and have NAKed an earlier
initiative to introduce global pwrseq bindings to the kernel[1].

In this approach, we model the existing regulators and GPIOs in DT but
the pwrseq subsystem requires each provider to provide a .match()
callback. Whenever a consumer requests a power sequencer handle, we
iterate over the list of pwrseq drivers and call .match() for each. It's
up to the driver to verify in a platform-specific way whether it deals
with its consumer and let the core pwrseq code know.

The advantage of this over reusing the regulator or reset subsystem is
that it's more generalized and can handle resources of all kinds as well
as deal with any kind of power-on sequences: for instance, Qualcomm has
a PCI switch they want a driver for but this switch requires enabling
some resources first (PCI pwrctl) and then configuring the device over
I2C (which can be handled by the pwrseq provider).

Patch 17/18:

This patch makes the Qualcomm Bluetooth driver get and use the power
sequencer for QCA6390.

Patch 18/18:

While tiny, this patch is possibly the highlight of the entire series.
It uses the two abstraction layers we introduced before to create an
elegant power sequencing PCI power control driver and supports the ath11k
module on QCA6390.

With this series we can now enable BT and WLAN on several new Qualcomm
boards upstream.

I tested the series on RB5 while Neil tested it on sm8650-qrd and
sm8550-qrd.

Best Regards,
Bartosz Golaszewski

It's hard to list the changes between versions here as the scope changed
significantly between each iteration and some versions were not even full
series but rather RFCs for parts of the solution. For this reason, I'll
only start listing changes starting from v6.

[*] This is what the docs say. In practice it seems that this delay can be
ignored. However the subsequent model - QCA6490 - *does* require users to
respect it, so the problem remains valid.

[1] https://lore.kernel.org/netdev/20210829131305.534417-1-dmitry.baryshkov at linaro.org/

Bartosz Golaszewski (15):
  arm64: defconfig: enable ath12k as a module
  dt-bindings: regulator: describe the PMU module of the QCA6390 package
  dt-bindings: net: bluetooth: qualcomm: describe regulators for QCA6390
  dt-bindings: new: wireless: qcom,ath11k: describe the ath11k on
    QCA6390
  dt-bindings: new: wireless: describe the ath12k PCI module
  arm64: dts: qcom: qrb5165-rb5: model the PMU of the QCA6391
  PCI: hold the rescan mutex when scanning for the first time
  PCI/pwrctl: reuse the OF node for power controlled devices
  PCI/pwrctl: create platform devices for child OF nodes of the port
    node
  PCI/pwrctl: add PCI power control core code
  PCI/pwrctl: add a power control driver for WCN7850
  power: sequencing: implement the pwrseq core
  power: pwrseq: add a driver for the QCA6390 PMU module
  Bluetooth: qca: use the power sequencer for QCA6390
  PCI/pwrctl: add a PCI power control driver for power sequenced devices

Jonathan Cameron (1):
  of: Add cleanup.h based auto release via __free(device_node) markings.

Neil Armstrong (2):
  arm64: dts: qcom: sm8550-qrd: add the Wifi node
  arm64: dts: qcom: sm8650-qrd: add the Wifi node

 .../net/bluetooth/qualcomm-bluetooth.yaml     |   17 +
 .../net/wireless/qcom,ath11k-pci.yaml         |   28 +
 .../net/wireless/qcom,ath12k-pci.yaml         |  103 ++
 .../bindings/regulator/qcom,qca6390-pmu.yaml  |  166 +++
 MAINTAINERS                                   |    8 +
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts      |  123 +-
 arch/arm64/boot/dts/qcom/sm8250.dtsi          |   10 +
 arch/arm64/boot/dts/qcom/sm8550-qrd.dts       |   37 +
 arch/arm64/boot/dts/qcom/sm8550.dtsi          |   10 +
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts       |   29 +
 arch/arm64/boot/dts/qcom/sm8650.dtsi          |   10 +
 arch/arm64/configs/defconfig                  |    1 +
 drivers/bluetooth/hci_qca.c                   |   31 +
 drivers/pci/Kconfig                           |    1 +
 drivers/pci/Makefile                          |    1 +
 drivers/pci/bus.c                             |    9 +-
 drivers/pci/of.c                              |   14 +-
 drivers/pci/probe.c                           |    2 +
 drivers/pci/pwrctl/Kconfig                    |   25 +
 drivers/pci/pwrctl/Makefile                   |    7 +
 drivers/pci/pwrctl/core.c                     |  136 +++
 drivers/pci/pwrctl/pci-pwrctl-pwrseq.c        |   84 ++
 drivers/pci/pwrctl/pci-pwrctl-wcn7850.c       |  202 ++++
 drivers/pci/remove.c                          |    2 +
 drivers/power/Kconfig                         |    1 +
 drivers/power/Makefile                        |    1 +
 drivers/power/sequencing/Kconfig              |   28 +
 drivers/power/sequencing/Makefile             |    6 +
 drivers/power/sequencing/core.c               | 1065 +++++++++++++++++
 drivers/power/sequencing/pwrseq-qca6390.c     |  353 ++++++
 include/linux/of.h                            |    2 +
 include/linux/pci-pwrctl.h                    |   51 +
 include/linux/pwrseq/consumer.h               |   56 +
 include/linux/pwrseq/provider.h               |   75 ++
 34 files changed, 2678 insertions(+), 16 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
 create mode 100644 Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml
 create mode 100644 drivers/pci/pwrctl/Kconfig
 create mode 100644 drivers/pci/pwrctl/Makefile
 create mode 100644 drivers/pci/pwrctl/core.c
 create mode 100644 drivers/pci/pwrctl/pci-pwrctl-pwrseq.c
 create mode 100644 drivers/pci/pwrctl/pci-pwrctl-wcn7850.c
 create mode 100644 drivers/power/sequencing/Kconfig
 create mode 100644 drivers/power/sequencing/Makefile
 create mode 100644 drivers/power/sequencing/core.c
 create mode 100644 drivers/power/sequencing/pwrseq-qca6390.c
 create mode 100644 include/linux/pci-pwrctl.h
 create mode 100644 include/linux/pwrseq/consumer.h
 create mode 100644 include/linux/pwrseq/provider.h

-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:31:58 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:31:58 +0100
Subject: [PATCH v5 01/18] of: Add cleanup.h based auto release via __free(device_node) markings.
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-2-brgl@bgdev.pl>

From: Jonathan Cameron <Jonathan.Cameron at huawei.com>

The recent addition of scope based cleanup support to the kernel
provides a convenient tool to reduce the chances of leaking reference
counts where of_node_put() should have been called in an error path.

This enables
	struct device_node *child __free(device_node) = NULL;

	for_each_child_of_node(np, child) {
		if (test)
			return test;
	}

with no need for a manual call of of_node_put().
A following patch will reduce the scope of the child variable to the
for loop, to avoid an issues with ordering of autocleanup, and make it
obvious when this assigned a non NULL value.

In this simple example the gains are small but there are some very
complex error handling cases buried in these loops that will be
greatly simplified by enabling early returns with out the need
for this manual of_node_put() call.

Note that there are coccinelle checks in
scripts/coccinelle/iterators/for_each_child.cocci to detect a failure
to call of_node_put(). This new approach does not cause false positives.
Longer term we may want to add scripting to check this new approach is
done correctly with no double of_node_put() calls being introduced due
to the auto cleanup. It may also be useful to script finding places
this new approach is useful.

Signed-off-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 include/linux/of.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index 331e05918f11..8df240214db1 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -13,6 +13,7 @@
  */
 #include <linux/types.h>
 #include <linux/bitops.h>
+#include <linux/cleanup.h>
 #include <linux/errno.h>
 #include <linux/kobject.h>
 #include <linux/mod_devicetable.h>
@@ -134,6 +135,7 @@ static inline struct device_node *of_node_get(struct device_node *node)
 }
 static inline void of_node_put(struct device_node *node) { }
 #endif /* !CONFIG_OF_DYNAMIC */
+DEFINE_FREE(device_node, struct device_node *, if (_T) of_node_put(_T))
 
 /* Pointer for first entry in chain of all nodes. */
 extern struct device_node *of_root;
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:03 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:03 +0100
Subject: [PATCH v5 06/18] dt-bindings: new: wireless: describe the ath12k PCI module
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-7-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Add device-tree bindings for the ATH12K module found in the WCN7850
package.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../net/wireless/qcom,ath12k-pci.yaml         | 103 ++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml

diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
new file mode 100644
index 000000000000..063c576b99a0
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2024 Linaro Limited
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/wireless/qcom,ath12k-pci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies ath12k wireless devices (PCIe)
+
+maintainers:
+  - Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
+
+description: |
+  Qualcomm Technologies IEEE 802.11ax PCIe devices
+
+properties:
+  compatible:
+    enum:
+      - pci17cb,1107  # WCN7850
+
+  reg:
+    maxItems: 1
+
+  enable-gpios:
+    maxItems: 1
+    description: GPIO line enabling the WLAN module
+
+  vdd-supply:
+    description: VDD supply regulator handle
+
+  vddio-supply:
+    description: VDD_IO supply regulator handle
+
+  vddio1p2-supply:
+    description: VDD_IO_1P2 supply regulator handle
+
+  vddaon-supply:
+    description: VDD_AON supply regulator handle
+
+  vdddig-supply:
+    description: VDD_DIG supply regulator handle
+
+  vddrfa1p2-supply:
+    description: VDD_RFA_1P2 supply regulator handle
+
+  vddrfa1p8-supply:
+    description: VDD_PCIE_1P8 supply regulator handle
+
+  clocks:
+    maxItems: 1
+    description:
+      Reference clock phandle
+
+required:
+  - compatible
+  - reg
+  - vdd-supply
+  - vddio-supply
+  - vddaon-supply
+  - vdddig-supply
+  - vddrfa1p2-supply
+  - vddrfa1p8-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    #include <dt-bindings/gpio/gpio.h>
+    pcie {
+        #address-cells = <3>;
+        #size-cells = <2>;
+
+        pcie at 0 {
+            device_type = "pci";
+            reg = <0x0 0x0 0x0 0x0 0x0>;
+            #address-cells = <3>;
+            #size-cells = <2>;
+            ranges;
+
+            bus-range = <0x01 0xff>;
+
+            wifi at 0 {
+                compatible = "pci17cb,1107";
+                reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+                pinctrl-names = "default";
+                pinctrl-0 = <&wlan_en>;
+
+                enable-gpios = <&tlmm 16 GPIO_ACTIVE_HIGH>;
+
+                vdd-supply = <&vreg_s4i_0p85>;
+                vddio-supply = <&vreg_l15b_1p8>;
+                vddio1p2-supply = <&vreg_l3c_1p2>;
+                vddaon-supply = <&vreg_s2c_0p8>;
+                vdddig-supply = <&vreg_s3c_0p9>;
+                vddrfa1p2-supply = <&vreg_s1c_1p2>;
+                vddrfa1p8-supply = <&vreg_s6c_1p8>;
+
+                clocks = <&rpmhcc RPMH_RF_CLK1>;
+            };
+        };
+    };
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:31:59 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:31:59 +0100
Subject: [PATCH v5 02/18] arm64: defconfig: enable ath12k as a module
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-3-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Build the ath12k driver as a module for arm64 default config.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index b8adb28185ad..23d6bb156cbc 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -409,6 +409,7 @@ CONFIG_WCN36XX=m
 CONFIG_ATH11K=m
 CONFIG_ATH11K_AHB=m
 CONFIG_ATH11K_PCI=m
+CONFIG_ATH12K=m
 CONFIG_BRCMFMAC=m
 CONFIG_MWIFIEX=m
 CONFIG_MWIFIEX_SDIO=m
-- 
2.40.1



From andersson at kernel.org  Fri Feb 16 12:33:16 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Fri, 16 Feb 2024 14:33:16 -0600
Subject: [PATCH 1/3] dt-bindings: mfd: qcom,spmi-pmic: Add pbs to SPMI
 device types
In-Reply-To: <20240205-pmi632-ppg-v1-1-e236c95a2099@fairphone.com>
References: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
 <20240205-pmi632-ppg-v1-1-e236c95a2099@fairphone.com>
Message-ID: <zaqjoyucfohfdqlkkjdwh3ggakmvgir7na5s7egorbcxdpvsit@oxmlh7jhjo4x>

On Mon, Feb 05, 2024 at 10:51:38AM +0100, Luca Weiss wrote:
> Add the PBS (Programmable Boot Sequencer) to the list of devices.
> 
> Signed-off-by: Luca Weiss <luca.weiss at fairphone.com>

Reviewed-by: Bjorn Andersson <andersson at kernel.org>

Regards,
Bjorn

> ---
>  Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
> index 8103fb61a16c..b7f01cbb8fff 100644
> --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
> +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
> @@ -160,6 +160,10 @@ patternProperties:
>      type: object
>      $ref: /schemas/nvmem/qcom,spmi-sdam.yaml#
>  
> +  "^pbs@[0-9a-f]+$":
> +    type: object
> +    $ref: /schemas/soc/qcom/qcom,pbs.yaml#
> +
>    "phy@[0-9a-f]+$":
>      type: object
>      $ref: /schemas/phy/qcom,snps-eusb2-repeater.yaml#
> 
> -- 
> 2.43.0
> 


From brgl at bgdev.pl  Fri Feb 16 12:32:06 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:06 +0100
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of the QCA6391
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-10-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Add a node for the PMU module of the QCA6391 present on the RB5 board.
Assign its LDO power outputs to the existing Bluetooth module. Add a
node for the PCIe port to sm8250.dtsi and define the WLAN node on it in
the board's .dts and also make it consume the power outputs of the PMU.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 123 +++++++++++++++++++++--
 arch/arm64/boot/dts/qcom/sm8250.dtsi     |  10 ++
 2 files changed, 122 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index cd0db4f31d4a..3331a3e5aaa8 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -108,6 +108,87 @@ lt9611_3v3: lt9611-3v3 {
 		regulator-always-on;
 	};
 
+	qca6390-pmu {
+		compatible = "qcom,qca6390-pmu";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_en_state>, <&wlan_en_state>;
+
+		vddaon-supply = <&vreg_s6a_0p95>;
+		vddpmu-supply = <&vreg_s2f_0p95>;
+		vddrfa0p95-supply = <&vreg_s2f_0p95>;
+		vddrfa1p3-supply = <&vreg_s8c_1p3>;
+		vddrfa1p9-supply = <&vreg_s5a_1p9>;
+		vddpcie1p3-supply = <&vreg_s8c_1p3>;
+		vddpcie1p9-supply = <&vreg_s5a_1p9>;
+		vddio-supply = <&vreg_s4a_1p8>;
+
+		wlan-enable-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
+		bt-enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+
+		regulators {
+			vreg_pmu_rfa_cmn: ldo0 {
+				regulator-name = "vreg_pmu_rfa_cmn";
+				regulator-min-microvolt = <760000>;
+				regulator-max-microvolt = <840000>;
+			};
+
+			vreg_pmu_aon_0p59: ldo1 {
+				regulator-name = "vreg_pmu_aon_0p59";
+				regulator-min-microvolt = <540000>;
+				regulator-max-microvolt = <840000>;
+			};
+
+			vreg_pmu_wlcx_0p8: ldo2 {
+				regulator-name = "vreg_pmu_wlcx_0p8";
+				regulator-min-microvolt = <760000>;
+				regulator-max-microvolt = <840000>;
+			};
+
+			vreg_pmu_wlmx_0p85: ldo3 {
+				regulator-name = "vreg_pmu_wlmx_0p85";
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <890000>;
+			};
+
+			vreg_pmu_btcmx_0p85: ldo4 {
+				regulator-name = "vreg_pmu_btcmx_0p85";
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <890000>;
+			};
+
+			vreg_pmu_rfa_0p8: ldo5 {
+				regulator-name = "vreg_pmu_rfa_0p8";
+				regulator-min-microvolt = <760000>;
+				regulator-max-microvolt = <840000>;
+			};
+
+			vreg_pmu_rfa_1p2: ldo6 {
+				regulator-name = "vreg_pmu_rfa_1p2";
+				regulator-min-microvolt = <1187000>;
+				regulator-max-microvolt = <1313000>;
+			};
+
+			vreg_pmu_rfa_1p7: ldo7 {
+				regulator-name = "vreg_pmu_rfa_1p7";
+				regulator-min-microvolt = <1710000>;
+				regulator-max-microvolt = <1890000>;
+			};
+
+			vreg_pmu_pcie_0p9: ldo8 {
+				regulator-name = "vreg_pmu_pcie_0p9";
+				regulator-min-microvolt = <870000>;
+				regulator-max-microvolt = <970000>;
+			};
+
+			vreg_pmu_pcie_1p8: ldo9 {
+				regulator-name = "vreg_pmu_pcie_1p8";
+				regulator-min-microvolt = <1710000>;
+				regulator-max-microvolt = <1890000>;
+			};
+		};
+	};
+
 	thermal-zones {
 		conn-thermal {
 			polling-delay-passive = <0>;
@@ -734,6 +815,23 @@ &pcie0_phy {
 	vdda-pll-supply = <&vreg_l9a_1p2>;
 };
 
+&pcieport0 {
+	wifi at 0 {
+		compatible = "pci17cb,1101";
+		reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+		vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+		vddaon-supply = <&vreg_pmu_aon_0p59>;
+		vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+		vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+		vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+		vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+		vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
+		vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+		vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+	};
+};
+
 &pcie1 {
 	status = "okay";
 };
@@ -1303,6 +1401,14 @@ sdc2_card_det_n: sd-card-det-n-state {
 		function = "gpio";
 		bias-pull-up;
 	};
+
+	wlan_en_state: wlan-default-state {
+		pins = "gpio20";
+		function = "gpio";
+		drive-strength = <16>;
+		output-low;
+		bias-pull-up;
+	};
 };
 
 &uart6 {
@@ -1311,17 +1417,12 @@ &uart6 {
 	bluetooth {
 		compatible = "qcom,qca6390-bt";
 
-		pinctrl-names = "default";
-		pinctrl-0 = <&bt_en_state>;
-
-		enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
-
-		vddio-supply = <&vreg_s4a_1p8>;
-		vddpmu-supply = <&vreg_s2f_0p95>;
-		vddaon-supply = <&vreg_s6a_0p95>;
-		vddrfa0p9-supply = <&vreg_s2f_0p95>;
-		vddrfa1p3-supply = <&vreg_s8c_1p3>;
-		vddrfa1p9-supply = <&vreg_s5a_1p9>;
+		vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+		vddaon-supply = <&vreg_pmu_aon_0p59>;
+		vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>;
+		vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+		vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+		vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
 	};
 };
 
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index f3c70b87efad..29d2ccb5b389 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -2203,6 +2203,16 @@ pcie0: pcie at 1c00000 {
 			dma-coherent;
 
 			status = "disabled";
+
+			pcieport0: pcie at 0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+
+				bus-range = <0x01 0xff>;
+			};
 		};
 
 		pcie0_phy: phy at 1c06000 {
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:04 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:04 +0100
Subject: [PATCH v5 07/18] arm64: dts: qcom: sm8550-qrd: add the Wifi node
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-8-brgl@bgdev.pl>

From: Neil Armstrong <neil.armstrong at linaro.org>

Describe the ath12k WLAN on-board the WCN7850 module present on the
board.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
[Bartosz:
  - move the pcieport0 node into the .dtsi
  - make regulator naming consistent with existing DT code
  - add commit message]
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 arch/arm64/boot/dts/qcom/sm8550-qrd.dts | 37 +++++++++++++++++++++++++
 arch/arm64/boot/dts/qcom/sm8550.dtsi    | 10 +++++++
 2 files changed, 47 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
index 92f015017418..67bd11e82abd 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
@@ -824,6 +824,25 @@ &pcie0 {
 	status = "okay";
 };
 
+&pcieport0 {
+	wifi at 0 {
+		compatible = "pci17cb,1107";
+		reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_en>, <&pmk8550_sleep_clk>;
+
+		enable-gpios = <&tlmm 80 GPIO_ACTIVE_HIGH>;
+
+		vdd-supply = <&vreg_s5g_0p85>;
+		vddio-supply = <&vreg_l15b_1p8>;
+		vddaon-supply = <&vreg_s2g_0p85>;
+		vdddig-supply = <&vreg_s4e_0p95>;
+		vddrfa1p2-supply = <&vreg_s4g_1p25>;
+		vddrfa1p8-supply = <&vreg_s6g_1p86>;
+	};
+};
+
 &pcie0_phy {
 	vdda-phy-supply = <&vreg_l1e_0p88>;
 	vdda-pll-supply = <&vreg_l3e_1p2>;
@@ -911,6 +930,17 @@ &pcie_1_phy_aux_clk {
 	clock-frequency = <1000>;
 };
 
+&pmk8550_gpios {
+	pmk8550_sleep_clk: sleep-clk-state {
+		pins = "gpio3";
+		function = "func1";
+		input-disable;
+		output-enable;
+		bias-disable;
+		power-source = <0>;
+	};
+};
+
 &qupv3_id_0 {
 	status = "okay";
 };
@@ -1084,6 +1114,13 @@ wcd_default: wcd-reset-n-active-state {
 		bias-disable;
 		output-low;
 	};
+
+	wlan_en: wlan-en-state {
+		pins = "gpio80";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-pull-down;
+	};
 };
 
 &uart7 {
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
index 9a545087d70e..5fcf8d5ac084 100644
--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
@@ -1767,6 +1767,16 @@ pcie0: pcie at 1c00000 {
 			phy-names = "pciephy";
 
 			status = "disabled";
+
+			pcieport0: pcie at 0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+
+				bus-range = <0x01 0xff>;
+			};
 		};
 
 		pcie0_phy: phy at 1c06000 {
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:09 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:09 +0100
Subject: [PATCH v5 12/18] PCI/pwrctl: create platform devices for child OF nodes of the port node
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-13-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

In preparation for introducing PCI device power control - a set of
library functions that will allow powering-up of PCI devices before
they're detected on the PCI bus - we need to populate the devices
defined on the device-tree.

We are reusing the platform bus as it provides us with all the
infrastructure we need to match the pwrctl drivers against the
compatibles from OF nodes.

These platform devices will be probed by the driver core and bound to
the PCI pwrctl drivers we'll introduce later.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/pci/bus.c    | 9 ++++++++-
 drivers/pci/remove.c | 2 ++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 826b5016a101..17ab41094c4e 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -12,6 +12,7 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/proc_fs.h>
 #include <linux/slab.h>
 
@@ -342,8 +343,14 @@ void pci_bus_add_device(struct pci_dev *dev)
 	 */
 	pcibios_bus_add_device(dev);
 	pci_fixup_device(pci_fixup_final, dev);
-	if (pci_is_bridge(dev))
+	if (pci_is_bridge(dev)) {
 		of_pci_make_dev_node(dev);
+		retval = of_platform_populate(dev->dev.of_node, NULL, NULL,
+					      &dev->dev);
+		if (retval)
+			pci_err(dev, "failed to populate child OF nodes (%d)\n",
+				retval);
+	}
 	pci_create_sysfs_dev_files(dev);
 	pci_proc_attach_device(dev);
 	pci_bridge_d3_update(dev);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index d749ea8250d6..fc9db2805888 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/pci.h>
 #include <linux/module.h>
+#include <linux/of_platform.h>
 #include "pci.h"
 
 static void pci_free_resources(struct pci_dev *dev)
@@ -22,6 +23,7 @@ static void pci_stop_dev(struct pci_dev *dev)
 		device_release_driver(&dev->dev);
 		pci_proc_detach_device(dev);
 		pci_remove_sysfs_dev_files(dev);
+		of_platform_depopulate(&dev->dev);
 		of_pci_remove_node(dev);
 
 		pci_dev_assign_added(dev, false);
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:07 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:07 +0100
Subject: [PATCH v5 10/18] PCI: hold the rescan mutex when scanning for the first time
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-11-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

With the introduction of PCI device power control drivers that will be
able to trigger the port rescan when probing, we need to hold the rescan
mutex during the initial pci_host_probe() too or the two could get in
each other's way.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/pci/probe.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 467c16358f17..f8ba073ffc9b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -3066,7 +3066,9 @@ int pci_host_probe(struct pci_host_bridge *bridge)
 	struct pci_bus *bus, *child;
 	int ret;
 
+	pci_lock_rescan_remove();
 	ret = pci_scan_root_bus_bridge(bridge);
+	pci_unlock_rescan_remove();
 	if (ret < 0) {
 		dev_err(bridge->dev.parent, "Scanning root bridge failed");
 		return ret;
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:05 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:05 +0100
Subject: [PATCH v5 08/18] arm64: dts: qcom: sm8650-qrd: add the Wifi node
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-9-brgl@bgdev.pl>

From: Neil Armstrong <neil.armstrong at linaro.org>

Describe the ath12k WLAN on-board the WCN7850 module present on the
board.

Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
[Bartosz:
  - move the pcieport0 node into the .dtsi
  - make regulator naming consistent with existing DT code
  - add commit message]
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts | 29 +++++++++++++++++++++++++
 arch/arm64/boot/dts/qcom/sm8650.dtsi    | 10 +++++++++
 2 files changed, 39 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
index b07cac2e5bc8..4623c358f634 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
@@ -845,6 +845,28 @@ &pcie0 {
 	status = "okay";
 };
 
+&pcieport0 {
+	wifi at 0 {
+		compatible = "pci17cb,1107";
+		reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_en>;
+
+		enable-gpios = <&tlmm 16 GPIO_ACTIVE_HIGH>;
+
+		vdd-supply = <&vreg_s4i_0p85>;
+		vddio-supply = <&vreg_l15b_1p8>;
+		vddio1p2-supply = <&vreg_l3c_1p2>;
+		vddaon-supply = <&vreg_s2c_0p8>;
+		vdddig-supply = <&vreg_s3c_0p9>;
+		vddrfa1p2-supply = <&vreg_s1c_1p2>;
+		vddrfa1p8-supply = <&vreg_s6c_1p8>;
+
+		clocks = <&rpmhcc RPMH_RF_CLK1>;
+	};
+};
+
 &pcie0_phy {
 	vdda-phy-supply = <&vreg_l1i_0p88>;
 	vdda-pll-supply = <&vreg_l3i_1p2>;
@@ -1139,6 +1161,13 @@ wcd_default: wcd-reset-n-active-state {
 		bias-disable;
 		output-low;
 	};
+
+	wlan_en: wlan-en-state {
+		pins = "gpio16";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-pull-down;
+	};
 };
 
 &uart14 {
diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
index d488b3b3265e..baf4932e460c 100644
--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -2293,6 +2293,16 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
 			dma-coherent;
 
 			status = "disabled";
+
+			pcieport0: pcie at 0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+
+				bus-range = <0x01 0xff>;
+			};
 		};
 
 		pcie0_phy: phy at 1c06000 {
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:08 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:08 +0100
Subject: [PATCH v5 11/18] PCI/pwrctl: reuse the OF node for power controlled devices
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-12-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

With PCI power control we deal with two struct device objects bound to
two different drivers but consuming the same OF node. We must not bind
the pinctrl twice. To that end: before setting the OF node of the newly
instantiated PCI device, check if a platform device consuming the same
OF node doesn't already exist on the platform bus and - if so - mark the
PCI device as reusing the OF node.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/pci/of.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 51e3dd0ea5ab..b908fe1ae951 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -6,6 +6,7 @@
  */
 #define pr_fmt(fmt)	"PCI: OF: " fmt
 
+#include <linux/cleanup.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -13,6 +14,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
+#include <linux/platform_device.h>
 #include "pci.h"
 
 #ifdef CONFIG_PCI
@@ -25,16 +27,20 @@
  */
 int pci_set_of_node(struct pci_dev *dev)
 {
-	struct device_node *node;
-
 	if (!dev->bus->dev.of_node)
 		return 0;
 
-	node = of_pci_find_child_device(dev->bus->dev.of_node, dev->devfn);
+	struct device_node *node __free(device_node) =
+		of_pci_find_child_device(dev->bus->dev.of_node, dev->devfn);
 	if (!node)
 		return 0;
 
-	device_set_node(&dev->dev, of_fwnode_handle(node));
+	struct device *pdev __free(put_device) =
+		bus_find_device_by_of_node(&platform_bus_type, node);
+	if (pdev)
+		dev->bus->dev.of_node_reused = true;
+
+	device_set_node(&dev->dev, of_fwnode_handle(no_free_ptr(node)));
 	return 0;
 }
 
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:11 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:11 +0100
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for WCN7850
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-15-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Add a PCI power control driver that's capable of correctly powering up
the ath12k module on WCN7850 using the PCI pwrctl functionality.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/pci/pwrctl/Kconfig              |   8 +
 drivers/pci/pwrctl/Makefile             |   2 +
 drivers/pci/pwrctl/pci-pwrctl-wcn7850.c | 202 ++++++++++++++++++++++++
 3 files changed, 212 insertions(+)
 create mode 100644 drivers/pci/pwrctl/pci-pwrctl-wcn7850.c

diff --git a/drivers/pci/pwrctl/Kconfig b/drivers/pci/pwrctl/Kconfig
index 96195395af69..b91170ebfb49 100644
--- a/drivers/pci/pwrctl/Kconfig
+++ b/drivers/pci/pwrctl/Kconfig
@@ -5,4 +5,12 @@ menu "PCI Power control drivers"
 config PCI_PWRCTL
 	tristate
 
+config PCI_PWRCTL_WCN7850
+	tristate "PCI Power Control driver for WCN7850"
+	select PCI_PWRCTL
+	default m if (ATH12K && ARCH_QCOM)
+	help
+	  Enable support for the PCI power control driver for the ath12k
+	  module of the WCN7850 WLAN/BT chip.
+
 endmenu
diff --git a/drivers/pci/pwrctl/Makefile b/drivers/pci/pwrctl/Makefile
index 52ae0640ef7b..de20c3af1b78 100644
--- a/drivers/pci/pwrctl/Makefile
+++ b/drivers/pci/pwrctl/Makefile
@@ -2,3 +2,5 @@
 
 obj-$(CONFIG_PCI_PWRCTL)		+= pci-pwrctl-core.o
 pci-pwrctl-core-y			:= core.o
+
+obj-$(CONFIG_PCI_PWRCTL_WCN7850)	+= pci-pwrctl-wcn7850.o
diff --git a/drivers/pci/pwrctl/pci-pwrctl-wcn7850.c b/drivers/pci/pwrctl/pci-pwrctl-wcn7850.c
new file mode 100644
index 000000000000..e2b2c53bff29
--- /dev/null
+++ b/drivers/pci/pwrctl/pci-pwrctl-wcn7850.c
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pci-pwrctl.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+struct pci_pwrctl_wcn7850_vreg {
+	const char *name;
+	unsigned int load_uA;
+};
+
+struct pci_pwrctl_wcn7850_pdata {
+	struct pci_pwrctl_wcn7850_vreg *vregs;
+	size_t num_vregs;
+	unsigned int delay_msec;
+};
+
+struct pci_pwrctl_wcn7850_ctx {
+	struct pci_pwrctl pwrctl;
+	const struct pci_pwrctl_wcn7850_pdata *pdata;
+	struct regulator_bulk_data *regs;
+	struct gpio_desc *en_gpio;
+	struct clk *clk;
+};
+
+static struct pci_pwrctl_wcn7850_vreg pci_pwrctl_wcn7850_vregs[] = {
+	{
+		.name = "vdd",
+		.load_uA = 16000,
+	},
+	{
+		.name = "vddio",
+		.load_uA = 5000,
+	},
+	{
+		.name = "vddio1p2",
+		.load_uA = 16000,
+	},
+	{
+		.name = "vddaon",
+		.load_uA = 26000,
+	},
+	{
+		.name = "vdddig",
+		.load_uA = 126000,
+	},
+	{
+		.name = "vddrfa1p2",
+		.load_uA = 257000,
+	},
+	{
+		.name = "vddrfa1p8",
+		.load_uA = 302000,
+	},
+};
+
+static struct pci_pwrctl_wcn7850_pdata pci_pwrctl_wcn7850_of_data = {
+	.vregs = pci_pwrctl_wcn7850_vregs,
+	.num_vregs = ARRAY_SIZE(pci_pwrctl_wcn7850_vregs),
+	.delay_msec = 50,
+};
+
+static int pci_pwrctl_wcn7850_power_on(struct pci_pwrctl_wcn7850_ctx *ctx)
+{
+	int ret;
+
+	ret = regulator_bulk_enable(ctx->pdata->num_vregs, ctx->regs);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(ctx->clk);
+	if (ret)
+		return ret;
+
+	gpiod_set_value_cansleep(ctx->en_gpio, 1);
+
+	if (ctx->pdata->delay_msec)
+		msleep(ctx->pdata->delay_msec);
+
+	return 0;
+}
+
+static int pci_pwrctl_wcn7850_power_off(struct pci_pwrctl_wcn7850_ctx *ctx)
+{
+	gpiod_set_value_cansleep(ctx->en_gpio, 0);
+	clk_disable_unprepare(ctx->clk);
+
+	return regulator_bulk_disable(ctx->pdata->num_vregs, ctx->regs);
+}
+
+static void devm_pci_pwrctl_wcn7850_power_off(void *data)
+{
+	struct pci_pwrctl_wcn7850_ctx *ctx = data;
+
+	pci_pwrctl_wcn7850_power_off(ctx);
+}
+
+static int pci_pwrctl_wcn7850_probe(struct platform_device *pdev)
+{
+	struct pci_pwrctl_wcn7850_ctx *ctx;
+	struct device *dev = &pdev->dev;
+	int ret, i;
+
+	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->pdata = of_device_get_match_data(dev);
+	if (!ctx->pdata)
+		return dev_err_probe(dev, -ENODEV,
+				     "Failed to obtain platform data\n");
+
+	if (ctx->pdata->vregs) {
+		ctx->regs = devm_kcalloc(dev, ctx->pdata->num_vregs,
+					 sizeof(*ctx->regs), GFP_KERNEL);
+		if (!ctx->regs)
+			return -ENOMEM;
+
+		for (i = 0; i < ctx->pdata->num_vregs; i++)
+			ctx->regs[i].supply = ctx->pdata->vregs[i].name;
+
+		ret = devm_regulator_bulk_get(dev, ctx->pdata->num_vregs,
+					      ctx->regs);
+		if (ret < 0)
+			return dev_err_probe(dev, ret,
+					     "Failed to get all regulators\n");
+
+		for (i = 0; i < ctx->pdata->num_vregs; i++) {
+			if (!ctx->pdata->vregs[1].load_uA)
+				continue;
+
+			ret = regulator_set_load(ctx->regs[i].consumer,
+						 ctx->pdata->vregs[i].load_uA);
+			if (ret)
+				return dev_err_probe(dev, ret,
+						     "Failed to set vreg load\n");
+		}
+	}
+
+	ctx->clk = devm_clk_get_optional(dev, NULL);
+	if (IS_ERR(ctx->clk))
+		return dev_err_probe(dev, PTR_ERR(ctx->clk),
+				     "Failed to get clock\n");
+
+	ctx->en_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
+	if (IS_ERR(ctx->en_gpio))
+		return dev_err_probe(dev, PTR_ERR(ctx->en_gpio),
+				     "Failed to get enable the GPIO\n");
+
+	ret = pci_pwrctl_wcn7850_power_on(ctx);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to power on the device\n");
+
+	ret = devm_add_action_or_reset(dev, devm_pci_pwrctl_wcn7850_power_off,
+				       ctx);
+	if (ret)
+		return ret;
+
+	ctx->pwrctl.dev = dev;
+
+	ret = devm_pci_pwrctl_device_set_ready(dev, &ctx->pwrctl);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to register the pwrctl wrapper\n");
+
+	return 0;
+}
+
+static const struct of_device_id pci_pwrctl_wcn7850_of_match[] = {
+	{
+		.compatible = "pci17cb,1107",
+		.data = &pci_pwrctl_wcn7850_of_data,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pci_pwrctl_wcn7850_of_match);
+
+static struct platform_driver pci_pwrctl_wcn7850_driver = {
+	.driver = {
+		.name = "pci-pwrctl-wcn7850",
+		.of_match_table = pci_pwrctl_wcn7850_of_match,
+	},
+	.probe = pci_pwrctl_wcn7850_probe,
+};
+module_platform_driver(pci_pwrctl_wcn7850_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski at linaro.org>");
+MODULE_DESCRIPTION("PCI Power Sequencing module for WCN7850");
+MODULE_LICENSE("GPL");
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:10 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:10 +0100
Subject: [PATCH v5 13/18] PCI/pwrctl: add PCI power control core code
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-14-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Some PCI devices must be powered-on before they can be detected on the
bus. Introduce a simple framework reusing the existing PCI OF
infrastructure.

The way this works is: a DT node representing a PCI device connected to
the port can be matched against its power control platform driver. If
the match succeeds, the driver is responsible for powering-up the device
and calling pcie_pwrctl_device_set_ready() which will trigger a PCI bus
rescan as well as subscribe to PCI bus notifications.

When the device is detected and created, we'll make it consume the same
DT node that the platform device did. When the device is bound, we'll
create a device link between it and the parent power control device.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/pci/Kconfig         |   1 +
 drivers/pci/Makefile        |   1 +
 drivers/pci/pwrctl/Kconfig  |   8 +++
 drivers/pci/pwrctl/Makefile |   4 ++
 drivers/pci/pwrctl/core.c   | 136 ++++++++++++++++++++++++++++++++++++
 include/linux/pci-pwrctl.h  |  51 ++++++++++++++
 6 files changed, 201 insertions(+)
 create mode 100644 drivers/pci/pwrctl/Kconfig
 create mode 100644 drivers/pci/pwrctl/Makefile
 create mode 100644 drivers/pci/pwrctl/core.c
 create mode 100644 include/linux/pci-pwrctl.h

diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index d35001589d88..aa4d1833f442 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -296,5 +296,6 @@ source "drivers/pci/hotplug/Kconfig"
 source "drivers/pci/controller/Kconfig"
 source "drivers/pci/endpoint/Kconfig"
 source "drivers/pci/switch/Kconfig"
+source "drivers/pci/pwrctl/Kconfig"
 
 endif
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 175302036890..8ddad57934a6 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_PCI)		+= access.o bus.o probe.o host-bridge.o \
 
 obj-$(CONFIG_PCI)		+= msi/
 obj-$(CONFIG_PCI)		+= pcie/
+obj-$(CONFIG_PCI)		+= pwrctl/
 
 ifdef CONFIG_PCI
 obj-$(CONFIG_PROC_FS)		+= proc.o
diff --git a/drivers/pci/pwrctl/Kconfig b/drivers/pci/pwrctl/Kconfig
new file mode 100644
index 000000000000..96195395af69
--- /dev/null
+++ b/drivers/pci/pwrctl/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+menu "PCI Power control drivers"
+
+config PCI_PWRCTL
+	tristate
+
+endmenu
diff --git a/drivers/pci/pwrctl/Makefile b/drivers/pci/pwrctl/Makefile
new file mode 100644
index 000000000000..52ae0640ef7b
--- /dev/null
+++ b/drivers/pci/pwrctl/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_PCI_PWRCTL)		+= pci-pwrctl-core.o
+pci-pwrctl-core-y			:= core.o
diff --git a/drivers/pci/pwrctl/core.c b/drivers/pci/pwrctl/core.c
new file mode 100644
index 000000000000..11bd19519841
--- /dev/null
+++ b/drivers/pci/pwrctl/core.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pci-pwrctl.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+
+static int pci_pwrctl_notify(struct notifier_block *nb, unsigned long action,
+			     void *data)
+{
+	struct pci_pwrctl *pwrctl = container_of(nb, struct pci_pwrctl, nb);
+	struct device *dev = data;
+
+	if (dev_fwnode(dev) != dev_fwnode(pwrctl->dev))
+		return NOTIFY_DONE;
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		/*
+		 * We will have two struct device objects bound to two different
+		 * drivers on different buses but consuming the same DT node. We
+		 * must not bind the pins twice in this case but only once for
+		 * the first device to be added.
+		 *
+		 * If we got here then the PCI device is the second after the
+		 * power control platform device. Mark its OF node as reused.
+		 */
+		dev->of_node_reused = true;
+		break;
+	case BUS_NOTIFY_BOUND_DRIVER:
+		pwrctl->link = device_link_add(dev, pwrctl->dev,
+					       DL_FLAG_AUTOREMOVE_CONSUMER);
+		if (!pwrctl->link)
+			dev_err(pwrctl->dev, "Failed to add device link\n");
+		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		if (pwrctl->link)
+			device_link_del(pwrctl->link);
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+/**
+ * pci_pwrctl_device_set_ready() - Notify the pwrctl subsystem that the PCI
+ * device is powered-up and ready to be detected.
+ *
+ * @pwrctl: PCI power control data
+ *
+ * Returns:
+ * 0 on success, negative error number on error.
+ *
+ * Note:
+ * This function returning 0 doesn't mean the device was detected. It means,
+ * that the bus rescan was successfully started. The device will get bound to
+ * its PCI driver asynchronously.
+ */
+int pci_pwrctl_device_set_ready(struct pci_pwrctl *pwrctl)
+{
+	int ret;
+
+	if (!pwrctl->dev)
+		return -ENODEV;
+
+	pwrctl->nb.notifier_call = pci_pwrctl_notify;
+	ret = bus_register_notifier(&pci_bus_type, &pwrctl->nb);
+	if (ret)
+		return ret;
+
+	pci_lock_rescan_remove();
+	pci_rescan_bus(to_pci_dev(pwrctl->dev->parent)->bus);
+	pci_unlock_rescan_remove();
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_pwrctl_device_set_ready);
+
+/**
+ * pci_pwrctl_device_unset_ready() - Notify the pwrctl subsystem that the PCI
+ * device is about to be powered-down.
+ *
+ * @pwrctl: PCI power control data
+ */
+void pci_pwrctl_device_unset_ready(struct pci_pwrctl *pwrctl)
+{
+	/*
+	 * We don't have to delete the link here. Typically, this function
+	 * is only called when the power control device is being detached. If
+	 * it is being detached then the child PCI device must have already
+	 * been unbound too or the device core wouldn't let us unbind.
+	 */
+	bus_unregister_notifier(&pci_bus_type, &pwrctl->nb);
+}
+EXPORT_SYMBOL_GPL(pci_pwrctl_device_unset_ready);
+
+static void devm_pci_pwrctl_device_unset_ready(void *data)
+{
+	struct pci_pwrctl *pwrctl = data;
+
+	pci_pwrctl_device_set_ready(pwrctl);
+}
+
+/**
+ * devm_pci_pwrctl_device_set_ready - Managed variant of
+ * pci_pwrctl_device_set_ready().
+ *
+ * @pwrctl: PCI power control data
+ *
+ * Returns:
+ * 0 on success, negative error number on error.
+ */
+int devm_pci_pwrctl_device_set_ready(struct device *dev,
+				     struct pci_pwrctl *pwrctl)
+{
+	int ret;
+
+	ret = pci_pwrctl_device_set_ready(pwrctl);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev,
+					devm_pci_pwrctl_device_unset_ready,
+					pwrctl);
+}
+EXPORT_SYMBOL_GPL(devm_pci_pwrctl_device_set_ready);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski at linaro.org>");
+MODULE_DESCRIPTION("PCI Device Power Control core driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/pci-pwrctl.h b/include/linux/pci-pwrctl.h
new file mode 100644
index 000000000000..ae8324ea7eeb
--- /dev/null
+++ b/include/linux/pci-pwrctl.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#ifndef __PCI_PWRCTL_H__
+#define __PCI_PWRCTL_H__
+
+#include <linux/notifier.h>
+
+struct device;
+struct device_link;
+
+/*
+ * This is a simple framework for solving the issue of PCI devices that require
+ * certain resources (regulators, GPIOs, clocks) to be enabled before the
+ * device can actually be detected on the PCI bus.
+ *
+ * The idea is to reuse the platform bus to populate OF nodes describing the
+ * PCI device and its resources, let these platform devices probe and enable
+ * relevant resources and then trigger a rescan of the PCI bus allowing for the
+ * same device (with a second associated struct device) to be registered with
+ * the PCI subsystem.
+ *
+ * To preserve a correct hierarchy for PCI power management and device reset,
+ * we create a device link between the power control platform device (parent)
+ * and the supplied PCI device (child).
+ */
+
+/**
+ * struct pci_pwrctl - PCI device power control context.
+ * @dev - Address of the power controlling device.
+ *
+ * An object of this type must be allocated by the PCI power control device and
+ * passed to the pwrctl subsystem to trigger a bus rescan and setup a device
+ * link with the device once it's up.
+ */
+struct pci_pwrctl {
+	struct device *dev;
+
+	/* Private, don't use. */
+	struct notifier_block nb;
+	struct device_link *link;
+};
+
+int pci_pwrctl_device_set_ready(struct pci_pwrctl *pwrctl);
+void pci_pwrctl_device_unset_ready(struct pci_pwrctl *pwrctl);
+int devm_pci_pwrctl_device_set_ready(struct device *dev,
+				     struct pci_pwrctl *pwrctl);
+
+#endif /* __PCI_PWRCTL_H__ */
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:13 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:13 +0100
Subject: [PATCH v5 16/18] power: pwrseq: add a driver for the QCA6390 PMU module
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-17-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

This adds the power sequencing driver for the QCA6390's PMU module. It
uses the pwrseq subsystem and knows how to match the sequencer to the
consumer device by verifying the relevant properties and DT layout.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/power/sequencing/Kconfig          |  16 +
 drivers/power/sequencing/Makefile         |   2 +
 drivers/power/sequencing/pwrseq-qca6390.c | 353 ++++++++++++++++++++++
 3 files changed, 371 insertions(+)
 create mode 100644 drivers/power/sequencing/pwrseq-qca6390.c

diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
index ba5732b1dbf8..84ddf3b4ae56 100644
--- a/drivers/power/sequencing/Kconfig
+++ b/drivers/power/sequencing/Kconfig
@@ -10,3 +10,19 @@ menuconfig POWER_SEQUENCING
 	  during power-up.
 
 	  If unsure, say no.
+
+if POWER_SEQUENCING
+
+config POWER_SEQUENCING_QCA6390
+	tristate "QCA6390 PMU driver"
+	default m if ARCH_QCOM
+	help
+	  Say U here to enable the power sequencing driver for Qualcomm
+	  QCA6390.
+
+	  The QCA6390 package contains the BT and WLAN modules whose power
+	  is controlled by the PMU module. As the former two share the power-up
+	  sequence which is executed by the PMU, this driver is needed for
+	  correct power control.
+
+endif
diff --git a/drivers/power/sequencing/Makefile b/drivers/power/sequencing/Makefile
index dcdf8c0c159e..628345c4e7ae 100644
--- a/drivers/power/sequencing/Makefile
+++ b/drivers/power/sequencing/Makefile
@@ -2,3 +2,5 @@
 
 obj-$(CONFIG_POWER_SEQUENCING)		+= pwrseq-core.o
 pwrseq-core-y				:= core.o
+
+obj-$(CONFIG_POWER_SEQUENCING_QCA6390)	+= pwrseq-qca6390.o
diff --git a/drivers/power/sequencing/pwrseq-qca6390.c b/drivers/power/sequencing/pwrseq-qca6390.c
new file mode 100644
index 000000000000..5f254f9c71d7
--- /dev/null
+++ b/drivers/power/sequencing/pwrseq-qca6390.c
@@ -0,0 +1,353 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/jiffies.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pwrseq/provider.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+struct pwrseq_qca6390_vreg {
+	const char *name;
+	unsigned int load_uA;
+};
+
+struct pwrseq_qca6390_pdata {
+	const struct pwrseq_qca6390_vreg *vregs_common;
+	size_t num_vregs_common;
+	const struct pwrseq_qca6390_vreg *vregs_wlan;
+	size_t num_vregs_wlan;
+	unsigned int pwup_delay_msec;
+};
+
+struct pwrseq_qca6390_ctx {
+	struct pwrseq_device *pwrseq;
+	struct device_node *of_node;
+	const struct pwrseq_qca6390_pdata *pdata;
+	struct regulator_bulk_data *regs_common;
+	struct regulator_bulk_data *regs_wlan;
+	struct gpio_desc *bt_gpio;
+	struct gpio_desc *wlan_gpio;
+	unsigned long last_gpio_enable;
+};
+
+static const struct pwrseq_qca6390_vreg pwrseq_qca6390_vregs_common[] = {
+	{
+		.name = "vddio",
+		.load_uA = 20000,
+	},
+	{
+		.name = "vddaon",
+		.load_uA = 100000,
+	},
+	{
+		.name = "vddpmu",
+		.load_uA = 1250000,
+	},
+	{
+		.name = "vddrfa0p95",
+		.load_uA = 200000,
+	},
+	{
+		.name = "vddrfa1p3",
+		.load_uA = 400000,
+	},
+	{
+		.name = "vddrfa1p9",
+		.load_uA = 400000,
+	},
+};
+
+static const struct pwrseq_qca6390_vreg pwrseq_qca6390_vregs_wlan[] = {
+	{
+		.name = "vddpcie1p3",
+		.load_uA = 35000,
+	},
+	{
+		.name = "vddpcie1p9",
+		.load_uA = 15000,
+	},
+};
+
+static void pwrseq_qca6390_ensure_gpio_delay(struct pwrseq_qca6390_ctx *ctx)
+{
+	unsigned long diff_jiffies = jiffies - ctx->last_gpio_enable;
+	unsigned int diff_msecs = jiffies_to_msecs(diff_jiffies);
+
+	if (diff_msecs < 100)
+		msleep(100 - diff_msecs);
+}
+
+static const struct pwrseq_qca6390_pdata pwrseq_qca6390_of_data = {
+	.vregs_common = pwrseq_qca6390_vregs_common,
+	.num_vregs_common = ARRAY_SIZE(pwrseq_qca6390_vregs_common),
+	.vregs_wlan = pwrseq_qca6390_vregs_wlan,
+	.num_vregs_wlan = ARRAY_SIZE(pwrseq_qca6390_vregs_wlan),
+	.pwup_delay_msec = 16,
+};
+
+static int pwrseq_qca6390_vregs_enable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	return regulator_bulk_enable(ctx->pdata->num_vregs_common,
+				     ctx->regs_common);
+}
+
+static int pwrseq_qca6390_vregs_disable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	return regulator_bulk_disable(ctx->pdata->num_vregs_common,
+				      ctx->regs_common);
+}
+
+static const struct pwrseq_unit_data pwrseq_qca6390_vregs_unit_data = {
+	.name = "regulators-enable",
+	.enable = pwrseq_qca6390_vregs_enable,
+	.disable = pwrseq_qca6390_vregs_disable,
+};
+
+static const struct pwrseq_unit_data *pwrseq_qca6390_unit_deps[] = {
+	&pwrseq_qca6390_vregs_unit_data,
+	NULL
+};
+
+static int pwrseq_qca6390_bt_enable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	pwrseq_qca6390_ensure_gpio_delay(ctx);
+	gpiod_set_value_cansleep(ctx->bt_gpio, 1);
+	ctx->last_gpio_enable = jiffies;
+
+	return 0;
+}
+
+static int pwrseq_qca6390_bt_disable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	gpiod_set_value_cansleep(ctx->bt_gpio, 0);
+
+	return 0;
+}
+
+static const struct pwrseq_unit_data pwrseq_qca6390_bt_unit_data = {
+	.name = "bluetooth-enable",
+	.deps = pwrseq_qca6390_unit_deps,
+	.enable = pwrseq_qca6390_bt_enable,
+	.disable = pwrseq_qca6390_bt_disable,
+};
+
+static int pwrseq_qca6390_wlan_enable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+	int ret;
+
+	ret = regulator_bulk_enable(ctx->pdata->num_vregs_wlan, ctx->regs_wlan);
+	if (ret)
+		return ret;
+
+	pwrseq_qca6390_ensure_gpio_delay(ctx);
+	gpiod_set_value_cansleep(ctx->wlan_gpio, 1);
+	ctx->last_gpio_enable = jiffies;
+
+	return 0;
+}
+
+static int pwrseq_qca6390_wlan_disable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	gpiod_set_value_cansleep(ctx->wlan_gpio, 0);
+
+	return regulator_bulk_disable(ctx->pdata->num_vregs_wlan,
+				      ctx->regs_wlan);
+}
+
+static const struct pwrseq_unit_data pwrseq_qca6390_wlan_unit_data = {
+	.name = "wlan-enable",
+	.deps = pwrseq_qca6390_unit_deps,
+	.enable = pwrseq_qca6390_wlan_enable,
+	.disable = pwrseq_qca6390_wlan_disable,
+};
+
+static int pwrseq_qca6390_pwup_delay(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	if (ctx->pdata->pwup_delay_msec)
+		msleep(ctx->pdata->pwup_delay_msec);
+
+	return 0;
+}
+
+static const struct pwrseq_target_data pwrseq_qca6390_bt_target_data = {
+	.name = "bluetooth",
+	.unit = &pwrseq_qca6390_bt_unit_data,
+	.post_enable = pwrseq_qca6390_pwup_delay,
+};
+
+static const struct pwrseq_target_data pwrseq_qca6390_wlan_target_data = {
+	.name = "wlan",
+	.unit = &pwrseq_qca6390_wlan_unit_data,
+	.post_enable = pwrseq_qca6390_pwup_delay,
+};
+
+static const struct pwrseq_target_data *pwrseq_qca6390_targets[] = {
+	&pwrseq_qca6390_bt_target_data,
+	&pwrseq_qca6390_wlan_target_data,
+	NULL
+};
+
+static int pwrseq_qca6390_match(struct pwrseq_device *pwrseq,
+				struct device *dev)
+{
+	struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+	struct device_node *dev_node = dev->of_node;
+
+	/*
+	 * The PMU supplies power to the Bluetooth and WLAN modules. both
+	 * consume the PMU AON output so check the presence of the
+	 * 'vddaon-supply' property and whether it leads us to the right
+	 * device.
+	 */
+	if (!of_property_present(dev_node, "vddaon-supply"))
+		return 0;
+
+	struct device_node *reg_node __free(device_node) =
+			of_parse_phandle(dev_node, "vddaon-supply", 0);
+	if (!reg_node)
+		return 0;
+
+	/*
+	 * `reg_node` is the PMU AON regulator, its parent is the `regulators`
+	 * node and finally its grandparent is the PMU device node that we're
+	 * looking for.
+	 */
+	if (!reg_node->parent || !reg_node->parent->parent ||
+	    reg_node->parent->parent != ctx->of_node)
+		return 0;
+
+	return 1;
+}
+
+static struct regulator_bulk_data *
+pwrseq_qca6390_get_regs(struct device *dev, size_t num_regs,
+			const struct pwrseq_qca6390_vreg *pdata)
+{
+	struct regulator_bulk_data *regs;
+	int ret, i;
+
+	regs = devm_kcalloc(dev, num_regs, sizeof(*regs), GFP_KERNEL);
+	if (!regs)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < num_regs; i++)
+		regs[i].supply = pdata[i].name;
+
+	ret = devm_regulator_bulk_get(dev, num_regs, regs);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	for (i = 0; i < num_regs; i++) {
+		if (!pdata[i].load_uA)
+			continue;
+
+		ret = regulator_set_load(regs[i].consumer, pdata[i].load_uA);
+		if (ret)
+			return ERR_PTR(ret);
+	}
+
+	return regs;
+}
+
+static int pwrseq_qca6390_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pwrseq_qca6390_ctx *ctx;
+	struct pwrseq_config config;
+
+	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->of_node = dev->of_node;
+
+	ctx->pdata = of_device_get_match_data(dev);
+	if (!ctx->pdata)
+		return dev_err_probe(dev, -ENODEV,
+				     "Failed to obtain platform data\n");
+
+	ctx->regs_common = pwrseq_qca6390_get_regs(dev,
+						   ctx->pdata->num_vregs_common,
+						   ctx->pdata->vregs_common);
+	if (IS_ERR(ctx->regs_common))
+		return dev_err_probe(dev, PTR_ERR(ctx->regs_common),
+				     "Failed to get all regulators\n");
+
+	ctx->regs_wlan = pwrseq_qca6390_get_regs(dev,
+						 ctx->pdata->num_vregs_wlan,
+						 ctx->pdata->vregs_wlan);
+	if (IS_ERR(ctx->regs_wlan))
+		return dev_err_probe(dev, PTR_ERR(ctx->regs_wlan),
+				     "Failed to get all regulators\n");
+
+	ctx->bt_gpio = devm_gpiod_get_optional(dev, "bt-enable", GPIOD_OUT_LOW);
+	if (IS_ERR(ctx->bt_gpio))
+		return dev_err_probe(dev, PTR_ERR(ctx->bt_gpio),
+				     "Failed to get the Bluetooth enable GPIO\n");
+
+	ctx->wlan_gpio = devm_gpiod_get_optional(dev, "wlan-enable",
+						 GPIOD_OUT_LOW);
+	if (IS_ERR(ctx->wlan_gpio))
+		return dev_err_probe(dev, PTR_ERR(ctx->wlan_gpio),
+				     "Failed to get the WLAN enable GPIO\n");
+
+	memset(&config, 0, sizeof(config));
+
+	config.parent = dev;
+	config.owner = THIS_MODULE;
+	config.drvdata = ctx;
+	config.match = pwrseq_qca6390_match;
+	config.targets = pwrseq_qca6390_targets;
+
+	ctx->pwrseq = devm_pwrseq_device_register(dev, &config);
+	if (IS_ERR(ctx->pwrseq))
+		return dev_err_probe(dev, PTR_ERR(ctx->pwrseq),
+				     "Failed to register the power sequencer\n");
+
+	return 0;
+}
+
+static const struct of_device_id pwrseq_qca6390_of_match[] = {
+	{
+		.compatible = "qcom,qca6390-pmu",
+		.data = &pwrseq_qca6390_of_data,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pwrseq_qca6390_of_match);
+
+static struct platform_driver pwrseq_qca6390_driver = {
+	.driver = {
+		.name = "pwrseq-qca6390",
+		.of_match_table = pwrseq_qca6390_of_match,
+	},
+	.probe = pwrseq_qca6390_probe,
+};
+module_platform_driver(pwrseq_qca6390_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski at linaro.org>");
+MODULE_DESCRIPTION("QCA6390 PMU power sequencing driver");
+MODULE_LICENSE("GPL");
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:12 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:12 +0100
Subject: [PATCH v5 15/18] power: sequencing: implement the pwrseq core
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-16-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Implement the power sequencing subsystem allowing devices to share
complex powering-up and down procedures. It's split into the consumer
and provider parts but does not implement any new DT bindings so that
the actual power sequencing is never revealed in the DT representation.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 MAINTAINERS                       |    8 +
 drivers/power/Kconfig             |    1 +
 drivers/power/Makefile            |    1 +
 drivers/power/sequencing/Kconfig  |   12 +
 drivers/power/sequencing/Makefile |    4 +
 drivers/power/sequencing/core.c   | 1065 +++++++++++++++++++++++++++++
 include/linux/pwrseq/consumer.h   |   56 ++
 include/linux/pwrseq/provider.h   |   75 ++
 8 files changed, 1222 insertions(+)
 create mode 100644 drivers/power/sequencing/Kconfig
 create mode 100644 drivers/power/sequencing/Makefile
 create mode 100644 drivers/power/sequencing/core.c
 create mode 100644 include/linux/pwrseq/consumer.h
 create mode 100644 include/linux/pwrseq/provider.h

diff --git a/MAINTAINERS b/MAINTAINERS
index cd7980e5b1ad..5187a30952e4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17647,6 +17647,14 @@ F:	include/linux/pm_*
 F:	include/linux/powercap.h
 F:	kernel/configs/nopm.config
 
+POWER SEQUENCING
+M:	Bartosz Golaszewski <brgl at bgdev.pl>
+L:	linux-pm at vger.kernel.org
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
+F:	drivers/power/sequencing/
+F:	include/linux/pwrseq/
+
 POWER STATE COORDINATION INTERFACE (PSCI)
 M:	Mark Rutland <mark.rutland at arm.com>
 M:	Lorenzo Pieralisi <lpieralisi at kernel.org>
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 696bf77a7042..9a8e44ca9ae4 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 source "drivers/power/reset/Kconfig"
+source "drivers/power/sequencing/Kconfig"
 source "drivers/power/supply/Kconfig"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index effbf0377f32..962a2cd30a51 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_POWER_RESET)	+= reset/
+obj-$(CONFIG_POWER_SEQUENCING)	+= sequencing/
 obj-$(CONFIG_POWER_SUPPLY)	+= supply/
diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
new file mode 100644
index 000000000000..ba5732b1dbf8
--- /dev/null
+++ b/drivers/power/sequencing/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+menuconfig POWER_SEQUENCING
+	tristate "Power Sequencing support"
+	help
+	  Say Y here to enable the Power Sequencing subsystem.
+
+	  This subsystem is designed to control power to devices that share
+	  complex resources and/or require specific power sequences to be run
+	  during power-up.
+
+	  If unsure, say no.
diff --git a/drivers/power/sequencing/Makefile b/drivers/power/sequencing/Makefile
new file mode 100644
index 000000000000..dcdf8c0c159e
--- /dev/null
+++ b/drivers/power/sequencing/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_POWER_SEQUENCING)		+= pwrseq-core.o
+pwrseq-core-y				:= core.o
diff --git a/drivers/power/sequencing/core.c b/drivers/power/sequencing/core.c
new file mode 100644
index 000000000000..00ad7964a0b6
--- /dev/null
+++ b/drivers/power/sequencing/core.c
@@ -0,0 +1,1065 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#include <linux/bug.h>
+#include <linux/cleanup.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/idr.h>
+#include <linux/kernel.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/property.h>
+#include <linux/pwrseq/consumer.h>
+#include <linux/pwrseq/provider.h>
+#include <linux/radix-tree.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+
+/*
+ * Power-sequencing framework for linux.
+ *
+ * This subsystem allows power sequence providers to register a set of targets
+ * that consumers may request and power-up/down.
+ *
+ * Glossary:
+ *
+ * Unit - a unit is a discreet chunk of a power sequence. For instance one unit
+ * may enable a set of regulators, another may enable a specific GPIO. Units
+ * can define dependencies in the form of other units that must be enabled
+ * before it itself can be.
+ *
+ * Target - a target is a set of units (composed of the "final" unit and its
+ * dependencies) that a consumer selects by its name when requesting a handle
+ * to the power sequencer. Via the dependency system, multiple targets may
+ * share the same parts of a power sequence but ignore parts that are
+ * irrelevant.
+ *
+ * Descriptor - a handle passed by the pwrseq core to every consumer that
+ * serves as the entry point to the provider layer. It ensures coherence
+ * between different users and keeps reference counting consistent.
+ *
+ * Each provider must define a .match() callback whose role is to determine
+ * whether a potential consumer is in fact associated with this sequencer.
+ * This allows creating abstraction layers on top of regular device-tree
+ * resources like regulators, clocks and other nodes connected to the consumer
+ * via phandle.
+ */
+
+static DEFINE_IDA(pwrseq_ida);
+
+/*
+ * Protects the device list on the pwrseq bus from concurrent modifications
+ * but allows simultaneous read-only access.
+ */
+static DECLARE_RWSEM(pwrseq_sem);
+
+/**
+ * struct pwrseq_unit - Private power-sequence unit data.
+ * @ref: Reference count for this object. When it goes to 0, the object is
+ *       destroyed.
+ * @name: Name of this target.
+ * @list: Link to siblings on the list of all units of a single sequencer.
+ * @deps: List of units on which this unit depends.
+ * @enable: Callback running the part of the power-on sequence provided by
+ *          this unit.
+ * @disable: Callback running the part of the power-off sequence provided
+ *           by this unit.
+ * @enable_count: Current number of users that enabled this unit. May be the
+ *                consumer of the power sequencer or other units that depend
+ *                on this one.
+ */
+struct pwrseq_unit {
+	struct kref ref;
+	const char *name;
+	struct list_head list;
+	struct list_head deps;
+	pwrseq_power_state_func enable;
+	pwrseq_power_state_func disable;
+	unsigned int enable_count;
+};
+
+static struct pwrseq_unit *pwrseq_unit_new(const struct pwrseq_unit_data *data)
+{
+	struct pwrseq_unit *unit;
+
+	unit = kzalloc(sizeof(*unit), GFP_KERNEL);
+	if (!unit)
+		return NULL;
+
+	unit->name = kstrdup_const(data->name, GFP_KERNEL);
+	if (!unit->name) {
+		kfree(unit);
+		return NULL;
+	}
+
+	kref_init(&unit->ref);
+	INIT_LIST_HEAD(&unit->deps);
+	unit->enable = data->enable;
+	unit->disable = data->disable;
+
+	return unit;
+}
+
+static struct pwrseq_unit *pwrseq_unit_incref(struct pwrseq_unit *unit)
+{
+	kref_get(&unit->ref);
+
+	return unit;
+}
+
+static void pwrseq_unit_release(struct kref *ref);
+
+static void pwrseq_unit_decref(struct pwrseq_unit *unit)
+{
+	kref_put(&unit->ref, pwrseq_unit_release);
+}
+
+/**
+ * struct pwrseq_unit_dep - Wrapper around a reference to the unit structure
+ *                          allowing to keep it on multiple dependency lists
+ *                          in different units.
+ * @list: Siblings on the list.
+ * @unit: Address of the referenced unit.
+ */
+struct pwrseq_unit_dep {
+	struct list_head list;
+	struct pwrseq_unit *unit;
+};
+
+static struct pwrseq_unit_dep *pwrseq_unit_dep_new(struct pwrseq_unit *unit)
+{
+	struct pwrseq_unit_dep *dep;
+
+	dep = kzalloc(sizeof(*dep), GFP_KERNEL);
+	if (!dep)
+		return NULL;
+
+	dep->unit = unit;
+
+	return dep;
+}
+
+static void pwrseq_unit_dep_free(struct pwrseq_unit_dep *ref)
+{
+	pwrseq_unit_decref(ref->unit);
+	kfree(ref);
+}
+
+static void pwrseq_unit_free_deps(struct list_head *list)
+{
+	struct pwrseq_unit_dep *dep, *next;
+
+	list_for_each_entry_safe(dep, next, list, list) {
+		list_del(&dep->list);
+		pwrseq_unit_dep_free(dep);
+	}
+}
+
+static void pwrseq_unit_release(struct kref *ref)
+{
+	struct pwrseq_unit *unit = container_of(ref, struct pwrseq_unit, ref);
+
+	pwrseq_unit_free_deps(&unit->deps);
+	list_del(&unit->list);
+	kfree_const(unit->name);
+	kfree(unit);
+}
+
+/**
+ * struct pwrseq_target - Private power-sequence target data.
+ * @list: Siblings on the list of all targets exposed by a power sequencer.
+ * @name: Name of the target.
+ * @unit: Final unit for this target.
+ * @post_enable: Callback run after the target unit has been enabled, *after*
+ *               the state lock has been released. It's useful for implementing
+ *               boot-up delays without blocking other users from powering up
+ *               using the same power sequencer.
+ */
+struct pwrseq_target {
+	struct list_head list;
+	const char *name;
+	struct pwrseq_unit *unit;
+	pwrseq_power_state_func post_enable;
+};
+
+static struct pwrseq_target *
+pwrseq_target_new(const struct pwrseq_target_data *data)
+{
+	struct pwrseq_target *target;
+
+	target = kzalloc(sizeof(*target), GFP_KERNEL);
+	if (!target)
+		return NULL;
+
+	target->name = kstrdup_const(data->name, GFP_KERNEL);
+	if (!target->name) {
+		kfree(target);
+		return NULL;
+	}
+
+	target->post_enable = data->post_enable;
+
+	return target;
+}
+
+static void pwrseq_target_free(struct pwrseq_target *target)
+{
+	pwrseq_unit_decref(target->unit);
+	kfree_const(target->name);
+	kfree(target);
+}
+
+/**
+ * struct pwrseq_device - Private power sequencing data.
+ * @dev: Device struct associated with this sequencer.
+ * @id: Device ID.
+ * @owner: Prevents removal of active power sequencing providers.
+ * @rw_lock: Protects the device from being unregistered while in use.
+ * @state_lock: Prevents multiple users running the power sequence at the same
+ *              time.
+ * @match: Power sequencer matching callback.
+ * @targets: List of targets exposed by this sequencer.
+ * @units: List of all units supported by this sequencer.
+ */
+struct pwrseq_device {
+	struct device dev;
+	int id;
+	struct module *owner;
+	struct rw_semaphore rw_lock;
+	struct mutex state_lock;
+	pwrseq_match_func match;
+	struct list_head targets;
+	struct list_head units;
+};
+
+static struct pwrseq_device *to_pwrseq_device(struct device *dev)
+{
+	return container_of(dev, struct pwrseq_device, dev);
+}
+
+static struct pwrseq_device *pwrseq_device_get(struct pwrseq_device *pwrseq)
+{
+	get_device(&pwrseq->dev);
+
+	return pwrseq;
+}
+
+static void pwrseq_device_put(struct pwrseq_device *pwrseq)
+{
+	put_device(&pwrseq->dev);
+}
+
+/**
+ * struct pwrseq_desc - Wraps access to the pwrseq_device and ensures that one
+ *                      user cannot break the reference counting for others.
+ * @pwrseq: Reference to the power sequencing device.
+ * @target: Reference to the target this descriptor allows to control.
+ * @powered_on: Power state set by the holder of the descriptor (not necessarily
+ * corresponding to the actual power state of the device).
+ */
+struct pwrseq_desc {
+	struct pwrseq_device *pwrseq;
+	struct pwrseq_target *target;
+	bool powered_on;
+};
+
+static const struct bus_type pwrseq_bus = {
+	.name = "pwrseq",
+};
+
+static void pwrseq_release(struct device *dev)
+{
+	struct pwrseq_device *pwrseq = to_pwrseq_device(dev);
+	struct pwrseq_target *target;
+
+	list_for_each_entry(target, &pwrseq->targets, list)
+		pwrseq_target_free(target);
+
+	mutex_destroy(&pwrseq->state_lock);
+	ida_free(&pwrseq_ida, pwrseq->id);
+	kfree(pwrseq);
+}
+
+static const struct device_type pwrseq_device_type = {
+	.name = "power_sequencer",
+	.release = pwrseq_release,
+};
+
+static int pwrseq_unit_setup_deps(const struct pwrseq_unit_data **data,
+				  struct list_head *dep_list,
+				  struct list_head *unit_list,
+				  struct radix_tree_root *processed_units)
+{
+	const struct pwrseq_unit_data *pos;
+	struct pwrseq_unit_dep *dep;
+	struct pwrseq_unit *unit;
+	int ret, i;
+
+	for (i = 0; data[i]; i++) {
+		pos = data[i];
+
+		unit = radix_tree_lookup(processed_units, (unsigned long)data);
+		if (unit) {
+			pwrseq_unit_incref(unit);
+		} else {
+			unit = pwrseq_unit_new(pos);
+			if (!unit)
+				return -ENOMEM;
+
+			if (pos->deps) {
+				ret = pwrseq_unit_setup_deps(pos->deps,
+							     &unit->deps,
+							     unit_list,
+							     processed_units);
+				if (ret) {
+					pwrseq_unit_decref(unit);
+					return ret;
+				}
+			}
+
+			ret = radix_tree_insert(processed_units,
+						(unsigned long)data, unit);
+			if (ret) {
+				pwrseq_unit_decref(unit);
+				return ret;
+			}
+
+			list_add_tail(&unit->list, unit_list);
+		}
+
+		dep = pwrseq_unit_dep_new(unit);
+		if (!dep) {
+			pwrseq_unit_decref(unit);
+			return -ENOMEM;
+		}
+
+		list_add_tail(&dep->list, dep_list);
+	}
+
+	return 0;
+}
+
+static int pwrseq_target_setup_unit(struct pwrseq_target *target,
+				    const struct pwrseq_unit_data *data,
+				    struct list_head *unit_list,
+				    struct radix_tree_root *processed_units)
+{
+	struct pwrseq_unit *unit;
+	int ret;
+
+	unit = radix_tree_lookup(processed_units, (unsigned long)data);
+	if (unit) {
+		target->unit = pwrseq_unit_incref(unit);
+		return 0;
+	}
+
+	unit = pwrseq_unit_new(data);
+	if (!unit)
+		return -ENOMEM;
+
+	ret = pwrseq_unit_setup_deps(data->deps, &unit->deps, unit_list,
+				     processed_units);
+	if (ret) {
+		pwrseq_unit_decref(unit);
+		return ret;
+	}
+
+	ret = radix_tree_insert(processed_units, (unsigned long)data, unit);
+	if (ret) {
+		pwrseq_unit_decref(unit);
+		return ret;
+	}
+
+	target->unit = unit;
+	list_add_tail(&unit->list, unit_list);
+
+	return 0;
+}
+
+static int pwrseq_do_setup_targets(const struct pwrseq_target_data **data,
+				   struct pwrseq_device *pwrseq,
+				   struct radix_tree_root *processed_units)
+{
+	const struct pwrseq_target_data *pos;
+	struct pwrseq_target *target;
+	int ret, i;
+
+	for (i = 0; data[i]; i++) {
+		pos = data[i];
+
+		target = pwrseq_target_new(pos);
+		if (!target)
+			return -ENOMEM;
+
+		ret = pwrseq_target_setup_unit(target, pos->unit,
+					       &pwrseq->units,
+					       processed_units);
+		if (ret) {
+			pwrseq_target_free(target);
+			return ret;
+		}
+
+		list_add_tail(&target->list, &pwrseq->targets);
+	}
+
+	return 0;
+}
+
+static int pwrseq_setup_targets(const struct pwrseq_target_data **targets,
+				struct pwrseq_device *pwrseq)
+{
+	struct radix_tree_root processed_units;
+	struct radix_tree_iter iter;
+	void __rcu **slot;
+	int ret;
+
+	INIT_RADIX_TREE(&processed_units, GFP_KERNEL);
+	ret = pwrseq_do_setup_targets(targets, pwrseq, &processed_units);
+	radix_tree_for_each_slot(slot, &processed_units, &iter, 0)
+		radix_tree_delete(&processed_units, iter.index);
+
+	return ret;
+}
+
+/**
+ * pwrseq_device_register() - Register a new power sequencer.
+ * @config: Configuration of the new power sequencing device.
+ *
+ * The config structure is only used during the call and can be freed after
+ * the function returns. The config structure *must* have the parent device
+ * as well as the match() callback and at least one target set.
+ *
+ * Returns:
+ * Returns the address of the new pwrseq device or ERR_PTR() on failure.
+ */
+struct pwrseq_device *
+pwrseq_device_register(const struct pwrseq_config *config)
+{
+	struct pwrseq_device *pwrseq;
+	int ret;
+
+	if (!config->parent || !config->match || !config->targets ||
+	    !config->targets[0])
+		return ERR_PTR(-EINVAL);
+
+	pwrseq = kzalloc(sizeof(*pwrseq), GFP_KERNEL);
+	if (!pwrseq)
+		return ERR_PTR(-ENOMEM);
+
+	pwrseq->dev.type = &pwrseq_device_type;
+	pwrseq->dev.bus = &pwrseq_bus;
+	pwrseq->dev.parent = config->parent;
+	device_set_node(&pwrseq->dev, dev_fwnode(config->parent));
+	dev_set_drvdata(&pwrseq->dev, config->drvdata);
+
+	pwrseq->id = ida_alloc(&pwrseq_ida, GFP_KERNEL);
+	if (pwrseq->id < 0) {
+		kfree(pwrseq);
+		return ERR_PTR(pwrseq->id);
+	}
+
+	/*
+	 * From this point onwards the device's release() callback is
+	 * responsible for freeing resources.
+	 */
+	device_initialize(&pwrseq->dev);
+
+	ret = dev_set_name(&pwrseq->dev, "pwrseq.%d", pwrseq->id);
+	if (ret)
+		goto err_put_pwrseq;
+
+	pwrseq->owner = config->owner ?: THIS_MODULE;
+	pwrseq->match = config->match;
+
+	init_rwsem(&pwrseq->rw_lock);
+	mutex_init(&pwrseq->state_lock);
+	INIT_LIST_HEAD(&pwrseq->targets);
+	INIT_LIST_HEAD(&pwrseq->units);
+
+	ret = pwrseq_setup_targets(config->targets, pwrseq);
+	if (ret)
+		goto err_put_pwrseq;
+
+	scoped_guard(rwsem_write, &pwrseq_sem) {
+		ret = device_add(&pwrseq->dev);
+		if (ret)
+			goto err_put_pwrseq;
+	}
+
+	return pwrseq;
+
+err_put_pwrseq:
+	pwrseq_device_put(pwrseq);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(pwrseq_device_register);
+
+/**
+ * pwrseq_device_unregister() - Unregister the power sequencer.
+ * @pwrseq: Power sequencer to unregister.
+ */
+void pwrseq_device_unregister(struct pwrseq_device *pwrseq)
+{
+	struct device *dev = &pwrseq->dev;
+	struct pwrseq_target *target;
+
+	scoped_guard(mutex, &pwrseq->state_lock) {
+		guard(rwsem_write)(&pwrseq->rw_lock);
+
+		list_for_each_entry(target, &pwrseq->targets, list)
+			WARN_ONCE(target->unit->enable_count,
+				  "REMOVING POWER SEQUENCER WITH ACTIVE USERS\n");
+
+		guard(rwsem_write)(&pwrseq_sem);
+
+		device_del(dev);
+	}
+
+	pwrseq_device_put(pwrseq);
+}
+EXPORT_SYMBOL_GPL(pwrseq_device_unregister);
+
+static void devm_pwrseq_device_unregister(void *data)
+{
+	struct pwrseq_device *pwrseq = data;
+
+	pwrseq_device_unregister(pwrseq);
+}
+
+/**
+ * devm_pwrseq_device_register() - Managed variant of pwrseq_device_register().
+ * @dev: Managing device.
+ * @config: Configuration of the new power sequencing device.
+ *
+ * Returns:
+ * Returns the address of the new pwrseq device or ERR_PTR() on failure.
+ */
+struct pwrseq_device *
+devm_pwrseq_device_register(struct device *dev,
+			    const struct pwrseq_config *config)
+{
+	struct pwrseq_device *pwrseq;
+	int ret;
+
+	pwrseq = pwrseq_device_register(config);
+	if (IS_ERR(pwrseq))
+		return pwrseq;
+
+	ret = devm_add_action_or_reset(dev, devm_pwrseq_device_unregister,
+				       pwrseq);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return pwrseq;
+}
+EXPORT_SYMBOL_GPL(devm_pwrseq_device_register);
+
+/**
+ * pwrseq_device_get_data() - Get the driver private data associated with this
+ *                            sequencer.
+ * @pwrseq: Power sequencer object.
+ *
+ * Returns:
+ * Address of the private driver data.
+ */
+void *pwrseq_device_get_drvdata(struct pwrseq_device *pwrseq)
+{
+	return dev_get_drvdata(&pwrseq->dev);
+}
+EXPORT_SYMBOL_GPL(pwrseq_device_get_drvdata);
+
+struct pwrseq_match_data {
+	struct pwrseq_desc *desc;
+	struct device *dev;
+	const char *target;
+};
+
+static int pwrseq_match_device(struct device *pwrseq_dev, void *data)
+{
+	struct pwrseq_device *pwrseq = to_pwrseq_device(pwrseq_dev);
+	struct pwrseq_match_data *match_data = data;
+	struct pwrseq_target *target;
+	int ret;
+
+	guard(rwsem_read)(&pwrseq->rw_lock);
+	if (!device_is_registered(&pwrseq->dev))
+		return 0;
+
+	ret = pwrseq->match(pwrseq, match_data->dev);
+	if (ret <= 0)
+		return ret;
+
+	/* We got the matching device, let's find the right target. */
+	list_for_each_entry(target, &pwrseq->targets, list) {
+		if (strcmp(target->name, match_data->target))
+			continue;
+
+		match_data->desc->target = target;
+	}
+
+	/*
+	 * This device does not have this target. No point in deferring as it
+	 * will not get a new target dynamically later.
+	 */
+	if (!match_data->desc->target)
+		return -ENOENT;
+
+	if (!try_module_get(pwrseq->owner))
+		return -EPROBE_DEFER;
+
+	match_data->desc->pwrseq = pwrseq_device_get(pwrseq);
+
+	return 1;
+}
+
+/**
+ * pwrseq_get() - Get the power sequencer associated with this device.
+ * @dev: Device for which to get the sequencer.
+ * @target: Name of the target exposed by the sequencer this device wants to
+ *          reach.
+ *
+ * Returns:
+ * New power sequencer descriptor for use by the consumer driver or ERR_PTR()
+ * on failure.
+ */
+struct pwrseq_desc *pwrseq_get(struct device *dev, const char *target)
+{
+	struct pwrseq_match_data match_data;
+	int ret;
+
+	struct pwrseq_desc *desc __free(kfree) = kzalloc(sizeof(*desc),
+							 GFP_KERNEL);
+	if (!desc)
+		return ERR_PTR(-ENOMEM);
+
+	match_data.desc = desc;
+	match_data.dev = dev;
+	match_data.target = target;
+
+	guard(rwsem_read)(&pwrseq_sem);
+
+	ret = bus_for_each_dev(&pwrseq_bus, NULL, &match_data,
+			       pwrseq_match_device);
+	if (ret < 0)
+		return ERR_PTR(ret);
+	if (ret == 0)
+		/* No device matched. */
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return no_free_ptr(desc);
+}
+EXPORT_SYMBOL_GPL(pwrseq_get);
+
+/**
+ * pwrseq_put() - Release the power sequencer descriptor.
+ * @desc: Descriptor to release.
+ */
+void pwrseq_put(struct pwrseq_desc *desc)
+{
+	struct pwrseq_device *pwrseq;
+
+	if (!desc)
+		return;
+
+	pwrseq = desc->pwrseq;
+
+	if (desc->powered_on)
+		pwrseq_power_off(desc);
+
+	kfree(desc);
+	module_put(pwrseq->owner);
+	pwrseq_device_put(pwrseq);
+}
+EXPORT_SYMBOL_GPL(pwrseq_put);
+
+static void devm_pwrseq_put(void *data)
+{
+	struct pwrseq_desc *desc = data;
+
+	pwrseq_put(desc);
+}
+
+/**
+ * devm_pwrseq_get() - Managed variant of pwrseq_get().
+ * @dev: Device for which to get the sequencer and which also manages its
+ *       lifetime.
+ * @target: Name of the target exposed by the sequencer this device wants to
+ *          reach.
+ *
+ * Returns:
+ * New power sequencer descriptor for use by the consumer driver or ERR_PTR()
+ * on failure.
+ */
+struct pwrseq_desc *devm_pwrseq_get(struct device *dev, const char *target)
+{
+	struct pwrseq_desc *desc;
+	int ret;
+
+	desc = pwrseq_get(dev, target);
+	if (IS_ERR(desc))
+		return desc;
+
+	ret = devm_add_action_or_reset(dev, devm_pwrseq_put, desc);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return desc;
+}
+EXPORT_SYMBOL_GPL(devm_pwrseq_get);
+
+static int pwrseq_unit_enable(struct pwrseq_device *pwrseq,
+			      struct pwrseq_unit *target);
+static int pwrseq_unit_disable(struct pwrseq_device *pwrseq,
+			       struct pwrseq_unit *target);
+
+static int pwrseq_unit_enable_deps(struct pwrseq_device *pwrseq,
+				   struct list_head *list)
+{
+	struct pwrseq_unit_dep *pos;
+	int ret = 0;
+
+	list_for_each_entry(pos, list, list) {
+		ret = pwrseq_unit_enable(pwrseq, pos->unit);
+		if (ret) {
+			list_for_each_entry_continue_reverse(pos, list, list)
+				pwrseq_unit_disable(pwrseq, pos->unit);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int pwrseq_unit_disable_deps(struct pwrseq_device *pwrseq,
+				    struct list_head *list)
+{
+	struct pwrseq_unit_dep *pos;
+	int ret = 0;
+
+	list_for_each_entry_reverse(pos, list, list) {
+		ret = pwrseq_unit_disable(pwrseq, pos->unit);
+		if (ret) {
+			list_for_each_entry_continue(pos, list, list)
+				pwrseq_unit_enable(pwrseq, pos->unit);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int pwrseq_unit_enable(struct pwrseq_device *pwrseq,
+			      struct pwrseq_unit *unit)
+{
+	int ret;
+
+	if (unit->enable_count != 0) {
+		unit->enable_count++;
+		return 0;
+	}
+
+	ret = pwrseq_unit_enable_deps(pwrseq, &unit->deps);
+	if (ret) {
+		dev_err(&pwrseq->dev,
+			"Failed to enable dependencies before power-on for target '%s': %d\n",
+			unit->name, ret);
+		return ret;
+	}
+
+	if (unit->enable) {
+		ret = unit->enable(pwrseq);
+		if (ret) {
+			dev_err(&pwrseq->dev,
+				"Failed to enable target '%s': %d\n",
+				unit->name, ret);
+			pwrseq_unit_disable_deps(pwrseq, &unit->deps);
+			return ret;
+		}
+	}
+
+	unit->enable_count++;
+
+	return 0;
+}
+
+static int pwrseq_unit_disable(struct pwrseq_device *pwrseq,
+			       struct pwrseq_unit *unit)
+{
+	int ret;
+
+	if (unit->enable_count == 0) {
+		WARN_ONCE(1, "Unmatched power-off for target '%s'\n",
+			  unit->name);
+		return -EBUSY;
+	}
+
+	if (unit->enable_count != 1) {
+		unit->enable_count--;
+		return 0;
+	}
+
+	if (unit->disable) {
+		ret = unit->disable(pwrseq);
+		if (ret) {
+			dev_err(&pwrseq->dev,
+				"Failed to disable target '%s': %d\n",
+				unit->name, ret);
+			return ret;
+		}
+	}
+
+	ret = pwrseq_unit_disable_deps(pwrseq, &unit->deps);
+	if (ret) {
+		dev_err(&pwrseq->dev,
+			"Failed to disable dependencies after power-off for target '%s': %d\n",
+			unit->name, ret);
+		if (unit->enable)
+			unit->enable(pwrseq);
+		return ret;
+	}
+
+	unit->enable_count--;
+
+	return 0;
+}
+
+/**
+ * pwrseq_power_on() - Issue a power-on request on behalf of the consumer
+ *                     device.
+ * @desc: Descriptor referencing the power sequencer.
+ *
+ * This function tells the power sequencer that the consumer wants to be
+ * powered-up. The sequencer may already have powered-up the device in which
+ * case the function returns 0. If the power-up sequence is already in
+ * progress, the function will block until it's done and return 0. If this is
+ * the first request, the device will be powered up.
+ *
+ * Returns:
+ * 0 on success, negative error number on failure.
+ */
+int pwrseq_power_on(struct pwrseq_desc *desc)
+{
+	struct pwrseq_device *pwrseq;
+	struct pwrseq_target *target;
+	struct pwrseq_unit *unit;
+	int ret;
+
+	might_sleep();
+
+	if (!desc || desc->powered_on)
+		return 0;
+
+	pwrseq = desc->pwrseq;
+	target = desc->target;
+	unit = target->unit;
+
+	guard(rwsem_read)(&pwrseq->rw_lock);
+	if (!device_is_registered(&pwrseq->dev))
+		return -ENODEV;
+
+	scoped_guard(mutex, &pwrseq->state_lock) {
+		ret = pwrseq_unit_enable(pwrseq, unit);
+		if (!ret)
+			desc->powered_on = true;
+	}
+
+	if (target->post_enable) {
+		ret = target->post_enable(pwrseq);
+		if (ret) {
+			pwrseq_unit_disable(pwrseq, unit);
+			desc->powered_on = false;
+		}
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pwrseq_power_on);
+
+/**
+ * pwrseq_power_off() - Issue a power-off request on behalf of the consumer
+ *                      device.
+ * @desc: Descriptor referencing the power sequencer.
+ *
+ * This undoes the effects of pwrseq_power_on(). It issues a power-off request
+ * on behalf of the consumer and when the last remaining user does so, the
+ * power-down sequence will be started. If one is in progress, the function
+ * will block until it's complete and then return.
+ *
+ * Returns:
+ * 0 on success, negative error number on failure.
+ */
+int pwrseq_power_off(struct pwrseq_desc *desc)
+{
+	struct pwrseq_device *pwrseq;
+	struct pwrseq_unit *unit;
+	int ret;
+
+	might_sleep();
+
+	if (!desc || !desc->powered_on)
+		return 0;
+
+	pwrseq = desc->pwrseq;
+	unit = desc->target->unit;
+
+	guard(rwsem_read)(&pwrseq->rw_lock);
+	if (!device_is_registered(&pwrseq->dev))
+		return -ENODEV;
+
+	guard(mutex)(&pwrseq->state_lock);
+
+	ret = pwrseq_unit_disable(pwrseq, unit);
+	if (!ret)
+		desc->powered_on = false;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pwrseq_power_off);
+
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+
+struct pwrseq_debugfs_count_ctx {
+	struct device *dev;
+	loff_t index;
+};
+
+static int pwrseq_debugfs_seq_count(struct device *dev, void *data)
+{
+	struct pwrseq_debugfs_count_ctx *ctx = data;
+
+	ctx->dev = dev;
+
+	return ctx->index-- ? 0 : 1;
+}
+
+static void *pwrseq_debugfs_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	struct pwrseq_debugfs_count_ctx ctx;
+
+	ctx.dev = NULL;
+	ctx.index = *pos;
+
+	/*
+	 * We're holding the lock for the entire printout so no need to fiddle
+	 * with device reference count.
+	 */
+	down_read(&pwrseq_sem);
+
+	bus_for_each_dev(&pwrseq_bus, NULL, &ctx, pwrseq_debugfs_seq_count);
+	if (!ctx.index)
+		return NULL;
+
+	return ctx.dev;
+}
+
+static void *pwrseq_debugfs_seq_next(struct seq_file *seq, void *data,
+				     loff_t *pos)
+{
+	struct device *curr = data;
+
+	++*pos;
+
+	struct device *next __free(put_device) =
+			bus_find_next_device(&pwrseq_bus, curr);
+	return next;
+}
+
+static void pwrseq_debugfs_seq_show_target(struct seq_file *seq,
+					   struct pwrseq_target *target)
+{
+	seq_printf(seq, "    target: [%s] (target unit: [%s])\n",
+		   target->name, target->unit->name);
+}
+
+static void pwrseq_debugfs_seq_show_unit(struct seq_file *seq,
+					 struct pwrseq_unit *unit)
+{
+	struct pwrseq_unit_dep *ref;
+
+	seq_printf(seq, "    unit: [%s] - enable count: %u\n",
+		   unit->name, unit->enable_count);
+
+	if (list_empty(&unit->deps))
+		return;
+
+	seq_puts(seq, "      dependencies:\n");
+	list_for_each_entry(ref, &unit->deps, list)
+		seq_printf(seq, "        [%s]\n", ref->unit->name);
+}
+
+static int pwrseq_debugfs_seq_show(struct seq_file *seq, void *data)
+{
+	struct device *dev = data;
+	struct pwrseq_device *pwrseq = to_pwrseq_device(dev);
+	struct pwrseq_target *target;
+	struct pwrseq_unit *unit;
+
+	seq_printf(seq, "%s:\n", dev_name(dev));
+
+	seq_puts(seq, "  targets:\n");
+	list_for_each_entry(target, &pwrseq->targets, list)
+		pwrseq_debugfs_seq_show_target(seq, target);
+
+	seq_puts(seq, "  units:\n");
+	list_for_each_entry(unit, &pwrseq->units, list)
+		pwrseq_debugfs_seq_show_unit(seq, unit);
+
+	return 0;
+}
+
+static void pwrseq_debugfs_seq_stop(struct seq_file *seq, void *data)
+{
+	up_read(&pwrseq_sem);
+}
+
+static const struct seq_operations pwrseq_debugfs_sops = {
+	.start = pwrseq_debugfs_seq_start,
+	.next = pwrseq_debugfs_seq_next,
+	.show = pwrseq_debugfs_seq_show,
+	.stop = pwrseq_debugfs_seq_stop,
+};
+DEFINE_SEQ_ATTRIBUTE(pwrseq_debugfs);
+
+static struct dentry *pwrseq_debugfs_dentry;
+
+#endif /* CONFIG_DEBUG_FS */
+
+static int __init pwrseq_init(void)
+{
+	int ret;
+
+	ret = bus_register(&pwrseq_bus);
+	if (ret) {
+		pr_err("Failed to register the power sequencer bus\n");
+		return ret;
+	}
+
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+	pwrseq_debugfs_dentry = debugfs_create_file("pwrseq", 0444, NULL, NULL,
+						    &pwrseq_debugfs_fops);
+#endif  /* CONFIG_DEBUG_FS */
+
+	return 0;
+}
+subsys_initcall(pwrseq_init);
+
+static void __exit pwrseq_exit(void)
+{
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+	debugfs_remove_recursive(pwrseq_debugfs_dentry);
+#endif  /* CONFIG_DEBUG_FS */
+
+	bus_unregister(&pwrseq_bus);
+}
+module_exit(pwrseq_exit);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski at linaro.org>");
+MODULE_DESCRIPTION("Power Sequencing subsystem core");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/pwrseq/consumer.h b/include/linux/pwrseq/consumer.h
new file mode 100644
index 000000000000..7d583b4f266e
--- /dev/null
+++ b/include/linux/pwrseq/consumer.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#ifndef __POWER_SEQUENCING_CONSUMER_H__
+#define __POWER_SEQUENCING_CONSUMER_H__
+
+#include <linux/err.h>
+
+struct device;
+struct pwrseq_desc;
+
+#if IS_ENABLED(CONFIG_POWER_SEQUENCING)
+
+struct pwrseq_desc * __must_check
+pwrseq_get(struct device *dev, const char *target);
+void pwrseq_put(struct pwrseq_desc *desc);
+
+struct pwrseq_desc * __must_check
+devm_pwrseq_get(struct device *dev, const char *target);
+
+int pwrseq_power_on(struct pwrseq_desc *desc);
+int pwrseq_power_off(struct pwrseq_desc *desc);
+
+#else /* CONFIG_POWER_SEQUENCING */
+
+static inline struct pwrseq_desc * __must_check
+pwrseq_get(struct device *dev, const char *target)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+static inline void pwrseq_put(struct pwrseq_desc *desc)
+{
+}
+
+static inline struct pwrseq_desc * __must_check
+devm_pwrseq_get(struct device *dev, const char *target)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+static inline int pwrseq_power_on(struct pwrseq_desc *desc)
+{
+	return -ENOSYS;
+}
+
+static inline int pwrseq_power_off(struct pwrseq_desc *desc)
+{
+	return -ENOSYS;
+}
+
+#endif /* CONFIG_POWER_SEQUENCING */
+
+#endif /* __POWER_SEQUENCING_CONSUMER_H__ */
diff --git a/include/linux/pwrseq/provider.h b/include/linux/pwrseq/provider.h
new file mode 100644
index 000000000000..e627ed2f4d91
--- /dev/null
+++ b/include/linux/pwrseq/provider.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#ifndef __POWER_SEQUENCING_PROVIDER_H__
+#define __POWER_SEQUENCING_PROVIDER_H__
+
+struct device;
+struct module;
+struct pwrseq_device;
+
+typedef int (*pwrseq_power_state_func)(struct pwrseq_device *);
+typedef int (*pwrseq_match_func)(struct pwrseq_device *, struct device *);
+
+/**
+ * struct pwrseq_unit_data - Configuration of a single power sequencing
+ *                           unit.
+ * @name: Name of the unit.
+ * @deps: Units that must be enabled before this one and disabled after it
+ *        in the order they come in this array.
+ * @enable: Callback running the part of the power-on sequence provided by
+ *          this unit.
+ * @disable: Callback running the part of the power-off sequence provided
+ *           by this unit.
+ */
+struct pwrseq_unit_data {
+	const char *name;
+	const struct pwrseq_unit_data **deps;
+	pwrseq_power_state_func enable;
+	pwrseq_power_state_func disable;
+};
+
+/**
+ * struct pwrseq_target_data - Configuration of a power sequencing target.
+ * @name: Name of the target.
+ * @unit: Final unit that this target must reach in order to be considered
+ *        enabled.
+ * @post_enable: Callback run after the target unit has been enabled, *after*
+ *               the state lock has been released. It's useful for implementing
+ *               boot-up delays without blocking other users from powering up
+ *               using the same power sequencer.
+ */
+struct pwrseq_target_data {
+	const char *name;
+	const struct pwrseq_unit_data *unit;
+	pwrseq_power_state_func post_enable;
+};
+
+/**
+ * struct pwrseq_config - Configuration used for registering a new provider.
+ * @parent: Parent device for the sequencer. Must be set.
+ * @owner: Module providing this device.
+ * @drvdata: Private driver data.
+ * @match: Provider callback used to match the consumer device to the sequencer.
+ * @targets: Array of targets for this power sequencer. Must be NULL-terminated.
+ */
+struct pwrseq_config {
+	struct device *parent;
+	struct module *owner;
+	void *drvdata;
+	pwrseq_match_func match;
+	const struct pwrseq_target_data **targets;
+};
+
+struct pwrseq_device *
+pwrseq_device_register(const struct pwrseq_config *config);
+void pwrseq_device_unregister(struct pwrseq_device *pwrseq);
+struct pwrseq_device *
+devm_pwrseq_device_register(struct device *dev,
+			    const struct pwrseq_config *config);
+
+void *pwrseq_device_get_drvdata(struct pwrseq_device *pwrseq);
+
+#endif /* __POWER_SEQUENCING_PROVIDER_H__ */
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:14 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:14 +0100
Subject: [PATCH v5 17/18] Bluetooth: qca: use the power sequencer for QCA6390
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-18-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Use the pwrseq subsystem's consumer API to run the power-up sequence for
the Bluetooth module of the QCA6390 package.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/bluetooth/hci_qca.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index edd2a81b4d5e..6e747db30492 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -29,6 +29,7 @@
 #include <linux/of.h>
 #include <linux/acpi.h>
 #include <linux/platform_device.h>
+#include <linux/pwrseq/consumer.h>
 #include <linux/regulator/consumer.h>
 #include <linux/serdev.h>
 #include <linux/mutex.h>
@@ -215,6 +216,7 @@ struct qca_power {
 	struct regulator_bulk_data *vreg_bulk;
 	int num_vregs;
 	bool vregs_on;
+	struct pwrseq_desc *pwrseq;
 };
 
 struct qca_serdev {
@@ -1792,6 +1794,11 @@ static int qca_power_on(struct hci_dev *hdev)
 		ret = qca_regulator_init(hu);
 		break;
 
+	case QCA_QCA6390:
+		qcadev = serdev_device_get_drvdata(hu->serdev);
+		ret = pwrseq_power_on(qcadev->bt_power->pwrseq);
+		break;
+
 	default:
 		qcadev = serdev_device_get_drvdata(hu->serdev);
 		if (qcadev->bt_en) {
@@ -2170,6 +2177,10 @@ static void qca_power_shutdown(struct hci_uart *hu)
 		}
 		break;
 
+	case QCA_QCA6390:
+		pwrseq_power_off(qcadev->bt_power->pwrseq);
+		break;
+
 	default:
 		gpiod_set_value_cansleep(qcadev->bt_en, 0);
 	}
@@ -2308,12 +2319,25 @@ static int qca_serdev_probe(struct serdev_device *serdev)
 	case QCA_WCN6750:
 	case QCA_WCN6855:
 	case QCA_WCN7850:
+	case QCA_QCA6390:
 		qcadev->bt_power = devm_kzalloc(&serdev->dev,
 						sizeof(struct qca_power),
 						GFP_KERNEL);
 		if (!qcadev->bt_power)
 			return -ENOMEM;
+		break;
+	default:
+		break;
+	}
 
+	switch (qcadev->btsoc_type) {
+	case QCA_WCN3988:
+	case QCA_WCN3990:
+	case QCA_WCN3991:
+	case QCA_WCN3998:
+	case QCA_WCN6750:
+	case QCA_WCN6855:
+	case QCA_WCN7850:
 		qcadev->bt_power->dev = &serdev->dev;
 		err = qca_init_regulators(qcadev->bt_power, data->vregs,
 					  data->num_vregs);
@@ -2354,6 +2378,13 @@ static int qca_serdev_probe(struct serdev_device *serdev)
 		}
 		break;
 
+	case QCA_QCA6390:
+		qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->dev,
+							   "bluetooth");
+		if (IS_ERR(qcadev->bt_power->pwrseq))
+			return PTR_ERR(qcadev->bt_power->pwrseq);
+		fallthrough;
+
 	default:
 		qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
 					       GPIOD_OUT_LOW);
-- 
2.40.1



From brgl at bgdev.pl  Fri Feb 16 12:32:15 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 16 Feb 2024 21:32:15 +0100
Subject: [PATCH v5 18/18] PCI/pwrctl: add a PCI power control driver for power sequenced devices
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <20240216203215.40870-19-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Add a PCI power control driver that's capable of correctly powering up
devices using the power sequencing subsystem. The first user of this
driver is the ath11k module on QCA6390.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/pci/pwrctl/Kconfig             |  9 +++
 drivers/pci/pwrctl/Makefile            |  1 +
 drivers/pci/pwrctl/pci-pwrctl-pwrseq.c | 84 ++++++++++++++++++++++++++
 3 files changed, 94 insertions(+)
 create mode 100644 drivers/pci/pwrctl/pci-pwrctl-pwrseq.c

diff --git a/drivers/pci/pwrctl/Kconfig b/drivers/pci/pwrctl/Kconfig
index b91170ebfb49..3880a88aa73b 100644
--- a/drivers/pci/pwrctl/Kconfig
+++ b/drivers/pci/pwrctl/Kconfig
@@ -5,6 +5,15 @@ menu "PCI Power control drivers"
 config PCI_PWRCTL
 	tristate
 
+config PCI_PWRCTL_PWRSEQ
+	tristate "PCI Power Control driver using the Power Sequencing subsystem"
+	select POWER_SEQUENCING
+	select PCI_PWRCTL
+	default m if (ATH11K_PCI && ARCH_QCOM)
+	help
+	  Enable support for the PCI power control driver for device
+	  drivers using the Power Sequencing subsystem.
+
 config PCI_PWRCTL_WCN7850
 	tristate "PCI Power Control driver for WCN7850"
 	select PCI_PWRCTL
diff --git a/drivers/pci/pwrctl/Makefile b/drivers/pci/pwrctl/Makefile
index de20c3af1b78..47ab9db1fb42 100644
--- a/drivers/pci/pwrctl/Makefile
+++ b/drivers/pci/pwrctl/Makefile
@@ -3,4 +3,5 @@
 obj-$(CONFIG_PCI_PWRCTL)		+= pci-pwrctl-core.o
 pci-pwrctl-core-y			:= core.o
 
+obj-$(CONFIG_PCI_PWRCTL_PWRSEQ)		+= pci-pwrctl-pwrseq.o
 obj-$(CONFIG_PCI_PWRCTL_WCN7850)	+= pci-pwrctl-wcn7850.o
diff --git a/drivers/pci/pwrctl/pci-pwrctl-pwrseq.c b/drivers/pci/pwrctl/pci-pwrctl-pwrseq.c
new file mode 100644
index 000000000000..43820a727b3f
--- /dev/null
+++ b/drivers/pci/pwrctl/pci-pwrctl-pwrseq.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pci-pwrctl.h>
+#include <linux/platform_device.h>
+#include <linux/pwrseq/consumer.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+struct pci_pwrctl_pwrseq_data {
+	struct pci_pwrctl ctx;
+	struct pwrseq_desc *pwrseq;
+};
+
+static void devm_pci_pwrctl_pwrseq_power_off(void *data)
+{
+	struct pwrseq_desc *pwrseq = data;
+
+	pwrseq_power_off(pwrseq);
+}
+
+static int pci_pwrctl_pwrseq_probe(struct platform_device *pdev)
+{
+	struct pci_pwrctl_pwrseq_data *data;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->pwrseq = devm_pwrseq_get(dev, of_device_get_match_data(dev));
+	if (IS_ERR(data->pwrseq))
+		return dev_err_probe(dev, PTR_ERR(data->pwrseq),
+				     "Failed to get the power sequencer\n");
+
+	ret = pwrseq_power_on(data->pwrseq);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to power-on the device\n");
+
+	ret = devm_add_action_or_reset(dev, devm_pci_pwrctl_pwrseq_power_off,
+				       data->pwrseq);
+	if (ret)
+		return ret;
+
+	data->ctx.dev = dev;
+
+	ret = devm_pci_pwrctl_device_set_ready(dev, &data->ctx);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to register the pwrctl wrapper\n");
+
+	return 0;
+}
+
+static const struct of_device_id pci_pwrctl_pwrseq_of_match[] = {
+	{
+		/* ATH11K in QCA6390 package. */
+		.compatible = "pci17cb,1101",
+		.data = "wlan",
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pci_pwrctl_pwrseq_of_match);
+
+static struct platform_driver pci_pwrctl_pwrseq_driver = {
+	.driver = {
+		.name = "pci-pwrctl-pwrseq",
+		.of_match_table = pci_pwrctl_pwrseq_of_match,
+	},
+	.probe = pci_pwrctl_pwrseq_probe,
+};
+module_platform_driver(pci_pwrctl_pwrseq_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski at linaro.org>");
+MODULE_DESCRIPTION("Generic PCI Power Control module for power sequenced devices");
+MODULE_LICENSE("GPL");
-- 
2.40.1



From tglx at linutronix.de  Fri Feb 16 12:50:10 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 16 Feb 2024 21:50:10 +0100
Subject: [PATCH v12 22/25] irqchip: Add RISC-V advanced PLIC driver for
 direct-mode
In-Reply-To: <20240127161753.114685-23-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-23-apatel@ventanamicro.com>
Message-ID: <875xyocewt.ffs@tglx>

On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> +static int aplic_direct_irqdomain_translate(struct irq_domain *d,
> +					 struct irq_fwspec *fwspec,
> +					 unsigned long *hwirq,
> +					 unsigned int *type)

Please align the arguments to the first argument of the first line and
use the 100 characters, i.e.

static int aplic_direct_irqdomain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
					    unsigned long *hwirq, unsigned int *type)
{

All over the place.

> +{
> +	struct aplic_priv *priv = d->host_data;
> +
> +	return aplic_irqdomain_translate(fwspec, priv->gsi_base,
> +					 hwirq, type);
> +}
> +
> +static int aplic_direct_irqdomain_alloc(struct irq_domain *domain,
> +				     unsigned int virq, unsigned int nr_irqs,
> +				     void *arg)
> +{
> +	int i, ret;
> +	unsigned int type;
> +	irq_hw_number_t hwirq;
> +	struct irq_fwspec *fwspec = arg;
> +	struct aplic_priv *priv = domain->host_data;
> +	struct aplic_direct *direct =
> +			container_of(priv, struct aplic_direct, priv);

Variable ordering. Please make this consistent according to documentation.

> +	ret = aplic_irqdomain_translate(fwspec, priv->gsi_base,
> +					&hwirq, &type);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; i < nr_irqs; i++) {
> +		irq_domain_set_info(domain, virq + i, hwirq + i,
> +				    &aplic_direct_chip, priv,
> +				    handle_fasteoi_irq, NULL, NULL);
> +		irq_set_affinity(virq + i, &direct->lmask);
> +		/* See the reason described in aplic_msi_irqdomain_alloc() */

I still have to understand that "reason". :)

> +		irq_set_status_flags(virq + i, IRQ_DISABLE_UNLAZY);
> +	}

Thanks,

        tglx


From bot at kernelci.org  Fri Feb 16 12:56:52 2024
From: bot at kernelci.org (kernelci.org bot)
Date: Fri, 16 Feb 2024 12:56:52 -0800 (PST)
Subject: arm64/for-kernelci build: 1 build: 0 failed, 1 passed,
 1 warning (v6.8-rc4-55-g905b00721763)
Message-ID: <65cfcc14.170a0220.b8b50.24d9@mx.google.com>

arm64/for-kernelci build: 1 build: 0 failed, 1 passed, 1 warning (v6.8-rc4-55-g905b00721763)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v6.8-rc4-55-g905b00721763/

Tree: arm64
Branch: for-kernelci
Git Describe: v6.8-rc4-55-g905b00721763
Git Commit: 905b007217637b34a6a877271f21ed0dada0f564
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

Warnings Detected:

arm64:
    defconfig (gcc-10): 1 warning


Warnings summary:

    1    security/security.c:810:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
defconfig (arm64, gcc-10) ? PASS, 0 errors, 1 warning, 0 section mismatches

Warnings:
    security/security.c:810:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

---
For more info write to <info at kernelci.org>


From tglx at linutronix.de  Fri Feb 16 13:04:03 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 16 Feb 2024 22:04:03 +0100
Subject: [PATCH v12 23/25] irqchip/riscv-aplic: Add support for MSI-mode
In-Reply-To: <20240127161753.114685-24-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-24-apatel@ventanamicro.com>
Message-ID: <8734tsce9o.ffs@tglx>

On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> We extend the existing APLIC irqchip driver to support MSI-mode for
> RISC-V platforms having both wired interrupts and MSIs.

We? Just s/We//

> +
> +static void aplic_msi_irq_unmask(struct irq_data *d)
> +{
> +	aplic_irq_unmask(d);
> +	irq_chip_unmask_parent(d);
> +}
> +
> +static void aplic_msi_irq_mask(struct irq_data *d)
> +{
> +	aplic_irq_mask(d);
> +	irq_chip_mask_parent(d);
> +}

Again asymmetric vs. unmask()

> +static void aplic_msi_irq_eoi(struct irq_data *d)
> +{
> +	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> +	u32 reg_off, reg_mask;
> +
> +	/*
> +	 * EOI handling only required only for level-triggered
> +	 * interrupts in APLIC MSI mode.
> +	 */
> +
> +	reg_off = APLIC_CLRIP_BASE + ((d->hwirq / APLIC_IRQBITS_PER_REG) * 4);
> +	reg_mask = BIT(d->hwirq % APLIC_IRQBITS_PER_REG);
> +	switch (irqd_get_trigger_type(d)) {
> +	case IRQ_TYPE_LEVEL_LOW:
> +		if (!(readl(priv->regs + reg_off) & reg_mask))
> +			writel(d->hwirq, priv->regs + APLIC_SETIPNUM_LE);

A comment what this condition is for would be nice.

Thanks,

        tglx


From tglx at linutronix.de  Fri Feb 16 13:05:36 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 16 Feb 2024 22:05:36 +0100
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <87v86pcxcb.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <CAK9=C2Vwtj2gZg-P73yLMxu0rPXQ3YrRRuxq6HcpHMXgs-jHaw@mail.gmail.com>
 <87bk8ig6t2.ffs@tglx>
 <CAK9=C2WsSSHgDF+7ruxx_QF0Lk+Dsx2F2Y-_NabnxrJ_qWhgGQ@mail.gmail.com>
 <87v86pcxcb.ffs@tglx>
Message-ID: <87zfw0azmn.ffs@tglx>

Anup!

On Thu, Feb 15 2024 at 20:59, Thomas Gleixner wrote:
> I'm going over the rest of the series after I dealt with my other patch
> backlog.

Aside of the nitpicks I had, this looks pretty reasonable.

Thanks,

        tglx


From cki-project at redhat.com  Fri Feb 16 13:11:07 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Fri, 16 Feb 2024 21:11:07 -0000
Subject: =?utf-8?b?4pyF?= PASS (MISSED 2 of 87): Test report for for-kernelci
 (6.8.0-rc4, arm-next, 905b0072)
Message-ID: <80094.124021616110800497@us-mta-458.us.mimecast.lan>

Hi, we tested your kernel and here are the results:

    Overall result: PASSED
             Merge: OK
           Compile: OK
              Test: OK

Tested-by: CKI Project <cki-project at redhat.com>

Kernel information:
    Commit message: Merge branch 'for-next/core' into for-kernelci

You can find all the details about the test run at
    https://datawarehouse.cki-project.org/kcidb/checkouts/129930

One or more kernel tests failed:
    We also see the following known issues which are not related to your changes:
        Issue: [rawhide] avc:  denied  { read write } for  pid=12364 comm="plymouthd" name="kmsg" dev="devtmpfs" ino=10 scontext=system_u:system_r:plymouthd_t:s0 tcontext=system_u:object_r:kmsg_device_t:s0 tclass=chr_file permissive=1
            URL: https://bugzilla.redhat.com/show_bug.cgi?id=2256442
            Affected tests:
                 aarch64 - Boot test
                 aarch64 - stress: stress-ng - cpu-cache
                 aarch64 - Reboot test
        Issue: [upstream] stress-ng: avc denial on secretmemory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1752
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: stress: stress-ng - memory: (panic) Comm: systemd-oomd Not tainted 6.1.0-rc3
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1461
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: Firmware test suite: mv: cannot stat 'dtcompilerparser.tab.c': No such file or directory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1544
            Affected tests:
                 aarch64 - Hardware - Firmware test suite


Tests that were not ran because of internal issues: 
     aarch64 - Memory function: memfd_create
     aarch64 - Memory function: memfd_create


If you find a failure unrelated to your changes, please ask the test maintainer to review it.
This will prevent the failures from being incorrectly reported in the future.

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
           `-'
______________________________________________________________________________



From eabachinin at salutedevices.com  Fri Feb 16 13:16:39 2024
From: eabachinin at salutedevices.com (Evgeny Bachinin)
Date: Sat, 17 Feb 2024 00:16:39 +0300
Subject: [PATCH 3/5] firmware: meson_sm: move common definitions to
 header file
In-Reply-To: <20231122125643.1717160-4-adeep@lexina.in>
References: <20231122125643.1717160-1-adeep@lexina.in>
 <20231122125643.1717160-4-adeep@lexina.in>
Message-ID: <7zhsafmokydl3fxtfsjjnhizq6tidxsuefqcemsqqwqdje6m4p@gxfz3ajr76mv>

On Wed, Nov 22, 2023 at 03:56:41PM +0300, Viacheslav Bocharov wrote:
> Move SM_CHIPID_* constants from firmware meson sm driver to
> header file.
> 
> Signed-off-by: Viacheslav Bocharov <adeep at lexina.in>
> ---
>  drivers/firmware/meson/meson_sm.c       | 4 ----
>  include/linux/firmware/meson/meson_sm.h | 4 ++++
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
> index 402851ed4ac0..96e50811336f 100644
> --- a/drivers/firmware/meson/meson_sm.c
> +++ b/drivers/firmware/meson/meson_sm.c
> @@ -240,10 +240,6 @@ struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node)
>  }
>  EXPORT_SYMBOL_GPL(meson_sm_get);
>  
> -#define SM_CHIP_ID_LENGTH	119
> -#define SM_CHIP_ID_OFFSET	4
> -#define SM_CHIP_ID_SIZE		12
> -
>  static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
>  			 char *buf)
>  {
> diff --git a/include/linux/firmware/meson/meson_sm.h b/include/linux/firmware/meson/meson_sm.h
> index 8eaf8922ab02..f62acd2bf52a 100644
> --- a/include/linux/firmware/meson/meson_sm.h
> +++ b/include/linux/firmware/meson/meson_sm.h
> @@ -7,6 +7,10 @@
>  #ifndef _MESON_SM_FW_H_
>  #define _MESON_SM_FW_H_
>  
> +#define SM_CHIP_ID_LENGTH	119

Does anybody know why this value is 119 bytes?
if in-shmem data, arrived from BL31, contains only up to 20 bytes
(in case of chipID v2):
+-----------+---------+---------------------------------+
| chipID ver|  cpu_id |        12b-serial               |
|  4 bytes  | 4 bytes |(per particular die unique data) |
+-----------+---------+---------------------------------+

> +#define SM_CHIP_ID_OFFSET	4
> +#define SM_CHIP_ID_SIZE		12

It seems that either the value (12) is incorrect or the current naming
is misleading. This is because the chipID is 16 bytes. Of course,
likely the SoC serial was meant here...

Furthermore, it appears that SM_CHIP_ID_SIZE is an unused symbol. It
has been unused since its creation in
0789724f86a5 ('firmware: meson_sm: Add serial number sysfs entry')

> +
>  enum {
>  	SM_EFUSE_READ,
>  	SM_EFUSE_WRITE,
> -- 
> 2.34.1
> 
> 

-- 
Best Regards,
Evgeny Bachinin


From bot at kernelci.org  Fri Feb 16 13:40:12 2024
From: bot at kernelci.org (kernelci.org bot)
Date: Fri, 16 Feb 2024 13:40:12 -0800 (PST)
Subject: arm64/for-kernelci baseline: 44 runs,
 7 regressions (v6.8-rc4-55-g905b00721763)
Message-ID: <65cfd63c.170a0220.3bec4.281d@mx.google.com>

arm64/for-kernelci baseline: 44 runs, 7 regressions (v6.8-rc4-55-g905b00721763)

Regressions Summary
-------------------

platform               | arch  | lab         | compiler | defconfig | regressions
-----------------------+-------+-------------+----------+-----------+------------
kontron-kbox-a-230-ls  | arm64 | lab-kontron | gcc-10   | defconfig | 5          
kontron-sl28-var3-ads2 | arm64 | lab-kontron | gcc-10   | defconfig | 2          

  Details:  https://kernelci.org/test/job/arm64/branch/for-kernelci/kernel/v6.8-rc4-55-g905b00721763/plan/baseline/

  Test:     baseline
  Tree:     arm64
  Branch:   for-kernelci
  Describe: v6.8-rc4-55-g905b00721763
  URL:      https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
  SHA:      905b007217637b34a6a877271f21ed0dada0f564 


Test Regressions
---------------- 


platform               | arch  | lab         | compiler | defconfig | regressions
-----------------------+-------+-------------+----------+-----------+------------
kontron-kbox-a-230-ls  | arm64 | lab-kontron | gcc-10   | defconfig | 5          

  Details:     https://kernelci.org/test/plan/id/65cfcc5690e9c84fa5637013

  Results:     90 PASS, 5 FAIL, 1 SKIP
  Full config: defconfig
  Compiler:    gcc-10 (aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc4-55-g905b00721763/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-kbox-a-230-ls.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc4-55-g905b00721763/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-kbox-a-230-ls.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230623.0/arm64/rootfs.cpio.gz 


  * baseline.bootrr.deferred-probe-empty: https://kernelci.org/test/case/id/65cfcc5690e9c84fa5637016
        failing since 17 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-16T20:57:38.157153  / # #
    2024-02-16T20:57:38.259335  export SHELL=/bin/sh
    2024-02-16T20:57:38.260071  #
    2024-02-16T20:57:38.361491  / # export SHELL=/bin/sh. /lava-431251/environment
    2024-02-16T20:57:38.362250  
    2024-02-16T20:57:38.463761  / # . /lava-431251/environment/lava-431251/bin/lava-test-runner /lava-431251/1
    2024-02-16T20:57:38.464917  
    2024-02-16T20:57:38.510276  / # /lava-431251/bin/lava-test-runner /lava-431251/1
    2024-02-16T20:57:38.572957  + export 'TESTRUN_ID=1_bootrr'
    2024-02-16T20:57:38.573393  + cd /lava-431251/1/tests/1_bootrr 
    ... (14 line(s) more)  

  * baseline.bootrr.fsl_enetc-enetc2-probed: https://kernelci.org/test/case/id/65cfcc5690e9c84fa563701a
        failing since 17 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-16T20:57:40.787352  /lava-431251/1/../bin/lava-test-case
    2024-02-16T20:57:40.815284  <8>[   26.137644] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc2-probed RESULT=fail>   

  * baseline.bootrr.mscc_felix-probed: https://kernelci.org/test/case/id/65cfcc5690e9c84fa563701c
        failing since 17 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-16T20:57:41.876654  /lava-431251/1/../bin/lava-test-case
    2024-02-16T20:57:41.903559  <8>[   27.226585] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=mscc_felix-probed RESULT=fail>   

  * baseline.bootrr.fsl_enetc-enetc0-probed: https://kernelci.org/test/case/id/65cfcc5690e9c84fa5637021
        failing since 17 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-16T20:57:43.137986  /lava-431251/1/../bin/lava-test-case
    2024-02-16T20:57:43.165934  <8>[   28.488082] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc0-probed RESULT=fail>   

  * baseline.bootrr.fsl_enetc-enetc1-probed: https://kernelci.org/test/case/id/65cfcc5690e9c84fa5637022
        failing since 17 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-16T20:57:44.189791  /lava-431251/1/../bin/lava-test-case
    2024-02-16T20:57:44.216915  <8>[   29.538565] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc1-probed RESULT=fail>   
 


platform               | arch  | lab         | compiler | defconfig | regressions
-----------------------+-------+-------------+----------+-----------+------------
kontron-sl28-var3-ads2 | arm64 | lab-kontron | gcc-10   | defconfig | 2          

  Details:     https://kernelci.org/test/plan/id/65cfcc7f90e9c84fa56373b5

  Results:     101 PASS, 2 FAIL, 1 SKIP
  Full config: defconfig
  Compiler:    gcc-10 (aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc4-55-g905b00721763/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-sl28-var3-ads2.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc4-55-g905b00721763/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-sl28-var3-ads2.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230623.0/arm64/rootfs.cpio.gz 


  * baseline.bootrr.deferred-probe-empty: https://kernelci.org/test/case/id/65cfcc7f90e9c84fa56373b8
        failing since 17 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-16T20:58:09.540318  / # #
    2024-02-16T20:58:09.642404  export SHELL=/bin/sh
    2024-02-16T20:58:09.643124  #
    2024-02-16T20:58:09.744781  / # export SHELL=/bin/sh. /lava-431249/environment
    2024-02-16T20:58:09.745504  
    2024-02-16T20:58:09.846852  / # . /lava-431249/environment/lava-431249/bin/lava-test-runner /lava-431249/1
    2024-02-16T20:58:09.847798  
    2024-02-16T20:58:09.865628  / # /lava-431249/bin/lava-test-runner /lava-431249/1
    2024-02-16T20:58:09.953838  + export 'TESTRUN_ID=1_bootrr'
    2024-02-16T20:58:09.954302  + cd /lava-431249/1/tests/1_bootrr 
    ... (10 line(s) more)  

  * baseline.bootrr.fsl_enetc-enetc0-probed: https://kernelci.org/test/case/id/65cfcc7f90e9c84fa56373cb
        failing since 17 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-16T20:58:12.893473  /lava-431249/1/../bin/lava-test-case
    2024-02-16T20:58:12.922356  <8>[   27.183603] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc0-probed RESULT=fail>   
  


From eabachinin at salutedevices.com  Fri Feb 16 13:53:41 2024
From: eabachinin at salutedevices.com (Evgeny Bachinin)
Date: Sat, 17 Feb 2024 00:53:41 +0300
Subject: [PATCH 4/5] soc: amlogic: Add Amlogic secure-monitor SoC
 Information driver
In-Reply-To: <20231122125643.1717160-5-adeep@lexina.in>
References: <20231122125643.1717160-1-adeep@lexina.in>
 <20231122125643.1717160-5-adeep@lexina.in>
Message-ID: <vln6wuzy3hdql6wwwghmwoetywm24jzzhzy6wutr6qphjl42hr@vfdsc737cust>

please, see notes below

On Wed, Nov 22, 2023 at 03:56:42PM +0300, Viacheslav Bocharov wrote:
> Amlogic SoCs have a SoC information secure-monitor call for SoC type,
> package type, revision information and chipid.
> This patchs adds support for secure-monitor call decoding and exposing


s/patchs/patch/


> with the SoC bus infrastructure in addition to the previous SoC
> Information driver.
> 
> Signed-off-by: Viacheslav Bocharov <adeep at lexina.in>
> ---
>  drivers/soc/amlogic/Kconfig               |  10 ++
>  drivers/soc/amlogic/Makefile              |   1 +
>  drivers/soc/amlogic/meson-gx-socinfo-sm.c | 178 ++++++++++++++++++++++
>  3 files changed, 189 insertions(+)
>  create mode 100644 drivers/soc/amlogic/meson-gx-socinfo-sm.c
> 
> diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig
> index d08e398bdad4..5634ecb60478 100644
> --- a/drivers/soc/amlogic/Kconfig
> +++ b/drivers/soc/amlogic/Kconfig
> @@ -26,6 +26,16 @@ config MESON_GX_SOCINFO
>  	  Say yes to support decoding of Amlogic Meson GX SoC family
>  	  information about the type, package and version.
>  
> +config MESON_GX_SOCINFO_SM
> +	bool "Amlogic Meson GX SoC Information driver via Secure Monitor"
> +	depends on (ARM64 && ARCH_MESON && MESON_GX_SOCINFO && MESON_SM) || COMPILE_TEST
> +	default MESON_GX_SOCINFO && MESON_SM
> +	select SOC_BUS
> +	help
> +	  Say yes to support decoding of Amlogic Meson GX SoC family
> +	  information about the type, package and version from secure
> +	  monitor call.
> +
>  config MESON_MX_SOCINFO
>  	bool "Amlogic Meson MX SoC Information driver"
>  	depends on (ARM && ARCH_MESON) || COMPILE_TEST
> diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile
> index c25f835e6a26..45d9d6f5904c 100644
> --- a/drivers/soc/amlogic/Makefile
> +++ b/drivers/soc/amlogic/Makefile
> @@ -2,4 +2,5 @@
>  obj-$(CONFIG_MESON_CANVAS) += meson-canvas.o
>  obj-$(CONFIG_MESON_CLK_MEASURE) += meson-clk-measure.o
>  obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
> +obj-$(CONFIG_MESON_GX_SOCINFO_SM) += meson-gx-socinfo-sm.o
>  obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o
> diff --git a/drivers/soc/amlogic/meson-gx-socinfo-sm.c b/drivers/soc/amlogic/meson-gx-socinfo-sm.c
> new file mode 100644
> index 000000000000..52bf3bce09e2
> --- /dev/null
> +++ b/drivers/soc/amlogic/meson-gx-socinfo-sm.c
> @@ -0,0 +1,178 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2023 JetHome
> + * Author: Viacheslav Bocharov <adeep at lexina.in>
> + *
> + */
> +
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/sys_soc.h>
> +#include <linux/bitfield.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +
> +#include <linux/firmware/meson/meson_sm.h>
> +
> +#include "meson-gx-socinfo-internal.h"
> +
> +static char *socinfo_get_cpuid(struct device *dev, struct meson_sm_firmware *fw,
> +			       unsigned int *socinfo)
> +{
> +	char *buf;
> +	uint8_t *id_buf;
> +	int chip_id_version;
> +	int ret;
> +
> +	id_buf = devm_kzalloc(dev, SM_CHIP_ID_LENGTH, GFP_KERNEL);
> +	if (!id_buf)
> +		return NULL;
> +
> +	ret = meson_sm_call_read(fw, id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
> +				 2, 0, 0, 0, 0);
> +	if (ret < 0) {
> +		kfree(id_buf);
> +		return NULL;
> +	}
> +
> +	chip_id_version = *((unsigned int *)id_buf);
> +
> +	if (chip_id_version != 2) {
> +		uint8_t tmp;

minor:
The scope of the variable 'tmp' can be reduced.

Up to you, guys. I just highlighted here.

> +		/**
> +		 * Legacy 12-byte chip ID read out, transform data

The Amlogic chipID v1 and v2 are both 16 bytes long. Probably,
the "serial" was intended here under "12 byte". However, since we are
dealing with chipID in this function, wouldn't it be better to just
remove "12-byte"?"


> +		 * to expected order format
> +		 */
> +
> +		memmove(&id_buf[SM_CHIP_ID_OFFSET + 4], &id_buf[SM_CHIP_ID_OFFSET], 12);
> +		for (int i = 0; i < 6; i++) {
> +			tmp = id_buf[i + SM_CHIP_ID_OFFSET + 4];
> +			id_buf[i + SM_CHIP_ID_OFFSET + 4] = id_buf[15 - i + SM_CHIP_ID_OFFSET];
> +			id_buf[15 - i + SM_CHIP_ID_OFFSET] = tmp;
> +		}
> +		*(uint32_t *)(id_buf + SM_CHIP_ID_OFFSET) =
> +					((*socinfo & 0xff000000)	|	// Family ID
> +					((*socinfo << 8) & 0xff0000)	|	// Chip Revision
> +					((*socinfo >> 8) & 0xff00))	|	// Package ID
> +					((*socinfo) & 0xff);			// Misc
> +	} else {
> +		*socinfo = id_buf[SM_CHIP_ID_OFFSET] << 24 |	// Family ID
> +		   id_buf[SM_CHIP_ID_OFFSET + 2] << 16 |	// Chip revision
> +		   id_buf[SM_CHIP_ID_OFFSET + 1] << 8 |		// Package ID
> +		   id_buf[SM_CHIP_ID_OFFSET + 3];		// Misc
> +	}
> +
> +	buf = kasprintf(GFP_KERNEL, "%16phN\n", &id_buf[SM_CHIP_ID_OFFSET]);
> +	kfree(id_buf);
> +
> +	return buf;
> +}
> +
> +static int meson_gx_socinfo_sm_probe(struct platform_device *pdev)
> +{
> +	struct soc_device_attribute *soc_dev_attr;
> +	struct soc_device *soc_dev;
> +	struct device_node *sm_np;
> +	struct meson_sm_firmware *fw;
> +	struct regmap *regmap;
> +	unsigned int socinfo;
> +	struct device *dev;
> +	int ret;
> +
> +	/* check if chip-id is available */

My apologies for nitpicking, but looks like the term "has-chip-id" is
misleading, too.
AFAIU it does not reflect the presence of the chipID in a particular
Amlogic SoC. Instead, it specifies the driver's ability to read the
cpu_id value from the register (via regmap). Therefore, I think,
it would be more accurate to call it as "has-cpu-id", although it seems
"has-chip-id" term is a legacy now.

> +	if (!of_property_read_bool(pdev->dev.of_node, "amlogic,has-chip-id"))
> +		return -ENODEV;
> +
> +	/* node should be a syscon */
> +	regmap = syscon_node_to_regmap(pdev->dev.of_node);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&pdev->dev, "failed to get regmap\n");
> +		return -ENODEV;
> +	}
> +
> +	sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
> +	if (!sm_np) {
> +		dev_err(&pdev->dev, "no secure-monitor node found\n");
> +		return -ENODEV;
> +	}
> +
> +	fw = meson_sm_get(sm_np);
> +	of_node_put(sm_np);
> +	if (!fw)
> +		return -EPROBE_DEFER;
> +
> +	dev_err(&pdev->dev, "secure-monitor node found\n");

Debug leftover?
Strange to see an error in the non-error path. I mean is it proper
log level?

> +
> +	ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (!socinfo) {
> +		dev_err(&pdev->dev, "invalid regmap chipid value\n");

s/chipid/cpuid/ ?
because value read from register is actually 4 byte cpuid

> +		return -EINVAL;
> +	}
> +
> +	soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr),
> +				    GFP_KERNEL);
> +	if (!soc_dev_attr)
> +		return -ENOMEM;
> +
> +	soc_dev_attr->serial_number = socinfo_get_cpuid(&pdev->dev, fw, &socinfo);

Several notes.

1) Could you please clarify, why don't you pass socinfo by value?

What's the necessity to overwrite inside socinfo_get_cpuid() the
socinfo value read above via regmap?

2) Seems, again names' collision.
Actually, the function returns the chipid as a retval (16 bytes,
consisting of cpu_id + SoC serial), but the function is named as
socinfo_get_cpuid(). The reason for this could be that the distinct
function carries out two actions (returning socinfo and chipid) instead
of just one specific action.

All in all, what do you think, could the function be renamed as
s/socinfo_get_cpuid/socinfo_get_chipid/ ?

> +
> +	meson_gx_socinfo_prepare_soc_driver_attr(soc_dev_attr, socinfo);
> +
> +	soc_dev = soc_device_register(soc_dev_attr);
> +	if (IS_ERR(soc_dev)) {
> +		kfree(soc_dev_attr->revision);
> +		kfree_const(soc_dev_attr->soc_id);
> +		kfree(soc_dev_attr);
> +		return PTR_ERR(soc_dev);
> +	}
> +
> +	dev = soc_device_to_device(soc_dev);
> +	platform_set_drvdata(pdev, soc_dev);
> +
> +	dev_info(dev, "Amlogic Meson %s Revision %x:%x (%x:%x) Detected at SM driver %x\n",
> +			soc_dev_attr->soc_id,
> +			socinfo_to_major(socinfo),
> +			socinfo_to_minor(socinfo),
> +			socinfo_to_pack(socinfo),
> +			socinfo_to_misc(socinfo), socinfo);
> +
> +	return PTR_ERR_OR_ZERO(dev);
> +}
> +
> +

is extra line supposed?

> +static int meson_gx_socinfo_sm_remove(struct platform_device *pdev)
> +{
> +	struct soc_device *soc_dev = platform_get_drvdata(pdev);
> +
> +	soc_device_unregister(soc_dev);
> +	return 0;
> +}
> +
> +static const struct of_device_id meson_gx_socinfo_match[] = {
> +	{ .compatible = "amlogic,meson-gx-ao-secure", },
> +	{ /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, meson_gx_socinfo_match);
> +
> +static struct platform_driver meson_gx_socinfo_driver = {
> +	.probe = meson_gx_socinfo_sm_probe,
> +	.remove	= meson_gx_socinfo_sm_remove,
> +	.driver = {
> +		.name = "meson-gx-socinfo-sm",
> +		.of_match_table = meson_gx_socinfo_match,
> +	},
> +};
> +
> +

extra line?

> +module_platform_driver(meson_gx_socinfo_driver);
> +
> +MODULE_AUTHOR("Viacheslav Bocharov <adeep at lexina.in>");
> +MODULE_DESCRIPTION("Amlogic Meson GX SOC SM driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.34.1
> 
> 

-- 
Best Regards,
Evgeny Bachinin


From semen.protsenko at linaro.org  Fri Feb 16 14:32:29 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:29 -0600
Subject: [PATCH 00/16] clk: samsung: Add CPU clocks for Exynos850
Message-ID: <20240216223245.12273-1-semen.protsenko@linaro.org>

The series implements CPU clock support for Exynos850, adds CPU CMUs to
the clock driver and enables those in dts. This is the first step
towards cpufreq implementation.

The breakup by patch:

  * Patch 01: Add bindings
  * Patches 02..12: Prepare clk-cpu.c for Exynos850 support
  * Patch 13: Add Exynos850 support
  * Patch 14: Init PLLs to be in manual mode
  * Patch 15: Add CPU CMUs in Exynos850 clock driver
  * Patch 16: Add CPU CMUs and clocks in Exynos850 dtsi

If possible, all patches should go through Krzysztof's tree. As
inter-series dependencies go:

  * All driver changes (patch 02..15) must be taken together following
    the order established in this series
  * Patch 16 (dts changes) depends on patch 01 (bindings additions)
  * Patch 15 (driver changes) depends on patch 01 (bindings additions)

The series was tested on E850-96 board, via DebugFS with
CLOCK_ALLOW_WRITE_DEBUGFS enabled, by setting different CPU clock rates,
like this:

  # cd /sys/kernel/debug/clk/cluster0_clk/
  # cat clk_rate
  1053000000
  # echo 10000000 > clk_rate
  # cat clk_rate
  130000000

Of course, DVFS/cpufreq is not implemented yet, so the CPU can't be
overclocked too much right now, and the cpufreq interface is not
available too. As per the TRM, the CPU operates at a voltage level of
0.65 V, 0.75 V, 0.85 V and 1.05 V. When the voltage is 0.85 V, A55
quad-core operates at 1.6 GHz and CoreSight at 200 MHz.

To check the actual frequency, the "perf" tool was used:

  # perf stat sleep 1

And to check that on a particular CPU core:

  # taskset -c 4 perf stat sleep 1

Some takeaways:

  * Max functional frequency right now is 1.586 GHz
  * 1.742 GHz or more leads to the system freeze, as it requires
    more voltage to be operational
  * Max possible frequency: 2.210 GHz
  * The lowest possible frequency: 130 MHz
  * Default boot up frequency: 1.053 GHz

Sam Protsenko (16):
  dt-bindings: clock: exynos850: Add CMU_CPUCLK0 and CMU_CPUCL1
  clk: samsung: Improve clk-cpu.c style
  clk: samsung: Pull struct exynos_cpuclk into clk-cpu.c
  clk: samsung: Reduce params count in exynos_register_cpu_clock()
  clk: samsung: Use single CPU clock notifier callback for all chips
  clk: samsung: Group CPU clock functions by chip
  clk: samsung: Pass actual clock controller base address to CPU_CLK()
  clk: samsung: Use clk.h as a single header for Samsung CCF
  clk: samsung: Pass register layout type explicitly to CLK_CPU()
  clk: samsung: Keep CPU clock chip specific data in a dedicated struct
  clk: samsung: Keep register offsets in chip specific structure
  clk: samsung: Pass mask to wait_until_mux_stable()
  clk: samsung: Add CPU clock support for Exynos850
  clk: samsung: Implement manual PLL control for ARM64 SoCs
  clk: samsung: exynos850: Add CMU_CPUCL0 and CMU_CPUCL1
  arm64: dts: exynos: Add CPU clocks

 .../clock/samsung,exynos850-clock.yaml        |  42 ++
 arch/arm64/boot/dts/exynos/exynos850.dtsi     |  26 +
 drivers/clk/samsung/clk-cpu.c                 | 565 +++++++++++++-----
 drivers/clk/samsung/clk-cpu.h                 |  53 +-
 drivers/clk/samsung/clk-exynos-arm64.c        |  44 +-
 drivers/clk/samsung/clk-exynos3250.c          |   4 +-
 drivers/clk/samsung/clk-exynos4.c             |  10 +-
 drivers/clk/samsung/clk-exynos5250.c          |   6 +-
 drivers/clk/samsung/clk-exynos5260.c          |   1 -
 drivers/clk/samsung/clk-exynos5420.c          |  17 +-
 drivers/clk/samsung/clk-exynos5433.c          |  12 +-
 drivers/clk/samsung/clk-exynos850.c           | 440 +++++++++++++-
 drivers/clk/samsung/clk-pll.c                 |   2 +-
 drivers/clk/samsung/clk-s3c64xx.c             |   1 -
 drivers/clk/samsung/clk-s5pv210.c             |   1 -
 drivers/clk/samsung/clk.h                     |   9 +-
 include/dt-bindings/clock/exynos850.h         |  54 ++
 17 files changed, 1042 insertions(+), 245 deletions(-)

-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:30 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:30 -0600
Subject: [PATCH 01/16] dt-bindings: clock: exynos850: Add CMU_CPUCLK0 and CMU_CPUCL1
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-2-semen.protsenko@linaro.org>

Document CPU clock management unit compatibles and add corresponding
clock indices. Exynos850 has two CPU clusters (CL0 and CL1), each
containing 4 Cortex-A55 cores. CPU PLLs are generating main CPU clocks
for each cluster, and there are alternate ("switch") clocks that can be
used temporarily while re-configuring the PLL for the new rate. ACLK,
ATCLK, PCLKDBG and PERIPHCLK clocks are driving corresponding buses.
CLK_CLUSTERx_SCLK are actual leaf CPU clocks and should be used to
change CPU rates. Also some CoreSight clocks can be derived from
DBG_USER (debug clock).

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../clock/samsung,exynos850-clock.yaml        | 42 +++++++++++++++
 include/dt-bindings/clock/exynos850.h         | 54 +++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
index c752c8985a53..cdc5ded59fe5 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
@@ -36,6 +36,8 @@ properties:
       - samsung,exynos850-cmu-aud
       - samsung,exynos850-cmu-cmgp
       - samsung,exynos850-cmu-core
+      - samsung,exynos850-cmu-cpucl0
+      - samsung,exynos850-cmu-cpucl1
       - samsung,exynos850-cmu-dpu
       - samsung,exynos850-cmu-g3d
       - samsung,exynos850-cmu-hsi
@@ -152,6 +154,46 @@ allOf:
             - const: dout_core_mmc_embd
             - const: dout_core_sss
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-cpucl0
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CPUCL0 switch clock (from CMU_TOP)
+            - description: CPUCL0 debug clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_cpucl0_switch
+            - const: dout_cpucl0_dbg
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-cpucl1
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CPUCL1 switch clock (from CMU_TOP)
+            - description: CPUCL1 debug clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_cpucl1_switch
+            - const: dout_cpucl1_dbg
+
   - if:
       properties:
         compatible:
diff --git a/include/dt-bindings/clock/exynos850.h b/include/dt-bindings/clock/exynos850.h
index bc15108aa3c2..7666241520f8 100644
--- a/include/dt-bindings/clock/exynos850.h
+++ b/include/dt-bindings/clock/exynos850.h
@@ -88,6 +88,18 @@
 #define CLK_MOUT_G3D_SWITCH		76
 #define CLK_GOUT_G3D_SWITCH		77
 #define CLK_DOUT_G3D_SWITCH		78
+#define CLK_MOUT_CPUCL0_DBG		79
+#define CLK_MOUT_CPUCL0_SWITCH		80
+#define CLK_GOUT_CPUCL0_DBG		81
+#define CLK_GOUT_CPUCL0_SWITCH		82
+#define CLK_DOUT_CPUCL0_DBG		83
+#define CLK_DOUT_CPUCL0_SWITCH		84
+#define CLK_MOUT_CPUCL1_DBG		85
+#define CLK_MOUT_CPUCL1_SWITCH		86
+#define CLK_GOUT_CPUCL1_DBG		87
+#define CLK_GOUT_CPUCL1_SWITCH		88
+#define CLK_DOUT_CPUCL1_DBG		89
+#define CLK_DOUT_CPUCL1_SWITCH		90
 
 /* CMU_APM */
 #define CLK_RCO_I3C_PMIC		1
@@ -195,6 +207,48 @@
 #define CLK_GOUT_CMGP_USI1_PCLK		14
 #define CLK_GOUT_SYSREG_CMGP_PCLK	15
 
+/* CMU_CPUCL0 */
+#define CLK_FOUT_CPUCL0_PLL		1
+#define CLK_MOUT_PLL_CPUCL0		2
+#define CLK_MOUT_CPUCL0_SWITCH_USER	3
+#define CLK_MOUT_CPUCL0_DBG_USER	4
+#define CLK_MOUT_CPUCL0_PLL		5
+#define CLK_DOUT_CPUCL0_CPU		6
+#define CLK_DOUT_CPUCL0_CMUREF		7
+#define CLK_DOUT_CPUCL0_PCLK		8
+#define CLK_DOUT_CLUSTER0_ACLK		9
+#define CLK_DOUT_CLUSTER0_ATCLK		10
+#define CLK_DOUT_CLUSTER0_PCLKDBG	11
+#define CLK_DOUT_CLUSTER0_PERIPHCLK	12
+#define CLK_GOUT_CLUSTER0_ATCLK		13
+#define CLK_GOUT_CLUSTER0_PCLK		14
+#define CLK_GOUT_CLUSTER0_PERIPHCLK	15
+#define CLK_GOUT_CLUSTER0_SCLK		16
+#define CLK_GOUT_CPUCL0_CMU_CPUCL0_PCLK	17
+#define CLK_GOUT_CLUSTER0_CPU		18
+#define CLK_CLUSTER0_SCLK		19
+
+/* CMU_CPUCL1 */
+#define CLK_FOUT_CPUCL1_PLL		1
+#define CLK_MOUT_PLL_CPUCL1		2
+#define CLK_MOUT_CPUCL1_SWITCH_USER	3
+#define CLK_MOUT_CPUCL1_DBG_USER	4
+#define CLK_MOUT_CPUCL1_PLL		5
+#define CLK_DOUT_CPUCL1_CPU		6
+#define CLK_DOUT_CPUCL1_CMUREF		7
+#define CLK_DOUT_CPUCL1_PCLK		8
+#define CLK_DOUT_CLUSTER1_ACLK		9
+#define CLK_DOUT_CLUSTER1_ATCLK		10
+#define CLK_DOUT_CLUSTER1_PCLKDBG	11
+#define CLK_DOUT_CLUSTER1_PERIPHCLK	12
+#define CLK_GOUT_CLUSTER1_ATCLK		13
+#define CLK_GOUT_CLUSTER1_PCLK		14
+#define CLK_GOUT_CLUSTER1_PERIPHCLK	15
+#define CLK_GOUT_CLUSTER1_SCLK		16
+#define CLK_GOUT_CPUCL1_CMU_CPUCL1_PCLK	17
+#define CLK_GOUT_CLUSTER1_CPU		18
+#define CLK_CLUSTER1_SCLK		19
+
 /* CMU_G3D */
 #define CLK_FOUT_G3D_PLL		1
 #define CLK_MOUT_G3D_PLL		2
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:31 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:31 -0600
Subject: [PATCH 02/16] clk: samsung: Improve clk-cpu.c style
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-3-semen.protsenko@linaro.org>

clk-cpu.c has numerous style issues reported by checkpatch and easily
identified otherwise. Give it some love and fix those warnings where it
makes sense. Also make stabilization time a named constant to get rid of
the magic number in clk-cpu.c.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c | 65 ++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 32 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 3e62ade120c5..e02730776aaa 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -16,18 +16,18 @@
  * of the SoC or supplied after the SoC characterization.
  *
  * The below implementation of the CPU clock allows the rate changes of the CPU
- * clock and the corresponding rate changes of the auxillary clocks of the CPU
+ * clock and the corresponding rate changes of the auxiliary clocks of the CPU
  * domain. The platform clock driver provides a clock register configuration
  * for each configurable rate which is then used to program the clock hardware
- * registers to acheive a fast co-oridinated rate change for all the CPU domain
+ * registers to achieve a fast coordinated rate change for all the CPU domain
  * clocks.
  *
  * On a rate change request for the CPU clock, the rate change is propagated
- * upto the PLL supplying the clock to the CPU domain clock blocks. While the
+ * up to the PLL supplying the clock to the CPU domain clock blocks. While the
  * CPU domain PLL is reconfigured, the CPU domain clocks are driven using an
  * alternate clock source. If required, the alternate clock source is divided
  * down in order to keep the output clock rate within the previous OPP limits.
-*/
+ */
 
 #include <linux/errno.h>
 #include <linux/io.h>
@@ -50,17 +50,19 @@
 #define E5433_DIV_STAT_CPU0	0x500
 #define E5433_DIV_STAT_CPU1	0x504
 
-#define E4210_DIV0_RATIO0_MASK	0x7
-#define E4210_DIV1_HPM_MASK	(0x7 << 4)
-#define E4210_DIV1_COPY_MASK	(0x7 << 0)
-#define E4210_MUX_HPM_MASK	(1 << 20)
+#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
+#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
+#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
+#define E4210_MUX_HPM_MASK	BIT(20)
 #define E4210_DIV0_ATB_SHIFT	16
 #define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
 
+/* Divider stabilization time, msec */
+#define MAX_STAB_TIME		10
 #define MAX_DIV			8
-#define DIV_MASK		7
-#define DIV_MASK_ALL		0xffffffff
-#define MUX_MASK		7
+#define DIV_MASK		GENMASK(2, 0)
+#define DIV_MASK_ALL		GENMASK(31, 0)
+#define MUX_MASK		GENMASK(2, 0)
 
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
@@ -68,7 +70,7 @@
  */
 static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
 {
-	unsigned long timeout = jiffies + msecs_to_jiffies(10);
+	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);
 
 	do {
 		if (!(readl(div_reg) & mask))
@@ -86,9 +88,9 @@ static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
  * value was changed.
  */
 static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
-					unsigned long mux_value)
+				  unsigned long mux_value)
 {
-	unsigned long timeout = jiffies + msecs_to_jiffies(10);
+	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);
 
 	do {
 		if (((readl(mux_reg) >> mux_pos) & MUX_MASK) == mux_value)
@@ -101,18 +103,18 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
 }
 
-/* common round rate callback useable for all types of CPU clocks */
-static long exynos_cpuclk_round_rate(struct clk_hw *hw,
-			unsigned long drate, unsigned long *prate)
+/* common round rate callback usable for all types of CPU clocks */
+static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate,
+				     unsigned long *prate)
 {
 	struct clk_hw *parent = clk_hw_get_parent(hw);
 	*prate = clk_hw_round_rate(parent, drate);
 	return *prate;
 }
 
-/* common recalc rate callback useable for all types of CPU clocks */
+/* common recalc rate callback usable for all types of CPU clocks */
 static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw,
-			unsigned long parent_rate)
+					       unsigned long parent_rate)
 {
 	/*
 	 * The CPU clock output (armclk) rate is the same as its parent
@@ -135,7 +137,7 @@ static const struct clk_ops exynos_cpuclk_clk_ops = {
  * dividers to be programmed.
  */
 static void exynos_set_safe_div(void __iomem *base, unsigned long div,
-					unsigned long mask)
+				unsigned long mask)
 {
 	unsigned long div0;
 
@@ -151,7 +153,6 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
-	unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
 
@@ -187,6 +188,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	 */
 	if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) {
 		unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate);
+		unsigned long alt_div, alt_div_mask = DIV_MASK;
 
 		alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
 		WARN_ON(alt_div >= MAX_DIV);
@@ -215,7 +217,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
 		writel(div1, base + E4210_DIV_CPU1);
 		wait_until_divider_stable(base + E4210_DIV_STAT_CPU1,
-				DIV_MASK_ALL);
+					  DIV_MASK_ALL);
 	}
 
 	spin_unlock_irqrestore(cpuclk->lock, flags);
@@ -263,7 +265,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
  * dividers to be programmed.
  */
 static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
-					unsigned long mask)
+				    unsigned long mask)
 {
 	unsigned long div0;
 
@@ -279,7 +281,6 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
-	unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
 
@@ -309,6 +310,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	 */
 	if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) {
 		unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate);
+		unsigned long alt_div, alt_div_mask = DIV_MASK;
 
 		alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
 		WARN_ON(alt_div >= MAX_DIV);
@@ -358,7 +360,7 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
  * notifications of the parent clock of cpuclk.
  */
 static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
-				unsigned long event, void *data)
+				     unsigned long event, void *data)
 {
 	struct clk_notifier_data *ndata = data;
 	struct exynos_cpuclk *cpuclk;
@@ -381,7 +383,7 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
  * notifications of the parent clock of cpuclk.
  */
 static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
-				unsigned long event, void *data)
+					 unsigned long event, void *data)
 {
 	struct clk_notifier_data *ndata = data;
 	struct exynos_cpuclk *cpuclk;
@@ -438,11 +440,10 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	else
 		cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
 
-
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
 		pr_err("%s: failed to register clock notifier for %s\n",
-				__func__, name);
+		       __func__, name);
 		goto free_cpuclk;
 	}
 
@@ -454,7 +455,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	ret = clk_hw_register(NULL, &cpuclk->hw);
 	if (ret) {
-		pr_err("%s: could not register cpuclk %s\n", __func__,	name);
+		pr_err("%s: could not register cpuclk %s\n", __func__, name);
 		goto free_cpuclk_data;
 	}
 
@@ -482,8 +483,8 @@ void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
 		for (num_cfgs = 0; list->cfg[num_cfgs].prate != 0; )
 			num_cfgs++;
 
-		exynos_register_cpu_clock(ctx, list->id, list->name, hws[list->parent_id],
-				hws[list->alt_parent_id], list->offset, list->cfg, num_cfgs,
-				list->flags);
+		exynos_register_cpu_clock(ctx, list->id, list->name,
+			hws[list->parent_id], hws[list->alt_parent_id],
+			list->offset, list->cfg, num_cfgs, list->flags);
 	}
 }
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:32 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:32 -0600
Subject: [PATCH 03/16] clk: samsung: Pull struct exynos_cpuclk into clk-cpu.c
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-4-semen.protsenko@linaro.org>

Reduce the scope of struct exynos_cpuclk, as it's only used in clk-cpu.c
internally. All drivers using clk-pll.h already include clk.h as well,
so this change doesn't break anything.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c | 29 +++++++++++++++++++++++++
 drivers/clk/samsung/clk-cpu.h | 41 +++++------------------------------
 2 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index e02730776aaa..6412fd2580e0 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -34,6 +34,8 @@
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+
+#include "clk.h"
 #include "clk-cpu.h"
 
 #define E4210_SRC_CPU		0x0
@@ -64,6 +66,33 @@
 #define DIV_MASK_ALL		GENMASK(31, 0)
 #define MUX_MASK		GENMASK(2, 0)
 
+/**
+ * struct exynos_cpuclk - information about clock supplied to a CPU core
+ * @hw:		handle between CCF and CPU clock
+ * @alt_parent:	alternate parent clock to use when switching the speed
+ *		of the primary parent clock
+ * @ctrl_base:	base address of the clock controller
+ * @lock:	cpu clock domain register access lock
+ * @cfg:	cpu clock rate configuration data
+ * @num_cfgs:	number of array elements in @cfg array
+ * @clk_nb:	clock notifier registered for changes in clock speed of the
+ *		primary parent clock
+ * @flags:	configuration flags for the CPU clock
+ *
+ * This structure holds information required for programming the CPU clock for
+ * various clock speeds.
+ */
+struct exynos_cpuclk {
+	struct clk_hw				hw;
+	const struct clk_hw			*alt_parent;
+	void __iomem				*ctrl_base;
+	spinlock_t				*lock;
+	const struct exynos_cpuclk_cfg_data	*cfg;
+	const unsigned long			num_cfgs;
+	struct notifier_block			clk_nb;
+	unsigned long				flags;
+};
+
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
  * value has changed.
diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h
index 0164bd9ad021..ee57f3638fed 100644
--- a/drivers/clk/samsung/clk-cpu.h
+++ b/drivers/clk/samsung/clk-cpu.h
@@ -8,7 +8,12 @@
 #ifndef __SAMSUNG_CLK_CPU_H
 #define __SAMSUNG_CLK_CPU_H
 
-#include "clk.h"
+/* The CPU clock registers have DIV1 configuration register */
+#define CLK_CPU_HAS_DIV1		BIT(0)
+/* When ALT parent is active, debug clocks need safe divider values */
+#define CLK_CPU_NEEDS_DEBUG_ALT_DIV	BIT(1)
+/* The CPU clock registers have Exynos5433-compatible layout */
+#define CLK_CPU_HAS_E5433_REGS_LAYOUT	BIT(2)
 
 /**
  * struct exynos_cpuclk_cfg_data - config data to setup cpu clocks
@@ -28,38 +33,4 @@ struct exynos_cpuclk_cfg_data {
 	unsigned long	div1;
 };
 
-/**
- * struct exynos_cpuclk - information about clock supplied to a CPU core
- * @hw:		handle between CCF and CPU clock
- * @alt_parent:	alternate parent clock to use when switching the speed
- *		of the primary parent clock
- * @ctrl_base:	base address of the clock controller
- * @lock:	cpu clock domain register access lock
- * @cfg:	cpu clock rate configuration data
- * @num_cfgs:	number of array elements in @cfg array
- * @clk_nb:	clock notifier registered for changes in clock speed of the
- *		primary parent clock
- * @flags:	configuration flags for the CPU clock
- *
- * This structure holds information required for programming the CPU clock for
- * various clock speeds.
- */
-struct exynos_cpuclk {
-	struct clk_hw				hw;
-	const struct clk_hw			*alt_parent;
-	void __iomem				*ctrl_base;
-	spinlock_t				*lock;
-	const struct exynos_cpuclk_cfg_data	*cfg;
-	const unsigned long			num_cfgs;
-	struct notifier_block			clk_nb;
-	unsigned long				flags;
-
-/* The CPU clock registers have DIV1 configuration register */
-#define CLK_CPU_HAS_DIV1		(1 << 0)
-/* When ALT parent is active, debug clocks need safe divider values */
-#define CLK_CPU_NEEDS_DEBUG_ALT_DIV	(1 << 1)
-/* The CPU clock registers have Exynos5433-compatible layout */
-#define CLK_CPU_HAS_E5433_REGS_LAYOUT	(1 << 2)
-};
-
 #endif /* __SAMSUNG_CLK_CPU_H */
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:33 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:33 -0600
Subject: [PATCH 04/16] clk: samsung: Reduce params count in exynos_register_cpu_clock()
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-5-semen.protsenko@linaro.org>

Pass CPU clock data structure to exynos_register_cpu_clock() instead of
passing its fields separately there. That simplifies the signature of
exynos_register_cpu_clock() and makes it easier to add more fields to
struct samsung_cpu_clock later. This style follows the example of
samsung_clk_register_pll().

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c | 46 +++++++++++++++++------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 6412fd2580e0..7b6fd331a7ec 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -432,16 +432,19 @@ static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
 
 /* helper function to register a CPU clock */
 static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
-		unsigned int lookup_id, const char *name,
-		const struct clk_hw *parent, const struct clk_hw *alt_parent,
-		unsigned long offset, const struct exynos_cpuclk_cfg_data *cfg,
-		unsigned long num_cfgs, unsigned long flags)
+				const struct samsung_cpu_clock *clk_data)
 {
+	const struct clk_hw *parent, *alt_parent;
+	struct clk_hw **hws;
 	struct exynos_cpuclk *cpuclk;
 	struct clk_init_data init;
 	const char *parent_name;
+	unsigned int num_cfgs;
 	int ret = 0;
 
+	hws = ctx->clk_data.hws;
+	parent = hws[clk_data->parent_id];
+	alt_parent = hws[clk_data->alt_parent_id];
 	if (IS_ERR(parent) || IS_ERR(alt_parent)) {
 		pr_err("%s: invalid parent clock(s)\n", __func__);
 		return -EINVAL;
@@ -453,7 +456,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	parent_name = clk_hw_get_name(parent);
 
-	init.name = name;
+	init.name = clk_data->name;
 	init.flags = CLK_SET_RATE_PARENT;
 	init.parent_names = &parent_name;
 	init.num_parents = 1;
@@ -461,10 +464,10 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	cpuclk->alt_parent = alt_parent;
 	cpuclk->hw.init = &init;
-	cpuclk->ctrl_base = ctx->reg_base + offset;
+	cpuclk->ctrl_base = ctx->reg_base + clk_data->offset;
 	cpuclk->lock = &ctx->lock;
-	cpuclk->flags = flags;
-	if (flags & CLK_CPU_HAS_E5433_REGS_LAYOUT)
+	cpuclk->flags = clk_data->flags;
+	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT)
 		cpuclk->clk_nb.notifier_call = exynos5433_cpuclk_notifier_cb;
 	else
 		cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
@@ -472,11 +475,16 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
 		pr_err("%s: failed to register clock notifier for %s\n",
-		       __func__, name);
+		       __func__, clk_data->name);
 		goto free_cpuclk;
 	}
 
-	cpuclk->cfg = kmemdup(cfg, sizeof(*cfg) * num_cfgs, GFP_KERNEL);
+	/* Find count of configuration rates in cfg */
+	for (num_cfgs = 0; clk_data->cfg[num_cfgs].prate != 0; )
+		num_cfgs++;
+
+	cpuclk->cfg = kmemdup(clk_data->cfg, sizeof(*clk_data->cfg) * num_cfgs,
+			      GFP_KERNEL);
 	if (!cpuclk->cfg) {
 		ret = -ENOMEM;
 		goto unregister_clk_nb;
@@ -484,11 +492,12 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	ret = clk_hw_register(NULL, &cpuclk->hw);
 	if (ret) {
-		pr_err("%s: could not register cpuclk %s\n", __func__, name);
+		pr_err("%s: could not register cpuclk %s\n", __func__,
+		       clk_data->name);
 		goto free_cpuclk_data;
 	}
 
-	samsung_clk_add_lookup(ctx, &cpuclk->hw, lookup_id);
+	samsung_clk_add_lookup(ctx, &cpuclk->hw, clk_data->id);
 	return 0;
 
 free_cpuclk_data:
@@ -504,16 +513,7 @@ void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
 		const struct samsung_cpu_clock *list, unsigned int nr_clk)
 {
 	unsigned int idx;
-	unsigned int num_cfgs;
-	struct clk_hw **hws = ctx->clk_data.hws;
 
-	for (idx = 0; idx < nr_clk; idx++, list++) {
-		/* find count of configuration rates in cfg */
-		for (num_cfgs = 0; list->cfg[num_cfgs].prate != 0; )
-			num_cfgs++;
-
-		exynos_register_cpu_clock(ctx, list->id, list->name,
-			hws[list->parent_id], hws[list->alt_parent_id],
-			list->offset, list->cfg, num_cfgs, list->flags);
-	}
+	for (idx = 0; idx < nr_clk; idx++)
+		exynos_register_cpu_clock(ctx, &list[idx]);
 }
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:34 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:34 -0600
Subject: [PATCH 05/16] clk: samsung: Use single CPU clock notifier callback for all chips
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-6-semen.protsenko@linaro.org>

Reduce the code duplication by making all chips use a single version of
exynos_cpuclk_notifier_cb() function. That will prevent the code bloat
when adding new chips support too.

Also don't pass base address to pre/post rate change functions, as it
can be easily derived from already passed cpuclk param.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c | 63 ++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 35 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 7b6fd331a7ec..427018e8dd8c 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -66,6 +66,11 @@
 #define DIV_MASK_ALL		GENMASK(31, 0)
 #define MUX_MASK		GENMASK(2, 0)
 
+struct exynos_cpuclk;
+
+typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
+				       struct exynos_cpuclk *cpuclk);
+
 /**
  * struct exynos_cpuclk - information about clock supplied to a CPU core
  * @hw:		handle between CCF and CPU clock
@@ -78,6 +83,8 @@
  * @clk_nb:	clock notifier registered for changes in clock speed of the
  *		primary parent clock
  * @flags:	configuration flags for the CPU clock
+ * @pre_rate_cb: callback to run before CPU clock rate change
+ * @post_rate_cb: callback to run after CPU clock rate change
  *
  * This structure holds information required for programming the CPU clock for
  * various clock speeds.
@@ -91,6 +98,9 @@ struct exynos_cpuclk {
 	const unsigned long			num_cfgs;
 	struct notifier_block			clk_nb;
 	unsigned long				flags;
+
+	exynos_rate_change_fn_t			pre_rate_cb;
+	exynos_rate_change_fn_t			post_rate_cb;
 };
 
 /*
@@ -178,9 +188,10 @@ static void exynos_set_safe_div(void __iomem *base, unsigned long div,
 
 /* handler for pre-rate change notification from parent clock */
 static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					 struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
@@ -255,9 +266,10 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 
 /* handler for post-rate change notification from parent clock */
 static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					  struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
 	unsigned long flags;
@@ -306,9 +318,10 @@ static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
 
 /* handler for pre-rate change notification from parent clock */
 static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					     struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
@@ -366,8 +379,9 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 
 /* handler for post-rate change notification from parent clock */
 static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					      struct exynos_cpuclk *cpuclk)
 {
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
 	unsigned long flags;
@@ -393,39 +407,14 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
 {
 	struct clk_notifier_data *ndata = data;
 	struct exynos_cpuclk *cpuclk;
-	void __iomem *base;
 	int err = 0;
 
 	cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb);
-	base = cpuclk->ctrl_base;
 
 	if (event == PRE_RATE_CHANGE)
-		err = exynos_cpuclk_pre_rate_change(ndata, cpuclk, base);
+		err = cpuclk->pre_rate_cb(ndata, cpuclk);
 	else if (event == POST_RATE_CHANGE)
-		err = exynos_cpuclk_post_rate_change(ndata, cpuclk, base);
-
-	return notifier_from_errno(err);
-}
-
-/*
- * This notifier function is called for the pre-rate and post-rate change
- * notifications of the parent clock of cpuclk.
- */
-static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
-					 unsigned long event, void *data)
-{
-	struct clk_notifier_data *ndata = data;
-	struct exynos_cpuclk *cpuclk;
-	void __iomem *base;
-	int err = 0;
-
-	cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb);
-	base = cpuclk->ctrl_base;
-
-	if (event == PRE_RATE_CHANGE)
-		err = exynos5433_cpuclk_pre_rate_change(ndata, cpuclk, base);
-	else if (event == POST_RATE_CHANGE)
-		err = exynos5433_cpuclk_post_rate_change(ndata, cpuclk, base);
+		err = cpuclk->post_rate_cb(ndata, cpuclk);
 
 	return notifier_from_errno(err);
 }
@@ -467,10 +456,14 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	cpuclk->ctrl_base = ctx->reg_base + clk_data->offset;
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
-	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT)
-		cpuclk->clk_nb.notifier_call = exynos5433_cpuclk_notifier_cb;
-	else
-		cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
+	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
+	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT) {
+		cpuclk->pre_rate_cb = exynos5433_cpuclk_pre_rate_change;
+		cpuclk->post_rate_cb = exynos5433_cpuclk_post_rate_change;
+	} else {
+		cpuclk->pre_rate_cb = exynos_cpuclk_pre_rate_change;
+		cpuclk->post_rate_cb = exynos_cpuclk_post_rate_change;
+	}
 
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:36 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:36 -0600
Subject: [PATCH 07/16] clk: samsung: Pass actual clock controller base address to CPU_CLK()
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-8-semen.protsenko@linaro.org>

The documentation for struct exynos_cpuclk says .ctrl_base field should
contain the controller base address. But in reality all Exynos clock
drivers are passing CPU_SRC register address via CPU_CLK() macro, which
in turn gets assigned to mentioned .ctrl_base field. Because CPU_SRC
address usually already has 0x200 offset from controller's base, all
other register offsets in clk-cpu.c (like DIVs and MUXes) are specified
as offsets from CPU_SRC offset, and not from controller's base. That
makes things confusing and not consistent with register offsets provided
in Exynis clock drivers, also breaking the contract for .ctrl_base field
as described in struct exynos_cpuclk doc. Rework all register offsets in
clk-cpu.c to be actual offsets from controller's base, and fix offsets
provided to CPU_CLK() macro in all Exynos clock drivers.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c        | 24 ++++++++++++------------
 drivers/clk/samsung/clk-exynos3250.c |  2 +-
 drivers/clk/samsung/clk-exynos4.c    |  9 ++++++---
 drivers/clk/samsung/clk-exynos5250.c |  4 ++--
 drivers/clk/samsung/clk-exynos5420.c | 16 ++++++++--------
 drivers/clk/samsung/clk-exynos5433.c | 10 ++++------
 6 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index d550a4bb632f..a59949990919 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -125,12 +125,12 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 
 /* ---- Exynos 3/4/5 -------------------------------------------------------- */
 
-#define E4210_SRC_CPU		0x0
-#define E4210_STAT_CPU		0x200
-#define E4210_DIV_CPU0		0x300
-#define E4210_DIV_CPU1		0x304
-#define E4210_DIV_STAT_CPU0	0x400
-#define E4210_DIV_STAT_CPU1	0x404
+#define E4210_SRC_CPU		0x200
+#define E4210_STAT_CPU		0x400
+#define E4210_DIV_CPU0		0x500
+#define E4210_DIV_CPU1		0x504
+#define E4210_DIV_STAT_CPU0	0x600
+#define E4210_DIV_STAT_CPU1	0x604
 
 #define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
 #define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
@@ -271,12 +271,12 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 
 /* ---- Exynos5433 ---------------------------------------------------------- */
 
-#define E5433_MUX_SEL2		0x008
-#define E5433_MUX_STAT2		0x208
-#define E5433_DIV_CPU0		0x400
-#define E5433_DIV_CPU1		0x404
-#define E5433_DIV_STAT_CPU0	0x500
-#define E5433_DIV_STAT_CPU1	0x504
+#define E5433_MUX_SEL2		0x208
+#define E5433_MUX_STAT2		0x408
+#define E5433_DIV_CPU0		0x600
+#define E5433_DIV_CPU1		0x604
+#define E5433_DIV_STAT_CPU0	0x700
+#define E5433_DIV_STAT_CPU1	0x704
 
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index a02461667664..bf149fae04c3 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -775,7 +775,7 @@ static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos3250_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-			CLK_CPU_HAS_DIV1, 0x14200, e3250_armclk_d),
+		CLK_CPU_HAS_DIV1, 0x14000, e3250_armclk_d),
 };
 
 static void __init exynos3_core_down_clock(void __iomem *reg_base)
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 4ec41221e68f..d5b1e9f49d8b 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1252,17 +1252,20 @@ static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos4210_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_SCLK_MPLL,
-			CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4210_armclk_d),
+		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
+		e4210_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4212_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4212_armclk_d),
+		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
+		e4212_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4412_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-			CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4412_armclk_d),
+		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
+		e4412_armclk_d),
 };
 
 /* register exynos4 clocks */
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 8ebe6155d8b7..58df80de52ef 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -776,8 +776,8 @@ static const struct exynos_cpuclk_cfg_data exynos5250_armclk_d[] __initconst = {
 };
 
 static const struct samsung_cpu_clock exynos5250_cpu_clks[] __initconst = {
-	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL, CLK_CPU_HAS_DIV1, 0x200,
-			exynos5250_armclk_d),
+	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL,
+		CLK_CPU_HAS_DIV1, 0x0, exynos5250_armclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 199843f12ae5..bd7b304d2c00 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -1555,17 +1555,17 @@ static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = {
 };
 
 static const struct samsung_cpu_clock exynos5420_cpu_clks[] __initconst = {
-	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200,
-			exynos5420_eglclk_d),
-	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200,
-			exynos5420_kfcclk_d),
+	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
+		0x0, exynos5420_eglclk_d),
+	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
+		0x28000, exynos5420_kfcclk_d),
 };
 
 static const struct samsung_cpu_clock exynos5800_cpu_clks[] __initconst = {
-	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200,
-			exynos5800_eglclk_d),
-	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200,
-			exynos5420_kfcclk_d),
+	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
+		0x0, exynos5800_eglclk_d),
+	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
+		0x28000, exynos5420_kfcclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index 6bfc5d0cd924..d3779eefb438 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -3700,9 +3700,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_apolloclk_d[] __initconst
 
 static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL,
-			CLK_MOUT_BUS_PLL_APOLLO_USER,
-			CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200,
-			exynos5433_apolloclk_d),
+		CLK_MOUT_BUS_PLL_APOLLO_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
+		0x0, exynos5433_apolloclk_d),
 };
 
 static const struct samsung_cmu_info apollo_cmu_info __initconst = {
@@ -3945,9 +3944,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_atlasclk_d[] __initconst =
 
 static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL,
-			CLK_MOUT_BUS_PLL_ATLAS_USER,
-			CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200,
-			exynos5433_atlasclk_d),
+		CLK_MOUT_BUS_PLL_ATLAS_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
+		0x0, exynos5433_atlasclk_d),
 };
 
 static const struct samsung_cmu_info atlas_cmu_info __initconst = {
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:35 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:35 -0600
Subject: [PATCH 06/16] clk: samsung: Group CPU clock functions by chip
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-7-semen.protsenko@linaro.org>

clk-cpu.c is going to get messy as new chips support is added.
Restructure the code by pulling related functions and definitions
together, grouping those by their relation to a particular chip or other
categories, to simplify the code navigation.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c | 114 ++++++++++++++++++----------------
 1 file changed, 61 insertions(+), 53 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 427018e8dd8c..d550a4bb632f 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -38,34 +38,6 @@
 #include "clk.h"
 #include "clk-cpu.h"
 
-#define E4210_SRC_CPU		0x0
-#define E4210_STAT_CPU		0x200
-#define E4210_DIV_CPU0		0x300
-#define E4210_DIV_CPU1		0x304
-#define E4210_DIV_STAT_CPU0	0x400
-#define E4210_DIV_STAT_CPU1	0x404
-
-#define E5433_MUX_SEL2		0x008
-#define E5433_MUX_STAT2		0x208
-#define E5433_DIV_CPU0		0x400
-#define E5433_DIV_CPU1		0x404
-#define E5433_DIV_STAT_CPU0	0x500
-#define E5433_DIV_STAT_CPU1	0x504
-
-#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
-#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
-#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
-#define E4210_MUX_HPM_MASK	BIT(20)
-#define E4210_DIV0_ATB_SHIFT	16
-#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
-
-/* Divider stabilization time, msec */
-#define MAX_STAB_TIME		10
-#define MAX_DIV			8
-#define DIV_MASK		GENMASK(2, 0)
-#define DIV_MASK_ALL		GENMASK(31, 0)
-#define MUX_MASK		GENMASK(2, 0)
-
 struct exynos_cpuclk;
 
 typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
@@ -103,6 +75,15 @@ struct exynos_cpuclk {
 	exynos_rate_change_fn_t			post_rate_cb;
 };
 
+/* ---- Common code --------------------------------------------------------- */
+
+/* Divider stabilization time, msec */
+#define MAX_STAB_TIME		10
+#define MAX_DIV			8
+#define DIV_MASK		GENMASK(2, 0)
+#define DIV_MASK_ALL		GENMASK(31, 0)
+#define MUX_MASK		GENMASK(2, 0)
+
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
  * value has changed.
@@ -142,33 +123,21 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
 }
 
-/* common round rate callback usable for all types of CPU clocks */
-static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate,
-				     unsigned long *prate)
-{
-	struct clk_hw *parent = clk_hw_get_parent(hw);
-	*prate = clk_hw_round_rate(parent, drate);
-	return *prate;
-}
+/* ---- Exynos 3/4/5 -------------------------------------------------------- */
 
-/* common recalc rate callback usable for all types of CPU clocks */
-static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw,
-					       unsigned long parent_rate)
-{
-	/*
-	 * The CPU clock output (armclk) rate is the same as its parent
-	 * rate. Although there exist certain dividers inside the CPU
-	 * clock block that could be used to divide the parent clock,
-	 * the driver does not make use of them currently, except during
-	 * frequency transitions.
-	 */
-	return parent_rate;
-}
+#define E4210_SRC_CPU		0x0
+#define E4210_STAT_CPU		0x200
+#define E4210_DIV_CPU0		0x300
+#define E4210_DIV_CPU1		0x304
+#define E4210_DIV_STAT_CPU0	0x400
+#define E4210_DIV_STAT_CPU1	0x404
 
-static const struct clk_ops exynos_cpuclk_clk_ops = {
-	.recalc_rate = exynos_cpuclk_recalc_rate,
-	.round_rate = exynos_cpuclk_round_rate,
-};
+#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
+#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
+#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
+#define E4210_MUX_HPM_MASK	BIT(20)
+#define E4210_DIV0_ATB_SHIFT	16
+#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
 
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
@@ -300,6 +269,15 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	return 0;
 }
 
+/* ---- Exynos5433 ---------------------------------------------------------- */
+
+#define E5433_MUX_SEL2		0x008
+#define E5433_MUX_STAT2		0x208
+#define E5433_DIV_CPU0		0x400
+#define E5433_DIV_CPU1		0x404
+#define E5433_DIV_STAT_CPU0	0x500
+#define E5433_DIV_STAT_CPU1	0x504
+
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
  * div and mask contain the divider value and the register bit mask of the
@@ -398,6 +376,36 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	return 0;
 }
 
+/* -------------------------------------------------------------------------- */
+
+/* Common round rate callback usable for all types of CPU clocks */
+static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate,
+				     unsigned long *prate)
+{
+	struct clk_hw *parent = clk_hw_get_parent(hw);
+	*prate = clk_hw_round_rate(parent, drate);
+	return *prate;
+}
+
+/* Common recalc rate callback usable for all types of CPU clocks */
+static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	/*
+	 * The CPU clock output (armclk) rate is the same as its parent
+	 * rate. Although there exist certain dividers inside the CPU
+	 * clock block that could be used to divide the parent clock,
+	 * the driver does not make use of them currently, except during
+	 * frequency transitions.
+	 */
+	return parent_rate;
+}
+
+static const struct clk_ops exynos_cpuclk_clk_ops = {
+	.recalc_rate = exynos_cpuclk_recalc_rate,
+	.round_rate = exynos_cpuclk_round_rate,
+};
+
 /*
  * This notifier function is called for the pre-rate and post-rate change
  * notifications of the parent clock of cpuclk.
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:42 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:42 -0600
Subject: [PATCH 13/16] clk: samsung: Add CPU clock support for Exynos850
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-14-semen.protsenko@linaro.org>

Implement CPU clock control for Exynos850 SoC. It follows the same
procedure which is already implemented for other SoCs in clk-cpu.c:

1. Set the correct rate for the alternate parent (if needed) before
   switching to use it as the CPU clock
2. Switch to the alternate parent, so the CPU continues to get clocked
   while the PLL is being re-configured
3. Adjust the dividers for the CPU related buses (ACLK, ATCLK, etc)
4. Re-configure the PLL for the new CPU clock rate. It's done
   automatically, as the CPU clock rate change propagates to the PLL
   clock, because the CPU clock has CLK_SET_RATE_PARENT flag set in
   exynos_register_cpu_clock()
5. Once the PLL is locked, set it back as the CPU clock source
6. Set alternate parent clock rate back to max speed

As in already existing clk-cpu.c code, the divider and mux clocks are
configured in a low-level fashion (using direct register access instead
of CCF API), to avoid affecting how DIV and MUX clock flags are declared
in the actual clock driver (clk-exynos850.c).

No functional change. This patch adds support for Exynos850 CPU clock,
but doesn't enable it per se.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c | 183 ++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-cpu.h |   4 +
 2 files changed, 187 insertions(+)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 5ea618da0bc1..cdf592da42e9 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -29,6 +29,7 @@
  * down in order to keep the output clock rate within the previous OPP limits.
  */
 
+#include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/slab.h>
@@ -396,6 +397,178 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	return 0;
 }
 
+/* ---- Exynos850 ----------------------------------------------------------- */
+
+#define E850_DIV_RATIO_MASK	GENMASK(3, 0)
+#define E850_BUSY_MASK		BIT(16)
+
+/* Max time for divider or mux to stabilize, usec */
+#define E850_DIV_MUX_STAB_TIME	100
+/* OSCCLK clock rate, Hz */
+#define E850_OSCCLK		(26 * MHZ)
+
+/**
+ * struct exynos850_cpuclk_regs - Register offsets for Exynos850 CPU clocks
+ * @mux:		offset of MUX register for choosing CPU clock source
+ * @divs:		offsets of DIV registers (ACLK, ATCLK, PCLKDBG and
+ *			PERIPHCLK)
+ */
+struct exynos850_cpuclk_regs {
+	u32 mux;
+	u32 divs[4];
+};
+
+static const struct exynos850_cpuclk_regs e850cl0_cpuclk_regs = {
+	.mux	= 0x100c,
+	.divs	= { 0x1800, 0x1808, 0x180c, 0x1810 },
+};
+
+static const struct exynos850_cpuclk_regs e850cl1_cpuclk_regs = {
+	.mux	= 0x1000,
+	.divs	= { 0x1800, 0x1808, 0x180c, 0x1810 },
+};
+
+/*
+ * Set alternate parent rate to "rate" value or less.
+ *
+ * rate: Desired alt_parent rate, or 0 for max alt_parent rate
+ *
+ * Exynos850 doesn't have CPU clock divider in CMU_CPUCLx block (CMUREF divider
+ * doesn't affect CPU speed). So CPUCLx_SWITCH divider from CMU_TOP is used
+ * instead to adjust alternate parent speed.
+ *
+ * It's possible to use clk_set_max_rate() instead of this function, but it
+ * would set overly pessimistic rate values to alternate parent.
+ */
+static int exynos850_alt_parent_set_max_rate(const struct clk_hw *alt_parent,
+					     unsigned long rate)
+{
+	struct clk_hw *clk_div, *clk_divp;
+	unsigned long divp_rate, div_rate, div;
+	int ret;
+
+	/* Divider from CMU_TOP */
+	clk_div = clk_hw_get_parent(alt_parent);
+	if (!clk_div)
+		return -ENOENT;
+	/* Divider's parent from CMU_TOP */
+	clk_divp = clk_hw_get_parent(clk_div);
+	if (!clk_divp)
+		return -ENOENT;
+	/* Divider input rate */
+	divp_rate = clk_hw_get_rate(clk_divp);
+	if (!divp_rate)
+		return -EINVAL;
+
+	/* Calculate new alt_parent rate for integer divider value */
+	if (rate == 0)
+		div = 1;
+	else
+		div = DIV_ROUND_UP(divp_rate, rate);
+	div_rate = DIV_ROUND_UP(divp_rate, div);
+	WARN_ON(div >= MAX_DIV);
+
+	/* alt_parent will propagate this change up to the divider */
+	ret = clk_set_rate(alt_parent->clk, div_rate);
+	if (ret)
+		return ret;
+	udelay(E850_DIV_MUX_STAB_TIME);
+
+	return 0;
+}
+
+/* Handler for pre-rate change notification from parent clock */
+static int exynos850_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
+					    struct exynos_cpuclk *cpuclk)
+{
+	const unsigned int shifts[4] = { 16, 12, 8, 4 }; /* E850_CPU_DIV0() */
+	const struct exynos850_cpuclk_regs * const regs = cpuclk->chip->regs;
+	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct clk_hw *alt_parent = cpuclk->alt_parent;
+	void __iomem *base = cpuclk->ctrl_base;
+	unsigned long alt_prate = clk_hw_get_rate(alt_parent);
+	unsigned long flags;
+	u32 mux_reg;
+	size_t i;
+	int ret;
+
+	/* No actions are needed when switching to or from OSCCLK parent */
+	if (ndata->new_rate == E850_OSCCLK || ndata->old_rate == E850_OSCCLK)
+		return 0;
+
+	/* Find out the divider values to use for clock data */
+	while ((cfg_data->prate * 1000) != ndata->new_rate) {
+		if (cfg_data->prate == 0)
+			return -EINVAL;
+		cfg_data++;
+	}
+
+	/*
+	 * If the old parent clock speed is less than the clock speed of
+	 * the alternate parent, then it should be ensured that at no point
+	 * the armclk speed is more than the old_prate until the dividers are
+	 * set.  Also workaround the issue of the dividers being set to lower
+	 * values before the parent clock speed is set to new lower speed
+	 * (this can result in too high speed of armclk output clocks).
+	 */
+	if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) {
+		unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate);
+
+		ret = exynos850_alt_parent_set_max_rate(alt_parent, tmp_rate);
+		if (ret)
+			return ret;
+	}
+
+	spin_lock_irqsave(cpuclk->lock, flags);
+
+	/* Select the alternate parent */
+	mux_reg = readl(base + regs->mux);
+	writel(mux_reg | 1, base + regs->mux);
+	wait_until_mux_stable(base + regs->mux, 16, 1, 0);
+
+	/* Alternate parent is active now. Set the dividers */
+	for (i = 0; i < ARRAY_SIZE(shifts); ++i) {
+		unsigned long div = (cfg_data->div0 >> shifts[i]) & 0xf;
+		u32 val;
+
+		val = readl(base + regs->divs[i]);
+		val = (val & ~E850_DIV_RATIO_MASK) | div;
+		writel(val, base + regs->divs[i]);
+		wait_until_divider_stable(base + regs->divs[i], E850_BUSY_MASK);
+	}
+
+	spin_unlock_irqrestore(cpuclk->lock, flags);
+
+	return 0;
+}
+
+/* Handler for post-rate change notification from parent clock */
+static int exynos850_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
+					     struct exynos_cpuclk *cpuclk)
+{
+	const struct exynos850_cpuclk_regs * const regs = cpuclk->chip->regs;
+	const struct clk_hw *alt_parent = cpuclk->alt_parent;
+	void __iomem *base = cpuclk->ctrl_base;
+	unsigned long flags;
+	u32 mux_reg;
+
+	/* No actions are needed when switching to or from OSCCLK parent */
+	if (ndata->new_rate == E850_OSCCLK || ndata->old_rate == E850_OSCCLK)
+		return 0;
+
+	spin_lock_irqsave(cpuclk->lock, flags);
+
+	/* Select main parent (PLL) for mux */
+	mux_reg = readl(base + regs->mux);
+	writel(mux_reg & ~1, base + regs->mux);
+	wait_until_mux_stable(base + regs->mux, 16, 1, 0);
+
+	spin_unlock_irqrestore(cpuclk->lock, flags);
+
+	/* Set alt_parent rate back to max */
+	return exynos850_alt_parent_set_max_rate(alt_parent, 0);
+}
+
 /* -------------------------------------------------------------------------- */
 
 /* Common round rate callback usable for all types of CPU clocks */
@@ -458,6 +631,16 @@ static const struct exynos_cpuclk_chip exynos_clkcpu_chips[] = {
 		.pre_rate_cb	= exynos5433_cpuclk_pre_rate_change,
 		.post_rate_cb	= exynos5433_cpuclk_post_rate_change,
 	},
+	[CPUCLK_LAYOUT_E850_CL0] = {
+		.regs		= &e850cl0_cpuclk_regs,
+		.pre_rate_cb	= exynos850_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos850_cpuclk_post_rate_change,
+	},
+	[CPUCLK_LAYOUT_E850_CL1] = {
+		.regs		= &e850cl1_cpuclk_regs,
+		.pre_rate_cb	= exynos850_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos850_cpuclk_post_rate_change,
+	},
 };
 
 /* helper function to register a CPU clock */
diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h
index 4382ab005ad3..892843611b0a 100644
--- a/drivers/clk/samsung/clk-cpu.h
+++ b/drivers/clk/samsung/clk-cpu.h
@@ -17,10 +17,14 @@
  * enum exynos_cpuclk_layout - CPU clock registers layout compatibility
  * @CPUCLK_LAYOUT_E4210: Exynos4210 compatible layout
  * @CPUCLK_LAYOUT_E5433: Exynos5433 compatible layout
+ * @CPUCLK_LAYOUT_E850_CL0: Exynos850 cluster 0 compatible layout
+ * @CPUCLK_LAYOUT_E850_CL1: Exynos850 cluster 1 compatible layout
  */
 enum exynos_cpuclk_layout {
 	CPUCLK_LAYOUT_E4210,
 	CPUCLK_LAYOUT_E5433,
+	CPUCLK_LAYOUT_E850_CL0,
+	CPUCLK_LAYOUT_E850_CL1,
 };
 
 /**
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:37 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:37 -0600
Subject: [PATCH 08/16] clk: samsung: Use clk.h as a single header for Samsung CCF
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-9-semen.protsenko@linaro.org>

Make both CPU and PLL clock headers to be included indirectly via clk.h.
All Samsung clock drivers already include clk.h, which provides API for
Samsung CCF clocks like muxes, gates, etc. Both CPU and PLL Samsung
clock are not that different. It makes sense to only use both clk-cpu.h
and clk-pll.h internally for Samsung CCF framework, and make clk.h the
facade for Samsung CCF. This way all clock drivers only have to include
clk.h.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c        | 1 -
 drivers/clk/samsung/clk-exynos3250.c | 2 --
 drivers/clk/samsung/clk-exynos4.c    | 1 -
 drivers/clk/samsung/clk-exynos5250.c | 1 -
 drivers/clk/samsung/clk-exynos5260.c | 1 -
 drivers/clk/samsung/clk-exynos5420.c | 1 -
 drivers/clk/samsung/clk-exynos5433.c | 2 --
 drivers/clk/samsung/clk-pll.c        | 2 +-
 drivers/clk/samsung/clk-s3c64xx.c    | 1 -
 drivers/clk/samsung/clk-s5pv210.c    | 1 -
 drivers/clk/samsung/clk.h            | 1 +
 11 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index a59949990919..4c46416281a3 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -36,7 +36,6 @@
 #include <linux/clk-provider.h>
 
 #include "clk.h"
-#include "clk-cpu.h"
 
 struct exynos_cpuclk;
 
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index bf149fae04c3..d1b72a75bc5a 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -14,8 +14,6 @@
 #include <dt-bindings/clock/exynos3250.h>
 
 #include "clk.h"
-#include "clk-cpu.h"
-#include "clk-pll.h"
 
 #define SRC_LEFTBUS		0x4200
 #define DIV_LEFTBUS		0x4500
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index d5b1e9f49d8b..3d57020a620f 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -16,7 +16,6 @@
 #include <linux/of_address.h>
 
 #include "clk.h"
-#include "clk-cpu.h"
 
 /* Exynos4 clock controller register offsets */
 #define SRC_LEFTBUS		0x4200
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 58df80de52ef..4953da754994 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -14,7 +14,6 @@
 #include <linux/of_address.h>
 
 #include "clk.h"
-#include "clk-cpu.h"
 #include "clk-exynos5-subcmu.h"
 
 #define APLL_LOCK		0x0
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c
index 16da6ef5ca0c..280330ded100 100644
--- a/drivers/clk/samsung/clk-exynos5260.c
+++ b/drivers/clk/samsung/clk-exynos5260.c
@@ -11,7 +11,6 @@
 
 #include "clk-exynos5260.h"
 #include "clk.h"
-#include "clk-pll.h"
 
 #include <dt-bindings/clock/exynos5260-clk.h>
 
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index bd7b304d2c00..531ef1c3fa30 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -15,7 +15,6 @@
 #include <linux/clk.h>
 
 #include "clk.h"
-#include "clk-cpu.h"
 #include "clk-exynos5-subcmu.h"
 
 #define APLL_LOCK		0x0
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index d3779eefb438..379744f0a5b6 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -17,9 +17,7 @@
 #include <dt-bindings/clock/exynos5433.h>
 
 #include "clk.h"
-#include "clk-cpu.h"
 #include "clk-exynos-arm64.h"
-#include "clk-pll.h"
 
 /* NOTE: Must be equal to the last clock ID increased by one */
 #define CLKS_NR_TOP			(CLK_SCLK_HDMI_SPDIF_DISP + 1)
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 4bbdf5e91650..37aa7beb547a 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -14,8 +14,8 @@
 #include <linux/timekeeping.h>
 #include <linux/clk-provider.h>
 #include <linux/io.h>
+
 #include "clk.h"
-#include "clk-pll.h"
 
 #define PLL_TIMEOUT_US		20000U
 #define PLL_TIMEOUT_LOOPS	1000000U
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
index d27a1f73f077..8ee3ffdf2b8d 100644
--- a/drivers/clk/samsung/clk-s3c64xx.c
+++ b/drivers/clk/samsung/clk-s3c64xx.c
@@ -14,7 +14,6 @@
 #include <dt-bindings/clock/samsung,s3c64xx-clock.h>
 
 #include "clk.h"
-#include "clk-pll.h"
 
 /* S3C64xx clock controller register offsets. */
 #define APLL_LOCK		0x000
diff --git a/drivers/clk/samsung/clk-s5pv210.c b/drivers/clk/samsung/clk-s5pv210.c
index cd85342e4ddb..29f2531fd5d3 100644
--- a/drivers/clk/samsung/clk-s5pv210.c
+++ b/drivers/clk/samsung/clk-s5pv210.c
@@ -13,7 +13,6 @@
 #include <linux/of_address.h>
 
 #include "clk.h"
-#include "clk-pll.h"
 
 #include <dt-bindings/clock/s5pv210.h>
 
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 516b716407e5..8157479f45eb 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -11,6 +11,7 @@
 #define __SAMSUNG_CLK_H
 
 #include <linux/clk-provider.h>
+#include "clk-cpu.h"
 #include "clk-pll.h"
 
 /**
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:39 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:39 -0600
Subject: [PATCH 10/16] clk: samsung: Keep CPU clock chip specific data in a dedicated struct
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-11-semen.protsenko@linaro.org>

Keep chip specific data in the data structure, don't mix it with code.
It makes it easier to add more chip specific data further.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c | 40 +++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 21998c89b96d..04394d2166c9 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -42,6 +42,16 @@ struct exynos_cpuclk;
 typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
 				       struct exynos_cpuclk *cpuclk);
 
+/**
+ * struct exynos_cpuclk_chip - Chip specific data for CPU clock
+ * @pre_rate_cb: callback to run before CPU clock rate change
+ * @post_rate_cb: callback to run after CPU clock rate change
+ */
+struct exynos_cpuclk_chip {
+	exynos_rate_change_fn_t	pre_rate_cb;
+	exynos_rate_change_fn_t	post_rate_cb;
+};
+
 /**
  * struct exynos_cpuclk - information about clock supplied to a CPU core
  * @hw:		handle between CCF and CPU clock
@@ -54,8 +64,7 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
  * @clk_nb:	clock notifier registered for changes in clock speed of the
  *		primary parent clock
  * @flags:	configuration flags for the CPU clock
- * @pre_rate_cb: callback to run before CPU clock rate change
- * @post_rate_cb: callback to run after CPU clock rate change
+ * @chip:	chip-specific data for the CPU clock
  *
  * This structure holds information required for programming the CPU clock for
  * various clock speeds.
@@ -69,9 +78,7 @@ struct exynos_cpuclk {
 	const unsigned long			num_cfgs;
 	struct notifier_block			clk_nb;
 	unsigned long				flags;
-
-	exynos_rate_change_fn_t			pre_rate_cb;
-	exynos_rate_change_fn_t			post_rate_cb;
+	const struct exynos_cpuclk_chip		*chip;
 };
 
 /* ---- Common code --------------------------------------------------------- */
@@ -419,13 +426,24 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
 	cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb);
 
 	if (event == PRE_RATE_CHANGE)
-		err = cpuclk->pre_rate_cb(ndata, cpuclk);
+		err = cpuclk->chip->pre_rate_cb(ndata, cpuclk);
 	else if (event == POST_RATE_CHANGE)
-		err = cpuclk->post_rate_cb(ndata, cpuclk);
+		err = cpuclk->chip->post_rate_cb(ndata, cpuclk);
 
 	return notifier_from_errno(err);
 }
 
+static const struct exynos_cpuclk_chip exynos_clkcpu_chips[] = {
+	[CPUCLK_LAYOUT_E4210] = {
+		.pre_rate_cb	= exynos_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos_cpuclk_post_rate_change,
+	},
+	[CPUCLK_LAYOUT_E5433] = {
+		.pre_rate_cb	= exynos5433_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos5433_cpuclk_post_rate_change,
+	},
+};
+
 /* helper function to register a CPU clock */
 static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 				const struct samsung_cpu_clock *clk_data)
@@ -464,13 +482,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
 	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
-	if (clk_data->reg_layout == CPUCLK_LAYOUT_E5433) {
-		cpuclk->pre_rate_cb = exynos5433_cpuclk_pre_rate_change;
-		cpuclk->post_rate_cb = exynos5433_cpuclk_post_rate_change;
-	} else {
-		cpuclk->pre_rate_cb = exynos_cpuclk_pre_rate_change;
-		cpuclk->post_rate_cb = exynos_cpuclk_post_rate_change;
-	}
+	cpuclk->chip = &exynos_clkcpu_chips[clk_data->reg_layout];
 
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:38 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:38 -0600
Subject: [PATCH 09/16] clk: samsung: Pass register layout type explicitly to CLK_CPU()
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-10-semen.protsenko@linaro.org>

Make it more obvious which register layout should be used for a CPU
clock. It prepares clk-cpu.c for adding new chips support.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c        |  2 +-
 drivers/clk/samsung/clk-cpu.h        | 12 ++++++++++--
 drivers/clk/samsung/clk-exynos3250.c |  2 +-
 drivers/clk/samsung/clk-exynos4.c    |  6 +++---
 drivers/clk/samsung/clk-exynos5250.c |  3 ++-
 drivers/clk/samsung/clk-exynos5420.c |  8 ++++----
 drivers/clk/samsung/clk-exynos5433.c |  8 ++++----
 drivers/clk/samsung/clk.h            |  4 +++-
 8 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 4c46416281a3..21998c89b96d 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -464,7 +464,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
 	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
-	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT) {
+	if (clk_data->reg_layout == CPUCLK_LAYOUT_E5433) {
 		cpuclk->pre_rate_cb = exynos5433_cpuclk_pre_rate_change;
 		cpuclk->post_rate_cb = exynos5433_cpuclk_post_rate_change;
 	} else {
diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h
index ee57f3638fed..4382ab005ad3 100644
--- a/drivers/clk/samsung/clk-cpu.h
+++ b/drivers/clk/samsung/clk-cpu.h
@@ -12,8 +12,16 @@
 #define CLK_CPU_HAS_DIV1		BIT(0)
 /* When ALT parent is active, debug clocks need safe divider values */
 #define CLK_CPU_NEEDS_DEBUG_ALT_DIV	BIT(1)
-/* The CPU clock registers have Exynos5433-compatible layout */
-#define CLK_CPU_HAS_E5433_REGS_LAYOUT	BIT(2)
+
+/**
+ * enum exynos_cpuclk_layout - CPU clock registers layout compatibility
+ * @CPUCLK_LAYOUT_E4210: Exynos4210 compatible layout
+ * @CPUCLK_LAYOUT_E5433: Exynos5433 compatible layout
+ */
+enum exynos_cpuclk_layout {
+	CPUCLK_LAYOUT_E4210,
+	CPUCLK_LAYOUT_E5433,
+};
 
 /**
  * struct exynos_cpuclk_cfg_data - config data to setup cpu clocks
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index d1b72a75bc5a..bd017a68163d 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -773,7 +773,7 @@ static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos3250_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-		CLK_CPU_HAS_DIV1, 0x14000, e3250_armclk_d),
+		CLK_CPU_HAS_DIV1, 0x14000, CPUCLK_LAYOUT_E4210, e3250_armclk_d),
 };
 
 static void __init exynos3_core_down_clock(void __iomem *reg_base)
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 3d57020a620f..e1b7a5e0dbb8 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1252,19 +1252,19 @@ static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
 static const struct samsung_cpu_clock exynos4210_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_SCLK_MPLL,
 		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
-		e4210_armclk_d),
+		CPUCLK_LAYOUT_E4210, e4210_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4212_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
 		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
-		e4212_armclk_d),
+		CPUCLK_LAYOUT_E4210, e4212_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4412_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
 		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
-		e4412_armclk_d),
+		CPUCLK_LAYOUT_E4210, e4412_armclk_d),
 };
 
 /* register exynos4 clocks */
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 4953da754994..36d28d466da9 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -776,7 +776,8 @@ static const struct exynos_cpuclk_cfg_data exynos5250_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos5250_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL,
-		CLK_CPU_HAS_DIV1, 0x0, exynos5250_armclk_d),
+		CLK_CPU_HAS_DIV1, 0x0, CPUCLK_LAYOUT_E4210,
+		exynos5250_armclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 531ef1c3fa30..f8cd28465b58 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -1555,16 +1555,16 @@ static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos5420_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
-		0x0, exynos5420_eglclk_d),
+		0x0, CPUCLK_LAYOUT_E4210, exynos5420_eglclk_d),
 	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
-		0x28000, exynos5420_kfcclk_d),
+		0x28000, CPUCLK_LAYOUT_E4210, exynos5420_kfcclk_d),
 };
 
 static const struct samsung_cpu_clock exynos5800_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
-		0x0, exynos5800_eglclk_d),
+		0x0, CPUCLK_LAYOUT_E4210, exynos5800_eglclk_d),
 	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
-		0x28000, exynos5420_kfcclk_d),
+		0x28000, CPUCLK_LAYOUT_E4210, exynos5420_kfcclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index 379744f0a5b6..d35901af21d0 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -3698,8 +3698,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_apolloclk_d[] __initconst
 
 static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL,
-		CLK_MOUT_BUS_PLL_APOLLO_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
-		0x0, exynos5433_apolloclk_d),
+		CLK_MOUT_BUS_PLL_APOLLO_USER, 0, 0x0,
+		CPUCLK_LAYOUT_E5433, exynos5433_apolloclk_d),
 };
 
 static const struct samsung_cmu_info apollo_cmu_info __initconst = {
@@ -3942,8 +3942,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_atlasclk_d[] __initconst =
 
 static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL,
-		CLK_MOUT_BUS_PLL_ATLAS_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
-		0x0, exynos5433_atlasclk_d),
+		CLK_MOUT_BUS_PLL_ATLAS_USER, 0, 0x0,
+		CPUCLK_LAYOUT_E5433, exynos5433_atlasclk_d),
 };
 
 static const struct samsung_cmu_info atlas_cmu_info __initconst = {
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 8157479f45eb..87bbb8b31b03 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -283,10 +283,11 @@ struct samsung_cpu_clock {
 	unsigned int	alt_parent_id;
 	unsigned long	flags;
 	int		offset;
+	enum exynos_cpuclk_layout reg_layout;
 	const struct exynos_cpuclk_cfg_data *cfg;
 };
 
-#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \
+#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _layout, _cfg) \
 	{							\
 		.id		  = _id,			\
 		.name		  = _name,			\
@@ -294,6 +295,7 @@ struct samsung_cpu_clock {
 		.alt_parent_id	  = _apid,			\
 		.flags		  = _flags,			\
 		.offset		  = _offset,			\
+		.reg_layout	  = _layout,			\
 		.cfg		  = _cfg,			\
 	}
 
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:40 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:40 -0600
Subject: [PATCH 11/16] clk: samsung: Keep register offsets in chip specific structure
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-12-semen.protsenko@linaro.org>

Abstract CPU clock registers by keeping their offsets in a dedicated
chip specific structure to accommodate for oncoming Exynos850 support,
which has different offsets for cluster 0 and cluster 1. This rework
also makes it possible to use exynos_set_safe_div() for all chips, so
exynos5433_set_safe_div() is removed here to reduce the code
duplication.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c | 156 +++++++++++++++++++---------------
 1 file changed, 86 insertions(+), 70 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 04394d2166c9..744b609c222d 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -44,12 +44,14 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
 
 /**
  * struct exynos_cpuclk_chip - Chip specific data for CPU clock
+ * @regs: register offsets for CPU related clocks
  * @pre_rate_cb: callback to run before CPU clock rate change
  * @post_rate_cb: callback to run after CPU clock rate change
  */
 struct exynos_cpuclk_chip {
-	exynos_rate_change_fn_t	pre_rate_cb;
-	exynos_rate_change_fn_t	post_rate_cb;
+	const void				* const regs;
+	exynos_rate_change_fn_t			pre_rate_cb;
+	exynos_rate_change_fn_t			post_rate_cb;
 };
 
 /**
@@ -90,6 +92,24 @@ struct exynos_cpuclk {
 #define DIV_MASK_ALL		GENMASK(31, 0)
 #define MUX_MASK		GENMASK(2, 0)
 
+/**
+ * struct exynos_cpuclk_regs - Register offsets for CPU related clocks
+ * @mux_sel: offset of CPU MUX_SEL register (for selecting MUX clock parent)
+ * @mux_stat: offset of CPU MUX_STAT register (for checking MUX clock status)
+ * @div_cpu0: offset of CPU DIV0 register (for modifying divider values)
+ * @div_cpu1: offset of CPU DIV1 register (for modifying divider values)
+ * @div_stat_cpu0: offset of CPU DIV0_STAT register (for checking DIV status)
+ * @div_stat_cpu1: offset of CPU DIV1_STAT register (for checking DIV status)
+ */
+struct exynos_cpuclk_regs {
+	u32 mux_sel;
+	u32 mux_stat;
+	u32 div_cpu0;
+	u32 div_cpu1;
+	u32 div_stat_cpu0;
+	u32 div_stat_cpu1;
+};
+
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
  * value has changed.
@@ -129,43 +149,48 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
 }
 
-/* ---- Exynos 3/4/5 -------------------------------------------------------- */
-
-#define E4210_SRC_CPU		0x200
-#define E4210_STAT_CPU		0x400
-#define E4210_DIV_CPU0		0x500
-#define E4210_DIV_CPU1		0x504
-#define E4210_DIV_STAT_CPU0	0x600
-#define E4210_DIV_STAT_CPU1	0x604
-
-#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
-#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
-#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
-#define E4210_MUX_HPM_MASK	BIT(20)
-#define E4210_DIV0_ATB_SHIFT	16
-#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
-
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
  * div and mask contain the divider value and the register bit mask of the
  * dividers to be programmed.
  */
-static void exynos_set_safe_div(void __iomem *base, unsigned long div,
+static void exynos_set_safe_div(struct exynos_cpuclk *cpuclk, unsigned long div,
 				unsigned long mask)
 {
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long div0;
 
-	div0 = readl(base + E4210_DIV_CPU0);
+	div0 = readl(base + regs->div_cpu0);
 	div0 = (div0 & ~mask) | (div & mask);
-	writel(div0, base + E4210_DIV_CPU0);
-	wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, mask);
+	writel(div0, base + regs->div_cpu0);
+	wait_until_divider_stable(base + regs->div_stat_cpu0, mask);
 }
 
+/* ---- Exynos 3/4/5 -------------------------------------------------------- */
+
+#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
+#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
+#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
+#define E4210_MUX_HPM_MASK	BIT(20)
+#define E4210_DIV0_ATB_SHIFT	16
+#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
+
+static const struct exynos_cpuclk_regs e4210_cpuclk_regs = {
+	.mux_sel	= 0x200,
+	.mux_stat	= 0x400,
+	.div_cpu0	= 0x500,
+	.div_cpu1	= 0x504,
+	.div_stat_cpu0	= 0x600,
+	.div_stat_cpu1	= 0x604,
+};
+
 /* handler for pre-rate change notification from parent clock */
 static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 					 struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
@@ -188,8 +213,8 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	div0 = cfg_data->div0;
 	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
 		div1 = cfg_data->div1;
-		if (readl(base + E4210_SRC_CPU) & E4210_MUX_HPM_MASK)
-			div1 = readl(base + E4210_DIV_CPU1) &
+		if (readl(base + regs->mux_sel) & E4210_MUX_HPM_MASK)
+			div1 = readl(base + regs->div_cpu1) &
 				(E4210_DIV1_HPM_MASK | E4210_DIV1_COPY_MASK);
 	}
 
@@ -216,22 +241,22 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 			alt_div |= E4210_DIV0_ATB_MASK;
 			alt_div_mask |= E4210_DIV0_ATB_MASK;
 		}
-		exynos_set_safe_div(base, alt_div, alt_div_mask);
+		exynos_set_safe_div(cpuclk, alt_div, alt_div_mask);
 		div0 |= alt_div;
 	}
 
 	/* select sclk_mpll as the alternate parent */
-	mux_reg = readl(base + E4210_SRC_CPU);
-	writel(mux_reg | (1 << 16), base + E4210_SRC_CPU);
-	wait_until_mux_stable(base + E4210_STAT_CPU, 16, 2);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg | (1 << 16), base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 16, 2);
 
 	/* alternate parent is active now. set the dividers */
-	writel(div0, base + E4210_DIV_CPU0);
-	wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, DIV_MASK_ALL);
+	writel(div0, base + regs->div_cpu0);
+	wait_until_divider_stable(base + regs->div_stat_cpu0, DIV_MASK_ALL);
 
 	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
-		writel(div1, base + E4210_DIV_CPU1);
-		wait_until_divider_stable(base + E4210_DIV_STAT_CPU1,
+		writel(div1, base + regs->div_cpu1);
+		wait_until_divider_stable(base + regs->div_stat_cpu1,
 					  DIV_MASK_ALL);
 	}
 
@@ -244,6 +269,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 					  struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
@@ -261,50 +287,37 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	spin_lock_irqsave(cpuclk->lock, flags);
 
 	/* select mout_apll as the alternate parent */
-	mux_reg = readl(base + E4210_SRC_CPU);
-	writel(mux_reg & ~(1 << 16), base + E4210_SRC_CPU);
-	wait_until_mux_stable(base + E4210_STAT_CPU, 16, 1);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg & ~(1 << 16), base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 16, 1);
 
 	if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
 		div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK);
 		div_mask |= E4210_DIV0_ATB_MASK;
 	}
 
-	exynos_set_safe_div(base, div, div_mask);
+	exynos_set_safe_div(cpuclk, div, div_mask);
 	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
 }
 
 /* ---- Exynos5433 ---------------------------------------------------------- */
 
-#define E5433_MUX_SEL2		0x208
-#define E5433_MUX_STAT2		0x408
-#define E5433_DIV_CPU0		0x600
-#define E5433_DIV_CPU1		0x604
-#define E5433_DIV_STAT_CPU0	0x700
-#define E5433_DIV_STAT_CPU1	0x704
-
-/*
- * Helper function to set the 'safe' dividers for the CPU clock. The parameters
- * div and mask contain the divider value and the register bit mask of the
- * dividers to be programmed.
- */
-static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
-				    unsigned long mask)
-{
-	unsigned long div0;
-
-	div0 = readl(base + E5433_DIV_CPU0);
-	div0 = (div0 & ~mask) | (div & mask);
-	writel(div0, base + E5433_DIV_CPU0);
-	wait_until_divider_stable(base + E5433_DIV_STAT_CPU0, mask);
-}
+static const struct exynos_cpuclk_regs e5433_cpuclk_regs = {
+	.mux_sel	= 0x208,
+	.mux_stat	= 0x408,
+	.div_cpu0	= 0x600,
+	.div_cpu1	= 0x604,
+	.div_stat_cpu0	= 0x700,
+	.div_stat_cpu1	= 0x704,
+};
 
 /* handler for pre-rate change notification from parent clock */
 static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 					     struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
@@ -341,21 +354,21 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 		alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
 		WARN_ON(alt_div >= MAX_DIV);
 
-		exynos5433_set_safe_div(base, alt_div, alt_div_mask);
+		exynos_set_safe_div(cpuclk, alt_div, alt_div_mask);
 		div0 |= alt_div;
 	}
 
 	/* select the alternate parent */
-	mux_reg = readl(base + E5433_MUX_SEL2);
-	writel(mux_reg | 1, base + E5433_MUX_SEL2);
-	wait_until_mux_stable(base + E5433_MUX_STAT2, 0, 2);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg | 1, base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 0, 2);
 
 	/* alternate parent is active now. set the dividers */
-	writel(div0, base + E5433_DIV_CPU0);
-	wait_until_divider_stable(base + E5433_DIV_STAT_CPU0, DIV_MASK_ALL);
+	writel(div0, base + regs->div_cpu0);
+	wait_until_divider_stable(base + regs->div_stat_cpu0, DIV_MASK_ALL);
 
-	writel(div1, base + E5433_DIV_CPU1);
-	wait_until_divider_stable(base + E5433_DIV_STAT_CPU1, DIV_MASK_ALL);
+	writel(div1, base + regs->div_cpu1);
+	wait_until_divider_stable(base + regs->div_stat_cpu1, DIV_MASK_ALL);
 
 	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
@@ -365,6 +378,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 					      struct exynos_cpuclk *cpuclk)
 {
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
@@ -373,11 +387,11 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	spin_lock_irqsave(cpuclk->lock, flags);
 
 	/* select apll as the alternate parent */
-	mux_reg = readl(base + E5433_MUX_SEL2);
-	writel(mux_reg & ~1, base + E5433_MUX_SEL2);
-	wait_until_mux_stable(base + E5433_MUX_STAT2, 0, 1);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg & ~1, base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 0, 1);
 
-	exynos5433_set_safe_div(base, div, div_mask);
+	exynos_set_safe_div(cpuclk, div, div_mask);
 	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
 }
@@ -435,10 +449,12 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
 
 static const struct exynos_cpuclk_chip exynos_clkcpu_chips[] = {
 	[CPUCLK_LAYOUT_E4210] = {
+		.regs		= &e4210_cpuclk_regs,
 		.pre_rate_cb	= exynos_cpuclk_pre_rate_change,
 		.post_rate_cb	= exynos_cpuclk_post_rate_change,
 	},
 	[CPUCLK_LAYOUT_E5433] = {
+		.regs		= &e5433_cpuclk_regs,
 		.pre_rate_cb	= exynos5433_cpuclk_pre_rate_change,
 		.post_rate_cb	= exynos5433_cpuclk_post_rate_change,
 	},
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:41 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:41 -0600
Subject: [PATCH 12/16] clk: samsung: Pass mask to wait_until_mux_stable()
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-13-semen.protsenko@linaro.org>

Make it possible to use wait_until_mux_stable() for MUX registers where
the mask is different from MUX_MASK (e.g. in upcoming CPU clock
implementation for Exynos850).

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-cpu.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 744b609c222d..5ea618da0bc1 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -134,16 +134,16 @@ static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
  * value was changed.
  */
 static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
-				  unsigned long mux_value)
+				  unsigned long mask, unsigned long mux_value)
 {
 	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);
 
 	do {
-		if (((readl(mux_reg) >> mux_pos) & MUX_MASK) == mux_value)
+		if (((readl(mux_reg) >> mux_pos) & mask) == mux_value)
 			return;
 	} while (time_before(jiffies, timeout));
 
-	if (((readl(mux_reg) >> mux_pos) & MUX_MASK) == mux_value)
+	if (((readl(mux_reg) >> mux_pos) & mask) == mux_value)
 		return;
 
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
@@ -248,7 +248,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	/* select sclk_mpll as the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg | (1 << 16), base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 16, 2);
+	wait_until_mux_stable(base + regs->mux_stat, 16, MUX_MASK, 2);
 
 	/* alternate parent is active now. set the dividers */
 	writel(div0, base + regs->div_cpu0);
@@ -289,7 +289,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	/* select mout_apll as the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg & ~(1 << 16), base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 16, 1);
+	wait_until_mux_stable(base + regs->mux_stat, 16, MUX_MASK, 1);
 
 	if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
 		div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK);
@@ -361,7 +361,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	/* select the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg | 1, base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 0, 2);
+	wait_until_mux_stable(base + regs->mux_stat, 0, MUX_MASK, 2);
 
 	/* alternate parent is active now. set the dividers */
 	writel(div0, base + regs->div_cpu0);
@@ -389,7 +389,7 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	/* select apll as the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg & ~1, base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 0, 1);
+	wait_until_mux_stable(base + regs->mux_stat, 0, MUX_MASK, 1);
 
 	exynos_set_safe_div(cpuclk, div, div_mask);
 	spin_unlock_irqrestore(cpuclk->lock, flags);
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:43 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:43 -0600
Subject: [PATCH 14/16] clk: samsung: Implement manual PLL control for ARM64 SoCs
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-15-semen.protsenko@linaro.org>

Some ARM64 Exynos chips are capable to control PLL clocks automatically.
For those chips, whether the PLL is controlled automatically or manually
is chosen in PLL_CON1 register with next bits:

    [28]  ENABLE_AUTOMATIC_CLKGATING
    [1]   MANUAL_PLL_CTRL
    [0]   AUTO_PLL_CTRL

The bl2 bootloader sets 0x10000001 value for some PLL_CON1 registers,
which means any attempt to control those PLLs manually (e.g.
disabling/enabling those PLLs or changing MUX parent clocks) would lead
to PLL lock timeout with error message like this:

    Could not lock PLL ...

At the moment, all Samsung clock drivers implement manual clock control.
So in order to make it possible to control PLLs, corresponding PLL_CON1
registers should be set to 0x2 first.

Some older ARM64 chips don't implement the automatic clock control
though. It also might be desirable to configure some PLLs for manual
control, while keeping the default configuration for the rest. So it'd
convenient to choose this PLL mode for each CMU separately. Introduce
.manual_plls field to CMU structure to choose the PLL control mode.
Because it'll be initialized with "false" in all existing CMU
structures by default, it won't affect any existing clock drivers,
allowing for this feature to be enabled gradually when it's needed with
no change for the rest of users. In case .manual_plls is set, set
PLL_CON1 registers to manual control, akin to what's already done for
gate clocks in exynos_arm64_init_clocks(). Of course, PLL_CON1 registers
should be added to corresponding struct samsung_cmu_info::clk_regs array
to make sure they get initialized.

No functional change. This patch adds a feature, but doesn't enable it
for any users.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-exynos-arm64.c | 44 +++++++++++++++++---------
 drivers/clk/samsung/clk.h              |  4 +++
 2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos-arm64.c b/drivers/clk/samsung/clk-exynos-arm64.c
index 6fb7194df7ab..55490209b9a9 100644
--- a/drivers/clk/samsung/clk-exynos-arm64.c
+++ b/drivers/clk/samsung/clk-exynos-arm64.c
@@ -25,6 +25,19 @@
 #define GATE_OFF_START		0x2000
 #define GATE_OFF_END		0x2fff
 
+/* PLL CON register offsets range */
+#define PLL_CON_START		0x100
+#define PLL_CON_END		0x600
+
+/* PLL register bits */
+#define PLL_CON1_MANUAL		BIT(1)
+
+/* Helper macros to check for particular clock regiter by its offset */
+#define IS_GATE_REG(o)		((o) >= GATE_OFF_START && (o) <= GATE_OFF_END)
+#define IS_PLL_CONx_REG(o)	((o) >= PLL_CON_START && (o) <= PLL_CON_END)
+#define IS_PLL_CON1_REG(o)	\
+	(IS_PLL_CONx_REG(o) && ((o) & 0xf) == 0x4 && !((o) & 0x10))
+
 struct exynos_arm64_cmu_data {
 	struct samsung_clk_reg_dump *clk_save;
 	unsigned int nr_clk_save;
@@ -40,15 +53,16 @@ struct exynos_arm64_cmu_data {
 
 /**
  * exynos_arm64_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
+ * @np:		CMU device tree node with "reg" property (CMU addr)
+ * @cmu:	CMU data
  *
- * Set manual control mode for all gate clocks.
+ * Set manual control mode for all gate and PLL clocks.
  */
 static void __init exynos_arm64_init_clocks(struct device_node *np,
-		const unsigned long *reg_offs, size_t reg_offs_len)
+					    const struct samsung_cmu_info *cmu)
 {
+	const unsigned long *reg_offs = cmu->clk_regs;
+	size_t reg_offs_len = cmu->nr_clk_regs;
 	void __iomem *reg_base;
 	size_t i;
 
@@ -60,14 +74,14 @@ static void __init exynos_arm64_init_clocks(struct device_node *np,
 		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);
+		if (cmu->manual_plls && IS_PLL_CON1_REG(reg_offs[i])) {
+			writel(PLL_CON1_MANUAL, reg);
+		} else if (IS_GATE_REG(reg_offs[i])) {
+			val = readl(reg);
+			val |= GATE_MANUAL;
+			val &= ~GATE_ENABLE_HWACG;
+			writel(val, reg);
+		}
 	}
 
 	iounmap(reg_base);
@@ -177,7 +191,7 @@ void __init exynos_arm64_register_cmu(struct device *dev,
 		pr_err("%s: could not enable bus clock %s; err = %d\n",
 		       __func__, cmu->clk_name, err);
 
-	exynos_arm64_init_clocks(np, cmu->clk_regs, cmu->nr_clk_regs);
+	exynos_arm64_init_clocks(np, cmu);
 	samsung_cmu_register_one(np, cmu);
 }
 
@@ -224,7 +238,7 @@ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev,
 		       __func__, cmu->clk_name, ret);
 
 	if (set_manual)
-		exynos_arm64_init_clocks(np, cmu->clk_regs, cmu->nr_clk_regs);
+		exynos_arm64_init_clocks(np, cmu);
 
 	reg_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(reg_base))
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 87bbb8b31b03..632c21dbd873 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -330,6 +330,7 @@ struct samsung_clock_reg_cache {
  * @suspend_regs: list of clock registers to set before suspend
  * @nr_suspend_regs: count of clock registers in @suspend_regs
  * @clk_name: name of the parent clock needed for CMU register access
+ * @manual_plls: Enable manual control for PLL clocks
  */
 struct samsung_cmu_info {
 	const struct samsung_pll_clock *pll_clks;
@@ -354,6 +355,9 @@ struct samsung_cmu_info {
 	const struct samsung_clk_reg_dump *suspend_regs;
 	unsigned int nr_suspend_regs;
 	const char *clk_name;
+
+	/* ARM64 Exynos CMUs */
+	bool manual_plls;
 };
 
 struct samsung_clk_provider *samsung_clk_init(struct device *dev,
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:45 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:45 -0600
Subject: [PATCH 16/16] arm64: dts: exynos: Add CPU clocks
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-17-semen.protsenko@linaro.org>

Define CPU cluster 0 and CPU cluster 1 CMUs, which generate CPU clocks,
and add corresponding CPU clocks to CPU nodes.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 arch/arm64/boot/dts/exynos/exynos850.dtsi | 26 +++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
index 2ba67c3d0681..0706c8534ceb 100644
--- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -93,6 +93,8 @@ cpu0: cpu at 0 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0>;
 			enable-method = "psci";
+			clocks = <&cmu_cpucl0 CLK_CLUSTER0_SCLK>;
+			clock-names = "cluster0_clk";
 		};
 		cpu1: cpu at 1 {
 			device_type = "cpu";
@@ -117,6 +119,8 @@ cpu4: cpu at 100 {
 			compatible = "arm,cortex-a55";
 			reg = <0x100>;
 			enable-method = "psci";
+			clocks = <&cmu_cpucl1 CLK_CLUSTER1_SCLK>;
+			clock-names = "cluster1_clk";
 		};
 		cpu5: cpu at 101 {
 			device_type = "cpu";
@@ -254,6 +258,28 @@ cmu_peri: clock-controller at 10030000 {
 				      "dout_peri_uart", "dout_peri_ip";
 		};
 
+		cmu_cpucl1: clock-controller at 10800000 {
+			compatible = "samsung,exynos850-cmu-cpucl1";
+			reg = <0x10800000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_CPUCL1_SWITCH>,
+				 <&cmu_top CLK_DOUT_CPUCL1_DBG>;
+			clock-names = "oscclk", "dout_cpucl1_switch",
+				      "dout_cpucl1_dbg";
+		};
+
+		cmu_cpucl0: clock-controller at 10900000 {
+			compatible = "samsung,exynos850-cmu-cpucl0";
+			reg = <0x10900000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_CPUCL0_SWITCH>,
+				 <&cmu_top CLK_DOUT_CPUCL0_DBG>;
+			clock-names = "oscclk", "dout_cpucl0_switch",
+				      "dout_cpucl0_dbg";
+		};
+
 		cmu_g3d: clock-controller at 11400000 {
 			compatible = "samsung,exynos850-cmu-g3d";
 			reg = <0x11400000 0x8000>;
-- 
2.39.2



From semen.protsenko at linaro.org  Fri Feb 16 14:32:44 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 16 Feb 2024 16:32:44 -0600
Subject: [PATCH 15/16] clk: samsung: exynos850: Add CMU_CPUCL0 and CMU_CPUCL1
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <20240216223245.12273-16-semen.protsenko@linaro.org>

Implement support for CPU clock management units:
  - CMU_CPUCL0: clocks for cluster 0: 4 x Cortex-A55 (cpu0..cpu3)
  - CMU_CPUCL1: clocks for cluster 1: 4 x Cortex-A55 (cpu4..cpu7)

CPU PLLs are generating main CPU clocks for each cluster, and there are
alternate ("switch") clocks that can be used temporarily while
re-configuring the PLL for a new rate. ACLK, ATCLK, PCLKDBG and
PERIPHCLK clocks are driving corresponding buses. CLK_CLUSTERx_SCLK are
actual leaf CPU clocks and should be used to change CPU rates. Also some
CoreSight clocks can be derived from DBG_USER (debug clock).

PLL table was extracted from ECT table. ECT stands for "Exynos
Characteristic Table", it's a Samsung specific binary data populated by
BL2 bootloader in RAM at 0x90000000 address, containing PLL tables for
various CMUs and other hardware specific information.

The particular PLL type used in CMU_CPUCL0 and CMU_CPUCL1 (pll0822x) is
an integer PLL with middle FVCO. The equation to calculate its output
rate is:

    fout = fin * M / (P*2^S)

where:

    fin = 26 MHz (OSCCLK frequency)
    M = 64..1023
    P = 1..63
    S = 0..6

The PLL table tries to keep "P" value low to reduce the locking time,
which for pll0822x is "t = P * 150" (in OSCCLK cycles).

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/clk/samsung/clk-exynos850.c | 440 +++++++++++++++++++++++++++-
 1 file changed, 439 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c
index 82cfa22c0788..6215471c4ac6 100644
--- a/drivers/clk/samsung/clk-exynos850.c
+++ b/drivers/clk/samsung/clk-exynos850.c
@@ -14,13 +14,16 @@
 #include <dt-bindings/clock/exynos850.h>
 
 #include "clk.h"
+#include "clk-cpu.h"
 #include "clk-exynos-arm64.h"
 
 /* NOTE: Must be equal to the last clock ID increased by one */
-#define CLKS_NR_TOP			(CLK_DOUT_G3D_SWITCH + 1)
+#define CLKS_NR_TOP			(CLK_DOUT_CPUCL1_SWITCH + 1)
 #define CLKS_NR_APM			(CLK_GOUT_SYSREG_APM_PCLK + 1)
 #define CLKS_NR_AUD			(CLK_GOUT_AUD_CMU_AUD_PCLK + 1)
 #define CLKS_NR_CMGP			(CLK_GOUT_SYSREG_CMGP_PCLK + 1)
+#define CLKS_NR_CPUCL0			(CLK_CLUSTER0_SCLK + 1)
+#define CLKS_NR_CPUCL1			(CLK_CLUSTER1_SCLK + 1)
 #define CLKS_NR_G3D			(CLK_GOUT_G3D_SYSREG_PCLK + 1)
 #define CLKS_NR_HSI			(CLK_GOUT_HSI_CMU_HSI_PCLK + 1)
 #define CLKS_NR_IS			(CLK_GOUT_IS_SYSREG_PCLK + 1)
@@ -47,6 +50,10 @@
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI		0x1018
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD	0x101c
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS		0x1020
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG	0x1024
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH	0x1028
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL1_DBG	0x102c
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH	0x1030
 #define CLK_CON_MUX_MUX_CLKCMU_DPU		0x1034
 #define CLK_CON_MUX_MUX_CLKCMU_G3D_SWITCH	0x1038
 #define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS		0x103c
@@ -69,6 +76,10 @@
 #define CLK_CON_DIV_CLKCMU_CORE_CCI		0x1824
 #define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD	0x1828
 #define CLK_CON_DIV_CLKCMU_CORE_SSS		0x182c
+#define CLK_CON_DIV_CLKCMU_CPUCL0_DBG		0x1830
+#define CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH	0x1834
+#define CLK_CON_DIV_CLKCMU_CPUCL1_DBG		0x1838
+#define CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH	0x183c
 #define CLK_CON_DIV_CLKCMU_DPU			0x1840
 #define CLK_CON_DIV_CLKCMU_G3D_SWITCH		0x1844
 #define CLK_CON_DIV_CLKCMU_HSI_BUS		0x1848
@@ -97,6 +108,10 @@
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI	0x2020
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD	0x2024
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS	0x2028
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG	0x202c
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH	0x2030
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL1_DBG	0x2034
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH	0x2038
 #define CLK_CON_GAT_GATE_CLKCMU_DPU		0x203c
 #define CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH	0x2040
 #define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS		0x2044
@@ -130,6 +145,10 @@ static const unsigned long top_clk_regs[] __initconst = {
 	CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
 	CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD,
 	CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL1_DBG,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
 	CLK_CON_MUX_MUX_CLKCMU_DPU,
 	CLK_CON_MUX_MUX_CLKCMU_G3D_SWITCH,
 	CLK_CON_MUX_MUX_CLKCMU_HSI_BUS,
@@ -152,6 +171,10 @@ static const unsigned long top_clk_regs[] __initconst = {
 	CLK_CON_DIV_CLKCMU_CORE_CCI,
 	CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD,
 	CLK_CON_DIV_CLKCMU_CORE_SSS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_DBG,
+	CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL1_DBG,
+	CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH,
 	CLK_CON_DIV_CLKCMU_DPU,
 	CLK_CON_DIV_CLKCMU_G3D_SWITCH,
 	CLK_CON_DIV_CLKCMU_HSI_BUS,
@@ -180,6 +203,10 @@ static const unsigned long top_clk_regs[] __initconst = {
 	CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
 	CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD,
 	CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL1_DBG,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
 	CLK_CON_GAT_GATE_CLKCMU_DPU,
 	CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
 	CLK_CON_GAT_GATE_CLKCMU_HSI_BUS,
@@ -234,6 +261,14 @@ PNAME(mout_core_mmc_embd_p)	= { "oscclk", "dout_shared0_div2",
 				    "oscclk", "oscclk" };
 PNAME(mout_core_sss_p)		= { "dout_shared0_div3", "dout_shared1_div3",
 				    "dout_shared0_div4", "dout_shared1_div4" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_CPUCL0 */
+PNAME(mout_cpucl0_switch_p)	= { "fout_shared0_pll", "fout_shared1_pll",
+				    "dout_shared0_div2", "dout_shared1_div2" };
+PNAME(mout_cpucl0_dbg_p)	= { "dout_shared0_div4", "dout_shared1_div4" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_CPUCL1 */
+PNAME(mout_cpucl1_switch_p)	= { "fout_shared0_pll", "fout_shared1_pll",
+				    "dout_shared0_div2", "dout_shared1_div2" };
+PNAME(mout_cpucl1_dbg_p)	= { "dout_shared0_div4", "dout_shared1_div4" };
 /* List of parent clocks for Muxes in CMU_TOP: for CMU_G3D */
 PNAME(mout_g3d_switch_p)	= { "dout_shared0_div2", "dout_shared1_div2",
 				    "dout_shared0_div3", "dout_shared1_div3" };
@@ -300,6 +335,18 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = {
 	MUX(CLK_MOUT_CORE_SSS, "mout_core_sss", mout_core_sss_p,
 	    CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 0, 2),
 
+	/* CPUCL0 */
+	MUX(CLK_MOUT_CPUCL0_DBG, "mout_cpucl0_dbg", mout_cpucl0_dbg_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG, 0, 1),
+	MUX(CLK_MOUT_CPUCL0_SWITCH, "mout_cpucl0_switch", mout_cpucl0_switch_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH, 0, 2),
+
+	/* CPUCL1 */
+	MUX(CLK_MOUT_CPUCL1_DBG, "mout_cpucl1_dbg", mout_cpucl1_dbg_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL1_DBG, 0, 1),
+	MUX(CLK_MOUT_CPUCL1_SWITCH, "mout_cpucl1_switch", mout_cpucl1_switch_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH, 0, 2),
+
 	/* DPU */
 	MUX(CLK_MOUT_DPU, "mout_dpu", mout_dpu_p,
 	    CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 2),
@@ -378,6 +425,18 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
 	DIV(CLK_DOUT_CORE_SSS, "dout_core_sss", "gout_core_sss",
 	    CLK_CON_DIV_CLKCMU_CORE_SSS, 0, 4),
 
+	/* CPUCL0 */
+	DIV(CLK_DOUT_CPUCL0_DBG, "dout_cpucl0_dbg", "gout_cpucl0_dbg",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_DBG, 0, 3),
+	DIV(CLK_DOUT_CPUCL0_SWITCH, "dout_cpucl0_switch", "gout_cpucl0_switch",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH, 0, 3),
+
+	/* CPUCL1 */
+	DIV(CLK_DOUT_CPUCL1_DBG, "dout_cpucl1_dbg", "gout_cpucl1_dbg",
+	    CLK_CON_DIV_CLKCMU_CPUCL1_DBG, 0, 3),
+	DIV(CLK_DOUT_CPUCL1_SWITCH, "dout_cpucl1_switch", "gout_cpucl1_switch",
+	    CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH, 0, 3),
+
 	/* DPU */
 	DIV(CLK_DOUT_DPU, "dout_dpu", "gout_dpu",
 	    CLK_CON_DIV_CLKCMU_DPU, 0, 4),
@@ -442,6 +501,18 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
 	GATE(CLK_GOUT_AUD, "gout_aud", "mout_aud",
 	     CLK_CON_GAT_GATE_CLKCMU_AUD, 21, 0, 0),
 
+	/* CPUCL0 */
+	GATE(CLK_GOUT_CPUCL0_DBG, "gout_cpucl0_dbg", "mout_cpucl0_dbg",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG, 21, 0, 0),
+	GATE(CLK_GOUT_CPUCL0_SWITCH, "gout_cpucl0_switch", "mout_cpucl0_switch",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH, 21, 0, 0),
+
+	/* CPUCL1 */
+	GATE(CLK_GOUT_CPUCL1_DBG, "gout_cpucl1_dbg", "mout_cpucl1_dbg",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL1_DBG, 21, 0, 0),
+	GATE(CLK_GOUT_CPUCL1_SWITCH, "gout_cpucl1_switch", "mout_cpucl1_switch",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH, 21, 0, 0),
+
 	/* DPU */
 	GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu",
 	     CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
@@ -1030,6 +1101,373 @@ static const struct samsung_cmu_info cmgp_cmu_info __initconst = {
 	.clk_name		= "gout_clkcmu_cmgp_bus",
 };
 
+/* ---- CMU_CPUCL0 ---------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_CPUCL0 (0x10900000) */
+#define PLL_LOCKTIME_PLL_CPUCL0				0x0000
+#define PLL_CON0_PLL_CPUCL0				0x0100
+#define PLL_CON1_PLL_CPUCL0				0x0104
+#define PLL_CON3_PLL_CPUCL0				0x010c
+#define PLL_CON0_MUX_CLKCMU_CPUCL0_DBG_USER		0x0600
+#define PLL_CON0_MUX_CLKCMU_CPUCL0_SWITCH_USER		0x0610
+#define CLK_CON_MUX_MUX_CLK_CPUCL0_PLL			0x100c
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_ACLK		0x1800
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_ATCLK		0x1808
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_PCLKDBG		0x180c
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_PERIPHCLK		0x1810
+#define CLK_CON_DIV_DIV_CLK_CPUCL0_CMUREF		0x1814
+#define CLK_CON_DIV_DIV_CLK_CPUCL0_CPU			0x1818
+#define CLK_CON_DIV_DIV_CLK_CPUCL0_PCLK			0x181c
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_ATCLK		0x2000
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PCLK		0x2004
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PERIPHCLK	0x2008
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_SCLK		0x200c
+#define CLK_CON_GAT_CLK_CPUCL0_CMU_CPUCL0_PCLK		0x2010
+#define CLK_CON_GAT_GATE_CLK_CPUCL0_CPU			0x2020
+
+static const unsigned long cpucl0_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CPUCL0,
+	PLL_CON0_PLL_CPUCL0,
+	PLL_CON1_PLL_CPUCL0,
+	PLL_CON3_PLL_CPUCL0,
+	PLL_CON0_MUX_CLKCMU_CPUCL0_DBG_USER,
+	PLL_CON0_MUX_CLKCMU_CPUCL0_SWITCH_USER,
+	CLK_CON_MUX_MUX_CLK_CPUCL0_PLL,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_ACLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_ATCLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_PCLKDBG,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_PERIPHCLK,
+	CLK_CON_DIV_DIV_CLK_CPUCL0_CMUREF,
+	CLK_CON_DIV_DIV_CLK_CPUCL0_CPU,
+	CLK_CON_DIV_DIV_CLK_CPUCL0_PCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_ATCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PERIPHCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_SCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CMU_CPUCL0_PCLK,
+	CLK_CON_GAT_GATE_CLK_CPUCL0_CPU,
+};
+
+/* List of parent clocks for Muxes in CMU_CPUCL0 */
+PNAME(mout_pll_cpucl0_p)		 = { "oscclk", "fout_cpucl0_pll" };
+PNAME(mout_cpucl0_switch_user_p)	 = { "oscclk", "dout_cpucl0_switch" };
+PNAME(mout_cpucl0_dbg_user_p)		 = { "oscclk", "dout_cpucl0_dbg" };
+PNAME(mout_cpucl0_pll_p)		 = { "mout_pll_cpucl0",
+					     "mout_cpucl0_switch_user" };
+
+static const struct samsung_pll_rate_table cpu_pll_rates[] __initconst = {
+	PLL_35XX_RATE(26 * MHZ, 2210000000U, 255, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 2106000000U, 243, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 2002000000U, 231, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1846000000U, 213, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1742000000U, 201, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1586000000U, 183, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1456000000U, 168, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1300000000U, 150, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1157000000U, 267, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 1053000000U, 243, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 949000000U,  219, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 806000000U,  186, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 650000000U,  150, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 546000000U,  252, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 442000000U,  204, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 351000000U,  162, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 247000000U,  114, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 182000000U,  168, 3, 3),
+	PLL_35XX_RATE(26 * MHZ, 130000000U,  120, 3, 3),
+};
+
+static const struct samsung_pll_clock cpucl0_pll_clks[] __initconst = {
+	PLL(pll_0822x, CLK_FOUT_CPUCL0_PLL, "fout_cpucl0_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_CPUCL0, PLL_CON3_PLL_CPUCL0, cpu_pll_rates),
+};
+
+static const struct samsung_mux_clock cpucl0_mux_clks[] __initconst = {
+	MUX_F(CLK_MOUT_PLL_CPUCL0, "mout_pll_cpucl0", mout_pll_cpucl0_p,
+	      PLL_CON0_PLL_CPUCL0, 4, 1,
+	      CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0),
+	MUX_F(CLK_MOUT_CPUCL0_SWITCH_USER, "mout_cpucl0_switch_user",
+	      mout_cpucl0_switch_user_p,
+	      PLL_CON0_MUX_CLKCMU_CPUCL0_SWITCH_USER, 4, 1,
+	      CLK_SET_RATE_PARENT, 0),
+	MUX(CLK_MOUT_CPUCL0_DBG_USER, "mout_cpucl0_dbg_user",
+	    mout_cpucl0_dbg_user_p,
+	    PLL_CON0_MUX_CLKCMU_CPUCL0_DBG_USER, 4, 1),
+	MUX_F(CLK_MOUT_CPUCL0_PLL, "mout_cpucl0_pll", mout_cpucl0_pll_p,
+	      CLK_CON_MUX_MUX_CLK_CPUCL0_PLL, 0, 1, CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_div_clock cpucl0_div_clks[] __initconst = {
+	DIV_F(CLK_DOUT_CPUCL0_CPU, "dout_cpucl0_cpu", "mout_cpucl0_pll",
+	      CLK_CON_DIV_DIV_CLK_CPUCL0_CPU, 0, 1,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL0_CMUREF, "dout_cpucl0_cmuref", "dout_cpucl0_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL0_CMUREF, 0, 3,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL0_PCLK, "dout_cpucl0_pclk", "dout_cpucl0_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL0_PCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+
+	/* EMBEDDED_CMU_CPUCL0 */
+	DIV_F(CLK_DOUT_CLUSTER0_ACLK, "dout_cluster0_aclk", "gout_cluster0_cpu",
+	      CLK_CON_DIV_DIV_CLK_CLUSTER0_ACLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER0_ATCLK, "dout_cluster0_atclk",
+	      "gout_cluster0_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER0_ATCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER0_PCLKDBG, "dout_cluster0_pclkdbg",
+	      "gout_cluster0_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER0_PCLKDBG, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER0_PERIPHCLK, "dout_cluster0_periphclk",
+	      "gout_cluster0_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER0_PERIPHCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+};
+
+static const struct samsung_gate_clock cpucl0_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_CPUCL0_CMU_CPUCL0_PCLK, "gout_cpucl0_cmu_cpucl0_pclk",
+	     "dout_cpucl0_pclk",
+	     CLK_CON_GAT_CLK_CPUCL0_CMU_CPUCL0_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+
+	/* EMBEDDED_CMU_CPUCL0 */
+	GATE(CLK_GOUT_CLUSTER0_CPU, "gout_cluster0_cpu", "dout_cpucl0_cpu",
+	     CLK_CON_GAT_GATE_CLK_CPUCL0_CPU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_SCLK, "gout_cluster0_sclk", "gout_cluster0_cpu",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_SCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_ATCLK, "gout_cluster0_atclk",
+	     "dout_cluster0_atclk",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_ATCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_PERIPHCLK, "gout_cluster0_periphclk",
+	     "dout_cluster0_periphclk",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PERIPHCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_PCLK, "gout_cluster0_pclk",
+	     "dout_cluster0_pclkdbg",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+/*
+ * Each parameter is going to be written into the corresponding DIV register. So
+ * the actual divider value for each parameter will be 1/(param+1). All these
+ * parameters must be in the range of 0..15, as the divider range for all of
+ * these DIV clocks is 1..16. The default values for these dividers is
+ * (1, 3, 3, 1).
+ */
+#define E850_CPU_DIV0(aclk, atclk, pclkdbg, periphclk) \
+	(((aclk) << 16) | ((atclk) << 12) | ((pclkdbg) << 8) | \
+	 ((periphclk) << 4))
+
+static const struct exynos_cpuclk_cfg_data exynos850_cluster_clk_d[] __initconst
+= {
+	{ 2210000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 2106000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 2002000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1846000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1742000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1586000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1456000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1300000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1157000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1053000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 949000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 806000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 650000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 546000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 442000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 351000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 247000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 182000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 130000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 0 }
+};
+
+static const struct samsung_cpu_clock cpucl0_cpu_clks[] __initconst = {
+	CPU_CLK(CLK_CLUSTER0_SCLK, "cluster0_clk", CLK_MOUT_PLL_CPUCL0,
+		CLK_MOUT_CPUCL0_SWITCH_USER, 0, 0x0, CPUCLK_LAYOUT_E850_CL0,
+		exynos850_cluster_clk_d),
+};
+
+static const struct samsung_cmu_info cpucl0_cmu_info __initconst = {
+	.pll_clks		= cpucl0_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cpucl0_pll_clks),
+	.mux_clks		= cpucl0_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cpucl0_mux_clks),
+	.div_clks		= cpucl0_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cpucl0_div_clks),
+	.gate_clks		= cpucl0_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cpucl0_gate_clks),
+	.cpu_clks		= cpucl0_cpu_clks,
+	.nr_cpu_clks		= ARRAY_SIZE(cpucl0_cpu_clks),
+	.nr_clk_ids		= CLKS_NR_CPUCL0,
+	.clk_regs		= cpucl0_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cpucl0_clk_regs),
+	.clk_name		= "dout_cpucl0_switch",
+	.manual_plls		= true,
+};
+
+static void __init exynos850_cmu_cpucl0_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &cpucl0_cmu_info);
+}
+
+/* Register CMU_CPUCL0 early, as CPU clocks should be available ASAP */
+CLK_OF_DECLARE(exynos850_cmu_cpucl0, "samsung,exynos850-cmu-cpucl0",
+	       exynos850_cmu_cpucl0_init);
+
+/* ---- CMU_CPUCL1 ---------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_CPUCL1 (0x10800000) */
+#define PLL_LOCKTIME_PLL_CPUCL1				0x0000
+#define PLL_CON0_PLL_CPUCL1				0x0100
+#define PLL_CON1_PLL_CPUCL1				0x0104
+#define PLL_CON3_PLL_CPUCL1				0x010c
+#define PLL_CON0_MUX_CLKCMU_CPUCL1_DBG_USER		0x0600
+#define PLL_CON0_MUX_CLKCMU_CPUCL1_SWITCH_USER		0x0610
+#define CLK_CON_MUX_MUX_CLK_CPUCL1_PLL			0x1000
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_ACLK		0x1800
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_ATCLK		0x1808
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_PCLKDBG		0x180c
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_PERIPHCLK		0x1810
+#define CLK_CON_DIV_DIV_CLK_CPUCL1_CMUREF		0x1814
+#define CLK_CON_DIV_DIV_CLK_CPUCL1_CPU			0x1818
+#define CLK_CON_DIV_DIV_CLK_CPUCL1_PCLK			0x181c
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_ATCLK		0x2000
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PCLK		0x2004
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PERIPHCLK	0x2008
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_SCLK		0x200c
+#define CLK_CON_GAT_CLK_CPUCL1_CMU_CPUCL1_PCLK		0x2010
+#define CLK_CON_GAT_GATE_CLK_CPUCL1_CPU			0x2020
+
+static const unsigned long cpucl1_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CPUCL1,
+	PLL_CON0_PLL_CPUCL1,
+	PLL_CON1_PLL_CPUCL1,
+	PLL_CON3_PLL_CPUCL1,
+	PLL_CON0_MUX_CLKCMU_CPUCL1_DBG_USER,
+	PLL_CON0_MUX_CLKCMU_CPUCL1_SWITCH_USER,
+	CLK_CON_MUX_MUX_CLK_CPUCL1_PLL,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_ACLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_ATCLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_PCLKDBG,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_PERIPHCLK,
+	CLK_CON_DIV_DIV_CLK_CPUCL1_CMUREF,
+	CLK_CON_DIV_DIV_CLK_CPUCL1_CPU,
+	CLK_CON_DIV_DIV_CLK_CPUCL1_PCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_ATCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PERIPHCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_SCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CMU_CPUCL1_PCLK,
+	CLK_CON_GAT_GATE_CLK_CPUCL1_CPU,
+};
+
+/* List of parent clocks for Muxes in CMU_CPUCL0 */
+PNAME(mout_pll_cpucl1_p)		 = { "oscclk", "fout_cpucl1_pll" };
+PNAME(mout_cpucl1_switch_user_p)	 = { "oscclk", "dout_cpucl1_switch" };
+PNAME(mout_cpucl1_dbg_user_p)		 = { "oscclk", "dout_cpucl1_dbg" };
+PNAME(mout_cpucl1_pll_p)		 = { "mout_pll_cpucl1",
+					     "mout_cpucl1_switch_user" };
+
+static const struct samsung_pll_clock cpucl1_pll_clks[] __initconst = {
+	PLL(pll_0822x, CLK_FOUT_CPUCL1_PLL, "fout_cpucl1_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_CPUCL1, PLL_CON3_PLL_CPUCL1, cpu_pll_rates),
+};
+
+static const struct samsung_mux_clock cpucl1_mux_clks[] __initconst = {
+	MUX_F(CLK_MOUT_PLL_CPUCL1, "mout_pll_cpucl1", mout_pll_cpucl1_p,
+	      PLL_CON0_PLL_CPUCL1, 4, 1,
+	      CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0),
+	MUX_F(CLK_MOUT_CPUCL1_SWITCH_USER, "mout_cpucl1_switch_user",
+	      mout_cpucl1_switch_user_p,
+	      PLL_CON0_MUX_CLKCMU_CPUCL1_SWITCH_USER, 4, 1,
+	      CLK_SET_RATE_PARENT, 0),
+	MUX(CLK_MOUT_CPUCL1_DBG_USER, "mout_cpucl1_dbg_user",
+	    mout_cpucl1_dbg_user_p,
+	    PLL_CON0_MUX_CLKCMU_CPUCL1_DBG_USER, 4, 1),
+	MUX_F(CLK_MOUT_CPUCL1_PLL, "mout_cpucl1_pll", mout_cpucl1_pll_p,
+	      CLK_CON_MUX_MUX_CLK_CPUCL1_PLL, 0, 1, CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_div_clock cpucl1_div_clks[] __initconst = {
+	DIV_F(CLK_DOUT_CPUCL1_CPU, "dout_cpucl1_cpu", "mout_cpucl1_pll",
+	      CLK_CON_DIV_DIV_CLK_CPUCL1_CPU, 0, 1,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL1_CMUREF, "dout_cpucl1_cmuref", "dout_cpucl1_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL1_CMUREF, 0, 3,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL1_PCLK, "dout_cpucl1_pclk", "dout_cpucl1_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL1_PCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+
+	/* EMBEDDED_CMU_CPUCL1 */
+	DIV_F(CLK_DOUT_CLUSTER1_ACLK, "dout_cluster1_aclk", "gout_cluster1_cpu",
+	      CLK_CON_DIV_DIV_CLK_CLUSTER1_ACLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER1_ATCLK, "dout_cluster1_atclk",
+	      "gout_cluster1_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER1_ATCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER1_PCLKDBG, "dout_cluster1_pclkdbg",
+	      "gout_cluster1_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER1_PCLKDBG, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER1_PERIPHCLK, "dout_cluster1_periphclk",
+	      "gout_cluster1_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER1_PERIPHCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+};
+
+static const struct samsung_gate_clock cpucl1_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_CPUCL1_CMU_CPUCL1_PCLK, "gout_cpucl1_cmu_cpucl1_pclk",
+	     "dout_cpucl1_pclk",
+	     CLK_CON_GAT_CLK_CPUCL1_CMU_CPUCL1_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+
+	/* EMBEDDED_CMU_CPUCL1 */
+	GATE(CLK_GOUT_CLUSTER1_CPU, "gout_cluster1_cpu", "dout_cpucl1_cpu",
+	     CLK_CON_GAT_GATE_CLK_CPUCL1_CPU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_SCLK, "gout_cluster1_sclk", "gout_cluster1_cpu",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_SCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_ATCLK, "gout_cluster1_atclk",
+	     "dout_cluster1_atclk",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_ATCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_PERIPHCLK, "gout_cluster1_periphclk",
+	     "dout_cluster1_periphclk",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PERIPHCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_PCLK, "gout_cluster1_pclk",
+	     "dout_cluster1_pclkdbg",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cpu_clock cpucl1_cpu_clks[] __initconst = {
+	CPU_CLK(CLK_CLUSTER1_SCLK, "cluster1_clk", CLK_MOUT_PLL_CPUCL1,
+		CLK_MOUT_CPUCL1_SWITCH_USER, 0, 0x0, CPUCLK_LAYOUT_E850_CL1,
+		exynos850_cluster_clk_d),
+};
+
+static const struct samsung_cmu_info cpucl1_cmu_info __initconst = {
+	.pll_clks		= cpucl1_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cpucl1_pll_clks),
+	.mux_clks		= cpucl1_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cpucl1_mux_clks),
+	.div_clks		= cpucl1_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cpucl1_div_clks),
+	.gate_clks		= cpucl1_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cpucl1_gate_clks),
+	.cpu_clks		= cpucl1_cpu_clks,
+	.nr_cpu_clks		= ARRAY_SIZE(cpucl1_cpu_clks),
+	.nr_clk_ids		= CLKS_NR_CPUCL1,
+	.clk_regs		= cpucl1_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cpucl1_clk_regs),
+	.clk_name		= "dout_cpucl1_switch",
+	.manual_plls		= true,
+};
+
+static void __init exynos850_cmu_cpucl1_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &cpucl1_cmu_info);
+}
+
+/* Register CMU_CPUCL1 early, as CPU clocks should be available ASAP */
+CLK_OF_DECLARE(exynos850_cmu_cpucl1, "samsung,exynos850-cmu-cpucl1",
+	       exynos850_cmu_cpucl1_init);
+
 /* ---- CMU_G3D ------------------------------------------------------------- */
 
 /* Register Offset definitions for CMU_G3D (0x11400000) */
-- 
2.39.2



From ardb at kernel.org  Fri Feb 16 14:34:35 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 16 Feb 2024 23:34:35 +0100
Subject: [PATCH v8 00/43] arm64: Add support for LPA2 and WXN at stage 1
In-Reply-To: <CAMj1kXEupLLE+xZaGygAJ0pOG8dm9Ov_7efWfK4af5JPgfZZfg@mail.gmail.com>
References: <20240214122845.2033971-45-ardb+git@google.com>
 <170810439864.589251.1526990737780573683.b4-ty@arm.com> <CAMj1kXEupLLE+xZaGygAJ0pOG8dm9Ov_7efWfK4af5JPgfZZfg@mail.gmail.com>
Message-ID: <CAMj1kXF0iRuxxmaj9o6a1qi_+uB68=p4UFoGGaya-rCPyPTqkg@mail.gmail.com>

On Fri, 16 Feb 2024 at 19:23, Ard Biesheuvel <ardb at kernel.org> wrote:
>
> On Fri, 16 Feb 2024 at 18:35, Catalin Marinas <catalin.marinas at arm.com> wrote:
> >
> > On Wed, 14 Feb 2024 13:28:46 +0100, Ard Biesheuvel wrote:
> > > This v8 covers the remaining changes that implement support for LPA2 and
> > > WXN at stage 1, now that some of the prerequisites are in place.
> > >
> > > v4: https://lore.kernel.org/r/20230912141549.278777-63-ardb at google.com/
> > > v5: https://lore.kernel.org/r/20231124101840.944737-41-ardb at google.com/
> > > v6: https://lore.kernel.org/r/20231129111555.3594833-43-ardb at google.com/
> > > v7: https://lore.kernel.org/r/20240123145258.1462979-52-ardb%2Bgit%40google.com/
> > >
> > > [...]
> >
> > I queued this series via the arm64 tree (for-next/stage1-lpa2). I tried
> > a couple of releases ago but for some reason my tests started failing at
> > it was very close to the merging window, so dropped. This time around,
> > if anything goes wrong, we have a bit of time to fix (it might as well
> > have been my test scripts and nothing to do with these patches).
> >
> > The last patch introducing WXN has ABI implications but it's default
> > off. I think we should keep the patch as certain markets will likely
> > turn it on.
> >
> > Surprisingly, there are no conflicts with Ryan's contpte series AFAICT
> > (I did a merge locally).
> >
>
> No *lexical* conflicts, right? :-)
>
> I built for-next/core with 16k pages/52-bits, and ended up with the
> splat below. Unfortunately, it is intermittent, and I haven't been
> able to reproduce it, so I have no idea whether it is my code, Ryan's
> code or an inadvertent interaction between the two. (Or perhaps some
> other code in the tree)
>

It's my code: on 16k without LPA2, the PUDs are folded at runtime, so
set_pud() is writing to swapper_pg_dir, which is mapped read-only.
I'll have a fix out shortly.


From sre at kernel.org  Fri Feb 16 14:34:23 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:23 +0100
Subject: [PATCH v3 04/16] dt-bindings: soc: imx: fsl,imx-anatop: add binding
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-5-sre@kernel.org>

Add missing binding for i.MX anatop syscon.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/soc/imx/fsl,imx-anatop.yaml      | 128 ++++++++++++++++++
 1 file changed, 128 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
new file mode 100644
index 000000000000..5a59e3470510
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
@@ -0,0 +1,128 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/imx/fsl,imx-anatop.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ANATOP register
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - fsl,imx6sl-anatop
+              - fsl,imx6sll-anatop
+              - fsl,imx6sx-anatop
+              - fsl,imx6ul-anatop
+              - fsl,imx7d-anatop
+          - const: fsl,imx6q-anatop
+          - const: syscon
+          - const: simple-mfd
+      - items:
+          - const: fsl,imx6q-anatop
+          - const: syscon
+          - const: simple-mfd
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Temperature sensor event
+      - description: Brown-out event on either of the support regulators
+      - description: Brown-out event on either the core, gpu or soc regulators
+
+  tempmon:
+    type: object
+    unevaluatedProperties: false
+    $ref: /schemas/thermal/imx-thermal.yaml
+
+patternProperties:
+  "regulator-((3p0)|(vddcore)|(vddsoc))$":
+    type: object
+    unevaluatedProperties: false
+    $ref: /schemas/regulator/anatop-regulator.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx6ul-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    anatop: anatop at 20c8000 {
+        compatible = "fsl,imx6ul-anatop", "fsl,imx6q-anatop",
+                     "syscon", "simple-mfd";
+        reg = <0x020c8000 0x1000>;
+        interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+
+        reg_3p0: regulator-3p0 {
+            compatible = "fsl,anatop-regulator";
+            regulator-name = "vdd3p0";
+            regulator-min-microvolt = <2625000>;
+            regulator-max-microvolt = <3400000>;
+            anatop-reg-offset = <0x120>;
+            anatop-vol-bit-shift = <8>;
+            anatop-vol-bit-width = <5>;
+            anatop-min-bit-val = <0>;
+            anatop-min-voltage = <2625000>;
+            anatop-max-voltage = <3400000>;
+            anatop-enable-bit = <0>;
+        };
+
+        reg_arm: regulator-vddcore {
+            compatible = "fsl,anatop-regulator";
+            regulator-name = "cpu";
+            regulator-min-microvolt = <725000>;
+            regulator-max-microvolt = <1450000>;
+            regulator-always-on;
+            anatop-reg-offset = <0x140>;
+            anatop-vol-bit-shift = <0>;
+            anatop-vol-bit-width = <5>;
+            anatop-delay-reg-offset = <0x170>;
+            anatop-delay-bit-shift = <24>;
+            anatop-delay-bit-width = <2>;
+            anatop-min-bit-val = <1>;
+            anatop-min-voltage = <725000>;
+            anatop-max-voltage = <1450000>;
+        };
+
+        reg_soc: regulator-vddsoc {
+            compatible = "fsl,anatop-regulator";
+            regulator-name = "vddsoc";
+            regulator-min-microvolt = <725000>;
+            regulator-max-microvolt = <1450000>;
+            regulator-always-on;
+            anatop-reg-offset = <0x140>;
+            anatop-vol-bit-shift = <18>;
+            anatop-vol-bit-width = <5>;
+            anatop-delay-reg-offset = <0x170>;
+            anatop-delay-bit-shift = <28>;
+            anatop-delay-bit-width = <2>;
+            anatop-min-bit-val = <1>;
+            anatop-min-voltage = <725000>;
+            anatop-max-voltage = <1450000>;
+        };
+
+        tempmon: tempmon {
+            compatible = "fsl,imx6ul-tempmon", "fsl,imx6sx-tempmon";
+            interrupt-parent = <&gpc>;
+            interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+            fsl,tempmon = <&anatop>;
+            nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
+            nvmem-cell-names = "calib", "temp_grade";
+            clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+            #thermal-sensor-cells = <0>;
+        };
+    };
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:27 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:27 +0100
Subject: [PATCH v3 08/16] ARM: dts: imx6ull: fix pinctrl node name
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-9-sre@kernel.org>

pinctrl node name must be either pinctrl or pinmux.

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ull.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
index 2bccd45e9fc2..8a1776067ecc 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
@@ -75,7 +75,7 @@ rngb: rng at 2284000 {
 				clocks = <&clks IMX6UL_CLK_DUMMY>;
 			};
 
-			iomuxc_snvs: iomuxc-snvs at 2290000 {
+			iomuxc_snvs: pinctrl at 2290000 {
 				compatible = "fsl,imx6ull-iomuxc-snvs";
 				reg = <0x02290000 0x4000>;
 			};
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:24 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:24 +0100
Subject: [PATCH v3 05/16] dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add imx6
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-6-sre@kernel.org>

Add compatibles used by different i.MX6 variants to the i.MX IOMUX
Controller GPR binding.

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml   | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
index 1da1b758b4ae..8451cb4dd87c 100644
--- a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
@@ -17,7 +17,23 @@ properties:
   compatible:
     oneOf:
       - items:
-          - const: fsl,imx8mq-iomuxc-gpr
+          - enum:
+              - fsl,imx6q-iomuxc-gpr
+              - fsl,imx8mq-iomuxc-gpr
+          - const: syscon
+          - const: simple-mfd
+      - items:
+          - enum:
+              - fsl,imx6sl-iomuxc-gpr
+              - fsl,imx6sll-iomuxc-gpr
+              - fsl,imx6ul-iomuxc-gpr
+          - const: fsl,imx6q-iomuxc-gpr
+          - const: syscon
+      - items:
+          - enum:
+              - fsl,imx6sx-iomuxc-gpr
+              - fsl,imx7d-iomuxc-gpr
+          - const: fsl,imx6q-iomuxc-gpr
           - const: syscon
           - const: simple-mfd
       - items:
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:22 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:22 +0100
Subject: [PATCH v3 03/16] dt-bindings: input: touchscreen: fsl,imx6ul-tsc convert to YAML
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-4-sre@kernel.org>

Convert the i.MX6UL touchscreen DT binding to YAML.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../input/touchscreen/fsl,imx6ul-tsc.yaml     | 97 +++++++++++++++++++
 .../bindings/input/touchscreen/imx6ul_tsc.txt | 38 --------
 2 files changed, 97 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
 delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml b/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
new file mode 100644
index 000000000000..678756ad0f92
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/fsl,imx6ul-tsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX6UL Touch Controller
+
+maintainers:
+  - Haibo Chen <haibo.chen at nxp.com>
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+properties:
+  compatible:
+    const: fsl,imx6ul-tsc
+
+  reg:
+    items:
+      - description: touch controller address
+      - description: ADC2 address
+
+  interrupts:
+    items:
+      - description: touch controller address
+      - description: ADC2 address
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: tsc
+      - const: adc
+
+  xnur-gpios:
+    maxItems: 1
+    description:
+      The X- gpio this controller connect to. This xnur-gpio returns to
+      low once the finger leave the touch screen (The last touch event
+      the touch controller capture).
+
+  measure-delay-time:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      The value of measure delay time. Before X-axis or Y-axis measurement,
+      the screen need some time before even potential distribution ready.
+    default: 0xffff
+    minimum: 0
+    maximum: 0xffffff
+
+  pre-charge-time:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      The touch screen need some time to precharge.
+    default: 0xfff
+    minimum: 0
+    maximum: 0xffffffff
+
+  touchscreen-average-samples:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: Number of data samples which are averaged for each read.
+    enum: [ 1, 4, 8, 16, 32 ]
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - xnur-gpios
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/imx6ul-clock.h>
+    #include <dt-bindings/gpio/gpio.h>
+    touchscreen at 2040000 {
+        compatible = "fsl,imx6ul-tsc";
+        reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
+        interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX6UL_CLK_IPG>,
+                 <&clks IMX6UL_CLK_ADC2>;
+        clock-names = "tsc", "adc";
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_tsc>;
+        xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+        measure-delay-time = <0xfff>;
+        pre-charge-time = <0xffff>;
+        touchscreen-average-samples = <32>;
+    };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
deleted file mode 100644
index 164915004424..000000000000
--- a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-* Freescale i.MX6UL Touch Controller
-
-Required properties:
-- compatible: must be "fsl,imx6ul-tsc".
-- reg: this touch controller address and the ADC2 address.
-- interrupts: the interrupt of this touch controller and ADC2.
-- clocks: the root clock of touch controller and ADC2.
-- clock-names; must be "tsc" and "adc".
-- xnur-gpio: the X- gpio this controller connect to.
-  This xnur-gpio returns to low once the finger leave the touch screen (The
-  last touch event the touch controller capture).
-
-Optional properties:
-- measure-delay-time: the value of measure delay time.
-  Before X-axis or Y-axis measurement, the screen need some time before
-  even potential distribution ready.
-  This value depends on the touch screen.
-- pre-charge-time: the touch screen need some time to precharge.
-  This value depends on the touch screen.
-- touchscreen-average-samples: Number of data samples which are averaged for
-  each read. Valid values are 1, 4, 8, 16 and 32.
-
-Example:
-	tsc: tsc at 2040000 {
-		compatible = "fsl,imx6ul-tsc";
-		reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
-		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clks IMX6UL_CLK_IPG>,
-			 <&clks IMX6UL_CLK_ADC2>;
-		clock-names = "tsc", "adc";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_tsc>;
-		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
-		measure-delay-time = <0xfff>;
-		pre-charge-time = <0xffff>;
-		touchscreen-average-samples = <32>;
-	};
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:19 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:19 +0100
Subject: [PATCH v3 00/16] UNI-T UTi260B support
Message-ID: <20240216223654.1312880-1-sre@kernel.org>

From: Sebastian Reichel <sebastian.reichel at collabora.com>

Hi,

This adds adds support for the UNI-T UTi260B thermal camera, which is based
on i.MX6ULL. Patches 1-14 clean up all warnings reported by CHECK_DTBS for
i.MX6ULL (i.e. for an empty board). They are not specific to the UTi260B and
in fact that machine has most of the IP handled by these patches marked as
disabled. Then patches 15+16 introduce the vendor and board compatible DT
bindings. Finally the last patches adds support for the thermal camera itself.

The DT is based on reverse engineered information. More information about
the device can be found in this presentation from Embedded Recipes 2023:

 * https://embedded-recipes.org/2023/wp-content/uploads/2023/10/Running-FOSS-on-a-Thermal-Camera-Sebastian-Reichel-compressed.pdf
 * https://www.youtube.com/watch?v=uvObsCG-Cqo

I also prepared a branch with these patches (and a minimal kernel config)
and published it here:

https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/log/?h=uti260b-v3

Changes since PATCHv2:
 * https://lore.kernel.org/all/20240213010347.1075251-1-sre at kernel.org/
  - drop fsl,imx-asrc YAML binding conversion (merged)
  - collect a bunch of Reviewed-by/Acked-by tags
  - weim DT binding: fix issue with requirements
  - xnur-gpio -> xnur-gpios change: Improve patch long description

Changes since PATCHv1:
 * https://lore.kernel.org/all/20240210012114.489102-1-sre at kernel.org/
  - uni-t,imx6ull-uti260b -> uni-t,uti260b
  - add Acked-by for uni-t vendor prefix
  - add Acked-by for HDMI audio index fix
  - add Acked-by for LCDIF power-domain requirement drop
  - anatop DT binding: Fixed indentation in example
  - anatop DT binding: Described IRQs
  - touchscreen DT binding: change tsc@ to touchscreen@ in example
  - touchscreen DT binding: change xnur-gpio to xnur-gpios
  - weim DT binding: drop acme,whatever example
  - weim DT binding: use flash@ instead of nor@
  - weim DT binding: update weim.txt reference in arcx,anybus-controller.txt
  - weim DT binding: switch to memory-controller binding
  - fsl,imx-asrc DT binding: fix ASoC patch subject prefix
  - fsl,imx-asrc DT binding: add constraints
  - add new patch fixing xnur-gpio(s) in all i.MX6UL board DT files
  - add new patch fixing touchscreen nodename in i.MX6UL SoC DT file
  - add new patch fixing weim nodename in all i.MX SoC DT files
  - device DTS: use color/functions for the led
  - device DTS: increase SPI speed
  - device DTS: add comment for SD / eMMC node

Unadressed feedback from PATCHv1:
  - anatop phandle vs parent: technically it makes sense to just use the
    parent, but this driver is only used by i.MX6. The current code makes
	use of the phandle, so we cannot drop it because of backwards
	compatibility. So I don't see a point in deprecating this property.
  - touchscreen binding: I kept measure-delay-time and pre-charge-time
    values in hex, since that is being used everywhere and the unit
	is unknown. The values are directly written into HW registers and
	the i.MX6UL TRM does not provide any hints about the unit. I do not
	have an i.MX6UL device with a touchsreen, so I cannot test either.
  - regulator name in DT: I did not rename the regulators to just
    "regulator", since the nodename must be unique.

Greetings,

-- Sebastian

Sebastian Reichel (16):
  dt-bindings: pinctrl: fsl,imx6ul-pinctrl: convert to YAML
  dt-bindings: bus: imx-weim: convert to YAML
  dt-bindings: input: touchscreen: fsl,imx6ul-tsc convert to YAML
  dt-bindings: soc: imx: fsl,imx-anatop: add binding
  dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add imx6
  dt-bindings: lcdif: Do not require power-domains for i.MX6ULL
  dt-bindings: fsl-imx-sdma: fix HDMI audio index
  ARM: dts: imx6ull: fix pinctrl node name
  ARM: dts: imx6ul: Remove fsl,anatop from usbotg1
  ARM: dts: imx6ul: add missing #thermal-sensor-cells
  ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
  ARM: dts: nxp: imx6ul: fix touchscreen node name
  ARM: dts: nxp: imx: fix weim node name
  dt-bindings: vendor-prefixes: add UNI-T
  dt-bindings: arm: add UNI-T UTi260B
  ARM: dts: imx6ull-uti260b: Add board

 .../devicetree/bindings/arm/fsl.yaml          |   1 +
 .../devicetree/bindings/bus/imx-weim.txt      | 117 ----
 .../bindings/display/fsl,lcdif.yaml           |   8 +-
 .../devicetree/bindings/dma/fsl,imx-sdma.yaml |   3 +-
 .../input/touchscreen/fsl,imx6ul-tsc.yaml     |  97 +++
 .../bindings/input/touchscreen/imx6ul_tsc.txt |  38 --
 .../fsl/fsl,imx-weim-peripherals.yaml         |  31 +
 .../memory-controllers/fsl/fsl,imx-weim.yaml  | 203 +++++++
 .../mc-peripheral-props.yaml                  |   1 +
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt   |  37 --
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.yaml  | 116 ++++
 .../bindings/soc/imx/fsl,imx-anatop.yaml      | 128 ++++
 .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml  |  18 +-
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm/boot/dts/nxp/imx/Makefile            |   1 +
 arch/arm/boot/dts/nxp/imx/imx1.dtsi           |   2 +-
 arch/arm/boot/dts/nxp/imx/imx27.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx31.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx35.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx51.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi        |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6sl.dtsi         |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6sx.dtsi         |   2 +-
 .../boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi    |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts     |   2 +-
 .../nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi    |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi         |   6 +-
 .../boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi   |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts | 572 ++++++++++++++++++
 arch/arm/boot/dts/nxp/imx/imx6ull.dtsi        |   2 +-
 .../fieldbus/arcx,anybus-controller.txt       |   2 +-
 31 files changed, 1195 insertions(+), 212 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
 delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts

-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:20 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:20 +0100
Subject: [PATCH v3 01/16] dt-bindings: pinctrl: fsl,imx6ul-pinctrl: convert to YAML
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-2-sre@kernel.org>

Convert i.MX6UL pinctrl bindings to YAML.

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt   |  37 ------
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.yaml  | 116 ++++++++++++++++++
 2 files changed, 116 insertions(+), 37 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
deleted file mode 100644
index 7ca4f6118d9a..000000000000
--- a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-* Freescale i.MX6 UltraLite IOMUX Controller
-
-Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
-and usage.
-
-Required properties:
-- compatible: "fsl,imx6ul-iomuxc" for main IOMUX controller or
-  "fsl,imx6ull-iomuxc-snvs" for i.MX 6ULL's SNVS IOMUX controller.
-- fsl,pins: each entry consists of 6 integers and represents the mux and config
-  setting for one pin.  The first 5 integers <mux_reg conf_reg input_reg mux_val
-  input_val> are specified using a PIN_FUNC_ID macro, which can be found in
-  imx6ul-pinfunc.h under device tree source folder.  The last integer CONFIG is
-  the pad setting value like pull-up on this pin.  Please refer to i.MX6 UltraLite
-  Reference Manual for detailed CONFIG settings.
-
-CONFIG bits definition:
-PAD_CTL_HYS                     (1 << 16)
-PAD_CTL_PUS_100K_DOWN           (0 << 14)
-PAD_CTL_PUS_47K_UP              (1 << 14)
-PAD_CTL_PUS_100K_UP             (2 << 14)
-PAD_CTL_PUS_22K_UP              (3 << 14)
-PAD_CTL_PUE                     (1 << 13)
-PAD_CTL_PKE                     (1 << 12)
-PAD_CTL_ODE                     (1 << 11)
-PAD_CTL_SPEED_LOW               (0 << 6)
-PAD_CTL_SPEED_MED               (1 << 6)
-PAD_CTL_SPEED_HIGH              (3 << 6)
-PAD_CTL_DSE_DISABLE             (0 << 3)
-PAD_CTL_DSE_260ohm              (1 << 3)
-PAD_CTL_DSE_130ohm              (2 << 3)
-PAD_CTL_DSE_87ohm               (3 << 3)
-PAD_CTL_DSE_65ohm               (4 << 3)
-PAD_CTL_DSE_52ohm               (5 << 3)
-PAD_CTL_DSE_43ohm               (6 << 3)
-PAD_CTL_DSE_37ohm               (7 << 3)
-PAD_CTL_SRE_FAST                (1 << 0)
-PAD_CTL_SRE_SLOW                (0 << 0)
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
new file mode 100644
index 000000000000..906b264a9e3c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
@@ -0,0 +1,116 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/fsl,imx6ul-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale IMX6UL IOMUX Controller
+
+maintainers:
+  - Dong Aisheng <aisheng.dong at nxp.com>
+
+description:
+  Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
+  for common binding part and usage.
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx6ul-iomuxc
+      - fsl,imx6ull-iomuxc-snvs
+
+  reg:
+    maxItems: 1
+
+# Client device subnode's properties
+patternProperties:
+  'grp$':
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+
+    properties:
+      fsl,pins:
+        description:
+          each entry consists of 6 integers and represents the mux and config
+          setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
+          mux_val input_val> are specified using a PIN_FUNC_ID macro, which can
+          be found in <arch/arm/boot/dts/imx6ul-pinfunc.h>. The last integer
+          CONFIG is the pad setting value like pull-up on this pin. Please
+          refer to i.MX6UL Reference Manual for detailed CONFIG settings.
+        $ref: /schemas/types.yaml#/definitions/uint32-matrix
+        items:
+          items:
+            - description: |
+                "mux_reg" indicates the offset of mux register.
+            - description: |
+                "conf_reg" indicates the offset of pad configuration register.
+            - description: |
+                "input_reg" indicates the offset of select input register.
+            - description: |
+                "mux_val" indicates the mux value to be applied.
+            - description: |
+                "input_val" indicates the select input value to be applied.
+            - description: |
+                "pad_setting" indicates the pad configuration value to be applied:
+                  PAD_CTL_HYS                     (1 << 16)
+                  PAD_CTL_PUS_100K_DOWN           (0 << 14)
+                  PAD_CTL_PUS_47K_UP              (1 << 14)
+                  PAD_CTL_PUS_100K_UP             (2 << 14)
+                  PAD_CTL_PUS_22K_UP              (3 << 14)
+                  PAD_CTL_PUE                     (1 << 13)
+                  PAD_CTL_PKE                     (1 << 12)
+                  PAD_CTL_ODE                     (1 << 11)
+                  PAD_CTL_SPEED_LOW               (0 << 6)
+                  PAD_CTL_SPEED_MED               (1 << 6)
+                  PAD_CTL_SPEED_HIGH              (3 << 6)
+                  PAD_CTL_DSE_DISABLE             (0 << 3)
+                  PAD_CTL_DSE_260ohm              (1 << 3)
+                  PAD_CTL_DSE_130ohm              (2 << 3)
+                  PAD_CTL_DSE_87ohm               (3 << 3)
+                  PAD_CTL_DSE_65ohm               (4 << 3)
+                  PAD_CTL_DSE_52ohm               (5 << 3)
+                  PAD_CTL_DSE_43ohm               (6 << 3)
+                  PAD_CTL_DSE_37ohm               (7 << 3)
+                  PAD_CTL_SRE_FAST                (1 << 0)
+                  PAD_CTL_SRE_SLOW                (0 << 0)
+
+    required:
+      - fsl,pins
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    iomuxc: pinctrl at 20e0000 {
+      compatible = "fsl,imx6ul-iomuxc";
+      reg = <0x020e0000 0x4000>;
+
+      mux_uart: uartgrp {
+        fsl,pins = <
+          0x0084 0x0310 0x0000 0 0 0x1b0b1
+          0x0088 0x0314 0x0624 0 3 0x1b0b1
+        >;
+      };
+    };
+  - |
+    iomuxc_snvs: pinctrl at 2290000 {
+      compatible = "fsl,imx6ull-iomuxc-snvs";
+      reg = <0x02290000 0x4000>;
+
+      pinctrl_snvs_usbc_det: snvsusbcdetgrp {
+        fsl,pins = <
+          0x0010 0x0054 0x0000 0x5 0x0 0x130b0
+        >;
+      };
+    };
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:30 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:30 +0100
Subject: [PATCH v3 11/16] ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-12-sre@kernel.org>

Replace all "xnur-gpio" with "xnur-gpios" in the i.MX6UL(L) Touchscreen
node, since the -gpio suffix is deprecated. All known implementations of
this binding can handle -gpio and -gpios since day 1, so this should be
fully backwards compatible.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi          | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts                | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi         | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
index 2ac40d69425b..f10f0525490b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
@@ -321,7 +321,7 @@ &snvs_pwrkey {
 &tsc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_tsc>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 	measure-delay-time = <0xffff>;
 	pre-charge-time = <0xfff>;
 	status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts b/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
index 875ae699c5cb..2ca18f3dad0a 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
@@ -203,7 +203,7 @@ &pwm8 {
 &tsc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_tsc>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 };
 
 &sai2 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
index 18cac19aa9b0..af337f18a266 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
@@ -156,7 +156,7 @@ &snvs_pwrkey {
 &tsc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_tsc>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 	measure-delay-time = <0xffff>;
 	pre-charge-time = <0xffff>;
 	status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
index 830b5a5064f2..6d2163250b5d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
@@ -273,7 +273,7 @@ &tsc {
 	pinctrl-names = "default";
 	pre-charge-time = <0xfff>;
 	touchscreen-average-samples = <32>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 };
 
 /* DHCOM UART1 */
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:25 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:25 +0100
Subject: [PATCH v3 06/16] dt-bindings: lcdif: Do not require power-domains for i.MX6ULL
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-7-sre@kernel.org>

i.MX6UL(L) uses "fsl,imx6sx-lcdif" as fallback compatible string,
but has only very lightweight DISPLAY power domain. Its DISPLAY
power domain is not supported by the binding / Linux kernel at
the moment. Since the current setup is working, let's remove the
power-domain from being required for that platform to fix the warning
printed by CHECK_DTBS=y.

Fixes: f62678a77d58 ("dt-bindings: mxsfb: Document i.MX8M/i.MX6SX/i.MX6SL power-domains property")
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/display/fsl,lcdif.yaml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
index 1c2be8d6f633..0681fc49aa1b 100644
--- a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
+++ b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
@@ -120,13 +120,19 @@ allOf:
           maxItems: 1
         clock-names:
           maxItems: 1
+  - if:
+      properties:
+        compatible:
+          const: fsl,imx6sx-lcdif
+    then:
+      required:
+        - power-domains
   - if:
       properties:
         compatible:
           contains:
             enum:
               - fsl,imx6sl-lcdif
-              - fsl,imx6sx-lcdif
               - fsl,imx8mm-lcdif
               - fsl,imx8mn-lcdif
               - fsl,imx8mp-lcdif
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:28 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:28 +0100
Subject: [PATCH v3 09/16] ARM: dts: imx6ul: Remove fsl,anatop from usbotg1
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-10-sre@kernel.org>

fsl,anatop should only be added to the usbphy nodes.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index a27a7554c2e7..9eb4eee0c272 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -855,7 +855,6 @@ usbotg1: usb at 2184000 {
 				clocks = <&clks IMX6UL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
-				fsl,anatop = <&anatop>;
 				ahb-burst-config = <0x0>;
 				tx-burst-size-dword = <0x10>;
 				rx-burst-size-dword = <0x10>;
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:21 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:21 +0100
Subject: [PATCH v3 02/16] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-3-sre@kernel.org>

Convert the i.MX  Wireless External Interface Module binding to YAML.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../devicetree/bindings/bus/imx-weim.txt      | 117 ----------
 .../fsl/fsl,imx-weim-peripherals.yaml         |  31 +++
 .../memory-controllers/fsl/fsl,imx-weim.yaml  | 203 ++++++++++++++++++
 .../mc-peripheral-props.yaml                  |   1 +
 .../fieldbus/arcx,anybus-controller.txt       |   2 +-
 5 files changed, 236 insertions(+), 118 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml

diff --git a/Documentation/devicetree/bindings/bus/imx-weim.txt b/Documentation/devicetree/bindings/bus/imx-weim.txt
deleted file mode 100644
index e7f502070d77..000000000000
--- a/Documentation/devicetree/bindings/bus/imx-weim.txt
+++ /dev/null
@@ -1,117 +0,0 @@
-Device tree bindings for i.MX Wireless External Interface Module (WEIM)
-
-The term "wireless" does not imply that the WEIM is literally an interface
-without wires. It simply means that this module was originally designed for
-wireless and mobile applications that use low-power technology.
-
-The actual devices are instantiated from the child nodes of a WEIM node.
-
-Required properties:
-
- - compatible:		Should contain one of the following:
-			  "fsl,imx1-weim"
-			  "fsl,imx27-weim"
-			  "fsl,imx51-weim"
-			  "fsl,imx50-weim"
-			  "fsl,imx6q-weim"
- - reg:			A resource specifier for the register space
-			(see the example below)
- - clocks:		the clock, see the example below.
- - #address-cells:	Must be set to 2 to allow memory address translation
- - #size-cells:		Must be set to 1 to allow CS address passing
- - ranges:		Must be set up to reflect the memory layout with four
-			integer values for each chip-select line in use:
-
-			   <cs-number> 0 <physical address of mapping> <size>
-
-Optional properties:
-
- - fsl,weim-cs-gpr:	For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
-			devices, it should be the phandle to the system General
-			Purpose Register controller that contains WEIM CS GPR
-			register, e.g. IOMUXC_GPR1 on i.MX6Q.  IOMUXC_GPR1[11:0]
-			should be set up as one of the following 4 possible
-			values depending on the CS space configuration.
-
-			IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
-			---------------------------------------------
-				05	    128M     0M     0M     0M
-				033          64M    64M     0M     0M
-				0113         64M    32M    32M     0M
-				01111        32M    32M    32M    32M
-
-			In case that the property is absent, the reset value or
-			what bootloader sets up in IOMUXC_GPR1[11:0] will be
-			used.
-
- - fsl,burst-clk-enable	For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
-			devices, the presence of this property indicates that
-			the weim bus should operate in Burst Clock Mode.
-
- - fsl,continuous-burst-clk	Make Burst Clock to output continuous clock.
-			Without this option Burst Clock will output clock
-			only when necessary. This takes effect only if
-			"fsl,burst-clk-enable" is set.
-
-Timing property for child nodes. It is mandatory, not optional.
-
- - fsl,weim-cs-timing:	The timing array, contains timing values for the
-			child node. We get the CS indexes from the address
-			ranges in the child node's "reg" property.
-			The number of registers depends on the selected chip:
-			For i.MX1, i.MX21 ("fsl,imx1-weim") there are two
-			registers: CSxU, CSxL.
-			For i.MX25, i.MX27, i.MX31 and i.MX35 ("fsl,imx27-weim")
-			there are three registers: CSCRxU, CSCRxL, CSCRxA.
-			For i.MX50, i.MX53 ("fsl,imx50-weim"),
-			i.MX51 ("fsl,imx51-weim") and i.MX6Q ("fsl,imx6q-weim")
-			there are six registers: CSxGCR1, CSxGCR2, CSxRCR1,
-			CSxRCR2, CSxWCR1, CSxWCR2.
-
-Example for an imx6q-sabreauto board, the NOR flash connected to the WEIM:
-
-	weim: weim at 21b8000 {
-		compatible = "fsl,imx6q-weim";
-		reg = <0x021b8000 0x4000>;
-		clocks = <&clks 196>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x08000000>;
-		fsl,weim-cs-gpr = <&gpr>;
-
-		nor at 0,0 {
-			compatible = "cfi-flash";
-			reg = <0 0 0x02000000>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			bank-width = <2>;
-			fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
-					0x0000c000 0x1404a38e 0x00000000>;
-		};
-	};
-
-Example for an imx6q-based board, a multi-chipselect device connected to WEIM:
-
-In this case, both chip select 0 and 1 will be configured with the same timing
-array values.
-
-	weim: weim at 21b8000 {
-		compatible = "fsl,imx6q-weim";
-		reg = <0x021b8000 0x4000>;
-		clocks = <&clks 196>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x02000000
-			  1 0 0x0a000000 0x02000000
-			  2 0 0x0c000000 0x02000000
-			  3 0 0x0e000000 0x02000000>;
-		fsl,weim-cs-gpr = <&gpr>;
-
-		acme at 0 {
-			compatible = "acme,whatever";
-			reg = <0 0 0x100>, <0 0x400000 0x800>,
-				<1 0x400000 0x800>;
-			fsl,weim-cs-timing = <0x024400b1 0x00001010 0x20081100
-				0x00000000 0xa0000240 0x00000000>;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
new file mode 100644
index 000000000000..82fc5f4a1ed6
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX WEIM Bus Peripheral Nodes
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+description:
+  This binding is meant for the child nodes of the WEIM node. The node
+  represents any device connected to the WEIM bus. It may be a Flash chip,
+  RAM chip or Ethernet controller, etc. These properties are meant for
+  configuring the WEIM settings/timings and will accompany the bindings
+  supported by the respective device.
+
+properties:
+  reg: true
+
+  fsl,weim-cs-timing:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Timing values for the child node.
+    minItems: 2
+    maxItems: 6
+
+# the WEIM child will have its own native properties
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
new file mode 100644
index 000000000000..2db59f3b1eb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
@@ -0,0 +1,203 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,imx-weim.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX Wireless External Interface Module (WEIM)
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+description:
+  The term "wireless" does not imply that the WEIM is literally an interface
+  without wires. It simply means that this module was originally designed for
+  wireless and mobile applications that use low-power technology. The actual
+  devices are instantiated from the child nodes of a WEIM node.
+
+properties:
+  $nodename:
+    pattern: "^memory-controller@[0-9a-f]+$"
+
+  compatible:
+    oneOf:
+      - enum:
+          - fsl,imx1-weim
+          - fsl,imx27-weim
+          - fsl,imx50-weim
+          - fsl,imx51-weim
+          - fsl,imx6q-weim
+      - items:
+          - enum:
+              - fsl,imx31-weim
+              - fsl,imx35-weim
+          - const: fsl,imx27-weim
+      - items:
+          - enum:
+              - fsl,imx6sx-weim
+              - fsl,imx6ul-weim
+          - const: fsl,imx6q-weim
+
+  '#address-cells':
+    const: 2
+
+  '#size-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  ranges: true
+
+  fsl,weim-cs-gpr:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Phandle to the system General Purpose Register controller that contains
+      WEIM CS GPR register, e.g. IOMUXC_GPR1 on i.MX6Q. IOMUXC_GPR1[11:0]
+      should be set up as one of the following 4 possible values depending on
+      the CS space configuration.
+
+      IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
+      ---------------------------------------------
+              05          128M     0M     0M     0M
+              033          64M    64M     0M     0M
+              0113         64M    32M    32M     0M
+              01111        32M    32M    32M    32M
+
+      In case that the property is absent, the reset value or what bootloader
+      sets up in IOMUXC_GPR1[11:0] will be used.
+
+  fsl,burst-clk-enable:
+    type: boolean
+    description:
+      The presence of this property indicates that the weim bus should operate
+      in Burst Clock Mode.
+
+  fsl,continuous-burst-clk:
+    type: boolean
+    description:
+      Make Burst Clock to output continuous clock. Without this option Burst
+      Clock will output clock only when necessary.
+
+patternProperties:
+  "^.*@[0-7],[0-9a-f]+$":
+    type: object
+    description: Devices attached to chip selects are represented as subnodes.
+    $ref: fsl,imx-weim-peripherals.yaml
+    additionalProperties: true
+    required:
+      - fsl,weim-cs-timing
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#address-cells'
+  - '#size-cells'
+  - ranges
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          not:
+            contains:
+              enum:
+                - fsl,imx50-weim
+                - fsl,imx6q-weim
+    then:
+      properties:
+        fsl,weim-cs-gpr: false
+        fsl,burst-clk-enable: false
+  - if:
+      properties:
+        fsl,burst-clk-enable: false
+    then:
+      properties:
+        fsl,continuous-burst-clk: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx1-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSxU
+                  - description: CSxL
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx27-weim
+              - fsl,imx31-weim
+              - fsl,imx35-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSCRxU
+                  - description: CSCRxL
+                  - description: CSCRxA
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx50-weim
+              - fsl,imx51-weim
+              - fsl,imx6q-weim
+              - fsl,imx6sx-weim
+              - fsl,imx6ul-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSxGCR1
+                  - description: CSxGCR2
+                  - description: CSxRCR1
+                  - description: CSxRCR2
+                  - description: CSxWCR1
+                  - description: CSxWCR2
+
+additionalProperties: false
+
+examples:
+  - |
+    memory-controller at 21b8000 {
+        compatible = "fsl,imx6q-weim";
+        reg = <0x021b8000 0x4000>;
+        clocks = <&clks 196>;
+        #address-cells = <2>;
+        #size-cells = <1>;
+        ranges = <0 0 0x08000000 0x08000000>;
+        fsl,weim-cs-gpr = <&gpr>;
+
+        flash at 0,0 {
+            compatible = "cfi-flash";
+            reg = <0 0 0x02000000>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            bank-width = <2>;
+            fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
+                                  0x0000c000 0x1404a38e 0x00000000>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml b/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml
index 8d9dae15ade0..00deeb09f87d 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml
@@ -37,5 +37,6 @@ allOf:
   - $ref: ingenic,nemc-peripherals.yaml#
   - $ref: intel,ixp4xx-expansion-peripheral-props.yaml#
   - $ref: ti,gpmc-child.yaml#
+  - $ref: fsl/fsl,imx-weim-peripherals.yaml
 
 additionalProperties: true
diff --git a/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt b/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt
index b1f9474f36d5..f34a95611645 100644
--- a/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt
+++ b/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt
@@ -48,7 +48,7 @@ Example of usage:
 -----------------
 
 This example places the bridge on top of the i.MX WEIM parallel bus, see:
-Documentation/devicetree/bindings/bus/imx-weim.txt
+Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
 
 &weim {
 	controller at 0,0 {
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:33 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:33 +0100
Subject: [PATCH v3 14/16] dt-bindings: vendor-prefixes: add UNI-T
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-15-sre@kernel.org>

Uni-Trend Technology is a manufacturer of measurement
and testing tools.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre 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 1a0dc04f1db4..e945e76696c2 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1484,6 +1484,8 @@ patternProperties:
     description: Ufi Space Co., Ltd.
   "^ugoos,.*":
     description: Ugoos Industrial Co., Ltd.
+  "^uni-t,.*":
+    description: Uni-Trend Technology (China) Co., Ltd.
   "^uniwest,.*":
     description: United Western Technologies Corp (UniWest)
   "^upisemi,.*":
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:29 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:29 +0100
Subject: [PATCH v3 10/16] ARM: dts: imx6ul: add missing #thermal-sensor-cells
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-11-sre@kernel.org>

Fix the following warning found via CHECK_DTBS:

tempmon: '#thermal-sensor-cells' is a required property

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index 9eb4eee0c272..45b7605ac381 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -638,6 +638,7 @@ tempmon: tempmon {
 					nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
 					nvmem-cell-names = "calib", "temp_grade";
 					clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+					#thermal-sensor-cells = <0>;
 				};
 			};
 
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:26 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:26 +0100
Subject: [PATCH v3 07/16] dt-bindings: fsl-imx-sdma: fix HDMI audio index
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-8-sre@kernel.org>

HDMI Audio has been added to the DT binding documentation with an
incorrect index. DT and the driver use index 26. This happened,
because the binding is missing MULTI_SAI type, which is using
index 25.

Reported-by: Michael Yackavage <michaely at ips-yes.com>
Fixes: 7bdbd87d4008 ("dt-bindings: fsl-imx-sdma: Convert imx sdma to DT schema")
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml b/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
index b95dd8db5a30..37135fa024f9 100644
--- a/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
+++ b/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
@@ -92,7 +92,8 @@ properties:
               description: needs firmware more than ver 2
           - Shared ASRC: 23
           - SAI: 24
-          - HDMI Audio: 25
+          - Multi SAI: 25
+          - HDMI Audio: 26
 
        The third cell: transfer priority ID
          enum:
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:32 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:32 +0100
Subject: [PATCH v3 13/16] ARM: dts: nxp: imx: fix weim node name
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-14-sre@kernel.org>

DT node names should be generic, so replace "weim" node name with
"memory-controller" in all i.MX SoC DT files.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx1.dtsi    | 2 +-
 arch/arm/boot/dts/nxp/imx/imx27.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx31.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx35.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx51.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6sl.dtsi  | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6sx.dtsi  | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi  | 2 +-
 9 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx1.dtsi b/arch/arm/boot/dts/nxp/imx/imx1.dtsi
index 1ac10965fdfd..389ecb1ebf8f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx1.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx1.dtsi
@@ -251,7 +251,7 @@ gpio4: gpio at 21c300 {
 			};
 		};
 
-		weim: weim at 220000 {
+		weim: memory-controller at 220000 {
 			#address-cells = <2>;
 			#size-cells = <1>;
 			compatible = "fsl,imx1-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx27.dtsi b/arch/arm/boot/dts/nxp/imx/imx27.dtsi
index ec472695c71e..ec3ccc8f4095 100644
--- a/arch/arm/boot/dts/nxp/imx/imx27.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx27.dtsi
@@ -568,7 +568,7 @@ nfc: nand-controller at d8000000 {
 			status = "disabled";
 		};
 
-		weim: weim at d8002000 {
+		weim: memory-controller at d8002000 {
 			#address-cells = <2>;
 			#size-cells = <1>;
 			compatible = "fsl,imx27-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx31.dtsi b/arch/arm/boot/dts/nxp/imx/imx31.dtsi
index e1ae7c175f7d..00006c90d9a7 100644
--- a/arch/arm/boot/dts/nxp/imx/imx31.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx31.dtsi
@@ -352,7 +352,7 @@ nfc: nand at b8000000 {
 				status = "disabled";
 			};
 
-			weim: weim at b8002000 {
+			weim: memory-controller at b8002000 {
 				compatible = "fsl,imx31-weim", "fsl,imx27-weim";
 				reg = <0xb8002000 0x1000>;
 				clocks = <&clks 56>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx35.dtsi b/arch/arm/boot/dts/nxp/imx/imx35.dtsi
index 2d20e5541acc..442dc15677b8 100644
--- a/arch/arm/boot/dts/nxp/imx/imx35.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx35.dtsi
@@ -374,7 +374,7 @@ nfc: nand at bb000000 {
 				status = "disabled";
 			};
 
-			weim: weim at b8002000 {
+			weim: memory-controller at b8002000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				clocks = <&clks 0>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx51.dtsi b/arch/arm/boot/dts/nxp/imx/imx51.dtsi
index c96d6311dfa7..4efce49022e4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx51.dtsi
@@ -578,7 +578,7 @@ m4if: m4if at 83fd8000 {
 				reg = <0x83fd8000 0x1000>;
 			};
 
-			weim: weim at 83fda000 {
+			weim: memory-controller at 83fda000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx51-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
index 81142c523fa8..8431b8a994f4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
@@ -1158,7 +1158,7 @@ mmdc1: memory-controller at 21b4000 { /* MMDC1 */
 				status = "disabled";
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx6q-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
index 28111efb19a6..6aa61235e39e 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
@@ -949,7 +949,7 @@ rngb: rngb at 21b4000 {
 				clocks = <&clks IMX6SL_CLK_DUMMY>;
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				reg = <0x021b8000 0x4000>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
index df3a375f0a3e..0de359d62a47 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
@@ -1107,7 +1107,7 @@ fec2: ethernet at 21b4000 {
 				status = "disabled";
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx6sx-weim", "fsl,imx6q-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index 8aa365f837ca..aeb7e07fd309 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -975,7 +975,7 @@ memory-controller at 21b0000 {
 				clocks = <&clks IMX6UL_CLK_MMDC_P0_IPG>;
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx6ul-weim", "fsl,imx6q-weim";
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:34 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:34 +0100
Subject: [PATCH v3 15/16] dt-bindings: arm: add UNI-T UTi260B
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-16-sre@kernel.org>

Add compatible value for i.MX6ULL based UNI-T UTi260B thermal camera.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 228dcc5c7d6f..7b65f9c9c1a5 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -708,6 +708,7 @@ properties:
               - toradex,colibri-imx6ull      # Colibri iMX6ULL Modules
               - toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module
               - toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Modules
+              - uni-t,uti260b             # UNI-T UTi260B Thermal Camera
           - const: fsl,imx6ull
 
       - description: i.MX6ULL Armadeus Systems OPOS6ULDev Board
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:31 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:31 +0100
Subject: [PATCH v3 12/16] ARM: dts: nxp: imx6ul: fix touchscreen node name
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-13-sre@kernel.org>

The canonical node name for touchscreens is "touchscreen",
so update the i.MX6UL "tsc" node accordingly.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index 45b7605ac381..8aa365f837ca 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -370,7 +370,7 @@ asrc: asrc at 2034000 {
 				};
 			};
 
-			tsc: tsc at 2040000 {
+			tsc: touchscreen at 2040000 {
 				compatible = "fsl,imx6ul-tsc";
 				reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
 				interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.43.0



From sre at kernel.org  Fri Feb 16 14:34:35 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Fri, 16 Feb 2024 23:34:35 +0100
Subject: [PATCH v3 16/16] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <20240216223654.1312880-1-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
Message-ID: <20240216223654.1312880-17-sre@kernel.org>

Add UNI-T UTi260b thermal camera board.

Reviewed-by: Stefan Wahren <wahrenst at gmx.net>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/Makefile            |   1 +
 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts | 572 ++++++++++++++++++
 2 files changed, 573 insertions(+)
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts

diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile
index a724d1a7a9a0..47350cf3ddeb 100644
--- a/arch/arm/boot/dts/nxp/imx/Makefile
+++ b/arch/arm/boot/dts/nxp/imx/Makefile
@@ -349,6 +349,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
 	imx6ull-tarragon-slavext.dtb \
 	imx6ull-tqma6ull2-mba6ulx.dtb \
 	imx6ull-tqma6ull2l-mba6ulx.dtb \
+	imx6ull-uti260b.dtb \
 	imx6ulz-14x14-evk.dtb \
 	imx6ulz-bsh-smm-m2.dtb
 dtb-$(CONFIG_SOC_IMX7D) += \
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
new file mode 100644
index 000000000000..2c0972145c79
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
@@ -0,0 +1,572 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright (C) 2022-2024 Sebastian Reichel <sre at kernel.org>
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/clock/imx6ul-clock.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "UNI-T UTi260B Thermal Camera";
+	compatible = "uni-t,uti260b", "fsl,imx6ull";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_led_ctrl>;
+
+		led {
+			color = <LED_COLOR_ID_WHITE>;
+			function = LED_FUNCTION_FLASH;
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_gpio_keys>;
+		autorepeat;
+
+		up-key {
+			label = "Up";
+			gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_UP>;
+		};
+
+		down-key {
+			label = "Down";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_DOWN>;
+		};
+
+		left-key {
+			label = "Left";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_LEFT>;
+		};
+
+		right-key {
+			label = "Right";
+			gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RIGHT>;
+		};
+
+		ok-key {
+			label = "Ok";
+			gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_ENTER>;
+		};
+
+		return-key {
+			label = "Return";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_ESC>;
+		};
+
+		play-key {
+			label = "Media";
+			gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_MEDIA>;
+		};
+
+		trigger-key {
+			label = "Trigger";
+			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_TRIGGER>;
+		};
+
+		power-key {
+			label = "Power";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+
+		light-key {
+			label = "Light";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_LIGHTS_TOGGLE>;
+		};
+	};
+
+	panel_backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+		enable-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_backlight_enable>;
+		power-supply = <&reg_vsd>;
+		pwms = <&pwm1 0 50000 0>;
+	};
+
+	reg_vsd: regulator-vsd {
+		compatible = "regulator-fixed";
+		regulator-name = "VSD_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_vref: regulator-vref-4v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "VREF_4V2";
+		regulator-min-microvolt = <4200000>;
+		regulator-max-microvolt = <4200000>;
+	};
+
+	tp5000: charger {
+		compatible = "gpio-charger";
+		charger-type = "usb-sdp";
+		gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_charger_stat1>;
+	};
+
+	battery: battery {
+		compatible = "simple-battery";
+		/* generic 26650 battery */
+		device-chemistry = "lithium-ion";
+		charge-full-design-microamp-hours = <5000000>;
+		voltage-max-design-microvolt = <4200000>;
+		voltage-min-design-microvolt = <3300000>;
+	};
+
+	fuel-gauge {
+		compatible = "adc-battery";
+		charged-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		io-channel-names = "voltage";
+		io-channels = <&adc1 7>;
+		monitored-battery = <&battery>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_charger_stat2>;
+		power-supplies = <&tp5000>;
+	};
+
+	poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_poweroff>;
+	};
+};
+
+&gpio1 {
+	ir-reset-hog {
+		gpio-hog;
+		gpios = <3 GPIO_ACTIVE_LOW>;
+		line-name = "ir-reset-gpio";
+		output-low;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_ir_reset>;
+	};
+};
+
+&gpio2 {
+	/* configuring this to output-high results in poweroff */
+	power-en-hog {
+		gpio-hog;
+		gpios = <6 GPIO_ACTIVE_HIGH>;
+		line-name = "power-en-gpio";
+		output-low;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_poweroff2>;
+	};
+};
+
+&ecspi3 {
+	cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_spi3>, <&mux_spi3_cs>;
+	status = "okay";
+
+	panel at 0 {
+		compatible = "inanbo,t28cp45tn89-v17";
+		reg = <0>;
+		backlight = <&panel_backlight>;
+		power-supply = <&reg_vsd>;
+		spi-cpha;
+		spi-cpol;
+		spi-max-frequency = <1000000>;
+		spi-rx-bus-width = <0>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&display_out>;
+			};
+		};
+	};
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_uart>;
+	status = "okay";
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_pwm>;
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_i2c1>;
+	status = "okay";
+
+	camera at 21 {
+		compatible = "galaxycore,gc0308";
+		reg = <0x21>;
+		clocks = <&clks IMX6UL_CLK_CSI>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_gc0308>;
+		powerdown-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+		vdd28-supply = <&reg_vsd>;
+
+		port {
+			gc0308_to_parallel: endpoint {
+				remote-endpoint = <&parallel_from_gc0308>;
+				bus-width = <8>;
+				data-shift = <2>; /* lines 9:2 are used */
+				hsync-active = <1>; /* active high */
+				vsync-active = <1>; /* active high */
+				data-active = <1>; /* active high */
+				pclk-sample = <1>; /* sample on rising edge */
+			};
+		};
+	};
+};
+
+&csi {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_csi>;
+
+	port {
+		parallel_from_gc0308: endpoint {
+			remote-endpoint = <&gc0308_to_parallel>;
+		};
+	};
+};
+
+&i2c2 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_i2c2>;
+	status = "okay";
+
+	rtc at 51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&lcdif {
+	assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_lcd_data>, <&mux_lcd_ctrl>;
+	status = "okay";
+
+	port {
+		display_out: endpoint {
+			remote-endpoint = <&panel_in>;
+		};
+	};
+};
+
+&usdhc1 {
+	/* MicroSD */
+	cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+	keep-power-in-suspend;
+	no-1-8-v;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&mux_sdhc1>, <&mux_sdhc1_cd>;
+	pinctrl-1 = <&mux_sdhc1_100mhz>, <&mux_sdhc1_cd>;
+	pinctrl-2 = <&mux_sdhc1_200mhz>, <&mux_sdhc1_cd>;
+	wakeup-source;
+	vmmc-supply = <&reg_vsd>;
+	status = "okay";
+};
+
+&usdhc2 {
+	/* eMMC */
+	keep-power-in-suspend;
+	no-1-8-v;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_sdhc2>;
+	wakeup-source;
+	status = "okay";
+};
+
+&wdog1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_wdog>;
+};
+
+&adc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_adc>;
+	vref-supply = <&reg_vref>;
+	#io-channel-cells = <1>;
+	status = "okay";
+};
+
+&usbotg1 {
+	/* USB-C connector */
+	disable-over-current;
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbotg2 {
+	/* thermal sensor */
+	disable-over-current;
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy1 {
+	fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+	fsl,tx-d-cal = <106>;
+};
+
+&iomuxc {
+	mux_ir_reset: irresetgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03		0x3008
+		>;
+	};
+
+	mux_poweroff: poweroffgrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04		0x3008
+		>;
+	};
+
+	mux_poweroff2: poweroff2grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06		0x3008
+		>;
+	};
+
+	mux_charger_stat1: charger1grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01		0x3008
+		>;
+	};
+
+	mux_charger_stat2: charger2grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO02__GPIO1_IO02		0x3008
+		>;
+	};
+
+	mux_wdog: wdoggrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY		0x30b0
+		>;
+	};
+
+	mux_sdhc1_cd: sdhc1-cd-grp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_RTS_B__GPIO1_IO19		0x17059
+		>;
+	};
+
+	mux_sdhc1: sdhc1grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x17059
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x10071
+			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
+		>;
+	};
+
+	mux_sdhc1_100mhz: sdhc1-100mhz-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x170b9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x170b9
+			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
+		>;
+	};
+
+	mux_sdhc1_200mhz: sdhc1-200mhz-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x170f9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x170f9
+			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
+		>;
+	};
+
+	mux_sdhc2: sdhc2grp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_RE_B__USDHC2_CLK			0x10069
+			MX6UL_PAD_NAND_WE_B__USDHC2_CMD			0x17059
+			MX6UL_PAD_NAND_DATA00__USDHC2_DATA0		0x17059
+			MX6UL_PAD_NAND_DATA01__USDHC2_DATA1		0x17059
+			MX6UL_PAD_NAND_DATA02__USDHC2_DATA2		0x17059
+			MX6UL_PAD_NAND_DATA03__USDHC2_DATA3		0x17059
+			MX6UL_PAD_NAND_DATA04__USDHC2_DATA4		0x17059
+			MX6UL_PAD_NAND_DATA05__USDHC2_DATA5		0x17059
+			MX6UL_PAD_NAND_DATA06__USDHC2_DATA6		0x17059
+			MX6UL_PAD_NAND_DATA07__USDHC2_DATA7		0x17059
+		>;
+	};
+
+	mux_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6UL_PAD_UART4_TX_DATA__I2C1_SCL		0x4001b8b0
+			MX6UL_PAD_UART4_RX_DATA__I2C1_SDA		0x4001b8b0
+		>;
+	};
+
+	mux_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6UL_PAD_UART5_TX_DATA__I2C2_SCL		0x4001f8a8
+			MX6UL_PAD_UART5_RX_DATA__I2C2_SDA		0x4001f8a8
+		>;
+	};
+
+	mux_uart: uartgrp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX		0x1b0b1
+			MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX		0x1b0b1
+		>;
+	};
+
+	mux_gpio_keys: gpiokeygrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11		0x3008
+			MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12		0x3008
+			MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13		0x3008
+			MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10		0x3008
+			MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09		0x3008
+			MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15		0x3008
+			MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08		0x3008
+			MX6UL_PAD_ENET2_TX_CLK__GPIO2_IO14		0x3008
+			MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03		0x3008
+			MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01		0x3008
+		>;
+	};
+
+	mux_led_ctrl: ledctrlgrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02		0x3008
+		>;
+	};
+
+	mux_adc: adcgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO07__GPIO1_IO07		0xb0
+		>;
+	};
+
+	mux_pwm: pwm1grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO08__PWM1_OUT			0x110b0
+		>;
+	};
+
+	mux_backlight_enable: blenablegrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO09__GPIO1_IO09		0x3008
+		>;
+	};
+
+	mux_lcd_data: lcdifdatgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA00__LCDIF_DATA00		0x79
+			MX6UL_PAD_LCD_DATA01__LCDIF_DATA01		0x79
+			MX6UL_PAD_LCD_DATA02__LCDIF_DATA02		0x79
+			MX6UL_PAD_LCD_DATA03__LCDIF_DATA03		0x79
+			MX6UL_PAD_LCD_DATA04__LCDIF_DATA04		0x79
+			MX6UL_PAD_LCD_DATA05__LCDIF_DATA05		0x79
+			MX6UL_PAD_LCD_DATA06__LCDIF_DATA06		0x79
+			MX6UL_PAD_LCD_DATA07__LCDIF_DATA07		0x79
+			MX6UL_PAD_LCD_DATA08__LCDIF_DATA08		0x79
+			MX6UL_PAD_LCD_DATA09__LCDIF_DATA09		0x79
+			MX6UL_PAD_LCD_DATA10__LCDIF_DATA10		0x79
+			MX6UL_PAD_LCD_DATA11__LCDIF_DATA11		0x79
+			MX6UL_PAD_LCD_DATA12__LCDIF_DATA12		0x79
+			MX6UL_PAD_LCD_DATA13__LCDIF_DATA13		0x79
+			MX6UL_PAD_LCD_DATA14__LCDIF_DATA14		0x79
+			MX6UL_PAD_LCD_DATA15__LCDIF_DATA15		0x79
+			MX6UL_PAD_LCD_DATA16__LCDIF_DATA16		0x79
+			MX6UL_PAD_LCD_DATA17__LCDIF_DATA17		0x79
+		>;
+	};
+
+	mux_lcd_ctrl: lcdifctrlgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_CLK__LCDIF_CLK			0x79
+			MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE		0x79
+			MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC		0x79
+			MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC		0x79
+		>;
+	};
+
+	mux_csi: csi1grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK		0x1b088
+			MX6UL_PAD_CSI_VSYNC__CSI_VSYNC			0x1b088
+			MX6UL_PAD_CSI_HSYNC__CSI_HSYNC			0x1b088
+			MX6UL_PAD_CSI_DATA00__CSI_DATA02		0x1b088
+			MX6UL_PAD_CSI_DATA01__CSI_DATA03		0x1b088
+			MX6UL_PAD_CSI_DATA02__CSI_DATA04		0x1b088
+			MX6UL_PAD_CSI_DATA03__CSI_DATA05		0x1b088
+			MX6UL_PAD_CSI_DATA04__CSI_DATA06		0x1b088
+			MX6UL_PAD_CSI_DATA05__CSI_DATA07		0x1b088
+			MX6UL_PAD_CSI_DATA06__CSI_DATA08		0x1b088
+			MX6UL_PAD_CSI_DATA07__CSI_DATA09		0x1b088
+		>;
+	};
+
+	mux_gc0308: gc0308grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_MCLK__CSI_MCLK			0x1e038
+			MX6UL_PAD_GPIO1_IO05__GPIO1_IO05		0x1b088
+			MX6UL_PAD_GPIO1_IO06__GPIO1_IO06		0x1b088
+		>;
+	};
+
+
+	mux_spi3: ecspi3grp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI		0x100b1
+			MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK		0x100b1
+		>;
+	};
+
+	mux_spi3_cs: ecspi3_csgrp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20		0x3008
+		>;
+	};
+};
-- 
2.43.0



From helgaas at kernel.org  Fri Feb 16 14:44:52 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 16 Feb 2024 16:44:52 -0600
Subject: [PATCH] MAINTAINERS: PCI: TI DRA7XX/J721E: Add Siddharth
 Vadapalli as a reviewer
In-Reply-To: <20240216065926.473805-1-s-vadapalli@ti.com>
Message-ID: <20240216224452.GA1360477@bhelgaas>

On Fri, Feb 16, 2024 at 12:29:26PM +0530, Siddharth Vadapalli wrote:
> Since I have been contributing to the driver for a while and wish to help
> with the review process, add myself as a reviewer.
> 
> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>

Applied to for-linus, for v6.8, thanks, Siddharth!

> ---
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index cd7980e5b1ad..7d6a60002fc1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16976,6 +16976,7 @@ F:	drivers/pci/controller/dwc/*designware*
>  
>  PCI DRIVER FOR TI DRA7XX/J721E
>  M:	Vignesh Raghavendra <vigneshr at ti.com>
> +R:	Siddharth Vadapalli <s-vadapalli at ti.com>
>  L:	linux-omap at vger.kernel.org
>  L:	linux-pci at vger.kernel.org
>  L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> -- 
> 2.34.1
> 


From l.sanfilippo at kunbus.com  Fri Feb 16 14:47:07 2024
From: l.sanfilippo at kunbus.com (Lino Sanfilippo)
Date: Fri, 16 Feb 2024 23:47:07 +0100
Subject: [PATCH 1/2] serial: stm32: do not always set SER_RS485_RX_DURING_TX if RS485 is enabled
Message-ID: <20240216224709.9928-1-l.sanfilippo@kunbus.com>

Before commit 07c30ea5861f ("serial: Do not hold the port lock when setting
rx-during-tx GPIO") the SER_RS485_RX_DURING_TX flag was only set if the
rx-during-tx mode was not controlled by a GPIO. Now the flag is set
unconditionally when RS485 is enabled. This results in an incorrect setting
if the rx-during-tx GPIO is not asserted.

Fix this by setting the flag only if the rx-during-tx mode is not
controlled by a GPIO and thus restore the correct behaviour.

Cc: <stable at vger.kernel.org> # 6.6+
Fixes: 07c30ea5861f ("serial: Do not hold the port lock when setting rx-during-tx GPIO")
Signed-off-by: Lino Sanfilippo <l.sanfilippo at kunbus.com>
---
 drivers/tty/serial/stm32-usart.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 794b77512740..693e932d6feb 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -251,7 +251,9 @@ static int stm32_usart_config_rs485(struct uart_port *port, struct ktermios *ter
 		writel_relaxed(cr3, port->membase + ofs->cr3);
 		writel_relaxed(cr1, port->membase + ofs->cr1);
 
-		rs485conf->flags |= SER_RS485_RX_DURING_TX;
+		if (!port->rs485_rx_during_tx_gpio)
+			rs485conf->flags |= SER_RS485_RX_DURING_TX;
+
 	} else {
 		stm32_usart_clr_bits(port, ofs->cr3,
 				     USART_CR3_DEM | USART_CR3_DEP);

base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de
-- 
2.43.0


From l.sanfilippo at kunbus.com  Fri Feb 16 14:47:08 2024
From: l.sanfilippo at kunbus.com (Lino Sanfilippo)
Date: Fri, 16 Feb 2024 23:47:08 +0100
Subject: [PATCH 2/2] serial: amba-pl011: Fix DMA transmission in RS485 mode
In-Reply-To: <20240216224709.9928-1-l.sanfilippo@kunbus.com>
References: <20240216224709.9928-1-l.sanfilippo@kunbus.com>
Message-ID: <20240216224709.9928-2-l.sanfilippo@kunbus.com>

When DMA is used in RS485 mode make sure that the UARTs tx section is
enabled before the DMA buffers are queued for transmission.

Cc: <stable at vger.kernel.org>
Fixes: 8d479237727c ("serial: amba-pl011: add RS485 support")
Signed-off-by: Lino Sanfilippo <l.sanfilippo at kunbus.com>
---
 drivers/tty/serial/amba-pl011.c | 60 ++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index fccec1698a54..cf2c890a560f 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1339,11 +1339,41 @@ static void pl011_start_tx_pio(struct uart_amba_port *uap)
 	}
 }
 
+static void pl011_rs485_tx_start(struct uart_amba_port *uap)
+{
+	struct uart_port *port = &uap->port;
+	u32 cr;
+
+	/* Enable transmitter */
+	cr = pl011_read(uap, REG_CR);
+	cr |= UART011_CR_TXE;
+
+	/* Disable receiver if half-duplex */
+	if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
+		cr &= ~UART011_CR_RXE;
+
+	if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
+		cr &= ~UART011_CR_RTS;
+	else
+		cr |= UART011_CR_RTS;
+
+	pl011_write(cr, uap, REG_CR);
+
+	if (port->rs485.delay_rts_before_send)
+		mdelay(port->rs485.delay_rts_before_send);
+
+	uap->rs485_tx_started = true;
+}
+
 static void pl011_start_tx(struct uart_port *port)
 {
 	struct uart_amba_port *uap =
 	    container_of(port, struct uart_amba_port, port);
 
+	if ((uap->port.rs485.flags & SER_RS485_ENABLED) &&
+	    !uap->rs485_tx_started)
+		pl011_rs485_tx_start(uap);
+
 	if (!pl011_dma_tx_start(uap))
 		pl011_start_tx_pio(uap);
 }
@@ -1424,42 +1454,12 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c,
 	return true;
 }
 
-static void pl011_rs485_tx_start(struct uart_amba_port *uap)
-{
-	struct uart_port *port = &uap->port;
-	u32 cr;
-
-	/* Enable transmitter */
-	cr = pl011_read(uap, REG_CR);
-	cr |= UART011_CR_TXE;
-
-	/* Disable receiver if half-duplex */
-	if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
-		cr &= ~UART011_CR_RXE;
-
-	if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
-		cr &= ~UART011_CR_RTS;
-	else
-		cr |= UART011_CR_RTS;
-
-	pl011_write(cr, uap, REG_CR);
-
-	if (port->rs485.delay_rts_before_send)
-		mdelay(port->rs485.delay_rts_before_send);
-
-	uap->rs485_tx_started = true;
-}
-
 /* Returns true if tx interrupts have to be (kept) enabled  */
 static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq)
 {
 	struct circ_buf *xmit = &uap->port.state->xmit;
 	int count = uap->fifosize >> 1;
 
-	if ((uap->port.rs485.flags & SER_RS485_ENABLED) &&
-	    !uap->rs485_tx_started)
-		pl011_rs485_tx_start(uap);
-
 	if (uap->port.x_char) {
 		if (!pl011_tx_char(uap, uap->port.x_char, from_irq))
 			return true;
-- 
2.43.0


From dmitry.baryshkov at linaro.org  Fri Feb 16 15:09:59 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 17 Feb 2024 01:09:59 +0200
Subject: [PATCH v5 08/18] arm64: dts: qcom: sm8650-qrd: add the Wifi node
In-Reply-To: <20240216203215.40870-9-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-9-brgl@bgdev.pl>
Message-ID: <CAA8EJpry2yiGXrtPqZ6RXnoTqQZr_hxA_gCPsUbmyFtEBuD4VA@mail.gmail.com>

On Fri, 16 Feb 2024 at 22:33, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> From: Neil Armstrong <neil.armstrong at linaro.org>
>
> Describe the ath12k WLAN on-board the WCN7850 module present on the
> board.

WCN7850 is the same combo WiFi + BT chip. Is there any reason for
describing its parts separately rather than using the same PMU
approach?

>
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> [Bartosz:
>   - move the pcieport0 node into the .dtsi
>   - make regulator naming consistent with existing DT code
>   - add commit message]
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/sm8650-qrd.dts | 29 +++++++++++++++++++++++++
>  arch/arm64/boot/dts/qcom/sm8650.dtsi    | 10 +++++++++
>  2 files changed, 39 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
> index b07cac2e5bc8..4623c358f634 100644
> --- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
> +++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
> @@ -845,6 +845,28 @@ &pcie0 {
>         status = "okay";
>  };
>
> +&pcieport0 {
> +       wifi at 0 {
> +               compatible = "pci17cb,1107";
> +               reg = <0x10000 0x0 0x0 0x0 0x0>;
> +
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&wlan_en>;
> +
> +               enable-gpios = <&tlmm 16 GPIO_ACTIVE_HIGH>;
> +
> +               vdd-supply = <&vreg_s4i_0p85>;
> +               vddio-supply = <&vreg_l15b_1p8>;
> +               vddio1p2-supply = <&vreg_l3c_1p2>;
> +               vddaon-supply = <&vreg_s2c_0p8>;
> +               vdddig-supply = <&vreg_s3c_0p9>;
> +               vddrfa1p2-supply = <&vreg_s1c_1p2>;
> +               vddrfa1p8-supply = <&vreg_s6c_1p8>;
> +
> +               clocks = <&rpmhcc RPMH_RF_CLK1>;
> +       };
> +};
> +
>  &pcie0_phy {
>         vdda-phy-supply = <&vreg_l1i_0p88>;
>         vdda-pll-supply = <&vreg_l3i_1p2>;
> @@ -1139,6 +1161,13 @@ wcd_default: wcd-reset-n-active-state {
>                 bias-disable;
>                 output-low;
>         };
> +
> +       wlan_en: wlan-en-state {
> +               pins = "gpio16";
> +               function = "gpio";
> +               drive-strength = <8>;
> +               bias-pull-down;
> +       };
>  };
>
>  &uart14 {
> diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
> index d488b3b3265e..baf4932e460c 100644
> --- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
> @@ -2293,6 +2293,16 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
>                         dma-coherent;
>
>                         status = "disabled";
> +
> +                       pcieport0: pcie at 0 {
> +                               device_type = "pci";
> +                               reg = <0x0 0x0 0x0 0x0 0x0>;
> +                               #address-cells = <3>;
> +                               #size-cells = <2>;
> +                               ranges;
> +
> +                               bus-range = <0x01 0xff>;
> +                       };
>                 };
>
>                 pcie0_phy: phy at 1c06000 {
> --
> 2.40.1
>


-- 
With best wishes
Dmitry


From andersson at kernel.org  Fri Feb 16 15:10:38 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Fri, 16 Feb 2024 17:10:38 -0600
Subject: (subset) [PATCH 0/3] Add PPG support for PMI632 LPG dtsi
In-Reply-To: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
References: <20240205-pmi632-ppg-v1-0-e236c95a2099@fairphone.com>
Message-ID: <170812504026.18043.12596968738983352722.b4-ty@kernel.org>


On Mon, 05 Feb 2024 10:51:37 +0100, Luca Weiss wrote:
> Hook up the PBS & SDAM to the PMI632 LPG so that we can use the
> hw_pattern for the LEDs.
> 
> 

Applied, thanks!

[3/3] arm64: defconfig: Enable QCOM PBS
      commit: 9c5c14c066f353ac1f4e3b4dd6e19451eac61e0c

Best regards,
-- 
Bjorn Andersson <andersson at kernel.org>


From dmitry.baryshkov at linaro.org  Fri Feb 16 15:17:17 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 17 Feb 2024 01:17:17 +0200
Subject: [PATCH v5 16/18] power: pwrseq: add a driver for the QCA6390 PMU module
In-Reply-To: <20240216203215.40870-17-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-17-brgl@bgdev.pl>
Message-ID: <CAA8EJpo=LFcw8PbFRvGwd9nS5ECazOHiBMWRsqfEpY-v0iQLLA@mail.gmail.com>

On Fri, 16 Feb 2024 at 22:33, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>
> This adds the power sequencing driver for the QCA6390's PMU module. It
> uses the pwrseq subsystem and knows how to match the sequencer to the
> consumer device by verifying the relevant properties and DT layout.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---
>  drivers/power/sequencing/Kconfig          |  16 +
>  drivers/power/sequencing/Makefile         |   2 +
>  drivers/power/sequencing/pwrseq-qca6390.c | 353 ++++++++++++++++++++++
>  3 files changed, 371 insertions(+)
>  create mode 100644 drivers/power/sequencing/pwrseq-qca6390.c
>
> diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
> index ba5732b1dbf8..84ddf3b4ae56 100644
> --- a/drivers/power/sequencing/Kconfig
> +++ b/drivers/power/sequencing/Kconfig
> @@ -10,3 +10,19 @@ menuconfig POWER_SEQUENCING
>           during power-up.
>
>           If unsure, say no.
> +
> +if POWER_SEQUENCING
> +
> +config POWER_SEQUENCING_QCA6390
> +       tristate "QCA6390 PMU driver"
> +       default m if ARCH_QCOM
> +       help
> +         Say U here to enable the power sequencing driver for Qualcomm
> +         QCA6390.
> +
> +         The QCA6390 package contains the BT and WLAN modules whose power
> +         is controlled by the PMU module. As the former two share the power-up
> +         sequence which is executed by the PMU, this driver is needed for
> +         correct power control.
> +
> +endif
> diff --git a/drivers/power/sequencing/Makefile b/drivers/power/sequencing/Makefile
> index dcdf8c0c159e..628345c4e7ae 100644
> --- a/drivers/power/sequencing/Makefile
> +++ b/drivers/power/sequencing/Makefile
> @@ -2,3 +2,5 @@
>
>  obj-$(CONFIG_POWER_SEQUENCING)         += pwrseq-core.o
>  pwrseq-core-y                          := core.o
> +
> +obj-$(CONFIG_POWER_SEQUENCING_QCA6390) += pwrseq-qca6390.o
> diff --git a/drivers/power/sequencing/pwrseq-qca6390.c b/drivers/power/sequencing/pwrseq-qca6390.c
> new file mode 100644
> index 000000000000..5f254f9c71d7
> --- /dev/null
> +++ b/drivers/power/sequencing/pwrseq-qca6390.c
> @@ -0,0 +1,353 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2024 Linaro Ltd.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/jiffies.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/pwrseq/provider.h>
> +#include <linux/string.h>
> +#include <linux/types.h>
> +
> +struct pwrseq_qca6390_vreg {
> +       const char *name;
> +       unsigned int load_uA;
> +};
> +
> +struct pwrseq_qca6390_pdata {
> +       const struct pwrseq_qca6390_vreg *vregs_common;
> +       size_t num_vregs_common;
> +       const struct pwrseq_qca6390_vreg *vregs_wlan;
> +       size_t num_vregs_wlan;
> +       unsigned int pwup_delay_msec;
> +};
> +
> +struct pwrseq_qca6390_ctx {
> +       struct pwrseq_device *pwrseq;
> +       struct device_node *of_node;
> +       const struct pwrseq_qca6390_pdata *pdata;
> +       struct regulator_bulk_data *regs_common;
> +       struct regulator_bulk_data *regs_wlan;
> +       struct gpio_desc *bt_gpio;
> +       struct gpio_desc *wlan_gpio;
> +       unsigned long last_gpio_enable;
> +};
> +
> +static const struct pwrseq_qca6390_vreg pwrseq_qca6390_vregs_common[] = {
> +       {
> +               .name = "vddio",
> +               .load_uA = 20000,
> +       },
> +       {
> +               .name = "vddaon",
> +               .load_uA = 100000,
> +       },
> +       {
> +               .name = "vddpmu",
> +               .load_uA = 1250000,
> +       },
> +       {
> +               .name = "vddrfa0p95",
> +               .load_uA = 200000,
> +       },
> +       {
> +               .name = "vddrfa1p3",
> +               .load_uA = 400000,
> +       },
> +       {
> +               .name = "vddrfa1p9",
> +               .load_uA = 400000,
> +       },
> +};
> +
> +static const struct pwrseq_qca6390_vreg pwrseq_qca6390_vregs_wlan[] = {
> +       {
> +               .name = "vddpcie1p3",
> +               .load_uA = 35000,
> +       },
> +       {
> +               .name = "vddpcie1p9",
> +               .load_uA = 15000,
> +       },
> +};

I thought that we had discussed this already. According to the docs,
all PMU supplies should be powered on when the chip is being switched
on, no matter whether it is for the WiFi or for the BT.

> +
> +static void pwrseq_qca6390_ensure_gpio_delay(struct pwrseq_qca6390_ctx *ctx)
> +{
> +       unsigned long diff_jiffies = jiffies - ctx->last_gpio_enable;
> +       unsigned int diff_msecs = jiffies_to_msecs(diff_jiffies);
> +
> +       if (diff_msecs < 100)
> +               msleep(100 - diff_msecs);
> +}
> +
> +static const struct pwrseq_qca6390_pdata pwrseq_qca6390_of_data = {
> +       .vregs_common = pwrseq_qca6390_vregs_common,
> +       .num_vregs_common = ARRAY_SIZE(pwrseq_qca6390_vregs_common),
> +       .vregs_wlan = pwrseq_qca6390_vregs_wlan,
> +       .num_vregs_wlan = ARRAY_SIZE(pwrseq_qca6390_vregs_wlan),
> +       .pwup_delay_msec = 16,
> +};
> +
> +static int pwrseq_qca6390_vregs_enable(struct pwrseq_device *pwrseq)
> +{
> +       struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
> +
> +       return regulator_bulk_enable(ctx->pdata->num_vregs_common,
> +                                    ctx->regs_common);
> +}
> +
> +static int pwrseq_qca6390_vregs_disable(struct pwrseq_device *pwrseq)
> +{
> +       struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
> +
> +       return regulator_bulk_disable(ctx->pdata->num_vregs_common,
> +                                     ctx->regs_common);
> +}
> +
> +static const struct pwrseq_unit_data pwrseq_qca6390_vregs_unit_data = {
> +       .name = "regulators-enable",
> +       .enable = pwrseq_qca6390_vregs_enable,
> +       .disable = pwrseq_qca6390_vregs_disable,
> +};
> +
> +static const struct pwrseq_unit_data *pwrseq_qca6390_unit_deps[] = {
> +       &pwrseq_qca6390_vregs_unit_data,
> +       NULL
> +};
> +
> +static int pwrseq_qca6390_bt_enable(struct pwrseq_device *pwrseq)
> +{
> +       struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
> +
> +       pwrseq_qca6390_ensure_gpio_delay(ctx);
> +       gpiod_set_value_cansleep(ctx->bt_gpio, 1);
> +       ctx->last_gpio_enable = jiffies;
> +
> +       return 0;
> +}
> +
> +static int pwrseq_qca6390_bt_disable(struct pwrseq_device *pwrseq)
> +{
> +       struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
> +
> +       gpiod_set_value_cansleep(ctx->bt_gpio, 0);
> +
> +       return 0;
> +}
> +
> +static const struct pwrseq_unit_data pwrseq_qca6390_bt_unit_data = {
> +       .name = "bluetooth-enable",
> +       .deps = pwrseq_qca6390_unit_deps,

Can we call corresponding regulator_bulk functions from bt and wlan
enable/disable? This will save us from building the tree-like
structures (and possible loops inside that tree).

> +       .enable = pwrseq_qca6390_bt_enable,
> +       .disable = pwrseq_qca6390_bt_disable,
> +};
> +
> +static int pwrseq_qca6390_wlan_enable(struct pwrseq_device *pwrseq)
> +{
> +       struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
> +       int ret;
> +
> +       ret = regulator_bulk_enable(ctx->pdata->num_vregs_wlan, ctx->regs_wlan);
> +       if (ret)
> +               return ret;
> +
> +       pwrseq_qca6390_ensure_gpio_delay(ctx);
> +       gpiod_set_value_cansleep(ctx->wlan_gpio, 1);
> +       ctx->last_gpio_enable = jiffies;
> +
> +       return 0;
> +}
> +
> +static int pwrseq_qca6390_wlan_disable(struct pwrseq_device *pwrseq)
> +{
> +       struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
> +
> +       gpiod_set_value_cansleep(ctx->wlan_gpio, 0);
> +
> +       return regulator_bulk_disable(ctx->pdata->num_vregs_wlan,
> +                                     ctx->regs_wlan);
> +}
> +
> +static const struct pwrseq_unit_data pwrseq_qca6390_wlan_unit_data = {
> +       .name = "wlan-enable",
> +       .deps = pwrseq_qca6390_unit_deps,
> +       .enable = pwrseq_qca6390_wlan_enable,
> +       .disable = pwrseq_qca6390_wlan_disable,
> +};
> +
> +static int pwrseq_qca6390_pwup_delay(struct pwrseq_device *pwrseq)
> +{
> +       struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
> +
> +       if (ctx->pdata->pwup_delay_msec)
> +               msleep(ctx->pdata->pwup_delay_msec);
> +
> +       return 0;
> +}
> +
> +static const struct pwrseq_target_data pwrseq_qca6390_bt_target_data = {
> +       .name = "bluetooth",
> +       .unit = &pwrseq_qca6390_bt_unit_data,
> +       .post_enable = pwrseq_qca6390_pwup_delay,
> +};
> +
> +static const struct pwrseq_target_data pwrseq_qca6390_wlan_target_data = {
> +       .name = "wlan",
> +       .unit = &pwrseq_qca6390_wlan_unit_data,
> +       .post_enable = pwrseq_qca6390_pwup_delay,
> +};
> +
> +static const struct pwrseq_target_data *pwrseq_qca6390_targets[] = {
> +       &pwrseq_qca6390_bt_target_data,
> +       &pwrseq_qca6390_wlan_target_data,
> +       NULL
> +};
> +
> +static int pwrseq_qca6390_match(struct pwrseq_device *pwrseq,
> +                               struct device *dev)
> +{
> +       struct pwrseq_qca6390_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
> +       struct device_node *dev_node = dev->of_node;
> +
> +       /*
> +        * The PMU supplies power to the Bluetooth and WLAN modules. both
> +        * consume the PMU AON output so check the presence of the
> +        * 'vddaon-supply' property and whether it leads us to the right
> +        * device.
> +        */
> +       if (!of_property_present(dev_node, "vddaon-supply"))
> +               return 0;
> +
> +       struct device_node *reg_node __free(device_node) =
> +                       of_parse_phandle(dev_node, "vddaon-supply", 0);
> +       if (!reg_node)
> +               return 0;
> +
> +       /*
> +        * `reg_node` is the PMU AON regulator, its parent is the `regulators`
> +        * node and finally its grandparent is the PMU device node that we're
> +        * looking for.
> +        */
> +       if (!reg_node->parent || !reg_node->parent->parent ||
> +           reg_node->parent->parent != ctx->of_node)
> +               return 0;
> +
> +       return 1;
> +}
> +
> +static struct regulator_bulk_data *
> +pwrseq_qca6390_get_regs(struct device *dev, size_t num_regs,
> +                       const struct pwrseq_qca6390_vreg *pdata)
> +{
> +       struct regulator_bulk_data *regs;
> +       int ret, i;
> +
> +       regs = devm_kcalloc(dev, num_regs, sizeof(*regs), GFP_KERNEL);
> +       if (!regs)
> +               return ERR_PTR(-ENOMEM);
> +
> +       for (i = 0; i < num_regs; i++)
> +               regs[i].supply = pdata[i].name;
> +
> +       ret = devm_regulator_bulk_get(dev, num_regs, regs);
> +       if (ret < 0)
> +               return ERR_PTR(ret);
> +
> +       for (i = 0; i < num_regs; i++) {
> +               if (!pdata[i].load_uA)
> +                       continue;
> +
> +               ret = regulator_set_load(regs[i].consumer, pdata[i].load_uA);
> +               if (ret)
> +                       return ERR_PTR(ret);
> +       }
> +
> +       return regs;
> +}
> +
> +static int pwrseq_qca6390_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct pwrseq_qca6390_ctx *ctx;
> +       struct pwrseq_config config;
> +
> +       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> +       if (!ctx)
> +               return -ENOMEM;
> +
> +       ctx->of_node = dev->of_node;
> +
> +       ctx->pdata = of_device_get_match_data(dev);
> +       if (!ctx->pdata)
> +               return dev_err_probe(dev, -ENODEV,
> +                                    "Failed to obtain platform data\n");
> +
> +       ctx->regs_common = pwrseq_qca6390_get_regs(dev,
> +                                                  ctx->pdata->num_vregs_common,
> +                                                  ctx->pdata->vregs_common);
> +       if (IS_ERR(ctx->regs_common))
> +               return dev_err_probe(dev, PTR_ERR(ctx->regs_common),
> +                                    "Failed to get all regulators\n");
> +
> +       ctx->regs_wlan = pwrseq_qca6390_get_regs(dev,
> +                                                ctx->pdata->num_vregs_wlan,
> +                                                ctx->pdata->vregs_wlan);
> +       if (IS_ERR(ctx->regs_wlan))
> +               return dev_err_probe(dev, PTR_ERR(ctx->regs_wlan),
> +                                    "Failed to get all regulators\n");
> +
> +       ctx->bt_gpio = devm_gpiod_get_optional(dev, "bt-enable", GPIOD_OUT_LOW);
> +       if (IS_ERR(ctx->bt_gpio))
> +               return dev_err_probe(dev, PTR_ERR(ctx->bt_gpio),
> +                                    "Failed to get the Bluetooth enable GPIO\n");
> +
> +       ctx->wlan_gpio = devm_gpiod_get_optional(dev, "wlan-enable",
> +                                                GPIOD_OUT_LOW);
> +       if (IS_ERR(ctx->wlan_gpio))
> +               return dev_err_probe(dev, PTR_ERR(ctx->wlan_gpio),
> +                                    "Failed to get the WLAN enable GPIO\n");
> +
> +       memset(&config, 0, sizeof(config));
> +
> +       config.parent = dev;
> +       config.owner = THIS_MODULE;
> +       config.drvdata = ctx;
> +       config.match = pwrseq_qca6390_match;
> +       config.targets = pwrseq_qca6390_targets;
> +
> +       ctx->pwrseq = devm_pwrseq_device_register(dev, &config);
> +       if (IS_ERR(ctx->pwrseq))
> +               return dev_err_probe(dev, PTR_ERR(ctx->pwrseq),
> +                                    "Failed to register the power sequencer\n");
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id pwrseq_qca6390_of_match[] = {
> +       {
> +               .compatible = "qcom,qca6390-pmu",
> +               .data = &pwrseq_qca6390_of_data,
> +       },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, pwrseq_qca6390_of_match);
> +
> +static struct platform_driver pwrseq_qca6390_driver = {
> +       .driver = {
> +               .name = "pwrseq-qca6390",
> +               .of_match_table = pwrseq_qca6390_of_match,
> +       },
> +       .probe = pwrseq_qca6390_probe,
> +};
> +module_platform_driver(pwrseq_qca6390_driver);
> +
> +MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski at linaro.org>");
> +MODULE_DESCRIPTION("QCA6390 PMU power sequencing driver");
> +MODULE_LICENSE("GPL");
> --
> 2.40.1
>


-- 
With best wishes
Dmitry


From ardb+git at google.com  Fri Feb 16 15:59:44 2024
From: ardb+git at google.com (Ard Biesheuvel)
Date: Sat, 17 Feb 2024 00:59:44 +0100
Subject: [PATCH] arm64: mm: Make PUD folding check in set_pud() a runtime check
Message-ID: <20240216235944.3677178-2-ardb+git@google.com>

From: Ard Biesheuvel <ardb at kernel.org>

When set_pud() is called on a 4-level paging build config that runs with
3 levels at runtime (which happens with 16k page size builds with
support for LPA2), the updated entry is in fact a PGD in
swapper_pg_dir[], and this is mapped read-only after boot.

So in this case, the existing check needs to be performed as well, even
though __PAGETABLE_PUD_FOLDED is not #define'd. So replace the #ifdef
with a call to pgtable_l4_enabled().

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Ryan Roberts <ryan.roberts at arm.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgtable.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index b3c716fa8121..8bec85350865 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -699,14 +699,14 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
 #define pud_user(pud)		pte_user(pud_pte(pud))
 #define pud_user_exec(pud)	pte_user_exec(pud_pte(pud))
 
+static inline bool pgtable_l4_enabled(void);
+
 static inline void set_pud(pud_t *pudp, pud_t pud)
 {
-#ifdef __PAGETABLE_PUD_FOLDED
-	if (in_swapper_pgdir(pudp)) {
+	if (!pgtable_l4_enabled() && in_swapper_pgdir(pudp)) {
 		set_swapper_pgd((pgd_t *)pudp, __pgd(pud_val(pud)));
 		return;
 	}
-#endif /* __PAGETABLE_PUD_FOLDED */
 
 	WRITE_ONCE(*pudp, pud);
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From namhyung at kernel.org  Fri Feb 16 16:25:09 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Fri, 16 Feb 2024 16:25:09 -0800
Subject: [PATCH v3 2/8] libperf cpumap: Ensure empty cpumap is NULL from alloc
In-Reply-To: <20240202234057.2085863-3-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com> <20240202234057.2085863-3-irogers@google.com>
Message-ID: <CAM9d7ci3VO7reyxPc8WOczdoyYYCUshxCJDMZ7wPpHknCubNXQ@mail.gmail.com>

On Fri, Feb 2, 2024 at 3:41?PM Ian Rogers <irogers at google.com> wrote:
>
> Potential corner cases could cause a cpumap to be allocated with size
> 0, but an empty cpumap should be represented as NULL. Add a path in
> perf_cpu_map__alloc to ensure this.
>
> Suggested-by: James Clark <james.clark at arm.com>
> Closes: https://lore.kernel.org/lkml/2cd09e7c-eb88-6726-6169-647dcd0a8101 at arm.com/
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/lib/perf/cpumap.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c
> index ba49552952c5..cae799ad44e1 100644
> --- a/tools/lib/perf/cpumap.c
> +++ b/tools/lib/perf/cpumap.c
> @@ -18,9 +18,13 @@ void perf_cpu_map__set_nr(struct perf_cpu_map *map, int nr_cpus)
>
>  struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus)
>  {
> -       RC_STRUCT(perf_cpu_map) *cpus = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
> +       RC_STRUCT(perf_cpu_map) *cpus;
>         struct perf_cpu_map *result;
>
> +       if (nr_cpus == 0)
> +               return NULL;

But allocation failure also returns NULL.  Then callers should check
what's the expected result.

Thanks,
Namhyung

> +
> +       cpus = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
>         if (ADD_RC_CHK(result, cpus)) {
>                 cpus->nr = nr_cpus;
>                 refcount_set(&cpus->refcnt, 1);
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From irogers at google.com  Fri Feb 16 16:52:31 2024
From: irogers at google.com (Ian Rogers)
Date: Fri, 16 Feb 2024 16:52:31 -0800
Subject: [PATCH v3 2/8] libperf cpumap: Ensure empty cpumap is NULL from alloc
In-Reply-To: <CAM9d7ci3VO7reyxPc8WOczdoyYYCUshxCJDMZ7wPpHknCubNXQ@mail.gmail.com>
References: <20240202234057.2085863-1-irogers@google.com> <20240202234057.2085863-3-irogers@google.com>
 <CAM9d7ci3VO7reyxPc8WOczdoyYYCUshxCJDMZ7wPpHknCubNXQ@mail.gmail.com>
Message-ID: <CAP-5=fVNLoes2VaCcqrueiDLBZAZNthSJVD17z77cnyE7wF7ag@mail.gmail.com>

On Fri, Feb 16, 2024 at 4:25?PM Namhyung Kim <namhyung at kernel.org> wrote:
>
> On Fri, Feb 2, 2024 at 3:41?PM Ian Rogers <irogers at google.com> wrote:
> >
> > Potential corner cases could cause a cpumap to be allocated with size
> > 0, but an empty cpumap should be represented as NULL. Add a path in
> > perf_cpu_map__alloc to ensure this.
> >
> > Suggested-by: James Clark <james.clark at arm.com>
> > Closes: https://lore.kernel.org/lkml/2cd09e7c-eb88-6726-6169-647dcd0a8101 at arm.com/
> > Signed-off-by: Ian Rogers <irogers at google.com>
> > ---
> >  tools/lib/perf/cpumap.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c
> > index ba49552952c5..cae799ad44e1 100644
> > --- a/tools/lib/perf/cpumap.c
> > +++ b/tools/lib/perf/cpumap.c
> > @@ -18,9 +18,13 @@ void perf_cpu_map__set_nr(struct perf_cpu_map *map, int nr_cpus)
> >
> >  struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus)
> >  {
> > -       RC_STRUCT(perf_cpu_map) *cpus = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
> > +       RC_STRUCT(perf_cpu_map) *cpus;
> >         struct perf_cpu_map *result;
> >
> > +       if (nr_cpus == 0)
> > +               return NULL;
>
> But allocation failure also returns NULL.  Then callers should check
> what's the expected result.

Right, we don't have a habit of just aborting on memory allocation
errors. In the case that NULL is returned it is assumed that an empty
CPU map is appropriate. Adding checks throughout the code base that an
empty CPU map is only returned when 0 is given is beyond the scope of
this patch set.

Thanks,
Ian

> Thanks,
> Namhyung
>
> > +
> > +       cpus = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
> >         if (ADD_RC_CHK(result, cpus)) {
> >                 cpus->nr = nr_cpus;
> >                 refcount_set(&cpus->refcnt, 1);
> > --
> > 2.43.0.594.gd9cf4e227d-goog
> >


From tzungbi at kernel.org  Fri Feb 16 16:58:06 2024
From: tzungbi at kernel.org (Tzung-Bi Shih)
Date: Sat, 17 Feb 2024 08:58:06 +0800
Subject: [PATCH v4 0/4] Allow coreboot modules to autoload and enable
 cbmem in the arm64 defconfig
In-Reply-To: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
References: <20240212-coreboot-mod-defconfig-v4-0-d14172676f6d@collabora.com>
Message-ID: <ZdAEno9gIwjmI0lN@google.com>

On Mon, Feb 12, 2024 at 09:50:04AM -0500, N?colas F. R. A. Prado wrote:
> This series adds the missing pieces to the coreboot bus and the module
> alias generation to allow coreboot modules to be automatically loaded
> when matching devices are detected.
> 
> The configs for cbmem coreboot entries are then enabled in the arm64
> defconfig, as modules, to allow reading logs from coreboot on arm64
> Chromebooks, which is useful for debugging the boot process.
> 
> [...]

Applied, thanks!

[1/4] firmware: coreboot: Generate modalias uevent for devices
      commit: c2b28f6806d2a26a8d46c0f02d4852bf9904929d
[2/4] firmware: coreboot: Generate aliases for coreboot modules
      commit: f1cebae1dbf85f9de65c13a2d9f5cc3be7e51dc4
[3/4] firmware: coreboot: Replace tag with id table in driver struct
      commit: 8a0a62941a042612f7487f6c4ff291f9054ff214


From namhyung at kernel.org  Fri Feb 16 17:01:45 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Fri, 16 Feb 2024 17:01:45 -0800
Subject: [PATCH v3 3/8] perf arm-spe/cs-etm: Directly iterate CPU maps
In-Reply-To: <20240202234057.2085863-4-irogers@google.com>
References: <20240202234057.2085863-1-irogers@google.com> <20240202234057.2085863-4-irogers@google.com>
Message-ID: <CAM9d7chPqFGEih7z7rp=eS5P30gSMvG=6fi=0QqT=EdfdMOH_A@mail.gmail.com>

On Fri, Feb 2, 2024 at 3:41?PM Ian Rogers <irogers at google.com> wrote:
>
> Rather than iterate all CPUs and see if they are in CPU maps, directly
> iterate the CPU map. Similarly make use of the intersect function
> taking care for when "any" CPU is specified. Switch
> perf_cpu_map__has_any_cpu_or_is_empty to more appropriate
> alternatives.
>
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/perf/arch/arm/util/cs-etm.c    | 114 ++++++++++++---------------
>  tools/perf/arch/arm64/util/arm-spe.c |   4 +-
>  2 files changed, 51 insertions(+), 67 deletions(-)
>
> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> index 77e6663c1703..07be32d99805 100644
> --- a/tools/perf/arch/arm/util/cs-etm.c
> +++ b/tools/perf/arch/arm/util/cs-etm.c
> @@ -197,38 +197,37 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr,
>  static int cs_etm_validate_config(struct auxtrace_record *itr,
>                                   struct evsel *evsel)
>  {
> -       int i, err = -EINVAL;
> +       int idx, err = 0;
>         struct perf_cpu_map *event_cpus = evsel->evlist->core.user_requested_cpus;
> -       struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
> -
> -       /* Set option of each CPU we have */
> -       for (i = 0; i < cpu__max_cpu().cpu; i++) {
> -               struct perf_cpu cpu = { .cpu = i, };
> +       struct perf_cpu_map *intersect_cpus;
> +       struct perf_cpu cpu;
>
> -               /*
> -                * In per-cpu case, do the validation for CPUs to work with.
> -                * In per-thread case, the CPU map is empty.  Since the traced
> -                * program can run on any CPUs in this case, thus don't skip
> -                * validation.
> -                */
> -               if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus) &&
> -                   !perf_cpu_map__has(event_cpus, cpu))
> -                       continue;
> +       /*
> +        * Set option of each CPU we have. In per-cpu case, do the validation
> +        * for CPUs to work with. In per-thread case, the CPU map has the "any"
> +        * CPU value. Since the traced program can run on any CPUs in this case,
> +        * thus don't skip validation.
> +        */
> +       if (!perf_cpu_map__has_any_cpu(event_cpus)) {
> +               struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
>
> -               if (!perf_cpu_map__has(online_cpus, cpu))
> -                       continue;
> +               intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
> +               perf_cpu_map__put(online_cpus);
> +       } else {
> +               intersect_cpus = perf_cpu_map__new_online_cpus();
> +       }

Would it be ok if any of these operations fail?  I believe the
cpu map functions work well with NULL already.

Thanks,
Namhyung

>
> -               err = cs_etm_validate_context_id(itr, evsel, i);
> +       perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
> +               err = cs_etm_validate_context_id(itr, evsel, cpu.cpu);
>                 if (err)
> -                       goto out;
> -               err = cs_etm_validate_timestamp(itr, evsel, i);
> +                       break;
> +
> +               err = cs_etm_validate_timestamp(itr, evsel, cpu.cpu);
>                 if (err)
> -                       goto out;
> +                       break;
>         }
>
> -       err = 0;
> -out:
> -       perf_cpu_map__put(online_cpus);
> +       perf_cpu_map__put(intersect_cpus);
>         return err;
>  }
>
> @@ -435,7 +434,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
>          * Also the case of per-cpu mmaps, need the contextID in order to be notified
>          * when a context switch happened.
>          */
> -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>                 evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
>                                            "timestamp", 1);
>                 evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
> @@ -461,7 +460,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
>         evsel->core.attr.sample_period = 1;
>
>         /* In per-cpu case, always need the time of mmap events etc */
> -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus))
> +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
>                 evsel__set_sample_bit(evsel, TIME);
>
>         err = cs_etm_validate_config(itr, cs_etm_evsel);
> @@ -533,45 +532,31 @@ static size_t
>  cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
>                       struct evlist *evlist __maybe_unused)
>  {
> -       int i;
> +       int idx;
>         int etmv3 = 0, etmv4 = 0, ete = 0;
>         struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus;
> -       struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
> -
> -       /* cpu map is not empty, we have specific CPUs to work with */
> -       if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
> -               for (i = 0; i < cpu__max_cpu().cpu; i++) {
> -                       struct perf_cpu cpu = { .cpu = i, };
> +       struct perf_cpu_map *intersect_cpus;
> +       struct perf_cpu cpu;
>
> -                       if (!perf_cpu_map__has(event_cpus, cpu) ||
> -                           !perf_cpu_map__has(online_cpus, cpu))
> -                               continue;
> +       if (!perf_cpu_map__has_any_cpu(event_cpus)) {
> +               /* cpu map is not "any" CPU , we have specific CPUs to work with */
> +               struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
>
> -                       if (cs_etm_is_ete(itr, i))
> -                               ete++;
> -                       else if (cs_etm_is_etmv4(itr, i))
> -                               etmv4++;
> -                       else
> -                               etmv3++;
> -               }
> +               intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
> +               perf_cpu_map__put(online_cpus);
>         } else {
> -               /* get configuration for all CPUs in the system */
> -               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))
> -                               ete++;
> -                       else if (cs_etm_is_etmv4(itr, i))
> -                               etmv4++;
> -                       else
> -                               etmv3++;
> -               }
> +               /* Event can be "any" CPU so count all online CPUs. */
> +               intersect_cpus = perf_cpu_map__new_online_cpus();
>         }
> -
> -       perf_cpu_map__put(online_cpus);
> +       perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
> +               if (cs_etm_is_ete(itr, cpu.cpu))
> +                       ete++;
> +               else if (cs_etm_is_etmv4(itr, cpu.cpu))
> +                       etmv4++;
> +               else
> +                       etmv3++;
> +       }
> +       perf_cpu_map__put(intersect_cpus);
>
>         return (CS_ETM_HEADER_SIZE +
>                (ete   * CS_ETE_PRIV_SIZE) +
> @@ -813,16 +798,15 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
>         if (!session->evlist->core.nr_mmaps)
>                 return -EINVAL;
>
> -       /* If the cpu_map is empty all online CPUs are involved */
> -       if (perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
> +       /* If the cpu_map has the "any" CPU all online CPUs are involved */
> +       if (perf_cpu_map__has_any_cpu(event_cpus)) {
>                 cpu_map = online_cpus;
>         } else {
>                 /* Make sure all specified CPUs are online */
> -               for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) {
> -                       struct perf_cpu cpu = { .cpu = i, };
> +               struct perf_cpu cpu;
>
> -                       if (perf_cpu_map__has(event_cpus, cpu) &&
> -                           !perf_cpu_map__has(online_cpus, cpu))
> +               perf_cpu_map__for_each_cpu(cpu, i, event_cpus) {
> +                       if (!perf_cpu_map__has(online_cpus, cpu))
>                                 return -EINVAL;
>                 }
>
> diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
> index 51ccbfd3d246..0b52e67edb3b 100644
> --- a/tools/perf/arch/arm64/util/arm-spe.c
> +++ b/tools/perf/arch/arm64/util/arm-spe.c
> @@ -232,7 +232,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
>          * In the case of per-cpu mmaps, sample CPU for AUX event;
>          * also enable the timestamp tracing for samples correlation.
>          */
> -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>                 evsel__set_sample_bit(arm_spe_evsel, CPU);
>                 evsel__set_config_if_unset(arm_spe_pmu, arm_spe_evsel,
>                                            "ts_enable", 1);
> @@ -265,7 +265,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
>         tracking_evsel->core.attr.sample_period = 1;
>
>         /* In per-cpu case, always need the time of mmap events etc */
> -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>                 evsel__set_sample_bit(tracking_evsel, TIME);
>                 evsel__set_sample_bit(tracking_evsel, CPU);
>
> --
> 2.43.0.594.gd9cf4e227d-goog
>


From namhyung at kernel.org  Fri Feb 16 17:04:01 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Fri, 16 Feb 2024 17:04:01 -0800
Subject: [PATCH v3 0/8] Clean up libperf cpumap's empty function
In-Reply-To: <CAP-5=fVjAHqAHHLqE=3v2bP6S6k98psiuZds7TUTFCT7RgMFdQ@mail.gmail.com>
References: <20240202234057.2085863-1-irogers@google.com> <CAP-5=fVjAHqAHHLqE=3v2bP6S6k98psiuZds7TUTFCT7RgMFdQ@mail.gmail.com>
Message-ID: <CAM9d7ciPYMd4zckrcgnPtradZ_bvaNOHji1tkkYQu_TTF5=eYw@mail.gmail.com>

On Wed, Feb 14, 2024 at 2:03?PM Ian Rogers <irogers at google.com> wrote:
>
> On Fri, Feb 2, 2024 at 3:41?PM Ian Rogers <irogers at google.com> wrote:
> >
> > Rename and clean up the use of libperf CPU map functions particularly
> > focussing on perf_cpu_map__empty that may return true for maps
> > containing CPUs but also with an "any CPU"/dummy value.
> >
> > perf_cpu_map__nr is also troubling in that iterating an empty CPU map
> > will yield the "any CPU"/dummy value. Reduce the appearance of some
> > calls to this by using the perf_cpu_map__for_each_cpu macro.
> >
> > v3: Address handling of "any" is arm-spe/cs-etm patch.
> > v2: 6 patches were merged by Arnaldo. New patch added ensure empty
> >     maps are allocated as NULL (suggested by James Clark). Hopefully a
> >     fix to "perf arm-spe/cs-etm: Directly iterate CPU maps".
> >
> > Ian Rogers (8):
> >   libperf cpumap: Add any, empty and min helpers
> >   libperf cpumap: Ensure empty cpumap is NULL from alloc
> >   perf arm-spe/cs-etm: Directly iterate CPU maps
> >   perf intel-pt/intel-bts: Switch perf_cpu_map__has_any_cpu_or_is_empty
> >     use
> >   perf cpumap: Clean up use of perf_cpu_map__has_any_cpu_or_is_empty
> >   perf arm64 header: Remove unnecessary CPU map get and put
> >   perf stat: Remove duplicate cpus_map_matched function
> >   perf cpumap: Use perf_cpu_map__for_each_cpu when possible
>
> Ping. Thanks,
> Ian

Adrian and James, are you ok with this now?

Thanks,
Namhyung


From sboyd at kernel.org  Fri Feb 16 17:05:50 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 16 Feb 2024 17:05:50 -0800
Subject: [PATCH v4 1/7] of: Always unflatten in unflatten_and_copy_device_tree()
In-Reply-To: <20240217010557.2381548-1-sboyd@kernel.org>
References: <20240217010557.2381548-1-sboyd@kernel.org>
Message-ID: <20240217010557.2381548-2-sboyd@kernel.org>

We want to populate an empty DT whenever CONFIG_OF is enabled so that
overlays can be applied and the DT unit tests can be run. Make
unflatten_and_copy_device_tree() stop printing a warning if the
'initial_boot_params' pointer is NULL. Instead, simply copy the dtb if
there is one and then unflatten it. If there isn't a DT to copy, then
the call to unflatten_device_tree() is largely a no-op, so nothing
really changes here.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list at gmail.com>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 drivers/of/fdt.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index bf502ba8da95..dfeba8b8ce94 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1318,6 +1318,21 @@ bool __init early_init_dt_scan(void *params)
 	return true;
 }
 
+static void *__init copy_device_tree(void *fdt)
+{
+	int size;
+	void *dt;
+
+	size = fdt_totalsize(fdt);
+	dt = early_init_dt_alloc_memory_arch(size,
+					     roundup_pow_of_two(FDT_V17_SIZE));
+
+	if (dt)
+		memcpy(dt, fdt, size);
+
+	return dt;
+}
+
 /**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
@@ -1350,22 +1365,9 @@ void __init unflatten_device_tree(void)
  */
 void __init unflatten_and_copy_device_tree(void)
 {
-	int size;
-	void *dt;
+	if (initial_boot_params)
+		initial_boot_params = copy_device_tree(initial_boot_params);
 
-	if (!initial_boot_params) {
-		pr_warn("No valid device tree found, continuing without\n");
-		return;
-	}
-
-	size = fdt_totalsize(initial_boot_params);
-	dt = early_init_dt_alloc_memory_arch(size,
-					     roundup_pow_of_two(FDT_V17_SIZE));
-
-	if (dt) {
-		memcpy(dt, initial_boot_params, size);
-		initial_boot_params = dt;
-	}
 	unflatten_device_tree();
 }
 
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb 16 17:05:51 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 16 Feb 2024 17:05:51 -0800
Subject: [PATCH v4 2/7] of: Create of_root if no dtb provided by firmware
In-Reply-To: <20240217010557.2381548-1-sboyd@kernel.org>
References: <20240217010557.2381548-1-sboyd@kernel.org>
Message-ID: <20240217010557.2381548-3-sboyd@kernel.org>

From: Frank Rowand <frowand.list at gmail.com>

When enabling CONFIG_OF on a platform where 'of_root' is not populated
by firmware, we end up without a root node. In order to apply overlays
and create subnodes of the root node, we need one. Create this root node
by unflattening an empty builtin dtb.

If firmware provides a flattened device tree (FDT) then the FDT is
unflattened via setup_arch(). Otherwise, the call to
unflatten(_and_copy)?_device_tree() will create an empty root node.

We make of_have_populated_dt() return true only if the DTB was loaded by
firmware so that existing callers don't change behavior after this
patch. The call in the of platform code is removed because it prevents
overlays from creating platform devices when the empty root node is
used.

Signed-off-by: Frank Rowand <frowand.list at gmail.com>
Link: https://lore.kernel.org/r/20230317053415.2254616-2-frowand.list at gmail.com
Cc: Rob Herring <robh+dt at kernel.org>
[sboyd at kernel.org: Update of_have_populated_dt() to treat this empty dtb
as not populated. Drop setup_of() initcall]
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 drivers/of/Kconfig        |  5 ++---
 drivers/of/Makefile       |  2 +-
 drivers/of/empty_root.dts |  6 ++++++
 drivers/of/fdt.c          | 32 +++++++++++++++++++++++++++++++-
 drivers/of/platform.c     |  3 ---
 include/linux/of.h        | 25 +++++++++++++++----------
 6 files changed, 55 insertions(+), 18 deletions(-)
 create mode 100644 drivers/of/empty_root.dts

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index da9826accb1b..d738fbad9c36 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -14,9 +14,8 @@ if OF
 
 config OF_UNITTEST
 	bool "Device Tree runtime unit tests"
-	depends on !SPARC
+	depends on OF_EARLY_FLATTREE
 	select IRQ_DOMAIN
-	select OF_EARLY_FLATTREE
 	select OF_RESOLVE
 	help
 	  This option builds in test cases for the device tree infrastructure
@@ -54,7 +53,7 @@ config OF_FLATTREE
 	select CRC32
 
 config OF_EARLY_FLATTREE
-	bool
+	def_bool OF && !(SPARC || ALPHA || HEXAGON || M68K || PARISC || S390)
 	select DMA_DECLARE_COHERENT if HAS_DMA && HAS_IOMEM
 	select OF_FLATTREE
 
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index eff624854575..df305348d1cb 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -2,7 +2,7 @@
 obj-y = base.o cpu.o device.o module.o platform.o property.o
 obj-$(CONFIG_OF_KOBJ) += kobj.o
 obj-$(CONFIG_OF_DYNAMIC) += dynamic.o
-obj-$(CONFIG_OF_FLATTREE) += fdt.o
+obj-$(CONFIG_OF_FLATTREE) += fdt.o empty_root.dtb.o
 obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o
 obj-$(CONFIG_OF_PROMTREE) += pdt.o
 obj-$(CONFIG_OF_ADDRESS)  += address.o
diff --git a/drivers/of/empty_root.dts b/drivers/of/empty_root.dts
new file mode 100644
index 000000000000..cf9e97a60f48
--- /dev/null
+++ b/drivers/of/empty_root.dts
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/dts-v1/;
+
+/ {
+
+};
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index dfeba8b8ce94..e5a385285149 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -8,6 +8,7 @@
 
 #define pr_fmt(fmt)	"OF: fdt: " fmt
 
+#include <linux/acpi.h>
 #include <linux/crash_dump.h>
 #include <linux/crc32.h>
 #include <linux/kernel.h>
@@ -32,6 +33,13 @@
 
 #include "of_private.h"
 
+/*
+ * __dtb_empty_root_begin[] and __dtb_empty_root_end[] magically created by
+ * cmd_dt_S_dtb in scripts/Makefile.lib
+ */
+extern uint8_t __dtb_empty_root_begin[];
+extern uint8_t __dtb_empty_root_end[];
+
 /*
  * of_fdt_limit_memory - limit the number of regions in the /memory node
  * @limit: maximum entries
@@ -1343,7 +1351,29 @@ static void *__init copy_device_tree(void *fdt)
  */
 void __init unflatten_device_tree(void)
 {
-	__unflatten_device_tree(initial_boot_params, NULL, &of_root,
+	void *fdt = initial_boot_params;
+
+	/* Don't use the bootloader provided DTB if ACPI is enabled */
+	if (!acpi_disabled)
+		fdt = NULL;
+
+	/*
+	 * Populate an empty root node when ACPI is enabled or bootloader
+	 * doesn't provide one.
+	 */
+	if (!fdt) {
+		fdt = (void *) __dtb_empty_root_begin;
+		/* fdt_totalsize() will be used for copy size */
+		if (fdt_totalsize(fdt) >
+		    __dtb_empty_root_end - __dtb_empty_root_begin) {
+			pr_err("invalid size in dtb_empty_root\n");
+			return;
+		}
+		of_fdt_crc32 = crc32_be(~0, fdt, fdt_totalsize(fdt));
+		fdt = copy_device_tree(fdt);
+	}
+
+	__unflatten_device_tree(fdt, NULL, &of_root,
 				early_init_dt_alloc_memory_arch, false);
 
 	/* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b7708a06dc78..39c0ceee3e95 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -510,9 +510,6 @@ static int __init of_platform_default_populate_init(void)
 
 	device_links_supplier_sync_state_pause();
 
-	if (!of_have_populated_dt())
-		return -ENODEV;
-
 	if (IS_ENABLED(CONFIG_PPC)) {
 		struct device_node *boot_display = NULL;
 		struct platform_device *dev;
diff --git a/include/linux/of.h b/include/linux/of.h
index 6a9ddf20e79a..52f6ad6a1c8c 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -180,11 +180,6 @@ static inline bool is_of_node(const struct fwnode_handle *fwnode)
 			&__of_fwnode_handle_node->fwnode : NULL;	\
 	})
 
-static inline bool of_have_populated_dt(void)
-{
-	return of_root != NULL;
-}
-
 static inline bool of_node_is_root(const struct device_node *node)
 {
 	return node && (node->parent == NULL);
@@ -549,11 +544,6 @@ static inline struct device_node *of_find_node_with_property(
 
 #define of_fwnode_handle(node) NULL
 
-static inline bool of_have_populated_dt(void)
-{
-	return false;
-}
-
 static inline struct device_node *of_get_compatible_child(const struct device_node *parent,
 					const char *compatible)
 {
@@ -1634,6 +1624,21 @@ static inline bool of_device_is_system_power_controller(const struct device_node
 	return of_property_read_bool(np, "system-power-controller");
 }
 
+/**
+ * of_have_populated_dt() - Has DT been populated by bootloader
+ *
+ * Return: True if a DTB has been populated by the bootloader and it isn't the
+ * empty builtin one. False otherwise.
+ */
+static inline bool of_have_populated_dt(void)
+{
+#ifdef CONFIG_OF
+	return of_property_present(of_root, "compatible");
+#else
+	return false;
+#endif
+}
+
 /*
  * Overlay support
  */
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb 16 17:05:53 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 16 Feb 2024 17:05:53 -0800
Subject: [PATCH v4 4/7] x86/of: Unconditionally call unflatten_and_copy_device_tree()
In-Reply-To: <20240217010557.2381548-1-sboyd@kernel.org>
References: <20240217010557.2381548-1-sboyd@kernel.org>
Message-ID: <20240217010557.2381548-5-sboyd@kernel.org>

Call this function unconditionally so that we can populate an empty DTB
on platforms that don't boot with a firmware provided or builtin DTB.
There's no harm in calling unflatten_device_tree() unconditionally here.
If there isn't a non-NULL 'initial_boot_params' pointer then
unflatten_device_tree() returns early.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list at gmail.com>
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: <x86 at kernel.org>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Tested-by: Saurabh Sengar <ssengar at linux.microsoft.com>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 arch/x86/kernel/devicetree.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index afd09924094e..650752d112a6 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -283,22 +283,24 @@ void __init x86_flattree_get_config(void)
 	u32 size, map_len;
 	void *dt;
 
-	if (!initial_dtb)
-		return;
+	if (initial_dtb) {
+		map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
 
-	map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
+		dt = early_memremap(initial_dtb, map_len);
+		size = fdt_totalsize(dt);
+		if (map_len < size) {
+			early_memunmap(dt, map_len);
+			dt = early_memremap(initial_dtb, size);
+			map_len = size;
+		}
 
-	dt = early_memremap(initial_dtb, map_len);
-	size = fdt_totalsize(dt);
-	if (map_len < size) {
-		early_memunmap(dt, map_len);
-		dt = early_memremap(initial_dtb, size);
-		map_len = size;
+		early_init_dt_verify(dt);
 	}
 
-	early_init_dt_verify(dt);
 	unflatten_and_copy_device_tree();
-	early_memunmap(dt, map_len);
+
+	if (initial_dtb)
+		early_memunmap(dt, map_len);
 }
 #endif
 
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb 16 17:05:54 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 16 Feb 2024 17:05:54 -0800
Subject: [PATCH v4 5/7] arm64: Unconditionally call unflatten_device_tree()
In-Reply-To: <20240217010557.2381548-1-sboyd@kernel.org>
References: <20240217010557.2381548-1-sboyd@kernel.org>
Message-ID: <20240217010557.2381548-6-sboyd@kernel.org>

Call this function unconditionally so that we can populate an empty DTB
on platforms that don't boot with a firmware provided or builtin DTB.
When ACPI is in use, unflatten_device_tree() ignores the
'initial_boot_params' pointer so the live DT on those systems won't be
whatever that's pointing to. Similarly, when kexec copies the DT data
the previous kernel to the new one on ACPI systems,
of_kexec_alloc_and_setup_fdt() will ignore the live DT (the empty root
one) and copy the 'initial_boot_params' data.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list 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: <linux-arm-kernel at lists.infradead.org>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 arch/arm64/kernel/setup.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 42c690bb2d60..0d210720d47d 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -351,8 +351,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 	/* Parse the ACPI tables for possible boot-time configuration */
 	acpi_boot_table_init();
 
-	if (acpi_disabled)
-		unflatten_device_tree();
+	unflatten_device_tree();
 
 	bootmem_init();
 
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb 16 17:05:55 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 16 Feb 2024 17:05:55 -0800
Subject: [PATCH v4 6/7] of: unittest: treat missing of_root as error instead of fixing up
In-Reply-To: <20240217010557.2381548-1-sboyd@kernel.org>
References: <20240217010557.2381548-1-sboyd@kernel.org>
Message-ID: <20240217010557.2381548-7-sboyd@kernel.org>

From: Frank Rowand <frowand.list at gmail.com>

unflatten_device_tree() now ensures that the 'of_root' node is populated
with the root of a default empty devicetree. Remove the unittest code
that created 'of_root' if it was missing. Verify that 'of_root' is valid
before attempting to attach the testcase-data subtree. Remove the
unittest code that unflattens the unittest overlay base if architecture
is UML because that is always done now.

Signed-off-by: Frank Rowand <frowand.list at gmail.com>
Link: https://lore.kernel.org/r/20230317053415.2254616-3-frowand.list at gmail.com
Cc: Rob Herring <robh+dt at kernel.org>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 drivers/of/unittest.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 891752a20a5f..4c67de37bf26 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -1744,20 +1744,16 @@ static int __init unittest_data_add(void)
 		return -EINVAL;
 	}
 
+	/* attach the sub-tree to live tree */
 	if (!of_root) {
-		of_root = unittest_data_node;
-		for_each_of_allnodes(np)
-			__of_attach_node_sysfs(np);
-		of_aliases = of_find_node_by_path("/aliases");
-		of_chosen = of_find_node_by_path("/chosen");
-		of_overlay_mutex_unlock();
-		return 0;
+		pr_warn("%s: no live tree to attach sub-tree\n", __func__);
+		kfree(unittest_data);
+		return -ENODEV;
 	}
 
 	EXPECT_BEGIN(KERN_INFO,
 		     "Duplicate name in testcase-data, renamed to \"duplicate-name#1\"");
 
-	/* attach the sub-tree to live tree */
 	np = unittest_data_node->child;
 	while (np) {
 		struct device_node *next = np->sibling;
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb 16 17:05:49 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 16 Feb 2024 17:05:49 -0800
Subject: [PATCH v4 0/7] of: populate of_root node if bootloader doesn't
Message-ID: <20240217010557.2381548-1-sboyd@kernel.org>

Arch maintainers, please ack/review patches.

This is a resend of a series from Frank last year[1]. I worked in Rob's
review comments to unconditionally call unflatten_device_tree() and
fixup/audit calls to of_have_populated_dt() so that behavior doesn't
change.

I need this series so I can add DT based tests in the clk framework.
Either I can merge it through the clk tree once everyone is happy, or
Rob can merge it through the DT tree and provide some branch so I can
base clk patches on it.

Changes from v3 (https://lore.kernel.org/r/20240202195909.3458162-1-sboyd at kernel.org):
 * Made OF_UNITTEST depend on OF_EARLY_FLATREE
 * Made OF_EARLY_FLATREE depend on absence of arches that don't call
   unflatten_device_tree()
 * Added of_ prefix to dtb_ prefixed KUnit tests
 * Picked up tags

Changes from v2 (https://lore.kernel.org/r/20240130004508.1700335-1-sboyd at kernel.org):
 * Reorder patches to have OF changes largely first
 * No longer modify initial_boot_params if ACPI=y
 * Put arm64 patch back to v1

Changes from v1 (https://lore.kernel.org/r/20240112200750.4062441-1-sboyd at kernel.org):
 * x86 patch included
 * arm64 knocks out initial dtb if acpi is in use
 * keep Kconfig hidden but def_bool enabled otherwise

Changes from Frank's series[1]:
 * Add a DTB loaded kunit test
 * Make of_have_populated_dt() return false if the DTB isn't from the
   bootloader
 * Architecture calls made unconditional so that a root node is always
   made

Frank Rowand (2):
  of: Create of_root if no dtb provided by firmware
  of: unittest: treat missing of_root as error instead of fixing up

Stephen Boyd (5):
  of: Always unflatten in unflatten_and_copy_device_tree()
  um: Unconditionally call unflatten_device_tree()
  x86/of: Unconditionally call unflatten_and_copy_device_tree()
  arm64: Unconditionally call unflatten_device_tree()
  of: Add KUnit test to confirm DTB is loaded

 arch/arm64/kernel/setup.c    |  3 +-
 arch/um/kernel/dtb.c         | 14 ++++----
 arch/x86/kernel/devicetree.c | 24 +++++++-------
 drivers/of/.kunitconfig      |  3 ++
 drivers/of/Kconfig           | 14 ++++++--
 drivers/of/Makefile          |  4 ++-
 drivers/of/empty_root.dts    |  6 ++++
 drivers/of/fdt.c             | 64 +++++++++++++++++++++++++++---------
 drivers/of/of_test.c         | 57 ++++++++++++++++++++++++++++++++
 drivers/of/platform.c        |  3 --
 drivers/of/unittest.c        | 16 +++------
 include/linux/of.h           | 25 ++++++++------
 12 files changed, 168 insertions(+), 65 deletions(-)
 create mode 100644 drivers/of/.kunitconfig
 create mode 100644 drivers/of/empty_root.dts
 create mode 100644 drivers/of/of_test.c

[1] https://lore.kernel.org/r/20230317053415.2254616-1-frowand.list at gmail.com

base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb 16 17:05:52 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 16 Feb 2024 17:05:52 -0800
Subject: [PATCH v4 3/7] um: Unconditionally call unflatten_device_tree()
In-Reply-To: <20240217010557.2381548-1-sboyd@kernel.org>
References: <20240217010557.2381548-1-sboyd@kernel.org>
Message-ID: <20240217010557.2381548-4-sboyd@kernel.org>

Call this function unconditionally so that we can populate an empty DTB
on platforms that don't boot with a command line provided DTB.  There's
no harm in calling unflatten_device_tree() unconditionally. If there
isn't a valid initial_boot_params dtb then unflatten_device_tree()
returns early.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list at gmail.com>
Cc: Richard Weinberger <richard at nod.at>
Cc: Anton Ivanov <anton.ivanov at cambridgegreys.com>
Cc: Johannes Berg <johannes at sipsolutions.net>
Cc: <linux-um at lists.infradead.org>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 arch/um/kernel/dtb.c  | 14 +++++++-------
 drivers/of/unittest.c |  4 ----
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/arch/um/kernel/dtb.c b/arch/um/kernel/dtb.c
index 484141b06938..4954188a6a09 100644
--- a/arch/um/kernel/dtb.c
+++ b/arch/um/kernel/dtb.c
@@ -16,16 +16,16 @@ void uml_dtb_init(void)
 	void *area;
 
 	area = uml_load_file(dtb, &size);
-	if (!area)
-		return;
+	if (area) {
+		if (!early_init_dt_scan(area)) {
+			pr_err("invalid DTB %s\n", dtb);
+			memblock_free(area, size);
+			return;
+		}
 
-	if (!early_init_dt_scan(area)) {
-		pr_err("invalid DTB %s\n", dtb);
-		memblock_free(area, size);
-		return;
+		early_init_fdt_scan_reserved_mem();
 	}
 
-	early_init_fdt_scan_reserved_mem();
 	unflatten_device_tree();
 }
 
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index cfd60e35a899..891752a20a5f 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -4087,10 +4087,6 @@ static int __init of_unittest(void)
 	add_taint(TAINT_TEST, LOCKDEP_STILL_OK);
 
 	/* adding data for unittest */
-
-	if (IS_ENABLED(CONFIG_UML))
-		unittest_unflatten_overlay_base();
-
 	res = unittest_data_add();
 	if (res)
 		return res;
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From sboyd at kernel.org  Fri Feb 16 17:05:56 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 16 Feb 2024 17:05:56 -0800
Subject: [PATCH v4 7/7] of: Add KUnit test to confirm DTB is loaded
In-Reply-To: <20240217010557.2381548-1-sboyd@kernel.org>
References: <20240217010557.2381548-1-sboyd@kernel.org>
Message-ID: <20240217010557.2381548-8-sboyd@kernel.org>

Add a KUnit test that confirms a DTB has been loaded, i.e. there is a
root node, and that the of_have_populated_dt() API works properly. We
skip the test when CONFIG_OF_EARLY_FLATREE=n because in that case we
know architecture code hasn't called unflatten_(and_copy_)?device_tree()
which would populate some sort of root node.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list at gmail.com>
Reviewed-by: David Gow <davidgow at google.com>
Cc: Brendan Higgins <brendan.higgins at linux.dev>
Signed-off-by: Stephen Boyd <sboyd at kernel.org>
---
 drivers/of/.kunitconfig |  3 +++
 drivers/of/Kconfig      |  9 +++++++
 drivers/of/Makefile     |  2 ++
 drivers/of/of_test.c    | 57 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 71 insertions(+)
 create mode 100644 drivers/of/.kunitconfig
 create mode 100644 drivers/of/of_test.c

diff --git a/drivers/of/.kunitconfig b/drivers/of/.kunitconfig
new file mode 100644
index 000000000000..5a8fee11978c
--- /dev/null
+++ b/drivers/of/.kunitconfig
@@ -0,0 +1,3 @@
+CONFIG_KUNIT=y
+CONFIG_OF=y
+CONFIG_OF_KUNIT_TEST=y
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index d738fbad9c36..dd726c7056bf 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -36,6 +36,15 @@ config OF_UNITTEST
 
 	  If unsure, say N here. This option is not safe to enable.
 
+config OF_KUNIT_TEST
+	tristate "Devicetree KUnit Test" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  This option builds KUnit unit tests for device tree infrastructure.
+
+	  If unsure, say N here, but this option is safe to enable.
+
 config OF_ALL_DTBS
 	bool "Build all Device Tree Blobs"
 	depends on COMPILE_TEST
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index df305348d1cb..251d33532148 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -19,4 +19,6 @@ obj-y	+= kexec.o
 endif
 endif
 
+obj-$(CONFIG_OF_KUNIT_TEST) += of_test.o
+
 obj-$(CONFIG_OF_UNITTEST) += unittest-data/
diff --git a/drivers/of/of_test.c b/drivers/of/of_test.c
new file mode 100644
index 000000000000..a9301d293f01
--- /dev/null
+++ b/drivers/of/of_test.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit tests for OF APIs
+ */
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include <kunit/test.h>
+
+/*
+ * Test that the root node "/" can be found by path.
+ */
+static void of_dtb_root_node_found_by_path(struct kunit *test)
+{
+	struct device_node *np;
+
+	np = of_find_node_by_path("/");
+	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, np);
+	of_node_put(np);
+}
+
+/*
+ * Test that the 'of_root' global variable is always populated when DT code is
+ * enabled. Remove this test once of_root is removed from global access.
+ */
+static void of_dtb_root_node_populates_of_root(struct kunit *test)
+{
+	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, of_root);
+}
+
+static struct kunit_case of_dtb_test_cases[] = {
+	KUNIT_CASE(of_dtb_root_node_found_by_path),
+	KUNIT_CASE(of_dtb_root_node_populates_of_root),
+	{}
+};
+
+static int of_dtb_test_init(struct kunit *test)
+{
+	if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE))
+		kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE");
+
+	return 0;
+}
+
+/*
+ * Test suite to confirm a DTB is loaded.
+ */
+static struct kunit_suite of_dtb_suite = {
+	.name = "of_dtb",
+	.test_cases = of_dtb_test_cases,
+	.init = of_dtb_test_init,
+};
+
+kunit_test_suites(
+	&of_dtb_suite,
+);
+MODULE_LICENSE("GPL");
-- 
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git



From irogers at google.com  Fri Feb 16 17:33:00 2024
From: irogers at google.com (Ian Rogers)
Date: Fri, 16 Feb 2024 17:33:00 -0800
Subject: [PATCH v3 3/8] perf arm-spe/cs-etm: Directly iterate CPU maps
In-Reply-To: <CAM9d7chPqFGEih7z7rp=eS5P30gSMvG=6fi=0QqT=EdfdMOH_A@mail.gmail.com>
References: <20240202234057.2085863-1-irogers@google.com> <20240202234057.2085863-4-irogers@google.com>
 <CAM9d7chPqFGEih7z7rp=eS5P30gSMvG=6fi=0QqT=EdfdMOH_A@mail.gmail.com>
Message-ID: <CAP-5=fXzqF--KUOo1awmxDewupF-r_a2=yFC75tuGasNE-WpXg@mail.gmail.com>

On Fri, Feb 16, 2024 at 5:02?PM Namhyung Kim <namhyung at kernel.org> wrote:
>
> On Fri, Feb 2, 2024 at 3:41?PM Ian Rogers <irogers at google.com> wrote:
> >
> > Rather than iterate all CPUs and see if they are in CPU maps, directly
> > iterate the CPU map. Similarly make use of the intersect function
> > taking care for when "any" CPU is specified. Switch
> > perf_cpu_map__has_any_cpu_or_is_empty to more appropriate
> > alternatives.
> >
> > Signed-off-by: Ian Rogers <irogers at google.com>
> > ---
> >  tools/perf/arch/arm/util/cs-etm.c    | 114 ++++++++++++---------------
> >  tools/perf/arch/arm64/util/arm-spe.c |   4 +-
> >  2 files changed, 51 insertions(+), 67 deletions(-)
> >
> > diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> > index 77e6663c1703..07be32d99805 100644
> > --- a/tools/perf/arch/arm/util/cs-etm.c
> > +++ b/tools/perf/arch/arm/util/cs-etm.c
> > @@ -197,38 +197,37 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr,
> >  static int cs_etm_validate_config(struct auxtrace_record *itr,
> >                                   struct evsel *evsel)
> >  {
> > -       int i, err = -EINVAL;
> > +       int idx, err = 0;
> >         struct perf_cpu_map *event_cpus = evsel->evlist->core.user_requested_cpus;
> > -       struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
> > -
> > -       /* Set option of each CPU we have */
> > -       for (i = 0; i < cpu__max_cpu().cpu; i++) {
> > -               struct perf_cpu cpu = { .cpu = i, };
> > +       struct perf_cpu_map *intersect_cpus;
> > +       struct perf_cpu cpu;
> >
> > -               /*
> > -                * In per-cpu case, do the validation for CPUs to work with.
> > -                * In per-thread case, the CPU map is empty.  Since the traced
> > -                * program can run on any CPUs in this case, thus don't skip
> > -                * validation.
> > -                */
> > -               if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus) &&
> > -                   !perf_cpu_map__has(event_cpus, cpu))
> > -                       continue;
> > +       /*
> > +        * Set option of each CPU we have. In per-cpu case, do the validation
> > +        * for CPUs to work with. In per-thread case, the CPU map has the "any"
> > +        * CPU value. Since the traced program can run on any CPUs in this case,
> > +        * thus don't skip validation.
> > +        */
> > +       if (!perf_cpu_map__has_any_cpu(event_cpus)) {
> > +               struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
> >
> > -               if (!perf_cpu_map__has(online_cpus, cpu))
> > -                       continue;
> > +               intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
> > +               perf_cpu_map__put(online_cpus);
> > +       } else {
> > +               intersect_cpus = perf_cpu_map__new_online_cpus();
> > +       }
>
> Would it be ok if any of these operations fail?  I believe the
> cpu map functions work well with NULL already.

If the allocation fails then the loop below won't iterate (the map
will be empty). The map is released and not used elsewhere in the
code. An allocation failure here won't cause the code to crash, but
there are other places where the code assumes what the properties of
having done this function are and they won't be working as intended.
It's not uncommon to see ENOMEM to just be abort for this reason.

Thanks,
Ian

> Thanks,
> Namhyung
>
> >
> > -               err = cs_etm_validate_context_id(itr, evsel, i);
> > +       perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
> > +               err = cs_etm_validate_context_id(itr, evsel, cpu.cpu);
> >                 if (err)
> > -                       goto out;
> > -               err = cs_etm_validate_timestamp(itr, evsel, i);
> > +                       break;
> > +
> > +               err = cs_etm_validate_timestamp(itr, evsel, cpu.cpu);
> >                 if (err)
> > -                       goto out;
> > +                       break;
> >         }
> >
> > -       err = 0;
> > -out:
> > -       perf_cpu_map__put(online_cpus);
> > +       perf_cpu_map__put(intersect_cpus);
> >         return err;
> >  }
> >
> > @@ -435,7 +434,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
> >          * Also the case of per-cpu mmaps, need the contextID in order to be notified
> >          * when a context switch happened.
> >          */
> > -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> > +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
> >                 evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
> >                                            "timestamp", 1);
> >                 evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
> > @@ -461,7 +460,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
> >         evsel->core.attr.sample_period = 1;
> >
> >         /* In per-cpu case, always need the time of mmap events etc */
> > -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus))
> > +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
> >                 evsel__set_sample_bit(evsel, TIME);
> >
> >         err = cs_etm_validate_config(itr, cs_etm_evsel);
> > @@ -533,45 +532,31 @@ static size_t
> >  cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
> >                       struct evlist *evlist __maybe_unused)
> >  {
> > -       int i;
> > +       int idx;
> >         int etmv3 = 0, etmv4 = 0, ete = 0;
> >         struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus;
> > -       struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
> > -
> > -       /* cpu map is not empty, we have specific CPUs to work with */
> > -       if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
> > -               for (i = 0; i < cpu__max_cpu().cpu; i++) {
> > -                       struct perf_cpu cpu = { .cpu = i, };
> > +       struct perf_cpu_map *intersect_cpus;
> > +       struct perf_cpu cpu;
> >
> > -                       if (!perf_cpu_map__has(event_cpus, cpu) ||
> > -                           !perf_cpu_map__has(online_cpus, cpu))
> > -                               continue;
> > +       if (!perf_cpu_map__has_any_cpu(event_cpus)) {
> > +               /* cpu map is not "any" CPU , we have specific CPUs to work with */
> > +               struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
> >
> > -                       if (cs_etm_is_ete(itr, i))
> > -                               ete++;
> > -                       else if (cs_etm_is_etmv4(itr, i))
> > -                               etmv4++;
> > -                       else
> > -                               etmv3++;
> > -               }
> > +               intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
> > +               perf_cpu_map__put(online_cpus);
> >         } else {
> > -               /* get configuration for all CPUs in the system */
> > -               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))
> > -                               ete++;
> > -                       else if (cs_etm_is_etmv4(itr, i))
> > -                               etmv4++;
> > -                       else
> > -                               etmv3++;
> > -               }
> > +               /* Event can be "any" CPU so count all online CPUs. */
> > +               intersect_cpus = perf_cpu_map__new_online_cpus();
> >         }
> > -
> > -       perf_cpu_map__put(online_cpus);
> > +       perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
> > +               if (cs_etm_is_ete(itr, cpu.cpu))
> > +                       ete++;
> > +               else if (cs_etm_is_etmv4(itr, cpu.cpu))
> > +                       etmv4++;
> > +               else
> > +                       etmv3++;
> > +       }
> > +       perf_cpu_map__put(intersect_cpus);
> >
> >         return (CS_ETM_HEADER_SIZE +
> >                (ete   * CS_ETE_PRIV_SIZE) +
> > @@ -813,16 +798,15 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
> >         if (!session->evlist->core.nr_mmaps)
> >                 return -EINVAL;
> >
> > -       /* If the cpu_map is empty all online CPUs are involved */
> > -       if (perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
> > +       /* If the cpu_map has the "any" CPU all online CPUs are involved */
> > +       if (perf_cpu_map__has_any_cpu(event_cpus)) {
> >                 cpu_map = online_cpus;
> >         } else {
> >                 /* Make sure all specified CPUs are online */
> > -               for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) {
> > -                       struct perf_cpu cpu = { .cpu = i, };
> > +               struct perf_cpu cpu;
> >
> > -                       if (perf_cpu_map__has(event_cpus, cpu) &&
> > -                           !perf_cpu_map__has(online_cpus, cpu))
> > +               perf_cpu_map__for_each_cpu(cpu, i, event_cpus) {
> > +                       if (!perf_cpu_map__has(online_cpus, cpu))
> >                                 return -EINVAL;
> >                 }
> >
> > diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
> > index 51ccbfd3d246..0b52e67edb3b 100644
> > --- a/tools/perf/arch/arm64/util/arm-spe.c
> > +++ b/tools/perf/arch/arm64/util/arm-spe.c
> > @@ -232,7 +232,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
> >          * In the case of per-cpu mmaps, sample CPU for AUX event;
> >          * also enable the timestamp tracing for samples correlation.
> >          */
> > -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> > +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
> >                 evsel__set_sample_bit(arm_spe_evsel, CPU);
> >                 evsel__set_config_if_unset(arm_spe_pmu, arm_spe_evsel,
> >                                            "ts_enable", 1);
> > @@ -265,7 +265,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
> >         tracking_evsel->core.attr.sample_period = 1;
> >
> >         /* In per-cpu case, always need the time of mmap events etc */
> > -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
> > +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
> >                 evsel__set_sample_bit(tracking_evsel, TIME);
> >                 evsel__set_sample_bit(tracking_evsel, CPU);
> >
> > --
> > 2.43.0.594.gd9cf4e227d-goog
> >


From syzbot+f1ceaa1a09ab891e1934 at syzkaller.appspotmail.com  Fri Feb 16 17:35:26 2024
From: syzbot+f1ceaa1a09ab891e1934 at syzkaller.appspotmail.com (syzbot)
Date: Fri, 16 Feb 2024 17:35:26 -0800
Subject: [syzbot] [arm?] [crypto?] KASAN: invalid-access Read in neon_aes_ctr_encrypt
Message-ID: <000000000000ff2c3f061189df71@google.com>

Hello,

syzbot found the following issue on:

HEAD commit:    c664e16bb1ba Merge tag 'docs-6.8-fixes2' of git://git.lwn...
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=13e83cc8180000
kernel config:  https://syzkaller.appspot.com/x/.config?x=b4dde08ba7d52a4b
dashboard link: https://syzkaller.appspot.com/bug?extid=f1ceaa1a09ab891e1934
compiler:       aarch64-linux-gnu-gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
userspace arch: arm64
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=13fff792180000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=15cbe4dc180000

Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/384ffdcca292/non_bootable_disk-c664e16b.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/864da5a66121/vmlinux-c664e16b.xz
kernel image: https://storage.googleapis.com/syzbot-assets/044de3e4ddc5/Image-c664e16b.gz.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+f1ceaa1a09ab891e1934 at syzkaller.appspotmail.com

==================================================================
BUG: KASAN: invalid-access in neon_aes_ctr_encrypt+0x15c/0x1ec arch/arm64/crypto/aes-modes.S:599
Read at addr fcff000006797ff1 by task syz-executor675/3149
Pointer tag: [fc], memory tag: [fe]

CPU: 1 PID: 3149 Comm: syz-executor675 Not tainted 6.8.0-rc4-syzkaller-00005-gc664e16bb1ba #0
Hardware name: linux,dummy-virt (DT)
Call trace:
 dump_backtrace+0x94/0xec arch/arm64/kernel/stacktrace.c:291
 show_stack+0x18/0x24 arch/arm64/kernel/stacktrace.c:298
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0x48/0x60 lib/dump_stack.c:106
 print_address_description mm/kasan/report.c:377 [inline]
 print_report+0x108/0x618 mm/kasan/report.c:488
 kasan_report+0x88/0xac mm/kasan/report.c:601
 report_tag_fault arch/arm64/mm/fault.c:334 [inline]
 do_tag_recovery arch/arm64/mm/fault.c:346 [inline]
 __do_kernel_fault+0x17c/0x1e8 arch/arm64/mm/fault.c:393
 do_bad_area arch/arm64/mm/fault.c:493 [inline]
 do_tag_check_fault+0x78/0x8c arch/arm64/mm/fault.c:772
 do_mem_abort+0x44/0x94 arch/arm64/mm/fault.c:848
 el1_abort+0x40/0x60 arch/arm64/kernel/entry-common.c:398
 el1h_64_sync_handler+0xd8/0xe4 arch/arm64/kernel/entry-common.c:458
 el1h_64_sync+0x64/0x68 arch/arm64/kernel/entry.S:593
 neon_aes_ctr_encrypt+0x15c/0x1ec arch/arm64/crypto/aes-modes.S:599
 ctr_encrypt+0xfc/0x144 arch/arm64/crypto/aes-neonbs-glue.c:230
 crypto_skcipher_decrypt+0x4c/0x60 crypto/skcipher.c:695
 _skcipher_recvmsg crypto/algif_skcipher.c:199 [inline]
 skcipher_recvmsg+0x39c/0x46c crypto/algif_skcipher.c:221
 sock_recvmsg_nosec net/socket.c:1046 [inline]
 sock_recvmsg net/socket.c:1068 [inline]
 sock_recvmsg net/socket.c:1064 [inline]
 sock_read_iter+0xec/0x118 net/socket.c:1138
 call_read_iter include/linux/fs.h:2079 [inline]
 new_sync_read fs/read_write.c:395 [inline]
 vfs_read+0x2cc/0x304 fs/read_write.c:476
 ksys_read+0xe8/0x104 fs/read_write.c:619
 __do_sys_read fs/read_write.c:629 [inline]
 __se_sys_read fs/read_write.c:627 [inline]
 __arm64_sys_read+0x1c/0x28 fs/read_write.c:627
 __invoke_syscall arch/arm64/kernel/syscall.c:37 [inline]
 invoke_syscall+0x48/0x114 arch/arm64/kernel/syscall.c:51
 el0_svc_common.constprop.0+0x40/0xe0 arch/arm64/kernel/syscall.c:136
 do_el0_svc+0x1c/0x28 arch/arm64/kernel/syscall.c:155
 el0_svc+0x34/0xd8 arch/arm64/kernel/entry-common.c:678
 el0t_64_sync_handler+0x100/0x12c arch/arm64/kernel/entry-common.c:696
 el0t_64_sync+0x19c/0x1a0 arch/arm64/kernel/entry.S:598

The buggy address belongs to the physical page:
page:0000000060acabc6 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x46797
flags: 0x1ffc28000000000(node=0|zone=0|lastcpupid=0x7ff|kasantag=0xa)
page_type: 0xffffffff()
raw: 01ffc28000000000 fffffc0000168bc8 fffffc0000199e08 0000000000000000
raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff000006797d00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
 ffff000006797e00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
>ffff000006797f00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
                                                                ^
 ffff000006798000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff000006798100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller at googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup


From apatel at ventanamicro.com  Fri Feb 16 21:42:29 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sat, 17 Feb 2024 11:12:29 +0530
Subject: [PATCH v12 14/25] irqchip/sifive-plic: Convert PLIC driver into a
 platform driver
In-Reply-To: <878r3kcg7e.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-15-apatel@ventanamicro.com> <87jzn4ctks.ffs@tglx>
 <CAAhSdy2aeyJBcMVre12jGwU52oP9Z=1emB-bcYxygdR3QhP+6w@mail.gmail.com> <878r3kcg7e.ffs@tglx>
Message-ID: <CAK9=C2WWBrUae2hduUBwuxd8=23_KO3-x1fF=BaTtxJMHVyFrg@mail.gmail.com>

On Sat, Feb 17, 2024 at 1:52?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Fri, Feb 16 2024 at 22:41, Anup Patel wrote:
> > On Fri, Feb 16, 2024 at 9:03?PM Thomas Gleixner <tglx at linutronix.de> wrote:
> >> I don't think that removing the setup protection is correct.
> >>
> >> Assume you have maxcpus=N on the kernel command line, then the above
> >> for_each_online_cpu() loop would result in cpuhp_setup == true when the
> >> instances for the not onlined CPUs are set up, no?
> >
> > A platform can have multiple PLIC instances where each PLIC
> > instance targets a subset of HARTs (or CPUs).
> >
> > Previously (before this patch), we were probing PLIC very early so on
> > a platform with multiple PLIC instances, we need to ensure that cpuhp
> > setup is done only after PLIC context associated with boot CPU is
> > initialized hence the plic_cpuhp_setup_done check.
> >
> > This patch converts PLIC driver into a platform driver so now PLIC
> > instances are probed after all available CPUs are brought-up. In this
> > case, the cpuhp setup must be done only after PLIC context of all
> > available CPUs are initialized otherwise some of the CPUs crash
> > in plic_starting_cpu() due to lack of PLIC context initialization.
>
> You're missing the point.
>
> Assume you have 8 CPUs and 2 PLIC instances one for CPU0-3 and one for
> CPU4-7.
>
> Add "maxcpus=4" on the kernel command line, then only the first 4 CPUs
> are brought up.
>
> So at probe time cpu_online_mask has bit 0,1,2,3 set.
>
> When the first PLIC it probed the loop which checks the context for each
> online CPU will not clear cpuhp_setup and the hotplug state is installed.
>
> Now the second PLIC is probed (the one for the offline CPUs 4-7) and the
> loop will again not clear cpuhp_setup and it tries to install the state
> again, no?

Ahh, yes. Good catch.

For the "maxcpus" in kernel command-line, we can't rely on the
cpu_online_mask. I will preserve the plic_cpuhp_setup_done
check in the next revision.

Regards,
Anup


From kvalo at kernel.org  Fri Feb 16 22:34:52 2024
From: kvalo at kernel.org (Kalle Valo)
Date: Sat, 17 Feb 2024 08:34:52 +0200
Subject: [PATCH v5 06/18] dt-bindings: new: wireless: describe the
 ath12k PCI module
In-Reply-To: <20240216203215.40870-7-brgl@bgdev.pl> (Bartosz Golaszewski's
	message of "Fri, 16 Feb 2024 21:32:03 +0100")
References: <20240216203215.40870-1-brgl@bgdev.pl>
	<20240216203215.40870-7-brgl@bgdev.pl>
Message-ID: <87cysvd2er.fsf@kernel.org>

Bartosz Golaszewski <brgl at bgdev.pl> writes:

> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>
> Add device-tree bindings for the ATH12K module found in the WCN7850
> package.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---
>  .../net/wireless/qcom,ath12k-pci.yaml         | 103 ++++++++++++++++++
>  1 file changed, 103 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
>
> diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
> new file mode 100644
> index 000000000000..063c576b99a0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
> @@ -0,0 +1,103 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (c) 2024 Linaro Limited
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/wireless/qcom,ath12k-pci.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm Technologies ath12k wireless devices (PCIe)
> +
> +maintainers:
> +  - Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Jeff and me are the ath12k driver maintainers so shouldn't we listed
here as well?

Jeff, this reminds me that we should add you to qcom,ath10k.yaml,
qcom,ath11k-pci.yaml and qcom,ath11k.yaml as maintainer.

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


From keescook at chromium.org  Fri Feb 16 22:50:49 2024
From: keescook at chromium.org (Kees Cook)
Date: Fri, 16 Feb 2024 22:50:49 -0800
Subject: [PATCH] mm: Revert x86_64 and arm64 ELF_ET_DYN_BASE base
In-Reply-To: <20170807201542.GA21271@beast>
References: <20170807201542.GA21271@beast>
Message-ID: <202402162238.E5D08F5968@keescook>

*extreme thread[1] necromancy*

On Mon, Aug 07, 2017 at 01:15:42PM -0700, Kees Cook wrote:
> Moving the x86_64 and arm64 PIE base from 0x555555554000 to 0x000100000000
> broke AddressSanitizer. This is a partial revert of:
> 
>   commit eab09532d400 ("binfmt_elf: use ELF_ET_DYN_BASE only for PIE")
>   commit 02445990a96e ("arm64: move ELF_ET_DYN_BASE to 4GB / 4MB")
> 
> The AddressSanitizer tool has hard-coded expectations about where
> executable mappings are loaded. The motivation for changing the PIE
> base in the above commits was to avoid the Stack-Clash CVEs that
> allowed executable mappings to get too close to heap and stack. This
> was mainly a problem on 32-bit, but the 64-bit bases were moved too,
> in an effort to proactively protect those systems (proofs of concept
> do exist that show 64-bit collisions, but other recent changes to fix
> stack accounting and setuid behaviors will minimize the impact).

I happened to be looking at this again today, and wondered where things
stood. It seems like ASan's mappings are documented here:
https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm#64-bit

This implies that it would be safe to move the ELF_ET_DYN_BASE from
0x555555554000 down to 0x200000000000, since the shadow map ends at
0x10007fff7fff. (Well, anything above there would work, I was just
picking a "round" number above it. We could just as well use
0x100080000000, I think.)

Is this correct? I'd like to open up some more room between mmap and
stack...

Thanks!

-Kees

[1] https://lore.kernel.org/lkml/20170807201542.GA21271 at beast/

> 
> The new 32-bit PIE base is fine for ASan (since it matches the ET_EXEC
> base), so only the 64-bit PIE base needs to be reverted to let x86 and
> arm64 ASan binaries run again. Future changes to the 64-bit PIE base on
> these architectures can be made optional once a more dynamic method for
> dealing with AddressSanitizer is found. (e.g. always loading PIE into
> the mmap region for marked binaries.)
> 
> Reported-by: Kostya Serebryany <kcc at google.com>
> Cc: stable at vger.kernel.org
> Signed-off-by: Kees Cook <keescook at chromium.org>
> ---
>  arch/arm64/include/asm/elf.h | 4 ++--
>  arch/x86/include/asm/elf.h   | 4 ++--
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index acae781f7359..3288c2b36731 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -114,10 +114,10 @@
>  
>  /*
>   * This is the base location for PIE (ET_DYN with INTERP) loads. On
> - * 64-bit, this is raised to 4GB to leave the entire 32-bit address
> + * 64-bit, this is above 4GB to leave the entire 32-bit address
>   * space open for things that want to use the area for 32-bit pointers.
>   */
> -#define ELF_ET_DYN_BASE		0x100000000UL
> +#define ELF_ET_DYN_BASE		(2 * TASK_SIZE_64 / 3)
>  
>  #ifndef __ASSEMBLY__
>  
> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
> index 1c18d83d3f09..9aeb91935ce0 100644
> --- a/arch/x86/include/asm/elf.h
> +++ b/arch/x86/include/asm/elf.h
> @@ -247,11 +247,11 @@ extern int force_personality32;
>  
>  /*
>   * This is the base location for PIE (ET_DYN with INTERP) loads. On
> - * 64-bit, this is raised to 4GB to leave the entire 32-bit address
> + * 64-bit, this is above 4GB to leave the entire 32-bit address
>   * space open for things that want to use the area for 32-bit pointers.
>   */
>  #define ELF_ET_DYN_BASE		(mmap_is_ia32() ? 0x000400000UL : \
> -						  0x100000000UL)
> +						  (TASK_SIZE / 3 * 2))
>  
>  /* 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,
> -- 
> 2.7.4
> 
> 
> -- 
> Kees Cook
> Pixel Security

-- 
Kees Cook


From yuanhsinte at chromium.org  Fri Feb 16 23:01:25 2024
From: yuanhsinte at chromium.org (Hsin-Te Yuan)
Date: Sat, 17 Feb 2024 15:01:25 +0800
Subject: [PATCH v3] arm64: dts: mt8195-cherry-tomato: change watchdog
 reset boot flow
In-Reply-To: <CAHc4DNKXOb54v7qJZJ2EsVP1KkMq7WnSJJLWhb2SzuhW_=qnxQ@mail.gmail.com>
References: <20240124-send-upstream-v3-1-5097c9862a73@chromium.org>
 <786c85c7-7b38-4a2a-85ec-282196de7b5e@collabora.com> <CAHc4DNKXOb54v7qJZJ2EsVP1KkMq7WnSJJLWhb2SzuhW_=qnxQ@mail.gmail.com>
Message-ID: <CAHc4DNKSj5MK5Pfi5DYm9hUqh=uxUs4S3uakqfht-3O18vgLTA@mail.gmail.com>

Hello AngeloGioacchino,

I noticed that this patch does not seem to have been landed yet.
Please let me know if there are any issues.

Thank you,
Hsin-Te


On Wed, Jan 24, 2024 at 5:04?PM Hsin-Te Yuan <yuanhsinte at chromium.org> wrote:
>
> Hi AngeloGioacchino,
>
> This bug can be triggered by stopping watchdog daemon and running
> `sleep 60 > /dev/watchdog`.
>
> Regards,
> Hsin-Te
>
>
>
> On Wed, Jan 24, 2024 at 4:27?PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno at collabora.com> wrote:
> >
> > Il 24/01/24 08:51, Hsin-Te Yuan ha scritto:
> > > From: Hsin-Te Yuan <yuanhsinte at google.com>
> > >
> > > The external output reset signal was originally disabled and sent from
> > > firmware. However, an unfixed bug in the firmware on tomato prevents
> > > the signal from being sent, causing the device to fail to boot. To fix
> > > this, enable external output reset signal to allow the device to reboot
> > > normally.
> > >
> > > Fixes: 5eb2e303ec6b ("arm64: dts: mediatek: Introduce MT8195 Cherry platform's Tomato")
> > > Signed-off-by: Hsin-Te Yuan <yuanhsinte at chromium.org>
> >
> > Can't trigger the bug, but also this commit gives no side effects, so:
> >
> > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> >
> >
> > > ---
> > > Changes in v3:
> > > - Add Fixes tag
> > >
> > > Changes in v2:
> > > - Limit the effect only on tomato.
> > > ---
> > >   arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts | 4 ++++
> > >   arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts | 4 ++++
> > >   arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts | 4 ++++
> > >   3 files changed, 12 insertions(+)
> > >
> > > diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
> > > index 2d5e8f371b6de..a82d716f10d44 100644
> > > --- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
> > > +++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
> > > @@ -23,3 +23,7 @@ &sound {
> > >   &ts_10 {
> > >       status = "okay";
> > >   };
> > > +
> > > +&watchdog {
> > > +     /delete-property/ mediatek,disable-extrst;
> > > +};
> > > diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
> > > index 2586c32ce6e6f..2fe20e0dad836 100644
> > > --- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
> > > +++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
> > > @@ -43,3 +43,7 @@ &sound {
> > >   &ts_10 {
> > >       status = "okay";
> > >   };
> > > +
> > > +&watchdog {
> > > +     /delete-property/ mediatek,disable-extrst;
> > > +};
> > > diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
> > > index f54f9477b99da..dd294ca98194c 100644
> > > --- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
> > > +++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
> > > @@ -44,3 +44,7 @@ &sound {
> > >   &ts_10 {
> > >       status = "okay";
> > >   };
> > > +
> > > +&watchdog {
> > > +     /delete-property/ mediatek,disable-extrst;
> > > +};
> > >
> > > ---
> > > base-commit: 64b50fcb03649ca7f0d762a50e7a3484cfc1d586
> > > change-id: 20230818-send-upstream-e91e615a893c
> > >
> > > Best regards,
> >


From gregkh at linuxfoundation.org  Fri Feb 16 23:59:07 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Sat, 17 Feb 2024 08:59:07 +0100
Subject: [PATCH] Staging: vc04_services: bcm2835-camera: fixed several
 brace coding style checks
In-Reply-To: <20240215220647.4096-1-mo.c.weber@gmail.com>
References: <20240215220647.4096-1-mo.c.weber@gmail.com>
Message-ID: <2024021727-maritime-barterer-f536@gregkh>

On Thu, Feb 15, 2024 at 11:06:47PM +0100, Moritz C. Weber wrote:
> Fixed coding style checks raised by checkpatch
> 
> Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
> ---
>  .../bcm2835-camera/bcm2835-camera.c           | 62 +++++++++----------
>  1 file changed, 29 insertions(+), 33 deletions(-)

Hi,

This is the friendly patch-bot of Greg Kroah-Hartman.  You have sent him
a patch that has triggered this response.  He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created.  Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.

You are receiving this message because of the following common error(s)
as indicated below:

- Your patch did many different things all at once, making it difficult
  to review.  All Linux kernel patches need to only do one thing at a
  time.  If you need to do multiple things (such as clean up all coding
  style issues in a file/driver), do it in a sequence of patches, each
  one doing only one thing.  This will make it easier to review the
  patches to ensure that they are correct, and to help alleviate any
  merge issues that larger patches can cause.

- You did not specify a description of why the patch is needed, or
  possibly, any description at all, in the email body.  Please read the
  section entitled "The canonical patch format" in the kernel file,
  Documentation/process/submitting-patches.rst for what is needed in
  order to properly describe the change.

If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.

thanks,

greg k-h's patch email bot


From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:17:53 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:17:53 +0100
Subject: [PATCH 1/4] clk: rockchip: rst-rk3588: Add BIU reset
In-Reply-To: <30d2-65cf5980-3-2ec9f500@242931553>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
 <20240216094922.257674-2-shreeya.patel@collabora.com>
 <237e690a-2f49-4046-b054-3a878eed6748@linaro.org>
 <30d2-65cf5980-3-2ec9f500@242931553>
Message-ID: <0c2f4d92-afa9-46f1-844e-994bd45924ef@linaro.org>

On 16/02/2024 13:48, Shreeya Patel wrote:
> On Friday, February 16, 2024 15:33 IST, Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:
> 
>> On 16/02/2024 10:49, Shreeya Patel wrote:
>>> Export hdmirx_biu soft reset id which is required by the hdmirx controller.
>>>
>>> Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
>>> ---
>>>  drivers/clk/rockchip/rst-rk3588.c               | 1 +
>>>  include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++
>>
>> Please run scripts/checkpatch.pl and fix reported warnings. Some
>> warnings can be ignored, but the code here looks like it needs a fix.
>> Feel free to get in touch if the warning is not clear.
>>
>> Please do internal review. The internal Collabora review would tell you:
>> YOU MUST run checkpatch. Then you see errors, so why do you send patch
>> with errors to the mailing list?
>>
> 
> I am sorry but what errors are you talking about?
> I don't see any errors reported by checkpatch :-
> 
> shreeya at shreeya:~/collabora/rd/rockchip/torvalds$ ./scripts/checkpatch.pl hdmirx/0001-clk-rockchip-rst-rk3588-Add-BIU-reset.patch
> WARNING: DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst

Here.

> 
> total: 0 errors, 1 warnings, 13 lines checked
> 
> NOTE: For some of the reported defects, checkpatch may be able to
>       mechanically convert to the typical style using --fix or --fix-inplace.
> 
> hdmirx-v1-1602/0001-clk-rockchip-rst-rk3588-Add-BIU-reset.patch has style problems, please review.
> 
> I see the above warning but that looks like a false positive to me.

Why for your patch it would be false positive and for all others would not?

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:18:33 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:18:33 +0100
Subject: [PATCH v2 2/4] dt-bindings: net: fec: add iommus property
In-Reply-To: <Zc+2EitZrVzLsA03@lizhi-Precision-Tower-5810>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240201-8qm_smmu-v2-2-3d12a80201a3@nxp.com>
 <49dbd0a2-a4b9-4c05-bb10-44f267672374@linaro.org>
 <Zc+2EitZrVzLsA03@lizhi-Precision-Tower-5810>
Message-ID: <668c1511-4ee6-4fad-9b7e-7783b6853988@linaro.org>

On 16/02/2024 20:22, Frank Li wrote:
> On Fri, Feb 02, 2024 at 09:23:37AM +0100, Krzysztof Kozlowski wrote:
>> On 01/02/2024 21:22, Frank Li wrote:
>>> iMX8QM have iommu. Add proerty 'iommus'.
>>>
>>> Signed-off-by: Frank Li <Frank.Li at nxp.com>
>>> ---
>>
>> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> Other 3 patches already been linux-next. Who will pick this one?

Resend it to net-next (with proper title).

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:25:01 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:25:01 +0100
Subject: [PATCH 02/13] dt-bindings: i2c: nomadik: add mobileye,eyeq5-i2c
 bindings and example
In-Reply-To: <CZ6FUECKEX2B.36QWZZA5EYPI@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>
 <20240216022227.GA850600-robh@kernel.org>
 <CZ6FD7EHIJDT.32IEDVT9FG2GP@bootlin.com>
 <6effca50-29a4-43b9-86eb-310bd4e08e5c@linaro.org>
 <CZ6FUECKEX2B.36QWZZA5EYPI@bootlin.com>
Message-ID: <cf360cbf-7414-4024-8bdd-d2aba7f048b3@linaro.org>

On 16/02/2024 11:40, Th?o Lebrun wrote:
> Hello,
> 
> On Fri Feb 16, 2024 at 11:33 AM CET, Krzysztof Kozlowski wrote:
>> On 16/02/2024 11:18, Th?o Lebrun wrote:
>>>
>>>>> +        mobileye,id:
>>>>> +          $ref: /schemas/types.yaml#/definitions/uint32
>>>>> +          description: Platform-wide controller ID (integer starting from zero).
>>>>
>>>> instance indexes are a NAK. You can use i2cN aliases if you must.
>>>>
>>>> Why do you need it? To access OLB? If so, add cell args to the OLB 
>>>> phandle instead.
>>>
>>> Why we do what we do: I2C controller must write a 2 bit value depending
>>> on the bus speed. All I2C controllers write into the same register.
>>
>> Which register?  Your devices do not share IO address space.
> 
> mobileye,olb is a prop with a phandle to a syscon. That syscon contains
> the register we are interested in.

So exactly what Rob said... I don't understand why you have chosen to go
with alias.


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:26:18 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:26:18 +0100
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
In-Reply-To: <ed59671f-6e0b-45a2-bae7-38f7b4b7e625@amd.com>
References: <94726c90ff519185767475f672d70311472ea925.1708073513.git.michal.simek@amd.com>
 <5a81f16b-8ece-4263-b424-4dd6cd6e386f@linaro.org>
 <ed59671f-6e0b-45a2-bae7-38f7b4b7e625@amd.com>
Message-ID: <ebcfd49d-f810-4d9b-8cba-b55071fc7fa6@linaro.org>

On 16/02/2024 10:42, Michal Simek wrote:
> 
> 
> On 2/16/24 10:19, Krzysztof Kozlowski wrote:
>> On 16/02/2024 09:51, Michal Simek wrote:
>>> RTC has its own power domain on Xilinx Versal SOC that's why describe it as
>>> optional property.
>>>
>>> Signed-off-by: Michal Simek <michal.simek at amd.com>
>>> ---
>>>
>>>   Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml | 3 +++
>>>   1 file changed, 3 insertions(+)
>>>
>>
>> But Versal is not described in this binding, is it? I see only one
>> compatible.
> 
> It is the same IP only as is on zynqmp with own power rail.

Then you should have separate compatible, because they are not
identical. It would also allow you to narrow the domains to versal and
also require it (on versal).

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:39:52 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:39:52 +0100
Subject: [PATCH v3 02/16] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240216223654.1312880-3-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
 <20240216223654.1312880-3-sre@kernel.org>
Message-ID: <e3b54b1c-79ab-4f25-8b42-fadc922c0d25@linaro.org>

On 16/02/2024 23:34, Sebastian Reichel wrote:
> Convert the i.MX  Wireless External Interface Module binding to YAML.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---
>  .../devicetree/bindings/bus/imx-weim.txt      | 117 ----------
>  .../fsl/fsl,imx-weim-peripherals.yaml         |  31 +++
>  .../memory-controllers/fsl/fsl,imx-weim.yaml  | 203 ++++++++++++++++++
>  .../mc-peripheral-props.yaml                  |   1 +
>  .../fieldbus/arcx,anybus-controller.txt       |   2 +-
>  5 files changed, 236 insertions(+), 118 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
> 
> diff --git a/Documentation/devicetree/bindings/bus/imx-weim.txt b/Documentation/devicetree/bindings/bus/imx-weim.txt
> deleted file mode 100644
> index e7f502070d77..000000000000
> --- a/Documentation/devicetree/bindings/bus/imx-weim.txt
> +++ /dev/null
> @@ -1,117 +0,0 @@
> -Device tree bindings for i.MX Wireless External Interface Module (WEIM)
> -
> -The term "wireless" does not imply that the WEIM is literally an interface
> -without wires. It simply means that this module was originally designed for
> -wireless and mobile applications that use low-power technology.
> -
> -The actual devices are instantiated from the child nodes of a WEIM node.
> -
> -Required properties:
> -
> - - compatible:		Should contain one of the following:
> -			  "fsl,imx1-weim"
> -			  "fsl,imx27-weim"
> -			  "fsl,imx51-weim"
> -			  "fsl,imx50-weim"
> -			  "fsl,imx6q-weim"
> - - reg:			A resource specifier for the register space
> -			(see the example below)
> - - clocks:		the clock, see the example below.
> - - #address-cells:	Must be set to 2 to allow memory address translation
> - - #size-cells:		Must be set to 1 to allow CS address passing
> - - ranges:		Must be set up to reflect the memory layout with four
> -			integer values for each chip-select line in use:
> -
> -			   <cs-number> 0 <physical address of mapping> <size>
> -
> -Optional properties:
> -
> - - fsl,weim-cs-gpr:	For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
> -			devices, it should be the phandle to the system General
> -			Purpose Register controller that contains WEIM CS GPR
> -			register, e.g. IOMUXC_GPR1 on i.MX6Q.  IOMUXC_GPR1[11:0]
> -			should be set up as one of the following 4 possible
> -			values depending on the CS space configuration.
> -
> -			IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
> -			---------------------------------------------
> -				05	    128M     0M     0M     0M
> -				033          64M    64M     0M     0M
> -				0113         64M    32M    32M     0M
> -				01111        32M    32M    32M    32M
> -
> -			In case that the property is absent, the reset value or
> -			what bootloader sets up in IOMUXC_GPR1[11:0] will be
> -			used.
> -
> - - fsl,burst-clk-enable	For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
> -			devices, the presence of this property indicates that
> -			the weim bus should operate in Burst Clock Mode.
> -
> - - fsl,continuous-burst-clk	Make Burst Clock to output continuous clock.
> -			Without this option Burst Clock will output clock
> -			only when necessary. This takes effect only if
> -			"fsl,burst-clk-enable" is set.
> -
> -Timing property for child nodes. It is mandatory, not optional.
> -
> - - fsl,weim-cs-timing:	The timing array, contains timing values for the
> -			child node. We get the CS indexes from the address
> -			ranges in the child node's "reg" property.
> -			The number of registers depends on the selected chip:
> -			For i.MX1, i.MX21 ("fsl,imx1-weim") there are two
> -			registers: CSxU, CSxL.
> -			For i.MX25, i.MX27, i.MX31 and i.MX35 ("fsl,imx27-weim")
> -			there are three registers: CSCRxU, CSCRxL, CSCRxA.
> -			For i.MX50, i.MX53 ("fsl,imx50-weim"),
> -			i.MX51 ("fsl,imx51-weim") and i.MX6Q ("fsl,imx6q-weim")
> -			there are six registers: CSxGCR1, CSxGCR2, CSxRCR1,
> -			CSxRCR2, CSxWCR1, CSxWCR2.
> -
> -Example for an imx6q-sabreauto board, the NOR flash connected to the WEIM:
> -
> -	weim: weim at 21b8000 {
> -		compatible = "fsl,imx6q-weim";
> -		reg = <0x021b8000 0x4000>;
> -		clocks = <&clks 196>;
> -		#address-cells = <2>;
> -		#size-cells = <1>;
> -		ranges = <0 0 0x08000000 0x08000000>;
> -		fsl,weim-cs-gpr = <&gpr>;
> -
> -		nor at 0,0 {
> -			compatible = "cfi-flash";
> -			reg = <0 0 0x02000000>;
> -			#address-cells = <1>;
> -			#size-cells = <1>;
> -			bank-width = <2>;
> -			fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
> -					0x0000c000 0x1404a38e 0x00000000>;
> -		};
> -	};
> -
> -Example for an imx6q-based board, a multi-chipselect device connected to WEIM:
> -
> -In this case, both chip select 0 and 1 will be configured with the same timing
> -array values.
> -
> -	weim: weim at 21b8000 {
> -		compatible = "fsl,imx6q-weim";
> -		reg = <0x021b8000 0x4000>;
> -		clocks = <&clks 196>;
> -		#address-cells = <2>;
> -		#size-cells = <1>;
> -		ranges = <0 0 0x08000000 0x02000000
> -			  1 0 0x0a000000 0x02000000
> -			  2 0 0x0c000000 0x02000000
> -			  3 0 0x0e000000 0x02000000>;
> -		fsl,weim-cs-gpr = <&gpr>;
> -
> -		acme at 0 {
> -			compatible = "acme,whatever";
> -			reg = <0 0 0x100>, <0 0x400000 0x800>,
> -				<1 0x400000 0x800>;
> -			fsl,weim-cs-timing = <0x024400b1 0x00001010 0x20081100
> -				0x00000000 0xa0000240 0x00000000>;
> -		};
> -	};
> diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
> new file mode 100644
> index 000000000000..82fc5f4a1ed6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
> @@ -0,0 +1,31 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: i.MX WEIM Bus Peripheral Nodes
> +
> +maintainers:
> +  - Shawn Guo <shawnguo at kernel.org>
> +  - Sascha Hauer <s.hauer at pengutronix.de>
> +
> +description:
> +  This binding is meant for the child nodes of the WEIM node. The node
> +  represents any device connected to the WEIM bus. It may be a Flash chip,
> +  RAM chip or Ethernet controller, etc. These properties are meant for
> +  configuring the WEIM settings/timings and will accompany the bindings
> +  supported by the respective device.
> +
> +properties:
> +  reg: true

Your pattern in weim schema suggests you have here minItems: 2.
maxItems: can be 2 or 255.

> +
> +  fsl,weim-cs-timing:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      Timing values for the child node.
> +    minItems: 2
> +    maxItems: 6
> +


...

> +patternProperties:
> +  "^.*@[0-7],[0-9a-f]+$":
> +    type: object
> +    description: Devices attached to chip selects are represented as subnodes.
> +    $ref: fsl,imx-weim-peripherals.yaml
> +    additionalProperties: true
> +    required:
> +      - fsl,weim-cs-timing
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - '#address-cells'
> +  - '#size-cells'

Plaese keep consistent quotes, either ' or "


> +  - ranges
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          not:
> +            contains:
> +              enum:
> +                - fsl,imx50-weim
> +                - fsl,imx6q-weim
> +    then:
> +      properties:
> +        fsl,weim-cs-gpr: false
> +        fsl,burst-clk-enable: false
> +  - if:
> +      properties:
> +        fsl,burst-clk-enable: false

This does not work, or at least should not IMO.

What you want is
  not:
    required:

https://elixir.bootlin.com/linux/v6.4-rc7/source/Documentation/devicetree/bindings/net/qcom,ipa.yaml#L174



> +    then:
> +      properties:
> +        fsl,continuous-burst-clk: false
> +

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:40:15 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:40:15 +0100
Subject: [PATCH v3 13/16] ARM: dts: nxp: imx: fix weim node name
In-Reply-To: <20240216223654.1312880-14-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
 <20240216223654.1312880-14-sre@kernel.org>
Message-ID: <94ae484c-0331-40de-b437-b7145a113b8d@linaro.org>

On 16/02/2024 23:34, Sebastian Reichel wrote:
> DT node names should be generic, so replace "weim" node name with
> "memory-controller" in all i.MX SoC DT files.
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:41:03 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:41:03 +0100
Subject: [PATCH v3 04/16] dt-bindings: soc: imx: fsl,imx-anatop: add
 binding
In-Reply-To: <20240216223654.1312880-5-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
 <20240216223654.1312880-5-sre@kernel.org>
Message-ID: <cf586141-d8d7-463e-bbbe-ffae87f7499f@linaro.org>

On 16/02/2024 23:34, Sebastian Reichel wrote:
> Add missing binding for i.MX anatop syscon.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:41:24 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:41:24 +0100
Subject: [PATCH v3 08/16] ARM: dts: imx6ull: fix pinctrl node name
In-Reply-To: <20240216223654.1312880-9-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
 <20240216223654.1312880-9-sre@kernel.org>
Message-ID: <ea3f07a3-46a4-47a3-b9c1-086e1afb3f4e@linaro.org>

On 16/02/2024 23:34, Sebastian Reichel wrote:
> pinctrl node name must be either pinctrl or pinmux.
> 
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:41:42 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:41:42 +0100
Subject: [PATCH v3 11/16] ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
In-Reply-To: <20240216223654.1312880-12-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
 <20240216223654.1312880-12-sre@kernel.org>
Message-ID: <e8bd7c96-66b9-4cf6-b084-1fd5d53008cd@linaro.org>

On 16/02/2024 23:34, Sebastian Reichel wrote:
> Replace all "xnur-gpio" with "xnur-gpios" in the i.MX6UL(L) Touchscreen
> node, since the -gpio suffix is deprecated. All known implementations of
> this binding can handle -gpio and -gpios since day 1, so this should be
> fully backwards compatible.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:41:50 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:41:50 +0100
Subject: [PATCH v3 12/16] ARM: dts: nxp: imx6ul: fix touchscreen node name
In-Reply-To: <20240216223654.1312880-13-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
 <20240216223654.1312880-13-sre@kernel.org>
Message-ID: <216970ac-8997-4dab-a9b1-813804cefa0b@linaro.org>

On 16/02/2024 23:34, Sebastian Reichel wrote:
> The canonical node name for touchscreens is "touchscreen",
> so update the i.MX6UL "tsc" node accordingly.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>
> ---


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 00:42:43 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 09:42:43 +0100
Subject: [PATCH v3 16/16] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <20240216223654.1312880-17-sre@kernel.org>
References: <20240216223654.1312880-1-sre@kernel.org>
 <20240216223654.1312880-17-sre@kernel.org>
Message-ID: <ffc890f0-3cf8-47ba-b9de-fd4a8ad876fb@linaro.org>

On 16/02/2024 23:34, Sebastian Reichel wrote:
> Add UNI-T UTi260b thermal camera board.
> 
> Reviewed-by: Stefan Wahren <wahrenst at gmx.net>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>


> +
> +
> +	mux_spi3: ecspi3grp {
> +		fsl,pins = <
> +			MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI		0x100b1
> +			MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK		0x100b1
> +		>;
> +	};
> +
> +	mux_spi3_cs: ecspi3_csgrp {

No undescores in node names, please. Use hyphens.

> +		fsl,pins = <
> +			MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20		0x3008
> +		>;
> +	};
> +};

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 01:00:41 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 10:00:41 +0100
Subject: [PATCH v1 1/6] dt-bindings: cache: Document the
 sifive,perfmon-counters property
In-Reply-To: <20240216000837.1868917-2-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
 <20240216000837.1868917-2-samuel.holland@sifive.com>
Message-ID: <eeb2331d-10e6-4902-91ba-85896a8f0ee1@linaro.org>

On 16/02/2024 01:08, Samuel Holland wrote:
> The SiFive Composable Cache controller contains an optional PMU with a
> configurable number of event counters. Document a property which

Configurable in what context? By chip designers or by OS? Why this
cannot be deduced from the compatible?

> describes the number of available counters.
> 
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
> 
>  Documentation/devicetree/bindings/cache/sifive,ccache0.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
>  

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 01:09:56 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 10:09:56 +0100
Subject: [PATCH v1 3/6] dt-bindings: cache: Add SiFive Extensible Cache
 controller
In-Reply-To: <20240216000837.1868917-4-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
 <20240216000837.1868917-4-samuel.holland@sifive.com>
Message-ID: <d655b72e-3094-4b6b-bee8-9677b7c987ce@linaro.org>

On 16/02/2024 01:08, Samuel Holland wrote:
> From: Eric Lin <eric.lin at sifive.com>
> 
> Add YAML DT binding documentation for the SiFive Extensible Cache
> controller. The Extensible Cache controller interleaves cache blocks
> across a number of heterogeneous independently-programmed slices. Each
> slice contains an MMIO interface for configuration, cache maintenance,
> error reporting, and performance monitoring.
> 
> +allOf:
> +  - $ref: /schemas/cache-controller.yaml#
> +
> +select:
> +  properties:
> +    compatible:
> +      contains:
> +        enum:
> +          - sifive,extensiblecache0
> +
> +  required:
> +    - compatible
> +
> +properties:
> +  compatible:
> +    items:
> +      - const: sifive,extensiblecache0
> +      - const: cache
> +
> +  "#address-cells": true

const or enum: [1, 2], depending on the addressing you need here.

> +  "#size-cells": true

ditto

> +  ranges: true
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  cache-block-size:
> +    const: 64
> +
> +  cache-level: true

5 is acceptable? I would argue this should be even const.

> +  cache-sets: true
> +  cache-size: true

Some constraints on any of these?

> +  cache-unified: true
> +
> +patternProperties:
> +  "^cache-controller@[0-9a-f]+$":
> +    type: object
> +    additionalProperties: false

What is this object supposed to represent? Add description.

> +    properties:
> +      reg:
> +        maxItems: 1
> +
> +      cache-block-size:
> +        const: 64
> +
> +      cache-sets: true
> +      cache-size: true
> +      cache-unified: true

cache-level

> +
> +      sifive,bm-event-counters:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        default: 0
> +        description: Number of bucket monitor registers in this slice
> +
> +      sifive,cache-ways:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description: Number of ways in this slice (independent of cache size)
> +
> +      sifive,perfmon-counters:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        default: 0
> +        description: Number of PMU counter registers in this slice
> +
> +    required:
> +      - reg
> +      - cache-block-size
> +      - cache-sets
> +      - cache-size
> +      - cache-unified
> +      - sifive,cache-ways
> +
> +required:
> +  - compatible
> +  - ranges
> +  - interrupts
> +  - cache-block-size
> +  - cache-level
> +  - cache-sets
> +  - cache-size
> +  - cache-unified
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    cache-controller at 30040000 {
> +        compatible = "sifive,extensiblecache0", "cache";
> +        ranges = <0x30040000 0x30040000 0x10000>;
> +        interrupts = <0x4>;

You use hex as interrupt numbers on your platforms?

> +        cache-block-size = <0x40>;
> +        cache-level = <3>;
> +        cache-sets = <0x800>;

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 01:12:17 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 10:12:17 +0100
Subject: [PATCH v1 5/6] dt-bindings: cache: Add SiFive Private L2 Cache
 controller
In-Reply-To: <20240216000837.1868917-6-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
 <20240216000837.1868917-6-samuel.holland@sifive.com>
Message-ID: <7d7fc53f-1b5d-4f1f-a53f-f0863a79a79c@linaro.org>

On 16/02/2024 01:08, Samuel Holland wrote:
> From: Eric Lin <eric.lin at sifive.com>
> 
> Add YAML DT binding documentation for the SiFive Private L2 Cache
> controller. Some functionality and the corresponding register bits were
> removed in the sifive,pl2cache1 version of the hardware, which creates
> the unusual situation where the newer hardware's compatible string is
> the fallback for the older one.
> 
> Signed-off-by: Eric Lin <eric.lin at sifive.com>
> Co-developed-by: Samuel Holland <samuel.holland at sifive.com>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
> 
> Changes in v1:
>  - Add back select: clause to binding
>  - Make sifive,pl2cache1 the fallback for sifive,pl2cache0
>  - Fix the order of the reg property declaration
>  - Document the sifive,perfmon-counters property

This is no v1. Please implement entire feedback from previous v2, v3 or
whatever it was and reference old posting or continue the numbering.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 01:39:37 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 10:39:37 +0100
Subject: [PATCH] phy: constify of_phandle_args in xlate
Message-ID: <20240217093937.58234-1-krzysztof.kozlowski@linaro.org>

The xlate callbacks are supposed to translate of_phandle_args to proper
provider without modifying the of_phandle_args.  Make the argument
pointer to const for code safety and readability.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 drivers/phy/allwinner/phy-sun4i-usb.c              |  2 +-
 drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c     |  2 +-
 drivers/phy/broadcom/phy-bcm-sr-pcie.c             |  2 +-
 drivers/phy/broadcom/phy-bcm-sr-usb.c              |  2 +-
 drivers/phy/broadcom/phy-bcm63xx-usbh.c            |  2 +-
 drivers/phy/broadcom/phy-brcm-usb.c                |  2 +-
 drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c    |  2 +-
 drivers/phy/freescale/phy-fsl-lynx-28g.c           |  2 +-
 drivers/phy/hisilicon/phy-histb-combphy.c          |  2 +-
 drivers/phy/intel/phy-intel-lgm-combo.c            |  2 +-
 drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c        |  2 +-
 drivers/phy/marvell/phy-armada375-usb2.c           |  2 +-
 drivers/phy/marvell/phy-armada38x-comphy.c         |  2 +-
 drivers/phy/marvell/phy-berlin-sata.c              |  2 +-
 drivers/phy/marvell/phy-mvebu-a3700-comphy.c       |  2 +-
 drivers/phy/marvell/phy-mvebu-cp110-comphy.c       |  2 +-
 drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c        |  2 +-
 drivers/phy/mediatek/phy-mtk-tphy.c                |  2 +-
 drivers/phy/mediatek/phy-mtk-xsphy.c               |  2 +-
 drivers/phy/microchip/lan966x_serdes.c             |  2 +-
 drivers/phy/microchip/sparx5_serdes.c              |  2 +-
 drivers/phy/mscc/phy-ocelot-serdes.c               |  2 +-
 drivers/phy/phy-core.c                             |  8 ++++----
 drivers/phy/phy-xgene.c                            |  2 +-
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c          |  2 +-
 drivers/phy/ralink/phy-mt7621-pci.c                |  2 +-
 drivers/phy/renesas/phy-rcar-gen2.c                |  2 +-
 drivers/phy/renesas/phy-rcar-gen3-usb2.c           |  2 +-
 drivers/phy/renesas/r8a779f0-ether-serdes.c        |  2 +-
 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c |  2 +-
 drivers/phy/rockchip/phy-rockchip-pcie.c           |  2 +-
 drivers/phy/samsung/phy-exynos-mipi-video.c        |  2 +-
 drivers/phy/samsung/phy-exynos5-usbdrd.c           |  2 +-
 drivers/phy/samsung/phy-samsung-usb2.c             |  2 +-
 drivers/phy/socionext/phy-uniphier-usb2.c          |  2 +-
 drivers/phy/st/phy-miphy28lp.c                     |  2 +-
 drivers/phy/st/phy-spear1310-miphy.c               |  2 +-
 drivers/phy/st/phy-spear1340-miphy.c               |  2 +-
 drivers/phy/st/phy-stm32-usbphyc.c                 |  2 +-
 drivers/phy/tegra/xusb.c                           |  2 +-
 drivers/phy/ti/phy-am654-serdes.c                  |  2 +-
 drivers/phy/ti/phy-da8xx-usb.c                     |  2 +-
 drivers/phy/ti/phy-gmii-sel.c                      |  2 +-
 drivers/phy/xilinx/phy-zynqmp.c                    |  2 +-
 drivers/pinctrl/tegra/pinctrl-tegra-xusb.c         |  2 +-
 include/linux/phy/phy.h                            | 14 +++++++-------
 46 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index e53a9a9317bc..b0f19e950601 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -683,7 +683,7 @@ static int sun4i_usb_phy0_vbus_notify(struct notifier_block *nb,
 }
 
 static struct phy *sun4i_usb_phy_xlate(struct device *dev,
-					struct of_phandle_args *args)
+					const struct of_phandle_args *args)
 {
 	struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c
index 2712c4bd549d..5468831d6ab9 100644
--- a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c
+++ b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c
@@ -350,7 +350,7 @@ static int phy_g12a_usb3_pcie_exit(struct phy *phy)
 }
 
 static struct phy *phy_g12a_usb3_pcie_xlate(struct device *dev,
-					    struct of_phandle_args *args)
+					    const struct of_phandle_args *args)
 {
 	struct phy_g12a_usb3_pcie_priv *priv = dev_get_drvdata(dev);
 	unsigned int mode;
diff --git a/drivers/phy/broadcom/phy-bcm-sr-pcie.c b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
index 8a4aadf166cf..ff9b3862bf7a 100644
--- a/drivers/phy/broadcom/phy-bcm-sr-pcie.c
+++ b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
@@ -195,7 +195,7 @@ static const struct phy_ops sr_paxc_phy_ops = {
 };
 
 static struct phy *sr_pcie_phy_xlate(struct device *dev,
-				     struct of_phandle_args *args)
+				     const struct of_phandle_args *args)
 {
 	struct sr_pcie_phy_core *core;
 	int phy_idx;
diff --git a/drivers/phy/broadcom/phy-bcm-sr-usb.c b/drivers/phy/broadcom/phy-bcm-sr-usb.c
index b0bd18a5df87..6bcfe83609c8 100644
--- a/drivers/phy/broadcom/phy-bcm-sr-usb.c
+++ b/drivers/phy/broadcom/phy-bcm-sr-usb.c
@@ -209,7 +209,7 @@ static const struct phy_ops sr_phy_ops = {
 };
 
 static struct phy *bcm_usb_phy_xlate(struct device *dev,
-				     struct of_phandle_args *args)
+				     const struct of_phandle_args *args)
 {
 	struct bcm_usb_phy_cfg *phy_cfg;
 	int phy_idx;
diff --git a/drivers/phy/broadcom/phy-bcm63xx-usbh.c b/drivers/phy/broadcom/phy-bcm63xx-usbh.c
index f8183dea774b..647644de041b 100644
--- a/drivers/phy/broadcom/phy-bcm63xx-usbh.c
+++ b/drivers/phy/broadcom/phy-bcm63xx-usbh.c
@@ -366,7 +366,7 @@ static const struct phy_ops bcm63xx_usbh_phy_ops = {
 };
 
 static struct phy *bcm63xx_usbh_phy_xlate(struct device *dev,
-					  struct of_phandle_args *args)
+					  const struct of_phandle_args *args)
 {
 	struct bcm63xx_usbh_phy *usbh = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c
index a16f0b58eb74..ad2eec095601 100644
--- a/drivers/phy/broadcom/phy-brcm-usb.c
+++ b/drivers/phy/broadcom/phy-brcm-usb.c
@@ -175,7 +175,7 @@ static const struct phy_ops brcm_usb_phy_ops = {
 };
 
 static struct phy *brcm_usb_phy_xlate(struct device *dev,
-				      struct of_phandle_args *args)
+				      const struct of_phandle_args *args)
 {
 	struct brcm_usb_phy_data *data = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c b/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c
index 0ae052df3765..38388dd04bdc 100644
--- a/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c
+++ b/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c
@@ -294,7 +294,7 @@ static int mixel_lvds_phy_reset(struct device *dev)
 }
 
 static struct phy *mixel_lvds_phy_xlate(struct device *dev,
-					struct of_phandle_args *args)
+					const struct of_phandle_args *args)
 {
 	struct mixel_lvds_phy_priv *priv = dev_get_drvdata(dev);
 	unsigned int phy_id;
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index e2187767ce00..b86da8e9daa4 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -556,7 +556,7 @@ static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane)
 }
 
 static struct phy *lynx_28g_xlate(struct device *dev,
-				  struct of_phandle_args *args)
+				  const struct of_phandle_args *args)
 {
 	struct lynx_28g_priv *priv = dev_get_drvdata(dev);
 	int idx = args->args[0];
diff --git a/drivers/phy/hisilicon/phy-histb-combphy.c b/drivers/phy/hisilicon/phy-histb-combphy.c
index c44588fd5a53..7436dcae3981 100644
--- a/drivers/phy/hisilicon/phy-histb-combphy.c
+++ b/drivers/phy/hisilicon/phy-histb-combphy.c
@@ -163,7 +163,7 @@ static const struct phy_ops histb_combphy_ops = {
 };
 
 static struct phy *histb_combphy_xlate(struct device *dev,
-				       struct of_phandle_args *args)
+				       const struct of_phandle_args *args)
 {
 	struct histb_combphy_priv *priv = dev_get_drvdata(dev);
 	struct histb_combphy_mode *mode = &priv->mode;
diff --git a/drivers/phy/intel/phy-intel-lgm-combo.c b/drivers/phy/intel/phy-intel-lgm-combo.c
index d32e267c0001..f8e3054a9e59 100644
--- a/drivers/phy/intel/phy-intel-lgm-combo.c
+++ b/drivers/phy/intel/phy-intel-lgm-combo.c
@@ -508,7 +508,7 @@ static const struct phy_ops intel_cbphy_ops = {
 };
 
 static struct phy *intel_cbphy_xlate(struct device *dev,
-				     struct of_phandle_args *args)
+				     const struct of_phandle_args *args)
 {
 	struct intel_combo_phy *cbphy = dev_get_drvdata(dev);
 	u32 iphy_id;
diff --git a/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c b/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c
index ef93bf2cba10..406a87c8b759 100644
--- a/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c
+++ b/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c
@@ -358,7 +358,7 @@ static const struct phy_ops ltq_vrx200_pcie_phy_ops = {
 };
 
 static struct phy *ltq_vrx200_pcie_phy_xlate(struct device *dev,
-					     struct of_phandle_args *args)
+					     const struct of_phandle_args *args)
 {
 	struct ltq_vrx200_pcie_phy_priv *priv = dev_get_drvdata(dev);
 	unsigned int mode;
diff --git a/drivers/phy/marvell/phy-armada375-usb2.c b/drivers/phy/marvell/phy-armada375-usb2.c
index b141e3cd8a94..3731f9b25655 100644
--- a/drivers/phy/marvell/phy-armada375-usb2.c
+++ b/drivers/phy/marvell/phy-armada375-usb2.c
@@ -61,7 +61,7 @@ static const struct phy_ops armada375_usb_phy_ops = {
  * USB3 case it still optional and we use ENODEV.
  */
 static struct phy *armada375_usb_phy_xlate(struct device *dev,
-					struct of_phandle_args *args)
+					const struct of_phandle_args *args)
 {
 	struct armada375_cluster_phy *cluster_phy = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/marvell/phy-armada38x-comphy.c b/drivers/phy/marvell/phy-armada38x-comphy.c
index d3259984ee8e..5063361b0120 100644
--- a/drivers/phy/marvell/phy-armada38x-comphy.c
+++ b/drivers/phy/marvell/phy-armada38x-comphy.c
@@ -160,7 +160,7 @@ static const struct phy_ops a38x_comphy_ops = {
 };
 
 static struct phy *a38x_comphy_xlate(struct device *dev,
-				     struct of_phandle_args *args)
+				     const struct of_phandle_args *args)
 {
 	struct a38x_comphy_lane *lane;
 	struct phy *phy;
diff --git a/drivers/phy/marvell/phy-berlin-sata.c b/drivers/phy/marvell/phy-berlin-sata.c
index f972d78372ea..c90e2867900c 100644
--- a/drivers/phy/marvell/phy-berlin-sata.c
+++ b/drivers/phy/marvell/phy-berlin-sata.c
@@ -155,7 +155,7 @@ static int phy_berlin_sata_power_off(struct phy *phy)
 }
 
 static struct phy *phy_berlin_sata_phy_xlate(struct device *dev,
-					     struct of_phandle_args *args)
+					     const struct of_phandle_args *args)
 {
 	struct phy_berlin_priv *priv = dev_get_drvdata(dev);
 	int i;
diff --git a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
index 24c3371e2bb2..41162d7228c9 100644
--- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
@@ -1213,7 +1213,7 @@ static const struct phy_ops mvebu_a3700_comphy_ops = {
 };
 
 static struct phy *mvebu_a3700_comphy_xlate(struct device *dev,
-					    struct of_phandle_args *args)
+					    const struct of_phandle_args *args)
 {
 	struct mvebu_a3700_comphy_lane *lane;
 	unsigned int port;
diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
index b0dd13366598..da5e8f405749 100644
--- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
+++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c
@@ -917,7 +917,7 @@ static const struct phy_ops mvebu_comphy_ops = {
 };
 
 static struct phy *mvebu_comphy_xlate(struct device *dev,
-				      struct of_phandle_args *args)
+				      const struct of_phandle_args *args)
 {
 	struct mvebu_comphy_lane *lane;
 	struct phy *phy;
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c b/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c
index 972c129185f7..058e1d926630 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c
@@ -165,7 +165,7 @@ static int mtk_mipi_phy_power_off(struct phy *phy)
 }
 
 static struct phy *mtk_mipi_cdphy_xlate(struct device *dev,
-					struct of_phandle_args *args)
+					const struct of_phandle_args *args)
 {
 	struct mtk_mipi_cdphy_port *priv = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index a4746f6cb8a1..25b86bbb9cec 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -1467,7 +1467,7 @@ static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 }
 
 static struct phy *mtk_phy_xlate(struct device *dev,
-					struct of_phandle_args *args)
+					const struct of_phandle_args *args)
 {
 	struct mtk_tphy *tphy = dev_get_drvdata(dev);
 	struct mtk_phy_instance *instance = NULL;
diff --git a/drivers/phy/mediatek/phy-mtk-xsphy.c b/drivers/phy/mediatek/phy-mtk-xsphy.c
index b222fbbd71d1..064fd0941727 100644
--- a/drivers/phy/mediatek/phy-mtk-xsphy.c
+++ b/drivers/phy/mediatek/phy-mtk-xsphy.c
@@ -378,7 +378,7 @@ static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 }
 
 static struct phy *mtk_phy_xlate(struct device *dev,
-				 struct of_phandle_args *args)
+				 const struct of_phandle_args *args)
 {
 	struct mtk_xsphy *xsphy = dev_get_drvdata(dev);
 	struct xsphy_instance *inst = NULL;
diff --git a/drivers/phy/microchip/lan966x_serdes.c b/drivers/phy/microchip/lan966x_serdes.c
index b5ac2b7995e7..835e369cdfc5 100644
--- a/drivers/phy/microchip/lan966x_serdes.c
+++ b/drivers/phy/microchip/lan966x_serdes.c
@@ -518,7 +518,7 @@ static const struct phy_ops serdes_ops = {
 };
 
 static struct phy *serdes_simple_xlate(struct device *dev,
-				       struct of_phandle_args *args)
+				       const struct of_phandle_args *args)
 {
 	struct serdes_ctrl *ctrl = dev_get_drvdata(dev);
 	unsigned int port, idx, i;
diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
index 01bd5ea620c5..7cb85029fab3 100644
--- a/drivers/phy/microchip/sparx5_serdes.c
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -2509,7 +2509,7 @@ static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] =  {
 
 /* Client lookup function, uses serdes index */
 static struct phy *sparx5_serdes_xlate(struct device *dev,
-				     struct of_phandle_args *args)
+				     const struct of_phandle_args *args)
 {
 	struct sparx5_serdes_private *priv = dev_get_drvdata(dev);
 	int idx;
diff --git a/drivers/phy/mscc/phy-ocelot-serdes.c b/drivers/phy/mscc/phy-ocelot-serdes.c
index d9443e865a78..1cd1b5db2ad7 100644
--- a/drivers/phy/mscc/phy-ocelot-serdes.c
+++ b/drivers/phy/mscc/phy-ocelot-serdes.c
@@ -441,7 +441,7 @@ static const struct phy_ops serdes_ops = {
 };
 
 static struct phy *serdes_simple_xlate(struct device *dev,
-				       struct of_phandle_args *args)
+				       const struct of_phandle_args *args)
 {
 	struct serdes_ctrl *ctrl = dev_get_drvdata(dev);
 	unsigned int port, idx, i;
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 2e8b07eb637a..c5c8d70bc853 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -747,8 +747,8 @@ EXPORT_SYMBOL_GPL(devm_phy_put);
  * should provide a custom of_xlate function that reads the *args* and returns
  * the appropriate phy.
  */
-struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
-	*args)
+struct phy *of_phy_simple_xlate(struct device *dev,
+				const struct of_phandle_args *args)
 {
 	struct phy *phy;
 	struct class_dev_iter iter;
@@ -1142,7 +1142,7 @@ EXPORT_SYMBOL_GPL(devm_phy_destroy);
 struct phy_provider *__of_phy_provider_register(struct device *dev,
 	struct device_node *children, struct module *owner,
 	struct phy * (*of_xlate)(struct device *dev,
-				 struct of_phandle_args *args))
+				 const struct of_phandle_args *args))
 {
 	struct phy_provider *phy_provider;
 
@@ -1205,7 +1205,7 @@ EXPORT_SYMBOL_GPL(__of_phy_provider_register);
 struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
 	struct device_node *children, struct module *owner,
 	struct phy * (*of_xlate)(struct device *dev,
-				 struct of_phandle_args *args))
+				 const struct of_phandle_args *args))
 {
 	struct phy_provider **ptr, *phy_provider;
 
diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c
index 1f0f908323f0..5007dc7a357c 100644
--- a/drivers/phy/phy-xgene.c
+++ b/drivers/phy/phy-xgene.c
@@ -1611,7 +1611,7 @@ static const struct phy_ops xgene_phy_ops = {
 };
 
 static struct phy *xgene_phy_xlate(struct device *dev,
-				   struct of_phandle_args *args)
+				   const struct of_phandle_args *args)
 {
 	struct xgene_phy_ctx *ctx = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index b6908a03da58..546d3c6bee32 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -3454,7 +3454,7 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp)
 	return 0;
 }
 
-static struct phy *qmp_combo_phy_xlate(struct device *dev, struct of_phandle_args *args)
+static struct phy *qmp_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args)
 {
 	struct qmp_combo *qmp = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/ralink/phy-mt7621-pci.c b/drivers/phy/ralink/phy-mt7621-pci.c
index 2f876f158e1d..a591ad95347c 100644
--- a/drivers/phy/ralink/phy-mt7621-pci.c
+++ b/drivers/phy/ralink/phy-mt7621-pci.c
@@ -263,7 +263,7 @@ static const struct phy_ops mt7621_pci_phy_ops = {
 };
 
 static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev,
-					    struct of_phandle_args *args)
+					    const struct of_phandle_args *args)
 {
 	struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/renesas/phy-rcar-gen2.c b/drivers/phy/renesas/phy-rcar-gen2.c
index 507435af2656..c0221e7258c0 100644
--- a/drivers/phy/renesas/phy-rcar-gen2.c
+++ b/drivers/phy/renesas/phy-rcar-gen2.c
@@ -306,7 +306,7 @@ static const struct of_device_id rcar_gen2_phy_match_table[] = {
 MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table);
 
 static struct phy *rcar_gen2_phy_xlate(struct device *dev,
-				       struct of_phandle_args *args)
+				       const struct of_phandle_args *args)
 {
 	struct rcar_gen2_phy_driver *drv;
 	struct device_node *np = args->np;
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 6387c0d34c55..fbab6ac0f0d1 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -608,7 +608,7 @@ static const unsigned int rcar_gen3_phy_cable[] = {
 };
 
 static struct phy *rcar_gen3_phy_usb2_xlate(struct device *dev,
-					    struct of_phandle_args *args)
+					    const struct of_phandle_args *args)
 {
 	struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/renesas/r8a779f0-ether-serdes.c b/drivers/phy/renesas/r8a779f0-ether-serdes.c
index fc6e398fa3bf..f1f1da4a0b1f 100644
--- a/drivers/phy/renesas/r8a779f0-ether-serdes.c
+++ b/drivers/phy/renesas/r8a779f0-ether-serdes.c
@@ -334,7 +334,7 @@ static const struct phy_ops r8a779f0_eth_serdes_ops = {
 };
 
 static struct phy *r8a779f0_eth_serdes_xlate(struct device *dev,
-					     struct of_phandle_args *args)
+					     const struct of_phandle_args *args)
 {
 	struct r8a779f0_eth_serdes_drv_data *dd = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index 5de5e2e97ffa..76b9cf417591 100644
--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -251,7 +251,7 @@ static const struct phy_ops rochchip_combphy_ops = {
 	.owner = THIS_MODULE,
 };
 
-static struct phy *rockchip_combphy_xlate(struct device *dev, struct of_phandle_args *args)
+static struct phy *rockchip_combphy_xlate(struct device *dev, const struct of_phandle_args *args)
 {
 	struct rockchip_combphy_priv *priv = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c
index 1bbd6be2a584..51cc5ece0e63 100644
--- a/drivers/phy/rockchip/phy-rockchip-pcie.c
+++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
@@ -82,7 +82,7 @@ static struct rockchip_pcie_phy *to_pcie_phy(struct phy_pcie_instance *inst)
 }
 
 static struct phy *rockchip_pcie_phy_of_xlate(struct device *dev,
-					      struct of_phandle_args *args)
+					      const struct of_phandle_args *args)
 {
 	struct rockchip_pcie_phy *rk_phy = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/samsung/phy-exynos-mipi-video.c b/drivers/phy/samsung/phy-exynos-mipi-video.c
index 592d8067e848..f6756a609a9a 100644
--- a/drivers/phy/samsung/phy-exynos-mipi-video.c
+++ b/drivers/phy/samsung/phy-exynos-mipi-video.c
@@ -274,7 +274,7 @@ static int exynos_mipi_video_phy_power_off(struct phy *phy)
 }
 
 static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
-					struct of_phandle_args *args)
+					const struct of_phandle_args *args)
 {
 	struct exynos_mipi_video_phy *state = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
index 3f310b28bfff..04171eed5b16 100644
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
@@ -715,7 +715,7 @@ static int exynos5420_usbdrd_phy_calibrate(struct exynos5_usbdrd_phy *phy_drd)
 }
 
 static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev,
-					struct of_phandle_args *args)
+					const struct of_phandle_args *args)
 {
 	struct exynos5_usbdrd_phy *phy_drd = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/samsung/phy-samsung-usb2.c b/drivers/phy/samsung/phy-samsung-usb2.c
index 68a174eca0ba..9de744cd6f39 100644
--- a/drivers/phy/samsung/phy-samsung-usb2.c
+++ b/drivers/phy/samsung/phy-samsung-usb2.c
@@ -87,7 +87,7 @@ static const struct phy_ops samsung_usb2_phy_ops = {
 };
 
 static struct phy *samsung_usb2_phy_xlate(struct device *dev,
-					struct of_phandle_args *args)
+					const struct of_phandle_args *args)
 {
 	struct samsung_usb2_phy_driver *drv;
 
diff --git a/drivers/phy/socionext/phy-uniphier-usb2.c b/drivers/phy/socionext/phy-uniphier-usb2.c
index 3f2086ed4fe4..21c201717d95 100644
--- a/drivers/phy/socionext/phy-uniphier-usb2.c
+++ b/drivers/phy/socionext/phy-uniphier-usb2.c
@@ -81,7 +81,7 @@ static int uniphier_u2phy_init(struct phy *phy)
 }
 
 static struct phy *uniphier_u2phy_xlate(struct device *dev,
-					struct of_phandle_args *args)
+					const struct of_phandle_args *args)
 {
 	struct uniphier_u2phy_priv *priv = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/st/phy-miphy28lp.c b/drivers/phy/st/phy-miphy28lp.c
index e30305b77f0d..063fc38788ed 100644
--- a/drivers/phy/st/phy-miphy28lp.c
+++ b/drivers/phy/st/phy-miphy28lp.c
@@ -1074,7 +1074,7 @@ static int miphy28lp_get_addr(struct miphy28lp_phy *miphy_phy)
 }
 
 static struct phy *miphy28lp_xlate(struct device *dev,
-				   struct of_phandle_args *args)
+				   const struct of_phandle_args *args)
 {
 	struct miphy28lp_dev *miphy_dev = dev_get_drvdata(dev);
 	struct miphy28lp_phy *miphy_phy = NULL;
diff --git a/drivers/phy/st/phy-spear1310-miphy.c b/drivers/phy/st/phy-spear1310-miphy.c
index 35a9831b5161..c661ab63505f 100644
--- a/drivers/phy/st/phy-spear1310-miphy.c
+++ b/drivers/phy/st/phy-spear1310-miphy.c
@@ -183,7 +183,7 @@ static const struct phy_ops spear1310_miphy_ops = {
 };
 
 static struct phy *spear1310_miphy_xlate(struct device *dev,
-					 struct of_phandle_args *args)
+					 const struct of_phandle_args *args)
 {
 	struct spear1310_miphy_priv *priv = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/st/phy-spear1340-miphy.c b/drivers/phy/st/phy-spear1340-miphy.c
index 34a1cf21015f..85a60d64ebb7 100644
--- a/drivers/phy/st/phy-spear1340-miphy.c
+++ b/drivers/phy/st/phy-spear1340-miphy.c
@@ -220,7 +220,7 @@ static SIMPLE_DEV_PM_OPS(spear1340_miphy_pm_ops, spear1340_miphy_suspend,
 			 spear1340_miphy_resume);
 
 static struct phy *spear1340_miphy_xlate(struct device *dev,
-					 struct of_phandle_args *args)
+					 const struct of_phandle_args *args)
 {
 	struct spear1340_miphy_priv *priv = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c
index d5e7e44000b5..9dbe60dcf319 100644
--- a/drivers/phy/st/phy-stm32-usbphyc.c
+++ b/drivers/phy/st/phy-stm32-usbphyc.c
@@ -574,7 +574,7 @@ static void stm32_usbphyc_switch_setup(struct stm32_usbphyc *usbphyc,
 }
 
 static struct phy *stm32_usbphyc_of_xlate(struct device *dev,
-					  struct of_phandle_args *args)
+					  const struct of_phandle_args *args)
 {
 	struct stm32_usbphyc *usbphyc = dev_get_drvdata(dev);
 	struct stm32_usbphyc_phy *usbphyc_phy = NULL;
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index 142ebe0247cc..0dc86a7740e3 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -22,7 +22,7 @@
 #include "xusb.h"
 
 static struct phy *tegra_xusb_pad_of_xlate(struct device *dev,
-					   struct of_phandle_args *args)
+					   const struct of_phandle_args *args)
 {
 	struct tegra_xusb_pad *pad = dev_get_drvdata(dev);
 	struct phy *phy = NULL;
diff --git a/drivers/phy/ti/phy-am654-serdes.c b/drivers/phy/ti/phy-am654-serdes.c
index 3f1d43e8b7ad..8b3b937de624 100644
--- a/drivers/phy/ti/phy-am654-serdes.c
+++ b/drivers/phy/ti/phy-am654-serdes.c
@@ -495,7 +495,7 @@ static void serdes_am654_release(struct phy *x)
 }
 
 static struct phy *serdes_am654_xlate(struct device *dev,
-				      struct of_phandle_args *args)
+				      const struct of_phandle_args *args)
 {
 	struct serdes_am654 *am654_phy;
 	struct phy *phy;
diff --git a/drivers/phy/ti/phy-da8xx-usb.c b/drivers/phy/ti/phy-da8xx-usb.c
index b7a9ef3f4654..0fe577f0d6c1 100644
--- a/drivers/phy/ti/phy-da8xx-usb.c
+++ b/drivers/phy/ti/phy-da8xx-usb.c
@@ -119,7 +119,7 @@ static const struct phy_ops da8xx_usb20_phy_ops = {
 };
 
 static struct phy *da8xx_usb_phy_of_xlate(struct device *dev,
-					 struct of_phandle_args *args)
+					 const struct of_phandle_args *args)
 {
 	struct da8xx_usb_phy *d_phy = dev_get_drvdata(dev);
 
diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c
index 81dd1c3449d9..b30bf740e2e0 100644
--- a/drivers/phy/ti/phy-gmii-sel.c
+++ b/drivers/phy/ti/phy-gmii-sel.c
@@ -297,7 +297,7 @@ static const struct phy_ops phy_gmii_sel_ops = {
 };
 
 static struct phy *phy_gmii_sel_of_xlate(struct device *dev,
-					 struct of_phandle_args *args)
+					 const struct of_phandle_args *args)
 {
 	struct phy_gmii_sel_priv *priv = dev_get_drvdata(dev);
 	int phy_id = args->args[0];
diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c
index 2559c6594cea..f72c5257d712 100644
--- a/drivers/phy/xilinx/phy-zynqmp.c
+++ b/drivers/phy/xilinx/phy-zynqmp.c
@@ -768,7 +768,7 @@ static const unsigned int icm_matrix[NUM_LANES][CONTROLLERS_PER_LANE] = {
 
 /* Translate OF phandle and args to PHY instance. */
 static struct phy *xpsgtr_xlate(struct device *dev,
-				struct of_phandle_args *args)
+				const struct of_phandle_args *args)
 {
 	struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev);
 	struct xpsgtr_phy *gtr_phy;
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c
index 7641848be4de..96ef57a7d385 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c
@@ -685,7 +685,7 @@ static const struct phy_ops sata_phy_ops = {
 };
 
 static struct phy *tegra_xusb_padctl_xlate(struct device *dev,
-					   struct of_phandle_args *args)
+					   const struct of_phandle_args *args)
 {
 	struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev);
 	unsigned int index = args->args[0];
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index aa76609ba258..03cd5bae92d3 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -181,7 +181,7 @@ struct phy_provider {
 	struct module		*owner;
 	struct list_head	list;
 	struct phy * (*of_xlate)(struct device *dev,
-		struct of_phandle_args *args);
+				 const struct of_phandle_args *args);
 };
 
 /**
@@ -272,7 +272,7 @@ void phy_put(struct device *dev, struct phy *phy);
 void devm_phy_put(struct device *dev, struct phy *phy);
 struct phy *of_phy_get(struct device_node *np, const char *con_id);
 struct phy *of_phy_simple_xlate(struct device *dev,
-	struct of_phandle_args *args);
+				const struct of_phandle_args *args);
 struct phy *phy_create(struct device *dev, struct device_node *node,
 		       const struct phy_ops *ops);
 struct phy *devm_phy_create(struct device *dev, struct device_node *node,
@@ -282,11 +282,11 @@ void devm_phy_destroy(struct device *dev, struct phy *phy);
 struct phy_provider *__of_phy_provider_register(struct device *dev,
 	struct device_node *children, struct module *owner,
 	struct phy * (*of_xlate)(struct device *dev,
-				 struct of_phandle_args *args));
+				 const struct of_phandle_args *args));
 struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
 	struct device_node *children, struct module *owner,
 	struct phy * (*of_xlate)(struct device *dev,
-				 struct of_phandle_args *args));
+				 const struct of_phandle_args *args));
 void of_phy_provider_unregister(struct phy_provider *phy_provider);
 void devm_of_phy_provider_unregister(struct device *dev,
 	struct phy_provider *phy_provider);
@@ -500,7 +500,7 @@ static inline struct phy *of_phy_get(struct device_node *np, const char *con_id)
 }
 
 static inline struct phy *of_phy_simple_xlate(struct device *dev,
-	struct of_phandle_args *args)
+					      const struct of_phandle_args *args)
 {
 	return ERR_PTR(-ENOSYS);
 }
@@ -530,7 +530,7 @@ static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
 static inline struct phy_provider *__of_phy_provider_register(
 	struct device *dev, struct device_node *children, struct module *owner,
 	struct phy * (*of_xlate)(struct device *dev,
-				 struct of_phandle_args *args))
+				 const struct of_phandle_args *args))
 {
 	return ERR_PTR(-ENOSYS);
 }
@@ -538,7 +538,7 @@ static inline struct phy_provider *__of_phy_provider_register(
 static inline struct phy_provider *__devm_of_phy_provider_register(struct device
 	*dev, struct device_node *children, struct module *owner,
 	struct phy * (*of_xlate)(struct device *dev,
-				 struct of_phandle_args *args))
+				 const struct of_phandle_args *args))
 {
 	return ERR_PTR(-ENOSYS);
 }
-- 
2.34.1



From martin.blumenstingl at googlemail.com  Sat Feb 17 02:01:58 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 17 Feb 2024 11:01:58 +0100
Subject: [PATCH v1 0/2] mmc: meson-mx-sdhc: two small cleanups
Message-ID: <20240217100200.1494980-1-martin.blumenstingl@googlemail.com>

Hello Ulf,

here are two small cleanups for the meson-mx-sdhc driver.

The first one is resolves a TODO comment from when the driver was
originally introduced where devm_clk_hw_get_clk() was not available
yet. Nowadays it is and we can and should use it.

The second one removes an incorrect .card_hw_reset callback from the
driver's mmc_host_ops. This part has never been correct as we're
resetting the host controller, not the card. It didn't seem to cause
any issues so far, which is why I don't think that it's -stable
material.



Martin Blumenstingl (2):
  mmc: meson-mx-sdhc: Use devm_clk_hw_get_clk() for clock retrieval
  mmc: meson-mx-sdhc: Remove .card_hw_reset callback

 drivers/mmc/host/meson-mx-sdhc-clkc.c | 43 ++++++++++++++-------------
 drivers/mmc/host/meson-mx-sdhc-mmc.c  | 13 ++++----
 2 files changed, 28 insertions(+), 28 deletions(-)

-- 
2.43.2



From martin.blumenstingl at googlemail.com  Sat Feb 17 02:01:59 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 17 Feb 2024 11:01:59 +0100
Subject: [PATCH v1 1/2] mmc: meson-mx-sdhc: Use devm_clk_hw_get_clk() for clock retrieval
In-Reply-To: <20240217100200.1494980-1-martin.blumenstingl@googlemail.com>
References: <20240217100200.1494980-1-martin.blumenstingl@googlemail.com>
Message-ID: <20240217100200.1494980-2-martin.blumenstingl@googlemail.com>

Now that devm_clk_hw_get_clk() has been available for a while we can
resolve an older TODO where this API did not exist yet. No functional
changes intended.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 drivers/mmc/host/meson-mx-sdhc-clkc.c | 43 ++++++++++++++-------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/drivers/mmc/host/meson-mx-sdhc-clkc.c b/drivers/mmc/host/meson-mx-sdhc-clkc.c
index 19200b7079a6..cbd17a596cd2 100644
--- a/drivers/mmc/host/meson-mx-sdhc-clkc.c
+++ b/drivers/mmc/host/meson-mx-sdhc-clkc.c
@@ -71,12 +71,23 @@ static int meson_mx_sdhc_clk_hw_register(struct device *dev,
 static int meson_mx_sdhc_gate_clk_hw_register(struct device *dev,
 					      const char *name_suffix,
 					      struct clk_hw *parent,
-					      struct clk_hw *hw)
+					      struct clk_hw *hw,
+					      struct clk_bulk_data *clk_bulk_data,
+					      u8 bulk_index)
 {
 	struct clk_parent_data parent_data = { .hw = parent };
+	int ret;
+
+	ret = meson_mx_sdhc_clk_hw_register(dev, name_suffix, &parent_data, 1,
+					    &clk_gate_ops, hw);
+	if (ret)
+		return ret;
+
+	clk_bulk_data[bulk_index].clk = devm_clk_hw_get_clk(dev, hw, name_suffix);
+	if (IS_ERR(clk_bulk_data[bulk_index].clk))
+		return PTR_ERR(clk_bulk_data[bulk_index].clk);
 
-	return meson_mx_sdhc_clk_hw_register(dev, name_suffix, &parent_data, 1,
-					     &clk_gate_ops, hw);
+	return 0;
 }
 
 int meson_mx_sdhc_register_clkc(struct device *dev, void __iomem *base,
@@ -115,7 +126,8 @@ int meson_mx_sdhc_register_clkc(struct device *dev, void __iomem *base,
 	clkc_data->mod_clk_en.bit_idx = 15;
 	ret = meson_mx_sdhc_gate_clk_hw_register(dev, "mod_clk_on",
 						 &clkc_data->div.hw,
-						 &clkc_data->mod_clk_en.hw);
+						 &clkc_data->mod_clk_en.hw,
+						 clk_bulk_data, 0);
 	if (ret)
 		return ret;
 
@@ -123,7 +135,8 @@ int meson_mx_sdhc_register_clkc(struct device *dev, void __iomem *base,
 	clkc_data->tx_clk_en.bit_idx = 14;
 	ret = meson_mx_sdhc_gate_clk_hw_register(dev, "tx_clk_on",
 						 &clkc_data->div.hw,
-						 &clkc_data->tx_clk_en.hw);
+						 &clkc_data->tx_clk_en.hw,
+						 clk_bulk_data, 1);
 	if (ret)
 		return ret;
 
@@ -131,7 +144,8 @@ int meson_mx_sdhc_register_clkc(struct device *dev, void __iomem *base,
 	clkc_data->rx_clk_en.bit_idx = 13;
 	ret = meson_mx_sdhc_gate_clk_hw_register(dev, "rx_clk_on",
 						 &clkc_data->div.hw,
-						 &clkc_data->rx_clk_en.hw);
+						 &clkc_data->rx_clk_en.hw,
+						 clk_bulk_data, 2);
 	if (ret)
 		return ret;
 
@@ -139,18 +153,7 @@ int meson_mx_sdhc_register_clkc(struct device *dev, void __iomem *base,
 	clkc_data->sd_clk_en.bit_idx = 12;
 	ret = meson_mx_sdhc_gate_clk_hw_register(dev, "sd_clk_on",
 						 &clkc_data->div.hw,
-						 &clkc_data->sd_clk_en.hw);
-	if (ret)
-		return ret;
-
-	/*
-	 * TODO: Replace clk_hw.clk with devm_clk_hw_get_clk() once that is
-	 * available.
-	 */
-	clk_bulk_data[0].clk = clkc_data->mod_clk_en.hw.clk;
-	clk_bulk_data[1].clk = clkc_data->sd_clk_en.hw.clk;
-	clk_bulk_data[2].clk = clkc_data->tx_clk_en.hw.clk;
-	clk_bulk_data[3].clk = clkc_data->rx_clk_en.hw.clk;
-
-	return 0;
+						 &clkc_data->sd_clk_en.hw,
+						 clk_bulk_data, 3);
+	return ret;
 }
-- 
2.43.2



From martin.blumenstingl at googlemail.com  Sat Feb 17 02:02:00 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 17 Feb 2024 11:02:00 +0100
Subject: [PATCH v1 2/2] mmc: meson-mx-sdhc: Remove .card_hw_reset callback
In-Reply-To: <20240217100200.1494980-1-martin.blumenstingl@googlemail.com>
References: <20240217100200.1494980-1-martin.blumenstingl@googlemail.com>
Message-ID: <20240217100200.1494980-3-martin.blumenstingl@googlemail.com>

Commit 32f18e596141 ("mmc: improve API to make clear hw_reset callback
is for cards") made it clear that the hw_reset callback is intended for
resetting the card. Remove the .card_hw_reset callback from the
meson-mx-sdhc-mmc driver because it's purpose is to reset the SDHC
controller (FIFOs, PHY, DMA interface, ...).

While here also rename and change the argument of meson_mx_sdhc_hw_reset
so it cannot be called by accident as a replacement for card_hw_reset in
the future.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 drivers/mmc/host/meson-mx-sdhc-mmc.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/meson-mx-sdhc-mmc.c b/drivers/mmc/host/meson-mx-sdhc-mmc.c
index 1ed9731e77ef..31f750301dc1 100644
--- a/drivers/mmc/host/meson-mx-sdhc-mmc.c
+++ b/drivers/mmc/host/meson-mx-sdhc-mmc.c
@@ -65,10 +65,8 @@ static const struct regmap_config meson_mx_sdhc_regmap_config = {
 	.max_register = MESON_SDHC_CLK2,
 };
 
-static void meson_mx_sdhc_hw_reset(struct mmc_host *mmc)
+static void meson_mx_sdhc_reset(struct meson_mx_sdhc_host *host)
 {
-	struct meson_mx_sdhc_host *host = mmc_priv(mmc);
-
 	regmap_write(host->regmap, MESON_SDHC_SRST, MESON_SDHC_SRST_MAIN_CTRL |
 		     MESON_SDHC_SRST_RXFIFO | MESON_SDHC_SRST_TXFIFO |
 		     MESON_SDHC_SRST_DPHY_RX | MESON_SDHC_SRST_DPHY_TX |
@@ -116,7 +114,7 @@ static void meson_mx_sdhc_wait_cmd_ready(struct mmc_host *mmc)
 		dev_warn(mmc_dev(mmc),
 			 "Failed to poll for CMD_BUSY while processing CMD%d\n",
 			 host->cmd->opcode);
-		meson_mx_sdhc_hw_reset(mmc);
+		meson_mx_sdhc_reset(host);
 	}
 
 	ret = regmap_read_poll_timeout(host->regmap, MESON_SDHC_ESTA, esta,
@@ -127,7 +125,7 @@ static void meson_mx_sdhc_wait_cmd_ready(struct mmc_host *mmc)
 		dev_warn(mmc_dev(mmc),
 			 "Failed to poll for ESTA[13:11] while processing CMD%d\n",
 			 host->cmd->opcode);
-		meson_mx_sdhc_hw_reset(mmc);
+		meson_mx_sdhc_reset(host);
 	}
 }
 
@@ -495,7 +493,6 @@ static int meson_mx_sdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 }
 
 static const struct mmc_host_ops meson_mx_sdhc_ops = {
-	.card_hw_reset			= meson_mx_sdhc_hw_reset,
 	.request			= meson_mx_sdhc_request,
 	.set_ios			= meson_mx_sdhc_set_ios,
 	.card_busy			= meson_mx_sdhc_card_busy,
@@ -618,7 +615,7 @@ static irqreturn_t meson_mx_sdhc_irq_thread(int irq, void *irq_data)
 	}
 
 	if (cmd->error == -EIO || cmd->error == -ETIMEDOUT)
-		meson_mx_sdhc_hw_reset(host->mmc);
+		meson_mx_sdhc_reset(host);
 	else if (cmd->data)
 		/*
 		 * Clear the FIFOs after completing data transfers to prevent
@@ -728,7 +725,7 @@ static void meson_mx_sdhc_init_hw(struct mmc_host *mmc)
 {
 	struct meson_mx_sdhc_host *host = mmc_priv(mmc);
 
-	meson_mx_sdhc_hw_reset(mmc);
+	meson_mx_sdhc_reset(host);
 
 	regmap_write(host->regmap, MESON_SDHC_CTRL,
 		     FIELD_PREP(MESON_SDHC_CTRL_RX_PERIOD, 0xf) |
-- 
2.43.2



From shreeya.patel at collabora.com  Sat Feb 17 02:18:26 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Sat, 17 Feb 2024 10:18:26 +0000
Subject: =?utf-8?q?Re=3A?= [PATCH 1/4] =?utf-8?q?clk=3A?==?utf-8?q?_rockchip=3A?=
 =?utf-8?q?_rst-rk3588=3A?= Add BIU reset
In-Reply-To: <0c2f4d92-afa9-46f1-844e-994bd45924ef@linaro.org>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
 <20240216094922.257674-2-shreeya.patel@collabora.com>
 <237e690a-2f49-4046-b054-3a878eed6748@linaro.org>
 <30d2-65cf5980-3-2ec9f500@242931553> <0c2f4d92-afa9-46f1-844e-994bd45924ef@linaro.org>
Message-ID: <1b9-65d08800-3-19290580@120474537>

On Saturday, February 17, 2024 13:47 IST, Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:

> On 16/02/2024 13:48, Shreeya Patel wrote:
> > On Friday, February 16, 2024 15:33 IST, Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:
> > 
> >> On 16/02/2024 10:49, Shreeya Patel wrote:
> >>> Export hdmirx_biu soft reset id which is required by the hdmirx controller.
> >>>
> >>> Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
> >>> ---
> >>>  drivers/clk/rockchip/rst-rk3588.c               | 1 +
> >>>  include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++
> >>
> >> Please run scripts/checkpatch.pl and fix reported warnings. Some
> >> warnings can be ignored, but the code here looks like it needs a fix.
> >> Feel free to get in touch if the warning is not clear.
> >>
> >> Please do internal review. The internal Collabora review would tell you:
> >> YOU MUST run checkpatch. Then you see errors, so why do you send patch
> >> with errors to the mailing list?
> >>
> > 
> > I am sorry but what errors are you talking about?
> > I don't see any errors reported by checkpatch :-
> > 
> > shreeya at shreeya:~/collabora/rd/rockchip/torvalds$ ./scripts/checkpatch.pl hdmirx/0001-clk-rockchip-rst-rk3588-Add-BIU-reset.patch
> > WARNING: DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst
> 
> Here.
> 
> > 
> > total: 0 errors, 1 warnings, 13 lines checked
> > 
> > NOTE: For some of the reported defects, checkpatch may be able to
> >       mechanically convert to the typical style using --fix or --fix-inplace.
> > 
> > hdmirx-v1-1602/0001-clk-rockchip-rst-rk3588-Add-BIU-reset.patch has style problems, please review.
> > 
> > I see the above warning but that looks like a false positive to me.
> 
> Why for your patch it would be false positive and for all others would not?
> 

OK, now I see what you meant. Since we are touching the include file and C file together, this warning was generated.
It was a bit confusing to interpret this as the warning also talks about Documentation which we didn't touch at all.

Anyway, I will create two separate patches for this in v2.


Thanks,
Shreeya Patel

> Best regards,
> Krzysztof
>



From krzysztof.kozlowski at linaro.org  Sat Feb 17 02:20:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 11:20:38 +0100
Subject: [PATCH 1/4] clk: rockchip: rst-rk3588: Add BIU reset
In-Reply-To: <1b9-65d08800-3-19290580@120474537>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
 <20240216094922.257674-2-shreeya.patel@collabora.com>
 <237e690a-2f49-4046-b054-3a878eed6748@linaro.org>
 <30d2-65cf5980-3-2ec9f500@242931553>
 <0c2f4d92-afa9-46f1-844e-994bd45924ef@linaro.org>
 <1b9-65d08800-3-19290580@120474537>
Message-ID: <c8cb8fd4-a67d-4982-b1f8-6fedbb7e9a4f@linaro.org>

On 17/02/2024 11:18, Shreeya Patel wrote:
> On Saturday, February 17, 2024 13:47 IST, Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:
> 
>> On 16/02/2024 13:48, Shreeya Patel wrote:
>>> On Friday, February 16, 2024 15:33 IST, Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:
>>>
>>>> On 16/02/2024 10:49, Shreeya Patel wrote:
>>>>> Export hdmirx_biu soft reset id which is required by the hdmirx controller.
>>>>>
>>>>> Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
>>>>> ---
>>>>>  drivers/clk/rockchip/rst-rk3588.c               | 1 +
>>>>>  include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++
>>>>
>>>> Please run scripts/checkpatch.pl and fix reported warnings. Some
>>>> warnings can be ignored, but the code here looks like it needs a fix.
>>>> Feel free to get in touch if the warning is not clear.
>>>>
>>>> Please do internal review. The internal Collabora review would tell you:
>>>> YOU MUST run checkpatch. Then you see errors, so why do you send patch
>>>> with errors to the mailing list?
>>>>
>>>
>>> I am sorry but what errors are you talking about?
>>> I don't see any errors reported by checkpatch :-
>>>
>>> shreeya at shreeya:~/collabora/rd/rockchip/torvalds$ ./scripts/checkpatch.pl hdmirx/0001-clk-rockchip-rst-rk3588-Add-BIU-reset.patch
>>> WARNING: DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst
>>
>> Here.
>>
>>>
>>> total: 0 errors, 1 warnings, 13 lines checked
>>>
>>> NOTE: For some of the reported defects, checkpatch may be able to
>>>       mechanically convert to the typical style using --fix or --fix-inplace.
>>>
>>> hdmirx-v1-1602/0001-clk-rockchip-rst-rk3588-Add-BIU-reset.patch has style problems, please review.
>>>
>>> I see the above warning but that looks like a false positive to me.
>>
>> Why for your patch it would be false positive and for all others would not?
>>
> 
> OK, now I see what you meant. Since we are touching the include file and C file together, this warning was generated.
> It was a bit confusing to interpret this as the warning also talks about Documentation which we didn't touch at all.

Really, no documentation touching? Care to check the full path of the
files you are changing?


> 
> Anyway, I will create two separate patches for this in v2.

I think rules cannot be clearer:
https://elixir.bootlin.com/linux/v6.8-rc4/source/Documentation/devicetree/bindings/submitting-patches.rst#L13


Best regards,
Krzysztof



From shreeya.patel at collabora.com  Sat Feb 17 02:36:46 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Sat, 17 Feb 2024 10:36:46 +0000
Subject: =?utf-8?q?Re=3A?= [PATCH 1/4] =?utf-8?q?clk=3A?==?utf-8?q?_rockchip=3A?=
 =?utf-8?q?_rst-rk3588=3A?= Add BIU reset
In-Reply-To: <c8cb8fd4-a67d-4982-b1f8-6fedbb7e9a4f@linaro.org>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
 <20240216094922.257674-2-shreeya.patel@collabora.com>
 <237e690a-2f49-4046-b054-3a878eed6748@linaro.org>
 <30d2-65cf5980-3-2ec9f500@242931553>
 <0c2f4d92-afa9-46f1-844e-994bd45924ef@linaro.org>
 <1b9-65d08800-3-19290580@120474537> <c8cb8fd4-a67d-4982-b1f8-6fedbb7e9a4f@linaro.org>
Message-ID: <1aae-65d08c00-1-625abd00@109408603>

On Saturday, February 17, 2024 15:50 IST, Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:

> On 17/02/2024 11:18, Shreeya Patel wrote:
> > On Saturday, February 17, 2024 13:47 IST, Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:
> > 
> >> On 16/02/2024 13:48, Shreeya Patel wrote:
> >>> On Friday, February 16, 2024 15:33 IST, Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:
> >>>
> >>>> On 16/02/2024 10:49, Shreeya Patel wrote:
> >>>>> Export hdmirx_biu soft reset id which is required by the hdmirx controller.
> >>>>>
> >>>>> Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
> >>>>> ---
> >>>>>  drivers/clk/rockchip/rst-rk3588.c               | 1 +
> >>>>>  include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++
> >>>>
> >>>> Please run scripts/checkpatch.pl and fix reported warnings. Some
> >>>> warnings can be ignored, but the code here looks like it needs a fix.
> >>>> Feel free to get in touch if the warning is not clear.
> >>>>
> >>>> Please do internal review. The internal Collabora review would tell you:
> >>>> YOU MUST run checkpatch. Then you see errors, so why do you send patch
> >>>> with errors to the mailing list?
> >>>>
> >>>
> >>> I am sorry but what errors are you talking about?
> >>> I don't see any errors reported by checkpatch :-
> >>>
> >>> shreeya at shreeya:~/collabora/rd/rockchip/torvalds$ ./scripts/checkpatch.pl hdmirx/0001-clk-rockchip-rst-rk3588-Add-BIU-reset.patch
> >>> WARNING: DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst
> >>
> >> Here.
> >>
> >>>
> >>> total: 0 errors, 1 warnings, 13 lines checked
> >>>
> >>> NOTE: For some of the reported defects, checkpatch may be able to
> >>>       mechanically convert to the typical style using --fix or --fix-inplace.
> >>>
> >>> hdmirx-v1-1602/0001-clk-rockchip-rst-rk3588-Add-BIU-reset.patch has style problems, please review.
> >>>
> >>> I see the above warning but that looks like a false positive to me.
> >>
> >> Why for your patch it would be false positive and for all others would not?
> >>
> > 
> > OK, now I see what you meant. Since we are touching the include file and C file together, this warning was generated.
> > It was a bit confusing to interpret this as the warning also talks about Documentation which we didn't touch at all.
> 
> Really, no documentation touching? Care to check the full path of the
> files you are changing?
> 

Well, I meant the dt-binding doc for rst-rk3588

> 
> > 
> > Anyway, I will create two separate patches for this in v2.
> 
> I think rules cannot be clearer:
> https://elixir.bootlin.com/linux/v6.8-rc4/source/Documentation/devicetree/bindings/submitting-patches.rst#L13
> 

right, it was my mistake and I think after this nice and kind feedback, I'll never make the same one again :)

Thanks,
Shreeya Patel

> 
> Best regards,
> Krzysztof
> 
> _______________________________________________
> Kernel mailing list -- kernel at mailman.collabora.com
> To unsubscribe send an email to kernel-leave at mailman.collabora.com
> This list is managed by https://mailman.collabora.com



From raphael.gallais-pou at foss.st.com  Sat Feb 17 03:02:55 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Sat, 17 Feb 2024 12:02:55 +0100
Subject: [PATCH v2 1/4] ARM: dts: stm32: add LTDC support for STM32MP13x
 SoC family
In-Reply-To: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>
References: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>
Message-ID: <20240217-ltdc_mp13-v2-1-50881f1b394e@foss.st.com>

STM32MP13x SoC family embeds a new version of LTDC (Liquid crystal
display - Thin film transistor) Display Controller.

It provides a parallel digital RGB (red, green, blue) and signals for
horizontal, vertical synchronization, pixel clock and data enable as
output to interface directly to a variety of LCD-TFT panels.

Main features
  * 2 input layers blended together to compose the display
  * Cropping of layers from any input size and location
  * Multiple input pixel formats:
    ? Predefined ARGB, with 7 formats: ARGB8888, ABGR8888, RGBA8888,
    BGRA8888, RGB565, BGR565, RGB888packed.
    ? Flexible ARGB, allowing any width and location for A,R,G,B
    components.
    ? Predefined YUV, with 3 formats: YUV422-1L (FourCC: YUYV,
    Interleaved), YUV420-2L (FourCC: NV12, semi planar), YUV420-3L
    (FourCC: Yxx, full planar) with some flexibility on the sequence of
    the component.
  * Color look-up table (CLUT) up to 256 colors (256x24 bits) per layer
  * Color transparency keying
  * Composition with flexible window position and size versus output
  display
  * Blending with flexible layer order and alpha value (per pixel or
  constant)
  * Background underlying color
  * Gamma with non-linear configurable table
  * Dithering for output with less bits per component (pseudo-random on
  2 bits)
  * Polarity inversion for HSync, VSync, and DataEnable outputs
  * Output as RGB888 24 bpp or YUV422 16 bpp
  * Secure layer (using Layer2) capability, with grouped regs and
  additional interrupt set
  * Interrupts based on 7 different events
  * AXI master interface with long efficient bursts (64 or 128 bytes)

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp135.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp135.dtsi b/arch/arm/boot/dts/st/stm32mp135.dtsi
index 68d32f9f5314..834a4d545fe4 100644
--- a/arch/arm/boot/dts/st/stm32mp135.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp135.dtsi
@@ -19,5 +19,16 @@ dcmipp: dcmipp at 5a000000 {
 			port {
 			};
 		};
+
+		ltdc: display-controller at 5a001000 {
+			compatible = "st,stm32-ltdc";
+			reg = <0x5a001000 0x400>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&rcc LTDC_PX>;
+			clock-names = "lcd";
+			resets = <&scmi_reset RST_SCMI_LTDC>;
+			status = "disabled";
+		};
 	};
 };

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Sat Feb 17 03:02:56 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Sat, 17 Feb 2024 12:02:56 +0100
Subject: [PATCH v2 2/4] ARM: dts: stm32: add LTDC pinctrl on STM32MP13x SoC
 family
In-Reply-To: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>
References: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>
Message-ID: <20240217-ltdc_mp13-v2-2-50881f1b394e@foss.st.com>

Adds LTDC pinctrl support and assigns dedicated GPIO pins.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 57 +++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
index 27e0c3826789..32c5d8a1e06a 100644
--- a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
@@ -47,6 +47,63 @@ pins {
 		};
 	};
 
+	ltdc_pins_a: ltdc-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D',  9, AF13)>, /* LCD_CLK */
+				 <STM32_PINMUX('C',  6, AF14)>, /* LCD_HSYNC */
+				 <STM32_PINMUX('G',  4, AF11)>, /* LCD_VSYNC */
+				 <STM32_PINMUX('H',  9, AF11)>, /* LCD_DE */
+				 <STM32_PINMUX('G',  7, AF14)>, /* LCD_R2 */
+				 <STM32_PINMUX('B', 12, AF13)>, /* LCD_R3 */
+				 <STM32_PINMUX('D', 14, AF14)>, /* LCD_R4 */
+				 <STM32_PINMUX('E',  7, AF14)>, /* LCD_R5 */
+				 <STM32_PINMUX('E', 13, AF14)>, /* LCD_R6 */
+				 <STM32_PINMUX('E',  9, AF14)>, /* LCD_R7 */
+				 <STM32_PINMUX('H', 13, AF14)>, /* LCD_G2 */
+				 <STM32_PINMUX('F',  3, AF14)>, /* LCD_G3 */
+				 <STM32_PINMUX('D',  5, AF14)>, /* LCD_G4 */
+				 <STM32_PINMUX('G',  0, AF14)>, /* LCD_G5 */
+				 <STM32_PINMUX('C',  7, AF14)>, /* LCD_G6 */
+				 <STM32_PINMUX('A', 15, AF11)>, /* LCD_G7 */
+				 <STM32_PINMUX('D', 10, AF14)>, /* LCD_B2 */
+				 <STM32_PINMUX('F',  2, AF14)>, /* LCD_B3 */
+				 <STM32_PINMUX('H', 14, AF11)>, /* LCD_B4 */
+				 <STM32_PINMUX('E',  0, AF14)>, /* LCD_B5 */
+				 <STM32_PINMUX('B',  6, AF7)>,  /* LCD_B6 */
+				 <STM32_PINMUX('F',  1, AF13)>; /* LCD_B7 */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	ltdc_sleep_pins_a: ltdc-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D',  9, ANALOG)>, /* LCD_CLK */
+				 <STM32_PINMUX('C',  6, ANALOG)>, /* LCD_HSYNC */
+				 <STM32_PINMUX('G',  4, ANALOG)>, /* LCD_VSYNC */
+				 <STM32_PINMUX('H',  9, ANALOG)>, /* LCD_DE */
+				 <STM32_PINMUX('G',  7, ANALOG)>, /* LCD_R2 */
+				 <STM32_PINMUX('B', 12, ANALOG)>, /* LCD_R3 */
+				 <STM32_PINMUX('D', 14, ANALOG)>, /* LCD_R4 */
+				 <STM32_PINMUX('E',  7, ANALOG)>, /* LCD_R5 */
+				 <STM32_PINMUX('E', 13, ANALOG)>, /* LCD_R6 */
+				 <STM32_PINMUX('E',  9, ANALOG)>, /* LCD_R7 */
+				 <STM32_PINMUX('H', 13, ANALOG)>, /* LCD_G2 */
+				 <STM32_PINMUX('F',  3, ANALOG)>, /* LCD_G3 */
+				 <STM32_PINMUX('D',  5, ANALOG)>, /* LCD_G4 */
+				 <STM32_PINMUX('G',  0, ANALOG)>, /* LCD_G5 */
+				 <STM32_PINMUX('C',  7, ANALOG)>, /* LCD_G6 */
+				 <STM32_PINMUX('A', 15, ANALOG)>, /* LCD_G7 */
+				 <STM32_PINMUX('D', 10, ANALOG)>, /* LCD_B2 */
+				 <STM32_PINMUX('F',  2, ANALOG)>, /* LCD_B3 */
+				 <STM32_PINMUX('H', 14, ANALOG)>, /* LCD_B4 */
+				 <STM32_PINMUX('E',  0, ANALOG)>, /* LCD_B5 */
+				 <STM32_PINMUX('B',  6, ANALOG)>, /* LCD_B6 */
+				 <STM32_PINMUX('F',  1, ANALOG)>; /* LCD_B7 */
+		};
+	};
+
 	mcp23017_pins_a: mcp23017-0 {
 		pins {
 			pinmux = <STM32_PINMUX('G', 12, GPIO)>;

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Sat Feb 17 03:02:58 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Sat, 17 Feb 2024 12:02:58 +0100
Subject: [PATCH v2 4/4] dt-bindings: display: simple: hardware can use
 several properties
In-Reply-To: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>
References: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>
Message-ID: <20240217-ltdc_mp13-v2-4-50881f1b394e@foss.st.com>

Setting a panel-timing in the device-tree overwrite the one specified in
the driver and set it as preferred.  In that case 'height-mm',
'width-mm' and 'panel-timing' are properties that can be use for simple
panels, according to panel-common.yaml

Fixes following warnings:
arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-rgb: 'height-mm', 'panel-timing', 'width-mm' do not match any of the regexes: 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
 Documentation/devicetree/bindings/display/panel/panel-simple.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 634a10c6f2dd..c02cbbc7a100 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -352,6 +352,9 @@ properties:
   no-hpd: true
   hpd-gpios: true
   data-mapping: true
+  height-mm: true
+  width-mm: true
+  panel-timing: true
 
 if:
   not:

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Sat Feb 17 03:02:57 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Sat, 17 Feb 2024 12:02:57 +0100
Subject: [PATCH v2 3/4] ARM: dts: stm32: enable display support on
 stm32mp135f-dk board
In-Reply-To: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>
References: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>
Message-ID: <20240217-ltdc_mp13-v2-3-50881f1b394e@foss.st.com>

Link panel and display controller.
Enable panel, backlight and display controller.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>

---
Changes in v2:
  - Fixed dtbs_check warnings :
arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-backlight: 'default-brightness-level' does not match any of the regexes: 'pinctrl-[0-9]+'
??from schema $id: http://devicetree.org/schemas/leds/backlight/gpio-backlight.yaml#
arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-rgb: data-mapping:0: 'bgr666' is not one of ['jeida-18', 'jeida-24', 'vesa-24']
??from schema $id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#
arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-rgb: compatible: ['rocktech,rk043fn48h', 'panel-dpi'] is too long
??from schema $id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#
arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-rgb: data-mapping: False schema does not allow ['bgr666']
??from schema $id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#
---
 arch/arm/boot/dts/st/stm32mp135f-dk.dts | 53 +++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
index eea740d097c7..c918f332cbfd 100644
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -66,6 +66,46 @@ led-blue {
 			default-state = "off";
 		};
 	};
+
+	panel_backlight: panel-backlight {
+		compatible = "gpio-backlight";
+		gpios = <&gpioe 12 GPIO_ACTIVE_HIGH>;
+		default-on;
+		status = "okay";
+	};
+
+	panel_rgb: panel-rgb {
+		compatible = "rocktech,rk043fn48h";
+		enable-gpios = <&gpioi 7 GPIO_ACTIVE_HIGH>;
+		backlight = <&panel_backlight>;
+		power-supply = <&scmi_v3v3_sw>;
+		status = "okay";
+
+		width-mm = <105>;
+		height-mm = <67>;
+
+		panel-timing {
+			clock-frequency = <10000000>;
+			hactive = <480>;
+			hback-porch = <43>;
+			hfront-porch = <10>;
+			hsync-len = <1>;
+			hsync-active = <0>;
+			vactive = <272>;
+			vback-porch = <26>;
+			vfront-porch = <4>;
+			vsync-len = <10>;
+			vsync-active = <0>;
+			de-active = <1>;
+			pixelclk-active = <1>;
+		};
+
+		port {
+			panel_in_rgb: endpoint {
+				remote-endpoint = <&ltdc_out_rgb>;
+			};
+		};
+	};
 };
 
 &adc_1 {
@@ -160,6 +200,19 @@ &iwdg2 {
 	status = "okay";
 };
 
+&ltdc {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&ltdc_pins_a>;
+	pinctrl-1 = <&ltdc_sleep_pins_a>;
+	status = "okay";
+
+	port {
+		ltdc_out_rgb: endpoint {
+			remote-endpoint = <&panel_in_rgb>;
+		};
+	};
+};
+
 &rtc {
 	status = "okay";
 };

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Sat Feb 17 03:02:54 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Sat, 17 Feb 2024 12:02:54 +0100
Subject: [PATCH v2 0/4] Add display support for stm32mp135f-dk board
Message-ID: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>

This serie aims to enable display support for the stm32mp135f-dk board

Those are only patches of the device-tree since the driver support has
already been added [1].

It respectivelly:
	- adds support for the display controller on stm32mp135
	- adds pinctrl for the display controller
	- enables panel, backlight and display controller on
	  stm32mp135f-dk

Finally it fixes the flags on the panel default mode in the
'panel-simple' driver, allowing to override the default mode by one
described in the device tree, and push further the blanking limit on the
panel.

[1] commit 1726cee3d053 ("drm/stm: ltdc: support of new hardware version")

Changes in v2:
  - Removed already merged patches
https://lore.kernel.org/lkml/170729755552.1647630.4818786052103823648.b4-ty at linaro.org/
https://lore.kernel.org/lkml/170729755662.1647630.425379349649657352.b4-ty at linaro.org/
  - Fixed CHECK_DTBS warnings
  - Added missing properties in panel-simple.yaml

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Raphael Gallais-Pou (4):
      ARM: dts: stm32: add LTDC support for STM32MP13x SoC family
      ARM: dts: stm32: add LTDC pinctrl on STM32MP13x SoC family
      ARM: dts: stm32: enable display support on stm32mp135f-dk board
      dt-bindings: display: simple: hardware can use several properties

 .../bindings/display/panel/panel-simple.yaml       |  3 ++
 arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi        | 57 ++++++++++++++++++++++
 arch/arm/boot/dts/st/stm32mp135.dtsi               | 11 +++++
 arch/arm/boot/dts/st/stm32mp135f-dk.dts            | 53 ++++++++++++++++++++
 4 files changed, 124 insertions(+)
---
base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
change-id: 20240124-ltdc_mp13-2f86a782424c

Best regards,
-- 
Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>



From mshavit at google.com  Sat Feb 17 04:25:36 2024
From: mshavit at google.com (Michael Shavit)
Date: Sat, 17 Feb 2024 20:25:36 +0800
Subject: [PATCH rc v2] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
In-Reply-To: <20240216123606.GA13330@nvidia.com>
References: <0-v2-7988c2682634+261-smmu_cd_atomic_jgg@nvidia.com>
 <20240216120512.GA1841@willie-the-truck> <20240216123606.GA13330@nvidia.com>
Message-ID: <CAKHBV27eBnCrnXeaoqONWksh89tfX1b0=yvLfTkxviU_wKG_mw@mail.gmail.com>

On Fri, Feb 16, 2024 at 8:36?PM Jason Gunthorpe <jgg at nvidia.com> wrote:
>
> On Fri, Feb 16, 2024 at 12:05:12PM +0000, Will Deacon wrote:
> > On Thu, Feb 15, 2024 at 10:56:57AM -0400, Jason Gunthorpe wrote:
> > > If the SMMU is configured to use a two level CD table then
> > > arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
> > > GFP_KERNEL. Due to recent changes this is being done under a spinlock to
> > > iterate over the device list - thus it will trigger a sleeping while
> > > atomic warning:
> > >
> > >   arm_smmu_sva_set_dev_pasid()
> > >     mutex_lock(&sva_lock);
> > >     __arm_smmu_sva_bind()
> > >      arm_smmu_mmu_notifier_get()
> > >       spin_lock_irqsave()
> > >       arm_smmu_write_ctx_desc()
> > >     arm_smmu_get_cd_ptr()
> > >          arm_smmu_alloc_cd_leaf_table()
> > >       dmam_alloc_coherent(GFP_KERNEL)
> > >
> > > This is a 64K high order allocation and really should not be done
> > > atomically.
> > >
> > > At the moment the rework of the SVA to follow the new API is half
> > > finished. Recently the CD table memory was moved from the domain to the
> > > master, however we have the confusing situation where the SVA code is
> > > wrongly using the RID domains device's list to track which CD tables the
> > > SVA is installed in.
> > >
> > > Remove the logic to replicate the CD across all the domain's masters
> > > during attach. We know which master and which CD table the PASID should be
> > > installed in.
> > >
> > > At the moment SVA is only invoked when dma-iommu.c is in control of the
> > > RID translation, which means we have a single iommu_domain shared across
> > > the entire group and that iommu_domain is not shared outside the group.
> > >
> > > For PCI cases the core code also insists on singleton groups so there is
> > > only ever one entry in the smmu_domain->domains list that is equal to the
> > > master being passed in to arm_smmu_sva_set_dev_pasid().
> > >
> > > Only non-PCI cases may have multi-device groups. However, the core code it
> > > self will replicate the calls to arm_smmu_sva_set_dev_pasid() across the
> > > entire group so we will still correctly install the CD into each group
> > > members master.
> >
> > Are you sure about this paragraph? arm_smmu_mmu_notifier_get() will return
> > early if it finds an existing notifier in the 'mmu_notifiers' list for the
> > domain, so I don't think we'll actually get as far as installing the CD,
> > will we?
>
> I think the paragraph is the right analysis, the code just isn't
> listening very well..
>
> Lifting up the arm_smmu_write_ctx_desc() into the caller will fix it.

Calling arm_smmu_write_ctx_desc requires the CD which we get from the
mmu_notifiers list...which makes it a bit more complicated than that.
But it does sound doable with some work (perhaps keeping it in
arm_smmu_mmu_notifier_get for now and changing the early return
logic?).

>
> Also Michael should look at it (I recall we talked about this once)
> and Nicolin should test it.


Just to make sure I follow why we're pursuing this instead of the v1
rc patch: in the non-PCI multidevice group scenario, the first call to
set_dev_pasid would only have pre-allocated for the current master but
arm_smmu_mmu_notifier_get would then still write
arm_smmu_write_ctx_desc to other masters?

>
> BTW, I have no idea if non-PCI cases exists, everyone I know is doing
> PCI SVA.
>
> Jason


From mhiramat at kernel.org  Sat Feb 17 04:35:04 2024
From: mhiramat at kernel.org (Masami Hiramatsu (Google))
Date: Sat, 17 Feb 2024 21:35:04 +0900
Subject: [PATCH] arm64: kretprobes: acquire the regs via a BRK exception
In-Reply-To: <20240208145916.2004154-1-mark.rutland@arm.com>
References: <20240208145916.2004154-1-mark.rutland@arm.com>
Message-ID: <20240217213504.25434e2b6c887f718ba22f4d@kernel.org>

Hi Mark,

On Thu,  8 Feb 2024 14:59:16 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> On arm64, kprobes always take an exception and so create a struct
> pt_regs through the usual exception entry logic. Similarly kretprobes
> taskes and exception for function entry, but for function returns it
> uses a trampoline which attempts to create a struct pt_regs without
> taking an exception.
> 
> This is problematic for a few reasons, including:
> 
> 1) The kretprobes trampoline neither saves nor restores all of the
>    portions of PSTATE. Before invoking the handler it saves a number of
>    portions of PSTATE, and after returning from the handler it restores
>    NZCV before returning to the original return address provided by the
>    handler.
> 
> 2) The kretprobe trampoline constructs the PSTATE value piecemeal from
>    special purpose registers as it cannot read all of PSTATE atomically
>    without taking an exception. This is somewhat fragile, and it's not
>    possible to reliably recover PSTATE information which only exists on
>    some physical CPUs (e.g. when SSBS support is mismatched).
> 
>    Today the kretprobes trampoline does not record:
> 
>    - BTYPE
>    - SSBS
>    - ALLINT
>    - SS
>    - PAN
>    - UAO
>    - DIT
>    - TCO
> 
>    ... and this will only get worse with future architecture extensions
>    which add more PSTATE bits.
> 
> 3) The kretprobes trampoline doesn't store portions of struct pt_regs
>    (e.g. the PMR value when using pseudo-NMIs). Due to this, helpers
>    which operate on a struct pt_regs, such as interrupts_enabled(), may
>    not work correctly.
> 
> 4) The function entry and function exit handlers run in different
>    contexts. The entry handler will always be run in a debug exception
>    context (which is currently treated as an NMI), but the return will
>    be treated as whatever context the instrumented function was executed
>    in. The differences between these contexts are liable to cause
>    problems (e.g. as the two can be differently interruptible or
>    preemptible, adversely affecting synchronization between the
>    handlers).
> 
> 5) As the kretprobes trampoline runs in the same context as the code
>    being probed, it is subject to the same single-stepping context,
>    which may not be desirable if this is being driven by the kprobes
>    handlers.
> 
> Overall, this is fragile, painful to maintain, and gets in the way of
> supporting other things (e.g. RELIABLE_STACKTRACE, FEAT_NMI).

I agree all of those reasons.

> 
> This patch addresses these issues by replacing the kretprobes trampoline
> with a `BRK` instruction, and using an exception boundary to acquire and
> restore the regs, in the same way as the regular kprobes trampoline.

This design and code looks good to me.

> 
> Ive tested this atop v6.8-rc3:
> 
> | KTAP version 1
> | 1..1
> |     KTAP version 1
> |     # Subtest: kprobes_test
> |     # module: test_kprobes
> |     1..7
> |     ok 1 test_kprobe
> |     ok 2 test_kprobes
> |     ok 3 test_kprobe_missed
> |     ok 4 test_kretprobe
> |     ok 5 test_kretprobes
> |     ok 6 test_stacktrace_on_kretprobe
> |     ok 7 test_stacktrace_on_nested_kretprobe
> | # kprobes_test: pass:7 fail:0 skip:0 total:7
> | # Totals: pass:7 fail:0 skip:0 total:7
> | ok 1 kprobes_test

Acked-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>

Thank you!

> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Florent Revest <revest at chromium.org>
> Cc: Masami Hiramatsu <mhiramat at kernel.org>
> Cc: Steven Rostedt <rostedt at goodmis.org>
> ---
>  arch/arm64/include/asm/brk-imm.h              |  2 +
>  arch/arm64/kernel/probes/kprobes.c            | 21 +++--
>  arch/arm64/kernel/probes/kprobes_trampoline.S | 78 ++-----------------
>  3 files changed, 24 insertions(+), 77 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/brk-imm.h b/arch/arm64/include/asm/brk-imm.h
> index 1abdcd508a113..beb42c62b6acc 100644
> --- a/arch/arm64/include/asm/brk-imm.h
> +++ b/arch/arm64/include/asm/brk-imm.h
> @@ -11,6 +11,7 @@
>   * 0x004: for installing kprobes
>   * 0x005: for installing uprobes
>   * 0x006: for kprobe software single-step
> + * 0x007: for kretprobe return
>   * Allowed values for kgdb are 0x400 - 0x7ff
>   * 0x100: for triggering a fault on purpose (reserved)
>   * 0x400: for dynamic BRK instruction
> @@ -23,6 +24,7 @@
>  #define KPROBES_BRK_IMM			0x004
>  #define UPROBES_BRK_IMM			0x005
>  #define KPROBES_BRK_SS_IMM		0x006
> +#define KRETPROBES_BRK_IMM		0x007
>  #define FAULT_BRK_IMM			0x100
>  #define KGDB_DYN_DBG_BRK_IMM		0x400
>  #define KGDB_COMPILED_DBG_BRK_IMM	0x401
> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> index 70b91a8c6bb3f..327855a11df2f 100644
> --- a/arch/arm64/kernel/probes/kprobes.c
> +++ b/arch/arm64/kernel/probes/kprobes.c
> @@ -371,6 +371,21 @@ static struct break_hook kprobes_break_ss_hook = {
>  	.fn = kprobe_breakpoint_ss_handler,
>  };
>  
> +static int __kprobes
> +kretprobe_breakpoint_handler(struct pt_regs *regs, unsigned long esr)
> +{
> +	if (regs->pc != (unsigned long)__kretprobe_trampoline)
> +		return DBG_HOOK_ERROR;
> +
> +	regs->pc = kretprobe_trampoline_handler(regs, (void *)regs->regs[29]);
> +	return DBG_HOOK_HANDLED;
> +}
> +
> +static struct break_hook kretprobes_break_hook = {
> +	.imm = KRETPROBES_BRK_IMM,
> +	.fn = kretprobe_breakpoint_handler,
> +};
> +
>  /*
>   * Provide a blacklist of symbols identifying ranges which cannot be kprobed.
>   * This blacklist is exposed to userspace via debugfs (kprobes/blacklist).
> @@ -396,11 +411,6 @@ int __init arch_populate_kprobe_blacklist(void)
>  	return ret;
>  }
>  
> -void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
> -{
> -	return (void *)kretprobe_trampoline_handler(regs, (void *)regs->regs[29]);
> -}
> -
>  void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
>  				      struct pt_regs *regs)
>  {
> @@ -420,6 +430,7 @@ int __init arch_init_kprobes(void)
>  {
>  	register_kernel_break_hook(&kprobes_break_hook);
>  	register_kernel_break_hook(&kprobes_break_ss_hook);
> +	register_kernel_break_hook(&kretprobes_break_hook);
>  
>  	return 0;
>  }
> diff --git a/arch/arm64/kernel/probes/kprobes_trampoline.S b/arch/arm64/kernel/probes/kprobes_trampoline.S
> index 9a6499bed58b0..a362f3dbb3d11 100644
> --- a/arch/arm64/kernel/probes/kprobes_trampoline.S
> +++ b/arch/arm64/kernel/probes/kprobes_trampoline.S
> @@ -4,83 +4,17 @@
>   */
>  
>  #include <linux/linkage.h>
> -#include <asm/asm-offsets.h>
> +#include <asm/asm-bug.h>
>  #include <asm/assembler.h>
>  
>  	.text
>  
> -	.macro	save_all_base_regs
> -	stp x0, x1, [sp, #S_X0]
> -	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 x0, sp, #PT_REGS_SIZE
> -	stp lr, x0, [sp, #S_LR]
> -	/*
> -	 * Construct a useful saved PSTATE
> -	 */
> -	mrs x0, nzcv
> -	mrs x1, daif
> -	orr x0, x0, x1
> -	mrs x1, CurrentEL
> -	orr x0, x0, x1
> -	mrs x1, SPSel
> -	orr x0, x0, x1
> -	stp xzr, x0, [sp, #S_PC]
> -	.endm
> -
> -	.macro	restore_all_base_regs
> -	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]
> -	.endm
> -
>  SYM_CODE_START(__kretprobe_trampoline)
> -	sub sp, sp, #PT_REGS_SIZE
> -
> -	save_all_base_regs
> -
> -	/* Setup a frame pointer. */
> -	add x29, sp, #S_FP
> -
> -	mov x0, sp
> -	bl trampoline_probe_handler
>  	/*
> -	 * Replace trampoline address in lr with actual orig_ret_addr return
> -	 * address.
> +	 * Trigger a breakpoint exception. The PC will be adjusted by
> +	 * kretprobe_breakpoint_handler(), and no subsequent instructions will
> +	 * be executed from the trampoline.
>  	 */
> -	mov lr, x0
> -
> -	/* The frame pointer (x29) is restored with other registers. */
> -	restore_all_base_regs
> -
> -	add sp, sp, #PT_REGS_SIZE
> -	ret
> -
> +	brk #KRETPROBES_BRK_IMM
> +	ASM_BUG()
>  SYM_CODE_END(__kretprobe_trampoline)
> -- 
> 2.30.2
> 


-- 
Masami Hiramatsu (Google) <mhiramat at kernel.org>


From alexandre.belloni at bootlin.com  Sat Feb 17 04:42:23 2024
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Sat, 17 Feb 2024 13:42:23 +0100
Subject: [PATCH 1/3] dt-bindings: i3c: drop "master" node name suffix
In-Reply-To: <00d6a0d5-6787-4777-8fb2-dcad4304a724@linaro.org>
References: <20240117075618.81932-1-krzysztof.kozlowski@linaro.org>
 <00d6a0d5-6787-4777-8fb2-dcad4304a724@linaro.org>
Message-ID: <2024021712422352187ad4@mail.local>

On 16/02/2024 12:26:12+0100, Krzysztof Kozlowski wrote:
> On 17/01/2024 08:56, Krzysztof Kozlowski wrote:
> > Drop the requirement of "-master" suffix in node names because:
> > 1. "Master" word is discouraged and MIPI Alliance renamed it to
> >    "Controller".
> > 2. Some devices can operate in Controller (Master) or Target mode, thus
> >    the name is not accurate in such cases.
> > 3. Other buses, like I2C controllers, use simple "i2c".
> > 
> > Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> > ---
> 
> Rob, can you pick this one up? It seems Alexandre did not take it.
> 

I'll take it but I don't think it is super urgent.

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From jgg at nvidia.com  Sat Feb 17 05:24:46 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Sat, 17 Feb 2024 09:24:46 -0400
Subject: [PATCH rc v2] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <CAKHBV27eBnCrnXeaoqONWksh89tfX1b0=yvLfTkxviU_wKG_mw@mail.gmail.com>
References: <0-v2-7988c2682634+261-smmu_cd_atomic_jgg@nvidia.com>
 <20240216120512.GA1841@willie-the-truck>
 <20240216123606.GA13330@nvidia.com>
 <CAKHBV27eBnCrnXeaoqONWksh89tfX1b0=yvLfTkxviU_wKG_mw@mail.gmail.com>
Message-ID: <20240217132446.GJ13330@nvidia.com>

On Sat, Feb 17, 2024 at 08:25:36PM +0800, Michael Shavit wrote:

> Calling arm_smmu_write_ctx_desc requires the CD which we get from the
> mmu_notifiers list...which makes it a bit more complicated than
> that.

@@ -404,9 +384,15 @@ static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
                goto err_free_bond;
        }
 
+       ret = arm_smmu_write_ctx_desc(master, pasid, bond->smmu_mn->cd);
+       if (ret)
+               goto err_put_notifier;
+


> > Also Michael should look at it (I recall we talked about this once)
> > and Nicolin should test it.
> 
> Just to make sure I follow why we're pursuing this instead of the v1
> rc patch: in the non-PCI multidevice group scenario, the first call to
> set_dev_pasid would only have pre-allocated for the current master but
> arm_smmu_mmu_notifier_get would then still write
> arm_smmu_write_ctx_desc to other masters?

Yes, though noting I have no idea if non-PCI exist but it does make
the code clearer and removes even the possibility of a non-atomic
allocation

Jason


From wahrenst at gmx.net  Sat Feb 17 05:37:22 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Sat, 17 Feb 2024 14:37:22 +0100
Subject: [PATCH] PCI: brcmstb: fix broken brcm_pcie_mdio_write() polling
Message-ID: <20240217133722.14391-1-wahrenst@gmx.net>

From: Jonathan Bell <jonathan at raspberrypi.com>

MDIO_WR_DONE() tests bit 31, which is always 0 (==done) as
readw_poll_timeout_atomic does a 16-bit read. Replace with the readl
variant.

Fixes: ca5dcc76314d ("PCI: brcmstb: Replace status loops with read_poll_timeout_atomic()")
Signed-off-by: Jonathan Bell <jonathan at raspberrypi.com>
Signed-off-by: Stefan Wahren <wahrenst at gmx.net>
---
 drivers/pci/controller/pcie-brcmstb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 618e84402eb50..a7f05e0c4ac51 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -420,7 +420,7 @@ static int brcm_pcie_mdio_write(void __iomem *base, u8 port,
 	readl(base + PCIE_RC_DL_MDIO_ADDR);
 	writel(MDIO_DATA_DONE_MASK | wrdata, base + PCIE_RC_DL_MDIO_WR_DATA);

-	err = readw_poll_timeout_atomic(base + PCIE_RC_DL_MDIO_WR_DATA, data,
+	err = readl_poll_timeout_atomic(base + PCIE_RC_DL_MDIO_WR_DATA, data,
 					MDIO_WT_DONE(data), 10, 100);
 	return err;
 }


From krzysztof.kozlowski at linaro.org  Sat Feb 17 05:42:25 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 14:42:25 +0100
Subject: [PATCH 1/3] dt-bindings: i3c: drop "master" node name suffix
In-Reply-To: <2024021712422352187ad4@mail.local>
References: <20240117075618.81932-1-krzysztof.kozlowski@linaro.org>
 <00d6a0d5-6787-4777-8fb2-dcad4304a724@linaro.org>
 <2024021712422352187ad4@mail.local>
Message-ID: <4b34c495-4aaa-4dd3-b7b0-b9d54baf9338@linaro.org>

On 17/02/2024 13:42, Alexandre Belloni wrote:
> On 16/02/2024 12:26:12+0100, Krzysztof Kozlowski wrote:
>> On 17/01/2024 08:56, Krzysztof Kozlowski wrote:
>>> Drop the requirement of "-master" suffix in node names because:
>>> 1. "Master" word is discouraged and MIPI Alliance renamed it to
>>>    "Controller".
>>> 2. Some devices can operate in Controller (Master) or Target mode, thus
>>>    the name is not accurate in such cases.
>>> 3. Other buses, like I2C controllers, use simple "i2c".
>>>
>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>> ---
>>
>> Rob, can you pick this one up? It seems Alexandre did not take it.
>>
> 
> I'll take it but I don't think it is super urgent.

It's not, but it was almost two weeks and we are also getting to end of
applying cycle of some maintainers, so I was going through my pending
stuff. Apologies if this was too pingi-ping.

Best regards,
Krzysztof



From quic_mkshah at quicinc.com  Sat Feb 17 05:57:06 2024
From: quic_mkshah at quicinc.com (Maulik Shah)
Date: Sat, 17 Feb 2024 19:27:06 +0530
Subject: [PATCH 0/2] Update init level for cmd-db, rpmh-rsc and psci
 cpuidle domains
Message-ID: <20240217-init_level-v1-0-bde9e11f8317@quicinc.com>

cmd-db and rpmh-rsc are used by clients like regulators, interconnects and
clocks for resource voting. These clients are in core_initcall() while
cmd-db and rpmh-rsc are in arch_initcall(). Update init level for these
drivers also to core_initcall() to avoid unnecessary probe defer during
boot up.

Similarly psci cpuidle psci power domains are used by rpmh-rsc driver and
they are in subsys_initcall(). Update it to core_initcall().

Signed-off-by: Maulik Shah <quic_mkshah at quicinc.com>
---
Maulik Shah (2):
      soc: qcom: Update init level to core_initcall() for cmd-db and rpmh-rsc
      cpuidle: psci: Update init level to core_initcall()

 drivers/cpuidle/cpuidle-psci-domain.c | 2 +-
 drivers/soc/qcom/cmd-db.c             | 2 +-
 drivers/soc/qcom/rpmh-rsc.c           | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
---
base-commit: d37e1e4c52bc60578969f391fb81f947c3e83118
change-id: 20240217-init_level-beb6d740d8d2

Best regards,
-- 
Maulik Shah <quic_mkshah at quicinc.com>



From quic_mkshah at quicinc.com  Sat Feb 17 05:57:07 2024
From: quic_mkshah at quicinc.com (Maulik Shah)
Date: Sat, 17 Feb 2024 19:27:07 +0530
Subject: [PATCH 1/2] soc: qcom: Update init level to core_initcall() for
 cmd-db and rpmh-rsc
In-Reply-To: <20240217-init_level-v1-0-bde9e11f8317@quicinc.com>
References: <20240217-init_level-v1-0-bde9e11f8317@quicinc.com>
Message-ID: <20240217-init_level-v1-1-bde9e11f8317@quicinc.com>

cmd-db and rpmh-rsc are used by clients like regulators, interconnects and
clocks for resource voting. These clients are in core_initcall() while
cmd-db and rpmh-rsc are in arch_initcall(). Update init level for these
drivers also to core_initcall() to avoid unnecessary probe defer during
boot up.

Signed-off-by: Maulik Shah <quic_mkshah at quicinc.com>
---
 drivers/soc/qcom/cmd-db.c   | 2 +-
 drivers/soc/qcom/rpmh-rsc.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
index a5fd68411bed..c344107bc36c 100644
--- a/drivers/soc/qcom/cmd-db.c
+++ b/drivers/soc/qcom/cmd-db.c
@@ -362,7 +362,7 @@ static int __init cmd_db_device_init(void)
 {
 	return platform_driver_register(&cmd_db_dev_driver);
 }
-arch_initcall(cmd_db_device_init);
+core_initcall(cmd_db_device_init);
 
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Command DB Driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
index a021dc71807b..c4c7aad957e6 100644
--- a/drivers/soc/qcom/rpmh-rsc.c
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -1154,7 +1154,7 @@ static int __init rpmh_driver_init(void)
 {
 	return platform_driver_register(&rpmh_driver);
 }
-arch_initcall(rpmh_driver_init);
+core_initcall(rpmh_driver_init);
 
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPMh Driver");
 MODULE_LICENSE("GPL v2");

-- 
2.22.0



From quic_mkshah at quicinc.com  Sat Feb 17 05:57:08 2024
From: quic_mkshah at quicinc.com (Maulik Shah)
Date: Sat, 17 Feb 2024 19:27:08 +0530
Subject: [PATCH 2/2] cpuidle: psci: Update init level to core_initcall()
In-Reply-To: <20240217-init_level-v1-0-bde9e11f8317@quicinc.com>
References: <20240217-init_level-v1-0-bde9e11f8317@quicinc.com>
Message-ID: <20240217-init_level-v1-2-bde9e11f8317@quicinc.com>

Clients like regulators, interconnects and clocks depend on rpmh-rsc to
vote on resources and rpmh-rsc depends on psci power-domains to complete
probe. All of them are in core_initcall().

Change psci domain init level to core_initcall() to avoid probe defer from
all of the above.

Signed-off-by: Maulik Shah <quic_mkshah at quicinc.com>
---
 drivers/cpuidle/cpuidle-psci-domain.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
index b88af1262f1a..3e5b1150f75b 100644
--- a/drivers/cpuidle/cpuidle-psci-domain.c
+++ b/drivers/cpuidle/cpuidle-psci-domain.c
@@ -200,4 +200,4 @@ static int __init psci_idle_init_domains(void)
 {
 	return platform_driver_register(&psci_cpuidle_domain_driver);
 }
-subsys_initcall(psci_idle_init_domains);
+core_initcall(psci_idle_init_domains);

-- 
2.22.0



From skseofh at gmail.com  Sat Feb 17 06:03:26 2024
From: skseofh at gmail.com (skseofh at gmail.com)
Date: Sat, 17 Feb 2024 23:03:26 +0900
Subject: [PATCH] arm64: add early fixmap initialization flag
Message-ID: <20240217140326.2367186-1-skseofh@gmail.com>

From: Daero Lee <skseofh at gmail.com>

early_fixmap_init may be called multiple times. Since there is no
change in the page table after early fixmap initialization, an
initialization flag was added.

Signed-off-by: Daero Lee <skseofh at gmail.com>
---
 arch/arm64/mm/fixmap.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
index c0a3301203bd..fbdd5f30f3a1 100644
--- a/arch/arm64/mm/fixmap.c
+++ b/arch/arm64/mm/fixmap.c
@@ -32,6 +32,8 @@ static pte_t bm_pte[NR_BM_PTE_TABLES][PTRS_PER_PTE] __page_aligned_bss;
 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 int early_fixmap_initialized __initdata;
+
 static inline pte_t *fixmap_pte(unsigned long addr)
 {
 	return &bm_pte[BM_PTE_TABLE_IDX(addr)][pte_index(addr)];
@@ -100,10 +102,15 @@ void __init early_fixmap_init(void)
 	unsigned long addr = FIXADDR_TOT_START;
 	unsigned long end = FIXADDR_TOP;
 
+	if (early_fixmap_initialized)
+		return;
+
 	pgd_t *pgdp = pgd_offset_k(addr);
 	p4d_t *p4dp = p4d_offset(pgdp, addr);
 
 	early_fixmap_init_pud(p4dp, addr, end);
+
+	early_fixmap_initialized = 1;
 }
 
 /*
-- 
2.25.1



From stano.jakubek at gmail.com  Sat Feb 17 06:17:15 2024
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Sat, 17 Feb 2024 15:17:15 +0100
Subject: [PATCH] dt-bindings: watchdog: drop obsolete brcm,bcm2835-pm-wdt
 bindings
Message-ID: <ZdC/624d1c8O3NRG@standask-GA-A55M-S2HP>

These bindings are already (better) described in soc/bcm/brcm,bcm2835-pm.
Drop these obsolete bindings.

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
 .../bindings/watchdog/brcm,bcm2835-pm-wdog.txt | 18 ------------------
 1 file changed, 18 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt

diff --git a/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt b/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt
deleted file mode 100644
index f801d71de1cd..000000000000
--- a/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-BCM2835 Watchdog timer
-
-Required properties:
-
-- compatible : should be "brcm,bcm2835-pm-wdt"
-- reg : Specifies base physical address and size of the registers.
-
-Optional properties:
-
-- timeout-sec   : Contains the watchdog timeout in seconds
-
-Example:
-
-watchdog {
-	compatible = "brcm,bcm2835-pm-wdt";
-	reg = <0x7e100000 0x28>;
-	timeout-sec = <10>;
-};
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Sat Feb 17 06:25:30 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 15:25:30 +0100
Subject: [PATCH 2/4] dt-bindings: hwinfo: ti,k3-socinfo: Add nvmem-cells
In-Reply-To: <z56fiu2jpokp57sjvnrdcbfy7brpq2ag4yxpektqlhtidecx4n@vc7dsurhxorb>
References: <20240206143711.2410135-1-msp@baylibre.com>
 <20240206143711.2410135-3-msp@baylibre.com>
 <20240206184305.GA1875492-robh@kernel.org>
 <z56fiu2jpokp57sjvnrdcbfy7brpq2ag4yxpektqlhtidecx4n@vc7dsurhxorb>
Message-ID: <cb75c098-521e-4eed-bc3e-7237f8a6498f@linaro.org>

On 14/02/2024 10:31, Markus Schneider-Pargmann wrote:
> Hi Rob,
> 
> On Tue, Feb 06, 2024 at 06:43:05PM +0000, Rob Herring wrote:
>> On Tue, Feb 06, 2024 at 03:37:09PM +0100, Markus Schneider-Pargmann wrote:
>>> The information k3-socinfo requires is stored in an efuse area. This
>>> area is required by other devices/drivers as well, so using nvmem-cells
>>> can be a cleaner way to describe which information are used.
>>>
>>> If nvmem-cells are supplied, the address range is not required.
>>> Cells chipvariant, chippartno and chipmanufacturer are introduced to
>>> cover all required information.
>>>
>>> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
>>> Reviewed-by: Andrew Davis <afd at ti.com>
>>> ---
>>>  .../bindings/hwinfo/ti,k3-socinfo.yaml        | 23 ++++++++++++++++++-
>>>  1 file changed, 22 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
>>> index dada28b47ea0..f085b7275b7d 100644
>>> --- a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
>>> +++ b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml
>>> @@ -26,9 +26,24 @@ properties:
>>>    reg:
>>>      maxItems: 1
>>>  
>>> +  nvmem-cells:
>>> +    $ref: /schemas/types.yaml#/definitions/phandle-array
>>> +
>>> +  nvmem-cell-names:
>>> +    items:
>>> +      - const: chipvariant
>>> +      - const: chippartno
>>> +      - const: chipmanufacturer
>>> +
>>>  required:
>>>    - compatible
>>> -  - reg
>>> +
>>> +oneOf:
>>> +  - required:
>>> +      - reg
>>> +  - required:
>>> +      - nvmem-cells
>>> +      - nvmem-cell-names
>>>  
>>>  additionalProperties: false
>>>  
>>> @@ -38,3 +53,9 @@ examples:
>>>          compatible = "ti,am654-chipid";
>>>          reg = <0x43000014 0x4>;
>>>      };
>>> +  - |
>>> +    chipid: chipid at 14 {
>>> +        compatible = "ti,am654-chipid";
>>
>> This isn't compatible if you have a completely different way to access 
>> it. 
> 
> Thanks, it is not entirely clear to me how I could go forward with this?
> Are you suggesting to use a different compatible? Or is it something
> else I could do to proceed with this conversion?

What you claim now, is that you have one device with entirely different
interfaces and programming model. So either this is not the same device
or you just wrote bindings to whatever you have in driver.

Nothing in commit msg explains this.

What you should do? Depends. If you just write bindings for driver, then
stop. It's a NAK. Instead write bindings for hardware.

If the first choice, just the hardware is somehow like this, then
explain in commit msg and device description, how this device can be
connected over other bus, not MMIO. You can draw some schematics in
commit msg explaining architecture etc.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 06:27:21 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 15:27:21 +0100
Subject: [PATCH 1/3] dt-bindings: cpufreq: Add nvmem-cells for chip
 information
In-Reply-To: <98c9d3ce-8a97-499f-b78a-b918a06ec779@linaro.org>
References: <20240206145721.2418893-1-msp@baylibre.com>
 <20240206145721.2418893-2-msp@baylibre.com>
 <98c9d3ce-8a97-499f-b78a-b918a06ec779@linaro.org>
Message-ID: <321bdb3d-d377-4044-b8c9-02f7e1af1b6a@linaro.org>

On 15/02/2024 09:24, Krzysztof Kozlowski wrote:
> On 06/02/2024 15:57, Markus Schneider-Pargmann wrote:
>> Add nvmem-cells to describe chip information like chipvariant and
>> chipspeed. If nvmem-cells are used, the syscon property is not necessary
>> anymore.
>>
>> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
>> Acked-by: Andrew Davis <afd at ti.com>
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

NAK

And unreviewed. Please carry on:

Nacked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

I found older discussion with Rob, who pointed out that one device
cannot have entirely different programming models, so this patchset has
the same errors. None of the previous issues were fixed here.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 17 06:27:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 17 Feb 2024 15:27:38 +0100
Subject: [PATCH 1/3] dt-bindings: cpufreq: Add nvmem-cells for chip
 information
In-Reply-To: <20240206145721.2418893-2-msp@baylibre.com>
References: <20240206145721.2418893-1-msp@baylibre.com>
 <20240206145721.2418893-2-msp@baylibre.com>
Message-ID: <f84a4933-ce7a-4820-9b57-84a1549602ff@linaro.org>

On 06/02/2024 15:57, Markus Schneider-Pargmann wrote:
> Add nvmem-cells to describe chip information like chipvariant and
> chipspeed. If nvmem-cells are used, the syscon property is not necessary
> anymore.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> Acked-by: Andrew Davis <afd at ti.com>
> ---
>  .../bindings/opp/operating-points-v2-ti-cpu.yaml | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml b/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml
> index 02d1d2c17129..b1881a0834fe 100644
> --- a/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml
> +++ b/Documentation/devicetree/bindings/opp/operating-points-v2-ti-cpu.yaml
> @@ -34,6 +34,14 @@ properties:
>        points to syscon node representing the control module
>        register space of the SoC.
>  
> +  nvmem-cells:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array

Why redefining the type?

Best regards,
Krzysztof



From ardb at kernel.org  Sat Feb 17 06:34:30 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sat, 17 Feb 2024 15:34:30 +0100
Subject: [syzbot] [arm?] [crypto?] KASAN: invalid-access Read in neon_aes_ctr_encrypt
In-Reply-To: <000000000000ff2c3f061189df71@google.com>
References: <000000000000ff2c3f061189df71@google.com>
Message-ID: <CAMj1kXHQYuv2H5XA+abgj+Mw8xyxsoHARx2w-tT7jRrDLQ=EVg@mail.gmail.com>

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git
neon-aes-ctr-fix

On Sat, 17 Feb 2024 at 02:35, syzbot
<syzbot+f1ceaa1a09ab891e1934 at syzkaller.appspotmail.com> wrote:
>
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit:    c664e16bb1ba Merge tag 'docs-6.8-fixes2' of git://git.lwn...
> git tree:       upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=13e83cc8180000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=b4dde08ba7d52a4b
> dashboard link: https://syzkaller.appspot.com/bug?extid=f1ceaa1a09ab891e1934
> compiler:       aarch64-linux-gnu-gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
> userspace arch: arm64
> syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=13fff792180000
> C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=15cbe4dc180000
>
> Downloadable assets:
> disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/384ffdcca292/non_bootable_disk-c664e16b.raw.xz
> vmlinux: https://storage.googleapis.com/syzbot-assets/864da5a66121/vmlinux-c664e16b.xz
> kernel image: https://storage.googleapis.com/syzbot-assets/044de3e4ddc5/Image-c664e16b.gz.xz
>
> IMPORTANT: if you fix the issue, please add the following tag to the commit:
> Reported-by: syzbot+f1ceaa1a09ab891e1934 at syzkaller.appspotmail.com
>
> ==================================================================
> BUG: KASAN: invalid-access in neon_aes_ctr_encrypt+0x15c/0x1ec arch/arm64/crypto/aes-modes.S:599
> Read at addr fcff000006797ff1 by task syz-executor675/3149
> Pointer tag: [fc], memory tag: [fe]
>
> CPU: 1 PID: 3149 Comm: syz-executor675 Not tainted 6.8.0-rc4-syzkaller-00005-gc664e16bb1ba #0
> Hardware name: linux,dummy-virt (DT)
> Call trace:
>  dump_backtrace+0x94/0xec arch/arm64/kernel/stacktrace.c:291
>  show_stack+0x18/0x24 arch/arm64/kernel/stacktrace.c:298
>  __dump_stack lib/dump_stack.c:88 [inline]
>  dump_stack_lvl+0x48/0x60 lib/dump_stack.c:106
>  print_address_description mm/kasan/report.c:377 [inline]
>  print_report+0x108/0x618 mm/kasan/report.c:488
>  kasan_report+0x88/0xac mm/kasan/report.c:601
>  report_tag_fault arch/arm64/mm/fault.c:334 [inline]
>  do_tag_recovery arch/arm64/mm/fault.c:346 [inline]
>  __do_kernel_fault+0x17c/0x1e8 arch/arm64/mm/fault.c:393
>  do_bad_area arch/arm64/mm/fault.c:493 [inline]
>  do_tag_check_fault+0x78/0x8c arch/arm64/mm/fault.c:772
>  do_mem_abort+0x44/0x94 arch/arm64/mm/fault.c:848
>  el1_abort+0x40/0x60 arch/arm64/kernel/entry-common.c:398
>  el1h_64_sync_handler+0xd8/0xe4 arch/arm64/kernel/entry-common.c:458
>  el1h_64_sync+0x64/0x68 arch/arm64/kernel/entry.S:593
>  neon_aes_ctr_encrypt+0x15c/0x1ec arch/arm64/crypto/aes-modes.S:599
>  ctr_encrypt+0xfc/0x144 arch/arm64/crypto/aes-neonbs-glue.c:230
>  crypto_skcipher_decrypt+0x4c/0x60 crypto/skcipher.c:695
>  _skcipher_recvmsg crypto/algif_skcipher.c:199 [inline]
>  skcipher_recvmsg+0x39c/0x46c crypto/algif_skcipher.c:221
>  sock_recvmsg_nosec net/socket.c:1046 [inline]
>  sock_recvmsg net/socket.c:1068 [inline]
>  sock_recvmsg net/socket.c:1064 [inline]
>  sock_read_iter+0xec/0x118 net/socket.c:1138
>  call_read_iter include/linux/fs.h:2079 [inline]
>  new_sync_read fs/read_write.c:395 [inline]
>  vfs_read+0x2cc/0x304 fs/read_write.c:476
>  ksys_read+0xe8/0x104 fs/read_write.c:619
>  __do_sys_read fs/read_write.c:629 [inline]
>  __se_sys_read fs/read_write.c:627 [inline]
>  __arm64_sys_read+0x1c/0x28 fs/read_write.c:627
>  __invoke_syscall arch/arm64/kernel/syscall.c:37 [inline]
>  invoke_syscall+0x48/0x114 arch/arm64/kernel/syscall.c:51
>  el0_svc_common.constprop.0+0x40/0xe0 arch/arm64/kernel/syscall.c:136
>  do_el0_svc+0x1c/0x28 arch/arm64/kernel/syscall.c:155
>  el0_svc+0x34/0xd8 arch/arm64/kernel/entry-common.c:678
>  el0t_64_sync_handler+0x100/0x12c arch/arm64/kernel/entry-common.c:696
>  el0t_64_sync+0x19c/0x1a0 arch/arm64/kernel/entry.S:598
>
> The buggy address belongs to the physical page:
> page:0000000060acabc6 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x46797
> flags: 0x1ffc28000000000(node=0|zone=0|lastcpupid=0x7ff|kasantag=0xa)
> page_type: 0xffffffff()
> raw: 01ffc28000000000 fffffc0000168bc8 fffffc0000199e08 0000000000000000
> raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
> page dumped because: kasan: bad access detected
>
> Memory state around the buggy address:
>  ffff000006797d00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
>  ffff000006797e00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
> >ffff000006797f00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
>                                                                 ^
>  ffff000006798000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>  ffff000006798100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> ==================================================================
>
>
> ---
> This report is generated by a bot. It may contain errors.
> See https://goo.gl/tpsmEJ for more information about syzbot.
> syzbot engineers can be reached at syzkaller at googlegroups.com.
>
> syzbot will keep track of this issue. See:
> https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
>
> If the report is already addressed, let syzbot know by replying with:
> #syz fix: exact-commit-title
>
> If you want syzbot to run the reproducer, reply with:
> #syz test: git://repo/address.git branch-or-commit-hash
> If you attach or paste a git patch, syzbot will apply it before testing.
>
> If you want to overwrite report's subsystems, reply with:
> #syz set subsystems: new-subsystem
> (See the list of subsystem names on the web dashboard)
>
> If the report is a duplicate of another one, reply with:
> #syz dup: exact-subject-of-another-report
>
> If you want to undo deduplication, reply with:
> #syz undup
>


From syzbot+f1ceaa1a09ab891e1934 at syzkaller.appspotmail.com  Sat Feb 17 07:01:04 2024
From: syzbot+f1ceaa1a09ab891e1934 at syzkaller.appspotmail.com (syzbot)
Date: Sat, 17 Feb 2024 07:01:04 -0800
Subject: [syzbot] [arm?] [crypto?] KASAN: invalid-access Read in neon_aes_ctr_encrypt
In-Reply-To: <CAMj1kXHQYuv2H5XA+abgj+Mw8xyxsoHARx2w-tT7jRrDLQ=EVg@mail.gmail.com>
Message-ID: <00000000000031b790061195214f@google.com>

Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-and-tested-by: syzbot+f1ceaa1a09ab891e1934 at syzkaller.appspotmail.com

Tested on:

commit:         67e0a702 crypto: arm64/neonbs - fix out-of-bounds acce..
git tree:       git://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git neon-aes-ctr-fix
console output: https://syzkaller.appspot.com/x/log.txt?x=122f4464180000
kernel config:  https://syzkaller.appspot.com/x/.config?x=b4dde08ba7d52a4b
dashboard link: https://syzkaller.appspot.com/bug?extid=f1ceaa1a09ab891e1934
compiler:       aarch64-linux-gnu-gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
userspace arch: arm64

Note: no patches were applied.
Note: testing is done by a robot and is best-effort only.


From quic_kathirav at quicinc.com  Sat Feb 17 07:41:25 2024
From: quic_kathirav at quicinc.com (Kathiravan Thirumoorthy)
Date: Sat, 17 Feb 2024 21:11:25 +0530
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <9638a213-76a5-4a72-b6b2-018ae50305be@lunn.ch>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com>
 <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
 <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
 <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com>
 <9638a213-76a5-4a72-b6b2-018ae50305be@lunn.ch>
Message-ID: <6c64a7fa-2cc4-4791-8af1-1a4972c3856b@quicinc.com>



On 2/16/2024 10:46 PM, Andrew Lunn wrote:
>> You can get the source at https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016/-/tree/NHSS.QSDK.12.2?ref_type=heads
> 
> Cool, thanks. But is it really u-boot from 2016?


Yes, it is. If you want to try on IPQ95xx / IPQ53xx SoCs, you can also 
use the 2023's u-boot, which is available at [1].

[1] 
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot/-/tree/NHSS.QSDK.12.4.5?ref_type=heads

> 
>> Yeah agree with your comments.
>>
>> QSDK's u-boot enables the network support, so the required NSSCC clocks are
>> turned ON and left it in ON state. CCF tries to disables the unused NSSCC
>> clocks but system goes for reboot.
>>
>> Reason being, to access the NSSCC clocks, these GCC clocks
>> (gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk)
>> should be turned ON. But CCF disables these clocks as well due to the lack
>> of consumer.
> 
> So there is your solution, make NSSCC a consumer of the clocks it
> actually consumes. If it needs these clocks, it should get and enable
> them.


Thanks for the suggestion. I will include these clocks in NSSCC DT node 
and enable the same in the NSSCC driver probe.


> 	Andrew


From quic_kathirav at quicinc.com  Sat Feb 17 07:44:55 2024
From: quic_kathirav at quicinc.com (Kathiravan Thirumoorthy)
Date: Sat, 17 Feb 2024 21:14:55 +0530
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <CAA8EJppe6aNf2WJ5BvaX8SPTbuaEwzRm74F8QKyFtbmnGQt=1w@mail.gmail.com>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com>
 <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
 <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
 <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com>
 <CAA8EJppe6aNf2WJ5BvaX8SPTbuaEwzRm74F8QKyFtbmnGQt=1w@mail.gmail.com>
Message-ID: <74f585c2-d220-4324-96eb-1a945fef9608@quicinc.com>


<snip>

>> Reason being, to access the NSSCC clocks, these GCC clocks
>> (gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk)
>> should be turned ON. But CCF disables these clocks as well due to the
>> lack of consumer.
> 
> This means that NSSCC is also a consumer of those clocks. Please fix
> both DT and nsscc driver to handle NSSNOC clocks.


Thanks Dmitry. I shall include these clocks in the NSSCC DT node and 
enable the same in the NSSCC driver probe.

> 
>>> Once you have actual drivers, this should solve itself, the drivers
>>> will consume the clocks.
>>
>>
>> Given that, NSSCC is being built as module, there is no issue in booting
>> the kernel. But if you do insmod of the nsscc-ipq5332.ko, system will
>> reset.
>>
>> Without the networking drivers, there is no need to install this module.
>> And as you stated, once the drivers are available, there will be no issues.
>>
>> So can I explain the shortcomings of installing this module without the
>> networking drivers in cover letter and drop this patch all together?
> 
> No. Using allyesconfig or allmodconfig and installing the full modules
> set should work.
> 


Okay, Got it. Thanks for the information.

<snip>


From broonie at kernel.org  Sat Feb 17 07:48:05 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 17 Feb 2024 15:48:05 +0000
Subject: [PATCH v5 03/18] dt-bindings: regulator: describe the PMU module
 of the QCA6390 package
In-Reply-To: <20240216203215.40870-4-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-4-brgl@bgdev.pl>
Message-ID: <ZdDVNbjv60G9YUNy@finisterre.sirena.org.uk>

On Fri, Feb 16, 2024 at 09:32:00PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> The QCA6390 package contains discreet modules for WLAN and Bluetooth. They
> are powered by the Power Management Unit (PMU) that takes inputs from the
> host and provides LDO outputs. This document describes this module.

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/20240217/27f04f3d/attachment.sig>

From martin.fuzzey at flowbird.group  Sat Feb 17 08:15:39 2024
From: martin.fuzzey at flowbird.group (Fuzzey, Martin)
Date: Sat, 17 Feb 2024 17:15:39 +0100
Subject: TI am625 deepsleep wakeup from main domain
Message-ID: <CANh8Qzx-aratebzbkYGLiL+ij5MPmvfuzZtu70AL=9JgLjZ8tw@mail.gmail.com>

Hi all,

I have deep sleep entry and exit working on TI AM625 using the RTC or
MCU domain GPIO using the upstream 6.6 kernel plus [0]
However I am unable to get it to work using a MAIN domain GPIO
(nothing happens and no measurable change in power consumption on
wakeup attempt).

To do that I also applied 3717194f2492 "Input: gpio-keys - add system
suspend support for dedicated wake irqs"
(which is already in mainline but not -6.6)

Then in DT (based on the TI docs)
&main_pmx0 {
    /* attempt at GPIO domain wakeup - when working move to SoC dtsi */
    compatible = "ti,am654-padconf";
    interrupt-parent = <&gic500>;
    interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
    interrupt-controller;
    #interrupt-cells = <1>;

    pinctrl_flb_carrier_gpio_keys: flb-gpiokeys-grp {
        pinctrl-single,pins = <
            AM62X_IOPAD(0x1a8, PIN_INPUT,  7) /*(D20)
MCASP0_AFSX.GPIO1_12 -  SODIMM 32 */
        >;
    };
};

gpio-keys {
    compatible = "gpio-keys";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flb_carrier_gpio_keys>;

    key-gpio {
        interrupts-extended = <&main_gpio1 12 IRQ_TYPE_EDGE_BOTH>,
<&main_pmx0 0x1a8>;
        interrupt-names = "irq", "wakeup";
        label = "GPIO Button";
        linux,code = <KEY_WAKEUP>;
        wakeup-source;
    };
};

(The reason for overriding the compatible on the the pinmux mode is
that the pinctrl_single driver already has the appropriate bits for
that compatible
sure it's a hack but should be ok for testing):

static const struct pcs_soc_data pinctrl_single_am654 = {
    .flags = PCS_QUIRK_SHARED_IRQ | PCS_CONTEXT_LOSS_OFF,
    .irq_enable_mask = (1 << 29),   /* WKUP_EN */
    .irq_status_mask = (1 << 30),   /* WKUP_EVT */
};

static const struct of_device_id pcs_of_match[] = {
...
    { .compatible = "ti,am654-padconf", .data = &pinctrl_single_am654 },
...
};

With this I see that bit 29 (WKUP_EN) of the pad config register is
being set but it doesn't wake up..
I do get input events when not suspended (so that should eliminate bad
hardware) and have checked that the button GPIO line still has power
in suspend.

Am I missing any other pieces here?

One thing I don't really understand is how the DM firmware knows what
wakeup sources should be enabled.

Any help much appreciated,

Martin


[0] https://lore.kernel.org/all/20230804115037.754994-1-d-gole at ti.com/


From dmitry.baryshkov at linaro.org  Sat Feb 17 08:45:40 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sat, 17 Feb 2024 18:45:40 +0200
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <74f585c2-d220-4324-96eb-1a945fef9608@quicinc.com>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com> <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com> <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
 <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com> <CAA8EJppe6aNf2WJ5BvaX8SPTbuaEwzRm74F8QKyFtbmnGQt=1w@mail.gmail.com>
 <74f585c2-d220-4324-96eb-1a945fef9608@quicinc.com>
Message-ID: <CAA8EJppuNRB9fhjimg4SUR2PydX7-KLWSb9H-nC-oSMYVOME-Q@mail.gmail.com>

On Sat, 17 Feb 2024 at 17:45, Kathiravan Thirumoorthy
<quic_kathirav at quicinc.com> wrote:
>
>
> <snip>
>
> >> Reason being, to access the NSSCC clocks, these GCC clocks
> >> (gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk)
> >> should be turned ON. But CCF disables these clocks as well due to the
> >> lack of consumer.
> >
> > This means that NSSCC is also a consumer of those clocks. Please fix
> > both DT and nsscc driver to handle NSSNOC clocks.
>
>
> Thanks Dmitry. I shall include these clocks in the NSSCC DT node and
> enable the same in the NSSCC driver probe.

Or use them through pm_clk. This might be better, as the system
doesn't need these clocks if NSSCC is suspended.

>
> >
> >>> Once you have actual drivers, this should solve itself, the drivers
> >>> will consume the clocks.
> >>
> >>
> >> Given that, NSSCC is being built as module, there is no issue in booting
> >> the kernel. But if you do insmod of the nsscc-ipq5332.ko, system will
> >> reset.
> >>
> >> Without the networking drivers, there is no need to install this module.
> >> And as you stated, once the drivers are available, there will be no issues.
> >>
> >> So can I explain the shortcomings of installing this module without the
> >> networking drivers in cover letter and drop this patch all together?
> >
> > No. Using allyesconfig or allmodconfig and installing the full modules
> > set should work.
> >
>
>
> Okay, Got it. Thanks for the information.
>
> <snip>



-- 
With best wishes
Dmitry


From florian.fainelli at broadcom.com  Sat Feb 17 09:27:20 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Sat, 17 Feb 2024 09:27:20 -0800
Subject: [PATCH] PCI: brcmstb: fix broken brcm_pcie_mdio_write() polling
In-Reply-To: <20240217133722.14391-1-wahrenst@gmx.net>
References: <20240217133722.14391-1-wahrenst@gmx.net>
Message-ID: <ba9fa05c-0a3d-4d68-bdb1-d9e6e2c59c78@broadcom.com>



On 2/17/2024 5:37 AM, Stefan Wahren wrote:
> From: Jonathan Bell <jonathan at raspberrypi.com>
> 
> MDIO_WR_DONE() tests bit 31, which is always 0 (==done) as
> readw_poll_timeout_atomic does a 16-bit read. Replace with the readl
> variant.
> 
> Fixes: ca5dcc76314d ("PCI: brcmstb: Replace status loops with read_poll_timeout_atomic()")
> Signed-off-by: Jonathan Bell <jonathan at raspberrypi.com>
> Signed-off-by: Stefan Wahren <wahrenst at gmx.net>

Excellent catch! Not sure what the real world impact was.

Acked-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240217/9690f1ee/attachment.p7s>

From aweber.kernel at gmail.com  Sat Feb 17 10:22:40 2024
From: aweber.kernel at gmail.com (Artur Weber)
Date: Sat, 17 Feb 2024 19:22:40 +0100
Subject: [PATCH] ARM: dts: exynos4412-*: decrease memory to account for
 unusable region
Message-ID: <20240217-exynos4-memsize-fix-v1-1-7858e9c5f844@gmail.com>

The last 4 MiB of RAM on those devices is likely used by trustzone
firmware, and is unusable under Linux. Change the device tree memory
node accordingly.

The proprietary bootloader (S-BOOT) passes these memory ranges through
ATAG_MEM; this change allows us to have the correct memory ranges
without relying on ATAG_MEM.

Tested-by: Henrik Grimler <henrik at grimler.se> # i9300, i9305
Signed-off-by: Artur Weber <aweber.kernel at gmail.com>
---

This follows a similar fix implemented for the exynos5420-based
Galaxy Tab boards:
https://lore.kernel.org/all/20240130-galaxy-tab-s-cleanup-v1-3-d4e17857241d at grimler.se/
...which in turn is inspired by another fix applied to exynos5422
Odroid devices, 6591a02e17e6 ("ARM: dts: reduce total RAM by 22 MiB
for exynos5422-odroidxu3"):
https://lore.kernel.org/all/1421842972-25807-1-git-send-email-m.szyprowski at samsung.com/
---
 arch/arm/boot/dts/samsung/exynos4412-i9300.dts   | 2 +-
 arch/arm/boot/dts/samsung/exynos4412-i9305.dts   | 2 +-
 arch/arm/boot/dts/samsung/exynos4412-n710x.dts   | 2 +-
 arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/samsung/exynos4412-i9300.dts b/arch/arm/boot/dts/samsung/exynos4412-i9300.dts
index 61aca5798f38..b79d456e976d 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-i9300.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-i9300.dts
@@ -18,7 +18,7 @@ / {
 
 	memory at 40000000 {
 		device_type = "memory";
-		reg = <0x40000000 0x40000000>;
+		reg = <0x40000000 0x3fc00000>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/samsung/exynos4412-i9305.dts b/arch/arm/boot/dts/samsung/exynos4412-i9305.dts
index 77083f1a8273..1048ef5d9bc3 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-i9305.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-i9305.dts
@@ -11,7 +11,7 @@ / {
 
 	memory at 40000000 {
 		device_type = "memory";
-		reg = <0x40000000 0x80000000>;
+		reg = <0x40000000 0x7fc00000>;
 	};
 };
 
diff --git a/arch/arm/boot/dts/samsung/exynos4412-n710x.dts b/arch/arm/boot/dts/samsung/exynos4412-n710x.dts
index 0a151437fc73..eee1000dea92 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-n710x.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-n710x.dts
@@ -9,7 +9,7 @@ / {
 
 	memory at 40000000 {
 		device_type = "memory";
-		reg = <0x40000000 0x80000000>;
+		reg = <0x40000000 0x7fc00000>;
 	};
 
 	/* bootargs are passed in by bootloader */
diff --git a/arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi b/arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi
index 0b89d5682f85..95fc63295860 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi
@@ -23,7 +23,7 @@ / {
 
 	memory at 40000000 {
 		device_type = "memory";
-		reg = <0x40000000 0x80000000>;
+		reg = <0x40000000 0x7fc00000>;
 	};
 
 	aliases {

---
base-commit: 0f1dd5e91e2ba3990143645faff2bcce2d99778e
change-id: 20240217-exynos4-memsize-fix-dccdb9eb75d6

Best regards,
-- 
Artur Weber <aweber.kernel at gmail.com>



From brgl at bgdev.pl  Sat Feb 17 10:30:44 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Sat, 17 Feb 2024 19:30:44 +0100
Subject: [PATCH v5 06/18] dt-bindings: new: wireless: describe the ath12k
 PCI module
In-Reply-To: <87cysvd2er.fsf@kernel.org>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-7-brgl@bgdev.pl>
 <87cysvd2er.fsf@kernel.org>
Message-ID: <CAMRc=Md10bNPswsLqdCmqzEmD+QmyZ+Eb4SUWknH-j5kK-speQ@mail.gmail.com>

On Sat, Feb 17, 2024 at 7:35?AM Kalle Valo <kvalo at kernel.org> wrote:
>
> Bartosz Golaszewski <brgl at bgdev.pl> writes:
>
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > Add device-tree bindings for the ATH12K module found in the WCN7850
> > package.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > ---
> >  .../net/wireless/qcom,ath12k-pci.yaml         | 103 ++++++++++++++++++
> >  1 file changed, 103 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
> > new file mode 100644
> > index 000000000000..063c576b99a0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
> > @@ -0,0 +1,103 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +# Copyright (c) 2024 Linaro Limited
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/wireless/qcom,ath12k-pci.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Qualcomm Technologies ath12k wireless devices (PCIe)
> > +
> > +maintainers:
> > +  - Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>
> Jeff and me are the ath12k driver maintainers so shouldn't we listed
> here as well?
>

Sure will do. I also noticed the subject is wrong, should have been
"net" not "new".

Also, Jeff is not showing up for ath12k bindings in get_maintainer.pl.
You could consider adding an N: ath12k entry to MAINTAINERS.

Bartosz

> Jeff, this reminds me that we should add you to qcom,ath10k.yaml,
> qcom,ath11k-pci.yaml and qcom,ath11k.yaml as maintainer.
>
> --
> https://patchwork.kernel.org/project/linux-wireless/list/
>
> https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


From brgl at bgdev.pl  Sat Feb 17 10:32:16 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Sat, 17 Feb 2024 19:32:16 +0100
Subject: [PATCH v5 03/18] dt-bindings: regulator: describe the PMU module
 of the QCA6390 package
In-Reply-To: <ZdDVNbjv60G9YUNy@finisterre.sirena.org.uk>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-4-brgl@bgdev.pl>
 <ZdDVNbjv60G9YUNy@finisterre.sirena.org.uk>
Message-ID: <CAMRc=Mf9Sro4kM_Jn8_v=cyO5PxCp6AnBdeS9XspqVDGKdA_Dg@mail.gmail.com>

On Sat, Feb 17, 2024 at 4:48?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Fri, Feb 16, 2024 at 09:32:00PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > The QCA6390 package contains discreet modules for WLAN and Bluetooth. They
> > are powered by the Power Management Unit (PMU) that takes inputs from the
> > host and provides LDO outputs. This document describes this module.
>
> 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.

Mark,

This is quite vague, could you elaborate? I have no idea what is wrong
with this patch.

Bartosz


From megi at xff.cz  Sat Feb 17 10:39:40 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 17 Feb 2024 19:39:40 +0100
Subject: [PATCH] drm: rockchip: Don't require MIPI DSI device when it's used for ISP
Message-ID: <20240217183941.1752463-1-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

On RK3399 one MIPI DSI device can be alternatively used with the ISP1,
to provide RX DPHY. When this is the case (ISP1 is enabled in device
tree), probe success of DRM is tied to probe success of ISP1 connected
camera sensor. This can fail if the user is able to killswitch the camera
power, like on Pinephone Pro.

Detect use of MIPI DSI controller by ISP, and don't include it in
component match list in that case.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 47 +++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index ab55d7132550..f47de94ad576 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -354,6 +354,43 @@ static void rockchip_drm_match_remove(struct device *dev)
 		device_link_del(link);
 }
 
+/*
+ * Check if ISP block linked to a mipi-dsi device via phys phandle is
+ * enabled in device tree.
+ */
+static bool rockchip_drm_is_mipi1_and_used_by_isp(struct device *dev)
+{
+	struct device_node *np = NULL, *phy_np;
+
+	if (!of_device_is_compatible(dev->of_node, "rockchip,rk3399-mipi-dsi"))
+		return false;
+
+	while (true) {
+		np = of_find_compatible_node(np, NULL, "rockchip,rk3399-cif-isp");
+		if (!np)
+			break;
+
+		if (!of_device_is_available(np)) {
+			of_node_put(np);
+			continue;
+		}
+
+		phy_np = of_parse_phandle(np, "phys", 0);
+		if (!phy_np) {
+			of_node_put(np);
+			continue;
+		}
+
+		of_node_put(phy_np);
+		of_node_put(np);
+
+		if (phy_np == dev->of_node)
+			return true;
+	}
+
+	return false;
+}
+
 static struct component_match *rockchip_drm_match_add(struct device *dev)
 {
 	struct component_match *match = NULL;
@@ -371,6 +408,16 @@ static struct component_match *rockchip_drm_match_add(struct device *dev)
 			if (!d)
 				break;
 
+			/*
+			 * If mipi1 is connected to ISP, we don't want to wait for mipi1 component,
+			 * because it will not be used by DRM anyway, to not tie success of camera
+			 * driver probe to display pipeline initialization.
+			 */
+			if (rockchip_drm_is_mipi1_and_used_by_isp(d)) {
+				dev_info(d, "used by ISP1, skipping from DRM\n");
+				continue;
+			}
+
 			device_link_add(dev, d, DL_FLAG_STATELESS);
 			component_match_add(dev, &match, component_compare_dev, d);
 		} while (true);
-- 
2.43.0



From megi at xff.cz  Sat Feb 17 10:47:15 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 17 Feb 2024 19:47:15 +0100
Subject: [PATCH] drm: rockchip: dw-mipi-dsi: Fix hsclk calculation for non-burst video modes
Message-ID: <20240217184720.1753730-1-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

For panels that don't use video burst mode, hsclock should match the
pixel clock * bpp / lane exactly. This fixes display image corruption
on Pinephone Pro, which doesn't use video burst mode to drive the panel.

To simplify the addition of exact fout calculation for non-burst modes,
the code is re-organized in order to not redo the same calculation
multiple times, and to use identical algorithm for per-lane bitrate
for internal and external dphy use cases.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 28 ++++++++-----------
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 4cc8ed8f4fbd..7468324872ec 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -548,8 +548,6 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
 {
 	struct dw_mipi_dsi_rockchip *dsi = priv_data;
 	int bpp;
-	unsigned long mpclk, tmp;
-	unsigned int target_mbps = 1000;
 	unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
 	unsigned long best_freq = 0;
 	unsigned long fvco_min, fvco_max, fin, fout;
@@ -567,30 +565,28 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
 		return bpp;
 	}
 
-	mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
-	if (mpclk) {
-		/* take 1 / 0.8, since mbps must big than bandwidth of RGB */
-		tmp = mpclk * (bpp / lanes) * 10 / 8;
-		if (tmp < max_mbps)
-			target_mbps = tmp;
-		else
-			DRM_DEV_ERROR(dsi->dev,
-				      "DPHY clock frequency is out of range\n");
+	fout = mode->clock * bpp / lanes;
+	if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+		fout = fout * 10 / 8;
+	fout *= MSEC_PER_SEC;
+
+	if (fout > max_mbps * USEC_PER_SEC) {
+		DRM_DEV_ERROR(dsi->dev,
+			      "DPHY clock frequency is out of range\n");
+		return -EINVAL;
 	}
 
-	/* for external phy only a the mipi_dphy_config is necessary */
+	/* for external phy only the mipi_dphy_config is necessary */
 	if (dsi->phy) {
-		phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 8,
-						 bpp, lanes,
+		phy_mipi_dphy_get_default_config_for_hsclk(fout, lanes,
 						 &dsi->phy_opts.mipi_dphy);
-		dsi->lane_mbps = target_mbps;
+		dsi->lane_mbps = DIV_ROUND_UP(fout, USEC_PER_SEC);
 		*lane_mbps = dsi->lane_mbps;
 
 		return 0;
 	}
 
 	fin = clk_get_rate(dsi->pllref_clk);
-	fout = target_mbps * USEC_PER_SEC;
 
 	/* constraint: 5Mhz <= Fref / N <= 40MHz */
 	min_prediv = DIV_ROUND_UP(fin, 40 * USEC_PER_SEC);
-- 
2.43.0



From patchwork-bot+netdevbpf at kernel.org  Sat Feb 17 10:50:25 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Sat, 17 Feb 2024 18:50:25 +0000
Subject: [PATCH net v2] net: stmmac: Fix incorrect dereference in interrupt
 handlers
In-Reply-To: <20240214092718.331891-1-p.sakharov@ispras.ru>
References: <20240214092718.331891-1-p.sakharov@ispras.ru>
Message-ID: <170819582570.11703.17257609518253001084.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (main)
by David S. Miller <davem at davemloft.net>:

On Wed, 14 Feb 2024 12:27:17 +0300 you wrote:
> If 'dev' or 'data' is NULL, the 'priv' variable has an incorrect address
> when dereferencing calling netdev_err().
> 
> Since we get as 'dev_id' or 'data' what was passed as the 'dev' argument
> to request_irq() during interrupt initialization (that is, the net_device
> and rx/tx queue pointers initialized at the time of the call) and since
> there are usually no checks for the 'dev_id' argument in such handlers
> in other drivers, remove these checks from the handlers in stmmac driver.
> 
> [...]

Here is the summary with links:
  - [net,v2] net: stmmac: Fix incorrect dereference in interrupt handlers
    https://git.kernel.org/netdev/net/c/97dde8402633

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From megi at xff.cz  Sat Feb 17 10:51:58 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 17 Feb 2024 19:51:58 +0100
Subject: [PATCH] media: rkisp1: Allow higher input resolution
Message-ID: <20240217185202.1754750-1-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

In BSP driver, it is allowed, and it works in practice. Tested on
Pinephone Pro/RK3399 with IMX258 at full res.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 drivers/media/platform/rockchip/rkisp1/rkisp1-common.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index 4b6b28c05b89..74098ddbeeb3 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -33,8 +33,8 @@ struct dentry;
 #define RKISP1_ISP_SD_SINK			BIT(1)
 
 /* min and max values for the widths and heights of the entities */
-#define RKISP1_ISP_MAX_WIDTH			4032
-#define RKISP1_ISP_MAX_HEIGHT			3024
+#define RKISP1_ISP_MAX_WIDTH			4416
+#define RKISP1_ISP_MAX_HEIGHT			3312
 #define RKISP1_ISP_MIN_WIDTH			32
 #define RKISP1_ISP_MIN_HEIGHT			32
 
-- 
2.43.0



From brgl at bgdev.pl  Sat Feb 17 10:53:44 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Sat, 17 Feb 2024 19:53:44 +0100
Subject: [PATCH v5 08/18] arm64: dts: qcom: sm8650-qrd: add the Wifi node
In-Reply-To: <CAA8EJpry2yiGXrtPqZ6RXnoTqQZr_hxA_gCPsUbmyFtEBuD4VA@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-9-brgl@bgdev.pl>
 <CAA8EJpry2yiGXrtPqZ6RXnoTqQZr_hxA_gCPsUbmyFtEBuD4VA@mail.gmail.com>
Message-ID: <CAMRc=MeEWvhHjKJsNgigF=Oja+b1=ejvtAjkK=ptKWK0Ojjo_Q@mail.gmail.com>

On Sat, Feb 17, 2024 at 12:10?AM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Fri, 16 Feb 2024 at 22:33, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> >
> > From: Neil Armstrong <neil.armstrong at linaro.org>
> >
> > Describe the ath12k WLAN on-board the WCN7850 module present on the
> > board.
>
> WCN7850 is the same combo WiFi + BT chip. Is there any reason for
> describing its parts separately rather than using the same PMU
> approach?
>

Yes, I explained the rationale in the cover letter in detail in the
section describing the DTS changes for the series.

Bart

[snip]


From aweber.kernel at gmail.com  Sat Feb 17 11:02:47 2024
From: aweber.kernel at gmail.com (Artur Weber)
Date: Sat, 17 Feb 2024 20:02:47 +0100
Subject: [PATCH] ARM: dts: exynos4212-tab3: limit usable memory range
Message-ID: <20240217-tab3-limit-usable-memory-range-v1-1-49cc9c86a5cc@gmail.com>

The stock bootloader on the Samsung Galaxy Tab 3 8.0 provides an
incorrect available memory range over ATAG_MEM. Limit the usable
memory in the DTS to prevent it from doing so, without having to
disable ATAG support.

Signed-off-by: Artur Weber <aweber.kernel at gmail.com>
---
 arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
index e5254e32aa8f..9bc05961577d 100644
--- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
@@ -45,6 +45,12 @@ chosen {
 		/* Default S-BOOT bootloader loads initramfs here */
 		linux,initrd-start = <0x42000000>;
 		linux,initrd-end = <0x42800000>;
+
+		/*
+		 * Stock bootloader provides incorrect memory size in ATAG_MEM;
+		 * override it here
+		 */
+		linux,usable-memory-range = <0x40000000 0x3fc00000>;
 	};
 
 	firmware at 204f000 {

---
base-commit: 0f1dd5e91e2ba3990143645faff2bcce2d99778e
change-id: 20240217-tab3-limit-usable-memory-range-1d1ffa8dc44d

Best regards,
-- 
Artur Weber <aweber.kernel at gmail.com>



From brgl at bgdev.pl  Sat Feb 17 11:09:08 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Sat, 17 Feb 2024 20:09:08 +0100
Subject: [PATCH v5 16/18] power: pwrseq: add a driver for the QCA6390 PMU module
In-Reply-To: <CAA8EJpo=LFcw8PbFRvGwd9nS5ECazOHiBMWRsqfEpY-v0iQLLA@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-17-brgl@bgdev.pl>
 <CAA8EJpo=LFcw8PbFRvGwd9nS5ECazOHiBMWRsqfEpY-v0iQLLA@mail.gmail.com>
Message-ID: <CAMRc=Mdsg5gDCKD-=ok=mfYJoFpUVpTGFUE+om+WPYvQOc0rzA@mail.gmail.com>

On Sat, Feb 17, 2024 at 12:17?AM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Fri, 16 Feb 2024 at 22:33, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> >
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > This adds the power sequencing driver for the QCA6390's PMU module. It
> > uses the pwrseq subsystem and knows how to match the sequencer to the
> > consumer device by verifying the relevant properties and DT layout.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > ---

[snip]

> > +
> > +static const struct pwrseq_qca6390_vreg pwrseq_qca6390_vregs_common[] = {
> > +       {
> > +               .name = "vddio",
> > +               .load_uA = 20000,
> > +       },
> > +       {
> > +               .name = "vddaon",
> > +               .load_uA = 100000,
> > +       },
> > +       {
> > +               .name = "vddpmu",
> > +               .load_uA = 1250000,
> > +       },
> > +       {
> > +               .name = "vddrfa0p95",
> > +               .load_uA = 200000,
> > +       },
> > +       {
> > +               .name = "vddrfa1p3",
> > +               .load_uA = 400000,
> > +       },
> > +       {
> > +               .name = "vddrfa1p9",
> > +               .load_uA = 400000,
> > +       },
> > +};
> > +
> > +static const struct pwrseq_qca6390_vreg pwrseq_qca6390_vregs_wlan[] = {
> > +       {
> > +               .name = "vddpcie1p3",
> > +               .load_uA = 35000,
> > +       },
> > +       {
> > +               .name = "vddpcie1p9",
> > +               .load_uA = 15000,
> > +       },
> > +};
>
> I thought that we had discussed this already. According to the docs,
> all PMU supplies should be powered on when the chip is being switched
> on, no matter whether it is for the WiFi or for the BT.
>

I know, I mostly did it to make Bjorn happy because he was adamant we
don't need the PCIe regulators for BT and when I checked, it does work
in practice so I thought: whatever. But indeed, the docs say
otherwise. Noted for v6.

[snip]

> > +
> > +static const struct pwrseq_unit_data pwrseq_qca6390_bt_unit_data = {
> > +       .name = "bluetooth-enable",
> > +       .deps = pwrseq_qca6390_unit_deps,
>
> Can we call corresponding regulator_bulk functions from bt and wlan
> enable/disable? This will save us from building the tree-like
> structures (and possible loops inside that tree).
>

Can we? Sure, but the dependency graph (yeah, we should enforce it to
be acyclic) is what makes this code future-proof and allows it to
avoid repeating calls in different targets.

[snip]

Bart


From megi at xff.cz  Sat Feb 17 11:34:38 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 17 Feb 2024 20:34:38 +0100
Subject: [PATCH] clk: rk3399: Allow to set rate of clk_i2s0_frac's parent
Message-ID: <20240217193439.1762213-1-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

Otherwise when when clk_i2s0 muxes to clk_i2s0_div which requires
setting high divider value on clk_i2s0_div, and then muxes back to
clk_i2s0_frac, clk_i2s0_frac would have no way to change the
clk_i2s0_div's divider ratio back to 1 so that it can satisfy the
condition for m/n > 20 for fractional division to work correctly.

Bug is reproducible by playing 44.1k audio, then 48k audio, and then
44.1k audio again. This results in clk_i2s0_div being set to 49 and
clk_i2s0_frac not being able to cope with such a low input clock rate
and audio playing extremely slowly.

The identical issue is on i2s1 and i2s2 clocks, too.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 drivers/clk/rockchip/clk-rk3399.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
index 5efac2ca3048..a17996acd065 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -597,7 +597,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
 	COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0,
 			RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS,
 			RK3399_CLKGATE_CON(8), 3, GFLAGS),
-	COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", 0,
+	COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT,
 			RK3399_CLKSEL_CON(96), 0,
 			RK3399_CLKGATE_CON(8), 4, GFLAGS,
 			&rk3399_i2s0_fracmux),
@@ -607,7 +607,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
 	COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0,
 			RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS,
 			RK3399_CLKGATE_CON(8), 6, GFLAGS),
-	COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", 0,
+	COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT,
 			RK3399_CLKSEL_CON(97), 0,
 			RK3399_CLKGATE_CON(8), 7, GFLAGS,
 			&rk3399_i2s1_fracmux),
@@ -617,7 +617,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
 	COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0,
 			RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS,
 			RK3399_CLKGATE_CON(8), 9, GFLAGS),
-	COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", 0,
+	COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT,
 			RK3399_CLKSEL_CON(98), 0,
 			RK3399_CLKGATE_CON(8), 10, GFLAGS,
 			&rk3399_i2s2_fracmux),
-- 
2.43.0



From joe at perches.com  Sat Feb 17 11:44:56 2024
From: joe at perches.com (Joe Perches)
Date: Sat, 17 Feb 2024 11:44:56 -0800
Subject: mediatek: media: Missing alloc null test
Message-ID: <102e5c65e07ebdade5400ca711fba131a37027a8.camel@perches.com>

There's a missing NULL alloc test here:

It doesn't appear obvious what a proper fix is.

diff -u -p ./drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c /tmp/nothing/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c
--- ./drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c
+++ /tmp/nothing/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c
@@ -79,7 +79,6 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_scp_
 	}
 
 	fw = devm_kzalloc(&plat_dev->dev, sizeof(*fw), GFP_KERNEL);
-	fw->type = SCP;
 	fw->ops = &mtk_vcodec_rproc_msg;
 	fw->scp = scp;



From andersson at kernel.org  Sat Feb 17 11:58:41 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 17 Feb 2024 13:58:41 -0600
Subject: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
In-Reply-To: <20240205182810.58382-1-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
Message-ID: <htsty5siakcu2nxxapiuq7pgs27tjwkb3yxgmfs3bonsl6kylw@joa2viypstoa>

On Mon, Feb 05, 2024 at 07:27:58PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> We've established the need for using separate secured memory pools for
> SCM and QSEECOM

Where has this need been established, what is the actual problem you're
solving with this series?

Does SCM and QSEECOM, as it's implemented in the kernel today, not work
satisfactory?

> as well as the upcoming scminvoke driver.
> 

Is smcinvoke driver upstreaming blocked by not transitioning the scm
driver to a "secure memory pool"?

Is this happening now, or do we need to merge this series when that day
comes?

> It's also become clear that in order to be future-proof, the new
> allocator must be an abstraction layer of a higher level as the SHM
> Bridge will not be the only memory protection mechanism that we'll see
> upstream. Hence the rename to TrustZone Memory rather than SCM Memory
> allocator.
> 
> Also to that end: the new allocator is its own module now and provides a
> Kconfig choice menu for selecting the mode of operation (currently
> default and SHM Bridge).
> 
> Tested on sm8550 and sa8775p with the Inline Crypto Engine and
> remoteproc.
> 

It's reasonable to assume from mentioning of this (and Andrew's t-b),
that the patchset has only been tested on recent platforms that indeed
does implement shmbridge. Can you please share the list of other
platforms that you've tested this on, and can you please get someone
from IPQ to also give their r-b or t-b?

Regards,
Bjorn

> v6 -> v7:
> - fix a Kconfig issue: TZMEM must select GENERIC_ALLOCATOR
> 
> v5 -> v6:
> Fixed two issues reported by autobuilders:
> - add a fix for memory leaks in the qseecom driver as the first patch for
>   easier backporting to the v6.6.y branch
> - explicitly cast the bus address stored in a variable of type dma_addr_t
>   to phys_addr_t expected by the genpool API
> 
> v4 -> v5:
> - fix the return value from qcom_tzmem_init() if SHM Bridge is not supported
> - remove a comment that's no longer useful
> - collect tags
> 
> v3 -> v4:
> - include linux/sizes.h for SZ_X macros
> - use dedicated RCU APIs to dereference radix tree slots
> - fix kerneldocs
> - fix the comment in patch 14/15: it's the hypervisor, not the TrustZone
>   that creates the SHM bridge
> 
> v2 -> v3:
> - restore pool management and use separate pools for different users
> - don't use the new allocator in qcom_scm_pas_init_image() as the
>   TrustZone will create an SHM bridge for us here
> - rewrite the entire series again for most part
> 
> v1 -> v2:
> - too many changes to list, it's a complete rewrite as explained above
> 
> Bartosz Golaszewski (12):
>   firmware: qcom: add a dedicated TrustZone buffer allocator
>   firmware: qcom: scm: enable the TZ mem allocator
>   firmware: qcom: scm: smc: switch to using the SCM allocator
>   firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ
>     allocator
>   firmware: qcom: qseecom: convert to using the TZ allocator
>   firmware: qcom: scm: add support for SHM bridge operations
>   firmware: qcom: tzmem: enable SHM Bridge support
>   firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
>   arm64: defconfig: enable SHM Bridge support for the TZ memory
>     allocator
> 
>  MAINTAINERS                                   |   8 +
>  arch/arm64/configs/defconfig                  |   1 +
>  drivers/firmware/qcom/Kconfig                 |  31 ++
>  drivers/firmware/qcom/Makefile                |   1 +
>  .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++---------
>  drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
>  drivers/firmware/qcom/qcom_scm.c              | 179 +++++----
>  drivers/firmware/qcom/qcom_scm.h              |   6 +
>  drivers/firmware/qcom/qcom_tzmem.c            | 365 ++++++++++++++++++
>  drivers/firmware/qcom/qcom_tzmem.h            |  13 +
>  include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
>  include/linux/firmware/qcom/qcom_scm.h        |   6 +
>  include/linux/firmware/qcom/qcom_tzmem.h      |  28 ++
>  13 files changed, 685 insertions(+), 268 deletions(-)
>  create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
>  create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
>  create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h
> 
> -- 
> 2.40.1
> 


From quic_jjohnson at quicinc.com  Sat Feb 17 12:02:35 2024
From: quic_jjohnson at quicinc.com (Jeff Johnson)
Date: Sat, 17 Feb 2024 12:02:35 -0800
Subject: [PATCH v5 06/18] dt-bindings: new: wireless: describe the ath12k
 PCI module
In-Reply-To: <CAMRc=Md10bNPswsLqdCmqzEmD+QmyZ+Eb4SUWknH-j5kK-speQ@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-7-brgl@bgdev.pl> <87cysvd2er.fsf@kernel.org>
 <CAMRc=Md10bNPswsLqdCmqzEmD+QmyZ+Eb4SUWknH-j5kK-speQ@mail.gmail.com>
Message-ID: <c084edd6-22cf-49a4-9dac-75163a1f4088@quicinc.com>

On 2/17/2024 10:30 AM, Bartosz Golaszewski wrote:
> On Sat, Feb 17, 2024 at 7:35?AM Kalle Valo <kvalo at kernel.org> wrote:
>>
>> Bartosz Golaszewski <brgl at bgdev.pl> writes:
>>
>>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>>
>>> Add device-tree bindings for the ATH12K module found in the WCN7850
>>> package.
>>>
>>> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>> ---
>>>  .../net/wireless/qcom,ath12k-pci.yaml         | 103 ++++++++++++++++++
>>>  1 file changed, 103 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
>>> new file mode 100644
>>> index 000000000000..063c576b99a0
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
>>> @@ -0,0 +1,103 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +# Copyright (c) 2024 Linaro Limited
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/net/wireless/qcom,ath12k-pci.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Qualcomm Technologies ath12k wireless devices (PCIe)
>>> +
>>> +maintainers:
>>> +  - Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>
>> Jeff and me are the ath12k driver maintainers so shouldn't we listed
>> here as well?
>>
> 
> Sure will do. I also noticed the subject is wrong, should have been
> "net" not "new".
> 
> Also, Jeff is not showing up for ath12k bindings in get_maintainer.pl.
> You could consider adding an N: ath12k entry to MAINTAINERS.
> 
> Bartosz
> 
>> Jeff, this reminds me that we should add you to qcom,ath10k.yaml,
>> qcom,ath11k-pci.yaml and qcom,ath11k.yaml as maintainer.

OK, I'll update those files.

And looking at MAINTAINERS, in ath10 we have an explicit path:
F:	Documentation/devicetree/bindings/net/wireless/qcom,ath10k.yaml

And in ath11k we have an explicit path:
F:	Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml

However the ath11k entry is missing:
Documentation/devicetree/bindings/net/wireless/qcom,ath11k-pci.yaml

So it looks like I have a few patches:
- update my entries in MAINTAINERS to use my @kernel.org e-mail
- add myself to the existing *ath1*k*.yaml files as a maintainer
- update MAINTAINERS to replace F: *.yaml with N: ath1*k to match any
related files, including the YAML files

/jeff


From conor at kernel.org  Sat Feb 17 12:35:06 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 17 Feb 2024 20:35:06 +0000
Subject: [PATCH] dt-bindings: watchdog: drop obsolete brcm,bcm2835-pm-wdt
 bindings
In-Reply-To: <ZdC/624d1c8O3NRG@standask-GA-A55M-S2HP>
References: <ZdC/624d1c8O3NRG@standask-GA-A55M-S2HP>
Message-ID: <20240217-unbroken-scanner-ae1e97b02d5a@spud>

On Sat, Feb 17, 2024 at 03:17:15PM +0100, Stanislav Jakubek wrote:
> These bindings are already (better) described in soc/bcm/brcm,bcm2835-pm.
> Drop these obsolete bindings.
> 
> Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
>  .../bindings/watchdog/brcm,bcm2835-pm-wdog.txt | 18 ------------------
>  1 file changed, 18 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt b/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt
> deleted file mode 100644
> index f801d71de1cd..000000000000
> --- a/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt
> +++ /dev/null
> @@ -1,18 +0,0 @@
> -BCM2835 Watchdog timer
> -
> -Required properties:
> -
> -- compatible : should be "brcm,bcm2835-pm-wdt"
> -- reg : Specifies base physical address and size of the registers.
> -
> -Optional properties:
> -
> -- timeout-sec   : Contains the watchdog timeout in seconds
> -
> -Example:
> -
> -watchdog {
> -	compatible = "brcm,bcm2835-pm-wdt";
> -	reg = <0x7e100000 0x28>;
> -	timeout-sec = <10>;
> -};
> -- 
> 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/20240217/535fda90/attachment.sig>

From broonie at kernel.org  Sat Feb 17 12:43:31 2024
From: broonie at kernel.org (Mark Brown)
Date: Sat, 17 Feb 2024 20:43:31 +0000
Subject: [PATCH v5 03/18] dt-bindings: regulator: describe the PMU module
 of the QCA6390 package
In-Reply-To: <CAMRc=Mf9Sro4kM_Jn8_v=cyO5PxCp6AnBdeS9XspqVDGKdA_Dg@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-4-brgl@bgdev.pl>
 <ZdDVNbjv60G9YUNy@finisterre.sirena.org.uk>
 <CAMRc=Mf9Sro4kM_Jn8_v=cyO5PxCp6AnBdeS9XspqVDGKdA_Dg@mail.gmail.com>
Message-ID: <ZdEac8I5aI9YLq6A@finisterre.sirena.org.uk>

On Sat, Feb 17, 2024 at 07:32:16PM +0100, Bartosz Golaszewski wrote:
> On Sat, Feb 17, 2024 at 4:48?PM Mark Brown <broonie at kernel.org> wrote:

> > 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.

> This is quite vague, could you elaborate? I have no idea what is wrong
> with this patch.

The subject line does not look like the subject line for a regulator
patch rendering it almost invisible in my inbox.  As you will see if you
follow the above suggestion and look at other commits to the same area
you should see that subject lines should start regulator:.
-------------- 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/20240217/63eef533/attachment.sig>

From mo.c.weber at gmail.com  Sat Feb 17 13:12:38 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Sat, 17 Feb 2024 22:12:38 +0100
Subject: [PATCH v2 0/8] Staging: vc04_services: bcm2835-camera: Fix code style checks
Message-ID: <20240217211246.28882-1-mo.c.weber@gmail.com>

Resubmit these patches to fix multiple code style checks for better readability, consistency, and to address errors indicated by Gregs patch bot

Moritz C. Weber (8):
  Staging: vc04_services: bcm2835-camera: fix brace code style check
  Staging: vc04_services: bcm2835-camera: fix brace code style check
  Staging: vc04_services: bcm2835-camera: fix brace code style check
  Staging: vc04_services: bcm2835-camera: fix brace code style check
  Staging: vc04_services: bcm2835-camera: fix brace code style check
  Staging: vc04_services: bcm2835-camera: fix blank line style check
  Staging: vc04_services: bcm2835-camera: fix brace code style check
  Staging: vc04_services: bcm2835-camera: fix brace code style check

 .../bcm2835-camera/bcm2835-camera.c           | 61 +++++++++----------
 1 file changed, 28 insertions(+), 33 deletions(-)

-- 
2.30.2



From mo.c.weber at gmail.com  Sat Feb 17 13:12:41 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Sat, 17 Feb 2024 22:12:41 +0100
Subject: [PATCH v2 3/8] Staging: vc04_services: bcm2835-camera: fix brace code style check
In-Reply-To: <20240217211246.28882-1-mo.c.weber@gmail.com>
References: <20240217211246.28882-1-mo.c.weber@gmail.com>
Message-ID: <20240217211246.28882-4-mo.c.weber@gmail.com>

Reformat function parameters to fix checkpatch check:
Increase readability and consistency

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 .../vc04_services/bcm2835-camera/bcm2835-camera.c        | 9 ++++-----
 1 file changed, 4 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 1fa868163..dfa9e7670 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -418,11 +418,10 @@ static int enable_camera(struct bcm2835_mmal_dev *dev)
 	int ret;
 
 	if (!dev->camera_use_count) {
-		ret = vchiq_mmal_port_parameter_set(
-			dev->instance,
-			&dev->component[COMP_CAMERA]->control,
-			MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num,
-			sizeof(dev->camera_num));
+		ret = vchiq_mmal_port_parameter_set(dev->instance,
+						    &dev->component[COMP_CAMERA]->control,
+						    MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num,
+						    sizeof(dev->camera_num));
 		if (ret < 0) {
 			v4l2_err(&dev->v4l2_dev,
 				 "Failed setting camera num, ret %d\n", ret);
-- 
2.30.2



From mo.c.weber at gmail.com  Sat Feb 17 13:12:42 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Sat, 17 Feb 2024 22:12:42 +0100
Subject: [PATCH v2 4/8] Staging: vc04_services: bcm2835-camera: fix brace code style check
In-Reply-To: <20240217211246.28882-1-mo.c.weber@gmail.com>
References: <20240217211246.28882-1-mo.c.weber@gmail.com>
Message-ID: <20240217211246.28882-5-mo.c.weber@gmail.com>

Reformat function parameters to fix checkpatch check:
Increase readability and consistency

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 .../vc04_services/bcm2835-camera/bcm2835-camera.c      | 10 +++++-----
 1 file changed, 5 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 dfa9e7670..e2d058732 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -465,11 +465,11 @@ static int disable_camera(struct bcm2835_mmal_dev *dev)
 				 "Failed disabling camera, ret %d\n", ret);
 			return -EINVAL;
 		}
-		vchiq_mmal_port_parameter_set(
-			dev->instance,
-			&dev->component[COMP_CAMERA]->control,
-			MMAL_PARAMETER_CAMERA_NUM, &i,
-			sizeof(i));
+		vchiq_mmal_port_parameter_set(dev->instance,
+					      &dev->component[COMP_CAMERA]->control,
+					      MMAL_PARAMETER_CAMERA_NUM,
+					      &i,
+					      sizeof(i));
 	}
 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 		 "Camera refcount now %d\n", dev->camera_use_count);
-- 
2.30.2



From mo.c.weber at gmail.com  Sat Feb 17 13:12:43 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Sat, 17 Feb 2024 22:12:43 +0100
Subject: [PATCH v2 5/8] Staging: vc04_services: bcm2835-camera: fix brace code style check
In-Reply-To: <20240217211246.28882-1-mo.c.weber@gmail.com>
References: <20240217211246.28882-1-mo.c.weber@gmail.com>
Message-ID: <20240217211246.28882-6-mo.c.weber@gmail.com>

Reformat function parameters to fix checkpatch check:
Increase readability and consistency

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 .../staging/vc04_services/bcm2835-camera/bcm2835-camera.c    | 5 ++---
 1 file changed, 2 insertions(+), 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 e2d058732..b9745bb80 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -783,9 +783,8 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on)
 			ret = vchiq_mmal_port_connect_tunnel(dev->instance, src,
 							     NULL);
 		if (ret >= 0)
-			ret = vchiq_mmal_component_disable(
-					dev->instance,
-					dev->component[COMP_PREVIEW]);
+			ret = vchiq_mmal_component_disable(dev->instance,
+							   dev->component[COMP_PREVIEW]);
 
 		disable_camera(dev);
 		return ret;
-- 
2.30.2



From mo.c.weber at gmail.com  Sat Feb 17 13:12:44 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Sat, 17 Feb 2024 22:12:44 +0100
Subject: [PATCH v2 6/8] Staging: vc04_services: bcm2835-camera: fix blank line style check
In-Reply-To: <20240217211246.28882-1-mo.c.weber@gmail.com>
References: <20240217211246.28882-1-mo.c.weber@gmail.com>
Message-ID: <20240217211246.28882-7-mo.c.weber@gmail.com>

Remove blank line to fix checkpatch check:
Increase readability and consistency

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index b9745bb80..a25a361c8 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -1002,7 +1002,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	return 0;
 }
 
-
 static int mmal_setup_video_component(struct bcm2835_mmal_dev *dev,
 				      struct v4l2_format *f)
 {
-- 
2.30.2



From mo.c.weber at gmail.com  Sat Feb 17 13:12:45 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Sat, 17 Feb 2024 22:12:45 +0100
Subject: [PATCH v2 7/8] Staging: vc04_services: bcm2835-camera: fix brace code style check
In-Reply-To: <20240217211246.28882-1-mo.c.weber@gmail.com>
References: <20240217211246.28882-1-mo.c.weber@gmail.com>
Message-ID: <20240217211246.28882-8-mo.c.weber@gmail.com>

Reformat function parameters to fix checkpatch check:
Increase readability and consistency

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index a25a361c8..9cd79850b 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -1037,8 +1037,8 @@ static int mmal_setup_video_component(struct bcm2835_mmal_dev *dev,
 
 	if (overlay_enabled) {
 		ret = vchiq_mmal_port_connect_tunnel(dev->instance,
-				preview_port,
-				&dev->component[COMP_PREVIEW]->input[0]);
+						     preview_port,
+						     &dev->component[COMP_PREVIEW]->input[0]);
 		if (ret)
 			return ret;
 
-- 
2.30.2



From mo.c.weber at gmail.com  Sat Feb 17 13:12:46 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Sat, 17 Feb 2024 22:12:46 +0100
Subject: [PATCH v2 8/8] Staging: vc04_services: bcm2835-camera: fix brace code style check
In-Reply-To: <20240217211246.28882-1-mo.c.weber@gmail.com>
References: <20240217211246.28882-1-mo.c.weber@gmail.com>
Message-ID: <20240217211246.28882-9-mo.c.weber@gmail.com>

Reformat function parameters to fix checkpatch check:
Increase readability and consistency

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 .../vc04_services/bcm2835-camera/bcm2835-camera.c      | 10 +++++-----
 1 file changed, 5 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 9cd79850b..c3ba490e5 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -1715,11 +1715,11 @@ static int mmal_init(struct bcm2835_mmal_dev *dev)
 	{
 		unsigned int enable = 1;
 
-		vchiq_mmal_port_parameter_set(
-			dev->instance,
-			&dev->component[COMP_VIDEO_ENCODE]->control,
-			MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
-			&enable, sizeof(enable));
+		vchiq_mmal_port_parameter_set(dev->instance,
+					      &dev->component[COMP_VIDEO_ENCODE]->control,
+					      MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
+					      &enable,
+					      sizeof(enable));
 
 		vchiq_mmal_port_parameter_set(dev->instance,
 					      &dev->component[COMP_VIDEO_ENCODE]->control,
-- 
2.30.2



From mo.c.weber at gmail.com  Sat Feb 17 13:12:40 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Sat, 17 Feb 2024 22:12:40 +0100
Subject: [PATCH v2 2/8] Staging: vc04_services: bcm2835-camera: fix brace code style check
In-Reply-To: <20240217211246.28882-1-mo.c.weber@gmail.com>
References: <20240217211246.28882-1-mo.c.weber@gmail.com>
Message-ID: <20240217211246.28882-3-mo.c.weber@gmail.com>

Reformat function parameters to fix checkpatch check:
Increase readability and consistency

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 .../vc04_services/bcm2835-camera/bcm2835-camera.c     | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index 05e5e4ab1..1fa868163 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -405,12 +405,11 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
 	    is_capturing(dev)) {
 		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 			 "Grab another frame as buffer has EOS");
-		vchiq_mmal_port_parameter_set(
-			instance,
-			dev->capture.camera_port,
-			MMAL_PARAMETER_CAPTURE,
-			&dev->capture.frame_count,
-			sizeof(dev->capture.frame_count));
+		vchiq_mmal_port_parameter_set(instance,
+					      dev->capture.camera_port,
+					      MMAL_PARAMETER_CAPTURE,
+					      &dev->capture.frame_count,
+					      sizeof(dev->capture.frame_count));
 	}
 }
 
-- 
2.30.2



From mo.c.weber at gmail.com  Sat Feb 17 13:12:39 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Sat, 17 Feb 2024 22:12:39 +0100
Subject: [PATCH v2 1/8] Staging: vc04_services: bcm2835-camera: fix brace code style check
In-Reply-To: <20240217211246.28882-1-mo.c.weber@gmail.com>
References: <20240217211246.28882-1-mo.c.weber@gmail.com>
Message-ID: <20240217211246.28882-2-mo.c.weber@gmail.com>

Reformat function parameters to fix checkpatch check:
Increase readability and consistency

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 .../vc04_services/bcm2835-camera/bcm2835-camera.c     | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index e6e89784d..05e5e4ab1 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -350,12 +350,11 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
 			if (is_capturing(dev)) {
 				v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 					 "Grab another frame");
-				vchiq_mmal_port_parameter_set(
-					instance,
-					dev->capture.camera_port,
-					MMAL_PARAMETER_CAPTURE,
-					&dev->capture.frame_count,
-					sizeof(dev->capture.frame_count));
+				vchiq_mmal_port_parameter_set(instance,
+							      dev->capture.camera_port,
+							      MMAL_PARAMETER_CAPTURE,
+							      &dev->capture.frame_count,
+							      sizeof(dev->capture.frame_count));
 			}
 			if (vchiq_mmal_submit_buffer(instance, port,
 						     &buf->mmal))
-- 
2.30.2



From marex at denx.de  Sat Feb 17 13:33:30 2024
From: marex at denx.de (Marek Vasut)
Date: Sat, 17 Feb 2024 22:33:30 +0100
Subject: [PATCH] arm64: dts: imx8mp: Set SPI NOR to max 40 MHz on Data Modul i.MX8M Plus eDM SBC
Message-ID: <20240217213358.164323-1-marex@denx.de>

The SPI NOR bus routing on this board cannot go above 50 MHz,
set the clock frequency to maximum of 40 MHz to be within a
safe margin. Remove the comment as well.

Fixes: 562d222f23f0 ("arm64: dts: imx8mp: Add support for Data Modul i.MX8M Plus eDM SBC")
Signed-off-by: Marek Vasut <marex at denx.de>
---
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: Fabio Estevam <festevam at gmail.com>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
Cc: Rob Herring <robh at kernel.org>
Cc: Sascha Hauer <s.hauer at pengutronix.de>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
index 12960226974ca..5c89c601b6817 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
@@ -164,7 +164,7 @@ &ecspi1 {
 	flash at 0 {	/* W25Q128JVEI */
 		compatible = "jedec,spi-nor";
 		reg = <0>;
-		spi-max-frequency = <100000000>;	/* Up to 133 MHz */
+		spi-max-frequency = <40000000>;
 		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <1>;
 	};
-- 
2.43.0



From anshuman.khandual at arm.com  Sat Feb 17 16:34:34 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Sun, 18 Feb 2024 06:04:34 +0530
Subject: [PATCH] arm64/sysreg: Add register fields for ID_AA64DFR1_EL1
In-Reply-To: <d2722ae9-d29c-41f9-9eec-f829589adf6e@sirena.org.uk>
References: <20240215065454.2489075-1-anshuman.khandual@arm.com>
 <d2722ae9-d29c-41f9-9eec-f829589adf6e@sirena.org.uk>
Message-ID: <785e9bd7-f47b-4e8f-9291-0616aa87fa27@arm.com>



On 2/15/24 18:34, Mark Brown wrote:
> On Thu, Feb 15, 2024 at 12:24:54PM +0530, Anshuman Khandual wrote:
> 
>>  Sysreg	ID_AA64DFR1_EL1	3	0	0	5	1
>> -Res0	63:0
>> +Field	63:56	ABL_CMPs
>> +Field	55:52	DPFZS
> 
> This is documented in the architecture as an enumeration, though I'm not
> immediately seeing what values to use.

Just wondering - would something like the following make sense. Because
0b0000 signifies that the cycle counter would just ignore PMCR_EL0.FZS,
where as it gets frozen with 0b0001.

UnsignedEnum   55:52   DPFZS
       0b0000  IGNR
       0b0001  FRZN
EndEnum

> 
> Otherwise this looks good.


From anshuman.khandual at arm.com  Sat Feb 17 16:54:59 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Sun, 18 Feb 2024 06:24:59 +0530
Subject: [PATCH] arm64/sysreg: Update ID_AA64DFR0_EL1 and ID_DFR0_EL1
In-Reply-To: <b103244b-7776-48fb-8055-5c003d773087@sirena.org.uk>
References: <20240215055159.2440898-1-anshuman.khandual@arm.com>
 <b103244b-7776-48fb-8055-5c003d773087@sirena.org.uk>
Message-ID: <05487b0c-207f-48c4-9094-6180c948783e@arm.com>



On 2/15/24 18:30, Mark Brown wrote:
> On Thu, Feb 15, 2024 at 11:21:59AM +0530, Anshuman Khandual wrote:
> 
>> This just updates ID_DFR0_EL1.CopDbg and ID_AA64DFR0_EL1.DebugVer register
>> fields as per the definitions based on DDI0601 2023-12.
> 
> Just as a general note for non-trival registers it's easier to review if
> we change one register per patch, it avoids having to re-review the same
> registers repeatedly and for incremental changes like this it helps with
> the fact that diff does badly at offering context.

Agreed, and noted.

> 
>> --- a/arch/arm64/tools/sysreg
>> +++ b/arch/arm64/tools/sysreg
>> @@ -231,6 +231,7 @@ Enum	3:0	CopDbg
>>  	0b1000	Debugv8p2
>>  	0b1001	Debugv8p4
>>  	0b1010	Debugv8p8
>> +	0b1011	Debugv8p9
>>  EndEnum
>>  EndSysreg
> 
> This is ID_AA64DFR0_EL1 and is missing at least an update to PMSVer.
> 
>>  
>> @@ -1247,6 +1248,7 @@ UnsignedEnum	3:0	DebugVer
>>  	0b1000	V8P2
>>  	0b1001	V8P4
>>  	0b1010	V8P8
>> +	0b1011	V8P9
>>  EndEnum
>>  EndSysreg
> 
> This is ID_DFR0_EL1 and is missing an update to at least PerfMon.

Will fold in the following changes i.e for ID_DFR0_EL1 and for
ID_AA64DFR0_EL1 respectively and then split the patch into two
- one for each register.

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index cc2914d6ebdc..508224a0e078 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -200,6 +200,7 @@ UnsignedEnum        27:24   PerfMon
        0b0110  PMUv3p5
        0b0111  PMUv3p7
        0b1000  PMUv3p8
+       0b1001  PMUv3p9
        0b1111  IMPDEF
 EndEnum
 Enum   23:20   MProfDbg
@@ -1222,6 +1223,7 @@ UnsignedEnum      35:32   PMSVer
        0b0010  V1P1
        0b0011  V1P2
        0b0100  V1P3
+       0b0101  V1P4
 EndEnum
 Field  31:28   CTX_CMPs
 Res0   27:24


From peng.fan at nxp.com  Sat Feb 17 17:37:23 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Sun, 18 Feb 2024 01:37:23 +0000
Subject: [PATCH v4 0/3] clocksource: imx-sysctr: support i.MX95
In-Reply-To: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>
References: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>
Message-ID: <PA4PR04MB941660F5ABD35C8715A1656E88522@PA4PR04MB9416.eurprd04.prod.outlook.com>

Hi Daniel,

> Subject: [PATCH v4 0/3] clocksource: imx-sysctr: support i.MX95
> 
> i.MX95 System Counter module control register space is blocked by SCMI
> firmware, so we use Read Register space to get the counter.

Ping..

Thanks,
Peng.
> 
> V2:
>   - imx95 is not compatible with the existing hardware, so add a
>     seperate entry for i.MX95 in dt-binding.
>   - Per Marco's comments, the global variables was removed except
>     to_sysctr. And add a new TIMER_OF_DECLARE entry for i.MX95
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
> Changes in v4:
> - Add A-b in patch 1
> - Include slab.h in patch 2 to fix kernel build failure for i386 compile test.
> - Link to v3: https://lore.kernel.org/r/20240126-imx-sysctr-v3-0-
> 33fe801d5f31 at nxp.com
> 
> Changes in v3:
> - Drop items in patch 1 per Conor's comments
> - Link to v2: https://lore.kernel.org/r/20240125-imx-sysctr-v2-0-
> 7332470cd7ae at nxp.com
> 
> ---
> Peng Fan (3):
>       dt-bindings: timer: nxp,sysctr-timer: support i.MX95
>       clocksource/drivers/imx-sysctr: drop use global variables
>       clocksource/drivers/imx-sysctr: support i.MX95
> 
>  .../bindings/timer/nxp,sysctr-timer.yaml           |   4 +-
>  drivers/clocksource/timer-imx-sysctr.c             | 117 +++++++++++++++------
>  2 files changed, 90 insertions(+), 31 deletions(-)
> ---
> base-commit: 01af33cc9894b4489fb68fa35c40e9fe85df63dc
> change-id: 20240125-imx-sysctr-3a89a0852376
> 
> Best regards,
> --
> Peng Fan <peng.fan at nxp.com>


From peng.fan at nxp.com  Sat Feb 17 17:38:17 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Sun, 18 Feb 2024 01:38:17 +0000
Subject: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
In-Reply-To: <20240201-imx-mailbox-v6-0-76f4f35b403e@nxp.com>
References: <20240201-imx-mailbox-v6-0-76f4f35b403e@nxp.com>
Message-ID: <PA4PR04MB941646795F4E19D1EC35134F88522@PA4PR04MB9416.eurprd04.prod.outlook.com>

Hi Jassi

> Subject: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
> 
> - Add dt-bindings
> - i.MX95 ELE/V2X use same register layout as i.MX8ULP S4 MU, but
>   the TR/RR num is different. To make code reusable and not add too much
>   macros, add runtime detect number of TR and RR by reading PAR_OFF
>   registers.
> - Add i.MX95 ELE/V2X MU entry in driver

Ping..

Thanks,
Peng.

> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
> Changes in v6:
> - Drop node labels and add Conor's R-b
> - Link to v5: https://lore.kernel.org/r/20240126-imx-mailbox-v5-0-
> 7ff3a3d53529 at nxp.com
> 
> Changes in v5:
> - Per Conor, add restriction to sram property.
> - Since i.MX95 MU has SRAM, we may not see it is compatible with i.MX8ULP
> MU, so drop the fallback compatible
> - Add R-b for patch 2&3
> - Link to v4: https://lore.kernel.org/r/20240125-imx-mailbox-v4-0-
> 800be5383c20 at nxp.com
> 
> Changes in v4:
> - Address dt-binding comments in V2 from Krzysztof
> - Link to v3: https://lore.kernel.org/r/20240123-imx-mailbox-v3-0-
> ed932945e0bf at nxp.com
> 
> Changes in v3:
> - Following dts coding style Per Krzysztof
> - Add return type for init function, patch 2 is new
> - Check return value when tr/rr is larger than 4 and return error.
> - Link to v2: https://lore.kernel.org/r/20240122-imx-mailbox-v2-0-
> 7b3c80333b92 at nxp.com
> 
> Changes in v2:
> - Support sram property and add example
> - Populate the sram node in driver
> - Link to v1: https://lore.kernel.org/r/20240122-imx-mailbox-v1-0-
> 81413f655210 at nxp.com
> 
> ---
> Peng Fan (4):
>       dt-bindings: mailbox: fsl,mu: add i.MX95 Generic/ELE/V2X MU compatible
>       mailbox: imx: support return value of init
>       mailbox: imx: get RR/TR registers num from Parameter register
>       mailbox: imx: support i.MX95 ELE/V2X MU
> 
>  .../devicetree/bindings/mailbox/fsl,mu.yaml        | 58 +++++++++++++-
>  drivers/mailbox/imx-mailbox.c                      | 88 ++++++++++++++++------
>  2 files changed, 123 insertions(+), 23 deletions(-)
> ---
> base-commit: ad5c60d66016e544c51ed98635a74073f761f45d
> change-id: 20240122-imx-mailbox-243021d12030
> 
> Best regards,
> --
> Peng Fan <peng.fan at nxp.com>


From lkp at intel.com  Sat Feb 17 17:43:48 2024
From: lkp at intel.com (kernel test robot)
Date: Sun, 18 Feb 2024 09:43:48 +0800
Subject: [PATCH 2/2] media: i2c: Add imx283 camera sensor driver
In-Reply-To: <20240215204436.9194-3-umang.jain@ideasonboard.com>
References: <20240215204436.9194-3-umang.jain@ideasonboard.com>
Message-ID: <202402180911.BqIsQdzm-lkp@intel.com>

Hi Umang,

kernel test robot noticed the following build errors:

[auto build test ERROR on media-tree/master]
[also build test ERROR on linuxtv-media-stage/master next-20240216]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Umang-Jain/media-dt-bindings-media-Add-bindings-for-IMX283/20240216-044628
base:   git://linuxtv.org/media_tree.git master
patch link:    https://lore.kernel.org/r/20240215204436.9194-3-umang.jain%40ideasonboard.com
patch subject: [PATCH 2/2] media: i2c: Add imx283 camera sensor driver
config: arm-allyesconfig (https://download.01.org/0day-ci/archive/20240218/202402180911.BqIsQdzm-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240218/202402180911.BqIsQdzm-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402180911.BqIsQdzm-lkp at intel.com/

All errors (new ones prefixed by >>):

   arm-linux-gnueabi-ld: drivers/media/i2c/imx283.o: in function `imx283_set_framing_limits':
>> imx283.c:(.text+0xfe4): undefined reference to `__aeabi_uldivmod'
   arm-linux-gnueabi-ld: drivers/media/i2c/imx283.o: in function `imx283_init_controls':
   imx283.c:(.text+0x1470): undefined reference to `__aeabi_uldivmod'
   arm-linux-gnueabi-ld: drivers/media/i2c/imx283.o: in function `imx283_set_ctrl':
   imx283.c:(.text+0x2378): undefined reference to `__aeabi_uldivmod'

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From jassisinghbrar at gmail.com  Sat Feb 17 18:07:18 2024
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Sat, 17 Feb 2024 20:07:18 -0600
Subject: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
In-Reply-To: <PA4PR04MB941646795F4E19D1EC35134F88522@PA4PR04MB9416.eurprd04.prod.outlook.com>
References: <20240201-imx-mailbox-v6-0-76f4f35b403e@nxp.com> <PA4PR04MB941646795F4E19D1EC35134F88522@PA4PR04MB9416.eurprd04.prod.outlook.com>
Message-ID: <CABb+yY0aM9Dn3LPBqb11vU3Ln4bCCGOBXX77sF499cyb_sXiUA@mail.gmail.com>

Hi Peng,

On Sat, Feb 17, 2024 at 7:38?PM Peng Fan <peng.fan at nxp.com> wrote:
>
> Hi Jassi
>
> > Subject: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
> >
> > - Add dt-bindings
> > - i.MX95 ELE/V2X use same register layout as i.MX8ULP S4 MU, but
> >   the TR/RR num is different. To make code reusable and not add too much
> >   macros, add runtime detect number of TR and RR by reading PAR_OFF
> >   registers.
> > - Add i.MX95 ELE/V2X MU entry in driver
>
> Ping..
>
dt bindings and compatibles first need to be acked by dt maintainers.

thanks


From peng.fan at nxp.com  Sat Feb 17 18:10:43 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Sun, 18 Feb 2024 02:10:43 +0000
Subject: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
In-Reply-To: <CABb+yY0aM9Dn3LPBqb11vU3Ln4bCCGOBXX77sF499cyb_sXiUA@mail.gmail.com>
References: <20240201-imx-mailbox-v6-0-76f4f35b403e@nxp.com>
 <PA4PR04MB941646795F4E19D1EC35134F88522@PA4PR04MB9416.eurprd04.prod.outlook.com>
 <CABb+yY0aM9Dn3LPBqb11vU3Ln4bCCGOBXX77sF499cyb_sXiUA@mail.gmail.com>
Message-ID: <DU0PR04MB94170454D64EF65E6774BEAB88522@DU0PR04MB9417.eurprd04.prod.outlook.com>

Hi Jassi,

> Subject: Re: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
> 
> Hi Peng,
> 
> On Sat, Feb 17, 2024 at 7:38?PM Peng Fan <peng.fan at nxp.com> wrote:
> >
> > Hi Jassi
> >
> > > Subject: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
> > >
> > > - Add dt-bindings
> > > - i.MX95 ELE/V2X use same register layout as i.MX8ULP S4 MU, but
> > >   the TR/RR num is different. To make code reusable and not add too
> much
> > >   macros, add runtime detect number of TR and RR by reading PAR_OFF
> > >   registers.
> > > - Add i.MX95 ELE/V2X MU entry in driver
> >
> > Ping..
> >
> dt bindings and compatibles first need to be acked by dt maintainers.

The bindings has been reviewed by Conor Dooley who listed as maintainer:
OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS                                                    
M:      Rob Herring <robh+dt at kernel.org>                                                            
M:      Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>                                     
M:      Conor Dooley <conor+dt at kernel.org>

https://lore.kernel.org/all/20240201-imx-mailbox-v6-1-76f4f35b403e at nxp.com/

Thanks,
Peng.

> 
> thanks

From peng.fan at nxp.com  Sat Feb 17 18:19:45 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Sun, 18 Feb 2024 02:19:45 +0000
Subject: [PATCH V4 2/2] clk: scmi: support state_ctrl_forbidden
In-Reply-To: <Za-fTES4owsmmxgO@bogus>
References: <20240121110901.1414856-1-peng.fan@oss.nxp.com>
 <20240121110901.1414856-2-peng.fan@oss.nxp.com> <Za-fTES4owsmmxgO@bogus>
Message-ID: <DU0PR04MB941784A5A667756BD1CC584288522@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH V4 2/2] clk: scmi: support state_ctrl_forbidden
> 
> On Sun, Jan 21, 2024 at 07:09:01PM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > Some clocks may exported to linux, while those clocks are not allowed
> > to configure by Linux. For example:
> >
> > SYS_CLK1-----
> >              \
> > 	     --MUX--->MMC1_CLK
> >              /
> > SYS_CLK2-----
> >
> > MMC1 needs set parent, so SYS_CLK1 and SYS_CLK2 are exported to Linux,
> > then the clk propagation will touch SYS_CLK1 or SYS_CLK2.
> > So we need bypass the failure for SYS_CLK1 or SYS_CLK2 when enable the
> > clock of MMC1, adding scmi_no_state_ctrl_clk_ops to use software
> > enable counter, while not calling scmi api.
> >
> 
> I would rewrite the commit message something like:
> "
>     clk: scmi: Add support for forbidden clock state controls
> 
>     Some clocks may be exported to OS agent, while certain configurations/
>     access to those clocks are restricted to the OS agent by the SCMI platform
>     firmware. For example:
> 
>     SYS_CLK1-----
>                  \
>                  --MUX--->MMC1_CLK
>                  /
>     SYS_CLK2-----
> 
>     MMC1_CLK needs to set parent as part of it initialisation and enabling.
>     SYS_CLK1 and SYS_CLK2 are exported to the OS agent. The clk propagation
>     will access SYS_CLK1 or SYS_CLK2 based on the configuration. However,
>     we need bypass the failure to access SYS_CLK1 or SYS_CLK2 when
> MMC1_CLK
>     is accessed and enabled.
> 
>     Add a separate scmi_no_state_ctrl clk_ops where the calls to the SCMI
>     platform firmware are avoided if the access is not permitted.
> "
> No need to repost.
> 
> I need Stephen's ack to take this together with scmi clk changes.

Stephen, 

would you please ack if you are ok?

Thanks,
Peng.

> 
> --
> Regards,
> Sudeep


From xiangyang3 at huawei.com  Sat Feb 17 18:30:55 2024
From: xiangyang3 at huawei.com (Xiang Yang)
Date: Sun, 18 Feb 2024 10:30:55 +0800
Subject: [PATCH 5.10.y 5/5] arm64: Stash shadow stack pointer in the task struct on interrupt
In-Reply-To: <20240218023055.145519-1-xiangyang3@huawei.com>
References: <20240218023055.145519-1-xiangyang3@huawei.com>
Message-ID: <20240218023055.145519-6-xiangyang3@huawei.com>

From: Ard Biesheuvel <ardb at kernel.org>

commit 59b37fe52f49955791a460752c37145f1afdcad1 upstream.

Instead of reloading the shadow call stack pointer from the ordinary
stack, which may be vulnerable to the kind of gadget based attacks
shadow call stacks were designed to prevent, let's store a task's shadow
call stack pointer in the task struct when switching to the shadow IRQ
stack.

Given that currently, the task_struct::scs_sp field is only used to
preserve the shadow call stack pointer while a task is scheduled out or
running in user space, reusing this field to preserve and restore it
while running off the IRQ stack must be safe, as those occurrences are
guaranteed to never overlap. (The stack switching logic only switches
stacks when running from the task stack, and so the value being saved
here always corresponds to the task mode shadow stack)

While at it, fold a mov/add/mov sequence into a single add.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Kees Cook <keescook at chromium.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>
Link: https://lore.kernel.org/r/20230109174800.3286265-3-ardb at kernel.org
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Xiang Yang <xiangyang3 at huawei.com>
---
 arch/arm64/kernel/entry.S | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index b0d102669dde..e35f3cec74d9 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -1011,19 +1011,19 @@ NOKPROBE(ret_from_fork)
  */
 SYM_FUNC_START(call_on_irq_stack)
 #ifdef CONFIG_SHADOW_CALL_STACK
-	stp	scs_sp, xzr, [sp, #-16]!
+	get_current_task x16
+	scs_save x16
 	adr_this_cpu scs_sp, irq_shadow_call_stack, x17
 #endif
+
 	/* Create a frame record to save our LR and SP (implicit in FP) */
 	stp	x29, x30, [sp, #-16]!
 	mov	x29, sp
 
 	ldr_this_cpu x16, irq_stack_ptr, x17
-	mov	x15, #IRQ_STACK_SIZE
-	add	x16, x16, x15
 
 	/* Move to the new stack and call the function there */
-	mov	sp, x16
+	add	sp, x16, #IRQ_STACK_SIZE
 	blr	x1
 
 	/*
@@ -1032,9 +1032,7 @@ SYM_FUNC_START(call_on_irq_stack)
 	 */
 	mov	sp, x29
 	ldp	x29, x30, [sp], #16
-#ifdef CONFIG_SHADOW_CALL_STACK
-	ldp	scs_sp, xzr, [sp], #16
-#endif
+	scs_load_current
 	ret
 SYM_FUNC_END(call_on_irq_stack)
 NOKPROBE(call_on_irq_stack)
-- 
2.34.1



From xiangyang3 at huawei.com  Sat Feb 17 18:30:52 2024
From: xiangyang3 at huawei.com (Xiang Yang)
Date: Sun, 18 Feb 2024 10:30:52 +0800
Subject: [PATCH 5.10.y 2/5] arm64: entry: move arm64_preempt_schedule_irq to entry-common.c
In-Reply-To: <20240218023055.145519-1-xiangyang3@huawei.com>
References: <20240218023055.145519-1-xiangyang3@huawei.com>
Message-ID: <20240218023055.145519-3-xiangyang3@huawei.com>

From: Mark Rutland <mark.rutland at arm.com>

commit 33a3581a76f3a36c7dcc9864120ce681bcfbcff1 upstream.

Subsequent patches will pull more of the IRQ entry handling into C. To
keep this in one place, let's move arm64_preempt_schedule_irq() into
entry-common.c along with the other entry management functions.

We no longer need to include <linux/lockdep.h> in process.c, so the
include directive is removed.

There should be no functional change as a result of this patch.

Reviewed-by Joey Gouly <joey.gouly at arm.com>

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Will Deacon <will at kernel.org>
Link: https://lore.kernel.org/r/20210607094624.34689-5-mark.rutland at arm.com
Signed-off-by: Will Deacon <will at kernel.org>
Signed-off-by: Xiang Yang <xiangyang3 at huawei.com>
---
 arch/arm64/kernel/entry-common.c | 20 ++++++++++++++++++++
 arch/arm64/kernel/process.c      | 17 -----------------
 2 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 7a8cd856ee85..a533f4827253 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -6,7 +6,11 @@
  */
 
 #include <linux/context_tracking.h>
+#include <linux/linkage.h>
+#include <linux/lockdep.h>
 #include <linux/ptrace.h>
+#include <linux/sched.h>
+#include <linux/sched/debug.h>
 #include <linux/thread_info.h>
 
 #include <asm/cpufeature.h>
@@ -109,6 +113,22 @@ asmlinkage void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs)
 		exit_to_kernel_mode(regs);
 }
 
+asmlinkage void __sched arm64_preempt_schedule_irq(void)
+{
+	lockdep_assert_irqs_disabled();
+
+	/*
+	 * Preempting a task from an IRQ means we leave copies of PSTATE
+	 * on the stack. cpufeature's enable calls may modify PSTATE, but
+	 * resuming one of these preempted tasks would undo those changes.
+	 *
+	 * Only allow a task to be preempted once cpufeatures have been
+	 * enabled.
+	 */
+	if (system_capabilities_finalized())
+		preempt_schedule_irq();
+}
+
 static void noinstr el1_abort(struct pt_regs *regs, unsigned long esr)
 {
 	unsigned long far = read_sysreg(far_el1);
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 3696dbcbfa80..a04b152696cf 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -18,7 +18,6 @@
 #include <linux/sched/task.h>
 #include <linux/sched/task_stack.h>
 #include <linux/kernel.h>
-#include <linux/lockdep.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/nospec.h>
@@ -702,22 +701,6 @@ static int __init tagged_addr_init(void)
 core_initcall(tagged_addr_init);
 #endif	/* CONFIG_ARM64_TAGGED_ADDR_ABI */
 
-asmlinkage void __sched arm64_preempt_schedule_irq(void)
-{
-	lockdep_assert_irqs_disabled();
-
-	/*
-	 * Preempting a task from an IRQ means we leave copies of PSTATE
-	 * on the stack. cpufeature's enable calls may modify PSTATE, but
-	 * resuming one of these preempted tasks would undo those changes.
-	 *
-	 * Only allow a task to be preempted once cpufeatures have been
-	 * enabled.
-	 */
-	if (system_capabilities_finalized())
-		preempt_schedule_irq();
-}
-
 #ifdef CONFIG_BINFMT_ELF
 int arch_elf_adjust_prot(int prot, const struct arch_elf_state *state,
 			 bool has_interp, bool is_interp)
-- 
2.34.1



From xiangyang3 at huawei.com  Sat Feb 17 18:30:53 2024
From: xiangyang3 at huawei.com (Xiang Yang)
Date: Sun, 18 Feb 2024 10:30:53 +0800
Subject: [PATCH 5.10.y 3/5] arm64: entry: add a call_on_irq_stack helper
In-Reply-To: <20240218023055.145519-1-xiangyang3@huawei.com>
References: <20240218023055.145519-1-xiangyang3@huawei.com>
Message-ID: <20240218023055.145519-4-xiangyang3@huawei.com>

From: Mark Rutland <mark.rutland at arm.com>

commit f8049488e7d37b0a0e438ee449e83b3e46958743 upstream.

When handling IRQ/FIQ exceptions the entry assembly may transition from
a task's stack to a CPU's IRQ stack (and IRQ shadow call stack).

In subsequent patches we want to migrate the IRQ/FIQ triage logic to C,
and as we want to perform some actions on the task stack (e.g. EL1
preemption), we need to switch stacks within the C handler. So that we
can do so, this patch adds a helper to call a function on a CPU's IRQ
stack (and shadow stack as appropriate).

Subsequent patches will make use of the new helper function.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Will Deacon <will at kernel.org>
Link: https://lore.kernel.org/r/20210607094624.34689-7-mark.rutland at arm.com
Signed-off-by: Will Deacon <will at kernel.org>
Signed-off-by: Xiang Yang <xiangyang3 at huawei.com>
---
 arch/arm64/include/asm/exception.h |  2 ++
 arch/arm64/kernel/entry.S          | 36 ++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index cc5b2203d876..def53267f4a2 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -28,6 +28,8 @@ static inline u32 disr_to_esr(u64 disr)
 
 asmlinkage void noinstr enter_el1_irq_or_nmi(struct pt_regs *regs);
 asmlinkage void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs);
+asmlinkage void call_on_irq_stack(struct pt_regs *regs,
+				  void (*func)(struct pt_regs *));
 asmlinkage void enter_from_user_mode(void);
 asmlinkage void exit_to_user_mode(void);
 void arm64_enter_nmi(struct pt_regs *regs);
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 020a455824be..8b17d83e8c87 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -1043,6 +1043,42 @@ SYM_CODE_START(ret_from_fork)
 SYM_CODE_END(ret_from_fork)
 NOKPROBE(ret_from_fork)
 
+/*
+ * void call_on_irq_stack(struct pt_regs *regs,
+ * 		          void (*func)(struct pt_regs *));
+ *
+ * Calls func(regs) using this CPU's irq stack and shadow irq stack.
+ */
+SYM_FUNC_START(call_on_irq_stack)
+#ifdef CONFIG_SHADOW_CALL_STACK
+	stp	scs_sp, xzr, [sp, #-16]!
+	adr_this_cpu scs_sp, irq_shadow_call_stack, x17
+#endif
+	/* Create a frame record to save our LR and SP (implicit in FP) */
+	stp	x29, x30, [sp, #-16]!
+	mov	x29, sp
+
+	ldr_this_cpu x16, irq_stack_ptr, x17
+	mov	x15, #IRQ_STACK_SIZE
+	add	x16, x16, x15
+
+	/* Move to the new stack and call the function there */
+	mov	sp, x16
+	blr	x1
+
+	/*
+	 * Restore the SP from the FP, and restore the FP and LR from the frame
+	 * record.
+	 */
+	mov	sp, x29
+	ldp	x29, x30, [sp], #16
+#ifdef CONFIG_SHADOW_CALL_STACK
+	ldp	scs_sp, xzr, [sp], #16
+#endif
+	ret
+SYM_FUNC_END(call_on_irq_stack)
+NOKPROBE(call_on_irq_stack)
+
 #ifdef CONFIG_ARM_SDE_INTERFACE
 
 #include <asm/sdei.h>
-- 
2.34.1



From xiangyang3 at huawei.com  Sat Feb 17 18:30:50 2024
From: xiangyang3 at huawei.com (Xiang Yang)
Date: Sun, 18 Feb 2024 10:30:50 +0800
Subject: [PATCH 5.10.y 0/5] Backport call_on_irq_stack to fix scs overwritten in irq_stack_entry
Message-ID: <20240218023055.145519-1-xiangyang3@huawei.com>

The shadow call stack for irq now stored in current task's thread info
may restored incorrectly, so backport call_on_irq_stack from mainline to
fix it.

Ard Biesheuvel (1):
  arm64: Stash shadow stack pointer in the task struct on interrupt

Mark Rutland (3):
  arm64: entry: move arm64_preempt_schedule_irq to entry-common.c
  arm64: entry: add a call_on_irq_stack helper
  arm64: entry: convert IRQ+FIQ handlers to C

Xiang Yang (1):
  Revert "arm64: Stash shadow stack pointer in the task struct on
    interrupt"

 arch/arm64/include/asm/exception.h |  5 ++
 arch/arm64/kernel/entry-common.c   | 86 ++++++++++++++++++++++++++++++
 arch/arm64/kernel/entry.S          | 84 ++++++++++++++---------------
 arch/arm64/kernel/process.c        | 17 ------
 4 files changed, 132 insertions(+), 60 deletions(-)

-- 
2.34.1



From xiangyang3 at huawei.com  Sat Feb 17 18:30:51 2024
From: xiangyang3 at huawei.com (Xiang Yang)
Date: Sun, 18 Feb 2024 10:30:51 +0800
Subject: [PATCH 5.10.y 1/5] Revert "arm64: Stash shadow stack pointer in the task struct on interrupt"
In-Reply-To: <20240218023055.145519-1-xiangyang3@huawei.com>
References: <20240218023055.145519-1-xiangyang3@huawei.com>
Message-ID: <20240218023055.145519-2-xiangyang3@huawei.com>

This reverts commit 3f225f29c69c13ce1cbdb1d607a42efeef080056.

The shadow call stack for irq now is stored in current task's thread info
in irq_stack_entry. There is a possibility that we have some soft irqs
pending at the end of hard irq, and when we process softirq with the irq
enabled, irq_stack_entry will enter again and overwrite the shadow call
stack whitch stored in current task's thread info, leading to the
incorrect shadow call stack restoration for the first entry of the hard
IRQ, then the system end up with a panic.

task A                               |  task A
-------------------------------------+------------------------------------
el1_irq        //irq1 enter          |
  irq_handler  //save scs_sp1        |
    gic_handle_irq                   |
    irq_exit                         |
      __do_softirq                   |
                                     | el1_irq         //irq2 enter
                                     |   irq_handler   //save scs_sp2
                                     |                 //overwrite scs_sp1
                                     |   ...
                                     |   irq_stack_exit //restore scs_sp2
  irq_stack_exit //restore wrong     |
                 //scs_sp2           |

Fixes: 3f225f29c69c ("arm64: Stash shadow stack pointer in the task struct on interrupt")

Cc: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Xiang Yang <xiangyang3 at huawei.com>
---
 arch/arm64/kernel/entry.S | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index a94acea770c7..020a455824be 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -431,7 +431,9 @@ SYM_CODE_END(__swpan_exit_el0)
 
 	.macro	irq_stack_entry
 	mov	x19, sp			// preserve the original sp
-	scs_save tsk			// preserve the original shadow stack
+#ifdef CONFIG_SHADOW_CALL_STACK
+	mov	x24, scs_sp		// preserve the original shadow stack
+#endif
 
 	/*
 	 * Compare sp with the base of the task stack.
@@ -465,7 +467,9 @@ SYM_CODE_END(__swpan_exit_el0)
 	 */
 	.macro	irq_stack_exit
 	mov	sp, x19
-	scs_load_current
+#ifdef CONFIG_SHADOW_CALL_STACK
+	mov	scs_sp, x24
+#endif
 	.endm
 
 /* GPRs used by entry code */
-- 
2.34.1



From xiangyang3 at huawei.com  Sat Feb 17 18:30:54 2024
From: xiangyang3 at huawei.com (Xiang Yang)
Date: Sun, 18 Feb 2024 10:30:54 +0800
Subject: [PATCH 5.10.y 4/5] arm64: entry: convert IRQ+FIQ handlers to C
In-Reply-To: <20240218023055.145519-1-xiangyang3@huawei.com>
References: <20240218023055.145519-1-xiangyang3@huawei.com>
Message-ID: <20240218023055.145519-5-xiangyang3@huawei.com>

From: Mark Rutland <mark.rutland at arm.com>

commit 064dbfb4169141943ec7d9dbfd02974dd008f2ce upstream.

For various reasons we'd like to convert the bulk of arm64's exception
triage logic to C. As a step towards that, this patch converts the EL1
and EL0 IRQ+FIQ triage logic to C.

Separate C functions are added for the native and compat cases so that
in subsequent patches we can handle native/compat differences in C.

Since the triage functions can now call arm64_apply_bp_hardening()
directly, the do_el0_irq_bp_hardening() wrapper function is removed.

Since the user_exit_irqoff macro is now unused, it is removed. The
user_enter_irqoff macro is still used by the ret_to_user code, and
cannot be removed at this time.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Cc: James Morse <james.morse at arm.com>
Cc: Will Deacon <will at kernel.org>
Link: https://lore.kernel.org/r/20210607094624.34689-8-mark.rutland at arm.com
Signed-off-by: Will Deacon <will at kernel.org>
Signed-off-by: Xiang Yang <xiangyang3 at huawei.com>
---
 arch/arm64/include/asm/exception.h |  3 ++
 arch/arm64/kernel/entry-common.c   | 68 +++++++++++++++++++++++++++++-
 arch/arm64/kernel/entry.S          | 54 +++---------------------
 3 files changed, 77 insertions(+), 48 deletions(-)

diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index def53267f4a2..846ca8132f76 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -26,6 +26,9 @@ static inline u32 disr_to_esr(u64 disr)
 	return esr;
 }
 
+asmlinkage void el1_irq_handler(struct pt_regs *regs);
+asmlinkage void el0_irq_handler(struct pt_regs *regs);
+asmlinkage void el0_irq_compat_handler(struct pt_regs *regs);
 asmlinkage void noinstr enter_el1_irq_or_nmi(struct pt_regs *regs);
 asmlinkage void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs);
 asmlinkage void call_on_irq_stack(struct pt_regs *regs,
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index a533f4827253..340249c65007 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -19,6 +19,8 @@
 #include <asm/exception.h>
 #include <asm/kprobes.h>
 #include <asm/mmu.h>
+#include <asm/processor.h>
+#include <asm/stacktrace.h>
 #include <asm/sysreg.h>
 
 /*
@@ -113,7 +115,7 @@ asmlinkage void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs)
 		exit_to_kernel_mode(regs);
 }
 
-asmlinkage void __sched arm64_preempt_schedule_irq(void)
+static void __sched arm64_preempt_schedule_irq(void)
 {
 	lockdep_assert_irqs_disabled();
 
@@ -141,6 +143,42 @@ static void noinstr el1_abort(struct pt_regs *regs, unsigned long esr)
 	exit_to_kernel_mode(regs);
 }
 
+static void do_interrupt_handler(struct pt_regs *regs,
+                                void (*handler)(struct pt_regs *))
+{
+	if (on_thread_stack())
+		call_on_irq_stack(regs, handler);
+	else
+		handler(regs);
+}
+
+extern void (*handle_arch_irq)(struct pt_regs *);
+
+static void noinstr el1_interrupt(struct pt_regs *regs,
+				  void (*handler)(struct pt_regs *))
+{
+	write_sysreg(DAIF_PROCCTX_NOIRQ, daif);
+
+	enter_el1_irq_or_nmi(regs);
+	do_interrupt_handler(regs, handler);
+
+	/*
+	 * Note: thread_info::preempt_count includes both thread_info::count
+	 * and thread_info::need_resched, and is not equivalent to
+	 * preempt_count().
+	 */
+	if (IS_ENABLED(CONFIG_PREEMPTION) &&
+	    READ_ONCE(current_thread_info()->preempt_count) == 0)
+		arm64_preempt_schedule_irq();
+
+	exit_el1_irq_or_nmi(regs);
+}
+
+asmlinkage void noinstr el1_irq_handler(struct pt_regs *regs)
+{
+	el1_interrupt(regs, handle_arch_irq);
+}
+
 static void noinstr el1_pc(struct pt_regs *regs, unsigned long esr)
 {
 	unsigned long far = read_sysreg(far_el1);
@@ -445,6 +483,29 @@ asmlinkage void noinstr el0_sync_handler(struct pt_regs *regs)
 	}
 }
 
+static void noinstr el0_interrupt(struct pt_regs *regs,
+				  void (*handler)(struct pt_regs *))
+{
+	enter_from_user_mode();
+
+	write_sysreg(DAIF_PROCCTX_NOIRQ, daif);
+
+	if (regs->pc & BIT(55))
+		arm64_apply_bp_hardening();
+
+	do_interrupt_handler(regs, handler);
+}
+
+static void noinstr __el0_irq_handler_common(struct pt_regs *regs)
+{
+	el0_interrupt(regs, handle_arch_irq);
+}
+
+asmlinkage void noinstr el0_irq_handler(struct pt_regs *regs)
+{
+	__el0_irq_handler_common(regs);
+}
+
 #ifdef CONFIG_COMPAT
 static void noinstr el0_cp15(struct pt_regs *regs, unsigned long esr)
 {
@@ -453,6 +514,11 @@ static void noinstr el0_cp15(struct pt_regs *regs, unsigned long esr)
 	do_el0_cp15(esr, regs);
 }
 
+asmlinkage void noinstr el0_irq_compat_handler(struct pt_regs *regs)
+{
+	__el0_irq_handler_common(regs);
+}
+
 static void noinstr el0_svc_compat(struct pt_regs *regs)
 {
 	enter_from_user_mode();
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 8b17d83e8c87..b0d102669dde 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -429,49 +429,6 @@ SYM_CODE_START_LOCAL(__swpan_exit_el0)
 SYM_CODE_END(__swpan_exit_el0)
 #endif
 
-	.macro	irq_stack_entry
-	mov	x19, sp			// preserve the original sp
-#ifdef CONFIG_SHADOW_CALL_STACK
-	mov	x24, scs_sp		// preserve the original shadow stack
-#endif
-
-	/*
-	 * Compare sp with the base of the task stack.
-	 * If the top ~(THREAD_SIZE - 1) bits match, we are on a task stack,
-	 * and should switch to the irq stack.
-	 */
-	ldr	x25, [tsk, TSK_STACK]
-	eor	x25, x25, x19
-	and	x25, x25, #~(THREAD_SIZE - 1)
-	cbnz	x25, 9998f
-
-	ldr_this_cpu x25, irq_stack_ptr, x26
-	mov	x26, #IRQ_STACK_SIZE
-	add	x26, x25, x26
-
-	/* switch to the irq stack */
-	mov	sp, x26
-
-#ifdef CONFIG_SHADOW_CALL_STACK
-	/* also switch to the irq shadow stack */
-	adr_this_cpu scs_sp, irq_shadow_call_stack, x26
-#endif
-
-9998:
-	.endm
-
-	/*
-	 * The callee-saved regs (x19-x29) should be preserved between
-	 * irq_stack_entry and irq_stack_exit, but note that kernel_entry
-	 * uses x20-x23 to store data for later use.
-	 */
-	.macro	irq_stack_exit
-	mov	sp, x19
-#ifdef CONFIG_SHADOW_CALL_STACK
-	mov	scs_sp, x24
-#endif
-	.endm
-
 /* GPRs used by entry code */
 tsk	.req	x28		// current thread_info
 
@@ -675,7 +632,8 @@ SYM_CODE_END(el1_sync)
 	.align	6
 SYM_CODE_START_LOCAL_NOALIGN(el1_irq)
 	kernel_entry 1
-	el1_interrupt_handler handle_arch_irq
+	mov	x0, sp
+	bl	el1_irq_handler
 	kernel_exit 1
 SYM_CODE_END(el1_irq)
 
@@ -702,7 +660,9 @@ SYM_CODE_END(el0_sync_compat)
 	.align	6
 SYM_CODE_START_LOCAL_NOALIGN(el0_irq_compat)
 	kernel_entry 0, 32
-	b	el0_irq_naked
+	mov	x0, sp
+	bl	el0_irq_compat_handler
+	b	ret_to_user
 SYM_CODE_END(el0_irq_compat)
 
 SYM_CODE_START_LOCAL_NOALIGN(el0_error_compat)
@@ -714,8 +674,8 @@ SYM_CODE_END(el0_error_compat)
 	.align	6
 SYM_CODE_START_LOCAL_NOALIGN(el0_irq)
 	kernel_entry 0
-el0_irq_naked:
-	el0_interrupt_handler handle_arch_irq
+	mov	x0, sp
+	bl	el0_irq_handler
 	b	ret_to_user
 SYM_CODE_END(el0_irq)
 
-- 
2.34.1



From andersson at kernel.org  Sat Feb 17 19:08:35 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 17 Feb 2024 21:08:35 -0600
Subject: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the
 TZ allocator
In-Reply-To: <20240205182810.58382-9-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
 <20240205182810.58382-9-brgl@bgdev.pl>
Message-ID: <yu5uhamdlygti3jo73ipy3gxhcmgxrm5g6imgqg6ksleim4ton@npvzlex2j4xi>

On Mon, Feb 05, 2024 at 07:28:06PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
> convert all users of it in the qseecom module to using the TZ allocator
> for creating SCM call buffers.

This reads as if this is removal of duplication, now that we have the TZ
allocation. But wasn't there something about you not being able to mix
and match shmbridge and non-shmbridge allocations in the interface, so
this transition is actually required? Or did I get that wrong and this
just reduction in duplication?

> Together with using the cleanup macros,
> it has the added benefit of a significant code shrink.

That is true, but the move to using cleanup macros at the same time as
changing the implementation makes it unnecessarily hard to reason about
this patch.

This patch would be much better if split in two.

> As this is
> largely a module separate from the SCM driver, let's use a separate
> memory pool.
> 

This module is effectively used to read and write EFI variables today.
Is that worth statically removing 256kb of DDR for? Is this done solely
because it logically makes sense, or did you choose this for a reason?

Regards,
Bjorn

> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
> Tested-by: Maximilian Luz <luzmaximilian at gmail.com>
> Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
> ---
>  .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++++-----------
>  drivers/firmware/qcom/qcom_scm.c              |  30 +-
>  include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
>  3 files changed, 111 insertions(+), 204 deletions(-)
> 
> diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
> index 32188f098ef3..3a068f8b6990 100644
> --- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
> +++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
> @@ -7,17 +7,21 @@
>   * Copyright (C) 2023 Maximilian Luz <luzmaximilian at gmail.com>
>   */
>  
> +#include <linux/cleanup.h>
>  #include <linux/efi.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/mutex.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> +#include <linux/sizes.h>
>  #include <linux/slab.h>
>  #include <linux/types.h>
>  #include <linux/ucs2_string.h>
>  
>  #include <linux/firmware/qcom/qcom_qseecom.h>
> +#include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/firmware/qcom/qcom_tzmem.h>
>  
>  /* -- Qualcomm "uefisecapp" interface definitions. -------------------------- */
>  
> @@ -253,6 +257,7 @@ struct qsee_rsp_uefi_query_variable_info {
>  struct qcuefi_client {
>  	struct qseecom_client *client;
>  	struct efivars efivars;
> +	struct qcom_tzmem_pool *mempool;
>  };
>  
>  static struct device *qcuefi_dev(struct qcuefi_client *qcuefi)
> @@ -272,11 +277,11 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  					   const efi_guid_t *guid, u32 *attributes,
>  					   unsigned long *data_size, void *data)
>  {
> -	struct qsee_req_uefi_get_variable *req_data;
> -	struct qsee_rsp_uefi_get_variable *rsp_data;
> +	struct qsee_req_uefi_get_variable *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_get_variable *rsp_data __free(qcom_tzmem) = NULL;
>  	unsigned long buffer_size = *data_size;
> -	efi_status_t efi_status = EFI_SUCCESS;
>  	unsigned long name_length;
> +	efi_status_t efi_status;
>  	size_t guid_offs;
>  	size_t name_offs;
>  	size_t req_size;
> @@ -304,17 +309,13 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  		__array(u8, buffer_size)
>  	);
>  
> -	req_data = kzalloc(req_size, GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE;
>  	req_data->data_size = buffer_size;
> @@ -325,28 +326,20 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  	req_data->length = req_size;
>  
>  	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
> -	if (status < 0) {
> -		efi_status = EFI_INVALID_PARAMETER;
> -		goto out_free;
> -	}
> +	if (status < 0)
> +		return EFI_INVALID_PARAMETER;
>  
>  	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length < sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length < sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
> @@ -360,18 +353,14 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  				*attributes = rsp_data->attributes;
>  		}
>  
> -		goto out_free;
> +		return efi_status;
>  	}
>  
> -	if (rsp_data->length > rsp_size) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length > rsp_size)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length)
> +		return EFI_DEVICE_ERROR;
>  
>  	/*
>  	 * Note: We need to set attributes and data size even if the buffer is
> @@ -394,33 +383,23 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  	if (attributes)
>  		*attributes = rsp_data->attributes;
>  
> -	if (buffer_size == 0 && !data) {
> -		efi_status = EFI_SUCCESS;
> -		goto out_free;
> -	}
> +	if (buffer_size == 0 && !data)
> +		return EFI_SUCCESS;
>  
> -	if (buffer_size < rsp_data->data_size) {
> -		efi_status = EFI_BUFFER_TOO_SMALL;
> -		goto out_free;
> -	}
> +	if (buffer_size < rsp_data->data_size)
> +		return EFI_BUFFER_TOO_SMALL;
>  
>  	memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size);
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const efi_char16_t *name,
>  					   const efi_guid_t *guid, u32 attributes,
>  					   unsigned long data_size, const void *data)
>  {
> -	struct qsee_req_uefi_set_variable *req_data;
> -	struct qsee_rsp_uefi_set_variable *rsp_data;
> -	efi_status_t efi_status = EFI_SUCCESS;
> +	struct qsee_req_uefi_set_variable *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_set_variable *rsp_data __free(qcom_tzmem) = NULL;
>  	unsigned long name_length;
>  	size_t name_offs;
>  	size_t guid_offs;
> @@ -450,17 +429,14 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
>  		__array_offs(u8, data_size, &data_offs)
>  	);
>  
> -	req_data = kzalloc(req_size, GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
> +				    GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
>  	req_data->attributes = attributes;
> @@ -473,10 +449,8 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
>  	req_data->length = req_size;
>  
>  	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
> -	if (status < 0) {
> -		efi_status = EFI_INVALID_PARAMETER;
> -		goto out_free;
> -	}
> +	if (status < 0)
> +		return EFI_INVALID_PARAMETER;
>  
>  	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
>  
> @@ -485,42 +459,31 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data,
>  				       sizeof(*rsp_data));
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length != sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length != sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
>  			__func__, rsp_data->status);
> -		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
> +		return qsee_uefi_status_to_efi(rsp_data->status);
>  	}
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  						unsigned long *name_size, efi_char16_t *name,
>  						efi_guid_t *guid)
>  {
> -	struct qsee_req_uefi_get_next_variable *req_data;
> -	struct qsee_rsp_uefi_get_next_variable *rsp_data;
> -	efi_status_t efi_status = EFI_SUCCESS;
> +	struct qsee_req_uefi_get_next_variable *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_get_next_variable *rsp_data __free(qcom_tzmem) = NULL;
> +	efi_status_t efi_status;
>  	size_t guid_offs;
>  	size_t name_offs;
>  	size_t req_size;
> @@ -545,17 +508,13 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  		__array(*name, *name_size / sizeof(*name))
>  	);
>  
> -	req_data = kzalloc(req_size, GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE;
>  	req_data->guid_offset = guid_offs;
> @@ -567,26 +526,18 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
>  	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name,
>  			      *name_size / sizeof(*name));
> -	if (status < 0) {
> -		efi_status = EFI_INVALID_PARAMETER;
> -		goto out_free;
> -	}
> +	if (status < 0)
> +		return EFI_INVALID_PARAMETER;
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length < sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length < sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
> @@ -601,77 +552,59 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  		if (efi_status == EFI_BUFFER_TOO_SMALL)
>  			*name_size = rsp_data->name_size;
>  
> -		goto out_free;
> +		return efi_status;
>  	}
>  
> -	if (rsp_data->length > rsp_size) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length > rsp_size)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length)
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->name_size > *name_size) {
>  		*name_size = rsp_data->name_size;
> -		efi_status = EFI_BUFFER_TOO_SMALL;
> -		goto out_free;
> +		return EFI_BUFFER_TOO_SMALL;
>  	}
>  
> -	if (rsp_data->guid_size != sizeof(*guid)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->guid_size != sizeof(*guid))
> +		return EFI_DEVICE_ERROR;
>  
>  	memcpy(guid, ((void *)rsp_data) + rsp_data->guid_offset, rsp_data->guid_size);
>  	status = ucs2_strscpy(name, ((void *)rsp_data) + rsp_data->name_offset,
>  			      rsp_data->name_size / sizeof(*name));
>  	*name_size = rsp_data->name_size;
>  
> -	if (status < 0) {
> +	if (status < 0)
>  		/*
>  		 * Return EFI_DEVICE_ERROR here because the buffer size should
>  		 * have already been validated above, causing this function to
>  		 * bail with EFI_BUFFER_TOO_SMALL.
>  		 */
> -		efi_status = EFI_DEVICE_ERROR;
> -	}
> +		return EFI_DEVICE_ERROR;
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, u32 attr,
>  						  u64 *storage_space, u64 *remaining_space,
>  						  u64 *max_variable_size)
>  {
> -	struct qsee_req_uefi_query_variable_info *req_data;
> -	struct qsee_rsp_uefi_query_variable_info *rsp_data;
> -	efi_status_t efi_status = EFI_SUCCESS;
> +	struct qsee_req_uefi_query_variable_info *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_query_variable_info *rsp_data __free(qcom_tzmem) = NULL;
>  	int status;
>  
> -	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*req_data),
> +				    GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
> +				    GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
>  	req_data->attributes = attr;
> @@ -679,26 +612,19 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data,
>  				       sizeof(*rsp_data));
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length != sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length != sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
>  			__func__, rsp_data->status);
> -		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
> -		goto out_free;
> +		return qsee_uefi_status_to_efi(rsp_data->status);
>  	}
>  
>  	if (storage_space)
> @@ -710,12 +636,7 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
>  	if (max_variable_size)
>  		*max_variable_size = rsp_data->max_variable_size;
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  /* -- Global efivar interface. ---------------------------------------------- */
> @@ -844,6 +765,10 @@ static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
>  	if (status)
>  		qcuefi_set_reference(NULL);
>  
> +	qcuefi->mempool = devm_qcom_tzmem_pool_new(&aux_dev->dev, SZ_256K);
> +	if (IS_ERR(qcuefi->mempool))
> +		return PTR_ERR(qcuefi->mempool);
> +
>  	return status;
>  }
>  
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 3a6cefb4eb2e..318d7d398e5f 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -1567,9 +1567,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id);
>  /**
>   * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app.
>   * @app_id:   The ID of the target app.
> - * @req:      Request buffer sent to the app (must be DMA-mappable).
> + * @req:      Request buffer sent to the app (must be TZ memory)
>   * @req_size: Size of the request buffer.
> - * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
> + * @rsp:      Response buffer, written to by the app (must be TZ memory)
>   * @rsp_size: Size of the response buffer.
>   *
>   * Sends a request to the QSEE app associated with the given ID and read back
> @@ -1585,26 +1585,12 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
>  {
>  	struct qcom_scm_qseecom_resp res = {};
>  	struct qcom_scm_desc desc = {};
> -	dma_addr_t req_phys;
> -	dma_addr_t rsp_phys;
> +	phys_addr_t req_phys;
> +	phys_addr_t rsp_phys;
>  	int status;
>  
> -	/* Map request buffer */
> -	req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE);
> -	status = dma_mapping_error(__scm->dev, req_phys);
> -	if (status) {
> -		dev_err(__scm->dev, "qseecom: failed to map request buffer\n");
> -		return status;
> -	}
> -
> -	/* Map response buffer */
> -	rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE);
> -	status = dma_mapping_error(__scm->dev, rsp_phys);
> -	if (status) {
> -		dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
> -		dev_err(__scm->dev, "qseecom: failed to map response buffer\n");
> -		return status;
> -	}
> +	req_phys = qcom_tzmem_to_phys(req);
> +	rsp_phys = qcom_tzmem_to_phys(rsp);
>  
>  	/* Set up SCM call data */
>  	desc.owner = QSEECOM_TZ_OWNER_TZ_APPS;
> @@ -1622,10 +1608,6 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
>  	/* Perform call */
>  	status = qcom_scm_qseecom_call(&desc, &res);
>  
> -	/* Unmap buffers */
> -	dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE);
> -	dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
> -
>  	if (status)
>  		return status;
>  
> diff --git a/include/linux/firmware/qcom/qcom_qseecom.h b/include/linux/firmware/qcom/qcom_qseecom.h
> index 5c28298a98be..e868fac55675 100644
> --- a/include/linux/firmware/qcom/qcom_qseecom.h
> +++ b/include/linux/firmware/qcom/qcom_qseecom.h
> @@ -27,9 +27,9 @@ struct qseecom_client {
>  /**
>   * qcom_qseecom_app_send() - Send to and receive data from a given QSEE app.
>   * @client:   The QSEECOM client associated with the target app.
> - * @req:      Request buffer sent to the app (must be DMA-mappable).
> + * @req:      Request buffer sent to the app (must be TZ memory).
>   * @req_size: Size of the request buffer.
> - * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
> + * @rsp:      Response buffer, written to by the app (must be TZ memory).
>   * @rsp_size: Size of the response buffer.
>   *
>   * Sends a request to the QSEE app associated with the given client and read
> -- 
> 2.40.1
> 


From jassisinghbrar at gmail.com  Sat Feb 17 19:10:42 2024
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Sat, 17 Feb 2024 21:10:42 -0600
Subject: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
In-Reply-To: <DU0PR04MB94170454D64EF65E6774BEAB88522@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20240201-imx-mailbox-v6-0-76f4f35b403e@nxp.com>
 <PA4PR04MB941646795F4E19D1EC35134F88522@PA4PR04MB9416.eurprd04.prod.outlook.com>
 <CABb+yY0aM9Dn3LPBqb11vU3Ln4bCCGOBXX77sF499cyb_sXiUA@mail.gmail.com> <DU0PR04MB94170454D64EF65E6774BEAB88522@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <CABb+yY3U5GzvznLDU7pyA1ppfLT50MQKQ3YRXB3rYwr_QwcH-g@mail.gmail.com>

On Sat, Feb 17, 2024 at 8:10?PM Peng Fan <peng.fan at nxp.com> wrote:
>
> Hi Jassi,
>
> > Subject: Re: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
> >
> > Hi Peng,
> >
> > On Sat, Feb 17, 2024 at 7:38?PM Peng Fan <peng.fan at nxp.com> wrote:
> > >
> > > Hi Jassi
> > >
> > > > Subject: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
> > > >
> > > > - Add dt-bindings
> > > > - i.MX95 ELE/V2X use same register layout as i.MX8ULP S4 MU, but
> > > >   the TR/RR num is different. To make code reusable and not add too
> > much
> > > >   macros, add runtime detect number of TR and RR by reading PAR_OFF
> > > >   registers.
> > > > - Add i.MX95 ELE/V2X MU entry in driver
> > >
> > > Ping..
> > >
> > dt bindings and compatibles first need to be acked by dt maintainers.
>
> The bindings has been reviewed by Conor Dooley who listed as maintainer:
> OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
> M:      Rob Herring <robh+dt at kernel.org>
> M:      Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> M:      Conor Dooley <conor+dt at kernel.org>
>
Ok, I didn't realise we have three maintainers now.

I see no problem other than adding of_platform_populate() and
compatibles in the same patch. They should be separate.

cheers.


From daniel at makrotopia.org  Sat Feb 17 19:11:15 2024
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 18 Feb 2024 03:11:15 +0000
Subject: [PATCH] clk: mediatek: mt7981-topckgen: flag SGM_REG_SEL as critical
Message-ID: <fc157139e6b7f8dfb6430ac7191ba754027705e8.1708221995.git.daniel@makrotopia.org>

Without the SGM_REG_SEL clock enabled the cpu freezes if trying to
access registers used by MT7981 clock drivers itself.
Mark SGM_REG_SEL as critical to make sure it is always enabled to
prevent freezes on boot even if the Ethernet driver which prepares
and enables the clock is not loaded or probed at a later point.

Fixes: 813c3b53b55b ("clk: mediatek: add MT7981 clock support")
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 drivers/clk/mediatek/clk-mt7981-topckgen.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt7981-topckgen.c b/drivers/clk/mediatek/clk-mt7981-topckgen.c
index 682f4ca9e89ad..493aa11d3a175 100644
--- a/drivers/clk/mediatek/clk-mt7981-topckgen.c
+++ b/drivers/clk/mediatek/clk-mt7981-topckgen.c
@@ -357,8 +357,9 @@ static const struct mtk_mux top_muxes[] = {
 	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_FLAGS(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents,
+				   0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22,
+				   CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
 	MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents,
 			     0x050, 0x054, 0x058, 24, 3, 31, 0x1C0, 23),
 	/* CLK_CFG_6 */
-- 
2.43.0



From andersson at kernel.org  Sat Feb 17 19:22:31 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 17 Feb 2024 21:22:31 -0600
Subject: [PATCH v7 01/12] firmware: qcom: add a dedicated TrustZone
 buffer allocator
In-Reply-To: <20240205182810.58382-2-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
 <20240205182810.58382-2-brgl@bgdev.pl>
Message-ID: <5ppezcfez6tb3xmeevznwefvjjwjefwyzb5r6co4zlo53ht2c2@tdbwgbnxaalt>

On Mon, Feb 05, 2024 at 07:27:59PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
[..]
> diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
> new file mode 100644
> index 000000000000..44a062f2abd4
> --- /dev/null
> +++ b/drivers/firmware/qcom/qcom_tzmem.c
> @@ -0,0 +1,302 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later

Could you please confirm that "-or-later" is intended?

> +/*
> + * Memory allocator for buffers shared with the TrustZone.
> + *
> + * Copyright (C) 2023 Linaro Ltd.
> + */
[..]
> +/**
> + * qcom_tzmem_pool_new() - Create a new TZ memory pool.
> + * @size: Size of the new pool in bytes.
> + *
> + * Create a new pool of memory suitable for sharing with the TrustZone.
> + *
> + * Must not be used in atomic context.

 * Context: Describes whether the function can sleep, what locks it takes,
 *          releases, or expects to be held. It can extend over multiple
 *          lines.

> + *
> + * Returns:
> + * New memory pool address or ERR_PTR() on error.

 * Return: Describe the return value of function_name.

both from:
https://docs.kernel.org/doc-guide/kernel-doc.html#function-documentation

Regards,
Bjorn


From andersson at kernel.org  Sat Feb 17 19:25:12 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 17 Feb 2024 21:25:12 -0600
Subject: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
In-Reply-To: <20240205182810.58382-3-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
 <20240205182810.58382-3-brgl@bgdev.pl>
Message-ID: <tnylagkmj36lve2ub5voumtkqjdy6j3hr6yyk4mqkaabvc3gdv@voaiu2oqi73o>

On Mon, Feb 05, 2024 at 07:28:00PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> Select the TrustZone memory allocator in Kconfig and create a pool of
> memory shareable with the TrustZone when probing the SCM driver.
> 
> This will allow a gradual conversion of all relevant SCM calls to using
> the dedicated allocator.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
> Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
> ---
>  drivers/firmware/qcom/Kconfig    |  1 +
>  drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> index f18686edf415..d24d83223867 100644
> --- a/drivers/firmware/qcom/Kconfig
> +++ b/drivers/firmware/qcom/Kconfig
> @@ -7,6 +7,7 @@
>  menu "Qualcomm firmware drivers"
>  
>  config QCOM_SCM
> +	select QCOM_TZMEM
>  	tristate
>  
>  config QCOM_TZMEM
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 520de9b5633a..0d4c028be0c1 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -8,8 +8,10 @@
>  #include <linux/completion.h>
>  #include <linux/cpumask.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/err.h>
>  #include <linux/export.h>
>  #include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/firmware/qcom/qcom_tzmem.h>
>  #include <linux/init.h>
>  #include <linux/interconnect.h>
>  #include <linux/interrupt.h>
> @@ -20,9 +22,11 @@
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/reset-controller.h>
> +#include <linux/sizes.h>
>  #include <linux/types.h>
>  
>  #include "qcom_scm.h"
> +#include "qcom_tzmem.h"
>  
>  static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
>  module_param(download_mode, bool, 0);
> @@ -41,6 +45,8 @@ struct qcom_scm {
>  	int scm_vote_count;
>  
>  	u64 dload_mode_addr;
> +
> +	struct qcom_tzmem_pool *mempool;
>  };
>  
>  struct qcom_scm_current_perm_info {
> @@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
>  	if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
>  		qcom_scm_disable_sdi();
>  
> +	ret = qcom_tzmem_enable(__scm->dev);
> +	if (ret)
> +		return dev_err_probe(__scm->dev, ret,
> +				     "Failed to enable the TrustZone memory allocator\n");
> +
> +	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);

As we're not moving from the callers freely allocating what they need,
to a fixed sized pool of 256kb. Please document why 256kb was choosen,
so that we have something to fall back on when someone runs out of this
space, or wonders "why not 128kb?".

Regards,
Bjorn

> +	if (IS_ERR(__scm->mempool))
> +		return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
> +				     "Failed to create the SCM memory pool\n");
> +
>  	/*
>  	 * Initialize the QSEECOM interface.
>  	 *
> -- 
> 2.40.1
> 


From andersson at kernel.org  Sat Feb 17 19:41:51 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 17 Feb 2024 21:41:51 -0600
Subject: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
In-Reply-To: <20240205182810.58382-11-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
 <20240205182810.58382-11-brgl@bgdev.pl>
Message-ID: <7pybw4wxlzxfl65yuqxzks5w7uq52hosyq53etlzas6i6o5l6d@vxd4sykcxora>

On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> Add a new Kconfig option for selecting the SHM Bridge mode of operation

The Kconfig option is the least significant bit of this patch. I guess
there isn't really a problem to describe, but let's at least mention
that we're switching TZ to shmbridge mode and all. 

> for the TrustZone memory allocator.
> 
> If enabled at build-time, it will still be checked for availability at
> run-time. If the architecture doesn't support SHM Bridge, the allocator
> will work just like in the default mode.

"default mode"...SHMBRIDGE is the default mode from this point onwards.

> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
> ---
>  drivers/firmware/qcom/Kconfig      | 10 +++++
>  drivers/firmware/qcom/qcom_tzmem.c | 65 +++++++++++++++++++++++++++++-
>  2 files changed, 74 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> index d24d83223867..af6f895c5adf 100644
> --- a/drivers/firmware/qcom/Kconfig
> +++ b/drivers/firmware/qcom/Kconfig
> @@ -28,6 +28,16 @@ config QCOM_TZMEM_MODE_DEFAULT
>  	  Use the default allocator mode. The memory is page-aligned, non-cachable
>  	  and contiguous.
>  
> +config QCOM_TZMEM_MODE_SHMBRIDGE
> +	bool "SHM Bridge"
> +	help
> +	  Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
> +	  in the 'Default' allocator but is also explicitly marked as an SHM Bridge
> +	  buffer.
> +
> +	  With this selected, all buffers passed to the TrustZone must be allocated
> +	  using the TZMem allocator or else the TrustZone will refuse to use them.

It's funny how this is the only place in the whole series I can find
this mentioned. One could from this statement guess that the eluding
scminvoke requires shmbridge and that this patch series exists solely
to facilitate the requirement stated in this paragraph.

Either this guess is correct and this should have been made clear in
the commit messages, or I'm guessing wrong here, in which case I need
some help to figure out why this series exists.

Regards,
Bjorn

> +
>  endchoice
>  
>  config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
> diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
> index 44a062f2abd4..1ca3773263e5 100644
> --- a/drivers/firmware/qcom/qcom_tzmem.c
> +++ b/drivers/firmware/qcom/qcom_tzmem.c
> @@ -55,7 +55,70 @@ static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
>  
>  }
>  
> -#endif /* CONFIG_QCOM_TZMEM_MODE_DEFAULT */
> +#elif IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE)
> +
> +#include <linux/firmware/qcom/qcom_scm.h>
> +
> +#define QCOM_SHM_BRIDGE_NUM_VM_SHIFT 9
> +
> +static bool qcom_tzmem_using_shm_bridge;
> +
> +static int qcom_tzmem_init(void)
> +{
> +	int ret;
> +
> +	ret = qcom_scm_shm_bridge_enable();
> +	if (ret == -EOPNOTSUPP) {
> +		dev_info(qcom_tzmem_dev, "SHM Bridge not supported\n");
> +		return 0;
> +	}
> +
> +	if (!ret)
> +		qcom_tzmem_using_shm_bridge = true;
> +
> +	return ret;
> +}
> +
> +static int qcom_tzmem_init_pool(struct qcom_tzmem_pool *pool)
> +{
> +	u64 pfn_and_ns_perm, ipfn_and_s_perm, size_and_flags, ns_perms;
> +	int ret;
> +
> +	if (!qcom_tzmem_using_shm_bridge)
> +		return 0;
> +
> +	ns_perms = (QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_READ);
> +	pfn_and_ns_perm = (u64)pool->pbase | ns_perms;
> +	ipfn_and_s_perm = (u64)pool->pbase | ns_perms;
> +	size_and_flags = pool->size | (1 << QCOM_SHM_BRIDGE_NUM_VM_SHIFT);
> +
> +	u64 *handle __free(kfree) = kzalloc(sizeof(*handle), GFP_KERNEL);
> +	if (!handle)
> +		return -ENOMEM;
> +
> +	ret = qcom_scm_shm_bridge_create(qcom_tzmem_dev, pfn_and_ns_perm,
> +					 ipfn_and_s_perm, size_and_flags,
> +					 QCOM_SCM_VMID_HLOS, handle);
> +	if (ret)
> +		return ret;
> +
> +	pool->priv = no_free_ptr(handle);
> +
> +	return 0;
> +}
> +
> +static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
> +{
> +	u64 *handle = pool->priv;
> +
> +	if (!qcom_tzmem_using_shm_bridge)
> +		return;
> +
> +	qcom_scm_shm_bridge_delete(qcom_tzmem_dev, *handle);
> +	kfree(handle);
> +}
> +
> +#endif /* CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE */
>  
>  /**
>   * qcom_tzmem_pool_new() - Create a new TZ memory pool.
> -- 
> 2.40.1
> 


From andersson at kernel.org  Sat Feb 17 19:50:01 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 17 Feb 2024 21:50:01 -0600
Subject: [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in
 qcom_scm_pas_init_image()
In-Reply-To: <20240205182810.58382-12-brgl@bgdev.pl>
References: <20240205182810.58382-1-brgl@bgdev.pl>
 <20240205182810.58382-12-brgl@bgdev.pl>
Message-ID: <ihz4jczbhn3gdcs6nkgnzpyv3577ebd73qbkynw6jz7ciy4fu3@kxqu7olrrely>

On Mon, Feb 05, 2024 at 07:28:09PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> The "memory protection" mechanism mentioned in the comment is the SHM
> Bridge. This is also the reason why we do not convert this call to using
> the TZ memory allocator.
> 

No, this mechanism predates shmbridge.

> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
> ---
>  drivers/firmware/qcom/qcom_scm.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 839773270a21..7ba5cff6e4e7 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -563,9 +563,13 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
>  	struct qcom_scm_res res;
>  
>  	/*
> -	 * During the scm call memory protection will be enabled for the meta
> -	 * data blob, so make sure it's physically contiguous, 4K aligned and
> -	 * non-cachable to avoid XPU violations.

What this is saying is that the memory will be made unaccessible to
Linux, so it needs to be contiguous and aligned.

> +	 * During the SCM call the hypervisor will make the buffer containing
> +	 * the program data into an SHM Bridge.

Are you saying that the hypervisor will convert this memory to a
shmbridge, and then pass it to TrustZone?

> This is why we exceptionally
> +	 * must not use the TrustZone memory allocator here as - depending on
> +	 * Kconfig - it may already use the SHM Bridge mechanism internally.
> +	 *

"it may already"? You describe above that we shouldn't pass shmbridge
memory, and the other case never deals with shmbridges. So, I think you
can omit this part.

> +	 * If we pass a buffer that is already part of an SHM Bridge to this
> +	 * call, it will fail.

Could this be because the consumer of this buffer operates in EL2, and
not TZ?

Regards,
Bjorn

>  	 */
>  	mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
>  				       GFP_KERNEL);
> -- 
> 2.40.1
> 


From aford173 at gmail.com  Sat Feb 17 20:16:38 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 17 Feb 2024 22:16:38 -0600
Subject: [PATCH V5 0/6] soc: imx8mp: Finish support for HDMI
Message-ID: <20240218041649.1209173-1-aford173@gmail.com>

The i.MX8M Plus has an HDMI controller, which depends on several
other systems.  The Parallel Video Interface (PVI) and the
HDMI-TX are already in the Linux-Next staging area 20240209, but
the HDMI PHY driver and several device trees updates are still needed.

This series is adapted from multiple series from Lucas Stach with
edits and suggestions from feedback from various attemps, but it
since it's difficult to use and test them independently,
I merged them into on unified series.  The version history is a
bit ambiguous since different components were submitted at different
times and had different amount of attempts. 

The previous attempt I did used the wrong starting point for the PHY,
so this update includes a newer starting point with tags from that version
and fixes from various people's feedback.  I hope I caught them all, but
I apologize if I missed something. Any tags from the previous attempt I
made were intentionally dropped, because of the significant change,
but I kept tags from the newer version I grabbed from patchwork.

Because several items from the last attempt were merged, this
series is only focussed on adding the HDMI PHY driver, and enabling
the power domain, irqsteer interrupt controller, and HDMI pipeline
in the device tree. The version numbers are a bit strange since
these all got pulled from various attempts with different versions,
but I wanted to push them together as a series to complete the pending
work.

This series restarted at V4 based on the version of the PHY driver and
the other drivers and power-domain changes have been applied already.
 

V5 primarily updates feedback from the PHY driver itself, but a small
   adjustment was made to the register size in the device tree. 
Adam Ford (1):
  arm64: defconfig: Enable DRM_IMX8MP_DW_HDMI_BRIDGE as module

Lucas Stach (5):
  dt-bindings: phy: add binding for the i.MX8MP HDMI PHY
  phy: freescale: add Samsung HDMI PHY
  arm64: dts: imx8mp: add HDMI power-domains
  arm64: dts: imx8mp: add HDMI irqsteer
  arm64: dts: imx8mp: add HDMI display pipeline

 .../bindings/phy/fsl,imx8mp-hdmi-phy.yaml     |  62 ++
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     | 145 ++++
 arch/arm64/configs/defconfig                  |   1 +
 drivers/phy/freescale/Kconfig                 |   6 +
 drivers/phy/freescale/Makefile                |   1 +
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c  | 720 ++++++++++++++++++
 6 files changed, 935 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml
 create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c

-- 
2.43.0



From aford173 at gmail.com  Sat Feb 17 20:16:39 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 17 Feb 2024 22:16:39 -0600
Subject: [PATCH V5 1/6] dt-bindings: phy: add binding for the i.MX8MP HDMI PHY
In-Reply-To: <20240218041649.1209173-1-aford173@gmail.com>
References: <20240218041649.1209173-1-aford173@gmail.com>
Message-ID: <20240218041649.1209173-2-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

Add a DT binding for the HDMI PHY found on the i.MX8MP SoC.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
---
V5:  No Change

V4:  No Change

V3:  Removed mintems at the request of Krzysztof and add his
     reviewed-by

V2:  I (Adam) tried to help move this along, so I took Lucas' patch
     and attempted to apply fixes based on feedback.  I don't have
     all the history, so apologies for that.

     Added phy-cells to the required list and fixed an error due
     to the word 'binding' being in the title.
---
 .../bindings/phy/fsl,imx8mp-hdmi-phy.yaml     | 62 +++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml
new file mode 100644
index 000000000000..c43e86a8c2e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,imx8mp-hdmi-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX8MP HDMI PHY
+
+maintainers:
+  - Lucas Stach <l.stach at pengutronix.de>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mp-hdmi-phy
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 0
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: apb
+      - const: ref
+
+  "#phy-cells":
+    const: 0
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - "#phy-cells"
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mp-clock.h>
+    #include <dt-bindings/power/imx8mp-power.h>
+
+    phy at 32fdff00 {
+        compatible = "fsl,imx8mp-hdmi-phy";
+        reg = <0x32fdff00 0x100>;
+        clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+                 <&clk IMX8MP_CLK_HDMI_24M>;
+        clock-names = "apb", "ref";
+        power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>;
+        #clock-cells = <0>;
+        #phy-cells = <0>;
+    };
-- 
2.43.0



From aford173 at gmail.com  Sat Feb 17 20:16:40 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 17 Feb 2024 22:16:40 -0600
Subject: [PATCH V5 2/6] phy: freescale: add Samsung HDMI PHY
In-Reply-To: <20240218041649.1209173-1-aford173@gmail.com>
References: <20240218041649.1209173-1-aford173@gmail.com>
Message-ID: <20240218041649.1209173-3-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the driver for the Samsung HDMI PHY found on the
i.MX8MP SoC. Based on downstream implementation from
Sandor Yu <Sandor.yu at nxp.com>.  According to the TRM, the PHY
receives parallel data from the link and serializes it.  It
also sets the PLL clock needed for the TX serializer.

Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com> (v2)
Tested-by: Richard Leitner <richard.leitner at skidata.com> (v2)
Co-developed-by: Marco Felsch <m.felsch at pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Frieder Schrempf <frieder.schrempf at kontron.de> # Kontron BL
Signed-off-by: Adam Ford <aford173 at gmail.com>
Tested-by: Marek Vasut <marex at denx.de>
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
---
V5:  Remove an unnecessary include
     Migrate from of_clk_add_provider to of_clk_add_hw_provider
     Make const structures static
     Fix uninitialized variables and prevent div by 0
     Mark PM functions as __maybe_unused

V4:
- I (Adam) added a comment in the code for clarifcation
  based on questions from Luca concerning a difference
  between the code and the ref manual.
- Fixed the GENMASK on REG14
- Expanded the commit message briefly describing
  a bit more of what this driver does.
- Removed some unnecessary include files.

v3:
- use GENMASK/FIELD_PREP
- lowercase hex values
- correct coding style
v2:
- use DEFINE_RUNTIME_DEV_PM_OPS
---
 drivers/phy/freescale/Kconfig                |   6 +
 drivers/phy/freescale/Makefile               |   1 +
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 720 +++++++++++++++++++
 3 files changed, 727 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index 853958fb2c06..5c2b73042dfc 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -35,6 +35,12 @@ config PHY_FSL_IMX8M_PCIE
 	  Enable this to add support for the PCIE PHY as found on
 	  i.MX8M family of SOCs.
 
+config PHY_FSL_SAMSUNG_HDMI_PHY
+	tristate "Samsung HDMI PHY support"
+	depends on OF && HAS_IOMEM
+	help
+	  Enable this to add support for the Samsung HDMI PHY in i.MX8MP.
+
 endif
 
 config PHY_FSL_LYNX_28G
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index cedb328bc4d2..c4386bfdb853 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
 obj-$(CONFIG_PHY_FSL_IMX8M_PCIE)	+= phy-fsl-imx8m-pcie.o
 obj-$(CONFIG_PHY_FSL_LYNX_28G)		+= phy-fsl-lynx-28g.o
+obj-$(CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY)	+= phy-fsl-samsung-hdmi.o
diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
new file mode 100644
index 000000000000..89e2c01f2ccf
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -0,0 +1,720 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 NXP
+ * Copyright 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#define PHY_REG_00		0x00
+#define PHY_REG_01		0x04
+#define PHY_REG_02		0x08
+#define PHY_REG_08		0x20
+#define PHY_REG_09		0x24
+#define PHY_REG_10		0x28
+#define PHY_REG_11		0x2c
+
+#define PHY_REG_12		0x30
+#define  REG12_CK_DIV_MASK	GENMASK(5, 4)
+
+#define PHY_REG_13		0x34
+#define  REG13_TG_CODE_LOW_MASK	GENMASK(7, 0)
+
+#define PHY_REG_14		0x38
+#define  REG14_TOL_MASK		GENMASK(7, 4)
+#define  REG14_RP_CODE_MASK	GENMASK(3, 1)
+#define  REG14_TG_CODE_HIGH_MASK	GENMASK(0, 0)
+
+#define PHY_REG_15		0x3c
+#define PHY_REG_16		0x40
+#define PHY_REG_17		0x44
+#define PHY_REG_18		0x48
+#define PHY_REG_19		0x4c
+#define PHY_REG_20		0x50
+
+#define PHY_REG_21		0x54
+#define  REG21_SEL_TX_CK_INV	BIT(7)
+#define  REG21_PMS_S_MASK	GENMASK(3, 0)
+
+#define PHY_REG_22		0x58
+#define PHY_REG_23		0x5c
+#define PHY_REG_24		0x60
+#define PHY_REG_25		0x64
+#define PHY_REG_26		0x68
+#define PHY_REG_27		0x6c
+#define PHY_REG_28		0x70
+#define PHY_REG_29		0x74
+#define PHY_REG_30		0x78
+#define PHY_REG_31		0x7c
+#define PHY_REG_32		0x80
+
+/*
+ * REG33 does not match the ref manual. According to Sandor Yu from NXP,
+ * "There is a doc issue on the i.MX8MP latest RM"
+ * REG33 is being used per guidance from Sandor
+ */
+
+#define PHY_REG_33		0x84
+#define  REG33_MODE_SET_DONE	BIT(7)
+#define  REG33_FIX_DA		BIT(1)
+
+#define PHY_REG_34		0x88
+#define  REG34_PHY_READY	BIT(7)
+#define  REG34_PLL_LOCK		BIT(6)
+#define  REG34_PHY_CLK_READY	BIT(5)
+
+#define PHY_REG_35		0x8c
+#define PHY_REG_36		0x90
+#define PHY_REG_37		0x94
+#define PHY_REG_38		0x98
+#define PHY_REG_39		0x9c
+#define PHY_REG_40		0xa0
+#define PHY_REG_41		0xa4
+#define PHY_REG_42		0xa8
+#define PHY_REG_43		0xac
+#define PHY_REG_44		0xb0
+#define PHY_REG_45		0xb4
+#define PHY_REG_46		0xb8
+#define PHY_REG_47		0xbc
+
+#define PHY_PLL_DIV_REGS_NUM 6
+
+struct phy_config {
+	u32	pixclk;
+	u8	pll_div_regs[PHY_PLL_DIV_REGS_NUM];
+};
+
+static const struct phy_config phy_pll_cfg[] = {
+	{
+		.pixclk = 22250000,
+		.pll_div_regs = { 0x4b, 0xf1, 0x89, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 23750000,
+		.pll_div_regs = { 0x50, 0xf1, 0x86, 0x85, 0x80, 0x40 },
+	}, {
+		.pixclk = 24000000,
+		.pll_div_regs = { 0x50, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 24024000,
+		.pll_div_regs = { 0x50, 0xf1, 0x99, 0x02, 0x80, 0x40 },
+	}, {
+		.pixclk = 25175000,
+		.pll_div_regs = { 0x54, 0xfc, 0xcc, 0x91, 0x80, 0x40 },
+	}, {
+		.pixclk = 25200000,
+		.pll_div_regs = { 0x54, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 26750000,
+		.pll_div_regs = { 0x5a, 0xf2, 0x89, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 27000000,
+		.pll_div_regs = { 0x5a, 0xf0, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 27027000,
+		.pll_div_regs = { 0x5a, 0xf2, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 29500000,
+		.pll_div_regs = { 0x62, 0xf4, 0x95, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 30750000,
+		.pll_div_regs = { 0x66, 0xf4, 0x82, 0x01, 0x88, 0x45 },
+	}, {
+		.pixclk = 30888000,
+		.pll_div_regs = { 0x66, 0xf4, 0x99, 0x18, 0x88, 0x45 },
+	}, {
+		.pixclk = 33750000,
+		.pll_div_regs = { 0x70, 0xf4, 0x82, 0x01, 0x80, 0x40 },
+	}, {
+		.pixclk = 35000000,
+		.pll_div_regs = { 0x58, 0xb8, 0x8b, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 36000000,
+		.pll_div_regs = { 0x5a, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 36036000,
+		.pll_div_regs = { 0x5a, 0xb2, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 40000000,
+		.pll_div_regs = { 0x64, 0xb0, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 43200000,
+		.pll_div_regs = { 0x5a, 0x90, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 43243200,
+		.pll_div_regs = { 0x5a, 0x92, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 44500000,
+		.pll_div_regs = { 0x5c, 0x92, 0x98, 0x11, 0x84, 0x41 },
+	}, {
+		.pixclk = 47000000,
+		.pll_div_regs = { 0x62, 0x94, 0x95, 0x82, 0x80, 0x40 },
+	}, {
+		.pixclk = 47500000,
+		.pll_div_regs = { 0x63, 0x96, 0xa1, 0x82, 0x80, 0x40 },
+	}, {
+		.pixclk = 50349650,
+		.pll_div_regs = { 0x54, 0x7c, 0xc3, 0x8f, 0x80, 0x40 },
+	}, {
+		.pixclk = 50400000,
+		.pll_div_regs = { 0x54, 0x70, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 53250000,
+		.pll_div_regs = { 0x58, 0x72, 0x84, 0x03, 0x82, 0x41 },
+	}, {
+		.pixclk = 53500000,
+		.pll_div_regs = { 0x5a, 0x72, 0x89, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 54000000,
+		.pll_div_regs = { 0x5a, 0x70, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 54054000,
+		.pll_div_regs = { 0x5a, 0x72, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 59000000,
+		.pll_div_regs = { 0x62, 0x74, 0x95, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 59340659,
+		.pll_div_regs = { 0x62, 0x74, 0xdb, 0x52, 0x88, 0x47 },
+	}, {
+		.pixclk = 59400000,
+		.pll_div_regs = { 0x63, 0x70, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 61500000,
+		.pll_div_regs = { 0x66, 0x74, 0x82, 0x01, 0x88, 0x45 },
+	}, {
+		.pixclk = 63500000,
+		.pll_div_regs = { 0x69, 0x74, 0x89, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 67500000,
+		.pll_div_regs = { 0x54, 0x52, 0x87, 0x03, 0x80, 0x40 },
+	}, {
+		.pixclk = 70000000,
+		.pll_div_regs = { 0x58, 0x58, 0x8b, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 72000000,
+		.pll_div_regs = { 0x5a, 0x50, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 72072000,
+		.pll_div_regs = { 0x5a, 0x52, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 74176000,
+		.pll_div_regs = { 0x5d, 0x58, 0xdb, 0xA2, 0x88, 0x41 },
+	}, {
+		.pixclk = 74250000,
+		.pll_div_regs = { 0x5c, 0x52, 0x90, 0x0d, 0x84, 0x41 },
+	}, {
+		.pixclk = 78500000,
+		.pll_div_regs = { 0x62, 0x54, 0x87, 0x01, 0x80, 0x40 },
+	}, {
+		.pixclk = 80000000,
+		.pll_div_regs = { 0x64, 0x50, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 82000000,
+		.pll_div_regs = { 0x66, 0x54, 0x82, 0x01, 0x88, 0x45 },
+	}, {
+		.pixclk = 82500000,
+		.pll_div_regs = { 0x67, 0x54, 0x88, 0x01, 0x90, 0x49 },
+	}, {
+		.pixclk = 89000000,
+		.pll_div_regs = { 0x70, 0x54, 0x84, 0x83, 0x80, 0x40 },
+	}, {
+		.pixclk = 90000000,
+		.pll_div_regs = { 0x70, 0x54, 0x82, 0x01, 0x80, 0x40 },
+	}, {
+		.pixclk = 94000000,
+		.pll_div_regs = { 0x4e, 0x32, 0xa7, 0x10, 0x80, 0x40 },
+	}, {
+		.pixclk = 95000000,
+		.pll_div_regs = { 0x50, 0x31, 0x86, 0x85, 0x80, 0x40 },
+	}, {
+		.pixclk = 98901099,
+		.pll_div_regs = { 0x52, 0x3a, 0xdb, 0x4c, 0x88, 0x47 },
+	}, {
+		.pixclk = 99000000,
+		.pll_div_regs = { 0x52, 0x32, 0x82, 0x01, 0x88, 0x47 },
+	}, {
+		.pixclk = 100699300,
+		.pll_div_regs = { 0x54, 0x3c, 0xc3, 0x8f, 0x80, 0x40 },
+	}, {
+		.pixclk = 100800000,
+		.pll_div_regs = { 0x54, 0x30, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 102500000,
+		.pll_div_regs = { 0x55, 0x32, 0x8c, 0x05, 0x90, 0x4b },
+	}, {
+		.pixclk = 104750000,
+		.pll_div_regs = { 0x57, 0x32, 0x98, 0x07, 0x90, 0x49 },
+	}, {
+		.pixclk = 106500000,
+		.pll_div_regs = { 0x58, 0x32, 0x84, 0x03, 0x82, 0x41 },
+	}, {
+		.pixclk = 107000000,
+		.pll_div_regs = { 0x5a, 0x32, 0x89, 0x88, 0x80, 0x40 },
+	}, {
+		.pixclk = 108000000,
+		.pll_div_regs = { 0x5a, 0x30, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 108108000,
+		.pll_div_regs = { 0x5a, 0x32, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 118000000,
+		.pll_div_regs = { 0x62, 0x34, 0x95, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 118800000,
+		.pll_div_regs = { 0x63, 0x30, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 123000000,
+		.pll_div_regs = { 0x66, 0x34, 0x82, 0x01, 0x88, 0x45 },
+	}, {
+		.pixclk = 127000000,
+		.pll_div_regs = { 0x69, 0x34, 0x89, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 135000000,
+		.pll_div_regs = { 0x70, 0x34, 0x82, 0x01, 0x80, 0x40 },
+	}, {
+		.pixclk = 135580000,
+		.pll_div_regs = { 0x71, 0x39, 0xe9, 0x82, 0x9c, 0x5b },
+	}, {
+		.pixclk = 137520000,
+		.pll_div_regs = { 0x72, 0x38, 0x99, 0x10, 0x85, 0x41 },
+	}, {
+		.pixclk = 138750000,
+		.pll_div_regs = { 0x73, 0x35, 0x88, 0x05, 0x90, 0x4d },
+	}, {
+		.pixclk = 140000000,
+		.pll_div_regs = { 0x75, 0x36, 0xa7, 0x90, 0x80, 0x40 },
+	}, {
+		.pixclk = 144000000,
+		.pll_div_regs = { 0x78, 0x30, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 148352000,
+		.pll_div_regs = { 0x7b, 0x35, 0xdb, 0x39, 0x90, 0x45 },
+	}, {
+		.pixclk = 148500000,
+		.pll_div_regs = { 0x7b, 0x35, 0x84, 0x03, 0x90, 0x45 },
+	}, {
+		.pixclk = 154000000,
+		.pll_div_regs = { 0x40, 0x18, 0x83, 0x01, 0x00, 0x40 },
+	}, {
+		.pixclk = 157000000,
+		.pll_div_regs = { 0x41, 0x11, 0xa7, 0x14, 0x80, 0x40 },
+	}, {
+		.pixclk = 160000000,
+		.pll_div_regs = { 0x42, 0x12, 0xa1, 0x20, 0x80, 0x40 },
+	}, {
+		.pixclk = 162000000,
+		.pll_div_regs = { 0x43, 0x18, 0x8b, 0x08, 0x96, 0x55 },
+	}, {
+		.pixclk = 164000000,
+		.pll_div_regs = { 0x45, 0x11, 0x83, 0x82, 0x90, 0x4b },
+	}, {
+		.pixclk = 165000000,
+		.pll_div_regs = { 0x45, 0x11, 0x84, 0x81, 0x90, 0x4b },
+	}, {
+		.pixclk = 180000000,
+		.pll_div_regs = { 0x4b, 0x10, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 185625000,
+		.pll_div_regs = { 0x4e, 0x12, 0x9a, 0x95, 0x80, 0x40 },
+	}, {
+		.pixclk = 188000000,
+		.pll_div_regs = { 0x4e, 0x12, 0xa7, 0x10, 0x80, 0x40 },
+	}, {
+		.pixclk = 198000000,
+		.pll_div_regs = { 0x52, 0x12, 0x82, 0x01, 0x88, 0x47 },
+	}, {
+		.pixclk = 205000000,
+		.pll_div_regs = { 0x55, 0x12, 0x8c, 0x05, 0x90, 0x4b },
+	}, {
+		.pixclk = 209500000,
+		.pll_div_regs = { 0x57, 0x12, 0x98, 0x07, 0x90, 0x49 },
+	}, {
+		.pixclk = 213000000,
+		.pll_div_regs = { 0x58, 0x12, 0x84, 0x03, 0x82, 0x41 },
+	}, {
+		.pixclk = 216000000,
+		.pll_div_regs = { 0x5a, 0x10, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 216216000,
+		.pll_div_regs = { 0x5a, 0x12, 0xfd, 0x0c, 0x80, 0x40 },
+	}, {
+		.pixclk = 237600000,
+		.pll_div_regs = { 0x63, 0x10, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 254000000,
+		.pll_div_regs = { 0x69, 0x14, 0x89, 0x08, 0x80, 0x40 },
+	}, {
+		.pixclk = 277500000,
+		.pll_div_regs = { 0x73, 0x15, 0x88, 0x05, 0x90, 0x4d },
+	}, {
+		.pixclk = 288000000,
+		.pll_div_regs = { 0x78, 0x10, 0x00, 0x00, 0x80, 0x00 },
+	}, {
+		.pixclk = 297000000,
+		.pll_div_regs = { 0x7b, 0x15, 0x84, 0x03, 0x90, 0x45 },
+	},
+};
+
+struct reg_settings {
+	u8 reg;
+	u8 val;
+};
+
+static const struct reg_settings common_phy_cfg[] = {
+	{ PHY_REG_00, 0x00 }, { PHY_REG_01, 0xd1 },
+	{ PHY_REG_08, 0x4f }, { PHY_REG_09, 0x30 },
+	{ PHY_REG_10, 0x33 }, { PHY_REG_11, 0x65 },
+	/* REG12 pixclk specific */
+	/* REG13 pixclk specific */
+	/* REG14 pixclk specific */
+	{ PHY_REG_15, 0x80 }, { PHY_REG_16, 0x6c },
+	{ PHY_REG_17, 0xf2 }, { PHY_REG_18, 0x67 },
+	{ PHY_REG_19, 0x00 }, { PHY_REG_20, 0x10 },
+	/* REG21 pixclk specific */
+	{ PHY_REG_22, 0x30 }, { PHY_REG_23, 0x32 },
+	{ PHY_REG_24, 0x60 }, { PHY_REG_25, 0x8f },
+	{ PHY_REG_26, 0x00 }, { PHY_REG_27, 0x00 },
+	{ PHY_REG_28, 0x08 }, { PHY_REG_29, 0x00 },
+	{ PHY_REG_30, 0x00 }, { PHY_REG_31, 0x00 },
+	{ PHY_REG_32, 0x00 }, { PHY_REG_33, 0x80 },
+	{ PHY_REG_34, 0x00 }, { PHY_REG_35, 0x00 },
+	{ PHY_REG_36, 0x00 }, { PHY_REG_37, 0x00 },
+	{ PHY_REG_38, 0x00 }, { PHY_REG_39, 0x00 },
+	{ PHY_REG_40, 0x00 }, { PHY_REG_41, 0xe0 },
+	{ PHY_REG_42, 0x83 }, { PHY_REG_43, 0x0f },
+	{ PHY_REG_44, 0x3E }, { PHY_REG_45, 0xf8 },
+	{ PHY_REG_46, 0x00 }, { PHY_REG_47, 0x00 }
+};
+
+struct fsl_samsung_hdmi_phy {
+	struct device *dev;
+	void __iomem *regs;
+	struct clk *apbclk;
+	struct clk *refclk;
+
+	/* clk provider */
+	struct clk_hw hw;
+	const struct phy_config *cur_cfg;
+};
+
+static inline struct fsl_samsung_hdmi_phy *
+to_fsl_samsung_hdmi_phy(struct clk_hw *hw)
+{
+	return container_of(hw, struct fsl_samsung_hdmi_phy, hw);
+}
+
+static void
+fsl_samsung_hdmi_phy_configure_pixclk(struct fsl_samsung_hdmi_phy *phy,
+				      const struct phy_config *cfg)
+{
+	u8 div = 0x1;
+
+	switch (cfg->pixclk) {
+	case  22250000 ...  33750000:
+		div = 0xf;
+		break;
+	case  35000000 ...  40000000:
+		div = 0xb;
+		break;
+	case  43200000 ...  47500000:
+		div = 0x9;
+		break;
+	case  50349650 ...  63500000:
+		div = 0x7;
+		break;
+	case  67500000 ...  90000000:
+		div = 0x5;
+		break;
+	case  94000000 ... 148500000:
+		div = 0x3;
+		break;
+	case 154000000 ... 297000000:
+		div = 0x1;
+		break;
+	}
+
+	writeb(REG21_SEL_TX_CK_INV | FIELD_PREP(REG21_PMS_S_MASK, div),
+	       phy->regs + PHY_REG_21);
+}
+
+static void
+fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
+					    const struct phy_config *cfg)
+{
+	u32 pclk = cfg->pixclk;
+	u32 fld_tg_code;
+	u32 pclk_khz;
+	u8 div = 1;
+
+	switch (cfg->pixclk) {
+	case  22250000 ...  47500000:
+		div = 1;
+		break;
+	case  50349650 ...  99000000:
+		div = 2;
+		break;
+	case 100699300 ... 198000000:
+		div = 4;
+		break;
+	case 205000000 ... 297000000:
+		div = 8;
+		break;
+	}
+
+	writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG_12);
+
+	/*
+	 * Calculation for the frequency lock detector target code (fld_tg_code)
+	 * is based on reference manual register description of PHY_REG13
+	 * (13.10.3.1.14.2):
+	 *   1st) Calculate int_pllclk which is determinded by FLD_CK_DIV
+	 *   2nd) Increase resolution to avoid rounding issues
+	 *   3th) Do the div (256 / Freq. of int_pllclk) * 24
+	 *   4th) Reduce the resolution and always round up since the NXP
+	 *        settings rounding up always too. TODO: Check if that is
+	 *        correct.
+	 */
+	pclk /= div;
+	pclk_khz = pclk / 1000;
+	fld_tg_code = 256 * 1000 * 1000 / pclk_khz * 24;
+	fld_tg_code = DIV_ROUND_UP(fld_tg_code, 1000);
+
+	/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
+	writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
+	       phy->regs + PHY_REG_13);
+	writeb(FIELD_PREP(REG14_TOL_MASK, 2) |
+	       FIELD_PREP(REG14_RP_CODE_MASK, 2) |
+	       FIELD_PREP(REG14_TG_CODE_HIGH_MASK, fld_tg_code >> 8),
+	       phy->regs + PHY_REG_14);
+}
+
+static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
+					  const struct phy_config *cfg)
+{
+	int i, ret;
+	u8 val;
+
+	/* HDMI PHY init */
+	writeb(REG33_FIX_DA, phy->regs + PHY_REG_33);
+
+	/* common PHY registers */
+	for (i = 0; i < ARRAY_SIZE(common_phy_cfg); i++)
+		writeb(common_phy_cfg[i].val, phy->regs + common_phy_cfg[i].reg);
+
+	/* set individual PLL registers PHY_REG2 ... PHY_REG7 */
+	for (i = 0; i < PHY_PLL_DIV_REGS_NUM; i++)
+		writeb(cfg->pll_div_regs[i], phy->regs + PHY_REG_02 + i * 4);
+
+	fsl_samsung_hdmi_phy_configure_pixclk(phy, cfg);
+	fsl_samsung_hdmi_phy_configure_pll_lock_det(phy, cfg);
+
+	writeb(REG33_FIX_DA | REG33_MODE_SET_DONE, phy->regs + PHY_REG_33);
+
+	ret = readb_poll_timeout(phy->regs + PHY_REG_34, val,
+				 val & REG34_PLL_LOCK, 50, 20000);
+	if (ret)
+		dev_err(phy->dev, "PLL failed to lock\n");
+
+	return ret;
+}
+
+static unsigned long phy_clk_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
+
+	if (!phy->cur_cfg)
+		return 74250000;
+
+	return phy->cur_cfg->pixclk;
+}
+
+static long phy_clk_round_rate(struct clk_hw *hw,
+			       unsigned long rate, unsigned long *parent_rate)
+{
+	int i;
+
+	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
+		if (phy_pll_cfg[i].pixclk <= rate)
+			return phy_pll_cfg[i].pixclk;
+
+	return -EINVAL;
+}
+
+static int phy_clk_set_rate(struct clk_hw *hw,
+			    unsigned long rate, unsigned long parent_rate)
+{
+	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
+	int i;
+
+	for (i = ARRAY_SIZE(phy_pll_cfg) - 1; i >= 0; i--)
+		if (phy_pll_cfg[i].pixclk <= rate)
+			break;
+
+	if (i < 0)
+		return -EINVAL;
+
+	phy->cur_cfg = &phy_pll_cfg[i];
+
+	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+}
+
+static const struct clk_ops phy_clk_ops = {
+	.recalc_rate = phy_clk_recalc_rate,
+	.round_rate = phy_clk_round_rate,
+	.set_rate = phy_clk_set_rate,
+};
+
+static int phy_clk_register(struct fsl_samsung_hdmi_phy *phy)
+{
+	struct device *dev = phy->dev;
+	struct device_node *np = dev->of_node;
+	struct clk_init_data init;
+	const char *parent_name;
+	struct clk *phyclk;
+	int ret;
+
+	parent_name = __clk_get_name(phy->refclk);
+
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	init.flags = 0;
+	init.name = "hdmi_pclk";
+	init.ops = &phy_clk_ops;
+
+	phy->hw.init = &init;
+
+	phyclk = devm_clk_register(dev, &phy->hw);
+	if (IS_ERR(phyclk))
+		return dev_err_probe(dev, PTR_ERR(phyclk),
+				     "failed to register clock\n");
+
+	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, phyclk);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to register clock provider\n");
+
+	return 0;
+}
+
+static int fsl_samsung_hdmi_phy_probe(struct platform_device *pdev)
+{
+	struct fsl_samsung_hdmi_phy *phy;
+	int ret;
+
+	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, phy);
+	phy->dev = &pdev->dev;
+
+	phy->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->regs))
+		return PTR_ERR(phy->regs);
+
+	phy->apbclk = devm_clk_get(phy->dev, "apb");
+	if (IS_ERR(phy->apbclk))
+		return dev_err_probe(phy->dev, PTR_ERR(phy->apbclk),
+				     "failed to get apb clk\n");
+
+	phy->refclk = devm_clk_get(phy->dev, "ref");
+	if (IS_ERR(phy->refclk))
+		return dev_err_probe(phy->dev, PTR_ERR(phy->refclk),
+				     "failed to get ref clk\n");
+
+	ret = clk_prepare_enable(phy->apbclk);
+	if (ret) {
+		dev_err(phy->dev, "failed to enable apbclk\n");
+		return ret;
+	}
+
+	pm_runtime_get_noresume(phy->dev);
+	pm_runtime_set_active(phy->dev);
+	pm_runtime_enable(phy->dev);
+
+	ret = phy_clk_register(phy);
+	if (ret) {
+		dev_err(&pdev->dev, "register clk failed\n");
+		goto register_clk_failed;
+	}
+
+	pm_runtime_put(phy->dev);
+
+	return 0;
+
+register_clk_failed:
+	clk_disable_unprepare(phy->apbclk);
+
+	return ret;
+}
+
+static int fsl_samsung_hdmi_phy_remove(struct platform_device *pdev)
+{
+	of_clk_del_provider(pdev->dev.of_node);
+
+	return 0;
+}
+
+static int __maybe_unused fsl_samsung_hdmi_phy_suspend(struct device *dev)
+{
+	struct fsl_samsung_hdmi_phy *phy = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(phy->apbclk);
+
+	return 0;
+}
+
+static int __maybe_unused fsl_samsung_hdmi_phy_resume(struct device *dev)
+{
+	struct fsl_samsung_hdmi_phy *phy = dev_get_drvdata(dev);
+	int ret = 0;
+
+	ret = clk_prepare_enable(phy->apbclk);
+	if (ret) {
+		dev_err(phy->dev, "failed to enable apbclk\n");
+		return ret;
+	}
+
+	if (phy->cur_cfg)
+		ret = fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+
+	return ret;
+
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(fsl_samsung_hdmi_phy_pm_ops,
+				 fsl_samsung_hdmi_phy_suspend,
+				 fsl_samsung_hdmi_phy_resume, NULL);
+
+static const struct of_device_id fsl_samsung_hdmi_phy_of_match[] = {
+	{
+		.compatible = "fsl,imx8mp-hdmi-phy",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, fsl_samsung_hdmi_phy_of_match);
+
+static struct platform_driver fsl_samsung_hdmi_phy_driver = {
+	.probe  = fsl_samsung_hdmi_phy_probe,
+	.remove = fsl_samsung_hdmi_phy_remove,
+	.driver = {
+		.name = "fsl-samsung-hdmi-phy",
+		.of_match_table = fsl_samsung_hdmi_phy_of_match,
+		.pm = pm_ptr(&fsl_samsung_hdmi_phy_pm_ops),
+	},
+};
+module_platform_driver(fsl_samsung_hdmi_phy_driver);
+
+MODULE_AUTHOR("Sandor Yu <Sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("SAMSUNG HDMI 2.0 Transmitter PHY Driver");
+MODULE_LICENSE("GPL");
-- 
2.43.0



From aford173 at gmail.com  Sat Feb 17 20:16:41 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 17 Feb 2024 22:16:41 -0600
Subject: [PATCH V5 3/6] arm64: dts: imx8mp: add HDMI power-domains
In-Reply-To: <20240218041649.1209173-1-aford173@gmail.com>
References: <20240218041649.1209173-1-aford173@gmail.com>
Message-ID: <20240218041649.1209173-4-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the PGC and HDMI blk-ctrl nodes providing power control for
HDMI subsystem peripherals.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Tested-by: Marek Vasut <marex at denx.de>
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
---
V5:  No Change

V4:  No Change

V3:  The hdmi_blk_ctrl was in the wrong place, so move it to AIPS4.
     power-domains@ fixed to read power-domain@

V2:  Add missing power-domains hdcp and hrv
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 38 +++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 9ab9c057f41e..0730d4cf9bc4 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -836,6 +836,23 @@ pgc_mediamix: power-domain at 10 {
 							 <&clk IMX8MP_CLK_MEDIA_APB_ROOT>;
 					};
 
+					pgc_hdmimix: power-domain at 14 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_HDMIMIX>;
+						clocks = <&clk IMX8MP_CLK_HDMI_ROOT>,
+							 <&clk IMX8MP_CLK_HDMI_APB>;
+						assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>,
+								  <&clk IMX8MP_CLK_HDMI_APB>;
+						assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>,
+									 <&clk IMX8MP_SYS_PLL1_133M>;
+						assigned-clock-rates = <500000000>, <133000000>;
+					};
+
+					pgc_hdmi_phy: power-domain at 15 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_HDMI_PHY>;
+					};
+
 					pgc_mipi_phy2: power-domain at 16 {
 						#power-domain-cells = <0>;
 						reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
@@ -1889,6 +1906,27 @@ hsio_blk_ctrl: blk-ctrl at 32f10000 {
 				#power-domain-cells = <1>;
 				#clock-cells = <0>;
 			};
+
+			hdmi_blk_ctrl: blk-ctrl at 32fc0000 {
+				compatible = "fsl,imx8mp-hdmi-blk-ctrl", "syscon";
+				reg = <0x32fc0000 0x1000>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_ROOT>,
+					 <&clk IMX8MP_CLK_HDMI_REF_266M>,
+					 <&clk IMX8MP_CLK_HDMI_24M>,
+					 <&clk IMX8MP_CLK_HDMI_FDCC_TST>;
+				clock-names = "apb", "axi", "ref_266m", "ref_24m", "fdcc";
+				power-domains = <&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmi_phy>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>;
+				power-domain-names = "bus", "irqsteer", "lcdif",
+						     "pai", "pvi", "trng",
+						     "hdmi-tx", "hdmi-tx-phy",
+						     "hdcp", "hrv";
+				#power-domain-cells = <1>;
+			};
 		};
 
 		pcie: pcie at 33800000 {
-- 
2.43.0



From aford173 at gmail.com  Sat Feb 17 20:16:42 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 17 Feb 2024 22:16:42 -0600
Subject: [PATCH V5 4/6] arm64: dts: imx8mp: add HDMI irqsteer
In-Reply-To: <20240218041649.1209173-1-aford173@gmail.com>
References: <20240218041649.1209173-1-aford173@gmail.com>
Message-ID: <20240218041649.1209173-5-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

The HDMI irqsteer is a secondary interrupt controller within the HDMI
subsystem that maps all HDMI peripheral IRQs into a single upstream
IRQ line.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>
Tested-by: Marek Vasut <marex at denx.de>
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
---
V5:  Increase size to 4KB to match the ref manual

V2:  Add my (Adam) s-o-b and re-order position under AIPS4
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 0730d4cf9bc4..cbb15ded4a74 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1927,6 +1927,19 @@ hdmi_blk_ctrl: blk-ctrl at 32fc0000 {
 						     "hdcp", "hrv";
 				#power-domain-cells = <1>;
 			};
+
+			irqsteer_hdmi: interrupt-controller at 32fc2000 {
+				compatible = "fsl,imx-irqsteer";
+				reg = <0x32fc2000 0x1000>;
+				interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				fsl,channel = <1>;
+				fsl,num-irqs = <64>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>;
+				clock-names = "ipg";
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>;
+			};
 		};
 
 		pcie: pcie at 33800000 {
-- 
2.43.0



From aford173 at gmail.com  Sat Feb 17 20:16:44 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 17 Feb 2024 22:16:44 -0600
Subject: [PATCH V5 6/6] arm64: defconfig: Enable DRM_IMX8MP_DW_HDMI_BRIDGE as module
In-Reply-To: <20240218041649.1209173-1-aford173@gmail.com>
References: <20240218041649.1209173-1-aford173@gmail.com>
Message-ID: <20240218041649.1209173-7-aford173@gmail.com>

The i.MX8M Plus has support for an HDMI transmitter.  The
video is genereated by lcdif3, routed to the hdmi parallel
video interface, then fed to a DW HDMI bridge to support
up to 4K video output.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
---
V5:  Added Review and tested-by from Luca
     No functional change since V1
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index b8adb28185ad..ccfd5e6f20eb 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -887,6 +887,7 @@ CONFIG_DRM_ANALOGIX_ANX7625=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_DRM_CDNS_MHDP8546=m
+CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE=m
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
 CONFIG_DRM_DW_HDMI_CEC=m
 CONFIG_DRM_IMX_DCSS=m
-- 
2.43.0



From aford173 at gmail.com  Sat Feb 17 20:16:43 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sat, 17 Feb 2024 22:16:43 -0600
Subject: [PATCH V5 5/6] arm64: dts: imx8mp: add HDMI display pipeline
In-Reply-To: <20240218041649.1209173-1-aford173@gmail.com>
References: <20240218041649.1209173-1-aford173@gmail.com>
Message-ID: <20240218041649.1209173-6-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the DT nodes for all the peripherals that make up the
HDMI display pipeline.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>
Tested-by: Marek Vasut <marex at denx.de>
Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
---
V5:  No change

V3:  Re-ordered the HDMI parts to properly come after irqstree_hdmi
     inside AIPS4.  Change size of LCDIF3 and PVI to match TRM sizes
     of 4KB.

V2:  I took this from Lucas' original submission with the following:
     Removed extra clock from HDMI-TX since it is now part of the
     power domain
     Added interrupt-parent to PVI
     Changed the name of the HDMI tranmitter to fsl,imx8mp-hdmi-tx
     Added ports to HDMI-tx
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 94 +++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index cbb15ded4a74..433ea4ae6a16 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1940,6 +1940,100 @@ irqsteer_hdmi: interrupt-controller at 32fc2000 {
 				clock-names = "ipg";
 				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>;
 			};
+
+			hdmi_pvi: display-bridge at 32fc4000 {
+				compatible = "fsl,imx8mp-hdmi-pvi";
+				reg = <0x32fc4000 0x1000>;
+				interrupt-parent = <&irqsteer_hdmi>;
+				interrupts = <12>;
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port at 0 {
+						reg = <0>;
+						pvi_from_lcdif3: endpoint {
+							remote-endpoint = <&lcdif3_to_pvi>;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+						pvi_to_hdmi_tx: endpoint {
+							remote-endpoint = <&hdmi_tx_from_pvi>;
+						};
+					};
+				};
+			};
+
+			lcdif3: display-controller at 32fc6000 {
+				compatible = "fsl,imx8mp-lcdif";
+				reg = <0x32fc6000 0x1000>;
+				interrupt-parent = <&irqsteer_hdmi>;
+				interrupts = <8>;
+				clocks = <&hdmi_tx_phy>,
+					 <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_ROOT>;
+				clock-names = "pix", "axi", "disp_axi";
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_LCDIF>;
+
+				port {
+					lcdif3_to_pvi: endpoint {
+						remote-endpoint = <&pvi_from_lcdif3>;
+					};
+				};
+			};
+
+			hdmi_tx: hdmi at 32fd8000 {
+				compatible = "fsl,imx8mp-hdmi-tx";
+				reg = <0x32fd8000 0x7eff>;
+				interrupt-parent = <&irqsteer_hdmi>;
+				interrupts = <0>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_REF_266M>,
+					 <&clk IMX8MP_CLK_32K>,
+					 <&hdmi_tx_phy>;
+				clock-names = "iahb", "isfr", "cec", "pix";
+				assigned-clocks = <&clk IMX8MP_CLK_HDMI_REF_266M>;
+				assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>;
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
+				reg-io-width = <1>;
+				status = "disabled";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port at 0 {
+						reg = <0>;
+
+						hdmi_tx_from_pvi: endpoint {
+							remote-endpoint = <&pvi_to_hdmi_tx>;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+						/* Point endpoint to the HDMI connector */
+					};
+				};
+			};
+
+			hdmi_tx_phy: phy at 32fdff00 {
+				compatible = "fsl,imx8mp-hdmi-phy";
+				reg = <0x32fdff00 0x100>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_24M>;
+				clock-names = "apb", "ref";
+				assigned-clocks = <&clk IMX8MP_CLK_HDMI_24M>;
+				assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
+				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>;
+				#clock-cells = <0>;
+				#phy-cells = <0>;
+				status = "disabled";
+			};
 		};
 
 		pcie: pcie at 33800000 {
-- 
2.43.0



From quic_kathirav at quicinc.com  Sat Feb 17 20:29:03 2024
From: quic_kathirav at quicinc.com (Kathiravan Thirumoorthy)
Date: Sun, 18 Feb 2024 09:59:03 +0530
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <CAA8EJppuNRB9fhjimg4SUR2PydX7-KLWSb9H-nC-oSMYVOME-Q@mail.gmail.com>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com>
 <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
 <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
 <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com>
 <CAA8EJppe6aNf2WJ5BvaX8SPTbuaEwzRm74F8QKyFtbmnGQt=1w@mail.gmail.com>
 <74f585c2-d220-4324-96eb-1a945fef9608@quicinc.com>
 <CAA8EJppuNRB9fhjimg4SUR2PydX7-KLWSb9H-nC-oSMYVOME-Q@mail.gmail.com>
Message-ID: <d518dbc1-41aa-46f9-b549-c95a33b06ee0@quicinc.com>



On 2/17/2024 10:15 PM, Dmitry Baryshkov wrote:
> On Sat, 17 Feb 2024 at 17:45, Kathiravan Thirumoorthy
> <quic_kathirav at quicinc.com> wrote:
>>
>>
>> <snip>
>>
>>>> Reason being, to access the NSSCC clocks, these GCC clocks
>>>> (gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk)
>>>> should be turned ON. But CCF disables these clocks as well due to the
>>>> lack of consumer.
>>>
>>> This means that NSSCC is also a consumer of those clocks. Please fix
>>> both DT and nsscc driver to handle NSSNOC clocks.
>>
>>
>> Thanks Dmitry. I shall include these clocks in the NSSCC DT node and
>> enable the same in the NSSCC driver probe.
> 
> Or use them through pm_clk. This might be better, as the system
> doesn't need these clocks if NSSCC is suspended.


IPQ53XX SoC doesn't support the PM(suspend / resume) functionality, so 
that, can I enable these clocks in NSSCC driver probe itself?


> 
>>
>>>
>>>>> Once you have actual drivers, this should solve itself, the drivers
>>>>> will consume the clocks.
>>>>
>>>>
>>>> Given that, NSSCC is being built as module, there is no issue in booting
>>>> the kernel. But if you do insmod of the nsscc-ipq5332.ko, system will
>>>> reset.
>>>>
>>>> Without the networking drivers, there is no need to install this module.
>>>> And as you stated, once the drivers are available, there will be no issues.
>>>>
>>>> So can I explain the shortcomings of installing this module without the
>>>> networking drivers in cover letter and drop this patch all together?
>>>
>>> No. Using allyesconfig or allmodconfig and installing the full modules
>>> set should work.
>>>
>>
>>
>> Okay, Got it. Thanks for the information.
>>
>> <snip>
> 
> 
> 


From niliqiang.io at gmail.com  Sat Feb 17 21:02:23 2024
From: niliqiang.io at gmail.com (ni.liqiang)
Date: Sun, 18 Feb 2024 13:02:23 +0800
Subject: [PATCH] drivers/iommu: Ensure that the queue base address is successfully written during SMMU initialization.
Message-ID: <20240218050224.33426-1-niliqiang.io@gmail.com>

In the system reboot test, I encountered an issue:
After the OS started, the base address of CMDQ failed to be written
successfully and remained at the default value of 0.

Through timing analysis of CMN, it was found that although
the write request for the CMDQ base precedes the write request
for CMDQEN, the write response for the CMDQ base might be later
than that for CMDQEN.

Upon reviewing the SMMU Architecture Specification,
I found the following explanation:
The registers must be initialized in this order:
1. Write SMMU_CMDQ_BASE to set the queue base and size.
2. Write initial values to SMMU_CMDQ_CONS and SMMU_CMDQ_PROD.
3. Enable the queue with an Update of the respective SMMU_CR0.CMDQEN to 1.

If there are no memory barriers, how can we ensure this order?
Therefore, I believe that adding a memory barrier before enabling CMDQ
is necessary to ensure that the base address of CMDQ is correctly written.

The base addresses of EVENTQ and PRIQ would also be subject
to the same situation.

Could you please review if this modification seems reasonable? Thank you.

Signed-off-by: ni.liqiang <niliqiang.io at gmail.com>
Reviewed-by: jin.qi <jin.qi at zte.com.cn>
Tested-by: ni.liqiang <niliqiang.io at gmail.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 +++++++++++++++
 1 file changed, 15 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 0ffb1cf17e0b..ac854c46fdf3 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3324,6 +3324,11 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 	writel_relaxed(smmu->cmdq.q.llq.prod, smmu->base + ARM_SMMU_CMDQ_PROD);
 	writel_relaxed(smmu->cmdq.q.llq.cons, smmu->base + ARM_SMMU_CMDQ_CONS);
 
+	/* Ensure that SMMU_CMDQ_BASE is written completely
+	 * when SMMU_CR0.CMDQEN == 0.
+	 */
+	__iomb();
+
 	enables = CR0_CMDQEN;
 	ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
 				      ARM_SMMU_CR0ACK);
@@ -3350,6 +3355,11 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 	writel_relaxed(smmu->evtq.q.llq.prod, smmu->page1 + ARM_SMMU_EVTQ_PROD);
 	writel_relaxed(smmu->evtq.q.llq.cons, smmu->page1 + ARM_SMMU_EVTQ_CONS);
 
+	/* Ensure that SMMU_EVENTQ_BASE is written completely
+	 * when SMMU_CR0.EVENTQEN == 0.
+	 */
+	__iomb();
+
 	enables |= CR0_EVTQEN;
 	ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
 				      ARM_SMMU_CR0ACK);
@@ -3367,6 +3377,11 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 		writel_relaxed(smmu->priq.q.llq.cons,
 			       smmu->page1 + ARM_SMMU_PRIQ_CONS);
 
+		/* Ensure that SMMU_PRIQ_BASE is written completely
+		 * when SMMU_CR0.PRIQEN == 0.
+		 */
+		__iomb();
+
 		enables |= CR0_PRIQEN;
 		ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
 					      ARM_SMMU_CR0ACK);
-- 
2.34.1



From peng.fan at oss.nxp.com  Sat Feb 17 22:38:50 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:38:50 +0800
Subject: [PATCH 0/3] arm64: dts: add i.MX95 and EVK board
Message-ID: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>

Add a minimal i.MX95 dtsi and EVK board dts.
i.MX95 has a M33 running SCMI firmware, but as of now, the scmi pinctrl
driver still not ready for i.MX95, so we count on bootloader to
configure the pinctrl for lpuart and sdhc and it boots well. After pinctrl
driver ready, we could move to use scmi pinctrl.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Peng Fan (3):
      dt-bindings: arm: fsl: add i.MX95 19x19 EVK board
      arm64: dts: freescale: add i.MX95 basic dtsi
      arm64: dts: freescale: add i.MX95 19x19 EVK minimal board dts

 Documentation/devicetree/bindings/arm/fsl.yaml    |    6 +
 arch/arm64/boot/dts/freescale/Makefile            |    1 +
 arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts |   88 ++
 arch/arm64/boot/dts/freescale/imx95-clock.h       |  187 ++++
 arch/arm64/boot/dts/freescale/imx95-power.h       |   55 +
 arch/arm64/boot/dts/freescale/imx95.dtsi          | 1215 +++++++++++++++++++++
 6 files changed, 1552 insertions(+)
---
base-commit: d37e1e4c52bc60578969f391fb81f947c3e83118
change-id: 20240218-imx95-dts-aae4316671a7

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Sat Feb 17 22:38:51 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:38:51 +0800
Subject: [PATCH 1/3] dt-bindings: arm: fsl: add i.MX95 19x19 EVK board
In-Reply-To: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>
References: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>
Message-ID: <20240218-imx95-dts-v1-1-2959f89f2018@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add DT compatible string for NXP i.MX95 19x19 EVK board.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 39378879777b..3b318c518e35 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -1264,6 +1264,12 @@ properties:
               - fsl,imx93-11x11-evk       # i.MX93 11x11 EVK Board
           - const: fsl,imx93
 
+      - description: i.MX95 based Boards
+        items:
+          - enum:
+              - fsl,imx95-19x19-evk       # i.MX95 19x19 EVK Board
+          - const: fsl,imx93
+
       - description: i.MXRT1050 based Boards
         items:
           - enum:

-- 
2.37.1



From peng.fan at oss.nxp.com  Sat Feb 17 22:38:52 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:38:52 +0800
Subject: [PATCH 2/3] arm64: dts: freescale: add i.MX95 basic dtsi
In-Reply-To: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>
References: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>
Message-ID: <20240218-imx95-dts-v1-2-2959f89f2018@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX95 features 6 A55 Cores, ARM Mali GPU, ISP, ML acceleration NPU,
and Edgelock secure enclave security. This patch is to add a minimal
dtsi, with cpu cores, coresight, scmi, gic, uart, mu, sdhc, lpi2c added.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx95-clock.h |  187 +++++
 arch/arm64/boot/dts/freescale/imx95-power.h |   55 ++
 arch/arm64/boot/dts/freescale/imx95.dtsi    | 1215 +++++++++++++++++++++++++++
 3 files changed, 1457 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95-clock.h b/arch/arm64/boot/dts/freescale/imx95-clock.h
new file mode 100644
index 000000000000..939655f0414e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-clock.h
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX95_H
+#define __DT_BINDINGS_CLOCK_IMX95_H
+
+/* The index should match i.MX95 SCMI Firmware */
+#define IMX95_CLK_32K                       1
+#define IMX95_CLK_24M                       2
+#define IMX95_CLK_FRO                       3
+#define IMX95_CLK_SYSPLL1_VCO               4
+#define IMX95_CLK_SYSPLL1_PFD0_UNGATED      5
+#define IMX95_CLK_SYSPLL1_PFD0              6
+#define IMX95_CLK_SYSPLL1_PFD0_DIV2         7
+#define IMX95_CLK_SYSPLL1_PFD1_UNGATED      8
+#define IMX95_CLK_SYSPLL1_PFD1              9
+#define IMX95_CLK_SYSPLL1_PFD1_DIV2         10
+#define IMX95_CLK_SYSPLL1_PFD2_UNGATED      11
+#define IMX95_CLK_SYSPLL1_PFD2              12
+#define IMX95_CLK_SYSPLL1_PFD2_DIV2         13
+#define IMX95_CLK_AUDIOPLL1_VCO             14
+#define IMX95_CLK_AUDIOPLL1                 15
+#define IMX95_CLK_AUDIOPLL2_VCO             16
+#define IMX95_CLK_AUDIOPLL2                 17
+#define IMX95_CLK_VIDEOPLL1_VCO             18
+#define IMX95_CLK_VIDEOPLL1                 19
+#define IMX95_CLK_RESERVED20                20
+#define IMX95_CLK_RESERVED21                21
+#define IMX95_CLK_RESERVED22                22
+#define IMX95_CLK_RESERVED23                23
+#define IMX95_CLK_ARMPLL_VCO                24
+#define IMX95_CLK_ARMPLL_PFD0_UNGATED       25
+#define IMX95_CLK_ARMPLL_PFD0               26
+#define IMX95_CLK_ARMPLL_PFD1_UNGATED       27
+#define IMX95_CLK_ARMPLL_PFD1               28
+#define IMX95_CLK_ARMPLL_PFD2_UNGATED       29
+#define IMX95_CLK_ARMPLL_PFD2               30
+#define IMX95_CLK_ARMPLL_PFD3_UNGATED       31
+#define IMX95_CLK_ARMPLL_PFD3               32
+#define IMX95_CLK_DRAMPLL_VCO               33
+#define IMX95_CLK_DRAMPLL                   34
+#define IMX95_CLK_HSIOPLL_VCO               35
+#define IMX95_CLK_HSIOPLL                   36
+#define IMX95_CLK_LDBPLL_VCO                37
+#define IMX95_CLK_LDBPLL                    38
+#define IMX95_CLK_EXT1                      39
+#define IMX95_CLK_EXT2                      40
+
+#define IMX95_CCM_NUM_CLK_SRC               41
+
+#define IMX95_CLK_ADC                      (IMX95_CCM_NUM_CLK_SRC + 0)
+#define IMX95_CLK_TMU                      (IMX95_CCM_NUM_CLK_SRC + 1)
+#define IMX95_CLK_BUSAON                   (IMX95_CCM_NUM_CLK_SRC + 2)
+#define IMX95_CLK_CAN1                     (IMX95_CCM_NUM_CLK_SRC + 3)
+#define IMX95_CLK_I3C1                     (IMX95_CCM_NUM_CLK_SRC + 4)
+#define IMX95_CLK_I3C1SLOW                 (IMX95_CCM_NUM_CLK_SRC + 5)
+#define IMX95_CLK_LPI2C1                   (IMX95_CCM_NUM_CLK_SRC + 6)
+#define IMX95_CLK_LPI2C2                   (IMX95_CCM_NUM_CLK_SRC + 7)
+#define IMX95_CLK_LPSPI1                   (IMX95_CCM_NUM_CLK_SRC + 8)
+#define IMX95_CLK_LPSPI2                   (IMX95_CCM_NUM_CLK_SRC + 9)
+#define IMX95_CLK_LPTMR1                   (IMX95_CCM_NUM_CLK_SRC + 10)
+#define IMX95_CLK_LPUART1                  (IMX95_CCM_NUM_CLK_SRC + 11)
+#define IMX95_CLK_LPUART2                  (IMX95_CCM_NUM_CLK_SRC + 12)
+#define IMX95_CLK_M33                      (IMX95_CCM_NUM_CLK_SRC + 13)
+#define IMX95_CLK_M33SYSTICK               (IMX95_CCM_NUM_CLK_SRC + 14)
+#define IMX95_CLK_MQS1                     (IMX95_CCM_NUM_CLK_SRC + 15)
+#define IMX95_CLK_PDM                      (IMX95_CCM_NUM_CLK_SRC + 16)
+#define IMX95_CLK_SAI1                     (IMX95_CCM_NUM_CLK_SRC + 17)
+#define IMX95_CLK_SENTINEL                 (IMX95_CCM_NUM_CLK_SRC + 18)
+#define IMX95_CLK_TPM2                     (IMX95_CCM_NUM_CLK_SRC + 19)
+#define IMX95_CLK_TSTMR1                   (IMX95_CCM_NUM_CLK_SRC + 20)
+#define IMX95_CLK_CAMAPB                   (IMX95_CCM_NUM_CLK_SRC + 21)
+#define IMX95_CLK_CAMAXI                   (IMX95_CCM_NUM_CLK_SRC + 22)
+#define IMX95_CLK_CAMCM0                   (IMX95_CCM_NUM_CLK_SRC + 23)
+#define IMX95_CLK_CAMISI                   (IMX95_CCM_NUM_CLK_SRC + 24)
+#define IMX95_CLK_MIPIPHYCFG               (IMX95_CCM_NUM_CLK_SRC + 25)
+#define IMX95_CLK_MIPIPHYPLLBYPASS         (IMX95_CCM_NUM_CLK_SRC + 26)
+#define IMX95_CLK_MIPIPHYPLLREF            (IMX95_CCM_NUM_CLK_SRC + 27)
+#define IMX95_CLK_MIPITESTBYTE             (IMX95_CCM_NUM_CLK_SRC + 28)
+#define IMX95_CLK_A55                      (IMX95_CCM_NUM_CLK_SRC + 29)
+#define IMX95_CLK_A55MTRBUS                (IMX95_CCM_NUM_CLK_SRC + 30)
+#define IMX95_CLK_A55PERIPH                (IMX95_CCM_NUM_CLK_SRC + 31)
+#define IMX95_CLK_DRAMALT                  (IMX95_CCM_NUM_CLK_SRC + 32)
+#define IMX95_CLK_DRAMAPB                  (IMX95_CCM_NUM_CLK_SRC + 33)
+#define IMX95_CLK_DISPAPB                  (IMX95_CCM_NUM_CLK_SRC + 34)
+#define IMX95_CLK_DISPAXI                  (IMX95_CCM_NUM_CLK_SRC + 35)
+#define IMX95_CLK_DISPDP                   (IMX95_CCM_NUM_CLK_SRC + 36)
+#define IMX95_CLK_DISPOCRAM                (IMX95_CCM_NUM_CLK_SRC + 37)
+#define IMX95_CLK_DISPUSB31                (IMX95_CCM_NUM_CLK_SRC + 38)
+#define IMX95_CLK_DISP1PIX                 (IMX95_CCM_NUM_CLK_SRC + 39)
+#define IMX95_CLK_DISP2PIX                 (IMX95_CCM_NUM_CLK_SRC + 40)
+#define IMX95_CLK_DISP3PIX                 (IMX95_CCM_NUM_CLK_SRC + 41)
+#define IMX95_CLK_GPUAPB                   (IMX95_CCM_NUM_CLK_SRC + 42)
+#define IMX95_CLK_GPU                      (IMX95_CCM_NUM_CLK_SRC + 43)
+#define IMX95_CLK_HSIOACSCAN480M           (IMX95_CCM_NUM_CLK_SRC + 44)
+#define IMX95_CLK_HSIOACSCAN80M            (IMX95_CCM_NUM_CLK_SRC + 45)
+#define IMX95_CLK_HSIO                     (IMX95_CCM_NUM_CLK_SRC + 46)
+#define IMX95_CLK_HSIOPCIEAUX              (IMX95_CCM_NUM_CLK_SRC + 47)
+#define IMX95_CLK_HSIOPCIETEST160M         (IMX95_CCM_NUM_CLK_SRC + 48)
+#define IMX95_CLK_HSIOPCIETEST400M         (IMX95_CCM_NUM_CLK_SRC + 49)
+#define IMX95_CLK_HSIOPCIETEST500M         (IMX95_CCM_NUM_CLK_SRC + 50)
+#define IMX95_CLK_HSIOUSBTEST50M           (IMX95_CCM_NUM_CLK_SRC + 51)
+#define IMX95_CLK_HSIOUSBTEST60M           (IMX95_CCM_NUM_CLK_SRC + 52)
+#define IMX95_CLK_BUSM7                    (IMX95_CCM_NUM_CLK_SRC + 53)
+#define IMX95_CLK_M7                       (IMX95_CCM_NUM_CLK_SRC + 54)
+#define IMX95_CLK_M7SYSTICK                (IMX95_CCM_NUM_CLK_SRC + 55)
+#define IMX95_CLK_BUSNETCMIX               (IMX95_CCM_NUM_CLK_SRC + 56)
+#define IMX95_CLK_ENET                     (IMX95_CCM_NUM_CLK_SRC + 57)
+#define IMX95_CLK_ENETPHYTEST200M          (IMX95_CCM_NUM_CLK_SRC + 58)
+#define IMX95_CLK_ENETPHYTEST500M          (IMX95_CCM_NUM_CLK_SRC + 59)
+#define IMX95_CLK_ENETPHYTEST667M          (IMX95_CCM_NUM_CLK_SRC + 60)
+#define IMX95_CLK_ENETREF                  (IMX95_CCM_NUM_CLK_SRC + 61)
+#define IMX95_CLK_ENETTIMER1               (IMX95_CCM_NUM_CLK_SRC + 62)
+#define IMX95_CLK_MQS2                     (IMX95_CCM_NUM_CLK_SRC + 63)
+#define IMX95_CLK_SAI2                     (IMX95_CCM_NUM_CLK_SRC + 64)
+#define IMX95_CLK_NOCAPB                   (IMX95_CCM_NUM_CLK_SRC + 65)
+#define IMX95_CLK_NOC                      (IMX95_CCM_NUM_CLK_SRC + 66)
+#define IMX95_CLK_NPUAPB                   (IMX95_CCM_NUM_CLK_SRC + 67)
+#define IMX95_CLK_NPU                      (IMX95_CCM_NUM_CLK_SRC + 68)
+#define IMX95_CLK_CCMCKO1                  (IMX95_CCM_NUM_CLK_SRC + 69)
+#define IMX95_CLK_CCMCKO2                  (IMX95_CCM_NUM_CLK_SRC + 70)
+#define IMX95_CLK_CCMCKO3                  (IMX95_CCM_NUM_CLK_SRC + 71)
+#define IMX95_CLK_CCMCKO4                  (IMX95_CCM_NUM_CLK_SRC + 72)
+#define IMX95_CLK_VPUAPB                   (IMX95_CCM_NUM_CLK_SRC + 73)
+#define IMX95_CLK_VPU                      (IMX95_CCM_NUM_CLK_SRC + 74)
+#define IMX95_CLK_VPUDSP                   (IMX95_CCM_NUM_CLK_SRC + 75)
+#define IMX95_CLK_VPUJPEG                  (IMX95_CCM_NUM_CLK_SRC + 76)
+#define IMX95_CLK_AUDIOXCVR                (IMX95_CCM_NUM_CLK_SRC + 77)
+#define IMX95_CLK_BUSWAKEUP                (IMX95_CCM_NUM_CLK_SRC + 78)
+#define IMX95_CLK_CAN2                     (IMX95_CCM_NUM_CLK_SRC + 79)
+#define IMX95_CLK_CAN3                     (IMX95_CCM_NUM_CLK_SRC + 80)
+#define IMX95_CLK_CAN4                     (IMX95_CCM_NUM_CLK_SRC + 81)
+#define IMX95_CLK_CAN5                     (IMX95_CCM_NUM_CLK_SRC + 82)
+#define IMX95_CLK_FLEXIO1                  (IMX95_CCM_NUM_CLK_SRC + 83)
+#define IMX95_CLK_FLEXIO2                  (IMX95_CCM_NUM_CLK_SRC + 84)
+#define IMX95_CLK_FLEXSPI1                 (IMX95_CCM_NUM_CLK_SRC + 85)
+#define IMX95_CLK_I3C2                     (IMX95_CCM_NUM_CLK_SRC + 86)
+#define IMX95_CLK_I3C2SLOW                 (IMX95_CCM_NUM_CLK_SRC + 87)
+#define IMX95_CLK_LPI2C3                   (IMX95_CCM_NUM_CLK_SRC + 88)
+#define IMX95_CLK_LPI2C4                   (IMX95_CCM_NUM_CLK_SRC + 89)
+#define IMX95_CLK_LPI2C5                   (IMX95_CCM_NUM_CLK_SRC + 90)
+#define IMX95_CLK_LPI2C6                   (IMX95_CCM_NUM_CLK_SRC + 91)
+#define IMX95_CLK_LPI2C7                   (IMX95_CCM_NUM_CLK_SRC + 92)
+#define IMX95_CLK_LPI2C8                   (IMX95_CCM_NUM_CLK_SRC + 93)
+#define IMX95_CLK_LPSPI3                   (IMX95_CCM_NUM_CLK_SRC + 94)
+#define IMX95_CLK_LPSPI4                   (IMX95_CCM_NUM_CLK_SRC + 95)
+#define IMX95_CLK_LPSPI5                   (IMX95_CCM_NUM_CLK_SRC + 96)
+#define IMX95_CLK_LPSPI6                   (IMX95_CCM_NUM_CLK_SRC + 97)
+#define IMX95_CLK_LPSPI7                   (IMX95_CCM_NUM_CLK_SRC + 98)
+#define IMX95_CLK_LPSPI8                   (IMX95_CCM_NUM_CLK_SRC + 99)
+#define IMX95_CLK_LPTMR2                   (IMX95_CCM_NUM_CLK_SRC + 100)
+#define IMX95_CLK_LPUART3                  (IMX95_CCM_NUM_CLK_SRC + 101)
+#define IMX95_CLK_LPUART4                  (IMX95_CCM_NUM_CLK_SRC + 102)
+#define IMX95_CLK_LPUART5                  (IMX95_CCM_NUM_CLK_SRC + 103)
+#define IMX95_CLK_LPUART6                  (IMX95_CCM_NUM_CLK_SRC + 104)
+#define IMX95_CLK_LPUART7                  (IMX95_CCM_NUM_CLK_SRC + 105)
+#define IMX95_CLK_LPUART8                  (IMX95_CCM_NUM_CLK_SRC + 106)
+#define IMX95_CLK_SAI3                     (IMX95_CCM_NUM_CLK_SRC + 107)
+#define IMX95_CLK_SAI4                     (IMX95_CCM_NUM_CLK_SRC + 108)
+#define IMX95_CLK_SAI5                     (IMX95_CCM_NUM_CLK_SRC + 109)
+#define IMX95_CLK_SPDIF                    (IMX95_CCM_NUM_CLK_SRC + 110)
+#define IMX95_CLK_SWOTRACE                 (IMX95_CCM_NUM_CLK_SRC + 111)
+#define IMX95_CLK_TPM4                     (IMX95_CCM_NUM_CLK_SRC + 112)
+#define IMX95_CLK_TPM5                     (IMX95_CCM_NUM_CLK_SRC + 113)
+#define IMX95_CLK_TPM6                     (IMX95_CCM_NUM_CLK_SRC + 114)
+#define IMX95_CLK_TSTMR2                   (IMX95_CCM_NUM_CLK_SRC + 115)
+#define IMX95_CLK_USBPHYBURUNIN            (IMX95_CCM_NUM_CLK_SRC + 116)
+#define IMX95_CLK_USDHC1                   (IMX95_CCM_NUM_CLK_SRC + 117)
+#define IMX95_CLK_USDHC2                   (IMX95_CCM_NUM_CLK_SRC + 118)
+#define IMX95_CLK_USDHC3                   (IMX95_CCM_NUM_CLK_SRC + 119)
+#define IMX95_CLK_V2XPK                    (IMX95_CCM_NUM_CLK_SRC + 120)
+#define IMX95_CLK_WAKEUPAXI                (IMX95_CCM_NUM_CLK_SRC + 121)
+#define IMX95_CLK_XSPISLVROOT              (IMX95_CCM_NUM_CLK_SRC + 122)
+#define IMX95_CLK_SEL_EXT                  (IMX95_CCM_NUM_CLK_SRC + 123 + 0)
+#define IMX95_CLK_SEL_A55C0                (IMX95_CCM_NUM_CLK_SRC + 123 + 1)
+#define IMX95_CLK_SEL_A55C1                (IMX95_CCM_NUM_CLK_SRC + 123 + 2)
+#define IMX95_CLK_SEL_A55C2                (IMX95_CCM_NUM_CLK_SRC + 123 + 3)
+#define IMX95_CLK_SEL_A55C3                (IMX95_CCM_NUM_CLK_SRC + 123 + 4)
+#define IMX95_CLK_SEL_A55C4                (IMX95_CCM_NUM_CLK_SRC + 123 + 5)
+#define IMX95_CLK_SEL_A55C5                (IMX95_CCM_NUM_CLK_SRC + 123 + 6)
+#define IMX95_CLK_SEL_A55P                 (IMX95_CCM_NUM_CLK_SRC + 123 + 7)
+#define IMX95_CLK_SEL_DRAM                 (IMX95_CCM_NUM_CLK_SRC + 123 + 8)
+#define IMX95_CLK_SEL_TEMPSENSE            (IMX95_CCM_NUM_CLK_SRC + 123 + 9)
+
+#endif	/* __DT_BINDINGS_CLOCK_IMX95_H */
diff --git a/arch/arm64/boot/dts/freescale/imx95-power.h b/arch/arm64/boot/dts/freescale/imx95-power.h
new file mode 100644
index 000000000000..17be8a4cb96b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-power.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ *  Copyright 2024 NXP
+ */
+
+#ifndef __DT_BINDINGS_IMX95_POWER_H__
+#define __DT_BINDINGS_IMX95_POWER_H__
+
+#define IMX95_PD_ANA		0
+#define IMX95_PD_AON		1
+#define IMX95_PD_BBSM		2
+#define IMX95_PD_CAMERA		3
+#define IMX95_PD_CCMSRCGPC	4
+#define IMX95_PD_A55C0		5
+#define IMX95_PD_A55C1		6
+#define IMX95_PD_A55C2		7
+#define IMX95_PD_A55C3		8
+#define IMX95_PD_A55C4		9
+#define IMX95_PD_A55C5		10
+#define IMX95_PD_A55P		11
+#define IMX95_PD_DDR		12
+#define IMX95_PD_DISPLAY	13
+#define IMX95_PD_GPU		14
+#define IMX95_PD_HSIO_TOP	15
+#define IMX95_PD_HSIO_WAON	16
+#define IMX95_PD_M7		17
+#define IMX95_PD_NETC		18
+#define IMX95_PD_NOC		19
+#define IMX95_PD_NPU		20
+#define IMX95_PD_VPU		21
+#define IMX95_PD_WAKEUP		22
+
+#define IMX95_PERF_ELE		0
+#define IMX95_PERF_M33		1
+#define IMX95_PERF_WAKEUP	2
+#define IMX95_PERF_M7		3
+#define IMX95_PERF_DRAM		4
+#define IMX95_PERF_HSIO		5
+#define IMX95_PERF_NPU		6
+#define IMX95_PERF_NOC		7
+#define IMX95_PERF_A55		8
+#define IMX95_PERF_GPU		9
+#define IMX95_PERF_VPU		10
+#define IMX95_PERF_CAM		11
+#define IMX95_PERF_DISP		12
+#define IMX95_PERF_A55PER	13
+#define IMX95_PERF_A55P		14
+#define IMX95_PERF_A55C0	15
+#define IMX95_PERF_A55C1	16
+#define IMX95_PERF_A55C2	17
+#define IMX95_PERF_A55C3	18
+#define IMX95_PERF_A55C4	19
+#define IMX95_PERF_A55C5	20
+
+#endif
diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
new file mode 100644
index 000000000000..5b5b29a9aff5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -0,0 +1,1215 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include "imx95-clock.h"
+#include "imx95-power.h"
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		gpio0 = &gpio1;
+		gpio1 = &gpio2;
+		gpio2 = &gpio3;
+		gpio3 = &gpio4;
+		gpio4 = &gpio5;
+		i2c0 = &lpi2c1;
+		i2c1 = &lpi2c2;
+		i2c2 = &lpi2c3;
+		i2c3 = &lpi2c4;
+		i2c4 = &lpi2c5;
+		i2c5 = &lpi2c6;
+		i2c6 = &lpi2c7;
+		i2c7 = &lpi2c8;
+		mmc0 = &usdhc1;
+		mmc1 = &usdhc2;
+		mmc2 = &usdhc3;
+		serial0 = &lpuart1;
+		serial1 = &lpuart2;
+		serial2 = &lpuart3;
+		serial3 = &lpuart4;
+		serial4 = &lpuart5;
+		serial5 = &lpuart6;
+		serial6 = &lpuart7;
+		serial7 = &lpuart8;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		idle-states {
+			entry-method = "psci";
+
+			cpu_pd_wait: cpu-pd-wait {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x0010033>;
+				local-timer-stop;
+				entry-latency-us = <10000>;
+				exit-latency-us = <7000>;
+				min-residency-us = <27000>;
+				wakeup-latency-us = <15000>;
+				status = "disabled";
+			};
+		};
+
+		A55_0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0>;
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_pd_wait>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l0>;
+		};
+
+		A55_1: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_pd_wait>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l1>;
+		};
+
+		A55_2: cpu at 200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x200>;
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_pd_wait>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l2>;
+		};
+
+		A55_3: cpu at 300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x300>;
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l3>;
+		};
+
+		A55_4: cpu at 400 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x400>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_pd_wait>;
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l4>;
+		};
+
+		A55_5: cpu at 500 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x500>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_pd_wait>;
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l5>;
+		};
+
+		l2_cache_l0: l2-cache-l0 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l1: l2-cache-l1 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l2: l2-cache-l2 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l3: l2-cache-l3 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l4: l2-cache-l4 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l5: l2-cache-l5 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l3_cache: l3-cache {
+			compatible = "cache";
+			cache-size = <524288>;
+			cache-line-size = <64>;
+			cache-sets = <1024>;
+			cache-level = <3>;
+			cache-unified;
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&A55_0>;
+				};
+
+				core1 {
+					cpu = <&A55_1>;
+				};
+
+				core2 {
+					cpu = <&A55_2>;
+				};
+
+				core3 {
+					cpu = <&A55_3>;
+				};
+
+				core4 {
+					cpu = <&A55_4>;
+				};
+
+				core5 {
+					cpu = <&A55_5>;
+				};
+			};
+		};
+	};
+
+	clk_ext1: clock-ext1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <133000000>;
+		clock-output-names = "clk_ext1";
+	};
+
+	dummy: clk-dummy {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+		clock-output-names = "dummy";
+	};
+
+	sai1_mclk: sai-mclk1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <0>;
+		clock-output-names = "sai1_mclk";
+	};
+
+	sai2_mclk: sai-mclk2 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <0>;
+		clock-output-names = "sai2_mclk";
+	};
+
+	sai3_mclk: sai-mclk3 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <0>;
+		clock-output-names = "sai3_mclk";
+	};
+
+	sai4_mclk: sai-mclk4 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <0>;
+		clock-output-names = "sai4_mclk";
+	};
+
+	sai5_mclk: sai-mclk5 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <0>;
+		clock-output-names = "sai5_mclk";
+	};
+
+	osc_24m: osc-24m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "osc_24m";
+	};
+
+	sram1: sram at 20480000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0x204c0000 0x0 0x18000>;
+	};
+
+	firmware {
+		scmi {
+			compatible = "arm,scmi";
+			mboxes = <&mu2 5 0>, <&mu2 3 0>, <&mu2 3 1>;
+			shmem = <&scmi_buf0>, <&scmi_buf1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			scmi_devpd: protocol at 11 {
+				reg = <0x11>;
+				#power-domain-cells = <1>;
+			};
+
+			scmi_sys_power: protocol at 12 {
+				reg = <0x12>;
+			};
+
+			scmi_perf: protocol at 13 {
+				reg = <0x13>;
+				#clock-cells = <1>;
+				#power-domain-cells = <1>;
+			};
+
+			scmi_clk: protocol at 14 {
+				reg = <0x14>;
+				#clock-cells = <1>;
+			};
+
+			scmi_sensor: protocol at 15 {
+				reg = <0x15>;
+				#thermal-sensor-cells = <1>;
+			};
+		};
+	};
+
+	pmu {
+		compatible = "arm,cortex-a55-pmu";
+		interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	thermal-zones {
+		a55 {
+			polling-delay-passive = <250>;
+			polling-delay = <2000>;
+			thermal-sensors = <&scmi_sensor 1>;
+
+			trips {
+				cpu_alert0: trip0 {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				cpu_crit0: trip1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert0>;
+					cooling-device =
+						<&A55_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&A55_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&A55_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&A55_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&A55_4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&A55_5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
+	etm0: etm at 40840000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		reg = <0x0 0x40840000 0x0 0x10000>;
+		arm,primecell-periphid = <0xbb95d>;
+		cpu = <&A55_0>;
+		clocks = <&scmi_clk IMX95_CLK_A55PERIPH>;
+		clock-names = "apb_pclk";
+		status = "disabled";
+
+		out-ports {
+			port {
+				etm0_out_port: endpoint {
+					remote-endpoint = <&ca_funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	funnel0: funnel {
+		/*
+		 * non-configurable funnel don't show up on the AMBA
+		 * bus.  As such no need to add "arm,primecell".
+		 */
+		compatible = "arm,coresight-static-funnel";
+		status = "disabled";
+
+		in-ports {
+			port {
+				ca_funnel_in_port0: endpoint {
+					remote-endpoint = <&etm0_out_port>;
+				};
+			};
+		};
+
+		out-ports {
+			port {
+				ca_funnel_out_port0: endpoint {
+					remote-endpoint = <&hugo_funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	funnel1: funnel_sys {
+		compatible = "arm,coresight-static-funnel";
+		status = "disabled";
+
+		in-ports {
+			port {
+				hugo_funnel_in_port0: endpoint {
+					remote-endpoint = <&ca_funnel_out_port0>;
+				};
+			};
+		};
+
+		out-ports {
+			port {
+				hugo_funnel_out_port0: endpoint {
+					remote-endpoint = <&etf_in_port>;
+				};
+			};
+		};
+	};
+
+	etf: etf at 41030000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x0 0x41030000 0x0 0x1000>;
+		clocks = <&scmi_clk IMX95_CLK_A55PERIPH>;
+		clock-names = "apb_pclk";
+		status = "disabled";
+
+		in-ports {
+			port {
+				etf_in_port: endpoint {
+					remote-endpoint = <&hugo_funnel_out_port0>;
+				};
+			};
+		};
+
+		out-ports {
+			port {
+				etf_out_port: endpoint {
+					remote-endpoint = <&etr_in_port>;
+				};
+			};
+		};
+	};
+
+	etr: etr at 41040000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x0 0x41040000 0x0 0x1000>;
+		clocks = <&scmi_clk IMX95_CLK_A55PERIPH>;
+		clock-names = "apb_pclk";
+		status = "disabled";
+
+		in-ports {
+			port {
+				etr_in_port: endpoint {
+					remote-endpoint = <&etf_out_port>;
+				};
+			};
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <24000000>;
+		arm,no-tick-in-suspend;
+		interrupt-parent = <&gic>;
+	};
+
+	gic: interrupt-controller at 48000000 {
+		compatible = "arm,gic-v3";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		reg = <0 0x48000000 0 0x10000>,
+		      <0 0x48060000 0 0xc0000>;
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		dma-noncoherent;
+		ranges;
+
+		its: msi-controller at 48040000 {
+			compatible = "arm,gic-v3-its";
+			dma-noncoherent;
+			msi-controller;
+			reg = <0 0x48040000 0 0x20000>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		aips2: bus at 42000000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0x0 0x42000000 0x0 0x800000>;
+			ranges = <0x42000000 0x0 0x42000000 0x8000000>,
+				 <0x28000000 0x0 0x28000000 0x10000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			mu7: mailbox at 42430000 {
+				compatible = "fsl,imx95-mu", "fsl,imx8ulp-mu";
+				reg = <0x42430000 0x10000>;
+				interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			mu8: mailbox at 42730000 {
+				compatible = "fsl,imx95-mu", "fsl,imx8ulp-mu";
+				reg = <0x42730000 0x10000>;
+				interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			wdog3: wdog at 42490000 {
+				compatible = "fsl,imx93-wdt";
+				reg = <0x42490000 0x10000>;
+				interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				timeout-sec = <40>;
+				fsl,ext-reset-output;
+				status = "disabled";
+			};
+
+			tpm3: pwm at 424e0000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x424e0000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			tpm4: pwm at 424f0000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x424f0000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_TPM4>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			tpm5: pwm at 42500000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x42500000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_TPM5>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			tpm6: pwm at 42510000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x42510000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_TPM6>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			lpi2c3: i2c at 42530000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x42530000 0x10000>;
+				interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C3>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpi2c4: i2c at 42540000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x42540000 0x10000>;
+				interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C4>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi3: spi at 42550000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x42550000 0x10000>;
+				interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI3>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi4: spi at 42560000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x42560000 0x10000>;
+				interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI4>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpuart3: serial at 42570000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x42570000 0x1000>;
+				interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART3>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart4: serial at 42580000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x42580000 0x1000>;
+				interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART4>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart5: serial at 42590000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x42590000 0x1000>;
+				interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART5>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart6: serial at 425a0000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x425a0000 0x1000>;
+				interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART6>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart7: serial at 42690000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x42690000 0x1000>;
+				interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART7>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart8: serial at 426a0000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x426a0000 0x1000>;
+				interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART8>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpi2c5: i2c at 426b0000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x426b0000 0x10000>;
+				interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C5>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpi2c6: i2c at 426c0000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x426c0000 0x10000>;
+				interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C6>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpi2c7: i2c at 426d0000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x426d0000 0x10000>;
+				interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C7>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpi2c8: i2c at 426e0000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x426e0000 0x10000>;
+				interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C8>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi5: spi at 426f0000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x426f0000 0x10000>;
+				interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI5>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi6: spi at 42700000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x42700000 0x10000>;
+				interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI6>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi7: spi at 42710000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x42710000 0x10000>;
+				interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI7>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi8: spi at 42720000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x42720000 0x10000>;
+				interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI8>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+		};
+
+		aips3: bus at 42800000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0 0x42800000 0 0x800000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x42800000 0x0 0x42800000 0x800000>;
+
+			usdhc1: mmc at 42850000 {
+				compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
+				reg = <0x42850000 0x10000>;
+				interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+					 <&scmi_clk IMX95_CLK_WAKEUPAXI>,
+					 <&scmi_clk IMX95_CLK_USDHC1>;
+				clock-names = "ipg", "ahb", "per";
+				assigned-clocks = <&scmi_clk IMX95_CLK_USDHC1>;
+				assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD1>;
+				assigned-clock-rates = <400000000>;
+				bus-width = <8>;
+				fsl,tuning-start-tap = <1>;
+				fsl,tuning-step= <2>;
+				status = "disabled";
+			};
+
+			usdhc2: mmc at 42860000 {
+				compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
+				reg = <0x42860000 0x10000>;
+				interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+					 <&scmi_clk IMX95_CLK_WAKEUPAXI>,
+					 <&scmi_clk IMX95_CLK_USDHC2>;
+				clock-names = "ipg", "ahb", "per";
+				assigned-clocks = <&scmi_clk IMX95_CLK_USDHC2>;
+				assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD1>;
+				assigned-clock-rates = <200000000>;
+				bus-width = <4>;
+				fsl,tuning-start-tap = <1>;
+				fsl,tuning-step= <2>;
+				status = "disabled";
+			};
+
+			usdhc3: mmc at 428b0000 {
+				compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
+				reg = <0x428b0000 0x10000>;
+				interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+					 <&scmi_clk IMX95_CLK_WAKEUPAXI>,
+					 <&scmi_clk IMX95_CLK_USDHC3>;
+				clock-names = "ipg", "ahb", "per";
+				bus-width = <4>;
+				fsl,tuning-start-tap = <1>;
+				fsl,tuning-step= <2>;
+				status = "disabled";
+			};
+		};
+
+		gpio2: gpio at 43810000 {
+			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+			reg = <0x0 0x43810000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+				 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+			clock-names = "gpio", "port";
+		};
+
+		gpio3: gpio at 43820000 {
+			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+			reg = <0x0 0x43820000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+				 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+			clock-names = "gpio", "port";
+		};
+
+		gpio4: gpio at 43840000 {
+			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+			reg = <0x0 0x43840000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+				 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+			clock-names = "gpio", "port";
+		};
+
+		gpio5: gpio at 43850000 {
+			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+			reg = <0x0 0x43850000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+				 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+			clock-names = "gpio", "port";
+		};
+
+		aips1: bus at 44000000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0x0 0x44000000 0x0 0x800000>;
+			ranges = <0x44000000 0x0 0x44000000 0x800000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			mu1: mailbox at 44220000 {
+				compatible = "fsl,imx95-mu", "fsl,imx8ulp-mu";
+				reg = <0x44220000 0x10000>;
+				interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			mu2: mailbox at 445b0000 {
+				compatible = "fsl,imx95-mu";
+				reg = <0x445b0000 0x1000>;
+				ranges;
+				interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				#mbox-cells = <2>;
+
+				sram0: sram at 445b1000 {
+					compatible = "mmio-sram";
+					reg = <0x445b1000 0x400>;
+					ranges = <0x0 0x445b1000 0x400>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					scmi_buf0: scmi-sram-section at 0 {
+						compatible = "arm,scmi-shmem";
+						reg = <0x0 0x80>;
+					};
+
+					scmi_buf1: scmi-sram-section at 80 {
+						compatible = "arm,scmi-shmem";
+						reg = <0x80 0x80>;
+					};
+				};
+
+			};
+
+			mu3: mailbox at 445d0000 {
+				compatible = "fsl,imx95-mu", "fsl,imx8ulp-mu";
+				reg = <0x445d0000 0x10000>;
+				interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			mu4: mailbox at 445f0000 {
+				compatible = "fsl,imx95-mu", "fsl,imx8ulp-mu";
+				reg = <0x445f0000 0x10000>;
+				interrupts = <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			mu6: mailbox at 44630000 {
+				compatible = "fsl,imx95-mu", "fsl,imx8ulp-mu";
+				reg = <0x44630000 0x10000>;
+				interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			tpm1: pwm at 44310000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x44310000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			tpm2: pwm at 44320000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x44320000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_TPM2>;
+				assigned-clocks = <&scmi_clk IMX95_CLK_TPM2>;
+				assigned-clock-parents = <&scmi_clk IMX95_CLK_24M>;
+				assigned-clock-rates = <24000000>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			lpi2c1: i2c at 44340000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x44340000 0x10000>;
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C1>,
+					 <&scmi_clk IMX95_CLK_BUSAON>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpi2c2: i2c at 44350000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x44350000 0x10000>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C2>,
+					 <&scmi_clk IMX95_CLK_BUSAON>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi1: spi at 44360000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x44360000 0x10000>;
+				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI1>,
+					 <&scmi_clk IMX95_CLK_BUSAON>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi2: spi at 44370000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x44370000 0x10000>;
+				interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI2>,
+					 <&scmi_clk IMX95_CLK_BUSAON>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpuart1: serial at 44380000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x44380000 0x1000>;
+				interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART1>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart2: serial at 44390000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x44390000 0x1000>;
+				interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART2>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			adc1: adc at 44530000 {
+				compatible = "nxp,imx93-adc";
+				reg = <0x44530000 0x10000>;
+				interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
+						<GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
+						<GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_ADC>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+		};
+
+		aips4: bus at 49000000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0x0 0x49000000 0x0 0x800000>;
+			ranges = <0x49000000 0x0 0x49000000 0x800000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			smmu: iommu at 490d0000 {
+				compatible = "arm,smmu-v3";
+				reg = <0x490d0000 0x100000>;
+				interrupts = <GIC_SPI 325 IRQ_TYPE_EDGE_RISING>,
+					     <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>,
+					     <GIC_SPI 334 IRQ_TYPE_EDGE_RISING>,
+					     <GIC_SPI 326 IRQ_TYPE_EDGE_RISING>;
+				interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+				#iommu-cells = <1>;
+				status = "disabled";
+			};
+		};
+
+		gpio1: gpio at 47400000 {
+			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+			reg = <0x0 0x47400000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&scmi_clk IMX95_CLK_M33>,
+				 <&scmi_clk IMX95_CLK_M33>;
+			clock-names = "gpio", "port";
+			status = "disabled";
+		};
+
+		elemu0: mailbox at 47520000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47520000 0x0 0x10000>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		elemu1: mailbox at 47530000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47530000 0x0 0x10000>;
+			interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		elemu2: mailbox at 47540000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47540000 0x0 0x10000>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		elemu3: mailbox at 47550000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47550000 0x0 0x10000>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+		};
+
+		elemu4: mailbox at 47560000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47560000 0x0 0x10000>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		elemu5: mailbox at 47570000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47570000 0x0 0x10000>;
+			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		v2x_mu: v2x-mu at 47350000 {
+			compatible = "fsl,imx95-mu-v2x";
+			reg = <0x0 0x47350000 0x0 0x10000>;
+			interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "tx", "rx";
+			#mbox-cells = <2>;
+			status = "okay";
+		};
+
+		v2x_mu6: mailbox at 47320000 {
+			compatible = "fsl,imx95-mu-v2x";
+			reg = <0x0 0x47320000 0x0 0x10000>;
+			interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "tx", "rx";
+			#mbox-cells = <2>;
+			status = "okay";
+		};
+
+		displaymix_irqsteer: interrupt-controller at 4b0b0000 {
+			compatible = "fsl,imx-irqsteer";
+			reg = <0x0 0x4b0b0000 0x0 0x1000>;
+			interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,	/* reserved */
+				     <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,	/* reserved */
+				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&scmi_devpd IMX95_PD_DISPLAY>;
+			clocks = <&scmi_clk IMX95_CLK_DISPAPB>;
+			clock-names = "ipg";
+			fsl,channel = <0>;
+			fsl,num-irqs = <512>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			status = "disabled";
+		};
+	};
+};

-- 
2.37.1



From peng.fan at oss.nxp.com  Sat Feb 17 22:38:53 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:38:53 +0800
Subject: [PATCH 3/3] arm64: dts: freescale: add i.MX95 19x19 EVK minimal
 board dts
In-Reply-To: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>
References: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>
Message-ID: <20240218-imx95-dts-v1-3-2959f89f2018@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add a minimal dts for i.MX95 19x19 EVK board:
 - lpuart1 as console
 - sdhc1/2 as storage

As of now, because scmi pinctrl support not ready, so count on
bootloader to set the pinctrl.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/Makefile            |  1 +
 arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts | 88 +++++++++++++++++++++++
 2 files changed, 89 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 518149d295a1..c830ff88f5f8 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -209,6 +209,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba93xxca.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba93xxla.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx93-var-som-symphony.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk.dtb
 
 imx8mm-venice-gw72xx-0x-imx219-dtbs	:= imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-imx219.dtbo
 imx8mm-venice-gw72xx-0x-rpidsi-dtbs	:= imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-rpidsi.dtbo
diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
new file mode 100644
index 000000000000..9640f3b49e63
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+/dts-v1/;
+
+#include "imx95.dtsi"
+
+/ {
+	model = "NXP i.MX95 19X19 board";
+	compatible = "fsl,imx95-19x19-evk", "fsl,imx95";
+
+	chosen {
+		stdout-path = &lpuart1;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0 0x80000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		linux_cma: linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0 0x3c000000>;
+			alloc-ranges = <0 0x80000000 0 0x7F000000>;
+			linux,cma-default;
+		};
+	};
+
+	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_vref_1v8: regulator-adc-vref {
+		compatible = "regulator-fixed";
+		regulator-name = "vref_1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+};
+
+&displaymix_irqsteer {
+	status = "okay";
+};
+
+&lpuart1 {
+	/* console */
+	status = "okay";
+};
+
+&mu7 {
+	status = "okay";
+};
+
+&usdhc1 {
+	bus-width = <8>;
+	non-removable;
+	no-sdio;
+	no-sd;
+	status = "okay";
+};
+
+&usdhc2 {
+	non-removable;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&wdog3 {
+	status = "okay";
+};

-- 
2.37.1



From xiaobo55x at gmail.com  Sat Feb 17 22:41:00 2024
From: xiaobo55x at gmail.com (Haibo Xu)
Date: Sun, 18 Feb 2024 14:41:00 +0800
Subject: [PATCH v5 00/12] RISCV: Add kvm Sstc timer selftests
In-Reply-To: <CAAhSdy2wFzk0h5MiM5y9Fij0HyWake=7vNuV1MExUxkEtMWShw@mail.gmail.com>
References: <cover.1705916069.git.haibo1.xu@intel.com> <CAAhSdy2wFzk0h5MiM5y9Fij0HyWake=7vNuV1MExUxkEtMWShw@mail.gmail.com>
Message-ID: <CAJve8okkfvdRtvh8onQYL7_bmv9ntrViP54u805fQMq3apWFcQ@mail.gmail.com>

On Mon, Feb 12, 2024 at 8:24?PM Anup Patel <anup at brainfault.org> wrote:
>
> On Mon, Jan 22, 2024 at 3:15?PM Haibo Xu <haibo1.xu at intel.com> wrote:
> >
> > The RISC-V arch_timer selftests is used to validate Sstc timer
> > functionality in a guest, which sets up periodic timer interrupts
> > and check the basic interrupt status upon its receipt.
> >
> > This KVM selftests was ported from aarch64 arch_timer and tested
> > with Linux v6.7-rc8 on a Qemu riscv64 virt machine.
> >
> > ---
> > Changed since v4:
> >   * Rebased to Linux 6.7-rc8
> >   * Added new patch(2/12) to clean up the data type in struct test_args
> >   * Re-ordered patch(11/11) in v4 to patch(3/12)
> >   * Changed the timer_err_margin_us type from int to uint32_t
> >
> > Haibo Xu (11):
> >   KVM: arm64: selftests: Data type cleanup for arch_timer test
> >   KVM: arm64: selftests: Enable tuning of error margin in arch_timer
> >     test
> >   KVM: arm64: selftests: Split arch_timer test code
> >   KVM: selftests: Add CONFIG_64BIT definition for the build
> >   tools: riscv: Add header file csr.h
> >   tools: riscv: Add header file vdso/processor.h
> >   KVM: riscv: selftests: Switch to use macro from csr.h
> >   KVM: riscv: selftests: Add exception handling support
> >   KVM: riscv: selftests: Add guest helper to get vcpu id
> >   KVM: riscv: selftests: Change vcpu_has_ext to a common function
> >   KVM: riscv: selftests: Add sstc timer test
> >
> > Paolo Bonzini (1):
> >   selftests/kvm: Fix issues with $(SPLIT_TESTS)
>
> Rebased on Linux-6.8-rc4 and queued this series for Linux-6.9
>

Thanks!

> Thanks,
> Anup
>
> >
> >  tools/arch/riscv/include/asm/csr.h            | 541 ++++++++++++++++++
> >  tools/arch/riscv/include/asm/vdso/processor.h |  32 ++
> >  tools/testing/selftests/kvm/Makefile          |  27 +-
> >  .../selftests/kvm/aarch64/arch_timer.c        | 295 +---------
> >  tools/testing/selftests/kvm/arch_timer.c      | 259 +++++++++
> >  .../selftests/kvm/include/aarch64/processor.h |   4 -
> >  .../selftests/kvm/include/kvm_util_base.h     |   9 +
> >  .../selftests/kvm/include/riscv/arch_timer.h  |  71 +++
> >  .../selftests/kvm/include/riscv/processor.h   |  65 ++-
> >  .../testing/selftests/kvm/include/test_util.h |   2 +
> >  .../selftests/kvm/include/timer_test.h        |  45 ++
> >  .../selftests/kvm/lib/riscv/handlers.S        | 101 ++++
> >  .../selftests/kvm/lib/riscv/processor.c       |  87 +++
> >  .../testing/selftests/kvm/riscv/arch_timer.c  | 111 ++++
> >  .../selftests/kvm/riscv/get-reg-list.c        |  11 +-
> >  15 files changed, 1353 insertions(+), 307 deletions(-)
> >  create mode 100644 tools/arch/riscv/include/asm/csr.h
> >  create mode 100644 tools/arch/riscv/include/asm/vdso/processor.h
> >  create mode 100644 tools/testing/selftests/kvm/arch_timer.c
> >  create mode 100644 tools/testing/selftests/kvm/include/riscv/arch_timer.h
> >  create mode 100644 tools/testing/selftests/kvm/include/timer_test.h
> >  create mode 100644 tools/testing/selftests/kvm/lib/riscv/handlers.S
> >  create mode 100644 tools/testing/selftests/kvm/riscv/arch_timer.c
> >
> > --
> > 2.34.1
> >


From peng.fan at oss.nxp.com  Sat Feb 17 22:56:12 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:56:12 +0800
Subject: [PATCH v7 0/6] mailbox: imx: support i.MX95 ELE/V2X MU
Message-ID: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>

- Add dt-bindings
- i.MX95 ELE/V2X use same register layout as i.MX8ULP S4 MU, but
  the TR/RR num is different. To make code reusable and not add too much
  macros, add runtime detect number of TR and RR by reading PAR_OFF
  registers.
- Add i.MX95 ELE/V2X MU entry in driver

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Changes in v7:
- Per Jassi, separate the patch to add of_platform_populate.
- Link to v6: https://lore.kernel.org/r/20240201-imx-mailbox-v6-0-76f4f35b403e at nxp.com

Changes in v6:
- Drop node labels and add Conor's R-b
- Link to v5: https://lore.kernel.org/r/20240126-imx-mailbox-v5-0-7ff3a3d53529 at nxp.com

Changes in v5:
- Per Conor, add restriction to sram property.
- Since i.MX95 MU has SRAM, we may not see it is compatible with
i.MX8ULP MU, so drop the fallback compatible
- Add R-b for patch 2&3
- Link to v4: https://lore.kernel.org/r/20240125-imx-mailbox-v4-0-800be5383c20 at nxp.com

Changes in v4:
- Address dt-binding comments in V2 from Krzysztof
- Link to v3: https://lore.kernel.org/r/20240123-imx-mailbox-v3-0-ed932945e0bf at nxp.com

Changes in v3:
- Following dts coding style Per Krzysztof
- Add return type for init function, patch 2 is new
- Check return value when tr/rr is larger than 4 and return error.
- Link to v2: https://lore.kernel.org/r/20240122-imx-mailbox-v2-0-7b3c80333b92 at nxp.com

Changes in v2:
- Support sram property and add example
- Populate the sram node in driver
- Link to v1: https://lore.kernel.org/r/20240122-imx-mailbox-v1-0-81413f655210 at nxp.com

---
Peng Fan (6):
      dt-bindings: mailbox: fsl,mu: add i.MX95 Generic/ELE/V2X MU compatible
      mailbox: imx: support return value of init
      mailbox: imx: get RR/TR registers num from Parameter register
      tt
      mailbox: imx: populate sub-nodes
      mailbox: imx: support i.MX95 Generic/ELE/V2X MU

 .../devicetree/bindings/mailbox/fsl,mu.yaml        | 58 +++++++++++++-
 drivers/mailbox/imx-mailbox.c                      | 88 ++++++++++++++++------
 2 files changed, 123 insertions(+), 23 deletions(-)
---
base-commit: ad5c60d66016e544c51ed98635a74073f761f45d
change-id: 20240122-imx-mailbox-243021d12030

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Sat Feb 17 22:56:13 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:56:13 +0800
Subject: [PATCH v7 1/6] dt-bindings: mailbox: fsl,mu: add i.MX95
 Generic/ELE/V2X MU compatible
In-Reply-To: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
References: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
Message-ID: <20240218-imx-mailbox-v7-1-8fb665eeae40@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add i.MX95 Generic, Secure Enclave and V2X Message Unit compatible string.
And the MUs in AONMIX has internal RAMs for SCMI shared buffer usage.

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/mailbox/fsl,mu.yaml        | 58 +++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml b/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml
index 12e7a7d536a3..00631afcd51d 100644
--- a/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml
+++ b/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml
@@ -29,8 +29,11 @@ properties:
       - const: fsl,imx8ulp-mu
       - const: fsl,imx8-mu-scu
       - const: fsl,imx8-mu-seco
-      - const: fsl,imx93-mu-s4
       - const: fsl,imx8ulp-mu-s4
+      - const: fsl,imx93-mu-s4
+      - const: fsl,imx95-mu
+      - const: fsl,imx95-mu-ele
+      - const: fsl,imx95-mu-v2x
       - items:
           - const: fsl,imx93-mu
           - const: fsl,imx8ulp-mu
@@ -95,6 +98,19 @@ properties:
   power-domains:
     maxItems: 1
 
+  ranges: true
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 1
+
+patternProperties:
+  "^sram@[a-f0-9]+":
+    $ref: /schemas/sram/sram.yaml#
+    unevaluatedProperties: false
+
 required:
   - compatible
   - reg
@@ -122,6 +138,15 @@ allOf:
         required:
           - interrupt-names
 
+  - if:
+      not:
+        properties:
+          compatible:
+            const: fsl,imx95-mu
+    then:
+      patternProperties:
+        "^sram@[a-f0-9]+": false
+
 additionalProperties: false
 
 examples:
@@ -134,3 +159,34 @@ examples:
         interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
         #mbox-cells = <2>;
     };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    mailbox at 445b0000 {
+        compatible = "fsl,imx95-mu";
+        reg = <0x445b0000 0x10000>;
+        ranges;
+        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        #mbox-cells = <2>;
+
+        sram at 445b1000 {
+            compatible = "mmio-sram";
+            reg = <0x445b1000 0x400>;
+            ranges = <0x0 0x445b1000 0x400>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            scmi-sram-section at 0 {
+                compatible = "arm,scmi-shmem";
+                reg = <0x0 0x80>;
+            };
+
+            scmi-sram-section at 80 {
+                compatible = "arm,scmi-shmem";
+                reg = <0x80 0x80>;
+            };
+        };
+    };

-- 
2.37.1



From peng.fan at oss.nxp.com  Sat Feb 17 22:56:14 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:56:14 +0800
Subject: [PATCH v7 2/6] mailbox: imx: support return value of init
In-Reply-To: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
References: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
Message-ID: <20240218-imx-mailbox-v7-2-8fb665eeae40@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

There will be changes that init may fail, so adding return value for
init function.

Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 656171362fe9..dced4614065f 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -110,7 +110,7 @@ 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);
+	int (*init)(struct imx_mu_priv *priv);
 	enum imx_mu_type type;
 	u32	xTR;		/* Transmit Register0 */
 	u32	xRR;		/* Receive Register0 */
@@ -737,7 +737,7 @@ static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox,
 	return imx_mu_xlate(mbox, sp);
 }
 
-static void imx_mu_init_generic(struct imx_mu_priv *priv)
+static int imx_mu_init_generic(struct imx_mu_priv *priv)
 {
 	unsigned int i;
 	unsigned int val;
@@ -757,7 +757,7 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
 	priv->mbox.of_xlate = imx_mu_xlate;
 
 	if (priv->side_b)
-		return;
+		return 0;
 
 	/* Set default MU configuration */
 	for (i = 0; i < IMX_MU_xCR_MAX; i++)
@@ -770,9 +770,11 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
 	/* Clear any pending RSR */
 	for (i = 0; i < IMX_MU_NUM_RR; i++)
 		imx_mu_read(priv, priv->dcfg->xRR + (i % 4) * 4);
+
+	return 0;
 }
 
-static void imx_mu_init_specific(struct imx_mu_priv *priv)
+static int imx_mu_init_specific(struct imx_mu_priv *priv)
 {
 	unsigned int i;
 	int num_chans = priv->dcfg->type & IMX_MU_V2_S4 ? IMX_MU_S4_CHANS : IMX_MU_SCU_CHANS;
@@ -794,12 +796,20 @@ static void imx_mu_init_specific(struct imx_mu_priv *priv)
 	/* Set default MU configuration */
 	for (i = 0; i < IMX_MU_xCR_MAX; i++)
 		imx_mu_write(priv, 0, priv->dcfg->xCR[i]);
+
+	return 0;
 }
 
-static void imx_mu_init_seco(struct imx_mu_priv *priv)
+static int imx_mu_init_seco(struct imx_mu_priv *priv)
 {
-	imx_mu_init_generic(priv);
+	int ret;
+
+	ret = imx_mu_init_generic(priv);
+	if (ret)
+		return ret;
 	priv->mbox.of_xlate = imx_mu_seco_xlate;
+
+	return 0;
 }
 
 static int imx_mu_probe(struct platform_device *pdev)
@@ -866,7 +876,11 @@ static int imx_mu_probe(struct platform_device *pdev)
 
 	priv->side_b = of_property_read_bool(np, "fsl,mu-side-b");
 
-	priv->dcfg->init(priv);
+	ret = priv->dcfg->init(priv);
+	if (ret) {
+		dev_err(dev, "Failed to init MU\n");
+		goto disable_clk;
+	}
 
 	spin_lock_init(&priv->xcr_lock);
 
@@ -878,10 +892,8 @@ static int imx_mu_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, priv);
 
 	ret = devm_mbox_controller_register(dev, &priv->mbox);
-	if (ret) {
-		clk_disable_unprepare(priv->clk);
-		return ret;
-	}
+	if (ret)
+		goto disable_clk;
 
 	pm_runtime_enable(dev);
 
@@ -899,6 +911,7 @@ static int imx_mu_probe(struct platform_device *pdev)
 
 disable_runtime_pm:
 	pm_runtime_disable(dev);
+disable_clk:
 	clk_disable_unprepare(priv->clk);
 	return ret;
 }

-- 
2.37.1



From peng.fan at oss.nxp.com  Sat Feb 17 22:56:15 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:56:15 +0800
Subject: [PATCH v7 3/6] mailbox: imx: get RR/TR registers num from
 Parameter register
In-Reply-To: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
References: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
Message-ID: <20240218-imx-mailbox-v7-3-8fb665eeae40@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX8ULP, i.MX93 MU has a Parameter register encoded as below:
BIT: 15 --- 8 | 7 --- 0
      RR_NUM    TR_NUM

So to make driver easy to support more variants, get the RR/TR
registers number from Parameter register.

The patch only adds support the specific MU, such as ELE MU.
For generic MU, not add support for number larger than 4.

Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 46 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index dced4614065f..9e89f773d2f9 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -29,7 +29,9 @@
 #define IMX_MU_S4_CHANS		2
 #define IMX_MU_CHAN_NAME_SIZE	20
 
-#define IMX_MU_NUM_RR		4
+#define IMX_MU_V2_PAR_OFF	0x4
+#define IMX_MU_V2_TR_MASK	GENMASK(7, 0)
+#define IMX_MU_V2_RR_MASK	GENMASK(15, 8)
 
 #define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000))
 #define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000))
@@ -93,10 +95,11 @@ struct imx_mu_priv {
 	struct clk		*clk;
 	int			irq[IMX_MU_CHANS];
 	bool			suspend;
-
-	u32 xcr[IMX_MU_xCR_MAX];
-
 	bool			side_b;
+
+	u32			xcr[IMX_MU_xCR_MAX];
+	u32			num_tr;
+	u32			num_rr;
 };
 
 enum imx_mu_type {
@@ -264,18 +267,17 @@ static int imx_mu_generic_rxdb(struct imx_mu_priv *priv,
 static int imx_mu_specific_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data)
 {
 	u32 *arg = data;
+	u32 num_tr = priv->num_tr;
 	int i, ret;
 	u32 xsr;
-	u32 size, max_size, num_tr;
+	u32 size, max_size;
 
 	if (priv->dcfg->type & IMX_MU_V2_S4) {
 		size = ((struct imx_s4_rpc_msg_max *)data)->hdr.size;
 		max_size = sizeof(struct imx_s4_rpc_msg_max);
-		num_tr = 8;
 	} else {
 		size = ((struct imx_sc_rpc_msg_max *)data)->hdr.size;
 		max_size = sizeof(struct imx_sc_rpc_msg_max);
-		num_tr = 4;
 	}
 
 	switch (cp->type) {
@@ -324,6 +326,7 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
 	int i, ret;
 	u32 xsr;
 	u32 size, max_size;
+	u32 num_rr = priv->num_rr;
 
 	data = (u32 *)priv->msg;
 
@@ -345,13 +348,13 @@ 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,
+					 xsr & IMX_MU_xSR_RFn(priv->dcfg->type, i % num_rr), 0,
 					 5 * USEC_PER_SEC);
 		if (ret) {
 			dev_err(priv->dev, "timeout read idx %d\n", i);
 			return ret;
 		}
-		*data++ = imx_mu_read(priv, priv->dcfg->xRR + (i % 4) * 4);
+		*data++ = imx_mu_read(priv, priv->dcfg->xRR + (i % num_rr) * 4);
 	}
 
 	imx_mu_xcr_rmw(priv, IMX_MU_RCR, IMX_MU_xCR_RIEn(priv->dcfg->type, 0), 0);
@@ -737,11 +740,30 @@ static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox,
 	return imx_mu_xlate(mbox, sp);
 }
 
+static void imx_mu_get_tr_rr(struct imx_mu_priv *priv)
+{
+	u32 val;
+
+	if (priv->dcfg->type & IMX_MU_V2) {
+		val = imx_mu_read(priv, IMX_MU_V2_PAR_OFF);
+		priv->num_tr = FIELD_GET(IMX_MU_V2_TR_MASK, val);
+		priv->num_rr = FIELD_GET(IMX_MU_V2_RR_MASK, val);
+	} else {
+		priv->num_tr = 4;
+		priv->num_rr = 4;
+	}
+}
+
 static int imx_mu_init_generic(struct imx_mu_priv *priv)
 {
 	unsigned int i;
 	unsigned int val;
 
+	if (priv->num_rr > 4 || priv->num_tr > 4) {
+		WARN_ONCE(true, "%s not support TR/RR larger than 4\n", __func__);
+		return -EOPNOTSUPP;
+	}
+
 	for (i = 0; i < IMX_MU_CHANS; i++) {
 		struct imx_mu_con_priv *cp = &priv->con_priv[i];
 
@@ -768,8 +790,8 @@ static int imx_mu_init_generic(struct imx_mu_priv *priv)
 	imx_mu_write(priv, val, priv->dcfg->xSR[IMX_MU_GSR]);
 
 	/* Clear any pending RSR */
-	for (i = 0; i < IMX_MU_NUM_RR; i++)
-		imx_mu_read(priv, priv->dcfg->xRR + (i % 4) * 4);
+	for (i = 0; i < priv->num_rr; i++)
+		imx_mu_read(priv, priv->dcfg->xRR + i * 4);
 
 	return 0;
 }
@@ -874,6 +896,8 @@ static int imx_mu_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	imx_mu_get_tr_rr(priv);
+
 	priv->side_b = of_property_read_bool(np, "fsl,mu-side-b");
 
 	ret = priv->dcfg->init(priv);

-- 
2.37.1



From peng.fan at oss.nxp.com  Sat Feb 17 22:56:16 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:56:16 +0800
Subject: [PATCH v7 4/6] tt
In-Reply-To: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
References: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
Message-ID: <20240218-imx-mailbox-v7-4-8fb665eeae40@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 9e89f773d2f9..306af1880415 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -4,6 +4,7 @@
  * Copyright 2022 NXP, Peng Fan <peng.fan at nxp.com>
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/firmware/imx/ipc.h>
 #include <linux/firmware/imx/s4.h>

-- 
2.37.1



From peng.fan at oss.nxp.com  Sat Feb 17 22:56:17 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:56:17 +0800
Subject: [PATCH v7 5/6] mailbox: imx: populate sub-nodes
In-Reply-To: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
References: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
Message-ID: <20240218-imx-mailbox-v7-5-8fb665eeae40@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Some MUs such as i.MX95 MU, have internal SRAM which could be used
for SCMI shared memory, so populate the sub-nodes to use the SRAM.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 306af1880415..b36267591db2 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -16,6 +16,7 @@
 #include <linux/mailbox_controller.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/suspend.h>
@@ -920,6 +921,8 @@ static int imx_mu_probe(struct platform_device *pdev)
 	if (ret)
 		goto disable_clk;
 
+	of_platform_populate(dev->of_node, NULL, NULL, dev);
+
 	pm_runtime_enable(dev);
 
 	ret = pm_runtime_resume_and_get(dev);

-- 
2.37.1



From peng.fan at oss.nxp.com  Sat Feb 17 22:56:18 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sun, 18 Feb 2024 14:56:18 +0800
Subject: [PATCH v7 6/6] mailbox: imx: support i.MX95 Generic/ELE/V2X MU
In-Reply-To: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
References: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
Message-ID: <20240218-imx-mailbox-v7-6-8fb665eeae40@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add i.MX95 Generic/ELE/V2X MU support, its register layout is same as
i.MX8ULP, but the Parameter registers would show different
TR/RR. Since the driver already supports get TR/RR from Parameter
registers, not hardcoding the number, this patch just add
the compatible entry to reuse i.MX8ULP S4 cfg data.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index b36267591db2..5c1d09cad761 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -1035,6 +1035,9 @@ static const struct of_device_id imx_mu_dt_ids[] = {
 	{ .compatible = "fsl,imx8ulp-mu", .data = &imx_mu_cfg_imx8ulp },
 	{ .compatible = "fsl,imx8ulp-mu-s4", .data = &imx_mu_cfg_imx8ulp_s4 },
 	{ .compatible = "fsl,imx93-mu-s4", .data = &imx_mu_cfg_imx93_s4 },
+	{ .compatible = "fsl,imx95-mu", .data = &imx_mu_cfg_imx8ulp },
+	{ .compatible = "fsl,imx95-mu-ele", .data = &imx_mu_cfg_imx8ulp_s4 },
+	{ .compatible = "fsl,imx95-mu-v2x", .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 },
 	{ },

-- 
2.37.1



From peng.fan at nxp.com  Sat Feb 17 22:48:36 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Sun, 18 Feb 2024 06:48:36 +0000
Subject: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
In-Reply-To: <CABb+yY3U5GzvznLDU7pyA1ppfLT50MQKQ3YRXB3rYwr_QwcH-g@mail.gmail.com>
References: <20240201-imx-mailbox-v6-0-76f4f35b403e@nxp.com>
 <PA4PR04MB941646795F4E19D1EC35134F88522@PA4PR04MB9416.eurprd04.prod.outlook.com>
 <CABb+yY0aM9Dn3LPBqb11vU3Ln4bCCGOBXX77sF499cyb_sXiUA@mail.gmail.com>
 <DU0PR04MB94170454D64EF65E6774BEAB88522@DU0PR04MB9417.eurprd04.prod.outlook.com>
 <CABb+yY3U5GzvznLDU7pyA1ppfLT50MQKQ3YRXB3rYwr_QwcH-g@mail.gmail.com>
Message-ID: <DU0PR04MB94173DAFBB30F61807396DB088522@DU0PR04MB9417.eurprd04.prod.outlook.com>

Hi Jassi,

> Subject: Re: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
> 
> On Sat, Feb 17, 2024 at 8:10?PM Peng Fan <peng.fan at nxp.com> wrote:
> >
> > Hi Jassi,
> >
> > > Subject: Re: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
> > >
> > > Hi Peng,
> > >
> > > On Sat, Feb 17, 2024 at 7:38?PM Peng Fan <peng.fan at nxp.com> wrote:
> > > >
> > > > Hi Jassi
> > > >
> > > > > Subject: [PATCH v6 0/4] mailbox: imx: support i.MX95 ELE/V2X MU
> > > > >
> > > > > - Add dt-bindings
> > > > > - i.MX95 ELE/V2X use same register layout as i.MX8ULP S4 MU, but
> > > > >   the TR/RR num is different. To make code reusable and not add
> > > > > too
> > > much
> > > > >   macros, add runtime detect number of TR and RR by reading
> PAR_OFF
> > > > >   registers.
> > > > > - Add i.MX95 ELE/V2X MU entry in driver
> > > >
> > > > Ping..
> > > >
> > > dt bindings and compatibles first need to be acked by dt maintainers.
> >
> > The bindings has been reviewed by Conor Dooley who listed as maintainer:
> > OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
> > M:      Rob Herring <robh+dt at kernel.org>
> > M:      Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> > M:      Conor Dooley <conor+dt at kernel.org>
> >
> Ok, I didn't realise we have three maintainers now.
> 
> I see no problem other than adding of_platform_populate() and compatibles
> in the same patch. They should be separate.

Just posted out V7 to address this, please have a look.

Thanks,
Peng.

> 
> cheers.

From zhangzj at rock-chips.com  Sat Feb 17 22:54:07 2024
From: zhangzj at rock-chips.com (Elon Zhang)
Date: Sun, 18 Feb 2024 14:54:07 +0800
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add devicetree support for TB-RK3588X board
Message-ID: <20240218065407.652213-1-zhangzj@rock-chips.com>

Add board file for Rockchip Toybrick TB-RK3588X board.

Specification:
	Rockchip Rk3588 SoC
	4x ARM Cortex-A76, 4x ARM Cortex-A55
	8/16GB Memory LPDDR4x
	Mali G610MC4 GPU
	2? MIPI-CSI0 Connector
	1x 2Lanes PCIe3.0 Connector
	1x SATA3.0 Connector
	32GB eMMC Module
	2x USB 2.0, 2x USB 3.0
	1x HDMI Output, 1x HDMI Input
	2x Ethernet Port

Functions work normally:
	[1] USB2.0 Host
	[2] Ethernet0 with PHY RTL8211F

More information can be obtained from the following websites:
	[1] https://t.rock-chips.com/en/wiki/EN/tb-rk3588x_en/index.html
	[2] http://t.rock-chips.com/

Signed-off-by: Elon Zhang <zhangzj at rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3588-toybrick-x0.dts  | 672 ++++++++++++++++++
 2 files changed, 673 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index a7b30e11beaf..e0722b6e2d99 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -110,6 +110,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-orangepi-5-plus.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-quartzpro64.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-toybrick-x0.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-turing-rk1.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-coolpi-4b.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
new file mode 100644
index 000000000000..ef7e5ee75021
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
@@ -0,0 +1,672 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588.dtsi"
+
+/ {
+	model = "Rockchip Toybrick TB-RK3588X Board";
+	compatible = "rockchip,rk3588-toybrick-x0", "rockchip,rk3588";
+
+	aliases {
+		mmc0 = &sdhci;
+		serial2 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-vol-up {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <17000>;
+		};
+
+		button-vol-down {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			press-threshold-microvolt = <417000>;
+		};
+
+		button-menu {
+			label = "Menu";
+			linux,code = <KEY_MENU>;
+			press-threshold-microvolt = <890000>;
+		};
+
+		button-escape {
+			label = "Escape";
+			linux,code = <KEY_ESC>;
+			press-threshold-microvolt = <1235000>;
+		};
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		power-supply = <&vcc12v_dcin>;
+		pwms = <&pwm2 0 25000 0>;
+	};
+
+	pcie20_avdd0v85: pcie20-avdd0v85-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie20_avdd0v85";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <850000>;
+		regulator-max-microvolt = <850000>;
+		vin-supply = <&vdd_0v85_s0>;
+	};
+
+	pcie20_avdd1v8: pcie20-avdd1v8-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie20_avdd1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&avcc_1v8_s0>;
+	};
+
+	pcie30_avdd0v75: pcie30-avdd0v75-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie30_avdd0v75";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <750000>;
+		regulator-max-microvolt = <750000>;
+		vin-supply = <&avdd_0v75_s0>;
+	};
+
+	pcie30_avdd1v8: pcie30-avdd1v8-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie30_avdd1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&avcc_1v8_s0>;
+	};
+
+	vcc12v_dcin: vcc12v-dcin-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc5v0_host: vcc5v0-host-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_host";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_host_en>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usbdcin: vcc5v0-usbdcin-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usbdcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usb: vcc5v0-usb-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usb";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usbdcin>;
+	};
+
+	vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v1_nldo_s3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+};
+
+&combphy0_ps {
+	status = "okay";
+};
+
+&combphy2_psu {
+	status = "okay";
+};
+
+&cpu_b0 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gmac0 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy>;
+	phy-mode = "rgmii-rxid";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+	pinctrl-names = "default";
+	rx_delay = <0x00>;
+	tx_delay = <0x43>;
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0m2_xfer>;
+	status = "okay";
+
+	vdd_cpu_big0_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu_big0_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	vdd_cpu_big1_s0: regulator at 43 {
+		compatible = "rockchip,rk8603", "rockchip,rk8602";
+		reg = <0x43>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu_big1_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	hym8563: rtc at 51 {
+		compatible = "haoyu,hym8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+		clock-output-names = "hym8563";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hym8563_int>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PD4 IRQ_TYPE_LEVEL_LOW>;
+		wakeup-source;
+	};
+};
+
+&mdio0 {
+	rgmii_phy: ethernet-phy at 1 {
+		/* RTL8211F */
+		compatible = "ethernet-phy-id001c.c916";
+		reg = <0x1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtl8211f_rst>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pinctrl {
+	rtl8211f {
+		rtl8211f_rst: rtl8211f-rst {
+			rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+	};
+
+	hym8563 {
+		hym8563_int: hym8563-int {
+			rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	usb {
+		vcc5v0_host_en: vcc5v0-host-en {
+			rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pwm2 {
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcc_1v8_s0>;
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	no-sdio;
+	no-sd;
+	non-removable;
+	mmc-hs400-1_8v;
+	mmc-hs400-enhanced-strobe;
+	status = "okay";
+};
+
+&spi2 {
+	status = "okay";
+	assigned-clocks = <&cru CLK_SPI2>;
+	assigned-clock-rates = <200000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+	num-cs = <1>;
+
+	pmic at 0 {
+		compatible = "rockchip,rk806";
+		spi-max-frequency = <1000000>;
+		reg = <0x0>;
+
+		interrupt-parent = <&gpio0>;
+		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+		system-power-controller;
+
+		vcc1-supply = <&vcc5v0_sys>;
+		vcc2-supply = <&vcc5v0_sys>;
+		vcc3-supply = <&vcc5v0_sys>;
+		vcc4-supply = <&vcc5v0_sys>;
+		vcc5-supply = <&vcc5v0_sys>;
+		vcc6-supply = <&vcc5v0_sys>;
+		vcc7-supply = <&vcc5v0_sys>;
+		vcc8-supply = <&vcc5v0_sys>;
+		vcc9-supply = <&vcc5v0_sys>;
+		vcc10-supply = <&vcc5v0_sys>;
+		vcc11-supply = <&vcc_2v0_pldo_s3>;
+		vcc12-supply = <&vcc5v0_sys>;
+		vcc13-supply = <&vcc_1v1_nldo_s3>;
+		vcc14-supply = <&vcc_1v1_nldo_s3>;
+		vcca-supply = <&vcc5v0_sys>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		rk806_dvs1_null: dvs1-null-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs2_null: dvs2-null-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs3_null: dvs3-null-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun0";
+		};
+
+		regulators {
+			vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_gpu_s0";
+				regulator-enable-ramp-delay = <400>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_cpu_lit_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_log_s0: dcdc-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <750000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_log_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-init-microvolt = <750000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_vdenc_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_ddr_s0: dcdc-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <900000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_ddr_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vdd2_ddr_s3: dcdc-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vdd2_ddr_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_2v0_pldo_s3: dcdc-reg7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <2000000>;
+				regulator-max-microvolt = <2000000>;
+				regulator-name = "vdd_2v0_pldo_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <2000000>;
+				};
+			};
+
+			vcc_3v3_s3: dcdc-reg8 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_3v3_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vddq_ddr_s0: dcdc-reg9 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vddq_ddr_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s3: dcdc-reg10 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			avcc_1v8_s0: pldo-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "avcc_1v8_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s0: pldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			avdd_1v2_s0: pldo-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-name = "avdd_1v2_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3_s0: pldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_3v3_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd_s0: pldo-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_sd_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			pldo6_s3: pldo-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "pldo6_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_0v75_s3: nldo-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdd_0v75_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_ddr_pll_s0: nldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdd_ddr_pll_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			avdd_0v75_s0: nldo-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <837500>;
+				regulator-max-microvolt = <837500>;
+				regulator-name = "avdd_0v75_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_0v85_s0: nldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdd_0v85_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_0v75_s0: nldo-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdd_0v75_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&u2phy2 {
+	status = "okay";
+};
+
+&u2phy2_host {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+&u2phy3 {
+	status = "okay";
+};
+
+&u2phy3_host {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-0 = <&uart2m0_xfer>;
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
-- 
2.34.1



From tongtiangen at huawei.com  Sat Feb 17 23:05:51 2024
From: tongtiangen at huawei.com (Tong Tiangen)
Date: Sun, 18 Feb 2024 15:05:51 +0800
Subject: [PATCH v11 0/5]arm64: add ARCH_HAS_COPY_MC support
In-Reply-To: <20240207132204.1720444-1-tongtiangen@huawei.com>
References: <20240207132204.1720444-1-tongtiangen@huawei.com>
Message-ID: <c49c2651-8a7a-286f-deaf-575510e5d3a5@huawei.com>

Hi Mark:

Kindly ping :)

Thanks.
Tong.

? 2024/2/7 21:21, Tong Tiangen ??:
> With the increase of memory capacity and density, the probability of memory
> error also increases. The increasing size and density of server RAM in data
> centers and clouds have shown increased uncorrectable memory errors.
> 
> Currently, more and more scenarios that can tolerate memory errors?such as
> CoW[1,2], KSM copy[3], coredump copy[4], khugepaged[5,6], uaccess copy[7],
> etc.
> 
> This patchset introduces a new processing framework on ARM64, which enables
> ARM64 to support error recovery in the above scenarios, and more scenarios
> can be expanded based on this in the future.
> 
> In arm64, memory error handling in do_sea(), which is divided into two cases:
>   1. If the user state consumed the memory errors, the solution is to kill
>      the user process and isolate the error page.
>   2. If the kernel state consumed the memory errors, the solution is to
>      panic.
> 
> For case 2, Undifferentiated panic may not be the optimal choice, as it can
> be handled better. In some scenarios, we can avoid panic, such as uaccess,
> if the uaccess fails due to memory error, only the user process will be
> affected, killing the user process and isolating the user page with
> hardware memory errors is a better choice.
> 
> [1] commit d302c2398ba2 ("mm, hwpoison: when copy-on-write hits poison, take page offline")
> [2] commit 1cb9dc4b475c ("mm: hwpoison: support recovery from HugePage copy-on-write faults")
> [3] commit 6b970599e807 ("mm: hwpoison: support recovery from ksm_might_need_to_copy()")
> [4] commit 245f09226893 ("mm: hwpoison: coredump: support recovery from dump_user_range()")
> [5] commit 98c76c9f1ef7 ("mm/khugepaged: recover from poisoned anonymous memory")
> [6] commit 12904d953364 ("mm/khugepaged: recover from poisoned file-backed memory")
> [7] commit 278b917f8cb9 ("x86/mce: Add _ASM_EXTABLE_CPY for copy user access")
> 
> ------------------
> Test result:
> 
> 1. copy_page(), copy_mc_page() basic function test pass, and the disassembly
>     contents remains the same before and after refactor.
> 
> 2. copy_to/from_user() access kernel NULL pointer raise translation fault
>     and dump error message then die(), test pass.
> 
> 3. Test following scenarios: copy_from_user(), get_user(), COW.
> 
>     Before patched: trigger a hardware memory error then panic.
>     After  patched: trigger a hardware memory error without panic.
> 
>     Testing step:
>     step1. start an user-process.
>     step2. poison(einj) the user-process's page.
>     step3: user-process access the poison page in kernel mode, then trigger SEA.
>     step4: the kernel will not panic, only the user process is killed, the poison
>            page is isolated. (before patched, the kernel will panic in do_sea())
> 
> ------------------
> 
> Since V10:
>   Accroding Mark's suggestion:
>   1. Merge V10's patch2 and patch3 to V11's patch2.
>   2. Patch2(V11): use new fixup_type for ld* in copy_to_user(), fix fatal
>      issues (NULL kernel pointeraccess) been fixup incorrectly.
>   3. Patch2(V11): refactoring the logic of do_sea().
>   4. Patch4(V11): Remove duplicate assembly logic and remove do_mte().
> 
>   Besides:
>   1. Patch2(V11): remove st* insn's fixup, st* generally not trigger memory error.
>   2. Split a part of the logic of patch2(V11) to patch5(V11), for detail,
>      see patch5(V11)'s commit msg.
>   3. Remove patch6(v10) ?arm64: introduce copy_mc_to_kernel() implementation?.
>      During modification, some problems that cannot be solved in a short
>      period are found. The patch will be released after the problems are
>      solved.
>   4. Add test result in this patch.
>   5. Modify patchset title, do not use machine check and remove "-next".
> 
> Since V9:
>   1. Rebase to latest kernel version 6.8-rc2.
>   2. Add patch 6/6 to support copy_mc_to_kernel().
> 
> Since V8:
>   1. Rebase to latest kernel version and fix topo in some of the patches.
>   2. According to the suggestion of Catalin, I attempted to modify the
>      return value of function copy_mc_[user]_highpage() to bytes not copied.
>      During the modification process, I found that it would be more
>      reasonable to return -EFAULT when copy error occurs (referring to the
>      newly added patch 4).
> 
>      For ARM64, the implementation of copy_mc_[user]_highpage() needs to
>      consider MTE. Considering the scenario where data copying is successful
>      but the MTE tag copying fails, it is also not reasonable to return
>      bytes not copied.
>   3. Considering the recent addition of machine check safe support for
>      multiple scenarios, modify commit message for patch 5 (patch 4 for V8).
> 
> Since V7:
>   Currently, there are patches supporting recover from poison
>   consumption for the cow scenario[1]. Therefore, Supporting cow
>   scenario under the arm64 architecture only needs to modify the relevant
>   code under the arch/.
>   [1]https://lore.kernel.org/lkml/20221031201029.102123-1-tony.luck at intel.com/
> 
> Since V6:
>   Resend patches that are not merged into the mainline in V6.
> 
> Since V5:
>   1. Add patch2/3 to add uaccess assembly helpers.
>   2. Optimize the implementation logic of arm64_do_kernel_sea() in patch8.
>   3. Remove kernel access fixup in patch9.
>   All suggestion are from Mark.
> 
> Since V4:
>   1. According Michael's suggestion, add patch5.
>   2. According Mark's suggestiog, do some restructuring to arm64
>   extable, then a new adaptation of machine check safe support is made based
>   on this.
>   3. According Mark's suggestion, support machine check safe in do_mte() in
>   cow scene.
>   4. In V4, two patches have been merged into -next, so V5 not send these
>   two patches.
> 
> Since V3:
>   1. According to Robin's suggestion, direct modify user_ldst and
>   user_ldp in asm-uaccess.h and modify mte.S.
>   2. Add new macro USER_MC in asm-uaccess.h, used in copy_from_user.S
>   and copy_to_user.S.
>   3. According to Robin's suggestion, using micro in copy_page_mc.S to
>   simplify code.
>   4. According to KeFeng's suggestion, modify powerpc code in patch1.
>   5. According to KeFeng's suggestion, modify mm/extable.c and some code
>   optimization.
> 
> Since V2:
>   1. According to Mark's suggestion, all uaccess can be recovered due to
>      memory error.
>   2. Scenario pagecache reading is also supported as part of uaccess
>      (copy_to_user()) and duplication code problem is also solved.
>      Thanks for Robin's suggestion.
>   3. According Mark's suggestion, update commit message of patch 2/5.
>   4. According Borisllav's suggestion, update commit message of patch 1/5.
> 
> Since V1:
>   1.Consistent with PPC/x86, Using CONFIG_ARCH_HAS_COPY_MC instead of
>     ARM64_UCE_KERNEL_RECOVERY.
>   2.Add two new scenes, cow and pagecache reading.
>   3.Fix two small bug(the first two patch).
> 
> V1 in here:
> https://lore.kernel.org/lkml/20220323033705.3966643-1-tongtiangen at huawei.com/
> 
> Tong Tiangen (5):
>    uaccess: add generic fallback version of copy_mc_to_user()
>    arm64: add support for ARCH_HAS_COPY_MC
>    mm/hwpoison: return -EFAULT when copy fail in
>      copy_mc_[user]_highpage()
>    arm64: support copy_mc_[user]_highpage()
>    arm64: send SIGBUS to user process for SEA exception
> 
>   arch/arm64/Kconfig                   |  1 +
>   arch/arm64/include/asm/asm-extable.h | 31 ++++++++++++---
>   arch/arm64/include/asm/asm-uaccess.h |  4 ++
>   arch/arm64/include/asm/extable.h     |  1 +
>   arch/arm64/include/asm/mte.h         |  9 +++++
>   arch/arm64/include/asm/page.h        | 10 +++++
>   arch/arm64/lib/Makefile              |  2 +
>   arch/arm64/lib/copy_mc_page.S        | 37 ++++++++++++++++++
>   arch/arm64/lib/copy_page.S           | 50 +++----------------------
>   arch/arm64/lib/copy_page_template.S  | 56 ++++++++++++++++++++++++++++
>   arch/arm64/lib/copy_to_user.S        | 10 ++---
>   arch/arm64/lib/mte.S                 | 29 ++++++++++++++
>   arch/arm64/mm/copypage.c             | 45 ++++++++++++++++++++++
>   arch/arm64/mm/extable.c              | 19 ++++++++++
>   arch/arm64/mm/fault.c                | 39 ++++++++++++++-----
>   arch/powerpc/include/asm/uaccess.h   |  1 +
>   arch/x86/include/asm/uaccess.h       |  1 +
>   include/linux/highmem.h              | 16 ++++++--
>   include/linux/uaccess.h              |  9 +++++
>   mm/khugepaged.c                      |  4 +-
>   20 files changed, 304 insertions(+), 70 deletions(-)
>   create mode 100644 arch/arm64/lib/copy_mc_page.S
>   create mode 100644 arch/arm64/lib/copy_page_template.S
> 


From o451686892 at gmail.com  Sun Feb 18 00:07:08 2024
From: o451686892 at gmail.com (Weizhao Ouyang)
Date: Sun, 18 Feb 2024 16:07:08 +0800
Subject: [PATCH v1 1/1] arm64: dts: rockchip: Add devicetree support for
 TB-RK3588X board
In-Reply-To: <20240218065407.652213-1-zhangzj@rock-chips.com>
References: <20240218065407.652213-1-zhangzj@rock-chips.com>
Message-ID: <CAHk0Hov1dryZmwxo40wnzExtHPSRxHOmU_0T3BPDXVZ8k75JZw@mail.gmail.com>

Hi Elon,

On Sun, Feb 18, 2024 at 2:54?PM Elon Zhang <zhangzj at rock-chips.com> wrote:
>
> Add board file for Rockchip Toybrick TB-RK3588X board.
>
> Specification:
>         Rockchip Rk3588 SoC
>         4x ARM Cortex-A76, 4x ARM Cortex-A55
>         8/16GB Memory LPDDR4x
>         Mali G610MC4 GPU
>         2? MIPI-CSI0 Connector
>         1x 2Lanes PCIe3.0 Connector
>         1x SATA3.0 Connector
>         32GB eMMC Module
>         2x USB 2.0, 2x USB 3.0
>         1x HDMI Output, 1x HDMI Input
>         2x Ethernet Port
>
> Functions work normally:
>         [1] USB2.0 Host
>         [2] Ethernet0 with PHY RTL8211F
>
> More information can be obtained from the following websites:
>         [1] https://t.rock-chips.com/en/wiki/EN/tb-rk3588x_en/index.html
>         [2] http://t.rock-chips.com/
>
> Signed-off-by: Elon Zhang <zhangzj at rock-chips.com>
> ---
>  arch/arm64/boot/dts/rockchip/Makefile         |   1 +
>  .../boot/dts/rockchip/rk3588-toybrick-x0.dts  | 672 ++++++++++++++++++
>  2 files changed, 673 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
>
> diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
> index a7b30e11beaf..e0722b6e2d99 100644
> --- a/arch/arm64/boot/dts/rockchip/Makefile
> +++ b/arch/arm64/boot/dts/rockchip/Makefile
> @@ -110,6 +110,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-orangepi-5-plus.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-quartzpro64.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-toybrick-x0.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-turing-rk1.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-coolpi-4b.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
> new file mode 100644
> index 000000000000..ef7e5ee75021
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
> @@ -0,0 +1,672 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2021 Rockchip Electronics Co., Ltd.

Do we need to update the copyright?

> + *
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +#include "rk3588.dtsi"
> +
> +/ {
> +       model = "Rockchip Toybrick TB-RK3588X Board";
> +       compatible = "rockchip,rk3588-toybrick-x0", "rockchip,rk3588";

"rockchip,rk3588-toybrick-x0" needs to be synchronized in
"Documentation/devicetree/bindings/arm/rockchip.yaml".

> +
> +       aliases {
> +               mmc0 = &sdhci;
> +               serial2 = &uart2;
> +       };
> +
> +       chosen {
> +               stdout-path = "serial2:1500000n8";
> +       };
> +
> +       adc-keys {
> +               compatible = "adc-keys";
> +               io-channels = <&saradc 1>;
> +               io-channel-names = "buttons";
> +               keyup-threshold-microvolt = <1800000>;
> +               poll-interval = <100>;
> +
> +               button-vol-up {
> +                       label = "Volume Up";
> +                       linux,code = <KEY_VOLUMEUP>;
> +                       press-threshold-microvolt = <17000>;
> +               };
> +
> +               button-vol-down {
> +                       label = "Volume Down";
> +                       linux,code = <KEY_VOLUMEDOWN>;
> +                       press-threshold-microvolt = <417000>;
> +               };
> +
> +               button-menu {
> +                       label = "Menu";
> +                       linux,code = <KEY_MENU>;
> +                       press-threshold-microvolt = <890000>;
> +               };
> +
> +               button-escape {
> +                       label = "Escape";
> +                       linux,code = <KEY_ESC>;
> +                       press-threshold-microvolt = <1235000>;
> +               };
> +       };
> +
> +       backlight: backlight {
> +               compatible = "pwm-backlight";
> +               power-supply = <&vcc12v_dcin>;
> +               pwms = <&pwm2 0 25000 0>;
> +       };
> +
> +       pcie20_avdd0v85: pcie20-avdd0v85-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "pcie20_avdd0v85";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <850000>;
> +               regulator-max-microvolt = <850000>;
> +               vin-supply = <&vdd_0v85_s0>;
> +       };
> +
> +       pcie20_avdd1v8: pcie20-avdd1v8-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "pcie20_avdd1v8";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <1800000>;
> +               regulator-max-microvolt = <1800000>;
> +               vin-supply = <&avcc_1v8_s0>;
> +       };
> +
> +       pcie30_avdd0v75: pcie30-avdd0v75-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "pcie30_avdd0v75";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <750000>;
> +               regulator-max-microvolt = <750000>;
> +               vin-supply = <&avdd_0v75_s0>;
> +       };
> +
> +       pcie30_avdd1v8: pcie30-avdd1v8-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "pcie30_avdd1v8";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <1800000>;
> +               regulator-max-microvolt = <1800000>;
> +               vin-supply = <&avcc_1v8_s0>;
> +       };
> +
> +       vcc12v_dcin: vcc12v-dcin-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc12v_dcin";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <12000000>;
> +               regulator-max-microvolt = <12000000>;
> +       };
> +
> +       vcc5v0_host: vcc5v0-host-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc5v0_host";
> +               regulator-boot-on;
> +               regulator-always-on;
> +               regulator-min-microvolt = <5000000>;
> +               regulator-max-microvolt = <5000000>;
> +               enable-active-high;
> +               gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&vcc5v0_host_en>;
> +               vin-supply = <&vcc5v0_usb>;
> +       };
> +
> +       vcc5v0_sys: vcc5v0-sys-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc5v0_sys";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <5000000>;
> +               regulator-max-microvolt = <5000000>;
> +               vin-supply = <&vcc12v_dcin>;
> +       };
> +
> +       vcc5v0_usbdcin: vcc5v0-usbdcin-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc5v0_usbdcin";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <5000000>;
> +               regulator-max-microvolt = <5000000>;
> +               vin-supply = <&vcc12v_dcin>;
> +       };
> +
> +       vcc5v0_usb: vcc5v0-usb-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc5v0_usb";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <5000000>;
> +               regulator-max-microvolt = <5000000>;
> +               vin-supply = <&vcc5v0_usbdcin>;
> +       };
> +
> +       vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc_1v1_nldo_s3";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <1100000>;
> +               regulator-max-microvolt = <1100000>;
> +               vin-supply = <&vcc5v0_sys>;
> +       };
> +};
> +
> +&combphy0_ps {
> +       status = "okay";
> +};
> +
> +&combphy2_psu {
> +       status = "okay";
> +};
> +
> +&cpu_b0 {
> +       cpu-supply = <&vdd_cpu_big0_s0>;
> +};
> +
> +&cpu_b1 {
> +       cpu-supply = <&vdd_cpu_big0_s0>;
> +};
> +
> +&cpu_b2 {
> +       cpu-supply = <&vdd_cpu_big1_s0>;
> +};
> +
> +&cpu_b3 {
> +       cpu-supply = <&vdd_cpu_big1_s0>;
> +};
> +
> +&cpu_l0 {
> +       cpu-supply = <&vdd_cpu_lit_s0>;
> +};
> +
> +&cpu_l1 {
> +       cpu-supply = <&vdd_cpu_lit_s0>;
> +};
> +
> +&cpu_l2 {
> +       cpu-supply = <&vdd_cpu_lit_s0>;
> +};
> +
> +&cpu_l3 {
> +       cpu-supply = <&vdd_cpu_lit_s0>;
> +};
> +
> +&gmac0 {
> +       clock_in_out = "output";
> +       phy-handle = <&rgmii_phy>;
> +       phy-mode = "rgmii-rxid";
> +       pinctrl-0 = <&gmac0_miim
> +                    &gmac0_tx_bus2
> +                    &gmac0_rx_bus2
> +                    &gmac0_rgmii_clk
> +                    &gmac0_rgmii_bus>;
> +       pinctrl-names = "default";
> +       rx_delay = <0x00>;
> +       tx_delay = <0x43>;
> +       status = "okay";
> +};
> +
> +&i2c0 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&i2c0m2_xfer>;
> +       status = "okay";
> +
> +       vdd_cpu_big0_s0: regulator at 42 {
> +               compatible = "rockchip,rk8602";
> +               reg = <0x42>;
> +               fcs,suspend-voltage-selector = <1>;
> +               regulator-name = "vdd_cpu_big0_s0";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <550000>;
> +               regulator-max-microvolt = <1050000>;
> +               regulator-ramp-delay = <2300>;
> +               vin-supply = <&vcc5v0_sys>;
> +
> +               regulator-state-mem {
> +                       regulator-off-in-suspend;
> +               };
> +       };
> +
> +       vdd_cpu_big1_s0: regulator at 43 {
> +               compatible = "rockchip,rk8603", "rockchip,rk8602";
> +               reg = <0x43>;
> +               fcs,suspend-voltage-selector = <1>;
> +               regulator-name = "vdd_cpu_big1_s0";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <550000>;
> +               regulator-max-microvolt = <1050000>;
> +               regulator-ramp-delay = <2300>;
> +               vin-supply = <&vcc5v0_sys>;
> +
> +               regulator-state-mem {
> +                       regulator-off-in-suspend;
> +               };
> +       };
> +};
> +
> +&i2c2 {
> +       status = "okay";
> +
> +       hym8563: rtc at 51 {
> +               compatible = "haoyu,hym8563";
> +               reg = <0x51>;
> +               #clock-cells = <0>;
> +               clock-output-names = "hym8563";
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&hym8563_int>;
> +               interrupt-parent = <&gpio0>;
> +               interrupts = <RK_PD4 IRQ_TYPE_LEVEL_LOW>;
> +               wakeup-source;
> +       };
> +};
> +
> +&mdio0 {
> +       rgmii_phy: ethernet-phy at 1 {
> +               /* RTL8211F */
> +               compatible = "ethernet-phy-id001c.c916";
> +               reg = <0x1>;
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&rtl8211f_rst>;
> +               reset-assert-us = <20000>;
> +               reset-deassert-us = <100000>;
> +               reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
> +       };
> +};
> +
> +&pinctrl {
> +       rtl8211f {
> +               rtl8211f_rst: rtl8211f-rst {
> +                       rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
> +               };
> +
> +       };
> +
> +       hym8563 {
> +               hym8563_int: hym8563-int {
> +                       rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
> +               };
> +       };
> +
> +       usb {
> +               vcc5v0_host_en: vcc5v0-host-en {
> +                       rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
> +               };
> +       };
> +};
> +
> +&pwm2 {
> +       status = "okay";
> +};
> +
> +&saradc {
> +       vref-supply = <&vcc_1v8_s0>;
> +       status = "okay";
> +};
> +
> +&sdhci {
> +       bus-width = <8>;
> +       no-sdio;
> +       no-sd;
> +       non-removable;
> +       mmc-hs400-1_8v;
> +       mmc-hs400-enhanced-strobe;
> +       status = "okay";
> +};
> +
> +&spi2 {
> +       status = "okay";
> +       assigned-clocks = <&cru CLK_SPI2>;
> +       assigned-clock-rates = <200000000>;
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
> +       num-cs = <1>;
> +
> +       pmic at 0 {
> +               compatible = "rockchip,rk806";
> +               spi-max-frequency = <1000000>;
> +               reg = <0x0>;
> +
> +               interrupt-parent = <&gpio0>;
> +               interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
> +
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
> +                           <&rk806_dvs2_null>, <&rk806_dvs3_null>;
> +
> +               system-power-controller;
> +
> +               vcc1-supply = <&vcc5v0_sys>;
> +               vcc2-supply = <&vcc5v0_sys>;
> +               vcc3-supply = <&vcc5v0_sys>;
> +               vcc4-supply = <&vcc5v0_sys>;
> +               vcc5-supply = <&vcc5v0_sys>;
> +               vcc6-supply = <&vcc5v0_sys>;
> +               vcc7-supply = <&vcc5v0_sys>;
> +               vcc8-supply = <&vcc5v0_sys>;
> +               vcc9-supply = <&vcc5v0_sys>;
> +               vcc10-supply = <&vcc5v0_sys>;
> +               vcc11-supply = <&vcc_2v0_pldo_s3>;
> +               vcc12-supply = <&vcc5v0_sys>;
> +               vcc13-supply = <&vcc_1v1_nldo_s3>;
> +               vcc14-supply = <&vcc_1v1_nldo_s3>;
> +               vcca-supply = <&vcc5v0_sys>;
> +
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +
> +               rk806_dvs1_null: dvs1-null-pins {
> +                       pins = "gpio_pwrctrl1";
> +                       function = "pin_fun0";
> +               };
> +
> +               rk806_dvs2_null: dvs2-null-pins {
> +                       pins = "gpio_pwrctrl2";
> +                       function = "pin_fun0";
> +               };
> +
> +               rk806_dvs3_null: dvs3-null-pins {
> +                       pins = "gpio_pwrctrl3";
> +                       function = "pin_fun0";
> +               };
> +
> +               regulators {
> +                       vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <550000>;
> +                               regulator-max-microvolt = <950000>;
> +                               regulator-ramp-delay = <12500>;
> +                               regulator-name = "vdd_gpu_s0";
> +                               regulator-enable-ramp-delay = <400>;
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <550000>;
> +                               regulator-max-microvolt = <950000>;
> +                               regulator-ramp-delay = <12500>;
> +                               regulator-name = "vdd_cpu_lit_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vdd_log_s0: dcdc-reg3 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <675000>;
> +                               regulator-max-microvolt = <750000>;
> +                               regulator-ramp-delay = <12500>;
> +                               regulator-name = "vdd_log_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                                       regulator-suspend-microvolt = <750000>;
> +                               };
> +                       };
> +
> +                       vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <550000>;
> +                               regulator-max-microvolt = <950000>;
> +                               regulator-init-microvolt = <750000>;
> +                               regulator-ramp-delay = <12500>;
> +                               regulator-name = "vdd_vdenc_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vdd_ddr_s0: dcdc-reg5 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <675000>;
> +                               regulator-max-microvolt = <900000>;
> +                               regulator-ramp-delay = <12500>;
> +                               regulator-name = "vdd_ddr_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                                       regulator-suspend-microvolt = <850000>;
> +                               };
> +                       };
> +
> +                       vdd2_ddr_s3: dcdc-reg6 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-name = "vdd2_ddr_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                               };
> +                       };
> +
> +                       vcc_2v0_pldo_s3: dcdc-reg7 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <2000000>;
> +                               regulator-max-microvolt = <2000000>;
> +                               regulator-name = "vdd_2v0_pldo_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                                       regulator-suspend-microvolt = <2000000>;
> +                               };
> +                       };
> +
> +                       vcc_3v3_s3: dcdc-reg8 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <3300000>;
> +                               regulator-max-microvolt = <3300000>;
> +                               regulator-name = "vcc_3v3_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                                       regulator-suspend-microvolt = <3300000>;
> +                               };
> +                       };
> +
> +                       vddq_ddr_s0: dcdc-reg9 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-name = "vddq_ddr_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vcc_1v8_s3: dcdc-reg10 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1800000>;
> +                               regulator-max-microvolt = <1800000>;
> +                               regulator-name = "vcc_1v8_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                                       regulator-suspend-microvolt = <1800000>;
> +                               };
> +                       };
> +
> +                       avcc_1v8_s0: pldo-reg1 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1800000>;
> +                               regulator-max-microvolt = <1800000>;
> +                               regulator-name = "avcc_1v8_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vcc_1v8_s0: pldo-reg2 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1800000>;
> +                               regulator-max-microvolt = <1800000>;
> +                               regulator-name = "vcc_1v8_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                                       regulator-suspend-microvolt = <1800000>;
> +                               };
> +                       };
> +
> +                       avdd_1v2_s0: pldo-reg3 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1200000>;
> +                               regulator-max-microvolt = <1200000>;
> +                               regulator-name = "avdd_1v2_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vcc_3v3_s0: pldo-reg4 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <3300000>;
> +                               regulator-max-microvolt = <3300000>;
> +                               regulator-name = "vcc_3v3_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vccio_sd_s0: pldo-reg5 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1800000>;
> +                               regulator-max-microvolt = <3300000>;
> +                               regulator-name = "vccio_sd_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       pldo6_s3: pldo-reg6 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1800000>;
> +                               regulator-max-microvolt = <1800000>;
> +                               regulator-name = "pldo6_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                                       regulator-suspend-microvolt = <1800000>;
> +                               };
> +                       };
> +
> +                       vdd_0v75_s3: nldo-reg1 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <750000>;
> +                               regulator-max-microvolt = <750000>;
> +                               regulator-name = "vdd_0v75_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                                       regulator-suspend-microvolt = <750000>;
> +                               };
> +                       };
> +
> +                       vdd_ddr_pll_s0: nldo-reg2 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <850000>;
> +                               regulator-max-microvolt = <850000>;
> +                               regulator-name = "vdd_ddr_pll_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                                       regulator-suspend-microvolt = <850000>;
> +                               };
> +                       };
> +
> +                       avdd_0v75_s0: nldo-reg3 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <837500>;
> +                               regulator-max-microvolt = <837500>;
> +                               regulator-name = "avdd_0v75_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vdd_0v85_s0: nldo-reg4 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <850000>;
> +                               regulator-max-microvolt = <850000>;
> +                               regulator-name = "vdd_0v85_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vdd_0v75_s0: nldo-reg5 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <750000>;
> +                               regulator-max-microvolt = <750000>;
> +                               regulator-name = "vdd_0v75_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +               };
> +       };
> +};
> +
> +&u2phy2 {
> +       status = "okay";
> +};
> +
> +&u2phy2_host {
> +       phy-supply = <&vcc5v0_host>;
> +       status = "okay";
> +};
> +
> +&u2phy3 {
> +       status = "okay";
> +};
> +
> +&u2phy3_host {
> +       phy-supply = <&vcc5v0_host>;
> +       status = "okay";
> +};
> +
> +&uart2 {
> +       pinctrl-0 = <&uart2m0_xfer>;
> +       status = "okay";
> +};
> +
> +&usb_host0_ehci {
> +       status = "okay";
> +};
> +
> +&usb_host0_ohci {
> +       status = "okay";
> +};
> +
> +&usb_host1_ehci {
> +       status = "okay";
> +};
> +
> +&usb_host1_ohci {
> +       status = "okay";
> +};
> --
> 2.34.1
>

BR,
Weizhao


From frank at oltmanns.dev  Sun Feb 18 00:29:15 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Sun, 18 Feb 2024 09:29:15 +0100
Subject: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum
 rate
In-Reply-To: <exb2lvjcozak5fayrgyenrd3ntii4jfxgvqork4klyz5pky2aq@dj2zyw5su6pv>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>
 <exb2lvjcozak5fayrgyenrd3ntii4jfxgvqork4klyz5pky2aq@dj2zyw5su6pv>
Message-ID: <874je6b2g4.fsf@oltmanns.dev>

Hi Maxime,

On 2024-02-08 at 13:16:27 +0100, Maxime Ripard <mripard at kernel.org> wrote:
> [[PGP Signed Part:Undecided]]
> On Mon, Feb 05, 2024 at 04:22:26PM +0100, Frank Oltmanns wrote:
>> According to the Allwinner User Manual, the Allwinner A64 requires
>> PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.
>>
>> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
>> ---
>>  drivers/clk/sunxi-ng/ccu_nkm.c | 13 +++++++++++++
>>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>>  2 files changed, 15 insertions(+)
>>
>> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
>> index 1168d894d636..7d135908d6e0 100644
>> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
>> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
>> @@ -181,6 +181,12 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
>>  	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
>>  		rate *= nkm->fixed_post_div;
>>
>> +	if (nkm->min_rate && rate < nkm->min_rate)
>> +		rate = nkm->min_rate;
>> +
>> +	if (nkm->max_rate && rate > nkm->max_rate)
>> +		rate = nkm->max_rate;
>> +
>
> This is provided by the clock range already. If you call
> clk_hw_set_rate_range, it should work just fine.

I have to admit, that I don't know that much about sunxi-ng or the CCF
and therefore humbly request some guidance.

I've looked at other examples of clk_hw_set_rate_range() usage and it
seems there is not a lot of adoption for this functionality even though
it was already introduced mid-2015. This makes me wonder, why that is.

Anyhow, it seems in all examples I found, clk_hw_set_rate_range() is
called immediately after registering the clk_hw. So, in the case of
sunxi-ng, we'd need to do that in sunxi_ccu_probe, which is a common
function for all sunxi-ng clock types. Correct?

If so, surely, you don't want me to introduce clock type specific code
to a common function, so I assume you want min_rate and max_rate to
become members of struct ccu_common. Correct?

If so, since there already are some clock types in sunxi-ng that support
having a minimum and maximum rate, these clocks should be refactored
eventually. Correct?

Finally, in sunxi-ng there is a feature of having a fixed_post_div (see,
e.g., the first to lines of the diff above). It seems to me that CCF
cannot know about these post_divs, so we'd also need to transfer the
fixed_post_div to ccu_common and use that when calling
clk_hw_set_rate_range. Correct?

The fact that you casually dropped the two sentences above and me
deducing you want a somewhat large refactoring of the functionality for
sunxi-ng, makes me wonder if I completely misunderstood your request.

Best regards,
  Frank

>
> Maxime
>
> [[End of PGP Signed Part]]


From zhangzj at rock-chips.com  Sun Feb 18 00:53:13 2024
From: zhangzj at rock-chips.com (Elon Zhang)
Date: Sun, 18 Feb 2024 16:53:13 +0800
Subject: [PATCH v2 1/2] arm64: dts: rockchip: Add devicetree support for TB-RK3588X board
In-Reply-To: <20240218065407.652213-1-zhangzj@rock-chips.com>
References: <20240218065407.652213-1-zhangzj@rock-chips.com>
Message-ID: <20240218085314.658223-1-zhangzj@rock-chips.com>

Add board file for Rockchip Toybrick TB-RK3588X board.

Specification:
	Rockchip Rk3588 SoC
	4x ARM Cortex-A76, 4x ARM Cortex-A55
	8/16GB Memory LPDDR4x
	Mali G610MC4 GPU
	2? MIPI-CSI0 Connector
	1x 2Lanes PCIe3.0 Connector
	1x SATA3.0 Connector
	32GB eMMC Module
	2x USB 2.0, 2x USB 3.0
	1x HDMI Output, 1x HDMI Input
	2x Ethernet Port

Functions work normally:
	[1] USB2.0 Host
	[2] Ethernet0 with PHY RTL8211F

More information can be obtained from the following websites:
	[1] https://t.rock-chips.com/en/wiki/EN/tb-rk3588x_en/index.html
	[2] http://t.rock-chips.com/

Signed-off-by: Elon Zhang <zhangzj at rock-chips.com>
---
v1->v2: update copyright

 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3588-toybrick-x0.dts  | 672 ++++++++++++++++++
 2 files changed, 673 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index a7b30e11beaf..e0722b6e2d99 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -110,6 +110,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-orangepi-5-plus.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-quartzpro64.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-toybrick-x0.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-turing-rk1.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-coolpi-4b.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
new file mode 100644
index 000000000000..f3f7c1d35ed2
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
@@ -0,0 +1,672 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588.dtsi"
+
+/ {
+	model = "Rockchip Toybrick TB-RK3588X Board";
+	compatible = "rockchip,rk3588-toybrick-x0", "rockchip,rk3588";
+
+	aliases {
+		mmc0 = &sdhci;
+		serial2 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-vol-up {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <17000>;
+		};
+
+		button-vol-down {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			press-threshold-microvolt = <417000>;
+		};
+
+		button-menu {
+			label = "Menu";
+			linux,code = <KEY_MENU>;
+			press-threshold-microvolt = <890000>;
+		};
+
+		button-escape {
+			label = "Escape";
+			linux,code = <KEY_ESC>;
+			press-threshold-microvolt = <1235000>;
+		};
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		power-supply = <&vcc12v_dcin>;
+		pwms = <&pwm2 0 25000 0>;
+	};
+
+	pcie20_avdd0v85: pcie20-avdd0v85-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie20_avdd0v85";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <850000>;
+		regulator-max-microvolt = <850000>;
+		vin-supply = <&vdd_0v85_s0>;
+	};
+
+	pcie20_avdd1v8: pcie20-avdd1v8-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie20_avdd1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&avcc_1v8_s0>;
+	};
+
+	pcie30_avdd0v75: pcie30-avdd0v75-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie30_avdd0v75";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <750000>;
+		regulator-max-microvolt = <750000>;
+		vin-supply = <&avdd_0v75_s0>;
+	};
+
+	pcie30_avdd1v8: pcie30-avdd1v8-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie30_avdd1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&avcc_1v8_s0>;
+	};
+
+	vcc12v_dcin: vcc12v-dcin-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc5v0_host: vcc5v0-host-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_host";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_host_en>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usbdcin: vcc5v0-usbdcin-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usbdcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usb: vcc5v0-usb-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usb";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usbdcin>;
+	};
+
+	vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v1_nldo_s3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+};
+
+&combphy0_ps {
+	status = "okay";
+};
+
+&combphy2_psu {
+	status = "okay";
+};
+
+&cpu_b0 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gmac0 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy>;
+	phy-mode = "rgmii-rxid";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+	pinctrl-names = "default";
+	rx_delay = <0x00>;
+	tx_delay = <0x43>;
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0m2_xfer>;
+	status = "okay";
+
+	vdd_cpu_big0_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu_big0_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	vdd_cpu_big1_s0: regulator at 43 {
+		compatible = "rockchip,rk8603", "rockchip,rk8602";
+		reg = <0x43>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu_big1_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	hym8563: rtc at 51 {
+		compatible = "haoyu,hym8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+		clock-output-names = "hym8563";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hym8563_int>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PD4 IRQ_TYPE_LEVEL_LOW>;
+		wakeup-source;
+	};
+};
+
+&mdio0 {
+	rgmii_phy: ethernet-phy at 1 {
+		/* RTL8211F */
+		compatible = "ethernet-phy-id001c.c916";
+		reg = <0x1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtl8211f_rst>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pinctrl {
+	rtl8211f {
+		rtl8211f_rst: rtl8211f-rst {
+			rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+	};
+
+	hym8563 {
+		hym8563_int: hym8563-int {
+			rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	usb {
+		vcc5v0_host_en: vcc5v0-host-en {
+			rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pwm2 {
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcc_1v8_s0>;
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	no-sdio;
+	no-sd;
+	non-removable;
+	mmc-hs400-1_8v;
+	mmc-hs400-enhanced-strobe;
+	status = "okay";
+};
+
+&spi2 {
+	status = "okay";
+	assigned-clocks = <&cru CLK_SPI2>;
+	assigned-clock-rates = <200000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+	num-cs = <1>;
+
+	pmic at 0 {
+		compatible = "rockchip,rk806";
+		spi-max-frequency = <1000000>;
+		reg = <0x0>;
+
+		interrupt-parent = <&gpio0>;
+		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+		system-power-controller;
+
+		vcc1-supply = <&vcc5v0_sys>;
+		vcc2-supply = <&vcc5v0_sys>;
+		vcc3-supply = <&vcc5v0_sys>;
+		vcc4-supply = <&vcc5v0_sys>;
+		vcc5-supply = <&vcc5v0_sys>;
+		vcc6-supply = <&vcc5v0_sys>;
+		vcc7-supply = <&vcc5v0_sys>;
+		vcc8-supply = <&vcc5v0_sys>;
+		vcc9-supply = <&vcc5v0_sys>;
+		vcc10-supply = <&vcc5v0_sys>;
+		vcc11-supply = <&vcc_2v0_pldo_s3>;
+		vcc12-supply = <&vcc5v0_sys>;
+		vcc13-supply = <&vcc_1v1_nldo_s3>;
+		vcc14-supply = <&vcc_1v1_nldo_s3>;
+		vcca-supply = <&vcc5v0_sys>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		rk806_dvs1_null: dvs1-null-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs2_null: dvs2-null-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs3_null: dvs3-null-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun0";
+		};
+
+		regulators {
+			vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_gpu_s0";
+				regulator-enable-ramp-delay = <400>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_cpu_lit_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_log_s0: dcdc-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <750000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_log_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-init-microvolt = <750000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_vdenc_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_ddr_s0: dcdc-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <900000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_ddr_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vdd2_ddr_s3: dcdc-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vdd2_ddr_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_2v0_pldo_s3: dcdc-reg7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <2000000>;
+				regulator-max-microvolt = <2000000>;
+				regulator-name = "vdd_2v0_pldo_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <2000000>;
+				};
+			};
+
+			vcc_3v3_s3: dcdc-reg8 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_3v3_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vddq_ddr_s0: dcdc-reg9 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vddq_ddr_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s3: dcdc-reg10 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			avcc_1v8_s0: pldo-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "avcc_1v8_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s0: pldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			avdd_1v2_s0: pldo-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-name = "avdd_1v2_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3_s0: pldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_3v3_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd_s0: pldo-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_sd_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			pldo6_s3: pldo-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "pldo6_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_0v75_s3: nldo-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdd_0v75_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_ddr_pll_s0: nldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdd_ddr_pll_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			avdd_0v75_s0: nldo-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <837500>;
+				regulator-max-microvolt = <837500>;
+				regulator-name = "avdd_0v75_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_0v85_s0: nldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdd_0v85_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_0v75_s0: nldo-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdd_0v75_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&u2phy2 {
+	status = "okay";
+};
+
+&u2phy2_host {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+&u2phy3 {
+	status = "okay";
+};
+
+&u2phy3_host {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-0 = <&uart2m0_xfer>;
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
-- 
2.34.1



From zhangzj at rock-chips.com  Sun Feb 18 00:53:14 2024
From: zhangzj at rock-chips.com (Elon Zhang)
Date: Sun, 18 Feb 2024 16:53:14 +0800
Subject: [PATCH v2 2/2] dt-bindings: arm: rockchip: Add Toybrick TB-RK3588X
In-Reply-To: <20240218085314.658223-1-zhangzj@rock-chips.com>
References: <20240218065407.652213-1-zhangzj@rock-chips.com>
 <20240218085314.658223-1-zhangzj@rock-chips.com>
Message-ID: <20240218085314.658223-2-zhangzj@rock-chips.com>

Add devicetree binding for Toybrick TB-RK3588X board from Rockchip Toybrick.

Signed-off-by: Elon Zhang <zhangzj at rock-chips.com>
---
 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 5cf5cbef2cf5..d29df97c7b25 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -878,6 +878,11 @@ properties:
           - const: rockchip,rv1108-evb
           - const: rockchip,rv1108
 
+      - description: Rockchip Toybrick TB-RK3588X board
+        items:
+          - const: rockchip,rk3588-toybrick-x0
+          - const: rockchip,rk3588
+
       - description: Theobroma Systems PX30-uQ7 with Haikou baseboard
         items:
           - const: tsd,px30-ringneck-haikou
-- 
2.34.1



From baolu.lu at linux.intel.com  Sun Feb 18 01:31:06 2024
From: baolu.lu at linux.intel.com (Baolu Lu)
Date: Sun, 18 Feb 2024 17:31:06 +0800
Subject: [PATCH 1/4] iommu: constify pointer to bus_type
In-Reply-To: <20240216144027.185959-1-krzysztof.kozlowski@linaro.org>
References: <20240216144027.185959-1-krzysztof.kozlowski@linaro.org>
Message-ID: <7b18a339-d0e3-4347-a20b-8fca9bbc7eb4@linux.intel.com>

On 2024/2/16 22:40, Krzysztof Kozlowski wrote:
> Make pointer to bus_type a pointer to const for code safety.
> 
> Signed-off-by: Krzysztof Kozlowski<krzysztof.kozlowski at linaro.org>
> ---
>   drivers/iommu/iommu-priv.h | 5 +++--
>   drivers/iommu/iommu.c      | 5 +++--
>   2 files changed, 6 insertions(+), 4 deletions(-)

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>

Best regards,
baolu


From chiawei_wang at aspeedtech.com  Sun Feb 18 01:36:27 2024
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Sun, 18 Feb 2024 09:36:27 +0000
Subject: =?utf-8?B?UkU6IOWbnuimhjogW1BBVENIXSBBZGQgZVNQSSBkZXZpY2UgZHJpdmVyIChm?=
 =?utf-8?Q?lash_channel)?=
In-Reply-To: <20240215-probable-gimmick-83d5dcbc4729@spud>
References: <20240213-espi_driver-v1-1-92741c812843@gmail.com>
 <KL1PR06MB665234A65DB334B3BDF6AFA6914E2@KL1PR06MB6652.apcprd06.prod.outlook.com>
 <20240214-yoyo-platinum-dcd0e7e16a22@spud>
 <TYZPR06MB6640F82C539F0B17BCDCC55E914D2@TYZPR06MB6640.apcprd06.prod.outlook.com>
 <20240215-probable-gimmick-83d5dcbc4729@spud>
Message-ID: <KL1PR06MB6652F1A2D8652B727D5F581A91522@KL1PR06MB6652.apcprd06.prod.outlook.com>

> From: Conor Dooley <conor at kernel.org>
> Sent: Friday, February 16, 2024 1:13 AM
> 
> On Thu, Feb 15, 2024 at 01:56:00AM +0000, ChiaWei Wang wrote:
> > >
> > > On Wed, Feb 14, 2024 at 11:34:31AM +0000, ChiaWei Wang wrote:
> > > > We appreciate that you are willing to help on the open source
> contribution.
> > > > However, please co-work with Aspeed before submitting drivers of
> > > > Aspeed
> > > HW.
> > > > Otherwise, a misleading driver on the community are going to bring
> > > > tons of
> > > customer issues to Aspeed.
> > >
> > > It may not apply in this particular case as Aspeed did write the
> > > original driver and it is polite to work with previous authors when
> > > respinning a patchset, but in general there is no need to work with
> > > a hardware vendor before writing drivers for their hardware.
> > >
> > > Blocking a driver because that company might receive more support
> > > requests is not the kernel's problem.
> >
> > I agree with that and Aspeed will not refuse to support.
> >
> > However, in this case, the authors, IBM, and Aspeed already have discussion
> (at least 4 times) before and foresee "issues" on practical eSPI SAFS use.
> > If there is already a known issue of the driver, why ignoring the previous
> discussion and push it?
> > A compromise is to ask for driver renaming to espi-mafs to avoid confusion.
> > Otherwise we need to explain, again, why the driver does not fulfill the SAFS
> expectation.
> 
> To be clear, in case you misunderstood, I was making a general point and not
> about this particular patchset.

Thanks for the clarification and I understand your point.

Most Aspeed-related drivers are from the Aspeed SDK.
And we keep revising the SDK based on our customers' feedback and issues reported.
We only wish that the version submitted to the community will not result in unnecessary misunderstanding and thus more customer issues.

Regards,
Chiawei

From devnull+forbidden405.outlook.com at kernel.org  Sun Feb 18 01:40:29 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Sun, 18 Feb 2024 17:40:29 +0800
Subject: [PATCH 0/2] arm64: dts: hi3798cv200: fix GICR size, add cache info
Message-ID: <20240218-cache-v1-0-2c0a8a4472e7@outlook.com>

They are tested on a hi3798mv200 board in fact. Though the 2 SoCs are
highly similar and the CPU should be the same. Still, Tested-by are
welcomed.

The patchset fixes some warnings reported by the kernel during boot.

The cache size info is from Processor_Datasheet_v2XX.pdf [1], Section
2.2.1 Master Processor.

The cache line size and the set-associative info are from Cortex-A53
Documentation [2]. Dts for other SoCs are also a good reference.

>From the doc, we know L1 i-cache is 4-way assoc, L1 d-cache is 2-way
assoc and L2 cache is 16-way assoc. Fill the dts props accordingly.

Dear maintainers, maybe consider Cc to stable too?

[1]: https://github.com/96boards/documentation/blob/master/enterprise/poplar/hardware-docs/Processor_Datasheet_v2XX.pdf
[2]: https://developer.arm.com/documentation/ddi0500/j/Level-1-Memory-System

Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
Yang Xiwen (2):
      arm64: dts: hi3798cv200: Fix the size of GICR
      arm64: dts: hi3798cv200: add cache info

 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 39 +++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)
---
base-commit: 8d3dea210042f54b952b481838c1e7dfc4ec751d
change-id: 20240218-cache-11c8bf7566c2

Best regards,
-- 
Yang Xiwen <forbidden405 at outlook.com>



From devnull+forbidden405.outlook.com at kernel.org  Sun Feb 18 01:40:31 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Sun, 18 Feb 2024 17:40:31 +0800
Subject: [PATCH 2/2] arm64: dts: hi3798cv200: add cache info
In-Reply-To: <20240218-cache-v1-0-2c0a8a4472e7@outlook.com>
References: <20240218-cache-v1-0-2c0a8a4472e7@outlook.com>
Message-ID: <20240218-cache-v1-2-2c0a8a4472e7@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

During boot, the kernel complains:

[    0.044029] cacheinfo: Unable to detect cache hierarchy for CPU 0

So add L1/L2 cache info to the dts according to the datasheet. (32KiB L1
i-cache + 32 KiB L1 d-cache + 512 KiB L2 unified cache)

With this patch, the line above is gone and the following info is added
to the output of `lscpu`:

Caches (sum of all):
  L1d:                   128 KiB (4 instances)
  L1i:                   128 KiB (4 instances)
  L2:                    512 KiB (1 instance)

Fixes: 2f20182ed670 ("arm64: dts: hisilicon: add dts files for hi3798cv200-poplar board")
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 37 ++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
index d01023401d7e..33ded6b97f61 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
@@ -31,6 +31,13 @@ cpu at 0 {
 			device_type = "cpu";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
 		};
 
 		cpu at 1 {
@@ -38,6 +45,13 @@ cpu at 1 {
 			device_type = "cpu";
 			reg = <0x0 0x1>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
 		};
 
 		cpu at 2 {
@@ -45,6 +59,13 @@ cpu at 2 {
 			device_type = "cpu";
 			reg = <0x0 0x2>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
 		};
 
 		cpu at 3 {
@@ -52,9 +73,25 @@ cpu at 3 {
 			device_type = "cpu";
 			reg = <0x0 0x3>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
 		};
 	};
 
+	L2_0: l2-cache0 {
+		compatible = "cache";
+		cache-unified;
+		cache-size = <0x80000>; /* 512 KiB */
+		cache-line-size = <64>;
+		cache-sets = <512>;
+		cache-level = <2>;
+	};
+
 	gic: interrupt-controller at f1001000 {
 		compatible = "arm,gic-400";
 		reg = <0x0 0xf1001000 0x0 0x1000>,  /* GICD */

-- 
2.43.0



From devnull+forbidden405.outlook.com at kernel.org  Sun Feb 18 01:40:30 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Sun, 18 Feb 2024 17:40:30 +0800
Subject: [PATCH 1/2] arm64: dts: hi3798cv200: Fix the size of GICR
In-Reply-To: <20240218-cache-v1-0-2c0a8a4472e7@outlook.com>
References: <20240218-cache-v1-0-2c0a8a4472e7@outlook.com>
Message-ID: <20240218-cache-v1-1-2c0a8a4472e7@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

During boot, kernel complains:

[    0.000000] GIC: GICv2 detected, but range too small and irqchip.gicv2_force_probe not set

Looking at GIC-400 datasheet, I believe this SoC is using a regular
GIC-400 and the GICR space size should be 8 KB rather than 256B.

With this patch:

[    0.000000] GIC: Using split EOI/Deactivate mode

So this should be the correct fix.

Fixes: 2f20182ed670 ("arm64: dts: hisilicon: add dts files for hi3798cv200-poplar board")
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
index ed1b5a7a6067..d01023401d7e 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
@@ -58,7 +58,7 @@ cpu at 3 {
 	gic: interrupt-controller at f1001000 {
 		compatible = "arm,gic-400";
 		reg = <0x0 0xf1001000 0x0 0x1000>,  /* GICD */
-		      <0x0 0xf1002000 0x0 0x100>;   /* GICC */
+		      <0x0 0xf1002000 0x0 0x2000>;  /* GICC */
 		#address-cells = <0>;
 		#interrupt-cells = <3>;
 		interrupt-controller;

-- 
2.43.0



From quic_jinlmao at quicinc.com  Sun Feb 18 01:43:18 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Sun, 18 Feb 2024 01:43:18 -0800
Subject: [PATCH v3 0/2] coresight: tpdm: Change qcom,dsb-element-size to qcom,dsb-elem-bits
Message-ID: <20240218094322.22470-1-quic_jinlmao@quicinc.com>

As unit of dsb element size is bit, change qcom,dsb-element-size to
qcom,dsb-elem-bits. And CMB uses -bits suffix as well. There is no
TPDM node in any DT now. Make such change before any TPDM node is added
to DT.

Change since V2:
1. Use fwnode_property_read_u32 to read the proprety value.

Change since V1:
1. Update the commit message for dt-binding.
2. Fix the dt_binding_check error for dt-binding change.

Mao Jinlong (2):
  dt-bindings: arm: qcom,coresight-tpdm: Rename qcom,dsb-element-size
  coresight-tpda: Change qcom,dsb-element-size to qcom,dsb-elem-bits

 .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml         | 5 ++---
 drivers/hwtracing/coresight/coresight-tpda.c                 | 4 ++--
 drivers/hwtracing/coresight/coresight-tpda.h                 | 2 +-
 3 files changed, 5 insertions(+), 6 deletions(-)

-- 
2.41.0



From quic_jinlmao at quicinc.com  Sun Feb 18 01:43:20 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Sun, 18 Feb 2024 01:43:20 -0800
Subject: [PATCH v3 2/2] coresight-tpda: Change qcom,dsb-element-size to qcom,dsb-elem-bits
In-Reply-To: <20240218094322.22470-1-quic_jinlmao@quicinc.com>
References: <20240218094322.22470-1-quic_jinlmao@quicinc.com>
Message-ID: <20240218094322.22470-3-quic_jinlmao@quicinc.com>

Change qcom,dsb-element-size to qcom,dsb-elem-bits as the unit is bit.
When use "-bits" suffix, the type of the property is u32 from
property-units.yaml, so use fwnode_property_read_u32 to read the
property.

Fixes: 57e7235aa1d1 ("coresight-tpda: Add DSB dataset support")
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-tpda.c | 4 ++--
 drivers/hwtracing/coresight/coresight-tpda.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 6863afe7ca94..7739bc7adc44 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -69,8 +69,8 @@ static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
 	struct tpdm_drvdata *tpdm_data = dev_get_drvdata(csdev->dev.parent);
 
 	if (tpdm_has_dsb_dataset(tpdm_data)) {
-		rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
-				"qcom,dsb-element-size", &drvdata->dsb_esize);
+		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
+				"qcom,dsb-element-bits", &drvdata->dsb_esize);
 	}
 	if (tpdm_has_cmb_dataset(tpdm_data)) {
 		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
index 19af64120fcf..c6af3d2da3ef 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.h
+++ b/drivers/hwtracing/coresight/coresight-tpda.h
@@ -36,7 +36,7 @@ struct tpda_drvdata {
 	struct coresight_device	*csdev;
 	spinlock_t		spinlock;
 	u8			atid;
-	u8			dsb_esize;
+	u32			dsb_esize;
 	u32			cmb_esize;
 };
 
-- 
2.41.0



From quic_jinlmao at quicinc.com  Sun Feb 18 01:43:19 2024
From: quic_jinlmao at quicinc.com (Mao Jinlong)
Date: Sun, 18 Feb 2024 01:43:19 -0800
Subject: [PATCH v3 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename qcom,dsb-element-size
In-Reply-To: <20240218094322.22470-1-quic_jinlmao@quicinc.com>
References: <20240218094322.22470-1-quic_jinlmao@quicinc.com>
Message-ID: <20240218094322.22470-2-quic_jinlmao@quicinc.com>

Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
bit. There is no tpdm node in any DT as of now. Make this change before
any tpdm node is added to DT.

Fixes: 2a8d9b371566 ("dt-bindings: arm: Add support for DSB element size")
Signed-off-by: Mao Jinlong <quic_jinlmao at quicinc.com>
---
 .../devicetree/bindings/arm/qcom,coresight-tpdm.yaml         | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
index d0647ffaed71..8eec07d9d454 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
@@ -44,12 +44,11 @@ properties:
     minItems: 1
     maxItems: 2
 
-  qcom,dsb-element-size:
+  qcom,dsb-element-bits:
     description:
       Specifies the DSB(Discrete Single Bit) element size supported by
       the monitor. The associated aggregator will read this size before it
       is enabled. DSB element size currently only supports 32-bit and 64-bit.
-    $ref: /schemas/types.yaml#/definitions/uint8
     enum: [32, 64]
 
   qcom,cmb-element-bits:
@@ -111,7 +110,7 @@ examples:
       compatible = "qcom,coresight-tpdm", "arm,primecell";
       reg = <0x0684c000 0x1000>;
 
-      qcom,dsb-element-size = /bits/ 8 <32>;
+      qcom,dsb-element-bits = <32>;
       qcom,dsb-msrs-num = <16>;
 
       clocks = <&aoss_qmp>;
-- 
2.41.0



From ardb at kernel.org  Sun Feb 18 02:06:50 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sun, 18 Feb 2024 11:06:50 +0100
Subject: [PATCH 5.10.y 0/5] Backport call_on_irq_stack to fix scs
 overwritten in irq_stack_entry
In-Reply-To: <20240218023055.145519-1-xiangyang3@huawei.com>
References: <20240218023055.145519-1-xiangyang3@huawei.com>
Message-ID: <CAMj1kXFbveXgHvk1jEs1Q4kE=Tak08cDYpebwEgKehhwYf9j4A@mail.gmail.com>

On Sun, 18 Feb 2024 at 03:33, Xiang Yang <xiangyang3 at huawei.com> wrote:
>
> The shadow call stack for irq now stored in current task's thread info
> may restored incorrectly, so backport call_on_irq_stack from mainline to
> fix it.
>
> Ard Biesheuvel (1):
>   arm64: Stash shadow stack pointer in the task struct on interrupt
>
> Mark Rutland (3):
>   arm64: entry: move arm64_preempt_schedule_irq to entry-common.c
>   arm64: entry: add a call_on_irq_stack helper
>   arm64: entry: convert IRQ+FIQ handlers to C
>
> Xiang Yang (1):
>   Revert "arm64: Stash shadow stack pointer in the task struct on
>     interrupt"
>

Backporting this was a mistake. Not only was the backport flawed, the
original issue (stashing the shadow call stack pointer onto the normal
stack) was not even present, at least not to the same extent.

Stashing the shadow call stack pointer in register X24 works around
the original issue, except for the case where a hardirq is taken while
softirqs are being processed. In this case, X24 will be preserved on
the stack by the hardirq handling logic, and restored after.
Theoretically, that creates a window where the shadow call stack
pointer could be corrupted deliberately, but it seems unlikely to me
that this is exploitable in practice.

So in the light of this, I think doing only the revert here should be
sufficient, and there is no need for the other backports in this
series.


From henrik at grimler.se  Sun Feb 18 02:24:49 2024
From: henrik at grimler.se (Henrik Grimler)
Date: Sun, 18 Feb 2024 11:24:49 +0100
Subject: [PATCH] ARM: dts: exynos4212-tab3: limit usable memory range
In-Reply-To: <20240217-tab3-limit-usable-memory-range-v1-1-49cc9c86a5cc@gmail.com>
References: <20240217-tab3-limit-usable-memory-range-v1-1-49cc9c86a5cc@gmail.com>
Message-ID: <20240218102449.GA7577@grimlerstat.localdomain>

Hi Artur,

On Sat, Feb 17, 2024 at 08:02:47PM +0100, Artur Weber wrote:
> The stock bootloader on the Samsung Galaxy Tab 3 8.0 provides an
> incorrect available memory range over ATAG_MEM. Limit the usable
> memory in the DTS to prevent it from doing so, without having to
> disable ATAG support.
> 
> Signed-off-by: Artur Weber <aweber.kernel at gmail.com>
> ---
>  arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
> index e5254e32aa8f..9bc05961577d 100644
> --- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
> +++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
> @@ -45,6 +45,12 @@ chosen {
>  		/* Default S-BOOT bootloader loads initramfs here */
>  		linux,initrd-start = <0x42000000>;
>  		linux,initrd-end = <0x42800000>;
> +
> +		/*
> +		 * Stock bootloader provides incorrect memory size in ATAG_MEM;
> +		 * override it here
> +		 */
> +		linux,usable-memory-range = <0x40000000 0x3fc00000>;

Maybe it would make sense to set the memory reg to
<0x40000000 0x60000000> (1.5 GiB) and move the comment about last
512(/516) MiB being weird/broken here instead.  It looks a bit weird
that the memory range and usable-memory-range are identical, and device tree
should describe hardware, which technically has 1.5 GiB RAM.

>From a functional point of view it does not really matter, so in any case:
Reviewed-by: Henrik Grimler <henrik at grimler.se>

>  	};
>  
>  	firmware at 204f000 {
> 
> ---
> base-commit: 0f1dd5e91e2ba3990143645faff2bcce2d99778e
> change-id: 20240217-tab3-limit-usable-memory-range-1d1ffa8dc44d
> 
> Best regards,
> -- 
> Artur Weber <aweber.kernel at gmail.com>
> 


From daniel.lezcano at linaro.org  Sun Feb 18 02:34:56 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Sun, 18 Feb 2024 11:34:56 +0100
Subject: [PATCH v4 0/3] clocksource: imx-sysctr: support i.MX95
In-Reply-To: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>
References: <20240205-imx-sysctr-v4-0-ca5a6e1552e7@nxp.com>
Message-ID: <c7a8a0ff-2905-4253-bd8c-053d4a39d43f@linaro.org>

On 05/02/2024 04:17, Peng Fan (OSS) wrote:
> i.MX95 System Counter module control register space is blocked
> by SCMI firmware, so we use Read Register space to get the counter.
> 
> V2:
>    - imx95 is not compatible with the existing hardware, so add a
>      seperate entry for i.MX95 in dt-binding.
>    - Per Marco's comments, the global variables was removed except
>      to_sysctr. And add a new TIMER_OF_DECLARE entry for i.MX95
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---

Applied, thanks

-- 
<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 arinc.unal at arinc9.com  Sun Feb 18 02:52:13 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Sun, 18 Feb 2024 13:52:13 +0300
Subject: [PATCH] arm64: dts: {mt7622,mt7986}: add port@5 as CPU port
In-Reply-To: <20230918074938.79796-1-arinc.unal@arinc9.com>
References: <20230918074938.79796-1-arinc.unal@arinc9.com>
Message-ID: <5d582382-9a31-4a95-bc81-01d99dde0a6e@arinc9.com>

Matthias, please apply this patch.

Ar?n?


From andy.yan at rock-chips.com  Sun Feb 18 03:14:56 2024
From: andy.yan at rock-chips.com (Andy Yan)
Date: Sun, 18 Feb 2024 19:14:56 +0800
Subject: [PATCH] drm: rockchip: Don't require MIPI DSI device when it's
 used for ISP
In-Reply-To: <20240217183941.1752463-1-megi@xff.cz>
References: <20240217183941.1752463-1-megi@xff.cz>
Message-ID: <4c66c084-5af6-43fb-a256-4746b2e00192@rock-chips.com>

Hi,

On 2/18/24 02:39, Ond?ej Jirman wrote:
> From: Ondrej Jirman <megi at xff.cz>
> 
> On RK3399 one MIPI DSI device can be alternatively used with the ISP1,
> to provide RX DPHY. When this is the case (ISP1 is enabled in device
> tree), probe success of DRM is tied to probe success of ISP1 connected
> camera sensor. This can fail if the user is able to killswitch the camera
> power, like on Pinephone Pro.
> 
> Detect use of MIPI DSI controller by ISP, and don't include it in
> component match list in that case.
> 

Isn't this supposed to be taken care of within the dts?
Since DPHY1 should exclusively used by MIPI DSI1 and ISP1, then if
a device want to use ISP1, the DSI1 should be disabled in dts.
> Signed-off-by: Ondrej Jirman <megi at xff.cz>
> ---
>   drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 47 +++++++++++++++++++++
>   1 file changed, 47 insertions(+)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index ab55d7132550..f47de94ad576 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -354,6 +354,43 @@ static void rockchip_drm_match_remove(struct device *dev)
>   		device_link_del(link);
>   }
>   
> +/*
> + * Check if ISP block linked to a mipi-dsi device via phys phandle is
> + * enabled in device tree.
> + */
> +static bool rockchip_drm_is_mipi1_and_used_by_isp(struct device *dev)
> +{
> +	struct device_node *np = NULL, *phy_np;
> +
> +	if (!of_device_is_compatible(dev->of_node, "rockchip,rk3399-mipi-dsi"))
> +		return false;
> +
> +	while (true) {
> +		np = of_find_compatible_node(np, NULL, "rockchip,rk3399-cif-isp");
> +		if (!np)
> +			break;
> +
> +		if (!of_device_is_available(np)) {
> +			of_node_put(np);
> +			continue;
> +		}
> +
> +		phy_np = of_parse_phandle(np, "phys", 0);
> +		if (!phy_np) {
> +			of_node_put(np);
> +			continue;
> +		}
> +
> +		of_node_put(phy_np);
> +		of_node_put(np);
> +
> +		if (phy_np == dev->of_node)
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
>   static struct component_match *rockchip_drm_match_add(struct device *dev)
>   {
>   	struct component_match *match = NULL;
> @@ -371,6 +408,16 @@ static struct component_match *rockchip_drm_match_add(struct device *dev)
>   			if (!d)
>   				break;
>   
> +			/*
> +			 * If mipi1 is connected to ISP, we don't want to wait for mipi1 component,
> +			 * because it will not be used by DRM anyway, to not tie success of camera
> +			 * driver probe to display pipeline initialization.
> +			 */
> +			if (rockchip_drm_is_mipi1_and_used_by_isp(d)) {
> +				dev_info(d, "used by ISP1, skipping from DRM\n");
> +				continue;
> +			}
> +
>   			device_link_add(dev, d, DL_FLAG_STATELESS);
>   			component_match_add(dev, &match, component_compare_dev, d);
>   		} while (true);


From martin.blumenstingl at googlemail.com  Sun Feb 18 03:19:58 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 18 Feb 2024 12:19:58 +0100
Subject: [PATCH v1 2/3] ARM: dts: meson8: fix &hwrng node compatible string
In-Reply-To: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>
References: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>
Message-ID: <20240218111959.1811676-3-martin.blumenstingl@googlemail.com>

There's no documentation for a "amlogic,meson8-rng" compatible string.
Keep the default compatible string from meson.dtsi which is
"amlogic,meson-rng" (which is also documented).

This fixes a binding check error.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 arch/arm/boot/dts/amlogic/meson8.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/amlogic/meson8.dtsi b/arch/arm/boot/dts/amlogic/meson8.dtsi
index 59932fbfd5d5..f57be9ae150f 100644
--- a/arch/arm/boot/dts/amlogic/meson8.dtsi
+++ b/arch/arm/boot/dts/amlogic/meson8.dtsi
@@ -645,7 +645,6 @@ pwrc: power-controller {
 };
 
 &hwrng {
-	compatible = "amlogic,meson8-rng", "amlogic,meson-rng";
 	clocks = <&clkc CLKID_RNG0>;
 	clock-names = "core";
 };
-- 
2.43.2



From martin.blumenstingl at googlemail.com  Sun Feb 18 03:19:59 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 18 Feb 2024 12:19:59 +0100
Subject: [PATCH v1 3/3] ARM: dts: meson8b: fix &hwrng node compatible string
In-Reply-To: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>
References: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>
Message-ID: <20240218111959.1811676-4-martin.blumenstingl@googlemail.com>

There's no documentation for a "amlogic,meson8b-rng" compatible string.
Keep the default compatible string from meson.dtsi which is
"amlogic,meson-rng" (which is also documented).

This fixes a binding check error.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 arch/arm/boot/dts/amlogic/meson8b.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/amlogic/meson8b.dtsi b/arch/arm/boot/dts/amlogic/meson8b.dtsi
index 5198f5177c2c..2d9d24d3a95d 100644
--- a/arch/arm/boot/dts/amlogic/meson8b.dtsi
+++ b/arch/arm/boot/dts/amlogic/meson8b.dtsi
@@ -620,7 +620,6 @@ pwrc: power-controller {
 };
 
 &hwrng {
-	compatible = "amlogic,meson8b-rng", "amlogic,meson-rng";
 	clocks = <&clkc CLKID_RNG0>;
 	clock-names = "core";
 };
-- 
2.43.2



From martin.blumenstingl at googlemail.com  Sun Feb 18 03:19:57 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 18 Feb 2024 12:19:57 +0100
Subject: [PATCH v1 1/3] ARM: dts: meson: fix bus node names
In-Reply-To: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>
References: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>
Message-ID: <20240218111959.1811676-2-martin.blumenstingl@googlemail.com>

This fixes a few binding check errors as the node name of a bus should
be "bus".

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 arch/arm/boot/dts/amlogic/meson.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/amlogic/meson.dtsi b/arch/arm/boot/dts/amlogic/meson.dtsi
index 8e3860d5d916..8cb0fc78b2af 100644
--- a/arch/arm/boot/dts/amlogic/meson.dtsi
+++ b/arch/arm/boot/dts/amlogic/meson.dtsi
@@ -23,7 +23,7 @@ soc {
 		#size-cells = <1>;
 		ranges;
 
-		cbus: cbus at c1100000 {
+		cbus: bus at c1100000 {
 			compatible = "simple-bus";
 			reg = <0xc1100000 0x200000>;
 			#address-cells = <1>;
@@ -206,7 +206,7 @@ gic: interrupt-controller at 1000 {
 			};
 		};
 
-		aobus: aobus at c8100000 {
+		aobus: bus at c8100000 {
 			compatible = "simple-bus";
 			reg = <0xc8100000 0x100000>;
 			#address-cells = <1>;
@@ -302,7 +302,7 @@ bootrom: bootrom at d9040000 {
 			reg = <0xd9040000 0x10000>;
 		};
 
-		secbus: secbus at da000000 {
+		secbus: bus at da000000 {
 			compatible = "simple-bus";
 			reg = <0xda000000 0x6000>;
 			#address-cells = <1>;
-- 
2.43.2



From martin.blumenstingl at googlemail.com  Sun Feb 18 03:19:56 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 18 Feb 2024 12:19:56 +0100
Subject: [PATCH v1 0/3] ARM: dts: amlogic: Three small binding check error fixes
Message-ID: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>

This series contains three small binding check fixes.
Nothing functional was broken before, so no need to backpport any of
these to -stable.


Martin Blumenstingl (3):
  ARM: dts: meson: fix bus node names
  ARM: dts: meson8: fix &hwrng node compatible string
  ARM: dts: meson8b: fix &hwrng node compatible string

 arch/arm/boot/dts/amlogic/meson.dtsi   | 6 +++---
 arch/arm/boot/dts/amlogic/meson8.dtsi  | 1 -
 arch/arm/boot/dts/amlogic/meson8b.dtsi | 1 -
 3 files changed, 3 insertions(+), 5 deletions(-)

-- 
2.43.2



From irui.wang at mediatek.com  Sun Feb 18 03:59:54 2024
From: irui.wang at mediatek.com (Irui Wang)
Date: Sun, 18 Feb 2024 19:59:54 +0800
Subject: [PATCH] media: mediatek: vcodec: Handle VP9 superframe bitstream with 8 sub-frames
Message-ID: <20240218115954.4038-1-irui.wang@mediatek.com>

The VP9 bitstream has 8 sub-frames into one superframe, the superframe
index validate failed when reach 8, modify the index checking so that the
last sub-frame can be decoded normally.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c
index 55355fa70090..4a9ced7348ee 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c
@@ -526,7 +526,7 @@ static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst)
 	/* if this super frame and it is not last sub-frame, get next fb for
 	 * sub-frame decode
 	 */
-	if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt - 1)
+	if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt)
 		vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
 }
 
@@ -735,7 +735,7 @@ static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)
 
 static int validate_vsi_array_indexes(struct vdec_vp9_inst *inst,
 		struct vdec_vp9_vsi *vsi) {
-	if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM - 1) {
+	if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM) {
 		mtk_vdec_err(inst->ctx, "Invalid vsi->sf_frm_idx=%u.", vsi->sf_frm_idx);
 		return -EIO;
 	}
-- 
2.18.0



From devnull+forbidden405.outlook.com at kernel.org  Sun Feb 18 04:02:50 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Sun, 18 Feb 2024 20:02:50 +0800
Subject: [PATCH v2 1/3] arm64: dts: hi3798cv200: fix the size of GICR
In-Reply-To: <20240218-cache-v2-0-1fd919e2bd3e@outlook.com>
References: <20240218-cache-v2-0-1fd919e2bd3e@outlook.com>
Message-ID: <20240218-cache-v2-1-1fd919e2bd3e@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

During boot, kernel complains:

[    0.000000] GIC: GICv2 detected, but range too small and irqchip.gicv2_force_probe not set

Looking at GIC-400 datasheet, I believe this SoC is using a regular
GIC-400 and the GICR space size should be 8 KB rather than 256B.

With this patch:

[    0.000000] GIC: Using split EOI/Deactivate mode

So this should be the correct fix.

Fixes: 2f20182ed670 ("arm64: dts: hisilicon: add dts files for hi3798cv200-poplar board")
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
index ed1b5a7a6067..d01023401d7e 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
@@ -58,7 +58,7 @@ cpu at 3 {
 	gic: interrupt-controller at f1001000 {
 		compatible = "arm,gic-400";
 		reg = <0x0 0xf1001000 0x0 0x1000>,  /* GICD */
-		      <0x0 0xf1002000 0x0 0x100>;   /* GICC */
+		      <0x0 0xf1002000 0x0 0x2000>;  /* GICC */
 		#address-cells = <0>;
 		#interrupt-cells = <3>;
 		interrupt-controller;

-- 
2.43.0



From devnull+forbidden405.outlook.com at kernel.org  Sun Feb 18 04:02:51 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Sun, 18 Feb 2024 20:02:51 +0800
Subject: [PATCH v2 2/3] arm64: dts: hi3798cv200: add GICH, GICV register
 space and irq
In-Reply-To: <20240218-cache-v2-0-1fd919e2bd3e@outlook.com>
References: <20240218-cache-v2-0-1fd919e2bd3e@outlook.com>
Message-ID: <20240218-cache-v2-2-1fd919e2bd3e@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

This is needed by KVM to make use of VGIC code. Just like regular
GIC-400, PPI #9 is the hypervisor maintenance interrupt. It has been
verified.

Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
index d01023401d7e..fc64d2fa99eb 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
@@ -58,7 +58,11 @@ cpu at 3 {
 	gic: interrupt-controller at f1001000 {
 		compatible = "arm,gic-400";
 		reg = <0x0 0xf1001000 0x0 0x1000>,  /* GICD */
-		      <0x0 0xf1002000 0x0 0x2000>;  /* GICC */
+		      <0x0 0xf1002000 0x0 0x2000>,  /* GICC */
+		      <0x0 0xf1004000 0x0 0x2000>,  /* GICH */
+		      <0x0 0xf1006000 0x0 0x2000>;  /* GICV */
+		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+			      IRQ_TYPE_LEVEL_HIGH)>;
 		#address-cells = <0>;
 		#interrupt-cells = <3>;
 		interrupt-controller;

-- 
2.43.0



From devnull+forbidden405.outlook.com at kernel.org  Sun Feb 18 04:02:49 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Sun, 18 Feb 2024 20:02:49 +0800
Subject: [PATCH v2 0/3] arm64: dts: hi3798cv200: fix GICR size, add cache
 info, maintenance irq and GICH, GICV spaces
Message-ID: <20240218-cache-v2-0-1fd919e2bd3e@outlook.com>

They are tested on a hi3798mv200 board in fact. Though the 2 SoCs are
highly similar and the CPU should be the same. Still, Tested-by are
welcomed.

The patchset fixes some warnings reported by the kernel during boot.

The cache size info is from Processor_Datasheet_v2XX.pdf [1], Section
2.2.1 Master Processor.

The cache line size and the set-associative info are from Cortex-A53
Documentation [2]. Dts for other SoCs are also a good reference.

>From the doc, we know L1 i-cache is 4-way assoc, L1 d-cache is 2-way
assoc and L2 cache is 16-way assoc. Fill the dts props accordingly.

Also, to use KVM's VGIC code, we need to add GICH, GICV and maintenance
IRQ to the dts. They are added with verification.

Dear maintainers, maybe consider Cc to stable too?

[1]: https://github.com/96boards/documentation/blob/master/enterprise/poplar/hardware-docs/Processor_Datasheet_v2XX.pdf
[2]: https://developer.arm.com/documentation/ddi0500/j/Level-1-Memory-System

Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
Changes in v2:
- arm64: dts: hi3798cv200: add GICH, GICV register spces and
  maintainance IRQ.
- Link to v1: https://lore.kernel.org/r/20240218-cache-v1-0-2c0a8a4472e7 at outlook.com

---
Yang Xiwen (3):
      arm64: dts: hi3798cv200: fix the size of GICR
      arm64: dts: hi3798cv200: add GICH, GICV register space and irq
      arm64: dts: hi3798cv200: add cache info

 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 43 +++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)
---
base-commit: 8d3dea210042f54b952b481838c1e7dfc4ec751d
change-id: 20240218-cache-11c8bf7566c2

Best regards,
-- 
Yang Xiwen <forbidden405 at outlook.com>



From devnull+forbidden405.outlook.com at kernel.org  Sun Feb 18 04:02:52 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Sun, 18 Feb 2024 20:02:52 +0800
Subject: [PATCH v2 3/3] arm64: dts: hi3798cv200: add cache info
In-Reply-To: <20240218-cache-v2-0-1fd919e2bd3e@outlook.com>
References: <20240218-cache-v2-0-1fd919e2bd3e@outlook.com>
Message-ID: <20240218-cache-v2-3-1fd919e2bd3e@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

During boot, the kernel complains:

[    0.044029] cacheinfo: Unable to detect cache hierarchy for CPU 0

So add L1/L2 cache info to the dts according to the datasheet. (32KiB L1
i-cache + 32 KiB L1 d-cache + 512 KiB L2 unified cache)

With this patch, the line above is gone and the following info is added
to the output of `lscpu`:

Caches (sum of all):
  L1d:                   128 KiB (4 instances)
  L1i:                   128 KiB (4 instances)
  L2:                    512 KiB (1 instance)

Fixes: 2f20182ed670 ("arm64: dts: hisilicon: add dts files for hi3798cv200-poplar board")
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 37 ++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
index fc64d2fa99eb..0a9533786f50 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
@@ -31,6 +31,13 @@ cpu at 0 {
 			device_type = "cpu";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
 		};
 
 		cpu at 1 {
@@ -38,6 +45,13 @@ cpu at 1 {
 			device_type = "cpu";
 			reg = <0x0 0x1>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
 		};
 
 		cpu at 2 {
@@ -45,6 +59,13 @@ cpu at 2 {
 			device_type = "cpu";
 			reg = <0x0 0x2>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
 		};
 
 		cpu at 3 {
@@ -52,9 +73,25 @@ cpu at 3 {
 			device_type = "cpu";
 			reg = <0x0 0x3>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2_0>;
 		};
 	};
 
+	L2_0: l2-cache0 {
+		compatible = "cache";
+		cache-unified;
+		cache-size = <0x80000>; /* 512 KiB */
+		cache-line-size = <64>;
+		cache-sets = <512>;
+		cache-level = <2>;
+	};
+
 	gic: interrupt-controller at f1001000 {
 		compatible = "arm,gic-400";
 		reg = <0x0 0xf1001000 0x0 0x1000>,  /* GICD */

-- 
2.43.0



From laurent.pinchart at ideasonboard.com  Sun Feb 18 04:40:14 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sun, 18 Feb 2024 14:40:14 +0200
Subject: [PATCH 2/2] media: i2c: Add imx283 camera sensor driver
In-Reply-To: <Zc8pF-27TRTgzVyk@kekkonen.localdomain>
References: <20240215204436.9194-1-umang.jain@ideasonboard.com>
 <20240215204436.9194-3-umang.jain@ideasonboard.com>
 <Zc8pF-27TRTgzVyk@kekkonen.localdomain>
Message-ID: <20240218124014.GC20376@pendragon.ideasonboard.com>

On Fri, Feb 16, 2024 at 09:21:27AM +0000, Sakari Ailus wrote:
> Hi Umang,
> 
> On Fri, Feb 16, 2024 at 02:14:35AM +0530, Umang Jain wrote:
> > From: Kieran Bingham <kieran.bingham at ideasonboard.com>
> > 
> > Add a v4l2 subdevice driver for the Sony IMX283 image sensor.
> > 
> > The IMX283 is a 20MP Diagonal 15.86 mm (Type 1) CMOS Image Sensor with
> > Square Pixel for Color Cameras.
> > 
> > The following features are supported:
> > - Manual exposure an gain control support
> > - vblank/hblank/link freq control support
> > - Test pattern support control
> > - Arbitrary horizontal and vertical cropping
> > - Supported resolution:
> >   - 5472x3648 @ 20fps (SRGGB12)
> >   - 5472x3648 @ 25fps (SRGGB10)
> >   - 2736x1824 @ 50fps (SRGGB12)
> > 
> > Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> > Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
> > ---
> >  MAINTAINERS                |    1 +
> >  drivers/media/i2c/Kconfig  |   13 +
> >  drivers/media/i2c/Makefile |    1 +
> >  drivers/media/i2c/imx283.c | 1601 ++++++++++++++++++++++++++++++++++++
> >  4 files changed, 1616 insertions(+)
> >  create mode 100644 drivers/media/i2c/imx283.c
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 53df4b6e3260..3826e5c5d746 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -20373,6 +20373,7 @@ L:	linux-media at vger.kernel.org
> >  S:	Maintained
> >  T:	git git://linuxtv.org/media_tree.git
> >  F:	Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
> > +F:	drivers/media/i2c/imx283.c
> >  
> >  SONY IMX290 SENSOR DRIVER
> >  M:	Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > index 56f276b920ab..b798c55a2be5 100644
> > --- a/drivers/media/i2c/Kconfig
> > +++ b/drivers/media/i2c/Kconfig
> > @@ -153,6 +153,19 @@ config VIDEO_IMX274
> >  	  This is a V4L2 sensor driver for the Sony IMX274
> >  	  CMOS image sensor.
> >  
> > +config VIDEO_IMX283
> > +	tristate "Sony IMX283 sensor support"
> > +	depends on I2C && VIDEO_DEV
> 
> This is already given.
> 
> > +	select MEDIA_CONTROLLER
> > +	select VIDEO_V4L2_SUBDEV_API
> 
> Both are already selected, no need to do this per driver.
> 
> > +	select V4L2_CCI_I2C
> > +	help
> > +	  This is a V4L2 sensor driver for the Sony IMX283
> > +	  CMOS image sensor.
> > +
> > +	  To compile this driver as a module, choose M here: the
> > +	  module will be called imx283.
> > +
> >  config VIDEO_IMX290
> >  	tristate "Sony IMX290 sensor support"
> >  	select REGMAP_I2C
> > diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> > index dfbe6448b549..0fbd81f9f420 100644
> > --- a/drivers/media/i2c/Makefile
> > +++ b/drivers/media/i2c/Makefile
> > @@ -48,6 +48,7 @@ obj-$(CONFIG_VIDEO_IMX214) += imx214.o
> >  obj-$(CONFIG_VIDEO_IMX219) += imx219.o
> >  obj-$(CONFIG_VIDEO_IMX258) += imx258.o
> >  obj-$(CONFIG_VIDEO_IMX274) += imx274.o
> > +obj-$(CONFIG_VIDEO_IMX283) += imx283.o
> >  obj-$(CONFIG_VIDEO_IMX290) += imx290.o
> >  obj-$(CONFIG_VIDEO_IMX296) += imx296.o
> >  obj-$(CONFIG_VIDEO_IMX319) += imx319.o
> > diff --git a/drivers/media/i2c/imx283.c b/drivers/media/i2c/imx283.c
> > new file mode 100644
> > index 000000000000..52fafea18e7a
> > --- /dev/null
> > +++ b/drivers/media/i2c/imx283.c
> > @@ -0,0 +1,1601 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * V4L2 Support for the IMX283
> > + *
> > + * Diagonal 15.86 mm (Type 1) CMOS Image Sensor with Square Pixel for Color
> > + * Cameras.
> > + *
> > + * Copyright (C) 2024 Ideas on Board Oy.
> > + *
> > + * Based on Sony IMX283 driver prepared by Will Whang
> > + *
> > + * Based on Sony imx477 camera driver
> > + * Copyright (C) 2019-2020 Raspberry Pi (Trading) Ltd
> > + */
> > +
> > +#include <asm/unaligned.h>
> 
> Do you still need this?
> 
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/gpio/consumer.h>
> > +#include <linux/i2c.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/regulator/consumer.h>
> > +#include <media/v4l2-cci.h>
> > +#include <media/v4l2-ctrls.h>
> > +#include <media/v4l2-device.h>
> > +#include <media/v4l2-event.h>
> > +#include <media/v4l2-fwnode.h>
> > +#include <media/v4l2-mediabus.h>
> > +
> > +/* Chip ID */
> > +#define IMX283_REG_CHIP_ID		CCI_REG8(0x3000)
> > +#define IMX283_CHIP_ID			0x0b	// Default power on state
> > +
> > +#define IMX283_REG_STANDBY		CCI_REG8(0x3000)
> > +#define   IMX283_ACTIVE			0
> > +#define   IMX283_STANDBY		BIT(0)
> > +#define   IMX283_STBLOGIC		BIT(1)
> > +#define   IMX283_STBMIPI		BIT(2)
> > +#define   IMX283_STBDV			BIT(3)
> > +#define   IMX283_SLEEP			BIT(4)
> > +
> > +#define IMX283_REG_CLAMP		CCI_REG8(0x3001)
> > +#define   IMX283_CLPSQRST		BIT(4)
> > +
> > +#define IMX283_REG_PLSTMG08		CCI_REG8(0x3003)
> > +#define   IMX283_PLSTMG08_VAL		0x77
> > +
> > +#define IMX283_REG_MDSEL1		CCI_REG8(0x3004)
> > +#define IMX283_REG_MDSEL2		CCI_REG8(0x3005)
> > +#define IMX283_REG_MDSEL3		CCI_REG8(0x3006)
> > +#define   IMX283_MDSEL3_VCROP_EN	BIT(5)
> > +#define IMX283_REG_MDSEL4		CCI_REG8(0x3007)
> > +#define   IMX283_MDSEL4_VCROP_EN	(BIT(4) | BIT(6))
> > +
> > +#define IMX283_REG_SVR			CCI_REG16_LE(0x3009)
> > +
> > +#define IMX283_REG_HTRIMMING		CCI_REG8(0x300b)
> > +#define   IMX283_MDVREV			BIT(0) /* VFLIP */
> > +#define   IMX283_HTRIMMING_EN		BIT(4)
> > +
> > +#define IMX283_REG_VWINPOS		CCI_REG16_LE(0x300f)
> > +#define IMX283_REG_VWIDCUT		CCI_REG16_LE(0x3011)
> > +
> > +#define IMX283_REG_MDSEL7		CCI_REG16_LE(0x3013)
> > +
> > +/* CSI Clock Configuration */
> > +#define IMX283_REG_TCLKPOST		CCI_REG8(0x3018)
> > +#define IMX283_REG_THSPREPARE		CCI_REG8(0x301a)
> > +#define IMX283_REG_THSZERO		CCI_REG8(0x301c)
> > +#define IMX283_REG_THSTRAIL		CCI_REG8(0x3020)
> > +#define IMX283_REG_TCLKPREPARE		CCI_REG8(0x3022)
> > +#define IMX283_REG_TCLKZERO		CCI_REG16_LE(0x3024)
> > +#define IMX283_REG_TLPX			CCI_REG8(0x3026)
> > +#define IMX283_REG_THSEXIT		CCI_REG8(0x3028)
> > +#define IMX283_REG_TCLKPRE		CCI_REG8(0x302a)
> > +
> > +#define IMX283_REG_Y_OUT_SIZE		CCI_REG16_LE(0x302f)
> > +#define IMX283_REG_WRITE_VSIZE		CCI_REG16_LE(0x3031)
> > +#define IMX283_REG_OB_SIZE_V		CCI_REG8(0x3033)
> > +
> > +/* HMAX internal HBLANK */
> > +#define IMX283_REG_HMAX			CCI_REG16_LE(0x3036)
> > +#define IMX283_HMAX_MAX			0xffff
> > +
> > +/* VMAX internal VBLANK */
> > +#define IMX283_REG_VMAX			CCI_REG24_LE(0x3038)
> > +#define   IMX283_VMAX_MAX		0xfffff
> > +
> > +/* SHR internal */
> > +#define IMX283_REG_SHR			CCI_REG16_LE(0x303b)
> > +#define   IMX283_SHR_MIN		11
> > +
> > +/*
> > + * Analog gain control
> > + *  Gain [dB] = -20log{(2048 - value [10:0]) /2048}
> > + *  Range: 0dB to approximately +27dB
> > + */
> > +#define IMX283_REG_ANALOG_GAIN		CCI_REG16_LE(0x3042)
> > +#define   IMX283_ANA_GAIN_MIN		0
> > +#define   IMX283_ANA_GAIN_MAX		1957
> > +#define   IMX283_ANA_GAIN_STEP		1
> > +#define   IMX283_ANA_GAIN_DEFAULT	0x0
> > +
> > +/*
> > + * Digital gain control
> > + *  Gain [dB] = value * 6
> > + *  Range: 0dB to +18db
> > + */
> > +#define IMX283_REG_DIGITAL_GAIN		CCI_REG8(0x3044)
> > +#define IMX283_DGTL_GAIN_MIN		0
> > +#define IMX283_DGTL_GAIN_MAX		3
> > +#define IMX283_DGTL_GAIN_DEFAULT	0
> > +#define IMX283_DGTL_GAIN_STEP		1
> > +
> > +#define IMX283_REG_HTRIMMING_START	CCI_REG16_LE(0x3058)
> > +#define IMX283_REG_HTRIMMING_END	CCI_REG16_LE(0x305a)
> > +
> > +#define IMX283_REG_MDSEL18		CCI_REG16_LE(0x30f6)
> > +
> > +/* Master Mode Operation Control */
> > +#define IMX283_REG_XMSTA		CCI_REG8(0x3105)
> > +#define   IMX283_XMSTA			BIT(0)
> > +
> > +#define IMX283_REG_SYNCDRV		CCI_REG8(0x3107)
> > +#define   IMX283_SYNCDRV_XHS_XVS	(0xa0 | 0x02)
> > +#define   IMX283_SYNCDRV_HIZ		(0xa0 | 0x03)
> > +
> > +/* PLL Standby */
> > +#define IMX283_REG_STBPL		CCI_REG8(0x320b)
> > +#define  IMX283_STBPL_NORMAL		0x00
> > +#define  IMX283_STBPL_STANDBY		0x03
> > +
> > +/* Input Frequency Setting */
> > +#define IMX283_REG_PLRD1		CCI_REG8(0x36c1)
> > +#define IMX283_REG_PLRD2		CCI_REG16_LE(0x36c2)
> > +#define IMX283_REG_PLRD3		CCI_REG8(0x36f7)
> > +#define IMX283_REG_PLRD4		CCI_REG8(0x36f8)
> > +
> > +#define IMX283_REG_PLSTMG02		CCI_REG8(0x36aa)
> > +#define   IMX283_PLSTMG02_VAL		0x00
> > +
> > +#define IMX283_REG_EBD_X_OUT_SIZE	CCI_REG16_LE(0x3a54)
> > +
> > +/* Test pattern generator */
> > +#define IMX283_REG_TPG_CTRL		CCI_REG8(0x3156)
> > +#define   IMX283_TPG_CTRL_CLKEN		BIT(0)
> > +#define   IMX283_TPG_CTRL_PATEN		BIT(4)
> > +
> > +#define IMX283_REG_TPG_PAT		CCI_REG8(0x3157)
> > +#define   IMX283_TPG_PAT_ALL_000	0x00
> > +#define   IMX283_TPG_PAT_ALL_FFF	0x01
> > +#define   IMX283_TPG_PAT_ALL_555	0x02
> > +#define   IMX283_TPG_PAT_ALL_AAA	0x03
> > +#define   IMX283_TPG_PAT_H_COLOR_BARS	0x0a
> > +#define   IMX283_TPG_PAT_V_COLOR_BARS	0x0b
> > +
> > +/* Exposure control */
> > +#define IMX283_EXPOSURE_MIN		52
> > +#define IMX283_EXPOSURE_STEP		1
> > +#define IMX283_EXPOSURE_DEFAULT		1000
> > +#define IMX283_EXPOSURE_MAX		49865
> > +
> > +/* Embedded metadata stream structure */
> > +#define IMX283_EMBEDDED_LINE_WIDTH 16384
> > +#define IMX283_NUM_EMBEDDED_LINES 1
> > +
> > +#define MHZ(x)				((x) * 1000 * 1000)
> 
> We have MEGA in linux/units.h. Could you use that instead of defining your
> own?
> 
> > +#define IMAGE_PAD			0
> > +
> > +#define imx283_XCLR_MIN_DELAY_US	1000
> > +#define imx283_XCLR_DELAY_RANGE_US	1000
> > +
> > +/* IMX283 native and active pixel array size. */
> > +static const struct v4l2_rect imx283_native_area = {
> > +	.top = 0,
> > +	.left = 0,
> > +	.width = 5592,
> > +	.height = 3710,
> > +};
> > +
> > +static const struct v4l2_rect imx283_active_area = {
> > +	.top = 40,
> > +	.left = 108,
> > +	.width = 5472,
> > +	.height = 3648,
> > +};
> > +
> > +struct IMX283_reg_list {
> > +	unsigned int num_of_regs;
> > +	const struct cci_reg_sequence *regs;
> > +};
> > +
> > +/* Mode : resolution and related config values */
> > +struct imx283_mode {
> > +	unsigned int mode;
> > +
> > +	/* Bits per pixel */
> > +	unsigned int bpp;
> > +
> > +	/* Frame width */
> > +	unsigned int width;
> > +
> > +	/* Frame height */
> > +	unsigned int height;
> > +
> > +	/*
> > +	 * Minimum horizontal timing in pixel-units
> > +	 *
> > +	 * Note that HMAX is written in 72MHz units, and the datasheet assumes a
> > +	 * 720MHz link frequency. Convert datasheet values with the following:
> > +	 *
> > +	 * For 12 bpp modes (480Mbps) convert with:
> > +	 *   hmax = [hmax in 72MHz units] * 480 / 72
> > +	 *
> > +	 * For 10 bpp modes (576Mbps) convert with:
> > +	 *   hmax = [hmax in 72MHz units] * 576 / 72
> > +	 */
> > +	u64 min_hmax;
> > +
> > +	/* minimum V-timing in lines */
> > +	u64 min_vmax;
> > +
> > +	/* default H-timing */
> > +	u64 default_hmax;
> > +
> > +	/* default V-timing */
> > +	u64 default_vmax;
> > +
> > +	/* minimum SHR */
> > +	u64 min_shr;
> > +
> 
> Why are all these 64-bit numbers?
> 
> > +	/* Abritrary vertical cropping */
> > +	u32 veff;
> > +	u32 vst;
> > +	u32 vct;

Store the crop rectangle in a v4l2_rect, it will make it easier to move
to arbitrary cropping.

> > +
> > +	/* Horizontal and vertical binning ratio */
> > +	u8 hbin_ratio;
> > +	u8 vbin_ratio;

Similarly, the binning ratio should be computed based on the crop size
and the output size.

In general, store in this structure data that maps to the V4L2 subdev
formats and selection rectangles, and calculate registers based on
those. Even better, don't make the driver mode-based.

> > +
> > +	/* Optical Blanking */
> > +	u32 horizontal_ob;
> > +	u32 vertical_ob;
> > +
> > +	/* Analog crop rectangle. */
> > +	struct v4l2_rect crop;

What's the "Arbitrary vertical cropping" above ? You should detail the
internal processing pipeline in a comment somewhere.

> > +};
> > +
> > +struct imx283_input_frequency {
> > +	unsigned int mhz;
> > +	unsigned int reg_count;
> > +	struct cci_reg_sequence regs[4];
> > +};
> > +
> > +static const struct imx283_input_frequency imx283_frequencies[] = {
> > +	{
> > +		.mhz = MHZ(6),
> > +		.reg_count = 4,
> > +		.regs = {
> > +			{ IMX283_REG_PLRD1, 0x00 },
> > +			{ IMX283_REG_PLRD2, 0x00f0 },
> > +			{ IMX283_REG_PLRD3, 0x00 },
> > +			{ IMX283_REG_PLRD4, 0xc0 },
> > +		},
> > +	},
> > +	{
> > +		.mhz = MHZ(12),
> > +		.reg_count = 4,
> > +		.regs = {
> > +			{ IMX283_REG_PLRD1, 0x01 },
> > +			{ IMX283_REG_PLRD2, 0x00f0 },
> > +			{ IMX283_REG_PLRD3, 0x01 },
> > +			{ IMX283_REG_PLRD4, 0xc0 },
> > +		},
> > +	},
> > +	{
> > +		.mhz = MHZ(18),
> > +		.reg_count = 4,
> > +		.regs = {
> > +			{ IMX283_REG_PLRD1, 0x01 },
> > +			{ IMX283_REG_PLRD2, 0x00a0 },
> > +			{ IMX283_REG_PLRD3, 0x01 },
> > +			{ IMX283_REG_PLRD4, 0x80 },
> > +		},
> > +	},
> > +	{
> > +		.mhz = MHZ(24),
> > +		.reg_count = 4,
> > +		.regs = {
> > +			{ IMX283_REG_PLRD1, 0x02 },
> > +			{ IMX283_REG_PLRD2, 0x00f0 },
> > +			{ IMX283_REG_PLRD3, 0x02 },
> > +			{ IMX283_REG_PLRD4, 0xc0 },
> > +		},
> > +	},
> > +};
> > +
> > +enum imx283_modes {
> > +	IMX283_MODE_0,
> > +	IMX283_MODE_1,
> > +	IMX283_MODE_1A,
> > +	IMX283_MODE_1S,
> > +	IMX283_MODE_2,
> > +	IMX283_MODE_2A,
> > +	IMX283_MODE_3,
> > +	IMX283_MODE_4,
> > +	IMX283_MODE_5,
> > +	IMX283_MODE_6,
> > +};
> > +
> > +struct imx283_readout_mode {
> > +	u64 mdsel1;
> > +	u64 mdsel2;
> > +	u64 mdsel3;
> > +	u64 mdsel4;
> > +};
> > +
> > +static const struct imx283_readout_mode imx283_readout_modes[] = {
> > +	/* All pixel scan modes */
> > +	[IMX283_MODE_0] = { 0x04, 0x03, 0x10, 0x00 }, /* 12 bit */
> > +	[IMX283_MODE_1] = { 0x04, 0x01, 0x00, 0x00 }, /* 10 bit */
> > +	[IMX283_MODE_1A] = { 0x04, 0x01, 0x20, 0x50 }, /* 10 bit */
> > +	[IMX283_MODE_1S] = { 0x04, 0x41, 0x20, 0x50 }, /* 10 bit */
> > +
> > +	/* Horizontal / Vertical 2/2-line binning */
> > +	[IMX283_MODE_2] = { 0x0d, 0x11, 0x50, 0x00 }, /* 12 bit */
> > +	[IMX283_MODE_2A] = { 0x0d, 0x11, 0x70, 0x50 }, /* 12 bit */
> > +
> > +	/* Horizontal / Vertical 3/3-line binning */
> > +	[IMX283_MODE_3] = { 0x1e, 0x18, 0x10, 0x00 }, /* 12 bit */
> > +
> > +	/* Veritcal 2/9 subsampling, horizontal 3 binning cropping */
> > +	[IMX283_MODE_4] = { 0x29, 0x18, 0x30, 0x50 }, /* 12 bit */
> > +
> > +	/* Vertical 2/19 subsampling binning, horizontal 3 binning */
> > +	[IMX283_MODE_5] = { 0x2d, 0x18, 0x10, 0x00 }, /* 12 bit */
> > +
> > +	/* Vertical 2 binning horizontal 2/4, subsampling 16:9 cropping */
> > +	[IMX283_MODE_6] = { 0x18, 0x21, 0x00, 0x09 }, /* 10 bit */
> > +};
> > +
> > +static const struct cci_reg_sequence mipi_data_rate_1440Mbps[] = {
> > +	/* The default register settings provide the 1440Mbps rate */
> > +	{ CCI_REG8(0x36c5), 0x00 }, /* Undocumented */
> > +	{ CCI_REG8(0x3ac4), 0x00 }, /* Undocumented */
> > +
> > +	{ CCI_REG8(0x320B), 0x00 }, /* STBPL */

Define named macros for the registers instead of adding comments at the
end of the lines here.

> > +	{ CCI_REG8(0x3018), 0xa7 }, /* TCLKPOST */
> > +	{ CCI_REG8(0x301A), 0x6f }, /* THSPREPARE */
> > +	{ CCI_REG8(0x301C), 0x9f }, /* THSZERO */
> > +	{ CCI_REG8(0x301E), 0x5f }, /* THSTRAIL */
> > +	{ CCI_REG8(0x3020), 0x5f }, /* TCLKTRAIL */
> > +	{ CCI_REG8(0x3022), 0x6f }, /* TCLKPREPARE */
> > +	{ CCI_REG8(0x3024), 0x7f }, /* TCLKZERO[7:0] */
> > +	{ CCI_REG8(0x3025), 0x01 }, /* TCLKZERO[8] */
> > +	{ CCI_REG8(0x3026), 0x4f }, /* TLPX*/
> > +	{ CCI_REG8(0x3028), 0x47 }, /* THSEXIT */
> > +	{ CCI_REG8(0x302A), 0x07 }, /* TCKLPRE */
> > +	{ CCI_REG8(0x3104), 0x02 }, /* SYSMODE */
> > +};
> > +
> > +static const struct cci_reg_sequence mipi_data_rate_720Mbps[] = {
> > +	/* Undocumented Additions "For 720MBps" Setting */
> > +	{ CCI_REG8(0x36c5), 0x01 }, /* Undocumented */
> > +	{ CCI_REG8(0x3ac4), 0x01 }, /* Undocumented */
> > +
> > +	{ CCI_REG8(0x320B), 0x00 }, /* STBPL */
> > +	{ CCI_REG8(0x3018), 0x77 }, /* TCLKPOST */
> > +	{ CCI_REG8(0x301A), 0x37 }, /* THSPREPARE */
> > +	{ CCI_REG8(0x301C), 0x67 }, /* THSZERO */
> > +	{ CCI_REG8(0x301E), 0x37 }, /* THSTRAIL */
> > +	{ CCI_REG8(0x3020), 0x37 }, /* TCLKTRAIL */
> > +	{ CCI_REG8(0x3022), 0x37 }, /* TCLKPREPARE */
> > +	{ CCI_REG8(0x3024), 0xDF }, /* TCLKZERO[7:0] */
> > +	{ CCI_REG8(0x3025), 0x00 }, /* TCLKZERO[8] */
> > +	{ CCI_REG8(0x3026), 0x2F }, /* TLPX*/
> > +	{ CCI_REG8(0x3028), 0x47 }, /* THSEXIT */
> > +	{ CCI_REG8(0x302A), 0x0F }, /* TCKLPRE */
> > +	{ CCI_REG8(0x3104), 0x02 }, /* SYSMODE */
> > +};
> > +
> > +static const s64 link_frequencies[] = {
> > +	MHZ(720), /* 1440 Mbps lane data rate */
> > +	MHZ(360), /* 720 Mbps data lane rate */
> > +};
> > +
> > +static const struct IMX283_reg_list link_freq_reglist[] = {
> > +	{ /* MHZ(720)*/
> 
> Missing space before '*'.
> 
> > +		.num_of_regs = ARRAY_SIZE(mipi_data_rate_1440Mbps),
> > +		.regs = mipi_data_rate_1440Mbps,
> > +	},
> > +	{ /* MHZ(360) */
> > +		.num_of_regs = ARRAY_SIZE(mipi_data_rate_720Mbps),
> > +		.regs = mipi_data_rate_720Mbps,
> > +	},
> > +};
> > +
> > +#define CENTERED_RECTANGLE(rect, _width, _height) \
> > +	{ \
> > +		.left = rect.left + ((rect.width - (_width)) / 2), \
> > +		.top = rect.top + ((rect.height - (_height)) / 2), \
> > +		.width = (_width), \
> > +		.height = (_height), \
> 
> Please align the backslashes to the same column.
> 
> > +	}
> > +
> > +/* Mode configs */
> > +static const struct imx283_mode supported_modes_12bit[] = {
> > +	{
> > +		/* 20MPix 21.40 fps readout mode 0 */
> > +		.mode = IMX283_MODE_0,
> > +		.bpp = 12,
> > +		.width = 5472,
> > +		.height = 3648,
> > +		.min_hmax = 5914, /* 887 @ 480MHz/72MHz */
> > +		.min_vmax = 3793, /* Lines */
> > +
> > +		.veff = 3694,
> > +		.vst = 0,
> > +		.vct = 0,
> > +
> > +		.hbin_ratio = 1,
> > +		.vbin_ratio = 1,
> > +
> > +		/* 20.00 FPS */
> > +		.default_hmax = 6000, /* 900 @ 480MHz/72MHz */
> > +		.default_vmax = 4000,
> > +
> > +		.min_shr = 11,
> > +		.horizontal_ob = 96,
> > +		.vertical_ob = 16,
> > +		.crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
> > +	},
> > +	{
> > +		/*
> > +		 * Readout mode 2 : 2/2 binned mode (2736x1824)
> > +		 */
> > +		.mode = IMX283_MODE_2,
> > +		.bpp = 12,
> > +		.width = 2736,
> > +		.height = 1824,
> > +		.min_hmax = 1870, /* Pixels (362 * 360/72 + padding) */
> > +		.min_vmax = 3840, /* Lines */
> > +
> > +		/* 50.00 FPS */
> > +		.default_hmax = 1870, /* 362 @ 360MHz/72MHz */
> > +		.default_vmax = 3960,
> > +
> > +		.veff = 1824,
> > +		.vst = 0,
> > +		.vct = 0,
> > +
> > +		.hbin_ratio = 2,
> > +		.vbin_ratio = 2,
> > +
> > +		.min_shr = 12,
> > +		.horizontal_ob = 48,
> > +		.vertical_ob = 4,
> > +
> > +		.crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
> > +	},
> > +};
> > +
> > +static const struct imx283_mode supported_modes_10bit[] = {
> > +	{
> > +		/* 20MPix 25.48 fps readout mode 1 */
> > +		.mode = IMX283_MODE_1,
> > +		.bpp = 10,
> > +		.width = 5472,
> > +		.height = 3648,
> > +		.min_hmax = 5960, /* 745 @ 576MHz / 72MHz */
> > +		.min_vmax = 3793,
> > +
> > +		/* 25.00 FPS */
> > +		.default_hmax = 1500, /* 750 @ 576MHz / 72MHz */
> > +		.default_vmax = 3840,
> > +
> > +		.min_shr = 10,
> > +		.horizontal_ob = 96,
> > +		.vertical_ob = 16,
> > +		.crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
> > +	},
> > +};
> > +
> > +/*
> > + * The supported mbus formats.
> > + */
> > +static const u32 codes[] = {
> > +	/* 12-bit modes. */
> > +	MEDIA_BUS_FMT_SRGGB12_1X12,
> > +
> > +	/* 10-bit modes. */
> 
> I'd say the three comments are redundant.
> 
> > +	MEDIA_BUS_FMT_SRGGB10_1X10,
> > +};
> > +
> > +/* regulator supplies */
> > +static const char *const imx283_supply_name[] = {
> > +	"vana", /* Analog (2.9V) supply */
> > +	"vdig", /* Supply Voltage 2 (1.8V) supply */
> > +	"vddl", /* Supply Voltage 3 (1.2V) supply */
> > +};
> > +
> > +
> > +struct imx283 {
> > +	struct device *dev;
> > +	struct regmap *cci;
> > +
> > +	const struct imx283_input_frequency *freq;
> > +
> > +	struct v4l2_subdev sd;
> > +	struct media_pad pad;
> > +
> > +	unsigned int fmt_code;

Set but never used, drop it.

> > +
> > +	struct clk *xclk;
> > +
> > +	struct gpio_desc *reset_gpio;
> > +	struct regulator_bulk_data supplies[ARRAY_SIZE(imx283_supply_name)];
> > +
> > +	/* V4L2 Controls */
> > +	struct v4l2_ctrl_handler ctrl_handler;
> > +	struct v4l2_ctrl *pixel_rate;
> > +	struct v4l2_ctrl *link_freq;
> > +	struct v4l2_ctrl *exposure;
> > +	struct v4l2_ctrl *vblank;
> > +	struct v4l2_ctrl *hblank;
> > +	struct v4l2_ctrl *vflip;
> 
> Please store pointers only to controls you need to access outside the
> control handler's callbacks.
> 
> > +
> > +	struct mutex mutex;

It doesn't seem like you need a custom lock. You however need to use the
same lock for the active state and the controls, and that can be the
default control handler lock.

> > +
> > +	/* Current mode */
> > +	const struct imx283_mode *mode;

Drop this field and find the mode in the imx283_start_streaming?)
function based on the active state instead, and pass it from there to
the other functions that need it when starting the stream.

> > +
> > +	unsigned long link_freq_bitmap;
> > +
> > +	u16 hmax;
> > +	u32 vmax;
> > +};
> > +
> > +static inline struct imx283 *to_imx283(struct v4l2_subdev *_sd)
> > +{
> > +	return container_of(_sd, struct imx283, sd);
> > +}
> > +
> > +static inline void get_mode_table(unsigned int code,
> > +				  const struct imx283_mode **mode_list,
> > +				  unsigned int *num_modes)
> > +{
> > +	switch (code) {
> > +	/* 12-bit */
> > +	case MEDIA_BUS_FMT_SRGGB12_1X12:
> > +	case MEDIA_BUS_FMT_SGRBG12_1X12:
> > +	case MEDIA_BUS_FMT_SGBRG12_1X12:
> > +	case MEDIA_BUS_FMT_SBGGR12_1X12:
> > +		*mode_list = supported_modes_12bit;
> > +		*num_modes = ARRAY_SIZE(supported_modes_12bit);
> > +		break;
> > +	/* 10-bit */
> 
> These two comments seem redudant, too.
> 
> > +	case MEDIA_BUS_FMT_SRGGB10_1X10:
> > +	case MEDIA_BUS_FMT_SGRBG10_1X10:
> > +	case MEDIA_BUS_FMT_SGBRG10_1X10:
> > +	case MEDIA_BUS_FMT_SBGGR10_1X10:
> > +		*mode_list = supported_modes_10bit;
> > +		*num_modes = ARRAY_SIZE(supported_modes_10bit);
> > +		break;
> > +	default:
> > +		*mode_list = NULL;
> > +		*num_modes = 0;
> > +	}
> > +}
> > +
> > +/* Calculate the Pixel Rate based on the current mode */
> > +static u64 imx283_pixel_rate(struct imx283 *imx283)
> > +{
> > +	const struct imx283_mode *mode = imx283->mode;
> > +	unsigned int bpp = mode->bpp;
> > +
> > +	const unsigned int ddr = 2; /* Double Data Rate */
> > +	const unsigned int lanes = 4; /* Only 4 lane support */
> > +
> 
> Extra newlines.
> 
> > +	u64 link_frequency = link_frequencies[__ffs(imx283->link_freq_bitmap)];
> > +	u64 pixel_rate = link_frequency * ddr * lanes / bpp;
> 
> 	return ...;
> 
> > +
> > +	return pixel_rate;
> > +}
> > +
> > +/* Convert from a variable pixel_rate to 72 MHz clock cycles */
> > +static u64 imx283_internal_clock(unsigned int pixel_rate, unsigned int pixels)
> > +{
> > +	/*
> > +	 * Determine the following operation without overflow:
> > +	 *    pixels * MHZ(72) / pixel_rate
> > +	 *
> > +	 * The internal clock at 72MHz and Pixel Rate (between 240 and 576MHz)
> > +	 * can easily overflow this calculation, so pre-divide to simplify.
> > +	 */
> > +	const u32 iclk_pre = MHZ(72) / 1000000;
> > +	const u32 pclk_pre = pixel_rate / 1000000;
> > +
> > +	return pixels * iclk_pre / pclk_pre;
> > +}
> > +
> > +/* Internal clock (72MHz) to Pixel Rate clock (Variable) */
> > +static u64 imx283_iclk_to_pix(unsigned int pixel_rate, unsigned int cycles)
> > +{
> > +	/*
> > +	 * Determine the following operation without overflow:
> > +	 *    cycles * pixel_rate / MHZ(72)
> > +	 *
> > +	 * The internal clock at 72MHz and Pixel Rate (between 240 and 576MHz)
> > +	 * can easily overflow this calculation, so pre-divide to simplify.
> > +	 */
> > +	const u32 iclk_pre = MHZ(72) / 1000000;
> > +	const u32 pclk_pre = pixel_rate / 1000000;
> > +
> > +	return cycles * pclk_pre / iclk_pre;
> > +}
> > +
> > +/* Determine the exposure based on current hmax, vmax and a given SHR */
> > +static u64 imx283_exposure(struct imx283 *imx283, u64 shr)
> > +{
> > +	u32 svr = 0; /* SVR feature is not currently supported */
> > +	u32 hmax = imx283->hmax;
> > +	u64 vmax = imx283->vmax;
> > +	u32 offset;
> > +	u64 numerator;
> > +
> > +	/* Number of clocks per internal offset period */
> > +	offset = imx283->mode->mode == IMX283_MODE_0 ? 209 : 157;
> > +	numerator = (vmax * (svr + 1) - shr) * hmax + offset;
> > +
> > +	do_div(numerator, hmax);
> > +	numerator = clamp_t(u32, numerator, 0, 0xFFFFFFFF);
> > +	return numerator;
> > +}
> > +
> > +static void imx283_exposure_limits(struct imx283 *imx283,
> > +				   u64 *min_exposure, u64 *max_exposure)
> > +{
> > +	u64 vmax = imx283->vmax;
> > +	u32 svr = 0; /* SVR feature is not currently supported */
> > +	u64 min_shr = imx283->mode->min_shr;
> > +	u64 max_shr = (svr + 1) * vmax - 4; /* Global Shutter is not supported */
> > +
> > +	max_shr = min_t(u64, max_shr, 0xFFFF);
> > +
> > +	*min_exposure = imx283_exposure(imx283, max_shr);
> > +	*max_exposure = imx283_exposure(imx283, min_shr);
> > +}
> > +
> > +/*
> > + * Integration Time [s] = [{VMAX x (SVR + 1) ? (SHR)} x HMAX + offset]
> > + *                      / (72 x 10^6)
> > + */
> > +static u32 imx283_shr(struct imx283 *imx283, u32 exposure)
> > +{
> > +	u32 svr = 0; /* SVR feature is not currently supported */
> > +	u32 hmax = imx283->hmax;
> > +	u64 vmax = imx283->vmax;
> > +	u32 shr;
> > +	u64 temp;
> > +
> > +	/* Number of clocks per internal offset period */
> > +	u32 offset = imx283->mode->mode == IMX283_MODE_0 ? 209 : 157;
> > +
> > +	temp = ((u64)exposure * hmax - offset);
> > +	do_div(temp, hmax);
> > +	shr = (u32)(vmax * (svr + 1) - temp);
> > +
> > +	return shr;
> > +}
> > +
> > +static const char * const imx283_tpg_menu[] = {
> > +	"Disabled",
> > +	"All 000h",
> > +	"All FFFh",
> > +	"All 555h",
> > +	"All AAAh",
> > +	"Horizontal color bars",
> > +	"Vertical color bars",
> > +};
> > +
> > +static const int imx283_tpg_val[] = {
> > +	IMX283_TPG_PAT_ALL_000,
> > +	IMX283_TPG_PAT_ALL_000,
> > +	IMX283_TPG_PAT_ALL_FFF,
> > +	IMX283_TPG_PAT_ALL_555,
> > +	IMX283_TPG_PAT_ALL_AAA,
> > +	IMX283_TPG_PAT_H_COLOR_BARS,
> > +	IMX283_TPG_PAT_V_COLOR_BARS,
> > +};
> > +
> > +static int imx283_update_test_pattern(struct imx283 *imx283, u32 pattern_index)
> > +{
> > +	int ret;
> > +
> > +	if (pattern_index >= ARRAY_SIZE(imx283_tpg_val))
> > +		return -EINVAL;
> > +
> > +	if (pattern_index) {
> > +		ret = cci_write(imx283->cci, IMX283_REG_TPG_PAT,
> > +				imx283_tpg_val[pattern_index], NULL);
> > +		if (ret)
> > +			return ret;
> > +
> > +		ret = cci_write(imx283->cci, IMX283_REG_TPG_CTRL,
> > +				IMX283_TPG_CTRL_CLKEN | IMX283_TPG_CTRL_PATEN, NULL);
> > +	} else {
> > +		ret = cci_write(imx283->cci, IMX283_REG_TPG_CTRL, 0x00, NULL);
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static int imx283_set_ctrl(struct v4l2_ctrl *ctrl)
> > +{
> > +	struct imx283 *imx283 = container_of(ctrl->handler, struct imx283,
> > +					     ctrl_handler);
> > +	const struct imx283_mode *mode = imx283->mode;
> > +	u64 shr, pixel_rate;
> > +	int ret = 0;
> > +
> > +	/*
> > +	 * The VBLANK control may change the limits of usable exposure, so check
> > +	 * and adjust if necessary.
> > +	 */
> > +	if (ctrl->id == V4L2_CID_VBLANK) {
> > +		/* Honour the VBLANK limits when setting exposure. */
> > +		u64 current_exposure, max_exposure, min_exposure;
> > +
> > +		imx283->vmax = mode->height + ctrl->val;
> > +
> > +		imx283_exposure_limits(imx283, &min_exposure, &max_exposure);
> > +
> > +		current_exposure = imx283->exposure->val;
> > +		current_exposure = clamp_t(u32, current_exposure, min_exposure,
> > +					   max_exposure);
> > +
> > +		__v4l2_ctrl_modify_range(imx283->exposure, min_exposure,
> > +					 max_exposure, 1, current_exposure);
> > +	}
> > +
> > +	/*
> > +	 * Applying V4L2 control value only happens
> > +	 * when power is up for streaming
> > +	 */
> > +	if (pm_runtime_get_if_in_use(imx283->dev) == 0)
> 
> As you're using autosuspend, you should use the if_active variant here.
> 
> > +		return 0;
> > +
> > +	switch (ctrl->id) {
> > +	case V4L2_CID_EXPOSURE:
> > +		shr = imx283_shr(imx283, ctrl->val);
> > +		dev_dbg(imx283->dev, "V4L2_CID_EXPOSURE : %d - SHR: %lld\n",
> > +			ctrl->val, shr);
> > +		ret = cci_write(imx283->cci, IMX283_REG_SHR, shr, NULL);
> > +		break;
> > +
> > +	case V4L2_CID_HBLANK:
> > +		pixel_rate = imx283_pixel_rate(imx283);
> > +		imx283->hmax = imx283_internal_clock(pixel_rate, mode->width + ctrl->val);
> > +		dev_dbg(imx283->dev, "V4L2_CID_HBLANK : %d  HMAX : %d\n",
> > +			ctrl->val, imx283->hmax);
> > +		ret = cci_write(imx283->cci, IMX283_REG_HMAX, imx283->hmax, NULL);
> > +		break;
> > +
> > +	case V4L2_CID_VBLANK:
> > +		imx283->vmax = mode->height + ctrl->val;
> > +		dev_dbg(imx283->dev, "V4L2_CID_VBLANK : %d  VMAX : %d\n",
> > +			ctrl->val, imx283->vmax);
> > +		ret = cci_write(imx283->cci, IMX283_REG_VMAX, imx283->vmax, NULL);
> > +		break;
> > +
> > +	case V4L2_CID_ANALOGUE_GAIN:
> > +		ret = cci_write(imx283->cci, IMX283_REG_ANALOG_GAIN, ctrl->val, NULL);
> > +		break;
> > +
> > +	case V4L2_CID_DIGITAL_GAIN:
> > +		ret = cci_write(imx283->cci, IMX283_REG_DIGITAL_GAIN, ctrl->val, NULL);
> > +		break;
> > +
> > +	case V4L2_CID_VFLIP:
> > +		/*
> > +		 * VFLIP is managed by BIT(0) of IMX283_REG_HTRIMMING address, hence
> > +		 * both needed to be set simulatenously.
> > +		 */
> > +		if (ctrl->val) {
> > +			cci_write(imx283->cci, IMX283_REG_HTRIMMING,
> > +				  IMX283_HTRIMMING_EN | IMX283_MDVREV, &ret);
> > +		} else {
> > +			cci_write(imx283->cci, IMX283_REG_HTRIMMING,
> > +				  IMX283_HTRIMMING_EN, &ret);
> > +		}
> > +		break;
> > +
> > +	case V4L2_CID_TEST_PATTERN:
> > +		ret = imx283_update_test_pattern(imx283, ctrl->val);
> > +		break;
> > +
> > +	default:
> > +		dev_err(imx283->dev, "ctrl(id:0x%x, val:0x%x) is not handled\n",
> > +			ctrl->id, ctrl->val);
> > +		break;
> > +	}
> > +
> > +	pm_runtime_put(imx283->dev);
> > +
> > +	return ret;
> > +}
> > +
> > +static const struct v4l2_ctrl_ops imx283_ctrl_ops = {
> > +	.s_ctrl = imx283_set_ctrl,
> > +};
> > +
> > +static int imx283_enum_mbus_code(struct v4l2_subdev *sd,
> > +				 struct v4l2_subdev_state *sd_state,
> > +				 struct v4l2_subdev_mbus_code_enum *code)
> > +{
> > +	if (code->index >= (ARRAY_SIZE(codes)))
> 
> Extra parentheses.
> 
> > +		return -EINVAL;
> > +
> > +	code->code = codes[code->index];
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx283_enum_frame_size(struct v4l2_subdev *sd,
> > +				  struct v4l2_subdev_state *sd_state,
> > +				  struct v4l2_subdev_frame_size_enum *fse)
> > +{
> > +	const struct imx283_mode *mode_list;
> > +	unsigned int num_modes;
> > +
> > +	get_mode_table(fse->code, &mode_list, &num_modes);
> > +
> > +	if (fse->index >= num_modes)
> > +		return -EINVAL;
> > +
> > +	fse->min_width = mode_list[fse->index].width;
> > +	fse->max_width = fse->min_width;
> > +	fse->min_height = mode_list[fse->index].height;
> > +	fse->max_height = fse->min_height;
> > +
> > +	return 0;
> > +}
> > +
> > +static void imx283_reset_colorspace(struct v4l2_mbus_framefmt *fmt)

Inline this in its only caller.

> > +{
> > +	fmt->colorspace = V4L2_COLORSPACE_RAW;
> > +	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);

The sensor outputs raw formats only, it would be clearer to set these
four values explicitly.

> > +}
> > +
> > +static void imx283_update_image_pad_format(struct imx283 *imx283,
> > +					   const struct imx283_mode *mode,
> > +					   struct v4l2_mbus_framefmt *format)
> > +{
> > +	format->width = mode->width;
> > +	format->height = mode->height;
> > +	format->field = V4L2_FIELD_NONE;
> > +	imx283_reset_colorspace(format);
> > +}
> > +
> > +static int imx283_init_state(struct v4l2_subdev *sd,
> > +			     struct v4l2_subdev_state *state)
> > +{
> > +	struct imx283 *imx283 = to_imx283(sd);
> > +	struct v4l2_mbus_framefmt *format;
> > +	const struct imx283_mode *mode;
> > +	struct v4l2_rect *crop;
> > +
> > +	/* Initialize try_fmt */
> > +	format = v4l2_subdev_state_get_format(state, IMAGE_PAD);
> > +
> > +	mode = &supported_modes_12bit[0];
> > +	imx283->mode = mode;
> > +	format->code = MEDIA_BUS_FMT_SRGGB12_1X12;
> > +	imx283_update_image_pad_format(imx283, mode, format);
> > +
> > +	/* Initialize crop rectangle to mode default */
> > +	crop = v4l2_subdev_state_get_crop(state, IMAGE_PAD);
> > +	*crop = mode->crop;
> > +
> > +	return 0;
> > +}
> > +
> > +static void imx283_set_framing_limits(struct imx283 *imx283)
> > +{
> > +	const struct imx283_mode *mode = imx283->mode;
> > +	u64 pixel_rate = imx283_pixel_rate(imx283);
> > +	u64 min_hblank, max_hblank, def_hblank;
> > +
> > +	/*
> > +	 * Initialise hmax and vmax for exposure calculations
> > +	 */
> 
> 	/* Single-line comment */
> 
> > +	imx283->hmax = imx283_internal_clock(pixel_rate, mode->default_hmax);
> > +	imx283->vmax = mode->default_vmax;
> > +
> > +	/*
> > +	 * Horizontal Blanking
> > +	 * Convert the HMAX_MAX (72MHz) to Pixel rate values for HBLANK_MAX
> > +	 */
> > +	min_hblank = mode->min_hmax - mode->width;
> > +	max_hblank = imx283_iclk_to_pix(pixel_rate, IMX283_HMAX_MAX) - mode->width;
> > +	def_hblank = mode->default_hmax - mode->width;
> > +	__v4l2_ctrl_modify_range(imx283->hblank, min_hblank, max_hblank, 1,
> > +				 def_hblank);
> > +	__v4l2_ctrl_s_ctrl(imx283->hblank, def_hblank);
> > +
> > +	/* Vertical Blanking */
> > +	__v4l2_ctrl_modify_range(imx283->vblank, mode->min_vmax - mode->height,
> > +				 IMX283_VMAX_MAX - mode->height, 1,
> > +				 mode->default_vmax - mode->height);
> > +	__v4l2_ctrl_s_ctrl(imx283->vblank, mode->default_vmax - mode->height);
> > +}
> > +
> > +static int imx283_set_pad_format(struct v4l2_subdev *sd,
> > +				 struct v4l2_subdev_state *sd_state,
> > +				 struct v4l2_subdev_format *fmt)
> > +{
> > +	struct v4l2_mbus_framefmt *format;
> > +	const struct imx283_mode *mode;
> > +	struct imx283 *imx283 = to_imx283(sd);
> > +	const struct imx283_mode *mode_list;
> > +	unsigned int num_modes;
> > +
> > +	get_mode_table(fmt->format.code, &mode_list, &num_modes);
> > +
> > +	mode = v4l2_find_nearest_size(mode_list, num_modes, width, height,
> > +				      fmt->format.width, fmt->format.height);
> > +
> > +	imx283_update_image_pad_format(imx283, mode, &fmt->format);

The only thing you can set here is the width and height, it would be
more efficient to copy them explicitly to the format, and then set
fmt->format = *format.

> > +
> > +	format = v4l2_subdev_state_get_format(sd_state, 0);
> > +
> > +	if (imx283->mode == mode && format->code == fmt->format.code)
> > +		return 0;

I'd drop this.

> > +
> > +	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
> > +		imx283->mode = mode;
> > +		imx283->fmt_code = fmt->format.code;
> 
> The code is available in sub-device state.
> 
> > +		imx283_set_framing_limits(imx283);
> > +	}
> > +
> > +	*format = fmt->format;
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx283_standby_cancel(struct imx283 *imx283)
> > +{
> > +	int ret = 0;
> > +	unsigned int link_freq_idx;
> 
> Please declare ret as last.
> 
> > +
> > +	cci_write(imx283->cci, IMX283_REG_STANDBY,
> > +		  IMX283_STBLOGIC | IMX283_STBDV, &ret);
> > +
> > +	/* Configure PLL clocks based on the xclk */
> > +	cci_multi_reg_write(imx283->cci, imx283->freq->regs,
> > +			    imx283->freq->reg_count, &ret);
> > +
> > +	dev_dbg(imx283->dev, "Using clk freq %d MHz", imx283->freq->mhz / MHZ(1));
> > +
> > +	/* Initialise communication */
> > +	cci_write(imx283->cci, IMX283_REG_PLSTMG08, IMX283_PLSTMG08_VAL, &ret);
> > +	cci_write(imx283->cci, IMX283_REG_PLSTMG02, IMX283_PLSTMG02_VAL, &ret);
> > +
> > +	/* Enable PLL */
> > +	cci_write(imx283->cci, IMX283_REG_STBPL, IMX283_STBPL_NORMAL, &ret);
> > +
> > +	/* Configure the MIPI link speed */
> > +	link_freq_idx = __ffs(imx283->link_freq_bitmap);
> > +	cci_multi_reg_write(imx283->cci,
> > +			    link_freq_reglist[link_freq_idx].regs,
> > +			    link_freq_reglist[link_freq_idx].num_of_regs,
> > +			    &ret);
> > +
> > +	usleep_range(1000, 2000); /* 1st Stabilisation period of 1 ms or more */
> > +
> > +	/* Activate */
> > +	cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_ACTIVE, &ret);
> > +	usleep_range(19000, 20000); /* 2nd Stabilisation period of 19ms or more */
> > +
> > +	cci_write(imx283->cci, IMX283_REG_CLAMP, IMX283_CLPSQRST, &ret);
> > +	cci_write(imx283->cci, IMX283_REG_XMSTA, 0, &ret);
> > +	cci_write(imx283->cci, IMX283_REG_SYNCDRV, IMX283_SYNCDRV_XHS_XVS, &ret);
> > +
> > +	return ret;
> > +}
> > +
> > +/* Start streaming */
> > +static int imx283_start_streaming(struct imx283 *imx283,
> > +				  struct v4l2_subdev_state *state)
> > +{
> > +	const struct imx283_readout_mode *readout;
> > +	const struct imx283_mode *mode = imx283->mode;
> > +	u32 v_widcut;
> > +	s32 v_pos;
> > +	u32 write_v_size;
> > +	u32 y_out_size;
> > +	int ret;
> > +
> > +	ret = imx283_standby_cancel(imx283);
> > +	if (ret) {
> > +		dev_err(imx283->dev, "failed to cancel standby\n");
> > +		return ret;
> > +	}
> > +
> > +	/*
> > +	 * Set the readout mode registers.
> > +	 * MDSEL3 and MDSEL4 are updated to enable Arbitrary Vertical Cropping.
> > +	 */
> > +	readout = &imx283_readout_modes[imx283->mode->mode];
> > +	cci_write(imx283->cci, IMX283_REG_MDSEL1, readout->mdsel1, &ret);
> > +	cci_write(imx283->cci, IMX283_REG_MDSEL2, readout->mdsel2, &ret);
> > +	cci_write(imx283->cci, IMX283_REG_MDSEL3,
> > +		  readout->mdsel3 | IMX283_MDSEL3_VCROP_EN, &ret);
> > +	cci_write(imx283->cci, IMX283_REG_MDSEL4,
> > +		  readout->mdsel4 | IMX283_MDSEL4_VCROP_EN, &ret);
> > +
> > +	/* Mode 1S specific entries from the Readout Drive Mode Tables */
> > +	if (mode->mode == IMX283_MODE_1S) {
> > +		cci_write(imx283->cci, IMX283_REG_MDSEL7, 0x01, &ret);
> > +		cci_write(imx283->cci, IMX283_REG_MDSEL18, 0x1098, &ret);
> > +	}
> > +
> > +	if (ret) {
> > +		dev_err(imx283->dev, "%s failed to set readout\n", __func__);
> > +		return ret;
> > +	}
> > +
> > +	/* Initialise SVR. Unsupported for now - Always 0 */
> > +	cci_write(imx283->cci, IMX283_REG_SVR, 0x00, &ret);
> > +
> > +	dev_dbg(imx283->dev, "Mode: Size %d x %d\n", mode->width, mode->height);
> > +	dev_dbg(imx283->dev, "Analogue Crop (in the mode) %d,%d %dx%d\n",
> > +		mode->crop.left,
> > +		mode->crop.top,
> > +		mode->crop.width,
> > +		mode->crop.height);
> > +
> > +	y_out_size = mode->crop.height / mode->vbin_ratio;
> > +	write_v_size = y_out_size + mode->vertical_ob;
> > +	/*
> > +	 * cropping start position = (VWINPOS ? Vst) ? 2
> > +	 * cropping width = Veff ? (VWIDCUT ? Vct) ? 2
> > +	 */
> > +	v_pos = imx283->vflip->val ?
> > +		((-mode->crop.top / mode->vbin_ratio) / 2) + mode->vst :
> > +		((mode->crop.top / mode->vbin_ratio) / 2)  + mode->vst;
> > +	v_widcut = ((mode->veff - y_out_size) / 2) + mode->vct;
> > +
> > +	cci_write(imx283->cci, IMX283_REG_Y_OUT_SIZE, y_out_size, &ret);
> > +	cci_write(imx283->cci, IMX283_REG_WRITE_VSIZE, write_v_size, &ret);
> > +	cci_write(imx283->cci, IMX283_REG_VWIDCUT, v_widcut, &ret);
> > +	cci_write(imx283->cci, IMX283_REG_VWINPOS, v_pos, &ret);
> > +
> > +	cci_write(imx283->cci, IMX283_REG_OB_SIZE_V, mode->vertical_ob, &ret);
> > +
> > +	/* TODO: Validate mode->crop is fully contained within imx283_native_area */
> > +	cci_write(imx283->cci, IMX283_REG_HTRIMMING_START, mode->crop.left, &ret);
> > +	cci_write(imx283->cci, IMX283_REG_HTRIMMING_END,
> > +		  mode->crop.left + mode->crop.width, &ret);
> > +
> > +	/* Disable embedded data */
> > +	cci_write(imx283->cci, IMX283_REG_EBD_X_OUT_SIZE, 0, &ret);
> > +
> > +	/* Apply customized values from controls (HMAX/VMAX/SHR) */
> > +	ret =  __v4l2_ctrl_handler_setup(imx283->sd.ctrl_handler);
> 
> 	return ...;
> 
> What does actually start streaming on the sensor here?
> 
> Shouldn't the control handler's setup be called before that (and much of
> what happens previous to that)?
> 
> > +
> > +	return ret;
> > +}
> > +
> > +/* Stop streaming */
> > +static void imx283_stop_streaming(struct imx283 *imx283)
> > +{
> > +	int ret;
> > +
> > +	ret = cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_STBLOGIC, NULL);
> > +	if (ret)
> > +		dev_err(imx283->dev, "%s failed to set stream\n", __func__);
> > +
> > +	pm_runtime_put(imx283->dev);
> > +}
> > +
> > +static int imx283_set_stream(struct v4l2_subdev *sd, int enable)
> > +{
> > +	struct imx283 *imx283 = to_imx283(sd);
> > +	struct v4l2_subdev_state *state;
> > +	int ret = 0;
> > +
> > +	state = v4l2_subdev_lock_and_get_active_state(sd);
> > +
> > +	if (enable) {
> > +		ret = pm_runtime_get_sync(imx283->dev);
> > +		if (ret < 0) {
> > +			pm_runtime_put_noidle(imx283->dev);
> > +			goto unlock;
> > +		}
> > +
> > +		/*
> > +		 * Apply default & customized values
> > +		 * and then start streaming.
> > +		 */
> > +		ret = imx283_start_streaming(imx283, state);
> > +		if (ret)
> > +			goto err_rpm_put;
> > +	} else {
> > +		imx283_stop_streaming(imx283);
> > +	}
> > +
> > +	v4l2_subdev_unlock_state(state);
> > +
> > +	return ret;
> > +
> > +err_rpm_put:
> > +	pm_runtime_put(imx283->dev);
> > +unlock:
> > +	v4l2_subdev_unlock_state(state);
> > +
> > +	return ret;
> > +}
> > +
> > +/* Power/clock management functions */
> > +static int imx283_power_on(struct device *dev)
> > +{
> > +	struct i2c_client *client = to_i2c_client(dev);
> > +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > +	struct imx283 *imx283 = to_imx283(sd);
> > +	int ret;
> > +
> > +	ret = regulator_bulk_enable(ARRAY_SIZE(imx283_supply_name),
> > +				    imx283->supplies);
> > +	if (ret) {
> > +		dev_err(imx283->dev, "%s: failed to enable regulators\n",
> > +			__func__);
> > +		return ret;
> > +	}
> > +
> > +	ret = clk_prepare_enable(imx283->xclk);
> > +	if (ret) {
> > +		dev_err(imx283->dev, "%s: failed to enable clock\n",
> > +			__func__);
> > +		goto reg_off;
> > +	}
> > +
> > +	gpiod_set_value_cansleep(imx283->reset_gpio, 1);
> > +
> > +	usleep_range(imx283_XCLR_MIN_DELAY_US,
> > +		     imx283_XCLR_MIN_DELAY_US + imx283_XCLR_DELAY_RANGE_US);
> > +
> > +	return 0;
> > +
> > +reg_off:
> > +	regulator_bulk_disable(ARRAY_SIZE(imx283_supply_name), imx283->supplies);
> > +	return ret;
> > +}
> > +
> > +static int imx283_power_off(struct device *dev)
> > +{
> > +	struct i2c_client *client = to_i2c_client(dev);
> > +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > +	struct imx283 *imx283 = to_imx283(sd);
> > +
> > +	gpiod_set_value_cansleep(imx283->reset_gpio, 0);
> > +	regulator_bulk_disable(ARRAY_SIZE(imx283_supply_name), imx283->supplies);
> > +	clk_disable_unprepare(imx283->xclk);
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx283_get_regulators(struct imx283 *imx283)
> > +{
> > +	unsigned int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(imx283_supply_name); i++)
> > +		imx283->supplies[i].supply = imx283_supply_name[i];
> > +
> > +	return devm_regulator_bulk_get(imx283->dev,
> > +				       ARRAY_SIZE(imx283_supply_name),
> > +				       imx283->supplies);
> > +}
> > +
> > +/* Verify chip ID */
> > +static int imx283_identify_module(struct imx283 *imx283)
> > +{
> > +	int ret;
> > +	u64 val;
> > +
> > +	ret = cci_read(imx283->cci, IMX283_REG_CHIP_ID, &val, NULL);
> > +	if (ret) {
> > +		dev_err(imx283->dev, "failed to read chip id %x, with error %d\n",
> > +			IMX283_CHIP_ID, ret);
> > +		return ret;
> > +	}
> > +
> > +	if (val != IMX283_CHIP_ID) {
> > +		dev_err(imx283->dev, "chip id mismatch: %x!=%llx\n",
> > +			IMX283_CHIP_ID, val);
> > +		return -EIO;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx283_get_selection(struct v4l2_subdev *sd,
> > +				struct v4l2_subdev_state *sd_state,
> > +				struct v4l2_subdev_selection *sel)
> > +{
> > +	switch (sel->target) {
> > +	case V4L2_SEL_TGT_CROP: {
> > +		sel->r = *v4l2_subdev_state_get_crop(sd_state, 0);
> > +		return 0;
> > +	}
> > +
> > +	case V4L2_SEL_TGT_NATIVE_SIZE:
> > +		sel->r = imx283_native_area;
> > +		return 0;
> > +
> > +	case V4L2_SEL_TGT_CROP_DEFAULT:
> > +	case V4L2_SEL_TGT_CROP_BOUNDS:
> > +		sel->r = imx283_active_area;
> > +		return 0;
> > +	}
> > +
> > +	return -EINVAL;
> > +}
> > +
> > +static const struct v4l2_subdev_core_ops imx283_core_ops = {
> > +	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> > +	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
> > +};
> > +
> > +static const struct v4l2_subdev_video_ops imx283_video_ops = {
> > +	.s_stream = imx283_set_stream,
> > +};
> > +
> > +static const struct v4l2_subdev_pad_ops imx283_pad_ops = {
> > +	.enum_mbus_code = imx283_enum_mbus_code,
> > +	.get_fmt = v4l2_subdev_get_fmt,
> > +	.set_fmt = imx283_set_pad_format,
> > +	.get_selection = imx283_get_selection,
> > +	.enum_frame_size = imx283_enum_frame_size,
> > +};
> > +
> > +static const struct v4l2_subdev_internal_ops imx283_internal_ops = {
> > +	.init_state = imx283_init_state,
> > +};
> > +
> > +static const struct v4l2_subdev_ops imx283_subdev_ops = {
> > +	.core = &imx283_core_ops,
> > +	.video = &imx283_video_ops,
> > +	.pad = &imx283_pad_ops,
> > +};
> > +
> > +/* Initialize control handlers */
> > +static int imx283_init_controls(struct imx283 *imx283)
> > +{
> > +	struct v4l2_ctrl_handler *ctrl_hdlr;
> > +	struct v4l2_fwnode_device_properties props;
> > +	const struct imx283_mode *mode = imx283->mode;
> > +	u64 min_hblank, max_hblank, def_hblank;
> > +	u64 pixel_rate;
> > +	int ret;
> > +
> > +	ctrl_hdlr = &imx283->ctrl_handler;
> > +	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Serialize controls with sensor device */
> > +	ctrl_hdlr->lock = &imx283->mutex;
> > +
> > +	/*
> > +	 * Create the controls here, but mode specific limits are setup
> > +	 * in the imx283_set_framing_limits() call below.
> > +	 */
> > +
> > +	/* By default, PIXEL_RATE is read only */
> > +	pixel_rate = imx283_pixel_rate(imx283);
> > +	imx283->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
> > +					       V4L2_CID_PIXEL_RATE, pixel_rate,
> > +					       pixel_rate, 1, pixel_rate);
> > +
> > +	imx283->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx283_ctrl_ops,
> > +						   V4L2_CID_LINK_FREQ,
> > +						   __fls(imx283->link_freq_bitmap),
> > +						   __ffs(imx283->link_freq_bitmap),
> > +						   link_frequencies);
> > +	if (imx283->link_freq)
> > +		imx283->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > +	/* Initialise vblank/hblank/exposure based on the current mode. */
> > +	imx283->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
> > +					   V4L2_CID_VBLANK,
> > +					   mode->min_vmax - mode->height,
> > +					   IMX283_VMAX_MAX, 1,
> > +					   mode->default_vmax - mode->height);
> > +
> > +	min_hblank = mode->min_hmax - mode->width;
> > +	max_hblank = imx283_iclk_to_pix(pixel_rate, IMX283_HMAX_MAX) - mode->width;
> > +	def_hblank = mode->default_hmax - mode->width;
> > +	imx283->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
> > +					   V4L2_CID_HBLANK, min_hblank, max_hblank,
> > +					   1, def_hblank);
> > +
> > +	imx283->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
> > +					     V4L2_CID_EXPOSURE,
> > +					     IMX283_EXPOSURE_MIN,
> > +					     IMX283_EXPOSURE_MAX,
> > +					     IMX283_EXPOSURE_STEP,
> > +					     IMX283_EXPOSURE_DEFAULT);
> > +
> > +	v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
> > +			  IMX283_ANA_GAIN_MIN, IMX283_ANA_GAIN_MAX,
> > +			  IMX283_ANA_GAIN_STEP, IMX283_ANA_GAIN_DEFAULT);
> > +
> > +	v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
> > +			  IMX283_DGTL_GAIN_MIN, IMX283_DGTL_GAIN_MAX,
> > +			  IMX283_DGTL_GAIN_STEP, IMX283_DGTL_GAIN_DEFAULT);
> > +
> > +	imx283->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_VFLIP,
> > +					  0, 1, 1, 0);
> > +	if (imx283->vflip)
> > +		imx283->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
> > +
> > +	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx283_ctrl_ops,
> > +				     V4L2_CID_TEST_PATTERN,
> > +				     ARRAY_SIZE(imx283_tpg_menu) - 1,
> > +				     0, 0, imx283_tpg_menu);
> > +
> > +	if (ctrl_hdlr->error) {
> > +		ret = ctrl_hdlr->error;
> > +		dev_err(imx283->dev, "%s control init failed (%d)\n",
> > +			__func__, ret);
> > +		goto error;
> > +	}
> > +
> > +	ret = v4l2_fwnode_device_parse(imx283->dev, &props);
> > +	if (ret)
> > +		goto error;
> > +
> > +	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx283_ctrl_ops,
> > +					      &props);
> > +	if (ret)
> > +		goto error;
> > +
> > +	imx283->sd.ctrl_handler = ctrl_hdlr;
> > +
> > +	mutex_lock(&imx283->mutex);
> > +
> > +	ret = __v4l2_ctrl_s_ctrl(imx283->link_freq,
> > +				 __ffs(imx283->link_freq_bitmap));
> 
> Is this needed? The default is already set when creating the control.
> 
> > +	if (ret)
> > +		goto error;
> > +
> > +	/* Setup exposure and frame/line length limits. */
> > +	imx283_set_framing_limits(imx283);
> > +
> > +	mutex_unlock(&imx283->mutex);
> > +
> > +	return 0;
> > +
> > +error:
> > +	v4l2_ctrl_handler_free(ctrl_hdlr);
> > +
> > +	return ret;
> > +}
> > +
> > +static void imx283_free_controls(struct imx283 *imx283)
> > +{
> > +	v4l2_ctrl_handler_free(imx283->sd.ctrl_handler);
> 
> You could call v4l2_ctrl_handler_free() directly.
> 
> > +}
> > +
> > +static const struct of_device_id imx283_dt_ids[] = {
> > +	{ .compatible = "sony,imx283", },
> > +	{ /* sentinel */ }
> > +};
> > +
> > +static int imx283_parse_endpoint(struct imx283 *imx283)
> > +{
> > +	struct fwnode_handle *fwnode = dev_fwnode(imx283->dev);
> > +	struct v4l2_fwnode_endpoint bus_cfg = {
> > +		.bus_type = V4L2_MBUS_CSI2_DPHY
> > +	};
> > +	struct fwnode_handle *ep;
> > +	int ret;
> > +
> > +	if (!fwnode)
> > +		return -ENXIO;
> > +
> > +	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> > +	if (!ep) {
> > +		dev_err(imx283->dev, "Failed to get next endpoint\n");
> > +		return -ENXIO;
> > +	}
> > +
> > +	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> > +	fwnode_handle_put(ep);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
> > +		dev_err(imx283->dev,
> > +			"number of CSI2 data lanes %d is not supported\n",
> > +			bus_cfg.bus.mipi_csi2.num_data_lanes);
> > +		ret = -EINVAL;
> > +		goto done_endpoint_free;
> > +	}
> > +
> > +	ret = v4l2_link_freq_to_bitmap(imx283->dev, bus_cfg.link_frequencies,
> > +				       bus_cfg.nr_of_link_frequencies,
> > +				       link_frequencies, ARRAY_SIZE(link_frequencies),
> > +				       &imx283->link_freq_bitmap);
> > +
> > +done_endpoint_free:
> > +	v4l2_fwnode_endpoint_free(&bus_cfg);
> > +
> > +	return ret;
> > +};
> > +
> > +static int imx283_probe(struct i2c_client *client)
> > +{
> > +	struct imx283 *imx283;
> > +	int ret;
> 
> Please declare ret as last.
> 
> > +	unsigned int i;
> > +	unsigned int xclk_freq;
> > +
> > +	imx283 = devm_kzalloc(&client->dev, sizeof(*imx283), GFP_KERNEL);
> > +	if (!imx283)
> > +		return -ENOMEM;
> > +
> > +	imx283->dev = &client->dev;
> > +
> > +	v4l2_i2c_subdev_init(&imx283->sd, client, &imx283_subdev_ops);
> > +
> > +	imx283->cci = devm_cci_regmap_init_i2c(client, 16);
> > +	if (IS_ERR(imx283->cci)) {
> > +		ret = PTR_ERR(imx283->cci);
> > +		dev_err(imx283->dev, "failed to initialize CCI: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/* Get system clock (xclk) */
> > +	imx283->xclk = devm_clk_get(imx283->dev, NULL);
> > +	if (IS_ERR(imx283->xclk)) {
> > +		dev_err(imx283->dev, "failed to get xclk\n");

dev_err_probe() would be useful here and in other locations.

> > +		return PTR_ERR(imx283->xclk);
> > +	}
> > +
> > +	xclk_freq = clk_get_rate(imx283->xclk);
> > +	for (i = 0; i < ARRAY_SIZE(imx283_frequencies); i++) {
> > +		if (xclk_freq == imx283_frequencies[i].mhz) {
> > +			imx283->freq = &imx283_frequencies[i];
> > +			break;
> > +		}
> > +	}
> > +	if (!imx283->freq) {
> > +		dev_err(imx283->dev, "xclk frequency unsupported: %d Hz\n", xclk_freq);
> 
> You could also pick the closest value and warn about it, these aren't
> always exactly what's expected. Up to you.
> 
> > +		return -EINVAL;
> > +	}
> > +
> > +	ret = imx283_get_regulators(imx283);
> > +	if (ret) {
> > +		dev_err(imx283->dev, "failed to get regulators\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = imx283_parse_endpoint(imx283);
> > +	if (ret) {
> > +		dev_err(imx283->dev, "failed to parse endpoint configuration\n");
> > +		return ret;
> > +	}
> > +
> > +	/* Request optional enable pin */
> > +	imx283->reset_gpio = devm_gpiod_get_optional(imx283->dev, "reset",
> > +						     GPIOD_OUT_HIGH);
> > +
> > +	mutex_init(&imx283->mutex);
> > +
> > +	/*
> > +	 * The sensor must be powered for imx283_identify_module()
> > +	 * to be able to read the CHIP_ID register
> > +	 */
> > +	ret = imx283_power_on(imx283->dev);
> > +	if (ret)
> 
> mutex_destroy() is missing on this code path (and elsewhere, too).
> 
> > +		return ret;
> > +
> > +	ret = imx283_identify_module(imx283);
> > +	if (ret)
> > +		goto error_power_off;
> > +
> > +	/* Initialize default format and mode to max resolution */
> > +	imx283->mode = &supported_modes_12bit[0];
> > +	imx283->fmt_code = MEDIA_BUS_FMT_SRGGB12_1X12;
> > +
> > +	/*
> > +	 * Enable runtime PM with autosuspend. As the device has been powered
> > +	 * manually, mark it as active, and increase the usage count without
> > +	 * resuming the device.
> > +	 */
> > +	pm_runtime_set_active(imx283->dev);
> > +	pm_runtime_get_noresume(imx283->dev);
> > +	pm_runtime_enable(imx283->dev);
> > +	pm_runtime_set_autosuspend_delay(imx283->dev, 1000);
> > +	pm_runtime_use_autosuspend(imx283->dev);
> > +
> > +	/* This needs the pm runtime to be registered. */
> > +	ret = imx283_init_controls(imx283);
> > +	if (ret)
> > +		goto error_pm;
> > +
> > +	/* Initialize subdev */
> > +	imx283->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> > +			    V4L2_SUBDEV_FL_HAS_EVENTS;
> > +	imx283->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> > +	imx283->sd.internal_ops = &imx283_internal_ops;
> > +
> > +	/* Initialize source pads */
> > +	imx283->pad.flags = MEDIA_PAD_FL_SOURCE;
> > +
> > +	ret = media_entity_pads_init(&imx283->sd.entity, 1, &imx283->pad);
> > +	if (ret) {
> > +		dev_err(imx283->dev, "failed to init entity pads: %d\n", ret);
> > +		goto error_handler_free;
> > +	}
> > +
> > +	imx283->sd.state_lock = imx283->ctrl_handler.lock;
> > +	ret = v4l2_subdev_init_finalize(&imx283->sd);
> > +	if (ret < 0) {
> > +		dev_err(imx283->dev, "subdev init error: %d\n", ret);
> > +		goto error_media_entity;
> > +	}
> > +
> > +	ret = v4l2_async_register_subdev_sensor(&imx283->sd);
> > +	if (ret < 0) {
> > +		dev_err(imx283->dev, "failed to register sensor sub-device: %d\n", ret);
> > +		goto error_subdev_cleanup;
> > +	}
> > +
> > +	return 0;
> > +
> > +error_subdev_cleanup:
> > +	v4l2_subdev_cleanup(&imx283->sd);
> > +
> > +error_media_entity:
> > +	media_entity_cleanup(&imx283->sd.entity);
> > +
> > +error_handler_free:
> > +	imx283_free_controls(imx283);
> > +
> > +error_pm:
> > +	pm_runtime_disable(imx283->dev);
> > +	pm_runtime_set_suspended(imx283->dev);
> > +error_power_off:
> > +	imx283_power_off(imx283->dev);
> > +
> > +	return ret;
> > +}
> > +
> > +static void imx283_remove(struct i2c_client *client)
> > +{
> > +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > +	struct imx283 *imx283 = to_imx283(sd);
> > +
> > +	v4l2_async_unregister_subdev(sd);
> > +	v4l2_subdev_cleanup(&imx283->sd);
> > +	media_entity_cleanup(&sd->entity);
> > +	imx283_free_controls(imx283);
> > +
> > +	pm_runtime_disable(imx283->dev);
> > +	if (!pm_runtime_status_suspended(imx283->dev))
> > +		imx283_power_off(imx283->dev);
> > +	pm_runtime_set_suspended(imx283->dev);
> > +}
> > +
> > +MODULE_DEVICE_TABLE(of, imx283_dt_ids);
> > +
> > +static const struct dev_pm_ops imx283_pm_ops = {
> > +	SET_RUNTIME_PM_OPS(imx283_power_off, imx283_power_on, NULL)
> > +};

You'll get compiler warnings with !CONFIG_PM. You can either mark the
handlers as __maybe_unused, or use RUNTIME_PM_OPS() + pm_ptr() below and
mark this structure as maybe unused.

> > +
> > +static struct i2c_driver imx283_i2c_driver = {
> > +	.driver = {
> > +		.name = "imx283",
> > +		.of_match_table	= imx283_dt_ids,
> > +		.pm = &imx283_pm_ops,
> > +	},
> > +	.probe = imx283_probe,
> > +	.remove = imx283_remove,
> > +};
> > +
> > +module_i2c_driver(imx283_i2c_driver);
> > +
> > +MODULE_AUTHOR("Will Whang <will at willwhang.com>");
> > +MODULE_AUTHOR("Kieran Bingham <kieran.bingham at ideasonboard.com>");
> > +MODULE_AUTHOR("Umang Jain <umang.jain at ideasonboard.com>");
> > +MODULE_DESCRIPTION("Sony IMX283 Sensor Driver");
> > +MODULE_LICENSE("GPL");

-- 
Regards,

Laurent Pinchart


From dmitry.baryshkov at linaro.org  Sun Feb 18 04:53:11 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sun, 18 Feb 2024 14:53:11 +0200
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>

On Fri, 16 Feb 2024 at 22:33, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>
> First, I'd like to apologize for the somewhat chaotic previous iterations
> of this series and improper versioning which was rightfully pointed out
> to me. I figured that the scope changed so much that it didn't make sense
> to consider previous submissions part of the same series as the original
> RFC but others thought otherwise so this one becomes v5 and I'll keep the
> versioning going forward.
>
> This is the summary of the work so far:
>
> v1: Original RFC:
>
> https://lore.kernel.org/lkml/20240104130123.37115-1-brgl at bgdev.pl/T/
>
> v2: First real patch series (should have been PATCH v2) adding what I
>     referred to back then as PCI power sequencing:
>
> https://lore.kernel.org/linux-arm-kernel/2024021413-grumbling-unlivable-c145 at gregkh/T/
>
> v3: RFC for the DT representation of the PMU supplying the WLAN and BT
>     modules inside the QCA6391 package (was largely separate from the
>     series but probably should have been called PATCH or RFC v3):
>
> https://lore.kernel.org/all/CAMRc=Mc+GNoi57eTQg71DXkQKjdaoAmCpB=h2ndEpGnmdhVV-Q at mail.gmail.com/T/
>
> v4: Second attempt at the full series with changed scope (introduction of
>     the pwrseq subsystem, should have been RFC v4)
>
> https://lore.kernel.org/lkml/20240201155532.49707-1-brgl at bgdev.pl/T/
>
> ===
>
> With that out of the way, I'd like to get down to explaining the two
> problems I'm trying to solve.
>
> Problem statement #1: Dynamic bus chicken-and-egg problem.
>
> Certain on-board PCI devices need to be powered up before they are can be
> detected but their PCI drivers won't get bound until the device is
> powered-up so enabling the relevant resources in the PCI device driver
> itself is impossible.
>
> Problem statement #2: Sharing inter-dependent resources between devices.
>
> Certain devices that use separate drivers (often on different busses)
> share resources (regulators, clocks, etc.). Typically these resources
> are reference-counted but in some cases there are additional interactions
> between them to consider, for example specific power-up sequence timings.
>
> ===
>
> The reason for tackling both of these problems in a single series is the
> fact the the platform I'm working on - Qualcomm RB5 - deals with both and
> both need to be addressed in order to enable WLAN and Bluetooth support
> upstream.
>
> The on-board WLAN/BT package - QCA6391 - has a Power Management Unit that
> takes inputs from the host and exposes LDO outputs consumed by the BT and
> WLAN modules which can be powered-up and down independently. However
> a delay of 100ms must be respected between enabling the BT- and
> WLAN-enable GPIOs[*].
>
> ===
>
> This series is logically split into several sections. I'll go
> patch-by-patch and explain each step.
>
> Patch 1/18:
>
> This is a commit taken from the list by Jonathan Cameron that adds
> a __free() helper for OF nodes. Not strictly related to the series but
> until said commit ends in next, I need to carry it with this series.
>
> Patch 2/18:
>
> This enables the ath12k PCI module in arm64 defconfig as Qualcomm sm8650
> and sm8550 reference platforms use it in the WCN7850 module.
>
> Patches 3/18-6/18:
>
> These contain all relevant DT bindings changes. We add new documents for
> the QCA6390 PMU and ATH12K devices as well as extend the bindings for the
> Qualcomm Bluetooth and ATH11K modules with regulators used by them in
> QCA6390.
>
> Patches 7/18-9/18:
>
> These contain changes to device-tree sources for the three platforms we
> work with in this series. As the WCN7850 module doesn't require any
> specific timings introducing dependencies between the Bluetooth and WLAN
> modules, while the QCA6390 does, we take two different approaches to how
> me model them in DT.
>
> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> necessary. The BT and WLAN devices on the device-tree are represented as
> consuming the inputs (relevant to the functionality of each) of the PMU
> directly.

We are describing the hardware. From the hardware point of view, there
is a PMU. I think at some point we would really like to describe all
Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).

> For QCA6390 on RB5 we add the PMU node as a platform device. It consumes
> regulators and GPIOs from the host and exposed regulators consumer in turn
> by the BT and WLAN modules. This represents the internal structure of the
> package.
>
> Patches 10/18-14/18:
>
> These contain the bulk of the PCI changes for this series. We introduce
> a simple framework for powering up PCI devices before detecting them on
> the bus and the first user of this library in the form of the WCN7850 PCI
> power control driver.
>
> The general approach is as follows: PCI devices that need special
> treatment before they can be powered up, scanned and bound to their PCI
> drivers must be described on the device-tree as child nodes of the PCI
> port node. These devices will be instantiated on the platform bus. They
> will in fact be generic platform devices with the compatible of the form
> used for PCI devices already upstream ("pci<vendor ID>,<device ID">). We
> add a new directory under drivers/pci/pwrctl/ that contains PCI pwrctl
> drivers. These drivers are platform drivers that will now be matched
> against the devices instantiated from port children just like any other
> platform pairs.
>
> Both the power control platform device *AND* the associated PCI device
> reuse the same OF node and have access to the same properties. The goal
> of the platform driver is to request and bring up any required resources
> and let the pwrctl framework know that it's now OK to rescan the bus and
> detect the devices. When the device is bound, we are notified about it
> by the PCI bus notifier event and can establish a device link between the
> power control device and the PCI device so that any future extension for
> power-management will already be able to work with the correct hierachy.
>
> The reusing of the OF node is the reason for the small changes to the PCI
> OF core: as the bootloader can possibly leave the relevant regulators on
> before booting linux, the PCI device can be detected before its platform
> abstraction is probed. In this case, we find that device first and mark
> its OF node as reused. The pwrctl framework handles the opposite case
> (when the PCI device is detected only after the platform driver
> successfully enabled it).
>
> Patches 15/18-16/18:
>
> These add a relatively simple power sequencing subsystem and the first
> driver using it: the pwrseq module for the QCA6390 PMU.
>
> For the record: Bjorn suggested a different solution: a regulator driver
> that would - based on which regulators are enabled by a consumer - enable
> relevant resources (drive the enable GPIOs) while respecting the
> HW-specific delays. This would however require significant and yet
> unprecised changed to the regulator subsystem as well as be an abuse of
> the regulator provider API akin to using the reset framework for power
> sequencing as proposed before.
>
> Instead I'm proposing to add a subsystem that allows different devices to
> use a shared power sequence split into consumer-specific as well as
> common "units".
>
> A power sequence provider driver registers a set of units with pwrseq
> core. Each unit can be enabled and disabled and contains an optional list
> of other units which must be enabled before it itself can be. A unit
> represents a discreet chunk of the power sequence.
>
> It also registers a list of targets: a target is an abstraction wrapping
> a unit which allows consumers to tell pwrseq which unit they want to
> reach. Real-life example is the driver we're adding here: there's a set
> of common regulators, two PCIe-specific ones and two enable GPIOs: one
> for Bluetooth and one for WLAN.
>
> The Bluetooth driver requests a descriptor to the power sequencer and
> names the target it wants to reach:
>
>     pwrseq = devm_pwrseq_get(dev, "bluetooth");

Is this target tied to the device or not? If not, this might become a
limitation, if somebody installs two WiFi/BT modules to a single
device.

> The pwrseq core then knows that when the driver calls:
>
>     pwrseq_power_on(pwrseq);
>
> It must enable the "bluetooth-enable" unit but it depends on the
> "regulators-common" unit so this one is enabled first. The provider
> driver is also in charge of assuring an appropriate delay between
> enabling the BT and WLAN enable GPIOs. The WLAN-specific resources are
> handled by the "wlan-enable" unit and so are not enabled until the WLAN
> driver requests the "wlan" target to be powered on.
>
> Another thing worth discussing is the way we associate the consumer with
> the relevant power sequencer. DT maintainers have expressed a discontent
> with the existing mmc pwrseq bindings and have NAKed an earlier
> initiative to introduce global pwrseq bindings to the kernel[1].
>
> In this approach, we model the existing regulators and GPIOs in DT but
> the pwrseq subsystem requires each provider to provide a .match()
> callback. Whenever a consumer requests a power sequencer handle, we
> iterate over the list of pwrseq drivers and call .match() for each. It's
> up to the driver to verify in a platform-specific way whether it deals
> with its consumer and let the core pwrseq code know.

This looks really nice, it will allow us to migrate the BT driver to
always use pwrseq instead of regulators without touching the DT.

>
> The advantage of this over reusing the regulator or reset subsystem is
> that it's more generalized and can handle resources of all kinds as well
> as deal with any kind of power-on sequences: for instance, Qualcomm has
> a PCI switch they want a driver for but this switch requires enabling
> some resources first (PCI pwrctl) and then configuring the device over
> I2C (which can be handled by the pwrseq provider).
>
> Patch 17/18:
>
> This patch makes the Qualcomm Bluetooth driver get and use the power
> sequencer for QCA6390.
>
> Patch 18/18:
>
> While tiny, this patch is possibly the highlight of the entire series.
> It uses the two abstraction layers we introduced before to create an
> elegant power sequencing PCI power control driver and supports the ath11k
> module on QCA6390.
>
> With this series we can now enable BT and WLAN on several new Qualcomm
> boards upstream.
>
> I tested the series on RB5 while Neil tested it on sm8650-qrd and
> sm8550-qrd.
>
> Best Regards,
> Bartosz Golaszewski
>
> It's hard to list the changes between versions here as the scope changed
> significantly between each iteration and some versions were not even full
> series but rather RFCs for parts of the solution. For this reason, I'll
> only start listing changes starting from v6.
>
> [*] This is what the docs say. In practice it seems that this delay can be
> ignored. However the subsequent model - QCA6490 - *does* require users to
> respect it, so the problem remains valid.
>
> [1] https://lore.kernel.org/netdev/20210829131305.534417-1-dmitry.baryshkov at linaro.org/
>
> Bartosz Golaszewski (15):
>   arm64: defconfig: enable ath12k as a module
>   dt-bindings: regulator: describe the PMU module of the QCA6390 package
>   dt-bindings: net: bluetooth: qualcomm: describe regulators for QCA6390
>   dt-bindings: new: wireless: qcom,ath11k: describe the ath11k on
>     QCA6390
>   dt-bindings: new: wireless: describe the ath12k PCI module
>   arm64: dts: qcom: qrb5165-rb5: model the PMU of the QCA6391
>   PCI: hold the rescan mutex when scanning for the first time
>   PCI/pwrctl: reuse the OF node for power controlled devices
>   PCI/pwrctl: create platform devices for child OF nodes of the port
>     node
>   PCI/pwrctl: add PCI power control core code
>   PCI/pwrctl: add a power control driver for WCN7850
>   power: sequencing: implement the pwrseq core
>   power: pwrseq: add a driver for the QCA6390 PMU module
>   Bluetooth: qca: use the power sequencer for QCA6390
>   PCI/pwrctl: add a PCI power control driver for power sequenced devices
>
> Jonathan Cameron (1):
>   of: Add cleanup.h based auto release via __free(device_node) markings.
>
> Neil Armstrong (2):
>   arm64: dts: qcom: sm8550-qrd: add the Wifi node
>   arm64: dts: qcom: sm8650-qrd: add the Wifi node
>
>  .../net/bluetooth/qualcomm-bluetooth.yaml     |   17 +
>  .../net/wireless/qcom,ath11k-pci.yaml         |   28 +
>  .../net/wireless/qcom,ath12k-pci.yaml         |  103 ++
>  .../bindings/regulator/qcom,qca6390-pmu.yaml  |  166 +++
>  MAINTAINERS                                   |    8 +
>  arch/arm64/boot/dts/qcom/qrb5165-rb5.dts      |  123 +-
>  arch/arm64/boot/dts/qcom/sm8250.dtsi          |   10 +
>  arch/arm64/boot/dts/qcom/sm8550-qrd.dts       |   37 +
>  arch/arm64/boot/dts/qcom/sm8550.dtsi          |   10 +
>  arch/arm64/boot/dts/qcom/sm8650-qrd.dts       |   29 +
>  arch/arm64/boot/dts/qcom/sm8650.dtsi          |   10 +
>  arch/arm64/configs/defconfig                  |    1 +
>  drivers/bluetooth/hci_qca.c                   |   31 +
>  drivers/pci/Kconfig                           |    1 +
>  drivers/pci/Makefile                          |    1 +
>  drivers/pci/bus.c                             |    9 +-
>  drivers/pci/of.c                              |   14 +-
>  drivers/pci/probe.c                           |    2 +
>  drivers/pci/pwrctl/Kconfig                    |   25 +
>  drivers/pci/pwrctl/Makefile                   |    7 +
>  drivers/pci/pwrctl/core.c                     |  136 +++
>  drivers/pci/pwrctl/pci-pwrctl-pwrseq.c        |   84 ++
>  drivers/pci/pwrctl/pci-pwrctl-wcn7850.c       |  202 ++++
>  drivers/pci/remove.c                          |    2 +
>  drivers/power/Kconfig                         |    1 +
>  drivers/power/Makefile                        |    1 +
>  drivers/power/sequencing/Kconfig              |   28 +
>  drivers/power/sequencing/Makefile             |    6 +
>  drivers/power/sequencing/core.c               | 1065 +++++++++++++++++
>  drivers/power/sequencing/pwrseq-qca6390.c     |  353 ++++++
>  include/linux/of.h                            |    2 +
>  include/linux/pci-pwrctl.h                    |   51 +
>  include/linux/pwrseq/consumer.h               |   56 +
>  include/linux/pwrseq/provider.h               |   75 ++
>  34 files changed, 2678 insertions(+), 16 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
>  create mode 100644 Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml
>  create mode 100644 drivers/pci/pwrctl/Kconfig
>  create mode 100644 drivers/pci/pwrctl/Makefile
>  create mode 100644 drivers/pci/pwrctl/core.c
>  create mode 100644 drivers/pci/pwrctl/pci-pwrctl-pwrseq.c
>  create mode 100644 drivers/pci/pwrctl/pci-pwrctl-wcn7850.c
>  create mode 100644 drivers/power/sequencing/Kconfig
>  create mode 100644 drivers/power/sequencing/Makefile
>  create mode 100644 drivers/power/sequencing/core.c
>  create mode 100644 drivers/power/sequencing/pwrseq-qca6390.c
>  create mode 100644 include/linux/pci-pwrctl.h
>  create mode 100644 include/linux/pwrseq/consumer.h
>  create mode 100644 include/linux/pwrseq/provider.h
>
> --
> 2.40.1
>


-- 
With best wishes
Dmitry


From apatel at ventanamicro.com  Sun Feb 18 05:16:14 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Sun, 18 Feb 2024 18:46:14 +0530
Subject: [PATCH v12 18/25] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <87h6i8ckwg.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-19-apatel@ventanamicro.com> <87h6i8ckwg.ffs@tglx>
Message-ID: <CAK9=C2XvYB8qrTvxKvtXspdfiKUro89t-oLRVzeMqczDbG7nrQ@mail.gmail.com>

On Sat, Feb 17, 2024 at 12:10?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> > +
> > +#ifdef CONFIG_SMP
> > +static irqreturn_t imsic_local_sync_handler(int irq, void *data)
> > +{
> > +     imsic_local_sync();
> > +     return IRQ_HANDLED;
> > +}
> > +
> > +static void imsic_ipi_send(unsigned int cpu)
> > +{
> > +     struct imsic_local_config *local =
> > +                             per_cpu_ptr(imsic->global.local, cpu);
>
> Let it stick out. We switched to line length 100 quite some time
> ago. Applies to the rest of the series too.

Okay, I will update.

>
> > +     writel_relaxed(IMSIC_IPI_ID, local->msi_va);
> > +}
> > +
> > +static void imsic_ipi_starting_cpu(void)
> > +{
> > +     /* Enable IPIs for current CPU. */
> > +     __imsic_id_set_enable(IMSIC_IPI_ID);
> > +
> > +     /* Enable virtual IPI used for IMSIC ID synchronization */
> > +     enable_percpu_irq(imsic->ipi_virq, 0);
> > +}
> > +
> > +static void imsic_ipi_dying_cpu(void)
> > +{
> > +     /*
> > +      * Disable virtual IPI used for IMSIC ID synchronization so
> > +      * that we don't receive ID synchronization requests.
> > +      */
> > +     disable_percpu_irq(imsic->ipi_virq);
>
> Shouldn't this disable the hardware too, i.e.
>
>           __imsic_id_clear_enable()
>
> ?

Yes, it should but somehow I missed and never saw any issue.

I will update.

>
> > +}
> > +
> > +static int __init imsic_ipi_domain_init(void)
> > +{
> > +     int virq;
> > +
> > +     /* Create IMSIC IPI multiplexing */
> > +     virq = ipi_mux_create(IMSIC_NR_IPI, imsic_ipi_send);
> > +     if (virq <= 0)
> > +             return (virq < 0) ? virq : -ENOMEM;
> > +     imsic->ipi_virq = virq;
> > +
> > +     /* First vIRQ is used for IMSIC ID synchronization */
> > +     virq = request_percpu_irq(imsic->ipi_virq, imsic_local_sync_handler,
> > +                               "riscv-imsic-lsync", imsic->global.local);
> > +     if (virq)
> > +             return virq;
>
> Please use a separate 'ret' variable. I had to read this 3 times to make
> sense of it.

Okay, I will update.

>
> > +     irq_set_status_flags(imsic->ipi_virq, IRQ_HIDDEN);
> > +     imsic->ipi_lsync_desc = irq_to_desc(imsic->ipi_virq);
>
> What's so special about this particular IPI that it can't be handled
> like all the other IPIs?

We are using this special under-the-hood IPI for synchronization
of IRQ enable/disable and IRQ movement across CPUs.

x86 has a more lazy approach of using a per-CPU timer so in
the next revision I will move to a similar approach. This means
both "ipi_virq" and "ipi_lsync_desc" will go away.

>
> > +static int __init imsic_early_probe(struct fwnode_handle *fwnode)
> > +{
> > +     int rc;
> > +     struct irq_domain *domain;
>
> https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations

Okay, I will update.

>
> > +
> > +     /* Find parent domain and register chained handler */
> > +     domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(),
> > +                                       DOMAIN_BUS_ANY);
> > +     if (!domain) {
> > +             pr_err("%pfwP: Failed to find INTC domain\n", fwnode);
> > +             return -ENOENT;
> > +     }
> > +     imsic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
> > +     if (!imsic_parent_irq) {
> > +             pr_err("%pfwP: Failed to create INTC mapping\n", fwnode);
> > +             return -ENOENT;
> > +     }
> > +     irq_set_chained_handler(imsic_parent_irq, imsic_handle_irq);
> > +
> > +     /* Initialize IPI domain */
> > +     rc = imsic_ipi_domain_init();
> > +     if (rc) {
> > +             pr_err("%pfwP: Failed to initialize IPI domain\n", fwnode);
> > +             return rc;
>
> Leaves the chained handler around and enabled.

Okay, I will set the chained hander after imsic_ipi_domain_init().

>
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > +
> > +#define imsic_csr_write(__c, __v)            \
> > +do {                                         \
> > +     csr_write(CSR_ISELECT, __c);            \
> > +     csr_write(CSR_IREG, __v);               \
> > +} while (0)
>
> Any reason why these macros can't be inlines?

No particular reason. I am fine with both maros and inline functions.

I will update in the next revision.

>
> > +const struct imsic_global_config *imsic_get_global_config(void)
> > +{
> > +     return imsic ? &imsic->global : NULL;
> > +}
> > +EXPORT_SYMBOL_GPL(imsic_get_global_config);
>
> Why is this exported?

This is for the KVM RISC-V module. We have follow up
KVM RISC-V patchs which need to know the IMSIC global
configuration so that it can assign IMSIC guest files to a
Guest/VM.

>
> > +#define __imsic_id_read_clear_enabled(__id)          \
> > +     __imsic_eix_read_clear((__id), false)
> > +#define __imsic_id_read_clear_pending(__id)          \
> > +     __imsic_eix_read_clear((__id), true)
>
> Please use inlines.

Okay, I will update.

>
> > +void __imsic_eix_update(unsigned long base_id,
> > +                     unsigned long num_id, bool pend, bool val)
> > +{
> > +     unsigned long i, isel, ireg;
> > +     unsigned long id = base_id, last_id = base_id + num_id;
> > +
> > +     while (id < last_id) {
> > +             isel = id / BITS_PER_LONG;
> > +             isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
> > +             isel += (pend) ? IMSIC_EIP0 : IMSIC_EIE0;
> > +
> > +             ireg = 0;
> > +             for (i = id & (__riscv_xlen - 1);
> > +                  (id < last_id) && (i < __riscv_xlen); i++) {
> > +                     ireg |= BIT(i);
> > +                     id++;
> > +             }
>
> This lacks a comment what this is doing.

Okay, I will add a comment block.

>
> > +
> > +             /*
> > +              * The IMSIC EIEx and EIPx registers are indirectly
> > +              * accessed via using ISELECT and IREG CSRs so we
> > +              * need to access these CSRs without getting preempted.
> > +              *
> > +              * All existing users of this function call this
> > +              * function with local IRQs disabled so we don't
> > +              * need to do anything special here.
> > +              */
> > +             if (val)
> > +                     imsic_csr_set(isel, ireg);
> > +             else
> > +                     imsic_csr_clear(isel, ireg);
> > +     }
> > +}
> > +
> > +void imsic_local_sync(void)
> > +{
> > +     struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> > +     struct imsic_local_config *mlocal;
> > +     struct imsic_vector *mvec;
> > +     unsigned long flags;
> > +     int i;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->ids_lock, flags);
> > +     for (i = 1; i <= imsic->global.nr_ids; i++) {
> > +             if (i == IMSIC_IPI_ID)
> > +                     continue;
> > +
> > +             if (test_bit(i, lpriv->ids_enabled_bitmap))
> > +                     __imsic_id_set_enable(i);
> > +             else
> > +                     __imsic_id_clear_enable(i);
> > +
> > +             mvec = lpriv->ids_move[i];
> > +             lpriv->ids_move[i] = NULL;
> > +             if (mvec) {
> > +                     if (__imsic_id_read_clear_pending(i)) {
> > +                             mlocal = per_cpu_ptr(imsic->global.local,
> > +                                                  mvec->cpu);
> > +                             writel_relaxed(mvec->local_id, mlocal->msi_va);
> > +                     }
> > +
> > +                     imsic_vector_free(&lpriv->vectors[i]);
> > +             }
>
> Again an uncommented piece of magic which you will have forgotten what
> it does 3 month down the road :)

Sure, I will add a comment block.

>
> > +
> > +     }
> > +     raw_spin_unlock_irqrestore(&lpriv->ids_lock, flags);
> > +}
> > +
> > +void imsic_local_delivery(bool enable)
> > +{
> > +     if (enable) {
> > +             imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
> > +             imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
> > +             return;
> > +     }
> > +
> > +     imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
> > +     imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
> > +}
> > +
> > +#ifdef CONFIG_SMP
> > +static void imsic_remote_sync(unsigned int cpu)
> > +{
> > +     /*
> > +      * We simply inject ID synchronization IPI to a target CPU
> > +      * if it is not same as the current CPU. The ipi_send_mask()
> > +      * implementation of IPI mux will inject ID synchronization
> > +      * IPI only for CPUs that have enabled it so offline CPUs
> > +      * won't receive IPI. An offline CPU will unconditionally
> > +      * synchronize IDs through imsic_starting_cpu() when the
> > +      * CPU is brought up.
> > +      */
> > +     if (cpu_online(cpu)) {
> > +             if (cpu != smp_processor_id())
> > +                     __ipi_send_mask(imsic->ipi_lsync_desc, cpumask_of(cpu));
>
> Still wondering why this can't use the regular API. There might be a
> reason, but then it wants to be documented.

As mentioned above, the "ipi_virq" and "irq_lsync_desc" will
be replaced by a per-CPU timer in the next revision.

>
> > +             else
> > +                     imsic_local_sync();
> > +     }
> > +}
> > +#else
> > +static inline void imsic_remote_sync(unsigned int cpu)
> > +{
> > +     imsic_local_sync();
> > +}
> > +#endif
> > +
> > +void imsic_vector_mask(struct imsic_vector *vec)
> > +{
> > +     struct imsic_local_priv *lpriv;
> > +     unsigned long flags;
> > +
> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> > +     if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> > +             return;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->ids_lock, flags);
>
> AFAICT, this is used from an irqchip callback:
>
> static void imsic_irq_mask(struct irq_data *d)
> {
>         imsic_vector_mask(irq_data_get_irq_chip_data(d));
> }
>
> So no need to use irqsave() here. Those callbacks run always with
> interrupts disabled when called from the core.

Okay, I will update.

>
> > +void imsic_vector_move(struct imsic_vector *old_vec,
> > +                     struct imsic_vector *new_vec)
> > +{
> > +     struct imsic_local_priv *old_lpriv, *new_lpriv;
> > +     unsigned long flags, flags1;
> > +
> > +     if (WARN_ON(old_vec->cpu == new_vec->cpu))
> > +             return;
> > +
> > +     old_lpriv = per_cpu_ptr(imsic->lpriv, old_vec->cpu);
> > +     if (WARN_ON(&old_lpriv->vectors[old_vec->local_id] != old_vec))
> > +             return;
> > +
> > +     new_lpriv = per_cpu_ptr(imsic->lpriv, new_vec->cpu);
> > +     if (WARN_ON(&new_lpriv->vectors[new_vec->local_id] != new_vec))
> > +             return;
> > +
> > +     raw_spin_lock_irqsave(&old_lpriv->ids_lock, flags);
> > +     raw_spin_lock_irqsave(&new_lpriv->ids_lock, flags1);
>
> Lockdep should yell at you for this, rightfully so. And not only because
> of the missing nested() annotation.
>
> Assume there are two CPUs setting affinity for two different interrupts.
>
> CPU0 moves an interrupt to CPU1 and CPU1 moves another interrupt to
> CPU0. The resulting lock order is:
>
> CPU0                     CPU1
> lock(lpriv[CPU0]);       lock(lpriv[CPU1]);
> lock(lpriv[CPU1]);       lock(lpriv[CPU0]);
>
> a classic ABBA deadlock.
>
> You need to take those locks always in the same order. Look at
> double_raw_lock() in kernel/sched/sched.h.

I have simplified the locking to avoid this nested locks so this
will be much simpler without any lock nesting.

>
> > +     /* Unmask the new vector entry */
> > +     if (test_bit(old_vec->local_id, old_lpriv->ids_enabled_bitmap))
> > +             bitmap_set(new_lpriv->ids_enabled_bitmap,
> > +                        new_vec->local_id, 1);
>
> Either make that one line or please add brackets. See:
>
>   https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#bracket-rules

Okay, I will update.

>
> > +static int __init imsic_local_init(void)
> > +{
> > +     struct imsic_global_config *global = &imsic->global;
> > +     struct imsic_local_priv *lpriv;
> > +     struct imsic_vector *vec;
> > +     int cpu, i;
> > +
> > +     /* Allocate per-CPU private state */
> > +     imsic->lpriv = alloc_percpu(typeof(*(imsic->lpriv)));
> > +     if (!imsic->lpriv)
> > +             return -ENOMEM;
> > +
> > +     /* Setup per-CPU private state */
> > +     for_each_possible_cpu(cpu) {
> > +             lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> > +
> > +             raw_spin_lock_init(&lpriv->ids_lock);
> > +
> > +             /* Allocate enabled bitmap */
> > +             lpriv->ids_enabled_bitmap = bitmap_zalloc(global->nr_ids + 1,
> > +                                                       GFP_KERNEL);
> > +             if (!lpriv->ids_enabled_bitmap) {
> > +                     imsic_local_cleanup();
> > +                     return -ENOMEM;
> > +             }
> > +
> > +             /* Allocate move array */
> > +             lpriv->ids_move = kcalloc(global->nr_ids + 1,
> > +                                     sizeof(*lpriv->ids_move), GFP_KERNEL);
> > +             if (!lpriv->ids_move) {
> > +                     imsic_local_cleanup();
> > +                     return -ENOMEM;
> > +             }
> > +
> > +             /* Allocate vector array */
> > +             lpriv->vectors = kcalloc(global->nr_ids + 1,
> > +                                      sizeof(*lpriv->vectors), GFP_KERNEL);
> > +             if (!lpriv->vectors) {
> > +                     imsic_local_cleanup();
> > +                     return -ENOMEM;
>
> Third instance of the same pattern. goto cleanup; perhaps?

Okay, I will add goto here.

>
> > +struct imsic_vector *imsic_vector_alloc(unsigned int hwirq,
> > +                                     const struct cpumask *mask)
> > +{
> > +     struct imsic_vector *vec = NULL;
> > +     struct imsic_local_priv *lpriv;
> > +     unsigned long flags;
> > +     unsigned int cpu;
> > +     int local_id;
> > +
> > +     raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> > +     local_id = irq_matrix_alloc(imsic->matrix, mask, false, &cpu);
> > +     raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> > +     if (local_id < 0)
> > +             return NULL;
> > +
> > +     lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> > +     vec = &lpriv->vectors[local_id];
> > +     vec->hwirq = hwirq;
> > +
> > +     return vec;
> > +}
>
> ...
>
> > +int imsic_hwirq_alloc(void)
> > +{
> > +     int ret;
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&imsic->hwirqs_lock, flags);
> > +     ret = bitmap_find_free_region(imsic->hwirqs_used_bitmap,
> > +                                   imsic->nr_hwirqs, 0);
> > +     raw_spin_unlock_irqrestore(&imsic->hwirqs_lock, flags);
> > +
> > +     return ret;
> > +}
>
> This part is just to create a unique hwirq number, right?

Yes, this is only for unique hwirq. We can directly use virq
instead of hwirq so this hwirq allocation/management will
go away in the next revision.

>
> > +
> > +     /* Find number of guest index bits in MSI address */
> > +     rc = of_property_read_u32(to_of_node(fwnode),
> > +                               "riscv,guest-index-bits",
> > +                               &global->guest_index_bits);
> > +     if (rc)
> > +             global->guest_index_bits = 0;
>
> So here you get the index bits, but then 50 lines further down you do
> sanity checking. Wouldn't it make sense to do that right here?
>
> Same for the other bits.

This is intentional because we already have a AIA ACPI series
where this helps to reduce the number of "if (acpi_disabled)"
checks.

>
> > +
> > +/*
> > + * The IMSIC driver uses 1 IPI for ID synchronization and
> > + * arch/riscv/kernel/smp.c require 6 IPIs so we fix the
> > + * total number of IPIs to 8.
> > + */
> > +#define IMSIC_IPI_ID                         1
> > +#define IMSIC_NR_IPI                         8
> > +
> > +struct imsic_vector {
> > +     /* Fixed details of the vector */
> > +     unsigned int cpu;
> > +     unsigned int local_id;
> > +     /* Details saved by driver in the vector */
> > +     unsigned int hwirq;
> > +};
> > +
> > +struct imsic_local_priv {
> > +     /* Local state of interrupt identities */
> > +     raw_spinlock_t ids_lock;
> > +     unsigned long *ids_enabled_bitmap;
> > +     struct imsic_vector **ids_move;
> > +
> > +     /* Local vector table */
> > +     struct imsic_vector *vectors;
>
> Please make those structs tabular:
>
> https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#struct-declarations-and-initializers

Okay, I will update.

>
> > +void __imsic_eix_update(unsigned long base_id,
> > +                     unsigned long num_id, bool pend, bool val);
> > +
> > +#define __imsic_id_set_enable(__id)          \
> > +     __imsic_eix_update((__id), 1, false, true)
> > +#define __imsic_id_clear_enable(__id)        \
> > +     __imsic_eix_update((__id), 1, false, false)
>
> inlines please.

Okay, I will update.

Regards,
Anup


From josua at solid-run.com  Sun Feb 18 06:18:21 2024
From: josua at solid-run.com (Josua Mayer)
Date: Sun, 18 Feb 2024 15:18:21 +0100
Subject: [PATCH v5 0/5] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
In-Reply-To: <8aa96c66-d054-4b33-8972-f9faf2e84482@ti.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
 <8aa96c66-d054-4b33-8972-f9faf2e84482@ti.com>
Message-ID: <c37af45e-def1-4a97-ae01-e00e5b22eb23@solid-run.com>

Am 13.02.24 um 07:12 schrieb Vignesh Raghavendra:
> Hi
>
> [...]
>
> On 11/02/24 20:37, Josua Mayer wrote:
>> ---
>> Josua Mayer (4):
>>        dt-bindings: arm: ti: Add bindings for SolidRun AM642 HummingBoard-T
>
>>        dt-bindings: rtc: abx80x: convert to yaml
>>        dt-bindings: iio: humidity: hdc20x0: add optional interrupts property
>>        dt-bindings: mtd: spi-nor: add optional interrupts property
> 2/5 needs to go via RTC subsystem tree. Could you split it out into its
> own series when you respin
Only rtc, or should I split out the other two as well?
>
> Rest will go via TI K3 arch tree.
>
>
>>        arm64: dts: add description for solidrun am642 som and evaluation board
>>        arm64: dts: ti: hummingboard-t: add overlays for m.2 pci-e and usb-3
>>
>> Suman Anna (1):
>>        arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
>>
>>   Documentation/devicetree/bindings/arm/ti/k3.yaml   |   7 +
>>   .../devicetree/bindings/rtc/abracon,abx80x.txt     |  31 --
>>   .../devicetree/bindings/rtc/abracon,abx80x.yaml    |  79 +++
>>   arch/arm64/boot/dts/ti/Makefile                    |   7 +
>>   arch/arm64/boot/dts/ti/k3-am64-main.dtsi           |  24 +
>>   .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  |  45 ++
>>   .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  |  44 ++
>>   arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
>>   arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 594 +++++++++++++++++++++
>>   9 files changed, 1092 insertions(+), 31 deletions(-)
>> ---
>> base-commit: 798d1ee1675be84d5c7eb639480aab33f2c8791e
>> change-id: 20240101-add-am64-som-51a1ca47edf3
>>
>> Sincerely,


From claudiu.beznea at tuxon.dev  Sun Feb 18 06:45:24 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sun, 18 Feb 2024 16:45:24 +0200
Subject: [PATCH v3 3/8] ARM: dts: microchip: sama5d27_som1_ek: Add
 power-supply properties for sdmmc nodes
In-Reply-To: <20240206120322.88907-4-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
 <20240206120322.88907-4-mihai.sain@microchip.com>
Message-ID: <c47013b3-f542-4d17-88cb-34e1158cc743@tuxon.dev>

Hi, Mihai,

I'm replying to this series as the description is still better to me than
the one from v4, but, few notes:

On 06.02.2024 14:03, Mihai Sain wrote:
> The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.

In schematic at [1] (for SDMMC0 at least) I see VDDSDHC could be either 1v8
or 3v3 and is selected by SDMMC_VDDSEL signal. Maybe update the description
to reflect the this.

[1]
https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocuments/UserGuides/SAMA5D27-SOM1-Kit1-Users-Guide-DS50002667.pdf

> Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
> The sdmmc controller from SAMA5D2 MPU has support for
> IO voltage signaling/switching required by the UHS sd-card.

Ok, it has support as you mentioned in one of the replies to v1.

> In order to avoid the issues from the tuning procedure required by
> the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.

But it is still not clear enough for me why you want to keep it at 3v3.
Maybe it would have been clearer if you kept the statement from your reply
to v1:

"On the SAMA5 MPUs there is support for IO voltage switching but since we
have issues with the tuning procedure required but the UHS cards,
we want to keep vqmmc at 3V3 in order to use high-speed mode"

Thank you,
Claudiu Beznea


> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts b/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
> index f3ffb8f01d8a..255ee0640133 100644
> --- a/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
> +++ b/arch/arm/boot/dts/microchip/at91-sama5d27_som1_ek.dts
> @@ -56,6 +56,8 @@ sdmmc0: sdio-host at a0000000 {
>  			bus-width = <8>;
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&pinctrl_sdmmc0_default>;
> +			vmmc-supply = <&vddin_3v3>;
> +			vqmmc-supply = <&vddin_3v3>;
>  			status = "okay";
>  		};
>  
> @@ -63,6 +65,8 @@ sdmmc1: sdio-host at b0000000 {
>  			bus-width = <4>;
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&pinctrl_sdmmc1_default>;
> +			vmmc-supply = <&vddin_3v3>;
> +			vqmmc-supply = <&vddin_3v3>;
>  			status = "okay";
>  		};
>  


From claudiu.beznea at tuxon.dev  Sun Feb 18 06:45:40 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sun, 18 Feb 2024 16:45:40 +0200
Subject: [PATCH v3 5/8] ARM: dts: microchip: sama5d27_wlsom1_ek: Add
 power-supply property for sdmmc0 node
In-Reply-To: <20240206120322.88907-6-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
 <20240206120322.88907-6-mihai.sain@microchip.com>
Message-ID: <c7486f71-56ef-4ba8-9764-54245d906958@tuxon.dev>



On 06.02.2024 14:03, Mihai Sain wrote:
> The sdmmc0 controller is powered from 3.3V regulator.

Same here. SDMMC0 data lines are powered by VDDSDHC which could be 1v8/3v3.

[1]
https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocuments/UserGuides/SAMA5D2-Wireless-SOM1-Kit-User%27s-Guide-50002931d.pdf

> Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.
> The sdmmc controller from SAMA5D2 MPU has support for
> IO voltage signaling/switching required by the UHS sd-card.
> In order to avoid the issues from the tuning procedure required by
> the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
> index 15239834d886..7b36e1970bb7 100644
> --- a/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
> +++ b/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
> @@ -199,6 +199,8 @@ &sdmmc0 {
>  	bus-width = <4>;
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_sdmmc0_default>;
> +	vmmc-supply = <&vdd_3v3>;
> +	vqmmc-supply = <&vdd_3v3>;
>  	status = "okay";
>  };
>  


From claudiu.beznea at tuxon.dev  Sun Feb 18 06:45:58 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sun, 18 Feb 2024 16:45:58 +0200
Subject: [PATCH v3 6/8] ARM: dts: microchip: sama5d29_curiosity: Add
 power-supply properties for sdmmc nodes
In-Reply-To: <20240206120322.88907-7-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
 <20240206120322.88907-7-mihai.sain@microchip.com>
Message-ID: <38ae8cf6-1daf-4c36-8431-95e01fcc906f@tuxon.dev>



On 06.02.2024 14:03, Mihai Sain wrote:
> The sdmmc0 and sdmmc1 controllers are powered from 3.3V regulator.

Same here (for SDMMC0), according to
https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocuments/UserGuides/SAMA5D29-Curiosity-EV07R15A-Users-Guide-DS60001822.pdf

> Add vmmc-supply and vqmmc-supply properties to sdmmc nodes.
> The sdmmc controller from SAMA5D2 MPU has support for
> IO voltage signaling/switching required by the UHS sd-card.
> In order to avoid the issues from the tuning procedure required by
> the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
> index 6b02b7bcfd49..4a86597d089a 100644
> --- a/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
> +++ b/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
> @@ -504,6 +504,8 @@ &sdmmc0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_sdmmc0_default>;
>  	disable-wp;
> +	vmmc-supply = <&vdd_3v3>;
> +	vqmmc-supply = <&vdd_3v3>;
>  	status = "okay";
>  };
>  
> @@ -512,6 +514,8 @@ &sdmmc1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_sdmmc1_default>;
>  	disable-wp;
> +	vmmc-supply = <&vdd_3v3>;
> +	vqmmc-supply = <&vdd_3v3>;
>  	status = "okay";
>  };
>  


From claudiu.beznea at tuxon.dev  Sun Feb 18 06:46:08 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sun, 18 Feb 2024 16:46:08 +0200
Subject: [PATCH v3 8/8] ARM: dts: microchip: sama5d2_xplained: Add
 power-supply property for sdmmc0 node
In-Reply-To: <20240206120322.88907-9-mihai.sain@microchip.com>
References: <20240206120322.88907-1-mihai.sain@microchip.com>
 <20240206120322.88907-9-mihai.sain@microchip.com>
Message-ID: <c40ecf74-1367-401b-80f5-7277c7a7f1ee@tuxon.dev>



On 06.02.2024 14:03, Mihai Sain wrote:
> The sdmmc0 controller is powered from 3.3V regulator.

Same here according to
https://ww1.microchip.com/downloads/en/DeviceDoc/SAMA5D2C-XULT-User%27s-Guide-50002691E.pdf

> Add vmmc-supply and vqmmc-supply properties to sdmmc0 node.
> The sdmmc controller from SAMA5D2 MPU has support for
> IO voltage signaling/switching required by the UHS sd-card.
> In order to avoid the issues from the tuning procedure required by
> the UHS cards, keep the vqmmc at 3V3 to use the sd high-speed mode.
> 
> Signed-off-by: Mihai Sain <mihai.sain at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
> index 6680031387e8..9b7e56790a5a 100644
> --- a/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
> +++ b/arch/arm/boot/dts/microchip/at91-sama5d2_xplained.dts
> @@ -67,6 +67,8 @@ sdmmc0: sdio-host at a0000000 {
>  			pinctrl-0 = <&pinctrl_sdmmc0_default>;
>  			non-removable;
>  			mmc-ddr-3_3v;
> +			vmmc-supply = <&vdd_3v3_reg>;
> +			vqmmc-supply = <&vdd_3v3_reg>;
>  			status = "okay";
>  		};
>  


From claudiu.beznea at tuxon.dev  Sun Feb 18 07:13:51 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 18 Feb 2024 17:13:51 +0200
Subject: [PATCH 0/2] ARM: dts: microchip: few DT cleanups
Message-ID: <20240218151353.3612621-1-claudiu.beznea@tuxon.dev>

Hi,

Series adds minor cleanups for sam9x60 and sama7g5.

Thank you,
Claudiu Beznea

Claudiu Beznea (2):
  ARM: dts: microchip: sama7g5: align dmas to opening '<'
  ARM: dts: microchip: sam9x60: align dmas to opening '<'

 arch/arm/boot/dts/microchip/sam9x60.dtsi | 64 ++++++++++++------------
 arch/arm/boot/dts/microchip/sama7g5.dtsi | 16 +++---
 2 files changed, 40 insertions(+), 40 deletions(-)

-- 
2.39.2



From claudiu.beznea at tuxon.dev  Sun Feb 18 07:13:52 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 18 Feb 2024 17:13:52 +0200
Subject: [PATCH 1/2] ARM: dts: microchip: sama7g5: align dmas to the opening '<'
In-Reply-To: <20240218151353.3612621-1-claudiu.beznea@tuxon.dev>
References: <20240218151353.3612621-1-claudiu.beznea@tuxon.dev>
Message-ID: <20240218151353.3612621-2-claudiu.beznea@tuxon.dev>

Align dmas to the opening '<' to comply with the dts coding style,
indentation section, point 3: "For arrays spanning across lines, it is
preferred to align the continued entries with opening < from the first
line."

Signed-off-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
---
 arch/arm/boot/dts/microchip/sama7g5.dtsi | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
index 269e0a3ca269..15227a870d34 100644
--- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
+++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
@@ -714,7 +714,7 @@ uart0: serial at 200 {
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 38>;
 				clock-names = "usart";
 				dmas = <&dma1 AT91_XDMAC_DT_PERID(6)>,
-					<&dma1 AT91_XDMAC_DT_PERID(5)>;
+				       <&dma1 AT91_XDMAC_DT_PERID(5)>;
 				dma-names = "tx", "rx";
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
@@ -740,7 +740,7 @@ i2c1: i2c at 600 {
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 39>;
 				atmel,fifo-size = <32>;
 				dmas = <&dma0 AT91_XDMAC_DT_PERID(8)>,
-					<&dma0 AT91_XDMAC_DT_PERID(7)>;
+				       <&dma0 AT91_XDMAC_DT_PERID(7)>;
 				dma-names = "tx", "rx";
 				status = "disabled";
 			};
@@ -763,7 +763,7 @@ uart3: serial at 200 {
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 41>;
 				clock-names = "usart";
 				dmas = <&dma1 AT91_XDMAC_DT_PERID(12)>,
-					<&dma1 AT91_XDMAC_DT_PERID(11)>;
+				       <&dma1 AT91_XDMAC_DT_PERID(11)>;
 				dma-names = "tx", "rx";
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
@@ -807,7 +807,7 @@ uart4: serial at 200 {
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 42>;
 				clock-names = "usart";
 				dmas = <&dma1 AT91_XDMAC_DT_PERID(14)>,
-					<&dma1 AT91_XDMAC_DT_PERID(13)>;
+				       <&dma1 AT91_XDMAC_DT_PERID(13)>;
 				dma-names = "tx", "rx";
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
@@ -833,7 +833,7 @@ uart7: serial at 200 {
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 45>;
 				clock-names = "usart";
 				dmas = <&dma1 AT91_XDMAC_DT_PERID(20)>,
-					<&dma1 AT91_XDMAC_DT_PERID(19)>;
+				       <&dma1 AT91_XDMAC_DT_PERID(19)>;
 				dma-names = "tx", "rx";
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
@@ -928,7 +928,7 @@ i2c8: i2c at 600 {
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 46>;
 				atmel,fifo-size = <32>;
 				dmas = <&dma0 AT91_XDMAC_DT_PERID(22)>,
-					<&dma0 AT91_XDMAC_DT_PERID(21)>;
+				       <&dma0 AT91_XDMAC_DT_PERID(21)>;
 				dma-names = "tx", "rx";
 				status = "disabled";
 			};
@@ -952,7 +952,7 @@ i2c9: i2c at 600 {
 				clocks = <&pmc PMC_TYPE_PERIPHERAL 47>;
 				atmel,fifo-size = <32>;
 				dmas = <&dma0 AT91_XDMAC_DT_PERID(24)>,
-					<&dma0 AT91_XDMAC_DT_PERID(23)>;
+				       <&dma0 AT91_XDMAC_DT_PERID(23)>;
 				dma-names = "tx", "rx";
 				status = "disabled";
 			};
@@ -977,7 +977,7 @@ spi11: spi at 400 {
 				#size-cells = <0>;
 				atmel,fifo-size = <32>;
 				dmas = <&dma0 AT91_XDMAC_DT_PERID(28)>,
-					    <&dma0 AT91_XDMAC_DT_PERID(27)>;
+				       <&dma0 AT91_XDMAC_DT_PERID(27)>;
 				dma-names = "tx", "rx";
 				status = "disabled";
 			};
-- 
2.39.2



From claudiu.beznea at tuxon.dev  Sun Feb 18 07:13:53 2024
From: claudiu.beznea at tuxon.dev (Claudiu Beznea)
Date: Sun, 18 Feb 2024 17:13:53 +0200
Subject: [PATCH 2/2] ARM: dts: microchip: sam9x60: align dmas to the opening '<'
In-Reply-To: <20240218151353.3612621-1-claudiu.beznea@tuxon.dev>
References: <20240218151353.3612621-1-claudiu.beznea@tuxon.dev>
Message-ID: <20240218151353.3612621-3-claudiu.beznea@tuxon.dev>

Align dmas to the opening '<' to comply with the dts coding style,
indentation section, point 3: "For arrays spanning across lines, it is
preferred to align the continued entries with opening < from the first
line."

Signed-off-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
---
 arch/arm/boot/dts/microchip/sam9x60.dtsi | 64 ++++++++++++------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/arch/arm/boot/dts/microchip/sam9x60.dtsi b/arch/arm/boot/dts/microchip/sam9x60.dtsi
index 73d570a17269..291540e5d81e 100644
--- a/arch/arm/boot/dts/microchip/sam9x60.dtsi
+++ b/arch/arm/boot/dts/microchip/sam9x60.dtsi
@@ -179,7 +179,7 @@ uart4: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(8))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(9))>;
@@ -202,7 +202,7 @@ spi4: spi at 400 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(8))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(9))>;
@@ -220,7 +220,7 @@ i2c4: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(8))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(9))>;
@@ -248,7 +248,7 @@ uart5: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(10))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(11))>;
@@ -271,7 +271,7 @@ spi5: spi at 400 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(10))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(11))>;
@@ -289,7 +289,7 @@ i2c5: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(10))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(11))>;
@@ -377,7 +377,7 @@ uart11: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(22))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(23))>;
@@ -399,7 +399,7 @@ i2c11: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(22))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(23))>;
@@ -426,7 +426,7 @@ uart12: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(24))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(25))>;
@@ -448,7 +448,7 @@ i2c12: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(24))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(25))>;
@@ -583,7 +583,7 @@ uart6: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(12))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(13))>;
@@ -605,7 +605,7 @@ i2c6: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(12))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(13))>;
@@ -632,7 +632,7 @@ uart7: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(14))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(15))>;
@@ -654,7 +654,7 @@ i2c7: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(14))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(15))>;
@@ -681,7 +681,7 @@ uart8: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(16))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(17))>;
@@ -703,7 +703,7 @@ i2c8: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(16))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(17))>;
@@ -730,7 +730,7 @@ uart0: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(0))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(1))>;
@@ -753,7 +753,7 @@ spi0: spi at 400 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(0))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(1))>;
@@ -771,7 +771,7 @@ i2c0: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(0))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(1))>;
@@ -798,7 +798,7 @@ uart1: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(2))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(3))>;
@@ -821,7 +821,7 @@ spi1: spi at 400 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(2))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(3))>;
@@ -839,7 +839,7 @@ i2c1: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(2))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(3))>;
@@ -866,7 +866,7 @@ uart2: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(4))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(5))>;
@@ -889,7 +889,7 @@ spi2: spi at 400 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(4))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(5))>;
@@ -907,7 +907,7 @@ i2c2: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(4))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(5))>;
@@ -934,7 +934,7 @@ uart3: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(6))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(7))>;
@@ -957,7 +957,7 @@ spi3: spi at 400 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(6))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(7))>;
@@ -975,7 +975,7 @@ i2c3: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(6))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(7))>;
@@ -1057,7 +1057,7 @@ uart9: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(18))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(19))>;
@@ -1079,7 +1079,7 @@ i2c9: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(18))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(19))>;
@@ -1106,7 +1106,7 @@ uart10: serial at 200 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(20))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(21))>;
@@ -1128,7 +1128,7 @@ i2c10: i2c at 600 {
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(20))>,
-						<&dma0
+					       <&dma0
 						(AT91_XDMAC_DT_MEM_IF(0) |
 						 AT91_XDMAC_DT_PER_IF(1) |
 						 AT91_XDMAC_DT_PERID(21))>;
-- 
2.39.2



From megi at xff.cz  Sun Feb 18 07:17:22 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Sun, 18 Feb 2024 16:17:22 +0100
Subject: [PATCH] drm: rockchip: Don't require MIPI DSI device when it's
 used for ISP
In-Reply-To: <4c66c084-5af6-43fb-a256-4746b2e00192@rock-chips.com>
References: <20240217183941.1752463-1-megi@xff.cz>
 <4c66c084-5af6-43fb-a256-4746b2e00192@rock-chips.com>
Message-ID: <bsc3lpdxvhy3ss2uja4do3jwvj43zbs7zhx4bzs2tryrakn7be@pt2qsyvryk73>

Hi Andy,

On Sun, Feb 18, 2024 at 07:14:56PM +0800, Andy Yan wrote:
> Hi,
> 
> On 2/18/24 02:39, Ond?ej Jirman wrote:
> > From: Ondrej Jirman <megi at xff.cz>
> > 
> > On RK3399 one MIPI DSI device can be alternatively used with the ISP1,
> > to provide RX DPHY. When this is the case (ISP1 is enabled in device
> > tree), probe success of DRM is tied to probe success of ISP1 connected
> > camera sensor. This can fail if the user is able to killswitch the camera
> > power, like on Pinephone Pro.
> > 
> > Detect use of MIPI DSI controller by ISP, and don't include it in
> > component match list in that case.
> > 
> 
> Isn't this supposed to be taken care of within the dts?
> Since DPHY1 should exclusively used by MIPI DSI1 and ISP1, then if
> a device want to use ISP1, the DSI1 should be disabled in dts.

DSI1 can't be disabled, because it provides PHY device for ISP1 in this
scenario.

The problem is that in this scenario DRM keeps waiting for DSI1 device,
despite it just being used for PHY for ISP1 and not as a component for
rockchip DRM driver.

See:

        isp1: isp1 at ff920000 {
                compatible = "rockchip,rk3399-cif-isp";
                reg = <0x0 0xff920000 0x0 0x4000>;
                interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH 0>;
                clocks = <&cru SCLK_ISP1>,
                         <&cru ACLK_ISP1_WRAPPER>,
                         <&cru HCLK_ISP1_WRAPPER>;
                clock-names = "isp", "aclk", "hclk";
                iommus = <&isp1_mmu>;
                phys = <&mipi_dsi1>;  <--------- 
                phy-names = "dphy";
                power-domains = <&power RK3399_PD_ISP1>;
                status = "disabled";

If mipi_dsi1 is disabled, isp1 will never probe.

It's a consequence of this special dual use of mipi_dsi1.

kind regards,
	o.

> > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > ---
> >   drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 47 +++++++++++++++++++++
> >   1 file changed, 47 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > index ab55d7132550..f47de94ad576 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > @@ -354,6 +354,43 @@ static void rockchip_drm_match_remove(struct device *dev)
> >   		device_link_del(link);
> >   }
> > +/*
> > + * Check if ISP block linked to a mipi-dsi device via phys phandle is
> > + * enabled in device tree.
> > + */
> > +static bool rockchip_drm_is_mipi1_and_used_by_isp(struct device *dev)
> > +{
> > +	struct device_node *np = NULL, *phy_np;
> > +
> > +	if (!of_device_is_compatible(dev->of_node, "rockchip,rk3399-mipi-dsi"))
> > +		return false;
> > +
> > +	while (true) {
> > +		np = of_find_compatible_node(np, NULL, "rockchip,rk3399-cif-isp");
> > +		if (!np)
> > +			break;
> > +
> > +		if (!of_device_is_available(np)) {
> > +			of_node_put(np);
> > +			continue;
> > +		}
> > +
> > +		phy_np = of_parse_phandle(np, "phys", 0);
> > +		if (!phy_np) {
> > +			of_node_put(np);
> > +			continue;
> > +		}
> > +
> > +		of_node_put(phy_np);
> > +		of_node_put(np);
> > +
> > +		if (phy_np == dev->of_node)
> > +			return true;
> > +	}
> > +
> > +	return false;
> > +}
> > +
> >   static struct component_match *rockchip_drm_match_add(struct device *dev)
> >   {
> >   	struct component_match *match = NULL;
> > @@ -371,6 +408,16 @@ static struct component_match *rockchip_drm_match_add(struct device *dev)
> >   			if (!d)
> >   				break;
> > +			/*
> > +			 * If mipi1 is connected to ISP, we don't want to wait for mipi1 component,
> > +			 * because it will not be used by DRM anyway, to not tie success of camera
> > +			 * driver probe to display pipeline initialization.
> > +			 */
> > +			if (rockchip_drm_is_mipi1_and_used_by_isp(d)) {
> > +				dev_info(d, "used by ISP1, skipping from DRM\n");
> > +				continue;
> > +			}
> > +
> >   			device_link_add(dev, d, DL_FLAG_STATELESS);
> >   			component_match_add(dev, &match, component_compare_dev, d);
> >   		} while (true);


From samuel.holland at sifive.com  Sun Feb 18 07:29:11 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Sun, 18 Feb 2024 09:29:11 -0600
Subject: [PATCH v1 1/6] dt-bindings: cache: Document the
 sifive,perfmon-counters property
In-Reply-To: <eeb2331d-10e6-4902-91ba-85896a8f0ee1@linaro.org>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
 <20240216000837.1868917-2-samuel.holland@sifive.com>
 <eeb2331d-10e6-4902-91ba-85896a8f0ee1@linaro.org>
Message-ID: <72221da1-4a1a-4947-a202-9de203032f5c@sifive.com>

Hi Krzysztof,

On 2024-02-17 3:00 AM, Krzysztof Kozlowski wrote:
> On 16/02/2024 01:08, Samuel Holland wrote:
>> The SiFive Composable Cache controller contains an optional PMU with a
>> configurable number of event counters. Document a property which
> 
> Configurable in what context? By chip designers or by OS? Why this
> cannot be deduced from the compatible?

This parameter is configurable by the chip designers.

The information certainly can be deduced from the SoC-specific compatible
string, but doing so makes the driver only work on that specific list of SoCs.
When provided via a property, the driver can work without changes on any SoC
that uses this IP block. (None of the SoCs currently listed in the binding
contain a PMU, so there is no backward compatibility concern with adding the new
property.)

My understanding of the purpose of the SoC-specific compatible string is to
handle eventualities (silicon bugs, integration quirks, etc.), not to
intentionally limit the driver to a narrow list of hardware.

Regards,
Samuel

>> describes the number of available counters.
>>
>> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
>> ---
>>
>>  Documentation/devicetree/bindings/cache/sifive,ccache0.yaml | 5 +++++
>>  1 file changed, 5 insertions(+)
>>  



From samuel.holland at sifive.com  Sun Feb 18 07:33:20 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Sun, 18 Feb 2024 09:33:20 -0600
Subject: [PATCH v1 5/6] dt-bindings: cache: Add SiFive Private L2 Cache
 controller
In-Reply-To: <7d7fc53f-1b5d-4f1f-a53f-f0863a79a79c@linaro.org>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
 <20240216000837.1868917-6-samuel.holland@sifive.com>
 <7d7fc53f-1b5d-4f1f-a53f-f0863a79a79c@linaro.org>
Message-ID: <a3139d86-f2d3-45c4-9eda-23afbeb3f3c2@sifive.com>

Hi Krzysztof,

On 2024-02-17 3:12 AM, Krzysztof Kozlowski wrote:
> On 16/02/2024 01:08, Samuel Holland wrote:
>> From: Eric Lin <eric.lin at sifive.com>
>>
>> Add YAML DT binding documentation for the SiFive Private L2 Cache
>> controller. Some functionality and the corresponding register bits were
>> removed in the sifive,pl2cache1 version of the hardware, which creates
>> the unusual situation where the newer hardware's compatible string is
>> the fallback for the older one.
>>
>> Signed-off-by: Eric Lin <eric.lin at sifive.com>
>> Co-developed-by: Samuel Holland <samuel.holland at sifive.com>
>> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
>> ---
>>
>> Changes in v1:
>>  - Add back select: clause to binding
>>  - Make sifive,pl2cache1 the fallback for sifive,pl2cache0
>>  - Fix the order of the reg property declaration
>>  - Document the sifive,perfmon-counters property
> 
> This is no v1. Please implement entire feedback from previous v2, v3 or
> whatever it was and reference old posting or continue the numbering.

The old posting is referenced in the cover letter:

This series is a follow-up to Eric Lin's series "[PATCH v2 0/3] Add
SiFive Private L2 cache and PMU driver":
https://lore.kernel.org/linux-riscv/20230720135125.21240-1-eric.lin at sifive.com/

So these changes include implementation of the feedback from that v2.

Regards,
Samuel



From samuel.holland at sifive.com  Sun Feb 18 07:50:59 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Sun, 18 Feb 2024 09:50:59 -0600
Subject: [PATCH v1 3/6] dt-bindings: cache: Add SiFive Extensible Cache
 controller
In-Reply-To: <d655b72e-3094-4b6b-bee8-9677b7c987ce@linaro.org>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
 <20240216000837.1868917-4-samuel.holland@sifive.com>
 <d655b72e-3094-4b6b-bee8-9677b7c987ce@linaro.org>
Message-ID: <3c2f1c61-89b4-4103-ac45-a2a541de215e@sifive.com>

Hi Krzysztof,

On 2024-02-17 3:09 AM, Krzysztof Kozlowski wrote:
> On 16/02/2024 01:08, Samuel Holland wrote:
>> From: Eric Lin <eric.lin at sifive.com>
>>
>> Add YAML DT binding documentation for the SiFive Extensible Cache
>> controller. The Extensible Cache controller interleaves cache blocks
>> across a number of heterogeneous independently-programmed slices. Each
>> slice contains an MMIO interface for configuration, cache maintenance,
>> error reporting, and performance monitoring.
>>
>> +allOf:
>> +  - $ref: /schemas/cache-controller.yaml#
>> +
>> +select:
>> +  properties:
>> +    compatible:
>> +      contains:
>> +        enum:
>> +          - sifive,extensiblecache0
>> +
>> +  required:
>> +    - compatible
>> +
>> +properties:
>> +  compatible:
>> +    items:
>> +      - const: sifive,extensiblecache0
>> +      - const: cache
>> +
>> +  "#address-cells": true
> 
> const or enum: [1, 2], depending on the addressing you need here.
> 
>> +  "#size-cells": true
> 
> ditto
> 
>> +  ranges: true
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  cache-block-size:
>> +    const: 64
>> +
>> +  cache-level: true
> 
> 5 is acceptable? I would argue this should be even const.
> 
>> +  cache-sets: true
>> +  cache-size: true
> 
> Some constraints on any of these?

Thanks for the feedback. I will add the various constraints in v2, though some
constraints will be somewhat loose as the topology is highly configurable.

>> +  cache-unified: true
>> +
>> +patternProperties:
>> +  "^cache-controller@[0-9a-f]+$":
>> +    type: object
>> +    additionalProperties: false
> 
> What is this object supposed to represent? Add description.

I will add a description in v2.

This object represents a single slice of the cache. Requests from clients are
interleaved between cache slices depending on the client, the address, etc.

Since there is no strong relationship between client (i.e. CPU) and cache slice,
the next-level-cache property must point to the top-level EC node, not a slice.

>> +    properties:
>> +      reg:
>> +        maxItems: 1
>> +
>> +      cache-block-size:
>> +        const: 64
>> +
>> +      cache-sets: true
>> +      cache-size: true
>> +      cache-unified: true
> 
> cache-level

I will add this in v2. It seemed redundant since the value cannot differ between
slices.

Regards,
Samuel

>> +
>> +      sifive,bm-event-counters:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        default: 0
>> +        description: Number of bucket monitor registers in this slice
>> +
>> +      sifive,cache-ways:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        description: Number of ways in this slice (independent of cache size)
>> +
>> +      sifive,perfmon-counters:
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        default: 0
>> +        description: Number of PMU counter registers in this slice
>> +
>> +    required:
>> +      - reg
>> +      - cache-block-size
>> +      - cache-sets
>> +      - cache-size
>> +      - cache-unified
>> +      - sifive,cache-ways
>> +
>> +required:
>> +  - compatible
>> +  - ranges
>> +  - interrupts
>> +  - cache-block-size
>> +  - cache-level
>> +  - cache-sets
>> +  - cache-size
>> +  - cache-unified
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    cache-controller at 30040000 {
>> +        compatible = "sifive,extensiblecache0", "cache";
>> +        ranges = <0x30040000 0x30040000 0x10000>;
>> +        interrupts = <0x4>;
> 
> You use hex as interrupt numbers on your platforms?
> 
>> +        cache-block-size = <0x40>;
>> +        cache-level = <3>;
>> +        cache-sets = <0x800>;
> 
> Best regards,
> Krzysztof
> 



From martin.blumenstingl at googlemail.com  Sun Feb 18 09:41:36 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 18 Feb 2024 18:41:36 +0100
Subject: [PATCH v1 0/2] clocksource/drivers/arm_global_timer: Two small fixes
Message-ID: <20240218174138.1942418-1-martin.blumenstingl@googlemail.com>

This series consists of two small fixes:
1) incorrect max width (and therefore mask calculation) of the prescaler
   field in the Global Timer Control Register. The field is actually 8
   bit wide according to the Cortex-A9 MPCore Technical Reference Manual
   r3p0 [0]
2) non-function: a stray tab which is inconsistent with to the coding
   style in the driver

I don't have any ARM/STI hardware to verify the first fix. However, I
tested this on an Amlogic Meson8b board with Cortex-A5 which uses the
same Global Timer implementation as Cortex-A9 SoCs and the documentation
confirms the same register layout: [1]


[0] https://developer.arm.com/documentation/ddi0407/g/Global-timer--private-timers--and-watchdog-registers/Global-timer-registers/Global-Timer-Control-Register
[1] https://developer.arm.com/documentation/ddi0434/b/CIHJGFEA


Martin Blumenstingl (2):
  clocksource/drivers/arm_global_timer: Fix maximum prescaler value
  clocksource/drivers/arm_global_timer: Remove stray tab

 drivers/clocksource/arm_global_timer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

-- 
2.43.2



From martin.blumenstingl at googlemail.com  Sun Feb 18 09:41:37 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 18 Feb 2024 18:41:37 +0100
Subject: [PATCH v1 1/2] clocksource/drivers/arm_global_timer: Fix maximum prescaler value
In-Reply-To: <20240218174138.1942418-1-martin.blumenstingl@googlemail.com>
References: <20240218174138.1942418-1-martin.blumenstingl@googlemail.com>
Message-ID: <20240218174138.1942418-2-martin.blumenstingl@googlemail.com>

The prescaler in the "Global Timer Control Register bit assignments" is
documented to use bits [15:8], which means that the maximum prescaler
register value is 0xff.

Fixes: 171b45a4a70e ("clocksource/drivers/arm_global_timer: Implement rate compensation whenever source clock changes")
Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 drivers/clocksource/arm_global_timer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index 44a61dc6f932..e1c773bb5535 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -32,7 +32,7 @@
 #define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
 #define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
 #define GT_CONTROL_PRESCALER_SHIFT      8
-#define GT_CONTROL_PRESCALER_MAX        0xF
+#define GT_CONTROL_PRESCALER_MAX        0xFF
 #define GT_CONTROL_PRESCALER_MASK       (GT_CONTROL_PRESCALER_MAX << \
 					 GT_CONTROL_PRESCALER_SHIFT)
 
-- 
2.43.2



From martin.blumenstingl at googlemail.com  Sun Feb 18 09:41:38 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 18 Feb 2024 18:41:38 +0100
Subject: [PATCH v1 2/2] clocksource/drivers/arm_global_timer: Remove stray tab
In-Reply-To: <20240218174138.1942418-1-martin.blumenstingl@googlemail.com>
References: <20240218174138.1942418-1-martin.blumenstingl@googlemail.com>
Message-ID: <20240218174138.1942418-3-martin.blumenstingl@googlemail.com>

Remove a stray tab in global_timer_of_register() which is different from
the coding style in the rest of the driver.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 drivers/clocksource/arm_global_timer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index e1c773bb5535..8dd1e46b7176 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -411,7 +411,7 @@ static int __init global_timer_of_register(struct device_node *np)
 	err = gt_clocksource_init();
 	if (err)
 		goto out_irq;
-	
+
 	err = cpuhp_setup_state(CPUHP_AP_ARM_GLOBAL_TIMER_STARTING,
 				"clockevents/arm/global_timer:starting",
 				gt_starting_cpu, gt_dying_cpu);
-- 
2.43.2



From laurent.pinchart at ideasonboard.com  Sun Feb 18 09:45:41 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sun, 18 Feb 2024 19:45:41 +0200
Subject: [PATCH v12 04/12] media: rkisp1: Support devices lacking dual
 crop
In-Reply-To: <20240216095458.2919694-5-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
 <20240216095458.2919694-5-paul.elder@ideasonboard.com>
Message-ID: <20240218174541.GH7120@pendragon.ideasonboard.com>

Hi Paul,

Thank you for the patch.

On Fri, Feb 16, 2024 at 06:54:50PM +0900, Paul Elder wrote:
> Some versions of the ISP supported by the rkisp1 driver, such as the ISP
> in the i.MX8MP, lack the dual crop registers and don't support cropping
> at the resizer input. They instead rely on cropping in the Image
> Stabilization module, at the output of the ISP, to modify the resizer
> input size and implement digital zoom.
> 
> Add a dual crop feature flag to distinguish the versions of the ISP that
> support dual crop from those that don't, and make sure that the sink
> crop is set to the sink format when dual crop is not supported.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Tested-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
> Changes in v12:
> - Remove mention of moving resizer input crop to image stabilizer from
>   commit message
> - Make sure the sink crop is set to the sink format when dual crop is
>   not supported
> ---
>  .../media/platform/rockchip/rkisp1/rkisp1-common.h    |  2 ++
>  drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c   |  6 ++++--
>  .../media/platform/rockchip/rkisp1/rkisp1-resizer.c   | 11 +++++++----
>  3 files changed, 13 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> index f7c251f79aa9..219d4a2547aa 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> @@ -112,6 +112,7 @@ enum rkisp1_isp_pad {
>   * @RKISP1_FEATURE_MIPI_CSI2: The ISP has an internal MIPI CSI-2 receiver
>   * @RKISP1_FEATURE_MAIN_STRIDE: The ISP supports configurable stride on the main path
>   * @RKISP1_FEATURE_SELF_PATH: The ISP has a self path
> + * @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the resizer input
>   *
>   * The ISP features are stored in a bitmask in &rkisp1_info.features and allow
>   * the driver to implement support for features present in some ISP versions
> @@ -121,6 +122,7 @@ enum rkisp1_feature {
>  	RKISP1_FEATURE_MIPI_CSI2 = BIT(0),
>  	RKISP1_FEATURE_MAIN_STRIDE = BIT(1),
>  	RKISP1_FEATURE_SELF_PATH = BIT(2),
> +	RKISP1_FEATURE_DUAL_CROP = BIT(3),
>  };
>  
>  #define rkisp1_has_feature(rkisp1, feature) \
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> index f48a21985b18..2e40c376cab5 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> @@ -507,7 +507,8 @@ static const struct rkisp1_info px30_isp_info = {
>  	.isr_size = ARRAY_SIZE(px30_isp_isrs),
>  	.isp_ver = RKISP1_V12,
>  	.features = RKISP1_FEATURE_MIPI_CSI2
> -		  | RKISP1_FEATURE_SELF_PATH,
> +		  | RKISP1_FEATURE_SELF_PATH
> +		  | RKISP1_FEATURE_DUAL_CROP,
>  };
>  
>  static const char * const rk3399_isp_clks[] = {
> @@ -527,7 +528,8 @@ static const struct rkisp1_info rk3399_isp_info = {
>  	.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
>  	.isp_ver = RKISP1_V10,
>  	.features = RKISP1_FEATURE_MIPI_CSI2
> -		  | RKISP1_FEATURE_SELF_PATH,
> +		  | RKISP1_FEATURE_SELF_PATH
> +		  | RKISP1_FEATURE_DUAL_CROP,
>  };
>  
>  static const struct of_device_id rkisp1_of_match[] = {
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
> index dd77a31e6014..755d319b568e 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
> @@ -447,8 +447,9 @@ static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
>  	/* Not crop for MP bayer raw data */

	/* Not crop for MP bayer raw data, or for devices lacking dual crop. */

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

I can handle this when applying.

>  	mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
>  
> -	if (rsz->id == RKISP1_MAINPATH &&
> -	    mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
> +	if ((rsz->id == RKISP1_MAINPATH &&
> +	     mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) ||
> +	    !rkisp1_has_feature(rsz->rkisp1, DUAL_CROP)) {
>  		sink_crop->left = 0;
>  		sink_crop->top = 0;
>  		sink_crop->width = sink_fmt->width;
> @@ -635,7 +636,8 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
>  	struct v4l2_subdev_state *sd_state;
>  
>  	if (!enable) {
> -		rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
> +		if (rkisp1_has_feature(rkisp1, DUAL_CROP))
> +			rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
>  		rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
>  		return 0;
>  	}
> @@ -646,7 +648,8 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
>  	sd_state = v4l2_subdev_lock_and_get_active_state(sd);
>  
>  	rkisp1_rsz_config(rsz, sd_state, when);
> -	rkisp1_dcrop_config(rsz, sd_state);
> +	if (rkisp1_has_feature(rkisp1, DUAL_CROP))
> +		rkisp1_dcrop_config(rsz, sd_state);
>  
>  	v4l2_subdev_unlock_state(sd_state);
>  

-- 
Regards,

Laurent Pinchart


From martin.blumenstingl at googlemail.com  Sun Feb 18 09:50:35 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 18 Feb 2024 18:50:35 +0100
Subject: [PATCH v1] drm/meson: improve encoder probe / initialization error handling
Message-ID: <20240218175035.1948165-1-martin.blumenstingl@googlemail.com>

Rename meson_encoder_{cvbs,dsi,hdmi}_init() to
meson_encoder_{cvbs,dsi,hdmi}_probe() so it's clear that these functions
are used at probe time during driver initialization. Also switch all
error prints inside those functions to use dev_err_probe() for
consistency.

This makes the code more straight forward to read and makes the error
prints within those functions consistent (by logging all -EPROBE_DEFER
with dev_dbg(), while actual errors are logged with dev_err() and get
the error value printed).

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
This is meant to be applied on top of my other patch called
"drm/meson: Don't remove bridges which are created by other drivers" [0]


[0] https://lore.kernel.org/dri-devel/20240215220442.1343152-1-martin.blumenstingl at googlemail.com/


 drivers/gpu/drm/meson/meson_drv.c          |  6 +++---
 drivers/gpu/drm/meson/meson_encoder_cvbs.c | 24 ++++++++++------------
 drivers/gpu/drm/meson/meson_encoder_cvbs.h |  2 +-
 drivers/gpu/drm/meson/meson_encoder_dsi.c  | 23 +++++++++------------
 drivers/gpu/drm/meson/meson_encoder_dsi.h  |  2 +-
 drivers/gpu/drm/meson/meson_encoder_hdmi.c | 15 +++++++-------
 drivers/gpu/drm/meson/meson_encoder_hdmi.h |  2 +-
 7 files changed, 35 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index cb674966e9ac..17a5cca007e2 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -312,7 +312,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 
 	/* Encoder Initialization */
 
-	ret = meson_encoder_cvbs_init(priv);
+	ret = meson_encoder_cvbs_probe(priv);
 	if (ret)
 		goto exit_afbcd;
 
@@ -326,12 +326,12 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 		}
 	}
 
-	ret = meson_encoder_hdmi_init(priv);
+	ret = meson_encoder_hdmi_probe(priv);
 	if (ret)
 		goto exit_afbcd;
 
 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
-		ret = meson_encoder_dsi_init(priv);
+		ret = meson_encoder_dsi_probe(priv);
 		if (ret)
 			goto exit_afbcd;
 	}
diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
index 3407450435e2..d1191de855d9 100644
--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
@@ -219,7 +219,7 @@ static const struct drm_bridge_funcs meson_encoder_cvbs_bridge_funcs = {
 	.atomic_reset = drm_atomic_helper_bridge_reset,
 };
 
-int meson_encoder_cvbs_init(struct meson_drm *priv)
+int meson_encoder_cvbs_probe(struct meson_drm *priv)
 {
 	struct drm_device *drm = priv->drm;
 	struct meson_encoder_cvbs *meson_encoder_cvbs;
@@ -240,10 +240,9 @@ int meson_encoder_cvbs_init(struct meson_drm *priv)
 
 	meson_encoder_cvbs->next_bridge = of_drm_find_bridge(remote);
 	of_node_put(remote);
-	if (!meson_encoder_cvbs->next_bridge) {
-		dev_err(priv->dev, "Failed to find CVBS Connector bridge\n");
-		return -EPROBE_DEFER;
-	}
+	if (!meson_encoder_cvbs->next_bridge)
+		return dev_err_probe(priv->dev, -EPROBE_DEFER,
+				     "Failed to find CVBS Connector bridge\n");
 
 	/* CVBS Encoder Bridge */
 	meson_encoder_cvbs->bridge.funcs = &meson_encoder_cvbs_bridge_funcs;
@@ -259,10 +258,9 @@ int meson_encoder_cvbs_init(struct meson_drm *priv)
 	/* Encoder */
 	ret = drm_simple_encoder_init(priv->drm, &meson_encoder_cvbs->encoder,
 				      DRM_MODE_ENCODER_TVDAC);
-	if (ret) {
-		dev_err(priv->dev, "Failed to init CVBS encoder: %d\n", ret);
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(priv->dev, ret,
+				     "Failed to init CVBS encoder\n");
 
 	meson_encoder_cvbs->encoder.possible_crtcs = BIT(0);
 
@@ -276,10 +274,10 @@ int meson_encoder_cvbs_init(struct meson_drm *priv)
 
 	/* Initialize & attach Bridge Connector */
 	connector = drm_bridge_connector_init(priv->drm, &meson_encoder_cvbs->encoder);
-	if (IS_ERR(connector)) {
-		dev_err(priv->dev, "Unable to create CVBS bridge connector\n");
-		return PTR_ERR(connector);
-	}
+	if (IS_ERR(connector))
+		return dev_err_probe(priv->dev, PTR_ERR(connector),
+				     "Unable to create CVBS bridge connector\n");
+
 	drm_connector_attach_encoder(connector, &meson_encoder_cvbs->encoder);
 
 	priv->encoders[MESON_ENC_CVBS] = meson_encoder_cvbs;
diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.h b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
index 09710fec3c66..7b7bc85c03f7 100644
--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.h
+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
@@ -24,7 +24,7 @@ struct meson_cvbs_mode {
 /* Modes supported by the CVBS output */
 extern struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT];
 
-int meson_encoder_cvbs_init(struct meson_drm *priv);
+int meson_encoder_cvbs_probe(struct meson_drm *priv);
 void meson_encoder_cvbs_remove(struct meson_drm *priv);
 
 #endif /* __MESON_VENC_CVBS_H */
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
index 311b91630fbe..7816902f5907 100644
--- a/drivers/gpu/drm/meson/meson_encoder_dsi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
@@ -100,7 +100,7 @@ static const struct drm_bridge_funcs meson_encoder_dsi_bridge_funcs = {
 	.atomic_reset = drm_atomic_helper_bridge_reset,
 };
 
-int meson_encoder_dsi_init(struct meson_drm *priv)
+int meson_encoder_dsi_probe(struct meson_drm *priv)
 {
 	struct meson_encoder_dsi *meson_encoder_dsi;
 	struct device_node *remote;
@@ -118,10 +118,9 @@ int meson_encoder_dsi_init(struct meson_drm *priv)
 	}
 
 	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\n");
-		return -EPROBE_DEFER;
-	}
+	if (!meson_encoder_dsi->next_bridge)
+		return dev_err_probe(priv->dev, -EPROBE_DEFER,
+				     "Failed to find DSI transceiver bridge\n");
 
 	/* DSI Encoder Bridge */
 	meson_encoder_dsi->bridge.funcs = &meson_encoder_dsi_bridge_funcs;
@@ -135,19 +134,17 @@ int meson_encoder_dsi_init(struct meson_drm *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;
-	}
+	if (ret)
+		return dev_err_probe(priv->dev, ret,
+				     "Failed to init DSI encoder\n");
 
 	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;
-	}
+	if (ret)
+		return dev_err_probe(priv->dev, ret,
+				     "Failed to attach bridge\n");
 
 	/*
 	 * We should have now in place:
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.h b/drivers/gpu/drm/meson/meson_encoder_dsi.h
index 9277d7015193..85d5b61805f2 100644
--- a/drivers/gpu/drm/meson/meson_encoder_dsi.h
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.h
@@ -7,7 +7,7 @@
 #ifndef __MESON_ENCODER_DSI_H
 #define __MESON_ENCODER_DSI_H
 
-int meson_encoder_dsi_init(struct meson_drm *priv);
+int meson_encoder_dsi_probe(struct meson_drm *priv);
 void meson_encoder_dsi_remove(struct meson_drm *priv);
 
 #endif /* __MESON_ENCODER_DSI_H */
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
index c4686568c9ca..22e07847a9a7 100644
--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -354,7 +354,7 @@ static const struct drm_bridge_funcs meson_encoder_hdmi_bridge_funcs = {
 	.atomic_reset = drm_atomic_helper_bridge_reset,
 };
 
-int meson_encoder_hdmi_init(struct meson_drm *priv)
+int meson_encoder_hdmi_probe(struct meson_drm *priv)
 {
 	struct meson_encoder_hdmi *meson_encoder_hdmi;
 	struct platform_device *pdev;
@@ -374,8 +374,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
 
 	meson_encoder_hdmi->next_bridge = of_drm_find_bridge(remote);
 	if (!meson_encoder_hdmi->next_bridge) {
-		dev_err(priv->dev, "Failed to find HDMI transceiver bridge\n");
-		ret = -EPROBE_DEFER;
+		ret = dev_err_probe(priv->dev, -EPROBE_DEFER,
+				    "Failed to find HDMI transceiver bridge\n");
 		goto err_put_node;
 	}
 
@@ -393,7 +393,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
 	ret = drm_simple_encoder_init(priv->drm, &meson_encoder_hdmi->encoder,
 				      DRM_MODE_ENCODER_TMDS);
 	if (ret) {
-		dev_err(priv->dev, "Failed to init HDMI encoder: %d\n", ret);
+		dev_err_probe(priv->dev, ret, "Failed to init HDMI encoder\n");
 		goto err_put_node;
 	}
 
@@ -403,7 +403,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
 	ret = drm_bridge_attach(&meson_encoder_hdmi->encoder, &meson_encoder_hdmi->bridge, NULL,
 				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (ret) {
-		dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
+		dev_err_probe(priv->dev, ret, "Failed to attach bridge\n");
 		goto err_put_node;
 	}
 
@@ -411,8 +411,9 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
 	meson_encoder_hdmi->connector = drm_bridge_connector_init(priv->drm,
 							&meson_encoder_hdmi->encoder);
 	if (IS_ERR(meson_encoder_hdmi->connector)) {
-		dev_err(priv->dev, "Unable to create HDMI bridge connector\n");
-		ret = PTR_ERR(meson_encoder_hdmi->connector);
+		ret = dev_err_probe(priv->dev,
+				    PTR_ERR(meson_encoder_hdmi->connector),
+				    "Unable to create HDMI bridge connector\n");
 		goto err_put_node;
 	}
 	drm_connector_attach_encoder(meson_encoder_hdmi->connector,
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.h b/drivers/gpu/drm/meson/meson_encoder_hdmi.h
index a6cd38eb5f71..fd5485875db8 100644
--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.h
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.h
@@ -7,7 +7,7 @@
 #ifndef __MESON_ENCODER_HDMI_H
 #define __MESON_ENCODER_HDMI_H
 
-int meson_encoder_hdmi_init(struct meson_drm *priv);
+int meson_encoder_hdmi_probe(struct meson_drm *priv);
 void meson_encoder_hdmi_remove(struct meson_drm *priv);
 
 #endif /* __MESON_ENCODER_HDMI_H */
-- 
2.43.2



From krzysztof.kozlowski at linaro.org  Sun Feb 18 10:21:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 18 Feb 2024 19:21:38 +0100
Subject: [GIT PULL 1/4] samsung: drivers for v6.9
Message-ID: <20240218182141.31213-1-krzysztof.kozlowski@linaro.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-drivers-6.9

for you to fetch changes up to 97d4b55111efd72926eb92cbd81c5ad8e6a7b3b1:

  MAINTAINERS: Remove Tomasz from Samsung clock and pinctrl entries (2024-02-07 16:35:26 +0100)

----------------------------------------------------------------
Samsung SoC driver changes for v6.9

1. Add bindings for Google GS101 I2C controller and SYSREG sycon block.
2. Remove Tomasz Figa from Samsung clock and pinctrl maintainer entries.

----------------------------------------------------------------
Andr? Draszik (1):
      dt-bindings: samsung: exynos-sysreg: gs101-peric0/1 require a clock

Tomasz Figa (1):
      MAINTAINERS: Remove Tomasz from Samsung clock and pinctrl entries

Tudor Ambarus (1):
      dt-bindings: i2c: exynos5: add google,gs101-hsi2c compatible

 Documentation/devicetree/bindings/i2c/i2c-exynos5.yaml                  | 1 +
 .../devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml          | 2 ++
 MAINTAINERS                                                             | 2 --
 3 files changed, 3 insertions(+), 2 deletions(-)


From krzysztof.kozlowski at linaro.org  Sun Feb 18 10:21:39 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 18 Feb 2024 19:21:39 +0100
Subject: [GIT PULL 2/4] arm64: dts: samsung: exynos and google for v6.9
In-Reply-To: <20240218182141.31213-1-krzysztof.kozlowski@linaro.org>
References: <20240218182141.31213-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240218182141.31213-2-krzysztof.kozlowski@linaro.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-6.9

for you to fetch changes up to 0791f541ff42f0ba7301f8caa7f3ab257284dc8f:

  arm64: dts: fsd: Add fifosize for UART in Device Tree (2024-02-12 14:21:29 +0100)

----------------------------------------------------------------
Samsung DTS ARM64 changes for v6.9

Mostly work around Google GS101 SoC and Pixel phone (Oriole) adding
support for:

1. Multi Core Timer (MCT) clocksource.
2. Several clock controllers (DTS and DT bindings) and use new clocks in
   several other device nodes.
3. More serial-interface instances: USI8 and USI12 with I2C.

Exynos850:
1. SPI and DMA controllers (PL330).

----------------------------------------------------------------
Andr? Draszik (7):
      arm64: dts: exynos: gs101: sysreg_peric0 needs a clock
      arm64: dts: exynos: gs101: use correct clocks for usi8
      arm64: dts: exynos: gs101: use correct clocks for usi_uart
      dt-bindings: clock: google,gs101-clock: add PERIC1 clock management unit
      arm64: dts: exynos: gs101: enable cmu-peric1 clock controller
      arm64: dts: exynos: gs101: define USI12 with I2C configuration
      arm64: dts: exynos: gs101: enable i2c bus 12 on gs101-oriole

Krzysztof Kozlowski (2):
      Merge tag 'samsung-dt-bindings-clk-6.9-3' into next/dt64
      arm64: dts: exynos: gs101: minor whitespace cleanup

Peter Griffin (1):
      arm64: dts: exynos: gs101: define Multi Core Timer (MCT) node

Sam Protsenko (3):
      dt-bindings: clock: exynos850: Add PDMA clocks
      arm64: dts: exynos: Add PDMA node for Exynos850
      arm64: dts: exynos: Add SPI nodes for Exynos850

Tamseel Shams (1):
      arm64: dts: fsd: Add fifosize for UART in Device Tree

Tudor Ambarus (6):
      dt-bindings: clock: google,gs101-clock: add PERIC0 clock management unit
      arm64: dts: exynos: gs101: remove reg-io-width from serial
      arm64: dts: exynos: gs101: enable cmu-peric0 clock controller
      arm64: dts: exynos: gs101: update USI UART to use peric0 clocks
      arm64: dts: exynos: gs101: define USI8 with I2C configuration
      arm64: dts: exynos: gs101: enable eeprom on gs101-oriole

 .../bindings/clock/google,gs101-clock.yaml         |  28 ++++-
 arch/arm64/boot/dts/exynos/exynos850.dtsi          |  64 ++++++++++
 arch/arm64/boot/dts/exynos/google/gs101-oriole.dts |  24 ++++
 .../boot/dts/exynos/google/gs101-pinctrl.dtsi      |   2 +-
 arch/arm64/boot/dts/exynos/google/gs101.dtsi       | 131 ++++++++++++++++++---
 arch/arm64/boot/dts/tesla/fsd.dtsi                 |   2 +
 include/dt-bindings/clock/exynos850.h              |   2 +
 include/dt-bindings/clock/google,gs101.h           | 129 ++++++++++++++++++++
 8 files changed, 360 insertions(+), 22 deletions(-)


From krzysztof.kozlowski at linaro.org  Sun Feb 18 10:21:40 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 18 Feb 2024 19:21:40 +0100
Subject: [GIT PULL 3/4] ARM: dts: samsung: for v6.9
In-Reply-To: <20240218182141.31213-1-krzysztof.kozlowski@linaro.org>
References: <20240218182141.31213-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240218182141.31213-3-krzysztof.kozlowski@linaro.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt-6.9

for you to fetch changes up to 60f1164e21cc04666d23b63e1153af74e7a5650d:

  ARM: dts: samsung: exynos5420-galaxy-tab-common: add wifi node (2024-02-07 16:22:01 +0100)

----------------------------------------------------------------
Samsung DTS ARM changes for v6.9

1. Disable thermal polling by Linux in Eynos5422 Odroid XU3 boards,
   because drivers implement now proper dynamic trip points management.

2. Mark crosc-ec-spi in Peach Pi and Peach Pit as wake-up source, to
   reflect the hardware capabilities.

3. Samsung P4 Note (Exynos4412): add accelerometer.

4. Samsung Galaxy Tab (Exynos5420):
   - Reduce available RAM to avoid conflict with TrustZone.
   - Add WiFi on MMC.

----------------------------------------------------------------
Henrik Grimler (2):
      ARM: dts: samsung: exynos5420-galaxy-tab: decrease available memory
      ARM: dts: samsung: exynos5420-galaxy-tab-common: add wifi node

Mark Hasemeyer (2):
      ARM: dts: samsung: exynos5420-peach: Enable cros-ec-spi as wake source
      ARM: dts: samsung: exynos5800-peach: Enable cros-ec-spi as wake source

Martin J?cker (1):
      ARM: dts: samsung: exynos4412-p4note: add accelerometer and gyro to p4note

Mateusz Majewski (1):
      ARM: dts: samsung: exynos5422-odroidxu3: disable thermal polling

 arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi   | 51 ++++++++++++++++++++++
 .../dts/samsung/exynos5420-galaxy-tab-common.dtsi  | 34 ++++++++++++++-
 arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts |  1 +
 .../dts/samsung/exynos5422-odroidxu3-common.dtsi   | 16 +++----
 arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts  |  1 +
 5 files changed, 91 insertions(+), 12 deletions(-)


From krzysztof.kozlowski at linaro.org  Sun Feb 18 10:21:41 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 18 Feb 2024 19:21:41 +0100
Subject: [GIT PULL 4/4] ARM: samsung: soc for v6.9
In-Reply-To: <20240218182141.31213-1-krzysztof.kozlowski@linaro.org>
References: <20240218182141.31213-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240218182141.31213-4-krzysztof.kozlowski@linaro.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-soc-6.9

for you to fetch changes up to a3891621d4a0783ae178d6f2845517e3dd571dd4:

  ARM: s3c64xx: make bus_type const (2024-02-12 08:28:44 +0100)

----------------------------------------------------------------
Samsung mach/soc changes for v6.9

Just cleanups: kerneldoc warning and add missing const to bus_type.

----------------------------------------------------------------
Randy Dunlap (1):
      ARM: s5pv210: fix pm.c kernel-doc warning

Ricardo B. Marliere (1):
      ARM: s3c64xx: make bus_type const

 arch/arm/mach-s3c/cpu.h     | 2 +-
 arch/arm/mach-s3c/s3c6410.c | 2 +-
 arch/arm/mach-s3c/s3c64xx.c | 2 +-
 arch/arm/mach-s5pv210/pm.c  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)


From krzysztof.kozlowski at linaro.org  Sun Feb 18 10:26:56 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 18 Feb 2024 19:26:56 +0100
Subject: [GIT PULL] ARM: dts: various improvements for v6.9
Message-ID: <20240218182656.32103-1-krzysztof.kozlowski@linaro.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-dt.git tags/dt-cleanup-6.9

for you to fetch changes up to 8c82b4eef2972200f6171aaa260d7bba2ad29889:

  ARM: dts: sti: minor whitespace cleanup around '=' (2024-01-26 15:30:45 +0100)

----------------------------------------------------------------
Minor improvements in ARM DTS for v6.9

1. Marvell MMP2: Very old issue, for which I sent patch back in 2014.
   Patch was never picked up and now another try to fix the same
   happened, so here it goes: use proper compatible MAX8925.
2. Marvell Dove: add proper unit-addresses.
3. TI DA850: add MMC interrupts.
4. STI: minor white-space fixes.

----------------------------------------------------------------
Alvin ?ipraga (1):
      ARM: dts: marvell: dove-cubox: fix si5351 node names

David Lechner (1):
      ARM: dts: da850: add MMD SDIO interrupts

Duje Mihanovi? (1):
      arm: dts: marvell: Fix maxium->maxim typo in brownstone dts

Krzysztof Kozlowski (1):
      ARM: dts: sti: minor whitespace cleanup around '='

 arch/arm/boot/dts/marvell/dove-cubox.dts      | 4 ++--
 arch/arm/boot/dts/marvell/mmp2-brownstone.dts | 2 +-
 arch/arm/boot/dts/st/stih407-pinctrl.dtsi     | 8 ++++----
 arch/arm/boot/dts/ti/davinci/da850.dtsi       | 4 ++--
 4 files changed, 9 insertions(+), 9 deletions(-)


From krzysztof.kozlowski at linaro.org  Sun Feb 18 10:35:35 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 18 Feb 2024 19:35:35 +0100
Subject: [PATCH v1 1/6] dt-bindings: cache: Document the
 sifive,perfmon-counters property
In-Reply-To: <72221da1-4a1a-4947-a202-9de203032f5c@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
 <20240216000837.1868917-2-samuel.holland@sifive.com>
 <eeb2331d-10e6-4902-91ba-85896a8f0ee1@linaro.org>
 <72221da1-4a1a-4947-a202-9de203032f5c@sifive.com>
Message-ID: <6ac4005b-01e6-48c2-971e-d6a127134d13@linaro.org>

On 18/02/2024 16:29, Samuel Holland wrote:
> Hi Krzysztof,
> 
> On 2024-02-17 3:00 AM, Krzysztof Kozlowski wrote:
>> On 16/02/2024 01:08, Samuel Holland wrote:
>>> The SiFive Composable Cache controller contains an optional PMU with a
>>> configurable number of event counters. Document a property which
>>
>> Configurable in what context? By chip designers or by OS? Why this
>> cannot be deduced from the compatible?
> 
> This parameter is configurable by the chip designers.
> 
> The information certainly can be deduced from the SoC-specific compatible
> string, but doing so makes the driver only work on that specific list of SoCs.

Usually that's exactly what's expected, so why here usual approach is wrong?

> When provided via a property, the driver can work without changes on any SoC
> that uses this IP block. (None of the SoCs currently listed in the binding

Sorry, properties are not a work-around for missing compatibles.

> contain a PMU, so there is no backward compatibility concern with adding the new
> property.)
> 
> My understanding of the purpose of the SoC-specific compatible string is to
> handle eventualities (silicon bugs, integration quirks, etc.), not to
> intentionally limit the driver to a narrow list of hardware.

Depends what is the hardware. For most of licensed blocks, the final
design is the hardware so equals to its compatible.

Best regards,
Krzysztof



From laurent.pinchart at ideasonboard.com  Sun Feb 18 10:53:47 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sun, 18 Feb 2024 20:53:47 +0200
Subject: [PATCH v12 08/12] media: rkisp1: Support i.MX8MP's 34-bit DMA
In-Reply-To: <1884916.CQOukoFCf9@steina-w>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
 <20240216095458.2919694-9-paul.elder@ideasonboard.com>
 <1884916.CQOukoFCf9@steina-w>
Message-ID: <20240218185347.GJ7120@pendragon.ideasonboard.com>

Hi Alexander,

On Fri, Feb 16, 2024 at 11:31:46AM +0100, Alexander Stein wrote:
> Hi Paul,
> 
> thanks for the update.
> 
> Am Freitag, 16. Februar 2024, 10:54:54 CET schrieb Paul Elder:
> > On the ISP that is integrated in the i.MX8MP, DMA addresses have been
> > extended to 34 bits, with the 32 MSBs stored in the DMA address
> > registers and the 2 LSBs set to 0.
> > 
> > To support this:
> > - Shift the addresses to the right by 2 when writing to registers
> > - Set the dma mask to 34 bits
> > - Use dma_addr_t instead of u32 when storing the addresses
> > 
> > Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> > Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > Tested-by: Adam Ford <aford173 at gmail.com>
> > Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> > ---
> > Changes since v5:
> > 
> > - Improve the commit message
> > 
> > Changes since v4:
> > 
> > - Squash in fix from Tomi:
> >   -
> > https://gitlab.com/ideasonboard/nxp/linux/-/commit/d6477fe673b1c0d05d12ae21
> > d8db9a03b07e7fea
> > 
> > Changes since v2:
> > 
> > - Document the RKISP1_FEATURE_DMA_34BIT bit
> > - Use the rkisp1_has_feature() macro
> > ---
> >  .../platform/rockchip/rkisp1/rkisp1-capture.c | 20 ++++++++++---------
> >  .../platform/rockchip/rkisp1/rkisp1-common.h  |  4 +++-
> >  .../platform/rockchip/rkisp1/rkisp1-dev.c     |  8 ++++++++
> >  3 files changed, 22 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> > b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c index
> > ca95f62822fa..1ee7639c42b7 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> > @@ -648,11 +648,13 @@ static void rkisp1_dummy_buf_destroy(struct
> > rkisp1_capture *cap)
> > 
> >  static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
> >  {
> > +	u8 shift = rkisp1_has_feature(cap->rkisp1, DMA_34BIT) ? 2 : 0;
> > +
> >  	cap->buf.curr = cap->buf.next;
> >  	cap->buf.next = NULL;
> > 
> >  	if (!list_empty(&cap->buf.queue)) {
> > -		u32 *buff_addr;
> > +		dma_addr_t *buff_addr;
> > 
> >  		cap->buf.next = list_first_entry(&cap->buf.queue, struct 
> rkisp1_buffer,

On a side note, any chance your mail client would have an option to
avoid this kind of wrapping ? :-)

> > queue); list_del(&cap->buf.next->queue);
> > @@ -660,7 +662,7 @@ static void rkisp1_set_next_buf(struct rkisp1_capture
> > *cap) buff_addr = cap->buf.next->buff_addr;
> > 
> >  		rkisp1_write(cap->rkisp1, cap->config->mi.y_base_ad_init,
> > -			     buff_addr[RKISP1_PLANE_Y]);
> > +			     buff_addr[RKISP1_PLANE_Y] >> shift);
> >  		/*
> >  		 * In order to support grey format we capture
> >  		 * YUV422 planar format from the camera and
> > @@ -669,17 +671,17 @@ static void rkisp1_set_next_buf(struct rkisp1_capture
> > *cap) if (cap->pix.cfg->fourcc == V4L2_PIX_FMT_GREY) {
> >  			rkisp1_write(cap->rkisp1,
> >  				     cap->config->mi.cb_base_ad_init,
> > -				     cap->buf.dummy.dma_addr);
> > +				     cap->buf.dummy.dma_addr >> 
> shift);
> >  			rkisp1_write(cap->rkisp1,
> >  				     cap->config->mi.cr_base_ad_init,
> > -				     cap->buf.dummy.dma_addr);
> > +				     cap->buf.dummy.dma_addr >> 
> shift);
> >  		} else {
> >  			rkisp1_write(cap->rkisp1,
> >  				     cap->config->mi.cb_base_ad_init,
> > -				     buff_addr[RKISP1_PLANE_CB]);
> > +				     buff_addr[RKISP1_PLANE_CB] >> 
> shift);
> >  			rkisp1_write(cap->rkisp1,
> >  				     cap->config->mi.cr_base_ad_init,
> > -				     buff_addr[RKISP1_PLANE_CR]);
> > +				     buff_addr[RKISP1_PLANE_CR] >> 
> shift);
> >  		}
> >  	} else {
> >  		/*
> > @@ -687,11 +689,11 @@ static void rkisp1_set_next_buf(struct rkisp1_capture
> > *cap) * throw data if there is no available buffer.
> >  		 */
> >  		rkisp1_write(cap->rkisp1, cap->config->mi.y_base_ad_init,
> > -			     cap->buf.dummy.dma_addr);
> > +			     cap->buf.dummy.dma_addr >> shift);
> >  		rkisp1_write(cap->rkisp1, cap->config->mi.cb_base_ad_init,
> > -			     cap->buf.dummy.dma_addr);
> > +			     cap->buf.dummy.dma_addr >> shift);
> >  		rkisp1_write(cap->rkisp1, cap->config->mi.cr_base_ad_init,
> > -			     cap->buf.dummy.dma_addr);
> > +			     cap->buf.dummy.dma_addr >> shift);
> >  	}
> > 
> >  	/* Set plane offsets */
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index
> > 69940014d597..26573f6ae575 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > @@ -114,6 +114,7 @@ enum rkisp1_isp_pad {
> >   * @RKISP1_FEATURE_MAIN_STRIDE: The ISP supports configurable stride on the
> > main path * @RKISP1_FEATURE_SELF_PATH: The ISP has a self path
> >   * @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the
> > resizer input + * @RKISP1_FEATURE_DMA_34BIT: The ISP uses 34-bit DMA
> > addresses
> >   *
> >   * The ISP features are stored in a bitmask in &rkisp1_info.features and
> > allow * the driver to implement support for features present in some ISP
> > versions @@ -124,6 +125,7 @@ enum rkisp1_feature {
> >  	RKISP1_FEATURE_MAIN_STRIDE = BIT(1),
> >  	RKISP1_FEATURE_SELF_PATH = BIT(2),
> >  	RKISP1_FEATURE_DUAL_CROP = BIT(3),
> > +	RKISP1_FEATURE_DMA_34BIT = BIT(4),
> >  };
> > 
> >  #define rkisp1_has_feature(rkisp1, feature) \
> > @@ -239,7 +241,7 @@ struct rkisp1_vdev_node {
> >  struct rkisp1_buffer {
> >  	struct vb2_v4l2_buffer vb;
> >  	struct list_head queue;
> > -	u32 buff_addr[VIDEO_MAX_PLANES];
> > +	dma_addr_t buff_addr[VIDEO_MAX_PLANES];
> >  };
> > 
> >  /*
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> > b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index
> > d0a3a13d9dd7..54a62487a4e8 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> > @@ -552,6 +552,7 @@ static int rkisp1_probe(struct platform_device *pdev)
> >  	struct device *dev = &pdev->dev;
> >  	struct rkisp1_device *rkisp1;
> >  	struct v4l2_device *v4l2_dev;
> > +	unsigned long long dma_mask;
> 
> The signature for dma_set_mask_and_coherent() uses u64 for the mask, so I 
> would use the same type here as well.

I'll do so in v13.

> >  	unsigned int i;
> >  	int ret, irq;
> >  	u32 cif_id;
> > @@ -566,6 +567,13 @@ static int rkisp1_probe(struct platform_device *pdev)
> >  	dev_set_drvdata(dev, rkisp1);
> >  	rkisp1->dev = dev;
> > 
> > +	dma_mask = rkisp1_has_feature(rkisp1, DMA_34BIT) ? DMA_BIT_MASK(34) 
> :
> > +							   
> DMA_BIT_MASK(32);
> > +
> > +	ret = dma_set_mask_and_coherent(dev, dma_mask);
> > +	if (ret)
> > +		return ret;
> > +
> >  	mutex_init(&rkisp1->stream_lock);
> > 
> >  	rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Sun Feb 18 12:01:12 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sun, 18 Feb 2024 22:01:12 +0200
Subject: [PATCH v12 11/12] media: rkisp1: Fix endianness on raw streams
 on i.MX8MP
In-Reply-To: <1980499.usQuhbGJ8B@steina-w>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
 <20240216095458.2919694-12-paul.elder@ideasonboard.com>
 <1980499.usQuhbGJ8B@steina-w>
Message-ID: <20240218200112.GK7120@pendragon.ideasonboard.com>

On Fri, Feb 16, 2024 at 11:28:36AM +0100, Alexander Stein wrote:
> Hi Paul,
> 
> thanks for updating this.
> 
> Am Freitag, 16. Februar 2024, 10:54:57 CET schrieb Paul Elder:
> > The i.MX8MP has extra register fields in the memory interface control
> > register for setting the output format, which work with the output
> > alignment format register for byte-swapping and LSB/MSB alignment.
> > 
> > With processed and 8-bit raw streams, it doesn't cause any problems to
> > not set these, but with raw streams of higher bit depth the endianness
> > is swapped and the data is not aligned properly.
> > 
> > Add support for settings these registers and plumb them in to fix this.

s/settings/setting/

> > 
> > Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> > ---
> > Changes in v12:
> > - replace MP_OUTPUT_FORMAT feature flag with MAIN_STRIDE
> > 
> > New in v6
> > ---
> >  .../platform/rockchip/rkisp1/rkisp1-capture.c | 93 ++++++++++++++-----
> >  .../platform/rockchip/rkisp1/rkisp1-regs.h    |  8 ++
> >  2 files changed, 78 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> > b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c index
> > 64b1d1104e20..28a99b31581b 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> > @@ -48,16 +48,20 @@ enum rkisp1_plane {
> >   * @fmt_type: helper filed for pixel format
> >   * @uv_swap: if cb cr swapped, for yuv
> >   * @yc_swap: if y and cb/cr swapped, for yuv
> > + * @byte_swap: if byte pairs are swapped, for raw
> >   * @write_format: defines how YCbCr self picture data is written to memory
> > - * @output_format: defines sp output format
> > + * @output_format_mp: defines mp output format
> > + * @output_format_sp: defines sp output format

I don't see any format that defines both output_format_mp and
output_format_sp. Unless you want to merge the rkisp1_mp_fmts and
rkisp1_sp_fmts arrays (I'm not sure it would be doable), you could use a
single output_format field. Only the description needs to be updated.

> >   * @mbus: the mbus code on the src resizer pad that matches the pixel
> > format */
> >  struct rkisp1_capture_fmt_cfg {
> >  	u32 fourcc;
> >  	u32 uv_swap : 1;
> >  	u32 yc_swap : 1;
> > +	u32 byte_swap : 1;
> >  	u32 write_format;
> > -	u32 output_format;
> > +	u32 output_format_mp;
> > +	u32 output_format_sp;
> >  	u32 mbus;
> >  };
> > 
> > @@ -96,42 +100,50 @@ static const struct rkisp1_capture_fmt_cfg
> > rkisp1_mp_fmts[] = { .fourcc = V4L2_PIX_FMT_YUYV,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_UYVY,
> >  		.uv_swap = 0,
> >  		.yc_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_YUV422P,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV16,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV61,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV16M,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV61M,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_YVU422M,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	},
> >  	/* yuv400 */
> > @@ -139,6 +151,7 @@ static const struct rkisp1_capture_fmt_cfg
> > rkisp1_mp_fmts[] = { .fourcc = V4L2_PIX_FMT_GREY,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	},
> >  	/* yuv420 */
> > @@ -146,81 +159,107 @@ static const struct rkisp1_capture_fmt_cfg
> > rkisp1_mp_fmts[] = { .fourcc = V4L2_PIX_FMT_NV21,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV12,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV21M,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV12M,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_YUV420,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_YVU420,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	},
> >  	/* raw */
> >  	{
> >  		.fourcc = V4L2_PIX_FMT_SRGGB8,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
> >  		.mbus = MEDIA_BUS_FMT_SRGGB8_1X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SGRBG8,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
> >  		.mbus = MEDIA_BUS_FMT_SGRBG8_1X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SGBRG8,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
> >  		.mbus = MEDIA_BUS_FMT_SGBRG8_1X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SBGGR8,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
> >  		.mbus = MEDIA_BUS_FMT_SBGGR8_1X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SRGGB10,
> > +		.byte_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
> >  		.mbus = MEDIA_BUS_FMT_SRGGB10_1X10,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SGRBG10,
> > +		.byte_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
> >  		.mbus = MEDIA_BUS_FMT_SGRBG10_1X10,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SGBRG10,
> > +		.byte_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
> >  		.mbus = MEDIA_BUS_FMT_SGBRG10_1X10,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SBGGR10,
> > +		.byte_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
> >  		.mbus = MEDIA_BUS_FMT_SBGGR10_1X10,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SRGGB12,
> > +		.byte_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
> >  		.mbus = MEDIA_BUS_FMT_SRGGB12_1X12,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SGRBG12,
> > +		.byte_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
> >  		.mbus = MEDIA_BUS_FMT_SGRBG12_1X12,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SGBRG12,
> > +		.byte_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
> >  		.mbus = MEDIA_BUS_FMT_SGBRG12_1X12,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_SBGGR12,
> > +		.byte_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
> > +		.output_format_mp = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
> >  		.mbus = MEDIA_BUS_FMT_SBGGR12_1X12,
> >  	},
> >  };
> > @@ -235,50 +274,50 @@ static const struct rkisp1_capture_fmt_cfg
> > rkisp1_sp_fmts[] = { .fourcc = V4L2_PIX_FMT_YUYV,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_UYVY,
> >  		.uv_swap = 0,
> >  		.yc_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_YUV422P,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV16,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV61,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV16M,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV61M,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_YVU422M,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	},
> >  	/* yuv400 */
> > @@ -286,19 +325,19 @@ static const struct rkisp1_capture_fmt_cfg
> > rkisp1_sp_fmts[] = { .fourcc = V4L2_PIX_FMT_GREY,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	},
> >  	/* rgb */
> >  	{
> >  		.fourcc = V4L2_PIX_FMT_XBGR32,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_RGB565,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
> >  	},
> >  	/* yuv420 */
> > @@ -306,37 +345,37 @@ static const struct rkisp1_capture_fmt_cfg
> > rkisp1_sp_fmts[] = { .fourcc = V4L2_PIX_FMT_NV21,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV12,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV21M,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_NV12M,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_YUV420,
> >  		.uv_swap = 0,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	}, {
> >  		.fourcc = V4L2_PIX_FMT_YVU420,
> >  		.uv_swap = 1,
> >  		.write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
> > -		.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> > +		.output_format_sp = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
> >  		.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
> >  	},
> >  };
> > @@ -484,10 +523,12 @@ static void rkisp1_mp_config(struct rkisp1_capture
> > *cap) */
> >  	if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
> >  		reg = rkisp1_read(rkisp1, 
> RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
> > -		if (cap->pix.cfg->yc_swap)
> > +		if (cap->pix.cfg->yc_swap || cap->pix.cfg->byte_swap)
> >  			reg |= 
> RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
> >  		else
> >  			reg &= 
> ~RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
> > +
> > +		reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_LSB_ALIGNMENT;
> >  		rkisp1_write(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT, 
> reg);
> >  	}
> > 
> > @@ -554,7 +595,7 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap)
> > mi_ctrl &= ~RKISP1_MI_CTRL_SP_FMT_MASK;
> >  	mi_ctrl |= cap->pix.cfg->write_format |
> >  		   RKISP1_MI_CTRL_SP_INPUT_YUV422 |
> > -		   cap->pix.cfg->output_format |
> > +		   cap->pix.cfg->output_format_sp |
> >  		   RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE;
> >  	rkisp1_write(rkisp1, RKISP1_CIF_MI_CTRL, mi_ctrl);
> >  }
> > @@ -946,6 +987,7 @@ static void rkisp1_cap_stream_enable(struct
> > rkisp1_capture *cap) struct rkisp1_device *rkisp1 = cap->rkisp1;
> >  	struct rkisp1_capture *other = &rkisp1->capture_devs[cap->id ^ 1];
> >  	bool has_self_path = rkisp1_has_feature(rkisp1, SELF_PATH);
> > +	u32 reg;
> > 
> >  	cap->ops->set_data_path(cap);
> >  	cap->ops->config(cap);
> > @@ -965,8 +1007,13 @@ static void rkisp1_cap_stream_enable(struct
> > rkisp1_capture *cap) */
> >  	if (!has_self_path || !other->is_streaming) {
> >  		/* force cfg update */
> > -		rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT,
> > -			     RKISP1_CIF_MI_INIT_SOFT_UPD);
> > +		reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_INIT);
> > +
> > +		if (rkisp1_has_feature(rkisp1, MAIN_STRIDE))
> > +			reg |= cap->pix.cfg->output_format_mp;
> 
> I don't have any documents regarding that ISP, but shouldn't you clear the 
> bits for output_format_mp before OR'ing the new ones on top?

I think it would be even better to set the output format in
rkisp1_mp_config(), writing the whole register there.

> > +
> > +		reg |= RKISP1_CIF_MI_INIT_SOFT_UPD;
> > +		rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT, reg);
> >  		rkisp1_set_next_buf(cap);
> >  	}
> >  	spin_unlock_irq(&cap->buf.lock);
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> > b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h index
> > 3b19c8411360..762243016f05 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> > @@ -144,6 +144,14 @@
> >  /* MI_INIT */
> >  #define RKISP1_CIF_MI_INIT_SKIP				BIT(2)
> >  #define RKISP1_CIF_MI_INIT_SOFT_UPD			BIT(4)
> > +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400		(0 << 5)
> > +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420		(1 << 5)
> > +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422		(2 << 5)
> > +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV444		(3 << 5)
> > +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12		(4 << 5)
> > +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8		(5 << 5)
> > +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_JPEG		(6 << 5)
> > +#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10		(7 << 5)
> > 
> >  /* MI_CTRL_SHD */
> >  #define RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED		BIT(0)

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Sun Feb 18 12:03:33 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sun, 18 Feb 2024 22:03:33 +0200
Subject: [PATCH v12 12/12] media: rkisp1: Add match data for i.MX8MP ISP
In-Reply-To: <20240216095458.2919694-13-paul.elder@ideasonboard.com>
References: <20240216095458.2919694-1-paul.elder@ideasonboard.com>
 <20240216095458.2919694-13-paul.elder@ideasonboard.com>
Message-ID: <20240218200333.GL7120@pendragon.ideasonboard.com>

Hi Paul,

Thank you for the patch.

On Fri, Feb 16, 2024 at 06:54:58PM +0900, Paul Elder wrote:
> Add match data to the rkisp1 driver to match the i.MX8MP ISP.
> 
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> Tested-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
> Changes in v12:
> - move out adding the version enum
> ---
>  .../platform/rockchip/rkisp1/rkisp1-dev.c     | 24 +++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> index 54a62487a4e8..a6b47f0af467 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
> @@ -533,6 +533,26 @@ static const struct rkisp1_info rk3399_isp_info = {
>  		  | RKISP1_FEATURE_DUAL_CROP,
>  };
>  
> +static const char * const imx8mp_isp_clks[] = {
> +	"isp",
> +	"hclk",
> +	"aclk",
> +};
> +
> +static const struct rkisp1_isr_data imx8mp_isp_isrs[] = {
> +	{ NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) },
> +};
> +
> +static const struct rkisp1_info imx8mp_isp_info = {
> +	.clks = imx8mp_isp_clks,
> +	.clk_size = ARRAY_SIZE(imx8mp_isp_clks),
> +	.isrs = imx8mp_isp_isrs,
> +	.isr_size = ARRAY_SIZE(imx8mp_isp_isrs),
> +	.isp_ver = RKISP1_V_IMX8MP,
> +	.features = RKISP1_FEATURE_MAIN_STRIDE
> +		  | RKISP1_FEATURE_DMA_34BIT,
> +};
> +
>  static const struct of_device_id rkisp1_of_match[] = {
>  	{
>  		.compatible = "rockchip,px30-cif-isp",
> @@ -542,6 +562,10 @@ static const struct of_device_id rkisp1_of_match[] = {
>  		.compatible = "rockchip,rk3399-cif-isp",
>  		.data = &rk3399_isp_info,
>  	},
> +	{
> +		.compatible = "fsl,imx8mp-isp",
> +		.data = &imx8mp_isp_info,
> +	},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, rkisp1_of_match);

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Sun Feb 18 12:59:08 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sun, 18 Feb 2024 22:59:08 +0200
Subject: [PATCH] media: rkisp1: Allow higher input resolution
In-Reply-To: <20240217185202.1754750-1-megi@xff.cz>
References: <20240217185202.1754750-1-megi@xff.cz>
Message-ID: <20240218205908.GA12766@pendragon.ideasonboard.com>

Hi Ondrej,

(CC'ing Paul and Umang)

Thank you for the patch.

On Sat, Feb 17, 2024 at 07:51:58PM +0100, Ond?ej Jirman wrote:
> From: Ondrej Jirman <megi at xff.cz>
> 
> In BSP driver, it is allowed, and it works in practice. Tested on
> Pinephone Pro/RK3399 with IMX258 at full res.

Paul, Umang, do I recall correctly that you have a similar change ?
Could you review and test this (especially on the i.MX8MP) ?

> Signed-off-by: Ondrej Jirman <megi at xff.cz>
> ---
>  drivers/media/platform/rockchip/rkisp1/rkisp1-common.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> index 4b6b28c05b89..74098ddbeeb3 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> @@ -33,8 +33,8 @@ struct dentry;
>  #define RKISP1_ISP_SD_SINK			BIT(1)
>  
>  /* min and max values for the widths and heights of the entities */
> -#define RKISP1_ISP_MAX_WIDTH			4032
> -#define RKISP1_ISP_MAX_HEIGHT			3024
> +#define RKISP1_ISP_MAX_WIDTH			4416
> +#define RKISP1_ISP_MAX_HEIGHT			3312
>  #define RKISP1_ISP_MIN_WIDTH			32
>  #define RKISP1_ISP_MIN_HEIGHT			32
>  

-- 
Regards,

Laurent Pinchart


From megi at xff.cz  Sun Feb 18 13:01:52 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Sun, 18 Feb 2024 22:01:52 +0100
Subject: [PATCH] media: rkisp1: Allow higher input resolution
In-Reply-To: <20240218205908.GA12766@pendragon.ideasonboard.com>
References: <20240217185202.1754750-1-megi@xff.cz>
 <20240218205908.GA12766@pendragon.ideasonboard.com>
Message-ID: <pftafukuzq7qzbhlvwtmeg3mburnttylgy4246timlghtrdgx4@r6munvmj6oqt>

On Sun, Feb 18, 2024 at 10:59:08PM +0200, Laurent Pinchart wrote:
> Hi Ondrej,
> 
> (CC'ing Paul and Umang)
> 
> Thank you for the patch.
> 
> On Sat, Feb 17, 2024 at 07:51:58PM +0100, Ond?ej Jirman wrote:
> > From: Ondrej Jirman <megi at xff.cz>
> > 
> > In BSP driver, it is allowed, and it works in practice. Tested on
> > Pinephone Pro/RK3399 with IMX258 at full res.
> 
> Paul, Umang, do I recall correctly that you have a similar change ?
> Could you review and test this (especially on the i.MX8MP) ?

It's also a limit from the datasheet, so the change should not be that
controversial:

  https://megous.com/dl/tmp/d2b333043ecebaf3.png

(so that it doesn't sound like I just copied the BSP values)

regards,
	o.

> > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > ---
> >  drivers/media/platform/rockchip/rkisp1/rkisp1-common.h | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > index 4b6b28c05b89..74098ddbeeb3 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > @@ -33,8 +33,8 @@ struct dentry;
> >  #define RKISP1_ISP_SD_SINK			BIT(1)
> >  
> >  /* min and max values for the widths and heights of the entities */
> > -#define RKISP1_ISP_MAX_WIDTH			4032
> > -#define RKISP1_ISP_MAX_HEIGHT			3024
> > +#define RKISP1_ISP_MAX_WIDTH			4416
> > +#define RKISP1_ISP_MAX_HEIGHT			3312
> >  #define RKISP1_ISP_MIN_WIDTH			32
> >  #define RKISP1_ISP_MIN_HEIGHT			32
> >  
> 
> -- 
> Regards,
> 
> Laurent Pinchart


From kilian.zinnecker at mail.de  Sun Feb 18 14:16:58 2024
From: kilian.zinnecker at mail.de (Kilian Zinnecker)
Date: Sun, 18 Feb 2024 23:16:58 +0100
Subject: [PATCH] crypto: rockchip - fix to check return value
Message-ID: <20240218221658.131043-1-kilian.zinnecker@mail.de>

crypto_engine_alloc_init may fail, e.g., as result of a fail of
devm_kzalloc or kthread_create_worker. Other drivers (e.g.,
amlogic-gxl-core.c, aspeed-acry.c, aspeed-hace.c, jr.c, etc.) check
crypto_engine_alloc_init's return value and return -ENOMEM in case
a NULL pointer is returned. This patch inserts a corresponding
return value check to rk3288_crypto.c.

Signed-off-by: Kilian Zinnecker <kilian.zinnecker at mail.de>
---
 drivers/crypto/rockchip/rk3288_crypto.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index 70edf40bc523..f74b3c81ba6d 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -371,6 +371,11 @@ static int rk_crypto_probe(struct platform_device *pdev)
 	}
 
 	crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true);
+	if (!crypto_info->engine) {
+		err = -ENOMEM;
+		goto err_crypto;
+	}
+
 	crypto_engine_start(crypto_info->engine);
 	init_completion(&crypto_info->complete);
 
-- 
2.34.1



From lk at c--e.de  Sun Feb 18 14:20:39 2024
From: lk at c--e.de (Christian A. Ehrhardt)
Date: Sun, 18 Feb 2024 23:20:39 +0100
Subject: [RFC PATCH 6/6] usb: typec: ucsi: Convert a?sync_write to a?sync_cmd
In-Reply-To: <20240218222039.822040-1-lk@c--e.de>
References: <20240218222039.822040-1-lk@c--e.de>
Message-ID: <20240218222039.822040-7-lk@c--e.de>

The ->sync_write an ->async_write callbacks are only used to write to
the UCSI_CONTROL field and start a command, now.

Rename them accordingly and remove parameters and code that are no
longer used. While there note that the command passed in from the
UCSI core is in host byte order but the command sent to UCSI must
be in little endian byte order.

Signed-off-by: Christian A. Ehrhardt <lk at c--e.de>
---
 drivers/usb/typec/ucsi/ucsi.c         | 29 ++++++-------------
 drivers/usb/typec/ucsi/ucsi.h         | 14 ++++-----
 drivers/usb/typec/ucsi/ucsi_acpi.c    | 41 ++++++++++++---------------
 drivers/usb/typec/ucsi/ucsi_ccg.c     | 35 +++++++++++------------
 drivers/usb/typec/ucsi/ucsi_glink.c   | 18 ++++++------
 drivers/usb/typec/ucsi/ucsi_stm32g0.c | 16 +++++------
 6 files changed, 67 insertions(+), 86 deletions(-)

diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index df3fe04cb9cd..5bec98381be6 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -51,22 +51,16 @@ static int ucsi_read_message_in(struct ucsi *ucsi, void *buf,
 
 static int ucsi_acknowledge_command(struct ucsi *ucsi)
 {
-	u64 ctrl;
+	u64 cmd = UCSI_ACK_CC_CI | UCSI_ACK_COMMAND_COMPLETE;
 
-	ctrl = UCSI_ACK_CC_CI;
-	ctrl |= UCSI_ACK_COMMAND_COMPLETE;
-
-	return ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &ctrl, sizeof(ctrl));
+	return ucsi->ops->sync_cmd(ucsi, cmd);
 }
 
 static int ucsi_acknowledge_connector_change(struct ucsi *ucsi)
 {
-	u64 ctrl;
-
-	ctrl = UCSI_ACK_CC_CI;
-	ctrl |= UCSI_ACK_CONNECTOR_CHANGE;
+	u64 cmd = UCSI_ACK_CC_CI | UCSI_ACK_CONNECTOR_CHANGE;
 
-	return ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &ctrl, sizeof(ctrl));
+	return ucsi->ops->sync_cmd(ucsi, cmd);
 }
 
 static int ucsi_exec_command(struct ucsi *ucsi, u64 command);
@@ -137,7 +131,7 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd)
 	u32 cci;
 	int ret;
 
-	ret = ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
+	ret = ucsi->ops->sync_cmd(ucsi, cmd);
 	if (ret)
 		return ret;
 	cci = READ_ONCE(ucsi->cci);
@@ -1014,15 +1008,13 @@ static int ucsi_reset_connector(struct ucsi_connector *con, bool hard)
 
 static int ucsi_reset_ppm(struct ucsi *ucsi)
 {
-	u64 command = UCSI_PPM_RESET;
 	unsigned long tmo;
 	u32 cci;
 	int ret;
 
 	mutex_lock(&ucsi->ppm_lock);
 
-	ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, &command,
-				     sizeof(command));
+	ret = ucsi->ops->async_cmd(ucsi, UCSI_PPM_RESET);
 	if (ret < 0)
 		goto out;
 
@@ -1041,9 +1033,7 @@ static int ucsi_reset_ppm(struct ucsi *ucsi)
 
 		/* If the PPM is still doing something else, reset it again. */
 		if (cci & ~UCSI_CCI_RESET_COMPLETE) {
-			ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL,
-						     &command,
-						     sizeof(command));
+			ret = ucsi->ops->async_cmd(ucsi, UCSI_PPM_RESET);
 			if (ret < 0)
 				goto out;
 		}
@@ -1549,7 +1539,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)
 	struct ucsi *ucsi;
 
 	if (!ops || !ops->poll_cci || !ops->read_data || !ops->write_data ||
-	    !ops->sync_write || !ops->async_write)
+	    !ops->sync_cmd || !ops->async_cmd)
 		return ERR_PTR(-EINVAL);
 
 	ucsi = kzalloc(sizeof(*ucsi), GFP_KERNEL);
@@ -1612,7 +1602,6 @@ EXPORT_SYMBOL_GPL(ucsi_register);
  */
 void ucsi_unregister(struct ucsi *ucsi)
 {
-	u64 cmd = UCSI_SET_NOTIFICATION_ENABLE;
 	int i;
 
 	/* Make sure that we are not in the middle of driver initialization */
@@ -1620,7 +1609,7 @@ void ucsi_unregister(struct ucsi *ucsi)
 	cancel_work_sync(&ucsi->resume_work);
 
 	/* Disable notifications */
-	ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
+	ucsi->ops->async_cmd(ucsi, UCSI_SET_NOTIFICATION_ENABLE);
 
 	if (!ucsi->connector)
 		return;
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 2ad68124511b..3cce83d1e70c 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -58,22 +58,20 @@ struct dentry;
  * @poll_cci: Update the cached CCI value from hardware. Required for reset.
  * @read_data: Read MESSAGE_IN data
  * @write_data: Write MESSAGE_OUT data
- * @sync_write: Blocking write operation
- * @async_write: Non-blocking write operation
+ * @sync_cmd: Blocking command execution
+ * @async_cmd: Non-blocking command execution
  * @update_altmodes: Squashes duplicate DP altmodes
  *
- * Read and write routines for UCSI interface. @sync_write must wait for the
- * Command Completion Event from the PPM before returning, and @async_write must
+ * Read and write routines for UCSI interface. @sync_cmd must wait for the
+ * Command Completion Event from the PPM before returning, and @async_cmd must
  * return immediately after sending the data to the PPM.
  */
 struct ucsi_operations {
 	int (*poll_cci)(struct ucsi *ucsi);
 	int (*read_data)(struct ucsi *ucsi, void *val, size_t val_len);
 	int (*write_data)(struct ucsi *ucsi, const void *val, size_t val_len);
-	int (*sync_write)(struct ucsi *ucsi, unsigned int offset,
-			  const void *val, size_t val_len);
-	int (*async_write)(struct ucsi *ucsi, unsigned int offset,
-			   const void *val, size_t val_len);
+	int (*sync_cmd)(struct ucsi *ucsi, u64 cmd);
+	int (*async_cmd)(struct ucsi *ucsi, u64 cmd);
 	bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig,
 				struct ucsi_altmode *updated);
 };
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
index 79b47b433e35..e6f67aa102d2 100644
--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
@@ -77,21 +77,20 @@ static int ucsi_acpi_write_data(struct ucsi *ucsi, const void *val,
 	return 0;
 }
 
-static int ucsi_acpi_async_write(struct ucsi *ucsi, unsigned int offset,
-				 const void *val, size_t val_len)
+static int ucsi_acpi_async_cmd(struct ucsi *ucsi, u64 cmd)
 {
 	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
+	__le64 __cmd = cpu_to_le64(cmd);
 
-	memcpy(ua->base + offset, val, val_len);
+	memcpy(ua->base + UCSI_CONTROL, &__cmd, sizeof(__cmd));
 
 	return ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_WRITE);
 }
 
-static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset,
-				const void *val, size_t val_len)
+static int ucsi_acpi_sync_cmd(struct ucsi *ucsi, u64 cmd)
 {
 	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
-	bool ack = UCSI_COMMAND(*(u64 *)val) == UCSI_ACK_CC_CI;
+	bool ack = UCSI_COMMAND(cmd) == UCSI_ACK_CC_CI;
 	int ret;
 
 	if (ack)
@@ -99,7 +98,7 @@ static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset,
 	else
 		set_bit(COMMAND_PENDING, &ua->flags);
 
-	ret = ucsi_acpi_async_write(ucsi, offset, val, val_len);
+	ret = ucsi_acpi_async_cmd(ucsi, cmd);
 	if (ret)
 		goto out_clear_bit;
 
@@ -119,8 +118,8 @@ static const struct ucsi_operations ucsi_acpi_ops = {
 	.poll_cci = ucsi_acpi_poll_cci,
 	.read_data = ucsi_acpi_read_data,
 	.write_data = ucsi_acpi_write_data,
-	.sync_write = ucsi_acpi_sync_write,
-	.async_write = ucsi_acpi_async_write
+	.sync_cmd = ucsi_acpi_sync_cmd,
+	.async_cmd = ucsi_acpi_async_cmd
 };
 
 /*
@@ -131,32 +130,28 @@ static const struct ucsi_operations ucsi_acpi_ops = {
  * subsequent commands will timeout.
  */
 static int
-ucsi_dell_sync_write(struct ucsi *ucsi, unsigned int offset,
-		     const void *val, size_t val_len)
+ucsi_dell_sync_cmd(struct ucsi *ucsi, u64 cmd)
 {
 	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
-	u64 cmd = *(u64 *)val, ack = 0;
+	u64 ack = 0;
 	int ret;
 
 	if (UCSI_COMMAND(cmd) == UCSI_ACK_CC_CI &&
 	    cmd & UCSI_ACK_CONNECTOR_CHANGE)
 		ack = UCSI_ACK_CC_CI | UCSI_ACK_COMMAND_COMPLETE;
 
-	ret = ucsi_acpi_sync_write(ucsi, offset, val, val_len);
+	ret = ucsi_acpi_sync_cmd(ucsi, cmd);
 	if (ret != 0)
 		return ret;
 	if (ack == 0)
-		return ret;
+		return 0;
 
 	if (!ua->dell_quirk_probed) {
 		ua->dell_quirk_probed = true;
 
-		cmd = UCSI_GET_CAPABILITY;
-		ret = ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, &cmd,
-					   sizeof(cmd));
+		ret = ucsi_acpi_sync_cmd(ucsi, UCSI_GET_CAPABILITY);
 		if (ret == 0)
-			return ucsi_acpi_sync_write(ucsi, UCSI_CONTROL,
-						    &ack, sizeof(ack));
+			return ucsi_acpi_sync_cmd(ucsi, ack);
 		if (ret != -ETIMEDOUT)
 			return ret;
 
@@ -166,17 +161,17 @@ ucsi_dell_sync_write(struct ucsi *ucsi, unsigned int offset,
 	}
 
 	if (!ua->dell_quirk_active)
-		return ret;
+		return 0;
 
-	return ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, &ack, sizeof(ack));
+	return ucsi_acpi_sync_cmd(ucsi, ack);
 }
 
 static const struct ucsi_operations ucsi_dell_ops = {
 	.poll_cci = ucsi_acpi_poll_cci,
 	.read_data = ucsi_acpi_read_data,
 	.write_data = ucsi_acpi_write_data,
-	.sync_write = ucsi_dell_sync_write,
-	.async_write = ucsi_acpi_async_write
+	.sync_cmd = ucsi_dell_sync_cmd,
+	.async_cmd = ucsi_acpi_async_cmd
 };
 
 static const struct dmi_system_id ucsi_acpi_quirks[] = {
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index d6026f61a0ed..5c60816e608f 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -605,23 +605,22 @@ static int ucsi_ccg_write_data(struct ucsi *ucsi, const void *val,
 	return ccg_write(uc, reg, val, val_len);
 }
 
-static int ucsi_ccg_async_write(struct ucsi *ucsi, unsigned int offset,
-				const void *val, size_t val_len)
+static int ucsi_ccg_async_cmd(struct ucsi *ucsi, u64 cmd)
 {
 	struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
-	u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(offset);
+	u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(UCSI_CONTROL);
+	__le64 __cmd = cpu_to_le64(cmd);
 
 	/*
-	 * UCSI may read CCI instantly after async_write,
+	 * UCSI may read CCI instantly after async_cmd,
 	 * clear CCI to avoid caller getting wrong data before we get CCI from ISR
 	 */
 	WRITE_ONCE(ucsi->cci, 0);
 
-	return ccg_write(uc, reg, val, val_len);
+	return ccg_write(uc, reg, (u8 *)&__cmd, sizeof(__cmd));
 }
 
-static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset,
-			       const void *val, size_t val_len)
+static int ucsi_ccg_sync_cmd(struct ucsi *ucsi, u64 cmd)
 {
 	struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
 	struct ucsi_connector *con;
@@ -632,19 +631,17 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset,
 	pm_runtime_get_sync(uc->dev);
 	set_bit(DEV_CMD_PENDING, &uc->flags);
 
-	if (offset == UCSI_CONTROL && val_len == sizeof(uc->last_cmd_sent)) {
-		uc->last_cmd_sent = *(u64 *)val;
+	uc->last_cmd_sent = cmd;
 
-		if (UCSI_COMMAND(uc->last_cmd_sent) == UCSI_SET_NEW_CAM &&
-		    uc->has_multiple_dp) {
-			con_index = (uc->last_cmd_sent >> 16) &
-				    UCSI_CMD_CONNECTOR_MASK;
-			con = &uc->ucsi->connector[con_index - 1];
-			ucsi_ccg_update_set_new_cam_cmd(uc, con, (u64 *)val);
-		}
+	if (UCSI_COMMAND(uc->last_cmd_sent) == UCSI_SET_NEW_CAM &&
+	    uc->has_multiple_dp) {
+		con_index = (uc->last_cmd_sent >> 16) &
+			    UCSI_CMD_CONNECTOR_MASK;
+		con = &uc->ucsi->connector[con_index - 1];
+		ucsi_ccg_update_set_new_cam_cmd(uc, con, &cmd);
 	}
 
-	ret = ucsi_ccg_async_write(ucsi, offset, val, val_len);
+	ret = ucsi_ccg_async_cmd(ucsi, cmd);
 	if (ret)
 		goto err_clear_bit;
 
@@ -663,8 +660,8 @@ static const struct ucsi_operations ucsi_ccg_ops = {
 	.poll_cci = ucsi_ccg_poll_cci,
 	.read_data = ucsi_ccg_read_data,
 	.write_data = ucsi_ccg_write_data,
-	.sync_write = ucsi_ccg_sync_write,
-	.async_write = ucsi_ccg_async_write,
+	.sync_cmd = ucsi_ccg_sync_cmd,
+	.async_cmd = ucsi_ccg_async_cmd,
 	.update_altmodes = ucsi_ccg_update_altmodes
 };
 
diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
index 9dab1b428ad9..1535877a9a41 100644
--- a/drivers/usb/typec/ucsi/ucsi_glink.c
+++ b/drivers/usb/typec/ucsi/ucsi_glink.c
@@ -186,23 +186,24 @@ static int pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi *ucsi, unsigned i
 	return 0;
 }
 
-static int pmic_glink_ucsi_async_write(struct ucsi *__ucsi, unsigned int offset,
-				       const void *val, size_t val_len)
+static int pmic_glink_ucsi_async_cmd(struct ucsi *__ucsi, u64 cmd)
 {
 	struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
+	__le64 __cmd = cpu_to_le64(cmd);
 	int ret;
 
 	mutex_lock(&ucsi->lock);
-	ret = pmic_glink_ucsi_locked_write(ucsi, offset, val, val_len);
+	ret = pmic_glink_ucsi_locked_write(ucsi, UCSI_CONTROL,
+					   &__cmd, sizeof(__cmd));
 	mutex_unlock(&ucsi->lock);
 
 	return ret;
 }
 
-static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset,
-				      const void *val, size_t val_len)
+static int pmic_glink_ucsi_sync_cmd(struct ucsi *__ucsi, u64 cmd)
 {
 	struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
+	__le64 __cmd = cpu_to_le64(cmd);
 	unsigned long left;
 	int ret;
 
@@ -212,7 +213,8 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset,
 	ucsi->sync_val = 0;
 	reinit_completion(&ucsi->sync_ack);
 	ucsi->sync_pending = true;
-	ret = pmic_glink_ucsi_locked_write(ucsi, offset, val, val_len);
+	ret = pmic_glink_ucsi_locked_write(ucsi, UCSI_CONTROL,
+					   &__cmd, sizeof(__cmd));
 	mutex_unlock(&ucsi->lock);
 
 	left = wait_for_completion_timeout(&ucsi->sync_ack, 5 * HZ);
@@ -232,8 +234,8 @@ static const struct ucsi_operations pmic_glink_ucsi_ops = {
 	.poll_cci = pmic_glink_ucsi_poll_cci,
 	.read_data = pmic_glink_ucsi_read_data,
 	.write_data = pmic_glink_ucsi_write_data,
-	.sync_write = pmic_glink_ucsi_sync_write,
-	.async_write = pmic_glink_ucsi_async_write
+	.sync_cmd = pmic_glink_ucsi_sync_cmd,
+	.async_cmd = pmic_glink_ucsi_async_cmd
 };
 
 static void pmic_glink_ucsi_read_ack(struct pmic_glink_ucsi *ucsi, const void *data, int len)
diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c
index d68aca118e41..0847e00163e8 100644
--- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c
+++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c
@@ -421,23 +421,23 @@ static int ucsi_stm32g0_write_data(struct ucsi *ucsi,
 	return ucsi_stm32g0_write_to_hw(g0, UCSI_MESSAGE_OUT, val, len);
 }
 
-static int ucsi_stm32g0_async_write(struct ucsi *ucsi, unsigned int offset,
-				    const void *val, size_t len)
+static int ucsi_stm32g0_async_cmd(struct ucsi *ucsi, u64 cmd)
 {
 	struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
+	__le64 __cmd = cpu_to_le64(cmd);
 
-	return ucsi_stm32g0_write_to_hw(g0, offset, val, len);
+	return ucsi_stm32g0_write_to_hw(g0, UCSI_CONTROL,
+					&__cmd, sizeof(__cmd));
 }
 
-static int ucsi_stm32g0_sync_write(struct ucsi *ucsi, unsigned int offset, const void *val,
-				   size_t len)
+static int ucsi_stm32g0_sync_cmd(struct ucsi *ucsi, u64 cmd)
 {
 	struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
 	int ret;
 
 	set_bit(COMMAND_PENDING, &g0->flags);
 
-	ret = ucsi_stm32g0_async_write(ucsi, offset, val, len);
+	ret = ucsi_stm32g0_async_cmd(ucsi, cmd);
 	if (ret)
 		goto out_clear_bit;
 
@@ -480,8 +480,8 @@ static const struct ucsi_operations ucsi_stm32g0_ops = {
 	.poll_cci = ucsi_stm32g0_poll_cci,
 	.read_data = ucsi_stm32g0_read_data,
 	.write_data = ucsi_stm32g0_write_data,
-	.sync_write = ucsi_stm32g0_sync_write,
-	.async_write = ucsi_stm32g0_async_write,
+	.sync_cmd = ucsi_stm32g0_sync_cmd,
+	.async_cmd = ucsi_stm32g0_async_cmd,
 };
 
 static int ucsi_stm32g0_register(struct ucsi *ucsi)
-- 
2.40.1



From lk at c--e.de  Sun Feb 18 14:20:36 2024
From: lk at c--e.de (Christian A. Ehrhardt)
Date: Sun, 18 Feb 2024 23:20:36 +0100
Subject: [RFC PATCH 3/6] usb: typec: ucsi: Make Version a parameter to ucsi_register
In-Reply-To: <20240218222039.822040-1-lk@c--e.de>
References: <20240218222039.822040-1-lk@c--e.de>
Message-ID: <20240218222039.822040-4-lk@c--e.de>

Reading UCSI_VERSION is a special case as there is no
notification that syncs the data into host memory.

Read UCSI_VERSION only once during initialization and provide
it as a parameter to ucsi_register().

Signed-off-by: Christian A. Ehrhardt <lk at c--e.de>
---
 drivers/usb/typec/ucsi/ucsi.c         | 13 ++++---------
 drivers/usb/typec/ucsi/ucsi.h         |  2 +-
 drivers/usb/typec/ucsi/ucsi_acpi.c    |  8 +++++++-
 drivers/usb/typec/ucsi/ucsi_ccg.c     | 12 ++++++++++--
 drivers/usb/typec/ucsi/ucsi_glink.c   | 11 ++++++++++-
 drivers/usb/typec/ucsi/ucsi_stm32g0.c | 26 ++++++++++++++++++++++----
 6 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index ae105383e69e..eb630447ba80 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -1581,18 +1581,13 @@ EXPORT_SYMBOL_GPL(ucsi_destroy);
 /**
  * ucsi_register - Register UCSI interface
  * @ucsi: UCSI instance
+ * @version: The revision of the UCSI spec
  */
-int ucsi_register(struct ucsi *ucsi)
+int ucsi_register(struct ucsi *ucsi, u16 version)
 {
-	int ret;
-
-	ret = ucsi->ops->read(ucsi, UCSI_VERSION, &ucsi->version,
-			      sizeof(ucsi->version));
-	if (ret)
-		return ret;
-
-	if (!ucsi->version)
+	if (!version)
 		return -ENODEV;
+	ucsi->version = version;
 
 	/*
 	 * Version format is JJ.M.N (JJ = Major version, M = Minor version,
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 7e35ffbe0a6f..100e16b49814 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -77,7 +77,7 @@ struct ucsi_operations {
 
 struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops);
 void ucsi_destroy(struct ucsi *ucsi);
-int ucsi_register(struct ucsi *ucsi);
+int ucsi_register(struct ucsi *ucsi, u16 version);
 void ucsi_unregister(struct ucsi *ucsi);
 void *ucsi_get_drvdata(struct ucsi *ucsi);
 void ucsi_set_drvdata(struct ucsi *ucsi, void *data);
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
index 928eacbeb21a..710ddfc03ed0 100644
--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
@@ -226,6 +226,7 @@ static int ucsi_acpi_probe(struct platform_device *pdev)
 	const struct dmi_system_id *id;
 	struct ucsi_acpi *ua;
 	struct resource *res;
+	u16 version;
 	acpi_status status;
 	int ret;
 
@@ -272,7 +273,12 @@ static int ucsi_acpi_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	ret = ucsi_register(ua->ucsi);
+	ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ);
+	if (ret)
+		return ret;
+	version = le16_to_cpu(*(__le16 *)(ua->base + UCSI_VERSION));
+
+	ret = ucsi_register(ua->ucsi, version);
 	if (ret) {
 		acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev),
 					   ACPI_DEVICE_NOTIFY,
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index 709295948c65..d47f5e31c98a 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -1356,7 +1356,7 @@ static int ccg_restart(struct ucsi_ccg *uc)
 		return status;
 	}
 
-	status = ucsi_register(uc->ucsi);
+	status = ucsi_register(uc->ucsi, uc->ucsi->version);
 	if (status) {
 		dev_err(uc->dev, "failed to register the interface\n");
 		return status;
@@ -1422,6 +1422,7 @@ static int ucsi_ccg_probe(struct i2c_client *client)
 	struct ucsi_ccg *uc;
 	const char *fw_name;
 	int status;
+	__le16 version;
 
 	uc = devm_kzalloc(dev, sizeof(*uc), GFP_KERNEL);
 	if (!uc)
@@ -1477,7 +1478,14 @@ static int ucsi_ccg_probe(struct i2c_client *client)
 		goto out_ucsi_destroy;
 	}
 
-	status = ucsi_register(uc->ucsi);
+	status = ccg_read(uc, CCGX_RAB_UCSI_DATA_BLOCK(UCSI_VERSION),
+			  (u8 *)&version, sizeof(version));
+	if (status < 0) {
+		dev_err(uc->dev, "cannot read UCSI version - %d\n", status);
+		return status;
+	}
+
+	status = ucsi_register(uc->ucsi, le16_to_cpu(version));
 	if (status)
 		goto out_free_irq;
 
diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
index 0a0d08467c56..7a0b28536abd 100644
--- a/drivers/usb/typec/ucsi/ucsi_glink.c
+++ b/drivers/usb/typec/ucsi/ucsi_glink.c
@@ -255,8 +255,17 @@ static void pmic_glink_ucsi_notify(struct work_struct *work)
 static void pmic_glink_ucsi_register(struct work_struct *work)
 {
 	struct pmic_glink_ucsi *ucsi = container_of(work, struct pmic_glink_ucsi, register_work);
+	__le16 version;
+	int ret;
+
+	ret = pmic_glink_ucsi_read(ucsi->ucsi, UCSI_VERSION, &version,
+				   sizeof(version));
+	if (ret < 0) {
+		dev_err(ucsi->dev, "cannot read version: %d\n", ret);
+		return;
+	}
 
-	ucsi_register(ucsi->ucsi);
+	ucsi_register(ucsi->ucsi, le16_to_cpu(version));
 }
 
 static void pmic_glink_ucsi_callback(const void *data, size_t len, void *priv)
diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c
index 93d7806681cf..112692c7a158 100644
--- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c
+++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c
@@ -325,10 +325,10 @@ static int ucsi_stm32g0_fw_rcv(struct ucsi *ucsi, void *data, size_t len)
 	return ucsi_stm32g0_bl_rcv_woack(ucsi, data, len);
 }
 
-/* UCSI ops */
-static int ucsi_stm32g0_read(struct ucsi *ucsi, unsigned int offset, void *val, size_t len)
+static int ucsi_stm32g0_read_from_hw(struct ucsi_stm32g0 *g0,
+				     unsigned int offset,
+				     void *val, size_t len)
 {
-	struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
 	struct i2c_client *client = g0->client;
 	u8 reg = offset;
 	struct i2c_msg msg[] = {
@@ -357,6 +357,15 @@ static int ucsi_stm32g0_read(struct ucsi *ucsi, unsigned int offset, void *val,
 	return 0;
 }
 
+/* UCSI ops */
+static int ucsi_stm32g0_read(struct ucsi *ucsi, unsigned int offset,
+			     void *val, size_t len)
+{
+	struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
+
+	return ucsi_stm32g0_read_from_hw(g0, offset, val, len);
+}
+
 static int ucsi_stm32g0_async_write(struct ucsi *ucsi, unsigned int offset, const void *val,
 				    size_t len)
 {
@@ -445,6 +454,7 @@ static int ucsi_stm32g0_register(struct ucsi *ucsi)
 {
 	struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
 	struct i2c_client *client = g0->client;
+	__le16 version;
 	int ret;
 
 	/* Request alert interrupt */
@@ -455,7 +465,15 @@ static int ucsi_stm32g0_register(struct ucsi *ucsi)
 		return ret;
 	}
 
-	ret = ucsi_register(ucsi);
+	ret = ucsi_stm32g0_read_from_hw(g0, UCSI_VERSION, &version,
+					sizeof(version));
+	if (ret) {
+		dev_err(g0->dev, "failed to read version number: %d\n", ret);
+		free_irq(client->irq, g0);
+		return ret;
+	}
+
+	ret = ucsi_register(ucsi, le16_to_cpu(version));
 	if (ret) {
 		dev_err_probe(g0->dev, ret, "ucsi_register failed\n");
 		free_irq(client->irq, g0);
-- 
2.40.1



From lk at c--e.de  Sun Feb 18 14:20:35 2024
From: lk at c--e.de (Christian A. Ehrhardt)
Date: Sun, 18 Feb 2024 23:20:35 +0100
Subject: [RFC PATCH 2/6] ucsi_ccg: Cleanup endianness confusion
In-Reply-To: <20240218222039.822040-1-lk@c--e.de>
References: <20240218222039.822040-1-lk@c--e.de>
Message-ID: <20240218222039.822040-3-lk@c--e.de>

When storing the cci value in the op_region struct it is
converted from host to little endian. However, the value is
read from hardware that is little endian according to the spec
and it is never converted to host byte order. However, the
value is used as if it where in host byte order.

Additionally, the message_in buffer is a byte array.
Any endian interpretation depends on the current command and
must be done in the ocntext of that command.

While all the UCSI world seems to be little endian and there
are many other endian issues if this is not true, this
particular value is treated with endian awareness, so it should
at least be done correctly.

Add the missing conversion from little endian to host byte order
when reading the CCI value from hardware. Additionally, make the
message_in buffer an u8 array and adjust the size macro accordingly.

Signed-off-by: Christian A. Ehrhardt <lk at c--e.de>
---
 drivers/usb/typec/ucsi/ucsi_ccg.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index dda7c7c94e08..709295948c65 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -192,10 +192,10 @@ struct ucsi_ccg_altmode {
 	bool checked;
 } __packed;
 
-#define CCGX_MESSAGE_IN_MAX 4
+#define CCGX_MESSAGE_IN_MAX 16
 struct op_region {
 	__le32 cci;
-	__le32 message_in[CCGX_MESSAGE_IN_MAX];
+	u8 message_in[CCGX_MESSAGE_IN_MAX];
 };
 
 struct ucsi_ccg {
@@ -678,6 +678,7 @@ static irqreturn_t ccg_irq_handler(int irq, void *data)
 	u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(UCSI_CCI);
 	struct ucsi_ccg *uc = data;
 	u8 intr_reg;
+	__le32 __cci;
 	u32 cci = 0;
 	int ret = 0;
 
@@ -690,9 +691,10 @@ static irqreturn_t ccg_irq_handler(int irq, void *data)
 	else if (!(intr_reg & UCSI_READ_INT))
 		goto err_clear_irq;
 
-	ret = ccg_read(uc, reg, (void *)&cci, sizeof(cci));
+	ret = ccg_read(uc, reg, (void *)&__cci, sizeof(__cci));
 	if (ret)
 		goto err_clear_irq;
+	cci = le32_to_cpu(__cci);
 
 	if (UCSI_CCI_CONNECTOR(cci))
 		ucsi_connector_change(uc->ucsi, UCSI_CCI_CONNECTOR(cci));
-- 
2.40.1



From lk at c--e.de  Sun Feb 18 14:20:38 2024
From: lk at c--e.de (Christian A. Ehrhardt)
Date: Sun, 18 Feb 2024 23:20:38 +0100
Subject: [RFC PATCH 5/6] usb: typec: ucsi: Introdcue ->read_data and ->write_data
In-Reply-To: <20240218222039.822040-1-lk@c--e.de>
References: <20240218222039.822040-1-lk@c--e.de>
Message-ID: <20240218222039.822040-6-lk@c--e.de>

With the previous refactoring ->read() is only used to read
from UCSI_MESSAGE_IN. So rename ->read() to ->read_data().

Before this change there is (at least for some backends)
no way to write to UCSI_MESSAGE_OUT without starting a command.
As a result it is not possible to send a command with additional
data on these backends. Currently, the UCSI core does not send
such commands but they are defined in the spec and presumably
will be required.

Introduce ->write_data() to write to UCSI_MESSAGE_OUT without
starting a command. This is symmetrical to ->read_data().

Signed-off-by: Christian A. Ehrhardt <lk at c--e.de>
---
 drivers/usb/typec/ucsi/ucsi.c         |  6 ++---
 drivers/usb/typec/ucsi/ucsi.h         |  7 ++---
 drivers/usb/typec/ucsi/ucsi_acpi.c    | 21 +++++++++++----
 drivers/usb/typec/ucsi/ucsi_ccg.c     | 18 ++++++++-----
 drivers/usb/typec/ucsi/ucsi_glink.c   | 37 +++++++++++++++++----------
 drivers/usb/typec/ucsi/ucsi_stm32g0.c | 30 +++++++++++++++++-----
 6 files changed, 82 insertions(+), 37 deletions(-)

diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index a4ae3d5966a0..df3fe04cb9cd 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -46,7 +46,7 @@ static int ucsi_read_message_in(struct ucsi *ucsi, void *buf,
 	if (ucsi->version <= UCSI_VERSION_1_2)
 		buf_size = clamp(buf_size, 0, 16);
 
-	return ucsi->ops->read(ucsi, UCSI_MESSAGE_IN, buf, buf_size);
+	return ucsi->ops->read_data(ucsi, buf, buf_size);
 }
 
 static int ucsi_acknowledge_command(struct ucsi *ucsi)
@@ -1548,8 +1548,8 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)
 {
 	struct ucsi *ucsi;
 
-	if (!ops || !ops->poll_cci || !ops->read || !ops->sync_write ||
-	    !ops->async_write)
+	if (!ops || !ops->poll_cci || !ops->read_data || !ops->write_data ||
+	    !ops->sync_write || !ops->async_write)
 		return ERR_PTR(-EINVAL);
 
 	ucsi = kzalloc(sizeof(*ucsi), GFP_KERNEL);
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 55e5c5a09b32..2ad68124511b 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -56,7 +56,8 @@ struct dentry;
 /**
  * struct ucsi_operations - UCSI I/O operations
  * @poll_cci: Update the cached CCI value from hardware. Required for reset.
- * @read: Read operation
+ * @read_data: Read MESSAGE_IN data
+ * @write_data: Write MESSAGE_OUT data
  * @sync_write: Blocking write operation
  * @async_write: Non-blocking write operation
  * @update_altmodes: Squashes duplicate DP altmodes
@@ -67,8 +68,8 @@ struct dentry;
  */
 struct ucsi_operations {
 	int (*poll_cci)(struct ucsi *ucsi);
-	int (*read)(struct ucsi *ucsi, unsigned int offset,
-		    void *val, size_t val_len);
+	int (*read_data)(struct ucsi *ucsi, void *val, size_t val_len);
+	int (*write_data)(struct ucsi *ucsi, const void *val, size_t val_len);
 	int (*sync_write)(struct ucsi *ucsi, unsigned int offset,
 			  const void *val, size_t val_len);
 	int (*async_write)(struct ucsi *ucsi, unsigned int offset,
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
index 3aedfe78fb65..79b47b433e35 100644
--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
@@ -58,12 +58,21 @@ static int ucsi_acpi_poll_cci(struct ucsi *ucsi)
 	return 0;
 }
 
-static int ucsi_acpi_read(struct ucsi *ucsi, unsigned int offset,
-			  void *val, size_t val_len)
+static int ucsi_acpi_read_data(struct ucsi *ucsi, void *val, size_t val_len)
 {
 	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
 
-	memcpy(val, ua->base + offset, val_len);
+	memcpy(val, ua->base + UCSI_MESSAGE_IN, val_len);
+
+	return 0;
+}
+
+static int ucsi_acpi_write_data(struct ucsi *ucsi, const void *val,
+				size_t val_len)
+{
+	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
+
+	memcpy(ua->base + UCSI_MESSAGE_OUT, val, val_len);
 
 	return 0;
 }
@@ -108,7 +117,8 @@ static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset,
 
 static const struct ucsi_operations ucsi_acpi_ops = {
 	.poll_cci = ucsi_acpi_poll_cci,
-	.read = ucsi_acpi_read,
+	.read_data = ucsi_acpi_read_data,
+	.write_data = ucsi_acpi_write_data,
 	.sync_write = ucsi_acpi_sync_write,
 	.async_write = ucsi_acpi_async_write
 };
@@ -163,7 +173,8 @@ ucsi_dell_sync_write(struct ucsi *ucsi, unsigned int offset,
 
 static const struct ucsi_operations ucsi_dell_ops = {
 	.poll_cci = ucsi_acpi_poll_cci,
-	.read = ucsi_acpi_read,
+	.read_data = ucsi_acpi_read_data,
+	.write_data = ucsi_acpi_write_data,
 	.sync_write = ucsi_dell_sync_write,
 	.async_write = ucsi_acpi_async_write
 };
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index 55d0fe5324f4..d6026f61a0ed 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -559,16 +559,12 @@ static int ucsi_ccg_poll_cci(struct ucsi *ucsi)
 	return 0;
 }
 
-static int ucsi_ccg_read(struct ucsi *ucsi, unsigned int offset,
-			 void *val, size_t val_len)
+static int ucsi_ccg_read_data(struct ucsi *ucsi, void *val, size_t val_len)
 {
 	struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
 	struct ucsi_capability *cap;
 	struct ucsi_altmode *alt;
 
-	if (offset != UCSI_MESSAGE_IN)
-		return -EINVAL;
-
 	spin_lock(&uc->op_lock);
 	memcpy(val, &uc->op_data.message_in, val_len);
 	spin_unlock(&uc->op_lock);
@@ -600,6 +596,15 @@ static int ucsi_ccg_read(struct ucsi *ucsi, unsigned int offset,
 	return 0;
 }
 
+static int ucsi_ccg_write_data(struct ucsi *ucsi, const void *val,
+			       size_t val_len)
+{
+	struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
+	u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(UCSI_MESSAGE_OUT);
+
+	return ccg_write(uc, reg, val, val_len);
+}
+
 static int ucsi_ccg_async_write(struct ucsi *ucsi, unsigned int offset,
 				const void *val, size_t val_len)
 {
@@ -656,7 +661,8 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset,
 
 static const struct ucsi_operations ucsi_ccg_ops = {
 	.poll_cci = ucsi_ccg_poll_cci,
-	.read = ucsi_ccg_read,
+	.read_data = ucsi_ccg_read_data,
+	.write_data = ucsi_ccg_write_data,
 	.sync_write = ucsi_ccg_sync_write,
 	.async_write = ucsi_ccg_async_write,
 	.update_altmodes = ucsi_ccg_update_altmodes
diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
index d65ab81b4ed6..9dab1b428ad9 100644
--- a/drivers/usb/typec/ucsi/ucsi_glink.c
+++ b/drivers/usb/typec/ucsi/ucsi_glink.c
@@ -75,6 +75,7 @@ struct pmic_glink_ucsi {
 	struct work_struct register_work;
 
 	u8 read_buf[UCSI_BUF_SIZE];
+	u8 write_buf[UCSI_BUF_SIZE];
 };
 
 static int pmic_glink_sync_read_buf(struct pmic_glink_ucsi *ucsi)
@@ -129,18 +130,28 @@ static int pmic_glink_ucsi_poll_cci(struct ucsi *__ucsi)
 	return 0;
 }
 
-static int pmic_glink_ucsi_read(struct ucsi *__ucsi, unsigned int offset,
-				void *val, size_t val_len)
+static int pmic_glink_ucsi_read_data(struct ucsi *__ucsi,
+				     void *val, size_t val_len)
 {
 	struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
 
 	mutex_lock(&ucsi->lock);
-	memcpy(val, &ucsi->read_buf[offset], val_len);
+	memcpy(val, &ucsi->read_buf[UCSI_MESSAGE_IN], val_len);
 	mutex_unlock(&ucsi->lock);
 
 	return 0;
 }
 
+static int pmic_glink_ucsi_write_data(struct ucsi *__ucsi,
+				      const void *val, size_t val_len)
+{
+	struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
+
+	memcpy(&ucsi->write_buf[UCSI_MESSAGE_OUT], val, val_len);
+
+	return 0;
+}
+
 static int pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi *ucsi, unsigned int offset,
 					const void *val, size_t val_len)
 {
@@ -148,10 +159,15 @@ static int pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi *ucsi, unsigned i
 	unsigned long left;
 	int ret;
 
+	if (offset != UCSI_CONTROL || val_len != sizeof(u64))
+		return -EINVAL;
+	memcpy(ucsi->write_buf + UCSI_CONTROL, val, val_len);
+
 	req.hdr.owner = cpu_to_le32(PMIC_GLINK_OWNER_USBC);
 	req.hdr.type = cpu_to_le32(MSG_TYPE_REQ_RESP);
 	req.hdr.opcode = cpu_to_le32(UC_UCSI_WRITE_BUF_REQ);
-	memcpy(&req.buf[offset], val, val_len);
+	memcpy(req.buf, ucsi->write_buf, UCSI_BUF_SIZE);
+	memset(ucsi->write_buf, 0, sizeof(ucsi->write_buf));
 
 	reinit_completion(&ucsi->write_ack);
 
@@ -214,7 +230,8 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset,
 
 static const struct ucsi_operations pmic_glink_ucsi_ops = {
 	.poll_cci = pmic_glink_ucsi_poll_cci,
-	.read = pmic_glink_ucsi_read,
+	.read_data = pmic_glink_ucsi_read_data,
+	.write_data = pmic_glink_ucsi_write_data,
 	.sync_write = pmic_glink_ucsi_sync_write,
 	.async_write = pmic_glink_ucsi_async_write
 };
@@ -286,7 +303,6 @@ static void pmic_glink_ucsi_notify(struct work_struct *work)
 static void pmic_glink_ucsi_register(struct work_struct *work)
 {
 	struct pmic_glink_ucsi *ucsi = container_of(work, struct pmic_glink_ucsi, register_work);
-	__le16 version;
 	int ret;
 
 	ret = pmic_glink_sync_read_buf(ucsi);
@@ -294,14 +310,9 @@ static void pmic_glink_ucsi_register(struct work_struct *work)
 		dev_err(ucsi->dev, "cannot sync read buf: %d\n", ret);
 		return;
 	}
-	ret = pmic_glink_ucsi_read(ucsi->ucsi, UCSI_VERSION, &version,
-				   sizeof(version));
-	if (ret < 0) {
-		dev_err(ucsi->dev, "cannot read version: %d\n", ret);
-		return;
-	}
 
-	ucsi_register(ucsi->ucsi, le16_to_cpu(version));
+	ucsi_register(ucsi->ucsi,
+		      le16_to_cpu(*(__le16 *)(ucsi->read_buf + UCSI_VERSION)));
 }
 
 static void pmic_glink_ucsi_callback(const void *data, size_t len, void *priv)
diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c
index bab2363b73f4..d68aca118e41 100644
--- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c
+++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c
@@ -372,18 +372,17 @@ static int ucsi_stm32g0_poll_cci(struct ucsi *ucsi)
 	return 0;
 }
 
-static int ucsi_stm32g0_read(struct ucsi *ucsi, unsigned int offset,
-			     void *val, size_t len)
+static int ucsi_stm32g0_read_data(struct ucsi *ucsi, void *val, size_t len)
 {
 	struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
 
-	return ucsi_stm32g0_read_from_hw(g0, offset, val, len);
+	return ucsi_stm32g0_read_from_hw(g0, UCSI_MESSAGE_IN, val, len);
 }
 
-static int ucsi_stm32g0_async_write(struct ucsi *ucsi, unsigned int offset, const void *val,
-				    size_t len)
+static int ucsi_stm32g0_write_to_hw(struct ucsi_stm32g0 *g0,
+				    unsigned int offset,
+				    const void *val, size_t len)
 {
-	struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
 	struct i2c_client *client = g0->client;
 	struct i2c_msg msg[] = {
 		{
@@ -414,6 +413,22 @@ static int ucsi_stm32g0_async_write(struct ucsi *ucsi, unsigned int offset, cons
 	return 0;
 }
 
+static int ucsi_stm32g0_write_data(struct ucsi *ucsi,
+				   const void *val, size_t len)
+{
+	struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
+
+	return ucsi_stm32g0_write_to_hw(g0, UCSI_MESSAGE_OUT, val, len);
+}
+
+static int ucsi_stm32g0_async_write(struct ucsi *ucsi, unsigned int offset,
+				    const void *val, size_t len)
+{
+	struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
+
+	return ucsi_stm32g0_write_to_hw(g0, offset, val, len);
+}
+
 static int ucsi_stm32g0_sync_write(struct ucsi *ucsi, unsigned int offset, const void *val,
 				   size_t len)
 {
@@ -463,7 +478,8 @@ static irqreturn_t ucsi_stm32g0_irq_handler(int irq, void *data)
 
 static const struct ucsi_operations ucsi_stm32g0_ops = {
 	.poll_cci = ucsi_stm32g0_poll_cci,
-	.read = ucsi_stm32g0_read,
+	.read_data = ucsi_stm32g0_read_data,
+	.write_data = ucsi_stm32g0_write_data,
 	.sync_write = ucsi_stm32g0_sync_write,
 	.async_write = ucsi_stm32g0_async_write,
 };
-- 
2.40.1



From lk at c--e.de  Sun Feb 18 14:20:37 2024
From: lk at c--e.de (Christian A. Ehrhardt)
Date: Sun, 18 Feb 2024 23:20:37 +0100
Subject: [RFC PATCH 4/6] usb: typec: ucsi: Cache current CCI value in struct ucsi
In-Reply-To: <20240218222039.822040-1-lk@c--e.de>
References: <20240218222039.822040-1-lk@c--e.de>
Message-ID: <20240218222039.822040-5-lk@c--e.de>

All notification handlers already read the CCI value.
Reading it again from hardware in ucsi_execute_command()
opens races and it is not clear that this really works.
The zenbook quirk in ucsi_acpi.c is one case where a re-read
causes problems.

In the ACPI case it is not even necessary to sync the
mailbox memory. According to the intel whitepaper the
ACPI handler does this before it notifies the OS.
Thus simply read the CCI value in the notification handler
without any ACPI method calls.

During reset of the PPM, it may be necessary to poll UCSI_CCI
from hardware as the reset completion may not send a notification.
Provide a new ->poll_cci API function that actively updates the
CCI value from hardware for this case.

While there take into account that the raw CCI value read
from hardware is little endian and convert it to host byte
order explicitly.

Signed-off-by: Christian A. Ehrhardt <lk at c--e.de>
---
 drivers/usb/typec/ucsi/ucsi.c         | 11 +++---
 drivers/usb/typec/ucsi/ucsi.h         |  5 +++
 drivers/usb/typec/ucsi/ucsi_acpi.c    | 53 ++++++++-------------------
 drivers/usb/typec/ucsi/ucsi_ccg.c     | 38 +++++++------------
 drivers/usb/typec/ucsi/ucsi_glink.c   | 48 +++++++++++++++++++++---
 drivers/usb/typec/ucsi/ucsi_stm32g0.c | 22 ++++++++++-
 6 files changed, 101 insertions(+), 76 deletions(-)

diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index eb630447ba80..a4ae3d5966a0 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -140,10 +140,7 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd)
 	ret = ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
 	if (ret)
 		return ret;
-
-	ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci));
-	if (ret)
-		return ret;
+	cci = READ_ONCE(ucsi->cci);
 
 	if (cmd != UCSI_CANCEL && cci & UCSI_CCI_BUSY)
 		return ucsi_exec_command(ucsi, UCSI_CANCEL);
@@ -1037,9 +1034,10 @@ static int ucsi_reset_ppm(struct ucsi *ucsi)
 			goto out;
 		}
 
-		ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci));
+		ret = ucsi->ops->poll_cci(ucsi);
 		if (ret)
 			goto out;
+		cci = READ_ONCE(ucsi->cci);
 
 		/* If the PPM is still doing something else, reset it again. */
 		if (cci & ~UCSI_CCI_RESET_COMPLETE) {
@@ -1550,7 +1548,8 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)
 {
 	struct ucsi *ucsi;
 
-	if (!ops || !ops->read || !ops->sync_write || !ops->async_write)
+	if (!ops || !ops->poll_cci || !ops->read || !ops->sync_write ||
+	    !ops->async_write)
 		return ERR_PTR(-EINVAL);
 
 	ucsi = kzalloc(sizeof(*ucsi), GFP_KERNEL);
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 100e16b49814..55e5c5a09b32 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -55,6 +55,7 @@ struct dentry;
 
 /**
  * struct ucsi_operations - UCSI I/O operations
+ * @poll_cci: Update the cached CCI value from hardware. Required for reset.
  * @read: Read operation
  * @sync_write: Blocking write operation
  * @async_write: Non-blocking write operation
@@ -65,6 +66,7 @@ struct dentry;
  * return immediately after sending the data to the PPM.
  */
 struct ucsi_operations {
+	int (*poll_cci)(struct ucsi *ucsi);
 	int (*read)(struct ucsi *ucsi, unsigned int offset,
 		    void *val, size_t val_len);
 	int (*sync_write)(struct ucsi *ucsi, unsigned int offset,
@@ -371,6 +373,9 @@ struct ucsi {
 	/* The latest "Notification Enable" bits (SET_NOTIFICATION_ENABLE) */
 	u64 ntfy;
 
+	/* The current value of the CCI field. Synced by notifications. */
+	u32 cci;
+
 	/* PPM communication flags */
 	unsigned long flags;
 #define EVENT_PENDING	0
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
index 710ddfc03ed0..3aedfe78fb65 100644
--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
@@ -24,7 +24,6 @@ struct ucsi_acpi {
 	struct completion complete;
 	unsigned long flags;
 	guid_t guid;
-	u64 cmd;
 	bool dell_quirk_probed;
 	bool dell_quirk_active;
 };
@@ -45,8 +44,7 @@ static int ucsi_acpi_dsm(struct ucsi_acpi *ua, int func)
 	return 0;
 }
 
-static int ucsi_acpi_read(struct ucsi *ucsi, unsigned int offset,
-			  void *val, size_t val_len)
+static int ucsi_acpi_poll_cci(struct ucsi *ucsi)
 {
 	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
 	int ret;
@@ -55,6 +53,16 @@ static int ucsi_acpi_read(struct ucsi *ucsi, unsigned int offset,
 	if (ret)
 		return ret;
 
+	WRITE_ONCE(ucsi->cci, le32_to_cpu(*(__le32 *)(ua->base + UCSI_CCI)));
+
+	return 0;
+}
+
+static int ucsi_acpi_read(struct ucsi *ucsi, unsigned int offset,
+			  void *val, size_t val_len)
+{
+	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
+
 	memcpy(val, ua->base + offset, val_len);
 
 	return 0;
@@ -66,7 +74,6 @@ static int ucsi_acpi_async_write(struct ucsi *ucsi, unsigned int offset,
 	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
 
 	memcpy(ua->base + offset, val, val_len);
-	ua->cmd = *(u64 *)val;
 
 	return ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_WRITE);
 }
@@ -100,34 +107,12 @@ static int ucsi_acpi_sync_write(struct ucsi *ucsi, unsigned int offset,
 }
 
 static const struct ucsi_operations ucsi_acpi_ops = {
+	.poll_cci = ucsi_acpi_poll_cci,
 	.read = ucsi_acpi_read,
 	.sync_write = ucsi_acpi_sync_write,
 	.async_write = ucsi_acpi_async_write
 };
 
-static int
-ucsi_zenbook_read(struct ucsi *ucsi, unsigned int offset, void *val, size_t val_len)
-{
-	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
-	int ret;
-
-	if (offset == UCSI_VERSION || UCSI_COMMAND(ua->cmd) == UCSI_PPM_RESET) {
-		ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ);
-		if (ret)
-			return ret;
-	}
-
-	memcpy(val, ua->base + offset, val_len);
-
-	return 0;
-}
-
-static const struct ucsi_operations ucsi_zenbook_ops = {
-	.read = ucsi_zenbook_read,
-	.sync_write = ucsi_acpi_sync_write,
-	.async_write = ucsi_acpi_async_write
-};
-
 /*
  * Some Dell laptops expect that an ACK command with the
  * UCSI_ACK_CONNECTOR_CHANGE bit set is followed by a (separate)
@@ -177,19 +162,13 @@ ucsi_dell_sync_write(struct ucsi *ucsi, unsigned int offset,
 }
 
 static const struct ucsi_operations ucsi_dell_ops = {
+	.poll_cci = ucsi_acpi_poll_cci,
 	.read = ucsi_acpi_read,
 	.sync_write = ucsi_dell_sync_write,
 	.async_write = ucsi_acpi_async_write
 };
 
 static const struct dmi_system_id ucsi_acpi_quirks[] = {
-	{
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
-		},
-		.driver_data = (void *)&ucsi_zenbook_ops,
-	},
 	{
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
@@ -203,11 +182,9 @@ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data)
 {
 	struct ucsi_acpi *ua = data;
 	u32 cci;
-	int ret;
 
-	ret = ua->ucsi->ops->read(ua->ucsi, UCSI_CCI, &cci, sizeof(cci));
-	if (ret)
-		return;
+	cci = le32_to_cpu(*(__le32 *)(ua->base + UCSI_CCI));
+	WRITE_ONCE(ua->ucsi->cci, cci);
 
 	if (UCSI_CCI_CONNECTOR(cci))
 		ucsi_connector_change(ua->ucsi, UCSI_CCI_CONNECTOR(cci));
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index d47f5e31c98a..55d0fe5324f4 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -194,7 +194,6 @@ struct ucsi_ccg_altmode {
 
 #define CCGX_MESSAGE_IN_MAX 16
 struct op_region {
-	__le32 cci;
 	u8 message_in[CCGX_MESSAGE_IN_MAX];
 };
 
@@ -338,7 +337,6 @@ static int ccg_op_region_update(struct ucsi_ccg *uc, u32 cci)
 	}
 
 	spin_lock(&uc->op_lock);
-	data->cci = cpu_to_le32(cci);
 	if (UCSI_CCI_LENGTH(cci))
 		memcpy(&data->message_in, buf, size);
 	spin_unlock(&uc->op_lock);
@@ -556,32 +554,24 @@ static void ucsi_ccg_nvidia_altmode(struct ucsi_ccg *uc,
 	}
 }
 
+static int ucsi_ccg_poll_cci(struct ucsi *ucsi)
+{
+	return 0;
+}
+
 static int ucsi_ccg_read(struct ucsi *ucsi, unsigned int offset,
 			 void *val, size_t val_len)
 {
 	struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
-	u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(offset);
 	struct ucsi_capability *cap;
 	struct ucsi_altmode *alt;
-	int ret = 0;
-
-	if (offset == UCSI_CCI) {
-		spin_lock(&uc->op_lock);
-		memcpy(val, &(uc->op_data).cci, val_len);
-		spin_unlock(&uc->op_lock);
-	} else if (offset == UCSI_MESSAGE_IN) {
-		spin_lock(&uc->op_lock);
-		memcpy(val, &(uc->op_data).message_in, val_len);
-		spin_unlock(&uc->op_lock);
-	} else {
-		ret = ccg_read(uc, reg, val, val_len);
-	}
-
-	if (ret)
-		return ret;
 
 	if (offset != UCSI_MESSAGE_IN)
-		return ret;
+		return -EINVAL;
+
+	spin_lock(&uc->op_lock);
+	memcpy(val, &uc->op_data.message_in, val_len);
+	spin_unlock(&uc->op_lock);
 
 	switch (UCSI_COMMAND(uc->last_cmd_sent)) {
 	case UCSI_GET_CURRENT_CAM:
@@ -607,7 +597,7 @@ static int ucsi_ccg_read(struct ucsi *ucsi, unsigned int offset,
 	}
 	uc->last_cmd_sent = 0;
 
-	return ret;
+	return 0;
 }
 
 static int ucsi_ccg_async_write(struct ucsi *ucsi, unsigned int offset,
@@ -620,9 +610,7 @@ static int ucsi_ccg_async_write(struct ucsi *ucsi, unsigned int offset,
 	 * UCSI may read CCI instantly after async_write,
 	 * clear CCI to avoid caller getting wrong data before we get CCI from ISR
 	 */
-	spin_lock(&uc->op_lock);
-	uc->op_data.cci = 0;
-	spin_unlock(&uc->op_lock);
+	WRITE_ONCE(ucsi->cci, 0);
 
 	return ccg_write(uc, reg, val, val_len);
 }
@@ -667,6 +655,7 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset,
 }
 
 static const struct ucsi_operations ucsi_ccg_ops = {
+	.poll_cci = ucsi_ccg_poll_cci,
 	.read = ucsi_ccg_read,
 	.sync_write = ucsi_ccg_sync_write,
 	.async_write = ucsi_ccg_async_write,
@@ -695,6 +684,7 @@ static irqreturn_t ccg_irq_handler(int irq, void *data)
 	if (ret)
 		goto err_clear_irq;
 	cci = le32_to_cpu(__cci);
+	WRITE_ONCE(uc->ucsi->cci, cci);
 
 	if (UCSI_CCI_CONNECTOR(cci))
 		ucsi_connector_change(uc->ucsi, UCSI_CCI_CONNECTOR(cci));
diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
index 7a0b28536abd..d65ab81b4ed6 100644
--- a/drivers/usb/typec/ucsi/ucsi_glink.c
+++ b/drivers/usb/typec/ucsi/ucsi_glink.c
@@ -77,10 +77,8 @@ struct pmic_glink_ucsi {
 	u8 read_buf[UCSI_BUF_SIZE];
 };
 
-static int pmic_glink_ucsi_read(struct ucsi *__ucsi, unsigned int offset,
-				void *val, size_t val_len)
+static int pmic_glink_sync_read_buf(struct pmic_glink_ucsi *ucsi)
 {
-	struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
 	struct ucsi_read_buf_req_msg req = {};
 	unsigned long left;
 	int ret;
@@ -106,7 +104,6 @@ static int pmic_glink_ucsi_read(struct ucsi *__ucsi, unsigned int offset,
 		goto out_unlock;
 	}
 
-	memcpy(val, &ucsi->read_buf[offset], val_len);
 	ret = 0;
 
 out_unlock:
@@ -115,6 +112,35 @@ static int pmic_glink_ucsi_read(struct ucsi *__ucsi, unsigned int offset,
 	return ret;
 }
 
+static int pmic_glink_ucsi_poll_cci(struct ucsi *__ucsi)
+{
+	struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
+	int ret;
+
+	ret = pmic_glink_sync_read_buf(ucsi);
+	if (ret)
+		return ret;
+
+	mutex_lock(&ucsi->lock);
+	WRITE_ONCE(__ucsi->cci,
+		   le32_to_cpu(*(__le32 *)&ucsi->read_buf[UCSI_CCI]));
+	mutex_unlock(&ucsi->lock);
+
+	return 0;
+}
+
+static int pmic_glink_ucsi_read(struct ucsi *__ucsi, unsigned int offset,
+				void *val, size_t val_len)
+{
+	struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
+
+	mutex_lock(&ucsi->lock);
+	memcpy(val, &ucsi->read_buf[offset], val_len);
+	mutex_unlock(&ucsi->lock);
+
+	return 0;
+}
+
 static int pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi *ucsi, unsigned int offset,
 					const void *val, size_t val_len)
 {
@@ -187,6 +213,7 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset,
 }
 
 static const struct ucsi_operations pmic_glink_ucsi_ops = {
+	.poll_cci = pmic_glink_ucsi_poll_cci,
 	.read = pmic_glink_ucsi_read,
 	.sync_write = pmic_glink_ucsi_sync_write,
 	.async_write = pmic_glink_ucsi_async_write
@@ -221,11 +248,15 @@ static void pmic_glink_ucsi_notify(struct work_struct *work)
 	u32 cci;
 	int ret;
 
-	ret = pmic_glink_ucsi_read(ucsi->ucsi, UCSI_CCI, &cci, sizeof(cci));
+	ret = pmic_glink_sync_read_buf(ucsi);
 	if (ret) {
-		dev_err(ucsi->dev, "failed to read CCI on notification\n");
+		dev_err(ucsi->dev, "failed to sync read buf\n");
 		return;
 	}
+	mutex_lock(&ucsi->lock);
+	cci = le32_to_cpu(*(__le32 *)&ucsi->read_buf[UCSI_CCI]);
+	mutex_unlock(&ucsi->lock);
+	WRITE_ONCE(ucsi->ucsi->cci, cci);
 
 	con_num = UCSI_CCI_CONNECTOR(cci);
 	if (con_num) {
@@ -258,6 +289,11 @@ static void pmic_glink_ucsi_register(struct work_struct *work)
 	__le16 version;
 	int ret;
 
+	ret = pmic_glink_sync_read_buf(ucsi);
+	if (ret < 0) {
+		dev_err(ucsi->dev, "cannot sync read buf: %d\n", ret);
+		return;
+	}
 	ret = pmic_glink_ucsi_read(ucsi->ucsi, UCSI_VERSION, &version,
 				   sizeof(version));
 	if (ret < 0) {
diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c
index 112692c7a158..bab2363b73f4 100644
--- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c
+++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c
@@ -358,6 +358,20 @@ static int ucsi_stm32g0_read_from_hw(struct ucsi_stm32g0 *g0,
 }
 
 /* UCSI ops */
+static int ucsi_stm32g0_poll_cci(struct ucsi *ucsi)
+{
+	struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi);
+	__le32 cci;
+	int ret;
+
+	ret = ucsi_stm32g0_read_from_hw(g0, UCSI_CCI, &cci, sizeof(cci));
+	if (ret)
+		return ret;
+	WRITE_ONCE(ucsi->cci, le32_to_cpu(cci));
+
+	return 0;
+}
+
 static int ucsi_stm32g0_read(struct ucsi *ucsi, unsigned int offset,
 			     void *val, size_t len)
 {
@@ -424,15 +438,18 @@ static int ucsi_stm32g0_sync_write(struct ucsi *ucsi, unsigned int offset, const
 static irqreturn_t ucsi_stm32g0_irq_handler(int irq, void *data)
 {
 	struct ucsi_stm32g0 *g0 = data;
+	__le32 __cci;
 	u32 cci;
 	int ret;
 
 	if (g0->suspended)
 		g0->wakeup_event = true;
 
-	ret = ucsi_stm32g0_read(g0->ucsi, UCSI_CCI, &cci, sizeof(cci));
+	ret = ucsi_stm32g0_read_from_hw(g0, UCSI_CCI, &__cci, sizeof(__cci));
 	if (ret)
 		return IRQ_NONE;
+	cci = le32_to_cpu(__cci);
+	WRITE_ONCE(g0->ucsi->cci, cci);
 
 	if (UCSI_CCI_CONNECTOR(cci))
 		ucsi_connector_change(g0->ucsi, UCSI_CCI_CONNECTOR(cci));
@@ -445,6 +462,7 @@ static irqreturn_t ucsi_stm32g0_irq_handler(int irq, void *data)
 }
 
 static const struct ucsi_operations ucsi_stm32g0_ops = {
+	.poll_cci = ucsi_stm32g0_poll_cci,
 	.read = ucsi_stm32g0_read,
 	.sync_write = ucsi_stm32g0_sync_write,
 	.async_write = ucsi_stm32g0_async_write,
@@ -626,7 +644,7 @@ static int ucsi_stm32g0_probe_bootloader(struct ucsi *ucsi)
 	 * Try to guess if the STM32G0 is running a UCSI firmware. First probe the UCSI FW at its
 	 * i2c address. Fallback to bootloader i2c address only if firmware-name is specified.
 	 */
-	ret = ucsi_stm32g0_read(ucsi, UCSI_VERSION, &ucsi_version, sizeof(ucsi_version));
+	ret = ucsi_stm32g0_read_from_hw(g0, UCSI_VERSION, &ucsi_version, sizeof(ucsi_version));
 	if (!ret || !g0->fw_name)
 		return ret;
 
-- 
2.40.1



From lk at c--e.de  Sun Feb 18 14:20:33 2024
From: lk at c--e.de (Christian A. Ehrhardt)
Date: Sun, 18 Feb 2024 23:20:33 +0100
Subject: [RFC PATCH 0/6] UCSI backend API refactoring
Message-ID: <20240218222039.822040-1-lk@c--e.de>

The (new) API for UCSI backends has some problems:

The UCSI spec assumes a mailbox style communication:
1. The OPM fills data (UCSI_MESSAGE_OUT and UCSI_CONTROL)
   into the mailbox memory region. In the ACPI case these are
   simple host memory accesses.
2. The OPM notifies the PPM that a command should be executed.
   In the ACPI case this is a call the _DSM ACPI function.
   Within that function the UCSI_CONTROL and the UCSI_MESSAGE_OUT
   data is transferred to something like the embedded controller
   and then the PPM is notified e.g. by an SMI.
3. The PPM executes the command. As a result UCSI_MESSAGE_IN and
   UCSI_CCI in the mailbox memory are updated and the OPM
   is notified. In the ACPI case the notification is an SCI and
   ACPI provides a handler that syncs UCSI_MESSAGE_IN and
   UCSI_CCI from the EC into host memory before notifying the
   OPM via the ACPI Notify() command.

The major problem is that steps 1 (update mailbox memory) and
step 2 (notify PPM and start command execution) are two different
steps. The current API only knows about a write function that
combines writing to mailbox memory and starting command execution.

This only works as long as the commands do not have arguments
that must be in UCSI_MESSAGE_OUT.

Additionally, Step 3 (at least in the ACPI case) above suggests
that UCSI_CCI and UCSI_MESSAGE_IN should generally be read from
mailbox memory. Except for some special cases the sync operation
via the _DSM-Read function in ACPI is not required and seems to
do more harm then good.

E.g. the zenbook quirks could be avoided if we didn't re-read the
UCSI_CCI and UCSI_MESSAGE_IN data from the embedded controller
on each read operation. The recent fix to the CCG backend seems
to address the same issue.

This change series proposes a new API with the following design
goals:
- Retain the nice features of the previous API redesign. In
  particular the synchronous execution of commands in the
  backend and the ability to handle quirks there.
- The API must still be able to handle all backends (obviously).
  Thus each new API function is currently implemented in all
  backends in the same change.
- Separate writing to mailbox data and starting command execution
  to allow for commands with UCSI_MESSAGE_OUT data.
- Avoid hardware accesses (as opposed to mailbox memory accesses)
  outside of the command execution context as much as possible.
- Avoid use of explicit mailbox offsets (that are subject to
  change with later UCSI revisions) in the UCSI core.

The proposed new API features:
- read_data() and write_data() for access to the message data
  fields. This is supposed to be a pure mailbox access that
  even in the case of a write does not start a command.
- sync_cmd() and async_cmd() to write the command register and
  start command execution.
- A cached version of the current contents of CCI in the core
  UCSI structure. This value is only updated if a notification
  is received from the hardware.
- poll_cci() to force an update of the cached CCI value from
  hardware. This is required to poll for PPM reset completion.

CAVEATs:
- The series will certainly need more polishing etc. before
  it can be accepted. I will do this provided that the series
  is considered a good idea in general.
- The series compiles, passes smatch, sparse and checkpatch but
  I only have ucsi_acpi hardware to test this. The other backends
  (ccg, glink, stm32g0) will need testers and likely some fixes
  as well.

So, what do you think?

Christian A. Ehrhardt (6):
  usb: ucsi_glink: Fix endianness issues
  ucsi_ccg: Cleanup endianness confusion
  usb: typec: ucsi: Make Version a parameter to ucsi_register
  usb: typec: ucsi: Cache current CCI value in struct ucsi
  usb: typec: ucsi: Introdcue ->read_data and ->write_data
  usb: typec: ucsi: Convert a?sync_write to a?sync_cmd

 drivers/usb/typec/ucsi/ucsi.c         |  53 ++++--------
 drivers/usb/typec/ucsi/ucsi.h         |  28 +++---
 drivers/usb/typec/ucsi/ucsi_acpi.c    | 119 ++++++++++++--------------
 drivers/usb/typec/ucsi/ucsi_ccg.c     | 107 ++++++++++++-----------
 drivers/usb/typec/ucsi/ucsi_glink.c   | 104 +++++++++++++++++-----
 drivers/usb/typec/ucsi/ucsi_stm32g0.c |  80 ++++++++++++++---
 6 files changed, 290 insertions(+), 201 deletions(-)

-- 
2.40.1



From lk at c--e.de  Sun Feb 18 14:20:34 2024
From: lk at c--e.de (Christian A. Ehrhardt)
Date: Sun, 18 Feb 2024 23:20:34 +0100
Subject: [RFC PATCH 1/6] usb: ucsi_glink: Fix endianness issues
In-Reply-To: <20240218222039.822040-1-lk@c--e.de>
References: <20240218222039.822040-1-lk@c--e.de>
Message-ID: <20240218222039.822040-2-lk@c--e.de>

Sparse complains that some little endian header fields
are assigned from plain integer values.

Add the proper cpu_to_le32() calls.

Signed-off-by: Christian A. Ehrhardt <lk at c--e.de>
---
 drivers/usb/typec/ucsi/ucsi_glink.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
index 0bd3f6dee678..0a0d08467c56 100644
--- a/drivers/usb/typec/ucsi/ucsi_glink.c
+++ b/drivers/usb/typec/ucsi/ucsi_glink.c
@@ -85,9 +85,9 @@ static int pmic_glink_ucsi_read(struct ucsi *__ucsi, unsigned int offset,
 	unsigned long left;
 	int ret;
 
-	req.hdr.owner = PMIC_GLINK_OWNER_USBC;
-	req.hdr.type = MSG_TYPE_REQ_RESP;
-	req.hdr.opcode = UC_UCSI_READ_BUF_REQ;
+	req.hdr.owner = cpu_to_le32(PMIC_GLINK_OWNER_USBC);
+	req.hdr.type = cpu_to_le32(MSG_TYPE_REQ_RESP);
+	req.hdr.opcode = cpu_to_le32(UC_UCSI_READ_BUF_REQ);
 
 	mutex_lock(&ucsi->lock);
 	memset(ucsi->read_buf, 0, sizeof(ucsi->read_buf));
@@ -122,9 +122,9 @@ static int pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi *ucsi, unsigned i
 	unsigned long left;
 	int ret;
 
-	req.hdr.owner = PMIC_GLINK_OWNER_USBC;
-	req.hdr.type = MSG_TYPE_REQ_RESP;
-	req.hdr.opcode = UC_UCSI_WRITE_BUF_REQ;
+	req.hdr.owner = cpu_to_le32(PMIC_GLINK_OWNER_USBC);
+	req.hdr.type = cpu_to_le32(MSG_TYPE_REQ_RESP);
+	req.hdr.opcode = cpu_to_le32(UC_UCSI_WRITE_BUF_REQ);
 	memcpy(&req.buf[offset], val, val_len);
 
 	reinit_completion(&ucsi->write_ack);
-- 
2.40.1



From alexandre.belloni at bootlin.com  Sun Feb 18 14:57:19 2024
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Sun, 18 Feb 2024 23:57:19 +0100
Subject: (subset) [PATCH 1/3] dt-bindings: i3c: drop "master" node name
 suffix
In-Reply-To: <20240117075618.81932-1-krzysztof.kozlowski@linaro.org>
References: <20240117075618.81932-1-krzysztof.kozlowski@linaro.org>
Message-ID: <170829700336.822203.177392854952786485.b4-ty@bootlin.com>

On Wed, 17 Jan 2024 08:56:16 +0100, Krzysztof Kozlowski wrote:
> Drop the requirement of "-master" suffix in node names because:
> 1. "Master" word is discouraged and MIPI Alliance renamed it to
>    "Controller".
> 2. Some devices can operate in Controller (Master) or Target mode, thus
>    the name is not accurate in such cases.
> 3. Other buses, like I2C controllers, use simple "i2c".
> 
> [...]

Applied, thanks!

[1/3] dt-bindings: i3c: drop "master" node name suffix
      https://git.kernel.org/abelloni/c/c53611f2e27a

Best regards,

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From daniel.lezcano at linaro.org  Sun Feb 18 14:59:07 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Sun, 18 Feb 2024 23:59:07 +0100
Subject: [PATCH v1 1/2] clocksource/drivers/arm_global_timer: Fix maximum
 prescaler value
In-Reply-To: <20240218174138.1942418-2-martin.blumenstingl@googlemail.com>
References: <20240218174138.1942418-1-martin.blumenstingl@googlemail.com>
 <20240218174138.1942418-2-martin.blumenstingl@googlemail.com>
Message-ID: <ec0b3dfb-3ce2-43f2-9cd4-042c3aca4cf7@linaro.org>

On 18/02/2024 18:41, Martin Blumenstingl wrote:
> The prescaler in the "Global Timer Control Register bit assignments" is
> documented to use bits [15:8], which means that the maximum prescaler
> register value is 0xff.
> 
> Fixes: 171b45a4a70e ("clocksource/drivers/arm_global_timer: Implement rate compensation whenever source clock changes")
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---
>   drivers/clocksource/arm_global_timer.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
> index 44a61dc6f932..e1c773bb5535 100644
> --- a/drivers/clocksource/arm_global_timer.c
> +++ b/drivers/clocksource/arm_global_timer.c
> @@ -32,7 +32,7 @@
>   #define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
>   #define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
>   #define GT_CONTROL_PRESCALER_SHIFT      8
> -#define GT_CONTROL_PRESCALER_MAX        0xF
> +#define GT_CONTROL_PRESCALER_MAX        0xFF
>   #define GT_CONTROL_PRESCALER_MASK       (GT_CONTROL_PRESCALER_MAX << \
>   					 GT_CONTROL_PRESCALER_SHIFT

Good catch!

IMO the initial confusion is coming from the shift and the mask size.

But should GT_CONTROL_PRESCALER_MAX be 256 ? so (0xFF + 1)

The following may be less confusing:

#define GT_CONTROL_PRESCALER_SHIFT	8
#define GT_CONTROL_PRESCALER_MASK	GENMASK(15,8)
#define GT_CONTROL_PRESCALER_MAX	(GT_CONTROL_PRESCALER_MASK >> \
					 GT_CONTROL_PRESCALER_SHIFT) + 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 martin.blumenstingl at googlemail.com  Sun Feb 18 15:18:53 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Mon, 19 Feb 2024 00:18:53 +0100
Subject: [PATCH v1 1/2] clocksource/drivers/arm_global_timer: Fix maximum
 prescaler value
In-Reply-To: <ec0b3dfb-3ce2-43f2-9cd4-042c3aca4cf7@linaro.org>
References: <20240218174138.1942418-1-martin.blumenstingl@googlemail.com>
 <20240218174138.1942418-2-martin.blumenstingl@googlemail.com> <ec0b3dfb-3ce2-43f2-9cd4-042c3aca4cf7@linaro.org>
Message-ID: <CAFBinCC0BbahEMeW9CYC+hKk0CBQ9a+CqNrOv3c92D8hDtQHdQ@mail.gmail.com>

Hi Daniel,

On Sun, Feb 18, 2024 at 11:59?PM Daniel Lezcano
<daniel.lezcano at linaro.org> wrote:
[...]
> >   #define GT_CONTROL_PRESCALER_SHIFT      8
> > -#define GT_CONTROL_PRESCALER_MAX        0xF
> > +#define GT_CONTROL_PRESCALER_MAX        0xFF
> >   #define GT_CONTROL_PRESCALER_MASK       (GT_CONTROL_PRESCALER_MAX << \
> >                                        GT_CONTROL_PRESCALER_SHIFT
>
> Good catch!
>
> IMO the initial confusion is coming from the shift and the mask size.
>
> But should GT_CONTROL_PRESCALER_MAX be 256 ? so (0xFF + 1)
It depends on what we consider "max" to be:
- the register value
- the actual number that's used in the calculation formula

If we ignore the usage of GT_CONTROL_PRESCALER_MAX within
GT_CONTROL_PRESCALER_MASK then there's only one occurrence left, which
decrements the calculated value right before comparing it against
GT_CONTROL_PRESCALER_MAX.
This means: the remaining driver currently considers
GT_CONTROL_PRESCALER_MAX to be the maximum value that can be written
to the register, having converted the value from the calculation
formula to register value beforehand.

> The following may be less confusing:
>
> #define GT_CONTROL_PRESCALER_SHIFT      8
> #define GT_CONTROL_PRESCALER_MASK       GENMASK(15,8)
> #define GT_CONTROL_PRESCALER_MAX        (GT_CONTROL_PRESCALER_MASK >> \
>                                          GT_CONTROL_PRESCALER_SHIFT) + 1
If you're interested then I'll work on a follow-up patch to clean up
the prescaler macros (using FIELD_PREP, FIELD_GET and GENMASK would
simplify things IMO).
I think that this patch is still good as-is since it's small and can
be backported easily (if someone wants to do that).


Best regards,
Martin


From daniel.lezcano at linaro.org  Sun Feb 18 15:48:37 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 19 Feb 2024 00:48:37 +0100
Subject: [PATCH v1 1/2] clocksource/drivers/arm_global_timer: Fix maximum
 prescaler value
In-Reply-To: <CAFBinCC0BbahEMeW9CYC+hKk0CBQ9a+CqNrOv3c92D8hDtQHdQ@mail.gmail.com>
References: <20240218174138.1942418-1-martin.blumenstingl@googlemail.com>
 <20240218174138.1942418-2-martin.blumenstingl@googlemail.com>
 <ec0b3dfb-3ce2-43f2-9cd4-042c3aca4cf7@linaro.org>
 <CAFBinCC0BbahEMeW9CYC+hKk0CBQ9a+CqNrOv3c92D8hDtQHdQ@mail.gmail.com>
Message-ID: <5f6229ac-1390-41b5-af91-53799641d3b2@linaro.org>

On 19/02/2024 00:18, Martin Blumenstingl wrote:
> Hi Daniel,
> 
> On Sun, Feb 18, 2024 at 11:59?PM Daniel Lezcano
> <daniel.lezcano at linaro.org> wrote:
> [...]
>>>    #define GT_CONTROL_PRESCALER_SHIFT      8
>>> -#define GT_CONTROL_PRESCALER_MAX        0xF
>>> +#define GT_CONTROL_PRESCALER_MAX        0xFF
>>>    #define GT_CONTROL_PRESCALER_MASK       (GT_CONTROL_PRESCALER_MAX << \
>>>                                         GT_CONTROL_PRESCALER_SHIFT
>>
>> Good catch!
>>
>> IMO the initial confusion is coming from the shift and the mask size.
>>
>> But should GT_CONTROL_PRESCALER_MAX be 256 ? so (0xFF + 1)
> It depends on what we consider "max" to be:
> - the register value
> - the actual number that's used in the calculation formula
> 
> If we ignore the usage of GT_CONTROL_PRESCALER_MAX within
> GT_CONTROL_PRESCALER_MASK then there's only one occurrence left, which
> decrements the calculated value right before comparing it against
> GT_CONTROL_PRESCALER_MAX.
> This means: the remaining driver currently considers
> GT_CONTROL_PRESCALER_MAX to be the maximum value that can be written
> to the register, having converted the value from the calculation
> formula to register value beforehand.
> 
>> The following may be less confusing:
>>
>> #define GT_CONTROL_PRESCALER_SHIFT      8
>> #define GT_CONTROL_PRESCALER_MASK       GENMASK(15,8)
>> #define GT_CONTROL_PRESCALER_MAX        (GT_CONTROL_PRESCALER_MASK >> \
>>                                           GT_CONTROL_PRESCALER_SHIFT) + 1
> If you're interested then I'll work on a follow-up patch to clean up
> the prescaler macros (using FIELD_PREP, FIELD_GET and GENMASK would
> simplify things IMO).

Yes, cleanups are welcome

> I think that this patch is still good as-is since it's small and can
> be backported easily (if someone wants to do that).

Ok, I'm fine with that


-- 
<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 peng.fan at nxp.com  Sun Feb 18 17:03:29 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 19 Feb 2024 01:03:29 +0000
Subject: [PATCH] clk: constify the of_phandle_args argument of
 of_clk_provider
In-Reply-To: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
References: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
Message-ID: <DU0PR04MB9417F8D996A661CAA9E542FE88512@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: [PATCH] clk: constify the of_phandle_args argument of
> of_clk_provider
> 
> None of the implementations of the get() and get_hw() callbacks of "struct
> of_clk_provider" modify the contents of received of_phandle_args pointer.
> They treat it as read-only variable used to find the clock to return.  Make
> obvious that implementations are not supposed to modify the
> of_phandle_args, by making it a pointer to const.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

For i.MX:
Acked-by: Peng Fan <peng.fan at nxp.com>

Regards,
Peng.


From sre at kernel.org  Sun Feb 18 17:59:26 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Mon, 19 Feb 2024 02:59:26 +0100
Subject: [PATCH v3 02/16] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <e3b54b1c-79ab-4f25-8b42-fadc922c0d25@linaro.org>
References: <20240216223654.1312880-1-sre@kernel.org>
 <20240216223654.1312880-3-sre@kernel.org>
 <e3b54b1c-79ab-4f25-8b42-fadc922c0d25@linaro.org>
Message-ID: <znyqirhcxfigmenthyrkpivraj43g23gbbx2e774uy3oc375dd@c6pmvckv3gjs>

Hi Krzysztof,

On Sat, Feb 17, 2024 at 09:39:52AM +0100, Krzysztof Kozlowski wrote:
> On 16/02/2024 23:34, Sebastian Reichel wrote:
> > +properties:
> > +  reg: true
> 
> Your pattern in weim schema suggests you have here minItems: 2.
> maxItems: can be 2 or 255.

Which part suggests minItems: 2?

It's minItems: 1 with each item consisting of two address cells and
one size cell. Most in-tree users actually have exactly one item.
The only exception seems to be arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts,
which has "davicom,dm9000" using two reg items. Considering this is an
external bus, any number is possible in theory. Should I keep it as is,
or use minItems: 1, maxItems: 255 instead?

-- Sebastian
-------------- 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/20240219/3475a090/attachment.sig>

From aford173 at gmail.com  Sun Feb 18 18:09:01 2024
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 18 Feb 2024 20:09:01 -0600
Subject: [PATCH] media: rkisp1: Allow higher input resolution
In-Reply-To: <pftafukuzq7qzbhlvwtmeg3mburnttylgy4246timlghtrdgx4@r6munvmj6oqt>
References: <20240217185202.1754750-1-megi@xff.cz> <20240218205908.GA12766@pendragon.ideasonboard.com>
 <pftafukuzq7qzbhlvwtmeg3mburnttylgy4246timlghtrdgx4@r6munvmj6oqt>
Message-ID: <CAHCN7x+zi3WxnY-mxZFKePs1cS=-DprEmh_CnypJ4XK7xBzjMQ@mail.gmail.com>

On Sun, Feb 18, 2024 at 3:02?PM Ond?ej Jirman <megi at xff.cz> wrote:
>
> On Sun, Feb 18, 2024 at 10:59:08PM +0200, Laurent Pinchart wrote:
> > Hi Ondrej,
> >
> > (CC'ing Paul and Umang)
> >
> > Thank you for the patch.
> >
> > On Sat, Feb 17, 2024 at 07:51:58PM +0100, Ond?ej Jirman wrote:
> > > From: Ondrej Jirman <megi at xff.cz>
> > >
> > > In BSP driver, it is allowed, and it works in practice. Tested on
> > > Pinephone Pro/RK3399 with IMX258 at full res.
> >
> > Paul, Umang, do I recall correctly that you have a similar change ?
> > Could you review and test this (especially on the i.MX8MP) ?
>
> It's also a limit from the datasheet, so the change should not be that
> controversial:
>
>   https://megous.com/dl/tmp/d2b333043ecebaf3.png
>
> (so that it doesn't sound like I just copied the BSP values)
>

>From what I see in the i.MX8M Plus reference manual, it has a max
resolution of 4096x3072, so it might be necessary to move this off
from a #define into a structure that varies by product family.

adam
> regards,
>         o.
>
> > > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > > ---
> > >  drivers/media/platform/rockchip/rkisp1/rkisp1-common.h | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > index 4b6b28c05b89..74098ddbeeb3 100644
> > > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > @@ -33,8 +33,8 @@ struct dentry;
> > >  #define RKISP1_ISP_SD_SINK                 BIT(1)
> > >
> > >  /* min and max values for the widths and heights of the entities */
> > > -#define RKISP1_ISP_MAX_WIDTH                       4032
> > > -#define RKISP1_ISP_MAX_HEIGHT                      3024
> > > +#define RKISP1_ISP_MAX_WIDTH                       4416
> > > +#define RKISP1_ISP_MAX_HEIGHT                      3312
> > >  #define RKISP1_ISP_MIN_WIDTH                       32
> > >  #define RKISP1_ISP_MIN_HEIGHT                      32
> > >
> >
> > --
> > Regards,
> >
> > Laurent Pinchart
>


From Shawn.Sung at mediatek.com  Sun Feb 18 18:06:19 2024
From: Shawn.Sung at mediatek.com (=?utf-8?B?U2hhd24gU3VuZyAo5a6L5a2d6KyZKQ==?=)
Date: Mon, 19 Feb 2024 02:06:19 +0000
Subject: [PATCH v5 10/13] drm/mediatek: Support CRC in display driver
In-Reply-To: <Zc-Vq2MeG9X37JJe@phenom.ffwll.local>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
	 <20240215101119.12629-11-shawn.sung@mediatek.com>
	 <Zc-Vq2MeG9X37JJe@phenom.ffwll.local>
Message-ID: <3e21e3ac5d8b0002305b7081d3222f190cc317f7.camel@mediatek.com>

Hi Daniel,

On Fri, 2024-02-16 at 18:04 +0100, Daniel Vetter wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  On Thu, Feb 15, 2024 at 06:11:16PM +0800, Hsiao Chien Sung wrote:
> > Register CRC related function pointers to support
> > CRC retrieval.
> > 
> > Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 239
> ++++++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |  39 ++++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   3 +
> >  3 files changed, 281 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index 14cf75fa217f9..6cb1ed419dee7 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -68,6 +68,9 @@ struct mtk_drm_crtc {
> >  /* lock for display hardware access */
> >  struct mutexhw_lock;
> >  boolconfig_updating;
> > +
> > +struct mtk_ddp_comp*crc_provider;
> > +unsigned intframes;
> >  };
> >  
> >  struct mtk_crtc_state {
> > @@ -635,6 +638,14 @@ static void mtk_crtc_ddp_irq(void *data)
> >  struct drm_crtc *crtc = data;
> >  struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> >  struct mtk_drm_private *priv = crtc->dev->dev_private;
> > +struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
> > +
> > +/*
> > + * crc providers should make sure the crc is always correct
> > + * by resetting it in .crc_read()
> > + */
> > +if (crtc->crc.opened)
> > +comp->funcs->crc_read(comp->dev);
> >  
> >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> >  if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
> > @@ -646,6 +657,24 @@ static void mtk_crtc_ddp_irq(void *data)
> >  if (!priv->data->shadow_register)
> >  mtk_crtc_ddp_config(crtc, NULL);
> >  #endif
> > +
> > +/*
> > + * drm_crtc_add_crc_entry() could take more than 50ms to finish
> > + * put it at the end of the isr
> > + */
> 
> Uh this looks really scary, especially since you put this before the
> call
> to drm_crtc_handle_vblank in the function below, which really
> shouldn't be
> unecessarily delayed (because that's the one that takes the vblank
> timestamp).

Thank you for pointing this out. This kind of expensive works should be
deferred to the bottom halve instead of in the interrupt context. This
is indeed an issue that was originally to be solved in a future
version, but since it may take some time to adjust the flow and verifiy
it, I fixed other minor issues and pushed this version so the reviewers
could check it first. Will resolve this problem in the next version.

> 
> This sounds like the perfect application for a vblank worker though,
> so
> you please look into drm_vblank_work.h. And if that is not useable
> due to
> hardware constraint, then please explain in a comment here and in the
> commit message why you cannot use that and have to roll your own.
> vblank
> work really should be your first choice here, because:
> - it's designed for expensive vblank work
> - it gives you all the flush/cancel_sync functions you need for
> disabling
>   crc again, and in a race-free implementation. Much better to use
> common
>   code than to reinvent synchronization wheels in drivers :-)
> 
> > +if (crtc->crc.opened) {
> 
> Because this is probably not race-free, so we need something solid
> here.

Thank you very much for the hint :)
Didn't know there is such a useful
tool in DRM.
Will try to integrate the CRC function with
drm_vblank_work.

Cheers, Sima
> 

From Shawn.Sung at mediatek.com  Sun Feb 18 18:28:38 2024
From: Shawn.Sung at mediatek.com (=?utf-8?B?U2hhd24gU3VuZyAo5a6L5a2d6KyZKQ==?=)
Date: Mon, 19 Feb 2024 02:28:38 +0000
Subject: [PATCH v5 10/13] drm/mediatek: Support CRC in display driver
In-Reply-To: <Zc-YtaJV1-EMiJoC@phenom.ffwll.local>
References: <20240215101119.12629-1-shawn.sung@mediatek.com>
	 <20240215101119.12629-11-shawn.sung@mediatek.com>
	 <Zc-Vq2MeG9X37JJe@phenom.ffwll.local> <Zc-YtaJV1-EMiJoC@phenom.ffwll.local>
Message-ID: <574c4d570ea4c1c7170ce7e0652c342b8ccbb5af.camel@mediatek.com>

Hi Daniel,

On Fri, 2024-02-16 at 18:17 +0100, Daniel Vetter wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  On Fri, Feb 16, 2024 at 06:04:43PM +0100, Daniel Vetter wrote:
> > On Thu, Feb 15, 2024 at 06:11:16PM +0800, Hsiao Chien Sung wrote:
> > > Register CRC related function pointers to support
> > > CRC retrieval.
> > > 
> > > Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.com>
> > > ---
> > >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 239
> ++++++++++++++++++++
> > >  drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |  39 ++++
> > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   3 +
> > >  3 files changed, 281 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > index 14cf75fa217f9..6cb1ed419dee7 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > > @@ -68,6 +68,9 @@ struct mtk_drm_crtc {
> > >  /* lock for display hardware access */
> > >  struct mutexhw_lock;
> > >  boolconfig_updating;
> > > +
> > > +struct mtk_ddp_comp*crc_provider;
> > > +unsigned intframes;
> > >  };
> > >  
> > >  struct mtk_crtc_state {
> > > @@ -635,6 +638,14 @@ static void mtk_crtc_ddp_irq(void *data)
> > >  struct drm_crtc *crtc = data;
> > >  struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> > >  struct mtk_drm_private *priv = crtc->dev->dev_private;
> > > +struct mtk_ddp_comp *comp = mtk_crtc->crc_provider;
> > > +
> > > +/*
> > > + * crc providers should make sure the crc is always correct
> > > + * by resetting it in .crc_read()
> > > + */
> > > +if (crtc->crc.opened)
> > > +comp->funcs->crc_read(comp->dev);
> > >  
> > >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > >  if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
> > > @@ -646,6 +657,24 @@ static void mtk_crtc_ddp_irq(void *data)
> > >  if (!priv->data->shadow_register)
> > >  mtk_crtc_ddp_config(crtc, NULL);
> > >  #endif
> > > +
> > > +/*
> > > + * drm_crtc_add_crc_entry() could take more than 50ms to finish
> > > + * put it at the end of the isr
> > > + */
> > 
> > Uh this looks really scary, especially since you put this before
> the call
> > to drm_crtc_handle_vblank in the function below, which really
> shouldn't be
> > unecessarily delayed (because that's the one that takes the vblank
> > timestamp).
> > 
> > This sounds like the perfect application for a vblank worker
> though, so
> > you please look into drm_vblank_work.h. And if that is not useable
> due to
> > hardware constraint, then please explain in a comment here and in
> the
> > commit message why you cannot use that and have to roll your own.
> vblank
> > work really should be your first choice here, because:
> > - it's designed for expensive vblank work
> > - it gives you all the flush/cancel_sync functions you need for
> disabling
> >   crc again, and in a race-free implementation. Much better to use
> common
> >   code than to reinvent synchronization wheels in drivers :-)
> > 
> > > +if (crtc->crc.opened) {
> > 
> > Because this is probably not race-free, so we need something solid
> here.
> 
> Since it's maybe a bit tricky to see how to use drm_vblank_work:
> 
> - in your crtc initialization you also need to setup the crc work
> with
>   drm_vblank_work_init().
> - Your mtk_drm_crtc_set_sourc needs to actually enable the crc by
> calling
>   drm_vblank_work_schedule for current vblank + 1, so that it
> immediately
>   starts
> - your vblank worker itself needs to again re-arm itself with
>   drm_vblank_work_schedule, again for the very next vblank
> - then your set_source also needs to handle the case where you
> disable the
>   crc again (source == NULL) by calling drm_vblank_work_cancel_sync
> - also you probably need to call drm_vblank_work_flush when shutting
> down
>   the crtc, or you might have use-after-free issues on driver unload.
>   Could probably also just put that in your crtc release function.
> 
> No changes to your interrupt handler needed, and also definitely no
> digging around in drm_crtc->crc data structure without locking -
> that's
> entirely internal to the common crc code and drivers must never look
> into it.
> 

I am deeply appreciative for the information you have shared. Will try
to implement it with DRM_vblank_work APIs.

Sincerely,
Shawn

From anshuman.khandual at arm.com  Sun Feb 18 18:52:33 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 19 Feb 2024 08:22:33 +0530
Subject: [PATCH V4 05/11] coresight: replicator: Move ACPI support from
 AMBA driver to platform driver
In-Reply-To: <b0c8b92e-53bc-4232-a748-ff3e6b94b112@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-6-anshuman.khandual@arm.com>
 <b72c54bf-17a8-453c-8fbb-fbc90abdb45a@arm.com>
 <b0c8b92e-53bc-4232-a748-ff3e6b94b112@arm.com>
Message-ID: <ff8cbe8c-c56e-4e04-8d89-040d2ba2fd0e@arm.com>



On 2/15/24 16:55, Suzuki K Poulose wrote:
> On 15/02/2024 11:23, Suzuki K Poulose wrote:
>> Hi Anshuman
>>
>> On 23/01/2024 05:46, Anshuman Khandual wrote:
>>> Add support for the dynamic replicator device in the platform driver, which
>>> can then be used on ACPI based platforms. This change would now allow
>>> runtime power management for repliacator devices on ACPI based systems.
>>>
>>> The driver would try to enable the APB clock if available. Also, rename the
>>> code to reflect the fact that it now handles both static and dynamic
>>> replicators.
>>>
>>> Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
>>> Cc: Sudeep Holla <sudeep.holla at arm.com>
>>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>>> Cc: Mike Leach <mike.leach at linaro.org>
>>> Cc: James Clark <james.clark at arm.com>
>>> Cc: linux-acpi at vger.kernel.org
>>> Cc: linux-arm-kernel at lists.infradead.org
>>> Cc: linux-kernel at vger.kernel.org
>>> Cc: coresight at lists.linaro.org
>>> Tested-by: Sudeep Holla <sudeep.holla at arm.com> # Boot and driver probe only
>>> Acked-by: Sudeep Holla <sudeep.holla at arm.com> # For ACPI related changes
>>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>>
>> I think the patch is doing three different things:
>>
>> 1) Use new helper to register/remove AMBA/Platform drivers
>> 2) Refactor replicator_probe() to make sure it can be reused for platform/amba driver, by moving the pm_runtime_put() to the callers.
>> 3) Actually moving the ACPI driver to Platform driver
>>
>> While (1) and (3) are obvious, (2) gave me hard time to review this
>> patch, without proper description. If you don't mind, are you able to
>> split the patch and add proper description of the 3 changes mentioned
>> above.
>>
> 
> You could even move (1) for all the existing drivers into a single patch
> or even fold it with the patch that introduces the helpers. That way it

There are only two existing coresight devices with both AMBA and platform
drivers available i.e replicator and funnel. Such devices could use these
new helpers right from the beginning. As you mentioned earlier such changes
might be folded back into the patch adding the helpers.

But coresight devices such as catu, tpiu, tmc, stm and debug don't have
platform drivers to begin with. Hence the helpers could only be used in
their respective patches adding platform drivers.

> is cleaner and easier to review. And (2) & (3) could be in the same patch for each driver, but please add something in the description for (2).

Please find the updated commit message here, does this look okay ?

    coresight: replicator: Move ACPI support from AMBA driver to platform driver

    Add support for the dynamic replicator device in the platform driver, which
    can then be used on ACPI based platforms. This change would now allow
    runtime power management for replicator devices on ACPI based systems.

    The driver would try to enable the APB clock if available. Also, rename the
    code to reflect the fact that it now handles both static and dynamic
    replicators. But first this refactors replicator_probe() making sure it can
    be used both for platform and AMBA drivers, by moving the pm_runtime_put()
    to the callers.


From andy.yan at rock-chips.com  Sun Feb 18 19:02:01 2024
From: andy.yan at rock-chips.com (Andy Yan)
Date: Mon, 19 Feb 2024 11:02:01 +0800
Subject: [PATCH] drm: rockchip: Don't require MIPI DSI device when it's
 used for ISP
In-Reply-To: <bsc3lpdxvhy3ss2uja4do3jwvj43zbs7zhx4bzs2tryrakn7be@pt2qsyvryk73>
References: <20240217183941.1752463-1-megi@xff.cz>
 <4c66c084-5af6-43fb-a256-4746b2e00192@rock-chips.com>
 <bsc3lpdxvhy3ss2uja4do3jwvj43zbs7zhx4bzs2tryrakn7be@pt2qsyvryk73>
Message-ID: <7044f324-5a45-4a4c-a15e-86614e53acf0@rock-chips.com>

Hi Ondrej:

On 2/18/24 23:17, Ond?ej Jirman wrote:
> Hi Andy,
> 
> On Sun, Feb 18, 2024 at 07:14:56PM +0800, Andy Yan wrote:
>> Hi,
>>
>> On 2/18/24 02:39, Ond?ej Jirman wrote:
>>> From: Ondrej Jirman <megi at xff.cz>
>>>
>>> On RK3399 one MIPI DSI device can be alternatively used with the ISP1,
>>> to provide RX DPHY. When this is the case (ISP1 is enabled in device
>>> tree), probe success of DRM is tied to probe success of ISP1 connected
>>> camera sensor. This can fail if the user is able to killswitch the camera
>>> power, like on Pinephone Pro.
>>>
>>> Detect use of MIPI DSI controller by ISP, and don't include it in
>>> component match list in that case.
>>>
>>
>> Isn't this supposed to be taken care of within the dts?
>> Since DPHY1 should exclusively used by MIPI DSI1 and ISP1, then if
>> a device want to use ISP1, the DSI1 should be disabled in dts.
> 
> DSI1 can't be disabled, because it provides PHY device for ISP1 in this
> scenario.
> 
> The problem is that in this scenario DRM keeps waiting for DSI1 device,
> despite it just being used for PHY for ISP1 and not as a component for
> rockchip DRM driver.


Oh, get it.
With a quick look, seems that Heiko has already take this scenario into consideration
when add PHY function in the dsi drivers[0]
Does this mean the current drivers does not work as expected?

[0]https://patchwork.freedesktop.org/patch/420386/
> 
> See:
> 
>          isp1: isp1 at ff920000 {
>                  compatible = "rockchip,rk3399-cif-isp";
>                  reg = <0x0 0xff920000 0x0 0x4000>;
>                  interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH 0>;
>                  clocks = <&cru SCLK_ISP1>,
>                           <&cru ACLK_ISP1_WRAPPER>,
>                           <&cru HCLK_ISP1_WRAPPER>;
>                  clock-names = "isp", "aclk", "hclk";
>                  iommus = <&isp1_mmu>;
>                  phys = <&mipi_dsi1>;  <---------
>                  phy-names = "dphy";
>                  power-domains = <&power RK3399_PD_ISP1>;
>                  status = "disabled";
> 
> If mipi_dsi1 is disabled, isp1 will never probe.
> 
> It's a consequence of this special dual use of mipi_dsi1.
> 
> kind regards,
> 	o.
> 
>>> Signed-off-by: Ondrej Jirman <megi at xff.cz>
>>> ---
>>>    drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 47 +++++++++++++++++++++
>>>    1 file changed, 47 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>>> index ab55d7132550..f47de94ad576 100644
>>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
>>> @@ -354,6 +354,43 @@ static void rockchip_drm_match_remove(struct device *dev)
>>>    		device_link_del(link);
>>>    }
>>> +/*
>>> + * Check if ISP block linked to a mipi-dsi device via phys phandle is
>>> + * enabled in device tree.
>>> + */
>>> +static bool rockchip_drm_is_mipi1_and_used_by_isp(struct device *dev)
>>> +{
>>> +	struct device_node *np = NULL, *phy_np;
>>> +
>>> +	if (!of_device_is_compatible(dev->of_node, "rockchip,rk3399-mipi-dsi"))
>>> +		return false;
>>> +
>>> +	while (true) {
>>> +		np = of_find_compatible_node(np, NULL, "rockchip,rk3399-cif-isp");
>>> +		if (!np)
>>> +			break;
>>> +
>>> +		if (!of_device_is_available(np)) {
>>> +			of_node_put(np);
>>> +			continue;
>>> +		}
>>> +
>>> +		phy_np = of_parse_phandle(np, "phys", 0);
>>> +		if (!phy_np) {
>>> +			of_node_put(np);
>>> +			continue;
>>> +		}
>>> +
>>> +		of_node_put(phy_np);
>>> +		of_node_put(np);
>>> +
>>> +		if (phy_np == dev->of_node)
>>> +			return true;
>>> +	}
>>> +
>>> +	return false;
>>> +}
>>> +
>>>    static struct component_match *rockchip_drm_match_add(struct device *dev)
>>>    {
>>>    	struct component_match *match = NULL;
>>> @@ -371,6 +408,16 @@ static struct component_match *rockchip_drm_match_add(struct device *dev)
>>>    			if (!d)
>>>    				break;
>>> +			/*
>>> +			 * If mipi1 is connected to ISP, we don't want to wait for mipi1 component,
>>> +			 * because it will not be used by DRM anyway, to not tie success of camera
>>> +			 * driver probe to display pipeline initialization.
>>> +			 */
>>> +			if (rockchip_drm_is_mipi1_and_used_by_isp(d)) {
>>> +				dev_info(d, "used by ISP1, skipping from DRM\n");
>>> +				continue;
>>> +			}
>>> +
>>>    			device_link_add(dev, d, DL_FLAG_STATELESS);
>>>    			component_match_add(dev, &match, component_compare_dev, d);
>>>    		} while (true);


From jcalvinowens at gmail.com  Sun Feb 18 20:09:06 2024
From: jcalvinowens at gmail.com (Calvin Owens)
Date: Sun, 18 Feb 2024 20:09:06 -0800
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
Message-ID: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>

32-bit arm builds uniquely emit a lot of spam like this:

    fs/bcachefs/backpointers.c: In function ?extent_matches_bp?:
    fs/bcachefs/backpointers.c:15:13: note: parameter passing for argument of type ?struct bch_backpointer? changed in GCC 9.1

Apply the arm64 change from commit ebcc5928c5d9 ("arm64: Silence gcc
warnings about arch ABI drift") to silence them. It seems like Dave's
original rationale applies here too.

Cc: Dave Martin <Dave.Martin at arm.com>
Signed-off-by: Calvin Owens <jcalvinowens at gmail.com>
---
 arch/arm/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 473280d5adce..184a5a2c7756 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -28,6 +28,9 @@ KBUILD_CFLAGS	+= $(call cc-option,-mno-fdpic)
 # This should work on most of the modern platforms
 KBUILD_DEFCONFIG := multi_v7_defconfig
 
+# Silence "note: xyz changed in GCC X.X" messages
+KBUILD_CFLAGS	+= $(call cc-disable-warning, psabi)
+
 # defines filename extension depending memory management type.
 ifeq ($(CONFIG_MMU),)
 MMUEXT		:= -nommu
-- 
2.43.0



From apatel at ventanamicro.com  Sun Feb 18 20:10:35 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 19 Feb 2024 09:40:35 +0530
Subject: [PATCH v12 19/25] irqchip/riscv-imsic: Add device MSI domain
 support for platform devices
In-Reply-To: <87eddccgo7.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-20-apatel@ventanamicro.com> <87eddccgo7.ffs@tglx>
Message-ID: <CAK9=C2VK-sOtyhxnDH83WwMNQbetC-zLssZdYG399pBghU+yUw@mail.gmail.com>

On Sat, Feb 17, 2024 at 1:42?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> > +static int imsic_cpu_page_phys(unsigned int cpu,
> > +                            unsigned int guest_index,
> > +                            phys_addr_t *out_msi_pa)
> > +{
> > +     struct imsic_global_config *global;
> > +     struct imsic_local_config *local;
> > +
> > +     global = &imsic->global;
> > +     local = per_cpu_ptr(global->local, cpu);
> > +
> > +     if (BIT(global->guest_index_bits) <= guest_index)
> > +             return -EINVAL;
>
> As the callsite does not care about the return value, just make this
> function boolean and return true on success.

Okay, I will update.

>
> > +     if (out_msi_pa)
> > +             *out_msi_pa = local->msi_pa +
> > +                           (guest_index * IMSIC_MMIO_PAGE_SZ);
> > +
> > +     return 0;
> > +}
> > +
> > +static void imsic_irq_mask(struct irq_data *d)
> > +{
> > +     imsic_vector_mask(irq_data_get_irq_chip_data(d));
> > +}
> > +
> > +static void imsic_irq_unmask(struct irq_data *d)
> > +{
> > +     imsic_vector_unmask(irq_data_get_irq_chip_data(d));
> > +}
> > +
> > +static int imsic_irq_retrigger(struct irq_data *d)
> > +{
> > +     struct imsic_vector *vec = irq_data_get_irq_chip_data(d);
> > +     struct imsic_local_config *local;
> > +
> > +     if (WARN_ON(vec == NULL))
> > +             return -ENOENT;
> > +
> > +     local = per_cpu_ptr(imsic->global.local, vec->cpu);
> > +     writel(vec->local_id, local->msi_va);
> > +     return 0;
> > +}
> > +
> > +static void imsic_irq_compose_vector_msg(struct imsic_vector *vec,
> > +                                      struct msi_msg *msg)
> > +{
> > +     phys_addr_t msi_addr;
> > +     int err;
> > +
> > +     if (WARN_ON(vec == NULL))
> > +             return;
> > +
> > +     err = imsic_cpu_page_phys(vec->cpu, 0, &msi_addr);
> > +     if (WARN_ON(err))
> > +             return;
>
>         if (WARN_ON(!imsic_cpu_page_phys(...)))
>                 return
> Hmm?

Okay, I will update like you suggested.

>
> > +
> > +     msg->address_hi = upper_32_bits(msi_addr);
> > +     msg->address_lo = lower_32_bits(msi_addr);
> > +     msg->data = vec->local_id;
> > +}
> > +
> > +static void imsic_irq_compose_msg(struct irq_data *d, struct msi_msg *msg)
> > +{
> > +     imsic_irq_compose_vector_msg(irq_data_get_irq_chip_data(d), msg);
> > +}
> > +
> > +#ifdef CONFIG_SMP
> > +static void imsic_msi_update_msg(struct irq_data *d, struct imsic_vector *vec)
> > +{
> > +     struct msi_msg msg[2] = { [1] = { }, };
> > +
> > +     imsic_irq_compose_vector_msg(vec, msg);
> > +     irq_data_get_irq_chip(d)->irq_write_msi_msg(d, msg);
> > +}
> > +
> > +static int imsic_irq_set_affinity(struct irq_data *d,
> > +                               const struct cpumask *mask_val,
> > +                               bool force)
> > +{
> > +     struct imsic_vector *old_vec, *new_vec;
> > +     struct irq_data *pd = d->parent_data;
> > +
> > +     old_vec = irq_data_get_irq_chip_data(pd);
> > +     if (WARN_ON(old_vec == NULL))
> > +             return -ENOENT;
> > +
> > +     /* Get a new vector on the desired set of CPUs */
> > +     new_vec = imsic_vector_alloc(old_vec->hwirq, mask_val);
> > +     if (!new_vec)
> > +             return -ENOSPC;
> > +
> > +     /* If old vector belongs to the desired CPU then do nothing */
> > +     if (old_vec->cpu == new_vec->cpu) {
> > +             imsic_vector_free(new_vec);
> > +             return IRQ_SET_MASK_OK_DONE;
> > +     }
>
> You can spare that exercise by checking it before the allocation:
>
>         if (cpumask_test_cpu(old_vec->cpu, mask_val))
>                 return IRQ_SET_MASK_OK_DONE;

Okay, I will update.

>
> > +
> > +     /* Point device to the new vector */
> > +     imsic_msi_update_msg(d, new_vec);
>
> > +static int imsic_irq_domain_alloc(struct irq_domain *domain,
> > +                               unsigned int virq, unsigned int nr_irqs,
> > +                               void *args)
> > +{
> > +     struct imsic_vector *vec;
> > +     int hwirq;
> > +
> > +     /* Legacy-MSI or multi-MSI not supported yet. */
>
> What's legacy MSI in that context?

The legacy-MSI is the MSI support in PCI v2.2 where
number of MSIs allocated by device were either 1, 2, 4,
8, 16, or 32 and the data written is <data_word> + <irqnum>.

>
> > +     if (nr_irqs > 1)
> > +             return -ENOTSUPP;
> > +
> > +     hwirq = imsic_hwirq_alloc();
> > +     if (hwirq < 0)
> > +             return hwirq;
> > +
> > +     vec = imsic_vector_alloc(hwirq, cpu_online_mask);
> > +     if (!vec) {
> > +             imsic_hwirq_free(hwirq);
> > +             return -ENOSPC;
> > +     }
> > +
> > +     irq_domain_set_info(domain, virq, hwirq,
> > +                         &imsic_irq_base_chip, vec,
> > +                         handle_simple_irq, NULL, NULL);
> > +     irq_set_noprobe(virq);
> > +     irq_set_affinity(virq, cpu_online_mask);
> > +
> > +     /*
> > +      * IMSIC does not implement irq_disable() so Linux interrupt
> > +      * subsystem will take a lazy approach for disabling an IMSIC
> > +      * interrupt. This means IMSIC interrupts are left unmasked
> > +      * upon system suspend and interrupts are not processed
> > +      * immediately upon system wake up. To tackle this, we disable
> > +      * the lazy approach for all IMSIC interrupts.
>
> Why? Lazy works perfectly fine even w/o an irq_disable() callback.

This was suggested by SiFive folks. I am also not sure why we
need this. For now, I will drop this and bring it back as a separate
patch if required.

>
> > +      */
> > +     irq_set_status_flags(virq, IRQ_DISABLE_UNLAZY);
>
> > +
> > +#define MATCH_PLATFORM_MSI           BIT(DOMAIN_BUS_PLATFORM_MSI)
>
> You really love macro indirections :)

This is to be consistent with MATCH_PCI_MSI introduced by the
subsequent patch.

Also, this is inspired from your ARM GIC patches.
https://lore.kernel.org/linux-arm-kernel/20221121140049.038269899 at linutronix.de/
https://lore.kernel.org/linux-arm-kernel/20221121140049.112451419 at linutronix.de/
https://lore.kernel.org/linux-arm-kernel/20221121140049.237988384 at linutronix.de/
https://lore.kernel.org/linux-arm-kernel/20221121140049.941784867 at linutronix.de/

>
> > +static const struct msi_parent_ops imsic_msi_parent_ops = {
> > +     .supported_flags        = MSI_GENERIC_FLAGS_MASK,
> > +     .required_flags         = MSI_FLAG_USE_DEF_DOM_OPS |
> > +                               MSI_FLAG_USE_DEF_CHIP_OPS,
> > +     .bus_select_token       = DOMAIN_BUS_NEXUS,
> > +     .bus_select_mask        = MATCH_PLATFORM_MSI,
> > +     .init_dev_msi_info      = imsic_init_dev_msi_info,
> > +};
> > +
> > +int imsic_irqdomain_init(void)
> > +{
> > +     struct imsic_global_config *global;
> > +
> > +     if (!imsic || !imsic->fwnode) {
> > +             pr_err("early driver not probed\n");
> > +             return -ENODEV;
> > +     }
> > +
> > +     if (imsic->base_domain) {
> > +             pr_err("%pfwP: irq domain already created\n", imsic->fwnode);
> > +             return -ENODEV;
> > +     }
> > +
> > +     global = &imsic->global;
>
> Please move that assignment down to the usage site. Here it's just a
> distraction.

Okay, I will update.

>
> > +     /* Create Base IRQ domain */
> > +     imsic->base_domain = irq_domain_create_tree(imsic->fwnode,
> > +                                     &imsic_base_domain_ops, imsic);
> > +     if (!imsic->base_domain) {
> > +             pr_err("%pfwP: failed to create IMSIC base domain\n",
> > +                     imsic->fwnode);
> > +             return -ENOMEM;
> > +     }
> > +     imsic->base_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
> > +     imsic->base_domain->msi_parent_ops = &imsic_msi_parent_ops;
>

Regards,
Anup


From vigneshr at ti.com  Sun Feb 18 20:22:18 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Mon, 19 Feb 2024 09:52:18 +0530
Subject: [PATCH v5 0/5] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
In-Reply-To: <c37af45e-def1-4a97-ae01-e00e5b22eb23@solid-run.com>
References: <20240211-add-am64-som-v5-0-790ed7121249@solid-run.com>
 <8aa96c66-d054-4b33-8972-f9faf2e84482@ti.com>
 <c37af45e-def1-4a97-ae01-e00e5b22eb23@solid-run.com>
Message-ID: <bd93e51b-70ec-4cd4-88a3-1c79a0e3c75f@ti.com>

Hi,

On 18/02/24 19:48, Josua Mayer wrote:
> Am 13.02.24 um 07:12 schrieb Vignesh Raghavendra:
>> Hi
>>
>> [...]
>>
>> On 11/02/24 20:37, Josua Mayer wrote:
>>> ---
>>> Josua Mayer (4):
>>> ?????? dt-bindings: arm: ti: Add bindings for SolidRun AM642
>>> HummingBoard-T

This goes via TI K3 arch tree

>>
>>> ?????? dt-bindings: rtc: abx80x: convert to yaml
>>> ?????? dt-bindings: iio: humidity: hdc20x0: add optional interrupts
>>> property
>>> ?????? dt-bindings: mtd: spi-nor: add optional interrupts property
>> 2/5 needs to go via RTC subsystem tree. Could you split it out into its
>> own series when you respin
> Only rtc, or should I split out the other two as well?

Split others too. RTC, IIO and SPI-NOR related bindings should go via
respective trees. Please post them individually to appropriate lists.

Regards
Vignesh


From apatel at ventanamicro.com  Sun Feb 18 20:41:10 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 19 Feb 2024 10:11:10 +0530
Subject: [PATCH v12 20/25] irqchip/riscv-imsic: Add device MSI domain
 support for PCI devices
In-Reply-To: <87bk8gcgjz.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-21-apatel@ventanamicro.com> <87bk8gcgjz.ffs@tglx>
Message-ID: <CAK9=C2XUre1A0+x7VjE2DvfTb5YxXgT7EHd-wKQQwJUhOOQNdw@mail.gmail.com>

On Sat, Feb 17, 2024 at 1:44?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> > +#ifdef CONFIG_RISCV_IMSIC_PCI
> > +
> > +static void imsic_pci_mask_irq(struct irq_data *d)
> > +{
> > +     pci_msi_mask_irq(d);
> > +     irq_chip_mask_parent(d);
> > +}
> > +
> > +static void imsic_pci_unmask_irq(struct irq_data *d)
> > +{
> > +     pci_msi_unmask_irq(d);
> > +     irq_chip_unmask_parent(d);
>
> That's asymmetric vs. mask().

Yes, this needs to be symmetric vs mask(). I will update.

Regards,
Anup


From peng.fan at oss.nxp.com  Sun Feb 18 21:22:35 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 19 Feb 2024 13:22:35 +0800
Subject: [PATCH v8 0/5] mailbox: imx: support i.MX95 ELE/V2X MU
Message-ID: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>

- Add dt-bindings
- i.MX95 ELE/V2X use same register layout as i.MX8ULP S4 MU, but
  the TR/RR num is different. To make code reusable and not add too much
  macros, add runtime detect number of TR and RR by reading PAR_OFF
  registers.
- Add i.MX95 ELE/V2X MU entry in driver

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Changes in v8:
- Drop [patch v7 4/6] which is wrongly included when doing cleanup.
- Link to v7: https://lore.kernel.org/r/20240218-imx-mailbox-v7-0-8fb665eeae40 at nxp.com

Changes in v7:
- Per Jassi, separate the patch to add of_platform_populate.
- Link to v6: https://lore.kernel.org/r/20240201-imx-mailbox-v6-0-76f4f35b403e at nxp.com

Changes in v6:
- Drop node labels and add Conor's R-b
- Link to v5: https://lore.kernel.org/r/20240126-imx-mailbox-v5-0-7ff3a3d53529 at nxp.com

Changes in v5:
- Per Conor, add restriction to sram property.
- Since i.MX95 MU has SRAM, we may not see it is compatible with
i.MX8ULP MU, so drop the fallback compatible
- Add R-b for patch 2&3
- Link to v4: https://lore.kernel.org/r/20240125-imx-mailbox-v4-0-800be5383c20 at nxp.com

Changes in v4:
- Address dt-binding comments in V2 from Krzysztof
- Link to v3: https://lore.kernel.org/r/20240123-imx-mailbox-v3-0-ed932945e0bf at nxp.com

Changes in v3:
- Following dts coding style Per Krzysztof
- Add return type for init function, patch 2 is new
- Check return value when tr/rr is larger than 4 and return error.
- Link to v2: https://lore.kernel.org/r/20240122-imx-mailbox-v2-0-7b3c80333b92 at nxp.com

Changes in v2:
- Support sram property and add example
- Populate the sram node in driver
- Link to v1: https://lore.kernel.org/r/20240122-imx-mailbox-v1-0-81413f655210 at nxp.com

---
Peng Fan (5):
      dt-bindings: mailbox: fsl,mu: add i.MX95 Generic/ELE/V2X MU compatible
      mailbox: imx: support return value of init
      mailbox: imx: get RR/TR registers num from Parameter register
      mailbox: imx: populate sub-nodes
      mailbox: imx: support i.MX95 Generic/ELE/V2X MU

 .../devicetree/bindings/mailbox/fsl,mu.yaml        | 58 +++++++++++++-
 drivers/mailbox/imx-mailbox.c                      | 88 ++++++++++++++++------
 2 files changed, 123 insertions(+), 23 deletions(-)
---
base-commit: ad5c60d66016e544c51ed98635a74073f761f45d
change-id: 20240122-imx-mailbox-243021d12030

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Sun Feb 18 21:22:36 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 19 Feb 2024 13:22:36 +0800
Subject: [PATCH v8 1/5] dt-bindings: mailbox: fsl,mu: add i.MX95
 Generic/ELE/V2X MU compatible
In-Reply-To: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>
References: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>
Message-ID: <20240219-imx-mailbox-v8-1-75535a87794e@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add i.MX95 Generic, Secure Enclave and V2X Message Unit compatible string.
And the MUs in AONMIX has internal RAMs for SCMI shared buffer usage.

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/mailbox/fsl,mu.yaml        | 58 +++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml b/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml
index 12e7a7d536a3..00631afcd51d 100644
--- a/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml
+++ b/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml
@@ -29,8 +29,11 @@ properties:
       - const: fsl,imx8ulp-mu
       - const: fsl,imx8-mu-scu
       - const: fsl,imx8-mu-seco
-      - const: fsl,imx93-mu-s4
       - const: fsl,imx8ulp-mu-s4
+      - const: fsl,imx93-mu-s4
+      - const: fsl,imx95-mu
+      - const: fsl,imx95-mu-ele
+      - const: fsl,imx95-mu-v2x
       - items:
           - const: fsl,imx93-mu
           - const: fsl,imx8ulp-mu
@@ -95,6 +98,19 @@ properties:
   power-domains:
     maxItems: 1
 
+  ranges: true
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 1
+
+patternProperties:
+  "^sram@[a-f0-9]+":
+    $ref: /schemas/sram/sram.yaml#
+    unevaluatedProperties: false
+
 required:
   - compatible
   - reg
@@ -122,6 +138,15 @@ allOf:
         required:
           - interrupt-names
 
+  - if:
+      not:
+        properties:
+          compatible:
+            const: fsl,imx95-mu
+    then:
+      patternProperties:
+        "^sram@[a-f0-9]+": false
+
 additionalProperties: false
 
 examples:
@@ -134,3 +159,34 @@ examples:
         interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
         #mbox-cells = <2>;
     };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    mailbox at 445b0000 {
+        compatible = "fsl,imx95-mu";
+        reg = <0x445b0000 0x10000>;
+        ranges;
+        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        #mbox-cells = <2>;
+
+        sram at 445b1000 {
+            compatible = "mmio-sram";
+            reg = <0x445b1000 0x400>;
+            ranges = <0x0 0x445b1000 0x400>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            scmi-sram-section at 0 {
+                compatible = "arm,scmi-shmem";
+                reg = <0x0 0x80>;
+            };
+
+            scmi-sram-section at 80 {
+                compatible = "arm,scmi-shmem";
+                reg = <0x80 0x80>;
+            };
+        };
+    };

-- 
2.37.1



From peng.fan at oss.nxp.com  Sun Feb 18 21:22:37 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 19 Feb 2024 13:22:37 +0800
Subject: [PATCH v8 2/5] mailbox: imx: support return value of init
In-Reply-To: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>
References: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>
Message-ID: <20240219-imx-mailbox-v8-2-75535a87794e@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

There will be changes that init may fail, so adding return value for
init function.

Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 656171362fe9..dced4614065f 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -110,7 +110,7 @@ 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);
+	int (*init)(struct imx_mu_priv *priv);
 	enum imx_mu_type type;
 	u32	xTR;		/* Transmit Register0 */
 	u32	xRR;		/* Receive Register0 */
@@ -737,7 +737,7 @@ static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox,
 	return imx_mu_xlate(mbox, sp);
 }
 
-static void imx_mu_init_generic(struct imx_mu_priv *priv)
+static int imx_mu_init_generic(struct imx_mu_priv *priv)
 {
 	unsigned int i;
 	unsigned int val;
@@ -757,7 +757,7 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
 	priv->mbox.of_xlate = imx_mu_xlate;
 
 	if (priv->side_b)
-		return;
+		return 0;
 
 	/* Set default MU configuration */
 	for (i = 0; i < IMX_MU_xCR_MAX; i++)
@@ -770,9 +770,11 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
 	/* Clear any pending RSR */
 	for (i = 0; i < IMX_MU_NUM_RR; i++)
 		imx_mu_read(priv, priv->dcfg->xRR + (i % 4) * 4);
+
+	return 0;
 }
 
-static void imx_mu_init_specific(struct imx_mu_priv *priv)
+static int imx_mu_init_specific(struct imx_mu_priv *priv)
 {
 	unsigned int i;
 	int num_chans = priv->dcfg->type & IMX_MU_V2_S4 ? IMX_MU_S4_CHANS : IMX_MU_SCU_CHANS;
@@ -794,12 +796,20 @@ static void imx_mu_init_specific(struct imx_mu_priv *priv)
 	/* Set default MU configuration */
 	for (i = 0; i < IMX_MU_xCR_MAX; i++)
 		imx_mu_write(priv, 0, priv->dcfg->xCR[i]);
+
+	return 0;
 }
 
-static void imx_mu_init_seco(struct imx_mu_priv *priv)
+static int imx_mu_init_seco(struct imx_mu_priv *priv)
 {
-	imx_mu_init_generic(priv);
+	int ret;
+
+	ret = imx_mu_init_generic(priv);
+	if (ret)
+		return ret;
 	priv->mbox.of_xlate = imx_mu_seco_xlate;
+
+	return 0;
 }
 
 static int imx_mu_probe(struct platform_device *pdev)
@@ -866,7 +876,11 @@ static int imx_mu_probe(struct platform_device *pdev)
 
 	priv->side_b = of_property_read_bool(np, "fsl,mu-side-b");
 
-	priv->dcfg->init(priv);
+	ret = priv->dcfg->init(priv);
+	if (ret) {
+		dev_err(dev, "Failed to init MU\n");
+		goto disable_clk;
+	}
 
 	spin_lock_init(&priv->xcr_lock);
 
@@ -878,10 +892,8 @@ static int imx_mu_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, priv);
 
 	ret = devm_mbox_controller_register(dev, &priv->mbox);
-	if (ret) {
-		clk_disable_unprepare(priv->clk);
-		return ret;
-	}
+	if (ret)
+		goto disable_clk;
 
 	pm_runtime_enable(dev);
 
@@ -899,6 +911,7 @@ static int imx_mu_probe(struct platform_device *pdev)
 
 disable_runtime_pm:
 	pm_runtime_disable(dev);
+disable_clk:
 	clk_disable_unprepare(priv->clk);
 	return ret;
 }

-- 
2.37.1



From peng.fan at oss.nxp.com  Sun Feb 18 21:22:38 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 19 Feb 2024 13:22:38 +0800
Subject: [PATCH v8 3/5] mailbox: imx: get RR/TR registers num from
 Parameter register
In-Reply-To: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>
References: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>
Message-ID: <20240219-imx-mailbox-v8-3-75535a87794e@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX8ULP, i.MX93 MU has a Parameter register encoded as below:
BIT: 15 --- 8 | 7 --- 0
      RR_NUM    TR_NUM

So to make driver easy to support more variants, get the RR/TR
registers number from Parameter register.

The patch only adds support the specific MU, such as ELE MU.
For generic MU, not add support for number larger than 4.

Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 47 +++++++++++++++++++++++++++++++++----------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index dced4614065f..306af1880415 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -4,6 +4,7 @@
  * Copyright 2022 NXP, Peng Fan <peng.fan at nxp.com>
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/firmware/imx/ipc.h>
 #include <linux/firmware/imx/s4.h>
@@ -29,7 +30,9 @@
 #define IMX_MU_S4_CHANS		2
 #define IMX_MU_CHAN_NAME_SIZE	20
 
-#define IMX_MU_NUM_RR		4
+#define IMX_MU_V2_PAR_OFF	0x4
+#define IMX_MU_V2_TR_MASK	GENMASK(7, 0)
+#define IMX_MU_V2_RR_MASK	GENMASK(15, 8)
 
 #define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000))
 #define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000))
@@ -93,10 +96,11 @@ struct imx_mu_priv {
 	struct clk		*clk;
 	int			irq[IMX_MU_CHANS];
 	bool			suspend;
-
-	u32 xcr[IMX_MU_xCR_MAX];
-
 	bool			side_b;
+
+	u32			xcr[IMX_MU_xCR_MAX];
+	u32			num_tr;
+	u32			num_rr;
 };
 
 enum imx_mu_type {
@@ -264,18 +268,17 @@ static int imx_mu_generic_rxdb(struct imx_mu_priv *priv,
 static int imx_mu_specific_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data)
 {
 	u32 *arg = data;
+	u32 num_tr = priv->num_tr;
 	int i, ret;
 	u32 xsr;
-	u32 size, max_size, num_tr;
+	u32 size, max_size;
 
 	if (priv->dcfg->type & IMX_MU_V2_S4) {
 		size = ((struct imx_s4_rpc_msg_max *)data)->hdr.size;
 		max_size = sizeof(struct imx_s4_rpc_msg_max);
-		num_tr = 8;
 	} else {
 		size = ((struct imx_sc_rpc_msg_max *)data)->hdr.size;
 		max_size = sizeof(struct imx_sc_rpc_msg_max);
-		num_tr = 4;
 	}
 
 	switch (cp->type) {
@@ -324,6 +327,7 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
 	int i, ret;
 	u32 xsr;
 	u32 size, max_size;
+	u32 num_rr = priv->num_rr;
 
 	data = (u32 *)priv->msg;
 
@@ -345,13 +349,13 @@ 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,
+					 xsr & IMX_MU_xSR_RFn(priv->dcfg->type, i % num_rr), 0,
 					 5 * USEC_PER_SEC);
 		if (ret) {
 			dev_err(priv->dev, "timeout read idx %d\n", i);
 			return ret;
 		}
-		*data++ = imx_mu_read(priv, priv->dcfg->xRR + (i % 4) * 4);
+		*data++ = imx_mu_read(priv, priv->dcfg->xRR + (i % num_rr) * 4);
 	}
 
 	imx_mu_xcr_rmw(priv, IMX_MU_RCR, IMX_MU_xCR_RIEn(priv->dcfg->type, 0), 0);
@@ -737,11 +741,30 @@ static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox,
 	return imx_mu_xlate(mbox, sp);
 }
 
+static void imx_mu_get_tr_rr(struct imx_mu_priv *priv)
+{
+	u32 val;
+
+	if (priv->dcfg->type & IMX_MU_V2) {
+		val = imx_mu_read(priv, IMX_MU_V2_PAR_OFF);
+		priv->num_tr = FIELD_GET(IMX_MU_V2_TR_MASK, val);
+		priv->num_rr = FIELD_GET(IMX_MU_V2_RR_MASK, val);
+	} else {
+		priv->num_tr = 4;
+		priv->num_rr = 4;
+	}
+}
+
 static int imx_mu_init_generic(struct imx_mu_priv *priv)
 {
 	unsigned int i;
 	unsigned int val;
 
+	if (priv->num_rr > 4 || priv->num_tr > 4) {
+		WARN_ONCE(true, "%s not support TR/RR larger than 4\n", __func__);
+		return -EOPNOTSUPP;
+	}
+
 	for (i = 0; i < IMX_MU_CHANS; i++) {
 		struct imx_mu_con_priv *cp = &priv->con_priv[i];
 
@@ -768,8 +791,8 @@ static int imx_mu_init_generic(struct imx_mu_priv *priv)
 	imx_mu_write(priv, val, priv->dcfg->xSR[IMX_MU_GSR]);
 
 	/* Clear any pending RSR */
-	for (i = 0; i < IMX_MU_NUM_RR; i++)
-		imx_mu_read(priv, priv->dcfg->xRR + (i % 4) * 4);
+	for (i = 0; i < priv->num_rr; i++)
+		imx_mu_read(priv, priv->dcfg->xRR + i * 4);
 
 	return 0;
 }
@@ -874,6 +897,8 @@ static int imx_mu_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	imx_mu_get_tr_rr(priv);
+
 	priv->side_b = of_property_read_bool(np, "fsl,mu-side-b");
 
 	ret = priv->dcfg->init(priv);

-- 
2.37.1



From peng.fan at oss.nxp.com  Sun Feb 18 21:22:39 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 19 Feb 2024 13:22:39 +0800
Subject: [PATCH v8 4/5] mailbox: imx: populate sub-nodes
In-Reply-To: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>
References: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>
Message-ID: <20240219-imx-mailbox-v8-4-75535a87794e@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Some MUs such as i.MX95 MU, have internal SRAM which could be used
for SCMI shared memory, so populate the sub-nodes to use the SRAM.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 306af1880415..b36267591db2 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -16,6 +16,7 @@
 #include <linux/mailbox_controller.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/suspend.h>
@@ -920,6 +921,8 @@ static int imx_mu_probe(struct platform_device *pdev)
 	if (ret)
 		goto disable_clk;
 
+	of_platform_populate(dev->of_node, NULL, NULL, dev);
+
 	pm_runtime_enable(dev);
 
 	ret = pm_runtime_resume_and_get(dev);

-- 
2.37.1



From peng.fan at oss.nxp.com  Sun Feb 18 21:22:40 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 19 Feb 2024 13:22:40 +0800
Subject: [PATCH v8 5/5] mailbox: imx: support i.MX95 Generic/ELE/V2X MU
In-Reply-To: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>
References: <20240219-imx-mailbox-v8-0-75535a87794e@nxp.com>
Message-ID: <20240219-imx-mailbox-v8-5-75535a87794e@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add i.MX95 Generic/ELE/V2X MU support, its register layout is same as
i.MX8ULP, but the Parameter registers would show different
TR/RR. Since the driver already supports get TR/RR from Parameter
registers, not hardcoding the number, this patch just add
the compatible entry to reuse i.MX8ULP S4 cfg data.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index b36267591db2..5c1d09cad761 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -1035,6 +1035,9 @@ static const struct of_device_id imx_mu_dt_ids[] = {
 	{ .compatible = "fsl,imx8ulp-mu", .data = &imx_mu_cfg_imx8ulp },
 	{ .compatible = "fsl,imx8ulp-mu-s4", .data = &imx_mu_cfg_imx8ulp_s4 },
 	{ .compatible = "fsl,imx93-mu-s4", .data = &imx_mu_cfg_imx93_s4 },
+	{ .compatible = "fsl,imx95-mu", .data = &imx_mu_cfg_imx8ulp },
+	{ .compatible = "fsl,imx95-mu-ele", .data = &imx_mu_cfg_imx8ulp_s4 },
+	{ .compatible = "fsl,imx95-mu-v2x", .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 },
 	{ },

-- 
2.37.1



From peng.fan at nxp.com  Sun Feb 18 21:15:02 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 19 Feb 2024 05:15:02 +0000
Subject: [PATCH v7 0/6] mailbox: imx: support i.MX95 ELE/V2X MU
In-Reply-To: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
References: <20240218-imx-mailbox-v7-0-8fb665eeae40@nxp.com>
Message-ID: <DU0PR04MB9417D8EF014B45F31E497B0988512@DU0PR04MB9417.eurprd04.prod.outlook.com>

Please ignore this V7 patchset, a patch was wrongly included.

Thanks,
Peng.
> Subject: [PATCH v7 0/6] mailbox: imx: support i.MX95 ELE/V2X MU
> 
> - Add dt-bindings
> - i.MX95 ELE/V2X use same register layout as i.MX8ULP S4 MU, but
>   the TR/RR num is different. To make code reusable and not add too much
>   macros, add runtime detect number of TR and RR by reading PAR_OFF
>   registers.
> - Add i.MX95 ELE/V2X MU entry in driver
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
> Changes in v7:
> - Per Jassi, separate the patch to add of_platform_populate.
> - Link to v6: https://lore.kernel.org/r/20240201-imx-mailbox-v6-0-
> 76f4f35b403e at nxp.com
> 
> Changes in v6:
> - Drop node labels and add Conor's R-b
> - Link to v5: https://lore.kernel.org/r/20240126-imx-mailbox-v5-0-
> 7ff3a3d53529 at nxp.com
> 
> Changes in v5:
> - Per Conor, add restriction to sram property.
> - Since i.MX95 MU has SRAM, we may not see it is compatible with i.MX8ULP
> MU, so drop the fallback compatible
> - Add R-b for patch 2&3
> - Link to v4: https://lore.kernel.org/r/20240125-imx-mailbox-v4-0-
> 800be5383c20 at nxp.com
> 
> Changes in v4:
> - Address dt-binding comments in V2 from Krzysztof
> - Link to v3: https://lore.kernel.org/r/20240123-imx-mailbox-v3-0-
> ed932945e0bf at nxp.com
> 
> Changes in v3:
> - Following dts coding style Per Krzysztof
> - Add return type for init function, patch 2 is new
> - Check return value when tr/rr is larger than 4 and return error.
> - Link to v2: https://lore.kernel.org/r/20240122-imx-mailbox-v2-0-
> 7b3c80333b92 at nxp.com
> 
> Changes in v2:
> - Support sram property and add example
> - Populate the sram node in driver
> - Link to v1: https://lore.kernel.org/r/20240122-imx-mailbox-v1-0-
> 81413f655210 at nxp.com
> 
> ---
> Peng Fan (6):
>       dt-bindings: mailbox: fsl,mu: add i.MX95 Generic/ELE/V2X MU compatible
>       mailbox: imx: support return value of init
>       mailbox: imx: get RR/TR registers num from Parameter register
>       tt
>       mailbox: imx: populate sub-nodes
>       mailbox: imx: support i.MX95 Generic/ELE/V2X MU
> 
>  .../devicetree/bindings/mailbox/fsl,mu.yaml        | 58 +++++++++++++-
>  drivers/mailbox/imx-mailbox.c                      | 88 ++++++++++++++++------
>  2 files changed, 123 insertions(+), 23 deletions(-)
> ---
> base-commit: ad5c60d66016e544c51ed98635a74073f761f45d
> change-id: 20240122-imx-mailbox-243021d12030
> 
> Best regards,
> --
> Peng Fan <peng.fan at nxp.com>


From danielmentz at google.com  Sun Feb 18 21:44:47 2024
From: danielmentz at google.com (Daniel Mentz)
Date: Sun, 18 Feb 2024 21:44:47 -0800
Subject: [PATCH] drivers/iommu: Ensure that the queue base address is
 successfully written during SMMU initialization.
In-Reply-To: <20240218050224.33426-1-niliqiang.io@gmail.com>
References: <20240218050224.33426-1-niliqiang.io@gmail.com>
Message-ID: <CAE2F3rA1Lb_ayrLQTw+urtNSMoBg9q6CmcSsP7_dZwbfiYygsw@mail.gmail.com>

On Sat, Feb 17, 2024 at 9:02?PM ni.liqiang <niliqiang.io at gmail.com> wrote:
> If there are no memory barriers, how can we ensure this order?

 The SMMU registers are accessed using Device-nGnRE attributes. It is
my understanding that, for Device-nGnRE, the Arm architecture requires
that writes to the same peripheral arrive at the endpoint in program
order.


From u-kumar1 at ti.com  Sun Feb 18 21:55:27 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Mon, 19 Feb 2024 11:25:27 +0530
Subject: [PATCH 2/2] arm64: dts: ti: k3-j722s-evm: Enable OSPI NOR support
In-Reply-To: <20240216135533.904130-3-vaishnav.a@ti.com>
References: <20240216135533.904130-1-vaishnav.a@ti.com>
 <20240216135533.904130-3-vaishnav.a@ti.com>
Message-ID: <0ca01a1b-8956-40dd-8286-77276e021633@ti.com>

Hi Vaishnav

On 2/16/2024 7:25 PM, Vaishnav Achath wrote:
> J722S EVM has S28HS512T 64 MiB Octal SPI NOR flash connected
> to the OSPI interface, add support for the flash and describe
> the partition information as per bootloader.
>
> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
> ---
>   arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 79 +++++++++++++++++++++++++
>   1 file changed, 79 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
> index 9e12a6e9111f..b1c6499c0c9d 100644
> --- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
> +++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
> @@ -169,6 +169,23 @@ J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) MDIO0_MDIO */
>   		>;
>   	};
>   
> +	ospi0_pins_default: ospi0-default-pins {
> +		pinctrl-single,pins = <
> +			J722S_IOPAD(0x0000, PIN_OUTPUT, 0) /* (P23) OSPI0_CLK */
> +			J722S_IOPAD(0x002c, PIN_OUTPUT, 0) /* (M25) OSPI0_CSn0 */
> +			J722S_IOPAD(0x000c, PIN_INPUT, 0) /* (L25) OSPI0_D0 */
> +			J722S_IOPAD(0x0010, PIN_INPUT, 0) /* (N24) OSPI0_D1 */
> +			J722S_IOPAD(0x0014, PIN_INPUT, 0) /* (N25) OSPI0_D2 */
> +			J722S_IOPAD(0x0018, PIN_INPUT, 0) /* (M24) OSPI0_D3 */
> +			J722S_IOPAD(0x001c, PIN_INPUT, 0) /* (N21) OSPI0_D4 */
> +			J722S_IOPAD(0x0020, PIN_INPUT, 0) /* (N22) OSPI0_D5 */
> +			J722S_IOPAD(0x0024, PIN_INPUT, 0) /* (P21) OSPI0_D6 */
> +			J722S_IOPAD(0x0028, PIN_INPUT, 0) /* (N20) OSPI0_D7 */
> +			J722S_IOPAD(0x0008, PIN_INPUT, 0) /* (P22) OSPI0_DQS */


Could you check, Pin name in comments

For example, Schematic says L22 is for OSPI0_DQS , but comments says P22

However offsets are good .

> +		>;
> +		bootph-all;
> +	};
> +
>   	rgmii1_pins_default: rgmii1-default-pins {
>   		pinctrl-single,pins = <
>   			J722S_IOPAD(0x014c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */
> @@ -290,6 +307,68 @@ exp1: gpio at 23 {
>   	};
>   };
>   
> +&ospi0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&ospi0_pins_default>;
> +	status = "okay";
> +
> +	flash at 0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0x0>;
> +		spi-tx-bus-width = <8>;
> +		spi-rx-bus-width = <8>;
> +		spi-max-frequency = <25000000>;
> +		cdns,tshsl-ns = <60>;
> +		cdns,tsd2d-ns = <60>;
> +		cdns,tchsh-ns = <60>;
> +		cdns,tslch-ns = <60>;
> +		cdns,read-delay = <4>;
> +		bootph-all;
> +
> +		partitions {
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			partition at 0 {
> +				label = "ospi.tiboot3";
> +				reg = <0x00 0x80000>;
> +			};


I suggest to keep 1MB to accommodate future size increase

> +
> +			partition at 80000 {
> +				label = "ospi.tispl";
> +				reg = <0x80000 0x200000>;
> +			};
> +
> +			partition at 280000 {
> +				label = "ospi.u-boot";
> +				reg = <0x280000 0x400000>;
> +			};
> +
> +			partition at 680000 {
> +				label = "ospi.env";
> +				reg = <0x680000 0x40000>;
> +			};
> +
> +			partition at 6c0000 {
> +				label = "ospi.env.backup";
> +				reg = <0x6c0000 0x40000>;
> +			};
> +
> +			partition at 800000 {
> +				label = "ospi.rootfs";
> +				reg = <0x800000 0x37c0000>;
> +			};
> +
> +			partition at 3fc0000 {
> +				label = "ospi.phypattern";
> +				reg = <0x3fc0000 0x40000>;
> +			};
> +		};
> +	};
> +
> +};
> +
>   &sdhci1 {
>   	/* SD/MMC */
>   	vmmc-supply = <&vdd_mmc1>;


From arnd at arndb.de  Sun Feb 18 22:21:11 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 19 Feb 2024 07:21:11 +0100
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
Message-ID: <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>

On Mon, Feb 19, 2024, at 05:09, Calvin Owens wrote:
> 32-bit arm builds uniquely emit a lot of spam like this:
>
>     fs/bcachefs/backpointers.c: In function ?extent_matches_bp?:
>     fs/bcachefs/backpointers.c:15:13: note: parameter passing for 
> argument of type ?struct bch_backpointer? changed in GCC 9.1
>
> Apply the arm64 change from commit ebcc5928c5d9 ("arm64: Silence gcc
> warnings about arch ABI drift") to silence them. It seems like Dave's
> original rationale applies here too.
>
> Cc: Dave Martin <Dave.Martin at arm.com>
> Signed-off-by: Calvin Owens <jcalvinowens at gmail.com>
> ---

I think these should be addressed in bcachefs instead.
While it's not the fault of bcachefs that the calling
convention changed between gcc versions, have a look at
the actual structure layout:

struct bch_val {
        __u64           __nothing[0];
};
struct bpos {
        /*
         * Word order matches machine byte order - btree code treats a bpos as a
         * single large integer, for search/comparison purposes
         *
         * Note that wherever a bpos is embedded in another on disk data
         * structure, it has to be byte swabbed when reading in metadata that
         * wasn't written in native endian order:
         */
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
        __u32           snapshot;
        __u64           offset;
        __u64           inode;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
        __u64           inode;
        __u64           offset;         /* Points to end of extent - sectors */
        __u32           snapshot;
#else
#error edit for your odd byteorder.
#endif
} __packed
struct bch_backpointer {
        struct bch_val          v;
        __u8                    btree_id;
        __u8                    level;
        __u8                    data_type;
        __u64                   bucket_offset:40;
        __u32                   bucket_len;
        struct bpos             pos;
} __packed __aligned(8);

This is not something that should ever be passed by value
into a function.

      Arnd


From claudiu.beznea at tuxon.dev  Sun Feb 18 22:25:08 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Mon, 19 Feb 2024 08:25:08 +0200
Subject: [PATCH] clk: constify the of_phandle_args argument of
 of_clk_provider
In-Reply-To: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
References: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
Message-ID: <e43727bd-d83d-4271-9871-ff995c8e7d03@tuxon.dev>



On 08.02.2024 18:37, Krzysztof Kozlowski wrote:
> None of the implementations of the get() and get_hw() callbacks of
> "struct of_clk_provider" modify the contents of received of_phandle_args
> pointer.  They treat it as read-only variable used to find the clock to
> return.  Make obvious that implementations are not supposed to modify
> the of_phandle_args, by making it a pointer to const.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>  drivers/clk/at91/pmc.c                        |  3 +-
>  drivers/clk/at91/pmc.h                        |  3 +-

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>


From kent.overstreet at linux.dev  Sun Feb 18 22:25:22 2024
From: kent.overstreet at linux.dev (Kent Overstreet)
Date: Mon, 19 Feb 2024 01:25:22 -0500
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
Message-ID: <k6cclnrqu2h6mh4wb33hpakhfasq7jec7dnbaiaxlpw525adan@cor5l3bi35u2>

On Mon, Feb 19, 2024 at 07:21:11AM +0100, Arnd Bergmann wrote:
> On Mon, Feb 19, 2024, at 05:09, Calvin Owens wrote:
> > 32-bit arm builds uniquely emit a lot of spam like this:
> >
> >     fs/bcachefs/backpointers.c: In function ?extent_matches_bp?:
> >     fs/bcachefs/backpointers.c:15:13: note: parameter passing for 
> > argument of type ?struct bch_backpointer? changed in GCC 9.1
> >
> > Apply the arm64 change from commit ebcc5928c5d9 ("arm64: Silence gcc
> > warnings about arch ABI drift") to silence them. It seems like Dave's
> > original rationale applies here too.
> >
> > Cc: Dave Martin <Dave.Martin at arm.com>
> > Signed-off-by: Calvin Owens <jcalvinowens at gmail.com>
> > ---
> 
> I think these should be addressed in bcachefs instead.
> While it's not the fault of bcachefs that the calling
> convention changed between gcc versions, have a look at
> the actual structure layout:
> 
> struct bch_val {
>         __u64           __nothing[0];
> };
> struct bpos {
>         /*
>          * Word order matches machine byte order - btree code treats a bpos as a
>          * single large integer, for search/comparison purposes
>          *
>          * Note that wherever a bpos is embedded in another on disk data
>          * structure, it has to be byte swabbed when reading in metadata that
>          * wasn't written in native endian order:
>          */
> #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
>         __u32           snapshot;
>         __u64           offset;
>         __u64           inode;
> #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
>         __u64           inode;
>         __u64           offset;         /* Points to end of extent - sectors */
>         __u32           snapshot;
> #else
> #error edit for your odd byteorder.
> #endif
> } __packed
> struct bch_backpointer {
>         struct bch_val          v;
>         __u8                    btree_id;
>         __u8                    level;
>         __u8                    data_type;
>         __u64                   bucket_offset:40;
>         __u32                   bucket_len;
>         struct bpos             pos;
> } __packed __aligned(8);
> 
> This is not something that should ever be passed by value
> into a function.

Why?


From jialong.yang at shingroup.cn  Sun Feb 18 22:37:08 2024
From: jialong.yang at shingroup.cn (=?UTF-8?B?WWFuZyBKaWFsb25nIOadqOS9s+m+mQ==?=)
Date: Mon, 19 Feb 2024 14:37:08 +0800
Subject: [PATCH] perf/arm_smmuv3: Omit the two judgements which done in
 framework
In-Reply-To: <a455e5db-676a-4cf8-8669-8a10e900361c@arm.com>
References: <20231221093802.20612-1-jialong.yang@shingroup.cn>
 <20240209160905.GA24565@willie-the-truck>
 <a455e5db-676a-4cf8-8669-8a10e900361c@arm.com>
Message-ID: <840C2556C7DDB57C+c4575f04-5d1b-44a5-8f7b-3a2ba1fd61c4@shingroup.cn>



? 2024/2/10 0:32, Robin Murphy ??:
> On 2024-02-09 4:09 pm, Will Deacon wrote:
>> On Thu, Dec 21, 2023 at 05:38:01PM +0800, JiaLong.Yang wrote:
>>> 'event->attr.type != event->pmu->type' has been done in
>>> core.c::perf_init_event() ,core.c::perf_event_modify_attr(), etc.
>>>
>>> This PMU is an uncore one. The core framework has disallowed
>>> uncore-task events. So the judgement to event->cpu < 0 is no mean.
>>
>> It would be great to refer to the changes which added those checks to
>> the perf core code. From reading the code myself, I can't convince myself
>> that perf_try_init_event() won't call into the driver.
>>
>>>
>>> The two judgements have been done in kernel/events/core.c
>>>
>>> Signed-off-by: JiaLong.Yang <jialong.yang at shingroup.cn>
>>> ---
>>> ? drivers/perf/arm_smmuv3_pmu.c | 8 --------
>>> ? 1 file changed, 8 deletions(-)
>>
>> It looks like _many_ perf drivers have these checks, so if they really
>> aren't needed, we can clean this up bveyond SMMU. However, as I said
>> above, I'm not quite convinced we can drop them.
> 
> Right, I think the logic prevents events with a specific PMU type being 
> offered to other PMUs, but as far as I'm aware doesn't apply the other 
> way round to stop generic events (PERF_TYPE_HARDWARE etc.) being offered 
> to all PMUs, so it's those that system PMUs need to reject. >
> It's been on my wishlist for a long time to have a capability flag to 
> say "I don't handle generic events, please only ever give me events of 
> my exact type" so we *can* truly factor this into the core.


It's core framework's responsible to differ generic events and others, 
or uncore pmu and core pmu.
Here we have flag PERF_TYPE_HARDWARE, PERF_TYPE_HW_CACHE, 
PERF_PMU_CAP_EXTENDED_HW_TYPE doing this.

again:
         rcu_read_lock();
         pmu = idr_find(&pmu_idr, type);
         rcu_read_unlock();
         if (pmu) {
                 if (event->attr.type != type && type != PERF_TYPE_RAW &&
                     !(pmu->capabilities & PERF_PMU_CAP_EXTENDED_HW_TYPE))
                         goto fail; /* generic event with no ability pmu */
This can avoid driver code (event->attr.type != event->pmu->type).

And, code:
if (pmu->task_ctx_nr == perf_invalid_context && (task || cgroup_fd != -1)) {
	err = -EINVAL;
	goto err_pmu;
}
can promise not uncore-task event.

We should confirm that uncore event should be cpu >= 0.

> 
> Thanks,
> Robin.
> 



From dan.carpenter at linaro.org  Sun Feb 18 22:39:35 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Mon, 19 Feb 2024 09:39:35 +0300
Subject: [PATCH] Staging: vc04_services: bcm2835-camera: fixed several
 brace coding style checks
In-Reply-To: <20240215220647.4096-1-mo.c.weber@gmail.com>
References: <20240215220647.4096-1-mo.c.weber@gmail.com>
Message-ID: <8fe8c4bf-5fa3-4bfc-9535-b48df12f80ff@moroto.mountain>

On Thu, Feb 15, 2024 at 11:06:47PM +0100, Moritz C. Weber wrote:
> @@ -406,12 +405,11 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
>  	    is_capturing(dev)) {
>  		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
>  			 "Grab another frame as buffer has EOS");
> -		vchiq_mmal_port_parameter_set(
> -			instance,
> -			dev->capture.camera_port,
> -			MMAL_PARAMETER_CAPTURE,
> -			&dev->capture.frame_count,
> -			sizeof(dev->capture.frame_count));
> +		vchiq_mmal_port_parameter_set(instance,
> +					      dev->capture.camera_port,
> +					      MMAL_PARAMETER_CAPTURE,
> +					      #N(#O(#O(#O(#O(&dev->capture.frame_count,
                                              ^^^^^^^^^^^^^^^^

Wut?

> +					      sizeof(dev->capture.frame_count));
>  	}
>  }
>  
> @@ -420,11 +418,11 @@ static int enable_camera(struct bcm2835_mmal_dev *dev)
>  	int ret;
>  
>  	if (!dev->camera_use_count) {
> -		ret = vchiq_mmal_port_parameter_set(
> -			dev->instance,
> -			&dev->component[COMP_CAMERA]->control,
> -			MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num,
> -			sizeof(dev->camera_num));
> +		ret = vchiq_mmal_port_parameter_set(dev->instance,
> +						    &dev->component[COMP_CAMERA]->control,
> +						    MMAL_PARAMETER_CAMERA_NUM,
> +						    &dev->camera_num,
> +						    **sizeof(dev->camera_num));

Also Wut???


regards,
dan carpenter



From xiangyang3 at huawei.com  Sun Feb 18 22:53:01 2024
From: xiangyang3 at huawei.com (Xiang Yang)
Date: Mon, 19 Feb 2024 14:53:01 +0800
Subject: [PATCH 5.10.y 0/5] Backport call_on_irq_stack to fix scs
 overwritten in irq_stack_entry
In-Reply-To: <CAMj1kXFbveXgHvk1jEs1Q4kE=Tak08cDYpebwEgKehhwYf9j4A@mail.gmail.com>
References: <20240218023055.145519-1-xiangyang3@huawei.com>
 <CAMj1kXFbveXgHvk1jEs1Q4kE=Tak08cDYpebwEgKehhwYf9j4A@mail.gmail.com>
Message-ID: <aeb81303-95c5-030b-4541-92dd9506d10d@huawei.com>

Thanks, I will send a v2 with the revert patch.

? 2024/2/18 18:06, Ard Biesheuvel ??:
> On Sun, 18 Feb 2024 at 03:33, Xiang Yang <xiangyang3 at huawei.com> wrote:
>>
>> The shadow call stack for irq now stored in current task's thread info
>> may restored incorrectly, so backport call_on_irq_stack from mainline to
>> fix it.
>>
>> Ard Biesheuvel (1):
>>   arm64: Stash shadow stack pointer in the task struct on interrupt
>>
>> Mark Rutland (3):
>>   arm64: entry: move arm64_preempt_schedule_irq to entry-common.c
>>   arm64: entry: add a call_on_irq_stack helper
>>   arm64: entry: convert IRQ+FIQ handlers to C
>>
>> Xiang Yang (1):
>>   Revert "arm64: Stash shadow stack pointer in the task struct on
>>     interrupt"
>>
> 
> Backporting this was a mistake. Not only was the backport flawed, the
> original issue (stashing the shadow call stack pointer onto the normal
> stack) was not even present, at least not to the same extent.
> 
> Stashing the shadow call stack pointer in register X24 works around
> the original issue, except for the case where a hardirq is taken while
> softirqs are being processed. In this case, X24 will be preserved on
> the stack by the hardirq handling logic, and restored after.
> Theoretically, that creates a window where the shadow call stack
> pointer could be corrupted deliberately, but it seems unlikely to me
> that this is exploitable in practice.
> 
> So in the light of this, I think doing only the revert here should be
> sufficient, and there is no need for the other backports in this
> series.
> .


From clabbe.montjoie at gmail.com  Sun Feb 18 22:57:27 2024
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Mon, 19 Feb 2024 07:57:27 +0100
Subject: [PATCH v4 00/20] Support more Amlogic SoC families in crypto
 driver
In-Reply-To: <20240215104719.njq6ie2niisntcnv@cab-wsm-0029881.sigma.sbrf.ru>
References: <20240212135108.549755-1-avromanov@salutedevices.com>
 <ZcsYaPIUrBSg8iXu@Red>
 <20240215104719.njq6ie2niisntcnv@cab-wsm-0029881.sigma.sbrf.ru>
Message-ID: <ZdL713ae1swwTU_B@Red>

Le Thu, Feb 15, 2024 at 10:47:24AM +0000, Alexey Romanov a ?crit :
> On Tue, Feb 13, 2024 at 08:21:12AM +0100, Corentin Labbe wrote:
> > Le Mon, Feb 12, 2024 at 04:50:48PM +0300, Alexey Romanov a 'ecrit :
> > > Hello!
> > > 
> > > This patchset expand the funcionality of the Amlogic
> > > crypto driver by adding support for more SoC families:
> > > AXG, G12A, G12B, SM1, A1, S4.
> > > 
> > > Also specify and enable crypto node in device tree
> > > for reference Amlogic devices.
> > > 
> > > Tested on AXG, G12A/B, SM1, A1 and S4 devices via
> > > custom tests [1] and tcrypt module.
> > > 
> > > ---
> > > 
> > 
> > added patchs up to  "drivers: crypto: meson: process more than MAXDESCS descriptors"
> 
> Including this patch or not?

The crash start with "drivers: crypto: meson: move algs definition and cipher API to cipher.c"


From jcalvinowens at gmail.com  Sun Feb 18 22:58:07 2024
From: jcalvinowens at gmail.com (Calvin Owens)
Date: Sun, 18 Feb 2024 22:58:07 -0800
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
Message-ID: <ZdL7_-2VCJqjn634@gmail.com>

On Monday 02/19 at 07:21 +0100, Arnd Bergmann wrote:
> On Mon, Feb 19, 2024, at 05:09, Calvin Owens wrote:
> > 32-bit arm builds uniquely emit a lot of spam like this:
> >
> >     fs/bcachefs/backpointers.c: In function ?extent_matches_bp?:
> >     fs/bcachefs/backpointers.c:15:13: note: parameter passing for 
> > argument of type ?struct bch_backpointer? changed in GCC 9.1
> >
> > Apply the arm64 change from commit ebcc5928c5d9 ("arm64: Silence gcc
> > warnings about arch ABI drift") to silence them. It seems like Dave's
> > original rationale applies here too.
> >
> > Cc: Dave Martin <Dave.Martin at arm.com>
> > Signed-off-by: Calvin Owens <jcalvinowens at gmail.com>
> > ---
>
> I think these should be addressed in bcachefs instead.

That seems reasonable to me. For clarity, I just happened to notice this
while doing allyesconfig cross builds for something entirely unrelated.

I'll take it up with them. It's not a big problem from my POV, the notes
don't cause -Werror builds to fail or anything like that.

Thanks,
Calvin

> While it's not the fault of bcachefs that the calling
> convention changed between gcc versions, have a look at
> the actual structure layout:
> 
> struct bch_val {
>         __u64           __nothing[0];
> };
> struct bpos {
>         /*
>          * Word order matches machine byte order - btree code treats a bpos as a
>          * single large integer, for search/comparison purposes
>          *
>          * Note that wherever a bpos is embedded in another on disk data
>          * structure, it has to be byte swabbed when reading in metadata that
>          * wasn't written in native endian order:
>          */
> #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
>         __u32           snapshot;
>         __u64           offset;
>         __u64           inode;
> #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
>         __u64           inode;
>         __u64           offset;         /* Points to end of extent - sectors */
>         __u32           snapshot;
> #else
> #error edit for your odd byteorder.
> #endif
> } __packed
> struct bch_backpointer {
>         struct bch_val          v;
>         __u8                    btree_id;
>         __u8                    level;
>         __u8                    data_type;
>         __u64                   bucket_offset:40;
>         __u32                   bucket_len;
>         struct bpos             pos;
> } __packed __aligned(8);
> 
> This is not something that should ever be passed by value
> into a function.
> 
>       Arnd


From krzysztof.kozlowski at linaro.org  Sun Feb 18 22:59:36 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 07:59:36 +0100
Subject: [PATCH] clk: constify the of_phandle_args argument of
 of_clk_provider
In-Reply-To: <e43727bd-d83d-4271-9871-ff995c8e7d03@tuxon.dev>
References: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
 <e43727bd-d83d-4271-9871-ff995c8e7d03@tuxon.dev>
Message-ID: <88de75cd-4069-4be6-9c4e-f32befa46d58@linaro.org>

On 19/02/2024 07:25, claudiu beznea wrote:
> 
> 
> On 08.02.2024 18:37, Krzysztof Kozlowski wrote:
>> None of the implementations of the get() and get_hw() callbacks of
>> "struct of_clk_provider" modify the contents of received of_phandle_args
>> pointer.  They treat it as read-only variable used to find the clock to
>> return.  Make obvious that implementations are not supposed to modify
>> the of_phandle_args, by making it a pointer to const.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>> ---
>>  drivers/clk/at91/pmc.c                        |  3 +-
>>  drivers/clk/at91/pmc.h                        |  3 +-
> 
> Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>

You understand there is no review for "part of patch"? You probably
meant Acked-by.

https://elixir.bootlin.com/linux/v6.8-rc5/source/Documentation/process/submitting-patches.rst#L544

Best regards,
Krzysztof



From kent.overstreet at linux.dev  Sun Feb 18 23:03:16 2024
From: kent.overstreet at linux.dev (Kent Overstreet)
Date: Mon, 19 Feb 2024 02:03:16 -0500
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <ZdL7_-2VCJqjn634@gmail.com>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
 <ZdL7_-2VCJqjn634@gmail.com>
Message-ID: <mtelhhn3z7qfo35odeb37doe3pqagesju46awcjnsyhq4xdk7t@ufoyklpskiyf>

On Sun, Feb 18, 2024 at 10:58:07PM -0800, Calvin Owens wrote:
> On Monday 02/19 at 07:21 +0100, Arnd Bergmann wrote:
> > On Mon, Feb 19, 2024, at 05:09, Calvin Owens wrote:
> > > 32-bit arm builds uniquely emit a lot of spam like this:
> > >
> > >     fs/bcachefs/backpointers.c: In function ?extent_matches_bp?:
> > >     fs/bcachefs/backpointers.c:15:13: note: parameter passing for 
> > > argument of type ?struct bch_backpointer? changed in GCC 9.1
> > >
> > > Apply the arm64 change from commit ebcc5928c5d9 ("arm64: Silence gcc
> > > warnings about arch ABI drift") to silence them. It seems like Dave's
> > > original rationale applies here too.
> > >
> > > Cc: Dave Martin <Dave.Martin at arm.com>
> > > Signed-off-by: Calvin Owens <jcalvinowens at gmail.com>
> > > ---
> >
> > I think these should be addressed in bcachefs instead.
> 
> That seems reasonable to me. For clarity, I just happened to notice this
> while doing allyesconfig cross builds for something entirely unrelated.
> 
> I'll take it up with them. It's not a big problem from my POV, the notes
> don't cause -Werror builds to fail or anything like that.

Considering we're not dynamic linking it's a non issue for us.


From mo.c.weber at gmail.com  Sun Feb 18 23:03:44 2024
From: mo.c.weber at gmail.com (Moritz Christian Weber)
Date: Mon, 19 Feb 2024 08:03:44 +0100
Subject: [PATCH] Staging: vc04_services: bcm2835-camera: fixed several
 brace coding style checks
In-Reply-To: <8fe8c4bf-5fa3-4bfc-9535-b48df12f80ff@moroto.mountain>
References: <20240215220647.4096-1-mo.c.weber@gmail.com> <8fe8c4bf-5fa3-4bfc-9535-b48df12f80ff@moroto.mountain>
Message-ID: <CAMn1LHB_XKNx_9VortrmxAmPrHxY--wp4eyUpg0GzjCjOvjv3A@mail.gmail.com>

Hi Dan,
thank for highlighting this. I have redone, split and resubmitted the
whole patch yesterday due to the issues Gregs patch bot raised. The
patches build, are checkpatched and also survive a last look. The two
issues that I introduced and which you raised have been not reproduced
in the new submission.

Best regards,
Moritz

On Mon, Feb 19, 2024 at 7:39?AM Dan Carpenter <dan.carpenter at linaro.org> wrote:
>
> On Thu, Feb 15, 2024 at 11:06:47PM +0100, Moritz C. Weber wrote:
> > @@ -406,12 +405,11 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
> >           is_capturing(dev)) {
> >               v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
> >                        "Grab another frame as buffer has EOS");
> > -             vchiq_mmal_port_parameter_set(
> > -                     instance,
> > -                     dev->capture.camera_port,
> > -                     MMAL_PARAMETER_CAPTURE,
> > -                     &dev->capture.frame_count,
> > -                     sizeof(dev->capture.frame_count));
> > +             vchiq_mmal_port_parameter_set(instance,
> > +                                           dev->capture.camera_port,
> > +                                           MMAL_PARAMETER_CAPTURE,
> > +                                           #N(#O(#O(#O(#O(&dev->capture.frame_count,
>                                               ^^^^^^^^^^^^^^^^
>
> Wut?
>
> > +                                           sizeof(dev->capture.frame_count));
> >       }
> >  }
> >
> > @@ -420,11 +418,11 @@ static int enable_camera(struct bcm2835_mmal_dev *dev)
> >       int ret;
> >
> >       if (!dev->camera_use_count) {
> > -             ret = vchiq_mmal_port_parameter_set(
> > -                     dev->instance,
> > -                     &dev->component[COMP_CAMERA]->control,
> > -                     MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num,
> > -                     sizeof(dev->camera_num));
> > +             ret = vchiq_mmal_port_parameter_set(dev->instance,
> > +                                                 &dev->component[COMP_CAMERA]->control,
> > +                                                 MMAL_PARAMETER_CAMERA_NUM,
> > +                                                 &dev->camera_num,
> > +                                                 **sizeof(dev->camera_num));
>
> Also Wut???
>
>
> regards,
> dan carpenter
>


From krzysztof.kozlowski at linaro.org  Sun Feb 18 23:11:00 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 08:11:00 +0100
Subject: [PATCH v3 02/16] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <znyqirhcxfigmenthyrkpivraj43g23gbbx2e774uy3oc375dd@c6pmvckv3gjs>
References: <20240216223654.1312880-1-sre@kernel.org>
 <20240216223654.1312880-3-sre@kernel.org>
 <e3b54b1c-79ab-4f25-8b42-fadc922c0d25@linaro.org>
 <znyqirhcxfigmenthyrkpivraj43g23gbbx2e774uy3oc375dd@c6pmvckv3gjs>
Message-ID: <ba71fe48-eabb-40c8-ba3f-6cb763508f23@linaro.org>

On 19/02/2024 02:59, Sebastian Reichel wrote:
> Hi Krzysztof,
> 
> On Sat, Feb 17, 2024 at 09:39:52AM +0100, Krzysztof Kozlowski wrote:
>> On 16/02/2024 23:34, Sebastian Reichel wrote:
>>> +properties:
>>> +  reg: true
>>
>> Your pattern in weim schema suggests you have here minItems: 2.
>> maxItems: can be 2 or 255.
> 
> Which part suggests minItems: 2?
> 
> It's minItems: 1 with each item consisting of two address cells and
> one size cell. Most in-tree users actually have exactly one item.
> The only exception seems to be arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts,
> which has "davicom,dm9000" using two reg items. Considering this is an
> external bus, any number is possible in theory. Should I keep it as is,
> or use minItems: 1, maxItems: 255 instead?

Hm, indeed, existing 'true' is fine.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 18 23:20:58 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 08:20:58 +0100
Subject: [PATCH v2 3/3] arm64: dts: hi3798cv200: add cache info
In-Reply-To: <20240218-cache-v2-3-1fd919e2bd3e@outlook.com>
References: <20240218-cache-v2-0-1fd919e2bd3e@outlook.com>
 <20240218-cache-v2-3-1fd919e2bd3e@outlook.com>
Message-ID: <4fdc2853-91f9-4b02-bfd6-68874baf1e9d@linaro.org>

On 18/02/2024 13:02, Yang Xiwen via B4 Relay wrote:
> From: Yang Xiwen <forbidden405 at outlook.com>
> 
> During boot, the kernel complains:
> 
> [    0.044029] cacheinfo: Unable to detect cache hierarchy for CPU 0
> 
> So add L1/L2 cache info to the dts according to the datasheet. (32KiB L1
> i-cache + 32 KiB L1 d-cache + 512 KiB L2 unified cache)


>  		cpu at 3 {
> @@ -52,9 +73,25 @@ cpu at 3 {
>  			device_type = "cpu";
>  			reg = <0x0 0x3>;
>  			enable-method = "psci";
> +			d-cache-size = <0x8000>; /* 32 KiB */
> +			d-cache-line-size = <64>;
> +			d-cache-sets = <128>;
> +			i-cache-size = <0x8000>; /* 32 KiB */
> +			i-cache-line-size = <64>;
> +			i-cache-sets = <256>;
> +			next-level-cache = <&L2_0>;
>  		};
>  	};
>  
> +	L2_0: l2-cache0 {

Do you have more than one? If not, then "l2-cache". If yes, then
"l2-cache-0".



Best regards,
Krzysztof



From sandor.yu at nxp.com  Sun Feb 18 23:24:25 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Mon, 19 Feb 2024 07:24:25 +0000
Subject: [EXT] Re: [PATCH v13 4/7] drm: bridge: Cadence: Add MHDP8501
 DP/HDMI driver
In-Reply-To: <3549548.iIbC2pHGDl@steina-w>
References: <cover.1707040881.git.Sandor.yu@nxp.com>
 <5bd01470cf971e2385ecd169c3d5ac659a020973.1707040881.git.Sandor.yu@nxp.com>
 <3549548.iIbC2pHGDl@steina-w>
Message-ID: <DB9PR04MB94522ED2DB0D32A0792EAB33F4512@DB9PR04MB9452.eurprd04.prod.outlook.com>

Hi Alexander,

Thanks for your comments,
get_edid function will be replace by edid_read as community update in the next version.

B.R
Sandor

>
>
> Hi Sandor,
>
> thanks for the update.
>
> Am Sonntag, 4. Februar 2024, 11:21:49 CET schrieb Sandor Yu:
> > Add a new DRM DisplayPort and HDMI bridge driver for Candence
> MHDP8501
> > used in i.MX8MQ SOC. MHDP8501 could support HDMI or DisplayPort
> > standards according embedded Firmware running in the uCPU.
> >
> > For iMX8MQ SOC, the DisplayPort/HDMI FW was loaded and activated by
> > SOC's ROM code. Bootload binary included respective specific firmware
> > is required.
> >
> > Driver will check display connector type and then load the
> > corresponding driver.
> >
> > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> > v12->v13:
> > - Explicitly include linux/platform_device.h for cdns-mhdp8501-core.c
> > - Fix build warning
> > - Order bit bpc and color_space in descending shit.
> >
> > v11->v12:
> > - Replace DRM_INFO with dev_info or dev_warn.
> > - Replace DRM_ERROR with dev_err.
> > - Return ret when cdns_mhdp_dpcd_read failed in function
> > cdns_dp_aux_transferi(). - Remove unused parmeter in function
> > cdns_dp_get_msa_misc
> >   and use two separate variables for color space and bpc.
> > - Add year 2024 to copyright.
> >
> >  drivers/gpu/drm/bridge/cadence/Kconfig        |  16 +
> >  drivers/gpu/drm/bridge/cadence/Makefile       |   2 +
> >  .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 316 ++++++++
> >  .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 365 +++++++++
> >  .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 699
> ++++++++++++++++++
> >  .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 679
> +++++++++++++++++
> >  6 files changed, 2077 insertions(+)
> >  create mode 100644
> > drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> >  create mode 100644
> > drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
> >  create mode 100644
> drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> >  create mode 100644
> > drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> >
> > [snip]
> > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> > b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c new file mode
> > 100644 index 0000000000000..0117cddb85694
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> > @@ -0,0 +1,699 @@
> > [snip]
> > +
> > +const struct drm_bridge_funcs cdns_dp_bridge_funcs = {
> > +     .attach = cdns_dp_bridge_attach,
> > +     .detect = cdns_dp_bridge_detect,
> > +     .get_edid = cdns_dp_bridge_get_edid,
>
> Please note that with commits d807ad80d811b ("drm/bridge: add
> ->edid_read hook and drm_bridge_edid_read()") and 27b8f91c08d99
> ("drm/bridge: remove ->get_edid
> callback") the API has slightly changed meanwhile.
>
> > +     .mode_valid = cdns_dp_bridge_mode_valid,
> > +     .atomic_enable = cdns_dp_bridge_atomic_enable,
> > +     .atomic_disable = cdns_dp_bridge_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, };
> > diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> > b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c new file mode
> > 100644 index 0000000000000..e6ed13b9f9ca3
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> > @@ -0,0 +1,679 @@
> > [snip]
> > +
> > +const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
> > +     .attach = cdns_hdmi_bridge_attach,
> > +     .detect = cdns_hdmi_bridge_detect,
> > +     .get_edid = cdns_hdmi_bridge_get_edid,
>
> Please note that with commits d807ad80d811b ("drm/bridge: add
> ->edid_read hook and drm_bridge_edid_read()") and 27b8f91c08d99
> ("drm/bridge: remove ->get_edid
> callback") the API has slightly changed meanwhile.
>
> > +     .mode_valid = cdns_hdmi_bridge_mode_valid,
> > +     .mode_fixup = cdns_hdmi_bridge_mode_fixup,
> > +     .atomic_enable = cdns_hdmi_bridge_atomic_enable,
> > +     .atomic_disable = cdns_hdmi_bridge_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, };
>
> Please rebase your patch series, thanks.
>
> Best regards,
> Alexander
> --
> TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht M?nchen, HRB 105018
> Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> http://www.tq-/
> group.com%2F&data=05%7C02%7CSandor.yu%40nxp.com%7Cfc532fc168004f
> 07439308dc2ebdf280%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%
> 7C638436640551238910%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAw
> MDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C
> &sdata=E1%2Fd8VTcDiXL3uhGDlHz7synQjRD%2BN1hDoHlbB72RiY%3D&reser
> ved=0
>



From krzysztof.kozlowski at linaro.org  Sun Feb 18 23:31:30 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 08:31:30 +0100
Subject: [PATCH v5 02/18] arm64: defconfig: enable ath12k as a module
In-Reply-To: <20240216203215.40870-3-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-3-brgl@bgdev.pl>
Message-ID: <71e9a57e-8be3-4213-9822-45dfc5eb7ceb@linaro.org>

On 16/02/2024 21:31, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> Build the ath12k driver as a module for arm64 default config.

This we see from the diff. Please tell us "why", e.g. "Board foo with
Qualcomm baz uses it."

Also this should not be in these series. It only makes the
power-sequencing patchset bigger, without any real reason.


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 18 23:32:07 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 08:32:07 +0100
Subject: [PATCH v5 03/18] dt-bindings: regulator: describe the PMU module
 of the QCA6390 package
In-Reply-To: <CAMRc=Mf9Sro4kM_Jn8_v=cyO5PxCp6AnBdeS9XspqVDGKdA_Dg@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-4-brgl@bgdev.pl>
 <ZdDVNbjv60G9YUNy@finisterre.sirena.org.uk>
 <CAMRc=Mf9Sro4kM_Jn8_v=cyO5PxCp6AnBdeS9XspqVDGKdA_Dg@mail.gmail.com>
Message-ID: <7c1327c0-d0ea-4797-a5fa-5844ba46bf53@linaro.org>

On 17/02/2024 19:32, Bartosz Golaszewski wrote:
> On Sat, Feb 17, 2024 at 4:48?PM Mark Brown <broonie at kernel.org> wrote:
>>
>> On Fri, Feb 16, 2024 at 09:32:00PM +0100, Bartosz Golaszewski wrote:
>>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>>
>>> The QCA6390 package contains discreet modules for WLAN and Bluetooth. They
>>> are powered by the Power Management Unit (PMU) that takes inputs from the
>>> host and provides LDO outputs. This document describes this module.
>>
>> 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.
> 
> Mark,
> 
> This is quite vague, could you elaborate? I have no idea what is wrong
> with this patch.

Use subject prefixes matching the subsystem. You can get them for
example with `git log --oneline -- DIRECTORY_OR_FILE` on the directory
your patch is touching.

Best regards,
Krzysztof



From claudiu.beznea at tuxon.dev  Sun Feb 18 23:33:53 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Mon, 19 Feb 2024 09:33:53 +0200
Subject: [PATCH] clk: constify the of_phandle_args argument of
 of_clk_provider
In-Reply-To: <88de75cd-4069-4be6-9c4e-f32befa46d58@linaro.org>
References: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org>
 <e43727bd-d83d-4271-9871-ff995c8e7d03@tuxon.dev>
 <88de75cd-4069-4be6-9c4e-f32befa46d58@linaro.org>
Message-ID: <e6c6e825-42dd-4f2d-8329-f7b3e09bb8a9@tuxon.dev>



On 19.02.2024 08:59, Krzysztof Kozlowski wrote:
> On 19/02/2024 07:25, claudiu beznea wrote:
>>
>>
>> On 08.02.2024 18:37, Krzysztof Kozlowski wrote:
>>> None of the implementations of the get() and get_hw() callbacks of
>>> "struct of_clk_provider" modify the contents of received of_phandle_args
>>> pointer.  They treat it as read-only variable used to find the clock to
>>> return.  Make obvious that implementations are not supposed to modify
>>> the of_phandle_args, by making it a pointer to const.
>>>
>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>> ---
>>>  drivers/clk/at91/pmc.c                        |  3 +-
>>>  drivers/clk/at91/pmc.h                        |  3 +-
>>
>> Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
> 
> You understand there is no review for "part of patch"? You probably
> meant Acked-by.

Sure... Here it is:
Acked-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>

> 
> https://elixir.bootlin.com/linux/v6.8-rc5/source/Documentation/process/submitting-patches.rst#L544
> 
> Best regards,
> Krzysztof
> 


From krzysztof.kozlowski at linaro.org  Sun Feb 18 23:34:11 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 08:34:11 +0100
Subject: [PATCH v5 03/18] dt-bindings: regulator: describe the PMU module
 of the QCA6390 package
In-Reply-To: <20240216203215.40870-4-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-4-brgl@bgdev.pl>
Message-ID: <55770080-9b27-4e04-a78e-7a7e508f37c2@linaro.org>

On 16/02/2024 21:32, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> The QCA6390 package contains discreet modules for WLAN and Bluetooth. They
> are powered by the Power Management Unit (PMU) that takes inputs from the
> host and provides LDO outputs. This document describes this module.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---
>  .../bindings/regulator/qcom,qca6390-pmu.yaml  | 166 ++++++++++++++++++
>  1 file changed, 166 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml
> 

This matches our internal discussions and how we see the QCA6390 power
handling based on datasheet.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 18 23:34:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 08:34:38 +0100
Subject: [PATCH v5 04/18] dt-bindings: net: bluetooth: qualcomm: describe
 regulators for QCA6390
In-Reply-To: <20240216203215.40870-5-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-5-brgl@bgdev.pl>
Message-ID: <e5adbea4-1706-46b1-9f45-6b3c3b5f0954@linaro.org>

On 16/02/2024 21:32, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> QCA6390 has a compatible listed in the bindings but is missing the
> regulators description. Add the missing supply property and list the
> required ones in the allOf section.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 18 23:38:12 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 08:38:12 +0100
Subject: [PATCH v5 06/18] dt-bindings: new: wireless: describe the ath12k
 PCI module
In-Reply-To: <20240216203215.40870-7-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-7-brgl@bgdev.pl>
Message-ID: <dcec7bac-410f-4063-aa45-da2cde7032bf@linaro.org>

On 16/02/2024 21:32, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> Add device-tree bindings for the ATH12K module found in the WCN7850
> package.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---
>  .../net/wireless/qcom,ath12k-pci.yaml         | 103 ++++++++++++++++++
>  1 file changed, 103 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
> new file mode 100644
> index 000000000000..063c576b99a0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml

This means there can be ath12k over AHB or some other bus, which would
be quite different and not fit together in one schema file. It's that
the case?

> @@ -0,0 +1,103 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (c) 2024 Linaro Limited
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/wireless/qcom,ath12k-pci.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm Technologies ath12k wireless devices (PCIe)
> +
> +maintainers:
> +  - Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> +
> +description: |

Do not need '|' unless you need to preserve formatting.

> +  Qualcomm Technologies IEEE 802.11ax PCIe devices
> +
> +properties:
> +  compatible:
> +    enum:
> +      - pci17cb,1107  # WCN7850
> +
> +  reg:
> +    maxItems: 1
> +
> +  enable-gpios:
> +    maxItems: 1
> +    description: GPIO line enabling the WLAN module
> +
> +  vdd-supply:
> +    description: VDD supply regulator handle
> +
> +  vddio-supply:
> +    description: VDD_IO supply regulator handle
> +
> +  vddio1p2-supply:
> +    description: VDD_IO_1P2 supply regulator handle
> +
> +  vddaon-supply:
> +    description: VDD_AON supply regulator handle
> +
> +  vdddig-supply:
> +    description: VDD_DIG supply regulator handle
> +
> +  vddrfa1p2-supply:
> +    description: VDD_RFA_1P2 supply regulator handle
> +
> +  vddrfa1p8-supply:
> +    description: VDD_PCIE_1P8 supply regulator handle
> +
> +  clocks:
> +    maxItems: 1
> +    description:
> +      Reference clock phandle

These three could be just:
items:
  - description: Reference clock

(phandle is redundant in this context)

Best regards,
Krzysztof



From dan.carpenter at linaro.org  Sun Feb 18 23:38:30 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Mon, 19 Feb 2024 10:38:30 +0300
Subject: [PATCH v2 0/8] Staging: vc04_services: bcm2835-camera: Fix code
 style checks
In-Reply-To: <20240217211246.28882-1-mo.c.weber@gmail.com>
References: <20240217211246.28882-1-mo.c.weber@gmail.com>
Message-ID: <510574c4-ad26-4fc2-93c4-7b67737f8eb1@moroto.mountain>

On Sat, Feb 17, 2024 at 10:12:38PM +0100, Moritz C. Weber wrote:
> Resubmit these patches to fix multiple code style checks for better readability, consistency, and to address errors indicated by Gregs patch bot
> 
> Moritz C. Weber (8):
>   Staging: vc04_services: bcm2835-camera: fix brace code style check
>   Staging: vc04_services: bcm2835-camera: fix brace code style check
>   Staging: vc04_services: bcm2835-camera: fix brace code style check
>   Staging: vc04_services: bcm2835-camera: fix brace code style check
>   Staging: vc04_services: bcm2835-camera: fix brace code style check
>   Staging: vc04_services: bcm2835-camera: fix blank line style check
>   Staging: vc04_services: bcm2835-camera: fix brace code style check
>   Staging: vc04_services: bcm2835-camera: fix brace code style check

These are automatically rejected because you sent 8 patches with the
same subject.  But really they should just be one patch.  In v1 Greg
complained that you were changing a bunch of random stuff.  It's not
clear what was going on there because it was random text and there was
no way it would compile.

Was it an AI generated patch or what one earth happened?

Anyway, that was the issue, not that you need to break up the patch line
by line and send each line as a separate patch.

regards,
dan carpenter




From krzysztof.kozlowski at linaro.org  Sun Feb 18 23:44:03 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 08:44:03 +0100
Subject: [PATCH] ARM: dts: exynos4212-tab3: limit usable memory range
In-Reply-To: <20240217-tab3-limit-usable-memory-range-v1-1-49cc9c86a5cc@gmail.com>
References: <20240217-tab3-limit-usable-memory-range-v1-1-49cc9c86a5cc@gmail.com>
Message-ID: <15ab6aa6-fb30-4970-9c50-546afb933e03@linaro.org>

On 17/02/2024 20:02, Artur Weber wrote:
> The stock bootloader on the Samsung Galaxy Tab 3 8.0 provides an
> incorrect available memory range over ATAG_MEM. Limit the usable
> memory in the DTS to prevent it from doing so, without having to
> disable ATAG support.
> 
> Signed-off-by: Artur Weber <aweber.kernel at gmail.com>
> ---
>  arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
> index e5254e32aa8f..9bc05961577d 100644
> --- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
> +++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
> @@ -45,6 +45,12 @@ chosen {
>  		/* Default S-BOOT bootloader loads initramfs here */
>  		linux,initrd-start = <0x42000000>;
>  		linux,initrd-end = <0x42800000>;
> +
> +		/*
> +		 * Stock bootloader provides incorrect memory size in ATAG_MEM;
> +		 * override it here
> +		 */
> +		linux,usable-memory-range = <0x40000000 0x3fc00000>;

Applied and dropped:
 chosen: linux,usable-memory-range:0: [4611686019496935424] is too short

Does not look you tested the bindings.

Please observe that we have dedicated subsystem profile since a release:
https://www.kernel.org/doc/html/latest/process/maintainers.html#arm-samsung-s3c-s5p-and-exynos-arm-architectures

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 18 23:50:33 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 08:50:33 +0100
Subject: [PATCH] ARM: dts: exynos4412-*: decrease memory to account for
 unusable region
In-Reply-To: <20240217-exynos4-memsize-fix-v1-1-7858e9c5f844@gmail.com>
References: <20240217-exynos4-memsize-fix-v1-1-7858e9c5f844@gmail.com>
Message-ID: <170832903316.9472.8907322109403267852.b4-ty@linaro.org>


On Sat, 17 Feb 2024 19:22:40 +0100, Artur Weber wrote:
> The last 4 MiB of RAM on those devices is likely used by trustzone
> firmware, and is unusable under Linux. Change the device tree memory
> node accordingly.
> 
> The proprietary bootloader (S-BOOT) passes these memory ranges through
> ATAG_MEM; this change allows us to have the correct memory ranges
> without relying on ATAG_MEM.
> 
> [...]

Applied, thanks!

[1/1] ARM: dts: exynos4412-*: decrease memory to account for unusable region
      https://git.kernel.org/krzk/linux/c/5fb1252944fc3bba4a1026adaa9d150cfe8a3e16

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From brgl at bgdev.pl  Sun Feb 18 23:56:57 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 08:56:57 +0100
Subject: [PATCH v5 02/18] arm64: defconfig: enable ath12k as a module
In-Reply-To: <71e9a57e-8be3-4213-9822-45dfc5eb7ceb@linaro.org>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-3-brgl@bgdev.pl>
 <71e9a57e-8be3-4213-9822-45dfc5eb7ceb@linaro.org>
Message-ID: <CAMRc=Md1PzoZFDWHWRufktmMiBE0Dp7eYhecpwuaS3AW-Y_g=w@mail.gmail.com>

On Mon, Feb 19, 2024 at 8:31?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 16/02/2024 21:31, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > Build the ath12k driver as a module for arm64 default config.
>
> This we see from the diff. Please tell us "why", e.g. "Board foo with
> Qualcomm baz uses it."
>
> Also this should not be in these series. It only makes the
> power-sequencing patchset bigger, without any real reason.
>
>
> Best regards,
> Krzysztof
>

Got it, I will resend it separately.

Bart


From arnd at arndb.de  Sun Feb 18 23:56:59 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 19 Feb 2024 08:56:59 +0100
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <k6cclnrqu2h6mh4wb33hpakhfasq7jec7dnbaiaxlpw525adan@cor5l3bi35u2>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
 <k6cclnrqu2h6mh4wb33hpakhfasq7jec7dnbaiaxlpw525adan@cor5l3bi35u2>
Message-ID: <4997c865-fc6f-4d8c-b73f-a649b6257ed0@app.fastmail.com>

On Mon, Feb 19, 2024, at 07:25, Kent Overstreet wrote:
> On Mon, Feb 19, 2024 at 07:21:11AM +0100, Arnd Bergmann wrote:
>> 
>> This is not something that should ever be passed by value
>> into a function.
>
> Why?

Mostly because of the size, as 8 registers (on 32-bit) or
4 registers (on 64 bit) mean that even in the best case
passing these through argument registers is going to cause
spills if anything else gets passed as well. Passing them
through the stack in turn requires the same number of
registers to get copied in and out for every call, which
in turn can evict other registers that hold local variables.

On top of that, you have all the complications that make
passing them inconsistent and possibly worse depending
on how exactly a particular ABI passes structures:

- If each struct member is passed individually, you always
  need eight registers
- bitfields tend to get the compiler into corner cases
  that are not as optimized
- __u64 members tend to need even/odd register pairs on
  many 32-bit architectures.
- on big-endian kernels, two __u64 members are
  misaligned, which causes them to be in two halves
  of separate registers if the struct gets passed as
  four 64-bit regs.
  
I can't think of any platform where passing the structure
through a const pointer ends up worse than passing
by value.

    Arnd


From sinthu.raja at mistralsolutions.com  Sun Feb 18 23:59:32 2024
From: sinthu.raja at mistralsolutions.com (Sinthu Raja)
Date: Mon, 19 Feb 2024 13:29:32 +0530
Subject: [PATCH V2] arm64: dts: ti: k3-am68-sk-som: Add support for OSPI flash
Message-ID: <20240219075932.6458-1-sinthu.raja@ti.com>

From: Sinthu Raja <sinthu.raja at ti.com>

AM68 SK has an OSPI NOR flash on its SOM connected to OSPI0 instance.
Enable support for the same. Also, describe the OSPI flash partition
information through the device tree, according to the offsets in the
bootloader.

Signed-off-by: Sinthu Raja <sinthu.raja at ti.com>
---

Changes in V2:
=============
1. Address review comments
   a. remove pin E20, which is not connected.

V1: https://patchwork.kernel.org/project/linux-arm-kernel/patch/20240206092334.30307-1-sinthu.raja at ti.com/

 arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi | 78 ++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
index 0f4a5da0ebc4..afaf702cfc9d 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
@@ -130,6 +130,24 @@ rtos_ipc_memory_region: ipc-memories at a8000000 {
 	};
 };
 
+&wkup_pmx0 {
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default {
+		pinctrl-single,pins = <
+			J721S2_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (D19) MCU_OSPI0_CLK */
+			J721S2_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F15) MCU_OSPI0_CSn0 */
+			J721S2_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (C19) MCU_OSPI0_D0 */
+			J721S2_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (F16) MCU_OSPI0_D1 */
+			J721S2_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (G15) MCU_OSPI0_D2 */
+			J721S2_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (F18) MCU_OSPI0_D3 */
+			J721S2_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (E19) MCU_OSPI0_D4 */
+			J721S2_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (G19) MCU_OSPI0_D5 */
+			J721S2_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (F19) MCU_OSPI0_D6 */
+			J721S2_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (F20) MCU_OSPI0_D7 */
+			J721S2_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (E18) MCU_OSPI0_DQS */
+		>;
+	};
+};
+
 &wkup_pmx2 {
 	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
 		pinctrl-single,pins = <
@@ -152,6 +170,66 @@ eeprom at 51 {
 	};
 };
 
+&ospi0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <4>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "ospi.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition at 80000 {
+				label = "ospi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition at 280000 {
+				label = "ospi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition at 680000 {
+				label = "ospi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition at 6c0000 {
+				label = "ospi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition at 800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition at 3fc0000 {
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+};
+
 &mailbox0_cluster0 {
 	status = "okay";
 	interrupts = <436>;
-- 
2.36.1



From horatiu.vultur at microchip.com  Mon Feb 19 00:00:43 2024
From: horatiu.vultur at microchip.com (Horatiu Vultur)
Date: Mon, 19 Feb 2024 09:00:43 +0100
Subject: [PATCH net v3] net: sparx5: Add spinlock for frame transmission from CPU
Message-ID: <20240219080043.1561014-1-horatiu.vultur@microchip.com>

Both registers used when doing manual injection or fdma injection are
shared between all the net devices of the switch. It was noticed that
when having two process which each of them trying to inject frames on
different ethernet ports, that the HW started to behave strange, by
sending out more frames then expected. When doing fdma injection it is
required to set the frame in the DCB and then make sure that the next
pointer of the last DCB is invalid. But because there is no locks for
this, then easily this pointer between the DCB can be broken and then it
would create a loop of DCBs. And that means that the HW will
continuously transmit these frames in a loop. Until the SW will break
this loop.
Therefore to fix this issue, add a spin lock for when accessing the
registers for manual or fdma injection.

Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>
Reviewed-by: Daniel Machon <daniel.machon at microchip.com>
Fixes: f3cad2611a77 ("net: sparx5: add hostmode with phylink support")
---
v2->v3:
- add missing fix tag as it is targeting net
v1->v2:
- target net instead of net-next
---
 drivers/net/ethernet/microchip/sparx5/sparx5_main.c   | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_main.h   | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_packet.c | 2 ++
 3 files changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index d1f7fc8b1b71a..3c066b62e6894 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -757,6 +757,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, sparx5);
 	sparx5->pdev = pdev;
 	sparx5->dev = &pdev->dev;
+	spin_lock_init(&sparx5->tx_lock);
 
 	/* Do switch core reset if available */
 	reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index 6f565c0c0c3dc..316fed5f27355 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -280,6 +280,7 @@ struct sparx5 {
 	int xtr_irq;
 	/* Frame DMA */
 	int fdma_irq;
+	spinlock_t tx_lock; /* lock for frame transmission */
 	struct sparx5_rx rx;
 	struct sparx5_tx tx;
 	/* PTP */
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
index 6db6ac6a3bbc2..ac7e1cffbcecf 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
@@ -244,10 +244,12 @@ netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	skb_tx_timestamp(skb);
+	spin_lock(&sparx5->tx_lock);
 	if (sparx5->fdma_irq > 0)
 		ret = sparx5_fdma_xmit(sparx5, ifh, skb);
 	else
 		ret = sparx5_inject(sparx5, ifh, skb, dev);
+	spin_unlock(&sparx5->tx_lock);
 
 	if (ret == -EBUSY)
 		goto busy;
-- 
2.34.1



From vigneshr at ti.com  Mon Feb 19 00:10:03 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Mon, 19 Feb 2024 13:40:03 +0530
Subject: [PATCH V2] arm64: dts: ti: k3-am68-sk-som: Add support for OSPI
 flash
In-Reply-To: <20240219075932.6458-1-sinthu.raja@ti.com>
References: <20240219075932.6458-1-sinthu.raja@ti.com>
Message-ID: <623c9ed1-85f2-47a3-9ca2-8c7fa5b2251b@ti.com>



On 19/02/24 13:29, Sinthu Raja wrote:
> From: Sinthu Raja <sinthu.raja at ti.com>
> 
> AM68 SK has an OSPI NOR flash on its SOM connected to OSPI0 instance.
> Enable support for the same. Also, describe the OSPI flash partition
> information through the device tree, according to the offsets in the
> bootloader.
> 
> Signed-off-by: Sinthu Raja <sinthu.raja at ti.com>
> ---
> 
> Changes in V2:
> =============
> 1. Address review comments
>    a. remove pin E20, which is not connected.
> 
> V1: https://patchwork.kernel.org/project/linux-arm-kernel/patch/20240206092334.30307-1-sinthu.raja at ti.com/
> 
>  arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi | 78 ++++++++++++++++++++++
>  1 file changed, 78 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
> index 0f4a5da0ebc4..afaf702cfc9d 100644
> --- a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
> @@ -130,6 +130,24 @@ rtos_ipc_memory_region: ipc-memories at a8000000 {
>  	};
>  };
>  
> +&wkup_pmx0 {
> +	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default {

pinmux nodes should end with -pins                        ^^^^^^


Please run make dtbs_check and fix the issues pointed out

> +		pinctrl-single,pins = <
> +			J721S2_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (D19) MCU_OSPI0_CLK */
> +			J721S2_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F15) MCU_OSPI0_CSn0 */
> +			J721S2_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (C19) MCU_OSPI0_D0 */
> +			J721S2_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (F16) MCU_OSPI0_D1 */
> +			J721S2_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (G15) MCU_OSPI0_D2 */
> +			J721S2_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (F18) MCU_OSPI0_D3 */
> +			J721S2_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (E19) MCU_OSPI0_D4 */
> +			J721S2_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (G19) MCU_OSPI0_D5 */
> +			J721S2_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (F19) MCU_OSPI0_D6 */
> +			J721S2_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (F20) MCU_OSPI0_D7 */
> +			J721S2_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (E18) MCU_OSPI0_DQS */
> +		>;
> +	};
> +};
> +
>  &wkup_pmx2 {
>  	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
>  		pinctrl-single,pins = <
> @@ -152,6 +170,66 @@ eeprom at 51 {
>  	};
>  };
>  
> +&ospi0 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
> +
> +	flash at 0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0x0>;
> +		spi-tx-bus-width = <8>;
> +		spi-rx-bus-width = <8>;
> +		spi-max-frequency = <25000000>;
> +		cdns,tshsl-ns = <60>;
> +		cdns,tsd2d-ns = <60>;
> +		cdns,tchsh-ns = <60>;
> +		cdns,tslch-ns = <60>;
> +		cdns,read-delay = <4>;
> +
> +		partitions {
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			partition at 0 {
> +				label = "ospi.tiboot3";
> +				reg = <0x0 0x80000>;

Should this be 1MB similar to comment at [0]

[0] lore.kernel.org/r/0ca01a1b-8956-40dd-8286-77276e021633 at ti.com

> +			};
> +
> +			partition at 80000 {
> +				label = "ospi.tispl";
> +				reg = <0x80000 0x200000>;
> +			};
> +
> +			partition at 280000 {
> +				label = "ospi.u-boot";
> +				reg = <0x280000 0x400000>;
> +			};
> +
> +			partition at 680000 {
> +				label = "ospi.env";
> +				reg = <0x680000 0x40000>;
> +			};
> +
> +			partition at 6c0000 {
> +				label = "ospi.env.backup";
> +				reg = <0x6c0000 0x40000>;
> +			};
> +
> +			partition at 800000 {
> +				label = "ospi.rootfs";
> +				reg = <0x800000 0x37c0000>;
> +			};
> +
> +			partition at 3fc0000 {
> +				label = "ospi.phypattern";
> +				reg = <0x3fc0000 0x40000>;
> +			};
> +		};
> +	};
> +};
> +
>  &mailbox0_cluster0 {
>  	status = "okay";
>  	interrupts = <436>;

-- 
Regards
Vignesh


From krzysztof.kozlowski at linaro.org  Mon Feb 19 00:13:52 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 09:13:52 +0100
Subject: [PATCH v3 1/2] dt-bindings: arm: qcom,coresight-tpdm: Rename
 qcom,dsb-element-size
In-Reply-To: <20240218094322.22470-2-quic_jinlmao@quicinc.com>
References: <20240218094322.22470-1-quic_jinlmao@quicinc.com>
 <20240218094322.22470-2-quic_jinlmao@quicinc.com>
Message-ID: <433e89c1-9522-4bfa-8c87-a32e7e62aca8@linaro.org>

On 18/02/2024 10:43, Mao Jinlong wrote:
> Change qcom,dsb-element-size to qcom,dsb-element-bits as the unit is
> bit. There is no tpdm node in any DT as of now. Make this change before

You should say why. "What" we see from the diff. I keep repeating this
like a broken record...

This applies to all your patches. Future as well.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Mon Feb 19 00:14:25 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 09:14:25 +0100
Subject: [PATCH v2 1/2] arm64: dts: rockchip: Add devicetree support for
 TB-RK3588X board
In-Reply-To: <20240218085314.658223-1-zhangzj@rock-chips.com>
References: <20240218065407.652213-1-zhangzj@rock-chips.com>
 <20240218085314.658223-1-zhangzj@rock-chips.com>
Message-ID: <335472bf-7371-4555-bddd-97bb34f73bc3@linaro.org>

On 18/02/2024 09:53, Elon Zhang wrote:
> Add board file for Rockchip Toybrick TB-RK3588X board.
> 
> Specification:
> 	Rockchip Rk3588 SoC
> 	4x ARM Cortex-A76, 4x ARM Cortex-A55
> 	8/16GB Memory LPDDR4x
> 	Mali G610MC4 GPU
> 	2? MIPI-CSI0 Connector

Do not attach (thread) your patchsets to some other threads (unrelated
or older versions). This buries them deep in the mailbox and might
interfere with applying entire sets.

Best regards,
Krzysztof



From neil.armstrong at linaro.org  Mon Feb 19 00:14:36 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 19 Feb 2024 09:14:36 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
Message-ID: <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org>

On 18/02/2024 13:53, Dmitry Baryshkov wrote:
> On Fri, 16 Feb 2024 at 22:33, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>>
>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>
>> First, I'd like to apologize for the somewhat chaotic previous iterations
>> of this series and improper versioning which was rightfully pointed out
>> to me. I figured that the scope changed so much that it didn't make sense
>> to consider previous submissions part of the same series as the original
>> RFC but others thought otherwise so this one becomes v5 and I'll keep the
>> versioning going forward.
>>
>> This is the summary of the work so far:
>>
>> v1: Original RFC:
>>
>> https://lore.kernel.org/lkml/20240104130123.37115-1-brgl at bgdev.pl/T/
>>
>> v2: First real patch series (should have been PATCH v2) adding what I
>>      referred to back then as PCI power sequencing:
>>
>> https://lore.kernel.org/linux-arm-kernel/2024021413-grumbling-unlivable-c145 at gregkh/T/
>>
>> v3: RFC for the DT representation of the PMU supplying the WLAN and BT
>>      modules inside the QCA6391 package (was largely separate from the
>>      series but probably should have been called PATCH or RFC v3):
>>
>> https://lore.kernel.org/all/CAMRc=Mc+GNoi57eTQg71DXkQKjdaoAmCpB=h2ndEpGnmdhVV-Q at mail.gmail.com/T/
>>
>> v4: Second attempt at the full series with changed scope (introduction of
>>      the pwrseq subsystem, should have been RFC v4)
>>
>> https://lore.kernel.org/lkml/20240201155532.49707-1-brgl at bgdev.pl/T/
>>
>> ===
>>
>> With that out of the way, I'd like to get down to explaining the two
>> problems I'm trying to solve.
>>
>> Problem statement #1: Dynamic bus chicken-and-egg problem.
>>
>> Certain on-board PCI devices need to be powered up before they are can be
>> detected but their PCI drivers won't get bound until the device is
>> powered-up so enabling the relevant resources in the PCI device driver
>> itself is impossible.
>>
>> Problem statement #2: Sharing inter-dependent resources between devices.
>>
>> Certain devices that use separate drivers (often on different busses)
>> share resources (regulators, clocks, etc.). Typically these resources
>> are reference-counted but in some cases there are additional interactions
>> between them to consider, for example specific power-up sequence timings.
>>
>> ===
>>
>> The reason for tackling both of these problems in a single series is the
>> fact the the platform I'm working on - Qualcomm RB5 - deals with both and
>> both need to be addressed in order to enable WLAN and Bluetooth support
>> upstream.
>>
>> The on-board WLAN/BT package - QCA6391 - has a Power Management Unit that
>> takes inputs from the host and exposes LDO outputs consumed by the BT and
>> WLAN modules which can be powered-up and down independently. However
>> a delay of 100ms must be respected between enabling the BT- and
>> WLAN-enable GPIOs[*].
>>
>> ===
>>
>> This series is logically split into several sections. I'll go
>> patch-by-patch and explain each step.
>>
>> Patch 1/18:
>>
>> This is a commit taken from the list by Jonathan Cameron that adds
>> a __free() helper for OF nodes. Not strictly related to the series but
>> until said commit ends in next, I need to carry it with this series.
>>
>> Patch 2/18:
>>
>> This enables the ath12k PCI module in arm64 defconfig as Qualcomm sm8650
>> and sm8550 reference platforms use it in the WCN7850 module.
>>
>> Patches 3/18-6/18:
>>
>> These contain all relevant DT bindings changes. We add new documents for
>> the QCA6390 PMU and ATH12K devices as well as extend the bindings for the
>> Qualcomm Bluetooth and ATH11K modules with regulators used by them in
>> QCA6390.
>>
>> Patches 7/18-9/18:
>>
>> These contain changes to device-tree sources for the three platforms we
>> work with in this series. As the WCN7850 module doesn't require any
>> specific timings introducing dependencies between the Bluetooth and WLAN
>> modules, while the QCA6390 does, we take two different approaches to how
>> me model them in DT.
>>
>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
>> necessary. The BT and WLAN devices on the device-tree are represented as
>> consuming the inputs (relevant to the functionality of each) of the PMU
>> directly.
> 
> We are describing the hardware. From the hardware point of view, there
> is a PMU. I think at some point we would really like to describe all
> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).

While I agree with older WiFi+BT units, I don't think it's needed for
WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
transparent.

> 
>> For QCA6390 on RB5 we add the PMU node as a platform device. It consumes
>> regulators and GPIOs from the host and exposed regulators consumer in turn
>> by the BT and WLAN modules. This represents the internal structure of the
>> package.
>>
>> Patches 10/18-14/18:
>>
>> These contain the bulk of the PCI changes for this series. We introduce
>> a simple framework for powering up PCI devices before detecting them on
>> the bus and the first user of this library in the form of the WCN7850 PCI
>> power control driver.
>>
>> The general approach is as follows: PCI devices that need special
>> treatment before they can be powered up, scanned and bound to their PCI
>> drivers must be described on the device-tree as child nodes of the PCI
>> port node. These devices will be instantiated on the platform bus. They
>> will in fact be generic platform devices with the compatible of the form
>> used for PCI devices already upstream ("pci<vendor ID>,<device ID">). We
>> add a new directory under drivers/pci/pwrctl/ that contains PCI pwrctl
>> drivers. These drivers are platform drivers that will now be matched
>> against the devices instantiated from port children just like any other
>> platform pairs.
>>
>> Both the power control platform device *AND* the associated PCI device
>> reuse the same OF node and have access to the same properties. The goal
>> of the platform driver is to request and bring up any required resources
>> and let the pwrctl framework know that it's now OK to rescan the bus and
>> detect the devices. When the device is bound, we are notified about it
>> by the PCI bus notifier event and can establish a device link between the
>> power control device and the PCI device so that any future extension for
>> power-management will already be able to work with the correct hierachy.
>>
>> The reusing of the OF node is the reason for the small changes to the PCI
>> OF core: as the bootloader can possibly leave the relevant regulators on
>> before booting linux, the PCI device can be detected before its platform
>> abstraction is probed. In this case, we find that device first and mark
>> its OF node as reused. The pwrctl framework handles the opposite case
>> (when the PCI device is detected only after the platform driver
>> successfully enabled it).
>>
>> Patches 15/18-16/18:
>>
>> These add a relatively simple power sequencing subsystem and the first
>> driver using it: the pwrseq module for the QCA6390 PMU.
>>
>> For the record: Bjorn suggested a different solution: a regulator driver
>> that would - based on which regulators are enabled by a consumer - enable
>> relevant resources (drive the enable GPIOs) while respecting the
>> HW-specific delays. This would however require significant and yet
>> unprecised changed to the regulator subsystem as well as be an abuse of
>> the regulator provider API akin to using the reset framework for power
>> sequencing as proposed before.
>>
>> Instead I'm proposing to add a subsystem that allows different devices to
>> use a shared power sequence split into consumer-specific as well as
>> common "units".
>>
>> A power sequence provider driver registers a set of units with pwrseq
>> core. Each unit can be enabled and disabled and contains an optional list
>> of other units which must be enabled before it itself can be. A unit
>> represents a discreet chunk of the power sequence.
>>
>> It also registers a list of targets: a target is an abstraction wrapping
>> a unit which allows consumers to tell pwrseq which unit they want to
>> reach. Real-life example is the driver we're adding here: there's a set
>> of common regulators, two PCIe-specific ones and two enable GPIOs: one
>> for Bluetooth and one for WLAN.
>>
>> The Bluetooth driver requests a descriptor to the power sequencer and
>> names the target it wants to reach:
>>
>>      pwrseq = devm_pwrseq_get(dev, "bluetooth");
> 
> Is this target tied to the device or not? If not, this might become a
> limitation, if somebody installs two WiFi/BT modules to a single
> device.
> 
>> The pwrseq core then knows that when the driver calls:
>>
>>      pwrseq_power_on(pwrseq);
>>
>> It must enable the "bluetooth-enable" unit but it depends on the
>> "regulators-common" unit so this one is enabled first. The provider
>> driver is also in charge of assuring an appropriate delay between
>> enabling the BT and WLAN enable GPIOs. The WLAN-specific resources are
>> handled by the "wlan-enable" unit and so are not enabled until the WLAN
>> driver requests the "wlan" target to be powered on.
>>
>> Another thing worth discussing is the way we associate the consumer with
>> the relevant power sequencer. DT maintainers have expressed a discontent
>> with the existing mmc pwrseq bindings and have NAKed an earlier
>> initiative to introduce global pwrseq bindings to the kernel[1].
>>
>> In this approach, we model the existing regulators and GPIOs in DT but
>> the pwrseq subsystem requires each provider to provide a .match()
>> callback. Whenever a consumer requests a power sequencer handle, we
>> iterate over the list of pwrseq drivers and call .match() for each. It's
>> up to the driver to verify in a platform-specific way whether it deals
>> with its consumer and let the core pwrseq code know.
> 
> This looks really nice, it will allow us to migrate the BT driver to
> always use pwrseq instead of regulators without touching the DT.
> 
>>
>> The advantage of this over reusing the regulator or reset subsystem is
>> that it's more generalized and can handle resources of all kinds as well
>> as deal with any kind of power-on sequences: for instance, Qualcomm has
>> a PCI switch they want a driver for but this switch requires enabling
>> some resources first (PCI pwrctl) and then configuring the device over
>> I2C (which can be handled by the pwrseq provider).
>>
>> Patch 17/18:
>>
>> This patch makes the Qualcomm Bluetooth driver get and use the power
>> sequencer for QCA6390.
>>
>> Patch 18/18:
>>
>> While tiny, this patch is possibly the highlight of the entire series.
>> It uses the two abstraction layers we introduced before to create an
>> elegant power sequencing PCI power control driver and supports the ath11k
>> module on QCA6390.
>>
>> With this series we can now enable BT and WLAN on several new Qualcomm
>> boards upstream.
>>
>> I tested the series on RB5 while Neil tested it on sm8650-qrd and
>> sm8550-qrd.
>>
>> Best Regards,
>> Bartosz Golaszewski
>>
>> It's hard to list the changes between versions here as the scope changed
>> significantly between each iteration and some versions were not even full
>> series but rather RFCs for parts of the solution. For this reason, I'll
>> only start listing changes starting from v6.
>>
>> [*] This is what the docs say. In practice it seems that this delay can be
>> ignored. However the subsequent model - QCA6490 - *does* require users to
>> respect it, so the problem remains valid.
>>
>> [1] https://lore.kernel.org/netdev/20210829131305.534417-1-dmitry.baryshkov at linaro.org/
>>
>> Bartosz Golaszewski (15):
>>    arm64: defconfig: enable ath12k as a module
>>    dt-bindings: regulator: describe the PMU module of the QCA6390 package
>>    dt-bindings: net: bluetooth: qualcomm: describe regulators for QCA6390
>>    dt-bindings: new: wireless: qcom,ath11k: describe the ath11k on
>>      QCA6390
>>    dt-bindings: new: wireless: describe the ath12k PCI module
>>    arm64: dts: qcom: qrb5165-rb5: model the PMU of the QCA6391
>>    PCI: hold the rescan mutex when scanning for the first time
>>    PCI/pwrctl: reuse the OF node for power controlled devices
>>    PCI/pwrctl: create platform devices for child OF nodes of the port
>>      node
>>    PCI/pwrctl: add PCI power control core code
>>    PCI/pwrctl: add a power control driver for WCN7850
>>    power: sequencing: implement the pwrseq core
>>    power: pwrseq: add a driver for the QCA6390 PMU module
>>    Bluetooth: qca: use the power sequencer for QCA6390
>>    PCI/pwrctl: add a PCI power control driver for power sequenced devices
>>
>> Jonathan Cameron (1):
>>    of: Add cleanup.h based auto release via __free(device_node) markings.
>>
>> Neil Armstrong (2):
>>    arm64: dts: qcom: sm8550-qrd: add the Wifi node
>>    arm64: dts: qcom: sm8650-qrd: add the Wifi node
>>
>>   .../net/bluetooth/qualcomm-bluetooth.yaml     |   17 +
>>   .../net/wireless/qcom,ath11k-pci.yaml         |   28 +
>>   .../net/wireless/qcom,ath12k-pci.yaml         |  103 ++
>>   .../bindings/regulator/qcom,qca6390-pmu.yaml  |  166 +++
>>   MAINTAINERS                                   |    8 +
>>   arch/arm64/boot/dts/qcom/qrb5165-rb5.dts      |  123 +-
>>   arch/arm64/boot/dts/qcom/sm8250.dtsi          |   10 +
>>   arch/arm64/boot/dts/qcom/sm8550-qrd.dts       |   37 +
>>   arch/arm64/boot/dts/qcom/sm8550.dtsi          |   10 +
>>   arch/arm64/boot/dts/qcom/sm8650-qrd.dts       |   29 +
>>   arch/arm64/boot/dts/qcom/sm8650.dtsi          |   10 +
>>   arch/arm64/configs/defconfig                  |    1 +
>>   drivers/bluetooth/hci_qca.c                   |   31 +
>>   drivers/pci/Kconfig                           |    1 +
>>   drivers/pci/Makefile                          |    1 +
>>   drivers/pci/bus.c                             |    9 +-
>>   drivers/pci/of.c                              |   14 +-
>>   drivers/pci/probe.c                           |    2 +
>>   drivers/pci/pwrctl/Kconfig                    |   25 +
>>   drivers/pci/pwrctl/Makefile                   |    7 +
>>   drivers/pci/pwrctl/core.c                     |  136 +++
>>   drivers/pci/pwrctl/pci-pwrctl-pwrseq.c        |   84 ++
>>   drivers/pci/pwrctl/pci-pwrctl-wcn7850.c       |  202 ++++
>>   drivers/pci/remove.c                          |    2 +
>>   drivers/power/Kconfig                         |    1 +
>>   drivers/power/Makefile                        |    1 +
>>   drivers/power/sequencing/Kconfig              |   28 +
>>   drivers/power/sequencing/Makefile             |    6 +
>>   drivers/power/sequencing/core.c               | 1065 +++++++++++++++++
>>   drivers/power/sequencing/pwrseq-qca6390.c     |  353 ++++++
>>   include/linux/of.h                            |    2 +
>>   include/linux/pci-pwrctl.h                    |   51 +
>>   include/linux/pwrseq/consumer.h               |   56 +
>>   include/linux/pwrseq/provider.h               |   75 ++
>>   34 files changed, 2678 insertions(+), 16 deletions(-)
>>   create mode 100644 Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
>>   create mode 100644 Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml
>>   create mode 100644 drivers/pci/pwrctl/Kconfig
>>   create mode 100644 drivers/pci/pwrctl/Makefile
>>   create mode 100644 drivers/pci/pwrctl/core.c
>>   create mode 100644 drivers/pci/pwrctl/pci-pwrctl-pwrseq.c
>>   create mode 100644 drivers/pci/pwrctl/pci-pwrctl-wcn7850.c
>>   create mode 100644 drivers/power/sequencing/Kconfig
>>   create mode 100644 drivers/power/sequencing/Makefile
>>   create mode 100644 drivers/power/sequencing/core.c
>>   create mode 100644 drivers/power/sequencing/pwrseq-qca6390.c
>>   create mode 100644 include/linux/pci-pwrctl.h
>>   create mode 100644 include/linux/pwrseq/consumer.h
>>   create mode 100644 include/linux/pwrseq/provider.h
>>
>> --
>> 2.40.1
>>
> 
> 



From krzysztof.kozlowski at linaro.org  Mon Feb 19 00:15:13 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 09:15:13 +0100
Subject: [PATCH v2 2/2] dt-bindings: arm: rockchip: Add Toybrick
 TB-RK3588X
In-Reply-To: <20240218085314.658223-2-zhangzj@rock-chips.com>
References: <20240218065407.652213-1-zhangzj@rock-chips.com>
 <20240218085314.658223-1-zhangzj@rock-chips.com>
 <20240218085314.658223-2-zhangzj@rock-chips.com>
Message-ID: <28ea8dc1-302b-496b-a3b5-6e7f9382b0ca@linaro.org>

On 18/02/2024 09:53, Elon Zhang wrote:
> Add devicetree binding for Toybrick TB-RK3588X board from Rockchip Toybrick.
> 
> Signed-off-by: Elon Zhang <zhangzj at rock-chips.com>
> ---
>  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 5cf5cbef2cf5..d29df97c7b25 100644
> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> @@ -878,6 +878,11 @@ properties:
>            - const: rockchip,rv1108-evb
>            - const: rockchip,rv1108
>  
> +      - description: Rockchip Toybrick TB-RK3588X board
> +        items:
> +          - const: rockchip,rk3588-toybrick-x0
> +          - const: rockchip,rk3588

Assuming you keep it in-order with existing ordering in this file:

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From neil.armstrong at linaro.org  Mon Feb 19 00:16:53 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 19 Feb 2024 09:16:53 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <20240216203215.40870-1-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
Message-ID: <6860e1cb-4364-44a4-bfe5-21d112ee6777@linaro.org>

On 16/02/2024 21:31, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> First, I'd like to apologize for the somewhat chaotic previous iterations
> of this series and improper versioning which was rightfully pointed out
> to me. I figured that the scope changed so much that it didn't make sense
> to consider previous submissions part of the same series as the original
> RFC but others thought otherwise so this one becomes v5 and I'll keep the
> versioning going forward.
> 
> This is the summary of the work so far:
> 
> v1: Original RFC:
> 
> https://lore.kernel.org/lkml/20240104130123.37115-1-brgl at bgdev.pl/T/
> 
> v2: First real patch series (should have been PATCH v2) adding what I
>      referred to back then as PCI power sequencing:
> 
> https://lore.kernel.org/linux-arm-kernel/2024021413-grumbling-unlivable-c145 at gregkh/T/
> 
> v3: RFC for the DT representation of the PMU supplying the WLAN and BT
>      modules inside the QCA6391 package (was largely separate from the
>      series but probably should have been called PATCH or RFC v3):
> 
> https://lore.kernel.org/all/CAMRc=Mc+GNoi57eTQg71DXkQKjdaoAmCpB=h2ndEpGnmdhVV-Q at mail.gmail.com/T/
> 
> v4: Second attempt at the full series with changed scope (introduction of
>      the pwrseq subsystem, should have been RFC v4)
> 
> https://lore.kernel.org/lkml/20240201155532.49707-1-brgl at bgdev.pl/T/
> 
> ===
> 
> With that out of the way, I'd like to get down to explaining the two
> problems I'm trying to solve.
> 
> Problem statement #1: Dynamic bus chicken-and-egg problem.
> 
> Certain on-board PCI devices need to be powered up before they are can be
> detected but their PCI drivers won't get bound until the device is
> powered-up so enabling the relevant resources in the PCI device driver
> itself is impossible.
> 
> Problem statement #2: Sharing inter-dependent resources between devices.
> 
> Certain devices that use separate drivers (often on different busses)
> share resources (regulators, clocks, etc.). Typically these resources
> are reference-counted but in some cases there are additional interactions
> between them to consider, for example specific power-up sequence timings.
> 
> ===
> 
> The reason for tackling both of these problems in a single series is the
> fact the the platform I'm working on - Qualcomm RB5 - deals with both and
> both need to be addressed in order to enable WLAN and Bluetooth support
> upstream.
> 
> The on-board WLAN/BT package - QCA6391 - has a Power Management Unit that
> takes inputs from the host and exposes LDO outputs consumed by the BT and
> WLAN modules which can be powered-up and down independently. However
> a delay of 100ms must be respected between enabling the BT- and
> WLAN-enable GPIOs[*].
> 
> ===
> 
> This series is logically split into several sections. I'll go
> patch-by-patch and explain each step.
> 
> Patch 1/18:
> 
> This is a commit taken from the list by Jonathan Cameron that adds
> a __free() helper for OF nodes. Not strictly related to the series but
> until said commit ends in next, I need to carry it with this series.
> 
> Patch 2/18:
> 
> This enables the ath12k PCI module in arm64 defconfig as Qualcomm sm8650
> and sm8550 reference platforms use it in the WCN7850 module.
> 
> Patches 3/18-6/18:
> 
> These contain all relevant DT bindings changes. We add new documents for
> the QCA6390 PMU and ATH12K devices as well as extend the bindings for the
> Qualcomm Bluetooth and ATH11K modules with regulators used by them in
> QCA6390.
> 
> Patches 7/18-9/18:
> 
> These contain changes to device-tree sources for the three platforms we
> work with in this series. As the WCN7850 module doesn't require any
> specific timings introducing dependencies between the Bluetooth and WLAN
> modules, while the QCA6390 does, we take two different approaches to how
> me model them in DT.
> 
> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> necessary. The BT and WLAN devices on the device-tree are represented as
> consuming the inputs (relevant to the functionality of each) of the PMU
> directly.
> 
> For QCA6390 on RB5 we add the PMU node as a platform device. It consumes
> regulators and GPIOs from the host and exposed regulators consumer in turn
> by the BT and WLAN modules. This represents the internal structure of the
> package.
> 
> Patches 10/18-14/18:
> 
> These contain the bulk of the PCI changes for this series. We introduce
> a simple framework for powering up PCI devices before detecting them on
> the bus and the first user of this library in the form of the WCN7850 PCI
> power control driver.
> 
> The general approach is as follows: PCI devices that need special
> treatment before they can be powered up, scanned and bound to their PCI
> drivers must be described on the device-tree as child nodes of the PCI
> port node. These devices will be instantiated on the platform bus. They
> will in fact be generic platform devices with the compatible of the form
> used for PCI devices already upstream ("pci<vendor ID>,<device ID">). We
> add a new directory under drivers/pci/pwrctl/ that contains PCI pwrctl
> drivers. These drivers are platform drivers that will now be matched
> against the devices instantiated from port children just like any other
> platform pairs.
> 
> Both the power control platform device *AND* the associated PCI device
> reuse the same OF node and have access to the same properties. The goal
> of the platform driver is to request and bring up any required resources
> and let the pwrctl framework know that it's now OK to rescan the bus and
> detect the devices. When the device is bound, we are notified about it
> by the PCI bus notifier event and can establish a device link between the
> power control device and the PCI device so that any future extension for
> power-management will already be able to work with the correct hierachy.
> 
> The reusing of the OF node is the reason for the small changes to the PCI
> OF core: as the bootloader can possibly leave the relevant regulators on
> before booting linux, the PCI device can be detected before its platform
> abstraction is probed. In this case, we find that device first and mark
> its OF node as reused. The pwrctl framework handles the opposite case
> (when the PCI device is detected only after the platform driver
> successfully enabled it).
> 
> Patches 15/18-16/18:
> 
> These add a relatively simple power sequencing subsystem and the first
> driver using it: the pwrseq module for the QCA6390 PMU.
> 
> For the record: Bjorn suggested a different solution: a regulator driver
> that would - based on which regulators are enabled by a consumer - enable
> relevant resources (drive the enable GPIOs) while respecting the
> HW-specific delays. This would however require significant and yet
> unprecised changed to the regulator subsystem as well as be an abuse of
> the regulator provider API akin to using the reset framework for power
> sequencing as proposed before.
> 
> Instead I'm proposing to add a subsystem that allows different devices to
> use a shared power sequence split into consumer-specific as well as
> common "units".
> 
> A power sequence provider driver registers a set of units with pwrseq
> core. Each unit can be enabled and disabled and contains an optional list
> of other units which must be enabled before it itself can be. A unit
> represents a discreet chunk of the power sequence.
> 
> It also registers a list of targets: a target is an abstraction wrapping
> a unit which allows consumers to tell pwrseq which unit they want to
> reach. Real-life example is the driver we're adding here: there's a set
> of common regulators, two PCIe-specific ones and two enable GPIOs: one
> for Bluetooth and one for WLAN.
> 
> The Bluetooth driver requests a descriptor to the power sequencer and
> names the target it wants to reach:
> 
>      pwrseq = devm_pwrseq_get(dev, "bluetooth");
> 
> The pwrseq core then knows that when the driver calls:
> 
>      pwrseq_power_on(pwrseq);
> 
> It must enable the "bluetooth-enable" unit but it depends on the
> "regulators-common" unit so this one is enabled first. The provider
> driver is also in charge of assuring an appropriate delay between
> enabling the BT and WLAN enable GPIOs. The WLAN-specific resources are
> handled by the "wlan-enable" unit and so are not enabled until the WLAN
> driver requests the "wlan" target to be powered on.
> 
> Another thing worth discussing is the way we associate the consumer with
> the relevant power sequencer. DT maintainers have expressed a discontent
> with the existing mmc pwrseq bindings and have NAKed an earlier
> initiative to introduce global pwrseq bindings to the kernel[1].
> 
> In this approach, we model the existing regulators and GPIOs in DT but
> the pwrseq subsystem requires each provider to provide a .match()
> callback. Whenever a consumer requests a power sequencer handle, we
> iterate over the list of pwrseq drivers and call .match() for each. It's
> up to the driver to verify in a platform-specific way whether it deals
> with its consumer and let the core pwrseq code know.
> 
> The advantage of this over reusing the regulator or reset subsystem is
> that it's more generalized and can handle resources of all kinds as well
> as deal with any kind of power-on sequences: for instance, Qualcomm has
> a PCI switch they want a driver for but this switch requires enabling
> some resources first (PCI pwrctl) and then configuring the device over
> I2C (which can be handled by the pwrseq provider).
> 
> Patch 17/18:
> 
> This patch makes the Qualcomm Bluetooth driver get and use the power
> sequencer for QCA6390.
> 
> Patch 18/18:
> 
> While tiny, this patch is possibly the highlight of the entire series.
> It uses the two abstraction layers we introduced before to create an
> elegant power sequencing PCI power control driver and supports the ath11k
> module on QCA6390.
> 
> With this series we can now enable BT and WLAN on several new Qualcomm
> boards upstream.
> 
> I tested the series on RB5 while Neil tested it on sm8650-qrd and
> sm8550-qrd.
> 
> Best Regards,
> Bartosz Golaszewski
> 
> It's hard to list the changes between versions here as the scope changed
> significantly between each iteration and some versions were not even full
> series but rather RFCs for parts of the solution. For this reason, I'll
> only start listing changes starting from v6.
> 
> [*] This is what the docs say. In practice it seems that this delay can be
> ignored. However the subsequent model - QCA6490 - *does* require users to
> respect it, so the problem remains valid.
> 
> [1] https://lore.kernel.org/netdev/20210829131305.534417-1-dmitry.baryshkov at linaro.org/
> 
> Bartosz Golaszewski (15):
>    arm64: defconfig: enable ath12k as a module
>    dt-bindings: regulator: describe the PMU module of the QCA6390 package
>    dt-bindings: net: bluetooth: qualcomm: describe regulators for QCA6390
>    dt-bindings: new: wireless: qcom,ath11k: describe the ath11k on
>      QCA6390
>    dt-bindings: new: wireless: describe the ath12k PCI module
>    arm64: dts: qcom: qrb5165-rb5: model the PMU of the QCA6391
>    PCI: hold the rescan mutex when scanning for the first time
>    PCI/pwrctl: reuse the OF node for power controlled devices
>    PCI/pwrctl: create platform devices for child OF nodes of the port
>      node
>    PCI/pwrctl: add PCI power control core code
>    PCI/pwrctl: add a power control driver for WCN7850
>    power: sequencing: implement the pwrseq core
>    power: pwrseq: add a driver for the QCA6390 PMU module
>    Bluetooth: qca: use the power sequencer for QCA6390
>    PCI/pwrctl: add a PCI power control driver for power sequenced devices
> 
> Jonathan Cameron (1):
>    of: Add cleanup.h based auto release via __free(device_node) markings.
> 
> Neil Armstrong (2):
>    arm64: dts: qcom: sm8550-qrd: add the Wifi node
>    arm64: dts: qcom: sm8650-qrd: add the Wifi node
> 
>   .../net/bluetooth/qualcomm-bluetooth.yaml     |   17 +
>   .../net/wireless/qcom,ath11k-pci.yaml         |   28 +
>   .../net/wireless/qcom,ath12k-pci.yaml         |  103 ++
>   .../bindings/regulator/qcom,qca6390-pmu.yaml  |  166 +++
>   MAINTAINERS                                   |    8 +
>   arch/arm64/boot/dts/qcom/qrb5165-rb5.dts      |  123 +-
>   arch/arm64/boot/dts/qcom/sm8250.dtsi          |   10 +
>   arch/arm64/boot/dts/qcom/sm8550-qrd.dts       |   37 +
>   arch/arm64/boot/dts/qcom/sm8550.dtsi          |   10 +
>   arch/arm64/boot/dts/qcom/sm8650-qrd.dts       |   29 +
>   arch/arm64/boot/dts/qcom/sm8650.dtsi          |   10 +
>   arch/arm64/configs/defconfig                  |    1 +
>   drivers/bluetooth/hci_qca.c                   |   31 +
>   drivers/pci/Kconfig                           |    1 +
>   drivers/pci/Makefile                          |    1 +
>   drivers/pci/bus.c                             |    9 +-
>   drivers/pci/of.c                              |   14 +-
>   drivers/pci/probe.c                           |    2 +
>   drivers/pci/pwrctl/Kconfig                    |   25 +
>   drivers/pci/pwrctl/Makefile                   |    7 +
>   drivers/pci/pwrctl/core.c                     |  136 +++
>   drivers/pci/pwrctl/pci-pwrctl-pwrseq.c        |   84 ++
>   drivers/pci/pwrctl/pci-pwrctl-wcn7850.c       |  202 ++++
>   drivers/pci/remove.c                          |    2 +
>   drivers/power/Kconfig                         |    1 +
>   drivers/power/Makefile                        |    1 +
>   drivers/power/sequencing/Kconfig              |   28 +
>   drivers/power/sequencing/Makefile             |    6 +
>   drivers/power/sequencing/core.c               | 1065 +++++++++++++++++
>   drivers/power/sequencing/pwrseq-qca6390.c     |  353 ++++++
>   include/linux/of.h                            |    2 +
>   include/linux/pci-pwrctl.h                    |   51 +
>   include/linux/pwrseq/consumer.h               |   56 +
>   include/linux/pwrseq/provider.h               |   75 ++
>   34 files changed, 2678 insertions(+), 16 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml
>   create mode 100644 Documentation/devicetree/bindings/regulator/qcom,qca6390-pmu.yaml
>   create mode 100644 drivers/pci/pwrctl/Kconfig
>   create mode 100644 drivers/pci/pwrctl/Makefile
>   create mode 100644 drivers/pci/pwrctl/core.c
>   create mode 100644 drivers/pci/pwrctl/pci-pwrctl-pwrseq.c
>   create mode 100644 drivers/pci/pwrctl/pci-pwrctl-wcn7850.c
>   create mode 100644 drivers/power/sequencing/Kconfig
>   create mode 100644 drivers/power/sequencing/Makefile
>   create mode 100644 drivers/power/sequencing/core.c
>   create mode 100644 drivers/power/sequencing/pwrseq-qca6390.c
>   create mode 100644 include/linux/pci-pwrctl.h
>   create mode 100644 include/linux/pwrseq/consumer.h
>   create mode 100644 include/linux/pwrseq/provider.h
> 

Tested-by: Neil Armstrong <neil.armstrong at linaro.org> # on SM8650-QRD
Tested-by: Neil Armstrong <neil.armstrong at linaro.org> # on SM8550-QRD

Thanks,
Neil


From krzysztof.kozlowski at linaro.org  Mon Feb 19 00:17:05 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 09:17:05 +0100
Subject: [PATCH 1/3] dt-bindings: arm: fsl: add i.MX95 19x19 EVK board
In-Reply-To: <20240218-imx95-dts-v1-1-2959f89f2018@nxp.com>
References: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>
 <20240218-imx95-dts-v1-1-2959f89f2018@nxp.com>
Message-ID: <5b7a6728-0a68-4332-968c-aab84537be73@linaro.org>

On 18/02/2024 07:38, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add DT compatible string for NXP i.MX95 19x19 EVK board.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  Documentation/devicetree/bindings/arm/fsl.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
> index 39378879777b..3b318c518e35 100644
> --- a/Documentation/devicetree/bindings/arm/fsl.yaml
> +++ b/Documentation/devicetree/bindings/arm/fsl.yaml
> @@ -1264,6 +1264,12 @@ properties:
>                - fsl,imx93-11x11-evk       # i.MX93 11x11 EVK Board
>            - const: fsl,imx93
>  
> +      - description: i.MX95 based Boards

You already have such entry for that fallback. Just add it there... or
you want to say the fallback compatible is wrong? It's anyway weird to
re-use other compatible without 95.

Best regards,
Krzysztof



From dan.carpenter at linaro.org  Mon Feb 19 00:17:38 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Mon, 19 Feb 2024 11:17:38 +0300
Subject: [PATCH v2 0/8] Staging: vc04_services: bcm2835-camera: Fix code
 style checks
In-Reply-To: <510574c4-ad26-4fc2-93c4-7b67737f8eb1@moroto.mountain>
References: <20240217211246.28882-1-mo.c.weber@gmail.com>
 <510574c4-ad26-4fc2-93c4-7b67737f8eb1@moroto.mountain>
Message-ID: <236d985c-1835-410f-b0b5-cacbd5fbf930@moroto.mountain>

On Mon, Feb 19, 2024 at 10:38:30AM +0300, Dan Carpenter wrote:
> On Sat, Feb 17, 2024 at 10:12:38PM +0100, Moritz C. Weber wrote:
> > Resubmit these patches to fix multiple code style checks for better readability, consistency, and to address errors indicated by Gregs patch bot
> > 
> > Moritz C. Weber (8):
> >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> >   Staging: vc04_services: bcm2835-camera: fix blank line style check

This blank line patch would be still separate of course.

> >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> >   Staging: vc04_services: bcm2835-camera: fix brace code style check

regards,
dan carpenter



From o451686892 at gmail.com  Mon Feb 19 00:20:30 2024
From: o451686892 at gmail.com (Weizhao Ouyang)
Date: Mon, 19 Feb 2024 16:20:30 +0800
Subject: [PATCH v2 1/2] arm64: dts: rockchip: Add devicetree support for
 TB-RK3588X board
In-Reply-To: <20240218085314.658223-1-zhangzj@rock-chips.com>
References: <20240218065407.652213-1-zhangzj@rock-chips.com> <20240218085314.658223-1-zhangzj@rock-chips.com>
Message-ID: <CAHk0HovD_s1xRs7VUt5qmye---0p3WW+SkBKGbuOwWWWGWQz6A@mail.gmail.com>

On Sun, Feb 18, 2024 at 4:53?PM Elon Zhang <zhangzj at rock-chips.com> wrote:
>
> Add board file for Rockchip Toybrick TB-RK3588X board.
>
> Specification:
>         Rockchip Rk3588 SoC
>         4x ARM Cortex-A76, 4x ARM Cortex-A55
>         8/16GB Memory LPDDR4x
>         Mali G610MC4 GPU
>         2? MIPI-CSI0 Connector
>         1x 2Lanes PCIe3.0 Connector
>         1x SATA3.0 Connector
>         32GB eMMC Module
>         2x USB 2.0, 2x USB 3.0
>         1x HDMI Output, 1x HDMI Input
>         2x Ethernet Port
>
> Functions work normally:
>         [1] USB2.0 Host
>         [2] Ethernet0 with PHY RTL8211F
>
> More information can be obtained from the following websites:
>         [1] https://t.rock-chips.com/en/wiki/EN/tb-rk3588x_en/index.html
>         [2] http://t.rock-chips.com/
>
> Signed-off-by: Elon Zhang <zhangzj at rock-chips.com>

Reviewed-by: Weizhao Ouyang <weizhao.ouyang at arm.com>

BR,
Weizhao

> ---
> v1->v2: update copyright
>
>  arch/arm64/boot/dts/rockchip/Makefile         |   1 +
>  .../boot/dts/rockchip/rk3588-toybrick-x0.dts  | 672 ++++++++++++++++++
>  2 files changed, 673 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
>
> diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
> index a7b30e11beaf..e0722b6e2d99 100644
> --- a/arch/arm64/boot/dts/rockchip/Makefile
> +++ b/arch/arm64/boot/dts/rockchip/Makefile
> @@ -110,6 +110,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-orangepi-5-plus.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-quartzpro64.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-toybrick-x0.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-turing-rk1.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-coolpi-4b.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
> new file mode 100644
> index 000000000000..f3f7c1d35ed2
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
> @@ -0,0 +1,672 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
> + *
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +#include "rk3588.dtsi"
> +
> +/ {
> +       model = "Rockchip Toybrick TB-RK3588X Board";
> +       compatible = "rockchip,rk3588-toybrick-x0", "rockchip,rk3588";
> +
> +       aliases {
> +               mmc0 = &sdhci;
> +               serial2 = &uart2;
> +       };
> +
> +       chosen {
> +               stdout-path = "serial2:1500000n8";
> +       };
> +
> +       adc-keys {
> +               compatible = "adc-keys";
> +               io-channels = <&saradc 1>;
> +               io-channel-names = "buttons";
> +               keyup-threshold-microvolt = <1800000>;
> +               poll-interval = <100>;
> +
> +               button-vol-up {
> +                       label = "Volume Up";
> +                       linux,code = <KEY_VOLUMEUP>;
> +                       press-threshold-microvolt = <17000>;
> +               };
> +
> +               button-vol-down {
> +                       label = "Volume Down";
> +                       linux,code = <KEY_VOLUMEDOWN>;
> +                       press-threshold-microvolt = <417000>;
> +               };
> +
> +               button-menu {
> +                       label = "Menu";
> +                       linux,code = <KEY_MENU>;
> +                       press-threshold-microvolt = <890000>;
> +               };
> +
> +               button-escape {
> +                       label = "Escape";
> +                       linux,code = <KEY_ESC>;
> +                       press-threshold-microvolt = <1235000>;
> +               };
> +       };
> +
> +       backlight: backlight {
> +               compatible = "pwm-backlight";
> +               power-supply = <&vcc12v_dcin>;
> +               pwms = <&pwm2 0 25000 0>;
> +       };
> +
> +       pcie20_avdd0v85: pcie20-avdd0v85-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "pcie20_avdd0v85";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <850000>;
> +               regulator-max-microvolt = <850000>;
> +               vin-supply = <&vdd_0v85_s0>;
> +       };
> +
> +       pcie20_avdd1v8: pcie20-avdd1v8-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "pcie20_avdd1v8";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <1800000>;
> +               regulator-max-microvolt = <1800000>;
> +               vin-supply = <&avcc_1v8_s0>;
> +       };
> +
> +       pcie30_avdd0v75: pcie30-avdd0v75-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "pcie30_avdd0v75";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <750000>;
> +               regulator-max-microvolt = <750000>;
> +               vin-supply = <&avdd_0v75_s0>;
> +       };
> +
> +       pcie30_avdd1v8: pcie30-avdd1v8-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "pcie30_avdd1v8";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <1800000>;
> +               regulator-max-microvolt = <1800000>;
> +               vin-supply = <&avcc_1v8_s0>;
> +       };
> +
> +       vcc12v_dcin: vcc12v-dcin-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc12v_dcin";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <12000000>;
> +               regulator-max-microvolt = <12000000>;
> +       };
> +
> +       vcc5v0_host: vcc5v0-host-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc5v0_host";
> +               regulator-boot-on;
> +               regulator-always-on;
> +               regulator-min-microvolt = <5000000>;
> +               regulator-max-microvolt = <5000000>;
> +               enable-active-high;
> +               gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&vcc5v0_host_en>;
> +               vin-supply = <&vcc5v0_usb>;
> +       };
> +
> +       vcc5v0_sys: vcc5v0-sys-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc5v0_sys";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <5000000>;
> +               regulator-max-microvolt = <5000000>;
> +               vin-supply = <&vcc12v_dcin>;
> +       };
> +
> +       vcc5v0_usbdcin: vcc5v0-usbdcin-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc5v0_usbdcin";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <5000000>;
> +               regulator-max-microvolt = <5000000>;
> +               vin-supply = <&vcc12v_dcin>;
> +       };
> +
> +       vcc5v0_usb: vcc5v0-usb-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc5v0_usb";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <5000000>;
> +               regulator-max-microvolt = <5000000>;
> +               vin-supply = <&vcc5v0_usbdcin>;
> +       };
> +
> +       vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
> +               compatible = "regulator-fixed";
> +               regulator-name = "vcc_1v1_nldo_s3";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <1100000>;
> +               regulator-max-microvolt = <1100000>;
> +               vin-supply = <&vcc5v0_sys>;
> +       };
> +};
> +
> +&combphy0_ps {
> +       status = "okay";
> +};
> +
> +&combphy2_psu {
> +       status = "okay";
> +};
> +
> +&cpu_b0 {
> +       cpu-supply = <&vdd_cpu_big0_s0>;
> +};
> +
> +&cpu_b1 {
> +       cpu-supply = <&vdd_cpu_big0_s0>;
> +};
> +
> +&cpu_b2 {
> +       cpu-supply = <&vdd_cpu_big1_s0>;
> +};
> +
> +&cpu_b3 {
> +       cpu-supply = <&vdd_cpu_big1_s0>;
> +};
> +
> +&cpu_l0 {
> +       cpu-supply = <&vdd_cpu_lit_s0>;
> +};
> +
> +&cpu_l1 {
> +       cpu-supply = <&vdd_cpu_lit_s0>;
> +};
> +
> +&cpu_l2 {
> +       cpu-supply = <&vdd_cpu_lit_s0>;
> +};
> +
> +&cpu_l3 {
> +       cpu-supply = <&vdd_cpu_lit_s0>;
> +};
> +
> +&gmac0 {
> +       clock_in_out = "output";
> +       phy-handle = <&rgmii_phy>;
> +       phy-mode = "rgmii-rxid";
> +       pinctrl-0 = <&gmac0_miim
> +                    &gmac0_tx_bus2
> +                    &gmac0_rx_bus2
> +                    &gmac0_rgmii_clk
> +                    &gmac0_rgmii_bus>;
> +       pinctrl-names = "default";
> +       rx_delay = <0x00>;
> +       tx_delay = <0x43>;
> +       status = "okay";
> +};
> +
> +&i2c0 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&i2c0m2_xfer>;
> +       status = "okay";
> +
> +       vdd_cpu_big0_s0: regulator at 42 {
> +               compatible = "rockchip,rk8602";
> +               reg = <0x42>;
> +               fcs,suspend-voltage-selector = <1>;
> +               regulator-name = "vdd_cpu_big0_s0";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <550000>;
> +               regulator-max-microvolt = <1050000>;
> +               regulator-ramp-delay = <2300>;
> +               vin-supply = <&vcc5v0_sys>;
> +
> +               regulator-state-mem {
> +                       regulator-off-in-suspend;
> +               };
> +       };
> +
> +       vdd_cpu_big1_s0: regulator at 43 {
> +               compatible = "rockchip,rk8603", "rockchip,rk8602";
> +               reg = <0x43>;
> +               fcs,suspend-voltage-selector = <1>;
> +               regulator-name = "vdd_cpu_big1_s0";
> +               regulator-always-on;
> +               regulator-boot-on;
> +               regulator-min-microvolt = <550000>;
> +               regulator-max-microvolt = <1050000>;
> +               regulator-ramp-delay = <2300>;
> +               vin-supply = <&vcc5v0_sys>;
> +
> +               regulator-state-mem {
> +                       regulator-off-in-suspend;
> +               };
> +       };
> +};
> +
> +&i2c2 {
> +       status = "okay";
> +
> +       hym8563: rtc at 51 {
> +               compatible = "haoyu,hym8563";
> +               reg = <0x51>;
> +               #clock-cells = <0>;
> +               clock-output-names = "hym8563";
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&hym8563_int>;
> +               interrupt-parent = <&gpio0>;
> +               interrupts = <RK_PD4 IRQ_TYPE_LEVEL_LOW>;
> +               wakeup-source;
> +       };
> +};
> +
> +&mdio0 {
> +       rgmii_phy: ethernet-phy at 1 {
> +               /* RTL8211F */
> +               compatible = "ethernet-phy-id001c.c916";
> +               reg = <0x1>;
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&rtl8211f_rst>;
> +               reset-assert-us = <20000>;
> +               reset-deassert-us = <100000>;
> +               reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
> +       };
> +};
> +
> +&pinctrl {
> +       rtl8211f {
> +               rtl8211f_rst: rtl8211f-rst {
> +                       rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
> +               };
> +
> +       };
> +
> +       hym8563 {
> +               hym8563_int: hym8563-int {
> +                       rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
> +               };
> +       };
> +
> +       usb {
> +               vcc5v0_host_en: vcc5v0-host-en {
> +                       rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
> +               };
> +       };
> +};
> +
> +&pwm2 {
> +       status = "okay";
> +};
> +
> +&saradc {
> +       vref-supply = <&vcc_1v8_s0>;
> +       status = "okay";
> +};
> +
> +&sdhci {
> +       bus-width = <8>;
> +       no-sdio;
> +       no-sd;
> +       non-removable;
> +       mmc-hs400-1_8v;
> +       mmc-hs400-enhanced-strobe;
> +       status = "okay";
> +};
> +
> +&spi2 {
> +       status = "okay";
> +       assigned-clocks = <&cru CLK_SPI2>;
> +       assigned-clock-rates = <200000000>;
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
> +       num-cs = <1>;
> +
> +       pmic at 0 {
> +               compatible = "rockchip,rk806";
> +               spi-max-frequency = <1000000>;
> +               reg = <0x0>;
> +
> +               interrupt-parent = <&gpio0>;
> +               interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
> +
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
> +                           <&rk806_dvs2_null>, <&rk806_dvs3_null>;
> +
> +               system-power-controller;
> +
> +               vcc1-supply = <&vcc5v0_sys>;
> +               vcc2-supply = <&vcc5v0_sys>;
> +               vcc3-supply = <&vcc5v0_sys>;
> +               vcc4-supply = <&vcc5v0_sys>;
> +               vcc5-supply = <&vcc5v0_sys>;
> +               vcc6-supply = <&vcc5v0_sys>;
> +               vcc7-supply = <&vcc5v0_sys>;
> +               vcc8-supply = <&vcc5v0_sys>;
> +               vcc9-supply = <&vcc5v0_sys>;
> +               vcc10-supply = <&vcc5v0_sys>;
> +               vcc11-supply = <&vcc_2v0_pldo_s3>;
> +               vcc12-supply = <&vcc5v0_sys>;
> +               vcc13-supply = <&vcc_1v1_nldo_s3>;
> +               vcc14-supply = <&vcc_1v1_nldo_s3>;
> +               vcca-supply = <&vcc5v0_sys>;
> +
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +
> +               rk806_dvs1_null: dvs1-null-pins {
> +                       pins = "gpio_pwrctrl1";
> +                       function = "pin_fun0";
> +               };
> +
> +               rk806_dvs2_null: dvs2-null-pins {
> +                       pins = "gpio_pwrctrl2";
> +                       function = "pin_fun0";
> +               };
> +
> +               rk806_dvs3_null: dvs3-null-pins {
> +                       pins = "gpio_pwrctrl3";
> +                       function = "pin_fun0";
> +               };
> +
> +               regulators {
> +                       vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <550000>;
> +                               regulator-max-microvolt = <950000>;
> +                               regulator-ramp-delay = <12500>;
> +                               regulator-name = "vdd_gpu_s0";
> +                               regulator-enable-ramp-delay = <400>;
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <550000>;
> +                               regulator-max-microvolt = <950000>;
> +                               regulator-ramp-delay = <12500>;
> +                               regulator-name = "vdd_cpu_lit_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vdd_log_s0: dcdc-reg3 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <675000>;
> +                               regulator-max-microvolt = <750000>;
> +                               regulator-ramp-delay = <12500>;
> +                               regulator-name = "vdd_log_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                                       regulator-suspend-microvolt = <750000>;
> +                               };
> +                       };
> +
> +                       vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <550000>;
> +                               regulator-max-microvolt = <950000>;
> +                               regulator-init-microvolt = <750000>;
> +                               regulator-ramp-delay = <12500>;
> +                               regulator-name = "vdd_vdenc_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vdd_ddr_s0: dcdc-reg5 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <675000>;
> +                               regulator-max-microvolt = <900000>;
> +                               regulator-ramp-delay = <12500>;
> +                               regulator-name = "vdd_ddr_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                                       regulator-suspend-microvolt = <850000>;
> +                               };
> +                       };
> +
> +                       vdd2_ddr_s3: dcdc-reg6 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-name = "vdd2_ddr_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                               };
> +                       };
> +
> +                       vcc_2v0_pldo_s3: dcdc-reg7 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <2000000>;
> +                               regulator-max-microvolt = <2000000>;
> +                               regulator-name = "vdd_2v0_pldo_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                                       regulator-suspend-microvolt = <2000000>;
> +                               };
> +                       };
> +
> +                       vcc_3v3_s3: dcdc-reg8 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <3300000>;
> +                               regulator-max-microvolt = <3300000>;
> +                               regulator-name = "vcc_3v3_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                                       regulator-suspend-microvolt = <3300000>;
> +                               };
> +                       };
> +
> +                       vddq_ddr_s0: dcdc-reg9 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-name = "vddq_ddr_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vcc_1v8_s3: dcdc-reg10 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1800000>;
> +                               regulator-max-microvolt = <1800000>;
> +                               regulator-name = "vcc_1v8_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                                       regulator-suspend-microvolt = <1800000>;
> +                               };
> +                       };
> +
> +                       avcc_1v8_s0: pldo-reg1 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1800000>;
> +                               regulator-max-microvolt = <1800000>;
> +                               regulator-name = "avcc_1v8_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vcc_1v8_s0: pldo-reg2 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1800000>;
> +                               regulator-max-microvolt = <1800000>;
> +                               regulator-name = "vcc_1v8_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                                       regulator-suspend-microvolt = <1800000>;
> +                               };
> +                       };
> +
> +                       avdd_1v2_s0: pldo-reg3 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1200000>;
> +                               regulator-max-microvolt = <1200000>;
> +                               regulator-name = "avdd_1v2_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vcc_3v3_s0: pldo-reg4 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <3300000>;
> +                               regulator-max-microvolt = <3300000>;
> +                               regulator-name = "vcc_3v3_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vccio_sd_s0: pldo-reg5 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1800000>;
> +                               regulator-max-microvolt = <3300000>;
> +                               regulator-name = "vccio_sd_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       pldo6_s3: pldo-reg6 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <1800000>;
> +                               regulator-max-microvolt = <1800000>;
> +                               regulator-name = "pldo6_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                                       regulator-suspend-microvolt = <1800000>;
> +                               };
> +                       };
> +
> +                       vdd_0v75_s3: nldo-reg1 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <750000>;
> +                               regulator-max-microvolt = <750000>;
> +                               regulator-name = "vdd_0v75_s3";
> +                               regulator-state-mem {
> +                                       regulator-on-in-suspend;
> +                                       regulator-suspend-microvolt = <750000>;
> +                               };
> +                       };
> +
> +                       vdd_ddr_pll_s0: nldo-reg2 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <850000>;
> +                               regulator-max-microvolt = <850000>;
> +                               regulator-name = "vdd_ddr_pll_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                                       regulator-suspend-microvolt = <850000>;
> +                               };
> +                       };
> +
> +                       avdd_0v75_s0: nldo-reg3 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <837500>;
> +                               regulator-max-microvolt = <837500>;
> +                               regulator-name = "avdd_0v75_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vdd_0v85_s0: nldo-reg4 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <850000>;
> +                               regulator-max-microvolt = <850000>;
> +                               regulator-name = "vdd_0v85_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +
> +                       vdd_0v75_s0: nldo-reg5 {
> +                               regulator-always-on;
> +                               regulator-boot-on;
> +                               regulator-min-microvolt = <750000>;
> +                               regulator-max-microvolt = <750000>;
> +                               regulator-name = "vdd_0v75_s0";
> +                               regulator-state-mem {
> +                                       regulator-off-in-suspend;
> +                               };
> +                       };
> +               };
> +       };
> +};
> +
> +&u2phy2 {
> +       status = "okay";
> +};
> +
> +&u2phy2_host {
> +       phy-supply = <&vcc5v0_host>;
> +       status = "okay";
> +};
> +
> +&u2phy3 {
> +       status = "okay";
> +};
> +
> +&u2phy3_host {
> +       phy-supply = <&vcc5v0_host>;
> +       status = "okay";
> +};
> +
> +&uart2 {
> +       pinctrl-0 = <&uart2m0_xfer>;
> +       status = "okay";
> +};
> +
> +&usb_host0_ehci {
> +       status = "okay";
> +};
> +
> +&usb_host0_ohci {
> +       status = "okay";
> +};
> +
> +&usb_host1_ehci {
> +       status = "okay";
> +};
> +
> +&usb_host1_ohci {
> +       status = "okay";
> +};
> --
> 2.34.1
>


From o451686892 at gmail.com  Mon Feb 19 00:20:55 2024
From: o451686892 at gmail.com (Weizhao Ouyang)
Date: Mon, 19 Feb 2024 16:20:55 +0800
Subject: [PATCH v2 2/2] dt-bindings: arm: rockchip: Add Toybrick TB-RK3588X
In-Reply-To: <20240218085314.658223-2-zhangzj@rock-chips.com>
References: <20240218065407.652213-1-zhangzj@rock-chips.com>
 <20240218085314.658223-1-zhangzj@rock-chips.com> <20240218085314.658223-2-zhangzj@rock-chips.com>
Message-ID: <CAHk0HovRrm3=99eTNvs+4UmdC-LYSuuuuP1Tuobr7KYbD23tCQ@mail.gmail.com>

On Sun, Feb 18, 2024 at 4:53?PM Elon Zhang <zhangzj at rock-chips.com> wrote:
>
> Add devicetree binding for Toybrick TB-RK3588X board from Rockchip Toybrick.
>
> Signed-off-by: Elon Zhang <zhangzj at rock-chips.com>

Reviewed-by: Weizhao Ouyang <weizhao.ouyang at arm.com>

BR,
Weizhao

> ---
>  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 5cf5cbef2cf5..d29df97c7b25 100644
> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> @@ -878,6 +878,11 @@ properties:
>            - const: rockchip,rv1108-evb
>            - const: rockchip,rv1108
>
> +      - description: Rockchip Toybrick TB-RK3588X board
> +        items:
> +          - const: rockchip,rk3588-toybrick-x0
> +          - const: rockchip,rk3588
> +
>        - description: Theobroma Systems PX30-uQ7 with Haikou baseboard
>          items:
>            - const: tsd,px30-ringneck-haikou
> --
> 2.34.1
>


From krzysztof.kozlowski at linaro.org  Mon Feb 19 00:21:24 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 09:21:24 +0100
Subject: [PATCH 2/3] arm64: dts: freescale: add i.MX95 basic dtsi
In-Reply-To: <20240218-imx95-dts-v1-2-2959f89f2018@nxp.com>
References: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>
 <20240218-imx95-dts-v1-2-2959f89f2018@nxp.com>
Message-ID: <da859ac9-8f87-43b1-88ba-0357fa9b7be3@linaro.org>

On 18/02/2024 07:38, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> i.MX95 features 6 A55 Cores, ARM Mali GPU, ISP, ML acceleration NPU,
> and Edgelock secure enclave security. This patch is to add a minimal
> dtsi, with cpu cores, coresight, scmi, gic, uart, mu, sdhc, lpi2c added.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx95-clock.h |  187 +++++
>  arch/arm64/boot/dts/freescale/imx95-power.h |   55 ++
>  arch/arm64/boot/dts/freescale/imx95.dtsi    | 1215 +++++++++++++++++++++++++++
>  3 files changed, 1457 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx95-clock.h b/arch/arm64/boot/dts/freescale/imx95-clock.h
> new file mode 100644
> index 000000000000..939655f0414e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx95-clock.h

What is this?


> @@ -0,0 +1,187 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#ifndef __DT_BINDINGS_CLOCK_IMX95_H

NAK, bindings do not go to DTS!


> +#endif	/* __DT_BINDINGS_CLOCK_IMX95_H */
> diff --git a/arch/arm64/boot/dts/freescale/imx95-power.h b/arch/arm64/boot/dts/freescale/imx95-power.h
> new file mode 100644
> index 000000000000..17be8a4cb96b
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx95-power.h
> @@ -0,0 +1,55 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
> +/*
> + *  Copyright 2024 NXP
> + */
> +
> +#ifndef __DT_BINDINGS_IMX95_POWER_H__
> +#define __DT_BINDINGS_IMX95_POWER_H__

NAK, bindings do not go to DTS.

> diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
> new file mode 100644
> index 000000000000..5b5b29a9aff5
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
> @@ -0,0 +1,1215 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)

Weird license. We do not want GPL v3 or v4.

> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/thermal/thermal.h>
> +
> +#include "imx95-clock.h"
> +#include "imx95-power.h"
> +
> +/ {
> +	interrupt-parent = <&gic>;
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	aliases {
> +		gpio0 = &gpio1;
> +		gpio1 = &gpio2;
> +		gpio2 = &gpio3;
> +		gpio3 = &gpio4;
> +		gpio4 = &gpio5;
> +		i2c0 = &lpi2c1;
> +		i2c1 = &lpi2c2;
> +		i2c2 = &lpi2c3;
> +		i2c3 = &lpi2c4;
> +		i2c4 = &lpi2c5;
> +		i2c5 = &lpi2c6;
> +		i2c6 = &lpi2c7;
> +		i2c7 = &lpi2c8;

None of these are properties of the SoC.

> +		mmc0 = &usdhc1;
> +		mmc1 = &usdhc2;
> +		mmc2 = &usdhc3;
> +		serial0 = &lpuart1;
> +		serial1 = &lpuart2;
> +		serial2 = &lpuart3;
> +		serial3 = &lpuart4;
> +		serial4 = &lpuart5;
> +		serial5 = &lpuart6;
> +		serial6 = &lpuart7;
> +		serial7 = &lpuart8;

Neither these.

> +	};
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		idle-states {
> +			entry-method = "psci";
> +
> +			cpu_pd_wait: cpu-pd-wait {
> +				compatible = "arm,idle-state";
> +				arm,psci-suspend-param = <0x0010033>;
> +				local-timer-stop;
> +				entry-latency-us = <10000>;
> +				exit-latency-us = <7000>;
> +				min-residency-us = <27000>;
> +				wakeup-latency-us = <15000>;
> +				status = "disabled";
> +			};
> +		};
> +
> +		A55_0: cpu at 0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a55";
> +			reg = <0x0>;
> +			enable-method = "psci";
> +			#cooling-cells = <2>;
> +			cpu-idle-states = <&cpu_pd_wait>;
> +			power-domains = <&scmi_devpd IMX95_PERF_A55>;
> +			power-domain-names = "perf";
> +			i-cache-size = <32768>;
> +			i-cache-line-size = <64>;
> +			i-cache-sets = <128>;
> +			d-cache-size = <32768>;
> +			d-cache-line-size = <64>;
> +			d-cache-sets = <128>;
> +			next-level-cache = <&l2_cache_l0>;
> +		};
> +
> +		A55_1: cpu at 100 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a55";
> +			reg = <0x100>;
> +			enable-method = "psci";
> +			#cooling-cells = <2>;
> +			cpu-idle-states = <&cpu_pd_wait>;
> +			power-domains = <&scmi_devpd IMX95_PERF_A55>;
> +			power-domain-names = "perf";
> +			i-cache-size = <32768>;
> +			i-cache-line-size = <64>;
> +			i-cache-sets = <128>;
> +			d-cache-size = <32768>;
> +			d-cache-line-size = <64>;
> +			d-cache-sets = <128>;
> +			next-level-cache = <&l2_cache_l1>;
> +		};
> +
> +		A55_2: cpu at 200 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a55";
> +			reg = <0x200>;
> +			enable-method = "psci";
> +			#cooling-cells = <2>;
> +			cpu-idle-states = <&cpu_pd_wait>;
> +			power-domains = <&scmi_devpd IMX95_PERF_A55>;
> +			power-domain-names = "perf";
> +			i-cache-size = <32768>;
> +			i-cache-line-size = <64>;
> +			i-cache-sets = <128>;
> +			d-cache-size = <32768>;
> +			d-cache-line-size = <64>;
> +			d-cache-sets = <128>;
> +			next-level-cache = <&l2_cache_l2>;
> +		};
> +
> +		A55_3: cpu at 300 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a55";
> +			reg = <0x300>;
> +			enable-method = "psci";
> +			#cooling-cells = <2>;
> +			power-domains = <&scmi_devpd IMX95_PERF_A55>;
> +			power-domain-names = "perf";
> +			i-cache-size = <32768>;
> +			i-cache-line-size = <64>;
> +			i-cache-sets = <128>;
> +			d-cache-size = <32768>;
> +			d-cache-line-size = <64>;
> +			d-cache-sets = <128>;
> +			next-level-cache = <&l2_cache_l3>;
> +		};
> +
> +		A55_4: cpu at 400 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a55";
> +			reg = <0x400>;
> +			power-domains = <&scmi_devpd IMX95_PERF_A55>;
> +			power-domain-names = "perf";
> +			enable-method = "psci";
> +			#cooling-cells = <2>;
> +			cpu-idle-states = <&cpu_pd_wait>;
> +			i-cache-size = <32768>;
> +			i-cache-line-size = <64>;
> +			i-cache-sets = <128>;
> +			d-cache-size = <32768>;
> +			d-cache-line-size = <64>;
> +			d-cache-sets = <128>;
> +			next-level-cache = <&l2_cache_l4>;
> +		};
> +
> +		A55_5: cpu at 500 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a55";
> +			reg = <0x500>;
> +			power-domains = <&scmi_devpd IMX95_PERF_A55>;
> +			power-domain-names = "perf";
> +			enable-method = "psci";
> +			#cooling-cells = <2>;
> +			cpu-idle-states = <&cpu_pd_wait>;
> +			i-cache-size = <32768>;
> +			i-cache-line-size = <64>;
> +			i-cache-sets = <128>;
> +			d-cache-size = <32768>;
> +			d-cache-line-size = <64>;
> +			d-cache-sets = <128>;
> +			next-level-cache = <&l2_cache_l5>;
> +		};
> +
> +		l2_cache_l0: l2-cache-l0 {
> +			compatible = "cache";
> +			cache-size = <65536>;
> +			cache-line-size = <64>;
> +			cache-sets = <256>;
> +			cache-level = <2>;
> +			cache-unified;
> +			next-level-cache = <&l3_cache>;
> +		};
> +
> +		l2_cache_l1: l2-cache-l1 {
> +			compatible = "cache";
> +			cache-size = <65536>;
> +			cache-line-size = <64>;
> +			cache-sets = <256>;
> +			cache-level = <2>;
> +			cache-unified;
> +			next-level-cache = <&l3_cache>;
> +		};
> +
> +		l2_cache_l2: l2-cache-l2 {
> +			compatible = "cache";
> +			cache-size = <65536>;
> +			cache-line-size = <64>;
> +			cache-sets = <256>;
> +			cache-level = <2>;
> +			cache-unified;
> +			next-level-cache = <&l3_cache>;
> +		};
> +
> +		l2_cache_l3: l2-cache-l3 {
> +			compatible = "cache";
> +			cache-size = <65536>;
> +			cache-line-size = <64>;
> +			cache-sets = <256>;
> +			cache-level = <2>;
> +			cache-unified;
> +			next-level-cache = <&l3_cache>;
> +		};
> +
> +		l2_cache_l4: l2-cache-l4 {
> +			compatible = "cache";
> +			cache-size = <65536>;
> +			cache-line-size = <64>;
> +			cache-sets = <256>;
> +			cache-level = <2>;
> +			cache-unified;
> +			next-level-cache = <&l3_cache>;
> +		};
> +
> +		l2_cache_l5: l2-cache-l5 {
> +			compatible = "cache";
> +			cache-size = <65536>;
> +			cache-line-size = <64>;
> +			cache-sets = <256>;
> +			cache-level = <2>;
> +			cache-unified;
> +			next-level-cache = <&l3_cache>;
> +		};
> +
> +		l3_cache: l3-cache {
> +			compatible = "cache";
> +			cache-size = <524288>;
> +			cache-line-size = <64>;
> +			cache-sets = <1024>;
> +			cache-level = <3>;
> +			cache-unified;
> +		};
> +
> +		cpu-map {
> +			cluster0 {
> +				core0 {
> +					cpu = <&A55_0>;
> +				};
> +
> +				core1 {
> +					cpu = <&A55_1>;
> +				};
> +
> +				core2 {
> +					cpu = <&A55_2>;
> +				};
> +
> +				core3 {
> +					cpu = <&A55_3>;
> +				};
> +
> +				core4 {
> +					cpu = <&A55_4>;
> +				};
> +
> +				core5 {
> +					cpu = <&A55_5>;
> +				};
> +			};
> +		};
> +	};
> +
> +	clk_ext1: clock-ext1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <133000000>;
> +		clock-output-names = "clk_ext1";
> +	};
> +
> +	dummy: clk-dummy {

Nothing explains why do you add dummy clocks. Dummy is fake, so don't
add fake clocks to DTS.

> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <0>;
> +		clock-output-names = "dummy";
> +	};
> +
> +	sai1_mclk: sai-mclk1 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency= <0>;
> +		clock-output-names = "sai1_mclk";
> +	};
> +
> +	sai2_mclk: sai-mclk2 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency= <0>;
> +		clock-output-names = "sai2_mclk";
> +	};
> +
> +	sai3_mclk: sai-mclk3 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency= <0>;
> +		clock-output-names = "sai3_mclk";
> +	};
> +
> +	sai4_mclk: sai-mclk4 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency= <0>;
> +		clock-output-names = "sai4_mclk";
> +	};
> +
> +	sai5_mclk: sai-mclk5 {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency= <0>;
> +		clock-output-names = "sai5_mclk";
> +	};
> +
> +	osc_24m: osc-24m {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <24000000>;
> +		clock-output-names = "osc_24m";
> +	};
> +
> +	sram1: sram at 20480000 {

It does not look like you tested the DTS against bindings. Please run
`make dtbs_check W=1` (see
Documentation/devicetree/bindings/writing-schema.rst or
https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
for instructions).

> +		compatible = "mmio-sram";
> +		reg = <0x0 0x204c0000 0x0 0x18000>;
> +	};
> +
> +	firmware {
> +		scmi {
> +			compatible = "arm,scmi";
> +			mboxes = <&mu2 5 0>, <&mu2 3 0>, <&mu2 3 1>;
> +			shmem = <&scmi_buf0>, <&scmi_buf1>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			scmi_devpd: protocol at 11 {
> +				reg = <0x11>;
> +				#power-domain-cells = <1>;
> +			};
> +
> +			scmi_sys_power: protocol at 12 {
> +				reg = <0x12>;
> +			};
> +
> +			scmi_perf: protocol at 13 {
> +				reg = <0x13>;
> +				#clock-cells = <1>;
> +				#power-domain-cells = <1>;
> +			};
> +
> +			scmi_clk: protocol at 14 {
> +				reg = <0x14>;
> +				#clock-cells = <1>;
> +			};
> +
> +			scmi_sensor: protocol at 15 {
> +				reg = <0x15>;
> +				#thermal-sensor-cells = <1>;
> +			};
> +		};
> +	};
> +
> +	pmu {
> +		compatible = "arm,cortex-a55-pmu";
> +		interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
> +	};
> +
> +	thermal-zones {
> +		a55 {

It does not look like you tested the DTS against bindings. Please run
`make dtbs_check W=1` (see
Documentation/devicetree/bindings/writing-schema.rst or
https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
for instructions).

> +			polling-delay-passive = <250>;
> +			polling-delay = <2000>;
> +			thermal-sensors = <&scmi_sensor 1>;
> +
> +			trips {
> +				cpu_alert0: trip0 {
> +					temperature = <85000>;
> +					hysteresis = <2000>;
> +					type = "passive";
> +				};
> +
> +				cpu_crit0: trip1 {
> +					temperature = <95000>;
> +					hysteresis = <2000>;
> +					type = "critical";
> +				};
> +			};
> +
> +			cooling-maps {
> +				map0 {
> +					trip = <&cpu_alert0>;
> +					cooling-device =
> +						<&A55_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +						<&A55_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +						<&A55_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +						<&A55_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +						<&A55_4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +						<&A55_5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> +				};
> +			};
> +		};
> +	};
> +


> +	etm0: etm at 40840000 {

It does not look like you tested the DTS against bindings. Please run
`make dtbs_check W=1` (see
Documentation/devicetree/bindings/writing-schema.rst or
https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
for instructions).

I see you did not test it at all. No need to review. First fix all the
issues found by tooling.

This applies to all your future submissions as well. You must first run
your patches through tooling before asking people to review. Otherwise
it is huge waste of our time and quite disrespectful to that time...
> +		compatible = "arm,coresight-etm4x", "arm,primecell";
> +		reg = <0x0 0x40840000 0x0 0x10000>;
> +		arm,primecell-periphid = <0xbb95d>;
> +		cpu = <&A55_0>;
> +		clocks = <&scmi_clk IMX95_CLK_A55PERIPH>;
> +		clock-names = "apb_pclk";
> +		status = "disabled";
> +

...

> +
> +		elemu5: mailbox at 47570000 {
> +			compatible = "fsl,imx95-mu-ele";
> +			reg = <0x0 0x47570000 0x0 0x10000>;
> +			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
> +			#mbox-cells = <2>;
> +			status = "disabled";
> +		};
> +
> +		v2x_mu: v2x-mu at 47350000 {
> +			compatible = "fsl,imx95-mu-v2x";
> +			reg = <0x0 0x47350000 0x0 0x10000>;
> +			interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-names = "tx", "rx";
> +			#mbox-cells = <2>;
> +			status = "okay";

Why? Drop. This applies everywhere.


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Mon Feb 19 00:21:50 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 09:21:50 +0100
Subject: [PATCH 3/3] arm64: dts: freescale: add i.MX95 19x19 EVK minimal
 board dts
In-Reply-To: <20240218-imx95-dts-v1-3-2959f89f2018@nxp.com>
References: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>
 <20240218-imx95-dts-v1-3-2959f89f2018@nxp.com>
Message-ID: <3275fd33-c000-427e-8153-4fd976f8cb9e@linaro.org>

On 18/02/2024 07:38, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add a minimal dts for i.MX95 19x19 EVK board:
>  - lpuart1 as console
>  - sdhc1/2 as storage
> 
> As of now, because scmi pinctrl support not ready, so count on
> bootloader to set the pinctrl.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/Makefile            |  1 +
>  arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts | 88 +++++++++++++++++++++++
>  2 files changed, 89 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index 518149d295a1..c830ff88f5f8 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -209,6 +209,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba93xxca.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba93xxla.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx93-var-som-symphony.dtb
> +dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk.dtb
>  
>  imx8mm-venice-gw72xx-0x-imx219-dtbs	:= imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-imx219.dtbo
>  imx8mm-venice-gw72xx-0x-rpidsi-dtbs	:= imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-rpidsi.dtbo
> diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> new file mode 100644
> index 000000000000..9640f3b49e63
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
> @@ -0,0 +1,88 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +/dts-v1/;
> +
> +#include "imx95.dtsi"
> +
> +/ {
> +	model = "NXP i.MX95 19X19 board";
> +	compatible = "fsl,imx95-19x19-evk", "fsl,imx95";

It does not look like you tested the DTS against bindings. Please run
`make dtbs_check W=1` (see
Documentation/devicetree/bindings/writing-schema.rst or
https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
for instructions).


Really, test your patches before sending.

Best regards,
Krzysztof



From vaishnav.a at ti.com  Mon Feb 19 00:23:13 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Mon, 19 Feb 2024 13:53:13 +0530
Subject: [PATCH 2/2] arm64: dts: ti: k3-j722s-evm: Enable OSPI NOR support
In-Reply-To: <0ca01a1b-8956-40dd-8286-77276e021633@ti.com>
References: <20240216135533.904130-1-vaishnav.a@ti.com>
 <20240216135533.904130-3-vaishnav.a@ti.com>
 <0ca01a1b-8956-40dd-8286-77276e021633@ti.com>
Message-ID: <09853939-e623-42f1-bf80-1938161d1136@ti.com>

Hi Udit,

On 19/02/24 11:25, Kumar, Udit wrote:
> Hi Vaishnav
> 
> On 2/16/2024 7:25 PM, Vaishnav Achath wrote:
>> J722S EVM has S28HS512T 64 MiB Octal SPI NOR flash connected
>> to the OSPI interface, add support for the flash and describe
>> the partition information as per bootloader.
>>
>> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
>> ---
>> ? arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 79 +++++++++++++++++++++++++
>> ? 1 file changed, 79 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts 
>> b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
>> index 9e12a6e9111f..b1c6499c0c9d 100644
>> --- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
>> +++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
>> @@ -169,6 +169,23 @@ J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) 
>> MDIO0_MDIO */
>> ????????? >;
>> ????? };
>> +??? ospi0_pins_default: ospi0-default-pins {
>> +??????? pinctrl-single,pins = <
>> +??????????? J722S_IOPAD(0x0000, PIN_OUTPUT, 0) /* (P23) OSPI0_CLK */
>> +??????????? J722S_IOPAD(0x002c, PIN_OUTPUT, 0) /* (M25) OSPI0_CSn0 */
>> +??????????? J722S_IOPAD(0x000c, PIN_INPUT, 0) /* (L25) OSPI0_D0 */
>> +??????????? J722S_IOPAD(0x0010, PIN_INPUT, 0) /* (N24) OSPI0_D1 */
>> +??????????? J722S_IOPAD(0x0014, PIN_INPUT, 0) /* (N25) OSPI0_D2 */
>> +??????????? J722S_IOPAD(0x0018, PIN_INPUT, 0) /* (M24) OSPI0_D3 */
>> +??????????? J722S_IOPAD(0x001c, PIN_INPUT, 0) /* (N21) OSPI0_D4 */
>> +??????????? J722S_IOPAD(0x0020, PIN_INPUT, 0) /* (N22) OSPI0_D5 */
>> +??????????? J722S_IOPAD(0x0024, PIN_INPUT, 0) /* (P21) OSPI0_D6 */
>> +??????????? J722S_IOPAD(0x0028, PIN_INPUT, 0) /* (N20) OSPI0_D7 */
>> +??????????? J722S_IOPAD(0x0008, PIN_INPUT, 0) /* (P22) OSPI0_DQS */
> 
> 
> Could you check, Pin name in comments
> 
> For example, Schematic says L22 is for OSPI0_DQS , but comments says P22
> 
> However offsets are good .

Thanks for the review, I will fix this in the next revision.

> 
>> +??????? >;
>> +??????? bootph-all;
>> +??? };
>> +
>> ????? rgmii1_pins_default: rgmii1-default-pins {
>> ????????? pinctrl-single,pins = <
>> ????????????? J722S_IOPAD(0x014c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */
>> @@ -290,6 +307,68 @@ exp1: gpio at 23 {
>> ????? };
>> ? };
>> +&ospi0 {
>> +??? pinctrl-names = "default";
>> +??? pinctrl-0 = <&ospi0_pins_default>;
>> +??? status = "okay";
>> +
>> +??? flash at 0 {
>> +??????? compatible = "jedec,spi-nor";
>> +??????? reg = <0x0>;
>> +??????? spi-tx-bus-width = <8>;
>> +??????? spi-rx-bus-width = <8>;
>> +??????? spi-max-frequency = <25000000>;
>> +??????? cdns,tshsl-ns = <60>;
>> +??????? cdns,tsd2d-ns = <60>;
>> +??????? cdns,tchsh-ns = <60>;
>> +??????? cdns,tslch-ns = <60>;
>> +??????? cdns,read-delay = <4>;
>> +??????? bootph-all;
>> +
>> +??????? partitions {
>> +??????????? compatible = "fixed-partitions";
>> +??????????? #address-cells = <1>;
>> +??????????? #size-cells = <1>;
>> +
>> +??????????? partition at 0 {
>> +??????????????? label = "ospi.tiboot3";
>> +??????????????? reg = <0x00 0x80000>;
>> +??????????? };
> 
> 
> I suggest to keep 1MB to accommodate future size increase
> 

For J722S, the maximum loadable SPL size is 0x7e000, images larger than 
these cannot be loaded by ROM, increasing the size here will not give 
any benefit, planning to keep as-is if there are no objections.

Thanks and Regards,
Vaishnav

>> +
>> +??????????? partition at 80000 {
>> +??????????????? label = "ospi.tispl";
>> +??????????????? reg = <0x80000 0x200000>;
>> +??????????? };
>> +
>> +??????????? partition at 280000 {
>> +??????????????? label = "ospi.u-boot";
>> +??????????????? reg = <0x280000 0x400000>;
>> +??????????? };
>> +
>> +??????????? partition at 680000 {
>> +??????????????? label = "ospi.env";
>> +??????????????? reg = <0x680000 0x40000>;
>> +??????????? };
>> +
>> +??????????? partition at 6c0000 {
>> +??????????????? label = "ospi.env.backup";
>> +??????????????? reg = <0x6c0000 0x40000>;
>> +??????????? };
>> +
>> +??????????? partition at 800000 {
>> +??????????????? label = "ospi.rootfs";
>> +??????????????? reg = <0x800000 0x37c0000>;
>> +??????????? };
>> +
>> +??????????? partition at 3fc0000 {
>> +??????????????? label = "ospi.phypattern";
>> +??????????????? reg = <0x3fc0000 0x40000>;
>> +??????????? };
>> +??????? };
>> +??? };
>> +
>> +};
>> +
>> ? &sdhci1 {
>> ????? /* SD/MMC */
>> ????? vmmc-supply = <&vdd_mmc1>;


From mshavit at google.com  Mon Feb 19 00:32:40 2024
From: mshavit at google.com (Michael Shavit)
Date: Mon, 19 Feb 2024 16:32:40 +0800
Subject: [PATCH rc v2] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
In-Reply-To: <20240217132446.GJ13330@nvidia.com>
References: <0-v2-7988c2682634+261-smmu_cd_atomic_jgg@nvidia.com>
 <20240216120512.GA1841@willie-the-truck> <20240216123606.GA13330@nvidia.com>
 <CAKHBV27eBnCrnXeaoqONWksh89tfX1b0=yvLfTkxviU_wKG_mw@mail.gmail.com> <20240217132446.GJ13330@nvidia.com>
Message-ID: <CAKHBV26bwkvRAeyNuiUdmh0OWmvLfS7Ja8OHabT-H9nUY=SyNg@mail.gmail.com>

On Sat, Feb 17, 2024 at 9:24?PM Jason Gunthorpe <jgg at nvidia.com> wrote:
>
> On Sat, Feb 17, 2024 at 08:25:36PM +0800, Michael Shavit wrote:
>
> > Calling arm_smmu_write_ctx_desc requires the CD which we get from the
> > mmu_notifiers list...which makes it a bit more complicated than
> > that.
>
> @@ -404,9 +384,15 @@ static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
>                 goto err_free_bond;
>         }
>
> +       ret = arm_smmu_write_ctx_desc(master, pasid, bond->smmu_mn->cd);
> +       if (ret)
> +               goto err_put_notifier;
> +
>
Oh hey that's not much more complicated :) . I'm guessing that'll be a
call to arm_smmu_mmu_notifier_put() rather than a goto on the error
path?
Speaking of... the arm_smmu_update_ctx_desc_devices call in
arm_smmu_mmu_notifier_put might be tricky as well if it's encountered
on the error path before all devices (in theoretical non-pci case) had
a chance to previously call arm_smmu_write_ctx_desc.


From neil.armstrong at linaro.org  Mon Feb 19 00:35:27 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 19 Feb 2024 09:35:27 +0100
Subject: [PATCH v1] drm/meson: improve encoder probe / initialization
 error handling
In-Reply-To: <20240218175035.1948165-1-martin.blumenstingl@googlemail.com>
References: <20240218175035.1948165-1-martin.blumenstingl@googlemail.com>
Message-ID: <4cfb1b74-7941-45af-a60e-0661b1888b79@linaro.org>

On 18/02/2024 18:50, Martin Blumenstingl wrote:
> Rename meson_encoder_{cvbs,dsi,hdmi}_init() to
> meson_encoder_{cvbs,dsi,hdmi}_probe() so it's clear that these functions
> are used at probe time during driver initialization. Also switch all
> error prints inside those functions to use dev_err_probe() for
> consistency.
> 
> This makes the code more straight forward to read and makes the error
> prints within those functions consistent (by logging all -EPROBE_DEFER
> with dev_dbg(), while actual errors are logged with dev_err() and get
> the error value printed).
> 
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---
> This is meant to be applied on top of my other patch called
> "drm/meson: Don't remove bridges which are created by other drivers" [0]
> 
> 
> [0] https://lore.kernel.org/dri-devel/20240215220442.1343152-1-martin.blumenstingl at googlemail.com/
> 
> 
>   drivers/gpu/drm/meson/meson_drv.c          |  6 +++---
>   drivers/gpu/drm/meson/meson_encoder_cvbs.c | 24 ++++++++++------------
>   drivers/gpu/drm/meson/meson_encoder_cvbs.h |  2 +-
>   drivers/gpu/drm/meson/meson_encoder_dsi.c  | 23 +++++++++------------
>   drivers/gpu/drm/meson/meson_encoder_dsi.h  |  2 +-
>   drivers/gpu/drm/meson/meson_encoder_hdmi.c | 15 +++++++-------
>   drivers/gpu/drm/meson/meson_encoder_hdmi.h |  2 +-
>   7 files changed, 35 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index cb674966e9ac..17a5cca007e2 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -312,7 +312,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
>   
>   	/* Encoder Initialization */
>   
> -	ret = meson_encoder_cvbs_init(priv);
> +	ret = meson_encoder_cvbs_probe(priv);
>   	if (ret)
>   		goto exit_afbcd;
>   
> @@ -326,12 +326,12 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
>   		}
>   	}
>   
> -	ret = meson_encoder_hdmi_init(priv);
> +	ret = meson_encoder_hdmi_probe(priv);
>   	if (ret)
>   		goto exit_afbcd;
>   
>   	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
> -		ret = meson_encoder_dsi_init(priv);
> +		ret = meson_encoder_dsi_probe(priv);
>   		if (ret)
>   			goto exit_afbcd;
>   	}
> diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
> index 3407450435e2..d1191de855d9 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
> +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
> @@ -219,7 +219,7 @@ static const struct drm_bridge_funcs meson_encoder_cvbs_bridge_funcs = {
>   	.atomic_reset = drm_atomic_helper_bridge_reset,
>   };
>   
> -int meson_encoder_cvbs_init(struct meson_drm *priv)
> +int meson_encoder_cvbs_probe(struct meson_drm *priv)
>   {
>   	struct drm_device *drm = priv->drm;
>   	struct meson_encoder_cvbs *meson_encoder_cvbs;
> @@ -240,10 +240,9 @@ int meson_encoder_cvbs_init(struct meson_drm *priv)
>   
>   	meson_encoder_cvbs->next_bridge = of_drm_find_bridge(remote);
>   	of_node_put(remote);
> -	if (!meson_encoder_cvbs->next_bridge) {
> -		dev_err(priv->dev, "Failed to find CVBS Connector bridge\n");
> -		return -EPROBE_DEFER;
> -	}
> +	if (!meson_encoder_cvbs->next_bridge)
> +		return dev_err_probe(priv->dev, -EPROBE_DEFER,
> +				     "Failed to find CVBS Connector bridge\n");
>   
>   	/* CVBS Encoder Bridge */
>   	meson_encoder_cvbs->bridge.funcs = &meson_encoder_cvbs_bridge_funcs;
> @@ -259,10 +258,9 @@ int meson_encoder_cvbs_init(struct meson_drm *priv)
>   	/* Encoder */
>   	ret = drm_simple_encoder_init(priv->drm, &meson_encoder_cvbs->encoder,
>   				      DRM_MODE_ENCODER_TVDAC);
> -	if (ret) {
> -		dev_err(priv->dev, "Failed to init CVBS encoder: %d\n", ret);
> -		return ret;
> -	}
> +	if (ret)
> +		return dev_err_probe(priv->dev, ret,
> +				     "Failed to init CVBS encoder\n");
>   
>   	meson_encoder_cvbs->encoder.possible_crtcs = BIT(0);
>   
> @@ -276,10 +274,10 @@ int meson_encoder_cvbs_init(struct meson_drm *priv)
>   
>   	/* Initialize & attach Bridge Connector */
>   	connector = drm_bridge_connector_init(priv->drm, &meson_encoder_cvbs->encoder);
> -	if (IS_ERR(connector)) {
> -		dev_err(priv->dev, "Unable to create CVBS bridge connector\n");
> -		return PTR_ERR(connector);
> -	}
> +	if (IS_ERR(connector))
> +		return dev_err_probe(priv->dev, PTR_ERR(connector),
> +				     "Unable to create CVBS bridge connector\n");
> +
>   	drm_connector_attach_encoder(connector, &meson_encoder_cvbs->encoder);
>   
>   	priv->encoders[MESON_ENC_CVBS] = meson_encoder_cvbs;
> diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.h b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
> index 09710fec3c66..7b7bc85c03f7 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.h
> +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
> @@ -24,7 +24,7 @@ struct meson_cvbs_mode {
>   /* Modes supported by the CVBS output */
>   extern struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT];
>   
> -int meson_encoder_cvbs_init(struct meson_drm *priv);
> +int meson_encoder_cvbs_probe(struct meson_drm *priv);
>   void meson_encoder_cvbs_remove(struct meson_drm *priv);
>   
>   #endif /* __MESON_VENC_CVBS_H */
> diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
> index 311b91630fbe..7816902f5907 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_dsi.c
> +++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
> @@ -100,7 +100,7 @@ static const struct drm_bridge_funcs meson_encoder_dsi_bridge_funcs = {
>   	.atomic_reset = drm_atomic_helper_bridge_reset,
>   };
>   
> -int meson_encoder_dsi_init(struct meson_drm *priv)
> +int meson_encoder_dsi_probe(struct meson_drm *priv)
>   {
>   	struct meson_encoder_dsi *meson_encoder_dsi;
>   	struct device_node *remote;
> @@ -118,10 +118,9 @@ int meson_encoder_dsi_init(struct meson_drm *priv)
>   	}
>   
>   	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\n");
> -		return -EPROBE_DEFER;
> -	}
> +	if (!meson_encoder_dsi->next_bridge)
> +		return dev_err_probe(priv->dev, -EPROBE_DEFER,
> +				     "Failed to find DSI transceiver bridge\n");
>   
>   	/* DSI Encoder Bridge */
>   	meson_encoder_dsi->bridge.funcs = &meson_encoder_dsi_bridge_funcs;
> @@ -135,19 +134,17 @@ int meson_encoder_dsi_init(struct meson_drm *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;
> -	}
> +	if (ret)
> +		return dev_err_probe(priv->dev, ret,
> +				     "Failed to init DSI encoder\n");
>   
>   	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;
> -	}
> +	if (ret)
> +		return dev_err_probe(priv->dev, ret,
> +				     "Failed to attach bridge\n");
>   
>   	/*
>   	 * We should have now in place:
> diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.h b/drivers/gpu/drm/meson/meson_encoder_dsi.h
> index 9277d7015193..85d5b61805f2 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_dsi.h
> +++ b/drivers/gpu/drm/meson/meson_encoder_dsi.h
> @@ -7,7 +7,7 @@
>   #ifndef __MESON_ENCODER_DSI_H
>   #define __MESON_ENCODER_DSI_H
>   
> -int meson_encoder_dsi_init(struct meson_drm *priv);
> +int meson_encoder_dsi_probe(struct meson_drm *priv);
>   void meson_encoder_dsi_remove(struct meson_drm *priv);
>   
>   #endif /* __MESON_ENCODER_DSI_H */
> diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
> index c4686568c9ca..22e07847a9a7 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
> +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
> @@ -354,7 +354,7 @@ static const struct drm_bridge_funcs meson_encoder_hdmi_bridge_funcs = {
>   	.atomic_reset = drm_atomic_helper_bridge_reset,
>   };
>   
> -int meson_encoder_hdmi_init(struct meson_drm *priv)
> +int meson_encoder_hdmi_probe(struct meson_drm *priv)
>   {
>   	struct meson_encoder_hdmi *meson_encoder_hdmi;
>   	struct platform_device *pdev;
> @@ -374,8 +374,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
>   
>   	meson_encoder_hdmi->next_bridge = of_drm_find_bridge(remote);
>   	if (!meson_encoder_hdmi->next_bridge) {
> -		dev_err(priv->dev, "Failed to find HDMI transceiver bridge\n");
> -		ret = -EPROBE_DEFER;
> +		ret = dev_err_probe(priv->dev, -EPROBE_DEFER,
> +				    "Failed to find HDMI transceiver bridge\n");
>   		goto err_put_node;
>   	}
>   
> @@ -393,7 +393,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
>   	ret = drm_simple_encoder_init(priv->drm, &meson_encoder_hdmi->encoder,
>   				      DRM_MODE_ENCODER_TMDS);
>   	if (ret) {
> -		dev_err(priv->dev, "Failed to init HDMI encoder: %d\n", ret);
> +		dev_err_probe(priv->dev, ret, "Failed to init HDMI encoder\n");
>   		goto err_put_node;
>   	}
>   
> @@ -403,7 +403,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
>   	ret = drm_bridge_attach(&meson_encoder_hdmi->encoder, &meson_encoder_hdmi->bridge, NULL,
>   				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>   	if (ret) {
> -		dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
> +		dev_err_probe(priv->dev, ret, "Failed to attach bridge\n");
>   		goto err_put_node;
>   	}
>   
> @@ -411,8 +411,9 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
>   	meson_encoder_hdmi->connector = drm_bridge_connector_init(priv->drm,
>   							&meson_encoder_hdmi->encoder);
>   	if (IS_ERR(meson_encoder_hdmi->connector)) {
> -		dev_err(priv->dev, "Unable to create HDMI bridge connector\n");
> -		ret = PTR_ERR(meson_encoder_hdmi->connector);
> +		ret = dev_err_probe(priv->dev,
> +				    PTR_ERR(meson_encoder_hdmi->connector),
> +				    "Unable to create HDMI bridge connector\n");
>   		goto err_put_node;
>   	}
>   	drm_connector_attach_encoder(meson_encoder_hdmi->connector,
> diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.h b/drivers/gpu/drm/meson/meson_encoder_hdmi.h
> index a6cd38eb5f71..fd5485875db8 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.h
> +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.h
> @@ -7,7 +7,7 @@
>   #ifndef __MESON_ENCODER_HDMI_H
>   #define __MESON_ENCODER_HDMI_H
>   
> -int meson_encoder_hdmi_init(struct meson_drm *priv);
> +int meson_encoder_hdmi_probe(struct meson_drm *priv);
>   void meson_encoder_hdmi_remove(struct meson_drm *priv);
>   
>   #endif /* __MESON_ENCODER_HDMI_H */

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 19 00:36:44 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 19 Feb 2024 09:36:44 +0100
Subject: [DMARC error][DKIM error] [PATCH 0/5] soc: amlogic: add new
 meson-gx-socinfo-sm driver
In-Reply-To: <20240216074716.a33hrvl5xnpm7aep@CAB-WSD-L081021>
References: <20231122125643.1717160-1-adeep@lexina.in>
 <20240216074716.a33hrvl5xnpm7aep@CAB-WSD-L081021>
Message-ID: <475dd166-6590-4a76-b076-a878c784ae31@linaro.org>

On 16/02/2024 08:47, Dmitry Rokosov wrote:
> Hello Neil,
> 
> May I put in my two cents on this patch series?
> 
> There appears to be a misunderstanding regarding the terminology used.
> Allow me to clarify my perspective.
> 
> The original Amlogic chipid has the following format:
> 
>      4 bytes      12 bytes
>      +-------+-------------------+
>      |       |                   |
>      | CPUID | SOC SERIAL NUMBER |
>      |       |                   |
>      +-------+-------------------+
>      0                          15
> 
> 
> In the current uboot [1] and kernel [2] upstream, only the SOC SERIAL
> NUMBER bytes are read from efuse OTP storage (and it isn't swapped, as
> Amlogic reference code does [3]). We refer to these bytes as "serial".
> 
> The original chipid value is utilized in several algorithms (for
> example, in the Amlogic boot protocols), making it crucial to have the
> ability to read the original chipid value as intended by the vendor.
> 
> In my opinion, we should align our naming terminology as follows:
>      - "chipid" - Represents the complete Amlogic SoC ID, includes
>                   "cpuid" and "serial"
>      - "serial" - 12 byte unique SoC number, identifying particular die
> 
> We strongly believe that this patch series is essential and are highly interested in seeing it applied to the upstream linux-amlogic, for the following reasons:
>      - We use chipid for device identification in our boards
>      - The Amlogic boot protocols utilize the full version of chipid
>        (ADNL, Optimus). As I mentioned in the IRC, we are preparing a
>        patch series for uboot incorporating them.
>      - in OPTEE: for generation of SSK (Secure Storage Key) [4]
>      - RPMB: for generation of RPMB key, further provisioned into RPMB
>        controller (thus particular SoC is bound to particular eMMC
> 
> Therefore, I propose that we rename "soc_id" in the Viacheslav patch
> series to "chipid" and subsequently port this patch series to uboot.
> 
> What are your thoughts on this matter?

I'm perfectly fine with that, but I don't like the shared functions, the only
shared stuff are the soc id tables, the shared functions is not important enough
to be shared.

Neil

> 
> Links:
> [1] - https://elixir.bootlin.com/u-boot/v2024.01/source/arch/arm/mach-meson/sm.c#L84
> [2] - https://elixir.bootlin.com/linux/v6.7.4/source/drivers/firmware/meson/meson_sm.c#L268
> [3] - https://github.com/CoreELEC/u-boot/blob/3efc85a8370796bcec3bcadcdecec9aed973f4a9/arch/arm/mach-meson/g12a/bl31_apis.c#L398-L417
> [4] - https://github.com/OP-TEE/optee_os/blob/5df2a985b2ffd0b6f1107f12ca2a88203bf31328/core/tee/tee_fs_key_manager.c#L152
> 
> On Wed, Nov 22, 2023 at 03:56:38PM +0300, Viacheslav Bocharov wrote:
>> The Amlogic Meson SoC Secure Monitor implements a call to retrieve an
>> unique SoC ID starting from the GX Family and all new families.
>> But GX-family chips (e.g. GXB, GXL and newer) supports also 128-bit
>> chip ID. 128-bit chip ID consists 32-bit SoC version and 96-bit OTP data.
>>
>> This is the second attempt to publish data from the Amlogic secure monitor
>> chipid call. After discussions with Neil Armstrong, it was decided to
>> publish the chipid call results through the soc driver. Since
>> soc_device_match cannot wait for the soc driver to load, and the secure
>> monitor calls in turn depend on the sm driver, it was necessary to create
>> a new driver rather than expand an existing one.
>>
>> In the patches, in addition to writing the driver:
>> - convert commonly used structures and functions of the meson-gx-socinfo
>> driver to a header file.
>> - transfer the chipid sm call constants to a header file (perhaps they
>> need renaming?).
>> - add secure-monitor references for amlogic,meson-gx-ao-secure sections
>> in dts files of the a1, axg, g12, gx families.
>>
>> Viacheslav Bocharov (5):
>>    soc: amlogic: meson-gx-socinfo: move common code to header file
>>    soc: amlogic: meson-gx-socinfo: move common code to exported function
>>    firmware: meson_sm: move common definitions to header file
>>    soc: amlogic: Add Amlogic secure-monitor SoC Information driver
>>    arm64: dts: meson: add dts links to secure-monitor for soc driver in
>>      a1, axg, gx, g12
>>
>>   arch/arm64/boot/dts/amlogic/meson-a1.dtsi     |   1 +
>>   arch/arm64/boot/dts/amlogic/meson-axg.dtsi    |   1 +
>>   .../boot/dts/amlogic/meson-g12-common.dtsi    |   1 +
>>   arch/arm64/boot/dts/amlogic/meson-gx.dtsi     |   1 +
>>   drivers/firmware/meson/meson_sm.c             |   4 -
>>   drivers/soc/amlogic/Kconfig                   |  10 +
>>   drivers/soc/amlogic/Makefile                  |   1 +
>>   .../soc/amlogic/meson-gx-socinfo-internal.h   | 102 ++++++++++
>>   drivers/soc/amlogic/meson-gx-socinfo-sm.c     | 178 ++++++++++++++++++
>>   drivers/soc/amlogic/meson-gx-socinfo.c        | 106 ++---------
>>   include/linux/firmware/meson/meson_sm.h       |   4 +
>>   11 files changed, 317 insertions(+), 92 deletions(-)
>>   create mode 100644 drivers/soc/amlogic/meson-gx-socinfo-internal.h
>>   create mode 100644 drivers/soc/amlogic/meson-gx-socinfo-sm.c
>>
>> -- 
>> 2.34.1
>>
>>
>> _______________________________________________
>> linux-amlogic mailing list
>> linux-amlogic at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-amlogic
> 



From neil.armstrong at linaro.org  Mon Feb 19 00:37:37 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 19 Feb 2024 09:37:37 +0100
Subject: [PATCH v1 0/3] ARM: dts: amlogic: Three small binding check error
 fixes
In-Reply-To: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>
References: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>
Message-ID: <f1dd75d3-d86b-447a-8a76-73da7d14c936@linaro.org>

On 18/02/2024 12:19, Martin Blumenstingl wrote:
> This series contains three small binding check fixes.
> Nothing functional was broken before, so no need to backpport any of
> these to -stable.
> 
> 
> Martin Blumenstingl (3):
>    ARM: dts: meson: fix bus node names
>    ARM: dts: meson8: fix &hwrng node compatible string
>    ARM: dts: meson8b: fix &hwrng node compatible string
> 
>   arch/arm/boot/dts/amlogic/meson.dtsi   | 6 +++---
>   arch/arm/boot/dts/amlogic/meson8.dtsi  | 1 -
>   arch/arm/boot/dts/amlogic/meson8b.dtsi | 1 -
>   3 files changed, 3 insertions(+), 5 deletions(-)
> 

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 19 00:38:21 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 19 Feb 2024 09:38:21 +0100
Subject: [PATCH] drm/meson: Don't remove bridges which are created by
 other drivers
In-Reply-To: <20240215220442.1343152-1-martin.blumenstingl@googlemail.com>
References: <20240215220442.1343152-1-martin.blumenstingl@googlemail.com>
Message-ID: <f2cde221-a779-486a-9073-44228c320d8a@linaro.org>

On 15/02/2024 23:04, Martin Blumenstingl wrote:
> Stop calling drm_bridge_remove() for bridges allocated/managed by other
> drivers in the remove paths of meson_encoder_{cvbs,dsi,hdmi}.
> drm_bridge_remove() unregisters the bridge so it cannot be used
> anymore. Doing so for bridges we don't own can lead to the video
> pipeline not being able to come up after -EPROBE_DEFER of the VPU
> because we're unregistering a bridge that's managed by another driver.
> The other driver doesn't know that we have unregistered it's bridge
> and on subsequent .probe() we're not able to find those bridges anymore
> (since nobody re-creates them).
> 
> This fixes probe errors on Meson8b boards with the CVBS outputs enabled.
> 
> Fixes: 09847723c12f ("drm/meson: remove drm bridges at aggregate driver unbind time")
> Fixes: 42dcf15f901c ("drm/meson: add DSI encoder")
> Cc: stable at vger.kernel.org
> Reported-by: Steve Morvai <stevemorvai at hotmail.com>
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---
> This issue was reported by Steve off-list to me (thanks again for your
> patience and sorry it took so long)!
> The Meson8b VPU driver is not upstream, but the problematic code is.
> Meaning: This issue can also appear on SoCs which are supported
> upstream if the meson DRM driver probe has to be re-tried (with
> -EPROBE_DEFER). That's why I chose to Cc the stable list.
> 
> 
>   drivers/gpu/drm/meson/meson_encoder_cvbs.c | 1 -
>   drivers/gpu/drm/meson/meson_encoder_dsi.c  | 1 -
>   drivers/gpu/drm/meson/meson_encoder_hdmi.c | 1 -
>   3 files changed, 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
> index 3f73b211fa8e..3407450435e2 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
> +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
> @@ -294,6 +294,5 @@ void meson_encoder_cvbs_remove(struct meson_drm *priv)
>   	if (priv->encoders[MESON_ENC_CVBS]) {
>   		meson_encoder_cvbs = priv->encoders[MESON_ENC_CVBS];
>   		drm_bridge_remove(&meson_encoder_cvbs->bridge);
> -		drm_bridge_remove(meson_encoder_cvbs->next_bridge);
>   	}
>   }
> diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
> index 3f93c70488ca..311b91630fbe 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_dsi.c
> +++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
> @@ -168,6 +168,5 @@ void meson_encoder_dsi_remove(struct meson_drm *priv)
>   	if (priv->encoders[MESON_ENC_DSI]) {
>   		meson_encoder_dsi = priv->encoders[MESON_ENC_DSI];
>   		drm_bridge_remove(&meson_encoder_dsi->bridge);
> -		drm_bridge_remove(meson_encoder_dsi->next_bridge);
>   	}
>   }
> diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
> index 25ea76558690..c4686568c9ca 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
> +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
> @@ -474,6 +474,5 @@ void meson_encoder_hdmi_remove(struct meson_drm *priv)
>   	if (priv->encoders[MESON_ENC_HDMI]) {
>   		meson_encoder_hdmi = priv->encoders[MESON_ENC_HDMI];
>   		drm_bridge_remove(&meson_encoder_hdmi->bridge);
> -		drm_bridge_remove(meson_encoder_hdmi->next_bridge);
>   	}
>   }

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>

Thanks a lot for the patch!

Neil


From cassel at kernel.org  Mon Feb 19 00:39:35 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Mon, 19 Feb 2024 09:39:35 +0100
Subject: [PATCH] dt-bindings: ata: convert MediaTek controller to the
 json-schema
In-Reply-To: <20240213074747.26151-1-zajec5@gmail.com>
References: <20240213074747.26151-1-zajec5@gmail.com>
Message-ID: <ZdMTx1CJzFR5uAzK@x1-carbon>

On Tue, Feb 13, 2024 at 08:47:47AM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Hello Rob,

For device tree patches for
Documentation/devicetree/bindings/ata/

Usually, if we see your Acked-by, we queue the patch via the libata tree.
(If it is part of a series, usually you take it via your tree.)

We have a R-b from Krzysztof, but no Ack from you.


Kind regards,
Niklas


From mwalle at kernel.org  Mon Feb 19 00:44:55 2024
From: mwalle at kernel.org (Michael Walle)
Date: Mon, 19 Feb 2024 09:44:55 +0100
Subject: [PATCH v2 1/2] dt-bindings: arm64: mediatek: add Kontron 3.5"-SBC-i1200
Message-ID: <20240219084456.1075445-1-mwalle@kernel.org>

Add the compatible string for the Kontron 3.5"-SBC-i1200 single board
computer.

Signed-off-by: Michael Walle <mwalle at kernel.org>
---
v2:
 - convert enum to const as there is only one specific board

 Documentation/devicetree/bindings/arm/mediatek.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 09f9ffd3ff7b..add167d8b8da 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -357,6 +357,11 @@ properties:
               - radxa,nio-12l
           - const: mediatek,mt8395
           - const: mediatek,mt8195
+      - description: Kontron 3.5"-SBC-i1200
+        items:
+          - const: kontron,3-5-sbc-i1200
+          - const: mediatek,mt8395
+          - const: mediatek,mt8195
       - items:
           - enum:
               - mediatek,mt8516-pumpkin
-- 
2.39.2



From u-kumar1 at ti.com  Mon Feb 19 00:45:10 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Mon, 19 Feb 2024 14:15:10 +0530
Subject: [PATCH 2/2] arm64: dts: ti: k3-j722s-evm: Enable OSPI NOR support
In-Reply-To: <09853939-e623-42f1-bf80-1938161d1136@ti.com>
References: <20240216135533.904130-1-vaishnav.a@ti.com>
 <20240216135533.904130-3-vaishnav.a@ti.com>
 <0ca01a1b-8956-40dd-8286-77276e021633@ti.com>
 <09853939-e623-42f1-bf80-1938161d1136@ti.com>
Message-ID: <64726f87-a909-4f85-93b5-e12c9a83e251@ti.com>

Hi?Vaishnav

On 2/19/2024 1:53 PM, Vaishnav Achath wrote:
> Hi Udit,
>
> On 19/02/24 11:25, Kumar, Udit wrote:
>> Hi Vaishnav
>>
>> On 2/16/2024 7:25 PM, Vaishnav Achath wrote:
>>> J722S EVM has S28HS512T 64 MiB Octal SPI NOR flash connected
>>> to the OSPI interface, add support for the flash and describe
>>> the partition information as per bootloader.
>>>
>>> Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
>>> ---
>>> ? arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 79 
>>> +++++++++++++++++++++++++
>>> ? 1 file changed, 79 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts 
>>> b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
>>> index 9e12a6e9111f..b1c6499c0c9d 100644
>>> --- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
>>> +++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
>>> @@ -169,6 +169,23 @@ J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) 
>>> MDIO0_MDIO */
>>> ????????? >;
>>> ????? };
>>> +??? ospi0_pins_default: ospi0-default-pins {
>>> +??????? pinctrl-single,pins = <
>>> +??????????? J722S_IOPAD(0x0000, PIN_OUTPUT, 0) /* (P23) OSPI0_CLK */
>>> +??????????? J722S_IOPAD(0x002c, PIN_OUTPUT, 0) /* (M25) OSPI0_CSn0 */
>>> +??????????? J722S_IOPAD(0x000c, PIN_INPUT, 0) /* (L25) OSPI0_D0 */
>>> +??????????? J722S_IOPAD(0x0010, PIN_INPUT, 0) /* (N24) OSPI0_D1 */
>>> +??????????? J722S_IOPAD(0x0014, PIN_INPUT, 0) /* (N25) OSPI0_D2 */
>>> +??????????? J722S_IOPAD(0x0018, PIN_INPUT, 0) /* (M24) OSPI0_D3 */
>>> +??????????? J722S_IOPAD(0x001c, PIN_INPUT, 0) /* (N21) OSPI0_D4 */
>>> +??????????? J722S_IOPAD(0x0020, PIN_INPUT, 0) /* (N22) OSPI0_D5 */
>>> +??????????? J722S_IOPAD(0x0024, PIN_INPUT, 0) /* (P21) OSPI0_D6 */
>>> +??????????? J722S_IOPAD(0x0028, PIN_INPUT, 0) /* (N20) OSPI0_D7 */
>>> +??????????? J722S_IOPAD(0x0008, PIN_INPUT, 0) /* (P22) OSPI0_DQS */
>>
>>
>> Could you check, Pin name in comments
>>
>> For example, Schematic says L22 is for OSPI0_DQS , but comments says P22
>>
>> However offsets are good .
>
> Thanks for the review, I will fix this in the next revision.
>
>>
>>> +??????? >;
>>> +??????? bootph-all;
>>> +??? };
>>> +
>>> ????? rgmii1_pins_default: rgmii1-default-pins {
>>> ????????? pinctrl-single,pins = <
>>> ????????????? J722S_IOPAD(0x014c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */
>>> @@ -290,6 +307,68 @@ exp1: gpio at 23 {
>>> ????? };
>>> ? };
>>> +&ospi0 {
>>> +??? pinctrl-names = "default";
>>> +??? pinctrl-0 = <&ospi0_pins_default>;
>>> +??? status = "okay";
>>> +
>>> +??? flash at 0 {
>>> +??????? compatible = "jedec,spi-nor";
>>> +??????? reg = <0x0>;
>>> +??????? spi-tx-bus-width = <8>;
>>> +??????? spi-rx-bus-width = <8>;
>>> +??????? spi-max-frequency = <25000000>;
>>> +??????? cdns,tshsl-ns = <60>;
>>> +??????? cdns,tsd2d-ns = <60>;
>>> +??????? cdns,tchsh-ns = <60>;
>>> +??????? cdns,tslch-ns = <60>;
>>> +??????? cdns,read-delay = <4>;
>>> +??????? bootph-all;
>>> +
>>> +??????? partitions {
>>> +??????????? compatible = "fixed-partitions";
>>> +??????????? #address-cells = <1>;
>>> +??????????? #size-cells = <1>;
>>> +
>>> +??????????? partition at 0 {
>>> +??????????????? label = "ospi.tiboot3";
>>> +??????????????? reg = <0x00 0x80000>;
>>> +??????????? };
>>
>>
>> I suggest to keep 1MB to accommodate future size increase
>>
>
> For J722S, the maximum loadable SPL size is 0x7e000, images larger 
> than these cannot be loaded by ROM, increasing the size here will not 
> give any benefit, planning to keep as-is if there are no objections.
>
If ROM is limiting size here, then no need to increase this


> Thanks and Regards,
> Vaishnav
>
>>> +
>>> +??????????? partition at 80000 {
>>> +??????????????? label = "ospi.tispl";
>>> +??????????????? reg = <0x80000 0x200000>;
>>> +??????????? };
>>> +
>>> +??????????? partition at 280000 {
>>> +??????????????? label = "ospi.u-boot";
>>> +??????????????? reg = <0x280000 0x400000>;
>>> +??????????? };
>>> +
>>> +??????????? partition at 680000 {
>>> +??????????????? label = "ospi.env";
>>> +??????????????? reg = <0x680000 0x40000>;
>>> +??????????? };
>>> +
>>> +??????????? partition at 6c0000 {
>>> +??????????????? label = "ospi.env.backup";
>>> +??????????????? reg = <0x6c0000 0x40000>;
>>> +??????????? };
>>> +
>>> +??????????? partition at 800000 {
>>> +??????????????? label = "ospi.rootfs";
>>> +??????????????? reg = <0x800000 0x37c0000>;
>>> +??????????? };
>>> +
>>> +??????????? partition at 3fc0000 {
>>> +??????????????? label = "ospi.phypattern";
>>> +??????????????? reg = <0x3fc0000 0x40000>;
>>> +??????????? };
>>> +??????? };
>>> +??? };
>>> +
>>> +};
>>> +
>>> ? &sdhci1 {
>>> ????? /* SD/MMC */
>>> ????? vmmc-supply = <&vdd_mmc1>;


From mwalle at kernel.org  Mon Feb 19 00:44:56 2024
From: mwalle at kernel.org (Michael Walle)
Date: Mon, 19 Feb 2024 09:44:56 +0100
Subject: [PATCH v2 2/2] arm64: dts: mediatek: add Kontron 3.5"-SBC-i1200
In-Reply-To: <20240219084456.1075445-1-mwalle@kernel.org>
References: <20240219084456.1075445-1-mwalle@kernel.org>
Message-ID: <20240219084456.1075445-2-mwalle@kernel.org>

Add basic support for the Kontron 3.5" single board computer featuring a
Mediatek i1200 SoC (MT8395/MT8195).

Signed-off-by: Michael Walle <mwalle at kernel.org>
---
v2:
 - none

 arch/arm64/boot/dts/mediatek/Makefile         |    1 +
 .../mediatek/mt8395-kontron-3-5-sbc-i1200.dts | 1091 +++++++++++++++++
 2 files changed, 1092 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 37b4ca3a87c9..697b6b5de3cb 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -76,5 +76,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-kontron-3-5-sbc-i1200.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts b/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
new file mode 100644
index 000000000000..0c634bc8776c
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
@@ -0,0 +1,1091 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2024 Kontron Europe GmbH
+ *
+ * Author: Michael Walle <mwalle at kernel.org>
+ */
+/dts-v1/;
+
+#include "mt8195.dtsi"
+#include "mt6359.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
+#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+	model = "Kontron 3.5\"-SBC-i1200";
+	compatible = "kontron,3-5-sbc-i1200", "mediatek,mt8395", "mediatek,mt8195";
+
+	aliases {
+		mmc0 = &mmc0;
+		mmc1 = &mmc1;
+		serial0 = &uart1;
+		serial1 = &uart2;
+		serial2 = &uart3;
+		serial3 = &uart4;
+		serial4 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	firmware {
+		optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_keys_pins>;
+
+		key-0 {
+			gpios = <&pio 106 GPIO_ACTIVE_LOW>;
+			label = "volume_up";
+			linux,code = <KEY_VOLUMEUP>;
+			wakeup-source;
+			debounce-interval = <15>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins>;
+
+		led-0 {
+			gpios = <&pio 107 GPIO_ACTIVE_HIGH>;
+			default-state = "keep";
+			function = LED_FUNCTION_POWER;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+	};
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0x0 0x80000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/*
+		 * 12 MiB reserved for OP-TEE (BL32)
+		 * +-----------------------+ 0x43e0_0000
+		 * |      SHMEM 2MiB       |
+		 * +-----------------------+ 0x43c0_0000
+		 * |        | TA_RAM  8MiB |
+		 * + TZDRAM +--------------+ 0x4340_0000
+		 * |        | TEE_RAM 2MiB |
+		 * +-----------------------+ 0x4320_0000
+		 */
+		optee_reserved: optee at 43200000 {
+			no-map;
+			reg = <0 0x43200000 0 0x00c00000>;
+		};
+
+		scp_mem: memory at 50000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x50000000 0 0x2900000>;
+			no-map;
+		};
+
+		vpu_mem: memory at 53000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x53000000 0 0x1400000>; /* 20 MB */
+		};
+
+		/* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+		bl31_secmon_mem: memory at 54600000 {
+			no-map;
+			reg = <0 0x54600000 0x0 0x200000>;
+		};
+
+		snd_dma_mem: memory at 60000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x60000000 0 0x1100000>;
+			no-map;
+		};
+
+		apu_mem: memory at 62000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x62000000 0 0x1400000>; /* 20 MB */
+		};
+	};
+
+	thermal_sensor0: thermal-sensor-0 {
+		compatible = "generic-adc-thermal";
+		#thermal-sensor-cells = <0>;
+		io-channels = <&auxadc 0>;
+		io-channel-names = "sensor-channel";
+		temperature-lookup-table = <(-25000) 1474
+					    (-20000) 1374
+					    (-15000) 1260
+					    (-10000) 1134
+					     (-5000) 1004
+						   0 874
+						5000 750
+					       10000 635
+					       15000 532
+					       20000 443
+					       25000 367
+					       30000 303
+					       35000 250
+					       40000 206
+					       45000 170
+					       50000 141
+					       55000 117
+					       60000 97
+					       65000 81
+					       70000 68
+					       75000 57
+					       80000 48
+					       85000 41
+					       90000 35
+					       95000 30
+					      100000 25
+					      105000 22
+					      110000 19
+					      115000 16
+					      120000 14
+					      125000 12
+					      130000 10
+					      135000 9
+					      140000 8
+					      145000 7
+					      150000 6>;
+	};
+
+	thermal_sensor1: thermal-sensor-1 {
+		compatible = "generic-adc-thermal";
+		#thermal-sensor-cells = <0>;
+		io-channels = <&auxadc 1>;
+		io-channel-names = "sensor-channel";
+		temperature-lookup-table = <(-25000) 1474
+					    (-20000) 1374
+					    (-15000) 1260
+					    (-10000) 1134
+					     (-5000) 1004
+						   0 874
+						5000 750
+					       10000 635
+					       15000 532
+					       20000 443
+					       25000 367
+					       30000 303
+					       35000 250
+					       40000 206
+					       45000 170
+					       50000 141
+					       55000 117
+					       60000 97
+					       65000 81
+					       70000 68
+					       75000 57
+					       80000 48
+					       85000 41
+					       90000 35
+					       95000 30
+					      100000 25
+					      105000 22
+					      110000 19
+					      115000 16
+					      120000 14
+					      125000 12
+					      130000 10
+					      135000 9
+					      140000 8
+					      145000 7
+					      150000 6>;
+	};
+
+	thermal_sensor2: thermal-sensor-2 {
+		compatible = "generic-adc-thermal";
+		#thermal-sensor-cells = <0>;
+		io-channels = <&auxadc 2>;
+		io-channel-names = "sensor-channel";
+		temperature-lookup-table = <(-25000) 1474
+					    (-20000) 1374
+					    (-15000) 1260
+					    (-10000) 1134
+					     (-5000) 1004
+						   0 874
+						5000 750
+					       10000 635
+					       15000 532
+					       20000 443
+					       25000 367
+					       30000 303
+					       35000 250
+					       40000 206
+					       45000 170
+					       50000 141
+					       55000 117
+					       60000 97
+					       65000 81
+					       70000 68
+					       75000 57
+					       80000 48
+					       85000 41
+					       90000 35
+					       95000 30
+					      100000 25
+					      105000 22
+					      110000 19
+					      115000 16
+					      120000 14
+					      125000 12
+					      130000 10
+					      135000 9
+					      140000 8
+					      145000 7
+					      150000 6>;
+	};
+};
+
+&auxadc {
+	status = "okay";
+};
+
+&eth {
+	phy-mode ="rgmii-id";
+	phy-handle = <&ethernet_phy0>;
+	snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>;
+	snps,reset-delays-us = <0 10000 80000>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&eth_default_pins>;
+	pinctrl-1 = <&eth_sleep_pins>;
+	status = "okay";
+
+	mdio {
+		ethernet_phy0: ethernet-phy at 1 {
+			reg = <0x1>;
+			interrupts-extended = <&pio 94 IRQ_TYPE_LEVEL_LOW>;
+		};
+	};
+};
+
+&gpu {
+	status = "okay";
+	mali-supply = <&mt6315_7_vbuck1>;
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_pins>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&i2c4 {
+	clock-frequency = <100000>;
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&i2c6 {
+	clock-frequency = <400000>;
+	pinctrl-0 = <&i2c6_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	mt6360: pmic at 34 {
+		compatible = "mediatek,mt6360";
+		reg = <0x34>;
+		interrupt-controller;
+		interrupts-extended = <&pio 101 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-names = "IRQB";
+
+		charger {
+			compatible = "mediatek,mt6360-chg";
+			richtek,vinovp-microvolt = <14500000>;
+
+			otg_vbus_regulator: usb-otg-vbus-regulator {
+				regulator-compatible = "usb-otg-vbus";
+				regulator-name = "usb-otg-vbus";
+				regulator-min-microvolt = <4425000>;
+				regulator-max-microvolt = <5825000>;
+			};
+		};
+
+		regulator {
+			compatible = "mediatek,mt6360-regulator";
+			LDO_VIN3-supply = <&mt6360_buck2>;
+
+			mt6360_buck1: buck1 {
+				regulator-compatible = "BUCK1";
+				regulator-name = "mt6360,buck1";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP
+							   MT6360_OPMODE_ULP>;
+				regulator-always-on;
+			};
+
+			mt6360_buck2: buck2 {
+				regulator-compatible = "BUCK2";
+				regulator-name = "mt6360,buck2";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP
+							   MT6360_OPMODE_ULP>;
+				regulator-always-on;
+			};
+
+			mt6360_ldo1: ldo1 {
+				regulator-compatible = "LDO1";
+				regulator-name = "mt6360,ldo1";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo2: ldo2 {
+				regulator-compatible = "LDO2";
+				regulator-name = "mt6360,ldo2";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo3: ldo3 {
+				regulator-compatible = "LDO3";
+				regulator-name = "mt6360,ldo3";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo5: ldo5 {
+				regulator-compatible = "LDO5";
+				regulator-name = "mt6360,ldo5";
+				regulator-min-microvolt = <2700000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo6: ldo6 {
+				regulator-compatible = "LDO6";
+				regulator-name = "mt6360,ldo6";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo7: ldo7 {
+				regulator-compatible = "LDO7";
+				regulator-name = "mt6360,ldo7";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_default_pins>;
+	pinctrl-1 = <&mmc0_uhs_pins>;
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	cap-mmc-hw-reset;
+	no-sdio;
+	no-sd;
+	hs400-ds-delay = <0x14c11>;
+	vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
+	vqmmc-supply = <&mt6359_vufs_ldo_reg>;
+	non-removable;
+	status = "okay";
+};
+
+&mmc1 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc1_default_pins>;
+	pinctrl-1 = <&mmc1_uhs_pins>;
+	cd-gpios = <&pio 129 GPIO_ACTIVE_LOW>;
+	bus-width = <4>;
+	max-frequency = <200000000>;
+	cap-sd-highspeed;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&mt6360_ldo5>;
+	vqmmc-supply = <&mt6360_ldo3>;
+	status = "okay";
+};
+
+&mt6359_vbbck_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vcore_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vgpu11_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vproc1_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vproc2_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vpu_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vrf12_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vsram_md_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vsram_others_ldo_reg {
+	regulator-always-on;
+};
+
+&nor_flash {
+	pinctrl-names = "default";
+	pinctrl-0 = <&nor_pins_default>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+		spi-rx-bus-width = <2>;
+		spi-tx-bus-width = <2>;
+	};
+};
+
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_pins_default>;
+	status = "okay";
+};
+
+&pcie1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_pins_default>;
+	status = "okay";
+};
+
+&pciephy {
+	status = "okay";
+};
+
+&pio {
+	eth_default_pins: eth-default-pins {
+		pins-txd {
+			pinmux = <PINMUX_GPIO77__FUNC_GBE_TXD3>,
+				 <PINMUX_GPIO78__FUNC_GBE_TXD2>,
+				 <PINMUX_GPIO79__FUNC_GBE_TXD1>,
+				 <PINMUX_GPIO80__FUNC_GBE_TXD0>;
+			drive-strength = <MTK_DRIVE_8mA>;
+		};
+
+		pins-rxd {
+			pinmux = <PINMUX_GPIO81__FUNC_GBE_RXD3>,
+				 <PINMUX_GPIO82__FUNC_GBE_RXD2>,
+				 <PINMUX_GPIO83__FUNC_GBE_RXD1>,
+				 <PINMUX_GPIO84__FUNC_GBE_RXD0>;
+		};
+
+		pins-cc {
+			pinmux = <PINMUX_GPIO85__FUNC_GBE_TXC>,
+				 <PINMUX_GPIO86__FUNC_GBE_RXC>,
+				 <PINMUX_GPIO87__FUNC_GBE_RXDV>,
+				 <PINMUX_GPIO88__FUNC_GBE_TXEN>;
+			drive-strength = <MTK_DRIVE_8mA>;
+		};
+
+		pins-mdio {
+			pinmux = <PINMUX_GPIO89__FUNC_GBE_MDC>,
+				 <PINMUX_GPIO90__FUNC_GBE_MDIO>;
+			input-enable;
+		};
+
+		pins-power {
+			pinmux = <PINMUX_GPIO91__FUNC_GPIO91>,
+				 <PINMUX_GPIO92__FUNC_GPIO92>;
+			output-high;
+		};
+
+		pins-reset {
+			pinmux = <PINMUX_GPIO93__FUNC_GPIO93>;
+			output-high;
+		};
+
+		pins-interrupt {
+			pinmux = <PINMUX_GPIO94__FUNC_GPIO94>;
+			input-enable;
+		};
+	};
+
+	eth_sleep_pins: eth-sleep-pins {
+		pins-txd {
+			pinmux = <PINMUX_GPIO77__FUNC_GPIO77>,
+				 <PINMUX_GPIO78__FUNC_GPIO78>,
+				 <PINMUX_GPIO79__FUNC_GPIO79>,
+				 <PINMUX_GPIO80__FUNC_GPIO80>;
+		};
+		pins-cc {
+			pinmux = <PINMUX_GPIO85__FUNC_GPIO85>,
+				 <PINMUX_GPIO88__FUNC_GPIO88>,
+				 <PINMUX_GPIO87__FUNC_GPIO87>,
+				 <PINMUX_GPIO86__FUNC_GPIO86>;
+		};
+		pins-rxd {
+			pinmux = <PINMUX_GPIO81__FUNC_GPIO81>,
+				 <PINMUX_GPIO82__FUNC_GPIO82>,
+				 <PINMUX_GPIO83__FUNC_GPIO83>,
+				 <PINMUX_GPIO84__FUNC_GPIO84>;
+		};
+		pins-mdio {
+			pinmux = <PINMUX_GPIO89__FUNC_GPIO89>,
+				 <PINMUX_GPIO90__FUNC_GPIO90>;
+			input-disable;
+			bias-disable;
+		};
+	};
+
+	gpio_keys_pins: gpio-keys-pins {
+		pins {
+			pinmux = <PINMUX_GPIO106__FUNC_GPIO106>;
+			input-enable;
+		};
+	};
+
+	i2c2_pins: i2c2-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
+				 <PINMUX_GPIO13__FUNC_SCL2>;
+			bias-pull-up;
+		};
+	};
+
+	i2c3_pins: i2c3-pins {
+		pins {
+			pinmux = <PINMUX_GPIO14__FUNC_SDA3>,
+				 <PINMUX_GPIO15__FUNC_SCL3>;
+			bias-pull-up;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		pins {
+			pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
+				 <PINMUX_GPIO17__FUNC_SCL4>;
+			bias-pull-up;
+		};
+	};
+
+	i2c6_pins: i2c6-pins {
+		pins {
+			pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
+				 <PINMUX_GPIO26__FUNC_SCL6>;
+			bias-pull-up;
+		};
+	};
+
+	mmc0_default_pins: mmc0-default-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+				 <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+				 <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+				 <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+				 <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+				 <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+				 <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+				 <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+				 <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins-rst {
+			pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+			drive-strength = <MTK_DRIVE_6mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	mmc0_uhs_pins: mmc0-uhs-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+				 <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+				 <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+				 <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+				 <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+				 <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+				 <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+				 <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+				 <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins-ds {
+			pinmux = <PINMUX_GPIO127__FUNC_MSDC0_DSL>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-rst {
+			pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	mmc1_default_pins: mmc1-default-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
+				 <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
+				 <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
+				 <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
+				 <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins-insert {
+			pinmux = <PINMUX_GPIO129__FUNC_GPIO129>;
+			bias-pull-up;
+		};
+	};
+
+	mmc1_uhs_pins: mmc1-uhs-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
+				 <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
+				 <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
+				 <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
+				 <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
+			input-enable;
+			drive-strength = <MTK_DRIVE_8mA>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	nor_pins_default: nor-default-pins {
+		pins-ck-io {
+			pinmux = <PINMUX_GPIO142__FUNC_SPINOR_IO0>,
+				 <PINMUX_GPIO141__FUNC_SPINOR_CK>,
+				 <PINMUX_GPIO143__FUNC_SPINOR_IO1>;
+			drive-strength = <6>;
+			bias-pull-down;
+		};
+
+		pins-cs {
+			pinmux = <PINMUX_GPIO140__FUNC_SPINOR_CS>;
+			drive-strength = <6>;
+			bias-pull-up;
+		};
+	};
+
+	pcie0_pins_default: pcie0-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO19__FUNC_WAKEN>,
+				 <PINMUX_GPIO20__FUNC_PERSTN>,
+				 <PINMUX_GPIO21__FUNC_CLKREQN>;
+			bias-pull-up;
+		};
+	};
+
+	pcie1_pins_default: pcie1-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO0__FUNC_PERSTN_1>,
+				 <PINMUX_GPIO1__FUNC_CLKREQN_1>,
+				 <PINMUX_GPIO2__FUNC_WAKEN_1>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	led_pins: led-pins {
+		pins-power-en {
+			pinmux = <PINMUX_GPIO107__FUNC_GPIO107>;
+			output-high;
+		};
+	};
+
+	spi0_pins: spi0-default-pins {
+		pins-cs-mosi-clk {
+			pinmux = <PINMUX_GPIO132__FUNC_SPIM0_CSB>,
+				 <PINMUX_GPIO134__FUNC_SPIM0_MO>,
+				 <PINMUX_GPIO133__FUNC_SPIM0_CLK>;
+			bias-disable;
+		};
+
+		pins-miso {
+			pinmux = <PINMUX_GPIO135__FUNC_SPIM0_MI>;
+			bias-pull-down;
+		};
+	};
+
+	spi1_pins: spi1-default-pins {
+		pins-cs-mosi-clk {
+			pinmux = <PINMUX_GPIO136__FUNC_SPIM1_CSB>,
+				 <PINMUX_GPIO138__FUNC_SPIM1_MO>,
+				 <PINMUX_GPIO137__FUNC_SPIM1_CLK>;
+			bias-disable;
+		};
+
+		pins-miso {
+			pinmux = <PINMUX_GPIO139__FUNC_SPIM1_MI>;
+			bias-pull-down;
+		};
+	};
+
+	uart0_pins: uart0-pins {
+		pins_rx {
+			pinmux = <PINMUX_GPIO99__FUNC_URXD0>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins_tx {
+			pinmux = <PINMUX_GPIO98__FUNC_UTXD0>;
+		};
+	};
+
+	uart1_pins: uart1-pins {
+		pins_rx {
+			pinmux = <PINMUX_GPIO103__FUNC_URXD1>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins_tx {
+			pinmux = <PINMUX_GPIO102__FUNC_UTXD1>;
+		};
+
+		pins_rts {
+			pinmux = <PINMUX_GPIO100__FUNC_URTS1>;
+			output-enable;
+		};
+
+		pins_cts {
+			pinmux = <PINMUX_GPIO101__FUNC_UCTS1>;
+			input-enable;
+		};
+	};
+
+	uart2_pins: uart2-pins {
+		pins_rx {
+			pinmux = <PINMUX_GPIO68__FUNC_URXD2>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins_tx {
+			pinmux = <PINMUX_GPIO67__FUNC_UTXD2>;
+		};
+
+		pins_rts {
+			pinmux = <PINMUX_GPIO66__FUNC_URTS2>;
+			output-enable;
+		};
+
+		pins_cts {
+			pinmux = <PINMUX_GPIO65__FUNC_UCTS2>;
+			input-enable;
+		};
+	};
+
+	uart3_pins: uart3-pins {
+		pins_rx {
+			pinmux = <PINMUX_GPIO5__FUNC_URXD3>;
+			input-enable;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins_tx {
+			pinmux = <PINMUX_GPIO4__FUNC_UTXD3>;
+		};
+	};
+
+	uart4_pins: uart4-pins {
+		pins_rx {
+			pinmux = <PINMUX_GPIO7__FUNC_URXD4>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins_tx {
+			pinmux = <PINMUX_GPIO6__FUNC_UTXD4>;
+		};
+	};
+};
+
+&pmic {
+	interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&scp {
+	memory-region = <&scp_mem>;
+	status = "okay";
+};
+
+&spmi {
+	#address-cells = <2>;
+	#size-cells = <0>;
+
+	mt6315 at 6 {
+		compatible = "mediatek,mt6315-regulator";
+		reg = <0x6 SPMI_USID>;
+
+		regulators {
+			mt6315_6_vbuck1: vbuck1 {
+				regulator-compatible = "vbuck1";
+				regulator-name = "Vbcpu";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1193750>;
+				regulator-enable-ramp-delay = <256>;
+				regulator-ramp-delay = <6250>;
+				regulator-allowed-modes = <0 1 2>;
+				regulator-always-on;
+			};
+		};
+	};
+
+	mt6315 at 7 {
+		compatible = "mediatek,mt6315-regulator";
+		reg = <0x7 SPMI_USID>;
+
+		regulators {
+			mt6315_7_vbuck1: vbuck1 {
+				regulator-compatible = "vbuck1";
+				regulator-name = "Vgpu";
+				regulator-min-microvolt = <625000>;
+				regulator-max-microvolt = <1193750>;
+				regulator-enable-ramp-delay = <256>;
+				regulator-ramp-delay = <6250>;
+				regulator-allowed-modes = <0 1 2>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_pins>;
+	mediatek,pad-select = <0>;
+	status = "okay";
+
+	tpm: tpm at 0 {
+		compatible = "infineon,slb9670";
+		reg = <0>;
+		spi-max-frequency = <18500000>;
+	};
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_pins>;
+	mediatek,pad-select = <0>;
+	status = "okay";
+};
+
+&thermal_zones {
+	board0-thermal {
+		polling-delay = <1000>; /* milliseconds */
+		polling-delay-passive = <0>; /* milliseconds */
+		thermal-sensors = <&thermal_sensor0>;
+
+		trips {
+			trip-alert {
+				temperature = <85000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			trip-crit {
+				temperature = <95000>;
+				hysteresis = <2000>;
+				type = "critical";
+			};
+		};
+	};
+
+	board1-thermal {
+		polling-delay = <1000>; /* milliseconds */
+		polling-delay-passive = <0>; /* milliseconds */
+		thermal-sensors = <&thermal_sensor1>;
+
+		trips {
+			trip-alert {
+				temperature = <75000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			trip-crit {
+				temperature = <85000>;
+				hysteresis = <2000>;
+				type = "critical";
+			};
+		};
+	};
+
+	board2-thermal {
+		polling-delay = <1000>; /* milliseconds */
+		polling-delay-passive = <0>; /* milliseconds */
+		thermal-sensors = <&thermal_sensor2>;
+
+		trips {
+			trip-alert {
+				temperature = <75000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			trip-crit {
+				temperature = <85000>;
+				hysteresis = <2000>;
+				type = "critical";
+			};
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+	status = "okay";
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins>;
+	status = "okay";
+};
+
+/* USB3 */
+&u3phy0 {
+	status = "okay";
+};
+
+/* PCIe1/USB2 */
+&u3phy1 {
+	status = "okay";
+};
+
+/* USB2 */
+&u3phy2 {
+	status = "okay";
+};
+
+/* USB2 */
+&u3phy3 {
+	status = "okay";
+};
+
+/* USB3 front port */
+&xhci0 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	vbus-supply = <&otg_vbus_regulator>;
+	status = "okay";
+};
+
+/* USB2 M.2 Key-B */
+&xhci1 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	mediatek,u3p-dis-msk = <0x01>;
+	status = "okay";
+};
+
+/* USB2 M.2 Key-E */
+&xhci2 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	status = "okay";
+};
+
+/* USB2 to on-board usb hub */
+&xhci3 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	status = "okay";
+};
-- 
2.39.2



From brgl at bgdev.pl  Mon Feb 19 00:46:10 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 09:46:10 +0100
Subject: [PATCH] arm64: defconfig: build ath12k as a module
Message-ID: <20240219084610.11007-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Qualcomm sm8550-qrd and sm8650-qrd boards have ath12k modules as part of
their on-board WCN7850 WLAN/BT packages. Enable the relevant driver in
defconfig.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 056a6cc546a4..3f3d3350cf90 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -408,6 +408,7 @@ CONFIG_WCN36XX=m
 CONFIG_ATH11K=m
 CONFIG_ATH11K_AHB=m
 CONFIG_ATH11K_PCI=m
+CONFIG_ATH12K=m
 CONFIG_BRCMFMAC=m
 CONFIG_MWIFIEX=m
 CONFIG_MWIFIEX_SDIO=m
-- 
2.40.1



From neil.armstrong at linaro.org  Mon Feb 19 00:47:13 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 19 Feb 2024 09:47:13 +0100
Subject: [PATCH] drm/meson: Don't remove bridges which are created by
 other drivers
In-Reply-To: <20240215220442.1343152-1-martin.blumenstingl@googlemail.com>
References: <20240215220442.1343152-1-martin.blumenstingl@googlemail.com>
Message-ID: <170833243318.1719293.16562400747417002919.b4-ty@linaro.org>

Hi,

On Thu, 15 Feb 2024 23:04:42 +0100, Martin Blumenstingl wrote:
> Stop calling drm_bridge_remove() for bridges allocated/managed by other
> drivers in the remove paths of meson_encoder_{cvbs,dsi,hdmi}.
> drm_bridge_remove() unregisters the bridge so it cannot be used
> anymore. Doing so for bridges we don't own can lead to the video
> pipeline not being able to come up after -EPROBE_DEFER of the VPU
> because we're unregistering a bridge that's managed by another driver.
> The other driver doesn't know that we have unregistered it's bridge
> and on subsequent .probe() we're not able to find those bridges anymore
> (since nobody re-creates them).
> 
> [...]

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git (drm-misc-fixes)

[1/1] drm/meson: Don't remove bridges which are created by other drivers
      https://cgit.freedesktop.org/drm/drm-misc/commit/?id=bd915ae73a2d78559b376ad2caf5e4ef51de2455

-- 
Neil



From norbert.karecki at quirkbyte.pl  Mon Feb 19 00:45:24 2024
From: norbert.karecki at quirkbyte.pl (Norbert Karecki)
Date: Mon, 19 Feb 2024 08:45:24 GMT
Subject: Fotowoltaika - propozycja instalacji
Message-ID: <20240219084500-0.1.1d.qts1.0.qenaf4wn1q@quirkbyte.pl>

Dzie? dobry,
 
Czy rozwa?ali Pa?stwo monta? systemu fotowoltaicznego?
 
Instalacja fotowoltaiczna jest najlepszym sposobem na obni?enie wysoko?ci rachunk?w za pr?d (pozostaj? tylko op?aty sta?e) i zabezpieczenie si? przed rosn?cymi cenami energii elektrycznej. Jest to w pe?ni odnawialne i bezemisyjne ?r?d?o energii, dzi?ki czemu przyczyniamy si? do ochrony ?rodowiska naturalnego.
 
Dzia?amy od wielu lat na rynku energetycznym. Przygotujemy projekt, wycen? oraz kompleksowo wykonamy i zg?osimy realizacj? do zak?adu energetycznego. 
 
Czy chc? Pa?stwo pozna? nasz? propozycj??  


Pozdrawiam
Norbert Karecki


From arnd at arndb.de  Mon Feb 19 00:48:10 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 19 Feb 2024 09:48:10 +0100
Subject: [PATCH] arm64: defconfig: build ath12k as a module
In-Reply-To: <20240219084610.11007-1-brgl@bgdev.pl>
References: <20240219084610.11007-1-brgl@bgdev.pl>
Message-ID: <c083c1af-31ef-43a8-ba2d-98d63dfe45e0@app.fastmail.com>

On Mon, Feb 19, 2024, at 09:46, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>
> Qualcomm sm8550-qrd and sm8650-qrd boards have ath12k modules as part of
> their on-board WCN7850 WLAN/BT packages. Enable the relevant driver in
> defconfig.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---

Acked-by: Arnd Bergmann <arnd at arndb.de>

I assume that Bjorn will pick this up through the qualcomm
tree.

     Arnd


From neil.armstrong at linaro.org  Mon Feb 19 00:51:13 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 19 Feb 2024 09:51:13 +0100
Subject: [PATCH v1] drm/meson: improve encoder probe / initialization
 error handling
In-Reply-To: <20240218175035.1948165-1-martin.blumenstingl@googlemail.com>
References: <20240218175035.1948165-1-martin.blumenstingl@googlemail.com>
Message-ID: <170833267304.1737509.12815192021500266320.b4-ty@linaro.org>

Hi,

On Sun, 18 Feb 2024 18:50:35 +0100, Martin Blumenstingl wrote:
> Rename meson_encoder_{cvbs,dsi,hdmi}_init() to
> meson_encoder_{cvbs,dsi,hdmi}_probe() so it's clear that these functions
> are used at probe time during driver initialization. Also switch all
> error prints inside those functions to use dev_err_probe() for
> consistency.
> 
> This makes the code more straight forward to read and makes the error
> prints within those functions consistent (by logging all -EPROBE_DEFER
> with dev_dbg(), while actual errors are logged with dev_err() and get
> the error value printed).
> 
> [...]

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git (drm-misc-next)

[1/1] drm/meson: improve encoder probe / initialization error handling
      https://cgit.freedesktop.org/drm/drm-misc/commit/?id=1a9e51bef89af0f0976cf4c83a1e682895695dcf

-- 
Neil



From neil.armstrong at linaro.org  Mon Feb 19 00:52:03 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 19 Feb 2024 09:52:03 +0100
Subject: [PATCH] arm64: dts: amlogic: replace underscores in node names
In-Reply-To: <20240213143217.336341-1-krzysztof.kozlowski@linaro.org>
References: <20240213143217.336341-1-krzysztof.kozlowski@linaro.org>
Message-ID: <ca1334d4-fc07-4951-a3f6-7c71d9ac4169@linaro.org>

On 13/02/2024 15:32, Krzysztof Kozlowski wrote:
> Underscores should not be used in node names (dtc with W=2 warns about
> them), so replace them with hyphens.
> 
> Cc: Marc Gonzalez <mgonzalez at freebox.fr>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>   .../arm64/boot/dts/amlogic/meson-a1-ad402.dts |  2 +-
>   .../meson-axg-jethome-jethub-j1xx.dtsi        | 14 ++++++-------
>   .../arm64/boot/dts/amlogic/meson-axg-s400.dts | 16 +++++++--------
>   .../dts/amlogic/meson-g12a-radxa-zero.dts     | 12 +++++------
>   .../boot/dts/amlogic/meson-g12a-sei510.dts    | 14 ++++++-------
>   .../boot/dts/amlogic/meson-g12a-u200.dts      | 16 +++++++--------
>   .../boot/dts/amlogic/meson-g12a-x96-max.dts   | 14 ++++++-------
>   .../dts/amlogic/meson-g12b-odroid-n2.dtsi     |  2 +-
>   .../boot/dts/amlogic/meson-g12b-odroid.dtsi   | 20 +++++++++----------
>   .../boot/dts/amlogic/meson-g12b-w400.dtsi     | 10 +++++-----
>   .../dts/amlogic/meson-gx-libretech-pc.dtsi    | 12 +++++------
>   .../boot/dts/amlogic/meson-gx-p23x-q20x.dtsi  |  8 ++++----
>   .../dts/amlogic/meson-gxbb-nexbox-a95x.dts    |  6 +++---
>   .../boot/dts/amlogic/meson-gxbb-odroidc2.dts  |  8 ++++----
>   .../boot/dts/amlogic/meson-gxbb-p200.dts      |  4 ++--
>   .../boot/dts/amlogic/meson-gxbb-p20x.dtsi     |  6 +++---
>   .../boot/dts/amlogic/meson-gxbb-vega-s95.dtsi |  8 ++++----
>   .../boot/dts/amlogic/meson-gxbb-wetek.dtsi    |  8 ++++----
>   .../amlogic/meson-gxl-s805x-libretech-ac.dts  |  8 ++++----
>   .../boot/dts/amlogic/meson-gxl-s805x-p241.dts |  8 ++++----
>   .../meson-gxl-s905w-jethome-jethub-j80.dts    |  8 ++++----
>   .../meson-gxl-s905x-hwacom-amazetv.dts        |  6 +++---
>   .../meson-gxl-s905x-libretech-cc-v2.dts       | 12 +++++------
>   .../amlogic/meson-gxl-s905x-libretech-cc.dts  |  6 +++---
>   .../amlogic/meson-gxl-s905x-nexbox-a95x.dts   |  6 +++---
>   .../dts/amlogic/meson-gxl-s905x-p212.dtsi     |  8 ++++----
>   .../dts/amlogic/meson-gxm-khadas-vim2.dts     |  8 ++++----
>   .../amlogic/meson-gxm-s912-libretech-pc.dts   |  2 +-
>   .../boot/dts/amlogic/meson-khadas-vim3.dtsi   | 16 +++++++--------
>   .../amlogic/meson-libretech-cottonwood.dtsi   |  6 +++---
>   .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 10 +++++-----
>   .../boot/dts/amlogic/meson-sm1-bananapi.dtsi  | 14 ++++++-------
>   .../boot/dts/amlogic/meson-sm1-odroid-hc4.dts |  4 ++--
>   .../boot/dts/amlogic/meson-sm1-odroid.dtsi    | 20 +++++++++----------
>   .../boot/dts/amlogic/meson-sm1-sei610.dts     | 12 +++++------
>   35 files changed, 167 insertions(+), 167 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts b/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
> index 1c20516fa653..4bc30af05848 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
> @@ -106,7 +106,7 @@ &spifc {
>   	pinctrl-0 = <&spifc_pins>;
>   	pinctrl-names = "default";
>   
> -	spi_nand at 0 {
> +	flash at 0 {
>   		compatible = "spi-nand";
>   		status = "okay";
>   		reg = <0>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
> index db605f3a22b4..a53e1fe9ac1e 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
> @@ -35,7 +35,7 @@ emmc_pwrseq: emmc-pwrseq {
>   		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -44,7 +44,7 @@ vcc_3v3: regulator-vcc_3v3 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_5v: regulator-vcc_5v {
> +	vcc_5v: regulator-vcc-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -52,7 +52,7 @@ vcc_5v: regulator-vcc_5v {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -61,7 +61,7 @@ vddao_3v3: regulator-vddao_3v3 {
>   		regulator-always-on;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
> @@ -70,7 +70,7 @@ vddio_ao18: regulator-vddio_ao18 {
>   		regulator-always-on;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <3300000>;
> @@ -79,7 +79,7 @@ vddio_boot: regulator-vddio_boot {
>   		regulator-always-on;
>   	};
>   
> -	vccq_1v8: regulator-vccq_1v8 {
> +	vccq_1v8: regulator-vccq-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCCQ_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -88,7 +88,7 @@ vccq_1v8: regulator-vccq_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	usb_pwr: regulator-usb_pwr {
> +	usb_pwr: regulator-usb-pwr {
>   		compatible = "regulator-fixed";
>   		regulator-name = "USB_PWR";
>   		regulator-min-microvolt = <5000000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
> index c8905663bc75..7ed526f45175 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
> @@ -12,7 +12,7 @@ / {
>   	compatible = "amlogic,s400", "amlogic,a113d", "amlogic,meson-axg";
>   	model = "Amlogic Meson AXG S400 Development Board";
>   
> -	adc_keys {
> +	keys {
>   		compatible = "adc-keys";
>   		io-channels = <&saradc 0>;
>   		io-channel-names = "buttons";
> @@ -111,7 +111,7 @@ memory at 0 {
>   		reg = <0x0 0x0 0x0 0x40000000>;
>   	};
>   
> -	main_12v: regulator-main_12v {
> +	main_12v: regulator-main-12v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "12V";
>   		regulator-min-microvolt = <12000000>;
> @@ -119,7 +119,7 @@ main_12v: regulator-main_12v {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -128,7 +128,7 @@ vcc_3v3: regulator-vcc_3v3 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_5v: regulator-vcc_5v {
> +	vcc_5v: regulator-vcc-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -139,7 +139,7 @@ vcc_5v: regulator-vcc_5v {
>   		enable-active-high;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -148,7 +148,7 @@ vddao_3v3: regulator-vddao_3v3 {
>   		regulator-always-on;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
> @@ -157,7 +157,7 @@ vddio_ao18: regulator-vddio_ao18 {
>   		regulator-always-on;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
> @@ -166,7 +166,7 @@ vddio_boot: regulator-vddio_boot {
>   		regulator-always-on;
>   	};
>   
> -	usb_pwr: regulator-usb_pwr {
> +	usb_pwr: regulator-usb-pwr {
>   		compatible = "regulator-fixed";
>   		regulator-name = "USB_PWR";
>   		regulator-min-microvolt = <5000000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
> index fcd7e1d8e16f..15b9bc280706 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
> @@ -60,7 +60,7 @@ sdio_pwrseq: sdio-pwrseq {
>   		clock-names = "ext_clock";
>   	};
>   
> -	ao_5v: regulator-ao_5v {
> +	ao_5v: regulator-ao-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "AO_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -68,7 +68,7 @@ ao_5v: regulator-ao_5v {
>   		regulator-always-on;
>   	};
>   
> -	vcc_1v8: regulator-vcc_1v8 {
> +	vcc_1v8: regulator-vcc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -77,7 +77,7 @@ vcc_1v8: regulator-vcc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -86,7 +86,7 @@ vcc_3v3: regulator-vcc_3v3 {
>   		regulator-always-on;
>   	};
>   
> -	hdmi_pw: regulator-hdmi_pw {
> +	hdmi_pw: regulator-hdmi-pw {
>   		compatible = "regulator-fixed";
>   		regulator-name = "HDMI_PW";
>   		regulator-min-microvolt = <5000000>;
> @@ -95,7 +95,7 @@ hdmi_pw: regulator-hdmi_pw {
>   		regulator-always-on;
>   	};
>   
> -	vddao_1v8: regulator-vddao_1v8 {
> +	vddao_1v8: regulator-vddao-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -104,7 +104,7 @@ vddao_1v8: regulator-vddao_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
> index 4c4550dd4711..61cb8135a392 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
> @@ -15,7 +15,7 @@ / {
>   	compatible = "seirobotics,sei510", "amlogic,g12a";
>   	model = "SEI Robotics SEI510";
>   
> -	adc_keys {
> +	keys {
>   		compatible = "adc-keys";
>   		io-channels = <&saradc 0>;
>   		io-channel-names = "buttons";
> @@ -83,7 +83,7 @@ memory at 0 {
>   		reg = <0x0 0x0 0x0 0x40000000>;
>   	};
>   
> -	ao_5v: regulator-ao_5v {
> +	ao_5v: regulator-ao-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "AO_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -92,7 +92,7 @@ ao_5v: regulator-ao_5v {
>   		regulator-always-on;
>   	};
>   
> -	dc_in: regulator-dc_in {
> +	dc_in: regulator-dc-in {
>   		compatible = "regulator-fixed";
>   		regulator-name = "DC_IN";
>   		regulator-min-microvolt = <5000000>;
> @@ -100,7 +100,7 @@ dc_in: regulator-dc_in {
>   		regulator-always-on;
>   	};
>   
> -	emmc_1v8: regulator-emmc_1v8 {
> +	emmc_1v8: regulator-emmc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "EMMC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -109,7 +109,7 @@ emmc_1v8: regulator-emmc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -118,7 +118,7 @@ vddao_3v3: regulator-vddao_3v3 {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3_t: regultor-vddao_3v3_t {
> +	vddao_3v3_t: regulator-vddao-3v3-t {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3_T";
>   		regulator-min-microvolt = <3300000>;
> @@ -147,7 +147,7 @@ vddcpu: regulator-vddcpu {
>   		regulator-always-on;
>   	};
>   
> -	vddio_ao1v8: regulator-vddio_ao1v8 {
> +	vddio_ao1v8: regulator-vddio-ao1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO1V8";
>   		regulator-min-microvolt = <1800000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
> index 8355ddd7e9ae..3da7922d83f1 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
> @@ -75,7 +75,7 @@ memory at 0 {
>   		reg = <0x0 0x0 0x0 0x40000000>;
>   	};
>   
> -	flash_1v8: regulator-flash_1v8 {
> +	flash_1v8: regulator-flash-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "FLASH_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -84,7 +84,7 @@ flash_1v8: regulator-flash_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	main_12v: regulator-main_12v {
> +	main_12v: regulator-main-12v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "12V";
>   		regulator-min-microvolt = <12000000>;
> @@ -92,7 +92,7 @@ main_12v: regulator-main_12v {
>   		regulator-always-on;
>   	};
>   
> -	usb_pwr_en: regulator-usb_pwr_en {
> +	usb_pwr_en: regulator-usb-pwr-en {
>   		compatible = "regulator-fixed";
>   		regulator-name = "USB_PWR_EN";
>   		regulator-min-microvolt = <5000000>;
> @@ -103,7 +103,7 @@ usb_pwr_en: regulator-usb_pwr_en {
>   		enable-active-high;
>   	};
>   
> -	vcc_1v8: regulator-vcc_1v8 {
> +	vcc_1v8: regulator-vcc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -112,7 +112,7 @@ vcc_1v8: regulator-vcc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -122,7 +122,7 @@ vcc_3v3: regulator-vcc_3v3 {
>   		/* FIXME: actually controlled by VDDCPU_B_EN */
>   	};
>   
> -	vcc_5v: regulator-vcc_5v {
> +	vcc_5v: regulator-vcc-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -133,7 +133,7 @@ vcc_5v: regulator-vcc_5v {
>   		enable-active-high;
>   	};
>   
> -	vddao_1v8: regulator-vddao_1v8 {
> +	vddao_1v8: regulator-vddao-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -142,7 +142,7 @@ vddao_1v8: regulator-vddao_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
> index 9b55982b6a6b..05c7a1e3f1b7 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
> @@ -66,7 +66,7 @@ sdio_pwrseq: sdio-pwrseq {
>   		clock-names = "ext_clock";
>   	};
>   
> -	flash_1v8: regulator-flash_1v8 {
> +	flash_1v8: regulator-flash-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "FLASH_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -75,7 +75,7 @@ flash_1v8: regulator-flash_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	dc_in: regulator-dc_in {
> +	dc_in: regulator-dc-in {
>   		compatible = "regulator-fixed";
>   		regulator-name = "DC_IN";
>   		regulator-min-microvolt = <5000000>;
> @@ -83,7 +83,7 @@ dc_in: regulator-dc_in {
>   		regulator-always-on;
>   	};
>   
> -	vcc_1v8: regulator-vcc_1v8 {
> +	vcc_1v8: regulator-vcc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -92,7 +92,7 @@ vcc_1v8: regulator-vcc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -102,7 +102,7 @@ vcc_3v3: regulator-vcc_3v3 {
>   		/* FIXME: actually controlled by VDDCPU_B_EN */
>   	};
>   
> -	vcc_5v: regulator-vcc_5v {
> +	vcc_5v: regulator-vcc-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -112,7 +112,7 @@ vcc_5v: regulator-vcc_5v {
>   		gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
>   	};
>   
> -	vddao_1v8: regulator-vddao_1v8 {
> +	vddao_1v8: regulator-vddao-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -121,7 +121,7 @@ vddao_1v8: regulator-vddao_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> 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 91c9769fda20..d80dd9a3da31 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
> @@ -19,7 +19,7 @@ dio2133: audio-amplifier-0 {
>   		status = "okay";
>   	};
>   
> -	hub_5v: regulator-hub_5v {
> +	hub_5v: regulator-hub-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "HUB_5V";
>   		regulator-min-microvolt = <5000000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi
> index 9e12a34b2840..09d959aefb18 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi
> @@ -48,7 +48,7 @@ led-blue {
>   		};
>   	};
>   
> -	tflash_vdd: regulator-tflash_vdd {
> +	tflash_vdd: regulator-tflash-vdd {
>   		compatible = "regulator-fixed";
>   
>   		regulator-name = "TFLASH_VDD";
> @@ -60,7 +60,7 @@ tflash_vdd: regulator-tflash_vdd {
>   		regulator-always-on;
>   	};
>   
> -	tf_io: gpio-regulator-tf_io {
> +	tf_io: gpio-regulator-tf-io {
>   		compatible = "regulator-gpio";
>   
>   		regulator-name = "TF_IO";
> @@ -74,7 +74,7 @@ tf_io: gpio-regulator-tf_io {
>   			 <1800000 1>;
>   	};
>   
> -	flash_1v8: regulator-flash_1v8 {
> +	flash_1v8: regulator-flash-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "FLASH_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -83,7 +83,7 @@ flash_1v8: regulator-flash_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	main_12v: regulator-main_12v {
> +	main_12v: regulator-main-12v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "12V";
>   		regulator-min-microvolt = <12000000>;
> @@ -91,7 +91,7 @@ main_12v: regulator-main_12v {
>   		regulator-always-on;
>   	};
>   
> -	usb_pwr_en: regulator-usb_pwr_en {
> +	usb_pwr_en: regulator-usb-pwr-en {
>   		compatible = "regulator-fixed";
>   		regulator-name = "USB_PWR_EN";
>   		regulator-min-microvolt = <5000000>;
> @@ -103,7 +103,7 @@ usb_pwr_en: regulator-usb_pwr_en {
>   		enable-active-high;
>   	};
>   
> -	vcc_5v: regulator-vcc_5v {
> +	vcc_5v: regulator-vcc-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -114,7 +114,7 @@ vcc_5v: regulator-vcc_5v {
>   		enable-active-high;
>   	};
>   
> -	vcc_1v8: regulator-vcc_1v8 {
> +	vcc_1v8: regulator-vcc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -123,7 +123,7 @@ vcc_1v8: regulator-vcc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -171,7 +171,7 @@ vddcpu_b: regulator-vddcpu-b {
>   		regulator-always-on;
>   	};
>   
> -	vddao_1v8: regulator-vddao_1v8 {
> +	vddao_1v8: regulator-vddao-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -180,7 +180,7 @@ vddao_1v8: regulator-vddao_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi
> index ac8b7178257e..4cb6930ffb19 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi
> @@ -39,7 +39,7 @@ sdio_pwrseq: sdio-pwrseq {
>   		clock-names = "ext_clock";
>   	};
>   
> -	flash_1v8: regulator-flash_1v8 {
> +	flash_1v8: regulator-flash-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "FLASH_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -48,7 +48,7 @@ flash_1v8: regulator-flash_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	main_12v: regulator-main_12v {
> +	main_12v: regulator-main-12v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "12V";
>   		regulator-min-microvolt = <12000000>;
> @@ -56,7 +56,7 @@ main_12v: regulator-main_12v {
>   		regulator-always-on;
>   	};
>   
> -	vcc_5v: regulator-vcc_5v {
> +	vcc_5v: regulator-vcc-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -67,7 +67,7 @@ vcc_5v: regulator-vcc_5v {
>   		enable-active-high;
>   	};
>   
> -	vcc_1v8: regulator-vcc_1v8 {
> +	vcc_1v8: regulator-vcc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -76,7 +76,7 @@ vcc_1v8: regulator-vcc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
> index 5e7b9273b062..efd662a452e8 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
> @@ -84,7 +84,7 @@ memory at 0 {
>   		reg = <0x0 0x0 0x0 0x80000000>;
>   	};
>   
> -	ao_5v: regulator-ao_5v {
> +	ao_5v: regulator-ao-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "AO_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -93,7 +93,7 @@ ao_5v: regulator-ao_5v {
>   		regulator-always-on;
>   	};
>   
> -	dc_in: regulator-dc_in {
> +	dc_in: regulator-dc-in {
>   		compatible = "regulator-fixed";
>   		regulator-name = "DC_IN";
>   		regulator-min-microvolt = <5000000>;
> @@ -120,7 +120,7 @@ led-blue {
>   		};
>   	};
>   
> -	vcc_card: regulator-vcc_card {
> +	vcc_card: regulator-vcc-card {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_CARD";
>   		regulator-min-microvolt = <3300000>;
> @@ -141,7 +141,7 @@ vcc5v: regulator-vcc5v {
>   		gpio = <&gpio GPIOH_3 GPIO_OPEN_DRAIN>;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
> @@ -150,7 +150,7 @@ vddio_ao18: regulator-vddio_ao18 {
>   		regulator-always-on;
>   	};
>   
> -	vddio_ao3v3: regulator-vddio_ao3v3 {
> +	vddio_ao3v3: regulator-vddio-ao3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -159,7 +159,7 @@ vddio_ao3v3: regulator-vddio_ao3v3 {
>   		regulator-always-on;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
> index e59c3c92b1e7..08d6b69ba469 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
> @@ -50,28 +50,28 @@ hdmi_5v: regulator-hdmi-5v {
>   		regulator-always-on;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
> index 4aab1ab705b4..cca129ce2c58 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
> @@ -78,21 +78,21 @@ vddio_card: gpio-regulator {
>   			 <3300000 1>;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
> index e6d2de7c45a9..c431986e6a33 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
> @@ -67,7 +67,7 @@ p5v0: regulator-p5v0 {
>   		regulator-always-on;
>   	};
>   
> -	hdmi_p5v0: regulator-hdmi_p5v0 {
> +	hdmi_p5v0: regulator-hdmi-p5v0 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "HDMI_P5V0";
>   		regulator-min-microvolt = <5000000>;
> @@ -76,7 +76,7 @@ hdmi_p5v0: regulator-hdmi_p5v0 {
>   		vin-supply = <&p5v0>;
>   	};
>   
> -	tflash_vdd: regulator-tflash_vdd {
> +	tflash_vdd: regulator-tflash-vdd {
>   		compatible = "regulator-fixed";
>   
>   		regulator-name = "TFLASH_VDD";
> @@ -92,7 +92,7 @@ tflash_vdd: regulator-tflash_vdd {
>   		vin-supply = <&vddio_ao3v3>;
>   	};
>   
> -	tf_io: gpio-regulator-tf_io {
> +	tf_io: gpio-regulator-tf-io {
>   		compatible = "regulator-gpio";
>   
>   		regulator-name = "TF_IO";
> @@ -148,7 +148,7 @@ vddio_ao3v3: regulator-vddio-ao3v3 {
>   		vin-supply = <&p5v0>;
>   	};
>   
> -	ddr3_1v5: regulator-ddr3_1v5 {
> +	ddr3_1v5: regulator-ddr3-1v5 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "DDR3_1V5";
>   		regulator-min-microvolt = <1500000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
> index 591455c50e88..7f94716876d3 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
> @@ -21,14 +21,14 @@ spdif_dit: audio-codec-0 {
>   		sound-name-prefix = "DIT";
>   	};
>   
> -	avdd18_usb_adc: regulator-avdd18_usb_adc {
> +	avdd18_usb_adc: regulator-avdd18-usb-adc {
>   		compatible = "regulator-fixed";
>   		regulator-name = "AVDD18_USB_ADC";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	adc_keys {
> +	keys {
>   		compatible = "adc-keys";
>   		io-channels = <&saradc 0>;
>   		io-channel-names = "buttons";
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
> index e803a466fe4e..52d57773a77f 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
> @@ -53,21 +53,21 @@ vddio_card: gpio-regulator {
>   		regulator-settling-time-down-us = <150000>;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
> index 74df32534231..255e93a0b36d 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
> @@ -47,28 +47,28 @@ usb_pwr: regulator-usb-pwrs {
>   		enable-active-high;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
> index 94dafb955301..deb295227189 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
> @@ -49,21 +49,21 @@ usb_pwr: regulator-usb-pwrs {
>   		enable-active-high;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
> @@ -71,7 +71,7 @@ vddio_ao18: regulator-vddio_ao18 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
> index a29b49f051ae..90ef9c17d80b 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
> @@ -42,7 +42,7 @@ cvbs_connector_in: endpoint {
>   		};
>   	};
>   
> -	dc_5v: regulator-dc_5v {
> +	dc_5v: regulator-dc-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "DC_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -89,7 +89,7 @@ vcck: regulator-vcck {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -98,7 +98,7 @@ vcc_3v3: regulator-vcc_3v3 {
>   		regulator-always-on;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
> @@ -107,7 +107,7 @@ vddio_ao18: regulator-vddio_ao18 {
>   		regulator-always-on;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
> index c0d6eb55100a..08a4718219b1 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
> @@ -64,28 +64,28 @@ memory at 0 {
>   		reg = <0x0 0x0 0x0 0x20000000>;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts
> index a18d6d241a5a..2b94b6e5285e 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts
> @@ -37,28 +37,28 @@ chosen {
>   		stdout-path = "serial0:115200n8";
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
> index c8d74e61dec1..89fe5110f7a2 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
> @@ -42,21 +42,21 @@ vddio_card: gpio-regulator {
>   			 <3300000 1>;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts
> index 2825db91e462..63b20860067c 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts
> @@ -67,7 +67,7 @@ memory at 0 {
>   		reg = <0x0 0x0 0x0 0x80000000>;
>   	};
>   
> -	ao_5v: regulator-ao_5v {
> +	ao_5v: regulator-ao-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "AO_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -76,7 +76,7 @@ ao_5v: regulator-ao_5v {
>   		regulator-always-on;
>   	};
>   
> -	dc_in: regulator-dc_in {
> +	dc_in: regulator-dc-in {
>   		compatible = "regulator-fixed";
>   		regulator-name = "DC_IN";
>   		regulator-min-microvolt = <5000000>;
> @@ -93,7 +93,7 @@ vcck: regulator-vcck {
>   		regulator-always-on;
>   	};
>   
> -	vcc_card: regulator-vcc_card {
> +	vcc_card: regulator-vcc-card {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_CARD";
>   		regulator-min-microvolt = <3300000>;
> @@ -114,7 +114,7 @@ vcc5v: regulator-vcc5v {
>   		gpio = <&gpio GPIOH_3 GPIO_OPEN_DRAIN>;
>   	};
>   
> -	vddio_ao3v3: regulator-vddio_ao3v3 {
> +	vddio_ao3v3: regulator-vddio-ao3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -139,7 +139,7 @@ vddio_card: regulator-vddio-card {
>   		regulator-settling-time-down-us = <50000>;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
> @@ -148,7 +148,7 @@ vddio_ao18: regulator-vddio_ao18 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_1v8: regulator-vcc_1v8 {
> +	vcc_1v8: regulator-vcc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC 1V8";
>   		regulator-min-microvolt = <1800000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
> index 27093e6ac9e2..8b26c9661be1 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
> @@ -93,7 +93,7 @@ hdmi_5v: regulator-hdmi-5v {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -117,7 +117,7 @@ vcc_card: regulator-vcc-card {
>   		regulator-settling-time-down-us = <50000>;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
> @@ -125,7 +125,7 @@ vddio_ao18: regulator-vddio_ao18 {
>   	};
>   
>   	/* This is provided by LDOs on the eMMC daugther card */
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
> index f1acca5c4434..c79f9f2099bf 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
> @@ -42,21 +42,21 @@ vddio_card: gpio-regulator {
>   			 <3300000 1>;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> 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 a150cc0e18ff..7e7dc87ede2d 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> @@ -39,28 +39,28 @@ hdmi_5v: regulator-hdmi-5v {
>   		regulator-always-on;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
> index 860f307494c5..07e7c3bedea0 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
> @@ -112,28 +112,28 @@ hdmi_5v: regulator-hdmi-5v {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
>   		regulator-max-microvolt = <3300000>;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddio_boot: regulator-vddio_boot {
> +	vddio_boot: regulator-vddio-boot {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_BOOT";
>   		regulator-min-microvolt = <1800000>;
>   		regulator-max-microvolt = <1800000>;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts
> index 4eda9f634c42..a66f19851ac9 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts
> @@ -14,7 +14,7 @@ / {
>   		     "amlogic,meson-gxm";
>   	model = "Libre Computer AML-S912-PC";
>   
> -	typec2_vbus: regulator-typec2_vbus {
> +	typec2_vbus: regulator-typec2-vbus {
>   		compatible = "regulator-fixed";
>   		regulator-name = "TYPEC2_VBUS";
>   		regulator-min-microvolt = <5000000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
> index 514a6dd4b124..e78cc9b577a0 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
> @@ -80,7 +80,7 @@ sdio_pwrseq: sdio-pwrseq {
>   		clock-names = "ext_clock";
>   	};
>   
> -	dc_in: regulator-dc_in {
> +	dc_in: regulator-dc-in {
>   		compatible = "regulator-fixed";
>   		regulator-name = "DC_IN";
>   		regulator-min-microvolt = <5000000>;
> @@ -88,7 +88,7 @@ dc_in: regulator-dc_in {
>   		regulator-always-on;
>   	};
>   
> -	vcc_5v: regulator-vcc_5v {
> +	vcc_5v: regulator-vcc-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -99,7 +99,7 @@ vcc_5v: regulator-vcc_5v {
>   		enable-active-high;
>   	};
>   
> -	vcc_1v8: regulator-vcc_1v8 {
> +	vcc_1v8: regulator-vcc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -108,7 +108,7 @@ vcc_1v8: regulator-vcc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -118,7 +118,7 @@ vcc_3v3: regulator-vcc_3v3 {
>   		/* FIXME: actually controlled by VDDCPU_B_EN */
>   	};
>   
> -	vddao_1v8: regulator-vddao_1v8 {
> +	vddao_1v8: regulator-vddao-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -127,7 +127,7 @@ vddao_1v8: regulator-vddao_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	emmc_1v8: regulator-emmc_1v8 {
> +	emmc_1v8: regulator-emmc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "EMMC_AO1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -136,7 +136,7 @@ emmc_1v8: regulator-emmc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vsys_3v3: regulator-vsys_3v3 {
> +	vsys_3v3: regulator-vsys-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VSYS_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -145,7 +145,7 @@ vsys_3v3: regulator-vsys_3v3 {
>   		regulator-always-on;
>   	};
>   
> -	usb_pwr: regulator-usb_pwr {
> +	usb_pwr: regulator-usb-pwr {
>   		compatible = "regulator-fixed";
>   		regulator-name = "USB_PWR";
>   		regulator-min-microvolt = <5000000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi b/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
> index 35e8f5bae990..082b72703cdf 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
> @@ -150,7 +150,7 @@ vcc_5v: regulator-vcc-5v {
>   		gpio-open-drain;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -171,7 +171,7 @@ vddcpu_b: regulator-vddcpu-b {
>   		pwm-dutycycle-range = <100 0>;
>   	};
>   
> -	vddio_ao18: regulator-vddio_ao18 {
> +	vddio_ao18: regulator-vddio-ao18 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO18";
>   		regulator-min-microvolt = <1800000>;
> @@ -180,7 +180,7 @@ vddio_ao18: regulator-vddio_ao18 {
>   		vin-supply = <&vddao_3v3>;
>   	};
>   
> -	vddio_c: regulator-vddio_c {
> +	vddio_c: regulator-vddio-c {
>   		compatible = "regulator-gpio";
>   		regulator-name = "VDDIO_C";
>   		regulator-min-microvolt = <1800000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
> index 46a34731f7e2..d1fa8b8bf795 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
> @@ -54,7 +54,7 @@ memory at 0 {
>   		reg = <0x0 0x0 0x0 0x40000000>;
>   	};
>   
> -	ao_5v: regulator-ao_5v {
> +	ao_5v: regulator-ao-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "AO_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -63,7 +63,7 @@ ao_5v: regulator-ao_5v {
>   		regulator-always-on;
>   	};
>   
> -	dc_in: regulator-dc_in {
> +	dc_in: regulator-dc-in {
>   		compatible = "regulator-fixed";
>   		regulator-name = "DC_IN";
>   		regulator-min-microvolt = <5000000>;
> @@ -71,7 +71,7 @@ dc_in: regulator-dc_in {
>   		regulator-always-on;
>   	};
>   
> -	emmc_1v8: regulator-emmc_1v8 {
> +	emmc_1v8: regulator-emmc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "EMMC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -80,7 +80,7 @@ emmc_1v8: regulator-emmc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -105,7 +105,7 @@ vddcpu: regulator-vddcpu {
>   		regulator-always-on;
>   	};
>   
> -	vddio_ao1v8: regulator-vddio_ao1v8 {
> +	vddio_ao1v8: regulator-vddio-ao1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO1V8";
>   		regulator-min-microvolt = <1800000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi
> index 62404743e62d..81dce862902a 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi
> @@ -82,7 +82,7 @@ memory at 0 {
>   		reg = <0x0 0x0 0x0 0x40000000>;
>   	};
>   
> -	emmc_1v8: regulator-emmc_1v8 {
> +	emmc_1v8: regulator-emmc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "EMMC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -91,7 +91,7 @@ emmc_1v8: regulator-emmc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	dc_in: regulator-dc_in {
> +	dc_in: regulator-dc-in {
>   		compatible = "regulator-fixed";
>   		regulator-name = "DC_IN";
>   		regulator-min-microvolt = <5000000>;
> @@ -99,7 +99,7 @@ dc_in: regulator-dc_in {
>   		regulator-always-on;
>   	};
>   
> -	vddio_c: regulator-vddio_c {
> +	vddio_c: regulator-vddio-c {
>   		compatible = "regulator-gpio";
>   		regulator-name = "VDDIO_C";
>   		regulator-min-microvolt = <1800000>;
> @@ -116,7 +116,7 @@ vddio_c: regulator-vddio_c {
>   			 <3300000 1>;
>   	};
>   
> -	tflash_vdd: regulator-tflash_vdd {
> +	tflash_vdd: regulator-tflash-vdd {
>   		compatible = "regulator-fixed";
>   		regulator-name = "TFLASH_VDD";
>   		regulator-min-microvolt = <3300000>;
> @@ -127,7 +127,7 @@ tflash_vdd: regulator-tflash_vdd {
>   		regulator-always-on;
>   	};
>   
> -	vddao_1v8: regulator-vddao_1v8 {
> +	vddao_1v8: regulator-vddao-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -136,7 +136,7 @@ vddao_1v8: regulator-vddao_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -165,7 +165,7 @@ vddcpu: regulator-vddcpu {
>   	};
>   
>   	/* USB Hub Power Enable */
> -	vl_pwr_en: regulator-vl_pwr_en {
> +	vl_pwr_en: regulator-vl-pwr-en {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VL_PWR_EN";
>   		regulator-min-microvolt = <5000000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts
> index 846a2d6c20e5..0170139b8d32 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts
> @@ -43,7 +43,7 @@ led-red {
>   	};
>   
>   	/* Powers the SATA Disk 0 regulator, which is enabled when a disk load is detected */
> -	p12v_0: regulator-p12v_0 {
> +	p12v_0: regulator-p12v-0 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "P12V_0";
>   		regulator-min-microvolt = <12000000>;
> @@ -56,7 +56,7 @@ p12v_0: regulator-p12v_0 {
>   	};
>   
>   	/* Powers the SATA Disk 1 regulator, which is enabled when a disk load is detected */
> -	p12v_1: regulator-p12v_1 {
> +	p12v_1: regulator-p12v-1 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "P12V_1";
>   		regulator-min-microvolt = <12000000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> index 1db2327bbd13..951eb8e3f0c0 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> @@ -28,7 +28,7 @@ emmc_pwrseq: emmc-pwrseq {
>   		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
>   	};
>   
> -	tflash_vdd: regulator-tflash_vdd {
> +	tflash_vdd: regulator-tflash-vdd {
>   		compatible = "regulator-fixed";
>   
>   		regulator-name = "TFLASH_VDD";
> @@ -40,7 +40,7 @@ tflash_vdd: regulator-tflash_vdd {
>   		regulator-always-on;
>   	};
>   
> -	tf_io: gpio-regulator-tf_io {
> +	tf_io: gpio-regulator-tf-io {
>   		compatible = "regulator-gpio";
>   
>   		regulator-name = "TF_IO";
> @@ -59,7 +59,7 @@ tf_io: gpio-regulator-tf_io {
>   			 <1800000 1>;
>   	};
>   
> -	flash_1v8: regulator-flash_1v8 {
> +	flash_1v8: regulator-flash-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "FLASH_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -68,7 +68,7 @@ flash_1v8: regulator-flash_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	main_12v: regulator-main_12v {
> +	main_12v: regulator-main-12v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "12V";
>   		regulator-min-microvolt = <12000000>;
> @@ -76,7 +76,7 @@ main_12v: regulator-main_12v {
>   		regulator-always-on;
>   	};
>   
> -	vcc_5v: regulator-vcc_5v {
> +	vcc_5v: regulator-vcc-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -87,7 +87,7 @@ vcc_5v: regulator-vcc_5v {
>   		enable-active-high;
>   	};
>   
> -	vcc_1v8: regulator-vcc_1v8 {
> +	vcc_1v8: regulator-vcc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -96,7 +96,7 @@ vcc_1v8: regulator-vcc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vcc_3v3: regulator-vcc_3v3 {
> +	vcc_3v3: regulator-vcc-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VCC_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -125,7 +125,7 @@ vddcpu: regulator-vddcpu {
>   		regulator-always-on;
>   	};
>   
> -	usb_pwr_en: regulator-usb_pwr_en {
> +	usb_pwr_en: regulator-usb-pwr-en {
>   		compatible = "regulator-fixed";
>   		regulator-name = "USB_PWR_EN";
>   		regulator-min-microvolt = <5000000>;
> @@ -137,7 +137,7 @@ usb_pwr_en: regulator-usb_pwr_en {
>   		enable-active-high;
>   	};
>   
> -	vddao_1v8: regulator-vddao_1v8 {
> +	vddao_1v8: regulator-vddao-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -146,7 +146,7 @@ vddao_1v8: regulator-vddao_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
> index 109932068dbe..3581e14cbf18 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
> @@ -127,7 +127,7 @@ memory at 0 {
>   		reg = <0x0 0x0 0x0 0x40000000>;
>   	};
>   
> -	ao_5v: regulator-ao_5v {
> +	ao_5v: regulator-ao-5v {
>   		compatible = "regulator-fixed";
>   		regulator-name = "AO_5V";
>   		regulator-min-microvolt = <5000000>;
> @@ -136,7 +136,7 @@ ao_5v: regulator-ao_5v {
>   		regulator-always-on;
>   	};
>   
> -	dc_in: regulator-dc_in {
> +	dc_in: regulator-dc-in {
>   		compatible = "regulator-fixed";
>   		regulator-name = "DC_IN";
>   		regulator-min-microvolt = <5000000>;
> @@ -144,7 +144,7 @@ dc_in: regulator-dc_in {
>   		regulator-always-on;
>   	};
>   
> -	emmc_1v8: regulator-emmc_1v8 {
> +	emmc_1v8: regulator-emmc-1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "EMMC_1V8";
>   		regulator-min-microvolt = <1800000>;
> @@ -153,7 +153,7 @@ emmc_1v8: regulator-emmc_1v8 {
>   		regulator-always-on;
>   	};
>   
> -	vddao_3v3: regulator-vddao_3v3 {
> +	vddao_3v3: regulator-vddao-3v3 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3";
>   		regulator-min-microvolt = <3300000>;
> @@ -163,7 +163,7 @@ vddao_3v3: regulator-vddao_3v3 {
>   	};
>   
>   	/* Used by Tuner, RGB Led & IR Emitter LED array */
> -	vddao_3v3_t: regulator-vddao_3v3_t {
> +	vddao_3v3_t: regulator-vddao-3v3-t {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDAO_3V3_T";
>   		regulator-min-microvolt = <3300000>;
> @@ -192,7 +192,7 @@ vddcpu: regulator-vddcpu {
>   		regulator-always-on;
>   	};
>   
> -	vddio_ao1v8: regulator-vddio_ao1v8 {
> +	vddio_ao1v8: regulator-vddio-ao1v8 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "VDDIO_AO1V8";
>   		regulator-min-microvolt = <1800000>;

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Mon Feb 19 00:54:30 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 19 Feb 2024 09:54:30 +0100
Subject: [PATCH] arm64: dts: amlogic: replace underscores in node names
In-Reply-To: <20240213143217.336341-1-krzysztof.kozlowski@linaro.org>
References: <20240213143217.336341-1-krzysztof.kozlowski@linaro.org>
Message-ID: <170833287080.1749763.10941075703798896000.b4-ty@linaro.org>

Hi,

On Tue, 13 Feb 2024 15:32:17 +0100, Krzysztof Kozlowski wrote:
> Underscores should not be used in node names (dtc with W=2 warns about
> them), so replace them with hyphens.
> 
> 

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v6.9/arm64-dt)

[1/1] arm64: dts: amlogic: replace underscores in node names
      https://git.kernel.org/amlogic/c/f0ed445e7397e386264d4752a5eb5d2dfc7f7fd2

These changes has been applied on the intermediate git tree [1].

The v6.9/arm64-dt branch will then be sent via a formal Pull Request to the Linux SoC maintainers
for inclusion in their intermediate git branches in order to be sent to Linus during
the next merge window, or sooner if it's a set of fixes.

In the cases of fixes, those will be merged in the current release candidate
kernel and as soon they appear on the Linux master branch they will be
backported to the previous Stable and Long-Stable kernels [2].

The intermediate git branches are merged daily in the linux-next tree [3],
people are encouraged testing these pre-release kernels and report issues on the
relevant mailing-lists.

If problems are discovered on those changes, please submit a signed-off-by revert
patch followed by a corrective changeset.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git
[2] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
[3] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git

-- 
Neil



From neil.armstrong at linaro.org  Mon Feb 19 00:55:26 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 19 Feb 2024 09:55:26 +0100
Subject: [PATCH v1 0/3] ARM: dts: amlogic: Three small binding check
 error fixes
In-Reply-To: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>
References: <20240218111959.1811676-1-martin.blumenstingl@googlemail.com>
Message-ID: <170833292669.1750802.15916025234070714227.b4-ty@linaro.org>

Hi,

On Sun, 18 Feb 2024 12:19:56 +0100, Martin Blumenstingl wrote:
> This series contains three small binding check fixes.
> Nothing functional was broken before, so no need to backpport any of
> these to -stable.
> 
> 
> Martin Blumenstingl (3):
>   ARM: dts: meson: fix bus node names
>   ARM: dts: meson8: fix &hwrng node compatible string
>   ARM: dts: meson8b: fix &hwrng node compatible string
> 
> [...]

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v6.9/arm-dt)

[1/3] ARM: dts: meson: fix bus node names
      https://git.kernel.org/amlogic/c/0a20438f4531b55393a2e85bd0cb9cc45362a6a4
[2/3] ARM: dts: meson8: fix &hwrng node compatible string
      https://git.kernel.org/amlogic/c/6f2cc11b4340cb5b0f81fe72eb732144bc7b6287
[3/3] ARM: dts: meson8b: fix &hwrng node compatible string
      https://git.kernel.org/amlogic/c/778a2c000470ee56551d0833a0eaa387530e4bec

These changes has been applied on the intermediate git tree [1].

The v6.9/arm-dt branch will then be sent via a formal Pull Request to the Linux SoC maintainers
for inclusion in their intermediate git branches in order to be sent to Linus during
the next merge window, or sooner if it's a set of fixes.

In the cases of fixes, those will be merged in the current release candidate
kernel and as soon they appear on the Linux master branch they will be
backported to the previous Stable and Long-Stable kernels [2].

The intermediate git branches are merged daily in the linux-next tree [3],
people are encouraged testing these pre-release kernels and report issues on the
relevant mailing-lists.

If problems are discovered on those changes, please submit a signed-off-by revert
patch followed by a corrective changeset.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git
[2] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
[3] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git

-- 
Neil



From neil.armstrong at linaro.org  Mon Feb 19 00:57:16 2024
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Mon, 19 Feb 2024 09:57:16 +0100
Subject: [PATCH] arm64: defconfig: build ath12k as a module
In-Reply-To: <20240219084610.11007-1-brgl@bgdev.pl>
References: <20240219084610.11007-1-brgl@bgdev.pl>
Message-ID: <83e153f6-4e48-4126-99bf-e8daf4f69b9c@linaro.org>

On 19/02/2024 09:46, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> Qualcomm sm8550-qrd and sm8650-qrd boards have ath12k modules as part of
> their on-board WCN7850 WLAN/BT packages. Enable the relevant driver in
> defconfig.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---
>   arch/arm64/configs/defconfig | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 056a6cc546a4..3f3d3350cf90 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -408,6 +408,7 @@ CONFIG_WCN36XX=m
>   CONFIG_ATH11K=m
>   CONFIG_ATH11K_AHB=m
>   CONFIG_ATH11K_PCI=m
> +CONFIG_ATH12K=m
>   CONFIG_BRCMFMAC=m
>   CONFIG_MWIFIEX=m
>   CONFIG_MWIFIEX_SDIO=m

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From brgl at bgdev.pl  Mon Feb 19 00:57:15 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 09:57:15 +0100
Subject: [PATCH] arm64: defconfig: build ath12k as a module
In-Reply-To: <c083c1af-31ef-43a8-ba2d-98d63dfe45e0@app.fastmail.com>
References: <20240219084610.11007-1-brgl@bgdev.pl> <c083c1af-31ef-43a8-ba2d-98d63dfe45e0@app.fastmail.com>
Message-ID: <CAMRc=Me1q_CV02DO4+i+-yik2RMwAbbTqropd9JU7c2axVwY8Q@mail.gmail.com>

On Mon, Feb 19, 2024 at 9:48?AM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Mon, Feb 19, 2024, at 09:46, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > Qualcomm sm8550-qrd and sm8650-qrd boards have ath12k modules as part of
> > their on-board WCN7850 WLAN/BT packages. Enable the relevant driver in
> > defconfig.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > ---
>
> Acked-by: Arnd Bergmann <arnd at arndb.de>
>
> I assume that Bjorn will pick this up through the qualcomm
> tree.
>
>      Arnd

This doesn't conflict with any of my other work and I was told to send
it separately to make the pwrseq series smaller. I think you can pick
it up already and send it upstream earlier.

Bart


From umang.jain at ideasonboard.com  Mon Feb 19 01:03:21 2024
From: umang.jain at ideasonboard.com (Umang Jain)
Date: Mon, 19 Feb 2024 14:33:21 +0530
Subject: [PATCH] media: rkisp1: Allow higher input resolution
In-Reply-To: <CAHCN7x+zi3WxnY-mxZFKePs1cS=-DprEmh_CnypJ4XK7xBzjMQ@mail.gmail.com>
References: <20240217185202.1754750-1-megi@xff.cz>
 <20240218205908.GA12766@pendragon.ideasonboard.com>
 <pftafukuzq7qzbhlvwtmeg3mburnttylgy4246timlghtrdgx4@r6munvmj6oqt>
 <CAHCN7x+zi3WxnY-mxZFKePs1cS=-DprEmh_CnypJ4XK7xBzjMQ@mail.gmail.com>
Message-ID: <b500676e-431f-40fc-868b-9f9bb359a109@ideasonboard.com>

Hi All,

On 19/02/24 7:39 am, Adam Ford wrote:
> On Sun, Feb 18, 2024 at 3:02?PM Ond?ej Jirman <megi at xff.cz> wrote:
>> On Sun, Feb 18, 2024 at 10:59:08PM +0200, Laurent Pinchart wrote:
>>> Hi Ondrej,
>>>
>>> (CC'ing Paul and Umang)
>>>
>>> Thank you for the patch.
>>>
>>> On Sat, Feb 17, 2024 at 07:51:58PM +0100, Ond?ej Jirman wrote:
>>>> From: Ondrej Jirman <megi at xff.cz>
>>>>
>>>> In BSP driver, it is allowed, and it works in practice. Tested on
>>>> Pinephone Pro/RK3399 with IMX258 at full res.
>>> Paul, Umang, do I recall correctly that you have a similar change ?
>>> Could you review and test this (especially on the i.MX8MP) ?
>> It's also a limit from the datasheet, so the change should not be that
>> controversial:
>>
>>    https://megous.com/dl/tmp/d2b333043ecebaf3.png
>>
>> (so that it doesn't sound like I just copied the BSP values)
>>
>  From what I see in the i.MX8M Plus reference manual, it has a max
> resolution of 4096x3072, so it might be necessary to move this off

This is what I (and I assume Paul too) have been working with on i.MX8M 
Plus. So it's the known and tested value of max ISP input from out side.
> from a #define into a structure that varies by product family.

Yeah!
>
> adam
>> regards,
>>          o.
>>
>>>> Signed-off-by: Ondrej Jirman <megi at xff.cz>
>>>> ---
>>>>   drivers/media/platform/rockchip/rkisp1/rkisp1-common.h | 4 ++--
>>>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
>>>> index 4b6b28c05b89..74098ddbeeb3 100644
>>>> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
>>>> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
>>>> @@ -33,8 +33,8 @@ struct dentry;
>>>>   #define RKISP1_ISP_SD_SINK                 BIT(1)
>>>>
>>>>   /* min and max values for the widths and heights of the entities */
>>>> -#define RKISP1_ISP_MAX_WIDTH                       4032
>>>> -#define RKISP1_ISP_MAX_HEIGHT                      3024
>>>> +#define RKISP1_ISP_MAX_WIDTH                       4416
>>>> +#define RKISP1_ISP_MAX_HEIGHT                      3312
>>>>   #define RKISP1_ISP_MIN_WIDTH                       32
>>>>   #define RKISP1_ISP_MIN_HEIGHT                      32
>>>>
>>> --
>>> Regards,
>>>
>>> Laurent Pinchart



From vaishnav.a at ti.com  Mon Feb 19 01:04:33 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Mon, 19 Feb 2024 14:34:33 +0530
Subject: [PATCH v2 0/2] Add OSPI and Ethernet support on J722S EVM
Message-ID: <20240219090435.934383-1-vaishnav.a@ti.com>

Hi,

This series adds support for Ethernet and OSPI NOR flash on J722S EVM.

V1: https://lore.kernel.org/all/20240216135533.904130-1-vaishnav.a at ti.com/

Changelog:
V1->V2:
  * Update comments indicating PAD numbers.  

EVM Schematics are available at:
	https://www.ti.com/lit/zip/sprr495

Test log (6.8.0-rc4-next-20240216):
  https://gist.github.com/vaishnavachath/b04e3be90af4cdec59fb0d9cc72441b9

For those interested, more details about this SoC can be found in the
Technical Reference Manual here:
            https://www.ti.com/lit/zip/sprujb3

Thanks and Regards,
Vaishnav

Siddharth Vadapalli (1):
  arm64: dts: ti: k3-j722s-evm: Enable CPSW3G RGMII1

Vaishnav Achath (1):
  arm64: dts: ti: k3-j722s-evm: Enable OSPI NOR support

 arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 132 ++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

-- 
2.34.1



From vaishnav.a at ti.com  Mon Feb 19 01:04:34 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Mon, 19 Feb 2024 14:34:34 +0530
Subject: [PATCH v2 1/2] arm64: dts: ti: k3-j722s-evm: Enable CPSW3G RGMII1
In-Reply-To: <20240219090435.934383-1-vaishnav.a@ti.com>
References: <20240219090435.934383-1-vaishnav.a@ti.com>
Message-ID: <20240219090435.934383-2-vaishnav.a@ti.com>

From: Siddharth Vadapalli <s-vadapalli at ti.com>

Enable MAC Port 1 of CPSW3G instance of CPSW Ethernet Switch in
RGMII-RXID mode of operation. Port 2 is not connected on the EVM,
thus keep it disabled.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 53 +++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
index b4f2fee53a97..9e12a6e9111f 100644
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
@@ -8,6 +8,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/net/ti-dp83867.h>
 #include "k3-j722s.dtsi"
 
 / {
@@ -160,6 +161,58 @@ J722S_IOPAD(0x0240, PIN_INPUT, 0) /* (B24) MMC1_SDCD */
 		>;
 		bootph-all;
 	};
+
+	mdio_pins_default: mdio-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AC24) MDIO0_MDC */
+			J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) MDIO0_MDIO */
+		>;
+	};
+
+	rgmii1_pins_default: rgmii1-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x014c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */
+			J722S_IOPAD(0x0150, PIN_INPUT, 0) /* (AD27) RGMII1_RD1 */
+			J722S_IOPAD(0x0154, PIN_INPUT, 0) /* (AE24) RGMII1_RD2 */
+			J722S_IOPAD(0x0158, PIN_INPUT, 0) /* (AE26) RGMII1_RD3 */
+			J722S_IOPAD(0x0148, PIN_INPUT, 0) /* (AE27) RGMII1_RXC */
+			J722S_IOPAD(0x0144, PIN_INPUT, 0) /* (AD23) RGMII1_RX_CTL */
+			J722S_IOPAD(0x0134, PIN_OUTPUT, 0) /* (AF27) RGMII1_TD0 */
+			J722S_IOPAD(0x0138, PIN_OUTPUT, 0) /* (AE23) RGMII1_TD1 */
+			J722S_IOPAD(0x013c, PIN_OUTPUT, 0) /* (AG25) RGMII1_TD2 */
+			J722S_IOPAD(0x0140, PIN_OUTPUT, 0) /* (AF24) RGMII1_TD3 */
+			J722S_IOPAD(0x0130, PIN_OUTPUT, 0) /* (AG26) RGMII1_TXC */
+			J722S_IOPAD(0x012c, PIN_OUTPUT, 0) /* (AF25) RGMII1_TX_CTL */
+		>;
+	};
+};
+
+&cpsw3g {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins_default>;
+};
+
+&cpsw3g_mdio {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio_pins_default>;
+
+	cpsw3g_phy0: ethernet-phy at 0 {
+		reg = <0>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+		ti,min-output-impedance;
+	};
+};
+
+&cpsw_port1 {
+	phy-mode = "rgmii-rxid";
+	phy-handle = <&cpsw3g_phy0>;
+};
+
+&cpsw_port2 {
+	status = "disabled";
 };
 
 &main_gpio1 {
-- 
2.34.1



From vaishnav.a at ti.com  Mon Feb 19 01:04:35 2024
From: vaishnav.a at ti.com (Vaishnav Achath)
Date: Mon, 19 Feb 2024 14:34:35 +0530
Subject: [PATCH v2 2/2] arm64: dts: ti: k3-j722s-evm: Enable OSPI NOR support
In-Reply-To: <20240219090435.934383-1-vaishnav.a@ti.com>
References: <20240219090435.934383-1-vaishnav.a@ti.com>
Message-ID: <20240219090435.934383-3-vaishnav.a@ti.com>

J722S EVM has S28HS512T 64 MiB Octal SPI NOR flash connected
to the OSPI interface, add support for the flash and describe
the partition information as per bootloader.

Signed-off-by: Vaishnav Achath <vaishnav.a at ti.com>
---

V1->V2:
  * Update comments indicating PAD numbers. 

 arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 79 +++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
index 9e12a6e9111f..cee3a8661d5e 100644
--- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
@@ -169,6 +169,23 @@ J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) MDIO0_MDIO */
 		>;
 	};
 
+	ospi0_pins_default: ospi0-default-pins {
+		pinctrl-single,pins = <
+			J722S_IOPAD(0x0000, PIN_OUTPUT, 0) /* (L24) OSPI0_CLK */
+			J722S_IOPAD(0x002c, PIN_OUTPUT, 0) /* (K26) OSPI0_CSn0 */
+			J722S_IOPAD(0x000c, PIN_INPUT, 0) /* (K27) OSPI0_D0 */
+			J722S_IOPAD(0x0010, PIN_INPUT, 0) /* (L27) OSPI0_D1 */
+			J722S_IOPAD(0x0014, PIN_INPUT, 0) /* (L26) OSPI0_D2 */
+			J722S_IOPAD(0x0018, PIN_INPUT, 0) /* (L25) OSPI0_D3 */
+			J722S_IOPAD(0x001c, PIN_INPUT, 0) /* (L21) OSPI0_D4 */
+			J722S_IOPAD(0x0020, PIN_INPUT, 0) /* (M26) OSPI0_D5 */
+			J722S_IOPAD(0x0024, PIN_INPUT, 0) /* (N27) OSPI0_D6 */
+			J722S_IOPAD(0x0028, PIN_INPUT, 0) /* (M27) OSPI0_D7 */
+			J722S_IOPAD(0x0008, PIN_INPUT, 0) /* (L22) OSPI0_DQS */
+		>;
+		bootph-all;
+	};
+
 	rgmii1_pins_default: rgmii1-default-pins {
 		pinctrl-single,pins = <
 			J722S_IOPAD(0x014c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */
@@ -290,6 +307,68 @@ exp1: gpio at 23 {
 	};
 };
 
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_pins_default>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <4>;
+		bootph-all;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "ospi.tiboot3";
+				reg = <0x00 0x80000>;
+			};
+
+			partition at 80000 {
+				label = "ospi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition at 280000 {
+				label = "ospi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition at 680000 {
+				label = "ospi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition at 6c0000 {
+				label = "ospi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition at 800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition at 3fc0000 {
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+
+};
+
 &sdhci1 {
 	/* SD/MMC */
 	vmmc-supply = <&vdd_mmc1>;
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Mon Feb 19 01:06:33 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 10:06:33 +0100
Subject: [PATCH v2 1/2] dt-bindings: arm64: mediatek: add Kontron
 3.5"-SBC-i1200
In-Reply-To: <20240219084456.1075445-1-mwalle@kernel.org>
References: <20240219084456.1075445-1-mwalle@kernel.org>
Message-ID: <72fffc25-33f0-4394-b7c1-8dbc2d23a4a4@linaro.org>

On 19/02/2024 09:44, Michael Walle wrote:
> Add the compatible string for the Kontron 3.5"-SBC-i1200 single board
> computer.
> 
> Signed-off-by: Michael Walle <mwalle at kernel.org>
> ---
> v2:
>  - convert enum to const as there is only one specific board
> 
>  Documentation/devicetree/bindings/arm/mediatek.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
> index 09f9ffd3ff7b..add167d8b8da 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
> @@ -357,6 +357,11 @@ properties:
>                - radxa,nio-12l
>            - const: mediatek,mt8395
>            - const: mediatek,mt8195
> +      - description: Kontron 3.5"-SBC-i1200
> +        items:
> +          - const: kontron,3-5-sbc-i1200

And then it should be part of earlier entry. Just take a look there in
the file...

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Mon Feb 19 01:07:52 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 10:07:52 +0100
Subject: [PATCH] dt-bindings: ata: convert MediaTek controller to the
 json-schema
In-Reply-To: <ZdMTx1CJzFR5uAzK@x1-carbon>
References: <20240213074747.26151-1-zajec5@gmail.com>
 <ZdMTx1CJzFR5uAzK@x1-carbon>
Message-ID: <77a7223b-9407-4191-b53a-0bfc623f14bf@linaro.org>

On 19/02/2024 09:39, Niklas Cassel wrote:
> On Tue, Feb 13, 2024 at 08:47:47AM +0100, Rafa? Mi?ecki wrote:
>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>
>> This helps validating DTS files.
>>
>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>> ---
> 
> Hello Rob,
> 
> For device tree patches for
> Documentation/devicetree/bindings/ata/
> 
> Usually, if we see your Acked-by, we queue the patch via the libata tree.
> (If it is part of a series, usually you take it via your tree.)
> 
> We have a R-b from Krzysztof, but no Ack from you.

You don't need Ack from Rob. Rb or Ack from one of three DT maintainers
is enough. Therefore mine is enough.

https://www.kernel.org/doc/html/latest/process/maintainers.html#open-firmware-and-flattened-device-tree-bindings

Best regards,
Krzysztof



From schwab at suse.de  Mon Feb 19 01:17:02 2024
From: schwab at suse.de (Andreas Schwab)
Date: Mon, 19 Feb 2024 10:17:02 +0100
Subject: 6.7 regression: platform 4809c000.mmc: deferred probe pending
In-Reply-To: <20240216120833.GT52537@atomide.com> (Tony Lindgren's message of
	"Fri, 16 Feb 2024 14:08:33 +0200")
References: <mvmcyt13idm.fsf@suse.de>
	<c92385d2-1909-43a8-aea8-cd9a8687a898@leemhuis.info>
	<20240215094640.GS52537@atomide.com> <mvmeddeyqb8.fsf@suse.de>
	<2024021516-stricken-bubble-bf8d@gregkh>
	<20240216120833.GT52537@atomide.com>
Message-ID: <mvmy1bgyfsh.fsf@suse.de>

On Feb 16 2024, Tony Lindgren wrote:

> Andreas, did commit 7a29fa05aeca solve the issue?

Yes, it does.  Thanks.

-- 
Andreas Schwab, SUSE Labs, schwab at suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


From angelogioacchino.delregno at collabora.com  Mon Feb 19 01:17:05 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 10:17:05 +0100
Subject: [PATCH] arm64: dts: {mt7622,mt7986}: add port@5 as CPU port
In-Reply-To: <5d582382-9a31-4a95-bc81-01d99dde0a6e@arinc9.com>
References: <20230918074938.79796-1-arinc.unal@arinc9.com>
 <5d582382-9a31-4a95-bc81-01d99dde0a6e@arinc9.com>
Message-ID: <2795a056-eac2-491b-bcb5-52bf4a331c07@collabora.com>

Il 18/02/24 11:52, Ar?n? ?NAL ha scritto:
> Matthias, please apply this patch.
> 
> Ar?n?

Please split this by SoC and resend as two patches.

If you can resend fast enough, I can apply the patches for 6.9.

Cheers,
Angelo


From will at kernel.org  Mon Feb 19 01:17:09 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 19 Feb 2024 09:17:09 +0000
Subject: [PATCH] drivers/iommu: Ensure that the queue base address is
 successfully written during SMMU initialization.
In-Reply-To: <CAE2F3rA1Lb_ayrLQTw+urtNSMoBg9q6CmcSsP7_dZwbfiYygsw@mail.gmail.com>
References: <20240218050224.33426-1-niliqiang.io@gmail.com>
 <CAE2F3rA1Lb_ayrLQTw+urtNSMoBg9q6CmcSsP7_dZwbfiYygsw@mail.gmail.com>
Message-ID: <20240219091709.GA4105@willie-the-truck>

On Sun, Feb 18, 2024 at 09:44:47PM -0800, Daniel Mentz wrote:
> On Sat, Feb 17, 2024 at 9:02?PM ni.liqiang <niliqiang.io at gmail.com> wrote:
> > If there are no memory barriers, how can we ensure this order?
> 
>  The SMMU registers are accessed using Device-nGnRE attributes. It is
> my understanding that, for Device-nGnRE, the Arm architecture requires
> that writes to the same peripheral arrive at the endpoint in program
> order.

Yup, that's correct. The "nR" part means "non-Reordering", so something
else is going on here.

Will


From maz at kernel.org  Mon Feb 19 01:20:01 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:01 +0000
Subject: [PATCH 00/13] KVM/arm64: Add NV support for ERET and PAuth
Message-ID: <20240219092014.783809-1-maz@kernel.org>

Although the current upstream NV support has *some* support for
correctly emulating ERET, that support is only partial as it doesn't
support the ERETAA and ERETAB variants.

Supporting these instructions was cast aside for a long time as it
involves implementing some form of PAuth emulation, something I wasn't
overly keen on. But I have reached a point where enough of the
infrastructure is there that it actually makes sense. So here it is!

This series completely relies on my previous VM configuration
enforcement series, as it expects all shadow registers to be sanitised
and to match the VM configuration.

The first 3 patches are only opportunistic cleanups and hardening.

Patch #4 adds the configuration of HCR_EL2 in the NV2 case, together
with VNCR_EL2 being populated.

Patches #5, #7 and #8 add more triage and trap forwarding on the
instruction side (SMC, ERET, PAC)

Patch #6 split the current ERET handling into a fixup which runs early
on exit, and the core part, which is only used when a translation
regime transition or an exception injection needs to take place.

The rest of the series finally adds the PAuth emulation for ERETA[AB]
(and only for these two instructions), plugs it into the ERET
handling, and finally advertises PAuth to the L1 guest.

Marc Zyngier (13):
  KVM: arm64: Harden __ctxt_sys_reg() against out-of-range values
  KVM: arm64: Clarify ESR_ELx_ERET_ISS_ERET*
  KVM: arm64: nv: Drop VCPU_HYP_CONTEXT flag
  KVM: arm64: nv: Configure HCR_EL2 for FEAT_NV2
  KVM: arm64: nv: Add trap forwarding for ERET and SMC
  KVM: arm64: nv: Fast-track 'InHost' exception returns
  KVM: arm64: nv: Honor HFGITR_EL2.ERET being set
  KVM: arm64: nv: Handle HCR_EL2.{API,APK} independantly
  KVM: arm64: nv: Reinject PAC exceptions caused by HCR_EL2.API==0
  KVM: arm64: nv: Add kvm_has_pauth() helper
  KVM: arm64: nv: Add emulation for ERETAx instructions
  KVM: arm64: nv: Handle ERETA[AB] instructions
  KVM: arm64: nv: Advertise support for PAuth

 arch/arm64/include/asm/esr.h            |   4 +-
 arch/arm64/include/asm/kvm_emulate.h    |   5 -
 arch/arm64/include/asm/kvm_host.h       |  26 +++-
 arch/arm64/include/asm/kvm_nested.h     |  13 ++
 arch/arm64/include/asm/pgtable-hwdef.h  |   1 +
 arch/arm64/include/asm/sysreg.h         |   1 +
 arch/arm64/kvm/Makefile                 |   1 +
 arch/arm64/kvm/emulate-nested.c         |  66 +++++---
 arch/arm64/kvm/handle_exit.c            |  38 ++++-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  36 ++++-
 arch/arm64/kvm/hyp/nvhe/switch.c        |   2 +-
 arch/arm64/kvm/hyp/vhe/switch.c         |  95 +++++++++++-
 arch/arm64/kvm/nested.c                 |   8 +-
 arch/arm64/kvm/pauth.c                  | 196 ++++++++++++++++++++++++
 14 files changed, 434 insertions(+), 58 deletions(-)
 create mode 100644 arch/arm64/kvm/pauth.c

-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:03 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:03 +0000
Subject: [PATCH 02/13] KVM: arm64: Clarify ESR_ELx_ERET_ISS_ERET*
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-3-maz@kernel.org>

The ESR_ELx_ERET_ISS_ERET* macros are a bit confusing:

- ESR_ELx_ERET_ISS_ERET really indicates that we have trapped an
  ERETA* instruction, as opposed to an ERET

- ESR_ELx_ERET_ISS_ERETA reallu indicates that we have trapped
  an ERETAB instruction, as opposed to an ERETAA.

Repaint the two helpers such as:

- ESR_ELx_ERET_ISS_ERET becomes ESR_ELx_ERET_ISS_ERETA

- ESR_ELx_ERET_ISS_ERETA becomes ESR_ELx_ERET_ISS_ERETAB

At the same time, use BIT() instead of raw values.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/esr.h | 4 ++--
 arch/arm64/kvm/handle_exit.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 353fe08546cf..72c7810ccf2c 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -290,8 +290,8 @@
 		 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
+#define ESR_ELx_ERET_ISS_ERETA		BIT(1)
+#define ESR_ELx_ERET_ISS_ERETAB		BIT(0)
 
 /*
  * ISS field definitions for floating-point exception traps
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 617ae6dea5d5..0646c623d1da 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -219,7 +219,7 @@ static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
 
 static int kvm_handle_eret(struct kvm_vcpu *vcpu)
 {
-	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERET)
+	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERETA)
 		return kvm_handle_ptrauth(vcpu);
 
 	/*
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:04 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:04 +0000
Subject: [PATCH 03/13] KVM: arm64: nv: Drop VCPU_HYP_CONTEXT flag
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-4-maz@kernel.org>

It has become obvious that HCR_EL2.NV serves the exact same use
as VCPU_HYP_CONTEXT, only in an architectural way. So just drop
the flag for good.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 2 --
 arch/arm64/kvm/hyp/vhe/switch.c   | 7 +------
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a5ec4c7d3966..75eb8e170515 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -816,8 +816,6 @@ struct kvm_vcpu_arch {
 #define DEBUG_STATE_SAVE_SPE	__vcpu_single_flag(iflags, BIT(5))
 /* Save TRBE context if active  */
 #define DEBUG_STATE_SAVE_TRBE	__vcpu_single_flag(iflags, BIT(6))
-/* vcpu running in HYP context */
-#define VCPU_HYP_CONTEXT	__vcpu_single_flag(iflags, BIT(7))
 
 /* SVE enabled for host EL0 */
 #define HOST_SVE_ENABLED	__vcpu_single_flag(sflags, BIT(0))
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 1581df6aec87..58415783fd53 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -197,7 +197,7 @@ 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_get_flag(vcpu, VCPU_HYP_CONTEXT))) {
+	if (unlikely(read_sysreg(hcr_el2) & HCR_NV)) {
 		u64 mode = *vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT);
 
 		switch (mode) {
@@ -240,11 +240,6 @@ 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_set_flag(vcpu, VCPU_HYP_CONTEXT);
-	else
-		vcpu_clear_flag(vcpu, VCPU_HYP_CONTEXT);
-
 	do {
 		/* Jump in the fire! */
 		exit_code = __guest_enter(vcpu);
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:06 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:06 +0000
Subject: [PATCH 05/13] KVM: arm64: nv: Add trap forwarding for ERET and SMC
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-6-maz@kernel.org>

Honor the trap forwarding bits for both ERET and SMC, using a new
helper that checks for common conditions.

Co-developed-by: Jintack Lim <jintack.lim 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_nested.h |  1 +
 arch/arm64/kvm/emulate-nested.c     | 27 +++++++++++++++++++++++++++
 arch/arm64/kvm/handle_exit.c        |  7 +++++++
 3 files changed, 35 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index c77d795556e1..dbc4e3a67356 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -60,6 +60,7 @@ static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
 	return ttbr0 & ~GENMASK_ULL(63, 48);
 }
 
+extern bool forward_smc_trap(struct kvm_vcpu *vcpu);
 
 int kvm_init_nv_sysregs(struct kvm *kvm);
 
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 4697ba41b3a9..2d80e81ae650 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2117,6 +2117,26 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
 	return true;
 }
 
+static 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 (!is_hyp_ctxt(vcpu) && control_bit_set) {
+		kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+		return true;
+	}
+	return false;
+}
+
+bool forward_smc_trap(struct kvm_vcpu *vcpu)
+{
+	return forward_traps(vcpu, HCR_TSC);
+}
+
 static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)
 {
 	u64 mode = spsr & PSR_MODE_MASK;
@@ -2155,6 +2175,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_traps(vcpu, HCR_NV))
+		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 0646c623d1da..1ccdfe40c691 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -55,6 +55,13 @@ static int handle_hvc(struct kvm_vcpu *vcpu)
 
 static int handle_smc(struct kvm_vcpu *vcpu)
 {
+	/*
+	 * Forward this trapped smc instruction to the virtual EL2 if
+	 * the guest has asked for it.
+	 */
+	if (forward_smc_trap(vcpu))
+		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
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:05 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:05 +0000
Subject: [PATCH 04/13] KVM: arm64: nv: Configure HCR_EL2 for FEAT_NV2
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-5-maz@kernel.org>

Add the HCR_EL2 configuration for FEAT_NV2, adding the required
bits for running a guest hypervisor, and overall merging the
allowed bits provided by the guest.

This heavily replies on unavaliable features being sanitised
when the HCR_EL2 shadow register is accessed, and only a couple
of bits must be explicitly disabled.

Non-NV guests are completely unaffected by any of this.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/sysreg.h         |  1 +
 arch/arm64/kvm/hyp/include/hyp/switch.h |  4 +--
 arch/arm64/kvm/hyp/nvhe/switch.c        |  2 +-
 arch/arm64/kvm/hyp/vhe/switch.c         | 34 ++++++++++++++++++++++++-
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 9e8999592f3a..a5361d9032a4 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -498,6 +498,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_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
 #define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index e3fcf8c4d5b4..f5f701f309a9 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -271,10 +271,8 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
 	__deactivate_traps_hfgxtr(vcpu);
 }
 
-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 c50f8459e4fc..4103625e46c5 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -40,7 +40,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 58415783fd53..29f59c374f7a 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -33,11 +33,43 @@ DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data);
 DEFINE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
 DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
 
+/*
+ * HCR_EL2 bits that the NV guest can freely change (no RES0/RES1
+ * semantics, irrespective of the configuration), but that cannot be
+ * applied to the actual HW as things would otherwise break badly.
+ *
+ * - TGE: we want to use EL1, which is incompatible with it being set
+ *
+ * - API/APK: for hysterical raisins, we enable PAuth lazily, which
+ *   means that the guest's bits cannot be directly applied (we really
+ *   want to see the traps). Revisit this at some point.
+ */
+#define NV_HCR_GUEST_EXCLUDE	(HCR_TGE | HCR_API | HCR_APK)
+
+static u64 __compute_hcr(struct kvm_vcpu *vcpu)
+{
+	u64 hcr = vcpu->arch.hcr_el2;
+
+	if (!vcpu_has_nv(vcpu))
+		return hcr;
+
+	if (is_hyp_ctxt(vcpu)) {
+		hcr |= HCR_NV | HCR_NV2 | HCR_AT | HCR_TTLB;
+
+		if (!vcpu_el2_e2h_is_set(vcpu))
+			hcr |= HCR_NV1;
+
+		write_sysreg_s(vcpu->arch.ctxt.vncr_array, SYS_VNCR_EL2);
+	}
+
+	return hcr | (__vcpu_sys_reg(vcpu, HCR_EL2) & ~NV_HCR_GUEST_EXCLUDE);
+}
+
 static void __activate_traps(struct kvm_vcpu *vcpu)
 {
 	u64 val;
 
-	___activate_traps(vcpu);
+	___activate_traps(vcpu, __compute_hcr(vcpu));
 
 	if (has_cntpoff()) {
 		struct timer_map map;
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:08 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:08 +0000
Subject: [PATCH 07/13] KVM: arm64: nv: Honor HFGITR_EL2.ERET being set
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-8-maz@kernel.org>

If the L1 hypervisor decides to trap ERETs while running L2,
make sure we don't try to emulate it, just like we wouldn't
if it had its NV bit set.

The exception will be reinjected from the core handler.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/vhe/switch.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 0c175516d114..a6c61d2ffc35 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -219,7 +219,8 @@ static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
 	 * Unless the trap has to be forwarded further down the line,
 	 * of course...
 	 */
-	if (__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_NV)
+	if ((__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_NV) ||
+	    (__vcpu_sys_reg(vcpu, HFGITR_EL2) & HFGITR_EL2_ERET))
 		return false;
 
 	spsr = read_sysreg_el1(SYS_SPSR);
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:11 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:11 +0000
Subject: [PATCH 10/13] KVM: arm64: nv: Add kvm_has_pauth() helper
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-11-maz@kernel.org>

Pointer Authentication comes in many flavors, and a faithful emulation
relies on correctly handling the flavour implemented by the HW.

For this, provide a new kvm_has_pauth() that checks whether we
expose to the guest a particular level of support. This checks
across all 3 possible authentication algorithms (Q5, Q3 and IMPDEF).

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 75eb8e170515..a97b092b7064 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1334,4 +1334,19 @@ bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
 	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
 	 get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
 
+/* Check for a given level of PAuth support */
+#define kvm_has_pauth(k, l)						\
+	({								\
+		bool pa, pi, pa3;					\
+									\
+		pa  = kvm_has_feat((k), ID_AA64ISAR1_EL1, APA, l);	\
+		pa &= kvm_has_feat((k), ID_AA64ISAR1_EL1, GPA, IMP);	\
+		pi  = kvm_has_feat((k), ID_AA64ISAR1_EL1, API, l);	\
+		pi &= kvm_has_feat((k), ID_AA64ISAR1_EL1, GPI, IMP);	\
+		pa3  = kvm_has_feat((k), ID_AA64ISAR2_EL1, APA3, l);	\
+		pa3 &= kvm_has_feat((k), ID_AA64ISAR2_EL1, GPA3, IMP);	\
+									\
+		(pa + pi + pa3) == 1;					\
+	})
+
 #endif /* __ARM64_KVM_HOST_H__ */
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:09 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:09 +0000
Subject: [PATCH 08/13] KVM: arm64: nv: Handle HCR_EL2.{API,APK} independantly
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-9-maz@kernel.org>

Although KVM couples API and APK for simplicity, the architecture
makes no such requirement, and the two can be independently set or
cleared.

Check for which of the two possible reasons we have trapped here,
and if the corresponding L1 control bit isn't set, delegate the
handling for forwarding.

Otherwise, set this exact bit in HCR_EL2 and resume the guest.
Of course, in the non-NV case, we keep setting both bits and
be done with it. Note that the entry core already saves/restores
the keys should any of the two control bits be set.

This result in a bit of rework, and the removal of the (trivial)
vcpu_ptrauth_enable() helper.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h    |  5 ----
 arch/arm64/kvm/hyp/include/hyp/switch.h | 32 +++++++++++++++++++++----
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index debc3753d2ef..d2177bc77844 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -125,11 +125,6 @@ static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu)
 	vcpu->arch.hcr_el2 |= HCR_TWI;
 }
 
-static inline void vcpu_ptrauth_enable(struct kvm_vcpu *vcpu)
-{
-	vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
-}
-
 static inline void vcpu_ptrauth_disable(struct kvm_vcpu *vcpu)
 {
 	vcpu->arch.hcr_el2 &= ~(HCR_API | HCR_APK);
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index f5f701f309a9..a0908d7a8f56 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -480,11 +480,35 @@ DECLARE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
 static bool kvm_hyp_handle_ptrauth(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	struct kvm_cpu_context *ctxt;
-	u64 val;
+	u64 enable = 0;
 
 	if (!vcpu_has_ptrauth(vcpu))
 		return false;
 
+	/*
+	 * NV requires us to handle API and APK independently, just in
+	 * case the hypervisor is totally nuts. Please barf >here<.
+	 */
+	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
+		switch (ESR_ELx_EC(kvm_vcpu_get_esr(vcpu))) {
+		case ESR_ELx_EC_PAC:
+			if (!(__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_API))
+				return false;
+
+			enable |= HCR_API;
+			break;
+
+		case ESR_ELx_EC_SYS64:
+			if (!(__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_APK))
+				return false;
+
+			enable |= HCR_APK;
+			break;
+		}
+	} else {
+		enable = HCR_API | HCR_APK;
+	}
+
 	ctxt = this_cpu_ptr(&kvm_hyp_ctxt);
 	__ptrauth_save_key(ctxt, APIA);
 	__ptrauth_save_key(ctxt, APIB);
@@ -492,11 +516,9 @@ static bool kvm_hyp_handle_ptrauth(struct kvm_vcpu *vcpu, u64 *exit_code)
 	__ptrauth_save_key(ctxt, APDB);
 	__ptrauth_save_key(ctxt, APGA);
 
-	vcpu_ptrauth_enable(vcpu);
 
-	val = read_sysreg(hcr_el2);
-	val |= (HCR_API | HCR_APK);
-	write_sysreg(val, hcr_el2);
+	vcpu->arch.hcr_el2 |= enable;
+	sysreg_clear_set(hcr_el2, 0, enable);
 
 	return true;
 }
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:10 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:10 +0000
Subject: [PATCH 09/13] KVM: arm64: nv: Reinject PAC exceptions caused by HCR_EL2.API==0
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-10-maz@kernel.org>

In order for a L1 hypervisor to correctly handle PAuth instructions,
it must observe traps caused by a L1 PAuth instruction when
HCR_EL2.API==0. Since we already handle the case for API==1 as
a fixup, only the exception injection case needs to be handled.

Rework the kvm_handle_ptrauth() callback to reinject the trap
in this case. Note that APK==0 is already handled by the exising
triage_sysreg_trap() helper.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/handle_exit.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 1ccdfe40c691..556af771a9e9 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -214,12 +214,34 @@ static int handle_sve(struct kvm_vcpu *vcpu)
 }
 
 /*
- * Guest usage of a ptrauth instruction (which the guest EL1 did not turn into
- * a NOP). If we get here, it is that we didn't fixup ptrauth on exit, and all
- * that we can do is give the guest an UNDEF.
+ * Two possibilities to handle a trapping ptrauth instruction:
+ *
+ * - Guest usage of a ptrauth instruction (which the guest EL1 did not
+ *   turn into a NOP). If we get here, it is that we didn't fixup
+ *   ptrauth on exit, and all that we can do is give the guest an
+ *   UNDEF (as the guest isn't supposed to use ptrauth without being
+ *   told it could).
+ *
+ * - Running an L2 NV guest while L1 has left HCR_EL2.API==0, and for
+ *   which we reinject the exception into L1. API==1 is handled as a
+ *   fixup so the only way to get here is when API==0.
+ *
+ * Anything else is an emulation bug (hence the WARN_ON + UNDEF).
  */
 static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
 {
+	if (!vcpu_has_ptrauth(vcpu)) {
+		kvm_inject_undefined(vcpu);
+		return 1;
+	}
+
+	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
+		kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+		return 1;
+	}
+
+	/* Really shouldn't be here! */
+	WARN_ON_ONCE(1);
 	kvm_inject_undefined(vcpu);
 	return 1;
 }
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:02 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:02 +0000
Subject: [PATCH 01/13] KVM: arm64: Harden __ctxt_sys_reg() against out-of-range values
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-2-maz@kernel.org>

The unsuspecting kernel tinkerer can be easily confused into
writing something that looks like this:

	ikey.lo = __vcpu_sys_reg(vcpu, SYS_APIAKEYLO_EL1);

which seems vaguely sensible, until you realise that the second
parameter is the encoding of a sysreg, and not the index into
the vcpu sysreg file... Debugging what happens in this case is
an interesting exercise in head<->wall interactions.

As they often say: "Any resemblance to actual persons, living
or dead, or actual events is purely coincidental".

In order to save people's time, add some compile-time hardening
that will at least weed out the "stupidly out of range" values.
This will *not* catch anything that isn't a compile-time constant.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 181fef12e8e8..a5ec4c7d3966 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -895,7 +895,7 @@ struct kvm_vcpu_arch {
  * Don't bother with VNCR-based accesses in the nVHE code, it has no
  * business dealing with NV.
  */
-static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
+static inline u64 *___ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
 {
 #if !defined (__KVM_NVHE_HYPERVISOR__)
 	if (unlikely(cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
@@ -905,6 +905,13 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
 	return (u64 *)&ctxt->sys_regs[r];
 }
 
+#define __ctxt_sys_reg(c,r)						\
+	({								\
+	    	BUILD_BUG_ON(__builtin_constant_p(r) &&			\
+			     (r) >= NR_SYS_REGS);			\
+		___ctxt_sys_reg(c, r);					\
+	})
+
 #define ctxt_sys_reg(c,r)	(*__ctxt_sys_reg(c,r))
 
 u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg);
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:07 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:07 +0000
Subject: [PATCH 06/13] KVM: arm64: nv: Fast-track 'InHost' exception returns
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-7-maz@kernel.org>

A significant part of the FEAT_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 | 44 +++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 2d80e81ae650..63a74c0330f1 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2172,8 +2172,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
@@ -2182,33 +2181,11 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
 	if (forward_traps(vcpu, HCR_NV))
 		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 29f59c374f7a..0c175516d114 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -205,6 +205,49 @@ void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu)
 	__vcpu_put_switch_sysregs(vcpu);
 }
 
+static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	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);
+	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,
@@ -215,6 +258,7 @@ static const exit_handler_fn hyp_exit_handlers[] = {
 	[ESR_ELx_EC_DABT_LOW]		= kvm_hyp_handle_dabt_low,
 	[ESR_ELx_EC_WATCHPT_LOW]	= kvm_hyp_handle_watchpt_low,
 	[ESR_ELx_EC_PAC]		= kvm_hyp_handle_ptrauth,
+	[ESR_ELx_EC_ERET]		= kvm_hyp_handle_eret,
 	[ESR_ELx_EC_MOPS]		= kvm_hyp_handle_mops,
 };
 
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:13 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:13 +0000
Subject: [PATCH 12/13] KVM: arm64: nv: Handle ERETA[AB] instructions
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-13-maz@kernel.org>

Now that we have some emulation in place for ERETA[AB], we can
plug it into the exception handling machinery.

As for a bare ERET, an "easy" ERETAx instruction is processed as
a fixup, while something that requires a translation regime
transition or an exception delivery is left to the slow path.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 22 ++++++++++++++++++++--
 arch/arm64/kvm/handle_exit.c    |  3 ++-
 arch/arm64/kvm/hyp/vhe/switch.c | 13 +++++++++++--
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 63a74c0330f1..6fc3b7580b24 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2172,7 +2172,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;
+	u64 spsr, elr, esr;
 
 	/*
 	 * Forward this trap to the virtual EL2 if the virtual
@@ -2181,12 +2181,30 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
 	if (forward_traps(vcpu, HCR_NV))
 		return;
 
+	/* Check for an ERETAx */
+	esr = kvm_vcpu_get_esr(vcpu);
+	if ((esr & ESR_ELx_ERET_ISS_ERETA) && !kvm_auth_eretax(vcpu, &elr)) {
+		/*
+		 * Oh no, ERETAx failed to authenticate.  If we have
+		 * FPACCOMBINE, deliver an exception right away.  If we
+		 * don't, then let the mangled ELR value trickle down the
+		 * ERET handling, and the guest will have a little surprise.
+		 */
+		if (kvm_has_pauth(vcpu->kvm, FPACCOMBINE)) {
+			esr &= ESR_ELx_ERET_ISS_ERETAB;
+			esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_FPAC);
+			kvm_inject_nested_sync(vcpu, esr);
+			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);
+	if (!(esr & ESR_ELx_ERET_ISS_ERETA))
+		elr = __vcpu_sys_reg(vcpu, ELR_EL2);
 
 	trace_kvm_nested_eret(vcpu, elr, spsr);
 
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 556af771a9e9..998838da7c32 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -248,7 +248,8 @@ static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
 
 static int kvm_handle_eret(struct kvm_vcpu *vcpu)
 {
-	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERETA)
+	if ((kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERETA) &&
+	    !vcpu_has_ptrauth(vcpu))
 		return kvm_handle_ptrauth(vcpu);
 
 	/*
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index a6c61d2ffc35..04592cd56e4b 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -207,7 +207,8 @@ void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu)
 
 static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
-	u64 spsr, mode;
+	u64 esr = kvm_vcpu_get_esr(vcpu);
+	u64 spsr, elr, mode;
 
 	/*
 	 * Going through the whole put/load motions is a waste of time
@@ -241,10 +242,18 @@ static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
 		return false;
 	}
 
+	/* If ERETAx fails, take the slow path */
+	if (esr & ESR_ELx_ERET_ISS_ERETA) {
+		if (!(vcpu_has_ptrauth(vcpu) && kvm_auth_eretax(vcpu, &elr)))
+			return false;
+	} else {
+		elr = read_sysreg_el1(SYS_ELR);
+	}
+
 	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);
+	write_sysreg_el2(elr, SYS_ELR);
 
 	return true;
 }
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:12 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:12 +0000
Subject: [PATCH 11/13] KVM: arm64: nv: Add emulation for ERETAx instructions
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-12-maz@kernel.org>

FEAT_NV has the interesting property of relying on ERET being
trapped. An added complexity is that it also traps ERETAA and
ERETAB, meaning that the Pointer Authentication aspect of these
instruction must be emulated.

Add an emulation of Pointer Authentication, limited to ERETAx
(always using SP_EL2 as the modifier and ELR_EL2 as the pointer),
using the Generic Authentication instructions.

The emulation, however small, is placed in its own compilation
unit so that it can be avoided if the configuration doesn't
include it (or the toolchan in not up to the task).

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h    |  12 ++
 arch/arm64/include/asm/pgtable-hwdef.h |   1 +
 arch/arm64/kvm/Makefile                |   1 +
 arch/arm64/kvm/pauth.c                 | 196 +++++++++++++++++++++++++
 4 files changed, 210 insertions(+)
 create mode 100644 arch/arm64/kvm/pauth.c

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index dbc4e3a67356..5e0ab0596246 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -64,4 +64,16 @@ extern bool forward_smc_trap(struct kvm_vcpu *vcpu);
 
 int kvm_init_nv_sysregs(struct kvm *kvm);
 
+#ifdef CONFIG_ARM64_PTR_AUTH
+bool kvm_auth_eretax(struct kvm_vcpu *vcpu, u64 *elr);
+#else
+static inline bool kvm_auth_eretax(struct kvm_vcpu *vcpu, u64 *elr)
+{
+	/* We really should never execute this... */
+	WARN_ON_ONCE(1);
+	*elr = 0xbad9acc0debadbad;
+	return false;
+}
+#endif
+
 #endif /* __ARM64_KVM_NESTED_H */
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index e4944d517c99..bb88e9ef6296 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -277,6 +277,7 @@
 #define TCR_TBI1		(UL(1) << 38)
 #define TCR_HA			(UL(1) << 39)
 #define TCR_HD			(UL(1) << 40)
+#define TCR_TBID0		(UL(1) << 51)
 #define TCR_TBID1		(UL(1) << 52)
 #define TCR_NFD0		(UL(1) << 53)
 #define TCR_NFD1		(UL(1) << 54)
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index c0c050e53157..04882b577575 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -23,6 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 vgic/vgic-its.o vgic/vgic-debug.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
+kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
 
 always-y := hyp_constants.h hyp-constants.s
 
diff --git a/arch/arm64/kvm/pauth.c b/arch/arm64/kvm/pauth.c
new file mode 100644
index 000000000000..33ef0a26eb35
--- /dev/null
+++ b/arch/arm64/kvm/pauth.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 - Google LLC
+ * Author: Marc Zyngier <maz at kernel.org>
+ *
+ * Primitive PAuth emulation for ERETAA/ERETAB.
+ *
+ * This code assumes that is is run from EL2, and that it is part of
+ * the emulation of ERETAx for a guest hypervisor. That's a lot of
+ * baked-in assumptions and shortcuts.
+ *
+ * Do no reuse for anything else!
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_emulate.h>
+#include <asm/pointer_auth.h>
+
+static u64 compute_pac(struct kvm_vcpu *vcpu, u64 ptr,
+		       struct ptrauth_key ikey)
+{
+	struct ptrauth_key gkey;
+	u64 mod, pac = 0;
+
+	preempt_disable();
+
+	if (!vcpu_get_flag(vcpu, SYSREGS_ON_CPU))
+		mod = __vcpu_sys_reg(vcpu, SP_EL2);
+	else
+		mod = read_sysreg(sp_el1);
+
+	gkey.lo = read_sysreg_s(SYS_APGAKEYLO_EL1);
+	gkey.hi = read_sysreg_s(SYS_APGAKEYHI_EL1);
+
+	__ptrauth_key_install_nosync(APGA, ikey);
+	isb();
+
+	asm volatile(ARM64_ASM_PREAMBLE ".arch_extension pauth\n"
+		     "pacga %0, %1, %2" : "=r" (pac) : "r" (ptr), "r" (mod));
+	isb();
+
+	__ptrauth_key_install_nosync(APGA, gkey);
+
+	preempt_enable();
+
+	/* PAC in the top 32bits */
+	return pac;
+}
+
+static bool effective_tbi(struct kvm_vcpu *vcpu, bool bit55)
+{
+	u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
+	bool tbi, tbid;
+
+	/*
+	 * Since we are authenticating an instruction address, we have
+	 * to take TBID into account. If E2H==0, ignore VA[55], as
+	 * TCR_EL2 only has a single TBI/TBID. If VA[55] was set in
+	 * this case, this is likely a guest bug...
+	 */
+	if (!vcpu_el2_e2h_is_set(vcpu)) {
+		tbi = tcr & BIT(20);
+		tbid = tcr & BIT(29);
+	} else if (bit55) {
+		tbi = tcr & TCR_TBI1;
+		tbid = tcr & TCR_TBID1;
+	} else {
+		tbi = tcr & TCR_TBI0;
+		tbid = tcr & TCR_TBID0;
+	}
+
+	return tbi && !tbid;
+}
+
+static int compute_bottom_pac(struct kvm_vcpu *vcpu, bool bit55)
+{
+	static const int maxtxsz = 39; // Revisit these two values once
+	static const int mintxsz = 16; // (if) we support TTST/LVA/LVA2
+	u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
+	int txsz;
+
+	if (!vcpu_el2_e2h_is_set(vcpu) || !bit55)
+		txsz = FIELD_GET(TCR_T0SZ_MASK, tcr);
+	else
+		txsz = FIELD_GET(TCR_T1SZ_MASK, tcr);
+
+	return 64 - clamp(txsz, mintxsz, maxtxsz);
+}
+
+static u64 compute_pac_mask(struct kvm_vcpu *vcpu, bool bit55)
+{
+	int bottom_pac;
+	u64 mask;
+
+	bottom_pac = compute_bottom_pac(vcpu, bit55);
+
+	mask = GENMASK(54, bottom_pac);
+	if (!effective_tbi(vcpu, bit55))
+		mask |= GENMASK(63, 56);
+
+	return mask;
+}
+
+static u64 to_canonical_addr(struct kvm_vcpu *vcpu, u64 ptr, u64 mask)
+{
+	bool bit55 = !!(ptr & BIT(55));
+
+	if (bit55)
+		return ptr | mask;
+
+	return ptr & ~mask;
+}
+
+static u64 corrupt_addr(struct kvm_vcpu *vcpu, u64 ptr)
+{
+	bool bit55 = !!(ptr & BIT(55));
+	u64 mask, error_code;
+	int shift;
+
+	if (effective_tbi(vcpu, bit55)) {
+		mask = GENMASK(54, 53);
+		shift = 53;
+	} else {
+		mask = GENMASK(62, 61);
+		shift = 61;
+	}
+
+	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERETAB)
+		error_code = 2 << shift;
+	else
+		error_code = 1 << shift;
+
+	ptr &= ~mask;
+	ptr |= error_code;
+
+	return ptr;
+}
+
+/*
+ * Authenticate an ERETAA/ERETAB instruction, returning true if the
+ * authentication succeeded and false otherwise. In all cases, *elr
+ * contains the VA to ERET to. Potential exception injection is left
+ * to the caller.
+ */
+bool kvm_auth_eretax(struct kvm_vcpu *vcpu, u64 *elr)
+{
+	u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL2);
+	u64 esr = kvm_vcpu_get_esr(vcpu);
+	u64 ptr, cptr, pac, mask;
+	struct ptrauth_key ikey;
+
+	*elr = ptr = vcpu_read_sys_reg(vcpu, ELR_EL2);
+
+	/* We assume we're already in the context of an ERETAx */
+	if (esr & ESR_ELx_ERET_ISS_ERETAB ) {
+		if (!(sctlr & SCTLR_EL1_EnIB))
+			return true;
+
+		ikey.lo = __vcpu_sys_reg(vcpu, APIBKEYLO_EL1);
+		ikey.hi = __vcpu_sys_reg(vcpu, APIBKEYHI_EL1);
+	} else {
+		if (!(sctlr & SCTLR_EL1_EnIA))
+			return true;
+
+		ikey.lo = __vcpu_sys_reg(vcpu, APIAKEYLO_EL1);
+		ikey.hi = __vcpu_sys_reg(vcpu, APIAKEYHI_EL1);
+	}
+
+	mask = compute_pac_mask(vcpu, !!(ptr & BIT(55)));
+	cptr = to_canonical_addr(vcpu, ptr, mask);
+
+	pac = compute_pac(vcpu, cptr, ikey);
+
+	/*
+	 * Slightly deviate from the pseudocode: if we have a PAC
+	 * match with the signed pointer, then it must be good.
+	 * Anything after this point is pure error handling.
+	 */
+	if ((pac & mask) == (ptr & mask)) {
+		*elr = cptr;
+		return true;
+	}
+
+	/*
+	 * Authentication failed, corrupt the canonical address if
+	 * PAuth2 isn't implemented, or some XORing if it is.
+	 */
+	if (!kvm_has_pauth(vcpu->kvm, PAuth2))
+		cptr = corrupt_addr(vcpu, cptr);
+	else
+		cptr = ptr ^ (pac & mask);
+
+	*elr = cptr;
+	return false;
+}
-- 
2.39.2



From maz at kernel.org  Mon Feb 19 01:20:14 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:20:14 +0000
Subject: [PATCH 13/13] KVM: arm64: nv: Advertise support for PAuth
In-Reply-To: <20240219092014.783809-1-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
Message-ID: <20240219092014.783809-14-maz@kernel.org>

Now that we (hopefully) correctly handle ERETAx, drop the masking
of the PAuth feature (something that was not even complete, as
APA3 and AGA3 were still exposed).

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/nested.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index ced30c90521a..6813c7c7f00a 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -35,13 +35,9 @@ static u64 limit_nv_id_reg(u32 id, u64 val)
 		break;
 
 	case SYS_ID_AA64ISAR1_EL1:
-		/* Support everything but PtrAuth and Spec Invalidation */
+		/* Support everything but Spec Invalidation */
 		val &= ~(GENMASK_ULL(63, 56)	|
-			 NV_FTR(ISAR1, SPECRES)	|
-			 NV_FTR(ISAR1, GPI)	|
-			 NV_FTR(ISAR1, GPA)	|
-			 NV_FTR(ISAR1, API)	|
-			 NV_FTR(ISAR1, APA));
+			 NV_FTR(ISAR1, SPECRES));
 		break;
 
 	case SYS_ID_AA64PFR0_EL1:
-- 
2.39.2



From dmitry.baryshkov at linaro.org  Mon Feb 19 01:22:18 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 11:22:18 +0200
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org>
References: <20240216203215.40870-1-brgl@bgdev.pl> <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org>
Message-ID: <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>

On Mon, 19 Feb 2024 at 10:14, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>
> On 18/02/2024 13:53, Dmitry Baryshkov wrote:
> > On Fri, 16 Feb 2024 at 22:33, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> >>
> >> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >>
> >> First, I'd like to apologize for the somewhat chaotic previous iterations
> >> of this series and improper versioning which was rightfully pointed out
> >> to me. I figured that the scope changed so much that it didn't make sense
> >> to consider previous submissions part of the same series as the original
> >> RFC but others thought otherwise so this one becomes v5 and I'll keep the
> >> versioning going forward.
> >>
> >> This is the summary of the work so far:
> >>
> >> v1: Original RFC:
> >>
> >> https://lore.kernel.org/lkml/20240104130123.37115-1-brgl at bgdev.pl/T/
> >>
> >> v2: First real patch series (should have been PATCH v2) adding what I
> >>      referred to back then as PCI power sequencing:
> >>
> >> https://lore.kernel.org/linux-arm-kernel/2024021413-grumbling-unlivable-c145 at gregkh/T/
> >>
> >> v3: RFC for the DT representation of the PMU supplying the WLAN and BT
> >>      modules inside the QCA6391 package (was largely separate from the
> >>      series but probably should have been called PATCH or RFC v3):
> >>
> >> https://lore.kernel.org/all/CAMRc=Mc+GNoi57eTQg71DXkQKjdaoAmCpB=h2ndEpGnmdhVV-Q at mail.gmail.com/T/
> >>
> >> v4: Second attempt at the full series with changed scope (introduction of
> >>      the pwrseq subsystem, should have been RFC v4)
> >>
> >> https://lore.kernel.org/lkml/20240201155532.49707-1-brgl at bgdev.pl/T/
> >>
> >> ===
> >>
> >> With that out of the way, I'd like to get down to explaining the two
> >> problems I'm trying to solve.
> >>
> >> Problem statement #1: Dynamic bus chicken-and-egg problem.
> >>
> >> Certain on-board PCI devices need to be powered up before they are can be
> >> detected but their PCI drivers won't get bound until the device is
> >> powered-up so enabling the relevant resources in the PCI device driver
> >> itself is impossible.
> >>
> >> Problem statement #2: Sharing inter-dependent resources between devices.
> >>
> >> Certain devices that use separate drivers (often on different busses)
> >> share resources (regulators, clocks, etc.). Typically these resources
> >> are reference-counted but in some cases there are additional interactions
> >> between them to consider, for example specific power-up sequence timings.
> >>
> >> ===
> >>
> >> The reason for tackling both of these problems in a single series is the
> >> fact the the platform I'm working on - Qualcomm RB5 - deals with both and
> >> both need to be addressed in order to enable WLAN and Bluetooth support
> >> upstream.
> >>
> >> The on-board WLAN/BT package - QCA6391 - has a Power Management Unit that
> >> takes inputs from the host and exposes LDO outputs consumed by the BT and
> >> WLAN modules which can be powered-up and down independently. However
> >> a delay of 100ms must be respected between enabling the BT- and
> >> WLAN-enable GPIOs[*].
> >>
> >> ===
> >>
> >> This series is logically split into several sections. I'll go
> >> patch-by-patch and explain each step.
> >>
> >> Patch 1/18:
> >>
> >> This is a commit taken from the list by Jonathan Cameron that adds
> >> a __free() helper for OF nodes. Not strictly related to the series but
> >> until said commit ends in next, I need to carry it with this series.
> >>
> >> Patch 2/18:
> >>
> >> This enables the ath12k PCI module in arm64 defconfig as Qualcomm sm8650
> >> and sm8550 reference platforms use it in the WCN7850 module.
> >>
> >> Patches 3/18-6/18:
> >>
> >> These contain all relevant DT bindings changes. We add new documents for
> >> the QCA6390 PMU and ATH12K devices as well as extend the bindings for the
> >> Qualcomm Bluetooth and ATH11K modules with regulators used by them in
> >> QCA6390.
> >>
> >> Patches 7/18-9/18:
> >>
> >> These contain changes to device-tree sources for the three platforms we
> >> work with in this series. As the WCN7850 module doesn't require any
> >> specific timings introducing dependencies between the Bluetooth and WLAN
> >> modules, while the QCA6390 does, we take two different approaches to how
> >> me model them in DT.
> >>
> >> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> >> necessary. The BT and WLAN devices on the device-tree are represented as
> >> consuming the inputs (relevant to the functionality of each) of the PMU
> >> directly.
> >
> > We are describing the hardware. From the hardware point of view, there
> > is a PMU. I think at some point we would really like to describe all
> > Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> > older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
>
> While I agree with older WiFi+BT units, I don't think it's needed for
> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
> transparent.

I don't see any significant difference between WCN6750/WCN6855 and
WCN7850 from the PMU / power up point of view. Could you please point
me to the difference?

-- 
With best wishes
Dmitry


From mo.c.weber at gmail.com  Mon Feb 19 01:22:40 2024
From: mo.c.weber at gmail.com (Moritz Christian Weber)
Date: Mon, 19 Feb 2024 10:22:40 +0100
Subject: [PATCH v2 0/8] Staging: vc04_services: bcm2835-camera: Fix code
 style checks
In-Reply-To: <236d985c-1835-410f-b0b5-cacbd5fbf930@moroto.mountain>
References: <20240217211246.28882-1-mo.c.weber@gmail.com> <510574c4-ad26-4fc2-93c4-7b67737f8eb1@moroto.mountain>
 <236d985c-1835-410f-b0b5-cacbd5fbf930@moroto.mountain>
Message-ID: <CAMn1LHB2H6hqMZLOWrQEN-hRQf3LTRU_q-6ggu4=qRDiU5=inw@mail.gmail.com>

Ok.. thanks for the explanation. Did not want to ask back stupidly
what the script was actually complaining about without providing a
suggestion on what I understood what it was asking for. I will submit
a version 3 patch for the braces and a separate blank line patch with
both good cover letters.

Best regards,
Moritz

On Mon, Feb 19, 2024 at 9:17?AM Dan Carpenter <dan.carpenter at linaro.org> wrote:
>
> On Mon, Feb 19, 2024 at 10:38:30AM +0300, Dan Carpenter wrote:
> > On Sat, Feb 17, 2024 at 10:12:38PM +0100, Moritz C. Weber wrote:
> > > Resubmit these patches to fix multiple code style checks for better readability, consistency, and to address errors indicated by Gregs patch bot
> > >
> > > Moritz C. Weber (8):
> > >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> > >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> > >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> > >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> > >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> > >   Staging: vc04_services: bcm2835-camera: fix blank line style check
>
> This blank line patch would be still separate of course.
>
> > >   Staging: vc04_services: bcm2835-camera: fix brace code style check
> > >   Staging: vc04_services: bcm2835-camera: fix brace code style check
>
> regards,
> dan carpenter
>


From angelogioacchino.delregno at collabora.com  Mon Feb 19 01:23:49 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 10:23:49 +0100
Subject: [PATCH v2 1/2] dt-bindings: arm64: mediatek: add Kontron
 3.5"-SBC-i1200
In-Reply-To: <20240219084456.1075445-1-mwalle@kernel.org>
References: <20240219084456.1075445-1-mwalle@kernel.org>
Message-ID: <ed3530f0-227a-47f2-938c-28eba90dd6eb@collabora.com>

Il 19/02/24 09:44, Michael Walle ha scritto:
> Add the compatible string for the Kontron 3.5"-SBC-i1200 single board
> computer.
> 
> Signed-off-by: Michael Walle <mwalle at kernel.org>
> ---
> v2:
>   - convert enum to const as there is only one specific board
> 
>   Documentation/devicetree/bindings/arm/mediatek.yaml | 5 +++++
>   1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
> index 09f9ffd3ff7b..add167d8b8da 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
> @@ -357,6 +357,11 @@ properties:
>                 - radxa,nio-12l
>             - const: mediatek,mt8395
>             - const: mediatek,mt8195
> +      - description: Kontron 3.5"-SBC-i1200
> +        items:
> +          - const: kontron,3-5-sbc-i1200
> +          - const: mediatek,mt8395
> +          - const: mediatek,mt8195
>         - items:
>             - enum:
>                 - mediatek,mt8516-pumpkin

I understand that you took inspiration from the Google Chromebooks entries, but
those are separated only because they've got "a bunch of revisions".

For machines that don't have a billion compatible strings, I would suggest to
add the compatible under a single big entry: like this, the binding is (imo) a
bit more readable .. and cleaner.

Eventually, the machine name is in the devicetree so we're not losing any kind
of information anyway... :-)

       - items:
           - enum:
               - kontron,3-5-sbc-i1200
               - mediatek,mt8395-evk
               - radxa,nio-12l
           - const: mediatek,mt8395
           - const: mediatek,mt8195

Cheers,
Angelo


From mwalle at kernel.org  Mon Feb 19 01:25:31 2024
From: mwalle at kernel.org (Michael Walle)
Date: Mon, 19 Feb 2024 10:25:31 +0100
Subject: [PATCH v2 1/2] dt-bindings: arm64: mediatek: add Kontron
 3.5"-SBC-i1200
In-Reply-To: <72fffc25-33f0-4394-b7c1-8dbc2d23a4a4@linaro.org>
References: <20240219084456.1075445-1-mwalle@kernel.org>
 <72fffc25-33f0-4394-b7c1-8dbc2d23a4a4@linaro.org>
Message-ID: <CZ8Y4DFQNLM9.3GIGATDIAXBR5@kernel.org>

On Mon Feb 19, 2024 at 10:06 AM CET, Krzysztof Kozlowski wrote:
> On 19/02/2024 09:44, Michael Walle wrote:
> > Add the compatible string for the Kontron 3.5"-SBC-i1200 single board
> > computer.
> > 
> > Signed-off-by: Michael Walle <mwalle at kernel.org>
> > ---
> > v2:
> >  - convert enum to const as there is only one specific board
> > 
> >  Documentation/devicetree/bindings/arm/mediatek.yaml | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
> > index 09f9ffd3ff7b..add167d8b8da 100644
> > --- a/Documentation/devicetree/bindings/arm/mediatek.yaml
> > +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
> > @@ -357,6 +357,11 @@ properties:
> >                - radxa,nio-12l
> >            - const: mediatek,mt8395
> >            - const: mediatek,mt8195
> > +      - description: Kontron 3.5"-SBC-i1200
> > +        items:
> > +          - const: kontron,3-5-sbc-i1200
>
> And then it should be part of earlier entry. Just take a look there in
> the file...

FWIW I did and all the entries with descriptions are by there own
(that's also true for fsl.yaml and sunxi.yaml).

mediatek.yaml seems to have both, either boards without description
like the "radxa,nio-12l" which you are probably referring to. Or
boards which has the same sub compatibles but still have individual
entries, like google,burnet, google,cozmo, google,damu.

Therefore, what is the rule of thumb here? Drop the description?
If so, why it it there in the first place?

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

From linux at armlinux.org.uk  Mon Feb 19 01:26:51 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 19 Feb 2024 09:26:51 +0000
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
Message-ID: <ZdMe24xN1Ej4QoVU@shell.armlinux.org.uk>

On Mon, Feb 19, 2024 at 07:21:11AM +0100, Arnd Bergmann wrote:
> I think these should be addressed in bcachefs instead.
> While it's not the fault of bcachefs that the calling
> convention changed between gcc versions, have a look at
> the actual structure layout:
> 
> struct bch_val {
>         __u64           __nothing[0];
> };
> struct bpos {
>         /*
>          * Word order matches machine byte order - btree code treats a bpos as a
>          * single large integer, for search/comparison purposes
>          *
>          * Note that wherever a bpos is embedded in another on disk data
>          * structure, it has to be byte swabbed when reading in metadata that
>          * wasn't written in native endian order:
>          */
> #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
>         __u32           snapshot;
>         __u64           offset;
>         __u64           inode;
> #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
>         __u64           inode;
>         __u64           offset;         /* Points to end of extent - sectors */
>         __u32           snapshot;
> #else
> #error edit for your odd byteorder.
> #endif
> } __packed
> struct bch_backpointer {
>         struct bch_val          v;
>         __u8                    btree_id;
>         __u8                    level;
>         __u8                    data_type;
>         __u64                   bucket_offset:40;
>         __u32                   bucket_len;
>         struct bpos             pos;
> } __packed __aligned(8);
> 
> This is not something that should ever be passed by value
> into a function.

+1 - bcachefs definitely needs fixing. Passing all that as an argument
not only means that it has to be read into registers, but also when
accessing members, it has to be extracted from those registers as well.

Passing that by argument is utterly insane.

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


From quic_mkshah at quicinc.com  Mon Feb 19 01:32:04 2024
From: quic_mkshah at quicinc.com (Maulik Shah)
Date: Mon, 19 Feb 2024 15:02:04 +0530
Subject: [PATCH] firmware/psci: Move psci_init_system_suspend() to
 late_initcall()
Message-ID: <20240219-suspend_ops_late_init-v1-1-6330ca9597fa@quicinc.com>

psci_init_system_suspend() invokes suspend_set_ops() very early during
bootup even before kernel command line for mem_sleep_default is setup.
This leads to kernel command line mem_sleep_default=s2idle not working
as mem_sleep_current gets changed to deep via suspend_set_ops() and never
changes back to s2idle.

Move psci_init_system_suspend() to late_initcall() to make sure kernel
command line mem_sleep_default=s2idle sets up s2idle as default suspend
mode.

Fixes: faf7ec4a92c0 ("drivers: firmware: psci: add system suspend support")
CC: stable at vger.kernel.org # 5.15+
Signed-off-by: Maulik Shah <quic_mkshah at quicinc.com>
---
 drivers/firmware/psci/psci.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index d9629ff87861..655a2db70a67 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -523,18 +523,26 @@ static void __init psci_init_system_reset2(void)
 		psci_system_reset2_supported = true;
 }
 
-static void __init psci_init_system_suspend(void)
+static int __init psci_init_system_suspend(void)
 {
 	int ret;
+	u32 ver;
 
 	if (!IS_ENABLED(CONFIG_SUSPEND))
-		return;
+		return 0;
+
+	ver = psci_0_2_get_version();
+	if (PSCI_VERSION_MAJOR(ver) < 1)
+		return 0;
 
 	ret = psci_features(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND));
 
 	if (ret != PSCI_RET_NOT_SUPPORTED)
 		suspend_set_ops(&psci_suspend_ops);
+
+	return ret;
 }
+late_initcall(psci_init_system_suspend)
 
 static void __init psci_init_cpu_suspend(void)
 {
@@ -651,7 +659,6 @@ static int __init psci_probe(void)
 	if (PSCI_VERSION_MAJOR(ver) >= 1) {
 		psci_init_smccc();
 		psci_init_cpu_suspend();
-		psci_init_system_suspend();
 		psci_init_system_reset2();
 		kvm_init_hyp_services();
 	}

---
base-commit: d37e1e4c52bc60578969f391fb81f947c3e83118
change-id: 20240219-suspend_ops_late_init-27fb0b15baee

Best regards,
-- 
Maulik Shah <quic_mkshah at quicinc.com>



From apatel at ventanamicro.com  Mon Feb 19 01:35:27 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 19 Feb 2024 15:05:27 +0530
Subject: [PATCH v12 22/25] irqchip: Add RISC-V advanced PLIC driver for direct-mode
In-Reply-To: <875xyocewt.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-23-apatel@ventanamicro.com> <875xyocewt.ffs@tglx>
Message-ID: <CAK9=C2UO4=H9jPXFjJhS5b9kPezVutto1aReAmH3rU_uUhf9=g@mail.gmail.com>

On Sat, Feb 17, 2024 at 2:20?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> > +static int aplic_direct_irqdomain_translate(struct irq_domain *d,
> > +                                      struct irq_fwspec *fwspec,
> > +                                      unsigned long *hwirq,
> > +                                      unsigned int *type)
>
> Please align the arguments to the first argument of the first line and
> use the 100 characters, i.e.
>
> static int aplic_direct_irqdomain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
>                                             unsigned long *hwirq, unsigned int *type)
> {
>
> All over the place.

Okay, I will update.

>
> > +{
> > +     struct aplic_priv *priv = d->host_data;
> > +
> > +     return aplic_irqdomain_translate(fwspec, priv->gsi_base,
> > +                                      hwirq, type);
> > +}
> > +
> > +static int aplic_direct_irqdomain_alloc(struct irq_domain *domain,
> > +                                  unsigned int virq, unsigned int nr_irqs,
> > +                                  void *arg)
> > +{
> > +     int i, ret;
> > +     unsigned int type;
> > +     irq_hw_number_t hwirq;
> > +     struct irq_fwspec *fwspec = arg;
> > +     struct aplic_priv *priv = domain->host_data;
> > +     struct aplic_direct *direct =
> > +                     container_of(priv, struct aplic_direct, priv);
>
> Variable ordering. Please make this consistent according to documentation.

Okay, I will update.

>
> > +     ret = aplic_irqdomain_translate(fwspec, priv->gsi_base,
> > +                                     &hwirq, &type);
> > +     if (ret)
> > +             return ret;
> > +
> > +     for (i = 0; i < nr_irqs; i++) {
> > +             irq_domain_set_info(domain, virq + i, hwirq + i,
> > +                                 &aplic_direct_chip, priv,
> > +                                 handle_fasteoi_irq, NULL, NULL);
> > +             irq_set_affinity(virq + i, &direct->lmask);
> > +             /* See the reason described in aplic_msi_irqdomain_alloc() */
>
> I still have to understand that "reason". :)

Like mentioned on another patch, I will drop it for now. If required
then we can bring it back as a separate patch with clear reasoning.

>
> > +             irq_set_status_flags(virq + i, IRQ_DISABLE_UNLAZY);
> > +     }
>
> Thanks,
>
>         tglx

Regards,
Anup


From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb 19 01:36:13 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Mon, 19 Feb 2024 12:36:13 +0300
Subject: [PATCH 1/2] arm64: dts: mt7622: add port@5 as CPU port
In-Reply-To: <20240219-for-mediatek-v1-0-7078f23eab82@arinc9.com>
References: <20240219-for-mediatek-v1-0-7078f23eab82@arinc9.com>
Message-ID: <20240219-for-mediatek-v1-1-7078f23eab82@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

On Banana Pi BPI-R64 and MediaTek MT7622 RFB1 board, port 5 of the MT7531
switch is connected to the second MAC of the SoC as a CPU port. Add the
port and set up the second MAC on the bindings.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 .../boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts  | 12 +++++++++++
 arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts       | 24 ++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
index 850b3e277368..224bb289660c 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -186,6 +186,18 @@ port at 4 {
 					label = "lan3";
 				};
 
+				port at 5 {
+					reg = <5>;
+					ethernet = <&gmac1>;
+					phy-mode = "rgmii";
+
+					fixed-link {
+						speed = <1000>;
+						full-duplex;
+						pause;
+					};
+				};
+
 				port at 6 {
 					reg = <6>;
 					label = "cpu";
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
index 5c26021fc4cf..41629769bdc8 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -118,6 +118,18 @@ fixed-link {
 		};
 	};
 
+	gmac1: mac at 1 {
+		compatible = "mediatek,eth-mac";
+		reg = <1>;
+		phy-mode = "rgmii";
+
+		fixed-link {
+			speed = <1000>;
+			full-duplex;
+			pause;
+		};
+	};
+
 	mdio-bus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -156,6 +168,18 @@ port at 4 {
 					label = "wan";
 				};
 
+				port at 5 {
+					reg = <5>;
+					ethernet = <&gmac1>;
+					phy-mode = "rgmii";
+
+					fixed-link {
+						speed = <1000>;
+						full-duplex;
+						pause;
+					};
+				};
+
 				port at 6 {
 					reg = <6>;
 					label = "cpu";

-- 
2.40.1



From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb 19 01:36:12 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Mon, 19 Feb 2024 12:36:12 +0300
Subject: [PATCH 0/2] Add port@5 as CPU port on certain MT7622 and MT7986
 boards
Message-ID: <20240219-for-mediatek-v1-0-7078f23eab82@arinc9.com>

Hi.

This patch series adds port at 5 as CPU port on certain MT7622 and MT7986
boards.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
Ar?n? ?NAL (2):
      arm64: dts: mt7622: add port at 5 as CPU port
      arm64: dts: mt7986: add port at 5 as CPU port

 .../boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts  | 12 +++++++++++
 arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts       | 24 ++++++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts       | 24 ++++++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts       | 24 ++++++++++++++++++++++
 4 files changed, 84 insertions(+)
---
base-commit: 5b6df373ec95cf051264f655be0dbe1d6caa173c
change-id: 20240219-for-mediatek-699a100bed94

Best regards,
-- 
Ar?n? ?NAL <arinc.unal at arinc9.com>



From devnull+arinc.unal.arinc9.com at kernel.org  Mon Feb 19 01:36:14 2024
From: devnull+arinc.unal.arinc9.com at kernel.org (=?utf-8?b?QXLEsW7DpyDDnE5BTA==?= via B4 Relay)
Date: Mon, 19 Feb 2024 12:36:14 +0300
Subject: [PATCH 2/2] arm64: dts: mt7986: add port@5 as CPU port
In-Reply-To: <20240219-for-mediatek-v1-0-7078f23eab82@arinc9.com>
References: <20240219-for-mediatek-v1-0-7078f23eab82@arinc9.com>
Message-ID: <20240219-for-mediatek-v1-2-7078f23eab82@arinc9.com>

From: Ar?n? ?NAL <arinc.unal at arinc9.com>

On MediaTek MT7986b RFB and MediaTek MT7986a RFB, port 5 of the MT7531
switch is connected to the second MAC of the SoC as a CPU port. Add the
port and set up the second MAC on the bindings.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
---
 arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 24 ++++++++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 24 ++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
index 2f884c24f1eb..5d8e3d3f6c20 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
@@ -65,6 +65,18 @@ fixed-link {
 		};
 	};
 
+	gmac1: mac at 1 {
+		compatible = "mediatek,eth-mac";
+		reg = <1>;
+		phy-mode = "rgmii";
+
+		fixed-link {
+			speed = <1000>;
+			full-duplex;
+			pause;
+		};
+	};
+
 	mdio: mdio-bus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -288,6 +300,18 @@ port at 4 {
 			label = "lan4";
 		};
 
+		port at 5 {
+			reg = <5>;
+			ethernet = <&gmac1>;
+			phy-mode = "rgmii";
+
+			fixed-link {
+				speed = <1000>;
+				full-duplex;
+				pause;
+			};
+		};
+
 		port at 6 {
 			reg = <6>;
 			label = "cpu";
diff --git a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
index 57dcaeef31d7..58f77d932429 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
@@ -45,6 +45,18 @@ fixed-link {
 		};
 	};
 
+	gmac1: mac at 1 {
+		compatible = "mediatek,eth-mac";
+		reg = <1>;
+		phy-mode = "rgmii";
+
+		fixed-link {
+			speed = <1000>;
+			full-duplex;
+			pause;
+		};
+	};
+
 	mdio: mdio-bus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -83,6 +95,18 @@ port at 4 {
 					label = "lan4";
 				};
 
+				port at 5 {
+					reg = <5>;
+					ethernet = <&gmac1>;
+					phy-mode = "rgmii";
+
+					fixed-link {
+						speed = <1000>;
+						full-duplex;
+						pause;
+					};
+				};
+
 				port at 6 {
 					reg = <6>;
 					label = "cpu";

-- 
2.40.1



From mwalle at kernel.org  Mon Feb 19 01:36:26 2024
From: mwalle at kernel.org (Michael Walle)
Date: Mon, 19 Feb 2024 10:36:26 +0100
Subject: [PATCH v2 1/2] dt-bindings: arm64: mediatek: add Kontron
 3.5"-SBC-i1200
In-Reply-To: <ed3530f0-227a-47f2-938c-28eba90dd6eb@collabora.com>
References: <20240219084456.1075445-1-mwalle@kernel.org>
 <ed3530f0-227a-47f2-938c-28eba90dd6eb@collabora.com>
Message-ID: <CZ8YCQETS7LL.1BLJJZNCLV7DT@kernel.org>

On Mon Feb 19, 2024 at 10:23 AM CET, AngeloGioacchino Del Regno wrote:
> Il 19/02/24 09:44, Michael Walle ha scritto:
> > Add the compatible string for the Kontron 3.5"-SBC-i1200 single board
> > computer.
> > 
> > Signed-off-by: Michael Walle <mwalle at kernel.org>
> > ---
> > v2:
> >   - convert enum to const as there is only one specific board
> > 
> >   Documentation/devicetree/bindings/arm/mediatek.yaml | 5 +++++
> >   1 file changed, 5 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
> > index 09f9ffd3ff7b..add167d8b8da 100644
> > --- a/Documentation/devicetree/bindings/arm/mediatek.yaml
> > +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
> > @@ -357,6 +357,11 @@ properties:
> >                 - radxa,nio-12l
> >             - const: mediatek,mt8395
> >             - const: mediatek,mt8195
> > +      - description: Kontron 3.5"-SBC-i1200
> > +        items:
> > +          - const: kontron,3-5-sbc-i1200
> > +          - const: mediatek,mt8395
> > +          - const: mediatek,mt8195
> >         - items:
> >             - enum:
> >                 - mediatek,mt8516-pumpkin
>
> I understand that you took inspiration from the Google Chromebooks entries, but
> those are separated only because they've got "a bunch of revisions".
>

I don't really care about the description. It's just the way I've
done it in the past. And in this file, there is also google,burnet,
google,cozmo, google,damu, without any further revs.

> For machines that don't have a billion compatible strings, I would suggest to
> add the compatible under a single big entry: like this, the binding is (imo) a
> bit more readable .. and cleaner.
>
> Eventually, the machine name is in the devicetree so we're not losing any kind
> of information anyway... :-)
>
>        - items:
>            - enum:
>                - kontron,3-5-sbc-i1200
>                - mediatek,mt8395-evk
>                - radxa,nio-12l
>            - const: mediatek,mt8395
>            - const: mediatek,mt8195

Ack. I'll give you some time to look at the actual DTS before
posting a new version.

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

From arinc.unal at arinc9.com  Mon Feb 19 01:38:05 2024
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Mon, 19 Feb 2024 12:38:05 +0300
Subject: [PATCH] arm64: dts: {mt7622,mt7986}: add port@5 as CPU port
In-Reply-To: <2795a056-eac2-491b-bcb5-52bf4a331c07@collabora.com>
References: <20230918074938.79796-1-arinc.unal@arinc9.com>
 <5d582382-9a31-4a95-bc81-01d99dde0a6e@arinc9.com>
 <2795a056-eac2-491b-bcb5-52bf4a331c07@collabora.com>
Message-ID: <27b9f494-b824-46b8-9028-23e2ed1ff0f9@arinc9.com>

On 19.02.2024 12:17, AngeloGioacchino Del Regno wrote:
> Il 18/02/24 11:52, Ar?n? ?NAL ha scritto:
>> Matthias, please apply this patch.
>>
>> Ar?n?
> 
> Please split this by SoC and resend as two patches.
> 
> If you can resend fast enough, I can apply the patches for 6.9.

Done.

https://lore.kernel.org/linux-mediatek/20240219-for-mediatek-v1-0-7078f23eab82 at arinc9.com/

Ar?n?


From arnd at kernel.org  Mon Feb 19 01:38:04 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 19 Feb 2024 10:38:04 +0100
Subject: [PATCH] arm64: config: disable new platforms in virt.config
Message-ID: <20240219093819.644324-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

A couple of new platforms got added since last year when Mark
added virt.config, so turn these off as well.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm64/configs/virt.config | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/configs/virt.config b/arch/arm64/configs/virt.config
index c47c36f8f67b..2d1d2ce7ae2a 100644
--- a/arch/arm64/configs/virt.config
+++ b/arch/arm64/configs/virt.config
@@ -14,6 +14,7 @@
 # CONFIG_ARCH_BERLIN is not set
 # CONFIG_ARCH_BRCMSTB is not set
 # CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SPARX5 is not set
 # CONFIG_ARCH_K3 is not set
 # CONFIG_ARCH_LAYERSCAPE is not set
 # CONFIG_ARCH_LG1K is not set
@@ -23,14 +24,17 @@
 # CONFIG_ARCH_MESON is not set
 # CONFIG_ARCH_MVEBU is not set
 # CONFIG_ARCH_NXP is not set
+# CONFIG_ARCH_MA35 is not set
 # CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_NPCM is not set
 # CONFIG_ARCH_QCOM is not set
+# CONFIG_ARCH_REALTEK is not set
 # CONFIG_ARCH_RENESAS is not set
 # CONFIG_ARCH_ROCKCHIP is not set
 # CONFIG_ARCH_S32 is not set
 # CONFIG_ARCH_SEATTLE is not set
 # CONFIG_ARCH_INTEL_SOCFPGA is not set
+# CONFIG_ARCH_STM32 is not set
 # CONFIG_ARCH_SYNQUACER is not set
 # CONFIG_ARCH_TEGRA is not set
 # CONFIG_ARCH_TESLA_FSD is not set
-- 
2.39.2



From sundongxu3 at huawei.com  Mon Feb 19 01:38:15 2024
From: sundongxu3 at huawei.com (sundongxu (A))
Date: Mon, 19 Feb 2024 17:38:15 +0800
Subject: [PATCH] KVM: arm64: Add capability for unconditional WFx
 passthrough
In-Reply-To: <Zbgx8hZgWCmtzMjH@linux.dev>
References: <20240129213918.3124494-1-coltonlewis@google.com>
 <Zbgx8hZgWCmtzMjH@linux.dev>
Message-ID: <a3a41828-e65d-bc7f-ca75-7d3e9477042c@huawei.com>

Hi Marc, Oliver,

On 2024/1/30 7:17, Oliver Upton wrote:
> Hi Colton,
> 
> On Mon, Jan 29, 2024 at 09:39:17PM +0000, Colton Lewis wrote:
>> Add KVM_CAP_ARM_WFX_PASSTHROUGH capability to always allow WFE/WFI
>> instructions to run without trapping. Current behavior is to only
>> allow this if the vcpu is the only task running. This commit keeps the
>> old behavior when the capability is not set.
>>
>> This allows userspace to set deterministic behavior and increase
>> efficiency for platforms with direct interrupt injection support.
> 
> Marc and I actually had an offlist conversation (shame on us!) about
> this very topic since there are users asking for the _opposite_ of this
> patch (unconditionally trap) [*].
> 
> I had originally wanted something like this, but Marc made the very good
> point that (1) the behavior of WFx traps is in no way user-visible and
> (2) it is entirely an IMP DEF behavior. The architecture only requires
> the traps be effective if the instruction does not complete in finite
> time.
> 
> We need to think of an interface that doesn't depend on
> implementation-specific behavior, such as a control based on runqueue
> depth.

If I understand correctly, this run queue belongs to the scheduler, right?
And I will be appreciated if you can share any more detail information
about this.

> 
> [*] https://lore.kernel.org/kvmarm/a481ef04-ddd2-dfc1-41b1-d2ec45c6a3b5 at huawei.com/
> 

Thanks,
Dongxu


From kent.overstreet at linux.dev  Mon Feb 19 01:40:00 2024
From: kent.overstreet at linux.dev (Kent Overstreet)
Date: Mon, 19 Feb 2024 04:40:00 -0500
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <ZdMe24xN1Ej4QoVU@shell.armlinux.org.uk>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
 <ZdMe24xN1Ej4QoVU@shell.armlinux.org.uk>
Message-ID: <xs2splnjhlj257uca5yae64fp4solc4ugbxrkczoyd75n42r66@42boyzdcmyj4>

On Mon, Feb 19, 2024 at 09:26:51AM +0000, Russell King (Oracle) wrote:
> On Mon, Feb 19, 2024 at 07:21:11AM +0100, Arnd Bergmann wrote:
> > I think these should be addressed in bcachefs instead.
> > While it's not the fault of bcachefs that the calling
> > convention changed between gcc versions, have a look at
> > the actual structure layout:
> > 
> > struct bch_val {
> >         __u64           __nothing[0];
> > };
> > struct bpos {
> >         /*
> >          * Word order matches machine byte order - btree code treats a bpos as a
> >          * single large integer, for search/comparison purposes
> >          *
> >          * Note that wherever a bpos is embedded in another on disk data
> >          * structure, it has to be byte swabbed when reading in metadata that
> >          * wasn't written in native endian order:
> >          */
> > #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
> >         __u32           snapshot;
> >         __u64           offset;
> >         __u64           inode;
> > #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
> >         __u64           inode;
> >         __u64           offset;         /* Points to end of extent - sectors */
> >         __u32           snapshot;
> > #else
> > #error edit for your odd byteorder.
> > #endif
> > } __packed
> > struct bch_backpointer {
> >         struct bch_val          v;
> >         __u8                    btree_id;
> >         __u8                    level;
> >         __u8                    data_type;
> >         __u64                   bucket_offset:40;
> >         __u32                   bucket_len;
> >         struct bpos             pos;
> > } __packed __aligned(8);
> > 
> > This is not something that should ever be passed by value
> > into a function.
> 
> +1 - bcachefs definitely needs fixing. Passing all that as an argument
> not only means that it has to be read into registers, but also when
> accessing members, it has to be extracted from those registers as well.
> 
> Passing that by argument is utterly insane.

If the compiler people can't figure out a vaguely efficient way to pass
a small struct by value, that's their problem - from the way you
describe it, I have to wonder at what insanity is going on there.


From frank at oltmanns.dev  Mon Feb 19 01:41:19 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 19 Feb 2024 10:41:19 +0100
Subject: [PATCH v2 0/6] Pinephone video out fixes (flipping between two
 frames)
In-Reply-To: <s7uslavg5gzqzzdetwcushcknwe3nuicmqhfhb7gbapzxx2npy@srjc252uinqv>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <jzl3mlzk4j7qvgcedvipgale5nhinznefodrnaehwsqfnseiwc@7zzlxd4dpueh>
 <bgyyemyi4shj3spo6qy4icvk56nrp5sihnzqurnozqdyktwugc@ikurx4ojoxpi>
 <87wmrbxckj.fsf@oltmanns.dev>
 <s7uslavg5gzqzzdetwcushcknwe3nuicmqhfhb7gbapzxx2npy@srjc252uinqv>
Message-ID: <87r0h8n64g.fsf@oltmanns.dev>

Hi Ond?ej,

On 2024-02-11 at 20:25:29 +0100, Ond?ej Jirman <megi at xff.cz> wrote:
> Hi Frank,
>
> On Sun, Feb 11, 2024 at 04:09:16PM +0100, Frank Oltmanns wrote:
>> Hi Ond?ej,
>>
>> On 2024-02-05 at 17:02:00 +0100, Ond?ej Jirman <megi at xff.cz> wrote:
>> > On Mon, Feb 05, 2024 at 04:54:07PM +0100, Ond?ej Jirman wrote:
>> >> On Mon, Feb 05, 2024 at 04:22:23PM +0100, Frank Oltmanns wrote:
>> >>
>> >> [...]
>> >>
>> >> Also sunxi-ng clk driver does apply NM factors at once to PLL_GPU clock,
>> >> which can cause sudden frequency increase beyond intended output frequency,
>> >> because division is applied immediately while multiplication is reflected
>> >> slowly.
>> >>
>> >> Eg. if you're changing divider from 7 to 1, you can get a sudden 7x output
>> >> frequency spike, before PLL VCO manages to lower the frequency through N clk
>> >> divider feedback loop and lock on again. This can mess up whatever's connected
>> >> to the output quite badly.
>> >>
>> >> You'd have to put logging on kernel writes to PLL_GPU register to see what
>> >> is written in there and if divider is lowered significantly on some GPU
>> >> devfreq frequency transitions.
>>
>> By looking at the clocks in clk_summary in debugfs, the rate of PLL-GPU
>> always matches the rate of the GPU (at least at 120, 312, and 432 MHz).
>> This is further underlined by the fact, that none of the rates can be
>> achieved by integer dividing one of the other rates. sunxi-ng would
>> only favor a different rate for pll-gpu than the one that is requested
>> for the gpu, if pll-gpu is already running at a rate such that there
>> exists an M ? {1, 2, 3, 4, 5, 6, 7, 8}, where
>>   rate of pll-gpu / M = requested gpu rate
>> or if the requested rate could not be reached directly by pll-gpu. Both
>> is not the case for the rates in question (120, 192, 312, and 432 MHz).
>>
>> This means that the following divisor/multipliers are used by sunxi-ng's
>> ccu_nm:
>> N =  5, M = 1 for 120 MHz (min value without PATCH 6)
>> N =  8, M = 1 for 192 MHz (min value after applying PATCH 6)
>> N = 13, M = 1 for 312 MHz
>> N = 18, M = 1 for 432 MHz
>>
>> So, with or without PATCH 6, the divider stays constant and it's only
>> the multiplier that changes. This means, there should be no unexpected
>> frequency spikes, right?
>
> Maybe. Thanks for giving it a try. There may still be other kinds of glitches
> even if the divisor stays the same. It all depends how the register update is
> implemented in the PLL block. It's hard to say. I guess, unless Allwinner
> guarantees glitchless output from a given PLL when changing its parameters,
> you can't rely on the output being clean during changes.
>
>> >> It's also unclear what happens when FRAC_CLK_OUT or PLL_MODE_SEL changes.
>>
>> Those are not changed once the clock is initialized. The bug however
>> occurs hours or days after booting. IMO, this makes it unlikely that this
>> could be the culprit.
>>
>> >> Maybe not much because M is supposed to be set to 1, but you still need to
>> >> care when enabling fractional mode, and setting M to 1 because that's exactly
>> >> the bad scenario if M was previously higher than 1.
>> >>
>> >> It's tricky.
>> >>
>> >> Having GPU module clock gated during PLL config changes may help! You can
>> >> do that without locking yourself out, unlike with the CPU PLL.
>> >>
>> >> There's a gate enable bit for it at GPU_CLK_REG.SCLK_GATING. (page 122)
>>
>> The GPU should already be properly gated:
>> https://elixir.bootlin.com/linux/v6.7.4/source/drivers/clk/sunxi-ng/ccu-sun50i-a64.c#L599
>
> How so? That's just clock declaration. How does it guarantee the clock to the
> module is gated during parent PLL configuration changes?
>

You're of course right.

I now tried using a similar approach like the one for changes for on
PLL-CPU. It's using a notifier to connect the CPU to the 24 MHz
oscillator and, after PLL-CPU is at its new rate, connecting it back to
PLL-CPU.

For the GPU my approach was to disable the GPU prior to changing
PLL-GPU's rate and then re-enabling it, once the rate change is
complete. I think, that's what you were proposing, right?

Unfortunately, this results in a frozen phone even more quickly.

Below is my code. Again, it doesn't solve the problem, but maybe
somebody can spot what I'm doing wrong.

Best regards,
  Frank

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index d68bdf7dd342..74538259d67a 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -977,6 +977,11 @@ static struct ccu_rate_reset_nb sun50i_a64_pll_video0_reset_tcon0_nb = {

 #define CCU_MIPI_DSI_CLK 0x168

+static struct ccu_div_nb sun50i_a64_gpu_nb = {
+	.common		= &gpu_clk.common,
+	.delay_us	= 1, /* ??? */
+};
+
 static int sun50i_a64_ccu_probe(struct platform_device *pdev)
 {
 	void __iomem *reg;
@@ -1025,6 +1030,10 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
 	sun50i_a64_pll_video0_reset_tcon0_nb.target_clk = tcon0_clk.common.hw.clk;
 	ccu_rate_reset_notifier_register(&sun50i_a64_pll_video0_reset_tcon0_nb);

+	/* Gate then ungate GPU on PLL-GPU changes */
+	ccu_div_notifier_register(pll_gpu_clk.common.hw.clk,
+				  &sun50i_a64_gpu_nb);
+
 	return 0;
 }

diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c
index cb10a3ea23f9..83813c54fb2f 100644
--- a/drivers/clk/sunxi-ng/ccu_div.c
+++ b/drivers/clk/sunxi-ng/ccu_div.c
@@ -4,7 +4,9 @@
  * Maxime Ripard <maxime.ripard at free-electrons.com>
  */

+#include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/delay.h>
 #include <linux/io.h>

 #include "ccu_gate.h"
@@ -142,3 +144,37 @@ const struct clk_ops ccu_div_ops = {
 	.set_rate	= ccu_div_set_rate,
 };
 EXPORT_SYMBOL_NS_GPL(ccu_div_ops, SUNXI_CCU);
+
+static int ccu_div_notifier_cb(struct notifier_block *nb,
+			       unsigned long event, void *data)
+{
+	struct ccu_div_nb *div_nb = to_ccu_div_nb(nb);
+
+	if (event == PRE_RATE_CHANGE) {
+		div_nb->original_enable = ccu_div_is_enabled(&div_nb->common->hw);
+		if (div_nb->original_enable) {
+			ccu_div_disable(&div_nb->common->hw);
+			udelay(div_nb->delay_us);
+		}
+	} else if (event == POST_RATE_CHANGE) {
+		if (div_nb->original_enable) {
+			ccu_div_enable(&div_nb->common->hw);
+			udelay(div_nb->delay_us);
+		}
+	}
+
+	return NOTIFY_OK;
+}
+
+int ccu_div_notifier_register(struct clk *clk, struct ccu_div_nb *div_nb)
+{
+	div_nb->clk_nb.notifier_call = ccu_div_notifier_cb;
+
+	return clk_notifier_register(clk, &div_nb->clk_nb);
+}
diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h
index 90d49ee8e0cc..e096c7be5dca 100644
--- a/drivers/clk/sunxi-ng/ccu_div.h
+++ b/drivers/clk/sunxi-ng/ccu_div.h
@@ -283,4 +283,16 @@ static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)

 extern const struct clk_ops ccu_div_ops;

+struct ccu_div_nb {
+	struct notifier_block	clk_nb;
+	struct ccu_common	*common;
+
+	u32	delay_us;	/* us to wait after changing parent rate */
+	int	original_enable;/* This is set by the notifier callback */
+};
+
+#define to_ccu_div_nb(_nb) container_of(_nb, struct ccu_div_nb, clk_nb)
+
+int ccu_div_notifier_register(struct clk *clk, struct ccu_div_nb *mux_nb);
+
 #endif /* _CCU_DIV_H_ */



>
> CLK_SET_RATE_PARENT only gates output on re-parenting, not on parent rate changes,
> according to the header:
>
>   https://elixir.bootlin.com/linux/v6.7.4/source/include/linux/clk-provider.h#L19
>
> You'd need perhaps CLK_SET_RATE_GATE *and* still verify that it actually works
> as expected via some tracing of gpu clock enable/disable/set_rate and pll-gpu
> set_rate. CLK_SET_RATE_GATE seems confusingly docummented:
>
>   https://elixir.bootlin.com/linux/v6.7.4/source/drivers/clk/clk.c#L1034
>
> so I don't particularly trust it does exaclty what the header claims and what
> would be needed to test the theory that gating gpu clock during rate change
> might help.
>
> kind regards,
> 	o.
>
>> Thank you for your detailed proposal! It was insightful to read. But
>> while those were all great ideas, they have all already been taken care
>> of. I'm fresh out of ideas again (except for pinning the GPU rate).
>>
>> Again, thank you so much,
>>   Frank
>>
>> >>
>> >> Kind regards,
>> >> 	o.
>> >>
>> >> > I very much appreciate your feedback!
>> >> >
>> >> > [1] https://gitlab.com/postmarketOS/pmaports/-/issues/805
>> >> >
>> >> > Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
>> >> > ---
>> >> > Changes in v2:
>> >> > - dts: Increase minimum GPU frequency to 192 MHz.
>> >> > - nkm and a64: Add minimum and maximum rate for PLL-MIPI.
>> >> > - nkm: Use the same approach for skipping invalid rates in
>> >> >   ccu_nkm_find_best() as in ccu_nkm_find_best_with_parent_adj().
>> >> > - nkm: Improve names for ratio struct members and hence get rid of
>> >> >   describing comments.
>> >> > - nkm and a64: Correct description in the commit messages: M/N <= 3
>> >> > - Remove patches for nm as they were not needed.
>> >> > - st7703: Rework the commit message to cover more background for the
>> >> >   change.
>> >> > - Link to v1: https://lore.kernel.org/r/20231218-pinephone-pll-fixes-v1-0-e238b6ed6dc1 at oltmanns.dev
>> >> >
>> >> > ---
>> >> > Frank Oltmanns (6):
>> >> >       clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate
>> >> >       clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate
>> >> >       clk: sunxi-ng: nkm: Support minimum and maximum rate
>> >> >       clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
>> >> >       drm/panel: st7703: Drive XBD599 panel at higher clock rate
>> >> >       arm64: dts: allwinner: a64: Fix minimum GPU OPP rate
>> >> >
>> >> >  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  4 ++--
>> >> >  drivers/clk/sunxi-ng/ccu-sun50i-a64.c         | 14 +++++++----
>> >> >  drivers/clk/sunxi-ng/ccu_nkm.c                | 34 +++++++++++++++++++++++++++
>> >> >  drivers/clk/sunxi-ng/ccu_nkm.h                |  4 ++++
>> >> >  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++++------
>> >> >  5 files changed, 56 insertions(+), 14 deletions(-)
>> >> > ---
>> >> > base-commit: 059c53e877ca6e723e10490c27c1487a63e66efe
>> >> > change-id: 20231218-pinephone-pll-fixes-0ccdfde273e4
>> >> >
>> >> > Best regards,
>> >> > --
>> >> > Frank Oltmanns <frank at oltmanns.dev>
>> >> >


From neil.armstrong at linaro.org  Mon Feb 19 01:42:39 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 19 Feb 2024 10:42:39 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org>
 <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
Message-ID: <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org>

On 19/02/2024 10:22, Dmitry Baryshkov wrote:
> On Mon, 19 Feb 2024 at 10:14, Neil Armstrong <neil.armstrong at linaro.org> wrote:
>>
>> On 18/02/2024 13:53, Dmitry Baryshkov wrote:
>>> On Fri, 16 Feb 2024 at 22:33, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>>>>
>>>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>>>
>>>> First, I'd like to apologize for the somewhat chaotic previous iterations
>>>> of this series and improper versioning which was rightfully pointed out
>>>> to me. I figured that the scope changed so much that it didn't make sense
>>>> to consider previous submissions part of the same series as the original
>>>> RFC but others thought otherwise so this one becomes v5 and I'll keep the
>>>> versioning going forward.
>>>>
>>>> This is the summary of the work so far:
>>>>
>>>> v1: Original RFC:
>>>>
>>>> https://lore.kernel.org/lkml/20240104130123.37115-1-brgl at bgdev.pl/T/
>>>>
>>>> v2: First real patch series (should have been PATCH v2) adding what I
>>>>       referred to back then as PCI power sequencing:
>>>>
>>>> https://lore.kernel.org/linux-arm-kernel/2024021413-grumbling-unlivable-c145 at gregkh/T/
>>>>
>>>> v3: RFC for the DT representation of the PMU supplying the WLAN and BT
>>>>       modules inside the QCA6391 package (was largely separate from the
>>>>       series but probably should have been called PATCH or RFC v3):
>>>>
>>>> https://lore.kernel.org/all/CAMRc=Mc+GNoi57eTQg71DXkQKjdaoAmCpB=h2ndEpGnmdhVV-Q at mail.gmail.com/T/
>>>>
>>>> v4: Second attempt at the full series with changed scope (introduction of
>>>>       the pwrseq subsystem, should have been RFC v4)
>>>>
>>>> https://lore.kernel.org/lkml/20240201155532.49707-1-brgl at bgdev.pl/T/
>>>>
>>>> ===
>>>>
>>>> With that out of the way, I'd like to get down to explaining the two
>>>> problems I'm trying to solve.
>>>>
>>>> Problem statement #1: Dynamic bus chicken-and-egg problem.
>>>>
>>>> Certain on-board PCI devices need to be powered up before they are can be
>>>> detected but their PCI drivers won't get bound until the device is
>>>> powered-up so enabling the relevant resources in the PCI device driver
>>>> itself is impossible.
>>>>
>>>> Problem statement #2: Sharing inter-dependent resources between devices.
>>>>
>>>> Certain devices that use separate drivers (often on different busses)
>>>> share resources (regulators, clocks, etc.). Typically these resources
>>>> are reference-counted but in some cases there are additional interactions
>>>> between them to consider, for example specific power-up sequence timings.
>>>>
>>>> ===
>>>>
>>>> The reason for tackling both of these problems in a single series is the
>>>> fact the the platform I'm working on - Qualcomm RB5 - deals with both and
>>>> both need to be addressed in order to enable WLAN and Bluetooth support
>>>> upstream.
>>>>
>>>> The on-board WLAN/BT package - QCA6391 - has a Power Management Unit that
>>>> takes inputs from the host and exposes LDO outputs consumed by the BT and
>>>> WLAN modules which can be powered-up and down independently. However
>>>> a delay of 100ms must be respected between enabling the BT- and
>>>> WLAN-enable GPIOs[*].
>>>>
>>>> ===
>>>>
>>>> This series is logically split into several sections. I'll go
>>>> patch-by-patch and explain each step.
>>>>
>>>> Patch 1/18:
>>>>
>>>> This is a commit taken from the list by Jonathan Cameron that adds
>>>> a __free() helper for OF nodes. Not strictly related to the series but
>>>> until said commit ends in next, I need to carry it with this series.
>>>>
>>>> Patch 2/18:
>>>>
>>>> This enables the ath12k PCI module in arm64 defconfig as Qualcomm sm8650
>>>> and sm8550 reference platforms use it in the WCN7850 module.
>>>>
>>>> Patches 3/18-6/18:
>>>>
>>>> These contain all relevant DT bindings changes. We add new documents for
>>>> the QCA6390 PMU and ATH12K devices as well as extend the bindings for the
>>>> Qualcomm Bluetooth and ATH11K modules with regulators used by them in
>>>> QCA6390.
>>>>
>>>> Patches 7/18-9/18:
>>>>
>>>> These contain changes to device-tree sources for the three platforms we
>>>> work with in this series. As the WCN7850 module doesn't require any
>>>> specific timings introducing dependencies between the Bluetooth and WLAN
>>>> modules, while the QCA6390 does, we take two different approaches to how
>>>> me model them in DT.
>>>>
>>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
>>>> necessary. The BT and WLAN devices on the device-tree are represented as
>>>> consuming the inputs (relevant to the functionality of each) of the PMU
>>>> directly.
>>>
>>> We are describing the hardware. From the hardware point of view, there
>>> is a PMU. I think at some point we would really like to describe all
>>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
>>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
>>
>> While I agree with older WiFi+BT units, I don't think it's needed for
>> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
>> transparent.
> 
> I don't see any significant difference between WCN6750/WCN6855 and
> WCN7850 from the PMU / power up point of view. Could you please point
> me to the difference?
> 

The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
and BT_EN ordering and the only requirement is to have all input regulators
up before pulling up WLAN_EN and/or BT_EN.

This makes the PMU transparent and BT and WLAN can be described as independent.

Neil


From naresh.kamboju at linaro.org  Mon Feb 19 01:42:45 2024
From: naresh.kamboju at linaro.org (Naresh Kamboju)
Date: Mon, 19 Feb 2024 15:12:45 +0530
Subject: next-20240219: arm64: boot failed - gic_of_init
Message-ID: <CA+G9fYugYiLd7MDn3wCxK+x5Td9WO-VUX2OvOtTN7D1d4GHCfg@mail.gmail.com>

The qemu-arm64 boot failed with linux next-20240219 tag kernel.

Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>

Boot log:
---------
<6>[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
<1>[    0.000000] Unable to handle kernel paging request at virtual
address ffff80008001ffe8
<1>[    0.000000] Mem abort info:
<1>[    0.000000]   ESR = 0x0000000096000004
<1>[    0.000000]   EC = 0x25: DABT (current EL), IL = 32 bits
<1>[    0.000000]   SET = 0, FnV = 0
<1>[    0.000000]   EA = 0, S1PTW = 0
<1>[    0.000000]   FSC = 0x04: level 0 translation fault
<1>[    0.000000] Data abort info:
<1>[    0.000000]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
<1>[    0.000000]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
<1>[    0.000000]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
<1>[    0.000000] swapper pgtable: 4k pages, 52-bit VAs, pgdp=0000000042497000
<1>[    0.000000] [ffff80008001ffe8] pgd=10000000439a5003,
p4d=10000001000e3003, pud=10000001000e4003, pmd=10000001000e5003,
pte=006800000800f413
<0>[    0.000000] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
<4>[    0.000000] Modules linked in:
<4>[    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted
6.8.0-rc5-next-20240219 #1
<4>[    0.000000] Hardware name: linux,dummy-virt (DT)
<4>[    0.000000] pstate: 804000c9 (Nzcv daIF +PAN -UAO -TCO -DIT
-SSBS BTYPE=--)
<4>[    0.000000] pc : gic_of_init+0x84/0x3a8
<4>[    0.000000] lr : gic_of_init+0x290/0x3a8
...
<4>[    0.000000] Call trace:
<4>[    0.000000]  gic_of_init+0x84/0x3a8
<4>[    0.000000]  of_irq_init+0x1d4/0x3d0
<4>[    0.000000]  irqchip_init+0x20/0x50
<4>[    0.000000]  init_IRQ+0xa8/0xc8
<4>[    0.000000]  start_kernel+0x270/0x690
<4>[    0.000000]  __primary_switched+0x80/0x90
<0>[    0.000000] Code: f94017e0 f90007e0 d29ffd00 8b0002c0 (b9400000)
<4>[    0.000000] ---[ end trace 0000000000000000 ]---
<0>[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
<0>[    0.000000] ---[ end Kernel panic - not syncing: Attempted to
kill the idle task! ]---

Links:
 - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240219/testrun/22730192/suite/boot/test/gcc-13-lkftconfig-armv8_features/log
 - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240219/testrun/22730192/suite/boot/tests/

--
Linaro LKFT
https://lkft.linaro.org


From ck.hu at mediatek.com  Mon Feb 19 01:33:49 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Mon, 19 Feb 2024 09:33:49 +0000
Subject: [PATCH v2 2/3] Subject: [PATCH] drm/mediatek/dp: Add HDCP2.x
 feature for DisplayPort
In-Reply-To: <20240205055055.25340-3-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
	 <20240205055055.25340-3-mac.shen@mediatek.com>
Message-ID: <97606a5ff68fad6fe1b848f67298f8668e1aa46c.camel@mediatek.com>

Hi, Mac:

On Mon, 2024-02-05 at 13:50 +0800, mac.shen wrote:
> Add HDCP2.x feature for DisplayPort.
> When userspace request the kernel protect future content communicated
> over the link with Content_Protection property, the feature will do
> HDCP2.x authentication if the sink support HDCP2.X.
> 
> Changes in v2:
> - remove switch case, and refine code to make more clear
> - remove some definitions, and use the definitions in
>   include/drm/drm_hdcp.h
> - use the struct which defined in include/drm/drm_hdcp.h
> - do HDCP2.x authentication when userspace request the
>   kernel protect future content communicated
> per suggestion from the previous thread:
> https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
> 9218a545c46.camel at mediatek.com/
> 
> Signed-off-by: mac.shen <mac.shen at mediatek.com>
> ---

[snip]

> +
> +int dp_tx_hdcp2_fsm(struct mtk_hdcp_info *hdcp_info)
> +{
> +	static u32 timeout_value;
> +	static u8 pre_main;
> +	static u8 pre_sub;
> +	static u32 pre_time;
> +	int err_code = HDCP_ERR_NONE;
> +	bool stored = false;
> +	u32 time;
> +	int ret = 0;
> +	bool tmp = false;
> +
> +	if (pre_main != hdcp_info->hdcp2_info.hdcp_handler.main_state
> ||
> +	    hdcp_info->hdcp2_info.hdcp_handler.sub_state != pre_sub) {
> +		DPTXHDCPMSG("2.x: Port(M : S)= (%d, %d)",
> +			    hdcp_info-
> >hdcp2_info.hdcp_handler.main_state,
> +			    hdcp_info-
> >hdcp2_info.hdcp_handler.sub_state);
> +		pre_main = hdcp_info-
> >hdcp2_info.hdcp_handler.main_state;
> +		pre_sub = hdcp_info->hdcp2_info.hdcp_handler.sub_state;
> +	}
> +
> +	switch (hdcp_info->hdcp2_info.hdcp_handler.main_state) {
> +	case HDCP2_MS_H1P1:
> +		/* HDCP2_MS_H1P1 */
> +		/* HDCP_2_2_AUTH_FAIL */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AUTH_FAIL) {
> +			pr_err("2.x: Authentication Fail!\n");
> +			dp_tx_hdcp2_enable_auth(hdcp_info, false);
> +			hdcp_info->auth_status = AUTH_FAIL;
> +		}
> +		break;
> +
> +	case HDCP2_MS_A0F0:
> +		/* HDCP2_MS_A0F0 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_NULL_MSG) {

Could you refer to intel driver to get rid of this state machine? It
seams this flow does not need state machine. Just step forward. If
error happen, break the flow. If your implement is like intel driver,
it's easier for me to compare and easier to review.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/i915/display/intel_hdcp.c?h=v6.8-rc5#n1868

Regards,
CK

> +			if (!hdcp_info->hdcp2_info.enable) {
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_H1P1, HDCP_2_2_AUTH_FAIL);
> +				DPTXHDCPMSG("2.x: Sink Doesn't Support
> Hdcp2x!\n");
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_init(hdcp_info);
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> HDCP_2_2_NULL_MSG);
> +			DPTXHDCPMSG("2.x: Sink Support Hdcp2x!\n");
> +		}
> +		break;
> +
> +	case HDCP2_MS_A1F1:
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_NULL_MSG) {
> +			if (hdcp_info->hdcp2_info.retry_count >=
> HDCP2_TX_RETRY_CNT) {
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_H1P1, HDCP_2_2_AUTH_FAIL);
> +				pr_err("2.x: Try Max Count\n");
> +				break;
> +			}
> +
> +			hdcp_info->hdcp2_info.retry_count++;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> HDCP_2_2_AKE_INIT);
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_INIT */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AKE_INIT) {
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_AKE_INIT);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +			dp_tx_hdcp2_rest_variable(hdcp_info);
> +			hdcp_info->hdcp2_info.read_certrx = true;
> +
> +			hdcp_info-
> >hdcp2_info.hdcp_handler.send_ake_init = true;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> HDCP_2_2_AKE_SEND_CERT);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_SEND_CERT */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AKE_SEND_CERT) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time < HDCP_2_2_CERT_TIMEOUT_MS) {
> +				msleep(20);
> +				break;
> +			}
> +			if (hdcp_info->hdcp2_info.read_certrx)
> +				dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_AKE_SEND_CERT);
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			ret = tee_ake_certificate(hdcp_info,
> +						  (u8 *)&hdcp_info-
> >hdcp2_info.hdcp_rx.cert_rx,
> +						  &stored,
> +				hdcp_info-
> >hdcp2_info.ake_stored_km.e_kh_km_m +
> +				HDCP_2_2_E_KH_KM_LEN,
> +				hdcp_info-
> >hdcp2_info.ake_stored_km.e_kh_km_m);
> +
> +			if (ret != RET_COMPARE_PASS) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			hdcp_info->hdcp2_info.hdcp_handler.stored_km =
> stored;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> +					      hdcp_info-
> >hdcp2_info.hdcp_handler.stored_km ?
> +					HDCP_2_2_AKE_STORED_KM :
> +					HDCP_2_2_AKE_NO_STORED_KM);
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_NO_STORED_KM */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AKE_NO_STORED_KM) {
> +			DPTXHDCPMSG("2.x: Get Km, derive Ekpub(km)\n");
> +
> +			tee_enc_rsaes_oaep(hdcp_info,
> +					   hdcp_info-
> >hdcp2_info.hdcp_tx.no_stored_km.e_kpub_km);
> +			/* Prepare e_kpub_km to send */
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_AKE_NO_STORED_KM);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> HDCP_2_2_AKE_SEND_HPRIME);
> +			timeout_value =
> HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_STORED_KM */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AKE_STORED_KM) {
> +			/* Prepare ekh_km & M to send */
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_AKE_STORED_KM);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			err_code = HDCP_ERR_NONE;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> HDCP_2_2_AKE_SEND_HPRIME);
> +			timeout_value =
> HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_SEND_HPRIME */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AKE_SEND_HPRIME) {
> +			if (hdcp_info->hdcp2_info.read_h_prime)
> +				dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_AKE_SEND_HPRIME);
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > timeout_value) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			ret = tee_ake_h_prime(hdcp_info,
> +					      hdcp_info-
> >hdcp2_info.hdcp_tx.ake_init.r_tx,
> +					      hdcp_info-
> >hdcp2_info.hdcp_rx.send_cert.r_rx,
> +				hdcp_info-
> >hdcp2_info.hdcp_rx.send_cert.rx_caps,
> +				(u8 *)&hdcp_info-
> >hdcp2_info.hdcp_tx.tx_caps,
> +				hdcp_info-
> >hdcp2_info.hdcp_rx.send_hprime.h_prime,
> +				HDCP_2_2_H_PRIME_LEN);
> +			if (ret != RET_COMPARE_PASS) {
> +				if (hdcp_info-
> >hdcp2_info.hdcp_handler.stored_km)
> +					tee_clear_paring(hdcp_info);
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (hdcp_info-
> >hdcp2_info.hdcp_handler.stored_km)
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_A2F2, HDCP_2_2_LC_INIT);
> +			else
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_A1F1,
> +						      HDCP_2_2_AKE_SEND
> _PAIRING_INFO);
> +
> +			pre_time = mtk_dp_get_system_time();
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_SEND_PAIRING_INFO */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> +			HDCP_2_2_AKE_SEND_PAIRING_INFO) {
> +			if (hdcp_info->hdcp2_info.read_pairing)
> +				dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_AKE_SEND_PAIRING_INFO);
> +
> +			/* Ekh_Km must be available less than 200ms,
> Give mode time for some Rx */
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time >	HDCP_2_2_PAIRING_TIMEOUT_MS *
> 2) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			/* Store m, km, Ekh(km) */
> +			tee_ake_paring(hdcp_info,
> +				       hdcp_info-
> >hdcp2_info.hdcp_rx.pairing_info.e_kh_km);
> +
> +			hdcp_info->hdcp2_info.hdcp_handler.send_pair =
> true;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A2F2,
> HDCP_2_2_LC_INIT);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +		break;
> +
> +	case HDCP2_MS_A2F2:
> +		/* HDCP2_MS_A2F2 */
> +		/* HDCP_2_2_LC_INIT */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_LC_INIT) {
> +			/* prepare Rn to send */
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_LC_INIT);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +			hdcp_info->hdcp2_info.hdcp_handler.send_lc_init 
> = true;
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A2F2,
> HDCP_2_2_LC_SEND_LPRIME);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A2F2 */
> +		/* HDCP_2_2_LC_SEND_LPRIME */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_LC_SEND_LPRIME) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time < HDCP_2_2_DP_HPRIME_READ_TIMEOUT_MS)
> +				break;
> +
> +			if (hdcp_info->hdcp2_info.read_l_prime)
> +				dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_LC_SEND_LPRIME);
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			ret = tee_lc_l_prime(hdcp_info, hdcp_info-
> >hdcp2_info.hdcp_tx.lc_init.r_n,
> +					     hdcp_info-
> >hdcp2_info.hdcp_rx.send_lprime.l_prime,
> +					     HDCP_2_2_L_PRIME_LEN);
> +			if (ret != RET_COMPARE_PASS) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			DPTXHDCPMSG("2.x: L' is PASS!!\n");
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A3F3,
> HDCP_2_2_NULL_MSG);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +		break;
> +
> +	case HDCP2_MS_A3F3:
> +		/* HDCP2_MS_A3F3 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_NULL_MSG) {
> +			tee_ske_enc_ks(hdcp_info, hdcp_info-
> >hdcp2_info.hdcp_tx.send_eks.riv,
> +				       hdcp_info-
> >hdcp2_info.hdcp_tx.send_eks.e_dkey_ks);
> +
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_SKE_SEND_EKS);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info->hdcp2_info.repeater)
> +				dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_STREAM_TYPE);
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A3F3,
> HDCP_2_2_SKE_SEND_EKS);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A3F3 */
> +		/* HDCP_2_2_SKE_SEND_EKS */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_SKE_SEND_EKS) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time >=
> HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN)
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_A4F4, HDCP_2_2_NULL_MSG);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A4F4:
> +		/* HDCP2_MS_A4F4 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_NULL_MSG) {
> +			if (!hdcp_info->hdcp2_info.repeater) {
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_A5F5, HDCP_2_2_AUTH_DONE);
> +				break;
> +			}
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A6F6,
> +					      HDCP_2_2_REP_SEND_RECVID_
> LIST);
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +		break;
> +
> +	case HDCP2_MS_A5F5:
> +		/* HDCP2_MS_A5F5 */
> +		/* HDCP_2_2_AUTH_DONE */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AUTH_DONE) {
> +			DPTXHDCPMSG("2.x: Authentication done!\n");
> +			hdcp_info->auth_status = AUTH_PASS;
> +			hdcp_info->hdcp2_info.retry_count = 0;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A5F5,
> HDCP_2_2_NULL_MSG);
> +			dp_tx_hdcp2_enable_auth(hdcp_info, true);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A6F6:
> +		/* HDCP2_MS_A6F6 */
> +		/* HDCP_2_2_REP_SEND_RECVID_LIST */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> +			HDCP_2_2_REP_SEND_RECVID_LIST) {
> +			if (hdcp_info->hdcp2_info.read_v_prime)
> +				dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_REP_SEND_RECVID_LIST);
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > HDCP_2_2_RECVID_LIST_TIMEOUT_MS) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			pre_time = mtk_dp_get_system_time();
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A7F7,
> +					      HDCP_2_2_REP_VERIFY_RECVI
> D_LIST);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A7F7:
> +		/* HDCP2_MS_A7F7 */
> +		/* HDCP_2_2_REP_VERIFY_RECVID_LIST */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> +			HDCP_2_2_REP_VERIFY_RECVID_LIST) {
> +			if ((hdcp_info-
> >hdcp2_info.hdcp_rx.receiverid_list.rx_info[1]
> +				& (BIT(2) | BIT(3))) != 0) {
> +				pr_err("2.x: DEVS_EXCEEDED or
> CASCADE_EXCEDDED!\n");
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			/* check seqNumV here */
> +			tmp = dp_tx_hdcp2_check_seq_num_v(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			tmp =
> dp_tx_hdcp2_recv_rep_auth_send_recv_id_list(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A8F8,
> HDCP_2_2_REP_SEND_ACK);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A8F8:
> +		/* HDCP2_MS_A8F8 */
> +		/* HDCP_2_2_REP_SEND_ACK */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_REP_SEND_ACK) {
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_REP_SEND_ACK);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > HDCP2_REP_SEND_ACK) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A9F9,
> HDCP_2_2_REP_STREAM_MANAGE);
> +			hdcp_info->hdcp2_info.hdcp_handler.retry_cnt =
> 0;
> +		}
> +		break;
> +
> +	case HDCP2_MS_A9F9:
> +		/* HDCP2_MS_A9F9 */
> +		/* HDCP_2_2_REP_STREAM_MANAGE */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_REP_STREAM_MANAGE) {
> +			tmp =
> dp_tx_hdcp2_process_rep_auth_stream_manage(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_REP_STREAM_MANAGE);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			pre_time = mtk_dp_get_system_time();
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A9F9,
> +					      HDCP_2_2_REP_STREAM_READY
> );
> +		}
> +
> +		/* HDCP2_MS_A9F9 */
> +		/* HDCP_2_2_REP_STREAM_READY */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_REP_STREAM_READY) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time <= HDCP_2_2_STREAM_READY_TIMEOUT_MS /
> 2)
> +				break;
> +
> +			dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_REP_STREAM_READY);
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > HDCP_2_2_STREAM_READY_TIMEOUT_MS) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg) {
> +				if (hdcp_info-
> >hdcp2_info.hdcp_handler.retry_cnt
> +					>=
> HDCP2_STREAM_MANAGE_RETRY_CNT) {
> +					err_code =
> HDCP_ERR_RESPONSE_TIMEROUT;
> +					dp_tx_hdcp2_err_handle(hdcp_inf
> o, err_code, __LINE__);
> +					break;
> +				}
> +
> +				hdcp_info-
> >hdcp2_info.hdcp_handler.retry_cnt++;
> +
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_A9F9,
> +						      HDCP_2_2_REP_STRE
> AM_READY);
> +				break;
> +			}
> +
> +			tmp =
> dp_tx_hdcp2_recv_rep_auth_stream_ready(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A5F5,
> HDCP_2_2_AUTH_DONE);
> +		}
> +		break;
> +
> +	default:
> +		err_code = HDCP_ERR_UNKNOWN_STATE;
> +		dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +		break;
> +	}
> +
> +	return err_code;
> +}
> +

From Jonathan.Cameron at Huawei.com  Mon Feb 19 01:45:10 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Mon, 19 Feb 2024 09:45:10 +0000
Subject: [PATCH RFC v4 01/15] ACPI: Only enumerate enabled (or
 functional) processor devices
In-Reply-To: <CAJZ5v0hY_LXp41WMVPhiLosPe7YVzF38Uz=EhmJqVwqFn==Upw@mail.gmail.com>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk>
	<E1rVDmP-0027YJ-EW@rmk-PC.armlinux.org.uk>
	<CAJZ5v0hY_LXp41WMVPhiLosPe7YVzF38Uz=EhmJqVwqFn==Upw@mail.gmail.com>
Message-ID: <20240219094510.00004843@Huawei.com>

On Thu, 15 Feb 2024 21:10:39 +0100
"Rafael J. Wysocki" <rafael at kernel.org> wrote:

> On Wed, Jan 31, 2024 at 5:49?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:
> >
> > From: James Morse <james.morse at arm.com>
> >
> > Today the ACPI enumeration code 'visits' all devices that are present.
> >
> > This is a problem for arm64, where CPUs are always present, but not
> > always enabled. When a device-check occurs because the firmware-policy
> > has changed and a CPU is now enabled, the following error occurs:
> > | acpi ACPI0007:48: Enumeration failure
> >
> > This is ultimately because acpi_dev_ready_for_enumeration() returns
> > true for a device that is not enabled. The ACPI Processor driver
> > will not register such CPUs as they are not 'decoding their resources'.
> >
> > ACPI allows a device to be functional instead of maintaining the
> > present and enabled bit, but we can't simply check the enabled bit
> > for all devices since firmware can be buggy.
> >
> > If ACPI indicates that the device is present and enabled, then all well
> > and good, we can enumate it. However, if the device is present and not
> > enabled, then we also check whether the device is a processor device
> > to limit the impact of this new check to just processor devices.
> >
> > This avoids enumerating present && functional processor devices that
> > are not enabled.
> >
> > Signed-off-by: James Morse <james.morse at arm.com>
> > Co-developed-by: Rafael J. Wysocki <rjw at rjwysocki.net>
> > Tested-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> > Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> > Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> > ---
> > Changes since RFC v2:
> >  * Incorporate comment suggestion by Gavin Shan.
> > Changes since RFC v3:
> >  * Fixed "sert" typo.
> > Changes since RFC v3 (smaller series):
> >  * Restrict checking the enabled bit to processor devices, update
> >    commit comments.
> >  * Use Rafael's suggestion in
> >    https://lore.kernel.org/r/5760569.DvuYhMxLoT at kreacher
> >  * Updated with a fix - see:
> >    https://lore.kernel.org/all/Zbe8WQRASx6D6RaG at shell.armlinux.org.uk/
> > ---
> >  drivers/acpi/acpi_processor.c | 11 +++++++++
> >  drivers/acpi/device_pm.c      |  2 +-
> >  drivers/acpi/device_sysfs.c   |  2 +-
> >  drivers/acpi/internal.h       |  4 ++-
> >  drivers/acpi/property.c       |  2 +-
> >  drivers/acpi/scan.c           | 46 +++++++++++++++++++++++++++--------
> >  6 files changed, 53 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> > index 4fe2ef54088c..cf7c1cca69dd 100644
> > --- a/drivers/acpi/acpi_processor.c
> > +++ b/drivers/acpi/acpi_processor.c
> > @@ -626,6 +626,17 @@ static struct acpi_scan_handler processor_handler = {
> >         },
> >  };
> >
> > +bool acpi_device_is_processor(const struct acpi_device *adev)
> > +{
> > +       if (adev->device_type == ACPI_BUS_TYPE_PROCESSOR)
> > +               return true;
> > +
> > +       if (adev->device_type != ACPI_BUS_TYPE_DEVICE)
> > +               return false;
> > +
> > +       return acpi_scan_check_handler(adev, &processor_handler);
> > +}
> > +
> >  static int acpi_processor_container_attach(struct acpi_device *dev,
> >                                            const struct acpi_device_id *id)
> >  {
> > diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
> > index 3b4d048c4941..e3c80f3b3b57 100644
> > --- a/drivers/acpi/device_pm.c
> > +++ b/drivers/acpi/device_pm.c
> > @@ -313,7 +313,7 @@ int acpi_bus_init_power(struct acpi_device *device)
> >                 return -EINVAL;
> >
> >         device->power.state = ACPI_STATE_UNKNOWN;
> > -       if (!acpi_device_is_present(device)) {
> > +       if (!acpi_dev_ready_for_enumeration(device)) {
> >                 device->flags.initialized = false;
> >                 return -ENXIO;
> >         }
> > diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c
> > index 23373faa35ec..a0256d2493a7 100644
> > --- a/drivers/acpi/device_sysfs.c
> > +++ b/drivers/acpi/device_sysfs.c
> > @@ -141,7 +141,7 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia
> >         struct acpi_hardware_id *id;
> >
> >         /* Avoid unnecessarily loading modules for non present devices. */
> > -       if (!acpi_device_is_present(acpi_dev))
> > +       if (!acpi_dev_ready_for_enumeration(acpi_dev))
> >                 return 0;
> >
> >         /*
> > diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
> > index 6588525c45ef..1bc8b6db60c5 100644
> > --- a/drivers/acpi/internal.h
> > +++ b/drivers/acpi/internal.h
> > @@ -62,6 +62,8 @@ void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
> >  int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler,
> >                                        const char *hotplug_profile_name);
> >  void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val);
> > +bool acpi_scan_check_handler(const struct acpi_device *adev,
> > +                            struct acpi_scan_handler *handler);
> >
> >  #ifdef CONFIG_DEBUG_FS
> >  extern struct dentry *acpi_debugfs_dir;
> > @@ -121,7 +123,6 @@ int acpi_device_setup_files(struct acpi_device *dev);
> >  void acpi_device_remove_files(struct acpi_device *dev);
> >  void acpi_device_add_finalize(struct acpi_device *device);
> >  void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
> > -bool acpi_device_is_present(const struct acpi_device *adev);
> >  bool acpi_device_is_battery(struct acpi_device *adev);
> >  bool acpi_device_is_first_physical_node(struct acpi_device *adev,
> >                                         const struct device *dev);
> > @@ -133,6 +134,7 @@ int acpi_bus_register_early_device(int type);
> >  const struct acpi_device *acpi_companion_match(const struct device *dev);
> >  int __acpi_device_uevent_modalias(const struct acpi_device *adev,
> >                                   struct kobj_uevent_env *env);
> > +bool acpi_device_is_processor(const struct acpi_device *adev);
> >
> >  /* --------------------------------------------------------------------------
> >                                    Power Resource
> > diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
> > index a6ead5204046..9f8d54038770 100644
> > --- a/drivers/acpi/property.c
> > +++ b/drivers/acpi/property.c
> > @@ -1486,7 +1486,7 @@ static bool acpi_fwnode_device_is_available(const struct fwnode_handle *fwnode)
> >         if (!is_acpi_device_node(fwnode))
> >                 return false;
> >
> > -       return acpi_device_is_present(to_acpi_device_node(fwnode));
> > +       return acpi_dev_ready_for_enumeration(to_acpi_device_node(fwnode));
> >  }
> >
> >  static const void *
> > diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> > index e6ed1ba91e5c..fd2e8b3a5749 100644
> > --- a/drivers/acpi/scan.c
> > +++ b/drivers/acpi/scan.c
> > @@ -304,7 +304,7 @@ static int acpi_scan_device_check(struct acpi_device *adev)
> >         int error;
> >
> >         acpi_bus_get_status(adev);
> > -       if (acpi_device_is_present(adev)) {
> > +       if (acpi_dev_ready_for_enumeration(adev)) {
> >                 /*
> >                  * This function is only called for device objects for which
> >                  * matching scan handlers exist.  The only situation in which
> > @@ -338,7 +338,7 @@ static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used)
> >         int error;
> >
> >         acpi_bus_get_status(adev);
> > -       if (!acpi_device_is_present(adev)) {
> > +       if (!acpi_dev_ready_for_enumeration(adev)) {
> >                 acpi_scan_device_not_enumerated(adev);
> >                 return 0;
> >         }
> > @@ -1917,11 +1917,6 @@ static bool acpi_device_should_be_hidden(acpi_handle handle)
> >         return true;
> >  }
> >
> > -bool acpi_device_is_present(const struct acpi_device *adev)
> > -{
> > -       return adev->status.present || adev->status.functional;
> > -}
> > -
> >  static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
> >                                        const char *idstr,
> >                                        const struct acpi_device_id **matchid)
> > @@ -1942,6 +1937,18 @@ static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
> >         return false;
> >  }
> >
> > +bool acpi_scan_check_handler(const struct acpi_device *adev,
> > +                            struct acpi_scan_handler *handler)
> > +{
> > +       struct acpi_hardware_id *hwid;
> > +
> > +       list_for_each_entry(hwid, &adev->pnp.ids, list)
> > +               if (acpi_scan_handler_matching(handler, hwid->id, NULL))
> > +                       return true;
> > +
> > +       return false;
> > +}
> > +
> >  static struct acpi_scan_handler *acpi_scan_match_handler(const char *idstr,
> >                                         const struct acpi_device_id **matchid)
> >  {
> > @@ -2405,16 +2412,35 @@ EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
> >   * acpi_dev_ready_for_enumeration - Check if the ACPI device is ready for enumeration
> >   * @device: Pointer to the &struct acpi_device to check
> >   *
> > - * Check if the device is present and has no unmet dependencies.
> > + * Check if the device is functional or enabled and has no unmet dependencies.
> >   *
> > - * Return true if the device is ready for enumeratino. Otherwise, return false.
> > + * Return true if the device is ready for enumeration. Otherwise, return false.
> >   */
> >  bool acpi_dev_ready_for_enumeration(const struct acpi_device *device)
> >  {
> >         if (device->flags.honor_deps && device->dep_unmet)
> >                 return false;
> >
> > -       return acpi_device_is_present(device);
> > +       /*
> > +        * ACPI 6.5's 6.3.7 "_STA (Device Status)" allows firmware to return
> > +        * (!present && functional) for certain types of devices that should be
> > +        * enumerated. Note that the enabled bit should not be set unless the
> > +        * present bit is set.
> > +        *
> > +        * However, limit this only to processor devices to reduce possible
> > +        * regressions with firmware.
> > +        */
> > +       if (!device->status.present)
> > +               return device->status.functional;
> > +
> > +       /*
> > +        * Fast path - if enabled is set, avoid the more expensive test to
> > +        * check whether this device is a processor.
> > +        */
> > +       if (device->status.enabled)
> > +               return true;
> > +
> > +       return !acpi_device_is_processor(device);
> >  }
> >  EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
> >
> > --  
> 
> I can queue this up for 6.9 as it looks like the rest of the series
> will still need some work.  What do you think?

The sooner this goes in the sooner we discover if some of the bios bug
workarounds we have dropped form the series are in reality necessary
(i.e. get it into big board test farms).

So I'm definitely keen to see this go in for 6.9.

Hopefully we can make rapid progress on the rest of the series and
hammer out which of the remaining subtle differences between
the two flows are real vs code evolution issues.

Jonathan


From apatel at ventanamicro.com  Mon Feb 19 01:45:37 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 19 Feb 2024 15:15:37 +0530
Subject: [PATCH v12 23/25] irqchip/riscv-aplic: Add support for MSI-mode
In-Reply-To: <8734tsce9o.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-24-apatel@ventanamicro.com> <8734tsce9o.ffs@tglx>
Message-ID: <CAK9=C2Vf63ZcETD-ja33tK11XARz+y5hg1dqjGP-bZTW-XNWHg@mail.gmail.com>

On Sat, Feb 17, 2024 at 2:34?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Sat, Jan 27 2024 at 21:47, Anup Patel wrote:
> > We extend the existing APLIC irqchip driver to support MSI-mode for
> > RISC-V platforms having both wired interrupts and MSIs.
>
> We? Just s/We//

Okay, I will update.

>
> > +
> > +static void aplic_msi_irq_unmask(struct irq_data *d)
> > +{
> > +     aplic_irq_unmask(d);
> > +     irq_chip_unmask_parent(d);
> > +}
> > +
> > +static void aplic_msi_irq_mask(struct irq_data *d)
> > +{
> > +     aplic_irq_mask(d);
> > +     irq_chip_mask_parent(d);
> > +}
>
> Again asymmetric vs. unmask()

Okay, I will update.

>
> > +static void aplic_msi_irq_eoi(struct irq_data *d)
> > +{
> > +     struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> > +     u32 reg_off, reg_mask;
> > +
> > +     /*
> > +      * EOI handling only required only for level-triggered
> > +      * interrupts in APLIC MSI mode.
> > +      */
> > +
> > +     reg_off = APLIC_CLRIP_BASE + ((d->hwirq / APLIC_IRQBITS_PER_REG) * 4);
> > +     reg_mask = BIT(d->hwirq % APLIC_IRQBITS_PER_REG);
> > +     switch (irqd_get_trigger_type(d)) {
> > +     case IRQ_TYPE_LEVEL_LOW:
> > +             if (!(readl(priv->regs + reg_off) & reg_mask))
> > +                     writel(d->hwirq, priv->regs + APLIC_SETIPNUM_LE);
>
> A comment what this condition is for would be nice.

Okay, I will add a comment about the condition.

Regards,
Anup


From maz at kernel.org  Mon Feb 19 01:48:28 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 09:48:28 +0000
Subject: next-20240219: arm64: boot failed - gic_of_init
In-Reply-To: <CA+G9fYugYiLd7MDn3wCxK+x5Td9WO-VUX2OvOtTN7D1d4GHCfg@mail.gmail.com>
References: <CA+G9fYugYiLd7MDn3wCxK+x5Td9WO-VUX2OvOtTN7D1d4GHCfg@mail.gmail.com>
Message-ID: <86edd84wer.wl-maz@kernel.org>

On Mon, 19 Feb 2024 09:42:45 +0000,
Naresh Kamboju <naresh.kamboju at linaro.org> wrote:
> 
> The qemu-arm64 boot failed with linux next-20240219 tag kernel.
> 
> Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>
> 
> Boot log:
> ---------
> <6>[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
> <1>[    0.000000] Unable to handle kernel paging request at virtual
> address ffff80008001ffe8
> <1>[    0.000000] Mem abort info:
> <1>[    0.000000]   ESR = 0x0000000096000004
> <1>[    0.000000]   EC = 0x25: DABT (current EL), IL = 32 bits
> <1>[    0.000000]   SET = 0, FnV = 0
> <1>[    0.000000]   EA = 0, S1PTW = 0
> <1>[    0.000000]   FSC = 0x04: level 0 translation fault
> <1>[    0.000000] Data abort info:
> <1>[    0.000000]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
> <1>[    0.000000]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> <1>[    0.000000]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> <1>[    0.000000] swapper pgtable: 4k pages, 52-bit VAs, pgdp=0000000042497000
> <1>[    0.000000] [ffff80008001ffe8] pgd=10000000439a5003,
> p4d=10000001000e3003, pud=10000001000e4003, pmd=10000001000e5003,
> pte=006800000800f413
> <0>[    0.000000] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
> <4>[    0.000000] Modules linked in:
> <4>[    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted
> 6.8.0-rc5-next-20240219 #1
> <4>[    0.000000] Hardware name: linux,dummy-virt (DT)
> <4>[    0.000000] pstate: 804000c9 (Nzcv daIF +PAN -UAO -TCO -DIT
> -SSBS BTYPE=--)
> <4>[    0.000000] pc : gic_of_init+0x84/0x3a8
> <4>[    0.000000] lr : gic_of_init+0x290/0x3a8
> ...
> <4>[    0.000000] Call trace:
> <4>[    0.000000]  gic_of_init+0x84/0x3a8
> <4>[    0.000000]  of_irq_init+0x1d4/0x3d0
> <4>[    0.000000]  irqchip_init+0x20/0x50
> <4>[    0.000000]  init_IRQ+0xa8/0xc8
> <4>[    0.000000]  start_kernel+0x270/0x690
> <4>[    0.000000]  __primary_switched+0x80/0x90
> <0>[    0.000000] Code: f94017e0 f90007e0 d29ffd00 8b0002c0 (b9400000)
> <4>[    0.000000] ---[ end trace 0000000000000000 ]---
> <0>[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
> <0>[    0.000000] ---[ end Kernel panic - not syncing: Attempted to
> kill the idle task! ]---
> 
> Links:
>  - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240219/testrun/22730192/suite/boot/test/gcc-13-lkftconfig-armv8_features/log
>  - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240219/testrun/22730192/suite/boot/tests/

Where is the configuration file? What are the parameters to QEMU?
Please consider making this a useful and actionable report.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From linux at armlinux.org.uk  Mon Feb 19 01:52:08 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 19 Feb 2024 09:52:08 +0000
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <xs2splnjhlj257uca5yae64fp4solc4ugbxrkczoyd75n42r66@42boyzdcmyj4>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
 <ZdMe24xN1Ej4QoVU@shell.armlinux.org.uk>
 <xs2splnjhlj257uca5yae64fp4solc4ugbxrkczoyd75n42r66@42boyzdcmyj4>
Message-ID: <ZdMkyPX/h9s8xht5@shell.armlinux.org.uk>

On Mon, Feb 19, 2024 at 04:40:00AM -0500, Kent Overstreet wrote:
> On Mon, Feb 19, 2024 at 09:26:51AM +0000, Russell King (Oracle) wrote:
> > On Mon, Feb 19, 2024 at 07:21:11AM +0100, Arnd Bergmann wrote:
> > > I think these should be addressed in bcachefs instead.
> > > While it's not the fault of bcachefs that the calling
> > > convention changed between gcc versions, have a look at
> > > the actual structure layout:
> > > 
> > > struct bch_val {
> > >         __u64           __nothing[0];
> > > };
> > > struct bpos {
> > >         /*
> > >          * Word order matches machine byte order - btree code treats a bpos as a
> > >          * single large integer, for search/comparison purposes
> > >          *
> > >          * Note that wherever a bpos is embedded in another on disk data
> > >          * structure, it has to be byte swabbed when reading in metadata that
> > >          * wasn't written in native endian order:
> > >          */
> > > #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
> > >         __u32           snapshot;
> > >         __u64           offset;
> > >         __u64           inode;
> > > #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
> > >         __u64           inode;
> > >         __u64           offset;         /* Points to end of extent - sectors */
> > >         __u32           snapshot;
> > > #else
> > > #error edit for your odd byteorder.
> > > #endif
> > > } __packed
> > > struct bch_backpointer {
> > >         struct bch_val          v;
> > >         __u8                    btree_id;
> > >         __u8                    level;
> > >         __u8                    data_type;
> > >         __u64                   bucket_offset:40;
> > >         __u32                   bucket_len;
> > >         struct bpos             pos;
> > > } __packed __aligned(8);
> > > 
> > > This is not something that should ever be passed by value
> > > into a function.
> > 
> > +1 - bcachefs definitely needs fixing. Passing all that as an argument
> > not only means that it has to be read into registers, but also when
> > accessing members, it has to be extracted from those registers as well.
> > 
> > Passing that by argument is utterly insane.
> 
> If the compiler people can't figure out a vaguely efficient way to pass
> a small struct by value, that's their problem - from the way you
> describe it, I have to wonder at what insanity is going on there.

It sounds like you have a personal cruisade here.

Passing structures on through function arguments is never efficient.
The entire thing _has_ to be loaded from memory at function call and
either placed onto the stack (creating an effective memcpy() on every
function call) or into registers. Fundamentally. It's not something
compiler people can mess around with.

Sorry but it's bcachefs that's the problem here, and well done to the
compiler people for pointing out stupid code.

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


From geert at linux-m68k.org  Mon Feb 19 01:54:14 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 19 Feb 2024 10:54:14 +0100 (CET)
Subject: Build regressions/improvements in v6.8-rc5
In-Reply-To: <20240219080729.777675-1-geert@linux-m68k.org>
References: <CAHk-=wi8vZD7EXZfob-yhfDERyfzWxzMOzG9FsOuaKU-v6+PHA@mail.gmail.com> <20240219080729.777675-1-geert@linux-m68k.org>
Message-ID: <a8609e7e-fb0-7ac-aca9-6aa21ba5126b@linux-m68k.org>

On Mon, 19 Feb 2024, Geert Uytterhoeven wrote:
> JFYI, when comparing v6.8-rc5[1] to v6.8-rc4[3], the summaries are:
>  - build errors: +6/-14

   + /kisskb/src/arch/arm64/include/asm/jump_label.h: error: invalid 'asm': invalid operand:  => 25:2

arm64-gcc5/arm64-allmodconfig

   + /kisskb/src/arch/sparc/kernel/setup_64.c: error: no previous prototype for 'alloc_irqstack_bootmem' [-Werror=missing-prototypes]:  => 602:13

sparc64-gcc{5,13}/sparc64-{allmod,allno,def}config

   + /kisskb/src/arch/sparc/kernel/time_64.c: error: no previous prototype for 'sched_clock' [-Werror=missing-prototypes]:  => 880:20

sparc64-gcc5/sparc64-{allmod,allno,def}config
sparc64-gcc13/sparc64-{allno,def}config

   + error: modpost: "__moddi3" [drivers/gpu/drm/tests/drm_buddy_test.ko] undefined!:  => N/A
   + error: modpost: "__umoddi3" [drivers/gpu/drm/tests/drm_buddy_test.ko] undefined!:  => N/A

m68k-gcc8/m68k-allmodconfig
xtensa-gcc13/xtensa-allmodconfig
parisc-gcc13/parisc-allmodconfig

Fixes available

   + {standard input}: Error: unknown pseudo-op: `.cfi_def_cfa_offse':  => 605

SH ICE crickets

> [1] http://kisskb.ellerman.id.au/kisskb/branch/linus/head/b401b621758e46812da61fa58a67c3fd8d91de0d/ (144 out of 239 configs)
> [3] http://kisskb.ellerman.id.au/kisskb/branch/linus/head/841c35169323cd833294798e58b9bf63fa4fa1de/ (238 out of 239 configs)

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 kent.overstreet at linux.dev  Mon Feb 19 01:56:51 2024
From: kent.overstreet at linux.dev (Kent Overstreet)
Date: Mon, 19 Feb 2024 04:56:51 -0500
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <ZdMkyPX/h9s8xht5@shell.armlinux.org.uk>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
 <ZdMe24xN1Ej4QoVU@shell.armlinux.org.uk>
 <xs2splnjhlj257uca5yae64fp4solc4ugbxrkczoyd75n42r66@42boyzdcmyj4>
 <ZdMkyPX/h9s8xht5@shell.armlinux.org.uk>
Message-ID: <fharyfc7fnh45dthgd2ehwsgdqzmdfptp7jw7gi5ahb6slwgf6@nrkhlhvbbzx7>

On Mon, Feb 19, 2024 at 09:52:08AM +0000, Russell King (Oracle) wrote:
> On Mon, Feb 19, 2024 at 04:40:00AM -0500, Kent Overstreet wrote:
> > On Mon, Feb 19, 2024 at 09:26:51AM +0000, Russell King (Oracle) wrote:
> > > On Mon, Feb 19, 2024 at 07:21:11AM +0100, Arnd Bergmann wrote:
> > > > I think these should be addressed in bcachefs instead.
> > > > While it's not the fault of bcachefs that the calling
> > > > convention changed between gcc versions, have a look at
> > > > the actual structure layout:
> > > > 
> > > > struct bch_val {
> > > >         __u64           __nothing[0];
> > > > };
> > > > struct bpos {
> > > >         /*
> > > >          * Word order matches machine byte order - btree code treats a bpos as a
> > > >          * single large integer, for search/comparison purposes
> > > >          *
> > > >          * Note that wherever a bpos is embedded in another on disk data
> > > >          * structure, it has to be byte swabbed when reading in metadata that
> > > >          * wasn't written in native endian order:
> > > >          */
> > > > #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
> > > >         __u32           snapshot;
> > > >         __u64           offset;
> > > >         __u64           inode;
> > > > #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
> > > >         __u64           inode;
> > > >         __u64           offset;         /* Points to end of extent - sectors */
> > > >         __u32           snapshot;
> > > > #else
> > > > #error edit for your odd byteorder.
> > > > #endif
> > > > } __packed
> > > > struct bch_backpointer {
> > > >         struct bch_val          v;
> > > >         __u8                    btree_id;
> > > >         __u8                    level;
> > > >         __u8                    data_type;
> > > >         __u64                   bucket_offset:40;
> > > >         __u32                   bucket_len;
> > > >         struct bpos             pos;
> > > > } __packed __aligned(8);
> > > > 
> > > > This is not something that should ever be passed by value
> > > > into a function.
> > > 
> > > +1 - bcachefs definitely needs fixing. Passing all that as an argument
> > > not only means that it has to be read into registers, but also when
> > > accessing members, it has to be extracted from those registers as well.
> > > 
> > > Passing that by argument is utterly insane.
> > 
> > If the compiler people can't figure out a vaguely efficient way to pass
> > a small struct by value, that's their problem - from the way you
> > describe it, I have to wonder at what insanity is going on there.
> 
> It sounds like you have a personal cruisade here.
> 
> Passing structures on through function arguments is never efficient.
> The entire thing _has_ to be loaded from memory at function call and
> either placed onto the stack (creating an effective memcpy() on every
> function call) or into registers. Fundamentally. It's not something
> compiler people can mess around with.
> 
> Sorry but it's bcachefs that's the problem here, and well done to the
> compiler people for pointing out stupid code.

Eh? Passing via stack copy is normal and expected; you were talking
about something else.

I'm not always trying to write code that will generate the fastest
assembly possible; there aro other considerations. As long a the
compiler is doing something /reasonable/, the code is fine.


From arnd at arndb.de  Mon Feb 19 01:57:46 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 19 Feb 2024 10:57:46 +0100
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <xs2splnjhlj257uca5yae64fp4solc4ugbxrkczoyd75n42r66@42boyzdcmyj4>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
 <ZdMe24xN1Ej4QoVU@shell.armlinux.org.uk>
 <xs2splnjhlj257uca5yae64fp4solc4ugbxrkczoyd75n42r66@42boyzdcmyj4>
Message-ID: <7299839b-06e6-40eb-8024-93ed5f9b733f@app.fastmail.com>

On Mon, Feb 19, 2024, at 10:40, Kent Overstreet wrote:
> On Mon, Feb 19, 2024 at 09:26:51AM +0000, Russell King (Oracle) wrote:
>> On Mon, Feb 19, 2024 at 07:21:11AM +0100, Arnd Bergmann wrote:
>> 
>> +1 - bcachefs definitely needs fixing. Passing all that as an argument
>> not only means that it has to be read into registers, but also when
>> accessing members, it has to be extracted from those registers as well.
>> 
>> Passing that by argument is utterly insane.
>
> If the compiler people can't figure out a vaguely efficient way to pass
> a small struct by value, that's their problem - from the way you
> describe it, I have to wonder at what insanity is going on there.

On most ABIs, there are only six argument registers (24 bytes)
for function calls. The compiler has very little choice here if
it tries to pass 32 bytes worth of data.

On both x86_64 and arm64, there are theoretically enough
registers to pass the data, but kernel disallows using the
vector and floating point registers for passing large
compounds arguments.

The integer registers on x86 apparently allow passing compounds
up to 16 bytes, but only if all members are naturally aligned.
Since you have both __packed members and bitfields, the compiler
would not even be allowed to pass the structure efficiently
even if it was small enough.

      Arnd


From angelogioacchino.delregno at collabora.com  Mon Feb 19 02:00:34 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 11:00:34 +0100
Subject: [PATCH v2 2/2] arm64: dts: mediatek: add Kontron 3.5"-SBC-i1200
In-Reply-To: <20240219084456.1075445-2-mwalle@kernel.org>
References: <20240219084456.1075445-1-mwalle@kernel.org>
 <20240219084456.1075445-2-mwalle@kernel.org>
Message-ID: <2ad6bda8-a457-421b-b35d-dc005fb00ae9@collabora.com>

Il 19/02/24 09:44, Michael Walle ha scritto:
> Add basic support for the Kontron 3.5" single board computer featuring a
> Mediatek i1200 SoC (MT8395/MT8195).
> 
> Signed-off-by: Michael Walle <mwalle at kernel.org>
> ---
> v2:
>   - none
> 
>   arch/arm64/boot/dts/mediatek/Makefile         |    1 +
>   .../mediatek/mt8395-kontron-3-5-sbc-i1200.dts | 1091 +++++++++++++++++
>   2 files changed, 1092 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
> 
> diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
> index 37b4ca3a87c9..697b6b5de3cb 100644
> --- a/arch/arm64/boot/dts/mediatek/Makefile
> +++ b/arch/arm64/boot/dts/mediatek/Makefile
> @@ -76,5 +76,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-kontron-3-5-sbc-i1200.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
> diff --git a/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts b/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
> new file mode 100644
> index 000000000000..0c634bc8776c
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
> @@ -0,0 +1,1091 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (C) 2024 Kontron Europe GmbH
> + *
> + * Author: Michael Walle <mwalle at kernel.org>
> + */
> +/dts-v1/;
> +
> +#include "mt8195.dtsi"
> +#include "mt6359.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/leds/common.h>
> +#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
> +#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
> +#include <dt-bindings/spmi/spmi.h>
> +
> +/ {
> +	model = "Kontron 3.5\"-SBC-i1200";
> +	compatible = "kontron,3-5-sbc-i1200", "mediatek,mt8395", "mediatek,mt8195";
> +
> +	aliases {
> +		mmc0 = &mmc0;
> +		mmc1 = &mmc1;
> +		serial0 = &uart1;
> +		serial1 = &uart2;
> +		serial2 = &uart3;
> +		serial3 = &uart4;
> +		serial4 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	firmware {
> +		optee {
> +			compatible = "linaro,optee-tz";
> +			method = "smc";
> +		};
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&gpio_keys_pins>;
> +
> +		key-0 {
> +			gpios = <&pio 106 GPIO_ACTIVE_LOW>;
> +			label = "volume_up";
> +			linux,code = <KEY_VOLUMEUP>;
> +			wakeup-source;
> +			debounce-interval = <15>;
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&led_pins>;
> +
> +		led-0 {
> +			gpios = <&pio 107 GPIO_ACTIVE_HIGH>;
> +			default-state = "keep";
> +			function = LED_FUNCTION_POWER;
> +			color = <LED_COLOR_ID_GREEN>;
> +		};
> +	};
> +
> +	memory at 40000000 {
> +		device_type = "memory";
> +		reg = <0 0x40000000 0x0 0x80000000>;
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		/*
> +		 * 12 MiB reserved for OP-TEE (BL32)
> +		 * +-----------------------+ 0x43e0_0000
> +		 * |      SHMEM 2MiB       |
> +		 * +-----------------------+ 0x43c0_0000
> +		 * |        | TA_RAM  8MiB |
> +		 * + TZDRAM +--------------+ 0x4340_0000
> +		 * |        | TEE_RAM 2MiB |
> +		 * +-----------------------+ 0x4320_0000
> +		 */
> +		optee_reserved: optee at 43200000 {
> +			no-map;
> +			reg = <0 0x43200000 0 0x00c00000>;
> +		};
> +
> +		scp_mem: memory at 50000000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0 0x50000000 0 0x2900000>;
> +			no-map;
> +		};
> +
> +		vpu_mem: memory at 53000000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0 0x53000000 0 0x1400000>; /* 20 MB */
> +		};
> +
> +		/* 2 MiB reserved for ARM Trusted Firmware (BL31) */
> +		bl31_secmon_mem: memory at 54600000 {
> +			no-map;
> +			reg = <0 0x54600000 0x0 0x200000>;
> +		};
> +
> +		snd_dma_mem: memory at 60000000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0 0x60000000 0 0x1100000>;
> +			no-map;
> +		};
> +
> +		apu_mem: memory at 62000000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0 0x62000000 0 0x1400000>; /* 20 MB */
> +		};
> +	};
> +
> +	thermal_sensor0: thermal-sensor-0 {
> +		compatible = "generic-adc-thermal";
> +		#thermal-sensor-cells = <0>;
> +		io-channels = <&auxadc 0>;
> +		io-channel-names = "sensor-channel";
> +		temperature-lookup-table = <(-25000) 1474
> +					    (-20000) 1374
> +					    (-15000) 1260
> +					    (-10000) 1134
> +					     (-5000) 1004
> +						   0 874
> +						5000 750
> +					       10000 635
> +					       15000 532
> +					       20000 443
> +					       25000 367
> +					       30000 303
> +					       35000 250
> +					       40000 206
> +					       45000 170
> +					       50000 141
> +					       55000 117
> +					       60000 97
> +					       65000 81
> +					       70000 68
> +					       75000 57
> +					       80000 48
> +					       85000 41
> +					       90000 35
> +					       95000 30
> +					      100000 25
> +					      105000 22
> +					      110000 19
> +					      115000 16
> +					      120000 14
> +					      125000 12
> +					      130000 10
> +					      135000 9
> +					      140000 8
> +					      145000 7
> +					      150000 6>;
> +	};
> +
> +	thermal_sensor1: thermal-sensor-1 {
> +		compatible = "generic-adc-thermal";
> +		#thermal-sensor-cells = <0>;
> +		io-channels = <&auxadc 1>;
> +		io-channel-names = "sensor-channel";
> +		temperature-lookup-table = <(-25000) 1474
> +					    (-20000) 1374
> +					    (-15000) 1260
> +					    (-10000) 1134
> +					     (-5000) 1004
> +						   0 874
> +						5000 750
> +					       10000 635
> +					       15000 532
> +					       20000 443
> +					       25000 367
> +					       30000 303
> +					       35000 250
> +					       40000 206
> +					       45000 170
> +					       50000 141
> +					       55000 117
> +					       60000 97
> +					       65000 81
> +					       70000 68
> +					       75000 57
> +					       80000 48
> +					       85000 41
> +					       90000 35
> +					       95000 30
> +					      100000 25
> +					      105000 22
> +					      110000 19
> +					      115000 16
> +					      120000 14
> +					      125000 12
> +					      130000 10
> +					      135000 9
> +					      140000 8
> +					      145000 7
> +					      150000 6>;
> +	};
> +
> +	thermal_sensor2: thermal-sensor-2 {
> +		compatible = "generic-adc-thermal";
> +		#thermal-sensor-cells = <0>;
> +		io-channels = <&auxadc 2>;
> +		io-channel-names = "sensor-channel";
> +		temperature-lookup-table = <(-25000) 1474
> +					    (-20000) 1374
> +					    (-15000) 1260
> +					    (-10000) 1134
> +					     (-5000) 1004
> +						   0 874
> +						5000 750
> +					       10000 635
> +					       15000 532
> +					       20000 443
> +					       25000 367
> +					       30000 303
> +					       35000 250
> +					       40000 206
> +					       45000 170
> +					       50000 141
> +					       55000 117
> +					       60000 97
> +					       65000 81
> +					       70000 68
> +					       75000 57
> +					       80000 48
> +					       85000 41
> +					       90000 35
> +					       95000 30
> +					      100000 25
> +					      105000 22
> +					      110000 19
> +					      115000 16
> +					      120000 14
> +					      125000 12
> +					      130000 10
> +					      135000 9
> +					      140000 8
> +					      145000 7
> +					      150000 6>;
> +	};
> +};
> +
> +&auxadc {
> +	status = "okay";
> +};
> +
> +&eth {
> +	phy-mode ="rgmii-id";
> +	phy-handle = <&ethernet_phy0>;
> +	snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>;
> +	snps,reset-delays-us = <0 10000 80000>;

snps,reset-delays-us and snps,reset-gpio are deprecated.

> +	pinctrl-names = "default", "sleep";
> +	pinctrl-0 = <&eth_default_pins>;
> +	pinctrl-1 = <&eth_sleep_pins>;
> +	status = "okay";
> +
> +	mdio {
> +		ethernet_phy0: ethernet-phy at 1 {

compatible = "is there any applicable compatible?"
P.S.: if you've got the usual rtl8211f, should be "ethernet-phy-id001c.c916"

reg = <0x1>;
interrupts-extended = <&pio 94 IRQ_TYPE_LEVEL_LOW>;
reset-assert-us = <10000>;
reset-deassert-us = <80000>;
reset-gpios = <&pio 93 GPIO_ACTIVE_HIGH>;


> +			reg = <0x1>;
> +			interrupts-extended = <&pio 94 IRQ_TYPE_LEVEL_LOW>;
> +		};
> +	};
> +};
> +
> +&gpu {
> +	status = "okay";
> +	mali-supply = <&mt6315_7_vbuck1>;
> +};
> +
> +&i2c2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c2_pins>;
> +	clock-frequency = <400000>;
> +	status = "okay";

Are i2c2,3,4 exposed as pins somewhere? If they are, can you please put a
comment saying so?

This is not mandatory, but IMO it's nice to have as a kind of documentation.

> +};
> +
> +&i2c3 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c3_pins>;
> +	clock-frequency = <100000>;
> +	status = "okay";
> +};
> +
> +&i2c4 {
> +	clock-frequency = <100000>;
> +	pinctrl-0 = <&i2c4_pins>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +};
> +
> +&i2c6 {
> +	clock-frequency = <400000>;
> +	pinctrl-0 = <&i2c6_pins>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +
> +	mt6360: pmic at 34 {
> +		compatible = "mediatek,mt6360";
> +		reg = <0x34>;
> +		interrupt-controller;
> +		interrupts-extended = <&pio 101 IRQ_TYPE_EDGE_FALLING>;
> +		interrupt-names = "IRQB";

#interrupt-cells = <1>;

> +
> +		charger {
> +			compatible = "mediatek,mt6360-chg";
> +			richtek,vinovp-microvolt = <14500000>;
> +
> +			otg_vbus_regulator: usb-otg-vbus-regulator {
> +				regulator-compatible = "usb-otg-vbus";

The regulator-compatible property is deprecated. Please don't use it.

> +				regulator-name = "usb-otg-vbus";
> +				regulator-min-microvolt = <4425000>;
> +				regulator-max-microvolt = <5825000>;
> +			};
> +		};
> +
> +		regulator {
> +			compatible = "mediatek,mt6360-regulator";
> +			LDO_VIN3-supply = <&mt6360_buck2>;
> +
> +			mt6360_buck1: buck1 {
> +				regulator-compatible = "BUCK1";

same here and everywhere else.

> +				regulator-name = "mt6360,buck1";
> +				regulator-min-microvolt = <300000>;
> +				regulator-max-microvolt = <1300000>;
> +				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
> +							   MT6360_OPMODE_LP
> +							   MT6360_OPMODE_ULP>;
> +				regulator-always-on;
> +			};
> +
> +			mt6360_buck2: buck2 {
> +				regulator-compatible = "BUCK2";
> +				regulator-name = "mt6360,buck2";
> +				regulator-min-microvolt = <300000>;
> +				regulator-max-microvolt = <1300000>;
> +				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
> +							   MT6360_OPMODE_LP
> +							   MT6360_OPMODE_ULP>;
> +				regulator-always-on;
> +			};
> +
> +			mt6360_ldo1: ldo1 {
> +				regulator-compatible = "LDO1";
> +				regulator-name = "mt6360,ldo1";
> +				regulator-min-microvolt = <1200000>;
> +				regulator-max-microvolt = <3600000>;
> +				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
> +							   MT6360_OPMODE_LP>;
> +			};
> +
> +			mt6360_ldo2: ldo2 {
> +				regulator-compatible = "LDO2";
> +				regulator-name = "mt6360,ldo2";
> +				regulator-min-microvolt = <1200000>;
> +				regulator-max-microvolt = <3600000>;
> +				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
> +							   MT6360_OPMODE_LP>;
> +			};
> +
> +			mt6360_ldo3: ldo3 {
> +				regulator-compatible = "LDO3";
> +				regulator-name = "mt6360,ldo3";
> +				regulator-min-microvolt = <1200000>;
> +				regulator-max-microvolt = <3600000>;
> +				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
> +							   MT6360_OPMODE_LP>;
> +			};
> +
> +			mt6360_ldo5: ldo5 {
> +				regulator-compatible = "LDO5";
> +				regulator-name = "mt6360,ldo5";
> +				regulator-min-microvolt = <2700000>;
> +				regulator-max-microvolt = <3600000>;
> +				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
> +							   MT6360_OPMODE_LP>;
> +			};
> +
> +			mt6360_ldo6: ldo6 {
> +				regulator-compatible = "LDO6";
> +				regulator-name = "mt6360,ldo6";
> +				regulator-min-microvolt = <500000>;
> +				regulator-max-microvolt = <2100000>;
> +				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
> +							   MT6360_OPMODE_LP>;
> +			};
> +
> +			mt6360_ldo7: ldo7 {
> +				regulator-compatible = "LDO7";
> +				regulator-name = "mt6360,ldo7";
> +				regulator-min-microvolt = <500000>;
> +				regulator-max-microvolt = <2100000>;
> +				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
> +							   MT6360_OPMODE_LP>;
> +				regulator-always-on;
> +			};
> +		};
> +	};
> +};
> +
> +&mmc0 {

This is not wrong, but can we please keep the ordering consistent between boards?

	pinctrl-names = "default", "state_uhs";
	pinctrl-0 = <&mmc0_default_pins>;
	pinctrl-1 = <&mmc0_uhs_pins>;
	bus-width = <8>;
	max-frequency = <200000000>;
	hs400-ds-delay = <0x14c11>;
	cap-mmc-highspeed;
	cap-mmc-hw-reset;
	mmc-hs200-1_8v;
	mmc-hs400-1_8v;
	no-sdio;
	no-sd;
	non-removable;
	vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
	vqmmc-supply = <&mt6359_vufs_ldo_reg>;

> +	pinctrl-names = "default", "state_uhs";
> +	pinctrl-0 = <&mmc0_default_pins>;
> +	pinctrl-1 = <&mmc0_uhs_pins>;
> +	bus-width = <8>;
> +	max-frequency = <200000000>;
> +	cap-mmc-highspeed;
> +	mmc-hs200-1_8v;
> +	mmc-hs400-1_8v;
> +	cap-mmc-hw-reset;
> +	no-sdio;
> +	no-sd;
> +	hs400-ds-delay = <0x14c11>;
> +	vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
> +	vqmmc-supply = <&mt6359_vufs_ldo_reg>;
> +	non-removable;
> +	status = "okay";
> +};
> +
> +&mmc1 {
> +	pinctrl-names = "default", "state_uhs";
> +	pinctrl-0 = <&mmc1_default_pins>;
> +	pinctrl-1 = <&mmc1_uhs_pins>;
> +	cd-gpios = <&pio 129 GPIO_ACTIVE_LOW>;
> +	bus-width = <4>;
> +	max-frequency = <200000000>;
> +	cap-sd-highspeed;
> +	sd-uhs-sdr50;
> +	sd-uhs-sdr104;
> +	vmmc-supply = <&mt6360_ldo5>;
> +	vqmmc-supply = <&mt6360_ldo3>;

Does mmc1 support eMMC and SDIO?

If not, no-mmc; no-sdio;

> +	status = "okay";
> +};
> +
> +&mt6359_vbbck_ldo_reg {
> +	regulator-always-on;
> +};
> +
> +&mt6359_vcore_buck_reg {
> +	regulator-always-on;
> +};
> +
> +&mt6359_vgpu11_buck_reg {
> +	regulator-always-on;
> +};
> +
> +&mt6359_vproc1_buck_reg {
> +	regulator-always-on;
> +};
> +
> +&mt6359_vproc2_buck_reg {
> +	regulator-always-on;
> +};
> +
> +&mt6359_vpu_buck_reg {
> +	regulator-always-on;
> +};
> +
> +&mt6359_vrf12_ldo_reg {
> +	regulator-always-on;
> +};
> +
> +&mt6359_vsram_md_ldo_reg {
> +	regulator-always-on;
> +};
> +
> +&mt6359_vsram_others_ldo_reg {
> +	regulator-always-on;
> +};
> +
> +&nor_flash {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&nor_pins_default>;
> +	status = "okay";
> +
> +	flash at 0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0>;
> +		spi-max-frequency = <52000000>;
> +		spi-rx-bus-width = <2>;
> +		spi-tx-bus-width = <2>;
> +	};
> +};
> +
> +&pcie0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie0_pins_default>;
> +	status = "okay";
> +};
> +
> +&pcie1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pcie1_pins_default>;
> +	status = "okay";
> +};
> +
> +&pciephy {
> +	status = "okay";
> +};
> +
> +&pio {
> +	eth_default_pins: eth-default-pins {
> +		pins-txd {
> +			pinmux = <PINMUX_GPIO77__FUNC_GBE_TXD3>,
> +				 <PINMUX_GPIO78__FUNC_GBE_TXD2>,
> +				 <PINMUX_GPIO79__FUNC_GBE_TXD1>,
> +				 <PINMUX_GPIO80__FUNC_GBE_TXD0>;
> +			drive-strength = <MTK_DRIVE_8mA>;
> +		};
> +
> +		pins-rxd {
> +			pinmux = <PINMUX_GPIO81__FUNC_GBE_RXD3>,
> +				 <PINMUX_GPIO82__FUNC_GBE_RXD2>,
> +				 <PINMUX_GPIO83__FUNC_GBE_RXD1>,
> +				 <PINMUX_GPIO84__FUNC_GBE_RXD0>;
> +		};
> +
> +		pins-cc {
> +			pinmux = <PINMUX_GPIO85__FUNC_GBE_TXC>,
> +				 <PINMUX_GPIO86__FUNC_GBE_RXC>,
> +				 <PINMUX_GPIO87__FUNC_GBE_RXDV>,
> +				 <PINMUX_GPIO88__FUNC_GBE_TXEN>;
> +			drive-strength = <MTK_DRIVE_8mA>;

s/MTK_DRIVE//g
s/mA//g

drive-strength = <8>;

Please, here and everywhere else, for all values - let's stop using those
MTK_DRIVE_(x)mA definitions, they're just defined as (x), where anyway
the drive-strength property is in milliamps by default.

We don't need these definitions.

> +		};
> +
> +		pins-mdio {
> +			pinmux = <PINMUX_GPIO89__FUNC_GBE_MDC>,
> +				 <PINMUX_GPIO90__FUNC_GBE_MDIO>;
> +			input-enable;
> +		};
> +
> +		pins-power {
> +			pinmux = <PINMUX_GPIO91__FUNC_GPIO91>,
> +				 <PINMUX_GPIO92__FUNC_GPIO92>;
> +			output-high;
> +		};
> +
> +		pins-reset {
> +			pinmux = <PINMUX_GPIO93__FUNC_GPIO93>;
> +			output-high;
> +		};
> +
> +		pins-interrupt {
> +			pinmux = <PINMUX_GPIO94__FUNC_GPIO94>;
> +			input-enable;
> +		};
> +	};
> +
> +	eth_sleep_pins: eth-sleep-pins {
> +		pins-txd {
> +			pinmux = <PINMUX_GPIO77__FUNC_GPIO77>,
> +				 <PINMUX_GPIO78__FUNC_GPIO78>,
> +				 <PINMUX_GPIO79__FUNC_GPIO79>,
> +				 <PINMUX_GPIO80__FUNC_GPIO80>;
> +		};
> +		pins-cc {
> +			pinmux = <PINMUX_GPIO85__FUNC_GPIO85>,
> +				 <PINMUX_GPIO88__FUNC_GPIO88>,
> +				 <PINMUX_GPIO87__FUNC_GPIO87>,
> +				 <PINMUX_GPIO86__FUNC_GPIO86>;
> +		};
> +		pins-rxd {
> +			pinmux = <PINMUX_GPIO81__FUNC_GPIO81>,
> +				 <PINMUX_GPIO82__FUNC_GPIO82>,
> +				 <PINMUX_GPIO83__FUNC_GPIO83>,
> +				 <PINMUX_GPIO84__FUNC_GPIO84>;
> +		};
> +		pins-mdio {
> +			pinmux = <PINMUX_GPIO89__FUNC_GPIO89>,
> +				 <PINMUX_GPIO90__FUNC_GPIO90>;
> +			input-disable;
> +			bias-disable;
> +		};
> +	};
> +
> +	gpio_keys_pins: gpio-keys-pins {
> +		pins {
> +			pinmux = <PINMUX_GPIO106__FUNC_GPIO106>;
> +			input-enable;
> +		};
> +	};
> +
> +	i2c2_pins: i2c2-default-pins {
> +		pins-bus {
> +			pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
> +				 <PINMUX_GPIO13__FUNC_SCL2>;
> +			bias-pull-up;
> +		};
> +	};
> +
> +	i2c3_pins: i2c3-pins {
> +		pins {
> +			pinmux = <PINMUX_GPIO14__FUNC_SDA3>,
> +				 <PINMUX_GPIO15__FUNC_SCL3>;
> +			bias-pull-up;
> +		};
> +	};
> +
> +	i2c4_pins: i2c4-pins {
> +		pins {
> +			pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
> +				 <PINMUX_GPIO17__FUNC_SCL4>;
> +			bias-pull-up;
> +		};
> +	};
> +
> +	i2c6_pins: i2c6-pins {
> +		pins {
> +			pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
> +				 <PINMUX_GPIO26__FUNC_SCL6>;
> +			bias-pull-up;
> +		};
> +	};
> +
> +	mmc0_default_pins: mmc0-default-pins {
> +		pins-clk {
> +			pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
> +			drive-strength = <MTK_DRIVE_6mA>;

drive-strength = <6>; etc :-)

> +			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
> +		};
> +
> +		pins-cmd-dat {
> +			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
> +				 <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
> +				 <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
> +				 <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
> +				 <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
> +				 <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
> +				 <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
> +				 <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
> +				 <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
> +			input-enable;
> +			drive-strength = <MTK_DRIVE_6mA>;
> +			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +		};
> +
> +		pins-rst {
> +			pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
> +			drive-strength = <MTK_DRIVE_6mA>;
> +			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +		};
> +	};
> +
> +	mmc0_uhs_pins: mmc0-uhs-pins {
> +		pins-clk {
> +			pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
> +			drive-strength = <MTK_DRIVE_8mA>;
> +			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
> +		};
> +
> +		pins-cmd-dat {
> +			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
> +				 <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
> +				 <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
> +				 <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
> +				 <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
> +				 <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
> +				 <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
> +				 <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
> +				 <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
> +			input-enable;
> +			drive-strength = <MTK_DRIVE_8mA>;
> +			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +		};
> +
> +		pins-ds {
> +			pinmux = <PINMUX_GPIO127__FUNC_MSDC0_DSL>;
> +			drive-strength = <MTK_DRIVE_8mA>;
> +			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
> +		};
> +
> +		pins-rst {
> +			pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
> +			drive-strength = <MTK_DRIVE_8mA>;
> +			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +		};
> +	};
> +
> +	mmc1_default_pins: mmc1-default-pins {
> +		pins-clk {
> +			pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
> +			drive-strength = <MTK_DRIVE_8mA>;
> +			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
> +		};
> +
> +		pins-cmd-dat {
> +			pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
> +				 <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
> +				 <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
> +				 <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
> +				 <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
> +			input-enable;
> +			drive-strength = <MTK_DRIVE_8mA>;
> +			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +		};
> +
> +		pins-insert {
> +			pinmux = <PINMUX_GPIO129__FUNC_GPIO129>;
> +			bias-pull-up;
> +		};
> +	};

MMC1 UHS and DEFAULT are exactly the same, you don't need to define those twice.
Here's how we can clean up this block:

	mmc1_default_pins: mmc1-default-pins {
		pins-clk {
			pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
			drive-strength = <8>;
		};

		pins-cmd-dat {
			pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
				 <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
				 <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
				 <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
				 <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
			drive-strength = <8>;
			input-enable;
		};
	};

	mmc1_pins_detect: mmc1-detect-pins {
		pins-insert {
			pinmux = <PINMUX_GPIO129__FUNC_GPIO129>;
			bias-pull-up;
		};
	};

&mmc1 {
	pinctrl-names = "default", "state_uhs";
	pinctrl-0 = <&mmc1_default_pins>, <&mmc1_pins_detect>;
	pinctrl-1 = <&mmc1_default_pins>;
	....
}


> +
> +	mmc1_uhs_pins: mmc1-uhs-pins {
> +		pins-clk {
> +			pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
> +			drive-strength = <MTK_DRIVE_8mA>;
> +			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
> +		};
> +
> +		pins-cmd-dat {
> +			pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
> +				 <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
> +				 <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
> +				 <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
> +				 <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
> +			input-enable;
> +			drive-strength = <MTK_DRIVE_8mA>;
> +			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +		};
> +	};
> +
> +	nor_pins_default: nor-default-pins {
> +		pins-ck-io {
> +			pinmux = <PINMUX_GPIO142__FUNC_SPINOR_IO0>,
> +				 <PINMUX_GPIO141__FUNC_SPINOR_CK>,
> +				 <PINMUX_GPIO143__FUNC_SPINOR_IO1>;
> +			drive-strength = <6>;
> +			bias-pull-down;
> +		};
> +
> +		pins-cs {
> +			pinmux = <PINMUX_GPIO140__FUNC_SPINOR_CS>;
> +			drive-strength = <6>;
> +			bias-pull-up;
> +		};
> +	};
> +
> +	pcie0_pins_default: pcie0-default-pins {
> +		pins-bus {
> +			pinmux = <PINMUX_GPIO19__FUNC_WAKEN>,
> +				 <PINMUX_GPIO20__FUNC_PERSTN>,
> +				 <PINMUX_GPIO21__FUNC_CLKREQN>;
> +			bias-pull-up;
> +		};
> +	};
> +
> +	pcie1_pins_default: pcie1-default-pins {
> +		pins-bus {
> +			pinmux = <PINMUX_GPIO0__FUNC_PERSTN_1>,
> +				 <PINMUX_GPIO1__FUNC_CLKREQN_1>,
> +				 <PINMUX_GPIO2__FUNC_WAKEN_1>;
> +			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +		};
> +	};
> +
> +	led_pins: led-pins {
> +		pins-power-en {
> +			pinmux = <PINMUX_GPIO107__FUNC_GPIO107>;
> +			output-high;
> +		};
> +	};
> +
> +	spi0_pins: spi0-default-pins {
> +		pins-cs-mosi-clk {
> +			pinmux = <PINMUX_GPIO132__FUNC_SPIM0_CSB>,
> +				 <PINMUX_GPIO134__FUNC_SPIM0_MO>,
> +				 <PINMUX_GPIO133__FUNC_SPIM0_CLK>;
> +			bias-disable;
> +		};
> +
> +		pins-miso {
> +			pinmux = <PINMUX_GPIO135__FUNC_SPIM0_MI>;
> +			bias-pull-down;
> +		};
> +	};
> +
> +	spi1_pins: spi1-default-pins {
> +		pins-cs-mosi-clk {
> +			pinmux = <PINMUX_GPIO136__FUNC_SPIM1_CSB>,
> +				 <PINMUX_GPIO138__FUNC_SPIM1_MO>,
> +				 <PINMUX_GPIO137__FUNC_SPIM1_CLK>;
> +			bias-disable;
> +		};
> +
> +		pins-miso {
> +			pinmux = <PINMUX_GPIO139__FUNC_SPIM1_MI>;
> +			bias-pull-down;
> +		};
> +	};
> +
> +	uart0_pins: uart0-pins {
> +		pins_rx {

No underscores, please.

> +			pinmux = <PINMUX_GPIO99__FUNC_URXD0>;
> +			input-enable;
> +			bias-pull-up;
> +		};
> +
> +		pins_tx {
> +			pinmux = <PINMUX_GPIO98__FUNC_UTXD0>;
> +		};
> +	};
> +
> +	uart1_pins: uart1-pins {
> +		pins_rx {
> +			pinmux = <PINMUX_GPIO103__FUNC_URXD1>;
> +			input-enable;
> +			bias-pull-up;
> +		};
> +
> +		pins_tx {
> +			pinmux = <PINMUX_GPIO102__FUNC_UTXD1>;
> +		};
> +
> +		pins_rts {
> +			pinmux = <PINMUX_GPIO100__FUNC_URTS1>;
> +			output-enable;

Are you really sure that you need output-enable here?!
RTS is not an output buffer....

I don't think you do. Please double check.

> +		};
> +
> +		pins_cts {
> +			pinmux = <PINMUX_GPIO101__FUNC_UCTS1>;
> +			input-enable;
> +		};
> +	};
> +
> +	uart2_pins: uart2-pins {
> +		pins_rx {
> +			pinmux = <PINMUX_GPIO68__FUNC_URXD2>;
> +			input-enable;
> +			bias-pull-up;
> +		};
> +
> +		pins_tx {
> +			pinmux = <PINMUX_GPIO67__FUNC_UTXD2>;
> +		};
> +
> +		pins_rts {
> +			pinmux = <PINMUX_GPIO66__FUNC_URTS2>;
> +			output-enable;
> +		};
> +
> +		pins_cts {
> +			pinmux = <PINMUX_GPIO65__FUNC_UCTS2>;
> +			input-enable;
> +		};
> +	};
> +
> +	uart3_pins: uart3-pins {
> +		pins_rx {
> +			pinmux = <PINMUX_GPIO5__FUNC_URXD3>;
> +			input-enable;
> +			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +		};
> +
> +		pins_tx {
> +			pinmux = <PINMUX_GPIO4__FUNC_UTXD3>;
> +		};
> +	};
> +
> +	uart4_pins: uart4-pins {
> +		pins_rx {
> +			pinmux = <PINMUX_GPIO7__FUNC_URXD4>;
> +			input-enable;
> +			bias-pull-up;
> +		};
> +
> +		pins_tx {
> +			pinmux = <PINMUX_GPIO6__FUNC_UTXD4>;
> +		};
> +	};
> +};
> +
> +&pmic {
> +	interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&scp {
> +	memory-region = <&scp_mem>;
> +	status = "okay";
> +};
> +
> +&spmi {
> +	#address-cells = <2>;
> +	#size-cells = <0>;
> +
> +	mt6315 at 6 {
> +		compatible = "mediatek,mt6315-regulator";
> +		reg = <0x6 SPMI_USID>;
> +
> +		regulators {
> +			mt6315_6_vbuck1: vbuck1 {
> +				regulator-compatible = "vbuck1";

We should check if we can avoid using regulator-compatible on mt6315 as well...
I honestly never checked if this is possible, but I think it is.

Eventually, if you can check and verify that it's not needed, we should even
remove that from all devicetrees, but that's not entirely relevant for this
patch anyway.

I'm just saying my plans out loud :-)

> +				regulator-name = "Vbcpu";
> +				regulator-min-microvolt = <300000>;
> +				regulator-max-microvolt = <1193750>;
> +				regulator-enable-ramp-delay = <256>;
> +				regulator-ramp-delay = <6250>;
> +				regulator-allowed-modes = <0 1 2>;
> +				regulator-always-on;
> +			};
> +		};
> +	};
> +
> +	mt6315 at 7 {
> +		compatible = "mediatek,mt6315-regulator";
> +		reg = <0x7 SPMI_USID>;
> +
> +		regulators {
> +			mt6315_7_vbuck1: vbuck1 {
> +				regulator-compatible = "vbuck1";
> +				regulator-name = "Vgpu";
> +				regulator-min-microvolt = <625000>;
> +				regulator-max-microvolt = <1193750>;
> +				regulator-enable-ramp-delay = <256>;
> +				regulator-ramp-delay = <6250>;
> +				regulator-allowed-modes = <0 1 2>;
> +				regulator-always-on;
> +			};
> +		};
> +	};
> +};
> +
> +&spi0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi0_pins>;
> +	mediatek,pad-select = <0>;
> +	status = "okay";
> +
> +	tpm: tpm at 0 {
> +		compatible = "infineon,slb9670";
> +		reg = <0>;
> +		spi-max-frequency = <18500000>;
> +	};
> +};
> +
> +&spi1 {

Same as before, is this exposed somewhere? If it is, can we please get a comment in
here advertising so?

> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi1_pins>;
> +	mediatek,pad-select = <0>;
> +	status = "okay";
> +};
> +
> +&thermal_zones {
> +	board0-thermal {

"board0" is a bit generic, is that on purpose?

If this is a fixed placement sensor, you could name this something like

pcb-bottom-thermal pcb-left-thermal skin-thermal board-soc-thermal

etc etc etc :-)

> +		polling-delay = <1000>; /* milliseconds */
> +		polling-delay-passive = <0>; /* milliseconds */
> +		thermal-sensors = <&thermal_sensor0>;
> +
> +		trips {
> +			trip-alert {
> +				temperature = <85000>;
> +				hysteresis = <2000>;
> +				type = "passive";
> +			};
> +
> +			trip-crit {
> +				temperature = <95000>;
> +				hysteresis = <2000>;
> +				type = "critical";
> +			};
> +		};
> +	};
> +
> +	board1-thermal {
> +		polling-delay = <1000>; /* milliseconds */
> +		polling-delay-passive = <0>; /* milliseconds */
> +		thermal-sensors = <&thermal_sensor1>;
> +
> +		trips {
> +			trip-alert {
> +				temperature = <75000>;
> +				hysteresis = <2000>;
> +				type = "passive";
> +			};
> +
> +			trip-crit {
> +				temperature = <85000>;
> +				hysteresis = <2000>;
> +				type = "critical";
> +			};
> +		};
> +	};
> +
> +	board2-thermal {
> +		polling-delay = <1000>; /* milliseconds */
> +		polling-delay-passive = <0>; /* milliseconds */
> +		thermal-sensors = <&thermal_sensor2>;
> +
> +		trips {
> +			trip-alert {
> +				temperature = <75000>;
> +				hysteresis = <2000>;
> +				type = "passive";
> +			};
> +
> +			trip-crit {
> +				temperature = <85000>;
> +				hysteresis = <2000>;
> +				type = "critical";
> +			};
> +		};
> +	};
> +};
> +
> +&uart0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart0_pins>;
> +	status = "okay";
> +};
> +
> +&uart1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart1_pins>;
> +	uart-has-rtscts;
> +	status = "okay";
> +};
> +
> +&uart2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart2_pins>;
> +	uart-has-rtscts;
> +	status = "okay";
> +};
> +
> +&uart3 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart3_pins>;
> +	status = "okay";
> +};
> +
> +&uart4 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart4_pins>;
> +	status = "okay";
> +};
> +
> +/* USB3 */
> +&u3phy0 {
> +	status = "okay";
> +};
> +
> +/* PCIe1/USB2 */
> +&u3phy1 {
> +	status = "okay";
> +};
> +
> +/* USB2 */
> +&u3phy2 {
> +	status = "okay";
> +};
> +
> +/* USB2 */
> +&u3phy3 {
> +	status = "okay";
> +};
> +
> +/* USB3 front port */
> +&xhci0 {

It's not gonna work like this. I recently fixed the USB nodes in MT8195 by adding
MTU3 where necessary...

Check mt8195.dtsi - only one XHCI controller isn't placed behind MTU3, and that is
XHCI1 (11290000), while the others are MTU3.

As far as I can see from this DT, it should now instead look like..

&ssusb0 {
	dr_mode = "host";
	vusb33-supply = <&mt6359_vusb_ldo_reg>;
	status = "okay";
};

&ssusb2 {
	dr_mode = "host";
	vusb33-supply = <&mt6359_vusb_ldo_reg>;
	status = "okay";
};

&ssusb3 {
	dr_mode = "host";
	vusb33-supply = <&mt6359_vusb_ldo_reg>;
	status = "okay";
};

&xhci0 {
	vbus-supply = <&otg_vbus_regulator>;
	status = "okay";
};

&xhci1 {
	vusb33-supply = <&mt6359_vusb_ldo_reg>;

vbus is always supplied by something, as otherwise USB won't work - whether this
is an always-on regulator or a passthrough from external supply this doesn't really
matter - you should model a regulator-fixed that provides the 5V VBUS line.

For example:
	vbus_fixed: regulator-vbus {
		compatible = "regulator-fixed";
		regulator-name = "usb-vbus";
		regulator-always-on;
		regulator-boot-on;
		regulator-min-microvolt = <5000000>;
		regulator-max-microvolt = <5000000>;
	};

P.S.: If the rail has a different name, please use that different name. Obviously
that requires you to have schematics at hand, and I don't know if you do: if you
don't, then that regulator-vbus name is just fine.


	vbus-supply = <&vbus_fixed>;
	mediatek,u3p-dis-msk = <0x1>;
	status = "okay";
};

&xhci2 {
	vbus-supply = <&vbus_fixed>;
	status = "okay";
};

&xhci3 {
	vbus-supply = <&vbus_fixed>;
	status = "okay";
};

Cheers,
Angelo

> +	vusb33-supply = <&mt6359_vusb_ldo_reg>;
> +	vbus-supply = <&otg_vbus_regulator>;
> +	status = "okay";
> +};
> +
> +/* USB2 M.2 Key-B */
> +&xhci1 {
> +	vusb33-supply = <&mt6359_vusb_ldo_reg>;
> +	mediatek,u3p-dis-msk = <0x01>;
> +	status = "okay";
> +};
> +
> +/* USB2 M.2 Key-E */
> +&xhci2 {
> +	vusb33-supply = <&mt6359_vusb_ldo_reg>;
> +	status = "okay";
> +};
> +
> +/* USB2 to on-board usb hub */
> +&xhci3 {
> +	vusb33-supply = <&mt6359_vusb_ldo_reg>;
> +	status = "okay";
> +};




From angelogioacchino.delregno at collabora.com  Mon Feb 19 02:03:00 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 11:03:00 +0100
Subject: [PATCH 0/2] Add port@5 as CPU port on certain MT7622 and MT7986 boards
In-Reply-To: <20240219-for-mediatek-v1-0-7078f23eab82@arinc9.com>
References: <20240219-for-mediatek-v1-0-7078f23eab82@arinc9.com>
Message-ID: <170833695121.72704.8159416902422246326.b4-ty@collabora.com>

On Mon, 19 Feb 2024 12:36:12 +0300, Ar?n? ?NAL wrote:
> This patch series adds port at 5 as CPU port on certain MT7622 and MT7986
> boards.
> 
> 

Applied to v6.8-next/dts64, thanks!

[1/2] arm64: dts: mt7622: add port at 5 as CPU port
      https://git.kernel.org/mediatek/c/7b8cc130
[2/2] arm64: dts: mt7986: add port at 5 as CPU port
      https://git.kernel.org/mediatek/c/43ec7fc9

Cheers,
Angelo



From geert at linux-m68k.org  Mon Feb 19 02:03:39 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 19 Feb 2024 11:03:39 +0100
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <20240206074552.541154-1-maskray@google.com>
References: <20240206074552.541154-1-maskray@google.com>
Message-ID: <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>

Hi Fangrui,

On Tue, Feb 6, 2024 at 8:46?AM Fangrui Song <maskray at google.com> wrote:
> The generic constraint "i" seems to be copied from x86 or arm (and with
> a redundant generic operand modifier "c"). It works with -fno-PIE but
> not with -fPIE/-fPIC in GCC's aarch64 port.

Thanks for your patch, which is now commit f9daab0ad01cf9d1 ("arm64:
jump_label: use constraints "Si" instead of "i"") in v6.8-rc5.

> The machine constraint "S", which denotes a symbol or label reference
> with a constant offset, supports PIC and has been available in GCC since
> 2012 and in Clang since 7.0. However, Clang before 19 does not support
> "S" on a symbol with a constant offset [1] (e.g.
> `static_key_false(&nf_hooks_needed[pf][hook])` in
> include/linux/netfilter.h), so we use "i" as a fallback.

https://gcc.gnu.org/releases.html says gcc-5 was released in 2015,
i.e. after 2012 ...

> Suggested-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Fangrui Song <maskray at google.com>
> Link: https://github.com/llvm/llvm-project/pull/80255 [1]
>
> ---
> Changes from
> arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
>
> * Use "Si" as Ard suggested to support Clang<19
> * Make branch a separate operand
>
> Changes from v1:
>
> * Use asmSymbolicName for readability

But it still fails on gcc-5:

    arch/arm64/include/asm/jump_label.h:25:2: error: invalid 'asm':
invalid operand
      asm goto(
      ^

http://kisskb.ellerman.id.au/kisskb/buildresult/15129281/

> --- a/arch/arm64/include/asm/jump_label.h
> +++ b/arch/arm64/include/asm/jump_label.h
> @@ -15,6 +15,10 @@
>
>  #define JUMP_LABEL_NOP_SIZE            AARCH64_INSN_SIZE
>
> +/*
> + * Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
> + * support "S" on a symbol with a constant offset, so we use "i" as a fallback.
> + */
>  static __always_inline bool arch_static_branch(struct static_key * const key,
>                                                const bool branch)
>  {
> @@ -23,9 +27,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
>                  "      .pushsection    __jump_table, \"aw\"    \n\t"
>                  "      .align          3                       \n\t"
>                  "      .long           1b - ., %l[l_yes] - .   \n\t"
> -                "      .quad           %c0 - .                 \n\t"
> +                "      .quad           (%[key] - .) + %[bit0]  \n\t"
>                  "      .popsection                             \n\t"
> -                :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> +                :  :  [key]"Si"(key), [bit0]"i"(branch) :  : l_yes);
>
>         return false;
>  l_yes:
> @@ -40,9 +44,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
>                  "      .pushsection    __jump_table, \"aw\"    \n\t"
>                  "      .align          3                       \n\t"
>                  "      .long           1b - ., %l[l_yes] - .   \n\t"
> -                "      .quad           %c0 - .                 \n\t"
> +                "      .quad           (%[key] - .) + %[bit0]  \n\t"
>                  "      .popsection                             \n\t"
> -                :  :  "i"(&((char *)key)[branch]) :  : l_yes);
> +                :  :  [key]"Si"(key), [bit0]"i"(branch) :  : l_yes);
>
>         return false;
>  l_yes:

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  Mon Feb 19 02:07:24 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 11:07:24 +0100
Subject: [PATCH v2 1/2] dt-bindings: arm64: mediatek: add Kontron
 3.5"-SBC-i1200
In-Reply-To: <CZ8YCQETS7LL.1BLJJZNCLV7DT@kernel.org>
References: <20240219084456.1075445-1-mwalle@kernel.org>
 <ed3530f0-227a-47f2-938c-28eba90dd6eb@collabora.com>
 <CZ8YCQETS7LL.1BLJJZNCLV7DT@kernel.org>
Message-ID: <9cc4fc3f-d697-4e51-a629-9f581dc3c35b@collabora.com>

Il 19/02/24 10:36, Michael Walle ha scritto:
> On Mon Feb 19, 2024 at 10:23 AM CET, AngeloGioacchino Del Regno wrote:
>> Il 19/02/24 09:44, Michael Walle ha scritto:
>>> Add the compatible string for the Kontron 3.5"-SBC-i1200 single board
>>> computer.
>>>
>>> Signed-off-by: Michael Walle <mwalle at kernel.org>
>>> ---
>>> v2:
>>>    - convert enum to const as there is only one specific board
>>>
>>>    Documentation/devicetree/bindings/arm/mediatek.yaml | 5 +++++
>>>    1 file changed, 5 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
>>> index 09f9ffd3ff7b..add167d8b8da 100644
>>> --- a/Documentation/devicetree/bindings/arm/mediatek.yaml
>>> +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
>>> @@ -357,6 +357,11 @@ properties:
>>>                  - radxa,nio-12l
>>>              - const: mediatek,mt8395
>>>              - const: mediatek,mt8195
>>> +      - description: Kontron 3.5"-SBC-i1200
>>> +        items:
>>> +          - const: kontron,3-5-sbc-i1200
>>> +          - const: mediatek,mt8395
>>> +          - const: mediatek,mt8195
>>>          - items:
>>>              - enum:
>>>                  - mediatek,mt8516-pumpkin
>>
>> I understand that you took inspiration from the Google Chromebooks entries, but
>> those are separated only because they've got "a bunch of revisions".
>>
> 
> I don't really care about the description. It's just the way I've
> done it in the past. And in this file, there is also google,burnet,
> google,cozmo, google,damu, without any further revs.
> 

Yeah, I have to check why it is like this - as in - if there's any real reason for
those to be like that... otherwise I wouldn't mind cleaning 'em all up.

Whatever - that's not on you, and completely irrelevant to this specific patch,
so don't worry about the cleanup of the other entries.

>> For machines that don't have a billion compatible strings, I would suggest to
>> add the compatible under a single big entry: like this, the binding is (imo) a
>> bit more readable .. and cleaner.
>>
>> Eventually, the machine name is in the devicetree so we're not losing any kind
>> of information anyway... :-)
>>
>>         - items:
>>             - enum:
>>                 - kontron,3-5-sbc-i1200
>>                 - mediatek,mt8395-evk
>>                 - radxa,nio-12l
>>             - const: mediatek,mt8395
>>             - const: mediatek,mt8195
> 
> Ack. I'll give you some time to look at the actual DTS before
> posting a new version.
> 
> -michael




From kent.overstreet at linux.dev  Mon Feb 19 02:08:47 2024
From: kent.overstreet at linux.dev (Kent Overstreet)
Date: Mon, 19 Feb 2024 05:08:47 -0500
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <7299839b-06e6-40eb-8024-93ed5f9b733f@app.fastmail.com>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
 <ZdMe24xN1Ej4QoVU@shell.armlinux.org.uk>
 <xs2splnjhlj257uca5yae64fp4solc4ugbxrkczoyd75n42r66@42boyzdcmyj4>
 <7299839b-06e6-40eb-8024-93ed5f9b733f@app.fastmail.com>
Message-ID: <a5afnvgygh3nk34oqiaq7cj5mqbbnz2vaokpsz2mmv6kqo76bd@4744h2x4zsvm>

On Mon, Feb 19, 2024 at 10:57:46AM +0100, Arnd Bergmann wrote:
> On Mon, Feb 19, 2024, at 10:40, Kent Overstreet wrote:
> > On Mon, Feb 19, 2024 at 09:26:51AM +0000, Russell King (Oracle) wrote:
> >> On Mon, Feb 19, 2024 at 07:21:11AM +0100, Arnd Bergmann wrote:
> >> 
> >> +1 - bcachefs definitely needs fixing. Passing all that as an argument
> >> not only means that it has to be read into registers, but also when
> >> accessing members, it has to be extracted from those registers as well.
> >> 
> >> Passing that by argument is utterly insane.
> >
> > If the compiler people can't figure out a vaguely efficient way to pass
> > a small struct by value, that's their problem - from the way you
> > describe it, I have to wonder at what insanity is going on there.
> 
> On most ABIs, there are only six argument registers (24 bytes)
> for function calls. The compiler has very little choice here if
> it tries to pass 32 bytes worth of data.
> 
> On both x86_64 and arm64, there are theoretically enough
> registers to pass the data, but kernel disallows using the
> vector and floating point registers for passing large
> compounds arguments.
> 
> The integer registers on x86 apparently allow passing compounds
> up to 16 bytes, but only if all members are naturally aligned.
> Since you have both __packed members and bitfields, the compiler
> would not even be allowed to pass the structure efficiently
> even if it was small enough.

from an efficiency pov, the thing that matters is whether the
compiler is going to emit a call to memcpy (bad) or inline the copy -
and also whether the compiler can elide the copy if the variable is
never modified in the callee.

if were passing by reference it's also going to be living on the stack,
not registers.


From angelogioacchino.delregno at collabora.com  Mon Feb 19 02:09:29 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 11:09:29 +0100
Subject: [PATCH] dt-bindings: ata: convert MediaTek controller to the
 json-schema
In-Reply-To: <20240213074747.26151-1-zajec5@gmail.com>
References: <20240213074747.26151-1-zajec5@gmail.com>
Message-ID: <3d98486e-f0cd-4930-8e97-4a09f1ad0aa2@collabora.com>

Il 13/02/24 08:47, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From paul.elder at ideasonboard.com  Mon Feb 19 02:11:20 2024
From: paul.elder at ideasonboard.com (Paul Elder)
Date: Mon, 19 Feb 2024 19:11:20 +0900
Subject: [PATCH] media: rkisp1: Allow higher input resolution
In-Reply-To: <b500676e-431f-40fc-868b-9f9bb359a109@ideasonboard.com>
References: <20240217185202.1754750-1-megi@xff.cz>
 <20240218205908.GA12766@pendragon.ideasonboard.com>
 <pftafukuzq7qzbhlvwtmeg3mburnttylgy4246timlghtrdgx4@r6munvmj6oqt>
 <CAHCN7x+zi3WxnY-mxZFKePs1cS=-DprEmh_CnypJ4XK7xBzjMQ@mail.gmail.com>
 <b500676e-431f-40fc-868b-9f9bb359a109@ideasonboard.com>
Message-ID: <ZdMpSLqYVFbU7sF0@pyrite.rasen.tech>

On Mon, Feb 19, 2024 at 02:33:21PM +0530, Umang Jain wrote:
> Hi All,
> 
> On 19/02/24 7:39 am, Adam Ford wrote:
> > On Sun, Feb 18, 2024 at 3:02?PM Ond?ej Jirman <megi at xff.cz> wrote:
> > > On Sun, Feb 18, 2024 at 10:59:08PM +0200, Laurent Pinchart wrote:
> > > > Hi Ondrej,
> > > > 
> > > > (CC'ing Paul and Umang)
> > > > 
> > > > Thank you for the patch.
> > > > 
> > > > On Sat, Feb 17, 2024 at 07:51:58PM +0100, Ond?ej Jirman wrote:
> > > > > From: Ondrej Jirman <megi at xff.cz>
> > > > > 
> > > > > In BSP driver, it is allowed, and it works in practice. Tested on
> > > > > Pinephone Pro/RK3399 with IMX258 at full res.
> > > > Paul, Umang, do I recall correctly that you have a similar change ?
> > > > Could you review and test this (especially on the i.MX8MP) ?
> > > It's also a limit from the datasheet, so the change should not be that
> > > controversial:
> > > 
> > >    https://megous.com/dl/tmp/d2b333043ecebaf3.png
> > > 
> > > (so that it doesn't sound like I just copied the BSP values)
> > > 
> >  From what I see in the i.MX8M Plus reference manual, it has a max
> > resolution of 4096x3072, so it might be necessary to move this off
> 
> This is what I (and I assume Paul too) have been working with on i.MX8M
> Plus. So it's the known and tested value of max ISP input from out side.
> > from a #define into a structure that varies by product family.

Yes, this is what needs to be done. Here's what I have in my notes:

- The RK3399 TRM says 4416x3312 max input and output on main path, with
  1920x1080 max output on self path.
- The PX30 datasheet [1] says 3264x2448 max input and output on main
  path, with 1920x1080 max output on self path.
- The RK3288 documentation [2] (under "Camera Interface and Image
  Processor") says 4416x3312 max input and output on main path, with
  1920x1080 max output on self path.
- The i.MX8MP reference manual (the open one) [3] (in table 13-1) says
  4096x3072 max resolution in single ISP mode

The i.MX8M Plus seems to indeed be limited to 4096x3072, but the TPG is
capable of generating 4416x3312, and the ISP works fine in bypass (and
therefore raw) mode, so technically it has different maximum sizes
depending on the format which makes this more exciting.

In any case, the PX30 (assuming the datasheet is correct) only supports
up to 3264x2448, so the existing #define is incorrect anyway.

I don't have a PX30 nor an RK3288 so I can't test those, and I haven't
set up my OV64A40 yet which (I've heard) can be used to test even bigger
resolutions.


Paul

[1] https://opensource.rock-chips.com/images/8/87/Rockchip_PX30_Datasheet_V1.4-20191227.pdf
[2] https://opensource.rock-chips.com/images/4/49/Rockchip_RK3288_Datasheet_V2.7-20191227.pdf
[3] (requires login) https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/i-mx-applications-processors/i-mx-8-applications-processors/i-mx-8m-plus-arm-cortex-a53-machine-learning-vision-multimedia-and-industrial-iot:IMX8MPLUS


> 
> Yeah!
> > 
> > adam
> > > regards,
> > >          o.
> > > 
> > > > > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > > > > ---
> > > > >   drivers/media/platform/rockchip/rkisp1/rkisp1-common.h | 4 ++--
> > > > >   1 file changed, 2 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > index 4b6b28c05b89..74098ddbeeb3 100644
> > > > > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > @@ -33,8 +33,8 @@ struct dentry;
> > > > >   #define RKISP1_ISP_SD_SINK                 BIT(1)
> > > > > 
> > > > >   /* min and max values for the widths and heights of the entities */
> > > > > -#define RKISP1_ISP_MAX_WIDTH                       4032
> > > > > -#define RKISP1_ISP_MAX_HEIGHT                      3024
> > > > > +#define RKISP1_ISP_MAX_WIDTH                       4416
> > > > > +#define RKISP1_ISP_MAX_HEIGHT                      3312
> > > > >   #define RKISP1_ISP_MIN_WIDTH                       32
> > > > >   #define RKISP1_ISP_MIN_HEIGHT                      32
> > > > > 
> > > > --
> > > > Regards,
> > > > 
> > > > Laurent Pinchart
> 


From macpaul.lin at mediatek.com  Mon Feb 19 02:11:03 2024
From: macpaul.lin at mediatek.com (Macpaul Lin)
Date: Mon, 19 Feb 2024 18:11:03 +0800
Subject: [PATCH v2 1/2] dt-bindings: phy: mediatek: tphy: add a property
 for force-mode switch
In-Reply-To: <170317895962.712473.102387666807925662.b4-ty@kernel.org>
References: <20231211025624.28991-1-chunfeng.yun@mediatek.com>
 <170317895962.712473.102387666807925662.b4-ty@kernel.org>
Message-ID: <91b2109d-1bf7-1fa7-ac16-ec1d9aba2f5b@mediatek.com>

On 12/22/23 01:15, Vinod Koul wrote:
> 	
> 
> External email : Please do not click links or open attachments until you 
> have verified the sender or the content.
> 
> On Mon, 11 Dec 2023 10:56:23 +0800, Chunfeng Yun wrote:
>> Due to some old SoCs with shared t-phy between usb3 and pcie only support
>> force-mode switch, and shared and non-shared t-phy may exist at the same
>> time on a SoC, can't use compatible to distinguish between shared and
>> non-shared t-phy, add a property to supported it.
>> Currently, only support switch from default pcie mode to usb3 mode.
>> But now prefer to use "mediatek,syscon-type" on new SoC as far as possible.
>> 
>> [...]
> 
> Applied, thanks!
> 
> [1/2] dt-bindings: phy: mediatek: tphy: add a property for force-mode switch
>        commit: cc230a4cd8e91f64c90b5494dfd76848197418ed
> [2/2] phy: mediatek: tphy: add support force phy mode switch
>        commit: 9b27303003f5af0d378f29ccccea57c7d65cc642
> 
> Best regards,
> -- 
> ~Vinod
> 
> 

Is it possible to cherry-pick these 2 patches to stable branches?
These 2 patches help fix USB port 1 (xhci1) for board mt8395-genio-1200-evb.
The following branch has been tested.
  - linux-6.7.y (6.7.5): apply test, build pass, function tested OK 
(with corresponded dtb change).
  - linux-6.6.y (6.6.17): apply test, build pass.
  - linux-6.1.y (6.1.78): apply test, build pass.

Thanks.
Macpaul Lin


From konrad.dybcio at linaro.org  Mon Feb 19 02:16:29 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 11:16:29 +0100
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <d518dbc1-41aa-46f9-b549-c95a33b06ee0@quicinc.com>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com>
 <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
 <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
 <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com>
 <CAA8EJppe6aNf2WJ5BvaX8SPTbuaEwzRm74F8QKyFtbmnGQt=1w@mail.gmail.com>
 <74f585c2-d220-4324-96eb-1a945fef9608@quicinc.com>
 <CAA8EJppuNRB9fhjimg4SUR2PydX7-KLWSb9H-nC-oSMYVOME-Q@mail.gmail.com>
 <d518dbc1-41aa-46f9-b549-c95a33b06ee0@quicinc.com>
Message-ID: <85538095-9550-4b24-b147-bf765c296a01@linaro.org>

On 18.02.2024 05:29, Kathiravan Thirumoorthy wrote:
> 
> 
> On 2/17/2024 10:15 PM, Dmitry Baryshkov wrote:
>> On Sat, 17 Feb 2024 at 17:45, Kathiravan Thirumoorthy
>> <quic_kathirav at quicinc.com> wrote:
>>>
>>>
>>> <snip>
>>>
>>>>> Reason being, to access the NSSCC clocks, these GCC clocks
>>>>> (gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk)
>>>>> should be turned ON. But CCF disables these clocks as well due to the
>>>>> lack of consumer.
>>>>
>>>> This means that NSSCC is also a consumer of those clocks. Please fix
>>>> both DT and nsscc driver to handle NSSNOC clocks.
>>>
>>>
>>> Thanks Dmitry. I shall include these clocks in the NSSCC DT node and
>>> enable the same in the NSSCC driver probe.
>>
>> Or use them through pm_clk. This might be better, as the system
>> doesn't need these clocks if NSSCC is suspended.
> 
> 
> IPQ53XX SoC doesn't support the PM(suspend / resume) functionality, so that, can I enable these clocks in NSSCC driver probe itself?

Surely the platform can s2idle..

Konrad


From james.clark at arm.com  Mon Feb 19 02:16:51 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 19 Feb 2024 10:16:51 +0000
Subject: [PATCH v3 3/8] perf arm-spe/cs-etm: Directly iterate CPU maps
In-Reply-To: <CAP-5=fXzqF--KUOo1awmxDewupF-r_a2=yFC75tuGasNE-WpXg@mail.gmail.com>
References: <20240202234057.2085863-1-irogers@google.com>
 <20240202234057.2085863-4-irogers@google.com>
 <CAM9d7chPqFGEih7z7rp=eS5P30gSMvG=6fi=0QqT=EdfdMOH_A@mail.gmail.com>
 <CAP-5=fXzqF--KUOo1awmxDewupF-r_a2=yFC75tuGasNE-WpXg@mail.gmail.com>
Message-ID: <b8bb3b4c-9774-e4e8-5705-5a6e01f68eb6@arm.com>



On 17/02/2024 01:33, Ian Rogers wrote:
> On Fri, Feb 16, 2024 at 5:02?PM Namhyung Kim <namhyung at kernel.org> wrote:
>>
>> On Fri, Feb 2, 2024 at 3:41?PM Ian Rogers <irogers at google.com> wrote:
>>>
>>> Rather than iterate all CPUs and see if they are in CPU maps, directly
>>> iterate the CPU map. Similarly make use of the intersect function
>>> taking care for when "any" CPU is specified. Switch
>>> perf_cpu_map__has_any_cpu_or_is_empty to more appropriate
>>> alternatives.
>>>
>>> Signed-off-by: Ian Rogers <irogers at google.com>
>>> ---
>>>  tools/perf/arch/arm/util/cs-etm.c    | 114 ++++++++++++---------------
>>>  tools/perf/arch/arm64/util/arm-spe.c |   4 +-
>>>  2 files changed, 51 insertions(+), 67 deletions(-)
>>>
>>> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
>>> index 77e6663c1703..07be32d99805 100644
>>> --- a/tools/perf/arch/arm/util/cs-etm.c
>>> +++ b/tools/perf/arch/arm/util/cs-etm.c
>>> @@ -197,38 +197,37 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr,
>>>  static int cs_etm_validate_config(struct auxtrace_record *itr,
>>>                                   struct evsel *evsel)
>>>  {
>>> -       int i, err = -EINVAL;
>>> +       int idx, err = 0;
>>>         struct perf_cpu_map *event_cpus = evsel->evlist->core.user_requested_cpus;
>>> -       struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
>>> -
>>> -       /* Set option of each CPU we have */
>>> -       for (i = 0; i < cpu__max_cpu().cpu; i++) {
>>> -               struct perf_cpu cpu = { .cpu = i, };
>>> +       struct perf_cpu_map *intersect_cpus;
>>> +       struct perf_cpu cpu;
>>>
>>> -               /*
>>> -                * In per-cpu case, do the validation for CPUs to work with.
>>> -                * In per-thread case, the CPU map is empty.  Since the traced
>>> -                * program can run on any CPUs in this case, thus don't skip
>>> -                * validation.
>>> -                */
>>> -               if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus) &&
>>> -                   !perf_cpu_map__has(event_cpus, cpu))
>>> -                       continue;
>>> +       /*
>>> +        * Set option of each CPU we have. In per-cpu case, do the validation
>>> +        * for CPUs to work with. In per-thread case, the CPU map has the "any"
>>> +        * CPU value. Since the traced program can run on any CPUs in this case,
>>> +        * thus don't skip validation.
>>> +        */
>>> +       if (!perf_cpu_map__has_any_cpu(event_cpus)) {
>>> +               struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
>>>
>>> -               if (!perf_cpu_map__has(online_cpus, cpu))
>>> -                       continue;
>>> +               intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
>>> +               perf_cpu_map__put(online_cpus);
>>> +       } else {
>>> +               intersect_cpus = perf_cpu_map__new_online_cpus();
>>> +       }
>>
>> Would it be ok if any of these operations fail?  I believe the
>> cpu map functions work well with NULL already.
> 
> If the allocation fails then the loop below won't iterate (the map
> will be empty). The map is released and not used elsewhere in the
> code. An allocation failure here won't cause the code to crash, but
> there are other places where the code assumes what the properties of
> having done this function are and they won't be working as intended.
> It's not uncommon to see ENOMEM to just be abort for this reason.
> 
> Thanks,
> Ian
> 
>> Thanks,
>> Namhyung
>>

Reviewed-by: James Clark <james.clark at arm.com>

About the out of memory case, I don't really have much preference about
that. I doubt much of the code is tested or resiliant to it and the
behaviour is probably already unpredictable.

>>>
>>> -               err = cs_etm_validate_context_id(itr, evsel, i);
>>> +       perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
>>> +               err = cs_etm_validate_context_id(itr, evsel, cpu.cpu);
>>>                 if (err)
>>> -                       goto out;
>>> -               err = cs_etm_validate_timestamp(itr, evsel, i);
>>> +                       break;
>>> +
>>> +               err = cs_etm_validate_timestamp(itr, evsel, cpu.cpu);
>>>                 if (err)
>>> -                       goto out;
>>> +                       break;
>>>         }
>>>
>>> -       err = 0;
>>> -out:
>>> -       perf_cpu_map__put(online_cpus);
>>> +       perf_cpu_map__put(intersect_cpus);
>>>         return err;
>>>  }
>>>
>>> @@ -435,7 +434,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
>>>          * Also the case of per-cpu mmaps, need the contextID in order to be notified
>>>          * when a context switch happened.
>>>          */
>>> -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
>>> +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>>>                 evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
>>>                                            "timestamp", 1);
>>>                 evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
>>> @@ -461,7 +460,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
>>>         evsel->core.attr.sample_period = 1;
>>>
>>>         /* In per-cpu case, always need the time of mmap events etc */
>>> -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus))
>>> +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
>>>                 evsel__set_sample_bit(evsel, TIME);
>>>
>>>         err = cs_etm_validate_config(itr, cs_etm_evsel);
>>> @@ -533,45 +532,31 @@ static size_t
>>>  cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
>>>                       struct evlist *evlist __maybe_unused)
>>>  {
>>> -       int i;
>>> +       int idx;
>>>         int etmv3 = 0, etmv4 = 0, ete = 0;
>>>         struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus;
>>> -       struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
>>> -
>>> -       /* cpu map is not empty, we have specific CPUs to work with */
>>> -       if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
>>> -               for (i = 0; i < cpu__max_cpu().cpu; i++) {
>>> -                       struct perf_cpu cpu = { .cpu = i, };
>>> +       struct perf_cpu_map *intersect_cpus;
>>> +       struct perf_cpu cpu;
>>>
>>> -                       if (!perf_cpu_map__has(event_cpus, cpu) ||
>>> -                           !perf_cpu_map__has(online_cpus, cpu))
>>> -                               continue;
>>> +       if (!perf_cpu_map__has_any_cpu(event_cpus)) {
>>> +               /* cpu map is not "any" CPU , we have specific CPUs to work with */
>>> +               struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
>>>
>>> -                       if (cs_etm_is_ete(itr, i))
>>> -                               ete++;
>>> -                       else if (cs_etm_is_etmv4(itr, i))
>>> -                               etmv4++;
>>> -                       else
>>> -                               etmv3++;
>>> -               }
>>> +               intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
>>> +               perf_cpu_map__put(online_cpus);
>>>         } else {
>>> -               /* get configuration for all CPUs in the system */
>>> -               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))
>>> -                               ete++;
>>> -                       else if (cs_etm_is_etmv4(itr, i))
>>> -                               etmv4++;
>>> -                       else
>>> -                               etmv3++;
>>> -               }
>>> +               /* Event can be "any" CPU so count all online CPUs. */
>>> +               intersect_cpus = perf_cpu_map__new_online_cpus();
>>>         }
>>> -
>>> -       perf_cpu_map__put(online_cpus);
>>> +       perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
>>> +               if (cs_etm_is_ete(itr, cpu.cpu))
>>> +                       ete++;
>>> +               else if (cs_etm_is_etmv4(itr, cpu.cpu))
>>> +                       etmv4++;
>>> +               else
>>> +                       etmv3++;
>>> +       }
>>> +       perf_cpu_map__put(intersect_cpus);
>>>
>>>         return (CS_ETM_HEADER_SIZE +
>>>                (ete   * CS_ETE_PRIV_SIZE) +
>>> @@ -813,16 +798,15 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
>>>         if (!session->evlist->core.nr_mmaps)
>>>                 return -EINVAL;
>>>
>>> -       /* If the cpu_map is empty all online CPUs are involved */
>>> -       if (perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
>>> +       /* If the cpu_map has the "any" CPU all online CPUs are involved */
>>> +       if (perf_cpu_map__has_any_cpu(event_cpus)) {
>>>                 cpu_map = online_cpus;
>>>         } else {
>>>                 /* Make sure all specified CPUs are online */
>>> -               for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) {
>>> -                       struct perf_cpu cpu = { .cpu = i, };
>>> +               struct perf_cpu cpu;
>>>
>>> -                       if (perf_cpu_map__has(event_cpus, cpu) &&
>>> -                           !perf_cpu_map__has(online_cpus, cpu))
>>> +               perf_cpu_map__for_each_cpu(cpu, i, event_cpus) {
>>> +                       if (!perf_cpu_map__has(online_cpus, cpu))
>>>                                 return -EINVAL;
>>>                 }
>>>
>>> diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
>>> index 51ccbfd3d246..0b52e67edb3b 100644
>>> --- a/tools/perf/arch/arm64/util/arm-spe.c
>>> +++ b/tools/perf/arch/arm64/util/arm-spe.c
>>> @@ -232,7 +232,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
>>>          * In the case of per-cpu mmaps, sample CPU for AUX event;
>>>          * also enable the timestamp tracing for samples correlation.
>>>          */
>>> -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
>>> +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>>>                 evsel__set_sample_bit(arm_spe_evsel, CPU);
>>>                 evsel__set_config_if_unset(arm_spe_pmu, arm_spe_evsel,
>>>                                            "ts_enable", 1);
>>> @@ -265,7 +265,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
>>>         tracking_evsel->core.attr.sample_period = 1;
>>>
>>>         /* In per-cpu case, always need the time of mmap events etc */
>>> -       if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) {
>>> +       if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
>>>                 evsel__set_sample_bit(tracking_evsel, TIME);
>>>                 evsel__set_sample_bit(tracking_evsel, CPU);
>>>
>>> --
>>> 2.43.0.594.gd9cf4e227d-goog
>>>


From dmitry.baryshkov at linaro.org  Mon Feb 19 02:23:03 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 12:23:03 +0200
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <d518dbc1-41aa-46f9-b549-c95a33b06ee0@quicinc.com>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com> <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com> <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
 <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com> <CAA8EJppe6aNf2WJ5BvaX8SPTbuaEwzRm74F8QKyFtbmnGQt=1w@mail.gmail.com>
 <74f585c2-d220-4324-96eb-1a945fef9608@quicinc.com> <CAA8EJppuNRB9fhjimg4SUR2PydX7-KLWSb9H-nC-oSMYVOME-Q@mail.gmail.com>
 <d518dbc1-41aa-46f9-b549-c95a33b06ee0@quicinc.com>
Message-ID: <CAA8EJppP_bAPRH7Upnq8dO7__xQPOJ6F_Lc-fpRAcutKKzk0eA@mail.gmail.com>

On Sun, 18 Feb 2024 at 06:29, Kathiravan Thirumoorthy
<quic_kathirav at quicinc.com> wrote:
>
>
>
> On 2/17/2024 10:15 PM, Dmitry Baryshkov wrote:
> > On Sat, 17 Feb 2024 at 17:45, Kathiravan Thirumoorthy
> > <quic_kathirav at quicinc.com> wrote:
> >>
> >>
> >> <snip>
> >>
> >>>> Reason being, to access the NSSCC clocks, these GCC clocks
> >>>> (gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk)
> >>>> should be turned ON. But CCF disables these clocks as well due to the
> >>>> lack of consumer.
> >>>
> >>> This means that NSSCC is also a consumer of those clocks. Please fix
> >>> both DT and nsscc driver to handle NSSNOC clocks.
> >>
> >>
> >> Thanks Dmitry. I shall include these clocks in the NSSCC DT node and
> >> enable the same in the NSSCC driver probe.
> >
> > Or use them through pm_clk. This might be better, as the system
> > doesn't need these clocks if NSSCC is suspended.
>
>
> IPQ53XX SoC doesn't support the PM(suspend / resume) functionality, so
> that, can I enable these clocks in NSSCC driver probe itself?

There is a difference between PM (suspend/resume) and runtime PM.


-- 
With best wishes
Dmitry


From cassel at kernel.org  Mon Feb 19 02:23:13 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Mon, 19 Feb 2024 11:23:13 +0100
Subject: [PATCH] dt-bindings: ata: convert MediaTek controller to the
 json-schema
In-Reply-To: <20240213074747.26151-1-zajec5@gmail.com>
References: <20240213074747.26151-1-zajec5@gmail.com>
Message-ID: <ZdMsEW2AnYVAB7Qf@x1-carbon>

On Tue, Feb 13, 2024 at 08:47:47AM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  .../devicetree/bindings/ata/ahci-mtk.txt      | 51 ----------
>  .../bindings/ata/mediatek,mtk-ahci.yaml       | 98 +++++++++++++++++++
>  2 files changed, 98 insertions(+), 51 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/ata/ahci-mtk.txt
>  create mode 100644 Documentation/devicetree/bindings/ata/mediatek,mtk-ahci.yaml
> 

Applied:
https://git.kernel.org/pub/scm/linux/kernel/git/libata/linux.git/log/?h=for-6.9


From piotrwejman90 at gmail.com  Mon Feb 19 02:24:05 2024
From: piotrwejman90 at gmail.com (Piotr Wejman)
Date: Mon, 19 Feb 2024 11:24:05 +0100
Subject: [PATCH] net: stmmac: fix rx queue priority assignment
Message-ID: <20240219102405.32015-1-piotrwejman90@gmail.com>

The driver should ensure that same priority is not mapped to multiple
rx queues. Currently dwmac4_rx_queue_priority function is adding
priorities for a queue without clearing them from others.

>From DesignWare Cores Ethernet Quality-of-Service
Databook, section 17.1.29 MAC_RxQ_Ctrl2:
"[...]The software must ensure that the content of this field is
mutually exclusive to the PSRQ fields for other queues, that is,
the same priority is not mapped to multiple Rx queues[...]"

After this patch, dwmac4_rx_queue_priority function will:
- assign desired priorities to a queue
- remove those priorities from all other queues
The write sequence of CTRL2 and CTRL3 registers is done in the way to
ensure this order.

Also, the PSRQn field contains the mask of priorities and not only one
priority. Rename "prio" argument to "prio_mask".

Signed-off-by: Piotr Wejman <piotrwejman90 at gmail.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 36 +++++++++++++------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 6b6d0de09619..6acc8bad794e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -89,22 +89,38 @@ static void dwmac4_rx_queue_enable(struct mac_device_info *hw,
 }
 
 static void dwmac4_rx_queue_priority(struct mac_device_info *hw,
-				     u32 prio, u32 queue)
+				     u32 prio_mask, u32 queue)
 {
 	void __iomem *ioaddr = hw->pcsr;
-	u32 base_register;
-	u32 value;
+	u32 clear_mask = 0;
+	u32 ctrl2, ctrl3;
+	int i;
 
-	base_register = (queue < 4) ? GMAC_RXQ_CTRL2 : GMAC_RXQ_CTRL3;
-	if (queue >= 4)
-		queue -= 4;
+	ctrl2 = readl(ioaddr + GMAC_RXQ_CTRL2);
+	ctrl3 = readl(ioaddr + GMAC_RXQ_CTRL3);
 
-	value = readl(ioaddr + base_register);
+	for (i = 0; i < 4; i++)
+		clear_mask |= ((prio_mask << GMAC_RXQCTRL_PSRQX_SHIFT(i)) &
+						GMAC_RXQCTRL_PSRQX_MASK(i));
 
-	value &= ~GMAC_RXQCTRL_PSRQX_MASK(queue);
-	value |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
+	ctrl2 &= ~clear_mask;
+	ctrl3 &= ~clear_mask;
+
+	if (queue < 4) {
+		ctrl2 |= (prio_mask << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
 						GMAC_RXQCTRL_PSRQX_MASK(queue);
-	writel(value, ioaddr + base_register);
+
+		writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
+		writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
+	} else {
+		queue -= 4;
+
+		ctrl3 |= (prio_mask << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
+						GMAC_RXQCTRL_PSRQX_MASK(queue);
+
+		writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
+		writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
+	}
 }
 
 static void dwmac4_tx_queue_priority(struct mac_device_info *hw,
-- 
2.25.1



From dmitry.baryshkov at linaro.org  Mon Feb 19 02:26:39 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 12:26:39 +0200
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org>
References: <20240216203215.40870-1-brgl@bgdev.pl> <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org> <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org>
Message-ID: <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>

On Mon, 19 Feb 2024 at 11:42, <neil.armstrong at linaro.org> wrote:
>
> On 19/02/2024 10:22, Dmitry Baryshkov wrote:
> > On Mon, 19 Feb 2024 at 10:14, Neil Armstrong <neil.armstrong at linaro.org> wrote:
> >>
> >> On 18/02/2024 13:53, Dmitry Baryshkov wrote:
> >>> On Fri, 16 Feb 2024 at 22:33, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> >>>>
> >>>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >>>>
> >>>> First, I'd like to apologize for the somewhat chaotic previous iterations
> >>>> of this series and improper versioning which was rightfully pointed out
> >>>> to me. I figured that the scope changed so much that it didn't make sense
> >>>> to consider previous submissions part of the same series as the original
> >>>> RFC but others thought otherwise so this one becomes v5 and I'll keep the
> >>>> versioning going forward.
> >>>>
> >>>> This is the summary of the work so far:
> >>>>
> >>>> v1: Original RFC:
> >>>>
> >>>> https://lore.kernel.org/lkml/20240104130123.37115-1-brgl at bgdev.pl/T/
> >>>>
> >>>> v2: First real patch series (should have been PATCH v2) adding what I
> >>>>       referred to back then as PCI power sequencing:
> >>>>
> >>>> https://lore.kernel.org/linux-arm-kernel/2024021413-grumbling-unlivable-c145 at gregkh/T/
> >>>>
> >>>> v3: RFC for the DT representation of the PMU supplying the WLAN and BT
> >>>>       modules inside the QCA6391 package (was largely separate from the
> >>>>       series but probably should have been called PATCH or RFC v3):
> >>>>
> >>>> https://lore.kernel.org/all/CAMRc=Mc+GNoi57eTQg71DXkQKjdaoAmCpB=h2ndEpGnmdhVV-Q at mail.gmail.com/T/
> >>>>
> >>>> v4: Second attempt at the full series with changed scope (introduction of
> >>>>       the pwrseq subsystem, should have been RFC v4)
> >>>>
> >>>> https://lore.kernel.org/lkml/20240201155532.49707-1-brgl at bgdev.pl/T/
> >>>>
> >>>> ===
> >>>>
> >>>> With that out of the way, I'd like to get down to explaining the two
> >>>> problems I'm trying to solve.
> >>>>
> >>>> Problem statement #1: Dynamic bus chicken-and-egg problem.
> >>>>
> >>>> Certain on-board PCI devices need to be powered up before they are can be
> >>>> detected but their PCI drivers won't get bound until the device is
> >>>> powered-up so enabling the relevant resources in the PCI device driver
> >>>> itself is impossible.
> >>>>
> >>>> Problem statement #2: Sharing inter-dependent resources between devices.
> >>>>
> >>>> Certain devices that use separate drivers (often on different busses)
> >>>> share resources (regulators, clocks, etc.). Typically these resources
> >>>> are reference-counted but in some cases there are additional interactions
> >>>> between them to consider, for example specific power-up sequence timings.
> >>>>
> >>>> ===
> >>>>
> >>>> The reason for tackling both of these problems in a single series is the
> >>>> fact the the platform I'm working on - Qualcomm RB5 - deals with both and
> >>>> both need to be addressed in order to enable WLAN and Bluetooth support
> >>>> upstream.
> >>>>
> >>>> The on-board WLAN/BT package - QCA6391 - has a Power Management Unit that
> >>>> takes inputs from the host and exposes LDO outputs consumed by the BT and
> >>>> WLAN modules which can be powered-up and down independently. However
> >>>> a delay of 100ms must be respected between enabling the BT- and
> >>>> WLAN-enable GPIOs[*].
> >>>>
> >>>> ===
> >>>>
> >>>> This series is logically split into several sections. I'll go
> >>>> patch-by-patch and explain each step.
> >>>>
> >>>> Patch 1/18:
> >>>>
> >>>> This is a commit taken from the list by Jonathan Cameron that adds
> >>>> a __free() helper for OF nodes. Not strictly related to the series but
> >>>> until said commit ends in next, I need to carry it with this series.
> >>>>
> >>>> Patch 2/18:
> >>>>
> >>>> This enables the ath12k PCI module in arm64 defconfig as Qualcomm sm8650
> >>>> and sm8550 reference platforms use it in the WCN7850 module.
> >>>>
> >>>> Patches 3/18-6/18:
> >>>>
> >>>> These contain all relevant DT bindings changes. We add new documents for
> >>>> the QCA6390 PMU and ATH12K devices as well as extend the bindings for the
> >>>> Qualcomm Bluetooth and ATH11K modules with regulators used by them in
> >>>> QCA6390.
> >>>>
> >>>> Patches 7/18-9/18:
> >>>>
> >>>> These contain changes to device-tree sources for the three platforms we
> >>>> work with in this series. As the WCN7850 module doesn't require any
> >>>> specific timings introducing dependencies between the Bluetooth and WLAN
> >>>> modules, while the QCA6390 does, we take two different approaches to how
> >>>> me model them in DT.
> >>>>
> >>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> >>>> necessary. The BT and WLAN devices on the device-tree are represented as
> >>>> consuming the inputs (relevant to the functionality of each) of the PMU
> >>>> directly.
> >>>
> >>> We are describing the hardware. From the hardware point of view, there
> >>> is a PMU. I think at some point we would really like to describe all
> >>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> >>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
> >>
> >> While I agree with older WiFi+BT units, I don't think it's needed for
> >> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
> >> transparent.
> >
> > I don't see any significant difference between WCN6750/WCN6855 and
> > WCN7850 from the PMU / power up point of view. Could you please point
> > me to the difference?
> >
>
> The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
> and BT_EN ordering and the only requirement is to have all input regulators
> up before pulling up WLAN_EN and/or BT_EN.
>
> This makes the PMU transparent and BT and WLAN can be described as independent.

>From the hardware perspective, there is a PMU. It has several LDOs. So
the device tree should have the same style as the previous
generations.

-- 
With best wishes
Dmitry


From apatel at ventanamicro.com  Mon Feb 19 02:28:45 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 19 Feb 2024 15:58:45 +0530
Subject: [PATCH v12 22/25] irqchip: Add RISC-V advanced PLIC driver for direct-mode
In-Reply-To: <CABgGipWKTR95wrMrgKuq83auQdQfn9M29U7eq46_OJUCHqrBjQ@mail.gmail.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-23-apatel@ventanamicro.com> <CABgGipWKTR95wrMrgKuq83auQdQfn9M29U7eq46_OJUCHqrBjQ@mail.gmail.com>
Message-ID: <CAK9=C2Vcq8Cyco-pN4RRfSjD_5S14gLSvwX817p1Tor9qxEyuQ@mail.gmail.com>

On Thu, Feb 1, 2024 at 12:09?PM Andy Chiu <andy.chiu at sifive.com> wrote:
>
> Hi Anup,
>
> On Sun, Jan 28, 2024 at 12:24?AM Anup Patel <apatel at ventanamicro.com> wrote:
> >
> > The RISC-V advanced interrupt architecture (AIA) specification defines
> > advanced platform-level interrupt controller (APLIC) which has two modes
> > of operation: 1) Direct mode and 2) MSI mode.
> > (For more details, refer https://github.com/riscv/riscv-aia)
> >
> > In APLIC direct-mode, wired interrupts are forwared to CPUs (or HARTs)
> > as a local external interrupt.
> >
> > We add a platform irqchip driver for the RISC-V APLIC direct-mode to
> > support RISC-V platforms having only wired interrupts.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  drivers/irqchip/Kconfig                  |   5 +
> >  drivers/irqchip/Makefile                 |   1 +
> >  drivers/irqchip/irq-riscv-aplic-direct.c | 343 +++++++++++++++++++++++
> >  drivers/irqchip/irq-riscv-aplic-main.c   | 232 +++++++++++++++
> >  drivers/irqchip/irq-riscv-aplic-main.h   |  45 +++
> >  include/linux/irqchip/riscv-aplic.h      | 119 ++++++++
> >  6 files changed, 745 insertions(+)
> >  create mode 100644 drivers/irqchip/irq-riscv-aplic-direct.c
> >  create mode 100644 drivers/irqchip/irq-riscv-aplic-main.c
> >  create mode 100644 drivers/irqchip/irq-riscv-aplic-main.h
> >  create mode 100644 include/linux/irqchip/riscv-aplic.h
> >
> > diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> > index 2fc0cb32341a..dbc8811d3764 100644
> > --- a/drivers/irqchip/Kconfig
> > +++ b/drivers/irqchip/Kconfig
> > @@ -546,6 +546,11 @@ config SIFIVE_PLIC
> >         select IRQ_DOMAIN_HIERARCHY
> >         select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
> >
> > +config RISCV_APLIC
> > +       bool
> > +       depends on RISCV
> > +       select IRQ_DOMAIN_HIERARCHY
> > +
> >  config RISCV_IMSIC
> >         bool
> >         depends on RISCV
> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> > index abca445a3229..7f8289790ed8 100644
> > --- a/drivers/irqchip/Makefile
> > +++ b/drivers/irqchip/Makefile
> > @@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)                        += irq-qcom-mpm.o
> >  obj-$(CONFIG_CSKY_MPINTC)              += irq-csky-mpintc.o
> >  obj-$(CONFIG_CSKY_APB_INTC)            += irq-csky-apb-intc.o
> >  obj-$(CONFIG_RISCV_INTC)               += irq-riscv-intc.o
> > +obj-$(CONFIG_RISCV_APLIC)              += irq-riscv-aplic-main.o irq-riscv-aplic-direct.o
> >  obj-$(CONFIG_RISCV_IMSIC)              += irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
> >  obj-$(CONFIG_SIFIVE_PLIC)              += irq-sifive-plic.o
> >  obj-$(CONFIG_IMX_IRQSTEER)             += irq-imx-irqsteer.o
> > diff --git a/drivers/irqchip/irq-riscv-aplic-direct.c b/drivers/irqchip/irq-riscv-aplic-direct.c
> > new file mode 100644
> > index 000000000000..9ed2666bfb5e
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-aplic-direct.c
> > @@ -0,0 +1,343 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
> > + */
> > +
> > +#include <linux/bitops.h>
> > +#include <linux/cpu.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/irqchip.h>
> > +#include <linux/irqchip/chained_irq.h>
> > +#include <linux/irqchip/riscv-aplic.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/printk.h>
> > +#include <linux/smp.h>
> > +
> > +#include "irq-riscv-aplic-main.h"
> > +
> > +#define APLIC_DISABLE_IDELIVERY                0
> > +#define APLIC_ENABLE_IDELIVERY         1
> > +#define APLIC_DISABLE_ITHRESHOLD       1
> > +#define APLIC_ENABLE_ITHRESHOLD                0
> > +
> > +struct aplic_direct {
> > +       struct aplic_priv       priv;
> > +       struct irq_domain       *irqdomain;
> > +       struct cpumask          lmask;
> > +};
> > +
> > +struct aplic_idc {
> > +       unsigned int            hart_index;
> > +       void __iomem            *regs;
> > +       struct aplic_direct     *direct;
> > +};
> > +
> > +static unsigned int aplic_direct_parent_irq;
> > +static DEFINE_PER_CPU(struct aplic_idc, aplic_idcs);
> > +
> > +static void aplic_direct_irq_eoi(struct irq_data *d)
> > +{
> > +       /*
> > +        * The fasteoi_handler requires irq_eoi() callback hence
> > +        * provide a dummy handler.
> > +        */
> > +}
> > +
> > +#ifdef CONFIG_SMP
> > +static int aplic_direct_set_affinity(struct irq_data *d,
> > +                                 const struct cpumask *mask_val, bool force)
> > +{
> > +       struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> > +       struct aplic_direct *direct =
> > +                       container_of(priv, struct aplic_direct, priv);
> > +       struct aplic_idc *idc;
> > +       unsigned int cpu, val;
> > +       struct cpumask amask;
> > +       void __iomem *target;
> > +
> > +       cpumask_and(&amask, &direct->lmask, mask_val);
> > +
> > +       if (force)
> > +               cpu = cpumask_first(&amask);
> > +       else
> > +               cpu = cpumask_any_and(&amask, cpu_online_mask);
> > +
> > +       if (cpu >= nr_cpu_ids)
> > +               return -EINVAL;
> > +
> > +       idc = per_cpu_ptr(&aplic_idcs, cpu);
> > +       target = priv->regs + APLIC_TARGET_BASE;
> > +       target += (d->hwirq - 1) * sizeof(u32);
> > +       val = idc->hart_index & APLIC_TARGET_HART_IDX_MASK;
> > +       val <<= APLIC_TARGET_HART_IDX_SHIFT;
> > +       val |= APLIC_DEFAULT_PRIORITY;
> > +       writel(val, target);
> > +
> > +       irq_data_update_effective_affinity(d, cpumask_of(cpu));
> > +
> > +       return IRQ_SET_MASK_OK_DONE;
> > +}
> > +#endif
> > +
> > +static struct irq_chip aplic_direct_chip = {
> > +       .name           = "APLIC-DIRECT",
> > +       .irq_mask       = aplic_irq_mask,
> > +       .irq_unmask     = aplic_irq_unmask,
> > +       .irq_set_type   = aplic_irq_set_type,
> > +       .irq_eoi        = aplic_direct_irq_eoi,
> > +#ifdef CONFIG_SMP
> > +       .irq_set_affinity = aplic_direct_set_affinity,
> > +#endif
> > +       .flags          = IRQCHIP_SET_TYPE_MASKED |
> > +                         IRQCHIP_SKIP_SET_WAKE |
> > +                         IRQCHIP_MASK_ON_SUSPEND,
> > +};
> > +
> > +static int aplic_direct_irqdomain_translate(struct irq_domain *d,
> > +                                        struct irq_fwspec *fwspec,
> > +                                        unsigned long *hwirq,
> > +                                        unsigned int *type)
> > +{
> > +       struct aplic_priv *priv = d->host_data;
> > +
> > +       return aplic_irqdomain_translate(fwspec, priv->gsi_base,
> > +                                        hwirq, type);
> > +}
> > +
> > +static int aplic_direct_irqdomain_alloc(struct irq_domain *domain,
> > +                                    unsigned int virq, unsigned int nr_irqs,
> > +                                    void *arg)
> > +{
> > +       int i, ret;
> > +       unsigned int type;
> > +       irq_hw_number_t hwirq;
> > +       struct irq_fwspec *fwspec = arg;
> > +       struct aplic_priv *priv = domain->host_data;
> > +       struct aplic_direct *direct =
> > +                       container_of(priv, struct aplic_direct, priv);
> > +
> > +       ret = aplic_irqdomain_translate(fwspec, priv->gsi_base,
> > +                                       &hwirq, &type);
> > +       if (ret)
> > +               return ret;
> > +
> > +       for (i = 0; i < nr_irqs; i++) {
> > +               irq_domain_set_info(domain, virq + i, hwirq + i,
> > +                                   &aplic_direct_chip, priv,
> > +                                   handle_fasteoi_irq, NULL, NULL);
> > +               irq_set_affinity(virq + i, &direct->lmask);
> > +               /* See the reason described in aplic_msi_irqdomain_alloc() */
> > +               irq_set_status_flags(virq + i, IRQ_DISABLE_UNLAZY);
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct irq_domain_ops aplic_direct_irqdomain_ops = {
> > +       .translate      = aplic_direct_irqdomain_translate,
> > +       .alloc          = aplic_direct_irqdomain_alloc,
> > +       .free           = irq_domain_free_irqs_top,
> > +};
> > +
> > +/*
> > + * To handle an APLIC direct interrupts, we just read the CLAIMI register
> > + * which will return highest priority pending interrupt and clear the
> > + * pending bit of the interrupt. This process is repeated until CLAIMI
> > + * register return zero value.
> > + */
> > +static void aplic_direct_handle_irq(struct irq_desc *desc)
> > +{
> > +       struct aplic_idc *idc = this_cpu_ptr(&aplic_idcs);
> > +       struct irq_chip *chip = irq_desc_get_chip(desc);
> > +       struct irq_domain *irqdomain = idc->direct->irqdomain;
> > +       irq_hw_number_t hw_irq;
> > +       int irq;
> > +
> > +       chained_irq_enter(chip, desc);
> > +
> > +       while ((hw_irq = readl(idc->regs + APLIC_IDC_CLAIMI))) {
> > +               hw_irq = hw_irq >> APLIC_IDC_TOPI_ID_SHIFT;
> > +               irq = irq_find_mapping(irqdomain, hw_irq);
> > +
> > +               if (unlikely(irq <= 0))
> > +                       dev_warn_ratelimited(idc->direct->priv.dev,
> > +                                            "hw_irq %lu mapping not found\n",
> > +                                            hw_irq);
> > +               else
> > +                       generic_handle_irq(irq);
> > +       }
> > +
> > +       chained_irq_exit(chip, desc);
> > +}
> > +
> > +static void aplic_idc_set_delivery(struct aplic_idc *idc, bool en)
> > +{
> > +       u32 de = (en) ? APLIC_ENABLE_IDELIVERY : APLIC_DISABLE_IDELIVERY;
> > +       u32 th = (en) ? APLIC_ENABLE_ITHRESHOLD : APLIC_DISABLE_ITHRESHOLD;
> > +
> > +       /* Priority must be less than threshold for interrupt triggering */
> > +       writel(th, idc->regs + APLIC_IDC_ITHRESHOLD);
> > +
> > +       /* Delivery must be set to 1 for interrupt triggering */
> > +       writel(de, idc->regs + APLIC_IDC_IDELIVERY);
> > +}
> > +
> > +static int aplic_direct_dying_cpu(unsigned int cpu)
> > +{
> > +       if (aplic_direct_parent_irq)
> > +               disable_percpu_irq(aplic_direct_parent_irq);
> > +
> > +       return 0;
> > +}
> > +
> > +static int aplic_direct_starting_cpu(unsigned int cpu)
> > +{
> > +       if (aplic_direct_parent_irq)
> > +               enable_percpu_irq(aplic_direct_parent_irq,
> > +                               irq_get_trigger_type(aplic_direct_parent_irq));
> > +
> > +       return 0;
> > +}
> > +
> > +static int aplic_direct_parse_parent_hwirq(struct device *dev,
> > +                                          u32 index, u32 *parent_hwirq,
> > +                                          unsigned long *parent_hartid)
> > +{
> > +       struct of_phandle_args parent;
> > +       int rc;
> > +
> > +       /*
> > +        * Currently, only OF fwnode is supported so extend this
> > +        * function for ACPI support.
> > +        */
> > +       if (!is_of_node(dev->fwnode))
> > +               return -EINVAL;
> > +
> > +       rc = of_irq_parse_one(to_of_node(dev->fwnode), index, &parent);
> > +       if (rc)
> > +               return rc;
> > +
> > +       rc = riscv_of_parent_hartid(parent.np, parent_hartid);
> > +       if (rc)
> > +               return rc;
> > +
> > +       *parent_hwirq = parent.args[0];
> > +       return 0;
> > +}
> > +
> > +int aplic_direct_setup(struct device *dev, void __iomem *regs)
> > +{
> > +       int i, j, rc, cpu, setup_count = 0;
> > +       struct aplic_direct *direct;
> > +       struct aplic_priv *priv;
> > +       struct irq_domain *domain;
> > +       unsigned long hartid;
> > +       struct aplic_idc *idc;
> > +       u32 val, hwirq;
> > +
> > +       direct = kzalloc(sizeof(*direct), GFP_KERNEL);
> > +       if (!direct)
> > +               return -ENOMEM;
> > +       priv = &direct->priv;
> > +
> > +       rc = aplic_setup_priv(priv, dev, regs);
> > +       if (rc) {
> > +               dev_err(dev, "failed to create APLIC context\n");
> > +               kfree(direct);
> > +               return rc;
> > +       }
> > +
> > +       /* Setup per-CPU IDC and target CPU mask */
> > +       for (i = 0; i < priv->nr_idcs; i++) {
> > +               rc = aplic_direct_parse_parent_hwirq(dev, i, &hwirq, &hartid);
> > +               if (rc) {
> > +                       dev_warn(dev, "parent irq for IDC%d not found\n", i);
> > +                       continue;
> > +               }
> > +
> > +               /*
> > +                * Skip interrupts other than external interrupts for
> > +                * current privilege level.
> > +                */
> > +               if (hwirq != RV_IRQ_EXT)
> > +                       continue;
> > +
> > +               cpu = riscv_hartid_to_cpuid(hartid);
> > +               if (cpu < 0) {
> > +                       dev_warn(dev, "invalid cpuid for IDC%d\n", i);
> > +                       continue;
> > +               }
> > +
> > +               cpumask_set_cpu(cpu, &direct->lmask);
> > +
> > +               idc = per_cpu_ptr(&aplic_idcs, cpu);
> > +               idc->hart_index = i;
> > +               idc->regs = priv->regs + APLIC_IDC_BASE + i * APLIC_IDC_SIZE;
> > +               idc->direct = direct;
> > +
> > +               aplic_idc_set_delivery(idc, true);
> > +
> > +               /*
> > +                * Boot cpu might not have APLIC hart_index = 0 so check
> > +                * and update target registers of all interrupts.
> > +                */
>
> IIUC, the use of smp_processor_id() has to be protected by turning off
> preemption. So maybe please consider adding:
>
> + preempt_disable();
>
> > +               if (cpu == smp_processor_id() && idc->hart_index) {
> > +                       val = idc->hart_index & APLIC_TARGET_HART_IDX_MASK;
> > +                       val <<= APLIC_TARGET_HART_IDX_SHIFT;
> > +                       val |= APLIC_DEFAULT_PRIORITY;
> > +                       for (j = 1; j <= priv->nr_irqs; j++)
> > +                               writel(val, priv->regs + APLIC_TARGET_BASE +
> > +                                           (j - 1) * sizeof(u32));
> > +               }
>
> , and here:
> + preempt_enable();
>
> Or use get_cpu()/put_cpu()  variant to guard the use of processor id.

The get_cpu()/put_cpu() is better so I'll use that in the next revision.

Regards,
Anup

>
> > +
> > +               setup_count++;
> > +       }
> > +
> > +       /* Find parent domain and register chained handler */
> > +       domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(),
> > +                                         DOMAIN_BUS_ANY);
> > +       if (!aplic_direct_parent_irq && domain) {
> > +               aplic_direct_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
> > +               if (aplic_direct_parent_irq) {
> > +                       irq_set_chained_handler(aplic_direct_parent_irq,
> > +                                               aplic_direct_handle_irq);
> > +
> > +                       /*
> > +                        * Setup CPUHP notifier to enable parent
> > +                        * interrupt on all CPUs
> > +                        */
> > +                       cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
> > +                                         "irqchip/riscv/aplic:starting",
> > +                                         aplic_direct_starting_cpu,
> > +                                         aplic_direct_dying_cpu);
> > +               }
> > +       }
> > +
> > +       /* Fail if we were not able to setup IDC for any CPU */
> > +       if (!setup_count) {
> > +               kfree(direct);
> > +               return -ENODEV;
> > +       }
> > +
> > +       /* Setup global config and interrupt delivery */
> > +       aplic_init_hw_global(priv, false);
> > +
> > +       /* Create irq domain instance for the APLIC */
> > +       direct->irqdomain = irq_domain_create_linear(dev->fwnode,
> > +                                                  priv->nr_irqs + 1,
> > +                                                  &aplic_direct_irqdomain_ops,
> > +                                                  priv);
> > +       if (!direct->irqdomain) {
> > +               dev_err(dev, "failed to create direct irq domain\n");
> > +               kfree(direct);
> > +               return -ENOMEM;
> > +       }
> > +
> > +       /* Advertise the interrupt controller */
> > +       dev_info(dev, "%d interrupts directly connected to %d CPUs\n",
> > +                priv->nr_irqs, priv->nr_idcs);
> > +
> > +       return 0;
> > +}
> > diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
> > new file mode 100644
> > index 000000000000..87450708a733
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-aplic-main.c
> > @@ -0,0 +1,232 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
> > + */
> > +
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/printk.h>
> > +#include <linux/module.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/irqchip/riscv-aplic.h>
> > +
> > +#include "irq-riscv-aplic-main.h"
> > +
> > +void aplic_irq_unmask(struct irq_data *d)
> > +{
> > +       struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> > +
> > +       writel(d->hwirq, priv->regs + APLIC_SETIENUM);
> > +}
> > +
> > +void aplic_irq_mask(struct irq_data *d)
> > +{
> > +       struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> > +
> > +       writel(d->hwirq, priv->regs + APLIC_CLRIENUM);
> > +}
> > +
> > +int aplic_irq_set_type(struct irq_data *d, unsigned int type)
> > +{
> > +       u32 val = 0;
> > +       void __iomem *sourcecfg;
> > +       struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
> > +
> > +       switch (type) {
> > +       case IRQ_TYPE_NONE:
> > +               val = APLIC_SOURCECFG_SM_INACTIVE;
> > +               break;
> > +       case IRQ_TYPE_LEVEL_LOW:
> > +               val = APLIC_SOURCECFG_SM_LEVEL_LOW;
> > +               break;
> > +       case IRQ_TYPE_LEVEL_HIGH:
> > +               val = APLIC_SOURCECFG_SM_LEVEL_HIGH;
> > +               break;
> > +       case IRQ_TYPE_EDGE_FALLING:
> > +               val = APLIC_SOURCECFG_SM_EDGE_FALL;
> > +               break;
> > +       case IRQ_TYPE_EDGE_RISING:
> > +               val = APLIC_SOURCECFG_SM_EDGE_RISE;
> > +               break;
> > +       default:
> > +               return -EINVAL;
> > +       }
> > +
> > +       sourcecfg = priv->regs + APLIC_SOURCECFG_BASE;
> > +       sourcecfg += (d->hwirq - 1) * sizeof(u32);
> > +       writel(val, sourcecfg);
> > +
> > +       return 0;
> > +}
> > +
> > +int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
> > +                             unsigned long *hwirq, unsigned int *type)
> > +{
> > +       if (WARN_ON(fwspec->param_count < 2))
> > +               return -EINVAL;
> > +       if (WARN_ON(!fwspec->param[0]))
> > +               return -EINVAL;
> > +
> > +       /* For DT, gsi_base is always zero. */
> > +       *hwirq = fwspec->param[0] - gsi_base;
> > +       *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
> > +
> > +       WARN_ON(*type == IRQ_TYPE_NONE);
> > +
> > +       return 0;
> > +}
> > +
> > +void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
> > +{
> > +       u32 val;
> > +#ifdef CONFIG_RISCV_M_MODE
> > +       u32 valH;
> > +
> > +       if (msi_mode) {
> > +               val = priv->msicfg.base_ppn;
> > +               valH = ((u64)priv->msicfg.base_ppn >> 32) &
> > +                       APLIC_xMSICFGADDRH_BAPPN_MASK;
> > +               valH |= (priv->msicfg.lhxw & APLIC_xMSICFGADDRH_LHXW_MASK)
> > +                       << APLIC_xMSICFGADDRH_LHXW_SHIFT;
> > +               valH |= (priv->msicfg.hhxw & APLIC_xMSICFGADDRH_HHXW_MASK)
> > +                       << APLIC_xMSICFGADDRH_HHXW_SHIFT;
> > +               valH |= (priv->msicfg.lhxs & APLIC_xMSICFGADDRH_LHXS_MASK)
> > +                       << APLIC_xMSICFGADDRH_LHXS_SHIFT;
> > +               valH |= (priv->msicfg.hhxs & APLIC_xMSICFGADDRH_HHXS_MASK)
> > +                       << APLIC_xMSICFGADDRH_HHXS_SHIFT;
> > +               writel(val, priv->regs + APLIC_xMSICFGADDR);
> > +               writel(valH, priv->regs + APLIC_xMSICFGADDRH);
> > +       }
> > +#endif
> > +
> > +       /* Setup APLIC domaincfg register */
> > +       val = readl(priv->regs + APLIC_DOMAINCFG);
> > +       val |= APLIC_DOMAINCFG_IE;
> > +       if (msi_mode)
> > +               val |= APLIC_DOMAINCFG_DM;
> > +       writel(val, priv->regs + APLIC_DOMAINCFG);
> > +       if (readl(priv->regs + APLIC_DOMAINCFG) != val)
> > +               dev_warn(priv->dev, "unable to write 0x%x in domaincfg\n",
> > +                        val);
> > +}
> > +
> > +static void aplic_init_hw_irqs(struct aplic_priv *priv)
> > +{
> > +       int i;
> > +
> > +       /* Disable all interrupts */
> > +       for (i = 0; i <= priv->nr_irqs; i += 32)
> > +               writel(-1U, priv->regs + APLIC_CLRIE_BASE +
> > +                           (i / 32) * sizeof(u32));
> > +
> > +       /* Set interrupt type and default priority for all interrupts */
> > +       for (i = 1; i <= priv->nr_irqs; i++) {
> > +               writel(0, priv->regs + APLIC_SOURCECFG_BASE +
> > +                         (i - 1) * sizeof(u32));
> > +               writel(APLIC_DEFAULT_PRIORITY,
> > +                      priv->regs + APLIC_TARGET_BASE +
> > +                      (i - 1) * sizeof(u32));
> > +       }
> > +
> > +       /* Clear APLIC domaincfg */
> > +       writel(0, priv->regs + APLIC_DOMAINCFG);
> > +}
> > +
> > +int aplic_setup_priv(struct aplic_priv *priv, struct device *dev,
> > +                    void __iomem *regs)
> > +{
> > +       struct of_phandle_args parent;
> > +       int rc;
> > +
> > +       /*
> > +        * Currently, only OF fwnode is supported so extend this
> > +        * function for ACPI support.
> > +        */
> > +       if (!is_of_node(dev->fwnode))
> > +               return -EINVAL;
> > +
> > +       /* Save device pointer and register base */
> > +       priv->dev = dev;
> > +       priv->regs = regs;
> > +
> > +       /* Find out number of interrupt sources */
> > +       rc = of_property_read_u32(to_of_node(dev->fwnode),
> > +                                            "riscv,num-sources",
> > +                                            &priv->nr_irqs);
> > +       if (rc) {
> > +               dev_err(dev, "failed to get number of interrupt sources\n");
> > +               return rc;
> > +       }
> > +
> > +       /*
> > +        * Find out number of IDCs based on parent interrupts
> > +        *
> > +        * If "msi-parent" property is present then we ignore the
> > +        * APLIC IDCs which forces the APLIC driver to use MSI mode.
> > +        */
> > +       if (!of_property_present(to_of_node(dev->fwnode), "msi-parent")) {
> > +               while (!of_irq_parse_one(to_of_node(dev->fwnode),
> > +                                        priv->nr_idcs, &parent))
> > +                       priv->nr_idcs++;
> > +       }
> > +
> > +       /* Setup initial state APLIC interrupts */
> > +       aplic_init_hw_irqs(priv);
> > +
> > +       return 0;
> > +}
> > +
> > +static int aplic_probe(struct platform_device *pdev)
> > +{
> > +       struct device *dev = &pdev->dev;
> > +       bool msi_mode = false;
> > +       struct resource *res;
> > +       void __iomem *regs;
> > +       int rc;
> > +
> > +       /* Map the MMIO registers */
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       if (!res) {
> > +               dev_err(dev, "failed to get MMIO resource\n");
> > +               return -EINVAL;
> > +       }
> > +       regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
> > +       if (!regs) {
> > +               dev_err(dev, "failed map MMIO registers\n");
> > +               return -ENOMEM;
> > +       }
> > +
> > +       /*
> > +        * If msi-parent property is present then setup APLIC MSI
> > +        * mode otherwise setup APLIC direct mode.
> > +        */
> > +       if (is_of_node(dev->fwnode))
> > +               msi_mode = of_property_present(to_of_node(dev->fwnode),
> > +                                               "msi-parent");
> > +       if (msi_mode)
> > +               rc = -ENODEV;
> > +       else
> > +               rc = aplic_direct_setup(dev, regs);
> > +       if (rc) {
> > +               dev_err(dev, "failed setup APLIC in %s mode\n",
> > +                       msi_mode ? "MSI" : "direct");
> > +               return rc;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct of_device_id aplic_match[] = {
> > +       { .compatible = "riscv,aplic" },
> > +       {}
> > +};
> > +
> > +static struct platform_driver aplic_driver = {
> > +       .driver = {
> > +               .name           = "riscv-aplic",
> > +               .of_match_table = aplic_match,
> > +       },
> > +       .probe = aplic_probe,
> > +};
> > +builtin_platform_driver(aplic_driver);
> > diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h
> > new file mode 100644
> > index 000000000000..474a04229334
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-aplic-main.h
> > @@ -0,0 +1,45 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
> > + */
> > +
> > +#ifndef _IRQ_RISCV_APLIC_MAIN_H
> > +#define _IRQ_RISCV_APLIC_MAIN_H
> > +
> > +#include <linux/device.h>
> > +#include <linux/io.h>
> > +#include <linux/irq.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/fwnode.h>
> > +
> > +#define APLIC_DEFAULT_PRIORITY         1
> > +
> > +struct aplic_msicfg {
> > +       phys_addr_t             base_ppn;
> > +       u32                     hhxs;
> > +       u32                     hhxw;
> > +       u32                     lhxs;
> > +       u32                     lhxw;
> > +};
> > +
> > +struct aplic_priv {
> > +       struct device           *dev;
> > +       u32                     gsi_base;
> > +       u32                     nr_irqs;
> > +       u32                     nr_idcs;
> > +       void __iomem            *regs;
> > +       struct aplic_msicfg     msicfg;
> > +};
> > +
> > +void aplic_irq_unmask(struct irq_data *d);
> > +void aplic_irq_mask(struct irq_data *d);
> > +int aplic_irq_set_type(struct irq_data *d, unsigned int type);
> > +int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
> > +                             unsigned long *hwirq, unsigned int *type);
> > +void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode);
> > +int aplic_setup_priv(struct aplic_priv *priv, struct device *dev,
> > +                    void __iomem *regs);
> > +int aplic_direct_setup(struct device *dev, void __iomem *regs);
> > +
> > +#endif
> > diff --git a/include/linux/irqchip/riscv-aplic.h b/include/linux/irqchip/riscv-aplic.h
> > new file mode 100644
> > index 000000000000..97e198ea0109
> > --- /dev/null
> > +++ b/include/linux/irqchip/riscv-aplic.h
> > @@ -0,0 +1,119 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
> > + */
> > +#ifndef __LINUX_IRQCHIP_RISCV_APLIC_H
> > +#define __LINUX_IRQCHIP_RISCV_APLIC_H
> > +
> > +#include <linux/bitops.h>
> > +
> > +#define APLIC_MAX_IDC                  BIT(14)
> > +#define APLIC_MAX_SOURCE               1024
> > +
> > +#define APLIC_DOMAINCFG                        0x0000
> > +#define APLIC_DOMAINCFG_RDONLY         0x80000000
> > +#define APLIC_DOMAINCFG_IE             BIT(8)
> > +#define APLIC_DOMAINCFG_DM             BIT(2)
> > +#define APLIC_DOMAINCFG_BE             BIT(0)
> > +
> > +#define APLIC_SOURCECFG_BASE           0x0004
> > +#define APLIC_SOURCECFG_D              BIT(10)
> > +#define APLIC_SOURCECFG_CHILDIDX_MASK  0x000003ff
> > +#define APLIC_SOURCECFG_SM_MASK        0x00000007
> > +#define APLIC_SOURCECFG_SM_INACTIVE    0x0
> > +#define APLIC_SOURCECFG_SM_DETACH      0x1
> > +#define APLIC_SOURCECFG_SM_EDGE_RISE   0x4
> > +#define APLIC_SOURCECFG_SM_EDGE_FALL   0x5
> > +#define APLIC_SOURCECFG_SM_LEVEL_HIGH  0x6
> > +#define APLIC_SOURCECFG_SM_LEVEL_LOW   0x7
> > +
> > +#define APLIC_MMSICFGADDR              0x1bc0
> > +#define APLIC_MMSICFGADDRH             0x1bc4
> > +#define APLIC_SMSICFGADDR              0x1bc8
> > +#define APLIC_SMSICFGADDRH             0x1bcc
> > +
> > +#ifdef CONFIG_RISCV_M_MODE
> > +#define APLIC_xMSICFGADDR              APLIC_MMSICFGADDR
> > +#define APLIC_xMSICFGADDRH             APLIC_MMSICFGADDRH
> > +#else
> > +#define APLIC_xMSICFGADDR              APLIC_SMSICFGADDR
> > +#define APLIC_xMSICFGADDRH             APLIC_SMSICFGADDRH
> > +#endif
> > +
> > +#define APLIC_xMSICFGADDRH_L           BIT(31)
> > +#define APLIC_xMSICFGADDRH_HHXS_MASK   0x1f
> > +#define APLIC_xMSICFGADDRH_HHXS_SHIFT  24
> > +#define APLIC_xMSICFGADDRH_LHXS_MASK   0x7
> > +#define APLIC_xMSICFGADDRH_LHXS_SHIFT  20
> > +#define APLIC_xMSICFGADDRH_HHXW_MASK   0x7
> > +#define APLIC_xMSICFGADDRH_HHXW_SHIFT  16
> > +#define APLIC_xMSICFGADDRH_LHXW_MASK   0xf
> > +#define APLIC_xMSICFGADDRH_LHXW_SHIFT  12
> > +#define APLIC_xMSICFGADDRH_BAPPN_MASK  0xfff
> > +
> > +#define APLIC_xMSICFGADDR_PPN_SHIFT    12
> > +
> > +#define APLIC_xMSICFGADDR_PPN_HART(__lhxs) \
> > +       (BIT(__lhxs) - 1)
> > +
> > +#define APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) \
> > +       (BIT(__lhxw) - 1)
> > +#define APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs) \
> > +       ((__lhxs))
> > +#define APLIC_xMSICFGADDR_PPN_LHX(__lhxw, __lhxs) \
> > +       (APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) << \
> > +        APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs))
> > +
> > +#define APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) \
> > +       (BIT(__hhxw) - 1)
> > +#define APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs) \
> > +       ((__hhxs) + APLIC_xMSICFGADDR_PPN_SHIFT)
> > +#define APLIC_xMSICFGADDR_PPN_HHX(__hhxw, __hhxs) \
> > +       (APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) << \
> > +        APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs))
> > +
> > +#define APLIC_IRQBITS_PER_REG          32
> > +
> > +#define APLIC_SETIP_BASE               0x1c00
> > +#define APLIC_SETIPNUM                 0x1cdc
> > +
> > +#define APLIC_CLRIP_BASE               0x1d00
> > +#define APLIC_CLRIPNUM                 0x1ddc
> > +
> > +#define APLIC_SETIE_BASE               0x1e00
> > +#define APLIC_SETIENUM                 0x1edc
> > +
> > +#define APLIC_CLRIE_BASE               0x1f00
> > +#define APLIC_CLRIENUM                 0x1fdc
> > +
> > +#define APLIC_SETIPNUM_LE              0x2000
> > +#define APLIC_SETIPNUM_BE              0x2004
> > +
> > +#define APLIC_GENMSI                   0x3000
> > +
> > +#define APLIC_TARGET_BASE              0x3004
> > +#define APLIC_TARGET_HART_IDX_SHIFT    18
> > +#define APLIC_TARGET_HART_IDX_MASK     0x3fff
> > +#define APLIC_TARGET_GUEST_IDX_SHIFT   12
> > +#define APLIC_TARGET_GUEST_IDX_MASK    0x3f
> > +#define APLIC_TARGET_IPRIO_MASK        0xff
> > +#define APLIC_TARGET_EIID_MASK 0x7ff
> > +
> > +#define APLIC_IDC_BASE                 0x4000
> > +#define APLIC_IDC_SIZE                 32
> > +
> > +#define APLIC_IDC_IDELIVERY            0x00
> > +
> > +#define APLIC_IDC_IFORCE               0x04
> > +
> > +#define APLIC_IDC_ITHRESHOLD           0x08
> > +
> > +#define APLIC_IDC_TOPI                 0x18
> > +#define APLIC_IDC_TOPI_ID_SHIFT        16
> > +#define APLIC_IDC_TOPI_ID_MASK 0x3ff
> > +#define APLIC_IDC_TOPI_PRIO_MASK       0xff
> > +
> > +#define APLIC_IDC_CLAIMI               0x1c
> > +
> > +#endif
> > --
> > 2.34.1
> >
> >
> > _______________________________________________
> > linux-riscv mailing list
> > linux-riscv at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-riscv
>
> Thanks,
> Andy


From james.clark at arm.com  Mon Feb 19 02:38:16 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 19 Feb 2024 10:38:16 +0000
Subject: [PATCH v3 2/8] libperf cpumap: Ensure empty cpumap is NULL from
 alloc
In-Reply-To: <CAP-5=fVNLoes2VaCcqrueiDLBZAZNthSJVD17z77cnyE7wF7ag@mail.gmail.com>
References: <20240202234057.2085863-1-irogers@google.com>
 <20240202234057.2085863-3-irogers@google.com>
 <CAM9d7ci3VO7reyxPc8WOczdoyYYCUshxCJDMZ7wPpHknCubNXQ@mail.gmail.com>
 <CAP-5=fVNLoes2VaCcqrueiDLBZAZNthSJVD17z77cnyE7wF7ag@mail.gmail.com>
Message-ID: <b260e3e1-ebe9-4fc2-6b81-bc4735a7bb66@arm.com>



On 17/02/2024 00:52, Ian Rogers wrote:
> On Fri, Feb 16, 2024 at 4:25?PM Namhyung Kim <namhyung at kernel.org> wrote:
>>
>> On Fri, Feb 2, 2024 at 3:41?PM Ian Rogers <irogers at google.com> wrote:
>>>
>>> Potential corner cases could cause a cpumap to be allocated with size
>>> 0, but an empty cpumap should be represented as NULL. Add a path in
>>> perf_cpu_map__alloc to ensure this.
>>>
>>> Suggested-by: James Clark <james.clark at arm.com>
>>> Closes: https://lore.kernel.org/lkml/2cd09e7c-eb88-6726-6169-647dcd0a8101 at arm.com/
>>> Signed-off-by: Ian Rogers <irogers at google.com>
>>> ---
>>>  tools/lib/perf/cpumap.c | 6 +++++-
>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c
>>> index ba49552952c5..cae799ad44e1 100644
>>> --- a/tools/lib/perf/cpumap.c
>>> +++ b/tools/lib/perf/cpumap.c
>>> @@ -18,9 +18,13 @@ void perf_cpu_map__set_nr(struct perf_cpu_map *map, int nr_cpus)
>>>
>>>  struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus)
>>>  {
>>> -       RC_STRUCT(perf_cpu_map) *cpus = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
>>> +       RC_STRUCT(perf_cpu_map) *cpus;
>>>         struct perf_cpu_map *result;
>>>
>>> +       if (nr_cpus == 0)
>>> +               return NULL;
>>
>> But allocation failure also returns NULL.  Then callers should check
>> what's the expected result.>
> Right, we don't have a habit of just aborting on memory allocation

I'm not sure why we don't abort on allocation. It would simplify the
code a lot and wouldn't change the behavior in any meaningful way. And
it would also allow us to print out which line exactly failed which is
much more useful than bubbling up the error and hiding it.

If we're making the decision that an empty map == NULL rather than
non-null but with 0 length then maybe it's time to start thinking about it.

> errors. In the case that NULL is returned it is assumed that an empty
> CPU map is appropriate. Adding checks throughout the code base that an
> empty CPU map is only returned when 0 is given is beyond the scope of
> this patch set.
> 
> Thanks,
> Ian
> 


>> Thanks,
>> Namhyung
>>
>>> +
>>> +       cpus = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
>>>         if (ADD_RC_CHK(result, cpus)) {
>>>                 cpus->nr = nr_cpus;
>>>                 refcount_set(&cpus->refcnt, 1);
>>> --
>>> 2.43.0.594.gd9cf4e227d-goog
>>>


From romain.gantois at bootlin.com  Mon Feb 19 02:40:56 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Mon, 19 Feb 2024 11:40:56 +0100 (CET)
Subject: [PATCH] net: stmmac: fix rx queue priority assignment
In-Reply-To: <20240219102405.32015-1-piotrwejman90@gmail.com>
References: <20240219102405.32015-1-piotrwejman90@gmail.com>
Message-ID: <6bb634fb-fe02-085b-a96f-ea56698ebcb4@bootlin.com>

Hello Piotr,

On Mon, 19 Feb 2024, Piotr Wejman wrote:

>  static void dwmac4_rx_queue_priority(struct mac_device_info *hw,
> -				     u32 prio, u32 queue)
> +				     u32 prio_mask, u32 queue)
>  {
>  	void __iomem *ioaddr = hw->pcsr;
> -	u32 base_register;
> -	u32 value;
> +	u32 clear_mask = 0;
> +	u32 ctrl2, ctrl3;
> +	int i;
>  
> -	base_register = (queue < 4) ? GMAC_RXQ_CTRL2 : GMAC_RXQ_CTRL3;
> -	if (queue >= 4)
> -		queue -= 4;
> +	ctrl2 = readl(ioaddr + GMAC_RXQ_CTRL2);
> +	ctrl3 = readl(ioaddr + GMAC_RXQ_CTRL3);
>  
> -	value = readl(ioaddr + base_register);
> +	for (i = 0; i < 4; i++)
> +		clear_mask |= ((prio_mask << GMAC_RXQCTRL_PSRQX_SHIFT(i)) &
> +						GMAC_RXQCTRL_PSRQX_MASK(i));
>  
> -	value &= ~GMAC_RXQCTRL_PSRQX_MASK(queue);
> -	value |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
> +	ctrl2 &= ~clear_mask;
> +	ctrl3 &= ~clear_mask;
> +
> +	if (queue < 4) {
> +		ctrl2 |= (prio_mask << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
This is a bit of a nitpick but do you think it would make sense to replace that 
"4" with a macro? Something like GMAC_RXQCTRL_PSRXQ_MAXCTRL2QUEUE?

>  						GMAC_RXQCTRL_PSRQX_MASK(queue);
> -	writel(value, ioaddr + base_register);
> +
> +		writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
> +		writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
I suppose that the order of these two writes are somehow important, else these 
could be factored out of the conditional block. Could you maybe add a short 
comment that explains why the order of these writes matter?

Best Regards,

-- 
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From jesper.nilsson at axis.com  Mon Feb 19 02:40:25 2024
From: jesper.nilsson at axis.com (Jesper Nilsson)
Date: Mon, 19 Feb 2024 11:40:25 +0100
Subject: [PATCH] net: stmmac: mmc_core: Assign, don't add interrupt
 registers
In-Reply-To: <61bdd802-abe4-4544-8e48-9493a6bb99c8@gmail.com>
References: <20240216-stmmac_stats-v1-1-7065fa4613f8@axis.com>
 <61bdd802-abe4-4544-8e48-9493a6bb99c8@gmail.com>
Message-ID: <20240219104025.GM22484@axis.com>

On Fri, Feb 16, 2024 at 09:13:51AM -0800, Florian Fainelli wrote:
> So in premise I agree with the patch, that incrementing those is not the
> right way to go about them. However these registers are currently provided
> as part of the statistics set, but they should instead be accessed via the
> register dumping method.

You mean extending the dump register code to dump the MAC Management Counter
registers that are not counters?
>From what I understand it's only the Rx and Tx interrupt and interrupt mask
registers that aren't counters. Oh, and the MMC control register itself?

To be honest, I don't think their use can justify the code churn.

> In either case you will get at best a snapshot of those two registers at any
> given time and I suppose this can help diagnose a stuck RX condition, but
> not much more than that.

Yeah, their use is very doubtful. For me, they only introduce more nonsense
data in my logs.

The Rx registers looks to have been added in the first version of the MMC
back in 2011, but the Tx registers never was.
In commit 1c901a46d57 Giuseppe mentions the MMC interrupts as something to
add later (if actually useful).

So Serge's suggestion to drop the entries completely is actually quite attractive.

> Florian

/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson at axis.com


From mark.rutland at arm.com  Mon Feb 19 02:48:26 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 19 Feb 2024 10:48:26 +0000
Subject: [PATCH] arm64: add early fixmap initialization flag
In-Reply-To: <20240217140326.2367186-1-skseofh@gmail.com>
References: <20240217140326.2367186-1-skseofh@gmail.com>
Message-ID: <ZdMx-svsHgrfguxX@FVFF77S0Q05N>

On Sat, Feb 17, 2024 at 11:03:26PM +0900, skseofh at gmail.com wrote:
> From: Daero Lee <skseofh at gmail.com>
> 
> early_fixmap_init may be called multiple times. Since there is no
> change in the page table after early fixmap initialization, an
> initialization flag was added.

Why is that better?

We call early_fixmap_init() in two places:

* early_fdt_map()
* setup_arch()

... and to get to setup_arch() we *must* have gone through early_fdt_map(),
since __primary_switched() calls that before going to setup_arch().

So AFAICT we can remove the second call to early_fixmap_init() in setup_arch(),
and rely on the earlier one in early_fdt_map().

Mark.

> 
> Signed-off-by: Daero Lee <skseofh at gmail.com>
> ---
>  arch/arm64/mm/fixmap.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
> index c0a3301203bd..fbdd5f30f3a1 100644
> --- a/arch/arm64/mm/fixmap.c
> +++ b/arch/arm64/mm/fixmap.c
> @@ -32,6 +32,8 @@ static pte_t bm_pte[NR_BM_PTE_TABLES][PTRS_PER_PTE] __page_aligned_bss;
>  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 int early_fixmap_initialized __initdata;
> +
>  static inline pte_t *fixmap_pte(unsigned long addr)
>  {
>  	return &bm_pte[BM_PTE_TABLE_IDX(addr)][pte_index(addr)];
> @@ -100,10 +102,15 @@ void __init early_fixmap_init(void)
>  	unsigned long addr = FIXADDR_TOT_START;
>  	unsigned long end = FIXADDR_TOP;
>  
> +	if (early_fixmap_initialized)
> +		return;
> +
>  	pgd_t *pgdp = pgd_offset_k(addr);
>  	p4d_t *p4dp = p4d_offset(pgdp, addr);
>  
>  	early_fixmap_init_pud(p4dp, addr, end);
> +
> +	early_fixmap_initialized = 1;
>  }
>  
>  /*
> -- 
> 2.25.1
> 


From wenst at chromium.org  Mon Feb 19 02:51:24 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 19 Feb 2024 18:51:24 +0800
Subject: [PATCH] clk: mediatek: mt8183: Correct parent of CLK_INFRA_SSPM_32K_SELF
Message-ID: <20240219105125.956278-1-wenst@chromium.org>

CLK_INFRA_SSPM_32K_SELF has the "f_f26m_ck" clock assigned as its parent.
This is inconsistent as the clock is part of a group that are all gates
without dividers, and this makes the kernel think it runs at 26 MHz.

After clarification from MediaTek engineers, the correct parent is
actually the system 32 KHz clock.

Fixes: 1eb8d61ac5c9 ("clk: mediatek: mt8183: Add back SSPM related clocks")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mt8183.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c
index 6e23461a0455..934d5a15acfc 100644
--- a/drivers/clk/mediatek/clk-mt8183.c
+++ b/drivers/clk/mediatek/clk-mt8183.c
@@ -790,7 +790,7 @@ static const struct mtk_gate infra_clks[] = {
 	/* infra_sspm_26m_self is main clock in co-processor, should not be closed in Linux. */
 	GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_26M_SELF, "infra_sspm_26m_self", "f_f26m_ck", 3, CLK_IS_CRITICAL),
 	/* infra_sspm_32k_self is main clock in co-processor, should not be closed in Linux. */
-	GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self", "f_f26m_ck", 4, CLK_IS_CRITICAL),
+	GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self", "clk32k", 4, CLK_IS_CRITICAL),
 	GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi", "axi_sel", 5),
 	GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6", "i2c_sel", 6),
 	GATE_INFRA3(CLK_INFRA_AP_MSDC0, "infra_ap_msdc0", "msdc50_hclk_sel", 7),
-- 
2.44.0.rc0.258.g7320e95886-goog



From ardb at kernel.org  Mon Feb 19 02:56:24 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 19 Feb 2024 11:56:24 +0100
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>
References: <20240206074552.541154-1-maskray@google.com> <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>
Message-ID: <CAMj1kXGaF5bobHTr1pTg+-=s4Ft7+5SSbX72-NxsR_W_Yuxb8Q@mail.gmail.com>

On Mon, 19 Feb 2024 at 11:03, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>
> Hi Fangrui,
>
> On Tue, Feb 6, 2024 at 8:46?AM Fangrui Song <maskray at google.com> wrote:
> > The generic constraint "i" seems to be copied from x86 or arm (and with
> > a redundant generic operand modifier "c"). It works with -fno-PIE but
> > not with -fPIE/-fPIC in GCC's aarch64 port.
>
> Thanks for your patch, which is now commit f9daab0ad01cf9d1 ("arm64:
> jump_label: use constraints "Si" instead of "i"") in v6.8-rc5.
>
> > The machine constraint "S", which denotes a symbol or label reference
> > with a constant offset, supports PIC and has been available in GCC since
> > 2012 and in Clang since 7.0. However, Clang before 19 does not support
> > "S" on a symbol with a constant offset [1] (e.g.
> > `static_key_false(&nf_hooks_needed[pf][hook])` in
> > include/linux/netfilter.h), so we use "i" as a fallback.
>
> https://gcc.gnu.org/releases.html says gcc-5 was released in 2015,
> i.e. after 2012 ...
>
> > Suggested-by: Ard Biesheuvel <ardb at kernel.org>
> > Signed-off-by: Fangrui Song <maskray at google.com>
> > Link: https://github.com/llvm/llvm-project/pull/80255 [1]
> >
> > ---
> > Changes from
> > arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
> >
> > * Use "Si" as Ard suggested to support Clang<19
> > * Make branch a separate operand
> >
> > Changes from v1:
> >
> > * Use asmSymbolicName for readability
>
> But it still fails on gcc-5:
>
>     arch/arm64/include/asm/jump_label.h:25:2: error: invalid 'asm':
> invalid operand
>       asm goto(
>       ^
>
> http://kisskb.ellerman.id.au/kisskb/buildresult/15129281/
>

How odd. godbolt.org has 5.4 and it seems perfectly happy with it.

https://godbolt.org/z/szzG3s59K


From ardb at kernel.org  Mon Feb 19 02:57:04 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 19 Feb 2024 11:57:04 +0100
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <CAMj1kXGaF5bobHTr1pTg+-=s4Ft7+5SSbX72-NxsR_W_Yuxb8Q@mail.gmail.com>
References: <20240206074552.541154-1-maskray@google.com> <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>
 <CAMj1kXGaF5bobHTr1pTg+-=s4Ft7+5SSbX72-NxsR_W_Yuxb8Q@mail.gmail.com>
Message-ID: <CAMj1kXGw+r7yEEBA8gYBcdrqkiP=VYOSzz9YLnNavJn2snmFwA@mail.gmail.com>

On Mon, 19 Feb 2024 at 11:56, Ard Biesheuvel <ardb at kernel.org> wrote:
>
> On Mon, 19 Feb 2024 at 11:03, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> >
> > Hi Fangrui,
> >
> > On Tue, Feb 6, 2024 at 8:46?AM Fangrui Song <maskray at google.com> wrote:
> > > The generic constraint "i" seems to be copied from x86 or arm (and with
> > > a redundant generic operand modifier "c"). It works with -fno-PIE but
> > > not with -fPIE/-fPIC in GCC's aarch64 port.
> >
> > Thanks for your patch, which is now commit f9daab0ad01cf9d1 ("arm64:
> > jump_label: use constraints "Si" instead of "i"") in v6.8-rc5.
> >
> > > The machine constraint "S", which denotes a symbol or label reference
> > > with a constant offset, supports PIC and has been available in GCC since
> > > 2012 and in Clang since 7.0. However, Clang before 19 does not support
> > > "S" on a symbol with a constant offset [1] (e.g.
> > > `static_key_false(&nf_hooks_needed[pf][hook])` in
> > > include/linux/netfilter.h), so we use "i" as a fallback.
> >
> > https://gcc.gnu.org/releases.html says gcc-5 was released in 2015,
> > i.e. after 2012 ...
> >
> > > Suggested-by: Ard Biesheuvel <ardb at kernel.org>
> > > Signed-off-by: Fangrui Song <maskray at google.com>
> > > Link: https://github.com/llvm/llvm-project/pull/80255 [1]
> > >
> > > ---
> > > Changes from
> > > arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
> > >
> > > * Use "Si" as Ard suggested to support Clang<19
> > > * Make branch a separate operand
> > >
> > > Changes from v1:
> > >
> > > * Use asmSymbolicName for readability
> >
> > But it still fails on gcc-5:
> >
> >     arch/arm64/include/asm/jump_label.h:25:2: error: invalid 'asm':
> > invalid operand
> >       asm goto(
> >       ^
> >
> > http://kisskb.ellerman.id.au/kisskb/buildresult/15129281/
> >
>
> How odd. godbolt.org has 5.4 and it seems perfectly happy with it.
>
> https://godbolt.org/z/szzG3s59K

Wrong link

https://godbolt.org/z/GTnf3vPaT


From sabiya.d at mistralsolutions.com  Mon Feb 19 03:14:20 2024
From: sabiya.d at mistralsolutions.com (sabiya.d at mistralsolutions.com)
Date: Mon, 19 Feb 2024 16:44:20 +0530
Subject: [RESEND PATCH V2 0/2] Add CAN and OSPI support for AM69-SK platform
Message-ID: <20240219111422.171315-1-sabiya.d@ti.com>

From: Dasnavis Sabiya <sabiya.d at ti.com>

Hi All,

This series adds support for the below interfaces on AM69-SK platform:
-  CAN support on both MCU and MAIN domains
-  OSPI NOR flash support

v2: Changelog:
1) Removed CAN interface aliasing.
2) Updated bootph property on the leaf nodes.

Resending version 2 adding linux-arm-kernel mailing list
Link to v1: https://lore.kernel.org/lkml/20240118153524.4135901-1-sabiya.d at ti.com/
Link to v2: https://lore.kernel.org/all/1d5c0570-fa10-4b87-9833-1710f33db01f at ti.com/

Dasnavis Sabiya (2):
  arm64: dts: ti: k3-am69-sk: Enable CAN interfaces for AM69 SK board
  arm64: dts: ti: k3-am69-sk: Add support for OSPI flash

 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 162 ++++++++++++++++++++++++++
 1 file changed, 162 insertions(+)

-- 
2.34.1



From sabiya.d at mistralsolutions.com  Mon Feb 19 03:14:21 2024
From: sabiya.d at mistralsolutions.com (sabiya.d at mistralsolutions.com)
Date: Mon, 19 Feb 2024 16:44:21 +0530
Subject: [RESEND PATCH V2 1/2] arm64: dts: ti: k3-am69-sk: Enable CAN interfaces for AM69 SK board
In-Reply-To: <20240219111422.171315-1-sabiya.d@ti.com>
References: <20240219111422.171315-1-sabiya.d@ti.com>
Message-ID: <20240219111422.171315-2-sabiya.d@ti.com>

From: Dasnavis Sabiya <sabiya.d at ti.com>

AM69 SK board has several CAN bus interfaces on both MCU and MAIN domains.
This enables the CAN interfaces on MCU and MAIN domain.

Signed-off-by: Dasnavis Sabiya <sabiya.d at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 81 +++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 475bcec99bd6..0ff4d1623cf4 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -322,6 +322,31 @@ tfp410_out: endpoint {
 			};
 		};
 	};
+
+	transceiver1: can-phy0 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver2: can-phy1 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver3: can-phy2 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver4: can-phy3 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
 };
 
 &main_pmx0 {
@@ -430,6 +455,20 @@ hdmi_hpd_pins_default: hdmi-hpd-default-pins {
 			J784S4_IOPAD(0x000, PIN_INPUT, 7) /* (AN35) EXTINTN.GPIO0_0 */
 		>;
 	};
+
+	main_mcan6_pins_default: main-mcan6-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x098, PIN_INPUT, 0) /* (AH36) MCAN6_RX */
+			J784S4_IOPAD(0x094, PIN_OUTPUT, 0) /* (AG35) MCAN6_TX */
+		>;
+	};
+
+	main_mcan7_pins_default: main-mcan7-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0A0, PIN_INPUT, 0) /* (AD34) MCAN7_RX */
+			J784S4_IOPAD(0x09C, PIN_OUTPUT, 0) /* (AF35) MCAN7_TX */
+		>;
+	};
 };
 
 &wkup_pmx2 {
@@ -526,6 +565,20 @@ hdmi_pdn_pins_default: hdmi-pdn-default-pins {
 			J784S4_WKUP_IOPAD(0x090, PIN_INPUT, 7) /* (H37) WKUP_GPIO0_14 */
 		>;
 	};
+
+	mcu_mcan0_pins_default: mcu-mcan0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x054, PIN_INPUT, 0) /* (F38) MCU_MCAN0_RX */
+			J784S4_WKUP_IOPAD(0x050, PIN_OUTPUT, 0) /* (K33) MCU_MCAN0_TX */
+		>;
+	};
+
+	mcu_mcan1_pins_default: mcu-mcan1-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (K36) WKUP_GPIO0_5.MCU_MCAN1_RX */
+			J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0)/* (H35) WKUP_GPIO0_4.MCU_MCAN1_TX */
+		>;
+	};
 };
 
 &wkup_pmx3 {
@@ -989,3 +1042,31 @@ dp0_out: endpoint {
 		};
 	};
 };
+
+&mcu_mcan0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan0_pins_default>;
+	phys = <&transceiver1>;
+};
+
+&mcu_mcan1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan1_pins_default>;
+	phys = <&transceiver2>;
+};
+
+&main_mcan6 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan6_pins_default>;
+	phys = <&transceiver3>;
+};
+
+&main_mcan7 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan7_pins_default>;
+	phys = <&transceiver4>;
+};
-- 
2.34.1



From sabiya.d at mistralsolutions.com  Mon Feb 19 03:14:22 2024
From: sabiya.d at mistralsolutions.com (sabiya.d at mistralsolutions.com)
Date: Mon, 19 Feb 2024 16:44:22 +0530
Subject: [RESEND PATCH V2 2/2] arm64: dts: ti: k3-am69-sk: Add support for OSPI flash
In-Reply-To: <20240219111422.171315-1-sabiya.d@ti.com>
References: <20240219111422.171315-1-sabiya.d@ti.com>
Message-ID: <20240219111422.171315-3-sabiya.d@ti.com>

From: Dasnavis Sabiya <sabiya.d at ti.com>

AM69 SK has S28HS512T OSPI flash connected to MCU OSPI0.
Enable support for the same. Also describe the partition
information according to the offsets in the bootloader.

Signed-off-by: Dasnavis Sabiya <sabiya.d at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 81 +++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 0ff4d1623cf4..acda25a9e814 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -471,6 +471,25 @@ J784S4_IOPAD(0x09C, PIN_OUTPUT, 0) /* (AF35) MCAN7_TX */
 	};
 };
 
+&wkup_pmx0 {
+	bootph-all;
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (E32) MCU_OSPI0_CLK */
+			J784S4_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (A32) MCU_OSPI0_CSn0 */
+			J784S4_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (B33) MCU_OSPI0_D0 */
+			J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (B32) MCU_OSPI0_D1 */
+			J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (C33) MCU_OSPI0_D2 */
+			J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (C35) MCU_OSPI0_D3 */
+			J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (D33) MCU_OSPI0_D4 */
+			J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D34) MCU_OSPI0_D5 */
+			J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (E34) MCU_OSPI0_D6 */
+			J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (E33) MCU_OSPI0_D7 */
+			J784S4_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (C34) MCU_OSPI0_DQS */
+		>;
+	};
+};
+
 &wkup_pmx2 {
 	bootph-all;
 	pmic_irq_pins_default: pmic-irq-default-pins {
@@ -1070,3 +1089,65 @@ &main_mcan7 {
 	pinctrl-0 = <&main_mcan7_pins_default>;
 	phys = <&transceiver4>;
 };
+
+&ospi0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <4>;
+
+		partitions {
+			bootph-all;
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "ospi.tiboot3";
+				reg = <0x0 0x80000>;
+			};
+
+			partition at 80000 {
+				label = "ospi.tispl";
+				reg = <0x80000 0x200000>;
+			};
+
+			partition at 280000 {
+				label = "ospi.u-boot";
+				reg = <0x280000 0x400000>;
+			};
+
+			partition at 680000 {
+				label = "ospi.env";
+				reg = <0x680000 0x40000>;
+			};
+
+			partition at 6c0000 {
+				label = "ospi.env.backup";
+				reg = <0x6c0000 0x40000>;
+			};
+
+			partition at 800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition at 3fc0000 {
+				bootph-pre-ram;
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+};
-- 
2.34.1



From mo.c.weber at gmail.com  Mon Feb 19 03:22:32 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Mon, 19 Feb 2024 12:22:32 +0100
Subject: [PATCH v3 0/2] Staging: vc04_services: bcm2835-camera: Fix code style checks
In-Reply-To: <236d985c-1835-410f-b0b5-cacbd5fbf930@moroto.mountain>
References: <236d985c-1835-410f-b0b5-cacbd5fbf930@moroto.mountain>
Message-ID: <20240219112234.8673-1-mo.c.weber@gmail.com>

Resubmit these patches to address comments to rebase the 8 v2 changes into
2 patches topicwise
Fix patches with same subject issue based on v2, which fixes multiple code
style checks for better readability, consistency, and fixes typos from v1

Moritz C. Weber (2):
  Staging: vc04_services: bcm2835-camera: fix blank line style check
  Staging: vc04_services: bcm2835-camera: fix brace code style check

 .../bcm2835-camera/bcm2835-camera.c           | 61 +++++++++----------
 1 file changed, 28 insertions(+), 33 deletions(-)

-- 
2.30.2



From mo.c.weber at gmail.com  Mon Feb 19 03:22:33 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Mon, 19 Feb 2024 12:22:33 +0100
Subject: [PATCH v3 1/2] Staging: vc04_services: bcm2835-camera: fix blank line style check
In-Reply-To: <20240219112234.8673-1-mo.c.weber@gmail.com>
References: <236d985c-1835-410f-b0b5-cacbd5fbf930@moroto.mountain>
 <20240219112234.8673-1-mo.c.weber@gmail.com>
Message-ID: <20240219112234.8673-2-mo.c.weber@gmail.com>

Remove blank line to fix checkpatch check:
Increase readability and consistency

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index e6e89784d..e6ff5ea04 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -1006,7 +1006,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	return 0;
 }
 
-
 static int mmal_setup_video_component(struct bcm2835_mmal_dev *dev,
 				      struct v4l2_format *f)
 {
-- 
2.30.2



From mo.c.weber at gmail.com  Mon Feb 19 03:22:34 2024
From: mo.c.weber at gmail.com (Moritz C. Weber)
Date: Mon, 19 Feb 2024 12:22:34 +0100
Subject: [PATCH v3 2/2] Staging: vc04_services: bcm2835-camera: fix brace code style check
In-Reply-To: <20240219112234.8673-1-mo.c.weber@gmail.com>
References: <236d985c-1835-410f-b0b5-cacbd5fbf930@moroto.mountain>
 <20240219112234.8673-1-mo.c.weber@gmail.com>
Message-ID: <20240219112234.8673-3-mo.c.weber@gmail.com>

Reformat function parameters to fix checkpatch check:
Increase readability and consistency

Signed-off-by: Moritz C. Weber <mo.c.weber at gmail.com>
---
 .../bcm2835-camera/bcm2835-camera.c           | 60 +++++++++----------
 1 file changed, 28 insertions(+), 32 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index e6ff5ea04..c3ba490e5 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -350,12 +350,11 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
 			if (is_capturing(dev)) {
 				v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 					 "Grab another frame");
-				vchiq_mmal_port_parameter_set(
-					instance,
-					dev->capture.camera_port,
-					MMAL_PARAMETER_CAPTURE,
-					&dev->capture.frame_count,
-					sizeof(dev->capture.frame_count));
+				vchiq_mmal_port_parameter_set(instance,
+							      dev->capture.camera_port,
+							      MMAL_PARAMETER_CAPTURE,
+							      &dev->capture.frame_count,
+							      sizeof(dev->capture.frame_count));
 			}
 			if (vchiq_mmal_submit_buffer(instance, port,
 						     &buf->mmal))
@@ -406,12 +405,11 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
 	    is_capturing(dev)) {
 		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 			 "Grab another frame as buffer has EOS");
-		vchiq_mmal_port_parameter_set(
-			instance,
-			dev->capture.camera_port,
-			MMAL_PARAMETER_CAPTURE,
-			&dev->capture.frame_count,
-			sizeof(dev->capture.frame_count));
+		vchiq_mmal_port_parameter_set(instance,
+					      dev->capture.camera_port,
+					      MMAL_PARAMETER_CAPTURE,
+					      &dev->capture.frame_count,
+					      sizeof(dev->capture.frame_count));
 	}
 }
 
@@ -420,11 +418,10 @@ static int enable_camera(struct bcm2835_mmal_dev *dev)
 	int ret;
 
 	if (!dev->camera_use_count) {
-		ret = vchiq_mmal_port_parameter_set(
-			dev->instance,
-			&dev->component[COMP_CAMERA]->control,
-			MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num,
-			sizeof(dev->camera_num));
+		ret = vchiq_mmal_port_parameter_set(dev->instance,
+						    &dev->component[COMP_CAMERA]->control,
+						    MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num,
+						    sizeof(dev->camera_num));
 		if (ret < 0) {
 			v4l2_err(&dev->v4l2_dev,
 				 "Failed setting camera num, ret %d\n", ret);
@@ -468,11 +465,11 @@ static int disable_camera(struct bcm2835_mmal_dev *dev)
 				 "Failed disabling camera, ret %d\n", ret);
 			return -EINVAL;
 		}
-		vchiq_mmal_port_parameter_set(
-			dev->instance,
-			&dev->component[COMP_CAMERA]->control,
-			MMAL_PARAMETER_CAMERA_NUM, &i,
-			sizeof(i));
+		vchiq_mmal_port_parameter_set(dev->instance,
+					      &dev->component[COMP_CAMERA]->control,
+					      MMAL_PARAMETER_CAMERA_NUM,
+					      &i,
+					      sizeof(i));
 	}
 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 		 "Camera refcount now %d\n", dev->camera_use_count);
@@ -786,9 +783,8 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on)
 			ret = vchiq_mmal_port_connect_tunnel(dev->instance, src,
 							     NULL);
 		if (ret >= 0)
-			ret = vchiq_mmal_component_disable(
-					dev->instance,
-					dev->component[COMP_PREVIEW]);
+			ret = vchiq_mmal_component_disable(dev->instance,
+							   dev->component[COMP_PREVIEW]);
 
 		disable_camera(dev);
 		return ret;
@@ -1041,8 +1037,8 @@ static int mmal_setup_video_component(struct bcm2835_mmal_dev *dev,
 
 	if (overlay_enabled) {
 		ret = vchiq_mmal_port_connect_tunnel(dev->instance,
-				preview_port,
-				&dev->component[COMP_PREVIEW]->input[0]);
+						     preview_port,
+						     &dev->component[COMP_PREVIEW]->input[0]);
 		if (ret)
 			return ret;
 
@@ -1719,11 +1715,11 @@ static int mmal_init(struct bcm2835_mmal_dev *dev)
 	{
 		unsigned int enable = 1;
 
-		vchiq_mmal_port_parameter_set(
-			dev->instance,
-			&dev->component[COMP_VIDEO_ENCODE]->control,
-			MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
-			&enable, sizeof(enable));
+		vchiq_mmal_port_parameter_set(dev->instance,
+					      &dev->component[COMP_VIDEO_ENCODE]->control,
+					      MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
+					      &enable,
+					      sizeof(enable));
 
 		vchiq_mmal_port_parameter_set(dev->instance,
 					      &dev->component[COMP_VIDEO_ENCODE]->control,
-- 
2.30.2



From Jonathan.Cameron at Huawei.com  Mon Feb 19 03:29:38 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Mon, 19 Feb 2024 11:29:38 +0000
Subject: [PATCH v1 2/6] drivers/perf: Add SiFive Composable Cache PMU
 driver
In-Reply-To: <20240216000837.1868917-3-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
	<20240216000837.1868917-3-samuel.holland@sifive.com>
Message-ID: <20240219112938.00002654@Huawei.com>

On Thu, 15 Feb 2024 16:08:14 -0800
Samuel Holland <samuel.holland at sifive.com> wrote:

> From: Eric Lin <eric.lin at sifive.com>
> 
> Add a driver for the PMU found in the SiFive Composable Cache
> controller. This PMU provides a configurable number of counters and a
> variety of events. Events are grouped into sets. Each counter can count
> events from only one set at a time; however, it can count any number of
> events within that set simultaneously. The PMU hardware does not provide
> an overflow interrupt or a way to atomically control groups of counters.
> 
> Some events can be filtered further by client ID (e.g. CPU or external
> DMA master). That functionality is not supported by this driver.
> 
> This driver further assumes that a single Composable Cache instance is
> shared by all CPUs in the system.
> 
> Example usage:
> 
> $ perf stat -a -e sifive_ccache_pmu/inner_acquire_block_btot/,
> 		  sifive_ccache_pmu/inner_acquire_block_hit/,
> 		  sifive_ccache_pmu/inner_acquire_block_ntob/ ls
> 
>  Performance counter stats for 'system wide':
> 
>                542      sifive_ccache_pmu/inner_acquire_block_btot/
>              22081      sifive_ccache_pmu/inner_acquire_block_hit/
>              22006      sifive_ccache_pmu/inner_acquire_block_ntob/
> 
>        0.064672432 seconds time elapsed
> 
> Example using numeric event selectors:
> 
> $ perf stat -a -e sifive_ccache_pmu/event=0x10001/,
> 		  sifive_ccache_pmu/event=0x2002/,
> 		  sifive_ccache_pmu/event=0x4001/ ls
> 
>  Performance counter stats for 'system wide':
> 
>                478      sifive_ccache_pmu/event=0x10001/
>               4717      sifive_ccache_pmu/event=0x2002/
>              44966      sifive_ccache_pmu/event=0x4001/
> 
>        0.111027326 seconds time elapsed
> 
> Signed-off-by: Eric Lin <eric.lin at sifive.com>
> Co-developed-by: Samuel Holland <samuel.holland at sifive.com>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>


Hi Samuel,

A few comments inline.

> diff --git a/drivers/perf/sifive_ccache_pmu.c b/drivers/perf/sifive_ccache_pmu.c
> new file mode 100644
> index 000000000000..8c9ef0d09f48
> --- /dev/null
> +++ b/drivers/perf/sifive_ccache_pmu.c


> +
> +#define to_ccache_pmu(p) (container_of(p, struct sifive_ccache_pmu, pmu))
> +
> +#ifndef readq
> +static inline u64 readq(void __iomem *addr)
> +{
> +	return readl(addr) | (((u64)readl(addr + 4)) << 32);
> +}
> +#endif
> +
> +#ifndef writeq
> +static inline void writeq(u64 v, void __iomem *addr)
> +{
> +	writel(lower_32_bits(v), addr);
> +	writel(upper_32_bits(v), addr + 4);

Include io-64-nonatomic-lo-hi.h 
and you shouldn't need these.

> +}
> +#endif


> +
> +/*
> + * pmu->stop: stop the counter
> + */
> +static void sifive_ccache_pmu_stop(struct perf_event *event, int flags)
> +{
> +	struct hw_perf_event *hwc = &event->hw;
> +
> +	if (hwc->state & PERF_HES_STOPPED)
> +		return;
> +
> +	/* Disable this counter to count events */
> +	writeq(0, (void *)hwc->config_base);

Not going to give address space warnings as writeq expects
__iomem?

> +	sifive_ccache_pmu_read(event);
> +
> +	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
> +}



> +/*
> + * pmu->del: delete the event from the PMU
Why use multi line comments?
> + */
> +static void sifive_ccache_pmu_del(struct perf_event *event, int flags)
> +{
> +	struct sifive_ccache_pmu *ccache_pmu = to_ccache_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	int idx = hwc->idx;
> +
> +	/* Stop and release this counter */
> +	sifive_ccache_pmu_stop(event, PERF_EF_UPDATE);
> +
> +	ccache_pmu->events[idx] = NULL;
> +	clear_bit(idx, ccache_pmu->used_mask);
> +
> +	perf_event_update_userpage(event);
> +}
> +
> +/*
> + * Driver initialization

Probably drop generic code organization comments like this.
They just rot over time and provide little benefit.

> + */

...

> +
> +static int sifive_ccache_pmu_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct sifive_ccache_pmu *ccache_pmu;
> +	u32 n_counters;
> +	int ret;
> +
> +	/* Instances without a sifive,perfmon-counters property do not contain a PMU */
> +	ret = device_property_read_u32(dev, "sifive,perfmon-counters", &n_counters);
> +	if (ret || !n_counters)
> +		return -ENODEV;
if (ret)
	return ret;

	if (!n_counters)
		return -ENODEV;

In general don't eat potentially useful return codes.

> +
> +	ccache_pmu = devm_kzalloc(dev, struct_size(ccache_pmu, events, n_counters), GFP_KERNEL);
> +	if (!ccache_pmu)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, ccache_pmu);
> +
> +	ccache_pmu->pmu = (struct pmu) {
> +		.parent		= dev,
> +		.attr_groups	= sifive_ccache_pmu_attr_grps,
> +		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
> +		.task_ctx_nr	= perf_invalid_context,
> +		.event_init	= sifive_ccache_pmu_event_init,
> +		.add		= sifive_ccache_pmu_add,
> +		.del		= sifive_ccache_pmu_del,
> +		.start		= sifive_ccache_pmu_start,
> +		.stop		= sifive_ccache_pmu_stop,
> +		.read		= sifive_ccache_pmu_read,
> +	};
> +	ccache_pmu->cpu = nr_cpu_ids;
> +	ccache_pmu->n_counters = n_counters;
> +
> +	ccache_pmu->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(ccache_pmu->base))
> +		return PTR_ERR(ccache_pmu->base);
> +
> +	sifive_ccache_pmu_hw_init(ccache_pmu);
> +
> +	ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE, &ccache_pmu->node);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to add CPU hotplug instance\n");

you could use devm_add_action_or_reset() and trivial callback to unwind this in remove + error
paths automatically.  Slight simplification of code, though may end up a line or two longer.

Do the same for perf_pmu_unregister() and you can get rid of remove entirely.

> +
> +	ret = perf_pmu_register(&ccache_pmu->pmu, "sifive_ccache_pmu", -1);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "Failed to register PMU\n");
> +		goto err_remove_instance;
> +	}
> +
> +	return 0;
> +
> +err_remove_instance:
> +	cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE, &ccache_pmu->node);
> +
> +	return ret;
> +}
> +
> +static void sifive_ccache_pmu_remove(struct platform_device *pdev)
> +{
> +	struct sifive_ccache_pmu *ccache_pmu = platform_get_drvdata(pdev);
> +
> +	perf_pmu_unregister(&ccache_pmu->pmu);
> +	cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE, &ccache_pmu->node);
> +}
> +
> +static const struct of_device_id sifive_ccache_pmu_of_match[] = {
> +	{ .compatible = "sifive,ccache0" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, sifive_ccache_pmu_of_match);
> +
> +static struct platform_driver sifive_ccache_pmu_driver = {
> +	.probe	= sifive_ccache_pmu_probe,
> +	.remove_new	= sifive_ccache_pmu_remove,

Is this actually aligning anything in a useful fashion?
I'd just use a single space instead and not bother. The alignment tends to
just end up broken and provides little readability advantage.


> +	.driver	= {
> +		.name		= "sifive_ccache_pmu",
> +		.of_match_table	= sifive_ccache_pmu_of_match,
> +	},
> +};

> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> index 172d0a743e5d..be6361fdc8ba 100644
> --- a/include/linux/cpuhotplug.h
> +++ b/include/linux/cpuhotplug.h
> @@ -230,6 +230,7 @@ enum cpuhp_state {
>  	CPUHP_AP_PERF_POWERPC_TRACE_IMC_ONLINE,
>  	CPUHP_AP_PERF_POWERPC_HV_24x7_ONLINE,
>  	CPUHP_AP_PERF_POWERPC_HV_GPCI_ONLINE,
> +	CPUHP_AP_PERF_RISCV_SIFIVE_CCACHE_ONLINE,

Not sure, but can you get away with CPUHP_AP_ONLINE_DYN ?
Nicer to avoid adding more entries to this list if that is suitable here.

>  	CPUHP_AP_PERF_CSKY_ONLINE,
>  	CPUHP_AP_WATCHDOG_ONLINE,
>  	CPUHP_AP_WORKQUEUE_ONLINE,



From joychakr at google.com  Mon Feb 19 03:31:48 2024
From: joychakr at google.com (Joy Chakraborty)
Date: Mon, 19 Feb 2024 11:31:48 +0000
Subject: [PATCH v1 0/1] nvmem: Handle actual amount of data read/written by suppliers
Message-ID: <20240219113149.2437990-1-joychakr@google.com>

This Patch series stems from discussions in patchset,
"[PATCH v2] nvmem: rmem: Fix return value of rmem_read()"
(https://lore.kernel.org/all/20240206042408.224138-1-joychakr at google.com/).
Where we come across the fact that currently the nvmem suppliers do not
actually let the core know how much data has been actually read or written.
Instead they are expected to return 0 for success and the core assumes that
the amount of data written is equal to what the core has requested.

On addition this patchset will also add some guards and checks based on the
count of data returned by the nvmem supplier.
---
V1 Changes : Change read/write callback prototype to ssize_t and
supplier changes to accomodate the same with core checks and bounds.
---

Joy Chakraborty (1):
  nvmem: Change return type of reg read/write to ssize_t

 drivers/nvmem/apple-efuses.c        |  5 +-
 drivers/nvmem/bcm-ocotp.c           |  8 ++--
 drivers/nvmem/brcm_nvram.c          |  8 +++-
 drivers/nvmem/core.c                | 73 +++++++++++++----------------
 drivers/nvmem/imx-iim.c             |  4 +-
 drivers/nvmem/imx-ocotp-ele.c       |  4 +-
 drivers/nvmem/imx-ocotp-scu.c       |  8 ++--
 drivers/nvmem/imx-ocotp.c           |  6 +--
 drivers/nvmem/jz4780-efuse.c        |  5 +-
 drivers/nvmem/lan9662-otpc.c        |  8 ++--
 drivers/nvmem/layerscape-sfp.c      |  7 ++-
 drivers/nvmem/lpc18xx_eeprom.c      | 10 ++--
 drivers/nvmem/lpc18xx_otp.c         |  4 +-
 drivers/nvmem/meson-efuse.c         | 10 +++-
 drivers/nvmem/meson-mx-efuse.c      |  4 +-
 drivers/nvmem/microchip-otpc.c      |  4 +-
 drivers/nvmem/mtk-efuse.c           |  4 +-
 drivers/nvmem/mxs-ocotp.c           |  5 +-
 drivers/nvmem/nintendo-otp.c        |  4 +-
 drivers/nvmem/qcom-spmi-sdam.c      |  8 ++--
 drivers/nvmem/qfprom.c              | 10 ++--
 drivers/nvmem/qoriq-efuse.c         |  4 +-
 drivers/nvmem/rave-sp-eeprom.c      | 12 ++---
 drivers/nvmem/rmem.c                |  2 +-
 drivers/nvmem/rockchip-efuse.c      | 11 +++--
 drivers/nvmem/rockchip-otp.c        | 13 ++---
 drivers/nvmem/sc27xx-efuse.c        |  3 +-
 drivers/nvmem/sec-qfprom.c          |  4 +-
 drivers/nvmem/snvs_lpgpr.c          | 13 +++--
 drivers/nvmem/sprd-efuse.c          |  8 ++--
 drivers/nvmem/stm32-bsec-optee-ta.c |  8 ++--
 drivers/nvmem/stm32-bsec-optee-ta.h | 12 ++---
 drivers/nvmem/stm32-romem.c         | 16 +++----
 drivers/nvmem/sunplus-ocotp.c       |  4 +-
 drivers/nvmem/sunxi_sid.c           | 11 +++--
 drivers/nvmem/u-boot-env.c          |  4 +-
 drivers/nvmem/uniphier-efuse.c      |  4 +-
 drivers/nvmem/vf610-ocotp.c         |  5 +-
 drivers/nvmem/zynqmp_nvmem.c        |  2 +-
 include/linux/nvmem-provider.h      |  4 +-
 40 files changed, 180 insertions(+), 159 deletions(-)

-- 
2.44.0.rc0.258.g7320e95886-goog



From joychakr at google.com  Mon Feb 19 03:31:49 2024
From: joychakr at google.com (Joy Chakraborty)
Date: Mon, 19 Feb 2024 11:31:49 +0000
Subject: [PATCH v1 1/1] nvmem: Change return type of reg read/write to ssize_t
In-Reply-To: <20240219113149.2437990-1-joychakr@google.com>
References: <20240219113149.2437990-1-joychakr@google.com>
Message-ID: <20240219113149.2437990-2-joychakr@google.com>

Change return type of reg_read() and reg_write() callback to ssize_t for
nvmem suppliers to return number of bytes read/written to the nvmem core.

Currently nvmem core assumes the amount of data read/written is equal
to what it has requested from the supplier, this return code facilitates
better error handling in the nvmem core.

Signed-off-by: Joy Chakraborty <joychakr at google.com>
---
 drivers/nvmem/apple-efuses.c        |  5 +-
 drivers/nvmem/bcm-ocotp.c           |  8 ++--
 drivers/nvmem/brcm_nvram.c          |  8 +++-
 drivers/nvmem/core.c                | 73 +++++++++++++----------------
 drivers/nvmem/imx-iim.c             |  4 +-
 drivers/nvmem/imx-ocotp-ele.c       |  4 +-
 drivers/nvmem/imx-ocotp-scu.c       |  8 ++--
 drivers/nvmem/imx-ocotp.c           |  6 +--
 drivers/nvmem/jz4780-efuse.c        |  5 +-
 drivers/nvmem/lan9662-otpc.c        |  8 ++--
 drivers/nvmem/layerscape-sfp.c      |  7 ++-
 drivers/nvmem/lpc18xx_eeprom.c      | 10 ++--
 drivers/nvmem/lpc18xx_otp.c         |  4 +-
 drivers/nvmem/meson-efuse.c         | 10 +++-
 drivers/nvmem/meson-mx-efuse.c      |  4 +-
 drivers/nvmem/microchip-otpc.c      |  4 +-
 drivers/nvmem/mtk-efuse.c           |  4 +-
 drivers/nvmem/mxs-ocotp.c           |  5 +-
 drivers/nvmem/nintendo-otp.c        |  4 +-
 drivers/nvmem/qcom-spmi-sdam.c      |  8 ++--
 drivers/nvmem/qfprom.c              | 10 ++--
 drivers/nvmem/qoriq-efuse.c         |  4 +-
 drivers/nvmem/rave-sp-eeprom.c      | 12 ++---
 drivers/nvmem/rmem.c                |  2 +-
 drivers/nvmem/rockchip-efuse.c      | 11 +++--
 drivers/nvmem/rockchip-otp.c        | 13 ++---
 drivers/nvmem/sc27xx-efuse.c        |  3 +-
 drivers/nvmem/sec-qfprom.c          |  4 +-
 drivers/nvmem/snvs_lpgpr.c          | 13 +++--
 drivers/nvmem/sprd-efuse.c          |  8 ++--
 drivers/nvmem/stm32-bsec-optee-ta.c |  8 ++--
 drivers/nvmem/stm32-bsec-optee-ta.h | 12 ++---
 drivers/nvmem/stm32-romem.c         | 16 +++----
 drivers/nvmem/sunplus-ocotp.c       |  4 +-
 drivers/nvmem/sunxi_sid.c           | 11 +++--
 drivers/nvmem/u-boot-env.c          |  4 +-
 drivers/nvmem/uniphier-efuse.c      |  4 +-
 drivers/nvmem/vf610-ocotp.c         |  5 +-
 drivers/nvmem/zynqmp_nvmem.c        |  2 +-
 include/linux/nvmem-provider.h      |  4 +-
 40 files changed, 180 insertions(+), 159 deletions(-)

diff --git a/drivers/nvmem/apple-efuses.c b/drivers/nvmem/apple-efuses.c
index d3d49d22338b..9a564cb0f26d 100644
--- a/drivers/nvmem/apple-efuses.c
+++ b/drivers/nvmem/apple-efuses.c
@@ -15,10 +15,11 @@ struct apple_efuses_priv {
 	void __iomem *fuses;
 };
 
-static int apple_efuses_read(void *context, unsigned int offset, void *val,
+static ssize_t apple_efuses_read(void *context, unsigned int offset, void *val,
 			     size_t bytes)
 {
 	struct apple_efuses_priv *priv = context;
+	size_t bytes_read = bytes;
 	u32 *dst = val;
 
 	while (bytes >= sizeof(u32)) {
@@ -27,7 +28,7 @@ static int apple_efuses_read(void *context, unsigned int offset, void *val,
 		offset += sizeof(u32);
 	}
 
-	return 0;
+	return bytes_read;
 }
 
 static int apple_efuses_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/bcm-ocotp.c b/drivers/nvmem/bcm-ocotp.c
index 2490f44caa40..803354574fe0 100644
--- a/drivers/nvmem/bcm-ocotp.c
+++ b/drivers/nvmem/bcm-ocotp.c
@@ -148,7 +148,7 @@ static int disable_ocotp_program(void __iomem *base)
 	return ret;
 }
 
-static int bcm_otpc_read(void *context, unsigned int offset, void *val,
+static ssize_t bcm_otpc_read(void *context, unsigned int offset, void *val,
 	size_t bytes)
 {
 	struct otpc_priv *priv = context;
@@ -176,10 +176,10 @@ static int bcm_otpc_read(void *context, unsigned int offset, void *val,
 		reset_start_bit(priv->base);
 	}
 
-	return 0;
+	return bytes_read;
 }
 
-static int bcm_otpc_write(void *context, unsigned int offset, void *val,
+static ssize_t bcm_otpc_write(void *context, unsigned int offset, void *val,
 	size_t bytes)
 {
 	struct otpc_priv *priv = context;
@@ -214,7 +214,7 @@ static int bcm_otpc_write(void *context, unsigned int offset, void *val,
 
 	disable_ocotp_program(priv->base);
 
-	return 0;
+	return bytes_written;
 }
 
 static struct nvmem_config bcm_otpc_nvmem_config = {
diff --git a/drivers/nvmem/brcm_nvram.c b/drivers/nvmem/brcm_nvram.c
index 5cdf339cfbec..d8700b7e2642 100644
--- a/drivers/nvmem/brcm_nvram.c
+++ b/drivers/nvmem/brcm_nvram.c
@@ -46,7 +46,7 @@ struct brcm_nvram_header {
 	__le32 config_ncdl;	/* ncdl values for memc */
 };
 
-static int brcm_nvram_read(void *context, unsigned int offset, void *val,
+static ssize_t brcm_nvram_read(void *context, unsigned int offset, void *val,
 			   size_t bytes)
 {
 	struct brcm_nvram *priv = context;
@@ -61,7 +61,11 @@ static int brcm_nvram_read(void *context, unsigned int offset, void *val,
 
 	memset((uint8_t *)val + to_copy, priv->padding_byte, bytes - to_copy);
 
-	return 0;
+	/*
+	 * Returning bytes requested as the whole buffer is padded even if the
+	 * requested bytes to be read is out of bounds of resource size.
+	 */
+	return bytes;
 }
 
 static int brcm_nvram_copy_data(struct brcm_nvram *priv, struct platform_device *pdev)
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index eb357ac2e54a..c3ee526d9396 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -55,7 +55,7 @@ static LIST_HEAD(nvmem_lookup_list);
 
 static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
 
-static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
+static ssize_t __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
 			    void *val, size_t bytes)
 {
 	if (nvmem->reg_read)
@@ -64,10 +64,10 @@ static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
 	return -EINVAL;
 }
 
-static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
+static ssize_t __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
 			     void *val, size_t bytes)
 {
-	int ret;
+	ssize_t ret;
 
 	if (nvmem->reg_write) {
 		gpiod_set_value_cansleep(nvmem->wp_gpio, 0);
@@ -79,7 +79,7 @@ static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
 	return -EINVAL;
 }
 
-static int nvmem_access_with_keepouts(struct nvmem_device *nvmem,
+static ssize_t nvmem_access_with_keepouts(struct nvmem_device *nvmem,
 				      unsigned int offset, void *val,
 				      size_t bytes, int write)
 {
@@ -88,7 +88,7 @@ static int nvmem_access_with_keepouts(struct nvmem_device *nvmem,
 	unsigned int kend, ksize;
 	const struct nvmem_keepout *keepout = nvmem->keepout;
 	const struct nvmem_keepout *keepoutend = keepout + nvmem->nkeepout;
-	int rc;
+	ssize_t rc, count = 0;
 
 	/*
 	 * Skip all keepouts before the range being accessed.
@@ -107,11 +107,12 @@ static int nvmem_access_with_keepouts(struct nvmem_device *nvmem,
 			else
 				rc = __nvmem_reg_read(nvmem, offset, val, ksize);
 
-			if (rc)
+			if (rc < 0)
 				return rc;
 
 			offset += ksize;
 			val += ksize;
+			count += rc;
 		}
 
 		/*
@@ -135,15 +136,20 @@ static int nvmem_access_with_keepouts(struct nvmem_device *nvmem,
 	if (offset < end) {
 		ksize = end - offset;
 		if (write)
-			return __nvmem_reg_write(nvmem, offset, val, ksize);
+			rc = __nvmem_reg_write(nvmem, offset, val, ksize);
 		else
-			return __nvmem_reg_read(nvmem, offset, val, ksize);
+			rc = __nvmem_reg_read(nvmem, offset, val, ksize);
+
+		if (rc < 0)
+			return rc;
+
+		count += rc;
 	}
 
-	return 0;
+	return count;
 }
 
-static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
+static ssize_t nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
 			  void *val, size_t bytes)
 {
 	if (!nvmem->nkeepout)
@@ -152,7 +158,7 @@ static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
 	return nvmem_access_with_keepouts(nvmem, offset, val, bytes, false);
 }
 
-static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
+static ssize_t nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
 			   void *val, size_t bytes)
 {
 	if (!nvmem->nkeepout)
@@ -195,7 +201,6 @@ static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
 {
 	struct device *dev;
 	struct nvmem_device *nvmem;
-	int rc;
 
 	if (attr->private)
 		dev = attr->private;
@@ -221,12 +226,7 @@ static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
 	if (!nvmem->reg_read)
 		return -EPERM;
 
-	rc = nvmem_reg_read(nvmem, pos, buf, count);
-
-	if (rc)
-		return rc;
-
-	return count;
+	return nvmem_reg_read(nvmem, pos, buf, count);
 }
 
 static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
@@ -235,7 +235,6 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
 {
 	struct device *dev;
 	struct nvmem_device *nvmem;
-	int rc;
 
 	if (attr->private)
 		dev = attr->private;
@@ -261,12 +260,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
 	if (!nvmem->reg_write)
 		return -EPERM;
 
-	rc = nvmem_reg_write(nvmem, pos, buf, count);
-
-	if (rc)
-		return rc;
-
-	return count;
+	return nvmem_reg_write(nvmem, pos, buf, count);
 }
 
 static umode_t nvmem_bin_attr_get_umode(struct nvmem_device *nvmem)
@@ -1633,9 +1627,12 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem,
 
 	rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->raw_len);
 
-	if (rc)
+	if (rc < 0)
 		return rc;
 
+	if (rc != cell->raw_len)
+		return -EIO;
+
 	/* shift bits in-place */
 	if (cell->bit_offset || cell->nbits)
 		nvmem_shift_read_buffer_in_place(cell, buf);
@@ -1708,8 +1705,11 @@ static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell_entry *cell,
 
 		/* setup the first byte with lsb bits from nvmem */
 		rc = nvmem_reg_read(nvmem, cell->offset, &v, 1);
-		if (rc)
+		if (rc < 1) {
+			if (rc == 0)
+				rc = -EIO;
 			goto err;
+		}
 		*b++ |= GENMASK(bit_offset - 1, 0) & v;
 
 		/* setup rest of the byte if any */
@@ -1728,8 +1728,11 @@ static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell_entry *cell,
 		/* setup the last byte with msb bits from nvmem */
 		rc = nvmem_reg_read(nvmem,
 				    cell->offset + cell->bytes - 1, &v, 1);
-		if (rc)
+		if (rc < 1) {
+			if (rc == 0)
+				rc = -EIO;
 			goto err;
+		}
 		*p |= GENMASK(7, (nbits + bit_offset) % BITS_PER_BYTE) & v;
 
 	}
@@ -1769,10 +1772,7 @@ static int __nvmem_cell_entry_write(struct nvmem_cell_entry *cell, void *buf, si
 	if (cell->bit_offset || cell->nbits)
 		kfree(buf);
 
-	if (rc)
-		return rc;
-
-	return len;
+	return rc;
 }
 
 /**
@@ -2047,17 +2047,10 @@ int nvmem_device_read(struct nvmem_device *nvmem,
 		      unsigned int offset,
 		      size_t bytes, void *buf)
 {
-	int rc;
-
 	if (!nvmem)
 		return -EINVAL;
 
-	rc = nvmem_reg_read(nvmem, offset, buf, bytes);
-
-	if (rc)
-		return rc;
-
-	return bytes;
+	return nvmem_reg_read(nvmem, offset, buf, bytes);
 }
 EXPORT_SYMBOL_GPL(nvmem_device_read);
 
diff --git a/drivers/nvmem/imx-iim.c b/drivers/nvmem/imx-iim.c
index f13bbd164086..af46c5490416 100644
--- a/drivers/nvmem/imx-iim.c
+++ b/drivers/nvmem/imx-iim.c
@@ -29,7 +29,7 @@ struct iim_priv {
 	struct clk *clk;
 };
 
-static int imx_iim_read(void *context, unsigned int offset,
+static ssize_t imx_iim_read(void *context, unsigned int offset,
 			  void *buf, size_t bytes)
 {
 	struct iim_priv *iim = context;
@@ -49,7 +49,7 @@ static int imx_iim_read(void *context, unsigned int offset,
 
 	clk_disable_unprepare(iim->clk);
 
-	return 0;
+	return bytes;
 }
 
 static struct imx_iim_drvdata imx27_drvdata = {
diff --git a/drivers/nvmem/imx-ocotp-ele.c b/drivers/nvmem/imx-ocotp-ele.c
index cf920542f939..3025fe8aa991 100644
--- a/drivers/nvmem/imx-ocotp-ele.c
+++ b/drivers/nvmem/imx-ocotp-ele.c
@@ -61,7 +61,7 @@ static enum fuse_type imx_ocotp_fuse_type(void *context, u32 index)
 	return FUSE_INVALID;
 }
 
-static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, size_t bytes)
+static ssize_t imx_ocotp_reg_read(void *context, unsigned int offset, void *val, size_t bytes)
 {
 	struct imx_ocotp_priv *priv = context;
 	void __iomem *reg = priv->base + priv->data->reg_off;
@@ -102,7 +102,7 @@ static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, siz
 
 	kfree(p);
 
-	return 0;
+	return bytes;
 };
 
 static int imx_ele_ocotp_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/imx-ocotp-scu.c b/drivers/nvmem/imx-ocotp-scu.c
index 517d83e11af2..2f9b9f035c49 100644
--- a/drivers/nvmem/imx-ocotp-scu.c
+++ b/drivers/nvmem/imx-ocotp-scu.c
@@ -129,7 +129,7 @@ static int imx_sc_misc_otp_fuse_read(struct imx_sc_ipc *ipc, u32 word,
 	return 0;
 }
 
-static int imx_scu_ocotp_read(void *context, unsigned int offset,
+static ssize_t imx_scu_ocotp_read(void *context, unsigned int offset,
 			      void *val, size_t bytes)
 {
 	struct ocotp_priv *priv = context;
@@ -174,10 +174,10 @@ static int imx_scu_ocotp_read(void *context, unsigned int offset,
 
 	kfree(p);
 
-	return 0;
+	return bytes;
 }
 
-static int imx_scu_ocotp_write(void *context, unsigned int offset,
+static ssize_t imx_scu_ocotp_write(void *context, unsigned int offset,
 			       void *val, size_t bytes)
 {
 	struct ocotp_priv *priv = context;
@@ -215,7 +215,7 @@ static int imx_scu_ocotp_write(void *context, unsigned int offset,
 
 	mutex_unlock(&scu_ocotp_mutex);
 
-	return res.a0;
+	return res.a0 < 0 ? res.a0 : bytes;
 }
 
 static struct nvmem_config imx_scu_ocotp_nvmem_config = {
diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
index 79dd4fda0329..2b04d49c7bf0 100644
--- a/drivers/nvmem/imx-ocotp.c
+++ b/drivers/nvmem/imx-ocotp.c
@@ -154,7 +154,7 @@ static void imx_ocotp_clr_err_if_set(struct ocotp_priv *priv)
 	writel(bm_ctrl_error, base + IMX_OCOTP_ADDR_CTRL_CLR);
 }
 
-static int imx_ocotp_read(void *context, unsigned int offset,
+static ssize_t imx_ocotp_read(void *context, unsigned int offset,
 			  void *val, size_t bytes)
 {
 	struct ocotp_priv *priv = context;
@@ -217,7 +217,7 @@ static int imx_ocotp_read(void *context, unsigned int offset,
 
 	kfree(p);
 
-	return ret;
+	return ret < 0 ? ret : bytes;
 }
 
 static int imx_ocotp_cell_pp(void *context, const char *id, int index,
@@ -307,7 +307,7 @@ static void imx_ocotp_set_imx7_timing(struct ocotp_priv *priv)
 	writel(timing, priv->base + IMX_OCOTP_ADDR_TIMING);
 }
 
-static int imx_ocotp_write(void *context, unsigned int offset, void *val,
+static ssize_t imx_ocotp_write(void *context, unsigned int offset, void *val,
 			   size_t bytes)
 {
 	struct ocotp_priv *priv = context;
diff --git a/drivers/nvmem/jz4780-efuse.c b/drivers/nvmem/jz4780-efuse.c
index 0b01b840edd9..3c3f57dd1ffc 100644
--- a/drivers/nvmem/jz4780-efuse.c
+++ b/drivers/nvmem/jz4780-efuse.c
@@ -66,10 +66,11 @@ struct jz4780_efuse {
 };
 
 /* main entry point */
-static int jz4780_efuse_read(void *context, unsigned int offset,
+static ssize_t jz4780_efuse_read(void *context, unsigned int offset,
 			     void *val, size_t bytes)
 {
 	struct jz4780_efuse *efuse = context;
+	size_t bytes_read = bytes;
 
 	while (bytes > 0) {
 		size_t start = offset & ~(JZ_EFU_READ_SIZE - 1);
@@ -112,7 +113,7 @@ static int jz4780_efuse_read(void *context, unsigned int offset,
 		bytes -= chunk;
 	}
 
-	return 0;
+	return bytes_read;
 }
 
 static struct nvmem_config jz4780_efuse_nvmem_config = {
diff --git a/drivers/nvmem/lan9662-otpc.c b/drivers/nvmem/lan9662-otpc.c
index 56fc19f092a7..a6bdc79867c7 100644
--- a/drivers/nvmem/lan9662-otpc.c
+++ b/drivers/nvmem/lan9662-otpc.c
@@ -119,7 +119,7 @@ static int lan9662_otp_write_byte(struct lan9662_otp *otp, u32 offset, u8 data)
 	return rc;
 }
 
-static int lan9662_otp_read(void *context, unsigned int offset,
+static ssize_t lan9662_otp_read(void *context, unsigned int offset,
 			    void *_val, size_t bytes)
 {
 	struct lan9662_otp *otp = context;
@@ -136,10 +136,10 @@ static int lan9662_otp_read(void *context, unsigned int offset,
 	}
 	lan9662_otp_power(otp, false);
 
-	return rc;
+	return rc < 0 ? rc : bytes;
 }
 
-static int lan9662_otp_write(void *context, unsigned int offset,
+static ssize_t lan9662_otp_write(void *context, unsigned int offset,
 			     void *_val, size_t bytes)
 {
 	struct lan9662_otp *otp = context;
@@ -167,7 +167,7 @@ static int lan9662_otp_write(void *context, unsigned int offset,
 	}
 	lan9662_otp_power(otp, false);
 
-	return rc;
+	return rc < 0 ? rc : bytes;
 }
 
 static struct nvmem_config otp_config = {
diff --git a/drivers/nvmem/layerscape-sfp.c b/drivers/nvmem/layerscape-sfp.c
index e2b424561949..0aab245abd6e 100644
--- a/drivers/nvmem/layerscape-sfp.c
+++ b/drivers/nvmem/layerscape-sfp.c
@@ -26,14 +26,17 @@ struct layerscape_sfp_data {
 	enum regmap_endian endian;
 };
 
-static int layerscape_sfp_read(void *context, unsigned int offset, void *val,
+static ssize_t layerscape_sfp_read(void *context, unsigned int offset, void *val,
 			       size_t bytes)
 {
 	struct layerscape_sfp_priv *priv = context;
+	int ret;
 
-	return regmap_bulk_read(priv->regmap,
+	ret = regmap_bulk_read(priv->regmap,
 				LAYERSCAPE_SFP_OTP_OFFSET + offset, val,
 				bytes / 4);
+
+	return ret < 0 ? ret : bytes;
 }
 
 static struct nvmem_config layerscape_sfp_nvmem_config = {
diff --git a/drivers/nvmem/lpc18xx_eeprom.c b/drivers/nvmem/lpc18xx_eeprom.c
index a0275b29afd5..cc8f59c2cd63 100644
--- a/drivers/nvmem/lpc18xx_eeprom.c
+++ b/drivers/nvmem/lpc18xx_eeprom.c
@@ -87,10 +87,11 @@ static int lpc18xx_eeprom_busywait_until_prog(struct lpc18xx_eeprom_dev *eeprom)
 	return -ETIMEDOUT;
 }
 
-static int lpc18xx_eeprom_gather_write(void *context, unsigned int reg,
+static ssize_t lpc18xx_eeprom_gather_write(void *context, unsigned int reg,
 				       void *val, size_t bytes)
 {
 	struct lpc18xx_eeprom_dev *eeprom = context;
+	size_t bytes_written = bytes;
 	unsigned int offset = reg;
 	int ret;
 
@@ -123,13 +124,14 @@ static int lpc18xx_eeprom_gather_write(void *context, unsigned int reg,
 	lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_PWRDWN,
 			      LPC18XX_EEPROM_PWRDWN_YES);
 
-	return 0;
+	return bytes_written;
 }
 
-static int lpc18xx_eeprom_read(void *context, unsigned int offset,
+static ssize_t lpc18xx_eeprom_read(void *context, unsigned int offset,
 			       void *val, size_t bytes)
 {
 	struct lpc18xx_eeprom_dev *eeprom = context;
+	size_t bytes_read = bytes;
 
 	lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_PWRDWN,
 			      LPC18XX_EEPROM_PWRDWN_NO);
@@ -147,7 +149,7 @@ static int lpc18xx_eeprom_read(void *context, unsigned int offset,
 	lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_PWRDWN,
 			      LPC18XX_EEPROM_PWRDWN_YES);
 
-	return 0;
+	return bytes_read;
 }
 
 
diff --git a/drivers/nvmem/lpc18xx_otp.c b/drivers/nvmem/lpc18xx_otp.c
index adc9948e7b2e..da7d7667e10c 100644
--- a/drivers/nvmem/lpc18xx_otp.c
+++ b/drivers/nvmem/lpc18xx_otp.c
@@ -37,7 +37,7 @@ struct lpc18xx_otp {
 	void __iomem *base;
 };
 
-static int lpc18xx_otp_read(void *context, unsigned int offset,
+static ssize_t lpc18xx_otp_read(void *context, unsigned int offset,
 			    void *val, size_t bytes)
 {
 	struct lpc18xx_otp *otp = context;
@@ -52,7 +52,7 @@ static int lpc18xx_otp_read(void *context, unsigned int offset,
 	for (i = index; i < (index + count); i++)
 		*buf++ = readl(otp->base + i * LPC18XX_OTP_WORD_SIZE);
 
-	return 0;
+	return bytes;
 }
 
 static struct nvmem_config lpc18xx_otp_nvmem_config = {
diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
index b922df99f9bc..da2e856b16a1 100644
--- a/drivers/nvmem/meson-efuse.c
+++ b/drivers/nvmem/meson-efuse.c
@@ -18,18 +18,24 @@ static int meson_efuse_read(void *context, unsigned int offset,
 			    void *val, size_t bytes)
 {
 	struct meson_sm_firmware *fw = context;
+	int ret;
 
-	return meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
+	ret = meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
 				  bytes, 0, 0, 0);
+
+	return ret < 0 ? ret : bytes;
 }
 
 static int meson_efuse_write(void *context, unsigned int offset,
 			     void *val, size_t bytes)
 {
 	struct meson_sm_firmware *fw = context;
+	int ret;
 
-	return meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
+	ret = meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
 				   bytes, 0, 0, 0);
+
+	return ret < 0 ? ret : bytes;
 }
 
 static const struct of_device_id meson_efuse_match[] = {
diff --git a/drivers/nvmem/meson-mx-efuse.c b/drivers/nvmem/meson-mx-efuse.c
index 3ff04d5ca8f8..fdc598adfe9e 100644
--- a/drivers/nvmem/meson-mx-efuse.c
+++ b/drivers/nvmem/meson-mx-efuse.c
@@ -132,7 +132,7 @@ static int meson_mx_efuse_read_addr(struct meson_mx_efuse *efuse,
 	return 0;
 }
 
-static int meson_mx_efuse_read(void *context, unsigned int offset,
+static ssize_t meson_mx_efuse_read(void *context, unsigned int offset,
 			       void *buf, size_t bytes)
 {
 	struct meson_mx_efuse *efuse = context;
@@ -163,7 +163,7 @@ static int meson_mx_efuse_read(void *context, unsigned int offset,
 
 	meson_mx_efuse_hw_disable(efuse);
 
-	return err;
+	return err < 0 ? err : bytes;
 }
 
 static const struct meson_mx_efuse_platform_data meson6_efuse_data = {
diff --git a/drivers/nvmem/microchip-otpc.c b/drivers/nvmem/microchip-otpc.c
index 7cf81738a3e0..9b53fcb75e98 100644
--- a/drivers/nvmem/microchip-otpc.c
+++ b/drivers/nvmem/microchip-otpc.c
@@ -143,7 +143,7 @@ static int mchp_otpc_prepare_read(struct mchp_otpc *otpc,
  * packet. The user will have to be aware of the memory footprint before doing
  * the read request.
  */
-static int mchp_otpc_read(void *priv, unsigned int off, void *val,
+static ssize_t mchp_otpc_read(void *priv, unsigned int off, void *val,
 			  size_t bytes)
 {
 	struct mchp_otpc *otpc = priv;
@@ -187,7 +187,7 @@ static int mchp_otpc_read(void *priv, unsigned int off, void *val,
 		} while (payload_size >= 0 && len < bytes);
 	}
 
-	return 0;
+	return len;
 }
 
 static int mchp_otpc_init_packets_list(struct mchp_otpc *otpc, u32 *size)
diff --git a/drivers/nvmem/mtk-efuse.c b/drivers/nvmem/mtk-efuse.c
index 84f05b40a411..3819d416b505 100644
--- a/drivers/nvmem/mtk-efuse.c
+++ b/drivers/nvmem/mtk-efuse.c
@@ -20,7 +20,7 @@ struct mtk_efuse_priv {
 	void __iomem *base;
 };
 
-static int mtk_reg_read(void *context,
+static ssize_t mtk_reg_read(void *context,
 			unsigned int reg, void *_val, size_t bytes)
 {
 	struct mtk_efuse_priv *priv = context;
@@ -31,7 +31,7 @@ static int mtk_reg_read(void *context,
 	for (i = 0; i < bytes; i++, val++)
 		*val = readb(addr + i);
 
-	return 0;
+	return bytes;
 }
 
 static int mtk_efuse_gpu_speedbin_pp(void *context, const char *id, int index,
diff --git a/drivers/nvmem/mxs-ocotp.c b/drivers/nvmem/mxs-ocotp.c
index 7b78f18f9545..ddf7394de71b 100644
--- a/drivers/nvmem/mxs-ocotp.c
+++ b/drivers/nvmem/mxs-ocotp.c
@@ -56,10 +56,11 @@ static int mxs_ocotp_wait(struct mxs_ocotp *otp)
 	return 0;
 }
 
-static int mxs_ocotp_read(void *context, unsigned int offset,
+static ssize_t mxs_ocotp_read(void *context, unsigned int offset,
 			  void *val, size_t bytes)
 {
 	struct mxs_ocotp *otp = context;
+	size_t bytes_read = bytes;
 	u32 *buf = val;
 	int ret;
 
@@ -102,7 +103,7 @@ static int mxs_ocotp_read(void *context, unsigned int offset,
 disable_clk:
 	clk_disable(otp->clk);
 
-	return ret;
+	return ret < 0 ? ret : bytes_read;
 }
 
 static struct nvmem_config ocotp_config = {
diff --git a/drivers/nvmem/nintendo-otp.c b/drivers/nvmem/nintendo-otp.c
index 355e7f1fc6d5..880f2915c030 100644
--- a/drivers/nvmem/nintendo-otp.c
+++ b/drivers/nvmem/nintendo-otp.c
@@ -45,7 +45,7 @@ static const struct nintendo_otp_devtype_data latte_otp_data = {
 	.num_banks = 8,
 };
 
-static int nintendo_otp_reg_read(void *context,
+static ssize_t nintendo_otp_reg_read(void *context,
 				 unsigned int reg, void *_val, size_t bytes)
 {
 	struct nintendo_otp_priv *priv = context;
@@ -61,7 +61,7 @@ static int nintendo_otp_reg_read(void *context,
 		reg += WORD_SIZE;
 	}
 
-	return 0;
+	return bytes;
 }
 
 static const struct of_device_id nintendo_otp_of_table[] = {
diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c
index 9aa8f42faa4c..c4dfde372794 100644
--- a/drivers/nvmem/qcom-spmi-sdam.c
+++ b/drivers/nvmem/qcom-spmi-sdam.c
@@ -60,7 +60,7 @@ static bool sdam_is_ro(unsigned int offset, size_t len)
 	return false;
 }
 
-static int sdam_read(void *priv, unsigned int offset, void *val,
+static ssize_t sdam_read(void *priv, unsigned int offset, void *val,
 				size_t bytes)
 {
 	struct sdam_chip *sdam = priv;
@@ -78,10 +78,10 @@ static int sdam_read(void *priv, unsigned int offset, void *val,
 		dev_err(dev, "Failed to read SDAM offset %#x len=%zd, rc=%d\n",
 						offset, bytes, rc);
 
-	return rc;
+	return rc < 0 ? rc : bytes;
 }
 
-static int sdam_write(void *priv, unsigned int offset, void *val,
+static ssize_t sdam_write(void *priv, unsigned int offset, void *val,
 				size_t bytes)
 {
 	struct sdam_chip *sdam = priv;
@@ -105,7 +105,7 @@ static int sdam_write(void *priv, unsigned int offset, void *val,
 		dev_err(dev, "Failed to write SDAM offset %#x len=%zd, rc=%d\n",
 						offset, bytes, rc);
 
-	return rc;
+	return rc < 0 ? rc : bytes;
 }
 
 static int sdam_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
index 116a39e804c7..4d571ae6ba3e 100644
--- a/drivers/nvmem/qfprom.c
+++ b/drivers/nvmem/qfprom.c
@@ -251,9 +251,9 @@ static int qfprom_enable_fuse_blowing(const struct qfprom_priv *priv,
  *
  * Writes to fuses.  WARNING: THIS IS PERMANENT.
  *
- * Return: 0 or -err.
+ * Return: bytes written or -err.
  */
-static int qfprom_reg_write(void *context, unsigned int reg, void *_val,
+static ssize_t qfprom_reg_write(void *context, unsigned int reg, void *_val,
 			    size_t bytes)
 {
 	struct qfprom_priv *priv = context;
@@ -314,10 +314,10 @@ static int qfprom_reg_write(void *context, unsigned int reg, void *_val,
 exit_enabled_fuse_blowing:
 	qfprom_disable_fuse_blowing(priv, &old);
 
-	return ret;
+	return ret < 0 ? ret : bytes;
 }
 
-static int qfprom_reg_read(void *context,
+static ssize_t qfprom_reg_read(void *context,
 			unsigned int reg, void *_val, size_t bytes)
 {
 	struct qfprom_priv *priv = context;
@@ -331,7 +331,7 @@ static int qfprom_reg_read(void *context,
 	while (words--)
 		*val++ = readb(base + reg + i++);
 
-	return 0;
+	return bytes;
 }
 
 static void qfprom_runtime_disable(void *data)
diff --git a/drivers/nvmem/qoriq-efuse.c b/drivers/nvmem/qoriq-efuse.c
index e7fd04d6dd94..1e7315953e44 100644
--- a/drivers/nvmem/qoriq-efuse.c
+++ b/drivers/nvmem/qoriq-efuse.c
@@ -14,7 +14,7 @@ struct qoriq_efuse_priv {
 	void __iomem *base;
 };
 
-static int qoriq_efuse_read(void *context, unsigned int offset, void *val,
+static ssize_t qoriq_efuse_read(void *context, unsigned int offset, void *val,
 			    size_t bytes)
 {
 	struct qoriq_efuse_priv *priv = context;
@@ -24,7 +24,7 @@ static int qoriq_efuse_read(void *context, unsigned int offset, void *val,
 
 	/* Ignore trailing bytes (there shouldn't be any) */
 
-	return 0;
+	return bytes;
 }
 
 static int qoriq_efuse_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/rave-sp-eeprom.c b/drivers/nvmem/rave-sp-eeprom.c
index 9ecf3873cbb7..6c8aecde8311 100644
--- a/drivers/nvmem/rave-sp-eeprom.c
+++ b/drivers/nvmem/rave-sp-eeprom.c
@@ -214,10 +214,10 @@ rave_sp_eeprom_page_access(struct rave_sp_eeprom *eeprom,
  * arbitrary offset (not necessary page aligned) of arbitrary length
  * (is not constrained by EEPROM page size).
  *
- * Returns zero in case of success or negative error code in case of
- * failure.
+ * Returns number of bytes in case of success or negative error code
+ * in case of failure.
  */
-static int rave_sp_eeprom_access(struct rave_sp_eeprom *eeprom,
+static ssize_t rave_sp_eeprom_access(struct rave_sp_eeprom *eeprom,
 				 enum rave_sp_eeprom_access_type type,
 				 unsigned int offset, u8 *data,
 				 unsigned int data_len)
@@ -267,17 +267,17 @@ static int rave_sp_eeprom_access(struct rave_sp_eeprom *eeprom,
 	} while (residue);
 out:
 	mutex_unlock(&eeprom->mutex);
-	return ret;
+	return ret < 0 ? ret : data_len;
 }
 
-static int rave_sp_eeprom_reg_read(void *eeprom, unsigned int offset,
+static ssize_t rave_sp_eeprom_reg_read(void *eeprom, unsigned int offset,
 				   void *val, size_t bytes)
 {
 	return rave_sp_eeprom_access(eeprom, RAVE_SP_EEPROM_READ,
 				     offset, val, bytes);
 }
 
-static int rave_sp_eeprom_reg_write(void *eeprom, unsigned int offset,
+static ssize_t rave_sp_eeprom_reg_write(void *eeprom, unsigned int offset,
 				    void *val, size_t bytes)
 {
 	return rave_sp_eeprom_access(eeprom, RAVE_SP_EEPROM_WRITE,
diff --git a/drivers/nvmem/rmem.c b/drivers/nvmem/rmem.c
index 752d0bf4445e..1ddb832cd178 100644
--- a/drivers/nvmem/rmem.c
+++ b/drivers/nvmem/rmem.c
@@ -17,7 +17,7 @@ struct rmem {
 	phys_addr_t size;
 };
 
-static int rmem_read(void *context, unsigned int offset,
+static ssize_t rmem_read(void *context, unsigned int offset,
 		     void *val, size_t bytes)
 {
 	struct rmem *priv = context;
diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c
index 2b40978ddb18..fe05d7afd281 100644
--- a/drivers/nvmem/rockchip-efuse.c
+++ b/drivers/nvmem/rockchip-efuse.c
@@ -52,7 +52,7 @@ struct rockchip_efuse_chip {
 	struct clk *clk;
 };
 
-static int rockchip_rk3288_efuse_read(void *context, unsigned int offset,
+static ssize_t rockchip_rk3288_efuse_read(void *context, unsigned int offset,
 				      void *val, size_t bytes)
 {
 	struct rockchip_efuse_chip *efuse = context;
@@ -65,6 +65,7 @@ static int rockchip_rk3288_efuse_read(void *context, unsigned int offset,
 		return ret;
 	}
 
+	ret = bytes;
 	writel(RK3288_LOAD | RK3288_PGENB, efuse->base + REG_EFUSE_CTRL);
 	udelay(1);
 	while (bytes--) {
@@ -89,7 +90,7 @@ static int rockchip_rk3288_efuse_read(void *context, unsigned int offset,
 
 	clk_disable_unprepare(efuse->clk);
 
-	return 0;
+	return ret;
 }
 
 static int rockchip_rk3328_efuse_read(void *context, unsigned int offset,
@@ -144,10 +145,10 @@ static int rockchip_rk3328_efuse_read(void *context, unsigned int offset,
 nomem:
 	clk_disable_unprepare(efuse->clk);
 
-	return ret;
+	return ret < 0 ? ret : bytes;
 }
 
-static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
+static ssize_t rockchip_rk3399_efuse_read(void *context, unsigned int offset,
 				      void *val, size_t bytes)
 {
 	struct rockchip_efuse_chip *efuse = context;
@@ -200,7 +201,7 @@ static int rockchip_rk3399_efuse_read(void *context, unsigned int offset,
 
 	clk_disable_unprepare(efuse->clk);
 
-	return 0;
+	return bytes;
 }
 
 static struct nvmem_config econfig = {
diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
index cb9aa5428350..f7eb1feea978 100644
--- a/drivers/nvmem/rockchip-otp.c
+++ b/drivers/nvmem/rockchip-otp.c
@@ -144,10 +144,11 @@ static int rockchip_otp_ecc_enable(struct rockchip_otp *otp, bool enable)
 	return ret;
 }
 
-static int px30_otp_read(void *context, unsigned int offset,
+static ssize_t px30_otp_read(void *context, unsigned int offset,
 			 void *val, size_t bytes)
 {
 	struct rockchip_otp *otp = context;
+	size_t bytes_read = bytes;
 	u8 *buf = val;
 	int ret;
 
@@ -181,10 +182,10 @@ static int px30_otp_read(void *context, unsigned int offset,
 read_end:
 	writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
 
-	return ret;
+	return ret < 0 ? ret : bytes_read;
 }
 
-static int rk3588_otp_read(void *context, unsigned int offset,
+static ssize_t rk3588_otp_read(void *context, unsigned int offset,
 			   void *val, size_t bytes)
 {
 	struct rockchip_otp *otp = context;
@@ -227,10 +228,10 @@ static int rk3588_otp_read(void *context, unsigned int offset,
 read_end:
 	kfree(buf);
 
-	return ret;
+	return ret < 0 ? ret : bytes;
 }
 
-static int rockchip_otp_read(void *context, unsigned int offset,
+static ssize_t rockchip_otp_read(void *context, unsigned int offset,
 			     void *val, size_t bytes)
 {
 	struct rockchip_otp *otp = context;
@@ -249,7 +250,7 @@ static int rockchip_otp_read(void *context, unsigned int offset,
 
 	clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks);
 
-	return ret;
+	return ret < 0 ? ret : bytes;
 }
 
 static struct nvmem_config otp_config = {
diff --git a/drivers/nvmem/sc27xx-efuse.c b/drivers/nvmem/sc27xx-efuse.c
index bff27011f4ff..309ba1306939 100644
--- a/drivers/nvmem/sc27xx-efuse.c
+++ b/drivers/nvmem/sc27xx-efuse.c
@@ -121,7 +121,7 @@ static int sc27xx_efuse_poll_status(struct sc27xx_efuse *efuse, u32 bits)
 	return 0;
 }
 
-static int sc27xx_efuse_read(void *context, u32 offset, void *val, size_t bytes)
+static ssize_t sc27xx_efuse_read(void *context, u32 offset, void *val, size_t bytes)
 {
 	struct sc27xx_efuse *efuse = context;
 	u32 buf, blk_index = offset / SC27XX_EFUSE_BLOCK_WIDTH;
@@ -194,6 +194,7 @@ static int sc27xx_efuse_read(void *context, u32 offset, void *val, size_t bytes)
 	if (!ret) {
 		buf >>= blk_offset;
 		memcpy(val, &buf, bytes);
+		ret = bytes;
 	}
 
 	return ret;
diff --git a/drivers/nvmem/sec-qfprom.c b/drivers/nvmem/sec-qfprom.c
index 19799b3fe00a..dbacaab519e7 100644
--- a/drivers/nvmem/sec-qfprom.c
+++ b/drivers/nvmem/sec-qfprom.c
@@ -20,7 +20,7 @@ struct sec_qfprom {
 	struct device *dev;
 };
 
-static int sec_qfprom_reg_read(void *context, unsigned int reg, void *_val, size_t bytes)
+static ssize_t sec_qfprom_reg_read(void *context, unsigned int reg, void *_val, size_t bytes)
 {
 	struct sec_qfprom *priv = context;
 	unsigned int i;
@@ -40,7 +40,7 @@ static int sec_qfprom_reg_read(void *context, unsigned int reg, void *_val, size
 		val[i] = tmp[reg & 3];
 	}
 
-	return 0;
+	return bytes;
 }
 
 static int sec_qfprom_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/snvs_lpgpr.c b/drivers/nvmem/snvs_lpgpr.c
index 89c27112320f..3019bf0c6271 100644
--- a/drivers/nvmem/snvs_lpgpr.c
+++ b/drivers/nvmem/snvs_lpgpr.c
@@ -50,7 +50,7 @@ static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx7d = {
 	.size		= 16,
 };
 
-static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
+static ssize_t snvs_lpgpr_write(void *context, unsigned int offset, void *val,
 			    size_t bytes)
 {
 	struct snvs_lpgpr_priv *priv = context;
@@ -72,18 +72,23 @@ static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
 	if (lock_reg & IMX_GPR_HL)
 		return -EPERM;
 
-	return regmap_bulk_write(priv->regmap, dcfg->offset + offset, val,
+	ret = regmap_bulk_write(priv->regmap, dcfg->offset + offset, val,
 				bytes / 4);
+
+	return ret < 0 ? ret : bytes;
 }
 
-static int snvs_lpgpr_read(void *context, unsigned int offset, void *val,
+static ssize_t snvs_lpgpr_read(void *context, unsigned int offset, void *val,
 			   size_t bytes)
 {
 	struct snvs_lpgpr_priv *priv = context;
 	const struct snvs_lpgpr_cfg *dcfg = priv->dcfg;
+	int ret;
 
-	return regmap_bulk_read(priv->regmap, dcfg->offset + offset,
+	ret = regmap_bulk_read(priv->regmap, dcfg->offset + offset,
 			       val, bytes / 4);
+
+	return ret < 0 ? ret : bytes;
 }
 
 static int snvs_lpgpr_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/sprd-efuse.c b/drivers/nvmem/sprd-efuse.c
index bb3105f3291f..5a1581df7555 100644
--- a/drivers/nvmem/sprd-efuse.c
+++ b/drivers/nvmem/sprd-efuse.c
@@ -291,7 +291,7 @@ static int sprd_efuse_raw_read(struct sprd_efuse *efuse, int blk, u32 *val,
 	return 0;
 }
 
-static int sprd_efuse_read(void *context, u32 offset, void *val, size_t bytes)
+static ssize_t sprd_efuse_read(void *context, u32 offset, void *val, size_t bytes)
 {
 	struct sprd_efuse *efuse = context;
 	bool blk_double = efuse->data->blk_double;
@@ -318,10 +318,10 @@ static int sprd_efuse_read(void *context, u32 offset, void *val, size_t bytes)
 
 unlock:
 	sprd_efuse_unlock(efuse);
-	return ret;
+	return ret < 0 ? ret : bytes;
 }
 
-static int sprd_efuse_write(void *context, u32 offset, void *val, size_t bytes)
+static ssize_t sprd_efuse_write(void *context, u32 offset, void *val, size_t bytes)
 {
 	struct sprd_efuse *efuse = context;
 	bool blk_double = efuse->data->blk_double;
@@ -355,7 +355,7 @@ static int sprd_efuse_write(void *context, u32 offset, void *val, size_t bytes)
 
 unlock:
 	sprd_efuse_unlock(efuse);
-	return ret;
+	return ret < 0 ? ret : bytes;
 }
 
 static int sprd_efuse_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/stm32-bsec-optee-ta.c b/drivers/nvmem/stm32-bsec-optee-ta.c
index f89ce791dd12..059f13af0886 100644
--- a/drivers/nvmem/stm32-bsec-optee-ta.c
+++ b/drivers/nvmem/stm32-bsec-optee-ta.c
@@ -136,7 +136,7 @@ void stm32_bsec_optee_ta_close(void *ctx)
 }
 
 /* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */
-int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
+ssize_t stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
 			     void *buf, size_t bytes)
 {
 	struct tee_shm *shm;
@@ -198,11 +198,11 @@ int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
 out_tee_session:
 	stm32_bsec_ta_close_session(ctx, session_id);
 
-	return ret;
+	return ret < 0 ? ret : bytes;
 }
 
 /* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
-int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
+ssize_t stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
 			      unsigned int offset, void *buf, size_t bytes)
 {	struct tee_shm *shm;
 	struct tee_ioctl_invoke_arg arg;
@@ -294,5 +294,5 @@ int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
 out_tee_session:
 	stm32_bsec_ta_close_session(ctx, session_id);
 
-	return ret;
+	return ret < 0 ? ret : bytes;
 }
diff --git a/drivers/nvmem/stm32-bsec-optee-ta.h b/drivers/nvmem/stm32-bsec-optee-ta.h
index 3966a0535179..799f9f915150 100644
--- a/drivers/nvmem/stm32-bsec-optee-ta.h
+++ b/drivers/nvmem/stm32-bsec-optee-ta.h
@@ -33,9 +33,9 @@ void stm32_bsec_optee_ta_close(void *ctx);
  * @bytes: number of bytes to read
  *
  * Return:
- *	On success, 0. On failure, -errno.
+ *	On success, bytes read. On failure, -errno.
  */
-int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
+ssize_t stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
 			     void *buf, size_t bytes);
 
 /**
@@ -47,9 +47,9 @@ int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
  * @bytes: number of bytes to write
  *
  * Return:
- *	On success, 0. On failure, -errno.
+ *	On success, bytes written. On failure, -errno.
  */
-int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
+ssize_t stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
 			      unsigned int offset, void *buf, size_t bytes);
 
 #else
@@ -63,14 +63,14 @@ static inline void stm32_bsec_optee_ta_close(void *ctx)
 {
 }
 
-static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
+static inline ssize_t stm32_bsec_optee_ta_read(struct tee_context *ctx,
 					   unsigned int offset, void *buf,
 					   size_t bytes)
 {
 	return -EOPNOTSUPP;
 }
 
-static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
+static inline ssize_t stm32_bsec_optee_ta_write(struct tee_context *ctx,
 					    unsigned int lower,
 					    unsigned int offset, void *buf,
 					    size_t bytes)
diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c
index 82879b1c9eb9..a8c6983f9139 100644
--- a/drivers/nvmem/stm32-romem.c
+++ b/drivers/nvmem/stm32-romem.c
@@ -40,7 +40,7 @@ struct stm32_romem_priv {
 	struct tee_context *ctx;
 };
 
-static int stm32_romem_read(void *context, unsigned int offset, void *buf,
+static ssize_t stm32_romem_read(void *context, unsigned int offset, void *buf,
 			    size_t bytes)
 {
 	struct stm32_romem_priv *priv = context;
@@ -50,7 +50,7 @@ static int stm32_romem_read(void *context, unsigned int offset, void *buf,
 	for (i = offset; i < offset + bytes; i++)
 		*buf8++ = readb_relaxed(priv->base + i);
 
-	return 0;
+	return bytes;
 }
 
 static int stm32_bsec_smc(u8 op, u32 otp, u32 data, u32 *result)
@@ -71,7 +71,7 @@ static int stm32_bsec_smc(u8 op, u32 otp, u32 data, u32 *result)
 #endif
 }
 
-static int stm32_bsec_read(void *context, unsigned int offset, void *buf,
+static ssize_t stm32_bsec_read(void *context, unsigned int offset, void *buf,
 			   size_t bytes)
 {
 	struct stm32_romem_priv *priv = context;
@@ -115,10 +115,10 @@ static int stm32_bsec_read(void *context, unsigned int offset, void *buf,
 		skip_bytes = 0;
 	}
 
-	return 0;
+	return bytes;
 }
 
-static int stm32_bsec_write(void *context, unsigned int offset, void *buf,
+static ssize_t stm32_bsec_write(void *context, unsigned int offset, void *buf,
 			    size_t bytes)
 {
 	struct stm32_romem_priv *priv = context;
@@ -142,10 +142,10 @@ static int stm32_bsec_write(void *context, unsigned int offset, void *buf,
 	if (offset + bytes >= priv->lower * 4)
 		dev_warn(dev, "Update of upper OTPs with ECC protection (word programming, only once)\n");
 
-	return 0;
+	return bytes;
 }
 
-static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
+static ssize_t stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
 			       size_t bytes)
 {
 	struct stm32_romem_priv *priv = context;
@@ -153,7 +153,7 @@ static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
 	return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
 }
 
-static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
+static ssize_t stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
 				size_t bytes)
 {
 	struct stm32_romem_priv *priv = context;
diff --git a/drivers/nvmem/sunplus-ocotp.c b/drivers/nvmem/sunplus-ocotp.c
index 38f5d9df39cd..7bda128bb93e 100644
--- a/drivers/nvmem/sunplus-ocotp.c
+++ b/drivers/nvmem/sunplus-ocotp.c
@@ -114,7 +114,7 @@ static int sp_otp_read_real(struct sp_ocotp_priv *otp, int addr, char *value)
 	return ret;
 }
 
-static int sp_ocotp_read(void *priv, unsigned int offset, void *value, size_t bytes)
+static ssize_t sp_ocotp_read(void *priv, unsigned int offset, void *value, size_t bytes)
 {
 	struct sp_ocotp_priv *otp = priv;
 	unsigned int addr;
@@ -140,7 +140,7 @@ static int sp_ocotp_read(void *priv, unsigned int offset, void *value, size_t by
 disable_clk:
 	clk_disable(otp->clk);
 
-	return ret;
+	return ret < 0 ? ret : bytes;
 }
 
 static struct nvmem_config sp_ocotp_nvmem_config = {
diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index ba14a76208ab..26580c7a3c6d 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -36,7 +36,7 @@ struct sunxi_sid {
 	u32			value_offset;
 };
 
-static int sunxi_sid_read(void *context, unsigned int offset,
+static ssize_t sunxi_sid_read(void *context, unsigned int offset,
 			  void *val, size_t bytes)
 {
 	struct sunxi_sid *sid = context;
@@ -56,7 +56,7 @@ static int sunxi_sid_read(void *context, unsigned int offset,
 	word = readl_relaxed(sid->base + sid->value_offset + offset);
 	memcpy(val, &word, bytes);
 
-	return 0;
+	return bytes;
 }
 
 static int sun8i_sid_register_readout(const struct sunxi_sid *sid,
@@ -90,10 +90,11 @@ static int sun8i_sid_register_readout(const struct sunxi_sid *sid,
  * to be not reliable at all.
  * Read by the registers instead.
  */
-static int sun8i_sid_read_by_reg(void *context, unsigned int offset,
+static ssize_t sun8i_sid_read_by_reg(void *context, unsigned int offset,
 				 void *val, size_t bytes)
 {
 	struct sunxi_sid *sid = context;
+	size_t bytes_read = bytes;
 	u32 word;
 	int ret;
 
@@ -109,7 +110,7 @@ static int sun8i_sid_read_by_reg(void *context, unsigned int offset,
 	}
 
 	if (!bytes)
-		return 0;
+		return bytes_read;
 
 	/* Handle any trailing bytes */
 	ret = sun8i_sid_register_readout(sid, offset, &word);
@@ -118,7 +119,7 @@ static int sun8i_sid_read_by_reg(void *context, unsigned int offset,
 
 	memcpy(val, &word, bytes);
 
-	return 0;
+	return bytes_read;
 }
 
 static int sunxi_sid_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/u-boot-env.c b/drivers/nvmem/u-boot-env.c
index befbab156cda..a3cf63dfac2a 100644
--- a/drivers/nvmem/u-boot-env.c
+++ b/drivers/nvmem/u-boot-env.c
@@ -47,7 +47,7 @@ struct u_boot_env_image_broadcom {
 	DECLARE_FLEX_ARRAY(uint8_t, data);
 } __packed;
 
-static int u_boot_env_read(void *context, unsigned int offset, void *val,
+static ssize_t u_boot_env_read(void *context, unsigned int offset, void *val,
 			   size_t bytes)
 {
 	struct u_boot_env *priv = context;
@@ -66,7 +66,7 @@ static int u_boot_env_read(void *context, unsigned int offset, void *val,
 		return -EIO;
 	}
 
-	return 0;
+	return bytes_read;
 }
 
 static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
diff --git a/drivers/nvmem/uniphier-efuse.c b/drivers/nvmem/uniphier-efuse.c
index 6ad3295d3195..728c9af9fbe4 100644
--- a/drivers/nvmem/uniphier-efuse.c
+++ b/drivers/nvmem/uniphier-efuse.c
@@ -16,7 +16,7 @@ struct uniphier_efuse_priv {
 	void __iomem *base;
 };
 
-static int uniphier_reg_read(void *context,
+static ssize_t uniphier_reg_read(void *context,
 			     unsigned int reg, void *_val, size_t bytes)
 {
 	struct uniphier_efuse_priv *priv = context;
@@ -26,7 +26,7 @@ static int uniphier_reg_read(void *context,
 	for (offs = 0; offs < bytes; offs += sizeof(u8))
 		*val++ = readb(priv->base + reg + offs);
 
-	return 0;
+	return bytes;
 }
 
 static int uniphier_efuse_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/vf610-ocotp.c b/drivers/nvmem/vf610-ocotp.c
index ee9c61ae727d..0ed91de61950 100644
--- a/drivers/nvmem/vf610-ocotp.c
+++ b/drivers/nvmem/vf610-ocotp.c
@@ -143,11 +143,12 @@ static int vf610_get_fuse_address(int base_addr_offset)
 	return -EINVAL;
 }
 
-static int vf610_ocotp_read(void *context, unsigned int offset,
+static ssize_t vf610_ocotp_read(void *context, unsigned int offset,
 			void *val, size_t bytes)
 {
 	struct vf610_ocotp *ocotp = context;
 	void __iomem *base = ocotp->base;
+	size_t bytes_read = bytes;
 	u32 reg, *buf = val;
 	int fuse_addr;
 	int ret;
@@ -193,7 +194,7 @@ static int vf610_ocotp_read(void *context, unsigned int offset,
 		offset += 4;
 	}
 
-	return 0;
+	return bytes_read;
 }
 
 static struct nvmem_config ocotp_config = {
diff --git a/drivers/nvmem/zynqmp_nvmem.c b/drivers/nvmem/zynqmp_nvmem.c
index 7f15aa89a9d0..50f8497cc17a 100644
--- a/drivers/nvmem/zynqmp_nvmem.c
+++ b/drivers/nvmem/zynqmp_nvmem.c
@@ -30,7 +30,7 @@ static int zynqmp_nvmem_read(void *context, unsigned int offset,
 	dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version);
 	*(int *)val = version & SILICON_REVISION_MASK;
 
-	return 0;
+	return bytes;
 }
 
 static struct nvmem_config econfig = {
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index f0ba0e03218f..2cdab3fec2be 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -16,9 +16,9 @@
 #include <linux/gpio/consumer.h>
 
 struct nvmem_device;
-typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
+typedef ssize_t (*nvmem_reg_read_t)(void *priv, unsigned int offset,
 				void *val, size_t bytes);
-typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
+typedef ssize_t (*nvmem_reg_write_t)(void *priv, unsigned int offset,
 				 void *val, size_t bytes);
 /* used for vendor specific post processing of cell data */
 typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index,
-- 
2.44.0.rc0.258.g7320e95886-goog



From maz at kernel.org  Mon Feb 19 03:32:36 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 11:32:36 +0000
Subject: next-20240219: arm64: boot failed - gic_of_init
In-Reply-To: <86edd84wer.wl-maz@kernel.org>
References: <CA+G9fYugYiLd7MDn3wCxK+x5Td9WO-VUX2OvOtTN7D1d4GHCfg@mail.gmail.com>
	<86edd84wer.wl-maz@kernel.org>
Message-ID: <86cyss4rl7.wl-maz@kernel.org>

On Mon, 19 Feb 2024 09:48:28 +0000,
Marc Zyngier <maz at kernel.org> wrote:
> 
> On Mon, 19 Feb 2024 09:42:45 +0000,
> Naresh Kamboju <naresh.kamboju at linaro.org> wrote:
> > 
> > The qemu-arm64 boot failed with linux next-20240219 tag kernel.
> > 
> > Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>
> > 
> > Boot log:
> > ---------
> > <6>[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
> > <1>[    0.000000] Unable to handle kernel paging request at virtual
> > address ffff80008001ffe8
> > <1>[    0.000000] Mem abort info:
> > <1>[    0.000000]   ESR = 0x0000000096000004
> > <1>[    0.000000]   EC = 0x25: DABT (current EL), IL = 32 bits
> > <1>[    0.000000]   SET = 0, FnV = 0
> > <1>[    0.000000]   EA = 0, S1PTW = 0
> > <1>[    0.000000]   FSC = 0x04: level 0 translation fault
> > <1>[    0.000000] Data abort info:
> > <1>[    0.000000]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
> > <1>[    0.000000]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> > <1>[    0.000000]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> > <1>[    0.000000] swapper pgtable: 4k pages, 52-bit VAs, pgdp=0000000042497000
> > <1>[    0.000000] [ffff80008001ffe8] pgd=10000000439a5003,
> > p4d=10000001000e3003, pud=10000001000e4003, pmd=10000001000e5003,
> > pte=006800000800f413
> > <0>[    0.000000] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
> > <4>[    0.000000] Modules linked in:
> > <4>[    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted
> > 6.8.0-rc5-next-20240219 #1
> > <4>[    0.000000] Hardware name: linux,dummy-virt (DT)
> > <4>[    0.000000] pstate: 804000c9 (Nzcv daIF +PAN -UAO -TCO -DIT
> > -SSBS BTYPE=--)
> > <4>[    0.000000] pc : gic_of_init+0x84/0x3a8
> > <4>[    0.000000] lr : gic_of_init+0x290/0x3a8
> > ...
> > <4>[    0.000000] Call trace:
> > <4>[    0.000000]  gic_of_init+0x84/0x3a8
> > <4>[    0.000000]  of_irq_init+0x1d4/0x3d0
> > <4>[    0.000000]  irqchip_init+0x20/0x50
> > <4>[    0.000000]  init_IRQ+0xa8/0xc8
> > <4>[    0.000000]  start_kernel+0x270/0x690
> > <4>[    0.000000]  __primary_switched+0x80/0x90
> > <0>[    0.000000] Code: f94017e0 f90007e0 d29ffd00 8b0002c0 (b9400000)
> > <4>[    0.000000] ---[ end trace 0000000000000000 ]---
> > <0>[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
> > <0>[    0.000000] ---[ end Kernel panic - not syncing: Attempted to
> > kill the idle task! ]---
> > 
> > Links:
> >  - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240219/testrun/22730192/suite/boot/test/gcc-13-lkftconfig-armv8_features/log
> >  - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240219/testrun/22730192/suite/boot/tests/
> 
> Where is the configuration file? What are the parameters to QEMU?
> Please consider making this a useful and actionable report.

For what it is worth, I've just tested both defconfig and my own
configuration with both 4k (kvmtool, QEMU+KVM and on SynQuacer) and
16k (kvmtool), without any obvious problem.

So until you come up with more specific details, there isn't much I
can do.

	M.

-- 
Without deviation from the norm, progress is not possible.


From thomas.bourgoin at foss.st.com  Mon Feb 19 03:37:42 2024
From: thomas.bourgoin at foss.st.com (Thomas Bourgoin)
Date: Mon, 19 Feb 2024 12:37:42 +0100
Subject: [PATCH 0/3] Enable the CRC and CRYP IP on STM32MP135F-DK board.
Message-ID: <20240219113745.92538-1-thomas.bourgoin@foss.st.com>

Enable the CRC and CRYP internal peripherals on STM32MP135F-DK board.

The first 2 patches adds the node crc1 in file stm32mp131.dtsi and
enables it for the board stm32mp135f-dk.
The last patch of the patchset enables the node cryp for the board
stm32mp135f-dk.

Lionel Debieve (2):
  ARM: dts: stm32: add CRC on stm32mp131
  ARM: dts: stm32: enable CRC on stm32mp135f-dk

Thomas Bourgoin (1):
  ARM: dts: stm32: enable crypto accelerator on stm32mp135f-dk

 arch/arm/boot/dts/st/stm32mp131.dtsi    | 7 +++++++
 arch/arm/boot/dts/st/stm32mp135f-dk.dts | 8 ++++++++
 2 files changed, 15 insertions(+)

--
2.25.1



From thomas.bourgoin at foss.st.com  Mon Feb 19 03:37:43 2024
From: thomas.bourgoin at foss.st.com (Thomas Bourgoin)
Date: Mon, 19 Feb 2024 12:37:43 +0100
Subject: [PATCH 1/3] ARM: dts: stm32: add CRC on stm32mp131
In-Reply-To: <20240219113745.92538-1-thomas.bourgoin@foss.st.com>
References: <20240219113745.92538-1-thomas.bourgoin@foss.st.com>
Message-ID: <20240219113745.92538-2-thomas.bourgoin@foss.st.com>

From: Lionel Debieve <lionel.debieve at foss.st.com>

The Cyclic redundancy check calculation unit (CRC) peripheral
offers a CRC-based operation (CRC32/CRC32C) used to verify data
transmission or storage integrity.
This peripheral is integrated in stm32mp131 and can be default
enabled.

Signed-off-by: Lionel Debieve <lionel.debieve at foss.st.com>
Signed-off-by: Thomas Bourgoin <thomas.bourgoin at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp131.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp131.dtsi b/arch/arm/boot/dts/st/stm32mp131.dtsi
index b04d24c939c3..3900f32da797 100644
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -1315,6 +1315,13 @@ sdmmc2: mmc at 58007000 {
 			status = "disabled";
 		};
 
+		crc1: crc at 58009000 {
+			compatible = "st,stm32f7-crc";
+			reg = <0x58009000 0x400>;
+			clocks = <&rcc CRC1>;
+			status = "disabled";
+		};
+
 		usbh_ohci: usb at 5800c000 {
 			compatible = "generic-ohci";
 			reg = <0x5800c000 0x1000>;
-- 
2.25.1



From thomas.bourgoin at foss.st.com  Mon Feb 19 03:37:44 2024
From: thomas.bourgoin at foss.st.com (Thomas Bourgoin)
Date: Mon, 19 Feb 2024 12:37:44 +0100
Subject: [PATCH 2/3] ARM: dts: stm32: enable CRC on stm32mp135f-dk
In-Reply-To: <20240219113745.92538-1-thomas.bourgoin@foss.st.com>
References: <20240219113745.92538-1-thomas.bourgoin@foss.st.com>
Message-ID: <20240219113745.92538-3-thomas.bourgoin@foss.st.com>

From: Lionel Debieve <lionel.debieve at foss.st.com>

Enable Cyclic redundancy check on stm32mp135f-dk.

Signed-off-by: Lionel Debieve <lionel.debieve at foss.st.com>
Signed-off-by: Thomas Bourgoin <thomas.bourgoin at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp135f-dk.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
index eea740d097c7..a7b1b2ca9d0b 100644
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -93,6 +93,10 @@ channel at 12 {
 	};
 };
 
+&crc1 {
+	status = "okay";
+};
+
 &i2c1 {
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&i2c1_pins_a>;
-- 
2.25.1



From thomas.bourgoin at foss.st.com  Mon Feb 19 03:37:45 2024
From: thomas.bourgoin at foss.st.com (Thomas Bourgoin)
Date: Mon, 19 Feb 2024 12:37:45 +0100
Subject: [PATCH 3/3] ARM: dts: stm32: enable crypto accelerator on stm32mp135f-dk
In-Reply-To: <20240219113745.92538-1-thomas.bourgoin@foss.st.com>
References: <20240219113745.92538-1-thomas.bourgoin@foss.st.com>
Message-ID: <20240219113745.92538-4-thomas.bourgoin@foss.st.com>

Add the crypto accelerator enable on stm32mp135f-dk board.

Signed-off-by: Thomas Bourgoin <thomas.bourgoin at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp135f-dk.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
index a7b1b2ca9d0b..52171214a308 100644
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -97,6 +97,10 @@ &crc1 {
 	status = "okay";
 };
 
+&cryp {
+	status = "okay";
+};
+
 &i2c1 {
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&i2c1_pins_a>;
-- 
2.25.1



From Jonathan.Cameron at Huawei.com  Mon Feb 19 03:40:39 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Mon, 19 Feb 2024 11:40:39 +0000
Subject: [PATCH v1 4/6] drivers/perf: Add SiFive Extensible Cache PMU
 driver
In-Reply-To: <20240216000837.1868917-5-samuel.holland@sifive.com>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
	<20240216000837.1868917-5-samuel.holland@sifive.com>
Message-ID: <20240219114039.00004a86@Huawei.com>

On Thu, 15 Feb 2024 16:08:16 -0800
Samuel Holland <samuel.holland at sifive.com> wrote:

> From: Eric Lin <eric.lin at sifive.com>
> 
> Add a driver for the PMU found in the SiFive Extensible Cache
> controller. This PMU provides a configurable number of counters and a
> variety of events. Events are grouped into sets. Each counter can count
> events from only one set at a time; however, it can count any number of
> events within that set simultaneously. The PMU hardware does not provide
> an overflow interrupt.
> 
> The counter inhibit register is used to atomically start/stop/read a
> group of counters so their values can be usefully compared.
> 
> Some events can be filtered further by client ID (e.g. CPU or external
> DMA master). That functionality is not supported by this driver.
> 
> This driver further assumes that a single Extensible Cache instance is
> shared by all CPUs in the system.
> 
> Example usage:
> 
> $ perf stat -e sifive_ecache_pmu/inner_rd_request/,
> 	       sifive_ecache_pmu/inner_wr_request/,
> 	       sifive_ecache_pmu/inner_rd_request_hit/,
> 	       sifive_ecache_pmu/inner_wr_request_hit/ ls
> 
>  Performance counter stats for 'system wide':
> 
>             148001      sifive_ecache_pmu/inner_rd_request/
>             121064      sifive_ecache_pmu/inner_wr_request/
>             113124      sifive_ecache_pmu/inner_rd_request_hit/
>             120860      sifive_ecache_pmu/inner_wr_request_hit/
> 
>        0.010643962 seconds time elapsed
> 
> Example combining the read/write events together within each counter:
> 
> $ perf stat -e sifive_ecache_pmu/event=0x601/,
> 	       sifive_ecache_pmu/event=0xc001/ ls
> 
>  Performance counter stats for 'system wide':
> 
>             262619      sifive_ecache_pmu/event=0x601/
>             224533      sifive_ecache_pmu/event=0xc001/
> 
>        0.009794808 seconds time elapsed
> 
> Signed-off-by: Eric Lin <eric.lin at sifive.com>
> Co-developed-by: Samuel Holland <samuel.holland at sifive.com>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>


Hi Samuel,

Some comments inline. Note this is a driver by review so not very
thorough!

Jonathan

> +
> +static u64 read_counter(const struct sifive_ecache_pmu *ecache_pmu, const struct hw_perf_event *hwc)
> +{
> +	u64 value = 0;
> +
> +	for (int i = 0; i < ecache_pmu->n_slices; i++) {
> +		void __iomem *base = ecache_pmu->slice[i].base;
> +
> +		value += readq(base + hwc->event_base);
Feels like this summing should be a userspace problem.
Knowing about slice imbalance is often useful (depending on the
micro architecture obviously!)


> +	}
> +
> +	return value;
> +}



> +
> +static int sifive_ecache_pmu_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *ecache_node = dev_of_node(dev);
> +	struct sifive_ecache_pmu *ecache_pmu;
> +	struct device_node *slice_node;
> +	u32 slice_counters;
> +	int n_slices, ret;
> +	int i = 0;
> +
> +	n_slices = of_get_available_child_count(ecache_node);
fwnode_get_available_child_count(dev_fwnode(&pdev->dev));

Not sure why there isn't yet a device version of this (IIRC anyway).

> +	if (!n_slices)
> +		return -ENODEV;
> +
> +	ecache_pmu = devm_kzalloc(dev, struct_size(ecache_pmu, slice, n_slices), GFP_KERNEL);
> +	if (!ecache_pmu)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, ecache_pmu);
> +
> +	ecache_pmu->pmu = (struct pmu) {
> +		.parent		= dev,
> +		.attr_groups	= sifive_ecache_pmu_attr_grps,
> +		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
> +		.task_ctx_nr	= perf_invalid_context,
> +		.event_init	= sifive_ecache_pmu_event_init,
> +		.add		= sifive_ecache_pmu_add,
> +		.del		= sifive_ecache_pmu_del,
> +		.start		= sifive_ecache_pmu_start,
> +		.stop		= sifive_ecache_pmu_stop,
> +		.read		= sifive_ecache_pmu_read,
> +		.start_txn	= sifive_ecache_pmu_start_txn,
> +		.commit_txn	= sifive_ecache_pmu_commit_txn,
> +		.cancel_txn	= sifive_ecache_pmu_cancel_txn,
> +	};
> +	ecache_pmu->cpu = nr_cpu_ids;
> +	ecache_pmu->n_counters = ECACHE_PMU_MAX_COUNTERS;
> +	ecache_pmu->n_slices = n_slices;
> +
> +	for_each_available_child_of_node(ecache_node, slice_node) {
device_for_each_child_node() (generic handlers only provide the available version btw
which is non obvious from naming)

> +		struct sifive_ecache_pmu_slice *slice = &ecache_pmu->slice[i++];
> +
> +		slice->base = devm_of_iomap(dev, slice_node, 0, NULL);
> +		if (IS_ERR(slice->base))
Leaked slice_node

FWIW https://lore.kernel.org/linux-iio/20240217164249.921878-1-jic23 at kernel.org/
adds device_for_each_child_node_scoped() which deals with this stuff using
cleanup.h magic.


> +			return PTR_ERR(slice->base);
> +
> +		/* Get number of counters from slice node */
> +		ret = of_property_read_u32(slice_node, "sifive,perfmon-counters", &slice_counters);
Not sure on what perf maintainers want, but I'd go with
device_property_read etc as in the previous driver.

> +		if (ret)
leaked slice_node

> +			return dev_err_probe(dev, ret,
> +					     "Slice %pOF missing sifive,perfmon-counters property\n",
> +					     slice_node);
> +
> +		ecache_pmu->n_counters = min_t(u32, slice_counters, ecache_pmu->n_counters);
> +	}
> +
> +	sifive_ecache_pmu_hw_init(ecache_pmu);
> +
> +	ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_SIFIVE_ECACHE_ONLINE, &ecache_pmu->node);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to add CPU hotplug instance\n");
> +
> +	ret = perf_pmu_register(&ecache_pmu->pmu, "sifive_ecache_pmu", -1);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "Failed to register PMU\n");
> +		goto err_remove_instance;
Comments from other review apply here as well so if you agree apply them in both drivers.

> +	}
> +
> +	return 0;
> +
> +err_remove_instance:
> +	cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_SIFIVE_ECACHE_ONLINE, &ecache_pmu->node);
> +
> +	return ret;
> +}


From laurent.pinchart at ideasonboard.com  Mon Feb 19 03:54:30 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 19 Feb 2024 13:54:30 +0200
Subject: [PATCH] media: rkisp1: Allow higher input resolution
In-Reply-To: <ZdMpSLqYVFbU7sF0@pyrite.rasen.tech>
References: <20240217185202.1754750-1-megi@xff.cz>
 <20240218205908.GA12766@pendragon.ideasonboard.com>
 <pftafukuzq7qzbhlvwtmeg3mburnttylgy4246timlghtrdgx4@r6munvmj6oqt>
 <CAHCN7x+zi3WxnY-mxZFKePs1cS=-DprEmh_CnypJ4XK7xBzjMQ@mail.gmail.com>
 <b500676e-431f-40fc-868b-9f9bb359a109@ideasonboard.com>
 <ZdMpSLqYVFbU7sF0@pyrite.rasen.tech>
Message-ID: <20240219115430.GC13043@pendragon.ideasonboard.com>

On Mon, Feb 19, 2024 at 07:11:20PM +0900, Paul Elder wrote:
> On Mon, Feb 19, 2024 at 02:33:21PM +0530, Umang Jain wrote:
> > On 19/02/24 7:39 am, Adam Ford wrote:
> > > On Sun, Feb 18, 2024 at 3:02?PM Ond?ej Jirman <megi at xff.cz> wrote:
> > > > On Sun, Feb 18, 2024 at 10:59:08PM +0200, Laurent Pinchart wrote:
> > > > > On Sat, Feb 17, 2024 at 07:51:58PM +0100, Ond?ej Jirman wrote:
> > > > > > From: Ondrej Jirman <megi at xff.cz>
> > > > > > 
> > > > > > In BSP driver, it is allowed, and it works in practice. Tested on
> > > > > > Pinephone Pro/RK3399 with IMX258 at full res.
> > > > >
> > > > > Paul, Umang, do I recall correctly that you have a similar change ?
> > > > > Could you review and test this (especially on the i.MX8MP) ?
> > > >
> > > > It's also a limit from the datasheet, so the change should not be that
> > > > controversial:
> > > > 
> > > >    https://megous.com/dl/tmp/d2b333043ecebaf3.png
> > > > 
> > > > (so that it doesn't sound like I just copied the BSP values)
> > > > 
> > >  From what I see in the i.MX8M Plus reference manual, it has a max
> > > resolution of 4096x3072, so it might be necessary to move this off
> > 
> > This is what I (and I assume Paul too) have been working with on i.MX8M
> > Plus. So it's the known and tested value of max ISP input from out side.
> >
> > > from a #define into a structure that varies by product family.
> 
> Yes, this is what needs to be done. Here's what I have in my notes:
> 
> - The RK3399 TRM says 4416x3312 max input and output on main path, with
>   1920x1080 max output on self path.
> - The PX30 datasheet [1] says 3264x2448 max input and output on main
>   path, with 1920x1080 max output on self path.
> - The RK3288 documentation [2] (under "Camera Interface and Image
>   Processor") says 4416x3312 max input and output on main path, with
>   1920x1080 max output on self path.
> - The i.MX8MP reference manual (the open one) [3] (in table 13-1) says
>   4096x3072 max resolution in single ISP mode
> 
> The i.MX8M Plus seems to indeed be limited to 4096x3072, but the TPG is
> capable of generating 4416x3312, and the ISP works fine in bypass (and
> therefore raw) mode, so technically it has different maximum sizes
> depending on the format which makes this more exciting.
> 
> In any case, the PX30 (assuming the datasheet is correct) only supports
> up to 3264x2448, so the existing #define is incorrect anyway.
> 
> I don't have a PX30 nor an RK3288 so I can't test those, and I haven't
> set up my OV64A40 yet which (I've heard) can be used to test even bigger
> resolutions.

Thanks for the summary Paul.

Ond?ej, would you be interested in implementing this ?

> [1] https://opensource.rock-chips.com/images/8/87/Rockchip_PX30_Datasheet_V1.4-20191227.pdf
> [2] https://opensource.rock-chips.com/images/4/49/Rockchip_RK3288_Datasheet_V2.7-20191227.pdf
> [3] (requires login) https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/i-mx-applications-processors/i-mx-8-applications-processors/i-mx-8m-plus-arm-cortex-a53-machine-learning-vision-multimedia-and-industrial-iot:IMX8MPLUS
> 
> > > > > > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > > > > > ---
> > > > > >   drivers/media/platform/rockchip/rkisp1/rkisp1-common.h | 4 ++--
> > > > > >   1 file changed, 2 insertions(+), 2 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > > index 4b6b28c05b89..74098ddbeeb3 100644
> > > > > > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > > @@ -33,8 +33,8 @@ struct dentry;
> > > > > >   #define RKISP1_ISP_SD_SINK                 BIT(1)
> > > > > > 
> > > > > >   /* min and max values for the widths and heights of the entities */
> > > > > > -#define RKISP1_ISP_MAX_WIDTH                       4032
> > > > > > -#define RKISP1_ISP_MAX_HEIGHT                      3024
> > > > > > +#define RKISP1_ISP_MAX_WIDTH                       4416
> > > > > > +#define RKISP1_ISP_MAX_HEIGHT                      3312
> > > > > >   #define RKISP1_ISP_MIN_WIDTH                       32
> > > > > >   #define RKISP1_ISP_MIN_HEIGHT                      32
> > > > > > 

-- 
Regards,

Laurent Pinchart


From andyshrk at 163.com  Mon Feb 19 04:01:15 2024
From: andyshrk at 163.com (Andy Yan)
Date: Mon, 19 Feb 2024 20:01:15 +0800
Subject: [PATCH] drm/rockchip: vop2: Remove AR30 and AB30 format support
Message-ID: <20240219120115.1306717-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

The Alpha blending for 30 bit RGB/BGR are not
functioning properly for rk3568/rk3588, so remove
it from the format list.

Fixes: bfd8a5c228fa ("drm/rockchip: vop2: Add more supported 10bit formats")
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
---

 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index 48170694ac6b..18efb3fe1c00 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -17,9 +17,7 @@
 
 static const uint32_t formats_cluster[] = {
 	DRM_FORMAT_XRGB2101010,
-	DRM_FORMAT_ARGB2101010,
 	DRM_FORMAT_XBGR2101010,
-	DRM_FORMAT_ABGR2101010,
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
 	DRM_FORMAT_XBGR8888,
-- 
2.34.1



From ricardo at marliere.net  Mon Feb 19 04:03:11 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Mon, 19 Feb 2024 09:03:11 -0300
Subject: [PATCH next] bus: fsl-mc: constify the struct device_type usage
Message-ID: <20240219-device_cleanup-fsl-mc-v1-1-d206b8b90f2b@marliere.net>

Since commit aed65af1cc2f ("drivers: make device_type const"), the driver
core can properly handle constant struct device_type. Move all the
device_type variables used in the bus to be constant structures as well,
placing it into read-only memory which can not be modified at runtime.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 drivers/bus/fsl-mc/fsl-mc-bus.c | 32 ++++++++++++++++----------------
 include/linux/fsl/mc.h          | 30 +++++++++++++++---------------
 2 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index 78b96cd63de9..f75ca3f0d75a 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -320,82 +320,82 @@ struct bus_type fsl_mc_bus_type = {
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_type);
 
-struct device_type fsl_mc_bus_dprc_type = {
+const struct device_type fsl_mc_bus_dprc_type = {
 	.name = "fsl_mc_bus_dprc"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dprc_type);
 
-struct device_type fsl_mc_bus_dpni_type = {
+const struct device_type fsl_mc_bus_dpni_type = {
 	.name = "fsl_mc_bus_dpni"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpni_type);
 
-struct device_type fsl_mc_bus_dpio_type = {
+const struct device_type fsl_mc_bus_dpio_type = {
 	.name = "fsl_mc_bus_dpio"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpio_type);
 
-struct device_type fsl_mc_bus_dpsw_type = {
+const struct device_type fsl_mc_bus_dpsw_type = {
 	.name = "fsl_mc_bus_dpsw"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpsw_type);
 
-struct device_type fsl_mc_bus_dpbp_type = {
+const struct device_type fsl_mc_bus_dpbp_type = {
 	.name = "fsl_mc_bus_dpbp"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpbp_type);
 
-struct device_type fsl_mc_bus_dpcon_type = {
+const struct device_type fsl_mc_bus_dpcon_type = {
 	.name = "fsl_mc_bus_dpcon"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpcon_type);
 
-struct device_type fsl_mc_bus_dpmcp_type = {
+const struct device_type fsl_mc_bus_dpmcp_type = {
 	.name = "fsl_mc_bus_dpmcp"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpmcp_type);
 
-struct device_type fsl_mc_bus_dpmac_type = {
+const struct device_type fsl_mc_bus_dpmac_type = {
 	.name = "fsl_mc_bus_dpmac"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpmac_type);
 
-struct device_type fsl_mc_bus_dprtc_type = {
+const struct device_type fsl_mc_bus_dprtc_type = {
 	.name = "fsl_mc_bus_dprtc"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dprtc_type);
 
-struct device_type fsl_mc_bus_dpseci_type = {
+const struct device_type fsl_mc_bus_dpseci_type = {
 	.name = "fsl_mc_bus_dpseci"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpseci_type);
 
-struct device_type fsl_mc_bus_dpdmux_type = {
+const struct device_type fsl_mc_bus_dpdmux_type = {
 	.name = "fsl_mc_bus_dpdmux"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdmux_type);
 
-struct device_type fsl_mc_bus_dpdcei_type = {
+const struct device_type fsl_mc_bus_dpdcei_type = {
 	.name = "fsl_mc_bus_dpdcei"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdcei_type);
 
-struct device_type fsl_mc_bus_dpaiop_type = {
+const struct device_type fsl_mc_bus_dpaiop_type = {
 	.name = "fsl_mc_bus_dpaiop"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpaiop_type);
 
-struct device_type fsl_mc_bus_dpci_type = {
+const struct device_type fsl_mc_bus_dpci_type = {
 	.name = "fsl_mc_bus_dpci"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpci_type);
 
-struct device_type fsl_mc_bus_dpdmai_type = {
+const struct device_type fsl_mc_bus_dpdmai_type = {
 	.name = "fsl_mc_bus_dpdmai"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdmai_type);
 
-struct device_type fsl_mc_bus_dpdbg_type = {
+const struct device_type fsl_mc_bus_dpdbg_type = {
 	.name = "fsl_mc_bus_dpdbg"
 };
 EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdbg_type);
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index a1b3de87a3d1..4b9311f122e0 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -438,21 +438,21 @@ struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev,
 
 extern struct bus_type fsl_mc_bus_type;
 
-extern struct device_type fsl_mc_bus_dprc_type;
-extern struct device_type fsl_mc_bus_dpni_type;
-extern struct device_type fsl_mc_bus_dpio_type;
-extern struct device_type fsl_mc_bus_dpsw_type;
-extern struct device_type fsl_mc_bus_dpbp_type;
-extern struct device_type fsl_mc_bus_dpcon_type;
-extern struct device_type fsl_mc_bus_dpmcp_type;
-extern struct device_type fsl_mc_bus_dpmac_type;
-extern struct device_type fsl_mc_bus_dprtc_type;
-extern struct device_type fsl_mc_bus_dpseci_type;
-extern struct device_type fsl_mc_bus_dpdmux_type;
-extern struct device_type fsl_mc_bus_dpdcei_type;
-extern struct device_type fsl_mc_bus_dpaiop_type;
-extern struct device_type fsl_mc_bus_dpci_type;
-extern struct device_type fsl_mc_bus_dpdmai_type;
+extern const struct device_type fsl_mc_bus_dprc_type;
+extern const struct device_type fsl_mc_bus_dpni_type;
+extern const struct device_type fsl_mc_bus_dpio_type;
+extern const struct device_type fsl_mc_bus_dpsw_type;
+extern const struct device_type fsl_mc_bus_dpbp_type;
+extern const struct device_type fsl_mc_bus_dpcon_type;
+extern const struct device_type fsl_mc_bus_dpmcp_type;
+extern const struct device_type fsl_mc_bus_dpmac_type;
+extern const struct device_type fsl_mc_bus_dprtc_type;
+extern const struct device_type fsl_mc_bus_dpseci_type;
+extern const struct device_type fsl_mc_bus_dpdmux_type;
+extern const struct device_type fsl_mc_bus_dpdcei_type;
+extern const struct device_type fsl_mc_bus_dpaiop_type;
+extern const struct device_type fsl_mc_bus_dpci_type;
+extern const struct device_type fsl_mc_bus_dpdmai_type;
 
 static inline bool is_fsl_mc_bus_dprc(const struct fsl_mc_device *mc_dev)
 {

---
base-commit: b401b621758e46812da61fa58a67c3fd8d91de0d
change-id: 20240219-device_cleanup-fsl-mc-b2d8f7a5308d

Best regards,
-- 
Ricardo B. Marliere <ricardo at marliere.net>



From lihuisong at huawei.com  Mon Feb 19 04:15:50 2024
From: lihuisong at huawei.com (lihuisong (C))
Date: Mon, 19 Feb 2024 20:15:50 +0800
Subject: [PATCH] cpufreq: CPPC: Resolve the large frequency discrepancy
 from cpuinfo_cur_freq
In-Reply-To: <ZcYEjMO7IhSaLAAF@e129154.nice.arm.com>
References: <ZZWfJOsDlEXWYHA5@arm.com>
 <9428a1ed-ba4d-1fe6-63e8-11e152bf1f09@huawei.com>
 <lnocwcitdbmgcyhd2dlczgdlhtfw4pfot2br2i3hqscnvr3xgq@nuxlauxum3nr>
 <d0f47e9d-6a58-8b46-89be-b3182abb69f0@huawei.com> <ZZwAmqp6hcmMF8aN@arm.com>
 <6505bdcb-5a5f-cba6-483b-75c51414a9c6@huawei.com>
 <ZaaOQzCpBjmW71xf@e129154.nice.arm.com>
 <a84a9749-97a5-a207-dfd3-8322a5a992d9@huawei.com>
 <Zbyi40XtqbqXm0CL@e129154.nice.arm.com>
 <4f66c62e-b089-a125-5a8d-4a98d4181618@huawei.com>
 <ZcYEjMO7IhSaLAAF@e129154.nice.arm.com>
Message-ID: <532d8a81-a42e-f818-332f-2d93acac1e26@huawei.com>


? 2024/2/9 18:55, Beata Michalska ??:
> On Tue, Feb 06, 2024 at 04:02:15PM +0800, lihuisong (C) wrote:
>> ? 2024/2/2 16:08, Beata Michalska ??:
>>> On Wed, Jan 17, 2024 at 05:18:40PM +0800, lihuisong (C) wrote:
>>>
>>> Hi ,
>>>
>>> Again, apologies for delay,
>>>
>>>> Hi,
>>>>
>>>> ? 2024/1/16 22:10, Beata Michalska ??:
>>>>> Hi,
>>>>>
>>>>> Apologies for jumping in so late....
>>>>>
>>>>> On Wed, Jan 10, 2024 at 03:09:48PM +0800, lihuisong (C) wrote:
>>>>>> Hi Ionela,
>>>>>>
>>>>>> ? 2024/1/8 22:03, Ionela Voinescu ??:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On Friday 05 Jan 2024 at 15:04:47 (+0800), lihuisong (C) wrote:
>>>>>>>> Hi Vanshi,
>>>>>>>>
>>>>>>>> ? 2024/1/5 8:48, Vanshidhar Konda ??:
>>>>>>>>> On Thu, Jan 04, 2024 at 05:36:51PM +0800, lihuisong (C) wrote:
>>>>>>>>>> ? 2024/1/4 1:53, Ionela Voinescu ??:
>>>>>>>>>>> Hi,
>>>>>>>>>>>
>>>>>>>>>>> On Tuesday 12 Dec 2023 at 15:26:17 (+0800), Huisong Li wrote:
>>>>>>>>>>>> Many developers found that the cpu current frequency is greater than
>>>>>>>>>>>> the maximum frequency of the platform, please see [1], [2] and [3].
>>>>>>>>>>>>
>>>>>>>>>>>> In the scenarios with high memory access pressure, the patch [1] has
>>>>>>>>>>>> proved the significant latency of cpc_read() which is used to obtain
>>>>>>>>>>>> delivered and reference performance counter cause an absurd frequency.
>>>>>>>>>>>> The sampling interval for this counters is very critical and
>>>>>>>>>>>> is expected
>>>>>>>>>>>> to be equal. However, the different latency of cpc_read() has a direct
>>>>>>>>>>>> impact on their sampling interval.
>>>>>>>>>>>>
>>>>>>>>>>> Would this [1] alternative solution work for you?
>>>>>>>>>> It would work for me AFAICS.
>>>>>>>>>> Because the "arch_freq_scale" is also from AMU core and constant
>>>>>>>>>> counter, and read together.
>>>>>>>>>> But, from their discuss line, it seems that there are some tricky
>>>>>>>>>> points to clarify or consider.
>>>>>>>>> I think the changes in [1] would work better when CPUs may be idle. With
>>>>>>>>> this
>>>>>>>>> patch we would have to wake any core that is in idle state to read the
>>>>>>>>> AMU
>>>>>>>>> counters. Worst case, if core 0 is trying to read the CPU frequency of
>>>>>>>>> all
>>>>>>>>> cores, it may need to wake up all the other cores to read the AMU
>>>>>>>>> counters.
>>>>>>>>     From the approach in [1], if all CPUs (one or more cores) under one policy
>>>>>>>> are idle, they still cannot be obtained the CPU frequency, right?
>>>>>>>> In this case, the [1] API will return 0 and have to back to call
>>>>>>>> cpufreq_driver->get() for cpuinfo_cur_freq.
>>>>>>>> Then we still need to face the issue this patch mentioned.
>>>>>>> With the implementation at [1], arch_freq_get_on_cpu() will not return 0
>>>>>>> for idle CPUs and the get() callback will not be called to wake up the
>>>>>>> CPUs.
>>>>>> Right, arch_freq_get_on_cpu() will not return 0 for idle CPUs.
>>>>>> However, for no-housekeeping CPUs, it will return 0 and have to call get()
>>>>>> callback, right?
>>>>>>> Worst case, arch_freq_get_on_cpu() will return a frequency based on the
>>>>>>> AMU counter values obtained on the last tick on that CPU. But if that CPU
>>>>>>> is not a housekeeping CPU, a housekeeping CPU in the same policy will be
>>>>>>> selected, as it would have had a more recent tick, and therefore a more
>>>>>>> recent frequency value for the domain.
>>>>>> But this frequency is from the last tick,
>>>>>> this last tick is probably a long time ago and it doesn't update
>>>>>> 'arch_freq_scale' for some reasons like CPU dile.
>>>>>> In addition, I'm not sure if there is possible that amu_scale_freq_tick() is
>>>>>> executed delayed under high stress case.
>>>>>> It also have an impact on the accuracy of the cpu frequency we query.
>>>>>>> I understand that the frequency returned here will not be up to date,
>>>>>>> but there's no proper frequency feedback for an idle CPU. If one only
>>>>>>> wakes up a CPU to sample counters, before the CPU goes back to sleep,
>>>>>>> the obtained frequency feedback is meaningless.
>>>>>>>
>>>>>>>>> For systems with 128 cores or more, this could be very expensive and
>>>>>>>>> happen
>>>>>>>>> very frequently.
>>>>>>>>>
>>>>>>>>> AFAICS, the approach in [1] would avoid this cost.
>>>>>>>> But the CPU frequency is just an average value for the last tick period
>>>>>>>> instead of the current one the CPU actually runs at.
>>>>>>>> In addition, there are some conditions to use 'arch_freq_scale' in this
>>>>>>>> approach.
>>>>>>> What are the conditions you are referring to?
>>>>>> It depends on the housekeeping CPUs.
>>>>>>>> So I'm not sure if this approach can entirely cover the frequency
>>>>>>>> discrepancy issue.
>>>>>>> Unfortunately there is no perfect frequency feedback. By the time you
>>>>>>> observe/use the value of scaling_cur_freq/cpuinfo_cur_freq, the frequency
>>>>>>> of the CPU might have already changed. Therefore, an average value might
>>>>>>> be a better indication of the recent performance level of a CPU.
>>>>>> An average value for CPU frequency is ok. It may be better if it has not any
>>>>>> delaying.
>>>>>>
>>>>>> The original implementation for cpuinfo_cur_freq can more reflect their
>>>>>> meaning in the user-guide [1]. The user-guide said:
>>>>>> "cpuinfo_cur_freq : Current frequency of the CPU as obtained from the
>>>>>> hardware, in KHz.
>>>>>> This is the frequency the CPU actually runs at."
>>>>>>
>>>>>>
>>>>>> [1]https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt
>>>>>>
>>>>>>> Would you be able to test [1] on your platform and usecase?
>>>>>> I has tested it on my platform (CPU number: 64, SMT: off and CPU base
>>>>>> frequency: 2.7GHz).
>>>>>> Accoding to the testing result,
>>>>>> 1> I found that patch [1] and [2] cannot cover the no housekeeping CPUs.
>>>>>> They still have to face the large frequency discrepancy issue my patch
>>>>>> mentioned.
>>>>>> 2> Additionally, the frequency value of all CPUs are almost the same by
>>>>>> using the 'arch_freq_scale' factor way. I'm not sure if it is ok.
>>>>>>
>>>>>> The patch [1] has been modified silightly as below:
>>>>>> -->
>>>>>> @@ -1756,7 +1756,10 @@ static unsigned int
>>>>>> cpufreq_verify_current_freq(struct cpufreq_policy *policy, b
>>>>>>    ?{
>>>>>>    ??????? unsigned int new_freq;
>>>>>>
>>>>>> -?????? new_freq = cpufreq_driver->get(policy->cpu);
>>>>>> +?????? new_freq = arch_freq_get_on_cpu(policy->cpu);
>>>>>> +?????? if (!new_freq)
>>>>>> +?????????????? new_freq = cpufreq_driver->get(policy->cpu);
>>>>>> +
>>>>> As pointed out this change will not make it to the next version of the patch.
>>>>> So I'd say you can safely ignore it and assume that arch_freq_get_on_cpu will
>>>>> only be wired for sysfs nodes for scaling_cur_freq/cpuinfo_cur_freq
>>>>>>    ??????? if (!new_freq)
>>>>>>    ??????????????? return 0;
>>>>>>
>>>>>> And the result is as follows:
>>>>>> *case 1:**No setting the nohz_full and cpufreq use performance governor*
>>>>>> *--> Step1: *read 'cpuinfo_cur_freq' in no pressure
>>>>>>    ? 0: 2699264???? 2: 2699264???? 4: 2699264???? 6: 2699264
>>>>>>    ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2699264
>>>>>>    ?16: 2699264??? 18: 2696628??? 20: 2699264??? 22: 2696628
>>>>>>    ?24: 2699264??? 26: 2696628??? 28: 2699264??? 30: 2696628
>>>>>>    ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
>>>>>>    ?40: 2699264??? 42: 2699264??? 44: 2696628??? 46: 2696628
>>>>>>    ?48: 2696628??? 50: 2699264??? 52: 2699264??? 54: 2696628
>>>>>>    ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
>>>>>>    ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2696628
>>>>>>    ?72: 2699264??? 74: 2696628??? 76: 2696628??? 78: 2699264
>>>>>>    ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
>>>>>>    ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2699264
>>>>>>    ?96: 2696628??? 98: 2699264?? 100: 2699264?? 102: 2696628
>>>>>> 104: 2699264?? 106: 2699264?? 108: 2699264?? 110: 2696628
>>>>>> 112: 2699264?? 114: 2699264?? 116: 2699264?? 118: 2699264
>>>>>> 120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2699264
>>>>>> Note: the frequency of all CPUs are almost the same.
>>>>> Were you expecting smth else ?
>>>> The frequency of each CPU might have a different value.
>>>> All value of all CPUs is the same under high pressure.
>>>> I don't know what the phenomenon is on other platform.
>>>> Do you know who else tested it?
>>> So I might have rushed a bit with my previous comment/question: apologies for
>>> that.
>>> The numbers above: those are on a fairly idle/lightly loaded system right?
>> Yes.
>>> Would you mind having another go with just the arch_freq_get_on_cpu
>>> implementation beign added and dropping the changes in the cpufreq and
>> All my tests are done when cpufreq policy is "performance" and OS isn't on a
>> high load.
>> Reading "scaling_cur_freq" or "scaling_cur_freq" for each physical core on
>> platform
>>
>> The testing result for "cpuinfo_cur_freq" with your changes on a fairly idle
>> and high loaded system can also be found in this thread.
>> *A: the result with your changes*
>> --> Reading "scaling_cur_freq"
>>  ? 0: 2688720???? 2: 2696628???? 4: 2699264???? 6: 2696628
>>  ? 8: 2699264??? 10: 2696628??? 12: 2699264??? 14: 2699264
>>  ?16: 2699264??? 18: 2696628??? 20: 2696628??? 22: 2696628
>>  ?24: 2699264??? 26: 2696628??? 28: 2696628??? 30: 2696628
>>  ?32: 2699264??? 34: 2691356??? 36: 2696628??? 38: 2699264
>>  ?40: 2699264??? 42: 2696628??? 44: 2696628??? 46: 2699264
>>  ?48: 2699264??? 50: 2696628??? 52: 2696628??? 54: 2696628
>>  ?56: 2696628??? 58: 2699264??? 60: 2691356??? 62: 2696628
>>  ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
>>  ?72: 2696628??? 74: 2696628??? 76: 2699264??? 78: 2696628
>>  ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
>>  ?88: 2625456??? 90: 2696628??? 92: 2699264??? 94: 2696628
>>  ?96: 2696628??? 98: 2696628?? 100: 2699264?? 102: 2699264
>> 104: 2699264?? 106: 2696628?? 108: 2699264?? 110: 2696628
>> 112: 2699264?? 114: 2699264?? 116: 2696628?? 118: 2696628
>> 120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2696628
>> -->Reading? "cpuinfo_cur_freq"
>>  ? 0: 2696628???? 2: 2696628???? 4: 2699264???? 6: 2688720
>>  ? 8: 2699264??? 10: 2700000??? 12: 2696628??? 14: 2698322
>>  ?16: 2699264??? 18: 2699264??? 20: 2696628??? 22: 2699264
>>  ?24: 2699264??? 26: 2699264??? 28: 2699264??? 30: 2699264
>>  ?32: 2699264??? 34: 2693992??? 36: 2696628??? 38: 2696628
>>  ?40: 2699264??? 42: 2699264??? 44: 2699264??? 46: 2696628
>>  ?48: 2696628??? 50: 2699264??? 52: 2696628??? 54: 2696628
>>  ?56: 2699264??? 58: 2699264??? 60: 2696628??? 62: 2699264
>>  ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2699264
>>  ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2693992
>>  ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
>>  ?88: 2696628??? 90: 2699264??? 92: 2696628??? 94: 2699264
>>  ?96: 2699264??? 98: 2696628?? 100: 2699264?? 102: 2699264
>> 104: 2691356?? 106: 2699264?? 108: 2699264?? 110: 2699264
>> 112: 2699264?? 114: 2696628?? 116: 2699264?? 118: 2699264
>> 120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628
>>
>> *B: the result without your changes*
>> -->Reading "scaling_cur_freq"
>>  ? 0: 2698245???? 2: 2706690???? 4: 2699649???? 6: 2702105
>>  ? 8: 2704362??? 10: 2697993??? 12: 2701672??? 14: 2704362
>>  ?16: 2701052??? 18: 2701052??? 20: 2694385??? 22: 2699650
>>  ?24: 2706802??? 26: 2702389??? 28: 2698299??? 30: 2698299
>>  ?32: 2697333??? 34: 2697993??? 36: 2701337??? 38: 2699328
>>  ?40: 2700330??? 42: 2700330??? 44: 2698019??? 46: 2697697
>>  ?48: 2699659??? 50: 2701700??? 52: 2703401??? 54: 2701700
>>  ?56: 2704013??? 58: 2697658??? 60: 2695000??? 62: 2697666
>>  ?64: 2697902??? 66: 2701052??? 68: 2698245??? 70: 2695789
>>  ?72: 2701315??? 74: 2696655??? 76: 2693666??? 78: 2695317
>>  ?80: 2704912??? 82: 2699649??? 84: 2698245??? 86: 2695454
>>  ?88: 2697966??? 90: 2697959??? 92: 2699319??? 94: 2700680
>>  ?96: 2695317??? 98: 2698996?? 100: 2700000?? 102: 2700334
>> 104: 2701320?? 106: 2695065?? 108: 2700986?? 110: 2703960
>> 112: 2697635?? 114: 2704421?? 116: 2700680?? 118: 2702040
>> 120: 2700334?? 122: 2697993?? 124: 2700334?? 126: 2705351
>> -->Reading "cpuinfo_cur_freq"
>>  ? 0: 2696853???? 2: 2695454???? 4: 2699649???? 6: 2706993
>>  ? 8: 2706060??? 10: 2704362??? 12: 2704362??? 14: 2697658
>>  ?16: 2707719??? 18: 2697192??? 20: 2702456??? 22: 2699650
>>  ?24: 2705782??? 26: 2698299??? 28: 2703061??? 30: 2705802
>>  ?32: 2700000??? 34: 2700671??? 36: 2701337??? 38: 2697658
>>  ?40: 2700330??? 42: 2700330??? 44: 2699672??? 46: 2697697
>>  ?48: 2703061??? 50: 2696610??? 52: 2692542??? 54: 2704406
>>  ?56: 2695317??? 58: 2699331??? 60: 2698996??? 62: 2702675
>>  ?64: 2704912??? 66: 2703859??? 68: 2699649??? 70: 2698596
>>  ?72: 2703908??? 74: 2703355??? 76: 2697658??? 78: 2695317
>>  ?80: 2702105??? 82: 2707719??? 84: 2702105??? 86: 2699649
>>  ?88: 2697966??? 90: 2691525??? 92: 2701700??? 94: 2700680
>>  ?96: 2695317??? 98: 2698996?? 100: 2698666?? 102: 2700334
>> 104: 2690429?? 106: 2707590?? 108: 2700986?? 110: 2701320
>> 112: 2696283?? 114: 2692881?? 116: 2697627?? 118: 2704421
>> 120: 2698996?? 122: 2696321?? 124: 2696655?? 126: 2695000
>>
> So in both cases : whether you use arch_freq_get_on_cpu or not
> (so with and without the patch) you get roughly the same frequencies
> on all cores - or am I missing smth from the dump above ?
The changes in "with/without your changes" I said is your patch 
intruduced arch_freq_get_on_cpu.
I just test them according to your requesting.
> And those are reflecting max freq you have provided earlier (?)
I know it is an average frequency for the last tickfor using 
arch_freq_get_on_cpu.
I have no any doubt that the freq is maximum value on performance governor.
I just want to say the difference between having or not having your patch.
The frequency values of all cores from cpuinfo_cur_freq and
scaling_cur_freq are almost the same if use this arch_freq_get_on_cpu on 
my platform.
However, the frequency values of all cores are different if doesn't use 
this arch_freq_get_on_cpu and just use .get().
> Note that the arch_freq_get_on_cpu will return an average frequency for
> the last tick, so even if your system is roughly idle with your performance
> governor those numbers make sense (some/most of the cores might be idle
> but you will see the last freq the core was running at before going to idle).
> I do not think there is an agreement what should be shown for idle core when
> querying their freq through sysfs. Showing last known freq makes sense, even
> more than waking up core just to try to get one.
I'm not opposed to using frequency scale factor to get CPU frequency. 
But it better be okay.
>
> @Ionela: Please jump in if I got things wrong.
>
>>> then read 'scaling_cur_freq', doing several reads in some intervals ?
>> It seems that above phenomenon has not a lot to do with reading intervals.
>>> The change has been tested on RD-N2 model (Neoverse N2 ref platform),
>>> it has also been discussed here [1]
>> I doesn't get the testing result on this platform in its thread.
> It might be missing exact numbers but the conclusions should be here [1]
>
>>>>>> *--> Step 2: *read 'cpuinfo_cur_freq' in the high memory access pressure.
>>>>>>    ? 0: 2696628???? 2: 2696628???? 4: 2696628???? 6: 2696628
>>>>>>    ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2696628
>>>>>>    ?16: 2696628??? 18: 2696628??? 20: 2696628??? 22: 2696628
>>>>>>    ?24: 2696628??? 26: 2696628??? 28: 2696628??? 30: 2696628
>>>>>>    ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
>>>>>>    ?40: 2696628??? 42: 2696628??? 44: 2696628??? 46: 2696628
>>>>>>    ?48: 2696628??? 50: 2696628??? 52: 2696628??? 54: 2696628
>>>>>>    ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
>>>>>>    ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
>>>>>>    ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2696628
>>>>>>    ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
>>>>>>    ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2696628
>>>>>>    ?96: 2696628??? 98: 2696628?? 100: 2696628?? 102: 2696628
>>>>>> 104: 2696628?? 106: 2696628?? 108: 2696628?? 110: 2696628
>>>>>> 112: 2696628?? 114: 2696628?? 116: 2696628?? 118: 2696628
>>>>>> 120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628
>>>>>>
>>>>>> *Case 2: setting nohz_full and cpufreq use ondemand governor*
>>>>>> There is "isolcpus=1-10,41-50 nohz_full=1-10,41-50 rcu_nocbs=1-10,41-50" in
>>>>>> /proc/cmdline.
>>>>> Right, so if I remember correctly nohz_full implies rcu_nocbs, so no need to
>>>>> set that one.
>>>>> Now, afair, isolcpus will make the selected CPUs to disappear from the
>>>>> schedulers view (no balancing, no migrating), so unless you affine smth
>>>>> explicitly to those CPUs, you will not see much of an activity there.
>>>> Correct.
>>>>> Need to double check though as it has been a while ...
>>>>>> *--> Step 1: *setting ondemand governor to all policy and query
>>>>>> 'cpuinfo_cur_freq' in no pressure case.
>>>>>> And the frequency of CPUs all are about 400MHz.
>>>>>> *--> Step 2:* read 'cpuinfo_cur_freq' in the high memory access pressure.
>>>>>> The high memory access pressure is from the command: "stress-ng -c 64
>>>>>> --cpu-load 100% --taskset 0-63"
>>>>> I'm not entirely convinced that this will affine to isolated cpus, especially
>>>>> that the affinity mask spans all available cpus. If that is the case, no wonder
>>>>> your isolated cpus are getting wasted being idle. But I would have to double
>>>>> check how this is being handled.
>>>>>> The result:
>>>>>>    ?0: 2696628???? 1:? 400000???? 2:? 400000???? 3:? 400909
>>>>>>    ?4:? 400000???? 5:? 400000???? 6:? 400000???? 7:? 400000
>>>>>>    ?8:? 400000???? 9:? 400000??? 10:? 400600??? 11: 2696628
>>>>>> 12: 2696628??? 13: 2696628??? 14: 2696628??? 15: 2696628
>>>>>> 16: 2696628??? 17: 2696628??? 18: 2696628??? 19: 2696628
>>>>>> 20: 2696628??? 21: 2696628??? 22: 2696628??? 23: 2696628
>>>>>> 24: 2696628??? 25: 2696628??? 26: 2696628??? 27: 2696628
>>>>>> 28: 2696628??? 29: 2696628??? 30: 2696628??? 31: 2696628
>>>>>> 32: 2696628??? 33: 2696628??? 34: 2696628??? 35: 2696628
>>>>>> 36: 2696628??? 37: 2696628??? 38: 2696628??? 39: 2696628
>>>>>> 40: 2696628??? 41:? 400000??? 42:? 400000??? 43:? 400000
>>>>>> 44:? 400000??? 45:? 398847??? 46:? 400000??? 47:? 400000
>>>>>> 48:? 400000??? 49:? 400000??? 50:? 400000??? 51: 2696628
>>>>>> 52: 2696628??? 53: 2696628??? 54: 2696628??? 55: 2696628
>>>>>> 56: 2696628??? 57: 2696628??? 58: 2696628??? 59: 2696628
>>>>>> 60: 2696628??? 61: 2696628??? 62: 2696628??? 63: 2699264
>>>>>>
>>>>>> Note:
>>>>>> (1) The frequency of 1-10 and 41-50 CPUs work on the lowest frequency.
>>>>>>    ???? It turned out that nohz full was already work.
>>>>>>    ???? I guess that stress-ng cannot use the CPU in the range of nohz full.
>>>>>>    ???? Because the CPU frequency will be increased to 2.7G by binding CPU to
>>>>>> other application.
>>>>>> (2) The frequency of the nohz full core is calculated by get() callback
>>>>>> according to ftrace.
>>>>> It is as there is no sched tick on those, and apparently there is nothing
>>>>> running on them either.
>>>> Yes.
>>>> If we select your approach and the above phenomenon is normal,
>>>> the large frequency discrepancy issue can be resolved for CPUs with sched
>>>> tick by the way.
>>>> But the nohz full cores still have to face this issue. So this patch is also
>>>> needed.
>>>>
>>> Yes, nohz cores full have to be handled by the cpufreq driver.
>> Correct. So we still have to face the issue in this patch and push this
>> patch.
>> Beata, would you please review this patch?
> Just to clarify for my benefit (apologies but I do have to contex switch
> pretty often these days): by reviewing this patch do you mean:
> 1) review your changes (if so I think there are few comments already to be
> addressed, but I can try to have another look)
Currently, the main comments is that my patch will wake up CPU to get 
frequency.
BTW, the core's always been wakened up to get the frequency for FFH way 
in cppc_acpi. please see cpc_read_ffh().
So it may be acceptable. After all, we don't query CPU frequency very often.
But your patch doesn't meet the non-housekeeping cpus.
> 2) review changes for AMU-based arch_freq_get_on_cpu ?
>
> *note: I will still try to have a look at the non-housekeeping cpus case
I am very much hope that this issue my patch mentioned can be resolved ASAP.
So what's your plan about non-housekeeping cpus case?
>
> ---
> [1] https://lore.kernel.org/lkml/691d3eb2-cd93-f0fc-a7a4-2a8c0d44262c at nvidia.com/
> ---
>
> BR
> Beata
>>
>> /Huisong
> [...]
> .


From brgl at bgdev.pl  Mon Feb 19 04:23:12 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 13:23:12 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org> <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org> <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
Message-ID: <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>

On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>

[snip]

> > >>>>
> > >>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> > >>>> necessary. The BT and WLAN devices on the device-tree are represented as
> > >>>> consuming the inputs (relevant to the functionality of each) of the PMU
> > >>>> directly.
> > >>>
> > >>> We are describing the hardware. From the hardware point of view, there
> > >>> is a PMU. I think at some point we would really like to describe all
> > >>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> > >>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
> > >>
> > >> While I agree with older WiFi+BT units, I don't think it's needed for
> > >> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
> > >> transparent.
> > >
> > > I don't see any significant difference between WCN6750/WCN6855 and
> > > WCN7850 from the PMU / power up point of view. Could you please point
> > > me to the difference?
> > >
> >
> > The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
> > and BT_EN ordering and the only requirement is to have all input regulators
> > up before pulling up WLAN_EN and/or BT_EN.
> >
> > This makes the PMU transparent and BT and WLAN can be described as independent.
>
> From the hardware perspective, there is a PMU. It has several LDOs. So
> the device tree should have the same style as the previous
> generations.
>

My thinking was this: yes, there is a PMU but describing it has no
benefit (unlike QCA6x90). If we do describe, then we'll end up having
to use pwrseq here despite it not being needed because now we won't be
able to just get regulators from WLAN/BT drivers directly.

So I also vote for keeping it this way. Let's go into the package
detail only if it's required.

Bartosz


From angelogioacchino.delregno at collabora.com  Mon Feb 19 04:28:49 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 13:28:49 +0100
Subject: [PATCH] clk: mediatek: mt8183: Correct parent of
 CLK_INFRA_SSPM_32K_SELF
In-Reply-To: <20240219105125.956278-1-wenst@chromium.org>
References: <20240219105125.956278-1-wenst@chromium.org>
Message-ID: <adf70c16-f1dc-4f01-a331-b0cd975a4c42@collabora.com>

Il 19/02/24 11:51, Chen-Yu Tsai ha scritto:
> CLK_INFRA_SSPM_32K_SELF has the "f_f26m_ck" clock assigned as its parent.
> This is inconsistent as the clock is part of a group that are all gates
> without dividers, and this makes the kernel think it runs at 26 MHz.
> 
> After clarification from MediaTek engineers, the correct parent is
> actually the system 32 KHz clock.
> 
> Fixes: 1eb8d61ac5c9 ("clk: mediatek: mt8183: Add back SSPM related clocks")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From dan.carpenter at linaro.org  Mon Feb 19 04:31:56 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Mon, 19 Feb 2024 15:31:56 +0300
Subject: [PATCH v3 0/2] Staging: vc04_services: bcm2835-camera: Fix code
 style checks
In-Reply-To: <20240219112234.8673-1-mo.c.weber@gmail.com>
References: <236d985c-1835-410f-b0b5-cacbd5fbf930@moroto.mountain>
 <20240219112234.8673-1-mo.c.weber@gmail.com>
Message-ID: <4295c4b8-bcee-4a7f-8960-80b6d3934530@moroto.mountain>

On Mon, Feb 19, 2024 at 12:22:32PM +0100, Moritz C. Weber wrote:
> Resubmit these patches to address comments to rebase the 8 v2 changes into
> 2 patches topicwise
> Fix patches with same subject issue based on v2, which fixes multiple code
> style checks for better readability, consistency, and fixes typos from v1
> 
> Moritz C. Weber (2):
>   Staging: vc04_services: bcm2835-camera: fix blank line style check
>   Staging: vc04_services: bcm2835-camera: fix brace code style check
> 

Looks okay now.

Reviewed-by: Dan Carpenter <dan.carpenter at linaro.org>

regards,
dan carpenter



From angelogioacchino.delregno at collabora.com  Mon Feb 19 04:33:26 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 13:33:26 +0100
Subject: [PATCH] clk: mediatek: mt7981-topckgen: flag SGM_REG_SEL as
 critical
In-Reply-To: <fc157139e6b7f8dfb6430ac7191ba754027705e8.1708221995.git.daniel@makrotopia.org>
References: <fc157139e6b7f8dfb6430ac7191ba754027705e8.1708221995.git.daniel@makrotopia.org>
Message-ID: <94919703-18b5-477c-8dc4-9a359129284d@collabora.com>

Il 18/02/24 04:11, Daniel Golle ha scritto:
> Without the SGM_REG_SEL clock enabled the cpu freezes if trying to
> access registers used by MT7981 clock drivers itself.
> Mark SGM_REG_SEL as critical to make sure it is always enabled to
> prevent freezes on boot even if the Ethernet driver which prepares
> and enables the clock is not loaded or probed at a later point.
> 
> Fixes: 813c3b53b55b ("clk: mediatek: add MT7981 clock support")
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From dmitry.baryshkov at linaro.org  Mon Feb 19 04:33:46 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 14:33:46 +0200
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org> <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org> <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
 <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
Message-ID: <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com>

On Mon, 19 Feb 2024 at 14:23, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
> <dmitry.baryshkov at linaro.org> wrote:
> >
>
> [snip]
>
> > > >>>>
> > > >>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> > > >>>> necessary. The BT and WLAN devices on the device-tree are represented as
> > > >>>> consuming the inputs (relevant to the functionality of each) of the PMU
> > > >>>> directly.
> > > >>>
> > > >>> We are describing the hardware. From the hardware point of view, there
> > > >>> is a PMU. I think at some point we would really like to describe all
> > > >>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> > > >>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
> > > >>
> > > >> While I agree with older WiFi+BT units, I don't think it's needed for
> > > >> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
> > > >> transparent.
> > > >
> > > > I don't see any significant difference between WCN6750/WCN6855 and
> > > > WCN7850 from the PMU / power up point of view. Could you please point
> > > > me to the difference?
> > > >
> > >
> > > The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
> > > and BT_EN ordering and the only requirement is to have all input regulators
> > > up before pulling up WLAN_EN and/or BT_EN.
> > >
> > > This makes the PMU transparent and BT and WLAN can be described as independent.
> >
> > From the hardware perspective, there is a PMU. It has several LDOs. So
> > the device tree should have the same style as the previous
> > generations.
> >
>
> My thinking was this: yes, there is a PMU but describing it has no
> benefit (unlike QCA6x90). If we do describe, then we'll end up having
> to use pwrseq here despite it not being needed because now we won't be
> able to just get regulators from WLAN/BT drivers directly.
>
> So I also vote for keeping it this way. Let's go into the package
> detail only if it's required.

The WiFi / BT parts are not powered up by the board regulators. They
are powered up by the PSU. So we are not describing it in the accurate
way.

Moreover, I think we definitely want to move BT driver to use only the
pwrseq power up method. Doing it in the other way results in the code
duplication and possible issues because of the regulator / pwrseq
taking different code paths.


-- 
With best wishes
Dmitry


From angelogioacchino.delregno at collabora.com  Mon Feb 19 04:36:14 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 13:36:14 +0100
Subject: [PATCH v3] arm64: dts: mt8195-cherry-tomato: change watchdog reset boot flow
In-Reply-To: <20240124-send-upstream-v3-1-5097c9862a73@chromium.org>
References: <20240124-send-upstream-v3-1-5097c9862a73@chromium.org>
Message-ID: <170834614185.140678.1878504560854372421.b4-ty@collabora.com>

On Wed, 24 Jan 2024 07:51:57 +0000, Hsin-Te Yuan wrote:
> The external output reset signal was originally disabled and sent from
> firmware. However, an unfixed bug in the firmware on tomato prevents
> the signal from being sent, causing the device to fail to boot. To fix
> this, enable external output reset signal to allow the device to reboot
> normally.
> 
> 
> [...]

Applied to v6.8-next/dts64, thanks!

[1/1] arm64: dts: mt8195-cherry-tomato: change watchdog reset boot flow
      https://git.kernel.org/mediatek/c/ef569d5d

Cheers,
Angelo



From brgl at bgdev.pl  Mon Feb 19 04:53:57 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 13:53:57 +0100
Subject: [PATCH v5 03/18] dt-bindings: regulator: describe the PMU module
 of the QCA6390 package
In-Reply-To: <7c1327c0-d0ea-4797-a5fa-5844ba46bf53@linaro.org>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-4-brgl@bgdev.pl>
 <ZdDVNbjv60G9YUNy@finisterre.sirena.org.uk> <CAMRc=Mf9Sro4kM_Jn8_v=cyO5PxCp6AnBdeS9XspqVDGKdA_Dg@mail.gmail.com>
 <7c1327c0-d0ea-4797-a5fa-5844ba46bf53@linaro.org>
Message-ID: <CAMRc=Me=3HhGc_yZuaEo1TsLbF2R=g+072185_PAh5GmAQ-M7w@mail.gmail.com>

On Mon, Feb 19, 2024 at 8:32?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 17/02/2024 19:32, Bartosz Golaszewski wrote:
> > On Sat, Feb 17, 2024 at 4:48?PM Mark Brown <broonie at kernel.org> wrote:
> >>
> >> On Fri, Feb 16, 2024 at 09:32:00PM +0100, Bartosz Golaszewski wrote:
> >>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >>>
> >>> The QCA6390 package contains discreet modules for WLAN and Bluetooth. They
> >>> are powered by the Power Management Unit (PMU) that takes inputs from the
> >>> host and provides LDO outputs. This document describes this module.
> >>
> >> 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.
> >
> > Mark,
> >
> > This is quite vague, could you elaborate? I have no idea what is wrong
> > with this patch.
>
> Use subject prefixes matching the subsystem. You can get them for
> example with `git log --oneline -- DIRECTORY_OR_FILE` on the directory
> your patch is touching.
>
> Best regards,
> Krzysztof
>

Yes, I always do. And for Documentation/devicetree/bindings/regulator/
the subjects are split 50:50 between "dt-bindings: regulator: ..." and
"regulator: dt-bindings: ...". For Documentation/devicetree/bindings/
it's overwhelmingly "dt-bindings: <subsystem>: ...". It's the first
time someone wants me to send a DT bindings patch without
"dt-bindings" coming first in the subject.

I mean: I can do it alright but it's not stated anywhere explicitly.

Bartosz


From krzysztof.kozlowski at linaro.org  Mon Feb 19 04:54:53 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 13:54:53 +0100
Subject: [PATCH] MAINTAINERS: samsung: gs101: match patches touching Google Tensor SoC
Message-ID: <20240219125453.103692-1-krzysztof.kozlowski@linaro.org>

Maintainers of Google Tensor SoC should be aware of all driver patches
having that name.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

---

This allows to spot easier such weird drivers (weird because they claim they are
for hardware, but they omit entirely hardware part) like:
https://lore.kernel.org/all/20240219061008.1761102-3-pumahsu at google.com/
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 36fac6b3499a..69fb1ae94897 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9126,6 +9126,7 @@ F:	Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
 F:	arch/arm64/boot/dts/exynos/google/
 F:	drivers/clk/samsung/clk-gs101.c
 F:	include/dt-bindings/clock/google,gs101.h
+K:	[gG]oogle.?[tT]ensor
 
 GPD POCKET FAN DRIVER
 M:	Hans de Goede <hdegoede at redhat.com>
-- 
2.34.1



From skseofh at gmail.com  Mon Feb 19 05:07:18 2024
From: skseofh at gmail.com (skseofh at gmail.com)
Date: Mon, 19 Feb 2024 22:07:18 +0900
Subject: [PATCH] arm64: remove duplicated early fixmap init
Message-ID: <20240219130718.2491496-1-skseofh@gmail.com>

From: Daero Lee <skseofh at gmail.com>

We call early_fixmap_init() in two place.
- early_fdt_init()
- setup_arch()

Because early_fdt_init() is called before going to setup_arch(),
early_fixmap_init() can be deleted from setup_arch()

Signed-off-by: Daero Lee <skseofh at gmail.com>
---
 arch/arm64/kernel/setup.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 42c690bb2d60..ce45f4a9ac4a 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -305,7 +305,6 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 	 */
 	arm64_use_ng_mappings = kaslr_requires_kpti();
 
-	early_fixmap_init();
 	early_ioremap_init();
 
 	setup_machine_fdt(__fdt_pointer);
-- 
2.25.1



From mwalle at kernel.org  Mon Feb 19 05:09:49 2024
From: mwalle at kernel.org (Michael Walle)
Date: Mon, 19 Feb 2024 14:09:49 +0100
Subject: [PATCH v2 2/2] arm64: dts: mediatek: add Kontron 3.5"-SBC-i1200
In-Reply-To: <2ad6bda8-a457-421b-b35d-dc005fb00ae9@collabora.com>
References: <20240219084456.1075445-1-mwalle@kernel.org>
 <20240219084456.1075445-2-mwalle@kernel.org>
 <2ad6bda8-a457-421b-b35d-dc005fb00ae9@collabora.com>
Message-ID: <CZ92W3VSYV1A.1693O76GY1XDP@kernel.org>

Hi,

thanks for the extensive review!

On Mon Feb 19, 2024 at 11:00 AM CET, AngeloGioacchino Del Regno wrote:

> > +&eth {
> > +	phy-mode ="rgmii-id";
> > +	phy-handle = <&ethernet_phy0>;
> > +	snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>;
> > +	snps,reset-delays-us = <0 10000 80000>;
>
> snps,reset-delays-us and snps,reset-gpio are deprecated.
>
> > +	pinctrl-names = "default", "sleep";
> > +	pinctrl-0 = <&eth_default_pins>;
> > +	pinctrl-1 = <&eth_sleep_pins>;
> > +	status = "okay";
> > +
> > +	mdio {
> > +		ethernet_phy0: ethernet-phy at 1 {
>
> compatible = "is there any applicable compatible?"
> P.S.: if you've got the usual rtl8211f, should be "ethernet-phy-id001c.c916"

I'd rather not have a compatible here. First, it's auto discoverable
and IIRC it's frowned upon adding any compatible if you ask the PHY
maintainers. And second, if we change the PHY (maybe due to a second
chip shortage or whatever), there is a chance you don't have to
update this in the DT.

> reg = <0x1>;
> interrupts-extended = <&pio 94 IRQ_TYPE_LEVEL_LOW>;
> reset-assert-us = <10000>;
> reset-deassert-us = <80000>;
> reset-gpios = <&pio 93 GPIO_ACTIVE_HIGH>;
>
>
> > +			reg = <0x1>;
> > +			interrupts-extended = <&pio 94 IRQ_TYPE_LEVEL_LOW>;
> > +		};
> > +	};
> > +};
> > +
> > +&gpu {
> > +	status = "okay";
> > +	mali-supply = <&mt6315_7_vbuck1>;
> > +};
> > +
> > +&i2c2 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&i2c2_pins>;
> > +	clock-frequency = <400000>;
> > +	status = "okay";
>
> Are i2c2,3,4 exposed as pins somewhere? If they are, can you please put a
> comment saying so?

This is only a basic device tree. On one i2c controller, there is
the LVDS bridge for example. My plan is to get the support for this
bridge upstream first and then adding the appropriate device nodes
here.

That being said, some are exposed to connectors. I'll add a comment
then.

> > +&mmc1 {
> > +	pinctrl-names = "default", "state_uhs";
> > +	pinctrl-0 = <&mmc1_default_pins>;
> > +	pinctrl-1 = <&mmc1_uhs_pins>;
> > +	cd-gpios = <&pio 129 GPIO_ACTIVE_LOW>;
> > +	bus-width = <4>;
> > +	max-frequency = <200000000>;
> > +	cap-sd-highspeed;
> > +	sd-uhs-sdr50;
> > +	sd-uhs-sdr104;
> > +	vmmc-supply = <&mt6360_ldo5>;
> > +	vqmmc-supply = <&mt6360_ldo3>;
>
> Does mmc1 support eMMC and SDIO?

No eMMC, but I'd guess it will support SDIO as in you can just plug
an SDIO card in the SD slot, right? Oh, it's a micro SD socket. So
uhm, I'm not sure if we should restrict it, though. Someone might
come up with a microsd to sd card adapter. I have one right in front
of me ;)

> If not, no-mmc; no-sdio;

So no-mmc;

> > +			drive-strength = <MTK_DRIVE_8mA>;
>
> s/MTK_DRIVE//g
> s/mA//g
>
> drive-strength = <8>;
>
> Please, here and everywhere else, for all values - let's stop using those
> MTK_DRIVE_(x)mA definitions, they're just defined as (x), where anyway
> the drive-strength property is in milliamps by default.
>
> We don't need these definitions.

Sure, the mt8195-demo was the blueprint for this. So maybe you should
get rid of it there to prevent any copying ;) (btw the same goes for
the regulator-compatible property).

Speaking of pinctrl, I find the R0R1 bias-pull-down values really
hard to grasp. The DT binding documentation didn't really help here.
What is R0 and R1, I presume some resistors which can be enabled.
Also are they in parallel or in series. I'd have assumed, the DT
binding should have hid this by giving the user a choice for the
resistance instead. Also I had a quick search in the RM and
couldn't find anything, I probably looked at the wrong place ;)

> > +	uart1_pins: uart1-pins {
> > +		pins_rx {
> > +			pinmux = <PINMUX_GPIO103__FUNC_URXD1>;
> > +			input-enable;
> > +			bias-pull-up;
> > +		};
> > +
> > +		pins_tx {
> > +			pinmux = <PINMUX_GPIO102__FUNC_UTXD1>;
> > +		};
> > +
> > +		pins_rts {
> > +			pinmux = <PINMUX_GPIO100__FUNC_URTS1>;
> > +			output-enable;
>
> Are you really sure that you need output-enable here?!
> RTS is not an output buffer....
>
> I don't think you do. Please double check.

Ahh, good catch, it's a leftover from mt8183-kukui.dts. There is
probably wrong, too.

> > +		};
> > +
> > +		pins_cts {
> > +			pinmux = <PINMUX_GPIO101__FUNC_UCTS1>;
> > +			input-enable;
> > +		};
> > +	};
> > +


> > +/* USB3 front port */
> > +&xhci0 {
>
> It's not gonna work like this. I recently fixed the USB nodes in MT8195 by adding
> MTU3 where necessary...

Uhm, seems like I've missed that.

> Check mt8195.dtsi - only one XHCI controller isn't placed behind MTU3, and that is
> XHCI1 (11290000), while the others are MTU3.
>
> As far as I can see from this DT, it should now instead look like..
>
> &ssusb0 {
> 	dr_mode = "host";
> 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
> 	status = "okay";
> };
>
> &ssusb2 {
> 	dr_mode = "host";
> 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
> 	status = "okay";
> };
>
> &ssusb3 {
> 	dr_mode = "host";
> 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
> 	status = "okay";
> };
>
> &xhci0 {
> 	vbus-supply = <&otg_vbus_regulator>;
> 	status = "okay";
> };
>
> &xhci1 {
> 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
>
> vbus is always supplied by something, as otherwise USB won't work - whether this
> is an always-on regulator or a passthrough from external supply this doesn't really
> matter - you should model a regulator-fixed that provides the 5V VBUS line.

I don't think this is correct, though. Think of an on-board USB
hub. There only D+/D- are connected (and maybe the USB3.2 SerDes
lanes). Or have a look at the M.2 pinout. There is no Vbus.

Also it seems I need the "mediatek,u3p-dis-msk = <0x01>;". At least
the last time I've tested it. I'll test it again, with and without.
The SerDes Line of the corresponding USB3.2 port is used for PCIe in
this case.

> For example:
> 	vbus_fixed: regulator-vbus {
> 		compatible = "regulator-fixed";
> 		regulator-name = "usb-vbus";
> 		regulator-always-on;
> 		regulator-boot-on;
> 		regulator-min-microvolt = <5000000>;
> 		regulator-max-microvolt = <5000000>;
> 	};

As mentioned above, I don't think this will make sense in my case.

> P.S.: If the rail has a different name, please use that different name. Obviously
> that requires you to have schematics at hand, and I don't know if you do: if you
> don't, then that regulator-vbus name is just fine.

I do have the schematics.

Thanks,
-michael
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 252 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240219/d55cb4cf/attachment-0001.sig>

From michal.simek at amd.com  Mon Feb 19 05:11:50 2024
From: michal.simek at amd.com (Michal Simek)
Date: Mon, 19 Feb 2024 14:11:50 +0100
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
In-Reply-To: <ebcfd49d-f810-4d9b-8cba-b55071fc7fa6@linaro.org>
References: <94726c90ff519185767475f672d70311472ea925.1708073513.git.michal.simek@amd.com>
 <5a81f16b-8ece-4263-b424-4dd6cd6e386f@linaro.org>
 <ed59671f-6e0b-45a2-bae7-38f7b4b7e625@amd.com>
 <ebcfd49d-f810-4d9b-8cba-b55071fc7fa6@linaro.org>
Message-ID: <96c0f613-7c53-4189-bfc8-7d572b308b9f@amd.com>



On 2/17/24 09:26, Krzysztof Kozlowski wrote:
> On 16/02/2024 10:42, Michal Simek wrote:
>>
>>
>> On 2/16/24 10:19, Krzysztof Kozlowski wrote:
>>> On 16/02/2024 09:51, Michal Simek wrote:
>>>> RTC has its own power domain on Xilinx Versal SOC that's why describe it as
>>>> optional property.
>>>>
>>>> Signed-off-by: Michal Simek <michal.simek at amd.com>
>>>> ---
>>>>
>>>>    Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml | 3 +++
>>>>    1 file changed, 3 insertions(+)
>>>>
>>>
>>> But Versal is not described in this binding, is it? I see only one
>>> compatible.
>>
>> It is the same IP only as is on zynqmp with own power rail.
> 
> Then you should have separate compatible, because they are not
> identical. It would also allow you to narrow the domains to versal and
> also require it (on versal).

I can double check with HW guys but I am quite sure IP itself is exactly the 
same. What it is different is that there is own power domain to it (not shared 
one as is in zynqmp case).

Also Linux is non secure sw and if secure firmware won't allow to change setting 
of it it can't be required. I am just saying that Linux doesn't need to be owner 
of any power domain that's why it shouldn't be required property.

Thanks,
Michal


From angelogioacchino.delregno at collabora.com  Mon Feb 19 05:12:25 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 14:12:25 +0100
Subject: [GIT,PULL,1/2] MediaTek ARM64 Device Tree updates for v6.9
Message-ID: <20240219131230.157792-1-angelogioacchino.delregno@collabora.com>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux.git tags/mtk-dts64-for-v6.9

for you to fetch changes up to ef569d5db50e7edd709e482157769a5b3c367e22:

  arm64: dts: mt8195-cherry-tomato: change watchdog reset boot flow (2024-02-19 13:35:24 +0100)

----------------------------------------------------------------
MediaTek ARM64 DeviceTree updates for v6.9

This adds support for the following new machines:
 - MT7981B: Xiaomi AX3000T
 - MT7986A: Acelink EW-7886CAX
 - MT7988A: BananaPi BPI-R4
 - MT8186 Chromebooks: Tentacruel, Tentacool, Steelix, Rusty, Magneton
 - MT8395/MT8195: Radxa NIO 12L

Also adds more support for the MediaTek MT8186 SoC's Video and JPEG
encoders and for MT7988 clocks, enables wakeup support for the CrOS
EC on SPI in all MediaTek Chromebooks, performs some cleanups and
includes some spare fixes.

----------------------------------------------------------------
Alexander Stein (1):
      arm64: dts: mediatek: Replace deprecated extcon-usb-gpio id-gpio/vbus-gpio properties

Allen-KH Cheng (1):
      arm64: dts: mediatek: mt8186: Add jpgenc node

AngeloGioacchino Del Regno (3):
      arm64: dts: mediatek: mt8195: Add MTU3 nodes and correctly describe USB
      dt-bindings: arm64: mediatek: Add MT8395 Radxa NIO 12L board compatible
      arm64: dts: mediatek: Introduce the MT8395 Radxa NIO 12L board

Ar?n? ?NAL (2):
      arm64: dts: mt7622: add port at 5 as CPU port
      arm64: dts: mt7986: add port at 5 as CPU port

Chen-Yu Tsai (9):
      dt-bindings: arm: mediatek: Sort entries by SoC then board compatibles
      dt-bindings: arm: mediatek: Add MT8186 Tentacruel / Tentacool Chromebooks
      dt-bindings: arm: mediatek: Add MT8186 Steelix Chromebook
      dt-bindings: arm: mediatek: Add MT8186 Rusty Chromebook
      dt-bindings: arm: mediatek: Add MT8186 Magneton Chromebooks
      arm64: dts: mediatek: Add MT8186 Krabby platform based Tentacruel / Tentacool
      arm64: dts: mediatek: Introduce MT8186 Steelix
      arm64: dts: mediatek: Add MT8186 Steelix platform based Rusty
      arm64: dts: mediatek: Add MT8186 Magneton Chromebooks

Eugen Hristev (5):
      dt-bindings: media: mtk-vcodec-encoder: fix non-vp8 clock name
      arm64: dts: mediatek: mt8192: fix vencoder clock name
      dt-bindings: media: mtk-vcodec-encoder: add compatible for mt8186
      arm64: dts: mediatek: mt8186: fix VENC power domain clocks
      dt-bindings: media: mediatek-jpeg-encoder: change max iommus count

Hsin-Te Yuan (1):
      arm64: dts: mt8195-cherry-tomato: change watchdog reset boot flow

Krzysztof Kozlowski (1):
      arm64: dts: mediatek: replace underscores in node names

Kyrie Wu (1):
      arm64: dts: mediatek: mt8186: Add venc node

Mark Hasemeyer (4):
      arm64: dts: mediatek: mt8173: Enable cros-ec-spi as wake source
      arm64: dts: mediatek: mt8183: Enable cros-ec-spi as wake source
      arm64: dts: mediatek: mt8192: Enable cros-ec-spi as wake source
      arm64: dts: mediatek: mt8195: Enable cros-ec-spi as wake source

N?colas F. R. A. Prado (4):
      arm64: dts: mt8183: Move CrosEC base detection node to kukui-based DTs
      arm64: dts: mediatek: mt8192-asurada: Remove CrosEC base detection node
      arm64: dts: mediatek: mt8186: Add missing clocks to ssusb power domains
      arm64: dts: mediatek: mt8186: Add missing xhci clock to usb controllers

Rafa? Mi?ecki (17):
      arm64: dts: mediatek: mt7986: fix reference to PWM in fan node
      arm64: dts: mediatek: mt7986: drop crypto's unneeded/invalid clock name
      arm64: dts: mediatek: mt7986: fix SPI bus width properties
      arm64: dts: mediatek: mt7986: fix SPI nodename
      arm64: dts: mediatek: mt7986: drop "#clock-cells" from PWM
      arm64: dts: mediatek: mt7986: add "#reset-cells" to infracfg
      dt-bindings: arm64: mediatek: Add MT7981B and Xiaomi AX3000T
      arm64: dts: mediatek: Add initial MT7981B and Xiaomi AX3000T
      dt-bindings: arm64: mediatek: Add MT7988A and BPI-R4
      arm64: dts: mediatek: Add initial MT7988A and BPI-R4
      arm64: dts: mediatek: mt7988: add clock controllers
      dt-bindings: vendor-prefixes: add acelink
      dt-bindings: arm64: dts: mediatek: Add Acelink EW-7886CAX access point
      arm64: dts: mediatek: Add Acelink EW-7886CAX
      arm64: dts: mediatek: mt7986: reorder properties
      arm64: dts: mediatek: mt7986: reorder nodes
      arm64: dts: mediatek: mt7622: add missing "device_type" to memory nodes

William-tw Lin (1):
      arm64: dts: mediatek: Add socinfo efuses to MT8173/83/96/92/95 SoCs

Yunfei Dong (1):
      arm64: dts: mediatek: mt8186: Add video decoder device nodes

 Documentation/devicetree/bindings/arm/mediatek.yaml                  |  198 ++++--
 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml |   31 +-
 Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml   |    3 +-
 Documentation/devicetree/bindings/vendor-prefixes.yaml               |    2 +
 arch/arm64/boot/dts/mediatek/Makefile                                |   14 +
 arch/arm64/boot/dts/mediatek/mt2712-evb.dts                          |    4 +-
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi                            |    2 +-
 arch/arm64/boot/dts/mediatek/mt6797.dtsi                             |    8 +-
 arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts             |   13 +
 arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts                         |   25 +
 arch/arm64/boot/dts/mediatek/mt7981b-xiaomi-ax3000t.dts              |   15 +
 arch/arm64/boot/dts/mediatek/mt7981b.dtsi                            |  105 ++++
 arch/arm64/boot/dts/mediatek/mt7986a-acelink-ew-7886cax.dts          |  173 ++++++
 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso       |    2 +-
 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts             |    2 +-
 arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts                         |   31 +-
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi                            |  180 +++---
 arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts                         |   31 +-
 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts             |   11 +
 arch/arm64/boot/dts/mediatek/mt7988a.dtsi                            |  136 ++++
 arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts                |    2 +-
 arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi                         |    3 +-
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts                          |    2 +-
 arch/arm64/boot/dts/mediatek/mt8173.dtsi                             |   19 +-
 arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi                |    4 +
 arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi                |    4 +
 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi                 |    4 +
 arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi                       |    5 +-
 arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts                      |    2 +-
 arch/arm64/boot/dts/mediatek/mt8183.dtsi                             |   11 +-
 arch/arm64/boot/dts/mediatek/mt8186-corsola-krabby.dtsi              |  129 ++++
 arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393216.dts   |   39 ++
 arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393217.dts   |   39 ++
 arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393218.dts   |   26 +
 arch/arm64/boot/dts/mediatek/mt8186-corsola-rusty-sku196608.dts      |   26 +
 arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131072.dts    |   18 +
 arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131073.dts    |   18 +
 arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix.dtsi             |  199 ++++++
 arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327681.dts  |   57 ++
 arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327683.dts  |   24 +
 arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262144.dts |   44 ++
 arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262148.dts |   26 +
 arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi                     | 1681 ++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt8186.dtsi                             |   93 ++-
 arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi                     |    5 +-
 arch/arm64/boot/dts/mediatek/mt8192.dtsi                             |   10 +-
 arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts             |    4 +
 arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts             |    4 +
 arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts             |    4 +
 arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi                      |   27 +-
 arch/arm64/boot/dts/mediatek/mt8195-demo.dts                         |   18 +-
 arch/arm64/boot/dts/mediatek/mt8195-evb.dts                          |   12 +
 arch/arm64/boot/dts/mediatek/mt8195.dtsi                             |  128 ++--
 arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts               |   17 +-
 arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts                |  825 +++++++++++++++++++++++++
 55 files changed, 4247 insertions(+), 268 deletions(-)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7981b-xiaomi-ax3000t.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7981b.dtsi
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-acelink-ew-7886cax.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a.dtsi
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-krabby.dtsi
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393216.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393217.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393218.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-rusty-sku196608.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131072.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131073.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix.dtsi
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327681.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327683.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262144.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262148.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts


From angelogioacchino.delregno at collabora.com  Mon Feb 19 05:12:26 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 14:12:26 +0100
Subject: [GIT,PULL,2/2] MediaTek soc driver updates for v6.9
In-Reply-To: <20240219131230.157792-1-angelogioacchino.delregno@collabora.com>
References: <20240219131230.157792-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20240219131230.157792-2-angelogioacchino.delregno@collabora.com>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux.git tags/mtk-soc-for-v6.9

for you to fetch changes up to 54d21dea6a6c117f3cab4caa1f9c3ffafb515dd6:

  soc: mediatek: mtk-socinfo: Add extra entry for MT8183 (2024-01-31 09:41:43 +0100)

----------------------------------------------------------------
MediaTek soc driver updates for v6.9

The only addition here is the MediaTek SoC Information driver,
registering socinfo for various MediaTek SoCs.

----------------------------------------------------------------
Chen-Yu Tsai (2):
      soc: mediatek: mtk-socinfo: Clean up NVMEM cell read
      soc: mediatek: mtk-socinfo: Add extra entry for MT8183

William-tw Lin (1):
      soc: mediatek: mtk-socinfo: Add driver for getting chip information

 drivers/soc/mediatek/Kconfig       |   9 ++++
 drivers/soc/mediatek/Makefile      |   1 +
 drivers/soc/mediatek/mtk-socinfo.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 201 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-socinfo.c



From brgl at bgdev.pl  Mon Feb 19 05:18:27 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 14:18:27 +0100
Subject: [PATCH v7 01/12] firmware: qcom: add a dedicated TrustZone buffer allocator
In-Reply-To: <5ppezcfez6tb3xmeevznwefvjjwjefwyzb5r6co4zlo53ht2c2@tdbwgbnxaalt>
References: <20240205182810.58382-1-brgl@bgdev.pl> <20240205182810.58382-2-brgl@bgdev.pl>
 <5ppezcfez6tb3xmeevznwefvjjwjefwyzb5r6co4zlo53ht2c2@tdbwgbnxaalt>
Message-ID: <CAMRc=MdioAp=LoHmp3imRtFe73zQz2k-CuAFioKJ_MzB4YcM0Q@mail.gmail.com>

On Sun, Feb 18, 2024 at 4:22?AM Bjorn Andersson <andersson at kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:27:59PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> [..]
> > diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
> > new file mode 100644
> > index 000000000000..44a062f2abd4
> > --- /dev/null
> > +++ b/drivers/firmware/qcom/qcom_tzmem.c
> > @@ -0,0 +1,302 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
>
> Could you please confirm that "-or-later" is intended?
>

No, it's not, should have been GPL-2.0-only.

> > +/*
> > + * Memory allocator for buffers shared with the TrustZone.
> > + *
> > + * Copyright (C) 2023 Linaro Ltd.
> > + */
> [..]
> > +/**
> > + * qcom_tzmem_pool_new() - Create a new TZ memory pool.
> > + * @size: Size of the new pool in bytes.
> > + *
> > + * Create a new pool of memory suitable for sharing with the TrustZone.
> > + *
> > + * Must not be used in atomic context.
>
>  * Context: Describes whether the function can sleep, what locks it takes,
>  *          releases, or expects to be held. It can extend over multiple
>  *          lines.
>
> > + *
> > + * Returns:
> > + * New memory pool address or ERR_PTR() on error.
>
>  * Return: Describe the return value of function_name.
>
> both from:
> https://docs.kernel.org/doc-guide/kernel-doc.html#function-documentation
>

I can change it but "Returns:" works too.

Bart

> Regards,
> Bjorn


From krzysztof.kozlowski at linaro.org  Mon Feb 19 05:19:17 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 14:19:17 +0100
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
In-Reply-To: <96c0f613-7c53-4189-bfc8-7d572b308b9f@amd.com>
References: <94726c90ff519185767475f672d70311472ea925.1708073513.git.michal.simek@amd.com>
 <5a81f16b-8ece-4263-b424-4dd6cd6e386f@linaro.org>
 <ed59671f-6e0b-45a2-bae7-38f7b4b7e625@amd.com>
 <ebcfd49d-f810-4d9b-8cba-b55071fc7fa6@linaro.org>
 <96c0f613-7c53-4189-bfc8-7d572b308b9f@amd.com>
Message-ID: <3f26624b-7c1d-43cb-a729-5fb50d184046@linaro.org>

On 19/02/2024 14:11, Michal Simek wrote:
> 
> 
> On 2/17/24 09:26, Krzysztof Kozlowski wrote:
>> On 16/02/2024 10:42, Michal Simek wrote:
>>>
>>>
>>> On 2/16/24 10:19, Krzysztof Kozlowski wrote:
>>>> On 16/02/2024 09:51, Michal Simek wrote:
>>>>> RTC has its own power domain on Xilinx Versal SOC that's why describe it as
>>>>> optional property.
>>>>>
>>>>> Signed-off-by: Michal Simek <michal.simek at amd.com>
>>>>> ---
>>>>>
>>>>>    Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml | 3 +++
>>>>>    1 file changed, 3 insertions(+)
>>>>>
>>>>
>>>> But Versal is not described in this binding, is it? I see only one
>>>> compatible.
>>>
>>> It is the same IP only as is on zynqmp with own power rail.
>>
>> Then you should have separate compatible, because they are not
>> identical. It would also allow you to narrow the domains to versal and
>> also require it (on versal).
> 
> I can double check with HW guys but I am quite sure IP itself is exactly the 
> same. What it is different is that there is own power domain to it (not shared 
> one as is in zynqmp case).

What does it mean shared one? If several devices share power domain,
then they all should have power-domains property.

> 
> Also Linux is non secure sw and if secure firmware won't allow to change setting 
> of it it can't be required. I am just saying that Linux doesn't need to be owner 
> of any power domain that's why it shouldn't be required property.


Best regards,
Krzysztof



From vigneshr at ti.com  Mon Feb 19 05:20:19 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Mon, 19 Feb 2024 18:50:19 +0530
Subject: [PATCH] arm64: dts: ti: Add reserved memory for watchdog
In-Reply-To: <20240117060654.109424-1-huaqian.li@siemens.com>
References: <20240117060654.109424-1-huaqian.li@siemens.com>
Message-ID: <170834878953.3471454.17341005022396223551.b4-ty@ti.com>

Hi huaqian.li at siemens.com,

On Wed, 17 Jan 2024 14:06:56 +0800, huaqian.li at siemens.com wrote:
> This patch adds a reserved memory for the TI AM65X platform watchdog
> to reserve the specific info, triggering the watchdog reset in last
> boot, to know if the board reboot is due to a watchdog reset.
> 
> 

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: Add reserved memory for watchdog
      commit: 14a65ea5fee71d716d246b8cc494a95bc9924306

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From michal.simek at amd.com  Mon Feb 19 05:21:54 2024
From: michal.simek at amd.com (Michal Simek)
Date: Mon, 19 Feb 2024 14:21:54 +0100
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
In-Reply-To: <3f26624b-7c1d-43cb-a729-5fb50d184046@linaro.org>
References: <94726c90ff519185767475f672d70311472ea925.1708073513.git.michal.simek@amd.com>
 <5a81f16b-8ece-4263-b424-4dd6cd6e386f@linaro.org>
 <ed59671f-6e0b-45a2-bae7-38f7b4b7e625@amd.com>
 <ebcfd49d-f810-4d9b-8cba-b55071fc7fa6@linaro.org>
 <96c0f613-7c53-4189-bfc8-7d572b308b9f@amd.com>
 <3f26624b-7c1d-43cb-a729-5fb50d184046@linaro.org>
Message-ID: <de8e68df-8b9b-4c75-9d0e-db6e150fe1e2@amd.com>



On 2/19/24 14:19, Krzysztof Kozlowski wrote:
> On 19/02/2024 14:11, Michal Simek wrote:
>>
>>
>> On 2/17/24 09:26, Krzysztof Kozlowski wrote:
>>> On 16/02/2024 10:42, Michal Simek wrote:
>>>>
>>>>
>>>> On 2/16/24 10:19, Krzysztof Kozlowski wrote:
>>>>> On 16/02/2024 09:51, Michal Simek wrote:
>>>>>> RTC has its own power domain on Xilinx Versal SOC that's why describe it as
>>>>>> optional property.
>>>>>>
>>>>>> Signed-off-by: Michal Simek <michal.simek at amd.com>
>>>>>> ---
>>>>>>
>>>>>>     Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml | 3 +++
>>>>>>     1 file changed, 3 insertions(+)
>>>>>>
>>>>>
>>>>> But Versal is not described in this binding, is it? I see only one
>>>>> compatible.
>>>>
>>>> It is the same IP only as is on zynqmp with own power rail.
>>>
>>> Then you should have separate compatible, because they are not
>>> identical. It would also allow you to narrow the domains to versal and
>>> also require it (on versal).
>>
>> I can double check with HW guys but I am quite sure IP itself is exactly the
>> same. What it is different is that there is own power domain to it (not shared
>> one as is in zynqmp case).
> 
> What does it mean shared one? If several devices share power domain,
> then they all should have power-domains property.

Shared one means that the same power domain is shared with other IPs or simply 
enabled by default without any option to disable it.

Thanks,
Michal



From xiangyang3 at huawei.com  Mon Feb 19 05:21:53 2024
From: xiangyang3 at huawei.com (Xiang Yang)
Date: Mon, 19 Feb 2024 21:21:53 +0800
Subject: [PATCH 5.10.y v2] Revert "arm64: Stash shadow stack pointer in the task struct on interrupt"
Message-ID: <20240219132153.378265-1-xiangyang3@huawei.com>

This reverts commit 3f225f29c69c13ce1cbdb1d607a42efeef080056.

The shadow call stack for irq now is stored in current task's thread info
in irq_stack_entry. There is a possibility that we have some soft irqs
pending at the end of hard irq, and when we process softirq with the irq
enabled, irq_stack_entry will enter again and overwrite the shadow call
stack whitch stored in current task's thread info, leading to the
incorrect shadow call stack restoration for the first entry of the hard
IRQ, then the system end up with a panic.

task A                               |  task A
-------------------------------------+------------------------------------
el1_irq        //irq1 enter          |
  irq_handler  //save scs_sp1        |
    gic_handle_irq                   |
    irq_exit                         |
      __do_softirq                   |
                                     | el1_irq         //irq2 enter
                                     |   irq_handler   //save scs_sp2
                                     |                 //overwrite scs_sp1
                                     |   ...
                                     |   irq_stack_exit //restore scs_sp2
  irq_stack_exit //restore wrong     |
                 //scs_sp2           |

So revert this commit to fix it.

Fixes: 3f225f29c69c ("arm64: Stash shadow stack pointer in the task struct on interrupt")

Signed-off-by: Xiang Yang <xiangyang3 at huawei.com>
---
 arch/arm64/kernel/entry.S | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index a94acea770c7..020a455824be 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -431,7 +431,9 @@ SYM_CODE_END(__swpan_exit_el0)
 
 	.macro	irq_stack_entry
 	mov	x19, sp			// preserve the original sp
-	scs_save tsk			// preserve the original shadow stack
+#ifdef CONFIG_SHADOW_CALL_STACK
+	mov	x24, scs_sp		// preserve the original shadow stack
+#endif
 
 	/*
 	 * Compare sp with the base of the task stack.
@@ -465,7 +467,9 @@ SYM_CODE_END(__swpan_exit_el0)
 	 */
 	.macro	irq_stack_exit
 	mov	sp, x19
-	scs_load_current
+#ifdef CONFIG_SHADOW_CALL_STACK
+	mov	scs_sp, x24
+#endif
 	.endm
 
 /* GPRs used by entry code */
-- 
2.34.1



From skseofh at gmail.com  Mon Feb 19 05:27:32 2024
From: skseofh at gmail.com (skseofh at gmail.com)
Date: Mon, 19 Feb 2024 22:27:32 +0900
Subject: [PATCH] arm64: remove duplicated early fixmap init
Message-ID: <20240219132732.2493485-1-skseofh@gmail.com>

From: Daero Lee <skseofh at gmail.com>

We call early_fixmap_init() in two places.
- early_fdt_map()
- setup_arch()

Because early_fdt_map() is called before going to setup_arch(),
early_fixmap_init() can be deleted from setup_arch().

Signed-off-by: Daero Lee <skseofh at gmail.com>
---
 arch/arm64/kernel/setup.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 42c690bb2d60..ce45f4a9ac4a 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -305,7 +305,6 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 	 */
 	arm64_use_ng_mappings = kaslr_requires_kpti();
 
-	early_fixmap_init();
 	early_ioremap_init();
 
 	setup_machine_fdt(__fdt_pointer);
-- 
2.25.1



From michal.simek at amd.com  Mon Feb 19 05:35:01 2024
From: michal.simek at amd.com (Michal Simek)
Date: Mon, 19 Feb 2024 14:35:01 +0100
Subject: [PATCH] clk: zynq: Prevent null pointer dereference caused by
 kmalloc failure
In-Reply-To: <20240214073318.82573-1-duoming@zju.edu.cn>
References: <20240214073318.82573-1-duoming@zju.edu.cn>
Message-ID: <86e1c66c-8fd4-402e-a827-cc4347d468c1@amd.com>



On 2/14/24 08:33, Duoming Zhou wrote:
> The kmalloc in zynq_clk_setup will return null if the
> physical memory has run out. As a result, if we use
> snprintf to write data to the null address, the null
> pointer dereference bug will happen.
> 
> The required memory is only 11 bytes, so this patch
> adds a "__GFP_NOFAIL" flag in kmalloc in order that
> the kmalloc will never return with failure.
> 
> Fixes: 0ee52b157b8e ("clk: zynq: Add clock controller driver")
> Signed-off-by: Duoming Zhou <duoming at zju.edu.cn>
> ---
>   drivers/clk/zynq/clkc.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
> index 7bdeaff2bfd..7621c2f0046 100644
> --- a/drivers/clk/zynq/clkc.c
> +++ b/drivers/clk/zynq/clkc.c
> @@ -427,7 +427,7 @@ static void __init zynq_clk_setup(struct device_node *np)
>   			SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock);
>   
>   	tmp = strlen("mio_clk_00x");
> -	clk_name = kmalloc(tmp, GFP_KERNEL);
> +	clk_name = kmalloc(tmp, GFP_KERNEL | __GFP_NOFAIL);
>   	for (i = 0; i < NUM_MIO_PINS; i++) {
>   		int idx;
>   

Reviewed-by: Michal Simek <michal.simek at amd.com>

Thanks,
Michal


From angelogioacchino.delregno at collabora.com  Mon Feb 19 05:35:26 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 19 Feb 2024 14:35:26 +0100
Subject: [PATCH v2 2/2] arm64: dts: mediatek: add Kontron 3.5"-SBC-i1200
In-Reply-To: <CZ92W3VSYV1A.1693O76GY1XDP@kernel.org>
References: <20240219084456.1075445-1-mwalle@kernel.org>
 <20240219084456.1075445-2-mwalle@kernel.org>
 <2ad6bda8-a457-421b-b35d-dc005fb00ae9@collabora.com>
 <CZ92W3VSYV1A.1693O76GY1XDP@kernel.org>
Message-ID: <b50d49fd-2976-46fc-9f35-354fb39720ad@collabora.com>

Il 19/02/24 14:09, Michael Walle ha scritto:
> Hi,
> 
> thanks for the extensive review!
> 
> On Mon Feb 19, 2024 at 11:00 AM CET, AngeloGioacchino Del Regno wrote:
> 
>>> +&eth {
>>> +	phy-mode ="rgmii-id";
>>> +	phy-handle = <&ethernet_phy0>;
>>> +	snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>;
>>> +	snps,reset-delays-us = <0 10000 80000>;
>>
>> snps,reset-delays-us and snps,reset-gpio are deprecated.
>>
>>> +	pinctrl-names = "default", "sleep";
>>> +	pinctrl-0 = <&eth_default_pins>;
>>> +	pinctrl-1 = <&eth_sleep_pins>;
>>> +	status = "okay";
>>> +
>>> +	mdio {
>>> +		ethernet_phy0: ethernet-phy at 1 {
>>
>> compatible = "is there any applicable compatible?"
>> P.S.: if you've got the usual rtl8211f, should be "ethernet-phy-id001c.c916"
> 
> I'd rather not have a compatible here. First, it's auto discoverable
> and IIRC it's frowned upon adding any compatible if you ask the PHY
> maintainers. And second, if we change the PHY (maybe due to a second
> chip shortage or whatever), there is a chance you don't have to
> update this in the DT.
> 

Okay then, I'm fine with leaving the compatible out.

>> reg = <0x1>;
>> interrupts-extended = <&pio 94 IRQ_TYPE_LEVEL_LOW>;
>> reset-assert-us = <10000>;
>> reset-deassert-us = <80000>;
>> reset-gpios = <&pio 93 GPIO_ACTIVE_HIGH>;
>>
>>
>>> +			reg = <0x1>;
>>> +			interrupts-extended = <&pio 94 IRQ_TYPE_LEVEL_LOW>;
>>> +		};
>>> +	};
>>> +};
>>> +
>>> +&gpu {
>>> +	status = "okay";
>>> +	mali-supply = <&mt6315_7_vbuck1>;
>>> +};
>>> +
>>> +&i2c2 {
>>> +	pinctrl-names = "default";
>>> +	pinctrl-0 = <&i2c2_pins>;
>>> +	clock-frequency = <400000>;
>>> +	status = "okay";
>>
>> Are i2c2,3,4 exposed as pins somewhere? If they are, can you please put a
>> comment saying so?
> 
> This is only a basic device tree. On one i2c controller, there is
> the LVDS bridge for example. My plan is to get the support for this
> bridge upstream first and then adding the appropriate device nodes
> here.
> 
> That being said, some are exposed to connectors. I'll add a comment
> then.

In that case, could be nice to read something like

&i2c(x) {
	properties
	blahblah
	status

	/* (model, if available) LVDS bridge at 0x10 */
}

it's again not mandatory, but I like seeing clear messages implying "this should be
there" as those implicitly mean "...yeah but it's not supported yet for reasons".

It's down to preferences though, and this is not a *strong* opinion, nor a strong
suggestion - your call here.

> 
>>> +&mmc1 {
>>> +	pinctrl-names = "default", "state_uhs";
>>> +	pinctrl-0 = <&mmc1_default_pins>;
>>> +	pinctrl-1 = <&mmc1_uhs_pins>;
>>> +	cd-gpios = <&pio 129 GPIO_ACTIVE_LOW>;
>>> +	bus-width = <4>;
>>> +	max-frequency = <200000000>;
>>> +	cap-sd-highspeed;
>>> +	sd-uhs-sdr50;
>>> +	sd-uhs-sdr104;
>>> +	vmmc-supply = <&mt6360_ldo5>;
>>> +	vqmmc-supply = <&mt6360_ldo3>;
>>
>> Does mmc1 support eMMC and SDIO?
> 
> No eMMC, but I'd guess it will support SDIO as in you can just plug
> an SDIO card in the SD slot, right? Oh, it's a micro SD socket. So
> uhm, I'm not sure if we should restrict it, though. Someone might
> come up with a microsd to sd card adapter. I have one right in front
> of me ;)
> 

Honestly ... I even forgot the existance of those adapters!!!
In that case, yes, since the controller should support SDIO on that slot, and since
there effectively are ways to add a SDIO card on there, obviously no-sdio shall be
omitted.

I agree.

>> If not, no-mmc; no-sdio;
> 
> So no-mmc;

Yes, agreed.

> 
>>> +			drive-strength = <MTK_DRIVE_8mA>;
>>
>> s/MTK_DRIVE//g
>> s/mA//g
>>
>> drive-strength = <8>;
>>
>> Please, here and everywhere else, for all values - let's stop using those
>> MTK_DRIVE_(x)mA definitions, they're just defined as (x), where anyway
>> the drive-strength property is in milliamps by default.
>>
>> We don't need these definitions.
> 
> Sure, the mt8195-demo was the blueprint for this. So maybe you should
> get rid of it there to prevent any copying ;) (btw the same goes for
> the regulator-compatible property).
> 

Yeah, that's right. You can imagine that my backlog is rather huge... :-)

> Speaking of pinctrl, I find the R0R1 bias-pull-down values really

If it was only pull-down it would be one problem, but it's also pull-up so
we can sum that up to *two* problems :-P

> hard to grasp. The DT binding documentation didn't really help here.
> What is R0 and R1, I presume some resistors which can be enabled.

You got it right

> Also are they in parallel or in series. I'd have assumed, the DT

I'm not sure, and it depends on the SoC most probably... but does that really
matter?

I mean, on the practical side, imo, it doesn't, but I am also a curious person
so I can understand why you're eager to know :-)

> binding should have hid this by giving the user a choice for the
> resistance instead. Also I had a quick search in the RM and
> couldn't find anything, I probably looked at the wrong place ;)
> 

I'm not sure you looked at mediatek,mt8195-pinctrl.yaml, but anyway, as you
can read in there, we're deprecating the MTK_PULL_SET_RSEL_xxx in favor of...

.... the right thing to do :-)

Look for "mediatek,rsel-resistance-in-si-unit": that'll allow you to specify
the PU/PD values in ohms, and that's what should be used.

Those RSEL definitions in the devicetree should disappear. Forever.

>>> +	uart1_pins: uart1-pins {
>>> +		pins_rx {
>>> +			pinmux = <PINMUX_GPIO103__FUNC_URXD1>;
>>> +			input-enable;
>>> +			bias-pull-up;
>>> +		};
>>> +
>>> +		pins_tx {
>>> +			pinmux = <PINMUX_GPIO102__FUNC_UTXD1>;
>>> +		};
>>> +
>>> +		pins_rts {
>>> +			pinmux = <PINMUX_GPIO100__FUNC_URTS1>;
>>> +			output-enable;
>>
>> Are you really sure that you need output-enable here?!
>> RTS is not an output buffer....
>>
>> I don't think you do. Please double check.
> 
> Ahh, good catch, it's a leftover from mt8183-kukui.dts. There is
> probably wrong, too.
> 

Probably. I don't really know either.

>>> +		};
>>> +
>>> +		pins_cts {
>>> +			pinmux = <PINMUX_GPIO101__FUNC_UCTS1>;
>>> +			input-enable;
>>> +		};
>>> +	};
>>> +
> 
> 
>>> +/* USB3 front port */
>>> +&xhci0 {
>>
>> It's not gonna work like this. I recently fixed the USB nodes in MT8195 by adding
>> MTU3 where necessary...
> 
> Uhm, seems like I've missed that.
> 

No worries!

>> Check mt8195.dtsi - only one XHCI controller isn't placed behind MTU3, and that is
>> XHCI1 (11290000), while the others are MTU3.
>>
>> As far as I can see from this DT, it should now instead look like..
>>
>> &ssusb0 {
>> 	dr_mode = "host";
>> 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
>> 	status = "okay";
>> };
>>
>> &ssusb2 {
>> 	dr_mode = "host";
>> 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
>> 	status = "okay";
>> };
>>
>> &ssusb3 {
>> 	dr_mode = "host";
>> 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
>> 	status = "okay";
>> };
>>
>> &xhci0 {
>> 	vbus-supply = <&otg_vbus_regulator>;
>> 	status = "okay";
>> };
>>
>> &xhci1 {
>> 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
>>
>> vbus is always supplied by something, as otherwise USB won't work - whether this
>> is an always-on regulator or a passthrough from external supply this doesn't really
>> matter - you should model a regulator-fixed that provides the 5V VBUS line.
> 
> I don't think this is correct, though. Think of an on-board USB
> hub. There only D+/D- are connected (and maybe the USB3.2 SerDes
> lanes). Or have a look at the M.2 pinout. There is no Vbus.
> 

Yes but the MediaTek MTU3 and/or controllers do have it ;-)

> Also it seems I need the "mediatek,u3p-dis-msk = <0x01>;". At least
> the last time I've tested it. I'll test it again, with and without.
> The SerDes Line of the corresponding USB3.2 port is used for PCIe in
> this case.
> 

Have I missed it in my example? If I missed it, that was unintentional.

Anyway, for the u3p-dis-msk, I'll spare you the time to check:
  - If the controller lies behind MTU3, that property goes to &ssusb(x)
  - If it is a standalone XHCI controller, it goes to &xhci(x)
    - The property never goes to both, and always goes to the *outer* node
      (this is why it goes to mtu3 if there's a mtu3 behind).

>> For example:
>> 	vbus_fixed: regulator-vbus {
>> 		compatible = "regulator-fixed";
>> 		regulator-name = "usb-vbus";
>> 		regulator-always-on;
>> 		regulator-boot-on;
>> 		regulator-min-microvolt = <5000000>;
>> 		regulator-max-microvolt = <5000000>;
>> 	};
> 
> As mentioned above, I don't think this will make sense in my case.
>  >> P.S.: If the rail has a different name, please use that different name. Obviously
>> that requires you to have schematics at hand, and I don't know if you do: if you
>> don't, then that regulator-vbus name is just fine.
> 
> I do have the schematics.

In that case, you should model the power tree with the fixed power lines,
check mt8195-cherry (and/or cherry-tomato) and radxa-nio-12l; even though
those are technically "doing nothing", this is device tree, so it should
provide a description of the hardware ... and the board does have fixed
power lines.
It has at least one: DC-IN (typec, barrel jack or whatever, the board needs
power, doesn't it?!).

Cheers,
Angelo




From konrad.dybcio at linaro.org  Mon Feb 19 05:35:46 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 14:35:46 +0100
Subject: [PATCH 1/8] dt-bindings: arm-smmu: Add QCM2290 GPU SMMU
In-Reply-To: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v1-1-d260fa854707@linaro.org>

The GPU SMMU on QCM2290 nicely fits into the description we already have
for SM61[12]5. Add it.

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index a4042ae24770..4a8d4022aebc 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -83,6 +83,7 @@ properties:
       - description: Qcom Adreno GPUs implementing "qcom,smmu-500" and "arm,mmu-500"
         items:
           - enum:
+              - qcom,qcm2290-smmu-500
               - qcom,sa8775p-smmu-500
               - qcom,sc7280-smmu-500
               - qcom,sc8280xp-smmu-500
@@ -462,6 +463,7 @@ allOf:
         compatible:
           items:
             - enum:
+                - qcom,qcm2290-smmu-500
                 - qcom,sm6115-smmu-500
                 - qcom,sm6125-smmu-500
             - const: qcom,adreno-smmu
@@ -534,7 +536,6 @@ allOf:
               - cavium,smmu-v2
               - marvell,ap806-smmu-500
               - nvidia,smmu-500
-              - qcom,qcm2290-smmu-500
               - qcom,qdu1000-smmu-500
               - qcom,sc7180-smmu-500
               - qcom,sc8180x-smmu-500

-- 
2.43.2



From konrad.dybcio at linaro.org  Mon Feb 19 05:35:45 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 14:35:45 +0100
Subject: [PATCH 0/8] A702 support
Message-ID: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>

Bit of a megaseries, bunched together for your testing convenience..
Needs mesa!27665 [1] on the userland part, kmscube happily spins.

I'm feeling quite lukewarm about the memory barriers in patch 3..

Patch 1 for Will/smmu, 5-6 for drm/msm, rest for qcom

[1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27665

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
Konrad Dybcio (8):
      dt-bindings: arm-smmu: Add QCM2290 GPU SMMU
      dt-bindings: clock: Add Qcom QCM2290 GPUCC
      clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
      clk: qcom: Add QCM2290 GPU clock controller driver
      drm/msm/adreno: Add missing defines for A702
      drm/msm/adreno: Add A702 support
      arm64: dts: qcom: qcm2290: Add GPU nodes
      arm64: dts: qcom: qrb2210-rb1: Enable the GPU

 .../bindings/clock/qcom,qcm2290-gpucc.yaml         |  76 ++++
 .../devicetree/bindings/iommu/arm,smmu.yaml        |   3 +-
 arch/arm64/boot/dts/qcom/qcm2290.dtsi              | 154 ++++++++
 arch/arm64/boot/dts/qcom/qrb2210-rb1.dts           |   8 +
 drivers/clk/qcom/Kconfig                           |   9 +
 drivers/clk/qcom/Makefile                          |   1 +
 drivers/clk/qcom/clk-alpha-pll.c                   |  45 +++
 drivers/clk/qcom/clk-alpha-pll.h                   |   3 +
 drivers/clk/qcom/gpucc-qcm2290.c                   | 423 +++++++++++++++++++++
 drivers/gpu/drm/msm/adreno/a6xx.xml.h              |  18 +
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c              |  92 ++++-
 drivers/gpu/drm/msm/adreno/adreno_device.c         |  18 +
 drivers/gpu/drm/msm/adreno/adreno_gpu.h            |  16 +-
 include/dt-bindings/clock/qcom,qcm2290-gpucc.h     |  32 ++
 14 files changed, 888 insertions(+), 10 deletions(-)
---
base-commit: 26d7d52b6253574d5b6fec16a93e1110d1489cef
change-id: 20240219-topic-rb1_gpu-3ec8c6830384

Best regards,
-- 
Konrad Dybcio <konrad.dybcio at linaro.org>



From konrad.dybcio at linaro.org  Mon Feb 19 05:35:47 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 14:35:47 +0100
Subject: [PATCH 2/8] dt-bindings: clock: Add Qcom QCM2290 GPUCC
In-Reply-To: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v1-2-d260fa854707@linaro.org>

Add device tree bindings for graphics clock controller for Qualcomm
Technology Inc's QCM2290 SoCs.

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 .../bindings/clock/qcom,qcm2290-gpucc.yaml         | 76 ++++++++++++++++++++++
 include/dt-bindings/clock/qcom,qcm2290-gpucc.h     | 32 +++++++++
 2 files changed, 108 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml
new file mode 100644
index 000000000000..a16cb7e87e26
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,qcm2290-gpucc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Graphics Clock & Reset Controller on QCM2290
+
+maintainers:
+  - Konrad Dybcio <konradybcio at kernel.org>
+
+description: |
+  Qualcomm graphics clock control module provides the clocks, resets and power
+  domains on Qualcomm SoCs.
+
+  See also::
+    include/dt-bindings/clock/qcom,qcm2290-gpucc.h
+
+properties:
+  compatible:
+    - const: qcom,qcm2290-gpucc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: AHB interface clock,
+      - description: SoC CXO clock
+      - description: GPLL0 main branch source
+      - description: GPLL0 div branch source
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-qcm2290.h>
+    #include <dt-bindings/clock/qcom,rpmcc.h>
+    #include <dt-bindings/power/qcom-rpmpd.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller at 5990000 {
+            compatible = "qcom,qcm2290-gpucc";
+            reg = <0x0 0x05990000 0x0 0x9000>;
+            clocks = <&gcc GCC_GPU_CFG_AHB_CLK>,
+                     <&rpmcc RPM_SMD_XO_CLK_SRC>,
+                     <&gcc GCC_GPU_GPLL0_CLK_SRC>,
+                     <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
+            power-domains = <&rpmpd QCM2290_VDDCX>;
+            required-opps = <&rpmpd_opp_low_svs>;
+            #clock-cells = <1>;
+            #reset-cells = <1>;
+            #power-domain-cells = <1>;
+        };
+    };
+...
diff --git a/include/dt-bindings/clock/qcom,qcm2290-gpucc.h b/include/dt-bindings/clock/qcom,qcm2290-gpucc.h
new file mode 100644
index 000000000000..7c76dd05278f
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,qcm2290-gpucc.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_QCM2290_H
+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_QCM2290_H
+
+/* GPU_CC clocks */
+#define GPU_CC_AHB_CLK			0
+#define GPU_CC_CRC_AHB_CLK		1
+#define GPU_CC_CX_GFX3D_CLK		2
+#define GPU_CC_CX_GMU_CLK		3
+#define GPU_CC_CX_SNOC_DVM_CLK		4
+#define GPU_CC_CXO_AON_CLK		5
+#define GPU_CC_CXO_CLK			6
+#define GPU_CC_GMU_CLK_SRC		7
+#define GPU_CC_GX_GFX3D_CLK		8
+#define GPU_CC_GX_GFX3D_CLK_SRC		9
+#define GPU_CC_PLL0			10
+#define GPU_CC_SLEEP_CLK		11
+#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK	12
+
+/* Resets */
+#define GPU_GX_BCR			0
+
+/* GDSCs */
+#define GPU_CX_GDSC			0
+#define GPU_GX_GDSC			1
+
+#endif

-- 
2.43.2



From konrad.dybcio at linaro.org  Mon Feb 19 05:35:48 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 14:35:48 +0100
Subject: [PATCH 3/8] clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
In-Reply-To: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v1-3-d260fa854707@linaro.org>

Commit 134b55b7e19f ("clk: qcom: support Huayra type Alpha PLL")
introduced an entry to the alpha offsets array, but diving into QCM2290
downstream and some documentation, it turned out that the name Huayra
apparently has been used quite liberally across many chips, even with
noticeably different hardware.

Introduce another set of offsets and a new configure function for the
Huayra PLL found on QCM2290. This is required e.g. for the consumers
of GPUCC_PLL0 to properly start.

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 45 ++++++++++++++++++++++++++++++++++++++++
 drivers/clk/qcom/clk-alpha-pll.h |  3 +++
 2 files changed, 48 insertions(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 8a412ef47e16..61b5abd13782 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -244,6 +244,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
 		[PLL_OFF_OPMODE] = 0x30,
 		[PLL_OFF_STATUS] = 0x3c,
 	},
+	[CLK_ALPHA_PLL_TYPE_HUAYRA_2290] =  {
+		[PLL_OFF_L_VAL] = 0x04,
+		[PLL_OFF_ALPHA_VAL] = 0x08,
+		[PLL_OFF_USER_CTL] = 0x0c,
+		[PLL_OFF_CONFIG_CTL] = 0x10,
+		[PLL_OFF_CONFIG_CTL_U] = 0x14,
+		[PLL_OFF_CONFIG_CTL_U1] = 0x18,
+		[PLL_OFF_TEST_CTL] = 0x1c,
+		[PLL_OFF_TEST_CTL_U] = 0x20,
+		[PLL_OFF_TEST_CTL_U1] = 0x24,
+		[PLL_OFF_OPMODE] = 0x28,
+		[PLL_OFF_STATUS] = 0x38,
+	},
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
 
@@ -779,6 +792,38 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 	return clamp(rate, min_freq, max_freq);
 }
 
+void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
+				   const struct alpha_pll_config *config)
+{
+	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
+	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);
+	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);
+	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);
+	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);
+	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);
+	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
+	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
+	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
+
+	/* Set PLL_BYPASSNL */
+	regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL);
+
+	/* Wait 5 us between setting BYPASS and deasserting reset */
+	mb();
+	udelay(5);
+
+	/* Take PLL out from reset state */
+	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
+
+	/* Wait 50us for PLL_LOCK_DET bit to go high */
+	mb();
+	usleep_range(50, 55);
+
+	/* Enable PLL output */
+	regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
+}
+EXPORT_SYMBOL(clk_huayra_2290_pll_configure);
+
 static unsigned long
 alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a)
 {
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index fb6d50263bb9..91d3d6f19eae 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -29,6 +29,7 @@ enum {
 	CLK_ALPHA_PLL_TYPE_BRAMMO_EVO,
 	CLK_ALPHA_PLL_TYPE_STROMER,
 	CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
+	CLK_ALPHA_PLL_TYPE_HUAYRA_2290,
 	CLK_ALPHA_PLL_TYPE_MAX,
 };
 
@@ -191,6 +192,8 @@ extern const struct clk_ops clk_alpha_pll_rivian_evo_ops;
 
 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 			     const struct alpha_pll_config *config);
+void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
+				   const struct alpha_pll_config *config);
 void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 				const struct alpha_pll_config *config);
 void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,

-- 
2.43.2



From konrad.dybcio at linaro.org  Mon Feb 19 05:35:49 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 14:35:49 +0100
Subject: [PATCH 4/8] clk: qcom: Add QCM2290 GPU clock controller driver
In-Reply-To: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v1-4-d260fa854707@linaro.org>

Add a driver for the GPU clock controller block found on the QCM2290 SoC.

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 drivers/clk/qcom/Kconfig         |   9 +
 drivers/clk/qcom/Makefile        |   1 +
 drivers/clk/qcom/gpucc-qcm2290.c | 423 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 433 insertions(+)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 4580edbd13ea..d70ea4548755 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -65,6 +65,15 @@ config CLK_X1E80100_TCSRCC
 	  Support for the TCSR clock controller on X1E80100 devices.
 	  Say Y if you want to use peripheral devices such as SD/UFS.
 
+config CLK_QCM2290_GPUCC
+	tristate "QCM2290 Graphics Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select CLK_QCM2290_GCC
+	help
+	  Support for the graphics clock controller on QCM2290 devices.
+	  Say Y if you want to support graphics controller devices and
+	  functionality such as 3D graphics.
+
 config QCOM_A53PLL
 	tristate "MSM8916 A53 PLL"
 	help
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 1da65ca78e24..b8d49c054558 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o
 obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o
 obj-$(CONFIG_CLK_X1E80100_GPUCC) += gpucc-x1e80100.o
 obj-$(CONFIG_CLK_X1E80100_TCSRCC) += tcsrcc-x1e80100.o
+obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o
 obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o
 obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o
 obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
diff --git a/drivers/clk/qcom/gpucc-qcm2290.c b/drivers/clk/qcom/gpucc-qcm2290.c
new file mode 100644
index 000000000000..b6e20d63ac85
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-qcm2290.c
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,qcm2290-gpucc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "clk-regmap-phy-mux.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_GCC_AHB_CLK,
+	DT_BI_TCXO,
+	DT_GCC_GPU_GPLL0_CLK_SRC,
+	DT_GCC_GPU_GPLL0_DIV_CLK_SRC,
+};
+
+enum {
+	P_BI_TCXO,
+	P_GPLL0_OUT_MAIN,
+	P_GPLL0_OUT_MAIN_DIV,
+	P_GPU_CC_PLL0_2X_DIV_CLK_SRC,
+	P_GPU_CC_PLL0_OUT_AUX,
+	P_GPU_CC_PLL0_OUT_AUX2,
+	P_GPU_CC_PLL0_OUT_MAIN,
+};
+
+static const struct pll_vco huayra_vco[] = {
+	{ 600000000, 3300000000, 0 },
+	{ 600000000, 2200000000, 1 },
+};
+
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+	.l = 0x25,
+	.config_ctl_val = 0x200d4828,
+	.config_ctl_hi_val = 0x6,
+	.test_ctl_val = GENMASK(28, 26),
+	.test_ctl_hi_val = BIT(14),
+	.user_ctl_val = 0xf,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = huayra_vco,
+	.num_vco = ARRAY_SIZE(huayra_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290],
+	.clkr = {
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_huayra_ops,
+		},
+	},
+};
+
+static const struct parent_map gpu_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPU_CC_PLL0_OUT_MAIN, 1 },
+	{ P_GPLL0_OUT_MAIN, 5 },
+	{ P_GPLL0_OUT_MAIN_DIV, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO, },
+	{ .hw = &gpu_cc_pll0.clkr.hw, },
+	{ .index = DT_GCC_GPU_GPLL0_CLK_SRC, },
+	{ .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC, },
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPU_CC_PLL0_2X_DIV_CLK_SRC, 1 },
+	{ P_GPU_CC_PLL0_OUT_AUX2, 2 },
+	{ P_GPU_CC_PLL0_OUT_AUX, 3 },
+	{ P_GPLL0_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO, },
+	{ .hw = &gpu_cc_pll0.clkr.hw, },
+	{ .hw = &gpu_cc_pll0.clkr.hw, },
+	{ .hw = &gpu_cc_pll0.clkr.hw, },
+	{ .index = DT_GCC_GPU_GPLL0_CLK_SRC, },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
+	.cmd_rcgr = 0x1120,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_0,
+	.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "gpu_cc_gmu_clk_src",
+		.parent_data = gpu_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
+	F(355200000, P_GPU_CC_PLL0_OUT_AUX, 2, 0, 0),
+	F(537600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	F(672000000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	F(844800000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	F(921600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	F(1017600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	F(1123200000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
+	.cmd_rcgr = 0x101c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_1,
+	.freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "gpu_cc_gx_gfx3d_clk_src",
+		.parent_data = gpu_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_branch gpu_cc_ahb_clk = {
+	.halt_reg = 0x1078,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x1078,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_ahb_clk",
+			.flags = CLK_IS_CRITICAL,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_crc_ahb_clk = {
+	.halt_reg = 0x107c,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x107c,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_crc_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_gfx3d_clk = {
+	.halt_reg = 0x10a4,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x10a4,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cx_gfx3d_clk",
+			.parent_data = &(const struct clk_parent_data){
+				.hw = &gpu_cc_gx_gfx3d_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+	.halt_reg = 0x1098,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1098,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cx_gmu_clk",
+			.parent_data = &(const struct clk_parent_data){
+				.hw = &gpu_cc_gmu_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
+	.halt_reg = 0x108c,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x108c,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cx_snoc_dvm_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cxo_aon_clk = {
+	.halt_reg = 0x1004,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x1004,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cxo_aon_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cxo_clk = {
+	.halt_reg = 0x109c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x109c,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cxo_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gx_gfx3d_clk = {
+	.halt_reg = 0x1054,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x1054,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_gx_gfx3d_clk",
+			.parent_data = &(const struct clk_parent_data){
+				.hw = &gpu_cc_gx_gfx3d_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_sleep_clk = {
+	.halt_reg = 0x1090,
+	.halt_check = BRANCH_VOTED,
+	.clkr = {
+		.enable_reg = 0x1090,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
+	.halt_reg = 0x5000,
+	.halt_check = BRANCH_VOTED,
+	.clkr = {
+		.enable_reg = 0x5000,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			 .name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
+			 .ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc gpu_cx_gdsc = {
+	.gdscr = 0x106c,
+	.gds_hw_ctrl = 0x1540,
+	.pd = {
+		.name = "gpu_cx_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
+static struct gdsc gpu_gx_gdsc = {
+	.gdscr = 0x100c,
+	.clamp_io_ctrl = 0x1508,
+	.resets = (unsigned int []){ GPU_GX_BCR },
+	.reset_count = 1,
+	.pd = {
+		.name = "gpu_gx_gdsc",
+	},
+	.parent = &gpu_cx_gdsc.pd,
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = CLAMP_IO | AON_RESET | SW_RESET,
+};
+
+static struct clk_regmap *gpu_cc_qcm2290_clocks[] = {
+	[GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
+	[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
+	[GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr,
+	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
+	[GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
+	[GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
+	[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
+	[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
+	[GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr,
+	[GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr,
+	[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
+	[GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
+	[GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
+};
+
+static const struct qcom_reset_map gpu_cc_qcm2290_resets[] = {
+	[GPU_GX_BCR] = { 0x1008 },
+};
+
+static struct gdsc *gpu_cc_qcm2290_gdscs[] = {
+	[GPU_CX_GDSC] = &gpu_cx_gdsc,
+	[GPU_GX_GDSC] = &gpu_gx_gdsc,
+};
+
+static const struct regmap_config gpu_cc_qcm2290_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x9000,
+	.fast_io = true,
+};
+
+
+static const struct qcom_cc_desc gpu_cc_qcm2290_desc = {
+	.config = &gpu_cc_qcm2290_regmap_config,
+	.clks = gpu_cc_qcm2290_clocks,
+	.num_clks = ARRAY_SIZE(gpu_cc_qcm2290_clocks),
+	.resets = gpu_cc_qcm2290_resets,
+	.num_resets = ARRAY_SIZE(gpu_cc_qcm2290_resets),
+	.gdscs = gpu_cc_qcm2290_gdscs,
+	.num_gdscs = ARRAY_SIZE(gpu_cc_qcm2290_gdscs),
+};
+
+static const struct of_device_id gpu_cc_qcm2290_match_table[] = {
+	{ .compatible = "qcom,qcm2290-gpucc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_qcm2290_match_table);
+
+static int gpu_cc_qcm2290_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	int ret;
+
+	regmap = qcom_cc_map(pdev, &gpu_cc_qcm2290_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = devm_pm_clk_create(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = pm_clk_add(&pdev->dev, NULL);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to acquire ahb clock\n");
+		return ret;
+	}
+
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret)
+		return ret;
+
+	clk_huayra_2290_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
+
+	regmap_update_bits(regmap, 0x1060, BIT(0), BIT(0)); /* GPU_CC_GX_CXO_CLK */
+
+	ret = qcom_cc_really_probe(pdev, &gpu_cc_qcm2290_desc, regmap);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register display clock controller\n");
+		goto out_pm_runtime_put;
+	}
+
+out_pm_runtime_put:
+	pm_runtime_put_sync(&pdev->dev);
+
+	return 0;
+}
+
+static struct platform_driver gpu_cc_qcm2290_driver = {
+	.probe = gpu_cc_qcm2290_probe,
+	.driver = {
+		.name = "gpucc-qcm2290",
+		.of_match_table = gpu_cc_qcm2290_match_table,
+	},
+};
+module_platform_driver(gpu_cc_qcm2290_driver);
+
+MODULE_DESCRIPTION("QTI QCM2290 GPU clock controller driver");
+MODULE_LICENSE("GPL");

-- 
2.43.2



From konrad.dybcio at linaro.org  Mon Feb 19 05:35:50 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 14:35:50 +0100
Subject: [PATCH 5/8] drm/msm/adreno: Add missing defines for A702
In-Reply-To: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v1-5-d260fa854707@linaro.org>

Add some defines required for A702. Can be substituted with a header
sync after merging mesa!27665 [1].

[1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27665
Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 drivers/gpu/drm/msm/adreno/a6xx.xml.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
index 863b5e3b0e67..1ec4dbc0e746 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
@@ -1945,6 +1945,24 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00
 
 #define REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE			0x00000122
 
+#define REG_A6XX_RBBM_CLOCK_CNTL_FCHE				0x00000123
+
+#define REG_A6XX_RBBM_CLOCK_DELAY_FCHE				0x00000124
+
+#define REG_A6XX_RBBM_CLOCK_HYST_FCHE				0x00000125
+
+#define REG_A6XX_RBBM_CLOCK_CNTL_MHUB				0x00000126
+
+#define REG_A6XX_RBBM_CLOCK_DELAY_MHUB				0x00000127
+
+#define REG_A6XX_RBBM_CLOCK_HYST_MHUB				0x00000128
+
+#define REG_A6XX_RBBM_CLOCK_DELAY_GLC				0x00000129
+
+#define REG_A6XX_RBBM_CLOCK_HYST_GLC				0x0000012a
+
+#define REG_A6XX_RBBM_CLOCK_CNTL_GLC				0x0000012b
+
 #define REG_A7XX_RBBM_CLOCK_HYST2_VFD				0x0000012f
 
 #define REG_A6XX_RBBM_LPAC_GBIF_CLIENT_QOS_CNTL			0x000005ff

-- 
2.43.2



From konrad.dybcio at linaro.org  Mon Feb 19 05:35:51 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 14:35:51 +0100
Subject: [PATCH 6/8] drm/msm/adreno: Add A702 support
In-Reply-To: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v1-6-d260fa854707@linaro.org>

The A702 is a weird mix of 600 and 700 series.. Perhaps even a
testing ground for some A7xx features with good ol' A6xx silicon.
It's basically A610 that's been beefed up with some new registers
and hw features (like APRIV!), that was then cut back in size,
memory bus and some other ways.

Add support for it, tested with QCM2290 / RB1.

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c      | 92 +++++++++++++++++++++++++++---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 18 ++++++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h    | 16 +++++-
 3 files changed, 117 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c9c55e2ea584..2a491a486ca1 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -837,6 +837,65 @@ const struct adreno_reglist a690_hwcg[] = {
 	{}
 };
 
+const struct adreno_reglist a702_hwcg[] = {
+	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002 },
+	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
+	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_FCHE, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_FCHE, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_FCHE, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GLC, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GLC, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GLC, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_MHUB, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_MHUB, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_MHUB, 0x00000000 },
+	{}
+};
+
 const struct adreno_reglist a730_hwcg[] = {
 	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222 },
 	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022222 },
@@ -968,6 +1027,8 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 		clock_cntl_on = 0x8aa8aa02;
 	else if (adreno_is_a610(adreno_gpu))
 		clock_cntl_on = 0xaaa8aa82;
+	else if (adreno_is_a702(adreno_gpu))
+		clock_cntl_on = 0xaaaaaa82;
 	else
 		clock_cntl_on = 0x8aa8aa82;
 
@@ -989,14 +1050,14 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 		return;
 
 	/* Disable SP clock before programming HWCG registers */
-	if (!adreno_is_a610(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
+	if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
 		gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0);
 
 	for (i = 0; (reg = &adreno_gpu->info->hwcg[i], reg->offset); i++)
 		gpu_write(gpu, reg->offset, state ? reg->value : 0);
 
 	/* Enable SP clock */
-	if (!adreno_is_a610(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
+	if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
 		gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1);
 
 	gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0);
@@ -1224,7 +1285,7 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu)
 	const u32 *regs = a6xx_protect;
 	unsigned i, count, count_max;
 
-	if (adreno_is_a650(adreno_gpu)) {
+	if (adreno_is_a650(adreno_gpu) || adreno_is_a702(adreno_gpu)) {
 		regs = a650_protect;
 		count = ARRAY_SIZE(a650_protect);
 		count_max = 48;
@@ -1320,6 +1381,12 @@ static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
 		gpu->ubwc_config.rgb565_predicator = 1;
 		gpu->ubwc_config.uavflagprd_inv = 2;
 	}
+
+	if (adreno_is_a702(gpu)) {
+		gpu->ubwc_config.highest_bank_bit = 14;
+		gpu->ubwc_config.min_acc_len = 1;
+		gpu->ubwc_config.ubwc_mode = 2;
+	}
 }
 
 static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
@@ -1453,7 +1520,7 @@ static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu,
 		return false;
 
 	/* A7xx is safe! */
-	if (adreno_is_a7xx(adreno_gpu))
+	if (adreno_is_a7xx(adreno_gpu) || adreno_is_a702(adreno_gpu))
 		return true;
 
 	/*
@@ -1671,7 +1738,7 @@ static int hw_init(struct msm_gpu *gpu)
 	a6xx_set_hwcg(gpu, true);
 
 	/* VBIF/GBIF start*/
-	if (adreno_is_a610(adreno_gpu) ||
+	if (adreno_is_a610_family(adreno_gpu) ||
 	    adreno_is_a640_family(adreno_gpu) ||
 	    adreno_is_a650_family(adreno_gpu) ||
 	    adreno_is_a7xx(adreno_gpu)) {
@@ -1705,6 +1772,7 @@ static int hw_init(struct msm_gpu *gpu)
 	}
 
 	if (!(adreno_is_a650_family(adreno_gpu) ||
+	      adreno_is_a702(adreno_gpu) ||
 	      adreno_is_a730(adreno_gpu))) {
 		gmem_range_min = adreno_is_a740_family(adreno_gpu) ? SZ_16M : SZ_1M;
 
@@ -1725,7 +1793,7 @@ static int hw_init(struct msm_gpu *gpu)
 	if (adreno_is_a640_family(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
-	} else if (adreno_is_a610(adreno_gpu)) {
+	} else if (adreno_is_a610_family(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x00800060);
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x40201b16);
 	} else if (!adreno_is_a7xx(adreno_gpu)) {
@@ -1740,13 +1808,18 @@ static int hw_init(struct msm_gpu *gpu)
 	if (adreno_is_a610(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 48);
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 47);
+	} else if (adreno_is_a702(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 64);
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 63);
 	} else if (!adreno_is_a7xx(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
 
 	/* Setting the primFifo thresholds default values,
 	 * and vccCacheSkipDis=1 bit (0x200) for A640 and newer
 	*/
-	if (adreno_is_a690(adreno_gpu))
+	if (adreno_is_a702(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x0000c000);
+	else if (adreno_is_a690(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00800200);
 	else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
@@ -1786,7 +1859,7 @@ static int hw_init(struct msm_gpu *gpu)
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4fffff);
 	else if (adreno_is_a619(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff);
-	else if (adreno_is_a610(adreno_gpu))
+	else if (adreno_is_a610(adreno_gpu) || adreno_is_a702(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3ffff);
 	else
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff);
@@ -1822,6 +1895,9 @@ static int hw_init(struct msm_gpu *gpu)
 		else
 			gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1);
 		gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0);
+	} else if (adreno_is_a702(adreno_gpu)) {
+		/* Something to do with the HLSQ cluster */
+		gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(24));
 	}
 
 	if (adreno_is_a690(adreno_gpu))
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 2ce7d7b1690d..b121abc71338 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -492,6 +492,24 @@ static const struct adreno_info gpulist[] = {
 		.zapfw = "a690_zap.mdt",
 		.hwcg = a690_hwcg,
 		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x07000200),
+		.family = ADRENO_6XX_GEN1, /* NOT a mistake! */
+		.fw = {
+			[ADRENO_FW_SQE] = "a702_sqe.fw",
+		},
+		.gmem = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a702_zap.mbn",
+		.hwcg = a702_hwcg,
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 236, 1 },
+			{ 178, 2 },
+			{ 142, 3 },
+		),
 	}, {
 		.chip_ids = ADRENO_CHIP_IDS(0x07030001),
 		.family = ADRENO_7XX_GEN1,
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index bc14df96feb0..f451881a6ddf 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -77,7 +77,7 @@ struct adreno_reglist {
 };
 
 extern const struct adreno_reglist a612_hwcg[], a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[];
-extern const struct adreno_reglist a660_hwcg[], a690_hwcg[], a730_hwcg[], a740_hwcg[];
+extern const struct adreno_reglist a660_hwcg[], a690_hwcg[], a702_hwcg[], a730_hwcg[], a740_hwcg[];
 
 struct adreno_speedbin {
 	uint16_t fuse;
@@ -382,6 +382,20 @@ static inline int adreno_is_a690(const struct adreno_gpu *gpu)
 	return gpu->info->chip_ids[0] == 0x06090000;
 }
 
+static inline int adreno_is_a702(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x07000200;
+}
+
+static inline int adreno_is_a610_family(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+
+	/* TODO: A612 */
+	return adreno_is_a610(gpu) || adreno_is_a702(gpu);
+}
+
 /* check for a615, a616, a618, a619 or any a630 derivatives */
 static inline int adreno_is_a630_family(const struct adreno_gpu *gpu)
 {

-- 
2.43.2



From konrad.dybcio at linaro.org  Mon Feb 19 05:35:52 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 14:35:52 +0100
Subject: [PATCH 7/8] arm64: dts: qcom: qcm2290: Add GPU nodes
In-Reply-To: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v1-7-d260fa854707@linaro.org>

Describe the GPU hardware on the QCM2290.

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 arch/arm64/boot/dts/qcom/qcm2290.dtsi | 154 ++++++++++++++++++++++++++++++++++
 1 file changed, 154 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi
index 89beac833d43..ec5aef5d9c69 100644
--- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/clock/qcom,dispcc-qcm2290.h>
 #include <dt-bindings/clock/qcom,gcc-qcm2290.h>
+#include <dt-bindings/clock/qcom,qcm2290-gpucc.h>
 #include <dt-bindings/clock/qcom,rpmcc.h>
 #include <dt-bindings/dma/qcom-gpi.h>
 #include <dt-bindings/firmware/qcom,scm.h>
@@ -737,6 +738,11 @@ qusb2_hstx_trim: hstx-trim at 25b {
 				reg = <0x25b 0x1>;
 				bits = <1 4>;
 			};
+
+			gpu_speed_bin: gpu-speed-bin at 2006 {
+				reg = <0x2006 0x2>;
+				bits = <5 8>;
+			};
 		};
 
 		pmu at 1b8e300 {
@@ -1383,6 +1389,154 @@ usb_dwc3: usb at 4e00000 {
 			};
 		};
 
+		gpu: gpu at 5900000 {
+			compatible = "qcom,adreno-07000200", "qcom,adreno";
+			reg = <0x0 0x05900000 0x0 0x40000>;
+			reg-names = "kgsl_3d0_reg_memory";
+
+			interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gpucc GPU_CC_GX_GFX3D_CLK>,
+				 <&gpucc GPU_CC_AHB_CLK>,
+				 <&gcc GCC_BIMC_GPU_AXI_CLK>,
+				 <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gpucc GPU_CC_CX_GMU_CLK>,
+				 <&gpucc GPU_CC_CXO_CLK>;
+			clock-names = "core",
+				      "iface",
+				      "mem_iface",
+				      "alt_mem_iface",
+				      "gmu",
+				      "xo";
+
+			interconnects = <&bimc MASTER_GFX3D RPM_ALWAYS_TAG
+					 &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>;
+			interconnect-names = "gfx-mem";
+
+			iommus = <&adreno_smmu 0 1>,
+				 <&adreno_smmu 2 0>;
+			operating-points-v2 = <&gpu_opp_table>;
+			power-domains = <&rpmpd QCM2290_VDDCX>;
+			qcom,gmu = <&gmu_wrapper>;
+
+			nvmem-cells = <&gpu_speed_bin>;
+			nvmem-cell-names = "speed_bin";
+			#cooling-cells = <2>;
+
+			status = "disabled";
+
+			zap-shader {
+				memory-region = <&pil_gpu_mem>;
+			};
+
+			gpu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				/* TODO: Scale RPM_SMD_BIMC_GPU_CLK w/ turbo freqs */
+				opp-1123200000 {
+					opp-hz = /bits/ 64 <1123200000>;
+					required-opps = <&rpmpd_opp_turbo_plus>;
+					opp-peak-kBps = <6881000>;
+					opp-supported-hw = <0x3>;
+					turbo-mode;
+				};
+
+				opp-1017600000 {
+					opp-hz = /bits/ 64 <1017600000>;
+					required-opps = <&rpmpd_opp_turbo>;
+					opp-peak-kBps = <6881000>;
+					opp-supported-hw = <0x3>;
+					turbo-mode;
+				};
+
+				opp-921600000 {
+					opp-hz = /bits/ 64 <921600000>;
+					required-opps = <&rpmpd_opp_nom_plus>;
+					opp-peak-kBps = <6881000>;
+					opp-supported-hw = <0x3>;
+				};
+
+				opp-844800000 {
+					opp-hz = /bits/ 64 <844800000>;
+					required-opps = <&rpmpd_opp_nom>;
+					opp-peak-kBps = <6881000>;
+					opp-supported-hw = <0x7>;
+				};
+
+				opp-672000000 {
+					opp-hz = /bits/ 64 <672000000>;
+					required-opps = <&rpmpd_opp_svs_plus>;
+					opp-peak-kBps = <3879000>;
+					opp-supported-hw = <0xf>;
+				};
+
+				opp-537600000 {
+					opp-hz = /bits/ 64 <537600000>;
+					required-opps = <&rpmpd_opp_svs>;
+					opp-peak-kBps = <2929000>;
+					opp-supported-hw = <0xf>;
+				};
+
+				opp-355200000 {
+					opp-hz = /bits/ 64 <355200000>;
+					required-opps = <&rpmpd_opp_low_svs>;
+					opp-peak-kBps = <1720000>;
+					opp-supported-hw = <0xf>;
+				};
+			};
+		};
+
+		gmu_wrapper: gmu at 596a000 {
+			compatible = "qcom,adreno-gmu-wrapper";
+			reg = <0x0 0x0596a000 0x0 0x30000>;
+			reg-names = "gmu";
+			power-domains = <&gpucc GPU_CX_GDSC>,
+					<&gpucc GPU_GX_GDSC>;
+			power-domain-names = "cx",
+					     "gx";
+		};
+
+		gpucc: clock-controller at 5990000 {
+			compatible = "qcom,qcm2290-gpucc";
+			reg = <0x0 0x05990000 0x0 0x9000>;
+			clocks = <&gcc GCC_GPU_CFG_AHB_CLK>,
+				 <&rpmcc RPM_SMD_XO_CLK_SRC>,
+				 <&gcc GCC_GPU_GPLL0_CLK_SRC>,
+				 <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
+			power-domains = <&rpmpd QCM2290_VDDCX>;
+			required-opps = <&rpmpd_opp_low_svs>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		adreno_smmu: iommu at 59a0000 {
+			compatible = "qcom,qcm2290-smmu-500", "qcom,adreno-smmu",
+				     "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x059a0000 0x0 0x10000>;
+			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+				 <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>;
+			clock-names = "mem",
+				      "hlos",
+				      "iface";
+
+			power-domains = <&gpucc GPU_CX_GDSC>;
+
+			#global-interrupts = <1>;
+			#iommu-cells = <2>;
+		};
+
 		mdss: display-subsystem at 5e00000 {
 			compatible = "qcom,qcm2290-mdss";
 			reg = <0x0 0x05e00000 0x0 0x1000>;

-- 
2.43.2



From konrad.dybcio at linaro.org  Mon Feb 19 05:35:53 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 14:35:53 +0100
Subject: [PATCH 8/8] arm64: dts: qcom: qrb2210-rb1: Enable the GPU
In-Reply-To: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v1-8-d260fa854707@linaro.org>

Enable the A702 GPU (also marketed as "3D accelerator by qcom [1], lol).

[1] https://docs.qualcomm.com/bundle/publicresource/87-61720-1_REV_A_QUALCOMM_ROBOTICS_RB1_PLATFORM__QUALCOMM_QRB2210__PRODUCT_BRIEF.pdf
Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
index 6e9dd0312adc..c9abca5a7e39 100644
--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
+++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
@@ -199,6 +199,14 @@ &gpi_dma0 {
 	status = "okay";
 };
 
+&gpu {
+	status = "okay";
+
+	zap-shader {
+		firmware-name = "qcom/qcm2290/a702_zap.mbn";
+	};
+};
+
 &i2c2 {
 	clock-frequency = <400000>;
 	status = "okay";

-- 
2.43.2



From theo.lebrun at bootlin.com  Mon Feb 19 05:41:24 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 19 Feb 2024 14:41:24 +0100
Subject: [PATCH 02/13] dt-bindings: i2c: nomadik: add mobileye,eyeq5-i2c
 bindings and example
In-Reply-To: <cf360cbf-7414-4024-8bdd-d2aba7f048b3@linaro.org>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>
 <20240216022227.GA850600-robh@kernel.org>
 <CZ6FD7EHIJDT.32IEDVT9FG2GP@bootlin.com>
 <6effca50-29a4-43b9-86eb-310bd4e08e5c@linaro.org>
 <CZ6FUECKEX2B.36QWZZA5EYPI@bootlin.com>
 <cf360cbf-7414-4024-8bdd-d2aba7f048b3@linaro.org>
Message-ID: <CZ93KAA53F8G.38AUM6RZGUYY7@bootlin.com>

Hello,

On Sat Feb 17, 2024 at 9:25 AM CET, Krzysztof Kozlowski wrote:
> On 16/02/2024 11:40, Th?o Lebrun wrote:
> > On Fri Feb 16, 2024 at 11:33 AM CET, Krzysztof Kozlowski wrote:
> >> On 16/02/2024 11:18, Th?o Lebrun wrote:
> >>>
> >>>>> +        mobileye,id:
> >>>>> +          $ref: /schemas/types.yaml#/definitions/uint32
> >>>>> +          description: Platform-wide controller ID (integer starting from zero).
> >>>>
> >>>> instance indexes are a NAK. You can use i2cN aliases if you must.
> >>>>
> >>>> Why do you need it? To access OLB? If so, add cell args to the OLB 
> >>>> phandle instead.
> >>>
> >>> Why we do what we do: I2C controller must write a 2 bit value depending
> >>> on the bus speed. All I2C controllers write into the same register.
> >>
> >> Which register?  Your devices do not share IO address space.
> > 
> > mobileye,olb is a prop with a phandle to a syscon. That syscon contains
> > the register we are interested in.
>
> So exactly what Rob said... I don't understand why you have chosen to go
> with alias.

I had misunderstood Rob's original message. Now that I've done some
tests to use cells I get what was meant. I'd have a follow-up question.
What should the cells contain? I see two options:

 - phandle + I2C controller global index (from 0 thru 4). Then Linux
   (or other) driver know how to map that index to register + mask
   combo. ie:

      i2c2: i2c at 500000 {
         compatible = "mobileye,eyeq5-i2c", "arm,primecell";
         reg = <0 0x500000 0x0 0x1000>;
         /* ... */
         mobileye,olb = <&olb 2>;
      };

 - phandle + register offset + mask. ie:

      i2c2: i2c at 500000 {
         compatible = "mobileye,eyeq5-i2c", "arm,primecell";
         reg = <0 0x500000 0x0 0x1000>;
         /* ... */
         mobileye,olb = <&olb 0xB8 0x300>; /* phandle + offset + mask */
      };

I would have guessed the second approach was frown upon as DT aren't
meant to contain iomem offsets. However I'm seeing quite a few drivers
using this approach, and no driver doing the first approach. Maybe my
instinct isn't leading me the right way.

See those bindings that use the second approach. They were found because
their drivers use the syscon_regmap_lookup_by_phandle_args() function
call. I've added the file creation date to highlight recent bindings
(that hopefully are closer to the right way).
 - phy/starfive,jh7110-pcie-phy.yaml    2023-06-29T15:51:12+08:00
 - usb/starfive,jh7110-usb.yaml         2023-05-18T19:27:48+08:00
 - net/starfive,jh7110-dwmac.yaml       2023-04-17T18:02:49+08:00
 - phy/qcom,sc8280xp-qmp-pcie-phy.yaml  2022-11-05T15:59:34+01:00
 - sound/snps,designware-i2s.yaml       2022-07-01T20:22:49+01:00
 - pinctrl/canaan,k210-fpioa.yaml       2020-12-13T22:50:44+09:00
 - media/ti,cal.yaml                    2019-11-12T15:53:47+01:00

I know looking at existing drivers/bindings isn't the right way, but I
have no other frame of reference. That's why I'm asking for guidance on
this one.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

------------------------------------------------------------------------



From ricardo at marliere.net  Mon Feb 19 05:43:05 2024
From: ricardo at marliere.net (Ricardo B. Marliere)
Date: Mon, 19 Feb 2024 10:43:05 -0300
Subject: [PATCH] coresight: constify the struct device_type usage
Message-ID: <20240219-device_cleanup-coresight-v1-1-4a8a0b816183@marliere.net>

Since commit aed65af1cc2f ("drivers: make device_type const"), the driver
core can properly handle constant struct device_type. Move the
coresight_dev_type variable to be a constant structure as well, placing it
into read-only memory which can not be modified at runtime.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
---
 drivers/hwtracing/coresight/coresight-priv.h  | 2 +-
 drivers/hwtracing/coresight/coresight-sysfs.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index eb365236f9a9..ca3362cbdb70 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -13,7 +13,7 @@
 #include <linux/pm_runtime.h>
 
 extern struct mutex coresight_mutex;
-extern struct device_type coresight_dev_type[];
+extern const struct device_type coresight_dev_type[];
 
 /*
  * Coresight management registers (0xf00-0xfcc)
diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
index f9444e2cb1d9..1e67cc7758d7 100644
--- a/drivers/hwtracing/coresight/coresight-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-sysfs.c
@@ -377,7 +377,7 @@ static struct attribute *coresight_source_attrs[] = {
 };
 ATTRIBUTE_GROUPS(coresight_source);
 
-struct device_type coresight_dev_type[] = {
+const struct device_type coresight_dev_type[] = {
 	[CORESIGHT_DEV_TYPE_SINK] = {
 		.name = "sink",
 		.groups = coresight_sink_groups,

---
base-commit: c099fdd218a0fedfe87e0b88d2ba0667eab3b3c8
change-id: 20240219-device_cleanup-coresight-00ba00fd5f21

Best regards,
-- 
Ricardo B. Marliere <ricardo at marliere.net>



From broonie at kernel.org  Mon Feb 19 05:42:29 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 19 Feb 2024 13:42:29 +0000
Subject: [PATCH] arm64/sysreg: Add register fields for ID_AA64DFR1_EL1
In-Reply-To: <785e9bd7-f47b-4e8f-9291-0616aa87fa27@arm.com>
References: <20240215065454.2489075-1-anshuman.khandual@arm.com>
 <d2722ae9-d29c-41f9-9eec-f829589adf6e@sirena.org.uk>
 <785e9bd7-f47b-4e8f-9291-0616aa87fa27@arm.com>
Message-ID: <6ec0f73f-cbac-44c5-a215-d3754ce6a5d8@sirena.org.uk>

On Sun, Feb 18, 2024 at 06:04:34AM +0530, Anshuman Khandual wrote:

> Just wondering - would something like the following make sense. Because
> 0b0000 signifies that the cycle counter would just ignore PMCR_EL0.FZS,
> where as it gets frozen with 0b0001.

> UnsignedEnum   55:52   DPFZS
>        0b0000  IGNR
>        0b0001  FRZN
> EndEnum

LGTM.
-------------- 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/20240219/f134579e/attachment.sig>

From mwalle at kernel.org  Mon Feb 19 05:59:16 2024
From: mwalle at kernel.org (Michael Walle)
Date: Mon, 19 Feb 2024 14:59:16 +0100
Subject: [PATCH v2 2/2] arm64: dts: mediatek: add Kontron 3.5"-SBC-i1200
In-Reply-To: <b50d49fd-2976-46fc-9f35-354fb39720ad@collabora.com>
References: <20240219084456.1075445-1-mwalle@kernel.org>
 <20240219084456.1075445-2-mwalle@kernel.org>
 <2ad6bda8-a457-421b-b35d-dc005fb00ae9@collabora.com>
 <CZ92W3VSYV1A.1693O76GY1XDP@kernel.org>
 <b50d49fd-2976-46fc-9f35-354fb39720ad@collabora.com>
Message-ID: <CZ93XYV3MB10.YRCFWLLHIICY@kernel.org>

On Mon Feb 19, 2024 at 2:35 PM CET, AngeloGioacchino Del Regno wrote:
> >> vbus is always supplied by something, as otherwise USB won't work - whether this
> >> is an always-on regulator or a passthrough from external supply this doesn't really
> >> matter - you should model a regulator-fixed that provides the 5V VBUS line.
> > 
> > I don't think this is correct, though. Think of an on-board USB
> > hub. There only D+/D- are connected (and maybe the USB3.2 SerDes
> > lanes). Or have a look at the M.2 pinout. There is no Vbus.
> > 
>
> Yes but the MediaTek MTU3 and/or controllers do have it ;-)

.. and ..

> >> For example:
> >> 	vbus_fixed: regulator-vbus {
> >> 		compatible = "regulator-fixed";
> >> 		regulator-name = "usb-vbus";
> >> 		regulator-always-on;
> >> 		regulator-boot-on;
> >> 		regulator-min-microvolt = <5000000>;
> >> 		regulator-max-microvolt = <5000000>;
> >> 	};
> > 
> > As mentioned above, I don't think this will make sense in my case.
> >  >> P.S.: If the rail has a different name, please use that different name. Obviously
> >> that requires you to have schematics at hand, and I don't know if you do: if you
> >> don't, then that regulator-vbus name is just fine.
> > 
> > I do have the schematics.
>
> In that case, you should model the power tree with the fixed power lines,
> check mt8195-cherry (and/or cherry-tomato) and radxa-nio-12l; even though
> those are technically "doing nothing", this is device tree, so it should
> provide a description of the hardware ... and the board does have fixed
> power lines.
> It has at least one: DC-IN (typec, barrel jack or whatever, the board needs
> power, doesn't it?!).

Mh, maybe I don't get it. But within the hardware there is simply no
Vbus. Thus I'd argue it doesn't make sense to have a vbus-supply
property. Besides, the mediatek,mtu3.yaml binding lists it as
deprecated anyway and it should rather be on the connector. There,
it makes perfectly sense (at least if it's a USB connector).

Thus in my case, the xhci for the front port has a vbus-supply
property (but it should rather have a connector node, as I've just
learned). But the internal port which connects to the USB hub
shouldn't have one.


  +-----+           +-----+                  +------+
  |     |<--Dp/Dn-->|     |<------Dp/Dn----->| USB  |
  | SoC |           |     |                  | Conn |
  |     |           |     |   +-----+        |      |
  +-----+           | USB |   | PWR |--Vbus->|      |
                    | Hub |   | SW  |        +------+
                    |     |   +-----+
                    |     |     ^
                    |     |     | PRTPWR
                    |     |-----'
                    +-----+

"PWR SW" is a power switch, the input (+5V) isn't shown here. The
power will be enabled by the USB Hub.

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

From mirela.rabulea at oss.nxp.com  Mon Feb 19 05:59:37 2024
From: mirela.rabulea at oss.nxp.com (Mirela Rabulea OSS)
Date: Mon, 19 Feb 2024 15:59:37 +0200
Subject: [PATCH] media: imx-jpeg: Support for negotiating bytesperline
 with client
In-Reply-To: <20240205072556.804809-1-ming.qian@nxp.com>
References: <20240205072556.804809-1-ming.qian@nxp.com>
Message-ID: <ed209781-78ed-45f5-8266-eb0376a559a3@oss.nxp.com>

Hi Ming,

On 05.02.2024 09:25, Ming Qian wrote:
> This mxc-jpeg driver doesn't allow the client to set the bytesperline,
> but for some android cts case, it need to negotiate the bytesperline
> between decoder and display, and fail the case if driver doesn't support
> negotiating bytesperline
> 
> The jpegdec and jpegenc does support to set bytesperline which is
> multiple of 2, and greater than the value calulated by driver.
> 
> Signed-off-by: Ming Qian <ming.qian at nxp.com>

There is a typo in the commit message: calulated.
Other than that,
Reviewed-by: Mirela Rabulea <mirela.rabulea at nxp.com>

Regards,
Mirela

> ---
>   drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 16 ++++++++++++++++
>   drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h |  1 +
>   2 files changed, 17 insertions(+)
> 
> diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> index 64112b63298c..cc97790ed30f 100644
> --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
> @@ -1373,6 +1373,8 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
>   		q_data_cap->crop.top = 0;
>   		q_data_cap->crop.width = jpeg_src_buf->w;
>   		q_data_cap->crop.height = jpeg_src_buf->h;
> +		q_data_cap->bytesperline[0] = 0;
> +		q_data_cap->bytesperline[1] = 0;
>   
>   		/*
>   		 * align up the resolution for CAST IP,
> @@ -1752,6 +1754,14 @@ static u32 mxc_jpeg_get_image_format(struct device *dev,
>   
>   static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision)
>   {
> +	u32 bytesperline[2];
> +
> +	bytesperline[0] = q->bytesperline[0];
> +	bytesperline[1] = q->bytesperline[0];	/*imx-jpeg only support the same line pitch*/
> +	v4l_bound_align_image(&bytesperline[0], 0, MXC_JPEG_MAX_LINE, 2,
> +			      &bytesperline[1], 0, MXC_JPEG_MAX_LINE, 2,
> +			      0);
> +
>   	/* Bytes distance between the leftmost pixels in two adjacent lines */
>   	if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
>   		/* bytesperline unused for compressed formats */
> @@ -1775,6 +1785,12 @@ static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision)
>   		q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8);
>   		q->bytesperline[1] = 0;
>   	}
> +
> +	if (q->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
> +		q->bytesperline[0] = max(q->bytesperline[0], bytesperline[0]);
> +		if (q->fmt->mem_planes > 1)
> +			q->bytesperline[1] = max(q->bytesperline[1], bytesperline[1]);
> +	}
>   }
>   
>   static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
> diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
> index dc4afeeff5b6..86e324b21aed 100644
> --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
> +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
> @@ -22,6 +22,7 @@
>   #define MXC_JPEG_MIN_HEIGHT		64
>   #define MXC_JPEG_MAX_WIDTH		0x2000
>   #define MXC_JPEG_MAX_HEIGHT		0x2000
> +#define MXC_JPEG_MAX_LINE		0x8000
>   #define MXC_JPEG_MAX_CFG_STREAM		0x1000
>   #define MXC_JPEG_H_ALIGN		3
>   #define MXC_JPEG_W_ALIGN		3


From sebastian.wick at redhat.com  Mon Feb 19 06:01:44 2024
From: sebastian.wick at redhat.com (Sebastian Wick)
Date: Mon, 19 Feb 2024 15:01:44 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi:
 Add Broadcast RGB property
In-Reply-To: <2mih3humepuedtli7ge52ncom4uffkqravdpalncgfyucmwdzc@bp5o7i3ky77a>
References: <Zb0M_2093UwPXK8y@intel.com>
 <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
 <20240212170618.GA1372043@toolbox>
 <2mih3humepuedtli7ge52ncom4uffkqravdpalncgfyucmwdzc@bp5o7i3ky77a>
Message-ID: <20240219140144.GB1956149@toolbox>

On Thu, Feb 15, 2024 at 12:00:01PM +0100, Maxime Ripard wrote:
> On Mon, Feb 12, 2024 at 06:06:18PM +0100, Sebastian Wick wrote:
> > On Mon, Feb 12, 2024 at 05:53:48PM +0100, Maxime Ripard wrote:
> > > On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> > > > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > > > > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > > > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > > > > Hi,
> > > > > > > > > > > 
> > > > > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > > > > >  /**
> > > > > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > > > > >   *
> > > > > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > + *      Full:
> > > > > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > > > > + *
> > > > > > > > > > > > > 
> > > > > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > > > > different things being affected:
> > > > > > > > > > > > > 
> > > > > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > > > > 
> > > > > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > > > > 
> > > > > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > > > > signalling, what happens?
> > > > > > > > > > > > 
> > > > > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > > > > YCbCr?
> > > > > > > > > > > 
> > > > > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > > > > vc4 will follow the value of the property.
> > > > > > > > > > 
> > > > > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > > > > That should explain why it's only affecting RGB.
> > > > > > > > > 
> > > > > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > > > > itself.
> > > > > > > > > 
> > > > > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > > > > to enable it.
> > > > > > > > > 
> > > > > > > > > vc4 supports it.
> > > > > > > > 
> > > > > > > > Someone implemented it incorrectly then.
> > > > > > > 
> > > > > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > > > > document any of it, and when people try to clean things up they get told
> > > > > > > that we got it all wrong.
> > > > > > 
> > > > > > FWIW, this was an i915 property and if another driver uses the same
> > > > > > property name it must have the same behavior. Yes, it isn't standardized
> > > > > > and yes, it's not documented (hence this effort here) but it's still on
> > > > > > vc4 to make the property compatible.
> > > > > 
> > > > > How is it not compatible? It's a superset of what i915 provides, but
> > > > > it's strictly compatible with it.
> > > > 
> > > > No it is not.
> > > 
> > > The property is compatible with i915 interpretation of it, whether you
> > > like it or not. And that's what Sebastian was referring to.
> > > 
> > > > Eg. what happens if you set the thing to full range for RGB (which you
> > > > must on many broken monitors), and then the kernel automagically
> > > > switches to YCbCr (for whatever reason) but the monitor doesn't
> > > > support full range YCbCr? Answer: you get crap output.
> > > 
> > > And that part is just moving goalposts.
> > 
> > But it's really not.
> 
> It really is. This whole discussion started by "well it would be nice if
> we made that property handled by the core", and we're now at the "we
> need to deal with broken YCbCr displays and i915 opinion about them"
> stage. After creating documentation, unit tests, etc. It's the textbook
> definition of moving goalposts. And while i915 won't be affected by all
> that work.

Sorry, but what you're saying is just not true.

The Broadcast RGB property is an Intel specific property. It lacked
documentation but the user space contract exists and it based on how
i915 implemented it. By changing the semantics you're breaking user
space. The documentation has to document the current contract between
i915 and user space, not whatever you want the property to be like.

I get that you're frustrated that you have to do work while i915 doesn't
but none of that is relevant for what the property is and how user space
expects it to work.

> That series has been stuck for multiple iterations on pointless and
> mundane debates while the biggest part and whole point of it is not
> getting any review. So yeah, sorry, it's frustrating.

I'm reviewing the parts that I can, and that's the uAPI. I find it
really offensive that you're saying that this is pointless and mundate.
The uAPI is your end product, if it can't be used, everything you do in
your driver is utterly pointless.

> > The Broadcast RGB property kind of works from a user space perspective
> > because it's a workaround for broken sinks. If a sink expects limited
> > range we can force full range. If this however affects YCbCr modes as
> > well, then this isn't a workaround for broken RGB range anymore
> > because it now breaks YCbCr.
> 
> Or, you know, it's a workaround for broken YCbCr display.

Displays can accept both RGB and YCbCr signals, drivers can chose
whichever they want, and user space can not influence or even know which
one is being used.

The automatic selection of the range is very different between RGB and
YCbCr. If user space forces the range to a specific value and the driver
for whatever reason switches from RGB to YCbCr or the other way around,
this forcing of the range will most likely be incorrect.

This is what we're talking about when we say that the semantics of the
vc4 Broadcast RGB property is broken. User space literally cannot use it
consistenly. By restricting it to RGB signals, user space can user it
consistently and fix monitors that do not follow the automatic
quantization range algorithm correctly. Yes, if there is an issue with
the quantization range of a YCbCr signal then this property doesn't
help, but it never tried to help those cases.

> > Sorry, but vc4 just has to change.
> > 
> > And again: let's please stop trying to improve the property.
> 
> I'm not. I'm super close to just dropping that patch entirely and keep
> the current situation that seems to work fine for everyone.

I mean, vc4 doesn't work fine apparently. You're just lucky that no one
reported issues to you.

All you have to do is adjust the documentation to say that Broadcast RGB
only affects RGB signalling. Yes, vc4 has a bug according to the docs
then, but that's okay. Fix it at some point.

> Maxime




From linus.walleij at linaro.org  Mon Feb 19 06:06:44 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:06:44 +0100
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com> <20240216022704.GB850600-robh@kernel.org>
 <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>
Message-ID: <CACRpkdZZhhzg5SY7U5dv_OfLEVejRFom4V9nCfkQXunAw1ZXSw@mail.gmail.com>

Hi Th?o,

thanks for your patch!

On Fri, Feb 16, 2024 at 10:16?AM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> i2c-mpc (fsl,timeout) and i2c-gpio (i2c-gpio,timeout-ms). I agree this
> prop has no reason to be compatible-specific.
>
> Feedback from dt-bindings and I2C host maintainers would be useful: what
> should the property be named? Having the unit makes it self-descriptive,
> which sounds like a good idea to me. timeout-usecs, timeout-us, another
> option?

Use i2c-transfer-timeout-ms in my opinion, so it us crystal clear
what that property is for.

As Rob mentioned this isn't in the kernel schemas but in dtschema, so
you need to patch this:
https://github.com/robherring/dt-schema

Yours,
Linus Walleij


From linus.walleij at linaro.org  Mon Feb 19 06:11:14 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:11:14 +0100
Subject: [PATCH 00/13] Add Mobileye EyeQ5 support to the Nomadik I2C
 controller & use hrtimers for timeouts
In-Reply-To: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
Message-ID: <CACRpkdbmQLAL-W_2y_T4sBJtZN-DRXMsYhODP=sXSJ4ysUKpxQ@mail.gmail.com>

On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

>  - Add a new compatible to support Mobileye EyeQ5 which uses the same IP
>    block as Nomadik.

Sweet! I'm amazed ST Micro licensed this "ARM PrimeCell" to Mobileye, but
it's a well tested IP and used in eg ST automotive SoC:s so it's a solid
product.

It feels worth it for all the time I have put into maintaining it, finally some
real users again! :)

Yours,
Linus Walleij


From linus.walleij at linaro.org  Mon Feb 19 06:12:58 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:12:58 +0100
Subject: [PATCH 04/13] i2c: nomadik: rename private struct pointers from
 dev to priv
In-Reply-To: <20240215-mbly-i2c-v1-4-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com> <20240215-mbly-i2c-v1-4-19a336e91dca@bootlin.com>
Message-ID: <CACRpkdaZVOpR8twgOiPifUgQeUKcertU9kdpH_vCYBaE0UhziQ@mail.gmail.com>

On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> Disambiguate the usage of dev as a variable name; it is usually best to
> keep it reserved for struct device pointers. Avoid having multiple
> names for the same struct pointer (previously: dev, nmk, nmk_i2c).
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Fair enough, it's more readable like this.
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Mon Feb 19 06:15:36 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:15:36 +0100
Subject: [PATCH 05/13] i2c: nomadik: simplify IRQ masking logic
In-Reply-To: <20240215-mbly-i2c-v1-5-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com> <20240215-mbly-i2c-v1-5-19a336e91dca@bootlin.com>
Message-ID: <CACRpkdYZTrEKdGfN-EiOTWtQhhMHVqk5zCjmcAuUZq9aWesqFQ@mail.gmail.com>

On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> IRQ_MASK and I2C_CLEAR_ALL_INTS are redundant. One masks the top three
> bits off as reserved, the other one masks the reserved IRQs inside the
> u32. Get rid of IRQ_MASK and only use the most restrictive mask.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Yeah, more readable like this definitely.
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From tglx at linutronix.de  Mon Feb 19 06:16:32 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 19 Feb 2024 15:16:32 +0100
Subject: [PATCH 01/12] irqchip/stm32-exti: Fix minor indentation issue
In-Reply-To: <20240216094758.916722-2-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
 <20240216094758.916722-2-antonio.borneo@foss.st.com>
Message-ID: <87frxoa69r.ffs@tglx>

On Fri, Feb 16 2024 at 10:47, Antonio Borneo wrote:
> Use only TAB for indentation, removing a leading space.
>
> Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
> Fixes: 046a6ee2343b ("irqchip: Bulk conversion to generic_handle_domain_irq()")

A whitespace cleanup really does not justify a Fixes tag.

Thanks,

        tglx


From linus.walleij at linaro.org  Mon Feb 19 06:16:41 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:16:41 +0100
Subject: [PATCH 06/13] i2c: nomadik: use bitops helpers
In-Reply-To: <20240215-mbly-i2c-v1-6-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com> <20240215-mbly-i2c-v1-6-19a336e91dca@bootlin.com>
Message-ID: <CACRpkdaUJ6tM51o5tDSMURFS3u8J=dfMN+p4j04QNXdGUPzCXg@mail.gmail.com>

On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> Constant register bit fields are declared using hardcoded hex values;
> replace them by calls to BIT() and GENMASK(). Replace custom GEN_MASK()
> macro by the generic FIELD_PREP(). Replace manual bit manipulations by
> the generic FIELD_GET() macro.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

I'm a fan of this style.
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From tglx at linutronix.de  Mon Feb 19 06:19:49 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 19 Feb 2024 15:19:49 +0100
Subject: [PATCH 02/12] dt-bindings: interrupt-controller: stm32-exti:
 Add irq nexus child node
In-Reply-To: <20240216094758.916722-3-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
 <20240216094758.916722-3-antonio.borneo@foss.st.com>
Message-ID: <87cyssa64a.ffs@tglx>

On Fri, Feb 16 2024 at 10:47, Antonio Borneo wrote:
> The mapping of EXTI interrupts to its parent interrupt controller
> is both SoC and instance dependent.
> The current implementation requires adding a new table to the
> driver's code and a new compatible for each new EXTI instance.
>
> Add to the binding an interrupt nexus child node that will be
> used on the new EXTI instances and can be optionally used on the
> existing instances.
> The property 'interrupt-map' in the nexus node maps each EXTI
> interrupt to the parent interrupt.
> Align #address-cells and #interrupt-cells between the EXTI node
> and its nexus node.
>
> Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>

This S-O-B chain is broken as it suggests that you wrote the patch and
Fabrice relayed it.

https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin

But that's not the case. If you co-developed this with Fabrice then
please use Co-developed-by. See:

https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by

Thanks,

        tglx



From linus.walleij at linaro.org  Mon Feb 19 06:19:52 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:19:52 +0100
Subject: [PATCH 07/13] i2c: nomadik: support short xfer timeouts using
 waitqueue & hrtimer
In-Reply-To: <20240215-mbly-i2c-v1-7-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com> <20240215-mbly-i2c-v1-7-19a336e91dca@bootlin.com>
Message-ID: <CACRpkdYC=vVBA-s6GmsaED=NdXfsr0JDzzF+x8q8C3tqQ0F8YQ@mail.gmail.com>

On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> Replace the completion by a waitqueue for synchronization from IRQ
> handler to task. For short timeouts, use hrtimers, else use timers.
> Usecase: avoid blocking the I2C bus for too long when an issue occurs.
>
> The threshold picked is one jiffy: if timeout is below that, use
> hrtimers. This threshold is NOT configurable.
>
> Implement behavior but do NOT change fetching of timeout. This means the
> timeout is unchanged (200ms) and the hrtimer case will never trigger.
>
> A waitqueue is used because it supports both desired timeout approaches.
> See wait_event_timeout() and wait_event_hrtimeout(). An atomic boolean
> serves as synchronization condition.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Part of me want to go and fix completions to handle hrtimer timeouts
for submicrosecond timeouts, BUT I realized that this is a bit thick
request for a simple driver, so just a suggestion for something we could
do one day. This is fine with me.
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Mon Feb 19 06:21:27 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:21:27 +0100
Subject: [PATCH 08/13] i2c: nomadik: replace jiffies by ktime for FIFO
 flushing timeout
In-Reply-To: <20240215-mbly-i2c-v1-8-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com> <20240215-mbly-i2c-v1-8-19a336e91dca@bootlin.com>
Message-ID: <CACRpkdbuTX50syD0CMFcZXBmAHw4nwpcSc-C1OOUQEA9WHqCwA@mail.gmail.com>

On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> The FIFO flush function uses a jiffies amount to detect timeouts as the
> flushing is async. Replace with ktime to get more accurate precision
> and support short timeouts.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Excellent patch. Thanks.
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From tglx at linutronix.de  Mon Feb 19 06:22:34 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 19 Feb 2024 15:22:34 +0100
Subject: [PATCH 03/12] irqchip/stm32-exti: Map interrupts through
 interrupt nexus node
In-Reply-To: <20240216094758.916722-4-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
 <20240216094758.916722-4-antonio.borneo@foss.st.com>
Message-ID: <87a5nwa5zp.ffs@tglx>

On Fri, Feb 16 2024 at 10:47, Antonio Borneo wrote:
> diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
> index 69982f21126a..95bb3dd10b2c 100644
> --- a/drivers/irqchip/irq-stm32-exti.c
> +++ b/drivers/irqchip/irq-stm32-exti.c
> @@ -61,6 +61,7 @@ struct stm32_exti_host_data {
>  	struct stm32_exti_chip_data *chips_data;
>  	const struct stm32_exti_drv_data *drv_data;
>  	struct hwspinlock *hwlock;
> +	struct device_node *irq_map_node;

Please keep variable declarations ordered in reverse fir tree layout:

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations

>  };
>  
>  static struct stm32_exti_host_data *stm32_host_data;
> @@ -713,8 +714,9 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm,
>  	u8 desc_irq;
>  	struct irq_fwspec *fwspec = data;
>  	struct irq_fwspec p_fwspec;
> +	struct of_phandle_args out_irq;

Please move this into the condition path where it is actually used.

>  	irq_hw_number_t hwirq;
> -	int bank;
> +	int bank, ret;
>  	u32 event_trg;
>  	struct irq_chip *chip;
>  
> @@ -731,6 +733,25 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm,
>  
>  	irq_domain_set_hwirq_and_chip(dm, virq, hwirq, chip, chip_data);
>  
> +	if (host_data->irq_map_node) {
> +		out_irq.np = host_data->irq_map_node;

Thanks,

        tglx


From linus.walleij at linaro.org  Mon Feb 19 06:22:30 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:22:30 +0100
Subject: [PATCH 09/13] i2c: nomadik: fetch timeout-usecs property from devicetree
In-Reply-To: <20240215-mbly-i2c-v1-9-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com> <20240215-mbly-i2c-v1-9-19a336e91dca@bootlin.com>
Message-ID: <CACRpkdYWi6kcCnS9EGwp-Saa7ZXQvRN+Pn9gOLetT_6Hbwq0bA@mail.gmail.com>

On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> Allow overriding the default timeout value (200ms) from devicetree,
> using the timeout-usecs property.
>
> The i2c_adapter->timeout field is an unaccurate jiffies amount;
> i2c-nomadik uses hrtimers for timeouts below one jiffy.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Once we agree on the binding name:

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From theo.lebrun at bootlin.com  Mon Feb 19 06:22:51 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 19 Feb 2024 15:22:51 +0100
Subject: [PATCH 00/13] Add Mobileye EyeQ5 support to the Nomadik I2C
 controller & use hrtimers for timeouts
In-Reply-To: <CACRpkdbmQLAL-W_2y_T4sBJtZN-DRXMsYhODP=sXSJ4ysUKpxQ@mail.gmail.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <CACRpkdbmQLAL-W_2y_T4sBJtZN-DRXMsYhODP=sXSJ4ysUKpxQ@mail.gmail.com>
Message-ID: <CZ94G0Z1KZEJ.1S56H5MK9T1RU@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 3:11 PM CET, Linus Walleij wrote:
> On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> >  - Add a new compatible to support Mobileye EyeQ5 which uses the same IP
> >    block as Nomadik.
>
> Sweet! I'm amazed ST Micro licensed this "ARM PrimeCell" to Mobileye, but
> it's a well tested IP and used in eg ST automotive SoC:s so it's a solid
> product.
>
> It feels worth it for all the time I have put into maintaining it, finally some
> real users again! :)

Using the existing Nomadik drivers with the AMBA bus infrastructure on a
non-ARM platform and having it work as-is made our day here at Bootlin.
We are indeed grateful for your work maintaining this platform!

Regards,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

------------------------------------------------------------------------



From theo.lebrun at bootlin.com  Mon Feb 19 06:29:57 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 19 Feb 2024 15:29:57 +0100
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <CACRpkdZZhhzg5SY7U5dv_OfLEVejRFom4V9nCfkQXunAw1ZXSw@mail.gmail.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>
 <20240216022704.GB850600-robh@kernel.org>
 <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>
 <CACRpkdZZhhzg5SY7U5dv_OfLEVejRFom4V9nCfkQXunAw1ZXSw@mail.gmail.com>
Message-ID: <CZ94LGRSF9KN.15ZO1VRMIQVR8@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 3:06 PM CET, Linus Walleij wrote:
> Hi Th?o,
>
> thanks for your patch!
>
> On Fri, Feb 16, 2024 at 10:16?AM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> > i2c-mpc (fsl,timeout) and i2c-gpio (i2c-gpio,timeout-ms). I agree this
> > prop has no reason to be compatible-specific.
> >
> > Feedback from dt-bindings and I2C host maintainers would be useful: what
> > should the property be named? Having the unit makes it self-descriptive,
> > which sounds like a good idea to me. timeout-usecs, timeout-us, another
> > option?
>
> Use i2c-transfer-timeout-ms in my opinion, so it us crystal clear
> what that property is for.

Using ?s (microseconds) would be OK? I'm not sure yet about the exact
timeout desired but a one millisecond granularity might not be enough
for the Mobileye usecase.

Expect incoming patches to use the I2C controller in Fast Mode Plus
(1Mbps) and High Speed Mode (3.4Mbps). Gotta go fast!

> As Rob mentioned this isn't in the kernel schemas but in dtschema, so
> you need to patch this:
> https://github.com/robherring/dt-schema

Indeed. The other question if we do microseconds is the
suffix: -us, -usecs, -microseconds, etc? I picked -usecs for my v1, but
a grep tells me I am the only user of this suffix. -us is much more
common.

BTW i2c-controller.yaml already has a ?s timeout:
i2c-scl-clk-low-timeout-us

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

------------------------------------------------------------------------



From theo.lebrun at bootlin.com  Mon Feb 19 06:31:45 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 19 Feb 2024 15:31:45 +0100
Subject: [PATCH 07/13] i2c: nomadik: support short xfer timeouts using
 waitqueue & hrtimer
In-Reply-To: <CACRpkdYC=vVBA-s6GmsaED=NdXfsr0JDzzF+x8q8C3tqQ0F8YQ@mail.gmail.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-7-19a336e91dca@bootlin.com>
 <CACRpkdYC=vVBA-s6GmsaED=NdXfsr0JDzzF+x8q8C3tqQ0F8YQ@mail.gmail.com>
Message-ID: <CZ94MU7BQIOE.2KYB4TWVOJISN@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 3:19 PM CET, Linus Walleij wrote:
> On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> > Replace the completion by a waitqueue for synchronization from IRQ
> > handler to task. For short timeouts, use hrtimers, else use timers.
> > Usecase: avoid blocking the I2C bus for too long when an issue occurs.
> >
> > The threshold picked is one jiffy: if timeout is below that, use
> > hrtimers. This threshold is NOT configurable.
> >
> > Implement behavior but do NOT change fetching of timeout. This means the
> > timeout is unchanged (200ms) and the hrtimer case will never trigger.
> >
> > A waitqueue is used because it supports both desired timeout approaches.
> > See wait_event_timeout() and wait_event_hrtimeout(). An atomic boolean
> > serves as synchronization condition.
> >
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
>
> Part of me want to go and fix completions to handle hrtimer timeouts
> for submicrosecond timeouts, BUT I realized that this is a bit thick
> request for a simple driver, so just a suggestion for something we could
> do one day. This is fine with me.
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Indeed having to switch to another abstraction because we desire another
timeout method is nonsensical. Completion supporting hrtimeouts would
make sense. As you said though, this is too much for a simple driver.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

------------------------------------------------------------------------



From robh at kernel.org  Mon Feb 19 06:32:16 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 19 Feb 2024 08:32:16 -0600
Subject: [PATCH 2/8] dt-bindings: clock: Add Qcom QCM2290 GPUCC
In-Reply-To: <20240219-topic-rb1_gpu-v1-2-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
 <20240219-topic-rb1_gpu-v1-2-d260fa854707@linaro.org>
Message-ID: <170835313573.3576894.7520977778258170562.robh@kernel.org>


On Mon, 19 Feb 2024 14:35:47 +0100, Konrad Dybcio wrote:
> Add device tree bindings for graphics clock controller for Qualcomm
> Technology Inc's QCM2290 SoCs.
> 
> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> ---
>  .../bindings/clock/qcom,qcm2290-gpucc.yaml         | 76 ++++++++++++++++++++++
>  include/dt-bindings/clock/qcom,qcm2290-gpucc.h     | 32 +++++++++
>  2 files changed, 108 insertions(+)
> 

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/dt-review-ci/linux/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml: properties:compatible: [{'const': 'qcom,qcm2290-gpucc'}] is not of type 'object', 'boolean'
	from schema $id: http://json-schema.org/draft-07/schema#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml: properties:compatible: [{'const': 'qcom,qcm2290-gpucc'}] is not of type 'object', 'boolean'
	from schema $id: http://devicetree.org/meta-schemas/keywords.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml: ignoring, error in schema: properties: compatible
Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.example.dtb: /example-0/soc/clock-controller at 5990000: failed to match any schema with compatible: ['qcom,qcm2290-gpucc']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240219-topic-rb1_gpu-v1-2-d260fa854707 at linaro.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From linus.walleij at linaro.org  Mon Feb 19 06:35:41 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:35:41 +0100
Subject: [PATCH 10/13] i2c: nomadik: support Mobileye EyeQ5 I2C controller
In-Reply-To: <20240215-mbly-i2c-v1-10-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com> <20240215-mbly-i2c-v1-10-19a336e91dca@bootlin.com>
Message-ID: <CACRpkdY4PtnWkAEa=8sHdx7zYXLVAsrqKEVJY9m7VqeG5h6ChQ@mail.gmail.com>

On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> Add compatible for the integration of the same DB8500 IP block into the
> Mobileye EyeQ5 platform. Two quirks are present:
>
>  - The memory bus only supports 32-bit accesses. One writeb() is done to
>    fill the Tx FIFO which we replace with a writel().
>
>  - A register must be configured for the I2C speed mode; it is located
>    in a shared register region called OLB. We access that memory region
>    using a syscon & regmap that gets passed as a phandle (mobileye,olb).
>
>    A two-bit enum per controller is written into the register; that
>    requires us to know the global index of the I2C
>    controller (mobileye,id).
>
> We add #include <linux/mfd/syscon.h> and <linux/regmap.h> and sort
> headers.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

(...)

> -               writeb(*priv->cli.buffer, priv->virtbase + I2C_TFR);
> +               if (priv->has_32b_bus)
> +                       writel(*priv->cli.buffer, priv->virtbase + I2C_TFR);
> +               else
> +                       writeb(*priv->cli.buffer, priv->virtbase + I2C_TFR);

Are the other byte accessors working flawlessly? I get the shivers.
If it's needed in one place I bet the others prefer 32bit access too.

Further the MIPS is big-endian is it not? It feels that this just happens
to work because of byte order access? writel() is little-endian by
definition.

What happens if you replace all writeb():s with something like

static void nmk_write_reg(struct nmk_i2c_dev *priv, u32 reg, u8 val)
{
    if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
        writeb(val, priv->virtbase + reg + 3);
        // if this doesn't work then use writeb((u32)val,
priv->virtbase + reg) I guess
   else
        writeb(val, priv->virtbase + reg);
}

and conversely for readb()?

Other accessors such as iowrite* are perhaps viable in this case, I'm not sure.

Yours,
Linus Walleij


From theo.lebrun at bootlin.com  Mon Feb 19 06:38:31 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 19 Feb 2024 15:38:31 +0100
Subject: [PATCH 08/13] i2c: nomadik: replace jiffies by ktime for FIFO
 flushing timeout
In-Reply-To: <CACRpkdbuTX50syD0CMFcZXBmAHw4nwpcSc-C1OOUQEA9WHqCwA@mail.gmail.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-8-19a336e91dca@bootlin.com>
 <CACRpkdbuTX50syD0CMFcZXBmAHw4nwpcSc-C1OOUQEA9WHqCwA@mail.gmail.com>
Message-ID: <CZ94S0SE0WFN.1RS0SY3KNMWQQ@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 3:21 PM CET, Linus Walleij wrote:
> On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> > The FIFO flush function uses a jiffies amount to detect timeouts as the
> > flushing is async. Replace with ktime to get more accurate precision
> > and support short timeouts.
> >
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
>
> Excellent patch. Thanks.
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Somewhat related to this patch: while writing it, I noticed the total
timeout of flush_i2c_fifo() is 10 times the timeout. Without this
series, this means 10*200ms of busywaiting!

If you have an opinion on a more sensible option for this I could add a
patch to my V2. I don't know enough to pick a sensible value.

I'm unsure if it makes sense that the timeout of flush_i2c_fifo() is a
multiple of the transfer timeout. Does it make sense that those two
timeouts are correlated?

Big thanks for your review,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From geert at linux-m68k.org  Mon Feb 19 06:42:48 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 19 Feb 2024 15:42:48 +0100
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <CAMj1kXGw+r7yEEBA8gYBcdrqkiP=VYOSzz9YLnNavJn2snmFwA@mail.gmail.com>
References: <20240206074552.541154-1-maskray@google.com> <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>
 <CAMj1kXGaF5bobHTr1pTg+-=s4Ft7+5SSbX72-NxsR_W_Yuxb8Q@mail.gmail.com> <CAMj1kXGw+r7yEEBA8gYBcdrqkiP=VYOSzz9YLnNavJn2snmFwA@mail.gmail.com>
Message-ID: <CAMuHMdX+6fnAf8Hm6EqYJPAjrrLO9T7c=Gu3S8V_pqjSDowJ6g@mail.gmail.com>

Hi Ard,

On Mon, Feb 19, 2024 at 11:57?AM Ard Biesheuvel <ardb at kernel.org> wrote:
> On Mon, 19 Feb 2024 at 11:56, Ard Biesheuvel <ardb at kernel.org> wrote:
> > On Mon, 19 Feb 2024 at 11:03, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> > > On Tue, Feb 6, 2024 at 8:46?AM Fangrui Song <maskray at google.com> wrote:
> > > > The generic constraint "i" seems to be copied from x86 or arm (and with
> > > > a redundant generic operand modifier "c"). It works with -fno-PIE but
> > > > not with -fPIE/-fPIC in GCC's aarch64 port.
> > >
> > > Thanks for your patch, which is now commit f9daab0ad01cf9d1 ("arm64:
> > > jump_label: use constraints "Si" instead of "i"") in v6.8-rc5.
> > >
> > > > The machine constraint "S", which denotes a symbol or label reference
> > > > with a constant offset, supports PIC and has been available in GCC since
> > > > 2012 and in Clang since 7.0. However, Clang before 19 does not support
> > > > "S" on a symbol with a constant offset [1] (e.g.
> > > > `static_key_false(&nf_hooks_needed[pf][hook])` in
> > > > include/linux/netfilter.h), so we use "i" as a fallback.
> > >
> > > https://gcc.gnu.org/releases.html says gcc-5 was released in 2015,
> > > i.e. after 2012 ...
> > >
> > > > Suggested-by: Ard Biesheuvel <ardb at kernel.org>
> > > > Signed-off-by: Fangrui Song <maskray at google.com>
> > > > Link: https://github.com/llvm/llvm-project/pull/80255 [1]
> > > >
> > > > ---
> > > > Changes from
> > > > arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
> > > >
> > > > * Use "Si" as Ard suggested to support Clang<19
> > > > * Make branch a separate operand
> > > >
> > > > Changes from v1:
> > > >
> > > > * Use asmSymbolicName for readability
> > >
> > > But it still fails on gcc-5:
> > >
> > >     arch/arm64/include/asm/jump_label.h:25:2: error: invalid 'asm':
> > > invalid operand
> > >       asm goto(
> > >       ^
> > >
> > > http://kisskb.ellerman.id.au/kisskb/buildresult/15129281/
> > >
> >
> > How odd. godbolt.org has 5.4 and it seems perfectly happy with it.

> https://godbolt.org/z/GTnf3vPaT

I could reproduce the issue on v6.8-rc5 using arm64 defconfig
and x86_64-gcc-5.5.0-nolibc-aarch64-linux.tar.xz from
https://cdn.kernel.org/pub/tools/crosstool/files/bin/x86_64/5.5.0/:

    In file included from ./include/linux/jump_label.h:112:0,
                     from ./include/linux/static_key.h:1,
                     from ./include/linux/kasan-enabled.h:5,
                     from ./arch/arm64/include/asm/cache.h:41,
                     from ./include/linux/cache.h:6,
                     from ./include/linux/slab.h:15,
                     from ./include/linux/resource_ext.h:11,
                     from ./include/linux/acpi.h:13,
                     from arch/arm64/mm/fault.c:10:
    arch/arm64/mm/fault.c: In function 'do_page_fault':
    ./arch/arm64/include/asm/jump_label.h:25:2: error: invalid 'asm':
invalid operand
      asm goto(
      ^
    ./arch/arm64/include/asm/jump_label.h:25:2: error: invalid 'asm':
invalid operand

There are also a few warnings due to unrecognized options:

    arch/arm64/mm/fault.c: At top level:
    cc1: warning: unrecognized command line option '-Wno-shift-negative-value'
    cc1: warning: unrecognized command line option '-Wno-stringop-overflow'

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 u-kumar1 at ti.com  Mon Feb 19 06:46:13 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Mon, 19 Feb 2024 20:16:13 +0530
Subject: [PATCH v2 0/2] Add OSPI and Ethernet support on J722S EVM
In-Reply-To: <20240219090435.934383-1-vaishnav.a@ti.com>
References: <20240219090435.934383-1-vaishnav.a@ti.com>
Message-ID: <be8be773-7ba0-4a08-af87-20ff9a830b27@ti.com>

Thanks Vaishnav

On 2/19/2024 2:34 PM, Vaishnav Achath wrote:
> Hi,
>
> This series adds support for Ethernet and OSPI NOR flash on J722S EVM.
>
> V1: https://lore.kernel.org/all/20240216135533.904130-1-vaishnav.a at ti.com/
>
> Changelog:
> V1->V2:
>    * Update comments indicating PAD numbers.
>
> EVM Schematics are available at:
> 	https://www.ti.com/lit/zip/sprr495
>
> Test log (6.8.0-rc4-next-20240216):
>    https://gist.github.com/vaishnavachath/b04e3be90af4cdec59fb0d9cc72441b9
>
> For those interested, more details about this SoC can be found in the
> Technical Reference Manual here:
>              https://www.ti.com/lit/zip/sprujb3
>
> Thanks and Regards,
> Vaishnav
>
> Siddharth Vadapalli (1):
>    arm64: dts: ti: k3-j722s-evm: Enable CPSW3G RGMII1

Series Reviewed-by: Udit Kumar <u-kumar1 at ti.com>


>
> Vaishnav Achath (1):
>    arm64: dts: ti: k3-j722s-evm: Enable OSPI NOR support
>
>   arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 132 ++++++++++++++++++++++++
>   1 file changed, 132 insertions(+)
>


From yuzenghui at huawei.com  Mon Feb 19 06:46:46 2024
From: yuzenghui at huawei.com (Zenghui Yu)
Date: Mon, 19 Feb 2024 22:46:46 +0800
Subject: next-20240219: arm64: boot failed - gic_of_init
In-Reply-To: <86cyss4rl7.wl-maz@kernel.org>
References: <CA+G9fYugYiLd7MDn3wCxK+x5Td9WO-VUX2OvOtTN7D1d4GHCfg@mail.gmail.com>
 <86edd84wer.wl-maz@kernel.org> <86cyss4rl7.wl-maz@kernel.org>
Message-ID: <a7d8e529-9a44-3f88-50ef-d87b80515c36@huawei.com>

On 2024/2/19 19:32, Marc Zyngier wrote:
> For what it is worth, I've just tested both defconfig and my own
> configuration with both 4k (kvmtool, QEMU+KVM and on SynQuacer) and
> 16k (kvmtool), without any obvious problem.

I had a quick test on top of next-20240219 with defconfig.  I can
reproduce it with QEMU parameter '-cpu max -accel tcg', but things are
fine with '-cpu max,lpa2=off -accel tcg'.

Bisection shows that the problem happens when we start putting the
latest arm64 and kvmarm changes together.  The following hack fixes the
problem for me (but I **only** write it for kernel built with defconfig
with ARM64_4K_PAGES=y atm).

I can investigate it further tomorrow (as it's too late now ;-) ).  Or
maybe Marc or Catalin can help fix it with a proper approach.

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 4f7662008ede..babdc3f4721b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2798,6 +2798,7 @@ static const struct arm64_cpu_capabilities 
arm64_features[] = {
| 		.sign = FTR_SIGNED,
| 		.field_pos = ID_AA64MMFR0_EL1_TGRAN4_SHIFT,
| 		.min_field_value = ID_AA64MMFR0_EL1_TGRAN4_52_BIT,
|+		.max_field_value = BIT(ID_AA64MMFR0_EL1_TGRAN4_WIDTH - 1) - 1,
| #else
| 		.sign = FTR_UNSIGNED,
| 		.field_pos = ID_AA64MMFR0_EL1_TGRAN16_SHIFT,

Thanks,
Zenghui


From dmitry.baryshkov at linaro.org  Mon Feb 19 06:47:37 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 16:47:37 +0200
Subject: [PATCH] irqchip/gic-v3: handle DOMAIN_BUS_ANY in
 gic_irq_domain_select
Message-ID: <20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f@linaro.org>

Before the commit de1ff306dcf4 ("genirq/irqdomain: Remove the param
count restriction from select()") the irq_find_matching_fwspec() was
handling the DOMAIN_BUS_ANY on its own. After this commit it is a job of
the select() callback. However the callback of GICv3 (even though it got
modified to handle zero param_count) wasn't prepared to return true for
DOMAIN_BUS_ANY bus_token.

This breaks probing of any of the child IRQ domains, since
platform_irqchip_probe() uses irq_find_matching_host(par_np,
DOMAIN_BUS_ANY) to check for the presence of the parent IRQ domain.

Fixes: 151378251004 ("irqchip/gic-v3: Make gic_irq_domain_select() robust for zero parameter count")
Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from select()")
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 drivers/irqchip/irq-gic-v3.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 6fb276504bcc..e9e9643c653f 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1696,7 +1696,8 @@ static int gic_irq_domain_select(struct irq_domain *d,
 
 	/* Handle pure domain searches */
 	if (!fwspec->param_count)
-		return d->bus_token == bus_token;
+		return d->bus_token == bus_token ||
+			bus_token == DOMAIN_BUS_ANY;
 
 	/* If this is not DT, then we have a single domain */
 	if (!is_of_node(fwspec->fwnode))

---
base-commit: 35a4fdde2466b9d90af297f249436a270ef9d30e
change-id: 20240219-gic-fix-child-domain-8a1840be9ff5

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



From dmitry.baryshkov at linaro.org  Mon Feb 19 06:49:13 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 16:49:13 +0200
Subject: [PATCH 8/8] arm64: dts: qcom: qrb2210-rb1: Enable the GPU
In-Reply-To: <20240219-topic-rb1_gpu-v1-8-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org> <20240219-topic-rb1_gpu-v1-8-d260fa854707@linaro.org>
Message-ID: <CAA8EJppPvXfkz=wVca8aFBhFaVUe9+OiVzcQUq7D8zPbK+T1FQ@mail.gmail.com>

On Mon, 19 Feb 2024 at 15:36, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>
> Enable the A702 GPU (also marketed as "3D accelerator by qcom [1], lol).

Is it not?

>
> [1] https://docs.qualcomm.com/bundle/publicresource/87-61720-1_REV_A_QUALCOMM_ROBOTICS_RB1_PLATFORM__QUALCOMM_QRB2210__PRODUCT_BRIEF.pdf
> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>

With the exception of the commit message:

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

> ---
>  arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)


-- 
With best wishes
Dmitry


From linus.walleij at linaro.org  Mon Feb 19 06:50:02 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:50:02 +0100
Subject: [PATCH 01/23] dt-bindings: gpio: nomadik: convert into yaml format
In-Reply-To: <20240214-mbly-gpio-v1-1-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-1-f88c0ccf372b@bootlin.com>
Message-ID: <CACRpkdZyw+WyrmdkjQoO9-y4exw0k6FiHk6NJ1V6N+OGZaKqRg@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> Create gpio/st,nomadik-gpio.yaml json-schema dt-bindings file as a
> direct translation from gpio-nmk.txt. Remove the txt file.
>
> Add clocks and gpio-ranges properties which were missing and are being
> used in Nomadik devicetrees.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Thanks for doing this.

With the fix pointed out by Krzysztof folded in:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Mon Feb 19 06:50:59 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:50:59 +0100
Subject: [PATCH 02/23] dt-bindings: gpio: nomadik: add optional ngpios property
In-Reply-To: <20240214-mbly-gpio-v1-2-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-2-f88c0ccf372b@bootlin.com>
Message-ID: <CACRpkdawXwae7GKf4zOfVUJPLgLOeEX-8w5fbnr8O6FXuZHuaw@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> This GPIO controller can support a lesser number of GPIOs than 32.
> Express that in devicetree using an optional, generic property.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> index a999908173d2..bbd23daed229 100644
> --- a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> +++ b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> @@ -50,6 +50,10 @@ properties:
>    gpio-ranges:
>      maxItems: 1
>
> +  ngpios:
> +    minimum: 0
> +    maximum: 32

I can't help but wonder what good is ngpios = <0>; but OK.
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From theo.lebrun at bootlin.com  Mon Feb 19 06:52:37 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 19 Feb 2024 15:52:37 +0100
Subject: [PATCH 10/13] i2c: nomadik: support Mobileye EyeQ5 I2C
 controller
In-Reply-To: <CACRpkdY4PtnWkAEa=8sHdx7zYXLVAsrqKEVJY9m7VqeG5h6ChQ@mail.gmail.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-10-19a336e91dca@bootlin.com>
 <CACRpkdY4PtnWkAEa=8sHdx7zYXLVAsrqKEVJY9m7VqeG5h6ChQ@mail.gmail.com>
Message-ID: <CZ952TBZGEVD.JYSAQGNL1ZAQ@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 3:35 PM CET, Linus Walleij wrote:
> On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> > Add compatible for the integration of the same DB8500 IP block into the
> > Mobileye EyeQ5 platform. Two quirks are present:
> >
> >  - The memory bus only supports 32-bit accesses. One writeb() is done to
> >    fill the Tx FIFO which we replace with a writel().
> >
> >  - A register must be configured for the I2C speed mode; it is located
> >    in a shared register region called OLB. We access that memory region
> >    using a syscon & regmap that gets passed as a phandle (mobileye,olb).
> >
> >    A two-bit enum per controller is written into the register; that
> >    requires us to know the global index of the I2C
> >    controller (mobileye,id).
> >
> > We add #include <linux/mfd/syscon.h> and <linux/regmap.h> and sort
> > headers.
> >
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
>
> (...)
>
> > -               writeb(*priv->cli.buffer, priv->virtbase + I2C_TFR);
> > +               if (priv->has_32b_bus)
> > +                       writel(*priv->cli.buffer, priv->virtbase + I2C_TFR);
> > +               else
> > +                       writeb(*priv->cli.buffer, priv->virtbase + I2C_TFR);
>
> Are the other byte accessors working flawlessly? I get the shivers.
> If it's needed in one place I bet the others prefer 32bit access too.

I see where your shivers come from; I'll investigate as I don't remember
my conclusion from the time when I worked on this driver (a few months
ago).

> Further the MIPS is big-endian is it not? It feels that this just happens
> to work because of byte order access? writel() is little-endian by
> definition.

Actually, no. Our platform is little-endian.

The full story, summarised: the endianness of our cores in kernel and
hypervisor mode is defined by a pin read at reset. User mode can toggle
the endianness at runtime I believe, but that is not of our concern.
Our endianness in kernel mode is little-endian because the pin in
question is hardwired to the value meaning little-endian.

> What happens if you replace all writeb():s with something like
>
> static void nmk_write_reg(struct nmk_i2c_dev *priv, u32 reg, u8 val)
> {
>     if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
>         writeb(val, priv->virtbase + reg + 3);
>         // if this doesn't work then use writeb((u32)val,
> priv->virtbase + reg) I guess
>    else
>         writeb(val, priv->virtbase + reg);
> }
>
> and conversely for readb()?

As mentionned above, big endian isn't the worry for us. I'll be checking
the readb() calls found in i2c_irq_handler() though.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From u-kumar1 at ti.com  Mon Feb 19 06:52:38 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Mon, 19 Feb 2024 20:22:38 +0530
Subject: [RESEND PATCH V2 2/2] arm64: dts: ti: k3-am69-sk: Add support for
 OSPI flash
In-Reply-To: <20240219111422.171315-3-sabiya.d@ti.com>
References: <20240219111422.171315-1-sabiya.d@ti.com>
 <20240219111422.171315-3-sabiya.d@ti.com>
Message-ID: <f4bb70f1-be4b-46d4-8e47-bf1bbc1c3ae6@ti.com>


On 2/19/2024 4:44 PM, sabiya.d at mistralsolutions.com wrote:
> From: Dasnavis Sabiya <sabiya.d at ti.com>
>
> AM69 SK has S28HS512T OSPI flash connected to MCU OSPI0.
> Enable support for the same. Also describe the partition
> information according to the offsets in the bootloader.
>
> Signed-off-by: Dasnavis Sabiya <sabiya.d at ti.com>
> ---
>   arch/arm64/boot/dts/ti/k3-am69-sk.dts | 81 +++++++++++++++++++++++++++
>   1 file changed, 81 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> index 0ff4d1623cf4..acda25a9e814 100644
> --- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
> @@ -471,6 +471,25 @@ J784S4_IOPAD(0x09C, PIN_OUTPUT, 0) /* (AF35) MCAN7_TX */
>   	};
>   };
>   
> +&wkup_pmx0 {
> +	bootph-all;
> +	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-default-pins {
> +		pinctrl-single,pins = <
> +			J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (E32) MCU_OSPI0_CLK */
> +			J784S4_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (A32) MCU_OSPI0_CSn0 */
> +			J784S4_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (B33) MCU_OSPI0_D0 */
> +			J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (B32) MCU_OSPI0_D1 */
> +			J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (C33) MCU_OSPI0_D2 */
> +			J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (C35) MCU_OSPI0_D3 */
> +			J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (D33) MCU_OSPI0_D4 */
> +			J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D34) MCU_OSPI0_D5 */
> +			J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (E34) MCU_OSPI0_D6 */
> +			J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (E33) MCU_OSPI0_D7 */
> +			J784S4_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (C34) MCU_OSPI0_DQS */
> +		>;
> +	};
> +};
> +
>   &wkup_pmx2 {
>   	bootph-all;
>   	pmic_irq_pins_default: pmic-irq-default-pins {
> @@ -1070,3 +1089,65 @@ &main_mcan7 {
>   	pinctrl-0 = <&main_mcan7_pins_default>;
>   	phys = <&transceiver4>;
>   };
> +
> +&ospi0 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
> +
> +	flash at 0 {
> +		compatible = "jedec,spi-nor";
> +		reg = <0x0>;
> +		spi-tx-bus-width = <8>;
> +		spi-rx-bus-width = <8>;
> +		spi-max-frequency = <25000000>;
> +		cdns,tshsl-ns = <60>;
> +		cdns,tsd2d-ns = <60>;
> +		cdns,tchsh-ns = <60>;
> +		cdns,tslch-ns = <60>;
> +		cdns,read-delay = <4>;
> +
> +		partitions {
> +			bootph-all;
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			partition at 0 {
> +				label = "ospi.tiboot3";
> +				reg = <0x0 0x80000>;
> +			};


Recent update around u-boot shows, 512K is not sufficient for tiboot3.

Please consider to make it 1MB

> +
> +			partition at 80000 {
> +				label = "ospi.tispl";
> +				reg = <0x80000 0x200000>;
> +			};
> +
> +			partition at 280000 {
> +				label = "ospi.u-boot";
> +				reg = <0x280000 0x400000>;
> +			};
> +
> +			partition at 680000 {
> +				label = "ospi.env";
> +				reg = <0x680000 0x40000>;
> +			};
> +
> +			partition at 6c0000 {
> +				label = "ospi.env.backup";
> +				reg = <0x6c0000 0x40000>;
> +			};
> +
> +			partition at 800000 {
> +				label = "ospi.rootfs";
> +				reg = <0x800000 0x37c0000>;
> +			};
> +
> +			partition at 3fc0000 {
> +				bootph-pre-ram;
> +				label = "ospi.phypattern";
> +				reg = <0x3fc0000 0x40000>;
> +			};
> +		};
> +	};
> +};


From linus.walleij at linaro.org  Mon Feb 19 06:53:15 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:53:15 +0100
Subject: [PATCH 08/13] i2c: nomadik: replace jiffies by ktime for FIFO
 flushing timeout
In-Reply-To: <CZ94S0SE0WFN.1RS0SY3KNMWQQ@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-8-19a336e91dca@bootlin.com> <CACRpkdbuTX50syD0CMFcZXBmAHw4nwpcSc-C1OOUQEA9WHqCwA@mail.gmail.com>
 <CZ94S0SE0WFN.1RS0SY3KNMWQQ@bootlin.com>
Message-ID: <CACRpkdaVCOB_C45KTEtuoZRwb66x1saGHN3A_ZpY7T=a8YtV+Q@mail.gmail.com>

On Mon, Feb 19, 2024 at 3:38?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> Somewhat related to this patch: while writing it, I noticed the total
> timeout of flush_i2c_fifo() is 10 times the timeout. Without this
> series, this means 10*200ms of busywaiting!
>
> If you have an opinion on a more sensible option for this I could add a
> patch to my V2. I don't know enough to pick a sensible value.
>
> I'm unsure if it makes sense that the timeout of flush_i2c_fifo() is a
> multiple of the transfer timeout. Does it make sense that those two
> timeouts are correlated?

I have a *vague* memory of the timeouts for flushing needing to be longer
but I might be mistaken. This is probably a Srinidhi or even Sachin question...
Sadly I don't have their current mail addresses.

Yours,
Linus Walleij


From dmitry.baryshkov at linaro.org  Mon Feb 19 06:53:35 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 16:53:35 +0200
Subject: [PATCH 3/8] clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
In-Reply-To: <20240219-topic-rb1_gpu-v1-3-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org> <20240219-topic-rb1_gpu-v1-3-d260fa854707@linaro.org>
Message-ID: <CAA8EJpq8XvQm9B3RZq9PNMqA5VAqKUyVn5qt8-WEYMQMWniDZA@mail.gmail.com>

On Mon, 19 Feb 2024 at 15:36, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>
> Commit 134b55b7e19f ("clk: qcom: support Huayra type Alpha PLL")
> introduced an entry to the alpha offsets array, but diving into QCM2290
> downstream and some documentation, it turned out that the name Huayra
> apparently has been used quite liberally across many chips, even with
> noticeably different hardware.
>
> Introduce another set of offsets and a new configure function for the
> Huayra PLL found on QCM2290. This is required e.g. for the consumers
> of GPUCC_PLL0 to properly start.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> ---
>  drivers/clk/qcom/clk-alpha-pll.c | 45 ++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/qcom/clk-alpha-pll.h |  3 +++
>  2 files changed, 48 insertions(+)
>
> diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
> index 8a412ef47e16..61b5abd13782 100644
> --- a/drivers/clk/qcom/clk-alpha-pll.c
> +++ b/drivers/clk/qcom/clk-alpha-pll.c
> @@ -244,6 +244,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
>                 [PLL_OFF_OPMODE] = 0x30,
>                 [PLL_OFF_STATUS] = 0x3c,
>         },
> +       [CLK_ALPHA_PLL_TYPE_HUAYRA_2290] =  {
> +               [PLL_OFF_L_VAL] = 0x04,
> +               [PLL_OFF_ALPHA_VAL] = 0x08,
> +               [PLL_OFF_USER_CTL] = 0x0c,
> +               [PLL_OFF_CONFIG_CTL] = 0x10,
> +               [PLL_OFF_CONFIG_CTL_U] = 0x14,
> +               [PLL_OFF_CONFIG_CTL_U1] = 0x18,
> +               [PLL_OFF_TEST_CTL] = 0x1c,
> +               [PLL_OFF_TEST_CTL_U] = 0x20,
> +               [PLL_OFF_TEST_CTL_U1] = 0x24,
> +               [PLL_OFF_OPMODE] = 0x28,
> +               [PLL_OFF_STATUS] = 0x38,
> +       },

Can you please move them next to the standard huayra PLL regs?

>  };
>  EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
>
> @@ -779,6 +792,38 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
>         return clamp(rate, min_freq, max_freq);
>  }
>
> +void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
> +                                  const struct alpha_pll_config *config)
> +{
> +       clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
> +       clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);
> +       clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);
> +       clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);
> +       clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);
> +       clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);
> +       clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
> +       clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
> +       clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
> +
> +       /* Set PLL_BYPASSNL */
> +       regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL);
> +
> +       /* Wait 5 us between setting BYPASS and deasserting reset */
> +       mb();
> +       udelay(5);
> +
> +       /* Take PLL out from reset state */
> +       regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
> +
> +       /* Wait 50us for PLL_LOCK_DET bit to go high */
> +       mb();
> +       usleep_range(50, 55);
> +
> +       /* Enable PLL output */
> +       regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
> +}
> +EXPORT_SYMBOL(clk_huayra_2290_pll_configure);
> +
>  static unsigned long
>  alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a)
>  {
> diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
> index fb6d50263bb9..91d3d6f19eae 100644
> --- a/drivers/clk/qcom/clk-alpha-pll.h
> +++ b/drivers/clk/qcom/clk-alpha-pll.h
> @@ -29,6 +29,7 @@ enum {
>         CLK_ALPHA_PLL_TYPE_BRAMMO_EVO,
>         CLK_ALPHA_PLL_TYPE_STROMER,
>         CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
> +       CLK_ALPHA_PLL_TYPE_HUAYRA_2290,

Also next to standard huayra PLL, please.

>         CLK_ALPHA_PLL_TYPE_MAX,
>  };
>
> @@ -191,6 +192,8 @@ extern const struct clk_ops clk_alpha_pll_rivian_evo_ops;
>
>  void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
>                              const struct alpha_pll_config *config);
> +void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
> +                                  const struct alpha_pll_config *config);
>  void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
>                                 const struct alpha_pll_config *config);
>  void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
>
> --
> 2.43.2
>


-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Mon Feb 19 06:54:33 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 16:54:33 +0200
Subject: [PATCH 4/8] clk: qcom: Add QCM2290 GPU clock controller driver
In-Reply-To: <20240219-topic-rb1_gpu-v1-4-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org> <20240219-topic-rb1_gpu-v1-4-d260fa854707@linaro.org>
Message-ID: <CAA8EJpq46Wn+gWKL81_zMxyddUpJRuKHDrx=4Q2DvbwufmWHWA@mail.gmail.com>

On Mon, 19 Feb 2024 at 15:36, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>
> Add a driver for the GPU clock controller block found on the QCM2290 SoC.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> ---
>  drivers/clk/qcom/Kconfig         |   9 +
>  drivers/clk/qcom/Makefile        |   1 +
>  drivers/clk/qcom/gpucc-qcm2290.c | 423 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 433 insertions(+)
>

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From ahalaney at redhat.com  Mon Feb 19 06:54:33 2024
From: ahalaney at redhat.com (Andrew Halaney)
Date: Mon, 19 Feb 2024 08:54:33 -0600
Subject: [PATCH 3/8] clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
In-Reply-To: <20240219-topic-rb1_gpu-v1-3-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
 <20240219-topic-rb1_gpu-v1-3-d260fa854707@linaro.org>
Message-ID: <u7beg6ui3i6nxoaulc3o7ghfkvcsy46ps53k3jynrurdwn6o7o@ppyqoz4jsotc>

On Mon, Feb 19, 2024 at 02:35:48PM +0100, Konrad Dybcio wrote:
> Commit 134b55b7e19f ("clk: qcom: support Huayra type Alpha PLL")
> introduced an entry to the alpha offsets array, but diving into QCM2290
> downstream and some documentation, it turned out that the name Huayra
> apparently has been used quite liberally across many chips, even with
> noticeably different hardware.
> 
> Introduce another set of offsets and a new configure function for the
> Huayra PLL found on QCM2290. This is required e.g. for the consumers
> of GPUCC_PLL0 to properly start.
> 
> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> ---
>  drivers/clk/qcom/clk-alpha-pll.c | 45 ++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/qcom/clk-alpha-pll.h |  3 +++
>  2 files changed, 48 insertions(+)
> 
> diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
> index 8a412ef47e16..61b5abd13782 100644
> --- a/drivers/clk/qcom/clk-alpha-pll.c
> +++ b/drivers/clk/qcom/clk-alpha-pll.c
> @@ -244,6 +244,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
>  		[PLL_OFF_OPMODE] = 0x30,
>  		[PLL_OFF_STATUS] = 0x3c,
>  	},
> +	[CLK_ALPHA_PLL_TYPE_HUAYRA_2290] =  {
> +		[PLL_OFF_L_VAL] = 0x04,
> +		[PLL_OFF_ALPHA_VAL] = 0x08,
> +		[PLL_OFF_USER_CTL] = 0x0c,
> +		[PLL_OFF_CONFIG_CTL] = 0x10,
> +		[PLL_OFF_CONFIG_CTL_U] = 0x14,
> +		[PLL_OFF_CONFIG_CTL_U1] = 0x18,
> +		[PLL_OFF_TEST_CTL] = 0x1c,
> +		[PLL_OFF_TEST_CTL_U] = 0x20,
> +		[PLL_OFF_TEST_CTL_U1] = 0x24,
> +		[PLL_OFF_OPMODE] = 0x28,
> +		[PLL_OFF_STATUS] = 0x38,
> +	},
>  };
>  EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
>  
> @@ -779,6 +792,38 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
>  	return clamp(rate, min_freq, max_freq);
>  }
>  
> +void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
> +				   const struct alpha_pll_config *config)
> +{
> +	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
> +	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);
> +	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);
> +	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);
> +	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);
> +	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);
> +	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
> +	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
> +	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
> +
> +	/* Set PLL_BYPASSNL */
> +	regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL);
> +
> +	/* Wait 5 us between setting BYPASS and deasserting reset */
> +	mb();
> +	udelay(5);
> +
> +	/* Take PLL out from reset state */
> +	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
> +
> +	/* Wait 50us for PLL_LOCK_DET bit to go high */
> +	mb();
> +	usleep_range(50, 55);

I *think* you'd want to use a read to ensure your write goes through
prior to your sleep... from memory-barriers.txt:

	5. A readX() by a CPU thread from the peripheral will complete before
	   any subsequent delay() loop can begin execution on the same thread.
	   This ensures that two MMIO register writes by the CPU to a peripheral
	   will arrive at least 1us apart if the first write is immediately read
	   back with readX() and udelay(1) is called prior to the second
	   writeX():

		writel(42, DEVICE_REGISTER_0); // Arrives at the device...
		readl(DEVICE_REGISTER_0);
		udelay(1);
		writel(42, DEVICE_REGISTER_1); // ...at least 1us before this.

also https://youtu.be/i6DayghhA8Q?si=7lp0be35q1HRmlnV&t=1677
for more references on this topic.


> +
> +	/* Enable PLL output */
> +	regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
> +}
> +EXPORT_SYMBOL(clk_huayra_2290_pll_configure);
> +
>  static unsigned long
>  alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a)
>  {
> diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
> index fb6d50263bb9..91d3d6f19eae 100644
> --- a/drivers/clk/qcom/clk-alpha-pll.h
> +++ b/drivers/clk/qcom/clk-alpha-pll.h
> @@ -29,6 +29,7 @@ enum {
>  	CLK_ALPHA_PLL_TYPE_BRAMMO_EVO,
>  	CLK_ALPHA_PLL_TYPE_STROMER,
>  	CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
> +	CLK_ALPHA_PLL_TYPE_HUAYRA_2290,
>  	CLK_ALPHA_PLL_TYPE_MAX,
>  };
>  
> @@ -191,6 +192,8 @@ extern const struct clk_ops clk_alpha_pll_rivian_evo_ops;
>  
>  void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
>  			     const struct alpha_pll_config *config);
> +void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
> +				   const struct alpha_pll_config *config);
>  void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
>  				const struct alpha_pll_config *config);
>  void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
> 
> -- 
> 2.43.2
> 
> 



From theo.lebrun at bootlin.com  Mon Feb 19 06:55:06 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 19 Feb 2024 15:55:06 +0100
Subject: [PATCH 02/23] dt-bindings: gpio: nomadik: add optional ngpios
 property
In-Reply-To: <CACRpkdawXwae7GKf4zOfVUJPLgLOeEX-8w5fbnr8O6FXuZHuaw@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-2-f88c0ccf372b@bootlin.com>
 <CACRpkdawXwae7GKf4zOfVUJPLgLOeEX-8w5fbnr8O6FXuZHuaw@mail.gmail.com>
Message-ID: <CZ954Q11FWMI.39QMRYTRZAO1C@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 3:50 PM CET, Linus Walleij wrote:
> On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> > This GPIO controller can support a lesser number of GPIOs than 32.
> > Express that in devicetree using an optional, generic property.
> >
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> > ---
> >  Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml | 4 ++++
> >  1 file changed, 4 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> > index a999908173d2..bbd23daed229 100644
> > --- a/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> > +++ b/Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml
> > @@ -50,6 +50,10 @@ properties:
> >    gpio-ranges:
> >      maxItems: 1
> >
> > +  ngpios:
> > +    minimum: 0
> > +    maximum: 32
>
> I can't help but wonder what good is ngpios = <0>; but OK.
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

A min value is required, else it is equal to the max. There was no
reason to pick anything bigger than zero.

I'll admit it is not a setup I have tested so the driver might have
issues with the ngpios==0 edge-case. Of course I do not expect anyone
to care.

Regards,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From linus.walleij at linaro.org  Mon Feb 19 06:55:08 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 15:55:08 +0100
Subject: [PATCH 04/23] dt-bindings: gpio: nomadik: add optional reset property
In-Reply-To: <20240214-mbly-gpio-v1-4-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-4-f88c0ccf372b@bootlin.com>
Message-ID: <CACRpkdZ5v4GUJtrOV4U4bhvKC+RZFXk8LZdyN1cbxmm5mxcLuQ@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> Add optional reset device-tree property to the Nomadik GPIO controller.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From dmitry.baryshkov at linaro.org  Mon Feb 19 06:57:23 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 16:57:23 +0200
Subject: [PATCH 7/8] arm64: dts: qcom: qcm2290: Add GPU nodes
In-Reply-To: <20240219-topic-rb1_gpu-v1-7-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org> <20240219-topic-rb1_gpu-v1-7-d260fa854707@linaro.org>
Message-ID: <CAA8EJprpZxCV-3xkE0OuGg4jHrHcb=EPKCi_wSy5viP7jVwPvg@mail.gmail.com>

On Mon, 19 Feb 2024 at 15:36, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>
> Describe the GPU hardware on the QCM2290.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/qcm2290.dtsi | 154 ++++++++++++++++++++++++++++++++++
>  1 file changed, 154 insertions(+)
>

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From geert+renesas at glider.be  Mon Feb 19 07:00:41 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Mon, 19 Feb 2024 16:00:41 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: gray-hawk-single: Add QSPI FLASH support
In-Reply-To: <cover.1708354463.git.geert+renesas@glider.be>
References: <cover.1708354463.git.geert+renesas@glider.be>
Message-ID: <96d6567024cef9fcd6b04f92a697301c1c8d1d8e.1708354463.git.geert+renesas@glider.be>

From: Cong Dang <cong.dang.xn at renesas.com>

Describe the QSPI FLASH on the Gray Hawk Single board.

Signed-off-by: Cong Dang <cong.dang.xn at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Apply to r8a779h0-gray-hawk-single.dts,
  - Add missing status = "okay".
---
 .../dts/renesas/r8a779h0-gray-hawk-single.dts | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
index 1163ac5e292755db..bc8616a56c039b20 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
+++ b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
@@ -181,12 +181,45 @@ mmc_pins: mmc {
 		power-source = <1800>;
 	};
 
+	qspi0_pins: qspi0 {
+		groups = "qspi0_ctrl", "qspi0_data4";
+		function = "qspi0";
+	};
+
 	scif_clk_pins: scif-clk {
 		groups = "scif_clk";
 		function = "scif_clk";
 	};
 };
 
+&rpc {
+	pinctrl-0 = <&qspi0_pins>;
+	pinctrl-names = "default";
+
+	status = "okay";
+
+	flash at 0 {
+		compatible = "spansion,s25fs512s", "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+		spi-rx-bus-width = <4>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			boot at 0 {
+				reg = <0x0 0x1200000>;
+				read-only;
+			};
+			user at 1200000 {
+				reg = <0x1200000 0x2e00000>;
+			};
+		};
+	};
+};
+
 &rwdt {
 	timeout-sec = <60>;
 	status = "okay";
-- 
2.34.1



From geert+renesas at glider.be  Mon Feb 19 07:00:40 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Mon, 19 Feb 2024 16:00:40 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: r8a779h0: Add RPC node
In-Reply-To: <cover.1708354463.git.geert+renesas@glider.be>
References: <cover.1708354463.git.geert+renesas@glider.be>
Message-ID: <26f9c5d5a7944db3813ed53459aa9c5767c1bdc0.1708354463.git.geert+renesas@glider.be>

From: Cong Dang <cong.dang.xn at renesas.com>

Add a device node for the SPI Multi I/O Bus Controller (RPC-IF) on the
Renesas R-Car V4M (R8A779H0) SoC.

Signed-off-by: Cong Dang <cong.dang.xn at renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Changes compared to the BSP:
  - Drop undocumented clock-names property.
---
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
index 46c586f4e326959f..11885729181bc903 100644
--- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -621,6 +621,22 @@ mmc0: mmc at ee140000 {
 			status = "disabled";
 		};
 
+		rpc: spi at ee200000 {
+			compatible = "renesas,r8a779h0-rpc-if",
+				     "renesas,rcar-gen4-rpc-if";
+			reg = <0 0xee200000 0 0x200>,
+			      <0 0x08000000 0 0x04000000>,
+			      <0 0xee208000 0 0x100>;
+			reg-names = "regs", "dirmap", "wbuf";
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 629>;
+			power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+			resets = <&cpg 629>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		gic: interrupt-controller at f1000000 {
 			compatible = "arm,gic-v3";
 			#interrupt-cells = <3>;
-- 
2.34.1



From geert+renesas at glider.be  Mon Feb 19 07:00:39 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Mon, 19 Feb 2024 16:00:39 +0100
Subject: [PATCH 0/2] arm64: dts: renesas: r8a779h0/gray-hawk-single: Add RPC and QSPI FLASH support
Message-ID: <arm64-dts-renesas-r8a779h0-gray-hawk-single-Add-RPC-.1708354463.git.geert+renesas@glider.be>

	Hi all,

This patch series adds SPI Multi I/O Bus Controller (RPC-IF) support for
the Renesas R-Car V4M (R8A779H0) Soc and QSPI FLASH support for the Gray
Hawk Single development board.

This has been tested on Gray Hawk Single (QSPI read speed is ca. 2.4
MiB/s).

I intend to queue this in renesas-devel for v6.9.
As usual, I have updated my topic branch at [1].

Thanks for your comments!

[1] https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/log/?h=topic/v4m-gray-hawk-single-v2

Cong Dang (2):
  arm64: dts: renesas: r8a779h0: Add RPC node
  arm64: dts: renesas: gray-hawk-single: Add QSPI FLASH support

 .../dts/renesas/r8a779h0-gray-hawk-single.dts | 33 +++++++++++++++++++
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi     | 16 +++++++++
 2 files changed, 49 insertions(+)

-- 
2.34.1

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 konrad.dybcio at linaro.org  Mon Feb 19 07:01:23 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 16:01:23 +0100
Subject: [PATCH 3/8] clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
In-Reply-To: <u7beg6ui3i6nxoaulc3o7ghfkvcsy46ps53k3jynrurdwn6o7o@ppyqoz4jsotc>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
 <20240219-topic-rb1_gpu-v1-3-d260fa854707@linaro.org>
 <u7beg6ui3i6nxoaulc3o7ghfkvcsy46ps53k3jynrurdwn6o7o@ppyqoz4jsotc>
Message-ID: <d212b700-aedb-4653-80e4-36320b33e51e@linaro.org>

On 19.02.2024 15:54, Andrew Halaney wrote:
> On Mon, Feb 19, 2024 at 02:35:48PM +0100, Konrad Dybcio wrote:
>> Commit 134b55b7e19f ("clk: qcom: support Huayra type Alpha PLL")
>> introduced an entry to the alpha offsets array, but diving into QCM2290
>> downstream and some documentation, it turned out that the name Huayra
>> apparently has been used quite liberally across many chips, even with
>> noticeably different hardware.
>>
>> Introduce another set of offsets and a new configure function for the
>> Huayra PLL found on QCM2290. This is required e.g. for the consumers
>> of GPUCC_PLL0 to properly start.
>>
>> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
>> ---
>>  drivers/clk/qcom/clk-alpha-pll.c | 45 ++++++++++++++++++++++++++++++++++++++++
>>  drivers/clk/qcom/clk-alpha-pll.h |  3 +++
>>  2 files changed, 48 insertions(+)
>>
>> diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
>> index 8a412ef47e16..61b5abd13782 100644
>> --- a/drivers/clk/qcom/clk-alpha-pll.c
>> +++ b/drivers/clk/qcom/clk-alpha-pll.c
>> @@ -244,6 +244,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
>>  		[PLL_OFF_OPMODE] = 0x30,
>>  		[PLL_OFF_STATUS] = 0x3c,
>>  	},
>> +	[CLK_ALPHA_PLL_TYPE_HUAYRA_2290] =  {
>> +		[PLL_OFF_L_VAL] = 0x04,
>> +		[PLL_OFF_ALPHA_VAL] = 0x08,
>> +		[PLL_OFF_USER_CTL] = 0x0c,
>> +		[PLL_OFF_CONFIG_CTL] = 0x10,
>> +		[PLL_OFF_CONFIG_CTL_U] = 0x14,
>> +		[PLL_OFF_CONFIG_CTL_U1] = 0x18,
>> +		[PLL_OFF_TEST_CTL] = 0x1c,
>> +		[PLL_OFF_TEST_CTL_U] = 0x20,
>> +		[PLL_OFF_TEST_CTL_U1] = 0x24,
>> +		[PLL_OFF_OPMODE] = 0x28,
>> +		[PLL_OFF_STATUS] = 0x38,
>> +	},
>>  };
>>  EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
>>  
>> @@ -779,6 +792,38 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
>>  	return clamp(rate, min_freq, max_freq);
>>  }
>>  
>> +void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
>> +				   const struct alpha_pll_config *config)
>> +{
>> +	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
>> +	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);
>> +	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);
>> +	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);
>> +	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);
>> +	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);
>> +	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
>> +	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
>> +	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
>> +
>> +	/* Set PLL_BYPASSNL */
>> +	regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL);
>> +
>> +	/* Wait 5 us between setting BYPASS and deasserting reset */
>> +	mb();
>> +	udelay(5);
>> +
>> +	/* Take PLL out from reset state */
>> +	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
>> +
>> +	/* Wait 50us for PLL_LOCK_DET bit to go high */
>> +	mb();
>> +	usleep_range(50, 55);
> 
> I *think* you'd want to use a read to ensure your write goes through
> prior to your sleep... from memory-barriers.txt:
> 
> 	5. A readX() by a CPU thread from the peripheral will complete before
> 	   any subsequent delay() loop can begin execution on the same thread.
> 	   This ensures that two MMIO register writes by the CPU to a peripheral
> 	   will arrive at least 1us apart if the first write is immediately read
> 	   back with readX() and udelay(1) is called prior to the second
> 	   writeX():
> 
> 		writel(42, DEVICE_REGISTER_0); // Arrives at the device...
> 		readl(DEVICE_REGISTER_0);
> 		udelay(1);
> 		writel(42, DEVICE_REGISTER_1); // ...at least 1us before this.
> 
> also https://youtu.be/i6DayghhA8Q?si=7lp0be35q1HRmlnV&t=1677
> for more references on this topic.

I mentioned this feels very iffy in the cover letter, but it's a combination
of two things:

1. i followed what qualcomm downstream code did

2. qualcomm downstream code is not known for being always correct



I suppose a readback would be the correct solution, but then it should be
done for all similar calls in this driver.

Although this code has shipped in literally hundreds of millions of devices
and it didn't explode badly :P (i'm not defending it, though)

Konrad


From maz at kernel.org  Mon Feb 19 07:02:07 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 15:02:07 +0000
Subject: next-20240219: arm64: boot failed - gic_of_init
In-Reply-To: <a7d8e529-9a44-3f88-50ef-d87b80515c36@huawei.com>
References: <CA+G9fYugYiLd7MDn3wCxK+x5Td9WO-VUX2OvOtTN7D1d4GHCfg@mail.gmail.com>
 <86edd84wer.wl-maz@kernel.org> <86cyss4rl7.wl-maz@kernel.org>
 <a7d8e529-9a44-3f88-50ef-d87b80515c36@huawei.com>
Message-ID: <20adfff58d44d09d0e968f5c502f28ce@kernel.org>

On 2024-02-19 14:46, Zenghui Yu wrote:
> On 2024/2/19 19:32, Marc Zyngier wrote:
>> For what it is worth, I've just tested both defconfig and my own
>> configuration with both 4k (kvmtool, QEMU+KVM and on SynQuacer) and
>> 16k (kvmtool), without any obvious problem.
> 
> I had a quick test on top of next-20240219 with defconfig.  I can
> reproduce it with QEMU parameter '-cpu max -accel tcg', but things are
> fine with '-cpu max,lpa2=off -accel tcg'.
> 
> Bisection shows that the problem happens when we start putting the
> latest arm64 and kvmarm changes together.  The following hack fixes the
> problem for me (but I **only** write it for kernel built with defconfig
> with ARM64_4K_PAGES=y atm).
> 
> I can investigate it further tomorrow (as it's too late now ;-) ).  Or
> maybe Marc or Catalin can help fix it with a proper approach.
> 
> diff --git a/arch/arm64/kernel/cpufeature.c 
> b/arch/arm64/kernel/cpufeature.c
> index 4f7662008ede..babdc3f4721b 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2798,6 +2798,7 @@ static const struct arm64_cpu_capabilities
> arm64_features[] = {
> | 		.sign = FTR_SIGNED,
> | 		.field_pos = ID_AA64MMFR0_EL1_TGRAN4_SHIFT,
> | 		.min_field_value = ID_AA64MMFR0_EL1_TGRAN4_52_BIT,
> |+		.max_field_value = BIT(ID_AA64MMFR0_EL1_TGRAN4_WIDTH - 1) - 1,
> | #else
> | 		.sign = FTR_UNSIGNED,
> | 		.field_pos = ID_AA64MMFR0_EL1_TGRAN16_SHIFT,

Yup, got to that point too.

Working on a slightly more elaborate fix.

Thanks,

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


From josua at solid-run.com  Mon Feb 19 07:02:59 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 19 Feb 2024 16:02:59 +0100
Subject: [PATCH v7 0/4] arm64: dts: add description for solidrun am642 som
 and hummingboard evb
Message-ID: <20240219-add-am64-som-v7-0-0e6e95b0a05d@solid-run.com>

This series adds DT bindings and dts descriptions for SolidRun AM642
based SoM and Hummingboard EVB.

Additionally a commit from downstream vendor kernel are included,
enhancing support for pru based ethernet.
I wasn't sure how to properly annotate it in commit description /
signed-off area ...:

1. add description for "Industrial Ethernet Peripherals" (IEP) to am64
   https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/commit/arch/arm64/boot/dts/ti/k3-am64-main.dtsi?h=ti-linux-6.1.y-cicd&id=5afb73d82a014b59462162d960b350b8c58e5ae6
   IEP is already supported in-tree by a driver, and used in
   k3-am65-main.dtsi.

To avoid introducing new dtbs_check errors, respective patches were
submitted via rtc, mtd and iio trees.

Only one error remains which is common to all k3-am64:

- 'mux-controller' does not match any of the regexes

To: Nishanth Menon <nm at ti.com>
To: Vignesh Raghavendra <vigneshr at ti.com>
To: Tero Kristo <kristo at kernel.org>
To: Rob Herring <robh+dt at kernel.org>
To: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
To: Conor Dooley <conor+dt at kernel.org>
Cc: Yazan Shhady <yazan.shhady at solid-run.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: devicetree at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Josua Mayer <josua at solid-run.com>

Changes in v7:
- split rtc, iio, mtd bindings to go via respective trees:
  - iio: https://lore.kernel.org/r/20240219-iio-hdc20x0-interrupt-binding-v7-1-c8ffb39c3768 at solid-run.com
  - mtd: https://lore.kernel.org/r/20240219-mtd-flash-interrupt-binding-v7-1-206e30a656fa at solid-run.com
  - rtc: https://lore.kernel.org/r/20240219-rtc-abracon-convert-bindings-v7-1-aca4fc3b8cec at solid-run.com
- Link to v6: https://lore.kernel.org/r/20240212-add-am64-som-v6-0-b59edb2bc8c3 at solid-run.com

Changes in v6:
- renamed pinctrl nodes to *-default-pins
  (reported by Vignesh Raghavendra <vigneshr at ti.com>)
  (dropped Reviewed-by: Andrew Davis <afd at ti.com> because all the rename)
- removed tabs from pinctrl comments to shorten lines
- updated humidity sensor yaml with interrupts property
- updated spi-nor flash yaml with interrupts property
- Link to v5: https://lore.kernel.org/r/20240211-add-am64-som-v5-0-790ed7121249 at solid-run.com

Changes in v5:
- abracon,abx80x.yaml:
  - reworded 'compatible' description
  - removed $ref to interrupts.yaml
  - nested example in fake i2c
  - changed maintainer to rtc list
  (reported by Conor Dooley <conor at kernel.org>)
- patch 4/5 dts:
  - re-added status properties for sdhci nodes
    k3-am64-main.dtsi has been changed in-tree since v1
    such that sdhci nodes are explicitly status disabled now.
  - picked up reviewed-by
  (reported by Andrew Davis <afd at ti.com>)
- Link to v4: https://lore.kernel.org/r/20240202-add-am64-som-v4-0-5f8b12af5e71 at solid-run.com

Changes in v4:
- abracon,abx80x.yaml: fixed dtc error in example irq reference
- Link to v3: https://lore.kernel.org/r/20240202-add-am64-som-v3-0-2f44023d50e9 at solid-run.com

Changes in v3:
- removed lots more status properties, double-checked against soc dtsi
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
  (reported by Andrew Davis <afd at ti.com>)
- removed intentionally-disabled pcie node from dts
- rewrote yaml bindings to use enum instead of anyof+const+description
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
- abracon yaml
  - added missing maintainer
  - added diode type property type
  - added example
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>)
  - added reference to /schemas/interrupts.yaml#
- use generic name for pru ethernet controller node
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>)
- removed unnamed dmas from pru ethernet controller node
- moved pcie/usb3 features to dtb overlays
- Link to v2: https://lore.kernel.org/r/20240112-add-am64-som-v2-0-1385246c428c at solid-run.com

Changes in v2:
- reordered patchset to drop separate patch adding iep handle to som
- moved dtbs_check warnings to cover letter
- converted abracon abx80x rtc bindings to yaml
- updated dts:
  - remove unnecessary status properties
  - changed non-generic node names
  - use color property for led descriptions,
    they have no default function on evaluation board
  - drop earlycon bootargs from chosen node
  (reported by Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>)
- converted charger node to comment, part not assembled, has no bindings
- picked up acked-by on board bindings patch
- Link to v1: https://lore.kernel.org/r/20240103-add-am64-som-v1-0-dda1f9227aef at solid-run.com

---
Josua Mayer (3):
      dt-bindings: arm: ti: Add bindings for SolidRun AM642 HummingBoard-T
      arm64: dts: add description for solidrun am642 som and evaluation board
      arm64: dts: ti: hummingboard-t: add overlays for m.2 pci-e and usb-3

Suman Anna (1):
      arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes

 Documentation/devicetree/bindings/arm/ti/k3.yaml   |   7 +
 arch/arm64/boot/dts/ti/Makefile                    |   7 +
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi           |  24 +
 .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  |  45 ++
 .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  |  44 ++
 arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 594 +++++++++++++++++++++
 7 files changed, 1013 insertions(+)
---
base-commit: 83d0ff463b50d2395e05339a34e35d14ba82043f
change-id: 20240101-add-am64-som-51a1ca47edf3

Best regards,
-- 
Josua Mayer <josua at solid-run.com>



From josua at solid-run.com  Mon Feb 19 07:03:00 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 19 Feb 2024 16:03:00 +0100
Subject: [PATCH v7 1/4] dt-bindings: arm: ti: Add bindings for SolidRun
 AM642 HummingBoard-T
In-Reply-To: <20240219-add-am64-som-v7-0-0e6e95b0a05d@solid-run.com>
References: <20240219-add-am64-som-v7-0-0e6e95b0a05d@solid-run.com>
Message-ID: <20240219-add-am64-som-v7-1-0e6e95b0a05d@solid-run.com>

Add bindings for SolidRun AM642 HummingBoard-T Board, which is the
evaluation board for SolidRun AM642 SoM.

Signed-off-by: Josua Mayer <josua at solid-run.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/ti/k3.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml
index c6506bccfe88..0233a8b0b6fc 100644
--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml
+++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -87,6 +87,13 @@ properties:
           - const: tq,am642-tqma6442l
           - const: ti,am642
 
+      - description: K3 AM642 SoC SolidRun SoM based boards
+        items:
+          - enum:
+              - solidrun,am642-hummingboard-t
+          - const: solidrun,am642-sr-som
+          - const: ti,am642
+
       - description: K3 AM654 SoC
         items:
           - enum:

-- 
2.35.3



From josua at solid-run.com  Mon Feb 19 07:03:01 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 19 Feb 2024 16:03:01 +0100
Subject: [PATCH v7 2/4] arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
In-Reply-To: <20240219-add-am64-som-v7-0-0e6e95b0a05d@solid-run.com>
References: <20240219-add-am64-som-v7-0-0e6e95b0a05d@solid-run.com>
Message-ID: <20240219-add-am64-som-v7-2-0e6e95b0a05d@solid-run.com>

From: Suman Anna <s-anna at ti.com>

The ICSSG IP on AM64x SoCs have two Industrial Ethernet Peripherals (IEPs)
to manage/generate Industrial Ethernet functions such as time stamping.
Each IEP sub-module is sourced from an internal clock mux that can be
derived from either of the IP instance's ICSSG_IEP_GCLK or from another
internal ICSSG CORE_CLK mux. Add both the IEP nodes for both the ICSSG
instances. The IEP clock is currently configured to be derived
indirectly from the ICSSG_ICLK running at 250 MHz.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
Signed-off-by: Suman Anna <s-anna at ti.com>
Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index e348114f42e0..9d2dad8ae8df 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -1244,6 +1244,18 @@ icssg0_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg0_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
+		icssg0_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
 		icssg0_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
@@ -1385,6 +1397,18 @@ icssg1_iepclk_mux: iepclk-mux at 30 {
 			};
 		};
 
+		icssg1_iep0: iep at 2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
+		icssg1_iep1: iep at 2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
 		icssg1_mii_rt: mii-rt at 32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;

-- 
2.35.3



From josua at solid-run.com  Mon Feb 19 07:03:02 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 19 Feb 2024 16:03:02 +0100
Subject: [PATCH v7 3/4] arm64: dts: add description for solidrun am642 som
 and evaluation board
In-Reply-To: <20240219-add-am64-som-v7-0-0e6e95b0a05d@solid-run.com>
References: <20240219-add-am64-som-v7-0-0e6e95b0a05d@solid-run.com>
Message-ID: <20240219-add-am64-som-v7-3-0e6e95b0a05d@solid-run.com>

Add description for the SolidRun AM642 SoM, and HummingBoard-T
evaluation board.

The SoM features:
- 1x cpsw ethernet with phy
- 2x pru ethernet with phy
- eMMC
- spi flash (assembly option)

Additionally microSD and usb-2.0 otg are included in the SoM
description as they are supported boot sources for the SOC boot-rom.

The Carrier provides:
- 3x RJ45 connector
- 2x M.2 connector
- USB-2.0 Hub
- USB-A Connector
- LEDs
- 2x CAN transceiver
- 1x RS485 transceiver
- sensors

The M.2 connectors support either USB-3.1 or PCI-E depending on status
of a mux. By default the mux is switched off.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/Makefile                    |   1 +
 arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts | 292 ++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi        | 594 +++++++++++++++++++++
 3 files changed, 887 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..bd73ce06acba 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -38,6 +38,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-hdmi-audio.dtbo
 
 # Boards with AM64x SoC
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
new file mode 100644
index 000000000000..234d76e4e944
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * DTS for SolidRun AM642 HummingBoard-T,
+ * running on Cortex A53.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-am642.dtsi"
+#include "k3-am642-sr-som.dtsi"
+
+/ {
+	model = "SolidRun AM642 HummingBoard-T";
+	compatible = "solidrun,am642-hummingboard-t", "solidrun,am642-sr-som", "ti,am642";
+
+	aliases {
+		serial5 = &main_uart3;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&leds_default_pins>;
+
+		/* D24 */
+		led1: led-1 {
+			label = "led1";
+			gpios = <&main_gpio0 29 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		/* D25 */
+		led2: led-2 {
+			label = "led2";
+			gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		/* D26 */
+		led3: led-3 {
+			label = "led3";
+			gpios = <&main_gpio0 33 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+	};
+
+	regulator-m2-3v3 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&regulator_pcie_3v3_default_pins>;
+		regulator-name = "m2-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&main_gpio1 17 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	regulator-vpp-1v8 {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&regulator_vpp_1v8_default_pins>;
+		regulator-name = "vpp-1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		gpio = <&main_gpio1 78 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	serdes_mux: mux-controller {
+		compatible = "gpio-mux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&serdes_mux_default_pins>;
+		#mux-control-cells = <0>;
+		/*
+		 * Mux has 2 IOs:
+		 * - select: 0 = USB-3 (M2); 1 = PCIE (M1)
+		 * - shutdown: 0 = active; 1 = disabled (high impedance)
+		 */
+		mux-gpios = <&main_gpio1 40 GPIO_ACTIVE_HIGH>, <&main_gpio1 41 GPIO_ACTIVE_HIGH>;
+		/* default disabled */
+		idle-state = <2>;
+	};
+};
+
+&main_gpio0 {
+	m2-reset-hog {
+		gpio-hog;
+		gpios = <12 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m2-reset";
+	};
+
+	m1-m2-w-disable1-hog {
+		gpio-hog;
+		gpios = <32 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m1-m2-pcie-w-disable1";
+	};
+
+	m1-m2-w-disable2-hog {
+		gpio-hog;
+		gpios = <34 GPIO_ACTIVE_LOW>;
+		output-low; /* deasserted */
+		line-name = "m1-m2-pcie-w-disable2";
+	};
+};
+
+&main_gpio1 {
+	m1-pcie-clkreq0-hog {
+		gpio-hog;
+		gpios = <11 GPIO_ACTIVE_LOW>;
+		input;
+		line-name = "m1-pcie-clkreq0";
+	};
+
+	m2-pcie-clkreq-hog {
+		gpio-hog;
+		gpios = <35 GPIO_ACTIVE_LOW>;
+		input;
+		line-name = "m2-pcie-clkreq";
+	};
+};
+
+&main_i2c0 {
+	pinctrl-0 = <&main_i2c0_default_pins>, <&main_i2c0_int_default_pins>;
+
+	humidity-sensor at 41 {
+		compatible = "ti,hdc2010";
+		reg = <0x41>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+	light-sensor at 44 {
+		compatible = "ti,opt3001";
+		reg = <0x44>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+	};
+
+	/* charger at 6a */
+};
+
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_default_pins>;
+	status = "okay";
+
+	rtc at 69 {
+		compatible = "abracon,abx80x";
+		reg = <0x69>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtc_int_default_pins>;
+		abracon,tc-diode = "schottky";
+		abracon,tc-resistor = <3>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
+	};
+};
+
+&main_mcan0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan0_default_pins>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <8000000>;
+	};
+};
+
+&main_mcan1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan1_default_pins>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <8000000>;
+	};
+};
+
+&main_pmx0 {
+	leds_default_pins: leds-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0074, PIN_OUTPUT, 7) /* GPMC0_AD14.GPIO0_29 */
+			AM64X_IOPAD(0x0078, PIN_OUTPUT, 7) /* GPMC0_AD15.GPIO0_30 */
+			AM64X_IOPAD(0x0088, PIN_OUTPUT, 7) /* GPMC0_OEn_REn.GPIO0_33 */
+		>;
+	};
+
+	main_i2c0_int_default_pins: main-i2c0-int-default-pins {
+		pinctrl-single,pins = <
+			/* external pull-up on Carrier */
+			AM64X_IOPAD(0x0098, PIN_INPUT, 7) /* GPMC0_WAIT0.GPIO0_37 */
+		>;
+	};
+
+	main_i2c1_default_pins: main-i2c1-default-pins {
+		pinctrl-single,pins = <
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x0268, PIN_INPUT, 0) /* I2C1_SCL.I2C1_SCL */
+			AM64X_IOPAD(0x026c, PIN_INPUT, 0) /* I2C1_SDA.I2C1_SDA */
+		>;
+	};
+
+	main_mcan0_default_pins: main-mcan0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0254, PIN_INPUT, 0) /* MCAN0_RX.MCAN0_RX */
+			AM64X_IOPAD(0x0250, PIN_OUTPUT, 0) /* MCAN0_TX.MCAN0_TX */
+		>;
+	};
+
+	main_mcan1_default_pins: main-mcan1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x025c, PIN_INPUT, 0) /* MCAN1_RX.MCAN1_RX */
+			AM64X_IOPAD(0x0258, PIN_OUTPUT, 0) /* MCAN1_TX.MCAN1_TX */
+		>;
+	};
+
+	main_uart3_default_pins: main-uart3-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x016c, PIN_INPUT, 10) /* PRG0_PRU0_GPO3.UART3_CTSn */
+			AM64X_IOPAD(0x0170, PIN_OUTPUT, 10) /* PRG0_PRU0_GPO4.UART3_TXD */
+			AM64X_IOPAD(0x0174, PIN_OUTPUT, 10) /* PRG0_PRU0_GPO5.UART3_RTSn */
+			AM64X_IOPAD(0x01ac, PIN_INPUT, 10) /* PRG0_PRU0_GPO19.UART3_RXD */
+		>;
+	};
+
+	pcie0_default_pins: pcie0-default-pins {
+		pinctrl-single,pins = <
+			/* connector M2 RESET */
+			AM64X_IOPAD(0x0030, PIN_OUTPUT, 7) /* OSPI0_CSn1.GPIO0_12 */
+			/* connectors M1 & M2 W_DISABLE1 */
+			AM64X_IOPAD(0x0084, PIN_OUTPUT, 7) /* GPMC0_ADVN_ALE.GPIO0_32 */
+			/* connectors M1 & M2 W_DISABLE2 */
+			AM64X_IOPAD(0x008c, PIN_OUTPUT, 7) /* GPMC0_WEN.GPIO0_34 */
+			/* connectors M1 & M2 PERST0 (PCI Reset) */
+			AM64X_IOPAD(0x019c, PIN_OUTPUT, 7) /* PRG0_PRU0_GPO15.GPIO1_15 */
+			/* connector M1 CLKREQ0 */
+			AM64X_IOPAD(0x018c, PIN_INPUT, 7) /* PRG0_PRU0_GPO11.GPIO1_11 */
+			/* connector M2 CLKREQ0 */
+			AM64X_IOPAD(0x01ec, PIN_INPUT, 7) /* PRG0_PRU1_GPO15.GPIO1_35 */
+		>;
+	};
+
+	regulator_pcie_3v3_default_pins: regulator-pcie-3v3-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01a4, PIN_OUTPUT, 7) /* PRG0_PRU0_GPO17.GPIO1_17 */
+		>;
+	};
+
+	regulator_vpp_1v8_default_pins: regulator-vpp-1v8-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x029c, PIN_OUTPUT, 7) /* MMC1_SDWP.GPIO1_78 */
+		>;
+	};
+
+	rtc_int_default_pins: rtc-int-default-pins {
+		pinctrl-single,pins = <
+			/* external pull-up on Carrier */
+			AM64X_IOPAD(0x00b4, PIN_INPUT, 7) /* GPMC0_CSn3.GPIO0_44 */
+		>;
+	};
+
+	serdes_mux_default_pins: serdes-mux-default-pins {
+		pinctrl-single,pins = <
+			/* SEL, 10k pull-down on carrier, 2.2k pullup on SoM */
+			AM64X_IOPAD(0x0200, PIN_OUTPUT, 7) /* PRG0_MDIO0_MDIO.GPIO1_40 */
+			/* EN */
+			AM64X_IOPAD(0x0204, PIN_OUTPUT, 7) /* PRG0_MDIO0_MDC.GPIO1_41 */
+		>;
+	};
+};
+
+&main_uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart3_default_pins>;
+	uart-has-rtscts;
+	rs485-rts-active-low;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+&usb0 {
+	dr_mode = "host";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
new file mode 100644
index 000000000000..c19d0b8bbf0f
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
@@ -0,0 +1,594 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ */
+
+#include <dt-bindings/net/ti-dp83869.h>
+
+/ {
+	model = "SolidRun AM642 SoM";
+	compatible = "solidrun,am642-sr-som", "ti,am642";
+
+	aliases {
+		ethernet0 = &cpsw_port1;
+		ethernet1 = &icssg1_emac0;
+		ethernet2 = &icssg1_emac1;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		serial2 = &main_uart0;
+	};
+
+	chosen {
+		/* SoC default UART console */
+		stdout-path = "serial2:115200n8";
+	};
+
+	/* PRU Ethernet Controller */
+	ethernet {
+		compatible = "ti,am642-icssg-prueth";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pru_rgmii1_default_pins>, <&pru_rgmii2_default_pins>;
+
+		sram = <&oc_sram>;
+		ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
+		firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+				"ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
+
+		/* configure internal pinmux for mii mode */
+		ti,pruss-gp-mux-sel = <2>, <2>, <2>, <2>, <2>, <2>;
+
+		ti,mii-g-rt = <&icssg1_mii_g_rt>;
+		ti,mii-rt = <&icssg1_mii_rt>;
+		ti,iep = <&icssg1_iep0>, <&icssg1_iep1>;
+
+		/*
+		 * Configure icssg interrupt controller to map pru-internal
+		 * interrupts 8/9 via channels 0/1 to host interrupts 0/1.
+		 *
+		 * For details see interrupt controller documentation:
+		 * Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
+		 */
+		interrupt-parent = <&icssg1_intc>;
+		interrupts = <24 0 2>, <25 1 3>;
+		interrupt-names = "tx_ts0", "tx_ts1";
+
+		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
+		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
+		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
+		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
+		       <&main_pktdma 0x4201 15>; /* ingress slice 1 */
+		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+			    "rx0", "rx1";
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			icssg1_emac0: port at 0 {
+				reg = <0>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4110>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				phy-handle = <&ethernet_phy2>;
+				phy-mode = "rgmii-id";
+			};
+
+			icssg1_emac1: port at 1 {
+				reg = <1>;
+				ti,syscon-rgmii-delay = <&main_conf 0x4114>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+				phy-handle = <&ethernet_phy1>;
+				phy-mode = "rgmii-id";
+			};
+		};
+	};
+
+	/* DDR16SS0:
+	 * - Bank 1 @ 0x080000000-0x0FFFFFFFF: max. 2GB in 32-bit address space
+	 * - Bank 2 @ 0x880000000-0x9FFFFFFFF: max. 6GB in 64-bit address space
+	 */
+	memory at 80000000 {
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+		      <0x00000008 0x80000000 0x00000001 0x80000000>;
+		device_type = "memory";
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		secure_ddr: optee at 9e800000 {
+			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+			no-map;
+		};
+
+		main_r5fss0_core0_dma_memory_region: r5f-dma-memory at a0000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core0_memory_region: r5f-memory at a0100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa0100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_dma_memory_region: r5f-dma-memory at a1000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss0_core1_memory_region: r5f-memory at a1100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa1100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_dma_memory_region: r5f-dma-memory at a2000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core0_memory_region: r5f-memory at a2100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa2100000 0x00 0xf00000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_dma_memory_region: r5f-dma-memory at a3000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3000000 0x00 0x100000>;
+			no-map;
+		};
+
+		main_r5fss1_core1_memory_region: r5f-memory at a3100000 {
+			compatible = "shared-dma-pool";
+			reg = <0x00 0xa3100000 0x00 0xf00000>;
+			no-map;
+		};
+	};
+
+	vdd_mmc0: regulator-vdd-mmc0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd-mmc0";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&cpsw3g {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_default_pins>;
+};
+
+&cpsw3g_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio0_default_pins>;
+	status = "okay";
+
+	ethernet_phy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy0_default_pins>;
+		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 84 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+};
+
+&cpsw_port1 {
+	phy-mode = "rgmii-id";
+	phy-handle = <&ethernet_phy0>;
+};
+
+&cpsw_port2 {
+	status = "disabled";
+};
+
+&icssg1_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pru1_mdio0_default_pins>;
+	status = "okay";
+
+	ethernet_phy1: ethernet-phy at 3 {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy1_default_pins>;
+		ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 20 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+
+	ethernet_phy2: ethernet-phy at f {
+		compatible = "ethernet-phy-id2000.a0f1";
+		reg = <0xf>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ethernet_phy2_default_pins>;
+		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+		/*
+		 * Disable interrupts because ISR never clears 0x0040
+		 *
+		 * interrupt-parent = <&main_gpio1>;
+		 * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+		 */
+		/*
+		 * Disable HW Reset because clock signal is daisy-chained
+		 *
+		 * reset-gpios = <&main_gpio0 52 GPIO_ACTIVE_LOW>;
+		 * reset-assert-us = <1>;
+		 * reset-deassert-us = <30>;
+		 */
+	};
+};
+
+&mailbox0_cluster2 {
+	status = "okay";
+
+	mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+
+	mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+		ti,mbox-rx = <2 0 2>;
+		ti,mbox-tx = <3 0 2>;
+	};
+};
+
+&mailbox0_cluster4 {
+	status = "okay";
+
+	mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+		ti,mbox-rx = <0 0 2>;
+		ti,mbox-tx = <1 0 2>;
+	};
+
+	mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+		ti,mbox-rx = <2 0 2>;
+		ti,mbox-tx = <3 0 2>;
+	};
+};
+
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_default_pins>;
+	status = "okay";
+
+	som_eeprom: eeprom at 50 {
+		compatible = "atmel,24c01";
+		reg = <0x50>;
+		pagesize = <8>;
+	};
+};
+
+&main_pmx0 {
+	/* hog global functions */
+	pinctrl-names = "default";
+	pinctrl-0 = <&ethernet_phy_default_pins>;
+
+	ethernet_phy_default_pins: ethernet-phy-default-pins {
+		pinctrl-single,pins = <
+			/* interrupt / power-down, external pull-up on SoM */
+			AM64X_IOPAD(0x0278, PIN_INPUT, 7) /* EXTINTn.GPIO1_70 */
+		>;
+	};
+
+	ethernet_phy0_default_pins: ethernet-phy0-default-pins {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x0154, PIN_OUTPUT, 7) /* PRG1_PRU1_GPO19.GPIO0_84 */
+			/* reference clock */
+			AM64X_IOPAD(0x0274, PIN_OUTPUT, 5) /* EXT_REFCLK1.CLKOUT0 */
+		>;
+	};
+
+	ethernet_phy1_default_pins: ethernet-phy1-default-pins {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x0150, PIN_OUTPUT, 7) /* PRG1_PRU1_GPO18.GPIO0_20 */
+			/* led0, external pull-down on SoM */
+			AM64X_IOPAD(0x0128, PIN_INPUT, 7) /* PRG1_PRU1_GPO8.GPIO0_73 */
+			/* led1/rxer */
+			AM64X_IOPAD(0x011c, PIN_INPUT, 7) /* PRG1_PRU1_GPO5.GPIO0_70 */
+		>;
+	};
+
+	ethernet_phy2_default_pins: ethernet-phy2-default-pins {
+		pinctrl-single,pins = <
+			/* reset */
+			AM64X_IOPAD(0x00d4, PIN_OUTPUT, 7) /* PRG1_PRU0_GPO7.GPIO0_52 */
+			/* led0, external pull-down on SoM */
+			AM64X_IOPAD(0x00d8, PIN_INPUT, 7) /* PRG1_PRU0_GPO8.GPIO0_53 */
+			/* led1/rxer */
+			AM64X_IOPAD(0x00cc, PIN_INPUT, 7) /* PRG1_PRU0_GPO5.GPIO0_50 */
+		>;
+	};
+
+	main_i2c0_default_pins: main-i2c0-default-pins {
+		pinctrl-single,pins = <
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x0260, PIN_INPUT, 0) /* I2C0_SCL.I2C0_SCL */
+			AM64X_IOPAD(0x0264, PIN_INPUT, 0) /* I2C0_SDA.I2C0_SDA */
+		>;
+	};
+
+	/*
+	 * main_mmc0_default_pins: main-mmc0-default-pins
+	 *
+	 * MMC0_CMD: no padconfig
+	 * MMC0_CLK: no padconfig, external pull-up on SoM
+	 * MMC0_DAT0: no padconfig
+	 * MMC0_DAT1: no padconfig
+	 * MMC0_DAT2: no padconfig
+	 * MMC0_DAT3: no padconfig
+	 * MMC0_DAT4: no padconfig
+	 * MMC0_DAT5: no padconfig
+	 * MMC0_DAT6: no padconfig
+	 * MMC0_DAT7: no padconfig
+	 * MMC0_DS: no padconfig, external pull-down on SoM
+	 */
+
+	main_mmc1_default_pins: main-mmc1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0294, PIN_INPUT_PULLUP, 0) /* (J19) MMC1_CMD */
+			AM64X_IOPAD(0x028c, PIN_INPUT, 0) /* MMC1_CLK.MMC1_CLK */
+			AM64X_IOPAD(0x0288, PIN_INPUT_PULLUP, 0) /* MMC1_DAT0.MMC1_DAT0 */
+			AM64X_IOPAD(0x0284, PIN_INPUT_PULLUP, 0) /* MMC1_DAT1.MMC1_DAT1 */
+			AM64X_IOPAD(0x0280, PIN_INPUT_PULLUP, 0) /* MMC1_DAT2.MMC1_DAT2 */
+			AM64X_IOPAD(0x027c, PIN_INPUT_PULLUP, 0) /* MMC1_DAT3.MMC1_DAT3 */
+			/* external pull-down on SoM & Carrier */
+			AM64X_IOPAD(0x0298, PIN_INPUT_PULLUP, 0) /* MMC1_SDCD.MMC1_SDCD */
+			AM64X_IOPAD(0x0290, PIN_INPUT, 0) /* MMC1_CLKLB: clock loopback */
+		>;
+	};
+
+	main_uart0_default_pins: main-uart0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0230, PIN_INPUT, 0) /* UART0_RXD.UART0_RXD */
+			AM64X_IOPAD(0x0234, PIN_OUTPUT, 0) /* UART0_TXD.UART0_TXD */
+		>;
+	};
+
+	mdio0_default_pins: mdio0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01fc, PIN_OUTPUT, 4) /* PRG0_PRU1_GPO19.MDIO0_MDC */
+			AM64X_IOPAD(0x01f8, PIN_INPUT, 4) /* PRG0_PRU1_GPO18.MDIO0_MDIO */
+		>;
+	};
+
+	ospi0_default_pins: ospi0-default-pins {
+		pinctrl-single,pins = <
+			/* external pull-down on SoM */
+			AM64X_IOPAD(0x0000, PIN_OUTPUT, 0) /* OSPI0_CLK.OSPI0_CLK */
+			AM64X_IOPAD(0x0008, PIN_OUTPUT, 0) /* OSPI0_DQS.OSPI0_DQS */
+			/* external pull-up on SoM */
+			AM64X_IOPAD(0x002c, PIN_OUTPUT, 0) /* OSPI0_CSn0.OSPI0_CSn0 */
+			AM64X_IOPAD(0x000c, PIN_INPUT, 0) /* OSPI0_D0.OSPI0_D0 */
+			AM64X_IOPAD(0x0010, PIN_INPUT, 0) /* OSPI0_D1.OSPI0_D1 */
+			AM64X_IOPAD(0x0014, PIN_INPUT, 0) /* OSPI0_D2.OSPI0_D2 */
+			AM64X_IOPAD(0x0018, PIN_INPUT, 0) /* OSPI0_D3.OSPI0_D3 */
+			AM64X_IOPAD(0x001c, PIN_INPUT, 0) /* OSPI0_D4.OSPI0_D4 */
+			AM64X_IOPAD(0x0020, PIN_INPUT, 0) /* OSPI0_D5.OSPI0_D5 */
+			AM64X_IOPAD(0x0024, PIN_INPUT, 0) /* OSPI0_D6.OSPI0_D6 */
+			AM64X_IOPAD(0x0028, PIN_INPUT, 0) /* OSPI0_D7.OSPI0_D7 */
+		>;
+	};
+
+	ospi0_flash0_default_pins: ospi0-flash0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0034, PIN_OUTPUT, 7) /* OSPI0_CSn2.GPIO0_13 */
+			AM64X_IOPAD(0x0038, PIN_INPUT, 7) /* OSPI0_CSn3.GPIO0_14 */
+		>;
+	};
+
+	pru1_mdio0_default_pins: pru1-mdio0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x015c, PIN_OUTPUT, 0) /* PRG1_MDIO0_MDC.PRG1_MDIO0_MDC */
+			AM64X_IOPAD(0x0158, PIN_INPUT, 0) /* PRG1_MDIO0_MDIO.PRG1_MDIO0_MDIO */
+		>;
+	};
+
+	pru_rgmii1_default_pins: pru-rgmii1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x00b8, PIN_INPUT, 2) /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
+			AM64X_IOPAD(0x00bc, PIN_INPUT, 2) /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
+			AM64X_IOPAD(0x00c0, PIN_INPUT, 2) /* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
+			AM64X_IOPAD(0x00c4, PIN_INPUT, 2) /* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
+			AM64X_IOPAD(0x00d0, PIN_INPUT, 2) /* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
+			AM64X_IOPAD(0x00c8, PIN_INPUT, 2) /* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
+			AM64X_IOPAD(0x00e4, PIN_OUTPUT, 2) /* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
+			AM64X_IOPAD(0x00e8, PIN_OUTPUT, 2) /* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
+			AM64X_IOPAD(0x00ec, PIN_OUTPUT, 2) /* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
+			AM64X_IOPAD(0x00f0, PIN_OUTPUT, 2) /* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
+			AM64X_IOPAD(0x00f8, PIN_INPUT, 2) /* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
+			AM64X_IOPAD(0x00f4, PIN_OUTPUT, 2) /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
+		>;
+	};
+
+	pru_rgmii2_default_pins: pru-rgmii2-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x0108, PIN_INPUT, 2) /* PRG1_PRU1_GPO0.RGMII2_RD0 */
+			AM64X_IOPAD(0x010c, PIN_INPUT, 2) /* PRG1_PRU1_GPO1.RGMII2_RD1 */
+			AM64X_IOPAD(0x0110, PIN_INPUT, 2) /* PRG1_PRU1_GPO2.RGMII2_RD2 */
+			AM64X_IOPAD(0x0114, PIN_INPUT, 2) /* PRG1_PRU1_GPO3.RGMII2_RD3 */
+			AM64X_IOPAD(0x0120, PIN_INPUT, 2) /* PRG1_PRU1_GPO6.RGMII2_RXC */
+			AM64X_IOPAD(0x0118, PIN_INPUT, 2) /* PRG1_PRU1_GPO4.RGMII2_RX_CTL */
+			AM64X_IOPAD(0x0134, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO11.RGMII2_TD0 */
+			AM64X_IOPAD(0x0138, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO12.RGMII2_TD1 */
+			AM64X_IOPAD(0x013c, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO13.RGMII2_TD2 */
+			AM64X_IOPAD(0x0140, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO14.RGMII2_TD3 */
+			AM64X_IOPAD(0x0148, PIN_INPUT, 2) /* PRG1_PRU1_GPO16.RGMII2_TXC */
+			AM64X_IOPAD(0x0144, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO15.RGMII2_TX_CTL */
+		>;
+	};
+
+	rgmii1_default_pins: rgmii1-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x01cc, PIN_INPUT, 4) /* PRG0_PRU1_GPO7.RGMII1_RD0 */
+			AM64X_IOPAD(0x01d4, PIN_INPUT, 4) /* PRG0_PRU1_GPO9.RGMII1_RD1 */
+			AM64X_IOPAD(0x01d8, PIN_INPUT, 4) /* PRG0_PRU1_GPO10.RGMII1_RD2 */
+			AM64X_IOPAD(0x01f4, PIN_INPUT, 4) /* PRG0_PRU1_GPO17.RGMII1_RD3 */
+			AM64X_IOPAD(0x0188, PIN_INPUT, 4) /* PRG0_PRU0_GPO10.RGMII1_RXC */
+			AM64X_IOPAD(0x0184, PIN_INPUT, 4) /* PRG0_PRU0_GPO9.RGMII1_RX_CTL */
+			AM64X_IOPAD(0x0124, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO7.RGMII1_TD0 */
+			AM64X_IOPAD(0x012c, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO9.RGMII1_TD1 */
+			AM64X_IOPAD(0x0130, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO10.RGMII1_TD2 */
+			AM64X_IOPAD(0x014c, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO17.RGMII1_TD3 */
+			AM64X_IOPAD(0x00e0, PIN_INPUT, 4) /* PRG1_PRU0_GPO10.RGMII1_TXC */
+			AM64X_IOPAD(0x00dc, PIN_OUTPUT, 4) /* PRG1_PRU0_GPO9.RGMII1_TX_CTL */
+		>;
+	};
+
+	usb0_default_pins: usb0-default-pins {
+		pinctrl-single,pins = <
+			AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0) /* USB0_DRVVBUS.USB0_DRVVBUS */
+		>;
+	};
+};
+
+&main_r5fss0_core0 {
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core0>;
+	memory-region = <&main_r5fss0_core0_dma_memory_region>,
+			<&main_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0_core1 {
+	mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core1>;
+	memory-region = <&main_r5fss0_core1_dma_memory_region>,
+			<&main_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss1_core0 {
+	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core0>;
+	memory-region = <&main_r5fss1_core0_dma_memory_region>,
+			<&main_r5fss1_core0_memory_region>;
+};
+
+&main_r5fss1_core1 {
+	mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core1>;
+	memory-region = <&main_r5fss1_core1_dma_memory_region>,
+			<&main_r5fss1_core1_memory_region>;
+};
+
+/* SoC default UART console */
+&main_uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_uart0_default_pins>;
+	status = "okay";
+};
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ospi0_default_pins>;
+	num-cs = <1>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ospi0_flash0_default_pins>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <200000000>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
+		cdns,read-delay = <0>;
+		interrupt-parent = <&main_gpio0>;
+		interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&main_gpio0 13 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&sdhci0 {
+	/* mmc0 pins have no padconfig */
+	bus-width = <8>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+	non-removable;
+	cap-mmc-hw-reset;
+	no-sd;
+	/*
+	 * MMC controller supports switching between 1.8V and 3.3V signalling.
+	 * However MMC0 (unlike MMC1) does not integrate an LDO.
+	 * Explicitly link a regulator node for indicating to the driver which
+	 * voltages are actually usable.
+	 */
+	vqmmc-supply = <&vdd_mmc0>;
+	status = "okay";
+};
+
+/*
+ * microSD is on carrier - however since SoC can boot from it,
+ * configure it just in case.
+ */
+&sdhci1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mmc1_default_pins>;
+	bus-width = <4>;
+	ti,driver-strength-ohm = <50>;
+	disable-wp;
+	status = "okay";
+};
+
+/*
+ * USB settings are a carrier choice - however since SoC can boot from it,
+ * configure as USB-2.0 OTG here, keeping USB-3 serdes disabled.
+ */
+&usb0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_default_pins>;
+	dr_mode = "otg";
+	maximum-speed = "high-speed";
+};
+
+&usbss0 {
+	ti,vbus-divider;
+	ti,usb2-only;
+};

-- 
2.35.3



From josua at solid-run.com  Mon Feb 19 07:03:03 2024
From: josua at solid-run.com (Josua Mayer)
Date: Mon, 19 Feb 2024 16:03:03 +0100
Subject: [PATCH v7 4/4] arm64: dts: ti: hummingboard-t: add overlays for
 m.2 pci-e and usb-3
In-Reply-To: <20240219-add-am64-som-v7-0-0e6e95b0a05d@solid-run.com>
References: <20240219-add-am64-som-v7-0-0e6e95b0a05d@solid-run.com>
Message-ID: <20240219-add-am64-som-v7-4-0e6e95b0a05d@solid-run.com>

HummingBoard-T features two M.2 connectors labeled "M1" and "M2".
The single SerDes lane of the SoC can be routed to either M1 pci-e
signals, or M2 usb-3 signals by a gpio-controlled mux.

Add overlays for each configuration.

Signed-off-by: Josua Mayer <josua at solid-run.com>
---
 arch/arm64/boot/dts/ti/Makefile                    |  6 +++
 .../boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso  | 45 ++++++++++++++++++++++
 .../boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso  | 44 +++++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index bd73ce06acba..cd12720638c7 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -37,8 +37,14 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-imx219.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-hdmi-audio.dtbo
 
 # Boards with AM64x SoC
+k3-am642-hummingboard-t-pcie-dtbs := \
+	k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-pcie.dtbo
+k3-am642-hummingboard-t-usb3-dtbs := \
+	k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-usb3.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-pcie.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-usb3.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
new file mode 100644
index 000000000000..bd9a5caf20da
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable PCI-E.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&pcie0_rc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_default_pins>;
+	reset-gpios = <&main_gpio1 15 GPIO_ACTIVE_HIGH>;
+	phys = <&serdes0_link>;
+	phy-names = "pcie-phy";
+	num-lanes = <1>;
+	status = "okay";
+};
+
+&serdes0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	serdes0_link: phy at 0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		cdns,phy-type = <PHY_TYPE_PCIE>;
+		#phy-cells = <0>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes_ln_ctrl {
+	idle-states = <AM64_SERDES0_LANE0_PCIE0>;
+};
+
+&serdes_mux {
+	idle-state = <1>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
new file mode 100644
index 000000000000..ffcc3bd3c7bc
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua at solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable USB-3.1.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&serdes0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	serdes0_link: phy at 0 {
+		reg = <0>;
+		cdns,num-lanes = <1>;
+		cdns,phy-type = <PHY_TYPE_USB3>;
+		#phy-cells = <0>;
+		resets = <&serdes_wiz0 1>;
+	};
+};
+
+&serdes_ln_ctrl {
+	idle-states = <AM64_SERDES0_LANE0_USB>;
+};
+
+&serdes_mux {
+	idle-state = <0>;
+};
+
+&usbss0 {
+	/delete-property/ ti,usb2-only;
+};
+
+&usb0 {
+	maximum-speed = "super-speed";
+	phys = <&serdes0_link>;
+	phy-names = "cdns3,usb3-phy";
+};

-- 
2.35.3



From devnull+forbidden405.outlook.com at kernel.org  Mon Feb 19 07:05:26 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Mon, 19 Feb 2024 23:05:26 +0800
Subject: [PATCH v3 1/3] arm64: dts: hi3798cv200: fix the size of GICR
In-Reply-To: <20240219-cache-v3-0-a33c57534ae9@outlook.com>
References: <20240219-cache-v3-0-a33c57534ae9@outlook.com>
Message-ID: <20240219-cache-v3-1-a33c57534ae9@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

During boot, Linux kernel complains:

[    0.000000] GIC: GICv2 detected, but range too small and irqchip.gicv2_force_probe not set

This SoC is using a regular GIC-400 and the GICR space size should be
8KB rather than 256B.

With this patch:

[    0.000000] GIC: Using split EOI/Deactivate mode

So this should be the correct fix.

Fixes: 2f20182ed670 ("arm64: dts: hisilicon: add dts files for hi3798cv200-poplar board")
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
Cc: stable at vger.kernel.org
---
 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
index ed1b5a7a6067..d01023401d7e 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
@@ -58,7 +58,7 @@ cpu at 3 {
 	gic: interrupt-controller at f1001000 {
 		compatible = "arm,gic-400";
 		reg = <0x0 0xf1001000 0x0 0x1000>,  /* GICD */
-		      <0x0 0xf1002000 0x0 0x100>;   /* GICC */
+		      <0x0 0xf1002000 0x0 0x2000>;  /* GICC */
 		#address-cells = <0>;
 		#interrupt-cells = <3>;
 		interrupt-controller;

-- 
2.43.0



From devnull+forbidden405.outlook.com at kernel.org  Mon Feb 19 07:05:27 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Mon, 19 Feb 2024 23:05:27 +0800
Subject: [PATCH v3 2/3] arm64: dts: hi3798cv200: add GICH, GICV register
 space and irq
In-Reply-To: <20240219-cache-v3-0-a33c57534ae9@outlook.com>
References: <20240219-cache-v3-0-a33c57534ae9@outlook.com>
Message-ID: <20240219-cache-v3-2-a33c57534ae9@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

This is needed by KVM to make use of VGIC code. Just like regular
GIC-400, PPI #9 is the hypervisor maintenance interrupt. It has been
verified.

Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
index d01023401d7e..fc64d2fa99eb 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
@@ -58,7 +58,11 @@ cpu at 3 {
 	gic: interrupt-controller at f1001000 {
 		compatible = "arm,gic-400";
 		reg = <0x0 0xf1001000 0x0 0x1000>,  /* GICD */
-		      <0x0 0xf1002000 0x0 0x2000>;  /* GICC */
+		      <0x0 0xf1002000 0x0 0x2000>,  /* GICC */
+		      <0x0 0xf1004000 0x0 0x2000>,  /* GICH */
+		      <0x0 0xf1006000 0x0 0x2000>;  /* GICV */
+		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+			      IRQ_TYPE_LEVEL_HIGH)>;
 		#address-cells = <0>;
 		#interrupt-cells = <3>;
 		interrupt-controller;

-- 
2.43.0



From devnull+forbidden405.outlook.com at kernel.org  Mon Feb 19 07:05:25 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Mon, 19 Feb 2024 23:05:25 +0800
Subject: [PATCH v3 0/3] arm64: dts: hi3798cv200: fix GICR size, add cache
 info, maintenance irq and GICH, GICV spaces
Message-ID: <20240219-cache-v3-0-a33c57534ae9@outlook.com>

The patchset fixes some warnings reported by the kernel during boot.

The cache size info is from Processor_Datasheet_v2XX.pdf [1], Section
2.2.1 Master Processor.

The cache line size and the set-associative info are from Cortex-A53
Documentation [2].

>From the doc, it can be concluded that L1 i-cache is 4-way assoc, L1
d-cache is 2-way assoc and L2 cache is 16-way assoc. Calculate the dts
props accordingly.

Also, to use KVM's VGIC code, GICH, GICV registers spaces and maintenance
IRQ are added to the dts with verification.

[1]: https://github.com/96boards/documentation/blob/master/enterprise/poplar/hardware-docs/Processor_Datasheet_v2XX.pdf
[2]: https://developer.arm.com/documentation/ddi0500/j/Level-1-Memory-System

Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
Changes in v3:
- send patches to stable (Andrew Lunn)
- rewrite the commit logs more formally (Andrew Lunn)
- rename l2-cache0 to l2-cache (Krzysztof Kozlowski)
- Link to v2: https://lore.kernel.org/r/20240218-cache-v2-0-1fd919e2bd3e at outlook.com

Changes in v2:
- arm64: dts: hi3798cv200: add GICH, GICV register spces and
  maintainance IRQ.
- Link to v1: https://lore.kernel.org/r/20240218-cache-v1-0-2c0a8a4472e7 at outlook.com

---
Yang Xiwen (3):
      arm64: dts: hi3798cv200: fix the size of GICR
      arm64: dts: hi3798cv200: add GICH, GICV register space and irq
      arm64: dts: hi3798cv200: add cache info

 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 43 +++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)
---
base-commit: 8d3dea210042f54b952b481838c1e7dfc4ec751d
change-id: 20240218-cache-11c8bf7566c2

Best regards,
-- 
Yang Xiwen <forbidden405 at outlook.com>



From devnull+forbidden405.outlook.com at kernel.org  Mon Feb 19 07:05:28 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Mon, 19 Feb 2024 23:05:28 +0800
Subject: [PATCH v3 3/3] arm64: dts: hi3798cv200: add cache info
In-Reply-To: <20240219-cache-v3-0-a33c57534ae9@outlook.com>
References: <20240219-cache-v3-0-a33c57534ae9@outlook.com>
Message-ID: <20240219-cache-v3-3-a33c57534ae9@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

During boot, the kernel complains:

[    0.044029] cacheinfo: Unable to detect cache hierarchy for CPU 0

So add L1/L2 cache info to the dts according to the datasheet. (32KiB L1
i-cache + 32 KiB L1 d-cache + 512 KiB L2 unified cache)

With this patch, the line above is gone and the following info is added
to the output of `lscpu`:

Caches (sum of all):
  L1d:                   128 KiB (4 instances)
  L1i:                   128 KiB (4 instances)
  L2:                    512 KiB (1 instance)

Fixes: 2f20182ed670 ("arm64: dts: hisilicon: add dts files for hi3798cv200-poplar board")
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
Cc: stable at vger.kernel.org
---
 arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi | 37 ++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
index fc64d2fa99eb..f6bc001c3832 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
@@ -31,6 +31,13 @@ cpu at 0 {
 			device_type = "cpu";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2>;
 		};
 
 		cpu at 1 {
@@ -38,6 +45,13 @@ cpu at 1 {
 			device_type = "cpu";
 			reg = <0x0 0x1>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2>;
 		};
 
 		cpu at 2 {
@@ -45,6 +59,13 @@ cpu at 2 {
 			device_type = "cpu";
 			reg = <0x0 0x2>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2>;
 		};
 
 		cpu at 3 {
@@ -52,9 +73,25 @@ cpu at 3 {
 			device_type = "cpu";
 			reg = <0x0 0x3>;
 			enable-method = "psci";
+			d-cache-size = <0x8000>; /* 32 KiB */
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			i-cache-size = <0x8000>; /* 32 KiB */
+			i-cache-line-size = <64>;
+			i-cache-sets = <256>;
+			next-level-cache = <&L2>;
 		};
 	};
 
+	L2: l2-cache {
+		compatible = "cache";
+		cache-unified;
+		cache-size = <0x80000>; /* 512 KiB */
+		cache-line-size = <64>;
+		cache-sets = <512>;
+		cache-level = <2>;
+	};
+
 	gic: interrupt-controller at f1001000 {
 		compatible = "arm,gic-400";
 		reg = <0x0 0xf1001000 0x0 0x1000>,  /* GICD */

-- 
2.43.0



From andriy.shevchenko at linux.intel.com  Mon Feb 19 07:08:54 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Mon, 19 Feb 2024 17:08:54 +0200
Subject: [PATCH v9 1/4] serial: 8250: Add 8250 port clock update method
In-Reply-To: <ow5mvkxa4g7mub3faiytsij4cyaaralcbzyn675jny5355han7@azw65mhkpwjz>
References: <20200723003357.26897-1-Sergey.Semin@baikalelectronics.ru>
 <20200723003357.26897-2-Sergey.Semin@baikalelectronics.ru>
 <ZczD7KPbeRnY4CFc@black.fi.intel.com>
 <raryiklwhctwxcfj3ulbnjcl32owagiccmxpwzmszlh3vm343y@h2ehupm7uiga>
 <Zc5oYJY6W_MCpwhN@smile.fi.intel.com>
 <ow5mvkxa4g7mub3faiytsij4cyaaralcbzyn675jny5355han7@azw65mhkpwjz>
Message-ID: <ZdNvBtOlxo4FlLUH@smile.fi.intel.com>

On Fri, Feb 16, 2024 at 08:19:37PM +0300, Serge Semin wrote:
> On Thu, Feb 15, 2024 at 09:39:12PM +0200, Andy Shevchenko wrote:

...

(thanks for the detailed explanation why you have done it that way)

> If what you suggest is to replace the serial8250_update_uartclk() body
> with a direct uart_port::set_termios() invocation then I don't find it
> being much clearer really. The serial8250_update_uartclk() is
> currently specialized on doing one thing: adjusting the divider in
> case of the UART-clock change. If instead the entire
> serial8250_set_termios() method is called then for a reader it won't
> be easy to understand what is really required for a 8250 serial port
> to perceive the ref-clock change. But from the maintainability point
> of view I guess that it might be safer to just call
> serial8250_set_termios() indeed, since among the other things the
> later method implies the divider update too. Thus the maintainer won't
> need to support the two clock divider update implementations.

> From that perspective I agree, directly calling serial8250_set_termios()
> might be more suitable despite of it' doing more than required.

Would it be possible for you to cook the patch (and test on your HW,
since it seems the only user of that)?

-- 
With Best Regards,
Andy Shevchenko




From d-gole at ti.com  Mon Feb 19 07:14:58 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Mon, 19 Feb 2024 20:44:58 +0530
Subject: TI am625 deepsleep wakeup from main domain
In-Reply-To: <CANh8Qzx-aratebzbkYGLiL+ij5MPmvfuzZtu70AL=9JgLjZ8tw@mail.gmail.com>
References: <CANh8Qzx-aratebzbkYGLiL+ij5MPmvfuzZtu70AL=9JgLjZ8tw@mail.gmail.com>
Message-ID: <20240219151458.2gvc3n6sjt4nyj25@dhruva>

Hi,

On Feb 17, 2024 at 17:15:39 +0100, Fuzzey, Martin wrote:
> Hi all,
> 
> I have deep sleep entry and exit working on TI AM625 using the RTC or
> MCU domain GPIO using the upstream 6.6 kernel plus [0]
> However I am unable to get it to work using a MAIN domain GPIO
> (nothing happens and no measurable change in power consumption on
> wakeup attempt).

Your observation is absolutely expected behaviour. Explaining in detail
below...

> 
> To do that I also applied 3717194f2492 "Input: gpio-keys - add system
> suspend support for dedicated wake irqs"
> (which is already in mainline but not -6.6)

Yes, this is one of the missing pieces, but an even more important thing
is io isolation is missing.


> 
> Then in DT (based on the TI docs)
> &main_pmx0 {
>     /* attempt at GPIO domain wakeup - when working move to SoC dtsi */
>     compatible = "ti,am654-padconf";
>     interrupt-parent = <&gic500>;
>     interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
>     interrupt-controller;
>     #interrupt-cells = <1>;
> 
>     pinctrl_flb_carrier_gpio_keys: flb-gpiokeys-grp {
>         pinctrl-single,pins = <
>             AM62X_IOPAD(0x1a8, PIN_INPUT,  7) /*(D20)
> MCASP0_AFSX.GPIO1_12 -  SODIMM 32 */
>         >;
>     };
> };
> 
> gpio-keys {
>     compatible = "gpio-keys";
>     pinctrl-names = "default";
>     pinctrl-0 = <&pinctrl_flb_carrier_gpio_keys>;
> 
>     key-gpio {
>         interrupts-extended = <&main_gpio1 12 IRQ_TYPE_EDGE_BOTH>,
> <&main_pmx0 0x1a8>;
>         interrupt-names = "irq", "wakeup";
>         label = "GPIO Button";
>         linux,code = <KEY_WAKEUP>;
>         wakeup-source;
>     };
> };
> 
> (The reason for overriding the compatible on the the pinmux mode is
> that the pinctrl_single driver already has the appropriate bits for
> that compatible
> sure it's a hack but should be ok for testing):
> 
> static const struct pcs_soc_data pinctrl_single_am654 = {
>     .flags = PCS_QUIRK_SHARED_IRQ | PCS_CONTEXT_LOSS_OFF,
>     .irq_enable_mask = (1 << 29),   /* WKUP_EN */
>     .irq_status_mask = (1 << 30),   /* WKUP_EVT */
> };
> 
> static const struct of_device_id pcs_of_match[] = {
> ...
>     { .compatible = "ti,am654-padconf", .data = &pinctrl_single_am654 },
> ...
> };
> 
> With this I see that bit 29 (WKUP_EN) of the pad config register is
> being set but it doesn't wake up..

That's good to know.

> I do get input events when not suspended (so that should eliminate bad
> hardware) and have checked that the button GPIO line still has power
> in suspend.

Umm how have you checked that it has power in suspend, I'm not sure?
The concept of IO daisychain is that GPIO controller itself WILL lose
power, however the "pad" associated with that particular GPIO stays
alive and has the ability to generate an interrupt to the DM which can
trigger the resume.

> 
> Am I missing any other pieces here?

The missing piece is the set_io_isolation [0]. I had removed that chunk
of code from V7 because we couldn't arrive at a satisfactory conclusion
as to where isolation should be set and removed. You can refer to V6 of
the same patch series [1] for more context.

Just for testing and if it's urgent, you can try and apply the V6 series
and it may just work for you...  I don't currently have a -next branch
with all of my patches applied otherwise would've shared.
The patches thus may not cleanly apply and may need a bit of merge
conflict resolutions.
If I get some time I'll try to apply necessary patches on -next sometime
later, but can't say when exactly due to other things at hand rn.

> 
> One thing I don't really understand is how the DM firmware knows what
> wakeup sources should be enabled.

Great qn. The DM wouldn't really know what wakeup sources are enabled,
so it just assumes today that wakeup can potentially come from any
hardware supported wakeup sources - IO daisychain / wakup UART/ reset
button etc...
It's Linux job in this context to properly configure and enable the
wakeup source that it wants to wakeup from in low power mode like
deepsleep. The DM will get the wake IRQ directly as long as linux has
setup the wakeup source properly, which does seem to be the case
according to what you've setup. You were only missing the io isolation
bits most likely.

I would also urge you to pick the latest boot binaries from ti-u-boot as
there's strong dependency on the correct OPTEE, ATF, other firmwares
that are all packaged as part of the boot bins. We hope to upstream the
remaining few patches to u-boot soon.

[0] https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/drivers/firmware/ti_sci.c?h=ti-linux-6.1.y-cicd#n1868
[1] https://lore.kernel.org/all/20230803064247.503036-5-d-gole at ti.com/

-- 
Best regards,
Dhruva Gole <d-gole at ti.com>


From puranjay12 at gmail.com  Mon Feb 19 07:15:20 2024
From: puranjay12 at gmail.com (Puranjay Mohan)
Date: Mon, 19 Feb 2024 15:15:20 +0000
Subject: [PATCH bpf-next v7 1/2] arm64: patching: implement text_poke API
In-Reply-To: <79088869-a5ba-4335-b3ab-8a2a26d8be74@huaweicloud.com>
References: <20240125133159.85086-1-puranjay12@gmail.com>
 <20240125133159.85086-2-puranjay12@gmail.com>
 <79088869-a5ba-4335-b3ab-8a2a26d8be74@huaweicloud.com>
Message-ID: <mb61p34topjsn.fsf@gmail.com>

Xu Kuohai <xukuohai at huaweicloud.com> writes:

> On 1/25/2024 9:31 PM, Puranjay Mohan wrote:
>> The text_poke API is used to implement functions like memcpy() and
>> memset() for instruction memory (RO+X). The implementation is similar to
>> the x86 version.
>> 
>> This will be used by the BPF JIT to write and modify BPF programs. There
>> could be more users of this in the future.
>> 
>> Signed-off-by: Puranjay Mohan <puranjay12 at gmail.com>
>> ---
>>   arch/arm64/include/asm/patching.h |  2 +
>>   arch/arm64/kernel/patching.c      | 80 +++++++++++++++++++++++++++++++
>>   2 files changed, 82 insertions(+)
>> 
>> diff --git a/arch/arm64/include/asm/patching.h b/arch/arm64/include/asm/patching.h
>> index 68908b82b168..587bdb91ab7a 100644
>> --- a/arch/arm64/include/asm/patching.h
>> +++ b/arch/arm64/include/asm/patching.h
>> @@ -8,6 +8,8 @@ int aarch64_insn_read(void *addr, u32 *insnp);
>>   int aarch64_insn_write(void *addr, u32 insn);
>>   
>>   int aarch64_insn_write_literal_u64(void *addr, u64 val);
>> +void *aarch64_insn_set(void *dst, u32 insn, size_t len);
>> +void *aarch64_insn_copy(void *dst, void *src, size_t len);
>>   
>>   int aarch64_insn_patch_text_nosync(void *addr, u32 insn);
>>   int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
>> diff --git a/arch/arm64/kernel/patching.c b/arch/arm64/kernel/patching.c
>> index b4835f6d594b..5c2d34d890cf 100644
>> --- a/arch/arm64/kernel/patching.c
>> +++ b/arch/arm64/kernel/patching.c
>> @@ -105,6 +105,86 @@ noinstr int aarch64_insn_write_literal_u64(void *addr, u64 val)
>>   	return ret;
>>   }
>>   
>> +typedef void text_poke_f(void *dst, void *src, size_t patched, size_t len);
>> +
>
> How about removing the argument 'patched' and passing 'src + patched' as the
> second argument?
>

The memcpy() function needs 'src + patched' but the memset() needs only the 'src' and
will ignore the 'patched'. To make these implementations generic, I pass
both src and patched separately and allow the implementation of
text_poke_f() to use them.

If you think there is a better way to implement this then I would love
to use that.

>> +static void *__text_poke(text_poke_f func, void *addr, void *src, size_t len)
>> +{
>> +	unsigned long flags;
>> +	size_t patched = 0;
>> +	size_t size;
>> +	void *waddr;
>> +	void *ptr;
>> +	int ret;
>> +
>> +	raw_spin_lock_irqsave(&patch_lock, flags);
>> +
>> +	while (patched < len) {
>> +		ptr = addr + patched;
>> +		size = min_t(size_t, PAGE_SIZE - offset_in_page(ptr),
>> +			     len - patched);
>> +
>> +		waddr = patch_map(ptr, FIX_TEXT_POKE0);
>> +		func(waddr, src, patched, size);
>> +		patch_unmap(FIX_TEXT_POKE0);
>> +
>> +		if (ret < 0) {
>
> Where is 'ret' assigned?
>

Will remove the error check in next version as func() is of type void
and this error check was left from the previous version.

Thanks,
Puranjay


From srinivas.kandagatla at linaro.org  Mon Feb 19 07:17:24 2024
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Mon, 19 Feb 2024 15:17:24 +0000
Subject: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
In-Reply-To: <htsty5siakcu2nxxapiuq7pgs27tjwkb3yxgmfs3bonsl6kylw@joa2viypstoa>
References: <20240205182810.58382-1-brgl@bgdev.pl>
 <htsty5siakcu2nxxapiuq7pgs27tjwkb3yxgmfs3bonsl6kylw@joa2viypstoa>
Message-ID: <98dea91a-5d2b-432e-8949-46179c824d1b@linaro.org>

On 17/02/2024 19:58, Bjorn Andersson wrote:
> On Mon, Feb 05, 2024 at 07:27:58PM +0100, Bartosz Golaszewski wrote:
>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>
>> We've established the need for using separate secured memory pools for
>> SCM and QSEECOM
> 
> Where has this need been established, what is the actual problem you're
> solving with this series?

SHMbridge will restrict the amount of memory that TZ can see, making 
system more secure.

Need for having different pools makes this more scalable overall, so 
that different usecases can run seamlessly. ex: loading a TA and SCM calls.

> 
> Does SCM and QSEECOM, as it's implemented in the kernel today, not work
> satisfactory?
> 
>> as well as the upcoming scminvoke driver.
>>
> 
> Is smcinvoke driver upstreaming blocked by not transitioning the scm
> driver to a "secure memory pool"?
> 
> Is this happening now, or do we need to merge this series when that day
> comes?

SMCInvoke development is happening now, I see no reason for this 
patchset to wait for it.

This series can go as it is for two reasons.
1> improves system security in general
2> Hardware Wrapped key support patches also use this which are also in 
good shape and tested, ready to be merged.

> 
>> It's also become clear that in order to be future-proof, the new
>> allocator must be an abstraction layer of a higher level as the SHM
>> Bridge will not be the only memory protection mechanism that we'll see
>> upstream. Hence the rename to TrustZone Memory rather than SCM Memory
>> allocator.
>>
>> Also to that end: the new allocator is its own module now and provides a
>> Kconfig choice menu for selecting the mode of operation (currently
>> default and SHM Bridge).
>>
>> Tested on sm8550 and sa8775p with the Inline Crypto Engine and
>> remoteproc.
>>
> 
> It's reasonable to assume from mentioning of this (and Andrew's t-b),
> that the patchset has only been tested on recent platforms that indeed
> does implement shmbridge. Can you please share the list of other
> platforms that you've tested this on, and can you please get someone
> from IPQ to also give their r-b or t-b?

We will try to reachout to someone who has access to these.

thanks,
Srini

> 
> Regards,
> Bjorn
> 
>> v6 -> v7:
>> - fix a Kconfig issue: TZMEM must select GENERIC_ALLOCATOR
>>
>> v5 -> v6:
>> Fixed two issues reported by autobuilders:
>> - add a fix for memory leaks in the qseecom driver as the first patch for
>>    easier backporting to the v6.6.y branch
>> - explicitly cast the bus address stored in a variable of type dma_addr_t
>>    to phys_addr_t expected by the genpool API
>>
>> v4 -> v5:
>> - fix the return value from qcom_tzmem_init() if SHM Bridge is not supported
>> - remove a comment that's no longer useful
>> - collect tags
>>
>> v3 -> v4:
>> - include linux/sizes.h for SZ_X macros
>> - use dedicated RCU APIs to dereference radix tree slots
>> - fix kerneldocs
>> - fix the comment in patch 14/15: it's the hypervisor, not the TrustZone
>>    that creates the SHM bridge
>>
>> v2 -> v3:
>> - restore pool management and use separate pools for different users
>> - don't use the new allocator in qcom_scm_pas_init_image() as the
>>    TrustZone will create an SHM bridge for us here
>> - rewrite the entire series again for most part
>>
>> v1 -> v2:
>> - too many changes to list, it's a complete rewrite as explained above
>>
>> Bartosz Golaszewski (12):
>>    firmware: qcom: add a dedicated TrustZone buffer allocator
>>    firmware: qcom: scm: enable the TZ mem allocator
>>    firmware: qcom: scm: smc: switch to using the SCM allocator
>>    firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
>>    firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
>>    firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
>>    firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ
>>      allocator
>>    firmware: qcom: qseecom: convert to using the TZ allocator
>>    firmware: qcom: scm: add support for SHM bridge operations
>>    firmware: qcom: tzmem: enable SHM Bridge support
>>    firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
>>    arm64: defconfig: enable SHM Bridge support for the TZ memory
>>      allocator
>>
>>   MAINTAINERS                                   |   8 +
>>   arch/arm64/configs/defconfig                  |   1 +
>>   drivers/firmware/qcom/Kconfig                 |  31 ++
>>   drivers/firmware/qcom/Makefile                |   1 +
>>   .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++---------
>>   drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
>>   drivers/firmware/qcom/qcom_scm.c              | 179 +++++----
>>   drivers/firmware/qcom/qcom_scm.h              |   6 +
>>   drivers/firmware/qcom/qcom_tzmem.c            | 365 ++++++++++++++++++
>>   drivers/firmware/qcom/qcom_tzmem.h            |  13 +
>>   include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
>>   include/linux/firmware/qcom/qcom_scm.h        |   6 +
>>   include/linux/firmware/qcom/qcom_tzmem.h      |  28 ++
>>   13 files changed, 685 insertions(+), 268 deletions(-)
>>   create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
>>   create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
>>   create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h
>>
>> -- 
>> 2.40.1
>>


From catalin.marinas at arm.com  Mon Feb 19 07:18:33 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 19 Feb 2024 15:18:33 +0000
Subject: [PATCH v6 12/18] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <892caa6a-e4fe-4009-aa33-0570526961c5@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-13-ryan.roberts@arm.com>
 <Zc9UQy-mtYAzNWm2@arm.com>
 <892caa6a-e4fe-4009-aa33-0570526961c5@arm.com>
Message-ID: <ZdNxSRR9MgvtMVao@arm.com>

On Fri, Feb 16, 2024 at 12:53:43PM +0000, Ryan Roberts wrote:
> On 16/02/2024 12:25, Catalin Marinas wrote:
> > On Thu, Feb 15, 2024 at 10:31:59AM +0000, Ryan Roberts wrote:
> >> +pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
> >> +{
> >> +	/*
> >> +	 * Gather access/dirty bits, which may be populated in any of the ptes
> >> +	 * of the contig range. We may not be holding the PTL, so any contiguous
> >> +	 * range may be unfolded/modified/refolded under our feet. Therefore we
> >> +	 * ensure we read a _consistent_ contpte range by checking that all ptes
> >> +	 * in the range are valid and have CONT_PTE set, that all pfns are
> >> +	 * contiguous and that all pgprots are the same (ignoring access/dirty).
> >> +	 * If we find a pte that is not consistent, then we must be racing with
> >> +	 * an update so start again. If the target pte does not have CONT_PTE
> >> +	 * set then that is considered consistent on its own because it is not
> >> +	 * part of a contpte range.
> >> +*/
[...]
> > After writing the comments above, I think I figured out that the whole
> > point of this loop is to check that the ptes in the contig range are
> > still consistent and the only variation allowed is the dirty/young
> > state to be passed to the orig_pte returned. The original pte may have
> > been updated by the time this loop finishes but I don't think it
> > matters, it wouldn't be any different than reading a single pte and
> > returning it while it is being updated.
> 
> Correct. The pte can be updated at any time, before after or during the reads.
> That was always the case. But now we have to cope with a whole contpte block
> being repainted while we are reading it. So we are just checking to make sure
> that all the ptes that we read from the contpte block are consistent with
> eachother and therefore we can trust that the access/dirty bits we gathered are
> consistent.

I've been thinking a bit more about this - do any of the callers of
ptep_get_lockless() check the dirty/access bits? The only one that seems
to care is ptdump but in that case I'd rather see the raw bits for
debugging rather than propagating the dirty/access bits to the rest in
the contig range.

So with some clearer documentation on the requirements, I think we don't
need an arm64-specific ptep_get_lockless() (unless I missed something).

-- 
Catalin


From lpieralisi at kernel.org  Mon Feb 19 07:21:26 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Mon, 19 Feb 2024 16:21:26 +0100
Subject: [PATCH v10 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>
Message-ID: <ZdNx9op+MhzF5FNB@lpieralisi>

On Mon, Feb 19, 2024 at 10:11:45AM -0500, Frank Li wrote:
> On Mon, Feb 05, 2024 at 12:33:21PM -0500, Frank Li wrote:
> > first 6 patches use drvdata: flags to simplify some switch-case code.
> > Improve maintaince and easy to read code.
> > 
> 
> @Lorenzo Pieralisi:
> 
> 	Do you have chance to look other patches?

Yes, they are fine.

> 	Mani's apply EP side change. 
> 	'PCI: imx6: Add iMX95 Endpoint (EP) support' need be rebased. 

What does that mean ? I think it is best to pull the series in a single
branch if there are not any dependencies on other branches.

Thanks,
Lorenzo

> Frank
> 
> > Then add imx95 basic pci host function.
> > 
> > follow two patch do endpoint code clean up.
> > Then add imx95 basic endpont function.
> > 
> > Compared with v2, added EP function support and some fixes,  please change
> > notes at each patches.
> > 
> > Change from v9 to v10
> > - remove two patches:
> > >   dt-bindings: imx6q-pcie: Add linux,pci-domain as required for iMX8MQ
> > >   PCI: imx6: Using "linux,pci-domain" as slot ID
> > it is not good solution to fixed hardcode check to get controller id.
> > Will see better solution later.
> > 
> > dt-binding pass pcie node:
> > 
> > pcie0: pcie at 4c300000 {
> >                         compatible = "fsl,imx95-pcie";
> >                         reg = <0 0x4c300000 0 0x40000>,
> >                                 <0 0x4c360000 0 0x10000>,
> >                                 <0 0x4c340000 0 0x20000>,
> >                                 <0 0x60100000 0 0xfe00000>;
> >                         reg-names = "dbi", "atu", "app", "config";
> >                         #address-cells = <3>;
> >                         #size-cells = <2>;
> >                         device_type = "pci";
> >                         linux,pci-domain = <0>;
> >                         bus-range = <0x00 0xff>;
> >                         ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
> >                                  <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
> >                         num-lanes = <1>;
> >                         num-viewport = <8>;
> >                         interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
> >                         interrupt-names = "msi";
> >                         #interrupt-cells = <1>;
> >                         interrupt-map-mask = <0 0 0 0x7>;
> >                         interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0 0 0 2 &gic 0 0 GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0 0 0 3 &gic 0 0 GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0 0 0 4 &gic 0 0 GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
> >                         fsl,max-link-speed = <3>;
> >                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
> >                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
> >                         assigned-clock-parents = <0>, <0>,
> >                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
> >                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> >                         /* 0x30~0x37 stream id for pci0 */
> >                         /*
> >                          * iommu-map = <0x000 &apps_smmu 0x30 0x1>,
> >                          * <0x100 &apps_smmu 0x31 0x1>;
> >                          */
> >                         status = "disabled";
> >                 };
> > 
> > pcie1: pcie-ep at 4c380000 {
> >                         compatible = "fsl,imx95-pcie-ep";
> >                         reg = <0 0x4c380000 0 0x20000>,
> >                               <0 0x4c3e0000 0 0x1000>,
> >                               <0 0x4c3a0000 0 0x1000>,
> >                               <0 0x4c3c0000 0 0x10000>,
> >                               <0 0x4c3f0000 0 0x10000>,
> >                               <0xa 0 1 0>;
> >                         reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
> >                         interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
> >                         interrupt-names = "dma";
> >                         fsl,max-link-speed = <3>;
> >                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
> >                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
> >                         assigned-clock-parents = <0>, <0>,
> >                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
> >                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> >                         status = "disabled";
> >                 };
> > 
> > Frank Li (13):
> >   PCI: imx6: Simplify clock handling by using clk_bulk*() function
> >   PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
> >   PCI: imx6: Simplify reset handling by using by using
> >     *_FLAG_HAS_*_RESET
> >   PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
> >   PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
> >   PCI: imx6: Simplify switch-case logic by involve init_phy callback
> >   dt-bindings: imx6q-pcie: Clean up irrationality clocks check
> >   dt-bindings: imx6q-pcie: Restruct reg and reg-name
> >   PCI: imx6: Add iMX95 PCIe Root Complex support
> >   PCI: imx6: Clean up get addr_space code
> >   PCI: imx6: Add epc_features in imx6_pcie_drvdata
> >   dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
> >   PCI: imx6: Add iMX95 Endpoint (EP) support
> > 
> > Richard Zhu (1):
> >   dt-bindings: imx6q-pcie: Add imx95 pcie compatible string
> > 
> >  .../bindings/pci/fsl,imx6q-pcie-common.yaml   |  17 +-
> >  .../bindings/pci/fsl,imx6q-pcie-ep.yaml       |  46 +-
> >  .../bindings/pci/fsl,imx6q-pcie.yaml          |  49 +-
> >  drivers/pci/controller/dwc/pci-imx6.c         | 634 ++++++++++--------
> >  4 files changed, 436 insertions(+), 310 deletions(-)
> > 
> > -- 
> > 2.34.1
> > 


From Frank.li at nxp.com  Mon Feb 19 07:11:45 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 19 Feb 2024 10:11:45 -0500
Subject: [PATCH v10 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <20240205173335.1120469-1-Frank.Li@nxp.com>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
Message-ID: <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>

On Mon, Feb 05, 2024 at 12:33:21PM -0500, Frank Li wrote:
> first 6 patches use drvdata: flags to simplify some switch-case code.
> Improve maintaince and easy to read code.
> 

@Lorenzo Pieralisi:

	Do you have chance to look other patches?
	Mani's apply EP side change. 
	'PCI: imx6: Add iMX95 Endpoint (EP) support' need be rebased. 

Frank

> Then add imx95 basic pci host function.
> 
> follow two patch do endpoint code clean up.
> Then add imx95 basic endpont function.
> 
> Compared with v2, added EP function support and some fixes,  please change
> notes at each patches.
> 
> Change from v9 to v10
> - remove two patches:
> >   dt-bindings: imx6q-pcie: Add linux,pci-domain as required for iMX8MQ
> >   PCI: imx6: Using "linux,pci-domain" as slot ID
> it is not good solution to fixed hardcode check to get controller id.
> Will see better solution later.
> 
> dt-binding pass pcie node:
> 
> pcie0: pcie at 4c300000 {
>                         compatible = "fsl,imx95-pcie";
>                         reg = <0 0x4c300000 0 0x40000>,
>                                 <0 0x4c360000 0 0x10000>,
>                                 <0 0x4c340000 0 0x20000>,
>                                 <0 0x60100000 0 0xfe00000>;
>                         reg-names = "dbi", "atu", "app", "config";
>                         #address-cells = <3>;
>                         #size-cells = <2>;
>                         device_type = "pci";
>                         linux,pci-domain = <0>;
>                         bus-range = <0x00 0xff>;
>                         ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
>                                  <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
>                         num-lanes = <1>;
>                         num-viewport = <8>;
>                         interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
>                         interrupt-names = "msi";
>                         #interrupt-cells = <1>;
>                         interrupt-map-mask = <0 0 0 0x7>;
>                         interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
>                                         <0 0 0 2 &gic 0 0 GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
>                                         <0 0 0 3 &gic 0 0 GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
>                                         <0 0 0 4 &gic 0 0 GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
>                         fsl,max-link-speed = <3>;
>                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
>                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
>                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
>                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
>                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
>                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
>                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
>                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
>                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
>                         assigned-clock-parents = <0>, <0>,
>                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
>                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
>                         /* 0x30~0x37 stream id for pci0 */
>                         /*
>                          * iommu-map = <0x000 &apps_smmu 0x30 0x1>,
>                          * <0x100 &apps_smmu 0x31 0x1>;
>                          */
>                         status = "disabled";
>                 };
> 
> pcie1: pcie-ep at 4c380000 {
>                         compatible = "fsl,imx95-pcie-ep";
>                         reg = <0 0x4c380000 0 0x20000>,
>                               <0 0x4c3e0000 0 0x1000>,
>                               <0 0x4c3a0000 0 0x1000>,
>                               <0 0x4c3c0000 0 0x10000>,
>                               <0 0x4c3f0000 0 0x10000>,
>                               <0xa 0 1 0>;
>                         reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
>                         interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
>                         interrupt-names = "dma";
>                         fsl,max-link-speed = <3>;
>                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
>                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
>                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
>                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
>                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
>                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
>                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
>                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
>                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
>                         assigned-clock-parents = <0>, <0>,
>                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
>                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
>                         status = "disabled";
>                 };
> 
> Frank Li (13):
>   PCI: imx6: Simplify clock handling by using clk_bulk*() function
>   PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
>   PCI: imx6: Simplify reset handling by using by using
>     *_FLAG_HAS_*_RESET
>   PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
>   PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
>   PCI: imx6: Simplify switch-case logic by involve init_phy callback
>   dt-bindings: imx6q-pcie: Clean up irrationality clocks check
>   dt-bindings: imx6q-pcie: Restruct reg and reg-name
>   PCI: imx6: Add iMX95 PCIe Root Complex support
>   PCI: imx6: Clean up get addr_space code
>   PCI: imx6: Add epc_features in imx6_pcie_drvdata
>   dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
>   PCI: imx6: Add iMX95 Endpoint (EP) support
> 
> Richard Zhu (1):
>   dt-bindings: imx6q-pcie: Add imx95 pcie compatible string
> 
>  .../bindings/pci/fsl,imx6q-pcie-common.yaml   |  17 +-
>  .../bindings/pci/fsl,imx6q-pcie-ep.yaml       |  46 +-
>  .../bindings/pci/fsl,imx6q-pcie.yaml          |  49 +-
>  drivers/pci/controller/dwc/pci-imx6.c         | 634 ++++++++++--------
>  4 files changed, 436 insertions(+), 310 deletions(-)
> 
> -- 
> 2.34.1
> 


From maz at kernel.org  Mon Feb 19 07:27:52 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 15:27:52 +0000
Subject: next-20240219: arm64: boot failed - gic_of_init
In-Reply-To: <a7d8e529-9a44-3f88-50ef-d87b80515c36@huawei.com>
References: <CA+G9fYugYiLd7MDn3wCxK+x5Td9WO-VUX2OvOtTN7D1d4GHCfg@mail.gmail.com>
	<86edd84wer.wl-maz@kernel.org>
	<86cyss4rl7.wl-maz@kernel.org>
	<a7d8e529-9a44-3f88-50ef-d87b80515c36@huawei.com>
Message-ID: <86a5nw4gp3.wl-maz@kernel.org>

On Mon, 19 Feb 2024 14:46:46 +0000,
Zenghui Yu <yuzenghui at huawei.com> wrote:
> 
> On 2024/2/19 19:32, Marc Zyngier wrote:
> > For what it is worth, I've just tested both defconfig and my own
> > configuration with both 4k (kvmtool, QEMU+KVM and on SynQuacer) and
> > 16k (kvmtool), without any obvious problem.
> 
> I had a quick test on top of next-20240219 with defconfig.  I can
> reproduce it with QEMU parameter '-cpu max -accel tcg', but things are
> fine with '-cpu max,lpa2=off -accel tcg'.
> 
> Bisection shows that the problem happens when we start putting the
> latest arm64 and kvmarm changes together.  The following hack fixes the
> problem for me (but I **only** write it for kernel built with defconfig
> with ARM64_4K_PAGES=y atm).
> 
> I can investigate it further tomorrow (as it's too late now ;-) ).  Or
> maybe Marc or Catalin can help fix it with a proper approach.
> 
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 4f7662008ede..babdc3f4721b 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2798,6 +2798,7 @@ static const struct arm64_cpu_capabilities
> arm64_features[] = {
> | 		.sign = FTR_SIGNED,
> | 		.field_pos = ID_AA64MMFR0_EL1_TGRAN4_SHIFT,
> | 		.min_field_value = ID_AA64MMFR0_EL1_TGRAN4_52_BIT,
> |+		.max_field_value = BIT(ID_AA64MMFR0_EL1_TGRAN4_WIDTH - 1) - 1,
> | #else
> | 		.sign = FTR_UNSIGNED,
> | 		.field_pos = ID_AA64MMFR0_EL1_TGRAN16_SHIFT,

I've posted my take on this at [1], which hopefully matches what you
were aiming at.

Thanks,

	M.

[1] https://lore.kernel.org/all/86bk8c4gyh.wl-maz at kernel.org/


-- 
Without deviation from the norm, progress is not possible.


From vladimir.oltean at nxp.com  Mon Feb 19 07:30:16 2024
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Mon, 19 Feb 2024 17:30:16 +0200
Subject: [RESEND PATCH net v4 1/2] soc: fsl: qbman: Always disable
 interrupts when taking cgr_lock
In-Reply-To: <20240215162327.3663092-1-sean.anderson@seco.com>
References: <20240215162327.3663092-1-sean.anderson@seco.com>
Message-ID: <20240219153016.ntltc76bphwrv6hn@skbuf>

Hi Sean,

On Thu, Feb 15, 2024 at 11:23:26AM -0500, Sean Anderson wrote:
> smp_call_function_single disables IRQs when executing the callback. To
> prevent deadlocks, we must disable IRQs when taking cgr_lock elsewhere.
> This is already done by qman_update_cgr and qman_delete_cgr; fix the
> other lockers.
> 
> Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
> CC: stable at vger.kernel.org
> Signed-off-by: Sean Anderson <sean.anderson at seco.com>
> Reviewed-by: Camelia Groza <camelia.groza at nxp.com>
> Tested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> ---
> I got no response the first time I sent this, so I am resending to net.
> This issue was introduced in a series which went through net, so I hope
> it makes sense to take it via net.
> 
> [1] https://lore.kernel.org/linux-arm-kernel/20240108161904.2865093-1-sean.anderson at seco.com/
> 
> (no changes since v3)
> 
> Changes in v3:
> - Change blamed commit to something more appropriate
> 
> Changes in v2:
> - Fix one additional call to spin_unlock

Leo Li (Li Yang) is no longer with NXP. Until we figure out within NXP
how to continue with the maintainership of drivers/soc/fsl/, yes, please
continue to submit this series to 'net'. I would also like to point
out to Arnd that this is the case.

Arnd, a large portion of drivers/soc/fsl/ is networking-related
(dpio, qbman). Would it make sense to transfer the maintainership
of these under the respective networking drivers, to simplify the
procedures?

Also, your patches are whitespace-damaged. They do not apply to the
kernel, and patchwork shows this as well.
https://patchwork.kernel.org/project/netdevbpf/patch/20240215162327.3663092-1-sean.anderson at seco.com/

Please repost with this fixed.


From Dharma.B at microchip.com  Mon Feb 19 07:30:52 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Mon, 19 Feb 2024 15:30:52 +0000
Subject: [PATCH v2] dt-bindings: interrupt-controller: Convert Atmel AIC
 to json-schema
In-Reply-To: <20240213-estranged-charger-bf0372f367e0@spud>
References: <20240209100122.61335-1-dharma.b@microchip.com>
 <20240212140824.GA107736-robh@kernel.org>
 <003d61c9-b914-4e1c-b3f8-1140ea640039@microchip.com>
 <20240213-estranged-charger-bf0372f367e0@spud>
Message-ID: <a97650cd-8e06-4df6-9757-826c00a4d7cc@microchip.com>

Hi Rob and Conor,

On 14/02/24 12:43 am, Conor Dooley wrote:
> On Tue, Feb 13, 2024 at 04:23:36AM +0000,Dharma.B at microchip.com  wrote:
>> On 12/02/24 7:38 pm, Rob Herring wrote:
>>> On Fri, Feb 09, 2024 at 03:31:22PM +0530, Dharma Balasubiramani wrote:
>>>> +  atmel,external-irqs:
>>>> +    $ref: /schemas/types.yaml#/definitions/uint32-array
>>>> +    description: u32 array of external irqs.
>>> Constraints on the array size and/or entry values?
>> The hardware's support for external IRQs may differ, which is why a u32
>> array is utilized. This choice is based on the fact that IRQ numbers are
>> commonly expressed as integers, and a 32-bit unsigned integer provides a
>> standardized size capable of representing a broad range of numbers. This
>> size is more than adequate for accommodating IRQ numbering.
> I don't think Rob was questioning your use of u32s, but rather the fact
> that you do not limit the values at all nor the number of values.

The peripheral identification defined at the product level corresponds 
to the interrupt source number.

SoC           External Interrupts    Peripheral ID
AT91RM9200    - IRQ0?IRQ6            25 - 31
SAMA5D2       - IRQ0?IRQn            49
SAMA5D3       - IRQ0?IRQn            47
SAMA5D4       - IRQ0?IRQn            56
SAM9x60       - IRQ0?IRQn            31

To reflect these constraints in bindings, I intend to make the following 
changes.

   atmel,external-irqs:
     $ref: /schemas/types.yaml#/definitions/uint32-array
     description: u32 array of external irqs.
     if:
       properties:
         compatible:
           contains:
             const: atmel,at91rm9200-aic
     then:
       minItems: 1
       maxItems: 7
     else:
       minItems: 1
       maxItems: 1


-- 
With Best Regards,
Dharma B.


From brgl at bgdev.pl  Mon Feb 19 07:33:55 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 16:33:55 +0100
Subject: [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from drivers/pinctrl/nomadik/
In-Reply-To: <e031566a85ae0da0ee71dffba5d87c6414ef83e1.camel@pengutronix.de>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com> <e031566a85ae0da0ee71dffba5d87c6414ef83e1.camel@pengutronix.de>
Message-ID: <CAMRc=Me-oEx9S0w=XhwC4MzV9uzV0o0HnWBfNSstcqg5jpXyZg@mail.gmail.com>

On Thu, Feb 15, 2024 at 11:03?AM Philipp Zabel <p.zabel at pengutronix.de> wrote:
>
> On Mi, 2024-02-14 at 17:23 +0100, Th?o Lebrun wrote:
> [...]
> > diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
> > new file mode 100644
> > index 000000000000..e39477e1a58f
> > --- /dev/null
> > +++ b/drivers/gpio/gpio-nomadik.c
> > @@ -0,0 +1,660 @@
> [...]
> > +static int nmk_gpio_probe(struct platform_device *dev)
> > +{
> [...]
> > +     ret = gpiochip_add_data(chip, nmk_chip);
>
> Use devm_gpiochip_add_data() to cleanup on unbind, before nmk_chip goes
> away. Or make the driver un-unbindable via suppress_bind_attrs. In that
> case you could drop devm_ prefixes everywhere for consistency.
>

No! Why? What about error paths in probe() where you want to undo everything?

Bart

> regards
> Philipp


From andre.przywara at arm.com  Mon Feb 19 07:36:32 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 19 Feb 2024 15:36:32 +0000
Subject: [PATCH v5 0/7] add support for H616 thermal system
Message-ID: <20240219153639.179814-1-andre.przywara@arm.com>

Hi,

this is v5 of this series originally by Martin, only some cosmetic
changes this time, for instance  mentioning experiments with the SRAM
controller registers to confirm that it's not an SRAM region which fixes
the temperature reporting issue.
See the Changelog below for more details.
==================

This series introduces support for the thermal sensors in the Allwinner
H616 SoCs, which includes its siblings H618 and T507. The actual
temperature reading turns out to be very similar to the H6 SoC, just
with support for two more sensors. One nasty complication is caused
by reports about temperatures above 200C, which are related to the
firmware being run (because the vendor U-Boot contains a hack avoiding
this problem). Some investigation and digging in BSP code later
we identified that bit 16 in register 0x3000000 (SYS_CFG) needs to be
cleared for the raw temperature register values to contain reasonable
values.
To achieve this, patch 1/7 exports this very register from the already
existing SRAM/syscon device. Patch 5/7 then adds code to the thermal
driver to find that device via a new DT property, and query its regmap
to clear bit 16 in there.
Patch 4/7 reworks the existing H6 calibration function to become
compatible with the H616, many thanks to Maksim for figuring this out.
This makes the actual enablement patch 6/7 very easy.

The rest of the patches are straightforward and build on Martin's
original work, with some simplifications, resulting in more code sharing.

Please have a look!

Cheers,
Andre

Changelog v4 .. v5:
- add tags
- extend commit message of SRAM controller patch (1/7)
- remove extra empty line (1/7)
- use global static constant for SRAM regmap field (5/7)

Changelog v3 .. v4:
- rebase on top of v6.8-rc2
- rework SYS_CFG bit poking patches to avoid syscon
- use sram lock for the SRAM driver regmap as well
- correctly advertise new allwinner,sram property in binding
- fix conditional definition of sram property
- new patch 4/7 to make the H6 and H616 calibrate functions compatible
- drop now obsolete definition of sun50i_h616_ths_calibrate()

Changelog v2 .. v3:
- rebase on top of v6.7-rc3
- add patches to clear bit 16 in SYS_CFG register 0x3000000
- add syscon to the binding documentation
- add patch explaining the unknown control register value

Changelog v1 .. v2:
- Fix typos
- Remove h616 calc and init functions
- Use TEMP_CALIB_MASK insteaf of 0xffff
- Adjust calibration function to new offset and scale
- Add proper comment to bindings patch
- Split delta calculations to 2 lines
- Add parentheses around caldata[2|3] >> 12
- Negate bindings if for clocks


Andre Przywara (3):
  soc: sunxi: sram: export register 0 for THS on H616
  thermal: sun8i: explain unknown H6 register value
  thermal: sun8i: add SRAM register access code

Maksim Kiselev (1):
  thermal: sun8i: extend H6 calibration to support 4 sensors

Martin Botka (3):
  dt-bindings: thermal: sun8i: Add H616 THS controller
  thermal: sun8i: add support for H616 THS controller
  arm64: dts: allwinner: h616: Add thermal sensor and zones

 .../thermal/allwinner,sun8i-a83t-ths.yaml     |  34 +++--
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi |  88 +++++++++++++
 drivers/soc/sunxi/sunxi_sram.c                |  22 ++++
 drivers/thermal/sun8i_thermal.c               | 123 +++++++++++++++---
 4 files changed, 235 insertions(+), 32 deletions(-)

-- 
2.25.1



From andre.przywara at arm.com  Mon Feb 19 07:36:33 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 19 Feb 2024 15:36:33 +0000
Subject: [PATCH v5 1/7] soc: sunxi: sram: export register 0 for THS on H616
In-Reply-To: <20240219153639.179814-1-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
Message-ID: <20240219153639.179814-2-andre.przywara@arm.com>

The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
in the SRAM control block. If bit 16 is set (the reset value), the
temperature readings of the THS are way off, leading to reports about
200C, at normal ambient temperatures. Clearing this bits brings the
reported values down to the expected values.
The BSP code clears this bit in firmware (U-Boot), and has an explicit
comment about this, but offers no real explanation.

Experiments in U-Boot show that register 0x0 has no effect on the SRAM C
visibility: all tested bit settings still allow full read and write
access by the CPU to the whole of SRAM C. Only bit 24 of the register at
offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling
the THS switch functionality as an SRAM region would not reflect reality.

Since we should not rely on firmware settings, allow other code (the THS
driver) to access this register, by exporting it through the already
existing regmap. This mimics what we already do for the LDO control and
the EMAC register.

To avoid concurrent accesses to the same register at the same time, by
the SRAM switch code and the regmap code, use the same lock to protect
the access. The regmap subsystem allows to use an existing lock, so we
just need to hook in there.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/soc/sunxi/sunxi_sram.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
index 4458b2e0562b0..6eb6cf06278e6 100644
--- a/drivers/soc/sunxi/sunxi_sram.c
+++ b/drivers/soc/sunxi/sunxi_sram.c
@@ -287,6 +287,7 @@ EXPORT_SYMBOL(sunxi_sram_release);
 struct sunxi_sramc_variant {
 	int num_emac_clocks;
 	bool has_ldo_ctrl;
+	bool has_ths_offset;
 };
 
 static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
@@ -308,8 +309,10 @@ static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
 
 static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
 	.num_emac_clocks = 2,
+	.has_ths_offset = true,
 };
 
+#define SUNXI_SRAM_THS_OFFSET_REG	0x0
 #define SUNXI_SRAM_EMAC_CLOCK_REG	0x30
 #define SUNXI_SYS_LDO_CTRL_REG		0x150
 
@@ -318,6 +321,8 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
 {
 	const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
 
+	if (reg == SUNXI_SRAM_THS_OFFSET_REG && variant->has_ths_offset)
+		return true;
 	if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG &&
 	    reg <  SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
 		return true;
@@ -327,6 +332,20 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
 	return false;
 }
 
+static void sunxi_sram_lock(void *_lock)
+{
+	spinlock_t *lock = _lock;
+
+	spin_lock(lock);
+}
+
+static void sunxi_sram_unlock(void *_lock)
+{
+	spinlock_t *lock = _lock;
+
+	spin_unlock(lock);
+}
+
 static struct regmap_config sunxi_sram_regmap_config = {
 	.reg_bits       = 32,
 	.val_bits       = 32,
@@ -336,6 +355,9 @@ static struct regmap_config sunxi_sram_regmap_config = {
 	/* other devices have no business accessing other registers */
 	.readable_reg	= sunxi_sram_regmap_accessible_reg,
 	.writeable_reg	= sunxi_sram_regmap_accessible_reg,
+	.lock		= sunxi_sram_lock,
+	.unlock		= sunxi_sram_unlock,
+	.lock_arg	= &sram_lock,
 };
 
 static int __init sunxi_sram_probe(struct platform_device *pdev)
-- 
2.25.1



From andre.przywara at arm.com  Mon Feb 19 07:36:34 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 19 Feb 2024 15:36:34 +0000
Subject: [PATCH v5 2/7] dt-bindings: thermal: sun8i: Add H616 THS controller
In-Reply-To: <20240219153639.179814-1-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
Message-ID: <20240219153639.179814-3-andre.przywara@arm.com>

From: Martin Botka <martin.botka at somainline.org>

This controller is similar to the H6, but covers four sensors and uses
slightly different calibration methods.
Also the H616 requires to poke a bit in the SYS_CFG register range for
correct operation, so add a phandle property to point there.

Signed-off-by: Martin Botka <martin.botka at somainline.org>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../thermal/allwinner,sun8i-a83t-ths.yaml     | 34 +++++++++++++------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
index 9b2272a9ec15d..6b3aea6d73b07 100644
--- a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
+++ b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
@@ -21,6 +21,7 @@ properties:
       - allwinner,sun50i-a100-ths
       - allwinner,sun50i-h5-ths
       - allwinner,sun50i-h6-ths
+      - allwinner,sun50i-h616-ths
 
   clocks:
     minItems: 1
@@ -50,6 +51,10 @@ properties:
   nvmem-cell-names:
     const: calibration
 
+  allwinner,sram:
+    maxItems: 1
+    description: phandle to device controlling temperate offset SYS_CFG register
+
   # See Documentation/devicetree/bindings/thermal/thermal-sensor.yaml for details
   "#thermal-sensor-cells":
     enum:
@@ -65,6 +70,7 @@ allOf:
               - allwinner,sun20i-d1-ths
               - allwinner,sun50i-a100-ths
               - allwinner,sun50i-h6-ths
+              - allwinner,sun50i-h616-ths
 
     then:
       properties:
@@ -82,6 +88,17 @@ allOf:
         clock-names:
           minItems: 2
 
+  - if:
+      not:
+        properties:
+          compatible:
+            contains:
+              const: allwinner,sun50i-h616-ths
+
+    then:
+      properties:
+        allwinner,sram: false
+
   - if:
       properties:
         compatible:
@@ -101,17 +118,12 @@ allOf:
           const: 1
 
   - if:
-      properties:
-        compatible:
-          contains:
-            enum:
-              - allwinner,sun8i-h3-ths
-              - allwinner,sun8i-r40-ths
-              - allwinner,sun20i-d1-ths
-              - allwinner,sun50i-a64-ths
-              - allwinner,sun50i-a100-ths
-              - allwinner,sun50i-h5-ths
-              - allwinner,sun50i-h6-ths
+      not:
+        properties:
+          compatible:
+            contains:
+              enum:
+                - allwinner,sun8i-a83t-ths
 
     then:
       required:
-- 
2.25.1



From andre.przywara at arm.com  Mon Feb 19 07:36:35 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 19 Feb 2024 15:36:35 +0000
Subject: [PATCH v5 3/7] thermal: sun8i: explain unknown H6 register value
In-Reply-To: <20240219153639.179814-1-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
Message-ID: <20240219153639.179814-4-andre.przywara@arm.com>

So far we were ORing in some "unknown" value into the THS control
register on the Allwinner H6. This part of the register is not explained
in the H6 manual, but the H616 manual details those bits, and on closer
inspection the THS IP blocks in both SoCs seem very close:
- The BSP code for both SoCs writes the same values into THS_CTRL.
- The reset values of at least the first three registers are the same.

Replace the "unknown" value with its proper meaning: "acquire time",
most probably the sample part of the sample & hold circuit of the ADC,
according to its explanation in the H616 manual.

No functional change, just a macro rename and adjustment.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/thermal/sun8i_thermal.c | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index 6a8e386dbc8dc..42bee03c4e507 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -50,7 +50,8 @@
 #define SUN8I_THS_CTRL2_T_ACQ1(x)		((GENMASK(15, 0) & (x)) << 16)
 #define SUN8I_THS_DATA_IRQ_STS(x)		BIT(x + 8)
 
-#define SUN50I_THS_CTRL0_T_ACQ(x)		((GENMASK(15, 0) & (x)) << 16)
+#define SUN50I_THS_CTRL0_T_ACQ(x)		(GENMASK(15, 0) & ((x) - 1))
+#define SUN50I_THS_CTRL0_T_SAMPLE_PER(x)	((GENMASK(15, 0) & ((x) - 1)) << 16)
 #define SUN50I_THS_FILTER_EN			BIT(2)
 #define SUN50I_THS_FILTER_TYPE(x)		(GENMASK(1, 0) & (x))
 #define SUN50I_H6_THS_PC_TEMP_PERIOD(x)		((GENMASK(19, 0) & (x)) << 12)
@@ -410,25 +411,27 @@ static int sun8i_h3_thermal_init(struct ths_device *tmdev)
 	return 0;
 }
 
-/*
- * Without this undocumented value, the returned temperatures would
- * be higher than real ones by about 20C.
- */
-#define SUN50I_H6_CTRL0_UNK 0x0000002f
-
 static int sun50i_h6_thermal_init(struct ths_device *tmdev)
 {
 	int val;
 
 	/*
-	 * T_acq = 20us
-	 * clkin = 24MHz
-	 *
-	 * x = T_acq * clkin - 1
-	 *   = 479
+	 * The manual recommends an overall sample frequency of 50 KHz (20us,
+	 * 480 cycles at 24 MHz), which provides plenty of time for both the
+	 * acquisition time (>24 cycles) and the actual conversion time
+	 * (>14 cycles).
+	 * The lower half of the CTRL register holds the "acquire time", in
+	 * clock cycles, which the manual recommends to be 2us:
+	 * 24MHz * 2us = 48 cycles.
+	 * The high half of THS_CTRL encodes the sample frequency, in clock
+	 * cycles: 24MHz * 20us = 480 cycles.
+	 * This is explained in the H616 manual, but apparently wrongly
+	 * described in the H6 manual, although the BSP code does the same
+	 * for both SoCs.
 	 */
 	regmap_write(tmdev->regmap, SUN50I_THS_CTRL0,
-		     SUN50I_H6_CTRL0_UNK | SUN50I_THS_CTRL0_T_ACQ(479));
+		     SUN50I_THS_CTRL0_T_ACQ(48) |
+		     SUN50I_THS_CTRL0_T_SAMPLE_PER(480));
 	/* average over 4 samples */
 	regmap_write(tmdev->regmap, SUN50I_H6_THS_MFC,
 		     SUN50I_THS_FILTER_EN |
-- 
2.25.1



From andre.przywara at arm.com  Mon Feb 19 07:36:36 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 19 Feb 2024 15:36:36 +0000
Subject: [PATCH v5 4/7] thermal: sun8i: extend H6 calibration to support 4 sensors
In-Reply-To: <20240219153639.179814-1-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
Message-ID: <20240219153639.179814-5-andre.przywara@arm.com>

From: Maksim Kiselev <bigunclemax at gmail.com>

The H616 SoC resembles the H6 thermal sensor controller, with a few
changes like four sensors.

Extend sun50i_h6_ths_calibrate() function to support calibration of
these sensors.

Co-developed-by: Martin Botka <martin.botka at somainline.org>
Signed-off-by: Martin Botka <martin.botka at somainline.org>
Signed-off-by: Maksim Kiselev <bigunclemax at gmail.com>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/thermal/sun8i_thermal.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index 42bee03c4e507..c919b0fd5e169 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -222,16 +222,21 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
 	struct device *dev = tmdev->dev;
 	int i, ft_temp;
 
-	if (!caldata[0] || callen < 2 + 2 * tmdev->chip->sensor_num)
+	if (!caldata[0])
 		return -EINVAL;
 
 	/*
 	 * efuse layout:
 	 *
-	 *	0   11  16	 32
-	 *	+-------+-------+-------+
-	 *	|temp|  |sensor0|sensor1|
-	 *	+-------+-------+-------+
+	 * 0      11  16     27   32     43   48    57
+	 * +----------+-----------+-----------+-----------+
+	 * |  temp |  |sensor0|   |sensor1|   |sensor2|   |
+	 * +----------+-----------+-----------+-----------+
+	 *                      ^           ^           ^
+	 *                      |           |           |
+	 *                      |           |           sensor3[11:8]
+	 *                      |           sensor3[7:4]
+	 *                      sensor3[3:0]
 	 *
 	 * The calibration data on the H6 is the ambient temperature and
 	 * sensor values that are filled during the factory test stage.
@@ -244,9 +249,16 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
 	ft_temp = (caldata[0] & FT_TEMP_MASK) * 100;
 
 	for (i = 0; i < tmdev->chip->sensor_num; i++) {
-		int sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK;
-		int cdata, offset;
-		int sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg);
+		int sensor_reg, sensor_temp, cdata, offset;
+
+		if (i == 3)
+			sensor_reg = (caldata[1] >> 12)
+				     | ((caldata[2] >> 12) << 4)
+				     | ((caldata[3] >> 12) << 8);
+		else
+			sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK;
+
+		sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg);
 
 		/*
 		 * Calibration data is CALIBRATE_DEFAULT - (calculated
-- 
2.25.1



From andre.przywara at arm.com  Mon Feb 19 07:36:37 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 19 Feb 2024 15:36:37 +0000
Subject: [PATCH v5 5/7] thermal: sun8i: add SRAM register access code
In-Reply-To: <20240219153639.179814-1-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
Message-ID: <20240219153639.179814-6-andre.przywara@arm.com>

The Allwinner H616 SoC needs to clear a bit in one register in the SRAM
controller, to report reasonable temperature values. On reset, bit 16 in
register 0x3000000 is set, which leads to the driver reporting
temperatures around 200C. Clearing this bit brings the values down to the
expected range. The BSP code does a one-time write in U-Boot, with a
comment just mentioning the effect on the THS, but offering no further
explanation.

To not rely on firmware to set things up for us, add code that queries
the SRAM controller device via a DT phandle link, then clear just this
single bit.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/thermal/sun8i_thermal.c | 51 +++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index c919b0fd5e169..c157e4fbf963b 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/nvmem-consumer.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
@@ -66,6 +67,7 @@ struct tsensor {
 struct ths_thermal_chip {
 	bool            has_mod_clk;
 	bool            has_bus_clk_reset;
+	bool		needs_sram;
 	int		sensor_num;
 	int		offset;
 	int		scale;
@@ -83,12 +85,16 @@ struct ths_device {
 	const struct ths_thermal_chip		*chip;
 	struct device				*dev;
 	struct regmap				*regmap;
+	struct regmap_field			*sram_regmap_field;
 	struct reset_control			*reset;
 	struct clk				*bus_clk;
 	struct clk                              *mod_clk;
 	struct tsensor				sensor[MAX_SENSOR_NUM];
 };
 
+/* The H616 needs to have a bit 16 in the SRAM control register cleared. */
+static const struct reg_field sun8i_ths_sram_reg_field = REG_FIELD(0x0, 16, 16);
+
 /* Temp Unit: millidegree Celsius */
 static int sun8i_ths_calc_temp(struct ths_device *tmdev,
 			       int id, int reg)
@@ -337,6 +343,34 @@ static void sun8i_ths_reset_control_assert(void *data)
 	reset_control_assert(data);
 }
 
+static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node)
+{
+	struct device_node *sram_node;
+	struct platform_device *sram_pdev;
+	struct regmap *regmap = NULL;
+
+	sram_node = of_parse_phandle(node, "allwinner,sram", 0);
+	if (!sram_node)
+		return ERR_PTR(-ENODEV);
+
+	sram_pdev = of_find_device_by_node(sram_node);
+	if (!sram_pdev) {
+		/* platform device might not be probed yet */
+		regmap = ERR_PTR(-EPROBE_DEFER);
+		goto out_put_node;
+	}
+
+	/* If no regmap is found then the other device driver is at fault */
+	regmap = dev_get_regmap(&sram_pdev->dev, NULL);
+	if (!regmap)
+		regmap = ERR_PTR(-EINVAL);
+
+	platform_device_put(sram_pdev);
+out_put_node:
+	of_node_put(sram_node);
+	return regmap;
+}
+
 static int sun8i_ths_resource_init(struct ths_device *tmdev)
 {
 	struct device *dev = tmdev->dev;
@@ -381,6 +415,19 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev)
 	if (ret)
 		return ret;
 
+	if (tmdev->chip->needs_sram) {
+		struct regmap *regmap;
+
+		regmap = sun8i_ths_get_sram_regmap(dev->of_node);
+		if (IS_ERR(regmap))
+			return PTR_ERR(regmap);
+		tmdev->sram_regmap_field = devm_regmap_field_alloc(dev,
+						      regmap,
+						      sun8i_ths_sram_reg_field);
+		if (IS_ERR(tmdev->sram_regmap_field))
+			return PTR_ERR(tmdev->sram_regmap_field);
+	}
+
 	ret = sun8i_ths_calibrate(tmdev);
 	if (ret)
 		return ret;
@@ -427,6 +474,10 @@ static int sun50i_h6_thermal_init(struct ths_device *tmdev)
 {
 	int val;
 
+	/* The H616 needs to have a bit in the SRAM control register cleared. */
+	if (tmdev->sram_regmap_field)
+		regmap_field_write(tmdev->sram_regmap_field, 0);
+
 	/*
 	 * The manual recommends an overall sample frequency of 50 KHz (20us,
 	 * 480 cycles at 24 MHz), which provides plenty of time for both the
-- 
2.25.1



From andre.przywara at arm.com  Mon Feb 19 07:36:38 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 19 Feb 2024 15:36:38 +0000
Subject: [PATCH v5 6/7] thermal: sun8i: add support for H616 THS controller
In-Reply-To: <20240219153639.179814-1-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
Message-ID: <20240219153639.179814-7-andre.przywara@arm.com>

From: Martin Botka <martin.botka at somainline.org>

Add support for the thermal sensor found in H616 SoCs, is the same as
the H6 thermal sensor controller, but with four sensors.
Also the registers readings are wrong, unless a bit in the first SYS_CFG
register cleared, so set exercise the SRAM regmap to take care of that.

Signed-off-by: Martin Botka <martin.botka at somainline.org>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/thermal/sun8i_thermal.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index c157e4fbf963b..63a7d2df3d6ec 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -684,6 +684,20 @@ static const struct ths_thermal_chip sun20i_d1_ths = {
 	.calc_temp = sun8i_ths_calc_temp,
 };
 
+static const struct ths_thermal_chip sun50i_h616_ths = {
+	.sensor_num = 4,
+	.has_bus_clk_reset = true,
+	.needs_sram = true,
+	.ft_deviation = 8000,
+	.offset = 263655,
+	.scale = 810,
+	.temp_data_base = SUN50I_H6_THS_TEMP_DATA,
+	.calibrate = sun50i_h6_ths_calibrate,
+	.init = sun50i_h6_thermal_init,
+	.irq_ack = sun50i_h6_irq_ack,
+	.calc_temp = sun8i_ths_calc_temp,
+};
+
 static const struct of_device_id of_ths_match[] = {
 	{ .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths },
 	{ .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths },
@@ -693,6 +707,7 @@ static const struct of_device_id of_ths_match[] = {
 	{ .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths },
 	{ .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths },
 	{ .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths },
+	{ .compatible = "allwinner,sun50i-h616-ths", .data = &sun50i_h616_ths },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, of_ths_match);
-- 
2.25.1



From james.clark at arm.com  Mon Feb 19 07:36:56 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 19 Feb 2024 15:36:56 +0000
Subject: [PATCH] coresight: constify the struct device_type usage
In-Reply-To: <20240219-device_cleanup-coresight-v1-1-4a8a0b816183@marliere.net>
References: <20240219-device_cleanup-coresight-v1-1-4a8a0b816183@marliere.net>
Message-ID: <9bdf420c-f716-2a18-4b68-a8c6331eeb39@arm.com>



On 19/02/2024 13:43, Ricardo B. Marliere wrote:
> Since commit aed65af1cc2f ("drivers: make device_type const"), the driver
> core can properly handle constant struct device_type. Move the
> coresight_dev_type variable to be a constant structure as well, placing it
> into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
> ---
>  drivers/hwtracing/coresight/coresight-priv.h  | 2 +-
>  drivers/hwtracing/coresight/coresight-sysfs.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
> index eb365236f9a9..ca3362cbdb70 100644
> --- a/drivers/hwtracing/coresight/coresight-priv.h
> +++ b/drivers/hwtracing/coresight/coresight-priv.h
> @@ -13,7 +13,7 @@
>  #include <linux/pm_runtime.h>
>  
>  extern struct mutex coresight_mutex;
> -extern struct device_type coresight_dev_type[];
> +extern const struct device_type coresight_dev_type[];
>  
>  /*
>   * Coresight management registers (0xf00-0xfcc)
> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
> index f9444e2cb1d9..1e67cc7758d7 100644
> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
> @@ -377,7 +377,7 @@ static struct attribute *coresight_source_attrs[] = {
>  };
>  ATTRIBUTE_GROUPS(coresight_source);
>  
> -struct device_type coresight_dev_type[] = {
> +const struct device_type coresight_dev_type[] = {
>  	[CORESIGHT_DEV_TYPE_SINK] = {
>  		.name = "sink",
>  		.groups = coresight_sink_groups,
> 
> ---
> base-commit: c099fdd218a0fedfe87e0b88d2ba0667eab3b3c8
> change-id: 20240219-device_cleanup-coresight-00ba00fd5f21
> 
> Best regards,


Reviewed-by: James Clark <james.clark at arm.com>


From andre.przywara at arm.com  Mon Feb 19 07:36:39 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 19 Feb 2024 15:36:39 +0000
Subject: [PATCH v5 7/7] arm64: dts: allwinner: h616: Add thermal sensor and zones
In-Reply-To: <20240219153639.179814-1-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
Message-ID: <20240219153639.179814-8-andre.przywara@arm.com>

From: Martin Botka <martin.botka at somainline.org>

There are four thermal sensors:
- CPU
- GPU
- VE
- DRAM

Add the thermal sensor configuration and the thermal zones.

Signed-off-by: Martin Botka <martin.botka at somainline.org>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 88 +++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index 12ffabc79bcde..7c7d7c285505c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -9,6 +9,7 @@
 #include <dt-bindings/clock/sun6i-rtc.h>
 #include <dt-bindings/reset/sun50i-h616-ccu.h>
 #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -138,6 +139,10 @@ sid: efuse at 3006000 {
 			reg = <0x03006000 0x1000>;
 			#address-cells = <1>;
 			#size-cells = <1>;
+
+			ths_calibration: thermal-sensor-calibration at 14 {
+				reg = <0x14 0x8>;
+			};
 		};
 
 		watchdog: watchdog at 30090a0 {
@@ -517,6 +522,19 @@ mdio0: mdio {
 			};
 		};
 
+		ths: thermal-sensor at 5070400 {
+			compatible = "allwinner,sun50i-h616-ths";
+			reg = <0x05070400 0x400>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_THS>;
+			clock-names = "bus";
+			resets = <&ccu RST_BUS_THS>;
+			nvmem-cells = <&ths_calibration>;
+			nvmem-cell-names = "calibration";
+			allwinner,sram = <&syscon>;
+			#thermal-sensor-cells = <1>;
+		};
+
 		usbotg: usb at 5100000 {
 			compatible = "allwinner,sun50i-h616-musb",
 				     "allwinner,sun8i-h3-musb";
@@ -761,4 +779,74 @@ r_rsb: rsb at 7083000 {
 			#size-cells = <0>;
 		};
 	};
+
+	thermal-zones {
+		cpu-thermal {
+			polling-delay-passive = <500>;
+			polling-delay = <1000>;
+			thermal-sensors = <&ths 2>;
+			sustainable-power = <1000>;
+
+			trips {
+				cpu_threshold: cpu-trip-0 {
+					temperature = <60000>;
+					type = "passive";
+					hysteresis = <0>;
+				};
+				cpu_target: cpu-trip-1 {
+					temperature = <70000>;
+					type = "passive";
+					hysteresis = <0>;
+				};
+				cpu_critical: cpu-trip-2 {
+					temperature = <110000>;
+					type = "critical";
+					hysteresis = <0>;
+				};
+			};
+		};
+
+		gpu-thermal {
+			polling-delay-passive = <500>;
+			polling-delay = <1000>;
+			thermal-sensors = <&ths 0>;
+			sustainable-power = <1100>;
+
+			trips {
+				gpu_temp_critical: gpu-trip-0 {
+					temperature = <110000>;
+					type = "critical";
+					hysteresis = <0>;
+				};
+			};
+		};
+
+		ve-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&ths 1>;
+
+			trips {
+				ve_temp_critical: ve-trip-0 {
+					temperature = <110000>;
+					type = "critical";
+					hysteresis = <0>;
+				};
+			};
+		};
+
+		ddr-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&ths 3>;
+
+			trips {
+				ddr_temp_critical: ddr-trip-0 {
+					temperature = <110000>;
+					type = "critical";
+					hysteresis = <0>;
+				};
+			};
+		};
+	};
 };
-- 
2.25.1



From anna-maria at linutronix.de  Mon Feb 19 07:39:33 2024
From: anna-maria at linutronix.de (Anna-Maria Behnsen)
Date: Mon, 19 Feb 2024 16:39:33 +0100
Subject: [PATCH 04/10] vdso/arm: make union vdso_data_store available for all
In-Reply-To: <20240219153939.75719-1-anna-maria@linutronix.de>
References: <20240219153939.75719-1-anna-maria@linutronix.de>
Message-ID: <20240219153939.75719-5-anna-maria@linutronix.de>

The vDSO data page "union vdso_data_store" is defined in an arm header file
and also defined in several other places.

Move the definition from arm header file into the generic vdso datapage
header to make it also usable for others and to prevent code duplication.

Signed-off-by: Anna-Maria Behnsen <anna-maria at linutronix.de>
Cc: Russell King <linux at armlinux.org.uk>
Cc: Eric Biederman <ebiederm at xmission.com>
Cc: Kees Cook <keescook at chromium.org>
Cc: linux-mm at kvack.org
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm/include/asm/elf.h           |  1 -
 arch/arm/include/asm/vdso_datapage.h | 26 --------------------------
 arch/arm/kernel/asm-offsets.c        |  4 +++-
 arch/arm/kernel/vdso.c               |  4 ----
 include/vdso/datapage.h              | 10 ++++++++++
 5 files changed, 13 insertions(+), 32 deletions(-)
 delete mode 100644 arch/arm/include/asm/vdso_datapage.h

diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index d68101655b74..9f21e170320f 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -4,7 +4,6 @@
 
 #include <asm/auxvec.h>
 #include <asm/hwcap.h>
-#include <asm/vdso_datapage.h>
 
 /*
  * ELF register definitions..
diff --git a/arch/arm/include/asm/vdso_datapage.h b/arch/arm/include/asm/vdso_datapage.h
deleted file mode 100644
index bef68f59928d..000000000000
--- a/arch/arm/include/asm/vdso_datapage.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Adapted from arm64 version.
- *
- * Copyright (C) 2012 ARM Limited
- */
-#ifndef __ASM_VDSO_DATAPAGE_H
-#define __ASM_VDSO_DATAPAGE_H
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-#include <vdso/datapage.h>
-#include <asm/page.h>
-
-union vdso_data_store {
-	struct vdso_data	data[CS_BASES];
-	u8			page[PAGE_SIZE];
-};
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 219cbc7e5d13..4915662842ff 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -21,10 +21,12 @@
 #include <asm/mpu.h>
 #include <asm/procinfo.h>
 #include <asm/suspend.h>
-#include <asm/vdso_datapage.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <linux/kbuild.h>
 #include <linux/arm-smccc.h>
+
+#include <vdso/datapage.h>
+
 #include "signal.h"
 
 /*
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index f297d66a8a76..d499ad461b00 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -21,7 +21,6 @@
 #include <asm/cacheflush.h>
 #include <asm/page.h>
 #include <asm/vdso.h>
-#include <asm/vdso_datapage.h>
 #include <clocksource/arm_arch_timer.h>
 #include <vdso/helpers.h>
 #include <vdso/vsyscall.h>
@@ -35,9 +34,6 @@ extern char vdso_start[], vdso_end[];
 /* Total number of pages needed for the data and text portions of the VDSO. */
 unsigned int vdso_total_pages __ro_after_init;
 
-/*
- * The VDSO data page.
- */
 static union vdso_data_store vdso_data_store __page_aligned_data;
 struct vdso_data *vdso_data = vdso_data_store.data;
 
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index 73eb622e7663..7ba44379a095 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -19,6 +19,8 @@
 #include <vdso/time32.h>
 #include <vdso/time64.h>
 
+#include <asm/page.h>
+
 #ifdef CONFIG_ARCH_HAS_VDSO_DATA
 #include <asm/vdso/data.h>
 #else
@@ -121,6 +123,14 @@ struct vdso_data {
 extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
 extern struct vdso_data _timens_data[CS_BASES] __attribute__((visibility("hidden")));
 
+/**
+ * union vdso_data_store - Generic vDSO data page
+ */
+union vdso_data_store {
+	struct vdso_data	data[CS_BASES];
+	u8			page[PAGE_SIZE];
+};
+
 /*
  * The generic vDSO implementation requires that gettimeofday.h
  * provides:
-- 
2.39.2



From anna-maria at linutronix.de  Mon Feb 19 07:39:34 2024
From: anna-maria at linutronix.de (Anna-Maria Behnsen)
Date: Mon, 19 Feb 2024 16:39:34 +0100
Subject: [PATCH 05/10] arm64/vdso: Use generic union vdso_data_store
In-Reply-To: <20240219153939.75719-1-anna-maria@linutronix.de>
References: <20240219153939.75719-1-anna-maria@linutronix.de>
Message-ID: <20240219153939.75719-6-anna-maria@linutronix.de>

There is already a generic union definition for vdso_data_store in vdso
datapage header.

Use this definition to prevent code duplication.

Signed-off-by: Anna-Maria Behnsen <anna-maria at linutronix.de>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/kernel/vdso.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 5562daf38a22..89b6e7840002 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -69,10 +69,7 @@ static struct vdso_abi_info vdso_info[] __ro_after_init = {
 /*
  * The vDSO data page.
  */
-static union {
-	struct vdso_data	data[CS_BASES];
-	u8			page[PAGE_SIZE];
-} vdso_data_store __page_aligned_data;
+static union vdso_data_store vdso_data_store __page_aligned_data;
 struct vdso_data *vdso_data = vdso_data_store.data;
 
 static int vdso_mremap(const struct vm_special_mapping *sm,
-- 
2.39.2



From ardb at kernel.org  Mon Feb 19 07:41:03 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 19 Feb 2024 16:41:03 +0100
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <CAMuHMdX+6fnAf8Hm6EqYJPAjrrLO9T7c=Gu3S8V_pqjSDowJ6g@mail.gmail.com>
References: <20240206074552.541154-1-maskray@google.com> <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>
 <CAMj1kXGaF5bobHTr1pTg+-=s4Ft7+5SSbX72-NxsR_W_Yuxb8Q@mail.gmail.com>
 <CAMj1kXGw+r7yEEBA8gYBcdrqkiP=VYOSzz9YLnNavJn2snmFwA@mail.gmail.com> <CAMuHMdX+6fnAf8Hm6EqYJPAjrrLO9T7c=Gu3S8V_pqjSDowJ6g@mail.gmail.com>
Message-ID: <CAMj1kXHh_m=V0QsiTpHrUXpFBXFbFfezdysz8quhPSgUrZg1MA@mail.gmail.com>

On Mon, 19 Feb 2024 at 15:43, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>
> Hi Ard,
>
> On Mon, Feb 19, 2024 at 11:57?AM Ard Biesheuvel <ardb at kernel.org> wrote:
> > On Mon, 19 Feb 2024 at 11:56, Ard Biesheuvel <ardb at kernel.org> wrote:
> > > On Mon, 19 Feb 2024 at 11:03, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> > > > On Tue, Feb 6, 2024 at 8:46?AM Fangrui Song <maskray at google.com> wrote:
> > > > > The generic constraint "i" seems to be copied from x86 or arm (and with
> > > > > a redundant generic operand modifier "c"). It works with -fno-PIE but
> > > > > not with -fPIE/-fPIC in GCC's aarch64 port.
> > > >
> > > > Thanks for your patch, which is now commit f9daab0ad01cf9d1 ("arm64:
> > > > jump_label: use constraints "Si" instead of "i"") in v6.8-rc5.
> > > >
> > > > > The machine constraint "S", which denotes a symbol or label reference
> > > > > with a constant offset, supports PIC and has been available in GCC since
> > > > > 2012 and in Clang since 7.0. However, Clang before 19 does not support
> > > > > "S" on a symbol with a constant offset [1] (e.g.
> > > > > `static_key_false(&nf_hooks_needed[pf][hook])` in
> > > > > include/linux/netfilter.h), so we use "i" as a fallback.
> > > >
> > > > https://gcc.gnu.org/releases.html says gcc-5 was released in 2015,
> > > > i.e. after 2012 ...
> > > >
> > > > > Suggested-by: Ard Biesheuvel <ardb at kernel.org>
> > > > > Signed-off-by: Fangrui Song <maskray at google.com>
> > > > > Link: https://github.com/llvm/llvm-project/pull/80255 [1]
> > > > >
> > > > > ---
> > > > > Changes from
> > > > > arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
> > > > >
> > > > > * Use "Si" as Ard suggested to support Clang<19
> > > > > * Make branch a separate operand
> > > > >
> > > > > Changes from v1:
> > > > >
> > > > > * Use asmSymbolicName for readability
> > > >
> > > > But it still fails on gcc-5:
> > > >
> > > >     arch/arm64/include/asm/jump_label.h:25:2: error: invalid 'asm':
> > > > invalid operand
> > > >       asm goto(
> > > >       ^
> > > >
> > > > http://kisskb.ellerman.id.au/kisskb/buildresult/15129281/
> > > >
> > >
> > > How odd. godbolt.org has 5.4 and it seems perfectly happy with it.
>
> > https://godbolt.org/z/GTnf3vPaT
>
> I could reproduce the issue on v6.8-rc5 using arm64 defconfig
> and x86_64-gcc-5.5.0-nolibc-aarch64-linux.tar.xz from
> https://cdn.kernel.org/pub/tools/crosstool/files/bin/x86_64/5.5.0/:
>

OK, I managed to do so as well.

And GCC 6.4 from the same source works correctly.

Not sure whether there are any plans to bump the minimal GCC version
any time soon (cc'ing Arnd), but we should probably drop this change
until that happens.


From brgl at bgdev.pl  Mon Feb 19 07:44:20 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 16:44:20 +0100
Subject: [PATCH 00/23] Rework Nomadik GPIO to add Mobileye EyeQ5 support
In-Reply-To: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
Message-ID: <CAMRc=MfLXCDXBiKKuEPZRjNoNiFN+gvhu+GjZkZ1SQuF1s4=UQ@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> Hi,
>
> This patch series reworks the Nomadik GPIO driver to bring it up to date
> to current kernel standards. We then add Mobileye EyeQ5 support that
> uses the same IP block but with limited functionality. We also add
> features required by our newly supported platform:
>
>  - Dynamic GPIO ID allocation;
>  - Make clock optional;
>  - Shared IRQ (usecase: EyeQ5 has two banks using the same IRQ);
>  - Handle variadic GPIO counts (usecase: EyeQ5 has <32 GPIOs per bank);
>  - Grab optional reset at probe (usecase: EyeQ5 has a reset available).
>
> This GPIO platform driver was previously declared & registered inside
> drivers/pinctrl/nomadik/pinctrl-nomadik.c, side-by-side with the
> pinctrl driver. Both are tightly integrated, mostly for muxing reasons.
> Now that gpio-nomadik is used for another platform, we loosen the
> relationship. The behavior should not change on already supported
> hardware but I do not have Nomadik hardware to test for that.
>

I hope Linus can leave his Tested-by under this series then.

> We have some dependencies, kept neatly to the end. Those are:
> - The base platform support series from Gr?gory [1]. This relates to the
>   last four patches (20 thru 23), ie defconfig and devicetree.
> - The OLB syscon support series [0]. It provides reset and pinctrl nodes
>   inside the devicetree. This relates to the last two patches (22 and
>   23), ie resets and gpio-ranges DT props. GPIO works fine without it
>   if patches 22 and 23 are dropped.
>
> This has been tested on the EyeQ5 hardware, with the two parent series
> applied. It also works fine without the OLB syscon series when our last
> two patches are removed. It has been built on both Arm defconfigs that
> rely on pinctrl-nomadik: nhk8815_defconfig and u8500_defconfig. I don't
> have any Nomadik hardware to test though.
>
> Have a nice day,
> Th?o
>

Are you targeting the GPIO branch with this or pinctrl? I guess GPIO
so I'll need Linus' Acks under the pinctrl patches.

> [0]: https://lore.kernel.org/lkml/20240212-mbly-clk-v6-0-c46fa1f93839 at bootlin.com/
> [1]: https://lore.kernel.org/lkml/20240205153503.574468-1-gregory.clement at bootlin.com/

Please advise the relevant maintainers that they should provide an
immutable branch for these series once they're queued in their
respective trees.

Bart

[snip]


From brgl at bgdev.pl  Mon Feb 19 07:48:04 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 16:48:04 +0100
Subject: [PATCH 16/23] gpio: nomadik: support shared GPIO IRQs
In-Reply-To: <20240214-mbly-gpio-v1-16-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-16-f88c0ccf372b@bootlin.com>
Message-ID: <CAMRc=MdFBFFTYKHgDfOieNZJ+-x7ZZMiYty6buOp2J=eFUjt0Q@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> Support a single IRQs used by multiple GPIO banks. Change the IRQ
> handler type from a chained handler (as used by gpiolib
> for ->parent_handler) to a threaded IRQ.
>
> Use a fake raw spinlock to ensure generic_handle_irq() is called in a
> no-irq context. See Documentation/driver-api/gpio/driver.rst, "CHAINED
> CASCADED GPIO IRQCHIPS" for additional information.
>

Any reason for not using preempt_disable()?

Bart

[snip]


From Frank.li at nxp.com  Mon Feb 19 07:34:02 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 19 Feb 2024 10:34:02 -0500
Subject: [PATCH v10 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <ZdNx9op+MhzF5FNB@lpieralisi>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>
 <ZdNx9op+MhzF5FNB@lpieralisi>
Message-ID: <ZdN06tsJH7A0o6fv@lizhi-Precision-Tower-5810>

On Mon, Feb 19, 2024 at 04:21:26PM +0100, Lorenzo Pieralisi wrote:
> On Mon, Feb 19, 2024 at 10:11:45AM -0500, Frank Li wrote:
> > On Mon, Feb 05, 2024 at 12:33:21PM -0500, Frank Li wrote:
> > > first 6 patches use drvdata: flags to simplify some switch-case code.
> > > Improve maintaince and easy to read code.
> > > 
> > 
> > @Lorenzo Pieralisi:
> > 
> > 	Do you have chance to look other patches?
> 
> Yes, they are fine.
> 
> > 	Mani's apply EP side change. 
> > 	'PCI: imx6: Add iMX95 Endpoint (EP) support' need be rebased. 
> 
> What does that mean ? I think it is best to pull the series in a single
> branch if there are not any dependencies on other branches.

Two options:

Options 1:
	Merge 1-13. Left 'PCI: imx6: Add iMX95 Endpoint (EP) support'.
I will send out later with other clean up patches.

Options 2:
	I rebase to https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=endpoint
	After Bjorn Helgaas merge to next, you can pick all.

I perfer opitons 1.

Frank

> 
> Thanks,
> Lorenzo
> 
> > Frank
> > 
> > > Then add imx95 basic pci host function.
> > > 
> > > follow two patch do endpoint code clean up.
> > > Then add imx95 basic endpont function.
> > > 
> > > Compared with v2, added EP function support and some fixes,  please change
> > > notes at each patches.
> > > 
> > > Change from v9 to v10
> > > - remove two patches:
> > > >   dt-bindings: imx6q-pcie: Add linux,pci-domain as required for iMX8MQ
> > > >   PCI: imx6: Using "linux,pci-domain" as slot ID
> > > it is not good solution to fixed hardcode check to get controller id.
> > > Will see better solution later.
> > > 
> > > dt-binding pass pcie node:
> > > 
> > > pcie0: pcie at 4c300000 {
> > >                         compatible = "fsl,imx95-pcie";
> > >                         reg = <0 0x4c300000 0 0x40000>,
> > >                                 <0 0x4c360000 0 0x10000>,
> > >                                 <0 0x4c340000 0 0x20000>,
> > >                                 <0 0x60100000 0 0xfe00000>;
> > >                         reg-names = "dbi", "atu", "app", "config";
> > >                         #address-cells = <3>;
> > >                         #size-cells = <2>;
> > >                         device_type = "pci";
> > >                         linux,pci-domain = <0>;
> > >                         bus-range = <0x00 0xff>;
> > >                         ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
> > >                                  <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
> > >                         num-lanes = <1>;
> > >                         num-viewport = <8>;
> > >                         interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
> > >                         interrupt-names = "msi";
> > >                         #interrupt-cells = <1>;
> > >                         interrupt-map-mask = <0 0 0 0x7>;
> > >                         interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
> > >                                         <0 0 0 2 &gic 0 0 GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
> > >                                         <0 0 0 3 &gic 0 0 GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
> > >                                         <0 0 0 4 &gic 0 0 GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
> > >                         fsl,max-link-speed = <3>;
> > >                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> > >                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
> > >                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> > >                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
> > >                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> > >                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
> > >                         assigned-clock-parents = <0>, <0>,
> > >                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
> > >                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> > >                         /* 0x30~0x37 stream id for pci0 */
> > >                         /*
> > >                          * iommu-map = <0x000 &apps_smmu 0x30 0x1>,
> > >                          * <0x100 &apps_smmu 0x31 0x1>;
> > >                          */
> > >                         status = "disabled";
> > >                 };
> > > 
> > > pcie1: pcie-ep at 4c380000 {
> > >                         compatible = "fsl,imx95-pcie-ep";
> > >                         reg = <0 0x4c380000 0 0x20000>,
> > >                               <0 0x4c3e0000 0 0x1000>,
> > >                               <0 0x4c3a0000 0 0x1000>,
> > >                               <0 0x4c3c0000 0 0x10000>,
> > >                               <0 0x4c3f0000 0 0x10000>,
> > >                               <0xa 0 1 0>;
> > >                         reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
> > >                         interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
> > >                         interrupt-names = "dma";
> > >                         fsl,max-link-speed = <3>;
> > >                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> > >                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
> > >                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> > >                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
> > >                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> > >                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
> > >                         assigned-clock-parents = <0>, <0>,
> > >                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
> > >                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> > >                         status = "disabled";
> > >                 };
> > > 
> > > Frank Li (13):
> > >   PCI: imx6: Simplify clock handling by using clk_bulk*() function
> > >   PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
> > >   PCI: imx6: Simplify reset handling by using by using
> > >     *_FLAG_HAS_*_RESET
> > >   PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
> > >   PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
> > >   PCI: imx6: Simplify switch-case logic by involve init_phy callback
> > >   dt-bindings: imx6q-pcie: Clean up irrationality clocks check
> > >   dt-bindings: imx6q-pcie: Restruct reg and reg-name
> > >   PCI: imx6: Add iMX95 PCIe Root Complex support
> > >   PCI: imx6: Clean up get addr_space code
> > >   PCI: imx6: Add epc_features in imx6_pcie_drvdata
> > >   dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
> > >   PCI: imx6: Add iMX95 Endpoint (EP) support
> > > 
> > > Richard Zhu (1):
> > >   dt-bindings: imx6q-pcie: Add imx95 pcie compatible string
> > > 
> > >  .../bindings/pci/fsl,imx6q-pcie-common.yaml   |  17 +-
> > >  .../bindings/pci/fsl,imx6q-pcie-ep.yaml       |  46 +-
> > >  .../bindings/pci/fsl,imx6q-pcie.yaml          |  49 +-
> > >  drivers/pci/controller/dwc/pci-imx6.c         | 634 ++++++++++--------
> > >  4 files changed, 436 insertions(+), 310 deletions(-)
> > > 
> > > -- 
> > > 2.34.1
> > > 


From maz at kernel.org  Mon Feb 19 07:53:48 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 15:53:48 +0000
Subject: [PATCH] irqchip/gic-v3: handle DOMAIN_BUS_ANY in gic_irq_domain_select
In-Reply-To: <20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f@linaro.org>
References: <20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f@linaro.org>
Message-ID: <868r3g4fhv.wl-maz@kernel.org>

On Mon, 19 Feb 2024 14:47:37 +0000,
Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> 
> Before the commit de1ff306dcf4 ("genirq/irqdomain: Remove the param
> count restriction from select()") the irq_find_matching_fwspec() was
> handling the DOMAIN_BUS_ANY on its own. After this commit it is a job of
> the select() callback. However the callback of GICv3 (even though it got
> modified to handle zero param_count) wasn't prepared to return true for
> DOMAIN_BUS_ANY bus_token.
> 
> This breaks probing of any of the child IRQ domains, since
> platform_irqchip_probe() uses irq_find_matching_host(par_np,
> DOMAIN_BUS_ANY) to check for the presence of the parent IRQ domain.
> 
> Fixes: 151378251004 ("irqchip/gic-v3: Make gic_irq_domain_select() robust for zero parameter count")
> Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from select()")
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> ---
>  drivers/irqchip/irq-gic-v3.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 6fb276504bcc..e9e9643c653f 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -1696,7 +1696,8 @@ static int gic_irq_domain_select(struct irq_domain *d,
>  
>  	/* Handle pure domain searches */
>  	if (!fwspec->param_count)
> -		return d->bus_token == bus_token;
> +		return d->bus_token == bus_token ||
> +			bus_token == DOMAIN_BUS_ANY;
>  
>  	/* If this is not DT, then we have a single domain */
>  	if (!is_of_node(fwspec->fwnode))
> 

I really dislike the look of this. If that's the case, any irqchip
that has a 'select' method (such as imx-intmux) should be similarly
hacked. And at this point, this should be handled by the core code.

Can you try this instead? I don't have any HW that relies on
behaviour, but I'd expect this to work.

Thanks,

	M.

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index aeb41655d6de..3dd1c871e091 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -449,7 +449,7 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
 	 */
 	mutex_lock(&irq_domain_mutex);
 	list_for_each_entry(h, &irq_domain_list, link) {
-		if (h->ops->select)
+		if (h->ops->select && bus_token != DOMAIN_BUS_ANY)
 			rc = h->ops->select(h, fwspec, bus_token);
 		else if (h->ops->match)
 			rc = h->ops->match(h, to_of_node(fwnode), bus_token);

-- 
Without deviation from the norm, progress is not possible.


From brgl at bgdev.pl  Mon Feb 19 07:54:43 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 16:54:43 +0100
Subject: [PATCH 13/23] gpio: nomadik: fix offset bug in nmk_pmx_set()
In-Reply-To: <20240214-mbly-gpio-v1-13-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-13-f88c0ccf372b@bootlin.com>
Message-ID: <CAMRc=MdwAQUgc=LP45r-j0UCtN1gzPg9_y3hrbQhCyH91D=W-g@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> Previously, the statement looked like:
>
>     slpm[x] &= ~BIT(g->pins[i]);
>
> Where:
>  - slpm is a unsigned int pointer;
>  - g->pins[i] is a pin number which can grow to more than 32.
>
> The expected shift amount is a pin bank offset.
>
> This bug does not occur on every group or pin: the altsetting must be
> NMK_GPIO_ALT_C and the pin must be 32 or above. It is possible that it
> occurred. For example, in pinctrl-nomadik-db8500.c, pin group i2c3_c_2
> has the right altsetting and has pins 229 and 230.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Maybe add a Fixes: tag and put it at the beginning of the series so
that it can go upstream earlier as a fix?

Bart

> ---
>  drivers/pinctrl/nomadik/pinctrl-nomadik.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
> index c7693fbc0484..99bdb25f358d 100644
> --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
> +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
> @@ -913,8 +913,9 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
>                  */
>                 for (i = 0; i < g->grp.npins; i++) {
>                         struct nmk_gpio_chip *nmk_chip;
> +                       unsigned int bit;
>
> -                       nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], NULL);
> +                       nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], &bit);
>                         if (!nmk_chip) {
>                                 dev_err(npct->dev,
>                                         "invalid pin offset %d in group %s at index %d\n",
> @@ -922,7 +923,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned int function,
>                                 goto out_pre_slpm_init;
>                         }
>
> -                       slpm[nmk_chip->bank] &= ~BIT(g->grp.pins[i]);
> +                       slpm[nmk_chip->bank] &= ~BIT(bit);
>                 }
>                 nmk_gpio_glitch_slpm_init(slpm);
>         }
>
> --
> 2.43.1
>


From theo.lebrun at bootlin.com  Mon Feb 19 07:54:55 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 19 Feb 2024 16:54:55 +0100
Subject: [PATCH 16/23] gpio: nomadik: support shared GPIO IRQs
In-Reply-To: <CAMRc=MdFBFFTYKHgDfOieNZJ+-x7ZZMiYty6buOp2J=eFUjt0Q@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-16-f88c0ccf372b@bootlin.com>
 <CAMRc=MdFBFFTYKHgDfOieNZJ+-x7ZZMiYty6buOp2J=eFUjt0Q@mail.gmail.com>
Message-ID: <CZ96EIJ22CYS.1AMRRY388V466@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 4:48 PM CET, Bartosz Golaszewski wrote:
> On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
> >
> > Support a single IRQs used by multiple GPIO banks. Change the IRQ
> > handler type from a chained handler (as used by gpiolib
> > for ->parent_handler) to a threaded IRQ.
> >
> > Use a fake raw spinlock to ensure generic_handle_irq() is called in a
> > no-irq context. See Documentation/driver-api/gpio/driver.rst, "CHAINED
> > CASCADED GPIO IRQCHIPS" for additional information.
> >
>
> Any reason for not using preempt_disable()?

I did what the doc recommended:

> The generic_handle_irq() is expected to be called with IRQ disabled,
> so the IRQ core will complain if it is called from an IRQ handler which is
> forced to a thread. The "fake?" raw lock can be used to work around this
> problem::
>
>   raw_spinlock_t wa_lock;
>   static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
>       unsigned long wa_lock_flags;
>       raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags);
>       generic_handle_irq(irq_find_mapping(bank->chip.irq.domain, bit));
>       raw_spin_unlock_irqrestore(&bank->wa_lock, wa_lock_flags);

If you confirm I should be using preempt_disable() that's what I'll do
in the next revision. I could even throw in a documentation patch if
the advice is outdated.

Thanks Bartosz,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From Frank.Li at nxp.com  Mon Feb 19 07:57:27 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Mon, 19 Feb 2024 10:57:27 -0500
Subject: [PATCH 1/1] dmaengine: mxs-dma: switch from dma_coherent to dma_pool
Message-ID: <20240219155728.606497-1-Frank.Li@nxp.com>

From: Han Xu <han.xu at nxp.com>

Using dma_pool to manage dma descriptor memory.

Signed-off-by: Han Xu <han.xu at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 drivers/dma/mxs-dma.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index cfb9962417ef6..a60bf7a22492d 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -24,6 +24,7 @@
 #include <linux/of_dma.h>
 #include <linux/list.h>
 #include <linux/dma/mxs-dma.h>
+#include <linux/dmapool.h>
 
 #include <asm/irq.h>
 
@@ -104,6 +105,7 @@ struct mxs_dma_ccw {
 
 #define CCW_BLOCK_SIZE	(4 * PAGE_SIZE)
 #define NUM_CCW	(int)(CCW_BLOCK_SIZE / sizeof(struct mxs_dma_ccw))
+#define CCW_BLOCK_ALGIN	32
 
 struct mxs_dma_chan {
 	struct mxs_dma_engine		*mxs_dma;
@@ -117,6 +119,7 @@ struct mxs_dma_chan {
 	enum dma_status			status;
 	unsigned int			flags;
 	bool				reset;
+	struct dma_pool			*ccw_pool;
 #define MXS_DMA_SG_LOOP			(1 << 0)
 #define MXS_DMA_USE_SEMAPHORE		(1 << 1)
 };
@@ -398,9 +401,8 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
 	struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
 	int ret;
 
-	mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev,
-					   CCW_BLOCK_SIZE,
-					   &mxs_chan->ccw_phys, GFP_KERNEL);
+	mxs_chan->ccw = dma_pool_zalloc(mxs_chan->ccw_pool, GFP_ATOMIC, &mxs_chan->ccw_phys);
+
 	if (!mxs_chan->ccw) {
 		ret = -ENOMEM;
 		goto err_alloc;
@@ -428,8 +430,7 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
 err_clk:
 	free_irq(mxs_chan->chan_irq, mxs_dma);
 err_irq:
-	dma_free_coherent(mxs_dma->dma_device.dev, CCW_BLOCK_SIZE,
-			mxs_chan->ccw, mxs_chan->ccw_phys);
+	dma_pool_free(mxs_chan->ccw_pool, mxs_chan->ccw, mxs_chan->ccw_phys);
 err_alloc:
 	return ret;
 }
@@ -443,8 +444,7 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
 
 	free_irq(mxs_chan->chan_irq, mxs_dma);
 
-	dma_free_coherent(mxs_dma->dma_device.dev, CCW_BLOCK_SIZE,
-			mxs_chan->ccw, mxs_chan->ccw_phys);
+	dma_pool_free(mxs_chan->ccw_pool, mxs_chan->ccw, mxs_chan->ccw_phys);
 
 	clk_disable_unprepare(mxs_dma->clk);
 }
@@ -745,6 +745,7 @@ static int mxs_dma_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	const struct mxs_dma_type *dma_type;
 	struct mxs_dma_engine *mxs_dma;
+	struct dma_pool *ccw_pool;
 	int ret, i;
 
 	mxs_dma = devm_kzalloc(&pdev->dev, sizeof(*mxs_dma), GFP_KERNEL);
@@ -797,6 +798,15 @@ static int mxs_dma_probe(struct platform_device *pdev)
 	mxs_dma->pdev = pdev;
 	mxs_dma->dma_device.dev = &pdev->dev;
 
+	ccw_pool = dma_pool_create("ccw_pool", mxs_dma->dma_device.dev, CCW_BLOCK_SIZE,
+				   CCW_BLOCK_ALGIN, 0);
+
+	for (i = 0; i < MXS_DMA_CHANNELS; i++) {
+		struct mxs_dma_chan *mxs_chan = &mxs_dma->mxs_chans[i];
+
+		mxs_chan->ccw_pool = ccw_pool;
+	}
+
 	/* mxs_dma gets 65535 bytes maximum sg size */
 	dma_set_max_seg_size(mxs_dma->dma_device.dev, MAX_XFER_BYTES);
 
-- 
2.34.1



From thierry.reding at gmail.com  Mon Feb 19 07:58:25 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 19 Feb 2024 16:58:25 +0100
Subject: [PATCH] phy: constify of_phandle_args in xlate
In-Reply-To: <20240217093937.58234-1-krzysztof.kozlowski@linaro.org>
References: <20240217093937.58234-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CZ96H72GI4Z0.SZJBZXA1VXJZ@gmail.com>

On Sat Feb 17, 2024 at 10:39 AM CET, Krzysztof Kozlowski wrote:
> The xlate callbacks are supposed to translate of_phandle_args to proper
> provider without modifying the of_phandle_args.  Make the argument
> pointer to const for code safety and readability.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>  drivers/phy/allwinner/phy-sun4i-usb.c              |  2 +-
>  drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c     |  2 +-
>  drivers/phy/broadcom/phy-bcm-sr-pcie.c             |  2 +-
>  drivers/phy/broadcom/phy-bcm-sr-usb.c              |  2 +-
>  drivers/phy/broadcom/phy-bcm63xx-usbh.c            |  2 +-
>  drivers/phy/broadcom/phy-brcm-usb.c                |  2 +-
>  drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c    |  2 +-
>  drivers/phy/freescale/phy-fsl-lynx-28g.c           |  2 +-
>  drivers/phy/hisilicon/phy-histb-combphy.c          |  2 +-
>  drivers/phy/intel/phy-intel-lgm-combo.c            |  2 +-
>  drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c        |  2 +-
>  drivers/phy/marvell/phy-armada375-usb2.c           |  2 +-
>  drivers/phy/marvell/phy-armada38x-comphy.c         |  2 +-
>  drivers/phy/marvell/phy-berlin-sata.c              |  2 +-
>  drivers/phy/marvell/phy-mvebu-a3700-comphy.c       |  2 +-
>  drivers/phy/marvell/phy-mvebu-cp110-comphy.c       |  2 +-
>  drivers/phy/mediatek/phy-mtk-mipi-csi-0-5.c        |  2 +-
>  drivers/phy/mediatek/phy-mtk-tphy.c                |  2 +-
>  drivers/phy/mediatek/phy-mtk-xsphy.c               |  2 +-
>  drivers/phy/microchip/lan966x_serdes.c             |  2 +-
>  drivers/phy/microchip/sparx5_serdes.c              |  2 +-
>  drivers/phy/mscc/phy-ocelot-serdes.c               |  2 +-
>  drivers/phy/phy-core.c                             |  8 ++++----
>  drivers/phy/phy-xgene.c                            |  2 +-
>  drivers/phy/qualcomm/phy-qcom-qmp-combo.c          |  2 +-
>  drivers/phy/ralink/phy-mt7621-pci.c                |  2 +-
>  drivers/phy/renesas/phy-rcar-gen2.c                |  2 +-
>  drivers/phy/renesas/phy-rcar-gen3-usb2.c           |  2 +-
>  drivers/phy/renesas/r8a779f0-ether-serdes.c        |  2 +-
>  drivers/phy/rockchip/phy-rockchip-naneng-combphy.c |  2 +-
>  drivers/phy/rockchip/phy-rockchip-pcie.c           |  2 +-
>  drivers/phy/samsung/phy-exynos-mipi-video.c        |  2 +-
>  drivers/phy/samsung/phy-exynos5-usbdrd.c           |  2 +-
>  drivers/phy/samsung/phy-samsung-usb2.c             |  2 +-
>  drivers/phy/socionext/phy-uniphier-usb2.c          |  2 +-
>  drivers/phy/st/phy-miphy28lp.c                     |  2 +-
>  drivers/phy/st/phy-spear1310-miphy.c               |  2 +-
>  drivers/phy/st/phy-spear1340-miphy.c               |  2 +-
>  drivers/phy/st/phy-stm32-usbphyc.c                 |  2 +-
>  drivers/phy/tegra/xusb.c                           |  2 +-
>  drivers/phy/ti/phy-am654-serdes.c                  |  2 +-
>  drivers/phy/ti/phy-da8xx-usb.c                     |  2 +-
>  drivers/phy/ti/phy-gmii-sel.c                      |  2 +-
>  drivers/phy/xilinx/phy-zynqmp.c                    |  2 +-
>  drivers/pinctrl/tegra/pinctrl-tegra-xusb.c         |  2 +-
>  include/linux/phy/phy.h                            | 14 +++++++-------
>  46 files changed, 55 insertions(+), 55 deletions(-)

Makes sense:

Acked-by: Thierry Reding <treding at nvidia.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/20240219/c6485ac8/attachment-0001.sig>

From brgl at bgdev.pl  Mon Feb 19 08:08:08 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 17:08:08 +0100
Subject: [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from drivers/pinctrl/nomadik/
In-Reply-To: <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>
Message-ID: <CAMRc=MfXHbpq7vgw64pYGGAyQQnYyGa1ei5NAQ6swtH7o--R=w@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> Previously, drivers/pinctrl/nomadik/pinctrl-nomadik.c registered two
> platform drivers: pinctrl & GPIO. Move the GPIO aspect to the
> drivers/gpio/ folder, as would be expected.
>
> Both drivers are intertwined for a reason; pinctrl requires access to
> GPIO registers for pinmuxing, pull-disable, disabling interrupts while
> setting the muxing and wakeup control. Information sharing is done
> through a shared array containing GPIO chips and a few helper
> functions. That shared array is not touched from gpio-nomadik when
> CONFIG_PINCTRL_NOMADIK is not defined.
>
> Make no change to the code that moved into gpio-nomadik; there should be
> no behavior change following. A few functions are shared and header
> comments are added. Checkpatch warnings are addressed. NUM_BANKS is
> renamed to NMK_MAX_BANKS.
>
> It is supported to compile gpio-nomadik without pinctrl-nomadik. The
> opposite is not true.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  MAINTAINERS                                        |   1 +
>  drivers/gpio/Kconfig                               |  12 +
>  drivers/gpio/Makefile                              |   1 +
>  drivers/gpio/gpio-nomadik.c                        | 660 +++++++++++++++++++
>  drivers/pinctrl/nomadik/Kconfig                    |   5 +-
>  drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c   |   3 +-
>  drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c  |   3 +-
>  drivers/pinctrl/nomadik/pinctrl-nomadik.c          | 722 +--------------------
>  .../linux/gpio/gpio-nomadik.h                      | 122 +++-
>  9 files changed, 804 insertions(+), 725 deletions(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 0cb2c459d1cf..3f864e773267 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2474,6 +2474,7 @@ F:        drivers/clk/clk-nomadik.c
>  F:     drivers/clocksource/clksrc-dbx500-prcmu.c
>  F:     drivers/dma/ste_dma40*
>  F:     drivers/pmdomain/st/ste-ux500-pm-domain.c
> +F:     drivers/gpio/gpio-nomadik.c
>  F:     drivers/hwspinlock/u8500_hsem.c
>  F:     drivers/i2c/busses/i2c-nomadik.c
>  F:     drivers/iio/adc/ab8500-gpadc.c
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 1301cec94f12..ff83371251c1 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -478,6 +478,18 @@ config GPIO_MXS
>         select GPIO_GENERIC
>         select GENERIC_IRQ_CHIP
>
> +config GPIO_NOMADIK
> +       bool "Nomadik GPIO driver"
> +       depends on ARCH_U8500 || ARCH_NOMADIK || COMPILE_TEST
> +       select OF_GPIO
> +       select GPIOLIB_IRQCHIP
> +       help
> +         Say yes here to support the Nomadik SoC GPIO block.
> +
> +         It handles up to 32 GPIOs per bank, that can all be interrupt sources.
> +         It is deeply interconnected with the associated pinctrl driver as GPIO
> +         registers handle muxing ("alternate functions") as well.
> +
>  config GPIO_NPCM_SGPIO
>         bool "Nuvoton SGPIO support"
>         depends on ARCH_NPCM || COMPILE_TEST
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 9e40af196aae..9fc2f5931b22 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -116,6 +116,7 @@ obj-$(CONFIG_GPIO_MT7621)           += gpio-mt7621.o
>  obj-$(CONFIG_GPIO_MVEBU)               += gpio-mvebu.o
>  obj-$(CONFIG_GPIO_MXC)                 += gpio-mxc.o
>  obj-$(CONFIG_GPIO_MXS)                 += gpio-mxs.o
> +obj-$(CONFIG_GPIO_NOMADIK)             += gpio-nomadik.o
>  obj-$(CONFIG_GPIO_NPCM_SGPIO)          += gpio-npcm-sgpio.o
>  obj-$(CONFIG_GPIO_OCTEON)              += gpio-octeon.o
>  obj-$(CONFIG_GPIO_OMAP)                        += gpio-omap.o
> diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
> new file mode 100644
> index 000000000000..e39477e1a58f
> --- /dev/null
> +++ b/drivers/gpio/gpio-nomadik.c
> @@ -0,0 +1,660 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * GPIO driver for the IP block found in the Nomadik SoC; it is an AMBA device,
> + * managing 32 pins with alternate functions. It can also handle the STA2X11
> + * block from ST.
> + *
> + * The GPIO chips are shared with pinctrl-nomadik if used; it needs access for
> + * pinmuxing functionality and others.
> + *
> + * Copyright (C) 2008,2009 STMicroelectronics
> + * Copyright (C) 2009 Alessandro Rubini <rubini at unipv.it>
> + *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar at st.com>
> + * Copyright (C) 2011-2013 Linus Walleij <linus.walleij at linaro.org>
> + */

Add a newline here.

> +#include <linux/cleanup.h>
> +#include <linux/clk.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/of_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset.h>
> +#include <linux/seq_file.h>
> +#include <linux/types.h>

You need linux/slab.h for GFP flags.

> +
> +#include <linux/gpio/gpio-nomadik.h>
> +
> +#ifndef CONFIG_PINCTRL_NOMADIK
> +static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
> +#endif
> +
> +void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset,
> +                        enum nmk_gpio_slpm mode)
> +{
> +       u32 slpm;
> +
> +       slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
> +       if (mode == NMK_GPIO_SLPM_NOCHANGE)
> +               slpm |= BIT(offset);
> +       else
> +               slpm &= ~BIT(offset);
> +       writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
> +}
> +
> +static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
> +                                 unsigned int offset, int val)
> +{
> +       if (val)
> +               writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATS);
> +       else
> +               writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATC);
> +}
> +
> +void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
> +                           unsigned int offset, int val)
> +{
> +       writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRS);
> +       __nmk_gpio_set_output(nmk_chip, offset, val);
> +}
> +
> +/* IRQ functions */
> +
> +static void nmk_gpio_irq_ack(struct irq_data *d)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> +
> +       clk_enable(nmk_chip->clk);
> +       writel(BIT(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
> +       clk_disable(nmk_chip->clk);
> +}
> +
> +enum nmk_gpio_irq_type {
> +       NORMAL,
> +       WAKE,
> +};
> +
> +static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
> +                                 int offset, enum nmk_gpio_irq_type which,
> +                                 bool enable)
> +{
> +       u32 *rimscval;
> +       u32 *fimscval;
> +       u32 rimscreg;
> +       u32 fimscreg;
> +
> +       if (which == NORMAL) {
> +               rimscreg = NMK_GPIO_RIMSC;
> +               fimscreg = NMK_GPIO_FIMSC;
> +               rimscval = &nmk_chip->rimsc;
> +               fimscval = &nmk_chip->fimsc;
> +       } else  {
> +               rimscreg = NMK_GPIO_RWIMSC;
> +               fimscreg = NMK_GPIO_FWIMSC;
> +               rimscval = &nmk_chip->rwimsc;
> +               fimscval = &nmk_chip->fwimsc;
> +       }
> +
> +       /* we must individually set/clear the two edges */
> +       if (nmk_chip->edge_rising & BIT(offset)) {
> +               if (enable)
> +                       *rimscval |= BIT(offset);
> +               else
> +                       *rimscval &= ~BIT(offset);
> +               writel(*rimscval, nmk_chip->addr + rimscreg);
> +       }
> +       if (nmk_chip->edge_falling & BIT(offset)) {
> +               if (enable)
> +                       *fimscval |= BIT(offset);
> +               else
> +                       *fimscval &= ~BIT(offset);
> +               writel(*fimscval, nmk_chip->addr + fimscreg);
> +       }
> +}
> +
> +static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
> +                               int offset, bool on)
> +{
> +       /*
> +        * Ensure WAKEUP_ENABLE is on.  No need to disable it if wakeup is
> +        * disabled, since setting SLPM to 1 increases power consumption, and
> +        * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
> +        */
> +       if (nmk_chip->sleepmode && on) {
> +               __nmk_gpio_set_slpm(nmk_chip, offset,
> +                                   NMK_GPIO_SLPM_WAKEUP_ENABLE);
> +       }
> +
> +       __nmk_gpio_irq_modify(nmk_chip, offset, WAKE, on);
> +}
> +
> +static void nmk_gpio_irq_maskunmask(struct nmk_gpio_chip *nmk_chip,
> +                                   struct irq_data *d, bool enable)
> +{
> +       unsigned long flags;
> +
> +       clk_enable(nmk_chip->clk);
> +       spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
> +       spin_lock(&nmk_chip->lock);
> +
> +       __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
> +
> +       if (!(nmk_chip->real_wake & BIT(d->hwirq)))
> +               __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
> +
> +       spin_unlock(&nmk_chip->lock);
> +       spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
> +       clk_disable(nmk_chip->clk);
> +}
> +
> +static void nmk_gpio_irq_mask(struct irq_data *d)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> +
> +       nmk_gpio_irq_maskunmask(nmk_chip, d, false);
> +       gpiochip_disable_irq(gc, irqd_to_hwirq(d));
> +}
> +
> +static void nmk_gpio_irq_unmask(struct irq_data *d)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> +
> +       gpiochip_enable_irq(gc, irqd_to_hwirq(d));
> +       nmk_gpio_irq_maskunmask(nmk_chip, d, true);
> +}
> +
> +static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> +       unsigned long flags;
> +
> +       clk_enable(nmk_chip->clk);
> +       spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
> +       spin_lock(&nmk_chip->lock);
> +
> +       if (irqd_irq_disabled(d))
> +               __nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
> +
> +       if (on)
> +               nmk_chip->real_wake |= BIT(d->hwirq);
> +       else
> +               nmk_chip->real_wake &= ~BIT(d->hwirq);
> +
> +       spin_unlock(&nmk_chip->lock);
> +       spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
> +       clk_disable(nmk_chip->clk);
> +
> +       return 0;
> +}
> +
> +static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> +       bool enabled = !irqd_irq_disabled(d);
> +       bool wake = irqd_is_wakeup_set(d);
> +       unsigned long flags;
> +
> +       if (type & IRQ_TYPE_LEVEL_HIGH)
> +               return -EINVAL;
> +       if (type & IRQ_TYPE_LEVEL_LOW)
> +               return -EINVAL;
> +
> +       clk_enable(nmk_chip->clk);
> +       spin_lock_irqsave(&nmk_chip->lock, flags);
> +
> +       if (enabled)
> +               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
> +
> +       if (enabled || wake)
> +               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
> +
> +       nmk_chip->edge_rising &= ~BIT(d->hwirq);
> +       if (type & IRQ_TYPE_EDGE_RISING)
> +               nmk_chip->edge_rising |= BIT(d->hwirq);
> +
> +       nmk_chip->edge_falling &= ~BIT(d->hwirq);
> +       if (type & IRQ_TYPE_EDGE_FALLING)
> +               nmk_chip->edge_falling |= BIT(d->hwirq);
> +
> +       if (enabled)
> +               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
> +
> +       if (enabled || wake)
> +               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
> +
> +       spin_unlock_irqrestore(&nmk_chip->lock, flags);
> +       clk_disable(nmk_chip->clk);
> +
> +       return 0;
> +}
> +
> +static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> +
> +       clk_enable(nmk_chip->clk);
> +       nmk_gpio_irq_unmask(d);
> +       return 0;
> +}
> +
> +static void nmk_gpio_irq_shutdown(struct irq_data *d)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> +
> +       nmk_gpio_irq_mask(d);
> +       clk_disable(nmk_chip->clk);
> +}
> +
> +static void nmk_gpio_irq_handler(struct irq_desc *desc)
> +{
> +       struct irq_chip *host_chip = irq_desc_get_chip(desc);
> +       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> +       u32 status;
> +
> +       chained_irq_enter(host_chip, desc);
> +
> +       clk_enable(nmk_chip->clk);
> +       status = readl(nmk_chip->addr + NMK_GPIO_IS);
> +       clk_disable(nmk_chip->clk);
> +
> +       while (status) {
> +               int bit = __ffs(status);
> +
> +               generic_handle_domain_irq(chip->irq.domain, bit);
> +               status &= ~BIT(bit);
> +       }
> +
> +       chained_irq_exit(host_chip, desc);
> +}
> +
> +/* I/O Functions */
> +
> +static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> +       int dir;
> +
> +       clk_enable(nmk_chip->clk);
> +
> +       dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset);
> +
> +       clk_disable(nmk_chip->clk);
> +
> +       if (dir)
> +               return GPIO_LINE_DIRECTION_OUT;
> +
> +       return GPIO_LINE_DIRECTION_IN;
> +}
> +
> +static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> +
> +       clk_enable(nmk_chip->clk);
> +
> +       writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC);
> +
> +       clk_disable(nmk_chip->clk);
> +
> +       return 0;
> +}
> +
> +static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> +       int value;
> +
> +       clk_enable(nmk_chip->clk);
> +
> +       value = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
> +
> +       clk_disable(nmk_chip->clk);
> +
> +       return value;
> +}
> +
> +static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned int offset,
> +                               int val)
> +{
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> +
> +       clk_enable(nmk_chip->clk);
> +
> +       __nmk_gpio_set_output(nmk_chip, offset, val);
> +
> +       clk_disable(nmk_chip->clk);
> +}
> +
> +static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned int offset,
> +                               int val)
> +{
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> +
> +       clk_enable(nmk_chip->clk);
> +
> +       __nmk_gpio_make_output(nmk_chip, offset, val);
> +
> +       clk_disable(nmk_chip->clk);
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_DEBUG_FS
> +
> +static int nmk_gpio_get_mode(struct nmk_gpio_chip *nmk_chip, int offset)
> +{
> +       u32 afunc, bfunc;
> +
> +       clk_enable(nmk_chip->clk);
> +
> +       afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & BIT(offset);
> +       bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & BIT(offset);
> +
> +       clk_disable(nmk_chip->clk);
> +
> +       return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
> +}
> +
> +void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev,
> +                          struct gpio_chip *chip, unsigned int offset,
> +                          unsigned int gpio)
> +{
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> +       int mode;
> +       bool is_out;
> +       bool data_out;
> +       bool pull;
> +       static const char * const modes[] = {
> +               [NMK_GPIO_ALT_GPIO]     = "gpio",
> +               [NMK_GPIO_ALT_A]        = "altA",
> +               [NMK_GPIO_ALT_B]        = "altB",
> +               [NMK_GPIO_ALT_C]        = "altC",
> +               [NMK_GPIO_ALT_C + 1]    = "altC1",
> +               [NMK_GPIO_ALT_C + 2]    = "altC2",
> +               [NMK_GPIO_ALT_C + 3]    = "altC3",
> +               [NMK_GPIO_ALT_C + 4]    = "altC4",
> +       };
> +
> +       char *label = gpiochip_dup_line_label(chip, offset);
> +       if (IS_ERR(label))
> +               return;
> +
> +       clk_enable(nmk_chip->clk);
> +       is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
> +       pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & BIT(offset));
> +       data_out = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
> +       mode = nmk_gpio_get_mode(nmk_chip, offset);
> +#ifdef CONFIG_PINCTRL_NOMADIK
> +       if (mode == NMK_GPIO_ALT_C && pctldev)
> +               mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio);
> +#endif
> +
> +       if (is_out) {
> +               seq_printf(s, " gpio-%-3d (%-20.20s) out %s           %s",
> +                          gpio,
> +                          label ?: "(none)",
> +                          data_out ? "hi" : "lo",
> +                          (mode < 0) ? "unknown" : modes[mode]);
> +       } else {
> +               int irq = chip->to_irq(chip, offset);
> +               const int pullidx = pull ? 1 : 0;
> +               int val;
> +               static const char * const pulls[] = {
> +                       "none        ",
> +                       "pull enabled",
> +               };
> +
> +               seq_printf(s, " gpio-%-3d (%-20.20s) in  %s %s",
> +                          gpio,
> +                          label ?: "(none)",
> +                          pulls[pullidx],
> +                          (mode < 0) ? "unknown" : modes[mode]);
> +
> +               val = nmk_gpio_get_input(chip, offset);
> +               seq_printf(s, " VAL %d", val);
> +
> +               /*
> +                * This races with request_irq(), set_irq_type(),
> +                * and set_irq_wake() ... but those are "rare".
> +                */
> +               if (irq > 0 && irq_has_action(irq)) {
> +                       char *trigger;
> +                       bool wake;
> +
> +                       if (nmk_chip->edge_rising & BIT(offset))
> +                               trigger = "edge-rising";
> +                       else if (nmk_chip->edge_falling & BIT(offset))
> +                               trigger = "edge-falling";
> +                       else
> +                               trigger = "edge-undefined";
> +
> +                       wake = !!(nmk_chip->real_wake & BIT(offset));
> +
> +                       seq_printf(s, " irq-%d %s%s",
> +                                  irq, trigger, wake ? " wakeup" : "");
> +               }
> +       }
> +       clk_disable(nmk_chip->clk);
> +}
> +
> +static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
> +{
> +       unsigned int i, gpio = chip->base;
> +
> +       for (i = 0; i < chip->ngpio; i++, gpio++) {
> +               nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio);
> +               seq_puts(s, "\n");
> +       }
> +}
> +
> +#else
> +
> +static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
> +                                        struct pinctrl_dev *pctldev,
> +                                        struct gpio_chip *chip,
> +                                        unsigned int offset,
> +                                        unsigned int gpio)
> +{
> +}
> +
> +#define nmk_gpio_dbg_show      NULL
> +
> +#endif
> +
> +/*
> + * We will allocate memory for the state container using devm* allocators
> + * binding to the first device reaching this point, it doesn't matter if
> + * it is the pin controller or GPIO driver. However we need to use the right
> + * platform device when looking up resources so pay attention to pdev.
> + */
> +struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
> +                                            struct platform_device *pdev)
> +{
> +       struct nmk_gpio_chip *nmk_chip;
> +       struct platform_device *gpio_pdev;
> +       struct gpio_chip *chip;
> +       struct resource *res;
> +       struct clk *clk;
> +       void __iomem *base;
> +       u32 id;
> +
> +       gpio_pdev = of_find_device_by_node(np);

Any way we can avoid using OF APIs here? How about bus_find_device_by_fwnode()?

In general I'd like to avoid adding new calls to OF functions and use
generic device properties everywhere, so all of_property_* in the
series would ideally be replaced with device_property_* alternatives.

> +       if (!gpio_pdev) {
> +               pr_err("populate \"%pOFn\": device not found\n", np);
> +               return ERR_PTR(-ENODEV);
> +       }
> +       if (of_property_read_u32(np, "gpio-bank", &id)) {
> +               dev_err(&pdev->dev, "populate: gpio-bank property not found\n");
> +               platform_device_put(gpio_pdev);
> +               return ERR_PTR(-EINVAL);
> +       }
> +
> +#ifdef CONFIG_PINCTRL_NOMADIK
> +       /* Already populated? */
> +       nmk_chip = nmk_gpio_chips[id];
> +       if (nmk_chip) {
> +               platform_device_put(gpio_pdev);
> +               return nmk_chip;
> +       }
> +#endif
> +
> +       nmk_chip = devm_kzalloc(&pdev->dev, sizeof(*nmk_chip), GFP_KERNEL);
> +       if (!nmk_chip) {
> +               platform_device_put(gpio_pdev);
> +               return ERR_PTR(-ENOMEM);
> +       }
> +
> +       nmk_chip->bank = id;
> +       chip = &nmk_chip->chip;
> +       chip->base = id * NMK_GPIO_PER_CHIP;
> +       chip->ngpio = NMK_GPIO_PER_CHIP;
> +       chip->label = dev_name(&gpio_pdev->dev);
> +       chip->parent = &gpio_pdev->dev;
> +
> +       res = platform_get_resource(gpio_pdev, IORESOURCE_MEM, 0);
> +       base = devm_ioremap_resource(&pdev->dev, res);

devm_platform_ioremap_resource()?

> +       if (IS_ERR(base)) {
> +               platform_device_put(gpio_pdev);
> +               return ERR_CAST(base);
> +       }
> +       nmk_chip->addr = base;
> +
> +       clk = clk_get(&gpio_pdev->dev, NULL);

devm_clk_get()?

> +       if (IS_ERR(clk)) {
> +               platform_device_put(gpio_pdev);
> +               return (void *)clk;
> +       }
> +       clk_prepare(clk);
> +       nmk_chip->clk = clk;
> +
> +#ifdef CONFIG_PINCTRL_NOMADIK
> +       BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
> +       nmk_gpio_chips[id] = nmk_chip;
> +#endif
> +       return nmk_chip;
> +}
> +
> +static void nmk_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> +
> +       seq_printf(p, "nmk%u-%u-%u", nmk_chip->bank,
> +                  gc->base, gc->base + gc->ngpio - 1);
> +}
> +
> +static const struct irq_chip nmk_irq_chip = {
> +       .irq_ack = nmk_gpio_irq_ack,
> +       .irq_mask = nmk_gpio_irq_mask,
> +       .irq_unmask = nmk_gpio_irq_unmask,
> +       .irq_set_type = nmk_gpio_irq_set_type,
> +       .irq_set_wake = nmk_gpio_irq_set_wake,
> +       .irq_startup = nmk_gpio_irq_startup,
> +       .irq_shutdown = nmk_gpio_irq_shutdown,
> +       .irq_print_chip = nmk_gpio_irq_print_chip,
> +       .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE,
> +       GPIOCHIP_IRQ_RESOURCE_HELPERS,
> +};
> +
> +static int nmk_gpio_probe(struct platform_device *dev)
> +{
> +       struct device_node *np = dev->dev.of_node;
> +       struct nmk_gpio_chip *nmk_chip;
> +       struct gpio_chip *chip;
> +       struct gpio_irq_chip *girq;
> +       bool supports_sleepmode;
> +       int irq;
> +       int ret;
> +
> +       nmk_chip = nmk_gpio_populate_chip(np, dev);
> +       if (IS_ERR(nmk_chip)) {
> +               dev_err(&dev->dev, "could not populate nmk chip struct\n");
> +               return PTR_ERR(nmk_chip);
> +       }
> +
> +       supports_sleepmode =
> +               of_property_read_bool(np, "st,supports-sleepmode");
> +
> +       /* Correct platform device ID */
> +       dev->id = nmk_chip->bank;
> +
> +       irq = platform_get_irq(dev, 0);
> +       if (irq < 0)
> +               return irq;
> +
> +       /*
> +        * The virt address in nmk_chip->addr is in the nomadik register space,
> +        * so we can simply convert the resource address, without remapping
> +        */
> +       nmk_chip->sleepmode = supports_sleepmode;
> +       spin_lock_init(&nmk_chip->lock);
> +
> +       chip = &nmk_chip->chip;
> +       chip->parent = &dev->dev;
> +       chip->request = gpiochip_generic_request;
> +       chip->free = gpiochip_generic_free;
> +       chip->get_direction = nmk_gpio_get_dir;
> +       chip->direction_input = nmk_gpio_make_input;
> +       chip->get = nmk_gpio_get_input;
> +       chip->direction_output = nmk_gpio_make_output;
> +       chip->set = nmk_gpio_set_output;
> +       chip->dbg_show = nmk_gpio_dbg_show;
> +       chip->can_sleep = false;
> +       chip->owner = THIS_MODULE;
> +
> +       girq = &chip->irq;
> +       gpio_irq_chip_set_chip(girq, &nmk_irq_chip);
> +       girq->parent_handler = nmk_gpio_irq_handler;
> +       girq->num_parents = 1;
> +       girq->parents = devm_kcalloc(&dev->dev, 1,
> +                                    sizeof(*girq->parents),
> +                                    GFP_KERNEL);
> +       if (!girq->parents)
> +               return -ENOMEM;
> +       girq->parents[0] = irq;
> +       girq->default_type = IRQ_TYPE_NONE;
> +       girq->handler = handle_edge_irq;
> +
> +       clk_enable(nmk_chip->clk);
> +       nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
> +       clk_disable(nmk_chip->clk);
> +
> +       ret = gpiochip_add_data(chip, nmk_chip);
> +       if (ret)
> +               return ret;
> +
> +       platform_set_drvdata(dev, nmk_chip);
> +
> +       dev_info(&dev->dev, "chip registered\n");
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id nmk_gpio_match[] = {
> +       { .compatible = "st,nomadik-gpio", },
> +       {}
> +};
> +
> +static struct platform_driver nmk_gpio_driver = {
> +       .driver = {
> +               .name = "gpio",
> +               .of_match_table = nmk_gpio_match,
> +       },
> +       .probe = nmk_gpio_probe,
> +};
> +
> +static int __init nmk_gpio_init(void)
> +{
> +       return platform_driver_register(&nmk_gpio_driver);
> +}
> +subsys_initcall(nmk_gpio_init);
> diff --git a/drivers/pinctrl/nomadik/Kconfig b/drivers/pinctrl/nomadik/Kconfig
> index 0fea167c283f..f47f0755a835 100644
> --- a/drivers/pinctrl/nomadik/Kconfig
> +++ b/drivers/pinctrl/nomadik/Kconfig
> @@ -22,11 +22,10 @@ if (ARCH_U8500 || ARCH_NOMADIK)
>
>  config PINCTRL_NOMADIK
>         bool "Nomadik pin controller driver"
> -       depends on OF && GPIOLIB
> +       depends on OF
>         select PINMUX
>         select PINCONF
> -       select OF_GPIO
> -       select GPIOLIB_IRQCHIP
> +       select GPIO_NOMADIK
>
>  config PINCTRL_STN8815
>         bool "STN8815 pin controller driver"
> diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
> index 490e0959e8be..0b4a3dd9d8c7 100644
> --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
> +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
> @@ -3,8 +3,9 @@
>  #include <linux/types.h>
>
>  #include <linux/pinctrl/pinctrl.h>
> +#include <linux/gpio/driver.h>
>
> -#include "pinctrl-nomadik.h"
> +#include <linux/gpio/gpio-nomadik.h>
>
>  /* All the pins that can be used for GPIO and some other functions */
>  #define _GPIO(offset)          (offset)
> diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
> index 1552222ac68e..c5a52fcaba30 100644
> --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
> +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
> @@ -3,8 +3,9 @@
>  #include <linux/types.h>
>
>  #include <linux/pinctrl/pinctrl.h>
> +#include <linux/gpio/driver.h>
>
> -#include "pinctrl-nomadik.h"
> +#include <linux/gpio/gpio-nomadik.h>
>
>  /* All the pins that can be used for GPIO and some other functions */
>  #define _GPIO(offset)          (offset)
> diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
> index 7911353ac97d..f3897dbfa2c3 100644
> --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
> +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
> @@ -1,6 +1,8 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * Generic GPIO driver for logic cells found in the Nomadik SoC
> + * Pinmux & pinconf driver for the IP block found in the Nomadik SoC. This
> + * depends on gpio-nomadik and some handling is intertwined; see nmk_gpio_chips
> + * which is used by this driver to access the GPIO banks array.
>   *
>   * Copyright (C) 2008,2009 STMicroelectronics
>   * Copyright (C) 2009 Alessandro Rubini <rubini at unipv.it>
> @@ -25,6 +27,7 @@
>  #include <linux/seq_file.h>
>  #include <linux/slab.h>
>  #include <linux/spinlock.h>
> +#include <linux/types.h>
>
>  /* Since we request GPIOs from ourself */
>  #include <linux/pinctrl/consumer.h>
> @@ -36,15 +39,7 @@
>  #include "../core.h"
>  #include "../pinctrl-utils.h"
>
> -#include "pinctrl-nomadik.h"
> -
> -/*
> - * The GPIO module in the Nomadik family of Systems-on-Chip is an
> - * AMBA device, managing 32 pins and alternate functions.  The logic block
> - * is currently used in the Nomadik and ux500.
> - *
> - * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
> - */
> +#include <linux/gpio/gpio-nomadik.h>
>
>  /*
>   * pin configurations are represented by 32-bit integers:
> @@ -200,75 +195,6 @@ typedef unsigned long pin_cfg_t;
>         (PIN_CFG_DEFAULT |\
>          (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
>
> -/*
> - * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
> - * the "gpio" namespace for generic and cross-machine functions
> - */
> -
> -#define GPIO_BLOCK_SHIFT 5
> -#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT)
> -#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP)
> -
> -/* Register in the logic block */
> -#define NMK_GPIO_DAT   0x00
> -#define NMK_GPIO_DATS  0x04
> -#define NMK_GPIO_DATC  0x08
> -#define NMK_GPIO_PDIS  0x0c
> -#define NMK_GPIO_DIR   0x10
> -#define NMK_GPIO_DIRS  0x14
> -#define NMK_GPIO_DIRC  0x18
> -#define NMK_GPIO_SLPC  0x1c
> -#define NMK_GPIO_AFSLA 0x20
> -#define NMK_GPIO_AFSLB 0x24
> -#define NMK_GPIO_LOWEMI        0x28
> -
> -#define NMK_GPIO_RIMSC 0x40
> -#define NMK_GPIO_FIMSC 0x44
> -#define NMK_GPIO_IS    0x48
> -#define NMK_GPIO_IC    0x4c
> -#define NMK_GPIO_RWIMSC        0x50
> -#define NMK_GPIO_FWIMSC        0x54
> -#define NMK_GPIO_WKS   0x58
> -/* These appear in DB8540 and later ASICs */
> -#define NMK_GPIO_EDGELEVEL 0x5C
> -#define NMK_GPIO_LEVEL 0x60
> -
> -
> -/* Pull up/down values */
> -enum nmk_gpio_pull {
> -       NMK_GPIO_PULL_NONE,
> -       NMK_GPIO_PULL_UP,
> -       NMK_GPIO_PULL_DOWN,
> -};
> -
> -/* Sleep mode */
> -enum nmk_gpio_slpm {
> -       NMK_GPIO_SLPM_INPUT,
> -       NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
> -       NMK_GPIO_SLPM_NOCHANGE,
> -       NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
> -};
> -
> -struct nmk_gpio_chip {
> -       struct gpio_chip chip;
> -       void __iomem *addr;
> -       struct clk *clk;
> -       unsigned int bank;
> -       void (*set_ioforce)(bool enable);
> -       spinlock_t lock;
> -       bool sleepmode;
> -       /* Keep track of configured edges */
> -       u32 edge_rising;
> -       u32 edge_falling;
> -       u32 real_wake;
> -       u32 rwimsc;
> -       u32 fwimsc;
> -       u32 rimsc;
> -       u32 fimsc;
> -       u32 pull_up;
> -       u32 lowemi;
> -};
> -
>  /**
>   * struct nmk_pinctrl - state container for the Nomadik pin controller
>   * @dev: containing device pointer
> @@ -283,11 +209,10 @@ struct nmk_pinctrl {
>         void __iomem *prcm_base;
>  };
>
> -static struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
> +/* See nmk_gpio_populate_chip() that fills this array. */
> +struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
>
> -static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
> -
> -#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips)
> +DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
>
>  static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
>                                 unsigned offset, int gpio_mode)
> @@ -304,19 +229,6 @@ static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
>         writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
>  }
>
> -static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
> -                               unsigned offset, enum nmk_gpio_slpm mode)
> -{
> -       u32 slpm;
> -
> -       slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
> -       if (mode == NMK_GPIO_SLPM_NOCHANGE)
> -               slpm |= BIT(offset);
> -       else
> -               slpm &= ~BIT(offset);
> -       writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
> -}
> -
>  static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
>                                 unsigned offset, enum nmk_gpio_pull pull)
>  {
> @@ -364,22 +276,6 @@ static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
>         writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC);
>  }
>
> -static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
> -                                 unsigned offset, int val)
> -{
> -       if (val)
> -               writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATS);
> -       else
> -               writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATC);
> -}
> -
> -static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
> -                                 unsigned offset, int val)
> -{
> -       writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRS);
> -       __nmk_gpio_set_output(nmk_chip, offset, val);
> -}
> -
>  static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
>                                      unsigned offset, int gpio_mode,
>                                      bool glitch)
> @@ -548,7 +444,7 @@ static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
>  {
>         int i;
>
> -       for (i = 0; i < NUM_BANKS; i++) {
> +       for (i = 0; i < NMK_MAX_BANKS; i++) {
>                 struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
>                 unsigned int temp = slpm[i];
>
> @@ -566,7 +462,7 @@ static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
>  {
>         int i;
>
> -       for (i = 0; i < NUM_BANKS; i++) {
> +       for (i = 0; i < NMK_MAX_BANKS; i++) {
>                 struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
>
>                 if (!chip)
> @@ -578,7 +474,8 @@ static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
>         }
>  }
>
> -static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
> +/* Only called by gpio-nomadik but requires knowledge of struct nmk_pinctrl. */
> +int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
>  {
>         int i;
>         u16 reg;
> @@ -610,576 +507,6 @@ static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev,
>         return NMK_GPIO_ALT_C;
>  }
>
> -/* IRQ functions */
> -
> -static void nmk_gpio_irq_ack(struct irq_data *d)
> -{
> -       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> -
> -       clk_enable(nmk_chip->clk);
> -       writel(BIT(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
> -       clk_disable(nmk_chip->clk);
> -}
> -
> -enum nmk_gpio_irq_type {
> -       NORMAL,
> -       WAKE,
> -};
> -
> -static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
> -                                 int offset, enum nmk_gpio_irq_type which,
> -                                 bool enable)
> -{
> -       u32 *rimscval;
> -       u32 *fimscval;
> -       u32 rimscreg;
> -       u32 fimscreg;
> -
> -       if (which == NORMAL) {
> -               rimscreg = NMK_GPIO_RIMSC;
> -               fimscreg = NMK_GPIO_FIMSC;
> -               rimscval = &nmk_chip->rimsc;
> -               fimscval = &nmk_chip->fimsc;
> -       } else  {
> -               rimscreg = NMK_GPIO_RWIMSC;
> -               fimscreg = NMK_GPIO_FWIMSC;
> -               rimscval = &nmk_chip->rwimsc;
> -               fimscval = &nmk_chip->fwimsc;
> -       }
> -
> -       /* we must individually set/clear the two edges */
> -       if (nmk_chip->edge_rising & BIT(offset)) {
> -               if (enable)
> -                       *rimscval |= BIT(offset);
> -               else
> -                       *rimscval &= ~BIT(offset);
> -               writel(*rimscval, nmk_chip->addr + rimscreg);
> -       }
> -       if (nmk_chip->edge_falling & BIT(offset)) {
> -               if (enable)
> -                       *fimscval |= BIT(offset);
> -               else
> -                       *fimscval &= ~BIT(offset);
> -               writel(*fimscval, nmk_chip->addr + fimscreg);
> -       }
> -}
> -
> -static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
> -                               int offset, bool on)
> -{
> -       /*
> -        * Ensure WAKEUP_ENABLE is on.  No need to disable it if wakeup is
> -        * disabled, since setting SLPM to 1 increases power consumption, and
> -        * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
> -        */
> -       if (nmk_chip->sleepmode && on) {
> -               __nmk_gpio_set_slpm(nmk_chip, offset,
> -                                   NMK_GPIO_SLPM_WAKEUP_ENABLE);
> -       }
> -
> -       __nmk_gpio_irq_modify(nmk_chip, offset, WAKE, on);
> -}
> -
> -static void nmk_gpio_irq_maskunmask(struct nmk_gpio_chip *nmk_chip,
> -                                   struct irq_data *d, bool enable)
> -{
> -       unsigned long flags;
> -
> -       clk_enable(nmk_chip->clk);
> -       spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
> -       spin_lock(&nmk_chip->lock);
> -
> -       __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
> -
> -       if (!(nmk_chip->real_wake & BIT(d->hwirq)))
> -               __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
> -
> -       spin_unlock(&nmk_chip->lock);
> -       spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
> -       clk_disable(nmk_chip->clk);
> -}
> -
> -static void nmk_gpio_irq_mask(struct irq_data *d)
> -{
> -       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> -
> -       nmk_gpio_irq_maskunmask(nmk_chip, d, false);
> -       gpiochip_disable_irq(gc, irqd_to_hwirq(d));
> -}
> -
> -static void nmk_gpio_irq_unmask(struct irq_data *d)
> -{
> -       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> -
> -       gpiochip_enable_irq(gc, irqd_to_hwirq(d));
> -       nmk_gpio_irq_maskunmask(nmk_chip, d, true);
> -}
> -
> -static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
> -{
> -       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> -       unsigned long flags;
> -
> -       clk_enable(nmk_chip->clk);
> -       spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
> -       spin_lock(&nmk_chip->lock);
> -
> -       if (irqd_irq_disabled(d))
> -               __nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
> -
> -       if (on)
> -               nmk_chip->real_wake |= BIT(d->hwirq);
> -       else
> -               nmk_chip->real_wake &= ~BIT(d->hwirq);
> -
> -       spin_unlock(&nmk_chip->lock);
> -       spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
> -       clk_disable(nmk_chip->clk);
> -
> -       return 0;
> -}
> -
> -static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> -{
> -       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> -       bool enabled = !irqd_irq_disabled(d);
> -       bool wake = irqd_is_wakeup_set(d);
> -       unsigned long flags;
> -
> -       if (type & IRQ_TYPE_LEVEL_HIGH)
> -               return -EINVAL;
> -       if (type & IRQ_TYPE_LEVEL_LOW)
> -               return -EINVAL;
> -
> -       clk_enable(nmk_chip->clk);
> -       spin_lock_irqsave(&nmk_chip->lock, flags);
> -
> -       if (enabled)
> -               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
> -
> -       if (enabled || wake)
> -               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
> -
> -       nmk_chip->edge_rising &= ~BIT(d->hwirq);
> -       if (type & IRQ_TYPE_EDGE_RISING)
> -               nmk_chip->edge_rising |= BIT(d->hwirq);
> -
> -       nmk_chip->edge_falling &= ~BIT(d->hwirq);
> -       if (type & IRQ_TYPE_EDGE_FALLING)
> -               nmk_chip->edge_falling |= BIT(d->hwirq);
> -
> -       if (enabled)
> -               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
> -
> -       if (enabled || wake)
> -               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
> -
> -       spin_unlock_irqrestore(&nmk_chip->lock, flags);
> -       clk_disable(nmk_chip->clk);
> -
> -       return 0;
> -}
> -
> -static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
> -{
> -       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> -
> -       clk_enable(nmk_chip->clk);
> -       nmk_gpio_irq_unmask(d);
> -       return 0;
> -}
> -
> -static void nmk_gpio_irq_shutdown(struct irq_data *d)
> -{
> -       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> -
> -       nmk_gpio_irq_mask(d);
> -       clk_disable(nmk_chip->clk);
> -}
> -
> -static void nmk_gpio_irq_handler(struct irq_desc *desc)
> -{
> -       struct irq_chip *host_chip = irq_desc_get_chip(desc);
> -       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> -       u32 status;
> -
> -       chained_irq_enter(host_chip, desc);
> -
> -       clk_enable(nmk_chip->clk);
> -       status = readl(nmk_chip->addr + NMK_GPIO_IS);
> -       clk_disable(nmk_chip->clk);
> -
> -       while (status) {
> -               int bit = __ffs(status);
> -
> -               generic_handle_domain_irq(chip->irq.domain, bit);
> -               status &= ~BIT(bit);
> -       }
> -
> -       chained_irq_exit(host_chip, desc);
> -}
> -
> -/* I/O Functions */
> -
> -static int nmk_gpio_get_dir(struct gpio_chip *chip, unsigned offset)
> -{
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> -       int dir;
> -
> -       clk_enable(nmk_chip->clk);
> -
> -       dir = readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset);
> -
> -       clk_disable(nmk_chip->clk);
> -
> -       if (dir)
> -               return GPIO_LINE_DIRECTION_OUT;
> -
> -       return GPIO_LINE_DIRECTION_IN;
> -}
> -
> -static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
> -{
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> -
> -       clk_enable(nmk_chip->clk);
> -
> -       writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC);
> -
> -       clk_disable(nmk_chip->clk);
> -
> -       return 0;
> -}
> -
> -static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
> -{
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> -       int value;
> -
> -       clk_enable(nmk_chip->clk);
> -
> -       value = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
> -
> -       clk_disable(nmk_chip->clk);
> -
> -       return value;
> -}
> -
> -static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
> -                               int val)
> -{
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> -
> -       clk_enable(nmk_chip->clk);
> -
> -       __nmk_gpio_set_output(nmk_chip, offset, val);
> -
> -       clk_disable(nmk_chip->clk);
> -}
> -
> -static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
> -                               int val)
> -{
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> -
> -       clk_enable(nmk_chip->clk);
> -
> -       __nmk_gpio_make_output(nmk_chip, offset, val);
> -
> -       clk_disable(nmk_chip->clk);
> -
> -       return 0;
> -}
> -
> -#ifdef CONFIG_DEBUG_FS
> -static int nmk_gpio_get_mode(struct nmk_gpio_chip *nmk_chip, int offset)
> -{
> -       u32 afunc, bfunc;
> -
> -       clk_enable(nmk_chip->clk);
> -
> -       afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & BIT(offset);
> -       bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & BIT(offset);
> -
> -       clk_disable(nmk_chip->clk);
> -
> -       return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
> -}
> -
> -static void nmk_gpio_dbg_show_one(struct seq_file *s,
> -       struct pinctrl_dev *pctldev, struct gpio_chip *chip,
> -       unsigned offset, unsigned gpio)
> -{
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip);
> -       int mode;
> -       bool is_out;
> -       bool data_out;
> -       bool pull;
> -       const char *modes[] = {
> -               [NMK_GPIO_ALT_GPIO]     = "gpio",
> -               [NMK_GPIO_ALT_A]        = "altA",
> -               [NMK_GPIO_ALT_B]        = "altB",
> -               [NMK_GPIO_ALT_C]        = "altC",
> -               [NMK_GPIO_ALT_C+1]      = "altC1",
> -               [NMK_GPIO_ALT_C+2]      = "altC2",
> -               [NMK_GPIO_ALT_C+3]      = "altC3",
> -               [NMK_GPIO_ALT_C+4]      = "altC4",
> -       };
> -
> -       char *label = gpiochip_dup_line_label(chip, offset);
> -       if (IS_ERR(label))
> -               return;
> -
> -       clk_enable(nmk_chip->clk);
> -       is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & BIT(offset));
> -       pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & BIT(offset));
> -       data_out = !!(readl(nmk_chip->addr + NMK_GPIO_DAT) & BIT(offset));
> -       mode = nmk_gpio_get_mode(nmk_chip, offset);
> -       if ((mode == NMK_GPIO_ALT_C) && pctldev)
> -               mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio);
> -
> -       if (is_out) {
> -               seq_printf(s, " gpio-%-3d (%-20.20s) out %s           %s",
> -                          gpio,
> -                          label ?: "(none)",
> -                          data_out ? "hi" : "lo",
> -                          (mode < 0) ? "unknown" : modes[mode]);
> -       } else {
> -               int irq = chip->to_irq(chip, offset);
> -               const int pullidx = pull ? 1 : 0;
> -               int val;
> -               static const char * const pulls[] = {
> -                       "none        ",
> -                       "pull enabled",
> -               };
> -
> -               seq_printf(s, " gpio-%-3d (%-20.20s) in  %s %s",
> -                          gpio,
> -                          label ?: "(none)",
> -                          pulls[pullidx],
> -                          (mode < 0) ? "unknown" : modes[mode]);
> -
> -               val = nmk_gpio_get_input(chip, offset);
> -               seq_printf(s, " VAL %d", val);
> -
> -               /*
> -                * This races with request_irq(), set_irq_type(),
> -                * and set_irq_wake() ... but those are "rare".
> -                */
> -               if (irq > 0 && irq_has_action(irq)) {
> -                       char *trigger;
> -                       bool wake;
> -
> -                       if (nmk_chip->edge_rising & BIT(offset))
> -                               trigger = "edge-rising";
> -                       else if (nmk_chip->edge_falling & BIT(offset))
> -                               trigger = "edge-falling";
> -                       else
> -                               trigger = "edge-undefined";
> -
> -                       wake = !!(nmk_chip->real_wake & BIT(offset));
> -
> -                       seq_printf(s, " irq-%d %s%s",
> -                                  irq, trigger, wake ? " wakeup" : "");
> -               }
> -       }
> -       clk_disable(nmk_chip->clk);
> -}
> -
> -static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
> -{
> -       unsigned                i;
> -       unsigned                gpio = chip->base;
> -
> -       for (i = 0; i < chip->ngpio; i++, gpio++) {
> -               nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio);
> -               seq_printf(s, "\n");
> -       }
> -}
> -
> -#else
> -static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
> -                                        struct pinctrl_dev *pctldev,
> -                                        struct gpio_chip *chip,
> -                                        unsigned offset, unsigned gpio)
> -{
> -}
> -#define nmk_gpio_dbg_show      NULL
> -#endif
> -
> -/*
> - * We will allocate memory for the state container using devm* allocators
> - * binding to the first device reaching this point, it doesn't matter if
> - * it is the pin controller or GPIO driver. However we need to use the right
> - * platform device when looking up resources so pay attention to pdev.
> - */
> -static struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
> -                                               struct platform_device *pdev)
> -{
> -       struct nmk_gpio_chip *nmk_chip;
> -       struct platform_device *gpio_pdev;
> -       struct gpio_chip *chip;
> -       struct resource *res;
> -       struct clk *clk;
> -       void __iomem *base;
> -       u32 id;
> -
> -       gpio_pdev = of_find_device_by_node(np);
> -       if (!gpio_pdev) {
> -               pr_err("populate \"%pOFn\": device not found\n", np);
> -               return ERR_PTR(-ENODEV);
> -       }
> -       if (of_property_read_u32(np, "gpio-bank", &id)) {
> -               dev_err(&pdev->dev, "populate: gpio-bank property not found\n");
> -               platform_device_put(gpio_pdev);
> -               return ERR_PTR(-EINVAL);
> -       }
> -
> -       /* Already populated? */
> -       nmk_chip = nmk_gpio_chips[id];
> -       if (nmk_chip) {
> -               platform_device_put(gpio_pdev);
> -               return nmk_chip;
> -       }
> -
> -       nmk_chip = devm_kzalloc(&pdev->dev, sizeof(*nmk_chip), GFP_KERNEL);
> -       if (!nmk_chip) {
> -               platform_device_put(gpio_pdev);
> -               return ERR_PTR(-ENOMEM);
> -       }
> -
> -       nmk_chip->bank = id;
> -       chip = &nmk_chip->chip;
> -       chip->base = id * NMK_GPIO_PER_CHIP;
> -       chip->ngpio = NMK_GPIO_PER_CHIP;
> -       chip->label = dev_name(&gpio_pdev->dev);
> -       chip->parent = &gpio_pdev->dev;
> -
> -       res = platform_get_resource(gpio_pdev, IORESOURCE_MEM, 0);
> -       base = devm_ioremap_resource(&pdev->dev, res);
> -       if (IS_ERR(base)) {
> -               platform_device_put(gpio_pdev);
> -               return ERR_CAST(base);
> -       }
> -       nmk_chip->addr = base;
> -
> -       clk = clk_get(&gpio_pdev->dev, NULL);
> -       if (IS_ERR(clk)) {
> -               platform_device_put(gpio_pdev);
> -               return (void *) clk;
> -       }
> -       clk_prepare(clk);
> -       nmk_chip->clk = clk;
> -
> -       BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
> -       nmk_gpio_chips[id] = nmk_chip;
> -       return nmk_chip;
> -}
> -
> -static void nmk_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
> -{
> -       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> -       struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc);
> -
> -       seq_printf(p, "nmk%u-%u-%u", nmk_chip->bank,
> -                  gc->base, gc->base + gc->ngpio - 1);
> -}
> -
> -static const struct irq_chip nmk_irq_chip = {
> -       .irq_ack = nmk_gpio_irq_ack,
> -       .irq_mask = nmk_gpio_irq_mask,
> -       .irq_unmask = nmk_gpio_irq_unmask,
> -       .irq_set_type = nmk_gpio_irq_set_type,
> -       .irq_set_wake = nmk_gpio_irq_set_wake,
> -       .irq_startup = nmk_gpio_irq_startup,
> -       .irq_shutdown = nmk_gpio_irq_shutdown,
> -       .irq_print_chip = nmk_gpio_irq_print_chip,
> -       .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE,
> -       GPIOCHIP_IRQ_RESOURCE_HELPERS,
> -};
> -
> -static int nmk_gpio_probe(struct platform_device *dev)
> -{
> -       struct device_node *np = dev->dev.of_node;
> -       struct nmk_gpio_chip *nmk_chip;
> -       struct gpio_chip *chip;
> -       struct gpio_irq_chip *girq;
> -       bool supports_sleepmode;
> -       int irq;
> -       int ret;
> -
> -       nmk_chip = nmk_gpio_populate_chip(np, dev);
> -       if (IS_ERR(nmk_chip)) {
> -               dev_err(&dev->dev, "could not populate nmk chip struct\n");
> -               return PTR_ERR(nmk_chip);
> -       }
> -
> -       supports_sleepmode =
> -               of_property_read_bool(np, "st,supports-sleepmode");
> -
> -       /* Correct platform device ID */
> -       dev->id = nmk_chip->bank;
> -
> -       irq = platform_get_irq(dev, 0);
> -       if (irq < 0)
> -               return irq;
> -
> -       /*
> -        * The virt address in nmk_chip->addr is in the nomadik register space,
> -        * so we can simply convert the resource address, without remapping
> -        */
> -       nmk_chip->sleepmode = supports_sleepmode;
> -       spin_lock_init(&nmk_chip->lock);
> -
> -       chip = &nmk_chip->chip;
> -       chip->parent = &dev->dev;
> -       chip->request = gpiochip_generic_request;
> -       chip->free = gpiochip_generic_free;
> -       chip->get_direction = nmk_gpio_get_dir;
> -       chip->direction_input = nmk_gpio_make_input;
> -       chip->get = nmk_gpio_get_input;
> -       chip->direction_output = nmk_gpio_make_output;
> -       chip->set = nmk_gpio_set_output;
> -       chip->dbg_show = nmk_gpio_dbg_show;
> -       chip->can_sleep = false;
> -       chip->owner = THIS_MODULE;
> -
> -       girq = &chip->irq;
> -       gpio_irq_chip_set_chip(girq, &nmk_irq_chip);
> -       girq->parent_handler = nmk_gpio_irq_handler;
> -       girq->num_parents = 1;
> -       girq->parents = devm_kcalloc(&dev->dev, 1,
> -                                    sizeof(*girq->parents),
> -                                    GFP_KERNEL);
> -       if (!girq->parents)
> -               return -ENOMEM;
> -       girq->parents[0] = irq;
> -       girq->default_type = IRQ_TYPE_NONE;
> -       girq->handler = handle_edge_irq;
> -
> -       clk_enable(nmk_chip->clk);
> -       nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
> -       clk_disable(nmk_chip->clk);
> -
> -       ret = gpiochip_add_data(chip, nmk_chip);
> -       if (ret)
> -               return ret;
> -
> -       platform_set_drvdata(dev, nmk_chip);
> -
> -       dev_info(&dev->dev, "chip registered\n");
> -
> -       return 0;
> -}
> -
>  static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
>  {
>         struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
> @@ -1197,12 +524,12 @@ static const char *nmk_get_group_name(struct pinctrl_dev *pctldev,
>
>  static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
>                               const unsigned **pins,
> -                             unsigned *npins)
> +                             unsigned int *num_pins)
>  {
>         struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
>
>         *pins = npct->soc->groups[selector].grp.pins;
> -       *npins = npct->soc->groups[selector].grp.npins;
> +       *num_pins = npct->soc->groups[selector].grp.npins;
>         return 0;
>  }
>
> @@ -1533,7 +860,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function,
>  {
>         struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
>         const struct nmk_pingroup *g;
> -       static unsigned int slpm[NUM_BANKS];
> +       static unsigned int slpm[NMK_MAX_BANKS];
>         unsigned long flags = 0;
>         bool glitch;
>         int ret = -EINVAL;
> @@ -1919,19 +1246,6 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
>         return 0;
>  }
>
> -static const struct of_device_id nmk_gpio_match[] = {
> -       { .compatible = "st,nomadik-gpio", },
> -       {}
> -};
> -
> -static struct platform_driver nmk_gpio_driver = {
> -       .driver = {
> -               .name = "gpio",
> -               .of_match_table = nmk_gpio_match,
> -       },
> -       .probe = nmk_gpio_probe,
> -};
> -
>  static SIMPLE_DEV_PM_OPS(nmk_pinctrl_pm_ops,
>                         nmk_pinctrl_suspend,
>                         nmk_pinctrl_resume);
> @@ -1945,12 +1259,6 @@ static struct platform_driver nmk_pinctrl_driver = {
>         .probe = nmk_pinctrl_probe,
>  };
>
> -static int __init nmk_gpio_init(void)
> -{
> -       return platform_driver_register(&nmk_gpio_driver);
> -}
> -subsys_initcall(nmk_gpio_init);
> -
>  static int __init nmk_pinctrl_init(void)
>  {
>         return platform_driver_register(&nmk_pinctrl_driver);
> diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.h b/include/linux/gpio/gpio-nomadik.h
> similarity index 61%
> rename from drivers/pinctrl/nomadik/pinctrl-nomadik.h
> rename to include/linux/gpio/gpio-nomadik.h
> index 1ef2559bc571..0166ddb71f43 100644
> --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.h
> +++ b/include/linux/gpio/gpio-nomadik.h
> @@ -1,16 +1,74 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef PINCTRL_PINCTRL_NOMADIK_H
> -#define PINCTRL_PINCTRL_NOMADIK_H
> -
> -#include <linux/kernel.h>
> -#include <linux/types.h>
> -
> -#include <linux/pinctrl/pinctrl.h>
> +#ifndef __LINUX_GPIO_NOMADIK_H
> +#define __LINUX_GPIO_NOMADIK_H
>
>  /* Package definitions */
>  #define PINCTRL_NMK_STN8815    0
>  #define PINCTRL_NMK_DB8500     1
>
> +#define GPIO_BLOCK_SHIFT 5
> +#define NMK_GPIO_PER_CHIP BIT(GPIO_BLOCK_SHIFT)
> +#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP)
> +
> +/* Register in the logic block */
> +#define NMK_GPIO_DAT   0x00
> +#define NMK_GPIO_DATS  0x04
> +#define NMK_GPIO_DATC  0x08
> +#define NMK_GPIO_PDIS  0x0c
> +#define NMK_GPIO_DIR   0x10
> +#define NMK_GPIO_DIRS  0x14
> +#define NMK_GPIO_DIRC  0x18
> +#define NMK_GPIO_SLPC  0x1c
> +#define NMK_GPIO_AFSLA 0x20
> +#define NMK_GPIO_AFSLB 0x24
> +#define NMK_GPIO_LOWEMI        0x28
> +
> +#define NMK_GPIO_RIMSC 0x40
> +#define NMK_GPIO_FIMSC 0x44
> +#define NMK_GPIO_IS    0x48
> +#define NMK_GPIO_IC    0x4c
> +#define NMK_GPIO_RWIMSC        0x50
> +#define NMK_GPIO_FWIMSC        0x54
> +#define NMK_GPIO_WKS   0x58
> +/* These appear in DB8540 and later ASICs */
> +#define NMK_GPIO_EDGELEVEL 0x5C
> +#define NMK_GPIO_LEVEL 0x60
> +
> +/* Pull up/down values */
> +enum nmk_gpio_pull {
> +       NMK_GPIO_PULL_NONE,
> +       NMK_GPIO_PULL_UP,
> +       NMK_GPIO_PULL_DOWN,
> +};
> +
> +/* Sleep mode */
> +enum nmk_gpio_slpm {
> +       NMK_GPIO_SLPM_INPUT,
> +       NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
> +       NMK_GPIO_SLPM_NOCHANGE,
> +       NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
> +};
> +
> +struct nmk_gpio_chip {
> +       struct gpio_chip chip;
> +       void __iomem *addr;
> +       struct clk *clk;
> +       unsigned int bank;
> +       void (*set_ioforce)(bool enable);
> +       spinlock_t lock;
> +       bool sleepmode;
> +       /* Keep track of configured edges */
> +       u32 edge_rising;
> +       u32 edge_falling;
> +       u32 real_wake;
> +       u32 rwimsc;
> +       u32 fwimsc;
> +       u32 rimsc;
> +       u32 fimsc;
> +       u32 pull_up;
> +       u32 lowemi;
> +};
> +
>  /* Alternate functions: function C is set in hw by setting both A and B */
>  #define NMK_GPIO_ALT_GPIO      0
>  #define NMK_GPIO_ALT_A 1
> @@ -104,7 +162,7 @@ struct prcm_gpiocr_altcx_pin_desc {
>  struct nmk_function {
>         const char *name;
>         const char * const *groups;
> -       unsigned ngroups;
> +       unsigned int ngroups;
>  };
>
>  /**
> @@ -141,13 +199,13 @@ struct nmk_pingroup {
>   */
>  struct nmk_pinctrl_soc_data {
>         const struct pinctrl_pin_desc *pins;
> -       unsigned npins;
> +       unsigned int npins;
>         const struct nmk_function *functions;
> -       unsigned nfunctions;
> +       unsigned int nfunctions;
>         const struct nmk_pingroup *groups;
> -       unsigned ngroups;
> +       unsigned int ngroups;
>         const struct prcm_gpiocr_altcx_pin_desc *altcx_pins;
> -       unsigned npins_altcx;
> +       unsigned int npins_altcx;
>         const u16 *prcm_gpiocr_registers;
>  };
>
> @@ -177,4 +235,42 @@ nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
>
>  #endif
>
> -#endif /* PINCTRL_PINCTRL_NOMADIK_H */
> +#ifdef CONFIG_PINCTRL_DB8540
> +
> +void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc);
> +
> +#else
> +
> +static inline void
> +nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
> +{
> +}
> +
> +#endif
> +
> +struct platform_device;
> +
> +/*
> + * Symbols declared in gpio-nomadik used by pinctrl-nomadik. If pinctrl-nomadik
> + * is enabled, then gpio-nomadik is enabled as well; the reverse if not always
> + * true.
> + */
> +void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev,
> +                          struct gpio_chip *chip, unsigned int offset,
> +                          unsigned int gpio);
> +void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
> +                           unsigned int offset, int val);
> +void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset,
> +                        enum nmk_gpio_slpm mode);
> +struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
> +                                            struct platform_device *pdev);
> +
> +/* Symbols declared in pinctrl-nomadik used by gpio-nomadik. */
> +#ifdef CONFIG_PINCTRL_NOMADIK
> +extern struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
> +extern spinlock_t nmk_gpio_slpm_lock;
> +int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev,
> +                                           int gpio);
> +#endif
> +
> +#endif /* __LINUX_GPIO_NOMADIK_H */
>
> --
> 2.43.1
>

Bart


From prabhakar.csengg at gmail.com  Mon Feb 19 08:09:08 2024
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Mon, 19 Feb 2024 16:09:08 +0000
Subject: [PATCH 0/4] Add new Renesas RZ/V2H SoC
Message-ID: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Hi,

This patch series adds initial support for RZ/V2H{P} (R9A09G057) SoC
identification.

The RZ/V2H{P} SoC is equipped with a Quad 64-bit Arm Cortex-A55 core
(up to 1.8 GHz), dual 32-bit Arm Cortex R8 core (up to 800 MHz) and a
32-bit Arm Cortex M33 core (up to 200 MHz). It supports the below
IP blocks/Features:
- Boot
  * Selectable boot CPU from Cortex-M33 or Cortex-A55
- Accelerated engines
  * AI accelerator (dynamically reconfigurable processor for AI (DRP-AI))
  * Dynamic re-configurable processor (DRP)
  * 3D graphics engine (GE3D MALI-G31) (optional)
  * Image signal processing (ISP MALI-C55) (optional)
  * Image scaling unit (ISU)
  * Video codec unit (VCU)
- On-chip SRAM and external memory interfaces
  * On-chip share SRAM (6-Mbyte with ECC)
  * 2-channel memory controller for LPDDR4-3200 or LPDDR4X-3200 with a
    32-bit bus width
  * xSPI interface
  * SDHI (eMMC/SD - 3ch)
- Timers
  * 32-bit general purpose timers (16 ch)
  * 32-bit CMTW (8 ch)
  * 32-bit GTM (8 ch)
  * RTC
  * WDT (4 ch)
- Communication/storage /network interface
  * Ethernet (2 ch: 10/100/1000 BASE)
  * USB2.0 (1 ch: Host/Function, 1 ch: Host only)
  * USB3.2 Gen2 (2 ch: Host only)
  * PCIe Gen3 (1/2/4 lanes)
  * MIPI CSI2 (4 ch: 1/2/4 lanes)
  * MIPI DSI (1ch: 1/2/4 lanes)
  * CAN/CANFD (6 ch)
  * SCI (10 ch: UART/SPI/I2C)
  * SCIF (1 ch)
  * SPI (3 ch)
  * I2C (9 ch)
  * I3C (1 ch)
- Audio
  * Asynchronous sampling rate converter unit (SCU) (up to 192 kHz)
  * DMAC for Audio (ADMAC) is available to transfer audio formats
    of I2S with SCU.
  * Flexible audio clock generator (ADG) for audio functions.
  * I2S (TDM) input/output interfaces (half-duplex 10 ch.; full-duplex
    5 ch.)
  * SPDIF input/output interfaces (3 ch.)
  * Pulse density modulation (PDM) input interfaces (6 ch.)
- Analogue/Digital converter and sensors
  * 2.5 Msps 12-bit ADC (8 ch)
  * Internal temperature sensors (2 ch)
- Security 
  * Hardware cryptographic engine (optional)

Logs:

~ # uname -ra
Linux rz/v2h 6.8.0-rc5+ #167 SMP PREEMPT Mon Feb 19 10:42:01 GMT 2024 aarch64 GNU/Linux
~ #
~ # for i in machine family soc_id revision; do echo -n "$i: ";cat /sys/devices/
soc0/$i; done
machine: Renesas EVK based on r9a09g057h44
family: RZ/V2H
soc_id: r9a09g057
revision: 0
~ # cat /proc/cpuinfo
processor       : 0
BogoMIPS        : 48.00
Features        : fp asimd evtstrm crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x2
CPU part        : 0xd05
CPU revision    : 0

processor       : 1
BogoMIPS        : 48.00
Features        : fp asimd evtstrm crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x2
CPU part        : 0xd05
CPU revision    : 0

processor       : 2
BogoMIPS        : 48.00
Features        : fp asimd evtstrm crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x2
CPU part        : 0xd05
CPU revision    : 0

processor       : 3
BogoMIPS        : 48.00
Features        : fp asimd evtstrm crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x2
CPU part        : 0xd05
CPU revision    : 0

~ # cat /proc/meminfo
MemTotal:       16240544 kB
MemFree:        16201748 kB
MemAvailable:   16073696 kB
Buffers:               0 kB
Cached:             2040 kB
SwapCached:            0 kB
Active:                0 kB
Inactive:             68 kB
Active(anon):          0 kB
Inactive(anon):       68 kB
Active(file):          0 kB
Inactive(file):        0 kB
Unevictable:        2040 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:            84 kB
Mapped:             1456 kB
Shmem:                 0 kB
KReclaimable:       2924 kB
Slab:               8720 kB
SReclaimable:       2924 kB
SUnreclaim:         5796 kB
KernelStack:        1056 kB
PageTables:           40 kB
SecPageTables:         0 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     8120272 kB
Committed_AS:        648 kB
VmallocTotal:   133141626880 kB
VmallocUsed:        1264 kB
VmallocChunk:          0 kB
Percpu:              352 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
FileHugePages:         0 kB
FilePmdMapped:         0 kB
CmaTotal:          32768 kB
CmaFree:           26624 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB
~ # cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
 11:       3426         66        291        243     GICv3  27 Level     arch_timer
 13:          0          0          0          0     GICv3 561 Level     11c01400.serial:rx err
 14:         15          0          0          0     GICv3 564 Level     11c01400.serial:rx full
 15:       1259          0          0          0     GICv3 565 Level     11c01400.serial:tx empty
 16:          0          0          0          0     GICv3 562 Level     11c01400.serial:break
 17:         82          0          0          0     GICv3 566 Level     11c01400.serial:rx ready
 18:          0          0          0          0     GICv3 563 Level     11c01400.serial:tx end
IPI0:         5         20          8         23       Rescheduling interrupts
IPI1:       530        204         91        155       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:         0          0          0          0       IRQ work interrupts
Err:          0
~ #

Cheers,
Prabhakar

Lad Prabhakar (4):
  dt-bindings: soc: renesas: Document Renesas RZ/V2H{P} SoC variants
  dt-bindings: arm: renesas: Document Renesas RZ/V2H{P} System
    Controller
  soc: renesas: Add identification support for RZ/V2H SoC
  arm64: defconfig: Enable R9A09G057 SoC

 .../soc/renesas/renesas,r9a09g057-sys.yaml    | 59 +++++++++++++++++++
 .../bindings/soc/renesas/renesas.yaml         |  8 +++
 arch/arm64/configs/defconfig                  |  1 +
 drivers/soc/renesas/Kconfig                   |  5 ++
 drivers/soc/renesas/renesas-soc.c             | 20 ++++++-
 5 files changed, 92 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml

-- 
2.34.1



From prabhakar.csengg at gmail.com  Mon Feb 19 08:09:10 2024
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Mon, 19 Feb 2024 16:09:10 +0000
Subject: [PATCH 2/4] dt-bindings: arm: renesas: Document Renesas RZ/V2H{P} System Controller
In-Reply-To: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20240219160912.1206647-3-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Add DT binding documentation for System Controller (SYS) found on
RZ/V2H{P} ("R9A09G057") SoC's.

SYS block contains the SYS_LSI_DEVID register which can be used to
retrieve SoC version information.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Fabrizio Castro <fabrizio.castro.jz at renesas.com>
---
Note, the reset index in example node will be update once the CPG
support is upstreamed.
---
 .../soc/renesas/renesas,r9a09g057-sys.yaml    | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml

diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml
new file mode 100644
index 000000000000..ba30d7734ee8
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/renesas/renesas,r9a09g057-sys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/V2H{P} System Controller (SYS)
+
+maintainers:
+  - Geert Uytterhoeven <geert+renesas at glider.be>
+
+description:
+  The RZ/V2H{P} SYS (System Controller) controls the overall
+  configuration of the LSI and supports the following functions,
+  - Trust zone control
+  - Extend access by specific masters to address beyond 4GB space
+  - GBETH configuration
+  - Control of settings and states of SRAM/PCIe/CM33/CA55/CR8/xSPI/ADC/TSU
+  - LSI version
+  - WDT stop control
+  - General registers
+
+properties:
+  compatible:
+    const: renesas,r9a09g057-sys
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Clock from external oscillator
+
+  resets:
+    items:
+      - description: SYS_0_PRESETN reset signal
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    extal_clk: extal-clk {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <24000000>;
+    };
+
+    sys: system-controller at 10430000 {
+        compatible = "renesas,r9a09g057-sys";
+        reg = <0x10430000 0x10000>;
+        clocks = <&extal_clk>;
+        resets = <&cpg 1>;
+    };
-- 
2.34.1



From prabhakar.csengg at gmail.com  Mon Feb 19 08:09:09 2024
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Mon, 19 Feb 2024 16:09:09 +0000
Subject: [PATCH 1/4] dt-bindings: soc: renesas: Document Renesas RZ/V2H{P} SoC variants
In-Reply-To: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20240219160912.1206647-2-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Document Renesas RZ/V2H{P} (R9A09G057) SoC variants.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Fabrizio Castro <fabrizio.castro.jz at renesas.com>
---
 .../devicetree/bindings/soc/renesas/renesas.yaml          | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
index c1ce4da2dc32..109fbc8d48db 100644
--- a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
@@ -513,6 +513,14 @@ properties:
               - renesas,rzv2mevk2   # RZ/V2M Eval Board v2.0
           - const: renesas,r9a09g011
 
+      - description: RZ/V2H{P} (R9A09G057)
+        items:
+          - enum:
+              - renesas,r9a09g057h41 # RZ/V2H
+              - renesas,r9a09g057h42 # RZ/V2H with Mali-G31 support
+              - renesas,r9a09g057h44 # RZ/V2HP with Mali-G31 + Mali-C55 support
+          - const: renesas,r9a09g057
+
 additionalProperties: true
 
 ...
-- 
2.34.1



From prabhakar.csengg at gmail.com  Mon Feb 19 08:09:11 2024
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Mon, 19 Feb 2024 16:09:11 +0000
Subject: [PATCH 3/4] soc: renesas: Add identification support for RZ/V2H SoC
In-Reply-To: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20240219160912.1206647-4-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Add support to identify the RZ/V2H (R9A09G057) SoC.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Fabrizio Castro <fabrizio.castro.jz at renesas.com>
---
 drivers/soc/renesas/Kconfig       |  5 +++++
 drivers/soc/renesas/renesas-soc.c | 20 +++++++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index 5deca747fb77..78d656d7699f 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -344,6 +344,11 @@ config ARCH_R9A09G011
 	help
 	  This enables support for the Renesas RZ/V2M SoC.
 
+config ARCH_R9A09G057
+	bool "ARM64 Platform support for RZ/V2H{P}"
+	help
+	  This enables support for the Renesas RZ/V2H{P} SoC variants.
+
 endif # ARM64
 
 if RISCV
diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
index 8f9b8d3736dc..499d120f9978 100644
--- a/drivers/soc/renesas/renesas-soc.c
+++ b/drivers/soc/renesas/renesas-soc.c
@@ -75,6 +75,10 @@ static const struct renesas_family fam_rzg3s __initconst __maybe_unused = {
 	.name	= "RZ/G3S",
 };
 
+static const struct renesas_family fam_rzv2h __initconst __maybe_unused = {
+	.name	= "RZ/V2H",
+};
+
 static const struct renesas_family fam_rzv2l __initconst __maybe_unused = {
 	.name	= "RZ/V2L",
 };
@@ -177,6 +181,11 @@ static const struct renesas_soc soc_rz_g3s __initconst __maybe_unused = {
 	.id	= 0x85e0447,
 };
 
+static const struct renesas_soc soc_rz_v2h __initconst __maybe_unused = {
+	.family = &fam_rzv2h,
+	.id     = 0x847A447,
+};
+
 static const struct renesas_soc soc_rz_v2l __initconst __maybe_unused = {
 	.family = &fam_rzv2l,
 	.id     = 0x8447447,
@@ -407,6 +416,9 @@ static const struct of_device_id renesas_socs[] __initconst __maybe_unused = {
 #ifdef CONFIG_ARCH_R9A09G011
 	{ .compatible = "renesas,r9a09g011",	.data = &soc_rz_v2m },
 #endif
+#ifdef CONFIG_ARCH_R9A09G057
+	{ .compatible = "renesas,r9a09g057",	.data = &soc_rz_v2h },
+#endif
 #ifdef CONFIG_ARCH_SH73A0
 	{ .compatible = "renesas,sh73a0",	.data = &soc_shmobile_ag5 },
 #endif
@@ -432,6 +444,11 @@ static const struct renesas_id id_rzg2l __initconst = {
 	.mask = 0xfffffff,
 };
 
+static const struct renesas_id id_rzv2h __initconst = {
+	.offset = 0x304,
+	.mask = 0xfffffff,
+};
+
 static const struct renesas_id id_rzv2m __initconst = {
 	.offset = 0x104,
 	.mask = 0xff,
@@ -449,6 +466,7 @@ static const struct of_device_id renesas_ids[] __initconst = {
 	{ .compatible = "renesas,r9a07g054-sysc",	.data = &id_rzg2l },
 	{ .compatible = "renesas,r9a08g045-sysc",	.data = &id_rzg2l },
 	{ .compatible = "renesas,r9a09g011-sys",	.data = &id_rzv2m },
+	{ .compatible = "renesas,r9a09g057-sys",	.data = &id_rzv2h },
 	{ .compatible = "renesas,prr",			.data = &id_prr },
 	{ /* sentinel */ }
 };
@@ -513,7 +531,7 @@ static int __init renesas_soc_init(void)
 			eslo = product & 0xf;
 			soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u",
 							   eshi, eslo);
-		}  else if (id == &id_rzg2l) {
+		}  else if (id == &id_rzg2l || id == &id_rzv2h) {
 			eshi =  ((product >> 28) & 0x0f);
 			soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%u",
 							   eshi);
-- 
2.34.1



From prabhakar.csengg at gmail.com  Mon Feb 19 08:09:12 2024
From: prabhakar.csengg at gmail.com (Prabhakar)
Date: Mon, 19 Feb 2024 16:09:12 +0000
Subject: [PATCH 4/4] arm64: defconfig: Enable R9A09G057 SoC
In-Reply-To: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20240219160912.1206647-5-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Enable support for the Renesas RZ/V2H (R9A09G057) SoC in the ARM64
defconfig.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Fabrizio Castro <fabrizio.castro.jz at renesas.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f9cc5bff157c..5d51ab7d14a3 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1387,6 +1387,7 @@ CONFIG_ARCH_R9A07G044=y
 CONFIG_ARCH_R9A07G054=y
 CONFIG_ARCH_R9A08G045=y
 CONFIG_ARCH_R9A09G011=y
+CONFIG_ARCH_R9A09G057=y
 CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
-- 
2.34.1



From manivannan.sadhasivam at linaro.org  Mon Feb 19 08:12:08 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Mon, 19 Feb 2024 21:42:08 +0530
Subject: [PATCH v10 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>
Message-ID: <20240219161208.GE3281@thinkpad>

On Mon, Feb 19, 2024 at 10:11:45AM -0500, Frank Li wrote:
> On Mon, Feb 05, 2024 at 12:33:21PM -0500, Frank Li wrote:
> > first 6 patches use drvdata: flags to simplify some switch-case code.
> > Improve maintaince and easy to read code.
> > 
> 
> @Lorenzo Pieralisi:
> 
> 	Do you have chance to look other patches?
> 	Mani's apply EP side change. 

Even though the controller is for the endpoint, it is still a controller
driver. So all the patches should go through Lorenzo.

I only merge patches under drivers/pci/endpoint. Hope this clarifies.

- Mani

> 	'PCI: imx6: Add iMX95 Endpoint (EP) support' need be rebased. 
> 
> Frank
> 
> > Then add imx95 basic pci host function.
> > 
> > follow two patch do endpoint code clean up.
> > Then add imx95 basic endpont function.
> > 
> > Compared with v2, added EP function support and some fixes,  please change
> > notes at each patches.
> > 
> > Change from v9 to v10
> > - remove two patches:
> > >   dt-bindings: imx6q-pcie: Add linux,pci-domain as required for iMX8MQ
> > >   PCI: imx6: Using "linux,pci-domain" as slot ID
> > it is not good solution to fixed hardcode check to get controller id.
> > Will see better solution later.
> > 
> > dt-binding pass pcie node:
> > 
> > pcie0: pcie at 4c300000 {
> >                         compatible = "fsl,imx95-pcie";
> >                         reg = <0 0x4c300000 0 0x40000>,
> >                                 <0 0x4c360000 0 0x10000>,
> >                                 <0 0x4c340000 0 0x20000>,
> >                                 <0 0x60100000 0 0xfe00000>;
> >                         reg-names = "dbi", "atu", "app", "config";
> >                         #address-cells = <3>;
> >                         #size-cells = <2>;
> >                         device_type = "pci";
> >                         linux,pci-domain = <0>;
> >                         bus-range = <0x00 0xff>;
> >                         ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
> >                                  <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
> >                         num-lanes = <1>;
> >                         num-viewport = <8>;
> >                         interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
> >                         interrupt-names = "msi";
> >                         #interrupt-cells = <1>;
> >                         interrupt-map-mask = <0 0 0 0x7>;
> >                         interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0 0 0 2 &gic 0 0 GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0 0 0 3 &gic 0 0 GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
> >                                         <0 0 0 4 &gic 0 0 GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
> >                         fsl,max-link-speed = <3>;
> >                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
> >                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
> >                         assigned-clock-parents = <0>, <0>,
> >                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
> >                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> >                         /* 0x30~0x37 stream id for pci0 */
> >                         /*
> >                          * iommu-map = <0x000 &apps_smmu 0x30 0x1>,
> >                          * <0x100 &apps_smmu 0x31 0x1>;
> >                          */
> >                         status = "disabled";
> >                 };
> > 
> > pcie1: pcie-ep at 4c380000 {
> >                         compatible = "fsl,imx95-pcie-ep";
> >                         reg = <0 0x4c380000 0 0x20000>,
> >                               <0 0x4c3e0000 0 0x1000>,
> >                               <0 0x4c3a0000 0 0x1000>,
> >                               <0 0x4c3c0000 0 0x10000>,
> >                               <0 0x4c3f0000 0 0x10000>,
> >                               <0xa 0 1 0>;
> >                         reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
> >                         interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
> >                         interrupt-names = "dma";
> >                         fsl,max-link-speed = <3>;
> >                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
> >                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
> >                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> >                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
> >                         assigned-clock-parents = <0>, <0>,
> >                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
> >                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> >                         status = "disabled";
> >                 };
> > 
> > Frank Li (13):
> >   PCI: imx6: Simplify clock handling by using clk_bulk*() function
> >   PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
> >   PCI: imx6: Simplify reset handling by using by using
> >     *_FLAG_HAS_*_RESET
> >   PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
> >   PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
> >   PCI: imx6: Simplify switch-case logic by involve init_phy callback
> >   dt-bindings: imx6q-pcie: Clean up irrationality clocks check
> >   dt-bindings: imx6q-pcie: Restruct reg and reg-name
> >   PCI: imx6: Add iMX95 PCIe Root Complex support
> >   PCI: imx6: Clean up get addr_space code
> >   PCI: imx6: Add epc_features in imx6_pcie_drvdata
> >   dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
> >   PCI: imx6: Add iMX95 Endpoint (EP) support
> > 
> > Richard Zhu (1):
> >   dt-bindings: imx6q-pcie: Add imx95 pcie compatible string
> > 
> >  .../bindings/pci/fsl,imx6q-pcie-common.yaml   |  17 +-
> >  .../bindings/pci/fsl,imx6q-pcie-ep.yaml       |  46 +-
> >  .../bindings/pci/fsl,imx6q-pcie.yaml          |  49 +-
> >  drivers/pci/controller/dwc/pci-imx6.c         | 634 ++++++++++--------
> >  4 files changed, 436 insertions(+), 310 deletions(-)
> > 
> > -- 
> > 2.34.1
> > 

-- 
????????? ????????


From brgl at bgdev.pl  Mon Feb 19 08:17:20 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 17:17:20 +0100
Subject: [PATCH 16/23] gpio: nomadik: support shared GPIO IRQs
In-Reply-To: <CZ96EIJ22CYS.1AMRRY388V466@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-16-f88c0ccf372b@bootlin.com> <CAMRc=MdFBFFTYKHgDfOieNZJ+-x7ZZMiYty6buOp2J=eFUjt0Q@mail.gmail.com>
 <CZ96EIJ22CYS.1AMRRY388V466@bootlin.com>
Message-ID: <CAMRc=MeKOJLMCxr2iMSYSK0A0O2L=Mw96B1opYiPdLsqQrB0_w@mail.gmail.com>

On Mon, Feb 19, 2024 at 4:54?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> Hello,
>
> On Mon Feb 19, 2024 at 4:48 PM CET, Bartosz Golaszewski wrote:
> > On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
> > >
> > > Support a single IRQs used by multiple GPIO banks. Change the IRQ
> > > handler type from a chained handler (as used by gpiolib
> > > for ->parent_handler) to a threaded IRQ.
> > >
> > > Use a fake raw spinlock to ensure generic_handle_irq() is called in a
> > > no-irq context. See Documentation/driver-api/gpio/driver.rst, "CHAINED
> > > CASCADED GPIO IRQCHIPS" for additional information.
> > >
> >
> > Any reason for not using preempt_disable()?
>
> I did what the doc recommended:
>
> > The generic_handle_irq() is expected to be called with IRQ disabled,
> > so the IRQ core will complain if it is called from an IRQ handler which is
> > forced to a thread. The "fake?" raw lock can be used to work around this
> > problem::
> >
> >   raw_spinlock_t wa_lock;
> >   static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
> >       unsigned long wa_lock_flags;
> >       raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags);
> >       generic_handle_irq(irq_find_mapping(bank->chip.irq.domain, bit));
> >       raw_spin_unlock_irqrestore(&bank->wa_lock, wa_lock_flags);
>
> If you confirm I should be using preempt_disable() that's what I'll do
> in the next revision. I could even throw in a documentation patch if
> the advice is outdated.
>
> Thanks Bartosz,

This was added 9 years ago:

commit c307b002548590c5d8c32b964831de671ad4affe
Author: Grygorii Strashko <grygorii.strashko at ti.com>
Date:   Tue Oct 20 17:22:15 2015 +0300

    gpio: add a real time compliance notes

    Put in a compliance checklist.

    Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
    Signed-off-by: Linus Walleij <linus.walleij at linaro.org>

I'm Cc'ing Grygorii - maybe he can remember if there was any reason
for using a spinlock over preempt_disable(). But for now I'd go with
the latter.

Bart

>
> --
> Th?o Lebrun, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


From brgl at bgdev.pl  Mon Feb 19 08:17:52 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 17:17:52 +0100
Subject: [PATCH 17/23] gpio: nomadik: handle variadic GPIO count
In-Reply-To: <20240214-mbly-gpio-v1-17-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-17-f88c0ccf372b@bootlin.com>
Message-ID: <CAMRc=Me=SiS5oScmm8jMNsed_2smN4p6s+xPnkTzjHM_hPPULQ@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> Read the "ngpios" device-tree property to determine the number of GPIOs
> for a bank. If not available, fallback to NMK_GPIO_PER_CHIP ie 32 ie
> the current behavior.
>
> The IP block always supports 32 GPIOs, but platforms can expose a lesser
> amount. The Mobileye EyeQ5 is in this case; one bank is 29 GPIOs and
> the other is 23.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  drivers/gpio/gpio-nomadik.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
> index 5b1e3b3efcff..02b53c58adf7 100644
> --- a/drivers/gpio/gpio-nomadik.c
> +++ b/drivers/gpio/gpio-nomadik.c
> @@ -490,7 +490,7 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
>         struct resource *res;
>         struct clk *clk;
>         void __iomem *base;
> -       u32 id;
> +       u32 id, ngpio;
>
>         gpio_pdev = of_find_device_by_node(np);
>         if (!gpio_pdev) {
> @@ -518,10 +518,15 @@ struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
>                 return ERR_PTR(-ENOMEM);
>         }
>
> +       if (of_property_read_u32(np, "ngpios", &ngpio)) {

As commented elsewhere - please try to use device_property_read_u32().

Bart

> +               ngpio = NMK_GPIO_PER_CHIP;
> +               dev_dbg(&pdev->dev, "populate: using default ngpio (%d)\n", ngpio);
> +       }
> +
>         nmk_chip->bank = id;
>         chip = &nmk_chip->chip;
>         chip->base = -1;
> -       chip->ngpio = NMK_GPIO_PER_CHIP;
> +       chip->ngpio = ngpio;
>         chip->label = dev_name(&gpio_pdev->dev);
>         chip->parent = &gpio_pdev->dev;
>
>
> --
> 2.43.1
>


From Frank.li at nxp.com  Mon Feb 19 08:18:03 2024
From: Frank.li at nxp.com (Frank Li)
Date: Mon, 19 Feb 2024 11:18:03 -0500
Subject: [PATCH v10 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <20240219161208.GE3281@thinkpad>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>
 <20240219161208.GE3281@thinkpad>
Message-ID: <ZdN/OyNpw0Xa7qXG@lizhi-Precision-Tower-5810>

On Mon, Feb 19, 2024 at 09:42:08PM +0530, Manivannan Sadhasivam wrote:
> On Mon, Feb 19, 2024 at 10:11:45AM -0500, Frank Li wrote:
> > On Mon, Feb 05, 2024 at 12:33:21PM -0500, Frank Li wrote:
> > > first 6 patches use drvdata: flags to simplify some switch-case code.
> > > Improve maintaince and easy to read code.
> > > 
> > 
> > @Lorenzo Pieralisi:
> > 
> > 	Do you have chance to look other patches?
> > 	Mani's apply EP side change. 
> 
> Even though the controller is for the endpoint, it is still a controller
> driver. So all the patches should go through Lorenzo.
> 
> I only merge patches under drivers/pci/endpoint. Hope this clarifies.

Sorry. It confused everyone. My means was that Mani applied Niklas Cassel's
patches, which cause my 14th patch build failure.

I asked if I need update my 14th patch or applied 1-13 only. 

Frank Li

> 
> - Mani
> 
> > 	'PCI: imx6: Add iMX95 Endpoint (EP) support' need be rebased. 
> > 
> > Frank
> > 
> > > Then add imx95 basic pci host function.
> > > 
> > > follow two patch do endpoint code clean up.
> > > Then add imx95 basic endpont function.
> > > 
> > > Compared with v2, added EP function support and some fixes,  please change
> > > notes at each patches.
> > > 
> > > Change from v9 to v10
> > > - remove two patches:
> > > >   dt-bindings: imx6q-pcie: Add linux,pci-domain as required for iMX8MQ
> > > >   PCI: imx6: Using "linux,pci-domain" as slot ID
> > > it is not good solution to fixed hardcode check to get controller id.
> > > Will see better solution later.
> > > 
> > > dt-binding pass pcie node:
> > > 
> > > pcie0: pcie at 4c300000 {
> > >                         compatible = "fsl,imx95-pcie";
> > >                         reg = <0 0x4c300000 0 0x40000>,
> > >                                 <0 0x4c360000 0 0x10000>,
> > >                                 <0 0x4c340000 0 0x20000>,
> > >                                 <0 0x60100000 0 0xfe00000>;
> > >                         reg-names = "dbi", "atu", "app", "config";
> > >                         #address-cells = <3>;
> > >                         #size-cells = <2>;
> > >                         device_type = "pci";
> > >                         linux,pci-domain = <0>;
> > >                         bus-range = <0x00 0xff>;
> > >                         ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
> > >                                  <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
> > >                         num-lanes = <1>;
> > >                         num-viewport = <8>;
> > >                         interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
> > >                         interrupt-names = "msi";
> > >                         #interrupt-cells = <1>;
> > >                         interrupt-map-mask = <0 0 0 0x7>;
> > >                         interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
> > >                                         <0 0 0 2 &gic 0 0 GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
> > >                                         <0 0 0 3 &gic 0 0 GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
> > >                                         <0 0 0 4 &gic 0 0 GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
> > >                         fsl,max-link-speed = <3>;
> > >                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> > >                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
> > >                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> > >                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
> > >                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> > >                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
> > >                         assigned-clock-parents = <0>, <0>,
> > >                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
> > >                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> > >                         /* 0x30~0x37 stream id for pci0 */
> > >                         /*
> > >                          * iommu-map = <0x000 &apps_smmu 0x30 0x1>,
> > >                          * <0x100 &apps_smmu 0x31 0x1>;
> > >                          */
> > >                         status = "disabled";
> > >                 };
> > > 
> > > pcie1: pcie-ep at 4c380000 {
> > >                         compatible = "fsl,imx95-pcie-ep";
> > >                         reg = <0 0x4c380000 0 0x20000>,
> > >                               <0 0x4c3e0000 0 0x1000>,
> > >                               <0 0x4c3a0000 0 0x1000>,
> > >                               <0 0x4c3c0000 0 0x10000>,
> > >                               <0 0x4c3f0000 0 0x10000>,
> > >                               <0xa 0 1 0>;
> > >                         reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
> > >                         interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
> > >                         interrupt-names = "dma";
> > >                         fsl,max-link-speed = <3>;
> > >                         clocks = <&scmi_clk IMX95_CLK_HSIO>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPLL>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> > >                                  <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> > >                         clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
> > >                         assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
> > >                                          <&scmi_clk IMX95_CLK_HSIOPLL>,
> > >                                          <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
> > >                         assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
> > >                         assigned-clock-parents = <0>, <0>,
> > >                                                  <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
> > >                         power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
> > >                         status = "disabled";
> > >                 };
> > > 
> > > Frank Li (13):
> > >   PCI: imx6: Simplify clock handling by using clk_bulk*() function
> > >   PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
> > >   PCI: imx6: Simplify reset handling by using by using
> > >     *_FLAG_HAS_*_RESET
> > >   PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
> > >   PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
> > >   PCI: imx6: Simplify switch-case logic by involve init_phy callback
> > >   dt-bindings: imx6q-pcie: Clean up irrationality clocks check
> > >   dt-bindings: imx6q-pcie: Restruct reg and reg-name
> > >   PCI: imx6: Add iMX95 PCIe Root Complex support
> > >   PCI: imx6: Clean up get addr_space code
> > >   PCI: imx6: Add epc_features in imx6_pcie_drvdata
> > >   dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
> > >   PCI: imx6: Add iMX95 Endpoint (EP) support
> > > 
> > > Richard Zhu (1):
> > >   dt-bindings: imx6q-pcie: Add imx95 pcie compatible string
> > > 
> > >  .../bindings/pci/fsl,imx6q-pcie-common.yaml   |  17 +-
> > >  .../bindings/pci/fsl,imx6q-pcie-ep.yaml       |  46 +-
> > >  .../bindings/pci/fsl,imx6q-pcie.yaml          |  49 +-
> > >  drivers/pci/controller/dwc/pci-imx6.c         | 634 ++++++++++--------
> > >  4 files changed, 436 insertions(+), 310 deletions(-)
> > > 
> > > -- 
> > > 2.34.1
> > > 
> 
> -- 
> ????????? ????????


From konrad.dybcio at linaro.org  Mon Feb 19 08:19:28 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 17:19:28 +0100
Subject: [PATCH 3/8] clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
In-Reply-To: <CAA8EJpq8XvQm9B3RZq9PNMqA5VAqKUyVn5qt8-WEYMQMWniDZA@mail.gmail.com>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
 <20240219-topic-rb1_gpu-v1-3-d260fa854707@linaro.org>
 <CAA8EJpq8XvQm9B3RZq9PNMqA5VAqKUyVn5qt8-WEYMQMWniDZA@mail.gmail.com>
Message-ID: <c78db7e1-65b5-4276-bb77-d43b1e22fd84@linaro.org>

On 19.02.2024 15:53, Dmitry Baryshkov wrote:
> On Mon, 19 Feb 2024 at 15:36, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>>
>> Commit 134b55b7e19f ("clk: qcom: support Huayra type Alpha PLL")
>> introduced an entry to the alpha offsets array, but diving into QCM2290
>> downstream and some documentation, it turned out that the name Huayra
>> apparently has been used quite liberally across many chips, even with
>> noticeably different hardware.
>>
>> Introduce another set of offsets and a new configure function for the
>> Huayra PLL found on QCM2290. This is required e.g. for the consumers
>> of GPUCC_PLL0 to properly start.
>>
>> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
>> ---
>>  drivers/clk/qcom/clk-alpha-pll.c | 45 ++++++++++++++++++++++++++++++++++++++++
>>  drivers/clk/qcom/clk-alpha-pll.h |  3 +++
>>  2 files changed, 48 insertions(+)
>>
>> diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
>> index 8a412ef47e16..61b5abd13782 100644
>> --- a/drivers/clk/qcom/clk-alpha-pll.c
>> +++ b/drivers/clk/qcom/clk-alpha-pll.c
>> @@ -244,6 +244,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
>>                 [PLL_OFF_OPMODE] = 0x30,
>>                 [PLL_OFF_STATUS] = 0x3c,
>>         },
>> +       [CLK_ALPHA_PLL_TYPE_HUAYRA_2290] =  {
>> +               [PLL_OFF_L_VAL] = 0x04,
>> +               [PLL_OFF_ALPHA_VAL] = 0x08,
>> +               [PLL_OFF_USER_CTL] = 0x0c,
>> +               [PLL_OFF_CONFIG_CTL] = 0x10,
>> +               [PLL_OFF_CONFIG_CTL_U] = 0x14,
>> +               [PLL_OFF_CONFIG_CTL_U1] = 0x18,
>> +               [PLL_OFF_TEST_CTL] = 0x1c,
>> +               [PLL_OFF_TEST_CTL_U] = 0x20,
>> +               [PLL_OFF_TEST_CTL_U1] = 0x24,
>> +               [PLL_OFF_OPMODE] = 0x28,
>> +               [PLL_OFF_STATUS] = 0x38,
>> +       },
> 
> Can you please move them next to the standard huayra PLL regs?

Sure, no prob

Konrad


From dmitry.baryshkov at linaro.org  Mon Feb 19 08:21:06 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 18:21:06 +0200
Subject: [PATCH] irqchip/gic-v3: handle DOMAIN_BUS_ANY in gic_irq_domain_select
In-Reply-To: <868r3g4fhv.wl-maz@kernel.org>
References: <20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f@linaro.org> <868r3g4fhv.wl-maz@kernel.org>
Message-ID: <CAA8EJpqiN6oRMWhAMMP6EsAeki5KSMbO+XzEtT9YRdJKc9_Gbg@mail.gmail.com>

On Mon, 19 Feb 2024 at 17:53, Marc Zyngier <maz at kernel.org> wrote:
>
> On Mon, 19 Feb 2024 14:47:37 +0000,
> Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> >
> > Before the commit de1ff306dcf4 ("genirq/irqdomain: Remove the param
> > count restriction from select()") the irq_find_matching_fwspec() was
> > handling the DOMAIN_BUS_ANY on its own. After this commit it is a job of
> > the select() callback. However the callback of GICv3 (even though it got
> > modified to handle zero param_count) wasn't prepared to return true for
> > DOMAIN_BUS_ANY bus_token.
> >
> > This breaks probing of any of the child IRQ domains, since
> > platform_irqchip_probe() uses irq_find_matching_host(par_np,
> > DOMAIN_BUS_ANY) to check for the presence of the parent IRQ domain.
> >
> > Fixes: 151378251004 ("irqchip/gic-v3: Make gic_irq_domain_select() robust for zero parameter count")
> > Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from select()")
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > ---
> >  drivers/irqchip/irq-gic-v3.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > index 6fb276504bcc..e9e9643c653f 100644
> > --- a/drivers/irqchip/irq-gic-v3.c
> > +++ b/drivers/irqchip/irq-gic-v3.c
> > @@ -1696,7 +1696,8 @@ static int gic_irq_domain_select(struct irq_domain *d,
> >
> >       /* Handle pure domain searches */
> >       if (!fwspec->param_count)
> > -             return d->bus_token == bus_token;
> > +             return d->bus_token == bus_token ||
> > +                     bus_token == DOMAIN_BUS_ANY;
> >
> >       /* If this is not DT, then we have a single domain */
> >       if (!is_of_node(fwspec->fwnode))
> >
>
> I really dislike the look of this. If that's the case, any irqchip
> that has a 'select' method (such as imx-intmux) should be similarly
> hacked. And at this point, this should be handled by the core code.
>
> Can you try this instead? I don't have any HW that relies on
> behaviour, but I'd expect this to work.
>
> Thanks,
>
>         M.
>
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index aeb41655d6de..3dd1c871e091 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -449,7 +449,7 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
>          */
>         mutex_lock(&irq_domain_mutex);
>         list_for_each_entry(h, &irq_domain_list, link) {
> -               if (h->ops->select)
> +               if (h->ops->select && bus_token != DOMAIN_BUS_ANY)
>                         rc = h->ops->select(h, fwspec, bus_token);
>                 else if (h->ops->match)
>                         rc = h->ops->match(h, to_of_node(fwnode), bus_token);

This works. But I wonder if the following change is even better. WDYT?

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index aeb41655d6de..2f0d2700709e 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -449,14 +449,17 @@ struct irq_domain
*irq_find_matching_fwspec(struct irq_fwspec *fwspec,
         */
        mutex_lock(&irq_domain_mutex);
        list_for_each_entry(h, &irq_domain_list, link) {
-               if (h->ops->select)
+               if (fwnode != NULL &&
+                   h->fwnode == fwnode &&
+                   bus_token == DOMAIN_BUS_ANY)
+                       rc = true;
+               else if (h->ops->select)
                        rc = h->ops->select(h, fwspec, bus_token);
                else if (h->ops->match)
                        rc = h->ops->match(h, to_of_node(fwnode), bus_token);
                else
                        rc = ((fwnode != NULL) && (h->fwnode == fwnode) &&
-                             ((bus_token == DOMAIN_BUS_ANY) ||
-                              (h->bus_token == bus_token)));
+                             (h->bus_token == bus_token));

                if (rc) {
                        found = h;


-- 
With best wishes
Dmitry


From festevam at gmail.com  Mon Feb 19 08:23:22 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Mon, 19 Feb 2024 13:23:22 -0300
Subject: [PATCH 1/1] dmaengine: mxs-dma: switch from dma_coherent to dma_pool
In-Reply-To: <20240219155728.606497-1-Frank.Li@nxp.com>
References: <20240219155728.606497-1-Frank.Li@nxp.com>
Message-ID: <CAOMZO5C4XFGoWYgexdFLgHiXAoAP7-aMdi=K6CG3adQE_mHAmA@mail.gmail.com>

On Mon, Feb 19, 2024 at 12:57?PM Frank Li <Frank.Li at nxp.com> wrote:
>
> From: Han Xu <han.xu at nxp.com>
>
> Using dma_pool to manage dma descriptor memory.

Please clearly describe the motivation for doing this.


From dmitry.baryshkov at linaro.org  Mon Feb 19 08:24:34 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 18:24:34 +0200
Subject: [PATCH 3/8] clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
In-Reply-To: <d212b700-aedb-4653-80e4-36320b33e51e@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
 <20240219-topic-rb1_gpu-v1-3-d260fa854707@linaro.org> <u7beg6ui3i6nxoaulc3o7ghfkvcsy46ps53k3jynrurdwn6o7o@ppyqoz4jsotc>
 <d212b700-aedb-4653-80e4-36320b33e51e@linaro.org>
Message-ID: <CAA8EJppcqE3rODfFsgaMuN=TqiphvVOBh3UUV81GULrUdsGRJA@mail.gmail.com>

On Mon, 19 Feb 2024 at 17:01, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>
> On 19.02.2024 15:54, Andrew Halaney wrote:
> > On Mon, Feb 19, 2024 at 02:35:48PM +0100, Konrad Dybcio wrote:
> >> Commit 134b55b7e19f ("clk: qcom: support Huayra type Alpha PLL")
> >> introduced an entry to the alpha offsets array, but diving into QCM2290
> >> downstream and some documentation, it turned out that the name Huayra
> >> apparently has been used quite liberally across many chips, even with
> >> noticeably different hardware.
> >>
> >> Introduce another set of offsets and a new configure function for the
> >> Huayra PLL found on QCM2290. This is required e.g. for the consumers
> >> of GPUCC_PLL0 to properly start.
> >>
> >> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> >> ---
> >>  drivers/clk/qcom/clk-alpha-pll.c | 45 ++++++++++++++++++++++++++++++++++++++++
> >>  drivers/clk/qcom/clk-alpha-pll.h |  3 +++
> >>  2 files changed, 48 insertions(+)
> >>
> >> diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
> >> index 8a412ef47e16..61b5abd13782 100644
> >> --- a/drivers/clk/qcom/clk-alpha-pll.c
> >> +++ b/drivers/clk/qcom/clk-alpha-pll.c
> >> @@ -244,6 +244,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
> >>              [PLL_OFF_OPMODE] = 0x30,
> >>              [PLL_OFF_STATUS] = 0x3c,
> >>      },
> >> +    [CLK_ALPHA_PLL_TYPE_HUAYRA_2290] =  {
> >> +            [PLL_OFF_L_VAL] = 0x04,
> >> +            [PLL_OFF_ALPHA_VAL] = 0x08,
> >> +            [PLL_OFF_USER_CTL] = 0x0c,
> >> +            [PLL_OFF_CONFIG_CTL] = 0x10,
> >> +            [PLL_OFF_CONFIG_CTL_U] = 0x14,
> >> +            [PLL_OFF_CONFIG_CTL_U1] = 0x18,
> >> +            [PLL_OFF_TEST_CTL] = 0x1c,
> >> +            [PLL_OFF_TEST_CTL_U] = 0x20,
> >> +            [PLL_OFF_TEST_CTL_U1] = 0x24,
> >> +            [PLL_OFF_OPMODE] = 0x28,
> >> +            [PLL_OFF_STATUS] = 0x38,
> >> +    },
> >>  };
> >>  EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
> >>
> >> @@ -779,6 +792,38 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> >>      return clamp(rate, min_freq, max_freq);
> >>  }
> >>
> >> +void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
> >> +                               const struct alpha_pll_config *config)
> >> +{
> >> +    clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
> >> +    clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);
> >> +    clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);
> >> +    clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);
> >> +    clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);
> >> +    clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);
> >> +    clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
> >> +    clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
> >> +    clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
> >> +
> >> +    /* Set PLL_BYPASSNL */
> >> +    regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL);
> >> +
> >> +    /* Wait 5 us between setting BYPASS and deasserting reset */
> >> +    mb();
> >> +    udelay(5);
> >> +
> >> +    /* Take PLL out from reset state */
> >> +    regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
> >> +
> >> +    /* Wait 50us for PLL_LOCK_DET bit to go high */
> >> +    mb();
> >> +    usleep_range(50, 55);
> >
> > I *think* you'd want to use a read to ensure your write goes through
> > prior to your sleep... from memory-barriers.txt:
> >
> >       5. A readX() by a CPU thread from the peripheral will complete before
> >          any subsequent delay() loop can begin execution on the same thread.
> >          This ensures that two MMIO register writes by the CPU to a peripheral
> >          will arrive at least 1us apart if the first write is immediately read
> >          back with readX() and udelay(1) is called prior to the second
> >          writeX():
> >
> >               writel(42, DEVICE_REGISTER_0); // Arrives at the device...
> >               readl(DEVICE_REGISTER_0);
> >               udelay(1);
> >               writel(42, DEVICE_REGISTER_1); // ...at least 1us before this.
> >
> > also https://youtu.be/i6DayghhA8Q?si=7lp0be35q1HRmlnV&t=1677
> > for more references on this topic.
>
> I mentioned this feels very iffy in the cover letter, but it's a combination
> of two things:
>
> 1. i followed what qualcomm downstream code did
>
> 2. qualcomm downstream code is not known for being always correct
>
>
>
> I suppose a readback would be the correct solution, but then it should be
> done for all similar calls in this driver.
>
> Although this code has shipped in literally hundreds of millions of devices
> and it didn't explode badly :P (i'm not defending it, though)

I think the idea behind the code looks pretty close to
clk_alpha_pll_stromer_plus_set_rate(), which uses neither wmb() nor
read-back.


-- 
With best wishes
Dmitry


From thierry.reding at gmail.com  Mon Feb 19 08:27:28 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 19 Feb 2024 17:27:28 +0100
Subject: [PATCH] interconnect: constify of_phandle_args in xlate
In-Reply-To: <41e371f1-96f4-45c0-9f65-81ed6924b325@linaro.org>
References: <20240216135236.129878-1-krzysztof.kozlowski@linaro.org>
 <488cc7dc-f45a-4c9e-b572-e4a6b3202e3e@linaro.org>
 <41e371f1-96f4-45c0-9f65-81ed6924b325@linaro.org>
Message-ID: <CZ973FMYMJAO.PQ0Z5YLXZPPM@gmail.com>

On Fri Feb 16, 2024 at 2:59 PM CET, Krzysztof Kozlowski wrote:
> On 16/02/2024 14:55, Konrad Dybcio wrote:
> > On 16.02.2024 14:52, Krzysztof Kozlowski wrote:
> >> The xlate callbacks are supposed to translate of_phandle_args to proper
> >> provider without modifying the of_phandle_args.  Make the argument
> >> pointer to const for code safety and readability.
> >>
> >> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> >> ---
> >>  drivers/gpio/gpiolib-of.c              |  2 +-
> >>  drivers/interconnect/core.c            |  4 ++--
> >>  drivers/interconnect/qcom/icc-common.c |  3 ++-
> >>  drivers/interconnect/qcom/icc-common.h |  3 ++-
> >>  drivers/interconnect/samsung/exynos.c  |  2 +-
> >>  drivers/memory/tegra/mc.c              |  2 +-
> >>  drivers/memory/tegra/tegra124-emc.c    |  2 +-
> >>  drivers/memory/tegra/tegra124.c        |  2 +-
> >>  drivers/memory/tegra/tegra186-emc.c    |  2 +-
> >>  drivers/memory/tegra/tegra20-emc.c     |  2 +-
> >>  drivers/memory/tegra/tegra20.c         |  2 +-
> >>  drivers/memory/tegra/tegra30-emc.c     |  2 +-
> >>  drivers/memory/tegra/tegra30.c         |  2 +-
> >>  include/linux/interconnect-provider.h  | 11 ++++++-----
> >>  include/soc/tegra/mc.h                 |  7 ++++---
> > 
> > Ended up being a bit wider than just icc..
> > 
> > Looks sane apart from that
>
> Tegra memory controllers are also interconnect providers, so two subsystems.
>
> This patch should go via interconnect tree.

I think Konrad might have been referring to the GPIO hunk, which seems
out of place. For the Tegra parts, though:

Acked-by: Thierry Reding <treding at nvidia.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/20240219/0a3b4f80/attachment.sig>

From theo.lebrun at bootlin.com  Mon Feb 19 08:27:56 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 19 Feb 2024 17:27:56 +0100
Subject: [PATCH 10/13] i2c: nomadik: support Mobileye EyeQ5 I2C
 controller
In-Reply-To: <CZ952TBZGEVD.JYSAQGNL1ZAQ@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-10-19a336e91dca@bootlin.com>
 <CACRpkdY4PtnWkAEa=8sHdx7zYXLVAsrqKEVJY9m7VqeG5h6ChQ@mail.gmail.com>
 <CZ952TBZGEVD.JYSAQGNL1ZAQ@bootlin.com>
Message-ID: <CZ973SP3M9PS.3GG13IHI2DNR4@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 3:52 PM CET, Th?o Lebrun wrote:
> On Mon Feb 19, 2024 at 3:35 PM CET, Linus Walleij wrote:
> > On Thu, Feb 15, 2024 at 5:52?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
> >
> > > Add compatible for the integration of the same DB8500 IP block into the
> > > Mobileye EyeQ5 platform. Two quirks are present:
> > >
> > >  - The memory bus only supports 32-bit accesses. One writeb() is done to
> > >    fill the Tx FIFO which we replace with a writel().
> > >
> > >  - A register must be configured for the I2C speed mode; it is located
> > >    in a shared register region called OLB. We access that memory region
> > >    using a syscon & regmap that gets passed as a phandle (mobileye,olb).
> > >
> > >    A two-bit enum per controller is written into the register; that
> > >    requires us to know the global index of the I2C
> > >    controller (mobileye,id).
> > >
> > > We add #include <linux/mfd/syscon.h> and <linux/regmap.h> and sort
> > > headers.
> > >
> > > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> >
> > (...)
> >
> > > -               writeb(*priv->cli.buffer, priv->virtbase + I2C_TFR);
> > > +               if (priv->has_32b_bus)
> > > +                       writel(*priv->cli.buffer, priv->virtbase + I2C_TFR);
> > > +               else
> > > +                       writeb(*priv->cli.buffer, priv->virtbase + I2C_TFR);
> >
> > Are the other byte accessors working flawlessly? I get the shivers.
> > If it's needed in one place I bet the others prefer 32bit access too.
>
> I see where your shivers come from; I'll investigate as I don't remember
> my conclusion from the time when I worked on this driver (a few months
> ago).
>
> > Further the MIPS is big-endian is it not? It feels that this just happens
> > to work because of byte order access? writel() is little-endian by
> > definition.
>
> Actually, no. Our platform is little-endian.
>
> The full story, summarised: the endianness of our cores in kernel and
> hypervisor mode is defined by a pin read at reset. User mode can toggle
> the endianness at runtime I believe, but that is not of our concern.
> Our endianness in kernel mode is little-endian because the pin in
> question is hardwired to the value meaning little-endian.
>
> > What happens if you replace all writeb():s with something like
> >
> > static void nmk_write_reg(struct nmk_i2c_dev *priv, u32 reg, u8 val)
> > {
> >     if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
> >         writeb(val, priv->virtbase + reg + 3);
> >         // if this doesn't work then use writeb((u32)val,
> > priv->virtbase + reg) I guess
> >    else
> >         writeb(val, priv->virtbase + reg);
> > }
> >
> > and conversely for readb()?
>
> As mentionned above, big endian isn't the worry for us. I'll be checking
> the readb() calls found in i2c_irq_handler() though.

Follow up on this. It was working by luck.

 - writeb() are generating Store Byte (sb) instructions which are
   unsupported on the memory bus.

 - readb() are generating Load Doubleword (ld) instructions and not the
   expected Load Byte (lb). It explains why readb() are working.

To be safe I'll make sure to use readl() and writel() everywhere for our
compatible. There is one writeb() and three readb(). Only the writeb()
was covered by this V1.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From maz at kernel.org  Mon Feb 19 08:37:52 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 16:37:52 +0000
Subject: [PATCH] irqchip/gic-v3: handle DOMAIN_BUS_ANY in gic_irq_domain_select
In-Reply-To: <CAA8EJpqiN6oRMWhAMMP6EsAeki5KSMbO+XzEtT9YRdJKc9_Gbg@mail.gmail.com>
References: <20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f@linaro.org>
	<868r3g4fhv.wl-maz@kernel.org>
	<CAA8EJpqiN6oRMWhAMMP6EsAeki5KSMbO+XzEtT9YRdJKc9_Gbg@mail.gmail.com>
Message-ID: <865xyk4dgf.wl-maz@kernel.org>

On Mon, 19 Feb 2024 16:21:06 +0000,
Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> 
> On Mon, 19 Feb 2024 at 17:53, Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Mon, 19 Feb 2024 14:47:37 +0000,
> > Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> > >
> > > Before the commit de1ff306dcf4 ("genirq/irqdomain: Remove the param
> > > count restriction from select()") the irq_find_matching_fwspec() was
> > > handling the DOMAIN_BUS_ANY on its own. After this commit it is a job of
> > > the select() callback. However the callback of GICv3 (even though it got
> > > modified to handle zero param_count) wasn't prepared to return true for
> > > DOMAIN_BUS_ANY bus_token.
> > >
> > > This breaks probing of any of the child IRQ domains, since
> > > platform_irqchip_probe() uses irq_find_matching_host(par_np,
> > > DOMAIN_BUS_ANY) to check for the presence of the parent IRQ domain.
> > >
> > > Fixes: 151378251004 ("irqchip/gic-v3: Make gic_irq_domain_select() robust for zero parameter count")
> > > Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from select()")
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > > ---
> > >  drivers/irqchip/irq-gic-v3.c | 3 ++-
> > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > > index 6fb276504bcc..e9e9643c653f 100644
> > > --- a/drivers/irqchip/irq-gic-v3.c
> > > +++ b/drivers/irqchip/irq-gic-v3.c
> > > @@ -1696,7 +1696,8 @@ static int gic_irq_domain_select(struct irq_domain *d,
> > >
> > >       /* Handle pure domain searches */
> > >       if (!fwspec->param_count)
> > > -             return d->bus_token == bus_token;
> > > +             return d->bus_token == bus_token ||
> > > +                     bus_token == DOMAIN_BUS_ANY;
> > >
> > >       /* If this is not DT, then we have a single domain */
> > >       if (!is_of_node(fwspec->fwnode))
> > >
> >
> > I really dislike the look of this. If that's the case, any irqchip
> > that has a 'select' method (such as imx-intmux) should be similarly
> > hacked. And at this point, this should be handled by the core code.
> >
> > Can you try this instead? I don't have any HW that relies on
> > behaviour, but I'd expect this to work.
> >
> > Thanks,
> >
> >         M.
> >
> > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> > index aeb41655d6de..3dd1c871e091 100644
> > --- a/kernel/irq/irqdomain.c
> > +++ b/kernel/irq/irqdomain.c
> > @@ -449,7 +449,7 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
> >          */
> >         mutex_lock(&irq_domain_mutex);
> >         list_for_each_entry(h, &irq_domain_list, link) {
> > -               if (h->ops->select)
> > +               if (h->ops->select && bus_token != DOMAIN_BUS_ANY)
> >                         rc = h->ops->select(h, fwspec, bus_token);
> >                 else if (h->ops->match)
> >                         rc = h->ops->match(h, to_of_node(fwnode), bus_token);
> 
> This works. But I wonder if the following change is even better. WDYT?
> 
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index aeb41655d6de..2f0d2700709e 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -449,14 +449,17 @@ struct irq_domain
> *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
>          */
>         mutex_lock(&irq_domain_mutex);
>         list_for_each_entry(h, &irq_domain_list, link) {
> -               if (h->ops->select)
> +               if (fwnode != NULL &&
> +                   h->fwnode == fwnode &&
> +                   bus_token == DOMAIN_BUS_ANY)
> +                       rc = true;
> +               else if (h->ops->select)
>                         rc = h->ops->select(h, fwspec, bus_token);
>                 else if (h->ops->match)
>                         rc = h->ops->match(h, to_of_node(fwnode), bus_token);
>                 else
>                         rc = ((fwnode != NULL) && (h->fwnode == fwnode) &&
> -                             ((bus_token == DOMAIN_BUS_ANY) ||
> -                              (h->bus_token == bus_token)));
> +                             (h->bus_token == bus_token));
> 
>                 if (rc) {
>                         found = h;
> 

Can't say I like it either. It duplicates the existing check without
any obvious benefit. Honestly, this code is shit enough that we should
try to make it simpler, not more complex...

I'd rather we keep the impact as minimal as possible, and use the
upcoming weeks to weed out the effects of these changes (there is
another report of some Renesas machine falling over itself here[1]).

Thanks,

	M.

[1] https://lore.kernel.org/all/170802702416.398.14922976721740218856.tip-bot2 at tip-bot2

-- 
Without deviation from the norm, progress is not possible.


From thierry.reding at gmail.com  Mon Feb 19 08:46:04 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 19 Feb 2024 17:46:04 +0100
Subject: [PATCH net-next v3 1/3] net: stmmac: Pass resources to DT parsing
 code
In-Reply-To: <20240219-stmmac-axi-config-v3-0-fca7f046e6ee@nvidia.com>
References: <20240219-stmmac-axi-config-v3-0-fca7f046e6ee@nvidia.com>
Message-ID: <20240219-stmmac-axi-config-v3-1-fca7f046e6ee@nvidia.com>

From: Thierry Reding <treding at nvidia.com>

We already pass the stmmac_resources structure to other initialization
functions since it allows us to exchange more data between the driver
and those functions. Passing this structure to the DT parsing code makes
it easier to extend what we pass around in the future.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
Changes in v2:
- fix bisectability
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c       |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c        |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c       |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c     |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 19 +++++++++++--------
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h |  3 ++-
 24 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
index 643ee6d8d4dd..f37d9912380b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
@@ -115,7 +115,7 @@ static int anarion_dwmac_probe(struct platform_device *pdev)
 	if (IS_ERR(gmac))
 		return PTR_ERR(gmac);
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
index ec924c6c76c6..36ef2ed9fd2d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
@@ -435,7 +435,7 @@ static int dwc_eth_dwmac_probe(struct platform_device *pdev)
 	if (IS_ERR(stmmac_res.addr))
 		return PTR_ERR(stmmac_res.addr);
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
index 598eff926815..98a00084807b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
@@ -27,7 +27,7 @@ static int dwmac_generic_probe(struct platform_device *pdev)
 		return ret;
 
 	if (pdev->dev.of_node) {
-		plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+		plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 		if (IS_ERR(plat_dat)) {
 			dev_err(&pdev->dev, "dt configuration failed\n");
 			return PTR_ERR(plat_dat);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
index 6b65420e11b5..d72b9d8ac464 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
@@ -331,7 +331,7 @@ static int imx_dwmac_probe(struct platform_device *pdev)
 	if (!dwmac)
 		return -ENOMEM;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c
index 19c93b998fb3..de2f5d7e95b2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ingenic.c
@@ -241,7 +241,7 @@ static int ingenic_mac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
index d68f0c4e7835..79582983c060 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
@@ -84,7 +84,7 @@ static int intel_eth_plat_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat)) {
 		dev_err(&pdev->dev, "dt configuration failed\n");
 		return PTR_ERR(plat_dat);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
index 281687d7083b..311410509012 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
@@ -384,7 +384,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
 	if (val)
 		return val;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
index 3e86810717d3..1ede4f409937 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
@@ -169,7 +169,7 @@ static int ls1x_dwmac_probe(struct platform_device *pdev)
 	if (!dwmac)
 		return -ENOMEM;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
 				     "dt configuration failed\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
index 4c810d8f5bea..004bf4d14fdb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
@@ -37,7 +37,7 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
index 2a9132d6d743..763ec218ff2c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -656,7 +656,7 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
index a16bfa9089ea..5bd936ef2796 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
@@ -52,7 +52,7 @@ static int meson6_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index b23944aa344e..88db2907640d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -400,7 +400,7 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 2691a250a5a7..7f4cbea4042f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -735,7 +735,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, ret,
 				     "Failed to get platform resources\n");
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat)) {
 		return dev_err_probe(dev, PTR_ERR(plat_dat),
 				     "dt configuration failed\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 382e8de1255d..4297a6919c8a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1824,7 +1824,7 @@ static int rk_gmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 68f85e4605cb..e827e01b4398 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -400,7 +400,7 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
index 4e1076faee0c..a0f15fbb8993 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
@@ -122,7 +122,7 @@ static int starfive_dwmac_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, err,
 				     "failed to get resources\n");
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
 				     "dt configuration failed\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
index 4445cddc4cbe..5b2cde45dc3e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -273,7 +273,7 @@ static int sti_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index c92dfc4ecf57..af131b0bf589 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -366,7 +366,7 @@ static int stm32_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index b21d99faa2d0..8f47f2e904d3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -1223,7 +1223,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return -EINVAL;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
index 2653a9f0958c..f78e244b9d81 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
@@ -108,7 +108,7 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
index 362f85136c3e..bab57d1675df 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
@@ -284,7 +284,7 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
 	if (err < 0)
 		goto disable_clks;
 
-	plat = devm_stmmac_probe_config_dt(pdev, res.mac);
+	plat = devm_stmmac_probe_config_dt(pdev, &res);
 	if (IS_ERR(plat)) {
 		err = PTR_ERR(plat);
 		goto disable_clks;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
index a5a5cfa989c6..f99d147b3424 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
@@ -220,7 +220,7 @@ static int visconti_eth_dwmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	plat_dat = devm_stmmac_probe_config_dt(pdev, &stmmac_res);
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 54797edc9b38..4e2eb54306f9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -424,13 +424,14 @@ static void stmmac_remove_config_dt(struct platform_device *pdev,
 /**
  * stmmac_probe_config_dt - parse device-tree driver parameters
  * @pdev: platform_device structure
- * @mac: MAC address to use
+ * @res: driver-specific parameters
  * Description:
  * this function is to read the driver parameters from device-tree and
  * set some private fields that will be used by the main at runtime.
  */
 static struct plat_stmmacenet_data *
-stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+stmmac_probe_config_dt(struct platform_device *pdev,
+		       struct stmmac_resources *res)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct plat_stmmacenet_data *plat;
@@ -443,12 +444,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 	if (!plat)
 		return ERR_PTR(-ENOMEM);
 
-	rc = of_get_mac_address(np, mac);
+	rc = of_get_mac_address(np, res->mac);
 	if (rc) {
 		if (rc == -EPROBE_DEFER)
 			return ERR_PTR(rc);
 
-		eth_zero_addr(mac);
+		eth_zero_addr(res->mac);
 	}
 
 	phy_mode = device_get_phy_mode(&pdev->dev);
@@ -677,17 +678,18 @@ static void devm_stmmac_remove_config_dt(void *data)
 /**
  * devm_stmmac_probe_config_dt
  * @pdev: platform_device structure
- * @mac: MAC address to use
+ * @res: driver-specific parameters
  * Description: Devres variant of stmmac_probe_config_dt(). Does not require
  * the user to call stmmac_remove_config_dt() at driver detach.
  */
 struct plat_stmmacenet_data *
-devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+devm_stmmac_probe_config_dt(struct platform_device *pdev,
+			    struct stmmac_resources *res)
 {
 	struct plat_stmmacenet_data *plat;
 	int ret;
 
-	plat = stmmac_probe_config_dt(pdev, mac);
+	plat = stmmac_probe_config_dt(pdev, res);
 	if (IS_ERR(plat))
 		return plat;
 
@@ -700,7 +702,8 @@ devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
 }
 #else
 struct plat_stmmacenet_data *
-devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+devm_stmmac_probe_config_dt(struct platform_device *pdev,
+			    struct stmmac_resources *res)
 {
 	return ERR_PTR(-EINVAL);
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
index bb6fc7e59aed..daf3bbb503a3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
@@ -12,7 +12,8 @@
 #include "stmmac.h"
 
 struct plat_stmmacenet_data *
-devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
+devm_stmmac_probe_config_dt(struct platform_device *pdev,
+			    struct stmmac_resources *res);
 
 int stmmac_get_platform_resources(struct platform_device *pdev,
 				  struct stmmac_resources *stmmac_res);

-- 
2.43.2



From thierry.reding at gmail.com  Mon Feb 19 08:46:03 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 19 Feb 2024 17:46:03 +0100
Subject: [PATCH net-next v3 0/3] net: stmmac: Allow driver-specific AXI
 configuration
Message-ID: <20240219-stmmac-axi-config-v3-0-fca7f046e6ee@nvidia.com>

AXI bus configuration can, in most cases, be derived from the compatible
string, so instead of relying exclusively on device tree for the AXI bus
configuration, create a method for device drivers to pass along a known-
good configuration.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
Changes in v3:
- add comments to help explain override logic
- add missing kerneldoc for new parameter
- Link to v2: https://lore.kernel.org/r/20240202-stmmac-axi-config-v2-0-64eab2bab17b at nvidia.com

Changes in v2:
- fix bisectability issue between patches 1 and 2
- Link to v1: https://lore.kernel.org/r/20240201-stmmac-axi-config-v1-0-822e97b2d26e at nvidia.com

---
Thierry Reding (3):
      net: stmmac: Pass resources to DT parsing code
      net: stmmac: Allow drivers to provide a default AXI configuration
      net: stmmac: Configure AXI on Tegra234 MGBE

 .../net/ethernet/stmicro/stmmac/dwmac-anarion.c    |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-generic.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-ingenic.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-loongson1.c  |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c  |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    |  2 +-
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-starfive.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c  | 11 ++-
 .../net/ethernet/stmicro/stmmac/dwmac-visconti.c   |  2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 78 ++++++++++++++--------
 .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |  3 +-
 25 files changed, 87 insertions(+), 49 deletions(-)
---
base-commit: 35a4fdde2466b9d90af297f249436a270ef9d30e
change-id: 20240201-stmmac-axi-config-77ea05ea9eff

Best regards,
-- 
Thierry Reding <treding at nvidia.com>



From thierry.reding at gmail.com  Mon Feb 19 08:46:05 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 19 Feb 2024 17:46:05 +0100
Subject: [PATCH net-next v3 2/3] net: stmmac: Allow drivers to provide a
 default AXI configuration
In-Reply-To: <20240219-stmmac-axi-config-v3-0-fca7f046e6ee@nvidia.com>
References: <20240219-stmmac-axi-config-v3-0-fca7f046e6ee@nvidia.com>
Message-ID: <20240219-stmmac-axi-config-v3-2-fca7f046e6ee@nvidia.com>

From: Thierry Reding <treding at nvidia.com>

In many cases the AXI configuration can be derived from the compatible
string, so there's no need to add the configuration to DT. Allow drivers
to pass in the default AXI configuration so they can be properly set up
without extra data in DT.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
Changes in v3:
- add comments to help explain override logic
- add missing kerneldoc for new parameter

Changes in v2:
- fix bisectability
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 59 +++++++++++++++-------
 2 files changed, 43 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index dddcaa9220cc..573c5d99b4d6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -36,6 +36,8 @@ struct stmmac_resources {
 	int sfty_ue_irq;
 	int rx_irq[MTL_MAX_RX_QUEUES];
 	int tx_irq[MTL_MAX_TX_QUEUES];
+
+	const struct stmmac_axi *axi;
 };
 
 enum stmmac_txbuf_type {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 4e2eb54306f9..583f78ae9bb0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -87,38 +87,61 @@ static int dwmac1000_validate_ucast_entries(struct device *dev,
 /**
  * stmmac_axi_setup - parse DT parameters for programming the AXI register
  * @pdev: platform device
+ * @res: driver-specific parameters
  * Description:
- * if required, from device-tree the AXI internal register can be tuned
- * by using platform parameters.
+ * Use driver-specific defaults for the AXI internal registers if available,
+ * or parse them from device tree, if present. Driver-specific defaults can
+ * be overridden by the values from device tree.
  */
-static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
+static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev,
+					   struct stmmac_resources *res)
 {
 	struct device_node *np;
 	struct stmmac_axi *axi;
 
+	/*
+	 * Exit early if the driver hasn't provided any defaults and the
+	 * device tree doesn't specify values for the AXI configuration.
+	 */
 	np = of_parse_phandle(pdev->dev.of_node, "snps,axi-config", 0);
-	if (!np)
+	if (!np && !res->axi)
 		return NULL;
 
 	axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
 	if (!axi) {
-		of_node_put(np);
+		if (np)
+			of_node_put(np);
+
 		return ERR_PTR(-ENOMEM);
 	}
 
-	axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
-	axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
-	axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
-	axi->axi_fb = of_property_read_bool(np, "snps,fb");
-	axi->axi_mb = of_property_read_bool(np, "snps,mb");
-	axi->axi_rb =  of_property_read_bool(np, "snps,rb");
+	/* copy defaults provided by the driver */
+	if (res->axi)
+		*axi = *res->axi;
+
+	/* override defaults with data from DT */
+	if (np) {
+		axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
+		axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
+		axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
+		axi->axi_fb = of_property_read_bool(np, "snps,fb");
+		axi->axi_mb = of_property_read_bool(np, "snps,mb");
+		axi->axi_rb =  of_property_read_bool(np, "snps,rb");
+
+		if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt)) {
+			if (!res->axi)
+				axi->axi_wr_osr_lmt = 1;
+		}
 
-	if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
-		axi->axi_wr_osr_lmt = 1;
-	if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt))
-		axi->axi_rd_osr_lmt = 1;
-	of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
-	of_node_put(np);
+		if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt)) {
+			if (!res->axi)
+				axi->axi_rd_osr_lmt = 1;
+		}
+
+		of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
+
+		of_node_put(np);
+	}
 
 	return axi;
 }
@@ -606,7 +629,7 @@ stmmac_probe_config_dt(struct platform_device *pdev,
 
 	of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed);
 
-	plat->axi = stmmac_axi_setup(pdev);
+	plat->axi = stmmac_axi_setup(pdev, res);
 
 	rc = stmmac_mtl_setup(pdev, plat);
 	if (rc) {

-- 
2.43.2



From thierry.reding at gmail.com  Mon Feb 19 08:46:06 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 19 Feb 2024 17:46:06 +0100
Subject: [PATCH net-next v3 3/3] net: stmmac: Configure AXI on Tegra234
 MGBE
In-Reply-To: <20240219-stmmac-axi-config-v3-0-fca7f046e6ee@nvidia.com>
References: <20240219-stmmac-axi-config-v3-0-fca7f046e6ee@nvidia.com>
Message-ID: <20240219-stmmac-axi-config-v3-3-fca7f046e6ee@nvidia.com>

From: Thierry Reding <treding at nvidia.com>

Allow the device to use bursts and increase the maximum number of
outstanding requests to improve performance. Measurements show an
increase in throughput of around 5x on a 1 Gbps link.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
index bab57d1675df..b6bfa48f279d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
@@ -199,6 +199,12 @@ static void mgbe_uphy_lane_bringup_serdes_down(struct net_device *ndev, void *mg
 	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 }
 
+static const struct stmmac_axi tegra234_mgbe_axi = {
+	.axi_wr_osr_lmt = 63,
+	.axi_rd_osr_lmt = 63,
+	.axi_blen = { 256, },
+};
+
 static int tegra_mgbe_probe(struct platform_device *pdev)
 {
 	struct plat_stmmacenet_data *plat;
@@ -284,6 +290,9 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
 	if (err < 0)
 		goto disable_clks;
 
+	/* setup default AXI configuration */
+	res.axi = &tegra234_mgbe_axi;
+
 	plat = devm_stmmac_probe_config_dt(pdev, &res);
 	if (IS_ERR(plat)) {
 		err = PTR_ERR(plat);

-- 
2.43.2



From catalin.marinas at arm.com  Mon Feb 19 08:48:26 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 19 Feb 2024 16:48:26 +0000
Subject: [PATCH] arm64: mm: Make PUD folding check in set_pud() a runtime check
In-Reply-To: <20240216235944.3677178-2-ardb+git@google.com>
References: <20240216235944.3677178-2-ardb+git@google.com>
Message-ID: <170836129861.475937.2295374467915367320.b4-ty@arm.com>

On Sat, 17 Feb 2024 00:59:44 +0100, Ard Biesheuvel wrote:
> When set_pud() is called on a 4-level paging build config that runs with
> 3 levels at runtime (which happens with 16k page size builds with
> support for LPA2), the updated entry is in fact a PGD in
> swapper_pg_dir[], and this is mapped read-only after boot.
> 
> So in this case, the existing check needs to be performed as well, even
> though __PAGETABLE_PUD_FOLDED is not #define'd. So replace the #ifdef
> with a call to pgtable_l4_enabled().
> 
> [...]

Applied to arm64 (for-next/stage1-lpa2), thanks!

[1/1] arm64: mm: Make PUD folding check in set_pud() a runtime check
      https://git.kernel.org/arm64/c/90e636f60b76

-- 
Catalin



From wsa+renesas at sang-engineering.com  Mon Feb 19 08:51:37 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Mon, 19 Feb 2024 17:51:37 +0100
Subject: [PATCH 1/2] arm64: dts: renesas: r8a779h0: Add RPC node
In-Reply-To: <26f9c5d5a7944db3813ed53459aa9c5767c1bdc0.1708354463.git.geert+renesas@glider.be>
References: <cover.1708354463.git.geert+renesas@glider.be>
 <26f9c5d5a7944db3813ed53459aa9c5767c1bdc0.1708354463.git.geert+renesas@glider.be>
Message-ID: <ZdOHGcqi2ZQ1xGI_@shikoro>

On Mon, Feb 19, 2024 at 04:00:40PM +0100, Geert Uytterhoeven wrote:
> From: Cong Dang <cong.dang.xn at renesas.com>
> 
> Add a device node for the SPI Multi I/O Bus Controller (RPC-IF) on the
> Renesas R-Car V4M (R8A779H0) SoC.
> 
> Signed-off-by: Cong Dang <cong.dang.xn at renesas.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

Reviewed-by: Wolfram Sang <wsa+renesas at sang-engineering.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/20240219/f937d98d/attachment.sig>

From wsa+renesas at sang-engineering.com  Mon Feb 19 08:53:19 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Mon, 19 Feb 2024 17:53:19 +0100
Subject: [PATCH 2/2] arm64: dts: renesas: gray-hawk-single: Add QSPI
 FLASH support
In-Reply-To: <96d6567024cef9fcd6b04f92a697301c1c8d1d8e.1708354463.git.geert+renesas@glider.be>
References: <cover.1708354463.git.geert+renesas@glider.be>
 <96d6567024cef9fcd6b04f92a697301c1c8d1d8e.1708354463.git.geert+renesas@glider.be>
Message-ID: <ZdOHf9ZQZWwQSkp4@shikoro>

On Mon, Feb 19, 2024 at 04:00:41PM +0100, Geert Uytterhoeven wrote:
> From: Cong Dang <cong.dang.xn at renesas.com>
> 
> Describe the QSPI FLASH on the Gray Hawk Single board.
> 
> Signed-off-by: Cong Dang <cong.dang.xn at renesas.com>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

Reviewed-by: Wolfram Sang <wsa+renesas at sang-engineering.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/20240219/11ce9593/attachment.sig>

From ardb at kernel.org  Mon Feb 19 08:57:07 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 19 Feb 2024 17:57:07 +0100
Subject: [PATCH 5.10.y v2] Revert "arm64: Stash shadow stack pointer in
 the task struct on interrupt"
In-Reply-To: <20240219132153.378265-1-xiangyang3@huawei.com>
References: <20240219132153.378265-1-xiangyang3@huawei.com>
Message-ID: <CAMj1kXFwTLJ77MYy3Pm+S9WGgkMw0hAGdTKOF05xdqqBg8giMw@mail.gmail.com>

On Mon, 19 Feb 2024 at 14:24, Xiang Yang <xiangyang3 at huawei.com> wrote:
>
> This reverts commit 3f225f29c69c13ce1cbdb1d607a42efeef080056.
>
> The shadow call stack for irq now is stored in current task's thread info
> in irq_stack_entry. There is a possibility that we have some soft irqs
> pending at the end of hard irq, and when we process softirq with the irq
> enabled, irq_stack_entry will enter again and overwrite the shadow call
> stack whitch stored in current task's thread info, leading to the
> incorrect shadow call stack restoration for the first entry of the hard
> IRQ, then the system end up with a panic.
>
> task A                               |  task A
> -------------------------------------+------------------------------------
> el1_irq        //irq1 enter          |
>   irq_handler  //save scs_sp1        |
>     gic_handle_irq                   |
>     irq_exit                         |
>       __do_softirq                   |
>                                      | el1_irq         //irq2 enter
>                                      |   irq_handler   //save scs_sp2
>                                      |                 //overwrite scs_sp1
>                                      |   ...
>                                      |   irq_stack_exit //restore scs_sp2
>   irq_stack_exit //restore wrong     |
>                  //scs_sp2           |
>
> So revert this commit to fix it.
>
> Fixes: 3f225f29c69c ("arm64: Stash shadow stack pointer in the task struct on interrupt")
>
> Signed-off-by: Xiang Yang <xiangyang3 at huawei.com>

Acked-by: Ard Biesheuvel <ardb at kernel.org>



> ---
>  arch/arm64/kernel/entry.S | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index a94acea770c7..020a455824be 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -431,7 +431,9 @@ SYM_CODE_END(__swpan_exit_el0)
>
>         .macro  irq_stack_entry
>         mov     x19, sp                 // preserve the original sp
> -       scs_save tsk                    // preserve the original shadow stack
> +#ifdef CONFIG_SHADOW_CALL_STACK
> +       mov     x24, scs_sp             // preserve the original shadow stack
> +#endif
>
>         /*
>          * Compare sp with the base of the task stack.
> @@ -465,7 +467,9 @@ SYM_CODE_END(__swpan_exit_el0)
>          */
>         .macro  irq_stack_exit
>         mov     sp, x19
> -       scs_load_current
> +#ifdef CONFIG_SHADOW_CALL_STACK
> +       mov     scs_sp, x24
> +#endif
>         .endm
>
>  /* GPRs used by entry code */
> --
> 2.34.1
>


From arnd at arndb.de  Mon Feb 19 09:06:19 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 19 Feb 2024 18:06:19 +0100
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <CAMj1kXHh_m=V0QsiTpHrUXpFBXFbFfezdysz8quhPSgUrZg1MA@mail.gmail.com>
References: <20240206074552.541154-1-maskray@google.com>
 <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>
 <CAMj1kXGaF5bobHTr1pTg+-=s4Ft7+5SSbX72-NxsR_W_Yuxb8Q@mail.gmail.com>
 <CAMj1kXGw+r7yEEBA8gYBcdrqkiP=VYOSzz9YLnNavJn2snmFwA@mail.gmail.com>
 <CAMuHMdX+6fnAf8Hm6EqYJPAjrrLO9T7c=Gu3S8V_pqjSDowJ6g@mail.gmail.com>
 <CAMj1kXHh_m=V0QsiTpHrUXpFBXFbFfezdysz8quhPSgUrZg1MA@mail.gmail.com>
Message-ID: <dca5b082-90d1-40ab-954f-8b3b6f51138c@app.fastmail.com>

On Mon, Feb 19, 2024, at 16:41, Ard Biesheuvel wrote:
> On Mon, 19 Feb 2024 at 15:43, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>> On Mon, Feb 19, 2024 at 11:57?AM Ard Biesheuvel <ardb at kernel.org> wrote:
>> > On Mon, 19 Feb 2024 at 11:56, Ard Biesheuvel <ardb at kernel.org> wrote:

>> > https://godbolt.org/z/GTnf3vPaT
>>
>> I could reproduce the issue on v6.8-rc5 using arm64 defconfig
>> and x86_64-gcc-5.5.0-nolibc-aarch64-linux.tar.xz from
>> https://cdn.kernel.org/pub/tools/crosstool/files/bin/x86_64/5.5.0/:
>>
>
> OK, I managed to do so as well.
>
> And GCC 6.4 from the same source works correctly.
>
> Not sure whether there are any plans to bump the minimal GCC version
> any time soon (cc'ing Arnd), but we should probably drop this change
> until that happens.

>From what I can tell, we may as well formally raise the minimum
gcc version to 8.1+ already, as that is a version that is
actually used in distros, and we have been on 5.1+ for a few
years already.

Not sure if there are any other benefits to gcc-8 besides
allowing minor cleanups.

gcc-9 would bring --std=gnu2x support, but it may be too
early for that.

      Arnd


From neil.armstrong at linaro.org  Mon Feb 19 09:18:28 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Mon, 19 Feb 2024 18:18:28 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org>
 <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org>
 <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
 <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
 <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com>
Message-ID: <b9a31374-8ea9-407e-9ec3-008a95e2b18b@linaro.org>

On 19/02/2024 13:33, Dmitry Baryshkov wrote:
> On Mon, 19 Feb 2024 at 14:23, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>>
>> On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
>> <dmitry.baryshkov at linaro.org> wrote:
>>>
>>
>> [snip]
>>
>>>>>>>>
>>>>>>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
>>>>>>>> necessary. The BT and WLAN devices on the device-tree are represented as
>>>>>>>> consuming the inputs (relevant to the functionality of each) of the PMU
>>>>>>>> directly.
>>>>>>>
>>>>>>> We are describing the hardware. From the hardware point of view, there
>>>>>>> is a PMU. I think at some point we would really like to describe all
>>>>>>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
>>>>>>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
>>>>>>
>>>>>> While I agree with older WiFi+BT units, I don't think it's needed for
>>>>>> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
>>>>>> transparent.
>>>>>
>>>>> I don't see any significant difference between WCN6750/WCN6855 and
>>>>> WCN7850 from the PMU / power up point of view. Could you please point
>>>>> me to the difference?
>>>>>
>>>>
>>>> The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
>>>> and BT_EN ordering and the only requirement is to have all input regulators
>>>> up before pulling up WLAN_EN and/or BT_EN.
>>>>
>>>> This makes the PMU transparent and BT and WLAN can be described as independent.
>>>
>>>  From the hardware perspective, there is a PMU. It has several LDOs. So
>>> the device tree should have the same style as the previous
>>> generations.
>>>
>>
>> My thinking was this: yes, there is a PMU but describing it has no
>> benefit (unlike QCA6x90). If we do describe, then we'll end up having
>> to use pwrseq here despite it not being needed because now we won't be
>> able to just get regulators from WLAN/BT drivers directly.
>>
>> So I also vote for keeping it this way. Let's go into the package
>> detail only if it's required.
> 
> The WiFi / BT parts are not powered up by the board regulators. They
> are powered up by the PSU. So we are not describing it in the accurate
> way.

I disagree, the WCN7850 can also be used as a discrete PCIe M.2 card, and in
this situation the PCIe part is powered with the M.2 slot and the BT side
is powered separately as we currently do it now.

So yes there's a PMU, but it's not an always visible hardware part, from the
SoC PoV, only the separate PCIe and BT subsystems are visible/controllable/powerable.

Neil

> 
> Moreover, I think we definitely want to move BT driver to use only the
> pwrseq power up method. Doing it in the other way results in the code
> duplication and possible issues because of the regulator / pwrseq
> taking different code paths.
> 
> 



From lpieralisi at kernel.org  Mon Feb 19 09:29:10 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Mon, 19 Feb 2024 18:29:10 +0100
Subject: [PATCH] firmware/psci: Move psci_init_system_suspend() to
 late_initcall()
In-Reply-To: <20240219-suspend_ops_late_init-v1-1-6330ca9597fa@quicinc.com>
References: <20240219-suspend_ops_late_init-v1-1-6330ca9597fa@quicinc.com>
Message-ID: <ZdOP5oAwZvEhNAsn@lpieralisi>

On Mon, Feb 19, 2024 at 03:02:04PM +0530, Maulik Shah wrote:
> psci_init_system_suspend() invokes suspend_set_ops() very early during
> bootup even before kernel command line for mem_sleep_default is setup.
> This leads to kernel command line mem_sleep_default=s2idle not working
> as mem_sleep_current gets changed to deep via suspend_set_ops() and never
> changes back to s2idle.
> 
> Move psci_init_system_suspend() to late_initcall() to make sure kernel
> command line mem_sleep_default=s2idle sets up s2idle as default suspend
> mode.

Why can't we fix it the other way around, namely enforce
mem_sleep_current according to the mem_sleep_default command line
even if suspend_set_ops() was already called ?

Just asking, I am not super keen on using initcalls ordering, it
looks fragile to me.

Thanks,
Lorenzo

> Fixes: faf7ec4a92c0 ("drivers: firmware: psci: add system suspend support")
> CC: stable at vger.kernel.org # 5.15+
> Signed-off-by: Maulik Shah <quic_mkshah at quicinc.com>
> ---
>  drivers/firmware/psci/psci.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
> index d9629ff87861..655a2db70a67 100644
> --- a/drivers/firmware/psci/psci.c
> +++ b/drivers/firmware/psci/psci.c
> @@ -523,18 +523,26 @@ static void __init psci_init_system_reset2(void)
>  		psci_system_reset2_supported = true;
>  }
>  
> -static void __init psci_init_system_suspend(void)
> +static int __init psci_init_system_suspend(void)
>  {
>  	int ret;
> +	u32 ver;
>  
>  	if (!IS_ENABLED(CONFIG_SUSPEND))
> -		return;
> +		return 0;
> +
> +	ver = psci_0_2_get_version();
> +	if (PSCI_VERSION_MAJOR(ver) < 1)
> +		return 0;
>  
>  	ret = psci_features(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND));
>  
>  	if (ret != PSCI_RET_NOT_SUPPORTED)
>  		suspend_set_ops(&psci_suspend_ops);
> +
> +	return ret;
>  }
> +late_initcall(psci_init_system_suspend)
>  
>  static void __init psci_init_cpu_suspend(void)
>  {
> @@ -651,7 +659,6 @@ static int __init psci_probe(void)
>  	if (PSCI_VERSION_MAJOR(ver) >= 1) {
>  		psci_init_smccc();
>  		psci_init_cpu_suspend();
> -		psci_init_system_suspend();
>  		psci_init_system_reset2();
>  		kvm_init_hyp_services();
>  	}
> 
> ---
> base-commit: d37e1e4c52bc60578969f391fb81f947c3e83118
> change-id: 20240219-suspend_ops_late_init-27fb0b15baee
> 
> Best regards,
> -- 
> Maulik Shah <quic_mkshah at quicinc.com>
> 


From oliver.upton at linux.dev  Mon Feb 19 09:34:35 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 19 Feb 2024 17:34:35 +0000
Subject: [PATCH v4 00/26] KVM/arm64: VM configuration enforcement
In-Reply-To: <20240214131827.2856277-1-maz@kernel.org>
References: <20240214131827.2856277-1-maz@kernel.org>
Message-ID: <170836405332.123390.1336178415163026364.b4-ty@linux.dev>

On Wed, 14 Feb 2024 13:18:01 +0000, Marc Zyngier wrote:
> This is the fourth version of this configurationm enforcement series
> after additional reviewing from Suzuki and Oliver. Many thanks to
> both.
> 
> I think I have taken most of the feedback into account, but please
> shout if I have ignored something.
> 
> [...]

Applied to kvmarm/next, thanks!

[01/26] arm64: sysreg: Add missing ID_AA64ISAR[13]_EL1 fields and variants
        https://git.kernel.org/kvmarm/kvmarm/c/aeddd5b214c8
[02/26] KVM: arm64: Add feature checking helpers
        https://git.kernel.org/kvmarm/kvmarm/c/c62d7a23b947
[03/26] KVM: arm64: nv: Add sanitising to VNCR-backed sysregs
        https://git.kernel.org/kvmarm/kvmarm/c/888f08807022
[04/26] KVM: arm64: nv: Add sanitising to EL2 configuration registers
        https://git.kernel.org/kvmarm/kvmarm/c/81ffcace31c2
[05/26] KVM: arm64: nv: Add sanitising to VNCR-backed FGT sysregs
        https://git.kernel.org/kvmarm/kvmarm/c/11adda4010ba
[06/26] KVM: arm64: nv: Add sanitising to VNCR-backed HCRX_EL2
        https://git.kernel.org/kvmarm/kvmarm/c/d39051d39269
[07/26] KVM: arm64: nv: Drop sanitised_sys_reg() helper
        https://git.kernel.org/kvmarm/kvmarm/c/76b457a5cdea
[08/26] KVM: arm64: Unify HDFG[WR]TR_GROUP FGT identifiers
        https://git.kernel.org/kvmarm/kvmarm/c/0beb14de740d
[09/26] KVM: arm64: nv: Correctly handle negative polarity FGTs
        https://git.kernel.org/kvmarm/kvmarm/c/9958d58779c9
[10/26] KVM: arm64: nv: Turn encoding ranges into discrete XArray stores
        https://git.kernel.org/kvmarm/kvmarm/c/fdd8e3452359
[11/26] KVM: arm64: Drop the requirement for XARRAY_MULTI
        https://git.kernel.org/kvmarm/kvmarm/c/52571d058b07
[12/26] KVM: arm64: nv: Move system instructions to their own sys_reg_desc array
        https://git.kernel.org/kvmarm/kvmarm/c/89bc63fabc8a
[13/26] KVM: arm64: Always populate the trap configuration xarray
        https://git.kernel.org/kvmarm/kvmarm/c/7fd498f473f1
[14/26] KVM: arm64: Register AArch64 system register entries with the sysreg xarray
        https://git.kernel.org/kvmarm/kvmarm/c/19f3e7ea29f8
[15/26] KVM: arm64: Use the xarray as the primary sysreg/sysinsn walker
        https://git.kernel.org/kvmarm/kvmarm/c/cc5f84fbb008
[16/26] KVM: arm64: Rename __check_nv_sr_forward() to triage_sysreg_trap()
        https://git.kernel.org/kvmarm/kvmarm/c/085eabaa74a1
[17/26] KVM: arm64: Add Fine-Grained UNDEF tracking information
        https://git.kernel.org/kvmarm/kvmarm/c/2fd8f31c32f0
[18/26] KVM: arm64: Propagate and handle Fine-Grained UNDEF bits
        https://git.kernel.org/kvmarm/kvmarm/c/f5a5a406b4b8
[19/26] KVM: arm64: Move existing feature disabling over to FGU infrastructure
        https://git.kernel.org/kvmarm/kvmarm/c/c5bac1ef7df6
[20/26] KVM: arm64: Streamline save/restore of HFG[RW]TR_EL2
        https://git.kernel.org/kvmarm/kvmarm/c/d196c20c6e58
[21/26] KVM: arm64: Make TLBI OS/Range UNDEF if not advertised to the guest
        https://git.kernel.org/kvmarm/kvmarm/c/8ecdccb9e5db
[22/26] KVM: arm64: Make PIR{,E0}_EL1 UNDEF if S1PIE is not advertised to the guest
        https://git.kernel.org/kvmarm/kvmarm/c/58627b722ee2
[23/26] KVM: arm64: Make AMU sysreg UNDEF if FEAT_AMU is not advertised to the guest
        https://git.kernel.org/kvmarm/kvmarm/c/b03e8bb5a906
[24/26] KVM: arm64: Make FEAT_MOPS UNDEF if not advertised to the guest
        https://git.kernel.org/kvmarm/kvmarm/c/84de212d739e
[25/26] KVM: arm64: Snapshot all non-zero RES0/RES1 sysreg fields for later checking
        https://git.kernel.org/kvmarm/kvmarm/c/b80b701d5a67
[26/26] KVM: arm64: Add debugfs file for guest's ID registers
        https://git.kernel.org/kvmarm/kvmarm/c/891766581dea

--
Best,
Oliver


From dmitry.baryshkov at linaro.org  Mon Feb 19 09:41:37 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 19:41:37 +0200
Subject: [PATCH] irqchip/gic-v3: handle DOMAIN_BUS_ANY in gic_irq_domain_select
In-Reply-To: <865xyk4dgf.wl-maz@kernel.org>
References: <20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f@linaro.org>
 <868r3g4fhv.wl-maz@kernel.org> <CAA8EJpqiN6oRMWhAMMP6EsAeki5KSMbO+XzEtT9YRdJKc9_Gbg@mail.gmail.com>
 <865xyk4dgf.wl-maz@kernel.org>
Message-ID: <CAA8EJprKUOMwrwawiQ51WKiLCipm72ZcpY6q520kSOg--9oKZg@mail.gmail.com>

On Mon, 19 Feb 2024 at 18:37, Marc Zyngier <maz at kernel.org> wrote:
>
> On Mon, 19 Feb 2024 16:21:06 +0000,
> Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> >
> > On Mon, 19 Feb 2024 at 17:53, Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > On Mon, 19 Feb 2024 14:47:37 +0000,
> > > Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> > > >
> > > > Before the commit de1ff306dcf4 ("genirq/irqdomain: Remove the param
> > > > count restriction from select()") the irq_find_matching_fwspec() was
> > > > handling the DOMAIN_BUS_ANY on its own. After this commit it is a job of
> > > > the select() callback. However the callback of GICv3 (even though it got
> > > > modified to handle zero param_count) wasn't prepared to return true for
> > > > DOMAIN_BUS_ANY bus_token.
> > > >
> > > > This breaks probing of any of the child IRQ domains, since
> > > > platform_irqchip_probe() uses irq_find_matching_host(par_np,
> > > > DOMAIN_BUS_ANY) to check for the presence of the parent IRQ domain.
> > > >
> > > > Fixes: 151378251004 ("irqchip/gic-v3: Make gic_irq_domain_select() robust for zero parameter count")
> > > > Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from select()")
> > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > > > ---
> > > >  drivers/irqchip/irq-gic-v3.c | 3 ++-
> > > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > > > index 6fb276504bcc..e9e9643c653f 100644
> > > > --- a/drivers/irqchip/irq-gic-v3.c
> > > > +++ b/drivers/irqchip/irq-gic-v3.c
> > > > @@ -1696,7 +1696,8 @@ static int gic_irq_domain_select(struct irq_domain *d,
> > > >
> > > >       /* Handle pure domain searches */
> > > >       if (!fwspec->param_count)
> > > > -             return d->bus_token == bus_token;
> > > > +             return d->bus_token == bus_token ||
> > > > +                     bus_token == DOMAIN_BUS_ANY;
> > > >
> > > >       /* If this is not DT, then we have a single domain */
> > > >       if (!is_of_node(fwspec->fwnode))
> > > >
> > >
> > > I really dislike the look of this. If that's the case, any irqchip
> > > that has a 'select' method (such as imx-intmux) should be similarly
> > > hacked. And at this point, this should be handled by the core code.
> > >
> > > Can you try this instead? I don't have any HW that relies on
> > > behaviour, but I'd expect this to work.
> > >
> > > Thanks,
> > >
> > >         M.
> > >
> > > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> > > index aeb41655d6de..3dd1c871e091 100644
> > > --- a/kernel/irq/irqdomain.c
> > > +++ b/kernel/irq/irqdomain.c
> > > @@ -449,7 +449,7 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
> > >          */
> > >         mutex_lock(&irq_domain_mutex);
> > >         list_for_each_entry(h, &irq_domain_list, link) {
> > > -               if (h->ops->select)
> > > +               if (h->ops->select && bus_token != DOMAIN_BUS_ANY)
> > >                         rc = h->ops->select(h, fwspec, bus_token);
> > >                 else if (h->ops->match)
> > >                         rc = h->ops->match(h, to_of_node(fwnode), bus_token);
> >
> > This works. But I wonder if the following change is even better. WDYT?
> >
> > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> > index aeb41655d6de..2f0d2700709e 100644
> > --- a/kernel/irq/irqdomain.c
> > +++ b/kernel/irq/irqdomain.c
> > @@ -449,14 +449,17 @@ struct irq_domain
> > *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
> >          */
> >         mutex_lock(&irq_domain_mutex);
> >         list_for_each_entry(h, &irq_domain_list, link) {
> > -               if (h->ops->select)
> > +               if (fwnode != NULL &&
> > +                   h->fwnode == fwnode &&
> > +                   bus_token == DOMAIN_BUS_ANY)
> > +                       rc = true;
> > +               else if (h->ops->select)
> >                         rc = h->ops->select(h, fwspec, bus_token);
> >                 else if (h->ops->match)
> >                         rc = h->ops->match(h, to_of_node(fwnode), bus_token);
> >                 else
> >                         rc = ((fwnode != NULL) && (h->fwnode == fwnode) &&
> > -                             ((bus_token == DOMAIN_BUS_ANY) ||
> > -                              (h->bus_token == bus_token)));
> > +                             (h->bus_token == bus_token));
> >
> >                 if (rc) {
> >                         found = h;
> >
>
> Can't say I like it either. It duplicates the existing check without
> any obvious benefit. Honestly, this code is shit enough that we should
> try to make it simpler, not more complex...

Only the fwnode conditions are duplicated. And it makes sense: we
should check for the DOMAIN_BUS_ANY first, before going to select. I'm
not sure whether at some point we'd have to add (&& bus_token !=
DOMAIN_BUS_ANY) to the ops->match check.

>
> I'd rather we keep the impact as minimal as possible, and use the
> upcoming weeks to weed out the effects of these changes (there is
> another report of some Renesas machine falling over itself here[1]).
>
> Thanks,
>
>         M.
>
> [1] https://lore.kernel.org/all/170802702416.398.14922976721740218856.tip-bot2 at tip-bot2
>
> --
> Without deviation from the norm, progress is not possible.



-- 
With best wishes
Dmitry


From tanmay.shah at amd.com  Mon Feb 19 09:44:28 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 09:44:28 -0800
Subject: [PATCH v11 0/4] add zynqmp TCM bindings
Message-ID: <20240219174437.3722620-1-tanmay.shah@amd.com>

Tightly-Coupled Memories(TCMs) are low-latency memory that provides
predictable instruction execution and predictable data load/store
timing. Each Cortex-R5F processor contains exclusive two 64 KB memory
banks on the ATCM and BTCM ports, for a total of 128 KB of memory.
In lockstep mode, both 128KB memory is accessible to the cluster.

As per ZynqMP Ultrascale+ Technical Reference Manual UG1085, following
is address space of TCM memory. The bindings in this patch series
introduces properties to accommodate following address space with
address translation between Linux and Cortex-R5 views.

|     |     |     |
| --- | --- | --- |
|      *Mode*        |   *R5 View* | *Linux view* |  Notes               |
| *Split Mode*       | *start addr*| *start addr* |                      |
| R5_0 ATCM (64 KB)  | 0x0000_0000 | 0xFFE0_0000  |                      |
| R5_0 BTCM (64 KB)  | 0x0002_0000 | 0xFFE2_0000  |                      |
| R5_1 ATCM (64 KB)  | 0x0000_0000 | 0xFFE9_0000  | alias of 0xFFE1_0000 |
| R5_1 BTCM (64 KB)  | 0x0002_0000 | 0xFFEB_0000  | alias of 0xFFE3_0000 |
|  ___               |     ___     |    ___       |                      |
| *Lockstep Mode*    |             |              |                      |
| R5_0 ATCM (128 KB) | 0x0000_0000 | 0xFFE0_0000  |                      |
| R5_0 BTCM (128 KB) | 0x0002_0000 | 0xFFE2_0000  |                      |

References:
UG1085 TCM address space:
https://docs.xilinx.com/r/en-US/ug1085-zynq-ultrascale-trm/Tightly-Coupled-Memory-Address-Map

Changes in v11:
  - Fix yamllint warning and reduce indentation as needed
  - Remove redundant initialization of the variable
  - Return correct error code if memory allocation failed

Changs in v10:
  - Add new patch (1/4) to series that changes hardcode TCM addresses in
    lockstep mode and removes separate handling of TCM in lockstep and
    split mode
  - modify number of "reg", "reg-names" and "power-domains" entries
    based on cluster mode
  - Add extra optional atcm and btcm in "reg" property for lockstep mode
  - Add "reg-names" for extra optional atcm and btcm for lockstep mode
  - Drop previous Ack as bindings has new change
  - Add individual tcm regions via "reg" and "reg-names" for lockstep mode
  - Add each tcm's power-domains in lockstep mode
  - Drop previous Ack as new change in dts patchset
  - Remove redundant changes in driver to handle TCM in lockstep mode

Changes in v9:
  - Fix rproc lockstep dts
  - Introduce new API to request and release core1 TCM power-domains in
    lockstep mode. This will be used during prepare -> add_tcm_banks
    callback to enable TCM in lockstep mode.
  - Parse TCM from device-tree in lockstep mode and split mode in
    uniform way.
  - Fix TCM representation in device-tree in lockstep mode.
  - Fix comments as suggested

Changes in v8:
  - Remove use of pm_domains framework
  - Remove checking of pm_domain_id validation to power on/off tcm
  - Remove spurious change
  - parse power-domains property from device-tree and use EEMI calls
    to power on/off TCM instead of using pm domains framework

Changes in v7:
  - %s/pm_dev1/pm_dev_core0/r
  - %s/pm_dev_link1/pm_dev_core0_link/r
  - %s/pm_dev2/pm_dev_core1/r
  - %s/pm_dev_link2/pm_dev_core1_link/r
  - remove pm_domain_id check to move next patch
  - add comment about how 1st entry in pm domain list is used
  - fix loop when jump to fail_add_pm_domains loop
  - move checking of pm_domain_id from previous patch
  - fix mem_bank_data memory allocation

Changes in v6:
  - Introduce new node entry for r5f cluster split mode dts and
    keep it disabled by default.
  - Keep remoteproc lockstep mode enabled by default to maintian
    back compatibility.
  - Enable split mode only for zcu102 board to demo split mode use
  - Remove spurious change
  - Handle errors in add_pm_domains function
  - Remove redundant code to handle errors from remove_pm_domains
  - Missing . at the end of the commit message
  - remove redundant initialization of variables
  - remove fail_tcm label and relevant code to free memory
    acquired using devm_* API. As this will be freed when device free it
  - add extra check to see if "reg" property is supported or not

Changes in v5:
  - maintain Rob's Ack on bindings patch as no changes in bindings
  - split previous patch into multiple patches
  - Use pm domain framework to turn on/off TCM
  - Add support of parsing TCM information from device-tree
  - maintain backward compatibility with previous bindings without
    TCM information available in device-tree

This patch series continues previous effort to upstream ZynqMP
TCM bindings:
Previous v4 version link:
https://lore.kernel.org/all/20230829181900.2561194-1-tanmay.shah at amd.com/

Previous v3 version link:
https://lore.kernel.org/all/1689964908-22371-1-git-send-email-radhey.shyam.pandey at amd.com/
Radhey Shyam Pandey (1):
  dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings



Radhey Shyam Pandey (1):
  dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings

Tanmay Shah (3):
  remoteproc: zynqmp: fix lockstep mode memory region
  dts: zynqmp: add properties for TCM in remoteproc
  remoteproc: zynqmp: parse TCM from device tree

 .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 +++++++++++--
 .../boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts  |   8 +
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  65 ++++-
 drivers/remoteproc/xlnx_r5_remoteproc.c       | 257 ++++++++----------
 4 files changed, 357 insertions(+), 165 deletions(-)


base-commit: 929654e8f1add50b01d5a56171a31c311b0a739a
-- 
2.25.1



From tanmay.shah at amd.com  Mon Feb 19 09:44:30 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 09:44:30 -0800
Subject: [PATCH v11 2/4] dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings
In-Reply-To: <20240219174437.3722620-1-tanmay.shah@amd.com>
References: <20240219174437.3722620-1-tanmay.shah@amd.com>
Message-ID: <20240219174437.3722620-3-tanmay.shah@amd.com>

From: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>

Introduce bindings for TCM memory address space on AMD-xilinx Zynq
UltraScale+ platform. It will help in defining TCM in device-tree
and make it's access platform agnostic and data-driven.

Tightly-coupled memories(TCMs) are low-latency memory that provides
predictable instruction execution and predictable data load/store
timing. Each Cortex-R5F processor contains two 64-bit wide 64 KB memory
banks on the ATCM and BTCM ports, for a total of 128 KB of memory.

The TCM resources(reg, reg-names and power-domain) are documented for
each TCM in the R5 node. The reg and reg-names are made as required
properties as we don't want to hardcode TCM addresses for future
platforms and for zu+ legacy implementation will ensure that the
old dts w/o reg/reg-names works and stable ABI is maintained.

It also extends the examples for TCM split and lockstep modes.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---

Changes in v11:
  - Fix yamllint warning and reduce indentation as needed

 .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 ++++++++++++++++--
 1 file changed, 170 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml b/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
index 78aac69f1060..77030edf41fa 100644
--- a/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
@@ -20,9 +20,21 @@ properties:
   compatible:
     const: xlnx,zynqmp-r5fss
 
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 2
+
+  ranges:
+    description: |
+      Standard ranges definition providing address translations for
+      local R5F TCM address spaces to bus addresses.
+
   xlnx,cluster-mode:
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [0, 1, 2]
+    default: 1
     description: |
       The RPU MPCore can operate in split mode (Dual-processor performance), Safety
       lock-step mode(Both RPU cores execute the same code in lock-step,
@@ -37,7 +49,7 @@ properties:
       2: single cpu mode
 
 patternProperties:
-  "^r5f-[a-f0-9]+$":
+  "^r5f@[0-9a-f]+$":
     type: object
     description: |
       The RPU is located in the Low Power Domain of the Processor Subsystem.
@@ -54,9 +66,6 @@ patternProperties:
       compatible:
         const: xlnx,zynqmp-r5f
 
-      power-domains:
-        maxItems: 1
-
       mboxes:
         minItems: 1
         items:
@@ -101,35 +110,174 @@ patternProperties:
 
     required:
       - compatible
-      - power-domains
 
-    unevaluatedProperties: false
+allOf:
+  - if:
+      properties:
+        xlnx,cluster-mode:
+          enum:
+            - 1
+    then:
+      patternProperties:
+        "^r5f@[0-9a-f]+$":
+          type: object
+
+          properties:
+            reg:
+              minItems: 1
+              items:
+                - description: ATCM internal memory
+                - description: BTCM internal memory
+                - description: extra ATCM memory in lockstep mode
+                - description: extra BTCM memory in lockstep mode
+
+            reg-names:
+              minItems: 1
+              items:
+                - const: atcm0
+                - const: btcm0
+                - const: atcm1
+                - const: btcm1
+
+            power-domains:
+              minItems: 2
+              maxItems: 5
+
+          required:
+            - reg
+            - reg-names
+            - power-domains
+
+    else:
+      patternProperties:
+        "^r5f@[0-9a-f]+$":
+          type: object
+
+          properties:
+            reg:
+              minItems: 1
+              items:
+                - description: ATCM internal memory
+                - description: BTCM internal memory
+
+            reg-names:
+              minItems: 1
+              items:
+                - const: atcm0
+                - const: btcm0
+
+            power-domains:
+              minItems: 2
+              maxItems: 3
+
+          required:
+            - reg
+            - reg-names
+            - power-domains
 
 required:
   - compatible
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
 
 additionalProperties: false
 
 examples:
   - |
-    remoteproc {
-        compatible = "xlnx,zynqmp-r5fss";
-        xlnx,cluster-mode = <1>;
-
-        r5f-0 {
-            compatible = "xlnx,zynqmp-r5f";
-            power-domains = <&zynqmp_firmware 0x7>;
-            memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
-            mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
-            mbox-names = "tx", "rx";
+    #include <dt-bindings/power/xlnx-zynqmp-power.h>
+
+    // Split mode configuration
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        remoteproc at ffe00000 {
+            compatible = "xlnx,zynqmp-r5fss";
+            xlnx,cluster-mode = <0>;
+
+            #address-cells = <2>;
+            #size-cells = <2>;
+            ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+                     <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+                     <0x1 0x0 0x0 0xffe90000 0x0 0x10000>,
+                     <0x1 0x20000 0x0 0xffeb0000 0x0 0x10000>;
+
+            r5f at 0 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x0 0x0 0x0 0x10000>, <0x0 0x20000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0";
+                power-domains = <&zynqmp_firmware PD_RPU_0>,
+                                <&zynqmp_firmware PD_R5_0_ATCM>,
+                                <&zynqmp_firmware PD_R5_0_BTCM>;
+                memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>,
+                                <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
+                mbox-names = "tx", "rx";
+            };
+
+            r5f at 1 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0";
+                power-domains = <&zynqmp_firmware PD_RPU_1>,
+                                <&zynqmp_firmware PD_R5_1_ATCM>,
+                                <&zynqmp_firmware PD_R5_1_BTCM>;
+                memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>,
+                                <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
+                mbox-names = "tx", "rx";
+            };
         };
+    };
+
+  - |
+    //Lockstep configuration
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        remoteproc at ffe00000 {
+            compatible = "xlnx,zynqmp-r5fss";
+            xlnx,cluster-mode = <1>;
+
+            #address-cells = <2>;
+            #size-cells = <2>;
+            ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+                     <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+                     <0x0 0x10000 0x0 0xffe10000 0x0 0x10000>,
+                     <0x0 0x30000 0x0 0xffe30000 0x0 0x10000>;
+
+            r5f at 0 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x0 0x0 0x0 0x10000>,
+                      <0x0 0x20000 0x0 0x10000>,
+                      <0x0 0x10000 0x0 0x10000>,
+                      <0x0 0x30000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0", "atcm1", "btcm1";
+                power-domains = <&zynqmp_firmware PD_RPU_0>,
+                                <&zynqmp_firmware PD_R5_0_ATCM>,
+                                <&zynqmp_firmware PD_R5_0_BTCM>,
+                                <&zynqmp_firmware PD_R5_1_ATCM>,
+                                <&zynqmp_firmware PD_R5_1_BTCM>;
+                memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>,
+                                <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
+                mbox-names = "tx", "rx";
+            };
 
-        r5f-1 {
-            compatible = "xlnx,zynqmp-r5f";
-            power-domains = <&zynqmp_firmware 0x8>;
-            memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
-            mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
-            mbox-names = "tx", "rx";
+            r5f at 1 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0";
+                power-domains = <&zynqmp_firmware PD_RPU_1>,
+                                <&zynqmp_firmware PD_R5_1_ATCM>,
+                                <&zynqmp_firmware PD_R5_1_BTCM>;
+                memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>,
+                                <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
+                mbox-names = "tx", "rx";
+            };
         };
     };
 ...
-- 
2.25.1



From tanmay.shah at amd.com  Mon Feb 19 09:44:29 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 09:44:29 -0800
Subject: [PATCH v11 1/4] remoteproc: zynqmp: fix lockstep mode memory region
In-Reply-To: <20240219174437.3722620-1-tanmay.shah@amd.com>
References: <20240219174437.3722620-1-tanmay.shah@amd.com>
Message-ID: <20240219174437.3722620-2-tanmay.shah@amd.com>

In lockstep mode, r5 core0 uses TCM of R5 core1. Following is lockstep
mode memory region as per hardware reference manual.

    |      *TCM*         |   *R5 View* | *Linux view* |
    | R5_0 ATCM (128 KB) | 0x0000_0000 | 0xFFE0_0000  |
    | R5_0 BTCM (128 KB) | 0x0002_0000 | 0xFFE2_0000  |

However, driver shouldn't model it as above because R5 core0 TCM and core1
TCM has different power-domains mapped to it.
Hence, TCM address space in lockstep mode should be modeled as 64KB
regions only where each region has its own power-domain as following:

    |      *TCM*         |   *R5 View* | *Linux view* |
    | R5_0 ATCM0 (64 KB) | 0x0000_0000 | 0xFFE0_0000  |
    | R5_0 BTCM0 (64 KB) | 0x0002_0000 | 0xFFE2_0000  |
    | R5_0 ATCM1 (64 KB) | 0x0001_0000 | 0xFFE1_0000  |
    | R5_0 BTCM1 (64 KB) | 0x0003_0000 | 0xFFE3_0000  |

This makes driver maintanance easy and makes design robust for future
platorms as well.

Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---
 drivers/remoteproc/xlnx_r5_remoteproc.c | 145 ++----------------------
 1 file changed, 12 insertions(+), 133 deletions(-)

diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index 4395edea9a64..42b0384d34f2 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -84,12 +84,12 @@ static const struct mem_bank_data zynqmp_tcm_banks_split[] = {
 	{0xffeb0000UL, 0x20000, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
 };
 
-/* In lockstep mode cluster combines each 64KB TCM and makes 128KB TCM */
+/* In lockstep mode cluster uses each 64KB TCM from second core as well */
 static const struct mem_bank_data zynqmp_tcm_banks_lockstep[] = {
-	{0xffe00000UL, 0x0, 0x20000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 128KB each */
-	{0xffe20000UL, 0x20000, 0x20000UL, PD_R5_0_BTCM, "btcm0"},
-	{0, 0, 0, PD_R5_1_ATCM, ""},
-	{0, 0, 0, PD_R5_1_BTCM, ""},
+	{0xffe00000UL, 0x0, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
+	{0xffe20000UL, 0x20000, 0x10000UL, PD_R5_0_BTCM, "btcm0"},
+	{0xffe10000UL, 0x10000, 0x10000UL, PD_R5_1_ATCM, "atcm1"},
+	{0xffe30000UL, 0x30000, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
 };
 
 /**
@@ -540,14 +540,14 @@ static int tcm_mem_map(struct rproc *rproc,
 }
 
 /*
- * add_tcm_carveout_split_mode()
+ * add_tcm_banks()
  * @rproc: single R5 core's corresponding rproc instance
  *
- * allocate and add remoteproc carveout for TCM memory in split mode
+ * allocate and add remoteproc carveout for TCM memory
  *
  * return 0 on success, otherwise non-zero value on failure
  */
-static int add_tcm_carveout_split_mode(struct rproc *rproc)
+static int add_tcm_banks(struct rproc *rproc)
 {
 	struct rproc_mem_entry *rproc_mem;
 	struct zynqmp_r5_core *r5_core;
@@ -580,10 +580,10 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 					     ZYNQMP_PM_REQUEST_ACK_BLOCKING);
 		if (ret < 0) {
 			dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
-			goto release_tcm_split;
+			goto release_tcm;
 		}
 
-		dev_dbg(dev, "TCM carveout split mode %s addr=%llx, da=0x%x, size=0x%lx",
+		dev_dbg(dev, "TCM carveout %s addr=%llx, da=0x%x, size=0x%lx",
 			bank_name, bank_addr, da, bank_size);
 
 		rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
@@ -593,7 +593,7 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 		if (!rproc_mem) {
 			ret = -ENOMEM;
 			zynqmp_pm_release_node(pm_domain_id);
-			goto release_tcm_split;
+			goto release_tcm;
 		}
 
 		rproc_add_carveout(rproc, rproc_mem);
@@ -601,7 +601,7 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 
 	return 0;
 
-release_tcm_split:
+release_tcm:
 	/* If failed, Turn off all TCM banks turned on before */
 	for (i--; i >= 0; i--) {
 		pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
@@ -610,127 +610,6 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 	return ret;
 }
 
-/*
- * add_tcm_carveout_lockstep_mode()
- * @rproc: single R5 core's corresponding rproc instance
- *
- * allocate and add remoteproc carveout for TCM memory in lockstep mode
- *
- * return 0 on success, otherwise non-zero value on failure
- */
-static int add_tcm_carveout_lockstep_mode(struct rproc *rproc)
-{
-	struct rproc_mem_entry *rproc_mem;
-	struct zynqmp_r5_core *r5_core;
-	int i, num_banks, ret;
-	phys_addr_t bank_addr;
-	size_t bank_size = 0;
-	struct device *dev;
-	u32 pm_domain_id;
-	char *bank_name;
-	u32 da;
-
-	r5_core = rproc->priv;
-	dev = r5_core->dev;
-
-	/* Go through zynqmp banks for r5 node */
-	num_banks = r5_core->tcm_bank_count;
-
-	/*
-	 * In lockstep mode, TCM is contiguous memory block
-	 * However, each TCM block still needs to be enabled individually.
-	 * So, Enable each TCM block individually.
-	 * Although ATCM and BTCM is contiguous memory block, add two separate
-	 * carveouts for both.
-	 */
-	for (i = 0; i < num_banks; i++) {
-		pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
-
-		/* Turn on each TCM bank individually */
-		ret = zynqmp_pm_request_node(pm_domain_id,
-					     ZYNQMP_PM_CAPABILITY_ACCESS, 0,
-					     ZYNQMP_PM_REQUEST_ACK_BLOCKING);
-		if (ret < 0) {
-			dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
-			goto release_tcm_lockstep;
-		}
-
-		bank_size = r5_core->tcm_banks[i]->size;
-		if (bank_size == 0)
-			continue;
-
-		bank_addr = r5_core->tcm_banks[i]->addr;
-		da = r5_core->tcm_banks[i]->da;
-		bank_name = r5_core->tcm_banks[i]->bank_name;
-
-		/* Register TCM address range, TCM map and unmap functions */
-		rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
-						 bank_size, da,
-						 tcm_mem_map, tcm_mem_unmap,
-						 bank_name);
-		if (!rproc_mem) {
-			ret = -ENOMEM;
-			zynqmp_pm_release_node(pm_domain_id);
-			goto release_tcm_lockstep;
-		}
-
-		/* If registration is success, add carveouts */
-		rproc_add_carveout(rproc, rproc_mem);
-
-		dev_dbg(dev, "TCM carveout lockstep mode %s addr=0x%llx, da=0x%x, size=0x%lx",
-			bank_name, bank_addr, da, bank_size);
-	}
-
-	return 0;
-
-release_tcm_lockstep:
-	/* If failed, Turn off all TCM banks turned on before */
-	for (i--; i >= 0; i--) {
-		pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
-		zynqmp_pm_release_node(pm_domain_id);
-	}
-	return ret;
-}
-
-/*
- * add_tcm_banks()
- * @rproc: single R5 core's corresponding rproc instance
- *
- * allocate and add remoteproc carveouts for TCM memory based on cluster mode
- *
- * return 0 on success, otherwise non-zero value on failure
- */
-static int add_tcm_banks(struct rproc *rproc)
-{
-	struct zynqmp_r5_cluster *cluster;
-	struct zynqmp_r5_core *r5_core;
-	struct device *dev;
-
-	r5_core = rproc->priv;
-	if (!r5_core)
-		return -EINVAL;
-
-	dev = r5_core->dev;
-
-	cluster = dev_get_drvdata(dev->parent);
-	if (!cluster) {
-		dev_err(dev->parent, "Invalid driver data\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * In lockstep mode TCM banks are one contiguous memory region of 256Kb
-	 * In split mode, each TCM bank is 64Kb and not contiguous.
-	 * We add memory carveouts accordingly.
-	 */
-	if (cluster->mode == SPLIT_MODE)
-		return add_tcm_carveout_split_mode(rproc);
-	else if (cluster->mode == LOCKSTEP_MODE)
-		return add_tcm_carveout_lockstep_mode(rproc);
-
-	return -EINVAL;
-}
-
 /*
  * zynqmp_r5_parse_fw()
  * @rproc: single R5 core's corresponding rproc instance
-- 
2.25.1



From tanmay.shah at amd.com  Mon Feb 19 09:44:35 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 09:44:35 -0800
Subject: [PATCH v11 2/4] dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings
In-Reply-To: <20240219174437.3722620-1-tanmay.shah@amd.com>
References: <20240219174437.3722620-1-tanmay.shah@amd.com>
Message-ID: <20240219174437.3722620-8-tanmay.shah@amd.com>

From: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>

Introduce bindings for TCM memory address space on AMD-xilinx Zynq
UltraScale+ platform. It will help in defining TCM in device-tree
and make it's access platform agnostic and data-driven.

Tightly-coupled memories(TCMs) are low-latency memory that provides
predictable instruction execution and predictable data load/store
timing. Each Cortex-R5F processor contains two 64-bit wide 64 KB memory
banks on the ATCM and BTCM ports, for a total of 128 KB of memory.

The TCM resources(reg, reg-names and power-domain) are documented for
each TCM in the R5 node. The reg and reg-names are made as required
properties as we don't want to hardcode TCM addresses for future
platforms and for zu+ legacy implementation will ensure that the
old dts w/o reg/reg-names works and stable ABI is maintained.

It also extends the examples for TCM split and lockstep modes.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey at amd.com>
Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---

Changes in v11:
  - Fix yamllint warning and reduce indentation as needed

 .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 ++++++++++++++++--
 1 file changed, 170 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml b/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
index 78aac69f1060..77030edf41fa 100644
--- a/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml
@@ -20,9 +20,21 @@ properties:
   compatible:
     const: xlnx,zynqmp-r5fss
 
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 2
+
+  ranges:
+    description: |
+      Standard ranges definition providing address translations for
+      local R5F TCM address spaces to bus addresses.
+
   xlnx,cluster-mode:
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [0, 1, 2]
+    default: 1
     description: |
       The RPU MPCore can operate in split mode (Dual-processor performance), Safety
       lock-step mode(Both RPU cores execute the same code in lock-step,
@@ -37,7 +49,7 @@ properties:
       2: single cpu mode
 
 patternProperties:
-  "^r5f-[a-f0-9]+$":
+  "^r5f@[0-9a-f]+$":
     type: object
     description: |
       The RPU is located in the Low Power Domain of the Processor Subsystem.
@@ -54,9 +66,6 @@ patternProperties:
       compatible:
         const: xlnx,zynqmp-r5f
 
-      power-domains:
-        maxItems: 1
-
       mboxes:
         minItems: 1
         items:
@@ -101,35 +110,174 @@ patternProperties:
 
     required:
       - compatible
-      - power-domains
 
-    unevaluatedProperties: false
+allOf:
+  - if:
+      properties:
+        xlnx,cluster-mode:
+          enum:
+            - 1
+    then:
+      patternProperties:
+        "^r5f@[0-9a-f]+$":
+          type: object
+
+          properties:
+            reg:
+              minItems: 1
+              items:
+                - description: ATCM internal memory
+                - description: BTCM internal memory
+                - description: extra ATCM memory in lockstep mode
+                - description: extra BTCM memory in lockstep mode
+
+            reg-names:
+              minItems: 1
+              items:
+                - const: atcm0
+                - const: btcm0
+                - const: atcm1
+                - const: btcm1
+
+            power-domains:
+              minItems: 2
+              maxItems: 5
+
+          required:
+            - reg
+            - reg-names
+            - power-domains
+
+    else:
+      patternProperties:
+        "^r5f@[0-9a-f]+$":
+          type: object
+
+          properties:
+            reg:
+              minItems: 1
+              items:
+                - description: ATCM internal memory
+                - description: BTCM internal memory
+
+            reg-names:
+              minItems: 1
+              items:
+                - const: atcm0
+                - const: btcm0
+
+            power-domains:
+              minItems: 2
+              maxItems: 3
+
+          required:
+            - reg
+            - reg-names
+            - power-domains
 
 required:
   - compatible
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
 
 additionalProperties: false
 
 examples:
   - |
-    remoteproc {
-        compatible = "xlnx,zynqmp-r5fss";
-        xlnx,cluster-mode = <1>;
-
-        r5f-0 {
-            compatible = "xlnx,zynqmp-r5f";
-            power-domains = <&zynqmp_firmware 0x7>;
-            memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
-            mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
-            mbox-names = "tx", "rx";
+    #include <dt-bindings/power/xlnx-zynqmp-power.h>
+
+    // Split mode configuration
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        remoteproc at ffe00000 {
+            compatible = "xlnx,zynqmp-r5fss";
+            xlnx,cluster-mode = <0>;
+
+            #address-cells = <2>;
+            #size-cells = <2>;
+            ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+                     <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+                     <0x1 0x0 0x0 0xffe90000 0x0 0x10000>,
+                     <0x1 0x20000 0x0 0xffeb0000 0x0 0x10000>;
+
+            r5f at 0 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x0 0x0 0x0 0x10000>, <0x0 0x20000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0";
+                power-domains = <&zynqmp_firmware PD_RPU_0>,
+                                <&zynqmp_firmware PD_R5_0_ATCM>,
+                                <&zynqmp_firmware PD_R5_0_BTCM>;
+                memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>,
+                                <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
+                mbox-names = "tx", "rx";
+            };
+
+            r5f at 1 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0";
+                power-domains = <&zynqmp_firmware PD_RPU_1>,
+                                <&zynqmp_firmware PD_R5_1_ATCM>,
+                                <&zynqmp_firmware PD_R5_1_BTCM>;
+                memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>,
+                                <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
+                mbox-names = "tx", "rx";
+            };
         };
+    };
+
+  - |
+    //Lockstep configuration
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        remoteproc at ffe00000 {
+            compatible = "xlnx,zynqmp-r5fss";
+            xlnx,cluster-mode = <1>;
+
+            #address-cells = <2>;
+            #size-cells = <2>;
+            ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+                     <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+                     <0x0 0x10000 0x0 0xffe10000 0x0 0x10000>,
+                     <0x0 0x30000 0x0 0xffe30000 0x0 0x10000>;
+
+            r5f at 0 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x0 0x0 0x0 0x10000>,
+                      <0x0 0x20000 0x0 0x10000>,
+                      <0x0 0x10000 0x0 0x10000>,
+                      <0x0 0x30000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0", "atcm1", "btcm1";
+                power-domains = <&zynqmp_firmware PD_RPU_0>,
+                                <&zynqmp_firmware PD_R5_0_ATCM>,
+                                <&zynqmp_firmware PD_R5_0_BTCM>,
+                                <&zynqmp_firmware PD_R5_1_ATCM>,
+                                <&zynqmp_firmware PD_R5_1_BTCM>;
+                memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>,
+                                <&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
+                mbox-names = "tx", "rx";
+            };
 
-        r5f-1 {
-            compatible = "xlnx,zynqmp-r5f";
-            power-domains = <&zynqmp_firmware 0x8>;
-            memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
-            mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
-            mbox-names = "tx", "rx";
+            r5f at 1 {
+                compatible = "xlnx,zynqmp-r5f";
+                reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+                reg-names = "atcm0", "btcm0";
+                power-domains = <&zynqmp_firmware PD_RPU_1>,
+                                <&zynqmp_firmware PD_R5_1_ATCM>,
+                                <&zynqmp_firmware PD_R5_1_BTCM>;
+                memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>,
+                                <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
+                mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
+                mbox-names = "tx", "rx";
+            };
         };
     };
 ...
-- 
2.25.1



From tanmay.shah at amd.com  Mon Feb 19 09:44:34 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 09:44:34 -0800
Subject: [PATCH v11 1/4] remoteproc: zynqmp: fix lockstep mode memory region
In-Reply-To: <20240219174437.3722620-1-tanmay.shah@amd.com>
References: <20240219174437.3722620-1-tanmay.shah@amd.com>
Message-ID: <20240219174437.3722620-7-tanmay.shah@amd.com>

In lockstep mode, r5 core0 uses TCM of R5 core1. Following is lockstep
mode memory region as per hardware reference manual.

    |      *TCM*         |   *R5 View* | *Linux view* |
    | R5_0 ATCM (128 KB) | 0x0000_0000 | 0xFFE0_0000  |
    | R5_0 BTCM (128 KB) | 0x0002_0000 | 0xFFE2_0000  |

However, driver shouldn't model it as above because R5 core0 TCM and core1
TCM has different power-domains mapped to it.
Hence, TCM address space in lockstep mode should be modeled as 64KB
regions only where each region has its own power-domain as following:

    |      *TCM*         |   *R5 View* | *Linux view* |
    | R5_0 ATCM0 (64 KB) | 0x0000_0000 | 0xFFE0_0000  |
    | R5_0 BTCM0 (64 KB) | 0x0002_0000 | 0xFFE2_0000  |
    | R5_0 ATCM1 (64 KB) | 0x0001_0000 | 0xFFE1_0000  |
    | R5_0 BTCM1 (64 KB) | 0x0003_0000 | 0xFFE3_0000  |

This makes driver maintanance easy and makes design robust for future
platorms as well.

Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---
 drivers/remoteproc/xlnx_r5_remoteproc.c | 145 ++----------------------
 1 file changed, 12 insertions(+), 133 deletions(-)

diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index 4395edea9a64..42b0384d34f2 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -84,12 +84,12 @@ static const struct mem_bank_data zynqmp_tcm_banks_split[] = {
 	{0xffeb0000UL, 0x20000, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
 };
 
-/* In lockstep mode cluster combines each 64KB TCM and makes 128KB TCM */
+/* In lockstep mode cluster uses each 64KB TCM from second core as well */
 static const struct mem_bank_data zynqmp_tcm_banks_lockstep[] = {
-	{0xffe00000UL, 0x0, 0x20000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 128KB each */
-	{0xffe20000UL, 0x20000, 0x20000UL, PD_R5_0_BTCM, "btcm0"},
-	{0, 0, 0, PD_R5_1_ATCM, ""},
-	{0, 0, 0, PD_R5_1_BTCM, ""},
+	{0xffe00000UL, 0x0, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
+	{0xffe20000UL, 0x20000, 0x10000UL, PD_R5_0_BTCM, "btcm0"},
+	{0xffe10000UL, 0x10000, 0x10000UL, PD_R5_1_ATCM, "atcm1"},
+	{0xffe30000UL, 0x30000, 0x10000UL, PD_R5_1_BTCM, "btcm1"},
 };
 
 /**
@@ -540,14 +540,14 @@ static int tcm_mem_map(struct rproc *rproc,
 }
 
 /*
- * add_tcm_carveout_split_mode()
+ * add_tcm_banks()
  * @rproc: single R5 core's corresponding rproc instance
  *
- * allocate and add remoteproc carveout for TCM memory in split mode
+ * allocate and add remoteproc carveout for TCM memory
  *
  * return 0 on success, otherwise non-zero value on failure
  */
-static int add_tcm_carveout_split_mode(struct rproc *rproc)
+static int add_tcm_banks(struct rproc *rproc)
 {
 	struct rproc_mem_entry *rproc_mem;
 	struct zynqmp_r5_core *r5_core;
@@ -580,10 +580,10 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 					     ZYNQMP_PM_REQUEST_ACK_BLOCKING);
 		if (ret < 0) {
 			dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
-			goto release_tcm_split;
+			goto release_tcm;
 		}
 
-		dev_dbg(dev, "TCM carveout split mode %s addr=%llx, da=0x%x, size=0x%lx",
+		dev_dbg(dev, "TCM carveout %s addr=%llx, da=0x%x, size=0x%lx",
 			bank_name, bank_addr, da, bank_size);
 
 		rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
@@ -593,7 +593,7 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 		if (!rproc_mem) {
 			ret = -ENOMEM;
 			zynqmp_pm_release_node(pm_domain_id);
-			goto release_tcm_split;
+			goto release_tcm;
 		}
 
 		rproc_add_carveout(rproc, rproc_mem);
@@ -601,7 +601,7 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 
 	return 0;
 
-release_tcm_split:
+release_tcm:
 	/* If failed, Turn off all TCM banks turned on before */
 	for (i--; i >= 0; i--) {
 		pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
@@ -610,127 +610,6 @@ static int add_tcm_carveout_split_mode(struct rproc *rproc)
 	return ret;
 }
 
-/*
- * add_tcm_carveout_lockstep_mode()
- * @rproc: single R5 core's corresponding rproc instance
- *
- * allocate and add remoteproc carveout for TCM memory in lockstep mode
- *
- * return 0 on success, otherwise non-zero value on failure
- */
-static int add_tcm_carveout_lockstep_mode(struct rproc *rproc)
-{
-	struct rproc_mem_entry *rproc_mem;
-	struct zynqmp_r5_core *r5_core;
-	int i, num_banks, ret;
-	phys_addr_t bank_addr;
-	size_t bank_size = 0;
-	struct device *dev;
-	u32 pm_domain_id;
-	char *bank_name;
-	u32 da;
-
-	r5_core = rproc->priv;
-	dev = r5_core->dev;
-
-	/* Go through zynqmp banks for r5 node */
-	num_banks = r5_core->tcm_bank_count;
-
-	/*
-	 * In lockstep mode, TCM is contiguous memory block
-	 * However, each TCM block still needs to be enabled individually.
-	 * So, Enable each TCM block individually.
-	 * Although ATCM and BTCM is contiguous memory block, add two separate
-	 * carveouts for both.
-	 */
-	for (i = 0; i < num_banks; i++) {
-		pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
-
-		/* Turn on each TCM bank individually */
-		ret = zynqmp_pm_request_node(pm_domain_id,
-					     ZYNQMP_PM_CAPABILITY_ACCESS, 0,
-					     ZYNQMP_PM_REQUEST_ACK_BLOCKING);
-		if (ret < 0) {
-			dev_err(dev, "failed to turn on TCM 0x%x", pm_domain_id);
-			goto release_tcm_lockstep;
-		}
-
-		bank_size = r5_core->tcm_banks[i]->size;
-		if (bank_size == 0)
-			continue;
-
-		bank_addr = r5_core->tcm_banks[i]->addr;
-		da = r5_core->tcm_banks[i]->da;
-		bank_name = r5_core->tcm_banks[i]->bank_name;
-
-		/* Register TCM address range, TCM map and unmap functions */
-		rproc_mem = rproc_mem_entry_init(dev, NULL, bank_addr,
-						 bank_size, da,
-						 tcm_mem_map, tcm_mem_unmap,
-						 bank_name);
-		if (!rproc_mem) {
-			ret = -ENOMEM;
-			zynqmp_pm_release_node(pm_domain_id);
-			goto release_tcm_lockstep;
-		}
-
-		/* If registration is success, add carveouts */
-		rproc_add_carveout(rproc, rproc_mem);
-
-		dev_dbg(dev, "TCM carveout lockstep mode %s addr=0x%llx, da=0x%x, size=0x%lx",
-			bank_name, bank_addr, da, bank_size);
-	}
-
-	return 0;
-
-release_tcm_lockstep:
-	/* If failed, Turn off all TCM banks turned on before */
-	for (i--; i >= 0; i--) {
-		pm_domain_id = r5_core->tcm_banks[i]->pm_domain_id;
-		zynqmp_pm_release_node(pm_domain_id);
-	}
-	return ret;
-}
-
-/*
- * add_tcm_banks()
- * @rproc: single R5 core's corresponding rproc instance
- *
- * allocate and add remoteproc carveouts for TCM memory based on cluster mode
- *
- * return 0 on success, otherwise non-zero value on failure
- */
-static int add_tcm_banks(struct rproc *rproc)
-{
-	struct zynqmp_r5_cluster *cluster;
-	struct zynqmp_r5_core *r5_core;
-	struct device *dev;
-
-	r5_core = rproc->priv;
-	if (!r5_core)
-		return -EINVAL;
-
-	dev = r5_core->dev;
-
-	cluster = dev_get_drvdata(dev->parent);
-	if (!cluster) {
-		dev_err(dev->parent, "Invalid driver data\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * In lockstep mode TCM banks are one contiguous memory region of 256Kb
-	 * In split mode, each TCM bank is 64Kb and not contiguous.
-	 * We add memory carveouts accordingly.
-	 */
-	if (cluster->mode == SPLIT_MODE)
-		return add_tcm_carveout_split_mode(rproc);
-	else if (cluster->mode == LOCKSTEP_MODE)
-		return add_tcm_carveout_lockstep_mode(rproc);
-
-	return -EINVAL;
-}
-
 /*
  * zynqmp_r5_parse_fw()
  * @rproc: single R5 core's corresponding rproc instance
-- 
2.25.1



From tanmay.shah at amd.com  Mon Feb 19 09:44:31 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 09:44:31 -0800
Subject: [PATCH v11 3/4] dts: zynqmp: add properties for TCM in remoteproc
In-Reply-To: <20240219174437.3722620-1-tanmay.shah@amd.com>
References: <20240219174437.3722620-1-tanmay.shah@amd.com>
Message-ID: <20240219174437.3722620-4-tanmay.shah@amd.com>

Add properties as per new bindings in zynqmp remoteproc node
to represent TCM address and size.

This patch also adds alternative remoteproc node to represent
remoteproc cluster in split mode. By default lockstep mode is
enabled and users should disable it before using split mode
dts. Both device-tree nodes can't be used simultaneously one
of them must be disabled. For zcu102-1.0 and zcu102-1.1 board
remoteproc split mode dts node is enabled and lockstep mode
dts is disabled.

Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---
 .../boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts  |  8 +++
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 65 +++++++++++++++++--
 2 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
index c8f71a1aec89..495ca94b45db 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
@@ -14,6 +14,14 @@ / {
 	compatible = "xlnx,zynqmp-zcu102-rev1.0", "xlnx,zynqmp-zcu102", "xlnx,zynqmp";
 };
 
+&rproc_split {
+	status = "okay";
+};
+
+&rproc_lockstep {
+	status = "disabled";
+};
+
 &eeprom {
 	#address-cells = <1>;
 	#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index eaba466804bc..c8a7fd0f3a1e 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -248,19 +248,74 @@ fpga_full: fpga-full {
 		ranges;
 	};
 
-	remoteproc {
+	rproc_lockstep: remoteproc at ffe00000 {
 		compatible = "xlnx,zynqmp-r5fss";
 		xlnx,cluster-mode = <1>;
 
-		r5f-0 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+			 <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+			 <0x0 0x10000 0x0 0xffe10000 0x0 0x10000>,
+			 <0x0 0x30000 0x0 0xffe30000 0x0 0x10000>;
+
+		r5f at 0 {
+			compatible = "xlnx,zynqmp-r5f";
+			reg = <0x0 0x0 0x0 0x10000>,
+			      <0x0 0x20000 0x0 0x10000>,
+			      <0x0 0x10000 0x0 0x10000>,
+			      <0x0 0x30000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0", "atcm1", "btcm1";
+			power-domains = <&zynqmp_firmware PD_RPU_0>,
+					<&zynqmp_firmware PD_R5_0_ATCM>,
+					<&zynqmp_firmware PD_R5_0_BTCM>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
+			memory-region = <&rproc_0_fw_image>;
+		};
+
+		r5f at 1 {
+			compatible = "xlnx,zynqmp-r5f";
+			reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_1>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
+			memory-region = <&rproc_1_fw_image>;
+		};
+	};
+
+	rproc_split: remoteproc-split at ffe00000 {
+		status = "disabled";
+		compatible = "xlnx,zynqmp-r5fss";
+		xlnx,cluster-mode = <0>;
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+			 <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+			 <0x1 0x0 0x0 0xffe90000 0x0 0x10000>,
+			 <0x1 0x20000 0x0 0xffeb0000 0x0 0x10000>;
+
+		r5f at 0 {
 			compatible = "xlnx,zynqmp-r5f";
-			power-domains = <&zynqmp_firmware PD_RPU_0>;
+			reg = <0x0 0x0 0x0 0x10000>, <0x0 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_0>,
+					<&zynqmp_firmware PD_R5_0_ATCM>,
+					<&zynqmp_firmware PD_R5_0_BTCM>;
 			memory-region = <&rproc_0_fw_image>;
 		};
 
-		r5f-1 {
+		r5f at 1 {
 			compatible = "xlnx,zynqmp-r5f";
-			power-domains = <&zynqmp_firmware PD_RPU_1>;
+			reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_1>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
 			memory-region = <&rproc_1_fw_image>;
 		};
 	};
-- 
2.25.1



From tanmay.shah at amd.com  Mon Feb 19 09:44:32 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 09:44:32 -0800
Subject: [PATCH v11 4/4] remoteproc: zynqmp: parse TCM from device tree
In-Reply-To: <20240219174437.3722620-1-tanmay.shah@amd.com>
References: <20240219174437.3722620-1-tanmay.shah@amd.com>
Message-ID: <20240219174437.3722620-5-tanmay.shah@amd.com>

ZynqMP TCM information was fixed in driver. Now ZynqMP TCM information
is available in device-tree. Parse TCM information in driver
as per new bindings.

Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---

Changes in v11:
  - Remove redundant initialization of the variable
  - return correct error code if memory allocation failed

 drivers/remoteproc/xlnx_r5_remoteproc.c | 112 ++++++++++++++++++++++--
 1 file changed, 107 insertions(+), 5 deletions(-)

diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index 42b0384d34f2..d4a22caebaad 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -74,8 +74,8 @@ struct mbox_info {
 };
 
 /*
- * Hardcoded TCM bank values. This will be removed once TCM bindings are
- * accepted for system-dt specifications and upstreamed in linux kernel
+ * Hardcoded TCM bank values. This will stay in driver to maintain backward
+ * compatibility with device-tree that does not have TCM information.
  */
 static const struct mem_bank_data zynqmp_tcm_banks_split[] = {
 	{0xffe00000UL, 0x0, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
@@ -757,6 +757,103 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)
 	return ERR_PTR(ret);
 }
 
+static int zynqmp_r5_get_tcm_node_from_dt(struct zynqmp_r5_cluster *cluster)
+{
+	int i, j, tcm_bank_count, ret, tcm_pd_idx, pd_count;
+	struct of_phandle_args out_args;
+	struct zynqmp_r5_core *r5_core;
+	struct platform_device *cpdev;
+	struct mem_bank_data *tcm;
+	struct device_node *np;
+	struct resource *res;
+	u64 abs_addr, size;
+	struct device *dev;
+
+	for (i = 0; i < cluster->core_count; i++) {
+		r5_core = cluster->r5_cores[i];
+		dev = r5_core->dev;
+		np = r5_core->np;
+
+		pd_count = of_count_phandle_with_args(np, "power-domains",
+						      "#power-domain-cells");
+
+		if (pd_count <= 0) {
+			dev_err(dev, "invalid power-domains property, %d\n", pd_count);
+			return -EINVAL;
+		}
+
+		/* First entry in power-domains list is for r5 core, rest for TCM. */
+		tcm_bank_count = pd_count - 1;
+
+		if (tcm_bank_count <= 0) {
+			dev_err(dev, "invalid TCM count %d\n", tcm_bank_count);
+			return -EINVAL;
+		}
+
+		r5_core->tcm_banks = devm_kcalloc(dev, tcm_bank_count,
+						  sizeof(struct mem_bank_data *),
+						  GFP_KERNEL);
+		if (!r5_core->tcm_banks)
+			return -ENOMEM;
+
+		r5_core->tcm_bank_count = tcm_bank_count;
+		for (j = 0, tcm_pd_idx = 1; j < tcm_bank_count; j++, tcm_pd_idx++) {
+			tcm = devm_kzalloc(dev, sizeof(struct mem_bank_data),
+					   GFP_KERNEL);
+			if (!tcm)
+				return -ENOMEM;
+
+			r5_core->tcm_banks[j] = tcm;
+
+			/* Get power-domains id of TCM. */
+			ret = of_parse_phandle_with_args(np, "power-domains",
+							 "#power-domain-cells",
+							 tcm_pd_idx, &out_args);
+			if (ret) {
+				dev_err(r5_core->dev,
+					"failed to get tcm %d pm domain, ret %d\n",
+					tcm_pd_idx, ret);
+				return ret;
+			}
+			tcm->pm_domain_id = out_args.args[0];
+			of_node_put(out_args.np);
+
+			/* Get TCM address without translation. */
+			ret = of_property_read_reg(np, j, &abs_addr, &size);
+			if (ret) {
+				dev_err(dev, "failed to get reg property\n");
+				return ret;
+			}
+
+			/*
+			 * Remote processor can address only 32 bits
+			 * so convert 64-bits into 32-bits. This will discard
+			 * any unwanted upper 32-bits.
+			 */
+			tcm->da = (u32)abs_addr;
+			tcm->size = (u32)size;
+
+			cpdev = to_platform_device(dev);
+			res = platform_get_resource(cpdev, IORESOURCE_MEM, j);
+			if (!res) {
+				dev_err(dev, "failed to get tcm resource\n");
+				return -EINVAL;
+			}
+
+			tcm->addr = (u32)res->start;
+			tcm->bank_name = (char *)res->name;
+			res = devm_request_mem_region(dev, tcm->addr, tcm->size,
+						      tcm->bank_name);
+			if (!res) {
+				dev_err(dev, "failed to request tcm resource\n");
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
 /**
  * zynqmp_r5_get_tcm_node()
  * Ideally this function should parse tcm node and store information
@@ -835,9 +932,14 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
 	struct zynqmp_r5_core *r5_core;
 	int ret, i;
 
-	ret = zynqmp_r5_get_tcm_node(cluster);
-	if (ret < 0) {
-		dev_err(dev, "can't get tcm node, err %d\n", ret);
+	r5_core = cluster->r5_cores[0];
+	if (of_find_property(r5_core->np, "reg", NULL))
+		ret = zynqmp_r5_get_tcm_node_from_dt(cluster);
+	else
+		ret = zynqmp_r5_get_tcm_node(cluster);
+
+	if (ret) {
+		dev_err(dev, "can't get tcm, err %d\n", ret);
 		return ret;
 	}
 
-- 
2.25.1



From tanmay.shah at amd.com  Mon Feb 19 09:44:33 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 09:44:33 -0800
Subject: [PATCH v11 0/4] add zynqmp TCM bindings
In-Reply-To: <20240219174437.3722620-1-tanmay.shah@amd.com>
References: <20240219174437.3722620-1-tanmay.shah@amd.com>
Message-ID: <20240219174437.3722620-6-tanmay.shah@amd.com>

Tightly-Coupled Memories(TCMs) are low-latency memory that provides
predictable instruction execution and predictable data load/store
timing. Each Cortex-R5F processor contains exclusive two 64 KB memory
banks on the ATCM and BTCM ports, for a total of 128 KB of memory.
In lockstep mode, both 128KB memory is accessible to the cluster.

As per ZynqMP Ultrascale+ Technical Reference Manual UG1085, following
is address space of TCM memory. The bindings in this patch series
introduces properties to accommodate following address space with
address translation between Linux and Cortex-R5 views.

|     |     |     |
| --- | --- | --- |
|      *Mode*        |   *R5 View* | *Linux view* |  Notes               |
| *Split Mode*       | *start addr*| *start addr* |                      |
| R5_0 ATCM (64 KB)  | 0x0000_0000 | 0xFFE0_0000  |                      |
| R5_0 BTCM (64 KB)  | 0x0002_0000 | 0xFFE2_0000  |                      |
| R5_1 ATCM (64 KB)  | 0x0000_0000 | 0xFFE9_0000  | alias of 0xFFE1_0000 |
| R5_1 BTCM (64 KB)  | 0x0002_0000 | 0xFFEB_0000  | alias of 0xFFE3_0000 |
|  ___               |     ___     |    ___       |                      |
| *Lockstep Mode*    |             |              |                      |
| R5_0 ATCM (128 KB) | 0x0000_0000 | 0xFFE0_0000  |                      |
| R5_0 BTCM (128 KB) | 0x0002_0000 | 0xFFE2_0000  |                      |

References:
UG1085 TCM address space:
https://docs.xilinx.com/r/en-US/ug1085-zynq-ultrascale-trm/Tightly-Coupled-Memory-Address-Map

Changes in v11:
  - Fix yamllint warning and reduce indentation as needed
  - Remove redundant initialization of the variable
  - Return correct error code if memory allocation failed

Changs in v10:
  - Add new patch (1/4) to series that changes hardcode TCM addresses in
    lockstep mode and removes separate handling of TCM in lockstep and
    split mode
  - modify number of "reg", "reg-names" and "power-domains" entries
    based on cluster mode
  - Add extra optional atcm and btcm in "reg" property for lockstep mode
  - Add "reg-names" for extra optional atcm and btcm for lockstep mode
  - Drop previous Ack as bindings has new change
  - Add individual tcm regions via "reg" and "reg-names" for lockstep mode
  - Add each tcm's power-domains in lockstep mode
  - Drop previous Ack as new change in dts patchset
  - Remove redundant changes in driver to handle TCM in lockstep mode

Changes in v9:
  - Fix rproc lockstep dts
  - Introduce new API to request and release core1 TCM power-domains in
    lockstep mode. This will be used during prepare -> add_tcm_banks
    callback to enable TCM in lockstep mode.
  - Parse TCM from device-tree in lockstep mode and split mode in
    uniform way.
  - Fix TCM representation in device-tree in lockstep mode.
  - Fix comments as suggested

Changes in v8:
  - Remove use of pm_domains framework
  - Remove checking of pm_domain_id validation to power on/off tcm
  - Remove spurious change
  - parse power-domains property from device-tree and use EEMI calls
    to power on/off TCM instead of using pm domains framework

Changes in v7:
  - %s/pm_dev1/pm_dev_core0/r
  - %s/pm_dev_link1/pm_dev_core0_link/r
  - %s/pm_dev2/pm_dev_core1/r
  - %s/pm_dev_link2/pm_dev_core1_link/r
  - remove pm_domain_id check to move next patch
  - add comment about how 1st entry in pm domain list is used
  - fix loop when jump to fail_add_pm_domains loop
  - move checking of pm_domain_id from previous patch
  - fix mem_bank_data memory allocation

Changes in v6:
  - Introduce new node entry for r5f cluster split mode dts and
    keep it disabled by default.
  - Keep remoteproc lockstep mode enabled by default to maintian
    back compatibility.
  - Enable split mode only for zcu102 board to demo split mode use
  - Remove spurious change
  - Handle errors in add_pm_domains function
  - Remove redundant code to handle errors from remove_pm_domains
  - Missing . at the end of the commit message
  - remove redundant initialization of variables
  - remove fail_tcm label and relevant code to free memory
    acquired using devm_* API. As this will be freed when device free it
  - add extra check to see if "reg" property is supported or not

Changes in v5:
  - maintain Rob's Ack on bindings patch as no changes in bindings
  - split previous patch into multiple patches
  - Use pm domain framework to turn on/off TCM
  - Add support of parsing TCM information from device-tree
  - maintain backward compatibility with previous bindings without
    TCM information available in device-tree

This patch series continues previous effort to upstream ZynqMP
TCM bindings:
Previous v4 version link:
https://lore.kernel.org/all/20230829181900.2561194-1-tanmay.shah at amd.com/

Previous v3 version link:
https://lore.kernel.org/all/1689964908-22371-1-git-send-email-radhey.shyam.pandey at amd.com/
Radhey Shyam Pandey (1):
  dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings



Radhey Shyam Pandey (1):
  dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings

Tanmay Shah (3):
  remoteproc: zynqmp: fix lockstep mode memory region
  dts: zynqmp: add properties for TCM in remoteproc
  remoteproc: zynqmp: parse TCM from device tree

 .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 +++++++++++--
 .../boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts  |   8 +
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  65 ++++-
 drivers/remoteproc/xlnx_r5_remoteproc.c       | 257 ++++++++----------
 4 files changed, 357 insertions(+), 165 deletions(-)


base-commit: 929654e8f1add50b01d5a56171a31c311b0a739a
-- 
2.25.1



From tanmay.shah at amd.com  Mon Feb 19 09:44:36 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 09:44:36 -0800
Subject: [PATCH v11 3/4] dts: zynqmp: add properties for TCM in remoteproc
In-Reply-To: <20240219174437.3722620-1-tanmay.shah@amd.com>
References: <20240219174437.3722620-1-tanmay.shah@amd.com>
Message-ID: <20240219174437.3722620-9-tanmay.shah@amd.com>

Add properties as per new bindings in zynqmp remoteproc node
to represent TCM address and size.

This patch also adds alternative remoteproc node to represent
remoteproc cluster in split mode. By default lockstep mode is
enabled and users should disable it before using split mode
dts. Both device-tree nodes can't be used simultaneously one
of them must be disabled. For zcu102-1.0 and zcu102-1.1 board
remoteproc split mode dts node is enabled and lockstep mode
dts is disabled.

Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---
 .../boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts  |  8 +++
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 65 +++++++++++++++++--
 2 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
index c8f71a1aec89..495ca94b45db 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts
@@ -14,6 +14,14 @@ / {
 	compatible = "xlnx,zynqmp-zcu102-rev1.0", "xlnx,zynqmp-zcu102", "xlnx,zynqmp";
 };
 
+&rproc_split {
+	status = "okay";
+};
+
+&rproc_lockstep {
+	status = "disabled";
+};
+
 &eeprom {
 	#address-cells = <1>;
 	#size-cells = <1>;
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index eaba466804bc..c8a7fd0f3a1e 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -248,19 +248,74 @@ fpga_full: fpga-full {
 		ranges;
 	};
 
-	remoteproc {
+	rproc_lockstep: remoteproc at ffe00000 {
 		compatible = "xlnx,zynqmp-r5fss";
 		xlnx,cluster-mode = <1>;
 
-		r5f-0 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+			 <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+			 <0x0 0x10000 0x0 0xffe10000 0x0 0x10000>,
+			 <0x0 0x30000 0x0 0xffe30000 0x0 0x10000>;
+
+		r5f at 0 {
+			compatible = "xlnx,zynqmp-r5f";
+			reg = <0x0 0x0 0x0 0x10000>,
+			      <0x0 0x20000 0x0 0x10000>,
+			      <0x0 0x10000 0x0 0x10000>,
+			      <0x0 0x30000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0", "atcm1", "btcm1";
+			power-domains = <&zynqmp_firmware PD_RPU_0>,
+					<&zynqmp_firmware PD_R5_0_ATCM>,
+					<&zynqmp_firmware PD_R5_0_BTCM>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
+			memory-region = <&rproc_0_fw_image>;
+		};
+
+		r5f at 1 {
+			compatible = "xlnx,zynqmp-r5f";
+			reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_1>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
+			memory-region = <&rproc_1_fw_image>;
+		};
+	};
+
+	rproc_split: remoteproc-split at ffe00000 {
+		status = "disabled";
+		compatible = "xlnx,zynqmp-r5fss";
+		xlnx,cluster-mode = <0>;
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
+			 <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
+			 <0x1 0x0 0x0 0xffe90000 0x0 0x10000>,
+			 <0x1 0x20000 0x0 0xffeb0000 0x0 0x10000>;
+
+		r5f at 0 {
 			compatible = "xlnx,zynqmp-r5f";
-			power-domains = <&zynqmp_firmware PD_RPU_0>;
+			reg = <0x0 0x0 0x0 0x10000>, <0x0 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_0>,
+					<&zynqmp_firmware PD_R5_0_ATCM>,
+					<&zynqmp_firmware PD_R5_0_BTCM>;
 			memory-region = <&rproc_0_fw_image>;
 		};
 
-		r5f-1 {
+		r5f at 1 {
 			compatible = "xlnx,zynqmp-r5f";
-			power-domains = <&zynqmp_firmware PD_RPU_1>;
+			reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
+			reg-names = "atcm0", "btcm0";
+			power-domains = <&zynqmp_firmware PD_RPU_1>,
+					<&zynqmp_firmware PD_R5_1_ATCM>,
+					<&zynqmp_firmware PD_R5_1_BTCM>;
 			memory-region = <&rproc_1_fw_image>;
 		};
 	};
-- 
2.25.1



From tanmay.shah at amd.com  Mon Feb 19 09:44:37 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 09:44:37 -0800
Subject: [PATCH v11 4/4] remoteproc: zynqmp: parse TCM from device tree
In-Reply-To: <20240219174437.3722620-1-tanmay.shah@amd.com>
References: <20240219174437.3722620-1-tanmay.shah@amd.com>
Message-ID: <20240219174437.3722620-10-tanmay.shah@amd.com>

ZynqMP TCM information was fixed in driver. Now ZynqMP TCM information
is available in device-tree. Parse TCM information in driver
as per new bindings.

Signed-off-by: Tanmay Shah <tanmay.shah at amd.com>
---

Changes in v11:
  - Remove redundant initialization of the variable
  - return correct error code if memory allocation failed

 drivers/remoteproc/xlnx_r5_remoteproc.c | 112 ++++++++++++++++++++++--
 1 file changed, 107 insertions(+), 5 deletions(-)

diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index 42b0384d34f2..d4a22caebaad 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -74,8 +74,8 @@ struct mbox_info {
 };
 
 /*
- * Hardcoded TCM bank values. This will be removed once TCM bindings are
- * accepted for system-dt specifications and upstreamed in linux kernel
+ * Hardcoded TCM bank values. This will stay in driver to maintain backward
+ * compatibility with device-tree that does not have TCM information.
  */
 static const struct mem_bank_data zynqmp_tcm_banks_split[] = {
 	{0xffe00000UL, 0x0, 0x10000UL, PD_R5_0_ATCM, "atcm0"}, /* TCM 64KB each */
@@ -757,6 +757,103 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)
 	return ERR_PTR(ret);
 }
 
+static int zynqmp_r5_get_tcm_node_from_dt(struct zynqmp_r5_cluster *cluster)
+{
+	int i, j, tcm_bank_count, ret, tcm_pd_idx, pd_count;
+	struct of_phandle_args out_args;
+	struct zynqmp_r5_core *r5_core;
+	struct platform_device *cpdev;
+	struct mem_bank_data *tcm;
+	struct device_node *np;
+	struct resource *res;
+	u64 abs_addr, size;
+	struct device *dev;
+
+	for (i = 0; i < cluster->core_count; i++) {
+		r5_core = cluster->r5_cores[i];
+		dev = r5_core->dev;
+		np = r5_core->np;
+
+		pd_count = of_count_phandle_with_args(np, "power-domains",
+						      "#power-domain-cells");
+
+		if (pd_count <= 0) {
+			dev_err(dev, "invalid power-domains property, %d\n", pd_count);
+			return -EINVAL;
+		}
+
+		/* First entry in power-domains list is for r5 core, rest for TCM. */
+		tcm_bank_count = pd_count - 1;
+
+		if (tcm_bank_count <= 0) {
+			dev_err(dev, "invalid TCM count %d\n", tcm_bank_count);
+			return -EINVAL;
+		}
+
+		r5_core->tcm_banks = devm_kcalloc(dev, tcm_bank_count,
+						  sizeof(struct mem_bank_data *),
+						  GFP_KERNEL);
+		if (!r5_core->tcm_banks)
+			return -ENOMEM;
+
+		r5_core->tcm_bank_count = tcm_bank_count;
+		for (j = 0, tcm_pd_idx = 1; j < tcm_bank_count; j++, tcm_pd_idx++) {
+			tcm = devm_kzalloc(dev, sizeof(struct mem_bank_data),
+					   GFP_KERNEL);
+			if (!tcm)
+				return -ENOMEM;
+
+			r5_core->tcm_banks[j] = tcm;
+
+			/* Get power-domains id of TCM. */
+			ret = of_parse_phandle_with_args(np, "power-domains",
+							 "#power-domain-cells",
+							 tcm_pd_idx, &out_args);
+			if (ret) {
+				dev_err(r5_core->dev,
+					"failed to get tcm %d pm domain, ret %d\n",
+					tcm_pd_idx, ret);
+				return ret;
+			}
+			tcm->pm_domain_id = out_args.args[0];
+			of_node_put(out_args.np);
+
+			/* Get TCM address without translation. */
+			ret = of_property_read_reg(np, j, &abs_addr, &size);
+			if (ret) {
+				dev_err(dev, "failed to get reg property\n");
+				return ret;
+			}
+
+			/*
+			 * Remote processor can address only 32 bits
+			 * so convert 64-bits into 32-bits. This will discard
+			 * any unwanted upper 32-bits.
+			 */
+			tcm->da = (u32)abs_addr;
+			tcm->size = (u32)size;
+
+			cpdev = to_platform_device(dev);
+			res = platform_get_resource(cpdev, IORESOURCE_MEM, j);
+			if (!res) {
+				dev_err(dev, "failed to get tcm resource\n");
+				return -EINVAL;
+			}
+
+			tcm->addr = (u32)res->start;
+			tcm->bank_name = (char *)res->name;
+			res = devm_request_mem_region(dev, tcm->addr, tcm->size,
+						      tcm->bank_name);
+			if (!res) {
+				dev_err(dev, "failed to request tcm resource\n");
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
 /**
  * zynqmp_r5_get_tcm_node()
  * Ideally this function should parse tcm node and store information
@@ -835,9 +932,14 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster,
 	struct zynqmp_r5_core *r5_core;
 	int ret, i;
 
-	ret = zynqmp_r5_get_tcm_node(cluster);
-	if (ret < 0) {
-		dev_err(dev, "can't get tcm node, err %d\n", ret);
+	r5_core = cluster->r5_cores[0];
+	if (of_find_property(r5_core->np, "reg", NULL))
+		ret = zynqmp_r5_get_tcm_node_from_dt(cluster);
+	else
+		ret = zynqmp_r5_get_tcm_node(cluster);
+
+	if (ret) {
+		dev_err(dev, "can't get tcm, err %d\n", ret);
 		return ret;
 	}
 
-- 
2.25.1



From broonie at kernel.org  Mon Feb 19 09:49:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 19 Feb 2024 17:49:53 +0000
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for
 WCN7850
In-Reply-To: <20240216203215.40870-15-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-15-brgl@bgdev.pl>
Message-ID: <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk>

On Fri, Feb 16, 2024 at 09:32:11PM +0100, Bartosz Golaszewski wrote:

> +static struct pci_pwrctl_wcn7850_vreg pci_pwrctl_wcn7850_vregs[] = {
> +	{
> +		.name = "vdd",
> +		.load_uA = 16000,
> +	},

I know a bunch of the QC stuff includes these load numbers but are they
actually doing anything constructive?  It keeps coming up that they're
causing a bunch of work and it's not clear that they have any great
effect on modern systems.

> +static int pci_pwrctl_wcn7850_power_on(struct pci_pwrctl_wcn7850_ctx *ctx)
> +{
> +	int ret;
> +
> +	ret = regulator_bulk_enable(ctx->pdata->num_vregs, ctx->regs);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(ctx->clk);
> +	if (ret)
> +		return ret;

This won't disable the regulators 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/20240219/26ebfd8c/attachment.sig>

From maz at kernel.org  Mon Feb 19 09:51:45 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 19 Feb 2024 17:51:45 +0000
Subject: [PATCH] irqchip/gic-v3: handle DOMAIN_BUS_ANY in gic_irq_domain_select
In-Reply-To: <CAA8EJprKUOMwrwawiQ51WKiLCipm72ZcpY6q520kSOg--9oKZg@mail.gmail.com>
References: <20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f@linaro.org>
	<868r3g4fhv.wl-maz@kernel.org>
	<CAA8EJpqiN6oRMWhAMMP6EsAeki5KSMbO+XzEtT9YRdJKc9_Gbg@mail.gmail.com>
	<865xyk4dgf.wl-maz@kernel.org>
	<CAA8EJprKUOMwrwawiQ51WKiLCipm72ZcpY6q520kSOg--9oKZg@mail.gmail.com>
Message-ID: <864je44a1a.wl-maz@kernel.org>

On Mon, 19 Feb 2024 17:41:37 +0000,
Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> 
> On Mon, 19 Feb 2024 at 18:37, Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Mon, 19 Feb 2024 16:21:06 +0000,
> > Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> > >
> > > On Mon, 19 Feb 2024 at 17:53, Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > On Mon, 19 Feb 2024 14:47:37 +0000,
> > > > Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> > > > >
> > > > > Before the commit de1ff306dcf4 ("genirq/irqdomain: Remove the param
> > > > > count restriction from select()") the irq_find_matching_fwspec() was
> > > > > handling the DOMAIN_BUS_ANY on its own. After this commit it is a job of
> > > > > the select() callback. However the callback of GICv3 (even though it got
> > > > > modified to handle zero param_count) wasn't prepared to return true for
> > > > > DOMAIN_BUS_ANY bus_token.
> > > > >
> > > > > This breaks probing of any of the child IRQ domains, since
> > > > > platform_irqchip_probe() uses irq_find_matching_host(par_np,
> > > > > DOMAIN_BUS_ANY) to check for the presence of the parent IRQ domain.
> > > > >
> > > > > Fixes: 151378251004 ("irqchip/gic-v3: Make gic_irq_domain_select() robust for zero parameter count")
> > > > > Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from select()")
> > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > > > > ---
> > > > >  drivers/irqchip/irq-gic-v3.c | 3 ++-
> > > > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > > > > index 6fb276504bcc..e9e9643c653f 100644
> > > > > --- a/drivers/irqchip/irq-gic-v3.c
> > > > > +++ b/drivers/irqchip/irq-gic-v3.c
> > > > > @@ -1696,7 +1696,8 @@ static int gic_irq_domain_select(struct irq_domain *d,
> > > > >
> > > > >       /* Handle pure domain searches */
> > > > >       if (!fwspec->param_count)
> > > > > -             return d->bus_token == bus_token;
> > > > > +             return d->bus_token == bus_token ||
> > > > > +                     bus_token == DOMAIN_BUS_ANY;
> > > > >
> > > > >       /* If this is not DT, then we have a single domain */
> > > > >       if (!is_of_node(fwspec->fwnode))
> > > > >
> > > >
> > > > I really dislike the look of this. If that's the case, any irqchip
> > > > that has a 'select' method (such as imx-intmux) should be similarly
> > > > hacked. And at this point, this should be handled by the core code.
> > > >
> > > > Can you try this instead? I don't have any HW that relies on
> > > > behaviour, but I'd expect this to work.
> > > >
> > > > Thanks,
> > > >
> > > >         M.
> > > >
> > > > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> > > > index aeb41655d6de..3dd1c871e091 100644
> > > > --- a/kernel/irq/irqdomain.c
> > > > +++ b/kernel/irq/irqdomain.c
> > > > @@ -449,7 +449,7 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
> > > >          */
> > > >         mutex_lock(&irq_domain_mutex);
> > > >         list_for_each_entry(h, &irq_domain_list, link) {
> > > > -               if (h->ops->select)
> > > > +               if (h->ops->select && bus_token != DOMAIN_BUS_ANY)
> > > >                         rc = h->ops->select(h, fwspec, bus_token);
> > > >                 else if (h->ops->match)
> > > >                         rc = h->ops->match(h, to_of_node(fwnode), bus_token);
> > >
> > > This works. But I wonder if the following change is even better. WDYT?
> > >
> > > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> > > index aeb41655d6de..2f0d2700709e 100644
> > > --- a/kernel/irq/irqdomain.c
> > > +++ b/kernel/irq/irqdomain.c
> > > @@ -449,14 +449,17 @@ struct irq_domain
> > > *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
> > >          */
> > >         mutex_lock(&irq_domain_mutex);
> > >         list_for_each_entry(h, &irq_domain_list, link) {
> > > -               if (h->ops->select)
> > > +               if (fwnode != NULL &&
> > > +                   h->fwnode == fwnode &&
> > > +                   bus_token == DOMAIN_BUS_ANY)
> > > +                       rc = true;
> > > +               else if (h->ops->select)
> > >                         rc = h->ops->select(h, fwspec, bus_token);
> > >                 else if (h->ops->match)
> > >                         rc = h->ops->match(h, to_of_node(fwnode), bus_token);
> > >                 else
> > >                         rc = ((fwnode != NULL) && (h->fwnode == fwnode) &&
> > > -                             ((bus_token == DOMAIN_BUS_ANY) ||
> > > -                              (h->bus_token == bus_token)));
> > > +                             (h->bus_token == bus_token));
> > >
> > >                 if (rc) {
> > >                         found = h;
> > >
> >
> > Can't say I like it either. It duplicates the existing check without
> > any obvious benefit. Honestly, this code is shit enough that we should
> > try to make it simpler, not more complex...
> 
> Only the fwnode conditions are duplicated. And it makes sense: we
> should check for the DOMAIN_BUS_ANY first, before going to select. I'm
> not sure whether at some point we'd have to add (&& bus_token !=
> DOMAIN_BUS_ANY) to the ops->match check.

ops->match should just *die*, and it is not going to see any sort of
semantic upgrade. Ever. No new code should be added using match.

And look at what my change does. It checks for DOMAIN_BUS_ANY before
doing anything else, ensuring that the default clause does the job. So
no, your suggestion doesn't make much sense to me.

	M.

-- 
Without deviation from the norm, progress is not possible.


From tanmay.shah at amd.com  Mon Feb 19 09:55:05 2024
From: tanmay.shah at amd.com (Tanmay Shah)
Date: Mon, 19 Feb 2024 11:55:05 -0600
Subject: [PATCH v11 0/4] add zynqmp TCM bindings
In-Reply-To: <20240219174437.3722620-6-tanmay.shah@amd.com>
References: <20240219174437.3722620-1-tanmay.shah@amd.com>
 <20240219174437.3722620-6-tanmay.shah@amd.com>
Message-ID: <0ceb2ba5-b595-483c-8a4a-2b64352871ed@amd.com>

Hello,

By mistake same set of patches were sent twice in same git send-email command.

Anyone can be reviewed. Please let me know if I need to take any action to fix it.

Thanks.

On 2/19/24 11:44 AM, Tanmay Shah wrote:
> Tightly-Coupled Memories(TCMs) are low-latency memory that provides
> predictable instruction execution and predictable data load/store
> timing. Each Cortex-R5F processor contains exclusive two 64 KB memory
> banks on the ATCM and BTCM ports, for a total of 128 KB of memory.
> In lockstep mode, both 128KB memory is accessible to the cluster.
>
> As per ZynqMP Ultrascale+ Technical Reference Manual UG1085, following
> is address space of TCM memory. The bindings in this patch series
> introduces properties to accommodate following address space with
> address translation between Linux and Cortex-R5 views.
>
> |     |     |     |
> | --- | --- | --- |
> |      *Mode*        |   *R5 View* | *Linux view* |  Notes               |
> | *Split Mode*       | *start addr*| *start addr* |                      |
> | R5_0 ATCM (64 KB)  | 0x0000_0000 | 0xFFE0_0000  |                      |
> | R5_0 BTCM (64 KB)  | 0x0002_0000 | 0xFFE2_0000  |                      |
> | R5_1 ATCM (64 KB)  | 0x0000_0000 | 0xFFE9_0000  | alias of 0xFFE1_0000 |
> | R5_1 BTCM (64 KB)  | 0x0002_0000 | 0xFFEB_0000  | alias of 0xFFE3_0000 |
> |  ___               |     ___     |    ___       |                      |
> | *Lockstep Mode*    |             |              |                      |
> | R5_0 ATCM (128 KB) | 0x0000_0000 | 0xFFE0_0000  |                      |
> | R5_0 BTCM (128 KB) | 0x0002_0000 | 0xFFE2_0000  |                      |
>
> References:
> UG1085 TCM address space:
> https://docs.xilinx.com/r/en-US/ug1085-zynq-ultrascale-trm/Tightly-Coupled-Memory-Address-Map
>
> Changes in v11:
>   - Fix yamllint warning and reduce indentation as needed
>   - Remove redundant initialization of the variable
>   - Return correct error code if memory allocation failed
>
> Changs in v10:
>   - Add new patch (1/4) to series that changes hardcode TCM addresses in
>     lockstep mode and removes separate handling of TCM in lockstep and
>     split mode
>   - modify number of "reg", "reg-names" and "power-domains" entries
>     based on cluster mode
>   - Add extra optional atcm and btcm in "reg" property for lockstep mode
>   - Add "reg-names" for extra optional atcm and btcm for lockstep mode
>   - Drop previous Ack as bindings has new change
>   - Add individual tcm regions via "reg" and "reg-names" for lockstep mode
>   - Add each tcm's power-domains in lockstep mode
>   - Drop previous Ack as new change in dts patchset
>   - Remove redundant changes in driver to handle TCM in lockstep mode
>
> Changes in v9:
>   - Fix rproc lockstep dts
>   - Introduce new API to request and release core1 TCM power-domains in
>     lockstep mode. This will be used during prepare -> add_tcm_banks
>     callback to enable TCM in lockstep mode.
>   - Parse TCM from device-tree in lockstep mode and split mode in
>     uniform way.
>   - Fix TCM representation in device-tree in lockstep mode.
>   - Fix comments as suggested
>
> Changes in v8:
>   - Remove use of pm_domains framework
>   - Remove checking of pm_domain_id validation to power on/off tcm
>   - Remove spurious change
>   - parse power-domains property from device-tree and use EEMI calls
>     to power on/off TCM instead of using pm domains framework
>
> Changes in v7:
>   - %s/pm_dev1/pm_dev_core0/r
>   - %s/pm_dev_link1/pm_dev_core0_link/r
>   - %s/pm_dev2/pm_dev_core1/r
>   - %s/pm_dev_link2/pm_dev_core1_link/r
>   - remove pm_domain_id check to move next patch
>   - add comment about how 1st entry in pm domain list is used
>   - fix loop when jump to fail_add_pm_domains loop
>   - move checking of pm_domain_id from previous patch
>   - fix mem_bank_data memory allocation
>
> Changes in v6:
>   - Introduce new node entry for r5f cluster split mode dts and
>     keep it disabled by default.
>   - Keep remoteproc lockstep mode enabled by default to maintian
>     back compatibility.
>   - Enable split mode only for zcu102 board to demo split mode use
>   - Remove spurious change
>   - Handle errors in add_pm_domains function
>   - Remove redundant code to handle errors from remove_pm_domains
>   - Missing . at the end of the commit message
>   - remove redundant initialization of variables
>   - remove fail_tcm label and relevant code to free memory
>     acquired using devm_* API. As this will be freed when device free it
>   - add extra check to see if "reg" property is supported or not
>
> Changes in v5:
>   - maintain Rob's Ack on bindings patch as no changes in bindings
>   - split previous patch into multiple patches
>   - Use pm domain framework to turn on/off TCM
>   - Add support of parsing TCM information from device-tree
>   - maintain backward compatibility with previous bindings without
>     TCM information available in device-tree
>
> This patch series continues previous effort to upstream ZynqMP
> TCM bindings:
> Previous v4 version link:
> https://lore.kernel.org/all/20230829181900.2561194-1-tanmay.shah at amd.com/
>
> Previous v3 version link:
> https://lore.kernel.org/all/1689964908-22371-1-git-send-email-radhey.shyam.pandey at amd.com/
> Radhey Shyam Pandey (1):
>   dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings
>
>
>
> Radhey Shyam Pandey (1):
>   dt-bindings: remoteproc: add Tightly Coupled Memory (TCM) bindings
>
> Tanmay Shah (3):
>   remoteproc: zynqmp: fix lockstep mode memory region
>   dts: zynqmp: add properties for TCM in remoteproc
>   remoteproc: zynqmp: parse TCM from device tree
>
>  .../remoteproc/xlnx,zynqmp-r5fss.yaml         | 192 +++++++++++--
>  .../boot/dts/xilinx/zynqmp-zcu102-rev1.0.dts  |   8 +
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  65 ++++-
>  drivers/remoteproc/xlnx_r5_remoteproc.c       | 257 ++++++++----------
>  4 files changed, 357 insertions(+), 165 deletions(-)
>
>
> base-commit: 929654e8f1add50b01d5a56171a31c311b0a739a


From broonie at kernel.org  Mon Feb 19 10:03:03 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 19 Feb 2024 18:03:03 +0000
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <20240216203215.40870-10-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-10-brgl@bgdev.pl>
Message-ID: <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk>

On Fri, Feb 16, 2024 at 09:32:06PM +0100, Bartosz Golaszewski wrote:

> +			vreg_pmu_aon_0p59: ldo1 {
> +				regulator-name = "vreg_pmu_aon_0p59";
> +				regulator-min-microvolt = <540000>;
> +				regulator-max-microvolt = <840000>;
> +			};

That's a *very* wide voltage range for a supply that's got a name ending
in _0_p59 which sounds a lot like it should be fixed at 0.59V.
Similarly for a bunch of the other supplies, and I'm not seeing any
evidence that the consumers do any voltage changes here?  There doesn't
appear to be any logic here, I'm not convinced these are validated or
safe constraints.
-------------- 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/20240219/bc7febb9/attachment.sig>

From mark.rutland at arm.com  Mon Feb 19 10:22:21 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 19 Feb 2024 18:22:21 +0000
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <dca5b082-90d1-40ab-954f-8b3b6f51138c@app.fastmail.com>
References: <20240206074552.541154-1-maskray@google.com>
 <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>
 <CAMj1kXGaF5bobHTr1pTg+-=s4Ft7+5SSbX72-NxsR_W_Yuxb8Q@mail.gmail.com>
 <CAMj1kXGw+r7yEEBA8gYBcdrqkiP=VYOSzz9YLnNavJn2snmFwA@mail.gmail.com>
 <CAMuHMdX+6fnAf8Hm6EqYJPAjrrLO9T7c=Gu3S8V_pqjSDowJ6g@mail.gmail.com>
 <CAMj1kXHh_m=V0QsiTpHrUXpFBXFbFfezdysz8quhPSgUrZg1MA@mail.gmail.com>
 <dca5b082-90d1-40ab-954f-8b3b6f51138c@app.fastmail.com>
Message-ID: <ZdOcXTvvHyl8s56I@FVFF77S0Q05N>

On Mon, Feb 19, 2024 at 06:06:19PM +0100, Arnd Bergmann wrote:
> On Mon, Feb 19, 2024, at 16:41, Ard Biesheuvel wrote:
> > On Mon, 19 Feb 2024 at 15:43, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> >> On Mon, Feb 19, 2024 at 11:57?AM Ard Biesheuvel <ardb at kernel.org> wrote:
> >> > On Mon, 19 Feb 2024 at 11:56, Ard Biesheuvel <ardb at kernel.org> wrote:
> 
> >> > https://godbolt.org/z/GTnf3vPaT
> >>
> >> I could reproduce the issue on v6.8-rc5 using arm64 defconfig
> >> and x86_64-gcc-5.5.0-nolibc-aarch64-linux.tar.xz from
> >> https://cdn.kernel.org/pub/tools/crosstool/files/bin/x86_64/5.5.0/:
> >>
> >
> > OK, I managed to do so as well.
> >
> > And GCC 6.4 from the same source works correctly.
> >
> > Not sure whether there are any plans to bump the minimal GCC version
> > any time soon (cc'ing Arnd), but we should probably drop this change
> > until that happens.
> 
> From what I can tell, we may as well formally raise the minimum
> gcc version to 8.1+ already, as that is a version that is
> actually used in distros, and we have been on 5.1+ for a few
> years already.
> 
> Not sure if there are any other benefits to gcc-8 besides
> allowing minor cleanups.

Arguably a minor cleanup, but on arm64 that'd allow us to get rid of the old
mcount-based ftrace implementation and rely on -fpatchable-function-entry.
On its own that'd save ~130 lines of asm and ~70 lines of C, but it'd also
remove some constraints on other features (e.g. the mcount-based form's graph
tracer isn't compatible with pointer authentication), it would simplify a few
things going forwards (e.g. the implementation of RELIABLE_STACKTRACE, since we
could rely on having ftrace_regs and a single trampoline), and the remaining
support would be better tested.

I've wanted to remove the old ftrace implementation for a while, but on its own
it was never important/urgent enough to justify bumping to GCC 8+.

Mark.


From fancer.lancer at gmail.com  Mon Feb 19 10:32:43 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Mon, 19 Feb 2024 21:32:43 +0300
Subject: [PATCH net-next v3 3/3] net: stmmac: Configure AXI on Tegra234
 MGBE
In-Reply-To: <20240219-stmmac-axi-config-v3-3-fca7f046e6ee@nvidia.com>
References: <20240219-stmmac-axi-config-v3-0-fca7f046e6ee@nvidia.com>
 <20240219-stmmac-axi-config-v3-3-fca7f046e6ee@nvidia.com>
Message-ID: <xne2i6jwqaptsrd2hjdahxbscysgtj7iabqendyjb75fnrjc5z@js7n7qngtzym>

On Mon, Feb 19, 2024 at 05:46:06PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding at nvidia.com>
> 
> Allow the device to use bursts and increase the maximum number of
> outstanding requests to improve performance. Measurements show an
> increase in throughput of around 5x on a 1 Gbps link.
> 
> Signed-off-by: Thierry Reding <treding at nvidia.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> index bab57d1675df..b6bfa48f279d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> @@ -199,6 +199,12 @@ static void mgbe_uphy_lane_bringup_serdes_down(struct net_device *ndev, void *mg
>  	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
>  }
>  
> +static const struct stmmac_axi tegra234_mgbe_axi = {
> +	.axi_wr_osr_lmt = 63,
> +	.axi_rd_osr_lmt = 63,
> +	.axi_blen = { 256, },
> +};
> +
>  static int tegra_mgbe_probe(struct platform_device *pdev)
>  {
>  	struct plat_stmmacenet_data *plat;
> @@ -284,6 +290,9 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
>  	if (err < 0)
>  		goto disable_clks;
>  
> +	/* setup default AXI configuration */
> +	res.axi = &tegra234_mgbe_axi;
> +
>  	plat = devm_stmmac_probe_config_dt(pdev, &res);
>  	if (IS_ERR(plat)) {
>  		err = PTR_ERR(plat);

Let's get back to the v2 discussion:

On Mon Feb 5, 2024 at 1:44 AM CET, Serge Semin wrote:
> The entire series can be converted to just a few lines of change:
>     plat = devm_stmmac_probe_config_dt(pdev, res.mac);
>     if (IS_ERR(plat)) {
>             err = PTR_ERR(plat);
>             goto disable_clks;
>     }
> +
> +   if (IS_ERR_OR_NULL(plat->axi)) {
> +           plat->axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
> +           if (!plat->axi) {
> +                   ret = -ENOMEM;
> +                   goto disable_clks;
> +           }
> +   } /* else memset plat->axi with zeros if you wish */
> +
> +   plat->axi->axi_wr_osr_lmt = 63;
> +   plat->axi->axi_rd_osr_lmt = 63;
> +   plat->axi->axi_blen[0] = 256;
>  
>     plat->has_xgmac = 1;
>     plat->flags |= STMMAC_FLAG_TSO_EN;
>     plat->pmt = 1;
>
> Please don't overcomplicate the already overcomplicated driver with a
> functionality which can be reached by the default one. In this case
> the easiest way is to let the generic code work and then
> override/replace/fix/etc the retrieved values. Thus there won't be
> need in adding the redundant functionality and keep the generic
> DT-platform code a bit simpler to read.

You responded with:

On Tue, Feb 13, 2024 at 04:51:34PM +0100, Thierry Reding wrote:
> I'm not sure I understand how this is overcomplicating things. The code
> is pretty much unchanged, except that the AXI configuration can now have
> driver-specified defaults before the DT is parsed. Perhaps I need to add
> comments to make that a bit clearer?
> 
> While your version is certainly simpler it has the drawback that it no
> longer allows the platform defaults to be overridden in device tree. I
> would prefer if the defaults can be derived from the compatible string
> but if need be for those defaults to still be overridable from device
> tree.

Currently available functionality is easier to read and understand: by
default the data is retrieved from the DT, if no AXI DT-node found you
can allocate/create your own AXI-configs, if there is AXI DT-node you
can fix it up in whatever way your wish. Thus the default behavior is
straightforward. You on the contrary suggest to add an additional
field to the resources structure which would need to be merged in with
the data retrieved from DT. It makes the stmmac_axi_setup() method and
the entire logic more complex and thus harder to comprehend. The
driver is already overwhelmed with flags and private/platform data
fixing the code here and there (see plat_stmmacenet_data, it's a
madness). So please justify in more details why do you need one more
complexity added instead of:
1. overriding the AXI-configs retrieved from DT,
2. updating DT on your platform
?

-Serge(y)

> 
> -- 
> 2.43.2
> 


From claudiu.beznea at tuxon.dev  Mon Feb 19 10:45:45 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Mon, 19 Feb 2024 20:45:45 +0200
Subject: [PATCH v3 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <20240216-eleven-exposure-dde558e63aaf@wendy>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
 <20240215091524.14732-3-mihai.sain@microchip.com>
 <20240215-lustily-flick-69cb48b123c3@spud>
 <PH8PR11MB6804E9353A8EEBD2B829D8B3824C2@PH8PR11MB6804.namprd11.prod.outlook.com>
 <20240216075609e58aeee4@mail.local>
 <cfafd563-1387-4775-bcb0-434ce3774827@tuxon.dev>
 <20240216-eleven-exposure-dde558e63aaf@wendy>
Message-ID: <0798f21e-1ab6-4fd2-b7e3-18f35163fad1@tuxon.dev>



On 16.02.2024 11:35, Conor Dooley wrote:
> On Fri, Feb 16, 2024 at 10:24:13AM +0200, claudiu beznea wrote:
>> On 16.02.2024 09:56, Alexandre Belloni wrote:
>>> On 16/02/2024 06:58:10+0000, Mihai.Sain at microchip.com wrote:
>>>>> diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
>>>>> index 269e0a3ca269..c030b318985a 100644
>>>>> --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
>>>>> +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
>>>>> @@ -958,6 +958,30 @@ i2c9: i2c at 600 {
>>>>>  			};
>>>>>  		};
>>>>>  
>>>>> +		flx10: flexcom at e2820000 {
>>>>> +			compatible = "atmel,sama5d2-flexcom";
>>>>
>>>> My comment here was ignored:
>>>> https://lore.kernel.org/all/20240214-robe-pregnancy-a1b056c9fe14 at spud/
>>>>
>>>> The SAMA7G5 has the same flexcom controller as SAMA5D2 MPU.
>>>>
>>>
>>> Still, it needs its own compatible plus a fallback to
>>> atmel,sama5d2-flexcom
>>
>> I agree with this. Though, flexcom documentation is subject to YAML
>> conversion (a patch has been re-posted these days [1] and *maybe* it will
>> be integrated this time). And there are multiple SoC DTs that need to be
>> updated with their own flexcom compatible (lan966x, sam9x60, sama7g5).
>>
>> To avoid conflicting with the work at [1] and postponing this series we may
>> do the update after the [1] is done.
>>
>> Let me know your thoughts. Either way is fine by me.
> 
> I'd be inclined to say that if we are gonna take a shortcut here, then
> this patch should add a specific compatible so that when the yaml
> conversion goes through you'll get a warning about this being
> undocumented rather than silence.

All the flexcom nodes from all flexcom capable SoCs (including SAMA7G5)
have the same compatible introduced by Mihai.

I don't like the idea of updating only the DTSes, either update all DTSes
and documentation or do it as it is already done (with sama5d2 compatible).

> 
> A resend on the flexcom patch is required though, the rebase was not
> done correctly, so maybe Balakrishnan could "atmel,sama7g5-flexcom"
> add with a fallback to "atmel,sama5d2-flexcom" while they're fixing
> it up?

I agree, and DTSes should also be updated along with documentation.

With this we can go forward with this patch and avoid conflicting with work
that is currently in progress for flexcom.

Thank you,
Claudiu Beznea

> 
> Cheers,
> Conor.


From brgl at bgdev.pl  Mon Feb 19 10:48:20 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 19 Feb 2024 19:48:20 +0100
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk>
Message-ID: <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>

On Mon, Feb 19, 2024 at 7:03?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Fri, Feb 16, 2024 at 09:32:06PM +0100, Bartosz Golaszewski wrote:
>
> > +                     vreg_pmu_aon_0p59: ldo1 {
> > +                             regulator-name = "vreg_pmu_aon_0p59";
> > +                             regulator-min-microvolt = <540000>;
> > +                             regulator-max-microvolt = <840000>;
> > +                     };
>
> That's a *very* wide voltage range for a supply that's got a name ending
> in _0_p59 which sounds a lot like it should be fixed at 0.59V.
> Similarly for a bunch of the other supplies, and I'm not seeing any
> evidence that the consumers do any voltage changes here?  There doesn't
> appear to be any logic here, I'm not convinced these are validated or
> safe constraints.

No, the users don't request any regulators (or rather: software
representations thereof) because - as per the cover letter - no
regulators are created by the PMU driver. This is what is physically
on the board - as the schematics and the datasheet define it. I took
the values from the docs verbatim. In C, we create a power sequencing
provider which doesn't use the regulator framework at all.

Bartosz


From oliver.upton at linux.dev  Mon Feb 19 10:58:05 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 19 Feb 2024 18:58:05 +0000
Subject: [PATCH 0/3] irqchip/gic-v3-its: Fix GICv4.1 initialization after kexec
Message-ID: <20240219185809.286724-1-oliver.upton@linux.dev>

Fix an issue with GICv4.1 redistributor initialization after kexec,
ensuring the vPE table gets reinstalled even if the kernel is using
preallocated LPI tables.

First patch is worthy of a backport back to the introduction of GICv4.1,
second two are intended to avoid these mess-ups in the future.

Tested by kexec'ing into a new kernel on a GICv4.1 system.

Oliver Upton (3):
  irqchip/gic-v3-its: Do not assume vPE tables are preallocated
  irqchip/gic-v3-its: Spin off GICv4 init into a separate function
  irqchip/gic-v3-its: Print the vPE table installed in redistributor

 drivers/irqchip/irq-gic-v3-its.c | 50 +++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 17 deletions(-)


base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
-- 
2.44.0.rc0.258.g7320e95886-goog



From oliver.upton at linux.dev  Mon Feb 19 10:58:06 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 19 Feb 2024 18:58:06 +0000
Subject: [PATCH 1/3] irqchip/gic-v3-its: Do not assume vPE tables are preallocated
In-Reply-To: <20240219185809.286724-1-oliver.upton@linux.dev>
References: <20240219185809.286724-1-oliver.upton@linux.dev>
Message-ID: <20240219185809.286724-2-oliver.upton@linux.dev>

We go through quite a bit of trouble to make sure we pick up any
preallocated LPI tables on the redistributors, as enabling LPIs is a
one-way switch. There is no such restriction for vLPIs, and for GICv4.1
we expect to allocate a new vPE table at boot.

This works as intended when initializing an ITS, however when setting up
a redistributor in its_cpu_init_lpis() the early return for preallocated
RD tables skips straight past GICv4 setup. This all comes to a head when
trying to kexec into a new kernel, as the new kernel silently fails to
set up GICv4, leading to a complete loss of SGIs and LPIs for KVM VMs
(ouch).

Slap a band-aid on the problem by ensuring its_cpu_init_lpis() always
initializes GICv4 on the way out, even if the other RD tables were
preallocated.

Cc: stable at vger.kernel.org
Fixes: 6479450f72c1 ("irqchip/gic-v4: Fix occasional VLPI drop")
Reported-by: George Cherian <gcherian at marvell.com>
Co-developed-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---

I debated a bit on the fixes tag between the blamed commit and commit
5e5168461c22 ("irqchip/gic-v4.1: VPE table (aka GICR_VPROPBASER)
allocation"), although it would appear GICv4 could be left in an unknown
state after kexec too.

 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index d097001c1e3e..0022852ce494 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -3172,6 +3172,7 @@ static void its_cpu_init_lpis(void)
 	val |= GICR_CTLR_ENABLE_LPIS;
 	writel_relaxed(val, rbase + GICR_CTLR);
 
+out:
 	if (gic_rdists->has_vlpis && !gic_rdists->has_rvpeid) {
 		void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
 
@@ -3207,7 +3208,6 @@ static void its_cpu_init_lpis(void)
 
 	/* Make sure the GIC has seen the above */
 	dsb(sy);
-out:
 	gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED;
 	pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n",
 		smp_processor_id(),
-- 
2.44.0.rc0.258.g7320e95886-goog



From oliver.upton at linux.dev  Mon Feb 19 10:58:07 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 19 Feb 2024 18:58:07 +0000
Subject: [PATCH 2/3] irqchip/gic-v3-its: Spin off GICv4 init into a separate function
In-Reply-To: <20240219185809.286724-1-oliver.upton@linux.dev>
References: <20240219185809.286724-1-oliver.upton@linux.dev>
Message-ID: <20240219185809.286724-3-oliver.upton@linux.dev>

Burying the GICv4 redistributor initialization into the routine for LPIs
is a bit confusing, and can lead to sillies where unexpected codepaths
may not fully initialize the RD.

Hoist it out of its_cpu_init_lpis() into a dedicated function.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 drivers/irqchip/irq-gic-v3-its.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 0022852ce494..63d1743f08cc 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -3173,8 +3173,25 @@ static void its_cpu_init_lpis(void)
 	writel_relaxed(val, rbase + GICR_CTLR);
 
 out:
-	if (gic_rdists->has_vlpis && !gic_rdists->has_rvpeid) {
+	/* Make sure the GIC has seen the above */
+	dsb(sy);
+	gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED;
+	pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n",
+		smp_processor_id(),
+		gic_data_rdist()->flags & RD_LOCAL_PENDTABLE_PREALLOCATED ?
+		"reserved" : "allocated",
+		&paddr);
+}
+
+static void its_cpu_init_vlpis(void)
+{
+	/* No vLPIs? No problem. */
+	if (!gic_rdists->has_vlpis)
+		return;
+
+	if (!gic_rdists->has_rvpeid) {
 		void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
+		u64 val;
 
 		/*
 		 * It's possible for CPU to receive VLPIs before it is
@@ -3193,7 +3210,8 @@ static void its_cpu_init_lpis(void)
 		 * ancient programming gets left in and has possibility of
 		 * corrupting memory.
 		 */
-		val = its_clear_vpend_valid(vlpi_base, 0, 0);
+		its_clear_vpend_valid(vlpi_base, 0, 0);
+		return;
 	}
 
 	if (allocate_vpe_l1_table()) {
@@ -3205,15 +3223,6 @@ static void its_cpu_init_lpis(void)
 		gic_rdists->has_rvpeid = false;
 		gic_rdists->has_vlpis = false;
 	}
-
-	/* Make sure the GIC has seen the above */
-	dsb(sy);
-	gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED;
-	pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n",
-		smp_processor_id(),
-		gic_data_rdist()->flags & RD_LOCAL_PENDTABLE_PREALLOCATED ?
-		"reserved" : "allocated",
-		&paddr);
 }
 
 static void its_cpu_init_collection(struct its_node *its)
@@ -5265,6 +5274,7 @@ int its_cpu_init(void)
 			return ret;
 
 		its_cpu_init_lpis();
+		its_cpu_init_vlpis();
 		its_cpu_init_collections();
 	}
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From oliver.upton at linux.dev  Mon Feb 19 10:58:08 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 19 Feb 2024 18:58:08 +0000
Subject: [PATCH 3/3] irqchip/gic-v3-its: Print the vPE table installed in redistributor
In-Reply-To: <20240219185809.286724-1-oliver.upton@linux.dev>
References: <20240219185809.286724-1-oliver.upton@linux.dev>
Message-ID: <20240219185809.286724-4-oliver.upton@linux.dev>

Hindsight is 20/20 of course, but the recent vPE table programming bug
could've been root caused a bit more quickly if we print the table
getting installed at every redistributor.

Promote to pr_info() and add some additional context, such as the
provenance of the installed vPE table.

Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
---
 drivers/irqchip/irq-gic-v3-its.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 63d1743f08cc..c3ef9665a2ad 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2835,7 +2835,8 @@ static int allocate_vpe_l1_table(void)
 	u64 val, gpsz, npg, pa;
 	unsigned int psz = SZ_64K;
 	unsigned int np, epp, esz;
-	struct page *page;
+	struct page *page = NULL;
+	bool from_its = false;
 
 	if (!gic_rdists->has_rvpeid)
 		return 0;
@@ -2865,8 +2866,10 @@ static int allocate_vpe_l1_table(void)
 		return -ENOMEM;
 
 	val = inherit_vpe_l1_table_from_its();
-	if (val & GICR_VPROPBASER_4_1_VALID)
+	if (val & GICR_VPROPBASER_4_1_VALID) {
+		from_its = true;
 		goto out;
+	}
 
 	/* First probe the page size */
 	val = FIELD_PREP(GICR_VPROPBASER_4_1_PAGE_SIZE, GIC_PAGE_SIZE_64K);
@@ -2945,9 +2948,12 @@ static int allocate_vpe_l1_table(void)
 	gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
 	cpumask_set_cpu(smp_processor_id(), gic_data_rdist()->vpe_table_mask);
 
-	pr_debug("CPU%d: VPROPBASER = %llx %*pbl\n",
-		 smp_processor_id(), val,
-		 cpumask_pr_args(gic_data_rdist()->vpe_table_mask));
+	pr_info("CPU%d: Using %s vPE table @%llx (%s)\n",
+		smp_processor_id(),
+		(val & GICR_VPROPBASER_4_1_INDIRECT) ? "indirect" : "direct",
+		val & GICR_VPROPBASER_4_1_ADDR,
+		(page) ? "allocated" :
+			 ((from_its) ? "inherited from ITS" : "inherited from RD"));
 
 	return 0;
 }
-- 
2.44.0.rc0.258.g7320e95886-goog



From sboyd at kernel.org  Mon Feb 19 11:08:27 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 19 Feb 2024 11:08:27 -0800
Subject: [PATCH] clk: constify the of_phandle_args argument of of_clk_provider
In-Reply-To: <02461595-16b3-4fea-a029-54190e10e6f5@linaro.org>
References: <20240208163710.512733-1-krzysztof.kozlowski@linaro.org> <38e7e80f61f7c67c984735cf55c3dfb3.sboyd@kernel.org> <02461595-16b3-4fea-a029-54190e10e6f5@linaro.org>
Message-ID: <e760847bd911671f1e364271888481fd.sboyd@kernel.org>

Quoting Krzysztof Kozlowski (2024-02-15 23:12:29)
> On 16/02/2024 00:12, Stephen Boyd wrote:
> > Quoting Krzysztof Kozlowski (2024-02-08 08:37:10)
> >> None of the implementations of the get() and get_hw() callbacks of
> >> "struct of_clk_provider" modify the contents of received of_phandle_args
> >> pointer.  They treat it as read-only variable used to find the clock to
> >> return.  Make obvious that implementations are not supposed to modify
> >> the of_phandle_args, by making it a pointer to const.
> >>
> >> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> >> ---
> > 
> > This will almost certainly break the build once it is merged to
> > linux-next. What's your plan to merge this?
> 
> First problem is that it might not apply... I prepared it on next to be
> sure all subsystems are updated.
> 
> The idea is to get reviews and acks and then:
> 1. Maybe it applies cleanly to your tree meaning there will be no
> conflicts with other trees,
> 2. If not, then I can keep rebasing it and it should be applied after rc1.
> 

The struct clk based version is probably not going to be used in any new
code. If you split the patch up and converted the struct clk based ones
first then that would probably apply without breaking anything, because
new code should only be using the struct clk_hw version.

The struct clk_hw version could be done in two steps. Introduce another
get_hw callback with the const signature, and then update the world to
use that callback, finally remove the old callback. We could call this
callback 'get_clk_hw'. This is probably more work than it's worth
though, but at least this way we don't have to worry about applying
after rc1.

Or perhaps we need to cast everything and use macros? It would be bad if
the callback actually did something with the clkspec and we cast it to
const, but your patch shows that nobody is doing that. We would get rid
of this macro garbage once everything is converted.

---8<---
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 2253c154a824..8e5ed16a97a0 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -4818,7 +4818,7 @@ struct of_clk_provider {
 	struct list_head link;
 
 	struct device_node *node;
-	struct clk *(*get)(struct of_phandle_args *clkspec, void *data);
+	struct clk *(*get)(const struct of_phandle_args *clkspec, void *data);
 	struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);
 	void *data;
 };
@@ -4880,8 +4880,8 @@ EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get);
  *
  * This function is *deprecated*. Use of_clk_add_hw_provider() instead.
  */
-int of_clk_add_provider(struct device_node *np,
-			struct clk *(*clk_src_get)(struct of_phandle_args *clkspec,
+int _of_clk_add_provider(struct device_node *np,
+			struct clk *(*clk_src_get)(const struct of_phandle_args *clkspec,
 						   void *data),
 			void *data)
 {
@@ -4914,7 +4914,7 @@ int of_clk_add_provider(struct device_node *np,
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(of_clk_add_provider);
+EXPORT_SYMBOL_GPL(_of_clk_add_provider);
 
 /**
  * of_clk_add_hw_provider() - Register a clock provider for a node
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 1293c38ddb7f..bfc660fa7c8f 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -1531,10 +1531,11 @@ struct clk_hw_onecell_data {
 	}
 
 #ifdef CONFIG_OF
-int of_clk_add_provider(struct device_node *np,
-			struct clk *(*clk_src_get)(struct of_phandle_args *args,
+int _of_clk_add_provider(struct device_node *np,
+			struct clk *(*clk_src_get)(const struct of_phandle_args *args,
 						   void *data),
 			void *data);
+
 int of_clk_add_hw_provider(struct device_node *np,
 			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
 						 void *data),
@@ -1559,8 +1560,8 @@ int of_clk_detect_critical(struct device_node *np, int index,
 
 #else /* !CONFIG_OF */
 
-static inline int of_clk_add_provider(struct device_node *np,
-			struct clk *(*clk_src_get)(struct of_phandle_args *args,
+static inline int _of_clk_add_provider(struct device_node *np,
+			struct clk *(*clk_src_get)(const struct of_phandle_args *args,
 						   void *data),
 			void *data)
 {
@@ -1614,6 +1615,12 @@ static inline int of_clk_detect_critical(struct device_node *np, int index,
 }
 #endif /* CONFIG_OF */
 
+typedef struct clk *(*clk_src_get_fn)(const struct of_phandle_args *args, void *data);
+
+#define of_clk_add_provider(np, get, data) ({				\
+		_of_clk_add_provider(np, (clk_src_get_fn)(get), data);		\
+})
+
 void clk_gate_restore_context(struct clk_hw *hw);
 
 #endif /* CLK_PROVIDER_H */


From dmitry.baryshkov at linaro.org  Mon Feb 19 11:28:32 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Mon, 19 Feb 2024 21:28:32 +0200
Subject: [PATCH] irqchip/gic-v3: handle DOMAIN_BUS_ANY in gic_irq_domain_select
In-Reply-To: <864je44a1a.wl-maz@kernel.org>
References: <20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f@linaro.org>
 <868r3g4fhv.wl-maz@kernel.org> <CAA8EJpqiN6oRMWhAMMP6EsAeki5KSMbO+XzEtT9YRdJKc9_Gbg@mail.gmail.com>
 <865xyk4dgf.wl-maz@kernel.org> <CAA8EJprKUOMwrwawiQ51WKiLCipm72ZcpY6q520kSOg--9oKZg@mail.gmail.com>
 <864je44a1a.wl-maz@kernel.org>
Message-ID: <CAA8EJppBemsbVsjPvzBK6wp8qDdB-mK_j6HG=sq=USs-zRUNHg@mail.gmail.com>

On Mon, 19 Feb 2024 at 19:51, Marc Zyngier <maz at kernel.org> wrote:
>
> On Mon, 19 Feb 2024 17:41:37 +0000,
> Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> >
> > On Mon, 19 Feb 2024 at 18:37, Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > On Mon, 19 Feb 2024 16:21:06 +0000,
> > > Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> > > >
> > > > On Mon, 19 Feb 2024 at 17:53, Marc Zyngier <maz at kernel.org> wrote:
> > > > >
> > > > > On Mon, 19 Feb 2024 14:47:37 +0000,
> > > > > Dmitry Baryshkov <dmitry.baryshkov at linaro.org> wrote:
> > > > > >
> > > > > > Before the commit de1ff306dcf4 ("genirq/irqdomain: Remove the param
> > > > > > count restriction from select()") the irq_find_matching_fwspec() was
> > > > > > handling the DOMAIN_BUS_ANY on its own. After this commit it is a job of
> > > > > > the select() callback. However the callback of GICv3 (even though it got
> > > > > > modified to handle zero param_count) wasn't prepared to return true for
> > > > > > DOMAIN_BUS_ANY bus_token.
> > > > > >
> > > > > > This breaks probing of any of the child IRQ domains, since
> > > > > > platform_irqchip_probe() uses irq_find_matching_host(par_np,
> > > > > > DOMAIN_BUS_ANY) to check for the presence of the parent IRQ domain.
> > > > > >
> > > > > > Fixes: 151378251004 ("irqchip/gic-v3: Make gic_irq_domain_select() robust for zero parameter count")
> > > > > > Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from select()")
> > > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> > > > > > ---
> > > > > >  drivers/irqchip/irq-gic-v3.c | 3 ++-
> > > > > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > > > >
> > > > > > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > > > > > index 6fb276504bcc..e9e9643c653f 100644
> > > > > > --- a/drivers/irqchip/irq-gic-v3.c
> > > > > > +++ b/drivers/irqchip/irq-gic-v3.c
> > > > > > @@ -1696,7 +1696,8 @@ static int gic_irq_domain_select(struct irq_domain *d,
> > > > > >
> > > > > >       /* Handle pure domain searches */
> > > > > >       if (!fwspec->param_count)
> > > > > > -             return d->bus_token == bus_token;
> > > > > > +             return d->bus_token == bus_token ||
> > > > > > +                     bus_token == DOMAIN_BUS_ANY;
> > > > > >
> > > > > >       /* If this is not DT, then we have a single domain */
> > > > > >       if (!is_of_node(fwspec->fwnode))
> > > > > >
> > > > >
> > > > > I really dislike the look of this. If that's the case, any irqchip
> > > > > that has a 'select' method (such as imx-intmux) should be similarly
> > > > > hacked. And at this point, this should be handled by the core code.
> > > > >
> > > > > Can you try this instead? I don't have any HW that relies on
> > > > > behaviour, but I'd expect this to work.
> > > > >
> > > > > Thanks,
> > > > >
> > > > >         M.
> > > > >
> > > > > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> > > > > index aeb41655d6de..3dd1c871e091 100644
> > > > > --- a/kernel/irq/irqdomain.c
> > > > > +++ b/kernel/irq/irqdomain.c
> > > > > @@ -449,7 +449,7 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
> > > > >          */
> > > > >         mutex_lock(&irq_domain_mutex);
> > > > >         list_for_each_entry(h, &irq_domain_list, link) {
> > > > > -               if (h->ops->select)
> > > > > +               if (h->ops->select && bus_token != DOMAIN_BUS_ANY)
> > > > >                         rc = h->ops->select(h, fwspec, bus_token);
> > > > >                 else if (h->ops->match)
> > > > >                         rc = h->ops->match(h, to_of_node(fwnode), bus_token);
> > > >
> > > > This works. But I wonder if the following change is even better. WDYT?
> > > >
> > > > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> > > > index aeb41655d6de..2f0d2700709e 100644
> > > > --- a/kernel/irq/irqdomain.c
> > > > +++ b/kernel/irq/irqdomain.c
> > > > @@ -449,14 +449,17 @@ struct irq_domain
> > > > *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
> > > >          */
> > > >         mutex_lock(&irq_domain_mutex);
> > > >         list_for_each_entry(h, &irq_domain_list, link) {
> > > > -               if (h->ops->select)
> > > > +               if (fwnode != NULL &&
> > > > +                   h->fwnode == fwnode &&
> > > > +                   bus_token == DOMAIN_BUS_ANY)
> > > > +                       rc = true;
> > > > +               else if (h->ops->select)
> > > >                         rc = h->ops->select(h, fwspec, bus_token);
> > > >                 else if (h->ops->match)
> > > >                         rc = h->ops->match(h, to_of_node(fwnode), bus_token);
> > > >                 else
> > > >                         rc = ((fwnode != NULL) && (h->fwnode == fwnode) &&
> > > > -                             ((bus_token == DOMAIN_BUS_ANY) ||
> > > > -                              (h->bus_token == bus_token)));
> > > > +                             (h->bus_token == bus_token));
> > > >
> > > >                 if (rc) {
> > > >                         found = h;
> > > >
> > >
> > > Can't say I like it either. It duplicates the existing check without
> > > any obvious benefit. Honestly, this code is shit enough that we should
> > > try to make it simpler, not more complex...
> >
> > Only the fwnode conditions are duplicated. And it makes sense: we
> > should check for the DOMAIN_BUS_ANY first, before going to select. I'm
> > not sure whether at some point we'd have to add (&& bus_token !=
> > DOMAIN_BUS_ANY) to the ops->match check.
>
> ops->match should just *die*, and it is not going to see any sort of
> semantic upgrade. Ever. No new code should be added using match.
>
> And look at what my change does. It checks for DOMAIN_BUS_ANY before
> doing anything else, ensuring that the default clause does the job. So
> no, your suggestion doesn't make much sense to me.

Yeah, I was worried about the DOMAIN_BUS_ANY vs match call. If that's
not an issue, your patch looks fine to me.

Please use 'Tested-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>'
with your patch.

>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.



-- 
With best wishes
Dmitry


From megi at xff.cz  Mon Feb 19 11:39:23 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Mon, 19 Feb 2024 20:39:23 +0100
Subject: [PATCH] drm: rockchip: Don't require MIPI DSI device when it's
 used for ISP
In-Reply-To: <7044f324-5a45-4a4c-a15e-86614e53acf0@rock-chips.com>
References: <20240217183941.1752463-1-megi@xff.cz>
 <4c66c084-5af6-43fb-a256-4746b2e00192@rock-chips.com>
 <bsc3lpdxvhy3ss2uja4do3jwvj43zbs7zhx4bzs2tryrakn7be@pt2qsyvryk73>
 <7044f324-5a45-4a4c-a15e-86614e53acf0@rock-chips.com>
Message-ID: <65qkkf7baecbcnemtabzup2nupd63obz4ewrhruk5frl2t3hwv@eqxm3tzgqcv6>

On Mon, Feb 19, 2024 at 11:02:01AM +0800, Andy Yan wrote:
> Hi Ondrej:
> 
> On 2/18/24 23:17, Ond?ej Jirman wrote:
> > Hi Andy,
> > 
> > On Sun, Feb 18, 2024 at 07:14:56PM +0800, Andy Yan wrote:
> > > Hi,
> > > 
> > > On 2/18/24 02:39, Ond?ej Jirman wrote:
> > > > From: Ondrej Jirman <megi at xff.cz>
> > > > 
> > > > On RK3399 one MIPI DSI device can be alternatively used with the ISP1,
> > > > to provide RX DPHY. When this is the case (ISP1 is enabled in device
> > > > tree), probe success of DRM is tied to probe success of ISP1 connected
> > > > camera sensor. This can fail if the user is able to killswitch the camera
> > > > power, like on Pinephone Pro.
> > > > 
> > > > Detect use of MIPI DSI controller by ISP, and don't include it in
> > > > component match list in that case.
> > > > 
> > > 
> > > Isn't this supposed to be taken care of within the dts?
> > > Since DPHY1 should exclusively used by MIPI DSI1 and ISP1, then if
> > > a device want to use ISP1, the DSI1 should be disabled in dts.
> > 
> > DSI1 can't be disabled, because it provides PHY device for ISP1 in this
> > scenario.
> > 
> > The problem is that in this scenario DRM keeps waiting for DSI1 device,
> > despite it just being used for PHY for ISP1 and not as a component for
> > rockchip DRM driver.
> 
> 
> Oh, get it.
> With a quick look, seems that Heiko has already take this scenario into consideration
> when add PHY function in the dsi drivers[0]
> Does this mean the current drivers does not work as expected?

It didn't work anymore since some fw devlink changes that were added some
time after 2021. But it might have got resolved since than.

So please ignore this patch for now.

kind regards,
	o.

> [0]https://patchwork.freedesktop.org/patch/420386/
> > 
> > See:
> > 
> >          isp1: isp1 at ff920000 {
> >                  compatible = "rockchip,rk3399-cif-isp";
> >                  reg = <0x0 0xff920000 0x0 0x4000>;
> >                  interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH 0>;
> >                  clocks = <&cru SCLK_ISP1>,
> >                           <&cru ACLK_ISP1_WRAPPER>,
> >                           <&cru HCLK_ISP1_WRAPPER>;
> >                  clock-names = "isp", "aclk", "hclk";
> >                  iommus = <&isp1_mmu>;
> >                  phys = <&mipi_dsi1>;  <---------
> >                  phy-names = "dphy";
> >                  power-domains = <&power RK3399_PD_ISP1>;
> >                  status = "disabled";
> > 
> > If mipi_dsi1 is disabled, isp1 will never probe.
> > 
> > It's a consequence of this special dual use of mipi_dsi1.
> > 
> > kind regards,
> > 	o.
> > 
> > > > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > > > ---
> > > >    drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 47 +++++++++++++++++++++
> > > >    1 file changed, 47 insertions(+)
> > > > 
> > > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > > > index ab55d7132550..f47de94ad576 100644
> > > > --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > > > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > > > @@ -354,6 +354,43 @@ static void rockchip_drm_match_remove(struct device *dev)
> > > >    		device_link_del(link);
> > > >    }
> > > > +/*
> > > > + * Check if ISP block linked to a mipi-dsi device via phys phandle is
> > > > + * enabled in device tree.
> > > > + */
> > > > +static bool rockchip_drm_is_mipi1_and_used_by_isp(struct device *dev)
> > > > +{
> > > > +	struct device_node *np = NULL, *phy_np;
> > > > +
> > > > +	if (!of_device_is_compatible(dev->of_node, "rockchip,rk3399-mipi-dsi"))
> > > > +		return false;
> > > > +
> > > > +	while (true) {
> > > > +		np = of_find_compatible_node(np, NULL, "rockchip,rk3399-cif-isp");
> > > > +		if (!np)
> > > > +			break;
> > > > +
> > > > +		if (!of_device_is_available(np)) {
> > > > +			of_node_put(np);
> > > > +			continue;
> > > > +		}
> > > > +
> > > > +		phy_np = of_parse_phandle(np, "phys", 0);
> > > > +		if (!phy_np) {
> > > > +			of_node_put(np);
> > > > +			continue;
> > > > +		}
> > > > +
> > > > +		of_node_put(phy_np);
> > > > +		of_node_put(np);
> > > > +
> > > > +		if (phy_np == dev->of_node)
> > > > +			return true;
> > > > +	}
> > > > +
> > > > +	return false;
> > > > +}
> > > > +
> > > >    static struct component_match *rockchip_drm_match_add(struct device *dev)
> > > >    {
> > > >    	struct component_match *match = NULL;
> > > > @@ -371,6 +408,16 @@ static struct component_match *rockchip_drm_match_add(struct device *dev)
> > > >    			if (!d)
> > > >    				break;
> > > > +			/*
> > > > +			 * If mipi1 is connected to ISP, we don't want to wait for mipi1 component,
> > > > +			 * because it will not be used by DRM anyway, to not tie success of camera
> > > > +			 * driver probe to display pipeline initialization.
> > > > +			 */
> > > > +			if (rockchip_drm_is_mipi1_and_used_by_isp(d)) {
> > > > +				dev_info(d, "used by ISP1, skipping from DRM\n");
> > > > +				continue;
> > > > +			}
> > > > +
> > > >    			device_link_add(dev, d, DL_FLAG_STATELESS);
> > > >    			component_match_add(dev, &match, component_compare_dev, d);
> > > >    		} while (true);


From kuba at kernel.org  Mon Feb 19 11:44:43 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 19 Feb 2024 11:44:43 -0800
Subject: [PATCH v2 2/4] dt-bindings: net: fec: add iommus property
In-Reply-To: <668c1511-4ee6-4fad-9b7e-7783b6853988@linaro.org>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
	<20240201-8qm_smmu-v2-2-3d12a80201a3@nxp.com>
	<49dbd0a2-a4b9-4c05-bb10-44f267672374@linaro.org>
	<Zc+2EitZrVzLsA03@lizhi-Precision-Tower-5810>
	<668c1511-4ee6-4fad-9b7e-7783b6853988@linaro.org>
Message-ID: <20240219114443.777fc3b3@kernel.org>

On Sat, 17 Feb 2024 09:18:33 +0100 Krzysztof Kozlowski wrote:
> >> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>  
> > 
> > Other 3 patches already been linux-next. Who will pick this one?  
> 
> Resend it to net-next (with proper title).

I happened to notice the discussion, let me take the v2. Thanks!


From peter.griffin at linaro.org  Mon Feb 19 11:47:35 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 19 Feb 2024 19:47:35 +0000
Subject: [PATCH v4 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <ab1f9285-73ba-4b69-8882-0cf08c508e28@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org>
 <20240208161700.268570-2-peter.griffin@linaro.org> <ab1f9285-73ba-4b69-8882-0cf08c508e28@linaro.org>
Message-ID: <CADrjBPqw9E5foNvZ-ETFZR3mb8=x8CYHz3UUhfJUbBpOi3iKYw@mail.gmail.com>

Hi Krzysztof,

Thanks for the review. I was OoO last week so just getting to this now.

On Thu, 15 Feb 2024 at 18:36, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 08/02/2024 17:16, Peter Griffin wrote:
> > Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> > security hardening reasons so that they are only write accessible in el3
> > via an SMC call.
> >
> > As most Exynos drivers that need to write PMU registers currently obtain a
> > regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> > is implemented in this driver using a custom regmap similar to syscon to
> > handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> > regmap like before. As regmaps abstract out the underlying register access
> > changes to the leaf drivers are minimal.
> >
> > A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> > that currently use syscon_regmap_lookup_by_phandle(). This also handles
> > deferred probing.
>
> I found an issue, which needs new version, so I also found few more nits.
>
> >
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > ---
> > Changes since v3:
> >  - Fix PMUALIVE_MASK
> >  - Add TENSOR_ prefix
> >  - clear SET_BITS bits on each loop iteration
> >  - change set_bit to set_bits in func name
> >  - Fix some alignment
> >  - Add missing return on dev_err_probe
> >  - Reduce indentation in loop
> >
> > Changes since v2
> >  - Add select REGMAP to Kconfig
> >  - Add constant for SET/CLEAR bits
> >  - Replace kerneldoc with one line comment
> >  - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
> >  - remove superfluous extern keyword
> >  - dev_err_probe() on probe error
> >  - shorten regmcfg name
> >  - no compatibles inside probe, use match data
> >  - don't mix declarations with/without initializations
> >  - tensor_sec_reg_read() use mmio to avoid access restrictions
> >  - Collect up Reviewed-by
> >  - const for regmap_config structs
> > ---
> >  drivers/soc/samsung/Kconfig            |   1 +
> >  drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
> >  drivers/soc/samsung/exynos-pmu.h       |   1 +
> >  include/linux/soc/samsung/exynos-pmu.h |  11 +-
> >  4 files changed, 243 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> > index 27ec99af77e3..1a5dfdc978dc 100644
> > --- a/drivers/soc/samsung/Kconfig
> > +++ b/drivers/soc/samsung/Kconfig
> > @@ -42,6 +42,7 @@ config EXYNOS_PMU
> >       depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
> >       select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
> >       select MFD_CORE
> > +     select REGMAP_MMIO
> >
> >  # There is no need to enable these drivers for ARMv8
> >  config EXYNOS_PMU_ARM_DRIVERS
> > diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> > index 250537d7cfd6..b846e343fcdd 100644
> > --- a/drivers/soc/samsung/exynos-pmu.c
> > +++ b/drivers/soc/samsung/exynos-pmu.c
> > @@ -5,6 +5,7 @@
> >  //
> >  // Exynos - CPU PMU(Power Management Unit) support
> >
> > +#include <linux/arm-smccc.h>
> >  #include <linux/of.h>
> >  #include <linux/of_address.h>
> >  #include <linux/mfd/core.h>
> > @@ -12,19 +13,132 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/delay.h>
> > +#include <linux/regmap.h>
> >
> >  #include <linux/soc/samsung/exynos-regs-pmu.h>
> >  #include <linux/soc/samsung/exynos-pmu.h>
> >
> >  #include "exynos-pmu.h"
> >
> > +#define PMUALIVE_MASK                        GENMASK(13, 0)
> > +#define TENSOR_SET_BITS                      (BIT(15) | BIT(14))
> > +#define TENSOR_CLR_BITS                      BIT(15)
> > +#define TENSOR_SMC_PMU_SEC_REG               0x82000504
> > +#define TENSOR_PMUREG_READ           0
> > +#define TENSOR_PMUREG_WRITE          1
> > +#define TENSOR_PMUREG_RMW            2
> > +
> >  struct exynos_pmu_context {
> >       struct device *dev;
> >       const struct exynos_pmu_data *pmu_data;
> > +     struct regmap *pmureg;
> >  };
> >
> >  void __iomem *pmu_base_addr;
> >  static struct exynos_pmu_context *pmu_context;
> > +/* forward declaration */
> > +static struct platform_driver exynos_pmu_driver;
> > +
> > +/*
> > + * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
> > + * from EL3, but are still read accessible. As Linux needs to write some of
> > + * these registers, the following functions are provided and exposed via
> > + * regmap.
> > + *
> > + * Note: This SMC interface is known to be implemented on gs101 and derivative
> > + * SoCs.
> > + */
> > +
> > +/* Write to a protected PMU register. */
> > +static int tensor_sec_reg_write(void *base, unsigned int reg, unsigned int val)
>
> Please use the same argument names in all these regmap functions as in
> struct regmap_config, so base->context

Will fix.

>
> > +{
> > +     struct arm_smccc_res res;
> > +     unsigned long pmu_base = (unsigned long)base;
> > +
> > +     arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> > +                   TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
> > +
> > +     /* returns -EINVAL if access isn't allowed or 0 */
> > +     if (res.a0)
> > +             pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> > +
> > +     return (int)res.a0;
> > +}
> > +
> > +/* Read/Modify/Write a protected PMU register. */
> > +static int tensor_sec_reg_rmw(void *base, unsigned int reg,
> > +                           unsigned int mask, unsigned int val)
> > +{
> > +     struct arm_smccc_res res;
> > +     unsigned long pmu_base = (unsigned long)base;
> > +
> > +     arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> > +                   TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
> > +
> > +     /* returns -EINVAL if access isn't allowed or 0 */
> > +     if (res.a0)
> > +             pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> > +
> > +     return (int)res.a0;
> > +}
> > +
> > +/*
> > + * Read a protected PMU register. All PMU registers can be read by Linux.
> > + * Note: The SMC read register is not used, as only registers that can be
> > + * written are readable via SMC.
> > + */
> > +static int tensor_sec_reg_read(void *base, unsigned int reg, unsigned int *val)
> > +{
> > +     *val = pmu_raw_readl(reg);
> > +     return 0;
> > +}
> > +
> > +/*
> > + * For SoCs that have set/clear bit hardware this function can be used when
> > + * the PMU register will be accessed by multiple masters.
> > + *
> > + * For example, to set bits 13:8 in PMU reg offset 0x3e80
> > + * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00);
> > + *
> > + * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80
> > + * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00);
> > + */
> > +static inline int tensor_set_bits_atomic(void *ctx, unsigned int offset,
>
> Usual practice is to rely on compiler to inline, so let's drop the
> keyword here.

Will fix

>
> > +                                      u32 val, u32 mask)
> > +{
> > +     int ret;
> > +     unsigned int i;
> > +
> > +     for (i = 0; i < 32; i++) {
> > +             if (!(mask & BIT(i)))
> > +                     continue;
> > +
> > +             offset &= ~TENSOR_SET_BITS;
> > +
> > +             if (val & BIT(i))
> > +                     offset |= TENSOR_SET_BITS;
> > +             else
> > +                     offset |= TENSOR_CLR_BITS;
> > +
> > +             ret = tensor_sec_reg_write(ctx, offset, i);
> > +             if (ret)
> > +                     return ret;
> > +     }
> > +     return ret;
> > +}
> > +
> > +static int tensor_sec_update_bits(void *ctx, unsigned int reg,
> > +                               unsigned int mask, unsigned int val)
> > +{
> > +     /*
> > +      * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
> > +      * as the target registers can be accessed by multiple masters.
> > +      */
> > +     if (reg > PMUALIVE_MASK)
> > +             return tensor_sec_reg_rmw(ctx, reg, mask, val);
> > +
> > +     return tensor_set_bits_atomic(ctx, reg, val, mask);
> > +}
> >
> >  void pmu_raw_writel(u32 val, u32 offset)
> >  {
> > @@ -75,11 +189,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
> >  #define exynos_pmu_data_arm_ptr(data)        NULL
> >  #endif
> >
> > +static const struct regmap_config regmap_smccfg = {
> > +     .name = "pmu_regs",
> > +     .reg_bits = 32,
> > +     .reg_stride = 4,
> > +     .val_bits = 32,
> > +     .fast_io = true,
> > +     .use_single_read = true,
> > +     .use_single_write = true,
> > +     .reg_read = tensor_sec_reg_read,
> > +     .reg_write = tensor_sec_reg_write,
> > +     .reg_update_bits = tensor_sec_update_bits,
>
> > +};
> > +
> > +static const struct regmap_config regmap_mmiocfg = {
> > +     .name = "pmu_regs",
> > +     .reg_bits = 32,
> > +     .reg_stride = 4,
> > +     .val_bits = 32,
> > +     .fast_io = true,
> > +     .use_single_read = true,
> > +     .use_single_write = true,
> > +};
> > +
> > +static const struct exynos_pmu_data gs101_pmu_data = {
> > +     .pmu_secure = true
> > +};
> > +
> >  /*
> >   * PMU platform driver and devicetree bindings.
> >   */
> >  static const struct of_device_id exynos_pmu_of_device_ids[] = {
> >       {
> > +             .compatible = "google,gs101-pmu",
> > +             .data = &gs101_pmu_data,
> > +     }, {
> >               .compatible = "samsung,exynos3250-pmu",
> >               .data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
> >       }, {
> > @@ -113,19 +257,73 @@ static const struct mfd_cell exynos_pmu_devs[] = {
> >       { .name = "exynos-clkout", },
> >  };
> >
> > +/**
> > + * exynos_get_pmu_regmap() - Obtain pmureg regmap
> > + *
> > + * Find the pmureg regmap previously configured in probe() and return regmap
> > + * pointer.
> > + *
> > + * Return: A pointer to regmap if found or ERR_PTR error value.
> > + */
> >  struct regmap *exynos_get_pmu_regmap(void)
> >  {
> >       struct device_node *np = of_find_matching_node(NULL,
> >                                                     exynos_pmu_of_device_ids);
> >       if (np)
> > -             return syscon_node_to_regmap(np);
> > +             return exynos_get_pmu_regmap_by_phandle(np, NULL);
> >       return ERR_PTR(-ENODEV);
> >  }
> >  EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
> >
> > +/**
> > + * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
> > + * @np: Pointer to device's Device Tree node
>
> A bit unusual naming... drop "Device Tree" anywhere here. This is:
> "device node holding PMU phandle property"

Will fix

>
>
> > + * @property: Device Tree property name which references the pmu
>
> Name of property holding a phandle value

Will fix

>
> > + *
> > + * Find the pmureg regmap previously configured in probe() and return regmap
> > + * pointer.
> > + *
> > + * Return: A pointer to regmap if found or ERR_PTR error value.
> > + */
> > +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> > +                                             const char *property)
>
> property -> propname

Will fix

>
> > +{
> > +     struct device *dev;
> > +     struct exynos_pmu_context *ctx;
> > +     struct device_node *pmu_np;
>
> Reversed christmass tree.

Will fix

>
> > +
> > +     if (property)
> > +             pmu_np = of_parse_phandle(np, property, 0);
> > +     else
> > +             pmu_np = np;
> > +
> > +     if (!pmu_np)
> > +             return ERR_PTR(-ENODEV);
> > +
> > +     /*
> > +      * Determine if exynos-pmu device has probed and therefore regmap
> > +      * has been created and can be returned to the caller. Otherwise we
> > +      * return -EPROBE_DEFER.
> > +      */
> > +     dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
> > +                                         (void *)pmu_np);
> > +
> > +     of_node_put(pmu_np);
>
> You are dropping now referencen from np when property==NULL. This does
> no look right.

Good spot, will fix. It seems syscon.c and altera-sysmgr also have the
same issue.

>
> > +     if (!dev)
> > +             return ERR_PTR(-EPROBE_DEFER);
> > +
> > +     ctx = dev_get_drvdata(dev);
> > +
> > +     return ctx->pmureg;
> > +}
> > +EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
> > +
> >  static int exynos_pmu_probe(struct platform_device *pdev)
> >  {
> >       struct device *dev = &pdev->dev;
> > +     struct regmap_config pmu_regmcfg;
> > +     struct regmap *regmap;
> > +     struct resource *res;
> >       int ret;
> >
> >       pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
> > @@ -133,13 +331,42 @@ static int exynos_pmu_probe(struct platform_device *pdev)
> >               return PTR_ERR(pmu_base_addr);
> >
> >       pmu_context = devm_kzalloc(&pdev->dev,
> > -                     sizeof(struct exynos_pmu_context),
> > -                     GFP_KERNEL);
> > +                                sizeof(struct exynos_pmu_context),
> > +                                GFP_KERNEL);
>
> Not related here. You could have separate patch for cleanups or just
> skip such change.

Will remove.

kind regards,

Peter.


From aweber.kernel at gmail.com  Mon Feb 19 11:49:46 2024
From: aweber.kernel at gmail.com (Artur Weber)
Date: Mon, 19 Feb 2024 20:49:46 +0100
Subject: [PATCH] ARM: dts: exynos4212-tab3: limit usable memory range
In-Reply-To: <15ab6aa6-fb30-4970-9c50-546afb933e03@linaro.org>
References: <20240217-tab3-limit-usable-memory-range-v1-1-49cc9c86a5cc@gmail.com>
 <15ab6aa6-fb30-4970-9c50-546afb933e03@linaro.org>
Message-ID: <c2fde69d-48c2-446f-ac56-876651c06b51@gmail.com>

On 19.02.2024 08:44, Krzysztof Kozlowski wrote:
> On 17/02/2024 20:02, Artur Weber wrote:
>> The stock bootloader on the Samsung Galaxy Tab 3 8.0 provides an
>> incorrect available memory range over ATAG_MEM. Limit the usable
>> memory in the DTS to prevent it from doing so, without having to
>> disable ATAG support.
>>
>> Signed-off-by: Artur Weber <aweber.kernel at gmail.com>
>> ---
>>   arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi | 6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
>> index e5254e32aa8f..9bc05961577d 100644
>> --- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
>> +++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
>> @@ -45,6 +45,12 @@ chosen {
>>   		/* Default S-BOOT bootloader loads initramfs here */
>>   		linux,initrd-start = <0x42000000>;
>>   		linux,initrd-end = <0x42800000>;
>> +
>> +		/*
>> +		 * Stock bootloader provides incorrect memory size in ATAG_MEM;
>> +		 * override it here
>> +		 */
>> +		linux,usable-memory-range = <0x40000000 0x3fc00000>;
> 
> Applied and dropped:
>   chosen: linux,usable-memory-range:0: [4611686019496935424] is too short

This seems to be a binding issue; the DT schema expects a 64-bit memory 
address and size, and doesn't allow a 32-bit range. I've tested the DTS 
on my device and this property seems to be handled fine, so I think this 
should allow 32-bit values as well.

I've opened a PR[1] against devicetree-org/dt-schema (where the schema 
for the chosen node is stored) to try and fix this. If my approach is 
incorrect, feel free to comment there as well.

Best regards
Artur

[1] https://github.com/devicetree-org/dt-schema/pull/128

> 
> Does not look you tested the bindings.
> 
> Please observe that we have dedicated subsystem profile since a release:
> https://www.kernel.org/doc/html/latest/process/maintainers.html#arm-samsung-s3c-s5p-and-exynos-arm-architectures
> 
> Best regards,
> Krzysztof
> 



From patchwork-bot+netdevbpf at kernel.org  Mon Feb 19 11:50:26 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Mon, 19 Feb 2024 19:50:26 +0000
Subject: [PATCH v2 0/4] Add 8qm SMMU information
In-Reply-To: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
Message-ID: <170837222679.28614.9914346623954739776.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Thu, 01 Feb 2024 15:22:40 -0500 you wrote:
> Change at v2
> - Remove iM95 for fec.
> 
> To: Ulf Hansson <ulf.hansson at linaro.org>
> To: Rob Herring <robh+dt at kernel.org>
> To: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> To: Conor Dooley <conor+dt at kernel.org>
> To: Shawn Guo <shawnguo at kernel.org>
> To: Sascha Hauer <s.hauer at pengutronix.de>
> To: Pengutronix Kernel Team <kernel at pengutronix.de>
> To: Fabio Estevam <festevam at gmail.com>
> To: NXP Linux Team <linux-imx at nxp.com>
> To: Wei Fang <wei.fang at nxp.com>
> To: Shenwei Wang <shenwei.wang at nxp.com>
> To: Clark Wang <xiaoning.wang at nxp.com>
> To: David S. Miller <davem at davemloft.net>
> To: Eric Dumazet <edumazet at google.com>
> To: Jakub Kicinski <kuba at kernel.org>
> To: Paolo Abeni <pabeni at redhat.com>
> Cc: linux-mmc at vger.kernel.org
> Cc: devicetree at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: netdev at vger.kernel.org
> Cc: imx at lists.linux.dev
> 
> [...]

Here is the summary with links:
  - [v2,1/4] dt-bindings: mmc: fsl-imx-esdhc: add iommus property
    (no matching commit)
  - [v2,2/4] dt-bindings: net: fec: add iommus property
    https://git.kernel.org/netdev/net-next/c/5983e5df8630
  - [v2,3/4] arm64: dts: imx8qm: add smmu node
    (no matching commit)
  - [v2,4/4] arm64: dts: imx8qm: add smmu stream id information
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From David.Laight at ACULAB.COM  Mon Feb 19 11:53:15 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Mon, 19 Feb 2024 19:53:15 +0000
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <fharyfc7fnh45dthgd2ehwsgdqzmdfptp7jw7gi5ahb6slwgf6@nrkhlhvbbzx7>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
 <ZdMe24xN1Ej4QoVU@shell.armlinux.org.uk>
 <xs2splnjhlj257uca5yae64fp4solc4ugbxrkczoyd75n42r66@42boyzdcmyj4>
 <ZdMkyPX/h9s8xht5@shell.armlinux.org.uk>
 <fharyfc7fnh45dthgd2ehwsgdqzmdfptp7jw7gi5ahb6slwgf6@nrkhlhvbbzx7>
Message-ID: <ff0164553d6f486f97643eae8235cc5f@AcuMS.aculab.com>

...
> I'm not always trying to write code that will generate the fastest
> assembly possible; there aro other considerations. As long a the
> compiler is doing something /reasonable/, the code is fine.

Speaks the man who was writing horrid 'jit' code ...

This also begs the question of why that data is so compressed
in the first place?
It is quite likely that a few accesses generate far more code
than the data you are attempting to save.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From peter.griffin at linaro.org  Mon Feb 19 11:55:39 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 19 Feb 2024 19:55:39 +0000
Subject: [PATCH] MAINTAINERS: samsung: gs101: match patches touching
 Google Tensor SoC
In-Reply-To: <20240219125453.103692-1-krzysztof.kozlowski@linaro.org>
References: <20240219125453.103692-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CADrjBPq1X2P7hTqSiTnZ03c_QguTQ4kbFen9MeWh5TaYn9fh-A@mail.gmail.com>

Hi Krzysztof,

On Mon, 19 Feb 2024 at 12:54, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> Maintainers of Google Tensor SoC should be aware of all driver patches
> having that name.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>
> ---
>
> This allows to spot easier such weird drivers (weird because they claim they are
> for hardware, but they omit entirely hardware part) like:
> https://lore.kernel.org/all/20240219061008.1761102-3-pumahsu at google.com/
> ---

Thanks for this, I hadn't seen the series you referenced above.

Reviewed-by: Peter Griffin <peter.griffin at linaro.org>


From broonie at kernel.org  Mon Feb 19 11:59:46 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 19 Feb 2024 19:59:46 +0000
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk>
 <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
Message-ID: <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk>

On Mon, Feb 19, 2024 at 07:48:20PM +0100, Bartosz Golaszewski wrote:
> On Mon, Feb 19, 2024 at 7:03?PM Mark Brown <broonie at kernel.org> wrote:
> > On Fri, Feb 16, 2024 at 09:32:06PM +0100, Bartosz Golaszewski wrote:

> > > +                     vreg_pmu_aon_0p59: ldo1 {
> > > +                             regulator-name = "vreg_pmu_aon_0p59";
> > > +                             regulator-min-microvolt = <540000>;
> > > +                             regulator-max-microvolt = <840000>;
> > > +                     };

> > That's a *very* wide voltage range for a supply that's got a name ending
> > in _0_p59 which sounds a lot like it should be fixed at 0.59V.
> > Similarly for a bunch of the other supplies, and I'm not seeing any
> > evidence that the consumers do any voltage changes here?  There doesn't
> > appear to be any logic here, I'm not convinced these are validated or
> > safe constraints.

> No, the users don't request any regulators (or rather: software
> representations thereof) because - as per the cover letter - no
> regulators are created by the PMU driver. This is what is physically
> on the board - as the schematics and the datasheet define it. I took

The above makes no sense.  How can constraints be "what is physically on
the board", particularly variable constrants when there isn't even a
consumer?  What values are you taking from which documentation?  

The cover letter and binding both claimed (buried after large amounts of
changelog) that these PMUs were exposing regulators to consumers and the
DTS puports to do exactly that...

> the values from the docs verbatim. In C, we create a power sequencing
> provider which doesn't use the regulator framework at all.

For something that doesn't use the regulator framework at all what
appears to be a provider in patch 16 ("power: pwrseq: add a driver for
the QCA6390 PMU module") seems to have a lot of regualtor API calls?
-------------- 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/20240219/02cafd6f/attachment.sig>

From f.fainelli at gmail.com  Mon Feb 19 12:17:35 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Mon, 19 Feb 2024 12:17:35 -0800
Subject: [PATCH] net: stmmac: mmc_core: Assign, don't add interrupt
 registers
In-Reply-To: <20240219104025.GM22484@axis.com>
References: <20240216-stmmac_stats-v1-1-7065fa4613f8@axis.com>
 <61bdd802-abe4-4544-8e48-9493a6bb99c8@gmail.com>
 <20240219104025.GM22484@axis.com>
Message-ID: <7961378c-9d4f-419b-bf86-4f5e55b3839a@gmail.com>



On 2/19/2024 2:40 AM, Jesper Nilsson wrote:
> On Fri, Feb 16, 2024 at 09:13:51AM -0800, Florian Fainelli wrote:
>> So in premise I agree with the patch, that incrementing those is not the
>> right way to go about them. However these registers are currently provided
>> as part of the statistics set, but they should instead be accessed via the
>> register dumping method.
> 
> You mean extending the dump register code to dump the MAC Management Counter
> registers that are not counters?

Yes that is what I meant.

>  From what I understand it's only the Rx and Tx interrupt and interrupt mask
> registers that aren't counters. Oh, and the MMC control register itself?
> 
> To be honest, I don't think their use can justify the code churn.

Fair enough, it really depends whether they are actually useful in 
troubleshooting or not.

> 
>> In either case you will get at best a snapshot of those two registers at any
>> given time and I suppose this can help diagnose a stuck RX condition, but
>> not much more than that.
> 
> Yeah, their use is very doubtful. For me, they only introduce more nonsense
> data in my logs.
> 
> The Rx registers looks to have been added in the first version of the MMC
> back in 2011, but the Tx registers never was.
> In commit 1c901a46d57 Giuseppe mentions the MMC interrupts as something to
> add later (if actually useful).
> 
> So Serge's suggestion to drop the entries completely is actually quite attractive.

No concerns from me to drop them, not much value in having inaccurate 
information.
-- 
Florian


From alexandre.belloni at bootlin.com  Mon Feb 19 12:19:16 2024
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Mon, 19 Feb 2024 21:19:16 +0100
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
In-Reply-To: <96c0f613-7c53-4189-bfc8-7d572b308b9f@amd.com>
References: <94726c90ff519185767475f672d70311472ea925.1708073513.git.michal.simek@amd.com>
 <5a81f16b-8ece-4263-b424-4dd6cd6e386f@linaro.org>
 <ed59671f-6e0b-45a2-bae7-38f7b4b7e625@amd.com>
 <ebcfd49d-f810-4d9b-8cba-b55071fc7fa6@linaro.org>
 <96c0f613-7c53-4189-bfc8-7d572b308b9f@amd.com>
Message-ID: <202402192019160b9c4120@mail.local>

On 19/02/2024 14:11:50+0100, Michal Simek wrote:
> 
> 
> On 2/17/24 09:26, Krzysztof Kozlowski wrote:
> > On 16/02/2024 10:42, Michal Simek wrote:
> > > 
> > > 
> > > On 2/16/24 10:19, Krzysztof Kozlowski wrote:
> > > > On 16/02/2024 09:51, Michal Simek wrote:
> > > > > RTC has its own power domain on Xilinx Versal SOC that's why describe it as
> > > > > optional property.
> > > > > 
> > > > > Signed-off-by: Michal Simek <michal.simek at amd.com>
> > > > > ---
> > > > > 
> > > > >    Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml | 3 +++
> > > > >    1 file changed, 3 insertions(+)
> > > > > 
> > > > 
> > > > But Versal is not described in this binding, is it? I see only one
> > > > compatible.
> > > 
> > > It is the same IP only as is on zynqmp with own power rail.
> > 
> > Then you should have separate compatible, because they are not
> > identical. It would also allow you to narrow the domains to versal and
> > also require it (on versal).
> 
> I can double check with HW guys but I am quite sure IP itself is exactly the
> same. What it is different is that there is own power domain to it (not
> shared one as is in zynqmp case).
> 
> Also Linux is non secure sw and if secure firmware won't allow to change
> setting of it it can't be required. I am just saying that Linux doesn't need
> to be owner of any power domain that's why it shouldn't be required
> property.

I guess because the integration is different, you still need a
differente compatible so you can forbid the property on non-Versal.

> 
> Thanks,
> Michal

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From cristian.ciocaltea at collabora.com  Mon Feb 19 12:37:24 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 19 Feb 2024 22:37:24 +0200
Subject: [PATCH] arm64: defconfig: Enable Rockchip HDMI/eDP Combo PHY
Message-ID: <20240219203725.283532-1-cristian.ciocaltea@collabora.com>

Enable support for the Rockchip HDMI/eDP Combo PHY, which is based on a
Samsung IP block. This is used by the RK3588 SoC family.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 056a6cc546a4..b1f8ff32f940 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1510,6 +1510,7 @@ CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=m
 CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=m
 CONFIG_PHY_ROCKCHIP_PCIE=m
+CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=m
 CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
 CONFIG_PHY_ROCKCHIP_TYPEC=y
 CONFIG_PHY_SAMSUNG_UFS=y
-- 
2.43.2



From peter.griffin at linaro.org  Mon Feb 19 12:42:36 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 19 Feb 2024 20:42:36 +0000
Subject: [PATCH v5 0/2] Add regmap support to exynos-pmu for protected PMU regs
Message-ID: <20240219204238.356942-1-peter.griffin@linaro.org>

Hi folks,

This is a v5 of the series to add support for protected PMU registers found
on gs101 and derivative SoCs. In v2 and later it was re-worked to be based
on a regmap abstraction that I think leads to a much neater overall
solution.

The advantage of the regmap abstraction is that most leaf drivers that
read/write PMU registers need minimal changes.

Example of Exynos drivers that require PMU register access are:
* watchdog
* usb phy
* mipi phy
* ufs phy

This series has been tested on Pixel 6 Oriole / gs101 (by me), exynos850
(by Sam) and odroid xu3 (exynos 5422) by Alexey. That confirms that both
the regmap mmio parts and regmap SMC parts are working correctly.

The expectation is this series would be merged via Krzysztofs Samsung Exynos
tree.

regards,

Peter

Changes since v4:
 - Use same argument names as in struct regmap_config
 - Remove inline keyword and rely on compiler
 - Update kerneldoc wording
 - property -> propname argument rename
 - reverse Xmas tree
 - Only call of_node_put() when of_parse_phandle() is called
 - Collect tags

Changes since v3:
 - Fix PMUALIVE_MASK
 - Add TENSOR_ prefix
 - clear SET_BITS bits on each loop iteration
 - change set_bit to set_bits func name
 - Fix some alignment
 - Add missing return on dev_err_probe
 - Reduce indentation in loop

Changes since v2
 - Add select REGMAP to Kconfig
 - Add constant for SET/CLEAR bits
 - Replace kerneldoc with one line comment
 - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
 - remove superflous extern keyword
 - dev_err_probe() on probe error
 - shorten regmcfg name
 - no compatibles inside probe, use match data
 - don't mix declarations with/without initializations
 - tensor_sec_reg_read() use mmio to avoid access restrictions
 - Collect up Reviewed-by
 - const for regmap_config structs

Changes since v1:
 - Refactor to use custom regmap to abstract SMC register access (Sam / Guenter)
 - Add deferred probing support (Saravana / Krzysztof)

v4 lore: https://lore.kernel.org/all/20240208161700.268570-1-peter.griffin at linaro.org/
v3 lore: https://lore.kernel.org/all/20240202145731.4082033-1-peter.griffin at linaro.org/
v2 lore: https://lore.kernel.org/lkml/20240129211912.3068411-1-peter.griffin at linaro.org/
v1 lore: https://lore.kernel.org/all/20240122225710.1952066-1-peter.griffin at linaro.org/

Peter Griffin (2):
  soc: samsung: exynos-pmu: Add regmap support for SoCs that protect PMU
    regs
  watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU
    regs

 drivers/soc/samsung/Kconfig            |   1 +
 drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
 drivers/soc/samsung/exynos-pmu.h       |   1 +
 drivers/watchdog/Kconfig               |   1 -
 drivers/watchdog/s3c2410_wdt.c         |   8 +-
 include/linux/soc/samsung/exynos-pmu.h |  11 +-
 6 files changed, 249 insertions(+), 8 deletions(-)

-- 
2.44.0.rc0.258.g7320e95886-goog



From peter.griffin at linaro.org  Mon Feb 19 12:42:37 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 19 Feb 2024 20:42:37 +0000
Subject: [PATCH v5 1/2] soc: samsung: exynos-pmu: Add regmap support for SoCs that protect PMU regs
In-Reply-To: <20240219204238.356942-1-peter.griffin@linaro.org>
References: <20240219204238.356942-1-peter.griffin@linaro.org>
Message-ID: <20240219204238.356942-2-peter.griffin@linaro.org>

Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
security hardening reasons so that they are only write accessible in el3
via an SMC call.

As most Exynos drivers that need to write PMU registers currently obtain a
regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
is implemented in this driver using a custom regmap similar to syscon to
handle the SMC call. Platforms that don't secure PMU registers, get a mmio
regmap like before. As regmaps abstract out the underlying register access
changes to the leaf drivers are minimal.

A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
that currently use syscon_regmap_lookup_by_phandle(). This also handles
deferred probing.

Tested-by: Sam Protsenko <semen.protsenko at linaro.org>
Tested-by: Alexey Klimov <alexey.klimov at linaro.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
Changes since v4:
 - Use same argument names as in struct regmap_config
 - Remove inline keyword and rely on compiler
 - Update kerneldoc wording
 - property -> propname argument rename
 - reverse Xmas tree
 - Only call of_node_put() when of_parse_phandle is called
 - Collect tags

Changes since v3:
 - Fix PMUALIVE_MASK
 - Add TENSOR_ prefix
 - clear SET_BITS bits on each loop iteration
 - change set_bit to set_bits in func name
 - Fix some alignment
 - Add missing return on dev_err_probe
 - Reduce indentation in loop

Changes since v2
 - Add select REGMAP to Kconfig
 - Add constant for SET/CLEAR bits
 - Replace kerneldoc with one line comment
 - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
 - remove superfluous extern keyword
 - dev_err_probe() on probe error
 - shorten regmcfg name
 - no compatibles inside probe, use match data
 - don't mix declarations with/without initializations
 - tensor_sec_reg_read() use mmio to avoid access restrictions
 - Collect up Reviewed-by
 - const for regmap_config structs
---
 drivers/soc/samsung/Kconfig            |   1 +
 drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
 drivers/soc/samsung/exynos-pmu.h       |   1 +
 include/linux/soc/samsung/exynos-pmu.h |  11 +-
 4 files changed, 245 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 27ec99af77e3..1a5dfdc978dc 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -42,6 +42,7 @@ config EXYNOS_PMU
 	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
 	select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
 	select MFD_CORE
+	select REGMAP_MMIO
 
 # There is no need to enable these drivers for ARMv8
 config EXYNOS_PMU_ARM_DRIVERS
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index 250537d7cfd6..d6ae8025fdb4 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -5,6 +5,7 @@
 //
 // Exynos - CPU PMU(Power Management Unit) support
 
+#include <linux/arm-smccc.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/mfd/core.h>
@@ -12,19 +13,134 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/regmap.h>
 
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/soc/samsung/exynos-pmu.h>
 
 #include "exynos-pmu.h"
 
+#define PMUALIVE_MASK			GENMASK(13, 0)
+#define TENSOR_SET_BITS			(BIT(15) | BIT(14))
+#define TENSOR_CLR_BITS			BIT(15)
+#define TENSOR_SMC_PMU_SEC_REG		0x82000504
+#define TENSOR_PMUREG_READ		0
+#define TENSOR_PMUREG_WRITE		1
+#define TENSOR_PMUREG_RMW		2
+
 struct exynos_pmu_context {
 	struct device *dev;
 	const struct exynos_pmu_data *pmu_data;
+	struct regmap *pmureg;
 };
 
 void __iomem *pmu_base_addr;
 static struct exynos_pmu_context *pmu_context;
+/* forward declaration */
+static struct platform_driver exynos_pmu_driver;
+
+/*
+ * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
+ * from EL3, but are still read accessible. As Linux needs to write some of
+ * these registers, the following functions are provided and exposed via
+ * regmap.
+ *
+ * Note: This SMC interface is known to be implemented on gs101 and derivative
+ * SoCs.
+ */
+
+/* Write to a protected PMU register. */
+static int tensor_sec_reg_write(void *context, unsigned int reg,
+				unsigned int val)
+{
+	struct arm_smccc_res res;
+	unsigned long pmu_base = (unsigned long)context;
+
+	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
+		      TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
+
+	/* returns -EINVAL if access isn't allowed or 0 */
+	if (res.a0)
+		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
+
+	return (int)res.a0;
+}
+
+/* Read/Modify/Write a protected PMU register. */
+static int tensor_sec_reg_rmw(void *context, unsigned int reg,
+			      unsigned int mask, unsigned int val)
+{
+	struct arm_smccc_res res;
+	unsigned long pmu_base = (unsigned long)context;
+
+	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
+		      TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
+
+	/* returns -EINVAL if access isn't allowed or 0 */
+	if (res.a0)
+		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
+
+	return (int)res.a0;
+}
+
+/*
+ * Read a protected PMU register. All PMU registers can be read by Linux.
+ * Note: The SMC read register is not used, as only registers that can be
+ * written are readable via SMC.
+ */
+static int tensor_sec_reg_read(void *context, unsigned int reg,
+			       unsigned int *val)
+{
+	*val = pmu_raw_readl(reg);
+	return 0;
+}
+
+/*
+ * For SoCs that have set/clear bit hardware this function can be used when
+ * the PMU register will be accessed by multiple masters.
+ *
+ * For example, to set bits 13:8 in PMU reg offset 0x3e80
+ * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00);
+ *
+ * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80
+ * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00);
+ */
+static int tensor_set_bits_atomic(void *ctx, unsigned int offset, u32 val,
+				  u32 mask)
+{
+	int ret;
+	unsigned int i;
+
+	for (i = 0; i < 32; i++) {
+		if (!(mask & BIT(i)))
+			continue;
+
+		offset &= ~TENSOR_SET_BITS;
+
+		if (val & BIT(i))
+			offset |= TENSOR_SET_BITS;
+		else
+			offset |= TENSOR_CLR_BITS;
+
+		ret = tensor_sec_reg_write(ctx, offset, i);
+		if (ret)
+			return ret;
+	}
+	return ret;
+}
+
+static int tensor_sec_update_bits(void *ctx, unsigned int reg,
+				  unsigned int mask, unsigned int val)
+{
+	/*
+	 * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
+	 * as the target registers can be accessed by multiple masters.
+	 */
+	if (reg > PMUALIVE_MASK)
+		return tensor_sec_reg_rmw(ctx, reg, mask, val);
+
+	return tensor_set_bits_atomic(ctx, reg, val, mask);
+}
 
 void pmu_raw_writel(u32 val, u32 offset)
 {
@@ -75,11 +191,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
 #define exynos_pmu_data_arm_ptr(data)	NULL
 #endif
 
+static const struct regmap_config regmap_smccfg = {
+	.name = "pmu_regs",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.use_single_read = true,
+	.use_single_write = true,
+	.reg_read = tensor_sec_reg_read,
+	.reg_write = tensor_sec_reg_write,
+	.reg_update_bits = tensor_sec_update_bits,
+};
+
+static const struct regmap_config regmap_mmiocfg = {
+	.name = "pmu_regs",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.use_single_read = true,
+	.use_single_write = true,
+};
+
+static const struct exynos_pmu_data gs101_pmu_data = {
+	.pmu_secure = true
+};
+
 /*
  * PMU platform driver and devicetree bindings.
  */
 static const struct of_device_id exynos_pmu_of_device_ids[] = {
 	{
+		.compatible = "google,gs101-pmu",
+		.data = &gs101_pmu_data,
+	}, {
 		.compatible = "samsung,exynos3250-pmu",
 		.data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
 	}, {
@@ -113,19 +259,75 @@ static const struct mfd_cell exynos_pmu_devs[] = {
 	{ .name = "exynos-clkout", },
 };
 
+/**
+ * exynos_get_pmu_regmap() - Obtain pmureg regmap
+ *
+ * Find the pmureg regmap previously configured in probe() and return regmap
+ * pointer.
+ *
+ * Return: A pointer to regmap if found or ERR_PTR error value.
+ */
 struct regmap *exynos_get_pmu_regmap(void)
 {
 	struct device_node *np = of_find_matching_node(NULL,
 						      exynos_pmu_of_device_ids);
 	if (np)
-		return syscon_node_to_regmap(np);
+		return exynos_get_pmu_regmap_by_phandle(np, NULL);
 	return ERR_PTR(-ENODEV);
 }
 EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
 
+/**
+ * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
+ * @np: Device node holding PMU phandle property
+ * @property: Name of property holding phandle value
+ *
+ * Find the pmureg regmap previously configured in probe() and return regmap
+ * pointer.
+ *
+ * Return: A pointer to regmap if found or ERR_PTR error value.
+ */
+struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+						const char *propname)
+{
+	struct exynos_pmu_context *ctx;
+	struct device_node *pmu_np;
+	struct device *dev;
+
+	if (propname)
+		pmu_np = of_parse_phandle(np, propname, 0);
+	else
+		pmu_np = np;
+
+	if (!pmu_np)
+		return ERR_PTR(-ENODEV);
+
+	/*
+	 * Determine if exynos-pmu device has probed and therefore regmap
+	 * has been created and can be returned to the caller. Otherwise we
+	 * return -EPROBE_DEFER.
+	 */
+	dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
+					    (void *)pmu_np);
+
+	if (propname)
+		of_node_put(pmu_np);
+
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	ctx = dev_get_drvdata(dev);
+
+	return ctx->pmureg;
+}
+EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
+
 static int exynos_pmu_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct regmap_config pmu_regmcfg;
+	struct regmap *regmap;
+	struct resource *res;
 	int ret;
 
 	pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
@@ -137,9 +339,38 @@ static int exynos_pmu_probe(struct platform_device *pdev)
 			GFP_KERNEL);
 	if (!pmu_context)
 		return -ENOMEM;
-	pmu_context->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
 	pmu_context->pmu_data = of_device_get_match_data(dev);
 
+	/* For SoCs that secure PMU register writes use custom regmap */
+	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_secure) {
+		pmu_regmcfg = regmap_smccfg;
+		pmu_regmcfg.max_register = resource_size(res) -
+					   pmu_regmcfg.reg_stride;
+		/* Need physical address for SMC call */
+		regmap = devm_regmap_init(dev, NULL,
+					  (void *)(uintptr_t)res->start,
+					  &pmu_regmcfg);
+	} else {
+		/* All other SoCs use a MMIO regmap */
+		pmu_regmcfg = regmap_mmiocfg;
+		pmu_regmcfg.max_register = resource_size(res) -
+					   pmu_regmcfg.reg_stride;
+		regmap = devm_regmap_init_mmio(dev, pmu_base_addr,
+					       &pmu_regmcfg);
+	}
+
+	if (IS_ERR(regmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(regmap),
+				     "regmap init failed\n");
+
+	pmu_context->pmureg = regmap;
+	pmu_context->dev = dev;
+
 	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init)
 		pmu_context->pmu_data->pmu_init();
 
diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
index 1c652ffd79b4..0a49a2c9a08e 100644
--- a/drivers/soc/samsung/exynos-pmu.h
+++ b/drivers/soc/samsung/exynos-pmu.h
@@ -21,6 +21,7 @@ struct exynos_pmu_conf {
 struct exynos_pmu_data {
 	const struct exynos_pmu_conf *pmu_config;
 	const struct exynos_pmu_conf *pmu_config_extra;
+	bool pmu_secure;
 
 	void (*pmu_init)(void);
 	void (*powerdown_conf)(enum sys_powerdown);
diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
index a4f5516cc956..2bd9d12d9a52 100644
--- a/include/linux/soc/samsung/exynos-pmu.h
+++ b/include/linux/soc/samsung/exynos-pmu.h
@@ -10,6 +10,7 @@
 #define __LINUX_SOC_EXYNOS_PMU_H
 
 struct regmap;
+struct device_node;
 
 enum sys_powerdown {
 	SYS_AFTR,
@@ -20,12 +21,20 @@ enum sys_powerdown {
 
 extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
 #ifdef CONFIG_EXYNOS_PMU
-extern struct regmap *exynos_get_pmu_regmap(void);
+struct regmap *exynos_get_pmu_regmap(void);
+struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+						const char *propname);
 #else
 static inline struct regmap *exynos_get_pmu_regmap(void)
 {
 	return ERR_PTR(-ENODEV);
 }
+
+static inline struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+							      const char *propname)
+{
+	return ERR_PTR(-ENODEV);
+}
 #endif
 
 #endif /* __LINUX_SOC_EXYNOS_PMU_H */
-- 
2.44.0.rc0.258.g7320e95886-goog



From peter.griffin at linaro.org  Mon Feb 19 12:42:38 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Mon, 19 Feb 2024 20:42:38 +0000
Subject: [PATCH v5 2/2] watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs
In-Reply-To: <20240219204238.356942-1-peter.griffin@linaro.org>
References: <20240219204238.356942-1-peter.griffin@linaro.org>
Message-ID: <20240219204238.356942-3-peter.griffin@linaro.org>

Obtain the PMU regmap using the new API added to exynos-pmu driver rather
than syscon_regmap_lookup_by_phandle(). As this driver no longer depends
on mfd syscon remove that header and Kconfig dependency.

Tested-by: Alexey Klimov <alexey.klimov at linaro.org>
Tested-by: Sam Protsenko <semen.protsenko at linaro.org>
Acked-by: Guenter Roeck <linux at roeck-us.net>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 drivers/watchdog/Kconfig       | 1 -
 drivers/watchdog/s3c2410_wdt.c | 8 ++++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7d22051b15a2..d78fe7137799 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -512,7 +512,6 @@ config S3C2410_WATCHDOG
 	tristate "S3C6410/S5Pv210/Exynos Watchdog"
 	depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
 	select WATCHDOG_CORE
-	select MFD_SYSCON if ARCH_EXYNOS
 	help
 	  Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos
 	  SoCs. This will reboot the system when the timer expires with
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 349d30462c8c..686cf544d0ae 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -24,9 +24,9 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/of.h>
-#include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/delay.h>
+#include <linux/soc/samsung/exynos-pmu.h>
 
 #define S3C2410_WTCON		0x00
 #define S3C2410_WTDAT		0x04
@@ -699,11 +699,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
 		return ret;
 
 	if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
-		wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
-						"samsung,syscon-phandle");
+		wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node,
+						 "samsung,syscon-phandle");
 		if (IS_ERR(wdt->pmureg))
 			return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
-					     "syscon regmap lookup failed.\n");
+					     "PMU regmap lookup failed.\n");
 	}
 
 	wdt_irq = platform_get_irq(pdev, 0);
-- 
2.44.0.rc0.258.g7320e95886-goog



From cristian.ciocaltea at collabora.com  Mon Feb 19 12:46:25 2024
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 19 Feb 2024 22:46:25 +0200
Subject: [PATCH] arm64: dts: rockchip: Add HDMI0 PHY to rk3588
Message-ID: <20240219204626.284399-1-cristian.ciocaltea@collabora.com>

Add DT nodes for HDMI0 PHY and related syscon found on RK3588 SoC.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index 36b1b7acfe6a..3a15a30543c3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -586,6 +586,11 @@ u2phy3_host: host-port {
 		};
 	};
 
+	hdptxphy0_grf: syscon at fd5e0000 {
+		compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
+		reg = <0x0 0xfd5e0000 0x0 0x100>;
+	};
+
 	ioc: syscon at fd5f0000 {
 		compatible = "rockchip,rk3588-ioc", "syscon";
 		reg = <0x0 0xfd5f0000 0x0 0x10000>;
@@ -2360,6 +2365,22 @@ dmac2: dma-controller at fed10000 {
 		#dma-cells = <1>;
 	};
 
+	hdptxphy_hdmi0: phy at fed60000 {
+		compatible = "rockchip,rk3588-hdptx-phy";
+		reg = <0x0 0xfed60000 0x0 0x2000>;
+		clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
+		clock-names = "ref", "apb";
+		#phy-cells = <0>;
+		resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
+			 <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
+			 <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
+			 <&cru SRST_HDPTX0_LCPLL>;
+		reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
+			      "lcpll";
+		rockchip,grf = <&hdptxphy0_grf>;
+		status = "disabled";
+	};
+
 	combphy0_ps: phy at fee00000 {
 		compatible = "rockchip,rk3588-naneng-combphy";
 		reg = <0x0 0xfee00000 0x0 0x100>;
-- 
2.43.2



From nicolas at ndufresne.ca  Mon Feb 19 13:09:54 2024
From: nicolas at ndufresne.ca (Nicolas Dufresne)
Date: Mon, 19 Feb 2024 16:09:54 -0500
Subject: [PATCH] media: mediatek: vcodec: Handle VP9 superframe
 bitstream with 8 sub-frames
In-Reply-To: <20240218115954.4038-1-irui.wang@mediatek.com>
References: <20240218115954.4038-1-irui.wang@mediatek.com>
Message-ID: <6bed645bc3ddd51092ed8f6e49672af40735c83d.camel@ndufresne.ca>

Hi,

Le dimanche 18 f?vrier 2024 ? 19:59 +0800, Irui Wang a ?crit?:
> The VP9 bitstream has 8 sub-frames into one superframe, the superframe
> index validate failed when reach 8, modify the index checking so that the
> last sub-frame can be decoded normally.

When I first saw this patch I was concerned, since we don't allow bundling super
frame into the stateless API, but now I realize that this is for the stateful
decoder. Perhaps you can help me and possibly other reviewers with simply
stating that this is for stateful decoders.

> 
> Signed-off-by: Irui Wang <irui.wang at mediatek.com>
> ---
>  .../media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c
> index 55355fa70090..4a9ced7348ee 100644
> --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c
> +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c
> @@ -526,7 +526,7 @@ static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst)
>  	/* if this super frame and it is not last sub-frame, get next fb for
>  	 * sub-frame decode
>  	 */
> -	if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt - 1)
> +	if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt)
>  		vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
>  }
>  
> @@ -735,7 +735,7 @@ static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)
>  
>  static int validate_vsi_array_indexes(struct vdec_vp9_inst *inst,
>  		struct vdec_vp9_vsi *vsi) {
> -	if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM - 1) {
> +	if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM) {

nit: I'd propose to define a new maximum (contractions allowed):

  #define VP9_MAX_NUM_SUPER_FRAMES 8

This way you can revisit bunch of `VP9_MAX_FRM_BUF_NUM-1`, and make the overall
code a bit more human readable. There is no relation between VP9_MAX_FRM_BUF_NUM
and this maximum. The limits simply comes from the fact
frames_in_superframe_minus_1 is expressed with 3 bits.

regards,
Nicolas

p.s. your change looks good otherwise.

>  		mtk_vdec_err(inst->ctx, "Invalid vsi->sf_frm_idx=%u.", vsi->sf_frm_idx);
>  		return -EIO;
>  	}



From krzysztof.kozlowski at linaro.org  Mon Feb 19 13:23:19 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 19 Feb 2024 22:23:19 +0100
Subject: [PATCH v5 03/18] dt-bindings: regulator: describe the PMU module
 of the QCA6390 package
In-Reply-To: <CAMRc=Me=3HhGc_yZuaEo1TsLbF2R=g+072185_PAh5GmAQ-M7w@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-4-brgl@bgdev.pl>
 <ZdDVNbjv60G9YUNy@finisterre.sirena.org.uk>
 <CAMRc=Mf9Sro4kM_Jn8_v=cyO5PxCp6AnBdeS9XspqVDGKdA_Dg@mail.gmail.com>
 <7c1327c0-d0ea-4797-a5fa-5844ba46bf53@linaro.org>
 <CAMRc=Me=3HhGc_yZuaEo1TsLbF2R=g+072185_PAh5GmAQ-M7w@mail.gmail.com>
Message-ID: <a9c34206-0068-4bd1-9fae-8963ad00eb36@linaro.org>

On 19/02/2024 13:53, Bartosz Golaszewski wrote:
> On Mon, Feb 19, 2024 at 8:32?AM Krzysztof Kozlowski
> <krzysztof.kozlowski at linaro.org> wrote:
>>
>> On 17/02/2024 19:32, Bartosz Golaszewski wrote:
>>> On Sat, Feb 17, 2024 at 4:48?PM Mark Brown <broonie at kernel.org> wrote:
>>>>
>>>> On Fri, Feb 16, 2024 at 09:32:00PM +0100, Bartosz Golaszewski wrote:
>>>>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>>>>
>>>>> The QCA6390 package contains discreet modules for WLAN and Bluetooth. They
>>>>> are powered by the Power Management Unit (PMU) that takes inputs from the
>>>>> host and provides LDO outputs. This document describes this module.
>>>>
>>>> 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.
>>>
>>> Mark,
>>>
>>> This is quite vague, could you elaborate? I have no idea what is wrong
>>> with this patch.
>>
>> Use subject prefixes matching the subsystem. You can get them for
>> example with `git log --oneline -- DIRECTORY_OR_FILE` on the directory
>> your patch is touching.
>>
>> Best regards,
>> Krzysztof
>>
> 
> Yes, I always do. And for Documentation/devicetree/bindings/regulator/
> the subjects are split 50:50 between "dt-bindings: regulator: ..." and

No, there are only ~54 "dt + regulator" ones and around 400 starting
with "regulator" (Mark removes first prefix if it is not regulator:). So
50 to 400 is not 50:50.


> "regulator: dt-bindings: ...". For Documentation/devicetree/bindings/
> it's overwhelmingly "dt-bindings: <subsystem>: ...". It's the first
> time someone wants me to send a DT bindings patch without
> "dt-bindings" coming first in the subject.
> 
> I mean: I can do it alright but it's not stated anywhere explicitly.

Well, practice was kind of known and obvious, but it is also stated:

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/submitting-patches.rst?h=next-20240219#n18



Best regards,
Krzysztof



From konrad.dybcio at linaro.org  Mon Feb 19 13:37:39 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Mon, 19 Feb 2024 22:37:39 +0100
Subject: [PATCH 8/8] arm64: dts: qcom: qrb2210-rb1: Enable the GPU
In-Reply-To: <CAA8EJppPvXfkz=wVca8aFBhFaVUe9+OiVzcQUq7D8zPbK+T1FQ@mail.gmail.com>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
 <20240219-topic-rb1_gpu-v1-8-d260fa854707@linaro.org>
 <CAA8EJppPvXfkz=wVca8aFBhFaVUe9+OiVzcQUq7D8zPbK+T1FQ@mail.gmail.com>
Message-ID: <b73e329a-02a4-46e0-bda4-5d5fae0a1180@linaro.org>

On 19.02.2024 15:49, Dmitry Baryshkov wrote:
> On Mon, 19 Feb 2024 at 15:36, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>>
>> Enable the A702 GPU (also marketed as "3D accelerator by qcom [1], lol).
> 
> Is it not?

Sure, every electronic device is also a heater, I suppose.. I found
this wording extremely funny though

> 
>>
>> [1] https://docs.qualcomm.com/bundle/publicresource/87-61720-1_REV_A_QUALCOMM_ROBOTICS_RB1_PLATFORM__QUALCOMM_QRB2210__PRODUCT_BRIEF.pdf
>> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> 
> With the exception of the commit message:

:(

Konrad

> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> 
>> ---
>>  arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 8 ++++++++
>>  1 file changed, 8 insertions(+)
> 
> 


From kent.overstreet at linux.dev  Mon Feb 19 13:38:16 2024
From: kent.overstreet at linux.dev (Kent Overstreet)
Date: Mon, 19 Feb 2024 16:38:16 -0500
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <ff0164553d6f486f97643eae8235cc5f@AcuMS.aculab.com>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
 <ZdMe24xN1Ej4QoVU@shell.armlinux.org.uk>
 <xs2splnjhlj257uca5yae64fp4solc4ugbxrkczoyd75n42r66@42boyzdcmyj4>
 <ZdMkyPX/h9s8xht5@shell.armlinux.org.uk>
 <fharyfc7fnh45dthgd2ehwsgdqzmdfptp7jw7gi5ahb6slwgf6@nrkhlhvbbzx7>
 <ff0164553d6f486f97643eae8235cc5f@AcuMS.aculab.com>
Message-ID: <msw3w26o27g2lvdgche535m47vqdzmr4g2evq5gc4uvmo5fqi2@bedh4opzimmt>

On Mon, Feb 19, 2024 at 07:53:15PM +0000, David Laight wrote:
> ...
> > I'm not always trying to write code that will generate the fastest
> > assembly possible; there aro other considerations. As long a the
> > compiler is doing something /reasonable/, the code is fine.
> 
> Speaks the man who was writing horrid 'jit' code ...
> 
> This also begs the question of why that data is so compressed
> in the first place?
> It is quite likely that a few accesses generate far more code
> than the data you are attempting to save.

It's easy to understand if you understand profiling, benchmarking and
cache effects.

That 'jit code' is for _all_ filesystem metadata.


From linus.walleij at linaro.org  Mon Feb 19 13:56:32 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 19 Feb 2024 22:56:32 +0100
Subject: [PATCH 13/23] gpio: nomadik: fix offset bug in nmk_pmx_set()
In-Reply-To: <20240214-mbly-gpio-v1-13-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-13-f88c0ccf372b@bootlin.com>
Message-ID: <CACRpkdbq_QxdftNGOv3+-SpfrV_qPTB-m-atdY0hCE_s8DK64A@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> Previously, the statement looked like:
>
>     slpm[x] &= ~BIT(g->pins[i]);
>
> Where:
>  - slpm is a unsigned int pointer;
>  - g->pins[i] is a pin number which can grow to more than 32.
>
> The expected shift amount is a pin bank offset.
>
> This bug does not occur on every group or pin: the altsetting must be
> NMK_GPIO_ALT_C and the pin must be 32 or above. It is possible that it
> occurred. For example, in pinctrl-nomadik-db8500.c, pin group i2c3_c_2
> has the right altsetting and has pins 229 and 230.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Ah good catch!
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

I this something I could just apply as a fix or are there
dependencies on other patches?

Yours,
Linus Walleij


From David.Laight at ACULAB.COM  Mon Feb 19 14:04:20 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Mon, 19 Feb 2024 22:04:20 +0000
Subject: [PATCH] arm: Silence gcc warnings about arch ABI drift
In-Reply-To: <msw3w26o27g2lvdgche535m47vqdzmr4g2evq5gc4uvmo5fqi2@bedh4opzimmt>
References: <fe51512baa18e1480ce997fc535813ce6a0b0721.1708286962.git.jcalvinowens@gmail.com>
 <431dd956-ad31-4da8-ad42-34f7380824bb@app.fastmail.com>
 <ZdMe24xN1Ej4QoVU@shell.armlinux.org.uk>
 <xs2splnjhlj257uca5yae64fp4solc4ugbxrkczoyd75n42r66@42boyzdcmyj4>
 <ZdMkyPX/h9s8xht5@shell.armlinux.org.uk>
 <fharyfc7fnh45dthgd2ehwsgdqzmdfptp7jw7gi5ahb6slwgf6@nrkhlhvbbzx7>
 <ff0164553d6f486f97643eae8235cc5f@AcuMS.aculab.com>
 <msw3w26o27g2lvdgche535m47vqdzmr4g2evq5gc4uvmo5fqi2@bedh4opzimmt>
Message-ID: <c479e2727e4e49739d86b8e2b0b0a221@AcuMS.aculab.com>

From: Kent Overstreet
> Sent: 19 February 2024 21:38
> 
> On Mon, Feb 19, 2024 at 07:53:15PM +0000, David Laight wrote:
> > ...
> > > I'm not always trying to write code that will generate the fastest
> > > assembly possible; there aro other considerations. As long a the
> > > compiler is doing something /reasonable/, the code is fine.
> >
> > Speaks the man who was writing horrid 'jit' code ...
> >
> > This also begs the question of why that data is so compressed
> > in the first place?
> > It is quite likely that a few accesses generate far more code
> > than the data you are attempting to save.
> 
> It's easy to understand if you understand profiling, benchmarking and
> cache effects.

And how arguments get passed to functions :-)

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From dmitry.baryshkov at linaro.org  Mon Feb 19 14:16:16 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 20 Feb 2024 00:16:16 +0200
Subject: [PATCH 8/8] arm64: dts: qcom: qrb2210-rb1: Enable the GPU
In-Reply-To: <b73e329a-02a4-46e0-bda4-5d5fae0a1180@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
 <20240219-topic-rb1_gpu-v1-8-d260fa854707@linaro.org> <CAA8EJppPvXfkz=wVca8aFBhFaVUe9+OiVzcQUq7D8zPbK+T1FQ@mail.gmail.com>
 <b73e329a-02a4-46e0-bda4-5d5fae0a1180@linaro.org>
Message-ID: <CAA8EJpqxYdjKx54Oph3=+H-42+cKpw=t=5GGJq54FVcOa26TDQ@mail.gmail.com>

On Mon, 19 Feb 2024 at 23:37, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>
> On 19.02.2024 15:49, Dmitry Baryshkov wrote:
> > On Mon, 19 Feb 2024 at 15:36, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
> >>
> >> Enable the A702 GPU (also marketed as "3D accelerator by qcom [1], lol).
> >
> > Is it not?
>
> Sure, every electronic device is also a heater, I suppose.. I found
> this wording extremely funny though

3D accelerator is a bit outdated term, but it's still valid. Well,
unless using A702 makes 3D applications run slower than when using
llvmpipe.

> >> [1] https://docs.qualcomm.com/bundle/publicresource/87-61720-1_REV_A_QUALCOMM_ROBOTICS_RB1_PLATFORM__QUALCOMM_QRB2210__PRODUCT_BRIEF.pdf
> >> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> >
> > With the exception of the commit message:
>
> :(
>
> Konrad
>
> >
> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> >
> >> ---
> >>  arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 8 ++++++++
> >>  1 file changed, 8 insertions(+)
> >
> >



-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Mon Feb 19 14:21:45 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 20 Feb 2024 00:21:45 +0200
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <b9a31374-8ea9-407e-9ec3-008a95e2b18b@linaro.org>
References: <20240216203215.40870-1-brgl@bgdev.pl> <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org> <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org> <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
 <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
 <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com> <b9a31374-8ea9-407e-9ec3-008a95e2b18b@linaro.org>
Message-ID: <CAA8EJppWY8c-pF75WaMadWtEuaAyCc5A1VLEq=JmB2Ngzk-zyw@mail.gmail.com>

On Mon, 19 Feb 2024 at 19:18, <neil.armstrong at linaro.org> wrote:
>
> On 19/02/2024 13:33, Dmitry Baryshkov wrote:
> > On Mon, 19 Feb 2024 at 14:23, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> >>
> >> On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
> >> <dmitry.baryshkov at linaro.org> wrote:
> >>>
> >>
> >> [snip]
> >>
> >>>>>>>>
> >>>>>>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> >>>>>>>> necessary. The BT and WLAN devices on the device-tree are represented as
> >>>>>>>> consuming the inputs (relevant to the functionality of each) of the PMU
> >>>>>>>> directly.
> >>>>>>>
> >>>>>>> We are describing the hardware. From the hardware point of view, there
> >>>>>>> is a PMU. I think at some point we would really like to describe all
> >>>>>>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> >>>>>>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
> >>>>>>
> >>>>>> While I agree with older WiFi+BT units, I don't think it's needed for
> >>>>>> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
> >>>>>> transparent.
> >>>>>
> >>>>> I don't see any significant difference between WCN6750/WCN6855 and
> >>>>> WCN7850 from the PMU / power up point of view. Could you please point
> >>>>> me to the difference?
> >>>>>
> >>>>
> >>>> The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
> >>>> and BT_EN ordering and the only requirement is to have all input regulators
> >>>> up before pulling up WLAN_EN and/or BT_EN.
> >>>>
> >>>> This makes the PMU transparent and BT and WLAN can be described as independent.
> >>>
> >>>  From the hardware perspective, there is a PMU. It has several LDOs. So
> >>> the device tree should have the same style as the previous
> >>> generations.
> >>>
> >>
> >> My thinking was this: yes, there is a PMU but describing it has no
> >> benefit (unlike QCA6x90). If we do describe, then we'll end up having
> >> to use pwrseq here despite it not being needed because now we won't be
> >> able to just get regulators from WLAN/BT drivers directly.
> >>
> >> So I also vote for keeping it this way. Let's go into the package
> >> detail only if it's required.
> >
> > The WiFi / BT parts are not powered up by the board regulators. They
> > are powered up by the PSU. So we are not describing it in the accurate
> > way.
>
> I disagree, the WCN7850 can also be used as a discrete PCIe M.2 card, and in
> this situation the PCIe part is powered with the M.2 slot and the BT side
> is powered separately as we currently do it now.

QCA6390 can also be used as a discrete M.2 card.

> So yes there's a PMU, but it's not an always visible hardware part, from the
> SoC PoV, only the separate PCIe and BT subsystems are visible/controllable/powerable.

>From the hardware point:
- There is a PMU
- The PMU is connected to the board supplies
- Both WiFi and BT parts are connected to the PMU
- The BT_EN / WLAN_EN pins are not connected to the PMU

So, not representing the PMU in the device tree is a simplification.

>
> Neil
>
> >
> > Moreover, I think we definitely want to move BT driver to use only the
> > pwrseq power up method. Doing it in the other way results in the code
> > duplication and possible issues because of the regulator / pwrseq
> > taking different code paths.

-- 
With best wishes
Dmitry


From dlechner at baylibre.com  Mon Feb 19 14:33:17 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 19 Feb 2024 16:33:17 -0600
Subject: [PATCH v2 0/5] spi: add support for pre-cooking messages
Message-ID: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>

This is a follow-up to [1] where it was suggested to break down the
proposed SPI offload support into smaller series.

This takes on the first suggested task of introducing an API to
"pre-cook" SPI messages. This idea was first discussed extensively in
2013 [2][3] and revisited more briefly 2022 [4].

The goal here is to be able to improve performance (higher throughput,
and reduced CPU usage) by allowing peripheral drivers that use the
same struct spi_message repeatedly to "pre-cook" the message once to
avoid repeating the same validation, and possibly other operations each
time the message is sent.

This series includes __spi_validate() and the automatic splitting of
xfers in the optimizations. Another frequently suggested optimization
is doing DMA mapping only once. This is not included in this series, but
can be added later (preferably by someone with a real use case for it).

To show how this all works and get some real-world measurements, this
series includes the core changes, optimization of a SPI controller
driver, and optimization of an ADC driver. This test case was only able
to take advantage of the single validation optimization, since it didn't
require splitting transfers. With these changes, CPU usage of the
threaded interrupt handler, which calls spi_sync(), was reduced from
83% to 73% while at the same time the sample rate (frequency of SPI
xfers) was increased from 20kHz to 25kHz.

[1]: https://lore.kernel.org/linux-spi/20240109-axi-spi-engine-series-3-v1-1-e42c6a986580 at baylibre.com/T/
[2]: https://lore.kernel.org/linux-spi/E81F4810-48DD-41EE-B110-D0D848B8A510 at martin.sperl.org/T/
[3]: https://lore.kernel.org/linux-spi/39DEC004-10A1-47EF-9D77-276188D2580C at martin.sperl.org/T/
[4]: https://lore.kernel.org/linux-spi/20220525163946.48ea40c9 at erd992/T/

---
Changes in v2:
- Removed pre_optimized parameter from __spi_optimize_message()
- Added comment explaining purpose of pre_optimized flag
- Fixed missing doc comment for @pre_optimized
- Removed kernel doc inclusion (/** -> /*) from static members
- Removed unrelated comment about calling spi_finalize_current_message()
- Reworked IIO driver patch
- Link to v1: https://lore.kernel.org/r/20240212-mainline-spi-precook-message-v1-0-a2373cd72d36 at baylibre.com

---
David Lechner (5):
      spi: add spi_optimize_message() APIs
      spi: move splitting transfers to spi_optimize_message()
      spi: stm32: move splitting transfers to optimize_message
      spi: axi-spi-engine: move message compile to optimize_message
      iio: adc: ad7380: use spi_optimize_message()

 drivers/iio/adc/ad7380.c         |  36 +++++-
 drivers/spi/spi-axi-spi-engine.c |  40 +++---
 drivers/spi/spi-stm32.c          |  28 +++--
 drivers/spi/spi.c                | 259 ++++++++++++++++++++++++++++++++-------
 include/linux/spi/spi.h          |  20 +++
 5 files changed, 297 insertions(+), 86 deletions(-)
---
base-commit: 55072343f1df834879b8bae9e419cd5cbb5f3259
prerequisite-patch-id: 844c06b6caf25a2724e130dfa7999dc90dd26fde
change-id: 20240208-mainline-spi-precook-message-189b2f08ba7f


From dlechner at baylibre.com  Mon Feb 19 14:33:18 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 19 Feb 2024 16:33:18 -0600
Subject: [PATCH v2 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
Message-ID: <20240219-mainline-spi-precook-message-v2-1-4a762c6701b9@baylibre.com>

This adds a new spi_optimize_message() function that can be used to
optimize SPI messages that are used more than once. Peripheral drivers
that use the same message multiple times can use this API to perform SPI
message validation and controller-specific optimizations once and then
reuse the message while avoiding the overhead of revalidating the
message on each spi_(a)sync() call.

Internally, the SPI core will also call this function for each message
if the peripheral driver did not explicitly call it. This is done to so
that controller drivers don't have to have multiple code paths for
optimized and non-optimized messages.

A hook is provided for controller drivers to perform controller-specific
optimizations.

Suggested-by: Martin Sperl <kernel at martin.sperl.org>
Link: https://lore.kernel.org/linux-spi/39DEC004-10A1-47EF-9D77-276188D2580C at martin.sperl.org/
Signed-off-by: David Lechner <dlechner at baylibre.com>
---

v2 changes:
- Removed pre_optimized parameter from __spi_optimize_message()
- Added comment explaining purpose of pre_optimized flag
- Fixed missing doc comment for @pre_optimized
- Removed kernel doc inclusion (/** -> /*) from static members
- Removed unrelated comment about calling spi_finalize_current_message()

 drivers/spi/spi.c       | 151 ++++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/spi/spi.h |  20 +++++++
 2 files changed, 167 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c2b10e2c75f0..f68d92b57543 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -2106,6 +2106,41 @@ struct spi_message *spi_get_next_queued_message(struct spi_controller *ctlr)
 }
 EXPORT_SYMBOL_GPL(spi_get_next_queued_message);
 
+/*
+ * __spi_unoptimize_message - shared implementation of spi_unoptimize_message()
+ *                            and spi_maybe_unoptimize_message()
+ * @msg: the message to unoptimize
+ *
+ * Peripheral drivers should use spi_unoptimize_message() and callers inside
+ * core should use spi_maybe_unoptimize_message() rather than calling this
+ * function directly.
+ *
+ * It is not valid to call this on a message that is not currently optimized.
+ */
+static void __spi_unoptimize_message(struct spi_message *msg)
+{
+	struct spi_controller *ctlr = msg->spi->controller;
+
+	if (ctlr->unoptimize_message)
+		ctlr->unoptimize_message(msg);
+
+	msg->optimized = false;
+	msg->opt_state = NULL;
+}
+
+/*
+ * spi_maybe_unoptimize_message - unoptimize msg not managed by a peripheral
+ * @msg: the message to unoptimize
+ *
+ * This function is used to unoptimize a message if and only if it was
+ * optimized by the core (via spi_maybe_optimize_message()).
+ */
+static void spi_maybe_unoptimize_message(struct spi_message *msg)
+{
+	if (!msg->pre_optimized && msg->optimized)
+		__spi_unoptimize_message(msg);
+}
+
 /**
  * spi_finalize_current_message() - the current message is complete
  * @ctlr: the controller to return the message to
@@ -2153,6 +2188,8 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
 
 	mesg->prepared = false;
 
+	spi_maybe_unoptimize_message(mesg);
+
 	WRITE_ONCE(ctlr->cur_msg_incomplete, false);
 	smp_mb(); /* See __spi_pump_transfer_message()... */
 	if (READ_ONCE(ctlr->cur_msg_need_completion))
@@ -4194,6 +4231,110 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
 	return 0;
 }
 
+/*
+ * __spi_optimize_message - shared implementation for spi_optimize_message()
+ *                          and spi_maybe_optimize_message()
+ * @spi: the device that will be used for the message
+ * @msg: the message to optimize
+ *
+ * Peripheral drivers will call spi_optimize_message() and the spi core will
+ * call spi_maybe_optimize_message() instead of calling this directly.
+ *
+ * It is not valid to call this on a message that has already been optimized.
+ *
+ * Return: zero on success, else a negative error code
+ */
+static int __spi_optimize_message(struct spi_device *spi,
+				  struct spi_message *msg)
+{
+	struct spi_controller *ctlr = spi->controller;
+	int ret;
+
+	ret = __spi_validate(spi, msg);
+	if (ret)
+		return ret;
+
+	if (ctlr->optimize_message) {
+		ret = ctlr->optimize_message(msg);
+		if (ret)
+			return ret;
+	}
+
+	msg->optimized = true;
+
+	return 0;
+}
+
+/*
+ * spi_maybe_optimize_message - optimize message if it isn't already pre-optimized
+ * @spi: the device that will be used for the message
+ * @msg: the message to optimize
+ * Return: zero on success, else a negative error code
+ */
+static int spi_maybe_optimize_message(struct spi_device *spi,
+				      struct spi_message *msg)
+{
+	if (msg->pre_optimized)
+		return 0;
+
+	return __spi_optimize_message(spi, msg);
+}
+
+/**
+ * spi_optimize_message - do any one-time validation and setup for a SPI message
+ * @spi: the device that will be used for the message
+ * @msg: the message to optimize
+ *
+ * Peripheral drivers that reuse the same message repeatedly may call this to
+ * perform as much message prep as possible once, rather than repeating it each
+ * time a message transfer is performed to improve throughput and reduce CPU
+ * usage.
+ *
+ * Once a message has been optimized, it cannot be modified with the exception
+ * of updating the contents of any xfer->tx_buf (the pointer can't be changed,
+ * only the data in the memory it points to).
+ *
+ * Calls to this function must be balanced with calls to spi_unoptimize_message()
+ * to avoid leaking resources.
+ *
+ * Context: can sleep
+ * Return: zero on success, else a negative error code
+ */
+int spi_optimize_message(struct spi_device *spi, struct spi_message *msg)
+{
+	int ret;
+
+	ret = __spi_optimize_message(spi, msg);
+	if (ret)
+		return ret;
+
+	/*
+	 * This flag indicates that the peripheral driver called spi_optimize_message()
+	 * and therefore we shouldn't unoptimize message automatically when finalizing
+	 * the message but rather wait until spi_unoptimize_message() is called
+	 * by the peripheral driver.
+	 */
+	msg->pre_optimized = true;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(spi_optimize_message);
+
+/**
+ * spi_unoptimize_message - releases any resources allocated by spi_optimize_message()
+ * @msg: the message to unoptimize
+ *
+ * Calls to this function must be balanced with calls to spi_optimize_message().
+ *
+ * Context: can sleep
+ */
+void spi_unoptimize_message(struct spi_message *msg)
+{
+	__spi_unoptimize_message(msg);
+	msg->pre_optimized = false;
+}
+EXPORT_SYMBOL_GPL(spi_unoptimize_message);
+
 static int __spi_async(struct spi_device *spi, struct spi_message *message)
 {
 	struct spi_controller *ctlr = spi->controller;
@@ -4258,8 +4399,8 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
 	int ret;
 	unsigned long flags;
 
-	ret = __spi_validate(spi, message);
-	if (ret != 0)
+	ret = spi_maybe_optimize_message(spi, message);
+	if (ret)
 		return ret;
 
 	spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags);
@@ -4271,6 +4412,8 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
 
 	spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags);
 
+	spi_maybe_unoptimize_message(message);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(spi_async);
@@ -4331,8 +4474,8 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message)
 		return -ESHUTDOWN;
 	}
 
-	status = __spi_validate(spi, message);
-	if (status != 0)
+	status = spi_maybe_optimize_message(spi, message);
+	if (status)
 		return status;
 
 	SPI_STATISTICS_INCREMENT_FIELD(ctlr->pcpu_statistics, spi_sync);
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 2b8e2746769a..ddfb66dd4caf 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -475,6 +475,8 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
  *
  * @set_cs: set the logic level of the chip select line.  May be called
  *          from interrupt context.
+ * @optimize_message: optimize the message for reuse
+ * @unoptimize_message: release resources allocated by optimize_message
  * @prepare_message: set up the controller to transfer a single message,
  *                   for example doing DMA mapping.  Called from threaded
  *                   context.
@@ -715,6 +717,8 @@ struct spi_controller {
 	struct completion               xfer_completion;
 	size_t				max_dma_len;
 
+	int (*optimize_message)(struct spi_message *msg);
+	int (*unoptimize_message)(struct spi_message *msg);
 	int (*prepare_transfer_hardware)(struct spi_controller *ctlr);
 	int (*transfer_one_message)(struct spi_controller *ctlr,
 				    struct spi_message *mesg);
@@ -1111,6 +1115,8 @@ struct spi_transfer {
  * @spi: SPI device to which the transaction is queued
  * @is_dma_mapped: if true, the caller provided both DMA and CPU virtual
  *	addresses for each transfer buffer
+ * @pre_optimized: peripheral driver pre-optimized the message
+ * @optimized: the message is in the optimized state
  * @prepared: spi_prepare_message was called for the this message
  * @status: zero for success, else negative errno
  * @complete: called to report transaction completions
@@ -1120,6 +1126,7 @@ struct spi_transfer {
  *	successful segments
  * @queue: for use by whichever driver currently owns the message
  * @state: for use by whichever driver currently owns the message
+ * @opt_state: for use by whichever driver currently owns the message
  * @resources: for resource management when the SPI message is processed
  *
  * A @spi_message is used to execute an atomic sequence of data transfers,
@@ -1143,6 +1150,11 @@ struct spi_message {
 
 	unsigned		is_dma_mapped:1;
 
+	/* spi_optimize_message() was called for this message */
+	bool			pre_optimized;
+	/* __spi_optimize_message() was called for this message */
+	bool			optimized;
+
 	/* spi_prepare_message() was called for this message */
 	bool			prepared;
 
@@ -1172,6 +1184,11 @@ struct spi_message {
 	 */
 	struct list_head	queue;
 	void			*state;
+	/*
+	 * Optional state for use by controller driver between calls to
+	 * __spi_optimize_message() and __spi_unoptimize_message().
+	 */
+	void			*opt_state;
 
 	/* List of spi_res resources when the SPI message is processed */
 	struct list_head        resources;
@@ -1255,6 +1272,9 @@ static inline void spi_message_free(struct spi_message *m)
 	kfree(m);
 }
 
+extern int spi_optimize_message(struct spi_device *spi, struct spi_message *msg);
+extern void spi_unoptimize_message(struct spi_message *msg);
+
 extern int spi_setup(struct spi_device *spi);
 extern int spi_async(struct spi_device *spi, struct spi_message *message);
 extern int spi_slave_abort(struct spi_device *spi);

-- 
2.43.2



From dlechner at baylibre.com  Mon Feb 19 14:33:19 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 19 Feb 2024 16:33:19 -0600
Subject: [PATCH v2 2/5] spi: move splitting transfers to spi_optimize_message()
In-Reply-To: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
Message-ID: <20240219-mainline-spi-precook-message-v2-2-4a762c6701b9@baylibre.com>

Splitting transfers is an expensive operation so we can potentially
optimize it by doing it only once per optimization of the message
instead of repeating each time the message is transferred.

The transfer splitting functions are currently the only user of
spi_res_alloc() so spi_res_release() can be safely moved at this time
from spi_finalize_current_message() to spi_unoptimize_message().

The doc comments of the public functions for splitting transfers are
also updated so that callers will know when it is safe to call them
to ensure proper resource management.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: David Lechner <dlechner at baylibre.com>
---

v2 changes:
- Changed line break for multiline if condition
- Removed kernel doc inclusion (/** -> /*) from static members
- Picked up Jonathan's Reviewed-by

 drivers/spi/spi.c | 110 +++++++++++++++++++++++++++++++++---------------------
 1 file changed, 68 insertions(+), 42 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index f68d92b57543..ba4d3fde2054 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1747,38 +1747,6 @@ static int __spi_pump_transfer_message(struct spi_controller *ctlr,
 
 	trace_spi_message_start(msg);
 
-	/*
-	 * If an SPI controller does not support toggling the CS line on each
-	 * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO
-	 * for the CS line, we can emulate the CS-per-word hardware function by
-	 * splitting transfers into one-word transfers and ensuring that
-	 * cs_change is set for each transfer.
-	 */
-	if ((msg->spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
-					       spi_is_csgpiod(msg->spi))) {
-		ret = spi_split_transfers_maxwords(ctlr, msg, 1);
-		if (ret) {
-			msg->status = ret;
-			spi_finalize_current_message(ctlr);
-			return ret;
-		}
-
-		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
-			/* Don't change cs_change on the last entry in the list */
-			if (list_is_last(&xfer->transfer_list, &msg->transfers))
-				break;
-			xfer->cs_change = 1;
-		}
-	} else {
-		ret = spi_split_transfers_maxsize(ctlr, msg,
-						  spi_max_transfer_size(msg->spi));
-		if (ret) {
-			msg->status = ret;
-			spi_finalize_current_message(ctlr);
-			return ret;
-		}
-	}
-
 	if (ctlr->prepare_message) {
 		ret = ctlr->prepare_message(ctlr, msg);
 		if (ret) {
@@ -2124,6 +2092,8 @@ static void __spi_unoptimize_message(struct spi_message *msg)
 	if (ctlr->unoptimize_message)
 		ctlr->unoptimize_message(msg);
 
+	spi_res_release(ctlr, msg);
+
 	msg->optimized = false;
 	msg->opt_state = NULL;
 }
@@ -2169,15 +2139,6 @@ void spi_finalize_current_message(struct spi_controller *ctlr)
 
 	spi_unmap_msg(ctlr, mesg);
 
-	/*
-	 * In the prepare_messages callback the SPI bus has the opportunity
-	 * to split a transfer to smaller chunks.
-	 *
-	 * Release the split transfers here since spi_map_msg() is done on
-	 * the split transfers.
-	 */
-	spi_res_release(ctlr, mesg);
-
 	if (mesg->prepared && ctlr->unprepare_message) {
 		ret = ctlr->unprepare_message(ctlr, mesg);
 		if (ret) {
@@ -3819,6 +3780,10 @@ static int __spi_split_transfer_maxsize(struct spi_controller *ctlr,
  * @msg:   the @spi_message to transform
  * @maxsize:  the maximum when to apply this
  *
+ * This function allocates resources that are automatically freed during the
+ * spi message unoptimize phase so this function should only be called from
+ * optimize_message callbacks.
+ *
  * Return: status of transformation
  */
 int spi_split_transfers_maxsize(struct spi_controller *ctlr,
@@ -3857,6 +3822,10 @@ EXPORT_SYMBOL_GPL(spi_split_transfers_maxsize);
  * @msg:      the @spi_message to transform
  * @maxwords: the number of words to limit each transfer to
  *
+ * This function allocates resources that are automatically freed during the
+ * spi message unoptimize phase so this function should only be called from
+ * optimize_message callbacks.
+ *
  * Return: status of transformation
  */
 int spi_split_transfers_maxwords(struct spi_controller *ctlr,
@@ -4231,6 +4200,57 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
 	return 0;
 }
 
+/*
+ * spi_split_transfers - generic handling of transfer splitting
+ * @msg: the message to split
+ *
+ * Under certain conditions, a SPI controller may not support arbitrary
+ * transfer sizes or other features required by a peripheral. This function
+ * will split the transfers in the message into smaller transfers that are
+ * supported by the controller.
+ *
+ * Controllers with special requirements not covered here can also split
+ * transfers in the optimize_message() callback.
+ *
+ * Context: can sleep
+ * Return: zero on success, else a negative error code
+ */
+static int spi_split_transfers(struct spi_message *msg)
+{
+	struct spi_controller *ctlr = msg->spi->controller;
+	struct spi_transfer *xfer;
+	int ret;
+
+	/*
+	 * If an SPI controller does not support toggling the CS line on each
+	 * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO
+	 * for the CS line, we can emulate the CS-per-word hardware function by
+	 * splitting transfers into one-word transfers and ensuring that
+	 * cs_change is set for each transfer.
+	 */
+	if ((msg->spi->mode & SPI_CS_WORD) &&
+	    (!(ctlr->mode_bits & SPI_CS_WORD) || spi_is_csgpiod(msg->spi))) {
+		ret = spi_split_transfers_maxwords(ctlr, msg, 1);
+		if (ret)
+			return ret;
+
+		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+			/* Don't change cs_change on the last entry in the list */
+			if (list_is_last(&xfer->transfer_list, &msg->transfers))
+				break;
+
+			xfer->cs_change = 1;
+		}
+	} else {
+		ret = spi_split_transfers_maxsize(ctlr, msg,
+						  spi_max_transfer_size(msg->spi));
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 /*
  * __spi_optimize_message - shared implementation for spi_optimize_message()
  *                          and spi_maybe_optimize_message()
@@ -4254,10 +4274,16 @@ static int __spi_optimize_message(struct spi_device *spi,
 	if (ret)
 		return ret;
 
+	ret = spi_split_transfers(msg);
+	if (ret)
+		return ret;
+
 	if (ctlr->optimize_message) {
 		ret = ctlr->optimize_message(msg);
-		if (ret)
+		if (ret) {
+			spi_res_release(ctlr, msg);
 			return ret;
+		}
 	}
 
 	msg->optimized = true;

-- 
2.43.2



From dlechner at baylibre.com  Mon Feb 19 14:33:20 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 19 Feb 2024 16:33:20 -0600
Subject: [PATCH v2 3/5] spi: stm32: move splitting transfers to optimize_message
In-Reply-To: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
Message-ID: <20240219-mainline-spi-precook-message-v2-3-4a762c6701b9@baylibre.com>

Since splitting transfers was moved to spi_optimize_message() in the
core SPI code, we now need to use the optimize_message callback in the
STM32 SPI driver to ensure that the operation is only performed once
when spi_optimize_message() is used by peripheral drivers explicitly.

Signed-off-by: David Lechner <dlechner at baylibre.com>
---

v2 changes: none

 drivers/spi/spi-stm32.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index c32e57bb38bd..e4e7ddb7524a 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -1118,6 +1118,21 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int stm32_spi_optimize_message(struct spi_message *msg)
+{
+	struct spi_controller *ctrl = msg->spi->controller;
+	struct stm32_spi *spi = spi_controller_get_devdata(ctrl);
+
+	/* On STM32H7, messages should not exceed a maximum size set
+	 * later via the set_number_of_data function. In order to
+	 * ensure that, split large messages into several messages
+	 */
+	if (spi->cfg->set_number_of_data)
+		return spi_split_transfers_maxwords(ctrl, msg, spi->t_size_max);
+
+	return 0;
+}
+
 /**
  * stm32_spi_prepare_msg - set up the controller to transfer a single message
  * @ctrl: controller interface
@@ -1163,18 +1178,6 @@ static int stm32_spi_prepare_msg(struct spi_controller *ctrl,
 		!!(spi_dev->mode & SPI_LSB_FIRST),
 		!!(spi_dev->mode & SPI_CS_HIGH));
 
-	/* On STM32H7, messages should not exceed a maximum size setted
-	 * afterward via the set_number_of_data function. In order to
-	 * ensure that, split large messages into several messages
-	 */
-	if (spi->cfg->set_number_of_data) {
-		int ret;
-
-		ret = spi_split_transfers_maxwords(ctrl, msg, spi->t_size_max);
-		if (ret)
-			return ret;
-	}
-
 	spin_lock_irqsave(&spi->lock, flags);
 
 	/* CPOL, CPHA and LSB FIRST bits have common register */
@@ -2180,6 +2183,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
 	ctrl->max_speed_hz = spi->clk_rate / spi->cfg->baud_rate_div_min;
 	ctrl->min_speed_hz = spi->clk_rate / spi->cfg->baud_rate_div_max;
 	ctrl->use_gpio_descriptors = true;
+	ctrl->optimize_message = stm32_spi_optimize_message;
 	ctrl->prepare_message = stm32_spi_prepare_msg;
 	ctrl->transfer_one = stm32_spi_transfer_one;
 	ctrl->unprepare_message = stm32_spi_unprepare_msg;

-- 
2.43.2



From dlechner at baylibre.com  Mon Feb 19 14:33:22 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 19 Feb 2024 16:33:22 -0600
Subject: [PATCH v2 5/5] iio: adc: ad7380: use spi_optimize_message()
In-Reply-To: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
Message-ID: <20240219-mainline-spi-precook-message-v2-5-4a762c6701b9@baylibre.com>

This modifies the ad7380 ADC driver to use spi_optimize_message() to
optimize the SPI message for the buffered read operation. Since buffered
reads reuse the same SPI message for each read, this can improve
performance by reducing the overhead of setting up some parts the SPI
message in each spi_sync() call.

Signed-off-by: David Lechner <dlechner at baylibre.com>
---

v2 changes:
- Removed dynamic allocation of spi xfer/msg
- Moved spi message optimization to probe function
- Dropped buffer pre/post callbacks

 drivers/iio/adc/ad7380.c | 36 ++++++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
index abd746aef868..6b3fd20c8f1f 100644
--- a/drivers/iio/adc/ad7380.c
+++ b/drivers/iio/adc/ad7380.c
@@ -133,6 +133,9 @@ struct ad7380_state {
 	struct spi_device *spi;
 	struct regulator *vref;
 	struct regmap *regmap;
+	/* xfer and msg for buffer reads */
+	struct spi_transfer xfer;
+	struct spi_message msg;
 	/*
 	 * DMA (thus cache coherency maintenance) requires the
 	 * transfer buffers to live in their own cache lines.
@@ -236,14 +239,9 @@ static irqreturn_t ad7380_trigger_handler(int irq, void *p)
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->indio_dev;
 	struct ad7380_state *st = iio_priv(indio_dev);
-	struct spi_transfer xfer = {
-		.bits_per_word = st->chip_info->channels[0].scan_type.realbits,
-		.len = 4,
-		.rx_buf = st->scan_data.raw,
-	};
 	int ret;
 
-	ret = spi_sync_transfer(st->spi, &xfer, 1);
+	ret = spi_sync(st->spi, &st->msg);
 	if (ret)
 		goto out;
 
@@ -335,6 +333,28 @@ static const struct iio_info ad7380_info = {
 	.debugfs_reg_access = &ad7380_debugfs_reg_access,
 };
 
+static void ad7380_unoptimize_spi_msg(void *msg)
+{
+	spi_unoptimize_message(msg);
+}
+
+static int devm_ad7380_setup_spi_msg(struct device *dev, struct ad7380_state *st)
+{
+	int ret;
+
+	st->xfer.bits_per_word = st->chip_info->channels[0].scan_type.realbits;
+	st->xfer.len = 4;
+	st->xfer.rx_buf = st->scan_data.raw;
+
+	spi_message_init_with_transfers(&st->msg, &st->xfer, 1);
+
+	ret = spi_optimize_message(st->spi, &st->msg);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to optimize message\n");
+
+	return devm_add_action_or_reset(dev, ad7380_unoptimize_spi_msg, &st->msg);
+}
+
 static int ad7380_init(struct ad7380_state *st)
 {
 	int ret;
@@ -411,6 +431,10 @@ static int ad7380_probe(struct spi_device *spi)
 		return dev_err_probe(&spi->dev, PTR_ERR(st->regmap),
 				     "failed to allocate register map\n");
 
+	ret = devm_ad7380_setup_spi_msg(&spi->dev, st);
+	if (ret)
+		return ret;
+
 	indio_dev->channels = st->chip_info->channels;
 	indio_dev->num_channels = st->chip_info->num_channels;
 	indio_dev->name = st->chip_info->name;

-- 
2.43.2



From dlechner at baylibre.com  Mon Feb 19 14:33:21 2024
From: dlechner at baylibre.com (David Lechner)
Date: Mon, 19 Feb 2024 16:33:21 -0600
Subject: [PATCH v2 4/5] spi: axi-spi-engine: move message compile to optimize_message
In-Reply-To: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
Message-ID: <20240219-mainline-spi-precook-message-v2-4-4a762c6701b9@baylibre.com>

In the AXI SPI Engine driver, compiling the message is an expensive
operation. Previously, it was done per message transfer in the
prepare_message hook. This patch moves the message compile to the
optimize_message hook so that it is only done once per message in
cases where the peripheral driver calls spi_optimize_message().

This can be a significant performance improvement for some peripherals.
For example, the ad7380 driver saw a 13% improvement in throughput
when using the AXI SPI Engine driver with this patch.

Since we now need two message states, one for the optimization stage
that doesn't change for the lifetime of the message and one that is
reset on each transfer for managing the current transfer state, the old
msg->state is split into msg->opt_state and spi_engine->msg_state. The
latter is included in the driver struct now since there is only one
current message at a time that can ever use it and it is in a hot path
so avoiding allocating a new one on each message transfer saves a few
cpu cycles and lets us get rid of the prepare_message callback.

Signed-off-by: David Lechner <dlechner at baylibre.com>
---

v2 changes: none

 drivers/spi/spi-axi-spi-engine.c | 40 +++++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c
index ca66d202f0e2..6177c1a8d56e 100644
--- a/drivers/spi/spi-axi-spi-engine.c
+++ b/drivers/spi/spi-axi-spi-engine.c
@@ -109,6 +109,7 @@ struct spi_engine {
 	spinlock_t lock;
 
 	void __iomem *base;
+	struct spi_engine_message_state msg_state;
 	struct completion msg_complete;
 	unsigned int int_enable;
 };
@@ -499,17 +500,11 @@ static irqreturn_t spi_engine_irq(int irq, void *devid)
 	return IRQ_HANDLED;
 }
 
-static int spi_engine_prepare_message(struct spi_controller *host,
-				      struct spi_message *msg)
+static int spi_engine_optimize_message(struct spi_message *msg)
 {
 	struct spi_engine_program p_dry, *p;
-	struct spi_engine_message_state *st;
 	size_t size;
 
-	st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (!st)
-		return -ENOMEM;
-
 	spi_engine_precompile_message(msg);
 
 	p_dry.length = 0;
@@ -517,31 +512,22 @@ static int spi_engine_prepare_message(struct spi_controller *host,
 
 	size = sizeof(*p->instructions) * (p_dry.length + 1);
 	p = kzalloc(sizeof(*p) + size, GFP_KERNEL);
-	if (!p) {
-		kfree(st);
+	if (!p)
 		return -ENOMEM;
-	}
 
 	spi_engine_compile_message(msg, false, p);
 
 	spi_engine_program_add_cmd(p, false, SPI_ENGINE_CMD_SYNC(
 						AXI_SPI_ENGINE_CUR_MSG_SYNC_ID));
 
-	st->p = p;
-	st->cmd_buf = p->instructions;
-	st->cmd_length = p->length;
-	msg->state = st;
+	msg->opt_state = p;
 
 	return 0;
 }
 
-static int spi_engine_unprepare_message(struct spi_controller *host,
-					struct spi_message *msg)
+static int spi_engine_unoptimize_message(struct spi_message *msg)
 {
-	struct spi_engine_message_state *st = msg->state;
-
-	kfree(st->p);
-	kfree(st);
+	kfree(msg->opt_state);
 
 	return 0;
 }
@@ -550,10 +536,18 @@ static int spi_engine_transfer_one_message(struct spi_controller *host,
 	struct spi_message *msg)
 {
 	struct spi_engine *spi_engine = spi_controller_get_devdata(host);
-	struct spi_engine_message_state *st = msg->state;
+	struct spi_engine_message_state *st = &spi_engine->msg_state;
+	struct spi_engine_program *p = msg->opt_state;
 	unsigned int int_enable = 0;
 	unsigned long flags;
 
+	/* reinitialize message state for this transfer */
+	memset(st, 0, sizeof(*st));
+	st->p = p;
+	st->cmd_buf = p->instructions;
+	st->cmd_length = p->length;
+	msg->state = st;
+
 	reinit_completion(&spi_engine->msg_complete);
 
 	spin_lock_irqsave(&spi_engine->lock, flags);
@@ -658,8 +652,8 @@ static int spi_engine_probe(struct platform_device *pdev)
 	host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
 	host->max_speed_hz = clk_get_rate(spi_engine->ref_clk) / 2;
 	host->transfer_one_message = spi_engine_transfer_one_message;
-	host->prepare_message = spi_engine_prepare_message;
-	host->unprepare_message = spi_engine_unprepare_message;
+	host->optimize_message = spi_engine_optimize_message;
+	host->unoptimize_message = spi_engine_unoptimize_message;
 	host->num_chipselect = 8;
 
 	if (host->max_speed_hz == 0)

-- 
2.43.2



From efectn at 6tel.net  Mon Feb 19 14:34:18 2024
From: efectn at 6tel.net (efectn at 6tel.net)
Date: Tue, 20 Feb 2024 01:34:18 +0300
Subject: [PATCH 2/9] arm64: dts: rockchip: Add PMIC to Khadas Edge 2
In-Reply-To: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
References: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
Message-ID: <617faf64a68f5af560267d77fd23fc9fb23e6c88.1708381247.git.efectn@protonmail.com>

From: Muhammed Efe Cetin <efectn at protonmail.com>

This commit adds PMIC to Khadas Edge 2 board.

Signed-off-by: Muhammed Efe Cetin <efectn at protonmail.com>
---
 .../dts/rockchip/rk3588s-khadas-edge2.dts     | 335 ++++++++++++++++++
 1 file changed, 335 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
index 1d1ce70a0f3a..b99d2b82c787 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
@@ -26,6 +26,16 @@ vcc5v0_sys: vcc5v0-sys-regulator {
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
 	};
+
+	vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v1_nldo_s3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
 };
 
 &cpu_b0 {
@@ -110,6 +120,331 @@ &sdhci {
 	status = "okay";
 };
 
+&spi2 {
+	status = "okay";
+	assigned-clocks = <&cru CLK_SPI2>;
+	assigned-clock-rates = <200000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+	num-cs = <1>;
+
+	pmic at 0 {
+		compatible = "rockchip,rk806";
+		spi-max-frequency = <1000000>;
+		reg = <0x0>;
+
+		interrupt-parent = <&gpio0>;
+		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+		system-power-controller;
+
+		vcc1-supply = <&vcc5v0_sys>;
+		vcc2-supply = <&vcc5v0_sys>;
+		vcc3-supply = <&vcc5v0_sys>;
+		vcc4-supply = <&vcc5v0_sys>;
+		vcc5-supply = <&vcc5v0_sys>;
+		vcc6-supply = <&vcc5v0_sys>;
+		vcc7-supply = <&vcc5v0_sys>;
+		vcc8-supply = <&vcc5v0_sys>;
+		vcc9-supply = <&vcc5v0_sys>;
+		vcc10-supply = <&vcc5v0_sys>;
+		vcc11-supply = <&vcc_2v0_pldo_s3>;
+		vcc12-supply = <&vcc5v0_sys>;
+		vcc13-supply = <&vcc_1v1_nldo_s3>;
+		vcc14-supply = <&vcc_1v1_nldo_s3>;
+		vcca-supply = <&vcc5v0_sys>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		rk806_dvs1_null: dvs1-null-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs2_null: dvs2-null-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs3_null: dvs3-null-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun0";
+		};
+
+		regulators {
+			vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_gpu_s0";
+				regulator-enable-ramp-delay = <400>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_cpu_lit_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_log_s0: dcdc-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <750000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_log_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_vdenc_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_ddr_s0: dcdc-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <900000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_ddr_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vdd2_ddr_s3: dcdc-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vdd2_ddr_s3";
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_2v0_pldo_s3: dcdc-reg7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <2000000>;
+				regulator-max-microvolt = <2000000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_2v0_pldo_s3";
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <2000000>;
+				};
+			};
+
+			vcc_3v3_s3: dcdc-reg8 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_3v3_s3";
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vddq_ddr_s0: dcdc-reg9 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vddq_ddr_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s3: dcdc-reg10 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8_s3";
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			avcc_1v8_s0: pldo-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "avcc_1v8_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s0: pldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			avdd_1v2_s0: pldo-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-name = "avdd_1v2_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3_s0: pldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vcc_3v3_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd_s0: pldo-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vccio_sd_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			pldo6_s3: pldo-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "pldo6_s3";
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_0v75_s3: nldo-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdd_0v75_s3";
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_ddr_pll_s0: nldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdd_ddr_pll_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			avdd_0v75_s0: nldo-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "avdd_0v75_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_0v85_s0: nldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdd_0v85_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_0v75_s0: nldo-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdd_0v75_s0";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
 &uart2 {
 	pinctrl-0 = <&uart2m0_xfer>;
 	status = "okay";
-- 
2.43.1



From efectn at 6tel.net  Mon Feb 19 14:34:21 2024
From: efectn at 6tel.net (efectn at 6tel.net)
Date: Tue, 20 Feb 2024 01:34:21 +0300
Subject: [PATCH 5/9] arm64: dts: rockchip: Add ir receiver and leds to Khadas Edge 2
In-Reply-To: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
References: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
Message-ID: <335629f57e593e20418a4a55a1e662505640cbde.1708381247.git.efectn@protonmail.com>

From: Muhammed Efe Cetin <efectn at protonmail.com>

Khadas Edge 2 exposes IR receiver pins as same as TF card via EXTIO. The
IR receiver is connected to MCU and SoC.

The board also has 2 PWM RGB leds. One is controlled by MCU and the
other is controlled by SoC. This commit adds support for the led
controlled by SoC using pwm-leds.

Signed-off-by: Muhammed Efe Cetin <efectn at protonmail.com>
---
 .../dts/rockchip/rk3588s-khadas-edge2.dts     | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
index ea7f1bb7c908..5a3b52e62dce 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
@@ -4,6 +4,7 @@
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/leds/common.h>
 #include "rk3588s.dtsi"
 
 / {
@@ -19,6 +20,47 @@ chosen {
 		stdout-path = "serial2:1500000n8";
 	};
 
+	ir-receiver {
+		compatible = "gpio-ir-receiver";
+		gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&ir_receiver_pin>;
+	};
+
+	leds {
+		compatible = "pwm-leds";
+
+		red_led: led-0 {
+			label = "red_led";
+			linux,default-trigger = "none";
+			default-state = "off";
+			function = LED_FUNCTION_INDICATOR;
+			color = <LED_COLOR_ID_RED>;
+			max-brightness = <255>;
+			pwms = <&pwm11 0 25000 0>;
+		};
+
+		green_led: led-1 {
+			label = "green_led";
+			linux,default-trigger = "default-on";
+			default-state = "on";
+			function = LED_FUNCTION_POWER;
+			color = <LED_COLOR_ID_GREEN>;
+			max-brightness = <255>;
+			pwms = <&pwm14 0 25000 0>;
+		};
+
+		blue_led: led-2 {
+			label = "blue_led";
+			linux,default-trigger = "none";
+			default-state = "off";
+			function = LED_FUNCTION_INDICATOR;
+			color = <LED_COLOR_ID_BLUE>;
+			max-brightness = <255>;
+			pwms = <&pwm15 0 25000 0>;
+		};
+	};
+
 	vcc5v0_sys: vcc5v0-sys-regulator {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc5v0_sys";
@@ -181,6 +223,12 @@ vcc5v0_host_en: vcc5v0-host-en {
 			rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
+
+	ir-receiver {
+		ir_receiver_pin: ir-receiver-pin {
+			rockchip,pins = <1  RK_PA7  RK_FUNC_GPIO  &pcfg_pull_none>;
+		};
+	};
 };
 
 &pcie2x1l2 {
@@ -191,6 +239,24 @@ &pcie2x1l2 {
 	status = "okay";
 };
 
+&pwm11 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm11m1_pins>;
+	status = "okay";
+};
+
+&pwm14 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm14m1_pins>;
+	status = "okay";
+};
+
+&pwm15 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm15m1_pins>;
+	status = "okay";
+};
+
 &sdhci {
 	bus-width = <8>;
 	no-sdio;
-- 
2.43.1



From efectn at 6tel.net  Mon Feb 19 14:34:20 2024
From: efectn at 6tel.net (efectn at 6tel.net)
Date: Tue, 20 Feb 2024 01:34:20 +0300
Subject: [PATCH 4/9] arm64: dts: rockchip: USB2, USB3 Host, PCIe2 to Khadas Edge 2
In-Reply-To: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
References: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
Message-ID: <4d22afd70e5583458f405f5170f67690584e7efa.1708381247.git.efectn@protonmail.com>

From: Muhammed Efe Cetin <efectn at protonmail.com>

Khadas Edge 2 has 1x USB2 with hub, 1x USB3 Host and 1x USB-C.
This commit adds support for PCIe2, USB3 Host and USB2.

Signed-off-by: Muhammed Efe Cetin <efectn at protonmail.com>
---
 .../dts/rockchip/rk3588s-khadas-edge2.dts     | 97 +++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
index 856ce4f869a2..ea7f1bb7c908 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
@@ -38,6 +38,33 @@ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
 		vin-supply = <&vcc5v0_sys>;
 	};
 
+	vcc5v0_host: vcc5v0-host-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_host";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_host_en>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc3v3_pcie_wl: vcc3v3-pcie-wl-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pcie2_2_vcc3v3_en>;
+		regulator-name = "vcc3v3_pcie_wl";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		startup-delay-us = <5000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
 	vdd_3v3_sd: vdd-3v3-sd-regulator {
 		compatible = "regulator-fixed";
 		regulator-name = "vdd_3v3_sd";
@@ -84,6 +111,14 @@ &cpu_l3 {
 	cpu-supply = <&vdd_cpu_lit_s0>;
 };
 
+&combphy0_ps {
+	status = "okay";
+};
+
+&combphy2_psu {
+	status = "okay";
+};
+
 &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0m2_xfer>;
@@ -130,6 +165,30 @@ vdd_sd_en: vdd-sd-en {
 			rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
 	};
+
+	pcie2 {
+		pcie2_2_rst: pcie2-2-rst {
+			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		pcie2_2_vcc3v3_en: pcie2-2-vcc-en {
+			rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		vcc5v0_host_en: vcc5v0-host-en {
+			rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pcie2x1l2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie2_2_rst>;
+	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_pcie_wl>;
+	status = "okay";
 };
 
 &sdhci {
@@ -483,3 +542,41 @@ &uart2 {
 	pinctrl-0 = <&uart2m0_xfer>;
 	status = "okay";
 };
+
+&u2phy2 {
+	status = "okay";
+};
+
+&u2phy2_host {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+&u2phy3 {
+	status = "okay";
+};
+
+&u2phy3_host {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&usb_host2_xhci {
+	status = "okay";
+};
-- 
2.43.1



From efectn at 6tel.net  Mon Feb 19 14:34:24 2024
From: efectn at 6tel.net (efectn at 6tel.net)
Date: Tue, 20 Feb 2024 01:34:24 +0300
Subject: [PATCH 8/9] arm64: dts: rockchip: Add UART9 (bluetooth) to Khadas Edge 2
In-Reply-To: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
References: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
Message-ID: <0a10afeff3aec3a8bccca2dbe4e65f7b4a2c4666.1708381247.git.efectn@protonmail.com>

From: Muhammed Efe Cetin <efectn at protonmail.com>

Khadas Edge 2 has onboard AP6275P Wi-Fi6 (PCIe2) and BT5 (UART9) module.
This commit enables UART9.

Signed-off-by: Muhammed Efe Cetin <efectn at protonmail.com>
---
 .../dts/rockchip/rk3588s-khadas-edge2.dts     | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
index c2a329f151a1..767e21b2dc34 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
@@ -244,6 +244,20 @@ ir_receiver_pin: ir-receiver-pin {
 			rockchip,pins = <1  RK_PA7  RK_FUNC_GPIO  &pcfg_pull_none>;
 		};
 	};
+
+	wireless-bluetooth {
+		bt_reset_pin: bt-reset-pin {
+			rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bt_wake_pin: bt-wake-pin {
+			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		bt_wake_host_irq: bt-wake-host-irq {
+			rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
 };
 
 &pcie2x1l2 {
@@ -647,6 +661,12 @@ &uart2 {
 	status = "okay";
 };
 
+&uart9 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart9m2_xfer &uart9m2_ctsn>;
+	status = "okay";
+};
+
 &u2phy2 {
 	status = "okay";
 };
-- 
2.43.1



From efectn at 6tel.net  Mon Feb 19 14:34:17 2024
From: efectn at 6tel.net (efectn at 6tel.net)
Date: Tue, 20 Feb 2024 01:34:17 +0300
Subject: [PATCH 1/9] arm64: dts: rockchip: Add cpu regulators and vcc5v0_sys to Khadas Edge 2
Message-ID: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>

From: Muhammed Efe Cetin <efectn at protonmail.com>

This commit adds 5V fixed power regulator and CPU regulators to Khadas
Edge 2.

Signed-off-by: Muhammed Efe Cetin <efectn at protonmail.com>
---
 .../dts/rockchip/rk3588s-khadas-edge2.dts     | 81 +++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
index f53e993c785e..1d1ce70a0f3a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
@@ -17,6 +17,87 @@ aliases {
 	chosen {
 		stdout-path = "serial2:1500000n8";
 	};
+
+	vcc5v0_sys: vcc5v0-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+};
+
+&cpu_b0 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0m2_xfer>;
+	status = "okay";
+
+	vdd_cpu_big0_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu_big0_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	vdd_cpu_big1_s0: regulator at 43 {
+		compatible = "rockchip,rk8603", "rockchip,rk8602";
+		reg = <0x43>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu_big1_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
 };
 
 &sdhci {
-- 
2.43.1



From efectn at 6tel.net  Mon Feb 19 14:34:19 2024
From: efectn at 6tel.net (efectn at 6tel.net)
Date: Tue, 20 Feb 2024 01:34:19 +0300
Subject: [PATCH 3/9] arm64: dts: rockchip: Add TF card to Khadas Edge 2
In-Reply-To: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
References: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
Message-ID: <6e9062feb40bbad304f2e5bb300601034e805081.1708381247.git.efectn@protonmail.com>

From: Muhammed Efe Cetin <efectn at protonmail.com>

Add TF card support to Khadas Edge 2.
The board exposes sdmmc pins via EXTIO. TF card can be used with IO
module.

Signed-off-by: Muhammed Efe Cetin <efectn at protonmail.com>
---
 .../dts/rockchip/rk3588s-khadas-edge2.dts     | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
index b99d2b82c787..856ce4f869a2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
@@ -12,6 +12,7 @@ / {
 
 	aliases {
 		mmc0 = &sdhci;
+		mmc1 = &sdmmc;
 	};
 
 	chosen {
@@ -36,6 +37,19 @@ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
 		regulator-max-microvolt = <1100000>;
 		vin-supply = <&vcc5v0_sys>;
 	};
+
+	vdd_3v3_sd: vdd-3v3-sd-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_3v3_sd";
+		gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>;
+		regulator-boot-on;
+		enable-active-high;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_3v3_s3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vdd_sd_en>;
+	};
 };
 
 &cpu_b0 {
@@ -110,6 +124,14 @@ regulator-state-mem {
 	};
 };
 
+&pinctrl {
+	vdd_sd {
+		vdd_sd_en: vdd-sd-en {
+			rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
 &sdhci {
 	bus-width = <8>;
 	no-sdio;
@@ -120,6 +142,18 @@ &sdhci {
 	status = "okay";
 };
 
+&sdmmc {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	disable-wp;
+	no-mmc;
+	no-sdio;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vdd_3v3_sd>;
+	vqmmc-supply = <&vccio_sd_s0>;
+	status = "okay";
+};
+
 &spi2 {
 	status = "okay";
 	assigned-clocks = <&cru CLK_SPI2>;
-- 
2.43.1



From efectn at 6tel.net  Mon Feb 19 14:34:23 2024
From: efectn at 6tel.net (efectn at 6tel.net)
Date: Tue, 20 Feb 2024 01:34:23 +0300
Subject: [PATCH 7/9] arm64: dts: rockchip: Add SFC to Khadas Edge 2
In-Reply-To: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
References: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
Message-ID: <00942603f7e61ecb2a0067bebf6795dab3571613.1708381247.git.efectn@protonmail.com>

From: Muhammed Efe Cetin <efectn at protonmail.com>

This commit adds SPI flash support for Khadas Edge 2.

Signed-off-by: Muhammed Efe Cetin <efectn at protonmail.com>
---
 .../boot/dts/rockchip/rk3588s-khadas-edge2.dts     | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
index dfcdbec3534d..c2a329f151a1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
@@ -299,6 +299,20 @@ &sdmmc {
 	status = "okay";
 };
 
+&sfc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&fspim2_pins>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-max-frequency = <100000000>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
+	};
+};
+
 &spi2 {
 	status = "okay";
 	assigned-clocks = <&cru CLK_SPI2>;
-- 
2.43.1



From efectn at 6tel.net  Mon Feb 19 14:34:22 2024
From: efectn at 6tel.net (efectn at 6tel.net)
Date: Tue, 20 Feb 2024 01:34:22 +0300
Subject: [PATCH 6/9] arm64: dts: rockchip: Add saradc and adc buttons to Khadas Edge 2 and enable tsadc
In-Reply-To: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
References: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
Message-ID: <03feaafefd0c13268ba1630251558749654a567d.1708381247.git.efectn@protonmail.com>

From: Muhammed Efe Cetin <efectn at protonmail.com>

This commit enables tsadc, saradc and the
function button on saradc line for Khadas Edge 2.

Signed-off-by: Muhammed Efe Cetin <efectn at protonmail.com>
---
 .../dts/rockchip/rk3588s-khadas-edge2.dts     | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
index 5a3b52e62dce..dfcdbec3534d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
@@ -3,6 +3,7 @@
 /dts-v1/;
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/leds/common.h>
 #include "rk3588s.dtsi"
@@ -20,6 +21,20 @@ chosen {
 		stdout-path = "serial2:1500000n8";
 	};
 
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-function {
+			label = "Function";
+			linux,code = <KEY_FN>;
+			press-threshold-microvolt = <17000>;
+		};
+	};
+
 	ir-receiver {
 		compatible = "gpio-ir-receiver";
 		gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>;
@@ -257,6 +272,11 @@ &pwm15 {
 	status = "okay";
 };
 
+&saradc {
+	vref-supply = <&avcc_1v8_s0>;
+	status = "okay";
+};
+
 &sdhci {
 	bus-width = <8>;
 	no-sdio;
@@ -604,6 +624,10 @@ regulator-state-mem {
 	};
 };
 
+&tsadc {
+	status = "okay";
+};
+
 &uart2 {
 	pinctrl-0 = <&uart2m0_xfer>;
 	status = "okay";
-- 
2.43.1



From efectn at 6tel.net  Mon Feb 19 14:34:25 2024
From: efectn at 6tel.net (efectn at 6tel.net)
Date: Tue, 20 Feb 2024 01:34:25 +0300
Subject: [PATCH 9/9] arm64: dts: rockchip: Add RTC to Khadas Edge 2
In-Reply-To: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
References: <5a7bd2cd8703e51382abfc11242de59d45286477.1708381247.git.efectn@protonmail.com>
Message-ID: <4c4c9140ff36f290ba64ecc8b3e218df6a5ab273.1708381247.git.efectn@protonmail.com>

From: Muhammed Efe Cetin <efectn at protonmail.com>

Khadas Edge 2 has PT7C4363 RTC that compatible with HYM8563.
The RTC pinctrl is also connected to MCU.

Signed-off-by: Muhammed Efe Cetin <efectn at protonmail.com>
---
 .../arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
index 767e21b2dc34..2022a174594c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
@@ -216,6 +216,18 @@ regulator-state-mem {
 	};
 };
 
+&i2c2 {
+	status = "okay";
+
+	hym8563: rtc at 51 {
+		compatible = "haoyu,hym8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+		clock-output-names = "hym8563";
+		wakeup-source;
+	};
+};
+
 &pinctrl {
 	vdd_sd {
 		vdd_sd_en: vdd-sd-en {
-- 
2.43.1



From danielmentz at google.com  Mon Feb 19 14:47:31 2024
From: danielmentz at google.com (Daniel Mentz)
Date: Mon, 19 Feb 2024 14:47:31 -0800
Subject: [PATCH v4 20/27] iommu: Add ops->domain_alloc_sva()
In-Reply-To: <20-v4-e7091cdd9e8d+43b1-smmuv3_newapi_p2_jgg@nvidia.com>
References: <0-v4-e7091cdd9e8d+43b1-smmuv3_newapi_p2_jgg@nvidia.com> <20-v4-e7091cdd9e8d+43b1-smmuv3_newapi_p2_jgg@nvidia.com>
Message-ID: <CAE2F3rBip7oe4ip-kK5GR6+nY_efsVrrxcxv=4m4_aWGKOg=gw@mail.gmail.com>

On Fri, Jan 26, 2024 at 10:15?AM Jason Gunthorpe <jgg at nvidia.com> wrote:
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> @@ -654,7 +654,7 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
>
>  static void arm_smmu_sva_domain_free(struct iommu_domain *domain)
>  {
> -       kfree(domain);
> +       kfree(to_smmu_domain(domain));
>  }

I'm wondering if this particular change belongs into the other change
with title "iommu/arm-smmu-v3: Make SVA allocate a normal
arm_smmu_domain"


From semen.protsenko at linaro.org  Mon Feb 19 15:05:50 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 19 Feb 2024 17:05:50 -0600
Subject: [PATCH v5 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <20240219204238.356942-2-peter.griffin@linaro.org>
References: <20240219204238.356942-1-peter.griffin@linaro.org> <20240219204238.356942-2-peter.griffin@linaro.org>
Message-ID: <CAPLW+4nOq_62rBhwRUf0RW0zTiGa+-Zpt+FLcTa87biX8Nq-BA@mail.gmail.com>

On Mon, Feb 19, 2024 at 2:42?PM Peter Griffin <peter.griffin at linaro.org> wrote:
>
> Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> security hardening reasons so that they are only write accessible in el3
> via an SMC call.
>
> As most Exynos drivers that need to write PMU registers currently obtain a
> regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> is implemented in this driver using a custom regmap similar to syscon to
> handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> regmap like before. As regmaps abstract out the underlying register access
> changes to the leaf drivers are minimal.
>
> A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> that currently use syscon_regmap_lookup_by_phandle(). This also handles
> deferred probing.
>
> Tested-by: Sam Protsenko <semen.protsenko at linaro.org>
> Tested-by: Alexey Klimov <alexey.klimov at linaro.org>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
> Changes since v4:
>  - Use same argument names as in struct regmap_config
>  - Remove inline keyword and rely on compiler
>  - Update kerneldoc wording
>  - property -> propname argument rename
>  - reverse Xmas tree
>  - Only call of_node_put() when of_parse_phandle is called
>  - Collect tags
>
> Changes since v3:
>  - Fix PMUALIVE_MASK
>  - Add TENSOR_ prefix
>  - clear SET_BITS bits on each loop iteration
>  - change set_bit to set_bits in func name
>  - Fix some alignment
>  - Add missing return on dev_err_probe
>  - Reduce indentation in loop
>
> Changes since v2
>  - Add select REGMAP to Kconfig
>  - Add constant for SET/CLEAR bits
>  - Replace kerneldoc with one line comment
>  - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
>  - remove superfluous extern keyword
>  - dev_err_probe() on probe error
>  - shorten regmcfg name
>  - no compatibles inside probe, use match data
>  - don't mix declarations with/without initializations
>  - tensor_sec_reg_read() use mmio to avoid access restrictions
>  - Collect up Reviewed-by
>  - const for regmap_config structs
> ---
>  drivers/soc/samsung/Kconfig            |   1 +
>  drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
>  drivers/soc/samsung/exynos-pmu.h       |   1 +
>  include/linux/soc/samsung/exynos-pmu.h |  11 +-
>  4 files changed, 245 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 27ec99af77e3..1a5dfdc978dc 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -42,6 +42,7 @@ config EXYNOS_PMU
>         depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
>         select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
>         select MFD_CORE
> +       select REGMAP_MMIO
>
>  # There is no need to enable these drivers for ARMv8
>  config EXYNOS_PMU_ARM_DRIVERS
> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> index 250537d7cfd6..d6ae8025fdb4 100644
> --- a/drivers/soc/samsung/exynos-pmu.c
> +++ b/drivers/soc/samsung/exynos-pmu.c
> @@ -5,6 +5,7 @@
>  //
>  // Exynos - CPU PMU(Power Management Unit) support
>
> +#include <linux/arm-smccc.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/mfd/core.h>
> @@ -12,19 +13,134 @@
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/delay.h>
> +#include <linux/regmap.h>
>
>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>  #include <linux/soc/samsung/exynos-pmu.h>
>
>  #include "exynos-pmu.h"
>
> +#define PMUALIVE_MASK                  GENMASK(13, 0)
> +#define TENSOR_SET_BITS                        (BIT(15) | BIT(14))
> +#define TENSOR_CLR_BITS                        BIT(15)
> +#define TENSOR_SMC_PMU_SEC_REG         0x82000504
> +#define TENSOR_PMUREG_READ             0
> +#define TENSOR_PMUREG_WRITE            1
> +#define TENSOR_PMUREG_RMW              2
> +
>  struct exynos_pmu_context {
>         struct device *dev;
>         const struct exynos_pmu_data *pmu_data;
> +       struct regmap *pmureg;
>  };
>
>  void __iomem *pmu_base_addr;
>  static struct exynos_pmu_context *pmu_context;
> +/* forward declaration */
> +static struct platform_driver exynos_pmu_driver;
> +
> +/*
> + * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
> + * from EL3, but are still read accessible. As Linux needs to write some of
> + * these registers, the following functions are provided and exposed via
> + * regmap.
> + *
> + * Note: This SMC interface is known to be implemented on gs101 and derivative
> + * SoCs.
> + */
> +
> +/* Write to a protected PMU register. */
> +static int tensor_sec_reg_write(void *context, unsigned int reg,
> +                               unsigned int val)
> +{
> +       struct arm_smccc_res res;
> +       unsigned long pmu_base = (unsigned long)context;
> +
> +       arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> +                     TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
> +
> +       /* returns -EINVAL if access isn't allowed or 0 */
> +       if (res.a0)
> +               pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> +
> +       return (int)res.a0;
> +}
> +
> +/* Read/Modify/Write a protected PMU register. */
> +static int tensor_sec_reg_rmw(void *context, unsigned int reg,
> +                             unsigned int mask, unsigned int val)
> +{
> +       struct arm_smccc_res res;
> +       unsigned long pmu_base = (unsigned long)context;
> +
> +       arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> +                     TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
> +
> +       /* returns -EINVAL if access isn't allowed or 0 */
> +       if (res.a0)
> +               pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> +
> +       return (int)res.a0;
> +}
> +
> +/*
> + * Read a protected PMU register. All PMU registers can be read by Linux.
> + * Note: The SMC read register is not used, as only registers that can be
> + * written are readable via SMC.
> + */
> +static int tensor_sec_reg_read(void *context, unsigned int reg,
> +                              unsigned int *val)
> +{
> +       *val = pmu_raw_readl(reg);
> +       return 0;
> +}
> +
> +/*
> + * For SoCs that have set/clear bit hardware this function can be used when
> + * the PMU register will be accessed by multiple masters.
> + *
> + * For example, to set bits 13:8 in PMU reg offset 0x3e80
> + * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00);
> + *
> + * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80
> + * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00);
> + */
> +static int tensor_set_bits_atomic(void *ctx, unsigned int offset, u32 val,
> +                                 u32 mask)
> +{
> +       int ret;
> +       unsigned int i;
> +
> +       for (i = 0; i < 32; i++) {
> +               if (!(mask & BIT(i)))
> +                       continue;
> +
> +               offset &= ~TENSOR_SET_BITS;
> +
> +               if (val & BIT(i))
> +                       offset |= TENSOR_SET_BITS;
> +               else
> +                       offset |= TENSOR_CLR_BITS;
> +
> +               ret = tensor_sec_reg_write(ctx, offset, i);
> +               if (ret)
> +                       return ret;
> +       }
> +       return ret;
> +}
> +
> +static int tensor_sec_update_bits(void *ctx, unsigned int reg,
> +                                 unsigned int mask, unsigned int val)
> +{
> +       /*
> +        * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
> +        * as the target registers can be accessed by multiple masters.
> +        */
> +       if (reg > PMUALIVE_MASK)
> +               return tensor_sec_reg_rmw(ctx, reg, mask, val);
> +
> +       return tensor_set_bits_atomic(ctx, reg, val, mask);
> +}
>
>  void pmu_raw_writel(u32 val, u32 offset)
>  {
> @@ -75,11 +191,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
>  #define exynos_pmu_data_arm_ptr(data)  NULL
>  #endif
>
> +static const struct regmap_config regmap_smccfg = {
> +       .name = "pmu_regs",
> +       .reg_bits = 32,
> +       .reg_stride = 4,
> +       .val_bits = 32,
> +       .fast_io = true,
> +       .use_single_read = true,
> +       .use_single_write = true,
> +       .reg_read = tensor_sec_reg_read,
> +       .reg_write = tensor_sec_reg_write,
> +       .reg_update_bits = tensor_sec_update_bits,
> +};
> +
> +static const struct regmap_config regmap_mmiocfg = {
> +       .name = "pmu_regs",
> +       .reg_bits = 32,
> +       .reg_stride = 4,
> +       .val_bits = 32,
> +       .fast_io = true,
> +       .use_single_read = true,
> +       .use_single_write = true,
> +};
> +
> +static const struct exynos_pmu_data gs101_pmu_data = {
> +       .pmu_secure = true
> +};
> +
>  /*
>   * PMU platform driver and devicetree bindings.
>   */
>  static const struct of_device_id exynos_pmu_of_device_ids[] = {
>         {
> +               .compatible = "google,gs101-pmu",
> +               .data = &gs101_pmu_data,
> +       }, {
>                 .compatible = "samsung,exynos3250-pmu",
>                 .data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
>         }, {
> @@ -113,19 +259,75 @@ static const struct mfd_cell exynos_pmu_devs[] = {
>         { .name = "exynos-clkout", },
>  };
>
> +/**
> + * exynos_get_pmu_regmap() - Obtain pmureg regmap
> + *
> + * Find the pmureg regmap previously configured in probe() and return regmap
> + * pointer.
> + *
> + * Return: A pointer to regmap if found or ERR_PTR error value.
> + */
>  struct regmap *exynos_get_pmu_regmap(void)
>  {
>         struct device_node *np = of_find_matching_node(NULL,
>                                                       exynos_pmu_of_device_ids);
>         if (np)
> -               return syscon_node_to_regmap(np);
> +               return exynos_get_pmu_regmap_by_phandle(np, NULL);
>         return ERR_PTR(-ENODEV);
>  }
>  EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
>
> +/**
> + * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
> + * @np: Device node holding PMU phandle property
> + * @property: Name of property holding phandle value

This doesn't match the actual param name.

> + *
> + * Find the pmureg regmap previously configured in probe() and return regmap
> + * pointer.
> + *
> + * Return: A pointer to regmap if found or ERR_PTR error value.
> + */
> +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> +                                               const char *propname)
> +{
> +       struct exynos_pmu_context *ctx;
> +       struct device_node *pmu_np;
> +       struct device *dev;
> +
> +       if (propname)
> +               pmu_np = of_parse_phandle(np, propname, 0);
> +       else
> +               pmu_np = np;
> +
> +       if (!pmu_np)
> +               return ERR_PTR(-ENODEV);
> +
> +       /*
> +        * Determine if exynos-pmu device has probed and therefore regmap
> +        * has been created and can be returned to the caller. Otherwise we
> +        * return -EPROBE_DEFER.
> +        */
> +       dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
> +                                           (void *)pmu_np);
> +
> +       if (propname)
> +               of_node_put(pmu_np);
> +
> +       if (!dev)
> +               return ERR_PTR(-EPROBE_DEFER);
> +
> +       ctx = dev_get_drvdata(dev);
> +
> +       return ctx->pmureg;
> +}
> +EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
> +
>  static int exynos_pmu_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> +       struct regmap_config pmu_regmcfg;
> +       struct regmap *regmap;
> +       struct resource *res;
>         int ret;
>
>         pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
> @@ -137,9 +339,38 @@ static int exynos_pmu_probe(struct platform_device *pdev)
>                         GFP_KERNEL);
>         if (!pmu_context)
>                 return -ENOMEM;
> -       pmu_context->dev = dev;
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!res)
> +               return -ENODEV;
> +
>         pmu_context->pmu_data = of_device_get_match_data(dev);
>
> +       /* For SoCs that secure PMU register writes use custom regmap */
> +       if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_secure) {
> +               pmu_regmcfg = regmap_smccfg;
> +               pmu_regmcfg.max_register = resource_size(res) -
> +                                          pmu_regmcfg.reg_stride;
> +               /* Need physical address for SMC call */
> +               regmap = devm_regmap_init(dev, NULL,
> +                                         (void *)(uintptr_t)res->start,
> +                                         &pmu_regmcfg);
> +       } else {
> +               /* All other SoCs use a MMIO regmap */
> +               pmu_regmcfg = regmap_mmiocfg;
> +               pmu_regmcfg.max_register = resource_size(res) -
> +                                          pmu_regmcfg.reg_stride;
> +               regmap = devm_regmap_init_mmio(dev, pmu_base_addr,
> +                                              &pmu_regmcfg);
> +       }
> +
> +       if (IS_ERR(regmap))
> +               return dev_err_probe(&pdev->dev, PTR_ERR(regmap),
> +                                    "regmap init failed\n");
> +
> +       pmu_context->pmureg = regmap;
> +       pmu_context->dev = dev;
> +
>         if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init)
>                 pmu_context->pmu_data->pmu_init();
>
> diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
> index 1c652ffd79b4..0a49a2c9a08e 100644
> --- a/drivers/soc/samsung/exynos-pmu.h
> +++ b/drivers/soc/samsung/exynos-pmu.h
> @@ -21,6 +21,7 @@ struct exynos_pmu_conf {
>  struct exynos_pmu_data {
>         const struct exynos_pmu_conf *pmu_config;
>         const struct exynos_pmu_conf *pmu_config_extra;
> +       bool pmu_secure;
>
>         void (*pmu_init)(void);
>         void (*powerdown_conf)(enum sys_powerdown);
> diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
> index a4f5516cc956..2bd9d12d9a52 100644
> --- a/include/linux/soc/samsung/exynos-pmu.h
> +++ b/include/linux/soc/samsung/exynos-pmu.h
> @@ -10,6 +10,7 @@
>  #define __LINUX_SOC_EXYNOS_PMU_H
>
>  struct regmap;
> +struct device_node;
>
>  enum sys_powerdown {
>         SYS_AFTR,
> @@ -20,12 +21,20 @@ enum sys_powerdown {
>
>  extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
>  #ifdef CONFIG_EXYNOS_PMU
> -extern struct regmap *exynos_get_pmu_regmap(void);
> +struct regmap *exynos_get_pmu_regmap(void);
> +struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> +                                               const char *propname);
>  #else
>  static inline struct regmap *exynos_get_pmu_regmap(void)
>  {
>         return ERR_PTR(-ENODEV);
>  }
> +
> +static inline struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
> +                                                             const char *propname)
> +{
> +       return ERR_PTR(-ENODEV);
> +}
>  #endif
>
>  #endif /* __LINUX_SOC_EXYNOS_PMU_H */
> --
> 2.44.0.rc0.258.g7320e95886-goog
>


From itaru.kitayama at linux.dev  Mon Feb 19 16:29:14 2024
From: itaru.kitayama at linux.dev (Itaru Kitayama)
Date: Tue, 20 Feb 2024 09:29:14 +0900
Subject: [PATCH] arm64: add early fixmap initialization flag
In-Reply-To: <ZdMx-svsHgrfguxX@FVFF77S0Q05N>
References: <20240217140326.2367186-1-skseofh@gmail.com>
 <ZdMx-svsHgrfguxX@FVFF77S0Q05N>
Message-ID: <ZdPyWkOlUan5AI9r@vm3>

On Mon, Feb 19, 2024 at 10:48:26AM +0000, Mark Rutland wrote:
> On Sat, Feb 17, 2024 at 11:03:26PM +0900, skseofh at gmail.com wrote:
> > From: Daero Lee <skseofh at gmail.com>
> > 
> > early_fixmap_init may be called multiple times. Since there is no
> > change in the page table after early fixmap initialization, an
> > initialization flag was added.
> 
> Why is that better?
> 
> We call early_fixmap_init() in two places:
> 
> * early_fdt_map()
> * setup_arch()
> 
> ... and to get to setup_arch() we *must* have gone through early_fdt_map(),
> since __primary_switched() calls that before going to setup_arch().
> 
> So AFAICT we can remove the second call to early_fixmap_init() in setup_arch(),
> and rely on the earlier one in early_fdt_map().

Removing the second call makes the code base a bit harder to understand
as the functions related to DT and ACPI setup are not separated cleanly.
I prefer calling the early_fixmap_init() in setup_arch() as well.

Itaru.

> 
> Mark.
> 
> > 
> > Signed-off-by: Daero Lee <skseofh at gmail.com>
> > ---
> >  arch/arm64/mm/fixmap.c | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
> > index c0a3301203bd..fbdd5f30f3a1 100644
> > --- a/arch/arm64/mm/fixmap.c
> > +++ b/arch/arm64/mm/fixmap.c
> > @@ -32,6 +32,8 @@ static pte_t bm_pte[NR_BM_PTE_TABLES][PTRS_PER_PTE] __page_aligned_bss;
> >  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 int early_fixmap_initialized __initdata;
> > +
> >  static inline pte_t *fixmap_pte(unsigned long addr)
> >  {
> >  	return &bm_pte[BM_PTE_TABLE_IDX(addr)][pte_index(addr)];
> > @@ -100,10 +102,15 @@ void __init early_fixmap_init(void)
> >  	unsigned long addr = FIXADDR_TOT_START;
> >  	unsigned long end = FIXADDR_TOP;
> >  
> > +	if (early_fixmap_initialized)
> > +		return;
> > +
> >  	pgd_t *pgdp = pgd_offset_k(addr);
> >  	p4d_t *p4dp = p4d_offset(pgdp, addr);
> >  
> >  	early_fixmap_init_pud(p4dp, addr, end);
> > +
> > +	early_fixmap_initialized = 1;
> >  }
> >  
> >  /*
> > -- 
> > 2.25.1
> > 


From jgg at nvidia.com  Mon Feb 19 16:35:28 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Mon, 19 Feb 2024 20:35:28 -0400
Subject: [PATCH rc v2] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <CAKHBV26bwkvRAeyNuiUdmh0OWmvLfS7Ja8OHabT-H9nUY=SyNg@mail.gmail.com>
References: <0-v2-7988c2682634+261-smmu_cd_atomic_jgg@nvidia.com>
 <20240216120512.GA1841@willie-the-truck>
 <20240216123606.GA13330@nvidia.com>
 <CAKHBV27eBnCrnXeaoqONWksh89tfX1b0=yvLfTkxviU_wKG_mw@mail.gmail.com>
 <20240217132446.GJ13330@nvidia.com>
 <CAKHBV26bwkvRAeyNuiUdmh0OWmvLfS7Ja8OHabT-H9nUY=SyNg@mail.gmail.com>
Message-ID: <20240220003528.GK13330@nvidia.com>

On Mon, Feb 19, 2024 at 04:32:40PM +0800, Michael Shavit wrote:
> On Sat, Feb 17, 2024 at 9:24?PM Jason Gunthorpe <jgg at nvidia.com> wrote:
> >
> > On Sat, Feb 17, 2024 at 08:25:36PM +0800, Michael Shavit wrote:
> >
> > > Calling arm_smmu_write_ctx_desc requires the CD which we get from the
> > > mmu_notifiers list...which makes it a bit more complicated than
> > > that.
> >
> > @@ -404,9 +384,15 @@ static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
> >                 goto err_free_bond;
> >         }
> >
> > +       ret = arm_smmu_write_ctx_desc(master, pasid, bond->smmu_mn->cd);
> > +       if (ret)
> > +               goto err_put_notifier;
> > +
> >
> Oh hey that's not much more complicated :) . I'm guessing that'll be a
> call to arm_smmu_mmu_notifier_put() rather than a goto on the error
> path?

Yes, error unwind is the goto which does put and kfree(bond)

> Speaking of... the arm_smmu_update_ctx_desc_devices call in
> arm_smmu_mmu_notifier_put might be tricky as well if it's encountered
> on the error path before all devices (in theoretical non-pci case) had
> a chance to previously call arm_smmu_write_ctx_desc.

It is hard to understand but I think it is close enough to OK..

The put will pair with the get and if this is the first member of the
group then it will do a symmetric tear down. The 

	if (!refcount_dec_and_test(&smmu_mn->refs))
		return;

Takes care of that

Otherwise the puts accumulate the refcount back down to zero which
should be hit once __iommu_remove_group_pasid() gets all the group
members removed.

IOW the CDs are not cleaned up on any devices until all the group
members have the PASID removed. Clearly it is not correct design, but
it looks like it works good enough even in error paths.

Then when it does eventually reach arm_smmu_update_ctx_desc_devices()
it wipes all the CDs of all the RID domain's masters which is the same
as the group membership.

Which will end up happening before iommu_attach_device_pasid() returns
on its error path.

(obviously this is all made to work logically and properly in part 2)

Jasson


From cki-project at redhat.com  Mon Feb 19 16:41:08 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Tue, 20 Feb 2024 00:41:08 -0000
Subject: =?utf-8?b?4pyF?= PASS (MISSED 2 of 87): Test report for for-kernelci
 (6.8.0-rc5, arm-next, 83d49ede)
Message-ID: <86451.124021919410900480@us-mta-418.us.mimecast.lan>

Hi, we tested your kernel and here are the results:

    Overall result: PASSED
             Merge: OK
           Compile: OK
              Test: OK

Tested-by: CKI Project <cki-project at redhat.com>

Kernel information:
    Commit message: Merge branch 'for-next/core' into for-kernelci

You can find all the details about the test run at
    https://datawarehouse.cki-project.org/kcidb/checkouts/130197

One or more kernel tests failed:
    We also see the following known issues which are not related to your changes:
        Issue: [rawhide] avc:  denied  { read write } for  pid=12364 comm="plymouthd" name="kmsg" dev="devtmpfs" ino=10 scontext=system_u:system_r:plymouthd_t:s0 tcontext=system_u:object_r:kmsg_device_t:s0 tclass=chr_file permissive=1
            URL: https://bugzilla.redhat.com/show_bug.cgi?id=2256442
            Affected tests:
                 aarch64 - Boot test
                 aarch64 - stress: stress-ng - cpu-cache
                 aarch64 - Reboot test
        Issue: [upstream] blktests tests nbd/001 failed
            URL: https://github.com/osandov/blktests/issues/132
            Affected tests:
                 aarch64 - Storage - blktests - blk - upstream
        Issue: [upstream] blktests tests/zbd/010 failed
            URL: https://lore.kernel.org/linux-block/CAHj4cs-kfojYC9i0G73PRkYzcxCTex=-vugRFeP40g_URGvnfQ at mail.gmail.com/T/#u
            Affected tests:
                 aarch64 - Storage - blktests - blk - upstream
        Issue: [upstream] stress-ng: avc denial on secretmemory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1752
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: stress: stress-ng - memory: (panic) Comm: systemd-oomd Not tainted 6.1.0-rc3
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1461
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: Firmware test suite: mv: cannot stat 'dtcompilerparser.tab.c': No such file or directory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1544
            Affected tests:
                 aarch64 - Hardware - Firmware test suite


Tests that were not ran because of internal issues: 
     aarch64 - Memory function: memfd_create
     aarch64 - Memory function: memfd_create


If you find a failure unrelated to your changes, please ask the test maintainer to review it.
This will prevent the failures from being incorrectly reported in the future.

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
           `-'
______________________________________________________________________________



From ychuang570808 at gmail.com  Mon Feb 19 16:41:55 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Tue, 20 Feb 2024 00:41:55 +0000
Subject: [PATCH v5 0/4] Add support for nuvoton ma35d1 pin control
Message-ID: <20240220004159.1580108-1-ychuang570808@gmail.com>

From: Jacky Huang <ychuang3 at nuvoton.com>

This patch series adds the pin control and GPIO driver for the nuvoton ma35d1
ARMv8 SoC. It includes DT binding documentation, the ma35d1 pin control driver,
and device tree updates.

This pin control driver has been tested on the ma35d1 som board with Linux 6.8-rc5	.

v5:
  - Update the pinctrl driver header file pinctrl-ma35.h
    - Include platform_device.h to fix compile issues.

v4:
  - Update the pinctrl driver Kconfig
    - Add depends to CONFIG_PINCTRL_MA35D1 to prevent compilation errors.
  - Update the pinctrl driver
    - Utilize devm_kcalloc() instead of devm_kzalloc().
    - Employ ARRAY_SIZE() instead of sizeof()/sizeof().

v3:
  - Update DTS and YAML files
    - Corrected the unit address of nodes gpioa ~ gpion.
    - Removed the invalid "pin-default" node.
    - Removed the phandle entry from "nuvoton,pins".
  - Update pinctrl driver
    - Fixed the Kconfig by using "depend on" instead of "if".
    - Removed unused #include of header files.
    - Utilized immutable irq_chip instead of dynamic irq_chip.
    - Replaced ma35_dt_free_map() with pinconf_generic_dt_free_map().
    - Implemented other minor fixes as suggested by the reviewer.

v2:
  - Update nuvoton,ma35d1-pinctrl.yaml
    - Update the 'nuvoton,pins' to follow the style of rockchip pinctrl approch.
    - Use power-source to indicate the pin voltage selection which follow the
      realtek pinctrl approch.
    - Instead of integer, use drive-strength-microamp to specify the real driving
      strength capability of IO pins.
  - Update ma35d1 pinctrl driver
    - Add I/O drive strength lookup table for translating device tree setting
      into control register.
  - Remove ma35d1-pinfunc.h which is unused after update definition of 'nuvoton,pins'.


Jacky Huang (4):
  dt-bindings: reset: Add syscon to nuvoton ma35d1 system-management
    node
  dt-bindings: pinctrl: Document nuvoton ma35d1 pin control
  arm64: dts: nuvoton: Add pinctrl support for ma35d1
  pinctrl: nuvoton: Add ma35d1 pinctrl and GPIO driver

 .../pinctrl/nuvoton,ma35d1-pinctrl.yaml       |  163 ++
 .../bindings/reset/nuvoton,ma35d1-reset.yaml  |    3 +-
 .../boot/dts/nuvoton/ma35d1-iot-512m.dts      |   80 +-
 .../boot/dts/nuvoton/ma35d1-som-256m.dts      |   83 +-
 arch/arm64/boot/dts/nuvoton/ma35d1.dtsi       |  150 +-
 drivers/pinctrl/nuvoton/Kconfig               |   19 +
 drivers/pinctrl/nuvoton/Makefile              |    2 +
 drivers/pinctrl/nuvoton/pinctrl-ma35.c        | 1211 +++++++++++
 drivers/pinctrl/nuvoton/pinctrl-ma35.h        |   51 +
 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c      | 1797 +++++++++++++++++
 10 files changed, 3549 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/nuvoton,ma35d1-pinctrl.yaml
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.c
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.h
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c

-- 
2.34.1



From ychuang570808 at gmail.com  Mon Feb 19 16:41:56 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Tue, 20 Feb 2024 00:41:56 +0000
Subject: [PATCH v5 1/4] dt-bindings: reset: Add syscon to nuvoton ma35d1 system-management node
In-Reply-To: <20240220004159.1580108-1-ychuang570808@gmail.com>
References: <20240220004159.1580108-1-ychuang570808@gmail.com>
Message-ID: <20240220004159.1580108-2-ychuang570808@gmail.com>

From: Jacky Huang <ychuang3 at nuvoton.com>

Add a compatible 'syscon' to the system management node since the system
control registers are mapped by this driver. The other driver must access
the system control registers through 'regmap' using a phandle that
references this node.

Signed-off-by: Jacky Huang <ychuang3 at nuvoton.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Philipp Zabel <p.zabel at pengutronix.de>
---
 .../devicetree/bindings/reset/nuvoton,ma35d1-reset.yaml        | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/reset/nuvoton,ma35d1-reset.yaml b/Documentation/devicetree/bindings/reset/nuvoton,ma35d1-reset.yaml
index 34c5c1c08ec1..3ce7dcecd87a 100644
--- a/Documentation/devicetree/bindings/reset/nuvoton,ma35d1-reset.yaml
+++ b/Documentation/devicetree/bindings/reset/nuvoton,ma35d1-reset.yaml
@@ -18,6 +18,7 @@ properties:
   compatible:
     items:
       - const: nuvoton,ma35d1-reset
+      - const: syscon
 
   reg:
     maxItems: 1
@@ -37,7 +38,7 @@ examples:
   - |
 
     system-management at 40460000 {
-        compatible = "nuvoton,ma35d1-reset";
+        compatible = "nuvoton,ma35d1-reset", "syscon";
         reg = <0x40460000 0x200>;
         #reset-cells = <1>;
     };
-- 
2.34.1



From ychuang570808 at gmail.com  Mon Feb 19 16:41:57 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Tue, 20 Feb 2024 00:41:57 +0000
Subject: [PATCH v5 2/4] dt-bindings: pinctrl: Document nuvoton ma35d1 pin control
In-Reply-To: <20240220004159.1580108-1-ychuang570808@gmail.com>
References: <20240220004159.1580108-1-ychuang570808@gmail.com>
Message-ID: <20240220004159.1580108-3-ychuang570808@gmail.com>

From: Jacky Huang <ychuang3 at nuvoton.com>

Add documentation to describe nuvoton ma35d1 pin control and GPIO.

Signed-off-by: Jacky Huang <ychuang3 at nuvoton.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../pinctrl/nuvoton,ma35d1-pinctrl.yaml       | 163 ++++++++++++++++++
 1 file changed, 163 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/nuvoton,ma35d1-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/nuvoton,ma35d1-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/nuvoton,ma35d1-pinctrl.yaml
new file mode 100644
index 000000000000..8b9ec263213f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/nuvoton,ma35d1-pinctrl.yaml
@@ -0,0 +1,163 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/nuvoton,ma35d1-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton MA35D1 pin control and GPIO
+
+maintainers:
+  - Shan-Chun Hung <schung at nuvoton.com>
+  - Jacky Huang <ychuang3 at nuvoton.com>
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+properties:
+  compatible:
+    enum:
+      - nuvoton,ma35d1-pinctrl
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 1
+
+  nuvoton,sys:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      phandle of the system-management node.
+
+  ranges: true
+
+patternProperties:
+  "^gpio@[0-9a-f]+$":
+    type: object
+    additionalProperties: false
+    properties:
+      gpio-controller: true
+
+      '#gpio-cells':
+        const: 2
+
+      reg:
+        maxItems: 1
+
+      clocks:
+        maxItems: 1
+
+      interrupt-controller: true
+
+      '#interrupt-cells':
+        const: 2
+
+      interrupts:
+        description:
+          The interrupt outputs to sysirq.
+        maxItems: 1
+
+    required:
+      - gpio-controller
+      - '#gpio-cells'
+      - reg
+      - clocks
+      - interrupt-controller
+      - '#interrupt-cells'
+      - interrupts
+
+  "^pin-[a-z0-9]+$":
+    type: object
+    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.
+
+    $ref: pincfg-node.yaml#
+
+    properties:
+      power-source:
+        description: |
+          Valid arguments are described as below:
+          0: power supply of 1.8V
+          1: power supply of 3.3V
+        enum: [0, 1]
+
+      drive-strength-microamp:
+        oneOf:
+          - enum: [ 2900, 4400, 5800, 7300, 8600, 10100, 11500, 13000 ]
+            description: 1.8V I/O driving strength
+          - enum: [ 17100, 25600, 34100, 42800, 48000, 56000, 77000, 82000 ]
+            description: 3.3V I/O driving strength
+
+    unevaluatedProperties: false
+
+  "-grp$":
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+    properties:
+      nuvoton,pins:
+        description:
+          Each entry consists of 4 parameters and represents the mux and config
+          setting for one pin.
+        $ref: /schemas/types.yaml#/definitions/uint32-matrix
+        minItems: 1
+        items:
+          items:
+            - minimum: 0
+              maximum: 13
+              description:
+                Pin bank.
+            - minimum: 0
+              maximum: 15
+              description:
+                Pin bank index.
+            - minimum: 0
+              maximum: 15
+              description:
+                Mux 0 means GPIO and mux 1 to 15 means the specific device function.
+
+required:
+  - compatible
+  - nuvoton,sys
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+
+    pinctrl at 40040000 {
+        compatible = "nuvoton,ma35d1-pinctrl";
+        #address-cells = <1>;
+        #size-cells = <1>;
+        nuvoton,sys = <&sys>;
+        ranges = <0 0x40040000 0xc00>;
+
+        gpio at 0 {
+            reg = <0x0 0x40>;
+            interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&clk GPA_GATE>;
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+        };
+
+        uart-grp {
+            uart11-pins {
+                nuvoton,pins = <11 0 2>,
+                               <11 1 2>,
+                               <11 2 2>,
+                               <11 3 2>;
+                bias-disable;
+                power-source = <1>;
+            };
+        };
+    };
-- 
2.34.1



From ychuang570808 at gmail.com  Mon Feb 19 16:41:58 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Tue, 20 Feb 2024 00:41:58 +0000
Subject: [PATCH v5 3/4] arm64: dts: nuvoton: Add pinctrl support for ma35d1
In-Reply-To: <20240220004159.1580108-1-ychuang570808@gmail.com>
References: <20240220004159.1580108-1-ychuang570808@gmail.com>
Message-ID: <20240220004159.1580108-4-ychuang570808@gmail.com>

From: Jacky Huang <ychuang3 at nuvoton.com>

Add 'pinctrl' node and 'gpioa' ~ 'gpion' nodes to the dtsi of ma35d1
SoC and describe default pin configurations.

Enable all UART nodes presented on som and iot boards, and add pinctrl
function settings to these nodes.

Signed-off-by: Jacky Huang <ychuang3 at nuvoton.com>
---
 .../boot/dts/nuvoton/ma35d1-iot-512m.dts      |  80 +++++++++-
 .../boot/dts/nuvoton/ma35d1-som-256m.dts      |  83 +++++++++-
 arch/arm64/boot/dts/nuvoton/ma35d1.dtsi       | 150 +++++++++++++++++-
 3 files changed, 304 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts b/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
index b89e2be6abae..9482bec1aa57 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1-iot-512m.dts
@@ -14,6 +14,10 @@ / {
 
 	aliases {
 		serial0 = &uart0;
+		serial10 = &uart10;
+		serial12 = &uart12;
+		serial13 = &uart13;
+		serial14 = &uart14;
 	};
 
 	chosen {
@@ -33,10 +37,6 @@ clk_hxt: clock-hxt {
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &clk {
 	assigned-clocks = <&clk CAPLL>,
 			  <&clk DDRPLL>,
@@ -54,3 +54,75 @@ &clk {
 			   "integer",
 			   "integer";
 };
+
+&pinctrl {
+	uart-grp {
+		pinctrl_uart0: uart0-pins {
+			nuvoton,pins = <4 14 1>,
+				       <4 15 1>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart10: uart10-pins {
+			nuvoton,pins = <7 4 2>,
+				       <7 5 2>,
+				       <7 6 2>,
+				       <7 7 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart12: uart12-pins {
+			nuvoton,pins = <2 13 2>,
+				       <2 14 2>,
+				       <2 15 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart13: uart13-pins {
+			nuvoton,pins = <7 12 3>,
+				       <7 13 3>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart14: uart14-pins {
+			nuvoton,pins = <7 14 2>,
+				       <7 15 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart0>;
+	status = "okay";
+};
+
+&uart10 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart10>;
+	status = "okay";
+};
+
+&uart12 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart12>;
+	status = "okay";
+};
+
+&uart13 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart13>;
+	status = "okay";
+};
+
+&uart14 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart14>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts b/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
index a1ebddecb7f8..f6f20a17e501 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1-som-256m.dts
@@ -14,6 +14,10 @@ / {
 
 	aliases {
 		serial0 = &uart0;
+		serial11 = &uart11;
+		serial12 = &uart12;
+		serial14 = &uart14;
+		serial16 = &uart16;
 	};
 
 	chosen {
@@ -33,10 +37,6 @@ clk_hxt: clock-hxt {
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &clk {
 	assigned-clocks = <&clk CAPLL>,
 			  <&clk DDRPLL>,
@@ -54,3 +54,78 @@ &clk {
 			   "integer",
 			   "integer";
 };
+
+&pinctrl {
+	uart-grp {
+		pinctrl_uart0: uart0-pins {
+			nuvoton,pins = <4 14 1>,
+				       <4 15 1>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart11: uart11-pins {
+			nuvoton,pins = <11 0 2>,
+				       <11 1 2>,
+				       <11 2 2>,
+				       <11 3 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart12: uart12-pins {
+			nuvoton,pins = <8 1 2>,
+				       <8 2 2>,
+				       <8 3 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart14: uart14-pins {
+			nuvoton,pins = <8 5 2>,
+				       <8 6 2>,
+				       <8 7 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+
+		pinctrl_uart16: uart16-pins {
+			nuvoton,pins = <10 0 2>,
+				       <10 1 2>,
+				       <10 2 2>,
+				       <10 3 2>;
+			bias-disable;
+			power-source = <1>;
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart0>;
+	status = "okay";
+};
+
+&uart11 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart11>;
+	status = "okay";
+};
+
+&uart12 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart12>;
+	status = "okay";
+};
+
+&uart14 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart14>;
+	status = "okay";
+};
+
+&uart16 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart16>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi b/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
index 781cdae566a0..5f366f4c7fde 100644
--- a/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
+++ b/arch/arm64/boot/dts/nuvoton/ma35d1.dtsi
@@ -83,7 +83,7 @@ soc {
 		ranges;
 
 		sys: system-management at 40460000 {
-			compatible = "nuvoton,ma35d1-reset";
+			compatible = "nuvoton,ma35d1-reset", "syscon";
 			reg = <0x0 0x40460000 0x0 0x200>;
 			#reset-cells = <1>;
 		};
@@ -95,6 +95,154 @@ clk: clock-controller at 40460200 {
 			clocks = <&clk_hxt>;
 		};
 
+		pinctrl: pinctrl at 40040000 {
+			compatible = "nuvoton,ma35d1-pinctrl";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			nuvoton,sys = <&sys>;
+			ranges = <0x0 0x0 0x40040000 0xc00>;
+
+			gpioa: gpio at 0 {
+				reg = <0x0 0x40>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPA_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiob: gpio at 40 {
+				reg = <0x40 0x40>;
+				interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPB_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpioc: gpio at 80 {
+				reg = <0x80 0x40>;
+				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPC_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiod: gpio at c0 {
+				reg = <0xc0 0x40>;
+				interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPD_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpioe: gpio at 100 {
+				reg = <0x100 0x40>;
+				interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPE_GATE>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiof: gpio at 140 {
+				reg = <0x140 0x40>;
+				interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPF_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiog: gpio at 180 {
+				reg = <0x180 0x40>;
+				interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPG_GATE>;
+				#gpio-cells = <2>;
+				gpio-controller;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpioh: gpio at 1c0 {
+				reg = <0x1c0 0x40>;
+				interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPH_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpioi: gpio at 200 {
+				reg = <0x200 0x40>;
+				interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPI_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpioj: gpio at 240 {
+				reg = <0x240 0x40>;
+				interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPJ_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiok: gpio at 280 {
+				reg = <0x280 0x40>;
+				interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPK_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiol: gpio at 2c0 {
+				reg = <0x2c0 0x40>;
+				interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPL_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpiom: gpio at 300 {
+				reg = <0x300 0x40>;
+				interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPM_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpion: gpio at 340 {
+				reg = <0x340 0x40>;
+				interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk GPN_GATE>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+		};
+
 		uart0: serial at 40700000 {
 			compatible = "nuvoton,ma35d1-uart";
 			reg = <0x0 0x40700000 0x0 0x100>;
-- 
2.34.1



From ychuang570808 at gmail.com  Mon Feb 19 16:41:59 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Tue, 20 Feb 2024 00:41:59 +0000
Subject: [PATCH v5 4/4] pinctrl: nuvoton: Add ma35d1 pinctrl and GPIO driver
In-Reply-To: <20240220004159.1580108-1-ychuang570808@gmail.com>
References: <20240220004159.1580108-1-ychuang570808@gmail.com>
Message-ID: <20240220004159.1580108-5-ychuang570808@gmail.com>

From: Jacky Huang <ychuang3 at nuvoton.com>

Add common pinctrl and GPIO driver for Nuvoton MA35 series SoC, and
add support for ma35d1 pinctrl.

Signed-off-by: Jacky Huang <ychuang3 at nuvoton.com>
---
 drivers/pinctrl/nuvoton/Kconfig          |   19 +
 drivers/pinctrl/nuvoton/Makefile         |    2 +
 drivers/pinctrl/nuvoton/pinctrl-ma35.c   | 1211 +++++++++++++++
 drivers/pinctrl/nuvoton/pinctrl-ma35.h   |   51 +
 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c | 1797 ++++++++++++++++++++++
 5 files changed, 3080 insertions(+)
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.c
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.h
 create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c

diff --git a/drivers/pinctrl/nuvoton/Kconfig b/drivers/pinctrl/nuvoton/Kconfig
index 2abbfcec1fae..7eadaaf48d6e 100644
--- a/drivers/pinctrl/nuvoton/Kconfig
+++ b/drivers/pinctrl/nuvoton/Kconfig
@@ -45,3 +45,22 @@ config PINCTRL_NPCM8XX
 	  Say Y or M here to enable pin controller and GPIO support for
 	  the Nuvoton NPCM8XX SoC. This is strongly recommended when
 	  building a kernel that will run on this chip.
+
+config PINCTRL_MA35
+	bool
+	depends on (ARCH_MA35 || COMPILE_TEST) && OF
+	select GENERIC_PINCTRL_GROUPS
+	select GENERIC_PINMUX_FUNCTIONS
+	select GENERIC_PINCONF
+	select GPIOLIB
+	select GPIO_GENERIC
+	select GPIOLIB_IRQCHIP
+	select MFD_SYSCON
+
+config PINCTRL_MA35D1
+	bool "Pinctrl and GPIO driver for Nuvoton MA35D1"
+	depends on (ARCH_MA35 || COMPILE_TEST) && OF
+	select PINCTRL_MA35
+	help
+	  Say Y here to enable pin controller and GPIO support
+	  for Nuvoton MA35D1 SoC.
diff --git a/drivers/pinctrl/nuvoton/Makefile b/drivers/pinctrl/nuvoton/Makefile
index 08031eab0af6..346c5082bc60 100644
--- a/drivers/pinctrl/nuvoton/Makefile
+++ b/drivers/pinctrl/nuvoton/Makefile
@@ -4,3 +4,5 @@
 obj-$(CONFIG_PINCTRL_WPCM450)	+= pinctrl-wpcm450.o
 obj-$(CONFIG_PINCTRL_NPCM7XX)	+= pinctrl-npcm7xx.o
 obj-$(CONFIG_PINCTRL_NPCM8XX)	+= pinctrl-npcm8xx.o
+obj-$(CONFIG_PINCTRL_MA35)	+= pinctrl-ma35.o
+obj-$(CONFIG_PINCTRL_MA35D1)	+= pinctrl-ma35d1.o
diff --git a/drivers/pinctrl/nuvoton/pinctrl-ma35.c b/drivers/pinctrl/nuvoton/pinctrl-ma35.c
new file mode 100644
index 000000000000..8efbe559be1e
--- /dev/null
+++ b/drivers/pinctrl/nuvoton/pinctrl-ma35.c
@@ -0,0 +1,1211 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Nuvoton Technology Corp.
+ *
+ * Author: Shan-Chun Hung <schung at nuvoton.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio/driver.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "../core.h"
+#include "../pinconf.h"
+#include "pinctrl-ma35.h"
+
+#define MA35_MFP_REG_BASE		0x80
+#define MA35_MFP_REG_SZ_PER_BANK	8
+#define MA35_MFP_BITS_PER_PORT		4
+
+#define MA35_GPIO_BANK_MAX		14
+#define MA35_GPIO_PORT_MAX		16
+
+/* GPIO control registers */
+#define MA35_GP_REG_MODE		0x00
+#define MA35_GP_REG_DINOFF		0x04
+#define MA35_GP_REG_DOUT		0x08
+#define MA35_GP_REG_DATMSK		0x0c
+#define MA35_GP_REG_PIN			0x10
+#define MA35_GP_REG_DBEN		0x14
+#define MA35_GP_REG_INTTYPE		0x18
+#define MA35_GP_REG_INTEN		0x1c
+#define MA35_GP_REG_INTSRC		0x20
+#define MA35_GP_REG_SMTEN		0x24
+#define MA35_GP_REG_SLEWCTL		0x28
+#define MA35_GP_REG_SPW			0x2c
+#define MA35_GP_REG_PUSEL		0x30
+#define MA35_GP_REG_DSL			0x38
+#define MA35_GP_REG_DSH			0x3c
+
+/* GPIO mode control */
+#define MA35_GP_MODE_INPUT		0x0
+#define MA35_GP_MODE_OUTPUT		0x1
+#define MA35_GP_MODE_OPEN_DRAIN		0x2
+#define MA35_GP_MODE_QUASI		0x3
+
+/* GPIO pull-up and pull-down selection control */
+#define MA35_GP_PUSEL_DISABLE		0x0
+#define MA35_GP_PUSEL_PULL_UP		0x1
+#define MA35_GP_PUSEL_PULL_DOWN		0x2
+
+/* Each pin data input/output is mapped by address mapping */
+#define MA35_PIN_MAP_BASE		0x800
+#define MA35_GP_DSH_BASE_PORT		8
+
+#define MVOLT_1800			0
+#define MVOLT_3300			1
+
+static const char * const gpio_group_name[] = {
+	"gpioa", "gpiob", "gpioc", "gpiod", "gpioe", "gpiof", "gpiog",
+	"gpioh", "gpioi", "gpioj", "gpiok", "gpiol", "gpiom", "gpion",
+};
+
+static const u32 ds_1800mv_tbl[] = {
+	2900, 4400, 5800, 7300, 8600, 10100, 11500, 13000,
+};
+
+static const u32 ds_3300mv_tbl[] = {
+	17100, 25600, 34100, 42800, 48000, 56000, 77000, 82000,
+};
+
+struct ma35_pin_func {
+	const char		*name;
+	const char		**groups;
+	u32			ngroups;
+};
+
+struct ma35_pin_setting {
+	u32			offset;
+	u32			shift;
+	u32			muxval;
+	unsigned long		*configs;
+	unsigned int		nconfigs;
+};
+
+struct ma35_pin_group {
+	const char		*name;
+	unsigned int		npins;
+	unsigned int		*pins;
+	struct ma35_pin_setting	*settings;
+};
+
+struct ma35_pin_bank {
+	void __iomem		*reg_base;
+	struct clk		*clk;
+	int			irq;
+	u8			nr_pins;
+	const char		*name;
+	u8			bank_num;
+	bool			valid;
+	struct device_node	*np;
+	struct gpio_chip	chip;
+	u32			irqtype;
+	u32			irqinten;
+	struct regmap		*regmap;
+	struct device		*dev;
+	spinlock_t		lock;
+};
+
+struct ma35_pin_ctrl {
+	struct ma35_pin_bank	*pin_banks;
+	u32			nr_banks;
+	u32			nr_pins;
+};
+
+struct ma35_pinctrl {
+	struct device		*dev;
+	struct ma35_pin_ctrl	*ctrl;
+	struct pinctrl_dev	*pctl;
+	const struct ma35_pinctrl_soc_info *info;
+	struct regmap		*regmap;
+	struct ma35_pin_group	*groups;
+	unsigned int		ngroups;
+	struct ma35_pin_func	*functions;
+	unsigned int		nfunctions;
+};
+
+static int ma35_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return npctl->ngroups;
+}
+
+static const char *ma35_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return npctl->groups[selector].name;
+}
+
+static int ma35_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
+			       const unsigned int **pins, unsigned int *npins)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	if (selector >= npctl->ngroups)
+		return -EINVAL;
+
+	*pins = npctl->groups[selector].pins;
+	*npins = npctl->groups[selector].npins;
+
+	return 0;
+}
+
+static struct ma35_pin_group *ma35_pinctrl_find_group_by_name(
+			      const struct ma35_pinctrl *npctl, const char *name)
+{
+	int i;
+
+	for (i = 0; i < npctl->ngroups; i++) {
+		if (!strcmp(npctl->groups[i].name, name))
+			return &npctl->groups[i];
+	}
+	return NULL;
+}
+
+static int ma35_pinctrl_dt_node_to_map_func(struct pinctrl_dev *pctldev,
+					    struct device_node *np,
+					    struct pinctrl_map **map,
+					    unsigned int *num_maps)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+	struct ma35_pin_group *grp;
+	struct pinctrl_map *new_map;
+	struct device_node *parent;
+	int map_num = 1;
+	int i;
+
+	/*
+	 * first find the group of this node and check if we need create
+	 * config maps for pins
+	 */
+	grp = ma35_pinctrl_find_group_by_name(npctl, np->name);
+	if (!grp) {
+		dev_err(npctl->dev, "unable to find group for node %s\n", np->name);
+		return -EINVAL;
+	}
+
+	map_num += grp->npins;
+	new_map = devm_kcalloc(pctldev->dev, map_num, sizeof(*new_map), GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	*map = new_map;
+	*num_maps = map_num;
+	/* create mux map */
+	parent = of_get_parent(np);
+	if (!parent) {
+		devm_kfree(pctldev->dev, new_map);
+		return -EINVAL;
+	}
+
+	new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+	new_map[0].data.mux.function = parent->name;
+	new_map[0].data.mux.group = np->name;
+	of_node_put(parent);
+
+	new_map++;
+	for (i = 0; i < grp->npins; i++) {
+		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+		new_map[i].data.configs.group_or_pin = pin_get_name(pctldev, grp->pins[i]);
+		new_map[i].data.configs.configs = grp->settings[i].configs;
+		new_map[i].data.configs.num_configs = grp->settings[i].nconfigs;
+	}
+	dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n",
+		(*map)->data.mux.function, (*map)->data.mux.group, map_num);
+
+	return 0;
+}
+
+static const struct pinctrl_ops ma35_pctrl_ops = {
+	.get_groups_count = ma35_get_groups_count,
+	.get_group_name = ma35_get_group_name,
+	.get_group_pins = ma35_get_group_pins,
+	.dt_node_to_map = ma35_pinctrl_dt_node_to_map_func,
+	.dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int ma35_pinmux_get_func_count(struct pinctrl_dev *pctldev)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return npctl->nfunctions;
+}
+
+static const char *ma35_pinmux_get_func_name(struct pinctrl_dev *pctldev,
+					     unsigned int selector)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return npctl->functions[selector].name;
+}
+
+static int ma35_pinmux_get_func_groups(struct pinctrl_dev *pctldev,
+				       unsigned int function,
+				       const char *const **groups,
+				       unsigned int *const num_groups)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = npctl->functions[function].groups;
+	*num_groups = npctl->functions[function].ngroups;
+
+	return 0;
+}
+
+static int ma35_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
+			       unsigned int group)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+	struct ma35_pin_group *grp = &npctl->groups[group];
+	struct ma35_pin_setting *setting = grp->settings;
+	u32 i, regval;
+
+	dev_dbg(npctl->dev, "enable function %s group %s\n",
+		npctl->functions[selector].name, npctl->groups[group].name);
+
+	for (i = 0; i < grp->npins; i++) {
+		regmap_read(npctl->regmap, setting->offset, &regval);
+		regval &= ~GENMASK(setting->shift + 3, setting->shift);
+		regval |= setting->muxval << setting->shift;
+		regmap_write(npctl->regmap, setting->offset, regval);
+		setting++;
+	}
+	return 0;
+}
+
+static const struct pinmux_ops ma35_pmx_ops = {
+	.get_functions_count = ma35_pinmux_get_func_count,
+	.get_function_name = ma35_pinmux_get_func_name,
+	.get_function_groups = ma35_pinmux_get_func_groups,
+	.set_mux = ma35_pinmux_set_mux,
+	.strict = true,
+};
+
+static int ma35_gpio_core_direction_in(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
+	void __iomem *reg_mode = bank->reg_base + MA35_GP_REG_MODE;
+	unsigned long flags;
+	unsigned int regval;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	regval = readl(reg_mode);
+	regval &= ~GENMASK(gpio * 2 + 1, gpio * 2);
+	regval |= MA35_GP_MODE_INPUT << gpio * 2;
+	writel(regval, reg_mode);
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+static int ma35_gpio_core_get(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
+
+	return readl(bank->reg_base + MA35_PIN_MAP_BASE + gpio * 4);
+}
+
+static void ma35_gpio_core_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
+
+	writel(val, bank->reg_base + MA35_PIN_MAP_BASE + gpio * 4);
+}
+
+static int ma35_gpio_core_direction_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
+	void __iomem *reg_dout = bank->reg_base + MA35_GP_REG_DOUT;
+	void __iomem *reg_mode = bank->reg_base + MA35_GP_REG_MODE;
+	unsigned long flags;
+	unsigned int regval;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	regval = readl(reg_dout);
+	if (val)
+		writel(regval | BIT(gpio), reg_dout);
+	else
+		writel(regval & ~BIT(gpio), reg_dout);
+
+	regval = readl(reg_mode);
+	regval &= ~GENMASK(gpio * 2 + 1, gpio * 2);
+	regval |= MA35_GP_MODE_OUTPUT << gpio * 2;
+	writel(regval, reg_mode);
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+static int ma35_gpio_core_to_request(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
+	u32 reg_offs, bit_offs, regval;
+
+	if (gpio < 8) {
+		/* The MFP low register controls port 0 ~ 7 */
+		reg_offs = bank->bank_num * MA35_MFP_REG_SZ_PER_BANK;
+		bit_offs = gpio * MA35_MFP_BITS_PER_PORT;
+	} else {
+		/* The MFP high register controls port 8 ~ 15 */
+		reg_offs = bank->bank_num * MA35_MFP_REG_SZ_PER_BANK + 4;
+		bit_offs = (gpio - 8) * MA35_MFP_BITS_PER_PORT;
+	}
+
+	regmap_read(bank->regmap, MA35_MFP_REG_BASE + reg_offs, &regval);
+	regval &= ~GENMASK(bit_offs + MA35_MFP_BITS_PER_PORT - 1, bit_offs);
+	regmap_write(bank->regmap, MA35_MFP_REG_BASE + reg_offs, regval);
+
+	return 0;
+}
+
+static void ma35_irq_gpio_mask(struct irq_data *d)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+	void __iomem *reg_ien = bank->reg_base + MA35_GP_REG_INTEN;
+	unsigned int num = (d->hwirq);
+	u32 regval;
+
+	regval = readl(reg_ien);
+
+	/*
+	 * The MA35_GP_REG_INTEN bits 0 ~ 15 control low-level or falling edge trigger,
+	 * while bits 16 ~ 31 control high-level or rising edge trigger.
+	 * We disable both type of interrupt.
+	 */
+	regval &= ~(BIT(num + 16) | BIT(num));
+
+	writel(regval, reg_ien);
+}
+
+static void ma35_irq_gpio_unmask(struct irq_data *d)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+	void __iomem *reg_itype = bank->reg_base + MA35_GP_REG_INTTYPE;
+	void __iomem *reg_ien = bank->reg_base + MA35_GP_REG_INTEN;
+	unsigned int num = (d->hwirq);
+	u32 bval, regval;
+
+	bval = bank->irqtype & BIT(num);
+
+	regval = readl(reg_itype);
+	regval &= ~BIT(num);
+	writel(regval | bval, reg_itype);
+
+	bval = bank->irqinten & (BIT(num + 16) | BIT(num));
+
+	regval = readl(reg_ien);
+	regval &= ~(BIT(num + 16) | BIT(num));
+	writel(regval | bval, reg_ien);
+}
+
+static int ma35_irq_irqtype(struct irq_data *d, unsigned int type)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+	void __iomem *reg_itype = bank->reg_base + MA35_GP_REG_INTTYPE;
+	void __iomem *reg_ien = bank->reg_base + MA35_GP_REG_INTEN;
+	unsigned int num = (d->hwirq);
+
+	if (type == IRQ_TYPE_PROBE) {
+		writel(readl(reg_itype) & ~BIT(num), reg_itype);
+		writel(readl(reg_ien) | BIT(num) | BIT(num + 16), reg_ien);
+		bank->irqtype &= ~BIT(num);
+		bank->irqinten |= BIT(num) | BIT(num + 16);
+		return 0;
+	}
+
+	if (type & IRQ_TYPE_LEVEL_MASK) {
+		writel(readl(reg_itype) | BIT(num), reg_itype);
+		writel(readl(reg_ien) & ~(BIT(num) | BIT(num + 16)), reg_ien);
+		bank->irqtype |= BIT(num);
+		bank->irqinten &= ~(BIT(num) | BIT(num + 16));
+		if (type == IRQ_TYPE_LEVEL_HIGH) {
+			writel(readl(reg_ien) | BIT(num + 16), reg_ien);
+			bank->irqinten |= BIT(num + 16);
+			return 0;
+		}
+
+		if (type == IRQ_TYPE_LEVEL_LOW) {
+			writel(readl(reg_ien) | BIT(num), reg_ien);
+			bank->irqinten |= BIT(num);
+			return 0;
+		}
+
+	} else {
+		writel(readl(reg_itype) & ~BIT(num), reg_itype);
+		bank->irqtype &= ~BIT(num);
+
+		if (type & IRQ_TYPE_EDGE_RISING) {
+			writel(readl(reg_ien) | BIT(num + 16), reg_ien);
+			bank->irqinten |= BIT(num + 16);
+
+		} else {
+			writel(readl(reg_ien) & ~BIT(num + 16), reg_ien);
+			bank->irqinten &= ~BIT(num + 16);
+		}
+
+		if (type & IRQ_TYPE_EDGE_FALLING) {
+			writel(readl(reg_ien) | BIT(num), reg_ien);
+			bank->irqinten |= BIT(num);
+
+		} else {
+			writel(readl(reg_ien) & ~BIT(num), reg_ien);
+			bank->irqinten &= ~BIT(num);
+		}
+	}
+	return 0;
+}
+
+static struct irq_chip ma35_gpio_irqchip = {
+	.name = "MA35-GPIO-IRQ",
+	.irq_disable = ma35_irq_gpio_mask,
+	.irq_enable = ma35_irq_gpio_unmask,
+	.irq_mask = ma35_irq_gpio_mask,
+	.irq_unmask = ma35_irq_gpio_unmask,
+	.irq_set_type = ma35_irq_irqtype,
+	.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE,
+};
+
+static void ma35_irq_demux_intgroup(struct irq_desc *desc)
+{
+	struct ma35_pin_bank *bank = gpiochip_get_data(irq_desc_get_handler_data(desc));
+	struct irq_domain *irqdomain = bank->chip.irq.domain;
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	unsigned int j, isr;
+
+	chained_irq_enter(irqchip, desc);
+
+	isr = readl(bank->reg_base + MA35_GP_REG_INTSRC);
+
+	if (isr != 0) {
+		writel(isr, bank->reg_base + MA35_GP_REG_INTSRC);
+
+		for (j = 0; j < 16; j++) {
+			if (isr & 0x1)
+				generic_handle_irq(irq_find_mapping(irqdomain, j));
+			isr = isr >> 1;
+		}
+	}
+
+	chained_irq_exit(irqchip, desc);
+}
+
+static int ma35_gpiolib_register(struct platform_device *pdev, struct ma35_pinctrl *npctl)
+{
+	struct ma35_pin_ctrl *ctrl = npctl->ctrl;
+	struct ma35_pin_bank *bank = ctrl->pin_banks;
+	int ret;
+	int i;
+
+	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		if (!bank->valid) {
+			dev_warn(&pdev->dev, "bank %s is not valid\n",
+				 bank->np->name);
+			continue;
+		}
+		bank->irqtype = 0;
+		bank->irqinten = 0;
+		bank->chip.label = bank->name;
+		bank->chip.of_gpio_n_cells = 2;
+		bank->chip.parent = &pdev->dev;
+		bank->chip.request = ma35_gpio_core_to_request;
+		bank->chip.direction_input = ma35_gpio_core_direction_in;
+		bank->chip.direction_output = ma35_gpio_core_direction_out;
+		bank->chip.get = ma35_gpio_core_get;
+		bank->chip.set = ma35_gpio_core_set;
+		bank->chip.base = -1;
+		bank->chip.ngpio = bank->nr_pins;
+		bank->chip.can_sleep = false;
+		spin_lock_init(&bank->lock);
+
+		if (bank->irq > 0) {
+			struct gpio_irq_chip *girq;
+
+			girq = &bank->chip.irq;
+			gpio_irq_chip_set_chip(girq, &ma35_gpio_irqchip);
+			girq->parent_handler = ma35_irq_demux_intgroup;
+			girq->num_parents = 1;
+
+			girq->parents = devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents),
+						     GFP_KERNEL);
+			if (!girq->parents)
+				return -ENOMEM;
+
+			girq->parents[0] = bank->irq;
+			girq->default_type = IRQ_TYPE_NONE;
+			girq->handler = handle_level_irq;
+		}
+
+		ret = gpiochip_add_data(&bank->chip, bank);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
+				bank->chip.label, ret);
+			goto fail;
+		}
+	}
+	return 0;
+
+fail:
+	for (--i, --bank; i >= 0; --i, --bank) {
+		if (!bank->valid)
+			continue;
+		gpiochip_remove(&bank->chip);
+	}
+	return ret;
+}
+
+static int ma35_get_bank_data(struct ma35_pin_bank *bank, struct ma35_pinctrl *npctl)
+{
+	struct resource res;
+
+	if (of_address_to_resource(bank->np, 0, &res)) {
+		dev_err(npctl->dev, "cannot find IO resource for bank\n");
+		return -ENOENT;
+	}
+
+	bank->reg_base = devm_ioremap_resource(npctl->dev, &res);
+	if (IS_ERR(bank->reg_base)) {
+		dev_err(npctl->dev, "cannot ioremap resource for bank\n");
+		return PTR_ERR(bank->reg_base);
+	}
+
+	bank->irq = irq_of_parse_and_map(bank->np, 0);
+	bank->nr_pins = MA35_GPIO_PORT_MAX;
+
+	bank->clk = of_clk_get(bank->np, 0);
+	if (IS_ERR(bank->clk))
+		return PTR_ERR(bank->clk);
+
+	return clk_prepare_enable(bank->clk);
+}
+
+static int ma35_pinctrl_get_soc_data(struct ma35_pinctrl *pctl, struct platform_device *pdev)
+{
+	struct fwnode_handle *child;
+	struct ma35_pin_ctrl *ctrl;
+	struct ma35_pin_bank *bank;
+	int i, id = 0;
+
+	ctrl = pctl->ctrl;
+	ctrl->nr_banks = MA35_GPIO_BANK_MAX;
+
+	ctrl->pin_banks = devm_kcalloc(&pdev->dev, ctrl->nr_banks,
+				       sizeof(*ctrl->pin_banks), GFP_KERNEL);
+	if (!ctrl->pin_banks)
+		return -ENOMEM;
+
+	for (i = 0; i < ctrl->nr_banks; i++) {
+		ctrl->pin_banks[i].bank_num = i;
+		ctrl->pin_banks[i].name = gpio_group_name[i];
+	}
+
+	for_each_gpiochip_node(&pdev->dev, child) {
+		struct device_node *np = to_of_node(child);
+
+		bank = &ctrl->pin_banks[id];
+		bank->np = np;
+		bank->regmap = pctl->regmap;
+		bank->dev = &pdev->dev;
+		if (!ma35_get_bank_data(bank, pctl))
+			bank->valid = true;
+		id++;
+	}
+	return 0;
+}
+
+static void ma35_gpio_cla_port(unsigned int gpio_num, unsigned int *group,
+			       unsigned int *num)
+{
+	*group = gpio_num / MA35_GPIO_PORT_MAX;
+	*num = gpio_num % MA35_GPIO_PORT_MAX;
+}
+
+static int ma35_pinconf_set_pull(struct ma35_pinctrl *npctl, unsigned int pin,
+				 int pull_up)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_PUSEL);
+	regval &= ~GENMASK(port * 2 + 1, port * 2);
+
+	switch (pull_up) {
+	case PIN_CONFIG_BIAS_PULL_UP:
+		regval |= MA35_GP_PUSEL_PULL_UP << port * 2;
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		regval |= MA35_GP_PUSEL_PULL_DOWN << port * 2;
+		break;
+
+	case MA35_GP_PUSEL_DISABLE:
+		regval |= MA35_GP_PUSEL_DISABLE << port * 2;
+		break;
+
+	default:
+		regval |= MA35_GP_PUSEL_DISABLE << port * 2;
+		break;
+	}
+	writel(regval, base + MA35_GP_REG_PUSEL);
+
+	return 0;
+}
+
+static int ma35_pinconf_get_output(struct ma35_pinctrl *npctl, unsigned int pin)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval, mode;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_MODE);
+	mode = (regval & GENMASK(port * 2 + 1, port * 2)) >> port * 2;
+
+	if (mode == MA35_GP_MODE_OUTPUT)
+		return 1;
+
+	return 0;
+}
+
+static int ma35_pinconf_get_pull(struct ma35_pinctrl *npctl, unsigned int pin)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval, mode;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_PUSEL);
+	mode = (regval & GENMASK(port * 2 + 1, port * 2)) >> port * 2;
+
+	switch (mode) {
+	case MA35_GP_PUSEL_PULL_UP:
+		return PIN_CONFIG_BIAS_PULL_UP;
+
+	case MA35_GP_PUSEL_PULL_DOWN:
+		return PIN_CONFIG_BIAS_PULL_DOWN;
+
+	case MA35_GP_PUSEL_DISABLE:
+		return PIN_CONFIG_BIAS_DISABLE;
+	}
+
+	return PIN_CONFIG_BIAS_DISABLE;
+}
+
+static int ma35_pinconf_set_output(struct ma35_pinctrl *npctl, unsigned int pin, bool out)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_MODE);
+	regval &= ~GENMASK(port * 2 + 1, port * 2);
+	regval |= MA35_GP_MODE_OUTPUT << port * 2;
+	writel(regval, base + MA35_GP_REG_MODE);
+
+	return 0;
+}
+
+static int ma35_pinconf_get_power_source(struct ma35_pinctrl *npctl, unsigned int pin)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SPW);
+
+	if (regval & BIT(port))
+		return MVOLT_3300;
+	else
+		return MVOLT_1800;
+}
+
+static int ma35_pinconf_set_power_source(struct ma35_pinctrl *npctl,
+					 unsigned int pin, int arg)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	if ((arg != MVOLT_1800) && (arg != MVOLT_3300))
+		return -EINVAL;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SPW);
+
+	if (arg == MVOLT_1800)
+		regval &= ~BIT(port);
+	else
+		regval |= BIT(port);
+
+	writel(regval, base + MA35_GP_REG_SPW);
+
+	return 0;
+}
+
+static int ma35_pinconf_get_drive_strength(struct ma35_pinctrl *npctl, unsigned int pin,
+					   u32 *strength)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval, ds_val;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	if (port < MA35_GP_DSH_BASE_PORT) {
+		regval = readl(base + MA35_GP_REG_DSL);
+		ds_val = (regval & GENMASK(port * 4 + 2, port * 4)) >> port * 4;
+	} else {
+		port -= MA35_GP_DSH_BASE_PORT;
+		regval = readl(base + MA35_GP_REG_DSH);
+		ds_val = (regval & GENMASK(port * 4 + 2, port * 4)) >> port * 4;
+	}
+
+	if (ma35_pinconf_get_power_source(npctl, pin) == MVOLT_1800)
+		*strength = ds_1800mv_tbl[ds_val];
+	else
+		*strength = ds_3300mv_tbl[ds_val];
+
+	return 0;
+}
+
+static int ma35_pinconf_set_drive_strength(struct ma35_pinctrl *npctl, unsigned int pin,
+					   int strength)
+{
+	int port, group_num;
+	void __iomem *base;
+	int i, ds_val = -1;
+	u32 regval;
+
+	if (ma35_pinconf_get_power_source(npctl, pin) == MVOLT_1800) {
+		for (i = 0; i < ARRAY_SIZE(ds_1800mv_tbl); i++) {
+			if (ds_1800mv_tbl[i] == strength)
+				ds_val = i;
+		}
+	} else {
+		for (i = 0; i < ARRAY_SIZE(ds_3300mv_tbl); i++) {
+			if (ds_3300mv_tbl[i] == strength)
+				ds_val = i;
+		}
+	}
+	if (ds_val == -1)
+		return -EINVAL;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	if (port < MA35_GP_DSH_BASE_PORT) {
+		regval = readl(base + MA35_GP_REG_DSL);
+		regval &= ~GENMASK(port * 4 + 2, port * 4);
+		regval |= ds_val << port * 4;
+		writel(regval, base + MA35_GP_REG_DSL);
+	} else {
+		port -= MA35_GP_DSH_BASE_PORT;
+		regval = readl(base + MA35_GP_REG_DSH);
+		regval &= ~GENMASK(port * 4 + 2, port * 4);
+		regval |= ds_val << port * 4;
+		writel(regval, base + MA35_GP_REG_DSH);
+	}
+	return 0;
+}
+
+static int ma35_pinconf_get_schmitt_enable(struct ma35_pinctrl *npctl, unsigned int pin)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SMTEN);
+
+	return !!(regval & BIT(port));
+}
+
+static int ma35_pinconf_set_schmitt(struct ma35_pinctrl *npctl, unsigned int pin, int enable)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SMTEN);
+
+	if (enable)
+		regval |= BIT(port);
+	else
+		regval &= ~BIT(port);
+
+	writel(regval, base + MA35_GP_REG_SMTEN);
+
+	return 0;
+}
+
+static int ma35_pinconf_get_slew_rate(struct ma35_pinctrl *npctl, unsigned int pin)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SLEWCTL);
+
+	return (regval & GENMASK(port * 2 + 1, port * 2)) >> port * 2;
+}
+
+static int ma35_pinconf_set_slew_rate(struct ma35_pinctrl *npctl, unsigned int pin, int rate)
+{
+	int port, group_num;
+	void __iomem *base;
+	u32 regval;
+
+	ma35_gpio_cla_port(pin, &group_num, &port);
+	base = npctl->ctrl->pin_banks[group_num].reg_base;
+
+	regval = readl(base + MA35_GP_REG_SLEWCTL);
+	regval &= ~GENMASK(port * 2 + 1, port * 2);
+	regval |= rate << port * 2;
+	writel(regval, base + MA35_GP_REG_SLEWCTL);
+
+	return 0;
+}
+
+static int ma35_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *config)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	u32 arg;
+	int ret;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (ma35_pinconf_get_pull(npctl, pin) == param)
+			arg = 1;
+		else
+			return -EINVAL;
+		break;
+
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		ret = ma35_pinconf_get_drive_strength(npctl, pin, &arg);
+		if (ret)
+			return ret;
+		break;
+
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		arg = ma35_pinconf_get_schmitt_enable(npctl, pin);
+		break;
+
+	case PIN_CONFIG_SLEW_RATE:
+		arg = ma35_pinconf_get_slew_rate(npctl, pin);
+		break;
+
+	case PIN_CONFIG_OUTPUT_ENABLE:
+		arg = ma35_pinconf_get_output(npctl, pin);
+		break;
+
+	case PIN_CONFIG_POWER_SOURCE:
+		arg = ma35_pinconf_get_power_source(npctl, pin);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int ma35_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+			    unsigned long *configs, unsigned int num_configs)
+{
+	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param;
+	unsigned int arg = 0;
+	int i, ret = 0;
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_DISABLE:
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			ret = ma35_pinconf_set_pull(npctl, pin, param);
+			break;
+
+		case PIN_CONFIG_DRIVE_STRENGTH:
+			ret = ma35_pinconf_set_drive_strength(npctl, pin, arg);
+			break;
+
+		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+			ret = ma35_pinconf_set_schmitt(npctl, pin, 1);
+			break;
+
+		case PIN_CONFIG_INPUT_SCHMITT:
+			ret = ma35_pinconf_set_schmitt(npctl, pin, arg);
+			break;
+
+		case PIN_CONFIG_SLEW_RATE:
+			ret = ma35_pinconf_set_slew_rate(npctl, pin, arg);
+			break;
+
+		case PIN_CONFIG_OUTPUT_ENABLE:
+			ret = ma35_pinconf_set_output(npctl, pin, arg);
+			break;
+
+		case PIN_CONFIG_POWER_SOURCE:
+			ret = ma35_pinconf_set_power_source(npctl, pin, arg);
+			break;
+
+		default:
+			return -EINVAL;
+		}
+	}
+	return ret;
+}
+
+static const struct pinconf_ops ma35_pinconf_ops = {
+	.pin_config_get = ma35_pinconf_get,
+	.pin_config_set = ma35_pinconf_set,
+	.is_generic = true,
+};
+
+static int ma35_pinctrl_parse_groups(struct device_node *np, struct ma35_pin_group *grp,
+				     struct ma35_pinctrl *npctl, u32 index)
+{
+	unsigned long *configs;
+	unsigned int nconfigs;
+	struct ma35_pin_setting *pin;
+	const __be32 *list;
+	int i, j, size, ret;
+
+	dev_dbg(npctl->dev, "group(%d): %s\n", index, np->name);
+
+	grp->name = np->name;
+
+	ret = pinconf_generic_parse_dt_config(np, NULL, &configs, &nconfigs);
+	if (ret)
+		return ret;
+
+	/*
+	 * the binding format is nuvoton,pins = <bank pin-mfp pin-function>,
+	 * do sanity check and calculate pins number
+	 */
+	list = of_get_property(np, "nuvoton,pins", &size);
+	size /= sizeof(*list);
+	if (!size || size % 3) {
+		dev_err(npctl->dev, "wrong setting!\n");
+		return -EINVAL;
+	}
+	grp->npins = size / 3;
+
+	grp->pins = devm_kcalloc(npctl->dev, grp->npins, sizeof(*grp->pins), GFP_KERNEL);
+	if (!grp->pins)
+		return -ENOMEM;
+
+	grp->settings = devm_kcalloc(npctl->dev, grp->npins, sizeof(*grp->settings), GFP_KERNEL);
+	if (!grp->settings)
+		return -ENOMEM;
+
+	pin = grp->settings;
+
+	for (i = 0, j = 0; i < size; i += 3, j++) {
+		pin->offset = be32_to_cpu(*list++) * MA35_MFP_REG_SZ_PER_BANK + MA35_MFP_REG_BASE;
+		pin->shift = (be32_to_cpu(*list++) * MA35_MFP_BITS_PER_PORT) % 32;
+		pin->muxval = be32_to_cpu(*list++);
+		pin->configs = configs;
+		pin->nconfigs = nconfigs;
+		grp->pins[j] = npctl->info->get_pin_num(pin->offset, pin->shift);
+		pin++;
+	}
+	return 0;
+}
+
+static int ma35_pinctrl_parse_functions(struct device_node *np, struct ma35_pinctrl *npctl,
+					u32 index)
+{
+	struct device_node *child;
+	struct ma35_pin_func *func;
+	struct ma35_pin_group *grp;
+	static u32 grp_index;
+	u32 ret, i = 0;
+
+	dev_dbg(npctl->dev, "parse function(%d): %s\n", index, np->name);
+
+	func = &npctl->functions[index];
+	func->name = np->name;
+	func->ngroups = of_get_child_count(np);
+
+	if (func->ngroups <= 0)
+		return 0;
+
+	func->groups = devm_kcalloc(npctl->dev, func->ngroups, sizeof(char *), GFP_KERNEL);
+	if (!func->groups)
+		return -ENOMEM;
+
+	for_each_child_of_node(np, child) {
+		func->groups[i] = child->name;
+		grp = &npctl->groups[grp_index++];
+		ret = ma35_pinctrl_parse_groups(child, grp, npctl, i++);
+		if (ret) {
+			of_node_put(child);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static int ma35_pinctrl_probe_dt(struct platform_device *pdev, struct ma35_pinctrl *npctl)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *child;
+	u32 idx = 0;
+	int ret;
+
+	if (!np)
+		return -ENODEV;
+
+	for_each_child_of_node(np, child) {
+		if (of_property_read_bool(child, "gpio-controller"))
+			continue;
+		npctl->nfunctions++;
+		npctl->ngroups += of_get_child_count(child);
+	}
+
+	npctl->functions = devm_kcalloc(&pdev->dev, npctl->nfunctions,
+					sizeof(*npctl->functions), GFP_KERNEL);
+	if (!npctl->functions)
+		return -ENOMEM;
+
+	npctl->groups = devm_kcalloc(&pdev->dev, npctl->ngroups,
+				     sizeof(*npctl->groups), GFP_KERNEL);
+	if (!npctl->groups)
+		return -ENOMEM;
+
+	dev_dbg(&pdev->dev, "nfunctions = %d\n", npctl->nfunctions);
+	dev_dbg(&pdev->dev, "ngroups = %d\n", npctl->ngroups);
+
+	for_each_child_of_node(np, child) {
+		if (of_property_read_bool(child, "gpio-controller"))
+			continue;
+
+		ret = ma35_pinctrl_parse_functions(child, npctl, idx++);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to parse function\n");
+			of_node_put(child);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+int ma35_pinctrl_probe(struct platform_device *pdev, const struct ma35_pinctrl_soc_info *info)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct pinctrl_desc *ma35_pinctrl_desc;
+	struct ma35_pinctrl *npctl;
+	int ret;
+
+	if (!info || !info->pins || !info->npins) {
+		dev_err(&pdev->dev, "wrong pinctrl info\n");
+		return -EINVAL;
+	}
+
+	npctl = devm_kzalloc(&pdev->dev, sizeof(*npctl), GFP_KERNEL);
+	if (!npctl)
+		return -ENOMEM;
+
+	ma35_pinctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*ma35_pinctrl_desc), GFP_KERNEL);
+	if (!ma35_pinctrl_desc)
+		return -ENOMEM;
+
+	npctl->ctrl = devm_kzalloc(&pdev->dev, sizeof(*npctl->ctrl), GFP_KERNEL);
+	if (!npctl->ctrl)
+		return -ENOMEM;
+
+	ma35_pinctrl_desc->name = dev_name(&pdev->dev);
+	ma35_pinctrl_desc->pins = info->pins;
+	ma35_pinctrl_desc->npins = info->npins;
+	ma35_pinctrl_desc->pctlops = &ma35_pctrl_ops;
+	ma35_pinctrl_desc->pmxops = &ma35_pmx_ops;
+	ma35_pinctrl_desc->confops = &ma35_pinconf_ops;
+	ma35_pinctrl_desc->owner = THIS_MODULE;
+
+	npctl->info = info;
+	npctl->dev = &pdev->dev;
+
+	npctl->regmap = syscon_regmap_lookup_by_phandle(np, "nuvoton,sys");
+	if (IS_ERR(npctl->regmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(npctl->regmap),
+				     "No syscfg phandle specified\n");
+
+	ma35_pinctrl_get_soc_data(npctl, pdev);
+
+	platform_set_drvdata(pdev, npctl);
+
+	ret = ma35_pinctrl_probe_dt(pdev, npctl);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "fail to probe MA35 pinctrl dt\n");
+
+	ret = devm_pinctrl_register_and_init(&pdev->dev, ma35_pinctrl_desc,
+					     npctl, &npctl->pctl);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "fail to register MA35 pinctrl\n");
+
+	ret = pinctrl_enable(npctl->pctl);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "fail to enable MA35 pinctrl\n");
+
+	return ma35_gpiolib_register(pdev, npctl);
+}
+
+int __maybe_unused ma35_pinctrl_suspend(struct device *dev)
+{
+	struct ma35_pinctrl *npctl = dev_get_drvdata(dev);
+
+	return pinctrl_force_sleep(npctl->pctl);
+}
+
+int __maybe_unused ma35_pinctrl_resume(struct device *dev)
+{
+	struct ma35_pinctrl *npctl = dev_get_drvdata(dev);
+
+	return pinctrl_force_default(npctl->pctl);
+}
diff --git a/drivers/pinctrl/nuvoton/pinctrl-ma35.h b/drivers/pinctrl/nuvoton/pinctrl-ma35.h
new file mode 100644
index 000000000000..281605e2c231
--- /dev/null
+++ b/drivers/pinctrl/nuvoton/pinctrl-ma35.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 Nuvoton Technology Corp.
+ *
+ * Author: Shan-Chun Hung <schung at nuvoton.com>
+ */
+#ifndef __PINCTRL_MA35_H
+#define __PINCTRL_MA35_H
+
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+
+struct ma35_mux_desc {
+	const char *name;
+	u32 muxval;
+};
+
+struct ma35_pin_data {
+	u32 offset;
+	u32 shift;
+	struct ma35_mux_desc *muxes;
+};
+
+struct ma35_pinctrl_soc_info {
+	const struct pinctrl_pin_desc *pins;
+	unsigned int npins;
+	int (*get_pin_num)(int offset, int shift);
+};
+
+#define MA35_PIN(num, n, o, s, ...) {			\
+	.number = num,					\
+	.name = #n,					\
+	.drv_data = &(struct ma35_pin_data) {		\
+		.offset = o,				\
+		.shift = s,				\
+		.muxes = (struct ma35_mux_desc[]) {	\
+			 __VA_ARGS__, { } },		\
+	},						\
+}
+
+#define MA35_MUX(_val, _name) {				\
+	.name = _name,					\
+	.muxval = _val,					\
+}
+
+int ma35_pinctrl_probe(struct platform_device *pdev, const struct ma35_pinctrl_soc_info *info);
+int ma35_pinctrl_suspend(struct device *dev);
+int ma35_pinctrl_resume(struct device *dev);
+
+#endif /* __PINCTRL_MA35_H */
diff --git a/drivers/pinctrl/nuvoton/pinctrl-ma35d1.c b/drivers/pinctrl/nuvoton/pinctrl-ma35d1.c
new file mode 100644
index 000000000000..36510c0b0690
--- /dev/null
+++ b/drivers/pinctrl/nuvoton/pinctrl-ma35d1.c
@@ -0,0 +1,1797 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Nuvoton Technology Corp.
+ *
+ * Author: Shan-Chun Hung <schung at nuvoton.com>
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-ma35.h"
+
+static const struct pinctrl_pin_desc ma35d1_pins[] = {
+	MA35_PIN(0, PA0, 0x80, 0x0,
+		MA35_MUX(0x0, "GPA0"),
+		MA35_MUX(0x2, "UART1_nCTS"),
+		MA35_MUX(0x3, "UART16_RXD"),
+		MA35_MUX(0x6, "NAND_DATA0"),
+		MA35_MUX(0x7, "EBI_AD0"),
+		MA35_MUX(0x9, "EBI_ADR0")),
+	MA35_PIN(1, PA1, 0x80, 0x4,
+		MA35_MUX(0x0, "GPA1"),
+		MA35_MUX(0x2, "UART1_nRTS"),
+		MA35_MUX(0x3, "UART16_TXD"),
+		MA35_MUX(0x6, "NAND_DATA1"),
+		MA35_MUX(0x7, "EBI_AD1"),
+		MA35_MUX(0x9, "EBI_ADR1")),
+	MA35_PIN(2, PA2, 0x80, 0x8,
+		MA35_MUX(0x0, "GPA2"),
+		MA35_MUX(0x2, "UART1_RXD"),
+		MA35_MUX(0x6, "NAND_DATA2"),
+		MA35_MUX(0x7, "EBI_AD2"),
+		MA35_MUX(0x9, "EBI_ADR2")),
+	MA35_PIN(3, PA3, 0x80, 0xc,
+		MA35_MUX(0x0, "GPA3"),
+		MA35_MUX(0x2, "UART1_TXD"),
+		MA35_MUX(0x6, "NAND_DATA3"),
+		MA35_MUX(0x7, "EBI_AD3"),
+		MA35_MUX(0x9, "EBI_ADR3")),
+	MA35_PIN(4, PA4, 0x80, 0x10,
+		MA35_MUX(0x0, "GPA4"),
+		MA35_MUX(0x2, "UART3_nCTS"),
+		MA35_MUX(0x3, "UART2_RXD"),
+		MA35_MUX(0x6, "NAND_DATA4"),
+		MA35_MUX(0x7, "EBI_AD4"),
+		MA35_MUX(0x9, "EBI_ADR4")),
+	MA35_PIN(5, PA5, 0x80, 0x14,
+		MA35_MUX(0x0, "GPA5"),
+		MA35_MUX(0x2, "UART3_nRTS"),
+		MA35_MUX(0x3, "UART2_TXD"),
+		MA35_MUX(0x6, "NAND_DATA5"),
+		MA35_MUX(0x7, "EBI_AD5"),
+		MA35_MUX(0x9, "EBI_ADR5")),
+	MA35_PIN(6, PA6, 0x80, 0x18,
+		MA35_MUX(0x0, "GPA6"),
+		MA35_MUX(0x2, "UART3_RXD"),
+		MA35_MUX(0x6, "NAND_DATA6"),
+		MA35_MUX(0x7, "EBI_AD6"),
+		MA35_MUX(0x9, "EBI_ADR6")),
+	MA35_PIN(7, PA7, 0x80, 0x1c,
+		MA35_MUX(0x0, "GPA7"),
+		MA35_MUX(0x2, "UART3_TXD"),
+		MA35_MUX(0x6, "NAND_DATA7"),
+		MA35_MUX(0x7, "EBI_AD7"),
+		MA35_MUX(0x9, "EBI_ADR7")),
+	MA35_PIN(8, PA8, 0x84, 0x0,
+		MA35_MUX(0x0, "GPA8"),
+		MA35_MUX(0x2, "UART5_nCTS"),
+		MA35_MUX(0x3, "UART4_RXD"),
+		MA35_MUX(0x6, "NAND_RDY0"),
+		MA35_MUX(0x7, "EBI_AD8"),
+		MA35_MUX(0x9, "EBI_ADR8")),
+	MA35_PIN(9, PA9, 0x84, 0x4,
+		MA35_MUX(0x0, "GPA9"),
+		MA35_MUX(0x2, "UART5_nRTS"),
+		MA35_MUX(0x3, "UART4_TXD"),
+		MA35_MUX(0x6, "NAND_nRE"),
+		MA35_MUX(0x7, "EBI_AD9"),
+		MA35_MUX(0x9, "EBI_ADR9")),
+	MA35_PIN(10, PA10, 0x84, 0x8,
+		MA35_MUX(0x0, "GPA10"),
+		MA35_MUX(0x2, "UART5_RXD"),
+		MA35_MUX(0x6, "NAND_nWE"),
+		MA35_MUX(0x7, "EBI_AD10"),
+		MA35_MUX(0x9, "EBI_ADR10")),
+	MA35_PIN(11, PA11, 0x84, 0xc,
+		MA35_MUX(0x0, "GPA11"),
+		MA35_MUX(0x2, "UART5_TXD"),
+		MA35_MUX(0x6, "NAND_CLE"),
+		MA35_MUX(0x7, "EBI_AD11"),
+		MA35_MUX(0x9, "EBI_ADR11")),
+	MA35_PIN(12, PA12, 0x84, 0x10,
+		MA35_MUX(0x0, "GPA12"),
+		MA35_MUX(0x2, "UART7_nCTS"),
+		MA35_MUX(0x3, "UART8_RXD"),
+		MA35_MUX(0x6, "NAND_ALE"),
+		MA35_MUX(0x7, "EBI_AD12"),
+		MA35_MUX(0x9, "EBI_ADR12")),
+	MA35_PIN(13, PA13, 0x84, 0x14,
+		MA35_MUX(0x0, "GPA13"),
+		MA35_MUX(0x2, "UART7_nRTS"),
+		MA35_MUX(0x3, "UART8_TXD"),
+		MA35_MUX(0x6, "NAND_nCS0"),
+		MA35_MUX(0x7, "EBI_AD13"),
+		MA35_MUX(0x9, "EBI_ADR13")),
+	MA35_PIN(14, PA14, 0x84, 0x18,
+		MA35_MUX(0x0, "GPA14"),
+		MA35_MUX(0x2, "UART7_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x6, "NAND_nWP"),
+		MA35_MUX(0x7, "EBI_AD14"),
+		MA35_MUX(0x9, "EBI_ADR14")),
+	MA35_PIN(15, PA15, 0x84, 0x1c,
+		MA35_MUX(0x0, "GPA15"),
+		MA35_MUX(0x1, "EPWM0_CH2"),
+		MA35_MUX(0x2, "UART9_nCTS"),
+		MA35_MUX(0x3, "UART6_RXD"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x5, "CAN2_RXD"),
+		MA35_MUX(0x7, "EBI_ALE"),
+		MA35_MUX(0x9, "QEI0_A"),
+		MA35_MUX(0xb, "TM1"),
+		MA35_MUX(0xe, "RGMII0_PPS"),
+		MA35_MUX(0xf, "RMII0_PPS")),
+	MA35_PIN(16, PB0, 0x88, 0x0,
+		MA35_MUX(0x0, "GPB0"),
+		MA35_MUX(0x8, "EADC0_CH0")),
+	MA35_PIN(17, PB1, 0x88, 0x4,
+		MA35_MUX(0x0, "GPB1"),
+		MA35_MUX(0x8, "EADC0_CH1")),
+	MA35_PIN(18, PB2, 0x88, 0x8,
+		MA35_MUX(0x0, "GPB2"),
+		MA35_MUX(0x8, "EADC0_CH2")),
+	MA35_PIN(19, PB3, 0x88, 0xc,
+		MA35_MUX(0x0, "GPB3"),
+		MA35_MUX(0x8, "EADC0_CH3")),
+	MA35_PIN(20, PB4, 0x88, 0x10,
+		MA35_MUX(0x0, "GPB4"),
+		MA35_MUX(0x8, "EADC0_CH4")),
+	MA35_PIN(21, PB5, 0x88, 0x14,
+		MA35_MUX(0x0, "GPB5"),
+		MA35_MUX(0x8, "EADC0_CH5")),
+	MA35_PIN(22, PB6, 0x88, 0x18,
+		MA35_MUX(0x0, "GPB6"),
+		MA35_MUX(0x8, "EADC0_CH6")),
+	MA35_PIN(23, PB7, 0x88, 0x1c,
+		MA35_MUX(0x0, "GPB7"),
+		MA35_MUX(0x8, "EADC0_CH7")),
+	MA35_PIN(24, PB8, 0x8c, 0x0,
+		MA35_MUX(0x0, "GPB8"),
+		MA35_MUX(0x1, "EPWM2_BRAKE0"),
+		MA35_MUX(0x2, "UART2_nCTS"),
+		MA35_MUX(0x3, "UART1_RXD"),
+		MA35_MUX(0x4, "I2C2_SDA"),
+		MA35_MUX(0x5, "SPI0_SS1"),
+		MA35_MUX(0x6, "SPI0_I2SMCLK"),
+		MA35_MUX(0x8, "ADC0_CH0"),
+		MA35_MUX(0x9, "EBI_nCS0"),
+		MA35_MUX(0xb, "TM4"),
+		MA35_MUX(0xe, "QEI2_INDEX"),
+		MA35_MUX(0xf, "KPI_ROW6")),
+	MA35_PIN(25, PB9, 0x8c, 0x4,
+		MA35_MUX(0x0, "GPB9"),
+		MA35_MUX(0x1, "EPWM2_CH4"),
+		MA35_MUX(0x2, "UART2_nRTS"),
+		MA35_MUX(0x3, "UART1_TXD"),
+		MA35_MUX(0x4, "I2C2_SCL"),
+		MA35_MUX(0x5, "SPI0_CLK"),
+		MA35_MUX(0x6, "I2S0_MCLK"),
+		MA35_MUX(0x7, "CCAP1_HSYNC"),
+		MA35_MUX(0x8, "ADC0_CH1"),
+		MA35_MUX(0x9, "EBI_ALE"),
+		MA35_MUX(0xa, "EBI_AD13"),
+		MA35_MUX(0xb, "TM0_EXT"),
+		MA35_MUX(0xc, "I2S1_MCLK"),
+		MA35_MUX(0xd, "SC0_nCD"),
+		MA35_MUX(0xe, "QEI2_A"),
+		MA35_MUX(0xf, "KPI_ROW7")),
+	MA35_PIN(26, PB10, 0x8c, 0x8,
+		MA35_MUX(0x0, "GPB10"),
+		MA35_MUX(0x1, "EPWM2_CH5"),
+		MA35_MUX(0x2, "UART2_RXD"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x5, "SPI0_MOSI"),
+		MA35_MUX(0x6, "EBI_MCLK"),
+		MA35_MUX(0x7, "CCAP1_VSYNC"),
+		MA35_MUX(0x8, "ADC0_CH2"),
+		MA35_MUX(0x9, "EBI_ADR15"),
+		MA35_MUX(0xa, "EBI_AD14"),
+		MA35_MUX(0xb, "TM5"),
+		MA35_MUX(0xc, "I2C1_SDA"),
+		MA35_MUX(0xd, "INT1"),
+		MA35_MUX(0xe, "QEI2_B")),
+	MA35_PIN(27, PB11, 0x8c, 0xc,
+		MA35_MUX(0x0, "GPB11"),
+		MA35_MUX(0x1, "EPWM2_BRAKE1"),
+		MA35_MUX(0x2, "UART2_TXD"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x5, "SPI0_MISO"),
+		MA35_MUX(0x6, "I2S1_MCLK"),
+		MA35_MUX(0x7, "CCAP1_SFIELD"),
+		MA35_MUX(0x8, "ADC0_CH3"),
+		MA35_MUX(0x9, "EBI_nCS2"),
+		MA35_MUX(0xa, "EBI_ALE"),
+		MA35_MUX(0xb, "TM5_EXT"),
+		MA35_MUX(0xc, "I2C1_SCL"),
+		MA35_MUX(0xd, "INT2"),
+		MA35_MUX(0xe, "QEI2_INDEX")),
+	MA35_PIN(28, PB12, 0x8c, 0x10,
+		MA35_MUX(0x0, "GPB12"),
+		MA35_MUX(0x1, "EPWM2_CH0"),
+		MA35_MUX(0x2, "UART4_nCTS"),
+		MA35_MUX(0x3, "UART3_RXD"),
+		MA35_MUX(0x4, "I2C3_SDA"),
+		MA35_MUX(0x5, "CAN2_RXD"),
+		MA35_MUX(0x6, "I2S1_LRCK"),
+		MA35_MUX(0x8, "ADC0_CH4"),
+		MA35_MUX(0x9, "EBI_ADR16"),
+		MA35_MUX(0xe, "ECAP2_IC0")),
+	MA35_PIN(29, PB13, 0x8c, 0x14,
+		MA35_MUX(0x0, "GPB13"),
+		MA35_MUX(0x1, "EPWM2_CH1"),
+		MA35_MUX(0x2, "UART4_nRTS"),
+		MA35_MUX(0x3, "UART3_TXD"),
+		MA35_MUX(0x4, "I2C3_SCL"),
+		MA35_MUX(0x5, "CAN2_TXD"),
+		MA35_MUX(0x6, "I2S1_BCLK"),
+		MA35_MUX(0x8, "ADC0_CH5"),
+		MA35_MUX(0x9, "EBI_ADR17"),
+		MA35_MUX(0xe, "ECAP2_IC1")),
+	MA35_PIN(30, PB14, 0x8c, 0x18,
+		MA35_MUX(0x0, "GPB14"),
+		MA35_MUX(0x1, "EPWM2_CH2"),
+		MA35_MUX(0x2, "UART4_RXD"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x5, "I2C4_SDA"),
+		MA35_MUX(0x6, "I2S1_DI"),
+		MA35_MUX(0x8, "ADC0_CH6"),
+		MA35_MUX(0x9, "EBI_ADR18"),
+		MA35_MUX(0xe, "ECAP2_IC2")),
+	MA35_PIN(31, PB15, 0x8c, 0x1c,
+		MA35_MUX(0x0, "GPB15"),
+		MA35_MUX(0x1, "EPWM2_CH3"),
+		MA35_MUX(0x2, "UART4_TXD"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x5, "I2C4_SCL"),
+		MA35_MUX(0x6, "I2S1_DO"),
+		MA35_MUX(0x8, "ADC0_CH7"),
+		MA35_MUX(0x9, "EBI_ADR19")),
+	MA35_PIN(32, PC0, 0x90, 0x0,
+		MA35_MUX(0x0, "GPC0"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x6, "SD0_CMD/eMMC0_CMD")),
+	MA35_PIN(33, PC1, 0x90, 0x4,
+		MA35_MUX(0x0, "GPC1"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x6, "SD0_CLK/eMMC0_CLK")),
+	MA35_PIN(34, PC2, 0x90, 0x8,
+		MA35_MUX(0x0, "GPC2"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x6, "SD0_DAT0/eMMC0_DAT0")),
+	MA35_PIN(35, PC3, 0x90, 0xc,
+		MA35_MUX(0x0, "GPC3"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x6, "SD0_DAT1/eMMC0_DAT1")),
+	MA35_PIN(36, PC4, 0x90, 0x10,
+		MA35_MUX(0x0, "GPC4"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x6, "SD0_DAT2/eMMC0_DAT2")),
+	MA35_PIN(37, PC5, 0x90, 0x14,
+		MA35_MUX(0x0, "GPC5"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x6, "SD0_DAT3/eMMC0_DAT3")),
+	MA35_PIN(38, PC6, 0x90, 0x18,
+		MA35_MUX(0x0, "GPC6"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x6, "SD0_nCD")),
+	MA35_PIN(39, PC7, 0x90, 0x1c,
+		MA35_MUX(0x0, "GPC7"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x6, "SD0_WP")),
+	MA35_PIN(40, PC12, 0x94, 0x10,
+		MA35_MUX(0x0, "GPC12"),
+		MA35_MUX(0x2, "UART12_nCTS"),
+		MA35_MUX(0x3, "UART11_RXD"),
+		MA35_MUX(0x6, "LCM_DATA16")),
+	MA35_PIN(41, PC13, 0x94, 0x14,
+		MA35_MUX(0x0, "GPC13"),
+		MA35_MUX(0x2, "UART12_nRTS"),
+		MA35_MUX(0x3, "UART11_TXD"),
+		MA35_MUX(0x6, "LCM_DATA17")),
+	MA35_PIN(42, PC14, 0x94, 0x18,
+		MA35_MUX(0x0, "GPC14"),
+		MA35_MUX(0x2, "UART12_RXD"),
+		MA35_MUX(0x6, "LCM_DATA18")),
+	MA35_PIN(43, PC15, 0x94, 0x1c,
+		MA35_MUX(0x0, "GPC15"),
+		MA35_MUX(0x2, "UART12_TXD"),
+		MA35_MUX(0x6, "LCM_DATA19"),
+		MA35_MUX(0x7, "LCM_MPU_TE"),
+		MA35_MUX(0x8, "LCM_MPU_VSYNC")),
+	MA35_PIN(44, PD0, 0x98, 0x0,
+		MA35_MUX(0x0, "GPD0"),
+		MA35_MUX(0x2, "UART3_nCTS"),
+		MA35_MUX(0x3, "UART4_RXD"),
+		MA35_MUX(0x5, "QSPI0_SS0")),
+	MA35_PIN(45, PD1, 0x98, 0x4,
+		MA35_MUX(0x0, "GPD1"),
+		MA35_MUX(0x2, "UART3_nRTS"),
+		MA35_MUX(0x3, "UART4_TXD"),
+		MA35_MUX(0x5, "QSPI0_CLK")),
+	MA35_PIN(46, PD2, 0x98, 0x8,
+		MA35_MUX(0x0, "GPD2"),
+		MA35_MUX(0x2, "UART3_RXD"),
+		MA35_MUX(0x5, "QSPI0_MOSI0")),
+	MA35_PIN(47, PD3, 0x98, 0xc,
+		MA35_MUX(0x0, "GPD3"),
+		MA35_MUX(0x2, "UART3_TXD"),
+		MA35_MUX(0x5, "QSPI0_MISO0")),
+	MA35_PIN(48, PD4, 0x98, 0x10,
+		MA35_MUX(0x0, "GPD4"),
+		MA35_MUX(0x2, "UART1_nCTS"),
+		MA35_MUX(0x3, "UART2_RXD"),
+		MA35_MUX(0x4, "I2C2_SDA"),
+		MA35_MUX(0x5, "QSPI0_MOSI1")),
+	MA35_PIN(49, PD5, 0x98, 0x14,
+		MA35_MUX(0x0, "GPD5"),
+		MA35_MUX(0x2, "UART1_nRTS"),
+		MA35_MUX(0x3, "UART2_TXD"),
+		MA35_MUX(0x4, "I2C2_SCL"),
+		MA35_MUX(0x5, "QSPI0_MISO1")),
+	MA35_PIN(50, PD6, 0x98, 0x18,
+		MA35_MUX(0x0, "GPD6"),
+		MA35_MUX(0x1, "EPWM0_SYNC_IN"),
+		MA35_MUX(0x2, "UART1_RXD"),
+		MA35_MUX(0x5, "QSPI1_MOSI1"),
+		MA35_MUX(0x6, "I2C0_SDA"),
+		MA35_MUX(0x7, "I2S0_MCLK"),
+		MA35_MUX(0x8, "EPWM0_CH0"),
+		MA35_MUX(0x9, "EBI_AD5"),
+		MA35_MUX(0xa, "SPI3_SS1"),
+		MA35_MUX(0xb, "TRACE_CLK")),
+	MA35_PIN(51, PD7, 0x98, 0x1c,
+		MA35_MUX(0x0, "GPD7"),
+		MA35_MUX(0x1, "EPWM0_SYNC_OUT"),
+		MA35_MUX(0x2, "UART1_TXD"),
+		MA35_MUX(0x5, "QSPI1_MISO1"),
+		MA35_MUX(0x6, "I2C0_SCL"),
+		MA35_MUX(0x7, "I2S1_MCLK"),
+		MA35_MUX(0x8, "EPWM0_CH1"),
+		MA35_MUX(0x9, "EBI_AD6"),
+		MA35_MUX(0xa, "SC1_nCD"),
+		MA35_MUX(0xb, "EADC0_ST")),
+	MA35_PIN(52, PD8, 0x9c, 0x0,
+		MA35_MUX(0x0, "GPD8"),
+		MA35_MUX(0x1, "EPWM0_BRAKE0"),
+		MA35_MUX(0x2, "UART16_nCTS"),
+		MA35_MUX(0x3, "UART15_RXD"),
+		MA35_MUX(0x5, "QSPI1_SS0"),
+		MA35_MUX(0x7, "I2S1_LRCK"),
+		MA35_MUX(0x8, "EPWM0_CH2"),
+		MA35_MUX(0x9, "EBI_AD7"),
+		MA35_MUX(0xa, "SC1_CLK"),
+		MA35_MUX(0xb, "TM0")),
+	MA35_PIN(53, PD9, 0x9c, 0x4,
+		MA35_MUX(0x0, "GPD9"),
+		MA35_MUX(0x1, "EPWM0_BRAKE1"),
+		MA35_MUX(0x2, "UART16_nRTS"),
+		MA35_MUX(0x3, "UART15_TXD"),
+		MA35_MUX(0x5, "QSPI1_CLK"),
+		MA35_MUX(0x7, "I2S1_BCLK"),
+		MA35_MUX(0x8, "EPWM0_CH3"),
+		MA35_MUX(0x9, "EBI_AD8"),
+		MA35_MUX(0xa, "SC1_DAT"),
+		MA35_MUX(0xb, "TM0_EXT")),
+	MA35_PIN(54, PD10, 0x9c, 0x8,
+		MA35_MUX(0x0, "GPD10"),
+		MA35_MUX(0x1, "EPWM1_BRAKE0"),
+		MA35_MUX(0x2, "UART16_RXD"),
+		MA35_MUX(0x5, "QSPI1_MOSI0"),
+		MA35_MUX(0x7, "I2S1_DI"),
+		MA35_MUX(0x8, "EPWM0_CH4"),
+		MA35_MUX(0x9, "EBI_AD9"),
+		MA35_MUX(0xa, "SC1_RST"),
+		MA35_MUX(0xb, "TM2")),
+	MA35_PIN(55, PD11, 0x9c, 0xc,
+		MA35_MUX(0x0, "GPD11"),
+		MA35_MUX(0x1, "EPWM1_BRAKE1"),
+		MA35_MUX(0x2, "UART16_TXD"),
+		MA35_MUX(0x5, "QSPI1_MISO0"),
+		MA35_MUX(0x7, "I2S1_DO"),
+		MA35_MUX(0x8, "EPWM0_CH5"),
+		MA35_MUX(0x9, "EBI_AD10"),
+		MA35_MUX(0xa, "SC1_PWR"),
+		MA35_MUX(0xb, "TM2_EXT")),
+	MA35_PIN(56, PD12, 0x9c, 0x10,
+		MA35_MUX(0x0, "GPD12"),
+		MA35_MUX(0x1, "EPWM0_BRAKE0"),
+		MA35_MUX(0x2, "UART11_TXD"),
+		MA35_MUX(0x3, "UART10_RXD"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x6, "TRACE_DATA0"),
+		MA35_MUX(0x7, "EBI_nCS1"),
+		MA35_MUX(0x8, "EBI_AD4"),
+		MA35_MUX(0x9, "QEI0_INDEX"),
+		MA35_MUX(0xb, "TM5"),
+		MA35_MUX(0xc, "I2S1_LRCK"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(57, PD13, 0x9c, 0x14,
+		MA35_MUX(0x0, "GPD13"),
+		MA35_MUX(0x1, "EPWM0_BRAKE1"),
+		MA35_MUX(0x2, "UART11_RXD"),
+		MA35_MUX(0x3, "UART10_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x6, "TRACE_DATA1"),
+		MA35_MUX(0x7, "EBI_nCS2"),
+		MA35_MUX(0x8, "EBI_AD5"),
+		MA35_MUX(0x9, "ECAP0_IC0"),
+		MA35_MUX(0xb, "TM5_EXT"),
+		MA35_MUX(0xc, "I2S1_BCLK")),
+	MA35_PIN(58, PD14, 0x9c, 0x18,
+		MA35_MUX(0x0, "GPD14"),
+		MA35_MUX(0x1, "EPWM0_SYNC_IN"),
+		MA35_MUX(0x2, "UART11_nCTS"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x6, "TRACE_DATA2"),
+		MA35_MUX(0x7, "EBI_MCLK"),
+		MA35_MUX(0x8, "EBI_AD6"),
+		MA35_MUX(0x9, "ECAP0_IC1"),
+		MA35_MUX(0xb, "TM6"),
+		MA35_MUX(0xc, "I2S1_DI"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(59, PD15, 0x9c, 0x1c,
+		MA35_MUX(0x0, "GPD15"),
+		MA35_MUX(0x1, "EPWM0_SYNC_OUT"),
+		MA35_MUX(0x2, "UART11_nRTS"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x6, "TRACE_DATA3"),
+		MA35_MUX(0x7, "EBI_ALE"),
+		MA35_MUX(0x8, "EBI_AD7"),
+		MA35_MUX(0x9, "ECAP0_IC2"),
+		MA35_MUX(0xb, "TM6_EXT"),
+		MA35_MUX(0xc, "I2S1_DO")),
+	MA35_PIN(60, PE0, 0xa0, 0x0,
+		MA35_MUX(0x0, "GPE0"),
+		MA35_MUX(0x2, "UART9_nCTS"),
+		MA35_MUX(0x3, "UART8_RXD"),
+		MA35_MUX(0x7, "CCAP1_DATA0"),
+		MA35_MUX(0x8, "RGMII0_MDC"),
+		MA35_MUX(0x9, "RMII0_MDC")),
+	MA35_PIN(61, PE1, 0xa0, 0x4,
+		MA35_MUX(0x0, "GPE1"),
+		MA35_MUX(0x2, "UART9_nRTS"),
+		MA35_MUX(0x3, "UART8_TXD"),
+		MA35_MUX(0x7, "CCAP1_DATA1"),
+		MA35_MUX(0x8, "RGMII0_MDIO"),
+		MA35_MUX(0x9, "RMII0_MDIO")),
+	MA35_PIN(62, PE2, 0xa0, 0x8,
+		MA35_MUX(0x0, "GPE2"),
+		MA35_MUX(0x2, "UART9_RXD"),
+		MA35_MUX(0x7, "CCAP1_DATA2"),
+		MA35_MUX(0x8, "RGMII0_TXCTL"),
+		MA35_MUX(0x9, "RMII0_TXEN")),
+	MA35_PIN(63, PE3, 0xa0, 0xc,
+		MA35_MUX(0x0, "GPE3"),
+		MA35_MUX(0x2, "UART9_TXD"),
+		MA35_MUX(0x7, "CCAP1_DATA3"),
+		MA35_MUX(0x8, "RGMII0_TXD0"),
+		MA35_MUX(0x9, "RMII0_TXD0")),
+	MA35_PIN(64, PE4, 0xa0, 0x10,
+		MA35_MUX(0x0, "GPE4"),
+		MA35_MUX(0x2, "UART4_nCTS"),
+		MA35_MUX(0x3, "UART3_RXD"),
+		MA35_MUX(0x7, "CCAP1_DATA4"),
+		MA35_MUX(0x8, "RGMII0_TXD1"),
+		MA35_MUX(0x9, "RMII0_TXD1")),
+	MA35_PIN(65, PE5, 0xa0, 0x14,
+		MA35_MUX(0x0, "GPE5"),
+		MA35_MUX(0x2, "UART4_nRTS"),
+		MA35_MUX(0x3, "UART3_TXD"),
+		MA35_MUX(0x7, "CCAP1_DATA5"),
+		MA35_MUX(0x8, "RGMII0_RXCLK"),
+		MA35_MUX(0x9, "RMII0_REFCLK")),
+	MA35_PIN(66, PE6, 0xa0, 0x18,
+		MA35_MUX(0x0, "GPE6"),
+		MA35_MUX(0x2, "UART4_RXD"),
+		MA35_MUX(0x7, "CCAP1_DATA6"),
+		MA35_MUX(0x8, "RGMII0_RXCTL"),
+		MA35_MUX(0x9, "RMII0_CRSDV")),
+	MA35_PIN(67, PE7, 0xa0, 0x1c,
+		MA35_MUX(0x0, "GPE7"),
+		MA35_MUX(0x2, "UART4_TXD"),
+		MA35_MUX(0x7, "CCAP1_DATA7"),
+		MA35_MUX(0x8, "RGMII0_RXD0"),
+		MA35_MUX(0x9, "RMII0_RXD0")),
+	MA35_PIN(68, PE8, 0xa4, 0x0,
+		MA35_MUX(0x0, "GPE8"),
+		MA35_MUX(0x2, "UART13_nCTS"),
+		MA35_MUX(0x3, "UART12_RXD"),
+		MA35_MUX(0x7, "CCAP1_SCLK"),
+		MA35_MUX(0x8, "RGMII0_RXD1"),
+		MA35_MUX(0x9, "RMII0_RXD1")),
+	MA35_PIN(69, PE9, 0xa4, 0x4,
+		MA35_MUX(0x0, "GPE9"),
+		MA35_MUX(0x2, "UART13_nRTS"),
+		MA35_MUX(0x3, "UART12_TXD"),
+		MA35_MUX(0x7, "CCAP1_PIXCLK"),
+		MA35_MUX(0x8, "RGMII0_RXD2"),
+		MA35_MUX(0x9, "RMII0_RXERR")),
+	MA35_PIN(70, PE10, 0xa4, 0x8,
+		MA35_MUX(0x0, "GPE10"),
+		MA35_MUX(0x2, "UART15_nCTS"),
+		MA35_MUX(0x3, "UART14_RXD"),
+		MA35_MUX(0x5, "SPI1_SS0"),
+		MA35_MUX(0x7, "CCAP1_HSYNC"),
+		MA35_MUX(0x8, "RGMII0_RXD3")),
+	MA35_PIN(71, PE11, 0xa4, 0xc,
+		MA35_MUX(0x0, "GPE11"),
+		MA35_MUX(0x2, "UART15_nRTS"),
+		MA35_MUX(0x3, "UART14_TXD"),
+		MA35_MUX(0x5, "SPI1_CLK"),
+		MA35_MUX(0x7, "CCAP1_VSYNC"),
+		MA35_MUX(0x8, "RGMII0_TXCLK")),
+	MA35_PIN(72, PE12, 0xa4, 0x10,
+		MA35_MUX(0x0, "GPE12"),
+		MA35_MUX(0x2, "UART15_RXD"),
+		MA35_MUX(0x5, "SPI1_MOSI"),
+		MA35_MUX(0x7, "CCAP1_DATA8"),
+		MA35_MUX(0x8, "RGMII0_TXD2")),
+	MA35_PIN(73, PE13, 0xa4, 0x14,
+		MA35_MUX(0x0, "GPE13"),
+		MA35_MUX(0x2, "UART15_TXD"),
+		MA35_MUX(0x5, "SPI1_MISO"),
+		MA35_MUX(0x7, "CCAP1_DATA9"),
+		MA35_MUX(0x8, "RGMII0_TXD3")),
+	MA35_PIN(74, PE14, 0xa4, 0x18,
+		MA35_MUX(0x0, "GPE14"),
+		MA35_MUX(0x1, "UART0_TXD")),
+	MA35_PIN(75, PE15, 0xa4, 0x1c,
+		MA35_MUX(0x0, "GPE15"),
+		MA35_MUX(0x1, "UART0_RXD")),
+	MA35_PIN(76, PF0, 0xa8, 0x0,
+		MA35_MUX(0x0, "GPF0"),
+		MA35_MUX(0x2, "UART2_nCTS"),
+		MA35_MUX(0x3, "UART1_RXD"),
+		MA35_MUX(0x6, "RGMII0_RXD3"),
+		MA35_MUX(0x8, "RGMII1_MDC"),
+		MA35_MUX(0x9, "RMII1_MDC"),
+		MA35_MUX(0xe, "KPI_COL0")),
+	MA35_PIN(77, PF1, 0xa8, 0x4,
+		MA35_MUX(0x0, "GPF1"),
+		MA35_MUX(0x2, "UART2_nRTS"),
+		MA35_MUX(0x3, "UART1_TXD"),
+		MA35_MUX(0x6, "RGMII0_TXCLK"),
+		MA35_MUX(0x8, "RGMII1_MDIO"),
+		MA35_MUX(0x9, "RMII1_MDIO"),
+		MA35_MUX(0xe, "KPI_COL1")),
+	MA35_PIN(78, PF2, 0xa8, 0x8,
+		MA35_MUX(0x0, "GPF2"),
+		MA35_MUX(0x2, "UART2_RXD"),
+		MA35_MUX(0x6, "RGMII0_TXD2"),
+		MA35_MUX(0x8, "RGMII1_TXCTL"),
+		MA35_MUX(0x9, "RMII1_TXEN"),
+		MA35_MUX(0xe, "KPI_COL2")),
+	MA35_PIN(79, PF3, 0xa8, 0xc,
+		MA35_MUX(0x0, "GPF3"),
+		MA35_MUX(0x2, "UART2_TXD"),
+		MA35_MUX(0x6, "RGMII0_TXD3"),
+		MA35_MUX(0x8, "RGMII1_TXD0"),
+		MA35_MUX(0x9, "RMII1_TXD0"),
+		MA35_MUX(0xe, "KPI_COL3")),
+	MA35_PIN(80, PF4, 0xa8, 0x10,
+		MA35_MUX(0x0, "GPF4"),
+		MA35_MUX(0x2, "UART11_nCTS"),
+		MA35_MUX(0x3, "UART10_RXD"),
+		MA35_MUX(0x4, "I2S0_LRCK"),
+		MA35_MUX(0x5, "SPI1_SS0"),
+		MA35_MUX(0x8, "RGMII1_TXD1"),
+		MA35_MUX(0x9, "RMII1_TXD1"),
+		MA35_MUX(0xd, "CAN2_RXD"),
+		MA35_MUX(0xe, "KPI_ROW0")),
+	MA35_PIN(81, PF5, 0xa8, 0x14,
+		MA35_MUX(0x0, "GPF5"),
+		MA35_MUX(0x2, "UART11_nRTS"),
+		MA35_MUX(0x3, "UART10_TXD"),
+		MA35_MUX(0x4, "I2S0_BCLK"),
+		MA35_MUX(0x5, "SPI1_CLK"),
+		MA35_MUX(0x8, "RGMII1_RXCLK"),
+		MA35_MUX(0x9, "RMII1_REFCLK"),
+		MA35_MUX(0xd, "CAN2_TXD"),
+		MA35_MUX(0xe, "KPI_ROW1")),
+	MA35_PIN(82, PF6, 0xa8, 0x18,
+		MA35_MUX(0x0, "GPF6"),
+		MA35_MUX(0x2, "UART11_RXD"),
+		MA35_MUX(0x4, "I2S0_DI"),
+		MA35_MUX(0x5, "SPI1_MOSI"),
+		MA35_MUX(0x8, "RGMII1_RXCTL"),
+		MA35_MUX(0x9, "RMII1_CRSDV"),
+		MA35_MUX(0xa, "I2C4_SDA"),
+		MA35_MUX(0xd, "SC0_CLK"),
+		MA35_MUX(0xe, "KPI_ROW2")),
+	MA35_PIN(83, PF7, 0xa8, 0x1c,
+		MA35_MUX(0x0, "GPF7"),
+		MA35_MUX(0x2, "UART11_TXD"),
+		MA35_MUX(0x4, "I2S0_DO"),
+		MA35_MUX(0x5, "SPI1_MISO"),
+		MA35_MUX(0x8, "RGMII1_RXD0"),
+		MA35_MUX(0x9, "RMII1_RXD0"),
+		MA35_MUX(0xa, "I2C4_SCL"),
+		MA35_MUX(0xd, "SC0_DAT"),
+		MA35_MUX(0xe, "KPI_ROW3")),
+	MA35_PIN(84, PF8, 0xac, 0x0,
+		MA35_MUX(0x0, "GPF8"),
+		MA35_MUX(0x2, "UART13_RXD"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x5, "SPI0_SS0"),
+		MA35_MUX(0x8, "RGMII1_RXD1"),
+		MA35_MUX(0x9, "RMII1_RXD1"),
+		MA35_MUX(0xd, "SC0_RST"),
+		MA35_MUX(0xe, "KPI_COL4")),
+	MA35_PIN(85, PF9, 0xac, 0x4,
+		MA35_MUX(0x0, "GPF9"),
+		MA35_MUX(0x2, "UART13_TXD"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x5, "SPI0_SS1"),
+		MA35_MUX(0x8, "RGMII1_RXD2"),
+		MA35_MUX(0x9, "RMII1_RXERR"),
+		MA35_MUX(0xd, "SC0_PWR"),
+		MA35_MUX(0xe, "KPI_COL5")),
+	MA35_PIN(86, PF10, 0xac, 0x8,
+		MA35_MUX(0x0, "GPF10"),
+		MA35_MUX(0x2, "UART13_nCTS"),
+		MA35_MUX(0x5, "I2S0_LRCK"),
+		MA35_MUX(0x6, "SPI1_SS0"),
+		MA35_MUX(0x8, "RGMII1_RXD3"),
+		MA35_MUX(0x9, "SC0_CLK"),
+		MA35_MUX(0xe, "KPI_COL6")),
+	MA35_PIN(87, PF11, 0xac, 0xc,
+		MA35_MUX(0x0, "GPF11"),
+		MA35_MUX(0x2, "UART13_nRTS"),
+		MA35_MUX(0x5, "I2S0_BCLK"),
+		MA35_MUX(0x6, "SPI1_CLK"),
+		MA35_MUX(0x8, "RGMII1_TXCLK"),
+		MA35_MUX(0x9, "SC0_DAT"),
+		MA35_MUX(0xe, "KPI_COL7")),
+	MA35_PIN(88, PF12, 0xac, 0x10,
+		MA35_MUX(0x0, "GPF12"),
+		MA35_MUX(0x5, "I2S0_DI"),
+		MA35_MUX(0x6, "SPI1_MOSI"),
+		MA35_MUX(0x8, "RGMII1_TXD2"),
+		MA35_MUX(0x9, "SC0_RST"),
+		MA35_MUX(0xe, "KPI_ROW4")),
+	MA35_PIN(89, PF13, 0xac, 0x14,
+		MA35_MUX(0x0, "GPF13"),
+		MA35_MUX(0x5, "I2S0_DO"),
+		MA35_MUX(0x6, "SPI1_MISO"),
+		MA35_MUX(0x8, "RGMII1_TXD3"),
+		MA35_MUX(0x9, "SC0_PWR"),
+		MA35_MUX(0xe, "KPI_ROW5")),
+	MA35_PIN(90, PF14, 0xac, 0x18,
+		MA35_MUX(0x0, "GPF14"),
+		MA35_MUX(0x1, "EPWM2_BRAKE0"),
+		MA35_MUX(0x2, "EADC0_ST"),
+		MA35_MUX(0x3, "RGMII1_PPS"),
+		MA35_MUX(0x4, "RMII1_PPS"),
+		MA35_MUX(0x5, "SPI0_I2SMCLK"),
+		MA35_MUX(0x6, "SPI1_I2SMCLK"),
+		MA35_MUX(0x7, "CCAP1_SFIELD"),
+		MA35_MUX(0x8, "RGMII0_PPS"),
+		MA35_MUX(0x9, "RMII0_PPS"),
+		MA35_MUX(0xb, "TM0"),
+		MA35_MUX(0xc, "INT0"),
+		MA35_MUX(0xd, "SPI1_SS1"),
+		MA35_MUX(0xe, "QEI2_INDEX"),
+		MA35_MUX(0xf, "I2S0_MCLK")),
+	MA35_PIN(91, PF15, 0xac, 0x1c,
+		MA35_MUX(0x0, "GPF15"),
+		MA35_MUX(0x1, "HSUSB0_VBUSVLD")),
+	MA35_PIN(92, PG0, 0xb0, 0x0,
+		MA35_MUX(0x0, "GPG0"),
+		MA35_MUX(0x1, "EPWM0_CH0"),
+		MA35_MUX(0x2, "UART7_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "SPI0_SS0"),
+		MA35_MUX(0x6, "EADC0_ST"),
+		MA35_MUX(0x7, "EBI_AD15"),
+		MA35_MUX(0x9, "I2S1_MCLK"),
+		MA35_MUX(0xa, "QEI0_INDEX"),
+		MA35_MUX(0xb, "TM1"),
+		MA35_MUX(0xc, "CLKO"),
+		MA35_MUX(0xd, "INT0"),
+		MA35_MUX(0xf, "EBI_ADR15")),
+	MA35_PIN(93, PG1, 0xb0, 0x4,
+		MA35_MUX(0x0, "GPG1"),
+		MA35_MUX(0x1, "EPWM0_CH3"),
+		MA35_MUX(0x2, "UART9_nRTS"),
+		MA35_MUX(0x3, "UART6_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x5, "CAN2_TXD"),
+		MA35_MUX(0x7, "EBI_nCS0"),
+		MA35_MUX(0x9, "QEI0_B"),
+		MA35_MUX(0xb, "TM1_EXT"),
+		MA35_MUX(0xe, "RGMII1_PPS"),
+		MA35_MUX(0xf, "RMII1_PPS")),
+	MA35_PIN(94, PG2, 0xb0, 0x8,
+		MA35_MUX(0x0, "GPG2"),
+		MA35_MUX(0x1, "EPWM0_CH4"),
+		MA35_MUX(0x2, "UART9_RXD"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x5, "SPI0_SS1"),
+		MA35_MUX(0x7, "EBI_ADR16"),
+		MA35_MUX(0x8, "EBI_nCS2"),
+		MA35_MUX(0xa, "QEI0_A"),
+		MA35_MUX(0xb, "TM3"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(95, PG3, 0xb0, 0xc,
+		MA35_MUX(0x0, "GPG3"),
+		MA35_MUX(0x1, "EPWM0_CH5"),
+		MA35_MUX(0x2, "UART9_TXD"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x5, "SPI0_I2SMCLK"),
+		MA35_MUX(0x7, "EBI_ADR17"),
+		MA35_MUX(0x8, "EBI_nCS1"),
+		MA35_MUX(0x9, "EBI_MCLK"),
+		MA35_MUX(0xa, "QEI0_B"),
+		MA35_MUX(0xb, "TM3_EXT"),
+		MA35_MUX(0xc, "I2S1_MCLK")),
+	MA35_PIN(96, PG4, 0xb0, 0x10,
+		MA35_MUX(0x0, "GPG4"),
+		MA35_MUX(0x1, "EPWM1_CH0"),
+		MA35_MUX(0x2, "UART5_nCTS"),
+		MA35_MUX(0x3, "UART6_RXD"),
+		MA35_MUX(0x5, "SPI3_SS0"),
+		MA35_MUX(0x6, "QEI1_INDEX"),
+		MA35_MUX(0x7, "EBI_ADR18"),
+		MA35_MUX(0x8, "EBI_nCS0"),
+		MA35_MUX(0x9, "I2S1_DO"),
+		MA35_MUX(0xa, "SC1_CLK"),
+		MA35_MUX(0xb, "TM4"),
+		MA35_MUX(0xd, "INT2"),
+		MA35_MUX(0xe, "ECAP1_IC2")),
+	MA35_PIN(97, PG5, 0xb0, 0x14,
+		MA35_MUX(0x0, "GPG5"),
+		MA35_MUX(0x1, "EPWM1_CH1"),
+		MA35_MUX(0x2, "UART5_nRTS"),
+		MA35_MUX(0x3, "UART6_TXD"),
+		MA35_MUX(0x5, "SPI3_CLK"),
+		MA35_MUX(0x6, "ECAP0_IC0"),
+		MA35_MUX(0x7, "EBI_ADR19"),
+		MA35_MUX(0x8, "EBI_ALE"),
+		MA35_MUX(0x9, "I2S1_DI"),
+		MA35_MUX(0xa, "SC1_DAT"),
+		MA35_MUX(0xb, "TM4_EXT")),
+	MA35_PIN(98, PG6, 0xb0, 0x18,
+		MA35_MUX(0x0, "GPG6"),
+		MA35_MUX(0x1, "EPWM1_CH2"),
+		MA35_MUX(0x2, "UART5_RXD"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x5, "SPI3_MOSI"),
+		MA35_MUX(0x6, "ECAP0_IC1"),
+		MA35_MUX(0x7, "EBI_nRD"),
+		MA35_MUX(0x9, "I2S1_BCLK"),
+		MA35_MUX(0xa, "SC1_RST"),
+		MA35_MUX(0xb, "TM7"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(99, PG7, 0xb0, 0x1c,
+		MA35_MUX(0x0, "GPG7"),
+		MA35_MUX(0x1, "EPWM1_CH3"),
+		MA35_MUX(0x2, "UART5_TXD"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x5, "SPI3_MISO"),
+		MA35_MUX(0x6, "ECAP0_IC2"),
+		MA35_MUX(0x7, "EBI_nWR"),
+		MA35_MUX(0x9, "I2S1_LRCK"),
+		MA35_MUX(0xa, "SC1_PWR"),
+		MA35_MUX(0xb, "TM7_EXT")),
+	MA35_PIN(100, PG8, 0xb4, 0x0,
+		MA35_MUX(0x0, "GPG8"),
+		MA35_MUX(0x1, "EPWM1_CH4"),
+		MA35_MUX(0x2, "UART12_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "SPI2_SS0"),
+		MA35_MUX(0x6, "LCM_VSYNC"),
+		MA35_MUX(0x7, "I2C3_SDA"),
+		MA35_MUX(0xc, "EBI_AD7"),
+		MA35_MUX(0xd, "EBI_nCS0")),
+	MA35_PIN(101, PG9, 0xb4, 0x4,
+		MA35_MUX(0x0, "GPG9"),
+		MA35_MUX(0x1, "EPWM1_CH5"),
+		MA35_MUX(0x2, "UART12_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "SPI2_CLK"),
+		MA35_MUX(0x6, "LCM_HSYNC"),
+		MA35_MUX(0x7, "I2C3_SCL"),
+		MA35_MUX(0xc, "EBI_AD8"),
+		MA35_MUX(0xd, "EBI_nCS1")),
+	MA35_PIN(102, PG10, 0xb4, 0x8,
+		MA35_MUX(0x0, "GPG10"),
+		MA35_MUX(0x2, "UART12_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x5, "SPI2_MOSI"),
+		MA35_MUX(0x6, "LCM_CLK"),
+		MA35_MUX(0xc, "EBI_AD9"),
+		MA35_MUX(0xd, "EBI_nWRH")),
+	MA35_PIN(103, PG11, 0xb4, 0xc,
+		MA35_MUX(0x0, "GPG11"),
+		MA35_MUX(0x3, "JTAG_TDO"),
+		MA35_MUX(0x5, "I2S0_MCLK"),
+		MA35_MUX(0x6, "NAND_RDY1"),
+		MA35_MUX(0x7, "EBI_nWRH"),
+		MA35_MUX(0x8, "EBI_nCS1"),
+		MA35_MUX(0xa, "EBI_AD0")),
+	MA35_PIN(104, PG12, 0xb4, 0x10,
+		MA35_MUX(0x0, "GPG12"),
+		MA35_MUX(0x3, "JTAG_TCK/SW_CLK"),
+		MA35_MUX(0x5, "I2S0_LRCK"),
+		MA35_MUX(0x7, "EBI_nWRL"),
+		MA35_MUX(0xa, "EBI_AD1")),
+	MA35_PIN(105, PG13, 0xb4, 0x14,
+		MA35_MUX(0x0, "GPG13"),
+		MA35_MUX(0x3, "JTAG_TMS/SW_DIO"),
+		MA35_MUX(0x5, "I2S0_BCLK"),
+		MA35_MUX(0x7, "EBI_MCLK"),
+		MA35_MUX(0xa, "EBI_AD2")),
+	MA35_PIN(106, PG14, 0xb4, 0x18,
+		MA35_MUX(0x0, "GPG14"),
+		MA35_MUX(0x3, "JTAG_TDI"),
+		MA35_MUX(0x5, "I2S0_DI"),
+		MA35_MUX(0x6, "NAND_nCS1"),
+		MA35_MUX(0x7, "EBI_ALE"),
+		MA35_MUX(0xa, "EBI_AD3")),
+	MA35_PIN(107, PG15, 0xb4, 0x1c,
+		MA35_MUX(0x0, "GPG15"),
+		MA35_MUX(0x3, "JTAG_nTRST"),
+		MA35_MUX(0x5, "I2S0_DO"),
+		MA35_MUX(0x7, "EBI_nCS0"),
+		MA35_MUX(0xa, "EBI_AD4")),
+	MA35_PIN(108, PH0, 0xb8, 0x0,
+		MA35_MUX(0x0, "GPH0"),
+		MA35_MUX(0x2, "UART8_nCTS"),
+		MA35_MUX(0x3, "UART7_RXD"),
+		MA35_MUX(0x6, "LCM_DATA8")),
+	MA35_PIN(109, PH1, 0xb8, 0x4,
+		MA35_MUX(0x0, "GPH1"),
+		MA35_MUX(0x2, "UART8_nRTS"),
+		MA35_MUX(0x3, "UART7_TXD"),
+		MA35_MUX(0x6, "LCM_DATA9")),
+	MA35_PIN(110, PH2, 0xb8, 0x8,
+		MA35_MUX(0x0, "GPH2"),
+		MA35_MUX(0x2, "UART8_RXD"),
+		MA35_MUX(0x6, "LCM_DATA10")),
+	MA35_PIN(111, PH3, 0xb8, 0xc,
+		MA35_MUX(0x0, "GPH3"),
+		MA35_MUX(0x2, "UART8_TXD"),
+		MA35_MUX(0x6, "LCM_DATA11")),
+	MA35_PIN(112, PH4, 0xb8, 0x10,
+		MA35_MUX(0x0, "GPH4"),
+		MA35_MUX(0x2, "UART10_nCTS"),
+		MA35_MUX(0x3, "UART9_RXD"),
+		MA35_MUX(0x6, "LCM_DATA12")),
+	MA35_PIN(113, PH5, 0xb8, 0x14,
+		MA35_MUX(0x0, "GPH5"),
+		MA35_MUX(0x2, "UART10_nRTS"),
+		MA35_MUX(0x3, "UART9_TXD"),
+		MA35_MUX(0x6, "LCM_DATA13")),
+	MA35_PIN(114, PH6, 0xb8, 0x18,
+		MA35_MUX(0x0, "GPH6"),
+		MA35_MUX(0x2, "UART10_RXD"),
+		MA35_MUX(0x6, "LCM_DATA14")),
+	MA35_PIN(115, PH7, 0xb8, 0x1c,
+		MA35_MUX(0x0, "GPH7"),
+		MA35_MUX(0x2, "UART10_TXD"),
+		MA35_MUX(0x6, "LCM_DATA15")),
+	MA35_PIN(116, PH8, 0xbc, 0x0,
+		MA35_MUX(0x0, "GPH8"),
+		MA35_MUX(0x6, "TAMPER0")),
+	MA35_PIN(117, PH9, 0xbc, 0x4,
+		MA35_MUX(0x0, "GPH9"),
+		MA35_MUX(0x4, "CLK_32KOUT"),
+		MA35_MUX(0x6, "TAMPER1")),
+	MA35_PIN(118, PH12, 0xbc, 0x10,
+		MA35_MUX(0x0, "GPH12"),
+		MA35_MUX(0x2, "UART14_nCTS"),
+		MA35_MUX(0x3, "UART13_RXD"),
+		MA35_MUX(0x6, "LCM_DATA20")),
+	MA35_PIN(119, PH13, 0xbc, 0x14,
+		MA35_MUX(0x0, "GPH13"),
+		MA35_MUX(0x2, "UART14_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x6, "LCM_DATA21")),
+	MA35_PIN(120, PH14, 0xbc, 0x18,
+		MA35_MUX(0x0, "GPH14"),
+		MA35_MUX(0x2, "UART14_RXD"),
+		MA35_MUX(0x6, "LCM_DATA22")),
+	MA35_PIN(121, PH15, 0xbc, 0x1c,
+		MA35_MUX(0x0, "GPH15"),
+		MA35_MUX(0x2, "UART14_TXD"),
+		MA35_MUX(0x6, "LCM_DATA23")),
+	MA35_PIN(122, PI0, 0xc0, 0x0,
+		MA35_MUX(0x0, "GPI0"),
+		MA35_MUX(0x1, "EPWM0_CH0"),
+		MA35_MUX(0x2, "UART12_nCTS"),
+		MA35_MUX(0x3, "UART11_RXD"),
+		MA35_MUX(0x4, "I2C2_SDA"),
+		MA35_MUX(0x5, "SPI3_SS0"),
+		MA35_MUX(0x7, "SC0_nCD"),
+		MA35_MUX(0x8, "EBI_ADR0"),
+		MA35_MUX(0xb, "TM0"),
+		MA35_MUX(0xc, "ECAP1_IC0")),
+	MA35_PIN(123, PI1, 0xc0, 0x4,
+		MA35_MUX(0x0, "GPI1"),
+		MA35_MUX(0x1, "EPWM0_CH1"),
+		MA35_MUX(0x2, "UART12_nRTS"),
+		MA35_MUX(0x3, "UART11_TXD"),
+		MA35_MUX(0x4, "I2C2_SCL"),
+		MA35_MUX(0x5, "SPI3_CLK"),
+		MA35_MUX(0x7, "SC0_CLK"),
+		MA35_MUX(0x8, "EBI_ADR1"),
+		MA35_MUX(0xb, "TM0_EXT"),
+		MA35_MUX(0xc, "ECAP1_IC1")),
+	MA35_PIN(124, PI2, 0xc0, 0x8,
+		MA35_MUX(0x0, "GPI2"),
+		MA35_MUX(0x1, "EPWM0_CH2"),
+		MA35_MUX(0x2, "UART12_RXD"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x5, "SPI3_MOSI"),
+		MA35_MUX(0x7, "SC0_DAT"),
+		MA35_MUX(0x8, "EBI_ADR2"),
+		MA35_MUX(0xb, "TM1"),
+		MA35_MUX(0xc, "ECAP1_IC2")),
+	MA35_PIN(125, PI3, 0xc0, 0xc,
+		MA35_MUX(0x0, "GPI3"),
+		MA35_MUX(0x1, "EPWM0_CH3"),
+		MA35_MUX(0x2, "UART12_TXD"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x5, "SPI3_MISO"),
+		MA35_MUX(0x7, "SC0_RST"),
+		MA35_MUX(0x8, "EBI_ADR3"),
+		MA35_MUX(0xb, "TM1_EXT")),
+	MA35_PIN(126, PI4, 0xc0, 0x10,
+		MA35_MUX(0x0, "GPI4"),
+		MA35_MUX(0x1, "EPWM0_CH4"),
+		MA35_MUX(0x2, "UART14_nCTS"),
+		MA35_MUX(0x3, "UART13_RXD"),
+		MA35_MUX(0x4, "I2C3_SDA"),
+		MA35_MUX(0x5, "SPI2_SS1"),
+		MA35_MUX(0x6, "I2S1_LRCK"),
+		MA35_MUX(0x8, "EBI_ADR4"),
+		MA35_MUX(0xd, "INT0")),
+	MA35_PIN(127, PI5, 0xc0, 0x14,
+		MA35_MUX(0x0, "GPI5"),
+		MA35_MUX(0x1, "EPWM0_CH5"),
+		MA35_MUX(0x2, "UART14_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x4, "I2C3_SCL"),
+		MA35_MUX(0x6, "I2S1_BCLK"),
+		MA35_MUX(0x8, "EBI_ADR5"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(128, PI6, 0xc0, 0x18,
+		MA35_MUX(0x0, "GPI6"),
+		MA35_MUX(0x1, "EPWM0_BRAKE0"),
+		MA35_MUX(0x2, "UART14_RXD"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x6, "I2S1_DI"),
+		MA35_MUX(0x8, "EBI_ADR6"),
+		MA35_MUX(0xc, "QEI1_INDEX"),
+		MA35_MUX(0xd, "INT2")),
+	MA35_PIN(129, PI7, 0xc0, 0x1c,
+		MA35_MUX(0x0, "GPI7"),
+		MA35_MUX(0x1, "EPWM0_BRAKE1"),
+		MA35_MUX(0x2, "UART14_TXD"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x6, "I2S1_DO"),
+		MA35_MUX(0x8, "EBI_ADR7"),
+		MA35_MUX(0xc, "ECAP0_IC0"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(130, PI8, 0xc4, 0x0,
+		MA35_MUX(0x0, "GPI8"),
+		MA35_MUX(0x2, "UART4_nCTS"),
+		MA35_MUX(0x3, "UART3_RXD"),
+		MA35_MUX(0x6, "LCM_DATA0"),
+		MA35_MUX(0xc, "EBI_AD11")),
+	MA35_PIN(131, PI9, 0xc4, 0x4,
+		MA35_MUX(0x0, "GPI9"),
+		MA35_MUX(0x2, "UART4_nRTS"),
+		MA35_MUX(0x3, "UART3_TXD"),
+		MA35_MUX(0x6, "LCM_DATA1"),
+		MA35_MUX(0xc, "EBI_AD12")),
+	MA35_PIN(132, PI10, 0xc4, 0x8,
+		MA35_MUX(0x0, "GPI10"),
+		MA35_MUX(0x2, "UART4_RXD"),
+		MA35_MUX(0x6, "LCM_DATA2"),
+		MA35_MUX(0xc, "EBI_AD13")),
+	MA35_PIN(133, PI11, 0xC4, 0xc,
+		MA35_MUX(0x0, "GPI11"),
+		MA35_MUX(0x2, "UART4_TXD"),
+		MA35_MUX(0x6, "LCM_DATA3"),
+		MA35_MUX(0xc, "EBI_AD14")),
+	MA35_PIN(134, PI12, 0xc4, 0x10,
+		MA35_MUX(0x0, "GPI12"),
+		MA35_MUX(0x2, "UART6_nCTS"),
+		MA35_MUX(0x3, "UART5_RXD"),
+		MA35_MUX(0x6, "LCM_DATA4")),
+	MA35_PIN(135, PI13, 0xc4, 0x14,
+		MA35_MUX(0x0, "GPI13"),
+		MA35_MUX(0x2, "UART6_nRTS"),
+		MA35_MUX(0x3, "UART5_TXD"),
+		MA35_MUX(0x6, "LCM_DATA5")),
+	MA35_PIN(136, PI14, 0xc4, 0x18,
+		MA35_MUX(0x0, "GPI14"),
+		MA35_MUX(0x2, "UART6_RXD"),
+		MA35_MUX(0x6, "LCM_DATA6")),
+	MA35_PIN(137, PI15, 0xc4, 0x1c,
+		MA35_MUX(0x0, "GPI15"),
+		MA35_MUX(0x2, "UART6_TXD"),
+		MA35_MUX(0x6, "LCM_DATA7")),
+	MA35_PIN(138, PJ0, 0xc8, 0x0,
+		MA35_MUX(0x0, "GPJ0"),
+		MA35_MUX(0x1, "EPWM1_BRAKE0"),
+		MA35_MUX(0x2, "UART8_nCTS"),
+		MA35_MUX(0x3, "UART7_RXD"),
+		MA35_MUX(0x4, "I2C2_SDA"),
+		MA35_MUX(0x5, "SPI2_SS0"),
+		MA35_MUX(0x6, "eMMC1_DAT4"),
+		MA35_MUX(0x7, "I2S0_LRCK"),
+		MA35_MUX(0x8, "SC0_CLK"),
+		MA35_MUX(0x9, "EBI_AD11"),
+		MA35_MUX(0xa, "EBI_ADR16"),
+		MA35_MUX(0xb, "EBI_nCS0"),
+		MA35_MUX(0xc, "EBI_AD7")),
+	MA35_PIN(139, PJ1, 0xc8, 0x4,
+		MA35_MUX(0x0, "GPJ1"),
+		MA35_MUX(0x1, "EPWM1_BRAKE1"),
+		MA35_MUX(0x2, "UART8_nRTS"),
+		MA35_MUX(0x3, "UART7_TXD"),
+		MA35_MUX(0x4, "I2C2_SCL"),
+		MA35_MUX(0x5, "SPI2_CLK"),
+		MA35_MUX(0x6, "eMMC1_DAT5"),
+		MA35_MUX(0x7, "I2S0_BCLK"),
+		MA35_MUX(0x8, "SC0_DAT"),
+		MA35_MUX(0x9, "EBI_AD12"),
+		MA35_MUX(0xa, "EBI_ADR17"),
+		MA35_MUX(0xb, "EBI_nCS1"),
+		MA35_MUX(0xc, "EBI_AD8")),
+	MA35_PIN(140, PJ2, 0xc8, 0x8,
+		MA35_MUX(0x0, "GPJ2"),
+		MA35_MUX(0x1, "EPWM1_CH4"),
+		MA35_MUX(0x2, "UART8_RXD"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x5, "SPI2_MOSI"),
+		MA35_MUX(0x6, "eMMC1_DAT6"),
+		MA35_MUX(0x7, "I2S0_DI"),
+		MA35_MUX(0x8, "SC0_RST"),
+		MA35_MUX(0x9, "EBI_AD13"),
+		MA35_MUX(0xa, "EBI_ADR18"),
+		MA35_MUX(0xb, "EBI_nWRH"),
+		MA35_MUX(0xc, "EBI_AD9")),
+	MA35_PIN(141, PJ3, 0xc8, 0xc,
+		MA35_MUX(0x0, "GPJ3"),
+		MA35_MUX(0x1, "EPWM1_CH5"),
+		MA35_MUX(0x2, "UART8_TXD"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x5, "SPI2_MISO"),
+		MA35_MUX(0x6, "eMMC1_DAT7"),
+		MA35_MUX(0x7, "I2S0_DO"),
+		MA35_MUX(0x8, "SC0_PWR"),
+		MA35_MUX(0x9, "EBI_AD14"),
+		MA35_MUX(0xa, "EBI_ADR19"),
+		MA35_MUX(0xb, "EBI_nWRL"),
+		MA35_MUX(0xc, "EBI_AD10")),
+	MA35_PIN(142, PJ4, 0xc8, 0x10,
+		MA35_MUX(0x0, "GPJ4"),
+		MA35_MUX(0x4, "I2C3_SDA"),
+		MA35_MUX(0x6, "SD1_WP")),
+	MA35_PIN(143, PJ5, 0xc8, 0x14,
+		MA35_MUX(0x0, "GPJ5"),
+		MA35_MUX(0x4, "I2C3_SCL"),
+		MA35_MUX(0x6, "SD1_nCD")),
+	MA35_PIN(144, PJ6, 0xc8, 0x18,
+		MA35_MUX(0x0, "GPJ6"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x6, "SD1_CMD/eMMC1_CMD")),
+	MA35_PIN(145, PJ7, 0xc8, 0x1c,
+		MA35_MUX(0x0, "GPJ7"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x6, "SD1_CLK/eMMC1_CLK")),
+	MA35_PIN(146, PJ8, 0xcc, 0x0,
+		MA35_MUX(0x0, "GPJ8"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x6, "SD1_DAT0/eMMC1_DAT0")),
+	MA35_PIN(147, PJ9, 0xcc, 0x4,
+		MA35_MUX(0x0, "GPJ9"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x6, "SD1_DAT1/eMMC1_DAT1")),
+	MA35_PIN(148, PJ10, 0xcc, 0x8,
+		MA35_MUX(0x0, "GPJ10"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x6, "SD1_DAT2/eMMC1_DAT2")),
+	MA35_PIN(149, PJ11, 0xcc, 0xc,
+		MA35_MUX(0x0, "GPJ11"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x6, "SD1_DAT3/eMMC1_DAT3")),
+	MA35_PIN(150, PJ12, 0xcc, 0x10,
+		MA35_MUX(0x0, "GPJ12"),
+		MA35_MUX(0x1, "EPWM1_CH2"),
+		MA35_MUX(0x2, "UART2_nCTS"),
+		MA35_MUX(0x3, "UART1_RXD"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x5, "SPI3_SS0"),
+		MA35_MUX(0x7, "SC1_CLK"),
+		MA35_MUX(0x8, "EBI_ADR12"),
+		MA35_MUX(0xb, "TM2"),
+		MA35_MUX(0xc, "QEI0_INDEX")),
+	MA35_PIN(151, PJ13, 0xcc, 0x14,
+		MA35_MUX(0x0, "GPJ13"),
+		MA35_MUX(0x1, "EPWM1_CH3"),
+		MA35_MUX(0x2, "UART2_nRTS"),
+		MA35_MUX(0x3, "UART1_TXD"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x5, "SPI3_MOSI"),
+		MA35_MUX(0x7, "SC1_DAT"),
+		MA35_MUX(0x8, "EBI_ADR13"),
+		MA35_MUX(0xb, "TM2_EXT")),
+	MA35_PIN(152, PJ14, 0xcc, 0x18,
+		MA35_MUX(0x0, "GPJ14"),
+		MA35_MUX(0x1, "EPWM1_CH4"),
+		MA35_MUX(0x2, "UART2_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "SPI3_MISO"),
+		MA35_MUX(0x7, "SC1_RST"),
+		MA35_MUX(0x8, "EBI_ADR14"),
+		MA35_MUX(0xb, "TM3")),
+	MA35_PIN(153, PJ15, 0xcc, 0x1c,
+		MA35_MUX(0x0, "GPJ15"),
+		MA35_MUX(0x1, "EPWM1_CH5"),
+		MA35_MUX(0x2, "UART2_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "SPI3_CLK"),
+		MA35_MUX(0x6, "EADC0_ST"),
+		MA35_MUX(0x7, "SC1_PWR"),
+		MA35_MUX(0x8, "EBI_ADR15"),
+		MA35_MUX(0xb, "TM3_EXT"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(154, PK0, 0xd0, 0x0,
+		MA35_MUX(0x0, "GPK0"),
+		MA35_MUX(0x1, "EPWM0_SYNC_IN"),
+		MA35_MUX(0x2, "UART16_nCTS"),
+		MA35_MUX(0x3, "UART15_RXD"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x6, "I2S1_MCLK"),
+		MA35_MUX(0x8, "EBI_ADR8"),
+		MA35_MUX(0xb, "TM7"),
+		MA35_MUX(0xc, "ECAP0_IC1")),
+	MA35_PIN(155, PK1, 0xd0, 0x4,
+		MA35_MUX(0x0, "GPK1"),
+		MA35_MUX(0x1, "EPWM0_SYNC_OUT"),
+		MA35_MUX(0x2, "UART16_nRTS"),
+		MA35_MUX(0x3, "UART15_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x6, "EADC0_ST"),
+		MA35_MUX(0x8, "EBI_ADR9"),
+		MA35_MUX(0xb, "TM7_EXT"),
+		MA35_MUX(0xc, "ECAP0_IC2")),
+	MA35_PIN(156, PK2, 0xd0, 0x8,
+		MA35_MUX(0x0, "GPK2"),
+		MA35_MUX(0x1, "EPWM1_CH0"),
+		MA35_MUX(0x2, "UART16_RXD"),
+		MA35_MUX(0x3, "CAN2_RXD"),
+		MA35_MUX(0x5, "SPI3_I2SMCLK"),
+		MA35_MUX(0x7, "SC0_PWR"),
+		MA35_MUX(0x8, "EBI_ADR10"),
+		MA35_MUX(0xc, "QEI0_A")),
+	MA35_PIN(157, PK3, 0xd0, 0xc,
+		MA35_MUX(0x0, "GPK3"),
+		MA35_MUX(0x1, "EPWM1_CH1"),
+		MA35_MUX(0x2, "UART16_TXD"),
+		MA35_MUX(0x3, "CAN2_TXD"),
+		MA35_MUX(0x5, "SPI3_SS1"),
+		MA35_MUX(0x7, "SC1_nCD"),
+		MA35_MUX(0x8, "EBI_ADR11"),
+		MA35_MUX(0xc, "QEI0_B")),
+	MA35_PIN(158, PK4, 0xd0, 0x10,
+		MA35_MUX(0x0, "GPK4"),
+		MA35_MUX(0x2, "UART12_nCTS"),
+		MA35_MUX(0x3, "UART13_RXD"),
+		MA35_MUX(0x5, "SPI2_MISO"),
+		MA35_MUX(0x6, "LCM_DEN"),
+		MA35_MUX(0xc, "EBI_AD10"),
+		MA35_MUX(0xd, "EBI_nWRL")),
+	MA35_PIN(159, PK5, 0xd0, 0x14,
+		MA35_MUX(0x0, "GPK5"),
+		MA35_MUX(0x1, "EPWM1_CH1"),
+		MA35_MUX(0x2, "UART12_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x5, "SPI2_CLK"),
+		MA35_MUX(0x7, "I2S1_DI"),
+		MA35_MUX(0x8, "SC0_DAT"),
+		MA35_MUX(0x9, "EADC0_ST"),
+		MA35_MUX(0xb, "TM8_EXT"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(160, PK6, 0xd0, 0x18,
+		MA35_MUX(0x0, "GPK6"),
+		MA35_MUX(0x1, "EPWM1_CH2"),
+		MA35_MUX(0x2, "UART12_RXD"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x5, "SPI2_MOSI"),
+		MA35_MUX(0x7, "I2S1_BCLK"),
+		MA35_MUX(0x8, "SC0_RST"),
+		MA35_MUX(0xb, "TM6"),
+		MA35_MUX(0xd, "INT2")),
+	MA35_PIN(161, PK7, 0xd0, 0x1c,
+		MA35_MUX(0x0, "GPK7"),
+		MA35_MUX(0x1, "EPWM1_CH3"),
+		MA35_MUX(0x2, "UART12_TXD"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x5, "SPI2_MISO"),
+		MA35_MUX(0x7, "I2S1_LRCK"),
+		MA35_MUX(0x8, "SC0_PWR"),
+		MA35_MUX(0x9, "CLKO"),
+		MA35_MUX(0xb, "TM6_EXT"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(162, PK8, 0xd4, 0x0,
+		MA35_MUX(0x0, "GPK8"),
+		MA35_MUX(0x1, "EPWM1_CH0"),
+		MA35_MUX(0x4, "I2C3_SDA"),
+		MA35_MUX(0x5, "SPI3_CLK"),
+		MA35_MUX(0x7, "EADC0_ST"),
+		MA35_MUX(0x8, "EBI_AD15"),
+		MA35_MUX(0x9, "EBI_MCLK"),
+		MA35_MUX(0xa, "EBI_ADR15"),
+		MA35_MUX(0xb, "TM8"),
+		MA35_MUX(0xc, "QEI1_INDEX")),
+	MA35_PIN(163, PK9, 0xd4, 0x4,
+		MA35_MUX(0x0, "GPK9"),
+		MA35_MUX(0x4, "I2C3_SCL"),
+		MA35_MUX(0x6, "CCAP0_SCLK"),
+		MA35_MUX(0x8, "EBI_AD0"),
+		MA35_MUX(0xa, "EBI_ADR0")),
+	MA35_PIN(164, PK10, 0xd4, 0x8,
+		MA35_MUX(0x0, "GPK10"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x6, "CCAP0_PIXCLK"),
+		MA35_MUX(0x8, "EBI_AD1"),
+		MA35_MUX(0xa, "EBI_ADR1")),
+	MA35_PIN(165, PK11, 0xd4, 0xc,
+		MA35_MUX(0x0, "GPK11"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x6, "CCAP0_HSYNC"),
+		MA35_MUX(0x8, "EBI_AD2"),
+		MA35_MUX(0xa, "EBI_ADR2")),
+	MA35_PIN(166, PK12, 0xd4, 0x10,
+		MA35_MUX(0x0, "GPK12"),
+		MA35_MUX(0x1, "EPWM2_CH0"),
+		MA35_MUX(0x2, "UART1_nCTS"),
+		MA35_MUX(0x3, "UART13_RXD"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x5, "I2S0_LRCK"),
+		MA35_MUX(0x6, "SPI1_SS0"),
+		MA35_MUX(0x8, "SC0_CLK"),
+		MA35_MUX(0xb, "TM10"),
+		MA35_MUX(0xd, "INT2")),
+	MA35_PIN(167, PK13, 0xd4, 0x14,
+		MA35_MUX(0x0, "GPK13"),
+		MA35_MUX(0x1, "EPWM2_CH1"),
+		MA35_MUX(0x2, "UART1_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x5, "I2S0_BCLK"),
+		MA35_MUX(0x6, "SPI1_CLK"),
+		MA35_MUX(0x8, "SC0_DAT"),
+		MA35_MUX(0xb, "TM10_EXT")),
+	MA35_PIN(168, PK14, 0xd4, 0x18,
+		MA35_MUX(0x0, "GPK14"),
+		MA35_MUX(0x1, "EPWM2_CH2"),
+		MA35_MUX(0x2, "UART1_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "I2S0_DI"),
+		MA35_MUX(0x6, "SPI1_MOSI"),
+		MA35_MUX(0x8, "SC0_RST"),
+		MA35_MUX(0xa, "I2C5_SDA"),
+		MA35_MUX(0xb, "TM11"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(169, PK15, 0xd4, 0x1c,
+		MA35_MUX(0x0, "GPK15"),
+		MA35_MUX(0x1, "EPWM2_CH3"),
+		MA35_MUX(0x2, "UART1_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "I2S0_DO"),
+		MA35_MUX(0x6, "SPI1_MISO"),
+		MA35_MUX(0x8, "SC0_PWR"),
+		MA35_MUX(0xa, "I2C5_SCL"),
+		MA35_MUX(0xb, "TM11_EXT")),
+	MA35_PIN(170, PL0, 0xd8, 0x0,
+		MA35_MUX(0x0, "GPL0"),
+		MA35_MUX(0x1, "EPWM1_CH0"),
+		MA35_MUX(0x2, "UART11_nCTS"),
+		MA35_MUX(0x3, "UART10_RXD"),
+		MA35_MUX(0x4, "I2C3_SDA"),
+		MA35_MUX(0x5, "SPI2_MOSI"),
+		MA35_MUX(0x6, "QSPI1_MOSI1"),
+		MA35_MUX(0x7, "I2S0_LRCK"),
+		MA35_MUX(0x8, "EBI_AD11"),
+		MA35_MUX(0x9, "SC1_CLK"),
+		MA35_MUX(0xb, "TM5"),
+		MA35_MUX(0xc, "QEI1_A")),
+	MA35_PIN(171, PL1, 0xd8, 0x4,
+		MA35_MUX(0x0, "GPL1"),
+		MA35_MUX(0x1, "EPWM1_CH1"),
+		MA35_MUX(0x2, "UART11_nRTS"),
+		MA35_MUX(0x3, "UART10_TXD"),
+		MA35_MUX(0x4, "I2C3_SCL"),
+		MA35_MUX(0x5, "SPI2_MISO"),
+		MA35_MUX(0x6, "QSPI1_MISO1"),
+		MA35_MUX(0x7, "I2S0_BCLK"),
+		MA35_MUX(0x8, "EBI_AD12"),
+		MA35_MUX(0x9, "SC1_DAT"),
+		MA35_MUX(0xb, "TM5_EXT"),
+		MA35_MUX(0xc, "QEI1_B")),
+	MA35_PIN(172, PL2, 0xd8, 0x8,
+		MA35_MUX(0x0, "GPL2"),
+		MA35_MUX(0x1, "EPWM1_CH2"),
+		MA35_MUX(0x2, "UART11_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "SPI2_SS0"),
+		MA35_MUX(0x6, "QSPI1_SS1"),
+		MA35_MUX(0x7, "I2S0_DI"),
+		MA35_MUX(0x8, "EBI_AD13"),
+		MA35_MUX(0x9, "SC1_RST"),
+		MA35_MUX(0xb, "TM7"),
+		MA35_MUX(0xc, "QEI1_INDEX")),
+	MA35_PIN(173, PL3, 0xd8, 0xc,
+		MA35_MUX(0x0, "GPL3"),
+		MA35_MUX(0x1, "EPWM1_CH3"),
+		MA35_MUX(0x2, "UART11_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "SPI2_CLK"),
+		MA35_MUX(0x6, "QSPI1_CLK"),
+		MA35_MUX(0x7, "I2S0_DO"),
+		MA35_MUX(0x8, "EBI_AD14"),
+		MA35_MUX(0x9, "SC1_PWR"),
+		MA35_MUX(0xb, "TM7_EXT"),
+		MA35_MUX(0xc, "ECAP0_IC0")),
+	MA35_PIN(174, PL4, 0xd8, 0x10,
+		MA35_MUX(0x0, "GPL4"),
+		MA35_MUX(0x1, "EPWM1_CH4"),
+		MA35_MUX(0x2, "UART2_nCTS"),
+		MA35_MUX(0x3, "UART1_RXD"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x5, "SPI3_MOSI"),
+		MA35_MUX(0x6, "QSPI1_MOSI0"),
+		MA35_MUX(0x7, "I2S0_MCLK"),
+		MA35_MUX(0x8, "EBI_nRD"),
+		MA35_MUX(0x9, "SC1_nCD"),
+		MA35_MUX(0xb, "TM9"),
+		MA35_MUX(0xc, "ECAP0_IC1")),
+	MA35_PIN(175, PL5, 0xd8, 0x14,
+		MA35_MUX(0x0, "GPL5"),
+		MA35_MUX(0x1, "EPWM1_CH5"),
+		MA35_MUX(0x2, "UART2_nRTS"),
+		MA35_MUX(0x3, "UART1_TXD"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x5, "SPI3_MISO"),
+		MA35_MUX(0x6, "QSPI1_MISO0"),
+		MA35_MUX(0x7, "I2S1_MCLK"),
+		MA35_MUX(0x8, "EBI_nWR"),
+		MA35_MUX(0x9, "SC0_nCD"),
+		MA35_MUX(0xb, "TM9_EXT"),
+		MA35_MUX(0xc, "ECAP0_IC2")),
+	MA35_PIN(176, PL6, 0xd8, 0x18,
+		MA35_MUX(0x0, "GPL6"),
+		MA35_MUX(0x1, "EPWM0_CH0"),
+		MA35_MUX(0x2, "UART2_RXD"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x6, "QSPI1_MOSI1"),
+		MA35_MUX(0x7, "TRACE_CLK"),
+		MA35_MUX(0x8, "EBI_AD5"),
+		MA35_MUX(0xb, "TM3"),
+		MA35_MUX(0xc, "ECAP1_IC0"),
+		MA35_MUX(0xd, "INT0")),
+	MA35_PIN(177, PL7, 0xd8, 0x1c,
+		MA35_MUX(0x0, "GPL7"),
+		MA35_MUX(0x1, "EPWM0_CH1"),
+		MA35_MUX(0x2, "UART2_TXD"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x6, "QSPI1_MISO1"),
+		MA35_MUX(0x8, "EBI_AD6"),
+		MA35_MUX(0xb, "TM3_EXT"),
+		MA35_MUX(0xc, "ECAP1_IC1"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(178, PL8, 0xdc, 0x0,
+		MA35_MUX(0x0, "GPL8"),
+		MA35_MUX(0x1, "EPWM0_CH2"),
+		MA35_MUX(0x2, "UART14_nCTS"),
+		MA35_MUX(0x3, "UART13_RXD"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x5, "SPI3_SS0"),
+		MA35_MUX(0x6, "EPWM0_CH4"),
+		MA35_MUX(0x7, "I2S1_LRCK"),
+		MA35_MUX(0x8, "EBI_AD7"),
+		MA35_MUX(0x9, "SC0_CLK"),
+		MA35_MUX(0xb, "TM4"),
+		MA35_MUX(0xc, "ECAP1_IC2"),
+		MA35_MUX(0xd, "INT2")),
+	MA35_PIN(179, PL9, 0xdc, 0x4,
+		MA35_MUX(0x0, "GPL9"),
+		MA35_MUX(0x1, "EPWM0_CH3"),
+		MA35_MUX(0x2, "UART14_nRTS"),
+		MA35_MUX(0x3, "UART13_TXD"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x5, "SPI3_CLK"),
+		MA35_MUX(0x6, "EPWM1_CH4"),
+		MA35_MUX(0x7, "I2S1_BCLK"),
+		MA35_MUX(0x8, "EBI_AD8"),
+		MA35_MUX(0x9, "SC0_DAT"),
+		MA35_MUX(0xb, "TM4_EXT"),
+		MA35_MUX(0xc, "QEI0_A"),
+		MA35_MUX(0xd, "INT3")),
+	MA35_PIN(180, PL10, 0xdc, 0x8,
+		MA35_MUX(0x0, "GPL10"),
+		MA35_MUX(0x1, "EPWM0_CH4"),
+		MA35_MUX(0x2, "UART14_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "SPI3_MOSI"),
+		MA35_MUX(0x6, "EPWM0_CH5"),
+		MA35_MUX(0x7, "I2S1_DI"),
+		MA35_MUX(0x8, "EBI_AD9"),
+		MA35_MUX(0x9, "SC0_RST"),
+		MA35_MUX(0xb, "EBI_nWRH"),
+		MA35_MUX(0xc, "QEI0_B")),
+	MA35_PIN(181, PL11, 0xdc, 0xc,
+		MA35_MUX(0x0, "GPL11"),
+		MA35_MUX(0x1, "EPWM0_CH5"),
+		MA35_MUX(0x2, "UART14_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "SPI3_MISO"),
+		MA35_MUX(0x6, "EPWM1_CH5"),
+		MA35_MUX(0x7, "I2S1_DO"),
+		MA35_MUX(0x8, "EBI_AD10"),
+		MA35_MUX(0x9, "SC0_PWR"),
+		MA35_MUX(0xb, "EBI_nWRL"),
+		MA35_MUX(0xc, "QEI0_INDEX")),
+	MA35_PIN(182, PL12, 0xdc, 0x10,
+		MA35_MUX(0x0, "GPL12"),
+		MA35_MUX(0x1, "EPWM0_SYNC_IN"),
+		MA35_MUX(0x2, "UART7_nCTS"),
+		MA35_MUX(0x3, "ECAP1_IC0"),
+		MA35_MUX(0x4, "UART14_RXD"),
+		MA35_MUX(0x5, "SPI0_SS0"),
+		MA35_MUX(0x6, "I2S1_LRCK"),
+		MA35_MUX(0x7, "SC1_CLK"),
+		MA35_MUX(0x8, "EBI_AD0"),
+		MA35_MUX(0x9, "HSUSBH_PWREN"),
+		MA35_MUX(0xa, "I2C2_SDA"),
+		MA35_MUX(0xb, "TM0"),
+		MA35_MUX(0xc, "EPWM0_CH2"),
+		MA35_MUX(0xd, "EBI_AD11"),
+		MA35_MUX(0xe, "RGMII0_PPS"),
+		MA35_MUX(0xf, "RMII0_PPS")),
+	MA35_PIN(183, PL13, 0xdc, 0x14,
+		MA35_MUX(0x0, "GPL13"),
+		MA35_MUX(0x1, "EPWM0_SYNC_OUT"),
+		MA35_MUX(0x2, "UART7_nRTS"),
+		MA35_MUX(0x3, "ECAP1_IC1"),
+		MA35_MUX(0x4, "UART14_TXD"),
+		MA35_MUX(0x5, "SPI0_CLK"),
+		MA35_MUX(0x6, "I2S1_BCLK"),
+		MA35_MUX(0x7, "SC1_DAT"),
+		MA35_MUX(0x8, "EBI_AD1"),
+		MA35_MUX(0x9, "HSUSBH_OVC"),
+		MA35_MUX(0xa, "I2C2_SCL"),
+		MA35_MUX(0xb, "TM0_EXT"),
+		MA35_MUX(0xc, "EPWM0_CH3"),
+		MA35_MUX(0xd, "EBI_AD12"),
+		MA35_MUX(0xe, "RGMII1_PPS"),
+		MA35_MUX(0xf, "RMII1_PPS")),
+	MA35_PIN(184, PL14, 0xdc, 0x18,
+		MA35_MUX(0x0, "GPL14"),
+		MA35_MUX(0x1, "EPWM0_CH2"),
+		MA35_MUX(0x2, "UART7_RXD"),
+		MA35_MUX(0x4, "CAN1_RXD"),
+		MA35_MUX(0x5, "SPI0_MOSI"),
+		MA35_MUX(0x6, "I2S1_DI"),
+		MA35_MUX(0x7, "SC1_RST"),
+		MA35_MUX(0x8, "EBI_AD2"),
+		MA35_MUX(0xb, "TM2"),
+		MA35_MUX(0xc, "INT0"),
+		MA35_MUX(0xd, "EBI_AD13")),
+	MA35_PIN(185, PL15, 0xdc, 0x1c,
+		MA35_MUX(0x0, "GPL15"),
+		MA35_MUX(0x1, "EPWM0_CH1"),
+		MA35_MUX(0x2, "UART7_TXD"),
+		MA35_MUX(0x3, "TRACE_CLK"),
+		MA35_MUX(0x4, "CAN1_TXD"),
+		MA35_MUX(0x5, "SPI0_MISO"),
+		MA35_MUX(0x6, "I2S1_DO"),
+		MA35_MUX(0x7, "SC1_PWR"),
+		MA35_MUX(0x8, "EBI_AD3"),
+		MA35_MUX(0xb, "TM2_EXT"),
+		MA35_MUX(0xc, "INT2"),
+		MA35_MUX(0xd, "EBI_AD14")),
+	MA35_PIN(186, PM0, 0xe0, 0x0,
+		MA35_MUX(0x0, "GPM0"),
+		MA35_MUX(0x4, "I2C4_SDA"),
+		MA35_MUX(0x6, "CCAP0_VSYNC"),
+		MA35_MUX(0x8, "EBI_AD3"),
+		MA35_MUX(0xa, "EBI_ADR3")),
+	MA35_PIN(187, PM1, 0xe0, 0x4,
+		MA35_MUX(0x0, "GPM1"),
+		MA35_MUX(0x4, "I2C4_SCL"),
+		MA35_MUX(0x5, "SPI3_I2SMCLK"),
+		MA35_MUX(0x6, "CCAP0_SFIELD"),
+		MA35_MUX(0x8, "EBI_AD4"),
+		MA35_MUX(0xa, "EBI_ADR4")),
+	MA35_PIN(188, PM2, 0xe0, 0x8,
+		MA35_MUX(0x0, "GPM2"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x6, "CCAP0_DATA0"),
+		MA35_MUX(0x8, "EBI_AD5"),
+		MA35_MUX(0xa, "EBI_ADR5")),
+	MA35_PIN(189, PM3, 0xe0, 0xc,
+		MA35_MUX(0x0, "GPM3"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x6, "CCAP0_DATA1"),
+		MA35_MUX(0x8, "EBI_AD6"),
+		MA35_MUX(0xa, "EBI_ADR6")),
+	MA35_PIN(190, PM4, 0xe0, 0x10,
+		MA35_MUX(0x0, "GPM4"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x6, "CCAP0_DATA2"),
+		MA35_MUX(0x8, "EBI_AD7"),
+		MA35_MUX(0xa, "EBI_ADR7")),
+	MA35_PIN(191, PM5, 0xe0, 0x14,
+		MA35_MUX(0x0, "GPM5"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x6, "CCAP0_DATA3"),
+		MA35_MUX(0x8, "EBI_AD8"),
+		MA35_MUX(0xa, "EBI_ADR8")),
+	MA35_PIN(192, PM6, 0xe0, 0x18,
+		MA35_MUX(0x0, "GPM6"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x6, "CCAP0_DATA4"),
+		MA35_MUX(0x8, "EBI_AD9"),
+		MA35_MUX(0xa, "EBI_ADR9")),
+	MA35_PIN(193, PM7, 0xe0, 0x1c,
+		MA35_MUX(0x0, "GPM7"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x6, "CCAP0_DATA5"),
+		MA35_MUX(0x8, "EBI_AD10"),
+		MA35_MUX(0xa, "EBI_ADR10")),
+	MA35_PIN(194, PM8, 0xe4, 0x0,
+		MA35_MUX(0x0, "GPM8"),
+		MA35_MUX(0x4, "I2C0_SDA"),
+		MA35_MUX(0x6, "CCAP0_DATA6"),
+		MA35_MUX(0x8, "EBI_AD11"),
+		MA35_MUX(0xa, "EBI_ADR11")),
+	MA35_PIN(195, PM9, 0xe4, 0x4,
+		MA35_MUX(0x0, "GPM9"),
+		MA35_MUX(0x4, "I2C0_SCL"),
+		MA35_MUX(0x6, "CCAP0_DATA7"),
+		MA35_MUX(0x8, "EBI_AD12"),
+		MA35_MUX(0xa, "EBI_ADR12")),
+	MA35_PIN(196, PM10, 0xe4, 0x8,
+		MA35_MUX(0x0, "GPM10"),
+		MA35_MUX(0x1, "EPWM1_CH2"),
+		MA35_MUX(0x3, "CAN2_RXD"),
+		MA35_MUX(0x5, "SPI3_SS0"),
+		MA35_MUX(0x6, "CCAP0_DATA8"),
+		MA35_MUX(0x7, "SPI2_I2SMCLK"),
+		MA35_MUX(0x8, "EBI_AD13"),
+		MA35_MUX(0xa, "EBI_ADR13")),
+	MA35_PIN(197, PM11, 0xe4, 0xc,
+		MA35_MUX(0x0, "GPM11"),
+		MA35_MUX(0x1, "EPWM1_CH3"),
+		MA35_MUX(0x3, "CAN2_TXD"),
+		MA35_MUX(0x5, "SPI3_SS1"),
+		MA35_MUX(0x6, "CCAP0_DATA9"),
+		MA35_MUX(0x7, "SPI2_SS1"),
+		MA35_MUX(0x8, "EBI_AD14"),
+		MA35_MUX(0xa, "EBI_ADR14")),
+	MA35_PIN(198, PM12, 0xe4, 0x10,
+		MA35_MUX(0x0, "GPM12"),
+		MA35_MUX(0x1, "EPWM1_CH4"),
+		MA35_MUX(0x2, "UART10_nCTS"),
+		MA35_MUX(0x3, "TRACE_DATA0"),
+		MA35_MUX(0x4, "UART11_RXD"),
+		MA35_MUX(0x5, "I2C2_SDA"),
+		MA35_MUX(0x7, "SC1_nCD"),
+		MA35_MUX(0x8, "EBI_AD8"),
+		MA35_MUX(0x9, "I2S1_MCLK"),
+		MA35_MUX(0xb, "TM8")),
+	MA35_PIN(199, PM13, 0xe4, 0x14,
+		MA35_MUX(0x0, "GPM13"),
+		MA35_MUX(0x1, "EPWM1_CH5"),
+		MA35_MUX(0x2, "UART10_nRTS"),
+		MA35_MUX(0x3, "TRACE_DATA1"),
+		MA35_MUX(0x4, "UART11_TXD"),
+		MA35_MUX(0x5, "I2C2_SCL"),
+		MA35_MUX(0x8, "EBI_AD9"),
+		MA35_MUX(0x9, "ECAP1_IC0"),
+		MA35_MUX(0xb, "TM8_EXT")),
+	MA35_PIN(200, PM14, 0xe4, 0x18,
+		MA35_MUX(0x0, "GPM14"),
+		MA35_MUX(0x1, "EPWM1_BRAKE0"),
+		MA35_MUX(0x2, "UART10_RXD"),
+		MA35_MUX(0x3, "TRACE_DATA2"),
+		MA35_MUX(0x4, "CAN2_RXD"),
+		MA35_MUX(0x6, "I2C3_SDA"),
+		MA35_MUX(0x8, "EBI_AD10"),
+		MA35_MUX(0x9, "ECAP1_IC1"),
+		MA35_MUX(0xb, "TM10"),
+		MA35_MUX(0xd, "INT1")),
+	MA35_PIN(201, PM15, 0xe4, 0x1c,
+		MA35_MUX(0x0, "GPM15"),
+		MA35_MUX(0x1, "EPWM1_BRAKE1"),
+		MA35_MUX(0x2, "UART10_TXD"),
+		MA35_MUX(0x3, "TRACE_DATA3"),
+		MA35_MUX(0x4, "CAN2_TXD"),
+		MA35_MUX(0x6, "I2C3_SCL"),
+		MA35_MUX(0x8, "EBI_AD11"),
+		MA35_MUX(0x9, "ECAP1_IC2"),
+		MA35_MUX(0xb, "TM10_EXT"),
+		MA35_MUX(0xd, "INT2")),
+	MA35_PIN(202, PN0, 0xe8, 0x0,
+		MA35_MUX(0x0, "GPN0"),
+		MA35_MUX(0x4, "I2C2_SDA"),
+		MA35_MUX(0x6, "CCAP1_DATA0")),
+	MA35_PIN(203, PN1, 0xe8, 0x4,
+		MA35_MUX(0x0, "GPN1"),
+		MA35_MUX(0x4, "I2C2_SCL"),
+		MA35_MUX(0x6, "CCAP1_DATA1")),
+	MA35_PIN(204, PN2, 0xe8, 0x8,
+		MA35_MUX(0x0, "GPN2"),
+		MA35_MUX(0x3, "CAN0_RXD"),
+		MA35_MUX(0x6, "CCAP1_DATA2")),
+	MA35_PIN(205, PN3, 0xe8, 0xc,
+		MA35_MUX(0x0, "GPN3"),
+		MA35_MUX(0x3, "CAN0_TXD"),
+		MA35_MUX(0x6, "CCAP1_DATA3")),
+	MA35_PIN(206, PN4, 0xe8, 0x10,
+		MA35_MUX(0x0, "GPN4"),
+		MA35_MUX(0x4, "I2C1_SDA"),
+		MA35_MUX(0x6, "CCAP1_DATA4")),
+	MA35_PIN(207, PN5, 0xe8, 0x14,
+		MA35_MUX(0x0, "GPN5"),
+		MA35_MUX(0x4, "I2C1_SCL"),
+		MA35_MUX(0x6, "CCAP1_DATA5")),
+	MA35_PIN(208, PN6, 0xe8, 0x18,
+		MA35_MUX(0x0, "GPN6"),
+		MA35_MUX(0x3, "CAN1_RXD"),
+		MA35_MUX(0x6, "CCAP1_DATA6")),
+	MA35_PIN(209, PN7, 0xe8, 0x1c,
+		MA35_MUX(0x0, "GPN7"),
+		MA35_MUX(0x3, "CAN1_TXD"),
+		MA35_MUX(0x6, "CCAP1_DATA7")),
+	MA35_PIN(210, PN10, 0xec, 0x8,
+		MA35_MUX(0x0, "GPN10"),
+		MA35_MUX(0x3, "CAN2_RXD"),
+		MA35_MUX(0x6, "CCAP1_SCLK")),
+	MA35_PIN(211, PN11, 0xec, 0xc,
+		MA35_MUX(0x0, "GPN11"),
+		MA35_MUX(0x3, "CAN2_TXD"),
+		MA35_MUX(0x6, "CCAP1_PIXCLK")),
+	MA35_PIN(212, PN12, 0xec, 0x10,
+		MA35_MUX(0x0, "GPN12"),
+		MA35_MUX(0x2, "UART6_nCTS"),
+		MA35_MUX(0x3, "UART12_RXD"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x6, "CCAP1_HSYNC")),
+	MA35_PIN(213, PN13, 0xec, 0x14,
+		MA35_MUX(0x0, "GPN13"),
+		MA35_MUX(0x2, "UART6_nRTS"),
+		MA35_MUX(0x3, "UART12_TXD"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x6, "CCAP1_VSYNC")),
+	MA35_PIN(214, PN14, 0xec, 0x18,
+		MA35_MUX(0x0, "GPN14"),
+		MA35_MUX(0x2, "UART6_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x5, "SPI1_SS1"),
+		MA35_MUX(0x6, "CCAP1_SFIELD"),
+		MA35_MUX(0x7, "SPI1_I2SMCLK")),
+	MA35_PIN(215, PN15, 0xec, 0x1c,
+		MA35_MUX(0x0, "GPN15"),
+		MA35_MUX(0x1, "EPWM2_CH4"),
+		MA35_MUX(0x2, "UART6_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x5, "I2S0_MCLK"),
+		MA35_MUX(0x6, "SPI1_SS1"),
+		MA35_MUX(0x7, "SPI1_I2SMCLK"),
+		MA35_MUX(0x8, "SC0_nCD"),
+		MA35_MUX(0x9, "EADC0_ST"),
+		MA35_MUX(0xa, "CLKO"),
+		MA35_MUX(0xb, "TM6")),
+	MA35_PIN(216, PN8, 0xec, 0x0,
+		MA35_MUX(0x0, "GPN8"),
+		MA35_MUX(0x1, "EPWM2_CH4"),
+		MA35_MUX(0x4, "I2C0_SDA"),
+		MA35_MUX(0x5, "SPI2_I2SMCLK"),
+		MA35_MUX(0x6, "CCAP1_DATA8")),
+	MA35_PIN(217, PN9, 0xec, 0x4,
+		MA35_MUX(0x0, "GPN9"),
+		MA35_MUX(0x1, "EPWM2_CH5"),
+		MA35_MUX(0x4, "I2C0_SCL"),
+		MA35_MUX(0x5, "SPI1_I2SMCLK"),
+		MA35_MUX(0x6, "CCAP1_DATA9")),
+	MA35_PIN(218, PN10, 0xec, 0x8,
+		MA35_MUX(0x0, "GPN10"),
+		MA35_MUX(0x3, "CAN2_RXD"),
+		MA35_MUX(0x4, "USBHL2_DM"),
+		MA35_MUX(0x6, "CCAP1_SCLK")),
+	MA35_PIN(219, PN11, 0xec, 0xc,
+		MA35_MUX(0x0, "GPN11"),
+		MA35_MUX(0x3, "CAN2_TXD"),
+		MA35_MUX(0x4, "USBHL2_DP"),
+		MA35_MUX(0x6, "CCAP1_PIXCLK")),
+	MA35_PIN(220, PN12, 0xec, 0x10,
+		MA35_MUX(0x0, "GPN12"),
+		MA35_MUX(0x2, "UART6_nCTS"),
+		MA35_MUX(0x3, "UART12_RXD"),
+		MA35_MUX(0x4, "I2C5_SDA"),
+		MA35_MUX(0x6, "CCAP1_HSYNC")),
+	MA35_PIN(221, PN13, 0xec, 0x14,
+		MA35_MUX(0x0, "GPN13"),
+		MA35_MUX(0x2, "UART6_nRTS"),
+		MA35_MUX(0x3, "UART12_TXD"),
+		MA35_MUX(0x4, "I2C5_SCL"),
+		MA35_MUX(0x6, "CCAP1_VSYNC")),
+	MA35_PIN(222, PN14, 0xec, 0x18,
+		MA35_MUX(0x0, "GPN14"),
+		MA35_MUX(0x2, "UART6_RXD"),
+		MA35_MUX(0x3, "CAN3_RXD"),
+		MA35_MUX(0x4, "USBHL3_DM"),
+		MA35_MUX(0x5, "SPI1_SS1"),
+		MA35_MUX(0x6, "CCAP1_SFIELD"),
+		MA35_MUX(0x7, "SPI1_I2SMCLK")),
+	MA35_PIN(223, PN15, 0xec, 0x1c,
+		MA35_MUX(0x0, "GPN15"),
+		MA35_MUX(0x1, "EPWM2_CH4"),
+		MA35_MUX(0x2, "UART6_TXD"),
+		MA35_MUX(0x3, "CAN3_TXD"),
+		MA35_MUX(0x4, "USBHL3_DP"),
+		MA35_MUX(0x5, "I2S0_MCLK"),
+		MA35_MUX(0x6, "SPI1_SS1"),
+		MA35_MUX(0x7, "SPI1_I2SMCLK"),
+		MA35_MUX(0x8, "SC0_nCD"),
+		MA35_MUX(0x9, "EADC0_ST"),
+		MA35_MUX(0xa, "CLKO"),
+		MA35_MUX(0xb, "TM6")),
+};
+
+static int ma35d1_get_pin_num(int offset, int shift)
+{
+	return (offset - 0x80) * 2 + shift / 4;
+}
+
+static struct ma35_pinctrl_soc_info ma35d1_pinctrl_info = {
+	.pins = ma35d1_pins,
+	.npins = ARRAY_SIZE(ma35d1_pins),
+	.get_pin_num = ma35d1_get_pin_num,
+};
+
+static const struct dev_pm_ops ma35d1_pinctrl_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(ma35_pinctrl_suspend, ma35_pinctrl_resume)
+};
+
+static int ma35d1_pinctrl_probe(struct platform_device *pdev)
+{
+	return ma35_pinctrl_probe(pdev, &ma35d1_pinctrl_info);
+}
+
+static const struct of_device_id ma35d1_pinctrl_of_match[] = {
+	{ .compatible = "nuvoton,ma35d1-pinctrl", },
+	{ },
+};
+
+static struct platform_driver ma35d1_pinctrl_driver = {
+	.probe = ma35d1_pinctrl_probe,
+	.driver = {
+		.name = "ma35d1-pinctrl",
+		.pm = &ma35d1_pinctrl_pm_ops,
+		.of_match_table = ma35d1_pinctrl_of_match,
+	},
+};
+
+static int __init ma35d1_pinctrl_init(void)
+{
+	return platform_driver_register(&ma35d1_pinctrl_driver);
+}
+arch_initcall(ma35d1_pinctrl_init);
+
+MODULE_AUTHOR("schung at nuvoton.com");
+MODULE_DESCRIPTION("Nuvoton MA35D1 pinctrl driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From kuninori.morimoto.gx at renesas.com  Mon Feb 19 17:16:02 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Tue, 20 Feb 2024 01:16:02 +0000
Subject: [PATCH v2 resend 1/4] gpu: drm: replace of_graph_get_next_endpoint()
In-Reply-To: <874je4kkdn.wl-kuninori.morimoto.gx@renesas.com>
References: <874je4kkdn.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <8734tokka5.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
---
 drivers/gpu/drm/drm_of.c                              | 4 +++-
 drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c | 2 +-
 drivers/gpu/drm/tiny/arcpgu.c                         | 2 +-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 177b600895d3..b6b2cade69ae 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -504,6 +504,8 @@ EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep);
  * Gets parent DSI bus for a DSI device controlled through a bus other
  * than MIPI-DCS (SPI, I2C, etc.) using the Device Tree.
  *
+ * This function assumes that the device's port at 0 is the DSI input.
+ *
  * Returns pointer to mipi_dsi_host if successful, -EINVAL if the
  * request is unsupported, -EPROBE_DEFER if the DSI host is found but
  * not available, or -ENODEV otherwise.
@@ -516,7 +518,7 @@ struct mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev)
 	/*
 	 * Get first endpoint child from device.
 	 */
-	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!endpoint)
 		return ERR_PTR(-ENODEV);
 
diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
index 4618c892cdd6..e10e469aa7a6 100644
--- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
+++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
@@ -400,7 +400,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c)
 	rpi_touchscreen_i2c_write(ts, REG_POWERON, 0);
 
 	/* Look up the DSI host.  It needs to probe before we do. */
-	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!endpoint)
 		return -ENODEV;
 
diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c
index 4f8f3172379e..8c29b719ea62 100644
--- a/drivers/gpu/drm/tiny/arcpgu.c
+++ b/drivers/gpu/drm/tiny/arcpgu.c
@@ -288,7 +288,7 @@ static int arcpgu_load(struct arcpgu_drm_private *arcpgu)
 	 * There is only one output port inside each device. It is linked with
 	 * encoder endpoint.
 	 */
-	endpoint_node = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
+	endpoint_node = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 0, -1);
 	if (endpoint_node) {
 		encoder_node = of_graph_get_remote_port_parent(endpoint_node);
 		of_node_put(endpoint_node);
-- 
2.25.1



From kuninori.morimoto.gx at renesas.com  Mon Feb 19 17:16:21 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Tue, 20 Feb 2024 01:16:21 +0000
Subject: [PATCH v2 resend 2/4] media: i2c: replace of_graph_get_next_endpoint()
In-Reply-To: <874je4kkdn.wl-kuninori.morimoto.gx@renesas.com>
References: <874je4kkdn.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <871q98kk9m.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Link: https://lore.kernel.org/r/9d1e99b0-892d-4a72-a9b3-886b8ed094b0 at xs4all.nl
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 drivers/media/i2c/adv7343.c              | 2 +-
 drivers/media/i2c/adv7604.c              | 4 ++--
 drivers/media/i2c/mt9p031.c              | 2 +-
 drivers/media/i2c/mt9v032.c              | 2 +-
 drivers/media/i2c/ov2659.c               | 2 +-
 drivers/media/i2c/ov5645.c               | 2 +-
 drivers/media/i2c/ov5647.c               | 2 +-
 drivers/media/i2c/s5c73m3/s5c73m3-core.c | 2 +-
 drivers/media/i2c/s5k5baf.c              | 2 +-
 drivers/media/i2c/tc358743.c             | 2 +-
 drivers/media/i2c/tda1997x.c             | 2 +-
 drivers/media/i2c/tvp514x.c              | 2 +-
 drivers/media/i2c/tvp7002.c              | 2 +-
 13 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index ff21cd4744d3..4fbe4e18570e 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -403,7 +403,7 @@ adv7343_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 810fa8826f30..319db3e847c4 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -3204,8 +3204,8 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
 
 	np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
 
-	/* Parse the endpoint. */
-	endpoint = of_graph_get_next_endpoint(np, NULL);
+	/* FIXME: Parse the endpoint. */
+	endpoint = of_graph_get_endpoint_by_regs(np, -1, -1);
 	if (!endpoint)
 		return -EINVAL;
 
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 596200d0248c..f4b481212356 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -1078,7 +1078,7 @@ mt9p031_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 3ca76eeae7ff..e9f5c6647f97 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -1006,7 +1006,7 @@ mt9v032_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!np)
 		return NULL;
 
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 1d0ef72a6403..d1653d7431d0 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1388,7 +1388,7 @@ ov2659_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!endpoint)
 		return NULL;
 
diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
index a26ac11c989d..9daf06ffedf4 100644
--- a/drivers/media/i2c/ov5645.c
+++ b/drivers/media/i2c/ov5645.c
@@ -1056,7 +1056,7 @@ static int ov5645_probe(struct i2c_client *client)
 	ov5645->i2c_client = client;
 	ov5645->dev = dev;
 
-	endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!endpoint) {
 		dev_err(dev, "endpoint node not found\n");
 		return -EINVAL;
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 96c0fd4ff5ab..7e1ecdf2485f 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -1363,7 +1363,7 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
 	struct device_node *ep;
 	int ret;
 
-	ep = of_graph_get_next_endpoint(np, NULL);
+	ep = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!ep)
 		return -EINVAL;
 
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index af8d01f78c32..cf6be509af33 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1568,7 +1568,7 @@ static int s5c73m3_get_dt_data(struct s5c73m3 *state)
 				     "failed to request gpio S5C73M3_RST\n");
 	gpiod_set_consumer_name(state->reset, "S5C73M3_RST");
 
-	node_ep = of_graph_get_next_endpoint(node, NULL);
+	node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!node_ep) {
 		dev_warn(dev, "no endpoint defined for node: %pOF\n", node);
 		return 0;
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index de079d2c9282..6b11039c3579 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1849,7 +1849,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
 			 state->mclk_frequency);
 	}
 
-	node_ep = of_graph_get_next_endpoint(node, NULL);
+	node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!node_ep) {
 		dev_err(dev, "no endpoint defined at node %pOF\n", node);
 		return -EINVAL;
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 2785935da497..872e802cdfbe 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1895,7 +1895,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
 		return dev_err_probe(dev, PTR_ERR(refclk),
 				     "failed to get refclk\n");
 
-	ep = of_graph_get_next_endpoint(dev->of_node, NULL);
+	ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!ep) {
 		dev_err(dev, "missing endpoint node\n");
 		return -EINVAL;
diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
index 1ea703a9909f..8e4a0718c4b6 100644
--- a/drivers/media/i2c/tda1997x.c
+++ b/drivers/media/i2c/tda1997x.c
@@ -2310,7 +2310,7 @@ static int tda1997x_parse_dt(struct tda1997x_state *state)
 	pdata->vidout_sel_de = DE_FREF_SEL_DE_VHREF;
 
 	np = state->client->dev.of_node;
-	ep = of_graph_get_next_endpoint(np, NULL);
+	ep = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!ep)
 		return -EINVAL;
 
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index 5a561e5bf659..f9c9c80c33ac 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -987,7 +987,7 @@ tvp514x_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!endpoint)
 		return NULL;
 
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 30831b4b56d6..6a04ffae5343 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -893,7 +893,7 @@ tvp7002_get_pdata(struct i2c_client *client)
 	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
 		return client->dev.platform_data;
 
-	endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+	endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
 	if (!endpoint)
 		return NULL;
 
-- 
2.25.1



From kuninori.morimoto.gx at renesas.com  Mon Feb 19 17:16:36 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Tue, 20 Feb 2024 01:16:36 +0000
Subject: [PATCH v2 resend 3/4] media: platform: replace of_graph_get_next_endpoint()
In-Reply-To: <874je4kkdn.wl-kuninori.morimoto.gx@renesas.com>
References: <874je4kkdn.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87zfvwj5or.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 drivers/media/platform/atmel/atmel-isi.c              | 4 ++--
 drivers/media/platform/intel/pxa_camera.c             | 2 +-
 drivers/media/platform/samsung/exynos4-is/fimc-is.c   | 2 +-
 drivers/media/platform/samsung/exynos4-is/mipi-csis.c | 3 ++-
 drivers/media/platform/st/stm32/stm32-dcmi.c          | 4 ++--
 drivers/media/platform/ti/davinci/vpif.c              | 3 +--
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index f8450a8ccda6..c1108df72dd5 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -834,7 +834,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
 	isi->pdata.full_mode = 1;
 	isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
 
-	np = of_graph_get_next_endpoint(np, NULL);
+	np = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!np) {
 		dev_err(&pdev->dev, "Could not find the endpoint\n");
 		return -EINVAL;
@@ -1158,7 +1158,7 @@ static int isi_graph_init(struct atmel_isi *isi)
 	struct device_node *ep;
 	int ret;
 
-	ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
+	ep = of_graph_get_endpoint_by_regs(isi->dev->of_node, 0, -1);
 	if (!ep)
 		return -EINVAL;
 
diff --git a/drivers/media/platform/intel/pxa_camera.c b/drivers/media/platform/intel/pxa_camera.c
index 59b89e421dc2..d904952bf00e 100644
--- a/drivers/media/platform/intel/pxa_camera.c
+++ b/drivers/media/platform/intel/pxa_camera.c
@@ -2207,7 +2207,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
 		pcdev->mclk = mclk_rate;
 	}
 
-	np = of_graph_get_next_endpoint(np, NULL);
+	np = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!np) {
 		dev_err(dev, "could not find endpoint\n");
 		return -EINVAL;
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
index a08c87ef6e2d..39aab667910d 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
@@ -175,7 +175,7 @@ static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,
 		return -EINVAL;
 	}
 
-	ep = of_graph_get_next_endpoint(node, NULL);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return -ENXIO;
 
diff --git a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
index aae8a8b2c0f4..4b9b20ba3504 100644
--- a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
@@ -727,7 +727,8 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
 				 &state->max_num_lanes))
 		return -EINVAL;
 
-	node = of_graph_get_next_endpoint(node, NULL);
+	/* from port at 3 or port at 4 */
+	node = of_graph_get_endpoint_by_regs(node, -1, -1);
 	if (!node) {
 		dev_err(&pdev->dev, "No port node at %pOF\n",
 				pdev->dev.of_node);
diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c
index c4610e305546..ff3331af9406 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmi.c
@@ -1855,7 +1855,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi)
 	struct device_node *ep;
 	int ret;
 
-	ep = of_graph_get_next_endpoint(dcmi->dev->of_node, NULL);
+	ep = of_graph_get_endpoint_by_regs(dcmi->dev->of_node, 0, -1);
 	if (!ep) {
 		dev_err(dcmi->dev, "Failed to get next endpoint\n");
 		return -EINVAL;
@@ -1907,7 +1907,7 @@ static int dcmi_probe(struct platform_device *pdev)
 				     "Could not get reset control\n");
 
 	/* Get bus characteristics from devicetree */
-	np = of_graph_get_next_endpoint(np, NULL);
+	np = of_graph_get_endpoint_by_regs(np, 0, -1);
 	if (!np) {
 		dev_err(&pdev->dev, "Could not find the endpoint\n");
 		return -ENODEV;
diff --git a/drivers/media/platform/ti/davinci/vpif.c b/drivers/media/platform/ti/davinci/vpif.c
index 63cdfed37bc9..f4e1fa76bf37 100644
--- a/drivers/media/platform/ti/davinci/vpif.c
+++ b/drivers/media/platform/ti/davinci/vpif.c
@@ -465,8 +465,7 @@ static int vpif_probe(struct platform_device *pdev)
 	 * so their devices need to be registered manually here
 	 * for their legacy platform_drivers to work.
 	 */
-	endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
-					      endpoint);
+	endpoint = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 0, -1);
 	if (!endpoint)
 		return 0;
 	of_node_put(endpoint);
-- 
2.25.1



From kuninori.morimoto.gx at renesas.com  Mon Feb 19 17:16:52 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Tue, 20 Feb 2024 01:16:52 +0000
Subject: [PATCH v2 resend 4/4] video: fbdev: replace of_graph_get_next_endpoint()
In-Reply-To: <874je4kkdn.wl-kuninori.morimoto.gx@renesas.com>
References: <874je4kkdn.wl-kuninori.morimoto.gx@renesas.com>
Message-ID: <87y1bgj5oc.wl-kuninori.morimoto.gx@renesas.com>

>From DT point of view, in general, drivers should be asking for a
specific port number because their function is fixed in the binding.

of_graph_get_next_endpoint() doesn't match to this concept.

Simply replace

	- of_graph_get_next_endpoint(xxx, NULL);
	+ of_graph_get_endpoint_by_regs(xxx, 0, -1);

Link: https://lore.kernel.org/r/20240202174941.GA310089-robh at kernel.org
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 drivers/video/fbdev/omap2/omapfb/dss/dsi.c    |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/dss-of.c | 20 +------------------
 drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c  |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c  |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/venc.c   |  3 ++-
 drivers/video/fbdev/pxafb.c                   |  2 +-
 include/video/omapfb_dss.h                    |  3 ---
 7 files changed, 10 insertions(+), 27 deletions(-)

diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
index b7eb17a16ec4..1f13bcf73da5 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
@@ -28,6 +28,7 @@
 #include <linux/debugfs.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/of_platform.h>
 #include <linux/component.h>
 
@@ -5079,7 +5080,7 @@ static int dsi_probe_of(struct platform_device *pdev)
 	struct device_node *ep;
 	struct omap_dsi_pin_config pin_cfg;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
index 0282d4eef139..14965a3fd05b 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
@@ -130,24 +130,6 @@ static struct device_node *omapdss_of_get_remote_port(const struct device_node *
 	return np;
 }
 
-struct device_node *
-omapdss_of_get_first_endpoint(const struct device_node *parent)
-{
-	struct device_node *port, *ep;
-
-	port = omapdss_of_get_next_port(parent, NULL);
-
-	if (!port)
-		return NULL;
-
-	ep = omapdss_of_get_next_endpoint(port, NULL);
-
-	of_node_put(port);
-
-	return ep;
-}
-EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint);
-
 struct omap_dss_device *
 omapdss_of_find_source_for_first_ep(struct device_node *node)
 {
@@ -155,7 +137,7 @@ omapdss_of_find_source_for_first_ep(struct device_node *node)
 	struct device_node *src_port;
 	struct omap_dss_device *src;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return ERR_PTR(-EINVAL);
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
index f05b4e35a842..8f407ec134dc 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
@@ -20,6 +20,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/regulator/consumer.h>
 #include <linux/component.h>
 #include <video/omapfb_dss.h>
@@ -529,7 +530,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
 	struct device_node *ep;
 	int r;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
index 03292945b1d4..4ad219f522b9 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
@@ -25,6 +25,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/regulator/consumer.h>
 #include <linux/component.h>
 #include <video/omapfb_dss.h>
@@ -561,7 +562,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
 	struct device_node *ep;
 	int r;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/venc.c b/drivers/video/fbdev/omap2/omapfb/dss/venc.c
index c9d40e28a06f..0bd80d3b8f1b 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/venc.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/venc.c
@@ -24,6 +24,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/component.h>
 
 #include <video/omapfb_dss.h>
@@ -764,7 +765,7 @@ static int venc_probe_of(struct platform_device *pdev)
 	u32 channels;
 	int r;
 
-	ep = omapdss_of_get_first_endpoint(node);
+	ep = of_graph_get_endpoint_by_regs(node, 0, -1);
 	if (!ep)
 		return 0;
 
diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
index fa943612c4e2..2ef56fa28aff 100644
--- a/drivers/video/fbdev/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
@@ -2171,7 +2171,7 @@ static int of_get_pxafb_mode_info(struct device *dev,
 	u32 bus_width;
 	int ret, i;
 
-	np = of_graph_get_next_endpoint(dev->of_node, NULL);
+	np = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 	if (!np) {
 		dev_err(dev, "could not find endpoint\n");
 		return -EINVAL;
diff --git a/include/video/omapfb_dss.h b/include/video/omapfb_dss.h
index e8eaac2cb7b8..a8c0c3eeeb5b 100644
--- a/include/video/omapfb_dss.h
+++ b/include/video/omapfb_dss.h
@@ -819,9 +819,6 @@ struct device_node *
 omapdss_of_get_next_endpoint(const struct device_node *parent,
 			     struct device_node *prev);
 
-struct device_node *
-omapdss_of_get_first_endpoint(const struct device_node *parent);
-
 struct omap_dss_device *
 omapdss_of_find_source_for_first_ep(struct device_node *node);
 #else
-- 
2.25.1



From zhi.mao at mediatek.com  Mon Feb 19 17:25:38 2024
From: zhi.mao at mediatek.com (Zhi Mao)
Date: Tue, 20 Feb 2024 09:25:38 +0800
Subject: [PATCH v5 0/2] media: i2c: Add support for GC08A3 sensor 
Message-ID: <20240220012540.10607-1-zhi.mao@mediatek.com>

This series adds YAML DT binding and V4L2 sub-device driver for Galaxycore's
GC08A3 8-megapixel 10-bit RAW CMOS 1/4" sensor, with an MIPI CSI-2 image data
interface and the I2C control bus.

The driver is implemented with V4L2 framework.
 - Async registered as a V4L2 sub-device.
 - As the first component of camera system including Seninf, ISP pipeline.
 - A media entity that provides one source pad in common.
 - Used in camera features on ChromeOS application.

Also this driver supports following features:
 - manual exposure and analog gain control support
 - vertical blanking control support
 - test pattern support
 - media controller support
 - runtime PM support
 - support resolution: 3264x2448 at 30fps, 1920x1080 at 60fps

Previous versions of this patch-set can be found here:
v4: https://lore.kernel.org/linux-media/20240204061538.2105-1-zhi.mao at mediatek.com/
v3: https://lore.kernel.org/linux-media/20240109022715.30278-1-zhi.mao at mediatek.com/
v2: https://lore.kernel.org/linux-media/20231207052016.25954-1-zhi.mao at mediatek.com/
v1: https://lore.kernel.org/linux-media/20231123115104.32094-1-zhi.mao at mediatek.com/

This series is based on linux-next, tag: next-20240219
Changes in v5:
- gc08a3 sensor driver?
-- sort the header files alphabetically in driver code
-- refine the register define and some macros, fix some typo 
-- drop variable??clinet/streaming? in struct gc08a3
-- refine "ret" flow in function:gc08a3_test_pattern()
-- drop the gc08a3_link_freq_config structure
-- rename some function and variable with a "gc08a3_" prefix
-- refine function:gc08a3_identify_module()/gc08a3_power_on()/gc08a3_power_off()/gc08a3_update_pad_format()
-- use stored crop rectangle in funcion:gc08a3_get_selectoin()
-- use cci_update_bits() in function:gc08a3_set_ctrl_hflip()/gc08a3_set_ctrl_vflip()
-- put the HFLIP and VFLIP controls in a cluster to make it efficiently set in an atomic operation
-- use "fwnode_graph_get_endpoint_by_id" in function: gc08a3_parse_fwnode()
-- remove function:gc08a3_enum_frame_interval()
-- enable autosuspend in function:probe()

Thanks

Zhi Mao (2):
  media: dt-bindings: i2c: add GalaxyCore GC08A3 image sensor
  media: i2c: Add GC08A3 image sensor driver

 .../bindings/media/i2c/galaxycore,gc08a3.yaml |  112 ++
 drivers/media/i2c/Kconfig                     |   10 +
 drivers/media/i2c/Makefile                    |    1 +
 drivers/media/i2c/gc08a3.c                    | 1335 +++++++++++++++++
 4 files changed, 1458 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml
 create mode 100644 drivers/media/i2c/gc08a3.c

-- 
2.25.1





From zhi.mao at mediatek.com  Mon Feb 19 17:25:39 2024
From: zhi.mao at mediatek.com (Zhi Mao)
Date: Tue, 20 Feb 2024 09:25:39 +0800
Subject: [PATCH v5 1/2] media: dt-bindings: i2c: add GalaxyCore GC08A3 image sensor
In-Reply-To: <20240220012540.10607-1-zhi.mao@mediatek.com>
References: <20240220012540.10607-1-zhi.mao@mediatek.com>
Message-ID: <20240220012540.10607-2-zhi.mao@mediatek.com>

Add YAML device tree binding for GC08A3 CMOS image sensor,
and the relevant MAINTAINERS entries.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
---
 .../bindings/media/i2c/galaxycore,gc08a3.yaml | 112 ++++++++++++++++++
 1 file changed, 112 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml

diff --git a/Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml
new file mode 100644
index 000000000000..8c09e8c121e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc08a3.yaml
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (c) 2023 MediaTek Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/galaxycore,gc08a3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GalaxyCore gc08a3 1/4" 8M Pixel MIPI CSI-2 sensor
+
+maintainers:
+  - Zhi Mao <zhi.mao at mediatek.com>
+
+description:
+  The gc08a3 is a raw image sensor with an MIPI CSI-2 image data
+  interface and CCI (I2C compatible) control bus. The output format
+  is raw Bayer.
+
+properties:
+  compatible:
+    const: galaxycore,gc08a3
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  dovdd-supply: true
+
+  avdd-supply: true
+
+  dvdd-supply: true
+
+  reset-gpios:
+    description: Reference to the GPIO connected to the RESETB pin.
+    maxItems: 1
+
+  port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    additionalProperties: false
+    description:
+      Output port node, single endpoint describing the CSI-2 transmitter.
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          data-lanes:
+            oneOf:
+              - items:
+                  - const: 1
+                  - const: 2
+                  - const: 3
+                  - const: 4
+              - items:
+                  - const: 1
+                  - const: 2
+
+          link-frequencies: true
+
+        required:
+          - data-lanes
+          - link-frequencies
+
+    required:
+      - endpoint
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - dovdd-supply
+  - avdd-supply
+  - dvdd-supply
+  - reset-gpios
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        sensor at 31 {
+            compatible = "galaxycore,gc08a3";
+            reg = <0x31>;
+
+            clocks = <&gc08a3_clk>;
+
+            reset-gpios = <&pio 19 GPIO_ACTIVE_HIGH>;
+
+            avdd-supply = <&gc08a3_avdd>;
+            dovdd-supply = <&gc08a3_dovdd>;
+            dvdd-supply = <&gc08a3_dvdd>;
+
+            port {
+                sensor_out: endpoint {
+                    data-lanes = <1 2 3 4>;
+                    link-frequencies = /bits/ 64 <336000000 207000000>;
+                    remote-endpoint = <&seninf_csi_port_0_in>;
+                };
+            };
+        };
+    };
+
+...
-- 
2.25.1



From kuninori.morimoto.gx at renesas.com  Mon Feb 19 17:13:56 2024
From: kuninori.morimoto.gx at renesas.com (Kuninori Morimoto)
Date: Tue, 20 Feb 2024 01:13:56 +0000
Subject: [PATCH v2 resend 0/4] of: replace of_graph_get_next_endpoint()
Message-ID: <874je4kkdn.wl-kuninori.morimoto.gx@renesas.com>


Hi Rob

This is resend v2 of replace of_graph_get_next_endpoint()

We should get rid of or minimize of_graph_get_next_endpoint() in
its current form. In general, drivers should be asking for a specific 
port number because their function is fixed in the binding.

	https://lore.kernel.org/r/20240131184347.GA1906672-robh at kernel.org

This patch-set replace of_graph_get_next_endpoint() by
of_graph_get_endpoint_by_regs(). There are still next_endpoint()
after this patch-set, but it will be replaced by
for_each_endpoint_of_node() in next patch-set (A)

[*] this patch-set
[o] done

	[o] tidyup of_graph_get_endpoint_count()
	[*] replace endpoint func - use endpoint_by_regs()
(A)	[ ] replace endpoint func - use for_each()
	[ ] rename endpoint func to device_endpoint
	[ ] add new port function
	[ ] add new endpont function
	[ ] remove of_graph_get_next_device_endpoint()

v1 -> v2
	- add Reviewed-by from Launrent
	- use by_regs(xx, -1, -1) for some devices
	- add extra explain for drm_of_get_dsi_bus()
	- add FIXME and Link on adv7604.c
	- based on latest of branch

Kuninori Morimoto (4):
  gpu: drm: replace of_graph_get_next_endpoint()
  media: i2c: replace of_graph_get_next_endpoint()
  media: platform: replace of_graph_get_next_endpoint()
  video: fbdev: replace of_graph_get_next_endpoint()

 drivers/gpu/drm/drm_of.c                      |  4 +++-
 .../drm/panel/panel-raspberrypi-touchscreen.c |  2 +-
 drivers/gpu/drm/tiny/arcpgu.c                 |  2 +-
 drivers/media/i2c/adv7343.c                   |  2 +-
 drivers/media/i2c/adv7604.c                   |  4 ++--
 drivers/media/i2c/mt9p031.c                   |  2 +-
 drivers/media/i2c/mt9v032.c                   |  2 +-
 drivers/media/i2c/ov2659.c                    |  2 +-
 drivers/media/i2c/ov5645.c                    |  2 +-
 drivers/media/i2c/ov5647.c                    |  2 +-
 drivers/media/i2c/s5c73m3/s5c73m3-core.c      |  2 +-
 drivers/media/i2c/s5k5baf.c                   |  2 +-
 drivers/media/i2c/tc358743.c                  |  2 +-
 drivers/media/i2c/tda1997x.c                  |  2 +-
 drivers/media/i2c/tvp514x.c                   |  2 +-
 drivers/media/i2c/tvp7002.c                   |  2 +-
 drivers/media/platform/atmel/atmel-isi.c      |  4 ++--
 drivers/media/platform/intel/pxa_camera.c     |  2 +-
 .../platform/samsung/exynos4-is/fimc-is.c     |  2 +-
 .../platform/samsung/exynos4-is/mipi-csis.c   |  3 ++-
 drivers/media/platform/st/stm32/stm32-dcmi.c  |  4 ++--
 drivers/media/platform/ti/davinci/vpif.c      |  3 +--
 drivers/video/fbdev/omap2/omapfb/dss/dsi.c    |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/dss-of.c | 20 +------------------
 drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c  |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c  |  3 ++-
 drivers/video/fbdev/omap2/omapfb/dss/venc.c   |  3 ++-
 drivers/video/fbdev/pxafb.c                   |  2 +-
 include/video/omapfb_dss.h                    |  3 ---
 29 files changed, 38 insertions(+), 53 deletions(-)

-- 
2.25.1



From ck.hu at mediatek.com  Mon Feb 19 17:37:26 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 20 Feb 2024 01:37:26 +0000
Subject: [PATCH v2 1/3] Subject: [PATCH] drm/mediatek/dp: Add tee client
 application for HDCP feature
In-Reply-To: <20240205055055.25340-2-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
	 <20240205055055.25340-2-mac.shen@mediatek.com>
Message-ID: <bae975ea502ba7b6cb0fa73f7c8d461f4c9b963f.camel@mediatek.com>

Hi, Mac:

On Mon, 2024-02-05 at 13:50 +0800, mac.shen wrote:
> Add tee client application which will be used for
> HDCP 1.x and 2.x authentication in DisplayPort.
> 
> Changes in v2:
> - remove ca folder, and change file name with lower case
> - refine the tci_t structure to make the data to tee can
>   through this structure
> - remove aux and regs from mtk_hdcp_info structure
> - remove some definitions, and use the definitions in
>   include/drm/drm_hdcp.h
> - remove useless code
> per suggestion from the previous thread:
> https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
> 9218a545c46.camel at mediatek.com/
> 
> Signed-off-by: mac.shen <mac.shen at mediatek.com>
> ---

[snip]

> +
> +#define RET_COMPARE_PASS 0
> +#define RET_COMPARE_FAIL 1
> +#define RET_NEW_DEVICE 2
> +#define RET_STORED_DEVICE 3

These definition are useless, so drop them.

Regards,
CK

> +

From zhi.mao at mediatek.com  Mon Feb 19 17:25:40 2024
From: zhi.mao at mediatek.com (Zhi Mao)
Date: Tue, 20 Feb 2024 09:25:40 +0800
Subject: [PATCH v5 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <20240220012540.10607-1-zhi.mao@mediatek.com>
References: <20240220012540.10607-1-zhi.mao@mediatek.com>
Message-ID: <20240220012540.10607-3-zhi.mao@mediatek.com>

Add a V4L2 sub-device driver for Galaxycore GC08A3 image sensor.

Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
---
 drivers/media/i2c/Kconfig  |   10 +
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/gc08a3.c | 1335 ++++++++++++++++++++++++++++++++++++
 3 files changed, 1346 insertions(+)
 create mode 100644 drivers/media/i2c/gc08a3.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 56f276b920ab..e4da68835683 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -70,6 +70,16 @@ config VIDEO_GC0308
 	  To compile this driver as a module, choose M here: the
 	  module will be called gc0308.
 
+config VIDEO_GC08A3
+	tristate "GalaxyCore gc08a3 sensor support"
+	select V4L2_CCI_I2C
+	help
+	  This is a Video4Linux2 sensor driver for the GalaxyCore gc08a3
+	  camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gc08a3.
+
 config VIDEO_GC2145
 	select V4L2_CCI_I2C
 	tristate "GalaxyCore GC2145 sensor support"
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index dfbe6448b549..b82e99ca7578 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
 obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
 obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
 obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
+obj-$(CONFIG_VIDEO_GC08A3) += gc08a3.o
 obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
 obj-$(CONFIG_VIDEO_HI556) += hi556.o
 obj-$(CONFIG_VIDEO_HI846) += hi846.o
diff --git a/drivers/media/i2c/gc08a3.c b/drivers/media/i2c/gc08a3.c
new file mode 100644
index 000000000000..76f19ab55b38
--- /dev/null
+++ b/drivers/media/i2c/gc08a3.c
@@ -0,0 +1,1335 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * gc08a3.c - gc08a3 sensor driver
+ *
+ * Copyright 2023 MediaTek
+ *
+ * Zhi Mao <zhi.mao at mediatek.com>
+ */
+#include <asm/unaligned.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <media/media-entity.h>
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#define GC08A3_REG_TEST_PATTERN_EN CCI_REG8(0x008c)
+#define GC08A3_REG_TEST_PATTERN_IDX CCI_REG8(0x008d)
+#define GC08A3_TEST_PATTERN_EN 0x01
+
+#define GC08A3_STREAMING_REG CCI_REG8(0x0100)
+
+#define GC08A3_FLIP_REG CCI_REG8(0x0101)
+#define GC08A3_FLIP_H_MASK BIT(0)
+#define GC08A3_FLIP_V_MASK BIT(1)
+
+#define GC08A3_EXP_REG CCI_REG16(0x0202)
+#define GC08A3_EXP_MARGIN 16
+#define GC08A3_EXP_MIN 4
+#define GC08A3_EXP_STEP 1
+
+#define GC08A3_AGAIN_REG CCI_REG16(0x0204)
+#define GC08A3_AGAIN_MIN 1024
+#define GC08A3_AGAIN_MAX (1024 * 16)
+#define GC08A3_AGAIN_STEP 1
+
+#define GC08A3_FRAME_LENGTH_REG CCI_REG16(0x0340)
+#define GC08A3_VTS_MAX 0xfff0
+
+#define GC08A3_REG_CHIP_ID CCI_REG16(0x03f0)
+#define GC08A3_CHIP_ID 0x08a3
+
+#define GC08A3_NATIVE_WIDTH 3264
+#define GC08A3_NATIVE_HEIGHT 2448
+
+#define GC08A3_DEFAULT_CLK_FREQ 24000000
+#define GC08A3_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
+#define GC08A3_DATA_LANES 4
+
+#define GC08A3_RGB_DEPTH 10
+
+#define GC08A3_SLEEP_US  2000
+
+static const char *const gc08a3_test_pattern_menu[] = {
+	"No Pattern", "Solid Black", "Colour Bar", "Solid White",
+	"Solid Red", "Solid Green", "Solid Blue", "Solid Yellow",
+};
+
+static const s64 gc08a3_link_freq_menu_items[] = {
+	336000000ULL,
+	207000000ULL,
+};
+
+static const char *const gc08a3_supply_name[] = {
+	"avdd",
+	"dvdd",
+	"dovdd",
+};
+
+struct gc08a3 {
+	struct device *dev;
+	struct v4l2_subdev sd;
+	struct media_pad pad;
+
+	struct clk *xclk;
+	struct regulator_bulk_data supplies[ARRAY_SIZE(gc08a3_supply_name)];
+	struct gpio_desc *reset_gpio;
+
+	struct v4l2_ctrl_handler ctrls;
+	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *link_freq;
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *hblank;
+	struct v4l2_ctrl *hflip;
+	struct v4l2_ctrl *vflip;
+
+	struct regmap *regmap;
+	unsigned long link_freq_bitmap;
+	const struct gc08a3_mode *cur_mode;
+};
+
+struct gc08a3_reg_list {
+	u32 num_of_regs;
+	const struct cci_reg_sequence *regs;
+};
+
+static const struct cci_reg_sequence mode_3264x2448[] = {
+	/* system */
+	{ CCI_REG8(0x0336), 0x70 },
+	{ CCI_REG8(0x0383), 0xbb },
+	{ CCI_REG8(0x0344), 0x00 },
+	{ CCI_REG8(0x0345), 0x06 },
+	{ CCI_REG8(0x0346), 0x00 },
+	{ CCI_REG8(0x0347), 0x04 },
+	{ CCI_REG8(0x0348), 0x0c },
+	{ CCI_REG8(0x0349), 0xd0 },
+	{ CCI_REG8(0x034a), 0x09 },
+	{ CCI_REG8(0x034b), 0x9c },
+	{ CCI_REG8(0x0202), 0x09 },
+	{ CCI_REG8(0x0203), 0x04 },
+	{ CCI_REG8(0x0340), 0x09 },
+	{ CCI_REG8(0x0341), 0xf4 },
+	{ CCI_REG8(0x0342), 0x07 },
+	{ CCI_REG8(0x0343), 0x1c },
+
+	{ CCI_REG8(0x0226), 0x00 },
+	{ CCI_REG8(0x0227), 0x28 },
+	{ CCI_REG8(0x0e38), 0x49 },
+	{ CCI_REG8(0x0210), 0x13 },
+	{ CCI_REG8(0x0218), 0x00 },
+	{ CCI_REG8(0x0241), 0x88 },
+	{ CCI_REG8(0x0392), 0x60 },
+
+	/* ISP */
+	{ CCI_REG8(0x00a2), 0x00 },
+	{ CCI_REG8(0x00a3), 0x00 },
+	{ CCI_REG8(0x00ab), 0x00 },
+	{ CCI_REG8(0x00ac), 0x00 },
+
+	/* GAIN */
+	{ CCI_REG8(0x0204), 0x04 },
+	{ CCI_REG8(0x0205), 0x00 },
+	{ CCI_REG8(0x0050), 0x5c },
+	{ CCI_REG8(0x0051), 0x44 },
+
+	/* out window */
+	{ CCI_REG8(0x009a), 0x66 },
+	{ CCI_REG8(0x0351), 0x00 },
+	{ CCI_REG8(0x0352), 0x06 },
+	{ CCI_REG8(0x0353), 0x00 },
+	{ CCI_REG8(0x0354), 0x08 },
+	{ CCI_REG8(0x034c), 0x0c },
+	{ CCI_REG8(0x034d), 0xc0 },
+	{ CCI_REG8(0x034e), 0x09 },
+	{ CCI_REG8(0x034f), 0x90 },
+
+	/* MIPI */
+	{ CCI_REG8(0x0114), 0x03 },
+	{ CCI_REG8(0x0180), 0x65 },
+	{ CCI_REG8(0x0181), 0xf0 },
+	{ CCI_REG8(0x0185), 0x01 },
+	{ CCI_REG8(0x0115), 0x30 },
+	{ CCI_REG8(0x011b), 0x12 },
+	{ CCI_REG8(0x011c), 0x12 },
+	{ CCI_REG8(0x0121), 0x06 },
+	{ CCI_REG8(0x0122), 0x06 },
+	{ CCI_REG8(0x0123), 0x15 },
+	{ CCI_REG8(0x0124), 0x01 },
+	{ CCI_REG8(0x0125), 0x0b },
+	{ CCI_REG8(0x0126), 0x08 },
+	{ CCI_REG8(0x0129), 0x06 },
+	{ CCI_REG8(0x012a), 0x08 },
+	{ CCI_REG8(0x012b), 0x08 },
+
+	{ CCI_REG8(0x0a73), 0x60 },
+	{ CCI_REG8(0x0a70), 0x11 },
+	{ CCI_REG8(0x0313), 0x80 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0a70), 0x00 },
+	{ CCI_REG8(0x00a4), 0x80 },
+	{ CCI_REG8(0x0316), 0x01 },
+	{ CCI_REG8(0x0a67), 0x00 },
+	{ CCI_REG8(0x0084), 0x10 },
+	{ CCI_REG8(0x0102), 0x09 },
+};
+
+static const struct cci_reg_sequence mode_1920x1080[] = {
+	/* system */
+	{ CCI_REG8(0x0336), 0x45 },
+	{ CCI_REG8(0x0383), 0x8b },
+	{ CCI_REG8(0x0344), 0x02 },
+	{ CCI_REG8(0x0345), 0xa6 },
+	{ CCI_REG8(0x0346), 0x02 },
+	{ CCI_REG8(0x0347), 0xb0 },
+	{ CCI_REG8(0x0348), 0x07 },
+	{ CCI_REG8(0x0349), 0x90 },
+	{ CCI_REG8(0x034a), 0x04 },
+	{ CCI_REG8(0x034b), 0x44 },
+	{ CCI_REG8(0x0202), 0x03 },
+	{ CCI_REG8(0x0203), 0x00 },
+	{ CCI_REG8(0x0340), 0x04 },
+	{ CCI_REG8(0x0341), 0xfc },
+	{ CCI_REG8(0x0342), 0x07 },
+	{ CCI_REG8(0x0343), 0x1c },
+	{ CCI_REG8(0x0226), 0x00 },
+	{ CCI_REG8(0x0227), 0x88 },
+	{ CCI_REG8(0x0e38), 0x49 },
+	{ CCI_REG8(0x0210), 0x13 },
+	{ CCI_REG8(0x0218), 0x00 },
+	{ CCI_REG8(0x0241), 0x88 },
+	{ CCI_REG8(0x0392), 0x60 },
+
+	/* ISP */
+	{ CCI_REG8(0x00a2), 0xac },
+	{ CCI_REG8(0x00a3), 0x02 },
+	{ CCI_REG8(0x00ab), 0xa0 },
+	{ CCI_REG8(0x00ac), 0x02 },
+
+	/* GAIN */
+	{ CCI_REG8(0x0204), 0x04 },
+	{ CCI_REG8(0x0205), 0x00 },
+	{ CCI_REG8(0x0050), 0x38 },
+	{ CCI_REG8(0x0051), 0x20 },
+
+	/* out window */
+	{ CCI_REG8(0x009a), 0x66 },
+	{ CCI_REG8(0x0351), 0x00 },
+	{ CCI_REG8(0x0352), 0x06 },
+	{ CCI_REG8(0x0353), 0x00 },
+	{ CCI_REG8(0x0354), 0x08 },
+	{ CCI_REG8(0x034c), 0x07 },
+	{ CCI_REG8(0x034d), 0x80 },
+	{ CCI_REG8(0x034e), 0x04 },
+	{ CCI_REG8(0x034f), 0x38 },
+
+	/* MIPI */
+	{ CCI_REG8(0x0114), 0x03 },
+	{ CCI_REG8(0x0180), 0x65 },
+	{ CCI_REG8(0x0181), 0xf0 },
+	{ CCI_REG8(0x0185), 0x01 },
+	{ CCI_REG8(0x0115), 0x30 },
+	{ CCI_REG8(0x011b), 0x12 },
+	{ CCI_REG8(0x011c), 0x12 },
+	{ CCI_REG8(0x0121), 0x02 },
+	{ CCI_REG8(0x0122), 0x03 },
+	{ CCI_REG8(0x0123), 0x0c },
+	{ CCI_REG8(0x0124), 0x00 },
+	{ CCI_REG8(0x0125), 0x09 },
+	{ CCI_REG8(0x0126), 0x06 },
+	{ CCI_REG8(0x0129), 0x04 },
+	{ CCI_REG8(0x012a), 0x03 },
+	{ CCI_REG8(0x012b), 0x06 },
+
+	{ CCI_REG8(0x0a73), 0x60 },
+	{ CCI_REG8(0x0a70), 0x11 },
+	{ CCI_REG8(0x0313), 0x80 },
+	{ CCI_REG8(0x0aff), 0x00 },
+	{ CCI_REG8(0x0a70), 0x00 },
+	{ CCI_REG8(0x00a4), 0x80 },
+	{ CCI_REG8(0x0316), 0x01 },
+	{ CCI_REG8(0x0a67), 0x00 },
+	{ CCI_REG8(0x0084), 0x10 },
+	{ CCI_REG8(0x0102), 0x09 },
+};
+
+static const struct cci_reg_sequence mode_table_common[] = {
+	{ GC08A3_STREAMING_REG, 0x00 },
+	/* system */
+	{ CCI_REG8(0x031c), 0x60 },
+	{ CCI_REG8(0x0337), 0x04 },
+	{ CCI_REG8(0x0335), 0x51 },
+	{ CCI_REG8(0x0336), 0x70 },
+	{ CCI_REG8(0x0383), 0xbb },
+	{ CCI_REG8(0x031a), 0x00 },
+	{ CCI_REG8(0x0321), 0x10 },
+	{ CCI_REG8(0x0327), 0x03 },
+	{ CCI_REG8(0x0325), 0x40 },
+	{ CCI_REG8(0x0326), 0x23 },
+	{ CCI_REG8(0x0314), 0x11 },
+	{ CCI_REG8(0x0315), 0xd6 },
+	{ CCI_REG8(0x0316), 0x01 },
+	{ CCI_REG8(0x0334), 0x40 },
+	{ CCI_REG8(0x0324), 0x42 },
+	{ CCI_REG8(0x031c), 0x00 },
+	{ CCI_REG8(0x031c), 0x9f },
+	{ CCI_REG8(0x039a), 0x13 },
+	{ CCI_REG8(0x0084), 0x30 },
+	{ CCI_REG8(0x02b3), 0x08 },
+	{ CCI_REG8(0x0057), 0x0c },
+	{ CCI_REG8(0x05c3), 0x50 },
+	{ CCI_REG8(0x0311), 0x90 },
+	{ CCI_REG8(0x05a0), 0x02 },
+	{ CCI_REG8(0x0074), 0x0a },
+	{ CCI_REG8(0x0059), 0x11 },
+	{ CCI_REG8(0x0070), 0x05 },
+	{ CCI_REG8(0x0101), 0x00 },
+
+	/* analog */
+	{ CCI_REG8(0x0344), 0x00 },
+	{ CCI_REG8(0x0345), 0x06 },
+	{ CCI_REG8(0x0346), 0x00 },
+	{ CCI_REG8(0x0347), 0x04 },
+	{ CCI_REG8(0x0348), 0x0c },
+	{ CCI_REG8(0x0349), 0xd0 },
+	{ CCI_REG8(0x034a), 0x09 },
+	{ CCI_REG8(0x034b), 0x9c },
+	{ CCI_REG8(0x0202), 0x09 },
+	{ CCI_REG8(0x0203), 0x04 },
+
+	{ CCI_REG8(0x0219), 0x05 },
+	{ CCI_REG8(0x0226), 0x00 },
+	{ CCI_REG8(0x0227), 0x28 },
+	{ CCI_REG8(0x0e0a), 0x00 },
+	{ CCI_REG8(0x0e0b), 0x00 },
+	{ CCI_REG8(0x0e24), 0x04 },
+	{ CCI_REG8(0x0e25), 0x04 },
+	{ CCI_REG8(0x0e26), 0x00 },
+	{ CCI_REG8(0x0e27), 0x10 },
+	{ CCI_REG8(0x0e01), 0x74 },
+	{ CCI_REG8(0x0e03), 0x47 },
+	{ CCI_REG8(0x0e04), 0x33 },
+	{ CCI_REG8(0x0e05), 0x44 },
+	{ CCI_REG8(0x0e06), 0x44 },
+	{ CCI_REG8(0x0e0c), 0x1e },
+	{ CCI_REG8(0x0e17), 0x3a },
+	{ CCI_REG8(0x0e18), 0x3c },
+	{ CCI_REG8(0x0e19), 0x40 },
+	{ CCI_REG8(0x0e1a), 0x42 },
+	{ CCI_REG8(0x0e28), 0x21 },
+	{ CCI_REG8(0x0e2b), 0x68 },
+	{ CCI_REG8(0x0e2c), 0x0d },
+	{ CCI_REG8(0x0e2d), 0x08 },
+	{ CCI_REG8(0x0e34), 0xf4 },
+	{ CCI_REG8(0x0e35), 0x44 },
+	{ CCI_REG8(0x0e36), 0x07 },
+	{ CCI_REG8(0x0e38), 0x49 },
+	{ CCI_REG8(0x0210), 0x13 },
+	{ CCI_REG8(0x0218), 0x00 },
+	{ CCI_REG8(0x0241), 0x88 },
+	{ CCI_REG8(0x0e32), 0x00 },
+	{ CCI_REG8(0x0e33), 0x18 },
+	{ CCI_REG8(0x0e42), 0x03 },
+	{ CCI_REG8(0x0e43), 0x80 },
+	{ CCI_REG8(0x0e44), 0x04 },
+	{ CCI_REG8(0x0e45), 0x00 },
+	{ CCI_REG8(0x0e4f), 0x04 },
+	{ CCI_REG8(0x057a), 0x20 },
+	{ CCI_REG8(0x0381), 0x7c },
+	{ CCI_REG8(0x0382), 0x9b },
+	{ CCI_REG8(0x0384), 0xfb },
+	{ CCI_REG8(0x0389), 0x38 },
+	{ CCI_REG8(0x038a), 0x03 },
+	{ CCI_REG8(0x0390), 0x6a },
+	{ CCI_REG8(0x0391), 0x0b },
+	{ CCI_REG8(0x0392), 0x60 },
+	{ CCI_REG8(0x0393), 0xc1 },
+	{ CCI_REG8(0x0396), 0xff },
+	{ CCI_REG8(0x0398), 0x62 },
+
+	/* cisctl reset */
+	{ CCI_REG8(0x031c), 0x80 },
+	{ CCI_REG8(0x03fe), 0x10 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x031c), 0x9f },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x031c), 0x80 },
+	{ CCI_REG8(0x03fe), 0x10 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x031c), 0x9f },
+	{ CCI_REG8(0x0360), 0x01 },
+	{ CCI_REG8(0x0360), 0x00 },
+	{ CCI_REG8(0x0316), 0x09 },
+	{ CCI_REG8(0x0a67), 0x80 },
+	{ CCI_REG8(0x0313), 0x00 },
+	{ CCI_REG8(0x0a53), 0x0e },
+	{ CCI_REG8(0x0a65), 0x17 },
+	{ CCI_REG8(0x0a68), 0xa1 },
+	{ CCI_REG8(0x0a58), 0x00 },
+	{ CCI_REG8(0x0ace), 0x0c },
+	{ CCI_REG8(0x00a4), 0x00 },
+	{ CCI_REG8(0x00a5), 0x01 },
+	{ CCI_REG8(0x00a7), 0x09 },
+	{ CCI_REG8(0x00a8), 0x9c },
+	{ CCI_REG8(0x00a9), 0x0c },
+	{ CCI_REG8(0x00aa), 0xd0 },
+	{ CCI_REG8(0x0a8a), 0x00 },
+	{ CCI_REG8(0x0a8b), 0xe0 },
+	{ CCI_REG8(0x0a8c), 0x13 },
+	{ CCI_REG8(0x0a8d), 0xe8 },
+	{ CCI_REG8(0x0a90), 0x0a },
+	{ CCI_REG8(0x0a91), 0x10 },
+	{ CCI_REG8(0x0a92), 0xf8 },
+	{ CCI_REG8(0x0a71), 0xf2 },
+	{ CCI_REG8(0x0a72), 0x12 },
+	{ CCI_REG8(0x0a73), 0x64 },
+	{ CCI_REG8(0x0a75), 0x41 },
+	{ CCI_REG8(0x0a70), 0x07 },
+	{ CCI_REG8(0x0313), 0x80 },
+
+	/* ISP */
+	{ CCI_REG8(0x00a0), 0x01 },
+	{ CCI_REG8(0x0080), 0xd2 },
+	{ CCI_REG8(0x0081), 0x3f },
+	{ CCI_REG8(0x0087), 0x51 },
+	{ CCI_REG8(0x0089), 0x03 },
+	{ CCI_REG8(0x009b), 0x40 },
+	{ CCI_REG8(0x05a0), 0x82 },
+	{ CCI_REG8(0x05ac), 0x00 },
+	{ CCI_REG8(0x05ad), 0x01 },
+	{ CCI_REG8(0x05ae), 0x00 },
+	{ CCI_REG8(0x0800), 0x0a },
+	{ CCI_REG8(0x0801), 0x14 },
+	{ CCI_REG8(0x0802), 0x28 },
+	{ CCI_REG8(0x0803), 0x34 },
+	{ CCI_REG8(0x0804), 0x0e },
+	{ CCI_REG8(0x0805), 0x33 },
+	{ CCI_REG8(0x0806), 0x03 },
+	{ CCI_REG8(0x0807), 0x8a },
+	{ CCI_REG8(0x0808), 0x50 },
+	{ CCI_REG8(0x0809), 0x00 },
+	{ CCI_REG8(0x080a), 0x34 },
+	{ CCI_REG8(0x080b), 0x03 },
+	{ CCI_REG8(0x080c), 0x26 },
+	{ CCI_REG8(0x080d), 0x03 },
+	{ CCI_REG8(0x080e), 0x18 },
+	{ CCI_REG8(0x080f), 0x03 },
+	{ CCI_REG8(0x0810), 0x10 },
+	{ CCI_REG8(0x0811), 0x03 },
+	{ CCI_REG8(0x0812), 0x00 },
+	{ CCI_REG8(0x0813), 0x00 },
+	{ CCI_REG8(0x0814), 0x01 },
+	{ CCI_REG8(0x0815), 0x00 },
+	{ CCI_REG8(0x0816), 0x01 },
+	{ CCI_REG8(0x0817), 0x00 },
+	{ CCI_REG8(0x0818), 0x00 },
+	{ CCI_REG8(0x0819), 0x0a },
+	{ CCI_REG8(0x081a), 0x01 },
+	{ CCI_REG8(0x081b), 0x6c },
+	{ CCI_REG8(0x081c), 0x00 },
+	{ CCI_REG8(0x081d), 0x0b },
+	{ CCI_REG8(0x081e), 0x02 },
+	{ CCI_REG8(0x081f), 0x00 },
+	{ CCI_REG8(0x0820), 0x00 },
+	{ CCI_REG8(0x0821), 0x0c },
+	{ CCI_REG8(0x0822), 0x02 },
+	{ CCI_REG8(0x0823), 0xd9 },
+	{ CCI_REG8(0x0824), 0x00 },
+	{ CCI_REG8(0x0825), 0x0d },
+	{ CCI_REG8(0x0826), 0x03 },
+	{ CCI_REG8(0x0827), 0xf0 },
+	{ CCI_REG8(0x0828), 0x00 },
+	{ CCI_REG8(0x0829), 0x0e },
+	{ CCI_REG8(0x082a), 0x05 },
+	{ CCI_REG8(0x082b), 0x94 },
+	{ CCI_REG8(0x082c), 0x09 },
+	{ CCI_REG8(0x082d), 0x6e },
+	{ CCI_REG8(0x082e), 0x07 },
+	{ CCI_REG8(0x082f), 0xe6 },
+	{ CCI_REG8(0x0830), 0x10 },
+	{ CCI_REG8(0x0831), 0x0e },
+	{ CCI_REG8(0x0832), 0x0b },
+	{ CCI_REG8(0x0833), 0x2c },
+	{ CCI_REG8(0x0834), 0x14 },
+	{ CCI_REG8(0x0835), 0xae },
+	{ CCI_REG8(0x0836), 0x0f },
+	{ CCI_REG8(0x0837), 0xc4 },
+	{ CCI_REG8(0x0838), 0x18 },
+	{ CCI_REG8(0x0839), 0x0e },
+	{ CCI_REG8(0x05ac), 0x01 },
+	{ CCI_REG8(0x059a), 0x00 },
+	{ CCI_REG8(0x059b), 0x00 },
+	{ CCI_REG8(0x059c), 0x01 },
+	{ CCI_REG8(0x0598), 0x00 },
+	{ CCI_REG8(0x0597), 0x14 },
+	{ CCI_REG8(0x05ab), 0x09 },
+	{ CCI_REG8(0x05a4), 0x02 },
+	{ CCI_REG8(0x05a3), 0x05 },
+	{ CCI_REG8(0x05a0), 0xc2 },
+	{ CCI_REG8(0x0207), 0xc4 },
+
+	/* GAIN */
+	{ CCI_REG8(0x0208), 0x01 },
+	{ CCI_REG8(0x0209), 0x72 },
+	{ CCI_REG8(0x0204), 0x04 },
+	{ CCI_REG8(0x0205), 0x00 },
+
+	{ CCI_REG8(0x0040), 0x22 },
+	{ CCI_REG8(0x0041), 0x20 },
+	{ CCI_REG8(0x0043), 0x10 },
+	{ CCI_REG8(0x0044), 0x00 },
+	{ CCI_REG8(0x0046), 0x08 },
+	{ CCI_REG8(0x0047), 0xf0 },
+	{ CCI_REG8(0x0048), 0x0f },
+	{ CCI_REG8(0x004b), 0x0f },
+	{ CCI_REG8(0x004c), 0x00 },
+	{ CCI_REG8(0x0050), 0x5c },
+	{ CCI_REG8(0x0051), 0x44 },
+	{ CCI_REG8(0x005b), 0x03 },
+	{ CCI_REG8(0x00c0), 0x00 },
+	{ CCI_REG8(0x00c1), 0x80 },
+	{ CCI_REG8(0x00c2), 0x31 },
+	{ CCI_REG8(0x00c3), 0x00 },
+	{ CCI_REG8(0x0460), 0x04 },
+	{ CCI_REG8(0x0462), 0x08 },
+	{ CCI_REG8(0x0464), 0x0e },
+	{ CCI_REG8(0x0466), 0x0a },
+	{ CCI_REG8(0x0468), 0x12 },
+	{ CCI_REG8(0x046a), 0x12 },
+	{ CCI_REG8(0x046c), 0x10 },
+	{ CCI_REG8(0x046e), 0x0c },
+	{ CCI_REG8(0x0461), 0x03 },
+	{ CCI_REG8(0x0463), 0x03 },
+	{ CCI_REG8(0x0465), 0x03 },
+	{ CCI_REG8(0x0467), 0x03 },
+	{ CCI_REG8(0x0469), 0x04 },
+	{ CCI_REG8(0x046b), 0x04 },
+	{ CCI_REG8(0x046d), 0x04 },
+	{ CCI_REG8(0x046f), 0x04 },
+	{ CCI_REG8(0x0470), 0x04 },
+	{ CCI_REG8(0x0472), 0x10 },
+	{ CCI_REG8(0x0474), 0x26 },
+	{ CCI_REG8(0x0476), 0x38 },
+	{ CCI_REG8(0x0478), 0x20 },
+	{ CCI_REG8(0x047a), 0x30 },
+	{ CCI_REG8(0x047c), 0x38 },
+	{ CCI_REG8(0x047e), 0x60 },
+	{ CCI_REG8(0x0471), 0x05 },
+	{ CCI_REG8(0x0473), 0x05 },
+	{ CCI_REG8(0x0475), 0x05 },
+	{ CCI_REG8(0x0477), 0x05 },
+	{ CCI_REG8(0x0479), 0x04 },
+	{ CCI_REG8(0x047b), 0x04 },
+	{ CCI_REG8(0x047d), 0x04 },
+	{ CCI_REG8(0x047f), 0x04 },
+};
+
+struct gc08a3_mode {
+	u32 width;
+	u32 height;
+	const struct gc08a3_reg_list reg_list;
+
+	u32 hts; /* Horizontal timining size */
+	u32 vts_def; /* Default vertical timining size */
+	u32 vts_min; /* Min vertical timining size */
+};
+
+/* Declare modes in order, from biggest to smallest height. */
+static const struct gc08a3_mode gc08a3_modes[] = {
+	{
+		/* 3264*2448 at 30fps */
+		.width = GC08A3_NATIVE_WIDTH,
+		.height = GC08A3_NATIVE_HEIGHT,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_3264x2448),
+			.regs = mode_3264x2448,
+		},
+		.hts = 3640,
+		.vts_def = 2548,
+		.vts_min = 2548,
+	},
+	{
+		/* 1920*1080 at 60fps */
+		.width = 1920,
+		.height = 1080,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_1920x1080),
+			.regs = mode_1920x1080,
+		},
+		.hts = 3640,
+		.vts_def = 1276,
+		.vts_min = 1276,
+	},
+};
+
+static inline struct gc08a3 *to_gc08a3(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct gc08a3, sd);
+}
+
+static int gc08a3_power_on(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct gc08a3 *gc08a3 = to_gc08a3(sd);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(gc08a3_supply_name),
+				    gc08a3->supplies);
+	if (ret < 0) {
+		dev_err(gc08a3->dev, "failed to enable regulators: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(gc08a3->xclk);
+	if (ret < 0) {
+		regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
+				       gc08a3->supplies);
+		dev_err(gc08a3->dev, "clk prepare enable failed\n");
+		return ret;
+	}
+
+	fsleep(GC08A3_SLEEP_US);
+
+	gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
+	fsleep(GC08A3_SLEEP_US);
+
+	return 0;
+}
+
+static int gc08a3_power_off(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct gc08a3 *gc08a3 = to_gc08a3(sd);
+
+	clk_disable_unprepare(gc08a3->xclk);
+	gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);
+	regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
+			       gc08a3->supplies);
+
+	return 0;
+}
+
+static int gc08a3_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index > 0)
+		return -EINVAL;
+
+	code->code = GC08A3_MBUS_CODE;
+
+	return 0;
+}
+
+static int gc08a3_enum_frame_size(struct v4l2_subdev *subdev,
+				  struct v4l2_subdev_state *sd_state,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->code != GC08A3_MBUS_CODE)
+		return -EINVAL;
+
+	if (fse->index >= ARRAY_SIZE(gc08a3_modes))
+		return -EINVAL;
+
+	fse->min_width = gc08a3_modes[fse->index].width;
+	fse->max_width = gc08a3_modes[fse->index].width;
+	fse->min_height = gc08a3_modes[fse->index].height;
+	fse->max_height = gc08a3_modes[fse->index].height;
+
+	return 0;
+}
+
+static int gc08a3_update_cur_mode_controls(struct gc08a3 *gc08a3,
+					   const struct gc08a3_mode *mode)
+{
+	s64 exposure_max, h_blank;
+	int ret;
+
+	ret = __v4l2_ctrl_modify_range(gc08a3->vblank,
+				       mode->vts_min - mode->height,
+				       GC08A3_VTS_MAX - mode->height, 1,
+				       mode->vts_def - mode->height);
+	if (ret) {
+		dev_err(gc08a3->dev, "VB ctrl range update failed\n");
+		return ret;
+	}
+
+	h_blank = mode->hts - mode->width;
+	ret = __v4l2_ctrl_modify_range(gc08a3->hblank, h_blank, h_blank, 1,
+				       h_blank);
+	if (ret) {
+		dev_err(gc08a3->dev, "HB ctrl range update failed\n");
+		return ret;
+	}
+
+	exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
+	ret = __v4l2_ctrl_modify_range(gc08a3->exposure, GC08A3_EXP_MIN,
+				       exposure_max, GC08A3_EXP_STEP,
+				       exposure_max);
+	if (ret) {
+		dev_err(gc08a3->dev, "exposure ctrl range update failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void gc08a3_update_pad_format(struct gc08a3 *gc08a3,
+				     const struct gc08a3_mode *mode,
+				     struct v4l2_mbus_framefmt *fmt)
+{
+	fmt->width = mode->width;
+	fmt->height = mode->height;
+	fmt->code = GC08A3_MBUS_CODE;
+	fmt->field = V4L2_FIELD_NONE;
+	fmt->colorspace = V4L2_COLORSPACE_RAW;
+	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
+	fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+	fmt->xfer_func = V4L2_XFER_FUNC_NONE;
+}
+
+static int gc08a3_set_format(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct gc08a3 *gc08a3 = to_gc08a3(sd);
+	struct v4l2_mbus_framefmt *mbus_fmt;
+	struct v4l2_rect *crop;
+	const struct gc08a3_mode *mode;
+
+	mode = v4l2_find_nearest_size(gc08a3_modes, ARRAY_SIZE(gc08a3_modes),
+				      width, height, fmt->format.width,
+				      fmt->format.height);
+
+	/*update crop info to subdev state*/
+	crop = v4l2_subdev_state_get_crop(state, 0);
+	crop->width = mode->width;
+	crop->height = mode->height;
+
+	/*update fmt info to subdev state*/
+	gc08a3_update_pad_format(gc08a3, mode, &fmt->format);
+	mbus_fmt = v4l2_subdev_state_get_format(state, 0);
+	*mbus_fmt = fmt->format;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+		return 0;
+
+	gc08a3->cur_mode = mode;
+	gc08a3_update_cur_mode_controls(gc08a3, mode);
+
+	return 0;
+}
+
+static int gc08a3_get_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *state,
+				struct v4l2_subdev_selection *sel)
+{
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP:
+		sel->r = *v4l2_subdev_state_get_crop(state, 0);
+		break;
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r.top = 0;
+		sel->r.left = 0;
+		sel->r.width = GC08A3_NATIVE_WIDTH;
+		sel->r.height = GC08A3_NATIVE_HEIGHT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int gc08a3_init_state(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_format fmt = {
+		.which = V4L2_SUBDEV_FORMAT_TRY,
+		.pad = 0,
+		.format = {
+			.code = GC08A3_MBUS_CODE,
+			.width = gc08a3_modes[0].width,
+			.height = gc08a3_modes[0].height,
+		},
+	};
+
+	gc08a3_set_format(sd, state, &fmt);
+
+	return 0;
+}
+
+static int gc08a3_set_ctrl_hflip(struct gc08a3 *gc08a3, u32 ctrl_val)
+{
+	int ret;
+	u64 val;
+
+	ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
+	if (ret) {
+		dev_err(gc08a3->dev, "read hflip register failed: %d\n", ret);
+		return ret;
+	}
+
+	return cci_update_bits(gc08a3->regmap, GC08A3_FLIP_REG,
+			       GC08A3_FLIP_H_MASK,
+			       ctrl_val ? GC08A3_FLIP_H_MASK : 0, NULL);
+}
+
+static int gc08a3_set_ctrl_vflip(struct gc08a3 *gc08a3, u32 ctrl_val)
+{
+	int ret;
+	u64 val;
+
+	ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
+	if (ret) {
+		dev_err(gc08a3->dev, "read vflip register failed: %d\n", ret);
+		return ret;
+	}
+
+	return cci_update_bits(gc08a3->regmap, GC08A3_FLIP_REG,
+			       GC08A3_FLIP_V_MASK,
+			       ctrl_val ? GC08A3_FLIP_V_MASK : 0, NULL);
+}
+
+static int gc08a3_test_pattern(struct gc08a3 *gc08a3, u32 pattern_menu)
+{
+	u32 pattern = 0;
+	int ret;
+
+	if (pattern_menu) {
+		switch (pattern_menu) {
+		case 1:
+			pattern = 0x00;
+			break;
+		case 2:
+			pattern = 0x10;
+			break;
+		case 3:
+		case 4:
+		case 5:
+		case 6:
+		case 7:
+			pattern = pattern_menu + 1;
+			break;
+		}
+
+		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_IDX,
+				pattern, NULL);
+		if (ret)
+			return ret;
+
+		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
+				GC08A3_TEST_PATTERN_EN, NULL);
+		if (ret)
+			return ret;
+	} else {
+		ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
+				0x00, NULL);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int gc08a3_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct gc08a3 *gc08a3 =
+		container_of(ctrl->handler, struct gc08a3, ctrls);
+	int ret = 0;
+	s64 exposure_max;
+	struct v4l2_subdev_state *state;
+	const struct v4l2_mbus_framefmt *format;
+
+	state = v4l2_subdev_get_locked_active_state(&gc08a3->sd);
+	format = v4l2_subdev_state_get_format(state, 0);
+
+	if (ctrl->id == V4L2_CID_VBLANK) {
+		/* Update max exposure while meeting expected vblanking */
+		exposure_max = format->height + ctrl->val - GC08A3_EXP_MARGIN;
+		__v4l2_ctrl_modify_range(gc08a3->exposure,
+					 gc08a3->exposure->minimum,
+					 exposure_max, gc08a3->exposure->step,
+					 exposure_max);
+	}
+
+	/*
+	 * Applying V4L2 control value only happens
+	 * when power is on for streaming
+	 */
+	if (!pm_runtime_get_if_in_use(gc08a3->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		ret = cci_write(gc08a3->regmap, GC08A3_EXP_REG,
+				ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = cci_write(gc08a3->regmap, GC08A3_AGAIN_REG,
+				ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_VBLANK:
+		ret = cci_write(gc08a3->regmap, GC08A3_FRAME_LENGTH_REG,
+				gc08a3->cur_mode->height + ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_HFLIP:
+		ret = gc08a3_set_ctrl_hflip(gc08a3, ctrl->val);
+		break;
+
+	case V4L2_CID_VFLIP:
+		ret = gc08a3_set_ctrl_vflip(gc08a3, ctrl->val);
+		break;
+
+	case V4L2_CID_TEST_PATTERN:
+		ret = gc08a3_test_pattern(gc08a3, ctrl->val);
+		break;
+
+	default:
+		break;
+	}
+
+	pm_runtime_put(gc08a3->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops gc08a3_ctrl_ops = {
+	.s_ctrl = gc08a3_set_ctrl,
+};
+
+static int gc08a3_start_streaming(struct gc08a3 *gc08a3)
+{
+	const struct gc08a3_mode *mode;
+	const struct gc08a3_reg_list *reg_list;
+	int ret;
+
+	ret = pm_runtime_resume_and_get(gc08a3->dev);
+	if (ret < 0)
+		return ret;
+
+	ret = cci_multi_reg_write(gc08a3->regmap,
+				  mode_table_common,
+				  ARRAY_SIZE(mode_table_common), NULL);
+	if (ret)
+		goto err_rpm_put;
+
+	mode = gc08a3->cur_mode;
+	reg_list = &mode->reg_list;
+	ret = cci_multi_reg_write(gc08a3->regmap,
+				  reg_list->regs, reg_list->num_of_regs, NULL);
+	if (ret < 0)
+		goto err_rpm_put;
+
+	ret = __v4l2_ctrl_handler_setup(&gc08a3->ctrls);
+	if (ret < 0) {
+		dev_err(gc08a3->dev, "could not sync v4l2 controls\n");
+		goto err_rpm_put;
+	}
+
+	ret = cci_write(gc08a3->regmap, GC08A3_STREAMING_REG, 1, NULL);
+	if (ret < 0) {
+		dev_err(gc08a3->dev, "write STRAEMING_REG failed: %d\n", ret);
+		goto err_rpm_put;
+	}
+
+	return 0;
+
+err_rpm_put:
+	pm_runtime_put(gc08a3->dev);
+	return ret;
+}
+
+static int gc08a3_stop_streaming(struct gc08a3 *gc08a3)
+{
+	int ret;
+
+	ret = cci_write(gc08a3->regmap, GC08A3_STREAMING_REG, 0, NULL);
+	if (ret < 0)
+		dev_err(gc08a3->dev, "could not sent stop streaming %d\n", ret);
+
+	pm_runtime_put(gc08a3->dev);
+	return ret;
+}
+
+static int gc08a3_s_stream(struct v4l2_subdev *subdev, int enable)
+{
+	struct gc08a3 *gc08a3 = to_gc08a3(subdev);
+	struct v4l2_subdev_state *state;
+	int ret;
+
+	state = v4l2_subdev_lock_and_get_active_state(subdev);
+
+	if (enable)
+		ret = gc08a3_start_streaming(gc08a3);
+	else
+		ret = gc08a3_stop_streaming(gc08a3);
+
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_video_ops gc08a3_video_ops = {
+	.s_stream = gc08a3_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops gc08a3_subdev_pad_ops = {
+	.enum_mbus_code = gc08a3_enum_mbus_code,
+	.enum_frame_size = gc08a3_enum_frame_size,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = gc08a3_set_format,
+	.get_selection = gc08a3_get_selection,
+};
+
+static const struct v4l2_subdev_core_ops gc08a3_core_ops = {
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_ops gc08a3_subdev_ops = {
+	.core = &gc08a3_core_ops,
+	.video = &gc08a3_video_ops,
+	.pad = &gc08a3_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops gc08a3_internal_ops = {
+	.init_state = gc08a3_init_state,
+};
+
+static int gc08a3_get_regulators(struct device *dev, struct gc08a3 *gc08a3)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(gc08a3_supply_name); i++)
+		gc08a3->supplies[i].supply = gc08a3_supply_name[i];
+
+	return devm_regulator_bulk_get(dev, ARRAY_SIZE(gc08a3_supply_name),
+				       gc08a3->supplies);
+}
+
+static int gc08a3_parse_fwnode(struct gc08a3 *gc08a3)
+{
+	struct fwnode_handle *endpoint;
+	struct v4l2_fwnode_endpoint bus_cfg = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY,
+	};
+	int ret;
+	struct device *dev = gc08a3->dev;
+
+	endpoint =
+		fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0,
+						FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (!endpoint) {
+		dev_err(dev, "endpoint node not found\n");
+		return -EINVAL;
+	}
+
+	ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
+	if (ret) {
+		dev_err(dev, "parsing endpoint node failed\n");
+		goto done;
+	}
+
+	ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
+				       bus_cfg.nr_of_link_frequencies,
+				       gc08a3_link_freq_menu_items,
+				       ARRAY_SIZE(gc08a3_link_freq_menu_items),
+				       &gc08a3->link_freq_bitmap);
+	if (ret)
+		goto done;
+
+done:
+	v4l2_fwnode_endpoint_free(&bus_cfg);
+	fwnode_handle_put(endpoint);
+	return ret;
+}
+
+static u64 gc08a3_to_pixel_rate(u32 f_index)
+{
+	u64 pixel_rate =
+		gc08a3_link_freq_menu_items[f_index] * 2 * GC08A3_DATA_LANES;
+
+	return div_u64(pixel_rate, GC08A3_RGB_DEPTH);
+}
+
+static int gc08a3_init_controls(struct gc08a3 *gc08a3)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
+	const struct gc08a3_mode *mode = &gc08a3_modes[0];
+	const struct v4l2_ctrl_ops *ops = &gc08a3_ctrl_ops;
+	struct v4l2_fwnode_device_properties props;
+	struct v4l2_ctrl_handler *ctrl_hdlr;
+	s64 exposure_max, h_blank;
+	int ret;
+
+	ctrl_hdlr = &gc08a3->ctrls;
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 9);
+	if (ret)
+		return ret;
+
+	gc08a3->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
+					  V4L2_CID_HFLIP, 0, 1, 1, 0);
+	gc08a3->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
+					  V4L2_CID_VFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_cluster(2, &gc08a3->hflip);
+
+	gc08a3->link_freq =
+	v4l2_ctrl_new_int_menu(ctrl_hdlr,
+			       &gc08a3_ctrl_ops,
+			       V4L2_CID_LINK_FREQ,
+			       ARRAY_SIZE(gc08a3_link_freq_menu_items) - 1,
+			       0,
+			       gc08a3_link_freq_menu_items);
+	if (gc08a3->link_freq)
+		gc08a3->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	gc08a3->pixel_rate =
+		v4l2_ctrl_new_std(ctrl_hdlr,
+				  &gc08a3_ctrl_ops,
+				  V4L2_CID_PIXEL_RATE, 0,
+				  gc08a3_to_pixel_rate(0),
+				  1,
+				  gc08a3_to_pixel_rate(0));
+
+	gc08a3->vblank =
+		v4l2_ctrl_new_std(ctrl_hdlr,
+				  &gc08a3_ctrl_ops, V4L2_CID_VBLANK,
+				  mode->vts_min - mode->height,
+				  GC08A3_VTS_MAX - mode->height, 1,
+				  mode->vts_def - mode->height);
+
+	h_blank = mode->hts - mode->width;
+	gc08a3->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
+					   V4L2_CID_HBLANK, h_blank, h_blank, 1,
+					   h_blank);
+	if (gc08a3->hblank)
+		gc08a3->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
+			  V4L2_CID_ANALOGUE_GAIN, GC08A3_AGAIN_MIN,
+			  GC08A3_AGAIN_MAX, GC08A3_AGAIN_STEP,
+			  GC08A3_AGAIN_MIN);
+
+	exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
+	gc08a3->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
+					     V4L2_CID_EXPOSURE, GC08A3_EXP_MIN,
+					     exposure_max, GC08A3_EXP_STEP,
+					     exposure_max);
+
+	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &gc08a3_ctrl_ops,
+				     V4L2_CID_TEST_PATTERN,
+				     ARRAY_SIZE(gc08a3_test_pattern_menu) - 1,
+				     0, 0, gc08a3_test_pattern_menu);
+
+	/* register properties to fwnode (e.g. rotation, orientation) */
+	ret = v4l2_fwnode_device_parse(&client->dev, &props);
+	if (ret)
+		goto error_ctrls;
+
+	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, ops, &props);
+	if (ret)
+		goto error_ctrls;
+
+	if (ctrl_hdlr->error) {
+		ret = ctrl_hdlr->error;
+		goto error_ctrls;
+	}
+
+	gc08a3->sd.ctrl_handler = ctrl_hdlr;
+
+	return 0;
+
+error_ctrls:
+	v4l2_ctrl_handler_free(ctrl_hdlr);
+
+	return ret;
+}
+
+static int gc08a3_identify_module(struct gc08a3 *gc08a3)
+{
+	u64 val;
+	int ret;
+
+	ret = cci_read(gc08a3->regmap, GC08A3_REG_CHIP_ID, &val, NULL);
+	if (ret) {
+		dev_err(gc08a3->dev, "failed to read chip id");
+		return ret;
+	}
+
+	if (val != GC08A3_CHIP_ID) {
+		dev_err(gc08a3->dev, "chip id mismatch: 0x%x!=0x%llx",
+			GC08A3_CHIP_ID, val);
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int gc08a3_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct gc08a3 *gc08a3;
+	int ret;
+
+	gc08a3 = devm_kzalloc(dev, sizeof(*gc08a3), GFP_KERNEL);
+	if (!gc08a3)
+		return -ENOMEM;
+
+	gc08a3->dev = dev;
+
+	ret = gc08a3_parse_fwnode(gc08a3);
+	if (ret)
+		return ret;
+
+	gc08a3->regmap = devm_cci_regmap_init_i2c(client, 16);
+	if (IS_ERR(gc08a3->regmap))
+		return dev_err_probe(dev, PTR_ERR(gc08a3->regmap),
+				     "failed to init CCI\n");
+
+	gc08a3->xclk = devm_clk_get(dev, NULL);
+	if (IS_ERR(gc08a3->xclk))
+		return dev_err_probe(dev, PTR_ERR(gc08a3->xclk),
+				     "failed to get xclk\n");
+
+	ret = clk_set_rate(gc08a3->xclk, GC08A3_DEFAULT_CLK_FREQ);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to set xclk frequency\n");
+
+	ret = gc08a3_get_regulators(dev, gc08a3);
+	if (ret < 0)
+		return dev_err_probe(dev, ret,
+				     "failed to get regulators\n");
+
+	gc08a3->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(gc08a3->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(gc08a3->reset_gpio),
+				     "failed to get gpio\n");
+
+	v4l2_i2c_subdev_init(&gc08a3->sd, client, &gc08a3_subdev_ops);
+	gc08a3->sd.internal_ops = &gc08a3_internal_ops;
+	gc08a3->cur_mode = &gc08a3_modes[0];
+
+	ret = gc08a3_power_on(gc08a3->dev);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to sensor power on\n");
+
+	ret = gc08a3_identify_module(gc08a3);
+	if (ret) {
+		dev_err(&client->dev, "failed to find sensor: %d\n", ret);
+		goto err_power_off;
+	}
+
+	ret = gc08a3_init_controls(gc08a3);
+	if (ret) {
+		dev_err(&client->dev, "failed to init controls: %d", ret);
+		goto err_power_off;
+	}
+
+	gc08a3->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+			    V4L2_SUBDEV_FL_HAS_EVENTS;
+	gc08a3->pad.flags = MEDIA_PAD_FL_SOURCE;
+	gc08a3->sd.dev = &client->dev;
+	gc08a3->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+	ret = media_entity_pads_init(&gc08a3->sd.entity, 1, &gc08a3->pad);
+	if (ret < 0) {
+		dev_err(dev, "could not register media entity\n");
+		goto err_v4l2_ctrl_handler_free;
+	}
+
+	gc08a3->sd.state_lock = gc08a3->ctrls.lock;
+	ret = v4l2_subdev_init_finalize(&gc08a3->sd);
+	if (ret < 0) {
+		dev_err(dev, "v4l2 subdev init error: %d\n", ret);
+		goto err_media_entity_cleanup;
+	}
+
+	pm_runtime_set_active(gc08a3->dev);
+	pm_runtime_enable(gc08a3->dev);
+	pm_runtime_set_autosuspend_delay(gc08a3->dev, 1000);
+	pm_runtime_use_autosuspend(gc08a3->dev);
+	pm_runtime_idle(gc08a3->dev);
+
+	ret = v4l2_async_register_subdev_sensor(&gc08a3->sd);
+	if (ret < 0) {
+		dev_err(dev, "could not register v4l2 device\n");
+		goto err_rpm;
+	}
+
+	return 0;
+
+err_rpm:
+	pm_runtime_disable(gc08a3->dev);
+	v4l2_subdev_cleanup(&gc08a3->sd);
+
+err_media_entity_cleanup:
+	media_entity_cleanup(&gc08a3->sd.entity);
+
+err_v4l2_ctrl_handler_free:
+	v4l2_ctrl_handler_free(gc08a3->sd.ctrl_handler);
+
+err_power_off:
+	gc08a3_power_off(gc08a3->dev);
+
+	return ret;
+}
+
+static void gc08a3_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct gc08a3 *gc08a3 = to_gc08a3(sd);
+
+	v4l2_async_unregister_subdev(&gc08a3->sd);
+	v4l2_subdev_cleanup(sd);
+	media_entity_cleanup(&gc08a3->sd.entity);
+	v4l2_ctrl_handler_free(&gc08a3->ctrls);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		gc08a3_power_off(gc08a3->dev);
+	pm_runtime_set_suspended(&client->dev);
+}
+
+static const struct of_device_id gc08a3_of_match[] = {
+	{ .compatible = "galaxycore,gc08a3" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, gc08a3_of_match);
+
+static const struct dev_pm_ops gc08a3_pm_ops = {
+	SET_RUNTIME_PM_OPS(gc08a3_power_off, gc08a3_power_on, NULL)
+};
+
+static struct i2c_driver gc08a3_i2c_driver = {
+	.driver = {
+		.of_match_table = gc08a3_of_match,
+		.pm = &gc08a3_pm_ops,
+		.name  = "gc08a3",
+	},
+	.probe  = gc08a3_probe,
+	.remove = gc08a3_remove,
+};
+
+module_i2c_driver(gc08a3_i2c_driver);
+
+MODULE_DESCRIPTION("GalaxyCore gc08a3 Camera driver");
+MODULE_AUTHOR("Zhi Mao <zhi.mao at mediatek.com>");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From thiago.bauermann at linaro.org  Mon Feb 19 18:00:46 2024
From: thiago.bauermann at linaro.org (Thiago Jung Bauermann)
Date: Mon, 19 Feb 2024 23:00:46 -0300
Subject: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in userspace
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <878r3f99o1.fsf@linaro.org>


Hello,

Mark Brown <broonie at kernel.org> writes:

> Changes in v8:
> - Invalidate signal cap token on stack when consuming.
> - Typo and other trivial fixes.
> - Don't try to use process_vm_write() on GCS, it intentionally does not
>   work.
> - Fix leak of thread GCSs.
> - Rebase onto latest clone3() series.
> - Link to v7: https://lore.kernel.org/r/20231122-arm64-gcs-v7-0-201c483bd775 at kernel.org

Thank you for addressing my comments. I still have a few nets and
questions in a few patches, but regardless of them:

Reviewed-by: Thiago Jung Bauermann <thiago.bauermann at linaro.org>

-- 
Thiago


From thiago.bauermann at linaro.org  Mon Feb 19 18:02:22 2024
From: thiago.bauermann at linaro.org (Thiago Jung Bauermann)
Date: Mon, 19 Feb 2024 23:02:22 -0300
Subject: [PATCH v8 20/38] arm64/gcs: Ensure that new threads have a GCS
In-Reply-To: <20240203-arm64-gcs-v8-20-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <20240203-arm64-gcs-v8-20-c9fec77673ef@kernel.org>
Message-ID: <874je399ld.fsf@linaro.org>


Mark Brown <broonie at kernel.org> writes:

> When a new thread is created by a thread with GCS enabled the GCS needs
> to be specified along with the regular stack.  clone3() has been
> extended to support this case, allowing userspace to explicitly specify
> the size and location of the GCS.  The specified GCS must have a valid
> GCS token at the top of the stack, as though userspace were pivoting to
> the new GCS.  This will be consumed on use.  At present we do not
> atomically consume the token, this will be addressed in a future
> revision.
>
> Unfortunately plain clone() is not extensible and existing clone3()
> users will not specify a stack so all existing code would be broken if
> we mandated specifying the stack explicitly.  For compatibility with
> these cases and also x86 (which did not initially implement clone3()
> support for shadow stacks) if no GCS is specified we will allocate one
> thread so when a thread is created which has GCS enabled allocate one
  ~~~~~~

This "thread" seems extraneous in the sentence. Remove it?

> for it.  We follow the extensively discussed x86 implementation and
> allocate min(RLIMIT_STACK, 4G).  Since the GCS only stores the call

Isn't it min(RLIMIT_STACK/2, 2G), as seen in gcs_size()? If true, this
size should also be fixed in Documentation/arch/arm64/gcs.rst.

> stack and not any variables this should be more than sufficient for most
> applications.
>
> GCSs allocated via this mechanism then it will be freed when the thread
> exits, those explicitly configured by the user will not.

I'm not sure I parsed this sentence correctly. Is it missing an "If" at
the beginning?

> +unsigned long gcs_alloc_thread_stack(struct task_struct *tsk,
> +				     const struct kernel_clone_args *args)
> +{
> +	unsigned long addr, size, gcspr_el0;
> +
> +	/* If the user specified a GCS use it. */
> +	if (args->shadow_stack_size) {
> +		if (!system_supports_gcs())
> +			return (unsigned long)ERR_PTR(-EINVAL);
> +
> +		addr = args->shadow_stack;
> +		size = args->shadow_stack_size;
> +
> +		/*
> +		 * There should be a token, there might be an end of
> +		 * stack marker.
> +		 */
> +		gcspr_el0 = addr + size - (2 * sizeof(u64));
> +		if (!gcs_consume_token(tsk, gcspr_el0)) {

Should this code validate the end of stack marker? Or doesn't it matter
whether the marker is correct or not?

> +			gcspr_el0 += sizeof(u64);
> +			if (!gcs_consume_token(tsk, gcspr_el0))
> +				return (unsigned long)ERR_PTR(-EINVAL);
> +		}
> +
> +		/* Userspace is responsible for unmapping */
> +		tsk->thread.gcspr_el0 = gcspr_el0 + sizeof(u64);
> +	} else {

-- 
Thiago


From sjg at chromium.org  Mon Feb 19 18:03:13 2024
From: sjg at chromium.org (Simon Glass)
Date: Mon, 19 Feb 2024 19:03:13 -0700
Subject: [PATCH v10 2/2] arm64: boot: Support Flat Image Tree
In-Reply-To: <20240202173034.221790-3-sjg@chromium.org>
References: <20240202173034.221790-1-sjg@chromium.org> <20240202173034.221790-3-sjg@chromium.org>
Message-ID: <CAFLszThi29VCh2rKzvouW6rSpLq5E=uOzWLASO2-CE3Jw_1NUA@mail.gmail.com>

Hi,

On Fri, 2 Feb 2024 at 10:30, Simon Glass <sjg at chromium.org> wrote:
>
> Add a script which produces a Flat Image Tree (FIT), a single file
> containing the built kernel and associated devicetree files.
> Compression defaults to gzip which gives a good balance of size and
> performance.
>
> The files compress from about 86MB to 24MB using this approach.
>
> The FIT can be used by bootloaders which support it, such as U-Boot
> and Linuxboot. It permits automatic selection of the correct
> devicetree, matching the compatible string of the running board with
> the closest compatible string in the FIT. There is no need for
> filenames or other workarounds.
>
> Add a 'make image.fit' build target for arm64, as well.
>
> The FIT can be examined using 'dumpimage -l'.
>
> This uses the 'dtbs-list' file but processes only .dtb files, ignoring
> the overlay .dtbo files.
>
> This features requires pylibfdt (use 'pip install libfdt'). It also
> requires compression utilities for the algorithm being used. Supported
> compression options are the same as the Image.xxx files. Use
> FIT_COMPRESSION to select an algorithm other than gzip.
>
> While FIT supports a ramdisk / initrd, no attempt is made to support
> this here, since it must be built separately from the Linux build.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> Changes in v10:
> - Make use of dtbs-list file
> - Mention dtbs-list and FIT_COMPRESSION
> - Update copyright year
> - Update cover letter to take account of an applied patch
>

Is there any news on this patch, please?

Regards,
Simon


From thiago.bauermann at linaro.org  Mon Feb 19 18:03:46 2024
From: thiago.bauermann at linaro.org (Thiago Jung Bauermann)
Date: Mon, 19 Feb 2024 23:03:46 -0300
Subject: [PATCH v8 23/38] arm64/signal: Set up and restore the GCS
 context for signal handlers
In-Reply-To: <20240203-arm64-gcs-v8-23-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <20240203-arm64-gcs-v8-23-c9fec77673ef@kernel.org>
Message-ID: <87zfvv7uyl.fsf@linaro.org>


Mark Brown <broonie at kernel.org> writes:

> +#ifdef CONFIG_ARM64_GCS
> +static int gcs_restore_signal(void)
> +{
> +	u64 gcspr_el0, cap;
> +	int ret;
> +
> +	if (!system_supports_gcs())
> +		return 0;
> +
> +	if (!(current->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE))
> +		return 0;
> +
> +	gcspr_el0 = read_sysreg_s(SYS_GCSPR_EL0);
> +
> +	/*
> +	 * GCSPR_EL0 should be pointing at a capped GCS, read the cap...
> +	 */
> +	gcsb_dsync();
> +	ret = copy_from_user(&cap, (__user void*)gcspr_el0, sizeof(cap));
> +	if (ret)
> +		return -EFAULT;
> +
> +	/*
> +	 * ...then check that the cap is the actual GCS before
> +	 * restoring it.
> +	 */
> +	if (!gcs_signal_cap_valid(gcspr_el0, cap))
> +		return -EINVAL;
> +
> +	/* Invalidate the token to prevent reuse */
> +	put_user_gcs(0, (__user void*)gcspr_el0, &ret);
> +	if (ret != 0)
> +		return -EFAULT;

You had mentioned that "ideally we'd be doing a compare and exchange
here to substitute in a zero". Is a compare and exchange not necessary
anymore, or is it just being left for later? In the latter case, a TODO
or FIXME comment mentioning it would be useful here.

> +
> +	current->thread.gcspr_el0 = gcspr_el0 + sizeof(cap);
> +	write_sysreg_s(current->thread.gcspr_el0, SYS_GCSPR_EL0);
> +
> +	return 0;
> +}

-- 
Thiago


From zhi.mao at mediatek.com  Mon Feb 19 18:12:26 2024
From: zhi.mao at mediatek.com (=?utf-8?B?WmhpIE1hbyAo5q+b5pm6KQ==?=)
Date: Tue, 20 Feb 2024 02:12:26 +0000
Subject: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <20240206184542.GE2827@pendragon.ideasonboard.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
	 <20240204061538.2105-3-zhi.mao@mediatek.com>
	 <20240206184542.GE2827@pendragon.ideasonboard.com>
Message-ID: <598f62bbb55157eec1e23dd1dbc307fea3851b21.camel@mediatek.com>

Hi Laurent,

Thanks for your review.


On Tue, 2024-02-06 at 20:45 +0200, Laurent Pinchart wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  Hi Zhi,
> 
> Thank you for the patch.
> 
> On Sun, Feb 04, 2024 at 02:15:38PM +0800, Zhi Mao wrote:
> > Add a V4L2 sub-device driver for Galaxycore GC08A3 image sensor.
> > 
> > Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> > ---
> >  drivers/media/i2c/Kconfig  |   10 +
> >  drivers/media/i2c/Makefile |    1 +
> >  drivers/media/i2c/gc08a3.c | 1448
> ++++++++++++++++++++++++++++++++++++
> >  3 files changed, 1459 insertions(+)
> >  create mode 100644 drivers/media/i2c/gc08a3.c
> > 
> > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > index 56f276b920ab..e4da68835683 100644
> > --- a/drivers/media/i2c/Kconfig
> > +++ b/drivers/media/i2c/Kconfig
> > @@ -70,6 +70,16 @@ config VIDEO_GC0308
> >    To compile this driver as a module, choose M here: the
> >    module will be called gc0308.
> >  
> > +config VIDEO_GC08A3
> > +tristate "GalaxyCore gc08a3 sensor support"
> > +select V4L2_CCI_I2C
> > +help
> > +  This is a Video4Linux2 sensor driver for the GalaxyCore gc08a3
> > +  camera.
> > +
> > +  To compile this driver as a module, choose M here: the
> > +  module will be called gc08a3.
> > +
> >  config VIDEO_GC2145
> >  select V4L2_CCI_I2C
> >  tristate "GalaxyCore GC2145 sensor support"
> > diff --git a/drivers/media/i2c/Makefile
> b/drivers/media/i2c/Makefile
> > index dfbe6448b549..b82e99ca7578 100644
> > --- a/drivers/media/i2c/Makefile
> > +++ b/drivers/media/i2c/Makefile
> > @@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
> >  obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
> >  obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
> >  obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
> > +obj-$(CONFIG_VIDEO_GC08A3) += gc08a3.o
> >  obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
> >  obj-$(CONFIG_VIDEO_HI556) += hi556.o
> >  obj-$(CONFIG_VIDEO_HI846) += hi846.o
> > diff --git a/drivers/media/i2c/gc08a3.c
> b/drivers/media/i2c/gc08a3.c
> > new file mode 100644
> > index 000000000000..3fc7fffb815c
> > --- /dev/null
> > +++ b/drivers/media/i2c/gc08a3.c
> > @@ -0,0 +1,1448 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * gc08a3.c - gc08a3 sensor driver
> > + *
> > + * Copyright 2023 MediaTek
> > + *
> > + * Zhi Mao <zhi.mao at mediatek.com>
> > + */
> > +
> > +#include <asm/unaligned.h>
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/gpio/consumer.h>
> > +#include <linux/i2c.h>
> > +#include <linux/module.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/regulator/consumer.h>
> > +#include <media/media-entity.h>
> > +#include <media/v4l2-ctrls.h>
> > +#include <media/v4l2-fwnode.h>
> > +#include <media/v4l2-subdev.h>
> > +#include <media/v4l2-cci.h>
> > +#include <media/v4l2-event.h>
> 
> Please sort the headers alphabetically.
> 
fixed in patch:v5.
> > +
> > +#define GC08A3_REG_CHIP_ID CCI_REG16(0x03f0)
> > +#define GC08A3_CHIP_ID 0x08a3
> > +
> > +#define GC08A3_NATIVE_WIDTH 3264
> > +#define GC08A3_NATIVE_HEIGHT 2448
> > +
> > +#define GC08A3_REG_TEST_PATTERN_EN CCI_REG8(0x008c)
> > +#define GC08A3_REG_TEST_PATTERN_IDX CCI_REG8(0x008d)
> > +#define GC08A3_TEST_PATTERN_EN 0x01
> > +
> > +#define GC08A3_STRAEMING_REG CCI_REG8(0x0100)
> 
> s/STRAEMING/STREAMING/
> 
fixed in patch:v5.
> > +
> > +#define GC08A3_DEFAULT_CLK_FREQ 24000000
> > +#define GC08A3_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
> > +#define GC08A3_DATA_LANES 4
> 
> Let's not mix registers and other macros. Please define the register
> and
> register field macros first (sorted by register address in numerical
> order), and then all other macros.
> 
fixed in patch:v5.
> > +
> > +/* for 1920*1080 */
> > +#define GC08A3_LINK_FREQ_207MHZ 207000000ULL
> > +/* for 3264*2448 */
> > +#define GC08A3_LINK_FREQ_336MHZ 336000000ULL
> 
> Use the values directly in the single location where the macros are
> used
> below, and drop the macros.
> 
fixed in patch:v5.
> > +
> > +#define GC08A3_RGB_DEPTH 10
> > +
> > +#define GC08A3_FRAME_LENGTH_REG CCI_REG16(0x0340)
> > +#define GC08A3_VTS_30FPS 2548
> > +#define GC08A3_VTS_30FPS_MIN 2548
> > +#define GC08A3_VTS_60FPS 1276
> > +#define GC08A3_VTS_60FPS_MIN 1276
> 
> These four macros don't improve readability, you can use the values
> directly in the single location where they are used.
> 
fixed in patch:v5.
> > +#define GC08A3_VTS_MAX 0xfff0
> > +
> > +#define GC08A3_HTS_30FPS 3640
> > +#define GC08A3_HTS_60FPS 3640
> 
> Same for these two macros.
> 
fixed in patch:v5.
> > +
> > +#define GC08A3_EXP_REG CCI_REG16(0x0202)
> > +#define GC08A3_EXP_MARGIN 16
> > +#define GC08A3_EXP_MIN 4
> > +#define GC08A3_EXP_STEP 1
> > +
> > +#define GC08A3_FLIP_REG CCI_REG8(0x0101)
> > +#define GC08A3_FLIP_H_MASK 0x1
> 
> BIT(0)
> 
> > +#define GC08A3_FLIP_V_MASK 0x2
> 
> BIT(1)
> 
fixed in patch:v5.
> > +
> > +#define GC08A3_AGAIN_REG CCI_REG16(0x0204)
> > +#define GC08A3_AGAIN_MIN 1024
> > +#define GC08A3_AGAIN_MAX (1024 * 16)
> > +#define GC08A3_AGAIN_STEP 1
> > +
> > +#define GC08A3_MIN_SLEEP_US  2000
> > +#define GC08A3_MAX_SLEEP_US  3000
> > +
> > +static const char *const gc08a3_test_pattern_menu[] = {
> > +"No Pattern", "Solid Black", "Colour Bar", "Solid White",
> > +"Solid Red", "Solid Green", "Solid Blue", "Solid Yellow",
> > +};
> > +
> > +enum {
> > +GC08A3_LINK_FREQ_336MHZ_INDEX,
> > +GC08A3_LINK_FREQ_207MHZ_INDEX,
> 
> The second value is never used, and the first one is used in
> gc08a3_init_controls() only. I would drop both, and pass
> link_freq_menu_items[0] to the to_pixel_rate() function instead of
> passing an index.
> 
fixed in patch:v5.
> > +};
> > +
> > +static const s64 link_freq_menu_items[] = {
> 
> s/link_freq_menu_items/gc08a3_link_freq_menu_items/
> 
> > +GC08A3_LINK_FREQ_336MHZ,
> > +GC08A3_LINK_FREQ_207MHZ,
> > +};
> > +
> > +static const char *const gc08a3_supply_name[] = {
> > +"avdd",
> > +"dvdd",
> > +"dovdd",
> > +};
> > +
> > +struct gc08a3 {
> > +struct device *dev;
> > +struct v4l2_subdev sd;
> > +struct media_pad pad;
> > +struct i2c_client *client;
> 
> Not used, you can drop this field.
> 
fixed in patch:v5.
> > +
> > +struct clk *xclk;
> > +struct regulator_bulk_data
> supplies[ARRAY_SIZE(gc08a3_supply_name)];
> > +struct gpio_desc *reset_gpio;
> > +
> > +struct v4l2_ctrl_handler ctrls;
> > +struct v4l2_ctrl *pixel_rate;
> > +struct v4l2_ctrl *link_freq;
> > +struct v4l2_ctrl *exposure;
> > +struct v4l2_ctrl *vblank;
> > +struct v4l2_ctrl *hblank;
> > +
> > +struct regmap *regmap;
> > +
> > +bool streaming;
> 
> Set but never used, you can drop this field.
> 
fixed in patch:v5.
> > +unsigned long link_freq_bitmap;
> > +
> > +/* Current mode */
> > +const struct gc08a3_mode *cur_mode;
> > +};
> > +
> > +struct gc08a3_reg_list {
> > +u32 num_of_regs;
> > +const struct cci_reg_sequence *regs;
> > +};
> > +
> > +struct gc08a3_link_freq_config {
> > +const struct gc08a3_reg_list reg_list;
> > +};
> > +
> > +static const struct cci_reg_sequence mode_3264x2448[] = {
> > +/* system */
> > +{ CCI_REG8(0x0336), 0x70 },
> > +{ CCI_REG8(0x0383), 0xbb },
> > +{ CCI_REG8(0x0344), 0x00 },
> > +{ CCI_REG8(0x0345), 0x06 },
> > +{ CCI_REG8(0x0346), 0x00 },
> > +{ CCI_REG8(0x0347), 0x04 },
> > +{ CCI_REG8(0x0348), 0x0c },
> > +{ CCI_REG8(0x0349), 0xd0 },
> > +{ CCI_REG8(0x034a), 0x09 },
> > +{ CCI_REG8(0x034b), 0x9c },
> > +{ CCI_REG8(0x0202), 0x09 },
> > +{ CCI_REG8(0x0203), 0x04 },
> > +{ CCI_REG8(0x0340), 0x09 },
> > +{ CCI_REG8(0x0341), 0xf4 },
> > +{ CCI_REG8(0x0342), 0x07 },
> > +{ CCI_REG8(0x0343), 0x1c },
> > +
> > +{ CCI_REG8(0x0226), 0x00 },
> > +{ CCI_REG8(0x0227), 0x28 },
> > +{ CCI_REG8(0x0e38), 0x49 },
> > +{ CCI_REG8(0x0210), 0x13 },
> > +{ CCI_REG8(0x0218), 0x00 },
> > +{ CCI_REG8(0x0241), 0x88 },
> > +{ CCI_REG8(0x0392), 0x60 },
> > +
> > +/* ISP */
> > +{ CCI_REG8(0x00a2), 0x00 },
> > +{ CCI_REG8(0x00a3), 0x00 },
> > +{ CCI_REG8(0x00ab), 0x00 },
> > +{ CCI_REG8(0x00ac), 0x00 },
> > +
> > +/* GAIN */
> > +{ CCI_REG8(0x0204), 0x04 },
> > +{ CCI_REG8(0x0205), 0x00 },
> > +{ CCI_REG8(0x0050), 0x5c },
> > +{ CCI_REG8(0x0051), 0x44 },
> > +
> > +/* out window */
> > +{ CCI_REG8(0x009a), 0x66 },
> > +{ CCI_REG8(0x0351), 0x00 },
> > +{ CCI_REG8(0x0352), 0x06 },
> > +{ CCI_REG8(0x0353), 0x00 },
> > +{ CCI_REG8(0x0354), 0x08 },
> > +{ CCI_REG8(0x034c), 0x0c },
> > +{ CCI_REG8(0x034d), 0xc0 },
> > +{ CCI_REG8(0x034e), 0x09 },
> > +{ CCI_REG8(0x034f), 0x90 },
> > +
> > +/* MIPI */
> > +{ CCI_REG8(0x0114), 0x03 },
> > +{ CCI_REG8(0x0180), 0x65 },
> > +{ CCI_REG8(0x0181), 0xf0 },
> > +{ CCI_REG8(0x0185), 0x01 },
> > +{ CCI_REG8(0x0115), 0x30 },
> > +{ CCI_REG8(0x011b), 0x12 },
> > +{ CCI_REG8(0x011c), 0x12 },
> > +{ CCI_REG8(0x0121), 0x06 },
> > +{ CCI_REG8(0x0122), 0x06 },
> > +{ CCI_REG8(0x0123), 0x15 },
> > +{ CCI_REG8(0x0124), 0x01 },
> > +{ CCI_REG8(0x0125), 0x0b },
> > +{ CCI_REG8(0x0126), 0x08 },
> > +{ CCI_REG8(0x0129), 0x06 },
> > +{ CCI_REG8(0x012a), 0x08 },
> > +{ CCI_REG8(0x012b), 0x08 },
> > +
> > +{ CCI_REG8(0x0a73), 0x60 },
> > +{ CCI_REG8(0x0a70), 0x11 },
> > +{ CCI_REG8(0x0313), 0x80 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> 
> Does this register really need to be written 8 times ? Same below.
> 
fixed in patch:v5.
> > +{ CCI_REG8(0x0a70), 0x00 },
> > +{ CCI_REG8(0x00a4), 0x80 },
> > +{ CCI_REG8(0x0316), 0x01 },
> > +{ CCI_REG8(0x0a67), 0x00 },
> > +{ CCI_REG8(0x0084), 0x10 },
> > +{ CCI_REG8(0x0102), 0x09 },
> > +};
> > +
> > +static const struct cci_reg_sequence mode_1920x1080[] = {
> > +/* system */
> > +{ CCI_REG8(0x0336), 0x45 },
> > +{ CCI_REG8(0x0383), 0x8b },
> > +{ CCI_REG8(0x0344), 0x02 },
> > +{ CCI_REG8(0x0345), 0xa6 },
> > +{ CCI_REG8(0x0346), 0x02 },
> > +{ CCI_REG8(0x0347), 0xb0 },
> > +{ CCI_REG8(0x0348), 0x07 },
> > +{ CCI_REG8(0x0349), 0x90 },
> > +{ CCI_REG8(0x034a), 0x04 },
> > +{ CCI_REG8(0x034b), 0x44 },
> > +{ CCI_REG8(0x0202), 0x03 },
> > +{ CCI_REG8(0x0203), 0x00 },
> > +{ CCI_REG8(0x0340), 0x04 },
> > +{ CCI_REG8(0x0341), 0xfc },
> > +{ CCI_REG8(0x0342), 0x07 },
> > +{ CCI_REG8(0x0343), 0x1c },
> > +{ CCI_REG8(0x0226), 0x00 },
> > +{ CCI_REG8(0x0227), 0x88 },
> > +{ CCI_REG8(0x0e38), 0x49 },
> > +{ CCI_REG8(0x0210), 0x13 },
> > +{ CCI_REG8(0x0218), 0x00 },
> > +{ CCI_REG8(0x0241), 0x88 },
> > +{ CCI_REG8(0x0392), 0x60 },
> > +
> > +/* ISP */
> > +{ CCI_REG8(0x00a2), 0xac },
> > +{ CCI_REG8(0x00a3), 0x02 },
> > +{ CCI_REG8(0x00ab), 0xa0 },
> > +{ CCI_REG8(0x00ac), 0x02 },
> > +
> > +/* GAIN */
> > +{ CCI_REG8(0x0204), 0x04 },
> > +{ CCI_REG8(0x0205), 0x00 },
> > +{ CCI_REG8(0x0050), 0x38 },
> > +{ CCI_REG8(0x0051), 0x20 },
> > +
> > +/* out window */
> > +{ CCI_REG8(0x009a), 0x66 },
> > +{ CCI_REG8(0x0351), 0x00 },
> > +{ CCI_REG8(0x0352), 0x06 },
> > +{ CCI_REG8(0x0353), 0x00 },
> > +{ CCI_REG8(0x0354), 0x08 },
> > +{ CCI_REG8(0x034c), 0x07 },
> > +{ CCI_REG8(0x034d), 0x80 },
> > +{ CCI_REG8(0x034e), 0x04 },
> > +{ CCI_REG8(0x034f), 0x38 },
> > +
> > +/* MIPI */
> > +{ CCI_REG8(0x0114), 0x03 },
> > +{ CCI_REG8(0x0180), 0x65 },
> > +{ CCI_REG8(0x0181), 0xf0 },
> > +{ CCI_REG8(0x0185), 0x01 },
> > +{ CCI_REG8(0x0115), 0x30 },
> > +{ CCI_REG8(0x011b), 0x12 },
> > +{ CCI_REG8(0x011c), 0x12 },
> > +{ CCI_REG8(0x0121), 0x02 },
> > +{ CCI_REG8(0x0122), 0x03 },
> > +{ CCI_REG8(0x0123), 0x0c },
> > +{ CCI_REG8(0x0124), 0x00 },
> > +{ CCI_REG8(0x0125), 0x09 },
> > +{ CCI_REG8(0x0126), 0x06 },
> > +{ CCI_REG8(0x0129), 0x04 },
> > +{ CCI_REG8(0x012a), 0x03 },
> > +{ CCI_REG8(0x012b), 0x06 },
> > +
> > +{ CCI_REG8(0x0a73), 0x60 },
> > +{ CCI_REG8(0x0a70), 0x11 },
> > +{ CCI_REG8(0x0313), 0x80 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0aff), 0x00 },
> > +{ CCI_REG8(0x0a70), 0x00 },
> > +{ CCI_REG8(0x00a4), 0x80 },
> > +{ CCI_REG8(0x0316), 0x01 },
> > +{ CCI_REG8(0x0a67), 0x00 },
> > +{ CCI_REG8(0x0084), 0x10 },
> > +{ CCI_REG8(0x0102), 0x09 },
> > +};
> > +
> > +static const struct cci_reg_sequence mode_table_common[] = {
> > +{ GC08A3_STRAEMING_REG, 0x00 },
> > +/* system */
> > +{ CCI_REG8(0x031c), 0x60 },
> > +{ CCI_REG8(0x0337), 0x04 },
> > +{ CCI_REG8(0x0335), 0x51 },
> > +{ CCI_REG8(0x0336), 0x70 },
> > +{ CCI_REG8(0x0383), 0xbb },
> > +{ CCI_REG8(0x031a), 0x00 },
> > +{ CCI_REG8(0x0321), 0x10 },
> > +{ CCI_REG8(0x0327), 0x03 },
> > +{ CCI_REG8(0x0325), 0x40 },
> > +{ CCI_REG8(0x0326), 0x23 },
> > +{ CCI_REG8(0x0314), 0x11 },
> > +{ CCI_REG8(0x0315), 0xd6 },
> > +{ CCI_REG8(0x0316), 0x01 },
> > +{ CCI_REG8(0x0334), 0x40 },
> > +{ CCI_REG8(0x0324), 0x42 },
> > +{ CCI_REG8(0x031c), 0x00 },
> > +{ CCI_REG8(0x031c), 0x9f },
> > +{ CCI_REG8(0x039a), 0x13 },
> > +{ CCI_REG8(0x0084), 0x30 },
> > +{ CCI_REG8(0x02b3), 0x08 },
> > +{ CCI_REG8(0x0057), 0x0c },
> > +{ CCI_REG8(0x05c3), 0x50 },
> > +{ CCI_REG8(0x0311), 0x90 },
> > +{ CCI_REG8(0x05a0), 0x02 },
> > +{ CCI_REG8(0x0074), 0x0a },
> > +{ CCI_REG8(0x0059), 0x11 },
> > +{ CCI_REG8(0x0070), 0x05 },
> > +{ CCI_REG8(0x0101), 0x00 },
> > +
> > +/* analog */
> > +{ CCI_REG8(0x0344), 0x00 },
> > +{ CCI_REG8(0x0345), 0x06 },
> > +{ CCI_REG8(0x0346), 0x00 },
> > +{ CCI_REG8(0x0347), 0x04 },
> > +{ CCI_REG8(0x0348), 0x0c },
> > +{ CCI_REG8(0x0349), 0xd0 },
> > +{ CCI_REG8(0x034a), 0x09 },
> > +{ CCI_REG8(0x034b), 0x9c },
> > +{ CCI_REG8(0x0202), 0x09 },
> > +{ CCI_REG8(0x0203), 0x04 },
> > +
> > +{ CCI_REG8(0x0219), 0x05 },
> > +{ CCI_REG8(0x0226), 0x00 },
> > +{ CCI_REG8(0x0227), 0x28 },
> > +{ CCI_REG8(0x0e0a), 0x00 },
> > +{ CCI_REG8(0x0e0b), 0x00 },
> > +{ CCI_REG8(0x0e24), 0x04 },
> > +{ CCI_REG8(0x0e25), 0x04 },
> > +{ CCI_REG8(0x0e26), 0x00 },
> > +{ CCI_REG8(0x0e27), 0x10 },
> > +{ CCI_REG8(0x0e01), 0x74 },
> > +{ CCI_REG8(0x0e03), 0x47 },
> > +{ CCI_REG8(0x0e04), 0x33 },
> > +{ CCI_REG8(0x0e05), 0x44 },
> > +{ CCI_REG8(0x0e06), 0x44 },
> > +{ CCI_REG8(0x0e0c), 0x1e },
> > +{ CCI_REG8(0x0e17), 0x3a },
> > +{ CCI_REG8(0x0e18), 0x3c },
> > +{ CCI_REG8(0x0e19), 0x40 },
> > +{ CCI_REG8(0x0e1a), 0x42 },
> > +{ CCI_REG8(0x0e28), 0x21 },
> > +{ CCI_REG8(0x0e2b), 0x68 },
> > +{ CCI_REG8(0x0e2c), 0x0d },
> > +{ CCI_REG8(0x0e2d), 0x08 },
> > +{ CCI_REG8(0x0e34), 0xf4 },
> > +{ CCI_REG8(0x0e35), 0x44 },
> > +{ CCI_REG8(0x0e36), 0x07 },
> > +{ CCI_REG8(0x0e38), 0x49 },
> > +{ CCI_REG8(0x0210), 0x13 },
> > +{ CCI_REG8(0x0218), 0x00 },
> > +{ CCI_REG8(0x0241), 0x88 },
> > +{ CCI_REG8(0x0e32), 0x00 },
> > +{ CCI_REG8(0x0e33), 0x18 },
> > +{ CCI_REG8(0x0e42), 0x03 },
> > +{ CCI_REG8(0x0e43), 0x80 },
> > +{ CCI_REG8(0x0e44), 0x04 },
> > +{ CCI_REG8(0x0e45), 0x00 },
> > +{ CCI_REG8(0x0e4f), 0x04 },
> > +{ CCI_REG8(0x057a), 0x20 },
> > +{ CCI_REG8(0x0381), 0x7c },
> > +{ CCI_REG8(0x0382), 0x9b },
> > +{ CCI_REG8(0x0384), 0xfb },
> > +{ CCI_REG8(0x0389), 0x38 },
> > +{ CCI_REG8(0x038a), 0x03 },
> > +{ CCI_REG8(0x0390), 0x6a },
> > +{ CCI_REG8(0x0391), 0x0b },
> > +{ CCI_REG8(0x0392), 0x60 },
> > +{ CCI_REG8(0x0393), 0xc1 },
> > +{ CCI_REG8(0x0396), 0xff },
> > +{ CCI_REG8(0x0398), 0x62 },
> > +
> > +/* cisctl reset */
> > +{ CCI_REG8(0x031c), 0x80 },
> > +{ CCI_REG8(0x03fe), 0x10 },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x031c), 0x9f },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x031c), 0x80 },
> > +{ CCI_REG8(0x03fe), 0x10 },
> > +{ CCI_REG8(0x03fe), 0x00 },
> > +{ CCI_REG8(0x031c), 0x9f },
> > +{ CCI_REG8(0x0360), 0x01 },
> > +{ CCI_REG8(0x0360), 0x00 },
> > +{ CCI_REG8(0x0316), 0x09 },
> > +{ CCI_REG8(0x0a67), 0x80 },
> > +{ CCI_REG8(0x0313), 0x00 },
> > +{ CCI_REG8(0x0a53), 0x0e },
> > +{ CCI_REG8(0x0a65), 0x17 },
> > +{ CCI_REG8(0x0a68), 0xa1 },
> > +{ CCI_REG8(0x0a58), 0x00 },
> > +{ CCI_REG8(0x0ace), 0x0c },
> > +{ CCI_REG8(0x00a4), 0x00 },
> > +{ CCI_REG8(0x00a5), 0x01 },
> > +{ CCI_REG8(0x00a7), 0x09 },
> > +{ CCI_REG8(0x00a8), 0x9c },
> > +{ CCI_REG8(0x00a9), 0x0c },
> > +{ CCI_REG8(0x00aa), 0xd0 },
> > +{ CCI_REG8(0x0a8a), 0x00 },
> > +{ CCI_REG8(0x0a8b), 0xe0 },
> > +{ CCI_REG8(0x0a8c), 0x13 },
> > +{ CCI_REG8(0x0a8d), 0xe8 },
> > +{ CCI_REG8(0x0a90), 0x0a },
> > +{ CCI_REG8(0x0a91), 0x10 },
> > +{ CCI_REG8(0x0a92), 0xf8 },
> > +{ CCI_REG8(0x0a71), 0xf2 },
> > +{ CCI_REG8(0x0a72), 0x12 },
> > +{ CCI_REG8(0x0a73), 0x64 },
> > +{ CCI_REG8(0x0a75), 0x41 },
> > +{ CCI_REG8(0x0a70), 0x07 },
> > +{ CCI_REG8(0x0313), 0x80 },
> > +
> > +/* ISP */
> > +{ CCI_REG8(0x00a0), 0x01 },
> > +{ CCI_REG8(0x0080), 0xd2 },
> > +{ CCI_REG8(0x0081), 0x3f },
> > +{ CCI_REG8(0x0087), 0x51 },
> > +{ CCI_REG8(0x0089), 0x03 },
> > +{ CCI_REG8(0x009b), 0x40 },
> > +{ CCI_REG8(0x05a0), 0x82 },
> > +{ CCI_REG8(0x05ac), 0x00 },
> > +{ CCI_REG8(0x05ad), 0x01 },
> > +{ CCI_REG8(0x05ae), 0x00 },
> > +{ CCI_REG8(0x0800), 0x0a },
> > +{ CCI_REG8(0x0801), 0x14 },
> > +{ CCI_REG8(0x0802), 0x28 },
> > +{ CCI_REG8(0x0803), 0x34 },
> > +{ CCI_REG8(0x0804), 0x0e },
> > +{ CCI_REG8(0x0805), 0x33 },
> > +{ CCI_REG8(0x0806), 0x03 },
> > +{ CCI_REG8(0x0807), 0x8a },
> > +{ CCI_REG8(0x0808), 0x50 },
> > +{ CCI_REG8(0x0809), 0x00 },
> > +{ CCI_REG8(0x080a), 0x34 },
> > +{ CCI_REG8(0x080b), 0x03 },
> > +{ CCI_REG8(0x080c), 0x26 },
> > +{ CCI_REG8(0x080d), 0x03 },
> > +{ CCI_REG8(0x080e), 0x18 },
> > +{ CCI_REG8(0x080f), 0x03 },
> > +{ CCI_REG8(0x0810), 0x10 },
> > +{ CCI_REG8(0x0811), 0x03 },
> > +{ CCI_REG8(0x0812), 0x00 },
> > +{ CCI_REG8(0x0813), 0x00 },
> > +{ CCI_REG8(0x0814), 0x01 },
> > +{ CCI_REG8(0x0815), 0x00 },
> > +{ CCI_REG8(0x0816), 0x01 },
> > +{ CCI_REG8(0x0817), 0x00 },
> > +{ CCI_REG8(0x0818), 0x00 },
> > +{ CCI_REG8(0x0819), 0x0a },
> > +{ CCI_REG8(0x081a), 0x01 },
> > +{ CCI_REG8(0x081b), 0x6c },
> > +{ CCI_REG8(0x081c), 0x00 },
> > +{ CCI_REG8(0x081d), 0x0b },
> > +{ CCI_REG8(0x081e), 0x02 },
> > +{ CCI_REG8(0x081f), 0x00 },
> > +{ CCI_REG8(0x0820), 0x00 },
> > +{ CCI_REG8(0x0821), 0x0c },
> > +{ CCI_REG8(0x0822), 0x02 },
> > +{ CCI_REG8(0x0823), 0xd9 },
> > +{ CCI_REG8(0x0824), 0x00 },
> > +{ CCI_REG8(0x0825), 0x0d },
> > +{ CCI_REG8(0x0826), 0x03 },
> > +{ CCI_REG8(0x0827), 0xf0 },
> > +{ CCI_REG8(0x0828), 0x00 },
> > +{ CCI_REG8(0x0829), 0x0e },
> > +{ CCI_REG8(0x082a), 0x05 },
> > +{ CCI_REG8(0x082b), 0x94 },
> > +{ CCI_REG8(0x082c), 0x09 },
> > +{ CCI_REG8(0x082d), 0x6e },
> > +{ CCI_REG8(0x082e), 0x07 },
> > +{ CCI_REG8(0x082f), 0xe6 },
> > +{ CCI_REG8(0x0830), 0x10 },
> > +{ CCI_REG8(0x0831), 0x0e },
> > +{ CCI_REG8(0x0832), 0x0b },
> > +{ CCI_REG8(0x0833), 0x2c },
> > +{ CCI_REG8(0x0834), 0x14 },
> > +{ CCI_REG8(0x0835), 0xae },
> > +{ CCI_REG8(0x0836), 0x0f },
> > +{ CCI_REG8(0x0837), 0xc4 },
> > +{ CCI_REG8(0x0838), 0x18 },
> > +{ CCI_REG8(0x0839), 0x0e },
> > +{ CCI_REG8(0x05ac), 0x01 },
> > +{ CCI_REG8(0x059a), 0x00 },
> > +{ CCI_REG8(0x059b), 0x00 },
> > +{ CCI_REG8(0x059c), 0x01 },
> > +{ CCI_REG8(0x0598), 0x00 },
> > +{ CCI_REG8(0x0597), 0x14 },
> > +{ CCI_REG8(0x05ab), 0x09 },
> > +{ CCI_REG8(0x05a4), 0x02 },
> > +{ CCI_REG8(0x05a3), 0x05 },
> > +{ CCI_REG8(0x05a0), 0xc2 },
> > +{ CCI_REG8(0x0207), 0xc4 },
> > +
> > +/* GAIN */
> > +{ CCI_REG8(0x0208), 0x01 },
> > +{ CCI_REG8(0x0209), 0x72 },
> > +{ CCI_REG8(0x0204), 0x04 },
> > +{ CCI_REG8(0x0205), 0x00 },
> > +
> > +{ CCI_REG8(0x0040), 0x22 },
> > +{ CCI_REG8(0x0041), 0x20 },
> > +{ CCI_REG8(0x0043), 0x10 },
> > +{ CCI_REG8(0x0044), 0x00 },
> > +{ CCI_REG8(0x0046), 0x08 },
> > +{ CCI_REG8(0x0047), 0xf0 },
> > +{ CCI_REG8(0x0048), 0x0f },
> > +{ CCI_REG8(0x004b), 0x0f },
> > +{ CCI_REG8(0x004c), 0x00 },
> > +{ CCI_REG8(0x0050), 0x5c },
> > +{ CCI_REG8(0x0051), 0x44 },
> > +{ CCI_REG8(0x005b), 0x03 },
> > +{ CCI_REG8(0x00c0), 0x00 },
> > +{ CCI_REG8(0x00c1), 0x80 },
> > +{ CCI_REG8(0x00c2), 0x31 },
> > +{ CCI_REG8(0x00c3), 0x00 },
> > +{ CCI_REG8(0x0460), 0x04 },
> > +{ CCI_REG8(0x0462), 0x08 },
> > +{ CCI_REG8(0x0464), 0x0e },
> > +{ CCI_REG8(0x0466), 0x0a },
> > +{ CCI_REG8(0x0468), 0x12 },
> > +{ CCI_REG8(0x046a), 0x12 },
> > +{ CCI_REG8(0x046c), 0x10 },
> > +{ CCI_REG8(0x046e), 0x0c },
> > +{ CCI_REG8(0x0461), 0x03 },
> > +{ CCI_REG8(0x0463), 0x03 },
> > +{ CCI_REG8(0x0465), 0x03 },
> > +{ CCI_REG8(0x0467), 0x03 },
> > +{ CCI_REG8(0x0469), 0x04 },
> > +{ CCI_REG8(0x046b), 0x04 },
> > +{ CCI_REG8(0x046d), 0x04 },
> > +{ CCI_REG8(0x046f), 0x04 },
> > +{ CCI_REG8(0x0470), 0x04 },
> > +{ CCI_REG8(0x0472), 0x10 },
> > +{ CCI_REG8(0x0474), 0x26 },
> > +{ CCI_REG8(0x0476), 0x38 },
> > +{ CCI_REG8(0x0478), 0x20 },
> > +{ CCI_REG8(0x047a), 0x30 },
> > +{ CCI_REG8(0x047c), 0x38 },
> > +{ CCI_REG8(0x047e), 0x60 },
> > +{ CCI_REG8(0x0471), 0x05 },
> > +{ CCI_REG8(0x0473), 0x05 },
> > +{ CCI_REG8(0x0475), 0x05 },
> > +{ CCI_REG8(0x0477), 0x05 },
> > +{ CCI_REG8(0x0479), 0x04 },
> > +{ CCI_REG8(0x047b), 0x04 },
> > +{ CCI_REG8(0x047d), 0x04 },
> > +{ CCI_REG8(0x047f), 0x04 },
> > +};
> > +
> > +static const struct gc08a3_link_freq_config
> gc08a3_link_freq_336m_configs = {
> > +.reg_list = {
> > +.num_of_regs = ARRAY_SIZE(mode_table_common),
> > +.regs = mode_table_common,
> > +}
> > +};
> > +
> > +static const struct gc08a3_link_freq_config
> gc08a3_link_freq_207m_configs = {
> > +.reg_list = {
> > +.num_of_regs = ARRAY_SIZE(mode_table_common),
> > +.regs = mode_table_common,
> > +}
> > +};
> 
> The registers are the same for both, so I think you can simplify this
> and drop the gc08a3_link_freq_config structure.
> 
fixed in patch:v5.
> > +
> > +struct gc08a3_mode {
> > +u32 width;
> > +u32 height;
> > +const struct gc08a3_reg_list reg_list;
> > +
> > +u32 hts; /* Horizontal timining size */
> > +u32 vts_def; /* Default vertical timining size */
> > +u32 vts_min; /* Min vertical timining size */
> > +u32 max_framerate;
> > +const struct gc08a3_link_freq_config *link_freq_configs;
> > +};
> > +
> > +/*
> > + * Declare modes in order, from biggest
> > + * to smallest height.
> > + */
> > +static const struct gc08a3_mode gc08a3_modes[] = {
> > +{
> > +.width = GC08A3_NATIVE_WIDTH,
> > +.height = GC08A3_NATIVE_HEIGHT,
> > +.reg_list = {
> > +.num_of_regs = ARRAY_SIZE(mode_3264x2448),
> > +.regs = mode_3264x2448,
> > +},
> > +.link_freq_configs = &gc08a3_link_freq_336m_configs,
> > +
> > +.hts = GC08A3_HTS_30FPS,
> > +.vts_def = GC08A3_VTS_30FPS,
> > +.vts_min = GC08A3_VTS_30FPS_MIN,
> > +.max_framerate = 300,
> > +},
> > +{
> > +.width = 1920,
> > +.height = 1080,
> > +.reg_list = {
> > +.num_of_regs = ARRAY_SIZE(mode_1920x1080),
> > +.regs = mode_1920x1080,
> > +},
> > +.link_freq_configs = &gc08a3_link_freq_207m_configs,
> > +
> > +.hts = GC08A3_HTS_60FPS,
> > +.vts_def = GC08A3_VTS_60FPS,
> > +.vts_min = GC08A3_VTS_60FPS_MIN,
> > +.max_framerate = 600,
> > +},
> > +};
> > +
> > +static u64 to_pixel_rate(u32 f_index)
> 
> Move this function just before gc08a3_init_controls() where it is
> used,
> and rename it with a gc08a3_ prefix.
> 
fixed in patch:v5.
> > +{
> > +u64 pixel_rate = link_freq_menu_items[f_index] * 2 *
> GC08A3_DATA_LANES;
> > +
> > +do_div(pixel_rate, GC08A3_RGB_DEPTH);
> > +
> > +return pixel_rate;
> > +}
> > +
> > +static int gc08a3_identify_module(struct gc08a3 *gc08a3)
> 
> I would also move this down, before the probe function.
> 
fixed in patch:v5.
> > +{
> > +struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
> > +u64 val = 0;
> 
> No need to initialize val to 0.
> 
fixed in patch:v5.
> > +int ret;
> > +
> > +ret = cci_read(gc08a3->regmap, GC08A3_REG_CHIP_ID, &val, NULL);
> > +if (ret) {
> > +dev_err(&client->dev,
> 
> Use gc08a3->dev and drop the local client variable.
> 
fixed in patch:v5.
> > +"failed to read chip id: 0x%x", GC08A3_CHIP_ID);
> 
> "failed to read chip id\n");
> 
> Printing GC08A3_CHIP_ID isn't useful.
> 
fixed in patch:v5.
> > +return ret;
> > +}
> > +
> > +if (val != GC08A3_CHIP_ID) {
> > +dev_err(&client->dev, "chip id mismatch: 0x%x!=0x%llx",
> > +GC08A3_CHIP_ID, val);
> > +return -ENXIO;
> > +}
> > +
> > +return 0;
> > +}
> > +
> > +static inline struct gc08a3 *to_gc08a3(struct v4l2_subdev *sd)
> > +{
> > +return container_of(sd, struct gc08a3, sd);
> > +}
> > +
> > +static int gc08a3_power_on(struct device *dev)
> > +{
> > +struct i2c_client *client = to_i2c_client(dev);
> > +struct v4l2_subdev *sd = i2c_get_clientdata(client);
> 
> You can use
> 
> struct v4l2_subdev *sd = dev_get_drvdata(dev);
> 
> Same below.
> 
fixed in patch:v5.
> > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +int ret;
> > +
> > +ret = regulator_bulk_enable(ARRAY_SIZE(gc08a3_supply_name),
> > +    gc08a3->supplies);
> > +if (ret < 0) {
> > +dev_err(gc08a3->dev, "failed to enable regulators: %d\n", ret);
> > +return ret;
> > +}
> > +
> > +ret = clk_prepare_enable(gc08a3->xclk);
> > +if (ret < 0) {
> > +regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
> > +       gc08a3->supplies);
> > +dev_err(gc08a3->dev, "clk prepare enable failed\n");
> > +return ret;
> > +}
> > +
> > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> 
> fsleep() is a good candidate to replace the usleep_range() calls.
> 
fixed in patch:v5.
> > +
> > +gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> 
> Are you asserting reset when powering on ? That sounds wrong, you
> should
> de-assert reset here (and acquire the reset gpio in probe() with
> GPIOD_OUT_HIGH). Drivers should use logical levels for GPIOs, setting
> a
> GPIO named "reset" to 1 should assert the reset signal, even if the
> physical signal is active low. You may have the wrong polarity in the
> device tree.
> 
According to the sensor power sequence sepc, "reset" pin should be pull
from low to high after "dovdd/dvdd/avdd" power on, so I follow this
power sequece to pull "reset" pin high in software flow.

> > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_power_off(struct device *dev)
> > +{
> > +struct i2c_client *client = to_i2c_client(dev);
> > +struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +
> > +clk_disable_unprepare(gc08a3->xclk);
> > +
> > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > +
> > +gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);
> > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > +
> > +regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
> > +       gc08a3->supplies);
> > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> 
> Do you need all those sleeps, especially the last one ?
> 
fixed in patch:v5.
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_enum_mbus_code(struct v4l2_subdev *sd,
> > + struct v4l2_subdev_state *sd_state,
> > + struct v4l2_subdev_mbus_code_enum *code)
> > +{
> > +if (code->index > 0)
> > +return -EINVAL;
> > +
> > +code->code = GC08A3_MBUS_CODE;
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_enum_frame_size(struct v4l2_subdev *subdev,
> > +  struct v4l2_subdev_state *sd_state,
> > +  struct v4l2_subdev_frame_size_enum *fse)
> > +{
> > +if (fse->code != GC08A3_MBUS_CODE)
> > +return -EINVAL;
> > +
> > +if (fse->index >= ARRAY_SIZE(gc08a3_modes))
> > +return -EINVAL;
> > +
> > +fse->min_width = gc08a3_modes[fse->index].width;
> > +fse->max_width = gc08a3_modes[fse->index].width;
> > +fse->min_height = gc08a3_modes[fse->index].height;
> > +fse->max_height = gc08a3_modes[fse->index].height;
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_update_cur_mode_controls(struct gc08a3 *gc08a3,
> > +   const struct gc08a3_mode *mode)
> > +{
> > +s64 exposure_max, h_blank;
> > +int ret = 0;
> > +
> > +ret = __v4l2_ctrl_modify_range(gc08a3->vblank,
> > +       mode->vts_min - mode->height,
> > +       GC08A3_VTS_MAX - mode->height, 1,
> > +       mode->vts_def - mode->height);
> > +if (ret)
> > +dev_err(gc08a3->dev, "VB ctrl range update failed\n");
> 
> return ret;
> }
> 
> Same below.
> 
fixed in patch:v5.

> > +
> > +h_blank = mode->hts - mode->width;
> > +ret = __v4l2_ctrl_modify_range(gc08a3->hblank, h_blank, h_blank,
> 1,
> > +       h_blank);
> > +if (ret)
> > +dev_err(gc08a3->dev, "HB ctrl range update failed\n");
> > +
> > +exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
> > +ret = __v4l2_ctrl_modify_range(gc08a3->exposure, GC08A3_EXP_MIN,
> > +       exposure_max, GC08A3_EXP_STEP,
> > +       exposure_max);
> > +if (ret)
> > +dev_err(gc08a3->dev, "exposure ctrl range update failed\n");
> > +
> > +return ret;
> > +}
> > +
> > +static void gc08a3_update_pad_format(struct gc08a3 *gc08a3,
> > +     const struct gc08a3_mode *mode,
> > +     struct v4l2_mbus_framefmt *fmt)
> > +{
> > +fmt->width = mode->width;
> > +fmt->height = mode->height;
> > +fmt->code = GC08A3_MBUS_CODE;
> > +fmt->field = V4L2_FIELD_NONE;
> > +fmt->colorspace = V4L2_COLORSPACE_SRGB;
> 
> It's a raw sensor, isn't V4L2_COLORSPACE_RAW more appropriate, or
> does
> the sensor really use the sRGB primaries ?
> 
fixed in patch:v5.

> > +fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
> > +fmt->quantization =
> > +V4L2_MAP_QUANTIZATION_DEFAULT(true,
> > +      fmt->colorspace,
> > +      fmt->ycbcr_enc);
> 
> I think you can write
> 
> fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
> 
> here, it's more explicit.
> 
> > +fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
> 
> Sensors usually produce linear output, V4L2_XFER_FUNC_NONE is likely
> what you need here.
> 
fixed in patch:v5.

> > +}
> > +
> > +static int gc08a3_set_format(struct v4l2_subdev *sd,
> > +     struct v4l2_subdev_state *state,
> > +     struct v4l2_subdev_format *fmt)
> > +{
> > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +struct v4l2_mbus_framefmt *mbus_fmt;
> > +struct v4l2_rect *crop;
> > +const struct gc08a3_mode *mode;
> > +
> > +mode = v4l2_find_nearest_size(gc08a3_modes,
> ARRAY_SIZE(gc08a3_modes),
> > +      width, height, fmt->format.width,
> > +      fmt->format.height);
> > +
> > +/*update crop info to subdev state*/
> 
> Missing spaces after /* and before */. Same below.
> 
fixed in patch:v5.

> > +crop = v4l2_subdev_state_get_crop(state, 0);
> > +crop->width = mode->width;
> > +crop->height = mode->height;
> > +
> > +/*update fmt info to subdev state*/
> > +gc08a3_update_pad_format(gc08a3, mode, &fmt->format);
> > +mbus_fmt = v4l2_subdev_state_get_format(state, 0);
> > +*mbus_fmt = fmt->format;
> > +
> > +if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
> > +return 0;
> > +
> > +gc08a3->cur_mode = mode;
> > +gc08a3_update_cur_mode_controls(gc08a3, mode);
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_get_selection(struct v4l2_subdev *sd,
> > +struct v4l2_subdev_state *state,
> > +struct v4l2_subdev_selection *sel)
> > +{
> > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +
> > +switch (sel->target) {
> > +case V4L2_SEL_TGT_CROP:
> > +sel->r = *v4l2_subdev_state_get_crop(state, 0);
> > +break;
> > +case V4L2_SEL_TGT_CROP_BOUNDS:
> > +sel->r.top = 0;
> > +sel->r.left = 0;
> > +sel->r.width = GC08A3_NATIVE_WIDTH;
> > +sel->r.height = GC08A3_NATIVE_HEIGHT;
> > +break;
> > +case V4L2_SEL_TGT_CROP_DEFAULT:
> > +if (gc08a3->cur_mode->width == GC08A3_NATIVE_WIDTH) {
> > +sel->r.top = 0;
> > +sel->r.left = 0;
> > +sel->r.width = gc08a3_modes[0].width;
> > +sel->r.height = gc08a3_modes[0].height;
> > +} else {
> > +sel->r.top = 0;
> > +sel->r.left = 0;
> > +sel->r.width = gc08a3_modes[1].width;
> > +sel->r.height = gc08a3_modes[1].height;
> > +}
> 
> You store the crop rectangle in the gc08a3_set_format() function, you
> can simplify this with
> 
> sel->r = *v4l2_subdev_state_get_crop(state, 0);
> 
fixed in patch:v5.
> > +break;
> > +default:
> > +return -EINVAL;
> > +}
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_init_state(struct v4l2_subdev *sd,
> > +     struct v4l2_subdev_state *state)
> > +{
> > +struct v4l2_subdev_format fmt = {
> > +.which = V4L2_SUBDEV_FORMAT_TRY,
> > +.pad = 0,
> > +.format = {
> > +.code = GC08A3_MBUS_CODE,
> > +.width = gc08a3_modes[0].width,
> > +.height = gc08a3_modes[0].height,
> > +},
> > +};
> > +
> > +gc08a3_set_format(sd, state, &fmt);
> > +
> > +return 0;
> > +}
> > +
> > +static int gc08a3_set_ctrl_hflip(struct gc08a3 *gc08a3, u32
> ctrl_val)
> > +{
> > +int ret;
> > +u64 val;
> > +
> > +ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
> > +if (ret) {
> > +dev_err(gc08a3->dev, "read hflip register failed: %d\n", ret);
> > +return ret;
> > +}
> > +
> > +val = ctrl_val ? (val | GC08A3_FLIP_H_MASK) :
> > +   (val & ~GC08A3_FLIP_H_MASK);
> > +ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
> > +if (ret < 0)
> > +dev_err(gc08a3->dev, "Error %d\n", ret);
> 
> You can use cci_update_bits()
> 
> return cci_update_bits(gc08a3->regmap, GC08A3_FLIP_REG,
>        GC08A3_FLIP_H_MASK,
>        ctrl_val ? GC08A3_FLIP_H_MASK : 0, NULL);
> 
> Same below.
> 
fixed in patch:v5.
> > +
> > +return ret;
> > +}
> > +
> > +static int gc08a3_set_ctrl_vflip(struct gc08a3 *gc08a3, u32
> ctrl_val)
> > +{
> > +int ret;
> > +u64 val;
> > +
> > +ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
> > +if (ret) {
> > +dev_err(gc08a3->dev, "read vflip register failed: %d\n", ret);
> > +return ret;
> > +}
> > +
> > +val = ctrl_val ? (val | GC08A3_FLIP_V_MASK) :
> > +   (val & ~GC08A3_FLIP_V_MASK);
> > +ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
> > +if (ret < 0)
> > +dev_err(gc08a3->dev, "Error %d\n", ret);
> > +
> > +return ret;
> > +}
> > +
> > +static int gc08a3_test_pattern(struct gc08a3 *gc08a3, u32
> pattern_menu)
> > +{
> > +u32 pattern = 0;
> > +int ret;
> 
> int ret = 0;
> 
According to Mr.Angelo's comments, I modified this function in
patch:v5.
> > +
> > +if (pattern_menu) {
> > +switch (pattern_menu) {
> > +case 1:
> > +pattern = 0x00;
> > +break;
> > +case 2:
> > +pattern = 0x10;
> > +break;
> > +case 3:
> > +case 4:
> > +case 5:
> > +case 6:
> > +case 7:
> > +pattern = pattern_menu + 1;
> > +break;
> > +}
> > +
> > +ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
> > +GC08A3_TEST_PATTERN_EN, NULL);
> > +if (ret)
> > +return ret;
> > +
> > +ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_IDX,
> > +pattern, NULL);
> > +
> 
> cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
>   GC08A3_TEST_PATTERN_EN, &ret);
> cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_IDX,
>   pattern, &ret);
> 
> And unless the sensor requires writing the GC08A3_REG_TEST_PATTERN_EN
> register first, I would write the test pattern index first, to avoid
> generating one frame with the wrong pattern.
> 
fixed in patch:v5.
> > +} else {
> > +ret = cci_write(gc08a3->regmap, GC08A3_REG_TEST_PATTERN_EN,
> > +0x00, NULL);
> > +}
> > +
> > +return ret;
> > +}
> > +
> > +static int gc08a3_set_ctrl(struct v4l2_ctrl *ctrl)
> > +{
> > +struct gc08a3 *gc08a3 =
> > +container_of(ctrl->handler, struct gc08a3, ctrls);
> > +int ret = 0;
> > +s64 exposure_max;
> > +
> > +if (ctrl->id == V4L2_CID_VBLANK) {
> > +/* Update max exposure while meeting expected vblanking */
> > +exposure_max = gc08a3->cur_mode->height + ctrl->val -
> > +       GC08A3_EXP_MARGIN;
> 
> Let's not use cur_mode here, but retrieve the height from the state.
> This makes the driver implementation less dependent on the modes,
> paving
> the way to make the sensor fully configurable. You can look at the
> imx219 driver for an example.
> 
fixed in patch:v5.
> > +__v4l2_ctrl_modify_range(gc08a3->exposure,
> > + gc08a3->exposure->minimum,
> > + exposure_max, gc08a3->exposure->step,
> > + exposure_max);
> > +}
> > +
> > +/*
> > + * Applying V4L2 control value only happens
> > + * when power is on for streaming
> > + */
> > +if (!pm_runtime_get_if_in_use(gc08a3->dev))
> > +return 0;
> > +
> > +switch (ctrl->id) {
> > +case V4L2_CID_EXPOSURE:
> > +ret = cci_write(gc08a3->regmap, GC08A3_EXP_REG,
> > +ctrl->val, NULL);
> > +break;
> > +
> > +case V4L2_CID_ANALOGUE_GAIN:
> > +ret = cci_write(gc08a3->regmap, GC08A3_AGAIN_REG,
> > +ctrl->val, NULL);
> > +break;
> > +
> > +case V4L2_CID_VBLANK:
> > +ret = cci_write(gc08a3->regmap, GC08A3_FRAME_LENGTH_REG,
> > +gc08a3->cur_mode->height + ctrl->val, NULL);
> > +break;
> > +
> > +case V4L2_CID_HFLIP:
> > +ret = gc08a3_set_ctrl_hflip(gc08a3, ctrl->val);
> > +break;
> > +
> > +case V4L2_CID_VFLIP:
> > +ret = gc08a3_set_ctrl_vflip(gc08a3, ctrl->val);
> > +break;
> > +
> > +case V4L2_CID_TEST_PATTERN:
> > +ret = gc08a3_test_pattern(gc08a3, ctrl->val);
> > +break;
> > +
> > +default:
> > +break;
> > +}
> > +
> > +pm_runtime_put(gc08a3->dev);
> > +
> > +return ret;
> > +}
> > +
> > +static const struct v4l2_ctrl_ops gc08a3_ctrl_ops = {
> > +.s_ctrl = gc08a3_set_ctrl,
> > +};
> > +
> > +static int gc08a3_start_streaming(struct gc08a3 *gc08a3)
> > +{
> > +const struct gc08a3_mode *mode;
> > +const struct gc08a3_reg_list *reg_list;
> > +const struct gc08a3_link_freq_config *link_freq_cfg;
> > +int ret;
> > +
> > +ret = pm_runtime_resume_and_get(gc08a3->dev);
> > +if (ret < 0)
> > +return ret;
> > +
> > +link_freq_cfg = gc08a3->cur_mode->link_freq_configs;
> > +
> > +reg_list = &link_freq_cfg->reg_list;
> > +ret = cci_multi_reg_write(gc08a3->regmap,
> > +  reg_list->regs, reg_list->num_of_regs, NULL);
> > +if (ret) {
> > +dev_err(gc08a3->dev, "could not sent common table %d\n", ret);
> 
> The cci helpers already write error messages, I think you can drop
> this
> one, as well as similar messages below.
> 
fixed in patch:v5.
> > +goto err_rpm_put;
> > +}
> > +
> > +mode = gc08a3->cur_mode;
> > +reg_list = &mode->reg_list;
> > +ret = cci_multi_reg_write(gc08a3->regmap,
> > +  reg_list->regs, reg_list->num_of_regs, NULL);
> > +if (ret < 0) {
> > +dev_err(gc08a3->dev, "could not sent mode table %d\n", ret);
> > +goto err_rpm_put;
> > +}
> > +
> > +ret = __v4l2_ctrl_handler_setup(&gc08a3->ctrls);
> > +if (ret < 0) {
> > +dev_err(gc08a3->dev, "could not sync v4l2 controls\n");
> > +goto err_rpm_put;
> > +}
> > +
> > +ret = cci_write(gc08a3->regmap, GC08A3_STRAEMING_REG, 1, NULL);
> > +if (ret < 0) {
> > +dev_err(gc08a3->dev, "write STRAEMING_REG failed: %d\n", ret);
> > +goto err_rpm_put;
> > +}
> > +
> > +return 0;
> > +
> > +err_rpm_put:
> > +pm_runtime_put(gc08a3->dev);
> > +return ret;
> > +}
> > +
> > +static int gc08a3_stop_streaming(struct gc08a3 *gc08a3)
> > +{
> > +int ret;
> > +
> > +ret = cci_write(gc08a3->regmap, GC08A3_STRAEMING_REG, 0, NULL);
> > +if (ret < 0)
> > +dev_err(gc08a3->dev, "could not sent stop streaming %d\n", ret);
> > +
> > +pm_runtime_put(gc08a3->dev);
> > +return ret;
> > +}
> > +
> > +static int gc08a3_s_stream(struct v4l2_subdev *subdev, int enable)
> > +{
> > +struct gc08a3 *gc08a3 = to_gc08a3(subdev);
> > +struct v4l2_subdev_state *state;
> > +int ret;
> > +
> > +state = v4l2_subdev_lock_and_get_active_state(subdev);
> > +
> > +if (enable)
> > +ret = gc08a3_start_streaming(gc08a3);
> > +else
> > +ret = gc08a3_stop_streaming(gc08a3);
> > +
> > +gc08a3->streaming = enable;
> > +v4l2_subdev_unlock_state(state);
> > +
> > +return ret;
> > +}
> > +
> > +static int
> > +gc08a3_enum_frame_interval(struct v4l2_subdev *subdev,
> > +   struct v4l2_subdev_state *sd_state,
> > +   struct v4l2_subdev_frame_interval_enum *fie)
> 
> Frame intervals on sensors should be controlled through the pixel
> rate
> and blanking. You can drop this function, as well as the
> gc08a3_mode.max_framerate field.
> 
fixed in patch:v5.
> > +{
> > +unsigned int index = fie->index;
> > +unsigned int i;
> > +
> > +for (i = 0; i < ARRAY_SIZE(gc08a3_modes); i++) {
> > +if (fie->width != gc08a3_modes[i].width ||
> > +    fie->height != gc08a3_modes[i].height)
> > +continue;
> > +
> > +if (index-- == 0) {
> > +fie->interval.numerator = 1;
> > +fie->interval.denominator =
> > +gc08a3_modes[i].max_framerate / 10;
> > +return 0;
> > +}
> > +}
> > +
> > +return -EINVAL;
> > +}
> > +
> > +static const struct v4l2_subdev_video_ops gc08a3_video_ops = {
> > +.s_stream = gc08a3_s_stream,
> > +};
> > +
> > +static const struct v4l2_subdev_pad_ops gc08a3_subdev_pad_ops = {
> > +.enum_mbus_code = gc08a3_enum_mbus_code,
> > +.enum_frame_size = gc08a3_enum_frame_size,
> > +.enum_frame_interval = gc08a3_enum_frame_interval,
> > +.get_fmt = v4l2_subdev_get_fmt,
> > +.set_fmt = gc08a3_set_format,
> > +.get_selection = gc08a3_get_selection,
> > +};
> > +
> > +static const struct v4l2_subdev_core_ops gc08a3_core_ops = {
> > +.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> > +.unsubscribe_event = v4l2_event_subdev_unsubscribe,
> > +};
> > +
> > +static const struct v4l2_subdev_ops gc08a3_subdev_ops = {
> > +.core = &gc08a3_core_ops,
> > +.video = &gc08a3_video_ops,
> > +.pad = &gc08a3_subdev_pad_ops,
> > +};
> > +
> > +static const struct v4l2_subdev_internal_ops gc08a3_internal_ops =
> {
> > +.init_state = gc08a3_init_state,
> > +};
> > +
> > +static int gc08a3_get_regulators(struct device *dev, struct gc08a3
> *gc08a3)
> > +{
> > +unsigned int i;
> > +
> > +for (i = 0; i < ARRAY_SIZE(gc08a3_supply_name); i++)
> > +gc08a3->supplies[i].supply = gc08a3_supply_name[i];
> > +
> > +return devm_regulator_bulk_get(dev,
> ARRAY_SIZE(gc08a3_supply_name),
> > +       gc08a3->supplies);
> > +}
> > +
> > +static int gc08a3_parse_fwnode(struct device *dev, struct gc08a3
> *gc08a3)
> 
> You can drop the first argument and use gc08a3->dev instead.
> 
fixed in patch:v5.
> > +{
> > +struct fwnode_handle *endpoint;
> > +struct v4l2_fwnode_endpoint bus_cfg = {
> > +.bus_type = V4L2_MBUS_CSI2_DPHY,
> > +};
> > +int ret;
> > +
> > +endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
> 
> Please use
> 
> endpoint = fwnode_graph_get_endpoint_by_id(dev_fwnode(gc08a3->dev),
>    0, 0,
>    FWNODE_GRAPH_ENDPOINT_NEXT);
> 
fixed in patch:v5.

> > +if (!endpoint) {
> > +dev_err(dev, "endpoint node not found\n");
> > +return -EINVAL;
> > +}
> > +
> > +ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
> > +if (ret) {
> > +dev_err(dev, "parsing endpoint node failed\n");
> > +goto done;
> > +}
> > +
> > +ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
> > +       bus_cfg.nr_of_link_frequencies,
> > +       link_freq_menu_items,
> > +       ARRAY_SIZE(link_freq_menu_items),
> > +       &gc08a3->link_freq_bitmap);
> > +if (ret)
> > +goto done;
> > +
> > +done:
> > +v4l2_fwnode_endpoint_free(&bus_cfg);
> > +fwnode_handle_put(endpoint);
> > +return ret;
> > +}
> > +
> > +static int gc08a3_init_controls(struct gc08a3 *gc08a3)
> > +{
> > +struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
> > +const struct gc08a3_mode *mode = &gc08a3_modes[0];
> > +const struct v4l2_ctrl_ops *ops = &gc08a3_ctrl_ops;
> > +struct v4l2_fwnode_device_properties props;
> > +struct v4l2_ctrl_handler *ctrl_hdlr;
> > +s64 exposure_max, h_blank;
> > +int ret;
> > +
> > +ctrl_hdlr = &gc08a3->ctrls;
> > +ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
> > +if (ret)
> > +return ret;
> > +
> > +gc08a3->link_freq =
> > +v4l2_ctrl_new_int_menu(ctrl_hdlr,
> > +       &gc08a3_ctrl_ops,
> > +       V4L2_CID_LINK_FREQ,
> > +       ARRAY_SIZE(link_freq_menu_items) - 1,
> > +       0, link_freq_menu_items);
> > +if (gc08a3->link_freq)
> > +gc08a3->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > +gc08a3->pixel_rate =
> > +v4l2_ctrl_new_std(ctrl_hdlr,
> > +  &gc08a3_ctrl_ops,
> > +  V4L2_CID_PIXEL_RATE, 0,
> > +  to_pixel_rate(GC08A3_LINK_FREQ_336MHZ_INDEX),
> > +  1,
> > +  to_pixel_rate(GC08A3_LINK_FREQ_336MHZ_INDEX));
> > +
> > +gc08a3->vblank =
> > +v4l2_ctrl_new_std(ctrl_hdlr,
> > +  &gc08a3_ctrl_ops, V4L2_CID_VBLANK,
> > +  mode->vts_min - mode->height,
> > +  GC08A3_VTS_MAX - mode->height, 1,
> > +  mode->vts_def - mode->height);
> > +
> > +h_blank = mode->hts - mode->width;
> > +gc08a3->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
> > +   V4L2_CID_HBLANK, h_blank, h_blank, 1,
> > +   h_blank);
> > +if (gc08a3->hblank)
> > +gc08a3->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > +v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
> > +  V4L2_CID_ANALOGUE_GAIN, GC08A3_AGAIN_MIN,
> > +  GC08A3_AGAIN_MAX, GC08A3_AGAIN_STEP,
> > +  GC08A3_AGAIN_MIN);
> > +
> > +exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
> > +gc08a3->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops,
> > +     V4L2_CID_EXPOSURE, GC08A3_EXP_MIN,
> > +     exposure_max, GC08A3_EXP_STEP,
> > +     exposure_max);
> > +
> > +v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &gc08a3_ctrl_ops,
> > +     V4L2_CID_TEST_PATTERN,
> > +     ARRAY_SIZE(gc08a3_test_pattern_menu) - 1,
> > +     0, 0, gc08a3_test_pattern_menu);
> > +
> > +v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops, V4L2_CID_HFLIP, 0,
> > +  1, 1, 0);
> > +
> > +v4l2_ctrl_new_std(ctrl_hdlr, &gc08a3_ctrl_ops, V4L2_CID_VFLIP, 0,
> > +  1, 1, 0);
> 
> Let's put the HFLIP and VFLIP controls in a cluster to make it
> possible
> to efficiently set them in an atomic operation. See the imx219 driver
> for an example.
> 
fixed in patch:v5.
> > +
> > +/* register properties to fwnode (e.g. rotation, orientation) */
> > +ret = v4l2_fwnode_device_parse(&client->dev, &props);
> > +if (ret)
> > +goto error_ctrls;
> > +
> > +ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, ops, &props);
> > +if (ret)
> > +goto error_ctrls;
> > +
> > +if (ctrl_hdlr->error) {
> > +ret = ctrl_hdlr->error;
> > +goto error_ctrls;
> > +}
> > +
> > +gc08a3->sd.ctrl_handler = ctrl_hdlr;
> > +
> > +return 0;
> > +
> > +error_ctrls:
> > +v4l2_ctrl_handler_free(ctrl_hdlr);
> > +
> > +return ret;
> > +}
> > +
> > +static int gc08a3_probe(struct i2c_client *client)
> > +{
> > +struct device *dev = &client->dev;
> > +struct gc08a3 *gc08a3;
> > +int ret;
> > +
> > +gc08a3 = devm_kzalloc(dev, sizeof(*gc08a3), GFP_KERNEL);
> > +if (!gc08a3)
> > +return -ENOMEM;
> > +
> > +gc08a3->dev = dev;
> > +
> > +ret = gc08a3_parse_fwnode(dev, gc08a3);
> > +if (ret)
> > +return ret;
> > +
> > +gc08a3->regmap = devm_cci_regmap_init_i2c(client, 16);
> > +if (IS_ERR(gc08a3->regmap))
> > +return dev_err_probe(dev, PTR_ERR(gc08a3->regmap),
> > +     "failed to init CCI\n");
> > +
> > +gc08a3->xclk = devm_clk_get(dev, NULL);
> > +if (IS_ERR(gc08a3->xclk))
> > +return dev_err_probe(dev, PTR_ERR(gc08a3->xclk),
> > +     "failed to get xclk\n");
> > +
> > +ret = clk_set_rate(gc08a3->xclk, GC08A3_DEFAULT_CLK_FREQ);
> > +if (ret)
> > +return dev_err_probe(dev, ret,
> > +     "failed to set xclk frequency\n");
> > +
> > +ret = gc08a3_get_regulators(dev, gc08a3);
> > +if (ret < 0)
> > +return dev_err_probe(dev, ret,
> > +     "failed to get regulators\n");
> > +
> > +gc08a3->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> > +if (IS_ERR(gc08a3->reset_gpio))
> > +return dev_err_probe(dev, PTR_ERR(gc08a3->reset_gpio),
> > +     "failed to get gpio\n");
> > +
> > +v4l2_i2c_subdev_init(&gc08a3->sd, client, &gc08a3_subdev_ops);
> > +gc08a3->sd.internal_ops = &gc08a3_internal_ops;
> > +gc08a3->cur_mode = &gc08a3_modes[0];
> > +
> > +ret = gc08a3_power_on(gc08a3->dev);
> > +if (ret)
> > +return dev_err_probe(dev, ret,
> > +     "failed to sensor power on\n");
> > +
> > +ret = gc08a3_identify_module(gc08a3);
> > +if (ret) {
> > +dev_err(&client->dev, "failed to find sensor: %d\n", ret);
> > +goto err_power_off;
> > +}
> > +
> > +ret = gc08a3_init_controls(gc08a3);
> > +if (ret) {
> > +dev_err(&client->dev, "failed to init controls: %d", ret);
> > +goto err_power_off;
> > +}
> > +
> > +gc08a3->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> > +    V4L2_SUBDEV_FL_HAS_EVENTS;
> > +gc08a3->pad.flags = MEDIA_PAD_FL_SOURCE;
> > +gc08a3->sd.dev = &client->dev;
> > +gc08a3->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> > +
> > +ret = media_entity_pads_init(&gc08a3->sd.entity, 1, &gc08a3->pad);
> > +if (ret < 0) {
> > +dev_err(dev, "could not register media entity\n");
> > +goto err_v4l2_ctrl_handler_free;
> > +}
> > +
> > +gc08a3->sd.state_lock = gc08a3->ctrls.lock;
> > +ret = v4l2_subdev_init_finalize(&gc08a3->sd);
> > +if (ret < 0) {
> > +dev_err(dev, "v4l2 subdev init error: %d\n", ret);
> > +goto err_media_entity_cleanup;
> > +}
> > +
> > +pm_runtime_set_active(gc08a3->dev);
> > +pm_runtime_enable(gc08a3->dev);
> > +pm_runtime_idle(gc08a3->dev);
> 
> Could you enable autosuspend ?
> 
fixed in patch:v5.
> > +
> > +ret = v4l2_async_register_subdev_sensor(&gc08a3->sd);
> > +if (ret < 0) {
> > +dev_err(dev, "could not register v4l2 device\n");
> > +goto err_rpm;
> > +}
> > +
> > +return 0;
> > +
> > +err_rpm:
> > +pm_runtime_disable(gc08a3->dev);
> > +v4l2_subdev_cleanup(&gc08a3->sd);
> > +
> > +err_media_entity_cleanup:
> > +media_entity_cleanup(&gc08a3->sd.entity);
> > +
> > +err_v4l2_ctrl_handler_free:
> > +v4l2_ctrl_handler_free(gc08a3->sd.ctrl_handler);
> > +
> > +err_power_off:
> > +gc08a3_power_off(gc08a3->dev);
> > +
> > +return ret;
> > +}
> > +
> > +static void gc08a3_remove(struct i2c_client *client)
> > +{
> > +struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +
> > +v4l2_async_unregister_subdev(&gc08a3->sd);
> > +v4l2_subdev_cleanup(sd);
> > +media_entity_cleanup(&gc08a3->sd.entity);
> > +v4l2_ctrl_handler_free(&gc08a3->ctrls);
> > +
> > +pm_runtime_disable(&client->dev);
> > +if (!pm_runtime_status_suspended(&client->dev))
> > +gc08a3_power_off(gc08a3->dev);
> > +pm_runtime_set_suspended(&client->dev);
> > +}
> > +
> > +static const struct of_device_id gc08a3_of_match[] = {
> > +{ .compatible = "galaxycore,gc08a3" },
> > +{}
> > +};
> > +MODULE_DEVICE_TABLE(of, gc08a3_of_match);
> > +
> > +static const struct dev_pm_ops gc08a3_pm_ops = {
> > +SET_RUNTIME_PM_OPS(gc08a3_power_off, gc08a3_power_on, NULL)
> > +};
> > +
> > +static struct i2c_driver gc08a3_i2c_driver = {
> > +.driver = {
> > +.of_match_table = gc08a3_of_match,
> > +.pm = &gc08a3_pm_ops,
> > +.name  = "gc08a3",
> > +},
> > +.probe  = gc08a3_probe,
> > +.remove = gc08a3_remove,
> > +};
> > +
> > +module_i2c_driver(gc08a3_i2c_driver);
> > +
> > +MODULE_DESCRIPTION("GalaxyCore gc08a3 Camera driver");
> > +MODULE_AUTHOR("Zhi Mao <zhi.mao at mediatek.com>");
> > +MODULE_LICENSE("GPL");
> 
> -- 
> Regards,
> 
> Laurent Pinchart

From thiago.bauermann at linaro.org  Mon Feb 19 18:15:57 2024
From: thiago.bauermann at linaro.org (Thiago Jung Bauermann)
Date: Mon, 19 Feb 2024 23:15:57 -0300
Subject: [PATCH v8 33/38] kselftest/arm64: Add a GCS test program built
 with the system libc
In-Reply-To: <20240203-arm64-gcs-v8-33-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <20240203-arm64-gcs-v8-33-c9fec77673ef@kernel.org>
Message-ID: <87sf1n7uea.fsf@linaro.org>


Mark Brown <broonie at kernel.org> writes:

> There are things like threads which nolibc struggles with which we want
> to add coverage for, and the ABI allows us to test most of these even if
> libc itself does not understand GCS so add a test application built
> using the system libc.
>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  tools/testing/selftests/arm64/gcs/.gitignore |   1 +
>  tools/testing/selftests/arm64/gcs/Makefile   |   4 +-
>  tools/testing/selftests/arm64/gcs/gcs-util.h |  10 +
>  tools/testing/selftests/arm64/gcs/libc-gcs.c | 736 +++++++++++++++++++++++++++
>  4 files changed, 750 insertions(+), 1 deletion(-)

In v7, several tests weren't running in my FVT VM for some reason.
This time they do:

$ ./run_kselftest.sh -t arm64:libc-gcs
TAP version 13
1..1
# timeout set to 45
# selftests: arm64: libc-gcs
# TAP version 13
# 1..118
# # Starting 118 tests from 32 test cases.
# #  RUN           global.can_call_function ...
# # can_call_function: Test terminated unexpectedly by signal 11
# #          FAIL  global.can_call_function
# not ok 1 global.can_call_function
# #  RUN           global.gcs_enabled_thread ...
# #            OK  global.gcs_enabled_thread
# ok 2 global.gcs_enabled_thread
   ?
# #  RUN           invalid_mprotect.exec_bti.do_map_read ...
# # Allocated stack from 0xffffb3aa9000-0xffffb3aaa000
# #            OK  invalid_mprotect.exec_bti.do_map_read
# ok 118 invalid_mprotect.exec_bti.do_map_read
# # FAILED: 117 / 118 tests passed.
# # Totals: pass:117 fail:1 xfail:0 xpass:0 skip:0 error:0
not ok 1 selftests: arm64: libc-gcs # exit=1

The only issue as can be seen above is that the can_call_function test
is failing. The child is getting a GCS Segmentation fault when returning
from fork().

I tried debugging it with GDB, but I don't see what's wrong since the
address in LR matches the first entry in GCSPR. Here is the
debug session:

(gdb) break libc-gcs.c:58
Breakpoint 1 at 0x3894: file libc-gcs.c, line 58.
(gdb) set follow-fork-mode child
(gdb) r
Starting program: /var/tmp/selftests/arm64/libc-gcs
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
TAP version 13
1..118
# Starting 118 tests from 32 test cases.
#  RUN           global.can_call_function ...
[Attaching after Thread 0xfffff7ff7e80 (LWP 9164) fork to child process 9168]
[New inferior 2 (process 9168)]
[Detaching after fork from parent process 9164]
[Inferior 1 (process 9164) detached]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".

Thread 2.1 "libc-gcs" received signal SIGSEGV, Segmentation fault
Guarded Control Stack error.
[Switching to Thread 0xfffff7ff7e80 (LWP 9168)]
0x0000fffff7ec6fc0 [GCS error] in __GI__Fork () at ../sysdeps/nptl/_Fork.c:50
warning: 50     ../sysdeps/nptl/_Fork.c: No such file or directory
(gdb) bt
#0  0x0000fffff7ec6fc0 [GCS error] in __GI__Fork () at ../sysdeps/nptl/_Fork.c:50
#1  0x0000fffff7ec6be0 in __libc_fork () at ./posix/fork.c:73
#2  0x0000aaaaaaaa49b8 in __run_test (f=f at entry=0xaaaaaaab98c8 <_fixture_global>,
    variant=variant at entry=0xffffffffefb8, t=t at entry=0xaaaaaaab81b0 <_can_call_function_object>)
    at /home/thiago.bauermann/src/linux/tools/testing/selftests/kselftest_harness.h:1128
#3  0x0000aaaaaaaa2ac4 in test_harness_run (argv=0xfffffffff158, argc=1)
    at /home/thiago.bauermann/src/linux/tools/testing/selftests/kselftest_harness.h:1199
#4  main (argc=1, argv=0xfffffffff158) at libc-gcs.c:735
(gdb) p $gcspr
$1 = (void *) 0xfffff7dfffe0
(gdb) p/x $lr
$3 = 0xfffff7ec6be0
(gdb) p/x *(unsigned long *)$gcspr
$5 = 0xfffff7ec6be0
(gdb) disassemble
Dump of assembler code for function __GI__Fork:
   0x0000fffff7ec6f70 <+0>:     mrs     x5, tpidr_el0
   0x0000fffff7ec6f74 <+4>:     mov     x0, #0x11                       // #17
   0x0000fffff7ec6f78 <+8>:     sub     x6, x5, #0x7c0
   0x0000fffff7ec6f7c <+12>:    sub     x4, x5, #0x6f0
   0x0000fffff7ec6f80 <+16>:    movk    x0, #0x120, lsl #16
   0x0000fffff7ec6f84 <+20>:    mov     x1, #0x0                        // #0
   0x0000fffff7ec6f88 <+24>:    mov     x2, #0x0                        // #0
   0x0000fffff7ec6f8c <+28>:    mov     x3, #0x0                        // #0
   0x0000fffff7ec6f90 <+32>:    mov     x8, #0xdc                       // #220
   0x0000fffff7ec6f94 <+36>:    svc     #0x0
   0x0000fffff7ec6f98 <+40>:    cmn     x0, #0x1, lsl #12
   0x0000fffff7ec6f9c <+44>:    b.hi    0xfffff7ec6fc4 <__GI__Fork+84>  // b.pmore
   0x0000fffff7ec6fa0 <+48>:    mov     w2, w0
   0x0000fffff7ec6fa4 <+52>:    cbnz    w0, 0xfffff7ec6fbc <__GI__Fork+76>
   0x0000fffff7ec6fa8 <+56>:    sub     x0, x5, #0x6e0
   0x0000fffff7ec6fac <+60>:    mov     x1, #0x18                       // #24
   0x0000fffff7ec6fb0 <+64>:    mov     x8, #0x63                       // #99
   0x0000fffff7ec6fb4 <+68>:    stp     x0, x0, [x6, #216]
   0x0000fffff7ec6fb8 <+72>:    svc     #0x0
   0x0000fffff7ec6fbc <+76>:    mov     w0, w2
=> 0x0000fffff7ec6fc0 <+80>:    ret
   0x0000fffff7ec6fc4 <+84>:    adrp    x1, 0xfffff7faa000 <sys_siglist+424>
   0x0000fffff7ec6fc8 <+88>:    ldr     x1, [x1, #3528]
   0x0000fffff7ec6fcc <+92>:    neg     w0, w0
   0x0000fffff7ec6fd0 <+96>:    mov     w2, #0xffffffff                 // #-1
   0x0000fffff7ec6fd4 <+100>:   str     w0, [x5, x1]
   0x0000fffff7ec6fd8 <+104>:   mov     w0, w2
   0x0000fffff7ec6fdc <+108>:   ret
End of assembler dump.
(gdb) p $w0
$8 = 0
(gdb) p $_siginfo.si_signo
$12 = 11
(gdb) p $_siginfo.si_code
$13 = 10
(gdb) p $_siginfo._sifields._sigfault.si_addr
$14 = (void *) 0xfffff7ec6fc0 <__GI__Fork+80>

-- 
Thiago


From thiago.bauermann at linaro.org  Mon Feb 19 18:17:57 2024
From: thiago.bauermann at linaro.org (Thiago Jung Bauermann)
Date: Mon, 19 Feb 2024 23:17:57 -0300
Subject: [PATCH v8 35/38] selftests/arm64: Add GCS signal tests
In-Reply-To: <20240203-arm64-gcs-v8-35-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <20240203-arm64-gcs-v8-35-c9fec77673ef@kernel.org>
Message-ID: <87o7cb7uay.fsf@linaro.org>


Mark Brown <broonie at kernel.org> writes:

> Do some testing of the signal handling for GCS, checking that a GCS
> frame has the expected information in it and that the expected signals
> are delivered with invalid operations.
>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  tools/testing/selftests/arm64/signal/.gitignore    |  1 +
>  .../selftests/arm64/signal/test_signals_utils.h    | 10 +++
>  .../arm64/signal/testcases/gcs_exception_fault.c   | 62 +++++++++++++++
>  .../selftests/arm64/signal/testcases/gcs_frame.c   | 88 ++++++++++++++++++++++
>  .../arm64/signal/testcases/gcs_write_fault.c       | 67 ++++++++++++++++
>  5 files changed, 228 insertions(+)

Just FYI, in v7 I reported that gcs_write_fault was failing for me.
Now all tests in this patch are passing.

-- 
Thiago


From zhi.mao at mediatek.com  Mon Feb 19 18:21:21 2024
From: zhi.mao at mediatek.com (=?utf-8?B?WmhpIE1hbyAo5q+b5pm6KQ==?=)
Date: Tue, 20 Feb 2024 02:21:21 +0000
Subject: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <21370bd8-502b-4b4e-8c9b-6d13c60685d5@collabora.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
	 <20240204061538.2105-3-zhi.mao@mediatek.com>
	 <21370bd8-502b-4b4e-8c9b-6d13c60685d5@collabora.com>
Message-ID: <1a9cb6c04de90cde777e30e15b0bced4c1d002f9.camel@mediatek.com>

Hi AngeloGioacchino,

Thanks for your review.

On Wed, 2024-02-07 at 15:42 +0100, AngeloGioacchino Del Regno wrote:
> Il 04/02/24 07:15, Zhi Mao ha scritto:
> > Add a V4L2 sub-device driver for Galaxycore GC08A3 image sensor.
> > 
> > Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> > ---
> >   drivers/media/i2c/Kconfig  |   10 +
> >   drivers/media/i2c/Makefile |    1 +
> >   drivers/media/i2c/gc08a3.c | 1448
> > ++++++++++++++++++++++++++++++++++++
> >   3 files changed, 1459 insertions(+)
> >   create mode 100644 drivers/media/i2c/gc08a3.c
> > 
> > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > index 56f276b920ab..e4da68835683 100644
> > --- a/drivers/media/i2c/Kconfig
> > +++ b/drivers/media/i2c/Kconfig
> > @@ -70,6 +70,16 @@ config VIDEO_GC0308
> >   	  To compile this driver as a module, choose M here: the
> >   	  module will be called gc0308.
> >   
> > +config VIDEO_GC08A3
> > +	tristate "GalaxyCore gc08a3 sensor support"
> > +	select V4L2_CCI_I2C
> > +	help
> > +	  This is a Video4Linux2 sensor driver for the GalaxyCore
> > gc08a3
> > +	  camera.
> > +
> > +	  To compile this driver as a module, choose M here: the
> > +	  module will be called gc08a3.
> > +
> >   config VIDEO_GC2145
> >   	select V4L2_CCI_I2C
> >   	tristate "GalaxyCore GC2145 sensor support"
> > diff --git a/drivers/media/i2c/Makefile
> > b/drivers/media/i2c/Makefile
> > index dfbe6448b549..b82e99ca7578 100644
> > --- a/drivers/media/i2c/Makefile
> > +++ b/drivers/media/i2c/Makefile
> > @@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
> >   obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
> >   obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
> >   obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
> > +obj-$(CONFIG_VIDEO_GC08A3) += gc08a3.o
> >   obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
> >   obj-$(CONFIG_VIDEO_HI556) += hi556.o
> >   obj-$(CONFIG_VIDEO_HI846) += hi846.o
> > diff --git a/drivers/media/i2c/gc08a3.c
> > b/drivers/media/i2c/gc08a3.c
> > new file mode 100644
> > index 000000000000..3fc7fffb815c
> > --- /dev/null
> > +++ b/drivers/media/i2c/gc08a3.c
> > @@ -0,0 +1,1448 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * gc08a3.c - gc08a3 sensor driver
> > + *
> > + * Copyright 2023 MediaTek
> > + *
> > + * Zhi Mao <zhi.mao at mediatek.com>
> > + */
> > +
> 
> ..snip..
> 
fixed in patch:v5.
> > +
> > +static const struct gc08a3_link_freq_config
> > gc08a3_link_freq_336m_configs = {
> > +	.reg_list = {
> > +		.num_of_regs = ARRAY_SIZE(mode_table_common),
> > +		.regs = mode_table_common,
> > +	}
> > +};
> > +
> > +static const struct gc08a3_link_freq_config
> > gc08a3_link_freq_207m_configs = {
> > +	.reg_list = {
> > +		.num_of_regs = ARRAY_SIZE(mode_table_common),
> > +		.regs = mode_table_common,
> > +	}
> > +};
> > +
> 
> Since you're documenting this structure anyway, why not kerneldoc? :-
> )
> 
As these registers are the same, I followed Mr.Laurent's comments and
droped this "gc08a3_link_freq_config" structure.

> > +struct gc08a3_mode {
> > +	u32 width;
> > +	u32 height;
> > +	const struct gc08a3_reg_list reg_list;
> > +
> > +	u32 hts; /* Horizontal timining size */
> > +	u32 vts_def; /* Default vertical timining size */
> > +	u32 vts_min; /* Min vertical timining size */
> > +	u32 max_framerate;
> > +	const struct gc08a3_link_freq_config *link_freq_configs;
> > +};
> > +
> > +/*
> > + * Declare modes in order, from biggest
> > + * to smallest height.
> > + */
> 
> one line is enough for this comment.
> 
fixed in patch:v5.
> > +static const struct gc08a3_mode gc08a3_modes[] = {
> > +	{
> > +		.width = GC08A3_NATIVE_WIDTH,
> > +		.height = GC08A3_NATIVE_HEIGHT,
> > +		.reg_list = {
> > +			.num_of_regs = ARRAY_SIZE(mode_3264x2448),
> > +			.regs = mode_3264x2448,
> > +		},
> > +		.link_freq_configs = &gc08a3_link_freq_336m_configs,
> > +
> > +		.hts = GC08A3_HTS_30FPS,
> > +		.vts_def = GC08A3_VTS_30FPS,
> > +		.vts_min = GC08A3_VTS_30FPS_MIN,
> > +		.max_framerate = 300,
> > +	},
> > +	{
> > +		.width = 1920,
> > +		.height = 1080,
> > +		.reg_list = {
> > +			.num_of_regs = ARRAY_SIZE(mode_1920x1080),
> > +			.regs = mode_1920x1080,
> > +		},
> > +		.link_freq_configs = &gc08a3_link_freq_207m_configs,
> > +
> > +		.hts = GC08A3_HTS_60FPS,
> > +		.vts_def = GC08A3_VTS_60FPS,
> > +		.vts_min = GC08A3_VTS_60FPS_MIN,
> > +		.max_framerate = 600,
> > +	},
> > +};
> > +
> > +static u64 to_pixel_rate(u32 f_index)
> > +{
> > +	u64 pixel_rate = link_freq_menu_items[f_index] * 2 *
> > GC08A3_DATA_LANES;
> > +
> > +	do_div(pixel_rate, GC08A3_RGB_DEPTH);
> 
> The divisor is (less than) 32 bits and the dividend is always 64
> bits: that will
> break on builds for 32-bits CPUs.
> 
> Just do....
> 
> 	return div_u64(pixel_rate, GB08A3_RGB_DEPTH);
> 
fixed in patch:v5.
> > +
> > +	return pixel_rate;
> > +}
> > +
> > +static int gc08a3_identify_module(struct gc08a3 *gc08a3)
> > +{
> > +	struct i2c_client *client = v4l2_get_subdevdata(&gc08a3->sd);
> > +	u64 val = 0;
> 
> u64 val;
> 
> > +	int ret;
> > +
> 
> Either log here or in the probe function, otherwise it's just
> redudant.
> 
please review patch:v5.
> > +	ret = cci_read(gc08a3->regmap, GC08A3_REG_CHIP_ID, &val, NULL);
> > +	if (ret) {
> > +		dev_err(&client->dev,
> > +			"failed to read chip id: 0x%x",
> > GC08A3_CHIP_ID);
> > +		return ret;
> > +	}
> > +
> > +	if (val != GC08A3_CHIP_ID) {
> > +		dev_err(&client->dev, "chip id mismatch: 0x%x!=0x%llx",
> > +			GC08A3_CHIP_ID, val);
> > +		return -ENXIO;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static inline struct gc08a3 *to_gc08a3(struct v4l2_subdev *sd)
> > +{
> > +	return container_of(sd, struct gc08a3, sd);
> > +}
> > +
> 
> ..snip..
> 
fixed in patch:v5.
> > +
> > +static int gc08a3_update_cur_mode_controls(struct gc08a3 *gc08a3,
> > +					   const struct gc08a3_mode
> > *mode)
> > +{
> > +	s64 exposure_max, h_blank;
> > +	int ret = 0;
> > +
> > +	ret = __v4l2_ctrl_modify_range(gc08a3->vblank,
> > +				       mode->vts_min - mode->height,
> > +				       GC08A3_VTS_MAX - mode->height,
> > 1,
> > +				       mode->vts_def - mode->height);
> > +	if (ret)
> > +		dev_err(gc08a3->dev, "VB ctrl range update failed\n");
> > +
> > +	h_blank = mode->hts - mode->width;
> > +	ret = __v4l2_ctrl_modify_range(gc08a3->hblank, h_blank,
> > h_blank, 1,
> > +				       h_blank);
> > +	if (ret)
> > +		dev_err(gc08a3->dev, "HB ctrl range update failed\n");
> > +
> > +	exposure_max = mode->vts_def - GC08A3_EXP_MARGIN;
> > +	ret = __v4l2_ctrl_modify_range(gc08a3->exposure,
> > GC08A3_EXP_MIN,
> > +				       exposure_max, GC08A3_EXP_STEP,
> > +				       exposure_max);
> > +	if (ret)
> > +		dev_err(gc08a3->dev, "exposure ctrl range update
> > failed\n");
> 
> No. You're not returning anywhere for error. That's not okay.
> Besides...
> 
> 	if (ret) {
> 		dev_err..
> 		return ret;
> 	}
> 
> 	return 0;
> 
fixed in patch:v5.
> > +
> > +	return ret;
> > +}
> > +
> > +static void gc08a3_update_pad_format(struct gc08a3 *gc08a3,
> > +				     const struct gc08a3_mode *mode,
> > +				     struct v4l2_mbus_framefmt *fmt)
> > +{
> > +	fmt->width = mode->width;
> > +	fmt->height = mode->height;
> > +	fmt->code = GC08A3_MBUS_CODE;
> > +	fmt->field = V4L2_FIELD_NONE;
> > +	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);
> > +}
> > +
> > +static int gc08a3_set_format(struct v4l2_subdev *sd,
> > +			     struct v4l2_subdev_state *state,
> > +			     struct v4l2_subdev_format *fmt)
> > +{
> > +	struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +	struct v4l2_mbus_framefmt *mbus_fmt;
> > +	struct v4l2_rect *crop;
> > +	const struct gc08a3_mode *mode;
> > +
> > +	mode = v4l2_find_nearest_size(gc08a3_modes,
> > ARRAY_SIZE(gc08a3_modes),
> > +				      width, height, fmt->format.width,
> > +				      fmt->format.height);
> > +
> > +	/*update crop info to subdev state*/
> > +	crop = v4l2_subdev_state_get_crop(state, 0);
> > +	crop->width = mode->width;
> > +	crop->height = mode->height;
> > +
> > +	/*update fmt info to subdev state*/
> > +	gc08a3_update_pad_format(gc08a3, mode, &fmt->format);
> > +	mbus_fmt = v4l2_subdev_state_get_format(state, 0);
> > +	*mbus_fmt = fmt->format;
> > +
> > +	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
> > +		return 0;
> > +
> > +	gc08a3->cur_mode = mode;
> > +	gc08a3_update_cur_mode_controls(gc08a3, mode);
> > +
> > +	return 0;
> > +}
> > +
> > +static int gc08a3_get_selection(struct v4l2_subdev *sd,
> > +				struct v4l2_subdev_state *state,
> > +				struct v4l2_subdev_selection *sel)
> > +{
> > +	struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > +
> > +	switch (sel->target) {
> > +	case V4L2_SEL_TGT_CROP:
> > +		sel->r = *v4l2_subdev_state_get_crop(state, 0);
> > +		break;
> > +	case V4L2_SEL_TGT_CROP_BOUNDS:
> > +		sel->r.top = 0;
> > +		sel->r.left = 0;
> > +		sel->r.width = GC08A3_NATIVE_WIDTH;
> > +		sel->r.height = GC08A3_NATIVE_HEIGHT;
> > +		break;
> > +	case V4L2_SEL_TGT_CROP_DEFAULT:
> > +		if (gc08a3->cur_mode->width == GC08A3_NATIVE_WIDTH) {
> > +			sel->r.top = 0;
> > +			sel->r.left = 0;
> > +			sel->r.width = gc08a3_modes[0].width;
> > +			sel->r.height = gc08a3_modes[0].height;
> > +		} else {
> > +			sel->r.top = 0;
> > +			sel->r.left = 0;
> > +			sel->r.width = gc08a3_modes[1].width;
> > +			sel->r.height = gc08a3_modes[1].height;
> > +		}
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int gc08a3_init_state(struct v4l2_subdev *sd,
> > +			     struct v4l2_subdev_state *state)
> > +{
> > +	struct v4l2_subdev_format fmt = {
> > +		.which = V4L2_SUBDEV_FORMAT_TRY,
> > +		.pad = 0,
> > +		.format = {
> > +			.code = GC08A3_MBUS_CODE,
> > +			.width = gc08a3_modes[0].width,
> > +			.height = gc08a3_modes[0].height,
> > +		},
> > +	};
> > +
> > +	gc08a3_set_format(sd, state, &fmt);
> > +
> > +	return 0;
> > +}
> > +
> > +static int gc08a3_set_ctrl_hflip(struct gc08a3 *gc08a3, u32
> > ctrl_val)
> > +{
> > +	int ret;
> > +	u64 val;
> > +
> > +	ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
> > +	if (ret) {
> > +		dev_err(gc08a3->dev, "read hflip register failed:
> > %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	val = ctrl_val ? (val | GC08A3_FLIP_H_MASK) :
> > +			   (val & ~GC08A3_FLIP_H_MASK);
> > +	ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
> > +	if (ret < 0)
> > +		dev_err(gc08a3->dev, "Error %d\n", ret);
> > +
> > +	return ret;
> > +}
> > +
> > +static int gc08a3_set_ctrl_vflip(struct gc08a3 *gc08a3, u32
> > ctrl_val)
> > +{
> > +	int ret;
> > +	u64 val;
> > +
> > +	ret = cci_read(gc08a3->regmap, GC08A3_FLIP_REG, &val, NULL);
> > +	if (ret) {
> > +		dev_err(gc08a3->dev, "read vflip register failed:
> > %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	val = ctrl_val ? (val | GC08A3_FLIP_V_MASK) :
> > +			   (val & ~GC08A3_FLIP_V_MASK);
> > +	ret = cci_write(gc08a3->regmap, GC08A3_FLIP_REG, val, NULL);
> > +	if (ret < 0)
> > +		dev_err(gc08a3->dev, "Error %d\n", ret);
> > +
> > +	return ret;
> > +}
> > +
> > +static int gc08a3_test_pattern(struct gc08a3 *gc08a3, u32
> > pattern_menu)
> > +{
> > +	u32 pattern = 0;
> > +	int ret;
> 
> ret not initialized is ok here;
> 
> > +
> > +	if (pattern_menu) {
> > +		switch (pattern_menu) {
> > +		case 1:
> > +			pattern = 0x00;
> > +			break;
> > +		case 2:
> > +			pattern = 0x10;
> > +			break;
> > +		case 3:
> > +		case 4:
> > +		case 5:
> > +		case 6:
> > +		case 7:
> > +			pattern = pattern_menu + 1;
> > +			break;
> > +		}
> > +
> > +		ret = cci_write(gc08a3->regmap,
> > GC08A3_REG_TEST_PATTERN_EN,
> > +				GC08A3_TEST_PATTERN_EN, NULL);
> > +		if (ret)
> > +			return ret;
> > +
> > +		ret = cci_write(gc08a3->regmap,
> > GC08A3_REG_TEST_PATTERN_IDX,
> > +				pattern, NULL);
> 
> if (ret)
> 	return ret;
> 
> > +
> > +	} else {
> > +		ret = cci_write(gc08a3->regmap,
> > GC08A3_REG_TEST_PATTERN_EN,
> > +				0x00, NULL);
> 
> if (ret)
> 	return ret;
> 
> > +	}
> > +
> 
> 	return 0;
> 
fixed in patch:v5.

> > +	return ret;
> > +}
> > +
> > +static int gc08a3_set_ctrl(struct v4l2_ctrl *ctrl)
> > +{
> > +	struct gc08a3 *gc08a3 =
> > +		container_of(ctrl->handler, struct gc08a3, ctrls);
> > +	int ret = 0;
> 
> int ret;
> 
> > +	s64 exposure_max;
> > +
> > +	if (ctrl->id == V4L2_CID_VBLANK) {
> > +		/* Update max exposure while meeting expected vblanking
> > */
> > +		exposure_max = gc08a3->cur_mode->height + ctrl->val -
> > +			       GC08A3_EXP_MARGIN;
> > +		__v4l2_ctrl_modify_range(gc08a3->exposure,
> > +					 gc08a3->exposure->minimum,
> > +					 exposure_max, gc08a3-
> > >exposure->step,
> > +					 exposure_max);
> > +	}
> > +
> > +	/*
> > +	 * Applying V4L2 control value only happens
> > +	 * when power is on for streaming
> > +	 */
> > +	if (!pm_runtime_get_if_in_use(gc08a3->dev))
> > +		return 0;
> > +
> > +	switch (ctrl->id) {
> > +	case V4L2_CID_EXPOSURE:
> > +		ret = cci_write(gc08a3->regmap, GC08A3_EXP_REG,
> > +				ctrl->val, NULL);
> > +		break;
> > +
> > +	case V4L2_CID_ANALOGUE_GAIN:
> > +		ret = cci_write(gc08a3->regmap, GC08A3_AGAIN_REG,
> > +				ctrl->val, NULL);
> > +		break;
> > +
> > +	case V4L2_CID_VBLANK:
> > +		ret = cci_write(gc08a3->regmap,
> > GC08A3_FRAME_LENGTH_REG,
> > +				gc08a3->cur_mode->height + ctrl->val,
> > NULL);
> > +		break;
> > +
> > +	case V4L2_CID_HFLIP:
> > +		ret = gc08a3_set_ctrl_hflip(gc08a3, ctrl->val);
> > +		break;
> > +
> > +	case V4L2_CID_VFLIP:
> > +		ret = gc08a3_set_ctrl_vflip(gc08a3, ctrl->val);
> > +		break;
> > +
> > +	case V4L2_CID_TEST_PATTERN:
> > +		ret = gc08a3_test_pattern(gc08a3, ctrl->val);
> > +		break;
> > +
> > +	default:
> > +		break;
> > +	}
> > +
> > +	pm_runtime_put(gc08a3->dev);
> 
> if (ret)
> 	return ret;
> 
> return 0;
> 
As "default" case is not assign the variable "ret", this return value
is not expected, so we need initialize the variable "ret=0". Can we
keep this coding style?
> > +
> > +	return ret;
> > +}
> > +
> 
> ...and I've ignored some more stuff as other reviewers already gave
> you feedback.
> 
> Regards,
> Angelo
> 

From yuzenghui at huawei.com  Mon Feb 19 18:26:50 2024
From: yuzenghui at huawei.com (Zenghui Yu)
Date: Tue, 20 Feb 2024 10:26:50 +0800
Subject: next-20240219: arm64: boot failed - gic_of_init
In-Reply-To: <86a5nw4gp3.wl-maz@kernel.org>
References: <CA+G9fYugYiLd7MDn3wCxK+x5Td9WO-VUX2OvOtTN7D1d4GHCfg@mail.gmail.com>
 <86edd84wer.wl-maz@kernel.org> <86cyss4rl7.wl-maz@kernel.org>
 <a7d8e529-9a44-3f88-50ef-d87b80515c36@huawei.com>
 <86a5nw4gp3.wl-maz@kernel.org>
Message-ID: <f3bd274b-2644-ce5c-315d-36a492814d13@huawei.com>

On 2024/2/19 23:27, Marc Zyngier wrote:
> On Mon, 19 Feb 2024 14:46:46 +0000,
> Zenghui Yu <yuzenghui at huawei.com> wrote:
>>
>> On 2024/2/19 19:32, Marc Zyngier wrote:
>>> For what it is worth, I've just tested both defconfig and my own
>>> configuration with both 4k (kvmtool, QEMU+KVM and on SynQuacer) and
>>> 16k (kvmtool), without any obvious problem.
>>
>> I had a quick test on top of next-20240219 with defconfig.  I can
>> reproduce it with QEMU parameter '-cpu max -accel tcg', but things are
>> fine with '-cpu max,lpa2=off -accel tcg'.
>>
>> Bisection shows that the problem happens when we start putting the
>> latest arm64 and kvmarm changes together.  The following hack fixes the
>> problem for me (but I **only** write it for kernel built with defconfig
>> with ARM64_4K_PAGES=y atm).
>>
>> I can investigate it further tomorrow (as it's too late now ;-) ).  Or
>> maybe Marc or Catalin can help fix it with a proper approach.
>>
>> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
>> index 4f7662008ede..babdc3f4721b 100644
>> --- a/arch/arm64/kernel/cpufeature.c
>> +++ b/arch/arm64/kernel/cpufeature.c
>> @@ -2798,6 +2798,7 @@ static const struct arm64_cpu_capabilities
>> arm64_features[] = {
>> | 		.sign = FTR_SIGNED,
>> | 		.field_pos = ID_AA64MMFR0_EL1_TGRAN4_SHIFT,
>> | 		.min_field_value = ID_AA64MMFR0_EL1_TGRAN4_52_BIT,
>> |+		.max_field_value = BIT(ID_AA64MMFR0_EL1_TGRAN4_WIDTH - 1) - 1,
>> | #else
>> | 		.sign = FTR_UNSIGNED,
>> | 		.field_pos = ID_AA64MMFR0_EL1_TGRAN16_SHIFT,
> 
> I've posted my take on this at [1], which hopefully matches what you
> were aiming at.
> 
> [1] https://lore.kernel.org/all/86bk8c4gyh.wl-maz at kernel.org/

Yup, this looks good to me.

Thanks,
Zenghui


From anshuman.khandual at arm.com  Mon Feb 19 18:32:03 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 20 Feb 2024 08:02:03 +0530
Subject: [PATCH V2] arm64/sysreg: Add register fields for ID_AA64DFR1_EL1
Message-ID: <20240220023203.3091229-1-anshuman.khandual@arm.com>

This adds register fields for ID_AA64DFR1_EL1 as per the definitions based
on DDI0601 2023-12.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Brown <broonie 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>
---
This applies on v6.8-rc5

Changes in V2:

- Added enumerated values for DPFZS field per Mark

Changes in V1:

https://lore.kernel.org/all/20240215065454.2489075-1-anshuman.khandual at arm.com/

 arch/arm64/tools/sysreg | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 4c9b67934367..dd693f992832 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1251,7 +1251,36 @@ EndEnum
 EndSysreg
 
 Sysreg	ID_AA64DFR1_EL1	3	0	0	5	1
-Res0	63:0
+Field	63:56	ABL_CMPs
+UnsignedEnum	55:52	DPFZS
+	0b0000	IGNR
+	0b0001	FRZN
+EndEnum
+UnsignedEnum	51:48	EBEP
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	47:44	ITE
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	43:40	ABLE
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	39:36	PMICNTR
+	0b0000	NI
+	0b0001	IMP
+EndEnum
+UnsignedEnum	35:32	SPMU
+	0b0000	NI
+	0b0001	IMP
+	0b0010	IMP_SPMZR
+EndEnum
+Field	31:24	CTX_CMPs
+Field	23:16	WRPs
+Field	15:8	BRPs
+Field	7:0	SYSPMUID
 EndSysreg
 
 Sysreg	ID_AA64AFR0_EL1	3	0	0	5	4
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Feb 19 18:53:43 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 20 Feb 2024 08:23:43 +0530
Subject: [PATCH V2] arm64/sysreg: Update ID_DFR0_EL1 register fields
Message-ID: <20240220025343.3093955-1-anshuman.khandual@arm.com>

This updates ID_DFR0_EL1.PerfMon and ID_DFR0_EL1.CopDbg register fields as
per the definitions based on DDI0601 2023-12.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Brown <broonie 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>
---
This applies on v6.8-rc5

Changes in V2:

- Split ID_DFR0_EL1 changes in this patch and updated PerfMon per Mark

Changes in V1:

https://lore.kernel.org/all/20240215055159.2440898-1-anshuman.khandual at arm.com/

 arch/arm64/tools/sysreg | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index dd693f992832..a9cab2b730a3 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -200,6 +200,7 @@ UnsignedEnum	27:24	PerfMon
 	0b0110	PMUv3p5
 	0b0111	PMUv3p7
 	0b1000	PMUv3p8
+	0b1001	PMUv3p9
 	0b1111	IMPDEF
 EndEnum
 Enum	23:20	MProfDbg
@@ -231,6 +232,7 @@ Enum	3:0	CopDbg
 	0b1000	Debugv8p2
 	0b1001	Debugv8p4
 	0b1010	Debugv8p8
+	0b1011	Debugv8p9
 EndEnum
 EndSysreg
 
-- 
2.25.1



From laurent.pinchart at ideasonboard.com  Mon Feb 19 19:01:04 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 20 Feb 2024 05:01:04 +0200
Subject: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <598f62bbb55157eec1e23dd1dbc307fea3851b21.camel@mediatek.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
 <20240204061538.2105-3-zhi.mao@mediatek.com>
 <20240206184542.GE2827@pendragon.ideasonboard.com>
 <598f62bbb55157eec1e23dd1dbc307fea3851b21.camel@mediatek.com>
Message-ID: <20240220030104.GF20376@pendragon.ideasonboard.com>

Hi Zhi,

On Tue, Feb 20, 2024 at 02:12:26AM +0000, Zhi Mao (??) wrote:
> On Tue, 2024-02-06 at 20:45 +0200, Laurent Pinchart wrote:
> > On Sun, Feb 04, 2024 at 02:15:38PM +0800, Zhi Mao wrote:
> > > Add a V4L2 sub-device driver for Galaxycore GC08A3 image sensor.
> > >
> > > Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> > > ---
> > >  drivers/media/i2c/Kconfig  |   10 +
> > >  drivers/media/i2c/Makefile |    1 +
> > >  drivers/media/i2c/gc08a3.c | 1448 ++++++++++++++++++++++++++++++++++++
> > >  3 files changed, 1459 insertions(+)
> > >  create mode 100644 drivers/media/i2c/gc08a3.c

[snip]

> > > diff --git a/drivers/media/i2c/gc08a3.c b/drivers/media/i2c/gc08a3.c
> > > new file mode 100644
> > > index 000000000000..3fc7fffb815c
> > > --- /dev/null
> > > +++ b/drivers/media/i2c/gc08a3.c
> > > @@ -0,0 +1,1448 @@

[snip]

> > > +static int gc08a3_power_on(struct device *dev)
> > > +{
> > > +	struct i2c_client *client = to_i2c_client(dev);
> > > +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > > +	struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > > +	int ret;
> > > +
> > > +	ret = regulator_bulk_enable(ARRAY_SIZE(gc08a3_supply_name),
> > > +				    gc08a3->supplies);
> > > +	if (ret < 0) {
> > > +		dev_err(gc08a3->dev, "failed to enable regulators: %d\n", ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	ret = clk_prepare_enable(gc08a3->xclk);
> > > +	if (ret < 0) {
> > > +		regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
> > > +				       gc08a3->supplies);
> > > +		dev_err(gc08a3->dev, "clk prepare enable failed\n");
> > > +		return ret;
> > > +	}
> > > +
> > > +	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > > +
> > > +	gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> >
> > Are you asserting reset when powering on ? That sounds wrong, you should
> > de-assert reset here (and acquire the reset gpio in probe() with
> > GPIOD_OUT_HIGH). Drivers should use logical levels for GPIOs, setting a
> > GPIO named "reset" to 1 should assert the reset signal, even if the
> > physical signal is active low. You may have the wrong polarity in the
> > device tree.
>
> According to the sensor power sequence sepc, "reset" pin should be pull
> from low to high after "dovdd/dvdd/avdd" power on, so I follow this
> power sequece to pull "reset" pin high in software flow.

>From a hardware point of view that's right, but the Linux kernel handles
logical level of GPIOs. If a GPIO is named "reset", it is expected that
calling

	gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);

will "assert" the reset signal, setting it to a logical "reset = true"
level. This maps to the hardware 0V output level, as the signal is
active-low. To achieve this, define the reset GPIO as active low in DT,
and the GPIO framework will invert the signal for you. You should then
call

	gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);

in the driver when you want to assert reset (set it to 0V), and

	gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);

when you want to deassert it (set it to 3.3V, or whatever the I/O
voltage for the signal is).

This way all driver use logical states, and the inversion is handled in
DT.

> > > +	usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > > +
> > > +	return 0;
> > > +}

[snip]

-- 
Regards,

Laurent Pinchart


From Sandor.yu at nxp.com  Mon Feb 19 19:23:48 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 20 Feb 2024 11:23:48 +0800
Subject: [PATCH v14 0/7] Initial support Cadence MHDP8501(HDMI/DP) for i.MX8MQ
Message-ID: <cover.1708395604.git.Sandor.yu@nxp.com>

The patch set initial support Cadence MHDP8501(HDMI/DP) DRM bridge
driver and Cadence HDP-TX PHY(HDMI/DP) drivers for Freescale i.MX8MQ.

The patch set compose of DRM bridge drivers and PHY drivers.

Both of them need by patch #1 and #2 to pass build.

DRM bridges driver patches:
  #1: drm: bridge: Cadence: Creat mhdp helper driver
  #2: phy: Add HDMI configuration options
  #3: dt-bindings: display: bridge: Add Cadence MHDP8501
  #4: drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver

PHY driver patches:
  #1: drm: bridge: Cadence: Creat mhdp helper driver
  #2: phy: Add HDMI configuration options
  #5: dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
  #6: phy: freescale: Add DisplayPort PHY driver for i.MX8MQ
  #7: phy: freescale: Add HDMI PHY driver for i.MX8MQ

v13->v14:
Patch #4:
- Rebase to next-20240219, replace get_edid function by edid_read
  function as commits d807ad80d811b ("drm/bridge: add ->edid_read
  hook and drm_bridge_edid_read()") and 27b8f91c08d99 ("drm/bridge:
  remove ->get_edid callback") had change the API.

v12->v13:
Patch #4:
- Explicitly include linux/platform_device.h for cdns-mhdp8501-core.c
- Fix build warning
- Order bit bpc and color_space in descending shit. 
Patch #7:
- Fix build warning

v11->v12:
Patch #1: 
- Move status initialize out of mbox_mutex.
- Reorder API functions in alphabetical.
- Add notes for malibox access functions.
- Add year 2024 to copyright.
Patch #4:
- Replace DRM_INFO with dev_info or dev_warn.
- Replace DRM_ERROR with dev_err.
- Return ret when cdns_mhdp_dpcd_read failed in function cdns_dp_aux_transferi().
- Remove unused parmeter in function cdns_dp_get_msa_misc
  and use two separate variables for color space and bpc.
- Add year 2024 to copyright.
Patch #6:
- Return error code to replace -1 for function wait_for_ack().
- Set cdns_phy->power_up = false in phy_power_down function.
- Remove "RATE_8_1 = 810000", it is not used in driver.
- Add year 2024 to copyright.
Patch #7:
- Adjust clk disable order.
- Return error code to replace -1 for function wait_for_ack().
- Use bool for variable pclk_in.
- Add year 2024 to copyright.

v10->v11:
- rewrite cdns_mhdp_set_firmware_active() in mhdp8546 core driver,
use cdns_mhdp_mailbox_send() to replace cdns_mhdp_mailbox_write()
same as the other mailbox access functions.
- use static for cdns_mhdp_mailbox_write() and cdns_mhdp_mailbox_read()
and remove them from EXPORT_SYMBOL_GPL().
- remove MODULE_ALIAS() from mhdp8501 driver.

v9->v10:
- Create mhdp helper driver to replace macro functions,
move all mhdp mailbox access functions and common functions
into the helper driver.
Patch #1:drm: bridge: Cadence: Creat mhdp helper driver
it is totaly different with v9.

v8->v9:
- Remove compatible string "cdns,mhdp8501" that had removed
  from dt-bindings file in v8.
- Add Dmitry's R-b tag to patch #2
- Add Krzysztof's R-b tag to patch #3

v7->v8:
MHDP8501 HDMI/DP:
- Correct DT node name to "display-bridge".
- Remove "cdns,mhdp8501" from mhdp8501 dt-binding doc.

HDMI/DP PHY:
- Introduced functions `wait_for_ack` and `wait_for_ack_clear` to handle
  waiting with acknowledgment bits set and cleared respectively.
- Use FIELD_PRE() to set bitfields for both HDMI and DP PHY.

v6->v7:
MHDP8501 HDMI/DP:
- Combine HDMI and DP driver into one mhdp8501 driver.
  Use the connector type to load the corresponding functions.
- Remove connector init functions.
- Add <linux/hdmi.h> in phy_hdmi.h to reuse ?enum hdmi_colorspace?.

HDMI/DP PHY:
- Lowercase hex values
- Fix parameters indent issue on some functions
- Replace ?udelay? with ?usleep_range?

v5->v6:
HDMI/DP bridge driver
- 8501 is the part number of Cadence MHDP on i.MX8MQ.
  Use MHDP8501 to name hdmi/dp drivers and files. 
- Add compatible "fsl,imx8mq-mhdp8501-dp" for i.MX8MQ DP driver
- Add compatible "fsl,imx8mq-mhdp8501-hdmi" for i.MX8MQ HDMI driver
- Combine HDMI and DP dt-bindings into one file cdns,mhdp8501.yaml
- Fix HDMI scrambling is not enable issue when driver working in 4Kp60
  mode.
- Add HDMI/DP PHY API mailbox protect.

HDMI/DP PHY driver:
- Rename DP and HDMI PHY files and move to folder phy/freescale/
- Remove properties num_lanes and link_rate from DP PHY driver.
- Combine HDMI and DP dt-bindings into one file fsl,imx8mq-dp-hdmi-phy.yaml
- Update compatible string to "fsl,imx8mq-dp-phy".
- Update compatible string to "fsl,imx8mq-hdmi-phy".

v4->v5:
- Drop "clk" suffix in clock name.
- Add output port property in the example of hdmi/dp.

v3->v4:
dt-bindings:
- Correct dt-bindings coding style and address review comments.
- Add apb_clk description.
- Add output port for HDMI/DP connector
PHY:
- Alphabetically sorted in Kconfig and Makefile for DP and HDMI PHY
- Remove unused registers define from HDMI and DP PHY drivers.
- More description in phy_hdmi.h.
- Add apb_clk to HDMI and DP phy driver.
HDMI/DP:
- Use get_unaligned_le32() to replace hardcode type conversion
  in HDMI AVI infoframe data fill function.
- Add mailbox mutex lock in HDMI/DP driver for phy functions
  to reslove race conditions between HDMI/DP and PHY drivers.
- Add apb_clk to both HDMI and DP driver.
- Rename some function names and add prefix with "cdns_hdmi/cdns_dp".
- Remove bpc 12 and 16 optional that not supported.

v2->v3:
Address comments for dt-bindings files.
- Correct dts-bindings file names 
  Rename phy-cadence-hdptx-dp.yaml to cdns,mhdp-imx8mq-dp.yaml
  Rename phy-cadence-hdptx-hdmi.yaml to cdns,mhdp-imx8mq-hdmi.yaml
- Drop redundant words and descriptions.
- Correct hdmi/dp node name.

v2 is a completely different version compared to v1.
Previous v1 can be available here [1].

v1->v2:
- Reuse Cadence mailbox access functions from mhdp8546 instead of
  rockchip DP.
- Mailbox access functions be convert to marco functions
  that will be referenced by HDP-TX PHY(HDMI/DP) driver too.
- Plain bridge instead of component driver.
- Standalone Cadence HDP-TX PHY(HDMI/DP) driver.
- Audio driver are removed from the patch set, it will be add in another
  patch set later.

[1] https://patchwork.kernel.org/project/linux-rockchip/cover/cover.1590982881.git.Sandor.yu at nxp.com/

Sandor Yu (7):
  drm: bridge: Cadence: Create mhdp helper driver
  phy: Add HDMI configuration options
  dt-bindings: display: bridge: Add Cadence MHDP8501
  drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
  dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
  phy: freescale: Add DisplayPort PHY driver for i.MX8MQ
  phy: freescale: Add HDMI PHY driver for i.MX8MQ

 .../display/bridge/cdns,mhdp8501.yaml         | 104 ++
 .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  |  53 +
 drivers/gpu/drm/bridge/cadence/Kconfig        |  20 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   3 +
 .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c | 304 ++++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 316 ++++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 365 +++++++
 .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 700 +++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 680 +++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 403 ++------
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  44 +-
 drivers/phy/freescale/Kconfig                 |  20 +
 drivers/phy/freescale/Makefile                |   2 +
 drivers/phy/freescale/phy-fsl-imx8mq-dp.c     | 726 +++++++++++++
 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c   | 960 ++++++++++++++++++
 include/drm/bridge/cdns-mhdp-helper.h         |  97 ++
 include/linux/phy/phy-hdmi.h                  |  24 +
 include/linux/phy/phy.h                       |   7 +-
 18 files changed, 4453 insertions(+), 375 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-dp.c
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
 create mode 100644 include/drm/bridge/cdns-mhdp-helper.h
 create mode 100644 include/linux/phy/phy-hdmi.h

-- 
2.34.1



From Sandor.yu at nxp.com  Mon Feb 19 19:23:49 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 20 Feb 2024 11:23:49 +0800
Subject: [PATCH v14 1/7] drm: bridge: Cadence: Create mhdp helper driver
In-Reply-To: <cover.1708395604.git.Sandor.yu@nxp.com>
References: <cover.1708395604.git.Sandor.yu@nxp.com>
Message-ID: <03622a9e3a649c5239948199ad34453deaf5110c.1708395604.git.Sandor.yu@nxp.com>

MHDP8546 mailbox access functions will be share to other mhdp driver
and Cadence HDP-TX HDMI/DP PHY drivers.
Create a new mhdp helper driver and move all those functions into.

cdns_mhdp_reg_write() is renamed to cdns_mhdp_dp_reg_write(),
because it use the DPTX command ID DPTX_WRITE_REGISTER.

New cdns_mhdp_reg_write() is created with the general command ID
GENERAL_REGISTER_WRITE.

rewrite cdns_mhdp_set_firmware_active() in mhdp8546 core driver,
use cdns_mhdp_mailbox_send() to replace cdns_mhdp_mailbox_write()
same as the other mailbox access functions.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
---
v12->v14:
 *No change.

V11->v12:
- Move status initialize out of mbox_mutex.
- Reorder API functions in alphabetical.
- Add notes for malibox access functions.
- Add year 2024 to copyright.

 drivers/gpu/drm/bridge/cadence/Kconfig        |   4 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   1 +
 .../gpu/drm/bridge/cadence/cdns-mhdp-helper.c | 304 +++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 403 +++---------------
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |  44 +-
 include/drm/bridge/cdns-mhdp-helper.h         |  97 +++++
 6 files changed, 479 insertions(+), 374 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
 create mode 100644 include/drm/bridge/cdns-mhdp-helper.h

diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig
index cced81633ddcd..e0973339e9e33 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -21,6 +21,9 @@ config DRM_CDNS_DSI_J721E
 	  the routing of the DSS DPI signal to the Cadence DSI.
 endif
 
+config CDNS_MHDP_HELPER
+	tristate
+
 config DRM_CDNS_MHDP8546
 	tristate "Cadence DPI/DP bridge"
 	select DRM_DISPLAY_DP_HELPER
@@ -28,6 +31,7 @@ config DRM_CDNS_MHDP8546
 	select DRM_DISPLAY_HELPER
 	select DRM_KMS_HELPER
 	select DRM_PANEL_BRIDGE
+	select CDNS_MHDP_HELPER
 	depends on OF
 	help
 	  Support Cadence DPI to DP bridge. This is an internal
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile
index c95fd5b81d137..087dc074820d7 100644
--- a/drivers/gpu/drm/bridge/cadence/Makefile
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
 cdns-dsi-y := cdns-dsi-core.o
 cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o
+obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
 cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
new file mode 100644
index 0000000000000..ba31695b483ac
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-helper.c
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <linux/dev_printk.h>
+#include <linux/module.h>
+
+/* Mailbox helper functions */
+static int cdns_mhdp_mailbox_read(struct cdns_mhdp_base *base)
+{
+	int ret, empty;
+
+	WARN_ON(!mutex_is_locked(base->mbox_mutex));
+
+	ret = readx_poll_timeout(readl, base->regs + CDNS_MAILBOX_EMPTY,
+				 empty, !empty, MAILBOX_RETRY_US,
+				 MAILBOX_TIMEOUT_US);
+	if (ret < 0)
+		return ret;
+
+	return readl(base->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
+}
+
+static int cdns_mhdp_mailbox_write(struct cdns_mhdp_base *base, u8 val)
+{
+	int ret, full;
+
+	WARN_ON(!mutex_is_locked(base->mbox_mutex));
+
+	ret = readx_poll_timeout(readl, base->regs + CDNS_MAILBOX_FULL,
+				 full, !full, MAILBOX_RETRY_US,
+				 MAILBOX_TIMEOUT_US);
+	if (ret < 0)
+		return ret;
+
+	writel(val, base->regs + CDNS_MAILBOX_TX_DATA);
+
+	return 0;
+}
+
+int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_base *base,
+				  u8 module_id, u8 opcode,
+				  u16 req_size)
+{
+	u32 mbox_size, i;
+	u8 header[4];
+	int ret;
+
+	/* read the header of the message */
+	for (i = 0; i < sizeof(header); i++) {
+		ret = cdns_mhdp_mailbox_read(base);
+		if (ret < 0)
+			return ret;
+
+		header[i] = ret;
+	}
+
+	mbox_size = get_unaligned_be16(header + 2);
+
+	if (opcode != header[0] || module_id != header[1] ||
+	    req_size != mbox_size) {
+		/*
+		 * If the message in mailbox is not what we want, we need to
+		 * clear the mailbox by reading its contents.
+		 */
+		for (i = 0; i < mbox_size; i++)
+			if (cdns_mhdp_mailbox_read(base) < 0)
+				break;
+
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_recv_header);
+
+int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_base *base,
+				u8 *buff, u16 buff_size)
+{
+	u32 i;
+	int ret;
+
+	for (i = 0; i < buff_size; i++) {
+		ret = cdns_mhdp_mailbox_read(base);
+		if (ret < 0)
+			return ret;
+
+		buff[i] = ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_recv_data);
+
+int cdns_mhdp_mailbox_send(struct cdns_mhdp_base *base, u8 module_id,
+			   u8 opcode, u16 size, u8 *message)
+{
+	u8 header[4];
+	int ret, i;
+
+	header[0] = opcode;
+	header[1] = module_id;
+	put_unaligned_be16(size, header + 2);
+
+	for (i = 0; i < sizeof(header); i++) {
+		ret = cdns_mhdp_mailbox_write(base, header[i]);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < size; i++) {
+		ret = cdns_mhdp_mailbox_write(base, message[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_mailbox_send);
+
+/* General helper functions */
+int cdns_mhdp_reg_read(struct cdns_mhdp_base *base, u32 addr, u32 *value)
+{
+	u8 msg[4], resp[8];
+	int ret;
+
+	put_unaligned_be32(addr, msg);
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_GENERAL,
+				     GENERAL_REGISTER_READ,
+				     sizeof(msg), msg);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_header(base, MB_MODULE_ID_GENERAL,
+					    GENERAL_REGISTER_READ,
+					    sizeof(resp));
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, resp, sizeof(resp));
+	if (ret)
+		goto out;
+
+	/* Returned address value should be the same as requested */
+	if (memcmp(msg, resp, sizeof(msg))) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	*value = get_unaligned_be32(resp + 4);
+
+out:
+	mutex_unlock(base->mbox_mutex);
+	if (ret) {
+		dev_err(base->dev, "Failed to read register\n");
+		*value = 0;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_reg_read);
+
+int cdns_mhdp_reg_write(struct cdns_mhdp_base *base, u32 addr, u32 val)
+{
+	u8 msg[8];
+	int ret;
+
+	put_unaligned_be32(addr, msg);
+	put_unaligned_be32(val, msg + 4);
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_GENERAL,
+				     GENERAL_REGISTER_WRITE,
+				     sizeof(msg), msg);
+
+	mutex_unlock(base->mbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_reg_write);
+
+/* DPTX helper functions */
+int cdns_mhdp_dp_reg_write(struct cdns_mhdp_base *base, u16 addr, u32 val)
+{
+	u8 msg[6];
+	int ret;
+
+	put_unaligned_be16(addr, msg);
+	put_unaligned_be32(val, msg + 2);
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_WRITE_REGISTER, sizeof(msg), msg);
+
+	mutex_unlock(base->mbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dp_reg_write);
+
+int cdns_mhdp_dp_reg_write_bit(struct cdns_mhdp_base *base, u16 addr,
+			       u8 start_bit, u8 bits_no, u32 val)
+{
+	u8 field[8];
+	int ret;
+
+	put_unaligned_be16(addr, field);
+	field[2] = start_bit;
+	field[3] = bits_no;
+	put_unaligned_be32(val, field + 4);
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_WRITE_FIELD, sizeof(field), field);
+
+	mutex_unlock(base->mbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dp_reg_write_bit);
+
+int cdns_mhdp_dpcd_read(struct cdns_mhdp_base *base,
+			u32 addr, u8 *data, u16 len)
+{
+	u8 msg[5], reg[5];
+	int ret;
+
+	put_unaligned_be16(len, msg);
+	put_unaligned_be24(addr, msg + 2);
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_READ_DPCD, sizeof(msg), msg);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_header(base, MB_MODULE_ID_DP_TX,
+					    DPTX_READ_DPCD,
+					    sizeof(reg) + len);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, reg, sizeof(reg));
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, data, len);
+
+out:
+	mutex_unlock(base->mbox_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dpcd_read);
+
+int cdns_mhdp_dpcd_write(struct cdns_mhdp_base *base, u32 addr, u8 value)
+{
+	u8 msg[6], reg[5];
+	int ret;
+
+	put_unaligned_be16(1, msg);
+	put_unaligned_be24(addr, msg + 2);
+	msg[5] = value;
+
+	mutex_lock(base->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(base, MB_MODULE_ID_DP_TX,
+				     DPTX_WRITE_DPCD, sizeof(msg), msg);
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_header(base, MB_MODULE_ID_DP_TX,
+					    DPTX_WRITE_DPCD, sizeof(reg));
+	if (ret)
+		goto out;
+
+	ret = cdns_mhdp_mailbox_recv_data(base, reg, sizeof(reg));
+	if (ret)
+		goto out;
+
+	if (addr != get_unaligned_be24(reg + 2))
+		ret = -EINVAL;
+
+out:
+	mutex_unlock(base->mbox_mutex);
+
+	if (ret)
+		dev_err(base->dev, "dpcd write failed: %d\n", ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cdns_mhdp_dpcd_write);
+
+MODULE_DESCRIPTION("Cadence MHDP Helper driver");
+MODULE_AUTHOR("Sandor Yu <Sandor.yu at nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index e226acc5c15e1..e45204e4488db 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -73,298 +73,28 @@ static void cdns_mhdp_bridge_hpd_disable(struct drm_bridge *bridge)
 	       mhdp->regs + CDNS_APB_INT_MASK);
 }
 
-static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
-{
-	int ret, empty;
-
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
-
-	ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_EMPTY,
-				 empty, !empty, MAILBOX_RETRY_US,
-				 MAILBOX_TIMEOUT_US);
-	if (ret < 0)
-		return ret;
-
-	return readl(mhdp->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
-}
-
-static int cdns_mhdp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val)
-{
-	int ret, full;
-
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
-
-	ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_FULL,
-				 full, !full, MAILBOX_RETRY_US,
-				 MAILBOX_TIMEOUT_US);
-	if (ret < 0)
-		return ret;
-
-	writel(val, mhdp->regs + CDNS_MAILBOX_TX_DATA);
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_device *mhdp,
-					 u8 module_id, u8 opcode,
-					 u16 req_size)
-{
-	u32 mbox_size, i;
-	u8 header[4];
-	int ret;
-
-	/* read the header of the message */
-	for (i = 0; i < sizeof(header); i++) {
-		ret = cdns_mhdp_mailbox_read(mhdp);
-		if (ret < 0)
-			return ret;
-
-		header[i] = ret;
-	}
-
-	mbox_size = get_unaligned_be16(header + 2);
-
-	if (opcode != header[0] || module_id != header[1] ||
-	    req_size != mbox_size) {
-		/*
-		 * If the message in mailbox is not what we want, we need to
-		 * clear the mailbox by reading its contents.
-		 */
-		for (i = 0; i < mbox_size; i++)
-			if (cdns_mhdp_mailbox_read(mhdp) < 0)
-				break;
-
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_device *mhdp,
-				       u8 *buff, u16 buff_size)
-{
-	u32 i;
-	int ret;
-
-	for (i = 0; i < buff_size; i++) {
-		ret = cdns_mhdp_mailbox_read(mhdp);
-		if (ret < 0)
-			return ret;
-
-		buff[i] = ret;
-	}
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id,
-				  u8 opcode, u16 size, u8 *message)
-{
-	u8 header[4];
-	int ret, i;
-
-	header[0] = opcode;
-	header[1] = module_id;
-	put_unaligned_be16(size, header + 2);
-
-	for (i = 0; i < sizeof(header); i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, header[i]);
-		if (ret)
-			return ret;
-	}
-
-	for (i = 0; i < size; i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, message[i]);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-static
-int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr, u32 *value)
-{
-	u8 msg[4], resp[8];
-	int ret;
-
-	put_unaligned_be32(addr, msg);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL,
-				     GENERAL_REGISTER_READ,
-				     sizeof(msg), msg);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_GENERAL,
-					    GENERAL_REGISTER_READ,
-					    sizeof(resp));
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, resp, sizeof(resp));
-	if (ret)
-		goto out;
-
-	/* Returned address value should be the same as requested */
-	if (memcmp(msg, resp, sizeof(msg))) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	*value = get_unaligned_be32(resp + 4);
-
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
-	if (ret) {
-		dev_err(mhdp->dev, "Failed to read register\n");
-		*value = 0;
-	}
-
-	return ret;
-}
-
-static
-int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u16 addr, u32 val)
-{
-	u8 msg[6];
-	int ret;
-
-	put_unaligned_be16(addr, msg);
-	put_unaligned_be32(val, msg + 2);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_REGISTER, sizeof(msg), msg);
-
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
 static
-int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr,
-			    u8 start_bit, u8 bits_no, u32 val)
-{
-	u8 field[8];
-	int ret;
-
-	put_unaligned_be16(addr, field);
-	field[2] = start_bit;
-	field[3] = bits_no;
-	put_unaligned_be32(val, field + 4);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_FIELD, sizeof(field), field);
-
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
-static
-int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp,
-			u32 addr, u8 *data, u16 len)
-{
-	u8 msg[5], reg[5];
-	int ret;
-
-	put_unaligned_be16(len, msg);
-	put_unaligned_be24(addr, msg + 2);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_READ_DPCD, sizeof(msg), msg);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
-					    DPTX_READ_DPCD,
-					    sizeof(reg) + len);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, data, len);
-
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
-static
-int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value)
+int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable)
 {
-	u8 msg[6], reg[5];
+	u8 status;
 	int ret;
 
-	put_unaligned_be16(1, msg);
-	put_unaligned_be24(addr, msg + 2);
-	msg[5] = value;
+	status = enable ? FW_ACTIVE : FW_STANDBY;
 
 	mutex_lock(&mhdp->mbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_DPCD, sizeof(msg), msg);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
-					    DPTX_WRITE_DPCD, sizeof(reg));
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_GENERAL,
+				     GENERAL_MAIN_CONTROL, sizeof(status), &status);
 	if (ret)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
-	if (ret)
-		goto out;
-
-	if (addr != get_unaligned_be24(reg + 2))
-		ret = -EINVAL;
-
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	if (ret)
-		dev_err(mhdp->dev, "dpcd write failed: %d\n", ret);
-	return ret;
-}
-
-static
-int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable)
-{
-	u8 msg[5];
-	int ret, i;
-
-	msg[0] = GENERAL_MAIN_CONTROL;
-	msg[1] = MB_MODULE_ID_GENERAL;
-	msg[2] = 0;
-	msg[3] = 1;
-	msg[4] = enable ? FW_ACTIVE : FW_STANDBY;
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	for (i = 0; i < sizeof(msg); i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, msg[i]);
-		if (ret)
-			goto out;
-	}
-
-	/* read the firmware state */
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, msg, sizeof(msg));
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_GENERAL,
+					    GENERAL_MAIN_CONTROL,
+					    sizeof(status));
 	if (ret)
 		goto out;
 
-	ret = 0;
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
 
 out:
 	mutex_unlock(&mhdp->mbox_mutex);
@@ -382,18 +112,18 @@ int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp)
 
 	mutex_lock(&mhdp->mbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 				     DPTX_HPD_STATE, 0, NULL);
 	if (ret)
 		goto err_get_hpd;
 
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 					    DPTX_HPD_STATE,
 					    sizeof(status));
 	if (ret)
 		goto err_get_hpd;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, &status, sizeof(status));
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
 	if (ret)
 		goto err_get_hpd;
 
@@ -424,22 +154,22 @@ int cdns_mhdp_get_edid_block(void *data, u8 *edid,
 		msg[0] = block / 2;
 		msg[1] = block % 2;
 
-		ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 					     DPTX_GET_EDID, sizeof(msg), msg);
 		if (ret)
 			continue;
 
-		ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 						    DPTX_GET_EDID,
 						    sizeof(reg) + length);
 		if (ret)
 			continue;
 
-		ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
 		if (ret)
 			continue;
 
-		ret = cdns_mhdp_mailbox_recv_data(mhdp, edid, length);
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid, length);
 		if (ret)
 			continue;
 
@@ -464,17 +194,17 @@ int cdns_mhdp_read_hpd_event(struct cdns_mhdp_device *mhdp)
 
 	mutex_lock(&mhdp->mbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 				     DPTX_READ_EVENT, 0, NULL);
 	if (ret)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 					    DPTX_READ_EVENT, sizeof(event));
 	if (ret < 0)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, &event, sizeof(event));
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &event, sizeof(event));
 out:
 	mutex_unlock(&mhdp->mbox_mutex);
 
@@ -512,20 +242,20 @@ int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, unsigned int nlanes,
 
 	mutex_lock(&mhdp->mbox_mutex);
 
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
 				     DPTX_ADJUST_LT,
 				     sizeof(payload), payload);
 	if (ret)
 		goto out;
 
 	/* Yes, read the DPCD read command response */
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_DP_TX,
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
 					    DPTX_READ_DPCD,
 					    sizeof(hdr) + DP_LINK_STATUS_SIZE);
 	if (ret)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, hdr, sizeof(hdr));
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, hdr, sizeof(hdr));
 	if (ret)
 		goto out;
 
@@ -533,7 +263,7 @@ int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, unsigned int nlanes,
 	if (addr != DP_LANE0_1_STATUS)
 		goto out;
 
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, link_status,
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, link_status,
 					  DP_LINK_STATUS_SIZE);
 
 out:
@@ -847,7 +577,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux,
 		unsigned int i;
 
 		for (i = 0; i < msg->size; ++i) {
-			ret = cdns_mhdp_dpcd_write(mhdp,
+			ret = cdns_mhdp_dpcd_write(&mhdp->base,
 						   msg->address + i, buf[i]);
 			if (!ret)
 				continue;
@@ -859,7 +589,7 @@ static ssize_t cdns_mhdp_transfer(struct drm_dp_aux *aux,
 			return ret;
 		}
 	} else {
-		ret = cdns_mhdp_dpcd_read(mhdp, msg->address,
+		ret = cdns_mhdp_dpcd_read(&mhdp->base, msg->address,
 					  msg->buffer, msg->size);
 		if (ret) {
 			dev_err(mhdp->dev,
@@ -887,12 +617,12 @@ static int cdns_mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 	if (!mhdp->host.scrambler)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_ENHNCD,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_ENHNCD,
 			    mhdp->sink.enhanced & mhdp->host.enhanced);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_LANE_EN,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_LANE_EN,
 			    CDNS_DP_LANE_EN_LANES(mhdp->link.num_lanes));
 
 	cdns_mhdp_link_configure(&mhdp->aux, &mhdp->link);
@@ -913,7 +643,7 @@ static int cdns_mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 		return ret;
 	}
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG,
 			    CDNS_PHY_COMMON_CONFIG |
 			    CDNS_PHY_TRAINING_EN |
 			    CDNS_PHY_TRAINING_TYPE(1) |
@@ -1058,7 +788,7 @@ static bool cdns_mhdp_link_training_channel_eq(struct cdns_mhdp_device *mhdp,
 		CDNS_PHY_TRAINING_TYPE(eq_tps);
 	if (eq_tps != 4)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
 	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 			   (eq_tps != 4) ? eq_tps | DP_LINK_SCRAMBLING_DISABLE :
@@ -1322,7 +1052,7 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp,
 			   mhdp->host.scrambler ? 0 :
 			   DP_LINK_SCRAMBLING_DISABLE);
 
-	ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &reg32);
+	ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &reg32);
 	if (ret < 0) {
 		dev_err(mhdp->dev,
 			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
@@ -1333,13 +1063,13 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp,
 	reg32 |= CDNS_DP_NUM_LANES(mhdp->link.num_lanes);
 	reg32 |= CDNS_DP_WR_FAILING_EDGE_VSYNC;
 	reg32 |= CDNS_DP_FRAMER_EN;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg32);
 
 	/* Reset PHY config */
 	reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
 	if (!mhdp->host.scrambler)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
 	return 0;
 err:
@@ -1347,7 +1077,7 @@ static int cdns_mhdp_link_training(struct cdns_mhdp_device *mhdp,
 	reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
 	if (!mhdp->host.scrambler)
 		reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_PHY_CONFIG, reg32);
 
 	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 			   DP_TRAINING_PATTERN_DISABLE);
@@ -1461,7 +1191,7 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
 	mhdp->link.num_lanes = cdns_mhdp_max_num_lanes(mhdp);
 
 	/* Disable framer for link training */
-	err = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
+	err = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
 	if (err < 0) {
 		dev_err(mhdp->dev,
 			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
@@ -1470,7 +1200,7 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
 	}
 
 	resp &= ~CDNS_DP_FRAMER_EN;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
 
 	/* Spread AMP if required, enable 8b/10b coding */
 	amp[0] = cdns_mhdp_get_ssc_supported(mhdp) ? DP_SPREAD_AMP_0_5 : 0;
@@ -1839,7 +1569,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 		bnd_hsync2vsync |= CDNS_IP_DET_INTERLACE_FORMAT;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_BND_HSYNC2VSYNC(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_BND_HSYNC2VSYNC(stream_id),
 			    bnd_hsync2vsync);
 
 	hsync2vsync_pol_ctrl = 0;
@@ -1847,10 +1577,10 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 		hsync2vsync_pol_ctrl |= CDNS_H2V_HSYNC_POL_ACTIVE_LOW;
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 		hsync2vsync_pol_ctrl |= CDNS_H2V_VSYNC_POL_ACTIVE_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_HSYNC2VSYNC_POL_CTRL(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_HSYNC2VSYNC_POL_CTRL(stream_id),
 			    hsync2vsync_pol_ctrl);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_PXL_REPR(stream_id), pxl_repr);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_PXL_REPR(stream_id), pxl_repr);
 
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 		dp_framer_sp |= CDNS_DP_FRAMER_INTERLACE;
@@ -1858,19 +1588,19 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 		dp_framer_sp |= CDNS_DP_FRAMER_HSYNC_POL_LOW;
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 		dp_framer_sp |= CDNS_DP_FRAMER_VSYNC_POL_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_SP(stream_id), dp_framer_sp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_SP(stream_id), dp_framer_sp);
 
 	front_porch = mode->crtc_hsync_start - mode->crtc_hdisplay;
 	back_porch = mode->crtc_htotal - mode->crtc_hsync_end;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRONT_BACK_PORCH(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRONT_BACK_PORCH(stream_id),
 			    CDNS_DP_FRONT_PORCH(front_porch) |
 			    CDNS_DP_BACK_PORCH(back_porch));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_BYTE_COUNT(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_BYTE_COUNT(stream_id),
 			    mode->crtc_hdisplay * bpp / 8);
 
 	msa_h0 = mode->crtc_htotal - mode->crtc_hsync_start;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_0(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_HORIZONTAL_0(stream_id),
 			    CDNS_DP_MSAH0_H_TOTAL(mode->crtc_htotal) |
 			    CDNS_DP_MSAH0_HSYNC_START(msa_h0));
 
@@ -1879,11 +1609,11 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 			   CDNS_DP_MSAH1_HDISP_WIDTH(mode->crtc_hdisplay);
 	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 		msa_horizontal_1 |= CDNS_DP_MSAH1_HSYNC_POL_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_1(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_HORIZONTAL_1(stream_id),
 			    msa_horizontal_1);
 
 	msa_v0 = mode->crtc_vtotal - mode->crtc_vsync_start;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_0(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_VERTICAL_0(stream_id),
 			    CDNS_DP_MSAV0_V_TOTAL(mode->crtc_vtotal) |
 			    CDNS_DP_MSAV0_VSYNC_START(msa_v0));
 
@@ -1892,7 +1622,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 			 CDNS_DP_MSAV1_VDISP_WIDTH(mode->crtc_vdisplay);
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 		msa_vertical_1 |= CDNS_DP_MSAV1_VSYNC_POL_LOW;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_1(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_VERTICAL_1(stream_id),
 			    msa_vertical_1);
 
 	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
@@ -1904,14 +1634,14 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	if (pxlfmt == DRM_COLOR_FORMAT_YCBCR420)
 		misc1 = CDNS_DP_TEST_VSC_SDP;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_MISC(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_MSA_MISC(stream_id),
 			    misc0 | (misc1 << 8));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_HORIZONTAL(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_HORIZONTAL(stream_id),
 			    CDNS_DP_H_HSYNC_WIDTH(hsync) |
 			    CDNS_DP_H_H_TOTAL(mode->crtc_hdisplay));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_0(stream_id),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_VERTICAL_0(stream_id),
 			    CDNS_DP_V0_VHEIGHT(mode->crtc_vdisplay) |
 			    CDNS_DP_V0_VSTART(msa_v0));
 
@@ -1920,13 +1650,13 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	    mode->crtc_vtotal % 2 == 0)
 		dp_vertical_1 |= CDNS_DP_V1_VTOTAL_EVEN;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_1(stream_id), dp_vertical_1);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_VERTICAL_1(stream_id), dp_vertical_1);
 
-	cdns_mhdp_reg_write_bit(mhdp, CDNS_DP_VB_ID(stream_id), 2, 1,
-				(mode->flags & DRM_MODE_FLAG_INTERLACE) ?
-				CDNS_DP_VB_ID_INTERLACED : 0);
+	cdns_mhdp_dp_reg_write_bit(&mhdp->base, CDNS_DP_VB_ID(stream_id), 2, 1,
+				   (mode->flags & DRM_MODE_FLAG_INTERLACE) ?
+				   CDNS_DP_VB_ID_INTERLACED : 0);
 
-	ret = cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer);
+	ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &framer);
 	if (ret < 0) {
 		dev_err(mhdp->dev,
 			"Failed to read CDNS_DP_FRAMER_GLOBAL_CONFIG %d\n",
@@ -1935,7 +1665,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp,
 	}
 	framer |= CDNS_DP_FRAMER_EN;
 	framer &= ~CDNS_DP_NO_VIDEO_MODE;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, framer);
 }
 
 static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp,
@@ -1968,15 +1698,15 @@ static void cdns_mhdp_sst_enable(struct cdns_mhdp_device *mhdp,
 
 	mhdp->stream_id = 0;
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_TU,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_TU,
 			    CDNS_DP_FRAMER_TU_VS(vs) |
 			    CDNS_DP_FRAMER_TU_SIZE(tu_size) |
 			    CDNS_DP_FRAMER_TU_CNT_RST_EN);
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_LINE_THRESH(0),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_LINE_THRESH(0),
 			    line_thresh & GENMASK(5, 0));
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_STREAM_CONFIG_2(0),
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_STREAM_CONFIG_2(0),
 			    CDNS_DP_SC2_TU_VS_DIFF((tu_size - vs > 3) ?
 						   0 : tu_size - vs));
 
@@ -2011,13 +1741,13 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
 		mhdp->info->ops->enable(mhdp);
 
 	/* Enable VIF clock for stream 0 */
-	ret = cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
+	ret = cdns_mhdp_reg_read(&mhdp->base, CDNS_DPTX_CAR, &resp);
 	if (ret < 0) {
 		dev_err(mhdp->dev, "Failed to read CDNS_DPTX_CAR %d\n", ret);
 		goto out;
 	}
 
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_CAR,
 			    resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN);
 
 	connector = drm_atomic_get_new_connector_for_encoder(state,
@@ -2085,16 +1815,16 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
 		cdns_mhdp_hdcp_disable(mhdp);
 
 	mhdp->bridge_enabled = false;
-	cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
+	cdns_mhdp_reg_read(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
 	resp &= ~CDNS_DP_FRAMER_EN;
 	resp |= CDNS_DP_NO_VIDEO_MODE;
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DP_FRAMER_GLOBAL_CONFIG, resp);
 
 	cdns_mhdp_link_down(mhdp);
 
 	/* Disable VIF clock for stream 0 */
-	cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
-	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
+	cdns_mhdp_reg_read(&mhdp->base, CDNS_DPTX_CAR, &resp);
+	cdns_mhdp_reg_write(&mhdp->base, CDNS_DPTX_CAR,
 			    resp & ~(CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN));
 
 	if (mhdp->info && mhdp->info->ops && mhdp->info->ops->disable)
@@ -2504,6 +2234,11 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, mhdp);
 
+	/* init base struct for access mailbox  */
+	mhdp->base.dev = mhdp->dev;
+	mhdp->base.regs = mhdp->regs;
+	mhdp->base.mbox_mutex = &mhdp->mbox_mutex;
+
 	mhdp->info = of_device_get_match_data(dev);
 
 	clk_prepare_enable(clk);
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
index bad2fc0c73066..f08db38c82bbd 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h
@@ -15,6 +15,7 @@
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 
+#include <drm/bridge/cdns-mhdp-helper.h>
 #include <drm/display/drm_dp_helper.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_connector.h>
@@ -27,10 +28,6 @@ struct phy;
 #define CDNS_APB_CTRL				0x00000
 #define CDNS_CPU_STALL				BIT(3)
 
-#define CDNS_MAILBOX_FULL			0x00008
-#define CDNS_MAILBOX_EMPTY			0x0000c
-#define CDNS_MAILBOX_TX_DATA			0x00010
-#define CDNS_MAILBOX_RX_DATA			0x00014
 #define CDNS_KEEP_ALIVE				0x00018
 #define CDNS_KEEP_ALIVE_MASK			GENMASK(7, 0)
 
@@ -198,45 +195,10 @@ struct phy;
 #define CDNS_DP_BYTE_COUNT(s)			(CDNS_DPTX_STREAM(s) + 0x7c)
 #define CDNS_DP_BYTE_COUNT_BYTES_IN_CHUNK_SHIFT	16
 
-/* mailbox */
-#define MAILBOX_RETRY_US			1000
-#define MAILBOX_TIMEOUT_US			2000000
-
-#define MB_OPCODE_ID				0
-#define MB_MODULE_ID				1
-#define MB_SIZE_MSB_ID				2
-#define MB_SIZE_LSB_ID				3
-#define MB_DATA_ID				4
-
-#define MB_MODULE_ID_DP_TX			0x01
-#define MB_MODULE_ID_HDCP_TX			0x07
-#define MB_MODULE_ID_HDCP_RX			0x08
-#define MB_MODULE_ID_HDCP_GENERAL		0x09
-#define MB_MODULE_ID_GENERAL			0x0a
-
-/* firmware and opcodes */
+/* firmware */
 #define FW_NAME					"cadence/mhdp8546.bin"
 #define CDNS_MHDP_IMEM				0x10000
 
-#define GENERAL_MAIN_CONTROL			0x01
-#define GENERAL_TEST_ECHO			0x02
-#define GENERAL_BUS_SETTINGS			0x03
-#define GENERAL_TEST_ACCESS			0x04
-#define GENERAL_REGISTER_READ			0x07
-
-#define DPTX_SET_POWER_MNG			0x00
-#define DPTX_GET_EDID				0x02
-#define DPTX_READ_DPCD				0x03
-#define DPTX_WRITE_DPCD				0x04
-#define DPTX_ENABLE_EVENT			0x05
-#define DPTX_WRITE_REGISTER			0x06
-#define DPTX_READ_REGISTER			0x07
-#define DPTX_WRITE_FIELD			0x08
-#define DPTX_READ_EVENT				0x0a
-#define DPTX_GET_LAST_AUX_STAUS			0x0e
-#define DPTX_HPD_STATE				0x11
-#define DPTX_ADJUST_LT				0x12
-
 #define FW_STANDBY				0
 #define FW_ACTIVE				1
 
@@ -352,6 +314,8 @@ struct cdns_mhdp_hdcp {
 };
 
 struct cdns_mhdp_device {
+	struct cdns_mhdp_base base;
+
 	void __iomem *regs;
 	void __iomem *sapb_regs;
 	void __iomem *j721e_regs;
diff --git a/include/drm/bridge/cdns-mhdp-helper.h b/include/drm/bridge/cdns-mhdp-helper.h
new file mode 100644
index 0000000000000..cdc124cd9c479
--- /dev/null
+++ b/include/drm/bridge/cdns-mhdp-helper.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 NXP Semiconductor, Inc.
+ */
+#ifndef __CDNS_MHDP_HELPER_H__
+#define __CDNS_MHDP_HELPER_H__
+
+#include <asm/unaligned.h>
+#include <linux/iopoll.h>
+
+/* mailbox regs offset */
+#define CDNS_MAILBOX_FULL			0x00008
+#define CDNS_MAILBOX_EMPTY			0x0000c
+#define CDNS_MAILBOX_TX_DATA			0x00010
+#define CDNS_MAILBOX_RX_DATA			0x00014
+
+#define MAILBOX_RETRY_US			1000
+#define MAILBOX_TIMEOUT_US			2000000
+
+/* Module ID Code */
+#define MB_MODULE_ID_DP_TX			0x01
+#define MB_MODULE_ID_HDMI_TX			0x03
+#define MB_MODULE_ID_HDCP_TX			0x07
+#define MB_MODULE_ID_HDCP_RX			0x08
+#define MB_MODULE_ID_HDCP_GENERAL		0x09
+#define MB_MODULE_ID_GENERAL			0x0A
+
+/* General Commands */
+#define GENERAL_MAIN_CONTROL			0x01
+#define GENERAL_TEST_ECHO			0x02
+#define GENERAL_BUS_SETTINGS			0x03
+#define GENERAL_TEST_ACCESS			0x04
+#define GENERAL_REGISTER_WRITE			0x05
+#define GENERAL_WRITE_FIELD			0x06
+#define GENERAL_REGISTER_READ			0x07
+#define GENERAL_GET_HPD_STATE			0x11
+
+/* DPTX Commands */
+#define DPTX_SET_POWER_MNG			0x00
+#define DPTX_SET_HOST_CAPABILITIES		0x01
+#define DPTX_GET_EDID				0x02
+#define DPTX_READ_DPCD				0x03
+#define DPTX_WRITE_DPCD				0x04
+#define DPTX_ENABLE_EVENT			0x05
+#define DPTX_WRITE_REGISTER			0x06
+#define DPTX_READ_REGISTER			0x07
+#define DPTX_WRITE_FIELD			0x08
+#define DPTX_TRAINING_CONTROL			0x09
+#define DPTX_READ_EVENT				0x0a
+#define DPTX_READ_LINK_STAT			0x0b
+#define DPTX_SET_VIDEO				0x0c
+#define DPTX_SET_AUDIO				0x0d
+#define DPTX_GET_LAST_AUX_STAUS			0x0e
+#define DPTX_SET_LINK_BREAK_POINT		0x0f
+#define DPTX_FORCE_LANES			0x10
+#define DPTX_HPD_STATE				0x11
+#define DPTX_ADJUST_LT				0x12
+
+/* HDMI TX Commands */
+#define HDMI_TX_READ				0x00
+#define HDMI_TX_WRITE				0x01
+#define HDMI_TX_UPDATE_READ			0x02
+#define HDMI_TX_EDID				0x03
+#define HDMI_TX_EVENTS				0x04
+#define HDMI_TX_HPD_STATUS			0x05
+
+struct cdns_mhdp_base {
+	struct device *dev;
+	void __iomem *regs;
+	/* protect mailbox communications with the firmware */
+	struct mutex *mbox_mutex;
+};
+
+/* Mailbox helper functions
+ * mbox_mutex in struct cdns_mhdp_base should locked
+ * when access these functions.
+ */
+int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_base *base,
+				u8 *buff, u16 buff_size);
+int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_base *base,
+				  u8 module_id, u8 opcode, u16 req_size);
+int cdns_mhdp_mailbox_send(struct cdns_mhdp_base *base, u8 module_id,
+			   u8 opcode, u16 size, u8 *message);
+
+/* General commands helper functions */
+int cdns_mhdp_reg_read(struct cdns_mhdp_base *base, u32 addr, u32 *value);
+int cdns_mhdp_reg_write(struct cdns_mhdp_base *base, u32 addr, u32 val);
+
+/* DPTX commands helper functions */
+int cdns_mhdp_dp_reg_write(struct cdns_mhdp_base *base, u16 addr, u32 val);
+int cdns_mhdp_dp_reg_write_bit(struct cdns_mhdp_base *base, u16 addr,
+			       u8 start_bit, u8 bits_no, u32 val);
+int cdns_mhdp_dpcd_read(struct cdns_mhdp_base *base,
+			u32 addr, u8 *data, u16 len);
+int cdns_mhdp_dpcd_write(struct cdns_mhdp_base *base, u32 addr, u8 value);
+
+#endif /* __CDNS_MHDP_HELPER_H__ */
-- 
2.34.1



From Sandor.yu at nxp.com  Mon Feb 19 19:23:50 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 20 Feb 2024 11:23:50 +0800
Subject: [PATCH v14 2/7] phy: Add HDMI configuration options
In-Reply-To: <cover.1708395604.git.Sandor.yu@nxp.com>
References: <cover.1708395604.git.Sandor.yu@nxp.com>
Message-ID: <064ffb53f4ecf25f5d07f64d050ae0a4646ed9fc.1708395604.git.Sandor.yu@nxp.com>

Allow HDMI PHYs to be configured through the generic
functions through a custom structure added to the generic union.

The parameters added here are based on HDMI PHY
implementation practices.  The current set of parameters
should cover the potential users.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Acked-by: Vinod Koul <vkoul at kernel.org>
---
v9->v14:
 *No change.

 include/linux/phy/phy-hdmi.h | 24 ++++++++++++++++++++++++
 include/linux/phy/phy.h      |  7 ++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/phy/phy-hdmi.h

diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
new file mode 100644
index 0000000000000..b7de88e9090f0
--- /dev/null
+++ b/include/linux/phy/phy-hdmi.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022 NXP
+ */
+
+#ifndef __PHY_HDMI_H_
+#define __PHY_HDMI_H_
+
+#include <linux/hdmi.h>
+/**
+ * struct phy_configure_opts_hdmi - HDMI configuration set
+ * @pixel_clk_rate: Pixel clock of video modes in KHz.
+ * @bpc: Maximum bits per color channel.
+ * @color_space: Colorspace in enum hdmi_colorspace.
+ *
+ * This structure is used to represent the configuration state of a HDMI phy.
+ */
+struct phy_configure_opts_hdmi {
+	unsigned int pixel_clk_rate;
+	unsigned int bpc;
+	enum hdmi_colorspace color_space;
+};
+
+#endif /* __PHY_HDMI_H_ */
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index aa76609ba2580..0731b8b707f7c 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -17,6 +17,7 @@
 #include <linux/regulator/consumer.h>
 
 #include <linux/phy/phy-dp.h>
+#include <linux/phy/phy-hdmi.h>
 #include <linux/phy/phy-lvds.h>
 #include <linux/phy/phy-mipi-dphy.h>
 
@@ -42,7 +43,8 @@ enum phy_mode {
 	PHY_MODE_MIPI_DPHY,
 	PHY_MODE_SATA,
 	PHY_MODE_LVDS,
-	PHY_MODE_DP
+	PHY_MODE_DP,
+	PHY_MODE_HDMI,
 };
 
 enum phy_media {
@@ -60,11 +62,14 @@ enum phy_media {
  *		the DisplayPort protocol.
  * @lvds:	Configuration set applicable for phys supporting
  *		the LVDS phy mode.
+ * @hdmi:	Configuration set applicable for phys supporting
+ *		the HDMI phy mode.
  */
 union phy_configure_opts {
 	struct phy_configure_opts_mipi_dphy	mipi_dphy;
 	struct phy_configure_opts_dp		dp;
 	struct phy_configure_opts_lvds		lvds;
+	struct phy_configure_opts_hdmi		hdmi;
 };
 
 /**
-- 
2.34.1



From Sandor.yu at nxp.com  Mon Feb 19 19:23:51 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 20 Feb 2024 11:23:51 +0800
Subject: [PATCH v14 3/7] dt-bindings: display: bridge: Add Cadence MHDP8501
In-Reply-To: <cover.1708395604.git.Sandor.yu@nxp.com>
References: <cover.1708395604.git.Sandor.yu@nxp.com>
Message-ID: <d9cb461b0de2aed1a38520aa7b754f081a0f85cf.1708395604.git.Sandor.yu@nxp.com>

Add bindings for Cadence MHDP8501 DisplayPort/HDMI bridge.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
v9->v14:
 *No change.

 .../display/bridge/cdns,mhdp8501.yaml         | 104 ++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml

diff --git a/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
new file mode 100644
index 0000000000000..3ae643845cfee
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/cdns,mhdp8501.yaml
@@ -0,0 +1,104 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/cdns,mhdp8501.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence MHDP8501 DP/HDMI bridge
+
+maintainers:
+  - Sandor Yu <Sandor.yu at nxp.com>
+
+description:
+  Cadence MHDP8501 DisplayPort/HDMI interface.
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mq-mhdp8501
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: MHDP8501 DP/HDMI APB clock.
+
+  phys:
+    maxItems: 1
+    description:
+      phandle to the DisplayPort or HDMI PHY
+
+  interrupts:
+    items:
+      - description: Hotplug cable plugin.
+      - description: Hotplug cable plugout.
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Input port from display controller output.
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output port to DisplayPort or HDMI connector.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+  - phys
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    mhdp: display-bridge at 32c00000 {
+        compatible = "fsl,imx8mq-mhdp8501";
+        reg = <0x32c00000 0x100000>;
+        interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "plug_in", "plug_out";
+        clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        phys = <&dp_phy>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+
+                mhdp_in: endpoint {
+                    remote-endpoint = <&dcss_out>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+
+                mhdp_out: endpoint {
+                    remote-endpoint = <&dp_connector>;
+                };
+            };
+        };
+    };
-- 
2.34.1



From Sandor.yu at nxp.com  Mon Feb 19 19:23:55 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 20 Feb 2024 11:23:55 +0800
Subject: [PATCH v14 7/7] phy: freescale: Add HDMI PHY driver for i.MX8MQ
In-Reply-To: <cover.1708395604.git.Sandor.yu@nxp.com>
References: <cover.1708395604.git.Sandor.yu@nxp.com>
Message-ID: <eb8c8aa5e5511d2bd462d05022764f67f7bb47c9.1708395604.git.Sandor.yu@nxp.com>

Add Cadence HDP-TX HDMI PHY driver for i.MX8MQ.

Cadence HDP-TX PHY could be put in either DP mode or
HDMI mode base on the configuration chosen.
HDMI PHY mode is configurated in the driver.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
v13->v14:
 *No change.

v12->v13:
- Fix build warning

v11->v12:
- Adjust clk disable order.
- Return error code to replace -1 for function wait_for_ack().
- Use bool for variable pclk_in.
- Add year 2024 to copyright.

 drivers/phy/freescale/Kconfig               |  10 +
 drivers/phy/freescale/Makefile              |   1 +
 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c | 960 ++++++++++++++++++++
 3 files changed, 971 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index c39709fd700ac..14f47b7cc77ab 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -45,6 +45,16 @@ config PHY_FSL_IMX8MQ_DP
 	  Enable this to support the Cadence HDPTX DP PHY driver
 	  on i.MX8MQ SOC.
 
+config PHY_FSL_IMX8MQ_HDMI
+	tristate "Freescale i.MX8MQ HDMI PHY support"
+	depends on OF && HAS_IOMEM
+	depends on COMMON_CLK
+	select GENERIC_PHY
+	select CDNS_MHDP_HELPER
+	help
+	  Enable this to support the Cadence HDPTX HDMI PHY driver
+	  on i.MX8MQ SOC.
+
 endif
 
 config PHY_FSL_LYNX_28G
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index 47e5285209fa8..1380ac31c2ead 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_FSL_IMX8MQ_DP)		+= phy-fsl-imx8mq-dp.o
+obj-$(CONFIG_PHY_FSL_IMX8MQ_HDMI)	+= phy-fsl-imx8mq-hdmi.o
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)	+= phy-fsl-imx8mq-usb.o
 obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
new file mode 100644
index 0000000000000..537b1f45c91cc
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
@@ -0,0 +1,960 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence High-Definition Multimedia Interface (HDMI) PHY driver
+ *
+ * Copyright (C) 2022-2024 NXP Semiconductor, Inc.
+ */
+#include <asm/unaligned.h>
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#define ADDR_PHY_AFE	0x80000
+
+/* PHY registers */
+#define CMN_SSM_BIAS_TMR			0x0022
+#define CMN_PLLSM0_USER_DEF_CTRL		0x002f
+#define CMN_PSM_CLK_CTRL			0x0061
+#define CMN_CDIAG_REFCLK_CTRL			0x0062
+#define CMN_PLL0_VCOCAL_START			0x0081
+#define CMN_PLL0_VCOCAL_INIT_TMR		0x0084
+#define CMN_PLL0_VCOCAL_ITER_TMR		0x0085
+#define CMN_TXPUCAL_CTRL			0x00e0
+#define CMN_TXPDCAL_CTRL			0x00f0
+#define CMN_TXPU_ADJ_CTRL			0x0108
+#define CMN_TXPD_ADJ_CTRL			0x010c
+#define CMN_DIAG_PLL0_FBH_OVRD			0x01c0
+#define CMN_DIAG_PLL0_FBL_OVRD			0x01c1
+#define CMN_DIAG_PLL0_OVRD			0x01c2
+#define CMN_DIAG_PLL0_TEST_MODE			0x01c4
+#define CMN_DIAG_PLL0_V2I_TUNE			0x01c5
+#define CMN_DIAG_PLL0_CP_TUNE			0x01c6
+#define CMN_DIAG_PLL0_LF_PROG			0x01c7
+#define CMN_DIAG_PLL0_PTATIS_TUNE1		0x01c8
+#define CMN_DIAG_PLL0_PTATIS_TUNE2		0x01c9
+#define CMN_DIAG_PLL0_INCLK_CTRL		0x01ca
+#define CMN_DIAG_PLL0_PXL_DIVH			0x01cb
+#define CMN_DIAG_PLL0_PXL_DIVL			0x01cc
+#define CMN_DIAG_HSCLK_SEL			0x01e0
+#define XCVR_PSM_RCTRL				0x4001
+#define TX_TXCC_CAL_SCLR_MULT_0			0x4047
+#define TX_TXCC_CPOST_MULT_00_0			0x404c
+#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
+#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
+#define XCVR_DIAG_HSCLK_SEL			0x40e1
+#define XCVR_DIAG_BIDI_CTRL			0x40e8
+#define TX_PSC_A0				0x4100
+#define TX_PSC_A1				0x4101
+#define TX_PSC_A2				0x4102
+#define TX_PSC_A3				0x4103
+#define TX_DIAG_TX_CTRL				0x41e0
+#define TX_DIAG_TX_DRV				0x41e1
+#define TX_DIAG_BGREF_PREDRV_DELAY		0x41e7
+#define TX_DIAG_ACYA_0				0x41ff
+#define TX_DIAG_ACYA_1				0x43ff
+#define TX_DIAG_ACYA_2				0x45ff
+#define TX_DIAG_ACYA_3				0x47ff
+#define TX_ANA_CTRL_REG_1			0x5020
+#define TX_ANA_CTRL_REG_2			0x5021
+#define TX_DIG_CTRL_REG_2			0x5024
+#define TXDA_CYA_AUXDA_CYA			0x5025
+#define TX_ANA_CTRL_REG_3			0x5026
+#define TX_ANA_CTRL_REG_4			0x5027
+#define TX_ANA_CTRL_REG_5			0x5029
+#define RX_PSC_A0				0x8000
+#define RX_PSC_CAL				0x8006
+#define PHY_HDP_MODE_CTRL			0xc008
+#define PHY_HDP_CLK_CTL				0xc009
+#define PHY_ISO_CMN_CTRL			0xc010
+#define PHY_PMA_CMN_CTRL1			0xc800
+#define PHY_PMA_ISO_CMN_CTRL			0xc810
+#define PHY_PMA_ISO_PLL_CTRL1			0xc812
+#define PHY_PMA_ISOLATION_CTRL			0xc81f
+
+/* PHY_HDP_CLK_CTL */
+#define PLL_DATA_RATE_CLK_DIV_MASK		GENMASK(15, 8)
+#define PLL_DATA_RATE_CLK_DIV_HBR		0x24
+#define PLL_DATA_RATE_CLK_DIV_HBR2		0x12
+#define PLL_CLK_EN_ACK_EN			BIT(3)
+#define PLL_CLK_EN				BIT(2)
+#define PLL_READY				BIT(1)
+#define PLL_EN					BIT(0)
+
+/* PHY_PMA_CMN_CTRL1 */
+#define CMA_REF_CLK_DIG_DIV_MASK		GENMASK(13, 12)
+#define CMA_REF_CLK_SEL_MASK			GENMASK(6, 4)
+#define CMA_REF_CLK_RCV_EN_MASK			BIT(3)
+#define CMA_REF_CLK_RCV_EN			1
+#define CMN_READY				BIT(0)
+
+/* PHY_PMA_ISO_PLL_CTRL1 */
+#define CMN_PLL0_CLK_DATART_DIV_MASK		GENMASK(7, 0)
+
+/* TX_DIAG_TX_DRV */
+#define TX_DRIVER_PROG_BOOST_ENABLE		BIT(10)
+#define TX_DRIVER_PROG_BOOST_LEVEL_MASK		GENMASK(9, 8)
+#define TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE	BIT(7)
+#define TX_DRIVER_LDO_BANDGAP_REF_ENABLE	BIT(6)
+
+/* TX_TXCC_CAL_SCLR_MULT_0 */
+#define SCALED_RESISTOR_CALIBRATION_CODE_ADD	BIT(8)
+#define RESISTOR_CAL_MULT_VAL_32_128		BIT(5)
+
+/* CMN_CDIAG_REFCLK_CTRL */
+#define DIG_REF_CLK_DIV_SCALER_MASK		GENMASK(14, 12)
+#define REFCLK_TERMINATION_EN_OVERRIDE_EN	BIT(7)
+#define REFCLK_TERMINATION_EN_OVERRIDE		BIT(6)
+
+/* CMN_DIAG_HSCLK_SEL */
+#define HSCLK1_SEL_MASK				GENMASK(5, 4)
+#define HSCLK0_SEL_MASK				GENMASK(1, 0)
+
+/* XCVR_DIAG_HSCLK_SEL */
+#define HSCLK_SEL_MODE3_MASK			GENMASK(13, 12)
+#define HSCLK_SEL_MODE3_HSCLK1			1
+
+/* CMN_PLL0_VCOCAL_START */
+#define VCO_CALIB_CODE_START_POINT_VAL_MASK	GENMASK(8, 0)
+
+/* CMN_DIAG_PLL0_FBH_OVRD */
+#define PLL_FEEDBACK_DIV_HI_OVERRIDE_EN		BIT(15)
+
+/* CMN_DIAG_PLL0_FBL_OVRD */
+#define PLL_FEEDBACK_DIV_LO_OVERRIDE_EN		BIT(15)
+
+/* CMN_DIAG_PLL0_PXL_DIVH */
+#define PLL_PCLK_DIV_EN				BIT(15)
+
+/* XCVR_DIAG_PLLDRC_CTRL */
+#define DPLL_CLK_SEL_MODE3			BIT(14)
+
+/* TX_DIAG_TX_CTRL */
+#define TX_IF_SUBRATE_MODE3_MASK		GENMASK(7, 6)
+
+/* PHY_HDP_MODE_CTRL */
+#define POWER_STATE_A3_ACK			BIT(7)
+#define POWER_STATE_A2_ACK			BIT(6)
+#define POWER_STATE_A1_ACK			BIT(5)
+#define POWER_STATE_A0_ACK			BIT(4)
+#define POWER_STATE_A3				BIT(3)
+#define POWER_STATE_A2				BIT(2)
+#define POWER_STATE_A1				BIT(1)
+#define POWER_STATE_A0				BIT(0)
+
+/* PHY_PMA_ISO_CMN_CTRL */
+#define CMN_MACRO_PWR_EN_ACK			BIT(5)
+
+#define KEEP_ALIVE		0x18
+
+#define REF_CLK_27MHZ		27000000
+
+/* HDMI TX clock control settings */
+struct hdptx_hdmi_ctrl {
+	u32 pixel_clk_freq_min;
+	u32 pixel_clk_freq_max;
+	u32 feedback_factor;
+	u32 data_range_kbps_min;
+	u32 data_range_kbps_max;
+	u32 cmnda_pll0_ip_div;
+	u32 cmn_ref_clk_dig_div;
+	u32 ref_clk_divider_scaler;
+	u32 pll_fb_div_total;
+	u32 cmnda_pll0_fb_div_low;
+	u32 cmnda_pll0_fb_div_high;
+	u32 pixel_div_total;
+	u32 cmnda_pll0_pxdiv_low;
+	u32 cmnda_pll0_pxdiv_high;
+	u32 vco_freq_min;
+	u32 vco_freq_max;
+	u32 vco_ring_select;
+	u32 cmnda_hs_clk_0_sel;
+	u32 cmnda_hs_clk_1_sel;
+	u32 hsclk_div_at_xcvr;
+	u32 hsclk_div_tx_sub_rate;
+	u32 cmnda_pll0_hs_sym_div_sel;
+	u32 cmnda_pll0_clk_freq_min;
+	u32 cmnda_pll0_clk_freq_max;
+};
+
+struct cdns_hdptx_hdmi_phy {
+	struct cdns_mhdp_base base;
+
+	void __iomem *regs;	/* DPTX registers base */
+	struct mutex mbox_mutex; /* mutex to protect mailbox */
+	struct device *dev;
+	struct phy *phy;
+	struct clk *ref_clk, *apb_clk;
+	u32 ref_clk_rate;
+	u32 pixel_clk_rate;
+	enum hdmi_colorspace color_space;
+	u32 bpc;
+};
+
+/* HDMI TX clock control settings, pixel clock is output */
+static const struct hdptx_hdmi_ctrl pixel_clk_output_ctrl_table[] = {
+/*Minclk  Maxclk Fdbak  DR_min   DR_max  ip_d  dig  DS    Totl */
+{ 27000,  27000, 1000,  270000,  270000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x3,  27000,  27000},
+{ 27000,  27000, 1250,  337500,  337500, 0x03, 0x1, 0x1,  300, 0x0ec, 0x03c, 100, 0x030, 0x030, 2700000, 2700000, 0, 2, 2, 2, 4, 0x3,  33750,  33750},
+{ 27000,  27000, 1500,  405000,  405000, 0x03, 0x1, 0x1,  360, 0x11c, 0x048, 120, 0x03a, 0x03a, 3240000, 3240000, 0, 2, 2, 2, 4, 0x3,  40500,  40500},
+{ 27000,  27000, 2000,  540000,  540000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x2,  54000,  54000},
+{ 54000,  54000, 1000,  540000,  540000, 0x03, 0x1, 0x1,  480, 0x17c, 0x060,  80, 0x026, 0x026, 4320000, 4320000, 1, 2, 2, 2, 4, 0x3,  54000,  54000},
+{ 54000,  54000, 1250,  675000,  675000, 0x04, 0x1, 0x1,  400, 0x13c, 0x050,  50, 0x017, 0x017, 2700000, 2700000, 0, 1, 1, 2, 4, 0x2,  67500,  67500},
+{ 54000,  54000, 1500,  810000,  810000, 0x04, 0x1, 0x1,  480, 0x17c, 0x060,  60, 0x01c, 0x01c, 3240000, 3240000, 0, 2, 2, 2, 2, 0x2,  81000,  81000},
+{ 54000,  54000, 2000, 1080000, 1080000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  40, 0x012, 0x012, 2160000, 2160000, 0, 2, 2, 2, 1, 0x1, 108000, 108000},
+{ 74250,  74250, 1000,  742500,  742500, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  80, 0x026, 0x026, 5940000, 5940000, 1, 2, 2, 2, 4, 0x3,  74250,  74250},
+{ 74250,  74250, 1250,  928125,  928125, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  50, 0x017, 0x017, 3712500, 3712500, 1, 1, 1, 2, 4, 0x2,  92812,  92812},
+{ 74250,  74250, 1500, 1113750, 1113750, 0x04, 0x1, 0x1,  660, 0x20c, 0x084,  60, 0x01c, 0x01c, 4455000, 4455000, 1, 2, 2, 2, 2, 0x2, 111375, 111375},
+{ 74250,  74250, 2000, 1485000, 1485000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  40, 0x012, 0x012, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1, 148500, 148500},
+{ 99000,  99000, 1000,  990000,  990000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  40, 0x012, 0x012, 3960000, 3960000, 1, 2, 2, 2, 2, 0x2,  99000,  99000},
+{ 99000,  99000, 1250, 1237500, 1237500, 0x03, 0x1, 0x1,  275, 0x0d8, 0x037,  25, 0x00b, 0x00a, 2475000, 2475000, 0, 1, 1, 2, 2, 0x1, 123750, 123750},
+{ 99000,  99000, 1500, 1485000, 1485000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  30, 0x00d, 0x00d, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1, 148500, 148500},
+{ 99000,  99000, 2000, 1980000, 1980000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  40, 0x012, 0x012, 3960000, 3960000, 1, 2, 2, 2, 1, 0x1, 198000, 198000},
+{148500, 148500, 1000, 1485000, 1485000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  40, 0x012, 0x012, 5940000, 5940000, 1, 2, 2, 2, 2, 0x2, 148500, 148500},
+{148500, 148500, 1250, 1856250, 1856250, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  25, 0x00b, 0x00a, 3712500, 3712500, 1, 1, 1, 2, 2, 0x1, 185625, 185625},
+{148500, 148500, 1500, 2227500, 2227500, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  30, 0x00d, 0x00d, 4455000, 4455000, 1, 1, 1, 2, 2, 0x1, 222750, 222750},
+{148500, 148500, 2000, 2970000, 2970000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  40, 0x012, 0x012, 5940000, 5940000, 1, 2, 2, 2, 1, 0x1, 297000, 297000},
+{198000, 198000, 1000, 1980000, 1980000, 0x03, 0x1, 0x1,  220, 0x0ac, 0x02c,  10, 0x003, 0x003, 1980000, 1980000, 0, 1, 1, 2, 1, 0x0, 198000, 198000},
+{198000, 198000, 1250, 2475000, 2475000, 0x03, 0x1, 0x1,  550, 0x1b4, 0x06e,  25, 0x00b, 0x00a, 4950000, 4950000, 1, 1, 1, 2, 2, 0x1, 247500, 247500},
+{198000, 198000, 1500, 2970000, 2970000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  15, 0x006, 0x005, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000, 297000},
+{198000, 198000, 2000, 3960000, 3960000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  20, 0x008, 0x008, 3960000, 3960000, 1, 1, 1, 2, 1, 0x0, 396000, 396000},
+{297000, 297000, 1000, 2970000, 2970000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  10, 0x003, 0x003, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000, 297000},
+{297000, 297000, 1500, 4455000, 4455000, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  15, 0x006, 0x005, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0, 445500, 445500},
+{297000, 297000, 2000, 5940000, 5940000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  20, 0x008, 0x008, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000},
+{594000, 594000, 1000, 5940000, 5940000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  10, 0x003, 0x003, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000},
+{594000, 594000,  750, 4455000, 4455000, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  10, 0x003, 0x003, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0, 445500, 445500},
+{594000, 594000,  625, 3712500, 3712500, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  10, 0x003, 0x003, 3712500, 3712500, 1, 1, 1, 2, 1, 0x0, 371250, 371250},
+{594000, 594000,  500, 2970000, 2970000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  10, 0x003, 0x003, 5940000, 5940000, 1, 1, 1, 2, 2, 0x1, 297000, 297000},
+};
+
+/* HDMI TX PLL tuning settings */
+struct hdptx_hdmi_pll_tuning {
+	u32 vco_freq_bin;
+	u32 vco_freq_min;
+	u32 vco_freq_max;
+	u32 volt_to_current_coarse;
+	u32 volt_to_current;
+	u32 ndac_ctrl;
+	u32 pmos_ctrl;
+	u32 ptat_ndac_ctrl;
+	u32 feedback_div_total;
+	u32 charge_pump_gain;
+	u32 coarse_code;
+	u32 v2i_code;
+	u32 vco_cal_code;
+};
+
+/* HDMI TX PLL tuning settings, pixel clock is output */
+static const struct hdptx_hdmi_pll_tuning pixel_clk_output_pll_table[] = {
+/*bin VCO_freq min/max  coar  cod NDAC  PMOS PTAT div-T P-Gain Coa V2I CAL */
+{  1, 1980000, 1980000, 0x4, 0x3, 0x0, 0x09, 0x09, 220, 0x42, 160, 5, 183 },
+{  2, 2160000, 2160000, 0x4, 0x3, 0x0, 0x09, 0x09, 240, 0x42, 166, 6, 208 },
+{  3, 2475000, 2475000, 0x5, 0x3, 0x1, 0x00, 0x07, 275, 0x42, 167, 6, 209 },
+{  4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 300, 0x42, 188, 6, 230 },
+{  4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 400, 0x4c, 188, 6, 230 },
+{  5, 2970000, 2970000, 0x6, 0x3, 0x1, 0x00, 0x07, 330, 0x42, 183, 6, 225 },
+{  6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 360, 0x42, 203, 7, 256 },
+{  6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 480, 0x4c, 203, 7, 256 },
+{  7, 3712500, 3712500, 0x4, 0x3, 0x0, 0x07, 0x0F, 550, 0x4c, 212, 7, 257 },
+{  8, 3960000, 3960000, 0x5, 0x3, 0x0, 0x07, 0x0F, 440, 0x42, 184, 6, 226 },
+{  9, 4320000, 4320000, 0x5, 0x3, 0x1, 0x07, 0x0F, 480, 0x42, 205, 7, 258 },
+{ 10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 495, 0x42, 219, 7, 272 },
+{ 10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 660, 0x4c, 219, 7, 272 },
+{ 11, 4950000, 4950000, 0x6, 0x3, 0x1, 0x00, 0x07, 550, 0x42, 213, 7, 258 },
+{ 12, 5940000, 5940000, 0x7, 0x3, 0x1, 0x00, 0x07, 660, 0x42, 244, 8, 292 },
+};
+
+static int cdns_phy_reg_write(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 addr, u32 val)
+{
+	return cdns_mhdp_reg_write(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), val);
+}
+
+static u32 cdns_phy_reg_read(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 addr)
+{
+	u32 reg32;
+
+	cdns_mhdp_reg_read(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), &reg32);
+
+	return reg32;
+}
+
+static int wait_for_ack(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 reg, u32 mask,
+			const char *err_msg)
+{
+	u32 val, i;
+
+	for (i = 0; i < 10; i++) {
+		val = cdns_phy_reg_read(cdns_phy, reg);
+		if (val & mask)
+			return 0;
+		msleep(20);
+	}
+
+	dev_err(cdns_phy->dev, "%s\n", err_msg);
+	return -ETIMEDOUT;
+}
+
+static bool hdptx_phy_check_alive(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	u32  alive, newalive;
+	u8 retries_left = 50;
+
+	alive = readl(cdns_phy->regs + KEEP_ALIVE);
+
+	while (retries_left--) {
+		udelay(2);
+
+		newalive = readl(cdns_phy->regs + KEEP_ALIVE);
+		if (alive == newalive)
+			continue;
+		return true;
+	}
+	return false;
+}
+
+static int hdptx_hdmi_clk_enable(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	struct device *dev = cdns_phy->dev;
+	u32 ref_clk_rate;
+	int ret;
+
+	cdns_phy->ref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(cdns_phy->ref_clk)) {
+		dev_err(dev, "phy ref clock not found\n");
+		return PTR_ERR(cdns_phy->ref_clk);
+	}
+
+	cdns_phy->apb_clk = devm_clk_get(dev, "apb");
+	if (IS_ERR(cdns_phy->apb_clk)) {
+		dev_err(dev, "phy apb clock not found\n");
+		return PTR_ERR(cdns_phy->apb_clk);
+	}
+
+	ret = clk_prepare_enable(cdns_phy->ref_clk);
+	if (ret) {
+		dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+		return ret;
+	}
+
+	ref_clk_rate = clk_get_rate(cdns_phy->ref_clk);
+	if (!ref_clk_rate) {
+		dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
+		goto err_ref_clk;
+	}
+
+	if (ref_clk_rate == REF_CLK_27MHZ) {
+		cdns_phy->ref_clk_rate = ref_clk_rate;
+	} else {
+		dev_err(cdns_phy->dev, "Not support Ref Clock Rate(%dHz)\n", ref_clk_rate);
+		goto err_ref_clk;
+	}
+
+	ret = clk_prepare_enable(cdns_phy->apb_clk);
+	if (ret) {
+		dev_err(cdns_phy->dev, "Failed to prepare apb clock\n");
+		goto err_ref_clk;
+	}
+
+	return 0;
+
+err_ref_clk:
+	clk_disable_unprepare(cdns_phy->ref_clk);
+	return -EINVAL;
+}
+
+static void hdptx_hdmi_clk_disable(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	clk_disable_unprepare(cdns_phy->apb_clk);
+	clk_disable_unprepare(cdns_phy->ref_clk);
+}
+
+static void hdptx_hdmi_arc_config(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	u16 txpu_calib_code;
+	u16 txpd_calib_code;
+	u16 txpu_adj_calib_code;
+	u16 txpd_adj_calib_code;
+	u16 prev_calib_code;
+	u16 new_calib_code;
+	u16 rdata;
+
+	/* Power ARC */
+	cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 0x0001);
+
+	prev_calib_code = cdns_phy_reg_read(cdns_phy, TX_DIG_CTRL_REG_2);
+	txpu_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPUCAL_CTRL);
+	txpd_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPDCAL_CTRL);
+	txpu_adj_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPU_ADJ_CTRL);
+	txpd_adj_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPD_ADJ_CTRL);
+
+	new_calib_code = ((txpu_calib_code + txpd_calib_code) / 2)
+		+ txpu_adj_calib_code + txpd_adj_calib_code;
+
+	if (new_calib_code != prev_calib_code) {
+		rdata = cdns_phy_reg_read(cdns_phy, TX_ANA_CTRL_REG_1);
+		rdata &= 0xdfff;
+		cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, rdata);
+		cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, new_calib_code);
+		mdelay(10);
+		rdata |= 0x2000;
+		cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, rdata);
+		usleep_range(150, 250);
+	}
+
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2098);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0010);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x4001);
+	mdelay(5);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2198);
+	mdelay(5);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d);
+	usleep_range(100, 200);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f);
+}
+
+static void hdptx_hdmi_phy_set_vswing(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	u32 k;
+	const u32 num_lanes = 4;
+
+	for (k = 0; k < num_lanes; k++) {
+		cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_DRV | (k << 9)),
+				   TX_DRIVER_PROG_BOOST_ENABLE |
+				   FIELD_PREP(TX_DRIVER_PROG_BOOST_LEVEL_MASK, 3) |
+				   TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE |
+				   TX_DRIVER_LDO_BANDGAP_REF_ENABLE);
+		cdns_phy_reg_write(cdns_phy, (TX_TXCC_CPOST_MULT_00_0 | (k << 9)), 0x0);
+		cdns_phy_reg_write(cdns_phy, (TX_TXCC_CAL_SCLR_MULT_0 | (k << 9)),
+				   SCALED_RESISTOR_CALIBRATION_CODE_ADD |
+				   RESISTOR_CAL_MULT_VAL_32_128);
+	}
+}
+
+static int hdptx_hdmi_feedback_factor(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	u32 feedback_factor;
+
+	switch (cdns_phy->color_space) {
+	case HDMI_COLORSPACE_YUV422:
+		feedback_factor = 1000;
+		break;
+
+	case HDMI_COLORSPACE_YUV420:
+		switch (cdns_phy->bpc) {
+		case 8:
+			feedback_factor = 500;
+			break;
+		case 10:
+			feedback_factor = 625;
+			break;
+		case 12:
+			feedback_factor = 750;
+			break;
+		case 16:
+			feedback_factor = 1000;
+			break;
+		default:
+			dev_dbg(cdns_phy->dev, "Invalid ColorDepth\n");
+			return 0;
+		}
+		break;
+
+	default:
+		/* Assume RGB/YUV444 */
+		switch (cdns_phy->bpc) {
+		case 10:
+			feedback_factor = 1250;
+			break;
+		case 12:
+			feedback_factor = 1500;
+			break;
+		case 16:
+			feedback_factor = 2000;
+			break;
+		default:
+			feedback_factor = 1000;
+		}
+	}
+
+	return feedback_factor;
+}
+
+static int hdptx_hdmi_phy_config(struct cdns_hdptx_hdmi_phy *cdns_phy,
+				 const struct hdptx_hdmi_ctrl *p_ctrl_table,
+				 const struct hdptx_hdmi_pll_tuning *p_pll_table,
+				 bool pclk_in)
+{
+	const u32 num_lanes = 4;
+	u32 val, k;
+	int ret;
+
+	/* enable PHY isolation mode only for CMN */
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISOLATION_CTRL, 0xd000);
+
+	/* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div dividers */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_ISO_PLL_CTRL1);
+	val &= ~CMN_PLL0_CLK_DATART_DIV_MASK;
+	val |= FIELD_PREP(CMN_PLL0_CLK_DATART_DIV_MASK, 0x12);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_PLL_CTRL1, val);
+
+	/* assert PHY reset from isolation register */
+	cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0000);
+	/* assert PMA CMN reset */
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0000);
+
+	/* register XCVR_DIAG_BIDI_CTRL */
+	for (k = 0; k < num_lanes; k++)
+		cdns_phy_reg_write(cdns_phy, XCVR_DIAG_BIDI_CTRL | (k << 9), 0x00ff);
+
+	/* Describing Task phy_cfg_hdp */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_RCV_EN_MASK;
+	val |= FIELD_PREP(CMA_REF_CLK_RCV_EN_MASK, CMA_REF_CLK_RCV_EN);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	/* PHY Registers */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_DIG_DIV_MASK;
+	val |= FIELD_PREP(CMA_REF_CLK_DIG_DIV_MASK, p_ctrl_table->cmn_ref_clk_dig_div);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_DATA_RATE_CLK_DIV_MASK;
+	val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
+			  PLL_DATA_RATE_CLK_DIV_HBR2);
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+
+	/* Common control module control and diagnostic registers */
+	val = cdns_phy_reg_read(cdns_phy, CMN_CDIAG_REFCLK_CTRL);
+	val &= ~DIG_REF_CLK_DIV_SCALER_MASK;
+	val |= FIELD_PREP(DIG_REF_CLK_DIV_SCALER_MASK, p_ctrl_table->ref_clk_divider_scaler);
+	val |= REFCLK_TERMINATION_EN_OVERRIDE_EN | REFCLK_TERMINATION_EN_OVERRIDE;
+	cdns_phy_reg_write(cdns_phy, CMN_CDIAG_REFCLK_CTRL, val);
+
+	/* High speed clock used */
+	val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL);
+	val &= ~(HSCLK1_SEL_MASK | HSCLK0_SEL_MASK);
+	val |= FIELD_PREP(HSCLK1_SEL_MASK, (p_ctrl_table->cmnda_hs_clk_1_sel >> 1));
+	val |= FIELD_PREP(HSCLK0_SEL_MASK, (p_ctrl_table->cmnda_hs_clk_0_sel >> 1));
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val);
+
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+		val &= ~HSCLK_SEL_MODE3_MASK;
+		val |= FIELD_PREP(HSCLK_SEL_MODE3_MASK,
+				  (p_ctrl_table->cmnda_hs_clk_0_sel >> 1));
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val);
+	}
+
+	/* PLL 0 control state machine registers */
+	val = p_ctrl_table->vco_ring_select << 12;
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_USER_DEF_CTRL, val);
+
+	if (pclk_in) {
+		val = 0x30a0;
+	} else {
+		val = cdns_phy_reg_read(cdns_phy, CMN_PLL0_VCOCAL_START);
+		val &= ~VCO_CALIB_CODE_START_POINT_VAL_MASK;
+		val |= FIELD_PREP(VCO_CALIB_CODE_START_POINT_VAL_MASK,
+				  p_pll_table->vco_cal_code);
+	}
+	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_START, val);
+
+	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_INIT_TMR, 0x0064);
+	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_ITER_TMR, 0x000a);
+
+	/* Common functions control and diagnostics registers */
+	val = p_ctrl_table->cmnda_pll0_hs_sym_div_sel << 8;
+	val |= p_ctrl_table->cmnda_pll0_ip_div;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_INCLK_CTRL, val);
+
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_OVRD, 0x0000);
+
+	val = p_ctrl_table->cmnda_pll0_fb_div_high;
+	val |= PLL_FEEDBACK_DIV_HI_OVERRIDE_EN;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBH_OVRD, val);
+
+	val = p_ctrl_table->cmnda_pll0_fb_div_low;
+	val |= PLL_FEEDBACK_DIV_LO_OVERRIDE_EN;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBL_OVRD, val);
+
+	if (!pclk_in) {
+		val = p_ctrl_table->cmnda_pll0_pxdiv_low;
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PXL_DIVL, val);
+
+		val = p_ctrl_table->cmnda_pll0_pxdiv_high;
+		val |= PLL_PCLK_DIV_EN;
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PXL_DIVH, val);
+	}
+
+	val = p_pll_table->volt_to_current_coarse;
+	val |= (p_pll_table->volt_to_current) << 4;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_V2I_TUNE, val);
+
+	val = p_pll_table->charge_pump_gain;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_CP_TUNE, val);
+
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_LF_PROG, 0x0008);
+
+	val = p_pll_table->pmos_ctrl;
+	val |= (p_pll_table->ndac_ctrl) << 8;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE1, val);
+
+	val = p_pll_table->ptat_ndac_ctrl;
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE2, val);
+
+	if (pclk_in)
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_TEST_MODE, 0x0022);
+	else
+		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_TEST_MODE, 0x0020);
+
+	cdns_phy_reg_write(cdns_phy, CMN_PSM_CLK_CTRL, 0x0016);
+
+	/* Transceiver control and diagnostic registers */
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+		val &= ~DPLL_CLK_SEL_MODE3;
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val);
+	}
+
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (TX_DIAG_TX_CTRL | (k << 9)));
+		val &= ~TX_IF_SUBRATE_MODE3_MASK;
+		val |= FIELD_PREP(TX_IF_SUBRATE_MODE3_MASK,
+				  (p_ctrl_table->hsclk_div_tx_sub_rate >> 1));
+		cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_CTRL | (k << 9)), val);
+	}
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_SEL_MASK;
+	/*
+	 * single ended reference clock (val |= 0x0030);
+	 * differential clock  (val |= 0x0000);
+	 * for differential clock on the refclk_p and
+	 * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1
+	 * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100);
+	 */
+	val |= FIELD_PREP(CMA_REF_CLK_SEL_MASK, 3);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	/* Deassert PHY reset */
+	cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0001);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0003);
+
+	/* Power state machine registers */
+	for (k = 0; k < num_lanes; k++)
+		cdns_phy_reg_write(cdns_phy, XCVR_PSM_RCTRL | (k << 9), 0xfefc);
+
+	/* Assert cmn_macro_pwr_en */
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0013);
+
+	/* wait for cmn_macro_pwr_en_ack */
+	ret = wait_for_ack(cdns_phy, PHY_PMA_ISO_CMN_CTRL, CMN_MACRO_PWR_EN_ACK,
+			   "MA output macro power up failed");
+	if (ret < 0)
+		return ret;
+
+	/* wait for cmn_ready */
+	ret = wait_for_ack(cdns_phy, PHY_PMA_CMN_CTRL1, CMN_READY,
+			   "PMA output ready failed");
+	if (ret < 0)
+		return ret;
+
+	for (k = 0; k < num_lanes; k++) {
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A0 | (k << 9), 0x6791);
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A1 | (k << 9), 0x6790);
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A2 | (k << 9), 0x0090);
+		cdns_phy_reg_write(cdns_phy, TX_PSC_A3 | (k << 9), 0x0090);
+
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, RX_PSC_CAL | (k << 9), val);
+
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, RX_PSC_A0 | (k << 9), val);
+	}
+
+	return 0;
+}
+
+static int hdptx_hdmi_phy_cfg(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 rate)
+{
+	const struct hdptx_hdmi_ctrl *p_ctrl_table;
+	const struct hdptx_hdmi_pll_tuning *p_pll_table;
+	const u32 refclk_freq_khz = cdns_phy->ref_clk_rate / 1000;
+	const bool pclk_in = false;
+	u32 pixel_freq = rate;
+	u32 vco_freq, char_freq;
+	u32 div_total, feedback_factor;
+	u32 i;
+
+	feedback_factor = hdptx_hdmi_feedback_factor(cdns_phy);
+
+	char_freq = pixel_freq * feedback_factor / 1000;
+
+	dev_dbg(cdns_phy->dev,
+		"Pixel clock: (%d KHz), character clock: %d, bpc is (%0d-bit)\n",
+		pixel_freq, char_freq, cdns_phy->bpc);
+
+	/* Get right row from the ctrl_table table.
+	 * Check if 'pixel_freq_khz' value matches the PIXEL_CLK_FREQ column.
+	 * Consider only the rows with FEEDBACK_FACTOR column matching feedback_factor.
+	 */
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++) {
+		if (feedback_factor == pixel_clk_output_ctrl_table[i].feedback_factor &&
+		    pixel_freq == pixel_clk_output_ctrl_table[i].pixel_clk_freq_min) {
+			p_ctrl_table = &pixel_clk_output_ctrl_table[i];
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(pixel_clk_output_ctrl_table)) {
+		dev_warn(cdns_phy->dev,
+			 "Pixel clk (%d KHz) not supported, bpc is (%0d-bit)\n",
+			 pixel_freq, cdns_phy->bpc);
+		return -EINVAL;
+	}
+
+	div_total = p_ctrl_table->pll_fb_div_total;
+	vco_freq = refclk_freq_khz * div_total / p_ctrl_table->cmnda_pll0_ip_div;
+
+	/* Get right row from the pixel_clk_output_pll_table table.
+	 * Check if vco_freq_khz and feedback_div_total
+	 * column matching with pixel_clk_output_pll_table.
+	 */
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_pll_table); i++) {
+		if (vco_freq == pixel_clk_output_pll_table[i].vco_freq_min &&
+		    div_total == pixel_clk_output_pll_table[i].feedback_div_total) {
+			p_pll_table = &pixel_clk_output_pll_table[i];
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(pixel_clk_output_pll_table)) {
+		dev_warn(cdns_phy->dev, "VCO (%d KHz) not supported\n", vco_freq);
+		return -EINVAL;
+	}
+	dev_dbg(cdns_phy->dev, "VCO frequency is (%d KHz)\n", vco_freq);
+
+	return hdptx_hdmi_phy_config(cdns_phy, p_ctrl_table, p_pll_table, pclk_in);
+}
+
+static int hdptx_hdmi_phy_power_up(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	int ret = 0;
+
+	/* set Power State to A2 */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2);
+
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1);
+
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2_ACK,
+			   "Wait A2 Ack failed");
+	if (ret < 0)
+		return ret;
+
+	/* Power up ARC */
+	hdptx_hdmi_arc_config(cdns_phy);
+
+	/* Configure PHY in A0 mode (PHY must be in the A0 power
+	 * state in order to transmit data)
+	 */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0);
+
+	return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0_ACK,
+			    "Wait A0 Ack failed");
+}
+
+static int hdptx_hdmi_phy_power_down(struct cdns_hdptx_hdmi_phy *cdns_phy)
+{
+	u32 val;
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL);
+	val &= ~(POWER_STATE_A0 | POWER_STATE_A1 | POWER_STATE_A2 | POWER_STATE_A3);
+	/* PHY_DP_MODE_CTL set to A3 power state */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, val | POWER_STATE_A3);
+
+	return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3_ACK,
+			    "Wait A3 Ack failed");
+}
+
+static int cdns_hdptx_hdmi_phy_on(struct phy *phy)
+{
+	struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
+
+	return hdptx_hdmi_phy_power_up(cdns_phy);
+}
+
+static int cdns_hdptx_hdmi_phy_off(struct phy *phy)
+{
+	struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
+
+	hdptx_hdmi_phy_power_down(cdns_phy);
+	return 0;
+}
+
+static int
+cdns_hdptx_hdmi_phy_valid(struct phy *phy, enum phy_mode mode,
+			  int submode, union phy_configure_opts *opts)
+{
+	u32 rate = opts->hdmi.pixel_clk_rate;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++)
+		if (rate == pixel_clk_output_ctrl_table[i].pixel_clk_freq_min)
+			return 0;
+
+	return -EINVAL;
+}
+
+static int cdns_hdptx_hdmi_phy_init(struct phy *phy)
+{
+	return 0;
+}
+
+static int cdns_hdptx_hdmi_configure(struct phy *phy,
+				     union phy_configure_opts *opts)
+{
+	struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
+	int ret;
+
+	cdns_phy->pixel_clk_rate = opts->hdmi.pixel_clk_rate;
+	cdns_phy->color_space = opts->hdmi.color_space;
+	cdns_phy->bpc = opts->hdmi.bpc;
+
+	/* Check HDMI FW alive before HDMI PHY init */
+	ret = hdptx_phy_check_alive(cdns_phy);
+	if (!ret) {
+		dev_err(cdns_phy->dev, "NO HDMI FW running\n");
+		return -ENXIO;
+	}
+
+	/* Configure PHY */
+	if (hdptx_hdmi_phy_cfg(cdns_phy, cdns_phy->pixel_clk_rate) < 0) {
+		dev_err(cdns_phy->dev, "failed to set phy pclock\n");
+		return -EINVAL;
+	}
+
+	ret = hdptx_hdmi_phy_power_up(cdns_phy);
+	if (ret < 0)
+		return ret;
+
+	hdptx_hdmi_phy_set_vswing(cdns_phy);
+
+	return 0;
+}
+
+static const struct phy_ops cdns_hdptx_hdmi_phy_ops = {
+	.init = cdns_hdptx_hdmi_phy_init,
+	.configure = cdns_hdptx_hdmi_configure,
+	.power_on = cdns_hdptx_hdmi_phy_on,
+	.power_off = cdns_hdptx_hdmi_phy_off,
+	.validate = cdns_hdptx_hdmi_phy_valid,
+	.owner = THIS_MODULE,
+};
+
+static int cdns_hdptx_hdmi_phy_probe(struct platform_device *pdev)
+{
+	struct cdns_hdptx_hdmi_phy *cdns_phy;
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct phy_provider *phy_provider;
+	struct resource *res;
+	struct phy *phy;
+	int ret;
+
+	cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
+	if (!cdns_phy)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, cdns_phy);
+	cdns_phy->dev = dev;
+	mutex_init(&cdns_phy->mbox_mutex);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(cdns_phy->regs))
+		return PTR_ERR(cdns_phy->regs);
+
+	phy = devm_phy_create(dev, node, &cdns_hdptx_hdmi_phy_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	phy->attrs.mode = PHY_MODE_HDMI;
+
+	cdns_phy->phy = phy;
+	phy_set_drvdata(phy, cdns_phy);
+
+	/* init base struct for access mhdp mailbox */
+	cdns_phy->base.dev = cdns_phy->dev;
+	cdns_phy->base.regs = cdns_phy->regs;
+	cdns_phy->base.mbox_mutex = &cdns_phy->mbox_mutex;
+
+	ret = hdptx_hdmi_clk_enable(cdns_phy);
+	if (ret) {
+		dev_err(dev, "Init clk fail\n");
+		return -EINVAL;
+	}
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider)) {
+		ret = PTR_ERR(phy_provider);
+		goto clk_disable;
+	}
+
+	dev_dbg(dev, "probe success!\n");
+
+	return 0;
+
+clk_disable:
+	hdptx_hdmi_clk_disable(cdns_phy);
+
+	return -EINVAL;
+}
+
+static int cdns_hdptx_hdmi_phy_remove(struct platform_device *pdev)
+{
+	struct cdns_hdptx_hdmi_phy *cdns_phy = platform_get_drvdata(pdev);
+
+	hdptx_hdmi_clk_disable(cdns_phy);
+
+	return 0;
+}
+
+static const struct of_device_id cdns_hdptx_hdmi_phy_of_match[] = {
+	{.compatible = "fsl,imx8mq-hdmi-phy" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cdns_hdptx_hdmi_phy_of_match);
+
+static struct platform_driver cdns_hdptx_hdmi_phy_driver = {
+	.probe = cdns_hdptx_hdmi_phy_probe,
+	.remove = cdns_hdptx_hdmi_phy_remove,
+	.driver = {
+		.name	= "cdns-hdptx-hdmi-phy",
+		.of_match_table	= cdns_hdptx_hdmi_phy_of_match,
+	}
+};
+module_platform_driver(cdns_hdptx_hdmi_phy_driver);
+
+MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("Cadence HDP-TX HDMI PHY driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From Sandor.yu at nxp.com  Mon Feb 19 19:23:54 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 20 Feb 2024 11:23:54 +0800
Subject: [PATCH v14 6/7] phy: freescale: Add DisplayPort PHY driver for i.MX8MQ
In-Reply-To: <cover.1708395604.git.Sandor.yu@nxp.com>
References: <cover.1708395604.git.Sandor.yu@nxp.com>
Message-ID: <400826b235dc5071981ff6b11070849d0f2ab5f3.1708395604.git.Sandor.yu@nxp.com>

Add Cadence HDP-TX DisplayPort PHY driver for i.MX8MQ

Cadence HDP-TX PHY could be put in either DP mode or
HDMI mode base on the configuration chosen.
DisplayPort PHY mode is configurated in the driver.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
---
v12->v14:
 *No change.

v11->v12:
- Return error code to replace -1 for function wait_for_ack().
- Set cdns_phy->power_up = false in phy_power_down function.
- Remove "RATE_8_1 = 810000", it is not used in driver.
- Add year 2024 to copyright.

 drivers/phy/freescale/Kconfig             |  10 +
 drivers/phy/freescale/Makefile            |   1 +
 drivers/phy/freescale/phy-fsl-imx8mq-dp.c | 726 ++++++++++++++++++++++
 3 files changed, 737 insertions(+)
 create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-dp.c

diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index 853958fb2c063..c39709fd700ac 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -35,6 +35,16 @@ config PHY_FSL_IMX8M_PCIE
 	  Enable this to add support for the PCIE PHY as found on
 	  i.MX8M family of SOCs.
 
+config PHY_FSL_IMX8MQ_DP
+	tristate "Freescale i.MX8MQ DP PHY support"
+	depends on OF && HAS_IOMEM
+	depends on COMMON_CLK
+	select GENERIC_PHY
+	select CDNS_MHDP_HELPER
+	help
+	  Enable this to support the Cadence HDPTX DP PHY driver
+	  on i.MX8MQ SOC.
+
 endif
 
 config PHY_FSL_LYNX_28G
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index cedb328bc4d28..47e5285209fa8 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_PHY_FSL_IMX8MQ_DP)		+= phy-fsl-imx8mq-dp.o
 obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)	+= phy-fsl-imx8mq-usb.o
 obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
 obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-dp.c b/drivers/phy/freescale/phy-fsl-imx8mq-dp.c
new file mode 100644
index 0000000000000..2e24ca04c5980
--- /dev/null
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-dp.c
@@ -0,0 +1,726 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence HDP-TX Display Port Interface (DP) PHY driver
+ *
+ * Copyright (C) 2022-2024 NXP Semiconductor, Inc.
+ */
+#include <asm/unaligned.h>
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#define ADDR_PHY_AFE	0x80000
+
+/* PHY registers */
+#define CMN_SSM_BIAS_TMR			0x0022
+#define CMN_PLLSM0_PLLEN_TMR			0x0029
+#define CMN_PLLSM0_PLLPRE_TMR			0x002a
+#define CMN_PLLSM0_PLLVREF_TMR			0x002b
+#define CMN_PLLSM0_PLLLOCK_TMR			0x002c
+#define CMN_PLLSM0_USER_DEF_CTRL		0x002f
+#define CMN_PSM_CLK_CTRL			0x0061
+#define CMN_PLL0_VCOCAL_START			0x0081
+#define CMN_PLL0_VCOCAL_INIT_TMR		0x0084
+#define CMN_PLL0_VCOCAL_ITER_TMR		0x0085
+#define CMN_PLL0_INTDIV				0x0094
+#define CMN_PLL0_FRACDIV			0x0095
+#define CMN_PLL0_HIGH_THR			0x0096
+#define CMN_PLL0_DSM_DIAG			0x0097
+#define CMN_PLL0_SS_CTRL2			0x0099
+#define CMN_ICAL_INIT_TMR			0x00c4
+#define CMN_ICAL_ITER_TMR			0x00c5
+#define CMN_RXCAL_INIT_TMR			0x00d4
+#define CMN_RXCAL_ITER_TMR			0x00d5
+#define CMN_TXPUCAL_INIT_TMR			0x00e4
+#define CMN_TXPUCAL_ITER_TMR			0x00e5
+#define CMN_TXPDCAL_INIT_TMR			0x00f4
+#define CMN_TXPDCAL_ITER_TMR			0x00f5
+#define CMN_ICAL_ADJ_INIT_TMR			0x0102
+#define CMN_ICAL_ADJ_ITER_TMR			0x0103
+#define CMN_RX_ADJ_INIT_TMR			0x0106
+#define CMN_RX_ADJ_ITER_TMR			0x0107
+#define CMN_TXPU_ADJ_INIT_TMR			0x010a
+#define CMN_TXPU_ADJ_ITER_TMR			0x010b
+#define CMN_TXPD_ADJ_INIT_TMR			0x010e
+#define CMN_TXPD_ADJ_ITER_TMR			0x010f
+#define CMN_DIAG_PLL0_FBH_OVRD			0x01c0
+#define CMN_DIAG_PLL0_FBL_OVRD			0x01c1
+#define CMN_DIAG_PLL0_OVRD			0x01c2
+#define CMN_DIAG_PLL0_TEST_MODE			0x01c4
+#define CMN_DIAG_PLL0_V2I_TUNE			0x01c5
+#define CMN_DIAG_PLL0_CP_TUNE			0x01c6
+#define CMN_DIAG_PLL0_LF_PROG			0x01c7
+#define CMN_DIAG_PLL0_PTATIS_TUNE1		0x01c8
+#define CMN_DIAG_PLL0_PTATIS_TUNE2		0x01c9
+#define CMN_DIAG_HSCLK_SEL			0x01e0
+#define CMN_DIAG_PER_CAL_ADJ			0x01ec
+#define CMN_DIAG_CAL_CTRL			0x01ed
+#define CMN_DIAG_ACYA				0x01ff
+#define XCVR_PSM_RCTRL				0x4001
+#define XCVR_PSM_CAL_TMR			0x4002
+#define XCVR_PSM_A0IN_TMR			0x4003
+#define TX_TXCC_CAL_SCLR_MULT_0			0x4047
+#define TX_TXCC_CPOST_MULT_00_0			0x404c
+#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
+#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
+#define XCVR_DIAG_HSCLK_SEL			0x40e1
+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR		0x40f2
+#define TX_PSC_A0				0x4100
+#define TX_PSC_A1				0x4101
+#define TX_PSC_A2				0x4102
+#define TX_PSC_A3				0x4103
+#define TX_RCVDET_EN_TMR			0x4122
+#define TX_RCVDET_ST_TMR			0x4123
+#define TX_DIAG_BGREF_PREDRV_DELAY		0x41e7
+#define TX_DIAG_BGREF_PREDRV_DELAY		0x41e7
+#define TX_DIAG_ACYA_0				0x41ff
+#define TX_DIAG_ACYA_1				0x43ff
+#define TX_DIAG_ACYA_2				0x45ff
+#define TX_DIAG_ACYA_3				0x47ff
+#define TX_ANA_CTRL_REG_1			0x5020
+#define TX_ANA_CTRL_REG_2			0x5021
+#define TX_DIG_CTRL_REG_1			0x5023
+#define TX_DIG_CTRL_REG_2			0x5024
+#define TXDA_CYA_AUXDA_CYA			0x5025
+#define TX_ANA_CTRL_REG_3			0x5026
+#define TX_ANA_CTRL_REG_4			0x5027
+#define TX_ANA_CTRL_REG_5			0x5029
+#define RX_PSC_A0				0x8000
+#define RX_PSC_CAL				0x8006
+#define PHY_HDP_MODE_CTRL			0xc008
+#define PHY_HDP_CLK_CTL				0xc009
+#define PHY_PMA_CMN_CTRL1			0xc800
+
+/* PHY_PMA_CMN_CTRL1 */
+#define CMA_REF_CLK_SEL_MASK			GENMASK(6, 4)
+#define CMA_REF_CLK_RCV_EN_MASK			BIT(3)
+#define CMA_REF_CLK_RCV_EN			1
+
+/* PHY_HDP_CLK_CTL */
+#define PLL_DATA_RATE_CLK_DIV_MASK		GENMASK(15, 8)
+#define PLL_DATA_RATE_CLK_DIV_HBR		0x24
+#define PLL_DATA_RATE_CLK_DIV_HBR2		0x12
+#define PLL_CLK_EN_ACK				BIT(3)
+#define PLL_CLK_EN				BIT(2)
+#define PLL_READY				BIT(1)
+#define PLL_EN					BIT(0)
+
+/* CMN_DIAG_HSCLK_SEL */
+#define HSCLK1_SEL_MASK				GENMASK(5, 4)
+#define HSCLK0_SEL_MASK				GENMASK(1, 0)
+#define HSCLK_PLL0_DIV2				1
+
+/* XCVR_DIAG_HSCLK_SEL */
+#define HSCLK_SEL_MODE3_MASK			GENMASK(13, 12)
+#define HSCLK_SEL_MODE3_HSCLK1			1
+
+/* XCVR_DIAG_PLLDRC_CTRL */
+#define DPLL_CLK_SEL_MODE3			BIT(14)
+#define DPLL_DATA_RATE_DIV_MODE3_MASK		GENMASK(13, 12)
+
+/* PHY_HDP_MODE_CTRL */
+#define POWER_STATE_A3_ACK			BIT(7)
+#define POWER_STATE_A2_ACK			BIT(6)
+#define POWER_STATE_A1_ACK			BIT(5)
+#define POWER_STATE_A0_ACK			BIT(4)
+#define POWER_STATE_A3				BIT(3)
+#define POWER_STATE_A2				BIT(2)
+#define POWER_STATE_A1				BIT(1)
+#define POWER_STATE_A0				BIT(0)
+
+#define REF_CLK_27MHZ		27000000
+
+enum dp_link_rate {
+	RATE_1_6 = 162000,
+	RATE_2_1 = 216000,
+	RATE_2_4 = 243000,
+	RATE_2_7 = 270000,
+	RATE_3_2 = 324000,
+	RATE_4_3 = 432000,
+	RATE_5_4 = 540000,
+};
+
+#define MAX_LINK_RATE RATE_5_4
+
+struct phy_pll_reg {
+	u16 val[7];
+	u32 addr;
+};
+
+static const struct phy_pll_reg phy_pll_27m_cfg[] = {
+	/*  1.62    2.16    2.43    2.7     3.24    4.32    5.4      register address */
+	{{ 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e }, CMN_PLL0_VCOCAL_INIT_TMR },
+	{{ 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b, 0x001b }, CMN_PLL0_VCOCAL_ITER_TMR },
+	{{ 0x30b9, 0x3087, 0x3096, 0x30b4, 0x30b9, 0x3087, 0x30b4 }, CMN_PLL0_VCOCAL_START },
+	{{ 0x0077, 0x009f, 0x00b3, 0x00c7, 0x0077, 0x009f, 0x00c7 }, CMN_PLL0_INTDIV },
+	{{ 0xf9da, 0xf7cd, 0xf6c7, 0xf5c1, 0xf9da, 0xf7cd, 0xf5c1 }, CMN_PLL0_FRACDIV },
+	{{ 0x001e, 0x0028, 0x002d, 0x0032, 0x001e, 0x0028, 0x0032 }, CMN_PLL0_HIGH_THR },
+	{{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_PLL0_DSM_DIAG },
+	{{ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000 }, CMN_PLLSM0_USER_DEF_CTRL },
+	{{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_OVRD },
+	{{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBH_OVRD },
+	{{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBL_OVRD },
+	{{ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007 }, CMN_DIAG_PLL0_V2I_TUNE },
+	{{ 0x0043, 0x0043, 0x0043, 0x0042, 0x0043, 0x0043, 0x0042 }, CMN_DIAG_PLL0_CP_TUNE },
+	{{ 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008 }, CMN_DIAG_PLL0_LF_PROG },
+	{{ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE1 },
+	{{ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE2 },
+	{{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_DIAG_PLL0_TEST_MODE},
+	{{ 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016 }, CMN_PSM_CLK_CTRL }
+};
+
+struct cdns_hdptx_dp_phy {
+	struct cdns_mhdp_base base;
+
+	void __iomem *regs;	/* DPTX registers base */
+	struct device *dev;
+	struct phy *phy;
+	struct mutex mbox_mutex;	/* mutex to protect mailbox */
+	struct clk *ref_clk, *apb_clk;
+	u32 ref_clk_rate;
+	u32 num_lanes;
+	u32 link_rate;
+	bool power_up;
+};
+
+static int cdns_phy_reg_write(struct cdns_hdptx_dp_phy *cdns_phy, u32 addr, u32 val)
+{
+	return cdns_mhdp_reg_write(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), val);
+}
+
+static u32 cdns_phy_reg_read(struct cdns_hdptx_dp_phy *cdns_phy, u32 addr)
+{
+	u32 reg32;
+
+	cdns_mhdp_reg_read(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), &reg32);
+	return reg32;
+}
+
+static int link_rate_index(u32 rate)
+{
+	switch (rate) {
+	case RATE_1_6:
+		return 0;
+	case RATE_2_1:
+		return 1;
+	case RATE_2_4:
+		return 2;
+	case RATE_2_7:
+		return 3;
+	case RATE_3_2:
+		return 4;
+	case RATE_4_3:
+		return 5;
+	case RATE_5_4:
+		return 6;
+	default:
+		return -1;
+	}
+}
+
+static int hdptx_dp_clk_enable(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	struct device *dev = cdns_phy->dev;
+	u32 ref_clk_rate;
+	int ret;
+
+	cdns_phy->ref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(cdns_phy->ref_clk)) {
+		dev_err(dev, "phy ref clock not found\n");
+		return PTR_ERR(cdns_phy->ref_clk);
+	}
+
+	cdns_phy->apb_clk = devm_clk_get(dev, "apb");
+	if (IS_ERR(cdns_phy->apb_clk)) {
+		dev_err(dev, "phy apb clock not found\n");
+		return PTR_ERR(cdns_phy->apb_clk);
+	}
+
+	ret = clk_prepare_enable(cdns_phy->ref_clk);
+	if (ret) {
+		dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+		return ret;
+	}
+
+	ref_clk_rate = clk_get_rate(cdns_phy->ref_clk);
+	if (!ref_clk_rate) {
+		dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
+		goto err_ref_clk;
+	}
+
+	if (ref_clk_rate == REF_CLK_27MHZ) {
+		cdns_phy->ref_clk_rate = ref_clk_rate;
+	} else {
+		dev_err(cdns_phy->dev, "Not support Ref Clock Rate(%dHz)\n", ref_clk_rate);
+		goto err_ref_clk;
+	}
+
+	ret = clk_prepare_enable(cdns_phy->apb_clk);
+	if (ret) {
+		dev_err(cdns_phy->dev, "Failed to prepare apb clock\n");
+		goto err_ref_clk;
+	}
+
+	return 0;
+
+err_ref_clk:
+	clk_disable_unprepare(cdns_phy->ref_clk);
+	return -EINVAL;
+}
+
+static void hdptx_dp_clk_disable(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	clk_disable_unprepare(cdns_phy->ref_clk);
+	clk_disable_unprepare(cdns_phy->apb_clk);
+}
+
+static void hdptx_dp_aux_cfg(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	/* Power up Aux */
+	cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 1);
+
+	cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_1, 0x3);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, 36);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa018);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0000);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x1001);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa098);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0xa198);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d);
+	ndelay(150);
+	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f);
+}
+
+/* PMA common configuration for 27MHz */
+static void hdptx_dp_phy_pma_cmn_cfg_27mhz(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	u32 num_lanes = cdns_phy->num_lanes;
+	u16 val;
+	int k;
+
+	/* Enable PMA input ref clk(CMN_REF_CLK_RCV_EN) */
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_RCV_EN_MASK;
+	val |= FIELD_PREP(CMA_REF_CLK_RCV_EN_MASK, CMA_REF_CLK_RCV_EN);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+
+	/* Startup state machine registers */
+	cdns_phy_reg_write(cdns_phy, CMN_SSM_BIAS_TMR, 0x0087);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLEN_TMR, 0x001b);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLPRE_TMR, 0x0036);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLVREF_TMR, 0x001b);
+	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_PLLLOCK_TMR, 0x006c);
+
+	/* Current calibration registers */
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_INIT_TMR, 0x0044);
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_ICAL_ADJ_ITER_TMR, 0x0006);
+
+	/* Resistor calibration registers */
+	cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPUCAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPU_ADJ_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPDCAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_TXPD_ADJ_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_RXCAL_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_RXCAL_ITER_TMR, 0x0006);
+	cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_INIT_TMR, 0x0022);
+	cdns_phy_reg_write(cdns_phy, CMN_RX_ADJ_ITER_TMR, 0x0006);
+
+	for (k = 0; k < num_lanes; k = k + 1) {
+		/* Power state machine registers */
+		cdns_phy_reg_write(cdns_phy, XCVR_PSM_CAL_TMR  | (k << 9), 0x016d);
+		cdns_phy_reg_write(cdns_phy, XCVR_PSM_A0IN_TMR | (k << 9), 0x016d);
+		/* Transceiver control and diagnostic registers */
+		cdns_phy_reg_write(cdns_phy, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9), 0x00a2);
+		cdns_phy_reg_write(cdns_phy, TX_DIAG_BGREF_PREDRV_DELAY | (k << 9), 0x0097);
+		/* Transmitter receiver detect registers */
+		cdns_phy_reg_write(cdns_phy, TX_RCVDET_EN_TMR | (k << 9), 0x0a8c);
+		cdns_phy_reg_write(cdns_phy, TX_RCVDET_ST_TMR | (k << 9), 0x0036);
+	}
+
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1);
+	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1);
+}
+
+static void hdptx_dp_phy_pma_cmn_pll0_27mhz(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	u32 num_lanes = cdns_phy->num_lanes;
+	u32 link_rate = cdns_phy->link_rate;
+	u16 val;
+	int index, i, k;
+
+	/* DP PLL data rate 0/1 clock divider value */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_DATA_RATE_CLK_DIV_MASK;
+	if (link_rate <= RATE_2_7)
+		val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
+				  PLL_DATA_RATE_CLK_DIV_HBR);
+	else
+		val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
+				  PLL_DATA_RATE_CLK_DIV_HBR2);
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+
+	/* High speed clock 0/1 div */
+	val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL);
+	val &= ~(HSCLK1_SEL_MASK | HSCLK0_SEL_MASK);
+	if (link_rate <= RATE_2_7) {
+		val |= FIELD_PREP(HSCLK1_SEL_MASK, HSCLK_PLL0_DIV2);
+		val |= FIELD_PREP(HSCLK0_SEL_MASK, HSCLK_PLL0_DIV2);
+	}
+	cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val);
+
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+		val &= ~HSCLK_SEL_MODE3_MASK;
+		if (link_rate <= RATE_2_7)
+			val |= FIELD_PREP(HSCLK_SEL_MODE3_MASK, HSCLK_SEL_MODE3_HSCLK1);
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val);
+	}
+
+	/* DP PHY PLL 27MHz configuration */
+	index = link_rate_index(link_rate);
+	for (i = 0; i < ARRAY_SIZE(phy_pll_27m_cfg); i++)
+		cdns_phy_reg_write(cdns_phy, phy_pll_27m_cfg[i].addr,
+				   phy_pll_27m_cfg[i].val[index]);
+
+	/* Transceiver control and diagnostic registers */
+	for (k = 0; k < num_lanes; k++) {
+		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+		val &= ~(DPLL_DATA_RATE_DIV_MODE3_MASK | DPLL_CLK_SEL_MODE3);
+		if (link_rate <= RATE_2_7)
+			val |= FIELD_PREP(DPLL_DATA_RATE_DIV_MODE3_MASK, 2);
+		else
+			val |= FIELD_PREP(DPLL_DATA_RATE_DIV_MODE3_MASK, 1);
+		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val);
+	}
+
+	for (k = 0; k < num_lanes; k = k + 1) {
+		/* Power state machine registers */
+		cdns_phy_reg_write(cdns_phy, (XCVR_PSM_RCTRL | (k << 9)), 0xbefc);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A0 | (k << 9)), 0x6799);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A1 | (k << 9)), 0x6798);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A2 | (k << 9)), 0x0098);
+		cdns_phy_reg_write(cdns_phy, (TX_PSC_A3 | (k << 9)), 0x0098);
+		/* Receiver calibration power state definition register */
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, (RX_PSC_CAL | (k << 9)), val);
+		val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9));
+		val &= 0xffbb;
+		cdns_phy_reg_write(cdns_phy, (RX_PSC_A0 | (k << 9)), val);
+	}
+}
+
+static void hdptx_dp_phy_ref_clock_type(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	u32 val;
+
+	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
+	val &= ~CMA_REF_CLK_SEL_MASK;
+	/*
+	 * single ended reference clock (val |= 0x0030);
+	 * differential clock  (val |= 0x0000);
+	 *
+	 * for differential clock on the refclk_p and
+	 * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1
+	 * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100);
+	 */
+	val |= FIELD_PREP(CMA_REF_CLK_SEL_MASK, 3);
+	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
+}
+
+static int wait_for_ack(struct cdns_hdptx_dp_phy *cdns_phy, u32 reg, u32 mask,
+			const char *err_msg)
+{
+	u32 val, i;
+
+	for (i = 0; i < 10; i++) {
+		val = cdns_phy_reg_read(cdns_phy, reg);
+		if (val & mask)
+			return 0;
+		msleep(20);
+	}
+
+	dev_err(cdns_phy->dev, "%s\n", err_msg);
+	return -ETIMEDOUT;
+}
+
+static int wait_for_ack_clear(struct cdns_hdptx_dp_phy *cdns_phy, u32 reg, u32 mask,
+			      const char *err_msg)
+{
+	u32 val, i;
+
+	for (i = 0; i < 10; i++) {
+		val = cdns_phy_reg_read(cdns_phy, reg);
+		if (!(val & mask))
+			return 0;
+		msleep(20);
+	}
+
+	dev_err(cdns_phy->dev, "%s\n", err_msg);
+	return -ETIMEDOUT;
+}
+
+static int hdptx_dp_phy_power_up(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	u32 val;
+	int ret = 0;
+
+	/* Enable HDP PLL?s for high speed clocks */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val |= PLL_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_CLK_CTL, PLL_READY,
+			   "Wait PLL Ack failed");
+	if (ret < 0)
+		return ret;
+
+	/* Enable HDP PLL?s data rate and full rate clocks out of PMA. */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val |= PLL_CLK_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_CLK_CTL, PLL_CLK_EN_ACK,
+			   "Wait PLL clock enable ACK failed");
+	if (ret < 0)
+		return ret;
+
+	/* Configure PHY in A2 Mode */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2_ACK,
+			   "Wait A2 Ack failed");
+	if (ret < 0)
+		return ret;
+
+	/* Configure PHY in A0 mode (PHY must be in the A0 power
+	 * state in order to transmit data)
+	 */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0);
+	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0_ACK,
+			   "Wait A0 Ack failed");
+	if (ret < 0)
+		return ret;
+
+	cdns_phy->power_up = true;
+
+	return ret;
+}
+
+static void hdptx_dp_phy_power_down(struct cdns_hdptx_dp_phy *cdns_phy)
+{
+	u16 val;
+
+	if (!cdns_phy->power_up)
+		return;
+
+	/* Place the PHY lanes in the A3 power state. */
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3);
+	if (wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3_ACK,
+			 "Wait A3 Ack failed"))
+		return;
+
+	/* Disable HDP PLL?s data rate and full rate clocks out of PMA. */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_CLK_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	if (wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL, PLL_CLK_EN_ACK,
+			       "Wait PLL clock Ack clear failed"))
+		return;
+
+	/* Disable HDP PLL?s for high speed clocks */
+	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
+	val &= ~PLL_EN;
+	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
+	if (wait_for_ack_clear(cdns_phy, PHY_HDP_CLK_CTL, PLL_READY,
+			       "Wait PLL Ack clear failed"))
+		return;
+
+	cdns_phy->power_up = false;
+}
+
+static int cdns_hdptx_dp_phy_on(struct phy *phy)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy);
+
+	return hdptx_dp_phy_power_up(cdns_phy);
+}
+
+static int cdns_hdptx_dp_phy_off(struct phy *phy)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy);
+
+	hdptx_dp_phy_power_down(cdns_phy);
+
+	return 0;
+}
+
+static int cdns_hdptx_dp_phy_init(struct phy *phy)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy);
+	int ret;
+
+	hdptx_dp_phy_ref_clock_type(cdns_phy);
+
+	/* PHY power up */
+	ret = hdptx_dp_phy_power_up(cdns_phy);
+	if (ret < 0)
+		return ret;
+
+	hdptx_dp_aux_cfg(cdns_phy);
+
+	return ret;
+}
+
+static int cdns_hdptx_dp_configure(struct phy *phy,
+				   union phy_configure_opts *opts)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy = phy_get_drvdata(phy);
+	int ret;
+
+	cdns_phy->link_rate = opts->dp.link_rate;
+	cdns_phy->num_lanes = opts->dp.lanes;
+
+	if (cdns_phy->link_rate > MAX_LINK_RATE) {
+		dev_err(cdns_phy->dev, "Link Rate(%d) Not supported\n", cdns_phy->link_rate);
+		return false;
+	}
+
+	/* Disable phy clock if PHY in power up state */
+	hdptx_dp_phy_power_down(cdns_phy);
+
+	if (cdns_phy->ref_clk_rate == REF_CLK_27MHZ) {
+		hdptx_dp_phy_pma_cmn_cfg_27mhz(cdns_phy);
+		hdptx_dp_phy_pma_cmn_pll0_27mhz(cdns_phy);
+	} else {
+		dev_err(cdns_phy->dev, "Not support ref clock rate\n");
+	}
+
+	/* PHY power up */
+	ret = hdptx_dp_phy_power_up(cdns_phy);
+
+	return ret;
+}
+
+static const struct phy_ops cdns_hdptx_dp_phy_ops = {
+	.init = cdns_hdptx_dp_phy_init,
+	.configure = cdns_hdptx_dp_configure,
+	.power_on = cdns_hdptx_dp_phy_on,
+	.power_off = cdns_hdptx_dp_phy_off,
+	.owner = THIS_MODULE,
+};
+
+static int cdns_hdptx_dp_phy_probe(struct platform_device *pdev)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy;
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct phy_provider *phy_provider;
+	struct resource *res;
+	struct phy *phy;
+	int ret;
+
+	cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
+	if (!cdns_phy)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, cdns_phy);
+	cdns_phy->dev = dev;
+	mutex_init(&cdns_phy->mbox_mutex);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(cdns_phy->regs))
+		return PTR_ERR(cdns_phy->regs);
+
+	phy = devm_phy_create(dev, node, &cdns_hdptx_dp_phy_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	phy->attrs.mode = PHY_MODE_DP;
+	cdns_phy->phy = phy;
+	phy_set_drvdata(phy, cdns_phy);
+
+	/* init base struct for access mhdp mailbox */
+	cdns_phy->base.dev = cdns_phy->dev;
+	cdns_phy->base.regs = cdns_phy->regs;
+	cdns_phy->base.mbox_mutex = &cdns_phy->mbox_mutex;
+
+	ret = hdptx_dp_clk_enable(cdns_phy);
+	if (ret) {
+		dev_err(dev, "Init clk fail\n");
+		return -EINVAL;
+	}
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider)) {
+		ret = PTR_ERR(phy_provider);
+		goto clk_disable;
+	}
+
+	return 0;
+
+clk_disable:
+	hdptx_dp_clk_disable(cdns_phy);
+
+	return -EINVAL;
+}
+
+static int cdns_hdptx_dp_phy_remove(struct platform_device *pdev)
+{
+	struct cdns_hdptx_dp_phy *cdns_phy = platform_get_drvdata(pdev);
+
+	hdptx_dp_clk_disable(cdns_phy);
+
+	return 0;
+}
+
+static const struct of_device_id cdns_hdptx_dp_phy_of_match[] = {
+	{.compatible = "fsl,imx8mq-dp-phy" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cdns_hdptx_dp_phy_of_match);
+
+static struct platform_driver cdns_hdptx_dp_phy_driver = {
+	.probe = cdns_hdptx_dp_phy_probe,
+	.remove = cdns_hdptx_dp_phy_remove,
+	.driver = {
+		.name	= "cdns-hdptx-dp-phy",
+		.of_match_table	= cdns_hdptx_dp_phy_of_match,
+	}
+};
+module_platform_driver(cdns_hdptx_dp_phy_driver);
+
+MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("Cadence HDP-TX DisplayPort PHY driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From Dharma.B at microchip.com  Mon Feb 19 19:34:16 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Tue, 20 Feb 2024 03:34:16 +0000
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
Message-ID: <ffd43756-b24e-4f19-be33-0e33047ad70c@microchip.com>

Hi Krzysztof,

On 12/02/24 3:53 pm, Krzysztof Kozlowski wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On 08/02/2024 11:43, Lee Jones wrote:
>> On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
>>> Convert the atmel,hlcdc binding to DT schema format.
>>>
>>> Align clocks and clock-names properties to clearly indicate that the LCD
>>> controller expects lvds_pll_clk when interfaced with the lvds display. This
>>> alignment with the specific hardware requirements ensures accurate device tree
>>> configuration for systems utilizing the HLCDC IP.
>>>
>>> [...]
>>
>> Applied, thanks!
>>
>> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
>>        commit: cb946db1335b599ece363d33966bf653ed0fa58a
>>
> 
> Next is still failing.
> 
> Dharma,
> You must explain and clearly mark dependencies between patches.

I sincerely apologize for any confusion caused by the oversight. I have 
organized the patches according to their dependencies in the patch 
series, but unfortunately, I neglected to explicitly mention these 
dependencies. I understand the importance of clear communication in our 
collaborative efforts. Please feel free to provide guidance on how I can 
assist you further in resolving this matter.

> 
> Lee,
> Can you pick up two previous patches as well?
> 
> Best regards,
> Krzysztof
> 

-- 
With Best Regards,
Dharma B.


From Sandor.yu at nxp.com  Mon Feb 19 19:23:53 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 20 Feb 2024 11:23:53 +0800
Subject: [PATCH v14 5/7] dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
In-Reply-To: <cover.1708395604.git.Sandor.yu@nxp.com>
References: <cover.1708395604.git.Sandor.yu@nxp.com>
Message-ID: <8ddbb34b5f6bf2414bdb03f9e7cd9da70e4e7228.1708395604.git.Sandor.yu@nxp.com>

Add bindings for Freescale iMX8MQ DP and HDMI PHY.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
v9->v14:
 *No change.

 .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  | 53 +++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
new file mode 100644
index 0000000000000..917f113503dca
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,imx8mq-dp-hdmi-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence HDP-TX DP/HDMI PHY for Freescale i.MX8MQ SoC
+
+maintainers:
+  - Sandor Yu <sandor.yu at nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mq-dp-phy
+      - fsl,imx8mq-hdmi-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PHY reference clock.
+      - description: APB clock.
+
+  clock-names:
+    items:
+      - const: ref
+      - const: apb
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/phy/phy.h>
+    dp_phy: phy at 32c00000 {
+        compatible = "fsl,imx8mq-dp-phy";
+        reg = <0x32c00000 0x100000>;
+        #phy-cells = <0>;
+        clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        clock-names = "ref", "apb";
+    };
-- 
2.34.1



From Sandor.yu at nxp.com  Mon Feb 19 19:23:52 2024
From: Sandor.yu at nxp.com (Sandor Yu)
Date: Tue, 20 Feb 2024 11:23:52 +0800
Subject: [PATCH v14 4/7] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver
In-Reply-To: <cover.1708395604.git.Sandor.yu@nxp.com>
References: <cover.1708395604.git.Sandor.yu@nxp.com>
Message-ID: <b1929bf43162d8c02fbfff034460077ccad9fb7f.1708395604.git.Sandor.yu@nxp.com>

Add a new DRM DisplayPort and HDMI bridge driver for Candence MHDP8501
used in i.MX8MQ SOC. MHDP8501 could support HDMI or DisplayPort
standards according embedded Firmware running in the uCPU.

For iMX8MQ SOC, the DisplayPort/HDMI FW was loaded and activated by
SOC's ROM code. Bootload binary included respective specific firmware
is required.

Driver will check display connector type and
then load the corresponding driver.

Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
v13->v14:
- Rebase to next-20240219, replace get_edid function by edid_read
  function.

v12->v13:
- Explicitly include linux/platform_device.h for cdns-mhdp8501-core.c
- Fix build warning
- Order bit bpc and color_space in descending shit. 

v11->v12:
- Replace DRM_INFO with dev_info or dev_warn.
- Replace DRM_ERROR with dev_err.
- Return ret when cdns_mhdp_dpcd_read failed in function cdns_dp_aux_transferi().
- Remove unused parmeter in function cdns_dp_get_msa_misc
  and use two separate variables for color space and bpc.
- Add year 2024 to copyright.

 drivers/gpu/drm/bridge/cadence/Kconfig        |  16 +
 drivers/gpu/drm/bridge/cadence/Makefile       |   2 +
 .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 316 ++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 365 +++++++++
 .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 700 ++++++++++++++++++
 .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 680 +++++++++++++++++
 6 files changed, 2079 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c

diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig
index e0973339e9e33..45848e741f5f4 100644
--- a/drivers/gpu/drm/bridge/cadence/Kconfig
+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
@@ -51,3 +51,19 @@ config DRM_CDNS_MHDP8546_J721E
 	  initializes the J721E Display Port and sets up the
 	  clock and data muxes.
 endif
+
+config DRM_CDNS_MHDP8501
+	tristate "Cadence MHDP8501 DP/HDMI bridge"
+	select DRM_KMS_HELPER
+	select DRM_PANEL_BRIDGE
+	select DRM_DISPLAY_DP_HELPER
+	select DRM_DISPLAY_HELPER
+	select CDNS_MHDP_HELPER
+	select DRM_CDNS_AUDIO
+	depends on OF
+	help
+	  Support Cadence MHDP8501 DisplayPort/HDMI bridge.
+	  Cadence MHDP8501 support one or more protocols,
+	  including DisplayPort and HDMI.
+	  To use the DP and HDMI drivers, their respective
+	  specific firmware is required.
diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile
index 087dc074820d7..02c1a9f3cf6fc 100644
--- a/drivers/gpu/drm/bridge/cadence/Makefile
+++ b/drivers/gpu/drm/bridge/cadence/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
 cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
+obj-$(CONFIG_DRM_CDNS_MHDP8501) += cdns-mhdp8501.o
+cdns-mhdp8501-y := cdns-mhdp8501-core.o cdns-mhdp8501-dp.o cdns-mhdp8501-hdmi.o
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
new file mode 100644
index 0000000000000..bc36797b39fdb
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence Display Port Interface (DP) driver
+ *
+ * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/drm_of.h>
+#include <drm/drm_print.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+
+#include "cdns-mhdp8501-core.h"
+
+static int cdns_mhdp8501_read_hpd(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 status;
+	int ret;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_GENERAL,
+				     GENERAL_GET_HPD_STATE, 0, NULL);
+	if (ret)
+		goto err_get_hpd;
+
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_GENERAL,
+					    GENERAL_GET_HPD_STATE,
+					    sizeof(status));
+	if (ret)
+		goto err_get_hpd;
+
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, &status, sizeof(status));
+	if (ret)
+		goto err_get_hpd;
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	return status;
+
+err_get_hpd:
+	dev_err(mhdp->dev, "read hpd  failed: %d\n", ret);
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	return ret;
+}
+
+enum drm_connector_status cdns_mhdp8501_detect(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 hpd = 0xf;
+
+	hpd = cdns_mhdp8501_read_hpd(mhdp);
+	if (hpd == 1)
+		return connector_status_connected;
+	else if (hpd == 0)
+		return connector_status_disconnected;
+
+	dev_warn(mhdp->dev, "Unknown cable status, hdp=%u\n", hpd);
+	return connector_status_unknown;
+}
+
+static void hotplug_work_func(struct work_struct *work)
+{
+	struct cdns_mhdp8501_device *mhdp = container_of(work,
+						     struct cdns_mhdp8501_device,
+						     hotplug_work.work);
+	enum drm_connector_status status = cdns_mhdp8501_detect(mhdp);
+
+	drm_bridge_hpd_notify(&mhdp->bridge, status);
+
+	if (status == connector_status_connected) {
+		/* Cable connected  */
+		DRM_INFO("HDMI/DP Cable Plug In\n");
+		enable_irq(mhdp->irq[IRQ_OUT]);
+	} else if (status == connector_status_disconnected) {
+		/* Cable Disconnected  */
+		DRM_INFO("HDMI/DP Cable Plug Out\n");
+		enable_irq(mhdp->irq[IRQ_IN]);
+	}
+}
+
+static irqreturn_t cdns_mhdp8501_irq_thread(int irq, void *data)
+{
+	struct cdns_mhdp8501_device *mhdp = data;
+
+	disable_irq_nosync(irq);
+
+	mod_delayed_work(system_wq, &mhdp->hotplug_work,
+			 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
+
+	return IRQ_HANDLED;
+}
+
+static int cdns_mhdp8501_dt_parse(struct cdns_mhdp8501_device *mhdp,
+				  struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *remote;
+
+	remote = of_graph_get_remote_node(np, 1, 0);
+	if (!remote) {
+		dev_err(dev, "fail to get remote node\n");
+		of_node_put(remote);
+		return -EINVAL;
+	}
+
+	/* get connector type */
+	if (of_device_is_compatible(remote, "hdmi-connector")) {
+		mhdp->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+
+	} else if (of_device_is_compatible(remote, "dp-connector")) {
+		mhdp->connector_type = DRM_MODE_CONNECTOR_DisplayPort;
+
+	} else {
+		dev_err(dev, "Unknown connector type\n");
+		of_node_put(remote);
+		return -EINVAL;
+	}
+
+	of_node_put(remote);
+	return true;
+}
+
+static void cdns_mhdp8501_add_bridge(struct cdns_mhdp8501_device *mhdp)
+{
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+		mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs;
+	} else if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+		mhdp->bridge.funcs = &cdns_dp_bridge_funcs;
+	} else {
+		dev_err(mhdp->dev, "Unsupported connector type!\n");
+		return;
+	}
+
+	mhdp->bridge.type = mhdp->connector_type;
+	mhdp->bridge.driver_private = mhdp;
+	mhdp->bridge.of_node = mhdp->dev->of_node;
+	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
+			   DRM_BRIDGE_OP_HPD;
+	drm_bridge_add(&mhdp->bridge);
+}
+
+static int cdns_mhdp8501_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cdns_mhdp8501_device *mhdp;
+	struct resource *res;
+	u32 reg;
+	int ret;
+
+	mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
+	if (!mhdp)
+		return -ENOMEM;
+
+	mutex_init(&mhdp->mbox_mutex);
+	mhdp->dev = dev;
+
+	INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	mhdp->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(mhdp->regs))
+		return PTR_ERR(mhdp->regs);
+
+	ret = cdns_mhdp8501_dt_parse(mhdp, pdev);
+	if (ret < 0)
+		return -EINVAL;
+
+	mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node, 0);
+	if (IS_ERR(mhdp->phy))
+		return dev_err_probe(dev, PTR_ERR(mhdp->phy), "no PHY configured\n");
+
+	mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
+	if (mhdp->irq[IRQ_IN] < 0)
+		return dev_err_probe(dev, mhdp->irq[IRQ_IN], "No plug_in irq number\n");
+
+	mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
+	if (mhdp->irq[IRQ_OUT] < 0)
+		return dev_err_probe(dev, mhdp->irq[IRQ_OUT], "No plug_out irq number\n");
+
+	irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
+					NULL, cdns_mhdp8501_irq_thread,
+					IRQF_ONESHOT, dev_name(dev), mhdp);
+	if (ret < 0) {
+		dev_err(dev, "can't claim irq %d\n", mhdp->irq[IRQ_IN]);
+		return -EINVAL;
+	}
+
+	irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
+					NULL, cdns_mhdp8501_irq_thread,
+					IRQF_ONESHOT, dev_name(dev), mhdp);
+	if (ret < 0) {
+		dev_err(dev, "can't claim irq %d\n", mhdp->irq[IRQ_OUT]);
+		return -EINVAL;
+	}
+
+	/* set default lane mapping */
+	mhdp->lane_mapping = LANE_MAPPING_NORMAL;
+
+	mhdp->plat_data = of_device_get_match_data(dev);
+	if (mhdp->plat_data) {
+		if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
+			mhdp->lane_mapping = mhdp->plat_data->dp_lane_mapping;
+		else if (mhdp->connector_type == DRM_MODE_CONNECTOR_HDMIA)
+			mhdp->lane_mapping = mhdp->plat_data->hdmi_lane_mapping;
+	}
+
+	dev_set_drvdata(dev, mhdp);
+
+	/* init base struct for access mhdp mailbox */
+	mhdp->base.dev = mhdp->dev;
+	mhdp->base.regs = mhdp->regs;
+	mhdp->base.mbox_mutex = &mhdp->mbox_mutex;
+
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+		drm_dp_aux_init(&mhdp->dp.aux);
+		mhdp->dp.aux.name = "mhdp8501_dp_aux";
+		mhdp->dp.aux.dev = dev;
+		mhdp->dp.aux.transfer = cdns_dp_aux_transfer;
+	}
+
+	/* Enable APB clock */
+	mhdp->apb_clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(mhdp->apb_clk))
+		return dev_err_probe(dev, PTR_ERR(mhdp->apb_clk),
+				     "couldn't get apb clk\n");
+
+	clk_prepare_enable(mhdp->apb_clk);
+
+	/*
+	 * Wait for the KEEP_ALIVE "message" on the first 8 bits.
+	 * Updated each sched "tick" (~2ms)
+	 */
+	ret = readl_poll_timeout(mhdp->regs + KEEP_ALIVE, reg,
+				 reg & CDNS_KEEP_ALIVE_MASK, 500,
+				 CDNS_KEEP_ALIVE_TIMEOUT);
+	if (ret) {
+		dev_err(dev, "device didn't give any life sign: reg %d\n", reg);
+		goto clk_disable;
+	}
+
+	/* Mailbox protect for HDMI PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	ret = phy_init(mhdp->phy);
+	mutex_unlock(&mhdp->mbox_mutex);
+	if (ret) {
+		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
+		goto clk_disable;
+	}
+
+	/* Enable cable hotplug detect */
+	if (cdns_mhdp8501_read_hpd(mhdp))
+		enable_irq(mhdp->irq[IRQ_OUT]);
+	else
+		enable_irq(mhdp->irq[IRQ_IN]);
+
+	cdns_mhdp8501_add_bridge(mhdp);
+
+	return 0;
+
+clk_disable:
+	clk_disable_unprepare(mhdp->apb_clk);
+
+	return -EINVAL;
+}
+
+static int cdns_mhdp8501_remove(struct platform_device *pdev)
+{
+	struct cdns_mhdp8501_device *mhdp = platform_get_drvdata(pdev);
+
+	if (mhdp->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
+		cdns_dp_aux_destroy(mhdp);
+
+	drm_bridge_remove(&mhdp->bridge);
+	clk_disable_unprepare(mhdp->apb_clk);
+
+	return 0;
+}
+
+static struct mhdp8501_plat_data imx8mq_mhdp_drv_data = {
+	.hdmi_lane_mapping = LANE_MAPPING_FLIPPED,
+	.dp_lane_mapping = LANE_MAPPING_IMX8MQ_DP,
+};
+
+static const struct of_device_id cdns_mhdp8501_dt_ids[] = {
+	{ .compatible = "fsl,imx8mq-mhdp8501",
+	  .data = &imx8mq_mhdp_drv_data
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, cdns_mhdp8501_dt_ids);
+
+static struct platform_driver cdns_mhdp8501_driver = {
+	.probe = cdns_mhdp8501_probe,
+	.remove = cdns_mhdp8501_remove,
+	.driver = {
+		.name = "cdns-mhdp8501",
+		.of_match_table = cdns_mhdp8501_dt_ids,
+	},
+};
+
+module_platform_driver(cdns_mhdp8501_driver);
+
+MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
+MODULE_DESCRIPTION("Cadence MHDP8501 bridge driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
new file mode 100644
index 0000000000000..f8a5774bc50ce
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
@@ -0,0 +1,365 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Cadence MHDP 8501 Common head file
+ *
+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
+ *
+ */
+
+#ifndef _CDNS_MHDP8501_CORE_H_
+#define _CDNS_MHDP8501_CORE_H_
+
+#include <drm/bridge/cdns-mhdp-helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_connector.h>
+#include <drm/display/drm_dp_helper.h>
+#include <linux/bitops.h>
+
+#define ADDR_IMEM			0x10000
+#define ADDR_DMEM			0x20000
+
+/* APB CFG addr */
+#define APB_CTRL			0
+#define XT_INT_CTRL			0x04
+#define MAILBOX_FULL_ADDR		0x08
+#define MAILBOX_EMPTY_ADDR		0x0c
+#define MAILBOX0_WR_DATA		0x10
+#define MAILBOX0_RD_DATA		0x14
+#define KEEP_ALIVE			0x18
+#define VER_L				0x1c
+#define VER_H				0x20
+#define VER_LIB_L_ADDR			0x24
+#define VER_LIB_H_ADDR			0x28
+#define SW_DEBUG_L			0x2c
+#define SW_DEBUG_H			0x30
+#define MAILBOX_INT_MASK		0x34
+#define MAILBOX_INT_STATUS		0x38
+#define SW_CLK_L			0x3c
+#define SW_CLK_H			0x40
+#define SW_EVENTS0			0x44
+#define SW_EVENTS1			0x48
+#define SW_EVENTS2			0x4c
+#define SW_EVENTS3			0x50
+#define XT_OCD_CTRL			0x60
+#define APB_INT_MASK			0x6c
+#define APB_STATUS_MASK			0x70
+
+/* Source phy comp */
+#define PHY_DATA_SEL			0x0818
+#define LANES_CONFIG			0x0814
+
+/* Source CAR Addr */
+#define SOURCE_HDTX_CAR			0x0900
+#define SOURCE_DPTX_CAR			0x0904
+#define SOURCE_PHY_CAR			0x0908
+#define SOURCE_CEC_CAR			0x090c
+#define SOURCE_CBUS_CAR			0x0910
+#define SOURCE_PKT_CAR			0x0918
+#define SOURCE_AIF_CAR			0x091c
+#define SOURCE_CIPHER_CAR		0x0920
+#define SOURCE_CRYPTO_CAR		0x0924
+
+/* clock meters addr */
+#define CM_CTRL				0x0a00
+#define CM_I2S_CTRL			0x0a04
+#define CM_SPDIF_CTRL			0x0a08
+#define CM_VID_CTRL			0x0a0c
+#define CM_LANE_CTRL			0x0a10
+#define I2S_NM_STABLE			0x0a14
+#define I2S_NCTS_STABLE			0x0a18
+#define SPDIF_NM_STABLE			0x0a1c
+#define SPDIF_NCTS_STABLE		0x0a20
+#define NMVID_MEAS_STABLE		0x0a24
+#define I2S_MEAS			0x0a40
+#define SPDIF_MEAS			0x0a80
+#define NMVID_MEAS			0x0ac0
+
+/* source vif addr */
+#define BND_HSYNC2VSYNC			0x0b00
+#define HSYNC2VSYNC_F1_L1		0x0b04
+#define HSYNC2VSYNC_STATUS		0x0b0c
+#define HSYNC2VSYNC_POL_CTRL		0x0b10
+
+/* MHDP TX_top_comp */
+#define SCHEDULER_H_SIZE		0x1000
+#define SCHEDULER_V_SIZE		0x1004
+#define HDTX_SIGNAL_FRONT_WIDTH		0x100c
+#define HDTX_SIGNAL_SYNC_WIDTH		0x1010
+#define HDTX_SIGNAL_BACK_WIDTH		0x1014
+#define HDTX_CONTROLLER			0x1018
+#define HDTX_HPD			0x1020
+#define HDTX_CLOCK_REG_0		0x1024
+#define HDTX_CLOCK_REG_1		0x1028
+
+/* DPTX hpd addr */
+#define HPD_IRQ_DET_MIN_TIMER		0x2100
+#define HPD_IRQ_DET_MAX_TIMER		0x2104
+#define HPD_UNPLGED_DET_MIN_TIMER	0x2108
+#define HPD_STABLE_TIMER		0x210c
+#define HPD_FILTER_TIMER		0x2110
+#define HPD_EVENT_MASK			0x211c
+#define HPD_EVENT_DET			0x2120
+
+/* DPTX framer addr */
+#define DP_FRAMER_GLOBAL_CONFIG		0x2200
+#define DP_SW_RESET			0x2204
+#define DP_FRAMER_TU			0x2208
+#define DP_FRAMER_PXL_REPR		0x220c
+#define DP_FRAMER_SP			0x2210
+#define AUDIO_PACK_CONTROL		0x2214
+#define DP_VC_TABLE(x)			(0x2218 + ((x) << 2))
+#define DP_VB_ID			0x2258
+#define DP_MTPH_LVP_CONTROL		0x225c
+#define DP_MTPH_SYMBOL_VALUES		0x2260
+#define DP_MTPH_ECF_CONTROL		0x2264
+#define DP_MTPH_ACT_CONTROL		0x2268
+#define DP_MTPH_STATUS			0x226c
+#define DP_INTERRUPT_SOURCE		0x2270
+#define DP_INTERRUPT_MASK		0x2274
+#define DP_FRONT_BACK_PORCH		0x2278
+#define DP_BYTE_COUNT			0x227c
+
+/* DPTX stream addr */
+#define MSA_HORIZONTAL_0		0x2280
+#define MSA_HORIZONTAL_1		0x2284
+#define MSA_VERTICAL_0			0x2288
+#define MSA_VERTICAL_1			0x228c
+#define MSA_MISC			0x2290
+#define STREAM_CONFIG			0x2294
+#define AUDIO_PACK_STATUS		0x2298
+#define VIF_STATUS			0x229c
+#define PCK_STUFF_STATUS_0		0x22a0
+#define PCK_STUFF_STATUS_1		0x22a4
+#define INFO_PACK_STATUS		0x22a8
+#define RATE_GOVERNOR_STATUS		0x22ac
+#define DP_HORIZONTAL			0x22b0
+#define DP_VERTICAL_0			0x22b4
+#define DP_VERTICAL_1			0x22b8
+#define DP_BLOCK_SDP			0x22bc
+
+/* DPTX glbl addr */
+#define DPTX_LANE_EN			0x2300
+#define DPTX_ENHNCD			0x2304
+#define DPTX_INT_MASK			0x2308
+#define DPTX_INT_STATUS			0x230c
+
+/* DP AUX Addr */
+#define DP_AUX_HOST_CONTROL		0x2800
+#define DP_AUX_INTERRUPT_SOURCE		0x2804
+#define DP_AUX_INTERRUPT_MASK		0x2808
+#define DP_AUX_SWAP_INVERSION_CONTROL	0x280c
+#define DP_AUX_SEND_NACK_TRANSACTION	0x2810
+#define DP_AUX_CLEAR_RX			0x2814
+#define DP_AUX_CLEAR_TX			0x2818
+#define DP_AUX_TIMER_STOP		0x281c
+#define DP_AUX_TIMER_CLEAR		0x2820
+#define DP_AUX_RESET_SW			0x2824
+#define DP_AUX_DIVIDE_2M		0x2828
+#define DP_AUX_TX_PREACHARGE_LENGTH	0x282c
+#define DP_AUX_FREQUENCY_1M_MAX		0x2830
+#define DP_AUX_FREQUENCY_1M_MIN		0x2834
+#define DP_AUX_RX_PRE_MIN		0x2838
+#define DP_AUX_RX_PRE_MAX		0x283c
+#define DP_AUX_TIMER_PRESET		0x2840
+#define DP_AUX_NACK_FORMAT		0x2844
+#define DP_AUX_TX_DATA			0x2848
+#define DP_AUX_RX_DATA			0x284c
+#define DP_AUX_TX_STATUS		0x2850
+#define DP_AUX_RX_STATUS		0x2854
+#define DP_AUX_RX_CYCLE_COUNTER		0x2858
+#define DP_AUX_MAIN_STATES		0x285c
+#define DP_AUX_MAIN_TIMER		0x2860
+#define DP_AUX_AFE_OUT			0x2864
+
+/* source pif addr */
+#define SOURCE_PIF_WR_ADDR		0x30800
+#define SOURCE_PIF_WR_REQ		0x30804
+#define SOURCE_PIF_RD_ADDR		0x30808
+#define SOURCE_PIF_RD_REQ		0x3080c
+#define SOURCE_PIF_DATA_WR		0x30810
+#define SOURCE_PIF_DATA_RD		0x30814
+#define SOURCE_PIF_FIFO1_FLUSH		0x30818
+#define SOURCE_PIF_FIFO2_FLUSH		0x3081c
+#define SOURCE_PIF_STATUS		0x30820
+#define SOURCE_PIF_INTERRUPT_SOURCE	0x30824
+#define SOURCE_PIF_INTERRUPT_MASK	0x30828
+#define SOURCE_PIF_PKT_ALLOC_REG	0x3082c
+#define SOURCE_PIF_PKT_ALLOC_WR_EN	0x30830
+#define SOURCE_PIF_SW_RESET		0x30834
+
+#define LINK_TRAINING_NOT_ACTIV		0
+#define LINK_TRAINING_RUN		1
+#define LINK_TRAINING_RESTART		2
+
+#define CONTROL_VIDEO_IDLE		0
+#define CONTROL_VIDEO_VALID		1
+
+#define INTERLACE_FMT_DET		BIT(12)
+#define VIF_BYPASS_INTERLACE		BIT(13)
+#define TU_CNT_RST_EN			BIT(15)
+#define INTERLACE_DTCT_WIN		0x20
+
+#define DP_FRAMER_SP_INTERLACE_EN	BIT(2)
+#define DP_FRAMER_SP_HSP		BIT(1)
+#define DP_FRAMER_SP_VSP		BIT(0)
+
+/* Capability */
+#define AUX_HOST_INVERT			3
+#define FAST_LT_SUPPORT			1
+#define FAST_LT_NOT_SUPPORT		0
+#define LANE_MAPPING_NORMAL		0x1b
+#define LANE_MAPPING_FLIPPED		0xe4
+#define LANE_MAPPING_IMX8MQ_DP		0xc6
+#define ENHANCED			1
+#define SCRAMBLER_EN			BIT(4)
+
+#define FULL_LT_STARTED			BIT(0)
+#define FASE_LT_STARTED			BIT(1)
+#define CLK_RECOVERY_FINISHED		BIT(2)
+#define EQ_PHASE_FINISHED		BIT(3)
+#define FASE_LT_START_FINISHED		BIT(4)
+#define CLK_RECOVERY_FAILED		BIT(5)
+#define EQ_PHASE_FAILED			BIT(6)
+#define FASE_LT_FAILED			BIT(7)
+
+#define TU_SIZE				30
+#define CDNS_DP_MAX_LINK_RATE		540000
+
+#define F_HDMI_ENCODING(x) (((x) & ((1 << 2) - 1)) << 16)
+#define F_VIF_DATA_WIDTH(x) (((x) & ((1 << 2) - 1)) << 2)
+#define F_HDMI_MODE(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_GCP_EN(x) (((x) & ((1 << 1) - 1)) << 12)
+#define F_DATA_EN(x) (((x) & ((1 << 1) - 1)) << 15)
+#define F_HDMI2_PREAMBLE_EN(x) (((x) & ((1 << 1) - 1)) << 18)
+#define F_PIC_3D(x) (((x) & ((1 << 4) - 1)) << 7)
+#define F_BCH_EN(x) (((x) & ((1 << 1) - 1)) << 11)
+#define F_SOURCE_PHY_MHDP_SEL(x) (((x) & ((1 << 2) - 1)) << 3)
+#define F_HPD_VALID_WIDTH(x) (((x) & ((1 << 12) - 1)) << 0)
+#define F_HPD_GLITCH_WIDTH(x) (((x) & ((1 << 8) - 1)) << 12)
+#define F_HDMI2_CTRL_IL_MODE(x) (((x) & ((1 << 1) - 1)) << 19)
+#define F_SOURCE_PHY_LANE0_SWAP(x) (((x) & ((1 << 2) - 1)) << 0)
+#define F_SOURCE_PHY_LANE1_SWAP(x) (((x) & ((1 << 2) - 1)) << 2)
+#define F_SOURCE_PHY_LANE2_SWAP(x) (((x) & ((1 << 2) - 1)) << 4)
+#define F_SOURCE_PHY_LANE3_SWAP(x) (((x) & ((1 << 2) - 1)) << 6)
+#define F_SOURCE_PHY_COMB_BYPASS(x) (((x) & ((1 << 1) - 1)) << 21)
+#define F_SOURCE_PHY_20_10(x) (((x) & ((1 << 1) - 1)) << 22)
+#define F_PKT_ALLOC_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_ACTIVE_IDLE_TYPE(x) (((x) & ((1 << 1) - 1)) << 17)
+#define F_FIFO1_FLUSH(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_PKT_ALLOC_WR_EN(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_DATA_WR(x) (x)
+#define F_WR_ADDR(x) (((x) & ((1 << 4) - 1)) << 0)
+#define F_HOST_WR(x) (((x) & ((1 << 1) - 1)) << 0)
+#define F_TYPE_VALID(x) (((x) & ((1 << 1) - 1)) << 16)
+#define F_PACKET_TYPE(x) (((x) & ((1 << 8) - 1)) << 8)
+
+/* Reference cycles when using lane clock as reference */
+#define LANE_REF_CYC			0x8000
+
+/* HPD Debounce */
+#define HOTPLUG_DEBOUNCE_MS		200
+
+/* HPD IRQ Index */
+#define IRQ_IN    0
+#define IRQ_OUT   1
+#define IRQ_NUM   2
+
+/* FW check alive timeout */
+#define CDNS_KEEP_ALIVE_TIMEOUT		2000
+#define CDNS_KEEP_ALIVE_MASK		GENMASK(7, 0)
+
+enum voltage_swing_level {
+	VOLTAGE_LEVEL_0,
+	VOLTAGE_LEVEL_1,
+	VOLTAGE_LEVEL_2,
+	VOLTAGE_LEVEL_3,
+};
+
+enum pre_emphasis_level {
+	PRE_EMPHASIS_LEVEL_0,
+	PRE_EMPHASIS_LEVEL_1,
+	PRE_EMPHASIS_LEVEL_2,
+	PRE_EMPHASIS_LEVEL_3,
+};
+
+enum pattern_set {
+	PTS1 = BIT(0),
+	PTS2 = BIT(1),
+	PTS3 = BIT(2),
+	PTS4 = BIT(3),
+	DP_NONE	= BIT(4)
+};
+
+enum vic_color_depth {
+	BCS_6 = 0x1,
+	BCS_8 = 0x2,
+	BCS_10 = 0x4,
+	BCS_12 = 0x8,
+	BCS_16 = 0x10,
+};
+
+enum vic_bt_type {
+	BT_601 = 0x0,
+	BT_709 = 0x1,
+};
+
+enum {
+	MODE_DVI,
+	MODE_HDMI_1_4,
+	MODE_HDMI_2_0,
+};
+
+struct video_info {
+	int bpc;
+	int color_fmt;
+};
+
+struct mhdp8501_plat_data {
+	int hdmi_lane_mapping;
+	int dp_lane_mapping;
+};
+
+struct cdns_mhdp8501_device {
+	struct cdns_mhdp_base base;
+
+	struct device *dev;
+	void __iomem *regs;
+	struct drm_connector *curr_conn;
+	struct drm_bridge bridge;
+	struct clk *apb_clk;
+	struct phy *phy;
+
+	struct video_info video_info;
+	struct drm_display_mode mode;
+
+	int irq[IRQ_NUM];
+	struct delayed_work hotplug_work;
+	int connector_type;
+	u32 lane_mapping;
+
+	/* protect mailbox communications with the firmware */
+	struct mutex mbox_mutex;
+
+	const struct mhdp8501_plat_data *plat_data;
+
+	union {
+		struct _dp_data {
+			u32 rate;
+			u8 num_lanes;
+			struct drm_dp_aux aux;
+			u8 dpcd[DP_RECEIVER_CAP_SIZE];
+		} dp;
+		struct _hdmi_data {
+			u32 hdmi_type;
+		} hdmi;
+	};
+};
+
+extern const struct drm_bridge_funcs cdns_dp_bridge_funcs;
+extern const struct drm_bridge_funcs cdns_hdmi_bridge_funcs;
+
+ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg);
+enum drm_connector_status cdns_mhdp8501_detect(struct cdns_mhdp8501_device *mhdp);
+int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp);
+
+#endif
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
new file mode 100644
index 0000000000000..d8cc31daf3228
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
@@ -0,0 +1,700 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence MHDP8501 DisplayPort(DP) bridge driver
+ *
+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-dp.h>
+
+#include "cdns-mhdp8501-core.h"
+
+#define LINK_TRAINING_TIMEOUT_MS	500
+#define LINK_TRAINING_RETRY_MS		20
+
+ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux,
+			     struct drm_dp_aux_msg *msg)
+{
+	struct cdns_mhdp8501_device *mhdp = dev_get_drvdata(aux->dev);
+	bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
+	int ret;
+
+	/* Ignore address only message */
+	if (!msg->size || !msg->buffer) {
+		msg->reply = native ?
+			DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
+		return msg->size;
+	}
+
+	if (!native) {
+		dev_err(mhdp->dev, "%s: only native messages supported\n", __func__);
+		return -EINVAL;
+	}
+
+	/* msg sanity check */
+	if (msg->size > DP_AUX_MAX_PAYLOAD_BYTES) {
+		dev_err(mhdp->dev, "%s: invalid msg: size(%zu), request(%x)\n",
+			__func__, msg->size, (unsigned int)msg->request);
+		return -EINVAL;
+	}
+
+	if (msg->request == DP_AUX_NATIVE_WRITE) {
+		const u8 *buf = msg->buffer;
+		int i;
+
+		for (i = 0; i < msg->size; ++i) {
+			ret = cdns_mhdp_dpcd_write(&mhdp->base,
+						   msg->address + i, buf[i]);
+			if (ret < 0) {
+				dev_err(mhdp->dev, "Failed to write DPCD\n");
+				return ret;
+			}
+		}
+		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+		return msg->size;
+	}
+
+	if (msg->request == DP_AUX_NATIVE_READ) {
+		ret = cdns_mhdp_dpcd_read(&mhdp->base, msg->address,
+					  msg->buffer, msg->size);
+		if (ret < 0)
+			return ret;
+		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+		return msg->size;
+	}
+	return 0;
+}
+
+int cdns_dp_aux_destroy(struct cdns_mhdp8501_device *mhdp)
+{
+	drm_dp_aux_unregister(&mhdp->dp.aux);
+
+	return 0;
+}
+
+static int cdns_dp_get_msa_misc(struct video_info *video)
+{
+	u32 msa_misc;
+	u8 color_space = 0;
+	u8 bpc = 0;
+
+	switch (video->color_fmt) {
+	/* set YUV default color space conversion to BT601 */
+	case DRM_COLOR_FORMAT_YCBCR444:
+		color_space = 6 + BT_601 * 8;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		color_space = 5 + BT_601 * 8;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		color_space = 5;
+		break;
+	case DRM_COLOR_FORMAT_RGB444:
+	default:
+		color_space = 0;
+		break;
+	};
+
+	switch (video->bpc) {
+	case 6:
+		bpc = 0;
+		break;
+	case 10:
+		bpc = 2;
+		break;
+	case 12:
+		bpc = 3;
+		break;
+	case 16:
+		bpc = 4;
+		break;
+	case 8:
+	default:
+		bpc = 1;
+		break;
+	};
+
+	msa_misc = (bpc << 5) | (color_space << 1);
+
+	return msa_misc;
+}
+
+static int cdns_dp_config_video(struct cdns_mhdp8501_device *mhdp)
+{
+	struct video_info *video = &mhdp->video_info;
+	struct drm_display_mode *mode = &mhdp->mode;
+	bool h_sync_polarity, v_sync_polarity;
+	u64 symbol;
+	u32 val, link_rate, rem;
+	u8 bit_per_pix, tu_size_reg = TU_SIZE;
+	int ret;
+
+	bit_per_pix = (video->color_fmt == DRM_COLOR_FORMAT_YCBCR422) ?
+		      (video->bpc * 2) : (video->bpc * 3);
+
+	link_rate = mhdp->dp.rate / 1000;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE);
+	if (ret)
+		goto err_config_video;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HSYNC2VSYNC_POL_CTRL, 0);
+	if (ret)
+		goto err_config_video;
+
+	/*
+	 * get a best tu_size and valid symbol:
+	 * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32
+	 * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes)
+	 * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set
+	 *    TU += 2 and repeat 2nd step.
+	 */
+	do {
+		tu_size_reg += 2;
+		symbol = tu_size_reg * mode->clock * bit_per_pix;
+		do_div(symbol, mhdp->dp.num_lanes * link_rate * 8);
+		rem = do_div(symbol, 1000);
+		if (tu_size_reg > 64) {
+			ret = -EINVAL;
+			dev_err(mhdp->dev, "tu error, clk:%d, lanes:%d, rate:%d\n",
+				mode->clock, mhdp->dp.num_lanes, link_rate);
+			goto err_config_video;
+		}
+	} while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
+		 (rem > 850) || (rem < 100));
+
+	val = symbol + (tu_size_reg << 8);
+	val |= TU_CNT_RST_EN;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_TU, val);
+	if (ret)
+		goto err_config_video;
+
+	/* set the FIFO Buffer size */
+	val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
+	val /= (mhdp->dp.num_lanes * link_rate);
+	val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
+	val += 2;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_VC_TABLE(15), val);
+
+	switch (video->bpc) {
+	case 6:
+		val = BCS_6;
+		break;
+	case 10:
+		val = BCS_10;
+		break;
+	case 12:
+		val = BCS_12;
+		break;
+	case 16:
+		val = BCS_16;
+		break;
+	case 8:
+	default:
+		val = BCS_8;
+		break;
+	};
+
+	val += video->color_fmt << 8;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_PXL_REPR, val);
+	if (ret)
+		goto err_config_video;
+
+	v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+	h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+
+	val = h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
+	val |= v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRAMER_SP, val);
+	if (ret)
+		goto err_config_video;
+
+	val = (mode->hsync_start - mode->hdisplay) << 16;
+	val |= mode->htotal - mode->hsync_end;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_FRONT_BACK_PORCH, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->hdisplay * bit_per_pix / 8;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_BYTE_COUNT, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_HORIZONTAL_0, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->hsync_end - mode->hsync_start;
+	val |= (mode->hdisplay << 16) | (h_sync_polarity << 15);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_HORIZONTAL_1, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vtotal;
+	val |= (mode->vtotal - mode->vsync_start) << 16;
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_VERTICAL_0, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vsync_end - mode->vsync_start;
+	val |= (mode->vdisplay << 16) | (v_sync_polarity << 15);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_VERTICAL_1, val);
+	if (ret)
+		goto err_config_video;
+
+	val = cdns_dp_get_msa_misc(video);
+	ret = cdns_mhdp_reg_write(&mhdp->base, MSA_MISC, val);
+	if (ret)
+		goto err_config_video;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, STREAM_CONFIG, 1);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->hsync_end - mode->hsync_start;
+	val |= mode->hdisplay << 16;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_HORIZONTAL, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vdisplay;
+	val |= (mode->vtotal - mode->vsync_start) << 16;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_VERTICAL_0, val);
+	if (ret)
+		goto err_config_video;
+
+	val = mode->vtotal;
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_VERTICAL_1, val);
+	if (ret)
+		goto err_config_video;
+
+	ret = cdns_mhdp_dp_reg_write_bit(&mhdp->base, DP_VB_ID, 2, 1, 0);
+
+err_config_video:
+	if (ret)
+		dev_err(mhdp->dev, "config video failed: %d\n", ret);
+	return ret;
+}
+
+static void cdns_dp_pixel_clk_reset(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 val;
+
+	/* reset pixel clk */
+	cdns_mhdp_reg_read(&mhdp->base, SOURCE_HDTX_CAR, &val);
+	cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, val & 0xFD);
+	cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, val);
+}
+
+static int cdns_dp_set_video_status(struct cdns_mhdp8501_device *mhdp, int active)
+{
+	u8 msg;
+	int ret;
+
+	msg = !!active;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
+				     sizeof(msg), &msg);
+	if (ret)
+		dev_err(mhdp->dev, "set video status failed: %d\n", ret);
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	return ret;
+}
+
+static int cdns_dp_training_start(struct cdns_mhdp8501_device *mhdp)
+{
+	unsigned long timeout;
+	u8 msg, event[2];
+	int ret;
+
+	msg = LINK_TRAINING_RUN;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	/* start training */
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_TRAINING_CONTROL, sizeof(msg), &msg);
+	if (ret)
+		goto err_training_start;
+
+	timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
+	while (time_before(jiffies, timeout)) {
+		msleep(LINK_TRAINING_RETRY_MS);
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+					     DPTX_READ_EVENT, 0, NULL);
+		if (ret)
+			goto err_training_start;
+
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
+						    DPTX_READ_EVENT, sizeof(event));
+		if (ret)
+			goto err_training_start;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, event, sizeof(event));
+		if (ret)
+			goto err_training_start;
+
+		if (event[1] & CLK_RECOVERY_FAILED) {
+			dev_err(mhdp->dev, "clock recovery failed\n");
+		} else if (event[1] & EQ_PHASE_FINISHED) {
+			mutex_unlock(&mhdp->mbox_mutex);
+			return 0;
+		}
+	}
+
+	ret = -ETIMEDOUT;
+
+err_training_start:
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	dev_err(mhdp->dev, "training failed: %d\n", ret);
+	return ret;
+}
+
+static int cdns_dp_get_training_status(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 status[13];
+	int ret;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_READ_LINK_STAT, 0, NULL);
+	if (ret)
+		goto err_get_training_status;
+
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
+					    DPTX_READ_LINK_STAT,
+					    sizeof(status));
+	if (ret)
+		goto err_get_training_status;
+
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, status, sizeof(status));
+	if (ret)
+		goto err_get_training_status;
+
+	mhdp->dp.rate = drm_dp_bw_code_to_link_rate(status[0]);
+	mhdp->dp.num_lanes = status[1];
+
+err_get_training_status:
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "get training status failed: %d\n", ret);
+	return ret;
+}
+
+static int cdns_dp_train_link(struct cdns_mhdp8501_device *mhdp)
+{
+	int ret;
+
+	ret = cdns_dp_training_start(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to start training %d\n", ret);
+		return ret;
+	}
+
+	ret = cdns_dp_get_training_status(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to get training stat %d\n", ret);
+		return ret;
+	}
+
+	dev_dbg(mhdp->dev, "rate:0x%x, lanes:%d\n", mhdp->dp.rate,
+		mhdp->dp.num_lanes);
+	return ret;
+}
+
+static int cdns_dp_set_host_cap(struct cdns_mhdp8501_device *mhdp)
+{
+	u8 msg[8];
+	int ret;
+
+	msg[0] = drm_dp_link_rate_to_bw_code(mhdp->dp.rate);
+	msg[1] = mhdp->dp.num_lanes | SCRAMBLER_EN;
+	msg[2] = VOLTAGE_LEVEL_2;
+	msg[3] = PRE_EMPHASIS_LEVEL_3;
+	msg[4] = PTS1 | PTS2 | PTS3 | PTS4;
+	msg[5] = FAST_LT_NOT_SUPPORT;
+	msg[6] = mhdp->lane_mapping;
+	msg[7] = ENHANCED;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+				     DPTX_SET_HOST_CAPABILITIES,
+				     sizeof(msg), msg);
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "set host cap failed: %d\n", ret);
+
+	return ret;
+}
+
+static int cdns_dp_get_edid_block(void *data, u8 *edid,
+				  unsigned int block, size_t length)
+{
+	struct cdns_mhdp8501_device *mhdp = data;
+	u8 msg[2], reg[2], i;
+	int ret;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	for (i = 0; i < 4; i++) {
+		msg[0] = block / 2;
+		msg[1] = block % 2;
+
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_DP_TX,
+					     DPTX_GET_EDID, sizeof(msg), msg);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_DP_TX,
+						    DPTX_GET_EDID,
+						    sizeof(reg) + length);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid, length);
+		if (ret)
+			continue;
+
+		if (reg[0] == length && reg[1] == block / 2)
+			break;
+	}
+
+	if (ret)
+		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", block, ret);
+
+	mutex_unlock(&mhdp->mbox_mutex);
+	return ret;
+}
+
+static void cdns_dp_mode_set(struct cdns_mhdp8501_device *mhdp)
+{
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	cdns_dp_pixel_clk_reset(mhdp);
+
+	/* Get DP Caps  */
+	ret = drm_dp_dpcd_read(&mhdp->dp.aux, DP_DPCD_REV, mhdp->dp.dpcd,
+			       DP_RECEIVER_CAP_SIZE);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "Failed to get caps %d\n", ret);
+		return;
+	}
+
+	mhdp->dp.rate = drm_dp_max_link_rate(mhdp->dp.dpcd);
+	mhdp->dp.num_lanes = drm_dp_max_lane_count(mhdp->dp.dpcd);
+
+	/* check the max link rate */
+	if (mhdp->dp.rate > CDNS_DP_MAX_LINK_RATE)
+		mhdp->dp.rate = CDNS_DP_MAX_LINK_RATE;
+
+	phy_cfg.dp.lanes = mhdp->dp.num_lanes;
+	phy_cfg.dp.link_rate = mhdp->dp.rate;
+	phy_cfg.dp.set_lanes = false;
+	phy_cfg.dp.set_rate = false;
+	phy_cfg.dp.set_voltages = true;
+
+	/* Mailbox protect for DP PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	ret = phy_configure(mhdp->phy, &phy_cfg);
+	mutex_unlock(&mhdp->mbox_mutex);
+	if (ret) {
+		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+			__func__, ret);
+		return;
+	}
+
+	/* Video off */
+	ret = cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_IDLE);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to valid video %d\n", ret);
+		return;
+	}
+
+	/* Line swapping */
+	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
+
+	/* Set DP host capability */
+	ret = cdns_dp_set_host_cap(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to set host cap %d\n", ret);
+		return;
+	}
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, DP_AUX_SWAP_INVERSION_CONTROL,
+				  AUX_HOST_INVERT);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to set host invert %d\n", ret);
+		return;
+	}
+
+	ret = cdns_dp_config_video(mhdp);
+	if (ret)
+		dev_err(mhdp->dev, "Failed to config video %d\n", ret);
+}
+
+static int cdns_dp_bridge_attach(struct drm_bridge *bridge,
+				 enum drm_bridge_attach_flags flags)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mhdp->dev, "do not support creating a drm_connector\n");
+		return -EINVAL;
+	}
+
+	mhdp->dp.aux.drm_dev = bridge->dev;
+
+	return drm_dp_aux_register(&mhdp->dp.aux);
+}
+
+static enum drm_mode_status
+cdns_dp_bridge_mode_valid(struct drm_bridge *bridge,
+			  const struct drm_display_info *info,
+			  const struct drm_display_mode *mode)
+{
+	enum drm_mode_status mode_status = MODE_OK;
+
+	/* We don't support double-clocked modes */
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
+	    mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_BAD;
+
+	/* MAX support pixel clock rate 594MHz */
+	if (mode->clock > 594000)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->hdisplay > 3840)
+		return MODE_BAD_HVALUE;
+
+	if (mode->vdisplay > 2160)
+		return MODE_BAD_VVALUE;
+
+	return mode_status;
+}
+
+static enum drm_connector_status
+cdns_dp_bridge_detect(struct drm_bridge *bridge)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return cdns_mhdp8501_detect(mhdp);
+}
+
+static const struct drm_edid
+*cdns_dp_bridge_edid_read(struct drm_bridge *bridge,
+			  struct drm_connector *connector)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return drm_edid_read_custom(connector, cdns_dp_get_edid_block, mhdp);
+}
+
+static void cdns_dp_bridge_atomic_disable(struct drm_bridge *bridge,
+					  struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_IDLE);
+	mhdp->curr_conn = NULL;
+
+	/* Mailbox protect for DP PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	phy_power_off(mhdp->phy);
+	mutex_unlock(&mhdp->mbox_mutex);
+}
+
+static void cdns_dp_bridge_atomic_enable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	struct drm_atomic_state *state = old_state->base.state;
+	struct drm_connector *connector;
+	struct video_info *video = &mhdp->video_info;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector_state *conn_state;
+	const struct drm_display_mode *mode;
+	int ret;
+
+	connector = drm_atomic_get_new_connector_for_encoder(state,
+							     bridge->encoder);
+	if (WARN_ON(!connector))
+		return;
+
+	mhdp->curr_conn = connector;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (WARN_ON(!conn_state))
+		return;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return;
+
+	mode = &crtc_state->adjusted_mode;
+
+	switch (connector->display_info.bpc) {
+	case 10:
+		video->bpc = 10;
+		break;
+	case 6:
+		video->bpc = 6;
+		break;
+	default:
+		video->bpc = 8;
+		break;
+	}
+
+	/* The only currently supported format */
+	video->color_fmt = DRM_COLOR_FORMAT_RGB444;
+
+	dev_dbg(mhdp->dev, "Mode: %dx%dp%d\n",
+		mode->hdisplay, mode->vdisplay, mode->clock);
+	memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
+
+	cdns_dp_mode_set(mhdp);
+
+	/* Link trainning */
+	ret = cdns_dp_train_link(mhdp);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed link train %d\n", ret);
+		return;
+	}
+
+	ret = cdns_dp_set_video_status(mhdp, CONTROL_VIDEO_VALID);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to valid video %d\n", ret);
+		return;
+	}
+}
+
+const struct drm_bridge_funcs cdns_dp_bridge_funcs = {
+	.attach = cdns_dp_bridge_attach,
+	.detect = cdns_dp_bridge_detect,
+	.edid_read = cdns_dp_bridge_edid_read,
+	.mode_valid = cdns_dp_bridge_mode_valid,
+	.atomic_enable = cdns_dp_bridge_atomic_enable,
+	.atomic_disable = cdns_dp_bridge_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,
+};
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
new file mode 100644
index 0000000000000..2fe899d015b14
--- /dev/null
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
@@ -0,0 +1,680 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence MHDP8501 HDMI bridge driver
+ *
+ * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
+ *
+ */
+#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_scdc_helper.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-hdmi.h>
+
+#include "cdns-mhdp8501-core.h"
+
+/**
+ * cdns_hdmi_infoframe_set() - fill the HDMI AVI infoframe
+ * @mhdp: phandle to mhdp device.
+ * @entry_id: The packet memory address in which the data is written.
+ * @packet_len: 32, only 32 bytes now.
+ * @packet: point to InfoFrame Packet.
+ *          packet[0] = 0
+ *          packet[1-3] = HB[0-2]  InfoFrame Packet Header
+ *          packet[4-31 = PB[0-27] InfoFrame Packet Contents
+ * @packet_type: Packet Type of InfoFrame in HDMI Specification.
+ *
+ */
+static void cdns_hdmi_infoframe_set(struct cdns_mhdp8501_device *mhdp,
+				    u8 entry_id, u8 packet_len,
+				    u8 *packet, u8 packet_type)
+{
+	u32 packet32, len32;
+	u32 val, i;
+
+	/* only support 32 bytes now */
+	if (packet_len != 32)
+		return;
+
+	/* invalidate entry */
+	val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id);
+	writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+	writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + SOURCE_PIF_PKT_ALLOC_WR_EN);
+
+	/* flush fifo 1 */
+	writel(F_FIFO1_FLUSH(1), mhdp->regs + SOURCE_PIF_FIFO1_FLUSH);
+
+	/* write packet into memory */
+	len32 = packet_len / 4;
+	for (i = 0; i < len32; i++) {
+		packet32 = get_unaligned_le32(packet + 4 * i);
+		writel(F_DATA_WR(packet32), mhdp->regs + SOURCE_PIF_DATA_WR);
+	}
+
+	/* write entry id */
+	writel(F_WR_ADDR(entry_id), mhdp->regs + SOURCE_PIF_WR_ADDR);
+
+	/* write request */
+	writel(F_HOST_WR(1), mhdp->regs + SOURCE_PIF_WR_REQ);
+
+	/* update entry */
+	val = F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) |
+		F_PACKET_TYPE(packet_type) | F_PKT_ALLOC_ADDRESS(entry_id);
+	writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+
+	writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + SOURCE_PIF_PKT_ALLOC_WR_EN);
+}
+
+static int cdns_hdmi_get_edid_block(void *data, u8 *edid,
+				    u32 block, size_t length)
+{
+	struct cdns_mhdp8501_device *mhdp = data;
+	u8 msg[2], reg[5], i;
+	int ret;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	for (i = 0; i < 4; i++) {
+		msg[0] = block / 2;
+		msg[1] = block % 2;
+
+		ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_HDMI_TX, HDMI_TX_EDID,
+					     sizeof(msg), msg);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_HDMI_TX,
+						    HDMI_TX_EDID, sizeof(reg) + length);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, edid, length);
+		if (ret)
+			continue;
+
+		if ((reg[3] << 8 | reg[4]) == length)
+			break;
+	}
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "get block[%d] edid failed: %d\n", block, ret);
+	return ret;
+}
+
+static int cdns_hdmi_scdc_write(struct cdns_mhdp8501_device *mhdp, u8 addr, u8 value)
+{
+	u8 msg[5], reg[5];
+	int ret;
+
+	msg[0] = 0x54;
+	msg[1] = addr;
+	msg[2] = 0;
+	msg[3] = 1;
+	msg[4] = value;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(&mhdp->base, MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
+				     sizeof(msg), msg);
+	if (ret)
+		goto err_scdc_write;
+
+	ret = cdns_mhdp_mailbox_recv_header(&mhdp->base, MB_MODULE_ID_HDMI_TX,
+					    HDMI_TX_WRITE, sizeof(reg));
+	if (ret)
+		goto err_scdc_write;
+
+	ret = cdns_mhdp_mailbox_recv_data(&mhdp->base, reg, sizeof(reg));
+	if (ret)
+		goto err_scdc_write;
+
+	if (reg[0] != 0)
+		ret = -EINVAL;
+
+err_scdc_write:
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		dev_err(mhdp->dev, "scdc write failed: %d\n", ret);
+	return ret;
+}
+
+static int cdns_hdmi_ctrl_init(struct cdns_mhdp8501_device *mhdp, int protocol)
+{
+	u32 reg0, reg1, val;
+	int ret;
+
+	/* Set PHY to HDMI data */
+	ret = cdns_mhdp_reg_write(&mhdp->base, PHY_DATA_SEL, F_SOURCE_PHY_MHDP_SEL(1));
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_HPD,
+				  F_HPD_VALID_WIDTH(4) | F_HPD_GLITCH_WIDTH(0));
+	if (ret < 0)
+		return ret;
+
+	/* open CARS */
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_PHY_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_HDTX_CAR, 0xFF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_PKT_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_AIF_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CIPHER_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CRYPTO_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, SOURCE_CEC_CAR, 3);
+	if (ret < 0)
+		return ret;
+
+	reg0 = 0x7c1f;
+	reg1 = 0x7c1f;
+	if (protocol == MODE_HDMI_2_0) {
+		reg0 = 0;
+		reg1 = 0xFFFFF;
+	}
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_0, reg0);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CLOCK_REG_1, reg1);
+	if (ret < 0)
+		return ret;
+
+	/* set HDMI mode and preemble mode data enable */
+	val = F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) |  F_DATA_EN(1) |
+			F_HDMI2_CTRL_IL_MODE(1) | F_BCH_EN(1) | F_PIC_3D(0XF);
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+
+	return ret;
+}
+
+static int cdns_hdmi_mode_config(struct cdns_mhdp8501_device *mhdp,
+				 struct drm_display_mode *mode,
+				 struct video_info *video_info)
+{
+	int ret;
+	u32 val;
+	u32 vsync_lines = mode->vsync_end - mode->vsync_start;
+	u32 eof_lines = mode->vsync_start - mode->vdisplay;
+	u32 sof_lines = mode->vtotal - mode->vsync_end;
+	u32 hblank = mode->htotal - mode->hdisplay;
+	u32 hactive = mode->hdisplay;
+	u32 vblank = mode->vtotal - mode->vdisplay;
+	u32 vactive = mode->vdisplay;
+	u32 hfront = mode->hsync_start - mode->hdisplay;
+	u32 hback = mode->htotal - mode->hsync_end;
+	u32 vfront = eof_lines;
+	u32 hsync = hblank - hfront - hback;
+	u32 vsync = vsync_lines;
+	u32 vback = sof_lines;
+	u32 v_h_polarity = ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1) +
+			((mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : 2);
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, SCHEDULER_H_SIZE, (hactive << 16) + hblank);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, SCHEDULER_V_SIZE, (vactive << 16) + vblank);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_FRONT_WIDTH, (vfront << 16) + hfront);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_SYNC_WIDTH, (vsync << 16) + hsync);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_SIGNAL_BACK_WIDTH, (vback << 16) + hback);
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HSYNC2VSYNC_POL_CTRL, v_h_polarity);
+	if (ret < 0)
+		return ret;
+
+	/* Reset Data Enable */
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+	val &= ~F_DATA_EN(1);
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+	if (ret < 0)
+		return ret;
+
+	/* Set bpc */
+	val &= ~F_VIF_DATA_WIDTH(3);
+	switch (video_info->bpc) {
+	case 10:
+		val |= F_VIF_DATA_WIDTH(1);
+		break;
+	case 12:
+		val |= F_VIF_DATA_WIDTH(2);
+		break;
+	case 16:
+		val |= F_VIF_DATA_WIDTH(3);
+		break;
+	case 8:
+	default:
+		val |= F_VIF_DATA_WIDTH(0);
+		break;
+	}
+
+	/* select color encoding */
+	val &= ~F_HDMI_ENCODING(3);
+	switch (video_info->color_fmt) {
+	case DRM_COLOR_FORMAT_YCBCR444:
+		val |= F_HDMI_ENCODING(2);
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		val |= F_HDMI_ENCODING(1);
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		val |= F_HDMI_ENCODING(3);
+		break;
+	case DRM_COLOR_FORMAT_RGB444:
+	default:
+		val |= F_HDMI_ENCODING(0);
+		break;
+	}
+
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+	if (ret < 0)
+		return ret;
+
+	/* set data enable */
+	val |= F_DATA_EN(1);
+	ret = cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+
+	return ret;
+}
+
+static int cdns_hdmi_disable_gcp(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 val;
+
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+	val &= ~F_GCP_EN(1);
+
+	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+}
+
+static int cdns_hdmi_enable_gcp(struct cdns_mhdp8501_device *mhdp)
+{
+	u32 val;
+
+	cdns_mhdp_reg_read(&mhdp->base, HDTX_CONTROLLER, &val);
+	val |= F_GCP_EN(1);
+
+	return cdns_mhdp_reg_write(&mhdp->base, HDTX_CONTROLLER, val);
+}
+
+static void cdns_hdmi_sink_config(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_scdc *scdc = &mhdp->curr_conn->display_info.hdmi.scdc;
+	u32 char_rate = mhdp->mode.clock * mhdp->video_info.bpc / 8;
+	u8 buff = 0;
+
+	/* Default work in HDMI1.4 */
+	mhdp->hdmi.hdmi_type = MODE_HDMI_1_4;
+
+	/* check sink support SCDC or not */
+	if (!scdc->supported) {
+		dev_info(mhdp->dev, "Sink Not Support SCDC\n");
+		return;
+	}
+
+	if (char_rate > 340000) {
+		/*
+		 * TMDS Character Rate above 340MHz should working in HDMI2.0
+		 * Enable scrambling and TMDS_Bit_Clock_Ratio
+		 */
+		buff = SCDC_TMDS_BIT_CLOCK_RATIO_BY_40 | SCDC_SCRAMBLING_ENABLE;
+		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+	} else if (scdc->scrambling.low_rates) {
+		/*
+		 * Enable scrambling and HDMI2.0 when scrambling capability of sink
+		 * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit
+		 */
+		buff = SCDC_SCRAMBLING_ENABLE;
+		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+	}
+
+	/* TMDS config */
+	cdns_hdmi_scdc_write(mhdp, SCDC_TMDS_CONFIG, buff);
+}
+
+static void cdns_hdmi_lanes_config(struct cdns_mhdp8501_device *mhdp)
+{
+	/* Line swapping */
+	cdns_mhdp_reg_write(&mhdp->base, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
+}
+
+static int cdns_hdmi_colorspace(int color_fmt)
+{
+	int color_space;
+
+	switch (color_fmt) {
+	case DRM_COLOR_FORMAT_YCBCR444:
+		color_space = HDMI_COLORSPACE_YUV444;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		color_space = HDMI_COLORSPACE_YUV422;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		color_space = HDMI_COLORSPACE_YUV420;
+		break;
+	case DRM_COLOR_FORMAT_RGB444:
+	default:
+		color_space = HDMI_COLORSPACE_RGB;
+		break;
+	}
+
+	return color_space;
+}
+
+static int cdns_hdmi_avi_info_set(struct cdns_mhdp8501_device *mhdp,
+				  struct drm_display_mode *mode)
+{
+	struct hdmi_avi_infoframe frame;
+	struct drm_connector_state *conn_state = mhdp->curr_conn->state;
+	struct drm_display_mode *adj_mode;
+	enum hdmi_quantization_range qr;
+	u8 buf[32];
+	int ret;
+
+	/* Initialise info frame from DRM mode */
+	drm_hdmi_avi_infoframe_from_display_mode(&frame, mhdp->curr_conn, mode);
+
+	frame.colorspace = cdns_hdmi_colorspace(mhdp->video_info.color_fmt);
+
+	drm_hdmi_avi_infoframe_colorimetry(&frame, conn_state);
+
+	adj_mode = &mhdp->bridge.encoder->crtc->state->adjusted_mode;
+
+	qr = drm_default_rgb_quant_range(adj_mode);
+
+	drm_hdmi_avi_infoframe_quant_range(&frame, mhdp->curr_conn,
+					   adj_mode, qr);
+
+	ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "failed to pack AVI infoframe: %d\n", ret);
+		return -1;
+	}
+
+	buf[0] = 0;
+	cdns_hdmi_infoframe_set(mhdp, 0, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_AVI);
+
+	return 0;
+}
+
+static void cdns_hdmi_vendor_info_set(struct cdns_mhdp8501_device *mhdp,
+				      struct drm_display_mode *mode)
+{
+	struct hdmi_vendor_infoframe frame;
+	u8 buf[32];
+	int ret;
+
+	/* Initialise vendor frame from DRM mode */
+	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mhdp->curr_conn, mode);
+	if (ret < 0) {
+		dev_info(mhdp->dev, "No vendor infoframe\n");
+		return;
+	}
+
+	ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+	if (ret < 0) {
+		dev_warn(mhdp->dev, "Unable to pack vendor infoframe: %d\n", ret);
+		return;
+	}
+
+	buf[0] = 0;
+	cdns_hdmi_infoframe_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_VENDOR);
+}
+
+static void cdns_hdmi_drm_info_set(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_connector_state *conn_state;
+	struct hdmi_drm_infoframe frame;
+	u8 buf[32];
+	int ret;
+
+	conn_state = mhdp->curr_conn->state;
+
+	if (!conn_state->hdr_output_metadata)
+		return;
+
+	ret = drm_hdmi_infoframe_set_hdr_metadata(&frame, conn_state);
+	if (ret < 0) {
+		dev_dbg(mhdp->dev, "couldn't set HDR metadata in infoframe\n");
+		return;
+	}
+
+	ret = hdmi_drm_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+	if (ret < 0) {
+		dev_dbg(mhdp->dev, "couldn't pack HDR infoframe\n");
+		return;
+	}
+
+	buf[0] = 0;
+	cdns_hdmi_infoframe_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_DRM);
+}
+
+static void cdns_hdmi_mode_set(struct cdns_mhdp8501_device *mhdp)
+{
+	struct drm_display_mode *mode = &mhdp->mode;
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	/* video mode check */
+	if (mode->clock == 0 || mode->hdisplay == 0 || mode->vdisplay == 0)
+		return;
+
+	cdns_hdmi_lanes_config(mhdp);
+
+	phy_cfg.hdmi.pixel_clk_rate = mode->clock;
+	phy_cfg.hdmi.bpc = mhdp->video_info.bpc;
+	phy_cfg.hdmi.color_space = cdns_hdmi_colorspace(mhdp->video_info.color_fmt);
+
+	/* Mailbox protect for HDMI PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	ret = phy_configure(mhdp->phy, &phy_cfg);
+	mutex_unlock(&mhdp->mbox_mutex);
+	if (ret) {
+		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+			__func__, ret);
+		return;
+	}
+
+	cdns_hdmi_sink_config(mhdp);
+
+	ret = cdns_hdmi_ctrl_init(mhdp, mhdp->hdmi.hdmi_type);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "%s, ret = %d\n", __func__, ret);
+		return;
+	}
+
+	/* Config GCP */
+	if (mhdp->video_info.bpc == 8)
+		cdns_hdmi_disable_gcp(mhdp);
+	else
+		cdns_hdmi_enable_gcp(mhdp);
+
+	ret = cdns_hdmi_avi_info_set(mhdp, mode);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "%s ret = %d\n", __func__, ret);
+		return;
+	}
+
+	/* vendor info frame is enabled only for HDMI1.4 4K mode */
+	cdns_hdmi_vendor_info_set(mhdp, mode);
+
+	cdns_hdmi_drm_info_set(mhdp);
+
+	ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info);
+	if (ret < 0) {
+		dev_err(mhdp->dev, "CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
+		return;
+	}
+}
+
+static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge,
+				   enum drm_bridge_attach_flags flags)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		dev_err(mhdp->dev, "do not support creating a drm_connector\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum drm_mode_status
+cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
+			    const struct drm_display_info *info,
+			    const struct drm_display_mode *mode)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	enum drm_mode_status mode_status = MODE_OK;
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	/* We don't support double-clocked and Interlaced modes */
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
+	    mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_BAD;
+
+	/* MAX support pixel clock rate 594MHz */
+	if (mode->clock > 594000)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->hdisplay > 3840)
+		return MODE_BAD_HVALUE;
+
+	if (mode->vdisplay > 2160)
+		return MODE_BAD_VVALUE;
+
+	/* Check modes supported by PHY */
+	phy_cfg.hdmi.pixel_clk_rate = mode->clock;
+
+	/* Mailbox protect for HDMI PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
+	mutex_unlock(&mhdp->mbox_mutex);
+	if (ret < 0)
+		return MODE_CLOCK_RANGE;
+
+	return mode_status;
+}
+
+static bool
+cdns_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+			    const struct drm_display_mode *mode,
+			    struct drm_display_mode *adjusted_mode)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	struct video_info *video = &mhdp->video_info;
+
+	/* The only currently supported format */
+	video->bpc = 8;
+	video->color_fmt = DRM_COLOR_FORMAT_RGB444;
+
+	return true;
+}
+
+static enum drm_connector_status
+cdns_hdmi_bridge_detect(struct drm_bridge *bridge)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return cdns_mhdp8501_detect(mhdp);
+}
+
+static const struct drm_edid
+*cdns_hdmi_bridge_edid_read(struct drm_bridge *bridge,
+			    struct drm_connector *connector)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	return drm_edid_read_custom(connector, cdns_hdmi_get_edid_block, mhdp);
+}
+
+static void cdns_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+
+	mhdp->curr_conn = NULL;
+
+	/* Mailbox protect for HDMI PHY access */
+	mutex_lock(&mhdp->mbox_mutex);
+	phy_power_off(mhdp->phy);
+	mutex_unlock(&mhdp->mbox_mutex);
+}
+
+static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
+					   struct drm_bridge_state *old_state)
+{
+	struct cdns_mhdp8501_device *mhdp = bridge->driver_private;
+	struct drm_atomic_state *state = old_state->base.state;
+	struct drm_connector *connector;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector_state *conn_state;
+	const struct drm_display_mode *mode;
+
+	connector = drm_atomic_get_new_connector_for_encoder(state,
+							     bridge->encoder);
+	if (WARN_ON(!connector))
+		return;
+
+	mhdp->curr_conn = connector;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (WARN_ON(!conn_state))
+		return;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return;
+
+	mode = &crtc_state->adjusted_mode;
+	dev_dbg(mhdp->dev, "Mode: %dx%dp%d\n",
+		mode->hdisplay, mode->vdisplay, mode->clock);
+	memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
+
+	cdns_hdmi_mode_set(mhdp);
+}
+
+const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
+	.attach = cdns_hdmi_bridge_attach,
+	.detect = cdns_hdmi_bridge_detect,
+	.edid_read = cdns_hdmi_bridge_edid_read,
+	.mode_valid = cdns_hdmi_bridge_mode_valid,
+	.mode_fixup = cdns_hdmi_bridge_mode_fixup,
+	.atomic_enable = cdns_hdmi_bridge_atomic_enable,
+	.atomic_disable = cdns_hdmi_bridge_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,
+};
-- 
2.34.1



From anshuman.khandual at arm.com  Mon Feb 19 19:48:29 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 20 Feb 2024 09:18:29 +0530
Subject: [PATCH V2] arm64/sysreg: Update ID_AA64DFR0_EL1 register
Message-ID: <20240220034829.3098373-1-anshuman.khandual@arm.com>

This updates ID_AA64DFR0_EL1.PMSVer and ID_AA64DFR0_EL1.DebugVer register
fields as per the definitions based on DDI0601 2023-12.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Brown <broonie 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>
---
This applies on v6.8-rc5

Changes in V2:

- Split ID_AA64DFR0_EL1 changes in this patch and updated PMSVer per Mark

Changes in V1:

https://lore.kernel.org/all/20240215055159.2440898-1-anshuman.khandual at arm.com/

 arch/arm64/tools/sysreg | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index a9cab2b730a3..508224a0e078 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1223,6 +1223,7 @@ UnsignedEnum	35:32	PMSVer
 	0b0010	V1P1
 	0b0011	V1P2
 	0b0100	V1P3
+	0b0101	V1P4
 EndEnum
 Field	31:28	CTX_CMPs
 Res0	27:24
@@ -1249,6 +1250,7 @@ UnsignedEnum	3:0	DebugVer
 	0b1000	V8P2
 	0b1001	V8P4
 	0b1010	V8P8
+	0b1011	V8P9
 EndEnum
 EndSysreg
 
-- 
2.25.1



From dongmenglong.8 at bytedance.com  Mon Feb 19 19:51:00 2024
From: dongmenglong.8 at bytedance.com (Menglong Dong)
Date: Tue, 20 Feb 2024 11:51:00 +0800
Subject: [PATCH bpf-next 0/5] bpf: make tracing program support multi-attach
Message-ID: <20240220035105.34626-1-dongmenglong.8@bytedance.com>

For now, the BPF program of type BPF_PROG_TYPE_TRACING is not allowed to
be attached to multiple hooks, and we have to create a BPF program for
each kernel function, for which we want to trace, even through all the
program have the same (or similar) logic. This can consume extra memory,
and make the program loading slow if we have plenty of kernel function to
trace.

In the commit 4a1e7c0c63e0 ("bpf: Support attaching freplace programs to
multiple attach points"), the freplace BPF program is made to support
attach to multiple attach points. And in this series, we extend it to
fentry/fexit/raw_tp/...

In the 1st patch, we add the support to record index of the accessed
function args of the target for tracing program. Meanwhile, we add the
function btf_check_func_part_match() to compare the accessed function args
of two function prototype. This function will be used in the next commit.

In the 2nd patch, we do some adjust to bpf_tracing_prog_attach() to make
it support multiple attaching.

In the 3rd patch, we allow to set bpf cookie in bpf_link_create() even if
target_btf_id is set, as we are allowed to attach the tracing program to
new target.

In the 4th patch, we introduce the function libbpf_find_kernel_btf_id() to
libbpf to find the btf type id of the kernel function, and this function
will be used in the next commit.

In the 5th patch, we add the testcases for this series.

Menglong Dong (5):
  bpf: tracing: add support to record and check the accessed args
  bpf: tracing: support to attach program to multi hooks
  libbpf: allow to set coookie when target_btf_id is set in
    bpf_link_create
  libbpf: add the function libbpf_find_kernel_btf_id()
  selftests/bpf: add test cases for multiple attach of tracing program

 include/linux/bpf.h                           |   6 +
 include/uapi/linux/bpf.h                      |   1 +
 kernel/bpf/btf.c                              | 121 ++++++++++++++
 kernel/bpf/syscall.c                          | 118 +++++++++++---
 tools/lib/bpf/bpf.c                           |  17 +-
 tools/lib/bpf/libbpf.c                        |  83 ++++++++++
 tools/lib/bpf/libbpf.h                        |   3 +
 tools/lib/bpf/libbpf.map                      |   1 +
 .../selftests/bpf/bpf_testmod/bpf_testmod.c   |  49 ++++++
 .../bpf/prog_tests/tracing_multi_attach.c     | 153 ++++++++++++++++++
 .../selftests/bpf/progs/tracing_multi_test.c  |  66 ++++++++
 11 files changed, 583 insertions(+), 35 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/tracing_multi_attach.c
 create mode 100644 tools/testing/selftests/bpf/progs/tracing_multi_test.c

-- 
2.39.2



From dongmenglong.8 at bytedance.com  Mon Feb 19 19:51:01 2024
From: dongmenglong.8 at bytedance.com (Menglong Dong)
Date: Tue, 20 Feb 2024 11:51:01 +0800
Subject: [PATCH bpf-next 1/5] bpf: tracing: add support to record and check the accessed args
In-Reply-To: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
Message-ID: <20240220035105.34626-2-dongmenglong.8@bytedance.com>

In this commit, we add the 'accessed_args' field to struct bpf_prog_aux,
which is used to record the accessed index of the function args in
btf_ctx_access().

Meanwhile, we add the function btf_check_func_part_match() to compare the
accessed function args of two function prototype. This function will be
used in the following commit.

Signed-off-by: Menglong Dong <dongmenglong.8 at bytedance.com>
---
 include/linux/bpf.h |   4 ++
 kernel/bpf/btf.c    | 121 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 125 insertions(+)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index c7aa99b44dbd..0225b8dbdd9d 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1464,6 +1464,7 @@ struct bpf_prog_aux {
 	const struct btf_type *attach_func_proto;
 	/* function name for valid attach_btf_id */
 	const char *attach_func_name;
+	u64 accessed_args;
 	struct bpf_prog **func;
 	void *jit_data; /* JIT specific data. arch dependent */
 	struct bpf_jit_poke_descriptor *poke_tab;
@@ -2566,6 +2567,9 @@ struct bpf_reg_state;
 int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog);
 int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *prog,
 			 struct btf *btf, const struct btf_type *t);
+int btf_check_func_part_match(struct btf *btf1, const struct btf_type *t1,
+			      struct btf *btf2, const struct btf_type *t2,
+			      u64 func_args);
 const char *btf_find_decl_tag_value(const struct btf *btf, const struct btf_type *pt,
 				    int comp_idx, const char *tag_key);
 int btf_find_next_decl_tag(const struct btf *btf, const struct btf_type *pt,
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 6ff0bd1a91d5..3a6931402fe4 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6203,6 +6203,9 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
 		/* skip first 'void *__data' argument in btf_trace_##name typedef */
 		args++;
 		nr_args--;
+		prog->aux->accessed_args |= (1 << (arg + 1));
+	} else {
+		prog->aux->accessed_args |= (1 << arg);
 	}
 
 	if (arg > nr_args) {
@@ -7010,6 +7013,124 @@ int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *pr
 	return btf_check_func_type_match(log, btf1, t1, btf2, t2);
 }
 
+static u32 get_ctx_arg_total_size(struct btf *btf, const struct btf_type *t)
+{
+	const struct btf_param *args;
+	u32 size = 0, nr_args;
+	int i;
+
+	nr_args = btf_type_vlen(t);
+	args = (const struct btf_param *)(t + 1);
+	for (i = 0; i < nr_args; i++) {
+		t = btf_type_skip_modifiers(btf, args[i].type, NULL);
+		size += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
+	}
+
+	return size;
+}
+
+static int get_ctx_arg_idx_aligned(struct btf *btf, const struct btf_type *t,
+				   int off)
+{
+	const struct btf_param *args;
+	u32 offset = 0, nr_args;
+	int i;
+
+	nr_args = btf_type_vlen(t);
+	args = (const struct btf_param *)(t + 1);
+	for (i = 0; i < nr_args; i++) {
+		if (offset == off)
+			return i;
+
+		t = btf_type_skip_modifiers(btf, args[i].type, NULL);
+		offset += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
+		if (offset > off)
+			return -1;
+	}
+	return -1;
+}
+
+/* This function is similar to btf_check_func_type_match(), except that it
+ * only compare some function args of the function prototype t1 and t2.
+ */
+int btf_check_func_part_match(struct btf *btf1, const struct btf_type *func1,
+			      struct btf *btf2, const struct btf_type *func2,
+			      u64 func_args)
+{
+	const struct btf_param *args1, *args2;
+	u32 nargs1, i, offset = 0;
+	const char *s1, *s2;
+
+	if (!btf_type_is_func_proto(func1) || !btf_type_is_func_proto(func2))
+		return -EINVAL;
+
+	args1 = (const struct btf_param *)(func1 + 1);
+	args2 = (const struct btf_param *)(func2 + 1);
+	nargs1 = btf_type_vlen(func1);
+
+	for (i = 0; i <= nargs1; i++) {
+		const struct btf_type *t1, *t2;
+
+		if (!(func_args & (1 << i)))
+			goto next;
+
+		if (i < nargs1) {
+			int t2_index;
+
+			/* get the index of the arg corresponding to args1[i]
+			 * by the offset.
+			 */
+			t2_index = get_ctx_arg_idx_aligned(btf2, func2,
+							   offset);
+			if (t2_index < 0)
+				return -EINVAL;
+
+			t1 = btf_type_skip_modifiers(btf1, args1[i].type, NULL);
+			t2 = btf_type_skip_modifiers(btf2, args2[t2_index].type,
+						     NULL);
+		} else {
+			/* i == nargs1, this is the index of return value of t1 */
+			if (get_ctx_arg_total_size(btf1, func1) !=
+			    get_ctx_arg_total_size(btf2, func2))
+				return -EINVAL;
+
+			/* check the return type of t1 and t2 */
+			t1 = btf_type_skip_modifiers(btf1, func1->type, NULL);
+			t2 = btf_type_skip_modifiers(btf2, func2->type, NULL);
+		}
+
+		if (t1->info != t2->info ||
+		    (btf_type_has_size(t1) && t1->size != t2->size))
+			return -EINVAL;
+		if (btf_type_is_int(t1) || btf_is_any_enum(t1))
+			goto next;
+
+		if (btf_type_is_struct(t1))
+			goto on_struct;
+
+		if (!btf_type_is_ptr(t1))
+			return -EINVAL;
+
+		t1 = btf_type_skip_modifiers(btf1, t1->type, NULL);
+		t2 = btf_type_skip_modifiers(btf2, t2->type, NULL);
+		if (!btf_type_is_struct(t1) || !btf_type_is_struct(t2))
+			return -EINVAL;
+
+on_struct:
+		s1 = btf_name_by_offset(btf1, t1->name_off);
+		s2 = btf_name_by_offset(btf2, t2->name_off);
+		if (strcmp(s1, s2))
+			return -EINVAL;
+next:
+		if (i < nargs1) {
+			t1 = btf_type_skip_modifiers(btf1, args1[i].type, NULL);
+			offset += btf_type_is_ptr(t1) ? 8 : roundup(t1->size, 8);
+		}
+	}
+
+	return 0;
+}
+
 static bool btf_is_dynptr_ptr(const struct btf *btf, const struct btf_type *t)
 {
 	const char *name;
-- 
2.39.2



From dongmenglong.8 at bytedance.com  Mon Feb 19 19:51:02 2024
From: dongmenglong.8 at bytedance.com (Menglong Dong)
Date: Tue, 20 Feb 2024 11:51:02 +0800
Subject: [PATCH bpf-next 2/5] bpf: tracing: support to attach program to multi hooks
In-Reply-To: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
Message-ID: <20240220035105.34626-3-dongmenglong.8@bytedance.com>

In this commit, we add the support to allow attaching a tracing BPF
program to multi hooks.

In the commit 4a1e7c0c63e0 ("bpf: Support attaching freplace programs to
multiple attach points"), the freplace BPF program is made to support
attach to multiple attach points. And in this commit, we extend it to
fentry/fexit/raw_tp/...

The use case is obvious. For now, we have to create a BPF program for each
kernel function, for which we want to trace, even through all the program
have the same (or similar logic). This can consume extra memory, and make
the program loading slow if we have plenty of kernel function to trace.
The KPROBE_MULTI maybe a alternative, but it can't what TRACING do. For
example, the kretprobe can't obtain the function args, but the FEXIT can.

Now, we need to hold the reference for the target btf and kernel module
in the bpf link, as a program can have multiple target. Therefore, we
introduce the attach_btf and mod field to the struct bpf_tracing_link.
During the attach, we will check the target is compatible with the
program, which means that the function args that the program accessed
in the target function prototype should be the same as the origin target.

Signed-off-by: Menglong Dong <dongmenglong.8 at bytedance.com>
---
 include/linux/bpf.h      |   2 +
 include/uapi/linux/bpf.h |   1 +
 kernel/bpf/syscall.c     | 117 +++++++++++++++++++++++++++++++--------
 3 files changed, 98 insertions(+), 22 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 0225b8dbdd9d..cf8f2df9afb9 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1606,6 +1606,8 @@ struct bpf_tracing_link {
 	enum bpf_attach_type attach_type;
 	struct bpf_trampoline *trampoline;
 	struct bpf_prog *tgt_prog;
+	struct btf *attach_btf;
+	struct module *mod;
 };
 
 struct bpf_link_primer {
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index d96708380e52..0ded10a85bfe 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1668,6 +1668,7 @@ union bpf_attr {
 		union {
 			__u32	target_fd;	/* target object to attach to or ... */
 			__u32	target_ifindex; /* target ifindex */
+			__u32	target_btf_obj_fd;
 		};
 		__u32		attach_type;	/* attach type */
 		__u32		flags;		/* extra flags */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index b2750b79ac80..3b432fcd5bdb 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -3178,6 +3178,9 @@ static void bpf_tracing_link_dealloc(struct bpf_link *link)
 	struct bpf_tracing_link *tr_link =
 		container_of(link, struct bpf_tracing_link, link.link);
 
+
+	btf_put(tr_link->attach_btf);
+	module_put(tr_link->mod);
 	kfree(tr_link);
 }
 
@@ -3220,6 +3223,35 @@ static const struct bpf_link_ops bpf_tracing_link_lops = {
 	.fill_link_info = bpf_tracing_link_fill_link_info,
 };
 
+static int bpf_tracing_check_multi(struct bpf_prog *prog,
+				   struct bpf_prog *tgt_prog,
+				   struct btf *btf2,
+				   const struct btf_type *t2)
+{
+	struct btf *btf1 = prog->aux->attach_btf;
+	const struct btf_type *t1;
+
+	/* this case is already valided in bpf_check_attach_target() */
+	if (prog->type == BPF_PROG_TYPE_EXT)
+		return 0;
+
+	/* For now, noly support multi attach for kernel function attach
+	 * point.
+	 */
+	if (!btf1)
+		return -EOPNOTSUPP;
+
+	btf2 = btf2 ?: tgt_prog->aux->btf;
+	t1 = prog->aux->attach_func_proto;
+
+	/* the target is the same as the origin one, this is a re-attach */
+	if (t1 == t2)
+		return 0;
+
+	return btf_check_func_part_match(btf1, t1, btf2, t2,
+					 prog->aux->accessed_args);
+}
+
 static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 				   int tgt_prog_fd,
 				   u32 btf_id,
@@ -3228,7 +3260,9 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 	struct bpf_link_primer link_primer;
 	struct bpf_prog *tgt_prog = NULL;
 	struct bpf_trampoline *tr = NULL;
+	struct btf *attach_btf = NULL;
 	struct bpf_tracing_link *link;
+	struct module *mod = NULL;
 	u64 key = 0;
 	int err;
 
@@ -3258,31 +3292,50 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 		goto out_put_prog;
 	}
 
-	if (!!tgt_prog_fd != !!btf_id) {
-		err = -EINVAL;
-		goto out_put_prog;
-	}
-
 	if (tgt_prog_fd) {
-		/*
-		 * For now we only allow new targets for BPF_PROG_TYPE_EXT. If this
-		 * part would be changed to implement the same for
-		 * BPF_PROG_TYPE_TRACING, do not forget to update the way how
-		 * attach_tracing_prog flag is set.
-		 */
-		if (prog->type != BPF_PROG_TYPE_EXT) {
+		if (!btf_id) {
 			err = -EINVAL;
 			goto out_put_prog;
 		}
-
 		tgt_prog = bpf_prog_get(tgt_prog_fd);
 		if (IS_ERR(tgt_prog)) {
-			err = PTR_ERR(tgt_prog);
 			tgt_prog = NULL;
-			goto out_put_prog;
+			/* tgt_prog_fd is the fd of the kernel module BTF */
+			attach_btf = btf_get_by_fd(tgt_prog_fd);
+			if (IS_ERR(attach_btf)) {
+				attach_btf = NULL;
+				err = -EINVAL;
+				goto out_put_prog;
+			}
+			if (!btf_is_kernel(attach_btf)) {
+				btf_put(attach_btf);
+				err = -EOPNOTSUPP;
+				goto out_put_prog;
+			}
+		} else if (prog->type == BPF_PROG_TYPE_TRACING &&
+			   tgt_prog->type == BPF_PROG_TYPE_TRACING) {
+			prog->aux->attach_tracing_prog = true;
 		}
-
-		key = bpf_trampoline_compute_key(tgt_prog, NULL, btf_id);
+		key = bpf_trampoline_compute_key(tgt_prog, attach_btf,
+						 btf_id);
+	} else if (btf_id) {
+		attach_btf = bpf_get_btf_vmlinux();
+		if (IS_ERR(attach_btf)) {
+			attach_btf = NULL;
+			err = PTR_ERR(attach_btf);
+			goto out_unlock;
+		}
+		if (!attach_btf) {
+			err = -EINVAL;
+			goto out_unlock;
+		}
+		btf_get(attach_btf);
+		key = bpf_trampoline_compute_key(NULL, attach_btf, btf_id);
+	} else {
+		attach_btf = prog->aux->attach_btf;
+		/* get the reference of the btf for bpf link */
+		if (attach_btf)
+			btf_get(attach_btf);
 	}
 
 	link = kzalloc(sizeof(*link), GFP_USER);
@@ -3319,7 +3372,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 	 *   are NULL, then program was already attached and user did not provide
 	 *   tgt_prog_fd so we have no way to find out or create trampoline
 	 */
-	if (!prog->aux->dst_trampoline && !tgt_prog) {
+	if (!prog->aux->dst_trampoline && !tgt_prog && !btf_id) {
 		/*
 		 * Allow re-attach for TRACING and LSM programs. If it's
 		 * currently linked, bpf_trampoline_link_prog will fail.
@@ -3346,17 +3399,27 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 		 * different from the destination specified at load time, we
 		 * need a new trampoline and a check for compatibility
 		 */
+		struct btf *origin_btf = prog->aux->attach_btf;
 		struct bpf_attach_target_info tgt_info = {};
 
+		/* use the new attach_btf to check the target */
+		prog->aux->attach_btf = attach_btf;
 		err = bpf_check_attach_target(NULL, prog, tgt_prog, btf_id,
 					      &tgt_info);
+		prog->aux->attach_btf = origin_btf;
 		if (err)
 			goto out_unlock;
 
-		if (tgt_info.tgt_mod) {
-			module_put(prog->aux->mod);
-			prog->aux->mod = tgt_info.tgt_mod;
-		}
+		mod = tgt_info.tgt_mod;
+		/* the new target and the previous target are in the same
+		 * module, release the reference once.
+		 */
+		if (mod && mod == prog->aux->mod)
+			module_put(mod);
+		err = bpf_tracing_check_multi(prog, tgt_prog, attach_btf,
+					      tgt_info.tgt_type);
+		if (err)
+			goto out_unlock;
 
 		tr = bpf_trampoline_get(key, &tgt_info);
 		if (!tr) {
@@ -3373,6 +3436,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 		 */
 		tr = prog->aux->dst_trampoline;
 		tgt_prog = prog->aux->dst_prog;
+		mod = prog->aux->mod;
 	}
 
 	err = bpf_link_prime(&link->link.link, &link_primer);
@@ -3388,6 +3452,8 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 
 	link->tgt_prog = tgt_prog;
 	link->trampoline = tr;
+	link->attach_btf = attach_btf;
+	link->mod = mod;
 
 	/* Always clear the trampoline and target prog from prog->aux to make
 	 * sure the original attach destination is not kept alive after a
@@ -3400,20 +3466,27 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 	if (prog->aux->dst_trampoline && tr != prog->aux->dst_trampoline)
 		/* we allocated a new trampoline, so free the old one */
 		bpf_trampoline_put(prog->aux->dst_trampoline);
+	if (prog->aux->mod && mod != prog->aux->mod)
+		/* the mod in prog is not used anywhere, move it to link */
+		module_put(prog->aux->mod);
 
 	prog->aux->dst_prog = NULL;
 	prog->aux->dst_trampoline = NULL;
+	prog->aux->mod = NULL;
 	mutex_unlock(&prog->aux->dst_mutex);
 
 	return bpf_link_settle(&link_primer);
 out_unlock:
 	if (tr && tr != prog->aux->dst_trampoline)
 		bpf_trampoline_put(tr);
+	if (mod && mod != prog->aux->mod)
+		module_put(mod);
 	mutex_unlock(&prog->aux->dst_mutex);
 	kfree(link);
 out_put_prog:
 	if (tgt_prog_fd && tgt_prog)
 		bpf_prog_put(tgt_prog);
+	btf_put(attach_btf);
 	return err;
 }
 
-- 
2.39.2



From dongmenglong.8 at bytedance.com  Mon Feb 19 19:51:03 2024
From: dongmenglong.8 at bytedance.com (Menglong Dong)
Date: Tue, 20 Feb 2024 11:51:03 +0800
Subject: [PATCH bpf-next 3/5] libbpf: allow to set coookie when target_btf_id is set in bpf_link_create
In-Reply-To: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
Message-ID: <20240220035105.34626-4-dongmenglong.8@bytedance.com>

As now we support to attach the tracing program to multiple target, we can
set the bpf cookie even if the target btf id is offered in
bpf_link_create().

Signed-off-by: Menglong Dong <dongmenglong.8 at bytedance.com>
---
 tools/lib/bpf/bpf.c | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 97ec005c3c47..0ca7c8375b40 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -737,23 +737,15 @@ int bpf_link_create(int prog_fd, int target_fd,
 	target_btf_id = OPTS_GET(opts, target_btf_id, 0);
 
 	/* validate we don't have unexpected combinations of non-zero fields */
-	if (iter_info_len || target_btf_id) {
-		if (iter_info_len && target_btf_id)
-			return libbpf_err(-EINVAL);
-		if (!OPTS_ZEROED(opts, target_btf_id))
-			return libbpf_err(-EINVAL);
-	}
+	if (iter_info_len && target_btf_id)
+		return libbpf_err(-EINVAL);
 
 	memset(&attr, 0, attr_sz);
 	attr.link_create.prog_fd = prog_fd;
 	attr.link_create.target_fd = target_fd;
 	attr.link_create.attach_type = attach_type;
 	attr.link_create.flags = OPTS_GET(opts, flags, 0);
-
-	if (target_btf_id) {
-		attr.link_create.target_btf_id = target_btf_id;
-		goto proceed;
-	}
+	attr.link_create.target_btf_id = target_btf_id;
 
 	switch (attach_type) {
 	case BPF_TRACE_ITER:
@@ -834,11 +826,10 @@ int bpf_link_create(int prog_fd, int target_fd,
 			return libbpf_err(-EINVAL);
 		break;
 	default:
-		if (!OPTS_ZEROED(opts, flags))
+		if (!target_btf_id && !OPTS_ZEROED(opts, flags))
 			return libbpf_err(-EINVAL);
 		break;
 	}
-proceed:
 	fd = sys_bpf_fd(BPF_LINK_CREATE, &attr, attr_sz);
 	if (fd >= 0)
 		return fd;
-- 
2.39.2



From dongmenglong.8 at bytedance.com  Mon Feb 19 19:51:04 2024
From: dongmenglong.8 at bytedance.com (Menglong Dong)
Date: Tue, 20 Feb 2024 11:51:04 +0800
Subject: [PATCH bpf-next 4/5] libbpf: add the function libbpf_find_kernel_btf_id()
In-Reply-To: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
Message-ID: <20240220035105.34626-5-dongmenglong.8@bytedance.com>

Add new function libbpf_find_kernel_btf_id() to find the btf type id of
the kernel, including vmlinux and modules.

Signed-off-by: Menglong Dong <dongmenglong.8 at bytedance.com>
---
 tools/lib/bpf/libbpf.c   | 83 ++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h   |  3 ++
 tools/lib/bpf/libbpf.map |  1 +
 3 files changed, 87 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 01f407591a92..44e34007de8c 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -9500,6 +9500,89 @@ int libbpf_find_vmlinux_btf_id(const char *name,
 	return libbpf_err(err);
 }
 
+int libbpf_find_kernel_btf_id(const char *name,
+			      enum bpf_attach_type attach_type,
+			      int *btf_obj_fd, int *btf_type_id)
+{
+	struct btf *btf, *vmlinux_btf;
+	struct bpf_btf_info info;
+	__u32 btf_id = 0, len;
+	char btf_name[64];
+	int err, fd;
+
+	vmlinux_btf = btf__load_vmlinux_btf();
+	err = libbpf_get_error(vmlinux_btf);
+	if (err)
+		return libbpf_err(err);
+
+	err = find_attach_btf_id(vmlinux_btf, name, attach_type);
+	if (err > 0) {
+		*btf_type_id = err;
+		*btf_obj_fd = 0;
+		err = 0;
+		goto out;
+	}
+
+	/* kernel too old to support module BTFs */
+	if (!feat_supported(NULL, FEAT_MODULE_BTF)) {
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	while (true) {
+		err = bpf_btf_get_next_id(btf_id, &btf_id);
+		if (err) {
+			err = -errno;
+			goto out;
+		}
+
+		fd = bpf_btf_get_fd_by_id(btf_id);
+		if (fd < 0) {
+			if (errno == ENOENT)
+				continue;
+			err = -errno;
+			goto out;
+		}
+
+		len = sizeof(info);
+		memset(&info, 0, sizeof(info));
+		info.name = ptr_to_u64(btf_name);
+		info.name_len = sizeof(btf_name);
+
+		err = bpf_btf_get_info_by_fd(fd, &info, &len);
+		if (err) {
+			err = -errno;
+			goto fd_out;
+		}
+
+		if (!info.kernel_btf || strcmp(btf_name, "vmlinux") == 0) {
+			close(fd);
+			continue;
+		}
+
+		btf = btf_get_from_fd(fd, vmlinux_btf);
+		err = libbpf_get_error(btf);
+		if (err)
+			goto fd_out;
+
+		err = find_attach_btf_id(btf, name, attach_type);
+		if (err > 0) {
+			*btf_type_id = err;
+			*btf_obj_fd = fd;
+			err = 0;
+			break;
+		}
+		close(fd);
+		continue;
+fd_out:
+		close(fd);
+		break;
+	}
+out:
+	btf__free(vmlinux_btf);
+	return err;
+}
+
 static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd)
 {
 	struct bpf_prog_info info;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 5723cbbfcc41..ca151bbec833 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -306,6 +306,9 @@ LIBBPF_API int libbpf_attach_type_by_name(const char *name,
 					  enum bpf_attach_type *attach_type);
 LIBBPF_API int libbpf_find_vmlinux_btf_id(const char *name,
 					  enum bpf_attach_type attach_type);
+LIBBPF_API int libbpf_find_kernel_btf_id(const char *name,
+					 enum bpf_attach_type attach_type,
+					 int *btf_obj_fd, int *btf_type_id);
 
 /* Accessors of bpf_program */
 struct bpf_program;
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 86804fd90dd1..73c60f47b4bb 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -413,4 +413,5 @@ LIBBPF_1.4.0 {
 		bpf_token_create;
 		btf__new_split;
 		btf_ext__raw_data;
+		libbpf_find_kernel_btf_id;
 } LIBBPF_1.3.0;
-- 
2.39.2



From dongmenglong.8 at bytedance.com  Mon Feb 19 19:51:05 2024
From: dongmenglong.8 at bytedance.com (Menglong Dong)
Date: Tue, 20 Feb 2024 11:51:05 +0800
Subject: [PATCH bpf-next 5/5] selftests/bpf: add test cases for multiple attach of tracing program
In-Reply-To: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
Message-ID: <20240220035105.34626-6-dongmenglong.8@bytedance.com>

In this commit, we add the testcases for multiple attaching of tracing,
include FENTRY, FEXIT, MODIFY_RETURN.

Signed-off-by: Menglong Dong <dongmenglong.8 at bytedance.com>
---
 .../selftests/bpf/bpf_testmod/bpf_testmod.c   |  49 ++++++
 .../bpf/prog_tests/tracing_multi_attach.c     | 155 ++++++++++++++++++
 .../selftests/bpf/progs/tracing_multi_test.c  |  72 ++++++++
 3 files changed, 276 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/tracing_multi_attach.c
 create mode 100644 tools/testing/selftests/bpf/progs/tracing_multi_test.c

diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
index 66787e99ba1b..237eeb7daa07 100644
--- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
@@ -98,12 +98,61 @@ bpf_testmod_test_struct_arg_8(u64 a, void *b, short c, int d, void *e,
 	return bpf_testmod_test_struct_arg_result;
 }
 
+noinline int
+bpf_testmod_test_struct_arg_9(struct bpf_testmod_struct_arg_2 a,
+			      struct bpf_testmod_struct_arg_1 b) {
+	bpf_testmod_test_struct_arg_result = a.a + a.b  + b.a;
+	return bpf_testmod_test_struct_arg_result;
+}
+
+noinline int
+bpf_testmod_test_struct_arg_10(int a, struct bpf_testmod_struct_arg_2 b) {
+	bpf_testmod_test_struct_arg_result = a + b.a + b.b;
+	return bpf_testmod_test_struct_arg_result;
+}
+
+noinline struct bpf_testmod_struct_arg_2 *
+bpf_testmod_test_struct_arg_11(int a, struct bpf_testmod_struct_arg_2 b, int c) {
+	bpf_testmod_test_struct_arg_result = a + b.a + b.b + c;
+	return (void *)bpf_testmod_test_struct_arg_result;
+}
+
+noinline int
+bpf_testmod_test_struct_arg_12(int a, struct bpf_testmod_struct_arg_2 b, int *c) {
+	bpf_testmod_test_struct_arg_result = a + b.a + b.b + *c;
+	return bpf_testmod_test_struct_arg_result;
+}
+
 noinline int
 bpf_testmod_test_arg_ptr_to_struct(struct bpf_testmod_struct_arg_1 *a) {
 	bpf_testmod_test_struct_arg_result = a->a;
 	return bpf_testmod_test_struct_arg_result;
 }
 
+noinline int
+bpf_testmod_test_arg_ptr_1(struct bpf_testmod_struct_arg_1 *a) {
+	bpf_testmod_test_struct_arg_result = a->a;
+	return bpf_testmod_test_struct_arg_result;
+}
+
+noinline int
+bpf_testmod_test_arg_ptr_2(struct bpf_testmod_struct_arg_2 *a) {
+	bpf_testmod_test_struct_arg_result = a->a + a->b;
+	return bpf_testmod_test_struct_arg_result;
+}
+
+noinline int
+bpf_testmod_test_arg_ptr_3(int a, struct bpf_testmod_struct_arg_2 *b) {
+	bpf_testmod_test_struct_arg_result = a + b->a + b->b;
+	return bpf_testmod_test_struct_arg_result;
+}
+
+noinline int
+bpf_testmod_test_arg_ptr_4(struct bpf_testmod_struct_arg_2 *a, int b) {
+	bpf_testmod_test_struct_arg_result = a->a + a->b + b;
+	return bpf_testmod_test_struct_arg_result;
+}
+
 __bpf_kfunc void
 bpf_testmod_test_mod_kfunc(int i)
 {
diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_multi_attach.c b/tools/testing/selftests/bpf/prog_tests/tracing_multi_attach.c
new file mode 100644
index 000000000000..6162d41cca9e
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/tracing_multi_attach.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2024 Bytedance. */
+
+#include <test_progs.h>
+#include "tracing_multi_test.skel.h"
+
+struct test_item {
+	char *prog;
+	char *target;
+	int attach_type;
+	bool success;
+	int link_fd;
+};
+
+static struct test_item test_items[] = {
+	{
+		.prog = "fentry_test1", .target = "bpf_testmod_test_struct_arg_9",
+		.attach_type = BPF_TRACE_FENTRY, .success = true,
+	},
+	{
+		.prog = "fentry_test1", .target = "bpf_testmod_test_struct_arg_1",
+		.attach_type = BPF_TRACE_FENTRY, .success = false,
+	},
+	{
+		.prog = "fentry_test1", .target = "bpf_testmod_test_struct_arg_2",
+		.attach_type = BPF_TRACE_FENTRY, .success = false,
+	},
+	{
+		.prog = "fentry_test1", .target = "bpf_testmod_test_arg_ptr_2",
+		.attach_type = BPF_TRACE_FENTRY, .success = false,
+	},
+	{
+		.prog = "fentry_test2", .target = "bpf_testmod_test_struct_arg_2",
+		.attach_type = BPF_TRACE_FENTRY, .success = false,
+	},
+	{
+		.prog = "fentry_test2", .target = "bpf_testmod_test_struct_arg_10",
+		.attach_type = BPF_TRACE_FENTRY, .success = true,
+	},
+	{
+		.prog = "fentry_test2", .target = "bpf_testmod_test_struct_arg_9",
+		.attach_type = BPF_TRACE_FENTRY, .success = false,
+	},
+	{
+		.prog = "fentry_test2", .target = "bpf_testmod_test_arg_ptr_3",
+		.attach_type = BPF_TRACE_FENTRY, .success = false,
+	},
+	{
+		.prog = "fentry_test3", .target = "bpf_testmod_test_arg_ptr_3",
+		.attach_type = BPF_TRACE_FENTRY, .success = false,
+	},
+	{
+		.prog = "fentry_test3", .target = "bpf_testmod_test_arg_ptr_4",
+		.attach_type = BPF_TRACE_FENTRY, .success = true,
+	},
+	{
+		.prog = "fentry_test4", .target = "bpf_testmod_test_struct_arg_4",
+		.attach_type = BPF_TRACE_FENTRY, .success = true,
+	},
+	{
+		.prog = "fentry_test4", .target = "bpf_testmod_test_struct_arg_2",
+		.attach_type = BPF_TRACE_FENTRY, .success = true,
+	},
+	{
+		.prog = "fentry_test4", .target = "bpf_testmod_test_struct_arg_12",
+		.attach_type = BPF_TRACE_FENTRY, .success = false,
+	},
+	{
+		.prog = "fexit_test1", .target = "bpf_testmod_test_struct_arg_2",
+		.attach_type = BPF_TRACE_FEXIT, .success = true,
+	},
+	{
+		.prog = "fexit_test1", .target = "bpf_testmod_test_struct_arg_3",
+		.attach_type = BPF_TRACE_FEXIT, .success = true,
+	},
+	{
+		.prog = "fexit_test1", .target = "bpf_testmod_test_struct_arg_4",
+		.attach_type = BPF_TRACE_FEXIT, .success = false,
+	},
+	{
+		.prog = "fexit_test2", .target = "bpf_testmod_test_struct_arg_10",
+		.attach_type = BPF_TRACE_FEXIT, .success = false,
+	},
+	{
+		.prog = "fexit_test2", .target = "bpf_testmod_test_struct_arg_11",
+		.attach_type = BPF_TRACE_FEXIT, .success = false,
+	},
+	{
+		.prog = "fexit_test2", .target = "bpf_testmod_test_struct_arg_12",
+		.attach_type = BPF_TRACE_FEXIT, .success = true,
+	},
+	{
+		.prog = "fmod_ret_test1", .target = "bpf_modify_return_test2",
+		.attach_type = BPF_MODIFY_RETURN, .success = true,
+	},
+};
+
+static int do_test_item(struct tracing_multi_test *skel, struct test_item *item)
+{
+	LIBBPF_OPTS(bpf_link_create_opts, link_opts);
+	struct bpf_program *prog;
+	int err, btf_fd = 0, btf_type_id;
+
+	err = libbpf_find_kernel_btf_id(item->target, item->attach_type,
+					&btf_fd, &btf_type_id);
+	if (!ASSERT_OK(err, "find_vmlinux_btf_id"))
+		return -1;
+
+	link_opts.target_btf_id = btf_type_id;
+	prog = bpf_object__find_program_by_name(skel->obj, item->prog);
+	if (!ASSERT_OK_PTR(prog, "find_program_by_name"))
+		return -1;
+
+	err = bpf_link_create(bpf_program__fd(prog), btf_fd, item->attach_type,
+			      &link_opts);
+	item->link_fd = err;
+	if (item->success) {
+		if (!ASSERT_GE(err, 0, "link_create"))
+			return -1;
+	} else {
+		if (!ASSERT_LT(err, 0, "link_create"))
+			return -1;
+	}
+
+	return 0;
+}
+
+void test_tracing_multi_attach(void)
+{
+	struct tracing_multi_test *skel;
+	int i = 0, err, fd;
+
+	skel = tracing_multi_test__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "tracing_multi_test__open_and_load"))
+		return;
+
+	err = tracing_multi_test__attach(skel);
+	if (!ASSERT_OK(err, "tracing_multi_test__attach"))
+		goto destroy_skel;
+
+	for (; i < ARRAY_SIZE(test_items); i++) {
+		if (do_test_item(skel, &test_items[i]))
+			break;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(test_items); i++) {
+		fd = test_items[i].link_fd;
+		if (fd >= 0)
+			close(fd);
+	}
+
+	tracing_multi_test__detach(skel);
+destroy_skel:
+	tracing_multi_test__destroy(skel);
+}
diff --git a/tools/testing/selftests/bpf/progs/tracing_multi_test.c b/tools/testing/selftests/bpf/progs/tracing_multi_test.c
new file mode 100644
index 000000000000..f1ca8b64ed16
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/tracing_multi_test.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2024 ByteDance */
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+char _license[] SEC("license") = "GPL";
+
+struct bpf_testmod_struct_arg_1 {
+	int a;
+};
+struct bpf_testmod_struct_arg_2 {
+	long a;
+	long b;
+};
+
+__u64 fentry_test1_result = 0;
+SEC("fentry/bpf_testmod_test_struct_arg_1")
+int BPF_PROG2(fentry_test1, struct bpf_testmod_struct_arg_2, a)
+{
+	fentry_test1_result = a.a + a.b;
+	return 0;
+}
+
+__u64 fentry_test2_result = 0;
+SEC("fentry/bpf_testmod_test_struct_arg_2")
+int BPF_PROG2(fentry_test2, int, a, struct bpf_testmod_struct_arg_2, b)
+{
+	fentry_test2_result = a + b.a + b.b;
+	return 0;
+}
+
+__u64 fentry_test3_result = 0;
+SEC("fentry/bpf_testmod_test_arg_ptr_2")
+int BPF_PROG(fentry_test3, struct bpf_testmod_struct_arg_2 *a)
+{
+	fentry_test3_result = a->a + a->b;
+	return 0;
+}
+
+__u64 fentry_test4_result = 0;
+SEC("fentry/bpf_testmod_test_struct_arg_1")
+int BPF_PROG2(fentry_test4, struct bpf_testmod_struct_arg_2, a, int, b,
+	      int, c)
+{
+	fentry_test3_result = c;
+	return 0;
+}
+
+__u64 fexit_test1_result = 0;
+SEC("fexit/bpf_testmod_test_struct_arg_1")
+int BPF_PROG2(fexit_test1, struct bpf_testmod_struct_arg_2, a, int, b,
+	      int, c, int, retval)
+{
+	fexit_test1_result = retval;
+	return 0;
+}
+
+__u64 fexit_test2_result = 0;
+SEC("fexit/bpf_testmod_test_struct_arg_2")
+int BPF_PROG2(fexit_test2, int, a, struct bpf_testmod_struct_arg_2, b,
+	      int, c, int, retval)
+{
+	fexit_test2_result = a + b.a + b.b + retval;
+	return 0;
+}
+
+SEC("fmod_ret/bpf_modify_return_test")
+int BPF_PROG(fmod_ret_test1, int a, int *b)
+{
+	return 0;
+}
-- 
2.39.2



From vigneshr at ti.com  Mon Feb 19 19:54:28 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 20 Feb 2024 09:24:28 +0530
Subject: (subset) [PATCH v5 0/4] Add common1 region for AM62, AM62A & AM65x
In-Reply-To: <20240216062426.4170528-1-devarsht@ti.com>
References: <20240216062426.4170528-1-devarsht@ti.com>
Message-ID: <170834878957.3471454.9863747085400602100.b4-ty@ti.com>

Hi Devarsh Thakkar,

On Fri, 16 Feb 2024 11:54:22 +0530, Devarsh Thakkar wrote:
> This adds DSS common1 region for respective SoCs supporting it.
> 
> Changelog:
> V2 : Remove do-not-merge tag and add am62a dss common1 reion
> V3 : Add Fixes tag to each commit
> V4 : Add Reviewed-by tag and AM62A SoC TRM Link
> V5 : Split dts patch to separate patches for each SoC
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[2/4] arm64: dts: ti: Add common1 register space for AM65x SoC
      commit: 1a5010eade10b409d353b770d97b548b0fbdf5d7
[3/4] arm64: dts: ti: Add common1 register space for AM62x SoC
      commit: 7d8ee2c3b8a2aabb9ce75795bad20773bfe1ba13
[4/4] arm64: dts: ti: Add common1 register space for AM62A SoC
      commit: 0f9eb43f009091501dd0c68232aa6530ba0e0185

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb 19 19:56:35 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 20 Feb 2024 09:26:35 +0530
Subject: [PATCH v4 0/9] Add CSI2RX capture support on TI J7 platforms
In-Reply-To: <20240215085518.552692-1-vaishnav.a@ti.com>
References: <20240215085518.552692-1-vaishnav.a@ti.com>
Message-ID: <170834878954.3471454.4526592845067575248.b4-ty@ti.com>

Hi Vaishnav Achath,

On Thu, 15 Feb 2024 14:25:09 +0530, Vaishnav Achath wrote:
> This series adds support for CSI2RX capture support on J7 platforms,
> series was tested for CSI2RX capture on OV5640 sensor and RPI camera
> v2 IMX219 sensor on J721e Common Processor Board, J721E Starter kit,
> J721S2 Common Processor Board, AM68 Starter Kit, J784s4 EVM and AM69
> Starter kit.
> 
> V1: https://lore.kernel.org/all/20240129132742.1189783-1-vaishnav.a at ti.com/
> V2: https://lore.kernel.org/all/20240208084254.295289-1-vaishnav.a at ti.com/
> V3: https://lore.kernel.org/all/20240208123233.391115-1-vaishnav.a at ti.com/
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/9] arm64: dts: ti: k3-j721s2-common-proc-board: Enable camera peripherals
      commit: f00c6ead159fb028ac989916ed2999bac2f7d43b
[2/9] arm64: dts: ti: k3-j784s4-evm: Enable camera peripherals
      commit: fa646b7096708db6d87b43bedefaddc7c605a9bf
[3/9] arm64: dts: ti: k3-am68-sk-base-board: Enable camera peripherals
      commit: 5dcc1aaf0b7aa861bf9cfd48a9db46a4a3b2d47a
[4/9] arm64: dts: ti: k3-am69-sk: Enable camera peripherals
      commit: 12d82b15b94c2b44bee7c8c90682850d3ad9b120
[5/9] arm64: dts: ti: k3-j721e-sk: Model CSI2RX connector mux
      commit: f87c88947396674586a42a163b72efa3999e3dee
[6/9] arm64: dts: ti: k3-j721e-main: Add CSI2RX capture nodes
      commit: 491821cebcf5cfa86dbc6bbf03f45322dea31b11
[7/9] arm64: dts: ti: k3-j721s2-main: Add CSI2RX capture nodes
      commit: 6aac91999ede6e855694cdb673a901bb7305c214
[8/9] arm64: dts: ti: k3-j784s4-main: Add CSI2RX capture nodes
      commit: 2ba8f21a74b7e75fd1af9ad9ccdbacaf43fe10e4
[9/9] arm64: dts: ti: k3-j721e-sk: Add overlay for IMX219
      commit: f767eb9180967c2961d47955dc1a3d099819f244

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb 19 19:57:36 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 20 Feb 2024 09:27:36 +0530
Subject: [PATCH v3 0/4] arm64: dts: ti: Modify pinmux for wkup_uart0 and mcu_uart0
In-Reply-To: <20240214105846.1096733-1-b-kapoor@ti.com>
References: <20240214105846.1096733-1-b-kapoor@ti.com>
Message-ID: <170834878954.3471454.4988713452460973346.b4-ty@ti.com>

Hi Bhavya Kapoor,

On Wed, 14 Feb 2024 16:28:42 +0530, Bhavya Kapoor wrote:
> WKUP_PADCONFIG registers for wkup_uart0 and mcu_uart0 lies under
> wkup_pmx2 for J7200. Thus, modify pinmux for both of them. Also,
> remove the redundant clock-frequency property from mcu_uart0 node.
> 
> Only Tx and Rx Signal lines for wkup_uart0 are brought out on
> J721S2 Common Proc Board and J784S4 EVM, but CTS and RTS signal lines
> are not brought out. Thus, remove pinmux for CTS and RTS signal lines
> for wkup_uart0 in J721S2 and J784S4.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/4] arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for wkup_uart0 and mcu_uart0
      commit: 566feddd2ba5e29d9ccab36d6508592ae563f275
[2/4] arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency from mcu_uart0
      commit: 0fa8b0e2083d333e4854b9767fb893f924e70ae5
[3/4] arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and RTS in wkup_uart0
      commit: 28e5b74d524050008edf415f20a3e38907b8f176
[4/4] arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in wkup_uart0
      commit: d29a6cf980572d8cf7b63935716fca663e2610f0

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb 19 19:57:56 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 20 Feb 2024 09:27:56 +0530
Subject: [PATCH v5 0/3] Add AM64x ICSSG Ethernet support
In-Reply-To: <20240215103036.2825096-1-danishanwar@ti.com>
References: <20240215103036.2825096-1-danishanwar@ti.com>
Message-ID: <170834878955.3471454.4379641943483865314.b4-ty@ti.com>

Hi MD Danish Anwar,

On Thu, 15 Feb 2024 16:00:33 +0530, MD Danish Anwar wrote:
> This series adds support for ICSSG ethernet on AM64x.
> This series is based on the latest next-20240214 linux-next.
> 
> AM64x EVM has three ethernet ports. One is dedicated to CPSW and one is
> dedicated to ICSSG1. The remaining port is muxed between CPSW and ICSSG1
> ICSSG1 ports. The ICSSG1 node is added in the k3-am642-evm.dts. By default
> the muxed port is used by CPSW so 2nd ICSSG1 port is disabled in the
> k3-am642-evm.dts. But overlay k3-am642-evm-icssg1-dualemac.dtso can be
> applied to use muxed port as ICSSG1.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/3] arm64: dts: ti: k3-am64-main: Add ICSSG IEP nodes
      commit: d4e8c8ad5d14ad51ed8813442d81c43019fd669d
[2/3] arm64: dts: ti: k3-am642-evm: add ICSSG1 Ethernet support
      commit: efb32a10a10d92f4bc3380106bd3b003ea790aa3
[3/3] arm64: dts: ti: k3-am642-evm: add overlay for ICSSG1 2nd port
      commit: ae0aba1218a0c67f144706c48502f534b2756491

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Mon Feb 19 20:03:17 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Tue, 20 Feb 2024 09:33:17 +0530
Subject: [PATCH v3 0/9] Fix MMC properties on Sitara K3 devices
In-Reply-To: <20240213235701.2438513-1-jm@ti.com>
References: <20240213235701.2438513-1-jm@ti.com>
Message-ID: <170834878955.3471454.11267750873554490606.b4-ty@ti.com>

Hi Judith Mendez,

On Tue, 13 Feb 2024 17:56:52 -0600, Judith Mendez wrote:
> This patch series aims to fix and update MMC nodes for TI
> Sitara K3 devices with the following changes.
> 
> The series introduces sdhci0 and sdhci2 nodes and enables
> eMMC for AM62ax platform.
> 
> Also introduce fixes for MMC ITAP/OTAP values for AM64x
> platform according to device datasheet [0], and add ITAP/
> OTAP values for AM62p to enable the highest timing possible
> for MMC0 and MMC1, according to device datasheet [1].
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/9] arm64: dts: ti: k3-am62a-main: Add sdhci0 instance
      commit: d3ae4e8d8b6ac0db82264c5576daa260cac3d536
[2/9] arm64: dts: ti: k3-am62a-main: Add sdhci2 instance
      commit: feb5d68cec77b6783f4febb8c91c1b1caa8b4924
[3/9] arm64: dts: ti: k3-am62a7-sk: Enable eMMC support
      commit: e041ec6e86e7dbc49f5245ace6f3b965bb7c26f7
[4/9] arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
      commit: 379c7752bbd0e81654544a896dd19c19ebb6faba
[5/9] arm64: dts: ti: k3-am62p: Add ITAP/OTAP values for MMC
      commit: 37f28165518f7df2ed085e4481dade9c262b593b
[6/9] arm64: dts: ti: k3-am6*: Remove DLL properties for soft PHYs
      commit: eea929f0e0e3f83d2c027b1e60630deb50df4494
[7/9] arm64: dts: ti: k3-am6*: Fix ti,clkbuf-sel property in MMC nodes
      commit: 2812d23ade3d614b451bff5d63d29a31b92d8859
[8/9] arm64: dts: ti: k3-am6*: Fix bus-width property in MMC nodes
      commit: 0ae3113a46a64266f19fdc9753d5e3a6748fc594
[9/9] arm64: dts: ti: k3-am6*: Add bootph-all property in MMC node
      commit: 5f0e6ce354f61092182b79d177585bd7310f12a2

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From quic_snehshah at quicinc.com  Mon Feb 19 21:07:35 2024
From: quic_snehshah at quicinc.com (Sneh Shah)
Date: Tue, 20 Feb 2024 10:37:35 +0530
Subject: [PATCH net-next v5] net: stmmac: dwmac-qcom-ethqos: Add support for 2.5G SGMII
Message-ID: <20240220050735.29507-1-quic_snehshah@quicinc.com>

Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000
mode for 1G/100M/10M speed.
Added changes to configure serdes phy and mac based on link speed.
Changing serdes phy speed involves multiple register writes for
serdes block. To avoid redundant write operations only update serdes
phy when new speed is different.
For 2500 speed MAC PCS autoneg needs to disabled. Added changes to
disable MAC PCS autoneg if ANE parameter is not set.

Signed-off-by: Sneh Shah <quic_snehshah at quicinc.com>
---
v5 changelog:
- Updated commit message with more details on MAC PCS autoneg disable
v4 changelog:
- Made cosmetic changes
v3 changelog:
- updated commit message
---
v2 changelog:
- updated stmmac_pcs_ane to support autoneg disable
- Update serdes speed to 1000 for 100M and 10M also---
---
 .../stmicro/stmmac/dwmac-qcom-ethqos.c        | 26 +++++++++++++++++++
 .../net/ethernet/stmicro/stmmac/stmmac_pcs.h  |  2 ++
 2 files changed, 28 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 31631e3f89d0..6bbdbb7bef44 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -106,6 +106,7 @@ struct qcom_ethqos {
 	struct clk *link_clk;
 	struct phy *serdes_phy;
 	unsigned int speed;
+	int serdes_speed;
 	phy_interface_t phy_mode;
 
 	const struct ethqos_emac_por *por;
@@ -606,19 +607,39 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos)
  */
 static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
 {
+	struct net_device *dev = platform_get_drvdata(ethqos->pdev);
+	struct stmmac_priv *priv = netdev_priv(dev);
 	int val;
 
 	val = readl(ethqos->mac_base + MAC_CTRL_REG);
 
 	switch (ethqos->speed) {
+	case SPEED_2500:
+		val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
+		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_IO_MACRO_CONFIG2);
+		if (ethqos->serdes_speed != SPEED_2500)
+			phy_set_speed(ethqos->serdes_phy, SPEED_2500);
+		ethqos->serdes_speed = SPEED_2500;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 0, 0, 0);
+		break;
 	case SPEED_1000:
 		val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
 		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
 			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
 			      RGMII_IO_MACRO_CONFIG2);
+		if (ethqos->serdes_speed != SPEED_1000)
+			phy_set_speed(ethqos->serdes_phy, SPEED_1000);
+		ethqos->serdes_speed = SPEED_1000;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
 		break;
 	case SPEED_100:
 		val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE;
+		if (ethqos->serdes_speed != SPEED_1000)
+			phy_set_speed(ethqos->serdes_phy, SPEED_1000);
+		ethqos->serdes_speed = SPEED_1000;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
 		break;
 	case SPEED_10:
 		val |= ETHQOS_MAC_CTRL_PORT_SEL;
@@ -627,6 +648,10 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
 			      FIELD_PREP(RGMII_CONFIG_SGMII_CLK_DVDR,
 					 SGMII_10M_RX_CLK_DVDR),
 			      RGMII_IO_MACRO_CONFIG);
+		if (ethqos->serdes_speed != SPEED_1000)
+			phy_set_speed(ethqos->serdes_phy, ethqos->speed);
+		ethqos->serdes_speed = SPEED_1000;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
 		break;
 	}
 
@@ -799,6 +824,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 				     "Failed to get serdes phy\n");
 
 	ethqos->speed = SPEED_1000;
+	ethqos->serdes_speed = SPEED_1000;
 	ethqos_update_link_clk(ethqos, SPEED_1000);
 	ethqos_set_func_clk_en(ethqos);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
index aefc121464b5..13a30e6df4c1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
@@ -110,6 +110,8 @@ static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane,
 	/* Enable and restart the Auto-Negotiation */
 	if (ane)
 		value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN;
+	else
+		value &= ~GMAC_AN_CTRL_ANE;
 
 	/* In case of MAC-2-MAC connection, block is configured to operate
 	 * according to MAC conf register.
-- 
2.17.1



From andrew at codeconstruct.com.au  Mon Feb 19 21:29:18 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Tue, 20 Feb 2024 15:59:18 +1030
Subject: [PATCH] dt-bindings: gpio: Convert Aspeed binding to YAML schema
Message-ID: <20240220052918.742793-1-andrew@codeconstruct.com.au>

Squash warnings such as:

```
arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-galaxy100.dtb: /ahb/apb at 1e600000/gpio at 1e780000: failed to match any schema with compatible: ['aspeed,ast2400-gpio']
```

Signed-off-by: Andrew Jeffery <andrew at codeconstruct.com.au>
---
 .../bindings/gpio/aspeed,ast2400-gpio.yaml    | 64 +++++++++++++++++++
 .../devicetree/bindings/gpio/gpio-aspeed.txt  | 39 -----------
 2 files changed, 64 insertions(+), 39 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
 delete mode 100644 Documentation/devicetree/bindings/gpio/gpio-aspeed.txt

diff --git a/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
new file mode 100644
index 000000000000..353c7620013f
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/aspeed,ast2400-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Aspeed GPIO controller
+
+maintainers:
+  - Andrew Jeffery <andrew at codeconstruct.com.au>
+
+allOf:
+  - $ref: /schemas/gpio/gpio.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: aspeed,ast2600-gpio
+    then:
+      required:
+        - ngpios
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2400-gpio
+      - aspeed,ast2500-gpio
+      - aspeed,ast2600-gpio
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: The clock to use for debounce timings
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-controller
+  - "#gpio-cells"
+  - gpio-controller
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    gpio at 1e780000 {
+        compatible = "aspeed,ast2400-gpio";
+        reg = <0x1e780000 0x1000>;
+        interrupts = <20>;
+        interrupt-controller;
+        #gpio-cells = <2>;
+        gpio-controller;
+    };
diff --git a/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt b/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt
deleted file mode 100644
index b2033fc3a71a..000000000000
--- a/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-Aspeed GPIO controller Device Tree Bindings
--------------------------------------------
-
-Required properties:
-- compatible		: Either "aspeed,ast2400-gpio", "aspeed,ast2500-gpio",
-					or "aspeed,ast2600-gpio".
-
-- #gpio-cells 		: Should be two
-			  - First cell is the GPIO line number
-			  - Second cell is used to specify optional
-			    parameters (unused)
-
-- reg			: Address and length of the register set for the device
-- gpio-controller	: Marks the device node as a GPIO controller.
-- interrupts		: Interrupt specifier (see interrupt bindings for
-			  details)
-- interrupt-controller	: Mark the GPIO controller as an interrupt-controller
-
-Optional properties:
-
-- clocks		: A phandle to the clock to use for debounce timings
-- ngpios		: Number of GPIOs controlled by this controller. Should	be set
-				  when there are multiple GPIO controllers on a SoC (ast2600).
-
-The gpio and interrupt properties are further described in their respective
-bindings documentation:
-
-- Documentation/devicetree/bindings/gpio/gpio.txt
-- Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
-
-  Example:
-	gpio at 1e780000 {
-		#gpio-cells = <2>;
-		compatible = "aspeed,ast2400-gpio";
-		gpio-controller;
-		interrupts = <20>;
-		reg = <0x1e780000 0x1000>;
-		interrupt-controller;
-	};

base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
-- 
2.39.2



From zhi.mao at mediatek.com  Mon Feb 19 21:45:54 2024
From: zhi.mao at mediatek.com (=?utf-8?B?WmhpIE1hbyAo5q+b5pm6KQ==?=)
Date: Tue, 20 Feb 2024 05:45:54 +0000
Subject: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <20240220030104.GF20376@pendragon.ideasonboard.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
	 <20240204061538.2105-3-zhi.mao@mediatek.com>
	 <20240206184542.GE2827@pendragon.ideasonboard.com>
	 <598f62bbb55157eec1e23dd1dbc307fea3851b21.camel@mediatek.com>
	 <20240220030104.GF20376@pendragon.ideasonboard.com>
Message-ID: <115698c0c549e747026cc8841a3bd571533f8e6f.camel@mediatek.com>

Hi Laurent,

Thanks for you reply.
I'd like to ask for advice about how to contrl "reset-pin", please
check the below comments.

On Tue, 2024-02-20 at 05:01 +0200, Laurent Pinchart wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  Hi Zhi,
> 
> On Tue, Feb 20, 2024 at 02:12:26AM +0000, Zhi Mao (??) wrote:
> > On Tue, 2024-02-06 at 20:45 +0200, Laurent Pinchart wrote:
> > > On Sun, Feb 04, 2024 at 02:15:38PM +0800, Zhi Mao wrote:
> > > > Add a V4L2 sub-device driver for Galaxycore GC08A3 image
> sensor.
> > > >
> > > > Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> > > > ---
> > > >  drivers/media/i2c/Kconfig  |   10 +
> > > >  drivers/media/i2c/Makefile |    1 +
> > > >  drivers/media/i2c/gc08a3.c | 1448
> ++++++++++++++++++++++++++++++++++++
> > > >  3 files changed, 1459 insertions(+)
> > > >  create mode 100644 drivers/media/i2c/gc08a3.c
> 
> [snip]
> 
> > > > diff --git a/drivers/media/i2c/gc08a3.c
> b/drivers/media/i2c/gc08a3.c
> > > > new file mode 100644
> > > > index 000000000000..3fc7fffb815c
> > > > --- /dev/null
> > > > +++ b/drivers/media/i2c/gc08a3.c
> > > > @@ -0,0 +1,1448 @@
> 
> [snip]
> 
> > > > +static int gc08a3_power_on(struct device *dev)
> > > > +{
> > > > +struct i2c_client *client = to_i2c_client(dev);
> > > > +struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > > > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > > > +int ret;
> > > > +
> > > > +ret = regulator_bulk_enable(ARRAY_SIZE(gc08a3_supply_name),
> > > > +    gc08a3->supplies);
> > > > +if (ret < 0) {
> > > > +dev_err(gc08a3->dev, "failed to enable regulators: %d\n",
> ret);
> > > > +return ret;
> > > > +}
> > > > +
> > > > +ret = clk_prepare_enable(gc08a3->xclk);
> > > > +if (ret < 0) {
> > > > +regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
> > > > +       gc08a3->supplies);
> > > > +dev_err(gc08a3->dev, "clk prepare enable failed\n");
> > > > +return ret;
> > > > +}
> > > > +
> > > > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > > > +
> > > > +gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > >
> > > Are you asserting reset when powering on ? That sounds wrong, you
> should
> > > de-assert reset here (and acquire the reset gpio in probe() with
> > > GPIOD_OUT_HIGH). Drivers should use logical levels for GPIOs,
> setting a
> > > GPIO named "reset" to 1 should assert the reset signal, even if
> the
> > > physical signal is active low. You may have the wrong polarity in
> the
> > > device tree.
> >
> > According to the sensor power sequence sepc, "reset" pin should be
> pull
> > from low to high after "dovdd/dvdd/avdd" power on, so I follow this
> > power sequece to pull "reset" pin high in software flow.
> 
> From a hardware point of view that's right, but the Linux kernel
> handles
> logical level of GPIOs. If a GPIO is named "reset", it is expected
> that
> calling
> 
> gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> 
> will "assert" the reset signal, setting it to a logical "reset =
> true"
> level. This maps to the hardware 0V output level, as the signal is
> active-low. To achieve this, define the reset GPIO as active low in
> DT,
> and the GPIO framework will invert the signal for you. You should
> then
> call
> 
> gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> 
> in the driver when you want to assert reset (set it to 0V), and
> 
> gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);
> 
> when you want to deassert it (set it to 3.3V, or whatever the I/O
> voltage for the signal is).
> 
> This way all driver use logical states, and the inversion is handled
> in
> DT.
> 

Sensor power sequence as below:
                      ------------------
                     | | |
                     | | | 
dvdd/avdd/dovdd  --------
                               ---------
                              |
                              |
reset-pin        -------------

In order to match this power sequece, "reset-pin" contrl flow is below:
1. config the "reset-pin" is "active-high" in DTS:
    reset-gpios = <&pio 19 GPIO_ACTIVE_HIGH>;

2. image sensor driver probe function:
gc08a3->reset_gpio = devm_gpiod_get(dev, "reset",
GPIOD_OUT_LOW);  //init "reset-pin" is low

3. image sensor driver power_on function:
gpiod_set_value_cansleep(gc08a3->reset_gpio, 1); //pull "reset-pin"
high 

so, the expect state of "reset-pin" is from low to high.
If I am wrong, please correct me.

> > > > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > > > +
> > > > +return 0;
> > > > +}
> 
> [snip]
> 
> -- 
> Regards,
> 
> Laurent Pinchart

From quic_mkshah at quicinc.com  Mon Feb 19 21:48:39 2024
From: quic_mkshah at quicinc.com (Maulik Shah (mkshah))
Date: Tue, 20 Feb 2024 11:18:39 +0530
Subject: [PATCH] firmware/psci: Move psci_init_system_suspend() to
 late_initcall()
In-Reply-To: <ZdOP5oAwZvEhNAsn@lpieralisi>
References: <20240219-suspend_ops_late_init-v1-1-6330ca9597fa@quicinc.com>
 <ZdOP5oAwZvEhNAsn@lpieralisi>
Message-ID: <dc16acc1-6ad1-4a81-8eeb-aadaf837ff2c@quicinc.com>



On 2/19/2024 10:59 PM, Lorenzo Pieralisi wrote:
> On Mon, Feb 19, 2024 at 03:02:04PM +0530, Maulik Shah wrote:
>> psci_init_system_suspend() invokes suspend_set_ops() very early during
>> bootup even before kernel command line for mem_sleep_default is setup.
>> This leads to kernel command line mem_sleep_default=s2idle not working
>> as mem_sleep_current gets changed to deep via suspend_set_ops() and never
>> changes back to s2idle.
>>
>> Move psci_init_system_suspend() to late_initcall() to make sure kernel
>> command line mem_sleep_default=s2idle sets up s2idle as default suspend
>> mode.
> 
> Why can't we fix it the other way around, namely enforce
> mem_sleep_current according to the mem_sleep_default command line
> even if suspend_set_ops() was already called ?

yes, this may be fixed other way also and i did not implement other way 
since mem_sleep_default_setup() only update mem_sleep_default and to 
avoid this race, it needs to also need to update mem_sleep_current along
with it. Below change also resolves the issue.

--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -192,6 +192,7 @@ static int __init mem_sleep_default_setup(char *str)
                 if (mem_sleep_labels[state] &&
                     !strcmp(str, mem_sleep_labels[state])) {
                         mem_sleep_default = state;
+                       mem_sleep_current = state;
                         break;
                 }

however it may be erasing thin line between mem_sleep_default v/s 
mem_sleep_current as both gets updated while set up of mem_sleep_default.

if this change looks Ok, i can send v2 with it.

> 
> Just asking, I am not super keen on using initcalls ordering, it
> looks fragile to me.

i agree with above.

Thanks,
Maulik


From apatel at ventanamicro.com  Mon Feb 19 22:07:05 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:05 +0530
Subject: [PATCH v13 00/13] Linux RISC-V AIA Support
Message-ID: <20240220060718.823229-1-apatel@ventanamicro.com>

The RISC-V AIA specification is ratified as-per the RISC-V international
process. The latest ratified AIA specifcation can be found at:
https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf

At a high-level, the AIA specification adds three things:
1) AIA CSRs
   - Improved local interrupt support
2) Incoming Message Signaled Interrupt Controller (IMSIC)
   - Per-HART MSI controller
   - Support MSI virtualization
   - Support IPI along with virtualization
3) Advanced Platform-Level Interrupt Controller (APLIC)
   - Wired interrupt controller
   - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
   - In Direct-mode, injects external interrupts directly into HARTs

For an overview of the AIA specification, refer the AIA virtualization
talk at KVM Forum 2022:
https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
https://www.youtube.com/watch?v=r071dL8Z0yo

To test this series, use QEMU v7.2 (or higher) and OpenSBI v1.2 (or higher).

This series depends upon per-device MSI domain patches merged by Thomas (tglx)
which are available in irq/msi branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git

These patches can also be found in the riscv_aia_v13 branch at:
https://github.com/avpatel/linux.git

Changes since v12:
 - Rebased on Linux-6.8-rc5
 - Dropped per-device MSI domain patches which are already merged by Thomas (tglx)
 - Addressed nit comments from Thomas and Clement
 - Added a new patch2 to fix lock dependency warning
 - Replaced local sync IPI in the IMSIC driver with per-CPU timer
 - Simplified locking in the IMSIC driver to avoid lock dependency issues
 - Added a dirty bitmap in the IMSIC driver to optimize per-CPU local sync loop

Changes since v11:
 - Rebased on Linux-6.8-rc1
 - Included kernel/irq related patches from "genirq, irqchip: Convert ARM
   MSI handling to per device MSI domains" series by Thomas.
   (PATCH7, PATCH8, PATCH9, PATCH14, PATCH16, PATCH17, PATCH18, PATCH19,
    PATCH20, PATCH21, PATCH22, PATCH23, and PATCH32 of
    https://lore.kernel.org/linux-arm-kernel/20221121135653.208611233 at linutronix.de/)
 - Updated APLIC MSI-mode driver to use the new WIRED_TO_MSI mechanism.
 - Updated IMSIC driver to support per-device MSI domains for PCI and
   platform devices.

Changes since v10:
 - Rebased on Linux-6.6-rc7
 - Dropped PATCH3 of v10 series since this has been merged by MarcZ
   for Linux-6.6-rc7
 - Changed the IMSIC ID management strategy from 1-n approach to
   x86-style 1-1 approach

Changes since v9:
 - Rebased on Linux-6.6-rc4
 - Use builtin_platform_driver() in PATCH5, PATCH9, and PATCH12

Changes since v8:
 - Rebased on Linux-6.6-rc3
 - Dropped PATCH2 of v8 series since we won't be requiring
   riscv_get_intc_hartid() based on Marc Z's comments on ACPI AIA support.
 - Addressed Saravana's comments in PATCH3 of v8 series
 - Update PATCH9 and PATCH13 of v8 series based on comments from Sunil

Changes since v7:
 - Rebased on Linux-6.6-rc1
 - Addressed comments on PATCH1 of v7 series and split it into two PATCHes
 - Use DEFINE_SIMPLE_PROP() in PATCH2 of v7 series

Changes since v6:
 - Rebased on Linux-6.5-rc4
 - Updated PATCH2 to use IS_ENABLED(CONFIG_SPARC) instead of
   !IS_ENABLED(CONFIG_OF_IRQ)
 - Added new PATCH4 to fix syscore registration in PLIC driver
 - Update PATCH5 to convert PLIC driver into full-blown platform driver
   with a re-written probe function.

Changes since v5:
 - Rebased on Linux-6.5-rc2
 - Updated the overall series to ensure that only IPI, timer, and
   INTC drivers are probed very early whereas rest of the interrupt
   controllers (such as PLIC, APLIC, and IMISC) are probed as
   regular platform drivers.
 - Renamed riscv_fw_parent_hartid() to riscv_get_intc_hartid()
 - New PATCH1 to add fw_devlink support for msi-parent DT property
 - New PATCH2 to ensure all INTC suppliers are initialized which in-turn
   fixes the probing issue for PLIC, APLIC and IMSIC as platform driver
 - New PATCH3 to use platform driver probing for PLIC
 - Re-structured the IMSIC driver into two separate drivers: early and
   platform. The IMSIC early driver (PATCH7) only initialized IMSIC state
   and provides IPIs whereas the IMSIC platform driver (PATCH8) is probed
   provides MSI domain for platform devices.
 - Re-structure the APLIC platform driver into three separe sources: main,
   direct mode, and MSI mode.

Changes since v4:
 - Rebased on Linux-6.5-rc1
 - Added "Dependencies" in the APLIC bindings (PATCH6 in v4)
 - Dropped the PATCH6 which was changing the IOMMU DMA domain APIs
 - Dropped use of IOMMU DMA APIs in the IMSIC driver (PATCH4)

Changes since v3:
 - Rebased on Linux-6.4-rc6
 - Dropped PATCH2 of v3 series instead we now set FWNODE_FLAG_BEST_EFFORT via
   IRQCHIP_DECLARE()
 - Extend riscv_fw_parent_hartid() to support both DT and ACPI in PATCH1
 - Extend iommu_dma_compose_msi_msg() instead of adding iommu_dma_select_msi()
   in PATCH6
 - Addressed Conor's comments in PATCH3
 - Addressed Conor's and Rob's comments in PATCH7

Changes since v2:
 - Rebased on Linux-6.4-rc1
 - Addressed Rob's comments on DT bindings patches 4 and 8.
 - Addessed Marc's comments on IMSIC driver PATCH5
 - Replaced use of OF apis in APLIC and IMSIC drivers with FWNODE apis
   this makes both drivers easily portable for ACPI support. This also
   removes unnecessary indirection from the APLIC and IMSIC drivers.
 - PATCH1 is a new patch for portability with ACPI support
 - PATCH2 is a new patch to fix probing in APLIC drivers for APLIC-only systems.
 - PATCH7 is a new patch which addresses the IOMMU DMA domain issues pointed
   out by SiFive

Changes since v1:
 - Rebased on Linux-6.2-rc2
 - Addressed comments on IMSIC DT bindings for PATCH4
 - Use raw_spin_lock_irqsave() on ids_lock for PATCH5
 - Improved MMIO alignment checks in PATCH5 to allow MMIO regions
   with holes.
 - Addressed comments on APLIC DT bindings for PATCH6
 - Fixed warning splat in aplic_msi_write_msg() caused by
   zeroed MSI message in PATCH7
 - Dropped DT property riscv,slow-ipi instead will have module
   parameter in future.

Anup Patel (12):
  irqchip/sifive-plic: Convert PLIC driver into a platform driver
  irqchip/sifive-plic: Improve locking safety by using
    irqsave/irqrestore
  irqchip/riscv-intc: Add support for RISC-V AIA
  dt-bindings: interrupt-controller: Add RISC-V incoming MSI controller
  irqchip: Add RISC-V incoming MSI controller early driver
  irqchip/riscv-imsic: Add device MSI domain support for platform
    devices
  irqchip/riscv-imsic: Add device MSI domain support for PCI devices
  dt-bindings: interrupt-controller: Add RISC-V advanced PLIC
  irqchip: Add RISC-V advanced PLIC driver for direct-mode
  irqchip/riscv-aplic: Add support for MSI-mode
  RISC-V: Select APLIC and IMSIC drivers
  MAINTAINERS: Add entry for RISC-V AIA drivers

Bj?rn T?pel (1):
  genirq/matrix: Dynamic bitmap allocation

 .../interrupt-controller/riscv,aplic.yaml     | 172 ++++
 .../interrupt-controller/riscv,imsics.yaml    | 172 ++++
 MAINTAINERS                                   |  14 +
 arch/riscv/Kconfig                            |   2 +
 arch/x86/include/asm/hw_irq.h                 |   2 -
 drivers/irqchip/Kconfig                       |  25 +
 drivers/irqchip/Makefile                      |   3 +
 drivers/irqchip/irq-riscv-aplic-direct.c      | 324 +++++++
 drivers/irqchip/irq-riscv-aplic-main.c        | 211 ++++
 drivers/irqchip/irq-riscv-aplic-main.h        |  52 +
 drivers/irqchip/irq-riscv-aplic-msi.c         | 263 +++++
 drivers/irqchip/irq-riscv-imsic-early.c       | 213 ++++
 drivers/irqchip/irq-riscv-imsic-platform.c    | 378 ++++++++
 drivers/irqchip/irq-riscv-imsic-state.c       | 906 ++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.h       |  99 ++
 drivers/irqchip/irq-riscv-intc.c              |  34 +-
 drivers/irqchip/irq-sifive-plic.c             | 285 ++++--
 include/linux/irqchip/riscv-aplic.h           | 145 +++
 include/linux/irqchip/riscv-imsic.h           |  87 ++
 kernel/irq/matrix.c                           |  28 +-
 20 files changed, 3298 insertions(+), 117 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
 create mode 100644 drivers/irqchip/irq-riscv-aplic-direct.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.h
 create mode 100644 drivers/irqchip/irq-riscv-aplic-msi.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-early.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.h
 create mode 100644 include/linux/irqchip/riscv-aplic.h
 create mode 100644 include/linux/irqchip/riscv-imsic.h

-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:06 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:06 +0530
Subject: [PATCH v13 01/13] irqchip/sifive-plic: Convert PLIC driver into a platform driver
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-2-apatel@ventanamicro.com>

The PLIC driver does not require very early initialization so let
us convert it into a platform driver.

As part of the conversion, the PLIC probing undergoes the following
changes:
1. Use dev_info(), dev_err() and dev_warn() instead of pr_info(),
   pr_err() and pr_warn()
2. Use devm_xyz() APIs wherever applicable
3. PLIC is now probed after CPUs are brought-up so we have to
   setup cpuhp state after context handler of all online CPUs
   are initialized otherwise we see crash on multi-socket systems

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-sifive-plic.c | 269 ++++++++++++++++++++----------
 1 file changed, 177 insertions(+), 92 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 5b7bc4fd9517..48483a1a41dd 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -3,7 +3,6 @@
  * Copyright (C) 2017 SiFive
  * Copyright (C) 2018 Christoph Hellwig
  */
-#define pr_fmt(fmt) "plic: " fmt
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -64,6 +63,7 @@
 #define PLIC_QUIRK_EDGE_INTERRUPT	0
 
 struct plic_priv {
+	struct device *dev;
 	struct cpumask lmask;
 	struct irq_domain *irqdomain;
 	void __iomem *regs;
@@ -371,7 +371,8 @@ static void plic_handle_irq(struct irq_desc *desc)
 		int err = generic_handle_domain_irq(handler->priv->irqdomain,
 						    hwirq);
 		if (unlikely(err))
-			pr_warn_ratelimited("can't find mapping for hwirq %lu\n",
+			dev_warn_ratelimited(handler->priv->dev,
+					"can't find mapping for hwirq %lu\n",
 					hwirq);
 	}
 
@@ -406,57 +407,126 @@ static int plic_starting_cpu(unsigned int cpu)
 	return 0;
 }
 
-static int __init __plic_init(struct device_node *node,
-			      struct device_node *parent,
-			      unsigned long plic_quirks)
+static const struct of_device_id plic_match[] = {
+	{ .compatible = "sifive,plic-1.0.0" },
+	{ .compatible = "riscv,plic0" },
+	{ .compatible = "andestech,nceplic100",
+	  .data = (const void *)BIT(PLIC_QUIRK_EDGE_INTERRUPT) },
+	{ .compatible = "thead,c900-plic",
+	  .data = (const void *)BIT(PLIC_QUIRK_EDGE_INTERRUPT) },
+	{}
+};
+
+static int plic_parse_nr_irqs_and_contexts(struct platform_device *pdev,
+					   u32 *nr_irqs, u32 *nr_contexts)
 {
-	int error = 0, nr_contexts, nr_handlers = 0, i;
-	u32 nr_irqs;
-	struct plic_priv *priv;
+	struct device *dev = &pdev->dev;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	rc = of_property_read_u32(to_of_node(dev->fwnode),
+				  "riscv,ndev", nr_irqs);
+	if (rc) {
+		dev_err(dev, "riscv,ndev property not available\n");
+		return rc;
+	}
+
+	*nr_contexts = of_irq_count(to_of_node(dev->fwnode));
+	if (WARN_ON(!(*nr_contexts))) {
+		dev_err(dev, "no PLIC context available\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int plic_parse_context_parent_hwirq(struct platform_device *pdev,
+					   u32 context, u32 *parent_hwirq,
+					   unsigned long *parent_hartid)
+{
+	struct device *dev = &pdev->dev;
+	struct of_phandle_args parent;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	rc = of_irq_parse_one(to_of_node(dev->fwnode), context, &parent);
+	if (rc)
+		return rc;
+
+	rc = riscv_of_parent_hartid(parent.np, parent_hartid);
+	if (rc)
+		return rc;
+
+	*parent_hwirq = parent.args[0];
+	return 0;
+}
+
+static int plic_probe(struct platform_device *pdev)
+{
+	int rc, nr_contexts, nr_handlers = 0, i, cpu;
+	unsigned long plic_quirks = 0, hartid;
+	struct device *dev = &pdev->dev;
 	struct plic_handler *handler;
-	unsigned int cpu;
+	u32 nr_irqs, parent_hwirq;
+	struct irq_domain *domain;
+	struct plic_priv *priv;
+	irq_hw_number_t hwirq;
+	struct resource *res;
+	bool cpuhp_setup;
+
+	if (is_of_node(dev->fwnode)) {
+		const struct of_device_id *id;
+
+		id = of_match_node(plic_match, to_of_node(dev->fwnode));
+		if (id)
+			plic_quirks = (unsigned long)id->data;
+	}
 
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
-
+	priv->dev = dev;
 	priv->plic_quirks = plic_quirks;
 
-	priv->regs = of_iomap(node, 0);
-	if (WARN_ON(!priv->regs)) {
-		error = -EIO;
-		goto out_free_priv;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "failed to get MMIO resource\n");
+		return -EINVAL;
+	}
+	priv->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (!priv->regs) {
+		dev_err(dev, "failed map MMIO registers\n");
+		return -EIO;
 	}
 
-	error = -EINVAL;
-	of_property_read_u32(node, "riscv,ndev", &nr_irqs);
-	if (WARN_ON(!nr_irqs))
-		goto out_iounmap;
-
+	rc = plic_parse_nr_irqs_and_contexts(pdev, &nr_irqs, &nr_contexts);
+	if (rc) {
+		dev_err(dev, "failed to parse irqs and contexts\n");
+		return rc;
+	}
 	priv->nr_irqs = nr_irqs;
 
-	priv->prio_save = bitmap_alloc(nr_irqs, GFP_KERNEL);
+	priv->prio_save = devm_bitmap_zalloc(dev, nr_irqs, GFP_KERNEL);
 	if (!priv->prio_save)
-		goto out_free_priority_reg;
-
-	nr_contexts = of_irq_count(node);
-	if (WARN_ON(!nr_contexts))
-		goto out_free_priority_reg;
-
-	error = -ENOMEM;
-	priv->irqdomain = irq_domain_add_linear(node, nr_irqs + 1,
-			&plic_irqdomain_ops, priv);
-	if (WARN_ON(!priv->irqdomain))
-		goto out_free_priority_reg;
+		return -ENOMEM;
 
 	for (i = 0; i < nr_contexts; i++) {
-		struct of_phandle_args parent;
-		irq_hw_number_t hwirq;
-		int cpu;
-		unsigned long hartid;
-
-		if (of_irq_parse_one(node, i, &parent)) {
-			pr_err("failed to parse parent for context %d.\n", i);
+		rc = plic_parse_context_parent_hwirq(pdev, i,
+						     &parent_hwirq, &hartid);
+		if (rc) {
+			dev_warn(dev, "hwirq for context%d not found\n", i);
 			continue;
 		}
 
@@ -464,7 +534,7 @@ static int __init __plic_init(struct device_node *node,
 		 * Skip contexts other than external interrupts for our
 		 * privilege level.
 		 */
-		if (parent.args[0] != RV_IRQ_EXT) {
+		if (parent_hwirq != RV_IRQ_EXT) {
 			/* Disable S-mode enable bits if running in M-mode. */
 			if (IS_ENABLED(CONFIG_RISCV_M_MODE)) {
 				void __iomem *enable_base = priv->regs +
@@ -477,21 +547,17 @@ static int __init __plic_init(struct device_node *node,
 			continue;
 		}
 
-		error = riscv_of_parent_hartid(parent.np, &hartid);
-		if (error < 0) {
-			pr_warn("failed to parse hart ID for context %d.\n", i);
-			continue;
-		}
-
 		cpu = riscv_hartid_to_cpuid(hartid);
 		if (cpu < 0) {
-			pr_warn("Invalid cpuid for context %d\n", i);
+			dev_warn(dev, "Invalid cpuid for context %d\n", i);
 			continue;
 		}
 
 		/* Find parent domain and register chained handler */
-		if (!plic_parent_irq && irq_find_host(parent.np)) {
-			plic_parent_irq = irq_of_parse_and_map(node, i);
+		domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(),
+						  DOMAIN_BUS_ANY);
+		if (!plic_parent_irq && domain) {
+			plic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
 			if (plic_parent_irq)
 				irq_set_chained_handler(plic_parent_irq,
 							plic_handle_irq);
@@ -504,7 +570,7 @@ static int __init __plic_init(struct device_node *node,
 		 */
 		handler = per_cpu_ptr(&plic_handlers, cpu);
 		if (handler->present) {
-			pr_warn("handler already present for context %d.\n", i);
+			dev_warn(dev, "handler already present for context%d.\n", i);
 			plic_set_threshold(handler, PLIC_DISABLE_THRESHOLD);
 			goto done;
 		}
@@ -518,10 +584,15 @@ static int __init __plic_init(struct device_node *node,
 			i * CONTEXT_ENABLE_SIZE;
 		handler->priv = priv;
 
-		handler->enable_save =  kcalloc(DIV_ROUND_UP(nr_irqs, 32),
-						sizeof(*handler->enable_save), GFP_KERNEL);
-		if (!handler->enable_save)
-			goto out_free_enable_reg;
+		handler->enable_save =  devm_kcalloc(dev,
+						DIV_ROUND_UP(nr_irqs, 32),
+						sizeof(*handler->enable_save),
+						GFP_KERNEL);
+		if (!handler->enable_save) {
+			rc = -ENOMEM;
+			goto fail_cleanup_contexts;
+		}
+
 done:
 		for (hwirq = 1; hwirq <= nr_irqs; hwirq++) {
 			plic_toggle(handler, hwirq, 0);
@@ -531,52 +602,66 @@ static int __init __plic_init(struct device_node *node,
 		nr_handlers++;
 	}
 
+	priv->irqdomain = irq_domain_create_linear(dev->fwnode, nr_irqs + 1,
+						   &plic_irqdomain_ops, priv);
+	if (WARN_ON(!priv->irqdomain)) {
+		rc = -ENOMEM;
+		goto fail_cleanup_contexts;
+	}
+
 	/*
 	 * We can have multiple PLIC instances so setup cpuhp state
-	 * and register syscore operations only when context handler
-	 * for current/boot CPU is present.
+	 * and register syscore operations only once after context
+	 * handlers of all online CPUs are initialized.
 	 */
-	handler = this_cpu_ptr(&plic_handlers);
-	if (handler->present && !plic_cpuhp_setup_done) {
-		cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
-				  "irqchip/sifive/plic:starting",
-				  plic_starting_cpu, plic_dying_cpu);
-		register_syscore_ops(&plic_irq_syscore_ops);
-		plic_cpuhp_setup_done = true;
+	if (!plic_cpuhp_setup_done) {
+		cpuhp_setup = true;
+		for_each_online_cpu(cpu) {
+			handler = per_cpu_ptr(&plic_handlers, cpu);
+			if (!handler->present) {
+				cpuhp_setup = false;
+				break;
+			}
+		}
+		if (cpuhp_setup) {
+			cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
+					  "irqchip/sifive/plic:starting",
+					  plic_starting_cpu, plic_dying_cpu);
+			register_syscore_ops(&plic_irq_syscore_ops);
+			plic_cpuhp_setup_done = true;
+		}
 	}
 
-	pr_info("%pOFP: mapped %d interrupts with %d handlers for"
-		" %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts);
+	dev_info(dev, "mapped %d interrupts with %d handlers for %d contexts.\n",
+		 nr_irqs, nr_handlers, nr_contexts);
 	return 0;
 
-out_free_enable_reg:
-	for_each_cpu(cpu, cpu_present_mask) {
+fail_cleanup_contexts:
+	for (i = 0; i < nr_contexts; i++) {
+		if (plic_parse_context_parent_hwirq(pdev, i,
+						    &parent_hwirq, &hartid))
+			continue;
+		if (parent_hwirq != RV_IRQ_EXT)
+			continue;
+		cpu = riscv_hartid_to_cpuid(hartid);
+		if (cpu < 0)
+			continue;
+
 		handler = per_cpu_ptr(&plic_handlers, cpu);
-		kfree(handler->enable_save);
+		handler->present = false;
+		handler->hart_base = NULL;
+		handler->enable_base = NULL;
+		handler->enable_save = NULL;
+		handler->priv = NULL;
 	}
-out_free_priority_reg:
-	kfree(priv->prio_save);
-out_iounmap:
-	iounmap(priv->regs);
-out_free_priv:
-	kfree(priv);
-	return error;
+	return rc;
 }
 
-static int __init plic_init(struct device_node *node,
-			    struct device_node *parent)
-{
-	return __plic_init(node, parent, 0);
-}
-
-IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init);
-IRQCHIP_DECLARE(riscv_plic0, "riscv,plic0", plic_init); /* for legacy systems */
-
-static int __init plic_edge_init(struct device_node *node,
-				 struct device_node *parent)
-{
-	return __plic_init(node, parent, BIT(PLIC_QUIRK_EDGE_INTERRUPT));
-}
-
-IRQCHIP_DECLARE(andestech_nceplic100, "andestech,nceplic100", plic_edge_init);
-IRQCHIP_DECLARE(thead_c900_plic, "thead,c900-plic", plic_edge_init);
+static struct platform_driver plic_driver = {
+	.driver = {
+		.name		= "riscv-plic",
+		.of_match_table	= plic_match,
+	},
+	.probe = plic_probe,
+};
+builtin_platform_driver(plic_driver);
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:07 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:07 +0530
Subject: [PATCH v13 02/13] irqchip/sifive-plic: Improve locking safety by using irqsave/irqrestore
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-3-apatel@ventanamicro.com>

Now that PLIC driver is probed as a regular platform driver, the lock
dependency validator complains about the safety of handler->enable_lock
usage:

[    0.956775]  Possible interrupt unsafe locking scenario:

[    0.956998]        CPU0                    CPU1
[    0.957247]        ----                    ----
[    0.957439]   lock(&handler->enable_lock);
[    0.957607]                                local_irq_disable();
[    0.957793]                                lock(&irq_desc_lock_class);
[    0.958021]                                lock(&handler->enable_lock);
[    0.958246]   <Interrupt>
[    0.958342]     lock(&irq_desc_lock_class);
[    0.958501]
                *** DEADLOCK ***

To address above, let's use raw_spin_lock_irqsave/unlock_irqrestore()
instead of raw_spin_lock/unlock().

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-sifive-plic.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 48483a1a41dd..e91077ff171f 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -103,9 +103,11 @@ static void __plic_toggle(void __iomem *enable_base, int hwirq, int enable)
 
 static void plic_toggle(struct plic_handler *handler, int hwirq, int enable)
 {
-	raw_spin_lock(&handler->enable_lock);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&handler->enable_lock, flags);
 	__plic_toggle(handler->enable_base, hwirq, enable);
-	raw_spin_unlock(&handler->enable_lock);
+	raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
 }
 
 static inline void plic_irq_toggle(const struct cpumask *mask,
@@ -236,6 +238,7 @@ static int plic_irq_set_type(struct irq_data *d, unsigned int type)
 static int plic_irq_suspend(void)
 {
 	unsigned int i, cpu;
+	unsigned long flags;
 	u32 __iomem *reg;
 	struct plic_priv *priv;
 
@@ -253,12 +256,12 @@ static int plic_irq_suspend(void)
 		if (!handler->present)
 			continue;
 
-		raw_spin_lock(&handler->enable_lock);
+		raw_spin_lock_irqsave(&handler->enable_lock, flags);
 		for (i = 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) {
 			reg = handler->enable_base + i * sizeof(u32);
 			handler->enable_save[i] = readl(reg);
 		}
-		raw_spin_unlock(&handler->enable_lock);
+		raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
 	}
 
 	return 0;
@@ -267,6 +270,7 @@ static int plic_irq_suspend(void)
 static void plic_irq_resume(void)
 {
 	unsigned int i, index, cpu;
+	unsigned long flags;
 	u32 __iomem *reg;
 	struct plic_priv *priv;
 
@@ -284,12 +288,12 @@ static void plic_irq_resume(void)
 		if (!handler->present)
 			continue;
 
-		raw_spin_lock(&handler->enable_lock);
+		raw_spin_lock_irqsave(&handler->enable_lock, flags);
 		for (i = 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) {
 			reg = handler->enable_base + i * sizeof(u32);
 			writel(handler->enable_save[i], reg);
 		}
-		raw_spin_unlock(&handler->enable_lock);
+		raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
 	}
 }
 
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:08 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:08 +0530
Subject: [PATCH v13 03/13] irqchip/riscv-intc: Add support for RISC-V AIA
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-4-apatel@ventanamicro.com>

The RISC-V advanced interrupt architecture (AIA) extends the per-HART
local interrupts in following ways:
1. Minimum 64 local interrupts for both RV32 and RV64
2. Ability to process multiple pending local interrupts in same
   interrupt handler
3. Priority configuration for each local interrupts
4. Special CSRs to configure/access the per-HART MSI controller

We add support for #1 and #2 described above in the RISC-V intc driver.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-intc.c | 34 ++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
index e8d01b14ccdd..bab536bbaf2c 100644
--- a/drivers/irqchip/irq-riscv-intc.c
+++ b/drivers/irqchip/irq-riscv-intc.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/smp.h>
+#include <asm/hwcap.h>
 
 static struct irq_domain *intc_domain;
 
@@ -30,6 +31,15 @@ static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
 	generic_handle_domain_irq(intc_domain, cause);
 }
 
+static asmlinkage void riscv_intc_aia_irq(struct pt_regs *regs)
+{
+	unsigned long topi;
+
+	while ((topi = csr_read(CSR_TOPI)))
+		generic_handle_domain_irq(intc_domain,
+					  topi >> TOPI_IID_SHIFT);
+}
+
 /*
  * On RISC-V systems local interrupts are masked or unmasked by writing
  * the SIE (Supervisor Interrupt Enable) CSR.  As CSRs can only be written
@@ -39,12 +49,18 @@ static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
 
 static void riscv_intc_irq_mask(struct irq_data *d)
 {
-	csr_clear(CSR_IE, BIT(d->hwirq));
+	if (IS_ENABLED(CONFIG_32BIT) && d->hwirq >= BITS_PER_LONG)
+		csr_clear(CSR_IEH, BIT(d->hwirq - BITS_PER_LONG));
+	else
+		csr_clear(CSR_IE, BIT(d->hwirq));
 }
 
 static void riscv_intc_irq_unmask(struct irq_data *d)
 {
-	csr_set(CSR_IE, BIT(d->hwirq));
+	if (IS_ENABLED(CONFIG_32BIT) && d->hwirq >= BITS_PER_LONG)
+		csr_set(CSR_IEH, BIT(d->hwirq - BITS_PER_LONG));
+	else
+		csr_set(CSR_IE, BIT(d->hwirq));
 }
 
 static void riscv_intc_irq_eoi(struct irq_data *d)
@@ -115,16 +131,20 @@ static struct fwnode_handle *riscv_intc_hwnode(void)
 
 static int __init riscv_intc_init_common(struct fwnode_handle *fn)
 {
-	int rc;
+	int rc, nr_irqs = riscv_isa_extension_available(NULL, SxAIA) ?
+			  64 : BITS_PER_LONG;
 
-	intc_domain = irq_domain_create_linear(fn, BITS_PER_LONG,
+	intc_domain = irq_domain_create_linear(fn, nr_irqs,
 					       &riscv_intc_domain_ops, NULL);
 	if (!intc_domain) {
 		pr_err("unable to add IRQ domain\n");
 		return -ENXIO;
 	}
 
-	rc = set_handle_irq(&riscv_intc_irq);
+	if (riscv_isa_extension_available(NULL, SxAIA))
+		rc = set_handle_irq(&riscv_intc_aia_irq);
+	else
+		rc = set_handle_irq(&riscv_intc_irq);
 	if (rc) {
 		pr_err("failed to set irq handler\n");
 		return rc;
@@ -132,7 +152,9 @@ static int __init riscv_intc_init_common(struct fwnode_handle *fn)
 
 	riscv_set_intc_hwnode_fn(riscv_intc_hwnode);
 
-	pr_info("%d local interrupts mapped\n", BITS_PER_LONG);
+	pr_info("%d local interrupts mapped%s\n",
+		nr_irqs, riscv_isa_extension_available(NULL, SxAIA) ?
+			 " using AIA" : "");
 
 	return 0;
 }
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:09 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:09 +0530
Subject: [PATCH v13 04/13] dt-bindings: interrupt-controller: Add RISC-V incoming MSI controller
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-5-apatel@ventanamicro.com>

We add DT bindings document for the RISC-V incoming MSI controller
(IMSIC) defined by the RISC-V advanced interrupt architecture (AIA)
specification.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../interrupt-controller/riscv,imsics.yaml    | 172 ++++++++++++++++++
 1 file changed, 172 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml b/Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
new file mode 100644
index 000000000000..84976f17a4a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
@@ -0,0 +1,172 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/riscv,imsics.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Incoming MSI Controller (IMSIC)
+
+maintainers:
+  - Anup Patel <anup at brainfault.org>
+
+description: |
+  The RISC-V advanced interrupt architecture (AIA) defines a per-CPU incoming
+  MSI controller (IMSIC) for handling MSIs in a RISC-V platform. The RISC-V
+  AIA specification can be found at https://github.com/riscv/riscv-aia.
+
+  The IMSIC is a per-CPU (or per-HART) device with separate interrupt file
+  for each privilege level (machine or supervisor). The configuration of
+  a IMSIC interrupt file is done using AIA CSRs and it also has a 4KB MMIO
+  space to receive MSIs from devices. Each IMSIC interrupt file supports a
+  fixed number of interrupt identities (to distinguish MSIs from devices)
+  which is same for given privilege level across CPUs (or HARTs).
+
+  The device tree of a RISC-V platform will have one IMSIC device tree node
+  for each privilege level (machine or supervisor) which collectively describe
+  IMSIC interrupt files at that privilege level across CPUs (or HARTs).
+
+  The arrangement of IMSIC interrupt files in MMIO space of a RISC-V platform
+  follows a particular scheme defined by the RISC-V AIA specification. A IMSIC
+  group is a set of IMSIC interrupt files co-located in MMIO space and we can
+  have multiple IMSIC groups (i.e. clusters, sockets, chiplets, etc) in a
+  RISC-V platform. The MSI target address of a IMSIC interrupt file at given
+  privilege level (machine or supervisor) encodes group index, HART index,
+  and guest index (shown below).
+
+  XLEN-1            > (HART Index MSB)                  12    0
+  |                  |                                  |     |
+  -------------------------------------------------------------
+  |xxxxxx|Group Index|xxxxxxxxxxx|HART Index|Guest Index|  0  |
+  -------------------------------------------------------------
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+  - $ref: /schemas/interrupt-controller/msi-controller.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - qemu,imsics
+      - const: riscv,imsics
+
+  reg:
+    minItems: 1
+    maxItems: 16384
+    description:
+      Base address of each IMSIC group.
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 0
+
+  msi-controller: true
+
+  "#msi-cells":
+    const: 0
+
+  interrupts-extended:
+    minItems: 1
+    maxItems: 16384
+    description:
+      This property represents the set of CPUs (or HARTs) for which given
+      device tree node describes the IMSIC interrupt files. Each node pointed
+      to should be a riscv,cpu-intc node, which has a CPU node (i.e. RISC-V
+      HART) as parent.
+
+  riscv,num-ids:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 63
+    maximum: 2047
+    description:
+      Number of interrupt identities supported by IMSIC interrupt file.
+
+  riscv,num-guest-ids:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 63
+    maximum: 2047
+    description:
+      Number of interrupt identities are supported by IMSIC guest interrupt
+      file. When not specified it is assumed to be same as specified by the
+      riscv,num-ids property.
+
+  riscv,guest-index-bits:
+    minimum: 0
+    maximum: 7
+    default: 0
+    description:
+      Number of guest index bits in the MSI target address.
+
+  riscv,hart-index-bits:
+    minimum: 0
+    maximum: 15
+    description:
+      Number of HART index bits in the MSI target address. When not
+      specified it is calculated based on the interrupts-extended property.
+
+  riscv,group-index-bits:
+    minimum: 0
+    maximum: 7
+    default: 0
+    description:
+      Number of group index bits in the MSI target address.
+
+  riscv,group-index-shift:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 55
+    default: 24
+    description:
+      The least significant bit position of the group index bits in the
+      MSI target address.
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - msi-controller
+  - "#msi-cells"
+  - interrupts-extended
+  - riscv,num-ids
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    // Example 1 (Machine-level IMSIC files with just one group):
+
+    interrupt-controller at 24000000 {
+      compatible = "qemu,imsics", "riscv,imsics";
+      interrupts-extended = <&cpu1_intc 11>,
+                            <&cpu2_intc 11>,
+                            <&cpu3_intc 11>,
+                            <&cpu4_intc 11>;
+      reg = <0x28000000 0x4000>;
+      interrupt-controller;
+      #interrupt-cells = <0>;
+      msi-controller;
+      #msi-cells = <0>;
+      riscv,num-ids = <127>;
+    };
+
+  - |
+    // Example 2 (Supervisor-level IMSIC files with two groups):
+
+    interrupt-controller at 28000000 {
+      compatible = "qemu,imsics", "riscv,imsics";
+      interrupts-extended = <&cpu1_intc 9>,
+                            <&cpu2_intc 9>,
+                            <&cpu3_intc 9>,
+                            <&cpu4_intc 9>;
+      reg = <0x28000000 0x2000>, /* Group0 IMSICs */
+            <0x29000000 0x2000>; /* Group1 IMSICs */
+      interrupt-controller;
+      #interrupt-cells = <0>;
+      msi-controller;
+      #msi-cells = <0>;
+      riscv,num-ids = <127>;
+      riscv,group-index-bits = <1>;
+      riscv,group-index-shift = <24>;
+    };
+...
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:10 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:10 +0530
Subject: [PATCH v13 05/13] genirq/matrix: Dynamic bitmap allocation
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-6-apatel@ventanamicro.com>

From: Bj?rn T?pel <bjorn at rivosinc.com>

Some (future) users of the irq matrix allocator, do not know the size
of the matrix bitmaps at compile time.

To avoid wasting memory on unnecessary large bitmaps, size the bitmap
at matrix allocation time.

Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 arch/x86/include/asm/hw_irq.h |  2 --
 kernel/irq/matrix.c           | 28 +++++++++++++++++-----------
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index b02c3cd3c0f6..edebf1020e04 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -16,8 +16,6 @@
 
 #include <asm/irq_vectors.h>
 
-#define IRQ_MATRIX_BITS		NR_VECTORS
-
 #ifndef __ASSEMBLY__
 
 #include <linux/percpu.h>
diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c
index 75d0ae490e29..8f222d1cccec 100644
--- a/kernel/irq/matrix.c
+++ b/kernel/irq/matrix.c
@@ -8,8 +8,6 @@
 #include <linux/cpu.h>
 #include <linux/irq.h>
 
-#define IRQ_MATRIX_SIZE	(BITS_TO_LONGS(IRQ_MATRIX_BITS))
-
 struct cpumap {
 	unsigned int		available;
 	unsigned int		allocated;
@@ -17,8 +15,8 @@ struct cpumap {
 	unsigned int		managed_allocated;
 	bool			initialized;
 	bool			online;
-	unsigned long		alloc_map[IRQ_MATRIX_SIZE];
-	unsigned long		managed_map[IRQ_MATRIX_SIZE];
+	unsigned long		*managed_map;
+	unsigned long		alloc_map[];
 };
 
 struct irq_matrix {
@@ -32,8 +30,8 @@ struct irq_matrix {
 	unsigned int		total_allocated;
 	unsigned int		online_maps;
 	struct cpumap __percpu	*maps;
-	unsigned long		scratch_map[IRQ_MATRIX_SIZE];
-	unsigned long		system_map[IRQ_MATRIX_SIZE];
+	unsigned long		*system_map;
+	unsigned long		scratch_map[];
 };
 
 #define CREATE_TRACE_POINTS
@@ -50,24 +48,32 @@ __init struct irq_matrix *irq_alloc_matrix(unsigned int matrix_bits,
 					   unsigned int alloc_start,
 					   unsigned int alloc_end)
 {
+	unsigned int cpu, matrix_size = BITS_TO_LONGS(matrix_bits);
 	struct irq_matrix *m;
 
-	if (matrix_bits > IRQ_MATRIX_BITS)
-		return NULL;
-
-	m = kzalloc(sizeof(*m), GFP_KERNEL);
+	m = kzalloc(struct_size(m, scratch_map, matrix_size * 2), GFP_KERNEL);
 	if (!m)
 		return NULL;
 
+	m->system_map = &m->scratch_map[matrix_size];
+
 	m->matrix_bits = matrix_bits;
 	m->alloc_start = alloc_start;
 	m->alloc_end = alloc_end;
 	m->alloc_size = alloc_end - alloc_start;
-	m->maps = alloc_percpu(*m->maps);
+	m->maps = __alloc_percpu(struct_size(m->maps, alloc_map, matrix_size * 2),
+				 __alignof__(*m->maps));
 	if (!m->maps) {
 		kfree(m);
 		return NULL;
 	}
+
+	for_each_possible_cpu(cpu) {
+		struct cpumap *cm = per_cpu_ptr(m->maps, cpu);
+
+		cm->managed_map = &cm->alloc_map[matrix_size];
+	}
+
 	return m;
 }
 
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:13 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:13 +0530
Subject: [PATCH v13 08/13] irqchip/riscv-imsic: Add device MSI domain support for PCI devices
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-9-apatel@ventanamicro.com>

The Linux PCI framework supports per-device MSI domains for PCI devices
so let us extend the IMSIC driver to allow per-device MSI domains for
PCI devices.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                    |  7 +++++
 drivers/irqchip/irq-riscv-imsic-platform.c | 36 ++++++++++++++++++++--
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 85f86e31c996..2fc0cb32341a 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -553,6 +553,13 @@ config RISCV_IMSIC
 	select GENERIC_IRQ_MATRIX_ALLOCATOR
 	select GENERIC_MSI_IRQ
 
+config RISCV_IMSIC_PCI
+	bool
+	depends on RISCV_IMSIC
+	depends on PCI
+	depends on PCI_MSI
+	default RISCV_IMSIC
+
 config EXYNOS_IRQ_COMBINER
 	bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
 	depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 7ee44c493dbc..37f47375d5b7 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -14,6 +14,7 @@
 #include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/msi.h>
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/smp.h>
@@ -209,6 +210,28 @@ static const struct irq_domain_ops imsic_base_domain_ops = {
 #endif
 };
 
+#ifdef CONFIG_RISCV_IMSIC_PCI
+
+static void imsic_pci_mask_irq(struct irq_data *d)
+{
+	pci_msi_mask_irq(d);
+	irq_chip_mask_parent(d);
+}
+
+static void imsic_pci_unmask_irq(struct irq_data *d)
+{
+	irq_chip_unmask_parent(d);
+	pci_msi_unmask_irq(d);
+}
+
+#define MATCH_PCI_MSI		BIT(DOMAIN_BUS_PCI_MSI)
+
+#else
+
+#define MATCH_PCI_MSI		0
+
+#endif
+
 static bool imsic_init_dev_msi_info(struct device *dev,
 				    struct irq_domain *domain,
 				    struct irq_domain *real_parent,
@@ -218,6 +241,7 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 
 	/* MSI parent domain specific settings */
 	switch (real_parent->bus_token) {
+	case DOMAIN_BUS_PCI_MSI:
 	case DOMAIN_BUS_NEXUS:
 		if (WARN_ON_ONCE(domain != real_parent))
 			return false;
@@ -232,6 +256,13 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 
 	/* Is the target supported? */
 	switch (info->bus_token) {
+#ifdef CONFIG_RISCV_IMSIC_PCI
+	case DOMAIN_BUS_PCI_DEVICE_MSI:
+	case DOMAIN_BUS_PCI_DEVICE_MSIX:
+		info->chip->irq_mask = imsic_pci_mask_irq;
+		info->chip->irq_unmask = imsic_pci_unmask_irq;
+		break;
+#endif
 	case DOMAIN_BUS_DEVICE_MSI:
 		/*
 		 * Per-device MSI should never have any MSI feature bits
@@ -271,11 +302,12 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 #define MATCH_PLATFORM_MSI		BIT(DOMAIN_BUS_PLATFORM_MSI)
 
 static const struct msi_parent_ops imsic_msi_parent_ops = {
-	.supported_flags	= MSI_GENERIC_FLAGS_MASK,
+	.supported_flags	= MSI_GENERIC_FLAGS_MASK |
+				  MSI_FLAG_PCI_MSIX,
 	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
 				  MSI_FLAG_USE_DEF_CHIP_OPS,
 	.bus_select_token	= DOMAIN_BUS_NEXUS,
-	.bus_select_mask	= MATCH_PLATFORM_MSI,
+	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
 	.init_dev_msi_info	= imsic_init_dev_msi_info,
 };
 
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:15 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:15 +0530
Subject: [PATCH v13 10/13] irqchip: Add RISC-V advanced PLIC driver for direct-mode
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-11-apatel@ventanamicro.com>

The RISC-V advanced interrupt architecture (AIA) specification defines
advanced platform-level interrupt controller (APLIC) which has two modes
of operation: 1) Direct mode and 2) MSI mode.
(For more details, refer https://github.com/riscv/riscv-aia)

In APLIC direct-mode, wired interrupts are forwared to CPUs (or HARTs)
as a local external interrupt.

We add a platform irqchip driver for the RISC-V APLIC direct-mode to
support RISC-V platforms having only wired interrupts.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                  |   5 +
 drivers/irqchip/Makefile                 |   1 +
 drivers/irqchip/irq-riscv-aplic-direct.c | 324 +++++++++++++++++++++++
 drivers/irqchip/irq-riscv-aplic-main.c   | 211 +++++++++++++++
 drivers/irqchip/irq-riscv-aplic-main.h   |  44 +++
 include/linux/irqchip/riscv-aplic.h      | 145 ++++++++++
 6 files changed, 730 insertions(+)
 create mode 100644 drivers/irqchip/irq-riscv-aplic-direct.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.h
 create mode 100644 include/linux/irqchip/riscv-aplic.h

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 2fc0cb32341a..dbc8811d3764 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -546,6 +546,11 @@ config SIFIVE_PLIC
 	select IRQ_DOMAIN_HIERARCHY
 	select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
 
+config RISCV_APLIC
+	bool
+	depends on RISCV
+	select IRQ_DOMAIN_HIERARCHY
+
 config RISCV_IMSIC
 	bool
 	depends on RISCV
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index abca445a3229..7f8289790ed8 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
 obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
+obj-$(CONFIG_RISCV_APLIC)		+= irq-riscv-aplic-main.o irq-riscv-aplic-direct.o
 obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
diff --git a/drivers/irqchip/irq-riscv-aplic-direct.c b/drivers/irqchip/irq-riscv-aplic-direct.c
new file mode 100644
index 000000000000..2430d6b81026
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-direct.c
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/riscv-aplic.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/printk.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-aplic-main.h"
+
+#define APLIC_DISABLE_IDELIVERY		0
+#define APLIC_ENABLE_IDELIVERY		1
+#define APLIC_DISABLE_ITHRESHOLD	1
+#define APLIC_ENABLE_ITHRESHOLD		0
+
+struct aplic_direct {
+	struct aplic_priv	priv;
+	struct irq_domain	*irqdomain;
+	struct cpumask		lmask;
+};
+
+struct aplic_idc {
+	unsigned int		hart_index;
+	void __iomem		*regs;
+	struct aplic_direct	*direct;
+};
+
+static unsigned int aplic_direct_parent_irq;
+static DEFINE_PER_CPU(struct aplic_idc, aplic_idcs);
+
+static void aplic_direct_irq_eoi(struct irq_data *d)
+{
+	/*
+	 * The fasteoi_handler requires irq_eoi() callback hence
+	 * provide a dummy handler.
+	 */
+}
+
+#ifdef CONFIG_SMP
+static int aplic_direct_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+				     bool force)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	struct aplic_direct *direct = container_of(priv, struct aplic_direct, priv);
+	struct aplic_idc *idc;
+	unsigned int cpu, val;
+	struct cpumask amask;
+	void __iomem *target;
+
+	cpumask_and(&amask, &direct->lmask, mask_val);
+
+	if (force)
+		cpu = cpumask_first(&amask);
+	else
+		cpu = cpumask_any_and(&amask, cpu_online_mask);
+
+	if (cpu >= nr_cpu_ids)
+		return -EINVAL;
+
+	idc = per_cpu_ptr(&aplic_idcs, cpu);
+	target = priv->regs + APLIC_TARGET_BASE + (d->hwirq - 1) * sizeof(u32);
+	val = FIELD_PREP(APLIC_TARGET_HART_IDX, idc->hart_index);
+	val |= FIELD_PREP(APLIC_TARGET_IPRIO, APLIC_DEFAULT_PRIORITY);
+	writel(val, target);
+
+	irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
+	return IRQ_SET_MASK_OK_DONE;
+}
+#endif
+
+static struct irq_chip aplic_direct_chip = {
+	.name		= "APLIC-DIRECT",
+	.irq_mask	= aplic_irq_mask,
+	.irq_unmask	= aplic_irq_unmask,
+	.irq_set_type	= aplic_irq_set_type,
+	.irq_eoi	= aplic_direct_irq_eoi,
+#ifdef CONFIG_SMP
+	.irq_set_affinity = aplic_direct_set_affinity,
+#endif
+	.flags		= IRQCHIP_SET_TYPE_MASKED |
+			  IRQCHIP_SKIP_SET_WAKE |
+			  IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static int aplic_direct_irqdomain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
+					    unsigned long *hwirq, unsigned int *type)
+{
+	struct aplic_priv *priv = d->host_data;
+
+	return aplic_irqdomain_translate(fwspec, priv->gsi_base, hwirq, type);
+}
+
+static int aplic_direct_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
+					unsigned int nr_irqs, void *arg)
+{
+	struct aplic_priv *priv = domain->host_data;
+	struct aplic_direct *direct = container_of(priv, struct aplic_direct, priv);
+	struct irq_fwspec *fwspec = arg;
+	irq_hw_number_t hwirq;
+	unsigned int type;
+	int i, ret;
+
+	ret = aplic_irqdomain_translate(fwspec, priv->gsi_base, &hwirq, &type);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nr_irqs; i++) {
+		irq_domain_set_info(domain, virq + i, hwirq + i, &aplic_direct_chip,
+				    priv, handle_fasteoi_irq, NULL, NULL);
+		irq_set_affinity(virq + i, &direct->lmask);
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops aplic_direct_irqdomain_ops = {
+	.translate	= aplic_direct_irqdomain_translate,
+	.alloc		= aplic_direct_irqdomain_alloc,
+	.free		= irq_domain_free_irqs_top,
+};
+
+/*
+ * To handle an APLIC direct interrupts, we just read the CLAIMI register
+ * which will return highest priority pending interrupt and clear the
+ * pending bit of the interrupt. This process is repeated until CLAIMI
+ * register return zero value.
+ */
+static void aplic_direct_handle_irq(struct irq_desc *desc)
+{
+	struct aplic_idc *idc = this_cpu_ptr(&aplic_idcs);
+	struct irq_domain *irqdomain = idc->direct->irqdomain;
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	irq_hw_number_t hw_irq;
+	int irq;
+
+	chained_irq_enter(chip, desc);
+
+	while ((hw_irq = readl(idc->regs + APLIC_IDC_CLAIMI))) {
+		hw_irq = hw_irq >> APLIC_IDC_TOPI_ID_SHIFT;
+		irq = irq_find_mapping(irqdomain, hw_irq);
+
+		if (unlikely(irq <= 0))
+			dev_warn_ratelimited(idc->direct->priv.dev,
+					     "hw_irq %lu mapping not found\n", hw_irq);
+		else
+			generic_handle_irq(irq);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static void aplic_idc_set_delivery(struct aplic_idc *idc, bool en)
+{
+	u32 de = (en) ? APLIC_ENABLE_IDELIVERY : APLIC_DISABLE_IDELIVERY;
+	u32 th = (en) ? APLIC_ENABLE_ITHRESHOLD : APLIC_DISABLE_ITHRESHOLD;
+
+	/* Priority must be less than threshold for interrupt triggering */
+	writel(th, idc->regs + APLIC_IDC_ITHRESHOLD);
+
+	/* Delivery must be set to 1 for interrupt triggering */
+	writel(de, idc->regs + APLIC_IDC_IDELIVERY);
+}
+
+static int aplic_direct_dying_cpu(unsigned int cpu)
+{
+	if (aplic_direct_parent_irq)
+		disable_percpu_irq(aplic_direct_parent_irq);
+
+	return 0;
+}
+
+static int aplic_direct_starting_cpu(unsigned int cpu)
+{
+	if (aplic_direct_parent_irq)
+		enable_percpu_irq(aplic_direct_parent_irq,
+				  irq_get_trigger_type(aplic_direct_parent_irq));
+
+	return 0;
+}
+
+static int aplic_direct_parse_parent_hwirq(struct device *dev, u32 index,
+					   u32 *parent_hwirq, unsigned long *parent_hartid)
+{
+	struct of_phandle_args parent;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	rc = of_irq_parse_one(to_of_node(dev->fwnode), index, &parent);
+	if (rc)
+		return rc;
+
+	rc = riscv_of_parent_hartid(parent.np, parent_hartid);
+	if (rc)
+		return rc;
+
+	*parent_hwirq = parent.args[0];
+	return 0;
+}
+
+int aplic_direct_setup(struct device *dev, void __iomem *regs)
+{
+	int i, j, rc, cpu, current_cpu, setup_count = 0;
+	struct aplic_direct *direct;
+	struct irq_domain *domain;
+	struct aplic_priv *priv;
+	struct aplic_idc *idc;
+	unsigned long hartid;
+	u32 v, hwirq;
+
+	direct = devm_kzalloc(dev, sizeof(*direct), GFP_KERNEL);
+	if (!direct)
+		return -ENOMEM;
+	priv = &direct->priv;
+
+	rc = aplic_setup_priv(priv, dev, regs);
+	if (rc) {
+		dev_err(dev, "failed to create APLIC context\n");
+		return rc;
+	}
+
+	/* Setup per-CPU IDC and target CPU mask */
+	current_cpu = get_cpu();
+	for (i = 0; i < priv->nr_idcs; i++) {
+		rc = aplic_direct_parse_parent_hwirq(dev, i, &hwirq, &hartid);
+		if (rc) {
+			dev_warn(dev, "parent irq for IDC%d not found\n", i);
+			continue;
+		}
+
+		/*
+		 * Skip interrupts other than external interrupts for
+		 * current privilege level.
+		 */
+		if (hwirq != RV_IRQ_EXT)
+			continue;
+
+		cpu = riscv_hartid_to_cpuid(hartid);
+		if (cpu < 0) {
+			dev_warn(dev, "invalid cpuid for IDC%d\n", i);
+			continue;
+		}
+
+		cpumask_set_cpu(cpu, &direct->lmask);
+
+		idc = per_cpu_ptr(&aplic_idcs, cpu);
+		idc->hart_index = i;
+		idc->regs = priv->regs + APLIC_IDC_BASE + i * APLIC_IDC_SIZE;
+		idc->direct = direct;
+
+		aplic_idc_set_delivery(idc, true);
+
+		/*
+		 * Boot cpu might not have APLIC hart_index = 0 so check
+		 * and update target registers of all interrupts.
+		 */
+		if (cpu == current_cpu && idc->hart_index) {
+			v = FIELD_PREP(APLIC_TARGET_HART_IDX, idc->hart_index);
+			v |= FIELD_PREP(APLIC_TARGET_IPRIO, APLIC_DEFAULT_PRIORITY);
+			for (j = 1; j <= priv->nr_irqs; j++)
+				writel(v, priv->regs + APLIC_TARGET_BASE + (j - 1) * sizeof(u32));
+		}
+
+		setup_count++;
+	}
+	put_cpu();
+
+	/* Find parent domain and register chained handler */
+	domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(),
+					  DOMAIN_BUS_ANY);
+	if (!aplic_direct_parent_irq && domain) {
+		aplic_direct_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
+		if (aplic_direct_parent_irq) {
+			irq_set_chained_handler(aplic_direct_parent_irq,
+						aplic_direct_handle_irq);
+
+			/*
+			 * Setup CPUHP notifier to enable parent
+			 * interrupt on all CPUs
+			 */
+			cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
+					  "irqchip/riscv/aplic:starting",
+					  aplic_direct_starting_cpu,
+					  aplic_direct_dying_cpu);
+		}
+	}
+
+	/* Fail if we were not able to setup IDC for any CPU */
+	if (!setup_count)
+		return -ENODEV;
+
+	/* Setup global config and interrupt delivery */
+	aplic_init_hw_global(priv, false);
+
+	/* Create irq domain instance for the APLIC */
+	direct->irqdomain = irq_domain_create_linear(dev->fwnode, priv->nr_irqs + 1,
+						     &aplic_direct_irqdomain_ops, priv);
+	if (!direct->irqdomain) {
+		dev_err(dev, "failed to create direct irq domain\n");
+		return -ENOMEM;
+	}
+
+	/* Advertise the interrupt controller */
+	dev_info(dev, "%d interrupts directly connected to %d CPUs\n",
+		 priv->nr_irqs, priv->nr_idcs);
+
+	return 0;
+}
diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
new file mode 100644
index 000000000000..e6617147daff
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/irqchip/riscv-aplic.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+
+#include "irq-riscv-aplic-main.h"
+
+void aplic_irq_unmask(struct irq_data *d)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+
+	writel(d->hwirq, priv->regs + APLIC_SETIENUM);
+}
+
+void aplic_irq_mask(struct irq_data *d)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+
+	writel(d->hwirq, priv->regs + APLIC_CLRIENUM);
+}
+
+int aplic_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	void __iomem *sourcecfg;
+	u32 val = 0;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		val = APLIC_SOURCECFG_SM_INACTIVE;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		val = APLIC_SOURCECFG_SM_LEVEL_LOW;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		val = APLIC_SOURCECFG_SM_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		val = APLIC_SOURCECFG_SM_EDGE_FALL;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		val = APLIC_SOURCECFG_SM_EDGE_RISE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sourcecfg = priv->regs + APLIC_SOURCECFG_BASE;
+	sourcecfg += (d->hwirq - 1) * sizeof(u32);
+	writel(val, sourcecfg);
+
+	return 0;
+}
+
+int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
+			      unsigned long *hwirq, unsigned int *type)
+{
+	if (WARN_ON(fwspec->param_count < 2))
+		return -EINVAL;
+	if (WARN_ON(!fwspec->param[0]))
+		return -EINVAL;
+
+	/* For DT, gsi_base is always zero. */
+	*hwirq = fwspec->param[0] - gsi_base;
+	*type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
+
+	WARN_ON(*type == IRQ_TYPE_NONE);
+
+	return 0;
+}
+
+void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
+{
+	u32 val;
+#ifdef CONFIG_RISCV_M_MODE
+	u32 valH;
+
+	if (msi_mode) {
+		val = lower_32_bits(priv->msicfg.base_ppn);
+		valH = FIELD_PREP(APLIC_xMSICFGADDRH_BAPPN, upper_32_bits(priv->msicfg.base_ppn));
+		valH |= FIELD_PREP(APLIC_xMSICFGADDRH_LHXW, priv->msicfg.lhxw);
+		valH |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXW, priv->msicfg.hhxw);
+		valH |= FIELD_PREP(APLIC_xMSICFGADDRH_LHXS, priv->msicfg.lhxs);
+		valH |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXS, priv->msicfg.hhxs);
+		writel(val, priv->regs + APLIC_xMSICFGADDR);
+		writel(valH, priv->regs + APLIC_xMSICFGADDRH);
+	}
+#endif
+
+	/* Setup APLIC domaincfg register */
+	val = readl(priv->regs + APLIC_DOMAINCFG);
+	val |= APLIC_DOMAINCFG_IE;
+	if (msi_mode)
+		val |= APLIC_DOMAINCFG_DM;
+	writel(val, priv->regs + APLIC_DOMAINCFG);
+	if (readl(priv->regs + APLIC_DOMAINCFG) != val)
+		dev_warn(priv->dev, "unable to write 0x%x in domaincfg\n", val);
+}
+
+static void aplic_init_hw_irqs(struct aplic_priv *priv)
+{
+	int i;
+
+	/* Disable all interrupts */
+	for (i = 0; i <= priv->nr_irqs; i += 32)
+		writel(-1U, priv->regs + APLIC_CLRIE_BASE + (i / 32) * sizeof(u32));
+
+	/* Set interrupt type and default priority for all interrupts */
+	for (i = 1; i <= priv->nr_irqs; i++) {
+		writel(0, priv->regs + APLIC_SOURCECFG_BASE + (i - 1) * sizeof(u32));
+		writel(APLIC_DEFAULT_PRIORITY,
+		       priv->regs + APLIC_TARGET_BASE + (i - 1) * sizeof(u32));
+	}
+
+	/* Clear APLIC domaincfg */
+	writel(0, priv->regs + APLIC_DOMAINCFG);
+}
+
+int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs)
+{
+	struct of_phandle_args parent;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	/* Save device pointer and register base */
+	priv->dev = dev;
+	priv->regs = regs;
+
+	/* Find out number of interrupt sources */
+	rc = of_property_read_u32(to_of_node(dev->fwnode), "riscv,num-sources",
+					     &priv->nr_irqs);
+	if (rc) {
+		dev_err(dev, "failed to get number of interrupt sources\n");
+		return rc;
+	}
+
+	/*
+	 * Find out number of IDCs based on parent interrupts
+	 *
+	 * If "msi-parent" property is present then we ignore the
+	 * APLIC IDCs which forces the APLIC driver to use MSI mode.
+	 */
+	if (!of_property_present(to_of_node(dev->fwnode), "msi-parent")) {
+		while (!of_irq_parse_one(to_of_node(dev->fwnode), priv->nr_idcs, &parent))
+			priv->nr_idcs++;
+	}
+
+	/* Setup initial state APLIC interrupts */
+	aplic_init_hw_irqs(priv);
+
+	return 0;
+}
+
+static int aplic_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	bool msi_mode = false;
+	void __iomem *regs;
+	int rc;
+
+	/* Map the MMIO registers */
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (!regs) {
+		dev_err(dev, "failed map MMIO registers\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * If msi-parent property is present then setup APLIC MSI
+	 * mode otherwise setup APLIC direct mode.
+	 */
+	if (is_of_node(dev->fwnode))
+		msi_mode = of_property_present(to_of_node(dev->fwnode), "msi-parent");
+	if (msi_mode)
+		rc = -ENODEV;
+	else
+		rc = aplic_direct_setup(dev, regs);
+	if (rc)
+		dev_err(dev, "failed to setup APLIC in %s mode\n", msi_mode ? "MSI" : "direct");
+
+	return rc;
+}
+
+static const struct of_device_id aplic_match[] = {
+	{ .compatible = "riscv,aplic" },
+	{}
+};
+
+static struct platform_driver aplic_driver = {
+	.driver = {
+		.name		= "riscv-aplic",
+		.of_match_table	= aplic_match,
+	},
+	.probe = aplic_probe,
+};
+builtin_platform_driver(aplic_driver);
diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h
new file mode 100644
index 000000000000..4cfbadf37ddc
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-main.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#ifndef _IRQ_RISCV_APLIC_MAIN_H
+#define _IRQ_RISCV_APLIC_MAIN_H
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/fwnode.h>
+
+#define APLIC_DEFAULT_PRIORITY		1
+
+struct aplic_msicfg {
+	phys_addr_t		base_ppn;
+	u32			hhxs;
+	u32			hhxw;
+	u32			lhxs;
+	u32			lhxw;
+};
+
+struct aplic_priv {
+	struct device		*dev;
+	u32			gsi_base;
+	u32			nr_irqs;
+	u32			nr_idcs;
+	void __iomem		*regs;
+	struct aplic_msicfg	msicfg;
+};
+
+void aplic_irq_unmask(struct irq_data *d);
+void aplic_irq_mask(struct irq_data *d);
+int aplic_irq_set_type(struct irq_data *d, unsigned int type);
+int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
+			      unsigned long *hwirq, unsigned int *type);
+void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode);
+int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs);
+int aplic_direct_setup(struct device *dev, void __iomem *regs);
+
+#endif
diff --git a/include/linux/irqchip/riscv-aplic.h b/include/linux/irqchip/riscv-aplic.h
new file mode 100644
index 000000000000..ec8f7df50583
--- /dev/null
+++ b/include/linux/irqchip/riscv-aplic.h
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+#ifndef __LINUX_IRQCHIP_RISCV_APLIC_H
+#define __LINUX_IRQCHIP_RISCV_APLIC_H
+
+#include <linux/bitops.h>
+
+#define APLIC_MAX_IDC			BIT(14)
+#define APLIC_MAX_SOURCE		1024
+
+#define APLIC_DOMAINCFG			0x0000
+#define APLIC_DOMAINCFG_RDONLY		0x80000000
+#define APLIC_DOMAINCFG_IE		BIT(8)
+#define APLIC_DOMAINCFG_DM		BIT(2)
+#define APLIC_DOMAINCFG_BE		BIT(0)
+
+#define APLIC_SOURCECFG_BASE		0x0004
+#define APLIC_SOURCECFG_D		BIT(10)
+#define APLIC_SOURCECFG_CHILDIDX_MASK	0x000003ff
+#define APLIC_SOURCECFG_SM_MASK	0x00000007
+#define APLIC_SOURCECFG_SM_INACTIVE	0x0
+#define APLIC_SOURCECFG_SM_DETACH	0x1
+#define APLIC_SOURCECFG_SM_EDGE_RISE	0x4
+#define APLIC_SOURCECFG_SM_EDGE_FALL	0x5
+#define APLIC_SOURCECFG_SM_LEVEL_HIGH	0x6
+#define APLIC_SOURCECFG_SM_LEVEL_LOW	0x7
+
+#define APLIC_MMSICFGADDR		0x1bc0
+#define APLIC_MMSICFGADDRH		0x1bc4
+#define APLIC_SMSICFGADDR		0x1bc8
+#define APLIC_SMSICFGADDRH		0x1bcc
+
+#ifdef CONFIG_RISCV_M_MODE
+#define APLIC_xMSICFGADDR		APLIC_MMSICFGADDR
+#define APLIC_xMSICFGADDRH		APLIC_MMSICFGADDRH
+#else
+#define APLIC_xMSICFGADDR		APLIC_SMSICFGADDR
+#define APLIC_xMSICFGADDRH		APLIC_SMSICFGADDRH
+#endif
+
+#define APLIC_xMSICFGADDRH_L		BIT(31)
+#define APLIC_xMSICFGADDRH_HHXS_MASK	0x1f
+#define APLIC_xMSICFGADDRH_HHXS_SHIFT	24
+#define APLIC_xMSICFGADDRH_HHXS		(APLIC_xMSICFGADDRH_HHXS_MASK << \
+					 APLIC_xMSICFGADDRH_HHXS_SHIFT)
+#define APLIC_xMSICFGADDRH_LHXS_MASK	0x7
+#define APLIC_xMSICFGADDRH_LHXS_SHIFT	20
+#define APLIC_xMSICFGADDRH_LHXS		(APLIC_xMSICFGADDRH_LHXS_MASK << \
+					 APLIC_xMSICFGADDRH_LHXS_SHIFT)
+#define APLIC_xMSICFGADDRH_HHXW_MASK	0x7
+#define APLIC_xMSICFGADDRH_HHXW_SHIFT	16
+#define APLIC_xMSICFGADDRH_HHXW		(APLIC_xMSICFGADDRH_HHXW_MASK << \
+					 APLIC_xMSICFGADDRH_HHXW_SHIFT)
+#define APLIC_xMSICFGADDRH_LHXW_MASK	0xf
+#define APLIC_xMSICFGADDRH_LHXW_SHIFT	12
+#define APLIC_xMSICFGADDRH_LHXW		(APLIC_xMSICFGADDRH_LHXW_MASK << \
+					 APLIC_xMSICFGADDRH_LHXW_SHIFT)
+#define APLIC_xMSICFGADDRH_BAPPN_MASK	0xfff
+#define APLIC_xMSICFGADDRH_BAPPN_SHIFT	0
+#define APLIC_xMSICFGADDRH_BAPPN	(APLIC_xMSICFGADDRH_BAPPN_MASK << \
+					 APLIC_xMSICFGADDRH_BAPPN_SHIFT)
+
+#define APLIC_xMSICFGADDR_PPN_SHIFT	12
+
+#define APLIC_xMSICFGADDR_PPN_HART(__lhxs) \
+	(BIT(__lhxs) - 1)
+
+#define APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) \
+	(BIT(__lhxw) - 1)
+#define APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs) \
+	((__lhxs))
+#define APLIC_xMSICFGADDR_PPN_LHX(__lhxw, __lhxs) \
+	(APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) << \
+	 APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs))
+
+#define APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) \
+	(BIT(__hhxw) - 1)
+#define APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs) \
+	((__hhxs) + APLIC_xMSICFGADDR_PPN_SHIFT)
+#define APLIC_xMSICFGADDR_PPN_HHX(__hhxw, __hhxs) \
+	(APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) << \
+	 APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs))
+
+#define APLIC_IRQBITS_PER_REG		32
+
+#define APLIC_SETIP_BASE		0x1c00
+#define APLIC_SETIPNUM			0x1cdc
+
+#define APLIC_CLRIP_BASE		0x1d00
+#define APLIC_CLRIPNUM			0x1ddc
+
+#define APLIC_SETIE_BASE		0x1e00
+#define APLIC_SETIENUM			0x1edc
+
+#define APLIC_CLRIE_BASE		0x1f00
+#define APLIC_CLRIENUM			0x1fdc
+
+#define APLIC_SETIPNUM_LE		0x2000
+#define APLIC_SETIPNUM_BE		0x2004
+
+#define APLIC_GENMSI			0x3000
+
+#define APLIC_TARGET_BASE		0x3004
+#define APLIC_TARGET_HART_IDX_SHIFT	18
+#define APLIC_TARGET_HART_IDX_MASK	0x3fff
+#define APLIC_TARGET_HART_IDX		(APLIC_TARGET_HART_IDX_MASK << \
+					 APLIC_TARGET_HART_IDX_SHIFT)
+#define APLIC_TARGET_GUEST_IDX_SHIFT	12
+#define APLIC_TARGET_GUEST_IDX_MASK	0x3f
+#define APLIC_TARGET_GUEST_IDX		(APLIC_TARGET_GUEST_IDX_MASK << \
+					 APLIC_TARGET_GUEST_IDX_SHIFT)
+#define APLIC_TARGET_IPRIO_SHIFT	0
+#define APLIC_TARGET_IPRIO_MASK		0xff
+#define APLIC_TARGET_IPRIO		(APLIC_TARGET_IPRIO_MASK << \
+					 APLIC_TARGET_IPRIO_SHIFT)
+#define APLIC_TARGET_EIID_SHIFT		0
+#define APLIC_TARGET_EIID_MASK		0x7ff
+#define APLIC_TARGET_EIID		(APLIC_TARGET_EIID_MASK << \
+					 APLIC_TARGET_EIID_SHIFT)
+
+#define APLIC_IDC_BASE			0x4000
+#define APLIC_IDC_SIZE			32
+
+#define APLIC_IDC_IDELIVERY		0x00
+
+#define APLIC_IDC_IFORCE		0x04
+
+#define APLIC_IDC_ITHRESHOLD		0x08
+
+#define APLIC_IDC_TOPI			0x18
+#define APLIC_IDC_TOPI_ID_SHIFT		16
+#define APLIC_IDC_TOPI_ID_MASK		0x3ff
+#define APLIC_IDC_TOPI_ID		(APLIC_IDC_TOPI_ID_MASK << \
+					 APLIC_IDC_TOPI_ID_SHIFT)
+#define APLIC_IDC_TOPI_PRIO_SHIFT	0
+#define APLIC_IDC_TOPI_PRIO_MASK	0xff
+#define APLIC_IDC_TOPI_PRIO		(APLIC_IDC_TOPI_PRIO_MASK << \
+					 APLIC_IDC_TOPI_PRIO_SHIFT)
+
+#define APLIC_IDC_CLAIMI		0x1c
+
+#endif
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:11 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:11 +0530
Subject: [PATCH v13 06/13] irqchip: Add RISC-V incoming MSI controller early driver
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-7-apatel@ventanamicro.com>

The RISC-V advanced interrupt architecture (AIA) specification
defines a new MSI controller called incoming message signalled
interrupt controller (IMSIC) which manages MSI on per-HART (or
per-CPU) basis. It also supports IPIs as software injected MSIs.
(For more details refer https://github.com/riscv/riscv-aia)

Let us add an early irqchip driver for RISC-V IMSIC which sets
up the IMSIC state and provide IPIs.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                 |   7 +
 drivers/irqchip/Makefile                |   1 +
 drivers/irqchip/irq-riscv-imsic-early.c | 213 ++++++
 drivers/irqchip/irq-riscv-imsic-state.c | 906 ++++++++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.h |  98 +++
 include/linux/irqchip/riscv-imsic.h     |  87 +++
 6 files changed, 1312 insertions(+)
 create mode 100644 drivers/irqchip/irq-riscv-imsic-early.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.h
 create mode 100644 include/linux/irqchip/riscv-imsic.h

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index f7149d0f3d45..85f86e31c996 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -546,6 +546,13 @@ config SIFIVE_PLIC
 	select IRQ_DOMAIN_HIERARCHY
 	select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
 
+config RISCV_IMSIC
+	bool
+	depends on RISCV
+	select IRQ_DOMAIN_HIERARCHY
+	select GENERIC_IRQ_MATRIX_ALLOCATOR
+	select GENERIC_MSI_IRQ
+
 config EXYNOS_IRQ_COMBINER
 	bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
 	depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index ffd945fe71aa..d714724387ce 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
 obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
+obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
 obj-$(CONFIG_IMX_INTMUX)		+= irq-imx-intmux.o
diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
new file mode 100644
index 000000000000..32fe428b1c19
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "riscv-imsic: " fmt
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-imsic-state.h"
+
+static int imsic_parent_irq;
+
+#ifdef CONFIG_SMP
+static void imsic_ipi_send(unsigned int cpu)
+{
+	struct imsic_local_config *local = per_cpu_ptr(imsic->global.local, cpu);
+
+	writel_relaxed(IMSIC_IPI_ID, local->msi_va);
+}
+
+static void imsic_ipi_starting_cpu(void)
+{
+	/* Enable IPIs for current CPU. */
+	__imsic_id_set_enable(IMSIC_IPI_ID);
+}
+
+static void imsic_ipi_dying_cpu(void)
+{
+	/* Disable IPIs for current CPU. */
+	__imsic_id_clear_enable(IMSIC_IPI_ID);
+}
+
+static int __init imsic_ipi_domain_init(void)
+{
+	int virq;
+
+	/* Create IMSIC IPI multiplexing */
+	virq = ipi_mux_create(IMSIC_NR_IPI, imsic_ipi_send);
+	if (virq <= 0)
+		return (virq < 0) ? virq : -ENOMEM;
+
+	/* Set vIRQ range */
+	riscv_ipi_set_virq_range(virq, IMSIC_NR_IPI, true);
+
+	/* Announce that IMSIC is providing IPIs */
+	pr_info("%pfwP: providing IPIs using interrupt %d\n", imsic->fwnode, IMSIC_IPI_ID);
+
+	return 0;
+}
+#else
+static void imsic_ipi_starting_cpu(void)
+{
+}
+
+static void imsic_ipi_dying_cpu(void)
+{
+}
+
+static int __init imsic_ipi_domain_init(void)
+{
+	return 0;
+}
+#endif
+
+/*
+ * To handle an interrupt, we read the TOPEI CSR and write zero in one
+ * instruction. If TOPEI CSR is non-zero then we translate TOPEI.ID to
+ * Linux interrupt number and let Linux IRQ subsystem handle it.
+ */
+static void imsic_handle_irq(struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int err, cpu = smp_processor_id();
+	struct imsic_vector *vec;
+	unsigned long local_id;
+
+	chained_irq_enter(chip, desc);
+
+	while ((local_id = csr_swap(CSR_TOPEI, 0))) {
+		local_id = local_id >> TOPEI_ID_SHIFT;
+
+		if (local_id == IMSIC_IPI_ID) {
+#ifdef CONFIG_SMP
+			ipi_mux_process();
+#endif
+			continue;
+		}
+
+		if (unlikely(!imsic->base_domain))
+			continue;
+
+		vec = imsic_vector_from_local_id(cpu, local_id);
+		if (!vec) {
+			pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id);
+			continue;
+		}
+
+		err = generic_handle_domain_irq(imsic->base_domain,
+						vec->hwirq);
+		if (unlikely(err))
+			pr_warn_ratelimited("hwirq 0x%x mapping not found\n", vec->hwirq);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static int imsic_starting_cpu(unsigned int cpu)
+{
+	/* Mark per-CPU IMSIC state as online */
+	imsic_state_online();
+
+	/* Enable per-CPU parent interrupt */
+	enable_percpu_irq(imsic_parent_irq, irq_get_trigger_type(imsic_parent_irq));
+
+	/* Setup IPIs */
+	imsic_ipi_starting_cpu();
+
+	/*
+	 * Interrupts identities might have been enabled/disabled while
+	 * this CPU was not running so sync-up local enable/disable state.
+	 */
+	imsic_local_sync_all();
+
+	/* Enable local interrupt delivery */
+	imsic_local_delivery(true);
+
+	return 0;
+}
+
+static int imsic_dying_cpu(unsigned int cpu)
+{
+	/* Cleanup IPIs */
+	imsic_ipi_dying_cpu();
+
+	/* Mark per-CPU IMSIC state as offline */
+	imsic_state_offline();
+
+	return 0;
+}
+
+static int __init imsic_early_probe(struct fwnode_handle *fwnode)
+{
+	struct irq_domain *domain;
+	int rc;
+
+	/* Find parent domain and register chained handler */
+	domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS_ANY);
+	if (!domain) {
+		pr_err("%pfwP: Failed to find INTC domain\n", fwnode);
+		return -ENOENT;
+	}
+	imsic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
+	if (!imsic_parent_irq) {
+		pr_err("%pfwP: Failed to create INTC mapping\n", fwnode);
+		return -ENOENT;
+	}
+
+	/* Initialize IPI domain */
+	rc = imsic_ipi_domain_init();
+	if (rc) {
+		pr_err("%pfwP: Failed to initialize IPI domain\n", fwnode);
+		return rc;
+	}
+
+	/* Setup chained handler to the parent domain interrupt */
+	irq_set_chained_handler(imsic_parent_irq, imsic_handle_irq);
+
+	/*
+	 * Setup cpuhp state (must be done after setting imsic_parent_irq)
+	 *
+	 * Don't disable per-CPU IMSIC file when CPU goes offline
+	 * because this affects IPI and the masking/unmasking of
+	 * virtual IPIs is done via generic IPI-Mux
+	 */
+	cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "irqchip/riscv/imsic:starting",
+			  imsic_starting_cpu, imsic_dying_cpu);
+
+	return 0;
+}
+
+static int __init imsic_early_dt_init(struct device_node *node,
+				      struct device_node *parent)
+{
+	struct fwnode_handle *fwnode = &node->fwnode;
+	int rc;
+
+	/* Setup IMSIC state */
+	rc = imsic_setup_state(fwnode);
+	if (rc) {
+		pr_err("%pfwP: failed to setup state (error %d)\n",
+			fwnode, rc);
+		return rc;
+	}
+
+	/* Do early setup of IPIs */
+	rc = imsic_early_probe(fwnode);
+	if (rc)
+		return rc;
+
+	/* Ensure that OF platform device gets probed */
+	of_node_clear_flag(node, OF_POPULATED);
+	return 0;
+}
+IRQCHIP_DECLARE(riscv_imsic, "riscv,imsics", imsic_early_dt_init);
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
new file mode 100644
index 000000000000..4f347486ec7c
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -0,0 +1,906 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "riscv-imsic: " fmt
+#include <linux/cpu.h>
+#include <linux/bitmap.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <asm/hwcap.h>
+
+#include "irq-riscv-imsic-state.h"
+
+#define IMSIC_DISABLE_EIDELIVERY		0
+#define IMSIC_ENABLE_EIDELIVERY			1
+#define IMSIC_DISABLE_EITHRESHOLD		1
+#define IMSIC_ENABLE_EITHRESHOLD		0
+
+static inline void imsic_csr_write(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	csr_write(CSR_IREG, val);
+}
+
+static inline unsigned long imsic_csr_read(unsigned long reg)
+{
+	csr_write(CSR_ISELECT, reg);
+	return csr_read(CSR_IREG);
+}
+
+static inline unsigned long imsic_csr_read_clear(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	return csr_read_clear(CSR_IREG, val);
+}
+
+static inline void imsic_csr_set(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	csr_set(CSR_IREG, val);
+}
+
+static inline void imsic_csr_clear(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	csr_clear(CSR_IREG, val);
+}
+
+struct imsic_priv *imsic;
+
+const struct imsic_global_config *imsic_get_global_config(void)
+{
+	return imsic ? &imsic->global : NULL;
+}
+EXPORT_SYMBOL_GPL(imsic_get_global_config);
+
+static bool __imsic_eix_read_clear(unsigned long id, bool pend)
+{
+	unsigned long isel, imask;
+
+	isel = id / BITS_PER_LONG;
+	isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
+	isel += pend ? IMSIC_EIP0 : IMSIC_EIE0;
+	imask = BIT(id & (__riscv_xlen - 1));
+
+	return (imsic_csr_read_clear(isel, imask) & imask) ? true : false;
+}
+
+static inline bool __imsic_id_read_clear_enabled(unsigned long id)
+{
+	return __imsic_eix_read_clear(id, false);
+}
+
+static inline bool __imsic_id_read_clear_pending(unsigned long id)
+{
+	return __imsic_eix_read_clear(id, true);
+}
+
+void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val)
+{
+	unsigned long id = base_id, last_id = base_id + num_id;
+	unsigned long i, isel, ireg;
+
+	while (id < last_id) {
+		isel = id / BITS_PER_LONG;
+		isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
+		isel += (pend) ? IMSIC_EIP0 : IMSIC_EIE0;
+
+		/*
+		 * Prepare the ID mask to be programmed in the
+		 * IMSIC EIEx and EIPx registers. These registers
+		 * are XLEN-wide and we must not touch IDs which
+		 * are < base_id and >= (base_id + num_id).
+		 */
+		ireg = 0;
+		for (i = id & (__riscv_xlen - 1); (id < last_id) && (i < __riscv_xlen); i++) {
+			ireg |= BIT(i);
+			id++;
+		}
+
+		/*
+		 * The IMSIC EIEx and EIPx registers are indirectly
+		 * accessed via using ISELECT and IREG CSRs so we
+		 * need to access these CSRs without getting preempted.
+		 *
+		 * All existing users of this function call this
+		 * function with local IRQs disabled so we don't
+		 * need to do anything special here.
+		 */
+		if (val)
+			imsic_csr_set(isel, ireg);
+		else
+			imsic_csr_clear(isel, ireg);
+	}
+}
+
+/* MUST be called with lpriv->lock held */
+static void __imsic_local_sync(struct imsic_local_priv *lpriv)
+{
+	struct imsic_local_config *mlocal;
+	struct imsic_vector *vec, *mvec;
+	int i;
+
+	/* This pairs with the barrier in __imsic_remote_sync(). */
+	smp_mb();
+
+	for_each_set_bit(i, lpriv->dirty_bitmap, imsic->global.nr_ids + 1) {
+		if (!i || i == IMSIC_IPI_ID)
+			goto skip;
+		vec = &lpriv->vectors[i];
+
+		if (vec->enable)
+			__imsic_id_set_enable(i);
+		else
+			__imsic_id_clear_enable(i);
+
+		/*
+		 * If the ID was being moved to a new ID on some other CPU
+		 * then we can get a MSI during the movement so check the
+		 * ID pending bit and re-trigger the new ID on other CPU
+		 * using MMIO write.
+		 */
+		mvec = vec->move;
+		vec->move = NULL;
+		if (mvec && mvec != vec) {
+			if (__imsic_id_read_clear_pending(i)) {
+				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
+				writel_relaxed(mvec->local_id, mlocal->msi_va);
+			}
+
+			imsic_vector_free(&lpriv->vectors[i]);
+		}
+
+skip:
+		bitmap_clear(lpriv->dirty_bitmap, i, 1);
+	}
+}
+
+void imsic_local_sync_all(void)
+{
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
+	__imsic_local_sync(lpriv);
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+}
+
+void imsic_local_delivery(bool enable)
+{
+	if (enable) {
+		imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
+		imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
+		return;
+	}
+
+	imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
+	imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
+}
+
+#ifdef CONFIG_SMP
+static void imsic_local_timer_callback(struct timer_list *timer)
+{
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	__imsic_local_sync(lpriv);
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+}
+
+/* MUST be called with lpriv->lock held */
+static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
+{
+	/*
+	 * Ensure that changes to vector enable, vector move and
+	 * dirty bitmap are visible to the target CPU.
+	 *
+	 * This pairs with the barrier in __imsic_local_sync().
+	 */
+	smp_mb();
+
+	/*
+	 * We schedule a timer on the target CPU if the target CPU is not
+	 * same as the current CPU. An offline CPU will unconditionally
+	 * synchronize IDs through imsic_starting_cpu() when the
+	 * CPU is brought up.
+	 */
+	if (cpu_online(cpu)) {
+		if (cpu != smp_processor_id()) {
+			if (!timer_pending(&lpriv->timer)) {
+				lpriv->timer.expires = jiffies + 1;
+				add_timer_on(&lpriv->timer, cpu);
+			}
+		} else {
+			__imsic_local_sync(lpriv);
+		}
+	}
+}
+#else
+/* MUST be called with lpriv->lock held */
+static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
+{
+	__imsic_local_sync(lpriv);
+}
+#endif
+
+void imsic_vector_mask(struct imsic_vector *vec)
+{
+	struct imsic_local_priv *lpriv;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
+		return;
+
+	/*
+	 * This function is called through Linux irq subsystem with
+	 * irqs disabled so no need to save/restore irq flags.
+	 */
+
+	raw_spin_lock(&lpriv->lock);
+
+	vec->enable = false;
+	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
+	__imsic_remote_sync(lpriv, vec->cpu);
+
+	raw_spin_unlock(&lpriv->lock);
+}
+
+void imsic_vector_unmask(struct imsic_vector *vec)
+{
+	struct imsic_local_priv *lpriv;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
+		return;
+
+	/*
+	 * This function is called through Linux irq subsystem with
+	 * irqs disabled so no need to save/restore irq flags.
+	 */
+
+	raw_spin_lock(&lpriv->lock);
+
+	vec->enable = true;
+	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
+	__imsic_remote_sync(lpriv, vec->cpu);
+
+	raw_spin_unlock(&lpriv->lock);
+}
+
+
+bool imsic_vector_isenabled(struct imsic_vector *vec)
+{
+	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	unsigned long flags;
+	bool ret;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	ret = vec->enable;
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+
+	return ret;
+}
+
+struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec)
+{
+	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	struct imsic_vector *ret;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	ret = vec->move;
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+
+	return ret;
+}
+
+static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, struct imsic_vector *vec,
+				     bool new_enable, struct imsic_vector *new_move)
+{
+	unsigned long flags;
+	bool enabled;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+
+	/* Update enable and move details */
+	enabled = vec->enable;
+	vec->enable = new_enable;
+	vec->move = new_move;
+
+	/* Mark the vector as dirty and synchronize */
+	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
+	__imsic_remote_sync(lpriv, vec->cpu);
+
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+
+	return enabled;
+}
+
+void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec)
+{
+	struct imsic_local_priv *old_lpriv, *new_lpriv;
+	bool enabled;
+
+	if (WARN_ON(old_vec->cpu == new_vec->cpu))
+		return;
+
+	old_lpriv = per_cpu_ptr(imsic->lpriv, old_vec->cpu);
+	if (WARN_ON(&old_lpriv->vectors[old_vec->local_id] != old_vec))
+		return;
+
+	new_lpriv = per_cpu_ptr(imsic->lpriv, new_vec->cpu);
+	if (WARN_ON(&new_lpriv->vectors[new_vec->local_id] != new_vec))
+		return;
+
+	/*
+	 * Move and re-trigger the new vector based on the pending
+	 * state of the old vector because we might get a device
+	 * interrupt on the old vector while device was being moved
+	 * to the new vector.
+	 */
+	enabled = imsic_vector_move_update(old_lpriv, old_vec, false, new_vec);
+	imsic_vector_move_update(new_lpriv, new_vec, enabled, new_vec);
+}
+
+#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
+void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind)
+{
+	struct imsic_local_priv *lpriv;
+	struct imsic_vector *mvec;
+	bool is_enabled;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
+		return;
+
+	is_enabled = imsic_vector_isenabled(vec);
+	mvec = imsic_vector_get_move(vec);
+
+	seq_printf(m, "%*starget_cpu      : %5u\n", ind, "", vec->cpu);
+	seq_printf(m, "%*starget_local_id : %5u\n", ind, "", vec->local_id);
+	seq_printf(m, "%*sis_reserved     : %5u\n", ind, "",
+		   (vec->local_id <= IMSIC_IPI_ID) ? 1 : 0);
+	seq_printf(m, "%*sis_enabled      : %5u\n", ind, "", (is_enabled) ? 1 : 0);
+	seq_printf(m, "%*sis_move_pending : %5u\n", ind, "", (mvec) ? 1 : 0);
+	if (mvec) {
+		seq_printf(m, "%*smove_cpu        : %5u\n", ind, "", mvec->cpu);
+		seq_printf(m, "%*smove_local_id   : %5u\n", ind, "", mvec->local_id);
+	}
+}
+
+void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
+{
+	irq_matrix_debug_show(m, imsic->matrix, ind);
+}
+#endif
+
+struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
+{
+	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+
+	if (!lpriv || imsic->global.nr_ids < local_id)
+		return NULL;
+
+	return &lpriv->vectors[local_id];
+}
+
+struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask)
+{
+	struct imsic_vector *vec = NULL;
+	struct imsic_local_priv *lpriv;
+	unsigned long flags;
+	unsigned int cpu;
+	int local_id;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	local_id = irq_matrix_alloc(imsic->matrix, mask, false, &cpu);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+	if (local_id < 0)
+		return NULL;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+	vec = &lpriv->vectors[local_id];
+	vec->hwirq = hwirq;
+	vec->enable = false;
+	vec->move = NULL;
+
+	return vec;
+}
+
+void imsic_vector_free(struct imsic_vector *vec)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	vec->hwirq = UINT_MAX;
+	irq_matrix_free(imsic->matrix, vec->cpu, vec->local_id, false);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+}
+
+static void __init imsic_local_cleanup(void)
+{
+	int cpu;
+	struct imsic_local_priv *lpriv;
+
+	for_each_possible_cpu(cpu) {
+		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+
+		bitmap_free(lpriv->dirty_bitmap);
+		kfree(lpriv->vectors);
+	}
+
+	free_percpu(imsic->lpriv);
+}
+
+static int __init imsic_local_init(void)
+{
+	struct imsic_global_config *global = &imsic->global;
+	struct imsic_local_priv *lpriv;
+	struct imsic_vector *vec;
+	int cpu, i;
+
+	/* Allocate per-CPU private state */
+	imsic->lpriv = alloc_percpu(typeof(*(imsic->lpriv)));
+	if (!imsic->lpriv)
+		return -ENOMEM;
+
+	/* Setup per-CPU private state */
+	for_each_possible_cpu(cpu) {
+		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+
+		raw_spin_lock_init(&lpriv->lock);
+
+		/* Allocate dirty bitmap */
+		lpriv->dirty_bitmap = bitmap_zalloc(global->nr_ids + 1, GFP_KERNEL);
+		if (!lpriv->dirty_bitmap)
+			goto fail_local_cleanup;
+
+#ifdef CONFIG_SMP
+		/* Setup lazy timer for synchronization */
+		timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
+#endif
+
+		/* Allocate vector array */
+		lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
+					 GFP_KERNEL);
+		if (!lpriv->vectors)
+			goto fail_local_cleanup;
+
+		/* Setup vector array */
+		for (i = 0; i <= global->nr_ids; i++) {
+			vec = &lpriv->vectors[i];
+			vec->cpu = cpu;
+			vec->local_id = i;
+			vec->hwirq = UINT_MAX;
+		}
+	}
+
+	return 0;
+
+fail_local_cleanup:
+	imsic_local_cleanup();
+	return -ENOMEM;
+}
+
+void imsic_state_online(void)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	irq_matrix_online(imsic->matrix);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+}
+
+void imsic_state_offline(void)
+{
+#ifdef CONFIG_SMP
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
+#endif
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	irq_matrix_offline(imsic->matrix);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+
+#ifdef CONFIG_SMP
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	WARN_ON_ONCE(try_to_del_timer_sync(&lpriv->timer) < 0);
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+#endif
+}
+
+static int __init imsic_matrix_init(void)
+{
+	struct imsic_global_config *global = &imsic->global;
+
+	raw_spin_lock_init(&imsic->matrix_lock);
+	imsic->matrix = irq_alloc_matrix(global->nr_ids + 1,
+					 0, global->nr_ids + 1);
+	if (!imsic->matrix)
+		return -ENOMEM;
+
+	/* Reserve ID#0 because it is special and never implemented */
+	irq_matrix_assign_system(imsic->matrix, 0, false);
+
+	/* Reserve IPI ID because it is special and used internally */
+	irq_matrix_assign_system(imsic->matrix, IMSIC_IPI_ID, false);
+
+	return 0;
+}
+
+static int __init imsic_get_parent_hartid(struct fwnode_handle *fwnode,
+					  u32 index, unsigned long *hartid)
+{
+	struct of_phandle_args parent;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(fwnode))
+		return -EINVAL;
+
+	rc = of_irq_parse_one(to_of_node(fwnode), index, &parent);
+	if (rc)
+		return rc;
+
+	/*
+	 * Skip interrupts other than external interrupts for
+	 * current privilege level.
+	 */
+	if (parent.args[0] != RV_IRQ_EXT)
+		return -EINVAL;
+
+	return riscv_of_parent_hartid(parent.np, hartid);
+}
+
+static int __init imsic_get_mmio_resource(struct fwnode_handle *fwnode,
+					  u32 index, struct resource *res)
+{
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(fwnode))
+		return -EINVAL;
+
+	return of_address_to_resource(to_of_node(fwnode), index, res);
+}
+
+static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
+				     struct imsic_global_config *global,
+				     u32 *nr_parent_irqs,
+				     u32 *nr_mmios)
+{
+	unsigned long hartid;
+	struct resource res;
+	int rc;
+	u32 i;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(fwnode))
+		return -EINVAL;
+
+	*nr_parent_irqs = 0;
+	*nr_mmios = 0;
+
+	/* Find number of parent interrupts */
+	while (!imsic_get_parent_hartid(fwnode, *nr_parent_irqs, &hartid))
+		(*nr_parent_irqs)++;
+	if (!(*nr_parent_irqs)) {
+		pr_err("%pfwP: no parent irqs available\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Find number of guest index bits in MSI address */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,guest-index-bits",
+				  &global->guest_index_bits);
+	if (rc)
+		global->guest_index_bits = 0;
+
+	/* Find number of HART index bits */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,hart-index-bits",
+				  &global->hart_index_bits);
+	if (rc) {
+		/* Assume default value */
+		global->hart_index_bits = __fls(*nr_parent_irqs);
+		if (BIT(global->hart_index_bits) < *nr_parent_irqs)
+			global->hart_index_bits++;
+	}
+
+	/* Find number of group index bits */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-bits",
+				  &global->group_index_bits);
+	if (rc)
+		global->group_index_bits = 0;
+
+	/*
+	 * Find first bit position of group index.
+	 * If not specified assumed the default APLIC-IMSIC configuration.
+	 */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-shift",
+				  &global->group_index_shift);
+	if (rc)
+		global->group_index_shift = IMSIC_MMIO_PAGE_SHIFT * 2;
+
+	/* Find number of interrupt identities */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-ids",
+				  &global->nr_ids);
+	if (rc) {
+		pr_err("%pfwP: number of interrupt identities not found\n",
+			fwnode);
+		return rc;
+	}
+
+	/* Find number of guest interrupt identities */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-guest-ids",
+				  &global->nr_guest_ids);
+	if (rc)
+		global->nr_guest_ids = global->nr_ids;
+
+	/* Sanity check guest index bits */
+	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT;
+	if (i < global->guest_index_bits) {
+		pr_err("%pfwP: guest index bits too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check HART index bits */
+	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT - global->guest_index_bits;
+	if (i < global->hart_index_bits) {
+		pr_err("%pfwP: HART index bits too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check group index bits */
+	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
+	    global->guest_index_bits - global->hart_index_bits;
+	if (i < global->group_index_bits) {
+		pr_err("%pfwP: group index bits too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check group index shift */
+	i = global->group_index_bits + global->group_index_shift - 1;
+	if (i >= BITS_PER_LONG) {
+		pr_err("%pfwP: group index shift too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check number of interrupt identities */
+	if ((global->nr_ids < IMSIC_MIN_ID) ||
+	    (global->nr_ids >= IMSIC_MAX_ID) ||
+	    ((global->nr_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID)) {
+		pr_err("%pfwP: invalid number of interrupt identities\n",
+			fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check number of guest interrupt identities */
+	if ((global->nr_guest_ids < IMSIC_MIN_ID) ||
+	    (global->nr_guest_ids >= IMSIC_MAX_ID) ||
+	    ((global->nr_guest_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID)) {
+		pr_err("%pfwP: invalid number of guest interrupt identities\n",
+			fwnode);
+		return -EINVAL;
+	}
+
+	/* Compute base address */
+	rc = imsic_get_mmio_resource(fwnode, 0, &res);
+	if (rc) {
+		pr_err("%pfwP: first MMIO resource not found\n", fwnode);
+		return -EINVAL;
+	}
+	global->base_addr = res.start;
+	global->base_addr &= ~(BIT(global->guest_index_bits +
+				   global->hart_index_bits +
+				   IMSIC_MMIO_PAGE_SHIFT) - 1);
+	global->base_addr &= ~((BIT(global->group_index_bits) - 1) <<
+			       global->group_index_shift);
+
+	/* Find number of MMIO register sets */
+	while (!imsic_get_mmio_resource(fwnode, *nr_mmios, &res))
+		(*nr_mmios)++;
+
+	return 0;
+}
+
+int __init imsic_setup_state(struct fwnode_handle *fwnode)
+{
+	u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
+	struct imsic_global_config *global;
+	struct imsic_local_config *local;
+	void __iomem **mmios_va = NULL;
+	struct resource *mmios = NULL;
+	unsigned long reloff, hartid;
+	phys_addr_t base_addr;
+	int rc, cpu;
+
+	/*
+	 * Only one IMSIC instance allowed in a platform for clean
+	 * implementation of SMP IRQ affinity and per-CPU IPIs.
+	 *
+	 * This means on a multi-socket (or multi-die) platform we
+	 * will have multiple MMIO regions for one IMSIC instance.
+	 */
+	if (imsic) {
+		pr_err("%pfwP: already initialized hence ignoring\n",
+			fwnode);
+		return -EALREADY;
+	}
+
+	if (!riscv_isa_extension_available(NULL, SxAIA)) {
+		pr_err("%pfwP: AIA support not available\n", fwnode);
+		return -ENODEV;
+	}
+
+	imsic = kzalloc(sizeof(*imsic), GFP_KERNEL);
+	if (!imsic)
+		return -ENOMEM;
+	imsic->fwnode = fwnode;
+	global = &imsic->global;
+
+	global->local = alloc_percpu(typeof(*(global->local)));
+	if (!global->local) {
+		rc = -ENOMEM;
+		goto out_free_priv;
+	}
+
+	/* Parse IMSIC fwnode */
+	rc = imsic_parse_fwnode(fwnode, global, &nr_parent_irqs, &nr_mmios);
+	if (rc)
+		goto out_free_local;
+
+	/* Allocate MMIO resource array */
+	mmios = kcalloc(nr_mmios, sizeof(*mmios), GFP_KERNEL);
+	if (!mmios) {
+		rc = -ENOMEM;
+		goto out_free_local;
+	}
+
+	/* Allocate MMIO virtual address array */
+	mmios_va = kcalloc(nr_mmios, sizeof(*mmios_va), GFP_KERNEL);
+	if (!mmios_va) {
+		rc = -ENOMEM;
+		goto out_iounmap;
+	}
+
+	/* Parse and map MMIO register sets */
+	for (i = 0; i < nr_mmios; i++) {
+		rc = imsic_get_mmio_resource(fwnode, i, &mmios[i]);
+		if (rc) {
+			pr_err("%pfwP: unable to parse MMIO regset %d\n",
+				fwnode, i);
+			goto out_iounmap;
+		}
+
+		base_addr = mmios[i].start;
+		base_addr &= ~(BIT(global->guest_index_bits +
+				   global->hart_index_bits +
+				   IMSIC_MMIO_PAGE_SHIFT) - 1);
+		base_addr &= ~((BIT(global->group_index_bits) - 1) <<
+			       global->group_index_shift);
+		if (base_addr != global->base_addr) {
+			rc = -EINVAL;
+			pr_err("%pfwP: address mismatch for regset %d\n",
+				fwnode, i);
+			goto out_iounmap;
+		}
+
+		mmios_va[i] = ioremap(mmios[i].start, resource_size(&mmios[i]));
+		if (!mmios_va[i]) {
+			rc = -EIO;
+			pr_err("%pfwP: unable to map MMIO regset %d\n",
+				fwnode, i);
+			goto out_iounmap;
+		}
+	}
+
+	/* Initialize local (or per-CPU )state */
+	rc = imsic_local_init();
+	if (rc) {
+		pr_err("%pfwP: failed to initialize local state\n",
+		       fwnode);
+		goto out_iounmap;
+	}
+
+	/* Configure handlers for target CPUs */
+	for (i = 0; i < nr_parent_irqs; i++) {
+		rc = imsic_get_parent_hartid(fwnode, i, &hartid);
+		if (rc) {
+			pr_warn("%pfwP: hart ID for parent irq%d not found\n",
+				fwnode, i);
+			continue;
+		}
+
+		cpu = riscv_hartid_to_cpuid(hartid);
+		if (cpu < 0) {
+			pr_warn("%pfwP: invalid cpuid for parent irq%d\n",
+				fwnode, i);
+			continue;
+		}
+
+		/* Find MMIO location of MSI page */
+		index = nr_mmios;
+		reloff = i * BIT(global->guest_index_bits) *
+			 IMSIC_MMIO_PAGE_SZ;
+		for (j = 0; nr_mmios; j++) {
+			if (reloff < resource_size(&mmios[j])) {
+				index = j;
+				break;
+			}
+
+			/*
+			 * MMIO region size may not be aligned to
+			 * BIT(global->guest_index_bits) * IMSIC_MMIO_PAGE_SZ
+			 * if holes are present.
+			 */
+			reloff -= ALIGN(resource_size(&mmios[j]),
+			BIT(global->guest_index_bits) * IMSIC_MMIO_PAGE_SZ);
+		}
+		if (index >= nr_mmios) {
+			pr_warn("%pfwP: MMIO not found for parent irq%d\n",
+				fwnode, i);
+			continue;
+		}
+
+		local = per_cpu_ptr(global->local, cpu);
+		local->msi_pa = mmios[index].start + reloff;
+		local->msi_va = mmios_va[index] + reloff;
+
+		nr_handlers++;
+	}
+
+	/* If no CPU handlers found then can't take interrupts */
+	if (!nr_handlers) {
+		pr_err("%pfwP: No CPU handlers found\n", fwnode);
+		rc = -ENODEV;
+		goto out_local_cleanup;
+	}
+
+	/* Initialize matrix allocator */
+	rc = imsic_matrix_init();
+	if (rc) {
+		pr_err("%pfwP: failed to create matrix allocator\n",
+		       fwnode);
+		goto out_local_cleanup;
+	}
+
+	/* We don't need MMIO arrays anymore so let's free-up */
+	kfree(mmios_va);
+	kfree(mmios);
+
+	return 0;
+
+out_local_cleanup:
+	imsic_local_cleanup();
+out_iounmap:
+	for (i = 0; i < nr_mmios; i++) {
+		if (mmios_va[i])
+			iounmap(mmios_va[i]);
+	}
+	kfree(mmios_va);
+	kfree(mmios);
+out_free_local:
+	free_percpu(imsic->global.local);
+out_free_priv:
+	kfree(imsic);
+	imsic = NULL;
+	return rc;
+}
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
new file mode 100644
index 000000000000..f0c983db99eb
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#ifndef _IRQ_RISCV_IMSIC_STATE_H
+#define _IRQ_RISCV_IMSIC_STATE_H
+
+#include <linux/irqchip/riscv-imsic.h>
+#include <linux/irqdomain.h>
+#include <linux/fwnode.h>
+#include <linux/timer.h>
+
+#define IMSIC_IPI_ID				1
+#define IMSIC_NR_IPI				8
+
+struct imsic_vector {
+	/* Fixed details of the vector */
+	unsigned int				cpu;
+	unsigned int				local_id;
+	/* Details saved by driver in the vector */
+	unsigned int				hwirq;
+	/* Details accessed using local lock held */
+	bool					enable;
+	struct imsic_vector			*move;
+};
+
+struct imsic_local_priv {
+	/* Local lock to protect vector enable/move variables and dirty bitmap */
+	raw_spinlock_t				lock;
+
+	/* Local dirty bitmap for synchronization */
+	unsigned long				*dirty_bitmap;
+
+#ifdef CONFIG_SMP
+	/* Local timer for synchronization */
+	struct timer_list			timer;
+#endif
+
+	/* Local vector table */
+	struct imsic_vector			*vectors;
+};
+
+struct imsic_priv {
+	/* Device details */
+	struct fwnode_handle			*fwnode;
+
+	/* Global configuration common for all HARTs */
+	struct imsic_global_config		global;
+
+	/* Per-CPU state */
+	struct imsic_local_priv __percpu	*lpriv;
+
+	/* State of IRQ matrix allocator */
+	raw_spinlock_t				matrix_lock;
+	struct irq_matrix			*matrix;
+
+	/* IRQ domains (created by platform driver) */
+	struct irq_domain			*base_domain;
+};
+
+extern struct imsic_priv *imsic;
+
+void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val);
+
+static inline void __imsic_id_set_enable(unsigned long id)
+{
+	__imsic_eix_update(id, 1, false, true);
+}
+
+static inline void __imsic_id_clear_enable(unsigned long id)
+{
+	__imsic_eix_update(id, 1, false, false);
+}
+
+void imsic_local_sync_all(void);
+void imsic_local_delivery(bool enable);
+
+void imsic_vector_mask(struct imsic_vector *vec);
+void imsic_vector_unmask(struct imsic_vector *vec);
+bool imsic_vector_isenabled(struct imsic_vector *vec);
+struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec);
+void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec);
+
+struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id);
+
+struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask);
+void imsic_vector_free(struct imsic_vector *vector);
+
+void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind);
+void imsic_vector_debug_show_summary(struct seq_file *m, int ind);
+
+void imsic_state_online(void);
+void imsic_state_offline(void);
+int imsic_setup_state(struct fwnode_handle *fwnode);
+
+#endif
diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
new file mode 100644
index 000000000000..b997eb277b5b
--- /dev/null
+++ b/include/linux/irqchip/riscv-imsic.h
@@ -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.
+ */
+#ifndef __LINUX_IRQCHIP_RISCV_IMSIC_H
+#define __LINUX_IRQCHIP_RISCV_IMSIC_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <asm/csr.h>
+
+#define IMSIC_MMIO_PAGE_SHIFT		12
+#define IMSIC_MMIO_PAGE_SZ		BIT(IMSIC_MMIO_PAGE_SHIFT)
+#define IMSIC_MMIO_PAGE_LE		0x00
+#define IMSIC_MMIO_PAGE_BE		0x04
+
+#define IMSIC_MIN_ID			63
+#define IMSIC_MAX_ID			2048
+
+#define IMSIC_EIDELIVERY		0x70
+
+#define IMSIC_EITHRESHOLD		0x72
+
+#define IMSIC_EIP0			0x80
+#define IMSIC_EIP63			0xbf
+#define IMSIC_EIPx_BITS			32
+
+#define IMSIC_EIE0			0xc0
+#define IMSIC_EIE63			0xff
+#define IMSIC_EIEx_BITS			32
+
+#define IMSIC_FIRST			IMSIC_EIDELIVERY
+#define IMSIC_LAST			IMSIC_EIE63
+
+#define IMSIC_MMIO_SETIPNUM_LE		0x00
+#define IMSIC_MMIO_SETIPNUM_BE		0x04
+
+struct imsic_local_config {
+	phys_addr_t				msi_pa;
+	void __iomem				*msi_va;
+};
+
+struct imsic_global_config {
+	/*
+	 * MSI Target Address Scheme
+	 *
+	 * XLEN-1                                                12     0
+	 * |                                                     |     |
+	 * -------------------------------------------------------------
+	 * |xxxxxx|Group Index|xxxxxxxxxxx|HART Index|Guest Index|  0  |
+	 * -------------------------------------------------------------
+	 */
+
+	/* Bits representing Guest index, HART index, and Group index */
+	u32					guest_index_bits;
+	u32					hart_index_bits;
+	u32					group_index_bits;
+	u32					group_index_shift;
+
+	/* Global base address matching all target MSI addresses */
+	phys_addr_t				base_addr;
+
+	/* Number of interrupt identities */
+	u32					nr_ids;
+
+	/* Number of guest interrupt identities */
+	u32					nr_guest_ids;
+
+	/* Per-CPU IMSIC addresses */
+	struct imsic_local_config __percpu	*local;
+};
+
+#ifdef CONFIG_RISCV_IMSIC
+
+extern const struct imsic_global_config *imsic_get_global_config(void);
+
+#else
+
+static inline const struct imsic_global_config *imsic_get_global_config(void)
+{
+	return NULL;
+}
+
+#endif
+
+#endif
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:16 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:16 +0530
Subject: [PATCH v13 11/13] irqchip/riscv-aplic: Add support for MSI-mode
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-12-apatel@ventanamicro.com>

The RISC-V advanced platform-level interrupt controller (APLIC) has
two modes of operation: 1) Direct mode and 2) MSI mode.
(For more details, refer https://github.com/riscv/riscv-aia)

In APLIC MSI-mode, wired interrupts are forwared as message signaled
interrupts (MSIs) to CPUs via IMSIC.

Extend the existing APLIC irqchip driver to support MSI-mode for
RISC-V platforms having both wired interrupts and MSIs.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                |   6 +
 drivers/irqchip/Makefile               |   1 +
 drivers/irqchip/irq-riscv-aplic-main.c |   2 +-
 drivers/irqchip/irq-riscv-aplic-main.h |   8 +
 drivers/irqchip/irq-riscv-aplic-msi.c  | 263 +++++++++++++++++++++++++
 5 files changed, 279 insertions(+), 1 deletion(-)
 create mode 100644 drivers/irqchip/irq-riscv-aplic-msi.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index dbc8811d3764..806b5fccb3e8 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -551,6 +551,12 @@ config RISCV_APLIC
 	depends on RISCV
 	select IRQ_DOMAIN_HIERARCHY
 
+config RISCV_APLIC_MSI
+	bool
+	depends on RISCV_APLIC
+	select GENERIC_MSI_IRQ
+	default RISCV_APLIC
+
 config RISCV_IMSIC
 	bool
 	depends on RISCV
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 7f8289790ed8..47995fdb2c60 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
 obj-$(CONFIG_RISCV_APLIC)		+= irq-riscv-aplic-main.o irq-riscv-aplic-direct.o
+obj-$(CONFIG_RISCV_APLIC_MSI)		+= irq-riscv-aplic-msi.o
 obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
index e6617147daff..302f4ed7c075 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.c
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -187,7 +187,7 @@ static int aplic_probe(struct platform_device *pdev)
 	if (is_of_node(dev->fwnode))
 		msi_mode = of_property_present(to_of_node(dev->fwnode), "msi-parent");
 	if (msi_mode)
-		rc = -ENODEV;
+		rc = aplic_msi_setup(dev, regs);
 	else
 		rc = aplic_direct_setup(dev, regs);
 	if (rc)
diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h
index 4cfbadf37ddc..4393927d8c80 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.h
+++ b/drivers/irqchip/irq-riscv-aplic-main.h
@@ -40,5 +40,13 @@ int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
 void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode);
 int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs);
 int aplic_direct_setup(struct device *dev, void __iomem *regs);
+#ifdef CONFIG_RISCV_APLIC_MSI
+int aplic_msi_setup(struct device *dev, void __iomem *regs);
+#else
+static inline int aplic_msi_setup(struct device *dev, void __iomem *regs)
+{
+	return -ENODEV;
+}
+#endif
 
 #endif
diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
new file mode 100644
index 000000000000..b2a25e011bb2
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-msi.c
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/riscv-aplic.h>
+#include <linux/irqchip/riscv-imsic.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-aplic-main.h"
+
+static void aplic_msi_irq_unmask(struct irq_data *d)
+{
+	aplic_irq_unmask(d);
+	irq_chip_unmask_parent(d);
+}
+
+static void aplic_msi_irq_mask(struct irq_data *d)
+{
+	irq_chip_mask_parent(d);
+	aplic_irq_mask(d);
+}
+
+static void aplic_msi_irq_eoi(struct irq_data *d)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	u32 reg_off, reg_mask;
+
+	/*
+	 * EOI handling is required only for level-triggered interrupts
+	 * when APLIC is in MSI mode.
+	 */
+
+	reg_off = APLIC_CLRIP_BASE + ((d->hwirq / APLIC_IRQBITS_PER_REG) * 4);
+	reg_mask = BIT(d->hwirq % APLIC_IRQBITS_PER_REG);
+	switch (irqd_get_trigger_type(d)) {
+	case IRQ_TYPE_LEVEL_LOW:
+		/*
+		 * If the rectified input value of the source is still low
+		 * then set the interrupt pending bit so that interrupt is
+		 * re-triggered via MSI.
+		 */
+		if (!(readl(priv->regs + reg_off) & reg_mask))
+			writel(d->hwirq, priv->regs + APLIC_SETIPNUM_LE);
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		/*
+		 * If the rectified input value of the source is still high
+		 * then set the interrupt pending bit so that interrupt is
+		 * re-triggered via MSI.
+		 */
+		if (readl(priv->regs + reg_off) & reg_mask)
+			writel(d->hwirq, priv->regs + APLIC_SETIPNUM_LE);
+		break;
+	}
+}
+
+static void aplic_msi_write_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	unsigned int group_index, hart_index, guest_index, val;
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	struct aplic_msicfg *mc = &priv->msicfg;
+	phys_addr_t tppn, tbppn, msg_addr;
+	void __iomem *target;
+
+	/* For zeroed MSI, simply write zero into the target register */
+	if (!msg->address_hi && !msg->address_lo && !msg->data) {
+		target = priv->regs + APLIC_TARGET_BASE;
+		target += (d->hwirq - 1) * sizeof(u32);
+		writel(0, target);
+		return;
+	}
+
+	/* Sanity check on message data */
+	WARN_ON(msg->data > APLIC_TARGET_EIID_MASK);
+
+	/* Compute target MSI address */
+	msg_addr = (((u64)msg->address_hi) << 32) | msg->address_lo;
+	tppn = msg_addr >> APLIC_xMSICFGADDR_PPN_SHIFT;
+
+	/* Compute target HART Base PPN */
+	tbppn = tppn;
+	tbppn &= ~APLIC_xMSICFGADDR_PPN_HART(mc->lhxs);
+	tbppn &= ~APLIC_xMSICFGADDR_PPN_LHX(mc->lhxw, mc->lhxs);
+	tbppn &= ~APLIC_xMSICFGADDR_PPN_HHX(mc->hhxw, mc->hhxs);
+	WARN_ON(tbppn != mc->base_ppn);
+
+	/* Compute target group and hart indexes */
+	group_index = (tppn >> APLIC_xMSICFGADDR_PPN_HHX_SHIFT(mc->hhxs)) &
+		     APLIC_xMSICFGADDR_PPN_HHX_MASK(mc->hhxw);
+	hart_index = (tppn >> APLIC_xMSICFGADDR_PPN_LHX_SHIFT(mc->lhxs)) &
+		     APLIC_xMSICFGADDR_PPN_LHX_MASK(mc->lhxw);
+	hart_index |= (group_index << mc->lhxw);
+	WARN_ON(hart_index > APLIC_TARGET_HART_IDX_MASK);
+
+	/* Compute target guest index */
+	guest_index = tppn & APLIC_xMSICFGADDR_PPN_HART(mc->lhxs);
+	WARN_ON(guest_index > APLIC_TARGET_GUEST_IDX_MASK);
+
+	/* Update IRQ TARGET register */
+	target = priv->regs + APLIC_TARGET_BASE;
+	target += (d->hwirq - 1) * sizeof(u32);
+	val = FIELD_PREP(APLIC_TARGET_HART_IDX, hart_index);
+	val |= FIELD_PREP(APLIC_TARGET_GUEST_IDX, guest_index);
+	val |= FIELD_PREP(APLIC_TARGET_EIID, msg->data);
+	writel(val, target);
+}
+
+static void aplic_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+	arg->desc = desc;
+	arg->hwirq = (u32)desc->data.icookie.value;
+}
+
+static int aplic_msi_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
+			       unsigned long *hwirq, unsigned int *type)
+{
+	struct msi_domain_info *info = d->host_data;
+	struct aplic_priv *priv = info->data;
+
+	return aplic_irqdomain_translate(fwspec, priv->gsi_base, hwirq, type);
+}
+
+static const struct msi_domain_template aplic_msi_template = {
+	.chip = {
+		.name			= "APLIC-MSI",
+		.irq_mask		= aplic_msi_irq_mask,
+		.irq_unmask		= aplic_msi_irq_unmask,
+		.irq_set_type		= aplic_irq_set_type,
+		.irq_eoi		= aplic_msi_irq_eoi,
+#ifdef CONFIG_SMP
+		.irq_set_affinity	= irq_chip_set_affinity_parent,
+#endif
+		.irq_write_msi_msg	= aplic_msi_write_msg,
+		.flags			= IRQCHIP_SET_TYPE_MASKED |
+					  IRQCHIP_SKIP_SET_WAKE |
+					  IRQCHIP_MASK_ON_SUSPEND,
+	},
+
+	.ops = {
+		.set_desc		= aplic_msi_set_desc,
+		.msi_translate		= aplic_msi_translate,
+	},
+
+	.info = {
+		.bus_token		= DOMAIN_BUS_WIRED_TO_MSI,
+		.flags			= MSI_FLAG_USE_DEV_FWNODE,
+		.handler		= handle_fasteoi_irq,
+	},
+};
+
+int aplic_msi_setup(struct device *dev, void __iomem *regs)
+{
+	const struct imsic_global_config *imsic_global;
+	struct aplic_priv *priv;
+	struct aplic_msicfg *mc;
+	phys_addr_t pa;
+	int rc;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	rc = aplic_setup_priv(priv, dev, regs);
+	if (rc) {
+		dev_err(dev, "failed to create APLIC context\n");
+		return rc;
+	}
+	mc = &priv->msicfg;
+
+	/*
+	 * The APLIC outgoing MSI config registers assume target MSI
+	 * controller to be RISC-V AIA IMSIC controller.
+	 */
+	imsic_global = imsic_get_global_config();
+	if (!imsic_global) {
+		dev_err(dev, "IMSIC global config not found\n");
+		return -ENODEV;
+	}
+
+	/* Find number of guest index bits (LHXS) */
+	mc->lhxs = imsic_global->guest_index_bits;
+	if (APLIC_xMSICFGADDRH_LHXS_MASK < mc->lhxs) {
+		dev_err(dev, "IMSIC guest index bits big for APLIC LHXS\n");
+		return -EINVAL;
+	}
+
+	/* Find number of HART index bits (LHXW) */
+	mc->lhxw = imsic_global->hart_index_bits;
+	if (APLIC_xMSICFGADDRH_LHXW_MASK < mc->lhxw) {
+		dev_err(dev, "IMSIC hart index bits big for APLIC LHXW\n");
+		return -EINVAL;
+	}
+
+	/* Find number of group index bits (HHXW) */
+	mc->hhxw = imsic_global->group_index_bits;
+	if (APLIC_xMSICFGADDRH_HHXW_MASK < mc->hhxw) {
+		dev_err(dev, "IMSIC group index bits big for APLIC HHXW\n");
+		return -EINVAL;
+	}
+
+	/* Find first bit position of group index (HHXS) */
+	mc->hhxs = imsic_global->group_index_shift;
+	if (mc->hhxs < (2 * APLIC_xMSICFGADDR_PPN_SHIFT)) {
+		dev_err(dev, "IMSIC group index shift should be >= %d\n",
+			(2 * APLIC_xMSICFGADDR_PPN_SHIFT));
+		return -EINVAL;
+	}
+	mc->hhxs -= (2 * APLIC_xMSICFGADDR_PPN_SHIFT);
+	if (APLIC_xMSICFGADDRH_HHXS_MASK < mc->hhxs) {
+		dev_err(dev, "IMSIC group index shift big for APLIC HHXS\n");
+		return -EINVAL;
+	}
+
+	/* Compute PPN base */
+	mc->base_ppn = imsic_global->base_addr >> APLIC_xMSICFGADDR_PPN_SHIFT;
+	mc->base_ppn &= ~APLIC_xMSICFGADDR_PPN_HART(mc->lhxs);
+	mc->base_ppn &= ~APLIC_xMSICFGADDR_PPN_LHX(mc->lhxw, mc->lhxs);
+	mc->base_ppn &= ~APLIC_xMSICFGADDR_PPN_HHX(mc->hhxw, mc->hhxs);
+
+	/* Setup global config and interrupt delivery */
+	aplic_init_hw_global(priv, true);
+
+	/* Set the APLIC device MSI domain if not available */
+	if (!dev_get_msi_domain(dev)) {
+		/*
+		 * The device MSI domain for OF devices is only set at the
+		 * time of populating/creating OF device. If the device MSI
+		 * domain is discovered later after the OF device is created
+		 * then we need to set it explicitly before using any platform
+		 * MSI functions.
+		 *
+		 * In case of APLIC device, the parent MSI domain is always
+		 * IMSIC and the IMSIC MSI domains are created later through
+		 * the platform driver probing so we set it explicitly here.
+		 */
+		if (is_of_node(dev->fwnode))
+			of_msi_configure(dev, to_of_node(dev->fwnode));
+	}
+
+	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, &aplic_msi_template,
+					  priv->nr_irqs + 1, priv, priv)) {
+		dev_err(dev, "failed to create MSI irq domain\n");
+		return -ENOMEM;
+	}
+
+	/* Advertise the interrupt controller */
+	pa = priv->msicfg.base_ppn << APLIC_xMSICFGADDR_PPN_SHIFT;
+	dev_info(dev, "%d interrupts forwared to MSI base %pa\n", priv->nr_irqs, &pa);
+
+	return 0;
+}
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:17 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:17 +0530
Subject: [PATCH v13 12/13] RISC-V: Select APLIC and IMSIC drivers
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-13-apatel@ventanamicro.com>

The QEMU virt machine supports AIA emulation and we also have
quite a few RISC-V platforms with AIA support under development
so let us select APLIC and IMSIC drivers for all RISC-V platforms.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 arch/riscv/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index bffbd869a068..569f2b6fd60a 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -162,6 +162,8 @@ config RISCV
 	select PCI_DOMAINS_GENERIC if PCI
 	select PCI_MSI if PCI
 	select RISCV_ALTERNATIVE if !XIP_KERNEL
+	select RISCV_APLIC
+	select RISCV_IMSIC
 	select RISCV_INTC
 	select RISCV_TIMER if RISCV_SBI
 	select SIFIVE_PLIC
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:18 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:18 +0530
Subject: [PATCH v13 13/13] MAINTAINERS: Add entry for RISC-V AIA drivers
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-14-apatel@ventanamicro.com>

Add myself as maintainer for RISC-V AIA drivers including the
RISC-V INTC driver which supports both AIA and non-AIA platforms.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 MAINTAINERS | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ed4d3868539..d948f9210f1b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18801,6 +18801,20 @@ S:	Maintained
 F:	drivers/mtd/nand/raw/r852.c
 F:	drivers/mtd/nand/raw/r852.h
 
+RISC-V AIA DRIVERS
+M:	Anup Patel <anup at brainfault.org>
+L:	linux-riscv at lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
+F:	Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
+F:	drivers/irqchip/irq-riscv-aplic-*.c
+F:	drivers/irqchip/irq-riscv-aplic-*.h
+F:	drivers/irqchip/irq-riscv-imsic-*.c
+F:	drivers/irqchip/irq-riscv-imsic-*.h
+F:	drivers/irqchip/irq-riscv-intc.c
+F:	include/linux/irqchip/riscv-aplic.h
+F:	include/linux/irqchip/riscv-imsic.h
+
 RISC-V ARCHITECTURE
 M:	Paul Walmsley <paul.walmsley at sifive.com>
 M:	Palmer Dabbelt <palmer at dabbelt.com>
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:14 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:14 +0530
Subject: [PATCH v13 09/13] dt-bindings: interrupt-controller: Add RISC-V advanced PLIC
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-10-apatel@ventanamicro.com>

We add DT bindings document for RISC-V advanced platform level interrupt
controller (APLIC) defined by the RISC-V advanced interrupt architecture
(AIA) specification.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 .../interrupt-controller/riscv,aplic.yaml     | 172 ++++++++++++++++++
 1 file changed, 172 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml b/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
new file mode 100644
index 000000000000..190a6499c932
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
@@ -0,0 +1,172 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/riscv,aplic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Advanced Platform Level Interrupt Controller (APLIC)
+
+maintainers:
+  - Anup Patel <anup at brainfault.org>
+
+description:
+  The RISC-V advanced interrupt architecture (AIA) defines an advanced
+  platform level interrupt controller (APLIC) for handling wired interrupts
+  in a RISC-V platform. The RISC-V AIA specification can be found at
+  https://github.com/riscv/riscv-aia.
+
+  The RISC-V APLIC is implemented as hierarchical APLIC domains where all
+  interrupt sources connect to the root APLIC domain and a parent APLIC
+  domain can delegate interrupt sources to it's child APLIC domains. There
+  is one device tree node for each APLIC domain.
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - qemu,aplic
+      - const: riscv,aplic
+
+  reg:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+  interrupts-extended:
+    minItems: 1
+    maxItems: 16384
+    description:
+      Given APLIC domain directly injects external interrupts to a set of
+      RISC-V HARTS (or CPUs). Each node pointed to should be a riscv,cpu-intc
+      node, which has a CPU node (i.e. RISC-V HART) as parent.
+
+  msi-parent:
+    description:
+      Given APLIC domain forwards wired interrupts as MSIs to a AIA incoming
+      message signaled interrupt controller (IMSIC). If both "msi-parent" and
+      "interrupts-extended" properties are present then it means the APLIC
+      domain supports both MSI mode and Direct mode in HW. In this case, the
+      APLIC driver has to choose between MSI mode or Direct mode.
+
+  riscv,num-sources:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 1023
+    description:
+      Specifies the number of wired interrupt sources supported by this
+      APLIC domain.
+
+  riscv,children:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 1024
+    items:
+      maxItems: 1
+    description:
+      A list of child APLIC domains for the given APLIC domain. Each child
+      APLIC domain is assigned a child index in increasing order, with the
+      first child APLIC domain assigned child index 0. The APLIC domain child
+      index is used by firmware to delegate interrupts from the given APLIC
+      domain to a particular child APLIC domain.
+
+  riscv,delegation:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 1024
+    items:
+      items:
+        - description: child APLIC domain phandle
+        - description: first interrupt number of the parent APLIC domain (inclusive)
+        - description: last interrupt number of the parent APLIC domain (inclusive)
+    description:
+      A interrupt delegation list where each entry is a triple consisting
+      of child APLIC domain phandle, first interrupt number of the parent
+      APLIC domain, and last interrupt number of the parent APLIC domain.
+      Firmware must configure interrupt delegation registers based on
+      interrupt delegation list.
+
+dependencies:
+  riscv,delegation: [ "riscv,children" ]
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - "#interrupt-cells"
+  - riscv,num-sources
+
+anyOf:
+  - required:
+      - interrupts-extended
+  - required:
+      - msi-parent
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    // Example 1 (APLIC domains directly injecting interrupt to HARTs):
+
+    interrupt-controller at c000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      interrupts-extended = <&cpu1_intc 11>,
+                            <&cpu2_intc 11>,
+                            <&cpu3_intc 11>,
+                            <&cpu4_intc 11>;
+      reg = <0xc000000 0x4080>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+      riscv,children = <&aplic1>, <&aplic2>;
+      riscv,delegation = <&aplic1 1 63>;
+    };
+
+    aplic1: interrupt-controller at d000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      interrupts-extended = <&cpu1_intc 9>,
+                            <&cpu2_intc 9>;
+      reg = <0xd000000 0x4080>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+    };
+
+    aplic2: interrupt-controller at e000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      interrupts-extended = <&cpu3_intc 9>,
+                            <&cpu4_intc 9>;
+      reg = <0xe000000 0x4080>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+    };
+
+  - |
+    // Example 2 (APLIC domains forwarding interrupts as MSIs):
+
+    interrupt-controller at c000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      msi-parent = <&imsic_mlevel>;
+      reg = <0xc000000 0x4000>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+      riscv,children = <&aplic3>;
+      riscv,delegation = <&aplic3 1 63>;
+    };
+
+    aplic3: interrupt-controller at d000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      msi-parent = <&imsic_slevel>;
+      reg = <0xd000000 0x4000>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+    };
+...
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:07:12 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:37:12 +0530
Subject: [PATCH v13 07/13] irqchip/riscv-imsic: Add device MSI domain support for platform devices
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <20240220060718.823229-8-apatel@ventanamicro.com>

The Linux platform MSI support allows per-device MSI domains so let
us add a platform irqchip driver for RISC-V IMSIC which provides a
base IRQ domain with MSI parent support for platform device domains.

This driver assumes that the IMSIC state is already initialized by
the IMSIC early driver.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Makefile                   |   2 +-
 drivers/irqchip/irq-riscv-imsic-platform.c | 346 +++++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.h    |   1 +
 3 files changed, 348 insertions(+), 1 deletion(-)
 create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index d714724387ce..abca445a3229 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -95,7 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
 obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
-obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o
+obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
 obj-$(CONFIG_IMX_INTMUX)		+= irq-imx-intmux.o
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
new file mode 100644
index 000000000000..7ee44c493dbc
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "riscv-imsic: " fmt
+#include <linux/bitmap.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-imsic-state.h"
+
+static bool imsic_cpu_page_phys(unsigned int cpu, unsigned int guest_index,
+				phys_addr_t *out_msi_pa)
+{
+	struct imsic_global_config *global;
+	struct imsic_local_config *local;
+
+	global = &imsic->global;
+	local = per_cpu_ptr(global->local, cpu);
+
+	if (BIT(global->guest_index_bits) <= guest_index)
+		return false;
+
+	if (out_msi_pa)
+		*out_msi_pa = local->msi_pa +
+			      (guest_index * IMSIC_MMIO_PAGE_SZ);
+
+	return true;
+}
+
+static void imsic_irq_mask(struct irq_data *d)
+{
+	imsic_vector_mask(irq_data_get_irq_chip_data(d));
+}
+
+static void imsic_irq_unmask(struct irq_data *d)
+{
+	imsic_vector_unmask(irq_data_get_irq_chip_data(d));
+}
+
+static int imsic_irq_retrigger(struct irq_data *d)
+{
+	struct imsic_vector *vec = irq_data_get_irq_chip_data(d);
+	struct imsic_local_config *local;
+
+	if (WARN_ON(vec == NULL))
+		return -ENOENT;
+
+	local = per_cpu_ptr(imsic->global.local, vec->cpu);
+	writel_relaxed(vec->local_id, local->msi_va);
+	return 0;
+}
+
+static void imsic_irq_compose_vector_msg(struct imsic_vector *vec, struct msi_msg *msg)
+{
+	phys_addr_t msi_addr;
+
+	if (WARN_ON(vec == NULL))
+		return;
+
+	if (WARN_ON(!imsic_cpu_page_phys(vec->cpu, 0, &msi_addr)))
+		return;
+
+	msg->address_hi = upper_32_bits(msi_addr);
+	msg->address_lo = lower_32_bits(msi_addr);
+	msg->data = vec->local_id;
+}
+
+static void imsic_irq_compose_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	imsic_irq_compose_vector_msg(irq_data_get_irq_chip_data(d), msg);
+}
+
+#ifdef CONFIG_SMP
+static void imsic_msi_update_msg(struct irq_data *d, struct imsic_vector *vec)
+{
+	struct msi_msg msg[2] = { [1] = { }, };
+
+	imsic_irq_compose_vector_msg(vec, msg);
+	irq_data_get_irq_chip(d)->irq_write_msi_msg(d, msg);
+}
+
+static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+				  bool force)
+{
+	struct imsic_vector *old_vec, *new_vec;
+	struct irq_data *pd = d->parent_data;
+
+	old_vec = irq_data_get_irq_chip_data(pd);
+	if (WARN_ON(old_vec == NULL))
+		return -ENOENT;
+
+	/* If old vector cpu belongs to the target cpumask then do nothing */
+	if (cpumask_test_cpu(old_vec->cpu, mask_val))
+		return IRQ_SET_MASK_OK_DONE;
+
+	/* If move is already in-flight then return failure */
+	if (imsic_vector_get_move(old_vec))
+		return -EBUSY;
+
+	/* Get a new vector on the desired set of CPUs */
+	new_vec = imsic_vector_alloc(old_vec->hwirq, mask_val);
+	if (!new_vec)
+		return -ENOSPC;
+
+	/* Point device to the new vector */
+	imsic_msi_update_msg(d, new_vec);
+
+	/* Update irq descriptors with the new vector */
+	pd->chip_data = new_vec;
+
+	/* Update effective affinity of parent irq data */
+	irq_data_update_effective_affinity(pd, cpumask_of(new_vec->cpu));
+
+	/* Move state of the old vector to the new vector */
+	imsic_vector_move(old_vec, new_vec);
+
+	return IRQ_SET_MASK_OK_DONE;
+}
+#endif
+
+static struct irq_chip imsic_irq_base_chip = {
+	.name			= "IMSIC",
+	.irq_mask		= imsic_irq_mask,
+	.irq_unmask		= imsic_irq_unmask,
+	.irq_retrigger		= imsic_irq_retrigger,
+	.irq_compose_msi_msg	= imsic_irq_compose_msg,
+	.flags			= IRQCHIP_SKIP_SET_WAKE |
+				  IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				  unsigned int nr_irqs, void *args)
+{
+	struct imsic_vector *vec;
+
+	/* Legacy-MSI or multi-MSI not supported yet. */
+	if (nr_irqs > 1)
+		return -ENOTSUPP;
+
+	vec = imsic_vector_alloc(virq, cpu_online_mask);
+	if (!vec)
+		return -ENOSPC;
+
+	irq_domain_set_info(domain, virq, virq,
+			    &imsic_irq_base_chip, vec,
+			    handle_simple_irq, NULL, NULL);
+	irq_set_noprobe(virq);
+	irq_set_affinity(virq, cpu_online_mask);
+
+	return 0;
+}
+
+static void imsic_irq_domain_free(struct irq_domain *domain, unsigned int virq,
+				  unsigned int nr_irqs)
+{
+	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+
+	imsic_vector_free(irq_data_get_irq_chip_data(d));
+	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+}
+
+static int imsic_irq_domain_select(struct irq_domain *domain, struct irq_fwspec *fwspec,
+				   enum irq_domain_bus_token bus_token)
+{
+	const struct msi_parent_ops *ops = domain->msi_parent_ops;
+	u32 busmask = BIT(bus_token);
+
+	if (fwspec->fwnode != domain->fwnode || fwspec->param_count != 0)
+		return 0;
+
+	/* Handle pure domain searches */
+	if (bus_token == ops->bus_select_token)
+		return 1;
+
+	return !!(ops->bus_select_mask & busmask);
+}
+
+#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
+static void imsic_irq_debug_show(struct seq_file *m, struct irq_domain *d,
+				 struct irq_data *irqd, int ind)
+{
+	if (!irqd) {
+		imsic_vector_debug_show_summary(m, ind);
+		return;
+	}
+
+	imsic_vector_debug_show(m, irq_data_get_irq_chip_data(irqd), ind);
+}
+#endif
+
+static const struct irq_domain_ops imsic_base_domain_ops = {
+	.alloc		= imsic_irq_domain_alloc,
+	.free		= imsic_irq_domain_free,
+	.select		= imsic_irq_domain_select,
+#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
+	.debug_show	= imsic_irq_debug_show,
+#endif
+};
+
+static bool imsic_init_dev_msi_info(struct device *dev,
+				    struct irq_domain *domain,
+				    struct irq_domain *real_parent,
+				    struct msi_domain_info *info)
+{
+	const struct msi_parent_ops *pops = real_parent->msi_parent_ops;
+
+	/* MSI parent domain specific settings */
+	switch (real_parent->bus_token) {
+	case DOMAIN_BUS_NEXUS:
+		if (WARN_ON_ONCE(domain != real_parent))
+			return false;
+#ifdef CONFIG_SMP
+		info->chip->irq_set_affinity = imsic_irq_set_affinity;
+#endif
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return false;
+	}
+
+	/* Is the target supported? */
+	switch (info->bus_token) {
+	case DOMAIN_BUS_DEVICE_MSI:
+		/*
+		 * Per-device MSI should never have any MSI feature bits
+		 * set. It's sole purpose is to create a dumb interrupt
+		 * chip which has a device specific irq_write_msi_msg()
+		 * callback.
+		 */
+		if (WARN_ON_ONCE(info->flags))
+			return false;
+
+		/* Core managed MSI descriptors */
+		info->flags |= MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS |
+			       MSI_FLAG_FREE_MSI_DESCS;
+		break;
+	case DOMAIN_BUS_WIRED_TO_MSI:
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return false;
+	}
+
+	/* Use hierarchial chip operations re-trigger */
+	info->chip->irq_retrigger = irq_chip_retrigger_hierarchy;
+
+	/*
+	 * Mask out the domain specific MSI feature flags which are not
+	 * supported by the real parent.
+	 */
+	info->flags &= pops->supported_flags;
+
+	/* Enforce the required flags */
+	info->flags |= pops->required_flags;
+
+	return true;
+}
+
+#define MATCH_PLATFORM_MSI		BIT(DOMAIN_BUS_PLATFORM_MSI)
+
+static const struct msi_parent_ops imsic_msi_parent_ops = {
+	.supported_flags	= MSI_GENERIC_FLAGS_MASK,
+	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
+				  MSI_FLAG_USE_DEF_CHIP_OPS,
+	.bus_select_token	= DOMAIN_BUS_NEXUS,
+	.bus_select_mask	= MATCH_PLATFORM_MSI,
+	.init_dev_msi_info	= imsic_init_dev_msi_info,
+};
+
+int imsic_irqdomain_init(void)
+{
+	struct imsic_global_config *global;
+
+	if (!imsic || !imsic->fwnode) {
+		pr_err("early driver not probed\n");
+		return -ENODEV;
+	}
+
+	if (imsic->base_domain) {
+		pr_err("%pfwP: irq domain already created\n", imsic->fwnode);
+		return -ENODEV;
+	}
+
+	/* Create Base IRQ domain */
+	imsic->base_domain = irq_domain_create_tree(imsic->fwnode,
+					&imsic_base_domain_ops, imsic);
+	if (!imsic->base_domain) {
+		pr_err("%pfwP: failed to create IMSIC base domain\n",
+			imsic->fwnode);
+		return -ENOMEM;
+	}
+	imsic->base_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
+	imsic->base_domain->msi_parent_ops = &imsic_msi_parent_ops;
+
+	irq_domain_update_bus_token(imsic->base_domain, DOMAIN_BUS_NEXUS);
+
+	global = &imsic->global;
+	pr_info("%pfwP:  hart-index-bits: %d,  guest-index-bits: %d\n",
+		imsic->fwnode, global->hart_index_bits, global->guest_index_bits);
+	pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n",
+		imsic->fwnode, global->group_index_bits, global->group_index_shift);
+	pr_info("%pfwP: per-CPU IDs %d at base PPN %pa\n",
+		imsic->fwnode, global->nr_ids, &global->base_addr);
+	pr_info("%pfwP: total %d interrupts available\n",
+		imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1));
+
+	return 0;
+}
+
+static int imsic_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	if (imsic && imsic->fwnode != dev->fwnode) {
+		dev_err(dev, "fwnode mismatch\n");
+		return -ENODEV;
+	}
+
+	return imsic_irqdomain_init();
+}
+
+static const struct of_device_id imsic_platform_match[] = {
+	{ .compatible = "riscv,imsics" },
+	{}
+};
+
+static struct platform_driver imsic_platform_driver = {
+	.driver = {
+		.name		= "riscv-imsic",
+		.of_match_table	= imsic_platform_match,
+	},
+	.probe = imsic_platform_probe,
+};
+builtin_platform_driver(imsic_platform_driver);
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index f0c983db99eb..a01a70eff3af 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -94,5 +94,6 @@ void imsic_vector_debug_show_summary(struct seq_file *m, int ind);
 void imsic_state_online(void);
 void imsic_state_offline(void);
 int imsic_setup_state(struct fwnode_handle *fwnode);
+int imsic_irqdomain_init(void);
 
 #endif
-- 
2.34.1



From apatel at ventanamicro.com  Mon Feb 19 22:12:09 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 11:42:09 +0530
Subject: [PATCH v12 00/25] Linux RISC-V AIA Support
In-Reply-To: <87zfw0azmn.ffs@tglx>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <CAK9=C2Vwtj2gZg-P73yLMxu0rPXQ3YrRRuxq6HcpHMXgs-jHaw@mail.gmail.com>
 <87bk8ig6t2.ffs@tglx> <CAK9=C2WsSSHgDF+7ruxx_QF0Lk+Dsx2F2Y-_NabnxrJ_qWhgGQ@mail.gmail.com>
 <87v86pcxcb.ffs@tglx> <87zfw0azmn.ffs@tglx>
Message-ID: <CAK9=C2W3cv0yd0faMrKjKwmSjGQ4zVVMkcbr=PtxJ1K0sn=SLQ@mail.gmail.com>

On Sat, Feb 17, 2024 at 2:35?AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> Anup!
>
> On Thu, Feb 15 2024 at 20:59, Thomas Gleixner wrote:
> > I'm going over the rest of the series after I dealt with my other patch
> > backlog.
>
> Aside of the nitpicks I had, this looks pretty reasonable.

Thanks for your review.

I have sent v13 series. Please have a look.

Regards,
Anup

>
> Thanks,
>
>         tglx


From j-luthra at ti.com  Mon Feb 19 22:18:01 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Tue, 20 Feb 2024 11:48:01 +0530
Subject: [PATCH v2 0/4] arm64: dts: ti: Enable camera for SK-AM62P
Message-ID: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>

This series enables support for camera sensors using CSI-RX ports on
AM62P family of SoCs.

Particularly, it enables OV5640 and IMX219 sensors via the 22-pin FFC
CSI-RX connector on SK-AM62P [1] using the existing common overlays for
SK-AM62* family of boards.

Capture test:
https://gist.github.com/jailuthra/11f3383ccc0902b9db90d806222597a3

[1]: https://www.ti.com/tool/SK-AM62P-LP

Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
Changes in v2:
- Rebase on top of ti-k3-dts-next
- Fix commit description of PATCH 3/4 to specify we are keeping the nodes
  disabled
- Link to v1: https://lore.kernel.org/r/20240201-am62p_csi-v1-0-c83bb9eaeb49 at ti.com

Range-diff from v1:

1:  646c0b26cee4 ! 1:  61c395edcfd3 arm64: dts: ti: k3-am62p: Fix memory ranges for DMSS
    @@ Commit message
         to enable programming the interrupts correctly.

         Fixes: 29075cc09f43 ("arm64: dts: ti: Introduce AM62P5 family of SoCs")
    +    Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>
         Signed-off-by: Jai Luthra <j-luthra at ti.com>

      ## arch/arm64/boot/dts/ti/k3-am62p.dtsi ##
2:  5d6c41db44e3 ! 2:  2720ce668bf9 arm64: dts: ti: k3-am62p: Add DMASS1 for CSI
    @@ Commit message
         On AM62P, CSI-RX uses a dedicated BCDMA instance (DMASS1) for
         transferring captured camera frames to DDR, so enable it.

    +    Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>
         Signed-off-by: Jai Luthra <j-luthra at ti.com>

      ## arch/arm64/boot/dts/ti/k3-am62p-main.dtsi ##
3:  2896237c1ad1 ! 3:  9853acf0bc6f arm64: dts: ti: k3-am62p: Add nodes for CSI-RX
    @@ Commit message

         AM62P supports image capture via the MIPI CSI-2 protocol, it uses three
         IPs to achieve this: Cadence DPHY, Cadence CSI-RX, and TI's pixelgrabber
    -    wrapper on top. Enable all of these IPs in the devicetree.
    +    wrapper on top. Add nodes for these IPs in the devicetree, and keep them
    +    disabled here, so these may be enabled by the sensor overlays.

    +    Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>
         Signed-off-by: Jai Luthra <j-luthra at ti.com>

      ## arch/arm64/boot/dts/ti/k3-am62p-main.dtsi ##
4:  7a82f73e345d < -:  ------------ arm64: dts: ti: Enable overlays for SK-AM62P
-:  ------------ > 4:  1a5e859dec12 arm64: dts: ti: Enable overlays for SK-AM62P

---
Jai Luthra (4):
      arm64: dts: ti: k3-am62p: Fix memory ranges for DMSS
      arm64: dts: ti: k3-am62p: Add DMASS1 for CSI
      arm64: dts: ti: k3-am62p: Add nodes for CSI-RX
      arm64: dts: ti: Enable overlays for SK-AM62P

 arch/arm64/boot/dts/ti/Makefile           | 10 ++++
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 98 +++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am62p.dtsi      |  2 +-
 3 files changed, 109 insertions(+), 1 deletion(-)
---
base-commit: 0f9eb43f009091501dd0c68232aa6530ba0e0185
change-id: 20240201-am62p_csi-b69d172406ca

Best regards,
-- 
Jai Luthra <j-luthra at ti.com>



From j-luthra at ti.com  Mon Feb 19 22:18:02 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Tue, 20 Feb 2024 11:48:02 +0530
Subject: [PATCH v2 1/4] arm64: dts: ti: k3-am62p: Fix memory ranges for
 DMSS
In-Reply-To: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>
References: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>
Message-ID: <20240220-am62p_csi-v2-1-3e71d9945571@ti.com>

The INTR module for DMASS1 (CSI specific DMASS) is outside the currently
available ranges, as it starts at 0x4e400000. So fix the ranges property
to enable programming the interrupts correctly.

Fixes: 29075cc09f43 ("arm64: dts: ti: Introduce AM62P5 family of SoCs")
Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>
Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
index d111e044bfdf..94babc412575 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
@@ -71,7 +71,7 @@ cbass_main: bus at f0000 {
 			 <0x00 0x43600000 0x00 0x43600000 0x00 0x00010000>, /* SA3 sproxy data */
 			 <0x00 0x44043000 0x00 0x44043000 0x00 0x00000fe0>, /* TI SCI DEBUG */
 			 <0x00 0x44860000 0x00 0x44860000 0x00 0x00040000>, /* SA3 sproxy config */
-			 <0x00 0x48000000 0x00 0x48000000 0x00 0x06400000>, /* DMSS */
+			 <0x00 0x48000000 0x00 0x48000000 0x00 0x06408000>, /* DMSS */
 			 <0x00 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS0 DAT1 */
 			 <0x00 0x70000000 0x00 0x70000000 0x00 0x00010000>, /* OCSRAM */
 			 <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */

-- 
2.43.0



From j-luthra at ti.com  Mon Feb 19 22:18:03 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Tue, 20 Feb 2024 11:48:03 +0530
Subject: [PATCH v2 2/4] arm64: dts: ti: k3-am62p: Add DMASS1 for CSI
In-Reply-To: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>
References: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>
Message-ID: <20240220-am62p_csi-v2-2-3e71d9945571@ti.com>

On AM62P, CSI-RX uses a dedicated BCDMA instance (DMASS1) for
transferring captured camera frames to DDR, so enable it.

Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>
Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 37 +++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index e43530beb79f..fb328774879c 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -158,6 +158,43 @@ main_pktdma: dma-controller at 485c0000 {
 		};
 	};
 
+	dmss_csi: bus at 4e000000 {
+		compatible = "simple-bus";
+		ranges = <0x00 0x4e000000 0x00 0x4e000000 0x00 0x408000>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dma-ranges;
+		ti,sci-dev-id = <198>;
+
+		inta_main_dmss_csi: interrupt-controller at 4e400000 {
+			compatible = "ti,sci-inta";
+			reg = <0x00 0x4e400000 0x00 0x8000>;
+			#interrupt-cells = <0>;
+			interrupt-controller;
+			interrupt-parent = <&gic500>;
+			msi-controller;
+			power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+			ti,sci = <&dmsc>;
+			ti,sci-dev-id = <200>;
+			ti,interrupt-ranges = <0 237 8>;
+			ti,unmapped-event-sources = <&main_bcdma_csi>;
+		};
+
+		main_bcdma_csi: dma-controller at 4e230000 {
+			compatible = "ti,am62a-dmss-bcdma-csirx";
+			reg = <0x00 0x4e230000 0x00 0x100>,
+			      <0x00 0x4e180000 0x00 0x8000>,
+			      <0x00 0x4e100000 0x00 0x10000>;
+			reg-names = "gcfg", "rchanrt", "ringrt";
+			#dma-cells = <3>;
+			msi-parent = <&inta_main_dmss_csi>;
+			power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+			ti,sci = <&dmsc>;
+			ti,sci-dev-id = <199>;
+			ti,sci-rm-range-rchan = <0x21>;
+		};
+	};
+
 	dmsc: system-controller at 44043000 {
 		compatible = "ti,k2g-sci";
 		ti,host-id = <12>;

-- 
2.43.0



From j-luthra at ti.com  Mon Feb 19 22:18:04 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Tue, 20 Feb 2024 11:48:04 +0530
Subject: [PATCH v2 3/4] arm64: dts: ti: k3-am62p: Add nodes for CSI-RX
In-Reply-To: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>
References: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>
Message-ID: <20240220-am62p_csi-v2-3-3e71d9945571@ti.com>

AM62P supports image capture via the MIPI CSI-2 protocol, it uses three
IPs to achieve this: Cadence DPHY, Cadence CSI-RX, and TI's pixelgrabber
wrapper on top. Add nodes for these IPs in the devicetree, and keep them
disabled here, so these may be enabled by the sensor overlays.

Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>
Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 61 +++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index fb328774879c..3f271e7710d8 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -966,4 +966,65 @@ mcasp2: audio-controller at 2b20000 {
 		power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 	};
+
+	ti_csi2rx0: ticsi2rx at 30102000 {
+		compatible = "ti,j721e-csi2rx-shim";
+		reg = <0x00 0x30102000 0x00 0x1000>;
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		dmas = <&main_bcdma_csi 0 0x5000 0>;
+		dma-names = "rx0";
+		power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
+		cdns_csi2rx0: csi-bridge at 30101000 {
+			compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+			reg = <0x00 0x30101000 0x00 0x1000>;
+			clocks = <&k3_clks 182 0>, <&k3_clks 182 3>, <&k3_clks 182 0>,
+				<&k3_clks 182 0>, <&k3_clks 182 4>, <&k3_clks 182 4>;
+			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+			phys = <&dphy0>;
+			phy-names = "dphy";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				csi0_port0: port at 0 {
+					reg = <0>;
+					status = "disabled";
+				};
+
+				csi0_port1: port at 1 {
+					reg = <1>;
+					status = "disabled";
+				};
+
+				csi0_port2: port at 2 {
+					reg = <2>;
+					status = "disabled";
+				};
+
+				csi0_port3: port at 3 {
+					reg = <3>;
+					status = "disabled";
+				};
+
+				csi0_port4: port at 4 {
+					reg = <4>;
+					status = "disabled";
+				};
+			};
+		};
+	};
+
+	dphy0: phy at 30110000 {
+		compatible = "cdns,dphy-rx";
+		reg = <0x00 0x30110000 0x00 0x1100>;
+		#phy-cells = <0>;
+		power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+	};
 };

-- 
2.43.0



From j-luthra at ti.com  Mon Feb 19 22:18:05 2024
From: j-luthra at ti.com (Jai Luthra)
Date: Tue, 20 Feb 2024 11:48:05 +0530
Subject: [PATCH v2 4/4] arm64: dts: ti: Enable overlays for SK-AM62P
In-Reply-To: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>
References: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>
Message-ID: <20240220-am62p_csi-v2-4-3e71d9945571@ti.com>

Enable symbols so that overlays can be applied on the base DTB for
SK-AM62P.

Also compile-test known-to-work camera sensor overlays for OV5640 and
IMX219.

Reviewed-by: Vaishnav Achath <vaishnav.a at ti.com>
Signed-off-by: Jai Luthra <j-luthra at ti.com>
---
 arch/arm64/boot/dts/ti/Makefile | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index d601c52ab181..9843b7656725 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -116,6 +116,12 @@ k3-am62a7-sk-csi2-ov5640-dtbs := k3-am62a7-sk.dtb \
 k3-am62a7-sk-csi2-tevi-ov5640-dtbs := k3-am62a7-sk.dtb \
 	k3-am62x-sk-csi2-tevi-ov5640.dtbo
 k3-am62a7-sk-hdmi-audio-dtbs := k3-am62a7-sk.dtb k3-am62x-sk-hdmi-audio.dtbo
+k3-am62p5-sk-csi2-imx219-dtbs := k3-am62p5-sk.dtb \
+	k3-am62x-sk-csi2-imx219.dtbo
+k3-am62p5-sk-csi2-ov5640-dtbs := k3-am62p5-sk.dtb \
+	k3-am62x-sk-csi2-ov5640.dtbo
+k3-am62p5-sk-csi2-tevi-ov5640-dtbs := k3-am62p5-sk.dtb \
+	k3-am62x-sk-csi2-tevi-ov5640.dtbo
 k3-am642-evm-icssg1-dualemac-dtbs := \
 	k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
 k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
@@ -142,6 +148,9 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am62a7-sk-csi2-imx219.dtb \
 	k3-am62a7-sk-csi2-ov5640.dtb \
 	k3-am62a7-sk-hdmi-audio.dtb \
+	k3-am62p5-sk-csi2-imx219.dtb \
+	k3-am62p5-sk-csi2-ov5640.dtb \
+	k3-am62p5-sk-csi2-tevi-ov5640.dtb \
 	k3-am642-evm-icssg1-dualemac.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
@@ -156,6 +165,7 @@ DTC_FLAGS_k3-am625-beagleplay += -@
 DTC_FLAGS_k3-am625-sk += -@
 DTC_FLAGS_k3-am62-lp-sk += -@
 DTC_FLAGS_k3-am62a7-sk += -@
+DTC_FLAGS_k3-am62p5-sk += -@
 DTC_FLAGS_k3-am642-evm += -@
 DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
 DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@

-- 
2.43.0



From wenst at chromium.org  Mon Feb 19 22:40:47 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 20 Feb 2024 14:40:47 +0800
Subject: [PATCH] soc: mediatek: mtk-socinfo: depends on CONFIG_SOC_BUS
In-Reply-To: <cc8f7f7da5bdccce514a320e0ae7468659cf7346.1707327680.git.daniel@makrotopia.org>
References: <cc8f7f7da5bdccce514a320e0ae7468659cf7346.1707327680.git.daniel@makrotopia.org>
Message-ID: <CAGXv+5EKCrvsvZwc2zYiMWAeT9vqvU0JnDrz=WBoebBBbcgp0g@mail.gmail.com>

On Thu, Feb 8, 2024 at 1:43?AM Daniel Golle <daniel at makrotopia.org> wrote:
>
> The mtk-socinfo driver uses symbols 'soc_device_register' and
> 'soc_device_unregister' which are part of the bus driver for
> System-on-Chip devices.
>
> Select SOC_BUS to make sure that driver is built and the symbols are
> available.
>
> Fixes: 423a54da3c7e ("soc: mediatek: mtk-socinfo: Add driver for getting chip information")
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>

Angelo, I believe this should be picked up for -next?

Also, mediatek/v6.8-next/soc is missing from mediatek/for-next in today's
linux-next.

> ---
>  drivers/soc/mediatek/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index 50c664b65f4d4..1b7afb19ccd63 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -72,6 +72,7 @@ config MTK_SOCINFO
>         tristate "MediaTek SoC Information"
>         default y
>         depends on NVMEM_MTK_EFUSE
> +       select SOC_BUS
>         help
>           The MediaTek SoC Information (mtk-socinfo) driver provides
>           information about the SoC to the userspace including the
> --
> 2.43.0
>
>


From krzysztof.kozlowski at linaro.org  Mon Feb 19 22:56:49 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 07:56:49 +0100
Subject: [PATCH v4 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <CADrjBPqw9E5foNvZ-ETFZR3mb8=x8CYHz3UUhfJUbBpOi3iKYw@mail.gmail.com>
References: <20240208161700.268570-1-peter.griffin@linaro.org>
 <20240208161700.268570-2-peter.griffin@linaro.org>
 <ab1f9285-73ba-4b69-8882-0cf08c508e28@linaro.org>
 <CADrjBPqw9E5foNvZ-ETFZR3mb8=x8CYHz3UUhfJUbBpOi3iKYw@mail.gmail.com>
Message-ID: <d25a887e-801d-410b-9ccd-2ec10fb28f23@linaro.org>

On 19/02/2024 20:47, Peter Griffin wrote:
>>
>>> +
>>> +     if (property)
>>> +             pmu_np = of_parse_phandle(np, property, 0);
>>> +     else
>>> +             pmu_np = np;
>>> +
>>> +     if (!pmu_np)
>>> +             return ERR_PTR(-ENODEV);
>>> +
>>> +     /*
>>> +      * Determine if exynos-pmu device has probed and therefore regmap
>>> +      * has been created and can be returned to the caller. Otherwise we
>>> +      * return -EPROBE_DEFER.
>>> +      */
>>> +     dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
>>> +                                         (void *)pmu_np);
>>> +
>>> +     of_node_put(pmu_np);
>>
>> You are dropping now referencen from np when property==NULL. This does
>> no look right.
> 
> Good spot, will fix. It seems syscon.c and altera-sysmgr also have the
> same issue.
> 

Do you plan on fixing them as well in such case?

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Mon Feb 19 22:59:35 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 07:59:35 +0100
Subject: [PATCH] interconnect: constify of_phandle_args in xlate
In-Reply-To: <CZ973FMYMJAO.PQ0Z5YLXZPPM@gmail.com>
References: <20240216135236.129878-1-krzysztof.kozlowski@linaro.org>
 <488cc7dc-f45a-4c9e-b572-e4a6b3202e3e@linaro.org>
 <41e371f1-96f4-45c0-9f65-81ed6924b325@linaro.org>
 <CZ973FMYMJAO.PQ0Z5YLXZPPM@gmail.com>
Message-ID: <ac4f1b66-2407-44e9-ab97-f6583a13a428@linaro.org>

On 19/02/2024 17:27, Thierry Reding wrote:
> On Fri Feb 16, 2024 at 2:59 PM CET, Krzysztof Kozlowski wrote:
>> On 16/02/2024 14:55, Konrad Dybcio wrote:
>>> On 16.02.2024 14:52, Krzysztof Kozlowski wrote:
>>>> The xlate callbacks are supposed to translate of_phandle_args to proper
>>>> provider without modifying the of_phandle_args.  Make the argument
>>>> pointer to const for code safety and readability.
>>>>
>>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>>> ---
>>>>  drivers/gpio/gpiolib-of.c              |  2 +-
>>>>  drivers/interconnect/core.c            |  4 ++--
>>>>  drivers/interconnect/qcom/icc-common.c |  3 ++-
>>>>  drivers/interconnect/qcom/icc-common.h |  3 ++-
>>>>  drivers/interconnect/samsung/exynos.c  |  2 +-
>>>>  drivers/memory/tegra/mc.c              |  2 +-
>>>>  drivers/memory/tegra/tegra124-emc.c    |  2 +-
>>>>  drivers/memory/tegra/tegra124.c        |  2 +-
>>>>  drivers/memory/tegra/tegra186-emc.c    |  2 +-
>>>>  drivers/memory/tegra/tegra20-emc.c     |  2 +-
>>>>  drivers/memory/tegra/tegra20.c         |  2 +-
>>>>  drivers/memory/tegra/tegra30-emc.c     |  2 +-
>>>>  drivers/memory/tegra/tegra30.c         |  2 +-
>>>>  include/linux/interconnect-provider.h  | 11 ++++++-----
>>>>  include/soc/tegra/mc.h                 |  7 ++++---
>>>
>>> Ended up being a bit wider than just icc..
>>>
>>> Looks sane apart from that
>>
>> Tegra memory controllers are also interconnect providers, so two subsystems.
>>
>> This patch should go via interconnect tree.
> 
> I think Konrad might have been referring to the GPIO hunk, which seems
> out of place. For the Tegra parts, though:

Oh, that's right. I mixed up patches.

Best regards,
Krzysztof



From s-vadapalli at ti.com  Mon Feb 19 23:00:07 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Tue, 20 Feb 2024 12:30:07 +0530
Subject: [PATCH net] net: phy: realtek: Fix rtl8211f_config_init() for RTL8211F(D)(I)-VD-CG PHY
Message-ID: <20240220070007.968762-1-s-vadapalli@ti.com>

Commit bb726b753f75 ("net: phy: realtek: add support for
RTL8211F(D)(I)-VD-CG") extended support of the driver from the existing
support for RTL8211F(D)(I)-CG PHY to the newer RTL8211F(D)(I)-VD-CG PHY.

While that commit indicated that the RTL8211F_PHYCR2 register is not
supported by the "VD-CG" PHY model and therefore updated the corresponding
section in rtl8211f_config_init() to be invoked conditionally, the call to
"genphy_soft_reset()" was left as-is, when it should have also been invoked
conditionally. This is because the call to "genphy_soft_reset()" was first
introduced by the commit 0a4355c2b7f8 ("net: phy: realtek: add dt property
to disable CLKOUT clock") since the RTL8211F guide indicates that a PHY
reset should be issued after setting bits in the PHYCR2 register.

As the PHYCR2 register is not applicable to the "VD-CG" PHY model, fix the
rtl8211f_config_init() function by invoking "genphy_soft_reset()"
conditionally based on the presence of the "PHYCR2" register.

Fixes: bb726b753f75 ("net: phy: realtek: add support for RTL8211F(D)(I)-VD-CG")
Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

Hello,

This patch is based on Linux 6.8-rc5.

Regards,
Siddharth.

 drivers/net/phy/realtek.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 481c79fbd6eb..1fa70427b2a2 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -413,9 +413,11 @@ static int rtl8211f_config_init(struct phy_device *phydev)
 				ERR_PTR(ret));
 			return ret;
 		}
+
+		return genphy_soft_reset(phydev);
 	}
 
-	return genphy_soft_reset(phydev);
+	return 0;
 }
 
 static int rtl821x_suspend(struct phy_device *phydev)
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Mon Feb 19 23:22:13 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 08:22:13 +0100
Subject: [PATCH v2] interconnect: constify of_phandle_args in xlate
Message-ID: <20240220072213.35779-1-krzysztof.kozlowski@linaro.org>

The xlate callbacks are supposed to translate of_phandle_args to proper
provider without modifying the of_phandle_args.  Make the argument
pointer to const for code safety and readability.

Acked-by: Konrad Dybcio <konrad.dybcio at linaro.org>
Acked-by: Thierry Reding <treding at nvidia.com> # Tegra
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

---

Changes in v2:
1. Drop unrelated gpiolib changes (Konrad, Thierry).
2. Add tags.
---
 drivers/interconnect/core.c            |  4 ++--
 drivers/interconnect/qcom/icc-common.c |  3 ++-
 drivers/interconnect/qcom/icc-common.h |  3 ++-
 drivers/interconnect/samsung/exynos.c  |  2 +-
 drivers/memory/tegra/mc.c              |  2 +-
 drivers/memory/tegra/tegra124-emc.c    |  2 +-
 drivers/memory/tegra/tegra124.c        |  2 +-
 drivers/memory/tegra/tegra186-emc.c    |  2 +-
 drivers/memory/tegra/tegra20-emc.c     |  2 +-
 drivers/memory/tegra/tegra20.c         |  2 +-
 drivers/memory/tegra/tegra30-emc.c     |  2 +-
 drivers/memory/tegra/tegra30.c         |  2 +-
 include/linux/interconnect-provider.h  | 11 ++++++-----
 include/soc/tegra/mc.h                 |  7 ++++---
 14 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
index 50bac2d79d9b..5d1010cafed8 100644
--- a/drivers/interconnect/core.c
+++ b/drivers/interconnect/core.c
@@ -343,7 +343,7 @@ EXPORT_SYMBOL_GPL(icc_std_aggregate);
  * an array of icc nodes specified in the icc_onecell_data struct when
  * registering the provider.
  */
-struct icc_node *of_icc_xlate_onecell(struct of_phandle_args *spec,
+struct icc_node *of_icc_xlate_onecell(const struct of_phandle_args *spec,
 				      void *data)
 {
 	struct icc_onecell_data *icc_data = data;
@@ -368,7 +368,7 @@ EXPORT_SYMBOL_GPL(of_icc_xlate_onecell);
  * Returns a valid pointer to struct icc_node_data on success or ERR_PTR()
  * on failure.
  */
-struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec)
+struct icc_node_data *of_icc_get_from_provider(const struct of_phandle_args *spec)
 {
 	struct icc_node *node = ERR_PTR(-EPROBE_DEFER);
 	struct icc_node_data *data = NULL;
diff --git a/drivers/interconnect/qcom/icc-common.c b/drivers/interconnect/qcom/icc-common.c
index f27f4fdc4531..9b9ee113f172 100644
--- a/drivers/interconnect/qcom/icc-common.c
+++ b/drivers/interconnect/qcom/icc-common.c
@@ -9,7 +9,8 @@
 
 #include "icc-common.h"
 
-struct icc_node_data *qcom_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+struct icc_node_data *qcom_icc_xlate_extended(const struct of_phandle_args *spec,
+					      void *data)
 {
 	struct icc_node_data *ndata;
 	struct icc_node *node;
diff --git a/drivers/interconnect/qcom/icc-common.h b/drivers/interconnect/qcom/icc-common.h
index 33bb2c38dff3..21c39b163948 100644
--- a/drivers/interconnect/qcom/icc-common.h
+++ b/drivers/interconnect/qcom/icc-common.h
@@ -8,6 +8,7 @@
 
 #include <linux/interconnect-provider.h>
 
-struct icc_node_data *qcom_icc_xlate_extended(struct of_phandle_args *spec, void *data);
+struct icc_node_data *qcom_icc_xlate_extended(const struct of_phandle_args *spec,
+					      void *data);
 
 #endif
diff --git a/drivers/interconnect/samsung/exynos.c b/drivers/interconnect/samsung/exynos.c
index 1ba14cb45d5a..c9e5361e17c5 100644
--- a/drivers/interconnect/samsung/exynos.c
+++ b/drivers/interconnect/samsung/exynos.c
@@ -82,7 +82,7 @@ static int exynos_generic_icc_set(struct icc_node *src, struct icc_node *dst)
 	return 0;
 }
 
-static struct icc_node *exynos_generic_icc_xlate(struct of_phandle_args *spec,
+static struct icc_node *exynos_generic_icc_xlate(const struct of_phandle_args *spec,
 						 void *data)
 {
 	struct exynos_icc_priv *priv = data;
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index a083921a8968..224b488794e5 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -755,7 +755,7 @@ const char *const tegra_mc_error_names[8] = {
 	[6] = "SMMU translation error",
 };
 
-struct icc_node *tegra_mc_icc_xlate(struct of_phandle_args *spec, void *data)
+struct icc_node *tegra_mc_icc_xlate(const struct of_phandle_args *spec, void *data)
 {
 	struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
 	struct icc_node *node;
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 00ed2b6a0d1b..47c0c19e13fd 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -1285,7 +1285,7 @@ to_tegra_emc_provider(struct icc_provider *provider)
 }
 
 static struct icc_node_data *
-emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct icc_provider *provider = data;
 	struct icc_node_data *ndata;
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index 470b7dbab2c2..9d7393e19f12 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -1170,7 +1170,7 @@ static int tegra124_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
 }
 
 static struct icc_node_data *
-tegra124_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+tegra124_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
 	const struct tegra_mc_client *client;
diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c
index fcd4aea48bda..57d9ae12fcfe 100644
--- a/drivers/memory/tegra/tegra186-emc.c
+++ b/drivers/memory/tegra/tegra186-emc.c
@@ -236,7 +236,7 @@ static int tegra_emc_icc_set_bw(struct icc_node *src, struct icc_node *dst)
 }
 
 static struct icc_node *
-tegra_emc_of_icc_xlate(struct of_phandle_args *spec, void *data)
+tegra_emc_of_icc_xlate(const struct of_phandle_args *spec, void *data)
 {
 	struct icc_provider *provider = data;
 	struct icc_node *node;
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index fd595c851a27..97cf59523b0b 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -950,7 +950,7 @@ to_tegra_emc_provider(struct icc_provider *provider)
 }
 
 static struct icc_node_data *
-emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct icc_provider *provider = data;
 	struct icc_node_data *ndata;
diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
index aa4b97d5e732..a3022e715dee 100644
--- a/drivers/memory/tegra/tegra20.c
+++ b/drivers/memory/tegra/tegra20.c
@@ -390,7 +390,7 @@ static int tegra20_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
 }
 
 static struct icc_node_data *
-tegra20_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+tegra20_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
 	unsigned int i, idx = spec->args[0];
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 9eae25c57ec6..d7b0a23c2d7d 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -1468,7 +1468,7 @@ to_tegra_emc_provider(struct icc_provider *provider)
 }
 
 static struct icc_node_data *
-emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct icc_provider *provider = data;
 	struct icc_node_data *ndata;
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index 06f8b35e0a14..d3e685c8431f 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -1332,7 +1332,7 @@ static int tegra30_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
 }
 
 static struct icc_node_data *
-tegra30_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+tegra30_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
 {
 	struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
 	const struct tegra_mc_client *client;
diff --git a/include/linux/interconnect-provider.h b/include/linux/interconnect-provider.h
index 7ba183f221f1..f5aef8784692 100644
--- a/include/linux/interconnect-provider.h
+++ b/include/linux/interconnect-provider.h
@@ -36,7 +36,7 @@ struct icc_onecell_data {
 	struct icc_node *nodes[] __counted_by(num_nodes);
 };
 
-struct icc_node *of_icc_xlate_onecell(struct of_phandle_args *spec,
+struct icc_node *of_icc_xlate_onecell(const struct of_phandle_args *spec,
 				      void *data);
 
 /**
@@ -65,8 +65,9 @@ struct icc_provider {
 			 u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
 	void (*pre_aggregate)(struct icc_node *node);
 	int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);
-	struct icc_node* (*xlate)(struct of_phandle_args *spec, void *data);
-	struct icc_node_data* (*xlate_extended)(struct of_phandle_args *spec, void *data);
+	struct icc_node* (*xlate)(const struct of_phandle_args *spec, void *data);
+	struct icc_node_data* (*xlate_extended)(const struct of_phandle_args *spec,
+						void *data);
 	struct device		*dev;
 	int			users;
 	bool			inter_set;
@@ -124,7 +125,7 @@ int icc_nodes_remove(struct icc_provider *provider);
 void icc_provider_init(struct icc_provider *provider);
 int icc_provider_register(struct icc_provider *provider);
 void icc_provider_deregister(struct icc_provider *provider);
-struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec);
+struct icc_node_data *of_icc_get_from_provider(const struct of_phandle_args *spec);
 void icc_sync_state(struct device *dev);
 
 #else
@@ -171,7 +172,7 @@ static inline int icc_provider_register(struct icc_provider *provider)
 
 static inline void icc_provider_deregister(struct icc_provider *provider) { }
 
-static inline struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec)
+static inline struct icc_node_data *of_icc_get_from_provider(const struct of_phandle_args *spec)
 {
 	return ERR_PTR(-ENOTSUPP);
 }
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index af1d73a7f0cd..6ee4c59db620 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -146,13 +146,14 @@ struct tegra_mc_icc_ops {
 	int (*set)(struct icc_node *src, struct icc_node *dst);
 	int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw,
 			 u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
-	struct icc_node* (*xlate)(struct of_phandle_args *spec, void *data);
-	struct icc_node_data *(*xlate_extended)(struct of_phandle_args *spec,
+	struct icc_node* (*xlate)(const struct of_phandle_args *spec, void *data);
+	struct icc_node_data *(*xlate_extended)(const struct of_phandle_args *spec,
 						void *data);
 	int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);
 };
 
-struct icc_node *tegra_mc_icc_xlate(struct of_phandle_args *spec, void *data);
+struct icc_node *tegra_mc_icc_xlate(const struct of_phandle_args *spec,
+				    void *data);
 extern const struct tegra_mc_icc_ops tegra_mc_icc_ops;
 
 struct tegra_mc_ops {
-- 
2.34.1



From sakari.ailus at linux.intel.com  Mon Feb 19 23:25:59 2024
From: sakari.ailus at linux.intel.com (sakari.ailus at linux.intel.com)
Date: Tue, 20 Feb 2024 07:25:59 +0000
Subject: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <115698c0c549e747026cc8841a3bd571533f8e6f.camel@mediatek.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
 <20240204061538.2105-3-zhi.mao@mediatek.com>
 <20240206184542.GE2827@pendragon.ideasonboard.com>
 <598f62bbb55157eec1e23dd1dbc307fea3851b21.camel@mediatek.com>
 <20240220030104.GF20376@pendragon.ideasonboard.com>
 <115698c0c549e747026cc8841a3bd571533f8e6f.camel@mediatek.com>
Message-ID: <ZdRUB92gkbRGPyr_@kekkonen.localdomain>

Hi Zhi,

On Tue, Feb 20, 2024 at 05:45:54AM +0000, Zhi Mao (??) wrote:
> Hi Laurent,
> 
> Thanks for you reply.
> I'd like to ask for advice about how to contrl "reset-pin", please
> check the below comments.
> 
> On Tue, 2024-02-20 at 05:01 +0200, Laurent Pinchart wrote:
> >  	 
> > External email : Please do not click links or open attachments until
> > you have verified the sender or the content.
> >  Hi Zhi,
> > 
> > On Tue, Feb 20, 2024 at 02:12:26AM +0000, Zhi Mao (??) wrote:
> > > On Tue, 2024-02-06 at 20:45 +0200, Laurent Pinchart wrote:
> > > > On Sun, Feb 04, 2024 at 02:15:38PM +0800, Zhi Mao wrote:
> > > > > Add a V4L2 sub-device driver for Galaxycore GC08A3 image
> > sensor.
> > > > >
> > > > > Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> > > > > ---
> > > > >  drivers/media/i2c/Kconfig  |   10 +
> > > > >  drivers/media/i2c/Makefile |    1 +
> > > > >  drivers/media/i2c/gc08a3.c | 1448
> > ++++++++++++++++++++++++++++++++++++
> > > > >  3 files changed, 1459 insertions(+)
> > > > >  create mode 100644 drivers/media/i2c/gc08a3.c
> > 
> > [snip]
> > 
> > > > > diff --git a/drivers/media/i2c/gc08a3.c
> > b/drivers/media/i2c/gc08a3.c
> > > > > new file mode 100644
> > > > > index 000000000000..3fc7fffb815c
> > > > > --- /dev/null
> > > > > +++ b/drivers/media/i2c/gc08a3.c
> > > > > @@ -0,0 +1,1448 @@
> > 
> > [snip]
> > 
> > > > > +static int gc08a3_power_on(struct device *dev)
> > > > > +{
> > > > > +struct i2c_client *client = to_i2c_client(dev);
> > > > > +struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > > > > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > > > > +int ret;
> > > > > +
> > > > > +ret = regulator_bulk_enable(ARRAY_SIZE(gc08a3_supply_name),
> > > > > +    gc08a3->supplies);
> > > > > +if (ret < 0) {
> > > > > +dev_err(gc08a3->dev, "failed to enable regulators: %d\n",
> > ret);
> > > > > +return ret;
> > > > > +}
> > > > > +
> > > > > +ret = clk_prepare_enable(gc08a3->xclk);
> > > > > +if (ret < 0) {
> > > > > +regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
> > > > > +       gc08a3->supplies);
> > > > > +dev_err(gc08a3->dev, "clk prepare enable failed\n");
> > > > > +return ret;
> > > > > +}
> > > > > +
> > > > > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > > > > +
> > > > > +gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > > >
> > > > Are you asserting reset when powering on ? That sounds wrong, you
> > should
> > > > de-assert reset here (and acquire the reset gpio in probe() with
> > > > GPIOD_OUT_HIGH). Drivers should use logical levels for GPIOs,
> > setting a
> > > > GPIO named "reset" to 1 should assert the reset signal, even if
> > the
> > > > physical signal is active low. You may have the wrong polarity in
> > the
> > > > device tree.
> > >
> > > According to the sensor power sequence sepc, "reset" pin should be
> > pull
> > > from low to high after "dovdd/dvdd/avdd" power on, so I follow this
> > > power sequece to pull "reset" pin high in software flow.
> > 
> > From a hardware point of view that's right, but the Linux kernel
> > handles
> > logical level of GPIOs. If a GPIO is named "reset", it is expected
> > that
> > calling
> > 
> > gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > 
> > will "assert" the reset signal, setting it to a logical "reset =
> > true"
> > level. This maps to the hardware 0V output level, as the signal is
> > active-low. To achieve this, define the reset GPIO as active low in
> > DT,
> > and the GPIO framework will invert the signal for you. You should
> > then
> > call
> > 
> > gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > 
> > in the driver when you want to assert reset (set it to 0V), and
> > 
> > gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);
> > 
> > when you want to deassert it (set it to 3.3V, or whatever the I/O
> > voltage for the signal is).
> > 
> > This way all driver use logical states, and the inversion is handled
> > in
> > DT.
> > 
> 
> Sensor power sequence as below:
>                       ------------------
>                      | | |
>                      | | | 
> dvdd/avdd/dovdd  --------
>                                ---------
>                               |
>                               |
> reset-pin        -------------
> 
> In order to match this power sequece, "reset-pin" contrl flow is below:
> 1. config the "reset-pin" is "active-high" in DTS:
>     reset-gpios = <&pio 19 GPIO_ACTIVE_HIGH>;
> 
> 2. image sensor driver probe function:
> gc08a3->reset_gpio = devm_gpiod_get(dev, "reset",
> GPIOD_OUT_LOW);  //init "reset-pin" is low
> 
> 3. image sensor driver power_on function:
> gpiod_set_value_cansleep(gc08a3->reset_gpio, 1); //pull "reset-pin"
> high 
> 
> so, the expect state of "reset-pin" is from low to high.
> If I am wrong, please correct me.


>From Documentation/driver-api/gpio/consumer.rst:

	As a consumer should not have to care about the physical line
	level, all of the gpiod_set_value_xxx() or
	gpiod_set_array_value_xxx() functions operate with the *logical*
	value. With this they take the active low property into account.
	This means that they check whether the GPIO is configured to be
	active low, and if so, they manipulate the passed value before the
	physical line level is driven.

I.e. when you want to enable reset, you set the value to 1 in the driver. I
think you're now setting the value to 0 in that case. The opposite for
disabling it of course.

-- 
Regards,

Sakari Ailus


From ankita at nvidia.com  Mon Feb 19 23:29:22 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Tue, 20 Feb 2024 12:59:22 +0530
Subject: [PATCH v8 0/4] kvm: arm64: allow the VM to select DEVICE_* and NORMAL_NC for IO memory
Message-ID: <20240220072926.6466-1-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

Currently, KVM for ARM64 maps at stage 2 memory that is considered device
with DEVICE_nGnRE memory attributes; this setting overrides (per
ARM architecture [1]) any device MMIO mapping present at stage 1,
resulting in a set-up whereby a guest operating system cannot
determine device MMIO mapping memory attributes on its own but
it is always overridden by the KVM stage 2 default.

This set-up does not allow guest operating systems to select device
memory attributes independently from KVM stage-2 mappings
(refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
which turns out to be an issue in that guest operating systems
(e.g. Linux) may request to map devices MMIO regions with memory
attributes that guarantee better performance (e.g. gathering
attribute - that for some devices can generate larger PCIe memory
writes TLPs) and specific operations (e.g. unaligned transactions)
such as the NormalNC memory type.

The default device stage 2 mapping was chosen in KVM for ARM64 since
it was considered safer (i.e. it would not allow guests to trigger
uncontained failures ultimately crashing the machine) but this
turned out to be asynchronous (SError) defeating the purpose.

For these reasons, relax the KVM stage 2 device memory attributes
from DEVICE_nGnRE to Normal-NC.

Generalizing to other devices may be problematic, however. E.g.
GICv2 VCPU interface, which is effectively a shared peripheral, can
allow a guest to affect another guest's interrupt distribution. Hence
limit the change to VFIO PCI as caution. This is achieved by
making the VFIO PCI core module set a flag that is tested by KVM
to activate the code. This could be extended to other devices in
the future once that is deemed safe.

[1] section D8.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf

Applied over v6.8-rc5.

History
=======
v7 -> v8
- Changed commit message of patches 2/4 and 4/4 to include detailed
  description of the VM_ALLOW_ANY_UNCACHED flag posted by Jason in
  the commit message.
- Added more detailed comment in the vfio_pci_core about
  VM_ALLOW_ANY_UNCACHED flag.
- Rebased to v6.8-rc5.

v6 -> v7
- Changed VM_VFIO_ALLOW_WC to VM_ALLOW_ANY_UNCACHED based on suggestion
  from Alex Williamson.
- Refactored stage2_set_prot_attr() based on Will's suggestion to
  reorganize the switch cases. Also updated the case to return -EINVAL
  when both KVM_PGTABLE_PROT_DEVICE and KVM_PGTABLE_PROT_NORMAL_NC set.
- Fixed nits pointed by Oliver and Catalin.

v5 -> v6
- Rebased to v6.8-rc2

v4 -> v5
- Moved the cover letter description text to patch 1/4.
- Cleaned up stage2_set_prot_attr() based on Marc Zyngier suggestions.
- Moved the mm header file changes to a separate patch.
- Rebased to v6.7-rc3.

v3 -> v4
- Moved the vfio-pci change to use the VM_VFIO_ALLOW_WC into
  separate patch.
- Added check to warn on the case NORMAL_NC and DEVICE are
  set simultaneously.
- Fixed miscellaneous nitpicks suggested in v3.

v2 -> v3
- Added a new patch (and converted to patch series) suggested by
  Catalin Marinas to ensure the code changes are restricted to
  VFIO PCI devices.
- Introduced VM_VFIO_ALLOW_WC flag for VFIO PCI to communicate
  with VMM.
- Reverted GIC mapping to DEVICE.

v1 -> v2
- Updated commit log to the one posted by
  Lorenzo Pieralisi <lpieralisi at kernel.org> (Thanks!)
- Added new flag to represent the NORMAL_NC setting. Updated
  stage2_set_prot_attr() to handle new flag.

v7 Link:
https://lore.kernel.org/all/20240211174705.31992-1-ankita at nvidia.com/

Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>

Ankit Agrawal (4):
  kvm: arm64: introduce new flag for non-cacheable IO memory
  mm: introduce new flag to indicate wc safe
  kvm: arm64: set io memory s2 pte as normalnc for vfio pci device
  vfio: convey kvm that the vfio-pci device is wc safe

 arch/arm64/include/asm/kvm_pgtable.h |  2 ++
 arch/arm64/include/asm/memory.h      |  2 ++
 arch/arm64/kvm/hyp/pgtable.c         | 24 +++++++++++++++++++-----
 arch/arm64/kvm/mmu.c                 | 14 ++++++++++----
 drivers/vfio/pci/vfio_pci_core.c     | 18 +++++++++++++++++-
 include/linux/mm.h                   | 14 ++++++++++++++
 6 files changed, 64 insertions(+), 10 deletions(-)

-- 
2.34.1



From ankita at nvidia.com  Mon Feb 19 23:29:23 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Tue, 20 Feb 2024 12:59:23 +0530
Subject: [PATCH v8 1/4] kvm: arm64: introduce new flag for non-cacheable IO memory
In-Reply-To: <20240220072926.6466-1-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
Message-ID: <20240220072926.6466-2-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

Currently, KVM for ARM64 maps at stage 2 memory that is considered device
(i.e. it is not RAM) with DEVICE_nGnRE memory attributes; this setting
overrides (as per the ARM architecture [1]) any device MMIO mapping
present at stage 1, resulting in a set-up whereby a guest operating
system cannot determine device MMIO mapping memory attributes on its
own but it is always overridden by the KVM stage 2 default.

This set-up does not allow guest operating systems to select device
memory attributes independently from KVM stage-2 mappings
(refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
which turns out to be an issue in that guest operating systems
(e.g. Linux) may request to map devices MMIO regions with memory
attributes that guarantee better performance (e.g. gathering
attribute - that for some devices can generate larger PCIe memory
writes TLPs) and specific operations (e.g. unaligned transactions)
such as the NormalNC memory type.

The default device stage 2 mapping was chosen in KVM for ARM64 since
it was considered safer (i.e. it would not allow guests to trigger
uncontained failures ultimately crashing the machine) but this
turned out to be asynchronous (SError) defeating the purpose.

Failures containability is a property of the platform and is independent
from the memory type used for MMIO device memory mappings.

Actually, DEVICE_nGnRE memory type is even more problematic than
Normal-NC memory type in terms of faults containability in that e.g.
aborts triggered on DEVICE_nGnRE loads cannot be made, architecturally,
synchronous (i.e. that would imply that the processor should issue at
most 1 load transaction at a time - it cannot pipeline them - otherwise
the synchronous abort semantics would break the no-speculation attribute
attached to DEVICE_XXX memory).

This means that regardless of the combined stage1+stage2 mappings a
platform is safe if and only if device transactions cannot trigger
uncontained failures and that in turn relies on platform capabilities
and the device type being assigned (i.e. PCIe AER/DPC error containment
and RAS architecture[3]); therefore the default KVM device stage 2
memory attributes play no role in making device assignment safer
for a given platform (if the platform design adheres to design
guidelines outlined in [3]) and therefore can be relaxed.

For all these reasons, relax the KVM stage 2 device memory attributes
from DEVICE_nGnRE to Normal-NC.

The NormalNC was chosen over a different Normal memory type default
at stage-2 (e.g. Normal Write-through) to avoid cache allocation/snooping.

Relaxing S2 KVM device MMIO mappings to Normal-NC is not expected to
trigger any issue on guest device reclaim use cases either (i.e. device
MMIO unmap followed by a device reset) at least for PCIe devices, in that
in PCIe a device reset is architected and carried out through PCI config
space transactions that are naturally ordered with respect to MMIO
transactions according to the PCI ordering rules.

Having Normal-NC S2 default puts guests in control (thanks to
stage1+stage2 combined memory attributes rules [1]) of device MMIO
regions memory mappings, according to the rules described in [1]
and summarized here ([(S1) - stage1], [(S2) - stage 2]):

S1           |  S2           | Result
NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>

It is worth noting that currently, to map devices MMIO space to user
space in a device pass-through use case the VFIO framework applies memory
attributes derived from pgprot_noncached() settings applied to VMAs, which
result in device-nGnRnE memory attributes for the stage-1 VMM mappings.

This means that a userspace mapping for device MMIO space carried
out with the current VFIO framework and a guest OS mapping for the same
MMIO space may result in a mismatched alias as described in [2].

Defaulting KVM device stage-2 mappings to Normal-NC attributes does not
change anything in this respect, in that the mismatched aliases would
only affect (refer to [2] for a detailed explanation) ordering between
the userspace and GuestOS mappings resulting stream of transactions
(i.e. it does not cause loss of property for either stream of
transactions on its own), which is harmless given that the userspace
and GuestOS access to the device is carried out through independent
transactions streams.

A Normal-NC flag is not present today. So add a new kvm_pgtable_prot
(KVM_PGTABLE_PROT_NORMAL_NC) flag for it, along with its
corresponding PTE value 0x5 (0b101) determined from [1].

Lastly, adapt the stage2 PTE property setter function
(stage2_set_prot_attr) to handle the NormalNC attribute.

[1] section D8.5.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
[2] section B2.8 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
[3] sections 1.7.7.3/1.8.5.2/appendix C - DEN0029H_SBSA_7.1.pdf

Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 arch/arm64/include/asm/kvm_pgtable.h |  2 ++
 arch/arm64/include/asm/memory.h      |  2 ++
 arch/arm64/kvm/hyp/pgtable.c         | 24 +++++++++++++++++++-----
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index cfdf40f734b1..19278dfe7978 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -197,6 +197,7 @@ enum kvm_pgtable_stage2_flags {
  * @KVM_PGTABLE_PROT_W:		Write permission.
  * @KVM_PGTABLE_PROT_R:		Read permission.
  * @KVM_PGTABLE_PROT_DEVICE:	Device attributes.
+ * @KVM_PGTABLE_PROT_NORMAL_NC:	Normal noncacheable attributes.
  * @KVM_PGTABLE_PROT_SW0:	Software bit 0.
  * @KVM_PGTABLE_PROT_SW1:	Software bit 1.
  * @KVM_PGTABLE_PROT_SW2:	Software bit 2.
@@ -208,6 +209,7 @@ enum kvm_pgtable_prot {
 	KVM_PGTABLE_PROT_R			= BIT(2),
 
 	KVM_PGTABLE_PROT_DEVICE			= BIT(3),
+	KVM_PGTABLE_PROT_NORMAL_NC		= BIT(4),
 
 	KVM_PGTABLE_PROT_SW0			= BIT(55),
 	KVM_PGTABLE_PROT_SW1			= BIT(56),
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index d82305ab420f..449ca2ff1df6 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -173,6 +173,7 @@
  * Memory types for Stage-2 translation
  */
 #define MT_S2_NORMAL		0xf
+#define MT_S2_NORMAL_NC		0x5
 #define MT_S2_DEVICE_nGnRE	0x1
 
 /*
@@ -180,6 +181,7 @@
  * Stage-2 enforces Normal-WB and Device-nGnRE
  */
 #define MT_S2_FWB_NORMAL	6
+#define MT_S2_FWB_NORMAL_NC	5
 #define MT_S2_FWB_DEVICE_nGnRE	1
 
 #ifdef CONFIG_ARM64_4K_PAGES
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index ab9d05fcf98b..3fae5830f8d2 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -717,15 +717,29 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
 static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
 				kvm_pte_t *ptep)
 {
-	bool device = prot & KVM_PGTABLE_PROT_DEVICE;
-	kvm_pte_t attr = device ? KVM_S2_MEMATTR(pgt, DEVICE_nGnRE) :
-			    KVM_S2_MEMATTR(pgt, NORMAL);
+	kvm_pte_t attr;
 	u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS;
 
+	switch (prot & (KVM_PGTABLE_PROT_DEVICE |
+			KVM_PGTABLE_PROT_NORMAL_NC)) {
+	case KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC:
+		return -EINVAL;
+	case KVM_PGTABLE_PROT_DEVICE:
+		if (prot & KVM_PGTABLE_PROT_X)
+			return -EINVAL;
+		attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
+		break;
+	case KVM_PGTABLE_PROT_NORMAL_NC:
+		if (prot & KVM_PGTABLE_PROT_X)
+			return -EINVAL;
+		attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
+		break;
+	default:
+		attr = KVM_S2_MEMATTR(pgt, NORMAL);
+	}
+
 	if (!(prot & KVM_PGTABLE_PROT_X))
 		attr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
-	else if (device)
-		return -EINVAL;
 
 	if (prot & KVM_PGTABLE_PROT_R)
 		attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
-- 
2.34.1



From ankita at nvidia.com  Mon Feb 19 23:29:24 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Tue, 20 Feb 2024 12:59:24 +0530
Subject: [PATCH v8 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <20240220072926.6466-1-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
Message-ID: <20240220072926.6466-3-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64, allowing KVM
stage 2 device mapping attributes to use NormalNC rather than
DEVICE_nGnRE, which allows guest mappings supporting combining
attributes (WC). ARM does not architecturally guarantee this is safe,
and indeed some MMIO regions like the GICv2 VCPU interface can trigger
uncontained faults if NormalNC is used.

Even worse we expect there are platforms where even DEVICE_nGnRE can
allow uncontained faults in corner cases. Unfortunately existing ARM IP
requires platform integration to take responsibility to prevent this.

To safely use VFIO in KVM the platform must guarantee full safety in the
guest where no action taken against a MMIO mapping can trigger an
uncontained failure. We belive that most VFIO PCI platforms support this
for both mapping types, at least in common flows, based on some
expectations of how PCI IP is integrated. This can be enabled more broadly,
for instance into vfio-platform drivers, but only after the platform
vendor completes auditing for safety.

The VMA flag VM_ALLOW_ANY_UNCACHED was found to be the simplest and
cleanest way to communicate the information from VFIO to KVM that
mapping the region in S2 as NormalNC is safe. KVM consumes it to
activate the code that does the S2 mapping as NormalNC.

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: David Hildenbrand <david at redhat.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 include/linux/mm.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index f5a97dec5169..59576e56c58b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -391,6 +391,20 @@ extern unsigned int kobjsize(const void *objp);
 # define VM_UFFD_MINOR		VM_NONE
 #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
 
+/*
+ * This flag is used to connect VFIO to arch specific KVM code. It
+ * indicates that the memory under this VMA is safe for use with any
+ * non-cachable memory type inside KVM. Some VFIO devices, on some
+ * platforms, are thought to be unsafe and can cause machine crashes
+ * if KVM does not lock down the memory type.
+ */
+#ifdef CONFIG_64BIT
+#define VM_ALLOW_ANY_UNCACHED_BIT	39
+#define VM_ALLOW_ANY_UNCACHED		BIT(VM_ALLOW_ANY_UNCACHED_BIT)
+#else
+#define VM_ALLOW_ANY_UNCACHED		VM_NONE
+#endif
+
 /* Bits set in the VMA until the stack is in its final location */
 #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
 
-- 
2.34.1



From ole.orhagen at northern.tech  Mon Feb 19 23:30:42 2024
From: ole.orhagen at northern.tech (Ole Orhagen)
Date: Tue, 20 Feb 2024 08:30:42 +0100
Subject: [PATCH 1/1] ARM: dts: vexpress: Set stdout-path to serial0 in the
 chosen node
In-Reply-To: <CACRpkda=b-uZmSfqRLkkC6Lp-JbSoi+YZpwhVn9-RMOPxiXszA@mail.gmail.com>
References: <20240209112807.1345164-2-ole.orhagen@northern.tech> <CACRpkda=b-uZmSfqRLkkC6Lp-JbSoi+YZpwhVn9-RMOPxiXszA@mail.gmail.com>
Message-ID: <CAD5A3CvRNpAibArAZg11TdfKP62V9Eeb9ccUhiQwWLiGKgk+Sw@mail.gmail.com>

On Fri, Feb 9, 2024 at 2:02?PM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> On Fri, Feb 9, 2024 at 12:29?PM Ole P. Orhagen
> <ole.orhagen at northern.tech> wrote:
>
> > Specify v2m_serial0 as the device for boot console output through the
> > stdout-path in the chosen node.
> >
> > Signed-off-by: Ole P. Orhagen <ole.orhagen at northern.tech>
>
> It's also the right way to do it.
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
>
> Sudeep: are you queueing Vexpress DTS changes or do you want me
> to handle it with other Versatile-ish ARM DTS stuff?
>
> Yours,
> Linus Walleij


Is there anything else I need to do here, or can I consider this a
valid handoff and forget about it?

Yours,
Ole P.


From ankita at nvidia.com  Mon Feb 19 23:29:25 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Tue, 20 Feb 2024 12:59:25 +0530
Subject: [PATCH v8 3/4] kvm: arm64: set io memory s2 pte as normalnc for vfio pci device
In-Reply-To: <20240220072926.6466-1-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
Message-ID: <20240220072926.6466-4-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

To provide VM with the ability to get device IO memory with NormalNC
property, map device MMIO in KVM for ARM64 at stage2 as NormalNC.
Having NormalNC S2 default puts guests in control (based on [1],
"Combining stage 1 and stage 2 memory type attributes") of device
MMIO regions memory mappings. The rules are summarized below:
([(S1) - stage1], [(S2) - stage 2])

S1           |  S2           | Result
NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>

Still this cannot be generalized to non PCI devices such as GICv2.
There is insufficient information and uncertainity in the behavior
of non PCI driver. A driver must indicate support using the
new flag VM_ALLOW_ANY_UNCACHED.

Adapt KVM to make use of the flag VM_ALLOW_ANY_UNCACHED as indicator to
activate the S2 setting to NormalNc.

[1] section D8.5.5 of DDI0487J_a_a-profile_architecture_reference_manual.pdf

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Jason Gunthorpe <jgg at nvidia.com>
Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 arch/arm64/kvm/mmu.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index d14504821b79..1742fdccb432 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1381,7 +1381,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	int ret = 0;
 	bool write_fault, writable, force_pte = false;
 	bool exec_fault, mte_allowed;
-	bool device = false;
+	bool device = false, vfio_allow_any_uc = false;
 	unsigned long mmu_seq;
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
@@ -1472,6 +1472,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	gfn = fault_ipa >> PAGE_SHIFT;
 	mte_allowed = kvm_vma_mte_allowed(vma);
 
+	vfio_allow_any_uc = vma->vm_flags & VM_ALLOW_ANY_UNCACHED;
+
 	/* Don't use the VMA after the unlock -- it may have vanished */
 	vma = NULL;
 
@@ -1557,10 +1559,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	if (exec_fault)
 		prot |= KVM_PGTABLE_PROT_X;
 
-	if (device)
-		prot |= KVM_PGTABLE_PROT_DEVICE;
-	else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
+	if (device) {
+		if (vfio_allow_any_uc)
+			prot |= KVM_PGTABLE_PROT_NORMAL_NC;
+		else
+			prot |= KVM_PGTABLE_PROT_DEVICE;
+	} else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) {
 		prot |= KVM_PGTABLE_PROT_X;
+	}
 
 	/*
 	 * Under the premise of getting a FSC_PERM fault, we just need to relax
-- 
2.34.1



From dvyukov at google.com  Mon Feb 19 23:47:09 2024
From: dvyukov at google.com (Dmitry Vyukov)
Date: Tue, 20 Feb 2024 08:47:09 +0100
Subject: [PATCH] mm: Revert x86_64 and arm64 ELF_ET_DYN_BASE base
In-Reply-To: <202402162238.E5D08F5968@keescook>
References: <20170807201542.GA21271@beast> <202402162238.E5D08F5968@keescook>
Message-ID: <CACT4Y+ZnNdb1z7oSq0zb3XHFTcdEwSMFvcvLJxm1VrgnpaohMw@mail.gmail.com>

On Sat, 17 Feb 2024 at 07:50, Kees Cook <keescook at chromium.org> wrote:
>
> *extreme thread[1] necromancy*
>
> On Mon, Aug 07, 2017 at 01:15:42PM -0700, Kees Cook wrote:
> > Moving the x86_64 and arm64 PIE base from 0x555555554000 to 0x000100000000
> > broke AddressSanitizer. This is a partial revert of:
> >
> >   commit eab09532d400 ("binfmt_elf: use ELF_ET_DYN_BASE only for PIE")
> >   commit 02445990a96e ("arm64: move ELF_ET_DYN_BASE to 4GB / 4MB")
> >
> > The AddressSanitizer tool has hard-coded expectations about where
> > executable mappings are loaded. The motivation for changing the PIE
> > base in the above commits was to avoid the Stack-Clash CVEs that
> > allowed executable mappings to get too close to heap and stack. This
> > was mainly a problem on 32-bit, but the 64-bit bases were moved too,
> > in an effort to proactively protect those systems (proofs of concept
> > do exist that show 64-bit collisions, but other recent changes to fix
> > stack accounting and setuid behaviors will minimize the impact).
>
> I happened to be looking at this again today, and wondered where things
> stood. It seems like ASan's mappings are documented here:
> https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm#64-bit
>
> This implies that it would be safe to move the ELF_ET_DYN_BASE from
> 0x555555554000 down to 0x200000000000, since the shadow map ends at
> 0x10007fff7fff. (Well, anything above there would work, I was just
> picking a "round" number above it. We could just as well use
> 0x100080000000, I think.)
>
> Is this correct? I'd like to open up some more room between mmap and
> stack...

Note that there is also TSAN and MSAN with their own mappings.
These are also different per-arch, e.g. TSAN/Linux/x86_64:
https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/tsan/rtl/tsan_platform.h#L48-L58

Search "linux/" in that file for other arches, e.g.:
https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/tsan/rtl/tsan_platform.h#L156-L165
https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/tsan/rtl/tsan_platform.h#L187-L196
https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/tsan/rtl/tsan_platform.h#L218-L227
https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/tsan/rtl/tsan_platform.h#L252-L263

And MSAN mappings:
https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/msan/msan.h#L44-L61


> Thanks!
>
> -Kees
>
> [1] https://lore.kernel.org/lkml/20170807201542.GA21271 at beast/
>
> >
> > The new 32-bit PIE base is fine for ASan (since it matches the ET_EXEC
> > base), so only the 64-bit PIE base needs to be reverted to let x86 and
> > arm64 ASan binaries run again. Future changes to the 64-bit PIE base on
> > these architectures can be made optional once a more dynamic method for
> > dealing with AddressSanitizer is found. (e.g. always loading PIE into
> > the mmap region for marked binaries.)
> >
> > Reported-by: Kostya Serebryany <kcc at google.com>
> > Cc: stable at vger.kernel.org
> > Signed-off-by: Kees Cook <keescook at chromium.org>
> > ---
> >  arch/arm64/include/asm/elf.h | 4 ++--
> >  arch/x86/include/asm/elf.h   | 4 ++--
> >  2 files changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> > index acae781f7359..3288c2b36731 100644
> > --- a/arch/arm64/include/asm/elf.h
> > +++ b/arch/arm64/include/asm/elf.h
> > @@ -114,10 +114,10 @@
> >
> >  /*
> >   * This is the base location for PIE (ET_DYN with INTERP) loads. On
> > - * 64-bit, this is raised to 4GB to leave the entire 32-bit address
> > + * 64-bit, this is above 4GB to leave the entire 32-bit address
> >   * space open for things that want to use the area for 32-bit pointers.
> >   */
> > -#define ELF_ET_DYN_BASE              0x100000000UL
> > +#define ELF_ET_DYN_BASE              (2 * TASK_SIZE_64 / 3)
> >
> >  #ifndef __ASSEMBLY__
> >
> > diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
> > index 1c18d83d3f09..9aeb91935ce0 100644
> > --- a/arch/x86/include/asm/elf.h
> > +++ b/arch/x86/include/asm/elf.h
> > @@ -247,11 +247,11 @@ extern int force_personality32;
> >
> >  /*
> >   * This is the base location for PIE (ET_DYN with INTERP) loads. On
> > - * 64-bit, this is raised to 4GB to leave the entire 32-bit address
> > + * 64-bit, this is above 4GB to leave the entire 32-bit address
> >   * space open for things that want to use the area for 32-bit pointers.
> >   */
> >  #define ELF_ET_DYN_BASE              (mmap_is_ia32() ? 0x000400000UL : \
> > -                                               0x100000000UL)
> > +                                               (TASK_SIZE / 3 * 2))
> >
> >  /* 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,
> > --
> > 2.7.4
> >
> >
> > --
> > Kees Cook
> > Pixel Security
>
> --
> Kees Cook


From ankita at nvidia.com  Mon Feb 19 23:29:26 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Tue, 20 Feb 2024 12:59:26 +0530
Subject: [PATCH v8 4/4] vfio: convey kvm that the vfio-pci device is wc safe
In-Reply-To: <20240220072926.6466-1-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
Message-ID: <20240220072926.6466-5-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64,
allowing KVM stage 2 device mapping attributes to use Normal-NC
rather than DEVICE_nGnRE, which allows guest mappings
supporting combining attributes (WC). ARM does not architecturally
guarantee this is safe, and indeed some MMIO regions like the GICv2
VCPU interface can trigger uncontained faults if Normal-NC is used.

To safely use VFIO in KVM the platform must guarantee full safety
in the guest where no action taken against a MMIO mapping can
trigger an uncontained failure. We belive that most VFIO PCI
platforms support this for both mapping types, at least in common
flows, based on some expectations of how PCI IP is integrated. So
make vfio-pci set the VM_ALLOW_ANY_UNCACHED flag.

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Reviewed-by: David Hildenbrand <david at redhat.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 drivers/vfio/pci/vfio_pci_core.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 1cbc990d42e0..c93bea18fc4b 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1862,8 +1862,24 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
 	/*
 	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
 	 * change vm_flags within the fault handler.  Set them now.
+	 *
+	 * VM_ALLOW_ANY_UNCACHED: The VMA flag is implemented for ARM64,
+	 * allowing KVM stage 2 device mapping attributes to use Normal-NC
+	 * rather than DEVICE_nGnRE, which allows guest mappings
+	 * supporting combining attributes (WC). ARM does not
+	 * architecturally guarantee this is safe, and indeed some MMIO
+	 * regions like the GICv2 VCPU interface can trigger uncontained
+	 * faults if Normal-NC is used.
+	 *
+	 * To safely use VFIO in KVM the platform must guarantee full
+	 * safety in the guest where no action taken against a MMIO
+	 * mapping can trigger an uncontained failure. We belive that
+	 * most VFIO PCI platforms support this for both mapping types,
+	 * at least in common flows, based on some expectations of how
+	 * PCI IP is integrated. So set VM_ALLOW_ANY_UNCACHED in VMA flags.
 	 */
-	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+	vm_flags_set(vma, VM_ALLOW_ANY_UNCACHED | VM_IO | VM_PFNMAP |
+			VM_DONTEXPAND | VM_DONTDUMP);
 	vma->vm_ops = &vfio_pci_mmap_ops;
 
 	return 0;
-- 
2.34.1



From ck.hu at mediatek.com  Mon Feb 19 23:53:56 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 20 Feb 2024 07:53:56 +0000
Subject: [PATCH v2 1/3] Subject: [PATCH] drm/mediatek/dp: Add tee client
 application for HDCP feature
In-Reply-To: <20240205055055.25340-2-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
	 <20240205055055.25340-2-mac.shen@mediatek.com>
Message-ID: <e06c53745d18eb2b275e677e61cbd258b96f7ebf.camel@mediatek.com>

Hi, Mac:

On Mon, 2024-02-05 at 13:50 +0800, mac.shen wrote:
> Add tee client application which will be used for
> HDCP 1.x and 2.x authentication in DisplayPort.
> 
> Changes in v2:
> - remove ca folder, and change file name with lower case
> - refine the tci_t structure to make the data to tee can
>   through this structure
> - remove aux and regs from mtk_hdcp_info structure
> - remove some definitions, and use the definitions in
>   include/drm/drm_hdcp.h
> - remove useless code
> per suggestion from the previous thread:
> https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
> 9218a545c46.camel at mediatek.com/
> 
> Signed-off-by: mac.shen <mac.shen at mediatek.com>
> ---

[snip]

> +
> +struct hdcp2_handler {
> +	u8 main_state;
> +	u8 sub_state;
> +	u8 down_stream_dev_cnt;

Useless, drop it.

> +	u8 hdcp_rx_ver;

Ditto.

> +	bool send_ake_init:1;

You set send_ake_init to ture, but never check it, so it's useless,
drop it.

> +	bool get_recv_id_list:1;

Useless, drop it.

> +	bool stored_km:1;
> +	bool send_lc_init:1;

You set send_lc_init to ture, but never check it, so it's useless, drop
it.

> +	bool send_ack:1;

Useless, drop it.

> +	bool sink_is_repeater:1;

Ditto.

> +	bool recv_msg:1;
> +	bool send_pair:1;

You set send_pair to ture, but never check it, so it's useless, drop
it.

Regards,
CK

> +	u32 seq_num_v_cnt;
> +	u32 retry_cnt;
> +};
> +

From ardb at kernel.org  Mon Feb 19 23:55:21 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 20 Feb 2024 08:55:21 +0100
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <ZdOcXTvvHyl8s56I@FVFF77S0Q05N>
References: <20240206074552.541154-1-maskray@google.com> <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>
 <CAMj1kXGaF5bobHTr1pTg+-=s4Ft7+5SSbX72-NxsR_W_Yuxb8Q@mail.gmail.com>
 <CAMj1kXGw+r7yEEBA8gYBcdrqkiP=VYOSzz9YLnNavJn2snmFwA@mail.gmail.com>
 <CAMuHMdX+6fnAf8Hm6EqYJPAjrrLO9T7c=Gu3S8V_pqjSDowJ6g@mail.gmail.com>
 <CAMj1kXHh_m=V0QsiTpHrUXpFBXFbFfezdysz8quhPSgUrZg1MA@mail.gmail.com>
 <dca5b082-90d1-40ab-954f-8b3b6f51138c@app.fastmail.com> <ZdOcXTvvHyl8s56I@FVFF77S0Q05N>
Message-ID: <CAMj1kXGWiTusoFWPCwM9OVwxp5=BHPfUdG-CurO13mWOdQr6Hg@mail.gmail.com>

On Mon, 19 Feb 2024 at 19:22, Mark Rutland <mark.rutland at arm.com> wrote:
>
> On Mon, Feb 19, 2024 at 06:06:19PM +0100, Arnd Bergmann wrote:
> > On Mon, Feb 19, 2024, at 16:41, Ard Biesheuvel wrote:
> > > On Mon, 19 Feb 2024 at 15:43, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> > >> On Mon, Feb 19, 2024 at 11:57?AM Ard Biesheuvel <ardb at kernel.org> wrote:
> > >> > On Mon, 19 Feb 2024 at 11:56, Ard Biesheuvel <ardb at kernel.org> wrote:
> >
> > >> > https://godbolt.org/z/GTnf3vPaT
> > >>
> > >> I could reproduce the issue on v6.8-rc5 using arm64 defconfig
> > >> and x86_64-gcc-5.5.0-nolibc-aarch64-linux.tar.xz from
> > >> https://cdn.kernel.org/pub/tools/crosstool/files/bin/x86_64/5.5.0/:
> > >>
> > >
> > > OK, I managed to do so as well.
> > >
> > > And GCC 6.4 from the same source works correctly.
> > >
> > > Not sure whether there are any plans to bump the minimal GCC version
> > > any time soon (cc'ing Arnd), but we should probably drop this change
> > > until that happens.
> >
> > From what I can tell, we may as well formally raise the minimum
> > gcc version to 8.1+ already, as that is a version that is
> > actually used in distros, and we have been on 5.1+ for a few
> > years already.
> >
> > Not sure if there are any other benefits to gcc-8 besides
> > allowing minor cleanups.
>
> Arguably a minor cleanup, but on arm64 that'd allow us to get rid of the old
> mcount-based ftrace implementation and rely on -fpatchable-function-entry.
> On its own that'd save ~130 lines of asm and ~70 lines of C, but it'd also
> remove some constraints on other features (e.g. the mcount-based form's graph
> tracer isn't compatible with pointer authentication), it would simplify a few
> things going forwards (e.g. the implementation of RELIABLE_STACKTRACE, since we
> could rely on having ftrace_regs and a single trampoline), and the remaining
> support would be better tested.
>
> I've wanted to remove the old ftrace implementation for a while, but on its own
> it was never important/urgent enough to justify bumping to GCC 8+.
>

I don't think this is minor, tbh. Supporting two versions of the
highly complex tracing infrastructure for a toolchain that is only
used in CI seems like a waste of time and effort.

I checked x86, and it needs at least GCC 7 for retpoline support, so I
reckon at least GCC 5/6 support might be dropped there as well.


From linus.walleij at linaro.org  Tue Feb 20 00:07:02 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 20 Feb 2024 09:07:02 +0100
Subject: [PATCH 16/23] gpio: nomadik: support shared GPIO IRQs
In-Reply-To: <CAMRc=MdFBFFTYKHgDfOieNZJ+-x7ZZMiYty6buOp2J=eFUjt0Q@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-16-f88c0ccf372b@bootlin.com> <CAMRc=MdFBFFTYKHgDfOieNZJ+-x7ZZMiYty6buOp2J=eFUjt0Q@mail.gmail.com>
Message-ID: <CACRpkdZ5qJY6qQRaq=4y3yf1_ppNMDo5EfDPV_fuCHMe+C+tnQ@mail.gmail.com>

On Mon, Feb 19, 2024 at 4:48?PM Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
> >
> > Support a single IRQs used by multiple GPIO banks. Change the IRQ
> > handler type from a chained handler (as used by gpiolib
> > for ->parent_handler) to a threaded IRQ.
> >
> > Use a fake raw spinlock to ensure generic_handle_irq() is called in a
> > no-irq context. See Documentation/driver-api/gpio/driver.rst, "CHAINED
> > CASCADED GPIO IRQCHIPS" for additional information.
> >
>
> Any reason for not using preempt_disable()?

I think this needs to be discussed with tglx if Grygorii is not available.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Tue Feb 20 00:08:06 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 20 Feb 2024 09:08:06 +0100
Subject: [PATCH 17/23] gpio: nomadik: handle variadic GPIO count
In-Reply-To: <20240214-mbly-gpio-v1-17-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-17-f88c0ccf372b@bootlin.com>
Message-ID: <CACRpkdZGixhbsqO+uNw4a1Z32LgdoGr_EhZeAsjzA9hKO53s0A@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> Read the "ngpios" device-tree property to determine the number of GPIOs
> for a bank. If not available, fallback to NMK_GPIO_PER_CHIP ie 32 ie
> the current behavior.
>
> The IP block always supports 32 GPIOs, but platforms can expose a lesser
> amount. The Mobileye EyeQ5 is in this case; one bank is 29 GPIOs and
> the other is 23.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

LGTM, with Bartosz' comments addressed:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From wenst at chromium.org  Tue Feb 20 00:19:18 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 20 Feb 2024 16:19:18 +0800
Subject: [PATCH v2 1/2] dt-bindings: net: bluetooth: Add MediaTek MT7921S
 SDIO Bluetooth
In-Reply-To: <CAPDyKFofy24N7ymzTF7wiADc17Tw9FiNTYMnbxgoioMBwDKVhA@mail.gmail.com>
References: <20240126063500.2684087-1-wenst@chromium.org> <20240126063500.2684087-2-wenst@chromium.org>
 <74b9f249-fcb4-4338-bf7b-8477de6c935c@linaro.org> <CAGXv+5Hu+KsTBd1JtnKcaE3qUzPhHbunoVaH2++yfNopHtFf4g@mail.gmail.com>
 <21568334-b21f-429e-81cd-5ce77accaf3c@linaro.org> <CAGXv+5HxXzjigN3Bp96vkv71WfTJ1S2b7Wgafc4GxLmhu6+jMg@mail.gmail.com>
 <a4324473-e0c6-4d53-8de0-03b69480e40b@linaro.org> <CAGXv+5HAqmUizXztMH_nY6e+6oQh01hCtxEJXKtCn3_74-sOsQ@mail.gmail.com>
 <78241d63-3b9d-4c04-9ea5-11b45eac6f00@linaro.org> <20240130223856.GA2538998-robh@kernel.org>
 <CAGXv+5FwaNe7oesGwZ=yR0Pg82tEzEF3B0zjoex4qw+6zsSYbQ@mail.gmail.com> <CAPDyKFofy24N7ymzTF7wiADc17Tw9FiNTYMnbxgoioMBwDKVhA@mail.gmail.com>
Message-ID: <CAGXv+5Fvdp__Razz_nxcedCV_P=Wbj=F_a6=s4V4SbW4RooueA@mail.gmail.com>

On Tue, Feb 6, 2024 at 1:50?AM Ulf Hansson <ulf.hansson at linaro.org> wrote:
>
> On Wed, 31 Jan 2024 at 04:39, Chen-Yu Tsai <wenst at chromium.org> wrote:
> >
> > (+CC Ulf Hansson)
> >
> > On Wed, Jan 31, 2024 at 6:38?AM Rob Herring <robh at kernel.org> wrote:
> > >
> > > On Tue, Jan 30, 2024 at 05:25:38PM +0100, Krzysztof Kozlowski wrote:
> > > > On 30/01/2024 08:47, Chen-Yu Tsai wrote:
> > > > > On Tue, Jan 30, 2024 at 3:37?PM Krzysztof Kozlowski
> > > > > <krzysztof.kozlowski at linaro.org> wrote:
> > > > >>
> > > > >> On 30/01/2024 04:32, Chen-Yu Tsai wrote:
> > > > >>> On Mon, Jan 29, 2024 at 3:34?PM Krzysztof Kozlowski
> > > > >>> <krzysztof.kozlowski at linaro.org> wrote:
> > > > >>>>
> > > > >>>> On 29/01/2024 04:38, Chen-Yu Tsai wrote:
> > > > >>>>
> > > > >>>>>>> +allOf:
> > > > >>>>>>> +  - $ref: bluetooth-controller.yaml#
> > > > >>>>>>> +
> > > > >>>>>>> +properties:
> > > > >>>>>>> +  compatible:
> > > > >>>>>>> +    enum:
> > > > >>>>>>> +      - mediatek,mt7921s-bluetooth
> > > > >>>>>>
> > > > >>>>>> Can it be also WiFi on separate bus? How many device nodes do you need
> > > > >>>>>> for this device?
> > > > >>>>>
> > > > >>>>> For the "S" variant, WiFi is also on SDIO. For the other two variants,
> > > > >>>>> "U" and "E", WiFi goes over USB and PCIe respectively. On both those
> > > > >>>>> variants, Bluetooth can either go over USB or UART. That is what I
> > > > >>>>> gathered from the pinouts. There are a dozen GPIO pins which don't
> > > > >>>>> have detailed descriptions though. If you want a comprehensive
> > > > >>>>> binding of the whole chip and all its variants, I suggest we ask
> > > > >>>>> MediaTek to provide it instead. My goal with the binding is to document
> > > > >>>>> existing usage and allow me to upstream new device trees.
> > > > >>>>>
> > > > >>>>> For now we only need the Bluetooth node. The WiFi part is perfectly
> > > > >>>>> detectable, and the driver doesn't seem to need the WiFi reset pin.
> > > > >>>>> The Bluetooth driver only uses its reset pin to reset a hung controller.
> > > > >>>>
> > > > >>>> Then suffix "bluetooth" seems redundant.
> > > > >>>
> > > > >>> I think keeping the suffix makes more sense though. The chip is a two
> > > > >>> function piece, and this only targets one of the functions. Also, the
> > > > >>
> > > > >> That's why I asked and you said there is only one interface: SDIO.
> > > > >
> > > > > There's only one interface, SDIO, but two SDIO functions. The two
> > > > > functions, if both were to be described in the device tree, would
> > > > > be two separate nodes. We just don't have any use for the WiFi one
> > > > > right now. Does that make sense to keep the suffix?
> > > >
> > > > Number of functions does not really matter. Number of interfaces on the
> > > > bus would matter. Why would you have two separate nodes for the same
> > > > SDIO interface? Or do you want to say there are two interfaces?
> >
> > There is only one external interface. I don't know how the functions
> > are stitched together internally.
> >
> > It could be that the separate functions have nothing in common other
> > than sharing a standard external SDIO interface. Each function can be
> > individually controlled, and operations for different functions are
> > directed internally to the corresponding core.
> >
> > > Right, one device at 2 addresses on a bus should be a node with 2 "reg"
> > > entries, not 2 nodes with 1 "reg" address each.
> >
> > AFAICU that's not what the MMC controller binding, which I quote below,
> > says. It implies that each SDIO function shall be a separate node under
> > the MMC controller node.
>
> Yes, that's what we decided to go with, a long time ago. At least in
> this particular case, I think it makes sense, as each function
> (child-node) may also describe additional resources routed to each
> function.
>
> A typical description could be for a WiFi-Bluetooth combo-chip, where
> each function may have its own clocks, irqs and regulators being
> routed.

Rob, Krzysztof, does that help you understand why the binding and example
are written with bluetooth being one node and WiFi (should it ever be added)
being a separate node? It is based on the existing MMC controller bindings.

ChenYu


> >
> >
> > patternProperties:
> >   "^.*@[0-9]+$":
> >     type: object
> >     description: |
> >       On embedded systems the cards connected to a host may need
> >       additional properties. These can be specified in subnodes to the
> >       host controller node. The subnodes are identified by the
> >       standard \'reg\' property. Which information exactly can be
> >       specified depends on the bindings for the SDIO function driver
> >       for the subnode, as specified by the compatible string.
> >
> >     properties:
> >       compatible:
> >         description: |
> >           Name of SDIO function following generic names recommended
> >           practice
> >
> >       reg:
> >         items:
> >           - minimum: 0
> >             maximum: 7
> >             description:
> >               Must contain the SDIO function number of the function this
> >               subnode describes. A value of 0 denotes the memory SD
> >               function, values from 1 to 7 denote the SDIO functions.
> >
> >
> > ChenYu
>
> Kind regards
> Uffe


From liuyuntao12 at huawei.com  Tue Feb 20 00:15:27 2024
From: liuyuntao12 at huawei.com (Yuntao Liu)
Date: Tue, 20 Feb 2024 08:15:27 +0000
Subject: [PATCH -next] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
Message-ID: <20240220081527.23408-1-liuyuntao12@huawei.com>

The current arm32 architecture does not yet support the
HAVE_LD_DEAD_CODE_DATA_ELIMINATION feature. arm32 is widely used in
embedded scenarios, and enabling this feature would be beneficial for
reducing the size of the kernel image.

In order to make this work, we keep the necessary tables by annotating
them with KEEP, also it requires further changes to linker script to KEEP
some tables and wildcard compiler generated sections into the right place.

It boots normally with defconfig, vexpress_defconfig and tinyconfig.

The size comparison of zImage is as follows:
defconfig       vexpress_defconfig      tinyconfig
5137712         5138024                 424192          no dce
5032560         4997824                 298384          dce
2.0%            2.7%                    29.7%           shrink

When using smaller config file, there is a significant reduction in the
size of the zImage.

We also tested this patch on a commercially available single-board
computer, and the comparison is as follows:
a15eb_config
2161384         no dce
2092240         dce
3.2%            shrink

The zImage size has been reduced by approximately 3.2%, which is 70KB on
2.1M.

Signed-off-by: Yuntao Liu <liuyuntao12 at huawei.com>
---
 arch/arm/Kconfig                       | 1 +
 arch/arm/boot/compressed/vmlinux.lds.S | 4 ++--
 arch/arm/include/asm/vmlinux.lds.h     | 8 ++++----
 arch/arm/kernel/vmlinux.lds.S          | 6 +++---
 4 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0af6709570d1..de78ceb821df 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -113,6 +113,7 @@ config ARM
 	select HAVE_KERNEL_XZ
 	select HAVE_KPROBES if !XIP_KERNEL && !CPU_ENDIAN_BE32 && !CPU_V7M
 	select HAVE_KRETPROBES if HAVE_KPROBES
+	select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
 	select HAVE_MOD_ARCH_SPECIFIC
 	select HAVE_NMI
 	select HAVE_OPTPROBES if !THUMB2_KERNEL
diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S
index 3fcb3e62dc56..da21244aa892 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.S
+++ b/arch/arm/boot/compressed/vmlinux.lds.S
@@ -89,7 +89,7 @@ SECTIONS
      * The EFI stub always executes from RAM, and runs strictly before the
      * decompressor, so we can make an exception for its r/w data, and keep it
      */
-    *(.data.efistub .bss.efistub)
+    *(.data.* .bss.*)
     __pecoff_data_end = .;
 
     /*
@@ -125,7 +125,7 @@ SECTIONS
 
   . = BSS_START;
   __bss_start = .;
-  .bss			: { *(.bss) }
+  .bss			: { *(.bss .bss.*) }
   _end = .;
 
   . = ALIGN(8);		/* the stack must be 64-bit aligned */
diff --git a/arch/arm/include/asm/vmlinux.lds.h b/arch/arm/include/asm/vmlinux.lds.h
index 4c8632d5c432..f2ff79f740ab 100644
--- a/arch/arm/include/asm/vmlinux.lds.h
+++ b/arch/arm/include/asm/vmlinux.lds.h
@@ -42,7 +42,7 @@
 #define PROC_INFO							\
 		. = ALIGN(4);						\
 		__proc_info_begin = .;					\
-		*(.proc.info.init)					\
+		KEEP(*(.proc.info.init))				\
 		__proc_info_end = .;
 
 #define IDMAP_TEXT							\
@@ -125,13 +125,13 @@
 	__vectors_lma = .;						\
 	OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) {		\
 		.vectors {						\
-			*(.vectors)					\
+			KEEP(*(.vectors))				\
 		}							\
 		.vectors.bhb.loop8 {					\
-			*(.vectors.bhb.loop8)				\
+			KEEP(*(.vectors.bhb.loop8))			\
 		}							\
 		.vectors.bhb.bpiall {					\
-			*(.vectors.bhb.bpiall)				\
+			KEEP(*(.vectors.bhb.bpiall))			\
 		}							\
 	}								\
 	ARM_LMA(__vectors, .vectors);					\
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index bd9127c4b451..de373c6c2ae8 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -74,7 +74,7 @@ SECTIONS
 	. = ALIGN(4);
 	__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
 		__start___ex_table = .;
-		ARM_MMU_KEEP(*(__ex_table))
+		ARM_MMU_KEEP(KEEP(*(__ex_table)))
 		__stop___ex_table = .;
 	}
 
@@ -99,7 +99,7 @@ SECTIONS
 	}
 	.init.arch.info : {
 		__arch_info_begin = .;
-		*(.arch.info.init)
+		KEEP(*(.arch.info.init))
 		__arch_info_end = .;
 	}
 	.init.tagtable : {
@@ -116,7 +116,7 @@ SECTIONS
 #endif
 	.init.pv_table : {
 		__pv_table_begin = .;
-		*(.pv_table)
+		KEEP(*(.pv_table))
 		__pv_table_end = .;
 	}
 
-- 
2.34.1



From lee at kernel.org  Tue Feb 20 00:20:26 2024
From: lee at kernel.org (Lee Jones)
Date: Tue, 20 Feb 2024 08:20:26 +0000
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <ffd43756-b24e-4f19-be33-0e33047ad70c@microchip.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
 <ffd43756-b24e-4f19-be33-0e33047ad70c@microchip.com>
Message-ID: <20240220082026.GG10170@google.com>

On Tue, 20 Feb 2024, Dharma.B at microchip.com wrote:

> Hi Krzysztof,
> 
> On 12/02/24 3:53 pm, Krzysztof Kozlowski wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > 
> > On 08/02/2024 11:43, Lee Jones wrote:
> >> On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
> >>> Convert the atmel,hlcdc binding to DT schema format.
> >>>
> >>> Align clocks and clock-names properties to clearly indicate that the LCD
> >>> controller expects lvds_pll_clk when interfaced with the lvds display. This
> >>> alignment with the specific hardware requirements ensures accurate device tree
> >>> configuration for systems utilizing the HLCDC IP.
> >>>
> >>> [...]
> >>
> >> Applied, thanks!
> >>
> >> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
> >>        commit: cb946db1335b599ece363d33966bf653ed0fa58a
> >>
> > 
> > Next is still failing.
> > 
> > Dharma,
> > You must explain and clearly mark dependencies between patches.
> 
> I sincerely apologize for any confusion caused by the oversight. I have 
> organized the patches according to their dependencies in the patch 
> series, but unfortunately, I neglected to explicitly mention these 
> dependencies. I understand the importance of clear communication in our 
> collaborative efforts. Please feel free to provide guidance on how I can 
> assist you further in resolving this matter.

If this continues to be an issue, I can just remove the commit.

-- 
Lee Jones [???]


From kurt at linutronix.de  Tue Feb 20 00:22:46 2024
From: kurt at linutronix.de (Kurt Kanzenbach)
Date: Tue, 20 Feb 2024 09:22:46 +0100
Subject: [PATCH net] net: stmmac: Fix EST offset for dwmac 5.10
Message-ID: <20240220-stmmac_est-v1-1-c41f9ae2e7b7@linutronix.de>

Fix EST offset for dwmac 5.10.

Currently configuring Qbv doesn't work as expected. The schedule is
configured, but never confirmed:

|[  128.250219] imx-dwmac 428a0000.ethernet eth1: configured EST

The reason seems to be the refactoring of the EST code which set the wrong
EST offset for the dwmac 5.10. After fixing this it works as before:

|[  106.359577] imx-dwmac 428a0000.ethernet eth1: configured EST
|[  128.430715] imx-dwmac 428a0000.ethernet eth1: EST: SWOL has been switched

Tested on imx93.

Fixes: c3f3b97238f6 ("net: stmmac: Refactor EST implementation")
Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
---
 drivers/net/ethernet/stmicro/stmmac/hwif.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 1bd34b2a47e8..29367105df54 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -224,7 +224,7 @@ static const struct stmmac_hwif_entry {
 		.regs = {
 			.ptp_off = PTP_GMAC4_OFFSET,
 			.mmc_off = MMC_GMAC4_OFFSET,
-			.est_off = EST_XGMAC_OFFSET,
+			.est_off = EST_GMAC4_OFFSET,
 		},
 		.desc = &dwmac4_desc_ops,
 		.dma = &dwmac410_dma_ops,

---
base-commit: 40b9385dd8e6a0515e1c9cd06a277483556b7286
change-id: 20240220-stmmac_est-ea6884f9ba3c

Best regards,
-- 
Kurt Kanzenbach <kurt at linutronix.de>



From zhiw at nvidia.com  Tue Feb 20 00:26:39 2024
From: zhiw at nvidia.com (Zhi Wang)
Date: Tue, 20 Feb 2024 08:26:39 +0000
Subject: [PATCH v8 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <20240220072926.6466-3-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-3-ankita@nvidia.com>
Message-ID: <bc5cdc2e-50d8-435a-8f9d-a0053a99598d@nvidia.com>

On 2/20/24 07:29, Ankit Agrawal wrote:
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64, allowing KVM
> stage 2 device mapping attributes to use NormalNC rather than
> DEVICE_nGnRE, which allows guest mappings supporting combining
> attributes (WC). ARM does not architecturally guarantee this is safe,
> and indeed some MMIO regions like the GICv2 VCPU interface can trigger
> uncontained faults if NormalNC is used.
> 
> Even worse we expect there are platforms where even DEVICE_nGnRE can
> allow uncontained faults in corner cases. Unfortunately existing ARM IP
> requires platform integration to take responsibility to prevent this.
> 
> To safely use VFIO in KVM the platform must guarantee full safety in the
> guest where no action taken against a MMIO mapping can trigger an
> uncontained failure. We belive that most VFIO PCI platforms support this

A nit, let's use passive voice in the patch comment. Also belive is mostly
a typo.

> for both mapping types, at least in common flows, based on some
> expectations of how PCI IP is integrated. This can be enabled more broadly,
> for instance into vfio-platform drivers, but only after the platform
> vendor completes auditing for safety.
> 
> The VMA flag VM_ALLOW_ANY_UNCACHED was found to be the simplest and
> cleanest way to communicate the information from VFIO to KVM that
> mapping the region in S2 as NormalNC is safe. KVM consumes it to
> activate the code that does the S2 mapping as NormalNC.
> 
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
> Acked-by: David Hildenbrand <david at redhat.com>
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> ---
>   include/linux/mm.h | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
> 
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index f5a97dec5169..59576e56c58b 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -391,6 +391,20 @@ extern unsigned int kobjsize(const void *objp);
>   # define VM_UFFD_MINOR		VM_NONE
>   #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
>   
> +/*
> + * This flag is used to connect VFIO to arch specific KVM code. It
> + * indicates that the memory under this VMA is safe for use with any
> + * non-cachable memory type inside KVM. Some VFIO devices, on some
> + * platforms, are thought to be unsafe and can cause machine crashes
> + * if KVM does not lock down the memory type.
> + */
> +#ifdef CONFIG_64BIT
> +#define VM_ALLOW_ANY_UNCACHED_BIT	39
> +#define VM_ALLOW_ANY_UNCACHED		BIT(VM_ALLOW_ANY_UNCACHED_BIT)
> +#else
> +#define VM_ALLOW_ANY_UNCACHED		VM_NONE
> +#endif
> +
>   /* Bits set in the VMA until the stack is in its final location */
>   #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
>   


From krzysztof.kozlowski at linaro.org  Tue Feb 20 00:27:05 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 09:27:05 +0100
Subject: [PATCH] dt-bindings: gpio: Convert Aspeed binding to YAML schema
In-Reply-To: <20240220052918.742793-1-andrew@codeconstruct.com.au>
References: <20240220052918.742793-1-andrew@codeconstruct.com.au>
Message-ID: <0d1dd262-b6dd-4d71-9239-8b0aec8cceff@linaro.org>

On 20/02/2024 06:29, Andrew Jeffery wrote:
> Squash warnings such as:
> 

Missing subject prefix: aspeed,ast2400-gpio


> ```
> arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-galaxy100.dtb: /ahb/apb at 1e600000/gpio at 1e780000: failed to match any schema with compatible: ['aspeed,ast2400-gpio']
> ```
> 
> Signed-off-by: Andrew Jeffery <andrew at codeconstruct.com.au>

Thank you for your patch. There is something to discuss/improve.


> ---
>  .../bindings/gpio/aspeed,ast2400-gpio.yaml    | 64 +++++++++++++++++++
>  .../devicetree/bindings/gpio/gpio-aspeed.txt  | 39 -----------
>  2 files changed, 64 insertions(+), 39 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
>  delete mode 100644 Documentation/devicetree/bindings/gpio/gpio-aspeed.txt
> 
> diff --git a/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
> new file mode 100644
> index 000000000000..353c7620013f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
> @@ -0,0 +1,64 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/gpio/aspeed,ast2400-gpio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Aspeed GPIO controller
> +
> +maintainers:
> +  - Andrew Jeffery <andrew at codeconstruct.com.au>
> +
> +allOf:
> +  - $ref: /schemas/gpio/gpio.yaml#

>From where did you take it? None of the bindings have such code. Start
from recent bindings in given category when writing new ones.

Please drop it.

> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: aspeed,ast2600-gpio
> +    then:
> +      required:
> +        - ngpios

Please put entire allOf: after required: block. That's the convention
when it has something more than $ref, because we still want the most
important parts at the top of the file.

> +
> +properties:
> +  compatible:
> +    enum:
> +      - aspeed,ast2400-gpio
> +      - aspeed,ast2500-gpio
> +      - aspeed,ast2600-gpio
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +    description: The clock to use for debounce timings
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  interrupt-controller: true
> +
> +  "#interrupt-cells":
> +    const: 2
> +

ngpios with some constraints

> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - interrupt-controller
> +  - "#gpio-cells"
> +  - gpio-controller
> +
> +unevaluatedProperties: false

Instead additionalProperties: false.


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 20 00:28:40 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 09:28:40 +0100
Subject: [PATCH v5 4/4] pinctrl: nuvoton: Add ma35d1 pinctrl and GPIO
 driver
In-Reply-To: <20240220004159.1580108-5-ychuang570808@gmail.com>
References: <20240220004159.1580108-1-ychuang570808@gmail.com>
 <20240220004159.1580108-5-ychuang570808@gmail.com>
Message-ID: <b40f5b2d-d41f-47fa-8aae-30290e0d2737@linaro.org>

On 20/02/2024 01:41, Jacky Huang wrote:
> From: Jacky Huang <ychuang3 at nuvoton.com>
> 
> Add common pinctrl and GPIO driver for Nuvoton MA35 series SoC, and
> add support for ma35d1 pinctrl.
> 
> Signed-off-by: Jacky Huang <ychuang3 at nuvoton.com>
> ---
>  drivers/pinctrl/nuvoton/Kconfig          |   19 +
>  drivers/pinctrl/nuvoton/Makefile         |    2 +
>  drivers/pinctrl/nuvoton/pinctrl-ma35.c   | 1211 +++++++++++++++
>  drivers/pinctrl/nuvoton/pinctrl-ma35.h   |   51 +
>  drivers/pinctrl/nuvoton/pinctrl-ma35d1.c | 1797 ++++++++++++++++++++++
>  5 files changed, 3080 insertions(+)
>  create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.c
>  create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.h
>  create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c

Driver cannot depend on DTS, so please reorganize patchset so DTS is not
in the middle or even split the DTS to separate patchset.

Best regards,
Krzysztof



From Dharma.B at microchip.com  Tue Feb 20 00:30:38 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Tue, 20 Feb 2024 08:30:38 +0000
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <20240220082026.GG10170@google.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
 <ffd43756-b24e-4f19-be33-0e33047ad70c@microchip.com>
 <20240220082026.GG10170@google.com>
Message-ID: <9dbfbeac-3a00-4571-95c0-83e4d47737c5@microchip.com>

Hi Lee,

On 20/02/24 1:50 pm, Lee Jones wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Tue, 20 Feb 2024, Dharma.B at microchip.com wrote:
> 
>> Hi Krzysztof,
>>
>> On 12/02/24 3:53 pm, Krzysztof Kozlowski wrote:
>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>>
>>> On 08/02/2024 11:43, Lee Jones wrote:
>>>> On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
>>>>> Convert the atmel,hlcdc binding to DT schema format.
>>>>>
>>>>> Align clocks and clock-names properties to clearly indicate that the LCD
>>>>> controller expects lvds_pll_clk when interfaced with the lvds display. This
>>>>> alignment with the specific hardware requirements ensures accurate device tree
>>>>> configuration for systems utilizing the HLCDC IP.
>>>>>
>>>>> [...]
>>>>
>>>> Applied, thanks!
>>>>
>>>> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
>>>>         commit: cb946db1335b599ece363d33966bf653ed0fa58a
>>>>
>>>
>>> Next is still failing.
>>>
>>> Dharma,
>>> You must explain and clearly mark dependencies between patches.
>>
>> I sincerely apologize for any confusion caused by the oversight. I have
>> organized the patches according to their dependencies in the patch
>> series, but unfortunately, I neglected to explicitly mention these
>> dependencies. I understand the importance of clear communication in our
>> collaborative efforts. Please feel free to provide guidance on how I can
>> assist you further in resolving this matter.
> 
> If this continues to be an issue, I can just remove the commit.

There won't be any issue if both pwm and display binding goes before the 
mfd binding.

Could you please pick the display binding as well?

> 
> --
> Lee Jones [???]

-- 
With Best Regards,
Dharma B.


From neil.armstrong at linaro.org  Tue Feb 20 00:38:30 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Tue, 20 Feb 2024 09:38:30 +0100
Subject: [PATCH 8/8] arm64: dts: qcom: qrb2210-rb1: Enable the GPU
In-Reply-To: <b73e329a-02a4-46e0-bda4-5d5fae0a1180@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
 <20240219-topic-rb1_gpu-v1-8-d260fa854707@linaro.org>
 <CAA8EJppPvXfkz=wVca8aFBhFaVUe9+OiVzcQUq7D8zPbK+T1FQ@mail.gmail.com>
 <b73e329a-02a4-46e0-bda4-5d5fae0a1180@linaro.org>
Message-ID: <90290e71-6d85-4aaa-af5b-79c44bc786ef@linaro.org>

On 19/02/2024 22:37, Konrad Dybcio wrote:
> On 19.02.2024 15:49, Dmitry Baryshkov wrote:
>> On Mon, 19 Feb 2024 at 15:36, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>>>
>>> Enable the A702 GPU (also marketed as "3D accelerator by qcom [1], lol).
>>
>> Is it not?
> 
> Sure, every electronic device is also a heater, I suppose.. I found
> this wording extremely funny though


GPU (Graphics Processing Unit) isn't accurate either since it can also run compute shaders do to non graphics processing,
so 3D Accelerator isn't that different.

A proper term would be Vectorized Mathematical Computing Complex or something similar.

Neil

> 
>>
>>>
>>> [1] https://docs.qualcomm.com/bundle/publicresource/87-61720-1_REV_A_QUALCOMM_ROBOTICS_RB1_PLATFORM__QUALCOMM_QRB2210__PRODUCT_BRIEF.pdf
>>> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
>>
>> With the exception of the commit message:
> 
> :(
> 
> Konrad
> 
>>
>> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>>
>>> ---
>>>   arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 8 ++++++++
>>>   1 file changed, 8 insertions(+)
>>
>>
> 



From u.kleine-koenig at pengutronix.de  Tue Feb 20 00:39:08 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Tue, 20 Feb 2024 09:39:08 +0100
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <20240220082026.GG10170@google.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
 <ffd43756-b24e-4f19-be33-0e33047ad70c@microchip.com>
 <20240220082026.GG10170@google.com>
Message-ID: <qywehfpajronx457jzaxpynjnae6wpl5uvswetr6nrtmmcm5wl@7rl5jfqsofzn>

Hello,

On Tue, Feb 20, 2024 at 08:20:26AM +0000, Lee Jones wrote:
> On Tue, 20 Feb 2024, Dharma.B at microchip.com wrote:
> > On 12/02/24 3:53 pm, Krzysztof Kozlowski wrote:
> > > On 08/02/2024 11:43, Lee Jones wrote:
> > >> On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
> > >>> Convert the atmel,hlcdc binding to DT schema format.
> > >>>
> > >>> Align clocks and clock-names properties to clearly indicate that the LCD
> > >>> controller expects lvds_pll_clk when interfaced with the lvds display. This
> > >>> alignment with the specific hardware requirements ensures accurate device tree
> > >>> configuration for systems utilizing the HLCDC IP.
> > >>>
> > >>> [...]
> > >>
> > >> Applied, thanks!
> > >>
> > >> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
> > >>        commit: cb946db1335b599ece363d33966bf653ed0fa58a
> > >>
> > > 
> > > Next is still failing.
>
> If this continues to be an issue, I can just remove the commit.

The missing part in next is that patch 1 isn't included. So the options
are:

 a) Someone (dri or dt folks?) merges patch 1
    This fixes the state in next, though some commits stay around that
    fail dt_binding_check

 b) Someone (mfd or dt?) merges all 3 patches in one go and the two
    patches already applied are dropped.
    This makes dt_binding_check happy for all revs.

For me a) is good enough, but I guess the dri people are not aware there
is something to do for them?! Would be nice if Sam or Boris commented.

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/20240220/aca9ba9e/attachment.sig>

From arnd at arndb.de  Tue Feb 20 00:40:01 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 20 Feb 2024 09:40:01 +0100
Subject: [PATCH -next] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
In-Reply-To: <20240220081527.23408-1-liuyuntao12@huawei.com>
References: <20240220081527.23408-1-liuyuntao12@huawei.com>
Message-ID: <1342759e-b967-4ec4-98d5-48146f81f695@app.fastmail.com>

On Tue, Feb 20, 2024, at 09:15, Yuntao Liu wrote:
> The current arm32 architecture does not yet support the
> HAVE_LD_DEAD_CODE_DATA_ELIMINATION feature. arm32 is widely used in
> embedded scenarios, and enabling this feature would be beneficial for
> reducing the size of the kernel image.
>
> In order to make this work, we keep the necessary tables by annotating
> them with KEEP, also it requires further changes to linker script to KEEP
> some tables and wildcard compiler generated sections into the right place.

Thanks for the patch, I think this is a very useful feature
and we should get this upstream, especially if we can combine
it with CONFIG_LTO_CLANG (which is supported on arm64 at the
moment, but not on arm).

> It boots normally with defconfig, vexpress_defconfig and tinyconfig.
>
> The size comparison of zImage is as follows:
> defconfig       vexpress_defconfig      tinyconfig
> 5137712         5138024                 424192          no dce
> 5032560         4997824                 298384          dce
> 2.0%            2.7%                    29.7%           shrink
>
> When using smaller config file, there is a significant reduction in the
> size of the zImage.
>
> We also tested this patch on a commercially available single-board
> computer, and the comparison is as follows:
> a15eb_config
> 2161384         no dce
> 2092240         dce
> 3.2%            shrink
>
> The zImage size has been reduced by approximately 3.2%, which is 70KB on
> 2.1M.

Nice description! I do suspect that there will be additional
bugs that we run into with some corner cases.

> diff --git a/arch/arm/boot/compressed/vmlinux.lds.S 
> b/arch/arm/boot/compressed/vmlinux.lds.S
> index 3fcb3e62dc56..da21244aa892 100644
> --- a/arch/arm/boot/compressed/vmlinux.lds.S
> +++ b/arch/arm/boot/compressed/vmlinux.lds.S
> @@ -89,7 +89,7 @@ SECTIONS
>       * The EFI stub always executes from RAM, and runs strictly before 
> the
>       * decompressor, so we can make an exception for its r/w data, and 
> keep it
>       */
> -    *(.data.efistub .bss.efistub)
> +    *(.data.* .bss.*)
>      __pecoff_data_end = .;
> 
>      /*

This doesn't seem right to me, or maybe I misunderstand what
the original version does. Have you tested with both
CONFIG_EFI_STUB on and off, and booting with and without
UEFI?

If I read this right, you would move all .data and .bss
into the stub here, not just the parts we actually want?

> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
> index bd9127c4b451..de373c6c2ae8 100644
> --- a/arch/arm/kernel/vmlinux.lds.S
> +++ b/arch/arm/kernel/vmlinux.lds.S
> @@ -74,7 +74,7 @@ SECTIONS
>  	. = ALIGN(4);
>  	__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
>  		__start___ex_table = .;
> -		ARM_MMU_KEEP(*(__ex_table))
> +		ARM_MMU_KEEP(KEEP(*(__ex_table)))
>  		__stop___ex_table = .;
>  	}
> 
> @@ -116,7 +116,7 @@ SECTIONS
>  #endif
>  	.init.pv_table : {
>  		__pv_table_begin = .;
> -		*(.pv_table)
> +		KEEP(*(.pv_table))
>  		__pv_table_end = .;
>  	}

I guess this prevents discarding any function that has a reference
from pv_table or ex_table, even if there are no other references,
right?

I don't know how to solve this other than forcing all the
uaccess and virt_to_phys functions to be out of line
helpers. For uaccess, there are probably very few functions
that need this, so it should make little difference.

You might want to try changing CONFIG_ARM_PATCH_PHYS_VIRT
into a method that just always adds an offset from C code
instead of the boot time patching. That way the code would
be a bit less efficient but you might be able to get
a larger size reduction by dropping additional unused code.

Maybe test your patch both with and without
ARM_PATCH_PHYS_VIRT to see what the best-case impact would
be.

      Arnd


From krzysztof.kozlowski at linaro.org  Tue Feb 20 00:43:21 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 09:43:21 +0100
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <ffd43756-b24e-4f19-be33-0e33047ad70c@microchip.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
 <ffd43756-b24e-4f19-be33-0e33047ad70c@microchip.com>
Message-ID: <e6fdfb54-aa2c-4c17-a5c2-4d12abf2591c@linaro.org>

On 20/02/2024 04:34, Dharma.B at microchip.com wrote:
> Hi Krzysztof,
> 
> On 12/02/24 3:53 pm, Krzysztof Kozlowski wrote:
>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>
>> On 08/02/2024 11:43, Lee Jones wrote:
>>> On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
>>>> Convert the atmel,hlcdc binding to DT schema format.
>>>>
>>>> Align clocks and clock-names properties to clearly indicate that the LCD
>>>> controller expects lvds_pll_clk when interfaced with the lvds display. This
>>>> alignment with the specific hardware requirements ensures accurate device tree
>>>> configuration for systems utilizing the HLCDC IP.
>>>>
>>>> [...]
>>>
>>> Applied, thanks!
>>>
>>> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
>>>        commit: cb946db1335b599ece363d33966bf653ed0fa58a
>>>
>>
>> Next is still failing.
>>
>> Dharma,
>> You must explain and clearly mark dependencies between patches.
> 
> I sincerely apologize for any confusion caused by the oversight. I have 
> organized the patches according to their dependencies in the patch 

Does it mean that all your other patchsets which contain multiple
patches have dependencies? That would be the meaning of above approach.
Unfortunately that's not good... I'll comment in other places for
individual issues.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 20 00:45:21 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 09:45:21 +0100
Subject: [PATCH v3 4/4] ARM: configs: at91: Enable LVDS serializer support
In-Reply-To: <20240207102802.200220-5-dharma.b@microchip.com>
References: <20240207102802.200220-1-dharma.b@microchip.com>
 <20240207102802.200220-5-dharma.b@microchip.com>
Message-ID: <5f1c9b8b-1e64-4b44-b7d5-a8f8136710a1@linaro.org>

On 07/02/2024 11:28, Dharma Balasubiramani wrote:
> Enable LVDS serializer support for display pipeline.
> 
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> Acked-by: Hari Prasath Gujulan Elango <hari.prasathge at microchip.com>
> Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
> ---
> Changelog
> v2 -> v3
> - No Changes.
> ---

In other email thread you mentioned that this depends on driver changes,
while that's only partially correct. This patch does not make sense if
others are not accepted, but the others are not dependency for this one.
This should go via arm soc.

In the future, please state clearly dependencies in cover letter or each
patch changelog (so ---, not commit msg).

Best regards,
Krzysztof



From ardb at kernel.org  Tue Feb 20 00:49:58 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 20 Feb 2024 09:49:58 +0100
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <CAMj1kXGWiTusoFWPCwM9OVwxp5=BHPfUdG-CurO13mWOdQr6Hg@mail.gmail.com>
References: <20240206074552.541154-1-maskray@google.com> <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>
 <CAMj1kXGaF5bobHTr1pTg+-=s4Ft7+5SSbX72-NxsR_W_Yuxb8Q@mail.gmail.com>
 <CAMj1kXGw+r7yEEBA8gYBcdrqkiP=VYOSzz9YLnNavJn2snmFwA@mail.gmail.com>
 <CAMuHMdX+6fnAf8Hm6EqYJPAjrrLO9T7c=Gu3S8V_pqjSDowJ6g@mail.gmail.com>
 <CAMj1kXHh_m=V0QsiTpHrUXpFBXFbFfezdysz8quhPSgUrZg1MA@mail.gmail.com>
 <dca5b082-90d1-40ab-954f-8b3b6f51138c@app.fastmail.com> <ZdOcXTvvHyl8s56I@FVFF77S0Q05N>
 <CAMj1kXGWiTusoFWPCwM9OVwxp5=BHPfUdG-CurO13mWOdQr6Hg@mail.gmail.com>
Message-ID: <CAMj1kXFK6nf3YM8d0Tfn+yBRnHCrNj3rGON9pdV7EuCGPEVpTg@mail.gmail.com>

On Tue, 20 Feb 2024 at 08:55, Ard Biesheuvel <ardb at kernel.org> wrote:
>
> On Mon, 19 Feb 2024 at 19:22, Mark Rutland <mark.rutland at arm.com> wrote:
> >
> > On Mon, Feb 19, 2024 at 06:06:19PM +0100, Arnd Bergmann wrote:
> > > On Mon, Feb 19, 2024, at 16:41, Ard Biesheuvel wrote:
> > > > On Mon, 19 Feb 2024 at 15:43, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> > > >> On Mon, Feb 19, 2024 at 11:57?AM Ard Biesheuvel <ardb at kernel.org> wrote:
> > > >> > On Mon, 19 Feb 2024 at 11:56, Ard Biesheuvel <ardb at kernel.org> wrote:
> > >
> > > >> > https://godbolt.org/z/GTnf3vPaT
> > > >>
> > > >> I could reproduce the issue on v6.8-rc5 using arm64 defconfig
> > > >> and x86_64-gcc-5.5.0-nolibc-aarch64-linux.tar.xz from
> > > >> https://cdn.kernel.org/pub/tools/crosstool/files/bin/x86_64/5.5.0/:
> > > >>
> > > >
> > > > OK, I managed to do so as well.
> > > >
> > > > And GCC 6.4 from the same source works correctly.
> > > >
> > > > Not sure whether there are any plans to bump the minimal GCC version
> > > > any time soon (cc'ing Arnd), but we should probably drop this change
> > > > until that happens.
> > >
> > > From what I can tell, we may as well formally raise the minimum
> > > gcc version to 8.1+ already, as that is a version that is
> > > actually used in distros, and we have been on 5.1+ for a few
> > > years already.
> > >
> > > Not sure if there are any other benefits to gcc-8 besides
> > > allowing minor cleanups.
> >
> > Arguably a minor cleanup, but on arm64 that'd allow us to get rid of the old
> > mcount-based ftrace implementation and rely on -fpatchable-function-entry.
> > On its own that'd save ~130 lines of asm and ~70 lines of C, but it'd also
> > remove some constraints on other features (e.g. the mcount-based form's graph
> > tracer isn't compatible with pointer authentication), it would simplify a few
> > things going forwards (e.g. the implementation of RELIABLE_STACKTRACE, since we
> > could rely on having ftrace_regs and a single trampoline), and the remaining
> > support would be better tested.
> >
> > I've wanted to remove the old ftrace implementation for a while, but on its own
> > it was never important/urgent enough to justify bumping to GCC 8+.
> >
>
> I don't think this is minor, tbh. Supporting two versions of the
> highly complex tracing infrastructure for a toolchain that is only
> used in CI seems like a waste of time and effort.
>
> I checked x86, and it needs at least GCC 7 for retpoline support, so I
> reckon at least GCC 5/6 support might be dropped there as well.

Another data point: __GCC_ASM_FLAG_OUTPUTS__ needs GCC 6 or later on x86.


From Dharma.B at microchip.com  Tue Feb 20 00:50:46 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Tue, 20 Feb 2024 08:50:46 +0000
Subject: [PATCH v3 4/4] ARM: configs: at91: Enable LVDS serializer support
In-Reply-To: <5f1c9b8b-1e64-4b44-b7d5-a8f8136710a1@linaro.org>
References: <20240207102802.200220-1-dharma.b@microchip.com>
 <20240207102802.200220-5-dharma.b@microchip.com>
 <5f1c9b8b-1e64-4b44-b7d5-a8f8136710a1@linaro.org>
Message-ID: <f7dbee94-8334-4282-8b10-4b15e7f32184@microchip.com>

Hi Krzysztof,

On 20/02/24 2:15 pm, Krzysztof Kozlowski wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On 07/02/2024 11:28, Dharma Balasubiramani wrote:
>> Enable LVDS serializer support for display pipeline.
>>
>> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
>> Acked-by: Hari Prasath Gujulan Elango <hari.prasathge at microchip.com>
>> Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
>> ---
>> Changelog
>> v2 -> v3
>> - No Changes.
>> ---
> 
> In other email thread you mentioned that this depends on driver changes,
> while that's only partially correct. This patch does not make sense if
> others are not accepted, but the others are not dependency for this one.
> This should go via arm soc.
> 
> In the future, please state clearly dependencies in cover letter or each
> patch changelog (so ---, not commit msg).

Understood, Thanks for the comprehensive explanation. I will take care 
of this in future.

> 
> Best regards,
> Krzysztof
> 

-- 
With Best Regards,
Dharma B.


From ankita at nvidia.com  Tue Feb 20 00:51:45 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Tue, 20 Feb 2024 08:51:45 +0000
Subject: [PATCH v8 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <bc5cdc2e-50d8-435a-8f9d-a0053a99598d@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-3-ankita@nvidia.com>
 <bc5cdc2e-50d8-435a-8f9d-a0053a99598d@nvidia.com>
Message-ID: <SA1PR12MB71992963218C5753F346B3D7B0502@SA1PR12MB7199.namprd12.prod.outlook.com>

>> To safely use VFIO in KVM the platform must guarantee full safety in the
>> guest where no action taken against a MMIO mapping can trigger an
>> uncontained failure. We belive that most VFIO PCI platforms support this
>
> A nit, let's use passive voice in the patch comment. Also belive is mostly
> a typo.

Sure, will do.

From angelogioacchino.delregno at collabora.com  Tue Feb 20 00:54:08 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 20 Feb 2024 09:54:08 +0100
Subject: [PATCH v2 2/2] arm64: dts: mediatek: add Kontron 3.5"-SBC-i1200
In-Reply-To: <CZ93XYV3MB10.YRCFWLLHIICY@kernel.org>
References: <20240219084456.1075445-1-mwalle@kernel.org>
 <20240219084456.1075445-2-mwalle@kernel.org>
 <2ad6bda8-a457-421b-b35d-dc005fb00ae9@collabora.com>
 <CZ92W3VSYV1A.1693O76GY1XDP@kernel.org>
 <b50d49fd-2976-46fc-9f35-354fb39720ad@collabora.com>
 <CZ93XYV3MB10.YRCFWLLHIICY@kernel.org>
Message-ID: <e0c44c03-8c66-4a44-9c6d-6b8c83e9d16f@collabora.com>

Il 19/02/24 14:59, Michael Walle ha scritto:
> On Mon Feb 19, 2024 at 2:35 PM CET, AngeloGioacchino Del Regno wrote:
>>>> vbus is always supplied by something, as otherwise USB won't work - whether this
>>>> is an always-on regulator or a passthrough from external supply this doesn't really
>>>> matter - you should model a regulator-fixed that provides the 5V VBUS line.
>>>
>>> I don't think this is correct, though. Think of an on-board USB
>>> hub. There only D+/D- are connected (and maybe the USB3.2 SerDes
>>> lanes). Or have a look at the M.2 pinout. There is no Vbus.
>>>
>>
>> Yes but the MediaTek MTU3 and/or controllers do have it ;-)
> 
> .. and ..
> 
>>>> For example:
>>>> 	vbus_fixed: regulator-vbus {
>>>> 		compatible = "regulator-fixed";
>>>> 		regulator-name = "usb-vbus";
>>>> 		regulator-always-on;
>>>> 		regulator-boot-on;
>>>> 		regulator-min-microvolt = <5000000>;
>>>> 		regulator-max-microvolt = <5000000>;
>>>> 	};
>>>
>>> As mentioned above, I don't think this will make sense in my case.
>>>   >> P.S.: If the rail has a different name, please use that different name. Obviously
>>>> that requires you to have schematics at hand, and I don't know if you do: if you
>>>> don't, then that regulator-vbus name is just fine.
>>>
>>> I do have the schematics.
>>
>> In that case, you should model the power tree with the fixed power lines,
>> check mt8195-cherry (and/or cherry-tomato) and radxa-nio-12l; even though
>> those are technically "doing nothing", this is device tree, so it should
>> provide a description of the hardware ... and the board does have fixed
>> power lines.
>> It has at least one: DC-IN (typec, barrel jack or whatever, the board needs
>> power, doesn't it?!).
> 
> Mh, maybe I don't get it. But within the hardware there is simply no
> Vbus. Thus I'd argue it doesn't make sense to have a vbus-supply
> property. Besides, the mediatek,mtu3.yaml binding lists it as
> deprecated anyway and it should rather be on the connector. There,
> it makes perfectly sense (at least if it's a USB connector).
> 
> Thus in my case, the xhci for the front port has a vbus-supply
> property (but it should rather have a connector node, as I've just
> learned). But the internal port which connects to the USB hub
> shouldn't have one.
> 
> 
>    +-----+           +-----+                  +------+
>    |     |<--Dp/Dn-->|     |<------Dp/Dn----->| USB  |
>    | SoC |           |     |                  | Conn |
>    |     |           |     |   +-----+        |      |
>    +-----+           | USB |   | PWR |--Vbus->|      |
>                      | Hub |   | SW  |        +------+
>                      |     |   +-----+
>                      |     |     ^
>                      |     |     | PRTPWR
>                      |     |-----'
>                      +-----+
> 
> "PWR SW" is a power switch, the input (+5V) isn't shown here. The
> power will be enabled by the USB Hub.
> 

Ok then, put the vbus on the connector, where applicable.

If PWR_SW is a physical switch (not detectable), then you can still model it as an
always-on regulator-fixed, as there's no other clean way of doing that.

As for modeling the power tree with the fixed power lines, I mean that you should
add the power rails as described in your schematics.
You will surely have one DC-IN supply, and others. That should be modeled as a
fixed regulator, which outputs to (probably) the PMIC, using it as an input for
its buck regulators.

Again, your PMIC must be getting a voltage from somewhere in order to regulate
that to a different voltage for a different power rail, right? :-)

Regards,
Angelo


From angelogioacchino.delregno at collabora.com  Tue Feb 20 00:56:05 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 20 Feb 2024 09:56:05 +0100
Subject: [PATCH] soc: mediatek: mtk-socinfo: depends on CONFIG_SOC_BUS
In-Reply-To: <CAGXv+5EKCrvsvZwc2zYiMWAeT9vqvU0JnDrz=WBoebBBbcgp0g@mail.gmail.com>
References: <cc8f7f7da5bdccce514a320e0ae7468659cf7346.1707327680.git.daniel@makrotopia.org>
 <CAGXv+5EKCrvsvZwc2zYiMWAeT9vqvU0JnDrz=WBoebBBbcgp0g@mail.gmail.com>
Message-ID: <f1fc67d4-f979-4c3e-988f-a803b7b11c46@collabora.com>

Il 20/02/24 07:40, Chen-Yu Tsai ha scritto:
> On Thu, Feb 8, 2024 at 1:43?AM Daniel Golle <daniel at makrotopia.org> wrote:
>>
>> The mtk-socinfo driver uses symbols 'soc_device_register' and
>> 'soc_device_unregister' which are part of the bus driver for
>> System-on-Chip devices.
>>
>> Select SOC_BUS to make sure that driver is built and the symbols are
>> available.
>>
>> Fixes: 423a54da3c7e ("soc: mediatek: mtk-socinfo: Add driver for getting chip information")
>> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> 
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
> 
> Angelo, I believe this should be picked up for -next?
> 

I'll pick this up for fixes, as I've already sent the PRs for v6.9.

> Also, mediatek/v6.8-next/soc is missing from mediatek/for-next in today's
> linux-next.
> 

Fixing immediately.

>> ---
>>   drivers/soc/mediatek/Kconfig | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
>> index 50c664b65f4d4..1b7afb19ccd63 100644
>> --- a/drivers/soc/mediatek/Kconfig
>> +++ b/drivers/soc/mediatek/Kconfig
>> @@ -72,6 +72,7 @@ config MTK_SOCINFO
>>          tristate "MediaTek SoC Information"
>>          default y
>>          depends on NVMEM_MTK_EFUSE
>> +       select SOC_BUS
>>          help
>>            The MediaTek SoC Information (mtk-socinfo) driver provides
>>            information about the SoC to the userspace including the
>> --
>> 2.43.0
>>
>>




From matthias.bgg at gmail.com  Tue Feb 20 00:59:30 2024
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Tue, 20 Feb 2024 09:59:30 +0100
Subject: [PATCH] soc: mediatek: mtk-socinfo: depends on CONFIG_SOC_BUS
In-Reply-To: <cc8f7f7da5bdccce514a320e0ae7468659cf7346.1707327680.git.daniel@makrotopia.org>
References: <cc8f7f7da5bdccce514a320e0ae7468659cf7346.1707327680.git.daniel@makrotopia.org>
Message-ID: <d7c1569b-30b3-45eb-bf41-44c1e9d0659f@gmail.com>



On 07/02/2024 18:42, Daniel Golle wrote:
> The mtk-socinfo driver uses symbols 'soc_device_register' and
> 'soc_device_unregister' which are part of the bus driver for
> System-on-Chip devices.
> 
> Select SOC_BUS to make sure that driver is built and the symbols are
> available.
> 
> Fixes: 423a54da3c7e ("soc: mediatek: mtk-socinfo: Add driver for getting chip information")
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>

Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

> ---
>   drivers/soc/mediatek/Kconfig | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index 50c664b65f4d4..1b7afb19ccd63 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -72,6 +72,7 @@ config MTK_SOCINFO
>   	tristate "MediaTek SoC Information"
>   	default y
>   	depends on NVMEM_MTK_EFUSE
> +	select SOC_BUS
>   	help
>   	  The MediaTek SoC Information (mtk-socinfo) driver provides
>   	  information about the SoC to the userspace including the


From dan.carpenter at linaro.org  Tue Feb 20 01:02:31 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Tue, 20 Feb 2024 12:02:31 +0300
Subject: [PATCH] char: xilinx_hwicap: Fix NULL vs IS_ERR() bug
Message-ID: <ef647a9c-b1b7-4338-9bc0-28165ec2a367@moroto.mountain>

The devm_platform_ioremap_resource() function returns error pointers.
It never returns NULL.  Update the check accordingly.

Fixes: 672371832193 ("char: xilinx_hwicap: Modernize driver probe")
Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>
---
 drivers/char/xilinx_hwicap/xilinx_hwicap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 019cf6079cec..6d2eadefd9dc 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -639,8 +639,8 @@ static int hwicap_setup(struct platform_device *pdev, int id,
 	dev_set_drvdata(dev, (void *)drvdata);
 
 	drvdata->base_address = devm_platform_ioremap_resource(pdev, 0);
-	if (!drvdata->base_address) {
-		retval = -ENODEV;
+	if (IS_ERR(drvdata->base_address)) {
+		retval = PTR_ERR(drvdata->base_address);
 		goto failed;
 	}
 
-- 
2.43.0



From wenst at chromium.org  Tue Feb 20 01:03:02 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 20 Feb 2024 17:03:02 +0800
Subject: [PATCH] soc: mediatek: mtk-socinfo: depends on CONFIG_SOC_BUS
In-Reply-To: <f1fc67d4-f979-4c3e-988f-a803b7b11c46@collabora.com>
References: <cc8f7f7da5bdccce514a320e0ae7468659cf7346.1707327680.git.daniel@makrotopia.org>
 <CAGXv+5EKCrvsvZwc2zYiMWAeT9vqvU0JnDrz=WBoebBBbcgp0g@mail.gmail.com> <f1fc67d4-f979-4c3e-988f-a803b7b11c46@collabora.com>
Message-ID: <CAGXv+5Gxc3OP8nE681C6YQbDMUNmFDf21BfSvJZPBFgoncve=A@mail.gmail.com>

On Tue, Feb 20, 2024 at 4:56?PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Il 20/02/24 07:40, Chen-Yu Tsai ha scritto:
> > On Thu, Feb 8, 2024 at 1:43?AM Daniel Golle <daniel at makrotopia.org> wrote:
> >>
> >> The mtk-socinfo driver uses symbols 'soc_device_register' and
> >> 'soc_device_unregister' which are part of the bus driver for
> >> System-on-Chip devices.
> >>
> >> Select SOC_BUS to make sure that driver is built and the symbols are
> >> available.
> >>
> >> Fixes: 423a54da3c7e ("soc: mediatek: mtk-socinfo: Add driver for getting chip information")
> >> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> >
> > Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
> >
> > Angelo, I believe this should be picked up for -next?
> >
>
> I'll pick this up for fixes, as I've already sent the PRs for v6.9.

The socinfo driver is in -next, so I guess you could pick it up as a fix
for v6.9.

ChenYu

> > Also, mediatek/v6.8-next/soc is missing from mediatek/for-next in today's
> > linux-next.
> >
>
> Fixing immediately.
>
> >> ---
> >>   drivers/soc/mediatek/Kconfig | 1 +
> >>   1 file changed, 1 insertion(+)
> >>
> >> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> >> index 50c664b65f4d4..1b7afb19ccd63 100644
> >> --- a/drivers/soc/mediatek/Kconfig
> >> +++ b/drivers/soc/mediatek/Kconfig
> >> @@ -72,6 +72,7 @@ config MTK_SOCINFO
> >>          tristate "MediaTek SoC Information"
> >>          default y
> >>          depends on NVMEM_MTK_EFUSE
> >> +       select SOC_BUS
> >>          help
> >>            The MediaTek SoC Information (mtk-socinfo) driver provides
> >>            information about the SoC to the userspace including the
> >> --
> >> 2.43.0
> >>
> >>
>
>


From angelogioacchino.delregno at collabora.com  Tue Feb 20 01:03:48 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 20 Feb 2024 10:03:48 +0100
Subject: [PATCH] soc: mediatek: mtk-socinfo: depends on CONFIG_SOC_BUS
In-Reply-To: <CAGXv+5Gxc3OP8nE681C6YQbDMUNmFDf21BfSvJZPBFgoncve=A@mail.gmail.com>
References: <cc8f7f7da5bdccce514a320e0ae7468659cf7346.1707327680.git.daniel@makrotopia.org>
 <CAGXv+5EKCrvsvZwc2zYiMWAeT9vqvU0JnDrz=WBoebBBbcgp0g@mail.gmail.com>
 <f1fc67d4-f979-4c3e-988f-a803b7b11c46@collabora.com>
 <CAGXv+5Gxc3OP8nE681C6YQbDMUNmFDf21BfSvJZPBFgoncve=A@mail.gmail.com>
Message-ID: <ab809d89-339a-44fc-8a5a-ac667d220ce1@collabora.com>

Il 20/02/24 10:03, Chen-Yu Tsai ha scritto:
> On Tue, Feb 20, 2024 at 4:56?PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno at collabora.com> wrote:
>>
>> Il 20/02/24 07:40, Chen-Yu Tsai ha scritto:
>>> On Thu, Feb 8, 2024 at 1:43?AM Daniel Golle <daniel at makrotopia.org> wrote:
>>>>
>>>> The mtk-socinfo driver uses symbols 'soc_device_register' and
>>>> 'soc_device_unregister' which are part of the bus driver for
>>>> System-on-Chip devices.
>>>>
>>>> Select SOC_BUS to make sure that driver is built and the symbols are
>>>> available.
>>>>
>>>> Fixes: 423a54da3c7e ("soc: mediatek: mtk-socinfo: Add driver for getting chip information")
>>>> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
>>>
>>> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
>>>
>>> Angelo, I believe this should be picked up for -next?
>>>
>>
>> I'll pick this up for fixes, as I've already sent the PRs for v6.9.
> 
> The socinfo driver is in -next, so I guess you could pick it up as a fix
> for v6.9.
> 

Of course! :-)

Cheers,
Angelo

> ChenYu
> 
>>> Also, mediatek/v6.8-next/soc is missing from mediatek/for-next in today's
>>> linux-next.
>>>
>>
>> Fixing immediately.
>>
>>>> ---
>>>>    drivers/soc/mediatek/Kconfig | 1 +
>>>>    1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
>>>> index 50c664b65f4d4..1b7afb19ccd63 100644
>>>> --- a/drivers/soc/mediatek/Kconfig
>>>> +++ b/drivers/soc/mediatek/Kconfig
>>>> @@ -72,6 +72,7 @@ config MTK_SOCINFO
>>>>           tristate "MediaTek SoC Information"
>>>>           default y
>>>>           depends on NVMEM_MTK_EFUSE
>>>> +       select SOC_BUS
>>>>           help
>>>>             The MediaTek SoC Information (mtk-socinfo) driver provides
>>>>             information about the SoC to the userspace including the
>>>> --
>>>> 2.43.0
>>>>
>>>>
>>
>>




From Shawn.Sung at mediatek.com  Tue Feb 20 01:06:08 2024
From: Shawn.Sung at mediatek.com (=?utf-8?B?U2hhd24gU3VuZyAo5a6L5a2d6KyZKQ==?=)
Date: Tue, 20 Feb 2024 09:06:08 +0000
Subject: [PATCH v2 1/1] drm/mediatek: Filter modes according to hardware
 capability
In-Reply-To: <d8bb9f158e03c41d2278545e1a5ef657943f7be4.camel@mediatek.com>
References: <20240207021510.24035-1-shawn.sung@mediatek.com>
	 <20240207021510.24035-2-shawn.sung@mediatek.com>
	 <d8bb9f158e03c41d2278545e1a5ef657943f7be4.camel@mediatek.com>
Message-ID: <2025e0ddff85a3bfa1f8894587b5e26ba3cfd65b.camel@mediatek.com>

Hi CK,

On Fri, 2024-02-16 at 09:38 +0000, CK Hu (???) wrote:
> Hi, Hsiao-chien:
> 
> On Wed, 2024-02-07 at 10:15 +0800, Hsiao Chien Sung wrote:
> > From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com
> > >
> > 
> > We found a stability issue on MT8188 when connecting an external
> > monitor
> > in 2560x1440 at 144Hz mode. Checked with the designer, there is a
> > function
> > called "prefetch" which is working during VBP (triggered by VSYNC).
> > If the duration of VBP is too short, the throughput requirement
> > could
> > increase more than 3 times and lead to stability issues.
> > 
> > The mode settings that VDOSYS supports are mainly affected by clock
> > rate and throughput, display driver should filter these settings
> > according to the SoC's limitation to avoid unstable conditions.
> > 
> > Since currently the mode filter is only available on MT8195 and
> > MT8188
> > and they share the same compatible name, the reference number
> > (8250)
> > is hard coded instead of in the driver data.
> > 
> > Signed-off-by: Hsiao Chien Sung <
> > shawn.sung at mediatek.corp-partner.google.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  4 ++
> >  drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 56
> > +++++++++++++++++++
> >  .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 17 ++++++
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 17 ++++++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   | 12 ++++
> >  6 files changed, 107 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > index eb738f14f09e3..4a5661334fb1a 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > @@ -72,6 +72,8 @@ void mtk_merge_advance_config(struct device *dev,
> > unsigned int l_w, unsigned int
> >  			      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);
> > +enum drm_mode_status mtk_merge_mode_valid(struct device *dev,
> > +					  const struct drm_display_mode
> > *mode);
> >  
> >  void mtk_ovl_bgclr_in_on(struct device *dev);
> >  void mtk_ovl_bgclr_in_off(struct device *dev);
> > @@ -130,6 +132,8 @@ unsigned int mtk_ovl_adaptor_layer_nr(struct
> > device *dev);
> >  struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev);
> >  const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
> >  size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
> > +enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device
> > *dev,
> > +						const struct
> > drm_display_mode *mode);
> >  
> >  void mtk_rdma_bypass_shadow(struct device *dev);
> >  int mtk_rdma_clk_enable(struct device *dev);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > index c19fb1836034d..6b065ee254455 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > @@ -223,6 +223,62 @@ void mtk_merge_clk_disable(struct device *dev)
> >  	clk_disable_unprepare(priv->clk);
> >  }
> >  
> > +enum drm_mode_status mtk_merge_mode_valid(struct device *dev,
> > +					  const struct drm_display_mode
> > *mode)
> > +{
> > +	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +	unsigned long rate = 0;
> > +
> > +	rate = clk_get_rate(priv->clk);
> > +
> > +	/* Convert to KHz and round the number */
> > +	rate = (rate + 500) / 1000;
> > +
> > +	if (rate && mode->clock > rate) {
> > +		dev_dbg(dev, "invalid clock: %d (>%lu)\n", mode-
> > >clock, 
> > rate);
> > +		return MODE_CLOCK_HIGH;
> > +	}
> > +
> > +	/*
> > +	 * Measure the bandwidth requirement of hardware prefetch (per
> > frame)
> > +	 *
> > +	 * let N = prefetch buffer size in lines
> > +	 *         (ex. N=3, then prefetch buffer size = 3 lines)
> > +	 *
> > +	 * prefetch size = htotal * N (pixels)
> > +	 * time per line = 1 / fps / vtotal (seconds)
> > +	 * duration      = vbp * time per line
> > +	 *               = vbp / fps / vtotal
> > +	 *
> > +	 * data rate = prefetch size / duration
> > +	 *           = htotal * N / (vbp / fps / vtotal)
> > +	 *           = htotal * vtotal * fps * N / vbp
> > +	 *           = clk * N / vbp (pixels per second)
> > +	 *
> > +	 * Say 4K60 (CAE-861) is the maximum mode supported by the SoC
> > +	 * data rate = 594000K * N / 72 = 8250 (standard)
> > +	 * (remove K*N because of the same unit)
> 
> Is N constant? For example, when 4K, N=3. When 2560x1440, N is still
> 3?
> I think the buffer size is constant, if N is still 3 when 2560x1440,
> the buffer is not full and some space is wasted.
> 

Yes, 'N' is a constant in the proposed formula, and indeed, in this
case, it seems there is some space wasted in the prefetch buffer.
However, if the throughput exceeds the expectation when only 3 lines of
the data is considered, then it must be insufficient for the whole
prefetch buffer.

In order to have as many common factors in different modes so they can
be eliminated when comparing with each other, here we just use the same
'N' for all kinds of resolutions.

Regards,
Shawn

From zhiw at nvidia.com  Tue Feb 20 01:07:36 2024
From: zhiw at nvidia.com (Zhi Wang)
Date: Tue, 20 Feb 2024 09:07:36 +0000
Subject: [PATCH v8 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <SA1PR12MB71992963218C5753F346B3D7B0502@SA1PR12MB7199.namprd12.prod.outlook.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-3-ankita@nvidia.com>
 <bc5cdc2e-50d8-435a-8f9d-a0053a99598d@nvidia.com>
 <SA1PR12MB71992963218C5753F346B3D7B0502@SA1PR12MB7199.namprd12.prod.outlook.com>
Message-ID: <b8630236-a081-489e-86aa-efbb39d3d9fa@nvidia.com>

On 2/20/24 08:51, Ankit Agrawal wrote:
>>> To safely use VFIO in KVM the platform must guarantee full safety in the
>>> guest where no action taken against a MMIO mapping can trigger an
>>> uncontained failure. We belive that most VFIO PCI platforms support this
>>
>> A nit, let's use passive voice in the patch comment. Also belive is mostly
>> a typo.
> 
> Sure, will do.
Also patch 4 has the same nit. It should be fixed as well.

From ankita at nvidia.com  Tue Feb 20 01:08:58 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Tue, 20 Feb 2024 09:08:58 +0000
Subject: [PATCH v8 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <b8630236-a081-489e-86aa-efbb39d3d9fa@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-3-ankita@nvidia.com>
 <bc5cdc2e-50d8-435a-8f9d-a0053a99598d@nvidia.com>
 <SA1PR12MB71992963218C5753F346B3D7B0502@SA1PR12MB7199.namprd12.prod.outlook.com>
 <b8630236-a081-489e-86aa-efbb39d3d9fa@nvidia.com>
Message-ID: <SA1PR12MB7199E64F383B1C3FFAAFA224B0502@SA1PR12MB7199.namprd12.prod.outlook.com>

>>>> To safely use VFIO in KVM the platform must guarantee full safety in the
>>>> guest where no action taken against a MMIO mapping can trigger an
>>>> uncontained failure. We belive that most VFIO PCI platforms support this
>>>
>>> A nit, let's use passive voice in the patch comment. Also belive is mostly
>>> a typo.
>>
>> Sure, will do.
>Also patch 4 has the same nit. It should be fixed as well.

Yes.

From david at redhat.com  Tue Feb 20 01:09:37 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 20 Feb 2024 10:09:37 +0100
Subject: [PATCH v8 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <SA1PR12MB71992963218C5753F346B3D7B0502@SA1PR12MB7199.namprd12.prod.outlook.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-3-ankita@nvidia.com>
 <bc5cdc2e-50d8-435a-8f9d-a0053a99598d@nvidia.com>
 <SA1PR12MB71992963218C5753F346B3D7B0502@SA1PR12MB7199.namprd12.prod.outlook.com>
Message-ID: <6ca94bf1-68b4-4a81-8cd0-d86683e0b12c@redhat.com>

On 20.02.24 09:51, Ankit Agrawal wrote:
>>> To safely use VFIO in KVM the platform must guarantee full safety in the
>>> guest where no action taken against a MMIO mapping can trigger an
>>> uncontained failure. We belive that most VFIO PCI platforms support this
>>
>> A nit, let's use passive voice in the patch comment. Also belive is mostly
>> a typo.
> 
> Sure, will do.
> 

s/we expect/the expectation is that/
s/We belive/The assumption is/

If it's just that, likely no need to resend. Maintainers usually can fix 
that up when applying (otherwise, they'll let you know :) ).

-- 
Cheers,

David / dhildenb



From fancer.lancer at gmail.com  Tue Feb 20 01:20:56 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Tue, 20 Feb 2024 12:20:56 +0300
Subject: [PATCH net] net: stmmac: Fix EST offset for dwmac 5.10
In-Reply-To: <20240220-stmmac_est-v1-1-c41f9ae2e7b7@linutronix.de>
References: <20240220-stmmac_est-v1-1-c41f9ae2e7b7@linutronix.de>
Message-ID: <mmjrlyzhegve5u3s3lhw4hmhooxixn3pwxkkdikxgxno4teqyz@rtetljwg6ffg>

Hi Kurt

On Tue, Feb 20, 2024 at 09:22:46AM +0100, Kurt Kanzenbach wrote:
> Fix EST offset for dwmac 5.10.
> 
> Currently configuring Qbv doesn't work as expected. The schedule is
> configured, but never confirmed:
> 
> |[  128.250219] imx-dwmac 428a0000.ethernet eth1: configured EST
> 
> The reason seems to be the refactoring of the EST code which set the wrong
> EST offset for the dwmac 5.10. After fixing this it works as before:
> 
> |[  106.359577] imx-dwmac 428a0000.ethernet eth1: configured EST
> |[  128.430715] imx-dwmac 428a0000.ethernet eth1: EST: SWOL has been switched
> 
> Tested on imx93.
> 
> Fixes: c3f3b97238f6 ("net: stmmac: Refactor EST implementation")
> Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
> ---
>  drivers/net/ethernet/stmicro/stmmac/hwif.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
> index 1bd34b2a47e8..29367105df54 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
> @@ -224,7 +224,7 @@ static const struct stmmac_hwif_entry {
>  		.regs = {
>  			.ptp_off = PTP_GMAC4_OFFSET,
>  			.mmc_off = MMC_GMAC4_OFFSET,
> -			.est_off = EST_XGMAC_OFFSET,
> +			.est_off = EST_GMAC4_OFFSET,

Unfortunate c&p typo indeed. Thanks for fixing it!
Reviewed-by: Serge Semin <fancer.lancer at gmail.com>

-Serge(y)

>  		},
>  		.desc = &dwmac4_desc_ops,
>  		.dma = &dwmac410_dma_ops,
> 
> ---
> base-commit: 40b9385dd8e6a0515e1c9cd06a277483556b7286
> change-id: 20240220-stmmac_est-ea6884f9ba3c
> 
> Best regards,
> -- 
> Kurt Kanzenbach <kurt at linutronix.de>
> 
> 


From ck.hu at mediatek.com  Tue Feb 20 01:30:27 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Tue, 20 Feb 2024 09:30:27 +0000
Subject: [PATCH v2 2/3] Subject: [PATCH] drm/mediatek/dp: Add HDCP2.x
 feature for DisplayPort
In-Reply-To: <20240205055055.25340-3-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
	 <20240205055055.25340-3-mac.shen@mediatek.com>
Message-ID: <40e68d74c0bb0df15f610fde017116357b40560d.camel@mediatek.com>

Hi, Mac:

On Mon, 2024-02-05 at 13:50 +0800, mac.shen wrote:
> Add HDCP2.x feature for DisplayPort.
> When userspace request the kernel protect future content communicated
> over the link with Content_Protection property, the feature will do
> HDCP2.x authentication if the sink support HDCP2.X.
> 
> Changes in v2:
> - remove switch case, and refine code to make more clear
> - remove some definitions, and use the definitions in
>   include/drm/drm_hdcp.h
> - use the struct which defined in include/drm/drm_hdcp.h
> - do HDCP2.x authentication when userspace request the
>   kernel protect future content communicated
> per suggestion from the previous thread:
> https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
> 9218a545c46.camel at mediatek.com/
> 
> Signed-off-by: mac.shen <mac.shen at mediatek.com>
> ---

[snip]

>  
> +void mtk_dp_check_hdcp_version(struct mtk_dp *mtk_dp, bool
> only_hdcp1x)
> +{
> +	if (!only_hdcp1x && dp_tx_hdcp2_support(&mtk_dp->hdcp_info))
> +		return;
> +
> +	if (tee_add_device(&mtk_dp->hdcp_info, HDCP_NONE) !=
> RET_SUCCESS)

Does this mean that if rx does not support hdcp, dp tx driver still
need to create tee device to work for no hdcp? If so, I think this
should be separated to an independent patch. I like the patch sequence
to be:

1. Support NO HDCP
2. Support HDCP 1x
3. Support HDCP 2x

Regards,
CK

> +		mtk_dp->hdcp_info.auth_status = AUTH_FAIL;
> +}
> +

From zhiw at nvidia.com  Tue Feb 20 01:33:45 2024
From: zhiw at nvidia.com (Zhi Wang)
Date: Tue, 20 Feb 2024 09:33:45 +0000
Subject: [PATCH v8 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <6ca94bf1-68b4-4a81-8cd0-d86683e0b12c@redhat.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-3-ankita@nvidia.com>
 <bc5cdc2e-50d8-435a-8f9d-a0053a99598d@nvidia.com>
 <SA1PR12MB71992963218C5753F346B3D7B0502@SA1PR12MB7199.namprd12.prod.outlook.com>
 <6ca94bf1-68b4-4a81-8cd0-d86683e0b12c@redhat.com>
Message-ID: <709fe097-9cc0-4d61-89e5-65147f541e95@nvidia.com>

On 2/20/24 09:09, David Hildenbrand wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 20.02.24 09:51, Ankit Agrawal wrote:
>>>> To safely use VFIO in KVM the platform must guarantee full safety in 
>>>> the
>>>> guest where no action taken against a MMIO mapping can trigger an
>>>> uncontained failure. We belive that most VFIO PCI platforms support 
>>>> this
>>>
>>> A nit, let's use passive voice in the patch comment. Also belive is 
>>> mostly
>>> a typo.
>>
>> Sure, will do.
>>
> 
> s/we expect/the expectation is that/
> s/We belive/The assumption is/
> 
> If it's just that, likely no need to resend. Maintainers usually can fix
> that up when applying (otherwise, they'll let you know :) ).
> 
Many thanks! :)
> -- 
> Cheers,
> 
> David / dhildenb
> 


From shawn.sung at mediatek.com  Tue Feb 20 01:37:11 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Tue, 20 Feb 2024 17:37:11 +0800
Subject: [PATCH v3 1/1] drm/mediatek: Filter modes according to hardware capability
In-Reply-To: <20240220093711.20546-1-shawn.sung@mediatek.com>
References: <20240220093711.20546-1-shawn.sung@mediatek.com>
Message-ID: <20240220093711.20546-2-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

We found a stability issue on MT8188 when connecting an external monitor
in 2560x1440 at 144Hz mode. Checked with the designer, there is a function
called "prefetch" which is working during VBP (triggered by VSYNC).
If the duration of VBP is too short, the throughput requirement could
increase more than 3 times and lead to stability issues.

The mode settings that VDOSYS supports are mainly affected by clock
rate and throughput, display driver should filter these settings
according to the SoC's limitation to avoid unstable conditions.

Since currently the mode filter is only available on MT8195 and MT8188
and they share the same compatible name, the reference number (8250)
is hard coded instead of in the driver data.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 65 +++++++++++++++++++
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 17 +++++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 17 +++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   | 12 ++++
 6 files changed, 116 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index eb738f14f09e3..4a5661334fb1a 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -72,6 +72,8 @@ void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned int
 			      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);
+enum drm_mode_status mtk_merge_mode_valid(struct device *dev,
+					  const struct drm_display_mode *mode);
 
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
@@ -130,6 +132,8 @@ unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
 struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev);
 const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
 size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
+enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
+						const struct drm_display_mode *mode);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index c19fb1836034d..80953b3e8ace6 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -223,6 +223,71 @@ void mtk_merge_clk_disable(struct device *dev)
 	clk_disable_unprepare(priv->clk);
 }
 
+enum drm_mode_status mtk_merge_mode_valid(struct device *dev,
+					  const struct drm_display_mode *mode)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+	unsigned long rate = 0;
+
+	rate = clk_get_rate(priv->clk);
+
+	/* Convert to KHz and round the number */
+	rate = (rate + 500) / 1000;
+
+	if (rate && mode->clock > rate) {
+		dev_dbg(dev, "invalid clock: %d (>%lu)\n", mode->clock, rate);
+		return MODE_CLOCK_HIGH;
+	}
+
+	/*
+	 * Measure the bandwidth requirement of hardware prefetch (per frame)
+	 *
+	 * let N = prefetch buffer size in lines
+	 *         (ex. N=3, then prefetch buffer size = 3 lines)
+	 *
+	 * prefetch size = htotal * N (pixels)
+	 * time per line = 1 / fps / vtotal (seconds)
+	 * duration      = vbp * time per line
+	 *               = vbp / fps / vtotal
+	 *
+	 * data rate = prefetch size / duration
+	 *           = htotal * N / (vbp / fps / vtotal)
+	 *           = htotal * vtotal * fps * N / vbp
+	 *           = clk * N / vbp (pixels per second)
+	 *
+	 * Say 4K60 (CEA-861) is the maximum mode supported by the SoC
+	 * data rate = 594000K * N / 72 = 8250 (standard)
+	 * (remove K * N due to the same unit)
+	 *
+	 * For 2560x1440 at 144 (clk=583600K, vbp=17):
+	 * data rate = 583600 / 17 ~= 34329 > 8250 (NG)
+	 *
+	 * For 2560x1440 at 120 (clk=497760K, vbp=77):
+	 * data rate = 497760 / 77 ~= 6464 < 8250 (OK)
+	 *
+	 * A non-standard 4K60 timing (clk=521280K, vbp=54)
+	 * data rate = 521280 / 54 ~= 9653 > 8250 (NG)
+	 *
+	 * Bandwidth requirement of hardware prefetch increases significantly
+	 * when the VBP decreases (more than 4x in this example).
+	 *
+	 * The proposed formula is only one way to estimate whether our SoC
+	 * supports the mode setting. The basic idea behind it is just to check
+	 * if the data rate requirement is too high (directly proportional to
+	 * pixel clock, inversely proportional to vbp). Please adjust the
+	 * function if it doesn't fit your situation in the future.
+	 */
+	rate = mode->clock / (mode->vtotal - mode->vsync_end);
+
+	if (rate > 8250) {
+		dev_dbg(dev, "invalid rate: %lu (>8250): " DRM_MODE_FMT "\n",
+			rate, DRM_MODE_ARG(mode));
+		return MODE_BAD;
+	}
+
+	return MODE_OK;
+}
+
 static int mtk_disp_merge_bind(struct device *dev, struct device *master,
 			       void *data)
 {
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index 10d23e76acaa9..6d4334955e3d3 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -88,6 +88,7 @@ static const struct mtk_ddp_comp_funcs ethdr = {
 static const struct mtk_ddp_comp_funcs merge = {
 	.clk_enable = mtk_merge_clk_enable,
 	.clk_disable = mtk_merge_clk_disable,
+	.mode_valid = mtk_merge_mode_valid,
 };
 
 static const struct mtk_ddp_comp_funcs padding = {
@@ -341,6 +342,22 @@ void mtk_ovl_adaptor_clk_disable(struct device *dev)
 	}
 }
 
+enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
+						const struct drm_display_mode *mode)
+
+{
+	int i;
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
+		dev = ovl_adaptor->ovl_adaptor_comp[i];
+		if (!dev || !comp_matches[i].funcs->mode_valid)
+			continue;
+		return comp_matches[i].funcs->mode_valid(dev, mode);
+	}
+	return MODE_OK;
+}
+
 unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev)
 {
 	return MTK_OVL_ADAPTOR_LAYER_NUM;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 1dac8d0fbc669..14cf75fa217f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -212,6 +212,22 @@ static void mtk_drm_crtc_destroy_state(struct drm_crtc *crtc,
 	kfree(to_mtk_crtc_state(state));
 }
 
+static enum drm_mode_status
+mtk_drm_crtc_mode_valid(struct drm_crtc *crtc,
+			const struct drm_display_mode *mode)
+{
+	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	enum drm_mode_status status = MODE_OK;
+	int i;
+
+	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
+		status = mtk_ddp_comp_mode_valid(mtk_crtc->ddp_comp[i], mode);
+		if (status != MODE_OK)
+			break;
+	}
+	return status;
+}
+
 static bool mtk_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 				    const struct drm_display_mode *mode,
 				    struct drm_display_mode *adjusted_mode)
@@ -830,6 +846,7 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
 static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
 	.mode_fixup	= mtk_drm_crtc_mode_fixup,
 	.mode_set_nofb	= mtk_drm_crtc_mode_set_nofb,
+	.mode_valid	= mtk_drm_crtc_mode_valid,
 	.atomic_begin	= mtk_drm_crtc_atomic_begin,
 	.atomic_flush	= mtk_drm_crtc_atomic_flush,
 	.atomic_enable	= mtk_drm_crtc_atomic_enable,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 9633e860cc3ce..94590227c56a9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -416,6 +416,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
 	.remove = mtk_ovl_adaptor_remove_comp,
 	.get_formats = mtk_ovl_adaptor_get_formats,
 	.get_num_formats = mtk_ovl_adaptor_get_num_formats,
+	.mode_valid = mtk_ovl_adaptor_mode_valid,
 };
 
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index f8c7e8d8ddc12..215b7234ff13c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -12,6 +12,8 @@
 #include <linux/soc/mediatek/mtk-mmsys.h>
 #include <linux/soc/mediatek/mtk-mutex.h>
 
+#include <drm/drm_modes.h>
+
 struct device;
 struct device_node;
 struct drm_crtc;
@@ -84,6 +86,7 @@ struct mtk_ddp_comp_funcs {
 	void (*add)(struct device *dev, struct mtk_mutex *mutex);
 	void (*remove)(struct device *dev, struct mtk_mutex *mutex);
 	unsigned int (*encoder_index)(struct device *dev);
+	enum drm_mode_status (*mode_valid)(struct device *dev, const struct drm_display_mode *mode);
 };
 
 struct mtk_ddp_comp {
@@ -125,6 +128,15 @@ static inline void mtk_ddp_comp_clk_disable(struct mtk_ddp_comp *comp)
 		comp->funcs->clk_disable(comp->dev);
 }
 
+static inline
+enum drm_mode_status mtk_ddp_comp_mode_valid(struct mtk_ddp_comp *comp,
+					     const struct drm_display_mode *mode)
+{
+	if (comp && comp->funcs && comp->funcs->mode_valid)
+		return comp->funcs->mode_valid(comp->dev, mode);
+	return MODE_OK;
+}
+
 static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
 				       unsigned int w, unsigned int h,
 				       unsigned int vrefresh, unsigned int bpc,
-- 
2.18.0



From shawn.sung at mediatek.com  Tue Feb 20 01:37:10 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Tue, 20 Feb 2024 17:37:10 +0800
Subject: [PATCH v3 0/1] Filter modes according to hardware capability
Message-ID: <20240220093711.20546-1-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

This series is based on mediatek-drm-next branch of
kernel/git/chunkuang.hu/linux.git.

Changes in v3:
- Add more information to the comment

Changes in v2:
- Refined the filtering formula
- Add the .mode_valid hook to the hardware that causes the limitation

Hsiao Chien Sung (1):
  drm/mediatek: Filter modes according to hardware capability

 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 65 +++++++++++++++++++
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 17 +++++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 17 +++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   | 12 ++++
 6 files changed, 116 insertions(+)

--
2.18.0



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:10 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:10 +0100
Subject: [PATCH 00/14] media: rockchip: cif: add support for rk3568 vicap
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>

Habidere,

This series introduces support for the Rockchip RK3568 Video Capture
(VICAP) block. It bases on the work of several Bootlin developers who
have been tirelessly submitting support for the PX30 Video Input
Processor (VIP) block for inclusion in mainline. The most recent
iteration is Mehdi Djait's v13 [0], which is a prerequisite for the
patches of this series.

The PX30 VIP and the RK3568 VICAP are similar enough to share a common
driver, but there are some subtle differences that require some tweaks
in the submitted code.

Although the v13 patches are still WIP and need some revision, I have
decided to push the current state of the art in order to gather a
first round of reviews and comments.

The patches are functional and have been tested successfully on a
custom RK3568 board including the ITE Tech. IT6801 HDMI receiver as
attached subdevice. The IT6801 driver still needs some loving care but
shall be submitted as well at some point.

Looking forward to your comments!

[0] https://lore.kernel.org/linux-media/cover.1707677804.git.mehdi.djait.k at gmail.com/

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
Michael Riesch (14):
      media: dt-bindings: media: video-interfaces: add defines for sampling modes
      media: dt-bindings: media: rockchip-cif: add port definitions
      media: dt-bindings: media: rockchip,px30-vip: add optional property iommus
      media: dt-bindings: media: rockchip,px30-vip: allow for different variants
      media: dt-bindings: media: rockchip,px30-vip: add rk3568-vicap compatible
      media: rockchip: cif: store endpoint information in private data
      media: rockchip: cif: fix formatting of find_output_fmt
      media: rockchip: cif: use port definitions from new header file
      media: rockchip: cif: add support for grf
      media: rockchip: cif: add variant specific input format list
      media: rockchip: cif: make scaler support variant specific
      media: rockchip: cif: make register access variant specific
      media: rockchip: cif: add support for rk3568 vicap
      arm64: dts: rockchip: add vicap node to rk356x

 .../bindings/media/rockchip,px30-vip.yaml          | 110 ++++--
 arch/arm64/boot/dts/rockchip/rk356x.dtsi           |  45 +++
 drivers/media/platform/rockchip/cif/cif-capture.c  | 172 +-------
 drivers/media/platform/rockchip/cif/cif-common.h   |  33 +-
 drivers/media/platform/rockchip/cif/cif-dev.c      | 434 ++++++++++++++++++++-
 drivers/media/platform/rockchip/cif/cif-regs.h     |  56 +--
 include/dt-bindings/media/rockchip-cif.h           |  12 +
 include/dt-bindings/media/video-interfaces.h       |   4 +
 8 files changed, 652 insertions(+), 214 deletions(-)
---
base-commit: b465b3c117718e5b8f4f3100d6ee780f7dc7b59d
change-id: 20240220-v6-8-topic-rk3568-vicap-b9b3f9925f44

Best regards,
-- 
Michael Riesch <michael.riesch at wolfvision.net>



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:11 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:11 +0100
Subject: [PATCH 01/14] media: dt-bindings: media: video-interfaces: add
 defines for sampling modes
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-1-2680a1fa640b@wolfvision.net>

Add defines for the pixel clock sampling modes (rising edge, falling edge,
dual edge) for parallel video interfaces.
This avoids hardcoded constants in device tree sources.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 include/dt-bindings/media/video-interfaces.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/dt-bindings/media/video-interfaces.h b/include/dt-bindings/media/video-interfaces.h
index 68ac4e05e37f..02d8239c2038 100644
--- a/include/dt-bindings/media/video-interfaces.h
+++ b/include/dt-bindings/media/video-interfaces.h
@@ -13,4 +13,8 @@
 #define MEDIA_BUS_TYPE_PARALLEL			5
 #define MEDIA_BUS_TYPE_BT656			6
 
+#define MEDIA_PCLK_SAMPLE_FALLING_EDGE		0
+#define MEDIA_PCLK_SAMPLE_RISING_EDGE		1
+#define MEDIA_PCLK_SAMPLE_DUAL_EDGE		2
+
 #endif /* __DT_BINDINGS_MEDIA_VIDEO_INTERFACES_H__ */

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:12 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:12 +0100
Subject: [PATCH 02/14] media: dt-bindings: media: rockchip-cif: add port
 definitions
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-2-2680a1fa640b@wolfvision.net>

The different variants of the Rockchip Camera Interface may feature
various ports. Add a new header file with port definitions to avoid
hardcoded constants in device tree sources.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 include/dt-bindings/media/rockchip-cif.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/dt-bindings/media/rockchip-cif.h b/include/dt-bindings/media/rockchip-cif.h
new file mode 100644
index 000000000000..37364ee1f7bc
--- /dev/null
+++ b/include/dt-bindings/media/rockchip-cif.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (C) 2023 Michael Riesch <michael.riesch at wolfvision.net>
+ */
+
+#ifndef __DT_BINDINGS_MEDIA_ROCKCHIP_CIF_H__
+#define __DT_BINDINGS_MEDIA_ROCKCHIP_CIF_H__
+
+#define MEDIA_ROCKCHIP_CIF_DVP		0
+#define MEDIA_ROCKCHIP_CIF_MIPI		1
+
+#endif /* __DT_BINDINGS_MEDIA_ROCKCHIP_CIF_H__ */

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:13 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:13 +0100
Subject: [PATCH 03/14] media: dt-bindings: media: rockchip,px30-vip: add
 optional property iommus
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-3-2680a1fa640b@wolfvision.net>

The PX30 VIP features an IOMMU and can be operated with or without using
it. Document the property iommus in order to support the former case.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
index 6af4a9b6774a..675a1ea47210 100644
--- a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
@@ -36,6 +36,9 @@ properties:
       - const: hclk
       - const: pclk
 
+  iommus:
+    maxItems: 1
+
   resets:
     items:
       - description: AXI

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:14 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:14 +0100
Subject: [PATCH 04/14] media: dt-bindings: media: rockchip,px30-vip: allow
 for different variants
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-4-2680a1fa640b@wolfvision.net>

Move the documentation of clocks and resets to a allOf: structure in order
to allow for different variants of the IP block.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../bindings/media/rockchip,px30-vip.yaml          | 58 ++++++++++++++--------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
index 675a1ea47210..7168f166798c 100644
--- a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
@@ -24,32 +24,16 @@ properties:
   interrupts:
     maxItems: 1
 
-  clocks:
-    items:
-      - description: ACLK
-      - description: HCLK
-      - description: PCLK
-
-  clock-names:
-    items:
-      - const: aclk
-      - const: hclk
-      - const: pclk
+  clocks: true
+
+  clock-names: true
 
   iommus:
     maxItems: 1
 
-  resets:
-    items:
-      - description: AXI
-      - description: AHB
-      - description: PCLK IN
+  resets: true
 
-  reset-names:
-    items:
-      - const: axi
-      - const: ahb
-      - const: pclkin
+  reset-names: true
 
   power-domains:
     maxItems: 1
@@ -85,6 +69,38 @@ required:
   - clocks
   - ports
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: rockchip,px30-vip
+    then:
+      properties:
+        clocks:
+          items:
+            - description: ACLK
+            - description: HCLK
+            - description: PCLK
+
+        clock-names:
+          items:
+            - const: aclk
+            - const: hclk
+            - const: pclk
+
+        resets:
+          items:
+            - description: AXI
+            - description: AHB
+            - description: PCLK IN
+
+        reset-names:
+          items:
+            - const: axi
+            - const: ahb
+            - const: pclkin
+
 additionalProperties: false
 
 examples:

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:15 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:15 +0100
Subject: [PATCH 05/14] media: dt-bindings: media: rockchip,px30-vip: add
 rk3568-vicap compatible
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-5-2680a1fa640b@wolfvision.net>

Add compatible for the variant found in the Rockchip RK3568 SoC.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../bindings/media/rockchip,px30-vip.yaml          | 45 +++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
index 7168f166798c..06d49f591efd 100644
--- a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
@@ -16,7 +16,9 @@ description:
 
 properties:
   compatible:
-    const: rockchip,px30-vip
+    enum:
+      - rockchip,px30-vip
+      - rockchip,rk3568-vicap
 
   reg:
     maxItems: 1
@@ -35,6 +37,11 @@ properties:
 
   reset-names: true
 
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to general register file used for video input block control.
+
   power-domains:
     maxItems: 1
 
@@ -100,6 +107,42 @@ allOf:
             - const: axi
             - const: ahb
             - const: pclkin
+ - if:
+      properties:
+        compatible:
+          contains:
+            const: rockchip,rk3568-vicap
+    then:
+      properties:
+        clocks:
+          items:
+            - description: ACLK
+            - description: HCLK
+            - description: DCLK
+            - description: ICLK
+
+        clock-names:
+          items:
+            - const: aclk
+            - const: hclk
+            - const: dclk
+            - const: iclk
+
+        resets:
+          items:
+            - description: ARST
+            - description: HRST
+            - description: DRST
+            - description: PRST
+            - description: IRST
+
+        reset-names:
+          items:
+            - const: arst
+            - const: hrst
+            - const: drst
+            - const: prst
+            - const: irst
 
 additionalProperties: false
 

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:17 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:17 +0100
Subject: [PATCH 07/14] media: rockchip: cif: fix formatting of
 find_output_fmt
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-7-2680a1fa640b@wolfvision.net>

Fix formatting according to coding conventions. No functional change.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 drivers/media/platform/rockchip/cif/cif-capture.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rockchip/cif/cif-capture.c b/drivers/media/platform/rockchip/cif/cif-capture.c
index 2c7716684de0..c80a52028a21 100644
--- a/drivers/media/platform/rockchip/cif/cif-capture.c
+++ b/drivers/media/platform/rockchip/cif/cif-capture.c
@@ -273,8 +273,8 @@ cif_input_fmt *get_input_fmt(struct v4l2_subdev *sd)
 	return NULL;
 }
 
-static struct
-cif_output_fmt *find_output_fmt(struct cif_stream *stream, u32 pixelfmt)
+static struct cif_output_fmt *find_output_fmt(struct cif_stream *stream,
+					      u32 pixelfmt)
 {
 	struct cif_output_fmt *fmt;
 	u32 i;

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:18 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:18 +0100
Subject: [PATCH 08/14] media: rockchip: cif: use port definitions from new
 header file
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-8-2680a1fa640b@wolfvision.net>

Use the recently introduced port definitions instead of hardcoded
constants.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 drivers/media/platform/rockchip/cif/cif-dev.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/rockchip/cif/cif-dev.c b/drivers/media/platform/rockchip/cif/cif-dev.c
index 923831827be4..c4282449a93d 100644
--- a/drivers/media/platform/rockchip/cif/cif-dev.c
+++ b/drivers/media/platform/rockchip/cif/cif-dev.c
@@ -7,6 +7,7 @@
  * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
  */
 
+#include <dt-bindings/media/rockchip-cif.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -85,7 +86,8 @@ static int cif_subdev_notifier(struct cif_device *cif_dev)
 
 	v4l2_async_nf_init(ntf, &cif_dev->v4l2_dev);
 
-	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0,
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
+					     MEDIA_ROCKCHIP_CIF_DVP, 0,
 					     FWNODE_GRAPH_ENDPOINT_NEXT);
 	if (!ep)
 		return -ENODEV;

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:19 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:19 +0100
Subject: [PATCH 09/14] media: rockchip: cif: add support for grf
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-9-2680a1fa640b@wolfvision.net>

Some variants of the Rockchip CIF require the General Register File
for video input block control.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 drivers/media/platform/rockchip/cif/cif-common.h | 3 +++
 drivers/media/platform/rockchip/cif/cif-dev.c    | 7 +++++++
 2 files changed, 10 insertions(+)

diff --git a/drivers/media/platform/rockchip/cif/cif-common.h b/drivers/media/platform/rockchip/cif/cif-common.h
index 34da800a0504..ae8fedeadd1c 100644
--- a/drivers/media/platform/rockchip/cif/cif-common.h
+++ b/drivers/media/platform/rockchip/cif/cif-common.h
@@ -11,6 +11,7 @@
 
 #include <linux/clk.h>
 #include <linux/mutex.h>
+#include <linux/regmap.h>
 
 #include <media/media-device.h>
 #include <media/media-entity.h>
@@ -96,6 +97,7 @@ static inline struct cif_stream *to_cif_stream(struct video_device *vdev)
 struct cif_match_data {
 	struct clk_bulk_data *clks;
 	int clks_num;
+	void (*grf_dvp_setup)(struct cif_device *cif_dev);
 };
 
 struct cif_device {
@@ -103,6 +105,7 @@ struct cif_device {
 	int				irq;
 	void __iomem			*base_addr;
 	struct reset_control		*cif_rst;
+	struct regmap			*grf;
 
 	struct v4l2_device		v4l2_dev;
 	struct media_device		media_dev;
diff --git a/drivers/media/platform/rockchip/cif/cif-dev.c b/drivers/media/platform/rockchip/cif/cif-dev.c
index c4282449a93d..b75b76508793 100644
--- a/drivers/media/platform/rockchip/cif/cif-dev.c
+++ b/drivers/media/platform/rockchip/cif/cif-dev.c
@@ -11,6 +11,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_graph.h>
@@ -103,6 +104,9 @@ static int cif_subdev_notifier(struct cif_device *cif_dev)
 		goto complete;
 	}
 
+	if (cif_dev->match_data->grf_dvp_setup)
+		cif_dev->match_data->grf_dvp_setup(cif_dev);
+
 	asd = v4l2_async_nf_add_fwnode_remote(ntf, ep,
 					      struct v4l2_async_connection);
 	if (IS_ERR(asd)) {
@@ -191,6 +195,9 @@ static int cif_plat_probe(struct platform_device *pdev)
 	if (IS_ERR(cif_dev->cif_rst))
 		return PTR_ERR(cif_dev->cif_rst);
 
+	cif_dev->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+						       "rockchip,grf");
+
 	cif_stream_init(cif_dev);
 	strscpy(cif_dev->media_dev.model, "cif",
 		sizeof(cif_dev->media_dev.model));

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:22 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:22 +0100
Subject: [PATCH 12/14] media: rockchip: cif: make register access variant
 specific
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-12-2680a1fa640b@wolfvision.net>

The offsets of the Rockchip CIF registers may differ between the
different variants. Modify the cif_{read,write} methods in order
to support variant specific register offsets

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 drivers/media/platform/rockchip/cif/cif-common.h | 26 ++++++++++++-
 drivers/media/platform/rockchip/cif/cif-dev.c    | 17 +++++++++
 drivers/media/platform/rockchip/cif/cif-regs.h   | 47 ++++++++++--------------
 3 files changed, 61 insertions(+), 29 deletions(-)

diff --git a/drivers/media/platform/rockchip/cif/cif-common.h b/drivers/media/platform/rockchip/cif/cif-common.h
index e5500705eee2..7ecdc820171e 100644
--- a/drivers/media/platform/rockchip/cif/cif-common.h
+++ b/drivers/media/platform/rockchip/cif/cif-common.h
@@ -19,6 +19,8 @@
 #include <media/v4l2-device.h>
 #include <media/videobuf2-v4l2.h>
 
+#include "cif-regs.h"
+
 #define CIF_DRIVER_NAME		"rockchip-cif"
 
 #define CIF_MAX_BUS_CLK		8
@@ -101,6 +103,7 @@ struct cif_match_data {
 	int in_fmts_num;
 	void (*grf_dvp_setup)(struct cif_device *cif_dev);
 	bool has_scaler;
+	unsigned int regs[CIF_REGISTERS_MAX];
 };
 
 struct cif_device {
@@ -121,14 +124,33 @@ struct cif_device {
 	const struct cif_match_data	*match_data;
 };
 
-static inline void cif_write(struct cif_device *cif_dev, unsigned int addr,
+static inline unsigned int cif_get_addr(struct cif_device *cif_device,
+					unsigned int index)
+{
+	if (index >= CIF_REGISTERS_MAX)
+		return CIF_REGISTERS_INVALID;
+
+	return cif_device->match_data->regs[index];
+}
+
+static inline void cif_write(struct cif_device *cif_dev, unsigned int index,
 			     u32 val)
 {
+	unsigned int addr = cif_get_addr(cif_dev, index);
+
+	if (addr == CIF_REGISTERS_INVALID)
+		return;
+
 	writel(val, cif_dev->base_addr + addr);
 }
 
-static inline u32 cif_read(struct cif_device *cif_dev, unsigned int addr)
+static inline u32 cif_read(struct cif_device *cif_dev, unsigned int index)
 {
+	unsigned int addr = cif_get_addr(cif_dev, index);
+
+	if (addr == CIF_REGISTERS_INVALID)
+		return 0;
+
 	return readl(cif_dev->base_addr + addr);
 }
 
diff --git a/drivers/media/platform/rockchip/cif/cif-dev.c b/drivers/media/platform/rockchip/cif/cif-dev.c
index e7b5ae5804ca..929ea39dd832 100644
--- a/drivers/media/platform/rockchip/cif/cif-dev.c
+++ b/drivers/media/platform/rockchip/cif/cif-dev.c
@@ -283,6 +283,23 @@ static const struct cif_match_data px30_cif_match_data = {
 	.in_fmts = px30_in_fmts,
 	.in_fmts_num = ARRAY_SIZE(px30_in_fmts),
 	.has_scaler = true,
+	.regs = {
+		[CIF_CTRL] = 0x00,
+		[CIF_INTEN] = 0x04,
+		[CIF_INTSTAT] = 0x08,
+		[CIF_FOR] = 0x0c,
+		[CIF_LINE_NUM_ADDR] = 0x10,
+		[CIF_FRM0_ADDR_Y] = 0x14,
+		[CIF_FRM0_ADDR_UV] = 0x18,
+		[CIF_FRM1_ADDR_Y] = 0x1c,
+		[CIF_FRM1_ADDR_UV] = 0x20,
+		[CIF_VIR_LINE_WIDTH] = 0x24,
+		[CIF_SET_SIZE] = 0x28,
+		[CIF_SCL_CTRL] = 0x48,
+		[CIF_FRAME_STATUS] = 0x60,
+		[CIF_LAST_LINE] = 0x68,
+		[CIF_LAST_PIX] = 0x6c,
+	},
 };
 
 static const struct of_device_id cif_plat_of_match[] = {
diff --git a/drivers/media/platform/rockchip/cif/cif-regs.h b/drivers/media/platform/rockchip/cif/cif-regs.h
index b8500f0a9ac1..2ce756fde204 100644
--- a/drivers/media/platform/rockchip/cif/cif-regs.h
+++ b/drivers/media/platform/rockchip/cif/cif-regs.h
@@ -9,33 +9,26 @@
 #ifndef _CIF_REGS_H
 #define _CIF_REGS_H
 
-#define CIF_CTRL				0x00
-#define CIF_INTEN				0x04
-#define CIF_INTSTAT				0x08
-#define CIF_FOR					0x0c
-#define CIF_LINE_NUM_ADDR			0x10
-#define CIF_FRM0_ADDR_Y				0x14
-#define CIF_FRM0_ADDR_UV			0x18
-#define CIF_FRM1_ADDR_Y				0x1c
-#define CIF_FRM1_ADDR_UV			0x20
-#define CIF_VIR_LINE_WIDTH			0x24
-#define CIF_SET_SIZE				0x28
-#define CIF_SCM_ADDR_Y				0x2c
-#define CIF_SCM_ADDR_U				0x30
-#define CIF_SCM_ADDR_V				0x34
-#define CIF_WB_UP_FILTER			0x38
-#define CIF_WB_LOW_FILTER			0x3c
-#define CIF_WBC_CNT				0x40
-#define CIF_CROP				0x44
-#define CIF_SCL_CTRL				0x48
-#define CIF_SCL_DST				0x4c
-#define CIF_SCL_FCT				0x50
-#define CIF_SCL_VALID_NUM			0x54
-#define CIF_LINE_LOOP_CTR			0x58
-#define CIF_FRAME_STATUS			0x60
-#define CIF_CUR_DST				0x64
-#define CIF_LAST_LINE				0x68
-#define CIF_LAST_PIX				0x6c
+enum cif_register {
+	CIF_CTRL,
+	CIF_INTEN,
+	CIF_INTSTAT,
+	CIF_FOR,
+	CIF_LINE_NUM_ADDR,
+	CIF_FRM0_ADDR_Y,
+	CIF_FRM0_ADDR_UV,
+	CIF_FRM1_ADDR_Y,
+	CIF_FRM1_ADDR_UV,
+	CIF_VIR_LINE_WIDTH,
+	CIF_SET_SIZE,
+	CIF_SCL_CTRL,
+	CIF_FRAME_STATUS,
+	CIF_LAST_LINE,
+	CIF_LAST_PIX,
+	CIF_REGISTERS_MAX,
+	CIF_REGISTERS_INVALID,
+};
+
 #define CIF_FETCH_Y_LAST_LINE(VAL)		((VAL) & 0x1fff)
 
 #define CIF_CTRL_ENABLE_CAPTURE			BIT(0)

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:24 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:24 +0100
Subject: [PATCH 14/14] arm64: dts: rockchip: add vicap node to rk356x
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-14-2680a1fa640b@wolfvision.net>

Add the device tree node for the RK356x Video Capture (VICAP)
block.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 45 ++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index c19c0f1b3778..ad61afd84c12 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -6,6 +6,7 @@
 #include <dt-bindings/clock/rk3568-cru.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/media/rockchip-cif.h>
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/power/rk3568-power.h>
@@ -593,6 +594,50 @@ gpu: gpu at fde60000 {
 		status = "disabled";
 	};
 
+	vicap: video-capture at fdfe0000 {
+		compatible = "rockchip,rk3568-vicap";
+		reg = <0x0 0xfdfe0000 0x0 0x200>;
+		interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+		assigned-clocks = <&cru DCLK_VICAP>;
+		assigned-clock-rates = <300000000>;
+		clocks = <&cru ACLK_VICAP>, <&cru HCLK_VICAP>,
+			 <&cru DCLK_VICAP>, <&cru ICLK_VICAP_G>;
+		clock-names = "aclk", "hclk", "dclk", "iclk";
+		iommus = <&vicap_mmu>;
+		power-domains = <&power RK3568_PD_VI>;
+		resets = <&cru SRST_A_VICAP>, <&cru SRST_H_VICAP>,
+			 <&cru SRST_D_VICAP>, <&cru SRST_P_VICAP>,
+			 <&cru SRST_I_VICAP>;
+		reset-names = "arst", "hrst", "drst", "prst", "irst";
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			vicap_dvp: port at MEDIA_ROCKCHIP_CIF_DVP {
+				reg = <MEDIA_ROCKCHIP_CIF_DVP>;
+			};
+
+			vicap_mipi: port at MEDIA_ROCKCHIP_CIF_MIPI {
+				reg = <MEDIA_ROCKCHIP_CIF_MIPI>;
+			};
+		};
+	};
+
+	vicap_mmu: iommu at fdfe0800 {
+		compatible = "rockchip,rk3568-iommu";
+		reg = <0x0 0xfdfe0800 0x0 0x100>;
+		interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VICAP>, <&cru HCLK_VICAP>;
+		clock-names = "aclk", "iface";
+		#iommu-cells = <0>;
+		power-domains = <&power RK3568_PD_VI>;
+		rockchip,disable-mmu-reset;
+		status = "disabled";
+	};
+
 	vpu: video-codec at fdea0400 {
 		compatible = "rockchip,rk3568-vpu";
 		reg = <0x0 0xfdea0000 0x0 0x800>;

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:21 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:21 +0100
Subject: [PATCH 11/14] media: rockchip: cif: make scaler support variant
 specific
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-11-2680a1fa640b@wolfvision.net>

Not all variants of the Rockchip CIF feature a scaler unit. Add
variant specific Boolean variable to account for this.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 drivers/media/platform/rockchip/cif/cif-capture.c | 8 +++++---
 drivers/media/platform/rockchip/cif/cif-common.h  | 1 +
 drivers/media/platform/rockchip/cif/cif-dev.c     | 1 +
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/rockchip/cif/cif-capture.c b/drivers/media/platform/rockchip/cif/cif-capture.c
index b26e6023c2b0..dd5c45f28cdd 100644
--- a/drivers/media/platform/rockchip/cif/cif-capture.c
+++ b/drivers/media/platform/rockchip/cif/cif-capture.c
@@ -365,9 +365,11 @@ static int cif_stream_start(struct cif_stream *stream)
 
 	cif_write(cif_dev, CIF_FRAME_STATUS, CIF_FRAME_STAT_CLS);
 	cif_write(cif_dev, CIF_INTSTAT, CIF_INTSTAT_CLS);
-	cif_write(cif_dev, CIF_SCL_CTRL, (fmt_type == CIF_FMT_TYPE_YUV) ?
-					 CIF_SCL_CTRL_ENABLE_YUV_16BIT_BYPASS :
-					 CIF_SCL_CTRL_ENABLE_RAW_16BIT_BYPASS);
+	if (cif_dev->match_data->has_scaler)
+		cif_write(cif_dev, CIF_SCL_CTRL,
+			  (fmt_type == CIF_FMT_TYPE_YUV) ?
+				  CIF_SCL_CTRL_ENABLE_YUV_16BIT_BYPASS :
+				  CIF_SCL_CTRL_ENABLE_RAW_16BIT_BYPASS);
 
 	ret = cif_init_buffers(stream);
 	if (ret)
diff --git a/drivers/media/platform/rockchip/cif/cif-common.h b/drivers/media/platform/rockchip/cif/cif-common.h
index 84a7545422e1..e5500705eee2 100644
--- a/drivers/media/platform/rockchip/cif/cif-common.h
+++ b/drivers/media/platform/rockchip/cif/cif-common.h
@@ -100,6 +100,7 @@ struct cif_match_data {
 	const struct cif_input_fmt *in_fmts;
 	int in_fmts_num;
 	void (*grf_dvp_setup)(struct cif_device *cif_dev);
+	bool has_scaler;
 };
 
 struct cif_device {
diff --git a/drivers/media/platform/rockchip/cif/cif-dev.c b/drivers/media/platform/rockchip/cif/cif-dev.c
index fb80e8f8dcab..e7b5ae5804ca 100644
--- a/drivers/media/platform/rockchip/cif/cif-dev.c
+++ b/drivers/media/platform/rockchip/cif/cif-dev.c
@@ -282,6 +282,7 @@ static const struct cif_match_data px30_cif_match_data = {
 	.clks_num = ARRAY_SIZE(px30_cif_clks),
 	.in_fmts = px30_in_fmts,
 	.in_fmts_num = ARRAY_SIZE(px30_in_fmts),
+	.has_scaler = true,
 };
 
 static const struct of_device_id cif_plat_of_match[] = {

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:16 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:16 +0100
Subject: [PATCH 06/14] media: rockchip: cif: store endpoint information in
 private data
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-6-2680a1fa640b@wolfvision.net>

The endpoint information such as bus width or flags are required
to set CIF (and on certain variants GRF) registers correctly. Store
the information in the private data of the driver in order to make
it accessible.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 drivers/media/platform/rockchip/cif/cif-common.h |  1 +
 drivers/media/platform/rockchip/cif/cif-dev.c    | 11 +++++------
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/rockchip/cif/cif-common.h b/drivers/media/platform/rockchip/cif/cif-common.h
index 89ed9dd6f36d..34da800a0504 100644
--- a/drivers/media/platform/rockchip/cif/cif-common.h
+++ b/drivers/media/platform/rockchip/cif/cif-common.h
@@ -108,6 +108,7 @@ struct cif_device {
 	struct media_device		media_dev;
 	struct v4l2_async_notifier	notifier;
 	struct v4l2_async_connection	asd;
+	struct v4l2_fwnode_endpoint	vep;
 	struct cif_remote		remote;
 
 	struct cif_stream		stream;
diff --git a/drivers/media/platform/rockchip/cif/cif-dev.c b/drivers/media/platform/rockchip/cif/cif-dev.c
index 660e28397916..923831827be4 100644
--- a/drivers/media/platform/rockchip/cif/cif-dev.c
+++ b/drivers/media/platform/rockchip/cif/cif-dev.c
@@ -79,9 +79,7 @@ static int cif_subdev_notifier(struct cif_device *cif_dev)
 	struct v4l2_async_notifier *ntf = &cif_dev->notifier;
 	struct device *dev = cif_dev->dev;
 	struct v4l2_async_connection *asd;
-	struct v4l2_fwnode_endpoint vep = {
-		.bus_type = V4L2_MBUS_UNKNOWN,
-	};
+	struct v4l2_fwnode_endpoint *vep = &cif_dev->vep;
 	struct fwnode_handle *ep;
 	int ret;
 
@@ -92,12 +90,13 @@ static int cif_subdev_notifier(struct cif_device *cif_dev)
 	if (!ep)
 		return -ENODEV;
 
-	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+	vep->bus_type = V4L2_MBUS_UNKNOWN;
+	ret = v4l2_fwnode_endpoint_parse(ep, vep);
 	if (ret)
 		goto complete;
 
-	if (vep.bus_type != V4L2_MBUS_BT656 &&
-	    vep.bus_type != V4L2_MBUS_PARALLEL) {
+	if (vep->bus_type != V4L2_MBUS_BT656 &&
+	    vep->bus_type != V4L2_MBUS_PARALLEL) {
 		v4l2_err(&cif_dev->v4l2_dev, "unsupported bus type\n");
 		goto complete;
 	}

-- 
2.30.2



From michael.riesch at wolfvision.net  Tue Feb 20 01:39:23 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:23 +0100
Subject: [PATCH 13/14] media: rockchip: cif: add support for rk3568 vicap
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-13-2680a1fa640b@wolfvision.net>

Add support for the Rockchip RK3568 video capture (VICAP) block.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 drivers/media/platform/rockchip/cif/cif-capture.c |   6 +
 drivers/media/platform/rockchip/cif/cif-dev.c     | 247 ++++++++++++++++++++++
 drivers/media/platform/rockchip/cif/cif-regs.h    |   9 +
 3 files changed, 262 insertions(+)

diff --git a/drivers/media/platform/rockchip/cif/cif-capture.c b/drivers/media/platform/rockchip/cif/cif-capture.c
index dd5c45f28cdd..d0e8f3b49d38 100644
--- a/drivers/media/platform/rockchip/cif/cif-capture.c
+++ b/drivers/media/platform/rockchip/cif/cif-capture.c
@@ -340,6 +340,7 @@ static int cif_stream_start(struct cif_stream *stream)
 	u32 val, fmt_type, xfer_mode = 0;
 	struct cif_device *cif_dev = stream->cifdev;
 	struct cif_remote *remote_info = &cif_dev->remote;
+	struct v4l2_mbus_config_parallel *parallel;
 	int ret;
 	u32 input_mode;
 
@@ -351,6 +352,11 @@ static int cif_stream_start(struct cif_stream *stream)
 		      CIF_FORMAT_INPUT_MODE_NTSC :
 		      CIF_FORMAT_INPUT_MODE_PAL;
 
+	parallel = &cif_dev->vep.bus.parallel;
+	if ((parallel->bus_width == 16) &&
+	    (parallel->flags & V4L2_MBUS_PCLK_SAMPLE_DUALEDGE))
+		xfer_mode |= CIF_FORMAT_BT1120_CLOCK_DOUBLE_EDGES;
+
 	val = input_mode | stream->cif_fmt_out->fmt_val |
 	      stream->cif_fmt_in->dvp_fmt_val | xfer_mode;
 	cif_write(cif_dev, CIF_FOR, val);
diff --git a/drivers/media/platform/rockchip/cif/cif-dev.c b/drivers/media/platform/rockchip/cif/cif-dev.c
index 929ea39dd832..3b895b496c45 100644
--- a/drivers/media/platform/rockchip/cif/cif-dev.c
+++ b/drivers/media/platform/rockchip/cif/cif-dev.c
@@ -302,11 +302,258 @@ static const struct cif_match_data px30_cif_match_data = {
 	},
 };
 
+static const struct cif_input_fmt rk3568_in_fmts[] = {
+	{
+		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YUYV,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YUYV,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_YVYU8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YVYU,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_YVYU8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YVYU,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_UYVY,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_UYVY,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_VYUY8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_VYUY,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_VYUY8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_VYUY,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_YUYV8_1X16,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+				  CIF_FORMAT_INPUT_MODE_BT1120 |
+				  CIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_YUYV8_1X16,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+				  CIF_FORMAT_INPUT_MODE_BT1120,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_YVYU8_1X16,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+				  CIF_FORMAT_INPUT_MODE_BT1120 |
+				  CIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_YVYU8_1X16,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+				  CIF_FORMAT_INPUT_MODE_BT1120,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_UYVY8_1X16,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+				  CIF_FORMAT_INPUT_MODE_BT1120 |
+				  CIF_FORMAT_BT1120_YC_SWAP |
+				  CIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_UYVY8_1X16,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+				  CIF_FORMAT_BT1120_YC_SWAP |
+				  CIF_FORMAT_INPUT_MODE_BT1120,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_VYUY8_1X16,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+				  CIF_FORMAT_INPUT_MODE_BT1120 |
+				  CIF_FORMAT_BT1120_YC_SWAP |
+				  CIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_VYUY8_1X16,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+				  CIF_FORMAT_BT1120_YC_SWAP |
+				  CIF_FORMAT_INPUT_MODE_BT1120,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGBRG8_1X8,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGRBG8_1X8,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SRGGB8_1X8,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SBGGR10_1X10,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGBRG10_1X10,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGRBG10_1X10,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SRGGB10_1X10,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SBGGR12_1X12,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGBRG12_1X12,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGRBG12_1X12,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SRGGB12_1X12,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_RGB888_1X24,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_Y8_1X8,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_Y10_1X10,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_Y12_1X12,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	},
+};
+
+static struct clk_bulk_data rk3568_cif_clks[] = {
+	{ .id = "aclk", },
+	{ .id = "hclk", },
+	{ .id = "dclk", },
+	{ .id = "iclk", },
+};
+
+static void rk3568_grf_dvp_setup(struct cif_device *cif_dev)
+{
+	u32 con1 = RK3568_GRF_WRITE_ENABLE(RK3568_GRF_VI_CON1_CIF_DATAPATH);
+
+	if (cif_dev->vep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_DUALEDGE)
+		con1 |= RK3568_GRF_VI_CON1_CIF_DATAPATH;
+
+	regmap_write(cif_dev->grf, RK3568_GRF_VI_CON1, con1);
+}
+
+static const struct cif_match_data rk3568_cif_match_data = {
+	.clks = rk3568_cif_clks,
+	.clks_num = ARRAY_SIZE(rk3568_cif_clks),
+	.grf_dvp_setup = rk3568_grf_dvp_setup,
+	.in_fmts = rk3568_in_fmts,
+	.in_fmts_num = ARRAY_SIZE(rk3568_in_fmts),
+	.has_scaler = false,
+	.regs = {
+		[CIF_CTRL] = 0x00,
+		[CIF_INTEN] = 0x04,
+		[CIF_INTSTAT] = 0x08,
+		[CIF_FOR] = 0x0c,
+		[CIF_LINE_NUM_ADDR] = 0x2c,
+		[CIF_FRM0_ADDR_Y] = 0x14,
+		[CIF_FRM0_ADDR_UV] = 0x18,
+		[CIF_FRM1_ADDR_Y] = 0x1c,
+		[CIF_FRM1_ADDR_UV] = 0x20,
+		[CIF_VIR_LINE_WIDTH] = 0x24,
+		[CIF_SET_SIZE] = 0x28,
+		[CIF_FRAME_STATUS] = 0x3c,
+		[CIF_LAST_LINE] = 0x44,
+		[CIF_LAST_PIX] = 0x48,
+	},
+};
+
 static const struct of_device_id cif_plat_of_match[] = {
 	{
 		.compatible = "rockchip,px30-vip",
 		.data = &px30_cif_match_data,
 	},
+	{
+		.compatible = "rockchip,rk3568-vicap",
+		.data = &rk3568_cif_match_data,
+	},
 	{},
 };
 
diff --git a/drivers/media/platform/rockchip/cif/cif-regs.h b/drivers/media/platform/rockchip/cif/cif-regs.h
index 2ce756fde204..261bc71240f2 100644
--- a/drivers/media/platform/rockchip/cif/cif-regs.h
+++ b/drivers/media/platform/rockchip/cif/cif-regs.h
@@ -117,4 +117,13 @@ enum cif_register {
 #define CIF_CROP_Y_SHIFT			16
 #define CIF_CROP_X_SHIFT			0
 
+/* GRF register offsets */
+#define RK3568_GRF_VI_CON0			0x340
+#define RK3568_GRF_VI_CON1			0x344
+#define RK3568_GRF_VI_STATUS0			0x348
+
+#define RK3568_GRF_VI_CON1_CIF_DATAPATH		BIT(9)
+
+#define RK3568_GRF_WRITE_ENABLE(x)		((x) << 16)
+
 #endif

-- 
2.30.2



From ankita at nvidia.com  Tue Feb 20 01:40:31 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Tue, 20 Feb 2024 09:40:31 +0000
Subject: [PATCH v8 2/4] mm: introduce new flag to indicate wc safe
In-Reply-To: <709fe097-9cc0-4d61-89e5-65147f541e95@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-3-ankita@nvidia.com>
 <bc5cdc2e-50d8-435a-8f9d-a0053a99598d@nvidia.com>
 <SA1PR12MB71992963218C5753F346B3D7B0502@SA1PR12MB7199.namprd12.prod.outlook.com>
 <6ca94bf1-68b4-4a81-8cd0-d86683e0b12c@redhat.com>
 <709fe097-9cc0-4d61-89e5-65147f541e95@nvidia.com>
Message-ID: <SA1PR12MB719965C8386AB1A309397B49B0502@SA1PR12MB7199.namprd12.prod.outlook.com>

>>>>> To safely use VFIO in KVM the platform must guarantee full safety in
>>>>> the
>>>>> guest where no action taken against a MMIO mapping can trigger an
>>>>> uncontained failure. We belive that most VFIO PCI platforms support
>>>>> this
>>>>
>>>> A nit, let's use passive voice in the patch comment. Also belive is
>>>> mostly
>>>> a typo.
>>>
>>> Sure, will do.
>>>
>>
>> s/we expect/the expectation is that/
>> s/We belive/The assumption is/
>>
>> If it's just that, likely no need to resend. Maintainers usually can fix
>> that up when applying (otherwise, they'll let you know :) ).
>>
> Many thanks! :)

Good to know, thanks David.


From kurt at linutronix.de  Tue Feb 20 01:44:57 2024
From: kurt at linutronix.de (Kurt Kanzenbach)
Date: Tue, 20 Feb 2024 10:44:57 +0100
Subject: [PATCH net] net: stmmac: Fix EST offset for dwmac 5.10
In-Reply-To: <mmjrlyzhegve5u3s3lhw4hmhooxixn3pwxkkdikxgxno4teqyz@rtetljwg6ffg>
References: <20240220-stmmac_est-v1-1-c41f9ae2e7b7@linutronix.de>
 <mmjrlyzhegve5u3s3lhw4hmhooxixn3pwxkkdikxgxno4teqyz@rtetljwg6ffg>
Message-ID: <87ttm3wjty.fsf@kurt.kurt.home>

On Tue Feb 20 2024, Serge Semin wrote:
> Hi Kurt
>
> On Tue, Feb 20, 2024 at 09:22:46AM +0100, Kurt Kanzenbach wrote:
>> Fix EST offset for dwmac 5.10.
>> 
>> Currently configuring Qbv doesn't work as expected. The schedule is
>> configured, but never confirmed:
>> 
>> |[  128.250219] imx-dwmac 428a0000.ethernet eth1: configured EST
>> 
>> The reason seems to be the refactoring of the EST code which set the wrong
>> EST offset for the dwmac 5.10. After fixing this it works as before:
>> 
>> |[  106.359577] imx-dwmac 428a0000.ethernet eth1: configured EST
>> |[  128.430715] imx-dwmac 428a0000.ethernet eth1: EST: SWOL has been switched
>> 
>> Tested on imx93.
>> 
>> Fixes: c3f3b97238f6 ("net: stmmac: Refactor EST implementation")
>> Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
>> ---
>>  drivers/net/ethernet/stmicro/stmmac/hwif.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
>> index 1bd34b2a47e8..29367105df54 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
>> @@ -224,7 +224,7 @@ static const struct stmmac_hwif_entry {
>>  		.regs = {
>>  			.ptp_off = PTP_GMAC4_OFFSET,
>>  			.mmc_off = MMC_GMAC4_OFFSET,
>> -			.est_off = EST_XGMAC_OFFSET,
>> +			.est_off = EST_GMAC4_OFFSET,
>
> Unfortunate c&p typo indeed. Thanks for fixing it!

No problem. I was just wondering why the confirmation message doesn't
show up after updating to v6.8-RT :-).

Thanks,
Kurt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 861 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240220/5d983914/attachment-0001.sig>

From krzysztof.kozlowski at linaro.org  Tue Feb 20 01:49:59 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 10:49:59 +0100
Subject: [PATCH 02/13] dt-bindings: i2c: nomadik: add mobileye,eyeq5-i2c
 bindings and example
In-Reply-To: <CZ93KAA53F8G.38AUM6RZGUYY7@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-2-19a336e91dca@bootlin.com>
 <20240216022227.GA850600-robh@kernel.org>
 <CZ6FD7EHIJDT.32IEDVT9FG2GP@bootlin.com>
 <6effca50-29a4-43b9-86eb-310bd4e08e5c@linaro.org>
 <CZ6FUECKEX2B.36QWZZA5EYPI@bootlin.com>
 <cf360cbf-7414-4024-8bdd-d2aba7f048b3@linaro.org>
 <CZ93KAA53F8G.38AUM6RZGUYY7@bootlin.com>
Message-ID: <37116892-bb59-4c40-85e2-8e1b4bc96b5f@linaro.org>

On 19/02/2024 14:41, Th?o Lebrun wrote:
> Hello,
> 
> On Sat Feb 17, 2024 at 9:25 AM CET, Krzysztof Kozlowski wrote:
>> On 16/02/2024 11:40, Th?o Lebrun wrote:
>>> On Fri Feb 16, 2024 at 11:33 AM CET, Krzysztof Kozlowski wrote:
>>>> On 16/02/2024 11:18, Th?o Lebrun wrote:
>>>>>
>>>>>>> +        mobileye,id:
>>>>>>> +          $ref: /schemas/types.yaml#/definitions/uint32
>>>>>>> +          description: Platform-wide controller ID (integer starting from zero).
>>>>>>
>>>>>> instance indexes are a NAK. You can use i2cN aliases if you must.
>>>>>>
>>>>>> Why do you need it? To access OLB? If so, add cell args to the OLB 
>>>>>> phandle instead.
>>>>>
>>>>> Why we do what we do: I2C controller must write a 2 bit value depending
>>>>> on the bus speed. All I2C controllers write into the same register.
>>>>
>>>> Which register?  Your devices do not share IO address space.
>>>
>>> mobileye,olb is a prop with a phandle to a syscon. That syscon contains
>>> the register we are interested in.
>>
>> So exactly what Rob said... I don't understand why you have chosen to go
>> with alias.
> 
> I had misunderstood Rob's original message. Now that I've done some
> tests to use cells I get what was meant. I'd have a follow-up question.
> What should the cells contain? I see two options:
> 
>  - phandle + I2C controller global index (from 0 thru 4). Then Linux
>    (or other) driver know how to map that index to register + mask
>    combo. ie:
> 
>       i2c2: i2c at 500000 {
>          compatible = "mobileye,eyeq5-i2c", "arm,primecell";
>          reg = <0 0x500000 0x0 0x1000>;
>          /* ... */
>          mobileye,olb = <&olb 2>;
>       };
> 
>  - phandle + register offset + mask. ie:
> 
>       i2c2: i2c at 500000 {
>          compatible = "mobileye,eyeq5-i2c", "arm,primecell";
>          reg = <0 0x500000 0x0 0x1000>;
>          /* ... */
>          mobileye,olb = <&olb 0xB8 0x300>; /* phandle + offset + mask */
>       };

Whichever works for your current and possibly future needs and hardware,
because property should have one meaning. It's anyway specific to the
property. Second option is quite popular. Please design it for entire
hardware, not for this one particular case.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 20 01:50:29 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 10:50:29 +0100
Subject: [PATCH 1/4] dt-bindings: soc: renesas: Document Renesas RZ/V2H{P}
 SoC variants
In-Reply-To: <20240219160912.1206647-2-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20240219160912.1206647-2-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <2d85b8a8-853d-4792-91d4-d0c43c4dec93@linaro.org>

On 19/02/2024 17:09, Prabhakar wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> 
> Document Renesas RZ/V2H{P} (R9A09G057) SoC variants.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> Reviewed-by: Fabrizio Castro <fabrizio.castro.jz at renesas.com>
> ---

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From cassel at kernel.org  Tue Feb 20 01:51:17 2024
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 20 Feb 2024 10:51:17 +0100
Subject: [PATCH v10 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <ZdN/OyNpw0Xa7qXG@lizhi-Precision-Tower-5810>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>
 <20240219161208.GE3281@thinkpad>
 <ZdN/OyNpw0Xa7qXG@lizhi-Precision-Tower-5810>
Message-ID: <ZdR2FRQ9Fe8hhK9I@x1-carbon>

On Mon, Feb 19, 2024 at 11:18:03AM -0500, Frank Li wrote:
> On Mon, Feb 19, 2024 at 09:42:08PM +0530, Manivannan Sadhasivam wrote:
> > On Mon, Feb 19, 2024 at 10:11:45AM -0500, Frank Li wrote:
> > > On Mon, Feb 05, 2024 at 12:33:21PM -0500, Frank Li wrote:
> > > > first 6 patches use drvdata: flags to simplify some switch-case code.
> > > > Improve maintaince and easy to read code.
> > > > 
> > > 
> > > @Lorenzo Pieralisi:
> > > 
> > > 	Do you have chance to look other patches?
> > > 	Mani's apply EP side change. 
> > 
> > Even though the controller is for the endpoint, it is still a controller
> > driver. So all the patches should go through Lorenzo.
> > 
> > I only merge patches under drivers/pci/endpoint. Hope this clarifies.
> 
> Sorry. It confused everyone. My means was that Mani applied Niklas Cassel's
> patches, which cause my 14th patch build failure.

Hello Frank,

Patch 14, which adds this:

+static const struct pci_epc_features imx95_pcie_epc_features = {
+       .msi_capable = true,
+       .bar_fixed_size[1] = SZ_64K,
+       .align = SZ_4K,
+};


Should, after rebasing on Mani's pci/endpoint branch, instead look like this:

+static const struct pci_epc_features imx95_pcie_epc_features = {
+       .msi_capable = true,
+       .bar[BAR_1] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
+       .align = SZ_4K,
+};


> 
> I asked if I need update my 14th patch or applied 1-13 only. 

I see, you want the maintainers to apply 1-13, and simply drop patch 14
instead of you sending out a rebased series.

I assume that the maintainers will be fine with your suggested approach.


Kind regards,
Niklas


From krzysztof.kozlowski at linaro.org  Tue Feb 20 01:51:49 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 10:51:49 +0100
Subject: [PATCH 2/4] dt-bindings: arm: renesas: Document Renesas RZ/V2H{P}
 System Controller
In-Reply-To: <20240219160912.1206647-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20240219160912.1206647-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <47c8bbe3-610d-40cc-b505-e9ce9a371ef7@linaro.org>

On 19/02/2024 17:09, Prabhakar wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> 
> Add DT binding documentation for System Controller (SYS) found on
> RZ/V2H{P} ("R9A09G057") SoC's.
> 
> SYS block contains the SYS_LSI_DEVID register which can be used to
> retrieve SoC version information.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> Reviewed-by: Fabrizio Castro <fabrizio.castro.jz at renesas.com>


> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    extal_clk: extal-clk {
> +        compatible = "fixed-clock";
> +        #clock-cells = <0>;
> +        clock-frequency = <24000000>;
> +    };

Drop the node, not relevant.

> +
> +    sys: system-controller at 10430000 {
> +        compatible = "renesas,r9a09g057-sys";
> +        reg = <0x10430000 0x10000>;
> +        clocks = <&extal_clk>;
> +        resets = <&cpg 1>;
> +    };

Best regards,
Krzysztof



From liuyuntao12 at huawei.com  Tue Feb 20 01:53:00 2024
From: liuyuntao12 at huawei.com (liuyuntao (F))
Date: Tue, 20 Feb 2024 17:53:00 +0800
Subject: [PATCH -next] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
In-Reply-To: <1342759e-b967-4ec4-98d5-48146f81f695@app.fastmail.com>
References: <20240220081527.23408-1-liuyuntao12@huawei.com>
 <1342759e-b967-4ec4-98d5-48146f81f695@app.fastmail.com>
Message-ID: <38c09a4b-69cc-4dc5-8a68-e5f5597613ac@huawei.com>



? 2024/2/20 16:40, Arnd Bergmann ??:
> On Tue, Feb 20, 2024, at 09:15, Yuntao Liu wrote:
>> diff --git a/arch/arm/boot/compressed/vmlinux.lds.S
>> b/arch/arm/boot/compressed/vmlinux.lds.S
>> index 3fcb3e62dc56..da21244aa892 100644
>> --- a/arch/arm/boot/compressed/vmlinux.lds.S
>> +++ b/arch/arm/boot/compressed/vmlinux.lds.S
>> @@ -89,7 +89,7 @@ SECTIONS
>>        * The EFI stub always executes from RAM, and runs strictly before
>> the
>>        * decompressor, so we can make an exception for its r/w data, and
>> keep it
>>        */
>> -    *(.data.efistub .bss.efistub)
>> +    *(.data.* .bss.*)
>>       __pecoff_data_end = .;
>>
>>       /*
> 
> This doesn't seem right to me, or maybe I misunderstand what
> the original version does. Have you tested with both
> CONFIG_EFI_STUB on and off, and booting with and without
> UEFI?

Yes, I have tested with CONFIG_EFI_STUB on and off, and booting with 
UEFI on a single-board computer, and it boots well.


> 
> If I read this right, you would move all .data and .bss
> into the stub here, not just the parts we actually want?

In the file "drivers/firmware/efi/libstub/Makefile", it is written:

---

#
# ARM discards the .data section because it disallows r/w data in the
# decompressor. So move our .data to .data.efistub and .bss to .bss.efistub,
# which are preserved explicitly by the decompressor linker script.
#
STUBCOPY_FLAGS-$(CONFIG_ARM)	+= --rename-section .data=.data.efistub	\
				   --rename-section .bss=.bss.efistub,load,alloc

---

I think that .data.efistub represents the entire .data section, the same 
applies to .bss as well,

so i move all .data and .bss into the stub here.


> 
>> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
>> index bd9127c4b451..de373c6c2ae8 100644
>> --- a/arch/arm/kernel/vmlinux.lds.S
>> +++ b/arch/arm/kernel/vmlinux.lds.S
>> @@ -74,7 +74,7 @@ SECTIONS
>>   	. = ALIGN(4);
>>   	__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
>>   		__start___ex_table = .;
>> -		ARM_MMU_KEEP(*(__ex_table))
>> +		ARM_MMU_KEEP(KEEP(*(__ex_table)))
>>   		__stop___ex_table = .;
>>   	}
>>
>> @@ -116,7 +116,7 @@ SECTIONS
>>   #endif
>>   	.init.pv_table : {
>>   		__pv_table_begin = .;
>> -		*(.pv_table)
>> +		KEEP(*(.pv_table))
>>   		__pv_table_end = .;
>>   	}
> 
> I guess this prevents discarding any function that has a reference
> from pv_table or ex_table, even if there are no other references,
> right?

Indeed so, if not keep ex_table,  the compilation process will result in

an error:

     no __ex_table in file: vmlinux

     Failed to sort kernel tables

and if not keep pv_table, It can be compiled successfully, but the QEMU 
boots will fail.

> 
> I don't know how to solve this other than forcing all the
> uaccess and virt_to_phys functions to be out of line
> helpers. For uaccess, there are probably very few functions
> that need this, so it should make little difference.
> 
> You might want to try changing CONFIG_ARM_PATCH_PHYS_VIRT
> into a method that just always adds an offset from C code
> instead of the boot time patching. That way the code would
> be a bit less efficient but you might be able to get
> a larger size reduction by dropping additional unused code.
> 
> Maybe test your patch both with and without
> ARM_PATCH_PHYS_VIRT to see what the best-case impact would
> be.
> 

This is a very good idea, I will give it a try.

>        Arnd


From miquel.raynal at bootlin.com  Tue Feb 20 01:53:13 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 20 Feb 2024 10:53:13 +0100
Subject: [PATCH v5 09/12] mtd: rawnand: brcmnand: Add support for
 getting ecc setting from strap
In-Reply-To: <20240207202257.271784-10-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
	<20240207202257.271784-10-william.zhang@broadcom.com>
Message-ID: <20240220105313.5e3c600d@xps-13>

Hi William,

william.zhang at broadcom.com wrote on Wed,  7 Feb 2024 12:22:54 -0800:

> BCMBCA broadband SoC based board design does not specify ecc setting in
> dts but rather use the SoC NAND strap info to obtain the ecc strength
> and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
> this purpose and update driver to support this option.
> 
> The generic nand ecc settings still take precedence over this flag. For
> example, if nand-ecc-strength is set in the dts, the driver ignores the
> strap setting and falls back to original behavior. This makes sure that
> the existing BCMBCA board dts still works the old way even the strap
> flag is set in the BCMBCA chip dtsi.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>
> 
> ---
> 
> Changes in v5: None
> Changes in v4:
> - Update the comments for ecc setting selection
> 
> Changes in v3: None
> Changes in v2:
> - Minor cosmetic fixes
> 
>  drivers/mtd/nand/raw/brcmnand/brcmnand.c | 83 ++++++++++++++++++++++--
>  1 file changed, 76 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index 73fdf7ce21aa..efeee9e80213 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -1038,6 +1038,19 @@ static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl)
>  		return -1;
>  }
>  
> +static int brcmnand_get_sector_size_1k(struct brcmnand_host *host)
> +{
> +	struct brcmnand_controller *ctrl = host->ctrl;
> +	int shift = brcmnand_sector_1k_shift(ctrl);
> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> +						  BRCMNAND_CS_ACC_CONTROL);
> +
> +	if (shift < 0)
> +		return 0;
> +
> +	return (nand_readreg(ctrl, acc_control_offs) >> shift) & 0x1;

What is this & 0x1 ? If you return a yes/no value, please make this
function return a bool. Also, please use intermediate steps to clarify
what you do.

sector_1k_bit = ...;
acc = nand_readreg();
return acc & BIT(sector_1k_bit);

Or something like that.

> +}
> +
>  static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
>  {
>  	struct brcmnand_controller *ctrl = host->ctrl;
> @@ -1055,6 +1068,38 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
>  	nand_writereg(ctrl, acc_control_offs, tmp);
>  }
>  
> +static int brcmnand_get_spare_size(struct brcmnand_host *host)
> +{
> +	struct brcmnand_controller *ctrl = host->ctrl;
> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> +						  BRCMNAND_CS_ACC_CONTROL);
> +	u32 acc = nand_readreg(ctrl, acc_control_offs);
> +
> +	return (acc & brcmnand_spare_area_mask(ctrl));
> +}
> +
> +static int brcmnand_get_ecc_strength(struct brcmnand_host *host)

					_from_strap

> +{
> +	struct brcmnand_controller *ctrl = host->ctrl;
> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> +						  BRCMNAND_CS_ACC_CONTROL);
> +	int sector_size_1k = brcmnand_get_sector_size_1k(host);
> +	int spare_area_size, ecc_level, ecc_strength;
> +	u32 acc;
> +
> +	spare_area_size = brcmnand_get_spare_size(host);
> +	acc = nand_readreg(ctrl, acc_control_offs);
> +	ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl->ecc_level_shift;

Please use FIELD_PREP/FIELD_GET.

> +	if (sector_size_1k)
> +		ecc_strength = ecc_level * 2;
> +	else if (spare_area_size == 16 && ecc_level == 15)
> +		ecc_strength = 1; /* hamming */
> +	else
> +		ecc_strength = ecc_level;
> +
> +	return ecc_strength;
> +}
> +
>  /***********************************************************************
>   * CS_NAND_SELECT
>   ***********************************************************************/
> @@ -2622,19 +2667,43 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
>  		nanddev_get_memorg(&chip->base);
>  	struct brcmnand_controller *ctrl = host->ctrl;
>  	struct brcmnand_cfg *cfg = &host->hwcfg;
> -	char msg[128];
> +	struct device_node *np = nand_get_flash_node(chip);
>  	u32 offs, tmp, oob_sector;
> -	int ret;
> +	int ret, sector_size_1k = 0;
> +	bool use_strap = false;
> +	char msg[128];
>  
>  	memset(cfg, 0, sizeof(*cfg));
> +	use_strap = of_property_read_bool(np, "brcm,nand-ecc-use-strap");
>  
> -	ret = of_property_read_u32(nand_get_flash_node(chip),
> -				   "brcm,nand-oob-sector-size",
> +	/*
> +	 * Set ECC size and strength based on hw configuration from strap
> +	 * if brcm,nand-ecc-use-strap is set. However if nand-ecc-strength
> +	 * is set, its value will be used and ignore the strap setting.

Please error out in this case. It's one or the other, not both.

> +	 */
> +	if (chip->ecc.strength)
> +		use_strap = 0;
> +
> +	if (use_strap) {
> +		chip->ecc.strength = brcmnand_get_ecc_strength(host);
> +		sector_size_1k = brcmnand_get_sector_size_1k(host);
> +		if (chip->ecc.size == 0) {
> +			if (sector_size_1k < 0)
> +				chip->ecc.size = 512;
> +			else
> +				chip->ecc.size = 512 << sector_size_1k;
> +		}

I'd instead make a function named brcmnand_get_ecc_settings() with the
chip->ecc parameter, so you can directly fill the entries without
getting another time the sector_size_1k thing.

Strength and step size are tightly linked, it does make sense to derive
them both at the same time.

> +	}
> +
> +	ret = of_property_read_u32(np, "brcm,nand-oob-sector-size",
>  				   &oob_sector);
>  	if (ret) {
> -		/* Use detected size */
> -		cfg->spare_area_size = mtd->oobsize /
> -					(mtd->writesize >> FC_SHIFT);
> +		if (use_strap)
> +			cfg->spare_area_size = brcmnand_get_spare_size(host);
> +		else
> +			/* Use detected size */
> +			cfg->spare_area_size = mtd->oobsize /
> +						(mtd->writesize >> FC_SHIFT);
>  	} else {
>  		cfg->spare_area_size = oob_sector;
>  	}


Thanks,
Miqu?l


From brgl at bgdev.pl  Tue Feb 20 01:54:02 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 20 Feb 2024 10:54:02 +0100
Subject: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
In-Reply-To: <yu5uhamdlygti3jo73ipy3gxhcmgxrm5g6imgqg6ksleim4ton@npvzlex2j4xi>
References: <20240205182810.58382-1-brgl@bgdev.pl> <20240205182810.58382-9-brgl@bgdev.pl>
 <yu5uhamdlygti3jo73ipy3gxhcmgxrm5g6imgqg6ksleim4ton@npvzlex2j4xi>
Message-ID: <CAMRc=Mctm-cyYPpu-Vb+fr1cWJPUW49shaa9HEXYp+rkF_CHUw@mail.gmail.com>

On Sun, Feb 18, 2024 at 4:08?AM Bjorn Andersson <andersson at kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:06PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
> > convert all users of it in the qseecom module to using the TZ allocator
> > for creating SCM call buffers.
>
> This reads as if this is removal of duplication, now that we have the TZ
> allocation. But wasn't there something about you not being able to mix
> and match shmbridge and non-shmbridge allocations in the interface, so
> this transition is actually required? Or did I get that wrong and this
> just reduction in duplication?
>

What is the question exactly? Yes it is required because once we
enable SHM bridge, "normal" memory will no longer be accepted for SCM
calls.

> > Together with using the cleanup macros,
> > it has the added benefit of a significant code shrink.
>
> That is true, but the move to using cleanup macros at the same time as
> changing the implementation makes it unnecessarily hard to reason about
> this patch.
>
> This patch would be much better if split in two.
>

I disagree. If we have a better interface in place, then let's use it
right away, otherwise it's just useless churn.

> > As this is
> > largely a module separate from the SCM driver, let's use a separate
> > memory pool.
> >
>
> This module is effectively used to read and write EFI variables today.
> Is that worth statically removing 256kb of DDR for? Is this done solely
> because it logically makes sense, or did you choose this for a reason?
>

Well, it will stop working (with SHM bridge enabled) if we don't. We
can possibly release the pool once we know we'll no longer need to
access EFI variables but I'm not sure if that makes sense? Or maybe
remove the pool after some time of driver inactivity and create a new
one when it's needed again?

Bart

[snip]


From michael.riesch at wolfvision.net  Tue Feb 20 01:39:20 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue, 20 Feb 2024 10:39:20 +0100
Subject: [PATCH 10/14] media: rockchip: cif: add variant specific input
 format list
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-v6-8-topic-rk3568-vicap-v1-10-2680a1fa640b@wolfvision.net>

The different variants of the Rockchip CIF may feature different input
formats. Add a variant specific input format list to account for this.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 drivers/media/platform/rockchip/cif/cif-capture.c | 154 +---------------------
 drivers/media/platform/rockchip/cif/cif-common.h  |   2 +
 drivers/media/platform/rockchip/cif/cif-dev.c     | 147 +++++++++++++++++++++
 3 files changed, 154 insertions(+), 149 deletions(-)

diff --git a/drivers/media/platform/rockchip/cif/cif-capture.c b/drivers/media/platform/rockchip/cif/cif-capture.c
index c80a52028a21..b26e6023c2b0 100644
--- a/drivers/media/platform/rockchip/cif/cif-capture.c
+++ b/drivers/media/platform/rockchip/cif/cif-capture.c
@@ -109,154 +109,10 @@ static struct cif_output_fmt out_fmts[] = {
 	}
 };
 
-static const struct cif_input_fmt in_fmts[] = {
-	{
-		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
-		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
-				  CIF_FORMAT_YUV_INPUT_ORDER_YUYV,
-		.fmt_type	= CIF_FMT_TYPE_YUV,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
-		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
-				  CIF_FORMAT_YUV_INPUT_ORDER_YUYV,
-		.fmt_type	= CIF_FMT_TYPE_YUV,
-		.field		= V4L2_FIELD_INTERLACED,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_YVYU8_2X8,
-		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
-				  CIF_FORMAT_YUV_INPUT_ORDER_YVYU,
-		.fmt_type	= CIF_FMT_TYPE_YUV,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_YVYU8_2X8,
-		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
-				  CIF_FORMAT_YUV_INPUT_ORDER_YVYU,
-		.fmt_type	= CIF_FMT_TYPE_YUV,
-		.field		= V4L2_FIELD_INTERLACED,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
-		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
-				  CIF_FORMAT_YUV_INPUT_ORDER_UYVY,
-		.fmt_type	= CIF_FMT_TYPE_YUV,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
-		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
-				  CIF_FORMAT_YUV_INPUT_ORDER_UYVY,
-		.fmt_type	= CIF_FMT_TYPE_YUV,
-		.field		= V4L2_FIELD_INTERLACED,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_VYUY8_2X8,
-		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
-				  CIF_FORMAT_YUV_INPUT_ORDER_VYUY,
-		.fmt_type	= CIF_FMT_TYPE_YUV,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_VYUY8_2X8,
-		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
-				  CIF_FORMAT_YUV_INPUT_ORDER_VYUY,
-		.fmt_type	= CIF_FMT_TYPE_YUV,
-		.field		= V4L2_FIELD_INTERLACED,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_8,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SGBRG8_1X8,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_8,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SGRBG8_1X8,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_8,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SRGGB8_1X8,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_8,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SBGGR10_1X10,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_10,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SGBRG10_1X10,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_10,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SGRBG10_1X10,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_10,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SRGGB10_1X10,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_10,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SBGGR12_1X12,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_12,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SGBRG12_1X12,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_12,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SGRBG12_1X12,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_12,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_SRGGB12_1X12,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_12,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_RGB888_1X24,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_Y8_1X8,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_8,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_Y10_1X10,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_10,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}, {
-		.mbus_code	= MEDIA_BUS_FMT_Y12_1X12,
-		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
-				  CIF_FORMAT_RAW_DATA_WIDTH_12,
-		.fmt_type	= CIF_FMT_TYPE_RAW,
-		.field		= V4L2_FIELD_NONE,
-	}
-};
-
-static const struct
-cif_input_fmt *get_input_fmt(struct v4l2_subdev *sd)
+static const struct cif_input_fmt *get_input_fmt(struct cif_device *cif_dev,
+						 struct v4l2_subdev *sd)
 {
+	const struct cif_input_fmt *in_fmts = cif_dev->match_data->in_fmts;
 	struct v4l2_subdev_format fmt;
 	u32 i;
 
@@ -264,7 +120,7 @@ cif_input_fmt *get_input_fmt(struct v4l2_subdev *sd)
 	fmt.pad = 0;
 	v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
 
-	for (i = 0; i < ARRAY_SIZE(in_fmts); i++)
+	for (i = 0; i < cif_dev->match_data->in_fmts_num; i++)
 		if (fmt.format.code == in_fmts[i].mbus_code &&
 		    fmt.format.field == in_fmts[i].field)
 			return &in_fmts[i];
@@ -550,7 +406,7 @@ static int cif_start_streaming(struct vb2_queue *queue, unsigned int count)
 
 	sd = cif_dev->remote.sd;
 
-	stream->cif_fmt_in = get_input_fmt(cif_dev->remote.sd);
+	stream->cif_fmt_in = get_input_fmt(cif_dev, sd);
 	if (!stream->cif_fmt_in)
 		goto runtime_put;
 
diff --git a/drivers/media/platform/rockchip/cif/cif-common.h b/drivers/media/platform/rockchip/cif/cif-common.h
index ae8fedeadd1c..84a7545422e1 100644
--- a/drivers/media/platform/rockchip/cif/cif-common.h
+++ b/drivers/media/platform/rockchip/cif/cif-common.h
@@ -97,6 +97,8 @@ static inline struct cif_stream *to_cif_stream(struct video_device *vdev)
 struct cif_match_data {
 	struct clk_bulk_data *clks;
 	int clks_num;
+	const struct cif_input_fmt *in_fmts;
+	int in_fmts_num;
 	void (*grf_dvp_setup)(struct cif_device *cif_dev);
 };
 
diff --git a/drivers/media/platform/rockchip/cif/cif-dev.c b/drivers/media/platform/rockchip/cif/cif-dev.c
index b75b76508793..fb80e8f8dcab 100644
--- a/drivers/media/platform/rockchip/cif/cif-dev.c
+++ b/drivers/media/platform/rockchip/cif/cif-dev.c
@@ -132,9 +132,156 @@ static struct clk_bulk_data px30_cif_clks[] = {
 	{ .id = "pclk", },
 };
 
+static const struct cif_input_fmt px30_in_fmts[] = {
+	{
+		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YUYV,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YUYV,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_YVYU8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YVYU,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_YVYU8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_YVYU,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_UYVY,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_UYVY,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_VYUY8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_VYUY,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_VYUY8_2X8,
+		.dvp_fmt_val	= CIF_FORMAT_YUV_INPUT_422 |
+				  CIF_FORMAT_YUV_INPUT_ORDER_VYUY,
+		.fmt_type	= CIF_FMT_TYPE_YUV,
+		.field		= V4L2_FIELD_INTERLACED,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGBRG8_1X8,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGRBG8_1X8,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SRGGB8_1X8,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SBGGR10_1X10,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGBRG10_1X10,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGRBG10_1X10,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SRGGB10_1X10,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SBGGR12_1X12,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGBRG12_1X12,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGRBG12_1X12,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SRGGB12_1X12,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_RGB888_1X24,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_Y8_1X8,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_Y10_1X10,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_Y12_1X12,
+		.dvp_fmt_val	= CIF_FORMAT_INPUT_MODE_RAW |
+				  CIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type	= CIF_FMT_TYPE_RAW,
+		.field		= V4L2_FIELD_NONE,
+	}
+};
+
 static const struct cif_match_data px30_cif_match_data = {
 	.clks = px30_cif_clks,
 	.clks_num = ARRAY_SIZE(px30_cif_clks),
+	.in_fmts = px30_in_fmts,
+	.in_fmts_num = ARRAY_SIZE(px30_in_fmts),
 };
 
 static const struct of_device_id cif_plat_of_match[] = {

-- 
2.30.2



From catalin.marinas at arm.com  Tue Feb 20 01:56:00 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 20 Feb 2024 09:56:00 +0000
Subject: [PATCH v8 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240220072926.6466-5-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-5-ankita@nvidia.com>
Message-ID: <ZdR3MI_4pqV0EZcR@arm.com>

On Tue, Feb 20, 2024 at 12:59:26PM +0530, ankita at nvidia.com wrote:
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 1cbc990d42e0..c93bea18fc4b 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -1862,8 +1862,24 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
>  	/*
>  	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
>  	 * change vm_flags within the fault handler.  Set them now.
> +	 *
> +	 * VM_ALLOW_ANY_UNCACHED: The VMA flag is implemented for ARM64,
> +	 * allowing KVM stage 2 device mapping attributes to use Normal-NC
> +	 * rather than DEVICE_nGnRE, which allows guest mappings
> +	 * supporting combining attributes (WC). ARM does not

Nitpick: "supporting write-combining" (if you plan to respin).

-- 
Catalin


From miquel.raynal at bootlin.com  Tue Feb 20 01:56:34 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 20 Feb 2024 10:56:34 +0100
Subject: [PATCH v5 03/12] dt-bindings: mtd: brcmnand: Add ecc strap
 property
In-Reply-To: <20240207202257.271784-4-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
	<20240207202257.271784-4-william.zhang@broadcom.com>
Message-ID: <20240220105634.02b505b6@xps-13>

Hi William,

william.zhang at broadcom.com wrote on Wed,  7 Feb 2024 12:22:48 -0800:

> Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
> board boot strap for broadband board designs because they do not specify
> ecc setting in dts but rather using the strap setting.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> 
> ---
> 
> Changes in v5:
> - Update the description for this ecc strap property
> - Add check to make sure brcm,nand-ecc-use-strap and
>   nand-ecc-strength/brcm,nand-oob-sector-size can not be used at the
>   same time
> 
> Changes in v4:
> - Move ecc strap property to this separate patch and remove some
> non-binding related text from the description
> 
> Changes in v3: None
> Changes in v2: None
> 
>  .../bindings/mtd/brcm,brcmnand.yaml           | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> index 6a717bcedfd3..52a4c993b6f1 100644
> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
> @@ -146,6 +146,13 @@ patternProperties:
>            layout.
>          $ref: /schemas/types.yaml#/definitions/uint32
>  
> +      brcm,nand-ecc-use-strap:
> +        description:
> +          This property requires the host system to get the ECC strength
> +          and step size from the SoC NAND boot strap setting. This is a
> +          common hardware design on BCMBCA based boards.
> +        $ref: /schemas/types.yaml#/definitions/flag
> +
>      unevaluatedProperties: false
>  
>  allOf:
> @@ -195,6 +202,18 @@ allOf:
>        required:
>          - interrupt-names
>  
> +  - if:
> +      patternProperties:
> +        "^nand@[a-f0-9]$":
> +          required:
> +            - brcm,nand-ecc-use-strap
> +    then:
> +      patternProperties:
> +        "^nand@[a-f0-9]$":
> +          properties:
> +            nand-ecc-strength: false
> +            brcm,nand-oob-sector-size: false

Can you also excluse all the other nand-ecc- settings and brcm,
settings as well? Either you use the strap *or* you provide values in
the DT, but not both.

> +
>  unevaluatedProperties: false
>  
>  required:


Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Tue Feb 20 01:58:24 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 20 Feb 2024 10:58:24 +0100
Subject: [PATCH v5 09/12] mtd: rawnand: brcmnand: Add support for
 getting ecc setting from strap
In-Reply-To: <20240207202257.271784-10-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
	<20240207202257.271784-10-william.zhang@broadcom.com>
Message-ID: <20240220105824.76556c51@xps-13>

Hi William,

william.zhang at broadcom.com wrote on Wed,  7 Feb 2024 12:22:54 -0800:

> BCMBCA broadband SoC based board design does not specify ecc setting in
> dts but rather use the SoC NAND strap info to obtain the ecc strength
> and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
> this purpose and update driver to support this option.
> 
> The generic nand ecc settings still take precedence over this flag. For

And this sentence can also be dropped. Please mention they cannot be
used at the same time.

> example, if nand-ecc-strength is set in the dts, the driver ignores the
> strap setting and falls back to original behavior. This makes sure that
> the existing BCMBCA board dts still works the old way even the strap
> flag is set in the BCMBCA chip dtsi.

I think I already said this was a bad idea IMHO :-)

Thanks,
Miqu?l


From michal.simek at amd.com  Tue Feb 20 01:59:00 2024
From: michal.simek at amd.com (Michal Simek)
Date: Tue, 20 Feb 2024 10:59:00 +0100
Subject: [PATCH] char: xilinx_hwicap: Fix NULL vs IS_ERR() bug
In-Reply-To: <ef647a9c-b1b7-4338-9bc0-28165ec2a367@moroto.mountain>
References: <ef647a9c-b1b7-4338-9bc0-28165ec2a367@moroto.mountain>
Message-ID: <cc7f775b-188e-42f8-87dc-00fef1042d9b@amd.com>



On 2/20/24 10:02, Dan Carpenter wrote:
> The devm_platform_ioremap_resource() function returns error pointers.
> It never returns NULL.  Update the check accordingly.
> 
> Fixes: 672371832193 ("char: xilinx_hwicap: Modernize driver probe")
> Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>
> ---
>   drivers/char/xilinx_hwicap/xilinx_hwicap.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
> index 019cf6079cec..6d2eadefd9dc 100644
> --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
> +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
> @@ -639,8 +639,8 @@ static int hwicap_setup(struct platform_device *pdev, int id,
>   	dev_set_drvdata(dev, (void *)drvdata);
>   
>   	drvdata->base_address = devm_platform_ioremap_resource(pdev, 0);
> -	if (!drvdata->base_address) {
> -		retval = -ENODEV;
> +	if (IS_ERR(drvdata->base_address)) {
> +		retval = PTR_ERR(drvdata->base_address);
>   		goto failed;
>   	}
>   

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

Thanks,
Michal


From miquel.raynal at bootlin.com  Tue Feb 20 02:01:28 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 20 Feb 2024 11:01:28 +0100
Subject: [PATCH v5 11/12] mtd: rawnand: brcmnand: exec_op helper
 functions return type fixes
In-Reply-To: <20240207202257.271784-12-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
	<20240207202257.271784-12-william.zhang@broadcom.com>
Message-ID: <20240220110128.3cadbcc2@xps-13>

Hi,

william.zhang at broadcom.com wrote on Wed,  7 Feb 2024 12:22:56 -0800:

> From: David Regan <dregan at broadcom.com>
> 
> fix return type for exec_op reset and status detect helper functions

Please make a correct sentence (Fic, detect?, '.').

> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
> Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
> Signed-off-by: David Regan <dregan at broadcom.com>
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: William Zhang <william.zhang at broadcom.com>
> 
> ---
> 
> Changes in v5: None
> Changes in v4:
> - Fix the commit id in the fixes tag
> 
> Changes in v3: None
> Changes in v2:
> - Added to patch series
> 
>  drivers/mtd/nand/raw/brcmnand/brcmnand.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index 8c1489ff7bd6..7ce2b267676f 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -625,7 +625,7 @@ enum {
>  /* Only for v7.2 */
>  #define	ACC_CONTROL_ECC_EXT_SHIFT		13
>  
> -static u8 brcmnand_status(struct brcmnand_host *host);
> +static int brcmnand_status(struct brcmnand_host *host);
>  
>  static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
>  {
> @@ -1749,7 +1749,7 @@ static int brcmnand_waitfunc(struct nand_chip *chip)
>  				 INTFC_FLASH_STATUS;
>  }
>  
> -static u8 brcmnand_status(struct brcmnand_host *host)
> +static int brcmnand_status(struct brcmnand_host *host)
>  {
>  	struct nand_chip *chip = &host->chip;
>  	struct mtd_info *mtd = nand_to_mtd(chip);
> @@ -1760,7 +1760,7 @@ static u8 brcmnand_status(struct brcmnand_host *host)
>  	return brcmnand_waitfunc(chip);
>  }
>  
> -static u8 brcmnand_reset(struct brcmnand_host *host)
> +static int brcmnand_reset(struct brcmnand_host *host)
>  {
>  	struct nand_chip *chip = &host->chip;
>  
> @@ -2492,11 +2492,14 @@ static int brcmnand_exec_op(struct nand_chip *chip,
>  
>  	if (brcmnand_op_is_status(op)) {
>  		status = op->instrs[1].ctx.data.buf.in;
> -		*status = brcmnand_status(host);
> +		ret = brcmnand_status(host);
> +		if (ret < 0)
> +			return ret;
> +
> +		*status = ret & 0xFF;
>  
>  		return 0;
> -	}
> -	else if (brcmnand_op_is_reset(op)) {
> +	} else if (brcmnand_op_is_reset(op)) {

This is another change, please make it in another patch. Also while you
are at it, there are probably other checkpatch warnings that can be
fixed, if you want.

>  		ret = brcmnand_reset(host);
>  		if (ret < 0)
>  			return ret;


Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Tue Feb 20 02:02:40 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 20 Feb 2024 11:02:40 +0100
Subject: [PATCH v5 11/12] mtd: rawnand: brcmnand: exec_op helper
 functions return type fixes
In-Reply-To: <20240207202257.271784-12-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
	<20240207202257.271784-12-william.zhang@broadcom.com>
Message-ID: <20240220110240.1ad5b995@xps-13>


william.zhang at broadcom.com wrote on Wed,  7 Feb 2024 12:22:56 -0800:

> From: David Regan <dregan at broadcom.com>
> 
> fix return type for exec_op reset and status detect helper functions
> 
> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
> Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
> Signed-off-by: David Regan <dregan at broadcom.com>
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: William Zhang <william.zhang at broadcom.com>

By the way, a Cc: stable tag might be useful as otherwise you may leak
an error code in a status value (which is a bug). And move this patch
first in your series so we're sure it does not conflict with any of the
other patches and can be backported more easily.

Thanks,
Miqu?l


From alexander.stein at ew.tq-group.com  Tue Feb 20 02:06:54 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 20 Feb 2024 11:06:54 +0100
Subject: [PATCH v14 5/7] dt-bindings: phy: Add Freescale iMX8MQ DP and HDMI PHY
In-Reply-To: <8ddbb34b5f6bf2414bdb03f9e7cd9da70e4e7228.1708395604.git.Sandor.yu@nxp.com>
References: <cover.1708395604.git.Sandor.yu@nxp.com> <8ddbb34b5f6bf2414bdb03f9e7cd9da70e4e7228.1708395604.git.Sandor.yu@nxp.com>
Message-ID: <10421561.nUPlyArG6x@steina-w>

Hi,

thanks for the update.

Am Dienstag, 20. Februar 2024, 04:23:53 CET schrieb Sandor Yu:
> Add bindings for Freescale iMX8MQ DP and HDMI PHY.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> ---
> v9->v14:
>  *No change.
> 
>  .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  | 53 +++++++++++++++++++
>  1 file changed, 53 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
> new file mode 100644
> index 0000000000000..917f113503dca
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
> @@ -0,0 +1,53 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/fsl,imx8mq-dp-hdmi-phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Cadence HDP-TX DP/HDMI PHY for Freescale i.MX8MQ SoC
> +
> +maintainers:
> +  - Sandor Yu <sandor.yu at nxp.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - fsl,imx8mq-dp-phy
> +      - fsl,imx8mq-hdmi-phy

While reading cdns-mhdp8501-core.c I'm not so sure about this. There is
only a single PHY which can be configured for either DP or HDMI.
Using separate compatibles for that somehow bugs me.
Maybe the DT maintainers can add some input if this should be single
or double compatibles.

Thanks and best regards,
Alexander

> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: PHY reference clock.
> +      - description: APB clock.
> +
> +  clock-names:
> +    items:
> +      - const: ref
> +      - const: apb
> +
> +  "#phy-cells":
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - "#phy-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/imx8mq-clock.h>
> +    #include <dt-bindings/phy/phy.h>
> +    dp_phy: phy at 32c00000 {
> +        compatible = "fsl,imx8mq-dp-phy";
> +        reg = <0x32c00000 0x100000>;
> +        #phy-cells = <0>;
> +        clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
> +        clock-names = "ref", "apb";
> +    };
> 


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From lpieralisi at kernel.org  Tue Feb 20 02:08:17 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Tue, 20 Feb 2024 11:08:17 +0100
Subject: [PATCH v10 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <ZdR2FRQ9Fe8hhK9I@x1-carbon>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>
 <20240219161208.GE3281@thinkpad>
 <ZdN/OyNpw0Xa7qXG@lizhi-Precision-Tower-5810>
 <ZdR2FRQ9Fe8hhK9I@x1-carbon>
Message-ID: <ZdR6EUOv6hzLEmUa@lpieralisi>

On Tue, Feb 20, 2024 at 10:51:17AM +0100, Niklas Cassel wrote:
> On Mon, Feb 19, 2024 at 11:18:03AM -0500, Frank Li wrote:
> > On Mon, Feb 19, 2024 at 09:42:08PM +0530, Manivannan Sadhasivam wrote:
> > > On Mon, Feb 19, 2024 at 10:11:45AM -0500, Frank Li wrote:
> > > > On Mon, Feb 05, 2024 at 12:33:21PM -0500, Frank Li wrote:
> > > > > first 6 patches use drvdata: flags to simplify some switch-case code.
> > > > > Improve maintaince and easy to read code.
> > > > > 
> > > > 
> > > > @Lorenzo Pieralisi:
> > > > 
> > > > 	Do you have chance to look other patches?
> > > > 	Mani's apply EP side change. 
> > > 
> > > Even though the controller is for the endpoint, it is still a controller
> > > driver. So all the patches should go through Lorenzo.
> > > 
> > > I only merge patches under drivers/pci/endpoint. Hope this clarifies.
> > 
> > Sorry. It confused everyone. My means was that Mani applied Niklas Cassel's
> > patches, which cause my 14th patch build failure.
> 
> Hello Frank,
> 
> Patch 14, which adds this:
> 
> +static const struct pci_epc_features imx95_pcie_epc_features = {
> +       .msi_capable = true,
> +       .bar_fixed_size[1] = SZ_64K,
> +       .align = SZ_4K,
> +};
> 
> 
> Should, after rebasing on Mani's pci/endpoint branch, instead look like this:
> 
> +static const struct pci_epc_features imx95_pcie_epc_features = {
> +       .msi_capable = true,
> +       .bar[BAR_1] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
> +       .align = SZ_4K,
> +};
> 
> 
> > 
> > I asked if I need update my 14th patch or applied 1-13 only. 
> 
> I see, you want the maintainers to apply 1-13, and simply drop patch 14
> instead of you sending out a rebased series.
> 
> I assume that the maintainers will be fine with your suggested approach.

If patch 14 has no dependencies on 1-13 yes; if it does we need to
coordinate the merge between branches in the PCI tree.

Lorenzo


From fancer.lancer at gmail.com  Tue Feb 20 02:08:40 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Tue, 20 Feb 2024 13:08:40 +0300
Subject: [PATCH] net: stmmac: fix rx queue priority assignment
In-Reply-To: <20240219102405.32015-1-piotrwejman90@gmail.com>
References: <20240219102405.32015-1-piotrwejman90@gmail.com>
Message-ID: <nniukwj6oil7hbr2aefvlwicw362h7gotrudarozre35dk3ugm@wjsosr7p27li>

On Mon, Feb 19, 2024 at 11:24:05AM +0100, Piotr Wejman wrote:
> The driver should ensure that same priority is not mapped to multiple
> rx queues. Currently dwmac4_rx_queue_priority function is adding
> priorities for a queue without clearing them from others.
> 
> From DesignWare Cores Ethernet Quality-of-Service
> Databook, section 17.1.29 MAC_RxQ_Ctrl2:
> "[...]The software must ensure that the content of this field is
> mutually exclusive to the PSRQ fields for other queues, that is,
> the same priority is not mapped to multiple Rx queues[...]"
> 
> After this patch, dwmac4_rx_queue_priority function will:
> - assign desired priorities to a queue
> - remove those priorities from all other queues
> The write sequence of CTRL2 and CTRL3 registers is done in the way to
> ensure this order.
> 

Thanks for the fix. The change in general seems good. The same is
applicable for the DW XGMAC too. Could you please apply it to
dwxgmac2_rx_queue_prio()?

> Also, the PSRQn field contains the mask of priorities and not only one
> priority. Rename "prio" argument to "prio_mask".

Please move this to a separate patch applied on top of the main change
described above. Also in order to be done coherently the renaming
should be extended onto all the Tx/Rx queue prio parts in the
driver:
0. dwmac4_core.c
   +-> dwmac4_rx_queue_priority()
   +-> dwmac4_tx_queue_priority()
1. dwxgmac2_core.c
   +-> dwxgmac2_rx_queue_prio()
   +-> dwxgmac2_tx_queue_prio()
2. hwif.h
   +-> stmmac_ops::rx_queue_prio
   +-> stmmac_ops::tx_queue_prio
3. stmmac.h
   +-> stmmac_rxq_cfg::prio
   +-> stmmac_txq_cfg::prio
4. stmmac_main.c:
   +-> stmmac_mac_config_rx_queues_prio()::prio
   +-> stmmac_mac_config_tx_queues_prio()::prio

* Hope I listed all of them.

-Serge(y)

> 
> Signed-off-by: Piotr Wejman <piotrwejman90 at gmail.com>
> ---
>  .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 36 +++++++++++++------
>  1 file changed, 26 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> index 6b6d0de09619..6acc8bad794e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> @@ -89,22 +89,38 @@ static void dwmac4_rx_queue_enable(struct mac_device_info *hw,
>  }
>  
>  static void dwmac4_rx_queue_priority(struct mac_device_info *hw,
> -				     u32 prio, u32 queue)
> +				     u32 prio_mask, u32 queue)
>  {
>  	void __iomem *ioaddr = hw->pcsr;
> -	u32 base_register;
> -	u32 value;
> +	u32 clear_mask = 0;
> +	u32 ctrl2, ctrl3;
> +	int i;
>  
> -	base_register = (queue < 4) ? GMAC_RXQ_CTRL2 : GMAC_RXQ_CTRL3;
> -	if (queue >= 4)
> -		queue -= 4;
> +	ctrl2 = readl(ioaddr + GMAC_RXQ_CTRL2);
> +	ctrl3 = readl(ioaddr + GMAC_RXQ_CTRL3);
>  
> -	value = readl(ioaddr + base_register);
> +	for (i = 0; i < 4; i++)
> +		clear_mask |= ((prio_mask << GMAC_RXQCTRL_PSRQX_SHIFT(i)) &
> +						GMAC_RXQCTRL_PSRQX_MASK(i));
>  
> -	value &= ~GMAC_RXQCTRL_PSRQX_MASK(queue);
> -	value |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
> +	ctrl2 &= ~clear_mask;
> +	ctrl3 &= ~clear_mask;
> +
> +	if (queue < 4) {
> +		ctrl2 |= (prio_mask << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
>  						GMAC_RXQCTRL_PSRQX_MASK(queue);
> -	writel(value, ioaddr + base_register);
> +
> +		writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
> +		writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
> +	} else {
> +		queue -= 4;
> +
> +		ctrl3 |= (prio_mask << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
> +						GMAC_RXQCTRL_PSRQX_MASK(queue);
> +
> +		writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
> +		writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
> +	}
>  }
>  
>  static void dwmac4_tx_queue_priority(struct mac_device_info *hw,
> -- 
> 2.25.1
> 
> 


From tglx at linutronix.de  Tue Feb 20 02:09:47 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 20 Feb 2024 11:09:47 +0100
Subject: [PATCH v13 01/13] irqchip/sifive-plic: Convert PLIC driver into
 a platform driver
In-Reply-To: <20240220060718.823229-2-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-2-apatel@ventanamicro.com>
Message-ID: <87il2jih04.ffs@tglx>

On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> The PLIC driver does not require very early initialization so let
> us convert it into a platform driver.

s/let us convert/convert/

Please us passive voice and imperative mood all over the changelogs. No
we/us, let....

> As part of the conversion, the PLIC probing undergoes the following
> changes:
> 1. Use dev_info(), dev_err() and dev_warn() instead of pr_info(),
>    pr_err() and pr_warn()
> 2. Use devm_xyz() APIs wherever applicable
> 3. PLIC is now probed after CPUs are brought-up so we have to
>    setup cpuhp state after context handler of all online CPUs
>    are initialized otherwise we see crash on multi-socket systems

This patch is really doing too many things at once, which makes it hard
to review. Can you split this into digestable pieces please?

>  		if (unlikely(err))
> -			pr_warn_ratelimited("can't find mapping for hwirq %lu\n",
> +			dev_warn_ratelimited(handler->priv->dev,
> +					"can't find mapping for hwirq %lu\n",
>  					hwirq);

Nit. Please use brackets around the condition. See:

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#bracket-rules

for reasoning.

Thanks,

        tglx


From james.clark at arm.com  Tue Feb 20 02:09:10 2024
From: james.clark at arm.com (James Clark)
Date: Tue, 20 Feb 2024 10:09:10 +0000
Subject: [PATCH v5 0/7] kvm/coresight: Support exclude guest and exclude host
Message-ID: <20240220100924.2761706-1-james.clark@arm.com>

This is a combination of the RFC for nVHE here [1] and v3 of VHE version
here [2]. After a few of the review comments it seemed much simpler for
both versions to use the same interface and be in the same patchset.

FEAT_TRF is a Coresight feature that allows trace capture to be
completely filtered at different exception levels, unlike the existing
TRCVICTLR controls which may still emit target addresses of branches,
even if the following trace is filtered.

Without FEAT_TRF, it was possible to start a trace session on a host and
also collect trace from the guest as TRCVICTLR was never programmed to
exclude guests (and it could still emit target addresses even if it
was).

With FEAT_TRF, the current behavior of trace in guests exists depends on
whether nVHE or VHE are being used. Both of the examples below are from
the host's point of view, as Coresight isn't accessible from guests.
This patchset is only relevant to when FEAT_TRF exists, otherwise there
is no change.

  nVHE/pKVM:

  Because the host and the guest are both using TRFCR_EL1, trace will be
  generated in guests depending on the same filter rules the host is
  using. For example if the host is tracing userspace only, then guest
  userspace trace will also be collected.

  (This is further limited by whether TRBE is used because an issue
  with TRBE means that it's completely disabled in nVHE guests, but it's
  possible to have other tracing components.)

  VHE:

  With VHE, the host filters will be in TRFCR_EL2, but the filters in
  TRFCR_EL1 will be active when the guest is running. Because we don't
  write to TRFCR_EL1, guest trace will be completely disabled.

With this change, the guest filtering rules from the Perf session are
now honored for both nVHE and VHE modes. This is done by either writing
to TRFCR_EL12 at the start of the Perf session and doing nothing else
further, or caching the guest value and writing it at guest switch for
nVHE. In pKVM, trace is now be disabled for both protected and
unprotected guests.

---

Changes since V4 [3]:
  * Remove all V3 changes that made it work in pKVM and just disable
    trace there instead
  * Restore PMU host/hyp state sharing back to how it was
    (kvm_pmu_update_vcpu_events())
  * Simplify some of the duplication in the comments and function docs
  * Add a WARN_ON_ONCE() if kvm_etm_set_guest_trfcr() is called when
    the trace filtering feature doesn't exist.
  * Split sysreg change into a tools update followed by the new register
    addition

Changes since V3:
  * Create a new shared area to store the host state instead of copying
    it before each VCPU run
  * Drop commit that moved SPE and trace registers from host_debug_state
    into the kvm sysregs array because the guest values were never used 
  * Document kvm_etm_set_guest_trfcr()
  * Guard kvm_etm_set_guest_trfcr() with a feature check
  * Drop Mark B and Suzuki's review tags on the sysreg patch because it
    turned out that broke the Perf build and needed some unconventional
    changes to fix it (as in: to update the tools copy of the headers in
    the same commit as the kernel changes)

Changes since V2:

  * Add a new iflag to signify presence of FEAT_TRF and keep the
    existing TRBE iflag. This fixes the issue where TRBLIMITR_EL1 was
    being accessed even if TRBE didn't exist
  * Reword a commit message

Changes since V1:

  * Squashed all the arm64/tools/sysreg changes into the first commit
  * Add a new commit to move SPE and TRBE regs into the kvm sysreg array
  * Add a comment above the TRFCR global that it's per host CPU rather
    than vcpu

Changes since nVHE RFC [1]:

 * Re-write just in terms of the register value to be written for the
   host and the guest. This removes some logic from the hyp code and
   a value of kvm_vcpu_arch:trfcr_el1 = 0 no longer means "don't
   restore".
 * Remove all the conditional compilation and new files.
 * Change the kvm_etm_update_vcpu_events macro to a function.
 * Re-use DEBUG_STATE_SAVE_TRFCR so iflags don't need to be expanded
   anymore.
 * Expand the cover letter.

Changes since VHE v3 [2]:

 * Use the same interface as nVHE mode so TRFCR_EL12 is now written by
   kvm.

[1]: https://lore.kernel.org/kvmarm/20230804101317.460697-1-james.clark at arm.com/
[2]: https://lore.kernel.org/kvmarm/20230905102117.2011094-1-james.clark at arm.com/
[3]: https://lore.kernel.org/linux-arm-kernel/20240104162714.1062610-1-james.clark at arm.com/

James Clark (7):
  arm64: KVM: Fix renamed function in comment
  arm64/sysreg/tools: Update tools copy of sysreg.h
  arm64/sysreg/tools: Move TRFCR definitions to sysreg
  arm64: KVM: Add iflag for FEAT_TRF
  arm64: KVM: Add interface to set guest value for TRFCR register
  arm64: KVM: Write TRFCR value on guest switch with nVHE
  coresight: Pass guest TRFCR value to KVM

 arch/arm64/include/asm/kvm_host.h             |   7 +-
 arch/arm64/include/asm/sysreg.h               |  12 -
 arch/arm64/kernel/image-vars.h                |   1 +
 arch/arm64/kvm/debug.c                        |  50 ++-
 arch/arm64/kvm/hyp/nvhe/debug-sr.c            |  53 ++-
 arch/arm64/kvm/hyp/nvhe/setup.c               |   2 +-
 arch/arm64/tools/sysreg                       |  41 ++
 .../coresight/coresight-etm4x-core.c          |  42 +-
 drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
 drivers/hwtracing/coresight/coresight-priv.h  |   3 +
 tools/arch/arm64/include/asm/sysreg.h         | 375 +++++++++++++++++-
 tools/include/linux/kasan-tags.h              |  15 +
 12 files changed, 541 insertions(+), 62 deletions(-)
 create mode 100644 tools/include/linux/kasan-tags.h

-- 
2.34.1



From james.clark at arm.com  Tue Feb 20 02:09:11 2024
From: james.clark at arm.com (James Clark)
Date: Tue, 20 Feb 2024 10:09:11 +0000
Subject: [PATCH v5 1/7] arm64: KVM: Fix renamed function in comment
In-Reply-To: <20240220100924.2761706-1-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
Message-ID: <20240220100924.2761706-2-james.clark@arm.com>

finalize_host_mappings() became fix_host_ownership() in
commit 0d16d12eb26e ("KVM: arm64: Fix-up hyp stage-1 refcounts for all
pages mapped at EL2") so update the comment.

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/kvm/hyp/nvhe/setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index bc58d1b515af..11d77aa36173 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -131,7 +131,7 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 	 * can't be donated or shared with another entity.
 	 *
 	 * The ownership transition requires matching changes in the host
-	 * stage-2. This will be done later (see finalize_host_mappings()) once
+	 * stage-2. This will be done later (see fix_host_ownership()) once
 	 * the hyp_vmemmap is addressable.
 	 */
 	prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED);
-- 
2.34.1



From james.clark at arm.com  Tue Feb 20 02:09:12 2024
From: james.clark at arm.com (James Clark)
Date: Tue, 20 Feb 2024 10:09:12 +0000
Subject: [PATCH v5 2/7] arm64/sysreg/tools: Update tools copy of sysreg.h
In-Reply-To: <20240220100924.2761706-1-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
Message-ID: <20240220100924.2761706-3-james.clark@arm.com>

Created with the following:

  cp include/linux/kasan-tags.h tools/include/linux/
  cp arch/arm64/include/asm/sysreg.h tools/arch/arm64/include/asm/

Update the tools copy of sysreg.h so that the next commit to add a new
register doesn't have unrelated changes in it. Because the new version
of sysreg.h includes kasan-tags.h, that file also now needs to be copied
into tools.

Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/arch/arm64/include/asm/sysreg.h | 363 +++++++++++++++++++++++++-
 tools/include/linux/kasan-tags.h      |  15 ++
 2 files changed, 375 insertions(+), 3 deletions(-)
 create mode 100644 tools/include/linux/kasan-tags.h

diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index ccc13e991376..9e8999592f3a 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -11,6 +11,7 @@
 
 #include <linux/bits.h>
 #include <linux/stringify.h>
+#include <linux/kasan-tags.h>
 
 #include <asm/gpr-num.h>
 
@@ -123,6 +124,37 @@
 #define SYS_DC_CIGSW			sys_insn(1, 0, 7, 14, 4)
 #define SYS_DC_CIGDSW			sys_insn(1, 0, 7, 14, 6)
 
+#define SYS_IC_IALLUIS			sys_insn(1, 0, 7, 1, 0)
+#define SYS_IC_IALLU			sys_insn(1, 0, 7, 5, 0)
+#define SYS_IC_IVAU			sys_insn(1, 3, 7, 5, 1)
+
+#define SYS_DC_IVAC			sys_insn(1, 0, 7, 6, 1)
+#define SYS_DC_IGVAC			sys_insn(1, 0, 7, 6, 3)
+#define SYS_DC_IGDVAC			sys_insn(1, 0, 7, 6, 5)
+
+#define SYS_DC_CVAC			sys_insn(1, 3, 7, 10, 1)
+#define SYS_DC_CGVAC			sys_insn(1, 3, 7, 10, 3)
+#define SYS_DC_CGDVAC			sys_insn(1, 3, 7, 10, 5)
+
+#define SYS_DC_CVAU			sys_insn(1, 3, 7, 11, 1)
+
+#define SYS_DC_CVAP			sys_insn(1, 3, 7, 12, 1)
+#define SYS_DC_CGVAP			sys_insn(1, 3, 7, 12, 3)
+#define SYS_DC_CGDVAP			sys_insn(1, 3, 7, 12, 5)
+
+#define SYS_DC_CVADP			sys_insn(1, 3, 7, 13, 1)
+#define SYS_DC_CGVADP			sys_insn(1, 3, 7, 13, 3)
+#define SYS_DC_CGDVADP			sys_insn(1, 3, 7, 13, 5)
+
+#define SYS_DC_CIVAC			sys_insn(1, 3, 7, 14, 1)
+#define SYS_DC_CIGVAC			sys_insn(1, 3, 7, 14, 3)
+#define SYS_DC_CIGDVAC			sys_insn(1, 3, 7, 14, 5)
+
+/* Data cache zero operations */
+#define SYS_DC_ZVA			sys_insn(1, 3, 7, 4, 1)
+#define SYS_DC_GVA			sys_insn(1, 3, 7, 4, 3)
+#define SYS_DC_GZVA			sys_insn(1, 3, 7, 4, 4)
+
 /*
  * Automatically generated definitions for system registers, the
  * manual encodings below are in the process of being converted to
@@ -162,6 +194,84 @@
 #define SYS_DBGDTRTX_EL0		sys_reg(2, 3, 0, 5, 0)
 #define SYS_DBGVCR32_EL2		sys_reg(2, 4, 0, 7, 0)
 
+#define SYS_BRBINF_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 0))
+#define SYS_BRBINFINJ_EL1		sys_reg(2, 1, 9, 1, 0)
+#define SYS_BRBSRC_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 1))
+#define SYS_BRBSRCINJ_EL1		sys_reg(2, 1, 9, 1, 1)
+#define SYS_BRBTGT_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 2))
+#define SYS_BRBTGTINJ_EL1		sys_reg(2, 1, 9, 1, 2)
+#define SYS_BRBTS_EL1			sys_reg(2, 1, 9, 0, 2)
+
+#define SYS_BRBCR_EL1			sys_reg(2, 1, 9, 0, 0)
+#define SYS_BRBFCR_EL1			sys_reg(2, 1, 9, 0, 1)
+#define SYS_BRBIDR0_EL1			sys_reg(2, 1, 9, 2, 0)
+
+#define SYS_TRCITECR_EL1		sys_reg(3, 0, 1, 2, 3)
+#define SYS_TRCACATR(m)			sys_reg(2, 1, 2, ((m & 7) << 1), (2 | (m >> 3)))
+#define SYS_TRCACVR(m)			sys_reg(2, 1, 2, ((m & 7) << 1), (0 | (m >> 3)))
+#define SYS_TRCAUTHSTATUS		sys_reg(2, 1, 7, 14, 6)
+#define SYS_TRCAUXCTLR			sys_reg(2, 1, 0, 6, 0)
+#define SYS_TRCBBCTLR			sys_reg(2, 1, 0, 15, 0)
+#define SYS_TRCCCCTLR			sys_reg(2, 1, 0, 14, 0)
+#define SYS_TRCCIDCCTLR0		sys_reg(2, 1, 3, 0, 2)
+#define SYS_TRCCIDCCTLR1		sys_reg(2, 1, 3, 1, 2)
+#define SYS_TRCCIDCVR(m)		sys_reg(2, 1, 3, ((m & 7) << 1), 0)
+#define SYS_TRCCLAIMCLR			sys_reg(2, 1, 7, 9, 6)
+#define SYS_TRCCLAIMSET			sys_reg(2, 1, 7, 8, 6)
+#define SYS_TRCCNTCTLR(m)		sys_reg(2, 1, 0, (4 | (m & 3)), 5)
+#define SYS_TRCCNTRLDVR(m)		sys_reg(2, 1, 0, (0 | (m & 3)), 5)
+#define SYS_TRCCNTVR(m)			sys_reg(2, 1, 0, (8 | (m & 3)), 5)
+#define SYS_TRCCONFIGR			sys_reg(2, 1, 0, 4, 0)
+#define SYS_TRCDEVARCH			sys_reg(2, 1, 7, 15, 6)
+#define SYS_TRCDEVID			sys_reg(2, 1, 7, 2, 7)
+#define SYS_TRCEVENTCTL0R		sys_reg(2, 1, 0, 8, 0)
+#define SYS_TRCEVENTCTL1R		sys_reg(2, 1, 0, 9, 0)
+#define SYS_TRCEXTINSELR(m)		sys_reg(2, 1, 0, (8 | (m & 3)), 4)
+#define SYS_TRCIDR0			sys_reg(2, 1, 0, 8, 7)
+#define SYS_TRCIDR10			sys_reg(2, 1, 0, 2, 6)
+#define SYS_TRCIDR11			sys_reg(2, 1, 0, 3, 6)
+#define SYS_TRCIDR12			sys_reg(2, 1, 0, 4, 6)
+#define SYS_TRCIDR13			sys_reg(2, 1, 0, 5, 6)
+#define SYS_TRCIDR1			sys_reg(2, 1, 0, 9, 7)
+#define SYS_TRCIDR2			sys_reg(2, 1, 0, 10, 7)
+#define SYS_TRCIDR3			sys_reg(2, 1, 0, 11, 7)
+#define SYS_TRCIDR4			sys_reg(2, 1, 0, 12, 7)
+#define SYS_TRCIDR5			sys_reg(2, 1, 0, 13, 7)
+#define SYS_TRCIDR6			sys_reg(2, 1, 0, 14, 7)
+#define SYS_TRCIDR7			sys_reg(2, 1, 0, 15, 7)
+#define SYS_TRCIDR8			sys_reg(2, 1, 0, 0, 6)
+#define SYS_TRCIDR9			sys_reg(2, 1, 0, 1, 6)
+#define SYS_TRCIMSPEC(m)		sys_reg(2, 1, 0, (m & 7), 7)
+#define SYS_TRCITEEDCR			sys_reg(2, 1, 0, 2, 1)
+#define SYS_TRCOSLSR			sys_reg(2, 1, 1, 1, 4)
+#define SYS_TRCPRGCTLR			sys_reg(2, 1, 0, 1, 0)
+#define SYS_TRCQCTLR			sys_reg(2, 1, 0, 1, 1)
+#define SYS_TRCRSCTLR(m)		sys_reg(2, 1, 1, (m & 15), (0 | (m >> 4)))
+#define SYS_TRCRSR			sys_reg(2, 1, 0, 10, 0)
+#define SYS_TRCSEQEVR(m)		sys_reg(2, 1, 0, (m & 3), 4)
+#define SYS_TRCSEQRSTEVR		sys_reg(2, 1, 0, 6, 4)
+#define SYS_TRCSEQSTR			sys_reg(2, 1, 0, 7, 4)
+#define SYS_TRCSSCCR(m)			sys_reg(2, 1, 1, (m & 7), 2)
+#define SYS_TRCSSCSR(m)			sys_reg(2, 1, 1, (8 | (m & 7)), 2)
+#define SYS_TRCSSPCICR(m)		sys_reg(2, 1, 1, (m & 7), 3)
+#define SYS_TRCSTALLCTLR		sys_reg(2, 1, 0, 11, 0)
+#define SYS_TRCSTATR			sys_reg(2, 1, 0, 3, 0)
+#define SYS_TRCSYNCPR			sys_reg(2, 1, 0, 13, 0)
+#define SYS_TRCTRACEIDR			sys_reg(2, 1, 0, 0, 1)
+#define SYS_TRCTSCTLR			sys_reg(2, 1, 0, 12, 0)
+#define SYS_TRCVICTLR			sys_reg(2, 1, 0, 0, 2)
+#define SYS_TRCVIIECTLR			sys_reg(2, 1, 0, 1, 2)
+#define SYS_TRCVIPCSSCTLR		sys_reg(2, 1, 0, 3, 2)
+#define SYS_TRCVISSCTLR			sys_reg(2, 1, 0, 2, 2)
+#define SYS_TRCVMIDCCTLR0		sys_reg(2, 1, 3, 2, 2)
+#define SYS_TRCVMIDCCTLR1		sys_reg(2, 1, 3, 3, 2)
+#define SYS_TRCVMIDCVR(m)		sys_reg(2, 1, 3, ((m & 7) << 1), 1)
+
+/* ETM */
+#define SYS_TRCOSLAR			sys_reg(2, 1, 1, 0, 4)
+
+#define SYS_BRBCR_EL2			sys_reg(2, 4, 9, 0, 0)
+
 #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)
@@ -202,8 +312,13 @@
 #define SYS_ERXCTLR_EL1			sys_reg(3, 0, 5, 4, 1)
 #define SYS_ERXSTATUS_EL1		sys_reg(3, 0, 5, 4, 2)
 #define SYS_ERXADDR_EL1			sys_reg(3, 0, 5, 4, 3)
+#define SYS_ERXPFGF_EL1			sys_reg(3, 0, 5, 4, 4)
+#define SYS_ERXPFGCTL_EL1		sys_reg(3, 0, 5, 4, 5)
+#define SYS_ERXPFGCDN_EL1		sys_reg(3, 0, 5, 4, 6)
 #define SYS_ERXMISC0_EL1		sys_reg(3, 0, 5, 5, 0)
 #define SYS_ERXMISC1_EL1		sys_reg(3, 0, 5, 5, 1)
+#define SYS_ERXMISC2_EL1		sys_reg(3, 0, 5, 5, 2)
+#define SYS_ERXMISC3_EL1		sys_reg(3, 0, 5, 5, 3)
 #define SYS_TFSR_EL1			sys_reg(3, 0, 5, 6, 0)
 #define SYS_TFSRE0_EL1			sys_reg(3, 0, 5, 6, 1)
 
@@ -274,6 +389,8 @@
 #define SYS_ICC_IGRPEN0_EL1		sys_reg(3, 0, 12, 12, 6)
 #define SYS_ICC_IGRPEN1_EL1		sys_reg(3, 0, 12, 12, 7)
 
+#define SYS_ACCDATA_EL1			sys_reg(3, 0, 13, 0, 5)
+
 #define SYS_CNTKCTL_EL1			sys_reg(3, 0, 14, 1, 0)
 
 #define SYS_AIDR_EL1			sys_reg(3, 1, 0, 0, 7)
@@ -369,6 +486,7 @@
 
 #define SYS_SCTLR_EL2			sys_reg(3, 4, 1, 0, 0)
 #define SYS_ACTLR_EL2			sys_reg(3, 4, 1, 0, 1)
+#define SYS_SCTLR2_EL2			sys_reg(3, 4, 1, 0, 3)
 #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)
@@ -382,12 +500,15 @@
 #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
 
 #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
-#define SYS_HDFGRTR_EL2			sys_reg(3, 4, 3, 1, 4)
-#define SYS_HDFGWTR_EL2			sys_reg(3, 4, 3, 1, 5)
+#define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
 #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_SPSR_irq			sys_reg(3, 4, 4, 3, 0)
+#define SYS_SPSR_abt			sys_reg(3, 4, 4, 3, 1)
+#define SYS_SPSR_und			sys_reg(3, 4, 4, 3, 2)
+#define SYS_SPSR_fiq			sys_reg(3, 4, 4, 3, 3)
 #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)
@@ -401,6 +522,18 @@
 
 #define SYS_MAIR_EL2			sys_reg(3, 4, 10, 2, 0)
 #define SYS_AMAIR_EL2			sys_reg(3, 4, 10, 3, 0)
+#define SYS_MPAMHCR_EL2			sys_reg(3, 4, 10, 4, 0)
+#define SYS_MPAMVPMV_EL2		sys_reg(3, 4, 10, 4, 1)
+#define SYS_MPAM2_EL2			sys_reg(3, 4, 10, 5, 0)
+#define __SYS__MPAMVPMx_EL2(x)		sys_reg(3, 4, 10, 6, x)
+#define SYS_MPAMVPM0_EL2		__SYS__MPAMVPMx_EL2(0)
+#define SYS_MPAMVPM1_EL2		__SYS__MPAMVPMx_EL2(1)
+#define SYS_MPAMVPM2_EL2		__SYS__MPAMVPMx_EL2(2)
+#define SYS_MPAMVPM3_EL2		__SYS__MPAMVPMx_EL2(3)
+#define SYS_MPAMVPM4_EL2		__SYS__MPAMVPMx_EL2(4)
+#define SYS_MPAMVPM5_EL2		__SYS__MPAMVPMx_EL2(5)
+#define SYS_MPAMVPM6_EL2		__SYS__MPAMVPMx_EL2(6)
+#define SYS_MPAMVPM7_EL2		__SYS__MPAMVPMx_EL2(7)
 
 #define SYS_VBAR_EL2			sys_reg(3, 4, 12, 0, 0)
 #define SYS_RVBAR_EL2			sys_reg(3, 4, 12, 0, 1)
@@ -449,24 +582,49 @@
 
 #define SYS_CONTEXTIDR_EL2		sys_reg(3, 4, 13, 0, 1)
 #define SYS_TPIDR_EL2			sys_reg(3, 4, 13, 0, 2)
+#define SYS_SCXTNUM_EL2			sys_reg(3, 4, 13, 0, 7)
+
+#define __AMEV_op2(m)			(m & 0x7)
+#define __AMEV_CRm(n, m)		(n | ((m & 0x8) >> 3))
+#define __SYS__AMEVCNTVOFF0n_EL2(m)	sys_reg(3, 4, 13, __AMEV_CRm(0x8, m), __AMEV_op2(m))
+#define SYS_AMEVCNTVOFF0n_EL2(m)	__SYS__AMEVCNTVOFF0n_EL2(m)
+#define __SYS__AMEVCNTVOFF1n_EL2(m)	sys_reg(3, 4, 13, __AMEV_CRm(0xA, m), __AMEV_op2(m))
+#define SYS_AMEVCNTVOFF1n_EL2(m)	__SYS__AMEVCNTVOFF1n_EL2(m)
 
 #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_BRBCR_EL12			sys_reg(2, 5, 9, 0, 0)
 #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
+#define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
+#define SYS_SCTLR2_EL12			sys_reg(3, 5, 1, 0, 3)
+#define SYS_ZCR_EL12			sys_reg(3, 5, 1, 2, 0)
+#define SYS_TRFCR_EL12			sys_reg(3, 5, 1, 2, 1)
+#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)
+#define SYS_TCR2_EL12			sys_reg(3, 5, 2, 0, 3)
 #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)
 #define SYS_TFSR_EL12			sys_reg(3, 5, 5, 6, 0)
+#define SYS_FAR_EL12			sys_reg(3, 5, 6, 0, 0)
+#define SYS_PMSCR_EL12			sys_reg(3, 5, 9, 9, 0)
 #define SYS_MAIR_EL12			sys_reg(3, 5, 10, 2, 0)
 #define SYS_AMAIR_EL12			sys_reg(3, 5, 10, 3, 0)
 #define SYS_VBAR_EL12			sys_reg(3, 5, 12, 0, 0)
+#define SYS_CONTEXTIDR_EL12		sys_reg(3, 5, 13, 0, 1)
+#define SYS_SCXTNUM_EL12		sys_reg(3, 5, 13, 0, 7)
 #define SYS_CNTKCTL_EL12		sys_reg(3, 5, 14, 1, 0)
 #define SYS_CNTP_TVAL_EL02		sys_reg(3, 5, 14, 2, 0)
 #define SYS_CNTP_CTL_EL02		sys_reg(3, 5, 14, 2, 1)
@@ -477,6 +635,165 @@
 
 #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_S1E1A	sys_insn(AT_Op0, 0, AT_CRn, 9, 2)
+#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)
+
+/* TLBI instructions */
+#define OP_TLBI_VMALLE1OS		sys_insn(1, 0, 8, 1, 0)
+#define OP_TLBI_VAE1OS			sys_insn(1, 0, 8, 1, 1)
+#define OP_TLBI_ASIDE1OS		sys_insn(1, 0, 8, 1, 2)
+#define OP_TLBI_VAAE1OS			sys_insn(1, 0, 8, 1, 3)
+#define OP_TLBI_VALE1OS			sys_insn(1, 0, 8, 1, 5)
+#define OP_TLBI_VAALE1OS		sys_insn(1, 0, 8, 1, 7)
+#define OP_TLBI_RVAE1IS			sys_insn(1, 0, 8, 2, 1)
+#define OP_TLBI_RVAAE1IS		sys_insn(1, 0, 8, 2, 3)
+#define OP_TLBI_RVALE1IS		sys_insn(1, 0, 8, 2, 5)
+#define OP_TLBI_RVAALE1IS		sys_insn(1, 0, 8, 2, 7)
+#define OP_TLBI_VMALLE1IS		sys_insn(1, 0, 8, 3, 0)
+#define OP_TLBI_VAE1IS			sys_insn(1, 0, 8, 3, 1)
+#define OP_TLBI_ASIDE1IS		sys_insn(1, 0, 8, 3, 2)
+#define OP_TLBI_VAAE1IS			sys_insn(1, 0, 8, 3, 3)
+#define OP_TLBI_VALE1IS			sys_insn(1, 0, 8, 3, 5)
+#define OP_TLBI_VAALE1IS		sys_insn(1, 0, 8, 3, 7)
+#define OP_TLBI_RVAE1OS			sys_insn(1, 0, 8, 5, 1)
+#define OP_TLBI_RVAAE1OS		sys_insn(1, 0, 8, 5, 3)
+#define OP_TLBI_RVALE1OS		sys_insn(1, 0, 8, 5, 5)
+#define OP_TLBI_RVAALE1OS		sys_insn(1, 0, 8, 5, 7)
+#define OP_TLBI_RVAE1			sys_insn(1, 0, 8, 6, 1)
+#define OP_TLBI_RVAAE1			sys_insn(1, 0, 8, 6, 3)
+#define OP_TLBI_RVALE1			sys_insn(1, 0, 8, 6, 5)
+#define OP_TLBI_RVAALE1			sys_insn(1, 0, 8, 6, 7)
+#define OP_TLBI_VMALLE1			sys_insn(1, 0, 8, 7, 0)
+#define OP_TLBI_VAE1			sys_insn(1, 0, 8, 7, 1)
+#define OP_TLBI_ASIDE1			sys_insn(1, 0, 8, 7, 2)
+#define OP_TLBI_VAAE1			sys_insn(1, 0, 8, 7, 3)
+#define OP_TLBI_VALE1			sys_insn(1, 0, 8, 7, 5)
+#define OP_TLBI_VAALE1			sys_insn(1, 0, 8, 7, 7)
+#define OP_TLBI_VMALLE1OSNXS		sys_insn(1, 0, 9, 1, 0)
+#define OP_TLBI_VAE1OSNXS		sys_insn(1, 0, 9, 1, 1)
+#define OP_TLBI_ASIDE1OSNXS		sys_insn(1, 0, 9, 1, 2)
+#define OP_TLBI_VAAE1OSNXS		sys_insn(1, 0, 9, 1, 3)
+#define OP_TLBI_VALE1OSNXS		sys_insn(1, 0, 9, 1, 5)
+#define OP_TLBI_VAALE1OSNXS		sys_insn(1, 0, 9, 1, 7)
+#define OP_TLBI_RVAE1ISNXS		sys_insn(1, 0, 9, 2, 1)
+#define OP_TLBI_RVAAE1ISNXS		sys_insn(1, 0, 9, 2, 3)
+#define OP_TLBI_RVALE1ISNXS		sys_insn(1, 0, 9, 2, 5)
+#define OP_TLBI_RVAALE1ISNXS		sys_insn(1, 0, 9, 2, 7)
+#define OP_TLBI_VMALLE1ISNXS		sys_insn(1, 0, 9, 3, 0)
+#define OP_TLBI_VAE1ISNXS		sys_insn(1, 0, 9, 3, 1)
+#define OP_TLBI_ASIDE1ISNXS		sys_insn(1, 0, 9, 3, 2)
+#define OP_TLBI_VAAE1ISNXS		sys_insn(1, 0, 9, 3, 3)
+#define OP_TLBI_VALE1ISNXS		sys_insn(1, 0, 9, 3, 5)
+#define OP_TLBI_VAALE1ISNXS		sys_insn(1, 0, 9, 3, 7)
+#define OP_TLBI_RVAE1OSNXS		sys_insn(1, 0, 9, 5, 1)
+#define OP_TLBI_RVAAE1OSNXS		sys_insn(1, 0, 9, 5, 3)
+#define OP_TLBI_RVALE1OSNXS		sys_insn(1, 0, 9, 5, 5)
+#define OP_TLBI_RVAALE1OSNXS		sys_insn(1, 0, 9, 5, 7)
+#define OP_TLBI_RVAE1NXS		sys_insn(1, 0, 9, 6, 1)
+#define OP_TLBI_RVAAE1NXS		sys_insn(1, 0, 9, 6, 3)
+#define OP_TLBI_RVALE1NXS		sys_insn(1, 0, 9, 6, 5)
+#define OP_TLBI_RVAALE1NXS		sys_insn(1, 0, 9, 6, 7)
+#define OP_TLBI_VMALLE1NXS		sys_insn(1, 0, 9, 7, 0)
+#define OP_TLBI_VAE1NXS			sys_insn(1, 0, 9, 7, 1)
+#define OP_TLBI_ASIDE1NXS		sys_insn(1, 0, 9, 7, 2)
+#define OP_TLBI_VAAE1NXS		sys_insn(1, 0, 9, 7, 3)
+#define OP_TLBI_VALE1NXS		sys_insn(1, 0, 9, 7, 5)
+#define OP_TLBI_VAALE1NXS		sys_insn(1, 0, 9, 7, 7)
+#define OP_TLBI_IPAS2E1IS		sys_insn(1, 4, 8, 0, 1)
+#define OP_TLBI_RIPAS2E1IS		sys_insn(1, 4, 8, 0, 2)
+#define OP_TLBI_IPAS2LE1IS		sys_insn(1, 4, 8, 0, 5)
+#define OP_TLBI_RIPAS2LE1IS		sys_insn(1, 4, 8, 0, 6)
+#define OP_TLBI_ALLE2OS			sys_insn(1, 4, 8, 1, 0)
+#define OP_TLBI_VAE2OS			sys_insn(1, 4, 8, 1, 1)
+#define OP_TLBI_ALLE1OS			sys_insn(1, 4, 8, 1, 4)
+#define OP_TLBI_VALE2OS			sys_insn(1, 4, 8, 1, 5)
+#define OP_TLBI_VMALLS12E1OS		sys_insn(1, 4, 8, 1, 6)
+#define OP_TLBI_RVAE2IS			sys_insn(1, 4, 8, 2, 1)
+#define OP_TLBI_RVALE2IS		sys_insn(1, 4, 8, 2, 5)
+#define OP_TLBI_ALLE2IS			sys_insn(1, 4, 8, 3, 0)
+#define OP_TLBI_VAE2IS			sys_insn(1, 4, 8, 3, 1)
+#define OP_TLBI_ALLE1IS			sys_insn(1, 4, 8, 3, 4)
+#define OP_TLBI_VALE2IS			sys_insn(1, 4, 8, 3, 5)
+#define OP_TLBI_VMALLS12E1IS		sys_insn(1, 4, 8, 3, 6)
+#define OP_TLBI_IPAS2E1OS		sys_insn(1, 4, 8, 4, 0)
+#define OP_TLBI_IPAS2E1			sys_insn(1, 4, 8, 4, 1)
+#define OP_TLBI_RIPAS2E1		sys_insn(1, 4, 8, 4, 2)
+#define OP_TLBI_RIPAS2E1OS		sys_insn(1, 4, 8, 4, 3)
+#define OP_TLBI_IPAS2LE1OS		sys_insn(1, 4, 8, 4, 4)
+#define OP_TLBI_IPAS2LE1		sys_insn(1, 4, 8, 4, 5)
+#define OP_TLBI_RIPAS2LE1		sys_insn(1, 4, 8, 4, 6)
+#define OP_TLBI_RIPAS2LE1OS		sys_insn(1, 4, 8, 4, 7)
+#define OP_TLBI_RVAE2OS			sys_insn(1, 4, 8, 5, 1)
+#define OP_TLBI_RVALE2OS		sys_insn(1, 4, 8, 5, 5)
+#define OP_TLBI_RVAE2			sys_insn(1, 4, 8, 6, 1)
+#define OP_TLBI_RVALE2			sys_insn(1, 4, 8, 6, 5)
+#define OP_TLBI_ALLE2			sys_insn(1, 4, 8, 7, 0)
+#define OP_TLBI_VAE2			sys_insn(1, 4, 8, 7, 1)
+#define OP_TLBI_ALLE1			sys_insn(1, 4, 8, 7, 4)
+#define OP_TLBI_VALE2			sys_insn(1, 4, 8, 7, 5)
+#define OP_TLBI_VMALLS12E1		sys_insn(1, 4, 8, 7, 6)
+#define OP_TLBI_IPAS2E1ISNXS		sys_insn(1, 4, 9, 0, 1)
+#define OP_TLBI_RIPAS2E1ISNXS		sys_insn(1, 4, 9, 0, 2)
+#define OP_TLBI_IPAS2LE1ISNXS		sys_insn(1, 4, 9, 0, 5)
+#define OP_TLBI_RIPAS2LE1ISNXS		sys_insn(1, 4, 9, 0, 6)
+#define OP_TLBI_ALLE2OSNXS		sys_insn(1, 4, 9, 1, 0)
+#define OP_TLBI_VAE2OSNXS		sys_insn(1, 4, 9, 1, 1)
+#define OP_TLBI_ALLE1OSNXS		sys_insn(1, 4, 9, 1, 4)
+#define OP_TLBI_VALE2OSNXS		sys_insn(1, 4, 9, 1, 5)
+#define OP_TLBI_VMALLS12E1OSNXS		sys_insn(1, 4, 9, 1, 6)
+#define OP_TLBI_RVAE2ISNXS		sys_insn(1, 4, 9, 2, 1)
+#define OP_TLBI_RVALE2ISNXS		sys_insn(1, 4, 9, 2, 5)
+#define OP_TLBI_ALLE2ISNXS		sys_insn(1, 4, 9, 3, 0)
+#define OP_TLBI_VAE2ISNXS		sys_insn(1, 4, 9, 3, 1)
+#define OP_TLBI_ALLE1ISNXS		sys_insn(1, 4, 9, 3, 4)
+#define OP_TLBI_VALE2ISNXS		sys_insn(1, 4, 9, 3, 5)
+#define OP_TLBI_VMALLS12E1ISNXS		sys_insn(1, 4, 9, 3, 6)
+#define OP_TLBI_IPAS2E1OSNXS		sys_insn(1, 4, 9, 4, 0)
+#define OP_TLBI_IPAS2E1NXS		sys_insn(1, 4, 9, 4, 1)
+#define OP_TLBI_RIPAS2E1NXS		sys_insn(1, 4, 9, 4, 2)
+#define OP_TLBI_RIPAS2E1OSNXS		sys_insn(1, 4, 9, 4, 3)
+#define OP_TLBI_IPAS2LE1OSNXS		sys_insn(1, 4, 9, 4, 4)
+#define OP_TLBI_IPAS2LE1NXS		sys_insn(1, 4, 9, 4, 5)
+#define OP_TLBI_RIPAS2LE1NXS		sys_insn(1, 4, 9, 4, 6)
+#define OP_TLBI_RIPAS2LE1OSNXS		sys_insn(1, 4, 9, 4, 7)
+#define OP_TLBI_RVAE2OSNXS		sys_insn(1, 4, 9, 5, 1)
+#define OP_TLBI_RVALE2OSNXS		sys_insn(1, 4, 9, 5, 5)
+#define OP_TLBI_RVAE2NXS		sys_insn(1, 4, 9, 6, 1)
+#define OP_TLBI_RVALE2NXS		sys_insn(1, 4, 9, 6, 5)
+#define OP_TLBI_ALLE2NXS		sys_insn(1, 4, 9, 7, 0)
+#define OP_TLBI_VAE2NXS			sys_insn(1, 4, 9, 7, 1)
+#define OP_TLBI_ALLE1NXS		sys_insn(1, 4, 9, 7, 4)
+#define OP_TLBI_VALE2NXS		sys_insn(1, 4, 9, 7, 5)
+#define OP_TLBI_VMALLS12E1NXS		sys_insn(1, 4, 9, 7, 6)
+
+/* Misc instructions */
+#define OP_GCSPUSHX			sys_insn(1, 0, 7, 7, 4)
+#define OP_GCSPOPCX			sys_insn(1, 0, 7, 7, 5)
+#define OP_GCSPOPX			sys_insn(1, 0, 7, 7, 6)
+#define OP_GCSPUSHM			sys_insn(1, 3, 7, 7, 0)
+
+#define OP_BRB_IALL			sys_insn(1, 1, 7, 2, 4)
+#define OP_BRB_INJ			sys_insn(1, 1, 7, 2, 5)
+#define OP_CFP_RCTX			sys_insn(1, 3, 7, 3, 4)
+#define OP_DVP_RCTX			sys_insn(1, 3, 7, 3, 5)
+#define OP_COSP_RCTX			sys_insn(1, 3, 7, 3, 6)
+#define OP_CPP_RCTX			sys_insn(1, 3, 7, 3, 7)
+
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_ENTP2	(BIT(60))
 #define SCTLR_ELx_DSSBS	(BIT(44))
@@ -561,10 +878,12 @@
 
 /* id_aa64mmfr0 */
 #define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN	0x0
+#define ID_AA64MMFR0_EL1_TGRAN4_LPA2		ID_AA64MMFR0_EL1_TGRAN4_52_BIT
 #define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MAX	0x7
 #define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED_MIN	0x0
 #define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED_MAX	0x7
 #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MIN	0x1
+#define ID_AA64MMFR0_EL1_TGRAN16_LPA2		ID_AA64MMFR0_EL1_TGRAN16_52_BIT
 #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MAX	0xf
 
 #define ARM64_MIN_PARANGE_BITS		32
@@ -572,6 +891,7 @@
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_DEFAULT	0x0
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_NONE		0x1
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MIN		0x2
+#define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2		0x3
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX		0x7
 
 #ifdef CONFIG_ARM64_PA_BITS_52
@@ -582,11 +902,13 @@
 
 #if defined(CONFIG_ARM64_4K_PAGES)
 #define ID_AA64MMFR0_EL1_TGRAN_SHIFT		ID_AA64MMFR0_EL1_TGRAN4_SHIFT
+#define ID_AA64MMFR0_EL1_TGRAN_LPA2		ID_AA64MMFR0_EL1_TGRAN4_52_BIT
 #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN
 #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX	ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MAX
 #define ID_AA64MMFR0_EL1_TGRAN_2_SHIFT		ID_AA64MMFR0_EL1_TGRAN4_2_SHIFT
 #elif defined(CONFIG_ARM64_16K_PAGES)
 #define ID_AA64MMFR0_EL1_TGRAN_SHIFT		ID_AA64MMFR0_EL1_TGRAN16_SHIFT
+#define ID_AA64MMFR0_EL1_TGRAN_LPA2		ID_AA64MMFR0_EL1_TGRAN16_52_BIT
 #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MIN
 #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX	ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MAX
 #define ID_AA64MMFR0_EL1_TGRAN_2_SHIFT		ID_AA64MMFR0_EL1_TGRAN16_2_SHIFT
@@ -610,6 +932,19 @@
 #define SYS_GCR_EL1_RRND	(BIT(16))
 #define SYS_GCR_EL1_EXCL_MASK	0xffffUL
 
+#ifdef CONFIG_KASAN_HW_TAGS
+/*
+ * KASAN always uses a whole byte for its tags. With CONFIG_KASAN_HW_TAGS it
+ * only uses tags in the range 0xF0-0xFF, which we map to MTE tags 0x0-0xF.
+ */
+#define __MTE_TAG_MIN		(KASAN_TAG_MIN & 0xf)
+#define __MTE_TAG_MAX		(KASAN_TAG_MAX & 0xf)
+#define __MTE_TAG_INCL		GENMASK(__MTE_TAG_MAX, __MTE_TAG_MIN)
+#define KERNEL_GCR_EL1_EXCL	(SYS_GCR_EL1_EXCL_MASK & ~__MTE_TAG_INCL)
+#else
+#define KERNEL_GCR_EL1_EXCL	SYS_GCR_EL1_EXCL_MASK
+#endif
+
 #define KERNEL_GCR_EL1		(SYS_GCR_EL1_RRND | KERNEL_GCR_EL1_EXCL)
 
 /* RGSR_EL1 Definitions */
@@ -716,6 +1051,19 @@
 
 #define PIRx_ELx_PERM(idx, perm)	((perm) << ((idx) * 4))
 
+/*
+ * Permission Overlay Extension (POE) permission encodings.
+ */
+#define POE_NONE	UL(0x0)
+#define POE_R		UL(0x1)
+#define POE_X		UL(0x2)
+#define POE_RX		UL(0x3)
+#define POE_W		UL(0x4)
+#define POE_RW		UL(0x5)
+#define POE_XW		UL(0x6)
+#define POE_RXW		UL(0x7)
+#define POE_MASK	UL(0xf)
+
 #define ARM64_FEATURE_FIELD_BITS	4
 
 /* Defined for compatibility only, do not add new users. */
@@ -789,15 +1137,21 @@
 /*
  * For registers without architectural names, or simply unsupported by
  * GAS.
+ *
+ * __check_r forces warnings to be generated by the compiler when
+ * evaluating r which wouldn't normally happen due to being passed to
+ * the assembler via __stringify(r).
  */
 #define read_sysreg_s(r) ({						\
 	u64 __val;							\
+	u32 __maybe_unused __check_r = (u32)(r);			\
 	asm volatile(__mrs_s("%0", r) : "=r" (__val));			\
 	__val;								\
 })
 
 #define write_sysreg_s(v, r) do {					\
 	u64 __val = (u64)(v);						\
+	u32 __maybe_unused __check_r = (u32)(r);			\
 	asm volatile(__msr_s(r, "%x0") : : "rZ" (__val));		\
 } while (0)
 
@@ -827,6 +1181,8 @@
 	par;								\
 })
 
+#define SYS_FIELD_VALUE(reg, field, val)	reg##_##field##_##val
+
 #define SYS_FIELD_GET(reg, field, val)		\
 		 FIELD_GET(reg##_##field##_MASK, val)
 
@@ -834,7 +1190,8 @@
 		 FIELD_PREP(reg##_##field##_MASK, val)
 
 #define SYS_FIELD_PREP_ENUM(reg, field, val)		\
-		 FIELD_PREP(reg##_##field##_MASK, reg##_##field##_##val)
+		 FIELD_PREP(reg##_##field##_MASK,	\
+			    SYS_FIELD_VALUE(reg, field, val))
 
 #endif
 
diff --git a/tools/include/linux/kasan-tags.h b/tools/include/linux/kasan-tags.h
new file mode 100644
index 000000000000..4f85f562512c
--- /dev/null
+++ b/tools/include/linux/kasan-tags.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_KASAN_TAGS_H
+#define _LINUX_KASAN_TAGS_H
+
+#define KASAN_TAG_KERNEL	0xFF /* native kernel pointers tag */
+#define KASAN_TAG_INVALID	0xFE /* inaccessible memory tag */
+#define KASAN_TAG_MAX		0xFD /* maximum value for random tags */
+
+#ifdef CONFIG_KASAN_HW_TAGS
+#define KASAN_TAG_MIN		0xF0 /* minimum value for random tags */
+#else
+#define KASAN_TAG_MIN		0x00 /* minimum value for random tags */
+#endif
+
+#endif /* LINUX_KASAN_TAGS_H */
-- 
2.34.1



From james.clark at arm.com  Tue Feb 20 02:09:13 2024
From: james.clark at arm.com (James Clark)
Date: Tue, 20 Feb 2024 10:09:13 +0000
Subject: [PATCH v5 3/7] arm64/sysreg/tools: Move TRFCR definitions to sysreg
In-Reply-To: <20240220100924.2761706-1-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
Message-ID: <20240220100924.2761706-4-james.clark@arm.com>

Add separate definitions for ELx and EL2 as TRFCR_EL1 doesn't have CX.
This also mirrors the previous definition so no code change is required.

Also add TRFCR_EL12 which will start to be used in a later commit.

Unfortunately, to avoid breaking the Perf build with duplicate
definition errors, the tools copy of the sysreg.h header needs to be
updated at the same time rather than the usual second commit. This is
because the generated version of sysreg
(arch/arm64/include/generated/asm/sysreg-defs.h), is currently shared
and tools/ does not have its own copy.

Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/include/asm/sysreg.h       | 12 --------
 arch/arm64/tools/sysreg               | 41 +++++++++++++++++++++++++++
 tools/arch/arm64/include/asm/sysreg.h | 12 --------
 3 files changed, 41 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 9e8999592f3a..35890cf3c49f 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -280,8 +280,6 @@
 #define SYS_RGSR_EL1			sys_reg(3, 0, 1, 0, 5)
 #define SYS_GCR_EL1			sys_reg(3, 0, 1, 0, 6)
 
-#define SYS_TRFCR_EL1			sys_reg(3, 0, 1, 2, 1)
-
 #define SYS_TCR_EL1			sys_reg(3, 0, 2, 0, 2)
 
 #define SYS_APIAKEYLO_EL1		sys_reg(3, 0, 2, 1, 0)
@@ -499,7 +497,6 @@
 #define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
 #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
 
-#define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
 #define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
 #define SYS_HAFGRTR_EL2			sys_reg(3, 4, 3, 1, 6)
 #define SYS_SPSR_EL2			sys_reg(3, 4, 4, 0, 0)
@@ -961,15 +958,6 @@
 /* Safe value for MPIDR_EL1: Bit31:RES1, Bit30:U:0, Bit24:MT:0 */
 #define SYS_MPIDR_SAFE_VAL	(BIT(31))
 
-#define TRFCR_ELx_TS_SHIFT		5
-#define TRFCR_ELx_TS_MASK		((0x3UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_VIRTUAL		((0x1UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_GUEST_PHYSICAL	((0x2UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_PHYSICAL		((0x3UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_EL2_CX			BIT(3)
-#define TRFCR_ELx_ExTRE			BIT(1)
-#define TRFCR_ELx_E0TRE			BIT(0)
-
 /* GIC Hypervisor interface registers */
 /* ICH_MISR_EL2 bit definitions */
 #define ICH_MISR_EOI		(1 << 0)
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index fa3fe0856880..c4a6b77d2756 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2970,3 +2970,44 @@ Field	5	F
 Field	4	P
 Field	3:0	Align
 EndSysreg
+
+SysregFields TRFCR_EL2
+Res0	63:7
+UnsignedEnum	6:5	TS
+	0b0000	USE_TRFCR_EL1_TS
+	0b0001	VIRTUAL
+	0b0010	GUEST_PHYSICAL
+	0b0011	PHYSICAL
+EndEnum
+Res0	4
+Field	3	CX
+Res0	2
+Field	1	E2TRE
+Field	0	E0HTRE
+EndSysregFields
+
+# TRFCR_EL1 doesn't have the CX bit so redefine it without CX instead of
+# using a shared definition between TRFCR_EL2 and TRFCR_EL1
+SysregFields TRFCR_ELx
+Res0	63:7
+UnsignedEnum	6:5	TS
+	0b0001	VIRTUAL
+	0b0010	GUEST_PHYSICAL
+	0b0011	PHYSICAL
+EndEnum
+Res0	4:2
+Field	1	ExTRE
+Field	0	E0TRE
+EndSysregFields
+
+Sysreg	TRFCR_EL1	3	0	1	2	1
+Fields	TRFCR_ELx
+EndSysreg
+
+Sysreg	TRFCR_EL2	3	4	1	2	1
+Fields	TRFCR_EL2
+EndSysreg
+
+Sysreg	TRFCR_EL12	3	5	1	2	1
+Fields	TRFCR_ELx
+EndSysreg
diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index 9e8999592f3a..35890cf3c49f 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -280,8 +280,6 @@
 #define SYS_RGSR_EL1			sys_reg(3, 0, 1, 0, 5)
 #define SYS_GCR_EL1			sys_reg(3, 0, 1, 0, 6)
 
-#define SYS_TRFCR_EL1			sys_reg(3, 0, 1, 2, 1)
-
 #define SYS_TCR_EL1			sys_reg(3, 0, 2, 0, 2)
 
 #define SYS_APIAKEYLO_EL1		sys_reg(3, 0, 2, 1, 0)
@@ -499,7 +497,6 @@
 #define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
 #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
 
-#define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
 #define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
 #define SYS_HAFGRTR_EL2			sys_reg(3, 4, 3, 1, 6)
 #define SYS_SPSR_EL2			sys_reg(3, 4, 4, 0, 0)
@@ -961,15 +958,6 @@
 /* Safe value for MPIDR_EL1: Bit31:RES1, Bit30:U:0, Bit24:MT:0 */
 #define SYS_MPIDR_SAFE_VAL	(BIT(31))
 
-#define TRFCR_ELx_TS_SHIFT		5
-#define TRFCR_ELx_TS_MASK		((0x3UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_VIRTUAL		((0x1UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_GUEST_PHYSICAL	((0x2UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_PHYSICAL		((0x3UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_EL2_CX			BIT(3)
-#define TRFCR_ELx_ExTRE			BIT(1)
-#define TRFCR_ELx_E0TRE			BIT(0)
-
 /* GIC Hypervisor interface registers */
 /* ICH_MISR_EL2 bit definitions */
 #define ICH_MISR_EOI		(1 << 0)
-- 
2.34.1



From james.clark at arm.com  Tue Feb 20 02:09:14 2024
From: james.clark at arm.com (James Clark)
Date: Tue, 20 Feb 2024 10:09:14 +0000
Subject: [PATCH v5 4/7] arm64: KVM: Add iflag for FEAT_TRF
In-Reply-To: <20240220100924.2761706-1-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
Message-ID: <20240220100924.2761706-5-james.clark@arm.com>

Add an extra iflag to signify if the TRFCR register is accessible.
Because TRBE requires FEAT_TRF, DEBUG_STATE_SAVE_TRBE still has the same
behavior even though it's only set when FEAT_TRF is present.

The following holes are left in struct kvm_vcpu_arch, but there aren't
enough other 8 bit fields to rearrange it to leave any hole smaller than
7 bytes:

  u8                         cflags;               /*  2292     1 */
  /* XXX 1 byte hole, try to pack */
  u16                        iflags;               /*  2294     2 */
  u8                         sflags;               /*  2296     1 */
  bool                       pause;                /*  2297     1 */
  /* XXX 6 bytes hole, try to pack */

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  4 +++-
 arch/arm64/kvm/debug.c            | 24 ++++++++++++++++++++----
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 21c57b812569..85b5477bd1b4 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -569,7 +569,7 @@ struct kvm_vcpu_arch {
 	u8 cflags;
 
 	/* Input flags to the hypervisor code, potentially cleared after use */
-	u8 iflags;
+	u16 iflags;
 
 	/* State flags for kernel bookkeeping, unused by the hypervisor code */
 	u8 sflags;
@@ -779,6 +779,8 @@ struct kvm_vcpu_arch {
 #define DEBUG_STATE_SAVE_TRBE	__vcpu_single_flag(iflags, BIT(6))
 /* vcpu running in HYP context */
 #define VCPU_HYP_CONTEXT	__vcpu_single_flag(iflags, BIT(7))
+/* Save trace filter controls */
+#define DEBUG_STATE_SAVE_TRFCR	__vcpu_single_flag(iflags, BIT(8))
 
 /* SVE enabled for host EL0 */
 #define HOST_SVE_ENABLED	__vcpu_single_flag(sflags, BIT(0))
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index ce8886122ed3..49a13e72ddd2 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -332,14 +332,30 @@ void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu)
 	    !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(PMBIDR_EL1_P_SHIFT)))
 		vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_SPE);
 
-	/* Check if we have TRBE implemented and available at the host */
-	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) &&
-	    !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P))
-		vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
+	/*
+	 * Set SAVE_TRFCR flag if FEAT_TRF (TraceFilt) exists. This flag
+	 * signifies that the exclude_host/exclude_guest settings of any active
+	 * host Perf session on a core running a VCPU can be written into
+	 * TRFCR_EL1 on guest switch.
+	 */
+	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceFilt_SHIFT)) {
+		vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
+		/*
+		 * Check if we have TRBE implemented and available at the host.
+		 * If it's in use at the time of guest switch then trace will
+		 * need to be completely disabled. The architecture mandates
+		 * FEAT_TRF with TRBE, so we only need to check for TRBE after
+		 * TRF.
+		 */
+		if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) &&
+		    !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P))
+			vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
+	}
 }
 
 void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
 {
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
+	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
 }
-- 
2.34.1



From james.clark at arm.com  Tue Feb 20 02:09:15 2024
From: james.clark at arm.com (James Clark)
Date: Tue, 20 Feb 2024 10:09:15 +0000
Subject: [PATCH v5 5/7] arm64: KVM: Add interface to set guest value for TRFCR register
In-Reply-To: <20240220100924.2761706-1-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
Message-ID: <20240220100924.2761706-6-james.clark@arm.com>

Add an interface for the Coresight driver to use to set the value of the
TRFCR register for the guest. This register controls the exclude
settings for trace at different exception levels, and is used to honor
the exclude_host and exclude_guest parameters from the Perf session.
This will be used to later write TRFCR_EL1 on nVHE at guest switch. For
VHE, the host trace is controlled by TRFCR_EL2 and thus we can write to
the TRFCR_EL1 immediately. Because guest writes to the register are
trapped, the value will persist and can't be modified.

Instead of adding a load of infrastructure to share the host's per-cpu
offsets with the hypervisor, just define the new storage as a NR_CPUS
array.

Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  3 +++
 arch/arm64/kernel/image-vars.h    |  1 +
 arch/arm64/kvm/debug.c            | 26 ++++++++++++++++++++++++++
 3 files changed, 30 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 85b5477bd1b4..56b7f7eca195 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -509,6 +509,7 @@ struct kvm_host_psci_config {
 	bool psci_0_1_cpu_off_implemented;
 	bool psci_0_1_migrate_implemented;
 };
+extern u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
 
 extern struct kvm_host_psci_config kvm_nvhe_sym(kvm_host_psci_config);
 #define kvm_host_psci_config CHOOSE_NVHE_SYM(kvm_host_psci_config)
@@ -1174,6 +1175,7 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu);
 void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr);
 void kvm_clr_pmu_events(u32 clr);
 bool kvm_set_pmuserenr(u64 val);
+void kvm_etm_set_guest_trfcr(u64 trfcr_guest);
 #else
 static inline void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) {}
 static inline void kvm_clr_pmu_events(u32 clr) {}
@@ -1181,6 +1183,7 @@ static inline bool kvm_set_pmuserenr(u64 val)
 {
 	return false;
 }
+static inline void kvm_etm_set_guest_trfcr(u64 trfcr_guest) {}
 #endif
 
 void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 5e4dc72ab1bd..a451e4f10804 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -59,6 +59,7 @@ KVM_NVHE_ALIAS(alt_cb_patch_nops);
 
 /* Global kernel state accessed by nVHE hyp code. */
 KVM_NVHE_ALIAS(kvm_vgic_global_state);
+KVM_NVHE_ALIAS(kvm_guest_trfcr);
 
 /* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */
 KVM_NVHE_ALIAS(nvhe_hyp_panic_handler);
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 49a13e72ddd2..c8d936ce6e2b 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -22,6 +22,7 @@
 				DBG_MDSCR_MDE)
 
 static DEFINE_PER_CPU(u64, mdcr_el2);
+u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
 
 /*
  * save/restore_guest_debug_regs
@@ -359,3 +360,28 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
 }
+
+/*
+ * Interface for the Coresight driver to use to set the value of the TRFCR
+ * register for the guest. This register controls the exclude settings for trace
+ * at different exception levels, and is used to honor the exclude_host and
+ * exclude_guest parameters from the Perf session.
+ *
+ * This will be used to later write TRFCR_EL1 on nVHE at guest switch. For VHE,
+ * the host trace is controlled by TRFCR_EL2 and thus we can write to the
+ * TRFCR_EL1 immediately. Because guest writes to the register are trapped, the
+ * value will persist and can't be modified. For pKVM, kvm_guest_trfcr can't
+ * be read by the hypervisor, so don't bother writing it.
+ */
+void kvm_etm_set_guest_trfcr(u64 trfcr_guest)
+{
+	if (WARN_ON_ONCE(!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
+							       ID_AA64DFR0_EL1_TraceFilt_SHIFT)))
+		return;
+
+	if (has_vhe())
+		write_sysreg_s(trfcr_guest, SYS_TRFCR_EL12);
+	else if (!is_protected_kvm_enabled())
+		kvm_guest_trfcr[smp_processor_id()] = trfcr_guest;
+}
+EXPORT_SYMBOL_GPL(kvm_etm_set_guest_trfcr);
-- 
2.34.1



From james.clark at arm.com  Tue Feb 20 02:09:16 2024
From: james.clark at arm.com (James Clark)
Date: Tue, 20 Feb 2024 10:09:16 +0000
Subject: [PATCH v5 6/7] arm64: KVM: Write TRFCR value on guest switch with nVHE
In-Reply-To: <20240220100924.2761706-1-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
Message-ID: <20240220100924.2761706-7-james.clark@arm.com>

The guest value for TRFCR requested by the Coresight driver is saved in
kvm_guest_trfcr. On guest switch this value needs to be written to
the register. Currently TRFCR is only modified when we want to disable
trace completely in guests due to an issue with TRBE. Expand the
__debug_save_trace() function to always write to the register if a
different value for guests is required, but also keep the existing TRBE
disable behavior if that's required.

In pKVM, the kvm_guest_trfcr can't be read and the host isn't trusted,
so always disable trace.

__debug_restore_trace() now has to restore unconditionally, because even
a value of 0 needs to be written to overwrite whatever was set for the
guest.

Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/kvm/hyp/nvhe/debug-sr.c | 53 +++++++++++++++++-------------
 1 file changed, 31 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 4558c02eb352..3adac2e01908 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -51,30 +51,39 @@ static void __debug_restore_spe(u64 pmscr_el1)
 	write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
 }
 
-static void __debug_save_trace(u64 *trfcr_el1)
+static void __debug_save_trace(struct kvm_vcpu *vcpu)
 {
-	*trfcr_el1 = 0;
-
-	/* Check if the TRBE is enabled */
-	if (!(read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E))
-		return;
-	/*
-	 * Prohibit trace generation while we are in guest.
-	 * Since access to TRFCR_EL1 is trapped, the guest can't
-	 * modify the filtering set by the host.
-	 */
-	*trfcr_el1 = read_sysreg_s(SYS_TRFCR_EL1);
-	write_sysreg_s(0, SYS_TRFCR_EL1);
-	isb();
-	/* Drain the trace buffer to memory */
-	tsb_csync();
+	u64 host_trfcr_el1 = read_sysreg_s(SYS_TRFCR_EL1);
+	u64 guest_trfcr_el1;
+
+	vcpu->arch.host_debug_state.trfcr_el1 = host_trfcr_el1;
+
+	/* Check if the TRBE buffer or pKVM is enabled */
+	if (is_protected_kvm_enabled() ||
+	    (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE) &&
+	     read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E)) {
+		/*
+		 * Prohibit trace generation while we are in guest. Since access
+		 * to TRFCR_EL1 is trapped, the guest can't modify the filtering
+		 * set by the host.
+		 */
+		write_sysreg_s(0, SYS_TRFCR_EL1);
+		isb();
+		/* Drain the trace buffer to memory */
+		tsb_csync();
+	} else {
+		/*
+		 * Tracing is allowed, apply the filters provided by the
+		 * Coresight driver.
+		 */
+		guest_trfcr_el1 = kvm_guest_trfcr[vcpu->cpu];
+		if (host_trfcr_el1 != guest_trfcr_el1)
+			write_sysreg_s(guest_trfcr_el1, SYS_TRFCR_EL1);
+	}
 }
 
 static void __debug_restore_trace(u64 trfcr_el1)
 {
-	if (!trfcr_el1)
-		return;
-
 	/* Restore trace filter controls */
 	write_sysreg_s(trfcr_el1, SYS_TRFCR_EL1);
 }
@@ -85,8 +94,8 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
 	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE))
 		__debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1);
 	/* Disable and flush Self-Hosted Trace generation */
-	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE))
-		__debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1);
+	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRFCR))
+		__debug_save_trace(vcpu);
 }
 
 void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
@@ -98,7 +107,7 @@ void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu)
 {
 	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE))
 		__debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1);
-	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE))
+	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRFCR))
 		__debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1);
 }
 
-- 
2.34.1



From james.clark at arm.com  Tue Feb 20 02:09:17 2024
From: james.clark at arm.com (James Clark)
Date: Tue, 20 Feb 2024 10:09:17 +0000
Subject: [PATCH v5 7/7] coresight: Pass guest TRFCR value to KVM
In-Reply-To: <20240220100924.2761706-1-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
Message-ID: <20240220100924.2761706-8-james.clark@arm.com>

Currently the userspace and kernel filters for guests are never set, so
no trace will be generated for them. Add support for tracing guests by
passing the desired TRFCR value to KVM so it can be applied to the
guest.

By writing either E1TRE or E0TRE, filtering on either guest kernel or
guest userspace is also supported. And if both E1TRE and E0TRE are
cleared when exclude_guest is set, that option is supported too. This
change also brings exclude_host support which is difficult to add as a
separate commit without excess churn and resulting in no trace at all.

Testing
=======

The addresses were counted with the following:

  $ perf report -D | grep -Eo 'EL2|EL1|EL0' | sort | uniq -c

Guest kernel only:

  $ perf record -e cs_etm//Gk -a -- true
    535 EL1
      1 EL2

Guest user only (only 5 addresses because the guest runs slowly in the
model):

  $ perf record -e cs_etm//Gu -a -- true
    5 EL0

Host kernel only:

  $  perf record -e cs_etm//Hk -a -- true
   3501 EL2

Host userspace only:

  $  perf record -e cs_etm//Hu -a -- true
    408 EL0
      1 EL2

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: James Clark <james.clark at arm.com>
---
 .../coresight/coresight-etm4x-core.c          | 42 ++++++++++++++++---
 drivers/hwtracing/coresight/coresight-etm4x.h |  2 +-
 drivers/hwtracing/coresight/coresight-priv.h  |  3 ++
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index ce1995a2827f..45a69bfdc6b5 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -6,6 +6,7 @@
 #include <linux/acpi.h>
 #include <linux/bitops.h>
 #include <linux/kernel.h>
+#include <linux/kvm_host.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -271,9 +272,22 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
 	/* If the CPU doesn't support FEAT_TRF, nothing to do */
 	if (!drvdata->trfcr)
 		return;
+	kvm_etm_set_guest_trfcr(0);
 	cpu_prohibit_trace();
 }
 
+static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
+{
+	u64 trfcr = drvdata->trfcr;
+
+	if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
+		trfcr &= ~TRFCR_ELx_ExTRE;
+	if (drvdata->config.mode & ETM_MODE_EXCL_USER)
+		trfcr &= ~TRFCR_ELx_E0TRE;
+
+	return trfcr;
+}
+
 /*
  * etm4x_allow_trace - Allow CPU tracing in the respective ELs,
  * as configured by the drvdata->config.mode for the current
@@ -286,18 +300,28 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
  */
 static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
 {
-	u64 trfcr = drvdata->trfcr;
+	u64 trfcr;
 
 	/* If the CPU doesn't support FEAT_TRF, nothing to do */
-	if (!trfcr)
+	if (!drvdata->trfcr)
 		return;
 
-	if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
-		trfcr &= ~TRFCR_ELx_ExTRE;
-	if (drvdata->config.mode & ETM_MODE_EXCL_USER)
-		trfcr &= ~TRFCR_ELx_E0TRE;
+	if (drvdata->config.mode & ETM_MODE_EXCL_HOST)
+		trfcr = drvdata->trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE);
+	else
+		trfcr = etm4x_get_kern_user_filter(drvdata);
 
 	write_trfcr(trfcr);
+
+	/* Set filters for guests and pass to KVM */
+	if (drvdata->config.mode & ETM_MODE_EXCL_GUEST)
+		trfcr = drvdata->trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE);
+	else
+		trfcr = etm4x_get_kern_user_filter(drvdata);
+
+	/* TRFCR_EL1 doesn't have CX so mask it out. */
+	trfcr &= ~TRFCR_EL2_CX;
+	kvm_etm_set_guest_trfcr(trfcr);
 }
 
 #ifdef CONFIG_ETM4X_IMPDEF_FEATURE
@@ -655,6 +679,12 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
 	if (attr->exclude_user)
 		config->mode = ETM_MODE_EXCL_USER;
 
+	if (attr->exclude_host)
+		config->mode |= ETM_MODE_EXCL_HOST;
+
+	if (attr->exclude_guest)
+		config->mode |= ETM_MODE_EXCL_GUEST;
+
 	/* Always start from the default config */
 	etm4_set_default_config(config);
 
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index da17b6c49b0f..70c29e91f4b5 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -841,7 +841,7 @@ enum etm_impdef_type {
  * @s_ex_level: Secure ELs where tracing is supported.
  */
 struct etmv4_config {
-	u32				mode;
+	u64				mode;
 	u32				pe_sel;
 	u32				cfg;
 	u32				eventctrl0;
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 767076e07970..727dd27ba800 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -39,6 +39,9 @@
 
 #define ETM_MODE_EXCL_KERN	BIT(30)
 #define ETM_MODE_EXCL_USER	BIT(31)
+#define ETM_MODE_EXCL_HOST	BIT(32)
+#define ETM_MODE_EXCL_GUEST	BIT(33)
+
 struct cs_pair_attribute {
 	struct device_attribute attr;
 	u32 lo_off;
-- 
2.34.1



From tglx at linutronix.de  Tue Feb 20 02:11:19 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 20 Feb 2024 11:11:19 +0100
Subject: [PATCH v13 02/13] irqchip/sifive-plic: Improve locking safety
 by using irqsave/irqrestore
In-Reply-To: <20240220060718.823229-3-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-3-apatel@ventanamicro.com>
Message-ID: <87frxnigxk.ffs@tglx>

On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> Now that PLIC driver is probed as a regular platform driver, the lock
> dependency validator complains about the safety of handler->enable_lock
> usage:
>
> [    0.956775]  Possible interrupt unsafe locking scenario:
>
> [    0.956998]        CPU0                    CPU1
> [    0.957247]        ----                    ----
> [    0.957439]   lock(&handler->enable_lock);
> [    0.957607]                                local_irq_disable();
> [    0.957793]                                lock(&irq_desc_lock_class);
> [    0.958021]                                lock(&handler->enable_lock);
> [    0.958246]   <Interrupt>
> [    0.958342]     lock(&irq_desc_lock_class);
> [    0.958501]
>                 *** DEADLOCK ***
>
> To address above, let's use raw_spin_lock_irqsave/unlock_irqrestore()
> instead of raw_spin_lock/unlock().

s/let's//


From tglx at linutronix.de  Tue Feb 20 02:13:14 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 20 Feb 2024 11:13:14 +0100
Subject: [PATCH v13 03/13] irqchip/riscv-intc: Add support for RISC-V AIA
In-Reply-To: <20240220060718.823229-4-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-4-apatel@ventanamicro.com>
Message-ID: <87cysrigud.ffs@tglx>

On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:

> The RISC-V advanced interrupt architecture (AIA) extends the per-HART
> local interrupts in following ways:
> 1. Minimum 64 local interrupts for both RV32 and RV64
> 2. Ability to process multiple pending local interrupts in same
>    interrupt handler
> 3. Priority configuration for each local interrupts
> 4. Special CSRs to configure/access the per-HART MSI controller
>
> We add support for #1 and #2 described above in the RISC-V intc
> driver.

S/We add/Add/

> +static asmlinkage void riscv_intc_aia_irq(struct pt_regs *regs)
> +{
> +	unsigned long topi;
> +
> +	while ((topi = csr_read(CSR_TOPI)))
> +		generic_handle_domain_irq(intc_domain,
> +					  topi >> TOPI_IID_SHIFT);

Please let it stick out. You got 100 characters. All over the place.

Thanks,

        tglx


From rppt at kernel.org  Tue Feb 20 02:30:01 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Tue, 20 Feb 2024 12:30:01 +0200
Subject: [PATCH v3 09/17] x86: Add KHO support
In-Reply-To: <20240117144704.602-10-graf@amazon.com>
References: <20240117144704.602-1-graf@amazon.com>
 <20240117144704.602-10-graf@amazon.com>
Message-ID: <ZdR_KQSIrPuEh5G5@kernel.org>

Hi Alex,

On Wed, Jan 17, 2024 at 02:46:56PM +0000, Alexander Graf wrote:
> We now have all bits in place to support KHO kexecs. This patch adds
> awareness of KHO in the kexec file as well as boot path for x86 and
> adds the respective kconfig option to the architecture so that it can
> use KHO successfully.
> 
> In addition, it enlightens it decompression code with KHO so that its
> KASLR location finder only considers memory regions that are not already
> occupied by KHO memory.
> 
> Signed-off-by: Alexander Graf <graf at amazon.com>
> 
> ---
> 
> v1 -> v2:
> 
>   - Change kconfig option to ARCH_SUPPORTS_KEXEC_KHO
>   - s/kho_reserve_mem/kho_reserve_previous_mem/g
>   - s/kho_reserve/kho_reserve_scratch/g
> ---
>  arch/x86/Kconfig                      |  3 ++
>  arch/x86/boot/compressed/kaslr.c      | 55 +++++++++++++++++++++++++++
>  arch/x86/include/uapi/asm/bootparam.h | 15 +++++++-
>  arch/x86/kernel/e820.c                |  9 +++++
>  arch/x86/kernel/kexec-bzimage64.c     | 39 +++++++++++++++++++
>  arch/x86/kernel/setup.c               | 46 ++++++++++++++++++++++
>  arch/x86/mm/init_32.c                 |  7 ++++
>  arch/x86/mm/init_64.c                 |  7 ++++
>  8 files changed, 180 insertions(+), 1 deletion(-)

...

> @@ -987,8 +1013,26 @@ void __init setup_arch(char **cmdline_p)
>  	cleanup_highmap();
>  
>  	memblock_set_current_limit(ISA_END_ADDRESS);
> +
>  	e820__memblock_setup();
>  
> +	/*
> +	 * We can resize memblocks at this point, let's dump all KHO
> +	 * reservations in and switch from scratch-only to normal allocations
> +	 */
> +	kho_reserve_previous_mem();
> +
> +	/* Allocations now skip scratch mem, return low 1M to the pool */
> +	if (is_kho_boot()) {
> +		u64 i;
> +		phys_addr_t base, end;
> +
> +		__for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE,
> +				     MEMBLOCK_SCRATCH, &base, &end, NULL)
> +			if (end <= ISA_END_ADDRESS)
> +				memblock_clear_scratch(base, end - base);
> +	}

You had to mark lower 16M as MEMBLOCK_SCRATCH because at this point the
mapping of the physical memory is not ready yet and page tables only cover
lower 16M and the memory mapped in kexec::init_pgtable(). Hence the call
for memblock_set_current_limit(ISA_END_ADDRESS) slightly above, which
essentially makes scratch mem reserved by KHO unusable for allocations.

I'd suggest to move kho_reserve_previous_mem() earlier, probably even right
next to kho_populate().
kho_populate() already does memblock_add(scratch) and at that point it's
the only physical memory that memblock knows of, so if it'll have to
allocate, the allocations will end up there.

Also, there are no kernel allocations before e820__memblock_setup(), so the
only memory that might need to be allocated is for memblock_double_array()
and that will be discarded later anyway.

With this, it seems that MEMBLOCK_SCRATCH is not needed, as the scratch
memory is anyway the only usable memory up to e820__memblock_setup().

>  	/*
>  	 * Needs to run after memblock setup because it needs the physical
>  	 * memory size.
> @@ -1104,6 +1148,8 @@ void __init setup_arch(char **cmdline_p)
>  	 */
>  	arch_reserve_crashkernel();
>  
> +	kho_reserve_scratch();
> +
>  	memblock_find_dma_reserve();
>  
>  	if (!early_xdbc_setup_hardware())
> diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
> index b63403d7179d..6c3810afed04 100644
> --- a/arch/x86/mm/init_32.c
> +++ b/arch/x86/mm/init_32.c
> @@ -20,6 +20,7 @@
>  #include <linux/smp.h>
>  #include <linux/init.h>
>  #include <linux/highmem.h>
> +#include <linux/kexec.h>
>  #include <linux/pagemap.h>
>  #include <linux/pci.h>
>  #include <linux/pfn.h>
> @@ -738,6 +739,12 @@ void __init mem_init(void)
>  	after_bootmem = 1;
>  	x86_init.hyper.init_after_bootmem();
>  
> +	/*
> +	 * Now that all KHO pages are marked as reserved, let's flip them back
> +	 * to normal pages with accurate refcount.
> +	 */
> +	kho_populate_refcount();

This should go to mm_core_init(), there's nothing architecture specific
there.

> +
>  	/*
>  	 * Check boundaries twice: Some fundamental inconsistencies can
>  	 * be detected at build time already.

-- 
Sincerely yours,
Mike.


From naresh.kamboju at linaro.org  Tue Feb 20 02:30:50 2024
From: naresh.kamboju at linaro.org (Naresh Kamboju)
Date: Tue, 20 Feb 2024 16:00:50 +0530
Subject: next-20240219: arm64: boot failed - gic_of_init
In-Reply-To: <86a5nw4gp3.wl-maz@kernel.org>
References: <CA+G9fYugYiLd7MDn3wCxK+x5Td9WO-VUX2OvOtTN7D1d4GHCfg@mail.gmail.com>
 <86edd84wer.wl-maz@kernel.org> <86cyss4rl7.wl-maz@kernel.org>
 <a7d8e529-9a44-3f88-50ef-d87b80515c36@huawei.com> <86a5nw4gp3.wl-maz@kernel.org>
Message-ID: <CA+G9fYtWqf1h3w1nkjJGXjYis7Zx5pNxN=EvmfFpMxgktW70Xw@mail.gmail.com>

On Mon, 19 Feb 2024 at 20:57, Marc Zyngier <maz at kernel.org> wrote:
>
> On Mon, 19 Feb 2024 14:46:46 +0000,
> Zenghui Yu <yuzenghui at huawei.com> wrote:
> >
> > On 2024/2/19 19:32, Marc Zyngier wrote:
> > > For what it is worth, I've just tested both defconfig and my own
> > > configuration with both 4k (kvmtool, QEMU+KVM and on SynQuacer) and
> > > 16k (kvmtool), without any obvious problem.
> >
> > I had a quick test on top of next-20240219 with defconfig.  I can
> > reproduce it with QEMU parameter '-cpu max -accel tcg', but things are
> > fine with '-cpu max,lpa2=off -accel tcg'.
> >
> > Bisection shows that the problem happens when we start putting the
> > latest arm64 and kvmarm changes together.  The following hack fixes the
> > problem for me (but I **only** write it for kernel built with defconfig
> > with ARM64_4K_PAGES=y atm).
> >
> > I can investigate it further tomorrow (as it's too late now ;-) ).  Or
> > maybe Marc or Catalin can help fix it with a proper approach.
> >
> > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > index 4f7662008ede..babdc3f4721b 100644
> > --- a/arch/arm64/kernel/cpufeature.c
> > +++ b/arch/arm64/kernel/cpufeature.c
> > @@ -2798,6 +2798,7 @@ static const struct arm64_cpu_capabilities
> > arm64_features[] = {
> > |             .sign = FTR_SIGNED,
> > |             .field_pos = ID_AA64MMFR0_EL1_TGRAN4_SHIFT,
> > |             .min_field_value = ID_AA64MMFR0_EL1_TGRAN4_52_BIT,
> > |+            .max_field_value = BIT(ID_AA64MMFR0_EL1_TGRAN4_WIDTH - 1) - 1,
> > | #else
> > |             .sign = FTR_UNSIGNED,
> > |             .field_pos = ID_AA64MMFR0_EL1_TGRAN16_SHIFT,
>
> I've posted my take on this at [1], which hopefully matches what you
> were aiming at.

This patch [1] applied on Linux next-20240219 and tested and the boot
test passed.
I have validated today's Linux next-20240220 and the boot test passed.

> Thanks,
>
>         M.
>
> [1] https://lore.kernel.org/all/86bk8c4gyh.wl-maz at kernel.org/

- Naresh


From mark.rutland at arm.com  Tue Feb 20 02:31:54 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 20 Feb 2024 10:31:54 +0000
Subject: [PATCH] arm64: errata: Don't enable workarounds for "rare"
 errata by default
In-Reply-To: <20240209183916.25860-1-will@kernel.org>
References: <20240209183916.25860-1-will@kernel.org>
Message-ID: <ZdR_mnss8JpSWVm9@FVFF77S0Q05N.cambridge.arm.com>

On Fri, Feb 09, 2024 at 06:39:16PM +0000, Will Deacon wrote:
> Arm classifies some of its CPU errata as "rare", indicating that the
> hardware error is unlikely to occur in practice. Given that the cost of
> errata workarounds can often be significant in terms of power and
> performance, don't enable workarounds for "rare" errata by default and
> update our documentation to reflect that.
> 
> Cc: James Morse <james.morse at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Signed-off-by: Will Deacon <will at kernel.org>

FWIW:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  Documentation/arch/arm64/silicon-errata.rst |  5 +++--
>  arch/arm64/Kconfig                          | 25 +++++++++------------
>  2 files changed, 14 insertions(+), 16 deletions(-)
> 
> diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
> index e8c2ce1f9df6..fa16b895c997 100644
> --- a/Documentation/arch/arm64/silicon-errata.rst
> +++ b/Documentation/arch/arm64/silicon-errata.rst
> @@ -35,8 +35,9 @@ can be triggered by Linux).
>  For software workarounds that may adversely impact systems unaffected by
>  the erratum in question, a Kconfig entry is added under "Kernel
>  Features" -> "ARM errata workarounds via the alternatives framework".
> -These are enabled by default and patched in at runtime when an affected
> -CPU is detected. For less-intrusive workarounds, a Kconfig option is not
> +With the exception of workarounds for errata deemed "rare" by Arm, these
> +are enabled by default and patched in at runtime when an affected CPU is
> +detected. For less-intrusive workarounds, a Kconfig option is not
>  available and the code is structured (preferably with a comment) in such
>  a way that the erratum will not be hit.
>  
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index aa7c1d435139..430fabf20f17 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -547,9 +547,8 @@ config ARM64_ERRATUM_832075
>  	  If unsure, say Y.
>  
>  config ARM64_ERRATUM_834220
> -	bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault"
> +	bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault (rare)"
>  	depends on KVM
> -	default y
>  	help
>  	  This option adds an alternative code sequence to work around ARM
>  	  erratum 834220 on Cortex-A57 parts up to r1p2.
> @@ -565,7 +564,7 @@ config ARM64_ERRATUM_834220
>  	  as it depends on the alternative framework, which will only patch
>  	  the kernel if an affected CPU is detected.
>  
> -	  If unsure, say Y.
> +	  If unsure, say N.
>  
>  config ARM64_ERRATUM_1742098
>  	bool "Cortex-A57/A72: 1742098: ELR recorded incorrectly on interrupt taken between cryptographic instructions in a sequence"
> @@ -692,8 +691,7 @@ config ARM64_WORKAROUND_REPEAT_TLBI
>  	bool
>  
>  config ARM64_ERRATUM_2441007
> -	bool "Cortex-A55: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"
> -	default y
> +	bool "Cortex-A55: Completion of affected memory accesses might not be guaranteed by completion of a TLBI (rare)"
>  	select ARM64_WORKAROUND_REPEAT_TLBI
>  	help
>  	  This option adds a workaround for ARM Cortex-A55 erratum #2441007.
> @@ -706,11 +704,10 @@ config ARM64_ERRATUM_2441007
>  	  Work around this by adding the affected CPUs to the list that needs
>  	  TLB sequences to be done twice.
>  
> -	  If unsure, say Y.
> +	  If unsure, say N.
>  
>  config ARM64_ERRATUM_1286807
> -	bool "Cortex-A76: Modification of the translation table for a virtual address might lead to read-after-read ordering violation"
> -	default y
> +	bool "Cortex-A76: Modification of the translation table for a virtual address might lead to read-after-read ordering violation (rare)"
>  	select ARM64_WORKAROUND_REPEAT_TLBI
>  	help
>  	  This option adds a workaround for ARM Cortex-A76 erratum 1286807.
> @@ -724,6 +721,8 @@ config ARM64_ERRATUM_1286807
>  	  invalidated has been observed by other observers. The
>  	  workaround repeats the TLBI+DSB operation.
>  
> +	  If unsure, say N.
> +
>  config ARM64_ERRATUM_1463225
>  	bool "Cortex-A76: Software Step might prevent interrupt recognition"
>  	default y
> @@ -743,8 +742,7 @@ config ARM64_ERRATUM_1463225
>  	  If unsure, say Y.
>  
>  config ARM64_ERRATUM_1542419
> -	bool "Neoverse-N1: workaround mis-ordering of instruction fetches"
> -	default y
> +	bool "Neoverse-N1: workaround mis-ordering of instruction fetches (rare)"
>  	help
>  	  This option adds a workaround for ARM Neoverse-N1 erratum
>  	  1542419.
> @@ -756,7 +754,7 @@ config ARM64_ERRATUM_1542419
>  	  Workaround the issue by hiding the DIC feature from EL0. This
>  	  forces user-space to perform cache maintenance.
>  
> -	  If unsure, say Y.
> +	  If unsure, say N.
>  
>  config ARM64_ERRATUM_1508412
>  	bool "Cortex-A77: 1508412: workaround deadlock on sequence of NC/Device load and store exclusive or PAR read"
> @@ -931,8 +929,7 @@ config ARM64_ERRATUM_2224489
>  	  If unsure, say Y.
>  
>  config ARM64_ERRATUM_2441009
> -	bool "Cortex-A510: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"
> -	default y
> +	bool "Cortex-A510: Completion of affected memory accesses might not be guaranteed by completion of a TLBI (rare)"
>  	select ARM64_WORKAROUND_REPEAT_TLBI
>  	help
>  	  This option adds a workaround for ARM Cortex-A510 erratum #2441009.
> @@ -945,7 +942,7 @@ config ARM64_ERRATUM_2441009
>  	  Work around this by adding the affected CPUs to the list that needs
>  	  TLB sequences to be done twice.
>  
> -	  If unsure, say Y.
> +	  If unsure, say N.
>  
>  config ARM64_ERRATUM_2064142
>  	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
> -- 
> 2.43.0.687.g38aa6559b0-goog
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From noname.nuno at gmail.com  Tue Feb 20 02:41:29 2024
From: noname.nuno at gmail.com (Nuno =?ISO-8859-1?Q?S=E1?=)
Date: Tue, 20 Feb 2024 11:41:29 +0100
Subject: [PATCH v2 5/5] iio: adc: ad7380: use spi_optimize_message()
In-Reply-To: <20240219-mainline-spi-precook-message-v2-5-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
	 <20240219-mainline-spi-precook-message-v2-5-4a762c6701b9@baylibre.com>
Message-ID: <0ec567d7df3632a9c8104485c4207a47e159fdb9.camel@gmail.com>

On Mon, 2024-02-19 at 16:33 -0600, David Lechner wrote:
> This modifies the ad7380 ADC driver to use spi_optimize_message() to
> optimize the SPI message for the buffered read operation. Since buffered
> reads reuse the same SPI message for each read, this can improve
> performance by reducing the overhead of setting up some parts the SPI
> message in each spi_sync() call.
> 
> Signed-off-by: David Lechner <dlechner at baylibre.com>
> ---
> 

Reviewed-by: Nuno Sa <nuno.sa at analog.com>

> v2 changes:
> - Removed dynamic allocation of spi xfer/msg
> - Moved spi message optimization to probe function
> - Dropped buffer pre/post callbacks
> 
> ?drivers/iio/adc/ad7380.c | 36 ++++++++++++++++++++++++++++++------
> ?1 file changed, 30 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
> index abd746aef868..6b3fd20c8f1f 100644
> --- a/drivers/iio/adc/ad7380.c
> +++ b/drivers/iio/adc/ad7380.c
> @@ -133,6 +133,9 @@ struct ad7380_state {
> ?	struct spi_device *spi;
> ?	struct regulator *vref;
> ?	struct regmap *regmap;
> +	/* xfer and msg for buffer reads */
> +	struct spi_transfer xfer;
> +	struct spi_message msg;
> ?	/*
> ?	 * DMA (thus cache coherency maintenance) requires the
> ?	 * transfer buffers to live in their own cache lines.
> @@ -236,14 +239,9 @@ static irqreturn_t ad7380_trigger_handler(int irq, void *p)
> ?	struct iio_poll_func *pf = p;
> ?	struct iio_dev *indio_dev = pf->indio_dev;
> ?	struct ad7380_state *st = iio_priv(indio_dev);
> -	struct spi_transfer xfer = {
> -		.bits_per_word = st->chip_info->channels[0].scan_type.realbits,
> -		.len = 4,
> -		.rx_buf = st->scan_data.raw,
> -	};
> ?	int ret;
> ?
> -	ret = spi_sync_transfer(st->spi, &xfer, 1);
> +	ret = spi_sync(st->spi, &st->msg);
> ?	if (ret)
> ?		goto out;
> ?
> @@ -335,6 +333,28 @@ static const struct iio_info ad7380_info = {
> ?	.debugfs_reg_access = &ad7380_debugfs_reg_access,
> ?};
> ?
> +static void ad7380_unoptimize_spi_msg(void *msg)
> +{
> +	spi_unoptimize_message(msg);
> +}
> +
> +static int devm_ad7380_setup_spi_msg(struct device *dev, struct ad7380_state *st)
> +{
> +	int ret;
> +
> +	st->xfer.bits_per_word = st->chip_info->channels[0].scan_type.realbits;
> +	st->xfer.len = 4;
> +	st->xfer.rx_buf = st->scan_data.raw;
> +
> +	spi_message_init_with_transfers(&st->msg, &st->xfer, 1);
> +
> +	ret = spi_optimize_message(st->spi, &st->msg);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "failed to optimize message\n");
> +
> +	return devm_add_action_or_reset(dev, ad7380_unoptimize_spi_msg, &st->msg);
> +}
> +
> ?static int ad7380_init(struct ad7380_state *st)
> ?{
> ?	int ret;
> @@ -411,6 +431,10 @@ static int ad7380_probe(struct spi_device *spi)
> ?		return dev_err_probe(&spi->dev, PTR_ERR(st->regmap),
> ?				???? "failed to allocate register map\n");
> ?
> +	ret = devm_ad7380_setup_spi_msg(&spi->dev, st);
> +	if (ret)
> +		return ret;
> +
> ?	indio_dev->channels = st->chip_info->channels;
> ?	indio_dev->num_channels = st->chip_info->num_channels;
> ?	indio_dev->name = st->chip_info->name;
> 



From alexander.stein at ew.tq-group.com  Tue Feb 20 02:41:39 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 20 Feb 2024 11:41:39 +0100
Subject: [PATCH v14 7/7] phy: freescale: Add HDMI PHY driver for i.MX8MQ
In-Reply-To: <eb8c8aa5e5511d2bd462d05022764f67f7bb47c9.1708395604.git.Sandor.yu@nxp.com>
References: <cover.1708395604.git.Sandor.yu@nxp.com> <eb8c8aa5e5511d2bd462d05022764f67f7bb47c9.1708395604.git.Sandor.yu@nxp.com>
Message-ID: <22191690.EfDdHjke4D@steina-w>

Hi,

thanks for the update.

Am Dienstag, 20. Februar 2024, 04:23:55 CET schrieb Sandor Yu:
> Add Cadence HDP-TX HDMI PHY driver for i.MX8MQ.
> 
> Cadence HDP-TX PHY could be put in either DP mode or
> HDMI mode base on the configuration chosen.
> HDMI PHY mode is configurated in the driver.
> 
> Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>

This still works as before. I noticed there is a lot of code duplication
with patch 6. IMHO these PHY drivers should be merged into a single
one where the mode is configured using phy_set_mode() from
cdns-mhdp8501-core.c. This nicely matches my concerns regarding patch 5.

Best regards,
Alexander

> ---
> v13->v14:
>  *No change.
> 
> v12->v13:
> - Fix build warning
> 
> v11->v12:
> - Adjust clk disable order.
> - Return error code to replace -1 for function wait_for_ack().
> - Use bool for variable pclk_in.
> - Add year 2024 to copyright.
> 
>  drivers/phy/freescale/Kconfig               |  10 +
>  drivers/phy/freescale/Makefile              |   1 +
>  drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c | 960 ++++++++++++++++++++
>  3 files changed, 971 insertions(+)
>  create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> 
> diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> index c39709fd700ac..14f47b7cc77ab 100644
> --- a/drivers/phy/freescale/Kconfig
> +++ b/drivers/phy/freescale/Kconfig
> @@ -45,6 +45,16 @@ config PHY_FSL_IMX8MQ_DP
>  	  Enable this to support the Cadence HDPTX DP PHY driver
>  	  on i.MX8MQ SOC.
>  
> +config PHY_FSL_IMX8MQ_HDMI
> +	tristate "Freescale i.MX8MQ HDMI PHY support"
> +	depends on OF && HAS_IOMEM
> +	depends on COMMON_CLK
> +	select GENERIC_PHY
> +	select CDNS_MHDP_HELPER
> +	help
> +	  Enable this to support the Cadence HDPTX HDMI PHY driver
> +	  on i.MX8MQ SOC.
> +
>  endif
>  
>  config PHY_FSL_LYNX_28G
> diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
> index 47e5285209fa8..1380ac31c2ead 100644
> --- a/drivers/phy/freescale/Makefile
> +++ b/drivers/phy/freescale/Makefile
> @@ -1,5 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-$(CONFIG_PHY_FSL_IMX8MQ_DP)		+= phy-fsl-imx8mq-dp.o
> +obj-$(CONFIG_PHY_FSL_IMX8MQ_HDMI)	+= phy-fsl-imx8mq-hdmi.o
>  obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)	+= phy-fsl-imx8mq-usb.o
>  obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)	+= phy-fsl-imx8qm-lvds-phy.o
>  obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)	+= phy-fsl-imx8-mipi-dphy.o
> diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> new file mode 100644
> index 0000000000000..537b1f45c91cc
> --- /dev/null
> +++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> @@ -0,0 +1,960 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Cadence High-Definition Multimedia Interface (HDMI) PHY driver
> + *
> + * Copyright (C) 2022-2024 NXP Semiconductor, Inc.
> + */
> +#include <asm/unaligned.h>
> +#include <drm/bridge/cdns-mhdp-helper.h>
> +#include <linux/clk.h>
> +#include <linux/kernel.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/io.h>
> +
> +#define ADDR_PHY_AFE	0x80000
> +
> +/* PHY registers */
> +#define CMN_SSM_BIAS_TMR			0x0022
> +#define CMN_PLLSM0_USER_DEF_CTRL		0x002f
> +#define CMN_PSM_CLK_CTRL			0x0061
> +#define CMN_CDIAG_REFCLK_CTRL			0x0062
> +#define CMN_PLL0_VCOCAL_START			0x0081
> +#define CMN_PLL0_VCOCAL_INIT_TMR		0x0084
> +#define CMN_PLL0_VCOCAL_ITER_TMR		0x0085
> +#define CMN_TXPUCAL_CTRL			0x00e0
> +#define CMN_TXPDCAL_CTRL			0x00f0
> +#define CMN_TXPU_ADJ_CTRL			0x0108
> +#define CMN_TXPD_ADJ_CTRL			0x010c
> +#define CMN_DIAG_PLL0_FBH_OVRD			0x01c0
> +#define CMN_DIAG_PLL0_FBL_OVRD			0x01c1
> +#define CMN_DIAG_PLL0_OVRD			0x01c2
> +#define CMN_DIAG_PLL0_TEST_MODE			0x01c4
> +#define CMN_DIAG_PLL0_V2I_TUNE			0x01c5
> +#define CMN_DIAG_PLL0_CP_TUNE			0x01c6
> +#define CMN_DIAG_PLL0_LF_PROG			0x01c7
> +#define CMN_DIAG_PLL0_PTATIS_TUNE1		0x01c8
> +#define CMN_DIAG_PLL0_PTATIS_TUNE2		0x01c9
> +#define CMN_DIAG_PLL0_INCLK_CTRL		0x01ca
> +#define CMN_DIAG_PLL0_PXL_DIVH			0x01cb
> +#define CMN_DIAG_PLL0_PXL_DIVL			0x01cc
> +#define CMN_DIAG_HSCLK_SEL			0x01e0
> +#define XCVR_PSM_RCTRL				0x4001
> +#define TX_TXCC_CAL_SCLR_MULT_0			0x4047
> +#define TX_TXCC_CPOST_MULT_00_0			0x404c
> +#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
> +#define XCVR_DIAG_PLLDRC_CTRL			0x40e0
> +#define XCVR_DIAG_HSCLK_SEL			0x40e1
> +#define XCVR_DIAG_BIDI_CTRL			0x40e8
> +#define TX_PSC_A0				0x4100
> +#define TX_PSC_A1				0x4101
> +#define TX_PSC_A2				0x4102
> +#define TX_PSC_A3				0x4103
> +#define TX_DIAG_TX_CTRL				0x41e0
> +#define TX_DIAG_TX_DRV				0x41e1
> +#define TX_DIAG_BGREF_PREDRV_DELAY		0x41e7
> +#define TX_DIAG_ACYA_0				0x41ff
> +#define TX_DIAG_ACYA_1				0x43ff
> +#define TX_DIAG_ACYA_2				0x45ff
> +#define TX_DIAG_ACYA_3				0x47ff
> +#define TX_ANA_CTRL_REG_1			0x5020
> +#define TX_ANA_CTRL_REG_2			0x5021
> +#define TX_DIG_CTRL_REG_2			0x5024
> +#define TXDA_CYA_AUXDA_CYA			0x5025
> +#define TX_ANA_CTRL_REG_3			0x5026
> +#define TX_ANA_CTRL_REG_4			0x5027
> +#define TX_ANA_CTRL_REG_5			0x5029
> +#define RX_PSC_A0				0x8000
> +#define RX_PSC_CAL				0x8006
> +#define PHY_HDP_MODE_CTRL			0xc008
> +#define PHY_HDP_CLK_CTL				0xc009
> +#define PHY_ISO_CMN_CTRL			0xc010
> +#define PHY_PMA_CMN_CTRL1			0xc800
> +#define PHY_PMA_ISO_CMN_CTRL			0xc810
> +#define PHY_PMA_ISO_PLL_CTRL1			0xc812
> +#define PHY_PMA_ISOLATION_CTRL			0xc81f
> +
> +/* PHY_HDP_CLK_CTL */
> +#define PLL_DATA_RATE_CLK_DIV_MASK		GENMASK(15, 8)
> +#define PLL_DATA_RATE_CLK_DIV_HBR		0x24
> +#define PLL_DATA_RATE_CLK_DIV_HBR2		0x12
> +#define PLL_CLK_EN_ACK_EN			BIT(3)
> +#define PLL_CLK_EN				BIT(2)
> +#define PLL_READY				BIT(1)
> +#define PLL_EN					BIT(0)
> +
> +/* PHY_PMA_CMN_CTRL1 */
> +#define CMA_REF_CLK_DIG_DIV_MASK		GENMASK(13, 12)
> +#define CMA_REF_CLK_SEL_MASK			GENMASK(6, 4)
> +#define CMA_REF_CLK_RCV_EN_MASK			BIT(3)
> +#define CMA_REF_CLK_RCV_EN			1
> +#define CMN_READY				BIT(0)
> +
> +/* PHY_PMA_ISO_PLL_CTRL1 */
> +#define CMN_PLL0_CLK_DATART_DIV_MASK		GENMASK(7, 0)
> +
> +/* TX_DIAG_TX_DRV */
> +#define TX_DRIVER_PROG_BOOST_ENABLE		BIT(10)
> +#define TX_DRIVER_PROG_BOOST_LEVEL_MASK		GENMASK(9, 8)
> +#define TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE	BIT(7)
> +#define TX_DRIVER_LDO_BANDGAP_REF_ENABLE	BIT(6)
> +
> +/* TX_TXCC_CAL_SCLR_MULT_0 */
> +#define SCALED_RESISTOR_CALIBRATION_CODE_ADD	BIT(8)
> +#define RESISTOR_CAL_MULT_VAL_32_128		BIT(5)
> +
> +/* CMN_CDIAG_REFCLK_CTRL */
> +#define DIG_REF_CLK_DIV_SCALER_MASK		GENMASK(14, 12)
> +#define REFCLK_TERMINATION_EN_OVERRIDE_EN	BIT(7)
> +#define REFCLK_TERMINATION_EN_OVERRIDE		BIT(6)
> +
> +/* CMN_DIAG_HSCLK_SEL */
> +#define HSCLK1_SEL_MASK				GENMASK(5, 4)
> +#define HSCLK0_SEL_MASK				GENMASK(1, 0)
> +
> +/* XCVR_DIAG_HSCLK_SEL */
> +#define HSCLK_SEL_MODE3_MASK			GENMASK(13, 12)
> +#define HSCLK_SEL_MODE3_HSCLK1			1
> +
> +/* CMN_PLL0_VCOCAL_START */
> +#define VCO_CALIB_CODE_START_POINT_VAL_MASK	GENMASK(8, 0)
> +
> +/* CMN_DIAG_PLL0_FBH_OVRD */
> +#define PLL_FEEDBACK_DIV_HI_OVERRIDE_EN		BIT(15)
> +
> +/* CMN_DIAG_PLL0_FBL_OVRD */
> +#define PLL_FEEDBACK_DIV_LO_OVERRIDE_EN		BIT(15)
> +
> +/* CMN_DIAG_PLL0_PXL_DIVH */
> +#define PLL_PCLK_DIV_EN				BIT(15)
> +
> +/* XCVR_DIAG_PLLDRC_CTRL */
> +#define DPLL_CLK_SEL_MODE3			BIT(14)
> +
> +/* TX_DIAG_TX_CTRL */
> +#define TX_IF_SUBRATE_MODE3_MASK		GENMASK(7, 6)
> +
> +/* PHY_HDP_MODE_CTRL */
> +#define POWER_STATE_A3_ACK			BIT(7)
> +#define POWER_STATE_A2_ACK			BIT(6)
> +#define POWER_STATE_A1_ACK			BIT(5)
> +#define POWER_STATE_A0_ACK			BIT(4)
> +#define POWER_STATE_A3				BIT(3)
> +#define POWER_STATE_A2				BIT(2)
> +#define POWER_STATE_A1				BIT(1)
> +#define POWER_STATE_A0				BIT(0)
> +
> +/* PHY_PMA_ISO_CMN_CTRL */
> +#define CMN_MACRO_PWR_EN_ACK			BIT(5)
> +
> +#define KEEP_ALIVE		0x18
> +
> +#define REF_CLK_27MHZ		27000000
> +
> +/* HDMI TX clock control settings */
> +struct hdptx_hdmi_ctrl {
> +	u32 pixel_clk_freq_min;
> +	u32 pixel_clk_freq_max;
> +	u32 feedback_factor;
> +	u32 data_range_kbps_min;
> +	u32 data_range_kbps_max;
> +	u32 cmnda_pll0_ip_div;
> +	u32 cmn_ref_clk_dig_div;
> +	u32 ref_clk_divider_scaler;
> +	u32 pll_fb_div_total;
> +	u32 cmnda_pll0_fb_div_low;
> +	u32 cmnda_pll0_fb_div_high;
> +	u32 pixel_div_total;
> +	u32 cmnda_pll0_pxdiv_low;
> +	u32 cmnda_pll0_pxdiv_high;
> +	u32 vco_freq_min;
> +	u32 vco_freq_max;
> +	u32 vco_ring_select;
> +	u32 cmnda_hs_clk_0_sel;
> +	u32 cmnda_hs_clk_1_sel;
> +	u32 hsclk_div_at_xcvr;
> +	u32 hsclk_div_tx_sub_rate;
> +	u32 cmnda_pll0_hs_sym_div_sel;
> +	u32 cmnda_pll0_clk_freq_min;
> +	u32 cmnda_pll0_clk_freq_max;
> +};
> +
> +struct cdns_hdptx_hdmi_phy {
> +	struct cdns_mhdp_base base;
> +
> +	void __iomem *regs;	/* DPTX registers base */
> +	struct mutex mbox_mutex; /* mutex to protect mailbox */
> +	struct device *dev;
> +	struct phy *phy;
> +	struct clk *ref_clk, *apb_clk;
> +	u32 ref_clk_rate;
> +	u32 pixel_clk_rate;
> +	enum hdmi_colorspace color_space;
> +	u32 bpc;
> +};
> +
> +/* HDMI TX clock control settings, pixel clock is output */
> +static const struct hdptx_hdmi_ctrl pixel_clk_output_ctrl_table[] = {
> +/*Minclk  Maxclk Fdbak  DR_min   DR_max  ip_d  dig  DS    Totl */
> +{ 27000,  27000, 1000,  270000,  270000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x3,  27000,  27000},
> +{ 27000,  27000, 1250,  337500,  337500, 0x03, 0x1, 0x1,  300, 0x0ec, 0x03c, 100, 0x030, 0x030, 2700000, 2700000, 0, 2, 2, 2, 4, 0x3,  33750,  33750},
> +{ 27000,  27000, 1500,  405000,  405000, 0x03, 0x1, 0x1,  360, 0x11c, 0x048, 120, 0x03a, 0x03a, 3240000, 3240000, 0, 2, 2, 2, 4, 0x3,  40500,  40500},
> +{ 27000,  27000, 2000,  540000,  540000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x2,  54000,  54000},
> +{ 54000,  54000, 1000,  540000,  540000, 0x03, 0x1, 0x1,  480, 0x17c, 0x060,  80, 0x026, 0x026, 4320000, 4320000, 1, 2, 2, 2, 4, 0x3,  54000,  54000},
> +{ 54000,  54000, 1250,  675000,  675000, 0x04, 0x1, 0x1,  400, 0x13c, 0x050,  50, 0x017, 0x017, 2700000, 2700000, 0, 1, 1, 2, 4, 0x2,  67500,  67500},
> +{ 54000,  54000, 1500,  810000,  810000, 0x04, 0x1, 0x1,  480, 0x17c, 0x060,  60, 0x01c, 0x01c, 3240000, 3240000, 0, 2, 2, 2, 2, 0x2,  81000,  81000},
> +{ 54000,  54000, 2000, 1080000, 1080000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,  40, 0x012, 0x012, 2160000, 2160000, 0, 2, 2, 2, 1, 0x1, 108000, 108000},
> +{ 74250,  74250, 1000,  742500,  742500, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  80, 0x026, 0x026, 5940000, 5940000, 1, 2, 2, 2, 4, 0x3,  74250,  74250},
> +{ 74250,  74250, 1250,  928125,  928125, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  50, 0x017, 0x017, 3712500, 3712500, 1, 1, 1, 2, 4, 0x2,  92812,  92812},
> +{ 74250,  74250, 1500, 1113750, 1113750, 0x04, 0x1, 0x1,  660, 0x20c, 0x084,  60, 0x01c, 0x01c, 4455000, 4455000, 1, 2, 2, 2, 2, 0x2, 111375, 111375},
> +{ 74250,  74250, 2000, 1485000, 1485000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  40, 0x012, 0x012, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1, 148500, 148500},
> +{ 99000,  99000, 1000,  990000,  990000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  40, 0x012, 0x012, 3960000, 3960000, 1, 2, 2, 2, 2, 0x2,  99000,  99000},
> +{ 99000,  99000, 1250, 1237500, 1237500, 0x03, 0x1, 0x1,  275, 0x0d8, 0x037,  25, 0x00b, 0x00a, 2475000, 2475000, 0, 1, 1, 2, 2, 0x1, 123750, 123750},
> +{ 99000,  99000, 1500, 1485000, 1485000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  30, 0x00d, 0x00d, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1, 148500, 148500},
> +{ 99000,  99000, 2000, 1980000, 1980000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  40, 0x012, 0x012, 3960000, 3960000, 1, 2, 2, 2, 1, 0x1, 198000, 198000},
> +{148500, 148500, 1000, 1485000, 1485000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  40, 0x012, 0x012, 5940000, 5940000, 1, 2, 2, 2, 2, 0x2, 148500, 148500},
> +{148500, 148500, 1250, 1856250, 1856250, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  25, 0x00b, 0x00a, 3712500, 3712500, 1, 1, 1, 2, 2, 0x1, 185625, 185625},
> +{148500, 148500, 1500, 2227500, 2227500, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  30, 0x00d, 0x00d, 4455000, 4455000, 1, 1, 1, 2, 2, 0x1, 222750, 222750},
> +{148500, 148500, 2000, 2970000, 2970000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  40, 0x012, 0x012, 5940000, 5940000, 1, 2, 2, 2, 1, 0x1, 297000, 297000},
> +{198000, 198000, 1000, 1980000, 1980000, 0x03, 0x1, 0x1,  220, 0x0ac, 0x02c,  10, 0x003, 0x003, 1980000, 1980000, 0, 1, 1, 2, 1, 0x0, 198000, 198000},
> +{198000, 198000, 1250, 2475000, 2475000, 0x03, 0x1, 0x1,  550, 0x1b4, 0x06e,  25, 0x00b, 0x00a, 4950000, 4950000, 1, 1, 1, 2, 2, 0x1, 247500, 247500},
> +{198000, 198000, 1500, 2970000, 2970000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  15, 0x006, 0x005, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000, 297000},
> +{198000, 198000, 2000, 3960000, 3960000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  20, 0x008, 0x008, 3960000, 3960000, 1, 1, 1, 2, 1, 0x0, 396000, 396000},
> +{297000, 297000, 1000, 2970000, 2970000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,  10, 0x003, 0x003, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000, 297000},
> +{297000, 297000, 1500, 4455000, 4455000, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  15, 0x006, 0x005, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0, 445500, 445500},
> +{297000, 297000, 2000, 5940000, 5940000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  20, 0x008, 0x008, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000},
> +{594000, 594000, 1000, 5940000, 5940000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  10, 0x003, 0x003, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000},
> +{594000, 594000,  750, 4455000, 4455000, 0x03, 0x1, 0x1,  495, 0x188, 0x063,  10, 0x003, 0x003, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0, 445500, 445500},
> +{594000, 594000,  625, 3712500, 3712500, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  10, 0x003, 0x003, 3712500, 3712500, 1, 1, 1, 2, 1, 0x0, 371250, 371250},
> +{594000, 594000,  500, 2970000, 2970000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  10, 0x003, 0x003, 5940000, 5940000, 1, 1, 1, 2, 2, 0x1, 297000, 297000},
> +};
> +
> +/* HDMI TX PLL tuning settings */
> +struct hdptx_hdmi_pll_tuning {
> +	u32 vco_freq_bin;
> +	u32 vco_freq_min;
> +	u32 vco_freq_max;
> +	u32 volt_to_current_coarse;
> +	u32 volt_to_current;
> +	u32 ndac_ctrl;
> +	u32 pmos_ctrl;
> +	u32 ptat_ndac_ctrl;
> +	u32 feedback_div_total;
> +	u32 charge_pump_gain;
> +	u32 coarse_code;
> +	u32 v2i_code;
> +	u32 vco_cal_code;
> +};
> +
> +/* HDMI TX PLL tuning settings, pixel clock is output */
> +static const struct hdptx_hdmi_pll_tuning pixel_clk_output_pll_table[] = {
> +/*bin VCO_freq min/max  coar  cod NDAC  PMOS PTAT div-T P-Gain Coa V2I CAL */
> +{  1, 1980000, 1980000, 0x4, 0x3, 0x0, 0x09, 0x09, 220, 0x42, 160, 5, 183 },
> +{  2, 2160000, 2160000, 0x4, 0x3, 0x0, 0x09, 0x09, 240, 0x42, 166, 6, 208 },
> +{  3, 2475000, 2475000, 0x5, 0x3, 0x1, 0x00, 0x07, 275, 0x42, 167, 6, 209 },
> +{  4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 300, 0x42, 188, 6, 230 },
> +{  4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 400, 0x4c, 188, 6, 230 },
> +{  5, 2970000, 2970000, 0x6, 0x3, 0x1, 0x00, 0x07, 330, 0x42, 183, 6, 225 },
> +{  6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 360, 0x42, 203, 7, 256 },
> +{  6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 480, 0x4c, 203, 7, 256 },
> +{  7, 3712500, 3712500, 0x4, 0x3, 0x0, 0x07, 0x0F, 550, 0x4c, 212, 7, 257 },
> +{  8, 3960000, 3960000, 0x5, 0x3, 0x0, 0x07, 0x0F, 440, 0x42, 184, 6, 226 },
> +{  9, 4320000, 4320000, 0x5, 0x3, 0x1, 0x07, 0x0F, 480, 0x42, 205, 7, 258 },
> +{ 10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 495, 0x42, 219, 7, 272 },
> +{ 10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 660, 0x4c, 219, 7, 272 },
> +{ 11, 4950000, 4950000, 0x6, 0x3, 0x1, 0x00, 0x07, 550, 0x42, 213, 7, 258 },
> +{ 12, 5940000, 5940000, 0x7, 0x3, 0x1, 0x00, 0x07, 660, 0x42, 244, 8, 292 },
> +};
> +
> +static int cdns_phy_reg_write(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 addr, u32 val)
> +{
> +	return cdns_mhdp_reg_write(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), val);
> +}
> +
> +static u32 cdns_phy_reg_read(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 addr)
> +{
> +	u32 reg32;
> +
> +	cdns_mhdp_reg_read(&cdns_phy->base, ADDR_PHY_AFE + (addr << 2), &reg32);
> +
> +	return reg32;
> +}
> +
> +static int wait_for_ack(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 reg, u32 mask,
> +			const char *err_msg)
> +{
> +	u32 val, i;
> +
> +	for (i = 0; i < 10; i++) {
> +		val = cdns_phy_reg_read(cdns_phy, reg);
> +		if (val & mask)
> +			return 0;
> +		msleep(20);
> +	}
> +
> +	dev_err(cdns_phy->dev, "%s\n", err_msg);
> +	return -ETIMEDOUT;
> +}
> +
> +static bool hdptx_phy_check_alive(struct cdns_hdptx_hdmi_phy *cdns_phy)
> +{
> +	u32  alive, newalive;
> +	u8 retries_left = 50;
> +
> +	alive = readl(cdns_phy->regs + KEEP_ALIVE);
> +
> +	while (retries_left--) {
> +		udelay(2);
> +
> +		newalive = readl(cdns_phy->regs + KEEP_ALIVE);
> +		if (alive == newalive)
> +			continue;
> +		return true;
> +	}
> +	return false;
> +}
> +
> +static int hdptx_hdmi_clk_enable(struct cdns_hdptx_hdmi_phy *cdns_phy)
> +{
> +	struct device *dev = cdns_phy->dev;
> +	u32 ref_clk_rate;
> +	int ret;
> +
> +	cdns_phy->ref_clk = devm_clk_get(dev, "ref");
> +	if (IS_ERR(cdns_phy->ref_clk)) {
> +		dev_err(dev, "phy ref clock not found\n");
> +		return PTR_ERR(cdns_phy->ref_clk);
> +	}
> +
> +	cdns_phy->apb_clk = devm_clk_get(dev, "apb");
> +	if (IS_ERR(cdns_phy->apb_clk)) {
> +		dev_err(dev, "phy apb clock not found\n");
> +		return PTR_ERR(cdns_phy->apb_clk);
> +	}
> +
> +	ret = clk_prepare_enable(cdns_phy->ref_clk);
> +	if (ret) {
> +		dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
> +		return ret;
> +	}
> +
> +	ref_clk_rate = clk_get_rate(cdns_phy->ref_clk);
> +	if (!ref_clk_rate) {
> +		dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
> +		goto err_ref_clk;
> +	}
> +
> +	if (ref_clk_rate == REF_CLK_27MHZ) {
> +		cdns_phy->ref_clk_rate = ref_clk_rate;
> +	} else {
> +		dev_err(cdns_phy->dev, "Not support Ref Clock Rate(%dHz)\n", ref_clk_rate);
> +		goto err_ref_clk;
> +	}
> +
> +	ret = clk_prepare_enable(cdns_phy->apb_clk);
> +	if (ret) {
> +		dev_err(cdns_phy->dev, "Failed to prepare apb clock\n");
> +		goto err_ref_clk;
> +	}
> +
> +	return 0;
> +
> +err_ref_clk:
> +	clk_disable_unprepare(cdns_phy->ref_clk);
> +	return -EINVAL;
> +}
> +
> +static void hdptx_hdmi_clk_disable(struct cdns_hdptx_hdmi_phy *cdns_phy)
> +{
> +	clk_disable_unprepare(cdns_phy->apb_clk);
> +	clk_disable_unprepare(cdns_phy->ref_clk);
> +}
> +
> +static void hdptx_hdmi_arc_config(struct cdns_hdptx_hdmi_phy *cdns_phy)
> +{
> +	u16 txpu_calib_code;
> +	u16 txpd_calib_code;
> +	u16 txpu_adj_calib_code;
> +	u16 txpd_adj_calib_code;
> +	u16 prev_calib_code;
> +	u16 new_calib_code;
> +	u16 rdata;
> +
> +	/* Power ARC */
> +	cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 0x0001);
> +
> +	prev_calib_code = cdns_phy_reg_read(cdns_phy, TX_DIG_CTRL_REG_2);
> +	txpu_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPUCAL_CTRL);
> +	txpd_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPDCAL_CTRL);
> +	txpu_adj_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPU_ADJ_CTRL);
> +	txpd_adj_calib_code = cdns_phy_reg_read(cdns_phy, CMN_TXPD_ADJ_CTRL);
> +
> +	new_calib_code = ((txpu_calib_code + txpd_calib_code) / 2)
> +		+ txpu_adj_calib_code + txpd_adj_calib_code;
> +
> +	if (new_calib_code != prev_calib_code) {
> +		rdata = cdns_phy_reg_read(cdns_phy, TX_ANA_CTRL_REG_1);
> +		rdata &= 0xdfff;
> +		cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, rdata);
> +		cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2, new_calib_code);
> +		mdelay(10);
> +		rdata |= 0x2000;
> +		cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, rdata);
> +		usleep_range(150, 250);
> +	}
> +
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100);
> +	usleep_range(100, 200);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300);
> +	usleep_range(100, 200);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000);
> +	usleep_range(100, 200);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008);
> +	usleep_range(100, 200);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018);
> +	usleep_range(100, 200);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2098);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0010);
> +	usleep_range(100, 200);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x4001);
> +	mdelay(5);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2198);
> +	mdelay(5);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d);
> +	usleep_range(100, 200);
> +	cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f);
> +}
> +
> +static void hdptx_hdmi_phy_set_vswing(struct cdns_hdptx_hdmi_phy *cdns_phy)
> +{
> +	u32 k;
> +	const u32 num_lanes = 4;
> +
> +	for (k = 0; k < num_lanes; k++) {
> +		cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_DRV | (k << 9)),
> +				   TX_DRIVER_PROG_BOOST_ENABLE |
> +				   FIELD_PREP(TX_DRIVER_PROG_BOOST_LEVEL_MASK, 3) |
> +				   TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE |
> +				   TX_DRIVER_LDO_BANDGAP_REF_ENABLE);
> +		cdns_phy_reg_write(cdns_phy, (TX_TXCC_CPOST_MULT_00_0 | (k << 9)), 0x0);
> +		cdns_phy_reg_write(cdns_phy, (TX_TXCC_CAL_SCLR_MULT_0 | (k << 9)),
> +				   SCALED_RESISTOR_CALIBRATION_CODE_ADD |
> +				   RESISTOR_CAL_MULT_VAL_32_128);
> +	}
> +}
> +
> +static int hdptx_hdmi_feedback_factor(struct cdns_hdptx_hdmi_phy *cdns_phy)
> +{
> +	u32 feedback_factor;
> +
> +	switch (cdns_phy->color_space) {
> +	case HDMI_COLORSPACE_YUV422:
> +		feedback_factor = 1000;
> +		break;
> +
> +	case HDMI_COLORSPACE_YUV420:
> +		switch (cdns_phy->bpc) {
> +		case 8:
> +			feedback_factor = 500;
> +			break;
> +		case 10:
> +			feedback_factor = 625;
> +			break;
> +		case 12:
> +			feedback_factor = 750;
> +			break;
> +		case 16:
> +			feedback_factor = 1000;
> +			break;
> +		default:
> +			dev_dbg(cdns_phy->dev, "Invalid ColorDepth\n");
> +			return 0;
> +		}
> +		break;
> +
> +	default:
> +		/* Assume RGB/YUV444 */
> +		switch (cdns_phy->bpc) {
> +		case 10:
> +			feedback_factor = 1250;
> +			break;
> +		case 12:
> +			feedback_factor = 1500;
> +			break;
> +		case 16:
> +			feedback_factor = 2000;
> +			break;
> +		default:
> +			feedback_factor = 1000;
> +		}
> +	}
> +
> +	return feedback_factor;
> +}
> +
> +static int hdptx_hdmi_phy_config(struct cdns_hdptx_hdmi_phy *cdns_phy,
> +				 const struct hdptx_hdmi_ctrl *p_ctrl_table,
> +				 const struct hdptx_hdmi_pll_tuning *p_pll_table,
> +				 bool pclk_in)
> +{
> +	const u32 num_lanes = 4;
> +	u32 val, k;
> +	int ret;
> +
> +	/* enable PHY isolation mode only for CMN */
> +	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISOLATION_CTRL, 0xd000);
> +
> +	/* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div dividers */
> +	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_ISO_PLL_CTRL1);
> +	val &= ~CMN_PLL0_CLK_DATART_DIV_MASK;
> +	val |= FIELD_PREP(CMN_PLL0_CLK_DATART_DIV_MASK, 0x12);
> +	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_PLL_CTRL1, val);
> +
> +	/* assert PHY reset from isolation register */
> +	cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0000);
> +	/* assert PMA CMN reset */
> +	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0000);
> +
> +	/* register XCVR_DIAG_BIDI_CTRL */
> +	for (k = 0; k < num_lanes; k++)
> +		cdns_phy_reg_write(cdns_phy, XCVR_DIAG_BIDI_CTRL | (k << 9), 0x00ff);
> +
> +	/* Describing Task phy_cfg_hdp */
> +	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
> +	val &= ~CMA_REF_CLK_RCV_EN_MASK;
> +	val |= FIELD_PREP(CMA_REF_CLK_RCV_EN_MASK, CMA_REF_CLK_RCV_EN);
> +	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
> +
> +	/* PHY Registers */
> +	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
> +	val &= ~CMA_REF_CLK_DIG_DIV_MASK;
> +	val |= FIELD_PREP(CMA_REF_CLK_DIG_DIV_MASK, p_ctrl_table->cmn_ref_clk_dig_div);
> +	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
> +
> +	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
> +	val &= ~PLL_DATA_RATE_CLK_DIV_MASK;
> +	val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
> +			  PLL_DATA_RATE_CLK_DIV_HBR2);
> +	cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
> +
> +	/* Common control module control and diagnostic registers */
> +	val = cdns_phy_reg_read(cdns_phy, CMN_CDIAG_REFCLK_CTRL);
> +	val &= ~DIG_REF_CLK_DIV_SCALER_MASK;
> +	val |= FIELD_PREP(DIG_REF_CLK_DIV_SCALER_MASK, p_ctrl_table->ref_clk_divider_scaler);
> +	val |= REFCLK_TERMINATION_EN_OVERRIDE_EN | REFCLK_TERMINATION_EN_OVERRIDE;
> +	cdns_phy_reg_write(cdns_phy, CMN_CDIAG_REFCLK_CTRL, val);
> +
> +	/* High speed clock used */
> +	val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL);
> +	val &= ~(HSCLK1_SEL_MASK | HSCLK0_SEL_MASK);
> +	val |= FIELD_PREP(HSCLK1_SEL_MASK, (p_ctrl_table->cmnda_hs_clk_1_sel >> 1));
> +	val |= FIELD_PREP(HSCLK0_SEL_MASK, (p_ctrl_table->cmnda_hs_clk_0_sel >> 1));
> +	cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val);
> +
> +	for (k = 0; k < num_lanes; k++) {
> +		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
> +		val &= ~HSCLK_SEL_MODE3_MASK;
> +		val |= FIELD_PREP(HSCLK_SEL_MODE3_MASK,
> +				  (p_ctrl_table->cmnda_hs_clk_0_sel >> 1));
> +		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val);
> +	}
> +
> +	/* PLL 0 control state machine registers */
> +	val = p_ctrl_table->vco_ring_select << 12;
> +	cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_USER_DEF_CTRL, val);
> +
> +	if (pclk_in) {
> +		val = 0x30a0;
> +	} else {
> +		val = cdns_phy_reg_read(cdns_phy, CMN_PLL0_VCOCAL_START);
> +		val &= ~VCO_CALIB_CODE_START_POINT_VAL_MASK;
> +		val |= FIELD_PREP(VCO_CALIB_CODE_START_POINT_VAL_MASK,
> +				  p_pll_table->vco_cal_code);
> +	}
> +	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_START, val);
> +
> +	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_INIT_TMR, 0x0064);
> +	cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_ITER_TMR, 0x000a);
> +
> +	/* Common functions control and diagnostics registers */
> +	val = p_ctrl_table->cmnda_pll0_hs_sym_div_sel << 8;
> +	val |= p_ctrl_table->cmnda_pll0_ip_div;
> +	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_INCLK_CTRL, val);
> +
> +	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_OVRD, 0x0000);
> +
> +	val = p_ctrl_table->cmnda_pll0_fb_div_high;
> +	val |= PLL_FEEDBACK_DIV_HI_OVERRIDE_EN;
> +	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBH_OVRD, val);
> +
> +	val = p_ctrl_table->cmnda_pll0_fb_div_low;
> +	val |= PLL_FEEDBACK_DIV_LO_OVERRIDE_EN;
> +	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBL_OVRD, val);
> +
> +	if (!pclk_in) {
> +		val = p_ctrl_table->cmnda_pll0_pxdiv_low;
> +		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PXL_DIVL, val);
> +
> +		val = p_ctrl_table->cmnda_pll0_pxdiv_high;
> +		val |= PLL_PCLK_DIV_EN;
> +		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PXL_DIVH, val);
> +	}
> +
> +	val = p_pll_table->volt_to_current_coarse;
> +	val |= (p_pll_table->volt_to_current) << 4;
> +	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_V2I_TUNE, val);
> +
> +	val = p_pll_table->charge_pump_gain;
> +	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_CP_TUNE, val);
> +
> +	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_LF_PROG, 0x0008);
> +
> +	val = p_pll_table->pmos_ctrl;
> +	val |= (p_pll_table->ndac_ctrl) << 8;
> +	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE1, val);
> +
> +	val = p_pll_table->ptat_ndac_ctrl;
> +	cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE2, val);
> +
> +	if (pclk_in)
> +		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_TEST_MODE, 0x0022);
> +	else
> +		cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_TEST_MODE, 0x0020);
> +
> +	cdns_phy_reg_write(cdns_phy, CMN_PSM_CLK_CTRL, 0x0016);
> +
> +	/* Transceiver control and diagnostic registers */
> +	for (k = 0; k < num_lanes; k++) {
> +		val = cdns_phy_reg_read(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
> +		val &= ~DPLL_CLK_SEL_MODE3;
> +		cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val);
> +	}
> +
> +	for (k = 0; k < num_lanes; k++) {
> +		val = cdns_phy_reg_read(cdns_phy, (TX_DIAG_TX_CTRL | (k << 9)));
> +		val &= ~TX_IF_SUBRATE_MODE3_MASK;
> +		val |= FIELD_PREP(TX_IF_SUBRATE_MODE3_MASK,
> +				  (p_ctrl_table->hsclk_div_tx_sub_rate >> 1));
> +		cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_CTRL | (k << 9)), val);
> +	}
> +
> +	val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
> +	val &= ~CMA_REF_CLK_SEL_MASK;
> +	/*
> +	 * single ended reference clock (val |= 0x0030);
> +	 * differential clock  (val |= 0x0000);
> +	 * for differential clock on the refclk_p and
> +	 * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1
> +	 * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100);
> +	 */
> +	val |= FIELD_PREP(CMA_REF_CLK_SEL_MASK, 3);
> +	cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
> +
> +	/* Deassert PHY reset */
> +	cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0001);
> +	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0003);
> +
> +	/* Power state machine registers */
> +	for (k = 0; k < num_lanes; k++)
> +		cdns_phy_reg_write(cdns_phy, XCVR_PSM_RCTRL | (k << 9), 0xfefc);
> +
> +	/* Assert cmn_macro_pwr_en */
> +	cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0013);
> +
> +	/* wait for cmn_macro_pwr_en_ack */
> +	ret = wait_for_ack(cdns_phy, PHY_PMA_ISO_CMN_CTRL, CMN_MACRO_PWR_EN_ACK,
> +			   "MA output macro power up failed");
> +	if (ret < 0)
> +		return ret;
> +
> +	/* wait for cmn_ready */
> +	ret = wait_for_ack(cdns_phy, PHY_PMA_CMN_CTRL1, CMN_READY,
> +			   "PMA output ready failed");
> +	if (ret < 0)
> +		return ret;
> +
> +	for (k = 0; k < num_lanes; k++) {
> +		cdns_phy_reg_write(cdns_phy, TX_PSC_A0 | (k << 9), 0x6791);
> +		cdns_phy_reg_write(cdns_phy, TX_PSC_A1 | (k << 9), 0x6790);
> +		cdns_phy_reg_write(cdns_phy, TX_PSC_A2 | (k << 9), 0x0090);
> +		cdns_phy_reg_write(cdns_phy, TX_PSC_A3 | (k << 9), 0x0090);
> +
> +		val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k << 9));
> +		val &= 0xffbb;
> +		cdns_phy_reg_write(cdns_phy, RX_PSC_CAL | (k << 9), val);
> +
> +		val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9));
> +		val &= 0xffbb;
> +		cdns_phy_reg_write(cdns_phy, RX_PSC_A0 | (k << 9), val);
> +	}
> +
> +	return 0;
> +}
> +
> +static int hdptx_hdmi_phy_cfg(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 rate)
> +{
> +	const struct hdptx_hdmi_ctrl *p_ctrl_table;
> +	const struct hdptx_hdmi_pll_tuning *p_pll_table;
> +	const u32 refclk_freq_khz = cdns_phy->ref_clk_rate / 1000;
> +	const bool pclk_in = false;
> +	u32 pixel_freq = rate;
> +	u32 vco_freq, char_freq;
> +	u32 div_total, feedback_factor;
> +	u32 i;
> +
> +	feedback_factor = hdptx_hdmi_feedback_factor(cdns_phy);
> +
> +	char_freq = pixel_freq * feedback_factor / 1000;
> +
> +	dev_dbg(cdns_phy->dev,
> +		"Pixel clock: (%d KHz), character clock: %d, bpc is (%0d-bit)\n",
> +		pixel_freq, char_freq, cdns_phy->bpc);
> +
> +	/* Get right row from the ctrl_table table.
> +	 * Check if 'pixel_freq_khz' value matches the PIXEL_CLK_FREQ column.
> +	 * Consider only the rows with FEEDBACK_FACTOR column matching feedback_factor.
> +	 */
> +	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++) {
> +		if (feedback_factor == pixel_clk_output_ctrl_table[i].feedback_factor &&
> +		    pixel_freq == pixel_clk_output_ctrl_table[i].pixel_clk_freq_min) {
> +			p_ctrl_table = &pixel_clk_output_ctrl_table[i];
> +			break;
> +		}
> +	}
> +	if (i == ARRAY_SIZE(pixel_clk_output_ctrl_table)) {
> +		dev_warn(cdns_phy->dev,
> +			 "Pixel clk (%d KHz) not supported, bpc is (%0d-bit)\n",
> +			 pixel_freq, cdns_phy->bpc);
> +		return -EINVAL;
> +	}
> +
> +	div_total = p_ctrl_table->pll_fb_div_total;
> +	vco_freq = refclk_freq_khz * div_total / p_ctrl_table->cmnda_pll0_ip_div;
> +
> +	/* Get right row from the pixel_clk_output_pll_table table.
> +	 * Check if vco_freq_khz and feedback_div_total
> +	 * column matching with pixel_clk_output_pll_table.
> +	 */
> +	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_pll_table); i++) {
> +		if (vco_freq == pixel_clk_output_pll_table[i].vco_freq_min &&
> +		    div_total == pixel_clk_output_pll_table[i].feedback_div_total) {
> +			p_pll_table = &pixel_clk_output_pll_table[i];
> +			break;
> +		}
> +	}
> +	if (i == ARRAY_SIZE(pixel_clk_output_pll_table)) {
> +		dev_warn(cdns_phy->dev, "VCO (%d KHz) not supported\n", vco_freq);
> +		return -EINVAL;
> +	}
> +	dev_dbg(cdns_phy->dev, "VCO frequency is (%d KHz)\n", vco_freq);
> +
> +	return hdptx_hdmi_phy_config(cdns_phy, p_ctrl_table, p_pll_table, pclk_in);
> +}
> +
> +static int hdptx_hdmi_phy_power_up(struct cdns_hdptx_hdmi_phy *cdns_phy)
> +{
> +	int ret = 0;
> +
> +	/* set Power State to A2 */
> +	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2);
> +
> +	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1);
> +	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1);
> +	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1);
> +	cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1);
> +
> +	ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A2_ACK,
> +			   "Wait A2 Ack failed");
> +	if (ret < 0)
> +		return ret;
> +
> +	/* Power up ARC */
> +	hdptx_hdmi_arc_config(cdns_phy);
> +
> +	/* Configure PHY in A0 mode (PHY must be in the A0 power
> +	 * state in order to transmit data)
> +	 */
> +	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0);
> +
> +	return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A0_ACK,
> +			    "Wait A0 Ack failed");
> +}
> +
> +static int hdptx_hdmi_phy_power_down(struct cdns_hdptx_hdmi_phy *cdns_phy)
> +{
> +	u32 val;
> +
> +	val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL);
> +	val &= ~(POWER_STATE_A0 | POWER_STATE_A1 | POWER_STATE_A2 | POWER_STATE_A3);
> +	/* PHY_DP_MODE_CTL set to A3 power state */
> +	cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, val | POWER_STATE_A3);
> +
> +	return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL, POWER_STATE_A3_ACK,
> +			    "Wait A3 Ack failed");
> +}
> +
> +static int cdns_hdptx_hdmi_phy_on(struct phy *phy)
> +{
> +	struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
> +
> +	return hdptx_hdmi_phy_power_up(cdns_phy);
> +}
> +
> +static int cdns_hdptx_hdmi_phy_off(struct phy *phy)
> +{
> +	struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
> +
> +	hdptx_hdmi_phy_power_down(cdns_phy);
> +	return 0;
> +}
> +
> +static int
> +cdns_hdptx_hdmi_phy_valid(struct phy *phy, enum phy_mode mode,
> +			  int submode, union phy_configure_opts *opts)
> +{
> +	u32 rate = opts->hdmi.pixel_clk_rate;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++)
> +		if (rate == pixel_clk_output_ctrl_table[i].pixel_clk_freq_min)
> +			return 0;
> +
> +	return -EINVAL;
> +}
> +
> +static int cdns_hdptx_hdmi_phy_init(struct phy *phy)
> +{
> +	return 0;
> +}
> +
> +static int cdns_hdptx_hdmi_configure(struct phy *phy,
> +				     union phy_configure_opts *opts)
> +{
> +	struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
> +	int ret;
> +
> +	cdns_phy->pixel_clk_rate = opts->hdmi.pixel_clk_rate;
> +	cdns_phy->color_space = opts->hdmi.color_space;
> +	cdns_phy->bpc = opts->hdmi.bpc;
> +
> +	/* Check HDMI FW alive before HDMI PHY init */
> +	ret = hdptx_phy_check_alive(cdns_phy);
> +	if (!ret) {
> +		dev_err(cdns_phy->dev, "NO HDMI FW running\n");
> +		return -ENXIO;
> +	}
> +
> +	/* Configure PHY */
> +	if (hdptx_hdmi_phy_cfg(cdns_phy, cdns_phy->pixel_clk_rate) < 0) {
> +		dev_err(cdns_phy->dev, "failed to set phy pclock\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = hdptx_hdmi_phy_power_up(cdns_phy);
> +	if (ret < 0)
> +		return ret;
> +
> +	hdptx_hdmi_phy_set_vswing(cdns_phy);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops cdns_hdptx_hdmi_phy_ops = {
> +	.init = cdns_hdptx_hdmi_phy_init,
> +	.configure = cdns_hdptx_hdmi_configure,
> +	.power_on = cdns_hdptx_hdmi_phy_on,
> +	.power_off = cdns_hdptx_hdmi_phy_off,
> +	.validate = cdns_hdptx_hdmi_phy_valid,
> +	.owner = THIS_MODULE,
> +};
> +
> +static int cdns_hdptx_hdmi_phy_probe(struct platform_device *pdev)
> +{
> +	struct cdns_hdptx_hdmi_phy *cdns_phy;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *node = dev->of_node;
> +	struct phy_provider *phy_provider;
> +	struct resource *res;
> +	struct phy *phy;
> +	int ret;
> +
> +	cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
> +	if (!cdns_phy)
> +		return -ENOMEM;
> +
> +	dev_set_drvdata(dev, cdns_phy);
> +	cdns_phy->dev = dev;
> +	mutex_init(&cdns_phy->mbox_mutex);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -ENODEV;
> +	cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res));
> +	if (IS_ERR(cdns_phy->regs))
> +		return PTR_ERR(cdns_phy->regs);
> +
> +	phy = devm_phy_create(dev, node, &cdns_hdptx_hdmi_phy_ops);
> +	if (IS_ERR(phy))
> +		return PTR_ERR(phy);
> +
> +	phy->attrs.mode = PHY_MODE_HDMI;
> +
> +	cdns_phy->phy = phy;
> +	phy_set_drvdata(phy, cdns_phy);
> +
> +	/* init base struct for access mhdp mailbox */
> +	cdns_phy->base.dev = cdns_phy->dev;
> +	cdns_phy->base.regs = cdns_phy->regs;
> +	cdns_phy->base.mbox_mutex = &cdns_phy->mbox_mutex;
> +
> +	ret = hdptx_hdmi_clk_enable(cdns_phy);
> +	if (ret) {
> +		dev_err(dev, "Init clk fail\n");
> +		return -EINVAL;
> +	}
> +
> +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +	if (IS_ERR(phy_provider)) {
> +		ret = PTR_ERR(phy_provider);
> +		goto clk_disable;
> +	}
> +
> +	dev_dbg(dev, "probe success!\n");
> +
> +	return 0;
> +
> +clk_disable:
> +	hdptx_hdmi_clk_disable(cdns_phy);
> +
> +	return -EINVAL;
> +}
> +
> +static int cdns_hdptx_hdmi_phy_remove(struct platform_device *pdev)
> +{
> +	struct cdns_hdptx_hdmi_phy *cdns_phy = platform_get_drvdata(pdev);
> +
> +	hdptx_hdmi_clk_disable(cdns_phy);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id cdns_hdptx_hdmi_phy_of_match[] = {
> +	{.compatible = "fsl,imx8mq-hdmi-phy" },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, cdns_hdptx_hdmi_phy_of_match);
> +
> +static struct platform_driver cdns_hdptx_hdmi_phy_driver = {
> +	.probe = cdns_hdptx_hdmi_phy_probe,
> +	.remove = cdns_hdptx_hdmi_phy_remove,
> +	.driver = {
> +		.name	= "cdns-hdptx-hdmi-phy",
> +		.of_match_table	= cdns_hdptx_hdmi_phy_of_match,
> +	}
> +};
> +module_platform_driver(cdns_hdptx_hdmi_phy_driver);
> +
> +MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
> +MODULE_DESCRIPTION("Cadence HDP-TX HDMI PHY driver");
> +MODULE_LICENSE("GPL");
> 


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From peter.griffin at linaro.org  Tue Feb 20 02:43:27 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 20 Feb 2024 10:43:27 +0000
Subject: [PATCH v4 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <d25a887e-801d-410b-9ccd-2ec10fb28f23@linaro.org>
References: <20240208161700.268570-1-peter.griffin@linaro.org>
 <20240208161700.268570-2-peter.griffin@linaro.org> <ab1f9285-73ba-4b69-8882-0cf08c508e28@linaro.org>
 <CADrjBPqw9E5foNvZ-ETFZR3mb8=x8CYHz3UUhfJUbBpOi3iKYw@mail.gmail.com> <d25a887e-801d-410b-9ccd-2ec10fb28f23@linaro.org>
Message-ID: <CADrjBPp9A2eYbE+tRxfOe7MPaNa0uW+=6OzWbQeu2En=VoA0iA@mail.gmail.com>

Hi Krzysztof,

On Tue, 20 Feb 2024 at 06:56, Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 19/02/2024 20:47, Peter Griffin wrote:
> >>
> >>> +
> >>> +     if (property)
> >>> +             pmu_np = of_parse_phandle(np, property, 0);
> >>> +     else
> >>> +             pmu_np = np;
> >>> +
> >>> +     if (!pmu_np)
> >>> +             return ERR_PTR(-ENODEV);
> >>> +
> >>> +     /*
> >>> +      * Determine if exynos-pmu device has probed and therefore regmap
> >>> +      * has been created and can be returned to the caller. Otherwise we
> >>> +      * return -EPROBE_DEFER.
> >>> +      */
> >>> +     dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
> >>> +                                         (void *)pmu_np);
> >>> +
> >>> +     of_node_put(pmu_np);
> >>
> >> You are dropping now referencen from np when property==NULL. This does
> >> no look right.
> >
> > Good spot, will fix. It seems syscon.c and altera-sysmgr also have the
> > same issue.
> >
>
> Do you plan on fixing them as well in such case?

Yes I'll send some patches to fix syscon and altera-sysmgr as well.

Thanks,

Peter


From noname.nuno at gmail.com  Tue Feb 20 02:45:55 2024
From: noname.nuno at gmail.com (Nuno =?ISO-8859-1?Q?S=E1?=)
Date: Tue, 20 Feb 2024 11:45:55 +0100
Subject: [PATCH v2 4/5] spi: axi-spi-engine: move message compile to
 optimize_message
In-Reply-To: <20240219-mainline-spi-precook-message-v2-4-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
	 <20240219-mainline-spi-precook-message-v2-4-4a762c6701b9@baylibre.com>
Message-ID: <d5fcd8b83f424bc05d8363210632bf8db4c376cb.camel@gmail.com>

On Mon, 2024-02-19 at 16:33 -0600, David Lechner wrote:
> In the AXI SPI Engine driver, compiling the message is an expensive
> operation. Previously, it was done per message transfer in the
> prepare_message hook. This patch moves the message compile to the
> optimize_message hook so that it is only done once per message in
> cases where the peripheral driver calls spi_optimize_message().
> 
> This can be a significant performance improvement for some peripherals.
> For example, the ad7380 driver saw a 13% improvement in throughput
> when using the AXI SPI Engine driver with this patch.
> 
> Since we now need two message states, one for the optimization stage
> that doesn't change for the lifetime of the message and one that is
> reset on each transfer for managing the current transfer state, the old
> msg->state is split into msg->opt_state and spi_engine->msg_state. The
> latter is included in the driver struct now since there is only one
> current message at a time that can ever use it and it is in a hot path
> so avoiding allocating a new one on each message transfer saves a few
> cpu cycles and lets us get rid of the prepare_message callback.
> 
> Signed-off-by: David Lechner <dlechner at baylibre.com>
> ---

Reviewed-by: Nuno Sa <nuno.sa at analog.com>

> 
> v2 changes: none
> 
> ?drivers/spi/spi-axi-spi-engine.c | 40 +++++++++++++++++-----------------------
> ?1 file changed, 17 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c
> index ca66d202f0e2..6177c1a8d56e 100644
> --- a/drivers/spi/spi-axi-spi-engine.c
> +++ b/drivers/spi/spi-axi-spi-engine.c
> @@ -109,6 +109,7 @@ struct spi_engine {
> ?	spinlock_t lock;
> ?
> ?	void __iomem *base;
> +	struct spi_engine_message_state msg_state;
> ?	struct completion msg_complete;
> ?	unsigned int int_enable;
> ?};
> @@ -499,17 +500,11 @@ static irqreturn_t spi_engine_irq(int irq, void *devid)
> ?	return IRQ_HANDLED;
> ?}
> ?
> -static int spi_engine_prepare_message(struct spi_controller *host,
> -				????? struct spi_message *msg)
> +static int spi_engine_optimize_message(struct spi_message *msg)
> ?{
> ?	struct spi_engine_program p_dry, *p;
> -	struct spi_engine_message_state *st;
> ?	size_t size;
> ?
> -	st = kzalloc(sizeof(*st), GFP_KERNEL);
> -	if (!st)
> -		return -ENOMEM;
> -
> ?	spi_engine_precompile_message(msg);
> ?
> ?	p_dry.length = 0;
> @@ -517,31 +512,22 @@ static int spi_engine_prepare_message(struct spi_controller
> *host,
> ?
> ?	size = sizeof(*p->instructions) * (p_dry.length + 1);
> ?	p = kzalloc(sizeof(*p) + size, GFP_KERNEL);
> -	if (!p) {
> -		kfree(st);
> +	if (!p)
> ?		return -ENOMEM;
> -	}
> ?
> ?	spi_engine_compile_message(msg, false, p);
> ?
> ?	spi_engine_program_add_cmd(p, false, SPI_ENGINE_CMD_SYNC(
> ?						AXI_SPI_ENGINE_CUR_MSG_SYNC_ID));
> ?
> -	st->p = p;
> -	st->cmd_buf = p->instructions;
> -	st->cmd_length = p->length;
> -	msg->state = st;
> +	msg->opt_state = p;
> ?
> ?	return 0;
> ?}
> ?
> -static int spi_engine_unprepare_message(struct spi_controller *host,
> -					struct spi_message *msg)
> +static int spi_engine_unoptimize_message(struct spi_message *msg)
> ?{
> -	struct spi_engine_message_state *st = msg->state;
> -
> -	kfree(st->p);
> -	kfree(st);
> +	kfree(msg->opt_state);
> ?
> ?	return 0;
> ?}
> @@ -550,10 +536,18 @@ static int spi_engine_transfer_one_message(struct
> spi_controller *host,
> ?	struct spi_message *msg)
> ?{
> ?	struct spi_engine *spi_engine = spi_controller_get_devdata(host);
> -	struct spi_engine_message_state *st = msg->state;
> +	struct spi_engine_message_state *st = &spi_engine->msg_state;
> +	struct spi_engine_program *p = msg->opt_state;
> ?	unsigned int int_enable = 0;
> ?	unsigned long flags;
> ?
> +	/* reinitialize message state for this transfer */
> +	memset(st, 0, sizeof(*st));
> +	st->p = p;
> +	st->cmd_buf = p->instructions;
> +	st->cmd_length = p->length;
> +	msg->state = st;
> +
> ?	reinit_completion(&spi_engine->msg_complete);
> ?
> ?	spin_lock_irqsave(&spi_engine->lock, flags);
> @@ -658,8 +652,8 @@ static int spi_engine_probe(struct platform_device *pdev)
> ?	host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
> ?	host->max_speed_hz = clk_get_rate(spi_engine->ref_clk) / 2;
> ?	host->transfer_one_message = spi_engine_transfer_one_message;
> -	host->prepare_message = spi_engine_prepare_message;
> -	host->unprepare_message = spi_engine_unprepare_message;
> +	host->optimize_message = spi_engine_optimize_message;
> +	host->unoptimize_message = spi_engine_unoptimize_message;
> ?	host->num_chipselect = 8;
> ?
> ?	if (host->max_speed_hz == 0)
> 



From s-vadapalli at ti.com  Tue Feb 20 02:50:06 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Tue, 20 Feb 2024 16:20:06 +0530
Subject: [PATCH] arm64: dts: ti: k3-j721e-evm-pcie0-ep: Extend overlay for PCIE1 in EP Mode
Message-ID: <20240220105006.1056824-1-s-vadapalli@ti.com>

Update the existing overlay which configures PCIE0 instance of PCIe on
J721E-EVM in Endpoint mode of operation, in order to configure PCIE1
instance of PCIe as well in Endpoint mode of operation. Hence, change the
name of the overlay to reflect its updated functionality.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

Hello,

This patch is based on linux-next tagged next-20240220.

Regards,
Siddharth.

 arch/arm64/boot/dts/ti/Makefile               |  8 ++---
 ....dtso => k3-j721e-evm-pcie0-pcie1-ep.dtso} | 30 +++++++++++++++++--
 2 files changed, 32 insertions(+), 6 deletions(-)
 rename arch/arm64/boot/dts/ti/{k3-j721e-evm-pcie0-ep.dtso => k3-j721e-evm-pcie0-pcie1-ep.dtso} (60%)

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index d601c52ab181..c7c9508e3980 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -75,7 +75,7 @@ k3-j721e-evm-dtbs := k3-j721e-common-proc-board.dtb k3-j721e-evm-quad-port-eth-e
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi-exp-board.dtbo
-dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-pcie1-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-dual-imx219.dtbo
 
@@ -126,8 +126,8 @@ k3-am68-sk-base-board-csi2-dual-imx219-dtbs := k3-am68-sk-base-board.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtbo
-k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
-	k3-j721e-evm-pcie0-ep.dtbo
+k3-j721e-evm-pcie0-pcie1-ep-dtbs := k3-j721e-common-proc-board.dtb \
+	k3-j721e-evm-pcie0-pcie1-ep.dtbo
 k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
@@ -147,7 +147,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
 	k3-am68-sk-base-board-csi2-dual-imx219-dtbs \
 	k3-am69-sk-csi2-dual-imx219-dtbs \
-	k3-j721e-evm-pcie0-ep.dtb \
+	k3-j721e-evm-pcie0-pcie1-ep.dtb \
 	k3-j721e-sk-csi2-dual-imx219-dtbs \
 	k3-j721s2-evm-pcie1-ep.dtb
 
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-pcie1-ep.dtso
similarity index 60%
rename from arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso
rename to arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-pcie1-ep.dtso
index 4062709d6579..5eaf304e3102 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-pcie1-ep.dtso
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only OR MIT
 /**
- * DT Overlay for enabling PCIE0 instance in Endpoint Configuration with the
- * J7 common processor board.
+ * DT Overlay for enabling PCIE0 and PCIE1 instances in Endpoint Configuration
+ * with the J7 common processor board.
  *
  * J7 Common Processor Board Product Link: https://www.ti.com/tool/J721EXCPXEVM
  *
@@ -24,6 +24,10 @@ &pcie0_rc {
 	status = "disabled";
 };
 
+&pcie1_rc {
+	status = "disabled";
+};
+
 &cbass_main {
 	#address-cells = <2>;
 	#size-cells = <2>;
@@ -50,4 +54,26 @@ pcie0_ep: pcie-ep at 2900000 {
 		phys = <&serdes0_pcie_link>;
 		phy-names = "pcie-phy";
 	};
+
+	pcie1_ep: pcie-ep at 2910000 {
+		compatible = "ti,j721e-pcie-ep";
+		reg = <0x00 0x02910000 0x00 0x1000>,
+		      <0x00 0x02917000 0x00 0x400>,
+		      <0x00 0x0d800000 0x00 0x00800000>,
+		      <0x00 0x18000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
+		ti,syscon-pcie-ctrl = <&scm_conf 0x4074>;
+		max-link-speed = <3>;
+		num-lanes = <2>;
+		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 240 1>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes1_pcie_link>;
+		phy-names = "pcie-phy";
+	};
 };
-- 
2.34.1



From noname.nuno at gmail.com  Tue Feb 20 02:50:40 2024
From: noname.nuno at gmail.com (Nuno =?ISO-8859-1?Q?S=E1?=)
Date: Tue, 20 Feb 2024 11:50:40 +0100
Subject: [PATCH v2 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <20240219-mainline-spi-precook-message-v2-1-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
	 <20240219-mainline-spi-precook-message-v2-1-4a762c6701b9@baylibre.com>
Message-ID: <42bc659ddda05f3d4ece7e4a65e4548da17d17ad.camel@gmail.com>

On Mon, 2024-02-19 at 16:33 -0600, David Lechner wrote:
> This adds a new spi_optimize_message() function that can be used to
> optimize SPI messages that are used more than once. Peripheral drivers
> that use the same message multiple times can use this API to perform SPI
> message validation and controller-specific optimizations once and then
> reuse the message while avoiding the overhead of revalidating the
> message on each spi_(a)sync() call.
> 
> Internally, the SPI core will also call this function for each message
> if the peripheral driver did not explicitly call it. This is done to so
> that controller drivers don't have to have multiple code paths for
> optimized and non-optimized messages.
> 
> A hook is provided for controller drivers to perform controller-specific
> optimizations.
> 
> Suggested-by: Martin Sperl <kernel at martin.sperl.org>
> Link:
> https://lore.kernel.org/linux-spi/39DEC004-10A1-47EF-9D77-276188D2580C at martin.sperl.org/
> Signed-off-by: David Lechner <dlechner at baylibre.com>
> ---

Acked-by: Nuno Sa <nuno.sa at analog.com>

> 
> v2 changes:
> - Removed pre_optimized parameter from __spi_optimize_message()
> - Added comment explaining purpose of pre_optimized flag
> - Fixed missing doc comment for @pre_optimized
> - Removed kernel doc inclusion (/** -> /*) from static members
> - Removed unrelated comment about calling spi_finalize_current_message()
> 
> ?drivers/spi/spi.c?????? | 151 ++++++++++++++++++++++++++++++++++++++++++++++--
> ?include/linux/spi/spi.h |? 20 +++++++
> ?2 files changed, 167 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index c2b10e2c75f0..f68d92b57543 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -2106,6 +2106,41 @@ struct spi_message *spi_get_next_queued_message(struct
> spi_controller *ctlr)
> ?}
> ?EXPORT_SYMBOL_GPL(spi_get_next_queued_message);
> ?
> +/*
> + * __spi_unoptimize_message - shared implementation of spi_unoptimize_message()
> + *??????????????????????????? and spi_maybe_unoptimize_message()
> + * @msg: the message to unoptimize
> + *
> + * Peripheral drivers should use spi_unoptimize_message() and callers inside
> + * core should use spi_maybe_unoptimize_message() rather than calling this
> + * function directly.
> + *
> + * It is not valid to call this on a message that is not currently optimized.
> + */
> +static void __spi_unoptimize_message(struct spi_message *msg)
> +{
> +	struct spi_controller *ctlr = msg->spi->controller;
> +
> +	if (ctlr->unoptimize_message)
> +		ctlr->unoptimize_message(msg);
> +
> +	msg->optimized = false;
> +	msg->opt_state = NULL;
> +}
> +
> +/*
> + * spi_maybe_unoptimize_message - unoptimize msg not managed by a peripheral
> + * @msg: the message to unoptimize
> + *
> + * This function is used to unoptimize a message if and only if it was
> + * optimized by the core (via spi_maybe_optimize_message()).
> + */
> +static void spi_maybe_unoptimize_message(struct spi_message *msg)
> +{
> +	if (!msg->pre_optimized && msg->optimized)
> +		__spi_unoptimize_message(msg);
> +}
> +
> ?/**
> ? * spi_finalize_current_message() - the current message is complete
> ? * @ctlr: the controller to return the message to
> @@ -2153,6 +2188,8 @@ void spi_finalize_current_message(struct spi_controller
> *ctlr)
> ?
> ?	mesg->prepared = false;
> ?
> +	spi_maybe_unoptimize_message(mesg);
> +
> ?	WRITE_ONCE(ctlr->cur_msg_incomplete, false);
> ?	smp_mb(); /* See __spi_pump_transfer_message()... */
> ?	if (READ_ONCE(ctlr->cur_msg_need_completion))
> @@ -4194,6 +4231,110 @@ static int __spi_validate(struct spi_device *spi, struct
> spi_message *message)
> ?	return 0;
> ?}
> ?
> +/*
> + * __spi_optimize_message - shared implementation for spi_optimize_message()
> + *????????????????????????? and spi_maybe_optimize_message()
> + * @spi: the device that will be used for the message
> + * @msg: the message to optimize
> + *
> + * Peripheral drivers will call spi_optimize_message() and the spi core will
> + * call spi_maybe_optimize_message() instead of calling this directly.
> + *
> + * It is not valid to call this on a message that has already been optimized.
> + *
> + * Return: zero on success, else a negative error code
> + */
> +static int __spi_optimize_message(struct spi_device *spi,
> +				? struct spi_message *msg)
> +{
> +	struct spi_controller *ctlr = spi->controller;
> +	int ret;
> +
> +	ret = __spi_validate(spi, msg);
> +	if (ret)
> +		return ret;
> +
> +	if (ctlr->optimize_message) {
> +		ret = ctlr->optimize_message(msg);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	msg->optimized = true;
> +
> +	return 0;
> +}
> +
> +/*
> + * spi_maybe_optimize_message - optimize message if it isn't already pre-optimized
> + * @spi: the device that will be used for the message
> + * @msg: the message to optimize
> + * Return: zero on success, else a negative error code
> + */
> +static int spi_maybe_optimize_message(struct spi_device *spi,
> +				????? struct spi_message *msg)
> +{
> +	if (msg->pre_optimized)
> +		return 0;
> +
> +	return __spi_optimize_message(spi, msg);
> +}
> +
> +/**
> + * spi_optimize_message - do any one-time validation and setup for a SPI message
> + * @spi: the device that will be used for the message
> + * @msg: the message to optimize
> + *
> + * Peripheral drivers that reuse the same message repeatedly may call this to
> + * perform as much message prep as possible once, rather than repeating it each
> + * time a message transfer is performed to improve throughput and reduce CPU
> + * usage.
> + *
> + * Once a message has been optimized, it cannot be modified with the exception
> + * of updating the contents of any xfer->tx_buf (the pointer can't be changed,
> + * only the data in the memory it points to).
> + *
> + * Calls to this function must be balanced with calls to spi_unoptimize_message()
> + * to avoid leaking resources.
> + *
> + * Context: can sleep
> + * Return: zero on success, else a negative error code
> + */
> +int spi_optimize_message(struct spi_device *spi, struct spi_message *msg)
> +{
> +	int ret;
> +
> +	ret = __spi_optimize_message(spi, msg);
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * This flag indicates that the peripheral driver called
> spi_optimize_message()
> +	 * and therefore we shouldn't unoptimize message automatically when
> finalizing
> +	 * the message but rather wait until spi_unoptimize_message() is called
> +	 * by the peripheral driver.
> +	 */
> +	msg->pre_optimized = true;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(spi_optimize_message);
> +
> +/**
> + * spi_unoptimize_message - releases any resources allocated by
> spi_optimize_message()
> + * @msg: the message to unoptimize
> + *
> + * Calls to this function must be balanced with calls to spi_optimize_message().
> + *
> + * Context: can sleep
> + */
> +void spi_unoptimize_message(struct spi_message *msg)
> +{
> +	__spi_unoptimize_message(msg);
> +	msg->pre_optimized = false;
> +}
> +EXPORT_SYMBOL_GPL(spi_unoptimize_message);
> +
> ?static int __spi_async(struct spi_device *spi, struct spi_message *message)
> ?{
> ?	struct spi_controller *ctlr = spi->controller;
> @@ -4258,8 +4399,8 @@ int spi_async(struct spi_device *spi, struct spi_message
> *message)
> ?	int ret;
> ?	unsigned long flags;
> ?
> -	ret = __spi_validate(spi, message);
> -	if (ret != 0)
> +	ret = spi_maybe_optimize_message(spi, message);
> +	if (ret)
> ?		return ret;
> ?
> ?	spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags);
> @@ -4271,6 +4412,8 @@ int spi_async(struct spi_device *spi, struct spi_message
> *message)
> ?
> ?	spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags);
> ?
> +	spi_maybe_unoptimize_message(message);
> +
> ?	return ret;
> ?}
> ?EXPORT_SYMBOL_GPL(spi_async);
> @@ -4331,8 +4474,8 @@ static int __spi_sync(struct spi_device *spi, struct
> spi_message *message)
> ?		return -ESHUTDOWN;
> ?	}
> ?
> -	status = __spi_validate(spi, message);
> -	if (status != 0)
> +	status = spi_maybe_optimize_message(spi, message);
> +	if (status)
> ?		return status;
> ?
> ?	SPI_STATISTICS_INCREMENT_FIELD(ctlr->pcpu_statistics, spi_sync);
> diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
> index 2b8e2746769a..ddfb66dd4caf 100644
> --- a/include/linux/spi/spi.h
> +++ b/include/linux/spi/spi.h
> @@ -475,6 +475,8 @@ extern struct spi_device *spi_new_ancillary_device(struct
> spi_device *spi, u8 ch
> ? *
> ? * @set_cs: set the logic level of the chip select line.? May be called
> ? *????????? from interrupt context.
> + * @optimize_message: optimize the message for reuse
> + * @unoptimize_message: release resources allocated by optimize_message
> ? * @prepare_message: set up the controller to transfer a single message,
> ? *?????????????????? for example doing DMA mapping.? Called from threaded
> ? *?????????????????? context.
> @@ -715,6 +717,8 @@ struct spi_controller {
> ?	struct completion?????????????? xfer_completion;
> ?	size_t				max_dma_len;
> ?
> +	int (*optimize_message)(struct spi_message *msg);
> +	int (*unoptimize_message)(struct spi_message *msg);
> ?	int (*prepare_transfer_hardware)(struct spi_controller *ctlr);
> ?	int (*transfer_one_message)(struct spi_controller *ctlr,
> ?				??? struct spi_message *mesg);
> @@ -1111,6 +1115,8 @@ struct spi_transfer {
> ? * @spi: SPI device to which the transaction is queued
> ? * @is_dma_mapped: if true, the caller provided both DMA and CPU virtual
> ? *	addresses for each transfer buffer
> + * @pre_optimized: peripheral driver pre-optimized the message
> + * @optimized: the message is in the optimized state
> ? * @prepared: spi_prepare_message was called for the this message
> ? * @status: zero for success, else negative errno
> ? * @complete: called to report transaction completions
> @@ -1120,6 +1126,7 @@ struct spi_transfer {
> ? *	successful segments
> ? * @queue: for use by whichever driver currently owns the message
> ? * @state: for use by whichever driver currently owns the message
> + * @opt_state: for use by whichever driver currently owns the message
> ? * @resources: for resource management when the SPI message is processed
> ? *
> ? * A @spi_message is used to execute an atomic sequence of data transfers,
> @@ -1143,6 +1150,11 @@ struct spi_message {
> ?
> ?	unsigned		is_dma_mapped:1;
> ?
> +	/* spi_optimize_message() was called for this message */
> +	bool			pre_optimized;
> +	/* __spi_optimize_message() was called for this message */
> +	bool			optimized;
> +
> ?	/* spi_prepare_message() was called for this message */
> ?	bool			prepared;
> ?
> @@ -1172,6 +1184,11 @@ struct spi_message {
> ?	 */
> ?	struct list_head	queue;
> ?	void			*state;
> +	/*
> +	 * Optional state for use by controller driver between calls to
> +	 * __spi_optimize_message() and __spi_unoptimize_message().
> +	 */
> +	void			*opt_state;
> ?
> ?	/* List of spi_res resources when the SPI message is processed */
> ?	struct list_head??????? resources;
> @@ -1255,6 +1272,9 @@ static inline void spi_message_free(struct spi_message *m)
> ?	kfree(m);
> ?}
> ?
> +extern int spi_optimize_message(struct spi_device *spi, struct spi_message *msg);
> +extern void spi_unoptimize_message(struct spi_message *msg);
> +
> ?extern int spi_setup(struct spi_device *spi);
> ?extern int spi_async(struct spi_device *spi, struct spi_message *message);
> ?extern int spi_slave_abort(struct spi_device *spi);
> 



From pabeni at redhat.com  Tue Feb 20 02:51:00 2024
From: pabeni at redhat.com (Paolo Abeni)
Date: Tue, 20 Feb 2024 11:51:00 +0100
Subject: [PATCH] net: stmmac: mmc_core: Assign, don't add interrupt
 registers
In-Reply-To: <20240219104025.GM22484@axis.com>
References: <20240216-stmmac_stats-v1-1-7065fa4613f8@axis.com>
	 <61bdd802-abe4-4544-8e48-9493a6bb99c8@gmail.com>
	 <20240219104025.GM22484@axis.com>
Message-ID: <68a7dbd619a1a609f102a0786c37bc33c24cdbcd.camel@redhat.com>

On Mon, 2024-02-19 at 11:40 +0100, Jesper Nilsson wrote:
> On Fri, Feb 16, 2024 at 09:13:51AM -0800, Florian Fainelli wrote:
> > So in premise I agree with the patch, that incrementing those is not the
> > right way to go about them. However these registers are currently provided
> > as part of the statistics set, but they should instead be accessed via the
> > register dumping method.
> 
> You mean extending the dump register code to dump the MAC Management Counter
> registers that are not counters?
> > From what I understand it's only the Rx and Tx interrupt and interrupt mask
> registers that aren't counters. Oh, and the MMC control register itself?
> 
> To be honest, I don't think their use can justify the code churn.
> 
> > In either case you will get at best a snapshot of those two registers at any
> > given time and I suppose this can help diagnose a stuck RX condition, but
> > not much more than that.
> 
> Yeah, their use is very doubtful. For me, they only introduce more nonsense
> data in my logs.
> 
> The Rx registers looks to have been added in the first version of the MMC
> back in 2011, but the Tx registers never was.
> In commit 1c901a46d57 Giuseppe mentions the MMC interrupts as something to
> add later (if actually useful).
> 
> So Serge's suggestion to drop the entries completely is actually quite attractive.

Please, go ahead and drop such entries.

Thank!

Paolo



From jay.buddhabhatti at amd.com  Tue Feb 20 02:51:57 2024
From: jay.buddhabhatti at amd.com (Buddhabhatti, Jay)
Date: Tue, 20 Feb 2024 10:51:57 +0000
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
In-Reply-To: <202402192019160b9c4120@mail.local>
References: <202402192019160b9c4120@mail.local>
Message-ID: <DM6PR12MB4465FAF7AB3F9CE15FAC6C879D502@DM6PR12MB4465.namprd12.prod.outlook.com>

Hi Alexandre,

> -----Original Message-----
> From: Alexandre Belloni <alexandre.belloni at bootlin.com>
> Sent: Tuesday, February 20, 2024 1:49 AM
> To: Simek, Michal <michal.simek at amd.com>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>; linux-
> kernel at vger.kernel.org; monstr at monstr.eu; michal.simek at xilinx.com;
> git at xilinx.com; Conor Dooley <conor+dt at kernel.org>; Krzysztof Kozlowski
> <krzysztof.kozlowski+dt at linaro.org>; Rob Herring <robh at kernel.org>; open
> list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
> <devicetree at vger.kernel.org>; moderated list:ARM/ZYNQ ARCHITECTURE
> <linux-arm-kernel at lists.infradead.org>; open list:REAL TIME CLOCK (RTC)
> SUBSYSTEM <linux-rtc at vger.kernel.org>
> Subject: Re: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains
> property
> 
> On 19/02/2024 14:11:50+0100, Michal Simek wrote:
> >
> >
> > On 2/17/24 09:26, Krzysztof Kozlowski wrote:
> > > On 16/02/2024 10:42, Michal Simek wrote:
> > > >
> > > >
> > > > On 2/16/24 10:19, Krzysztof Kozlowski wrote:
> > > > > On 16/02/2024 09:51, Michal Simek wrote:
> > > > > > RTC has its own power domain on Xilinx Versal SOC that's why
> > > > > > describe it as optional property.
> > > > > >
> > > > > > Signed-off-by: Michal Simek <michal.simek at amd.com>
> > > > > > ---
> > > > > >
> > > > > >    Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml | 3
> +++
> > > > > >    1 file changed, 3 insertions(+)
> > > > > >
> > > > >
> > > > > But Versal is not described in this binding, is it? I see only
> > > > > one compatible.
> > > >
> > > > It is the same IP only as is on zynqmp with own power rail.
> > >
> > > Then you should have separate compatible, because they are not
> > > identical. It would also allow you to narrow the domains to versal
> > > and also require it (on versal).
> >
> > I can double check with HW guys but I am quite sure IP itself is
> > exactly the same. What it is different is that there is own power
> > domain to it (not shared one as is in zynqmp case).
> >
> > Also Linux is non secure sw and if secure firmware won't allow to
> > change setting of it it can't be required. I am just saying that Linux
> > doesn't need to be owner of any power domain that's why it shouldn't
> > be required property.
> 
> I guess because the integration is different, you still need a differente
> compatible so you can forbid the property on non-Versal.

[Jay] RTC has its own power domain in case of Versal and ZynqMP both that we double check it.

Thanks,
Jay
> 
> >
> > Thanks,
> > Michal
> 
> --
> Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel
> engineering https://bootlin.com



From noname.nuno at gmail.com  Tue Feb 20 02:52:59 2024
From: noname.nuno at gmail.com (Nuno =?ISO-8859-1?Q?S=E1?=)
Date: Tue, 20 Feb 2024 11:52:59 +0100
Subject: [PATCH v2 2/5] spi: move splitting transfers to
 spi_optimize_message()
In-Reply-To: <20240219-mainline-spi-precook-message-v2-2-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
	 <20240219-mainline-spi-precook-message-v2-2-4a762c6701b9@baylibre.com>
Message-ID: <f0ec7c23aabc531f609f57b5e7ffb0c00047dfc4.camel@gmail.com>

On Mon, 2024-02-19 at 16:33 -0600, David Lechner wrote:
> Splitting transfers is an expensive operation so we can potentially
> optimize it by doing it only once per optimization of the message
> instead of repeating each time the message is transferred.
> 
> The transfer splitting functions are currently the only user of
> spi_res_alloc() so spi_res_release() can be safely moved at this time
> from spi_finalize_current_message() to spi_unoptimize_message().
> 
> The doc comments of the public functions for splitting transfers are
> also updated so that callers will know when it is safe to call them
> to ensure proper resource management.
> 
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Signed-off-by: David Lechner <dlechner at baylibre.com>
> ---

Acked-by: Nuno Sa <nuno.sa at analog.com>

> 
> v2 changes:
> - Changed line break for multiline if condition
> - Removed kernel doc inclusion (/** -> /*) from static members
> - Picked up Jonathan's Reviewed-by
> 
> ?drivers/spi/spi.c | 110 +++++++++++++++++++++++++++++++++---------------------
> ?1 file changed, 68 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index f68d92b57543..ba4d3fde2054 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -1747,38 +1747,6 @@ static int __spi_pump_transfer_message(struct spi_controller
> *ctlr,
> ?
> ?	trace_spi_message_start(msg);
> ?
> -	/*
> -	 * If an SPI controller does not support toggling the CS line on each
> -	 * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO
> -	 * for the CS line, we can emulate the CS-per-word hardware function by
> -	 * splitting transfers into one-word transfers and ensuring that
> -	 * cs_change is set for each transfer.
> -	 */
> -	if ((msg->spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
> -					?????? spi_is_csgpiod(msg->spi))) {
> -		ret = spi_split_transfers_maxwords(ctlr, msg, 1);
> -		if (ret) {
> -			msg->status = ret;
> -			spi_finalize_current_message(ctlr);
> -			return ret;
> -		}
> -
> -		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
> -			/* Don't change cs_change on the last entry in the list */
> -			if (list_is_last(&xfer->transfer_list, &msg->transfers))
> -				break;
> -			xfer->cs_change = 1;
> -		}
> -	} else {
> -		ret = spi_split_transfers_maxsize(ctlr, msg,
> -						? spi_max_transfer_size(msg-
> >spi));
> -		if (ret) {
> -			msg->status = ret;
> -			spi_finalize_current_message(ctlr);
> -			return ret;
> -		}
> -	}
> -
> ?	if (ctlr->prepare_message) {
> ?		ret = ctlr->prepare_message(ctlr, msg);
> ?		if (ret) {
> @@ -2124,6 +2092,8 @@ static void __spi_unoptimize_message(struct spi_message *msg)
> ?	if (ctlr->unoptimize_message)
> ?		ctlr->unoptimize_message(msg);
> ?
> +	spi_res_release(ctlr, msg);
> +
> ?	msg->optimized = false;
> ?	msg->opt_state = NULL;
> ?}
> @@ -2169,15 +2139,6 @@ void spi_finalize_current_message(struct spi_controller
> *ctlr)
> ?
> ?	spi_unmap_msg(ctlr, mesg);
> ?
> -	/*
> -	 * In the prepare_messages callback the SPI bus has the opportunity
> -	 * to split a transfer to smaller chunks.
> -	 *
> -	 * Release the split transfers here since spi_map_msg() is done on
> -	 * the split transfers.
> -	 */
> -	spi_res_release(ctlr, mesg);
> -
> ?	if (mesg->prepared && ctlr->unprepare_message) {
> ?		ret = ctlr->unprepare_message(ctlr, mesg);
> ?		if (ret) {
> @@ -3819,6 +3780,10 @@ static int __spi_split_transfer_maxsize(struct
> spi_controller *ctlr,
> ? * @msg:?? the @spi_message to transform
> ? * @maxsize:? the maximum when to apply this
> ? *
> + * This function allocates resources that are automatically freed during the
> + * spi message unoptimize phase so this function should only be called from
> + * optimize_message callbacks.
> + *
> ? * Return: status of transformation
> ? */
> ?int spi_split_transfers_maxsize(struct spi_controller *ctlr,
> @@ -3857,6 +3822,10 @@ EXPORT_SYMBOL_GPL(spi_split_transfers_maxsize);
> ? * @msg:????? the @spi_message to transform
> ? * @maxwords: the number of words to limit each transfer to
> ? *
> + * This function allocates resources that are automatically freed during the
> + * spi message unoptimize phase so this function should only be called from
> + * optimize_message callbacks.
> + *
> ? * Return: status of transformation
> ? */
> ?int spi_split_transfers_maxwords(struct spi_controller *ctlr,
> @@ -4231,6 +4200,57 @@ static int __spi_validate(struct spi_device *spi, struct
> spi_message *message)
> ?	return 0;
> ?}
> ?
> +/*
> + * spi_split_transfers - generic handling of transfer splitting
> + * @msg: the message to split
> + *
> + * Under certain conditions, a SPI controller may not support arbitrary
> + * transfer sizes or other features required by a peripheral. This function
> + * will split the transfers in the message into smaller transfers that are
> + * supported by the controller.
> + *
> + * Controllers with special requirements not covered here can also split
> + * transfers in the optimize_message() callback.
> + *
> + * Context: can sleep
> + * Return: zero on success, else a negative error code
> + */
> +static int spi_split_transfers(struct spi_message *msg)
> +{
> +	struct spi_controller *ctlr = msg->spi->controller;
> +	struct spi_transfer *xfer;
> +	int ret;
> +
> +	/*
> +	 * If an SPI controller does not support toggling the CS line on each
> +	 * transfer (indicated by the SPI_CS_WORD flag) or we are using a GPIO
> +	 * for the CS line, we can emulate the CS-per-word hardware function by
> +	 * splitting transfers into one-word transfers and ensuring that
> +	 * cs_change is set for each transfer.
> +	 */
> +	if ((msg->spi->mode & SPI_CS_WORD) &&
> +	??? (!(ctlr->mode_bits & SPI_CS_WORD) || spi_is_csgpiod(msg->spi))) {
> +		ret = spi_split_transfers_maxwords(ctlr, msg, 1);
> +		if (ret)
> +			return ret;
> +
> +		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
> +			/* Don't change cs_change on the last entry in the list */
> +			if (list_is_last(&xfer->transfer_list, &msg->transfers))
> +				break;
> +
> +			xfer->cs_change = 1;
> +		}
> +	} else {
> +		ret = spi_split_transfers_maxsize(ctlr, msg,
> +						? spi_max_transfer_size(msg-
> >spi));
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> ?/*
> ? * __spi_optimize_message - shared implementation for spi_optimize_message()
> ? *????????????????????????? and spi_maybe_optimize_message()
> @@ -4254,10 +4274,16 @@ static int __spi_optimize_message(struct spi_device *spi,
> ?	if (ret)
> ?		return ret;
> ?
> +	ret = spi_split_transfers(msg);
> +	if (ret)
> +		return ret;
> +
> ?	if (ctlr->optimize_message) {
> ?		ret = ctlr->optimize_message(msg);
> -		if (ret)
> +		if (ret) {
> +			spi_res_release(ctlr, msg);
> ?			return ret;
> +		}
> ?	}
> ?
> ?	msg->optimized = true;
> 



From krzysztof.kozlowski at linaro.org  Tue Feb 20 02:53:22 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 11:53:22 +0100
Subject: [PATCH 07/16] clk: samsung: Pass actual clock controller base
 address to CPU_CLK()
In-Reply-To: <20240216223245.12273-8-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
 <20240216223245.12273-8-semen.protsenko@linaro.org>
Message-ID: <8c1f0a4f-8a8b-41e7-b7f1-4c5a38ec7c1a@linaro.org>

On 16/02/2024 23:32, Sam Protsenko wrote:
> The documentation for struct exynos_cpuclk says .ctrl_base field should
> contain the controller base address. But in reality all Exynos clock
> drivers are passing CPU_SRC register address via CPU_CLK() macro, which
> in turn gets assigned to mentioned .ctrl_base field. Because CPU_SRC
> address usually already has 0x200 offset from controller's base, all
> other register offsets in clk-cpu.c (like DIVs and MUXes) are specified
> as offsets from CPU_SRC offset, and not from controller's base. That
> makes things confusing and not consistent with register offsets provided
> in Exynis clock drivers, also breaking the contract for .ctrl_base field

Typo: Exynos

> as described in struct exynos_cpuclk doc. Rework all register offsets in
> clk-cpu.c to be actual offsets from controller's base, and fix offsets
> provided to CPU_CLK() macro in all Exynos clock drivers.

Change is fine and makes sense on devices having separate CPU clock
controller. That's not the case for:
1. Exynos3250: dedicated CPU clock controller space, but we merged it
into one driver/binding.
2. Exynos4 and 5250: no obvious dedicated CPU clock controller, but
register layout suggests that there is such, just not explicit.

In all these cases you provide not the correct offset against explicit
or implicit CPU base, but from main clock controller base.

Mention it briefly in above commit msg.


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 20 02:55:06 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 11:55:06 +0100
Subject: [PATCH 08/16] clk: samsung: Use clk.h as a single header for
 Samsung CCF
In-Reply-To: <20240216223245.12273-9-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
 <20240216223245.12273-9-semen.protsenko@linaro.org>
Message-ID: <96ded232-d6c8-48b2-a8f0-1714601ae516@linaro.org>

On 16/02/2024 23:32, Sam Protsenko wrote:
> Make both CPU and PLL clock headers to be included indirectly via clk.h.
> All Samsung clock drivers already include clk.h, which provides API for
> Samsung CCF clocks like muxes, gates, etc. Both CPU and PLL Samsung
> clock are not that different. It makes sense to only use both clk-cpu.h
> and clk-pll.h internally for Samsung CCF framework, and make clk.h the
> facade for Samsung CCF. This way all clock drivers only have to include
> clk.h.

Each header and unit file should include only what's necessary, so this
change is contradictory with basic rule.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 20 02:56:48 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 11:56:48 +0100
Subject: [PATCH 09/16] clk: samsung: Pass register layout type explicitly
 to CLK_CPU()
In-Reply-To: <20240216223245.12273-10-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
 <20240216223245.12273-10-semen.protsenko@linaro.org>
Message-ID: <25fde6ca-e1f4-4ca7-a534-efaae8a2a324@linaro.org>

On 16/02/2024 23:32, Sam Protsenko wrote:
> Make it more obvious which register layout should be used for a CPU
> clock. It prepares clk-cpu.c for adding new chips support.
> 
> No functional change.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  drivers/clk/samsung/clk-cpu.c        |  2 +-
>  drivers/clk/samsung/clk-cpu.h        | 12 ++++++++++--
>  drivers/clk/samsung/clk-exynos3250.c |  2 +-
>  drivers/clk/samsung/clk-exynos4.c    |  6 +++---
>  drivers/clk/samsung/clk-exynos5250.c |  3 ++-
>  drivers/clk/samsung/clk-exynos5420.c |  8 ++++----
>  drivers/clk/samsung/clk-exynos5433.c |  8 ++++----
>  drivers/clk/samsung/clk.h            |  4 +++-
>  8 files changed, 28 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
> index 4c46416281a3..21998c89b96d 100644
> --- a/drivers/clk/samsung/clk-cpu.c
> +++ b/drivers/clk/samsung/clk-cpu.c
> @@ -464,7 +464,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
>  	cpuclk->lock = &ctx->lock;
>  	cpuclk->flags = clk_data->flags;
>  	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
> -	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT) {
> +	if (clk_data->reg_layout == CPUCLK_LAYOUT_E5433) {

Why flags cannot work for it and we need one more property? The point of
flags is to customize the variant entirely. You basically split now
flags into flags A and flags B.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 20 03:04:33 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 12:04:33 +0100
Subject: [PATCH 11/16] clk: samsung: Keep register offsets in chip
 specific structure
In-Reply-To: <20240216223245.12273-12-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
 <20240216223245.12273-12-semen.protsenko@linaro.org>
Message-ID: <ce515530-428a-4a21-8c56-5a497cc8130a@linaro.org>

On 16/02/2024 23:32, Sam Protsenko wrote:
> Abstract CPU clock registers by keeping their offsets in a dedicated
> chip specific structure to accommodate for oncoming Exynos850 support,
> which has different offsets for cluster 0 and cluster 1. This rework
> also makes it possible to use exynos_set_safe_div() for all chips, so
> exynos5433_set_safe_div() is removed here to reduce the code
> duplication.
> 

So that's the answer why you could not use flags anymore - you need an
enum, not a bitmap. Such short explanation should be in previous commits
justifying moving reg layout to new property.

> No functional change.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  drivers/clk/samsung/clk-cpu.c | 156 +++++++++++++++++++---------------
>  1 file changed, 86 insertions(+), 70 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
> index 04394d2166c9..744b609c222d 100644
> --- a/drivers/clk/samsung/clk-cpu.c
> +++ b/drivers/clk/samsung/clk-cpu.c
> @@ -44,12 +44,14 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
>  
>  /**
>   * struct exynos_cpuclk_chip - Chip specific data for CPU clock
> + * @regs: register offsets for CPU related clocks
>   * @pre_rate_cb: callback to run before CPU clock rate change
>   * @post_rate_cb: callback to run after CPU clock rate change
>   */
>  struct exynos_cpuclk_chip {
> -	exynos_rate_change_fn_t	pre_rate_cb;
> -	exynos_rate_change_fn_t	post_rate_cb;
> +	const void				* const regs;

Why this is void?

> +	exynos_rate_change_fn_t			pre_rate_cb;
> +	exynos_rate_change_fn_t			post_rate_cb;
>  };
>  



Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 20 03:07:46 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Tue, 20 Feb 2024 12:07:46 +0100
Subject: [PATCH 00/16] clk: samsung: Add CPU clocks for Exynos850
In-Reply-To: <20240216223245.12273-1-semen.protsenko@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
Message-ID: <29090d97-9118-4765-a4fd-3bbe271a39bd@linaro.org>

On 16/02/2024 23:32, Sam Protsenko wrote:
> The series implements CPU clock support for Exynos850, adds CPU CMUs to
> the clock driver and enables those in dts. This is the first step
> towards cpufreq implementation.
> 
> The breakup by patch:
> 
>   * Patch 01: Add bindings
>   * Patches 02..12: Prepare clk-cpu.c for Exynos850 support
>   * Patch 13: Add Exynos850 support
>   * Patch 14: Init PLLs to be in manual mode
>   * Patch 15: Add CPU CMUs in Exynos850 clock driver
>   * Patch 16: Add CPU CMUs and clocks in Exynos850 dtsi

This crossed the threshold for a patch bomb, which is in general fine
for me, but then please put v2 changelog in each patch's changelog. If
the patch did not change, annotate it as well. It's not possible to keep
jumping between cover letter and individual patches.

Best regards,
Krzysztof



From martin.fuzzey at flowbird.group  Tue Feb 20 03:09:12 2024
From: martin.fuzzey at flowbird.group (Fuzzey, Martin)
Date: Tue, 20 Feb 2024 12:09:12 +0100
Subject: TI am625 deepsleep wakeup from main domain
In-Reply-To: <20240219151458.2gvc3n6sjt4nyj25@dhruva>
References: <CANh8Qzx-aratebzbkYGLiL+ij5MPmvfuzZtu70AL=9JgLjZ8tw@mail.gmail.com>
 <20240219151458.2gvc3n6sjt4nyj25@dhruva>
Message-ID: <CANh8QzwpvC7aJvbdphsiJKNUgETPpoQ5nVJy4+nVy_HV0DYyLA@mail.gmail.com>

Hi Dhruva,

Thank you *very* much for that.

TLDR: Enabling IO isolation indeed makes it work.

On Mon, 19 Feb 2024 at 16:15, Dhruva Gole <d-gole at ti.com> wrote:
>
> Yes, this is one of the missing pieces, but an even more important thing
> is io isolation is missing.
>
>
> >
> > I do get input events when not suspended (so that should eliminate bad
> > hardware) and have checked that the button GPIO line still has power
> > in suspend.
>
> Umm how have you checked that it has power in suspend, I'm not sure?
> The concept of IO daisychain is that GPIO controller itself WILL lose
> power, however the "pad" associated with that particular GPIO stays
> alive and has the ability to generate an interrupt to the DM which can
> trigger the resume.
>

I just meant that I put a scope on the IO line connected to the wakeup
button  end made sure I still got an edge when pressing it in suspend.
Of course that doesn't say anything about the power state of the GPIO
module in the SoC itself but does ensure there were no board level
power / regulator issues.

> >
> > Am I missing any other pieces here?
>
> The missing piece is the set_io_isolation [0]. I had removed that chunk
> of code from V7 because we couldn't arrive at a satisfactory conclusion
> as to where isolation should be set and removed. You can refer to V6 of
> the same patch series [1] for more context.
>
> Just for testing and if it's urgent, you can try and apply the V6 series
> and it may just work for you...  I don't currently have a -next branch
> with all of my patches applied otherwise would've shared.
> The patches thus may not cleanly apply and may need a bit of merge
> conflict resolutions.


I manually merged ti_sci_cmd_set_io_isolation() and its call from
ti_sci_suspend()
and ti_sci_resume() and that was enough.

>
> deepsleep. The DM will get the wake IRQ directly as long as linux has
> setup the wakeup source properly, which does seem to be the case
> according to what you've setup. You were only missing the io isolation
> bits most likely.
>

Yes indeed,
thanks again!

>
> I would also urge you to pick the latest boot binaries from ti-u-boot as
> there's strong dependency on the correct OPTEE, ATF, other firmwares
> that are all packaged as part of the boot bins. We hope to upstream the
> remaining few patches to u-boot soon.

Yes, for the benefit of the list here's my config

I'm using OPTEE from the TI 09.01.00.08 BSP (which is upstream 4.0.0 it seems).
It didn't work correctly with a locally built upstream 4.1.0 (no local
patches) - only one core came out of suspend.
Not sure if it's a problem with 4.1.0 or the way I'm building it.
I'll try the 4.0.0 tag with a local build but it's not that urgent from me.

ATF works with both the upstream v2.10.0 tag and the TI binary from
the BSP above.

The TI binary firmware is from tag 09.02.00.003

If it will all land in u-boot soon I'll likely wait for that.

Regards,

Martin


From brgl at bgdev.pl  Tue Feb 20 03:16:10 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 20 Feb 2024 12:16:10 +0100
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk> <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
 <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk>
Message-ID: <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>

On Mon, Feb 19, 2024 at 8:59?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Mon, Feb 19, 2024 at 07:48:20PM +0100, Bartosz Golaszewski wrote:
> > On Mon, Feb 19, 2024 at 7:03?PM Mark Brown <broonie at kernel.org> wrote:
> > > On Fri, Feb 16, 2024 at 09:32:06PM +0100, Bartosz Golaszewski wrote:
>
> > > > +                     vreg_pmu_aon_0p59: ldo1 {
> > > > +                             regulator-name = "vreg_pmu_aon_0p59";
> > > > +                             regulator-min-microvolt = <540000>;
> > > > +                             regulator-max-microvolt = <840000>;
> > > > +                     };
>
> > > That's a *very* wide voltage range for a supply that's got a name ending

Because it's an error, it should have been 640000. Thanks for spotting it.

> > > in _0_p59 which sounds a lot like it should be fixed at 0.59V.
> > > Similarly for a bunch of the other supplies, and I'm not seeing any
> > > evidence that the consumers do any voltage changes here?  There doesn't
> > > appear to be any logic here, I'm not convinced these are validated or
> > > safe constraints.
>
> > No, the users don't request any regulators (or rather: software
> > representations thereof) because - as per the cover letter - no
> > regulators are created by the PMU driver. This is what is physically
> > on the board - as the schematics and the datasheet define it. I took
>
> The above makes no sense.  How can constraints be "what is physically on
> the board", particularly variable constrants when there isn't even a
> consumer?  What values are you taking from which documentation?
>

The operating conditions for PMU outputs. I took them from a
confidential datasheet. There's a table for input constraints and
possible output values.

And what do you mean by there not being any consumers? The WLAN and BT
*are* the consumers.

> The cover letter and binding both claimed (buried after large amounts of
> changelog) that these PMUs were exposing regulators to consumers and the
> DTS puports to do exactly that...
>

Yes, but I'm not sure what the question is.

> > the values from the docs verbatim. In C, we create a power sequencing
> > provider which doesn't use the regulator framework at all.
>
> For something that doesn't use the regulator framework at all what
> appears to be a provider in patch 16 ("power: pwrseq: add a driver for
> the QCA6390 PMU module") seems to have a lot of regualtor API calls?

This driver is a power sequencing *provider* but also a regulator
*consumer*. It gets regulators from the host and exposes a power
sequencer to *its* consumers (WLAN and BT). On DT it exposes
regulators (LDO outputs of the PMU) but we don't instantiate them in
C.

Bart


From alexander.stein at ew.tq-group.com  Tue Feb 20 03:19:48 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 20 Feb 2024 12:19:48 +0100
Subject: [PATCH 1/1] phy: fsl-imx8mq-usb: make vbus regulator optional
Message-ID: <20240220111948.2227506-1-alexander.stein@ew.tq-group.com>

vbus-supply property is optional, so instead of allocating a
dummy regulator make it pure optional.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index 0b9a59d5b8f02..3af007b8e77f5 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -323,9 +323,11 @@ static int imx8mq_phy_power_on(struct phy *phy)
 	struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy);
 	int ret;
 
-	ret = regulator_enable(imx_phy->vbus);
-	if (ret)
-		return ret;
+	if (imx_phy->vbus) {
+		ret = regulator_enable(imx_phy->vbus);
+		if (ret)
+			return ret;
+	}
 
 	return clk_prepare_enable(imx_phy->clk);
 }
@@ -335,7 +337,8 @@ static int imx8mq_phy_power_off(struct phy *phy)
 	struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy);
 
 	clk_disable_unprepare(imx_phy->clk);
-	regulator_disable(imx_phy->vbus);
+	if (imx_phy->vbus)
+		regulator_disable(imx_phy->vbus);
 
 	return 0;
 }
@@ -392,8 +395,10 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev)
 	if (IS_ERR(imx_phy->phy))
 		return PTR_ERR(imx_phy->phy);
 
-	imx_phy->vbus = devm_regulator_get(dev, "vbus");
-	if (IS_ERR(imx_phy->vbus))
+	imx_phy->vbus = devm_regulator_get_optional(dev, "vbus");
+	if (PTR_ERR(imx_phy->vbus) == -ENODEV)
+		imx_phy->vbus = NULL;
+	else if (IS_ERR(imx_phy->vbus))
 		return dev_err_probe(dev, PTR_ERR(imx_phy->vbus), "failed to get vbus\n");
 
 	phy_set_drvdata(imx_phy->phy, imx_phy);
-- 
2.34.1



From joey.gouly at arm.com  Tue Feb 20 03:20:31 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 20 Feb 2024 11:20:31 +0000
Subject: [PATCH 01/13] KVM: arm64: Harden __ctxt_sys_reg() against
 out-of-range values
In-Reply-To: <20240219092014.783809-2-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
 <20240219092014.783809-2-maz@kernel.org>
Message-ID: <20240220112031.GA16168@e124191.cambridge.arm.com>

On Mon, Feb 19, 2024 at 09:20:02AM +0000, Marc Zyngier wrote:
> The unsuspecting kernel tinkerer can be easily confused into
> writing something that looks like this:
> 
> 	ikey.lo = __vcpu_sys_reg(vcpu, SYS_APIAKEYLO_EL1);
> 
> which seems vaguely sensible, until you realise that the second
> parameter is the encoding of a sysreg, and not the index into
> the vcpu sysreg file... Debugging what happens in this case is

type safety :(

> an interesting exercise in head<->wall interactions.
> 
> As they often say: "Any resemblance to actual persons, living
> or dead, or actual events is purely coincidental".
> 
> In order to save people's time, add some compile-time hardening
> that will at least weed out the "stupidly out of range" values.
> This will *not* catch anything that isn't a compile-time constant.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_host.h | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 181fef12e8e8..a5ec4c7d3966 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -895,7 +895,7 @@ struct kvm_vcpu_arch {
>   * Don't bother with VNCR-based accesses in the nVHE code, it has no
>   * business dealing with NV.
>   */
> -static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
> +static inline u64 *___ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)

When in doubt, add more underscores!

>  {
>  #if !defined (__KVM_NVHE_HYPERVISOR__)
>  	if (unlikely(cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
> @@ -905,6 +905,13 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
>  	return (u64 *)&ctxt->sys_regs[r];
>  }
>  
> +#define __ctxt_sys_reg(c,r)						\
> +	({								\
> +	    	BUILD_BUG_ON(__builtin_constant_p(r) &&			\
> +			     (r) >= NR_SYS_REGS);			\
> +		___ctxt_sys_reg(c, r);					\
> +	})

I'm assuming the extra macro layer is to try make __builtin_constant_p() as
effective as possible? Otherwise maybe it relies on the compiler inling the
___ctxt_sys_reg() function? 

> +
>  #define ctxt_sys_reg(c,r)	(*__ctxt_sys_reg(c,r))
>  
>  u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg);

Thanks,
Joey


From shradha.t at samsung.com  Tue Feb 20 00:40:44 2024
From: shradha.t at samsung.com (Shradha Todi)
Date: Tue, 20 Feb 2024 14:10:44 +0530
Subject: [PATCH v6 0/2] Add helper function to get and enable all bulk
 clocks
References: <CGME20240220084109epcas5p3dc6b95a0ed69b63e93f4aa0a6fc919fe@epcas5p3.samsung.com>
Message-ID: <20240220084046.23786-1-shradha.t@samsung.com>

Create a managed API wrapper to get all the bulk clocks and enable them
as it is a very common practice in many drivers. The second patch uses
this API to adapt to clk_bulk_* APIs in the exynos driver.
v1:
 - https://lore.kernel.org/lkml/20231009062216.6729-1-shradha.t at samsung.com/
v2:
 - https://lore.kernel.org/lkml/20231115065621.27014-1-shradha.t at samsung.com/
 - Addressed Manivannan's comments to improve patch
v3:
 - https://lore.kernel.org/all/20240110110115.56270-1-shradha.t at samsung.com/
 - Took Marek's suggestion to make a common bulk clk wrapper and use it in
   the exynos driver
v4:
 - https://lore.kernel.org/all/20240124103838.32478-1-shradha.t at samsung.com/
 - Addressed Alim and Manivannan's comments
 - Changed enabled->enable and disabled->disable in function name
 - Remove num_clks out parameter as it is not required by user
 - Removed exit callback and used function name directly in release
v5:
 - https://lore.kernel.org/lkml/20240213132751.46813-1-shradha.t at samsung.com/
 - Rephrased comments for better readability
v6:
 - Removed extra new line

Shradha Todi (2):
  clk: Provide managed helper to get and enable bulk clocks
  PCI: exynos: Adapt to clk_bulk_* APIs

 drivers/clk/clk-devres.c                | 40 ++++++++++++++++++
 drivers/pci/controller/dwc/pci-exynos.c | 54 ++-----------------------
 include/linux/clk.h                     | 22 ++++++++++
 3 files changed, 66 insertions(+), 50 deletions(-)

-- 
2.17.1



From shradha.t at samsung.com  Tue Feb 20 00:40:45 2024
From: shradha.t at samsung.com (Shradha Todi)
Date: Tue, 20 Feb 2024 14:10:45 +0530
Subject: [PATCH v6 1/2] clk: Provide managed helper to get and enable bulk
 clocks
In-Reply-To: <20240220084046.23786-1-shradha.t@samsung.com>
References: <20240220084046.23786-1-shradha.t@samsung.com>
	<CGME20240220084120epcas5p1e8980539667c3d9da20f49fc645d8f4c@epcas5p1.samsung.com>
Message-ID: <20240220084046.23786-2-shradha.t@samsung.com>

Provide a managed devm_clk_bulk* wrapper to get and enable all
bulk clocks in order to simplify drivers that keeps all clocks
enabled for the time of driver operation.

Suggested-by: Marek Szyprowski <m.szyprowski at samsung.com>
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/clk/clk-devres.c | 40 ++++++++++++++++++++++++++++++++++++++++
 include/linux/clk.h      | 22 ++++++++++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 4fb4fd4b06bd..cbbd2cc339c3 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -182,6 +182,46 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all);
 
+static void devm_clk_bulk_release_all_enable(struct device *dev, void *res)
+{
+	struct clk_bulk_devres *devres = res;
+
+	clk_bulk_disable_unprepare(devres->num_clks, devres->clks);
+	clk_bulk_put_all(devres->num_clks, devres->clks);
+}
+
+int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
+					      struct clk_bulk_data **clks)
+{
+	struct clk_bulk_devres *devres;
+	int ret;
+
+	devres = devres_alloc(devm_clk_bulk_release_all_enable,
+			      sizeof(*devres), GFP_KERNEL);
+	if (!devres)
+		return -ENOMEM;
+
+	ret = clk_bulk_get_all(dev, &devres->clks);
+	if (ret > 0) {
+		*clks = devres->clks;
+		devres->num_clks = ret;
+	} else {
+		devres_free(devres);
+		return ret;
+	}
+
+	ret = clk_bulk_prepare_enable(devres->num_clks, *clks);
+	if (!ret) {
+		devres_add(dev, devres);
+	} else {
+		clk_bulk_put_all(devres->num_clks, devres->clks);
+		devres_free(devres);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enable);
+
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
 	struct clk **c = res;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1ef013324237..a8e6b045b848 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -438,6 +438,22 @@ int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks,
 int __must_check devm_clk_bulk_get_all(struct device *dev,
 				       struct clk_bulk_data **clks);
 
+/**
+ * devm_clk_bulk_get_all_enable - Get and enable all clocks of the consumer (managed)
+ * @dev: device for clock "consumer"
+ * @clks: pointer to the clk_bulk_data table of consumer
+ *
+ * Returns success (0) or negative errno.
+ *
+ * This helper function allows drivers to get all clocks of the
+ * consumer and enables them in one operation with management.
+ * The clks will automatically be disabled and freed when the device
+ * is unbound.
+ */
+
+int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
+					      struct clk_bulk_data **clks);
+
 /**
  * devm_clk_get - lookup and obtain a managed reference to a clock producer.
  * @dev: device for clock "consumer"
@@ -960,6 +976,12 @@ static inline int __must_check devm_clk_bulk_get_all(struct device *dev,
 	return 0;
 }
 
+static inline int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
+						struct clk_bulk_data **clks)
+{
+	return 0;
+}
+
 static inline struct clk *devm_get_clk_from_child(struct device *dev,
 				struct device_node *np, const char *con_id)
 {
-- 
2.17.1



From shradha.t at samsung.com  Tue Feb 20 00:40:46 2024
From: shradha.t at samsung.com (Shradha Todi)
Date: Tue, 20 Feb 2024 14:10:46 +0530
Subject: [PATCH v6 2/2] PCI: exynos: Adapt to clk_bulk_* APIs
In-Reply-To: <20240220084046.23786-1-shradha.t@samsung.com>
References: <20240220084046.23786-1-shradha.t@samsung.com>
	<CGME20240220084125epcas5p28c6d886685006800fc26c11918d5d1dd@epcas5p2.samsung.com>
Message-ID: <20240220084046.23786-3-shradha.t@samsung.com>

There is no need to hardcode the clock info in the driver as driver can
rely on the devicetree to supply the clocks required for the functioning
of the peripheral. Get rid of the static clock info and obtain the
platform supplied clocks. All the clocks supplied is obtained and enabled
using the devm_clk_bulk_get_all_enable() API.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
---
 drivers/pci/controller/dwc/pci-exynos.c | 54 ++-----------------------
 1 file changed, 4 insertions(+), 50 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index ec5611005566..3234eb5be1fb 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -54,43 +54,11 @@
 struct exynos_pcie {
 	struct dw_pcie			pci;
 	void __iomem			*elbi_base;
-	struct clk			*clk;
-	struct clk			*bus_clk;
+	struct clk_bulk_data		*clks;
 	struct phy			*phy;
 	struct regulator_bulk_data	supplies[2];
 };
 
-static int exynos_pcie_init_clk_resources(struct exynos_pcie *ep)
-{
-	struct device *dev = ep->pci.dev;
-	int ret;
-
-	ret = clk_prepare_enable(ep->clk);
-	if (ret) {
-		dev_err(dev, "cannot enable pcie rc clock");
-		return ret;
-	}
-
-	ret = clk_prepare_enable(ep->bus_clk);
-	if (ret) {
-		dev_err(dev, "cannot enable pcie bus clock");
-		goto err_bus_clk;
-	}
-
-	return 0;
-
-err_bus_clk:
-	clk_disable_unprepare(ep->clk);
-
-	return ret;
-}
-
-static void exynos_pcie_deinit_clk_resources(struct exynos_pcie *ep)
-{
-	clk_disable_unprepare(ep->bus_clk);
-	clk_disable_unprepare(ep->clk);
-}
-
 static void exynos_pcie_writel(void __iomem *base, u32 val, u32 reg)
 {
 	writel(val, base + reg);
@@ -332,17 +300,9 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 	if (IS_ERR(ep->elbi_base))
 		return PTR_ERR(ep->elbi_base);
 
-	ep->clk = devm_clk_get(dev, "pcie");
-	if (IS_ERR(ep->clk)) {
-		dev_err(dev, "Failed to get pcie rc clock\n");
-		return PTR_ERR(ep->clk);
-	}
-
-	ep->bus_clk = devm_clk_get(dev, "pcie_bus");
-	if (IS_ERR(ep->bus_clk)) {
-		dev_err(dev, "Failed to get pcie bus clock\n");
-		return PTR_ERR(ep->bus_clk);
-	}
+	ret = devm_clk_bulk_get_all_enable(dev, &ep->clks);
+	if (ret < 0)
+		return ret;
 
 	ep->supplies[0].supply = "vdd18";
 	ep->supplies[1].supply = "vdd10";
@@ -351,10 +311,6 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = exynos_pcie_init_clk_resources(ep);
-	if (ret)
-		return ret;
-
 	ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies);
 	if (ret)
 		return ret;
@@ -369,7 +325,6 @@ static int exynos_pcie_probe(struct platform_device *pdev)
 
 fail_probe:
 	phy_exit(ep->phy);
-	exynos_pcie_deinit_clk_resources(ep);
 	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
 
 	return ret;
@@ -383,7 +338,6 @@ static int __exit exynos_pcie_remove(struct platform_device *pdev)
 	exynos_pcie_assert_core_reset(ep);
 	phy_power_off(ep->phy);
 	phy_exit(ep->phy);
-	exynos_pcie_deinit_clk_resources(ep);
 	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
 
 	return 0;
-- 
2.17.1



From m.shams at samsung.com  Tue Feb 20 02:12:27 2024
From: m.shams at samsung.com (Tamseel Shams)
Date: Tue, 20 Feb 2024 15:42:27 +0530
Subject: [PATCH v3] serial: samsung: honor fifosize from dts at first
References: <CGME20240220101235epcas5p16db3f82c8db1efd32299c48c875cdc87@epcas5p1.samsung.com>
Message-ID: <20240220101227.80741-1-m.shams@samsung.com>

Currently for platforms which passes UART fifosize from DT gets
override by local driver structure "s3c24xx_serial_drv_data",
which is not intended. Change the code to honor fifosize from
device tree at first.

Signed-off-by: Tamseel Shams <m.shams at samsung.com>
---
Change Log:
v1 -> v2:
Acknowledged Krzysztof's comments
Initialized "ret" variable

v2 -> v3:
intoduced new variable "fifosize_prop" to handle
return value from call of "of_property_read_u32"

 drivers/tty/serial/samsung_tty.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 71d17d804fda..745702ec8eda 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -1952,7 +1952,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	struct s3c24xx_uart_port *ourport;
 	int index = probe_index;
-	int ret, prop = 0;
+	int ret, prop = 0, fifosize_prop = 1;
 
 	if (np) {
 		ret = of_alias_get_id(np, "serial");
@@ -1990,8 +1990,8 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 	}
 
 	if (np) {
-		of_property_read_u32(np,
-			"samsung,uart-fifosize", &ourport->port.fifosize);
+		fifosize_prop = of_property_read_u32(np, "samsung,uart-fifosize",
+				&ourport->port.fifosize);
 
 		if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
 			switch (prop) {
@@ -2009,10 +2009,13 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (ourport->drv_data->fifosize[index])
-		ourport->port.fifosize = ourport->drv_data->fifosize[index];
-	else if (ourport->info->fifosize)
-		ourport->port.fifosize = ourport->info->fifosize;
+	if (fifosize_prop) {
+		if (ourport->drv_data->fifosize[index])
+			ourport->port.fifosize = ourport->drv_data->fifosize[index];
+		else if (ourport->info->fifosize)
+			ourport->port.fifosize = ourport->info->fifosize;
+	}
+
 	ourport->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_SAMSUNG_CONSOLE);
 
 	/*
-- 
2.17.1



From brgl at bgdev.pl  Tue Feb 20 03:22:42 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 20 Feb 2024 12:22:42 +0100
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for WCN7850
In-Reply-To: <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-15-brgl@bgdev.pl>
 <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk>
Message-ID: <CAMRc=MeUjKPS3ANE6=7WZ3kbbGAdyE8HeXFN=75Jp-pVyBaWrQ@mail.gmail.com>

On Mon, Feb 19, 2024 at 6:50?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Fri, Feb 16, 2024 at 09:32:11PM +0100, Bartosz Golaszewski wrote:
>
> > +static struct pci_pwrctl_wcn7850_vreg pci_pwrctl_wcn7850_vregs[] = {
> > +     {
> > +             .name = "vdd",
> > +             .load_uA = 16000,
> > +     },
>
> I know a bunch of the QC stuff includes these load numbers but are they
> actually doing anything constructive?  It keeps coming up that they're
> causing a bunch of work and it's not clear that they have any great
> effect on modern systems.
>

Yes, we have what is called a high-power mode and a low-power mode in
regulators and these values are used to determine which one to use.

> > +static int pci_pwrctl_wcn7850_power_on(struct pci_pwrctl_wcn7850_ctx *ctx)
> > +{
> > +     int ret;
> > +
> > +     ret = regulator_bulk_enable(ctx->pdata->num_vregs, ctx->regs);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = clk_prepare_enable(ctx->clk);
> > +     if (ret)
> > +             return ret;
>
> This won't disable the regulators on error.

Indeed. Thanks for catching this.

Bart


From alexandru.elisei at arm.com  Tue Feb 20 03:26:38 2024
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 20 Feb 2024 11:26:38 +0000
Subject: arm64 MTE tag storage reuse - alternatives to MIGRATE_CMA
Message-ID: <ZdSMbjGf2Fj98diT@raptor>

Hello,

This is a request to discuss alternatives to the current approach for
reusing the MTE tag storage memory for data allocations [1]. Each iteration
of the series uncovered new issues, the latest being that memory allocation
is being performed in atomic contexts [2]; I would like to start a
discussion regarding possible alternative, which would integrate better
with the memory management code.

This is a high level overview of the current approach:

 * Tag storage pages are put on the MIGRATE_CMA lists, meaning they can be
   used for data allocations like (almost) any other page in the system.

 * When a page is allocated as tagged, the corresponding tag storage is
   also allocated.

 * There's a static relationship between a page and the location in memory
   where its tags are stored. Because of this, if the corresponding tag
   storage is used for data, the tag storage page is migrated.

Although this is the most generic approach because tag storage pages are
treated like normal pages, it has some disadvantages:

 * HW KASAN (MTE in the kernel) cannot be used. The kernel allocates memory
   in atomic context, where migration is not possible.

 * Tag storage pages cannot be themselves tagged, and this means that all
   CMA pages, even those which aren't tag storage, cannot be used for
   tagged allocations.

 * Page migration is costly, and a process that uses MTE can experience
   measurable slowdowns if the tag storage it requires is in use for data.
   There might be ways to reduce this cost (by reducing the likelihood that
   tag storage pages are allocated), but it cannot be completely
   eliminated.

 * Worse yet, a userspace process can use a tag storage page in such a way
   that migration is effectively impossible [3],[4].  A malicious process
   can make use of this to prevent the allocation of tag storage for other
   processes in the system, leading to a degraded experience for the
   affected processes. Worst case scenario, progress becomes impossible for
   those processes.

One alternative approach I'm looking at right now is cleancache. Cleancache
was removed in v5.17 (commit 0a4ee518185e) because the only backend, the
tmem driver, had been removed earlier (in v5.3, commit 814bbf49dcd0).

With this approach, MTE tag storage would be implemented as a driver
backend for cleancache. When a tag storage page is needed for storing tags,
the page would simply be dropped from the cache (cleancache_get_page()
returns -1).

I believe this is a very good fit for tag storage reuse, because it allows
tag storage to be allocated even in atomic contexts, which enables MTE in
the kernel. As a bonus, all of the changes to MM from the current approach
wouldn't be needed, as tag storage allocation can be handled entirely in
set_ptes_at(), copy_*highpage() or arch_swap_restore().

Is this a viable approach that would be upstreamable? Are there other
solutions that I haven't considered? I'm very much open to any alternatives
that would make tag storage reuse viable.

[1] https://lore.kernel.org/all/20240125164256.4147-1-alexandru.elisei at arm.com/
[2] https://lore.kernel.org/all/CAMn1gO7M51QtxPxkRO3ogH1zasd2-vErWqoPTqGoPiEvr8Pvcw at mail.gmail.com/
[3] https://lore.kernel.org/linux-trace-kernel/4e7a4054-092c-4e34-ae00-0105d7c9343c at redhat.com/
[4] https://lore.kernel.org/linux-trace-kernel/92833873-cd70-44b0-9f34-f4ac11b9e498 at redhat.com/

Thanks,
Alex


From linux at armlinux.org.uk  Tue Feb 20 03:27:15 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 20 Feb 2024 11:27:15 +0000
Subject: [PATCH RFC v4 02/15] ACPI: processor: Register all CPUs from
 acpi_processor_get_info()
In-Reply-To: <CAJZ5v0iiJpUWq5GMSnKFWQTzn_bdwoQz9m=hDaXNg4Lj_ePF4g@mail.gmail.com>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk>
 <E1rVDmU-0027YP-Jz@rmk-PC.armlinux.org.uk>
 <CAJZ5v0iiJpUWq5GMSnKFWQTzn_bdwoQz9m=hDaXNg4Lj_ePF4g@mail.gmail.com>
Message-ID: <ZdSMk93c1I6x973h@shell.armlinux.org.uk>

On Thu, Feb 15, 2024 at 08:22:29PM +0100, Rafael J. Wysocki wrote:
> On Wed, Jan 31, 2024 at 5:50?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:
> > diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> > index cf7c1cca69dd..a68c475cdea5 100644
> > --- a/drivers/acpi/acpi_processor.c
> > +++ b/drivers/acpi/acpi_processor.c
> > @@ -314,6 +314,18 @@ static int acpi_processor_get_info(struct acpi_device *device)
> >                         cpufreq_add_device("acpi-cpufreq");
> >         }
> >
> > +       /*
> > +        * Register CPUs that are present. get_cpu_device() is used to skip
> > +        * duplicate CPU descriptions from firmware.
> > +        */
> > +       if (!invalid_logical_cpuid(pr->id) && cpu_present(pr->id) &&
> > +           !get_cpu_device(pr->id)) {
> > +               int ret = arch_register_cpu(pr->id);
> > +
> > +               if (ret)
> > +                       return ret;
> > +       }
> > +
> >         /*
> >          *  Extra Processor objects may be enumerated on MP systems with
> >          *  less than the max # of CPUs. They should be ignored _iff
> 
> This is interesting, because right below there is the following code:
> 
>     if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
>         int ret = acpi_processor_hotadd_init(pr);
> 
>         if (ret)
>             return ret;
>     }
> 
> and acpi_processor_hotadd_init() essentially calls arch_register_cpu()
> with some extra things around it (more about that below).
> 
> I do realize that acpi_processor_hotadd_init() is defined under
> CONFIG_ACPI_HOTPLUG_CPU, so for the sake of the argument let's
> consider an architecture where CONFIG_ACPI_HOTPLUG_CPU is set.
> 
> So why are the two conditionals that almost contradict each other both
> needed?  It looks like the new code could be combined with
> acpi_processor_hotadd_init() to do the right thing in all cases.
> 
> Now, acpi_processor_hotadd_init() does some extra things that look
> like they should be done by the new code too.
> 
> 1. It checks invalid_phys_cpuid() which appears to be a good idea to me.
> 
> 2. It uses locking around arch_register_cpu() which doesn't seem
> unreasonable either.
> 
> 3. It calls acpi_map_cpu() and I'm not sure why this is not done by
> the new code.
> 
> The only thing that can be dropped from it is the _STA check AFAICS,
> because acpi_processor_add() won't even be called if the CPU is not
> present (and not enabled after the first patch).
> 
> So why does the code not do 1 - 3 above?

Honestly, I'm out of my depth with this and can't answer your
questions - and I really don't want to try fiddling with this code
because it's just too icky (even in its current form in mainline)
to be understandable to anyone who hasn't gained a detailed knowledge
of this code.

It's going to require a lot of analysis - how acpi_map_cpuid() behaves
in all circumstances, what this means for invalid_logical_cpuid() and
invalid_phys_cpuid(), what paths will be taken in each case. This code
is already just too hairy for someone who isn't an experienced ACPI
hacker to be able to follow and I don't see an obvious way to make it
more readable.

James' additions make it even more complex and less readable.

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


From linux at armlinux.org.uk  Tue Feb 20 03:30:28 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 20 Feb 2024 11:30:28 +0000
Subject: [PATCH RFC v4 01/15] ACPI: Only enumerate enabled (or
 functional) processor devices
In-Reply-To: <CAJZ5v0hY_LXp41WMVPhiLosPe7YVzF38Uz=EhmJqVwqFn==Upw@mail.gmail.com>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk>
 <E1rVDmP-0027YJ-EW@rmk-PC.armlinux.org.uk>
 <CAJZ5v0hY_LXp41WMVPhiLosPe7YVzF38Uz=EhmJqVwqFn==Upw@mail.gmail.com>
Message-ID: <ZdSNVPjsti7XKxCV@shell.armlinux.org.uk>

On Thu, Feb 15, 2024 at 09:10:39PM +0100, Rafael J. Wysocki wrote:
> On Wed, Jan 31, 2024 at 5:49?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:
> >
> > From: James Morse <james.morse at arm.com>
> >
> > Today the ACPI enumeration code 'visits' all devices that are present.
> >
> > This is a problem for arm64, where CPUs are always present, but not
> > always enabled. When a device-check occurs because the firmware-policy
> > has changed and a CPU is now enabled, the following error occurs:
> > | acpi ACPI0007:48: Enumeration failure
> >
> > This is ultimately because acpi_dev_ready_for_enumeration() returns
> > true for a device that is not enabled. The ACPI Processor driver
> > will not register such CPUs as they are not 'decoding their resources'.
> >
> > ACPI allows a device to be functional instead of maintaining the
> > present and enabled bit, but we can't simply check the enabled bit
> > for all devices since firmware can be buggy.
> >
> > If ACPI indicates that the device is present and enabled, then all well
> > and good, we can enumate it. However, if the device is present and not
> > enabled, then we also check whether the device is a processor device
> > to limit the impact of this new check to just processor devices.
> >
> > This avoids enumerating present && functional processor devices that
> > are not enabled.
> >
> > Signed-off-by: James Morse <james.morse at arm.com>
> > Co-developed-by: Rafael J. Wysocki <rjw at rjwysocki.net>
> > Tested-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> > Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> > Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> 
> I can queue this up for 6.9 as it looks like the rest of the series
> will still need some work.  What do you think?

That seems to be the only way we can make some progress with this
series. I've no idea how we progress from here because I can't answer
your questions on patch 2.

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


From joey.gouly at arm.com  Tue Feb 20 03:31:27 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 20 Feb 2024 11:31:27 +0000
Subject: [PATCH 02/13] KVM: arm64: Clarify ESR_ELx_ERET_ISS_ERET*
In-Reply-To: <20240219092014.783809-3-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
 <20240219092014.783809-3-maz@kernel.org>
Message-ID: <20240220113127.GB16168@e124191.cambridge.arm.com>

On Mon, Feb 19, 2024 at 09:20:03AM +0000, Marc Zyngier wrote:
> The ESR_ELx_ERET_ISS_ERET* macros are a bit confusing:
> 
> - ESR_ELx_ERET_ISS_ERET really indicates that we have trapped an
>   ERETA* instruction, as opposed to an ERET
> 
> - ESR_ELx_ERET_ISS_ERETA reallu indicates that we have trapped
>   an ERETAB instruction, as opposed to an ERETAA.
> 
> Repaint the two helpers such as:
> 
> - ESR_ELx_ERET_ISS_ERET becomes ESR_ELx_ERET_ISS_ERETA
> 
> - ESR_ELx_ERET_ISS_ERETA becomes ESR_ELx_ERET_ISS_ERETAB
> 
> At the same time, use BIT() instead of raw values.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

I'm somewhat against this, as the original names are what the Arm ARM specifies.

> ---
>  arch/arm64/include/asm/esr.h | 4 ++--
>  arch/arm64/kvm/handle_exit.c | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index 353fe08546cf..72c7810ccf2c 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -290,8 +290,8 @@
>  		 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
> +#define ESR_ELx_ERET_ISS_ERETA		BIT(1)
> +#define ESR_ELx_ERET_ISS_ERETAB		BIT(0)
>  
>  /*
>   * ISS field definitions for floating-point exception traps
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 617ae6dea5d5..0646c623d1da 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -219,7 +219,7 @@ static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
>  
>  static int kvm_handle_eret(struct kvm_vcpu *vcpu)
>  {
> -	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERET)
> +	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERETA)

If this part is confusing due to the name, maybe introduce a function in esr.h
esr_is_pac_eret() (name pending bikeshedding)?

>  		return kvm_handle_ptrauth(vcpu);
>  
>  	/*

Thanks,
Joey


From haibo.li at mediatek.com  Tue Feb 20 03:33:41 2024
From: haibo.li at mediatek.com (Haibo Li)
Date: Tue, 20 Feb 2024 19:33:41 +0800
Subject: [PATCH] arm:dump the stack usage after stack overflows
Message-ID: <20240220113341.24523-1-haibo.li@mediatek.com>

With the help of vmap stack,it is able to detect stack overflow.

To make it easy to debug stack overflow,dump the stack usage of
each frame by walking the stack.

After this patch,the log after stack overflows like below:

Insufficient stack space to handle exception!
Task stack:     [0xf4a70000..0xf4a72000]
IRQ stack:      [0xf0800000..0xf0802000]
Overflow stack: [0x818c1000..0x818c2000]
Depth   usage   size   Location
  0      8232     96   _prb_read_valid
  1      8136     24   prb_read_valid
  2      8112    200   printk_get_next_message
  3      7912    104   console_flush_all
  4      7808     64   console_unlock
  5      7744     40   vprintk_emit
  6      7704     16   vprintk_default
  7      7688     32   _printk
  8      7656   1048   do_circle_loop
  9      6608   1048   do_circle_loop
 10      5560   1048   do_circle_loop
 11      4512   1048   do_circle_loop
 12      3464   1048   do_circle_loop
 13      2416   1048   do_circle_loop
 14      1368   1048   do_circle_loop
 15       320      8   stack_ovf_selftest
 16       312     24   param_attr_store
 17       288     40   kernfs_fop_write_iter
 18       248    112   vfs_write
 19       136     48   ksys_write
-----    -----  -----   ------
Internal error: kernel stack overflow: 0 [#1] SMP ARM
...

Signed-off-by: Haibo Li <haibo.li at mediatek.com>
---
 arch/arm/kernel/traps.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 3bad79db5d6e..641ca68b44ba 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -921,6 +921,33 @@ static int __init allocate_overflow_stacks(void)
 }
 early_initcall(allocate_overflow_stacks);
 
+static void dump_stack_usage(struct pt_regs *regs)
+{
+	struct stackframe frame;
+	unsigned int depth = 0;
+	unsigned long prev_pc;
+	unsigned long prev_sp;
+	unsigned long stack_high = (unsigned long)current->stack + THREAD_SIZE;
+
+	arm_get_current_stackframe(regs, &frame);
+	pr_emerg("Depth   usage   size   Location\n");
+	while (1) {
+		prev_pc = frame.pc;
+		prev_sp = frame.sp;
+#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+		//meet the requirement of frame_pointer_check
+		if (frame.sp < (unsigned long)current->stack)
+			frame.sp = (unsigned long)current->stack + 4;
+#endif
+		if (unwind_frame(&frame) < 0)
+			break;
+		pr_emerg("%3d     %5ld  %5ld   %ps\n",
+			 depth++, stack_high - prev_sp,
+			 frame.sp - prev_sp, (void *)prev_pc);
+	}
+	pr_emerg("-----    -----  -----   ------\n");
+}
+
 asmlinkage void handle_bad_stack(struct pt_regs *regs)
 {
 	unsigned long tsk_stk = (unsigned long)current->stack;
@@ -940,6 +967,7 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
 #endif
 	pr_emerg("Overflow stack: [0x%08lx..0x%08lx]\n",
 		 ovf_stk - OVERFLOW_STACK_SIZE, ovf_stk);
+	dump_stack_usage(regs);
 
 	die("kernel stack overflow", regs, 0);
 }
-- 
2.18.0



From michal.simek at amd.com  Tue Feb 20 03:34:18 2024
From: michal.simek at amd.com (Michal Simek)
Date: Tue, 20 Feb 2024 12:34:18 +0100
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
In-Reply-To: <DM6PR12MB4465FAF7AB3F9CE15FAC6C879D502@DM6PR12MB4465.namprd12.prod.outlook.com>
References: <202402192019160b9c4120@mail.local>
 <DM6PR12MB4465FAF7AB3F9CE15FAC6C879D502@DM6PR12MB4465.namprd12.prod.outlook.com>
Message-ID: <74cfdded-be3a-4af6-b23a-eea2c5e748b8@amd.com>



On 2/20/24 11:51, Buddhabhatti, Jay wrote:
> Hi Alexandre,
> 
>> -----Original Message-----
>> From: Alexandre Belloni <alexandre.belloni at bootlin.com>
>> Sent: Tuesday, February 20, 2024 1:49 AM
>> To: Simek, Michal <michal.simek at amd.com>
>> Cc: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>; linux-
>> kernel at vger.kernel.org; monstr at monstr.eu; michal.simek at xilinx.com;
>> git at xilinx.com; Conor Dooley <conor+dt at kernel.org>; Krzysztof Kozlowski
>> <krzysztof.kozlowski+dt at linaro.org>; Rob Herring <robh at kernel.org>; open
>> list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
>> <devicetree at vger.kernel.org>; moderated list:ARM/ZYNQ ARCHITECTURE
>> <linux-arm-kernel at lists.infradead.org>; open list:REAL TIME CLOCK (RTC)
>> SUBSYSTEM <linux-rtc at vger.kernel.org>
>> Subject: Re: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains
>> property
>>
>> On 19/02/2024 14:11:50+0100, Michal Simek wrote:
>>>
>>>
>>> On 2/17/24 09:26, Krzysztof Kozlowski wrote:
>>>> On 16/02/2024 10:42, Michal Simek wrote:
>>>>>
>>>>>
>>>>> On 2/16/24 10:19, Krzysztof Kozlowski wrote:
>>>>>> On 16/02/2024 09:51, Michal Simek wrote:
>>>>>>> RTC has its own power domain on Xilinx Versal SOC that's why
>>>>>>> describe it as optional property.
>>>>>>>
>>>>>>> Signed-off-by: Michal Simek <michal.simek at amd.com>
>>>>>>> ---
>>>>>>>
>>>>>>>     Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml | 3
>> +++
>>>>>>>     1 file changed, 3 insertions(+)
>>>>>>>
>>>>>>
>>>>>> But Versal is not described in this binding, is it? I see only
>>>>>> one compatible.
>>>>>
>>>>> It is the same IP only as is on zynqmp with own power rail.
>>>>
>>>> Then you should have separate compatible, because they are not
>>>> identical. It would also allow you to narrow the domains to versal
>>>> and also require it (on versal).
>>>
>>> I can double check with HW guys but I am quite sure IP itself is
>>> exactly the same. What it is different is that there is own power
>>> domain to it (not shared one as is in zynqmp case).
>>>
>>> Also Linux is non secure sw and if secure firmware won't allow to
>>> change setting of it it can't be required. I am just saying that Linux
>>> doesn't need to be owner of any power domain that's why it shouldn't
>>> be required property.
>>
>> I guess because the integration is different, you still need a differente
>> compatible so you can forbid the property on non-Versal.
> 
> [Jay] RTC has its own power domain in case of Versal and ZynqMP both that we double check it.

Thanks Jay for looking into it. I should definitely update my commit message to 
reflect it. Do you still want me to create soc specific property?

Thanks,
Michal


From rongwei.wang at linux.alibaba.com  Tue Feb 20 03:36:01 2024
From: rongwei.wang at linux.alibaba.com (Rongwei Wang)
Date: Tue, 20 Feb 2024 19:36:01 +0800
Subject: [PATCH v1 1/2] arch_numa: remove __init for early_cpu_to_node
In-Reply-To: <20240220113602.6943-1-rongwei.wang@linux.alibaba.com>
References: <20231012024842.99703-1-rongwei.wang@linux.alibaba.com>
 <20240220113602.6943-1-rongwei.wang@linux.alibaba.com>
Message-ID: <20240220113602.6943-2-rongwei.wang@linux.alibaba.com>

Next, in order to support other arch, early_cpu_to_node()
will be called in a general function. We have to delete
'__init' to avoid warning messages during compiling.

Signed-off-by: Rongwei Wang <rongwei.wang at linux.alibaba.com>
Signed-off-by: Teng Ma <teng.ma at linux.alibaba.com>
---
 drivers/base/arch_numa.c   | 2 +-
 include/asm-generic/numa.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
index 5b59d133b6af..90519d981471 100644
--- a/drivers/base/arch_numa.c
+++ b/drivers/base/arch_numa.c
@@ -144,7 +144,7 @@ void __init early_map_cpu_to_node(unsigned int cpu, int nid)
 unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(__per_cpu_offset);
 
-int __init early_cpu_to_node(int cpu)
+int early_cpu_to_node(int cpu)
 {
 	return cpu_to_node_map[cpu];
 }
diff --git a/include/asm-generic/numa.h b/include/asm-generic/numa.h
index c32e0cf23c90..16073111bffc 100644
--- a/include/asm-generic/numa.h
+++ b/include/asm-generic/numa.h
@@ -35,7 +35,7 @@ int __init numa_add_memblk(int nodeid, u64 start, u64 end);
 void __init numa_set_distance(int from, int to, int distance);
 void __init numa_free_distance(void);
 void __init early_map_cpu_to_node(unsigned int cpu, int nid);
-int __init early_cpu_to_node(int cpu);
+int early_cpu_to_node(int cpu);
 void numa_store_cpu_info(unsigned int cpu);
 void numa_add_cpu(unsigned int cpu);
 void numa_remove_cpu(unsigned int cpu);
-- 
2.32.0.3.gf3a3e56d6



From rongwei.wang at linux.alibaba.com  Tue Feb 20 03:36:00 2024
From: rongwei.wang at linux.alibaba.com (Rongwei Wang)
Date: Tue, 20 Feb 2024 19:36:00 +0800
Subject: [PATCH v1 0/2] support NUMA emulation for genertic arch
In-Reply-To: <20231012024842.99703-1-rongwei.wang@linux.alibaba.com>
References: <20231012024842.99703-1-rongwei.wang@linux.alibaba.com>
Message-ID: <20240220113602.6943-1-rongwei.wang@linux.alibaba.com>

A brief introduction
====================

The NUMA emulation can fake more node base on a single
node system, e.g.

one node system:

[root at localhost ~]# numactl -H
available: 1 nodes (0)
node 0 cpus: 0 1 2 3 4 5 6 7
node 0 size: 31788 MB
node 0 free: 31446 MB
node distances:
node   0
  0:  10

add numa=fake=2 (fake 2 node on each origin node):

[root at localhost ~]# numactl -H
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7
node 0 size: 15806 MB
node 0 free: 15451 MB
node 1 cpus: 0 1 2 3 4 5 6 7
node 1 size: 16029 MB
node 1 free: 15989 MB
node distances:
node   0   1
  0:  10  10
  1:  10  10

As above shown, a new node has been faked. As cpus, the realization
of x86 NUMA emulation is kept. Maybe each node should has 4 cores is
better (not sure, next to do if so).

Why do this
===========

It seems has following reasons:
  (1) In x86 host, apply NUMA emulation can fake more nodes environment
      to test or verify some performance stuff, but arm64 only has
      one method that modify ACPI table to do this. It's troublesome
      more or less.
  (2) Reduce competition for some locks. Here an example we found:
      will-it-scale/tlb_flush1_processes -t 96 -s 10, it shows obvious
      hotspot on lruvec->lock when test in single environment. What's
      more, The performance improved greatly if test in two more nodes
      system. The data shows below (more is better):

      ---------------------------------------------------------------------
      threads/process |   1     |     12   |     24   |   48     |   96
      ---------------------------------------------------------------------
      one node        | 14 1122 | 110 5372 | 111 2615 | 79 7084  | 72 4516
      ---------------------------------------------------------------------
      numa=fake=2     | 14 1168 | 144 4848 | 215 9070 | 157 0412 | 142 3968
      ---------------------------------------------------------------------
                      | For concurrency 12, no lruvec->lock hotspot. For 24,
      hotspot         | one node has 24% hotspot on lruvec->lock, but
                      | two nodes env hasn't.
      ---------------------------------------------------------------------

As for risks (e.g. numa balance...), they need to be discussed here.

Lastly, it seems not a good choice to realize x86 and other genertic
archs separately. But it can indeed avoid some architecture related
APIs adjustments and alleviate future maintenance. The previous RFC
link see [1].

Any advice are welcome, Thanks!

Change log
==========

RFC v1 -> v1
* add new CONFIG_NUMA_FAKE for genertic archs.
* keep x86 implementation, realize numa emulation in driver/base/ for
  genertic arch, e.g, arm64.

[1] RFC v1: https://patchwork.kernel.org/project/linux-arm-kernel/cover/20231012024842.99703-1-rongwei.wang at linux.alibaba.com/

Rongwei Wang (2):
  arch_numa: remove __init for early_cpu_to_node
  numa: introduce numa emulation for genertic arch

 drivers/base/Kconfig          |   9 +
 drivers/base/Makefile         |   1 +
 drivers/base/arch_numa.c      |  32 +-
 drivers/base/numa_emulation.c | 909 ++++++++++++++++++++++++++++++++++
 drivers/base/numa_emulation.h |  41 ++
 include/asm-generic/numa.h    |   2 +-
 6 files changed, 992 insertions(+), 2 deletions(-)
 create mode 100644 drivers/base/numa_emulation.c
 create mode 100644 drivers/base/numa_emulation.h

-- 
2.32.0.3.gf3a3e56d6



From rongwei.wang at linux.alibaba.com  Tue Feb 20 03:36:02 2024
From: rongwei.wang at linux.alibaba.com (Rongwei Wang)
Date: Tue, 20 Feb 2024 19:36:02 +0800
Subject: [PATCH v1 2/2] numa: introduce numa emulation for genertic arch
In-Reply-To: <20240220113602.6943-1-rongwei.wang@linux.alibaba.com>
References: <20231012024842.99703-1-rongwei.wang@linux.alibaba.com>
 <20240220113602.6943-1-rongwei.wang@linux.alibaba.com>
Message-ID: <20240220113602.6943-3-rongwei.wang@linux.alibaba.com>

Currently, x86 has already support numa
emulation for a long time. That's enabled
by CONFIG_NUMA_EMU. This patch mainly to
introduce numa emulation for genertic
arch (refer to x86 implementation).

In order to avoid changing APIs (especially
related to NUMA), and more coupling, maintaining
x86 and other genertic archs separately
would be a better choice. So a new configure
CONFIG_NUMA_FAKE used to enable it, also avoid
some conflicts with CONFIG_NUMA_EMU.

Signed-off-by: Rongwei Wang <rongwei.wang at linux.alibaba.com>
Signed-off-by: Teng Ma <teng.ma at linux.alibaba.com>
---
 drivers/base/Kconfig          |   9 +
 drivers/base/Makefile         |   1 +
 drivers/base/arch_numa.c      |  30 ++
 drivers/base/numa_emulation.c | 909 ++++++++++++++++++++++++++++++++++
 drivers/base/numa_emulation.h |  41 ++
 5 files changed, 990 insertions(+)
 create mode 100644 drivers/base/numa_emulation.c
 create mode 100644 drivers/base/numa_emulation.h

diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 2b8fd6bb7da0..c162aedf1458 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -230,6 +230,15 @@ config GENERIC_ARCH_NUMA
 	  Enable support for generic NUMA implementation. Currently, RISC-V
 	  and ARM64 use it.
 
+config NUMA_FAKE
+	bool "NUMA emulation"
+	depends on NUMA
+	depends on GENERIC_ARCH_NUMA
+	help
+	  Enable NUMA emulation. A flat machine will be split
+	  into virtual nodes when booted with "numa=fake=N", where N is the
+	  number of nodes. This is only useful for debugging.
+
 config FW_DEVLINK_SYNC_STATE_TIMEOUT
 	bool "sync_state() behavior defaults to timeout instead of strict"
 	help
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 3079bfe53d04..23976a1babae 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -34,3 +34,4 @@ ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
 # define_trace.h needs to know how to find our header
 CFLAGS_trace.o		:= -I$(src)
 obj-$(CONFIG_TRACING)	+= trace.o
+obj-$(CONFIG_NUMA_FAKE)	+=  numa_emulation.o
diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
index 90519d981471..77ea423e2bf9 100644
--- a/drivers/base/arch_numa.c
+++ b/drivers/base/arch_numa.c
@@ -24,12 +24,25 @@ static int numa_distance_cnt;
 static u8 *numa_distance;
 bool numa_off;
 
+#ifdef CONFIG_NUMA_FAKE
+extern struct numa_meminfo numa_meminfo;
+
+extern void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt);
+extern int __init numa_cleanup_meminfo(struct numa_meminfo *mi);
+extern int __init numa_register_memblks(struct numa_meminfo *mi);
+extern int __init numa_add_memblk_to(int nid, u64 start, u64 end,
+				     struct numa_meminfo *mi);
+extern int __init numa_emu_cmdline(char *str);
+#endif
+
 static __init int numa_parse_early_param(char *opt)
 {
 	if (!opt)
 		return -EINVAL;
 	if (str_has_prefix(opt, "off"))
 		numa_off = true;
+	if (!strncmp(opt, "fake=", 5))
+		return numa_emu_cmdline(opt + 5);
 
 	return 0;
 }
@@ -61,6 +74,7 @@ EXPORT_SYMBOL(cpumask_of_node);
 
 #endif
 
+#ifndef CONFIG_NUMA_FAKE
 static void numa_update_cpu(unsigned int cpu, bool remove)
 {
 	int nid = cpu_to_node(cpu);
@@ -89,6 +103,7 @@ void numa_clear_node(unsigned int cpu)
 	numa_remove_cpu(cpu);
 	set_cpu_numa_node(cpu, NUMA_NO_NODE);
 }
+#endif
 
 /*
  * Allocate node_to_cpumask_map based on number of available nodes
@@ -202,6 +217,9 @@ int __init numa_add_memblk(int nid, u64 start, u64 end)
 {
 	int ret;
 
+	if (IS_ENABLED(CONFIG_NUMA_FAKE))
+		return numa_add_memblk_to(nid, start, end, &numa_meminfo);
+
 	ret = memblock_set_node(start, (end - start), &memblock.memory, nid);
 	if (ret < 0) {
 		pr_err("memblock [0x%llx - 0x%llx] failed to add on node %d\n",
@@ -395,6 +413,18 @@ static int __init numa_init(int (*init_func)(void))
 		goto out_free_distance;
 	}
 
+#ifdef CONFIG_NUMA_FAKE
+	ret = numa_cleanup_meminfo(&numa_meminfo);
+	if (ret < 0)
+		return ret;
+
+	numa_emulation(&numa_meminfo, numa_distance_cnt);
+
+	ret = numa_register_memblks(&numa_meminfo);
+	if (ret < 0)
+		return ret;
+#endif
+
 	ret = numa_register_nodes();
 	if (ret < 0)
 		goto out_free_distance;
diff --git a/drivers/base/numa_emulation.c b/drivers/base/numa_emulation.c
new file mode 100644
index 000000000000..379e52b30327
--- /dev/null
+++ b/drivers/base/numa_emulation.c
@@ -0,0 +1,909 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NUMA emulation
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/topology.h>
+#include <linux/memblock.h>
+#include <asm/dma.h>
+#include "numa_emulation.h"
+
+static int emu_nid_to_phys[MAX_NUMNODES];
+static char *emu_cmdline __initdata;
+
+struct numa_meminfo numa_meminfo __initdata_or_meminfo;
+static struct numa_meminfo numa_reserved_meminfo __initdata_or_meminfo;
+
+void __init numa_remove_memblk_from(int idx, struct numa_meminfo *mi);
+void __init numa_reset_distance(void);
+
+int __init numa_emu_cmdline(char *str)
+{
+	emu_cmdline = str;
+	return 0;
+}
+
+/**
+ * numa_remove_memblk_from - Remove one numa_memblk from a numa_meminfo
+ * @idx: Index of memblk to remove
+ * @mi: numa_meminfo to remove memblk from
+ *
+ * Remove @idx'th numa_memblk from @mi by shifting @mi->blk[] and
+ * decrementing @mi->nr_blks.
+ */
+void __init numa_remove_memblk_from(int idx, struct numa_meminfo *mi)
+{
+	mi->nr_blks--;
+	memmove(&mi->blk[idx], &mi->blk[idx + 1],
+		(mi->nr_blks - idx) * sizeof(mi->blk[0]));
+}
+
+/**
+ * numa_move_tail_memblk - Move a numa_memblk from one numa_meminfo to another
+ * @dst: numa_meminfo to append block to
+ * @idx: Index of memblk to remove
+ * @src: numa_meminfo to remove memblk from
+ */
+static void __init numa_move_tail_memblk(struct numa_meminfo *dst, int idx,
+					 struct numa_meminfo *src)
+{
+	dst->blk[dst->nr_blks++] = src->blk[idx];
+	numa_remove_memblk_from(idx, src);
+}
+
+int __init numa_add_memblk_to(int nid, u64 start, u64 end,
+			      struct numa_meminfo *mi)
+{
+	/* ignore zero length blks */
+	if (start == end)
+		return 0;
+
+	/* whine about and ignore invalid blks */
+	if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
+		pr_warn("Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
+			nid, start, end - 1);
+		return 0;
+	}
+
+	if (mi->nr_blks >= NR_NODE_MEMBLKS) {
+		pr_err("too many memblk ranges\n");
+		return -EINVAL;
+	}
+
+	mi->blk[mi->nr_blks].start = start;
+	mi->blk[mi->nr_blks].end = end;
+	mi->blk[mi->nr_blks].nid = nid;
+	mi->nr_blks++;
+	return 0;
+}
+
+/**
+ * numa_cleanup_meminfo - Cleanup a numa_meminfo
+ * @mi: numa_meminfo to clean up
+ *
+ * Sanitize @mi by merging and removing unnecessary memblks.  Also check for
+ * conflicts and clear unused memblks.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int __init numa_cleanup_meminfo(struct numa_meminfo *mi)
+{
+	const u64 low = 0;
+	const u64 high = PFN_PHYS(max_pfn);
+	int i, j, k;
+
+	/* first, trim all entries */
+	for (i = 0; i < mi->nr_blks; i++) {
+		struct numa_memblk *bi = &mi->blk[i];
+
+		/* move / save reserved memory ranges */
+		if (!memblock_overlaps_region(&memblock.memory,
+					bi->start, bi->end - bi->start)) {
+			numa_move_tail_memblk(&numa_reserved_meminfo, i--, mi);
+			continue;
+		}
+
+		/* make sure all non-reserved blocks are inside the limits */
+		bi->start = max(bi->start, low);
+
+		/* preserve info for non-RAM areas above 'max_pfn': */
+		if (bi->end > high) {
+			numa_add_memblk_to(bi->nid, high, bi->end,
+					   &numa_reserved_meminfo);
+			bi->end = high;
+		}
+
+		/* and there's no empty block */
+		if (bi->start >= bi->end)
+			numa_remove_memblk_from(i--, mi);
+	}
+
+	/* merge neighboring / overlapping entries */
+	for (i = 0; i < mi->nr_blks; i++) {
+		struct numa_memblk *bi = &mi->blk[i];
+
+		for (j = i + 1; j < mi->nr_blks; j++) {
+			struct numa_memblk *bj = &mi->blk[j];
+			u64 start, end;
+
+			/*
+			 * See whether there are overlapping blocks.  Whine
+			 * about but allow overlaps of the same nid.  They
+			 * will be merged below.
+			 */
+			if (bi->end > bj->start && bi->start < bj->end) {
+				if (bi->nid != bj->nid) {
+					pr_err("node %d [mem %#010Lx-%#010Lx] overlaps with node %d [mem %#010Lx-%#010Lx]\n",
+					       bi->nid, bi->start, bi->end - 1,
+					       bj->nid, bj->start, bj->end - 1);
+					return -EINVAL;
+				}
+				pr_warn("Warning: node %d [mem %#010Lx-%#010Lx] overlaps with itself [mem %#010Lx-%#010Lx]\n",
+					bi->nid, bi->start, bi->end - 1,
+					bj->start, bj->end - 1);
+			}
+
+			/*
+			 * Join together blocks on the same node, holes
+			 * between which don't overlap with memory on other
+			 * nodes.
+			 */
+			if (bi->nid != bj->nid)
+				continue;
+			start = min(bi->start, bj->start);
+			end = max(bi->end, bj->end);
+			for (k = 0; k < mi->nr_blks; k++) {
+				struct numa_memblk *bk = &mi->blk[k];
+
+				if (bi->nid == bk->nid)
+					continue;
+				if (start < bk->end && end > bk->start)
+					break;
+			}
+			if (k < mi->nr_blks)
+				continue;
+			printk(KERN_INFO "NUMA: Node %d [mem %#010Lx-%#010Lx] + [mem %#010Lx-%#010Lx] -> [mem %#010Lx-%#010Lx]\n",
+			       bi->nid, bi->start, bi->end - 1, bj->start,
+			       bj->end - 1, start, end - 1);
+			bi->start = start;
+			bi->end = end;
+			numa_remove_memblk_from(j--, mi);
+		}
+	}
+
+	/* clear unused ones */
+	for (i = mi->nr_blks; i < ARRAY_SIZE(mi->blk); i++) {
+		mi->blk[i].start = mi->blk[i].end = 0;
+		mi->blk[i].nid = NUMA_NO_NODE;
+	}
+
+	return 0;
+}
+
+/*
+ * Mark all currently memblock-reserved physical memory (which covers the
+ * kernel's own memory ranges) as hot-unswappable.
+ */
+static void __init numa_clear_kernel_node_hotplug(void)
+{
+	nodemask_t reserved_nodemask = NODE_MASK_NONE;
+	struct memblock_region *mb_region;
+	int i;
+
+	/*
+	 * We have to do some preprocessing of memblock regions, to
+	 * make them suitable for reservation.
+	 *
+	 * At this time, all memory regions reserved by memblock are
+	 * used by the kernel, but those regions are not split up
+	 * along node boundaries yet, and don't necessarily have their
+	 * node ID set yet either.
+	 *
+	 * So iterate over all memory known to the x86 architecture,
+	 * and use those ranges to set the nid in memblock.reserved.
+	 * This will split up the memblock regions along node
+	 * boundaries and will set the node IDs as well.
+	 */
+	for (i = 0; i < numa_meminfo.nr_blks; i++) {
+		struct numa_memblk *mb = numa_meminfo.blk + i;
+		int ret;
+
+		ret = memblock_set_node(mb->start, mb->end - mb->start, &memblock.reserved, mb->nid);
+		WARN_ON_ONCE(ret);
+	}
+
+	/*
+	 * Now go over all reserved memblock regions, to construct a
+	 * node mask of all kernel reserved memory areas.
+	 *
+	 * [ Note, when booting with mem=nn[kMG] or in a kdump kernel,
+	 *   numa_meminfo might not include all memblock.reserved
+	 *   memory ranges, because quirks such as trim_snb_memory()
+	 *   reserve specific pages for Sandy Bridge graphics. ]
+	 */
+	for_each_reserved_mem_region(mb_region) {
+		int nid = memblock_get_region_node(mb_region);
+
+		if (nid != MAX_NUMNODES)
+			node_set(nid, reserved_nodemask);
+	}
+
+	/*
+	 * Finally, clear the MEMBLOCK_HOTPLUG flag for all memory
+	 * belonging to the reserved node mask.
+	 *
+	 * Note that this will include memory regions that reside
+	 * on nodes that contain kernel memory - entire nodes
+	 * become hot-unpluggable:
+	 */
+	for (i = 0; i < numa_meminfo.nr_blks; i++) {
+		struct numa_memblk *mb = numa_meminfo.blk + i;
+
+		if (!node_isset(mb->nid, reserved_nodemask))
+			continue;
+
+		memblock_clear_hotplug(mb->start, mb->end - mb->start);
+	}
+}
+
+/*
+ * Set nodes, which have memory in @mi, in *@nodemask.
+ */
+static void __init numa_nodemask_from_meminfo(nodemask_t *nodemask,
+					      const struct numa_meminfo *mi)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mi->blk); i++)
+		if (mi->blk[i].start != mi->blk[i].end &&
+		    mi->blk[i].nid != NUMA_NO_NODE)
+			node_set(mi->blk[i].nid, *nodemask);
+}
+
+int __init numa_register_memblks(struct numa_meminfo *mi)
+{
+	int i;
+
+	/* Account for nodes with cpus and no memory */
+	node_possible_map = numa_nodes_parsed;
+	numa_nodemask_from_meminfo(&node_possible_map, mi);
+	if (WARN_ON(nodes_empty(node_possible_map)))
+		return -EINVAL;
+
+	for (i = 0; i < mi->nr_blks; i++) {
+		struct numa_memblk *mb = &mi->blk[i];
+		memblock_set_node(mb->start, mb->end - mb->start,
+				  &memblock.memory, mb->nid);
+	}
+
+	/*
+	 * At very early time, the kernel have to use some memory such as
+	 * loading the kernel image. We cannot prevent this anyway. So any
+	 * node the kernel resides in should be un-hotpluggable.
+	 *
+	 * And when we come here, alloc node data won't fail.
+	 */
+	numa_clear_kernel_node_hotplug();
+
+	/*
+	 * If sections array is gonna be used for pfn -> nid mapping, check
+	 * whether its granularity is fine enough.
+	 */
+	if (IS_ENABLED(NODE_NOT_IN_PAGE_FLAGS)) {
+		unsigned long pfn_align = node_map_pfn_alignment();
+
+		if (pfn_align && pfn_align < PAGES_PER_SECTION) {
+			pr_warn("Node alignment %LuMB < min %LuMB, rejecting NUMA config\n",
+				PFN_PHYS(pfn_align) >> 20,
+				PFN_PHYS(PAGES_PER_SECTION) >> 20);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int __init emu_find_memblk_by_nid(int nid, const struct numa_meminfo *mi)
+{
+	int i;
+
+	for (i = 0; i < mi->nr_blks; i++)
+		if (mi->blk[i].nid == nid)
+			return i;
+	return -ENOENT;
+}
+
+static u64 __init mem_hole_size(u64 start, u64 end)
+{
+	unsigned long start_pfn = PFN_UP(start);
+	unsigned long end_pfn = PFN_DOWN(end);
+
+	if (start_pfn < end_pfn)
+		return PFN_PHYS(absent_pages_in_range(start_pfn, end_pfn));
+	return 0;
+}
+
+/*
+ * Sets up nid to range from @start to @end.  The return value is -errno if
+ * something went wrong, 0 otherwise.
+ */
+static int __init emu_setup_memblk(struct numa_meminfo *ei,
+				   struct numa_meminfo *pi,
+				   int nid, int phys_blk, u64 size)
+{
+	struct numa_memblk *eb = &ei->blk[ei->nr_blks];
+	struct numa_memblk *pb = &pi->blk[phys_blk];
+
+	if (ei->nr_blks >= NR_NODE_MEMBLKS) {
+		pr_err("NUMA: Too many emulated memblks, failing emulation\n");
+		return -EINVAL;
+	}
+
+	ei->nr_blks++;
+	eb->start = pb->start;
+	eb->end = pb->start + size;
+	eb->nid = nid;
+
+	if (emu_nid_to_phys[nid] == NUMA_NO_NODE)
+		emu_nid_to_phys[nid] = pb->nid;
+
+	pb->start += size;
+	if (pb->start >= pb->end) {
+		WARN_ON_ONCE(pb->start > pb->end);
+		numa_remove_memblk_from(phys_blk, pi);
+	}
+
+	printk(KERN_INFO "Faking node %d at [mem %#018Lx-%#018Lx] (%LuMB)\n",
+	       nid, eb->start, eb->end - 1, (eb->end - eb->start) >> 20);
+	return 0;
+}
+
+/*
+ * Sets up nr_nodes fake nodes interleaved over physical nodes ranging from addr
+ * to max_addr.
+ *
+ * Returns zero on success or negative on error.
+ */
+static int __init split_nodes_interleave(struct numa_meminfo *ei,
+					 struct numa_meminfo *pi,
+					 u64 addr, u64 max_addr, int nr_nodes)
+{
+	nodemask_t physnode_mask = numa_nodes_parsed;
+	u64 size;
+	int big;
+	int nid = 0;
+	int i, ret;
+
+	if (nr_nodes <= 0)
+		return -1;
+	if (nr_nodes > MAX_NUMNODES) {
+		pr_info("numa=fake=%d too large, reducing to %d\n",
+			nr_nodes, MAX_NUMNODES);
+		nr_nodes = MAX_NUMNODES;
+	}
+
+	/*
+	 * Calculate target node size.  x86_32 freaks on __udivdi3() so do
+	 * the division in ulong number of pages and convert back.
+	 */
+	size = max_addr - addr - mem_hole_size(addr, max_addr);
+	size = PFN_PHYS((unsigned long)(size >> PAGE_SHIFT) / nr_nodes);
+
+	/*
+	 * Calculate the number of big nodes that can be allocated as a result
+	 * of consolidating the remainder.
+	 */
+	big = ((size & ~FAKE_NODE_MIN_HASH_MASK) * nr_nodes) /
+		FAKE_NODE_MIN_SIZE;
+
+	size &= FAKE_NODE_MIN_HASH_MASK;
+	if (!size) {
+		pr_err("Not enough memory for each node.  "
+			"NUMA emulation disabled.\n");
+		return -1;
+	}
+
+	/*
+	 * Continue to fill physical nodes with fake nodes until there is no
+	 * memory left on any of them.
+	 */
+	while (!nodes_empty(physnode_mask)) {
+		for_each_node_mask(i, physnode_mask) {
+#ifdef CONFIG_ZONE_DMA32
+			unsigned long dma32_max_pfn = PFN_DOWN(min(4UL * SZ_1G, memblock_end_of_DRAM() - 1) + 1);
+			u64 dma32_end = PFN_PHYS(dma32_max_pfn);
+#endif
+			u64 start, limit, end;
+			int phys_blk;
+
+			phys_blk = emu_find_memblk_by_nid(i, pi);
+			if (phys_blk < 0) {
+				node_clear(i, physnode_mask);
+				continue;
+			}
+			start = pi->blk[phys_blk].start;
+			limit = pi->blk[phys_blk].end;
+			end = start + size;
+
+			if (nid < big)
+				end += FAKE_NODE_MIN_SIZE;
+
+			/*
+			 * Continue to add memory to this fake node if its
+			 * non-reserved memory is less than the per-node size.
+			 */
+			while (end - start - mem_hole_size(start, end) < size) {
+				end += FAKE_NODE_MIN_SIZE;
+				if (end > limit) {
+					end = limit;
+					break;
+				}
+			}
+
+#ifdef CONFIG_ZONE_DMA32
+			/*
+			 * If there won't be at least FAKE_NODE_MIN_SIZE of
+			 * non-reserved memory in ZONE_DMA32 for the next node,
+			 * this one must extend to the boundary.
+			 */
+			if (end < dma32_end && dma32_end - end -
+			    mem_hole_size(end, dma32_end) < FAKE_NODE_MIN_SIZE)
+				end = dma32_end;
+#endif
+
+			/*
+			 * If there won't be enough non-reserved memory for the
+			 * next node, this one must extend to the end of the
+			 * physical node.
+			 */
+			if (limit - end - mem_hole_size(end, limit) < size)
+				end = limit;
+
+			ret = emu_setup_memblk(ei, pi, nid++ % nr_nodes,
+					       phys_blk,
+					       min(end, limit) - start);
+			if (ret < 0)
+				return ret;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Returns the end address of a node so that there is at least `size' amount of
+ * non-reserved memory or `max_addr' is reached.
+ */
+static u64 __init find_end_of_node(u64 start, u64 max_addr, u64 size)
+{
+	u64 end = start + size;
+
+	while (end - start - mem_hole_size(start, end) < size) {
+		end += FAKE_NODE_MIN_SIZE;
+		if (end > max_addr) {
+			end = max_addr;
+			break;
+		}
+	}
+	return end;
+}
+
+static u64 uniform_size(u64 max_addr, u64 base, u64 hole, int nr_nodes)
+{
+	unsigned long max_pfn = PHYS_PFN(max_addr);
+	unsigned long base_pfn = PHYS_PFN(base);
+	unsigned long hole_pfns = PHYS_PFN(hole);
+
+	return PFN_PHYS((max_pfn - base_pfn - hole_pfns) / nr_nodes);
+}
+
+/*
+ * Sets up fake nodes of `size' interleaved over physical nodes ranging from
+ * `addr' to `max_addr'.
+ *
+ * Returns zero on success or negative on error.
+ */
+static int __init split_nodes_size_interleave_uniform(struct numa_meminfo *ei,
+					      struct numa_meminfo *pi,
+					      u64 addr, u64 max_addr, u64 size,
+					      int nr_nodes, struct numa_memblk *pblk,
+					      int nid)
+{
+	nodemask_t physnode_mask = numa_nodes_parsed;
+	int i, ret, uniform = 0;
+	u64 min_size;
+
+	if ((!size && !nr_nodes) || (nr_nodes && !pblk))
+		return -1;
+
+	/*
+	 * In the 'uniform' case split the passed in physical node by
+	 * nr_nodes, in the non-uniform case, ignore the passed in
+	 * physical block and try to create nodes of at least size
+	 * @size.
+	 *
+	 * In the uniform case, split the nodes strictly by physical
+	 * capacity, i.e. ignore holes. In the non-uniform case account
+	 * for holes and treat @size as a minimum floor.
+	 */
+	if (!nr_nodes)
+		nr_nodes = MAX_NUMNODES;
+	else {
+		nodes_clear(physnode_mask);
+		node_set(pblk->nid, physnode_mask);
+		uniform = 1;
+	}
+
+	if (uniform) {
+		min_size = uniform_size(max_addr, addr, 0, nr_nodes);
+		size = min_size;
+	} else {
+		/*
+		 * The limit on emulated nodes is MAX_NUMNODES, so the
+		 * size per node is increased accordingly if the
+		 * requested size is too small.  This creates a uniform
+		 * distribution of node sizes across the entire machine
+		 * (but not necessarily over physical nodes).
+		 */
+		min_size = uniform_size(max_addr, addr,
+				mem_hole_size(addr, max_addr), nr_nodes);
+	}
+	min_size = ALIGN(max(min_size, FAKE_NODE_MIN_SIZE), FAKE_NODE_MIN_SIZE);
+	if (size < min_size) {
+		pr_err("Fake node size %LuMB too small, increasing to %LuMB\n",
+			size >> 20, min_size >> 20);
+		size = min_size;
+	}
+	size = ALIGN_DOWN(size, FAKE_NODE_MIN_SIZE);
+
+	/*
+	 * Fill physical nodes with fake nodes of size until there is no memory
+	 * left on any of them.
+	 */
+	while (!nodes_empty(physnode_mask)) {
+		for_each_node_mask(i, physnode_mask) {
+#ifdef CONFIG_ZONE_DMA32
+			unsigned long dma32_max_pfn = PFN_DOWN(min(4UL * SZ_1G, memblock_end_of_DRAM() - 1) + 1);
+			u64 dma32_end = PFN_PHYS(dma32_max_pfn);
+#endif
+			u64 start, limit, end;
+			int phys_blk;
+
+			phys_blk = emu_find_memblk_by_nid(i, pi);
+			if (phys_blk < 0) {
+				node_clear(i, physnode_mask);
+				continue;
+			}
+
+			start = pi->blk[phys_blk].start;
+			limit = pi->blk[phys_blk].end;
+
+			if (uniform)
+				end = start + size;
+			else
+				end = find_end_of_node(start, limit, size);
+#ifdef CONFIG_ZONE_DMA32
+			/*
+			 * If there won't be at least FAKE_NODE_MIN_SIZE of
+			 * non-reserved memory in ZONE_DMA32 for the next node,
+			 * this one must extend to the boundary.
+			 */
+			if (end < dma32_end && dma32_end - end -
+			    mem_hole_size(end, dma32_end) < FAKE_NODE_MIN_SIZE)
+				end = dma32_end;
+#endif
+
+			/*
+			 * If there won't be enough non-reserved memory for the
+			 * next node, this one must extend to the end of the
+			 * physical node.
+			 */
+			if ((limit - end - mem_hole_size(end, limit) < size)
+					&& !uniform)
+				end = limit;
+
+			ret = emu_setup_memblk(ei, pi, nid++ % MAX_NUMNODES,
+					       phys_blk,
+					       min(end, limit) - start);
+			if (ret < 0)
+				return ret;
+		}
+	}
+	return nid;
+}
+
+static int __init split_nodes_size_interleave(struct numa_meminfo *ei,
+					      struct numa_meminfo *pi,
+					      u64 addr, u64 max_addr, u64 size)
+{
+	return split_nodes_size_interleave_uniform(ei, pi, addr, max_addr, size,
+			0, NULL, 0);
+}
+
+static int __init setup_emu2phys_nid(int *dfl_phys_nid)
+{
+	int i, max_emu_nid = 0;
+
+	*dfl_phys_nid = NUMA_NO_NODE;
+	for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++) {
+		if (emu_nid_to_phys[i] != NUMA_NO_NODE) {
+			max_emu_nid = i;
+			if (*dfl_phys_nid == NUMA_NO_NODE)
+				*dfl_phys_nid = emu_nid_to_phys[i];
+		}
+	}
+
+	return max_emu_nid;
+}
+
+/**
+ * numa_emulation - Emulate NUMA nodes
+ * @numa_meminfo: NUMA configuration to massage
+ * @numa_dist_cnt: The size of the physical NUMA distance table
+ *
+ * Emulate NUMA nodes according to the numa=fake kernel parameter.
+ * @numa_meminfo contains the physical memory configuration and is modified
+ * to reflect the emulated configuration on success.  @numa_dist_cnt is
+ * used to determine the size of the physical distance table.
+ *
+ * On success, the following modifications are made.
+ *
+ * - @numa_meminfo is updated to reflect the emulated nodes.
+ *
+ * - __apicid_to_node[] is updated such that APIC IDs are mapped to the
+ *   emulated nodes.
+ *
+ * - NUMA distance table is rebuilt to represent distances between emulated
+ *   nodes.  The distances are determined considering how emulated nodes
+ *   are mapped to physical nodes and match the actual distances.
+ *
+ * - emu_nid_to_phys[] reflects how emulated nodes are mapped to physical
+ *   nodes.  This is used by numa_add_cpu() and numa_remove_cpu().
+ *
+ * If emulation is not enabled or fails, emu_nid_to_phys[] is filled with
+ * identity mapping and no other modification is made.
+ */
+void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
+{
+	static struct numa_meminfo ei __initdata;
+	static struct numa_meminfo pi __initdata;
+	const u64 max_addr = PFN_PHYS(max_pfn);
+	u8 *phys_dist = NULL;
+	size_t phys_size = numa_dist_cnt * numa_dist_cnt * sizeof(phys_dist[0]);
+	int max_emu_nid, dfl_phys_nid;
+	int i, j, ret;
+
+	if (!emu_cmdline)
+		goto no_emu;
+
+	memset(&ei, 0, sizeof(ei));
+	pi = *numa_meminfo;
+
+	for (i = 0; i < MAX_NUMNODES; i++)
+		emu_nid_to_phys[i] = NUMA_NO_NODE;
+
+	/*
+	 * If the numa=fake command-line contains a 'M' or 'G', it represents
+	 * the fixed node size.  Otherwise, if it is just a single number N,
+	 * split the system RAM into N fake nodes.
+	 */
+	if (strchr(emu_cmdline, 'U')) {
+		nodemask_t physnode_mask = numa_nodes_parsed;
+		unsigned long n;
+		int nid = 0;
+
+		n = simple_strtoul(emu_cmdline, &emu_cmdline, 0);
+		ret = -1;
+		for_each_node_mask(i, physnode_mask) {
+			/*
+			 * The reason we pass in blk[0] is due to
+			 * numa_remove_memblk_from() called by
+			 * emu_setup_memblk() will delete entry 0
+			 * and then move everything else up in the pi.blk
+			 * array. Therefore we should always be looking
+			 * at blk[0].
+			 */
+			ret = split_nodes_size_interleave_uniform(&ei, &pi,
+					pi.blk[0].start, pi.blk[0].end, 0,
+					n, &pi.blk[0], nid);
+			if (ret < 0)
+				break;
+			if (ret < n) {
+				pr_info("%s: phys: %d only got %d of %ld nodes, failing\n",
+						__func__, i, ret, n);
+				ret = -1;
+				break;
+			}
+			nid = ret;
+		}
+	} else if (strchr(emu_cmdline, 'M') || strchr(emu_cmdline, 'G')) {
+		u64 size;
+
+		size = memparse(emu_cmdline, &emu_cmdline);
+		ret = split_nodes_size_interleave(&ei, &pi, 0, max_addr, size);
+	} else {
+		unsigned long n;
+
+		n = simple_strtoul(emu_cmdline, &emu_cmdline, 0);
+		ret = split_nodes_interleave(&ei, &pi, 0, max_addr, n);
+	}
+	if (*emu_cmdline == ':')
+		emu_cmdline++;
+
+	if (ret < 0)
+		goto no_emu;
+
+	if (numa_cleanup_meminfo(&ei) < 0) {
+		pr_warn("NUMA: Warning: constructed meminfo invalid, disabling emulation\n");
+		goto no_emu;
+	}
+
+	/* copy the physical distance table */
+	if (numa_dist_cnt) {
+		u64 phys;
+
+		phys = memblock_phys_alloc_range(phys_size, PAGE_SIZE, 0,
+						 MEMBLOCK_ALLOC_ACCESSIBLE);
+		if (!phys) {
+			pr_warn("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
+			goto no_emu;
+		}
+		phys_dist = __va(phys);
+
+		for (i = 0; i < numa_dist_cnt; i++)
+			for (j = 0; j < numa_dist_cnt; j++)
+				phys_dist[i * numa_dist_cnt + j] =
+					node_distance(i, j);
+	}
+
+	/*
+	 * Determine the max emulated nid and the default phys nid to use
+	 * for unmapped nodes.
+	 */
+	max_emu_nid = setup_emu2phys_nid(&dfl_phys_nid);
+
+	/* commit */
+	*numa_meminfo = ei;
+
+	/* Make sure numa_nodes_parsed only contains emulated nodes */
+	nodes_clear(numa_nodes_parsed);
+	for (i = 0; i < ARRAY_SIZE(ei.blk); i++)
+		if (ei.blk[i].start != ei.blk[i].end &&
+		    ei.blk[i].nid != NUMA_NO_NODE)
+			node_set(ei.blk[i].nid, numa_nodes_parsed);
+
+#ifdef CONFIG_X86
+	/*
+	 * Transform __apicid_to_node table to use emulated nids by
+	 * reverse-mapping phys_nid.  The maps should always exist but fall
+	 * back to zero just in case.
+	 */
+	for (i = 0; i < ARRAY_SIZE(__apicid_to_node); i++) {
+		if (__apicid_to_node[i] == NUMA_NO_NODE)
+			continue;
+		for (j = 0; j < ARRAY_SIZE(emu_nid_to_phys); j++)
+			if (__apicid_to_node[i] == emu_nid_to_phys[j])
+				break;
+		__apicid_to_node[i] = j < ARRAY_SIZE(emu_nid_to_phys) ? j : 0;
+	}
+#endif
+
+	/* make sure all emulated nodes are mapped to a physical node */
+	for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++)
+		if (emu_nid_to_phys[i] == NUMA_NO_NODE)
+			emu_nid_to_phys[i] = dfl_phys_nid;
+
+	/* transform distance table */
+	numa_free_distance();
+	for (i = 0; i < max_emu_nid + 1; i++) {
+		for (j = 0; j < max_emu_nid + 1; j++) {
+			int physi = emu_nid_to_phys[i];
+			int physj = emu_nid_to_phys[j];
+			int dist;
+
+			if (get_option(&emu_cmdline, &dist) == 2)
+				;
+			else if (physi >= numa_dist_cnt || physj >= numa_dist_cnt)
+				dist = physi == physj ?
+					LOCAL_DISTANCE : REMOTE_DISTANCE;
+			else
+				dist = phys_dist[physi * numa_dist_cnt + physj];
+
+			numa_set_distance(i, j, dist);
+		}
+	}
+
+	/* free the copied physical distance table */
+	memblock_free(phys_dist, phys_size);
+	return;
+
+no_emu:
+	/* No emulation.  Build identity emu_nid_to_phys[] for numa_add_cpu() */
+	for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++)
+		emu_nid_to_phys[i] = i;
+}
+
+#ifndef CONFIG_DEBUG_PER_CPU_MAPS
+void numa_add_cpu(unsigned int cpu)
+{
+	int physnid, nid;
+
+	nid = early_cpu_to_node(cpu);
+	BUG_ON(nid == NUMA_NO_NODE || !node_online(nid));
+
+	physnid = emu_nid_to_phys[nid];
+
+	/*
+	 * Map the cpu to each emulated node that is allocated on the physical
+	 * node of the cpu's apic id.
+	 */
+	for_each_online_node(nid)
+		if (emu_nid_to_phys[nid] == physnid)
+			cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
+}
+
+void numa_remove_cpu(unsigned int cpu)
+{
+	int i;
+
+	for_each_online_node(i)
+		cpumask_clear_cpu(cpu, node_to_cpumask_map[i]);
+}
+#else	/* !CONFIG_DEBUG_PER_CPU_MAPS */
+static void debug_cpumask_set_cpu(int cpu, int node, bool enable)
+{
+	struct cpumask *mask;
+
+	if (node == NUMA_NO_NODE) {
+		/* early_cpu_to_node() already emits a warning and trace */
+		return;
+	}
+	mask = node_to_cpumask_map[node];
+	if (!cpumask_available(mask)) {
+		pr_err("node_to_cpumask_map[%i] NULL\n", node);
+		dump_stack();
+		return;
+	}
+
+	if (enable)
+		cpumask_set_cpu(cpu, mask);
+	else
+		cpumask_clear_cpu(cpu, mask);
+
+	printk(KERN_DEBUG "%s cpu %d node %d: mask now %*pbl\n",
+		enable ? "numa_add_cpu" : "numa_remove_cpu",
+		cpu, node, cpumask_pr_args(mask));
+	return;
+}
+
+static void numa_set_cpumask(unsigned int cpu, bool enable)
+{
+	int nid, physnid;
+
+	nid = early_cpu_to_node(cpu);
+	if (nid == NUMA_NO_NODE) {
+		/* early_cpu_to_node() already emits a warning and trace */
+		return;
+	}
+
+	physnid = emu_nid_to_phys[nid];
+
+	for_each_online_node(nid) {
+		if (emu_nid_to_phys[nid] != physnid)
+			continue;
+
+		debug_cpumask_set_cpu(cpu, nid, enable);
+	}
+}
+
+void numa_add_cpu(unsigned int cpu)
+{
+	numa_set_cpumask(cpu, true);
+}
+
+void numa_remove_cpu(unsigned int cpu)
+{
+	numa_set_cpumask(cpu, false);
+}
+#endif	/* !CONFIG_DEBUG_PER_CPU_MAPS */
diff --git a/drivers/base/numa_emulation.h b/drivers/base/numa_emulation.h
new file mode 100644
index 000000000000..c54642006b7f
--- /dev/null
+++ b/drivers/base/numa_emulation.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __NUMA_FAKE_H
+#define __NUMA_FAKE_H
+
+#include <linux/types.h>
+#include <asm/numa.h>
+
+struct numa_memblk {
+	u64			start;
+	u64			end;
+	int			nid;
+};
+
+struct numa_meminfo {
+	int			nr_blks;
+	struct numa_memblk	blk[NR_NODE_MEMBLKS];
+};
+
+#ifdef CONFIG_NUMA_FAKE
+#define FAKE_NODE_MIN_SIZE	((u64)32 << 20)
+#define FAKE_NODE_MIN_HASH_MASK	(~(FAKE_NODE_MIN_SIZE - 1UL))
+int numa_emu_cmdline(char *str);
+
+void __init numa_emulation(struct numa_meminfo *numa_meminfo,
+			   int numa_dist_cnt);
+int __init numa_cleanup_meminfo(struct numa_meminfo *mi);
+int __init numa_register_memblks(struct numa_meminfo *mi);
+int __init numa_add_memblk_to(int nid, u64 start, u64 end,
+			      struct numa_meminfo *mi);
+int __init numa_emu_cmdline(char *str);
+#else /* CONFIG_NUMA_FAKE */
+static inline void numa_emulation(struct numa_meminfo *numa_meminfo,
+				  int numa_dist_cnt)
+{ }
+
+static inline int numa_emu_cmdline(char *str)
+{
+	return -EINVAL;
+}
+#endif
+#endif
-- 
2.32.0.3.gf3a3e56d6



From jay.buddhabhatti at amd.com  Tue Feb 20 03:45:52 2024
From: jay.buddhabhatti at amd.com (Buddhabhatti, Jay)
Date: Tue, 20 Feb 2024 11:45:52 +0000
Subject: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains property
In-Reply-To: <74cfdded-be3a-4af6-b23a-eea2c5e748b8@amd.com>
References: <202402192019160b9c4120@mail.local>
 <DM6PR12MB4465FAF7AB3F9CE15FAC6C879D502@DM6PR12MB4465.namprd12.prod.outlook.com>
 <74cfdded-be3a-4af6-b23a-eea2c5e748b8@amd.com>
Message-ID: <DM6PR12MB4465A3F36E78DDDD0B4C68F89D502@DM6PR12MB4465.namprd12.prod.outlook.com>

Hi Michal,

> -----Original Message-----
> From: Simek, Michal <michal.simek at amd.com>
> Sent: Tuesday, February 20, 2024 5:04 PM
> To: Buddhabhatti, Jay <jay.buddhabhatti at amd.com>; Alexandre Belloni
> <alexandre.belloni at bootlin.com>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>; linux-
> kernel at vger.kernel.org; monstr at monstr.eu; michal.simek at xilinx.com;
> git at xilinx.com; Conor Dooley <conor+dt at kernel.org>; Krzysztof Kozlowski
> <krzysztof.kozlowski+dt at linaro.org>; Rob Herring <robh at kernel.org>; open
> list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
> <devicetree at vger.kernel.org>; moderated list:ARM/ZYNQ ARCHITECTURE
> <linux-arm-kernel at lists.infradead.org>; open list:REAL TIME CLOCK (RTC)
> SUBSYSTEM <linux-rtc at vger.kernel.org>
> Subject: Re: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains
> property
> 
> 
> 
> On 2/20/24 11:51, Buddhabhatti, Jay wrote:
> > Hi Alexandre,
> >
> >> -----Original Message-----
> >> From: Alexandre Belloni <alexandre.belloni at bootlin.com>
> >> Sent: Tuesday, February 20, 2024 1:49 AM
> >> To: Simek, Michal <michal.simek at amd.com>
> >> Cc: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>; linux-
> >> kernel at vger.kernel.org; monstr at monstr.eu; michal.simek at xilinx.com;
> >> git at xilinx.com; Conor Dooley <conor+dt at kernel.org>; Krzysztof
> >> Kozlowski <krzysztof.kozlowski+dt at linaro.org>; Rob Herring
> >> <robh at kernel.org>; open list:OPEN FIRMWARE AND FLATTENED DEVICE
> TREE
> >> BINDINGS <devicetree at vger.kernel.org>; moderated list:ARM/ZYNQ
> >> ARCHITECTURE <linux-arm-kernel at lists.infradead.org>; open list:REAL
> >> TIME CLOCK (RTC) SUBSYSTEM <linux-rtc at vger.kernel.org>
> >> Subject: Re: [PATCH] dt-bindings: rtc: zynqmp: Describe power-domains
> >> property
> >>
> >> On 19/02/2024 14:11:50+0100, Michal Simek wrote:
> >>>
> >>>
> >>> On 2/17/24 09:26, Krzysztof Kozlowski wrote:
> >>>> On 16/02/2024 10:42, Michal Simek wrote:
> >>>>>
> >>>>>
> >>>>> On 2/16/24 10:19, Krzysztof Kozlowski wrote:
> >>>>>> On 16/02/2024 09:51, Michal Simek wrote:
> >>>>>>> RTC has its own power domain on Xilinx Versal SOC that's why
> >>>>>>> describe it as optional property.
> >>>>>>>
> >>>>>>> Signed-off-by: Michal Simek <michal.simek at amd.com>
> >>>>>>> ---
> >>>>>>>
> >>>>>>>     Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml |
> >>>>>>> 3
> >> +++
> >>>>>>>     1 file changed, 3 insertions(+)
> >>>>>>>
> >>>>>>
> >>>>>> But Versal is not described in this binding, is it? I see only
> >>>>>> one compatible.
> >>>>>
> >>>>> It is the same IP only as is on zynqmp with own power rail.
> >>>>
> >>>> Then you should have separate compatible, because they are not
> >>>> identical. It would also allow you to narrow the domains to versal
> >>>> and also require it (on versal).
> >>>
> >>> I can double check with HW guys but I am quite sure IP itself is
> >>> exactly the same. What it is different is that there is own power
> >>> domain to it (not shared one as is in zynqmp case).
> >>>
> >>> Also Linux is non secure sw and if secure firmware won't allow to
> >>> change setting of it it can't be required. I am just saying that
> >>> Linux doesn't need to be owner of any power domain that's why it
> >>> shouldn't be required property.
> >>
> >> I guess because the integration is different, you still need a
> >> differente compatible so you can forbid the property on non-Versal.
> >
> > [Jay] RTC has its own power domain in case of Versal and ZynqMP both that
> we double check it.
> 
> Thanks Jay for looking into it. I should definitely update my commit message to
> reflect it. Do you still want me to create soc specific property?

[Jay] This should be for both ZynqMP and Versal since RTC have its own power domain we should add power domain property for both SoCs.

> 
> Thanks,
> Michal

From maz at kernel.org  Tue Feb 20 03:47:31 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 20 Feb 2024 11:47:31 +0000
Subject: [PATCH] genirq/irqdomain: Don't call ops->select for DOMAIN_BUS_ANY tokens
Message-ID: <20240220114731.1898534-1-maz@kernel.org>

Users of the IRQCHIP_PLATFORM_DRIVER_{BEGIN,END} helpers rely
on a fwspec containing only the fwnode (and crucially a number
of parameters set to 0) together with a DOMAIN_BUS_ANY token
to check whether a parent irqchip has probed and registered
a domain.

Since de1ff306dcf4 ("genirq/irqdomain: Remove the param count
restriction from select()"), we call ops->select unconditionally,
meaning that irqchips implementing select now need to handle
ANY as a match.

Instead of adding more esoteric checks to the individual drivers,
add that condition to irq_find_matching_fwspec(), and let it
handle the corner case, as per the comment in the function.

This restores the functionnality of the above helpers.

Reported-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Tested-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Reported-by: Biju Das <biju.das.jz at bp.renesas.com>
Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from select()")
Signed-off-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/r/20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f at linaro.org
---
 kernel/irq/irqdomain.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index aeb41655d6de..3dd1c871e091 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -449,7 +449,7 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
 	 */
 	mutex_lock(&irq_domain_mutex);
 	list_for_each_entry(h, &irq_domain_list, link) {
-		if (h->ops->select)
+		if (h->ops->select && bus_token != DOMAIN_BUS_ANY)
 			rc = h->ops->select(h, fwspec, bus_token);
 		else if (h->ops->match)
 			rc = h->ops->match(h, to_of_node(fwnode), bus_token);
-- 
2.39.2



From will at kernel.org  Tue Feb 20 03:49:38 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 20 Feb 2024 11:49:38 +0000
Subject: arm64/for-kernelci build: 1 build: 0 failed, 1 passed, 1 warning
 (v6.8-rc4-55-g905b00721763)
In-Reply-To: <65cfcc14.170a0220.b8b50.24d9@mx.google.com>
References: <65cfcc14.170a0220.b8b50.24d9@mx.google.com>
Message-ID: <20240220114937.GA5545@willie-the-truck>

[+Paul Moore for the array bounds warning]

On Fri, Feb 16, 2024 at 12:56:52PM -0800, kernelci.org bot wrote:
> arm64/for-kernelci build: 1 build: 0 failed, 1 passed, 1 warning (v6.8-rc4-55-g905b00721763)
> 
> Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v6.8-rc4-55-g905b00721763/
> 
> Tree: arm64
> Branch: for-kernelci
> Git Describe: v6.8-rc4-55-g905b00721763
> Git Commit: 905b007217637b34a6a877271f21ed0dada0f564
> Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
> Built: 1 unique architecture
> 
> Warnings Detected:
> 
> arm64:
>     defconfig (gcc-10): 1 warning
> 
> 
> Warnings summary:
> 
>     1    security/security.c:810:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]
> 
> ================================================================================
> 
> Detailed per-defconfig build reports:
> 
> --------------------------------------------------------------------------------
> defconfig (arm64, gcc-10) ? PASS, 0 errors, 1 warning, 0 section mismatches
> 
> Warnings:
>     security/security.c:810:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

Paul, sorry if you've had lots of these reports already, but this one keeps
showing up in our CI and I don't think it's related to any of our arm64
changes. So, on the off chance that you're not aware, here it is!

Will


From peter.griffin at linaro.org  Tue Feb 20 03:50:09 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 20 Feb 2024 11:50:09 +0000
Subject: [PATCH 0/3] mfd syscon and altera-sysmgr cleanup
Message-ID: <20240220115012.471689-1-peter.griffin@linaro.org>

Hi,

Whilst implementing a driver similar to altera-sysmgr for exynos
it was noticed during the review feedback that we should only call
of_node_put() if the property is provided otherwise nothing has
taken a reference on the node. Both syscon and altera-sysmgr also
have the same issue which this series fixes.

Another piece of review feedback was not to use extern keyword in
the header file, so I also cleaned that up whilst being here.

regards,

Peter.

Peter Griffin (3):
  mfd: syscon: call of_node_put() only when of_parse_phandle() takes a
    ref
  mfd: syscon: remove extern from function prototypes
  mfd: altera-sysmgr: call of_node_put() only when of_parse_phandle()
    takes a ref

 drivers/mfd/altera-sysmgr.c |  4 +++-
 drivers/mfd/syscon.c        |  4 +++-
 include/linux/mfd/syscon.h  | 25 +++++++++++--------------
 3 files changed, 17 insertions(+), 16 deletions(-)

-- 
2.44.0.rc0.258.g7320e95886-goog



From peter.griffin at linaro.org  Tue Feb 20 03:50:10 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 20 Feb 2024 11:50:10 +0000
Subject: [PATCH 1/3] mfd: syscon: call of_node_put() only when of_parse_phandle() takes a ref
In-Reply-To: <20240220115012.471689-1-peter.griffin@linaro.org>
References: <20240220115012.471689-1-peter.griffin@linaro.org>
Message-ID: <20240220115012.471689-2-peter.griffin@linaro.org>

of_parse_phandle() returns a device_node with refcount incremented, which
the callee needs to call of_node_put() on when done. We should only call
of_node_put() when the property argument is provided though as otherwise
nothing has taken a reference on the node.

Fixes: 45330bb43421 ("mfd: syscon: Allow property as NULL in syscon_regmap_lookup_by_phandle")
Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 drivers/mfd/syscon.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index c9550368d9ea..7d0e91164cba 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -238,7 +238,9 @@ struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
 		return ERR_PTR(-ENODEV);
 
 	regmap = syscon_node_to_regmap(syscon_np);
-	of_node_put(syscon_np);
+
+	if (property)
+		of_node_put(syscon_np);
 
 	return regmap;
 }
-- 
2.44.0.rc0.258.g7320e95886-goog



From peter.griffin at linaro.org  Tue Feb 20 03:50:11 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 20 Feb 2024 11:50:11 +0000
Subject: [PATCH 2/3] mfd: syscon: remove extern from function prototypes
In-Reply-To: <20240220115012.471689-1-peter.griffin@linaro.org>
References: <20240220115012.471689-1-peter.griffin@linaro.org>
Message-ID: <20240220115012.471689-3-peter.griffin@linaro.org>

The kernel coding style does not require 'extern' in function prototypes
in .h files, so remove them as they are not needed.

To avoid checkpatch warnings such as
CHECK: Lines should not end with a '('
+struct regmap *syscon_regmap_lookup_by_phandle(

The indentation is also updated. No functional changes in this patch.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 include/linux/mfd/syscon.h | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h
index fecc2fa2a364..c315903f6dab 100644
--- a/include/linux/mfd/syscon.h
+++ b/include/linux/mfd/syscon.h
@@ -17,20 +17,17 @@
 struct device_node;
 
 #ifdef CONFIG_MFD_SYSCON
-extern struct regmap *device_node_to_regmap(struct device_node *np);
-extern struct regmap *syscon_node_to_regmap(struct device_node *np);
-extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
-extern struct regmap *syscon_regmap_lookup_by_phandle(
-					struct device_node *np,
-					const char *property);
-extern struct regmap *syscon_regmap_lookup_by_phandle_args(
-					struct device_node *np,
-					const char *property,
-					int arg_count,
-					unsigned int *out_args);
-extern struct regmap *syscon_regmap_lookup_by_phandle_optional(
-					struct device_node *np,
-					const char *property);
+struct regmap *device_node_to_regmap(struct device_node *np);
+struct regmap *syscon_node_to_regmap(struct device_node *np);
+struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
+struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
+					       const char *property);
+struct regmap *syscon_regmap_lookup_by_phandle_args(struct device_node *np,
+						    const char *property,
+						    int arg_count,
+						    unsigned int *out_args);
+struct regmap *syscon_regmap_lookup_by_phandle_optional(struct device_node *np,
+							const char *property);
 #else
 static inline struct regmap *device_node_to_regmap(struct device_node *np)
 {
-- 
2.44.0.rc0.258.g7320e95886-goog



From peter.griffin at linaro.org  Tue Feb 20 03:50:12 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 20 Feb 2024 11:50:12 +0000
Subject: [PATCH 3/3] mfd: altera-sysmgr: call of_node_put() only when of_parse_phandle() takes a ref
In-Reply-To: <20240220115012.471689-1-peter.griffin@linaro.org>
References: <20240220115012.471689-1-peter.griffin@linaro.org>
Message-ID: <20240220115012.471689-4-peter.griffin@linaro.org>

of_parse_phandle() returns a device_node with refcount incremented, which
the callee needs to call of_node_put() on when done. We should only call
of_node_put() when the property argument is provided though as otherwise
nothing has taken a reference on the node.

Fixes: f36e789a1f8d ("mfd: altera-sysmgr: Add SOCFPGA System Manager")
Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 drivers/mfd/altera-sysmgr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c
index 0e52bd2ebd74..fb5f988e61f3 100644
--- a/drivers/mfd/altera-sysmgr.c
+++ b/drivers/mfd/altera-sysmgr.c
@@ -109,7 +109,9 @@ struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
 
 	dev = driver_find_device_by_of_node(&altr_sysmgr_driver.driver,
 					    (void *)sysmgr_np);
-	of_node_put(sysmgr_np);
+	if (property)
+		of_node_put(sysmgr_np);
+
 	if (!dev)
 		return ERR_PTR(-EPROBE_DEFER);
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From bjorn at kernel.org  Tue Feb 20 03:52:42 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Tue, 20 Feb 2024 12:52:42 +0100
Subject: [PATCH v13 06/13] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <20240220060718.823229-7-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-7-apatel@ventanamicro.com>
Message-ID: <87frxnfj3p.fsf@all.your.base.are.belong.to.us>

Anup,

This version is so much easier to follow! Thanks a lot for then
cleanups/design changes.

A bunch of nits, and a major one, below.

Anup Patel <apatel at ventanamicro.com> writes:

> The RISC-V advanced interrupt architecture (AIA) specification
> defines a new MSI controller called incoming message signalled
> interrupt controller (IMSIC) which manages MSI on per-HART (or
> per-CPU) basis. It also supports IPIs as software injected MSIs.
> (For more details refer https://github.com/riscv/riscv-aia)
>
> Let us add an early irqchip driver for RISC-V IMSIC which sets
> up the IMSIC state and provide IPIs.
>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> ---
>  drivers/irqchip/Kconfig                 |   7 +
>  drivers/irqchip/Makefile                |   1 +
>  drivers/irqchip/irq-riscv-imsic-early.c | 213 ++++++
>  drivers/irqchip/irq-riscv-imsic-state.c | 906 ++++++++++++++++++++++++
>  drivers/irqchip/irq-riscv-imsic-state.h |  98 +++
>  include/linux/irqchip/riscv-imsic.h     |  87 +++
>  6 files changed, 1312 insertions(+)
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-early.c
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-state.c
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-state.h
>  create mode 100644 include/linux/irqchip/riscv-imsic.h
>
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index f7149d0f3d45..85f86e31c996 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -546,6 +546,13 @@ config SIFIVE_PLIC
>  	select IRQ_DOMAIN_HIERARCHY
>  	select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
>  
> +config RISCV_IMSIC
> +	bool
> +	depends on RISCV
> +	select IRQ_DOMAIN_HIERARCHY
> +	select GENERIC_IRQ_MATRIX_ALLOCATOR
> +	select GENERIC_MSI_IRQ
> +
>  config EXYNOS_IRQ_COMBINER
>  	bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
>  	depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index ffd945fe71aa..d714724387ce 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
>  obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
>  obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
>  obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
> +obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o
>  obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
>  obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
>  obj-$(CONFIG_IMX_INTMUX)		+= irq-imx-intmux.o
> diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
> new file mode 100644
> index 000000000000..32fe428b1c19
> --- /dev/null
> +++ b/drivers/irqchip/irq-riscv-imsic-early.c
> @@ -0,0 +1,213 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> + * Copyright (C) 2022 Ventana Micro Systems Inc.
> + */
> +
> +#define pr_fmt(fmt) "riscv-imsic: " fmt
> +#include <linux/cpu.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/module.h>
> +#include <linux/spinlock.h>
> +#include <linux/smp.h>
> +
> +#include "irq-riscv-imsic-state.h"
> +
> +static int imsic_parent_irq;
> +
> +#ifdef CONFIG_SMP
> +static void imsic_ipi_send(unsigned int cpu)
> +{
> +	struct imsic_local_config *local = per_cpu_ptr(imsic->global.local, cpu);
> +
> +	writel_relaxed(IMSIC_IPI_ID, local->msi_va);
> +}
> +
> +static void imsic_ipi_starting_cpu(void)
> +{
> +	/* Enable IPIs for current CPU. */
> +	__imsic_id_set_enable(IMSIC_IPI_ID);
> +}
> +
> +static void imsic_ipi_dying_cpu(void)
> +{
> +	/* Disable IPIs for current CPU. */
> +	__imsic_id_clear_enable(IMSIC_IPI_ID);
> +}
> +
> +static int __init imsic_ipi_domain_init(void)
> +{
> +	int virq;
> +
> +	/* Create IMSIC IPI multiplexing */
> +	virq = ipi_mux_create(IMSIC_NR_IPI, imsic_ipi_send);
> +	if (virq <= 0)
> +		return (virq < 0) ? virq : -ENOMEM;

Nit: No parenthesis need to clutter.

> +
> +	/* Set vIRQ range */
> +	riscv_ipi_set_virq_range(virq, IMSIC_NR_IPI, true);
> +
> +	/* Announce that IMSIC is providing IPIs */
> +	pr_info("%pfwP: providing IPIs using interrupt %d\n", imsic->fwnode, IMSIC_IPI_ID);
> +
> +	return 0;
> +}
> +#else
> +static void imsic_ipi_starting_cpu(void)
> +{
> +}
> +
> +static void imsic_ipi_dying_cpu(void)
> +{
> +}
> +
> +static int __init imsic_ipi_domain_init(void)
> +{
> +	return 0;
> +}
> +#endif
> +
> +/*
> + * To handle an interrupt, we read the TOPEI CSR and write zero in one
> + * instruction. If TOPEI CSR is non-zero then we translate TOPEI.ID to
> + * Linux interrupt number and let Linux IRQ subsystem handle it.
> + */
> +static void imsic_handle_irq(struct irq_desc *desc)
> +{
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	int err, cpu = smp_processor_id();
> +	struct imsic_vector *vec;
> +	unsigned long local_id;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	while ((local_id = csr_swap(CSR_TOPEI, 0))) {
> +		local_id = local_id >> TOPEI_ID_SHIFT;

Nit: Wdyt about moving shift into the loop predicate, or using >>=?

> +
> +		if (local_id == IMSIC_IPI_ID) {
> +#ifdef CONFIG_SMP
> +			ipi_mux_process();
> +#endif

Is IMSIC_IPI_ID a thing on !IS_ENABLED(CONFIG_SMP)?

> +			continue;
> +		}
> +
> +		if (unlikely(!imsic->base_domain))
> +			continue;
> +
> +		vec = imsic_vector_from_local_id(cpu, local_id);
> +		if (!vec) {
> +			pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id);
> +			continue;
> +		}
> +
> +		err = generic_handle_domain_irq(imsic->base_domain,
> +						vec->hwirq);

Nit: 100 chars

> +		if (unlikely(err))
> +			pr_warn_ratelimited("hwirq 0x%x mapping not found\n", vec->hwirq);
> +	}
> +
> +	chained_irq_exit(chip, desc);
> +}
> +
> +static int imsic_starting_cpu(unsigned int cpu)
> +{
> +	/* Mark per-CPU IMSIC state as online */
> +	imsic_state_online();
> +
> +	/* Enable per-CPU parent interrupt */
> +	enable_percpu_irq(imsic_parent_irq, irq_get_trigger_type(imsic_parent_irq));
> +
> +	/* Setup IPIs */
> +	imsic_ipi_starting_cpu();
> +
> +	/*
> +	 * Interrupts identities might have been enabled/disabled while
> +	 * this CPU was not running so sync-up local enable/disable state.
> +	 */
> +	imsic_local_sync_all();
> +
> +	/* Enable local interrupt delivery */
> +	imsic_local_delivery(true);
> +
> +	return 0;
> +}
> +
> +static int imsic_dying_cpu(unsigned int cpu)
> +{
> +	/* Cleanup IPIs */
> +	imsic_ipi_dying_cpu();
> +
> +	/* Mark per-CPU IMSIC state as offline */
> +	imsic_state_offline();
> +
> +	return 0;
> +}
> +
> +static int __init imsic_early_probe(struct fwnode_handle *fwnode)
> +{
> +	struct irq_domain *domain;
> +	int rc;
> +
> +	/* Find parent domain and register chained handler */
> +	domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS_ANY);
> +	if (!domain) {
> +		pr_err("%pfwP: Failed to find INTC domain\n", fwnode);
> +		return -ENOENT;
> +	}
> +	imsic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
> +	if (!imsic_parent_irq) {
> +		pr_err("%pfwP: Failed to create INTC mapping\n", fwnode);
> +		return -ENOENT;
> +	}
> +
> +	/* Initialize IPI domain */
> +	rc = imsic_ipi_domain_init();
> +	if (rc) {
> +		pr_err("%pfwP: Failed to initialize IPI domain\n", fwnode);
> +		return rc;
> +	}
> +
> +	/* Setup chained handler to the parent domain interrupt */
> +	irq_set_chained_handler(imsic_parent_irq, imsic_handle_irq);
> +
> +	/*
> +	 * Setup cpuhp state (must be done after setting imsic_parent_irq)
> +	 *
> +	 * Don't disable per-CPU IMSIC file when CPU goes offline
> +	 * because this affects IPI and the masking/unmasking of
> +	 * virtual IPIs is done via generic IPI-Mux
> +	 */
> +	cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "irqchip/riscv/imsic:starting",
> +			  imsic_starting_cpu, imsic_dying_cpu);
> +
> +	return 0;
> +}
> +
> +static int __init imsic_early_dt_init(struct device_node *node,
> +				      struct device_node *parent)
> +{
> +	struct fwnode_handle *fwnode = &node->fwnode;
> +	int rc;
> +
> +	/* Setup IMSIC state */
> +	rc = imsic_setup_state(fwnode);
> +	if (rc) {
> +		pr_err("%pfwP: failed to setup state (error %d)\n",
> +			fwnode, rc);

Nit. 100 chars

> +		return rc;
> +	}
> +
> +	/* Do early setup of IPIs */
> +	rc = imsic_early_probe(fwnode);
> +	if (rc)
> +		return rc;
> +
> +	/* Ensure that OF platform device gets probed */
> +	of_node_clear_flag(node, OF_POPULATED);
> +	return 0;
> +}
> +IRQCHIP_DECLARE(riscv_imsic, "riscv,imsics", imsic_early_dt_init);
> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> new file mode 100644
> index 000000000000..4f347486ec7c
> --- /dev/null
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -0,0 +1,906 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> + * Copyright (C) 2022 Ventana Micro Systems Inc.
> + */
> +
> +#define pr_fmt(fmt) "riscv-imsic: " fmt
> +#include <linux/cpu.h>
> +#include <linux/bitmap.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/seq_file.h>
> +#include <linux/spinlock.h>
> +#include <linux/smp.h>
> +#include <asm/hwcap.h>
> +
> +#include "irq-riscv-imsic-state.h"
> +
> +#define IMSIC_DISABLE_EIDELIVERY		0
> +#define IMSIC_ENABLE_EIDELIVERY			1
> +#define IMSIC_DISABLE_EITHRESHOLD		1
> +#define IMSIC_ENABLE_EITHRESHOLD		0
> +
> +static inline void imsic_csr_write(unsigned long reg, unsigned long val)
> +{
> +	csr_write(CSR_ISELECT, reg);
> +	csr_write(CSR_IREG, val);
> +}
> +
> +static inline unsigned long imsic_csr_read(unsigned long reg)
> +{
> +	csr_write(CSR_ISELECT, reg);
> +	return csr_read(CSR_IREG);
> +}
> +
> +static inline unsigned long imsic_csr_read_clear(unsigned long reg, unsigned long val)
> +{
> +	csr_write(CSR_ISELECT, reg);
> +	return csr_read_clear(CSR_IREG, val);
> +}
> +
> +static inline void imsic_csr_set(unsigned long reg, unsigned long val)
> +{
> +	csr_write(CSR_ISELECT, reg);
> +	csr_set(CSR_IREG, val);
> +}
> +
> +static inline void imsic_csr_clear(unsigned long reg, unsigned long val)
> +{
> +	csr_write(CSR_ISELECT, reg);
> +	csr_clear(CSR_IREG, val);
> +}
> +
> +struct imsic_priv *imsic;
> +
> +const struct imsic_global_config *imsic_get_global_config(void)
> +{
> +	return imsic ? &imsic->global : NULL;
> +}
> +EXPORT_SYMBOL_GPL(imsic_get_global_config);
> +
> +static bool __imsic_eix_read_clear(unsigned long id, bool pend)
> +{
> +	unsigned long isel, imask;
> +
> +	isel = id / BITS_PER_LONG;
> +	isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
> +	isel += pend ? IMSIC_EIP0 : IMSIC_EIE0;
> +	imask = BIT(id & (__riscv_xlen - 1));
> +
> +	return (imsic_csr_read_clear(isel, imask) & imask) ? true : false;

Nit: use return !!(imsic_csr_read_clear(isel, imask) & imask)

> +}
> +
> +static inline bool __imsic_id_read_clear_enabled(unsigned long id)
> +{
> +	return __imsic_eix_read_clear(id, false);
> +}
> +
> +static inline bool __imsic_id_read_clear_pending(unsigned long id)
> +{
> +	return __imsic_eix_read_clear(id, true);
> +}
> +
> +void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val)
> +{
> +	unsigned long id = base_id, last_id = base_id + num_id;
> +	unsigned long i, isel, ireg;
> +
> +	while (id < last_id) {
> +		isel = id / BITS_PER_LONG;
> +		isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
> +		isel += (pend) ? IMSIC_EIP0 : IMSIC_EIE0;

Nit: Redundant parenthesis.

> +
> +		/*
> +		 * Prepare the ID mask to be programmed in the
> +		 * IMSIC EIEx and EIPx registers. These registers
> +		 * are XLEN-wide and we must not touch IDs which
> +		 * are < base_id and >= (base_id + num_id).
> +		 */
> +		ireg = 0;
> +		for (i = id & (__riscv_xlen - 1); (id < last_id) && (i < __riscv_xlen); i++) {

Nit: Redundant parenthesis "(id < last_id) && (i < __riscv_xlen)", which
is also inconsistent with other usage in this changeset.

> +			ireg |= BIT(i);
> +			id++;
> +		}
> +
> +		/*
> +		 * The IMSIC EIEx and EIPx registers are indirectly
> +		 * accessed via using ISELECT and IREG CSRs so we
> +		 * need to access these CSRs without getting preempted.
> +		 *
> +		 * All existing users of this function call this
> +		 * function with local IRQs disabled so we don't
> +		 * need to do anything special here.
> +		 */
> +		if (val)
> +			imsic_csr_set(isel, ireg);
> +		else
> +			imsic_csr_clear(isel, ireg);
> +	}
> +}
> +
> +/* MUST be called with lpriv->lock held */
> +static void __imsic_local_sync(struct imsic_local_priv *lpriv)
> +{
> +	struct imsic_local_config *mlocal;
> +	struct imsic_vector *vec, *mvec;
> +	int i;
> +
> +	/* This pairs with the barrier in __imsic_remote_sync(). */
> +	smp_mb();
> +
> +	for_each_set_bit(i, lpriv->dirty_bitmap, imsic->global.nr_ids + 1) {
> +		if (!i || i == IMSIC_IPI_ID)
> +			goto skip;
> +		vec = &lpriv->vectors[i];
> +
> +		if (vec->enable)
> +			__imsic_id_set_enable(i);
> +		else
> +			__imsic_id_clear_enable(i);
> +
> +		/*
> +		 * If the ID was being moved to a new ID on some other CPU
> +		 * then we can get a MSI during the movement so check the
> +		 * ID pending bit and re-trigger the new ID on other CPU
> +		 * using MMIO write.
> +		 */
> +		mvec = vec->move;
> +		vec->move = NULL;
> +		if (mvec && mvec != vec) {
> +			if (__imsic_id_read_clear_pending(i)) {
> +				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
> +				writel_relaxed(mvec->local_id, mlocal->msi_va);
> +			}
> +
> +			imsic_vector_free(&lpriv->vectors[i]);
> +		}
> +
> +skip:
> +		bitmap_clear(lpriv->dirty_bitmap, i, 1);
> +	}
> +}
> +
> +void imsic_local_sync_all(void)
> +{
> +	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +	bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
> +	__imsic_local_sync(lpriv);
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> +}
> +
> +void imsic_local_delivery(bool enable)
> +{
> +	if (enable) {
> +		imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
> +		imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
> +		return;
> +	}
> +
> +	imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
> +	imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
> +}
> +
> +#ifdef CONFIG_SMP
> +static void imsic_local_timer_callback(struct timer_list *timer)
> +{
> +	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +	__imsic_local_sync(lpriv);
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> +}
> +
> +/* MUST be called with lpriv->lock held */
> +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
> +{
> +	/*
> +	 * Ensure that changes to vector enable, vector move and
> +	 * dirty bitmap are visible to the target CPU.
> +	 *
> +	 * This pairs with the barrier in __imsic_local_sync().
> +	 */
> +	smp_mb();
> +
> +	/*
> +	 * We schedule a timer on the target CPU if the target CPU is not
> +	 * same as the current CPU. An offline CPU will unconditionally
> +	 * synchronize IDs through imsic_starting_cpu() when the
> +	 * CPU is brought up.
> +	 */
> +	if (cpu_online(cpu)) {
> +		if (cpu != smp_processor_id()) {
> +			if (!timer_pending(&lpriv->timer)) {
> +				lpriv->timer.expires = jiffies + 1;
> +				add_timer_on(&lpriv->timer, cpu);
> +			}
> +		} else {
> +			__imsic_local_sync(lpriv);
> +		}

Nit: Early exit/return vs else-clause for readability


> +	}
> +}
> +#else
> +/* MUST be called with lpriv->lock held */
> +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
> +{
> +	__imsic_local_sync(lpriv);
> +}
> +#endif
> +
> +void imsic_vector_mask(struct imsic_vector *vec)
> +{
> +	struct imsic_local_priv *lpriv;
> +
> +	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> +	if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> +		return;
> +
> +	/*
> +	 * This function is called through Linux irq subsystem with
> +	 * irqs disabled so no need to save/restore irq flags.
> +	 */
> +
> +	raw_spin_lock(&lpriv->lock);
> +
> +	vec->enable = false;
> +	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> +	__imsic_remote_sync(lpriv, vec->cpu);
> +
> +	raw_spin_unlock(&lpriv->lock);
> +}

Really nice that you're using a timer for the vector affinity change,
and got rid of the special/weird IMSIC/sync IPI. Can you really use a
timer for mask/unmask? That makes the mask/unmask operation
asynchronous!

That was what I was trying to get though with this comment:
https://lore.kernel.org/linux-riscv/87sf24mo1g.fsf at all.your.base.are.belong.to.us/

Also, using the smp_* IPI functions, you can pass arguments, so you
don't need the dirty_bitmap tracking the changes.

> +
> +void imsic_vector_unmask(struct imsic_vector *vec)
> +{
> +	struct imsic_local_priv *lpriv;
> +
> +	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> +	if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> +		return;
> +
> +	/*
> +	 * This function is called through Linux irq subsystem with
> +	 * irqs disabled so no need to save/restore irq flags.
> +	 */
> +
> +	raw_spin_lock(&lpriv->lock);
> +
> +	vec->enable = true;
> +	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> +	__imsic_remote_sync(lpriv, vec->cpu);
> +
> +	raw_spin_unlock(&lpriv->lock);
> +}
> +
> +
> +bool imsic_vector_isenabled(struct imsic_vector *vec)
> +{
> +	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> +	unsigned long flags;
> +	bool ret;
> +
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +	ret = vec->enable;
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> +
> +	return ret;
> +}
> +
> +struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec)
> +{
> +	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> +	struct imsic_vector *ret;
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +	ret = vec->move;
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> +
> +	return ret;
> +}
> +
> +static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, struct imsic_vector *vec,
> +				     bool new_enable, struct imsic_vector *new_move)
> +{
> +	unsigned long flags;
> +	bool enabled;
> +
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +
> +	/* Update enable and move details */
> +	enabled = vec->enable;
> +	vec->enable = new_enable;
> +	vec->move = new_move;
> +
> +	/* Mark the vector as dirty and synchronize */
> +	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> +	__imsic_remote_sync(lpriv, vec->cpu);
> +
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> +
> +	return enabled;
> +}
> +
> +void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec)
> +{
> +	struct imsic_local_priv *old_lpriv, *new_lpriv;
> +	bool enabled;
> +
> +	if (WARN_ON(old_vec->cpu == new_vec->cpu))
> +		return;
> +
> +	old_lpriv = per_cpu_ptr(imsic->lpriv, old_vec->cpu);
> +	if (WARN_ON(&old_lpriv->vectors[old_vec->local_id] != old_vec))
> +		return;
> +
> +	new_lpriv = per_cpu_ptr(imsic->lpriv, new_vec->cpu);
> +	if (WARN_ON(&new_lpriv->vectors[new_vec->local_id] != new_vec))
> +		return;
> +
> +	/*
> +	 * Move and re-trigger the new vector based on the pending
> +	 * state of the old vector because we might get a device
> +	 * interrupt on the old vector while device was being moved
> +	 * to the new vector.
> +	 */
> +	enabled = imsic_vector_move_update(old_lpriv, old_vec, false, new_vec);
> +	imsic_vector_move_update(new_lpriv, new_vec, enabled, new_vec);
> +}
> +
> +#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
> +void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind)
> +{
> +	struct imsic_local_priv *lpriv;
> +	struct imsic_vector *mvec;
> +	bool is_enabled;
> +
> +	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> +	if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> +		return;
> +
> +	is_enabled = imsic_vector_isenabled(vec);
> +	mvec = imsic_vector_get_move(vec);
> +
> +	seq_printf(m, "%*starget_cpu      : %5u\n", ind, "", vec->cpu);
> +	seq_printf(m, "%*starget_local_id : %5u\n", ind, "", vec->local_id);
> +	seq_printf(m, "%*sis_reserved     : %5u\n", ind, "",
> +		   (vec->local_id <= IMSIC_IPI_ID) ? 1 : 0);
> +	seq_printf(m, "%*sis_enabled      : %5u\n", ind, "", (is_enabled) ? 1 : 0);
> +	seq_printf(m, "%*sis_move_pending : %5u\n", ind, "", (mvec) ? 1 : 0);

Nit: Redundant parenthesis.

> +	if (mvec) {
> +		seq_printf(m, "%*smove_cpu        : %5u\n", ind, "", mvec->cpu);
> +		seq_printf(m, "%*smove_local_id   : %5u\n", ind, "", mvec->local_id);
> +	}
> +}
> +
> +void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
> +{
> +	irq_matrix_debug_show(m, imsic->matrix, ind);
> +}
> +#endif
> +
> +struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
> +{
> +	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> +
> +	if (!lpriv || imsic->global.nr_ids < local_id)
> +		return NULL;
> +
> +	return &lpriv->vectors[local_id];
> +}
> +
> +struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask)
> +{
> +	struct imsic_vector *vec = NULL;
> +	struct imsic_local_priv *lpriv;
> +	unsigned long flags;
> +	unsigned int cpu;
> +	int local_id;
> +
> +	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> +	local_id = irq_matrix_alloc(imsic->matrix, mask, false, &cpu);
> +	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> +	if (local_id < 0)
> +		return NULL;
> +
> +	lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> +	vec = &lpriv->vectors[local_id];
> +	vec->hwirq = hwirq;
> +	vec->enable = false;
> +	vec->move = NULL;
> +
> +	return vec;
> +}
> +
> +void imsic_vector_free(struct imsic_vector *vec)
> +{
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> +	vec->hwirq = UINT_MAX;
> +	irq_matrix_free(imsic->matrix, vec->cpu, vec->local_id, false);
> +	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> +}
> +
> +static void __init imsic_local_cleanup(void)
> +{
> +	int cpu;
> +	struct imsic_local_priv *lpriv;
> +
> +	for_each_possible_cpu(cpu) {
> +		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> +
> +		bitmap_free(lpriv->dirty_bitmap);
> +		kfree(lpriv->vectors);
> +	}
> +
> +	free_percpu(imsic->lpriv);
> +}
> +
> +static int __init imsic_local_init(void)
> +{
> +	struct imsic_global_config *global = &imsic->global;
> +	struct imsic_local_priv *lpriv;
> +	struct imsic_vector *vec;
> +	int cpu, i;
> +
> +	/* Allocate per-CPU private state */
> +	imsic->lpriv = alloc_percpu(typeof(*(imsic->lpriv)));
> +	if (!imsic->lpriv)
> +		return -ENOMEM;
> +
> +	/* Setup per-CPU private state */
> +	for_each_possible_cpu(cpu) {
> +		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> +
> +		raw_spin_lock_init(&lpriv->lock);
> +
> +		/* Allocate dirty bitmap */
> +		lpriv->dirty_bitmap = bitmap_zalloc(global->nr_ids + 1, GFP_KERNEL);
> +		if (!lpriv->dirty_bitmap)
> +			goto fail_local_cleanup;
> +
> +#ifdef CONFIG_SMP
> +		/* Setup lazy timer for synchronization */
> +		timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
> +#endif
> +
> +		/* Allocate vector array */
> +		lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
> +					 GFP_KERNEL);
> +		if (!lpriv->vectors)
> +			goto fail_local_cleanup;
> +
> +		/* Setup vector array */
> +		for (i = 0; i <= global->nr_ids; i++) {
> +			vec = &lpriv->vectors[i];
> +			vec->cpu = cpu;
> +			vec->local_id = i;
> +			vec->hwirq = UINT_MAX;
> +		}
> +	}
> +
> +	return 0;
> +
> +fail_local_cleanup:
> +	imsic_local_cleanup();
> +	return -ENOMEM;
> +}
> +
> +void imsic_state_online(void)
> +{
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> +	irq_matrix_online(imsic->matrix);
> +	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> +}
> +
> +void imsic_state_offline(void)
> +{
> +#ifdef CONFIG_SMP
> +	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> +#endif
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> +	irq_matrix_offline(imsic->matrix);
> +	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> +
> +#ifdef CONFIG_SMP
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +	WARN_ON_ONCE(try_to_del_timer_sync(&lpriv->timer) < 0);
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> +#endif
> +}
> +
> +static int __init imsic_matrix_init(void)
> +{
> +	struct imsic_global_config *global = &imsic->global;
> +
> +	raw_spin_lock_init(&imsic->matrix_lock);
> +	imsic->matrix = irq_alloc_matrix(global->nr_ids + 1,
> +					 0, global->nr_ids + 1);
> +	if (!imsic->matrix)
> +		return -ENOMEM;
> +
> +	/* Reserve ID#0 because it is special and never implemented */
> +	irq_matrix_assign_system(imsic->matrix, 0, false);
> +
> +	/* Reserve IPI ID because it is special and used internally */
> +	irq_matrix_assign_system(imsic->matrix, IMSIC_IPI_ID, false);
> +
> +	return 0;
> +}
> +
> +static int __init imsic_get_parent_hartid(struct fwnode_handle *fwnode,
> +					  u32 index, unsigned long *hartid)
> +{
> +	struct of_phandle_args parent;
> +	int rc;
> +
> +	/*
> +	 * Currently, only OF fwnode is supported so extend this
> +	 * function for ACPI support.
> +	 */
> +	if (!is_of_node(fwnode))
> +		return -EINVAL;
> +
> +	rc = of_irq_parse_one(to_of_node(fwnode), index, &parent);
> +	if (rc)
> +		return rc;
> +
> +	/*
> +	 * Skip interrupts other than external interrupts for
> +	 * current privilege level.
> +	 */
> +	if (parent.args[0] != RV_IRQ_EXT)
> +		return -EINVAL;
> +
> +	return riscv_of_parent_hartid(parent.np, hartid);
> +}
> +
> +static int __init imsic_get_mmio_resource(struct fwnode_handle *fwnode,
> +					  u32 index, struct resource *res)
> +{
> +	/*
> +	 * Currently, only OF fwnode is supported so extend this
> +	 * function for ACPI support.
> +	 */
> +	if (!is_of_node(fwnode))
> +		return -EINVAL;
> +
> +	return of_address_to_resource(to_of_node(fwnode), index, res);
> +}
> +
> +static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> +				     struct imsic_global_config *global,
> +				     u32 *nr_parent_irqs,
> +				     u32 *nr_mmios)
> +{
> +	unsigned long hartid;
> +	struct resource res;
> +	int rc;
> +	u32 i;
> +
> +	/*
> +	 * Currently, only OF fwnode is supported so extend this
> +	 * function for ACPI support.
> +	 */
> +	if (!is_of_node(fwnode))
> +		return -EINVAL;
> +
> +	*nr_parent_irqs = 0;
> +	*nr_mmios = 0;
> +
> +	/* Find number of parent interrupts */
> +	while (!imsic_get_parent_hartid(fwnode, *nr_parent_irqs, &hartid))
> +		(*nr_parent_irqs)++;
> +	if (!(*nr_parent_irqs)) {

Nit: Redundant parenthesis

> +		pr_err("%pfwP: no parent irqs available\n", fwnode);
> +		return -EINVAL;
> +	}
> +
> +	/* Find number of guest index bits in MSI address */
> +	rc = of_property_read_u32(to_of_node(fwnode), "riscv,guest-index-bits",
> +				  &global->guest_index_bits);
> +	if (rc)
> +		global->guest_index_bits = 0;
> +
> +	/* Find number of HART index bits */
> +	rc = of_property_read_u32(to_of_node(fwnode), "riscv,hart-index-bits",
> +				  &global->hart_index_bits);
> +	if (rc) {
> +		/* Assume default value */
> +		global->hart_index_bits = __fls(*nr_parent_irqs);
> +		if (BIT(global->hart_index_bits) < *nr_parent_irqs)
> +			global->hart_index_bits++;
> +	}
> +
> +	/* Find number of group index bits */
> +	rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-bits",
> +				  &global->group_index_bits);
> +	if (rc)
> +		global->group_index_bits = 0;
> +
> +	/*
> +	 * Find first bit position of group index.
> +	 * If not specified assumed the default APLIC-IMSIC configuration.
> +	 */
> +	rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-shift",
> +				  &global->group_index_shift);
> +	if (rc)
> +		global->group_index_shift = IMSIC_MMIO_PAGE_SHIFT * 2;
> +
> +	/* Find number of interrupt identities */
> +	rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-ids",
> +				  &global->nr_ids);
> +	if (rc) {
> +		pr_err("%pfwP: number of interrupt identities not found\n",
> +			fwnode);
> +		return rc;
> +	}
> +
> +	/* Find number of guest interrupt identities */
> +	rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-guest-ids",
> +				  &global->nr_guest_ids);
> +	if (rc)
> +		global->nr_guest_ids = global->nr_ids;
> +
> +	/* Sanity check guest index bits */
> +	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT;
> +	if (i < global->guest_index_bits) {
> +		pr_err("%pfwP: guest index bits too big\n", fwnode);
> +		return -EINVAL;
> +	}
> +
> +	/* Sanity check HART index bits */
> +	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT - global->guest_index_bits;
> +	if (i < global->hart_index_bits) {
> +		pr_err("%pfwP: HART index bits too big\n", fwnode);
> +		return -EINVAL;
> +	}
> +
> +	/* Sanity check group index bits */
> +	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
> +	    global->guest_index_bits - global->hart_index_bits;
> +	if (i < global->group_index_bits) {
> +		pr_err("%pfwP: group index bits too big\n", fwnode);
> +		return -EINVAL;
> +	}
> +
> +	/* Sanity check group index shift */
> +	i = global->group_index_bits + global->group_index_shift - 1;
> +	if (i >= BITS_PER_LONG) {
> +		pr_err("%pfwP: group index shift too big\n", fwnode);
> +		return -EINVAL;
> +	}
> +
> +	/* Sanity check number of interrupt identities */
> +	if ((global->nr_ids < IMSIC_MIN_ID) ||
> +	    (global->nr_ids >= IMSIC_MAX_ID) ||
> +	    ((global->nr_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID)) {
> +		pr_err("%pfwP: invalid number of interrupt identities\n",
> +			fwnode);

Nit: 100 chars

> +		return -EINVAL;
> +	}
> +
> +	/* Sanity check number of guest interrupt identities */
> +	if ((global->nr_guest_ids < IMSIC_MIN_ID) ||
> +	    (global->nr_guest_ids >= IMSIC_MAX_ID) ||
> +	    ((global->nr_guest_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID)) {
> +		pr_err("%pfwP: invalid number of guest interrupt identities\n",
> +			fwnode);

Nit: 100 chars

> +		return -EINVAL;
> +	}
> +
> +	/* Compute base address */
> +	rc = imsic_get_mmio_resource(fwnode, 0, &res);
> +	if (rc) {
> +		pr_err("%pfwP: first MMIO resource not found\n", fwnode);
> +		return -EINVAL;
> +	}
> +	global->base_addr = res.start;
> +	global->base_addr &= ~(BIT(global->guest_index_bits +
> +				   global->hart_index_bits +
> +				   IMSIC_MMIO_PAGE_SHIFT) - 1);
> +	global->base_addr &= ~((BIT(global->group_index_bits) - 1) <<
> +			       global->group_index_shift);
> +
> +	/* Find number of MMIO register sets */
> +	while (!imsic_get_mmio_resource(fwnode, *nr_mmios, &res))
> +		(*nr_mmios)++;
> +
> +	return 0;
> +}
> +
> +int __init imsic_setup_state(struct fwnode_handle *fwnode)
> +{
> +	u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> +	struct imsic_global_config *global;
> +	struct imsic_local_config *local;
> +	void __iomem **mmios_va = NULL;
> +	struct resource *mmios = NULL;
> +	unsigned long reloff, hartid;
> +	phys_addr_t base_addr;
> +	int rc, cpu;
> +
> +	/*
> +	 * Only one IMSIC instance allowed in a platform for clean
> +	 * implementation of SMP IRQ affinity and per-CPU IPIs.
> +	 *
> +	 * This means on a multi-socket (or multi-die) platform we
> +	 * will have multiple MMIO regions for one IMSIC instance.
> +	 */
> +	if (imsic) {
> +		pr_err("%pfwP: already initialized hence ignoring\n",
> +			fwnode);

Nit: 100 chars

> +		return -EALREADY;
> +	}
> +
> +	if (!riscv_isa_extension_available(NULL, SxAIA)) {
> +		pr_err("%pfwP: AIA support not available\n", fwnode);
> +		return -ENODEV;
> +	}
> +
> +	imsic = kzalloc(sizeof(*imsic), GFP_KERNEL);
> +	if (!imsic)
> +		return -ENOMEM;
> +	imsic->fwnode = fwnode;
> +	global = &imsic->global;
> +
> +	global->local = alloc_percpu(typeof(*(global->local)));
> +	if (!global->local) {
> +		rc = -ENOMEM;
> +		goto out_free_priv;
> +	}
> +
> +	/* Parse IMSIC fwnode */
> +	rc = imsic_parse_fwnode(fwnode, global, &nr_parent_irqs, &nr_mmios);
> +	if (rc)
> +		goto out_free_local;
> +
> +	/* Allocate MMIO resource array */
> +	mmios = kcalloc(nr_mmios, sizeof(*mmios), GFP_KERNEL);
> +	if (!mmios) {
> +		rc = -ENOMEM;
> +		goto out_free_local;
> +	}
> +
> +	/* Allocate MMIO virtual address array */
> +	mmios_va = kcalloc(nr_mmios, sizeof(*mmios_va), GFP_KERNEL);
> +	if (!mmios_va) {
> +		rc = -ENOMEM;
> +		goto out_iounmap;
> +	}
> +
> +	/* Parse and map MMIO register sets */
> +	for (i = 0; i < nr_mmios; i++) {
> +		rc = imsic_get_mmio_resource(fwnode, i, &mmios[i]);
> +		if (rc) {
> +			pr_err("%pfwP: unable to parse MMIO regset %d\n",
> +				fwnode, i);

Nit: 100 chars

> +			goto out_iounmap;
> +		}
> +
> +		base_addr = mmios[i].start;
> +		base_addr &= ~(BIT(global->guest_index_bits +
> +				   global->hart_index_bits +
> +				   IMSIC_MMIO_PAGE_SHIFT) - 1);
> +		base_addr &= ~((BIT(global->group_index_bits) - 1) <<
> +			       global->group_index_shift);
> +		if (base_addr != global->base_addr) {
> +			rc = -EINVAL;
> +			pr_err("%pfwP: address mismatch for regset %d\n",
> +				fwnode, i);

Nit: 100 chars... and all the places below where applicable.


Bj?rn


From bjorn at kernel.org  Tue Feb 20 03:52:54 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Tue, 20 Feb 2024 12:52:54 +0100
Subject: [PATCH v13 00/13] Linux RISC-V AIA Support
In-Reply-To: <20240220060718.823229-1-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
Message-ID: <87edd7fj3d.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

> The RISC-V AIA specification is ratified as-per the RISC-V international
> process. The latest ratified AIA specifcation can be found at:
> https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf
>
> At a high-level, the AIA specification adds three things:
> 1) AIA CSRs
>    - Improved local interrupt support
> 2) Incoming Message Signaled Interrupt Controller (IMSIC)
>    - Per-HART MSI controller
>    - Support MSI virtualization
>    - Support IPI along with virtualization
> 3) Advanced Platform-Level Interrupt Controller (APLIC)
>    - Wired interrupt controller
>    - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
>    - In Direct-mode, injects external interrupts directly into HARTs
>
> For an overview of the AIA specification, refer the AIA virtualization
> talk at KVM Forum 2022:
> https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
> https://www.youtube.com/watch?v=r071dL8Z0yo
>
> To test this series, use QEMU v7.2 (or higher) and OpenSBI v1.2 (or higher).
>
> This series depends upon per-device MSI domain patches merged by Thomas (tglx)
> which are available in irq/msi branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git
>
> These patches can also be found in the riscv_aia_v13 branch at:
> https://github.com/avpatel/linux.git
>
> Changes since v12:
>  - Rebased on Linux-6.8-rc5
>  - Dropped per-device MSI domain patches which are already merged by Thomas (tglx)
>  - Addressed nit comments from Thomas and Clement
>  - Added a new patch2 to fix lock dependency warning
>  - Replaced local sync IPI in the IMSIC driver with per-CPU timer
>  - Simplified locking in the IMSIC driver to avoid lock dependency issues
>  - Added a dirty bitmap in the IMSIC driver to optimize per-CPU local sync loop

Thanks, Anup.

I will take it for a spin, with Alex' v1 of the stop_machine()/ftrace
IPI fix.

The defconfig change (12/13)breaks a bunch a builds:
https://patchwork.kernel.org/project/linux-riscv/list/?series=827706

Download the logs here:
https://github.com/linux-riscv/linux-riscv/suites/20917102160/logs?attempt=1
and grep for '##[error]'

Bj?rn


From bjorn at kernel.org  Tue Feb 20 03:53:05 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Tue, 20 Feb 2024 12:53:05 +0100
Subject: [PATCH v13 07/13] irqchip/riscv-imsic: Add device MSI domain
 support for platform devices
In-Reply-To: <20240220060718.823229-8-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-8-apatel@ventanamicro.com>
Message-ID: <87cysrfj32.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

> The Linux platform MSI support allows per-device MSI domains so let
> us add a platform irqchip driver for RISC-V IMSIC which provides a
> base IRQ domain with MSI parent support for platform device domains.
>
> This driver assumes that the IMSIC state is already initialized by
> the IMSIC early driver.
>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> ---
>  drivers/irqchip/Makefile                   |   2 +-
>  drivers/irqchip/irq-riscv-imsic-platform.c | 346 +++++++++++++++++++++
>  drivers/irqchip/irq-riscv-imsic-state.h    |   1 +
>  3 files changed, 348 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c
>
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index d714724387ce..abca445a3229 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -95,7 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
>  obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
>  obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
>  obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
> -obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o
> +obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
>  obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
>  obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
>  obj-$(CONFIG_IMX_INTMUX)		+= irq-imx-intmux.o
> diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
> new file mode 100644
> index 000000000000..7ee44c493dbc
> --- /dev/null
> +++ b/drivers/irqchip/irq-riscv-imsic-platform.c
> @@ -0,0 +1,346 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> + * Copyright (C) 2022 Ventana Micro Systems Inc.
> + */
> +
> +#define pr_fmt(fmt) "riscv-imsic: " fmt
> +#include <linux/bitmap.h>
> +#include <linux/cpu.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip.h>
> +#include <linux/irqdomain.h>
> +#include <linux/module.h>
> +#include <linux/msi.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +#include <linux/smp.h>
> +
> +#include "irq-riscv-imsic-state.h"
> +
> +static bool imsic_cpu_page_phys(unsigned int cpu, unsigned int guest_index,
> +				phys_addr_t *out_msi_pa)
> +{
> +	struct imsic_global_config *global;
> +	struct imsic_local_config *local;
> +
> +	global = &imsic->global;
> +	local = per_cpu_ptr(global->local, cpu);
> +
> +	if (BIT(global->guest_index_bits) <= guest_index)
> +		return false;
> +
> +	if (out_msi_pa)
> +		*out_msi_pa = local->msi_pa +
> +			      (guest_index * IMSIC_MMIO_PAGE_SZ);
> +
> +	return true;
> +}
> +
> +static void imsic_irq_mask(struct irq_data *d)
> +{
> +	imsic_vector_mask(irq_data_get_irq_chip_data(d));
> +}
> +
> +static void imsic_irq_unmask(struct irq_data *d)
> +{
> +	imsic_vector_unmask(irq_data_get_irq_chip_data(d));
> +}
> +
> +static int imsic_irq_retrigger(struct irq_data *d)
> +{
> +	struct imsic_vector *vec = irq_data_get_irq_chip_data(d);
> +	struct imsic_local_config *local;
> +
> +	if (WARN_ON(vec == NULL))

Checkpatch: use !vec

> +		return -ENOENT;
> +
> +	local = per_cpu_ptr(imsic->global.local, vec->cpu);
> +	writel_relaxed(vec->local_id, local->msi_va);
> +	return 0;
> +}
> +
> +static void imsic_irq_compose_vector_msg(struct imsic_vector *vec, struct msi_msg *msg)
> +{
> +	phys_addr_t msi_addr;
> +
> +	if (WARN_ON(vec == NULL))

Checkpatch: use !vec

> +		return;
> +
> +	if (WARN_ON(!imsic_cpu_page_phys(vec->cpu, 0, &msi_addr)))
> +		return;
> +
> +	msg->address_hi = upper_32_bits(msi_addr);
> +	msg->address_lo = lower_32_bits(msi_addr);
> +	msg->data = vec->local_id;
> +}
> +
> +static void imsic_irq_compose_msg(struct irq_data *d, struct msi_msg *msg)
> +{
> +	imsic_irq_compose_vector_msg(irq_data_get_irq_chip_data(d), msg);
> +}
> +
> +#ifdef CONFIG_SMP
> +static void imsic_msi_update_msg(struct irq_data *d, struct imsic_vector *vec)
> +{
> +	struct msi_msg msg[2] = { [1] = { }, };
> +
> +	imsic_irq_compose_vector_msg(vec, msg);
> +	irq_data_get_irq_chip(d)->irq_write_msi_msg(d, msg);
> +}
> +
> +static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
> +				  bool force)
> +{
> +	struct imsic_vector *old_vec, *new_vec;
> +	struct irq_data *pd = d->parent_data;
> +
> +	old_vec = irq_data_get_irq_chip_data(pd);
> +	if (WARN_ON(old_vec == NULL))

Checkpatch: use !old_vec

> +		return -ENOENT;
> +
> +	/* If old vector cpu belongs to the target cpumask then do nothing */
> +	if (cpumask_test_cpu(old_vec->cpu, mask_val))
> +		return IRQ_SET_MASK_OK_DONE;
> +
> +	/* If move is already in-flight then return failure */
> +	if (imsic_vector_get_move(old_vec))
> +		return -EBUSY;
> +
> +	/* Get a new vector on the desired set of CPUs */
> +	new_vec = imsic_vector_alloc(old_vec->hwirq, mask_val);
> +	if (!new_vec)
> +		return -ENOSPC;
> +
> +	/* Point device to the new vector */
> +	imsic_msi_update_msg(d, new_vec);
> +
> +	/* Update irq descriptors with the new vector */
> +	pd->chip_data = new_vec;
> +
> +	/* Update effective affinity of parent irq data */
> +	irq_data_update_effective_affinity(pd, cpumask_of(new_vec->cpu));
> +
> +	/* Move state of the old vector to the new vector */
> +	imsic_vector_move(old_vec, new_vec);
> +
> +	return IRQ_SET_MASK_OK_DONE;
> +}
> +#endif
> +
> +static struct irq_chip imsic_irq_base_chip = {
> +	.name			= "IMSIC",
> +	.irq_mask		= imsic_irq_mask,
> +	.irq_unmask		= imsic_irq_unmask,
> +	.irq_retrigger		= imsic_irq_retrigger,
> +	.irq_compose_msi_msg	= imsic_irq_compose_msg,
> +	.flags			= IRQCHIP_SKIP_SET_WAKE |
> +				  IRQCHIP_MASK_ON_SUSPEND,
> +};
> +
> +static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> +				  unsigned int nr_irqs, void *args)
> +{
> +	struct imsic_vector *vec;
> +
> +	/* Legacy-MSI or multi-MSI not supported yet. */
> +	if (nr_irqs > 1)
> +		return -ENOTSUPP;

Checkpatch: WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP


Bj?rn


From bjorn at kernel.org  Tue Feb 20 03:53:15 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Tue, 20 Feb 2024 12:53:15 +0100
Subject: [PATCH v13 06/13] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <20240220060718.823229-7-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-7-apatel@ventanamicro.com>
Message-ID: <87a5nvfj2s.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

> The RISC-V advanced interrupt architecture (AIA) specification
> defines a new MSI controller called incoming message signalled
> interrupt controller (IMSIC) which manages MSI on per-HART (or
> per-CPU) basis. It also supports IPIs as software injected MSIs.
> (For more details refer https://github.com/riscv/riscv-aia)
>
> Let us add an early irqchip driver for RISC-V IMSIC which sets
> up the IMSIC state and provide IPIs.
>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>

This patch has a couple of checkpatch issues:

CHECK: Alignment should match open parenthesis
CHECK: Please don't use multiple blank lines
CHECK: Please use a blank line after function/struct/union/enum declarations
CHECK: Unnecessary parentheses around 'global->nr_guest_ids < IMSIC_MIN_ID'
CHECK: Unnecessary parentheses around 'global->nr_guest_ids >= IMSIC_MAX_ID'
CHECK: Unnecessary parentheses around 'global->nr_ids < IMSIC_MIN_ID'
CHECK: Unnecessary parentheses around 'global->nr_ids >= IMSIC_MAX_ID'
CHECK: Unnecessary parentheses around global->local
CHECK: Unnecessary parentheses around imsic->lpriv
CHECK: extern prototypes should be avoided in .h files

Bj?rn


From mark.rutland at arm.com  Tue Feb 20 03:55:30 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 20 Feb 2024 11:55:30 +0000
Subject: [PATCH] arm64: add early fixmap initialization flag
In-Reply-To: <ZdPyWkOlUan5AI9r@vm3>
References: <20240217140326.2367186-1-skseofh@gmail.com>
 <ZdMx-svsHgrfguxX@FVFF77S0Q05N>
 <ZdPyWkOlUan5AI9r@vm3>
Message-ID: <ZdSTMgxcWYsT9ECs@FVFF77S0Q05N.cambridge.arm.com>

On Tue, Feb 20, 2024 at 09:29:14AM +0900, Itaru Kitayama wrote:
> On Mon, Feb 19, 2024 at 10:48:26AM +0000, Mark Rutland wrote:
> > On Sat, Feb 17, 2024 at 11:03:26PM +0900, skseofh at gmail.com wrote:
> > > From: Daero Lee <skseofh at gmail.com>
> > > 
> > > early_fixmap_init may be called multiple times. Since there is no
> > > change in the page table after early fixmap initialization, an
> > > initialization flag was added.
> > 
> > Why is that better?
> > 
> > We call early_fixmap_init() in two places:
> > 
> > * early_fdt_map()
> > * setup_arch()
> > 
> > ... and to get to setup_arch() we *must* have gone through early_fdt_map(),
> > since __primary_switched() calls that before going to setup_arch().
> > 
> > So AFAICT we can remove the second call to early_fixmap_init() in setup_arch(),
> > and rely on the earlier one in early_fdt_map().
> 
> Removing the second call makes the code base a bit harder to understand
> as the functions related to DT and ACPI setup are not separated cleanly.
> I prefer calling the early_fixmap_init() in setup_arch() as well.

I appreciate what you're saying here, but I don't think that it's better to
keep the second call in setup_arch().

We rely on having a (stub) DT in order to find UEFI and ACPI tables, so the DT
and ACPI setup can never be truly separated. We always need to map that DT in
order to find the UEFI+ACPI tables, and in order to do that we must initialize
the fixmap first.

I don't think there's any good reason to keep a redundant call in setup_arch();
that's just misleading and potentially problematic if we ever change
early_fixmap_init() so that it's not idempotent.

I agree it's somewhat a layering violation for  early_fdt_map() to be
responsible for initialising the fixmap, so how about we just pull that out,
e.g. as below?

Mark.

---->8----
>From 5f07f9c1d352f760fa7aba97f1b4f42d9cb99496 Mon Sep 17 00:00:00 2001
From: Mark Rutland <mark.rutland at arm.com>
Date: Tue, 20 Feb 2024 11:09:17 +0000
Subject: [PATCH] arm64: clean up fixmap initalization

Currently we have redundant initialization of the fixmap, first in
early_fdt_map(), and then again in setup_arch() before we call
early_ioremap_init(). This redundant initialization isn't harmful, as
early_fixmap_init() happens to be idempotent, but it's redundant and
potentially confusing.

We need to call early_fixmap_init() before we map the FDT and before we
call early_ioremap_init(). Ideally we'd place early_fixmap_init() and
early_ioremap_init() in the same caller as early_ioremap_init() is
somewhat coupled with the fixmap code.

Clean this up by moving the calls to early_fixmap_init() and
early_ioremap_init() into a new early_mappings_init() function, and
calling this once in __primary_switched() before we call
early_fdt_map(). This means we initialize the fixmap once, and keep
early_fixmap_init() and early_ioremap_init() together.

This is a cleanup, not a fix, and does not need to be backported to
stable kernels.

Reported-by: Daero Lee <skseofh at gmail.com>
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Itaru Kitayama <itaru.kitayama at linux.dev>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/setup.h |  1 +
 arch/arm64/kernel/head.S       |  2 ++
 arch/arm64/kernel/setup.c      | 11 ++++++-----
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
index 2e4d7da74fb87..c8ba018bcc09f 100644
--- a/arch/arm64/include/asm/setup.h
+++ b/arch/arm64/include/asm/setup.h
@@ -9,6 +9,7 @@
 
 void *get_early_fdt_ptr(void);
 void early_fdt_map(u64 dt_phys);
+void early_mappings_init(void);
 
 /*
  * These two variables are used in the head.S file.
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index cab7f91949d8f..c60c5454c5704 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -510,6 +510,8 @@ SYM_FUNC_START_LOCAL(__primary_switched)
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 	bl	kasan_early_init
 #endif
+	bl	early_mappings_init
+
 	mov	x0, x21				// pass FDT address in x0
 	bl	early_fdt_map			// Try mapping the FDT early
 	mov	x0, x20				// pass the full boot status
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 42c690bb2d608..7a539534ced78 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -176,8 +176,6 @@ void __init *get_early_fdt_ptr(void)
 asmlinkage void __init early_fdt_map(u64 dt_phys)
 {
 	int fdt_size;
-
-	early_fixmap_init();
 	early_fdt_ptr = fixmap_remap_fdt(dt_phys, &fdt_size, PAGE_KERNEL);
 }
 
@@ -290,6 +288,12 @@ u64 cpu_logical_map(unsigned int cpu)
 	return __cpu_logical_map[cpu];
 }
 
+asmlinkage void __init early_mappings_init(void)
+{
+	early_fixmap_init();
+	early_ioremap_init();
+}
+
 void __init __no_sanitize_address setup_arch(char **cmdline_p)
 {
 	setup_initial_init_mm(_stext, _etext, _edata, _end);
@@ -305,9 +309,6 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 	 */
 	arm64_use_ng_mappings = kaslr_requires_kpti();
 
-	early_fixmap_init();
-	early_ioremap_init();
-
 	setup_machine_fdt(__fdt_pointer);
 
 	/*
-- 
2.30.2



From maz at kernel.org  Tue Feb 20 03:57:04 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 20 Feb 2024 11:57:04 +0000
Subject: [PATCH 01/13] KVM: arm64: Harden __ctxt_sys_reg() against out-of-range values
In-Reply-To: <20240220112031.GA16168@e124191.cambridge.arm.com>
References: <20240219092014.783809-1-maz@kernel.org>
	<20240219092014.783809-2-maz@kernel.org>
	<20240220112031.GA16168@e124191.cambridge.arm.com>
Message-ID: <8634tn4acv.wl-maz@kernel.org>

On Tue, 20 Feb 2024 11:20:31 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> On Mon, Feb 19, 2024 at 09:20:02AM +0000, Marc Zyngier wrote:
> > The unsuspecting kernel tinkerer can be easily confused into
> > writing something that looks like this:
> > 
> > 	ikey.lo = __vcpu_sys_reg(vcpu, SYS_APIAKEYLO_EL1);
> > 
> > which seems vaguely sensible, until you realise that the second
> > parameter is the encoding of a sysreg, and not the index into
> > the vcpu sysreg file... Debugging what happens in this case is
> 
> type safety :(

Are you advocating for making everything a struct? Or something else?

> 
> > an interesting exercise in head<->wall interactions.
> > 
> > As they often say: "Any resemblance to actual persons, living
> > or dead, or actual events is purely coincidental".
> > 
> > In order to save people's time, add some compile-time hardening
> > that will at least weed out the "stupidly out of range" values.
> > This will *not* catch anything that isn't a compile-time constant.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/include/asm/kvm_host.h | 9 ++++++++-
> >  1 file changed, 8 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 181fef12e8e8..a5ec4c7d3966 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -895,7 +895,7 @@ struct kvm_vcpu_arch {
> >   * Don't bother with VNCR-based accesses in the nVHE code, it has no
> >   * business dealing with NV.
> >   */
> > -static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
> > +static inline u64 *___ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
> 
> When in doubt, add more underscores!

That's the one true way.

> 
> >  {
> >  #if !defined (__KVM_NVHE_HYPERVISOR__)
> >  	if (unlikely(cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
> > @@ -905,6 +905,13 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
> >  	return (u64 *)&ctxt->sys_regs[r];
> >  }
> >  
> > +#define __ctxt_sys_reg(c,r)						\
> > +	({								\
> > +	    	BUILD_BUG_ON(__builtin_constant_p(r) &&			\
> > +			     (r) >= NR_SYS_REGS);			\
> > +		___ctxt_sys_reg(c, r);					\
> > +	})
> 
> I'm assuming the extra macro layer is to try make __builtin_constant_p() as
> effective as possible? Otherwise maybe it relies on the compiler inling the
> ___ctxt_sys_reg() function?

It's not about efficiency. It's about making it *work*. Otherwise,
lack of inlining will screw you over, and you may not check anything.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From joey.gouly at arm.com  Tue Feb 20 03:58:06 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 20 Feb 2024 11:58:06 +0000
Subject: [PATCH 03/13] KVM: arm64: nv: Drop VCPU_HYP_CONTEXT flag
In-Reply-To: <20240219092014.783809-4-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
 <20240219092014.783809-4-maz@kernel.org>
Message-ID: <20240220115806.GC16168@e124191.cambridge.arm.com>

On Mon, Feb 19, 2024 at 09:20:04AM +0000, Marc Zyngier wrote:
> It has become obvious that HCR_EL2.NV serves the exact same use
> as VCPU_HYP_CONTEXT, only in an architectural way. So just drop
> the flag for good.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_host.h | 2 --
>  arch/arm64/kvm/hyp/vhe/switch.c   | 7 +------
>  2 files changed, 1 insertion(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index a5ec4c7d3966..75eb8e170515 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -816,8 +816,6 @@ struct kvm_vcpu_arch {
>  #define DEBUG_STATE_SAVE_SPE	__vcpu_single_flag(iflags, BIT(5))
>  /* Save TRBE context if active  */
>  #define DEBUG_STATE_SAVE_TRBE	__vcpu_single_flag(iflags, BIT(6))
> -/* vcpu running in HYP context */
> -#define VCPU_HYP_CONTEXT	__vcpu_single_flag(iflags, BIT(7))
>  
>  /* SVE enabled for host EL0 */
>  #define HOST_SVE_ENABLED	__vcpu_single_flag(sflags, BIT(0))
> diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
> index 1581df6aec87..58415783fd53 100644
> --- a/arch/arm64/kvm/hyp/vhe/switch.c
> +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> @@ -197,7 +197,7 @@ 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_get_flag(vcpu, VCPU_HYP_CONTEXT))) {
> +	if (unlikely(read_sysreg(hcr_el2) & HCR_NV)) {
>  		u64 mode = *vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT);
>  
>  		switch (mode) {
> @@ -240,11 +240,6 @@ 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_set_flag(vcpu, VCPU_HYP_CONTEXT);
> -	else
> -		vcpu_clear_flag(vcpu, VCPU_HYP_CONTEXT);
> -
>  	do {
>  		/* Jump in the fire! */
>  		exit_code = __guest_enter(vcpu);

Makes sense to me.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>

Thanks,
Joey


From jesper.nilsson at axis.com  Tue Feb 20 04:00:22 2024
From: jesper.nilsson at axis.com (Jesper Nilsson)
Date: Tue, 20 Feb 2024 13:00:22 +0100
Subject: [PATCH v2] net: stmmac: mmc_core: Drop interrupt registers from
 stats
Message-ID: <20240220-stmmac_stats-v2-1-0a78863bec70@axis.com>

The MMC IPC interrupt status and interrupt mask registers are
of little use as Ethernet statistics, but incrementing counters
based on the current interrupt and interrupt mask registers
makes them actively misleading.

For example, if the interrupt mask is set to 0x08420842,
the current code will increment by that amount each iteration,
leading to the following sequence of nonsense:

mmc_rx_ipc_intr_mask: 969816526
mmc_rx_ipc_intr_mask: 1108361744

These registers have been included in the Ethernet statistics
since the first version of MMC back in 2011 (commit 1c901a46d57).
That commit also mentions the MMC interrupts as
"something to add later (if actually useful)".

If the registers are actually useful, they should probably
be part of the Ethernet register dump instead of statistics,
but for now, drop the counters for mmc_rx_ipc_intr and
mmc_rx_ipc_intr_mask completely.

Signed-off-by: Jesper Nilsson <jesper.nilsson at axis.com>
---
Changes in v2:
- Drop the misleading registers completely
- Link to v1: https://lore.kernel.org/r/20240216-stmmac_stats-v1-1-7065fa4613f8 at axis.com
---
 drivers/net/ethernet/stmicro/stmmac/mmc.h            | 3 ---
 drivers/net/ethernet/stmicro/stmmac/mmc_core.c       | 3 ---
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 --
 3 files changed, 8 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h
index a0c05925883e..8cfba817491b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/mmc.h
+++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h
@@ -78,9 +78,6 @@ struct stmmac_counters {
 	unsigned int mmc_rx_fifo_overflow;
 	unsigned int mmc_rx_vlan_frames_gb;
 	unsigned int mmc_rx_watchdog_error;
-	/* IPC */
-	unsigned int mmc_rx_ipc_intr_mask;
-	unsigned int mmc_rx_ipc_intr;
 	/* IPv4 */
 	unsigned int mmc_rx_ipv4_gd;
 	unsigned int mmc_rx_ipv4_hderr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
index 6a7c1d325c46..ab3b7770f62d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
@@ -279,9 +279,6 @@ static void dwmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc)
 	mmc->mmc_rx_fifo_overflow += readl(mmcaddr + MMC_RX_FIFO_OVERFLOW);
 	mmc->mmc_rx_vlan_frames_gb += readl(mmcaddr + MMC_RX_VLAN_FRAMES_GB);
 	mmc->mmc_rx_watchdog_error += readl(mmcaddr + MMC_RX_WATCHDOG_ERROR);
-	/* IPC */
-	mmc->mmc_rx_ipc_intr_mask += readl(mmcaddr + MMC_RX_IPC_INTR_MASK);
-	mmc->mmc_rx_ipc_intr += readl(mmcaddr + MMC_RX_IPC_INTR);
 	/* IPv4 */
 	mmc->mmc_rx_ipv4_gd += readl(mmcaddr + MMC_RX_IPV4_GD);
 	mmc->mmc_rx_ipv4_hderr += readl(mmcaddr + MMC_RX_IPV4_HDERR);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index f628411ae4ae..28accdc98282 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -236,8 +236,6 @@ static const struct stmmac_stats stmmac_mmc[] = {
 	STMMAC_MMC_STAT(mmc_rx_fifo_overflow),
 	STMMAC_MMC_STAT(mmc_rx_vlan_frames_gb),
 	STMMAC_MMC_STAT(mmc_rx_watchdog_error),
-	STMMAC_MMC_STAT(mmc_rx_ipc_intr_mask),
-	STMMAC_MMC_STAT(mmc_rx_ipc_intr),
 	STMMAC_MMC_STAT(mmc_rx_ipv4_gd),
 	STMMAC_MMC_STAT(mmc_rx_ipv4_hderr),
 	STMMAC_MMC_STAT(mmc_rx_ipv4_nopay),

---
base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
change-id: 20240216-stmmac_stats-e3561d460d0e

Best regards,
-- 

/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson at axis.com



From will at kernel.org  Tue Feb 20 04:05:30 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 20 Feb 2024 12:05:30 +0000
Subject: [PATCH v2] arm64: jump_label: use constraints "Si" instead of "i"
In-Reply-To: <CAMj1kXHh_m=V0QsiTpHrUXpFBXFbFfezdysz8quhPSgUrZg1MA@mail.gmail.com>
References: <20240206074552.541154-1-maskray@google.com>
 <CAMuHMdVOoxVFohcwwoQtY0KgZEvbjgJJ6mib8Fabo97P0krEqw@mail.gmail.com>
 <CAMj1kXGaF5bobHTr1pTg+-=s4Ft7+5SSbX72-NxsR_W_Yuxb8Q@mail.gmail.com>
 <CAMj1kXGw+r7yEEBA8gYBcdrqkiP=VYOSzz9YLnNavJn2snmFwA@mail.gmail.com>
 <CAMuHMdX+6fnAf8Hm6EqYJPAjrrLO9T7c=Gu3S8V_pqjSDowJ6g@mail.gmail.com>
 <CAMj1kXHh_m=V0QsiTpHrUXpFBXFbFfezdysz8quhPSgUrZg1MA@mail.gmail.com>
Message-ID: <20240220120529.GA5613@willie-the-truck>

On Mon, Feb 19, 2024 at 04:41:03PM +0100, Ard Biesheuvel wrote:
> On Mon, 19 Feb 2024 at 15:43, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> > > > > > Changes from
> > > > > > arm64: jump_label: use constraint "S" instead of "i" (https://lore.kernel.org/all/20240131065322.1126831-1-maskray at google.com/)
> > > > > >
> > > > > > * Use "Si" as Ard suggested to support Clang<19
> > > > > > * Make branch a separate operand
> > > > > >
> > > > > > Changes from v1:
> > > > > >
> > > > > > * Use asmSymbolicName for readability
> > > > >
> > > > > But it still fails on gcc-5:
> > > > >
> > > > >     arch/arm64/include/asm/jump_label.h:25:2: error: invalid 'asm':
> > > > > invalid operand
> > > > >       asm goto(
> > > > >       ^
> > > > >
> > > > > http://kisskb.ellerman.id.au/kisskb/buildresult/15129281/
> > > > >
> > > >
> > > > How odd. godbolt.org has 5.4 and it seems perfectly happy with it.
> >
> > > https://godbolt.org/z/GTnf3vPaT
> >
> > I could reproduce the issue on v6.8-rc5 using arm64 defconfig
> > and x86_64-gcc-5.5.0-nolibc-aarch64-linux.tar.xz from
> > https://cdn.kernel.org/pub/tools/crosstool/files/bin/x86_64/5.5.0/:
> >
> 
> OK, I managed to do so as well.
> 
> And GCC 6.4 from the same source works correctly.
> 
> Not sure whether there are any plans to bump the minimal GCC version
> any time soon (cc'ing Arnd), but we should probably drop this change
> until that happens.

Yup, makes sense to me. I'll revert the original change and we can bring it
back later if we decide to bump the minimum GCC version.

Cheers,

Will


From david at redhat.com  Tue Feb 20 04:05:42 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 20 Feb 2024 13:05:42 +0100
Subject: arm64 MTE tag storage reuse - alternatives to MIGRATE_CMA
In-Reply-To: <ZdSMbjGf2Fj98diT@raptor>
References: <ZdSMbjGf2Fj98diT@raptor>
Message-ID: <70d77490-9036-48ac-afc9-4b976433070d@redhat.com>

On 20.02.24 12:26, Alexandru Elisei wrote:
> Hello,
> 

Hi!

> This is a request to discuss alternatives to the current approach for
> reusing the MTE tag storage memory for data allocations [1]. Each iteration
> of the series uncovered new issues, the latest being that memory allocation
> is being performed in atomic contexts [2]; I would like to start a
> discussion regarding possible alternative, which would integrate better
> with the memory management code.
> 
> This is a high level overview of the current approach:
> 
>   * Tag storage pages are put on the MIGRATE_CMA lists, meaning they can be
>     used for data allocations like (almost) any other page in the system.
> 
>   * When a page is allocated as tagged, the corresponding tag storage is
>     also allocated.
> 
>   * There's a static relationship between a page and the location in memory
>     where its tags are stored. Because of this, if the corresponding tag
>     storage is used for data, the tag storage page is migrated.
> 
> Although this is the most generic approach because tag storage pages are
> treated like normal pages, it has some disadvantages:
> 
>   * HW KASAN (MTE in the kernel) cannot be used. The kernel allocates memory
>     in atomic context, where migration is not possible.
> 
>   * Tag storage pages cannot be themselves tagged, and this means that all
>     CMA pages, even those which aren't tag storage, cannot be used for
>     tagged allocations.
> 
>   * Page migration is costly, and a process that uses MTE can experience
>     measurable slowdowns if the tag storage it requires is in use for data.
>     There might be ways to reduce this cost (by reducing the likelihood that
>     tag storage pages are allocated), but it cannot be completely
>     eliminated.
> 
>   * Worse yet, a userspace process can use a tag storage page in such a way
>     that migration is effectively impossible [3],[4].  A malicious process
>     can make use of this to prevent the allocation of tag storage for other
>     processes in the system, leading to a degraded experience for the
>     affected processes. Worst case scenario, progress becomes impossible for
>     those processes.
> 
> One alternative approach I'm looking at right now is cleancache. Cleancache
> was removed in v5.17 (commit 0a4ee518185e) because the only backend, the
> tmem driver, had been removed earlier (in v5.3, commit 814bbf49dcd0).
> 
> With this approach, MTE tag storage would be implemented as a driver
> backend for cleancache. When a tag storage page is needed for storing tags,
> the page would simply be dropped from the cache (cleancache_get_page()
> returns -1).

With large folios in place, we'd likely want to investigate not working 
on individual pages, but on (possibly large) folios instead.

> 
> I believe this is a very good fit for tag storage reuse, because it allows
> tag storage to be allocated even in atomic contexts, which enables MTE in
> the kernel. As a bonus, all of the changes to MM from the current approach
> wouldn't be needed, as tag storage allocation can be handled entirely in
> set_ptes_at(), copy_*highpage() or arch_swap_restore().
> 
> Is this a viable approach that would be upstreamable? Are there other
> solutions that I haven't considered? I'm very much open to any alternatives
> that would make tag storage reuse viable.

As raised recently, I had similar ideas with something like virtio-mem 
in the past (wanted to call it virtio-tmem back then), but didn't have 
time to look into it yet.

I considered both, using special device memory as "cleancache" backend, 
and using it as backend storage for something similar to zswap. We would 
not need a memmap/"struct page" for that special device memory, which 
reduces memory overhead and makes "adding more memory" a more reliable 
operation.

Using it as "cleancache" backend does make some things a lot easier.

The idea would be to provide a variable amount of additional memory to a 
VM, that can be reclaimed easily and reliably on demand.

The details are a bit more involved, but in essence, imagine a special 
physical memory region that is provided by a the hypervisor via a device 
to the VM. A virtio device "owns" that region and the driver manages it, 
based on requests from the hypervisor.

Similar to virtio-mem, there are ways for the hypervisor to request 
changes to the memory consumption of a device (setting the requested 
size). So when requested to consume less, clean pagecache pages can be 
dropped and the memory can be handed back to the hypervisor.

Of course, likely we would want to consider using "slower" memory in the 
hypervisor to back such a device.

I also thought about better integrating memory reclaim in the 
hypervisor, similar to "MADV_FREE" semantic way. One idea I had was that 
the memory provided by the device might have "special" semantics (as if 
the memory is always marked MADV_FREE), whereby the hypervisor could 
reclaim+discard any memory in that region any time, and the driver would 
have ways to get notified about that, or detect that reclaim happened.

I learned that there are cases where data that is significantly larger 
than main memory might be read repeatedly. As long as there is free 
memory in the hypervisor, it could be used as a cache for clean 
pagecache pages. In contrast to memory ballonning + virtio-mem, that 
memory can be easily and reliably reclaimed. And reclaiming that memory 
cannot really hurt the VM, it would only affect performance.

Long story short: what I had in mind would require similar hooks (again).

In contrast to tmem, with arm64 MTE we could get an actual supported 
cleancache backend fairly easily. I recall that tmem was abandoned in 
XEN and never really reached production quality.

-- 
Cheers,

David / dhildenb



From biju.das.jz at bp.renesas.com  Tue Feb 20 04:10:02 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Tue, 20 Feb 2024 12:10:02 +0000
Subject: [PATCH] genirq/irqdomain: Don't call ops->select for
 DOMAIN_BUS_ANY tokens
In-Reply-To: <20240220114731.1898534-1-maz@kernel.org>
References: <20240220114731.1898534-1-maz@kernel.org>
Message-ID: <TYCPR01MB112691814D4D444C0CFB51C5186502@TYCPR01MB11269.jpnprd01.prod.outlook.com>

Hi Marc Zyngier,

> -----Original Message-----
> From: Marc Zyngier <maz at kernel.org>
> Sent: Tuesday, February 20, 2024 11:48 AM
> Subject: [PATCH] genirq/irqdomain: Don't call ops->select for
> DOMAIN_BUS_ANY tokens
> 
> Users of the IRQCHIP_PLATFORM_DRIVER_{BEGIN,END} helpers rely on a fwspec
> containing only the fwnode (and crucially a number of parameters set to 0)
> together with a DOMAIN_BUS_ANY token to check whether a parent irqchip has
> probed and registered a domain.
> 
> Since de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction
> from select()"), we call ops->select unconditionally, meaning that
> irqchips implementing select now need to handle ANY as a match.
> 
> Instead of adding more esoteric checks to the individual drivers, add that
> condition to irq_find_matching_fwspec(), and let it handle the corner
> case, as per the comment in the function.
> 
> This restores the functionnality of the above helpers.
> 
> Reported-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Tested-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Reported-by: Biju Das <biju.das.jz at bp.renesas.com>

Tested-by: Biju Das <biju.das.jz at bp.renesas.com>

Cheers,
Biju

> Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction
> from select()")
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Link:
> ---
>  kernel/irq/irqdomain.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index
> aeb41655d6de..3dd1c871e091 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -449,7 +449,7 @@ struct irq_domain *irq_find_matching_fwspec(struct
> irq_fwspec *fwspec,
>  	 */
>  	mutex_lock(&irq_domain_mutex);
>  	list_for_each_entry(h, &irq_domain_list, link) {
> -		if (h->ops->select)
> +		if (h->ops->select && bus_token != DOMAIN_BUS_ANY)
>  			rc = h->ops->select(h, fwspec, bus_token);
>  		else if (h->ops->match)
>  			rc = h->ops->match(h, to_of_node(fwnode), bus_token);
> --
> 2.39.2



From ankita at nvidia.com  Tue Feb 20 04:11:19 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Tue, 20 Feb 2024 12:11:19 +0000
Subject: [PATCH v8 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <ZdR3MI_4pqV0EZcR@arm.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-5-ankita@nvidia.com> <ZdR3MI_4pqV0EZcR@arm.com>
Message-ID: <SA1PR12MB7199A969E2A4B31220EFF152B0502@SA1PR12MB7199.namprd12.prod.outlook.com>

>> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
>> index 1cbc990d42e0..c93bea18fc4b 100644
>> --- a/drivers/vfio/pci/vfio_pci_core.c
>> +++ b/drivers/vfio/pci/vfio_pci_core.c
>> @@ -1862,8 +1862,24 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
>>?????? /*
>>??????? * See remap_pfn_range(), called from vfio_pci_fault() but we can't
>>??????? * change vm_flags within the fault handler.? Set them now.
>> +????? *
>> +????? * VM_ALLOW_ANY_UNCACHED: The VMA flag is implemented for ARM64,
>> +????? * allowing KVM stage 2 device mapping attributes to use Normal-NC
>> +????? * rather than DEVICE_nGnRE, which allows guest mappings
>> +????? * supporting combining attributes (WC). ARM does not
>
> Nitpick: "supporting write-combining" (if you plan to respin).

Ack.

From alim.akhtar at samsung.com  Tue Feb 20 04:18:01 2024
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 20 Feb 2024 17:48:01 +0530
Subject: [PATCH v2] interconnect: constify of_phandle_args in xlate
In-Reply-To: <20240220072213.35779-1-krzysztof.kozlowski@linaro.org>
References: <CGME20240220072224epcas5p4ff60556b0b5632abfc44d2b8ad932b8f@epcas5p4.samsung.com>
	<20240220072213.35779-1-krzysztof.kozlowski@linaro.org>
Message-ID: <1d9b01da63f6$daeb0170$90c10450$@samsung.com>



> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Sent: Tuesday, February 20, 2024 12:52 PM
> To: Georgi Djakov <djakov at kernel.org>; Bjorn Andersson
> <andersson at kernel.org>; Konrad Dybcio <konrad.dybcio at linaro.org>;
> Sylwester Nawrocki <s.nawrocki at samsung.com>; Artur ?wigo?
> <a.swigon at samsung.com>; Krzysztof Kozlowski
> <krzysztof.kozlowski at linaro.org>; Alim Akhtar
> <alim.akhtar at samsung.com>; Thierry Reding <thierry.reding at gmail.com>;
> Jonathan Hunter <jonathanh at nvidia.com>; linux-pm at vger.kernel.org;
> linux-kernel at vger.kernel.org; linux-arm-msm at vger.kernel.org; linux-
> samsung-soc at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> tegra at vger.kernel.org
> Cc: Thierry Reding <treding at nvidia.com>
> Subject: [PATCH v2] interconnect: constify of_phandle_args in xlate
> 
> The xlate callbacks are supposed to translate of_phandle_args to proper
> provider without modifying the of_phandle_args.  Make the argument
> pointer to const for code safety and readability.
> 
> Acked-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> Acked-by: Thierry Reding <treding at nvidia.com> # Tegra
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> ---
> 
> Changes in v2:
> 1. Drop unrelated gpiolib changes (Konrad, Thierry).
> 2. Add tags.
> ---
>  drivers/interconnect/core.c            |  4 ++--
>  drivers/interconnect/qcom/icc-common.c |  3 ++-
> drivers/interconnect/qcom/icc-common.h |  3 ++-
> drivers/interconnect/samsung/exynos.c  |  2 +-
>  drivers/memory/tegra/mc.c              |  2 +-
>  drivers/memory/tegra/tegra124-emc.c    |  2 +-
>  drivers/memory/tegra/tegra124.c        |  2 +-
>  drivers/memory/tegra/tegra186-emc.c    |  2 +-
>  drivers/memory/tegra/tegra20-emc.c     |  2 +-
>  drivers/memory/tegra/tegra20.c         |  2 +-
>  drivers/memory/tegra/tegra30-emc.c     |  2 +-
>  drivers/memory/tegra/tegra30.c         |  2 +-
>  include/linux/interconnect-provider.h  | 11 ++++++-----
>  include/soc/tegra/mc.h                 |  7 ++++---
>  14 files changed, 25 insertions(+), 21 deletions(-)
> 

For Samsung/Exynos
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
.
.
[snip]
> --
> 2.34.1





From will at kernel.org  Tue Feb 20 04:21:03 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 20 Feb 2024 12:21:03 +0000
Subject: [PATCH v8 1/4] kvm: arm64: introduce new flag for non-cacheable
 IO memory
In-Reply-To: <20240220072926.6466-2-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-2-ankita@nvidia.com>
Message-ID: <20240220122103.GB5613@willie-the-truck>

On Tue, Feb 20, 2024 at 12:59:23PM +0530, ankita at nvidia.com wrote:
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> Currently, KVM for ARM64 maps at stage 2 memory that is considered device
> (i.e. it is not RAM) with DEVICE_nGnRE memory attributes; this setting
> overrides (as per the ARM architecture [1]) any device MMIO mapping
> present at stage 1, resulting in a set-up whereby a guest operating
> system cannot determine device MMIO mapping memory attributes on its
> own but it is always overridden by the KVM stage 2 default.
> 
> This set-up does not allow guest operating systems to select device
> memory attributes independently from KVM stage-2 mappings
> (refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
> which turns out to be an issue in that guest operating systems
> (e.g. Linux) may request to map devices MMIO regions with memory
> attributes that guarantee better performance (e.g. gathering
> attribute - that for some devices can generate larger PCIe memory
> writes TLPs) and specific operations (e.g. unaligned transactions)
> such as the NormalNC memory type.
> 
> The default device stage 2 mapping was chosen in KVM for ARM64 since
> it was considered safer (i.e. it would not allow guests to trigger
> uncontained failures ultimately crashing the machine) but this
> turned out to be asynchronous (SError) defeating the purpose.
> 
> Failures containability is a property of the platform and is independent
> from the memory type used for MMIO device memory mappings.
> 
> Actually, DEVICE_nGnRE memory type is even more problematic than
> Normal-NC memory type in terms of faults containability in that e.g.
> aborts triggered on DEVICE_nGnRE loads cannot be made, architecturally,
> synchronous (i.e. that would imply that the processor should issue at
> most 1 load transaction at a time - it cannot pipeline them - otherwise
> the synchronous abort semantics would break the no-speculation attribute
> attached to DEVICE_XXX memory).
> 
> This means that regardless of the combined stage1+stage2 mappings a
> platform is safe if and only if device transactions cannot trigger
> uncontained failures and that in turn relies on platform capabilities
> and the device type being assigned (i.e. PCIe AER/DPC error containment
> and RAS architecture[3]); therefore the default KVM device stage 2
> memory attributes play no role in making device assignment safer
> for a given platform (if the platform design adheres to design
> guidelines outlined in [3]) and therefore can be relaxed.
> 
> For all these reasons, relax the KVM stage 2 device memory attributes
> from DEVICE_nGnRE to Normal-NC.
> 
> The NormalNC was chosen over a different Normal memory type default
> at stage-2 (e.g. Normal Write-through) to avoid cache allocation/snooping.
> 
> Relaxing S2 KVM device MMIO mappings to Normal-NC is not expected to
> trigger any issue on guest device reclaim use cases either (i.e. device
> MMIO unmap followed by a device reset) at least for PCIe devices, in that
> in PCIe a device reset is architected and carried out through PCI config
> space transactions that are naturally ordered with respect to MMIO
> transactions according to the PCI ordering rules.
> 
> Having Normal-NC S2 default puts guests in control (thanks to
> stage1+stage2 combined memory attributes rules [1]) of device MMIO
> regions memory mappings, according to the rules described in [1]
> and summarized here ([(S1) - stage1], [(S2) - stage 2]):
> 
> S1           |  S2           | Result
> NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
> NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
> NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
> DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>
> 
> It is worth noting that currently, to map devices MMIO space to user
> space in a device pass-through use case the VFIO framework applies memory
> attributes derived from pgprot_noncached() settings applied to VMAs, which
> result in device-nGnRnE memory attributes for the stage-1 VMM mappings.
> 
> This means that a userspace mapping for device MMIO space carried
> out with the current VFIO framework and a guest OS mapping for the same
> MMIO space may result in a mismatched alias as described in [2].
> 
> Defaulting KVM device stage-2 mappings to Normal-NC attributes does not
> change anything in this respect, in that the mismatched aliases would
> only affect (refer to [2] for a detailed explanation) ordering between
> the userspace and GuestOS mappings resulting stream of transactions
> (i.e. it does not cause loss of property for either stream of
> transactions on its own), which is harmless given that the userspace
> and GuestOS access to the device is carried out through independent
> transactions streams.
> 
> A Normal-NC flag is not present today. So add a new kvm_pgtable_prot
> (KVM_PGTABLE_PROT_NORMAL_NC) flag for it, along with its
> corresponding PTE value 0x5 (0b101) determined from [1].
> 
> Lastly, adapt the stage2 PTE property setter function
> (stage2_set_prot_attr) to handle the NormalNC attribute.
> 
> [1] section D8.5.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
> [2] section B2.8 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
> [3] sections 1.7.7.3/1.8.5.2/appendix C - DEN0029H_SBSA_7.1.pdf
> 
> Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> ---
>  arch/arm64/include/asm/kvm_pgtable.h |  2 ++
>  arch/arm64/include/asm/memory.h      |  2 ++
>  arch/arm64/kvm/hyp/pgtable.c         | 24 +++++++++++++++++++-----
>  3 files changed, 23 insertions(+), 5 deletions(-)

Acked-by: Will Deacon <will at kernel.org>

Will


From fancer.lancer at gmail.com  Tue Feb 20 04:24:06 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Tue, 20 Feb 2024 15:24:06 +0300
Subject: [PATCH v2] net: stmmac: mmc_core: Drop interrupt registers from
 stats
In-Reply-To: <20240220-stmmac_stats-v2-1-0a78863bec70@axis.com>
References: <20240220-stmmac_stats-v2-1-0a78863bec70@axis.com>
Message-ID: <sz3jfyimap4thkhxg76nrv6m2lyk5rwnsve5xxghqt7e5uo6lg@wkxcwsdhp44v>

Hi Jesper

On Tue, Feb 20, 2024 at 01:00:22PM +0100, Jesper Nilsson wrote:
> The MMC IPC interrupt status and interrupt mask registers are
> of little use as Ethernet statistics, but incrementing counters
> based on the current interrupt and interrupt mask registers
> makes them actively misleading.
> 
> For example, if the interrupt mask is set to 0x08420842,
> the current code will increment by that amount each iteration,
> leading to the following sequence of nonsense:
> 
> mmc_rx_ipc_intr_mask: 969816526
> mmc_rx_ipc_intr_mask: 1108361744
> 
> These registers have been included in the Ethernet statistics
> since the first version of MMC back in 2011 (commit 1c901a46d57).
> That commit also mentions the MMC interrupts as
> "something to add later (if actually useful)".
> 
> If the registers are actually useful, they should probably
> be part of the Ethernet register dump instead of statistics,
> but for now, drop the counters for mmc_rx_ipc_intr and
> mmc_rx_ipc_intr_mask completely.
> 
> Signed-off-by: Jesper Nilsson <jesper.nilsson at axis.com>

Thank you very much! Definitely:
Reviewed-by: Serge Semin <fancer.lancer at gmail.com>

One more statistics-related clean-up you may find useful:

net: stmmac: mmc: Discard double Rx CRC errors counter read
    
DW XGMAC MMC Rx CRC errors counter is read twice in a row. It's redundant
to do so, because unlikely the counter has changed since the first read
much while up to date statistics can be retrieved on the next MMC-read
operation. In that matter Rx CRC errors counter is no different from the
other counters, which are read just once in the same callback. So most
likely the second Rx CRC errors counter read has been added by mistake.
Let's discard it then.
    
Fixes: b6cdf09f51c2 ("net: stmmac: xgmac: Implement MMC counters")

diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
index 8597c6abae8d..759a83100f11 100644
--- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
@@ -467,8 +467,6 @@ static void dwxgmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc)
                             &mmc->mmc_rx_multicastframe_g);
        dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_CRC_ERR,
                             &mmc->mmc_rx_crc_error);
-       dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_CRC_ERR,
-                            &mmc->mmc_rx_crc_error);
        mmc->mmc_rx_run_error += readl(mmcaddr + MMC_XGMAC_RX_RUNT_ERR);
        mmc->mmc_rx_jabber_error += readl(mmcaddr + MMC_XGMAC_RX_JABBER_ERR);
        mmc->mmc_rx_undersize_g += readl(mmcaddr + MMC_XGMAC_RX_UNDER);

-Serge(y)

> ---
> Changes in v2:
> - Drop the misleading registers completely
> - Link to v1: https://lore.kernel.org/r/20240216-stmmac_stats-v1-1-7065fa4613f8 at axis.com
> ---
>  drivers/net/ethernet/stmicro/stmmac/mmc.h            | 3 ---
>  drivers/net/ethernet/stmicro/stmmac/mmc_core.c       | 3 ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 --
>  3 files changed, 8 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h
> index a0c05925883e..8cfba817491b 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/mmc.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h
> @@ -78,9 +78,6 @@ struct stmmac_counters {
>  	unsigned int mmc_rx_fifo_overflow;
>  	unsigned int mmc_rx_vlan_frames_gb;
>  	unsigned int mmc_rx_watchdog_error;
> -	/* IPC */
> -	unsigned int mmc_rx_ipc_intr_mask;
> -	unsigned int mmc_rx_ipc_intr;
>  	/* IPv4 */
>  	unsigned int mmc_rx_ipv4_gd;
>  	unsigned int mmc_rx_ipv4_hderr;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
> index 6a7c1d325c46..ab3b7770f62d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
> @@ -279,9 +279,6 @@ static void dwmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc)
>  	mmc->mmc_rx_fifo_overflow += readl(mmcaddr + MMC_RX_FIFO_OVERFLOW);
>  	mmc->mmc_rx_vlan_frames_gb += readl(mmcaddr + MMC_RX_VLAN_FRAMES_GB);
>  	mmc->mmc_rx_watchdog_error += readl(mmcaddr + MMC_RX_WATCHDOG_ERROR);
> -	/* IPC */
> -	mmc->mmc_rx_ipc_intr_mask += readl(mmcaddr + MMC_RX_IPC_INTR_MASK);
> -	mmc->mmc_rx_ipc_intr += readl(mmcaddr + MMC_RX_IPC_INTR);
>  	/* IPv4 */
>  	mmc->mmc_rx_ipv4_gd += readl(mmcaddr + MMC_RX_IPV4_GD);
>  	mmc->mmc_rx_ipv4_hderr += readl(mmcaddr + MMC_RX_IPV4_HDERR);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> index f628411ae4ae..28accdc98282 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> @@ -236,8 +236,6 @@ static const struct stmmac_stats stmmac_mmc[] = {
>  	STMMAC_MMC_STAT(mmc_rx_fifo_overflow),
>  	STMMAC_MMC_STAT(mmc_rx_vlan_frames_gb),
>  	STMMAC_MMC_STAT(mmc_rx_watchdog_error),
> -	STMMAC_MMC_STAT(mmc_rx_ipc_intr_mask),
> -	STMMAC_MMC_STAT(mmc_rx_ipc_intr),
>  	STMMAC_MMC_STAT(mmc_rx_ipv4_gd),
>  	STMMAC_MMC_STAT(mmc_rx_ipv4_hderr),
>  	STMMAC_MMC_STAT(mmc_rx_ipv4_nopay),
> 
> ---
> base-commit: 0dd3ee31125508cd67f7e7172247f05b7fd1753a
> change-id: 20240216-stmmac_stats-e3561d460d0e
> 
> Best regards,
> -- 
> 
> /^JN - Jesper Nilsson
> -- 
>                Jesper Nilsson -- jesper.nilsson at axis.com
> 
> 


From maz at kernel.org  Tue Feb 20 04:29:30 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 20 Feb 2024 12:29:30 +0000
Subject: [PATCH 02/13] KVM: arm64: Clarify ESR_ELx_ERET_ISS_ERET*
In-Reply-To: <20240220113127.GB16168@e124191.cambridge.arm.com>
References: <20240219092014.783809-1-maz@kernel.org>
	<20240219092014.783809-3-maz@kernel.org>
	<20240220113127.GB16168@e124191.cambridge.arm.com>
Message-ID: <861q9748ut.wl-maz@kernel.org>

On Tue, 20 Feb 2024 11:31:27 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> On Mon, Feb 19, 2024 at 09:20:03AM +0000, Marc Zyngier wrote:
> > The ESR_ELx_ERET_ISS_ERET* macros are a bit confusing:
> > 
> > - ESR_ELx_ERET_ISS_ERET really indicates that we have trapped an
> >   ERETA* instruction, as opposed to an ERET
> > 
> > - ESR_ELx_ERET_ISS_ERETA reallu indicates that we have trapped
> >   an ERETAB instruction, as opposed to an ERETAA.
> > 
> > Repaint the two helpers such as:
> > 
> > - ESR_ELx_ERET_ISS_ERET becomes ESR_ELx_ERET_ISS_ERETA
> > 
> > - ESR_ELx_ERET_ISS_ERETA becomes ESR_ELx_ERET_ISS_ERETAB
> > 
> > At the same time, use BIT() instead of raw values.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> 
> I'm somewhat against this, as the original names are what the Arm
> ARM specifies.

I don't disagree, but that doesn't make the ARM ARM right! ;-)

> 
> > ---
> >  arch/arm64/include/asm/esr.h | 4 ++--
> >  arch/arm64/kvm/handle_exit.c | 2 +-
> >  2 files changed, 3 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> > index 353fe08546cf..72c7810ccf2c 100644
> > --- a/arch/arm64/include/asm/esr.h
> > +++ b/arch/arm64/include/asm/esr.h
> > @@ -290,8 +290,8 @@
> >  		 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
> > +#define ESR_ELx_ERET_ISS_ERETA		BIT(1)
> > +#define ESR_ELx_ERET_ISS_ERETAB		BIT(0)
> >  
> >  /*
> >   * ISS field definitions for floating-point exception traps
> > diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> > index 617ae6dea5d5..0646c623d1da 100644
> > --- a/arch/arm64/kvm/handle_exit.c
> > +++ b/arch/arm64/kvm/handle_exit.c
> > @@ -219,7 +219,7 @@ static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
> >  
> >  static int kvm_handle_eret(struct kvm_vcpu *vcpu)
> >  {
> > -	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERET)
> > +	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERETA)
> 
> If this part is confusing due to the name, maybe introduce a function in esr.h
> esr_is_pac_eret() (name pending bikeshedding)?

That's indeed a better option. Now for the bikeshed aspect:

- esr_iss_is_eretax(): check for ESR_ELx_ERET_ISS_ERET being set

- esr_iss_is_eretab(): check for ESR_ELx_ERET_ISS_ERETA being set

Thoughts?

	M.

-- 
Without deviation from the norm, progress is not possible.


From broonie at kernel.org  Tue Feb 20 04:47:48 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 12:47:48 +0000
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for
 WCN7850
In-Reply-To: <CAMRc=MeUjKPS3ANE6=7WZ3kbbGAdyE8HeXFN=75Jp-pVyBaWrQ@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-15-brgl@bgdev.pl>
 <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk>
 <CAMRc=MeUjKPS3ANE6=7WZ3kbbGAdyE8HeXFN=75Jp-pVyBaWrQ@mail.gmail.com>
Message-ID: <ea08a286-ff53-4d58-ae41-38cca151508c@sirena.org.uk>

On Tue, Feb 20, 2024 at 12:22:42PM +0100, Bartosz Golaszewski wrote:
> On Mon, Feb 19, 2024 at 6:50?PM Mark Brown <broonie at kernel.org> wrote:
> > On Fri, Feb 16, 2024 at 09:32:11PM +0100, Bartosz Golaszewski wrote:

> > > +static struct pci_pwrctl_wcn7850_vreg pci_pwrctl_wcn7850_vregs[] = {
> > > +     {
> > > +             .name = "vdd",
> > > +             .load_uA = 16000,
> > > +     },

> > I know a bunch of the QC stuff includes these load numbers but are they
> > actually doing anything constructive?  It keeps coming up that they're
> > causing a bunch of work and it's not clear that they have any great
> > effect on modern systems.

> Yes, we have what is called a high-power mode and a low-power mode in
> regulators and these values are used to determine which one to use.

Are you *sure* this actually happens (and that the regulators don't
figure it out by themselves), especially given that the consumers are
just specifying the load once rather than varying it dynamically at
runtime which is supposed to be the use case for this API?  This API is
intended to be used dynamically, if the regulator always needs to be in
a particular mode just configure that statically.
-------------- 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/20240220/c254ca1c/attachment.sig>

From abel.vesa at linaro.org  Tue Feb 20 04:59:20 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Tue, 20 Feb 2024 14:59:20 +0200
Subject: [PATCH RFC v4 0/4] spmi: pmic-arb: Add support for multiple buses
Message-ID: <20240220-spmi-multi-master-support-v4-0-dc813c878ba8@linaro.org>

This RFC prepares for and adds support for 2 buses, which is supported
in HW starting with version 7. Until now, none of the currently
supported platforms in upstream have used the second bus. The X1E80100
platform, on the other hand, needs the second bus for the USB2.0 to work
as there are 3 SMB2360 PMICs which provide eUSB2 repeaters and they are
all found on the second bus.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
Changes in v4:
- Fixed comment above pmic_arb_init_apid_v7 by dropping the extra "bus" word
- Swicthed to devm_platform_ioremap_resource_byname for obsrvr and chnls.
  The core remains with platform_get_resource_byname as we need the core size.
- Dropped comment from probe related to the need of platform_get_resource_byname
  as it not true anymore.
- Dropped the qcom,bus-id optional property.
- Link to v3: https://lore.kernel.org/r/20240214-spmi-multi-master-support-v3-0-0bae0ef04faf at linaro.org

Changes in v3:
- Split the change into 3 separate patches. First 2 patches are moving
  apid init and core resources into version specific ops. Third one is
  adding the support for 2 buses and dedicated compatible.
- Added separate bindings patch
- Link to v2: https://lore.kernel.org/r/20240213-spmi-multi-master-support-v2-1-b3b102326906 at linaro.org

Changes in v2:
- Reworked it so that it registers a spmi controller for each bus
  rather than relying on the generic framework to pass on the bus
  (master) id.
- Link to v1: https://lore.kernel.org/r/20240207-spmi-multi-master-support-v1-0-ce57f301c7fd at linaro.org

---
Abel Vesa (4):
      dt-bindings: spmi: Add PMIC ARB v7 schema
      spmi: pmic-arb: Make the APID init a version operation
      spmi: pmic-arb: Make core resources acquiring a version operation
      spmi: pmic-arb: Add multi bus support

 .../bindings/spmi/qcom,spmi-pmic-arb-v7.yaml       | 119 +++
 drivers/spmi/spmi-pmic-arb.c                       | 951 +++++++++++++--------
 2 files changed, 700 insertions(+), 370 deletions(-)
---
base-commit: 2d5c7b7eb345249cb34d42cbc2b97b4c57ea944e
change-id: 20240207-spmi-multi-master-support-832a704b779b

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>



From abel.vesa at linaro.org  Tue Feb 20 04:59:21 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Tue, 20 Feb 2024 14:59:21 +0200
Subject: [PATCH RFC v4 1/4] dt-bindings: spmi: Add PMIC ARB v7 schema
In-Reply-To: <20240220-spmi-multi-master-support-v4-0-dc813c878ba8@linaro.org>
References: <20240220-spmi-multi-master-support-v4-0-dc813c878ba8@linaro.org>
Message-ID: <20240220-spmi-multi-master-support-v4-1-dc813c878ba8@linaro.org>

Add dedicated schema for PMIC ARB v7 as it allows multiple
buses by declaring them as child nodes. These child nodes
will follow the generic spmi bus bindings.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 .../bindings/spmi/qcom,spmi-pmic-arb-v7.yaml       | 119 +++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml
new file mode 100644
index 000000000000..8a93d2145aa5
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spmi/qcom,spmi-pmic-arb-v7.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SPMI Controller v7 (PMIC Arbiter)
+
+maintainers:
+  - Stephen Boyd <sboyd at kernel.org>
+
+description: |
+  The SPMI PMIC Arbiter v7 is found on Snapdragon chipsets. It is an SPMI
+  controller with wrapping arbitration logic to allow for multiple on-chip
+  devices to control up to 2 SPMI separate buses.
+
+  The PMIC Arbiter can also act as an interrupt controller, providing interrupts
+  to slave devices.
+
+properties:
+  compatible:
+    const: qcom,spmi-pmic-arb-v7
+
+  reg:
+    items:
+      - description: core registers
+      - description: tx-channel per virtual slave regosters
+      - description: rx-channel (called observer) per virtual slave registers
+
+  reg-names:
+    items:
+      - const: core
+      - const: chnls
+      - const: obsrvr
+
+  ranges: true
+
+  '#address-cells':
+    const: 2
+
+  '#size-cells':
+    const: 2
+
+  qcom,ee:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 5
+    description: >
+      indicates the active Execution Environment identifier
+
+  qcom,channel:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 5
+    description: >
+      which of the PMIC Arb provided channels to use for accesses
+
+patternProperties:
+  "spmi@[0-1]$":
+    type: object
+    $ref: /schemas/spmi/spmi.yaml
+
+required:
+  - compatible
+  - reg-names
+  - qcom,ee
+  - qcom,channel
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    spmi: arbiter at c400000 {
+      compatible = "qcom,spmi-pmic-arb-v7";
+      reg = <0x0c400000 0x3000>,
+            <0x0c500000 0x4000000>,
+            <0x0c440000 0x80000>;
+      reg-names = "core", "chnls", "obsrvr";
+
+      qcom,ee = <0>;
+      qcom,channel = <0>;
+
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      spmi_bus0: spmi at 0 {
+        reg = <0 0x0c42d000 0 0x4000>,
+              <0 0x0c4c0000 0 0x10000>;
+        reg-names = "cnfg", "intr";
+
+        interrupt-names = "periph_irq";
+        interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-controller;
+        #interrupt-cells = <4>;
+
+        qcom,bus-id = <0>;
+
+        #address-cells = <2>;
+        #size-cells = <0>;
+      };
+
+      spmi_bus1: spmi at 1 {
+        reg = <0 0x0c432000 0 0x4000>,
+              <0 0x0c4d0000 0 0x10000>;
+        reg-names = "cnfg", "intr";
+
+        interrupt-names = "periph_irq";
+        interrupts-extended = <&pdc 3 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-controller;
+        #interrupt-cells = <4>;
+
+        qcom,bus-id = <1>;
+
+        #address-cells = <2>;
+        #size-cells = <0>;
+      };
+    };

-- 
2.34.1



From abel.vesa at linaro.org  Tue Feb 20 04:59:22 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Tue, 20 Feb 2024 14:59:22 +0200
Subject: [PATCH RFC v4 2/4] spmi: pmic-arb: Make the APID init a version
 operation
In-Reply-To: <20240220-spmi-multi-master-support-v4-0-dc813c878ba8@linaro.org>
References: <20240220-spmi-multi-master-support-v4-0-dc813c878ba8@linaro.org>
Message-ID: <20240220-spmi-multi-master-support-v4-2-dc813c878ba8@linaro.org>

Rather than using conditionals in probe function, add the APID init
as a version specific operation. Due to v7, which supports multiple
buses, pass on the bus index to be used for sorting out the apid base
and count.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 199 +++++++++++++++++++++++++++----------------
 1 file changed, 124 insertions(+), 75 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 9ed1180fe31f..38fed8a585fe 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -183,6 +183,7 @@ struct spmi_pmic_arb {
  * struct pmic_arb_ver_ops - version dependent functionality.
  *
  * @ver_str:		version string.
+ * @init_apid:		finds the apid base and count
  * @ppid_to_apid:	finds the apid for a given ppid.
  * @non_data_cmd:	on v1 issues an spmi non-data command.
  *			on v2 no HW support, returns -EOPNOTSUPP.
@@ -202,6 +203,7 @@ struct spmi_pmic_arb {
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
+	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
 	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
 	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
@@ -942,6 +944,38 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 	return 0;
 }
 
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
+{
+	/*
+	 * Initialize max_apid/min_apid to the opposite bounds, during
+	 * the irq domain translation, we are sure to update these
+	 */
+	pmic_arb->max_apid = 0;
+	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
+
+	return 0;
+}
+
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	u32 *mapping_table;
+
+	if (index) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs,
+				     sizeof(*mapping_table), GFP_KERNEL);
+	if (!mapping_table)
+		return -ENOMEM;
+
+	pmic_arb->mapping_table = mapping_table;
+
+	return pmic_arb_init_apid_min_max(pmic_arb);
+}
+
 static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 {
 	u32 *mapping_table = pmic_arb->mapping_table;
@@ -1144,6 +1178,40 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0x1000 * pmic_arb->ee + 0x8000 * apid;
 }
 
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	int ret;
+
+	if (index) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	pmic_arb->base_apid = 0;
+	pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+					   PMIC_ARB_FEATURES_PERIPH_MASK;
+
+	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+			pmic_arb->base_apid + pmic_arb->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	if (ret) {
+		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v5 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
@@ -1178,6 +1246,49 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return offset;
 }
 
+/*
+ * Only v7 supports 2 buses. Each bus will get a different apid count, read
+ * from different registers.
+ */
+static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	int ret;
+
+	if (index == 0) {
+		pmic_arb->base_apid = 0;
+		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else if (index == 1) {
+		pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						  PMIC_ARB_FEATURES_PERIPH_MASK;
+		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+			pmic_arb->base_apid + pmic_arb->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	if (ret) {
+		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v7 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
@@ -1358,6 +1469,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v1,
 	.offset			= pmic_arb_offset_v1,
@@ -1372,6 +1484,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.ver_str		= "v2",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1386,6 +1499,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.ver_str		= "v3",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1400,6 +1514,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.ver_str		= "v5",
+	.init_apid		= pmic_arb_init_apid_v5,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v5,
@@ -1414,6 +1529,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.ver_str		= "v7",
+	.init_apid		= pmic_arb_init_apid_v7,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v7,
@@ -1439,7 +1555,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	struct spmi_controller *ctrl;
 	struct resource *res;
 	void __iomem *core;
-	u32 *mapping_table;
 	u32 channel, ee, hw_ver;
 	int err;
 
@@ -1467,12 +1582,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	pmic_arb->core_size = resource_size(res);
 
-	pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
-					      sizeof(*pmic_arb->ppid_to_apid),
-					      GFP_KERNEL);
-	if (!pmic_arb->ppid_to_apid)
-		return -ENOMEM;
-
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
 	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
@@ -1506,58 +1615,17 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 			return PTR_ERR(pmic_arb->wr_base);
 	}
 
-	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
+		 pmic_arb->ver_ops->ver_str, hw_ver);
 
-	if (hw_ver >= PMIC_ARB_VERSION_V7_MIN) {
+	if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+	else
 		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
-		/* Optional property for v7: */
-		of_property_read_u32(pdev->dev.of_node, "qcom,bus-id",
-					&pmic_arb->bus_instance);
-		if (pmic_arb->bus_instance > 1) {
-			dev_err(&pdev->dev, "invalid bus instance (%u) specified\n",
-				pmic_arb->bus_instance);
-			return -EINVAL;
-		}
-
-		if (pmic_arb->bus_instance == 0) {
-			pmic_arb->base_apid = 0;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		} else {
-			pmic_arb->base_apid =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES1) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		}
 
-		if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->base_apid + pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	} else if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		pmic_arb->base_apid = 0;
-		pmic_arb->apid_count = readl_relaxed(core + PMIC_ARB_FEATURES) &
-					PMIC_ARB_FEATURES_PERIPH_MASK;
-
-		if (pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	}
-
-	pmic_arb->apid_data = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					   sizeof(*pmic_arb->apid_data),
-					   GFP_KERNEL);
-	if (!pmic_arb->apid_data)
-		return -ENOMEM;
-
-	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
-		 pmic_arb->ver_ops->ver_str, hw_ver);
+	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
+	if (err)
+		return err;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
 	pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
@@ -1599,16 +1667,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	}
 
 	pmic_arb->ee = ee;
-	mapping_table = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					sizeof(*mapping_table), GFP_KERNEL);
-	if (!mapping_table)
-		return -ENOMEM;
-
-	pmic_arb->mapping_table = mapping_table;
-	/* Initialize max_apid/min_apid to the opposite bounds, during
-	 * the irq domain translation, we are sure to update these */
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
 
 	platform_set_drvdata(pdev, ctrl);
 	raw_spin_lock_init(&pmic_arb->lock);
@@ -1617,15 +1675,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	ctrl->read_cmd = pmic_arb_read_cmd;
 	ctrl->write_cmd = pmic_arb_write_cmd;
 
-	if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		err = pmic_arb_read_apid_map_v5(pmic_arb);
-		if (err) {
-			dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n",
-				err);
-			return err;
-		}
-	}
-
 	dev_dbg(&pdev->dev, "adding irq domain\n");
 	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
 					 &pmic_arb_irq_domain_ops, pmic_arb);

-- 
2.34.1



From abel.vesa at linaro.org  Tue Feb 20 04:59:23 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Tue, 20 Feb 2024 14:59:23 +0200
Subject: [PATCH RFC v4 3/4] spmi: pmic-arb: Make core resources acquiring a
 version operation
In-Reply-To: <20240220-spmi-multi-master-support-v4-0-dc813c878ba8@linaro.org>
References: <20240220-spmi-multi-master-support-v4-0-dc813c878ba8@linaro.org>
Message-ID: <20240220-spmi-multi-master-support-v4-3-dc813c878ba8@linaro.org>

Rather than setting up the core, obsrv and chnls in probe by using
version specific conditionals, add a dedicated "get_core_resources"
version specific op and move the acquiring in there.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 115 +++++++++++++++++++++++++++----------------
 1 file changed, 72 insertions(+), 43 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 38fed8a585fe..5aad188a3db2 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -203,6 +203,7 @@ struct spmi_pmic_arb {
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
+	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
 	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
 	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
@@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
 	return 0;
 }
 
+static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->wr_base = core;
+	pmic_arb->rd_base = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+	return 0;
+}
+
 static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
 {
 	u32 *mapping_table;
@@ -1063,6 +1077,35 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 	return apid;
 }
 
+static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+
+	pmic_arb->rd_base = devm_platform_ioremap_resource_byname(pdev, "obsrvr");
+	if (IS_ERR(pmic_arb->rd_base))
+		return PTR_ERR(pmic_arb->rd_base);
+
+	pmic_arb->wr_base = devm_platform_ioremap_resource_byname(pdev, "chnls");
+	if (IS_ERR(pmic_arb->wr_base))
+		return PTR_ERR(pmic_arb->wr_base);
+
+	return 0;
+}
+
+static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->core = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+	return pmic_arb_get_obsrvr_chnls_v2(pdev);
+}
+
 static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 {
 	u16 apid_valid;
@@ -1246,6 +1289,18 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return offset;
 }
 
+static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->core = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+
+	return pmic_arb_get_obsrvr_chnls_v2(pdev);
+}
+
 /*
  * Only v7 supports 2 buses. Each bus will get a different apid count, read
  * from different registers.
@@ -1469,6 +1524,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
+	.get_core_resources	= pmic_arb_get_core_resources_v1,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v1,
@@ -1484,6 +1540,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.ver_str		= "v2",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1499,6 +1556,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.ver_str		= "v3",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1514,6 +1572,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.ver_str		= "v5",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v5,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1529,6 +1588,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.ver_str		= "v7",
+	.get_core_resources	= pmic_arb_get_core_resources_v7,
 	.init_apid		= pmic_arb_init_apid_v7,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1565,16 +1625,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	pmic_arb = spmi_controller_get_drvdata(ctrl);
 	pmic_arb->spmic = ctrl;
 
-	/*
-	 * Please don't replace this with devm_platform_ioremap_resource() or
-	 * devm_ioremap_resource().  These both result in a call to
-	 * devm_request_mem_region() which prevents multiple mappings of this
-	 * register address range.  SoCs with PMIC arbiter v7 may define two
-	 * arbiter devices, for the two physical SPMI interfaces, which  share
-	 * some register address ranges (i.e. "core", "obsrvr", and "chnls").
-	 * Ensure that both devices probe successfully by calling devm_ioremap()
-	 * which does not result in a devm_request_mem_region() call.
-	 */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
 	core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
 	if (IS_ERR(core))
@@ -1584,44 +1634,23 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
-	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
+	if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
 		pmic_arb->ver_ops = &pmic_arb_v1;
-		pmic_arb->wr_base = core;
-		pmic_arb->rd_base = core;
-	} else {
-		pmic_arb->core = core;
-
-		if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v2;
-		else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v3;
-		else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v5;
-		else
-			pmic_arb->ver_ops = &pmic_arb_v7;
-
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   "obsrvr");
-		pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start,
-						 resource_size(res));
-		if (IS_ERR(pmic_arb->rd_base))
-			return PTR_ERR(pmic_arb->rd_base);
-
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   "chnls");
-		pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start,
-						 resource_size(res));
-		if (IS_ERR(pmic_arb->wr_base))
-			return PTR_ERR(pmic_arb->wr_base);
-	}
+	else if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v2;
+	else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v3;
+	else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v5;
+	else
+		pmic_arb->ver_ops = &pmic_arb_v7;
 
 	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
 		 pmic_arb->ver_ops->ver_str, hw_ver);
 
-	if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
-		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
-	else
-		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
+	if (err)
+		return err;
 
 	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
 	if (err)

-- 
2.34.1



From abel.vesa at linaro.org  Tue Feb 20 04:59:24 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Tue, 20 Feb 2024 14:59:24 +0200
Subject: [PATCH RFC v4 4/4] spmi: pmic-arb: Add multi bus support
In-Reply-To: <20240220-spmi-multi-master-support-v4-0-dc813c878ba8@linaro.org>
References: <20240220-spmi-multi-master-support-v4-0-dc813c878ba8@linaro.org>
Message-ID: <20240220-spmi-multi-master-support-v4-4-dc813c878ba8@linaro.org>

Starting with HW version 7, there are actually two separate buses
(with two separate sets of wires). So in order to support both
buses, we need to register a separate spmi controller for each one.
Add a separate compatible for v7 only, but allow the legacy platforms
that have v7 to still work with the old one, for DT backwards
compatibility.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 727 +++++++++++++++++++++++++------------------
 1 file changed, 430 insertions(+), 297 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 5aad188a3db2..1fe95e96c045 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -13,6 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spmi.h>
@@ -94,6 +96,8 @@ enum pmic_arb_channel {
 	PMIC_ARB_CHANNEL_OBS,
 };
 
+#define PMIC_ARB_MAX_BUSES		2
+
 /* Maximum number of support PMIC peripherals */
 #define PMIC_ARB_MAX_PERIPHS		512
 #define PMIC_ARB_MAX_PERIPHS_V7		1024
@@ -125,58 +129,68 @@ struct apid_data {
 	u8		irq_ee;
 };
 
+struct spmi_pmic_arb;
+
 /**
- * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ * struct spmi_pmic_arb_bus - SPMI PMIC Arbiter Bus object
  *
- * @rd_base:		on v1 "core", on v2 "observer" register base off DT.
- * @wr_base:		on v1 "core", on v2 "chnls"    register base off DT.
  * @intr:		address of the SPMI interrupt control registers.
  * @cnfg:		address of the PMIC Arbiter configuration registers.
- * @lock:		lock to synchronize accesses.
- * @channel:		execution environment channel to use for accesses.
- * @irq:		PMIC ARB interrupt.
- * @ee:			the current Execution Environment
- * @bus_instance:	on v7: 0 = primary SPMI bus, 1 = secondary SPMI bus
- * @min_apid:		minimum APID (used for bounding IRQ search)
- * @max_apid:		maximum APID
+ * @domain:		irq domain object for PMIC IRQ domain
  * @base_apid:		on v7: minimum APID associated with the particular SPMI
  *			bus instance
  * @apid_count:		on v5 and v7: number of APIDs associated with the
  *			particular SPMI bus instance
  * @mapping_table:	in-memory copy of PPID -> APID mapping table.
- * @domain:		irq domain object for PMIC IRQ domain
- * @spmic:		SPMI controller object
- * @ver_ops:		version dependent operations.
  * @ppid_to_apid:	in-memory copy of PPID -> APID mapping table.
- * @last_apid:		Highest value APID in use
  * @apid_data:		Table of data for all APIDs
+ * @last_apid:		Highest value APID in use
+ * @irq:		PMIC ARB interrupt.
+ */
+struct spmi_pmic_arb_bus {
+	struct spmi_pmic_arb	*pmic_arb;
+	struct irq_domain	*domain;
+	void __iomem		*intr;
+	void __iomem		*cnfg;
+	struct spmi_controller	*spmic;
+	u16			base_apid;
+	int			apid_count;
+	u32			*mapping_table;
+	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
+	u16			*ppid_to_apid;
+	u16			last_apid;
+	struct apid_data	*apid_data;
+	u16			min_apid;
+	u16			max_apid;
+	int			irq;
+	u8			id;
+};
+
+/**
+ * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ *
+ * @rd_base:		on v1 "core", on v2 "observer" register base off DT.
+ * @wr_base:		on v1 "core", on v2 "chnls"    register base off DT.
+ * @lock:		lock to synchronize accesses.
+ * @channel:		execution environment channel to use for accesses.
+ * @ee:			the current Execution Environment
+ * @min_apid:		minimum APID (used for bounding IRQ search)
+ * @max_apid:		maximum APID
+ * @ver_ops:		version dependent operations.
  * @max_periphs:	Number of elements in apid_data[]
  */
 struct spmi_pmic_arb {
 	void __iomem		*rd_base;
 	void __iomem		*wr_base;
-	void __iomem		*intr;
-	void __iomem		*cnfg;
 	void __iomem		*core;
 	resource_size_t		core_size;
 	raw_spinlock_t		lock;
 	u8			channel;
-	int			irq;
 	u8			ee;
-	u32			bus_instance;
-	u16			min_apid;
-	u16			max_apid;
-	u16			base_apid;
-	int			apid_count;
-	u32			*mapping_table;
-	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
-	struct irq_domain	*domain;
-	struct spmi_controller	*spmic;
 	const struct pmic_arb_ver_ops *ver_ops;
-	u16			*ppid_to_apid;
-	u16			last_apid;
-	struct apid_data	*apid_data;
 	int			max_periphs;
+	struct spmi_pmic_arb_bus buses[PMIC_ARB_MAX_BUSES];
+	int			buses_available;
 };
 
 /**
@@ -204,21 +218,21 @@ struct spmi_pmic_arb {
 struct pmic_arb_ver_ops {
 	const char *ver_str;
 	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
-	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
-	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
+	int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index);
+	int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
-	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type);
+	int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+		      enum pmic_arb_channel ch_type);
 	u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
 	int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
 	/* Interrupts controller functionality (offset of PIC registers) */
-	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb *pmic_arb, u8 m,
+	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb_bus *bus, u8 m,
 					  u16 n);
-	void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*acc_enable)(struct spmi_pmic_arb_bus *bus, u16 n);
+	void __iomem *(*irq_status)(struct spmi_pmic_arb_bus *bus, u16 n);
+	void __iomem *(*irq_clear)(struct spmi_pmic_arb_bus *bus, u16 n);
 	u32 (*apid_map_offset)(u16 n);
-	void __iomem *(*apid_owner)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*apid_owner)(struct spmi_pmic_arb_bus *bus, u16 n);
 };
 
 static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -266,13 +280,14 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 				  void __iomem *base, u8 sid, u16 addr,
 				  enum pmic_arb_channel ch_type)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 status = 0;
 	u32 timeout = PMIC_ARB_TIMEOUT_US;
 	u32 offset;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type);
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr, ch_type);
 	if (rc < 0)
 		return rc;
 
@@ -284,21 +299,21 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 
 		if (status & PMIC_ARB_STATUS_DONE) {
 			if (status & PMIC_ARB_STATUS_DENIED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction denied (%#x)\n",
+					__func__, bus->id, sid, addr, status);
 				return -EPERM;
 			}
 
 			if (status & PMIC_ARB_STATUS_FAILURE) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction failed (%#x) reg: 0x%x\n",
+					__func__, bus->id, sid, addr, status, offset);
 				WARN_ON(1);
 				return -EIO;
 			}
 
 			if (status & PMIC_ARB_STATUS_DROPPED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction dropped (%#x)\n",
+					__func__, bus->id, sid, addr, status);
 				return -EIO;
 			}
 
@@ -307,8 +322,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 		udelay(1);
 	}
 
-	dev_err(&ctrl->dev, "%s: %#x %#x: timeout, status %#x\n",
-		__func__, sid, addr, status);
+	dev_err(&ctrl->dev, "%s: %#x %#x %#x: timeout, status %#x\n",
+		__func__, bus->id, sid, addr, status);
 	return -ETIMEDOUT;
 }
 
@@ -316,12 +331,13 @@ static int
 pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[0];
 	unsigned long flags;
 	u32 cmd;
 	int rc;
 	u32 offset;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW);
+	rc = pmic_arb->ver_ops->offset(bus, sid, 0, PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
@@ -357,20 +373,21 @@ static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
 	return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid);
 }
 
-static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 sid,
+static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb_bus *bus, u8 opc, u8 sid,
 				 u16 addr, size_t len, u32 *cmd, u32 *offset)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr,
 				       PMIC_ARB_CHANNEL_OBS);
 	if (rc < 0)
 		return rc;
 
 	*offset = rc;
 	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-		dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+		dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
 			PMIC_ARB_MAX_TRANS_BYTES, len);
 		return  -EINVAL;
 	}
@@ -394,7 +411,8 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      u32 offset, u8 sid, u16 addr, u8 *buf,
 				      size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
@@ -416,12 +434,13 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 			     u16 addr, u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned long flags;
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_read_cmd(bus, opc, sid, addr, len, &cmd,
 				   &offset);
 	if (rc)
 		return rc;
@@ -433,21 +452,22 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 	return rc;
 }
 
-static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc,
+static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb_bus *bus, u8 opc,
 				  u8 sid, u16 addr, size_t len, u32 *cmd,
 				  u32 *offset)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr,
 					PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
 	*offset = rc;
 	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-		dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+		dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
 			PMIC_ARB_MAX_TRANS_BYTES, len);
 		return  -EINVAL;
 	}
@@ -473,7 +493,8 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      u32 offset, u8 sid, u16 addr,
 				      const u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 
 	/* Write data to FIFOs */
@@ -492,12 +513,13 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 			      u16 addr, const u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned long flags;
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_write_cmd(bus, opc, sid, addr, len, &cmd,
 				    &offset);
 	if (rc)
 		return rc;
@@ -513,18 +535,19 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr,
 				 const u8 *buf, const u8 *mask, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 read_cmd, read_offset, write_cmd, write_offset;
 	u8 temp[PMIC_ARB_MAX_TRANS_BYTES];
 	unsigned long flags;
 	int rc, i;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, SPMI_CMD_EXT_READL, sid, addr, len,
+	rc = pmic_arb_fmt_read_cmd(bus, SPMI_CMD_EXT_READL, sid, addr, len,
 				   &read_cmd, &read_offset);
 	if (rc)
 		return rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, SPMI_CMD_EXT_WRITEL, sid, addr,
+	rc = pmic_arb_fmt_write_cmd(bus, SPMI_CMD_EXT_WRITEL, sid, addr,
 				    len, &write_cmd, &write_offset);
 	if (rc)
 		return rc;
@@ -567,25 +590,25 @@ struct spmi_pmic_arb_qpnpint_type {
 static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
 			       size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
+	if (pmic_arb_write_cmd(bus->spmic, SPMI_CMD_EXT_WRITEL, sid,
 			       (per << 8) + reg, buf, len))
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
 }
 
 static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, sid,
+	if (pmic_arb_read_cmd(bus->spmic, SPMI_CMD_EXT_READL, sid,
 			      (per << 8) + reg, buf, len))
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
 }
 
@@ -593,47 +616,49 @@ static int qpnpint_spmi_masked_write(struct irq_data *d, u8 reg,
 				     const void *buf, const void *mask,
 				     size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 	int rc;
 
-	rc = pmic_arb_masked_write(pmic_arb->spmic, sid, (per << 8) + reg, buf,
+	rc = pmic_arb_masked_write(bus->spmic, sid, (per << 8) + reg, buf,
 				   mask, len);
 	if (rc)
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
 				    d->irq, rc);
 	return rc;
 }
 
-static void cleanup_irq(struct spmi_pmic_arb *pmic_arb, u16 apid, int id)
+static void cleanup_irq(struct spmi_pmic_arb_bus *bus, u16 apid, int id)
 {
-	u16 ppid = pmic_arb->apid_data[apid].ppid;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	u16 ppid = bus->apid_data[apid].ppid;
 	u8 sid = ppid >> 8;
 	u8 per = ppid & 0xFF;
 	u8 irq_mask = BIT(id);
 
-	dev_err_ratelimited(&pmic_arb->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
-			__func__, apid, sid, per, id);
-	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	dev_err_ratelimited(&bus->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
+			    __func__, apid, sid, per, id);
+	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(bus, apid));
 }
 
-static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
+static int periph_interrupt(struct spmi_pmic_arb_bus *bus, u16 apid)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned int irq;
 	u32 status, id;
 	int handled = 0;
-	u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF;
-	u8 per = pmic_arb->apid_data[apid].ppid & 0xFF;
+	u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF;
+	u8 per = bus->apid_data[apid].ppid & 0xFF;
 
-	status = readl_relaxed(pmic_arb->ver_ops->irq_status(pmic_arb, apid));
+	status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid));
 	while (status) {
 		id = ffs(status) - 1;
 		status &= ~BIT(id);
-		irq = irq_find_mapping(pmic_arb->domain,
-					spec_to_hwirq(sid, per, id, apid));
+		irq = irq_find_mapping(bus->domain,
+				       spec_to_hwirq(sid, per, id, apid));
 		if (irq == 0) {
-			cleanup_irq(pmic_arb, apid, id);
+			cleanup_irq(bus, apid, id);
 			continue;
 		}
 		generic_handle_irq(irq);
@@ -645,16 +670,17 @@ static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
 
 static void pmic_arb_chained_irq(struct irq_desc *desc)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb_bus *bus = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int first = pmic_arb->min_apid;
-	int last = pmic_arb->max_apid;
+	int first = bus->min_apid;
+	int last = bus->max_apid;
 	/*
 	 * acc_offset will be non-zero for the secondary SPMI bus instance on
 	 * v7 controllers.
 	 */
-	int acc_offset = pmic_arb->base_apid >> 5;
+	int acc_offset = bus->base_apid >> 5;
 	u8 ee = pmic_arb->ee;
 	u32 status, enable, handled = 0;
 	int i, id, apid;
@@ -665,7 +691,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	chained_irq_enter(chip, desc);
 
 	for (i = first >> 5; i <= last >> 5; ++i) {
-		status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i - acc_offset));
+		status = readl_relaxed(ver_ops->owner_acc_status(bus, ee, i - acc_offset));
 		if (status)
 			acc_valid = true;
 
@@ -679,9 +705,9 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 				continue;
 			}
 			enable = readl_relaxed(
-					ver_ops->acc_enable(pmic_arb, apid));
+					ver_ops->acc_enable(bus, apid));
 			if (enable & SPMI_PIC_ACC_ENABLE_BIT)
-				if (periph_interrupt(pmic_arb, apid) != 0)
+				if (periph_interrupt(bus, apid) != 0)
 					handled++;
 		}
 	}
@@ -690,19 +716,19 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	if (!acc_valid) {
 		for (i = first; i <= last; i++) {
 			/* skip if APPS is not irq owner */
-			if (pmic_arb->apid_data[i].irq_ee != pmic_arb->ee)
+			if (bus->apid_data[i].irq_ee != pmic_arb->ee)
 				continue;
 
 			irq_status = readl_relaxed(
-					     ver_ops->irq_status(pmic_arb, i));
+					     ver_ops->irq_status(bus, i));
 			if (irq_status) {
 				enable = readl_relaxed(
-					     ver_ops->acc_enable(pmic_arb, i));
+					     ver_ops->acc_enable(bus, i));
 				if (enable & SPMI_PIC_ACC_ENABLE_BIT) {
-					dev_dbg(&pmic_arb->spmic->dev,
+					dev_dbg(&bus->spmic->dev,
 						"Dispatching IRQ for apid=%d status=%x\n",
 						i, irq_status);
-					if (periph_interrupt(pmic_arb, i) != 0)
+					if (periph_interrupt(bus, i) != 0)
 						handled++;
 				}
 			}
@@ -717,12 +743,13 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 
 static void qpnpint_irq_ack(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 data;
 
-	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(bus, apid));
 
 	data = BIT(irq);
 	qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
@@ -738,14 +765,15 @@ static void qpnpint_irq_mask(struct irq_data *d)
 
 static void qpnpint_irq_unmask(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 buf[2];
 
 	writel_relaxed(SPMI_PIC_ACC_ENABLE_BIT,
-			ver_ops->acc_enable(pmic_arb, apid));
+			ver_ops->acc_enable(bus, apid));
 
 	qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1);
 	if (!(buf[0] & BIT(irq))) {
@@ -802,9 +830,9 @@ static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
 
 static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 
-	return irq_set_irq_wake(pmic_arb->irq, on);
+	return irq_set_irq_wake(bus->irq, on);
 }
 
 static int qpnpint_get_irqchip_state(struct irq_data *d,
@@ -826,17 +854,18 @@ static int qpnpint_get_irqchip_state(struct irq_data *d,
 static int qpnpint_irq_domain_activate(struct irq_domain *domain,
 				       struct irq_data *d, bool reserve)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 periph = hwirq_to_per(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u16 sid = hwirq_to_sid(d->hwirq);
 	u16 irq = hwirq_to_irq(d->hwirq);
 	u8 buf;
 
-	if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
+	if (bus->apid_data[apid].irq_ee != pmic_arb->ee) {
+		dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
 			sid, periph, irq, pmic_arb->ee,
-			pmic_arb->apid_data[apid].irq_ee);
+			bus->apid_data[apid].irq_ee);
 		return -ENODEV;
 	}
 
@@ -863,15 +892,16 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 					unsigned long *out_hwirq,
 					unsigned int *out_type)
 {
-	struct spmi_pmic_arb *pmic_arb = d->host_data;
+	struct spmi_pmic_arb_bus *bus = d->host_data;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 *intspec = fwspec->param;
 	u16 apid, ppid;
 	int rc;
 
-	dev_dbg(&pmic_arb->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
+	dev_dbg(&bus->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
 		intspec[0], intspec[1], intspec[2]);
 
-	if (irq_domain_get_of_node(d) != pmic_arb->spmic->dev.of_node)
+	if (irq_domain_get_of_node(d) != bus->spmic->dev.of_node)
 		return -EINVAL;
 	if (fwspec->param_count != 4)
 		return -EINVAL;
@@ -879,37 +909,38 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 		return -EINVAL;
 
 	ppid = intspec[0] << 8 | intspec[1];
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
 	if (rc < 0) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
-		intspec[0], intspec[1], intspec[2], rc);
+		dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
+			intspec[0], intspec[1], intspec[2], rc);
 		return rc;
 	}
 
 	apid = rc;
 	/* Keep track of {max,min}_apid for bounding search during interrupt */
-	if (apid > pmic_arb->max_apid)
-		pmic_arb->max_apid = apid;
-	if (apid < pmic_arb->min_apid)
-		pmic_arb->min_apid = apid;
+	if (apid > bus->max_apid)
+		bus->max_apid = apid;
+	if (apid < bus->min_apid)
+		bus->min_apid = apid;
 
 	*out_hwirq = spec_to_hwirq(intspec[0], intspec[1], intspec[2], apid);
 	*out_type  = intspec[3] & IRQ_TYPE_SENSE_MASK;
 
-	dev_dbg(&pmic_arb->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
+	dev_dbg(&bus->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
 
 	return 0;
 }
 
 static struct lock_class_key qpnpint_irq_lock_class, qpnpint_irq_request_class;
 
-static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb,
+static void qpnpint_irq_domain_map(struct spmi_pmic_arb_bus *bus,
 				   struct irq_domain *domain, unsigned int virq,
 				   irq_hw_number_t hwirq, unsigned int type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	irq_flow_handler_t handler;
 
-	dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
+	dev_dbg(&bus->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
 		virq, hwirq, type);
 
 	if (type & IRQ_TYPE_EDGE_BOTH)
@@ -928,7 +959,7 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 				    unsigned int virq, unsigned int nr_irqs,
 				    void *data)
 {
-	struct spmi_pmic_arb *pmic_arb = domain->host_data;
+	struct spmi_pmic_arb_bus *bus = domain->host_data;
 	struct irq_fwspec *fwspec = data;
 	irq_hw_number_t hwirq;
 	unsigned int type;
@@ -939,20 +970,22 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 		return ret;
 
 	for (i = 0; i < nr_irqs; i++)
-		qpnpint_irq_domain_map(pmic_arb, domain, virq + i, hwirq + i,
+		qpnpint_irq_domain_map(bus, domain, virq + i, hwirq + i,
 				       type);
 
 	return 0;
 }
 
-static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb_bus *bus)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+
 	/*
 	 * Initialize max_apid/min_apid to the opposite bounds, during
 	 * the irq domain translation, we are sure to update these
 	 */
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
+	bus->max_apid = 0;
+	bus->min_apid = pmic_arb->max_periphs - 1;
 
 	return 0;
 }
@@ -970,43 +1003,44 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
 	return 0;
 }
 
-static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 *mapping_table;
 
 	if (index) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
 			index);
 		return -EINVAL;
 	}
 
-	mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs,
+	mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs,
 				     sizeof(*mapping_table), GFP_KERNEL);
 	if (!mapping_table)
 		return -ENOMEM;
 
-	pmic_arb->mapping_table = mapping_table;
+	bus->mapping_table = mapping_table;
 
-	return pmic_arb_init_apid_min_max(pmic_arb);
+	return pmic_arb_init_apid_min_max(bus);
 }
 
-static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	u32 *mapping_table = pmic_arb->mapping_table;
+	u32 *mapping_table = bus->mapping_table;
 	int index = 0, i;
 	u16 apid_valid;
 	u16 apid;
 	u32 data;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = bus->ppid_to_apid[ppid];
 	if (apid_valid & PMIC_ARB_APID_VALID) {
 		apid = apid_valid & ~PMIC_ARB_APID_VALID;
 		return apid;
 	}
 
 	for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
-		if (!test_and_set_bit(index, pmic_arb->mapping_table_valid))
-			mapping_table[index] = readl_relaxed(pmic_arb->cnfg +
+		if (!test_and_set_bit(index, bus->mapping_table_valid))
+			mapping_table[index] = readl_relaxed(bus->cnfg +
 						SPMI_MAPPING_TABLE_REG(index));
 
 		data = mapping_table[index];
@@ -1016,9 +1050,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				bus->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				bus->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		} else {
@@ -1026,9 +1060,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				bus->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				bus->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		}
@@ -1038,24 +1072,26 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 }
 
 /* v1 offset per ee */
-static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v1(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return 0x800 + 0x80 * pmic_arb->channel;
 }
 
-static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static u16 pmic_arb_find_apid(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid];
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	struct apid_data *apidd = &bus->apid_data[bus->last_apid];
 	u32 regval, offset;
 	u16 id, apid;
 
-	for (apid = pmic_arb->last_apid; ; apid++, apidd++) {
+	for (apid = bus->last_apid; ; apid++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(apid);
 		if (offset >= pmic_arb->core_size)
 			break;
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus,
 								     apid));
 		apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 		apidd->write_ee = apidd->irq_ee;
@@ -1065,14 +1101,14 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 			continue;
 
 		id = (regval >> 8) & PMIC_ARB_PPID_MASK;
-		pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
+		bus->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
 		apidd->ppid = id;
 		if (id == ppid) {
 			apid |= PMIC_ARB_APID_VALID;
 			break;
 		}
 	}
-	pmic_arb->last_apid = apid & ~PMIC_ARB_APID_VALID;
+	bus->last_apid = apid & ~PMIC_ARB_APID_VALID;
 
 	return apid;
 }
@@ -1106,21 +1142,22 @@ static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
 	return pmic_arb_get_obsrvr_chnls_v2(pdev);
 }
 
-static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
 	u16 apid_valid;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = bus->ppid_to_apid[ppid];
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
-		apid_valid = pmic_arb_find_apid(pmic_arb, ppid);
+		apid_valid = pmic_arb_find_apid(bus, ppid);
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
 	return apid_valid & ~PMIC_ARB_APID_VALID;
 }
 
-static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	struct apid_data *apidd;
 	struct apid_data *prev_apidd;
 	u16 i, apid, ppid, apid_max;
@@ -1142,9 +1179,9 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 	 * where N = number of APIDs supported by the primary bus and
 	 *       M = number of APIDs supported by the secondary bus
 	 */
-	apidd = &pmic_arb->apid_data[pmic_arb->base_apid];
-	apid_max = pmic_arb->base_apid + pmic_arb->apid_count;
-	for (i = pmic_arb->base_apid; i < apid_max; i++, apidd++) {
+	apidd = &bus->apid_data[bus->base_apid];
+	apid_max = bus->base_apid + bus->apid_count;
+	for (i = bus->base_apid; i < apid_max; i++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(i);
 		if (offset >= pmic_arb->core_size)
 			break;
@@ -1155,19 +1192,18 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		ppid = (regval >> 8) & PMIC_ARB_PPID_MASK;
 		is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval);
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
-								     i));
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i));
 		apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 
 		apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE;
 
-		valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
-		apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
-		prev_apidd = &pmic_arb->apid_data[apid];
+		valid = bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
+		apid = bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+		prev_apidd = &bus->apid_data[apid];
 
 		if (!valid || apidd->write_ee == pmic_arb->ee) {
 			/* First PPID mapping or one for this EE */
-			pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+			bus->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
 		} else if (valid && is_irq_ee &&
 			   prev_apidd->write_ee == pmic_arb->ee) {
 			/*
@@ -1178,42 +1214,43 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		}
 
 		apidd->ppid = ppid;
-		pmic_arb->last_apid = i;
+		bus->last_apid = i;
 	}
 
 	/* Dump the mapping table for debug purposes. */
-	dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
+	dev_dbg(&bus->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
 	for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) {
-		apid = pmic_arb->ppid_to_apid[ppid];
+		apid = bus->ppid_to_apid[ppid];
 		if (apid & PMIC_ARB_APID_VALID) {
 			apid &= ~PMIC_ARB_APID_VALID;
-			apidd = &pmic_arb->apid_data[apid];
-			dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n",
-			      ppid, apid, apidd->write_ee, apidd->irq_ee);
+			apidd = &bus->apid_data[apid];
+			dev_dbg(&bus->spmic->dev, "%#03X %3u %2u %2u\n",
+				ppid, apid, apidd->write_ee, apidd->irq_ee);
 		}
 	}
 
 	return 0;
 }
 
-static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
+	if (!(bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
-	return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+	return bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
 }
 
 /* v2 offset per ppid and per ee */
-static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	u16 ppid;
 	int rc;
 
 	ppid = sid << 8 | ((addr >> 8) & 0xFF);
-	rc = pmic_arb_ppid_to_apid_v2(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v2(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1221,33 +1258,34 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0x1000 * pmic_arb->ee + 0x8000 * apid;
 }
 
-static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	int ret;
 
 	if (index) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
 			index);
 		return -EINVAL;
 	}
 
-	pmic_arb->base_apid = 0;
-	pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+	bus->base_apid = 0;
+	bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 					   PMIC_ARB_FEATURES_PERIPH_MASK;
 
-	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
-			pmic_arb->base_apid + pmic_arb->apid_count);
+	if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+		dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+			bus->base_apid + bus->apid_count);
 		return -EINVAL;
 	}
 
-	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	ret = pmic_arb_init_apid_min_max(bus);
 	if (ret)
 		return ret;
 
-	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	ret = pmic_arb_read_apid_map_v5(bus);
 	if (ret) {
-		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+		dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
 			ret);
 		return ret;
 	}
@@ -1259,15 +1297,16 @@ static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
  * v5 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v5(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v5(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1277,8 +1316,8 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
-			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+		if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+			dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
 		}
@@ -1305,38 +1344,39 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
  * Only v7 supports 2 buses. Each bus will get a different apid count, read
  * from different registers.
  */
-static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	int ret;
 
 	if (index == 0) {
-		pmic_arb->base_apid = 0;
-		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+		bus->base_apid = 0;
+		bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 						   PMIC_ARB_FEATURES_PERIPH_MASK;
 	} else if (index == 1) {
-		pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+		bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 						  PMIC_ARB_FEATURES_PERIPH_MASK;
-		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+		bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
 						   PMIC_ARB_FEATURES_PERIPH_MASK;
 	} else {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
-			index);
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
+			bus->id);
 		return -EINVAL;
 	}
 
-	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
-			pmic_arb->base_apid + pmic_arb->apid_count);
+	if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+		dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+			bus->base_apid + bus->apid_count);
 		return -EINVAL;
 	}
 
-	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	ret = pmic_arb_init_apid_min_max(bus);
 	if (ret)
 		return ret;
 
-	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	ret = pmic_arb_read_apid_map_v5(bus);
 	if (ret) {
-		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+		dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
 			ret);
 		return ret;
 	}
@@ -1348,15 +1388,16 @@ static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
  * v7 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v7(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1366,8 +1407,8 @@ static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x8000 * pmic_arb->ee + 0x20 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
-			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+		if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+			dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
 		}
@@ -1389,104 +1430,110 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x20 * m + 0x4 * n;
+	return bus->intr + 0x20 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x100000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x200000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x10000 * m + 0x4 * n;
+	return bus->intr + 0x10000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x200 + 0x4 * n;
+	return bus->intr + 0x200 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * n;
+	return bus->intr + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x600 + 0x4 * n;
+	return bus->intr + 0x600 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x4 + 0x1000 * n;
+	return bus->intr + 0x4 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0xA00 + 0x4 * n;
+	return bus->intr + 0xA00 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x8 + 0x1000 * n;
+	return bus->intr + 0x8 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x1000 * n;
 }
 
@@ -1506,9 +1553,9 @@ static u32 pmic_arb_apid_map_offset_v7(u16 n)
 }
 
 static void __iomem *
-pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->cnfg + 0x700 + 0x4 * n;
+	return bus->cnfg + 0x700 + 0x4 * n;
 }
 
 /*
@@ -1517,9 +1564,9 @@ pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
  * 0.
  */
 static void __iomem *
-pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->cnfg + 0x4 * (n - pmic_arb->base_apid);
+	return  bus->cnfg + 0x4 * (n - bus->base_apid);
 }
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
@@ -1609,29 +1656,160 @@ static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
 	.translate = qpnpint_irq_domain_translate,
 };
 
+static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
+				  struct device_node *node,
+				  struct spmi_pmic_arb *pmic_arb)
+{
+	int bus_index = pmic_arb->buses_available;
+	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[bus_index];
+	struct device *dev = &pdev->dev;
+	struct spmi_controller *ctrl;
+	void __iomem *intr;
+	void __iomem *cnfg;
+	int index, ret;
+	u32 irq;
+
+	ctrl = devm_spmi_controller_alloc(dev, sizeof(*ctrl));
+	if (IS_ERR(ctrl))
+		return PTR_ERR(ctrl);
+
+	ctrl->cmd = pmic_arb_cmd;
+	ctrl->read_cmd = pmic_arb_read_cmd;
+	ctrl->write_cmd = pmic_arb_write_cmd;
+
+	bus = spmi_controller_get_drvdata(ctrl);
+	bus->spmic = ctrl;
+
+	bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID,
+					 sizeof(*bus->ppid_to_apid),
+					 GFP_KERNEL);
+	if (!bus->ppid_to_apid)
+		return -ENOMEM;
+
+	bus->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs,
+				      sizeof(*bus->apid_data),
+				      GFP_KERNEL);
+	if (!bus->apid_data)
+		return -ENOMEM;
+
+	index = of_property_match_string(node, "reg-names", "cnfg");
+	if (index < 0) {
+		dev_err(dev, "cnfg reg region missing");
+		return -EINVAL;
+	}
+
+	cnfg = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(cnfg))
+		return PTR_ERR(cnfg);
+
+	index = of_property_match_string(node, "reg-names", "intr");
+	if (index < 0) {
+		dev_err(dev, "intr reg region missing");
+		return -EINVAL;
+	}
+
+	intr = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(intr))
+		return PTR_ERR(intr);
+
+	irq = of_irq_get_byname(node, "periph_irq");
+	if (irq < 0)
+		return irq;
+
+	bus->pmic_arb = pmic_arb;
+	bus->intr = intr;
+	bus->cnfg = cnfg;
+	bus->irq = irq;
+	bus->id = bus_index;
+
+	ret = pmic_arb->ver_ops->init_apid(bus, bus_index);
+	if (ret)
+		return ret;
+
+	dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index);
+
+	bus->domain = irq_domain_add_tree(dev->of_node,
+					  &pmic_arb_irq_domain_ops, bus);
+	if (!bus->domain) {
+		dev_err(&pdev->dev, "unable to create irq_domain\n");
+		return -ENOMEM;
+	}
+
+	irq_set_chained_handler_and_data(bus->irq,
+					 pmic_arb_chained_irq, bus);
+
+	bus->spmic->dev.of_node = node;
+	dev_set_name(&bus->spmic->dev, "spmi-%d", bus_index);
+
+	ret = devm_spmi_controller_add(dev, bus->spmic);
+	if (ret)
+		return ret;
+
+	pmic_arb->buses_available++;
+
+	return 0;
+}
+
+static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb,
+					struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct device_node *child;
+	int ret;
+
+	/* legacy mode doesn't provide child node for the bus */
+	if (of_device_is_compatible(node, "qcom,spmi-pmic-arb-v7")) {
+		for_each_available_child_of_node(node, child) {
+			if (of_node_name_eq(child, "spmi")) {
+				ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb);
+				if (ret)
+					return ret;
+			}
+		}
+	} else {
+		ret = spmi_pmic_arb_bus_init(pdev, node, pmic_arb);
+	}
+
+	return ret;
+}
+
+static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb)
+{
+	int i;
+
+	for (i = 0; i < PMIC_ARB_MAX_BUSES; i++) {
+		struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[i];
+
+		irq_set_chained_handler_and_data(bus->irq,
+						 NULL, NULL);
+		irq_domain_remove(bus->domain);
+	}
+}
+
 static int spmi_pmic_arb_probe(struct platform_device *pdev)
 {
 	struct spmi_pmic_arb *pmic_arb;
-	struct spmi_controller *ctrl;
+	struct device *dev = &pdev->dev;
 	struct resource *res;
 	void __iomem *core;
 	u32 channel, ee, hw_ver;
 	int err;
 
-	ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*pmic_arb));
-	if (IS_ERR(ctrl))
-		return PTR_ERR(ctrl);
-
-	pmic_arb = spmi_controller_get_drvdata(ctrl);
-	pmic_arb->spmic = ctrl;
+	pmic_arb = devm_kzalloc(dev, sizeof(*pmic_arb), GFP_KERNEL);
+	if (!pmic_arb)
+		return -ENOMEM;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
-	core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
+	core = devm_ioremap(dev, res->start, resource_size(res));
 	if (IS_ERR(core))
 		return PTR_ERR(core);
 
 	pmic_arb->core_size = resource_size(res);
 
+	platform_set_drvdata(pdev, pmic_arb);
+	raw_spin_lock_init(&pmic_arb->lock);
+
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
 	if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
@@ -1645,30 +1823,12 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	else
 		pmic_arb->ver_ops = &pmic_arb_v7;
 
-	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
-		 pmic_arb->ver_ops->ver_str, hw_ver);
-
 	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
 	if (err)
 		return err;
 
-	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
-	if (err)
-		return err;
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
-	pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->intr))
-		return PTR_ERR(pmic_arb->intr);
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
-	pmic_arb->cnfg = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->cnfg))
-		return PTR_ERR(pmic_arb->cnfg);
-
-	pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq");
-	if (pmic_arb->irq < 0)
-		return pmic_arb->irq;
+	dev_info(dev, "PMIC arbiter version %s (0x%x)\n",
+		 pmic_arb->ver_ops->ver_str, hw_ver);
 
 	err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
 	if (err) {
@@ -1697,46 +1857,19 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	pmic_arb->ee = ee;
 
-	platform_set_drvdata(pdev, ctrl);
-	raw_spin_lock_init(&pmic_arb->lock);
-
-	ctrl->cmd = pmic_arb_cmd;
-	ctrl->read_cmd = pmic_arb_read_cmd;
-	ctrl->write_cmd = pmic_arb_write_cmd;
-
-	dev_dbg(&pdev->dev, "adding irq domain\n");
-	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
-					 &pmic_arb_irq_domain_ops, pmic_arb);
-	if (!pmic_arb->domain) {
-		dev_err(&pdev->dev, "unable to create irq_domain\n");
-		return -ENOMEM;
-	}
-
-	irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq,
-					pmic_arb);
-	err = spmi_controller_add(ctrl);
-	if (err)
-		goto err_domain_remove;
-
-	return 0;
-
-err_domain_remove:
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
-	return err;
+	return spmi_pmic_arb_register_buses(pmic_arb, pdev);
 }
 
 static void spmi_pmic_arb_remove(struct platform_device *pdev)
 {
-	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
-	spmi_controller_remove(ctrl);
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	spmi_pmic_arb_deregister_buses(pmic_arb);
 }
 
 static const struct of_device_id spmi_pmic_arb_match_table[] = {
 	{ .compatible = "qcom,spmi-pmic-arb", },
+	{ .compatible = "qcom,spmi-pmic-arb-v7", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);

-- 
2.34.1



From apatel at ventanamicro.com  Tue Feb 20 05:00:34 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 18:30:34 +0530
Subject: [PATCH v13 06/13] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <87frxnfj3p.fsf@all.your.base.are.belong.to.us>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-7-apatel@ventanamicro.com> <87frxnfj3p.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAK9=C2Xnzg3KAVETXN+ZGLWhVtaJuU4uXs3WH2ZondkBJMHFcA@mail.gmail.com>

On Tue, Feb 20, 2024 at 5:22?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Anup,
>
> This version is so much easier to follow! Thanks a lot for then
> cleanups/design changes.
>
> A bunch of nits, and a major one, below.

Sure, I will address the nits in the next revision.

>
> Anup Patel <apatel at ventanamicro.com> writes:
>
> > The RISC-V advanced interrupt architecture (AIA) specification
> > defines a new MSI controller called incoming message signalled
> > interrupt controller (IMSIC) which manages MSI on per-HART (or
> > per-CPU) basis. It also supports IPIs as software injected MSIs.
> > (For more details refer https://github.com/riscv/riscv-aia)
> >
> > Let us add an early irqchip driver for RISC-V IMSIC which sets
> > up the IMSIC state and provide IPIs.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  drivers/irqchip/Kconfig                 |   7 +
> >  drivers/irqchip/Makefile                |   1 +
> >  drivers/irqchip/irq-riscv-imsic-early.c | 213 ++++++
> >  drivers/irqchip/irq-riscv-imsic-state.c | 906 ++++++++++++++++++++++++
> >  drivers/irqchip/irq-riscv-imsic-state.h |  98 +++
> >  include/linux/irqchip/riscv-imsic.h     |  87 +++
> >  6 files changed, 1312 insertions(+)
> >  create mode 100644 drivers/irqchip/irq-riscv-imsic-early.c
> >  create mode 100644 drivers/irqchip/irq-riscv-imsic-state.c
> >  create mode 100644 drivers/irqchip/irq-riscv-imsic-state.h
> >  create mode 100644 include/linux/irqchip/riscv-imsic.h
> >
> > diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> > index f7149d0f3d45..85f86e31c996 100644
> > --- a/drivers/irqchip/Kconfig
> > +++ b/drivers/irqchip/Kconfig
> > @@ -546,6 +546,13 @@ config SIFIVE_PLIC
> >       select IRQ_DOMAIN_HIERARCHY
> >       select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
> >
> > +config RISCV_IMSIC
> > +     bool
> > +     depends on RISCV
> > +     select IRQ_DOMAIN_HIERARCHY
> > +     select GENERIC_IRQ_MATRIX_ALLOCATOR
> > +     select GENERIC_MSI_IRQ
> > +
> >  config EXYNOS_IRQ_COMBINER
> >       bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
> >       depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> > index ffd945fe71aa..d714724387ce 100644
> > --- a/drivers/irqchip/Makefile
> > +++ b/drivers/irqchip/Makefile
> > @@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)                      += irq-qcom-mpm.o
> >  obj-$(CONFIG_CSKY_MPINTC)            += irq-csky-mpintc.o
> >  obj-$(CONFIG_CSKY_APB_INTC)          += irq-csky-apb-intc.o
> >  obj-$(CONFIG_RISCV_INTC)             += irq-riscv-intc.o
> > +obj-$(CONFIG_RISCV_IMSIC)            += irq-riscv-imsic-state.o irq-riscv-imsic-early.o
> >  obj-$(CONFIG_SIFIVE_PLIC)            += irq-sifive-plic.o
> >  obj-$(CONFIG_IMX_IRQSTEER)           += irq-imx-irqsteer.o
> >  obj-$(CONFIG_IMX_INTMUX)             += irq-imx-intmux.o
> > diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
> > new file mode 100644
> > index 000000000000..32fe428b1c19
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-imsic-early.c
> > @@ -0,0 +1,213 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
> > + */
> > +
> > +#define pr_fmt(fmt) "riscv-imsic: " fmt
> > +#include <linux/cpu.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/irq.h>
> > +#include <linux/irqchip.h>
> > +#include <linux/irqchip/chained_irq.h>
> > +#include <linux/module.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/smp.h>
> > +
> > +#include "irq-riscv-imsic-state.h"
> > +
> > +static int imsic_parent_irq;
> > +
> > +#ifdef CONFIG_SMP
> > +static void imsic_ipi_send(unsigned int cpu)
> > +{
> > +     struct imsic_local_config *local = per_cpu_ptr(imsic->global.local, cpu);
> > +
> > +     writel_relaxed(IMSIC_IPI_ID, local->msi_va);
> > +}
> > +
> > +static void imsic_ipi_starting_cpu(void)
> > +{
> > +     /* Enable IPIs for current CPU. */
> > +     __imsic_id_set_enable(IMSIC_IPI_ID);
> > +}
> > +
> > +static void imsic_ipi_dying_cpu(void)
> > +{
> > +     /* Disable IPIs for current CPU. */
> > +     __imsic_id_clear_enable(IMSIC_IPI_ID);
> > +}
> > +
> > +static int __init imsic_ipi_domain_init(void)
> > +{
> > +     int virq;
> > +
> > +     /* Create IMSIC IPI multiplexing */
> > +     virq = ipi_mux_create(IMSIC_NR_IPI, imsic_ipi_send);
> > +     if (virq <= 0)
> > +             return (virq < 0) ? virq : -ENOMEM;
>
> Nit: No parenthesis need to clutter.
>
> > +
> > +     /* Set vIRQ range */
> > +     riscv_ipi_set_virq_range(virq, IMSIC_NR_IPI, true);
> > +
> > +     /* Announce that IMSIC is providing IPIs */
> > +     pr_info("%pfwP: providing IPIs using interrupt %d\n", imsic->fwnode, IMSIC_IPI_ID);
> > +
> > +     return 0;
> > +}
> > +#else
> > +static void imsic_ipi_starting_cpu(void)
> > +{
> > +}
> > +
> > +static void imsic_ipi_dying_cpu(void)
> > +{
> > +}
> > +
> > +static int __init imsic_ipi_domain_init(void)
> > +{
> > +     return 0;
> > +}
> > +#endif
> > +
> > +/*
> > + * To handle an interrupt, we read the TOPEI CSR and write zero in one
> > + * instruction. If TOPEI CSR is non-zero then we translate TOPEI.ID to
> > + * Linux interrupt number and let Linux IRQ subsystem handle it.
> > + */
> > +static void imsic_handle_irq(struct irq_desc *desc)
> > +{
> > +     struct irq_chip *chip = irq_desc_get_chip(desc);
> > +     int err, cpu = smp_processor_id();
> > +     struct imsic_vector *vec;
> > +     unsigned long local_id;
> > +
> > +     chained_irq_enter(chip, desc);
> > +
> > +     while ((local_id = csr_swap(CSR_TOPEI, 0))) {
> > +             local_id = local_id >> TOPEI_ID_SHIFT;
>
> Nit: Wdyt about moving shift into the loop predicate, or using >>=?
>
> > +
> > +             if (local_id == IMSIC_IPI_ID) {
> > +#ifdef CONFIG_SMP
> > +                     ipi_mux_process();
> > +#endif
>
> Is IMSIC_IPI_ID a thing on !IS_ENABLED(CONFIG_SMP)?
>
> > +                     continue;
> > +             }
> > +
> > +             if (unlikely(!imsic->base_domain))
> > +                     continue;
> > +
> > +             vec = imsic_vector_from_local_id(cpu, local_id);
> > +             if (!vec) {
> > +                     pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id);
> > +                     continue;
> > +             }
> > +
> > +             err = generic_handle_domain_irq(imsic->base_domain,
> > +                                             vec->hwirq);
>
> Nit: 100 chars
>
> > +             if (unlikely(err))
> > +                     pr_warn_ratelimited("hwirq 0x%x mapping not found\n", vec->hwirq);
> > +     }
> > +
> > +     chained_irq_exit(chip, desc);
> > +}
> > +
> > +static int imsic_starting_cpu(unsigned int cpu)
> > +{
> > +     /* Mark per-CPU IMSIC state as online */
> > +     imsic_state_online();
> > +
> > +     /* Enable per-CPU parent interrupt */
> > +     enable_percpu_irq(imsic_parent_irq, irq_get_trigger_type(imsic_parent_irq));
> > +
> > +     /* Setup IPIs */
> > +     imsic_ipi_starting_cpu();
> > +
> > +     /*
> > +      * Interrupts identities might have been enabled/disabled while
> > +      * this CPU was not running so sync-up local enable/disable state.
> > +      */
> > +     imsic_local_sync_all();
> > +
> > +     /* Enable local interrupt delivery */
> > +     imsic_local_delivery(true);
> > +
> > +     return 0;
> > +}
> > +
> > +static int imsic_dying_cpu(unsigned int cpu)
> > +{
> > +     /* Cleanup IPIs */
> > +     imsic_ipi_dying_cpu();
> > +
> > +     /* Mark per-CPU IMSIC state as offline */
> > +     imsic_state_offline();
> > +
> > +     return 0;
> > +}
> > +
> > +static int __init imsic_early_probe(struct fwnode_handle *fwnode)
> > +{
> > +     struct irq_domain *domain;
> > +     int rc;
> > +
> > +     /* Find parent domain and register chained handler */
> > +     domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS_ANY);
> > +     if (!domain) {
> > +             pr_err("%pfwP: Failed to find INTC domain\n", fwnode);
> > +             return -ENOENT;
> > +     }
> > +     imsic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
> > +     if (!imsic_parent_irq) {
> > +             pr_err("%pfwP: Failed to create INTC mapping\n", fwnode);
> > +             return -ENOENT;
> > +     }
> > +
> > +     /* Initialize IPI domain */
> > +     rc = imsic_ipi_domain_init();
> > +     if (rc) {
> > +             pr_err("%pfwP: Failed to initialize IPI domain\n", fwnode);
> > +             return rc;
> > +     }
> > +
> > +     /* Setup chained handler to the parent domain interrupt */
> > +     irq_set_chained_handler(imsic_parent_irq, imsic_handle_irq);
> > +
> > +     /*
> > +      * Setup cpuhp state (must be done after setting imsic_parent_irq)
> > +      *
> > +      * Don't disable per-CPU IMSIC file when CPU goes offline
> > +      * because this affects IPI and the masking/unmasking of
> > +      * virtual IPIs is done via generic IPI-Mux
> > +      */
> > +     cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "irqchip/riscv/imsic:starting",
> > +                       imsic_starting_cpu, imsic_dying_cpu);
> > +
> > +     return 0;
> > +}
> > +
> > +static int __init imsic_early_dt_init(struct device_node *node,
> > +                                   struct device_node *parent)
> > +{
> > +     struct fwnode_handle *fwnode = &node->fwnode;
> > +     int rc;
> > +
> > +     /* Setup IMSIC state */
> > +     rc = imsic_setup_state(fwnode);
> > +     if (rc) {
> > +             pr_err("%pfwP: failed to setup state (error %d)\n",
> > +                     fwnode, rc);
>
> Nit. 100 chars
>
> > +             return rc;
> > +     }
> > +
> > +     /* Do early setup of IPIs */
> > +     rc = imsic_early_probe(fwnode);
> > +     if (rc)
> > +             return rc;
> > +
> > +     /* Ensure that OF platform device gets probed */
> > +     of_node_clear_flag(node, OF_POPULATED);
> > +     return 0;
> > +}
> > +IRQCHIP_DECLARE(riscv_imsic, "riscv,imsics", imsic_early_dt_init);
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > new file mode 100644
> > index 000000000000..4f347486ec7c
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -0,0 +1,906 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
> > + */
> > +
> > +#define pr_fmt(fmt) "riscv-imsic: " fmt
> > +#include <linux/cpu.h>
> > +#include <linux/bitmap.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/irq.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/seq_file.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/smp.h>
> > +#include <asm/hwcap.h>
> > +
> > +#include "irq-riscv-imsic-state.h"
> > +
> > +#define IMSIC_DISABLE_EIDELIVERY             0
> > +#define IMSIC_ENABLE_EIDELIVERY                      1
> > +#define IMSIC_DISABLE_EITHRESHOLD            1
> > +#define IMSIC_ENABLE_EITHRESHOLD             0
> > +
> > +static inline void imsic_csr_write(unsigned long reg, unsigned long val)
> > +{
> > +     csr_write(CSR_ISELECT, reg);
> > +     csr_write(CSR_IREG, val);
> > +}
> > +
> > +static inline unsigned long imsic_csr_read(unsigned long reg)
> > +{
> > +     csr_write(CSR_ISELECT, reg);
> > +     return csr_read(CSR_IREG);
> > +}
> > +
> > +static inline unsigned long imsic_csr_read_clear(unsigned long reg, unsigned long val)
> > +{
> > +     csr_write(CSR_ISELECT, reg);
> > +     return csr_read_clear(CSR_IREG, val);
> > +}
> > +
> > +static inline void imsic_csr_set(unsigned long reg, unsigned long val)
> > +{
> > +     csr_write(CSR_ISELECT, reg);
> > +     csr_set(CSR_IREG, val);
> > +}
> > +
> > +static inline void imsic_csr_clear(unsigned long reg, unsigned long val)
> > +{
> > +     csr_write(CSR_ISELECT, reg);
> > +     csr_clear(CSR_IREG, val);
> > +}
> > +
> > +struct imsic_priv *imsic;
> > +
> > +const struct imsic_global_config *imsic_get_global_config(void)
> > +{
> > +     return imsic ? &imsic->global : NULL;
> > +}
> > +EXPORT_SYMBOL_GPL(imsic_get_global_config);
> > +
> > +static bool __imsic_eix_read_clear(unsigned long id, bool pend)
> > +{
> > +     unsigned long isel, imask;
> > +
> > +     isel = id / BITS_PER_LONG;
> > +     isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
> > +     isel += pend ? IMSIC_EIP0 : IMSIC_EIE0;
> > +     imask = BIT(id & (__riscv_xlen - 1));
> > +
> > +     return (imsic_csr_read_clear(isel, imask) & imask) ? true : false;
>
> Nit: use return !!(imsic_csr_read_clear(isel, imask) & imask)
>
> > +}
> > +
> > +static inline bool __imsic_id_read_clear_enabled(unsigned long id)
> > +{
> > +     return __imsic_eix_read_clear(id, false);
> > +}
> > +
> > +static inline bool __imsic_id_read_clear_pending(unsigned long id)
> > +{
> > +     return __imsic_eix_read_clear(id, true);
> > +}
> > +
> > +void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val)
> > +{
> > +     unsigned long id = base_id, last_id = base_id + num_id;
> > +     unsigned long i, isel, ireg;
> > +
> > +     while (id < last_id) {
> > +             isel = id / BITS_PER_LONG;
> > +             isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
> > +             isel += (pend) ? IMSIC_EIP0 : IMSIC_EIE0;
>
> Nit: Redundant parenthesis.
>
> > +
> > +             /*
> > +              * Prepare the ID mask to be programmed in the
> > +              * IMSIC EIEx and EIPx registers. These registers
> > +              * are XLEN-wide and we must not touch IDs which
> > +              * are < base_id and >= (base_id + num_id).
> > +              */
> > +             ireg = 0;
> > +             for (i = id & (__riscv_xlen - 1); (id < last_id) && (i < __riscv_xlen); i++) {
>
> Nit: Redundant parenthesis "(id < last_id) && (i < __riscv_xlen)", which
> is also inconsistent with other usage in this changeset.
>
> > +                     ireg |= BIT(i);
> > +                     id++;
> > +             }
> > +
> > +             /*
> > +              * The IMSIC EIEx and EIPx registers are indirectly
> > +              * accessed via using ISELECT and IREG CSRs so we
> > +              * need to access these CSRs without getting preempted.
> > +              *
> > +              * All existing users of this function call this
> > +              * function with local IRQs disabled so we don't
> > +              * need to do anything special here.
> > +              */
> > +             if (val)
> > +                     imsic_csr_set(isel, ireg);
> > +             else
> > +                     imsic_csr_clear(isel, ireg);
> > +     }
> > +}
> > +
> > +/* MUST be called with lpriv->lock held */
> > +static void __imsic_local_sync(struct imsic_local_priv *lpriv)
> > +{
> > +     struct imsic_local_config *mlocal;
> > +     struct imsic_vector *vec, *mvec;
> > +     int i;
> > +
> > +     /* This pairs with the barrier in __imsic_remote_sync(). */
> > +     smp_mb();
> > +
> > +     for_each_set_bit(i, lpriv->dirty_bitmap, imsic->global.nr_ids + 1) {
> > +             if (!i || i == IMSIC_IPI_ID)
> > +                     goto skip;
> > +             vec = &lpriv->vectors[i];
> > +
> > +             if (vec->enable)
> > +                     __imsic_id_set_enable(i);
> > +             else
> > +                     __imsic_id_clear_enable(i);
> > +
> > +             /*
> > +              * If the ID was being moved to a new ID on some other CPU
> > +              * then we can get a MSI during the movement so check the
> > +              * ID pending bit and re-trigger the new ID on other CPU
> > +              * using MMIO write.
> > +              */
> > +             mvec = vec->move;
> > +             vec->move = NULL;
> > +             if (mvec && mvec != vec) {
> > +                     if (__imsic_id_read_clear_pending(i)) {
> > +                             mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
> > +                             writel_relaxed(mvec->local_id, mlocal->msi_va);
> > +                     }
> > +
> > +                     imsic_vector_free(&lpriv->vectors[i]);
> > +             }
> > +
> > +skip:
> > +             bitmap_clear(lpriv->dirty_bitmap, i, 1);
> > +     }
> > +}
> > +
> > +void imsic_local_sync_all(void)
> > +{
> > +     struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +     bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
> > +     __imsic_local_sync(lpriv);
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> > +}
> > +
> > +void imsic_local_delivery(bool enable)
> > +{
> > +     if (enable) {
> > +             imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
> > +             imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
> > +             return;
> > +     }
> > +
> > +     imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
> > +     imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
> > +}
> > +
> > +#ifdef CONFIG_SMP
> > +static void imsic_local_timer_callback(struct timer_list *timer)
> > +{
> > +     struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +     __imsic_local_sync(lpriv);
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> > +}
> > +
> > +/* MUST be called with lpriv->lock held */
> > +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
> > +{
> > +     /*
> > +      * Ensure that changes to vector enable, vector move and
> > +      * dirty bitmap are visible to the target CPU.
> > +      *
> > +      * This pairs with the barrier in __imsic_local_sync().
> > +      */
> > +     smp_mb();
> > +
> > +     /*
> > +      * We schedule a timer on the target CPU if the target CPU is not
> > +      * same as the current CPU. An offline CPU will unconditionally
> > +      * synchronize IDs through imsic_starting_cpu() when the
> > +      * CPU is brought up.
> > +      */
> > +     if (cpu_online(cpu)) {
> > +             if (cpu != smp_processor_id()) {
> > +                     if (!timer_pending(&lpriv->timer)) {
> > +                             lpriv->timer.expires = jiffies + 1;
> > +                             add_timer_on(&lpriv->timer, cpu);
> > +                     }
> > +             } else {
> > +                     __imsic_local_sync(lpriv);
> > +             }
>
> Nit: Early exit/return vs else-clause for readability
>
>
> > +     }
> > +}
> > +#else
> > +/* MUST be called with lpriv->lock held */
> > +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
> > +{
> > +     __imsic_local_sync(lpriv);
> > +}
> > +#endif
> > +
> > +void imsic_vector_mask(struct imsic_vector *vec)
> > +{
> > +     struct imsic_local_priv *lpriv;
> > +
> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> > +     if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> > +             return;
> > +
> > +     /*
> > +      * This function is called through Linux irq subsystem with
> > +      * irqs disabled so no need to save/restore irq flags.
> > +      */
> > +
> > +     raw_spin_lock(&lpriv->lock);
> > +
> > +     vec->enable = false;
> > +     bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> > +     __imsic_remote_sync(lpriv, vec->cpu);
> > +
> > +     raw_spin_unlock(&lpriv->lock);
> > +}
>
> Really nice that you're using a timer for the vector affinity change,
> and got rid of the special/weird IMSIC/sync IPI. Can you really use a
> timer for mask/unmask? That makes the mask/unmask operation
> asynchronous!
>
> That was what I was trying to get though with this comment:
> https://lore.kernel.org/linux-riscv/87sf24mo1g.fsf at all.your.base.are.belong.to.us/
>
> Also, using the smp_* IPI functions, you can pass arguments, so you
> don't need the dirty_bitmap tracking the changes.

The mask/unmask operations are called with irqs disabled so if
CPU X does synchronous IPI to another CPU Y from mask/unmask
operation then while CPU X is waiting for IPI to complete it cannot
receive IPI from other CPUs which can lead to crashes and stalls.

In general, we should not do any block/busy-wait work in
mask/unmask operation of an irqchip driver.

The AIA IMSIC spec allows setting ID pending bit using MSI write
irrespective whether ID is enabled or not but the interrupt will be
taken only after ID is enabled. In other words, there will be no
loss of interrupt with delayed mask/unmask using async IPI or
lazy timer.

>
> > +
> > +void imsic_vector_unmask(struct imsic_vector *vec)
> > +{
> > +     struct imsic_local_priv *lpriv;
> > +
> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> > +     if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> > +             return;
> > +
> > +     /*
> > +      * This function is called through Linux irq subsystem with
> > +      * irqs disabled so no need to save/restore irq flags.
> > +      */
> > +
> > +     raw_spin_lock(&lpriv->lock);
> > +
> > +     vec->enable = true;
> > +     bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> > +     __imsic_remote_sync(lpriv, vec->cpu);
> > +
> > +     raw_spin_unlock(&lpriv->lock);
> > +}
> > +
> > +
> > +bool imsic_vector_isenabled(struct imsic_vector *vec)
> > +{
> > +     struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> > +     unsigned long flags;
> > +     bool ret;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +     ret = vec->enable;
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> > +
> > +     return ret;
> > +}
> > +
> > +struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec)
> > +{
> > +     struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> > +     struct imsic_vector *ret;
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +     ret = vec->move;
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> > +
> > +     return ret;
> > +}
> > +
> > +static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, struct imsic_vector *vec,
> > +                                  bool new_enable, struct imsic_vector *new_move)
> > +{
> > +     unsigned long flags;
> > +     bool enabled;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +
> > +     /* Update enable and move details */
> > +     enabled = vec->enable;
> > +     vec->enable = new_enable;
> > +     vec->move = new_move;
> > +
> > +     /* Mark the vector as dirty and synchronize */
> > +     bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> > +     __imsic_remote_sync(lpriv, vec->cpu);
> > +
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> > +
> > +     return enabled;
> > +}
> > +
> > +void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec)
> > +{
> > +     struct imsic_local_priv *old_lpriv, *new_lpriv;
> > +     bool enabled;
> > +
> > +     if (WARN_ON(old_vec->cpu == new_vec->cpu))
> > +             return;
> > +
> > +     old_lpriv = per_cpu_ptr(imsic->lpriv, old_vec->cpu);
> > +     if (WARN_ON(&old_lpriv->vectors[old_vec->local_id] != old_vec))
> > +             return;
> > +
> > +     new_lpriv = per_cpu_ptr(imsic->lpriv, new_vec->cpu);
> > +     if (WARN_ON(&new_lpriv->vectors[new_vec->local_id] != new_vec))
> > +             return;
> > +
> > +     /*
> > +      * Move and re-trigger the new vector based on the pending
> > +      * state of the old vector because we might get a device
> > +      * interrupt on the old vector while device was being moved
> > +      * to the new vector.
> > +      */
> > +     enabled = imsic_vector_move_update(old_lpriv, old_vec, false, new_vec);
> > +     imsic_vector_move_update(new_lpriv, new_vec, enabled, new_vec);
> > +}
> > +
> > +#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
> > +void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind)
> > +{
> > +     struct imsic_local_priv *lpriv;
> > +     struct imsic_vector *mvec;
> > +     bool is_enabled;
> > +
> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> > +     if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> > +             return;
> > +
> > +     is_enabled = imsic_vector_isenabled(vec);
> > +     mvec = imsic_vector_get_move(vec);
> > +
> > +     seq_printf(m, "%*starget_cpu      : %5u\n", ind, "", vec->cpu);
> > +     seq_printf(m, "%*starget_local_id : %5u\n", ind, "", vec->local_id);
> > +     seq_printf(m, "%*sis_reserved     : %5u\n", ind, "",
> > +                (vec->local_id <= IMSIC_IPI_ID) ? 1 : 0);
> > +     seq_printf(m, "%*sis_enabled      : %5u\n", ind, "", (is_enabled) ? 1 : 0);
> > +     seq_printf(m, "%*sis_move_pending : %5u\n", ind, "", (mvec) ? 1 : 0);
>
> Nit: Redundant parenthesis.
>
> > +     if (mvec) {
> > +             seq_printf(m, "%*smove_cpu        : %5u\n", ind, "", mvec->cpu);
> > +             seq_printf(m, "%*smove_local_id   : %5u\n", ind, "", mvec->local_id);
> > +     }
> > +}
> > +
> > +void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
> > +{
> > +     irq_matrix_debug_show(m, imsic->matrix, ind);
> > +}
> > +#endif
> > +
> > +struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
> > +{
> > +     struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> > +
> > +     if (!lpriv || imsic->global.nr_ids < local_id)
> > +             return NULL;
> > +
> > +     return &lpriv->vectors[local_id];
> > +}
> > +
> > +struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask)
> > +{
> > +     struct imsic_vector *vec = NULL;
> > +     struct imsic_local_priv *lpriv;
> > +     unsigned long flags;
> > +     unsigned int cpu;
> > +     int local_id;
> > +
> > +     raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> > +     local_id = irq_matrix_alloc(imsic->matrix, mask, false, &cpu);
> > +     raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> > +     if (local_id < 0)
> > +             return NULL;
> > +
> > +     lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> > +     vec = &lpriv->vectors[local_id];
> > +     vec->hwirq = hwirq;
> > +     vec->enable = false;
> > +     vec->move = NULL;
> > +
> > +     return vec;
> > +}
> > +
> > +void imsic_vector_free(struct imsic_vector *vec)
> > +{
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> > +     vec->hwirq = UINT_MAX;
> > +     irq_matrix_free(imsic->matrix, vec->cpu, vec->local_id, false);
> > +     raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> > +}
> > +
> > +static void __init imsic_local_cleanup(void)
> > +{
> > +     int cpu;
> > +     struct imsic_local_priv *lpriv;
> > +
> > +     for_each_possible_cpu(cpu) {
> > +             lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> > +
> > +             bitmap_free(lpriv->dirty_bitmap);
> > +             kfree(lpriv->vectors);
> > +     }
> > +
> > +     free_percpu(imsic->lpriv);
> > +}
> > +
> > +static int __init imsic_local_init(void)
> > +{
> > +     struct imsic_global_config *global = &imsic->global;
> > +     struct imsic_local_priv *lpriv;
> > +     struct imsic_vector *vec;
> > +     int cpu, i;
> > +
> > +     /* Allocate per-CPU private state */
> > +     imsic->lpriv = alloc_percpu(typeof(*(imsic->lpriv)));
> > +     if (!imsic->lpriv)
> > +             return -ENOMEM;
> > +
> > +     /* Setup per-CPU private state */
> > +     for_each_possible_cpu(cpu) {
> > +             lpriv = per_cpu_ptr(imsic->lpriv, cpu);
> > +
> > +             raw_spin_lock_init(&lpriv->lock);
> > +
> > +             /* Allocate dirty bitmap */
> > +             lpriv->dirty_bitmap = bitmap_zalloc(global->nr_ids + 1, GFP_KERNEL);
> > +             if (!lpriv->dirty_bitmap)
> > +                     goto fail_local_cleanup;
> > +
> > +#ifdef CONFIG_SMP
> > +             /* Setup lazy timer for synchronization */
> > +             timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
> > +#endif
> > +
> > +             /* Allocate vector array */
> > +             lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
> > +                                      GFP_KERNEL);
> > +             if (!lpriv->vectors)
> > +                     goto fail_local_cleanup;
> > +
> > +             /* Setup vector array */
> > +             for (i = 0; i <= global->nr_ids; i++) {
> > +                     vec = &lpriv->vectors[i];
> > +                     vec->cpu = cpu;
> > +                     vec->local_id = i;
> > +                     vec->hwirq = UINT_MAX;
> > +             }
> > +     }
> > +
> > +     return 0;
> > +
> > +fail_local_cleanup:
> > +     imsic_local_cleanup();
> > +     return -ENOMEM;
> > +}
> > +
> > +void imsic_state_online(void)
> > +{
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> > +     irq_matrix_online(imsic->matrix);
> > +     raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> > +}
> > +
> > +void imsic_state_offline(void)
> > +{
> > +#ifdef CONFIG_SMP
> > +     struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> > +#endif
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> > +     irq_matrix_offline(imsic->matrix);
> > +     raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> > +
> > +#ifdef CONFIG_SMP
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +     WARN_ON_ONCE(try_to_del_timer_sync(&lpriv->timer) < 0);
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> > +#endif
> > +}
> > +
> > +static int __init imsic_matrix_init(void)
> > +{
> > +     struct imsic_global_config *global = &imsic->global;
> > +
> > +     raw_spin_lock_init(&imsic->matrix_lock);
> > +     imsic->matrix = irq_alloc_matrix(global->nr_ids + 1,
> > +                                      0, global->nr_ids + 1);
> > +     if (!imsic->matrix)
> > +             return -ENOMEM;
> > +
> > +     /* Reserve ID#0 because it is special and never implemented */
> > +     irq_matrix_assign_system(imsic->matrix, 0, false);
> > +
> > +     /* Reserve IPI ID because it is special and used internally */
> > +     irq_matrix_assign_system(imsic->matrix, IMSIC_IPI_ID, false);
> > +
> > +     return 0;
> > +}
> > +
> > +static int __init imsic_get_parent_hartid(struct fwnode_handle *fwnode,
> > +                                       u32 index, unsigned long *hartid)
> > +{
> > +     struct of_phandle_args parent;
> > +     int rc;
> > +
> > +     /*
> > +      * Currently, only OF fwnode is supported so extend this
> > +      * function for ACPI support.
> > +      */
> > +     if (!is_of_node(fwnode))
> > +             return -EINVAL;
> > +
> > +     rc = of_irq_parse_one(to_of_node(fwnode), index, &parent);
> > +     if (rc)
> > +             return rc;
> > +
> > +     /*
> > +      * Skip interrupts other than external interrupts for
> > +      * current privilege level.
> > +      */
> > +     if (parent.args[0] != RV_IRQ_EXT)
> > +             return -EINVAL;
> > +
> > +     return riscv_of_parent_hartid(parent.np, hartid);
> > +}
> > +
> > +static int __init imsic_get_mmio_resource(struct fwnode_handle *fwnode,
> > +                                       u32 index, struct resource *res)
> > +{
> > +     /*
> > +      * Currently, only OF fwnode is supported so extend this
> > +      * function for ACPI support.
> > +      */
> > +     if (!is_of_node(fwnode))
> > +             return -EINVAL;
> > +
> > +     return of_address_to_resource(to_of_node(fwnode), index, res);
> > +}
> > +
> > +static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
> > +                                  struct imsic_global_config *global,
> > +                                  u32 *nr_parent_irqs,
> > +                                  u32 *nr_mmios)
> > +{
> > +     unsigned long hartid;
> > +     struct resource res;
> > +     int rc;
> > +     u32 i;
> > +
> > +     /*
> > +      * Currently, only OF fwnode is supported so extend this
> > +      * function for ACPI support.
> > +      */
> > +     if (!is_of_node(fwnode))
> > +             return -EINVAL;
> > +
> > +     *nr_parent_irqs = 0;
> > +     *nr_mmios = 0;
> > +
> > +     /* Find number of parent interrupts */
> > +     while (!imsic_get_parent_hartid(fwnode, *nr_parent_irqs, &hartid))
> > +             (*nr_parent_irqs)++;
> > +     if (!(*nr_parent_irqs)) {
>
> Nit: Redundant parenthesis
>
> > +             pr_err("%pfwP: no parent irqs available\n", fwnode);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* Find number of guest index bits in MSI address */
> > +     rc = of_property_read_u32(to_of_node(fwnode), "riscv,guest-index-bits",
> > +                               &global->guest_index_bits);
> > +     if (rc)
> > +             global->guest_index_bits = 0;
> > +
> > +     /* Find number of HART index bits */
> > +     rc = of_property_read_u32(to_of_node(fwnode), "riscv,hart-index-bits",
> > +                               &global->hart_index_bits);
> > +     if (rc) {
> > +             /* Assume default value */
> > +             global->hart_index_bits = __fls(*nr_parent_irqs);
> > +             if (BIT(global->hart_index_bits) < *nr_parent_irqs)
> > +                     global->hart_index_bits++;
> > +     }
> > +
> > +     /* Find number of group index bits */
> > +     rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-bits",
> > +                               &global->group_index_bits);
> > +     if (rc)
> > +             global->group_index_bits = 0;
> > +
> > +     /*
> > +      * Find first bit position of group index.
> > +      * If not specified assumed the default APLIC-IMSIC configuration.
> > +      */
> > +     rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-shift",
> > +                               &global->group_index_shift);
> > +     if (rc)
> > +             global->group_index_shift = IMSIC_MMIO_PAGE_SHIFT * 2;
> > +
> > +     /* Find number of interrupt identities */
> > +     rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-ids",
> > +                               &global->nr_ids);
> > +     if (rc) {
> > +             pr_err("%pfwP: number of interrupt identities not found\n",
> > +                     fwnode);
> > +             return rc;
> > +     }
> > +
> > +     /* Find number of guest interrupt identities */
> > +     rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-guest-ids",
> > +                               &global->nr_guest_ids);
> > +     if (rc)
> > +             global->nr_guest_ids = global->nr_ids;
> > +
> > +     /* Sanity check guest index bits */
> > +     i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT;
> > +     if (i < global->guest_index_bits) {
> > +             pr_err("%pfwP: guest index bits too big\n", fwnode);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* Sanity check HART index bits */
> > +     i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT - global->guest_index_bits;
> > +     if (i < global->hart_index_bits) {
> > +             pr_err("%pfwP: HART index bits too big\n", fwnode);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* Sanity check group index bits */
> > +     i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
> > +         global->guest_index_bits - global->hart_index_bits;
> > +     if (i < global->group_index_bits) {
> > +             pr_err("%pfwP: group index bits too big\n", fwnode);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* Sanity check group index shift */
> > +     i = global->group_index_bits + global->group_index_shift - 1;
> > +     if (i >= BITS_PER_LONG) {
> > +             pr_err("%pfwP: group index shift too big\n", fwnode);
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* Sanity check number of interrupt identities */
> > +     if ((global->nr_ids < IMSIC_MIN_ID) ||
> > +         (global->nr_ids >= IMSIC_MAX_ID) ||
> > +         ((global->nr_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID)) {
> > +             pr_err("%pfwP: invalid number of interrupt identities\n",
> > +                     fwnode);
>
> Nit: 100 chars
>
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* Sanity check number of guest interrupt identities */
> > +     if ((global->nr_guest_ids < IMSIC_MIN_ID) ||
> > +         (global->nr_guest_ids >= IMSIC_MAX_ID) ||
> > +         ((global->nr_guest_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID)) {
> > +             pr_err("%pfwP: invalid number of guest interrupt identities\n",
> > +                     fwnode);
>
> Nit: 100 chars
>
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* Compute base address */
> > +     rc = imsic_get_mmio_resource(fwnode, 0, &res);
> > +     if (rc) {
> > +             pr_err("%pfwP: first MMIO resource not found\n", fwnode);
> > +             return -EINVAL;
> > +     }
> > +     global->base_addr = res.start;
> > +     global->base_addr &= ~(BIT(global->guest_index_bits +
> > +                                global->hart_index_bits +
> > +                                IMSIC_MMIO_PAGE_SHIFT) - 1);
> > +     global->base_addr &= ~((BIT(global->group_index_bits) - 1) <<
> > +                            global->group_index_shift);
> > +
> > +     /* Find number of MMIO register sets */
> > +     while (!imsic_get_mmio_resource(fwnode, *nr_mmios, &res))
> > +             (*nr_mmios)++;
> > +
> > +     return 0;
> > +}
> > +
> > +int __init imsic_setup_state(struct fwnode_handle *fwnode)
> > +{
> > +     u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
> > +     struct imsic_global_config *global;
> > +     struct imsic_local_config *local;
> > +     void __iomem **mmios_va = NULL;
> > +     struct resource *mmios = NULL;
> > +     unsigned long reloff, hartid;
> > +     phys_addr_t base_addr;
> > +     int rc, cpu;
> > +
> > +     /*
> > +      * Only one IMSIC instance allowed in a platform for clean
> > +      * implementation of SMP IRQ affinity and per-CPU IPIs.
> > +      *
> > +      * This means on a multi-socket (or multi-die) platform we
> > +      * will have multiple MMIO regions for one IMSIC instance.
> > +      */
> > +     if (imsic) {
> > +             pr_err("%pfwP: already initialized hence ignoring\n",
> > +                     fwnode);
>
> Nit: 100 chars
>
> > +             return -EALREADY;
> > +     }
> > +
> > +     if (!riscv_isa_extension_available(NULL, SxAIA)) {
> > +             pr_err("%pfwP: AIA support not available\n", fwnode);
> > +             return -ENODEV;
> > +     }
> > +
> > +     imsic = kzalloc(sizeof(*imsic), GFP_KERNEL);
> > +     if (!imsic)
> > +             return -ENOMEM;
> > +     imsic->fwnode = fwnode;
> > +     global = &imsic->global;
> > +
> > +     global->local = alloc_percpu(typeof(*(global->local)));
> > +     if (!global->local) {
> > +             rc = -ENOMEM;
> > +             goto out_free_priv;
> > +     }
> > +
> > +     /* Parse IMSIC fwnode */
> > +     rc = imsic_parse_fwnode(fwnode, global, &nr_parent_irqs, &nr_mmios);
> > +     if (rc)
> > +             goto out_free_local;
> > +
> > +     /* Allocate MMIO resource array */
> > +     mmios = kcalloc(nr_mmios, sizeof(*mmios), GFP_KERNEL);
> > +     if (!mmios) {
> > +             rc = -ENOMEM;
> > +             goto out_free_local;
> > +     }
> > +
> > +     /* Allocate MMIO virtual address array */
> > +     mmios_va = kcalloc(nr_mmios, sizeof(*mmios_va), GFP_KERNEL);
> > +     if (!mmios_va) {
> > +             rc = -ENOMEM;
> > +             goto out_iounmap;
> > +     }
> > +
> > +     /* Parse and map MMIO register sets */
> > +     for (i = 0; i < nr_mmios; i++) {
> > +             rc = imsic_get_mmio_resource(fwnode, i, &mmios[i]);
> > +             if (rc) {
> > +                     pr_err("%pfwP: unable to parse MMIO regset %d\n",
> > +                             fwnode, i);
>
> Nit: 100 chars
>
> > +                     goto out_iounmap;
> > +             }
> > +
> > +             base_addr = mmios[i].start;
> > +             base_addr &= ~(BIT(global->guest_index_bits +
> > +                                global->hart_index_bits +
> > +                                IMSIC_MMIO_PAGE_SHIFT) - 1);
> > +             base_addr &= ~((BIT(global->group_index_bits) - 1) <<
> > +                            global->group_index_shift);
> > +             if (base_addr != global->base_addr) {
> > +                     rc = -EINVAL;
> > +                     pr_err("%pfwP: address mismatch for regset %d\n",
> > +                             fwnode, i);
>
> Nit: 100 chars... and all the places below where applicable.
>
>
> Bj?rn

Regards,
Anup


From anup at brainfault.org  Tue Feb 20 05:09:34 2024
From: anup at brainfault.org (Anup Patel)
Date: Tue, 20 Feb 2024 18:39:34 +0530
Subject: [PATCH v13 00/13] Linux RISC-V AIA Support
In-Reply-To: <87edd7fj3d.fsf@all.your.base.are.belong.to.us>
References: <20240220060718.823229-1-apatel@ventanamicro.com> <87edd7fj3d.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAAhSdy1mDnE0Z5hs+LHrSUmQzEBC3EHF2TfU=Bd416RacgbjeA@mail.gmail.com>

On Tue, Feb 20, 2024 at 5:22?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Anup Patel <apatel at ventanamicro.com> writes:
>
> > The RISC-V AIA specification is ratified as-per the RISC-V international
> > process. The latest ratified AIA specifcation can be found at:
> > https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf
> >
> > At a high-level, the AIA specification adds three things:
> > 1) AIA CSRs
> >    - Improved local interrupt support
> > 2) Incoming Message Signaled Interrupt Controller (IMSIC)
> >    - Per-HART MSI controller
> >    - Support MSI virtualization
> >    - Support IPI along with virtualization
> > 3) Advanced Platform-Level Interrupt Controller (APLIC)
> >    - Wired interrupt controller
> >    - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
> >    - In Direct-mode, injects external interrupts directly into HARTs
> >
> > For an overview of the AIA specification, refer the AIA virtualization
> > talk at KVM Forum 2022:
> > https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
> > https://www.youtube.com/watch?v=r071dL8Z0yo
> >
> > To test this series, use QEMU v7.2 (or higher) and OpenSBI v1.2 (or higher).
> >
> > This series depends upon per-device MSI domain patches merged by Thomas (tglx)
> > which are available in irq/msi branch at:
> > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git
> >
> > These patches can also be found in the riscv_aia_v13 branch at:
> > https://github.com/avpatel/linux.git
> >
> > Changes since v12:
> >  - Rebased on Linux-6.8-rc5
> >  - Dropped per-device MSI domain patches which are already merged by Thomas (tglx)
> >  - Addressed nit comments from Thomas and Clement
> >  - Added a new patch2 to fix lock dependency warning
> >  - Replaced local sync IPI in the IMSIC driver with per-CPU timer
> >  - Simplified locking in the IMSIC driver to avoid lock dependency issues
> >  - Added a dirty bitmap in the IMSIC driver to optimize per-CPU local sync loop
>
> Thanks, Anup.
>
> I will take it for a spin, with Alex' v1 of the stop_machine()/ftrace
> IPI fix.
>
> The defconfig change (12/13)breaks a bunch a builds:
> https://patchwork.kernel.org/project/linux-riscv/list/?series=827706
>
> Download the logs here:
> https://github.com/linux-riscv/linux-riscv/suites/20917102160/logs?attempt=1
> and grep for '##[error]'

You need to pull-in 14 dependent patches which Thomas has merged
in his irq/msi branch at
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git.

Regards,
Anup


From anup at brainfault.org  Tue Feb 20 05:15:47 2024
From: anup at brainfault.org (Anup Patel)
Date: Tue, 20 Feb 2024 18:45:47 +0530
Subject: [PATCH v13 06/13] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <87a5nvfj2s.fsf@all.your.base.are.belong.to.us>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-7-apatel@ventanamicro.com> <87a5nvfj2s.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAAhSdy187H0E1-V4uhrik42qHoZrk-w499YWFzR13EWX-Wyu=g@mail.gmail.com>

On Tue, Feb 20, 2024 at 5:23?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Anup Patel <apatel at ventanamicro.com> writes:
>
> > The RISC-V advanced interrupt architecture (AIA) specification
> > defines a new MSI controller called incoming message signalled
> > interrupt controller (IMSIC) which manages MSI on per-HART (or
> > per-CPU) basis. It also supports IPIs as software injected MSIs.
> > (For more details refer https://github.com/riscv/riscv-aia)
> >
> > Let us add an early irqchip driver for RISC-V IMSIC which sets
> > up the IMSIC state and provide IPIs.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
>
> This patch has a couple of checkpatch issues:
>
> CHECK: Alignment should match open parenthesis
> CHECK: Please don't use multiple blank lines
> CHECK: Please use a blank line after function/struct/union/enum declarations
> CHECK: Unnecessary parentheses around 'global->nr_guest_ids < IMSIC_MIN_ID'
> CHECK: Unnecessary parentheses around 'global->nr_guest_ids >= IMSIC_MAX_ID'
> CHECK: Unnecessary parentheses around 'global->nr_ids < IMSIC_MIN_ID'
> CHECK: Unnecessary parentheses around 'global->nr_ids >= IMSIC_MAX_ID'
> CHECK: Unnecessary parentheses around global->local
> CHECK: Unnecessary parentheses around imsic->lpriv
> CHECK: extern prototypes should be avoided in .h files
>

Okay, I will address these in the next revision.

Regards,
Anup


From tglx at linutronix.de  Tue Feb 20 05:15:56 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 20 Feb 2024 14:15:56 +0100
Subject: [PATCH v13 06/13] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <20240220060718.823229-7-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-7-apatel@ventanamicro.com>
Message-ID: <87a5nvi8dv.ffs@tglx>

On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> The RISC-V advanced interrupt architecture (AIA) specification
> defines a new MSI controller called incoming message signalled
> interrupt controller (IMSIC) which manages MSI on per-HART (or
> per-CPU) basis. It also supports IPIs as software injected MSIs.
> (For more details refer https://github.com/riscv/riscv-aia)
>
> Let us add an early irqchip driver for RISC-V IMSIC which sets
> up the IMSIC state and provide IPIs.

s/Let us add/Add/

> +#else
> +static void imsic_ipi_starting_cpu(void)
> +{
> +}
> +
> +static void imsic_ipi_dying_cpu(void)
> +{
> +}
> +
> +static int __init imsic_ipi_domain_init(void)
> +{
> +	return 0;
> +}

Please condense this into

static void imsic_ipi_starting_cpu(void) { }
static void imsic_ipi_dying_cpu(void) { }
static int __init imsic_ipi_domain_init(void) { return 0; }

No point in wasting space for these stubs.

> + * To handle an interrupt, we read the TOPEI CSR and write zero in one
> + * instruction. If TOPEI CSR is non-zero then we translate TOPEI.ID to
> + * Linux interrupt number and let Linux IRQ subsystem handle it.
> + */
> +static void imsic_handle_irq(struct irq_desc *desc)
> +{
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	int err, cpu = smp_processor_id();
> +	struct imsic_vector *vec;
> +	unsigned long local_id;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	while ((local_id = csr_swap(CSR_TOPEI, 0))) {
> +		local_id = local_id >> TOPEI_ID_SHIFT;
> +
> +		if (local_id == IMSIC_IPI_ID) {
> +#ifdef CONFIG_SMP

	if (IS_ENABLED(CONFIG_SMP))

> +			ipi_mux_process();
> +#endif
> +			continue;
> +		}

> +
> +/* MUST be called with lpriv->lock held */

Instead of a comment which cannot be enforced just have

        lockdep_assert_held(&lpriv->lock);

right at the top of the function. That documents the requirement and
lets lockdep yell if not followed.

> +#ifdef CONFIG_SMP
> +static void imsic_local_timer_callback(struct timer_list *timer)
> +{
> +	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +	__imsic_local_sync(lpriv);
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> +}
> +
> +/* MUST be called with lpriv->lock held */

Ditto

> +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)

> +void imsic_vector_mask(struct imsic_vector *vec)
> +{
> +	struct imsic_local_priv *lpriv;
> +
> +	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> +	if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> +		return;

WARN_ON_ONCE(), no?

> +bool imsic_vector_isenabled(struct imsic_vector *vec)
> +{
> +	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> +	unsigned long flags;
> +	bool ret;
> +
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +	ret = vec->enable;
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);

I'm not sure what you are trying to protect here. vec->enable can
obviously change right after the lock is dropped. So that's just a
snapshot, which is not any better than using

          READ_ONCE(vec->enable);

and a corresponding WRITE_ONCE() at the update site, which obviously
needs serialization.

> +static void __init imsic_local_cleanup(void)
> +{
> +	int cpu;
> +	struct imsic_local_priv *lpriv;

        struct imsic_local_priv *lpriv;
	int cpu;

Please.

> +void imsic_state_offline(void)
> +{
> +#ifdef CONFIG_SMP
> +	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> +#endif

You can move that into the #ifdef below.

> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> +	irq_matrix_offline(imsic->matrix);
> +	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> +
> +#ifdef CONFIG_SMP
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +	WARN_ON_ONCE(try_to_del_timer_sync(&lpriv->timer) < 0);
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> +#endif
> +}


Thanks,

        tglx


From joey.gouly at arm.com  Tue Feb 20 05:17:45 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 20 Feb 2024 13:17:45 +0000
Subject: [PATCH 01/13] KVM: arm64: Harden __ctxt_sys_reg() against
 out-of-range values
In-Reply-To: <8634tn4acv.wl-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
 <20240219092014.783809-2-maz@kernel.org>
 <20240220112031.GA16168@e124191.cambridge.arm.com>
 <8634tn4acv.wl-maz@kernel.org>
Message-ID: <20240220131745.GA8575@e124191.cambridge.arm.com>

On Tue, Feb 20, 2024 at 11:57:04AM +0000, Marc Zyngier wrote:
> On Tue, 20 Feb 2024 11:20:31 +0000,
> Joey Gouly <joey.gouly at arm.com> wrote:
> > 
> > On Mon, Feb 19, 2024 at 09:20:02AM +0000, Marc Zyngier wrote:
> > > The unsuspecting kernel tinkerer can be easily confused into
> > > writing something that looks like this:
> > > 
> > > 	ikey.lo = __vcpu_sys_reg(vcpu, SYS_APIAKEYLO_EL1);
> > > 
> > > which seems vaguely sensible, until you realise that the second
> > > parameter is the encoding of a sysreg, and not the index into
> > > the vcpu sysreg file... Debugging what happens in this case is
> > 
> > type safety :(
> 
> Are you advocating for making everything a struct? Or something else?

No, merely lamenting the situation.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>

> 
> > 
> > > an interesting exercise in head<->wall interactions.
> > > 
> > > As they often say: "Any resemblance to actual persons, living
> > > or dead, or actual events is purely coincidental".
> > > 
> > > In order to save people's time, add some compile-time hardening
> > > that will at least weed out the "stupidly out of range" values.
> > > This will *not* catch anything that isn't a compile-time constant.
> > > 
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > ---
> > >  arch/arm64/include/asm/kvm_host.h | 9 ++++++++-
> > >  1 file changed, 8 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > > index 181fef12e8e8..a5ec4c7d3966 100644
> > > --- a/arch/arm64/include/asm/kvm_host.h
> > > +++ b/arch/arm64/include/asm/kvm_host.h
> > > @@ -895,7 +895,7 @@ struct kvm_vcpu_arch {
> > >   * Don't bother with VNCR-based accesses in the nVHE code, it has no
> > >   * business dealing with NV.
> > >   */
> > > -static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
> > > +static inline u64 *___ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
> > 
> > When in doubt, add more underscores!
> 
> That's the one true way.
> 
> > 
> > >  {
> > >  #if !defined (__KVM_NVHE_HYPERVISOR__)
> > >  	if (unlikely(cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
> > > @@ -905,6 +905,13 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
> > >  	return (u64 *)&ctxt->sys_regs[r];
> > >  }
> > >  
> > > +#define __ctxt_sys_reg(c,r)						\
> > > +	({								\
> > > +	    	BUILD_BUG_ON(__builtin_constant_p(r) &&			\
> > > +			     (r) >= NR_SYS_REGS);			\
> > > +		___ctxt_sys_reg(c, r);					\
> > > +	})
> > 
> > I'm assuming the extra macro layer is to try make __builtin_constant_p() as
> > effective as possible? Otherwise maybe it relies on the compiler inling the
> > ___ctxt_sys_reg() function?
> 
> It's not about efficiency. It's about making it *work*. Otherwise,
> lack of inlining will screw you over, and you may not check anything.

Thanks,
Joey


From peter.griffin at linaro.org  Tue Feb 20 05:20:37 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 20 Feb 2024 13:20:37 +0000
Subject: [PATCH v5 1/2] soc: samsung: exynos-pmu: Add regmap support for
 SoCs that protect PMU regs
In-Reply-To: <CAPLW+4nOq_62rBhwRUf0RW0zTiGa+-Zpt+FLcTa87biX8Nq-BA@mail.gmail.com>
References: <20240219204238.356942-1-peter.griffin@linaro.org>
 <20240219204238.356942-2-peter.griffin@linaro.org> <CAPLW+4nOq_62rBhwRUf0RW0zTiGa+-Zpt+FLcTa87biX8Nq-BA@mail.gmail.com>
Message-ID: <CADrjBPrMC4Zh1yOzfPZ81bfnkz5BG9MktPpgny9r3F0x8mekxw@mail.gmail.com>

Hi Sam,

On Mon, 19 Feb 2024 at 23:06, Sam Protsenko <semen.protsenko at linaro.org> wrote:
>
> On Mon, Feb 19, 2024 at 2:42?PM Peter Griffin <peter.griffin at linaro.org> wrote:
> >
> > Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
> > security hardening reasons so that they are only write accessible in el3
> > via an SMC call.
> >
> > As most Exynos drivers that need to write PMU registers currently obtain a
> > regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
> > is implemented in this driver using a custom regmap similar to syscon to
> > handle the SMC call. Platforms that don't secure PMU registers, get a mmio
> > regmap like before. As regmaps abstract out the underlying register access
> > changes to the leaf drivers are minimal.
> >
> > A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
> > that currently use syscon_regmap_lookup_by_phandle(). This also handles
> > deferred probing.
> >
> > Tested-by: Sam Protsenko <semen.protsenko at linaro.org>
> > Tested-by: Alexey Klimov <alexey.klimov at linaro.org>
> > Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > ---
> > Changes since v4:
> >  - Use same argument names as in struct regmap_config
> >  - Remove inline keyword and rely on compiler
> >  - Update kerneldoc wording
> >  - property -> propname argument rename
> >  - reverse Xmas tree
> >  - Only call of_node_put() when of_parse_phandle is called
> >  - Collect tags
> >
> > Changes since v3:
> >  - Fix PMUALIVE_MASK
> >  - Add TENSOR_ prefix
> >  - clear SET_BITS bits on each loop iteration
> >  - change set_bit to set_bits in func name
> >  - Fix some alignment
> >  - Add missing return on dev_err_probe
> >  - Reduce indentation in loop
> >
> > Changes since v2
> >  - Add select REGMAP to Kconfig
> >  - Add constant for SET/CLEAR bits
> >  - Replace kerneldoc with one line comment
> >  - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
> >  - remove superfluous extern keyword
> >  - dev_err_probe() on probe error
> >  - shorten regmcfg name
> >  - no compatibles inside probe, use match data
> >  - don't mix declarations with/without initializations
> >  - tensor_sec_reg_read() use mmio to avoid access restrictions
> >  - Collect up Reviewed-by
> >  - const for regmap_config structs
> > ---
> >  drivers/soc/samsung/Kconfig            |   1 +
> >  drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
> >  drivers/soc/samsung/exynos-pmu.h       |   1 +
> >  include/linux/soc/samsung/exynos-pmu.h |  11 +-
> >  4 files changed, 245 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> > index 27ec99af77e3..1a5dfdc978dc 100644
> > --- a/drivers/soc/samsung/Kconfig
> > +++ b/drivers/soc/samsung/Kconfig
> > @@ -42,6 +42,7 @@ config EXYNOS_PMU
> >         depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
> >         select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
> >         select MFD_CORE
> > +       select REGMAP_MMIO
> >
> >  # There is no need to enable these drivers for ARMv8
> >  config EXYNOS_PMU_ARM_DRIVERS
> > diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> > index 250537d7cfd6..d6ae8025fdb4 100644
> > --- a/drivers/soc/samsung/exynos-pmu.c
> > +++ b/drivers/soc/samsung/exynos-pmu.c
> > @@ -5,6 +5,7 @@
> >  //
> >  // Exynos - CPU PMU(Power Management Unit) support
> >
> > +#include <linux/arm-smccc.h>
> >  #include <linux/of.h>
> >  #include <linux/of_address.h>
> >  #include <linux/mfd/core.h>
> > @@ -12,19 +13,134 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/delay.h>
> > +#include <linux/regmap.h>
> >
> >  #include <linux/soc/samsung/exynos-regs-pmu.h>
> >  #include <linux/soc/samsung/exynos-pmu.h>
> >
> >  #include "exynos-pmu.h"
> >
> > +#define PMUALIVE_MASK                  GENMASK(13, 0)
> > +#define TENSOR_SET_BITS                        (BIT(15) | BIT(14))
> > +#define TENSOR_CLR_BITS                        BIT(15)
> > +#define TENSOR_SMC_PMU_SEC_REG         0x82000504
> > +#define TENSOR_PMUREG_READ             0
> > +#define TENSOR_PMUREG_WRITE            1
> > +#define TENSOR_PMUREG_RMW              2
> > +
> >  struct exynos_pmu_context {
> >         struct device *dev;
> >         const struct exynos_pmu_data *pmu_data;
> > +       struct regmap *pmureg;
> >  };
> >
> >  void __iomem *pmu_base_addr;
> >  static struct exynos_pmu_context *pmu_context;
> > +/* forward declaration */
> > +static struct platform_driver exynos_pmu_driver;
> > +
> > +/*
> > + * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
> > + * from EL3, but are still read accessible. As Linux needs to write some of
> > + * these registers, the following functions are provided and exposed via
> > + * regmap.
> > + *
> > + * Note: This SMC interface is known to be implemented on gs101 and derivative
> > + * SoCs.
> > + */
> > +
> > +/* Write to a protected PMU register. */
> > +static int tensor_sec_reg_write(void *context, unsigned int reg,
> > +                               unsigned int val)
> > +{
> > +       struct arm_smccc_res res;
> > +       unsigned long pmu_base = (unsigned long)context;
> > +
> > +       arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> > +                     TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
> > +
> > +       /* returns -EINVAL if access isn't allowed or 0 */
> > +       if (res.a0)
> > +               pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> > +
> > +       return (int)res.a0;
> > +}
> > +
> > +/* Read/Modify/Write a protected PMU register. */
> > +static int tensor_sec_reg_rmw(void *context, unsigned int reg,
> > +                             unsigned int mask, unsigned int val)
> > +{
> > +       struct arm_smccc_res res;
> > +       unsigned long pmu_base = (unsigned long)context;
> > +
> > +       arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
> > +                     TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
> > +
> > +       /* returns -EINVAL if access isn't allowed or 0 */
> > +       if (res.a0)
> > +               pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
> > +
> > +       return (int)res.a0;
> > +}
> > +
> > +/*
> > + * Read a protected PMU register. All PMU registers can be read by Linux.
> > + * Note: The SMC read register is not used, as only registers that can be
> > + * written are readable via SMC.
> > + */
> > +static int tensor_sec_reg_read(void *context, unsigned int reg,
> > +                              unsigned int *val)
> > +{
> > +       *val = pmu_raw_readl(reg);
> > +       return 0;
> > +}
> > +
> > +/*
> > + * For SoCs that have set/clear bit hardware this function can be used when
> > + * the PMU register will be accessed by multiple masters.
> > + *
> > + * For example, to set bits 13:8 in PMU reg offset 0x3e80
> > + * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00);
> > + *
> > + * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80
> > + * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00);
> > + */
> > +static int tensor_set_bits_atomic(void *ctx, unsigned int offset, u32 val,
> > +                                 u32 mask)
> > +{
> > +       int ret;
> > +       unsigned int i;
> > +
> > +       for (i = 0; i < 32; i++) {
> > +               if (!(mask & BIT(i)))
> > +                       continue;
> > +
> > +               offset &= ~TENSOR_SET_BITS;
> > +
> > +               if (val & BIT(i))
> > +                       offset |= TENSOR_SET_BITS;
> > +               else
> > +                       offset |= TENSOR_CLR_BITS;
> > +
> > +               ret = tensor_sec_reg_write(ctx, offset, i);
> > +               if (ret)
> > +                       return ret;
> > +       }
> > +       return ret;
> > +}
> > +
> > +static int tensor_sec_update_bits(void *ctx, unsigned int reg,
> > +                                 unsigned int mask, unsigned int val)
> > +{
> > +       /*
> > +        * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
> > +        * as the target registers can be accessed by multiple masters.
> > +        */
> > +       if (reg > PMUALIVE_MASK)
> > +               return tensor_sec_reg_rmw(ctx, reg, mask, val);
> > +
> > +       return tensor_set_bits_atomic(ctx, reg, val, mask);
> > +}
> >
> >  void pmu_raw_writel(u32 val, u32 offset)
> >  {
> > @@ -75,11 +191,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
> >  #define exynos_pmu_data_arm_ptr(data)  NULL
> >  #endif
> >
> > +static const struct regmap_config regmap_smccfg = {
> > +       .name = "pmu_regs",
> > +       .reg_bits = 32,
> > +       .reg_stride = 4,
> > +       .val_bits = 32,
> > +       .fast_io = true,
> > +       .use_single_read = true,
> > +       .use_single_write = true,
> > +       .reg_read = tensor_sec_reg_read,
> > +       .reg_write = tensor_sec_reg_write,
> > +       .reg_update_bits = tensor_sec_update_bits,
> > +};
> > +
> > +static const struct regmap_config regmap_mmiocfg = {
> > +       .name = "pmu_regs",
> > +       .reg_bits = 32,
> > +       .reg_stride = 4,
> > +       .val_bits = 32,
> > +       .fast_io = true,
> > +       .use_single_read = true,
> > +       .use_single_write = true,
> > +};
> > +
> > +static const struct exynos_pmu_data gs101_pmu_data = {
> > +       .pmu_secure = true
> > +};
> > +
> >  /*
> >   * PMU platform driver and devicetree bindings.
> >   */
> >  static const struct of_device_id exynos_pmu_of_device_ids[] = {
> >         {
> > +               .compatible = "google,gs101-pmu",
> > +               .data = &gs101_pmu_data,
> > +       }, {
> >                 .compatible = "samsung,exynos3250-pmu",
> >                 .data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
> >         }, {
> > @@ -113,19 +259,75 @@ static const struct mfd_cell exynos_pmu_devs[] = {
> >         { .name = "exynos-clkout", },
> >  };
> >
> > +/**
> > + * exynos_get_pmu_regmap() - Obtain pmureg regmap
> > + *
> > + * Find the pmureg regmap previously configured in probe() and return regmap
> > + * pointer.
> > + *
> > + * Return: A pointer to regmap if found or ERR_PTR error value.
> > + */
> >  struct regmap *exynos_get_pmu_regmap(void)
> >  {
> >         struct device_node *np = of_find_matching_node(NULL,
> >                                                       exynos_pmu_of_device_ids);
> >         if (np)
> > -               return syscon_node_to_regmap(np);
> > +               return exynos_get_pmu_regmap_by_phandle(np, NULL);
> >         return ERR_PTR(-ENODEV);
> >  }
> >  EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
> >
> > +/**
> > + * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
> > + * @np: Device node holding PMU phandle property
> > + * @property: Name of property holding phandle value
>
> This doesn't match the actual param name.

Doh, I missed the kerneldoc comment in the renaming from property ->
propname. I will send a v6 in a moment with this fixed

Peter.


From joey.gouly at arm.com  Tue Feb 20 05:23:50 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 20 Feb 2024 13:23:50 +0000
Subject: [PATCH 02/13] KVM: arm64: Clarify ESR_ELx_ERET_ISS_ERET*
In-Reply-To: <861q9748ut.wl-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
 <20240219092014.783809-3-maz@kernel.org>
 <20240220113127.GB16168@e124191.cambridge.arm.com>
 <861q9748ut.wl-maz@kernel.org>
Message-ID: <20240220132350.GB8575@e124191.cambridge.arm.com>

On Tue, Feb 20, 2024 at 12:29:30PM +0000, Marc Zyngier wrote:
> On Tue, 20 Feb 2024 11:31:27 +0000,
> Joey Gouly <joey.gouly at arm.com> wrote:
> > 
> > On Mon, Feb 19, 2024 at 09:20:03AM +0000, Marc Zyngier wrote:
> > > The ESR_ELx_ERET_ISS_ERET* macros are a bit confusing:
> > > 
> > > - ESR_ELx_ERET_ISS_ERET really indicates that we have trapped an
> > >   ERETA* instruction, as opposed to an ERET
> > > 
> > > - ESR_ELx_ERET_ISS_ERETA reallu indicates that we have trapped
> > >   an ERETAB instruction, as opposed to an ERETAA.
> > > 
> > > Repaint the two helpers such as:
> > > 
> > > - ESR_ELx_ERET_ISS_ERET becomes ESR_ELx_ERET_ISS_ERETA
> > > 
> > > - ESR_ELx_ERET_ISS_ERETA becomes ESR_ELx_ERET_ISS_ERETAB
> > > 
> > > At the same time, use BIT() instead of raw values.
> > > 
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > 
> > I'm somewhat against this, as the original names are what the Arm
> > ARM specifies.
> 
> I don't disagree, but that doesn't make the ARM ARM right! ;-)
> 
> > 
> > > ---
> > >  arch/arm64/include/asm/esr.h | 4 ++--
> > >  arch/arm64/kvm/handle_exit.c | 2 +-
> > >  2 files changed, 3 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> > > index 353fe08546cf..72c7810ccf2c 100644
> > > --- a/arch/arm64/include/asm/esr.h
> > > +++ b/arch/arm64/include/asm/esr.h
> > > @@ -290,8 +290,8 @@
> > >  		 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
> > > +#define ESR_ELx_ERET_ISS_ERETA		BIT(1)
> > > +#define ESR_ELx_ERET_ISS_ERETAB		BIT(0)
> > >  
> > >  /*
> > >   * ISS field definitions for floating-point exception traps
> > > diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> > > index 617ae6dea5d5..0646c623d1da 100644
> > > --- a/arch/arm64/kvm/handle_exit.c
> > > +++ b/arch/arm64/kvm/handle_exit.c
> > > @@ -219,7 +219,7 @@ static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
> > >  
> > >  static int kvm_handle_eret(struct kvm_vcpu *vcpu)
> > >  {
> > > -	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERET)
> > > +	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERETA)
> > 
> > If this part is confusing due to the name, maybe introduce a function in esr.h
> > esr_is_pac_eret() (name pending bikeshedding)?
> 
> That's indeed a better option. Now for the bikeshed aspect:
> 
> - esr_iss_is_eretax(): check for ESR_ELx_ERET_ISS_ERET being set
> 
> - esr_iss_is_eretab(): check for ESR_ELx_ERET_ISS_ERETA being set
> 
> Thoughts?
> 

I was trying to avoid the ERETA* confusion by suggesting 'pac_eret', but if I
were to pick between your options I'd pick esr_iss_is_eretax().

Thanks,
Joey


From alexandru.elisei at arm.com  Tue Feb 20 05:26:38 2024
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 20 Feb 2024 13:26:38 +0000
Subject: arm64 MTE tag storage reuse - alternatives to MIGRATE_CMA
In-Reply-To: <70d77490-9036-48ac-afc9-4b976433070d@redhat.com>
References: <ZdSMbjGf2Fj98diT@raptor>
 <70d77490-9036-48ac-afc9-4b976433070d@redhat.com>
Message-ID: <ZdSojvNyaqli2rWE@raptor>

Hi David,

On Tue, Feb 20, 2024 at 01:05:42PM +0100, David Hildenbrand wrote:
> On 20.02.24 12:26, Alexandru Elisei wrote:
> > Hello,
> > 
> 
> Hi!
> 
> > This is a request to discuss alternatives to the current approach for
> > reusing the MTE tag storage memory for data allocations [1]. Each iteration
> > of the series uncovered new issues, the latest being that memory allocation
> > is being performed in atomic contexts [2]; I would like to start a
> > discussion regarding possible alternative, which would integrate better
> > with the memory management code.
> > 
> > This is a high level overview of the current approach:
> > 
> >   * Tag storage pages are put on the MIGRATE_CMA lists, meaning they can be
> >     used for data allocations like (almost) any other page in the system.
> > 
> >   * When a page is allocated as tagged, the corresponding tag storage is
> >     also allocated.
> > 
> >   * There's a static relationship between a page and the location in memory
> >     where its tags are stored. Because of this, if the corresponding tag
> >     storage is used for data, the tag storage page is migrated.
> > 
> > Although this is the most generic approach because tag storage pages are
> > treated like normal pages, it has some disadvantages:
> > 
> >   * HW KASAN (MTE in the kernel) cannot be used. The kernel allocates memory
> >     in atomic context, where migration is not possible.
> > 
> >   * Tag storage pages cannot be themselves tagged, and this means that all
> >     CMA pages, even those which aren't tag storage, cannot be used for
> >     tagged allocations.
> > 
> >   * Page migration is costly, and a process that uses MTE can experience
> >     measurable slowdowns if the tag storage it requires is in use for data.
> >     There might be ways to reduce this cost (by reducing the likelihood that
> >     tag storage pages are allocated), but it cannot be completely
> >     eliminated.
> > 
> >   * Worse yet, a userspace process can use a tag storage page in such a way
> >     that migration is effectively impossible [3],[4].  A malicious process
> >     can make use of this to prevent the allocation of tag storage for other
> >     processes in the system, leading to a degraded experience for the
> >     affected processes. Worst case scenario, progress becomes impossible for
> >     those processes.
> > 
> > One alternative approach I'm looking at right now is cleancache. Cleancache
> > was removed in v5.17 (commit 0a4ee518185e) because the only backend, the
> > tmem driver, had been removed earlier (in v5.3, commit 814bbf49dcd0).
> > 
> > With this approach, MTE tag storage would be implemented as a driver
> > backend for cleancache. When a tag storage page is needed for storing tags,
> > the page would simply be dropped from the cache (cleancache_get_page()
> > returns -1).
> 
> With large folios in place, we'd likely want to investigate not working on
> individual pages, but on (possibly large) folios instead.

Yes, that would be interesting. Since the backend has no way of controlling
what tag storage page will be needed for tags, and subsequently dropped
from the cache, we would have to figure out what to do if one of the pages
that is part of a large folio is dropped. The easiest solution that I can
see is to remove the entire folio from the cleancache, but that would mean
also dropping the rest of the pages from the folio unnecessarily.

> 
> > 
> > I believe this is a very good fit for tag storage reuse, because it allows
> > tag storage to be allocated even in atomic contexts, which enables MTE in
> > the kernel. As a bonus, all of the changes to MM from the current approach
> > wouldn't be needed, as tag storage allocation can be handled entirely in
> > set_ptes_at(), copy_*highpage() or arch_swap_restore().
> > 
> > Is this a viable approach that would be upstreamable? Are there other
> > solutions that I haven't considered? I'm very much open to any alternatives
> > that would make tag storage reuse viable.
> 
> As raised recently, I had similar ideas with something like virtio-mem in
> the past (wanted to call it virtio-tmem back then), but didn't have time to
> look into it yet.
> 
> I considered both, using special device memory as "cleancache" backend, and
> using it as backend storage for something similar to zswap. We would not
> need a memmap/"struct page" for that special device memory, which reduces
> memory overhead and makes "adding more memory" a more reliable operation.

Hm... this might not work with tag storage memory, the kernel needs to
perform cache maintenance on the memory when it transitions to and from
storing tags and storing data, so the memory must be mapped by the kernel.

> 
> Using it as "cleancache" backend does make some things a lot easier.
> 
> The idea would be to provide a variable amount of additional memory to a VM,
> that can be reclaimed easily and reliably on demand.
> 
> The details are a bit more involved, but in essence, imagine a special
> physical memory region that is provided by a the hypervisor via a device to
> the VM. A virtio device "owns" that region and the driver manages it, based
> on requests from the hypervisor.
> 
> Similar to virtio-mem, there are ways for the hypervisor to request changes
> to the memory consumption of a device (setting the requested size). So when
> requested to consume less, clean pagecache pages can be dropped and the
> memory can be handed back to the hypervisor.
> 
> Of course, likely we would want to consider using "slower" memory in the
> hypervisor to back such a device.

I'm not sure how useful that will be with tag storage reuse. KVM must
assume that **all** the memory that the guest uses is tagged and it needs
tag storage allocated (it's a known architectural limitation), so that will
leave even less tag storage memory to distribute between the host and the
guest(s).

Adding to that, at the moment Android is going to be the major (only?) user
of tag storage reuse, and as far as I know pKVM is more restrictive with
regards to the emulated devices and the memory that is shared between
guests and the host.

> 
> I also thought about better integrating memory reclaim in the hypervisor,
> similar to "MADV_FREE" semantic way. One idea I had was that the memory
> provided by the device might have "special" semantics (as if the memory is
> always marked MADV_FREE), whereby the hypervisor could reclaim+discard any
> memory in that region any time, and the driver would have ways to get
> notified about that, or detect that reclaim happened.
> 
> I learned that there are cases where data that is significantly larger than
> main memory might be read repeatedly. As long as there is free memory in the
> hypervisor, it could be used as a cache for clean pagecache pages. In
> contrast to memory ballonning + virtio-mem, that memory can be easily and
> reliably reclaimed. And reclaiming that memory cannot really hurt the VM, it
> would only affect performance.
> 
> Long story short: what I had in mind would require similar hooks (again).
> 
> In contrast to tmem, with arm64 MTE we could get an actual supported
> cleancache backend fairly easily. I recall that tmem was abandoned in XEN
> and never really reached production quality.

Yes, that was also my impression after reading commit 814bbf49dcd0 ("xen:
remove tmem driver").

Thanks,
Alex

> 
> -- 
> Cheers,
> 
> David / dhildenb
> 


From broonie at kernel.org  Tue Feb 20 05:31:25 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 13:31:25 +0000
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk>
 <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
 <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk>
 <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>
Message-ID: <5a3f5e1b-8162-4619-a10b-d4711afe533b@sirena.org.uk>

On Tue, Feb 20, 2024 at 12:16:10PM +0100, Bartosz Golaszewski wrote:
> On Mon, Feb 19, 2024 at 8:59?PM Mark Brown <broonie at kernel.org> wrote:
> > On Mon, Feb 19, 2024 at 07:48:20PM +0100, Bartosz Golaszewski wrote:

> > > No, the users don't request any regulators (or rather: software
> > > representations thereof) because - as per the cover letter - no
> > > regulators are created by the PMU driver. This is what is physically
> > > on the board - as the schematics and the datasheet define it. I took

> > The above makes no sense.  How can constraints be "what is physically on
> > the board", particularly variable constrants when there isn't even a
> > consumer?  What values are you taking from which documentation?

> The operating conditions for PMU outputs. I took them from a
> confidential datasheet. There's a table for input constraints and
> possible output values.

That sounds like you're just putting the maximum range of voltages that
the PMU can output in there.  This is a fundamental misunderstanding of
what the constraints are for, the constraints exist to specify what is
safe on a specific board which will in essentially all cases be much
more restricted.  The regulator driver should describe whatever the PMU
can support by itself, the constraints whatever is actually safe and
functional on the specific board.

> And what do you mean by there not being any consumers? The WLAN and BT
> *are* the consumers.

There are no drivers that bind to the regulators and vary the voltages
at runtime.

> > > the values from the docs verbatim. In C, we create a power sequencing
> > > provider which doesn't use the regulator framework at all.

> > For something that doesn't use the regulator framework at all what
> > appears to be a provider in patch 16 ("power: pwrseq: add a driver for
> > the QCA6390 PMU module") seems to have a lot of regualtor API calls?

> This driver is a power sequencing *provider* but also a regulator
> *consumer*. It gets regulators from the host and exposes a power
> sequencer to *its* consumers (WLAN and BT). On DT it exposes
> regulators (LDO outputs of the PMU) but we don't instantiate them in
> C.

Right, which sounds a lot like being a user of the regualtor framework.
-------------- 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/20240220/1378c35c/attachment.sig>

From tglx at linutronix.de  Tue Feb 20 05:32:27 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 20 Feb 2024 14:32:27 +0100
Subject: [PATCH v13 07/13] irqchip/riscv-imsic: Add device MSI domain
 support for platform devices
In-Reply-To: <20240220060718.823229-8-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-8-apatel@ventanamicro.com>
Message-ID: <875xyji7mc.ffs@tglx>

On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> +#ifdef CONFIG_SMP
> +static void imsic_msi_update_msg(struct irq_data *d, struct imsic_vector *vec)
> +{
> +	struct msi_msg msg[2] = { [1] = { }, };

That's a weird initializer and why do you need an array here?

       struct msi_msg msg = { };

Should be sufficient, no?

> +
> +	imsic_irq_compose_vector_msg(vec, msg);
> +	irq_data_get_irq_chip(d)->irq_write_msi_msg(d, msg);
> +}

> +static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> +				  unsigned int nr_irqs, void *args)
> +{
> +	struct imsic_vector *vec;
> +
> +	/* Legacy-MSI or multi-MSI not supported yet. */

Coming back to my earlier question:

>> What's legacy MSI in that context?
>
> The legacy-MSI is the MSI support in PCI v2.2 where
> number of MSIs allocated by device were either 1, 2, 4,
> 8, 16, or 32 and the data written is <data_word> + <irqnum>.

You talk about PCI/MSI, where more than one vector is named
multi-MSI. Contrary to the modern v3.0 variant which is PCI/MSI-X.

So this should be "Multi-MSI is not supported yet", no?

> +	if (nr_irqs > 1)
> +		return -ENOTSUPP;
> +
> +	vec = imsic_vector_alloc(virq, cpu_online_mask);
> +	if (!vec)
> +		return -ENOSPC;
> +
> +	irq_domain_set_info(domain, virq, virq,
> +			    &imsic_irq_base_chip, vec,
> +			    handle_simple_irq, NULL, NULL);

Please utilize the 100 characters.

> +	irq_set_noprobe(virq);
> +	irq_set_affinity(virq, cpu_online_mask);
> +
> +	return 0;
> +}

Thanks,

        tglx


From tglx at linutronix.de  Tue Feb 20 05:35:36 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 20 Feb 2024 14:35:36 +0100
Subject: [PATCH v13 08/13] irqchip/riscv-imsic: Add device MSI domain
 support for PCI devices
In-Reply-To: <20240220060718.823229-9-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-9-apatel@ventanamicro.com>
Message-ID: <8734tni7h3.ffs@tglx>

On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
>  static bool imsic_init_dev_msi_info(struct device *dev,
>  				    struct irq_domain *domain,
>  				    struct irq_domain *real_parent,
> @@ -218,6 +241,7 @@ static bool imsic_init_dev_msi_info(struct device *dev,
>  
>  	/* MSI parent domain specific settings */
>  	switch (real_parent->bus_token) {
> +	case DOMAIN_BUS_PCI_MSI:

	case DOMAIN_BUS_PCI_DEVICE_MSIX:

?

Thanks,

        tglx


From brgl at bgdev.pl  Tue Feb 20 05:38:33 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 20 Feb 2024 14:38:33 +0100
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <5a3f5e1b-8162-4619-a10b-d4711afe533b@sirena.org.uk>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk> <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
 <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk> <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>
 <5a3f5e1b-8162-4619-a10b-d4711afe533b@sirena.org.uk>
Message-ID: <CAMRc=MdTub4u0dm5PgTQPnYPuR=SRnh=ympEZqo_UyrQDrQw6w@mail.gmail.com>

On Tue, Feb 20, 2024 at 2:31?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Tue, Feb 20, 2024 at 12:16:10PM +0100, Bartosz Golaszewski wrote:
> > On Mon, Feb 19, 2024 at 8:59?PM Mark Brown <broonie at kernel.org> wrote:
> > > On Mon, Feb 19, 2024 at 07:48:20PM +0100, Bartosz Golaszewski wrote:
>
> > > > No, the users don't request any regulators (or rather: software
> > > > representations thereof) because - as per the cover letter - no
> > > > regulators are created by the PMU driver. This is what is physically
> > > > on the board - as the schematics and the datasheet define it. I took
>
> > > The above makes no sense.  How can constraints be "what is physically on
> > > the board", particularly variable constrants when there isn't even a
> > > consumer?  What values are you taking from which documentation?
>
> > The operating conditions for PMU outputs. I took them from a
> > confidential datasheet. There's a table for input constraints and
> > possible output values.
>
> That sounds like you're just putting the maximum range of voltages that
> the PMU can output in there.  This is a fundamental misunderstanding of
> what the constraints are for, the constraints exist to specify what is
> safe on a specific board which will in essentially all cases be much
> more restricted.  The regulator driver should describe whatever the PMU
> can support by itself, the constraints whatever is actually safe and
> functional on the specific board.
>

Ok, got it. Yeah I misunderstood that, but I think it's maybe the
second or third time I'm adding a regulators node myself to DT. I'll
change that.

> > And what do you mean by there not being any consumers? The WLAN and BT
> > *are* the consumers.
>
> There are no drivers that bind to the regulators and vary the voltages
> at runtime.
>

Even with the above misunderstanding clarified: so what? DT is the
representation of hardware. There's nothing that obligates us to model
DT sources in drivers 1:1.

> > > > the values from the docs verbatim. In C, we create a power sequencing
> > > > provider which doesn't use the regulator framework at all.
>
> > > For something that doesn't use the regulator framework at all what
> > > appears to be a provider in patch 16 ("power: pwrseq: add a driver for
> > > the QCA6390 PMU module") seems to have a lot of regualtor API calls?
>
> > This driver is a power sequencing *provider* but also a regulator
> > *consumer*. It gets regulators from the host and exposes a power
> > sequencer to *its* consumers (WLAN and BT). On DT it exposes
> > regulators (LDO outputs of the PMU) but we don't instantiate them in
> > C.
>
> Right, which sounds a lot like being a user of the regualtor framework.

Ok, I meant "user" as a regulator provider but maybe I wasn't clear enough.

Bart


From tglx at linutronix.de  Tue Feb 20 05:40:56 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 20 Feb 2024 14:40:56 +0100
Subject: [PATCH v13 10/13] irqchip: Add RISC-V advanced PLIC driver for
 direct-mode
In-Reply-To: <20240220060718.823229-11-apatel@ventanamicro.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-11-apatel@ventanamicro.com>
Message-ID: <87zfvvgsnr.ffs@tglx>

On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> +/*
> + * To handle an APLIC direct interrupts, we just read the CLAIMI register
> + * which will return highest priority pending interrupt and clear the
> + * pending bit of the interrupt. This process is repeated until CLAIMI
> + * register return zero value.
> + */
> +static void aplic_direct_handle_irq(struct irq_desc *desc)
> +{
> +	struct aplic_idc *idc = this_cpu_ptr(&aplic_idcs);
> +	struct irq_domain *irqdomain = idc->direct->irqdomain;
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	irq_hw_number_t hw_irq;
> +	int irq;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	while ((hw_irq = readl(idc->regs + APLIC_IDC_CLAIMI))) {
> +		hw_irq = hw_irq >> APLIC_IDC_TOPI_ID_SHIFT;
> +		irq = irq_find_mapping(irqdomain, hw_irq);
> +
> +		if (unlikely(irq <= 0))
> +			dev_warn_ratelimited(idc->direct->priv.dev,
> +					     "hw_irq %lu mapping not found\n", hw_irq);

Lacks brackets. See Documentation....

> +		else
> +			generic_handle_irq(irq);
> +	}
> +
> +static int aplic_direct_starting_cpu(unsigned int cpu)
> +{
> +	if (aplic_direct_parent_irq)
> +		enable_percpu_irq(aplic_direct_parent_irq,
> +				  irq_get_trigger_type(aplic_direct_parent_irq));

Ditto.

> +	return 0;
> +}

> +void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
> +{
> +	u32 val;
> +#ifdef CONFIG_RISCV_M_MODE
> +	u32 valH;

No camel case please.

> +
> +	if (msi_mode) {
> +		val = lower_32_bits(priv->msicfg.base_ppn);
> +		valH = FIELD_PREP(APLIC_xMSICFGADDRH_BAPPN, upper_32_bits(priv->msicfg.base_ppn));
> +		valH |= FIELD_PREP(APLIC_xMSICFGADDRH_LHXW, priv->msicfg.lhxw);
> +		valH |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXW, priv->msicfg.hhxw);
> +		valH |= FIELD_PREP(APLIC_xMSICFGADDRH_LHXS, priv->msicfg.lhxs);
> +		valH |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXS, priv->msicfg.hhxs);
> +		writel(val, priv->regs + APLIC_xMSICFGADDR);
> +		writel(valH, priv->regs + APLIC_xMSICFGADDRH);
> +	}

Thanks,

        tglx


From maz at kernel.org  Tue Feb 20 05:41:15 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 20 Feb 2024 13:41:15 +0000
Subject: [PATCH 02/13] KVM: arm64: Clarify ESR_ELx_ERET_ISS_ERET*
In-Reply-To: <20240220132350.GB8575@e124191.cambridge.arm.com>
References: <20240219092014.783809-1-maz@kernel.org>
	<20240219092014.783809-3-maz@kernel.org>
	<20240220113127.GB16168@e124191.cambridge.arm.com>
	<861q9748ut.wl-maz@kernel.org>
	<20240220132350.GB8575@e124191.cambridge.arm.com>
Message-ID: <86zfvv2qys.wl-maz@kernel.org>

On Tue, 20 Feb 2024 13:23:50 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> On Tue, Feb 20, 2024 at 12:29:30PM +0000, Marc Zyngier wrote:
> > On Tue, 20 Feb 2024 11:31:27 +0000,
> > Joey Gouly <joey.gouly at arm.com> wrote:
> > > 
> > > If this part is confusing due to the name, maybe introduce a function in esr.h
> > > esr_is_pac_eret() (name pending bikeshedding)?
> > 
> > That's indeed a better option. Now for the bikeshed aspect:
> > 
> > - esr_iss_is_eretax(): check for ESR_ELx_ERET_ISS_ERET being set
> > 
> > - esr_iss_is_eretab(): check for ESR_ELx_ERET_ISS_ERETA being set
> > 
> > Thoughts?
> > 
> 
> I was trying to avoid the ERETA* confusion by suggesting 'pac_eret', but if I
> were to pick between your options I'd pick esr_iss_is_eretax().

It's not an either/or situation. We actually need both:

- esr_iss_is_eretax() being true tells you that you need to
  authenticate the ERET

- esr_iss_is_eretab() tells you that you need to use the A or B key

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From broonie at kernel.org  Tue Feb 20 05:48:42 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 13:48:42 +0000
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <CAMRc=MdTub4u0dm5PgTQPnYPuR=SRnh=ympEZqo_UyrQDrQw6w@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk>
 <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
 <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk>
 <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>
 <5a3f5e1b-8162-4619-a10b-d4711afe533b@sirena.org.uk>
 <CAMRc=MdTub4u0dm5PgTQPnYPuR=SRnh=ympEZqo_UyrQDrQw6w@mail.gmail.com>
Message-ID: <f72723f3-f5c5-4c16-a257-e5f57c4f9e73@sirena.org.uk>

On Tue, Feb 20, 2024 at 02:38:33PM +0100, Bartosz Golaszewski wrote:
> On Tue, Feb 20, 2024 at 2:31?PM Mark Brown <broonie at kernel.org> wrote:
> > On Tue, Feb 20, 2024 at 12:16:10PM +0100, Bartosz Golaszewski wrote:

> > > And what do you mean by there not being any consumers? The WLAN and BT
> > > *are* the consumers.

> > There are no drivers that bind to the regulators and vary the voltages
> > at runtime.

> Even with the above misunderstanding clarified: so what? DT is the
> representation of hardware. There's nothing that obligates us to model
> DT sources in drivers 1:1.

It is generally a bad sign if there is a voltage range specified on a
regulator that's not got any indication that the voltage is going to be
actively managed, especially in situations like with several of the
supplies the DT was specifying where there are clear indications that
the supply is intended to be fixed voltage (or cases where every single
supply has a voltage range which would be highly unusual).  Looking at
the consumers might provide an explanation for such unusual and likely
incorrect constraints, and the lack of any consumers in conjunction with 
other warning signs reenforces those warning signs.
-------------- 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/20240220/691aa0db/attachment-0001.sig>

From broonie at kernel.org  Tue Feb 20 05:49:44 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 13:49:44 +0000
Subject: [PATCH 1/1] phy: fsl-imx8mq-usb: make vbus regulator optional
In-Reply-To: <20240220111948.2227506-1-alexander.stein@ew.tq-group.com>
References: <20240220111948.2227506-1-alexander.stein@ew.tq-group.com>
Message-ID: <3b65d837-3614-443b-8298-2bf367c781c4@sirena.org.uk>

On Tue, Feb 20, 2024 at 12:19:48PM +0100, Alexander Stein wrote:

> vbus-supply property is optional, so instead of allocating a
> dummy regulator make it pure optional.

In general supplies should not be optional unless they may reasonably be
physically absent which is highly unusual.
-------------- 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/20240220/96fe10a9/attachment.sig>

From brgl at bgdev.pl  Tue Feb 20 05:51:25 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 20 Feb 2024 14:51:25 +0100
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <f72723f3-f5c5-4c16-a257-e5f57c4f9e73@sirena.org.uk>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk> <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
 <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk> <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>
 <5a3f5e1b-8162-4619-a10b-d4711afe533b@sirena.org.uk> <CAMRc=MdTub4u0dm5PgTQPnYPuR=SRnh=ympEZqo_UyrQDrQw6w@mail.gmail.com>
 <f72723f3-f5c5-4c16-a257-e5f57c4f9e73@sirena.org.uk>
Message-ID: <CAMRc=McFCauVwpATbVqCOtpyP_buKQDiN0OdZP9EfXmc3CgSUA@mail.gmail.com>

On Tue, Feb 20, 2024 at 2:48?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Tue, Feb 20, 2024 at 02:38:33PM +0100, Bartosz Golaszewski wrote:
> > On Tue, Feb 20, 2024 at 2:31?PM Mark Brown <broonie at kernel.org> wrote:
> > > On Tue, Feb 20, 2024 at 12:16:10PM +0100, Bartosz Golaszewski wrote:
>
> > > > And what do you mean by there not being any consumers? The WLAN and BT
> > > > *are* the consumers.
>
> > > There are no drivers that bind to the regulators and vary the voltages
> > > at runtime.
>
> > Even with the above misunderstanding clarified: so what? DT is the
> > representation of hardware. There's nothing that obligates us to model
> > DT sources in drivers 1:1.
>
> It is generally a bad sign if there is a voltage range specified on a
> regulator that's not got any indication that the voltage is going to be
> actively managed, especially in situations like with several of the
> supplies the DT was specifying where there are clear indications that
> the supply is intended to be fixed voltage (or cases where every single
> supply has a voltage range which would be highly unusual).  Looking at
> the consumers might provide an explanation for such unusual and likely
> incorrect constraints, and the lack of any consumers in conjunction with
> other warning signs reenforces those warning signs.

What do you recommend? No values at all in these regulators as it's
the PMU which will manage those on its own once powered up by the host
PMIC?

Bartosz


From will at kernel.org  Tue Feb 20 06:04:38 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 20 Feb 2024 14:04:38 +0000
Subject: [PATCH v3 0/2] arm64/sme: Fix handling of traps on resume
In-Reply-To: <20240213-arm64-sme-resume-v3-0-17e05e493471@kernel.org>
References: <20240213-arm64-sme-resume-v3-0-17e05e493471@kernel.org>
Message-ID: <170843155702.2619064.8773471291853791364.b4-ty@kernel.org>

On Tue, 13 Feb 2024 23:06:31 +0000, Mark Brown wrote:
> The fast model was recently changed to reset system registers to 0 on
> resume, exposing the fact that for SME we do not restore the
> configuration of traps for extensions that add state.  Fix this.
> 
> 

Applied to arm64 (for-next/fixes), thanks!

[1/2] arm64/sme: Restore SME registers on exit from suspend
      https://git.kernel.org/arm64/c/9533864816fb
[2/2] arm64/sme: Restore SMCR_EL1.EZT0 on exit from suspend
      https://git.kernel.org/arm64/c/d7b77a0d565b

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Tue Feb 20 06:04:39 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 20 Feb 2024 14:04:39 +0000
Subject: [PATCH v3] perf: CXL: fix CPMU filter value mask length
In-Reply-To: <20240216014522.32321-1-hj96.nam@samsung.com>
References: <CGME20240216014507epcas2p41686c0ccb1fa73715499e45bbbc7d7e9@epcas2p4.samsung.com> <20240216014522.32321-1-hj96.nam@samsung.com>
Message-ID: <170843064764.2617406.4906791201590222748.b4-ty@kernel.org>

On Fri, 16 Feb 2024 10:45:22 +0900, hj96.nam at samsung.com wrote:
> From: Hojin Nam <hj96.nam at samsung.com>
> 
> CPMU filter value is described as 4B length in CXL r3.0 8.2.7.2.2.
> However, it is used as 2B length in code and comments.
> 
> 

Applied to arm64 (for-next/fixes), thanks!

[1/1] perf: CXL: fix CPMU filter value mask length
      https://git.kernel.org/arm64/c/802379b8f9e1

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From javier.carrasco at wolfvision.net  Tue Feb 20 06:05:44 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Tue, 20 Feb 2024 15:05:44 +0100
Subject: [PATCH v4 0/8] usb: misc: onboard_hub: add support for XMOS
 XVF3500
Message-ID: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>

This series adds support for the XMOS XVF3500 VocalFusion Voice
Processor[1], a low-latency, 32-bit multicore controller for voice
processing.

The XVF3500 requires a specific power sequence, which consists of
enabling the regulators that control the 3V3 and 1V0 device supplies,
and a reset de-assertion after a delay of at least 100ns. Once in normal
operation, the XVF3500 registers itself as a regular USB device and no
device-specific management is required.

The power management provided by onboard_usb_hub is not specific for hubs
and any other USB device with the same power sequence could profit from
that driver, provided that the device does not have any specific
requirements beyond the power management. To account for non-hub devices,
the driver has been renamed and an extra flag has been added to identify
hubs and provide their specific functionality. Support for
device-specific power suply names has been added, keeping generic names
for backwards compatibility and as a fallback mechanism.

The references to onboard_usb_hub in the core and config files have been
updated as well.

The diff is way much bulkier than the actual code addition because of the
file renaming, so in order to ease reviews and catch hub-specific code
that might still affect non-hub devices, the complete renaming was moved
to a single commit.

The device binding has been added to sound/ because it is the subsystem
that covers its functionality (voice processing) during normal
operation. If it should reside under usb/ instead, it will be moved as
required.

This series has been tested with a Rockchip-based SoC and an XMOS
XVF3500-FB167-C.

[1] https://www.xmos.com/xvf3500/

To: Liam Girdwood <lgirdwood at gmail.com>
To: Mark Brown <broonie at kernel.org>
To: Rob Herring <robh+dt at kernel.org>
To: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
To: Conor Dooley <conor+dt at kernel.org>
To: Matthias Kaehlcke <mka at chromium.org>
To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
To: Helen Koike <helen.koike at collabora.com>
To: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
To: Maxime Ripard <mripard at kernel.org>
To: Thomas Zimmermann <tzimmermann at suse.de>
To: David Airlie <airlied at gmail.com>
To: Daniel Vetter <daniel at ffwll.ch>
To: Catalin Marinas <catalin.marinas at arm.com>
To: Will Deacon <will at kernel.org>
To: Russell King <linux at armlinux.org.uk>
Cc: linux-sound at vger.kernel.org
Cc: devicetree at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-usb at vger.kernel.org
Cc: dri-devel at lists.freedesktop.org
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>

Changes in v4:
- General: use device supply names and generics as fallback.
- onbord_usb_dev.c: fix suspend callback for non-hub devices.
- onboard_usb_dev.c: fix typos.

- Link to v3: https://lore.kernel.org/r/20240206-onboard_xvf3500-v3-0-f85b04116688 at wolfvision.net

Changes in v3:
- onboard_usb_hub: rename to onboard_usb_dev to include non-hub devices.
- onboard_hub_dev: add flag to identify hubs and provide their extra
  functionality.
- dt-bindings: add reference to usb-device.yaml and usb node in the
  example.
- dt-bindings: generic node name.
- Link to v2: https://lore.kernel.org/r/20240130-onboard_xvf3500-v1-0-51b5398406cb at wolfvision.net

Changes in v2:
- general: add support in onboard_usb_hub instead of using a dedicated
  driver.
- dt-bindings: use generic usb-device compatible ("usbVID,PID").
- Link to v1: https://lore.kernel.org/all/20240115-feature-xvf3500_driver-v1-0-ed9cfb48bb85 at wolfvision.net/

---
Javier Carrasco (8):
      usb: misc: onboard_hub: rename to onboard_dev
      usb: misc: onboard_dev: add support for non-hub devices
      drm: ci: arm64.config: update ONBOARD_USB_HUB to ONBOARD_USB_DEV
      arm64: defconfig: update ONBOARD_USB_HUB to ONBOARD_USB_DEV
      ARM: multi_v7_defconfig: update ONBOARD_USB_HUB name
      usb: misc: onboard_dev: use device supply names
      ASoC: dt-bindings: xmos,xvf3500: add XMOS XVF3500 voice processor
      usb: misc: onboard_hub: add support for XMOS XVF3500

 ...-usb-hub => sysfs-bus-platform-onboard-usb-dev} |   4 +-
 .../devicetree/bindings/sound/xmos,xvf3500.yaml    |  63 +++
 MAINTAINERS                                        |   4 +-
 arch/arm/configs/multi_v7_defconfig                |   2 +-
 arch/arm64/configs/defconfig                       |   2 +-
 drivers/gpu/drm/ci/arm64.config                    |   4 +-
 drivers/usb/core/Makefile                          |   4 +-
 drivers/usb/core/hub.c                             |   8 +-
 drivers/usb/core/hub.h                             |   2 +-
 drivers/usb/misc/Kconfig                           |  16 +-
 drivers/usb/misc/Makefile                          |   2 +-
 drivers/usb/misc/onboard_usb_dev.c                 | 525 +++++++++++++++++++++
 .../misc/{onboard_usb_hub.h => onboard_usb_dev.h}  |  69 ++-
 ...ard_usb_hub_pdevs.c => onboard_usb_dev_pdevs.c} |  47 +-
 drivers/usb/misc/onboard_usb_hub.c                 | 501 --------------------
 include/linux/usb/onboard_dev.h                    |  18 +
 include/linux/usb/onboard_hub.h                    |  18 -
 17 files changed, 709 insertions(+), 580 deletions(-)
---
base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
change-id: 20240130-onboard_xvf3500-6c0e78d11a1b

Best regards,
-- 
Javier Carrasco <javier.carrasco at wolfvision.net>



From javier.carrasco at wolfvision.net  Tue Feb 20 06:05:45 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Tue, 20 Feb 2024 15:05:45 +0100
Subject: [PATCH v4 1/8] usb: misc: onboard_hub: rename to onboard_dev
In-Reply-To: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
Message-ID: <20240220-onboard_xvf3500-v4-1-dc1617cc5dd4@wolfvision.net>

This patch prepares onboad_hub to support non-hub devices by renaming
the driver files and their content, the headers and their references.

The comments and descriptions have been slightly modified to keep
coherence and account for the specific cases that only affect onboard
hubs (e.g. peer-hub).

The "hub" variables in functions where "dev" (and similar names) variables
already exist have been renamed to onboard_dev for clarity, which adds a
few lines in cases where more than 80 characters are used.

No new functionality has been added.

Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
---
 ...-usb-hub => sysfs-bus-platform-onboard-usb-dev} |   4 +-
 MAINTAINERS                                        |   4 +-
 drivers/usb/core/Makefile                          |   4 +-
 drivers/usb/core/hub.c                             |   8 +-
 drivers/usb/core/hub.h                             |   2 +-
 drivers/usb/misc/Kconfig                           |  16 +-
 drivers/usb/misc/Makefile                          |   2 +-
 drivers/usb/misc/onboard_usb_dev.c                 | 518 +++++++++++++++++++++
 .../misc/{onboard_usb_hub.h => onboard_usb_dev.h}  |  28 +-
 ...ard_usb_hub_pdevs.c => onboard_usb_dev_pdevs.c} |  47 +-
 drivers/usb/misc/onboard_usb_hub.c                 | 501 --------------------
 include/linux/usb/onboard_dev.h                    |  18 +
 include/linux/usb/onboard_hub.h                    |  18 -
 13 files changed, 594 insertions(+), 576 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-hub b/Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-dev
similarity index 67%
rename from Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-hub
rename to Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-dev
index 42deb0552065..cd31f76362e7 100644
--- a/Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-hub
+++ b/Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-dev
@@ -4,5 +4,5 @@ KernelVersion:	5.20
 Contact:	Matthias Kaehlcke <matthias at kaehlcke.net>
 		linux-usb at vger.kernel.org
 Description:
-		(RW) Controls whether the USB hub remains always powered
-		during system suspend or not.
\ No newline at end of file
+		(RW) Controls whether the USB device remains always powered
+		during system suspend or not.
diff --git a/MAINTAINERS b/MAINTAINERS
index 8999497011a2..7ad556ecca40 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16297,8 +16297,8 @@ ONBOARD USB HUB DRIVER
 M:	Matthias Kaehlcke <mka at chromium.org>
 L:	linux-usb at vger.kernel.org
 S:	Maintained
-F:	Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-hub
-F:	drivers/usb/misc/onboard_usb_hub.c
+F:	Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-dev
+F:	drivers/usb/misc/onboard_usb_dev.c
 
 ONENAND FLASH DRIVER
 M:	Kyungmin Park <kyungmin.park at samsung.com>
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 7d338e9c0657..ac006abd13b3 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -12,8 +12,8 @@ usbcore-$(CONFIG_OF)		+= of.o
 usbcore-$(CONFIG_USB_PCI)		+= hcd-pci.o
 usbcore-$(CONFIG_ACPI)		+= usb-acpi.o
 
-ifdef CONFIG_USB_ONBOARD_HUB
-usbcore-y			+= ../misc/onboard_usb_hub_pdevs.o
+ifdef CONFIG_USB_ONBOARD_DEV
+usbcore-y			+= ../misc/onboard_usb_dev_pdevs.o
 endif
 
 obj-$(CONFIG_USB)		+= usbcore.o
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index ffd7c99e24a3..f85b3e928a35 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -23,7 +23,7 @@
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/usb/hcd.h>
-#include <linux/usb/onboard_hub.h>
+#include <linux/usb/onboard_dev.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/quirks.h>
 #include <linux/workqueue.h>
@@ -1776,7 +1776,7 @@ static void hub_disconnect(struct usb_interface *intf)
 	if (hub->quirk_disable_autosuspend)
 		usb_autopm_put_interface(intf);
 
-	onboard_hub_destroy_pdevs(&hub->onboard_hub_devs);
+	onboard_dev_destroy_pdevs(&hub->onboard_devs);
 
 	kref_put(&hub->kref, hub_release);
 }
@@ -1895,7 +1895,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	INIT_DELAYED_WORK(&hub->leds, led_work);
 	INIT_DELAYED_WORK(&hub->init_work, NULL);
 	INIT_WORK(&hub->events, hub_event);
-	INIT_LIST_HEAD(&hub->onboard_hub_devs);
+	INIT_LIST_HEAD(&hub->onboard_devs);
 	spin_lock_init(&hub->irq_urb_lock);
 	timer_setup(&hub->irq_urb_retry, hub_retry_irq_urb, 0);
 	usb_get_intf(intf);
@@ -1925,7 +1925,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	}
 
 	if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) {
-		onboard_hub_create_pdevs(hdev, &hub->onboard_hub_devs);
+		onboard_dev_create_pdevs(hdev, &hub->onboard_devs);
 
 		return 0;
 	}
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 43ce21c96a51..3820703b11d8 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -74,7 +74,7 @@ struct usb_hub {
 	spinlock_t		irq_urb_lock;
 	struct timer_list	irq_urb_retry;
 	struct usb_port		**ports;
-	struct list_head        onboard_hub_devs;
+	struct list_head        onboard_devs;
 };
 
 /**
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index c510af7baa0d..50b86d531701 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -316,18 +316,18 @@ config BRCM_USB_PINMAP
 	  signals, which are typically on dedicated pins on the chip,
 	  to any gpio.
 
-config USB_ONBOARD_HUB
-	tristate "Onboard USB hub support"
+config USB_ONBOARD_DEV
+	tristate "Onboard USB device support"
 	depends on OF
 	help
-	  Say Y here if you want to support discrete onboard USB hubs that
-	  don't require an additional control bus for initialization, but
-	  need some non-trivial form of initialization, such as enabling a
-	  power regulator. An example for such a hub is the Realtek
-	  RTS5411.
+	  Say Y here if you want to support discrete onboard USB devices
+	  that don't require an additional control bus for initialization,
+	  but need some non-trivial form of initialization, such as
+	  enabling a power regulator. An example for such device is the
+	  Realtek RTS5411 hub.
 
 	  This driver can be used as a module but its state (module vs
 	  builtin) must match the state of the USB subsystem. Enabling
 	  this config will enable the driver and it will automatically
 	  match the state of the USB subsystem. If this driver is a
-	  module it will be called onboard_usb_hub.
+	  module it will be called onboard_usb_dev.
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 0bc732bcb162..0cd5bc8f52fe 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -33,4 +33,4 @@ obj-$(CONFIG_USB_CHAOSKEY)		+= chaoskey.o
 obj-$(CONFIG_USB_SISUSBVGA)		+= sisusbvga/
 obj-$(CONFIG_USB_LINK_LAYER_TEST)	+= lvstest.o
 obj-$(CONFIG_BRCM_USB_PINMAP)		+= brcmstb-usb-pinmap.o
-obj-$(CONFIG_USB_ONBOARD_HUB)		+= onboard_usb_hub.o
+obj-$(CONFIG_USB_ONBOARD_DEV)		+= onboard_usb_dev.o
diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
new file mode 100644
index 000000000000..2103af2cb2a6
--- /dev/null
+++ b/drivers/usb/misc/onboard_usb_dev.c
@@ -0,0 +1,518 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for onboard USB devices
+ *
+ * Copyright (c) 2022, Google LLC
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include <linux/sysfs.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/onboard_dev.h>
+#include <linux/workqueue.h>
+
+#include "onboard_usb_dev.h"
+
+/*
+ * Use generic names, as the actual names might differ between devices. If a new
+ * device requires more than the currently supported supplies, add a new one
+ * here.
+ */
+static const char * const supply_names[] = {
+	"vdd",
+	"vdd2",
+};
+
+#define MAX_SUPPLIES ARRAY_SIZE(supply_names)
+
+static void onboard_dev_attach_usb_driver(struct work_struct *work);
+
+static struct usb_device_driver onboard_dev_usbdev_driver;
+static DECLARE_WORK(attach_usb_driver_work, onboard_dev_attach_usb_driver);
+
+/************************** Platform driver **************************/
+
+struct usbdev_node {
+	struct usb_device *udev;
+	struct list_head list;
+};
+
+struct onboard_dev {
+	struct regulator_bulk_data supplies[MAX_SUPPLIES];
+	struct device *dev;
+	const struct onboard_dev_pdata *pdata;
+	struct gpio_desc *reset_gpio;
+	bool always_powered_in_suspend;
+	bool is_powered_on;
+	bool going_away;
+	struct list_head udev_list;
+	struct mutex lock;
+	struct clk *clk;
+};
+
+static int onboard_dev_power_on(struct onboard_dev *onboard_dev)
+{
+	int err;
+
+	err = clk_prepare_enable(onboard_dev->clk);
+	if (err) {
+		dev_err(onboard_dev->dev, "failed to enable clock: %pe\n",
+			ERR_PTR(err));
+		return err;
+	}
+
+	err = regulator_bulk_enable(onboard_dev->pdata->num_supplies,
+				    onboard_dev->supplies);
+	if (err) {
+		dev_err(onboard_dev->dev, "failed to enable supplies: %pe\n",
+			ERR_PTR(err));
+		return err;
+	}
+
+	fsleep(onboard_dev->pdata->reset_us);
+	gpiod_set_value_cansleep(onboard_dev->reset_gpio, 0);
+
+	onboard_dev->is_powered_on = true;
+
+	return 0;
+}
+
+static int onboard_dev_power_off(struct onboard_dev *onboard_dev)
+{
+	int err;
+
+	gpiod_set_value_cansleep(onboard_dev->reset_gpio, 1);
+
+	err = regulator_bulk_disable(onboard_dev->pdata->num_supplies,
+				     onboard_dev->supplies);
+	if (err) {
+		dev_err(onboard_dev->dev, "failed to disable supplies: %pe\n",
+			ERR_PTR(err));
+		return err;
+	}
+
+	clk_disable_unprepare(onboard_dev->clk);
+
+	onboard_dev->is_powered_on = false;
+
+	return 0;
+}
+
+static int __maybe_unused onboard_dev_suspend(struct device *dev)
+{
+	struct onboard_dev *onboard_dev = dev_get_drvdata(dev);
+	struct usbdev_node *node;
+	bool power_off = true;
+
+	if (onboard_dev->always_powered_in_suspend)
+		return 0;
+
+	mutex_lock(&onboard_dev->lock);
+
+	list_for_each_entry(node, &onboard_dev->udev_list, list) {
+		if (!device_may_wakeup(node->udev->bus->controller))
+			continue;
+
+		if (usb_wakeup_enabled_descendants(node->udev)) {
+			power_off = false;
+			break;
+		}
+	}
+
+	mutex_unlock(&onboard_dev->lock);
+
+	if (!power_off)
+		return 0;
+
+	return onboard_dev_power_off(onboard_dev);
+}
+
+static int __maybe_unused onboard_dev_resume(struct device *dev)
+{
+	struct onboard_dev *onboard_dev = dev_get_drvdata(dev);
+
+	if (onboard_dev->is_powered_on)
+		return 0;
+
+	return onboard_dev_power_on(onboard_dev);
+}
+
+static inline void get_udev_link_name(const struct usb_device *udev, char *buf,
+				      size_t size)
+{
+	snprintf(buf, size, "usb_dev.%s", dev_name(&udev->dev));
+}
+
+static int onboard_dev_add_usbdev(struct onboard_dev *onboard_dev,
+				  struct usb_device *udev)
+{
+	struct usbdev_node *node;
+	char link_name[64];
+	int err;
+
+	mutex_lock(&onboard_dev->lock);
+
+	if (onboard_dev->going_away) {
+		err = -EINVAL;
+		goto error;
+	}
+
+	node = kzalloc(sizeof(*node), GFP_KERNEL);
+	if (!node) {
+		err = -ENOMEM;
+		goto error;
+	}
+
+	node->udev = udev;
+
+	list_add(&node->list, &onboard_dev->udev_list);
+
+	mutex_unlock(&onboard_dev->lock);
+
+	get_udev_link_name(udev, link_name, sizeof(link_name));
+	WARN_ON(sysfs_create_link(&onboard_dev->dev->kobj, &udev->dev.kobj,
+				  link_name));
+
+	return 0;
+
+error:
+	mutex_unlock(&onboard_dev->lock);
+
+	return err;
+}
+
+static void onboard_dev_remove_usbdev(struct onboard_dev *onboard_dev,
+				      const struct usb_device *udev)
+{
+	struct usbdev_node *node;
+	char link_name[64];
+
+	get_udev_link_name(udev, link_name, sizeof(link_name));
+	sysfs_remove_link(&onboard_dev->dev->kobj, link_name);
+
+	mutex_lock(&onboard_dev->lock);
+
+	list_for_each_entry(node, &onboard_dev->udev_list, list) {
+		if (node->udev == udev) {
+			list_del(&node->list);
+			kfree(node);
+			break;
+		}
+	}
+
+	mutex_unlock(&onboard_dev->lock);
+}
+
+static ssize_t always_powered_in_suspend_show(struct device *dev,
+					      struct device_attribute *attr,
+					      char *buf)
+{
+	const struct onboard_dev *onboard_dev = dev_get_drvdata(dev);
+
+	return sysfs_emit(buf, "%d\n", onboard_dev->always_powered_in_suspend);
+}
+
+static ssize_t always_powered_in_suspend_store(struct device *dev,
+					       struct device_attribute *attr,
+					       const char *buf, size_t count)
+{
+	struct onboard_dev *onboard_dev = dev_get_drvdata(dev);
+	bool val;
+	int ret;
+
+	ret = kstrtobool(buf, &val);
+	if (ret < 0)
+		return ret;
+
+	onboard_dev->always_powered_in_suspend = val;
+
+	return count;
+}
+static DEVICE_ATTR_RW(always_powered_in_suspend);
+
+static struct attribute *onboard_dev_attrs[] = {
+	&dev_attr_always_powered_in_suspend.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(onboard_dev);
+
+static void onboard_dev_attach_usb_driver(struct work_struct *work)
+{
+	int err;
+
+	err = driver_attach(&onboard_dev_usbdev_driver.driver);
+	if (err)
+		pr_err("Failed to attach USB driver: %pe\n", ERR_PTR(err));
+}
+
+static int onboard_dev_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct onboard_dev *onboard_dev;
+	unsigned int i;
+	int err;
+
+	onboard_dev = devm_kzalloc(dev, sizeof(*onboard_dev), GFP_KERNEL);
+	if (!onboard_dev)
+		return -ENOMEM;
+
+	onboard_dev->pdata = device_get_match_data(&pdev->dev);
+	if (!onboard_dev->pdata)
+		return -EINVAL;
+
+	if (onboard_dev->pdata->num_supplies > MAX_SUPPLIES)
+		return dev_err_probe(dev, -EINVAL, "max %zu supplies supported!\n",
+				     MAX_SUPPLIES);
+
+	for (i = 0; i < onboard_dev->pdata->num_supplies; i++)
+		onboard_dev->supplies[i].supply = supply_names[i];
+
+	err = devm_regulator_bulk_get(dev, onboard_dev->pdata->num_supplies,
+				      onboard_dev->supplies);
+	if (err) {
+		dev_err(dev, "Failed to get regulator supplies: %pe\n", ERR_PTR(err));
+		return err;
+	}
+
+	onboard_dev->clk = devm_clk_get_optional(dev, NULL);
+	if (IS_ERR(onboard_dev->clk))
+		return dev_err_probe(dev, PTR_ERR(onboard_dev->clk),
+				     "failed to get clock\n");
+
+	onboard_dev->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+							  GPIOD_OUT_HIGH);
+	if (IS_ERR(onboard_dev->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(onboard_dev->reset_gpio),
+				     "failed to get reset GPIO\n");
+
+	onboard_dev->dev = dev;
+	mutex_init(&onboard_dev->lock);
+	INIT_LIST_HEAD(&onboard_dev->udev_list);
+
+	dev_set_drvdata(dev, onboard_dev);
+
+	err = onboard_dev_power_on(onboard_dev);
+	if (err)
+		return err;
+
+	/*
+	 * The USB driver might have been detached from the USB devices by
+	 * onboard_dev_remove() (e.g. through an 'unbind' by userspace),
+	 * make sure to re-attach it if needed.
+	 *
+	 * This needs to be done deferred to avoid self-deadlocks on systems
+	 * with nested onboard hubs.
+	 */
+	schedule_work(&attach_usb_driver_work);
+
+	return 0;
+}
+
+static void onboard_dev_remove(struct platform_device *pdev)
+{
+	struct onboard_dev *onboard_dev = dev_get_drvdata(&pdev->dev);
+	struct usbdev_node *node;
+	struct usb_device *udev;
+
+	onboard_dev->going_away = true;
+
+	mutex_lock(&onboard_dev->lock);
+
+	/* unbind the USB devices to avoid dangling references to this device */
+	while (!list_empty(&onboard_dev->udev_list)) {
+		node = list_first_entry(&onboard_dev->udev_list,
+					struct usbdev_node, list);
+		udev = node->udev;
+
+		/*
+		 * Unbinding the driver will call onboard_dev_remove_usbdev(),
+		 * which acquires onboard_dev->lock. We must release the lock
+		 * first.
+		 */
+		get_device(&udev->dev);
+		mutex_unlock(&onboard_dev->lock);
+		device_release_driver(&udev->dev);
+		put_device(&udev->dev);
+		mutex_lock(&onboard_dev->lock);
+	}
+
+	mutex_unlock(&onboard_dev->lock);
+
+	onboard_dev_power_off(onboard_dev);
+}
+
+MODULE_DEVICE_TABLE(of, onboard_dev_match);
+
+static const struct dev_pm_ops __maybe_unused onboard_dev_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(onboard_dev_suspend, onboard_dev_resume)
+};
+
+static struct platform_driver onboard_dev_driver = {
+	.probe = onboard_dev_probe,
+	.remove_new = onboard_dev_remove,
+
+	.driver = {
+		.name = "onboard-usb-dev",
+		.of_match_table = onboard_dev_match,
+		.pm = pm_ptr(&onboard_dev_pm_ops),
+		.dev_groups = onboard_dev_groups,
+	},
+};
+
+/************************** USB driver **************************/
+
+#define VENDOR_ID_CYPRESS	0x04b4
+#define VENDOR_ID_GENESYS	0x05e3
+#define VENDOR_ID_MICROCHIP	0x0424
+#define VENDOR_ID_REALTEK	0x0bda
+#define VENDOR_ID_TI		0x0451
+#define VENDOR_ID_VIA		0x2109
+
+/*
+ * Returns the onboard_dev platform device that is associated with the USB
+ * device passed as parameter.
+ */
+static struct onboard_dev *_find_onboard_dev(struct device *dev)
+{
+	struct platform_device *pdev;
+	struct device_node *np;
+	struct onboard_dev *onboard_dev;
+
+	pdev = of_find_device_by_node(dev->of_node);
+	if (!pdev) {
+		np = of_parse_phandle(dev->of_node, "peer-hub", 0);
+		if (!np) {
+			dev_err(dev, "failed to find device node for peer hub\n");
+			return ERR_PTR(-EINVAL);
+		}
+
+		pdev = of_find_device_by_node(np);
+		of_node_put(np);
+
+		if (!pdev)
+			return ERR_PTR(-ENODEV);
+	}
+
+	onboard_dev = dev_get_drvdata(&pdev->dev);
+	put_device(&pdev->dev);
+
+	/*
+	 * The presence of drvdata ('hub') indicates that the platform driver
+	 * finished probing. This handles the case where (conceivably) we could
+	 * be running at the exact same time as the platform driver's probe. If
+	 * we detect the race we request probe deferral and we'll come back and
+	 * try again.
+	 */
+	if (!onboard_dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return onboard_dev;
+}
+
+static int onboard_dev_usbdev_probe(struct usb_device *udev)
+{
+	struct device *dev = &udev->dev;
+	struct onboard_dev *onboard_dev;
+	int err;
+
+	/* ignore supported devices without device tree node */
+	if (!dev->of_node)
+		return -ENODEV;
+
+	onboard_dev = _find_onboard_dev(dev);
+	if (IS_ERR(onboard_dev))
+		return PTR_ERR(onboard_dev);
+
+	dev_set_drvdata(dev, onboard_dev);
+
+	err = onboard_dev_add_usbdev(onboard_dev, udev);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static void onboard_dev_usbdev_disconnect(struct usb_device *udev)
+{
+	struct onboard_dev *onboard_dev = dev_get_drvdata(&udev->dev);
+
+	onboard_dev_remove_usbdev(onboard_dev, udev);
+}
+
+static const struct usb_device_id onboard_dev_id_table[] = {
+	{ USB_DEVICE(VENDOR_ID_CYPRESS, 0x6504) }, /* CYUSB33{0,1,2}x/CYUSB230x 3.0 */
+	{ USB_DEVICE(VENDOR_ID_CYPRESS, 0x6506) }, /* CYUSB33{0,1,2}x/CYUSB230x 2.0 */
+	{ USB_DEVICE(VENDOR_ID_CYPRESS, 0x6570) }, /* CY7C6563x 2.0 */
+	{ USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 */
+	{ USB_DEVICE(VENDOR_ID_GENESYS, 0x0610) }, /* Genesys Logic GL852G USB 2.0 */
+	{ USB_DEVICE(VENDOR_ID_GENESYS, 0x0620) }, /* Genesys Logic GL3523 USB 3.1 */
+	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2412) }, /* USB2412 USB 2.0 */
+	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 */
+	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 */
+	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2744) }, /* USB5744 USB 2.0 */
+	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x5744) }, /* USB5744 USB 3.0 */
+	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x0411) }, /* RTS5411 USB 3.1 */
+	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x5411) }, /* RTS5411 USB 2.1 */
+	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x0414) }, /* RTS5414 USB 3.2 */
+	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x5414) }, /* RTS5414 USB 2.1 */
+	{ USB_DEVICE(VENDOR_ID_TI, 0x8140) }, /* TI USB8041 3.0 */
+	{ USB_DEVICE(VENDOR_ID_TI, 0x8142) }, /* TI USB8041 2.0 */
+	{ USB_DEVICE(VENDOR_ID_VIA, 0x0817) }, /* VIA VL817 3.1 */
+	{ USB_DEVICE(VENDOR_ID_VIA, 0x2817) }, /* VIA VL817 2.0 */
+	{}
+};
+MODULE_DEVICE_TABLE(usb, onboard_dev_id_table);
+
+static struct usb_device_driver onboard_dev_usbdev_driver = {
+	.name = "onboard-usb-dev",
+	.probe = onboard_dev_usbdev_probe,
+	.disconnect = onboard_dev_usbdev_disconnect,
+	.generic_subclass = 1,
+	.supports_autosuspend =	1,
+	.id_table = onboard_dev_id_table,
+};
+
+static int __init onboard_dev_init(void)
+{
+	int ret;
+
+	ret = usb_register_device_driver(&onboard_dev_usbdev_driver, THIS_MODULE);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&onboard_dev_driver);
+	if (ret)
+		usb_deregister_device_driver(&onboard_dev_usbdev_driver);
+
+	return ret;
+}
+module_init(onboard_dev_init);
+
+static void __exit onboard_dev_exit(void)
+{
+	usb_deregister_device_driver(&onboard_dev_usbdev_driver);
+	platform_driver_unregister(&onboard_dev_driver);
+
+	cancel_work_sync(&attach_usb_driver_work);
+}
+module_exit(onboard_dev_exit);
+
+MODULE_AUTHOR("Matthias Kaehlcke <mka at chromium.org>");
+MODULE_DESCRIPTION("Driver for discrete onboard USB devices");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/misc/onboard_usb_hub.h b/drivers/usb/misc/onboard_usb_dev.h
similarity index 71%
rename from drivers/usb/misc/onboard_usb_hub.h
rename to drivers/usb/misc/onboard_usb_dev.h
index f360d5cf8d8a..f13d11a84371 100644
--- a/drivers/usb/misc/onboard_usb_hub.h
+++ b/drivers/usb/misc/onboard_usb_dev.h
@@ -3,60 +3,60 @@
  * Copyright (c) 2022, Google LLC
  */
 
-#ifndef _USB_MISC_ONBOARD_USB_HUB_H
-#define _USB_MISC_ONBOARD_USB_HUB_H
+#ifndef _USB_MISC_ONBOARD_USB_DEV_H
+#define _USB_MISC_ONBOARD_USB_DEV_H
 
-struct onboard_hub_pdata {
+struct onboard_dev_pdata {
 	unsigned long reset_us;		/* reset pulse width in us */
 	unsigned int num_supplies;	/* number of supplies */
 };
 
-static const struct onboard_hub_pdata microchip_usb424_data = {
+static const struct onboard_dev_pdata microchip_usb424_data = {
 	.reset_us = 1,
 	.num_supplies = 1,
 };
 
-static const struct onboard_hub_pdata microchip_usb5744_data = {
+static const struct onboard_dev_pdata microchip_usb5744_data = {
 	.reset_us = 0,
 	.num_supplies = 2,
 };
 
-static const struct onboard_hub_pdata realtek_rts5411_data = {
+static const struct onboard_dev_pdata realtek_rts5411_data = {
 	.reset_us = 0,
 	.num_supplies = 1,
 };
 
-static const struct onboard_hub_pdata ti_tusb8041_data = {
+static const struct onboard_dev_pdata ti_tusb8041_data = {
 	.reset_us = 3000,
 	.num_supplies = 1,
 };
 
-static const struct onboard_hub_pdata cypress_hx3_data = {
+static const struct onboard_dev_pdata cypress_hx3_data = {
 	.reset_us = 10000,
 	.num_supplies = 2,
 };
 
-static const struct onboard_hub_pdata cypress_hx2vl_data = {
+static const struct onboard_dev_pdata cypress_hx2vl_data = {
 	.reset_us = 1,
 	.num_supplies = 1,
 };
 
-static const struct onboard_hub_pdata genesys_gl850g_data = {
+static const struct onboard_dev_pdata genesys_gl850g_data = {
 	.reset_us = 3,
 	.num_supplies = 1,
 };
 
-static const struct onboard_hub_pdata genesys_gl852g_data = {
+static const struct onboard_dev_pdata genesys_gl852g_data = {
 	.reset_us = 50,
 	.num_supplies = 1,
 };
 
-static const struct onboard_hub_pdata vialab_vl817_data = {
+static const struct onboard_dev_pdata vialab_vl817_data = {
 	.reset_us = 10,
 	.num_supplies = 1,
 };
 
-static const struct of_device_id onboard_hub_match[] = {
+static const struct of_device_id onboard_dev_match[] = {
 	{ .compatible = "usb424,2412", .data = &microchip_usb424_data, },
 	{ .compatible = "usb424,2514", .data = &microchip_usb424_data, },
 	{ .compatible = "usb424,2517", .data = &microchip_usb424_data, },
@@ -80,4 +80,4 @@ static const struct of_device_id onboard_hub_match[] = {
 	{}
 };
 
-#endif /* _USB_MISC_ONBOARD_USB_HUB_H */
+#endif /* _USB_MISC_ONBOARD_USB_DEV_H */
diff --git a/drivers/usb/misc/onboard_usb_hub_pdevs.c b/drivers/usb/misc/onboard_usb_dev_pdevs.c
similarity index 69%
rename from drivers/usb/misc/onboard_usb_hub_pdevs.c
rename to drivers/usb/misc/onboard_usb_dev_pdevs.c
index ed22a18f4ab7..ca56f67393f1 100644
--- a/drivers/usb/misc/onboard_usb_hub_pdevs.c
+++ b/drivers/usb/misc/onboard_usb_dev_pdevs.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * API for creating and destroying USB onboard hub platform devices
+ * API for creating and destroying USB onboard platform devices
  *
  * Copyright (c) 2022, Google LLC
  */
@@ -15,29 +15,30 @@
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
 #include <linux/usb/of.h>
-#include <linux/usb/onboard_hub.h>
+#include <linux/usb/onboard_dev.h>
 
-#include "onboard_usb_hub.h"
+#include "onboard_usb_dev.h"
 
 struct pdev_list_entry {
 	struct platform_device *pdev;
 	struct list_head node;
 };
 
-static bool of_is_onboard_usb_hub(const struct device_node *np)
+static bool of_is_onboard_usb_dev(struct device_node *np)
 {
-	return !!of_match_node(onboard_hub_match, np);
+	return !!of_match_node(onboard_dev_match, np);
 }
 
 /**
- * onboard_hub_create_pdevs -- create platform devices for onboard USB hubs
- * @parent_hub	: parent hub to scan for connected onboard hubs
- * @pdev_list	: list of onboard hub platform devices owned by the parent hub
+ * onboard_dev_create_pdevs -- create platform devices for onboard USB devices
+ * @parent_hub	: parent hub to scan for connected onboard devices
+ * @pdev_list	: list of onboard platform devices owned by the parent hub
  *
- * Creates a platform device for each supported onboard hub that is connected to
- * the given parent hub. The platform device is in charge of initializing the
- * hub (enable regulators, take the hub out of reset, ...) and can optionally
- * control whether the hub remains powered during system suspend or not.
+ * Creates a platform device for each supported onboard device that is connected
+ * to the given parent hub. The platform device is in charge of initializing the
+ * device (enable regulators, take the device out of reset, ...) and can
+ * optionally control whether the device remains powered during system suspend
+ * or not.
  *
  * To keep track of the platform devices they are added to a list that is owned
  * by the parent hub.
@@ -50,9 +51,9 @@ static bool of_is_onboard_usb_hub(const struct device_node *np)
  * node. That means the root hubs of the primary and secondary HCD share the
  * same device tree node (the HCD node). As a result this function can be called
  * twice with the same DT node for root hubs. We only want to create a single
- * platform device for each physical onboard hub, hence for root hubs the loop
- * is only executed for the root hub of the primary HCD. Since the function
- * scans through all child nodes it still creates pdevs for onboard hubs
+ * platform device for each physical onboard device, hence for root hubs the
+ * loop is only executed for the root hub of the primary HCD. Since the function
+ * scans through all child nodes it still creates pdevs for onboard devices
  * connected to the root hub of the secondary HCD if needed.
  *
  * Further there must be only one platform device for onboard hubs with a peer
@@ -63,7 +64,7 @@ static bool of_is_onboard_usb_hub(const struct device_node *np)
  * the function processes the nodes of both peers. A platform device is only
  * created if the peer hub doesn't have one already.
  */
-void onboard_hub_create_pdevs(struct usb_device *parent_hub, struct list_head *pdev_list)
+void onboard_dev_create_pdevs(struct usb_device *parent_hub, struct list_head *pdev_list)
 {
 	int i;
 	struct usb_hcd *hcd = bus_to_hcd(parent_hub->bus);
@@ -82,7 +83,7 @@ void onboard_hub_create_pdevs(struct usb_device *parent_hub, struct list_head *p
 		if (!np)
 			continue;
 
-		if (!of_is_onboard_usb_hub(np))
+		if (!of_is_onboard_usb_dev(np))
 			goto node_put;
 
 		npc = of_parse_phandle(np, "peer-hub", 0);
@@ -104,7 +105,7 @@ void onboard_hub_create_pdevs(struct usb_device *parent_hub, struct list_head *p
 		pdev = of_platform_device_create(np, NULL, &parent_hub->dev);
 		if (!pdev) {
 			dev_err(&parent_hub->dev,
-				"failed to create platform device for onboard hub '%pOF'\n", np);
+				"failed to create platform device for onboard dev '%pOF'\n", np);
 			goto node_put;
 		}
 
@@ -121,16 +122,16 @@ void onboard_hub_create_pdevs(struct usb_device *parent_hub, struct list_head *p
 		of_node_put(np);
 	}
 }
-EXPORT_SYMBOL_GPL(onboard_hub_create_pdevs);
+EXPORT_SYMBOL_GPL(onboard_dev_create_pdevs);
 
 /**
- * onboard_hub_destroy_pdevs -- free resources of onboard hub platform devices
- * @pdev_list	: list of onboard hub platform devices
+ * onboard_dev_destroy_pdevs -- free resources of onboard platform devices
+ * @pdev_list	: list of onboard platform devices
  *
  * Destroys the platform devices in the given list and frees the memory associated
  * with the list entry.
  */
-void onboard_hub_destroy_pdevs(struct list_head *pdev_list)
+void onboard_dev_destroy_pdevs(struct list_head *pdev_list)
 {
 	struct pdev_list_entry *pdle, *tmp;
 
@@ -140,4 +141,4 @@ void onboard_hub_destroy_pdevs(struct list_head *pdev_list)
 		kfree(pdle);
 	}
 }
-EXPORT_SYMBOL_GPL(onboard_hub_destroy_pdevs);
+EXPORT_SYMBOL_GPL(onboard_dev_destroy_pdevs);
diff --git a/drivers/usb/misc/onboard_usb_hub.c b/drivers/usb/misc/onboard_usb_hub.c
deleted file mode 100644
index 0dd2b032c90b..000000000000
--- a/drivers/usb/misc/onboard_usb_hub.c
+++ /dev/null
@@ -1,501 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Driver for onboard USB hubs
- *
- * Copyright (c) 2022, Google LLC
- */
-
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/export.h>
-#include <linux/err.h>
-#include <linux/gpio/consumer.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/suspend.h>
-#include <linux/sysfs.h>
-#include <linux/usb.h>
-#include <linux/usb/hcd.h>
-#include <linux/usb/onboard_hub.h>
-#include <linux/workqueue.h>
-
-#include "onboard_usb_hub.h"
-
-/*
- * Use generic names, as the actual names might differ between hubs. If a new
- * hub requires more than the currently supported supplies, add a new one here.
- */
-static const char * const supply_names[] = {
-	"vdd",
-	"vdd2",
-};
-
-#define MAX_SUPPLIES ARRAY_SIZE(supply_names)
-
-static void onboard_hub_attach_usb_driver(struct work_struct *work);
-
-static struct usb_device_driver onboard_hub_usbdev_driver;
-static DECLARE_WORK(attach_usb_driver_work, onboard_hub_attach_usb_driver);
-
-/************************** Platform driver **************************/
-
-struct usbdev_node {
-	struct usb_device *udev;
-	struct list_head list;
-};
-
-struct onboard_hub {
-	struct regulator_bulk_data supplies[MAX_SUPPLIES];
-	struct device *dev;
-	const struct onboard_hub_pdata *pdata;
-	struct gpio_desc *reset_gpio;
-	bool always_powered_in_suspend;
-	bool is_powered_on;
-	bool going_away;
-	struct list_head udev_list;
-	struct mutex lock;
-	struct clk *clk;
-};
-
-static int onboard_hub_power_on(struct onboard_hub *hub)
-{
-	int err;
-
-	err = clk_prepare_enable(hub->clk);
-	if (err) {
-		dev_err(hub->dev, "failed to enable clock: %pe\n", ERR_PTR(err));
-		return err;
-	}
-
-	err = regulator_bulk_enable(hub->pdata->num_supplies, hub->supplies);
-	if (err) {
-		dev_err(hub->dev, "failed to enable supplies: %pe\n", ERR_PTR(err));
-		return err;
-	}
-
-	fsleep(hub->pdata->reset_us);
-	gpiod_set_value_cansleep(hub->reset_gpio, 0);
-
-	hub->is_powered_on = true;
-
-	return 0;
-}
-
-static int onboard_hub_power_off(struct onboard_hub *hub)
-{
-	int err;
-
-	gpiod_set_value_cansleep(hub->reset_gpio, 1);
-
-	err = regulator_bulk_disable(hub->pdata->num_supplies, hub->supplies);
-	if (err) {
-		dev_err(hub->dev, "failed to disable supplies: %pe\n", ERR_PTR(err));
-		return err;
-	}
-
-	clk_disable_unprepare(hub->clk);
-
-	hub->is_powered_on = false;
-
-	return 0;
-}
-
-static int __maybe_unused onboard_hub_suspend(struct device *dev)
-{
-	struct onboard_hub *hub = dev_get_drvdata(dev);
-	struct usbdev_node *node;
-	bool power_off = true;
-
-	if (hub->always_powered_in_suspend)
-		return 0;
-
-	mutex_lock(&hub->lock);
-
-	list_for_each_entry(node, &hub->udev_list, list) {
-		if (!device_may_wakeup(node->udev->bus->controller))
-			continue;
-
-		if (usb_wakeup_enabled_descendants(node->udev)) {
-			power_off = false;
-			break;
-		}
-	}
-
-	mutex_unlock(&hub->lock);
-
-	if (!power_off)
-		return 0;
-
-	return onboard_hub_power_off(hub);
-}
-
-static int __maybe_unused onboard_hub_resume(struct device *dev)
-{
-	struct onboard_hub *hub = dev_get_drvdata(dev);
-
-	if (hub->is_powered_on)
-		return 0;
-
-	return onboard_hub_power_on(hub);
-}
-
-static inline void get_udev_link_name(const struct usb_device *udev, char *buf, size_t size)
-{
-	snprintf(buf, size, "usb_dev.%s", dev_name(&udev->dev));
-}
-
-static int onboard_hub_add_usbdev(struct onboard_hub *hub, struct usb_device *udev)
-{
-	struct usbdev_node *node;
-	char link_name[64];
-	int err;
-
-	mutex_lock(&hub->lock);
-
-	if (hub->going_away) {
-		err = -EINVAL;
-		goto error;
-	}
-
-	node = kzalloc(sizeof(*node), GFP_KERNEL);
-	if (!node) {
-		err = -ENOMEM;
-		goto error;
-	}
-
-	node->udev = udev;
-
-	list_add(&node->list, &hub->udev_list);
-
-	mutex_unlock(&hub->lock);
-
-	get_udev_link_name(udev, link_name, sizeof(link_name));
-	WARN_ON(sysfs_create_link(&hub->dev->kobj, &udev->dev.kobj, link_name));
-
-	return 0;
-
-error:
-	mutex_unlock(&hub->lock);
-
-	return err;
-}
-
-static void onboard_hub_remove_usbdev(struct onboard_hub *hub, const struct usb_device *udev)
-{
-	struct usbdev_node *node;
-	char link_name[64];
-
-	get_udev_link_name(udev, link_name, sizeof(link_name));
-	sysfs_remove_link(&hub->dev->kobj, link_name);
-
-	mutex_lock(&hub->lock);
-
-	list_for_each_entry(node, &hub->udev_list, list) {
-		if (node->udev == udev) {
-			list_del(&node->list);
-			kfree(node);
-			break;
-		}
-	}
-
-	mutex_unlock(&hub->lock);
-}
-
-static ssize_t always_powered_in_suspend_show(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	const struct onboard_hub *hub = dev_get_drvdata(dev);
-
-	return sysfs_emit(buf, "%d\n", hub->always_powered_in_suspend);
-}
-
-static ssize_t always_powered_in_suspend_store(struct device *dev, struct device_attribute *attr,
-			    const char *buf, size_t count)
-{
-	struct onboard_hub *hub = dev_get_drvdata(dev);
-	bool val;
-	int ret;
-
-	ret = kstrtobool(buf, &val);
-	if (ret < 0)
-		return ret;
-
-	hub->always_powered_in_suspend = val;
-
-	return count;
-}
-static DEVICE_ATTR_RW(always_powered_in_suspend);
-
-static struct attribute *onboard_hub_attrs[] = {
-	&dev_attr_always_powered_in_suspend.attr,
-	NULL,
-};
-ATTRIBUTE_GROUPS(onboard_hub);
-
-static void onboard_hub_attach_usb_driver(struct work_struct *work)
-{
-	int err;
-
-	err = driver_attach(&onboard_hub_usbdev_driver.driver);
-	if (err)
-		pr_err("Failed to attach USB driver: %pe\n", ERR_PTR(err));
-}
-
-static int onboard_hub_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct onboard_hub *hub;
-	unsigned int i;
-	int err;
-
-	hub = devm_kzalloc(dev, sizeof(*hub), GFP_KERNEL);
-	if (!hub)
-		return -ENOMEM;
-
-	hub->pdata = device_get_match_data(&pdev->dev);
-	if (!hub->pdata)
-		return -EINVAL;
-
-	if (hub->pdata->num_supplies > MAX_SUPPLIES)
-		return dev_err_probe(dev, -EINVAL, "max %zu supplies supported!\n",
-				     MAX_SUPPLIES);
-
-	for (i = 0; i < hub->pdata->num_supplies; i++)
-		hub->supplies[i].supply = supply_names[i];
-
-	err = devm_regulator_bulk_get(dev, hub->pdata->num_supplies, hub->supplies);
-	if (err) {
-		dev_err(dev, "Failed to get regulator supplies: %pe\n", ERR_PTR(err));
-		return err;
-	}
-
-	hub->clk = devm_clk_get_optional(dev, NULL);
-	if (IS_ERR(hub->clk))
-		return dev_err_probe(dev, PTR_ERR(hub->clk), "failed to get clock\n");
-
-	hub->reset_gpio = devm_gpiod_get_optional(dev, "reset",
-						  GPIOD_OUT_HIGH);
-	if (IS_ERR(hub->reset_gpio))
-		return dev_err_probe(dev, PTR_ERR(hub->reset_gpio), "failed to get reset GPIO\n");
-
-	hub->dev = dev;
-	mutex_init(&hub->lock);
-	INIT_LIST_HEAD(&hub->udev_list);
-
-	dev_set_drvdata(dev, hub);
-
-	err = onboard_hub_power_on(hub);
-	if (err)
-		return err;
-
-	/*
-	 * The USB driver might have been detached from the USB devices by
-	 * onboard_hub_remove() (e.g. through an 'unbind' by userspace),
-	 * make sure to re-attach it if needed.
-	 *
-	 * This needs to be done deferred to avoid self-deadlocks on systems
-	 * with nested onboard hubs.
-	 */
-	schedule_work(&attach_usb_driver_work);
-
-	return 0;
-}
-
-static void onboard_hub_remove(struct platform_device *pdev)
-{
-	struct onboard_hub *hub = dev_get_drvdata(&pdev->dev);
-	struct usbdev_node *node;
-	struct usb_device *udev;
-
-	hub->going_away = true;
-
-	mutex_lock(&hub->lock);
-
-	/* unbind the USB devices to avoid dangling references to this device */
-	while (!list_empty(&hub->udev_list)) {
-		node = list_first_entry(&hub->udev_list, struct usbdev_node, list);
-		udev = node->udev;
-
-		/*
-		 * Unbinding the driver will call onboard_hub_remove_usbdev(),
-		 * which acquires hub->lock.  We must release the lock first.
-		 */
-		get_device(&udev->dev);
-		mutex_unlock(&hub->lock);
-		device_release_driver(&udev->dev);
-		put_device(&udev->dev);
-		mutex_lock(&hub->lock);
-	}
-
-	mutex_unlock(&hub->lock);
-
-	onboard_hub_power_off(hub);
-}
-
-MODULE_DEVICE_TABLE(of, onboard_hub_match);
-
-static const struct dev_pm_ops __maybe_unused onboard_hub_pm_ops = {
-	SET_LATE_SYSTEM_SLEEP_PM_OPS(onboard_hub_suspend, onboard_hub_resume)
-};
-
-static struct platform_driver onboard_hub_driver = {
-	.probe = onboard_hub_probe,
-	.remove_new = onboard_hub_remove,
-
-	.driver = {
-		.name = "onboard-usb-hub",
-		.of_match_table = onboard_hub_match,
-		.pm = pm_ptr(&onboard_hub_pm_ops),
-		.dev_groups = onboard_hub_groups,
-	},
-};
-
-/************************** USB driver **************************/
-
-#define VENDOR_ID_CYPRESS	0x04b4
-#define VENDOR_ID_GENESYS	0x05e3
-#define VENDOR_ID_MICROCHIP	0x0424
-#define VENDOR_ID_REALTEK	0x0bda
-#define VENDOR_ID_TI		0x0451
-#define VENDOR_ID_VIA		0x2109
-
-/*
- * Returns the onboard_hub platform device that is associated with the USB
- * device passed as parameter.
- */
-static struct onboard_hub *_find_onboard_hub(struct device *dev)
-{
-	struct platform_device *pdev;
-	struct device_node *np;
-	struct onboard_hub *hub;
-
-	pdev = of_find_device_by_node(dev->of_node);
-	if (!pdev) {
-		np = of_parse_phandle(dev->of_node, "peer-hub", 0);
-		if (!np) {
-			dev_err(dev, "failed to find device node for peer hub\n");
-			return ERR_PTR(-EINVAL);
-		}
-
-		pdev = of_find_device_by_node(np);
-		of_node_put(np);
-
-		if (!pdev)
-			return ERR_PTR(-ENODEV);
-	}
-
-	hub = dev_get_drvdata(&pdev->dev);
-	put_device(&pdev->dev);
-
-	/*
-	 * The presence of drvdata ('hub') indicates that the platform driver
-	 * finished probing. This handles the case where (conceivably) we could
-	 * be running at the exact same time as the platform driver's probe. If
-	 * we detect the race we request probe deferral and we'll come back and
-	 * try again.
-	 */
-	if (!hub)
-		return ERR_PTR(-EPROBE_DEFER);
-
-	return hub;
-}
-
-static int onboard_hub_usbdev_probe(struct usb_device *udev)
-{
-	struct device *dev = &udev->dev;
-	struct onboard_hub *hub;
-	int err;
-
-	/* ignore supported hubs without device tree node */
-	if (!dev->of_node)
-		return -ENODEV;
-
-	hub = _find_onboard_hub(dev);
-	if (IS_ERR(hub))
-		return PTR_ERR(hub);
-
-	dev_set_drvdata(dev, hub);
-
-	err = onboard_hub_add_usbdev(hub, udev);
-	if (err)
-		return err;
-
-	return 0;
-}
-
-static void onboard_hub_usbdev_disconnect(struct usb_device *udev)
-{
-	struct onboard_hub *hub = dev_get_drvdata(&udev->dev);
-
-	onboard_hub_remove_usbdev(hub, udev);
-}
-
-static const struct usb_device_id onboard_hub_id_table[] = {
-	{ USB_DEVICE(VENDOR_ID_CYPRESS, 0x6504) }, /* CYUSB33{0,1,2}x/CYUSB230x 3.0 */
-	{ USB_DEVICE(VENDOR_ID_CYPRESS, 0x6506) }, /* CYUSB33{0,1,2}x/CYUSB230x 2.0 */
-	{ USB_DEVICE(VENDOR_ID_CYPRESS, 0x6570) }, /* CY7C6563x 2.0 */
-	{ USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 */
-	{ USB_DEVICE(VENDOR_ID_GENESYS, 0x0610) }, /* Genesys Logic GL852G USB 2.0 */
-	{ USB_DEVICE(VENDOR_ID_GENESYS, 0x0620) }, /* Genesys Logic GL3523 USB 3.1 */
-	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2412) }, /* USB2412 USB 2.0 */
-	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 */
-	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 */
-	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2744) }, /* USB5744 USB 2.0 */
-	{ USB_DEVICE(VENDOR_ID_MICROCHIP, 0x5744) }, /* USB5744 USB 3.0 */
-	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x0411) }, /* RTS5411 USB 3.1 */
-	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x5411) }, /* RTS5411 USB 2.1 */
-	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x0414) }, /* RTS5414 USB 3.2 */
-	{ USB_DEVICE(VENDOR_ID_REALTEK, 0x5414) }, /* RTS5414 USB 2.1 */
-	{ USB_DEVICE(VENDOR_ID_TI, 0x8140) }, /* TI USB8041 3.0 */
-	{ USB_DEVICE(VENDOR_ID_TI, 0x8142) }, /* TI USB8041 2.0 */
-	{ USB_DEVICE(VENDOR_ID_VIA, 0x0817) }, /* VIA VL817 3.1 */
-	{ USB_DEVICE(VENDOR_ID_VIA, 0x2817) }, /* VIA VL817 2.0 */
-	{}
-};
-MODULE_DEVICE_TABLE(usb, onboard_hub_id_table);
-
-static struct usb_device_driver onboard_hub_usbdev_driver = {
-	.name = "onboard-usb-hub",
-	.probe = onboard_hub_usbdev_probe,
-	.disconnect = onboard_hub_usbdev_disconnect,
-	.generic_subclass = 1,
-	.supports_autosuspend =	1,
-	.id_table = onboard_hub_id_table,
-};
-
-static int __init onboard_hub_init(void)
-{
-	int ret;
-
-	ret = usb_register_device_driver(&onboard_hub_usbdev_driver, THIS_MODULE);
-	if (ret)
-		return ret;
-
-	ret = platform_driver_register(&onboard_hub_driver);
-	if (ret)
-		usb_deregister_device_driver(&onboard_hub_usbdev_driver);
-
-	return ret;
-}
-module_init(onboard_hub_init);
-
-static void __exit onboard_hub_exit(void)
-{
-	usb_deregister_device_driver(&onboard_hub_usbdev_driver);
-	platform_driver_unregister(&onboard_hub_driver);
-
-	cancel_work_sync(&attach_usb_driver_work);
-}
-module_exit(onboard_hub_exit);
-
-MODULE_AUTHOR("Matthias Kaehlcke <mka at chromium.org>");
-MODULE_DESCRIPTION("Driver for discrete onboard USB hubs");
-MODULE_LICENSE("GPL v2");
diff --git a/include/linux/usb/onboard_dev.h b/include/linux/usb/onboard_dev.h
new file mode 100644
index 000000000000..b79db6d193c8
--- /dev/null
+++ b/include/linux/usb/onboard_dev.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __LINUX_USB_ONBOARD_DEV_H
+#define __LINUX_USB_ONBOARD_DEV_H
+
+struct usb_device;
+struct list_head;
+
+#if IS_ENABLED(CONFIG_USB_ONBOARD_DEV)
+void onboard_dev_create_pdevs(struct usb_device *parent_dev, struct list_head *pdev_list);
+void onboard_dev_destroy_pdevs(struct list_head *pdev_list);
+#else
+static inline void onboard_dev_create_pdevs(struct usb_device *parent_dev,
+					    struct list_head *pdev_list) {}
+static inline void onboard_dev_destroy_pdevs(struct list_head *pdev_list) {}
+#endif
+
+#endif /* __LINUX_USB_ONBOARD_DEV_H */
diff --git a/include/linux/usb/onboard_hub.h b/include/linux/usb/onboard_hub.h
deleted file mode 100644
index d9373230556e..000000000000
--- a/include/linux/usb/onboard_hub.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef __LINUX_USB_ONBOARD_HUB_H
-#define __LINUX_USB_ONBOARD_HUB_H
-
-struct usb_device;
-struct list_head;
-
-#if IS_ENABLED(CONFIG_USB_ONBOARD_HUB)
-void onboard_hub_create_pdevs(struct usb_device *parent_hub, struct list_head *pdev_list);
-void onboard_hub_destroy_pdevs(struct list_head *pdev_list);
-#else
-static inline void onboard_hub_create_pdevs(struct usb_device *parent_hub,
-					    struct list_head *pdev_list) {}
-static inline void onboard_hub_destroy_pdevs(struct list_head *pdev_list) {}
-#endif
-
-#endif /* __LINUX_USB_ONBOARD_HUB_H */

-- 
2.40.1



From javier.carrasco at wolfvision.net  Tue Feb 20 06:05:46 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Tue, 20 Feb 2024 15:05:46 +0100
Subject: [PATCH v4 2/8] usb: misc: onboard_dev: add support for non-hub
 devices
In-Reply-To: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
Message-ID: <20240220-onboard_xvf3500-v4-2-dc1617cc5dd4@wolfvision.net>

Most of the functionality this driver provides can be used by non-hub
devices as well.

To account for the hub-specific code, add a flag to the device data
structure and check its value for hub-specific code.

Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
---
 drivers/usb/misc/onboard_usb_dev.c |  3 ++-
 drivers/usb/misc/onboard_usb_dev.h | 10 ++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
index 2103af2cb2a6..f43130a6786f 100644
--- a/drivers/usb/misc/onboard_usb_dev.c
+++ b/drivers/usb/misc/onboard_usb_dev.c
@@ -129,7 +129,8 @@ static int __maybe_unused onboard_dev_suspend(struct device *dev)
 		if (!device_may_wakeup(node->udev->bus->controller))
 			continue;
 
-		if (usb_wakeup_enabled_descendants(node->udev)) {
+		if (usb_wakeup_enabled_descendants(node->udev) ||
+		    !onboard_dev->pdata->is_hub) {
 			power_off = false;
 			break;
 		}
diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h
index f13d11a84371..ebe83e19d818 100644
--- a/drivers/usb/misc/onboard_usb_dev.h
+++ b/drivers/usb/misc/onboard_usb_dev.h
@@ -9,51 +9,61 @@
 struct onboard_dev_pdata {
 	unsigned long reset_us;		/* reset pulse width in us */
 	unsigned int num_supplies;	/* number of supplies */
+	bool is_hub;
 };
 
 static const struct onboard_dev_pdata microchip_usb424_data = {
 	.reset_us = 1,
 	.num_supplies = 1,
+	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata microchip_usb5744_data = {
 	.reset_us = 0,
 	.num_supplies = 2,
+	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata realtek_rts5411_data = {
 	.reset_us = 0,
 	.num_supplies = 1,
+	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata ti_tusb8041_data = {
 	.reset_us = 3000,
 	.num_supplies = 1,
+	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata cypress_hx3_data = {
 	.reset_us = 10000,
 	.num_supplies = 2,
+	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata cypress_hx2vl_data = {
 	.reset_us = 1,
 	.num_supplies = 1,
+	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata genesys_gl850g_data = {
 	.reset_us = 3,
 	.num_supplies = 1,
+	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata genesys_gl852g_data = {
 	.reset_us = 50,
 	.num_supplies = 1,
+	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata vialab_vl817_data = {
 	.reset_us = 10,
 	.num_supplies = 1,
+	.is_hub = true,
 };
 
 static const struct of_device_id onboard_dev_match[] = {

-- 
2.40.1



From javier.carrasco at wolfvision.net  Tue Feb 20 06:05:47 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Tue, 20 Feb 2024 15:05:47 +0100
Subject: [PATCH v4 3/8] drm: ci: arm64.config: update ONBOARD_USB_HUB to
 ONBOARD_USB_DEV
In-Reply-To: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
Message-ID: <20240220-onboard_xvf3500-v4-3-dc1617cc5dd4@wolfvision.net>

The onboard_usb_hub driver has been updated to support non-hub devices,
which has led to some renaming.

Update to the new name (ONBOARD_USB_DEV) accordingly.

Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
---
 drivers/gpu/drm/ci/arm64.config | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/ci/arm64.config b/drivers/gpu/drm/ci/arm64.config
index 8dbce9919a57..4140303d6260 100644
--- a/drivers/gpu/drm/ci/arm64.config
+++ b/drivers/gpu/drm/ci/arm64.config
@@ -87,7 +87,7 @@ CONFIG_DRM_PARADE_PS8640=y
 CONFIG_DRM_LONTIUM_LT9611UXC=y
 CONFIG_PHY_QCOM_USB_HS=y
 CONFIG_QCOM_GPI_DMA=y
-CONFIG_USB_ONBOARD_HUB=y
+CONFIG_USB_ONBOARD_DEV=y
 CONFIG_NVMEM_QCOM_QFPROM=y
 CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y
 
@@ -97,7 +97,7 @@ CONFIG_USB_RTL8152=y
 # db820c ethernet
 CONFIG_ATL1C=y
 # Chromebooks ethernet
-CONFIG_USB_ONBOARD_HUB=y
+CONFIG_USB_ONBOARD_DEV=y
 # 888 HDK ethernet
 CONFIG_USB_LAN78XX=y
 

-- 
2.40.1



From javier.carrasco at wolfvision.net  Tue Feb 20 06:05:48 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Tue, 20 Feb 2024 15:05:48 +0100
Subject: [PATCH v4 4/8] arm64: defconfig: update ONBOARD_USB_HUB to
 ONBOARD_USB_DEV
In-Reply-To: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
Message-ID: <20240220-onboard_xvf3500-v4-4-dc1617cc5dd4@wolfvision.net>

The onboard_usb_hub driver has been updated to support non-hub devices,
which has led to some renaming.

Update to the new name (ONBOARD_USB_DEV) accordingly.

Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
---
 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 e6cf3e5d63c3..3c6196b6c984 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1047,7 +1047,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
 CONFIG_USB_SERIAL_OPTION=m
 CONFIG_USB_QCOM_EUD=m
 CONFIG_USB_HSIC_USB3503=y
-CONFIG_USB_ONBOARD_HUB=m
+CONFIG_USB_ONBOARD_DEV=m
 CONFIG_NOP_USB_XCEIV=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_RENESAS_USBHS_UDC=m

-- 
2.40.1



From javier.carrasco at wolfvision.net  Tue Feb 20 06:05:49 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Tue, 20 Feb 2024 15:05:49 +0100
Subject: [PATCH v4 5/8] ARM: multi_v7_defconfig: update ONBOARD_USB_HUB
 name
In-Reply-To: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
Message-ID: <20240220-onboard_xvf3500-v4-5-dc1617cc5dd4@wolfvision.net>

The onboard_usb_hub driver has been updated to support non-hub devices,
which has led to some renaming. Update to the new name accordingly.

Update to the new name (ONBOARD_USB_DEV) accordingly.

Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
---
 arch/arm/configs/multi_v7_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index ecb3e286107a..6a6ebec173dc 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -876,7 +876,7 @@ CONFIG_USB_CHIPIDEA_UDC=y
 CONFIG_USB_CHIPIDEA_HOST=y
 CONFIG_USB_ISP1760=y
 CONFIG_USB_HSIC_USB3503=y
-CONFIG_USB_ONBOARD_HUB=m
+CONFIG_USB_ONBOARD_DEV=m
 CONFIG_AB8500_USB=y
 CONFIG_KEYSTONE_USB_PHY=m
 CONFIG_NOP_USB_XCEIV=y

-- 
2.40.1



From javier.carrasco at wolfvision.net  Tue Feb 20 06:05:50 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Tue, 20 Feb 2024 15:05:50 +0100
Subject: [PATCH v4 6/8] usb: misc: onboard_dev: use device supply names
In-Reply-To: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
Message-ID: <20240220-onboard_xvf3500-v4-6-dc1617cc5dd4@wolfvision.net>

The current mechanism uses generic names for the power supplies, which
conflicts with proper name definitions in the device bindings.

Add a per-device property to include real supply names and keep generic
names as a fallback mechanism for backward compatibility.

Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
---
 drivers/usb/misc/onboard_usb_dev.c | 54 ++++++++++++++++++++------------------
 drivers/usb/misc/onboard_usb_dev.h | 23 ++++++++++++++++
 2 files changed, 52 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
index f43130a6786f..e66fcac93006 100644
--- a/drivers/usb/misc/onboard_usb_dev.c
+++ b/drivers/usb/misc/onboard_usb_dev.c
@@ -29,18 +29,6 @@
 
 #include "onboard_usb_dev.h"
 
-/*
- * Use generic names, as the actual names might differ between devices. If a new
- * device requires more than the currently supported supplies, add a new one
- * here.
- */
-static const char * const supply_names[] = {
-	"vdd",
-	"vdd2",
-};
-
-#define MAX_SUPPLIES ARRAY_SIZE(supply_names)
-
 static void onboard_dev_attach_usb_driver(struct work_struct *work);
 
 static struct usb_device_driver onboard_dev_usbdev_driver;
@@ -66,6 +54,33 @@ struct onboard_dev {
 	struct clk *clk;
 };
 
+static int onboard_dev_get_regulator_bulk(struct device *dev,
+					  struct onboard_dev *onboard_dev)
+{
+	unsigned int i;
+	int err;
+
+	const char * const *supply_names = onboard_dev->pdata->supply_names;
+
+	if (onboard_dev->pdata->num_supplies > MAX_SUPPLIES)
+		return dev_err_probe(dev, -EINVAL, "max %zu supplies supported!\n",
+				     MAX_SUPPLIES);
+
+	if (!supply_names[0])
+		supply_names = generic_supply_names;
+
+	for (i = 0; i < onboard_dev->pdata->num_supplies; i++)
+		onboard_dev->supplies[i].supply = supply_names[i];
+
+	err = devm_regulator_bulk_get(dev, onboard_dev->pdata->num_supplies,
+				      onboard_dev->supplies);
+	if (err)
+		dev_err(dev, "Failed to get regulator supplies: %pe\n",
+			ERR_PTR(err));
+
+	return err;
+}
+
 static int onboard_dev_power_on(struct onboard_dev *onboard_dev)
 {
 	int err;
@@ -266,7 +281,6 @@ static int onboard_dev_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct onboard_dev *onboard_dev;
-	unsigned int i;
 	int err;
 
 	onboard_dev = devm_kzalloc(dev, sizeof(*onboard_dev), GFP_KERNEL);
@@ -277,19 +291,9 @@ static int onboard_dev_probe(struct platform_device *pdev)
 	if (!onboard_dev->pdata)
 		return -EINVAL;
 
-	if (onboard_dev->pdata->num_supplies > MAX_SUPPLIES)
-		return dev_err_probe(dev, -EINVAL, "max %zu supplies supported!\n",
-				     MAX_SUPPLIES);
-
-	for (i = 0; i < onboard_dev->pdata->num_supplies; i++)
-		onboard_dev->supplies[i].supply = supply_names[i];
-
-	err = devm_regulator_bulk_get(dev, onboard_dev->pdata->num_supplies,
-				      onboard_dev->supplies);
-	if (err) {
-		dev_err(dev, "Failed to get regulator supplies: %pe\n", ERR_PTR(err));
+	err = onboard_dev_get_regulator_bulk(dev, onboard_dev);
+	if (err)
 		return err;
-	}
 
 	onboard_dev->clk = devm_clk_get_optional(dev, NULL);
 	if (IS_ERR(onboard_dev->clk))
diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h
index ebe83e19d818..59dced6bd339 100644
--- a/drivers/usb/misc/onboard_usb_dev.h
+++ b/drivers/usb/misc/onboard_usb_dev.h
@@ -6,63 +6,86 @@
 #ifndef _USB_MISC_ONBOARD_USB_DEV_H
 #define _USB_MISC_ONBOARD_USB_DEV_H
 
+/*
+ * Fallback supply names for backwards compatibility. If the device requires
+ * more than the currently supported supplies, add a new one here, and if
+ * possible, the real name supplies to the device-specific data.
+ */
+static const char * const generic_supply_names[] = {
+	"vdd",
+	"vdd2",
+};
+
+#define MAX_SUPPLIES ARRAY_SIZE(generic_supply_names)
+
 struct onboard_dev_pdata {
 	unsigned long reset_us;		/* reset pulse width in us */
 	unsigned int num_supplies;	/* number of supplies */
 	bool is_hub;
+	const char * const supply_names[MAX_SUPPLIES];
+
 };
 
 static const struct onboard_dev_pdata microchip_usb424_data = {
 	.reset_us = 1,
 	.num_supplies = 1,
+	.supply_names = { NULL },
 	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata microchip_usb5744_data = {
 	.reset_us = 0,
 	.num_supplies = 2,
+	.supply_names = { NULL },
 	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata realtek_rts5411_data = {
 	.reset_us = 0,
 	.num_supplies = 1,
+	.supply_names = { NULL },
 	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata ti_tusb8041_data = {
 	.reset_us = 3000,
 	.num_supplies = 1,
+	.supply_names = { NULL },
 	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata cypress_hx3_data = {
 	.reset_us = 10000,
 	.num_supplies = 2,
+	.supply_names = { NULL },
 	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata cypress_hx2vl_data = {
 	.reset_us = 1,
 	.num_supplies = 1,
+	.supply_names = { NULL },
 	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata genesys_gl850g_data = {
 	.reset_us = 3,
 	.num_supplies = 1,
+	.supply_names = { NULL },
 	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata genesys_gl852g_data = {
 	.reset_us = 50,
 	.num_supplies = 1,
+	.supply_names = { NULL },
 	.is_hub = true,
 };
 
 static const struct onboard_dev_pdata vialab_vl817_data = {
 	.reset_us = 10,
 	.num_supplies = 1,
+	.supply_names = { NULL },
 	.is_hub = true,
 };
 

-- 
2.40.1



From javier.carrasco at wolfvision.net  Tue Feb 20 06:05:51 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Tue, 20 Feb 2024 15:05:51 +0100
Subject: [PATCH v4 7/8] ASoC: dt-bindings: xmos,xvf3500: add XMOS XVF3500
 voice processor
In-Reply-To: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
Message-ID: <20240220-onboard_xvf3500-v4-7-dc1617cc5dd4@wolfvision.net>

The XMOS XVF3500 VocalFusion Voice Processor[1] is a low-latency, 32-bit
multicore controller for voice processing.

Add new bindings to define the device properties.

[1] https://www.xmos.com/xvf3500/

Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
---
 .../devicetree/bindings/sound/xmos,xvf3500.yaml    | 63 ++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/xmos,xvf3500.yaml b/Documentation/devicetree/bindings/sound/xmos,xvf3500.yaml
new file mode 100644
index 000000000000..fb77a61f1350
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/xmos,xvf3500.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/xmos,xvf3500.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: XMOS XVF3500 VocalFusion Voice Processor
+
+maintainers:
+  - Javier Carrasco <javier.carrasco at wolfvision.net>
+
+description:
+  The XMOS XVF3500 VocalFusion Voice Processor is a low-latency, 32-bit
+  multicore controller for voice processing.
+  https://www.xmos.com/xvf3500/
+
+allOf:
+  - $ref: /schemas/usb/usb-device.yaml#
+
+properties:
+  compatible:
+    const: usb20b1,0013
+
+  reg: true
+
+  reset-gpios:
+    maxItems: 1
+
+  vdd-supply:
+    description:
+      Regulator for the 1V0 supply.
+
+  vddio-supply:
+    description:
+      Regulator for the 3V3 supply.
+
+required:
+  - compatible
+  - reg
+  - reset-gpios
+  - vdd-supply
+  - vddio-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    usb {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        voice_processor: voice-processor at 1 {
+            compatible = "usb20b1,0013";
+            reg = <1>;
+            reset-gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+            vdd-supply = <&vcc1v0>;
+            vddio-supply = <&vcc3v3>;
+        };
+    };
+
+...

-- 
2.40.1



From javier.carrasco at wolfvision.net  Tue Feb 20 06:05:52 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Tue, 20 Feb 2024 15:05:52 +0100
Subject: [PATCH v4 8/8] usb: misc: onboard_hub: add support for XMOS
 XVF3500
In-Reply-To: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
Message-ID: <20240220-onboard_xvf3500-v4-8-dc1617cc5dd4@wolfvision.net>

The XMOS XVF3500 VocalFusion Voice Processor[1] is a low-latency, 32-bit
multicore controller for voice processing.

This device requires a specific power sequence, which consists of
enabling the regulators that control the 3V3 and 1V0 device supplies,
and a reset de-assertion after a delay of at least 100ns. Such power
sequence is already supported by the onboard_hub driver, and it can be
reused for non-hub USB devices as well.

Once in normal operation, the XVF3500 registers itself as a USB device,
and it does not require any device-specific operations in the driver.

[1] https://www.xmos.com/xvf3500/

Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
---
 drivers/usb/misc/onboard_usb_dev.c | 2 ++
 drivers/usb/misc/onboard_usb_dev.h | 8 ++++++++
 2 files changed, 10 insertions(+)

diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
index e66fcac93006..e717d1ca8d79 100644
--- a/drivers/usb/misc/onboard_usb_dev.c
+++ b/drivers/usb/misc/onboard_usb_dev.c
@@ -388,6 +388,7 @@ static struct platform_driver onboard_dev_driver = {
 #define VENDOR_ID_REALTEK	0x0bda
 #define VENDOR_ID_TI		0x0451
 #define VENDOR_ID_VIA		0x2109
+#define VENDOR_ID_XMOS		0x20B1
 
 /*
  * Returns the onboard_dev platform device that is associated with the USB
@@ -480,6 +481,7 @@ static const struct usb_device_id onboard_dev_id_table[] = {
 	{ USB_DEVICE(VENDOR_ID_TI, 0x8142) }, /* TI USB8041 2.0 */
 	{ USB_DEVICE(VENDOR_ID_VIA, 0x0817) }, /* VIA VL817 3.1 */
 	{ USB_DEVICE(VENDOR_ID_VIA, 0x2817) }, /* VIA VL817 2.0 */
+	{ USB_DEVICE(VENDOR_ID_XMOS, 0x0013) }, /* XVF3500 */
 	{}
 };
 MODULE_DEVICE_TABLE(usb, onboard_dev_id_table);
diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h
index 59dced6bd339..921a5276fc7f 100644
--- a/drivers/usb/misc/onboard_usb_dev.h
+++ b/drivers/usb/misc/onboard_usb_dev.h
@@ -89,6 +89,13 @@ static const struct onboard_dev_pdata vialab_vl817_data = {
 	.is_hub = true,
 };
 
+static const struct onboard_dev_pdata xmos_xvf3500_data = {
+	.reset_us = 1,
+	.num_supplies = 2,
+	.supply_names = { "vdd", "vddio" },
+	.is_hub = false,
+};
+
 static const struct of_device_id onboard_dev_match[] = {
 	{ .compatible = "usb424,2412", .data = &microchip_usb424_data, },
 	{ .compatible = "usb424,2514", .data = &microchip_usb424_data, },
@@ -110,6 +117,7 @@ static const struct of_device_id onboard_dev_match[] = {
 	{ .compatible = "usbbda,5414", .data = &realtek_rts5411_data, },
 	{ .compatible = "usb2109,817", .data = &vialab_vl817_data, },
 	{ .compatible = "usb2109,2817", .data = &vialab_vl817_data, },
+	{ .compatible = "usb20b1,0013", .data = &xmos_xvf3500_data, },
 	{}
 };
 

-- 
2.40.1



From david at redhat.com  Tue Feb 20 06:07:22 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 20 Feb 2024 15:07:22 +0100
Subject: arm64 MTE tag storage reuse - alternatives to MIGRATE_CMA
In-Reply-To: <ZdSojvNyaqli2rWE@raptor>
References: <ZdSMbjGf2Fj98diT@raptor>
 <70d77490-9036-48ac-afc9-4b976433070d@redhat.com> <ZdSojvNyaqli2rWE@raptor>
Message-ID: <e0b7c884-4345-44b1-b8c0-2711a28a980e@redhat.com>

>>
>> With large folios in place, we'd likely want to investigate not working on
>> individual pages, but on (possibly large) folios instead.
> 
> Yes, that would be interesting. Since the backend has no way of controlling
> what tag storage page will be needed for tags, and subsequently dropped
> from the cache, we would have to figure out what to do if one of the pages
> that is part of a large folio is dropped. The easiest solution that I can
> see is to remove the entire folio from the cleancache, but that would mean
> also dropping the rest of the pages from the folio unnecessarily.

Right, but likely that won't be an issue. Things get interesting when 
thinking about an efficient allocation approach.

> 
>>
>>>
>>> I believe this is a very good fit for tag storage reuse, because it allows
>>> tag storage to be allocated even in atomic contexts, which enables MTE in
>>> the kernel. As a bonus, all of the changes to MM from the current approach
>>> wouldn't be needed, as tag storage allocation can be handled entirely in
>>> set_ptes_at(), copy_*highpage() or arch_swap_restore().
>>>
>>> Is this a viable approach that would be upstreamable? Are there other
>>> solutions that I haven't considered? I'm very much open to any alternatives
>>> that would make tag storage reuse viable.
>>
>> As raised recently, I had similar ideas with something like virtio-mem in
>> the past (wanted to call it virtio-tmem back then), but didn't have time to
>> look into it yet.
>>
>> I considered both, using special device memory as "cleancache" backend, and
>> using it as backend storage for something similar to zswap. We would not
>> need a memmap/"struct page" for that special device memory, which reduces
>> memory overhead and makes "adding more memory" a more reliable operation.
> 
> Hm... this might not work with tag storage memory, the kernel needs to
> perform cache maintenance on the memory when it transitions to and from
> storing tags and storing data, so the memory must be mapped by the kernel.

The direct map will definitely be required I think (copy in/out data). 
But memmap for tag memory will likely not be required. Of course, it 
depends how to manage tag storage. Likely we have to store some 
metadata, hopefully we can avoid the full memmap and just use something 
else.

[...]

>> Similar to virtio-mem, there are ways for the hypervisor to request changes
>> to the memory consumption of a device (setting the requested size). So when
>> requested to consume less, clean pagecache pages can be dropped and the
>> memory can be handed back to the hypervisor.
>>
>> Of course, likely we would want to consider using "slower" memory in the
>> hypervisor to back such a device.
> 
> I'm not sure how useful that will be with tag storage reuse. KVM must
> assume that **all** the memory that the guest uses is tagged and it needs
> tag storage allocated (it's a known architectural limitation), so that will
> leave even less tag storage memory to distribute between the host and the
> guest(s).

Yes, I don't think this applies to tag storage.

> 
> Adding to that, at the moment Android is going to be the major (only?) user
> of tag storage reuse, and as far as I know pKVM is more restrictive with
> regards to the emulated devices and the memory that is shared between
> guests and the host.

Right, what I described here does not have overlap with tag storage 
besides requiring similar (cleancache) hooks.

-- 
Cheers,

David / dhildenb



From jgg at nvidia.com  Tue Feb 20 06:09:39 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 20 Feb 2024 10:09:39 -0400
Subject: [PATCH v4 20/27] iommu: Add ops->domain_alloc_sva()
In-Reply-To: <CAE2F3rBip7oe4ip-kK5GR6+nY_efsVrrxcxv=4m4_aWGKOg=gw@mail.gmail.com>
References: <0-v4-e7091cdd9e8d+43b1-smmuv3_newapi_p2_jgg@nvidia.com>
 <20-v4-e7091cdd9e8d+43b1-smmuv3_newapi_p2_jgg@nvidia.com>
 <CAE2F3rBip7oe4ip-kK5GR6+nY_efsVrrxcxv=4m4_aWGKOg=gw@mail.gmail.com>
Message-ID: <20240220140939.GN13330@nvidia.com>

On Mon, Feb 19, 2024 at 02:47:31PM -0800, Daniel Mentz wrote:
> On Fri, Jan 26, 2024 at 10:15?AM Jason Gunthorpe <jgg at nvidia.com> wrote:
> > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> > @@ -654,7 +654,7 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
> >
> >  static void arm_smmu_sva_domain_free(struct iommu_domain *domain)
> >  {
> > -       kfree(domain);
> > +       kfree(to_smmu_domain(domain));
> >  }
> 
> I'm wondering if this particular change belongs into the other change
> with title "iommu/arm-smmu-v3: Make SVA allocate a normal
> arm_smmu_domain"

Yes, you are right. I think it is a rebasing error..

Thanks,
Jason


From broonie at kernel.org  Tue Feb 20 06:10:10 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 14:10:10 +0000
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <CAMRc=McFCauVwpATbVqCOtpyP_buKQDiN0OdZP9EfXmc3CgSUA@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk>
 <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
 <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk>
 <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>
 <5a3f5e1b-8162-4619-a10b-d4711afe533b@sirena.org.uk>
 <CAMRc=MdTub4u0dm5PgTQPnYPuR=SRnh=ympEZqo_UyrQDrQw6w@mail.gmail.com>
 <f72723f3-f5c5-4c16-a257-e5f57c4f9e73@sirena.org.uk>
 <CAMRc=McFCauVwpATbVqCOtpyP_buKQDiN0OdZP9EfXmc3CgSUA@mail.gmail.com>
Message-ID: <4586127e-d224-48cd-9e56-a06a4a9d46bc@sirena.org.uk>

On Tue, Feb 20, 2024 at 02:51:25PM +0100, Bartosz Golaszewski wrote:
> On Tue, Feb 20, 2024 at 2:48?PM Mark Brown <broonie at kernel.org> wrote:

> > It is generally a bad sign if there is a voltage range specified on a
> > regulator that's not got any indication that the voltage is going to be
> > actively managed, especially in situations like with several of the
> > supplies the DT was specifying where there are clear indications that
> > the supply is intended to be fixed voltage (or cases where every single
> > supply has a voltage range which would be highly unusual).  Looking at
> > the consumers might provide an explanation for such unusual and likely
> > incorrect constraints, and the lack of any consumers in conjunction with
> > other warning signs reenforces those warning signs.

> What do you recommend? No values at all in these regulators as it's
> the PMU which will manage those on its own once powered up by the host
> PMIC?

Unless something is actively going to change the voltages at runtime
or Linux needs to set a specific voltage (in which case minimum and
maximum should be identical) there should be nothing specified.
-------------- 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/20240220/f72d61cd/attachment.sig>

From alexander.stein at ew.tq-group.com  Tue Feb 20 06:23:06 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 20 Feb 2024 15:23:06 +0100
Subject: [PATCH 1/1] arm64: dts: freescale: imx8mm/imx8mq: mba8mx: Use PCIe clock generator
Message-ID: <20240220142306.2514269-1-alexander.stein@ew.tq-group.com>

PCIe reference clock is provided by Renesas 9FGV0441. Reference this
instead of a fixed-clock.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
I've dropped Geert Uytterhoeven and Magnus Damm from get_maintainers.pl
output as they seem to be triggered by 'renesas' keyword only.

It's a bit unclear what the clock IMX8MQ_CLK_PCIEx_PHY is actually
about. I assume 'pcie_bus' is the reference clock for the PCIe
device while 'pcie_phy' is the reference clock for the RC. Both
are provided by the external clock generator.

 .../dts/freescale/imx8mm-tqma8mqml-mba8mx.dts | 14 +++++++----
 .../dts/freescale/imx8mq-tqma8mq-mba8mx.dts   | 23 +++++--------------
 arch/arm64/boot/dts/freescale/mba8mx.dtsi     | 19 ++++++++++-----
 3 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
index ea6e8b85169f7..01b632b220dc7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
@@ -5,6 +5,8 @@
 
 /dts-v1/;
 
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+
 #include "imx8mm-tqma8mqml.dtsi"
 #include "mba8mx.dtsi"
 
@@ -74,19 +76,23 @@ expander2: gpio at 27 {
 };
 
 &pcie_phy {
-	clocks = <&pcie0_refclk>;
+	fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+	fsl,clkreq-unsupported;
+	clocks = <&pcieclk 2>;
+	clock-names = "ref";
 	status = "okay";
 };
 
+/* PCIe slot on X36 */
 &pcie0 {
 	reset-gpio = <&expander0 14 GPIO_ACTIVE_LOW>;
-	clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&pcie0_refclk>,
+	clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&pcieclk 3>,
 		 <&clk IMX8MM_CLK_PCIE1_AUX>;
 	assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
-				<&clk IMX8MM_CLK_PCIE1_CTRL>;
+			  <&clk IMX8MM_CLK_PCIE1_CTRL>;
 	assigned-clock-rates = <10000000>, <250000000>;
 	assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
-				<&clk IMX8MM_SYS_PLL2_250M>;
+				 <&clk IMX8MM_SYS_PLL2_250M>;
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
index b302daca4ce64..b2e17d4f335eb 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
@@ -28,18 +28,6 @@ extcon_usbotg: extcon-usbotg0 {
 		id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
 	};
 
-	pcie0_refclk: pcie0-refclk {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <100000000>;
-	};
-
-	pcie1_refclk: pcie1-refclk {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <100000000>;
-	};
-
 	reg_otg_vbus: regulator-otg-vbus {
 		compatible = "regulator-fixed";
 		pinctrl-names = "default";
@@ -103,23 +91,24 @@ &led2 {
 	gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
 };
 
+/* PCIe slot on X36 */
 &pcie0 {
 	reset-gpio = <&expander0 14 GPIO_ACTIVE_LOW>;
 	clocks = <&clk IMX8MQ_CLK_PCIE1_ROOT>,
-		 <&pcie0_refclk>,
-		 <&clk IMX8MQ_CLK_PCIE1_PHY>,
+		 <&pcieclk 3>,
+		 <&pcieclk 2>,
 		 <&clk IMX8MQ_CLK_PCIE1_AUX>;
 	status = "okay";
 };
 
 /*
- * miniPCIe, also usable for cards with USB. Therefore configure the reset as
+ * miniPCIe on X28, also usable for cards with USB. Therefore configure the reset as
  * static gpio hog.
  */
 &pcie1 {
 	clocks = <&clk IMX8MQ_CLK_PCIE2_ROOT>,
-		 <&pcie1_refclk>,
-		 <&clk IMX8MQ_CLK_PCIE2_PHY>,
+		 <&pcieclk 1>,
+		 <&pcieclk 0>,
 		 <&clk IMX8MQ_CLK_PCIE2_AUX>;
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
index e2bc53b8d39a8..c82af672d1834 100644
--- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
@@ -29,6 +29,12 @@ chosen {
 		stdout-path = &uart3;
 	};
 
+	clk_xtal25: clk-xtal25 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+
 	gpio-keys {
 		compatible = "gpio-keys";
 		pinctrl-names = "default";
@@ -100,12 +106,6 @@ panel_in_lvds: 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";
@@ -264,6 +264,13 @@ eeprom3: eeprom at 57 {
 		pagesize = <16>;
 		vcc-supply = <&reg_vcc_3v3>;
 	};
+
+	pcieclk: clk at 68 {
+		compatible = "renesas,9fgv0441";
+		reg = <0x68>;
+		clocks = <&clk_xtal25>;
+		#clock-cells = <1>;
+	};
 };
 
 &i2c3 {
-- 
2.34.1



From lpieralisi at kernel.org  Tue Feb 20 06:27:22 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Tue, 20 Feb 2024 15:27:22 +0100
Subject: [PATCH v8 1/4] kvm: arm64: introduce new flag for non-cacheable
 IO memory
In-Reply-To: <20240220072926.6466-2-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-2-ankita@nvidia.com>
Message-ID: <ZdS2yl1kzZv/h+vH@lpieralisi>

On Tue, Feb 20, 2024 at 12:59:23PM +0530, ankita at nvidia.com wrote:
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> Currently, KVM for ARM64 maps at stage 2 memory that is considered device
> (i.e. it is not RAM) with DEVICE_nGnRE memory attributes; this setting
> overrides (as per the ARM architecture [1]) any device MMIO mapping
> present at stage 1, resulting in a set-up whereby a guest operating
> system cannot determine device MMIO mapping memory attributes on its
> own but it is always overridden by the KVM stage 2 default.
> 
> This set-up does not allow guest operating systems to select device
> memory attributes independently from KVM stage-2 mappings
> (refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
> which turns out to be an issue in that guest operating systems
> (e.g. Linux) may request to map devices MMIO regions with memory
> attributes that guarantee better performance (e.g. gathering
> attribute - that for some devices can generate larger PCIe memory
> writes TLPs) and specific operations (e.g. unaligned transactions)
> such as the NormalNC memory type.
> 
> The default device stage 2 mapping was chosen in KVM for ARM64 since
> it was considered safer (i.e. it would not allow guests to trigger
> uncontained failures ultimately crashing the machine) but this
> turned out to be asynchronous (SError) defeating the purpose.
> 
> Failures containability is a property of the platform and is independent
> from the memory type used for MMIO device memory mappings.
> 
> Actually, DEVICE_nGnRE memory type is even more problematic than
> Normal-NC memory type in terms of faults containability in that e.g.
> aborts triggered on DEVICE_nGnRE loads cannot be made, architecturally,
> synchronous (i.e. that would imply that the processor should issue at
> most 1 load transaction at a time - it cannot pipeline them - otherwise
> the synchronous abort semantics would break the no-speculation attribute
> attached to DEVICE_XXX memory).
> 
> This means that regardless of the combined stage1+stage2 mappings a
> platform is safe if and only if device transactions cannot trigger
> uncontained failures and that in turn relies on platform capabilities
> and the device type being assigned (i.e. PCIe AER/DPC error containment
> and RAS architecture[3]); therefore the default KVM device stage 2
> memory attributes play no role in making device assignment safer
> for a given platform (if the platform design adheres to design
> guidelines outlined in [3]) and therefore can be relaxed.
> 
> For all these reasons, relax the KVM stage 2 device memory attributes
> from DEVICE_nGnRE to Normal-NC.
> 
> The NormalNC was chosen over a different Normal memory type default
> at stage-2 (e.g. Normal Write-through) to avoid cache allocation/snooping.
> 
> Relaxing S2 KVM device MMIO mappings to Normal-NC is not expected to
> trigger any issue on guest device reclaim use cases either (i.e. device
> MMIO unmap followed by a device reset) at least for PCIe devices, in that
> in PCIe a device reset is architected and carried out through PCI config
> space transactions that are naturally ordered with respect to MMIO
> transactions according to the PCI ordering rules.
> 
> Having Normal-NC S2 default puts guests in control (thanks to
> stage1+stage2 combined memory attributes rules [1]) of device MMIO
> regions memory mappings, according to the rules described in [1]
> and summarized here ([(S1) - stage1], [(S2) - stage 2]):
> 
> S1           |  S2           | Result
> NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
> NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
> NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
> DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>
> 
> It is worth noting that currently, to map devices MMIO space to user
> space in a device pass-through use case the VFIO framework applies memory
> attributes derived from pgprot_noncached() settings applied to VMAs, which
> result in device-nGnRnE memory attributes for the stage-1 VMM mappings.
> 
> This means that a userspace mapping for device MMIO space carried
> out with the current VFIO framework and a guest OS mapping for the same
> MMIO space may result in a mismatched alias as described in [2].
> 
> Defaulting KVM device stage-2 mappings to Normal-NC attributes does not
> change anything in this respect, in that the mismatched aliases would
> only affect (refer to [2] for a detailed explanation) ordering between
> the userspace and GuestOS mappings resulting stream of transactions
> (i.e. it does not cause loss of property for either stream of
> transactions on its own), which is harmless given that the userspace
> and GuestOS access to the device is carried out through independent
> transactions streams.
> 
> A Normal-NC flag is not present today. So add a new kvm_pgtable_prot
> (KVM_PGTABLE_PROT_NORMAL_NC) flag for it, along with its
> corresponding PTE value 0x5 (0b101) determined from [1].
> 
> Lastly, adapt the stage2 PTE property setter function
> (stage2_set_prot_attr) to handle the NormalNC attribute.
> 
> [1] section D8.5.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
> [2] section B2.8 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
> [3] sections 1.7.7.3/1.8.5.2/appendix C - DEN0029H_SBSA_7.1.pdf
> 

A couple of Link: tags would not hurt in my opinion, lest we forget:

Link: https://lore.kernel.org/r/20230907181459.18145-2-ankita at nvidia.com/
Link: https://lore.kernel.org/r/20231205033015.10044-1-ankita at nvidia.com

> Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> ---
>  arch/arm64/include/asm/kvm_pgtable.h |  2 ++
>  arch/arm64/include/asm/memory.h      |  2 ++
>  arch/arm64/kvm/hyp/pgtable.c         | 24 +++++++++++++++++++-----
>  3 files changed, 23 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index cfdf40f734b1..19278dfe7978 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -197,6 +197,7 @@ enum kvm_pgtable_stage2_flags {
>   * @KVM_PGTABLE_PROT_W:		Write permission.
>   * @KVM_PGTABLE_PROT_R:		Read permission.
>   * @KVM_PGTABLE_PROT_DEVICE:	Device attributes.
> + * @KVM_PGTABLE_PROT_NORMAL_NC:	Normal noncacheable attributes.
>   * @KVM_PGTABLE_PROT_SW0:	Software bit 0.
>   * @KVM_PGTABLE_PROT_SW1:	Software bit 1.
>   * @KVM_PGTABLE_PROT_SW2:	Software bit 2.
> @@ -208,6 +209,7 @@ enum kvm_pgtable_prot {
>  	KVM_PGTABLE_PROT_R			= BIT(2),
>  
>  	KVM_PGTABLE_PROT_DEVICE			= BIT(3),
> +	KVM_PGTABLE_PROT_NORMAL_NC		= BIT(4),
>  
>  	KVM_PGTABLE_PROT_SW0			= BIT(55),
>  	KVM_PGTABLE_PROT_SW1			= BIT(56),
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index d82305ab420f..449ca2ff1df6 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -173,6 +173,7 @@
>   * Memory types for Stage-2 translation
>   */
>  #define MT_S2_NORMAL		0xf
> +#define MT_S2_NORMAL_NC		0x5
>  #define MT_S2_DEVICE_nGnRE	0x1
>  
>  /*
> @@ -180,6 +181,7 @@
>   * Stage-2 enforces Normal-WB and Device-nGnRE
>   */
>  #define MT_S2_FWB_NORMAL	6
> +#define MT_S2_FWB_NORMAL_NC	5
>  #define MT_S2_FWB_DEVICE_nGnRE	1
>  
>  #ifdef CONFIG_ARM64_4K_PAGES
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index ab9d05fcf98b..3fae5830f8d2 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -717,15 +717,29 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
>  static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
>  				kvm_pte_t *ptep)
>  {
> -	bool device = prot & KVM_PGTABLE_PROT_DEVICE;
> -	kvm_pte_t attr = device ? KVM_S2_MEMATTR(pgt, DEVICE_nGnRE) :
> -			    KVM_S2_MEMATTR(pgt, NORMAL);
> +	kvm_pte_t attr;
>  	u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS;
>  
> +	switch (prot & (KVM_PGTABLE_PROT_DEVICE |
> +			KVM_PGTABLE_PROT_NORMAL_NC)) {
> +	case KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC:
> +		return -EINVAL;
> +	case KVM_PGTABLE_PROT_DEVICE:
> +		if (prot & KVM_PGTABLE_PROT_X)
> +			return -EINVAL;
> +		attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
> +		break;
> +	case KVM_PGTABLE_PROT_NORMAL_NC:
> +		if (prot & KVM_PGTABLE_PROT_X)
> +			return -EINVAL;
> +		attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
> +		break;
> +	default:
> +		attr = KVM_S2_MEMATTR(pgt, NORMAL);
> +	}
> +
>  	if (!(prot & KVM_PGTABLE_PROT_X))
>  		attr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
> -	else if (device)
> -		return -EINVAL;
>  
>  	if (prot & KVM_PGTABLE_PROT_R)
>  		attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
> -- 
> 2.34.1
> 


From thierry.reding at gmail.com  Tue Feb 20 06:28:39 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Tue, 20 Feb 2024 15:28:39 +0100
Subject: [PATCH net-next v3 3/3] net: stmmac: Configure AXI on Tegra234
 MGBE
In-Reply-To: <xne2i6jwqaptsrd2hjdahxbscysgtj7iabqendyjb75fnrjc5z@js7n7qngtzym>
References: <20240219-stmmac-axi-config-v3-0-fca7f046e6ee@nvidia.com>
 <20240219-stmmac-axi-config-v3-3-fca7f046e6ee@nvidia.com>
 <xne2i6jwqaptsrd2hjdahxbscysgtj7iabqendyjb75fnrjc5z@js7n7qngtzym>
Message-ID: <CZ9Z70HO2C7J.398BRNM8NBIG1@gmail.com>

On Mon Feb 19, 2024 at 7:32 PM CET, Serge Semin wrote:
> On Mon, Feb 19, 2024 at 05:46:06PM +0100, Thierry Reding wrote:
> > From: Thierry Reding <treding at nvidia.com>
> > 
> > Allow the device to use bursts and increase the maximum number of
> > outstanding requests to improve performance. Measurements show an
> > increase in throughput of around 5x on a 1 Gbps link.
> > 
> > Signed-off-by: Thierry Reding <treding at nvidia.com>
> > ---
> >  drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> > index bab57d1675df..b6bfa48f279d 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> > @@ -199,6 +199,12 @@ static void mgbe_uphy_lane_bringup_serdes_down(struct net_device *ndev, void *mg
> >  	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
> >  }
> >  
> > +static const struct stmmac_axi tegra234_mgbe_axi = {
> > +	.axi_wr_osr_lmt = 63,
> > +	.axi_rd_osr_lmt = 63,
> > +	.axi_blen = { 256, },
> > +};
> > +
> >  static int tegra_mgbe_probe(struct platform_device *pdev)
> >  {
> >  	struct plat_stmmacenet_data *plat;
> > @@ -284,6 +290,9 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
> >  	if (err < 0)
> >  		goto disable_clks;
> >  
> > +	/* setup default AXI configuration */
> > +	res.axi = &tegra234_mgbe_axi;
> > +
> >  	plat = devm_stmmac_probe_config_dt(pdev, &res);
> >  	if (IS_ERR(plat)) {
> >  		err = PTR_ERR(plat);
>
> Let's get back to the v2 discussion:
>
> On Mon Feb 5, 2024 at 1:44 AM CET, Serge Semin wrote:
> > The entire series can be converted to just a few lines of change:
> >     plat = devm_stmmac_probe_config_dt(pdev, res.mac);
> >     if (IS_ERR(plat)) {
> >             err = PTR_ERR(plat);
> >             goto disable_clks;
> >     }
> > +
> > +   if (IS_ERR_OR_NULL(plat->axi)) {
> > +           plat->axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
> > +           if (!plat->axi) {
> > +                   ret = -ENOMEM;
> > +                   goto disable_clks;
> > +           }
> > +   } /* else memset plat->axi with zeros if you wish */
> > +
> > +   plat->axi->axi_wr_osr_lmt = 63;
> > +   plat->axi->axi_rd_osr_lmt = 63;
> > +   plat->axi->axi_blen[0] = 256;
> >  
> >     plat->has_xgmac = 1;
> >     plat->flags |= STMMAC_FLAG_TSO_EN;
> >     plat->pmt = 1;
> >
> > Please don't overcomplicate the already overcomplicated driver with a
> > functionality which can be reached by the default one. In this case
> > the easiest way is to let the generic code work and then
> > override/replace/fix/etc the retrieved values. Thus there won't be
> > need in adding the redundant functionality and keep the generic
> > DT-platform code a bit simpler to read.
>
> You responded with:
>
> On Tue, Feb 13, 2024 at 04:51:34PM +0100, Thierry Reding wrote:
> > I'm not sure I understand how this is overcomplicating things. The code
> > is pretty much unchanged, except that the AXI configuration can now have
> > driver-specified defaults before the DT is parsed. Perhaps I need to add
> > comments to make that a bit clearer?
> > 
> > While your version is certainly simpler it has the drawback that it no
> > longer allows the platform defaults to be overridden in device tree. I
> > would prefer if the defaults can be derived from the compatible string
> > but if need be for those defaults to still be overridable from device
> > tree.
>
> Currently available functionality is easier to read and understand: by
> default the data is retrieved from the DT, if no AXI DT-node found you
> can allocate/create your own AXI-configs, if there is AXI DT-node you
> can fix it up in whatever way your wish. Thus the default behavior is
> straightforward. You on the contrary suggest to add an additional
> field to the resources structure which would need to be merged in with
> the data retrieved from DT. It makes the stmmac_axi_setup() method and
> the entire logic more complex and thus harder to comprehend.

I suppose that's subjective. Being able to let the driver provide
defaults that can then be overridden by values from DT doesn't seem like
a very exotic (or complicated) feature to me. We do that elsewhere all
the time. Do the comments that I added in this version not sufficiently
explain what's going on?

> The driver is already overwhelmed with flags and private/platform data
> fixing the code here and there (see plat_stmmacenet_data, it's a
> madness). So please justify in more details why do you need one more
> complexity added instead of:
> 1. overriding the AXI-configs retrieved from DT,

Again, overriding the AXI configs read from DT doesn't keep the current
default behaviour of DT being the final authority. That's a policy that
should remain intact. This patch (series) is about allowing the driver
to override the AXI defaults with something that's sensible based on
the compatible string. The current defaults, for example, cause the GBE
on Tegra devices to run at around 100 Mbps even on a 1 Gbps link.

> 2. updating DT on your platform

That's one possibility and was in fact the first variant I used, but it
has a few drawbacks. For example, it means that I need to create the AXI
node just to make the device functional, but if possible it's better to
derive all necessary information from the compatible string. Having this
in a separate AXI configuration node is duplicating information that's
already implied by the compatible string.

Also, on Tegra we have a few instances of this device that are all
configured the same way. Since the AXI configuration node is supposed to
be a child of the Ethernet controller node, we end up having to
duplicate even more information.

Thierry
-------------- 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/20240220/b5a26be6/attachment.sig>

From helen.koike at collabora.com  Tue Feb 20 06:33:55 2024
From: helen.koike at collabora.com (Helen Koike)
Date: Tue, 20 Feb 2024 11:33:55 -0300
Subject: [PATCH v4 3/8] drm: ci: arm64.config: update ONBOARD_USB_HUB to
 ONBOARD_USB_DEV
In-Reply-To: <20240220-onboard_xvf3500-v4-3-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
 <20240220-onboard_xvf3500-v4-3-dc1617cc5dd4@wolfvision.net>
Message-ID: <6e542474-906d-4ad2-9564-47fd44fe6c2d@collabora.com>



On 20/02/2024 11:05, Javier Carrasco wrote:
> The onboard_usb_hub driver has been updated to support non-hub devices,
> which has led to some renaming.
> 
> Update to the new name (ONBOARD_USB_DEV) accordingly.
> 
> Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>

Acked-by: Helen Koike <helen.koike at collabora.com>

Regards,
Helen

> ---
>   drivers/gpu/drm/ci/arm64.config | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/ci/arm64.config b/drivers/gpu/drm/ci/arm64.config
> index 8dbce9919a57..4140303d6260 100644
> --- a/drivers/gpu/drm/ci/arm64.config
> +++ b/drivers/gpu/drm/ci/arm64.config
> @@ -87,7 +87,7 @@ CONFIG_DRM_PARADE_PS8640=y
>   CONFIG_DRM_LONTIUM_LT9611UXC=y
>   CONFIG_PHY_QCOM_USB_HS=y
>   CONFIG_QCOM_GPI_DMA=y
> -CONFIG_USB_ONBOARD_HUB=y
> +CONFIG_USB_ONBOARD_DEV=y
>   CONFIG_NVMEM_QCOM_QFPROM=y
>   CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y
>   
> @@ -97,7 +97,7 @@ CONFIG_USB_RTL8152=y
>   # db820c ethernet
>   CONFIG_ATL1C=y
>   # Chromebooks ethernet
> -CONFIG_USB_ONBOARD_HUB=y
> +CONFIG_USB_ONBOARD_DEV=y
>   # 888 HDK ethernet
>   CONFIG_USB_LAN78XX=y
>   
> 


From alexander.stein at ew.tq-group.com  Tue Feb 20 06:34:55 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 20 Feb 2024 15:34:55 +0100
Subject: [PATCH v4 0/8] usb: misc: onboard_hub: add support for XMOS XVF3500
In-Reply-To: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
Message-ID: <3548824.iIbC2pHGDl@steina-w>

Hi,

Am Dienstag, 20. Februar 2024, 15:05:44 CET schrieb Javier Carrasco:
> This series adds support for the XMOS XVF3500 VocalFusion Voice
> Processor[1], a low-latency, 32-bit multicore controller for voice
> processing.
> 
> The XVF3500 requires a specific power sequence, which consists of
> enabling the regulators that control the 3V3 and 1V0 device supplies,
> and a reset de-assertion after a delay of at least 100ns. Once in normal
> operation, the XVF3500 registers itself as a regular USB device and no
> device-specific management is required.

While reading this, [1] come into my mind.

Best regards,
Alexander

[1] https://lore.kernel.org/all/20211006035407.1147909-1-dmitry.baryshkov at linaro.org/

> The power management provided by onboard_usb_hub is not specific for hubs
> and any other USB device with the same power sequence could profit from
> that driver, provided that the device does not have any specific
> requirements beyond the power management. To account for non-hub devices,
> the driver has been renamed and an extra flag has been added to identify
> hubs and provide their specific functionality. Support for
> device-specific power suply names has been added, keeping generic names
> for backwards compatibility and as a fallback mechanism.
> 
> The references to onboard_usb_hub in the core and config files have been
> updated as well.
> 
> The diff is way much bulkier than the actual code addition because of the
> file renaming, so in order to ease reviews and catch hub-specific code
> that might still affect non-hub devices, the complete renaming was moved
> to a single commit.
> 
> The device binding has been added to sound/ because it is the subsystem
> that covers its functionality (voice processing) during normal
> operation. If it should reside under usb/ instead, it will be moved as
> required.
> 
> This series has been tested with a Rockchip-based SoC and an XMOS
> XVF3500-FB167-C.
> 
> [1] https://www.xmos.com/xvf3500/
> 
> To: Liam Girdwood <lgirdwood at gmail.com>
> To: Mark Brown <broonie at kernel.org>
> To: Rob Herring <robh+dt at kernel.org>
> To: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
> To: Conor Dooley <conor+dt at kernel.org>
> To: Matthias Kaehlcke <mka at chromium.org>
> To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> To: Helen Koike <helen.koike at collabora.com>
> To: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> To: Maxime Ripard <mripard at kernel.org>
> To: Thomas Zimmermann <tzimmermann at suse.de>
> To: David Airlie <airlied at gmail.com>
> To: Daniel Vetter <daniel at ffwll.ch>
> To: Catalin Marinas <catalin.marinas at arm.com>
> To: Will Deacon <will at kernel.org>
> To: Russell King <linux at armlinux.org.uk>
> Cc: linux-sound at vger.kernel.org
> Cc: devicetree at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-usb at vger.kernel.org
> Cc: dri-devel at lists.freedesktop.org
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
> 
> Changes in v4:
> - General: use device supply names and generics as fallback.
> - onbord_usb_dev.c: fix suspend callback for non-hub devices.
> - onboard_usb_dev.c: fix typos.
> 
> - Link to v3: https://lore.kernel.org/r/20240206-onboard_xvf3500-v3-0-f85b04116688 at wolfvision.net
> 
> Changes in v3:
> - onboard_usb_hub: rename to onboard_usb_dev to include non-hub devices.
> - onboard_hub_dev: add flag to identify hubs and provide their extra
>   functionality.
> - dt-bindings: add reference to usb-device.yaml and usb node in the
>   example.
> - dt-bindings: generic node name.
> - Link to v2: https://lore.kernel.org/r/20240130-onboard_xvf3500-v1-0-51b5398406cb at wolfvision.net
> 
> Changes in v2:
> - general: add support in onboard_usb_hub instead of using a dedicated
>   driver.
> - dt-bindings: use generic usb-device compatible ("usbVID,PID").
> - Link to v1: https://lore.kernel.org/all/20240115-feature-xvf3500_driver-v1-0-ed9cfb48bb85 at wolfvision.net/
> 
> ---
> Javier Carrasco (8):
>       usb: misc: onboard_hub: rename to onboard_dev
>       usb: misc: onboard_dev: add support for non-hub devices
>       drm: ci: arm64.config: update ONBOARD_USB_HUB to ONBOARD_USB_DEV
>       arm64: defconfig: update ONBOARD_USB_HUB to ONBOARD_USB_DEV
>       ARM: multi_v7_defconfig: update ONBOARD_USB_HUB name
>       usb: misc: onboard_dev: use device supply names
>       ASoC: dt-bindings: xmos,xvf3500: add XMOS XVF3500 voice processor
>       usb: misc: onboard_hub: add support for XMOS XVF3500
> 
>  ...-usb-hub => sysfs-bus-platform-onboard-usb-dev} |   4 +-
>  .../devicetree/bindings/sound/xmos,xvf3500.yaml    |  63 +++
>  MAINTAINERS                                        |   4 +-
>  arch/arm/configs/multi_v7_defconfig                |   2 +-
>  arch/arm64/configs/defconfig                       |   2 +-
>  drivers/gpu/drm/ci/arm64.config                    |   4 +-
>  drivers/usb/core/Makefile                          |   4 +-
>  drivers/usb/core/hub.c                             |   8 +-
>  drivers/usb/core/hub.h                             |   2 +-
>  drivers/usb/misc/Kconfig                           |  16 +-
>  drivers/usb/misc/Makefile                          |   2 +-
>  drivers/usb/misc/onboard_usb_dev.c                 | 525 +++++++++++++++++++++
>  .../misc/{onboard_usb_hub.h => onboard_usb_dev.h}  |  69 ++-
>  ...ard_usb_hub_pdevs.c => onboard_usb_dev_pdevs.c} |  47 +-
>  drivers/usb/misc/onboard_usb_hub.c                 | 501 --------------------
>  include/linux/usb/onboard_dev.h                    |  18 +
>  include/linux/usb/onboard_hub.h                    |  18 -
>  17 files changed, 709 insertions(+), 580 deletions(-)
> ---
> base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
> change-id: 20240130-onboard_xvf3500-6c0e78d11a1b
> 
> Best regards,
> 


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From gregkh at linuxfoundation.org  Tue Feb 20 06:35:53 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Tue, 20 Feb 2024 15:35:53 +0100
Subject: 6.7 regression: platform 4809c000.mmc: deferred probe pending
In-Reply-To: <2024021516-stricken-bubble-bf8d@gregkh>
References: <mvmcyt13idm.fsf@suse.de>
 <c92385d2-1909-43a8-aea8-cd9a8687a898@leemhuis.info>
 <20240215094640.GS52537@atomide.com>
 <mvmeddeyqb8.fsf@suse.de>
 <2024021516-stricken-bubble-bf8d@gregkh>
Message-ID: <2024022022-happiest-affirm-60cf@gregkh>

On Thu, Feb 15, 2024 at 12:16:34PM +0100, Greg KH wrote:
> On Thu, Feb 15, 2024 at 11:28:27AM +0100, Andreas Schwab wrote:
> > On Feb 15 2024, Tony Lindgren wrote:
> > 
> > > There was a regression recently with the PMIC which would cause NFSroot
> > > on devices to keep working but may have affected MMC. Please check that
> > > commit 7a29fa05aeca ("mfd: twl6030-irq: Revert to use of_match_device()")
> > > is applied.
> > 
> > That commit hasn't hit stable yet.  Maybe it's because it references a
> > non-existant commit id (1e0c866887f4 instead of 830fafce06e6).
> 
> Yeah, our tools can't do about a commit that does not have a cc: stable@
> tag in it AND the only commit it does reference is not one actually in
> the tree at all.
> 
> An impossible task for us here, please ask stable at vger.kernel.org to
> take the commit if this is needed, and let us know how far back it
> should go.

To be explicit, does this need to be applied to the stable tree(s)?  If
so, please email stable at vger.kernel.org with the git id to do so.

thanks,

greg k-h


From vladimir.oltean at nxp.com  Tue Feb 20 06:50:37 2024
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Tue, 20 Feb 2024 16:50:37 +0200
Subject: [PATCH] arm64: ls1046ardb: Replace XGMII with 10GBASE-R phy mode
In-Reply-To: <20240214-ls1046-dts-use-10gbase-r-v1-1-8c2d68547393@concurrent-rt.com>
Message-ID: <20240220145037.kf3avnykjif24kkr@skbuf>

Hi Zachary,

On Wed, Feb 14, 2024 at 05:21:54PM -0500, Zachary Goldstein via B4 Relay wrote:
> From: Zachary Goldstein <zachary.goldstein at concurrent-rt.com>
> 
> The AQR107 family does not support XGMII, but USXGMII and
> 10GBASE-R instead. Since ce64c1f77a9d ("net: phy: aquantia: add USXGMII
> support and warn if XGMII mode is set") the kernel warns about XGMII
> being used. The LS1046A SoC does not support USXGMII, so use 10GBASE-R
> instead.
> 
> Signed-off-by: Zachary Goldstein <zachary.goldstein at concurrent-rt.com>
> ---
>  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> index 07f6cc6e354a..d2066f733dc5 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> @@ -149,7 +149,7 @@ ethernet at ea000 {
>  
>  	ethernet at f0000 { /* 10GEC1 */
>  		phy-handle = <&aqr106_phy>;
> -		phy-connection-type = "xgmii";
> +		phy-connection-type = "10gbase-r";
>  	};
>  
>  	ethernet at f2000 { /* 10GEC2 */
> 
> ---
> 2.40.1
> base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de
> 
> 

You do not need this patch in upstream, and I strongly advise against
merging it as-is. I've just tested pure net-next on LS1046A-RDB, and I
can bring up fm1-mac9 without any warning.

You'll notice that commit 5d93cfcf7360 ("net: dpaa: Convert to phylink")
did this in fman_memac.c:

	/* The internal connection to the serdes is XGMII, but this isn't
	 * really correct for the phy mode (which is the external connection).
	 * However, this is how all older device trees say that they want
	 * 10GBASE-R (aka XFI), so just convert it for them.
	 */
	if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
		mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;

So, what gets passed to the Aquantia PHY is PHY_INTERFACE_MODE_10GBASER,
even if in the device tree, phy-connection-type = "xgmii".

Now, _if_ your patch were to be applied on top of upstream, it would
actually break fm1-mac9 like this (WARN_ON added by me for a call stack
of the phylink_validate() failure path):

WARNING: CPU: 2 PID: 1 at drivers/net/phy/phylink.c:763 phylink_create+0x8f8/0x90c
Modules linked in:
CPU: 2 PID: 1 Comm: swapper/0 Tainted: G        W          6.8.0-rc4-01058-g9e1deba407fb #1812
Hardware name: LS1046A RDB Board (DT)
Call trace:
 phylink_create+0x8f8/0x90c
 dpaa_netdev_init+0x1a8/0x2c8
 dpaa_eth_probe+0xd70/0xf64
 platform_probe+0xa8/0xd0
 really_probe+0x130/0x2e4
 __driver_probe_device+0xa0/0x128
 driver_probe_device+0x3c/0x200
 __driver_attach+0xe8/0x1b4
 bus_for_each_dev+0xec/0x144
 driver_attach+0x24/0x30
 bus_add_driver+0x154/0x244
 driver_register+0x68/0x100
 __platform_driver_register+0x24/0x30
 dpaa_load+0x34/0x64
 do_one_initcall+0xf8/0x34c
---[ end trace 0000000000000000 ]---
fsl_dpaa_mac 1af0000.ethernet (unnamed net_device) (uninitialized): failed to validate link configuration for in-band status
fsl_dpaa_mac 1af0000.ethernet: error -EINVAL: Could not create phylink
fsl_dpa: probe of dpaa-ethernet.4 failed with error -22

It fails because of this in phylink_validate():

	if (!test_bit(state->interface, interfaces))
		return -EINVAL;

And state->interface (PHY_INTERFACE_MODE_10GBASER) is not in
mac_dev->phylink_config.supported_interfaces, because the fman_memac
code is not prepared to handle this combination.

The device tree node for fm1-mac9 looks like this, generated by an
awkward merge between the following:

	ethernet at f0000 {
		phy-connection-type = "xgmii";	// fsl-ls1046a-rdb.dts
		local-mac-address = [...];	// U-Boot
		cell-index = <0x8>;		// qoriq-fman3-0-10g-0.dtsi
		pcsphy-handle = <0x31>;		// qoriq-fman3-0-10g-0.dtsi
		compatible = "fsl,fman-memac";	// qoriq-fman3-0-10g-0.dtsi
		reg = <0xf0000 0x1000>;		// qoriq-fman3-0-10g-0.dtsi
		phy-handle = <&aqr106_phy>;	// fsl-ls1046a-rdb.dts
		fsl,fman-ports = <0x2f 0x30>;	// qoriq-fman3-0-10g-0.dtsi
	};

Notice that unlike fm1-mac10 (node "ethernet at f2000"), there is no
pcs-handle-names property (fm1-mac10 has it defined in fsl-ls1046-post.dtsi,
whereas fm1-mac9 doesn't. Don't ask me why, I don't know....)

So, knowing that of_property_match_string(mac_node, "pcs-handle-names", "xfi")
will return an error code for fm1-mac9, now please walk through memac_initialization()
and see what happens in the 2 cases:

- mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII (current device tree). The
  code creates a default PCS and assigns it to memac->xfi_pcs like this:
	if (err == -EINVAL || err == -ENODATA)
		pcs = memac_pcs_create(mac_node, 0);
	(...)
	if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
		memac->xfi_pcs = pcs;

- mac_dev->phy_if == PHY_INTERFACE_MODE_10GBASER (your modification).
  The code will still create the default PCS, but assign it to
  memac->sgmii_pcs instead!

	if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) // not XGMII, but 10GBASER!
		memac->xfi_pcs = pcs;
	else
		memac->sgmii_pcs = pcs;

And this is why, with a NULL memac->xfi_pcs, PHY_INTERFACE_MODE_10GBASER
will not be in phylink's supported_interfaces.

To make your device tree patch work as intended with the current
mainline code, what you want is to also modify the driver like this:

>From d6bda34b132d17d1c236d27436b9335fac22c062 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean at nxp.com>
Date: Tue, 20 Feb 2024 16:12:27 +0200
Subject: [PATCH] net: dpaa: fman_memac: accept phy-interface-type =
 "10gbase-r" in the device tree

We support the phy-interface-mode = "xgmii" conversion to "10gbase-r"
through code, but not actually through the device tree proper. This is
because boards such as LS1046A-RDB do not define pcs-handle-names in the
ethernet at f0000 device tree node, and the code only has fallback xfi_pcs
determination logic for "xgmii".

By reversing the order between the fallback xfi_pcs assignment and the
"xgmii" overwrite with "10gbase-r", we are able to support both values
in the device tree, with identical behavior.

Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
 .../net/ethernet/freescale/fman/fman_memac.c   | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index e30bf75b1d48..0996759907a8 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -1076,6 +1076,14 @@ int memac_initialization(struct mac_device *mac_dev,
 	unsigned long		 capabilities;
 	unsigned long		*supported;
 
+	/* The internal connection to the serdes is XGMII, but this isn't
+	 * really correct for the phy mode (which is the external connection).
+	 * However, this is how all older device trees say that they want
+	 * 10GBASE-R (aka XFI), so just convert it for them.
+	 */
+	if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
+		mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
+
 	mac_dev->phylink_ops		= &memac_mac_ops;
 	mac_dev->set_promisc		= memac_set_promiscuous;
 	mac_dev->change_addr		= memac_modify_mac_address;
@@ -1142,7 +1150,7 @@ int memac_initialization(struct mac_device *mac_dev,
 	 * (and therefore that xfi_pcs cannot be set). If we are defaulting to
 	 * XGMII, assume this is for XFI. Otherwise, assume it is for SGMII.
 	 */
-	if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
+	if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_10GBASER)
 		memac->xfi_pcs = pcs;
 	else
 		memac->sgmii_pcs = pcs;
@@ -1156,14 +1164,6 @@ int memac_initialization(struct mac_device *mac_dev,
 		goto _return_fm_mac_free;
 	}
 
-	/* The internal connection to the serdes is XGMII, but this isn't
-	 * really correct for the phy mode (which is the external connection).
-	 * However, this is how all older device trees say that they want
-	 * 10GBASE-R (aka XFI), so just convert it for them.
-	 */
-	if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
-		mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
-
 	/* TODO: The following interface modes are supported by (some) hardware
 	 * but not by this driver:
 	 * - 1000BASE-KX

But!

Device tree is stable ABI, and changes made to the device tree file are
meant to be backwards and forwards compatible with the code (it can be
provided separately and not necessarily in lockstep with the kernel
version. For example, I understand Arm SystemReady IR wants U-Boot to
provide its own device tree to Linux through EFI). So, in general,
device tree changes which only work with a corresponding kernel change
are frowned upon (unless maybe if the kernel change is a bug fix that is
backported to all relevant stable kernel branches).

So at this stage we should take a step back and re-analyze the cost/benefit.
You said there is a stack trace in the Aquantia PHY driver, which there
is not (in current mainline kernels). I _think_ you are seeing the stack
trace with LSDK, which is currently distributed on top of linux-6.1.y
and has not yet integrated the fman_memac conversion to phylink - thus,
it does not contain commit 5d93cfcf7360 ("net: dpaa: Convert to phylink").
At least, I do see this stack trace there. I think it can also be seen
with mainline kernels before the phylink conversion, but I did not test
those.

The main take-away is: ALWAYS test the patch you are submitting to the
target kernel it is going to be applied to. Especially in the area of
device tree bindings for DPAA1, things are rarely as simple as they
appear :) If you don't, you will have an unintended negative effect
upon current mainline kernels (which must still work), and not the
intended effect upon LSDK (more below).

There are a few options to go forward from here.

As there is nothing broken in the mainline kernel where you are
submitting this patch, the simplest one, as bland as it may sound, is
simply to wait for a new LSDK release on top of linux-6.6.y. Even in
lf-6.1.y, AFAICS, nothing is broken except for the stack trace. You can
keep the patch in your local kernel tree copy to suppress that.

The other option would be to submit the fman_memac change as a bug fix
for stable, wait for a while for it to have time to propagate, then
modify the device tree as well. But, it is much higher effort, and
there is no procedure in place, AFAIK, for LSDK to integrate your patch
(other than through upstream + a few months of waiting). The upcoming
LSDK release will be on top of linux-6.6.y, it will make your effort
irrelevant if it's only for suppressing the stack trace, and you are
racing against it. This path is only worth it if you have the dedication
to dig a bit deeper and tidy things up in the DPAA1 kernel support
(which would be appreciated though).

_If_ you are using an older linux-stable branch but not LSDK, yes, the
feedback loop between your patch and its effect will close much sooner,
but you will have to convince the linux-stable people that it's worth
accepting your driver rework patches for a functional reason and not
just aesthetic (see Documentation/process/stable-kernel-rules.rst for
reference).


From paul at paul-moore.com  Tue Feb 20 06:59:23 2024
From: paul at paul-moore.com (Paul Moore)
Date: Tue, 20 Feb 2024 09:59:23 -0500
Subject: arm64/for-kernelci build: 1 build: 0 failed, 1 passed, 1 warning (v6.8-rc4-55-g905b00721763)
In-Reply-To: <20240220114937.GA5545@willie-the-truck>
References: <65cfcc14.170a0220.b8b50.24d9@mx.google.com> <20240220114937.GA5545@willie-the-truck>
Message-ID: <CAHC9VhS4wFVAbaC2vuHvdbP6ny6Sg0jgASrtbPUtH0Am95h56g@mail.gmail.com>

On Tue, Feb 20, 2024 at 6:49?AM Will Deacon <will at kernel.org> wrote:
>
> [+Paul Moore for the array bounds warning]
>
> On Fri, Feb 16, 2024 at 12:56:52PM -0800, kernelci.org bot wrote:
> > arm64/for-kernelci build: 1 build: 0 failed, 1 passed, 1 warning (v6.8-rc4-55-g905b00721763)
> >
> > Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v6.8-rc4-55-g905b00721763/
> >
> > Tree: arm64
> > Branch: for-kernelci
> > Git Describe: v6.8-rc4-55-g905b00721763
> > Git Commit: 905b007217637b34a6a877271f21ed0dada0f564
> > Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
> > Built: 1 unique architecture
> >
> > Warnings Detected:
> >
> > arm64:
> >     defconfig (gcc-10): 1 warning
> >
> >
> > Warnings summary:
> >
> >     1    security/security.c:810:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]
> >
> > ================================================================================
> >
> > Detailed per-defconfig build reports:
> >
> > --------------------------------------------------------------------------------
> > defconfig (arm64, gcc-10) ? PASS, 0 errors, 1 warning, 0 section mismatches
> >
> > Warnings:
> >     security/security.c:810:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]
>
> Paul, sorry if you've had lots of these reports already, but this one keeps
> showing up in our CI and I don't think it's related to any of our arm64
> changes. So, on the off chance that you're not aware, here it is!

Hi Will,

Yes, I've seen this reported quite a bit and I've double (triple ...)
checked that it is a bogus warning.  Kees mentioned that it was due to
a known gcc bug so I've been ignoring it, I would appreciate it if you
could do the same.  I love to see bugs reported during the development
cycle - thanks for your help in this regard! - but I do get tired of
seeing the same bogus warnings caused by a buggy toolchain.

-- 
paul-moore.com


From vincent.guittot at linaro.org  Tue Feb 20 06:59:42 2024
From: vincent.guittot at linaro.org (Vincent Guittot)
Date: Tue, 20 Feb 2024 15:59:42 +0100
Subject: [PATCH v5 0/5] Rework system pressure interface to the scheduler
Message-ID: <20240220145947.1107937-1-vincent.guittot@linaro.org>

Following the consolidation and cleanup of CPU capacity in [1], this serie
reworks how the scheduler gets the pressures on CPUs. We need to take into
account all pressures applied by cpufreq on the compute capacity of a CPU
for dozens of ms or more and not only cpufreq cooling device or HW
mitigiations. We split the pressure applied on CPU's capacity in 2 parts:
- one from cpufreq and freq_qos
- one from HW high freq mitigiation.

The next step will be to add a dedicated interface for long standing
capping of the CPU capacity (i.e. for seconds or more) like the
scaling_max_freq of cpufreq sysfs. The latter is already taken into
account by this serie but as a temporary pressure which is not always the
best choice when we know that it will happen for seconds or more.

[1] https://lore.kernel.org/lkml/20231211104855.558096-1-vincent.guittot at linaro.org/

Change since v4:
- Add READ_ONCE() in cpufreq_get_pressure()
- Add ack and reviewed tags

Change since v3:
- Fix uninitialized variables in cpufreq_update_pressure()

Change since v2:
- Rework cpufreq_update_pressure()

Change since v1:
- Use struct cpufreq_policy as parameter of cpufreq_update_pressure()
- Fix typos and comments
- Make sched_thermal_decay_shift boot param as deprecated

Vincent Guittot (5):
  cpufreq: Add a cpufreq pressure feedback for the scheduler
  sched: Take cpufreq feedback into account
  thermal/cpufreq: Remove arch_update_thermal_pressure()
  sched: Rename arch_update_thermal_pressure into
    arch_update_hw_pressure
  sched/pelt: Remove shift of thermal clock

 .../admin-guide/kernel-parameters.txt         |  1 +
 arch/arm/include/asm/topology.h               |  6 +-
 arch/arm64/include/asm/topology.h             |  6 +-
 drivers/base/arch_topology.c                  | 26 ++++----
 drivers/cpufreq/cpufreq.c                     | 36 +++++++++++
 drivers/cpufreq/qcom-cpufreq-hw.c             |  4 +-
 drivers/thermal/cpufreq_cooling.c             |  3 -
 include/linux/arch_topology.h                 |  8 +--
 include/linux/cpufreq.h                       | 10 +++
 include/linux/sched/topology.h                |  8 +--
 .../{thermal_pressure.h => hw_pressure.h}     | 14 ++---
 include/trace/events/sched.h                  |  2 +-
 init/Kconfig                                  | 12 ++--
 kernel/sched/core.c                           |  8 +--
 kernel/sched/fair.c                           | 63 +++++++++----------
 kernel/sched/pelt.c                           | 18 +++---
 kernel/sched/pelt.h                           | 16 ++---
 kernel/sched/sched.h                          | 22 +------
 18 files changed, 144 insertions(+), 119 deletions(-)
 rename include/trace/events/{thermal_pressure.h => hw_pressure.h} (55%)

-- 
2.34.1



From vincent.guittot at linaro.org  Tue Feb 20 06:59:43 2024
From: vincent.guittot at linaro.org (Vincent Guittot)
Date: Tue, 20 Feb 2024 15:59:43 +0100
Subject: [PATCH v5 1/5] cpufreq: Add a cpufreq pressure feedback for the scheduler
In-Reply-To: <20240220145947.1107937-1-vincent.guittot@linaro.org>
References: <20240220145947.1107937-1-vincent.guittot@linaro.org>
Message-ID: <20240220145947.1107937-2-vincent.guittot@linaro.org>

Provide to the scheduler a feedback about the temporary max available
capacity. Unlike arch_update_thermal_pressure, this doesn't need to be
filtered as the pressure will happen for dozens ms or more.

Signed-off-by: Vincent Guittot <vincent.guittot at linaro.org>
Acked-by: Rafael J. Wysocki <rafael at kernel.org>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
Reviewed-by: Qais Yousef <qyousef at layalina.io>
---
 drivers/cpufreq/cpufreq.c | 36 ++++++++++++++++++++++++++++++++++++
 include/linux/cpufreq.h   | 10 ++++++++++
 2 files changed, 46 insertions(+)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 44db4f59c4cc..f4eee3d107f1 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2563,6 +2563,40 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
 }
 EXPORT_SYMBOL(cpufreq_get_policy);
 
+DEFINE_PER_CPU(unsigned long, cpufreq_pressure);
+
+/**
+ * cpufreq_update_pressure() - Update cpufreq pressure for CPUs
+ * @policy: cpufreq policy of the CPUs.
+ *
+ * Update the value of cpufreq pressure for all @cpus in the policy.
+ */
+static void cpufreq_update_pressure(struct cpufreq_policy *policy)
+{
+	unsigned long max_capacity, capped_freq, pressure;
+	u32 max_freq;
+	int cpu;
+
+	cpu = cpumask_first(policy->related_cpus);
+	max_freq = arch_scale_freq_ref(cpu);
+	capped_freq = policy->max;
+
+	/*
+	 * Handle properly the boost frequencies, which should simply clean
+	 * the cpufreq pressure value.
+	 */
+	if (max_freq <= capped_freq) {
+		pressure = 0;
+	} else {
+		max_capacity = arch_scale_cpu_capacity(cpu);
+		pressure = max_capacity -
+			   mult_frac(max_capacity, capped_freq, max_freq);
+	}
+
+	for_each_cpu(cpu, policy->related_cpus)
+		WRITE_ONCE(per_cpu(cpufreq_pressure, cpu), pressure);
+}
+
 /**
  * cpufreq_set_policy - Modify cpufreq policy parameters.
  * @policy: Policy object to modify.
@@ -2618,6 +2652,8 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
 	policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H);
 	trace_cpu_frequency_limits(policy);
 
+	cpufreq_update_pressure(policy);
+
 	policy->cached_target_freq = UINT_MAX;
 
 	pr_debug("new min and max freqs are %u - %u kHz\n",
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index afda5f24d3dd..13b69a816747 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -241,6 +241,12 @@ struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy);
 void cpufreq_enable_fast_switch(struct cpufreq_policy *policy);
 void cpufreq_disable_fast_switch(struct cpufreq_policy *policy);
 bool has_target_index(void);
+
+DECLARE_PER_CPU(unsigned long, cpufreq_pressure);
+static inline unsigned long cpufreq_get_pressure(int cpu)
+{
+	return READ_ONCE(per_cpu(cpufreq_pressure, cpu));
+}
 #else
 static inline unsigned int cpufreq_get(unsigned int cpu)
 {
@@ -263,6 +269,10 @@ static inline bool cpufreq_supports_freq_invariance(void)
 	return false;
 }
 static inline void disable_cpufreq(void) { }
+static inline unsigned long cpufreq_get_pressure(int cpu)
+{
+	return 0;
+}
 #endif
 
 #ifdef CONFIG_CPU_FREQ_STAT
-- 
2.34.1



From vincent.guittot at linaro.org  Tue Feb 20 06:59:44 2024
From: vincent.guittot at linaro.org (Vincent Guittot)
Date: Tue, 20 Feb 2024 15:59:44 +0100
Subject: [PATCH v5 2/5] sched: Take cpufreq feedback into account
In-Reply-To: <20240220145947.1107937-1-vincent.guittot@linaro.org>
References: <20240220145947.1107937-1-vincent.guittot@linaro.org>
Message-ID: <20240220145947.1107937-3-vincent.guittot@linaro.org>

Aggregate the different pressures applied on the capacity of CPUs and
create a new function that returns the actual capacity of the CPU:
  get_actual_cpu_capacity()

Signed-off-by: Vincent Guittot <vincent.guittot at linaro.org>
Reviewed-by: Lukasz Luba <lukasz.luba at arm.com>
Reviewed-by: Qais Yousef <qyousef at layalina.io>
---
 kernel/sched/fair.c | 45 +++++++++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 8e30e2bb77a0..9c650b860946 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4959,13 +4959,22 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
 	trace_sched_util_est_se_tp(&p->se);
 }
 
+static inline unsigned long get_actual_cpu_capacity(int cpu)
+{
+	unsigned long capacity = arch_scale_cpu_capacity(cpu);
+
+	capacity -= max(thermal_load_avg(cpu_rq(cpu)), cpufreq_get_pressure(cpu));
+
+	return capacity;
+}
+
 static inline int util_fits_cpu(unsigned long util,
 				unsigned long uclamp_min,
 				unsigned long uclamp_max,
 				int cpu)
 {
-	unsigned long capacity_orig, capacity_orig_thermal;
 	unsigned long capacity = capacity_of(cpu);
+	unsigned long capacity_orig;
 	bool fits, uclamp_max_fits;
 
 	/*
@@ -4997,7 +5006,6 @@ static inline int util_fits_cpu(unsigned long util,
 	 * goal is to cap the task. So it's okay if it's getting less.
 	 */
 	capacity_orig = arch_scale_cpu_capacity(cpu);
-	capacity_orig_thermal = capacity_orig - arch_scale_thermal_pressure(cpu);
 
 	/*
 	 * We want to force a task to fit a cpu as implied by uclamp_max.
@@ -5072,7 +5080,8 @@ static inline int util_fits_cpu(unsigned long util,
 	 * handle the case uclamp_min > uclamp_max.
 	 */
 	uclamp_min = min(uclamp_min, uclamp_max);
-	if (fits && (util < uclamp_min) && (uclamp_min > capacity_orig_thermal))
+	if (fits && (util < uclamp_min) &&
+	    (uclamp_min > get_actual_cpu_capacity(cpu)))
 		return -1;
 
 	return fits;
@@ -7453,7 +7462,7 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
 		 * Look for the CPU with best capacity.
 		 */
 		else if (fits < 0)
-			cpu_cap = arch_scale_cpu_capacity(cpu) - thermal_load_avg(cpu_rq(cpu));
+			cpu_cap = get_actual_cpu_capacity(cpu);
 
 		/*
 		 * First, select CPU which fits better (-1 being better than 0).
@@ -7946,8 +7955,8 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 	struct root_domain *rd = this_rq()->rd;
 	int cpu, best_energy_cpu, target = -1;
 	int prev_fits = -1, best_fits = -1;
-	unsigned long best_thermal_cap = 0;
-	unsigned long prev_thermal_cap = 0;
+	unsigned long best_actual_cap = 0;
+	unsigned long prev_actual_cap = 0;
 	struct sched_domain *sd;
 	struct perf_domain *pd;
 	struct energy_env eenv;
@@ -7977,7 +7986,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 
 	for (; pd; pd = pd->next) {
 		unsigned long util_min = p_util_min, util_max = p_util_max;
-		unsigned long cpu_cap, cpu_thermal_cap, util;
+		unsigned long cpu_cap, cpu_actual_cap, util;
 		long prev_spare_cap = -1, max_spare_cap = -1;
 		unsigned long rq_util_min, rq_util_max;
 		unsigned long cur_delta, base_energy;
@@ -7989,18 +7998,17 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 		if (cpumask_empty(cpus))
 			continue;
 
-		/* Account thermal pressure for the energy estimation */
+		/* Account external pressure for the energy estimation */
 		cpu = cpumask_first(cpus);
-		cpu_thermal_cap = arch_scale_cpu_capacity(cpu);
-		cpu_thermal_cap -= arch_scale_thermal_pressure(cpu);
+		cpu_actual_cap = get_actual_cpu_capacity(cpu);
 
-		eenv.cpu_cap = cpu_thermal_cap;
+		eenv.cpu_cap = cpu_actual_cap;
 		eenv.pd_cap = 0;
 
 		for_each_cpu(cpu, cpus) {
 			struct rq *rq = cpu_rq(cpu);
 
-			eenv.pd_cap += cpu_thermal_cap;
+			eenv.pd_cap += cpu_actual_cap;
 
 			if (!cpumask_test_cpu(cpu, sched_domain_span(sd)))
 				continue;
@@ -8071,7 +8079,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 			if (prev_delta < base_energy)
 				goto unlock;
 			prev_delta -= base_energy;
-			prev_thermal_cap = cpu_thermal_cap;
+			prev_actual_cap = cpu_actual_cap;
 			best_delta = min(best_delta, prev_delta);
 		}
 
@@ -8086,7 +8094,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 			 * but best energy cpu has better capacity.
 			 */
 			if ((max_fits < 0) &&
-			    (cpu_thermal_cap <= best_thermal_cap))
+			    (cpu_actual_cap <= best_actual_cap))
 				continue;
 
 			cur_delta = compute_energy(&eenv, pd, cpus, p,
@@ -8107,14 +8115,14 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 			best_delta = cur_delta;
 			best_energy_cpu = max_spare_cap_cpu;
 			best_fits = max_fits;
-			best_thermal_cap = cpu_thermal_cap;
+			best_actual_cap = cpu_actual_cap;
 		}
 	}
 	rcu_read_unlock();
 
 	if ((best_fits > prev_fits) ||
 	    ((best_fits > 0) && (best_delta < prev_delta)) ||
-	    ((best_fits < 0) && (best_thermal_cap > prev_thermal_cap)))
+	    ((best_fits < 0) && (best_actual_cap > prev_actual_cap)))
 		target = best_energy_cpu;
 
 	return target;
@@ -9490,8 +9498,8 @@ static inline void init_sd_lb_stats(struct sd_lb_stats *sds)
 
 static unsigned long scale_rt_capacity(int cpu)
 {
+	unsigned long max = get_actual_cpu_capacity(cpu);
 	struct rq *rq = cpu_rq(cpu);
-	unsigned long max = arch_scale_cpu_capacity(cpu);
 	unsigned long used, free;
 	unsigned long irq;
 
@@ -9503,12 +9511,9 @@ static unsigned long scale_rt_capacity(int cpu)
 	/*
 	 * avg_rt.util_avg and avg_dl.util_avg track binary signals
 	 * (running and not running) with weights 0 and 1024 respectively.
-	 * avg_thermal.load_avg tracks thermal pressure and the weighted
-	 * average uses the actual delta max capacity(load).
 	 */
 	used = READ_ONCE(rq->avg_rt.util_avg);
 	used += READ_ONCE(rq->avg_dl.util_avg);
-	used += thermal_load_avg(rq);
 
 	if (unlikely(used >= max))
 		return 1;
-- 
2.34.1



From vincent.guittot at linaro.org  Tue Feb 20 06:59:45 2024
From: vincent.guittot at linaro.org (Vincent Guittot)
Date: Tue, 20 Feb 2024 15:59:45 +0100
Subject: [PATCH v5 3/5] thermal/cpufreq: Remove arch_update_thermal_pressure()
In-Reply-To: <20240220145947.1107937-1-vincent.guittot@linaro.org>
References: <20240220145947.1107937-1-vincent.guittot@linaro.org>
Message-ID: <20240220145947.1107937-4-vincent.guittot@linaro.org>

arch_update_thermal_pressure() aims to update fast changing signal which
should be averaged using PELT filtering before being provided to the
scheduler which can't make smart use of fast changing signal.
cpufreq now provides the maximum freq_qos pressure on the capacity to the
scheduler, which includes cpufreq cooling device. Remove the call to
arch_update_thermal_pressure() in cpufreq cooling device as this is
handled by cpufreq_get_pressure().

Signed-off-by: Vincent Guittot <vincent.guittot at linaro.org>
Reviewed-by: Lukasz Luba <lukasz.luba at arm.com>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/thermal/cpufreq_cooling.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
index e2cc7bd30862..e77d3b44903e 100644
--- a/drivers/thermal/cpufreq_cooling.c
+++ b/drivers/thermal/cpufreq_cooling.c
@@ -448,7 +448,6 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
 				 unsigned long state)
 {
 	struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
-	struct cpumask *cpus;
 	unsigned int frequency;
 	int ret;
 
@@ -465,8 +464,6 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
 	ret = freq_qos_update_request(&cpufreq_cdev->qos_req, frequency);
 	if (ret >= 0) {
 		cpufreq_cdev->cpufreq_state = state;
-		cpus = cpufreq_cdev->policy->related_cpus;
-		arch_update_thermal_pressure(cpus, frequency);
 		ret = 0;
 	}
 
-- 
2.34.1



From vincent.guittot at linaro.org  Tue Feb 20 06:59:46 2024
From: vincent.guittot at linaro.org (Vincent Guittot)
Date: Tue, 20 Feb 2024 15:59:46 +0100
Subject: [PATCH v5 4/5] sched: Rename arch_update_thermal_pressure into arch_update_hw_pressure
In-Reply-To: <20240220145947.1107937-1-vincent.guittot@linaro.org>
References: <20240220145947.1107937-1-vincent.guittot@linaro.org>
Message-ID: <20240220145947.1107937-5-vincent.guittot@linaro.org>

Now that cpufreq provides a pressure value to the scheduler, rename
arch_update_thermal_pressure into HW pressure to reflect that it returns
a pressure applied by HW (i.e. with a high frequency change) and not
always related to thermal mitigation but also generated by max current
limitation as an example. Such high frequency signal needs filtering to be
smoothed and provide an value that reflects the average available capacity
into the scheduler time scale.

Signed-off-by: Vincent Guittot <vincent.guittot at linaro.org>
Reviewed-by: Qais Yousef <qyousef at layalina.io>
---
 arch/arm/include/asm/topology.h               |  6 ++---
 arch/arm64/include/asm/topology.h             |  6 ++---
 drivers/base/arch_topology.c                  | 26 +++++++++----------
 drivers/cpufreq/qcom-cpufreq-hw.c             |  4 +--
 include/linux/arch_topology.h                 |  8 +++---
 include/linux/sched/topology.h                |  8 +++---
 .../{thermal_pressure.h => hw_pressure.h}     | 14 +++++-----
 include/trace/events/sched.h                  |  2 +-
 init/Kconfig                                  | 12 ++++-----
 kernel/sched/core.c                           |  8 +++---
 kernel/sched/fair.c                           | 16 ++++++------
 kernel/sched/pelt.c                           | 18 ++++++-------
 kernel/sched/pelt.h                           | 16 ++++++------
 kernel/sched/sched.h                          | 10 +++----
 14 files changed, 77 insertions(+), 77 deletions(-)
 rename include/trace/events/{thermal_pressure.h => hw_pressure.h} (55%)

diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h
index 853c4f81ba4a..ad36b6570067 100644
--- a/arch/arm/include/asm/topology.h
+++ b/arch/arm/include/asm/topology.h
@@ -22,9 +22,9 @@
 /* Enable topology flag updates */
 #define arch_update_cpu_topology topology_update_cpu_topology
 
-/* Replace task scheduler's default thermal pressure API */
-#define arch_scale_thermal_pressure topology_get_thermal_pressure
-#define arch_update_thermal_pressure	topology_update_thermal_pressure
+/* Replace task scheduler's default HW pressure API */
+#define arch_scale_hw_pressure topology_get_hw_pressure
+#define arch_update_hw_pressure	topology_update_hw_pressure
 
 #else
 
diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h
index a323b109b9c4..0f6ef432fb84 100644
--- a/arch/arm64/include/asm/topology.h
+++ b/arch/arm64/include/asm/topology.h
@@ -35,9 +35,9 @@ void update_freq_counters_refs(void);
 /* Enable topology flag updates */
 #define arch_update_cpu_topology topology_update_cpu_topology
 
-/* Replace task scheduler's default thermal pressure API */
-#define arch_scale_thermal_pressure topology_get_thermal_pressure
-#define arch_update_thermal_pressure	topology_update_thermal_pressure
+/* Replace task scheduler's default HW pressure API */
+#define arch_scale_hw_pressure topology_get_hw_pressure
+#define arch_update_hw_pressure	topology_update_hw_pressure
 
 #include <asm-generic/topology.h>
 
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index 018ac202de34..69a3a3624e78 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -22,7 +22,7 @@
 #include <linux/units.h>
 
 #define CREATE_TRACE_POINTS
-#include <trace/events/thermal_pressure.h>
+#include <trace/events/hw_pressure.h>
 
 static DEFINE_PER_CPU(struct scale_freq_data __rcu *, sft_data);
 static struct cpumask scale_freq_counters_mask;
@@ -160,26 +160,26 @@ void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity)
 	per_cpu(cpu_scale, cpu) = capacity;
 }
 
-DEFINE_PER_CPU(unsigned long, thermal_pressure);
+DEFINE_PER_CPU(unsigned long, hw_pressure);
 
 /**
- * topology_update_thermal_pressure() - Update thermal pressure for CPUs
+ * topology_update_hw_pressure() - Update HW pressure for CPUs
  * @cpus        : The related CPUs for which capacity has been reduced
  * @capped_freq : The maximum allowed frequency that CPUs can run at
  *
- * Update the value of thermal pressure for all @cpus in the mask. The
+ * Update the value of HW pressure for all @cpus in the mask. The
  * cpumask should include all (online+offline) affected CPUs, to avoid
  * operating on stale data when hot-plug is used for some CPUs. The
  * @capped_freq reflects the currently allowed max CPUs frequency due to
- * thermal capping. It might be also a boost frequency value, which is bigger
+ * HW capping. It might be also a boost frequency value, which is bigger
  * than the internal 'capacity_freq_ref' max frequency. In such case the
  * pressure value should simply be removed, since this is an indication that
- * there is no thermal throttling. The @capped_freq must be provided in kHz.
+ * there is no HW throttling. The @capped_freq must be provided in kHz.
  */
-void topology_update_thermal_pressure(const struct cpumask *cpus,
+void topology_update_hw_pressure(const struct cpumask *cpus,
 				      unsigned long capped_freq)
 {
-	unsigned long max_capacity, capacity, th_pressure;
+	unsigned long max_capacity, capacity, hw_pressure;
 	u32 max_freq;
 	int cpu;
 
@@ -189,21 +189,21 @@ void topology_update_thermal_pressure(const struct cpumask *cpus,
 
 	/*
 	 * Handle properly the boost frequencies, which should simply clean
-	 * the thermal pressure value.
+	 * the HW pressure value.
 	 */
 	if (max_freq <= capped_freq)
 		capacity = max_capacity;
 	else
 		capacity = mult_frac(max_capacity, capped_freq, max_freq);
 
-	th_pressure = max_capacity - capacity;
+	hw_pressure = max_capacity - capacity;
 
-	trace_thermal_pressure_update(cpu, th_pressure);
+	trace_hw_pressure_update(cpu, hw_pressure);
 
 	for_each_cpu(cpu, cpus)
-		WRITE_ONCE(per_cpu(thermal_pressure, cpu), th_pressure);
+		WRITE_ONCE(per_cpu(hw_pressure, cpu), hw_pressure);
 }
-EXPORT_SYMBOL_GPL(topology_update_thermal_pressure);
+EXPORT_SYMBOL_GPL(topology_update_hw_pressure);
 
 static ssize_t cpu_capacity_show(struct device *dev,
 				 struct device_attribute *attr,
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 70b0f21968a0..ec8df5496a0c 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -347,8 +347,8 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)
 
 	throttled_freq = freq_hz / HZ_PER_KHZ;
 
-	/* Update thermal pressure (the boost frequencies are accepted) */
-	arch_update_thermal_pressure(policy->related_cpus, throttled_freq);
+	/* Update HW pressure (the boost frequencies are accepted) */
+	arch_update_hw_pressure(policy->related_cpus, throttled_freq);
 
 	/*
 	 * In the unlikely case policy is unregistered do not enable
diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h
index a63d61ca55af..b721f360d759 100644
--- a/include/linux/arch_topology.h
+++ b/include/linux/arch_topology.h
@@ -60,14 +60,14 @@ void topology_scale_freq_tick(void);
 void topology_set_scale_freq_source(struct scale_freq_data *data, const struct cpumask *cpus);
 void topology_clear_scale_freq_source(enum scale_freq_source source, const struct cpumask *cpus);
 
-DECLARE_PER_CPU(unsigned long, thermal_pressure);
+DECLARE_PER_CPU(unsigned long, hw_pressure);
 
-static inline unsigned long topology_get_thermal_pressure(int cpu)
+static inline unsigned long topology_get_hw_pressure(int cpu)
 {
-	return per_cpu(thermal_pressure, cpu);
+	return per_cpu(hw_pressure, cpu);
 }
 
-void topology_update_thermal_pressure(const struct cpumask *cpus,
+void topology_update_hw_pressure(const struct cpumask *cpus,
 				      unsigned long capped_freq);
 
 struct cpu_topology {
diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
index a6e04b4a21d7..e3b2cf7de018 100644
--- a/include/linux/sched/topology.h
+++ b/include/linux/sched/topology.h
@@ -264,17 +264,17 @@ unsigned long arch_scale_cpu_capacity(int cpu)
 }
 #endif
 
-#ifndef arch_scale_thermal_pressure
+#ifndef arch_scale_hw_pressure
 static __always_inline
-unsigned long arch_scale_thermal_pressure(int cpu)
+unsigned long arch_scale_hw_pressure(int cpu)
 {
 	return 0;
 }
 #endif
 
-#ifndef arch_update_thermal_pressure
+#ifndef arch_update_hw_pressure
 static __always_inline
-void arch_update_thermal_pressure(const struct cpumask *cpus,
+void arch_update_hw_pressure(const struct cpumask *cpus,
 				  unsigned long capped_frequency)
 { }
 #endif
diff --git a/include/trace/events/thermal_pressure.h b/include/trace/events/hw_pressure.h
similarity index 55%
rename from include/trace/events/thermal_pressure.h
rename to include/trace/events/hw_pressure.h
index b68680201360..b9cd68854128 100644
--- a/include/trace/events/thermal_pressure.h
+++ b/include/trace/events/hw_pressure.h
@@ -1,27 +1,27 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #undef TRACE_SYSTEM
-#define TRACE_SYSTEM thermal_pressure
+#define TRACE_SYSTEM hw_pressure
 
 #if !defined(_TRACE_THERMAL_PRESSURE_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_THERMAL_PRESSURE_H
 
 #include <linux/tracepoint.h>
 
-TRACE_EVENT(thermal_pressure_update,
-	TP_PROTO(int cpu, unsigned long thermal_pressure),
-	TP_ARGS(cpu, thermal_pressure),
+TRACE_EVENT(hw_pressure_update,
+	TP_PROTO(int cpu, unsigned long hw_pressure),
+	TP_ARGS(cpu, hw_pressure),
 
 	TP_STRUCT__entry(
-		__field(unsigned long, thermal_pressure)
+		__field(unsigned long, hw_pressure)
 		__field(int, cpu)
 	),
 
 	TP_fast_assign(
-		__entry->thermal_pressure = thermal_pressure;
+		__entry->hw_pressure = hw_pressure;
 		__entry->cpu = cpu;
 	),
 
-	TP_printk("cpu=%d thermal_pressure=%lu", __entry->cpu, __entry->thermal_pressure)
+	TP_printk("cpu=%d hw_pressure=%lu", __entry->cpu, __entry->hw_pressure)
 );
 #endif /* _TRACE_THERMAL_PRESSURE_H */
 
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index dbb01b4b7451..d115d64c4011 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -752,7 +752,7 @@ DECLARE_TRACE(pelt_dl_tp,
 	TP_PROTO(struct rq *rq),
 	TP_ARGS(rq));
 
-DECLARE_TRACE(pelt_thermal_tp,
+DECLARE_TRACE(pelt_hw_tp,
 	TP_PROTO(struct rq *rq),
 	TP_ARGS(rq));
 
diff --git a/init/Kconfig b/init/Kconfig
index deda3d14135b..436762bfae75 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -538,24 +538,24 @@ config HAVE_SCHED_AVG_IRQ
 	depends on IRQ_TIME_ACCOUNTING || PARAVIRT_TIME_ACCOUNTING
 	depends on SMP
 
-config SCHED_THERMAL_PRESSURE
+config SCHED_HW_PRESSURE
 	bool
 	default y if ARM && ARM_CPU_TOPOLOGY
 	default y if ARM64
 	depends on SMP
 	depends on CPU_FREQ_THERMAL
 	help
-	  Select this option to enable thermal pressure accounting in the
-	  scheduler. Thermal pressure is the value conveyed to the scheduler
+	  Select this option to enable HW pressure accounting in the
+	  scheduler. HW pressure is the value conveyed to the scheduler
 	  that reflects the reduction in CPU compute capacity resulted from
-	  thermal throttling. Thermal throttling occurs when the performance of
-	  a CPU is capped due to high operating temperatures.
+	  HW throttling. HW throttling occurs when the performance of
+	  a CPU is capped due to high operating temperatures as an example.
 
 	  If selected, the scheduler will be able to balance tasks accordingly,
 	  i.e. put less load on throttled CPUs than on non/less throttled ones.
 
 	  This requires the architecture to implement
-	  arch_update_thermal_pressure() and arch_scale_thermal_pressure().
+	  arch_update_hw_pressure() and arch_scale_thermal_pressure().
 
 config BSD_PROCESS_ACCT
 	bool "BSD Process Accounting"
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index a76c7095f736..8bfe5ce4ccd3 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -108,7 +108,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_rt_tp);
 EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_dl_tp);
 EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_irq_tp);
 EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_se_tp);
-EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_thermal_tp);
+EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_hw_tp);
 EXPORT_TRACEPOINT_SYMBOL_GPL(sched_cpu_capacity_tp);
 EXPORT_TRACEPOINT_SYMBOL_GPL(sched_overutilized_tp);
 EXPORT_TRACEPOINT_SYMBOL_GPL(sched_util_est_cfs_tp);
@@ -5657,7 +5657,7 @@ void scheduler_tick(void)
 	struct rq *rq = cpu_rq(cpu);
 	struct task_struct *curr = rq->curr;
 	struct rq_flags rf;
-	unsigned long thermal_pressure;
+	unsigned long hw_pressure;
 	u64 resched_latency;
 
 	if (housekeeping_cpu(cpu, HK_TYPE_TICK))
@@ -5668,8 +5668,8 @@ void scheduler_tick(void)
 	rq_lock(rq, &rf);
 
 	update_rq_clock(rq);
-	thermal_pressure = arch_scale_thermal_pressure(cpu_of(rq));
-	update_thermal_load_avg(rq_clock_thermal(rq), rq, thermal_pressure);
+	hw_pressure = arch_scale_hw_pressure(cpu_of(rq));
+	update_hw_load_avg(rq_clock_hw(rq), rq, hw_pressure);
 	curr->sched_class->task_tick(rq, curr, 0);
 	if (sched_feat(LATENCY_WARN))
 		resched_latency = cpu_resched_latency(rq);
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 9c650b860946..8961d307f232 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -78,7 +78,7 @@ static unsigned int normalized_sysctl_sched_base_slice	= 750000ULL;
 
 const_debug unsigned int sysctl_sched_migration_cost	= 500000UL;
 
-int sched_thermal_decay_shift;
+int sched_hw_decay_shift;
 static int __init setup_sched_thermal_decay_shift(char *str)
 {
 	int _shift = 0;
@@ -86,7 +86,7 @@ static int __init setup_sched_thermal_decay_shift(char *str)
 	if (kstrtoint(str, 0, &_shift))
 		pr_warn("Unable to set scheduler thermal pressure decay shift parameter\n");
 
-	sched_thermal_decay_shift = clamp(_shift, 0, 10);
+	sched_hw_decay_shift = clamp(_shift, 0, 10);
 	return 1;
 }
 __setup("sched_thermal_decay_shift=", setup_sched_thermal_decay_shift);
@@ -4963,7 +4963,7 @@ static inline unsigned long get_actual_cpu_capacity(int cpu)
 {
 	unsigned long capacity = arch_scale_cpu_capacity(cpu);
 
-	capacity -= max(thermal_load_avg(cpu_rq(cpu)), cpufreq_get_pressure(cpu));
+	capacity -= max(hw_load_avg(cpu_rq(cpu)), cpufreq_get_pressure(cpu));
 
 	return capacity;
 }
@@ -4996,7 +4996,7 @@ static inline int util_fits_cpu(unsigned long util,
 	 * Similarly if a task is capped to arch_scale_cpu_capacity(little_cpu), it
 	 * should fit a little cpu even if there's some pressure.
 	 *
-	 * Only exception is for thermal pressure since it has a direct impact
+	 * Only exception is for HW or cpufreq pressure since it has a direct impact
 	 * on available OPP of the system.
 	 *
 	 * We honour it for uclamp_min only as a drop in performance level
@@ -9251,7 +9251,7 @@ static inline bool others_have_blocked(struct rq *rq)
 	if (READ_ONCE(rq->avg_dl.util_avg))
 		return true;
 
-	if (thermal_load_avg(rq))
+	if (hw_load_avg(rq))
 		return true;
 
 #ifdef CONFIG_HAVE_SCHED_AVG_IRQ
@@ -9283,7 +9283,7 @@ static bool __update_blocked_others(struct rq *rq, bool *done)
 {
 	const struct sched_class *curr_class;
 	u64 now = rq_clock_pelt(rq);
-	unsigned long thermal_pressure;
+	unsigned long hw_pressure;
 	bool decayed;
 
 	/*
@@ -9292,11 +9292,11 @@ static bool __update_blocked_others(struct rq *rq, bool *done)
 	 */
 	curr_class = rq->curr->sched_class;
 
-	thermal_pressure = arch_scale_thermal_pressure(cpu_of(rq));
+	hw_pressure = arch_scale_hw_pressure(cpu_of(rq));
 
 	decayed = update_rt_rq_load_avg(now, rq, curr_class == &rt_sched_class) |
 		  update_dl_rq_load_avg(now, rq, curr_class == &dl_sched_class) |
-		  update_thermal_load_avg(rq_clock_thermal(rq), rq, thermal_pressure) |
+		  update_hw_load_avg(rq_clock_hw(rq), rq, hw_pressure) |
 		  update_irq_load_avg(rq, 0);
 
 	if (others_have_blocked(rq))
diff --git a/kernel/sched/pelt.c b/kernel/sched/pelt.c
index 63b6cf898220..f951c44f1d52 100644
--- a/kernel/sched/pelt.c
+++ b/kernel/sched/pelt.c
@@ -384,30 +384,30 @@ int update_dl_rq_load_avg(u64 now, struct rq *rq, int running)
 	return 0;
 }
 
-#ifdef CONFIG_SCHED_THERMAL_PRESSURE
+#ifdef CONFIG_SCHED_HW_PRESSURE
 /*
- * thermal:
+ * hardware:
  *
  *   load_sum = \Sum se->avg.load_sum but se->avg.load_sum is not tracked
  *
  *   util_avg and runnable_load_avg are not supported and meaningless.
  *
  * Unlike rt/dl utilization tracking that track time spent by a cpu
- * running a rt/dl task through util_avg, the average thermal pressure is
- * tracked through load_avg. This is because thermal pressure signal is
+ * running a rt/dl task through util_avg, the average HW pressure is
+ * tracked through load_avg. This is because HW pressure signal is
  * time weighted "delta" capacity unlike util_avg which is binary.
  * "delta capacity" =  actual capacity  -
- *			capped capacity a cpu due to a thermal event.
+ *			capped capacity a cpu due to a HW event.
  */
 
-int update_thermal_load_avg(u64 now, struct rq *rq, u64 capacity)
+int update_hw_load_avg(u64 now, struct rq *rq, u64 capacity)
 {
-	if (___update_load_sum(now, &rq->avg_thermal,
+	if (___update_load_sum(now, &rq->avg_hw,
 			       capacity,
 			       capacity,
 			       capacity)) {
-		___update_load_avg(&rq->avg_thermal, 1);
-		trace_pelt_thermal_tp(rq);
+		___update_load_avg(&rq->avg_hw, 1);
+		trace_pelt_hw_tp(rq);
 		return 1;
 	}
 
diff --git a/kernel/sched/pelt.h b/kernel/sched/pelt.h
index 9e1083465fbc..2150062949d4 100644
--- a/kernel/sched/pelt.h
+++ b/kernel/sched/pelt.h
@@ -7,21 +7,21 @@ int __update_load_avg_cfs_rq(u64 now, struct cfs_rq *cfs_rq);
 int update_rt_rq_load_avg(u64 now, struct rq *rq, int running);
 int update_dl_rq_load_avg(u64 now, struct rq *rq, int running);
 
-#ifdef CONFIG_SCHED_THERMAL_PRESSURE
-int update_thermal_load_avg(u64 now, struct rq *rq, u64 capacity);
+#ifdef CONFIG_SCHED_HW_PRESSURE
+int update_hw_load_avg(u64 now, struct rq *rq, u64 capacity);
 
-static inline u64 thermal_load_avg(struct rq *rq)
+static inline u64 hw_load_avg(struct rq *rq)
 {
-	return READ_ONCE(rq->avg_thermal.load_avg);
+	return READ_ONCE(rq->avg_hw.load_avg);
 }
 #else
 static inline int
-update_thermal_load_avg(u64 now, struct rq *rq, u64 capacity)
+update_hw_load_avg(u64 now, struct rq *rq, u64 capacity)
 {
 	return 0;
 }
 
-static inline u64 thermal_load_avg(struct rq *rq)
+static inline u64 hw_load_avg(struct rq *rq)
 {
 	return 0;
 }
@@ -202,12 +202,12 @@ update_dl_rq_load_avg(u64 now, struct rq *rq, int running)
 }
 
 static inline int
-update_thermal_load_avg(u64 now, struct rq *rq, u64 capacity)
+update_hw_load_avg(u64 now, struct rq *rq, u64 capacity)
 {
 	return 0;
 }
 
-static inline u64 thermal_load_avg(struct rq *rq)
+static inline u64 hw_load_avg(struct rq *rq)
 {
 	return 0;
 }
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 001fe047bd5d..1f8799788cea 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1089,8 +1089,8 @@ struct rq {
 #ifdef CONFIG_HAVE_SCHED_AVG_IRQ
 	struct sched_avg	avg_irq;
 #endif
-#ifdef CONFIG_SCHED_THERMAL_PRESSURE
-	struct sched_avg	avg_thermal;
+#ifdef CONFIG_SCHED_HW_PRESSURE
+	struct sched_avg	avg_hw;
 #endif
 	u64			idle_stamp;
 	u64			avg_idle;
@@ -1542,11 +1542,11 @@ static inline u64 rq_clock_task(struct rq *rq)
  *	3			256
  *	4			512
  */
-extern int sched_thermal_decay_shift;
+extern int sched_hw_decay_shift;
 
-static inline u64 rq_clock_thermal(struct rq *rq)
+static inline u64 rq_clock_hw(struct rq *rq)
 {
-	return rq_clock_task(rq) >> sched_thermal_decay_shift;
+	return rq_clock_task(rq) >> sched_hw_decay_shift;
 }
 
 static inline void rq_clock_skip_update(struct rq *rq)
-- 
2.34.1



From vincent.guittot at linaro.org  Tue Feb 20 06:59:47 2024
From: vincent.guittot at linaro.org (Vincent Guittot)
Date: Tue, 20 Feb 2024 15:59:47 +0100
Subject: [PATCH v5 5/5] sched/pelt: Remove shift of thermal clock
In-Reply-To: <20240220145947.1107937-1-vincent.guittot@linaro.org>
References: <20240220145947.1107937-1-vincent.guittot@linaro.org>
Message-ID: <20240220145947.1107937-6-vincent.guittot@linaro.org>

The optional shift of the clock used by thermal/hw load avg has been
introduced to handle case where the signal was not always a high frequency
hw signal. Now that cpufreq provides a signal for firmware and
SW pressure, we can remove this exception and always keep this PELT signal
aligned with other signals.
Mark sysctl_sched_migration_cost boot parameter as deprecated

Signed-off-by: Vincent Guittot <vincent.guittot at linaro.org>
Reviewed-by: Qais Yousef <qyousef at layalina.io>
---
 .../admin-guide/kernel-parameters.txt          |  1 +
 kernel/sched/core.c                            |  2 +-
 kernel/sched/fair.c                            | 10 ++--------
 kernel/sched/sched.h                           | 18 ------------------
 4 files changed, 4 insertions(+), 27 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 31b3a25680d0..4dc54bd1bbf2 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -5749,6 +5749,7 @@
 			but is useful for debugging and performance tuning.
 
 	sched_thermal_decay_shift=
+			[Deprecated]
 			[KNL, SMP] Set a decay shift for scheduler thermal
 			pressure signal. Thermal pressure signal follows the
 			default decay period of other scheduler pelt
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 8bfe5ce4ccd3..b740dcdc86a0 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5669,7 +5669,7 @@ void scheduler_tick(void)
 
 	update_rq_clock(rq);
 	hw_pressure = arch_scale_hw_pressure(cpu_of(rq));
-	update_hw_load_avg(rq_clock_hw(rq), rq, hw_pressure);
+	update_hw_load_avg(rq_clock_task(rq), rq, hw_pressure);
 	curr->sched_class->task_tick(rq, curr, 0);
 	if (sched_feat(LATENCY_WARN))
 		resched_latency = cpu_resched_latency(rq);
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 8961d307f232..f7c2bf0eba65 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -78,15 +78,9 @@ static unsigned int normalized_sysctl_sched_base_slice	= 750000ULL;
 
 const_debug unsigned int sysctl_sched_migration_cost	= 500000UL;
 
-int sched_hw_decay_shift;
 static int __init setup_sched_thermal_decay_shift(char *str)
 {
-	int _shift = 0;
-
-	if (kstrtoint(str, 0, &_shift))
-		pr_warn("Unable to set scheduler thermal pressure decay shift parameter\n");
-
-	sched_hw_decay_shift = clamp(_shift, 0, 10);
+	pr_warn("Ignoring the deprecated sched_thermal_decay_shift= option\n");
 	return 1;
 }
 __setup("sched_thermal_decay_shift=", setup_sched_thermal_decay_shift);
@@ -9296,7 +9290,7 @@ static bool __update_blocked_others(struct rq *rq, bool *done)
 
 	decayed = update_rt_rq_load_avg(now, rq, curr_class == &rt_sched_class) |
 		  update_dl_rq_load_avg(now, rq, curr_class == &dl_sched_class) |
-		  update_hw_load_avg(rq_clock_hw(rq), rq, hw_pressure) |
+		  update_hw_load_avg(now, rq, hw_pressure) |
 		  update_irq_load_avg(rq, 0);
 
 	if (others_have_blocked(rq))
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 1f8799788cea..638c61efe19d 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1531,24 +1531,6 @@ static inline u64 rq_clock_task(struct rq *rq)
 	return rq->clock_task;
 }
 
-/**
- * By default the decay is the default pelt decay period.
- * The decay shift can change the decay period in
- * multiples of 32.
- *  Decay shift		Decay period(ms)
- *	0			32
- *	1			64
- *	2			128
- *	3			256
- *	4			512
- */
-extern int sched_hw_decay_shift;
-
-static inline u64 rq_clock_hw(struct rq *rq)
-{
-	return rq_clock_task(rq) >> sched_hw_decay_shift;
-}
-
 static inline void rq_clock_skip_update(struct rq *rq)
 {
 	lockdep_assert_rq_held(rq);
-- 
2.34.1



From horms at kernel.org  Tue Feb 20 07:00:50 2024
From: horms at kernel.org (Simon Horman)
Date: Tue, 20 Feb 2024 15:00:50 +0000
Subject: [PATCH net] net: phy: realtek: Fix rtl8211f_config_init() for
 RTL8211F(D)(I)-VD-CG PHY
In-Reply-To: <20240220070007.968762-1-s-vadapalli@ti.com>
References: <20240220070007.968762-1-s-vadapalli@ti.com>
Message-ID: <20240220150050.GO40273@kernel.org>

On Tue, Feb 20, 2024 at 12:30:07PM +0530, Siddharth Vadapalli wrote:
> Commit bb726b753f75 ("net: phy: realtek: add support for
> RTL8211F(D)(I)-VD-CG") extended support of the driver from the existing
> support for RTL8211F(D)(I)-CG PHY to the newer RTL8211F(D)(I)-VD-CG PHY.
> 
> While that commit indicated that the RTL8211F_PHYCR2 register is not
> supported by the "VD-CG" PHY model and therefore updated the corresponding
> section in rtl8211f_config_init() to be invoked conditionally, the call to
> "genphy_soft_reset()" was left as-is, when it should have also been invoked
> conditionally. This is because the call to "genphy_soft_reset()" was first
> introduced by the commit 0a4355c2b7f8 ("net: phy: realtek: add dt property
> to disable CLKOUT clock") since the RTL8211F guide indicates that a PHY
> reset should be issued after setting bits in the PHYCR2 register.
> 
> As the PHYCR2 register is not applicable to the "VD-CG" PHY model, fix the
> rtl8211f_config_init() function by invoking "genphy_soft_reset()"
> conditionally based on the presence of the "PHYCR2" register.
> 
> Fixes: bb726b753f75 ("net: phy: realtek: add support for RTL8211F(D)(I)-VD-CG")
> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>

Reviewed-by: Simon Horman <horms at kernel.org>



From broonie at kernel.org  Tue Feb 20 07:08:26 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 15:08:26 +0000
Subject: [PATCH V2] arm64/sysreg: Add register fields for ID_AA64DFR1_EL1
In-Reply-To: <20240220023203.3091229-1-anshuman.khandual@arm.com>
References: <20240220023203.3091229-1-anshuman.khandual@arm.com>
Message-ID: <c31cf2b5-ff37-4c52-a00e-d59549cd2f3b@sirena.org.uk>

On Tue, Feb 20, 2024 at 08:02:03AM +0530, Anshuman Khandual wrote:
> This adds register fields for ID_AA64DFR1_EL1 as per the definitions based
> on DDI0601 2023-12.

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/20240220/0870b892/attachment-0001.sig>

From broonie at kernel.org  Tue Feb 20 07:09:47 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 15:09:47 +0000
Subject: [PATCH V2] arm64/sysreg: Update ID_DFR0_EL1 register fields
In-Reply-To: <20240220025343.3093955-1-anshuman.khandual@arm.com>
References: <20240220025343.3093955-1-anshuman.khandual@arm.com>
Message-ID: <013824e8-4c6a-49c2-9390-14fb8090676d@sirena.org.uk>

On Tue, Feb 20, 2024 at 08:23:43AM +0530, Anshuman Khandual wrote:
> This updates ID_DFR0_EL1.PerfMon and ID_DFR0_EL1.CopDbg register fields as
> per the definitions based on DDI0601 2023-12.

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/20240220/a0e57e46/attachment.sig>

From sebastianene at google.com  Tue Feb 20 07:10:30 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Tue, 20 Feb 2024 15:10:30 +0000
Subject: [PATCH v6 1/6] KVM: arm64: Move pagetable definitions to common header
In-Reply-To: <20240220151035.327199-1-sebastianene@google.com>
References: <20240220151035.327199-1-sebastianene@google.com>
Message-ID: <20240220151035.327199-2-sebastianene@google.com>

In preparation for using the stage-2 definitions in ptdump, move some of
these macros in the common header.

Signed-off-by: Sebastian Ene <sebastianene at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 42 ++++++++++++++++++++++++++++
 arch/arm64/kvm/hyp/pgtable.c         | 42 ----------------------------
 2 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index cfdf40f734b1..dd759e93084a 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -59,6 +59,48 @@ typedef u64 kvm_pte_t;
 
 #define KVM_PHYS_INVALID		(-1ULL)
 
+#define KVM_PTE_LEAF_ATTR_LO		GENMASK(11, 2)
+
+#define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX	GENMASK(4, 2)
+#define KVM_PTE_LEAF_ATTR_LO_S1_AP	GENMASK(7, 6)
+#define KVM_PTE_LEAF_ATTR_LO_S1_AP_RO		\
+	({ cpus_have_final_cap(ARM64_KVM_HVHE) ? 2 : 3; })
+#define KVM_PTE_LEAF_ATTR_LO_S1_AP_RW		\
+	({ cpus_have_final_cap(ARM64_KVM_HVHE) ? 0 : 1; })
+#define KVM_PTE_LEAF_ATTR_LO_S1_SH	GENMASK(9, 8)
+#define KVM_PTE_LEAF_ATTR_LO_S1_SH_IS	3
+#define KVM_PTE_LEAF_ATTR_LO_S1_AF	BIT(10)
+
+#define KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR	GENMASK(5, 2)
+#define KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R	BIT(6)
+#define KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W	BIT(7)
+#define KVM_PTE_LEAF_ATTR_LO_S2_SH	GENMASK(9, 8)
+#define KVM_PTE_LEAF_ATTR_LO_S2_SH_IS	3
+#define KVM_PTE_LEAF_ATTR_LO_S2_AF	BIT(10)
+
+#define KVM_PTE_LEAF_ATTR_HI		GENMASK(63, 50)
+
+#define KVM_PTE_LEAF_ATTR_HI_SW		GENMASK(58, 55)
+
+#define KVM_PTE_LEAF_ATTR_HI_S1_XN	BIT(54)
+
+#define KVM_PTE_LEAF_ATTR_HI_S2_XN	BIT(54)
+
+#define KVM_PTE_LEAF_ATTR_HI_S1_GP	BIT(50)
+
+#define KVM_PTE_LEAF_ATTR_S2_PERMS	(KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | \
+					 KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
+					 KVM_PTE_LEAF_ATTR_HI_S2_XN)
+
+#define KVM_INVALID_PTE_OWNER_MASK	GENMASK(9, 2)
+#define KVM_MAX_OWNER_ID		1
+
+/*
+ * Used to indicate a pte for which a 'break-before-make' sequence is in
+ * progress.
+ */
+#define KVM_INVALID_PTE_LOCKED		BIT(10)
+
 static inline bool kvm_pte_valid(kvm_pte_t pte)
 {
 	return pte & KVM_PTE_VALID;
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index ab9d05fcf98b..eb83c8464b36 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -17,48 +17,6 @@
 #define KVM_PTE_TYPE_PAGE		1
 #define KVM_PTE_TYPE_TABLE		1
 
-#define KVM_PTE_LEAF_ATTR_LO		GENMASK(11, 2)
-
-#define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX	GENMASK(4, 2)
-#define KVM_PTE_LEAF_ATTR_LO_S1_AP	GENMASK(7, 6)
-#define KVM_PTE_LEAF_ATTR_LO_S1_AP_RO		\
-	({ cpus_have_final_cap(ARM64_KVM_HVHE) ? 2 : 3; })
-#define KVM_PTE_LEAF_ATTR_LO_S1_AP_RW		\
-	({ cpus_have_final_cap(ARM64_KVM_HVHE) ? 0 : 1; })
-#define KVM_PTE_LEAF_ATTR_LO_S1_SH	GENMASK(9, 8)
-#define KVM_PTE_LEAF_ATTR_LO_S1_SH_IS	3
-#define KVM_PTE_LEAF_ATTR_LO_S1_AF	BIT(10)
-
-#define KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR	GENMASK(5, 2)
-#define KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R	BIT(6)
-#define KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W	BIT(7)
-#define KVM_PTE_LEAF_ATTR_LO_S2_SH	GENMASK(9, 8)
-#define KVM_PTE_LEAF_ATTR_LO_S2_SH_IS	3
-#define KVM_PTE_LEAF_ATTR_LO_S2_AF	BIT(10)
-
-#define KVM_PTE_LEAF_ATTR_HI		GENMASK(63, 50)
-
-#define KVM_PTE_LEAF_ATTR_HI_SW		GENMASK(58, 55)
-
-#define KVM_PTE_LEAF_ATTR_HI_S1_XN	BIT(54)
-
-#define KVM_PTE_LEAF_ATTR_HI_S2_XN	BIT(54)
-
-#define KVM_PTE_LEAF_ATTR_HI_S1_GP	BIT(50)
-
-#define KVM_PTE_LEAF_ATTR_S2_PERMS	(KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | \
-					 KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
-					 KVM_PTE_LEAF_ATTR_HI_S2_XN)
-
-#define KVM_INVALID_PTE_OWNER_MASK	GENMASK(9, 2)
-#define KVM_MAX_OWNER_ID		1
-
-/*
- * Used to indicate a pte for which a 'break-before-make' sequence is in
- * progress.
- */
-#define KVM_INVALID_PTE_LOCKED		BIT(10)
-
 struct kvm_pgtable_walk_data {
 	struct kvm_pgtable_walker	*walker;
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From sebastianene at google.com  Tue Feb 20 07:10:29 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Tue, 20 Feb 2024 15:10:29 +0000
Subject: [PATCH v6 0/6] arm64: ptdump: View the second stage page-tables
Message-ID: <20240220151035.327199-1-sebastianene@google.com>

Hi,

This is the first part of the series which enables dumping of the guest
stage-2 pagetables. The support for dumping the host stage-2 pagetables
which is pKVM specific will be part of a follow-up series as per the
feedback received in v4. 

When CONFIG_PTDUMP_STAGE2_DEBUGFS is enabled, ptdump registers 
'/sys/debug/kvm/<guest_id>/stage2_page_tables' entry with debugfs
upon guest creation. This allows userspace tools (eg. cat) to dump the
stage-2 pagetables by reading the registered file.

Reading the debugfs file shows stage-2 memory ranges in following format:
<IPA range> <size> <descriptor type> <access permissions> <mem_attributes>

Below is the output of a guest stage-2 pagetable mappings running under
Qemu:

---[ IPA bits 33 start lvl 2 ]---
0x0000000000000000-0x0000000080000000           2G PGD
0x0000000080000000-0x0000000080c00000          12M PGD      R W AF        BLK
0x0000000080c00000-0x0000000080e00000           2M PGD   XN R W AF        BLK
0x0000000080e00000-0x0000000081000000           2M PGD      R W AF        BLK
0x0000000081000000-0x0000000081400000           4M PGD   XN R W AF        BLK
0x0000000081400000-0x000000008fe00000         234M PGD
0x000000008fe00000-0x0000000090000000           2M PGD   XN R W AF        BLK
0x0000000090000000-0x00000000fa000000        1696M PGD
0x00000000fa000000-0x00000000fe000000          64M PGD   XN R W AF        BLK
0x00000000fe000000-0x0000000100000000          32M PGD
0x0000000100000000-0x0000000101c00000          28M PGD   XN R W AF        BLK
0x0000000101c00000-0x0000000102000000           4M PGD
0x0000000102000000-0x0000000102200000           2M PGD   XN R W AF        BLK
0x0000000102200000-0x000000017b000000        1934M PGD
0x000000017b000000-0x0000000180000000          80M PGD   XN R W AF        BLK

Link to v5:
https://lore.kernel.org/all/20240207144832.1017815-2-sebastianene at google.com/

Link to v4:
https://lore.kernel.org/all/20231218135859.2513568-2-sebastianene at google.com/

Link to v3:
https://lore.kernel.org/all/20231115171639.2852644-2-sebastianene at google.com/

Changelog:
 v5 -> current:
 * don't return an error if the kvm_arch_create_vm_debugfs fails to
   initialize (ref.
https://lore.kernel.org/all/20240216155941.2029458-1-oliver.upton at linux.dev/)  
 * fix use-after-free suggested by getting a reference to the
   KVM struct while manipulating the debugfs files
   and put the reference on the file close.
 * do all the allocations at once for the ptdump parser state tracking
   and simplify the initialization.
 * move the ptdump parser state initialization as part of the file_open
 * create separate files for printing the guest stage-2 pagetable
   configuration such as: the start level of the pagetable walk and the
   number of bits used for the IPA space representation.
 * fixed the wrong header format for the newly added file
 * include missing patch which hasn't been posted on the v5:
   "KVM-arm64-Move-pagetable-definitions-to-common-heade.patch" 


 v4 -> v5:
 * refactorization: split the series into two parts as per the feedback
   received from Oliver. Introduce the base support which allows dumping
   of the guest stage-2 pagetables.
 
 * removed the *ops* struct wrapper built on top of the file_ops and
   simplify the ptdump interface access.
 
 * keep the page table walker away from the ptdump specific code

  v3 -> current_version:
  * refactorization: moved all the **KVM** specific components under
    kvm/ as suggested by Oliver. Introduced a new file
    arm64/kvm/ptdump.c which handled the second stage translation.
    re-used only the display portion from mm/ptdump.c

  * pagetable snapshot creation now uses memory donated from the host.
    The memory is no longer shared with the host as this can pose a security
    risk if the host has access to manipulate the pagetable copy while
    the hypervisor iterates it.

  * fixed a memory leak: while memory was used from the memcache for
    building the snapshot pagetable, it was no longer giving back the
    pages to the host for freeing. A separate array was introduced to
    keep track of the pages allocated from the memcache.


  v2 -> v3:
  * register the stage-2 debugfs entry for the host under
    /sys/debug/kvm/host_stage2_page_tables and in
    /sys/debug/kvm/<guest_id>/stage2_page_tables for guests.

  * don't use a static array for parsing the attributes description,
    generate it dynamically based on the number of pagetable levels

  * remove the lock that was guarding the seq_file private inode data,
    and keep the data private to the open file session.

  * minor fixes & renaming of CONFIG_NVHE_EL2_PTDUMP_DEBUGFS to
    CONFIG_PTDUMP_STAGE2_DEBUGFS


  v1 -> v2:
  * use the stage-2 pagetable walker for dumping descriptors instead of
    the one provided by ptdump.

  * support for guests pagetables dumping under VHE/nVHE non-protected

Thanks,

Sebastian Ene (6):
  KVM: arm64: Move pagetable definitions to common header
  arm64: ptdump: Expose the attribute parsing functionality
  arm64: ptdump: Use the mask from the state structure
  KVM: arm64: Register ptdump with debugfs on guest creation
  KVM: arm64: Initialize the ptdump parser with stage-2 attributes
  KVM: arm64: Expose guest stage-2 pagetable config to debugfs

 arch/arm64/include/asm/kvm_pgtable.h |  42 +++++
 arch/arm64/include/asm/ptdump.h      |  42 ++++-
 arch/arm64/kvm/Kconfig               |  13 ++
 arch/arm64/kvm/Makefile              |   1 +
 arch/arm64/kvm/debug.c               |   8 +
 arch/arm64/kvm/hyp/pgtable.c         |  42 -----
 arch/arm64/kvm/kvm_ptdump.h          |  20 ++
 arch/arm64/kvm/ptdump.c              | 270 +++++++++++++++++++++++++++
 arch/arm64/mm/ptdump.c               |  49 +----
 9 files changed, 405 insertions(+), 82 deletions(-)
 create mode 100644 arch/arm64/kvm/kvm_ptdump.h
 create mode 100644 arch/arm64/kvm/ptdump.c

-- 
2.44.0.rc0.258.g7320e95886-goog



From sebastianene at google.com  Tue Feb 20 07:10:31 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Tue, 20 Feb 2024 15:10:31 +0000
Subject: [PATCH v6 2/6] arm64: ptdump: Expose the attribute parsing functionality
In-Reply-To: <20240220151035.327199-1-sebastianene@google.com>
References: <20240220151035.327199-1-sebastianene@google.com>
Message-ID: <20240220151035.327199-3-sebastianene@google.com>

To keep the same output format as the arch specific ptdump and for the
sake of reusability, move the parser's state tracking code out
of the arch specific.

Signed-off-by: Sebastian Ene <sebastianene at google.com>
---
 arch/arm64/include/asm/ptdump.h | 41 ++++++++++++++++++++++++++++++++-
 arch/arm64/mm/ptdump.c          | 36 ++---------------------------
 2 files changed, 42 insertions(+), 35 deletions(-)

diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
index 581caac525b0..23510be35084 100644
--- a/arch/arm64/include/asm/ptdump.h
+++ b/arch/arm64/include/asm/ptdump.h
@@ -9,6 +9,8 @@
 
 #include <linux/mm_types.h>
 #include <linux/seq_file.h>
+#include <linux/ptdump.h>
+
 
 struct addr_marker {
 	unsigned long start_address;
@@ -21,15 +23,52 @@ struct ptdump_info {
 	unsigned long			base_addr;
 };
 
+struct prot_bits {
+	u64		mask;
+	u64		val;
+	const char	*set;
+	const char	*clear;
+};
+
+struct pg_level {
+	const struct prot_bits	*bits;
+	const char		*name;
+	size_t			num;
+	u64			mask;
+};
+
+/*
+ * The page dumper groups page table entries of the same type into a single
+ * description. It uses pg_state to track the range information while
+ * iterating over the pte entries. When the continuity is broken it then
+ * dumps out a description of the range.
+ */
+struct pg_state {
+	struct ptdump_state		ptdump;
+	struct seq_file			*seq;
+	const struct addr_marker	*marker;
+	unsigned long			start_address;
+	int				level;
+	u64				current_prot;
+	bool				check_wx;
+	unsigned long			wx_pages;
+	unsigned long			uxn_pages;
+};
+
 void ptdump_walk(struct seq_file *s, struct ptdump_info *info);
+void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
+	       u64 val);
 #ifdef CONFIG_PTDUMP_DEBUGFS
 #define EFI_RUNTIME_MAP_END	DEFAULT_MAP_WINDOW_64
 void __init ptdump_debugfs_register(struct ptdump_info *info, const char *name);
 #else
 static inline void ptdump_debugfs_register(struct ptdump_info *info,
 					   const char *name) { }
-#endif
+#endif /* CONFIG_PTDUMP_DEBUGFS */
 void ptdump_check_wx(void);
+#else
+static inline void note_page(void *pt_st, unsigned long addr,
+			     int level, u64 val) { }
 #endif /* CONFIG_PTDUMP_CORE */
 
 #ifdef CONFIG_DEBUG_WX
diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
index e305b6593c4e..64127c70b109 100644
--- a/arch/arm64/mm/ptdump.c
+++ b/arch/arm64/mm/ptdump.c
@@ -66,31 +66,6 @@ static struct addr_marker address_markers[] = {
 		seq_printf(m, fmt);	\
 })
 
-/*
- * The page dumper groups page table entries of the same type into a single
- * description. It uses pg_state to track the range information while
- * iterating over the pte entries. When the continuity is broken it then
- * dumps out a description of the range.
- */
-struct pg_state {
-	struct ptdump_state ptdump;
-	struct seq_file *seq;
-	const struct addr_marker *marker;
-	unsigned long start_address;
-	int level;
-	u64 current_prot;
-	bool check_wx;
-	unsigned long wx_pages;
-	unsigned long uxn_pages;
-};
-
-struct prot_bits {
-	u64		mask;
-	u64		val;
-	const char	*set;
-	const char	*clear;
-};
-
 static const struct prot_bits pte_bits[] = {
 	{
 		.mask	= PTE_VALID,
@@ -170,13 +145,6 @@ static const struct prot_bits pte_bits[] = {
 	}
 };
 
-struct pg_level {
-	const struct prot_bits *bits;
-	const char *name;
-	size_t num;
-	u64 mask;
-};
-
 static struct pg_level pg_level[] = {
 	{ /* pgd */
 		.name	= "PGD",
@@ -248,8 +216,8 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
 	st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
 }
 
-static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
-		      u64 val)
+void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
+	       u64 val)
 {
 	struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
 	static const char units[] = "KMGTPE";
-- 
2.44.0.rc0.258.g7320e95886-goog



From sebastianene at google.com  Tue Feb 20 07:10:32 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Tue, 20 Feb 2024 15:10:32 +0000
Subject: [PATCH v6 3/6] arm64: ptdump: Use the mask from the state structure
In-Reply-To: <20240220151035.327199-1-sebastianene@google.com>
References: <20240220151035.327199-1-sebastianene@google.com>
Message-ID: <20240220151035.327199-4-sebastianene@google.com>

Printing the descriptor attributes requires accessing a mask which has a
different set of attributes for stage-2. In preparation for adding support
for the stage-2 pagetables dumping, use the mask from the local context
and not from the globally defined pg_level array. Store a pointer to
the pg_level array in the ptdump state structure. This will allow us to
extract the mask which is wrapped in the pg_level array and use it for
descriptor parsing in the note_page.

Signed-off-by: Sebastian Ene <sebastianene at google.com>
---
 arch/arm64/include/asm/ptdump.h |  1 +
 arch/arm64/mm/ptdump.c          | 13 ++++++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
index 23510be35084..4e728d2a1f2c 100644
--- a/arch/arm64/include/asm/ptdump.h
+++ b/arch/arm64/include/asm/ptdump.h
@@ -45,6 +45,7 @@ struct pg_level {
  */
 struct pg_state {
 	struct ptdump_state		ptdump;
+	struct pg_level			*pg_level;
 	struct seq_file			*seq;
 	const struct addr_marker	*marker;
 	unsigned long			start_address;
diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
index 64127c70b109..015ed65d3e9b 100644
--- a/arch/arm64/mm/ptdump.c
+++ b/arch/arm64/mm/ptdump.c
@@ -220,11 +220,12 @@ void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
 	       u64 val)
 {
 	struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
+	struct pg_level *pg_info = st->pg_level;
 	static const char units[] = "KMGTPE";
 	u64 prot = 0;
 
 	if (level >= 0)
-		prot = val & pg_level[level].mask;
+		prot = val & pg_info[level].mask;
 
 	if (st->level == -1) {
 		st->level = level;
@@ -250,10 +251,10 @@ void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
 			unit++;
 		}
 		pt_dump_seq_printf(st->seq, "%9lu%c %s", delta, *unit,
-				   pg_level[st->level].name);
-		if (st->current_prot && pg_level[st->level].bits)
-			dump_prot(st, pg_level[st->level].bits,
-				  pg_level[st->level].num);
+				   pg_info[st->level].name);
+		if (st->current_prot && pg_info[st->level].bits)
+			dump_prot(st, pg_info[st->level].bits,
+				  pg_info[st->level].num);
 		pt_dump_seq_puts(st->seq, "\n");
 
 		if (addr >= st->marker[1].start_address) {
@@ -284,6 +285,7 @@ void ptdump_walk(struct seq_file *s, struct ptdump_info *info)
 	st = (struct pg_state){
 		.seq = s,
 		.marker = info->markers,
+		.pg_level = &pg_level[0],
 		.level = -1,
 		.ptdump = {
 			.note_page = note_page,
@@ -321,6 +323,7 @@ void ptdump_check_wx(void)
 			{ 0, NULL},
 			{ -1, NULL},
 		},
+		.pg_level = &pg_level[0],
 		.level = -1,
 		.check_wx = true,
 		.ptdump = {
-- 
2.44.0.rc0.258.g7320e95886-goog



From sebastianene at google.com  Tue Feb 20 07:10:33 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Tue, 20 Feb 2024 15:10:33 +0000
Subject: [PATCH v6 4/6] KVM: arm64: Register ptdump with debugfs on guest creation
In-Reply-To: <20240220151035.327199-1-sebastianene@google.com>
References: <20240220151035.327199-1-sebastianene@google.com>
Message-ID: <20240220151035.327199-5-sebastianene@google.com>

While arch/*/mem/ptdump handles the kernel pagetable dumping code,
introduce KVM/ptdump which shows the guest stage-2 pagetables. The
separation is necessary because most of the definitions from the
stage-2 pagetable reside in the KVM path and we will be invoking
functionality **specific** to KVM.

When a guest is created, register a new file entry under the guest
debugfs dir which allows userspace to show the contents of the guest
stage-2 pagetables when accessed.

Signed-off-by: Sebastian Ene <sebastianene at google.com>
---
 arch/arm64/kvm/Kconfig      | 13 ++++++
 arch/arm64/kvm/Makefile     |  1 +
 arch/arm64/kvm/debug.c      |  8 ++++
 arch/arm64/kvm/kvm_ptdump.h | 20 +++++++++
 arch/arm64/kvm/ptdump.c     | 88 +++++++++++++++++++++++++++++++++++++
 5 files changed, 130 insertions(+)
 create mode 100644 arch/arm64/kvm/kvm_ptdump.h
 create mode 100644 arch/arm64/kvm/ptdump.c

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 27ca89b628a0..83ca07d16cf4 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -67,4 +67,17 @@ config PROTECTED_NVHE_STACKTRACE
 
 	  If unsure, or not using protected nVHE (pKVM), say N.
 
+config PTDUMP_STAGE2_DEBUGFS
+       bool "Present the stage-2 pagetables to debugfs"
+       depends on PTDUMP_DEBUGFS && KVM
+       default n
+       help
+         Say Y here if you want to show the stage-2 kernel pagetables
+         layout in a debugfs file. This information is only useful for kernel developers
+         who are working in architecture specific areas of the kernel.
+         It is probably not a good idea to enable this feature in a production
+         kernel.
+
+         If in doubt, say N.
+
 endif # VIRTUALIZATION
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index c0c050e53157..190eac17538c 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -23,6 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 vgic/vgic-its.o vgic/vgic-debug.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
+kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
 
 always-y := hyp_constants.h hyp-constants.s
 
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 8725291cb00a..ff97af2c0513 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -14,6 +14,8 @@
 #include <asm/kvm_arm.h>
 #include <asm/kvm_emulate.h>
 
+#include <kvm_ptdump.h>
+
 #include "trace.h"
 
 /* These are the bits of MDSCR_EL1 we may manipulate */
@@ -342,3 +344,9 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
 }
+
+int kvm_arch_create_vm_debugfs(struct kvm *kvm)
+{
+	kvm_ptdump_guest_register(kvm);
+	return 0;
+}
diff --git a/arch/arm64/kvm/kvm_ptdump.h b/arch/arm64/kvm/kvm_ptdump.h
new file mode 100644
index 000000000000..5e8a655605f1
--- /dev/null
+++ b/arch/arm64/kvm/kvm_ptdump.h
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) Google, 2023
+ * Author: Sebastian Ene <sebastianene at google.com>
+ */
+
+#ifndef __KVM_PTDUMP_H
+#define __KVM_PTDUMP_H
+
+#include <linux/kvm_host.h>
+#include <asm/ptdump.h>
+
+
+#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
+void kvm_ptdump_guest_register(struct kvm *kvm);
+#else
+static inline void kvm_ptdump_guest_register(struct kvm *kvm) {}
+#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
+
+#endif /* __KVM_PTDUMP_H */
diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
new file mode 100644
index 000000000000..9b04c24bb9be
--- /dev/null
+++ b/arch/arm64/kvm/ptdump.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Debug helper used to dump the stage-2 pagetables of the system and their
+ * associated permissions.
+ *
+ * Copyright (C) Google, 2023
+ * Author: Sebastian Ene <sebastianene at google.com>
+ */
+#include <linux/debugfs.h>
+#include <linux/kvm_host.h>
+#include <linux/seq_file.h>
+
+#include <asm/kvm_pgtable.h>
+#include <kvm_ptdump.h>
+
+
+static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
+			      enum kvm_pgtable_walk_flags visit)
+{
+	struct pg_state *st = ctx->arg;
+	struct ptdump_state *pt_st = &st->ptdump;
+
+	note_page(pt_st, ctx->addr, ctx->level, ctx->old);
+	return 0;
+}
+
+static int kvm_ptdump_show_common(struct seq_file *m,
+				  struct kvm_pgtable *pgtable,
+				  struct pg_state *parser_state)
+{
+	struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker) {
+		.cb     = kvm_ptdump_visitor,
+		.arg	= parser_state,
+		.flags	= KVM_PGTABLE_WALK_LEAF,
+	};
+
+	return kvm_pgtable_walk(pgtable, 0, BIT(pgtable->ia_bits), &walker);
+}
+
+static int kvm_ptdump_guest_show(struct seq_file *m, void *)
+{
+	struct kvm *kvm = m->private;
+	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
+	struct pg_state parser_state = {0};
+	int ret;
+
+	write_lock(&kvm->mmu_lock);
+	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
+	write_unlock(&kvm->mmu_lock);
+
+	return ret;
+}
+
+static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
+{
+	struct kvm *kvm = m->i_private;
+	int ret;
+
+	if (!kvm_get_kvm_safe(kvm))
+		return -ENOENT;
+
+	ret = single_open(file, kvm_ptdump_guest_show, m->i_private);
+	if (ret < 0)
+		kvm_put_kvm(kvm);
+
+	return ret;
+}
+
+static int kvm_ptdump_guest_close(struct inode *m, struct file *file)
+{
+	struct kvm *kvm = m->i_private;
+
+	kvm_put_kvm(kvm);
+	return single_release(m, file);
+}
+
+static const struct file_operations kvm_ptdump_guest_fops = {
+	.open		= kvm_ptdump_guest_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= kvm_ptdump_guest_close,
+};
+
+void kvm_ptdump_guest_register(struct kvm *kvm)
+{
+	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
+			    kvm, &kvm_ptdump_guest_fops);
+}
-- 
2.44.0.rc0.258.g7320e95886-goog



From sebastianene at google.com  Tue Feb 20 07:10:34 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Tue, 20 Feb 2024 15:10:34 +0000
Subject: [PATCH v6 5/6] KVM: arm64: Initialize the ptdump parser with stage-2 attributes
In-Reply-To: <20240220151035.327199-1-sebastianene@google.com>
References: <20240220151035.327199-1-sebastianene@google.com>
Message-ID: <20240220151035.327199-6-sebastianene@google.com>

Define a set of attributes used by the ptdump parser to display the
properties of a guest memory region covered by a pagetable descriptor.
Build a description of the pagetable levels and initialize the parser
with this configuration.

Signed-off-by: Sebastian Ene <sebastianene at google.com>
---
 arch/arm64/kvm/ptdump.c | 146 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 139 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
index 9b04c24bb9be..2c4e0c122d23 100644
--- a/arch/arm64/kvm/ptdump.c
+++ b/arch/arm64/kvm/ptdump.c
@@ -14,6 +14,61 @@
 #include <kvm_ptdump.h>
 
 
+#define MARKERS_LEN		(2)
+#define KVM_PGTABLE_LEVELS	(KVM_PGTABLE_LAST_LEVEL + 1)
+
+struct kvm_ptdump_guest_state {
+	struct kvm		*kvm;
+	struct pg_state		parser_state;
+	struct addr_marker	ipa_marker[MARKERS_LEN];
+	struct pg_level		level[KVM_PGTABLE_LEVELS];
+	struct ptdump_range	range[MARKERS_LEN];
+};
+
+static const struct prot_bits stage2_pte_bits[] = {
+	{
+		.mask	= PTE_VALID,
+		.val	= PTE_VALID,
+		.set	= " ",
+		.clear	= "F",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
+		.set	= "XN",
+		.clear	= "  ",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
+		.set	= "R",
+		.clear	= " ",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
+		.set	= "W",
+		.clear	= " ",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
+		.set	= "AF",
+		.clear	= "  ",
+	}, {
+		.mask	= PTE_NG,
+		.val	= PTE_NG,
+		.set	= "FnXS",
+		.clear	= "  ",
+	}, {
+		.mask	= PTE_CONT | PTE_VALID,
+		.val	= PTE_CONT | PTE_VALID,
+		.set	= "CON",
+		.clear	= "   ",
+	}, {
+		.mask	= PTE_TABLE_BIT,
+		.val	= PTE_TABLE_BIT,
+		.set	= "   ",
+		.clear	= "BLK",
+	},
+};
+
 static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
 			      enum kvm_pgtable_walk_flags visit)
 {
@@ -37,15 +92,78 @@ static int kvm_ptdump_show_common(struct seq_file *m,
 	return kvm_pgtable_walk(pgtable, 0, BIT(pgtable->ia_bits), &walker);
 }
 
+static int kvm_ptdump_build_levels(struct pg_level *level, u32 start_lvl)
+{
+	static const char * const level_names[] = {"PGD", "PUD", "PMD", "PTE"};
+	u32 i = 0;
+	u64 mask = 0;
+
+	if (start_lvl > 2) {
+		pr_err("invalid start_lvl %u\n", start_lvl);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(stage2_pte_bits); i++)
+		mask |= stage2_pte_bits[i].mask;
+
+	for (i = start_lvl; i <= KVM_PGTABLE_LAST_LEVEL; i++) {
+		level[i].name	= level_names[i];
+		level[i].num	= ARRAY_SIZE(stage2_pte_bits);
+		level[i].bits	= stage2_pte_bits;
+		level[i].mask	= mask;
+	}
+
+	if (start_lvl > 0)
+		level[start_lvl].name = level_names[0];
+
+	return 0;
+}
+
+static struct kvm_ptdump_guest_state
+*kvm_ptdump_parser_init(struct kvm *kvm)
+{
+	struct kvm_ptdump_guest_state *st;
+	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
+	struct kvm_pgtable *pgtable = mmu->pgt;
+	int ret;
+
+	st = kzalloc(sizeof(struct kvm_ptdump_guest_state), GFP_KERNEL_ACCOUNT);
+	if (!st)
+		return NULL;
+
+	ret = kvm_ptdump_build_levels(&st->level[0], pgtable->start_level);
+	if (ret)
+		goto free_with_state;
+
+	st->ipa_marker[0].name		= "Guest IPA";
+	st->ipa_marker[1].start_address = BIT(pgtable->ia_bits);
+	st->range[0].end		= BIT(pgtable->ia_bits);
+
+	st->kvm				= kvm;
+	st->parser_state = (struct pg_state) {
+		.marker		= &st->ipa_marker[0],
+		.level		= -1,
+		.pg_level	= &st->level[0],
+		.ptdump.range	= &st->range[0],
+	};
+
+	return st;
+free_with_state:
+	kfree(st);
+	return NULL;
+}
+
 static int kvm_ptdump_guest_show(struct seq_file *m, void *)
 {
-	struct kvm *kvm = m->private;
+	struct kvm_ptdump_guest_state *st = m->private;
+	struct kvm *kvm = st->kvm;
 	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
-	struct pg_state parser_state = {0};
 	int ret;
 
+	st->parser_state.seq = m;
+
 	write_lock(&kvm->mmu_lock);
-	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
+	ret = kvm_ptdump_show_common(m, mmu->pgt, &st->parser_state);
 	write_unlock(&kvm->mmu_lock);
 
 	return ret;
@@ -54,22 +172,36 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *)
 static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
 {
 	struct kvm *kvm = m->i_private;
+	struct kvm_ptdump_guest_state *st;
 	int ret;
 
-	if (!kvm_get_kvm_safe(kvm))
-		return -ENOENT;
+	st = kvm_ptdump_parser_init(kvm);
+	if (!st)
+		return -ENOMEM;
 
-	ret = single_open(file, kvm_ptdump_guest_show, m->i_private);
+	if (!kvm_get_kvm_safe(kvm)) {
+		ret = -ENOENT;
+		goto free_with_state;
+	}
+
+	ret = single_open(file, kvm_ptdump_guest_show, st);
 	if (ret < 0)
-		kvm_put_kvm(kvm);
+		goto free_with_kvm_ref;
 
 	return ret;
+free_with_kvm_ref:
+	kvm_put_kvm(kvm);
+free_with_state:
+	kfree(st);
+	return ret;
 }
 
 static int kvm_ptdump_guest_close(struct inode *m, struct file *file)
 {
 	struct kvm *kvm = m->i_private;
+	void *st = ((struct seq_file *)file->private_data)->private;
 
+	kfree(st);
 	kvm_put_kvm(kvm);
 	return single_release(m, file);
 }
-- 
2.44.0.rc0.258.g7320e95886-goog



From sebastianene at google.com  Tue Feb 20 07:10:35 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Tue, 20 Feb 2024 15:10:35 +0000
Subject: [PATCH v6 6/6] KVM: arm64: Expose guest stage-2 pagetable config to debugfs
In-Reply-To: <20240220151035.327199-1-sebastianene@google.com>
References: <20240220151035.327199-1-sebastianene@google.com>
Message-ID: <20240220151035.327199-7-sebastianene@google.com>

Make the start level and the IPA bits properties available in the
virtual machine debugfs directory. Make sure that the KVM structure
doesn't disappear behind our back and keep a reference to the KVM struct
while these files are opened.

Signed-off-by: Sebastian Ene <sebastianene at google.com>
---
 arch/arm64/kvm/ptdump.c | 50 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
index 2c4e0c122d23..a68a22592e97 100644
--- a/arch/arm64/kvm/ptdump.c
+++ b/arch/arm64/kvm/ptdump.c
@@ -213,8 +213,58 @@ static const struct file_operations kvm_ptdump_guest_fops = {
 	.release	= kvm_ptdump_guest_close,
 };
 
+static int kvm_pgtable_debugfs_show(struct seq_file *m, void *)
+{
+	const struct file *file = m->file;
+	struct kvm_pgtable *pgtable = m->private;
+
+	if (!strcmp(file_dentry(file)->d_iname, "ipa_range"))
+		seq_printf(m, "%2u\n", pgtable->ia_bits);
+	else if (!strcmp(file_dentry(file)->d_iname, "stage2_levels"))
+		seq_printf(m, "%1d\n", pgtable->start_level);
+	return 0;
+}
+
+static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file)
+{
+	struct kvm *kvm = m->i_private;
+	struct kvm_s2_mmu *mmu;
+	struct kvm_pgtable *pgtable;
+	int ret;
+
+	if (!kvm_get_kvm_safe(kvm))
+		return -ENOENT;
+
+	mmu = &kvm->arch.mmu;
+	pgtable = mmu->pgt;
+
+	ret = single_open(file, kvm_pgtable_debugfs_show, pgtable);
+	if (ret < 0)
+		kvm_put_kvm(kvm);
+	return ret;
+}
+
+static int kvm_pgtable_debugfs_close(struct inode *m, struct file *file)
+{
+	struct kvm *kvm = m->i_private;
+
+	kvm_put_kvm(kvm);
+	return single_release(m, file);
+}
+
+static const struct file_operations kvm_pgtable_debugfs_fops = {
+	.open		= kvm_pgtable_debugfs_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= kvm_pgtable_debugfs_close,
+};
+
 void kvm_ptdump_guest_register(struct kvm *kvm)
 {
 	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
 			    kvm, &kvm_ptdump_guest_fops);
+	debugfs_create_file("ipa_range", 0400, kvm->debugfs_dentry, kvm,
+			    &kvm_pgtable_debugfs_fops);
+	debugfs_create_file("stage2_levels", 0400, kvm->debugfs_dentry,
+			    kvm, &kvm_pgtable_debugfs_fops);
 }
-- 
2.44.0.rc0.258.g7320e95886-goog



From broonie at kernel.org  Tue Feb 20 07:13:07 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 15:13:07 +0000
Subject: [PATCH V2] arm64/sysreg: Update ID_AA64DFR0_EL1 register
In-Reply-To: <20240220034829.3098373-1-anshuman.khandual@arm.com>
References: <20240220034829.3098373-1-anshuman.khandual@arm.com>
Message-ID: <bea8006b-4f4e-44e8-af68-3a52f8bace73@sirena.org.uk>

On Tue, Feb 20, 2024 at 09:18:29AM +0530, Anshuman Khandual wrote:
> This updates ID_AA64DFR0_EL1.PMSVer and ID_AA64DFR0_EL1.DebugVer register
> fields as per the definitions based on DDI0601 2023-12.

Reviewed-by: Mark Brown <broonie at kernel.org>

> @@ -1223,6 +1223,7 @@ UnsignedEnum	35:32	PMSVer
>  	0b0010	V1P1
>  	0b0011	V1P2
>  	0b0100	V1P3
> +	0b0101	V1P4
>  EndEnum

There's also a FEAT_SPE_SME documented in the text but not in the table
of enumerated values (I've reported this) - it makes sense to me to skip
this until the XML is internally consistent.

>  Field	31:28	CTX_CMPs
>  Res0	27:24
> @@ -1249,6 +1250,7 @@ UnsignedEnum	3:0	DebugVer
>  	0b1000	V8P2
>  	0b1001	V8P4
>  	0b1010	V8P8
> +	0b1011	V8P9
>  EndEnum

There's an IMPDEF value defined for this like the 32 bit equivalent but
that was a preexisting issue.
-------------- 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/20240220/790a0051/attachment.sig>

From linux at armlinux.org.uk  Tue Feb 20 07:13:58 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 20 Feb 2024 15:13:58 +0000
Subject: [PATCH RFC v4 02/15] ACPI: processor: Register all CPUs from
 acpi_processor_get_info()
In-Reply-To: <ZdSMk93c1I6x973h@shell.armlinux.org.uk>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk>
 <E1rVDmU-0027YP-Jz@rmk-PC.armlinux.org.uk>
 <CAJZ5v0iiJpUWq5GMSnKFWQTzn_bdwoQz9m=hDaXNg4Lj_ePF4g@mail.gmail.com>
 <ZdSMk93c1I6x973h@shell.armlinux.org.uk>
Message-ID: <ZdTBtt0oR6Q1RcAB@shell.armlinux.org.uk>

On Tue, Feb 20, 2024 at 11:27:15AM +0000, Russell King (Oracle) wrote:
> On Thu, Feb 15, 2024 at 08:22:29PM +0100, Rafael J. Wysocki wrote:
> > On Wed, Jan 31, 2024 at 5:50?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:
> > > diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> > > index cf7c1cca69dd..a68c475cdea5 100644
> > > --- a/drivers/acpi/acpi_processor.c
> > > +++ b/drivers/acpi/acpi_processor.c
> > > @@ -314,6 +314,18 @@ static int acpi_processor_get_info(struct acpi_device *device)
> > >                         cpufreq_add_device("acpi-cpufreq");
> > >         }
> > >
> > > +       /*
> > > +        * Register CPUs that are present. get_cpu_device() is used to skip
> > > +        * duplicate CPU descriptions from firmware.
> > > +        */
> > > +       if (!invalid_logical_cpuid(pr->id) && cpu_present(pr->id) &&
> > > +           !get_cpu_device(pr->id)) {
> > > +               int ret = arch_register_cpu(pr->id);
> > > +
> > > +               if (ret)
> > > +                       return ret;
> > > +       }
> > > +
> > >         /*
> > >          *  Extra Processor objects may be enumerated on MP systems with
> > >          *  less than the max # of CPUs. They should be ignored _iff
> > 
> > This is interesting, because right below there is the following code:
> > 
> >     if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
> >         int ret = acpi_processor_hotadd_init(pr);
> > 
> >         if (ret)
> >             return ret;
> >     }
> > 
> > and acpi_processor_hotadd_init() essentially calls arch_register_cpu()
> > with some extra things around it (more about that below).
> > 
> > I do realize that acpi_processor_hotadd_init() is defined under
> > CONFIG_ACPI_HOTPLUG_CPU, so for the sake of the argument let's
> > consider an architecture where CONFIG_ACPI_HOTPLUG_CPU is set.
> > 
> > So why are the two conditionals that almost contradict each other both
> > needed?  It looks like the new code could be combined with
> > acpi_processor_hotadd_init() to do the right thing in all cases.
> > 
> > Now, acpi_processor_hotadd_init() does some extra things that look
> > like they should be done by the new code too.
> > 
> > 1. It checks invalid_phys_cpuid() which appears to be a good idea to me.
> > 
> > 2. It uses locking around arch_register_cpu() which doesn't seem
> > unreasonable either.
> > 
> > 3. It calls acpi_map_cpu() and I'm not sure why this is not done by
> > the new code.
> > 
> > The only thing that can be dropped from it is the _STA check AFAICS,
> > because acpi_processor_add() won't even be called if the CPU is not
> > present (and not enabled after the first patch).
> > 
> > So why does the code not do 1 - 3 above?
> 
> Honestly, I'm out of my depth with this and can't answer your
> questions - and I really don't want to try fiddling with this code
> because it's just too icky (even in its current form in mainline)
> to be understandable to anyone who hasn't gained a detailed knowledge
> of this code.
> 
> It's going to require a lot of analysis - how acpi_map_cpuid() behaves
> in all circumstances, what this means for invalid_logical_cpuid() and
> invalid_phys_cpuid(), what paths will be taken in each case. This code
> is already just too hairy for someone who isn't an experienced ACPI
> hacker to be able to follow and I don't see an obvious way to make it
> more readable.
> 
> James' additions make it even more complex and less readable.

As an illustration of the problems I'm having here, I was just writing
a reply to this with a suggestion of transforming this code ultimately
to:

	if (!get_cpu_device(pr->id)) {
		int ret;

		if (!invalid_logical_cpuid(pr->id) && cpu_present(pr->id))
			ret = acpi_processor_make_enabled(pr);
		else
			ret = acpi_processor_make_present(pr);

		if (ret)
			return ret;
	}

(acpi_processor_make_present() would be acpi_processor_hotadd_init()
and acpi_processor_make_enabled() would be arch_register_cpu() at this
point.)

Then I realised that's a bad idea - because we really need to check
that pr->id is valid before calling get_cpu_device() on it, so this
won't work. That leaves us with:

	int ret;

	if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
		/* x86 et.al. path */
		ret = acpi_processor_make_present(pr);
	} else if (!get_cpu_device(pr->id)) {
		/* Arm64 path */
		ret = acpi_processor_make_enabled(pr);
	} else {
		ret = 0;
	}

	if (ret)
		return ret;

Now, the next transformation would be to move !get_cpu_device(pr->id)
into acpi_processor_make_enabled() which would eliminate one of those
if() legs.

Now, if we want to somehow make the call to arch_regster_cpu() common
in these two paths, the next question is what are the _precise_
semantics of acpi_map_cpu(), particularly with respect to it
modifying pr->id. Is it guaranteed to always give the same result
for the same processor described in ACPI? What acpi_map_cpu() anyway,
I can find no documentation for it.

Then there's the question whether calling acpi_unmap_cpu() should be
done on the failure path if arch_register_cpu() fails, which is done
for the x86 path but not the Arm64 path. Should it be done for the
Arm64 path? I've no idea, but as Arm64 doesn't implement either of
these two functions, I guess they could be stubbed out and thus be
no-ops - but then we open a hole where if pr->id is invalid, we
end up passing that invalid value to arch_register_cpu() which I'm
quite sure will explode with a negative CPU number.

So, to my mind, what you're effectively asking for is a total rewrite
of all the code in and called by acpi_processor_get_info()... and that
is not something I am willing to do (because it's too far outside of
my knowledge area.)

As I said in my reply to patch 1, I think your comments on patch 2
make Arm64 vcpu hotplug unachievable in a reasonable time frame, and
certainly outside the bounds of what I can do to progress this.

So, at this point I'm going to stand down from further participation
with this patch set as I believe I've reached the limit of what I can
do to progress it.

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


From joey.gouly at arm.com  Tue Feb 20 07:16:00 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 20 Feb 2024 15:16:00 +0000
Subject: [PATCH 04/13] KVM: arm64: nv: Configure HCR_EL2 for FEAT_NV2
In-Reply-To: <20240219092014.783809-5-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
 <20240219092014.783809-5-maz@kernel.org>
Message-ID: <20240220151600.GC8575@e124191.cambridge.arm.com>

Hi,

On Mon, Feb 19, 2024 at 09:20:05AM +0000, Marc Zyngier wrote:
> Add the HCR_EL2 configuration for FEAT_NV2, adding the required
> bits for running a guest hypervisor, and overall merging the
> allowed bits provided by the guest.
> 
> This heavily replies on unavaliable features being sanitised
> when the HCR_EL2 shadow register is accessed, and only a couple
> of bits must be explicitly disabled.
> 
> Non-NV guests are completely unaffected by any of this.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/include/asm/sysreg.h         |  1 +
>  arch/arm64/kvm/hyp/include/hyp/switch.h |  4 +--
>  arch/arm64/kvm/hyp/nvhe/switch.c        |  2 +-
>  arch/arm64/kvm/hyp/vhe/switch.c         | 34 ++++++++++++++++++++++++-
>  4 files changed, 36 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 9e8999592f3a..a5361d9032a4 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -498,6 +498,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_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
>  #define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)

I'm seeing double! (SYS_VNCR_EL2 is already defined a few lines down)

> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index e3fcf8c4d5b4..f5f701f309a9 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -271,10 +271,8 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
>  	__deactivate_traps_hfgxtr(vcpu);
>  }
>  
> -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 c50f8459e4fc..4103625e46c5 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -40,7 +40,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 58415783fd53..29f59c374f7a 100644
> --- a/arch/arm64/kvm/hyp/vhe/switch.c
> +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> @@ -33,11 +33,43 @@ DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data);
>  DEFINE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
>  DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
>  
> +/*
> + * HCR_EL2 bits that the NV guest can freely change (no RES0/RES1
> + * semantics, irrespective of the configuration), but that cannot be
> + * applied to the actual HW as things would otherwise break badly.
> + *
> + * - TGE: we want to use EL1, which is incompatible with it being set

Can you make this a bit clearer:

	we want the guest to use EL1

Assuming I've understood correctly. I first read it as 'we' == kvm.

> + *
> + * - API/APK: for hysterical raisins, we enable PAuth lazily, which
> + *   means that the guest's bits cannot be directly applied (we really
> + *   want to see the traps). Revisit this at some point.
> + */
> +#define NV_HCR_GUEST_EXCLUDE	(HCR_TGE | HCR_API | HCR_APK)
> +
> +static u64 __compute_hcr(struct kvm_vcpu *vcpu)
> +{
> +	u64 hcr = vcpu->arch.hcr_el2;
> +
> +	if (!vcpu_has_nv(vcpu))
> +		return hcr;
> +
> +	if (is_hyp_ctxt(vcpu)) {
> +		hcr |= HCR_NV | HCR_NV2 | HCR_AT | HCR_TTLB;
> +
> +		if (!vcpu_el2_e2h_is_set(vcpu))
> +			hcr |= HCR_NV1;
> +
> +		write_sysreg_s(vcpu->arch.ctxt.vncr_array, SYS_VNCR_EL2);
> +	}
> +
> +	return hcr | (__vcpu_sys_reg(vcpu, HCR_EL2) & ~NV_HCR_GUEST_EXCLUDE);
> +}
> +
>  static void __activate_traps(struct kvm_vcpu *vcpu)
>  {
>  	u64 val;
>  
> -	___activate_traps(vcpu);
> +	___activate_traps(vcpu, __compute_hcr(vcpu));
>  
>  	if (has_cntpoff()) {
>  		struct timer_map map;

Otherwise,

Reviewed-by: Joey Gouly <joey.gouly at arm.com>

Thanks,
Joey


From joey.gouly at arm.com  Tue Feb 20 07:18:51 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 20 Feb 2024 15:18:51 +0000
Subject: [PATCH 02/13] KVM: arm64: Clarify ESR_ELx_ERET_ISS_ERET*
In-Reply-To: <86zfvv2qys.wl-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
 <20240219092014.783809-3-maz@kernel.org>
 <20240220113127.GB16168@e124191.cambridge.arm.com>
 <861q9748ut.wl-maz@kernel.org>
 <20240220132350.GB8575@e124191.cambridge.arm.com>
 <86zfvv2qys.wl-maz@kernel.org>
Message-ID: <20240220151851.GA57578@e124191.cambridge.arm.com>

On Tue, Feb 20, 2024 at 01:41:15PM +0000, Marc Zyngier wrote:
> On Tue, 20 Feb 2024 13:23:50 +0000,
> Joey Gouly <joey.gouly at arm.com> wrote:
> > 
> > On Tue, Feb 20, 2024 at 12:29:30PM +0000, Marc Zyngier wrote:
> > > On Tue, 20 Feb 2024 11:31:27 +0000,
> > > Joey Gouly <joey.gouly at arm.com> wrote:
> > > > 
> > > > If this part is confusing due to the name, maybe introduce a function in esr.h
> > > > esr_is_pac_eret() (name pending bikeshedding)?
> > > 
> > > That's indeed a better option. Now for the bikeshed aspect:
> > > 
> > > - esr_iss_is_eretax(): check for ESR_ELx_ERET_ISS_ERET being set
> > > 
> > > - esr_iss_is_eretab(): check for ESR_ELx_ERET_ISS_ERETA being set
> > > 
> > > Thoughts?
> > > 
> > 
> > I was trying to avoid the ERETA* confusion by suggesting 'pac_eret', but if I
> > were to pick between your options I'd pick esr_iss_is_eretax().
> 
> It's not an either/or situation. We actually need both:
> 
> - esr_iss_is_eretax() being true tells you that you need to
>   authenticate the ERET
> 
> - esr_iss_is_eretab() tells you that you need to use the A or B key

Oh right, yes that makes sense (please add a brief comment like ^ above the
functions)

Thanks,
Joey


From andy.shevchenko at gmail.com  Tue Feb 20 07:19:14 2024
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Tue, 20 Feb 2024 17:19:14 +0200
Subject: [PATCH v5 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <20240220012540.10607-3-zhi.mao@mediatek.com>
References: <20240220012540.10607-1-zhi.mao@mediatek.com> <20240220012540.10607-3-zhi.mao@mediatek.com>
Message-ID: <CAHp75Vfbc0jE43Z-trFRnFdT5SxvJN+w2x7hS4vHuF5M2kTXgg@mail.gmail.com>

On Tue, Feb 20, 2024 at 3:47?AM Zhi Mao <zhi.mao at mediatek.com> wrote:
>
> Add a V4L2 sub-device driver for Galaxycore GC08A3 image sensor.

...

> +#include <asm/unaligned.h>

Usually asm/* go after linux/*

> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>

This looks semi-random.
For example, _at least_ the array_size.h, bits.h, container_of.h,
device.h, err.h, mod_devicetable.h, property.h, types.h are missing,
Please, use IWYU principle.

...

> +#define GC08A3_DEFAULT_CLK_FREQ 24000000

HZ_PER_MHZ ?

...

> +#define GC08A3_SLEEP_US  2000

USEC_PER_MSEC ?

...

> +static const s64 gc08a3_link_freq_menu_items[] = {
> +       336000000ULL,
> +       207000000ULL,

HZ_PER_MHZ ?

> +};

...

> +static const struct dev_pm_ops gc08a3_pm_ops = {
> +       SET_RUNTIME_PM_OPS(gc08a3_power_off, gc08a3_power_on, NULL)
> +};

> +               .pm = &gc08a3_pm_ops,

Use new PM macros (pm_ptr() and friends).

-- 
With Best Regards,
Andy Shevchenko


From gregkh at linuxfoundation.org  Tue Feb 20 07:31:47 2024
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Tue, 20 Feb 2024 16:31:47 +0100
Subject: Patch "Revert "arm64: Stash shadow stack pointer in the task struct on interrupt"" has been added to the 5.10-stable tree
In-Reply-To: <20240219132153.378265-1-xiangyang3@huawei.com>
Message-ID: <2024022047-democrat-persuader-ef91@gregkh>


This is a note to let you know that I've just added the patch titled

    Revert "arm64: Stash shadow stack pointer in the task struct on interrupt"

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:
     revert-arm64-stash-shadow-stack-pointer-in-the-task-struct-on-interrupt.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 xiangyang3 at huawei.com  Tue Feb 20 16:30:54 2024
From: Xiang Yang <xiangyang3 at huawei.com>
Date: Mon, 19 Feb 2024 21:21:53 +0800
Subject: Revert "arm64: Stash shadow stack pointer in the task struct on interrupt"
To: <ardb at kernel.org>, <mark.rutland at arm.com>, <catalin.marinas at arm.com>, <will at kernel.org>
Cc: <keescook at chromium.org>, <linux-arm-kernel at lists.infradead.org>, <stable at vger.kernel.org>, <gregkh at linuxfoundation.org>, <xiangyang3 at huawei.com>, <xiujianfeng at huawei.com>, <liaochang1 at huawei.com>
Message-ID: <20240219132153.378265-1-xiangyang3 at huawei.com>


This reverts commit 3f225f29c69c13ce1cbdb1d607a42efeef080056 which is
commit 59b37fe52f49955791a460752c37145f1afdcad1 upstream.

The shadow call stack for irq now is stored in current task's thread info
in irq_stack_entry. There is a possibility that we have some soft irqs
pending at the end of hard irq, and when we process softirq with the irq
enabled, irq_stack_entry will enter again and overwrite the shadow call
stack whitch stored in current task's thread info, leading to the
incorrect shadow call stack restoration for the first entry of the hard
IRQ, then the system end up with a panic.

task A                               |  task A
-------------------------------------+------------------------------------
el1_irq        //irq1 enter          |
  irq_handler  //save scs_sp1        |
    gic_handle_irq                   |
    irq_exit                         |
      __do_softirq                   |
                                     | el1_irq         //irq2 enter
                                     |   irq_handler   //save scs_sp2
                                     |                 //overwrite scs_sp1
                                     |   ...
                                     |   irq_stack_exit //restore scs_sp2
  irq_stack_exit //restore wrong     |
                 //scs_sp2           |

So revert this commit to fix it.

Fixes: 3f225f29c69c ("arm64: Stash shadow stack pointer in the task struct on interrupt")
Signed-off-by: Xiang Yang <xiangyang3 at huawei.com>
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 arch/arm64/kernel/entry.S |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -431,7 +431,9 @@ SYM_CODE_END(__swpan_exit_el0)
 
 	.macro	irq_stack_entry
 	mov	x19, sp			// preserve the original sp
-	scs_save tsk			// preserve the original shadow stack
+#ifdef CONFIG_SHADOW_CALL_STACK
+	mov	x24, scs_sp		// preserve the original shadow stack
+#endif
 
 	/*
 	 * Compare sp with the base of the task stack.
@@ -465,7 +467,9 @@ SYM_CODE_END(__swpan_exit_el0)
 	 */
 	.macro	irq_stack_exit
 	mov	sp, x19
-	scs_load_current
+#ifdef CONFIG_SHADOW_CALL_STACK
+	mov	scs_sp, x24
+#endif
 	.endm
 
 /* GPRs used by entry code */


Patches currently in stable-queue which might be from xiangyang3 at huawei.com are

queue-5.10/revert-arm64-stash-shadow-stack-pointer-in-the-task-struct-on-interrupt.patch


From gregkh at linuxfoundation.org  Tue Feb 20 07:31:57 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Tue, 20 Feb 2024 16:31:57 +0100
Subject: [PATCH 5.10.y v2] Revert "arm64: Stash shadow stack pointer in
 the task struct on interrupt"
In-Reply-To: <CAMj1kXFwTLJ77MYy3Pm+S9WGgkMw0hAGdTKOF05xdqqBg8giMw@mail.gmail.com>
References: <20240219132153.378265-1-xiangyang3@huawei.com>
 <CAMj1kXFwTLJ77MYy3Pm+S9WGgkMw0hAGdTKOF05xdqqBg8giMw@mail.gmail.com>
Message-ID: <2024022049-worst-dividable-0f1c@gregkh>

On Mon, Feb 19, 2024 at 05:57:07PM +0100, Ard Biesheuvel wrote:
> On Mon, 19 Feb 2024 at 14:24, Xiang Yang <xiangyang3 at huawei.com> wrote:
> >
> > This reverts commit 3f225f29c69c13ce1cbdb1d607a42efeef080056.
> >
> > The shadow call stack for irq now is stored in current task's thread info
> > in irq_stack_entry. There is a possibility that we have some soft irqs
> > pending at the end of hard irq, and when we process softirq with the irq
> > enabled, irq_stack_entry will enter again and overwrite the shadow call
> > stack whitch stored in current task's thread info, leading to the
> > incorrect shadow call stack restoration for the first entry of the hard
> > IRQ, then the system end up with a panic.
> >
> > task A                               |  task A
> > -------------------------------------+------------------------------------
> > el1_irq        //irq1 enter          |
> >   irq_handler  //save scs_sp1        |
> >     gic_handle_irq                   |
> >     irq_exit                         |
> >       __do_softirq                   |
> >                                      | el1_irq         //irq2 enter
> >                                      |   irq_handler   //save scs_sp2
> >                                      |                 //overwrite scs_sp1
> >                                      |   ...
> >                                      |   irq_stack_exit //restore scs_sp2
> >   irq_stack_exit //restore wrong     |
> >                  //scs_sp2           |
> >
> > So revert this commit to fix it.
> >
> > Fixes: 3f225f29c69c ("arm64: Stash shadow stack pointer in the task struct on interrupt")
> >
> > Signed-off-by: Xiang Yang <xiangyang3 at huawei.com>
> 
> Acked-by: Ard Biesheuvel <ardb at kernel.org>

Now queued up, thanks.

greg k-h


From broonie at kernel.org  Tue Feb 20 07:33:31 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 15:33:31 +0000
Subject: arm64/for-kernelci build: 1 build: 0 failed, 1 passed, 1 warning
 (v6.8-rc4-55-g905b00721763)
In-Reply-To: <CAHC9VhS4wFVAbaC2vuHvdbP6ny6Sg0jgASrtbPUtH0Am95h56g@mail.gmail.com>
References: <65cfcc14.170a0220.b8b50.24d9@mx.google.com>
 <20240220114937.GA5545@willie-the-truck>
 <CAHC9VhS4wFVAbaC2vuHvdbP6ny6Sg0jgASrtbPUtH0Am95h56g@mail.gmail.com>
Message-ID: <ab5c9ea4-1915-436c-8b70-2b33b2633c1f@sirena.org.uk>

On Tue, Feb 20, 2024 at 09:59:23AM -0500, Paul Moore wrote:

> Yes, I've seen this reported quite a bit and I've double (triple ...)
> checked that it is a bogus warning.  Kees mentioned that it was due to
> a known gcc bug so I've been ignoring it, I would appreciate it if you
> could do the same.  I love to see bugs reported during the development
> cycle - thanks for your help in this regard! - but I do get tired of
> seeing the same bogus warnings caused by a buggy toolchain.

Note that the toolchain concerned is the Debian one (oldstable now, we
should be upgrading soonish but I don't know about other users) rather
than something obscure and custom.
-------------- 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/20240220/f5b0da6a/attachment-0001.sig>

From alexander.stein at ew.tq-group.com  Tue Feb 20 07:33:33 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 20 Feb 2024 16:33:33 +0100
Subject: [PATCH 1/2] arm64: dts: imx8mq: tqma8mq-mba8mx: Add missing USB vbus supply
Message-ID: <20240220153334.2624873-1-alexander.stein@ew.tq-group.com>

VBUS 5V is statically provided to both USB host and on-bard USB-hub.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
index b2e17d4f335eb..0165f3a259853 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
@@ -160,6 +160,7 @@ &usb_dwc3_0 {
 };
 
 &usb3_phy1 {
+	vbus-supply = <&reg_hub_vbus>;
 	status = "okay";
 };
 
-- 
2.34.1



From alexander.stein at ew.tq-group.com  Tue Feb 20 07:33:34 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 20 Feb 2024 16:33:34 +0100
Subject: [PATCH 2/2] arm64: dts: imx8mn: tqma8mqnl-mba8mx: Add missing USB PHY vbus supply
In-Reply-To: <20240220153334.2624873-1-alexander.stein@ew.tq-group.com>
References: <20240220153334.2624873-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240220153334.2624873-2-alexander.stein@ew.tq-group.com>

VBUS 5V is statically provided to both USB host and on-bard USB-hub.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
index c07d59147ab55..5b682dd907578 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
@@ -86,6 +86,10 @@ &usbotg1 {
 	status = "okay";
 };
 
+&usbphynop1 {
+	vbus-supply = <&reg_hub_vbus>;
+};
+
 &iomuxc {
 	pinctrl_ecspi1: ecspi1grp {
 		fsl,pins = <MX8MN_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK	0x00000146>,
-- 
2.34.1



From bot at kernelci.org  Tue Feb 20 07:34:16 2024
From: bot at kernelci.org (kernelci.org bot)
Date: Tue, 20 Feb 2024 07:34:16 -0800 (PST)
Subject: arm64/for-kernelci build: 1 build: 0 failed, 1 passed,
 1 warning (v6.8-rc5-58-g83d49ede4b181)
Message-ID: <65d4c678.170a0220.b175c.737f@mx.google.com>

arm64/for-kernelci build: 1 build: 0 failed, 1 passed, 1 warning (v6.8-rc5-58-g83d49ede4b181)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v6.8-rc5-58-g83d49ede4b181/

Tree: arm64
Branch: for-kernelci
Git Describe: v6.8-rc5-58-g83d49ede4b181
Git Commit: 83d49ede4b18155a0346064c586a814301b75a76
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

Warnings Detected:

arm64:
    defconfig (gcc-10): 1 warning


Warnings summary:

    1    security/security.c:811:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
defconfig (arm64, gcc-10) ? PASS, 0 errors, 1 warning, 0 section mismatches

Warnings:
    security/security.c:811:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

---
For more info write to <info at kernelci.org>


From maz at kernel.org  Tue Feb 20 07:41:23 2024
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 20 Feb 2024 15:41:23 +0000
Subject: [PATCH 04/13] KVM: arm64: nv: Configure HCR_EL2 for FEAT_NV2
In-Reply-To: <20240220151600.GC8575@e124191.cambridge.arm.com>
References: <20240219092014.783809-1-maz@kernel.org>
	<20240219092014.783809-5-maz@kernel.org>
	<20240220151600.GC8575@e124191.cambridge.arm.com>
Message-ID: <86y1bf2lek.wl-maz@kernel.org>

On Tue, 20 Feb 2024 15:16:00 +0000,
Joey Gouly <joey.gouly at arm.com> wrote:
> 
> Hi,
> 
> On Mon, Feb 19, 2024 at 09:20:05AM +0000, Marc Zyngier wrote:
> > Add the HCR_EL2 configuration for FEAT_NV2, adding the required
> > bits for running a guest hypervisor, and overall merging the
> > allowed bits provided by the guest.
> > 
> > This heavily replies on unavaliable features being sanitised
> > when the HCR_EL2 shadow register is accessed, and only a couple
> > of bits must be explicitly disabled.
> > 
> > Non-NV guests are completely unaffected by any of this.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/include/asm/sysreg.h         |  1 +
> >  arch/arm64/kvm/hyp/include/hyp/switch.h |  4 +--
> >  arch/arm64/kvm/hyp/nvhe/switch.c        |  2 +-
> >  arch/arm64/kvm/hyp/vhe/switch.c         | 34 ++++++++++++++++++++++++-
> >  4 files changed, 36 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index 9e8999592f3a..a5361d9032a4 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -498,6 +498,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_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
> >  #define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
> 
> I'm seeing double! (SYS_VNCR_EL2 is already defined a few lines
> down)

Ah, it got added by Miguel and my rebase didn't weed it out. It also
doesn't help that SYS_TRFCR_EL2 is out of sequence... Anyway, I'll
drop this, thanks for spotting it.

> 
> > diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > index e3fcf8c4d5b4..f5f701f309a9 100644
> > --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> > +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > @@ -271,10 +271,8 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
> >  	__deactivate_traps_hfgxtr(vcpu);
> >  }
> >  
> > -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 c50f8459e4fc..4103625e46c5 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> > @@ -40,7 +40,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 58415783fd53..29f59c374f7a 100644
> > --- a/arch/arm64/kvm/hyp/vhe/switch.c
> > +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> > @@ -33,11 +33,43 @@ DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data);
> >  DEFINE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
> >  DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
> >  
> > +/*
> > + * HCR_EL2 bits that the NV guest can freely change (no RES0/RES1
> > + * semantics, irrespective of the configuration), but that cannot be
> > + * applied to the actual HW as things would otherwise break badly.
> > + *
> > + * - TGE: we want to use EL1, which is incompatible with it being set
> 
> Can you make this a bit clearer:
> 
> 	we want the guest to use EL1
> 
> Assuming I've understood correctly. I first read it as 'we' == kvm.

Sure thing, happy to update that.

>> > + *
> > + * - API/APK: for hysterical raisins, we enable PAuth lazily, which
> > + *   means that the guest's bits cannot be directly applied (we really
> > + *   want to see the traps). Revisit this at some point.
> > + */
> > +#define NV_HCR_GUEST_EXCLUDE	(HCR_TGE | HCR_API | HCR_APK)
> > +
> > +static u64 __compute_hcr(struct kvm_vcpu *vcpu)
> > +{
> > +	u64 hcr = vcpu->arch.hcr_el2;
> > +
> > +	if (!vcpu_has_nv(vcpu))
> > +		return hcr;
> > +
> > +	if (is_hyp_ctxt(vcpu)) {
> > +		hcr |= HCR_NV | HCR_NV2 | HCR_AT | HCR_TTLB;
> > +
> > +		if (!vcpu_el2_e2h_is_set(vcpu))
> > +			hcr |= HCR_NV1;
> > +
> > +		write_sysreg_s(vcpu->arch.ctxt.vncr_array, SYS_VNCR_EL2);
> > +	}
> > +
> > +	return hcr | (__vcpu_sys_reg(vcpu, HCR_EL2) & ~NV_HCR_GUEST_EXCLUDE);
> > +}
> > +
> >  static void __activate_traps(struct kvm_vcpu *vcpu)
> >  {
> >  	u64 val;
> >  
> > -	___activate_traps(vcpu);
> > +	___activate_traps(vcpu, __compute_hcr(vcpu));
> >  
> >  	if (has_cntpoff()) {
> >  		struct timer_map map;
> 
> Otherwise,
> 
> Reviewed-by: Joey Gouly <joey.gouly at arm.com>

Thanks!

	M.

-- 
Without deviation from the norm, progress is not possible.


From geissonator at gmail.com  Tue Feb 20 04:36:15 2024
From: geissonator at gmail.com (Andrew Geissler)
Date: Tue, 20 Feb 2024 06:36:15 -0600
Subject: [PATCH] ipmi: kcs: Update OBF poll timeout to reduce latency
Message-ID: <20240220123615.963916-1-geissonator@gmail.com>

From: Andrew Geissler <geissonator at yahoo.com>

Commit f90bc0f97f2b ("ipmi: kcs: Poll OBF briefly to reduce OBE
latency") introduced an optimization to poll when the host has
read the output data register (ODR). Testing has shown that the 100us
timeout was not always enough. When we miss that 100us window, it
results in 10x the time to get the next message from the BMC to the
host. When you're sending 100's of messages between the BMC and Host,
this results in a server boot taking 50% longer for IBM P10 machines.

Started with 1000 and worked it down until the issue started to reoccur.
200 was the sweet spot in my testing. 150 showed the issue
intermittently.
Signed-off-by: Andrew Geissler <geissonator at yahoo.com>
---
 drivers/char/ipmi/kcs_bmc_aspeed.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c
index 72640da55380..af1eae6153f6 100644
--- a/drivers/char/ipmi/kcs_bmc_aspeed.c
+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
@@ -422,7 +422,7 @@ static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask,
 			 * missed the event.
 			 */
 			rc = read_poll_timeout_atomic(aspeed_kcs_inb, str,
-						      !(str & KCS_BMC_STR_OBF), 1, 100, false,
+						      !(str & KCS_BMC_STR_OBF), 1, 200, false,
 						      &priv->kcs_bmc, priv->kcs_bmc.ioreg.str);
 			/* Time for the slow path? */
 			if (rc == -ETIMEDOUT)
-- 
2.39.2



From pmenzel at molgen.mpg.de  Tue Feb 20 07:51:21 2024
From: pmenzel at molgen.mpg.de (Paul Menzel)
Date: Tue, 20 Feb 2024 16:51:21 +0100
Subject: [PATCH] ipmi: kcs: Update OBF poll timeout to reduce latency
In-Reply-To: <20240220123615.963916-1-geissonator@gmail.com>
References: <20240220123615.963916-1-geissonator@gmail.com>
Message-ID: <a9169894-6972-49c0-a1d4-d80863f5b511@molgen.mpg.de>

Dear Andrew,


Thank you for your patch. Some style suggestions.

Am 20.02.24 um 13:36 schrieb Andrew Geissler:
> From: Andrew Geissler <geissonator at yahoo.com>

(Oh no, Yahoo. (ignore))

You could be more specific in the git commit message by using *Double*:

 > ipmi: kcs: Double OBF poll timeout to reduce latency

 > ipmi: kcs: Double OBF poll timeout to 200 us to reduce latency

> Commit f90bc0f97f2b ("ipmi: kcs: Poll OBF briefly to reduce OBE
> latency") introduced an optimization to poll when the host has
> read the output data register (ODR). Testing has shown that the 100us
> timeout was not always enough. When we miss that 100us window, it
> results in 10x the time to get the next message from the BMC to the
> host. When you're sending 100's of messages between the BMC and Host,

I do not understand, how this poll timeout can result in such an 
increase, and why a quite big timeout hurts, but I do not know the 
implementation.

> this results in a server boot taking 50% longer for IBM P10 machines.
> 
> Started with 1000 and worked it down until the issue started to reoccur.
> 200 was the sweet spot in my testing. 150 showed the issue
> intermittently.

I?d add a blank line here.

> Signed-off-by: Andrew Geissler <geissonator at yahoo.com>
> ---
>   drivers/char/ipmi/kcs_bmc_aspeed.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c
> index 72640da55380..af1eae6153f6 100644
> --- a/drivers/char/ipmi/kcs_bmc_aspeed.c
> +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
> @@ -422,7 +422,7 @@ static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask,
>   			 * missed the event.
>   			 */
>   			rc = read_poll_timeout_atomic(aspeed_kcs_inb, str,
> -						      !(str & KCS_BMC_STR_OBF), 1, 100, false,
> +						      !(str & KCS_BMC_STR_OBF), 1, 200, false,
>   						      &priv->kcs_bmc, priv->kcs_bmc.ioreg.str);
>   			/* Time for the slow path? */
>   			if (rc == -ETIMEDOUT)


Kind regards,

Paul


From alexandru.elisei at arm.com  Tue Feb 20 08:03:06 2024
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 20 Feb 2024 16:03:06 +0000
Subject: arm64 MTE tag storage reuse - alternatives to MIGRATE_CMA
In-Reply-To: <e0b7c884-4345-44b1-b8c0-2711a28a980e@redhat.com>
References: <ZdSMbjGf2Fj98diT@raptor>
 <70d77490-9036-48ac-afc9-4b976433070d@redhat.com>
 <ZdSojvNyaqli2rWE@raptor>
 <e0b7c884-4345-44b1-b8c0-2711a28a980e@redhat.com>
Message-ID: <ZdTNOq9BoOoKo8bZ@raptor>

Hi,

On Tue, Feb 20, 2024 at 03:07:22PM +0100, David Hildenbrand wrote:
> > > 
> > > With large folios in place, we'd likely want to investigate not working on
> > > individual pages, but on (possibly large) folios instead.
> > 
> > Yes, that would be interesting. Since the backend has no way of controlling
> > what tag storage page will be needed for tags, and subsequently dropped
> > from the cache, we would have to figure out what to do if one of the pages
> > that is part of a large folio is dropped. The easiest solution that I can
> > see is to remove the entire folio from the cleancache, but that would mean
> > also dropping the rest of the pages from the folio unnecessarily.
> 
> Right, but likely that won't be an issue. Things get interesting when
> thinking about an efficient allocation approach.

Indeed.

> 
> > 
> > > 
> > > > 
> > > > I believe this is a very good fit for tag storage reuse, because it allows
> > > > tag storage to be allocated even in atomic contexts, which enables MTE in
> > > > the kernel. As a bonus, all of the changes to MM from the current approach
> > > > wouldn't be needed, as tag storage allocation can be handled entirely in
> > > > set_ptes_at(), copy_*highpage() or arch_swap_restore().
> > > > 
> > > > Is this a viable approach that would be upstreamable? Are there other
> > > > solutions that I haven't considered? I'm very much open to any alternatives
> > > > that would make tag storage reuse viable.
> > > 
> > > As raised recently, I had similar ideas with something like virtio-mem in
> > > the past (wanted to call it virtio-tmem back then), but didn't have time to
> > > look into it yet.
> > > 
> > > I considered both, using special device memory as "cleancache" backend, and
> > > using it as backend storage for something similar to zswap. We would not
> > > need a memmap/"struct page" for that special device memory, which reduces
> > > memory overhead and makes "adding more memory" a more reliable operation.
> > 
> > Hm... this might not work with tag storage memory, the kernel needs to
> > perform cache maintenance on the memory when it transitions to and from
> > storing tags and storing data, so the memory must be mapped by the kernel.
> 
> The direct map will definitely be required I think (copy in/out data). But
> memmap for tag memory will likely not be required. Of course, it depends how
> to manage tag storage. Likely we have to store some metadata, hopefully we
> can avoid the full memmap and just use something else.

So I guess instead of ZONE_DEVICE I should try to use arch_add_memory()
directly? That has the limitation that it cannot be used by a driver
(symbol not exported to modules).

Thanks,
Alex


From alexander.stein at ew.tq-group.com  Tue Feb 20 08:03:37 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 20 Feb 2024 17:03:37 +0100
Subject: [PATCH 1/1] arm64: dts: imx8mn: tqma8mqnl-mba8mx: Add USB DR overlay
Message-ID: <20240220160338.2683715-1-alexander.stein@ew.tq-group.com>

imx8mn has only one USB interface. The platform supports using as USB host
(default), or switch to USB DR using this overlay.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm64/boot/dts/freescale/Makefile        |  2 +
 .../imx8mn-tqma8mqnl-mba8mx-usbotg.dtso       | 64 +++++++++++++++++++
 .../dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts |  5 +-
 arch/arm64/boot/dts/freescale/mba8mx.dtsi     |  2 +-
 4 files changed, 69 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-usbotg.dtso

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index fa0ed4f0c9b71..7c2410bad5bac 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -134,7 +134,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mn-var-som-symphony.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-venice-gw7902.dtb
 
 imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33-dtbs += imx8mn-tqma8mqnl-mba8mx.dtb imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtbo
+imx8mn-tqma8mqnl-mba8mx-usbotg-dtbs += imx8mn-tqma8mqnl-mba8mx.dtb imx8mn-tqma8mqnl-mba8mx-usbotg.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mn-tqma8mqnl-mba8mx-usbotg.dtb
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-beacon-kit.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-data-modul-edm-sbc.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-usbotg.dtso b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-usbotg.dtso
new file mode 100644
index 0000000000000..96db07fc9bece
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-usbotg.dtso
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2022-2024 TQ-Systems GmbH <linux at ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mn-pinfunc.h"
+
+&{/} {
+	connector {
+		compatible = "gpio-usb-b-connector", "usb-b-connector";
+		type = "micro";
+		label = "X19";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usb1_connector>;
+		id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+
+		port {
+			usb_dr_connector: endpoint {
+				remote-endpoint = <&usb1_drd_sw>;
+			};
+		};
+	};
+};
+
+&rst_usb_hub_hog {
+	output-low;
+};
+
+&sel_usb_hub_hog {
+	output-low;
+};
+
+&usbotg1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg>;
+	dr_mode = "otg";
+	srp-disable;
+	hnp-disable;
+	adp-disable;
+	power-active-high;
+	/delete-property/ disable-over-current;
+	over-current-active-low;
+	usb-role-switch;
+	status = "okay";
+
+	port {
+		usb1_drd_sw: endpoint {
+			remote-endpoint = <&usb_dr_connector>;
+		};
+	};
+};
+
+&iomuxc {
+	pinctrl_usb1_connector: usb1-connectorgrp {
+		fsl,pins = <MX8MN_IOMUXC_GPIO1_IO10_GPIO1_IO10		0x1c0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
index 5b682dd907578..ca388705ec396 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
@@ -41,7 +41,7 @@ &gpio2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usb0hub_sel>;
 
-	sel-usb-hub-hog {
+	sel_usb_hub_hog: sel-usb-hub-hog {
 		gpio-hog;
 		gpios = <1 GPIO_ACTIVE_HIGH>;
 		output-high;
@@ -202,8 +202,7 @@ pinctrl_usb0hub_sel: usb0hub-selgrp {
 
 	pinctrl_usbotg: usbotggrp {
 		fsl,pins = <MX8MN_IOMUXC_GPIO1_IO12_USB1_OTG_PWR	0x84>,
-			   <MX8MN_IOMUXC_GPIO1_IO13_USB1_OTG_OC		0x84>,
-			   <MX8MN_IOMUXC_GPIO1_IO10_USB1_OTG_ID		0x1C4>;
+			   <MX8MN_IOMUXC_GPIO1_IO13_USB1_OTG_OC		0x84>;
 	};
 
 	pinctrl_usdhc2: usdhc2grp {
diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
index c82af672d1834..427467df42bfa 100644
--- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
@@ -219,7 +219,7 @@ boot-cfg-oe-hog {
 			line-name = "BOOT_CFG_OE#";
 		};
 
-		rst-usb-hub-hog {
+		rst_usb_hub_hog: rst-usb-hub-hog {
 			gpio-hog;
 			gpios = <13 0>;
 			output-high;
-- 
2.34.1



From sean.anderson at seco.com  Tue Feb 20 08:04:19 2024
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 20 Feb 2024 11:04:19 -0500
Subject: [RESEND PATCH net v4 1/2] soc: fsl: qbman: Always disable
 interrupts when taking cgr_lock
In-Reply-To: <20240219153016.ntltc76bphwrv6hn@skbuf>
References: <20240215162327.3663092-1-sean.anderson@seco.com>
 <20240219153016.ntltc76bphwrv6hn@skbuf>
Message-ID: <cc5794cd-8f75-4694-bec6-1c8d7860f877@seco.com>

On 2/19/24 10:30, Vladimir Oltean wrote:
> Hi Sean,
>
> On Thu, Feb 15, 2024 at 11:23:26AM -0500, Sean Anderson wrote:
>> smp_call_function_single disables IRQs when executing the callback. To
>> prevent deadlocks, we must disable IRQs when taking cgr_lock elsewhere.
>> This is already done by qman_update_cgr and qman_delete_cgr; fix the
>> other lockers.
>>
>> Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
>> CC: stable at vger.kernel.org
>> Signed-off-by: Sean Anderson <sean.anderson at seco.com>
>> Reviewed-by: Camelia Groza <camelia.groza at nxp.com>
>> Tested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
>> ---
>> I got no response the first time I sent this, so I am resending to net.
>> This issue was introduced in a series which went through net, so I hope
>> it makes sense to take it via net.
>>
>> [1] https://cas5-0-urlprotect.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2flore.kernel.org%2flinux%2darm%2dkernel%2f20240108161904.2865093%2d1%2dsean.anderson%40seco.com%2f&umid=75622bdd-3d90-45a2-89a9-60921f1f3189&auth=d807158c60b7d2502abde8a2fc01f40662980862-0625a208f4f6c241a307b4380763ba50532758bf
>>
>> (no changes since v3)
>>
>> Changes in v3:
>> - Change blamed commit to something more appropriate
>>
>> Changes in v2:
>> - Fix one additional call to spin_unlock
>
> Leo Li (Li Yang) is no longer with NXP. Until we figure out within NXP
> how to continue with the maintainership of drivers/soc/fsl/, yes, please
> continue to submit this series to 'net'. I would also like to point
> out to Arnd that this is the case.
>
> Arnd, a large portion of drivers/soc/fsl/ is networking-related
> (dpio, qbman). Would it make sense to transfer the maintainership
> of these under the respective networking drivers, to simplify the
> procedures?
>
> Also, your patches are whitespace-damaged. They do not apply to the
> kernel, and patchwork shows this as well.
> https://cas5-0-urlprotect.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2fpatchwork.kernel.org%2fproject%2fnetdevbpf%2fpatch%2f20240215162327.3663092%2d1%2dsean.anderson%40seco.com%2f&umid=75622bdd-3d90-45a2-89a9-60921f1f3189&auth=d807158c60b7d2502abde8a2fc01f40662980862-ec9df03b11ef3e6b48a457ca5469e0b20c4b0439
>
> Please repost with this fixed.

Hm, I used the same method I have in the past (git send-email). But I
guess something is converting my tabs to spaces? Maybe it is related to
the embedded world advertisement...

Maybe the solution is to get a kernel.org email...

--Sean

[Embedded World 2024, SECO SpA]<https://www.messe-ticket.de/Nuernberg/embeddedworld2024/Register/ew24517689>


From vanshikonda at os.amperecomputing.com  Tue Feb 20 08:11:12 2024
From: vanshikonda at os.amperecomputing.com (Vanshidhar Konda)
Date: Tue, 20 Feb 2024 08:11:12 -0800
Subject: [PATCH] cpufreq: CPPC: Resolve the large frequency
 discrepancy from cpuinfo_cur_freq
In-Reply-To: <532d8a81-a42e-f818-332f-2d93acac1e26@huawei.com>
References: <lnocwcitdbmgcyhd2dlczgdlhtfw4pfot2br2i3hqscnvr3xgq@nuxlauxum3nr>
 <d0f47e9d-6a58-8b46-89be-b3182abb69f0@huawei.com>
 <ZZwAmqp6hcmMF8aN@arm.com>
 <6505bdcb-5a5f-cba6-483b-75c51414a9c6@huawei.com>
 <ZaaOQzCpBjmW71xf@e129154.nice.arm.com>
 <a84a9749-97a5-a207-dfd3-8322a5a992d9@huawei.com>
 <Zbyi40XtqbqXm0CL@e129154.nice.arm.com>
 <4f66c62e-b089-a125-5a8d-4a98d4181618@huawei.com>
 <ZcYEjMO7IhSaLAAF@e129154.nice.arm.com>
 <532d8a81-a42e-f818-332f-2d93acac1e26@huawei.com>
Message-ID: <hzfmwbqhhsk7oz6l7pcokdedp3foqdkw7lqh6xjbx4k3erkscx@sjyqnchz7gnp>

On Mon, Feb 19, 2024 at 08:15:50PM +0800, lihuisong (C) wrote:
>
>? 2024/2/9 18:55, Beata Michalska ??:
>>On Tue, Feb 06, 2024 at 04:02:15PM +0800, lihuisong (C) wrote:
>>>? 2024/2/2 16:08, Beata Michalska ??:
>>>>On Wed, Jan 17, 2024 at 05:18:40PM +0800, lihuisong (C) wrote:
>>>>
>>>>Hi ,
>>>>
>>>>Again, apologies for delay,
>>>>
>>>>>Hi,
>>>>>
>>>>>? 2024/1/16 22:10, Beata Michalska ??:
>>>>>>Hi,
>>>>>>
>>>>>>Apologies for jumping in so late....
>>>>>>
>>>>>>On Wed, Jan 10, 2024 at 03:09:48PM +0800, lihuisong (C) wrote:
>>>>>>>Hi Ionela,
>>>>>>>
>>>>>>>? 2024/1/8 22:03, Ionela Voinescu ??:
>>>>>>>>Hi,
>>>>>>>>
>>>>>>>>On Friday 05 Jan 2024 at 15:04:47 (+0800), lihuisong (C) wrote:
>>>>>>>>>Hi Vanshi,
>>>>>>>>>
>>>>>>>>>? 2024/1/5 8:48, Vanshidhar Konda ??:
>>>>>>>>>>On Thu, Jan 04, 2024 at 05:36:51PM +0800, lihuisong (C) wrote:
>>>>>>>>>>>? 2024/1/4 1:53, Ionela Voinescu ??:
>>>>>>>>>>>>Hi,
>>>>>>>>>>>>
>>>>>>>>>>>>On Tuesday 12 Dec 2023 at 15:26:17 (+0800), Huisong Li wrote:
>>>>>>>>>>>>>Many developers found that the cpu current frequency is greater than
>>>>>>>>>>>>>the maximum frequency of the platform, please see [1], [2] and [3].
>>>>>>>>>>>>>
>>>>>>>>>>>>>In the scenarios with high memory access pressure, the patch [1] has
>>>>>>>>>>>>>proved the significant latency of cpc_read() which is used to obtain
>>>>>>>>>>>>>delivered and reference performance counter cause an absurd frequency.
>>>>>>>>>>>>>The sampling interval for this counters is very critical and
>>>>>>>>>>>>>is expected
>>>>>>>>>>>>>to be equal. However, the different latency of cpc_read() has a direct
>>>>>>>>>>>>>impact on their sampling interval.
>>>>>>>>>>>>>
>>>>>>>>>>>>Would this [1] alternative solution work for you?
>>>>>>>>>>>It would work for me AFAICS.
>>>>>>>>>>>Because the "arch_freq_scale" is also from AMU core and constant
>>>>>>>>>>>counter, and read together.
>>>>>>>>>>>But, from their discuss line, it seems that there are some tricky
>>>>>>>>>>>points to clarify or consider.
>>>>>>>>>>I think the changes in [1] would work better when CPUs may be idle. With
>>>>>>>>>>this
>>>>>>>>>>patch we would have to wake any core that is in idle state to read the
>>>>>>>>>>AMU
>>>>>>>>>>counters. Worst case, if core 0 is trying to read the CPU frequency of
>>>>>>>>>>all
>>>>>>>>>>cores, it may need to wake up all the other cores to read the AMU
>>>>>>>>>>counters.
>>>>>>>>>    From the approach in [1], if all CPUs (one or more cores) under one policy
>>>>>>>>>are idle, they still cannot be obtained the CPU frequency, right?
>>>>>>>>>In this case, the [1] API will return 0 and have to back to call
>>>>>>>>>cpufreq_driver->get() for cpuinfo_cur_freq.
>>>>>>>>>Then we still need to face the issue this patch mentioned.
>>>>>>>>With the implementation at [1], arch_freq_get_on_cpu() will not return 0
>>>>>>>>for idle CPUs and the get() callback will not be called to wake up the
>>>>>>>>CPUs.
>>>>>>>Right, arch_freq_get_on_cpu() will not return 0 for idle CPUs.
>>>>>>>However, for no-housekeeping CPUs, it will return 0 and have to call get()
>>>>>>>callback, right?
>>>>>>>>Worst case, arch_freq_get_on_cpu() will return a frequency based on the
>>>>>>>>AMU counter values obtained on the last tick on that CPU. But if that CPU
>>>>>>>>is not a housekeeping CPU, a housekeeping CPU in the same policy will be
>>>>>>>>selected, as it would have had a more recent tick, and therefore a more
>>>>>>>>recent frequency value for the domain.
>>>>>>>But this frequency is from the last tick,
>>>>>>>this last tick is probably a long time ago and it doesn't update
>>>>>>>'arch_freq_scale' for some reasons like CPU dile.
>>>>>>>In addition, I'm not sure if there is possible that amu_scale_freq_tick() is
>>>>>>>executed delayed under high stress case.
>>>>>>>It also have an impact on the accuracy of the cpu frequency we query.
>>>>>>>>I understand that the frequency returned here will not be up to date,
>>>>>>>>but there's no proper frequency feedback for an idle CPU. If one only
>>>>>>>>wakes up a CPU to sample counters, before the CPU goes back to sleep,
>>>>>>>>the obtained frequency feedback is meaningless.
>>>>>>>>
>>>>>>>>>>For systems with 128 cores or more, this could be very expensive and
>>>>>>>>>>happen
>>>>>>>>>>very frequently.
>>>>>>>>>>
>>>>>>>>>>AFAICS, the approach in [1] would avoid this cost.
>>>>>>>>>But the CPU frequency is just an average value for the last tick period
>>>>>>>>>instead of the current one the CPU actually runs at.
>>>>>>>>>In addition, there are some conditions to use 'arch_freq_scale' in this
>>>>>>>>>approach.
>>>>>>>>What are the conditions you are referring to?
>>>>>>>It depends on the housekeeping CPUs.
>>>>>>>>>So I'm not sure if this approach can entirely cover the frequency
>>>>>>>>>discrepancy issue.
>>>>>>>>Unfortunately there is no perfect frequency feedback. By the time you
>>>>>>>>observe/use the value of scaling_cur_freq/cpuinfo_cur_freq, the frequency
>>>>>>>>of the CPU might have already changed. Therefore, an average value might
>>>>>>>>be a better indication of the recent performance level of a CPU.
>>>>>>>An average value for CPU frequency is ok. It may be better if it has not any
>>>>>>>delaying.
>>>>>>>
>>>>>>>The original implementation for cpuinfo_cur_freq can more reflect their
>>>>>>>meaning in the user-guide [1]. The user-guide said:
>>>>>>>"cpuinfo_cur_freq : Current frequency of the CPU as obtained from the
>>>>>>>hardware, in KHz.
>>>>>>>This is the frequency the CPU actually runs at."
>>>>>>>
>>>>>>>
>>>>>>>[1]https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt
>>>>>>>
>>>>>>>>Would you be able to test [1] on your platform and usecase?
>>>>>>>I has tested it on my platform (CPU number: 64, SMT: off and CPU base
>>>>>>>frequency: 2.7GHz).
>>>>>>>Accoding to the testing result,
>>>>>>>1> I found that patch [1] and [2] cannot cover the no housekeeping CPUs.
>>>>>>>They still have to face the large frequency discrepancy issue my patch
>>>>>>>mentioned.
>>>>>>>2> Additionally, the frequency value of all CPUs are almost the same by
>>>>>>>using the 'arch_freq_scale' factor way. I'm not sure if it is ok.
>>>>>>>
>>>>>>>The patch [1] has been modified silightly as below:
>>>>>>>-->
>>>>>>>@@ -1756,7 +1756,10 @@ static unsigned int
>>>>>>>cpufreq_verify_current_freq(struct cpufreq_policy *policy, b
>>>>>>>   ?{
>>>>>>>   ??????? unsigned int new_freq;
>>>>>>>
>>>>>>>-?????? new_freq = cpufreq_driver->get(policy->cpu);
>>>>>>>+?????? new_freq = arch_freq_get_on_cpu(policy->cpu);
>>>>>>>+?????? if (!new_freq)
>>>>>>>+?????????????? new_freq = cpufreq_driver->get(policy->cpu);
>>>>>>>+
>>>>>>As pointed out this change will not make it to the next version of the patch.
>>>>>>So I'd say you can safely ignore it and assume that arch_freq_get_on_cpu will
>>>>>>only be wired for sysfs nodes for scaling_cur_freq/cpuinfo_cur_freq
>>>>>>>   ??????? if (!new_freq)
>>>>>>>   ??????????????? return 0;
>>>>>>>
>>>>>>>And the result is as follows:
>>>>>>>*case 1:**No setting the nohz_full and cpufreq use performance governor*
>>>>>>>*--> Step1: *read 'cpuinfo_cur_freq' in no pressure
>>>>>>>   ? 0: 2699264???? 2: 2699264???? 4: 2699264???? 6: 2699264
>>>>>>>   ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2699264
>>>>>>>   ?16: 2699264??? 18: 2696628??? 20: 2699264??? 22: 2696628
>>>>>>>   ?24: 2699264??? 26: 2696628??? 28: 2699264??? 30: 2696628
>>>>>>>   ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
>>>>>>>   ?40: 2699264??? 42: 2699264??? 44: 2696628??? 46: 2696628
>>>>>>>   ?48: 2696628??? 50: 2699264??? 52: 2699264??? 54: 2696628
>>>>>>>   ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
>>>>>>>   ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2696628
>>>>>>>   ?72: 2699264??? 74: 2696628??? 76: 2696628??? 78: 2699264
>>>>>>>   ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
>>>>>>>   ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2699264
>>>>>>>   ?96: 2696628??? 98: 2699264?? 100: 2699264?? 102: 2696628
>>>>>>>104: 2699264?? 106: 2699264?? 108: 2699264?? 110: 2696628
>>>>>>>112: 2699264?? 114: 2699264?? 116: 2699264?? 118: 2699264
>>>>>>>120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2699264
>>>>>>>Note: the frequency of all CPUs are almost the same.
>>>>>>Were you expecting smth else ?
>>>>>The frequency of each CPU might have a different value.
>>>>>All value of all CPUs is the same under high pressure.
>>>>>I don't know what the phenomenon is on other platform.
>>>>>Do you know who else tested it?
>>>>So I might have rushed a bit with my previous comment/question: apologies for
>>>>that.
>>>>The numbers above: those are on a fairly idle/lightly loaded system right?
>>>Yes.
>>>>Would you mind having another go with just the arch_freq_get_on_cpu
>>>>implementation beign added and dropping the changes in the cpufreq and
>>>All my tests are done when cpufreq policy is "performance" and OS isn't on a
>>>high load.
>>>Reading "scaling_cur_freq" or "scaling_cur_freq" for each physical core on
>>>platform
>>>
>>>The testing result for "cpuinfo_cur_freq" with your changes on a fairly idle
>>>and high loaded system can also be found in this thread.
>>>*A: the result with your changes*
>>>--> Reading "scaling_cur_freq"
>>> ? 0: 2688720???? 2: 2696628???? 4: 2699264???? 6: 2696628
>>> ? 8: 2699264??? 10: 2696628??? 12: 2699264??? 14: 2699264
>>> ?16: 2699264??? 18: 2696628??? 20: 2696628??? 22: 2696628
>>> ?24: 2699264??? 26: 2696628??? 28: 2696628??? 30: 2696628
>>> ?32: 2699264??? 34: 2691356??? 36: 2696628??? 38: 2699264
>>> ?40: 2699264??? 42: 2696628??? 44: 2696628??? 46: 2699264
>>> ?48: 2699264??? 50: 2696628??? 52: 2696628??? 54: 2696628
>>> ?56: 2696628??? 58: 2699264??? 60: 2691356??? 62: 2696628
>>> ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
>>> ?72: 2696628??? 74: 2696628??? 76: 2699264??? 78: 2696628
>>> ?80: 2696628??? 82: 2696628??? 84: 2699264??? 86: 2696628
>>> ?88: 2625456??? 90: 2696628??? 92: 2699264??? 94: 2696628
>>> ?96: 2696628??? 98: 2696628?? 100: 2699264?? 102: 2699264
>>>104: 2699264?? 106: 2696628?? 108: 2699264?? 110: 2696628
>>>112: 2699264?? 114: 2699264?? 116: 2696628?? 118: 2696628
>>>120: 2696628?? 122: 2699264?? 124: 2696628?? 126: 2696628
>>>-->Reading? "cpuinfo_cur_freq"
>>> ? 0: 2696628???? 2: 2696628???? 4: 2699264???? 6: 2688720
>>> ? 8: 2699264??? 10: 2700000??? 12: 2696628??? 14: 2698322
>>> ?16: 2699264??? 18: 2699264??? 20: 2696628??? 22: 2699264
>>> ?24: 2699264??? 26: 2699264??? 28: 2699264??? 30: 2699264
>>> ?32: 2699264??? 34: 2693992??? 36: 2696628??? 38: 2696628
>>> ?40: 2699264??? 42: 2699264??? 44: 2699264??? 46: 2696628
>>> ?48: 2696628??? 50: 2699264??? 52: 2696628??? 54: 2696628
>>> ?56: 2699264??? 58: 2699264??? 60: 2696628??? 62: 2699264
>>> ?64: 2696628??? 66: 2699264??? 68: 2696628??? 70: 2699264
>>> ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2693992
>>> ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
>>> ?88: 2696628??? 90: 2699264??? 92: 2696628??? 94: 2699264
>>> ?96: 2699264??? 98: 2696628?? 100: 2699264?? 102: 2699264
>>>104: 2691356?? 106: 2699264?? 108: 2699264?? 110: 2699264
>>>112: 2699264?? 114: 2696628?? 116: 2699264?? 118: 2699264
>>>120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628
>>>
>>>*B: the result without your changes*
>>>-->Reading "scaling_cur_freq"
>>> ? 0: 2698245???? 2: 2706690???? 4: 2699649???? 6: 2702105
>>> ? 8: 2704362??? 10: 2697993??? 12: 2701672??? 14: 2704362
>>> ?16: 2701052??? 18: 2701052??? 20: 2694385??? 22: 2699650
>>> ?24: 2706802??? 26: 2702389??? 28: 2698299??? 30: 2698299
>>> ?32: 2697333??? 34: 2697993??? 36: 2701337??? 38: 2699328
>>> ?40: 2700330??? 42: 2700330??? 44: 2698019??? 46: 2697697
>>> ?48: 2699659??? 50: 2701700??? 52: 2703401??? 54: 2701700
>>> ?56: 2704013??? 58: 2697658??? 60: 2695000??? 62: 2697666
>>> ?64: 2697902??? 66: 2701052??? 68: 2698245??? 70: 2695789
>>> ?72: 2701315??? 74: 2696655??? 76: 2693666??? 78: 2695317
>>> ?80: 2704912??? 82: 2699649??? 84: 2698245??? 86: 2695454
>>> ?88: 2697966??? 90: 2697959??? 92: 2699319??? 94: 2700680
>>> ?96: 2695317??? 98: 2698996?? 100: 2700000?? 102: 2700334
>>>104: 2701320?? 106: 2695065?? 108: 2700986?? 110: 2703960
>>>112: 2697635?? 114: 2704421?? 116: 2700680?? 118: 2702040
>>>120: 2700334?? 122: 2697993?? 124: 2700334?? 126: 2705351
>>>-->Reading "cpuinfo_cur_freq"
>>> ? 0: 2696853???? 2: 2695454???? 4: 2699649???? 6: 2706993
>>> ? 8: 2706060??? 10: 2704362??? 12: 2704362??? 14: 2697658
>>> ?16: 2707719??? 18: 2697192??? 20: 2702456??? 22: 2699650
>>> ?24: 2705782??? 26: 2698299??? 28: 2703061??? 30: 2705802
>>> ?32: 2700000??? 34: 2700671??? 36: 2701337??? 38: 2697658
>>> ?40: 2700330??? 42: 2700330??? 44: 2699672??? 46: 2697697
>>> ?48: 2703061??? 50: 2696610??? 52: 2692542??? 54: 2704406
>>> ?56: 2695317??? 58: 2699331??? 60: 2698996??? 62: 2702675
>>> ?64: 2704912??? 66: 2703859??? 68: 2699649??? 70: 2698596
>>> ?72: 2703908??? 74: 2703355??? 76: 2697658??? 78: 2695317
>>> ?80: 2702105??? 82: 2707719??? 84: 2702105??? 86: 2699649
>>> ?88: 2697966??? 90: 2691525??? 92: 2701700??? 94: 2700680
>>> ?96: 2695317??? 98: 2698996?? 100: 2698666?? 102: 2700334
>>>104: 2690429?? 106: 2707590?? 108: 2700986?? 110: 2701320
>>>112: 2696283?? 114: 2692881?? 116: 2697627?? 118: 2704421
>>>120: 2698996?? 122: 2696321?? 124: 2696655?? 126: 2695000
>>>
>>So in both cases : whether you use arch_freq_get_on_cpu or not
>>(so with and without the patch) you get roughly the same frequencies
>>on all cores - or am I missing smth from the dump above ?
>The changes in "with/without your changes" I said is your patch 
>intruduced arch_freq_get_on_cpu.
>I just test them according to your requesting.
>>And those are reflecting max freq you have provided earlier (?)
>I know it is an average frequency for the last tickfor using 
>arch_freq_get_on_cpu.
>I have no any doubt that the freq is maximum value on performance governor.
>I just want to say the difference between having or not having your patch.
>The frequency values of all cores from cpuinfo_cur_freq and
>scaling_cur_freq are almost the same if use this arch_freq_get_on_cpu 
>on my platform.
>However, the frequency values of all cores are different if doesn't 
>use this arch_freq_get_on_cpu and just use .get().
>>Note that the arch_freq_get_on_cpu will return an average frequency for
>>the last tick, so even if your system is roughly idle with your performance
>>governor those numbers make sense (some/most of the cores might be idle
>>but you will see the last freq the core was running at before going to idle).
>>I do not think there is an agreement what should be shown for idle core when
>>querying their freq through sysfs. Showing last known freq makes sense, even
>>more than waking up core just to try to get one.
>I'm not opposed to using frequency scale factor to get CPU frequency. 
>But it better be okay.
>>
>>@Ionela: Please jump in if I got things wrong.
>>
>>>>then read 'scaling_cur_freq', doing several reads in some intervals ?
>>>It seems that above phenomenon has not a lot to do with reading intervals.
>>>>The change has been tested on RD-N2 model (Neoverse N2 ref platform),
>>>>it has also been discussed here [1]
>>>I doesn't get the testing result on this platform in its thread.
>>It might be missing exact numbers but the conclusions should be here [1]
>>
>>>>>>>*--> Step 2: *read 'cpuinfo_cur_freq' in the high memory access pressure.
>>>>>>>   ? 0: 2696628???? 2: 2696628???? 4: 2696628???? 6: 2696628
>>>>>>>   ? 8: 2696628??? 10: 2696628??? 12: 2696628??? 14: 2696628
>>>>>>>   ?16: 2696628??? 18: 2696628??? 20: 2696628??? 22: 2696628
>>>>>>>   ?24: 2696628??? 26: 2696628??? 28: 2696628??? 30: 2696628
>>>>>>>   ?32: 2696628??? 34: 2696628??? 36: 2696628??? 38: 2696628
>>>>>>>   ?40: 2696628??? 42: 2696628??? 44: 2696628??? 46: 2696628
>>>>>>>   ?48: 2696628??? 50: 2696628??? 52: 2696628??? 54: 2696628
>>>>>>>   ?56: 2696628??? 58: 2696628??? 60: 2696628??? 62: 2696628
>>>>>>>   ?64: 2696628??? 66: 2696628??? 68: 2696628??? 70: 2696628
>>>>>>>   ?72: 2696628??? 74: 2696628??? 76: 2696628??? 78: 2696628
>>>>>>>   ?80: 2696628??? 82: 2696628??? 84: 2696628??? 86: 2696628
>>>>>>>   ?88: 2696628??? 90: 2696628??? 92: 2696628??? 94: 2696628
>>>>>>>   ?96: 2696628??? 98: 2696628?? 100: 2696628?? 102: 2696628
>>>>>>>104: 2696628?? 106: 2696628?? 108: 2696628?? 110: 2696628
>>>>>>>112: 2696628?? 114: 2696628?? 116: 2696628?? 118: 2696628
>>>>>>>120: 2696628?? 122: 2696628?? 124: 2696628?? 126: 2696628
>>>>>>>
>>>>>>>*Case 2: setting nohz_full and cpufreq use ondemand governor*
>>>>>>>There is "isolcpus=1-10,41-50 nohz_full=1-10,41-50 rcu_nocbs=1-10,41-50" in
>>>>>>>/proc/cmdline.
>>>>>>Right, so if I remember correctly nohz_full implies rcu_nocbs, so no need to
>>>>>>set that one.
>>>>>>Now, afair, isolcpus will make the selected CPUs to disappear from the
>>>>>>schedulers view (no balancing, no migrating), so unless you affine smth
>>>>>>explicitly to those CPUs, you will not see much of an activity there.
>>>>>Correct.
>>>>>>Need to double check though as it has been a while ...
>>>>>>>*--> Step 1: *setting ondemand governor to all policy and query
>>>>>>>'cpuinfo_cur_freq' in no pressure case.
>>>>>>>And the frequency of CPUs all are about 400MHz.
>>>>>>>*--> Step 2:* read 'cpuinfo_cur_freq' in the high memory access pressure.
>>>>>>>The high memory access pressure is from the command: "stress-ng -c 64
>>>>>>>--cpu-load 100% --taskset 0-63"
>>>>>>I'm not entirely convinced that this will affine to isolated cpus, especially
>>>>>>that the affinity mask spans all available cpus. If that is the case, no wonder
>>>>>>your isolated cpus are getting wasted being idle. But I would have to double
>>>>>>check how this is being handled.
>>>>>>>The result:
>>>>>>>   ?0: 2696628???? 1:? 400000???? 2:? 400000???? 3:? 400909
>>>>>>>   ?4:? 400000???? 5:? 400000???? 6:? 400000???? 7:? 400000
>>>>>>>   ?8:? 400000???? 9:? 400000??? 10:? 400600??? 11: 2696628
>>>>>>>12: 2696628??? 13: 2696628??? 14: 2696628??? 15: 2696628
>>>>>>>16: 2696628??? 17: 2696628??? 18: 2696628??? 19: 2696628
>>>>>>>20: 2696628??? 21: 2696628??? 22: 2696628??? 23: 2696628
>>>>>>>24: 2696628??? 25: 2696628??? 26: 2696628??? 27: 2696628
>>>>>>>28: 2696628??? 29: 2696628??? 30: 2696628??? 31: 2696628
>>>>>>>32: 2696628??? 33: 2696628??? 34: 2696628??? 35: 2696628
>>>>>>>36: 2696628??? 37: 2696628??? 38: 2696628??? 39: 2696628
>>>>>>>40: 2696628??? 41:? 400000??? 42:? 400000??? 43:? 400000
>>>>>>>44:? 400000??? 45:? 398847??? 46:? 400000??? 47:? 400000
>>>>>>>48:? 400000??? 49:? 400000??? 50:? 400000??? 51: 2696628
>>>>>>>52: 2696628??? 53: 2696628??? 54: 2696628??? 55: 2696628
>>>>>>>56: 2696628??? 57: 2696628??? 58: 2696628??? 59: 2696628
>>>>>>>60: 2696628??? 61: 2696628??? 62: 2696628??? 63: 2699264
>>>>>>>
>>>>>>>Note:
>>>>>>>(1) The frequency of 1-10 and 41-50 CPUs work on the lowest frequency.
>>>>>>>   ???? It turned out that nohz full was already work.
>>>>>>>   ???? I guess that stress-ng cannot use the CPU in the range of nohz full.
>>>>>>>   ???? Because the CPU frequency will be increased to 2.7G by binding CPU to
>>>>>>>other application.
>>>>>>>(2) The frequency of the nohz full core is calculated by get() callback
>>>>>>>according to ftrace.
>>>>>>It is as there is no sched tick on those, and apparently there is nothing
>>>>>>running on them either.
>>>>>Yes.
>>>>>If we select your approach and the above phenomenon is normal,
>>>>>the large frequency discrepancy issue can be resolved for CPUs with sched
>>>>>tick by the way.
>>>>>But the nohz full cores still have to face this issue. So this patch is also
>>>>>needed.
>>>>>
>>>>Yes, nohz cores full have to be handled by the cpufreq driver.
>>>Correct. So we still have to face the issue in this patch and push this
>>>patch.
>>>Beata, would you please review this patch?
>>Just to clarify for my benefit (apologies but I do have to contex switch
>>pretty often these days): by reviewing this patch do you mean:
>>1) review your changes (if so I think there are few comments already to be
>>addressed, but I can try to have another look)
>Currently, the main comments is that my patch will wake up CPU to get 
>frequency.
>BTW, the core's always been wakened up to get the frequency for FFH 
>way in cppc_acpi. please see cpc_read_ffh().
>So it may be acceptable. After all, we don't query CPU frequency very often.

Today's implementation of cpc_read_ffh() wakes up the core to read AMU
counters - this is far from ideal. According to the architecture
specification the CPU_CYCLES and CNT_CYCLES counters in AMU do not
increment when the core is in WFI or WFE. If we cache the value of the
AMU counter before a PE goes idle, we may be able to avoid waking up a
PE just to read the AMU counters. I'm wondering if it makes sense to
cache the value in cpu_do_idle() and return this cached value if
idle_cpu() returns true.

>But your patch doesn't meet the non-housekeeping cpus.

For non-housekeeping CPUs may be it is better to just invoke
cpufreq->get() call?

Thanks,
Vanshi

>>2) review changes for AMU-based arch_freq_get_on_cpu ?
>>
>>*note: I will still try to have a look at the non-housekeeping cpus case
>I am very much hope that this issue my patch mentioned can be resolved ASAP.
>So what's your plan about non-housekeeping cpus case?
>>
>>---
>>[1] https://lore.kernel.org/lkml/691d3eb2-cd93-f0fc-a7a4-2a8c0d44262c at nvidia.com/
>>---
>>
>>BR
>>Beata
>>>
>>>/Huisong
>>[...]
>>.


From broonie at kernel.org  Tue Feb 20 08:11:30 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 16:11:30 +0000
Subject: [PATCH v5 3/7] arm64/sysreg/tools: Move TRFCR definitions to
 sysreg
In-Reply-To: <20240220100924.2761706-4-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
 <20240220100924.2761706-4-james.clark@arm.com>
Message-ID: <18995343-e43e-4e92-a97d-3df74ec6ddb7@sirena.org.uk>

On Tue, Feb 20, 2024 at 10:09:13AM +0000, James Clark wrote:
> Add separate definitions for ELx and EL2 as TRFCR_EL1 doesn't have CX.
> This also mirrors the previous definition so no code change is required.

This is also converting to automatic generation in the process.

> +SysregFields TRFCR_EL2
> +Res0	63:7
> +UnsignedEnum	6:5	TS
> +	0b0000	USE_TRFCR_EL1_TS
> +	0b0001	VIRTUAL
> +	0b0010	GUEST_PHYSICAL
> +	0b0011	PHYSICAL
> +EndEnum
> +Res0	4
> +Field	3	CX
> +Res0	2
> +Field	1	E2TRE
> +Field	0	E0HTRE
> +EndSysregFields

This has exactly one user and I'd not expect more so why have a separate
SysregFields?

> +# TRFCR_EL1 doesn't have the CX bit so redefine it without CX instead of
> +# using a shared definition between TRFCR_EL2 and TRFCR_EL1

This comment is reflecting the default state?

> +Sysreg	TRFCR_EL1	3	0	1	2	1
> +Fields	TRFCR_ELx
> +EndSysreg
> +
> +Sysreg	TRFCR_EL2	3	4	1	2	1
> +Fields	TRFCR_EL2
> +EndSysreg
> +
> +Sysreg	TRFCR_EL12	3	5	1	2	1
> +Fields	TRFCR_ELx
> +EndSysreg

These are generally sorted by encoding (simiarly to how sysreg.h was
sorted historically).
-------------- 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/20240220/7e732c36/attachment.sig>

From broonie at kernel.org  Tue Feb 20 08:12:57 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 16:12:57 +0000
Subject: [PATCH v5 2/7] arm64/sysreg/tools: Update tools copy of sysreg.h
In-Reply-To: <20240220100924.2761706-3-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
 <20240220100924.2761706-3-james.clark@arm.com>
Message-ID: <3bfe4365-bbee-4a25-9d12-3bb2b72a36da@sirena.org.uk>

On Tue, Feb 20, 2024 at 10:09:12AM +0000, James Clark wrote:
> Created with the following:
> 
>   cp include/linux/kasan-tags.h tools/include/linux/
>   cp arch/arm64/include/asm/sysreg.h tools/arch/arm64/include/asm/
> 
> Update the tools copy of sysreg.h so that the next commit to add a new
> register doesn't have unrelated changes in it. Because the new version
> of sysreg.h includes kasan-tags.h, that file also now needs to be copied
> into tools.

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/20240220/dc1d09c6/attachment.sig>

From david at redhat.com  Tue Feb 20 08:16:26 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 20 Feb 2024 17:16:26 +0100
Subject: arm64 MTE tag storage reuse - alternatives to MIGRATE_CMA
In-Reply-To: <ZdTNOq9BoOoKo8bZ@raptor>
References: <ZdSMbjGf2Fj98diT@raptor>
 <70d77490-9036-48ac-afc9-4b976433070d@redhat.com> <ZdSojvNyaqli2rWE@raptor>
 <e0b7c884-4345-44b1-b8c0-2711a28a980e@redhat.com> <ZdTNOq9BoOoKo8bZ@raptor>
Message-ID: <b10d52ba-4a8d-43bd-96c1-cde848bec143@redhat.com>

>>>>> I believe this is a very good fit for tag storage reuse, because it allows
>>>>> tag storage to be allocated even in atomic contexts, which enables MTE in
>>>>> the kernel. As a bonus, all of the changes to MM from the current approach
>>>>> wouldn't be needed, as tag storage allocation can be handled entirely in
>>>>> set_ptes_at(), copy_*highpage() or arch_swap_restore().
>>>>>
>>>>> Is this a viable approach that would be upstreamable? Are there other
>>>>> solutions that I haven't considered? I'm very much open to any alternatives
>>>>> that would make tag storage reuse viable.
>>>>
>>>> As raised recently, I had similar ideas with something like virtio-mem in
>>>> the past (wanted to call it virtio-tmem back then), but didn't have time to
>>>> look into it yet.
>>>>
>>>> I considered both, using special device memory as "cleancache" backend, and
>>>> using it as backend storage for something similar to zswap. We would not
>>>> need a memmap/"struct page" for that special device memory, which reduces
>>>> memory overhead and makes "adding more memory" a more reliable operation.
>>>
>>> Hm... this might not work with tag storage memory, the kernel needs to
>>> perform cache maintenance on the memory when it transitions to and from
>>> storing tags and storing data, so the memory must be mapped by the kernel.
>>
>> The direct map will definitely be required I think (copy in/out data). But
>> memmap for tag memory will likely not be required. Of course, it depends how
>> to manage tag storage. Likely we have to store some metadata, hopefully we
>> can avoid the full memmap and just use something else.
> 
> So I guess instead of ZONE_DEVICE I should try to use arch_add_memory()
> directly? That has the limitation that it cannot be used by a driver
> (symbol not exported to modules).
You can certainly start with something simple, and we can work on 
removing that memmap allocation later.

Maybe we have to expose new primitives in the context of such drivers. 
arch_add_memory() likely also doesn't do what you need.

I recall that we had a way of only messing with the direct map.

Last time I worked with that was in the context of memtrace
(arch/powerpc/platforms/powernv/memtrace.c)

There, we call arch_create_linear_mapping()/arch_remove_linear_mapping().

... and now my memory comes back: we never finished factoring out 
arch_create_linear_mapping/arch_remove_linear_mapping so they would be 
available on all architectures.


Your driver will be very arm64 specific, so doing it in an arm64-special 
way might be good enough initially. For example, the arm64-core could 
detect that special memory region and just statically prepare the direct 
map and not expose the memory to the buddy/allocate a memmap. Similar to 
how we handle the crashkernel/kexec IIRC (we likely do not have a direct 
map for that, though; ).

[I was also wondering if we could simply dynamically map/unmap when 
required so you can just avoid creating the entire direct map; might bot 
be the best approach performance-wise, though]

There are a bunch of details to be sorted out, but I don't consider the 
directmap/memmap side of things a big problem.

-- 
Cheers,

David / dhildenb



From bot at kernelci.org  Tue Feb 20 08:17:34 2024
From: bot at kernelci.org (kernelci.org bot)
Date: Tue, 20 Feb 2024 08:17:34 -0800 (PST)
Subject: arm64/for-kernelci baseline: 36 runs,
 7 regressions (v6.8-rc5-58-g83d49ede4b181)
Message-ID: <65d4d09e.630a0220.63ec1.4fd8@mx.google.com>

arm64/for-kernelci baseline: 36 runs, 7 regressions (v6.8-rc5-58-g83d49ede4b181)

Regressions Summary
-------------------

platform               | arch  | lab         | compiler | defconfig | regressions
-----------------------+-------+-------------+----------+-----------+------------
kontron-kbox-a-230-ls  | arm64 | lab-kontron | gcc-10   | defconfig | 5          
kontron-sl28-var3-ads2 | arm64 | lab-kontron | gcc-10   | defconfig | 2          

  Details:  https://kernelci.org/test/job/arm64/branch/for-kernelci/kernel/v6.8-rc5-58-g83d49ede4b181/plan/baseline/

  Test:     baseline
  Tree:     arm64
  Branch:   for-kernelci
  Describe: v6.8-rc5-58-g83d49ede4b181
  URL:      https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
  SHA:      83d49ede4b18155a0346064c586a814301b75a76 


Test Regressions
---------------- 


platform               | arch  | lab         | compiler | defconfig | regressions
-----------------------+-------+-------------+----------+-----------+------------
kontron-kbox-a-230-ls  | arm64 | lab-kontron | gcc-10   | defconfig | 5          

  Details:     https://kernelci.org/test/plan/id/65d4c664f9e7edfe9e63701e

  Results:     90 PASS, 5 FAIL, 1 SKIP
  Full config: defconfig
  Compiler:    gcc-10 (aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc5-58-g83d49ede4b181/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-kbox-a-230-ls.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc5-58-g83d49ede4b181/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-kbox-a-230-ls.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230623.0/arm64/rootfs.cpio.gz 


  * baseline.bootrr.deferred-probe-empty: https://kernelci.org/test/case/id/65d4c664f9e7edfe9e637025
        failing since 20 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-20T15:33:36.972688  / # #
    2024-02-20T15:33:37.074893  export SHELL=/bin/sh
    2024-02-20T15:33:37.075643  #
    2024-02-20T15:33:37.177006  / # export SHELL=/bin/sh. /lava-432699/environment
    2024-02-20T15:33:37.177811  
    2024-02-20T15:33:37.279301  / # . /lava-432699/environment/lava-432699/bin/lava-test-runner /lava-432699/1
    2024-02-20T15:33:37.280561  
    2024-02-20T15:33:37.299800  / # /lava-432699/bin/lava-test-runner /lava-432699/1
    2024-02-20T15:33:37.342946  + export 'TESTRUN_ID=1_bootrr'
    2024-02-20T15:33:37.343369  + <8>[   20.525207] <LAVA_SIGNAL_STARTRUN 1_bootrr 432699_1.5.2.4.5> 
    ... (14 line(s) more)  

  * baseline.bootrr.fsl_enetc-enetc2-probed: https://kernelci.org/test/case/id/65d4c664f9e7edfe9e637029
        failing since 20 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-20T15:33:39.451840  /lava-432699/1/../bin/lava-test-case
    2024-02-20T15:33:39.451958  <8>[   22.635628] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc2-probed RESULT=fail>
    2024-02-20T15:33:39.452031  /lava-432699/1/../bin/lava-test-case   

  * baseline.bootrr.mscc_felix-probed: https://kernelci.org/test/case/id/65d4c664f9e7edfe9e63702b
        failing since 20 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-20T15:33:40.512200  /lava-432699/1/../bin/lava-test-case
    2024-02-20T15:33:40.512636  <8>[   23.674476] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=mscc_felix-probed RESULT=fail>   

  * baseline.bootrr.fsl_enetc-enetc0-probed: https://kernelci.org/test/case/id/65d4c664f9e7edfe9e637030
        failing since 20 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-20T15:33:41.590182  /lava-432699/1/../bin/lava-test-case   

  * baseline.bootrr.fsl_enetc-enetc1-probed: https://kernelci.org/test/case/id/65d4c664f9e7edfe9e637031
        failing since 20 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-20T15:33:41.593369  <8>[   24.790377] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc0-probed RESULT=fail>
    2024-02-20T15:33:42.647812  /lava-432699/1/../bin/lava-test-case
    2024-02-20T15:33:42.648252  <8>[   25.812130] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc1-probed RESULT=fail>
    2024-02-20T15:33:42.648606  /lava-432699/1/../bin/lava-test-case   
 


platform               | arch  | lab         | compiler | defconfig | regressions
-----------------------+-------+-------------+----------+-----------+------------
kontron-sl28-var3-ads2 | arm64 | lab-kontron | gcc-10   | defconfig | 2          

  Details:     https://kernelci.org/test/plan/id/65d4c6792a587e833963701e

  Results:     101 PASS, 2 FAIL, 1 SKIP
  Full config: defconfig
  Compiler:    gcc-10 (aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc5-58-g83d49ede4b181/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-sl28-var3-ads2.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc5-58-g83d49ede4b181/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-sl28-var3-ads2.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230623.0/arm64/rootfs.cpio.gz 


  * baseline.bootrr.deferred-probe-empty: https://kernelci.org/test/case/id/65d4c6792a587e8339637025
        failing since 20 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-20T15:34:04.034774  / # #
    2024-02-20T15:34:04.136760  export SHELL=/bin/sh
    2024-02-20T15:34:04.137358  #
    2024-02-20T15:34:04.238405  / # export SHELL=/bin/sh. /lava-432704/environment
    2024-02-20T15:34:04.238953  
    2024-02-20T15:34:04.339967  / # . /lava-432704/environment/lava-432704/bin/lava-test-runner /lava-432704/1
    2024-02-20T15:34:04.340436  
    2024-02-20T15:34:04.349548  / # /lava-432704/bin/lava-test-runner /lava-432704/1
    2024-02-20T15:34:04.389949  + export 'TESTRUN_ID=1_bootrr'
    2024-02-20T15:34:04.410554  + <8>[   21.024191] <LAVA_SIGNAL_STARTRUN 1_bootrr 432704_1.5.2.4.5> 
    ... (10 line(s) more)  

  * baseline.bootrr.fsl_enetc-enetc0-probed: https://kernelci.org/test/case/id/65d4c6792a587e8339637038
        failing since 20 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-20T15:34:06.846785  /lava-432704/1/../bin/lava-test-case
    2024-02-20T15:34:06.847246  <8>[   23.444680] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc0-probed RESULT=fail>
    2024-02-20T15:34:06.847543  /lava-432704/1/../bin/lava-test-case   
  


From Frank.Li at nxp.com  Tue Feb 20 08:19:10 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:10 -0500
Subject: [PATCH v11 00/14] PCI: imx6: Clean up and add imx95 pci support
Message-ID: <20240220161924.3871774-1-Frank.Li@nxp.com>

first 6 patches use drvdata: flags to simplify some switch-case code.
Improve maintaince and easy to read code.

Then add imx95 basic pci host function.

follow two patch do endpoint code clean up.
Then add imx95 basic endpont function.

Compared with v2, added EP function support and some fixes,  please change
notes at each patches.

Change from v10 to v11
- Rebase to linux-pci/endpoint

Change from v9 to v10
- remove two patches:
>   dt-bindings: imx6q-pcie: Add linux,pci-domain as required for iMX8MQ
>   PCI: imx6: Using "linux,pci-domain" as slot ID
it is not good solution to fixed hardcode check to get controller id.
Will see better solution later.

dt-binding pass pcie node:

pcie0: pcie at 4c300000 {
                        compatible = "fsl,imx95-pcie";
                        reg = <0 0x4c300000 0 0x40000>,
                                <0 0x4c360000 0 0x10000>,
                                <0 0x4c340000 0 0x20000>,
                                <0 0x60100000 0 0xfe00000>;
                        reg-names = "dbi", "atu", "app", "config";
                        #address-cells = <3>;
                        #size-cells = <2>;
                        device_type = "pci";
                        linux,pci-domain = <0>;
                        bus-range = <0x00 0xff>;
                        ranges = <0x81000000 0x0 0x00000000 0x0 0x6ff00000 0 0x00100000>,
                                 <0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000>;
                        num-lanes = <1>;
                        num-viewport = <8>;
                        interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "msi";
                        #interrupt-cells = <1>;
                        interrupt-map-mask = <0 0 0 0x7>;
                        interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
                                        <0 0 0 2 &gic 0 0 GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
                                        <0 0 0 3 &gic 0 0 GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
                                        <0 0 0 4 &gic 0 0 GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
                        fsl,max-link-speed = <3>;
                        clocks = <&scmi_clk IMX95_CLK_HSIO>,
                                 <&scmi_clk IMX95_CLK_HSIOPLL>,
                                 <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
                                 <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
                        clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
                        assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
                                         <&scmi_clk IMX95_CLK_HSIOPLL>,
                                         <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
                        assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
                        assigned-clock-parents = <0>, <0>,
                                                 <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
                        power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
                        /* 0x30~0x37 stream id for pci0 */
                        /*
                         * iommu-map = <0x000 &apps_smmu 0x30 0x1>,
                         * <0x100 &apps_smmu 0x31 0x1>;
                         */
                        status = "disabled";
                };

pcie1: pcie-ep at 4c380000 {
                        compatible = "fsl,imx95-pcie-ep";
                        reg = <0 0x4c380000 0 0x20000>,
                              <0 0x4c3e0000 0 0x1000>,
                              <0 0x4c3a0000 0 0x1000>,
                              <0 0x4c3c0000 0 0x10000>,
                              <0 0x4c3f0000 0 0x10000>,
                              <0xa 0 1 0>;
                        reg-names = "dbi", "atu", "dbi2", "app", "dma", "addr_space";
                        interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "dma";
                        fsl,max-link-speed = <3>;
                        clocks = <&scmi_clk IMX95_CLK_HSIO>,
                                 <&scmi_clk IMX95_CLK_HSIOPLL>,
                                 <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
                                 <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
                        clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux";
                        assigned-clocks =<&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
                                         <&scmi_clk IMX95_CLK_HSIOPLL>,
                                         <&scmi_clk IMX95_CLK_HSIOPCIEAUX>;
                        assigned-clock-rates = <3600000000>, <100000000>, <10000000>;
                        assigned-clock-parents = <0>, <0>,
                                                 <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
                        power-domains = <&scmi_devpd IMX95_PD_HSIO_TOP>;
                        status = "disabled";
                };

Frank Li (13):
  PCI: imx6: Simplify clock handling by using clk_bulk*() function
  PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
  PCI: imx6: Simplify reset handling by using by using
    *_FLAG_HAS_*_RESET
  PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
  PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
  PCI: imx6: Simplify switch-case logic by involve init_phy callback
  dt-bindings: imx6q-pcie: Clean up irrationality clocks check
  dt-bindings: imx6q-pcie: Restruct reg and reg-name
  PCI: imx6: Add iMX95 PCIe Root Complex support
  PCI: imx6: Clean up get addr_space code
  PCI: imx6: Add epc_features in imx6_pcie_drvdata
  dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
  PCI: imx6: Add iMX95 Endpoint (EP) support

Richard Zhu (1):
  dt-bindings: imx6q-pcie: Add imx95 pcie compatible string

 .../bindings/pci/fsl,imx6q-pcie-common.yaml   |  17 +-
 .../bindings/pci/fsl,imx6q-pcie-ep.yaml       |  46 +-
 .../bindings/pci/fsl,imx6q-pcie.yaml          |  49 +-
 drivers/pci/controller/dwc/pci-imx6.c         | 634 ++++++++++--------
 4 files changed, 436 insertions(+), 310 deletions(-)

-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:11 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:11 -0500
Subject: [PATCH v11 01/14] PCI: imx6: Simplify clock handling by using clk_bulk*() function
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-2-Frank.Li@nxp.com>

Refector the clock handling logic. Add 'clk_names' define in drvdata. Use
clk_bulk*() api simplify the code.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v9 to v10
    - fixed missed delete a case, which need failthrough to next one.
    Change from v8 to v9
    - change clks names
    - Add Manivannan's review tag
    
    Change from v7 to v8
    - update comment message
    - using ARRAY_SIZE to count clk_names.
    Change from v6 to v7
    - none
    Change from v4 to v5
    - update commit message
    - direct using clk name list, instead of macro
    - still keep caculate clk list count because sizeof return pre allocated
    array size.
    
    Change from v3 to v4
    - using clk_bulk_*() API
    Change from v1 to v3
    - none
    
    Change from v4 to v5
    - update commit message
    - direct using clk name list, instead of macro
    - still keep caculate clk list count because sizeof return pre allocated
    array size.
    
    Change from v3 to v4
    - using clk_bulk_*() API
    Change from v1 to v3
    - none
    
    Change from v8 to v9
    - change clks names
    - Add Manivannan's review tag
    
    Change from v7 to v8
    - update comment message
    - using ARRAY_SIZE to count clk_names.
    Change from v6 to v7
    - none
    Change from v4 to v5
    - update commit message
    - direct using clk name list, instead of macro
    - still keep caculate clk list count because sizeof return pre allocated
    array size.
    
    Change from v3 to v4
    - using clk_bulk_*() API
    Change from v1 to v3
    - none
    
    Change from v4 to v5
    - update commit message
    - direct using clk name list, instead of macro
    - still keep caculate clk list count because sizeof return pre allocated
    array size.
    
    Change from v3 to v4
    - using clk_bulk_*() API
    Change from v1 to v3
    - none

 drivers/pci/controller/dwc/pci-imx6.c | 138 ++++++++++----------------
 1 file changed, 50 insertions(+), 88 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 1975ab74a5ec9..93c304899bd6c 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -61,12 +61,16 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
 #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
 
+#define IMX6_PCIE_MAX_CLKS       6
+
 struct imx6_pcie_drvdata {
 	enum imx6_pcie_variants variant;
 	enum dw_pcie_device_mode mode;
 	u32 flags;
 	int dbi_length;
 	const char *gpr;
+	const char * const *clk_names;
+	const u32 clks_cnt;
 };
 
 struct imx6_pcie {
@@ -74,11 +78,7 @@ struct imx6_pcie {
 	int			reset_gpio;
 	bool			gpio_active_high;
 	bool			link_is_up;
-	struct clk		*pcie_bus;
-	struct clk		*pcie_phy;
-	struct clk		*pcie_inbound_axi;
-	struct clk		*pcie;
-	struct clk		*pcie_aux;
+	struct clk_bulk_data	clks[IMX6_PCIE_MAX_CLKS];
 	struct regmap		*iomuxc_gpr;
 	u16			msi_ctrl;
 	u32			controller_id;
@@ -407,13 +407,18 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
 
 static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
 {
-	unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy);
+	unsigned long phy_rate = 0;
 	int mult, div;
 	u16 val;
+	int i;
 
 	if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY))
 		return 0;
 
+	for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
+		if (strncmp(imx6_pcie->clks[i].id, "pcie_phy", 8) == 0)
+			phy_rate = clk_get_rate(imx6_pcie->clks[i].clk);
+
 	switch (phy_rate) {
 	case 125000000:
 		/*
@@ -550,19 +555,11 @@ static int imx6_pcie_attach_pd(struct device *dev)
 
 static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 {
-	struct dw_pcie *pci = imx6_pcie->pci;
-	struct device *dev = pci->dev;
 	unsigned int offset;
 	int ret = 0;
 
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX6SX:
-		ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
-		if (ret) {
-			dev_err(dev, "unable to enable pcie_axi clock\n");
-			break;
-		}
-
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
 		break;
@@ -589,12 +586,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 	case IMX8MQ_EP:
 	case IMX8MP:
 	case IMX8MP_EP:
-		ret = clk_prepare_enable(imx6_pcie->pcie_aux);
-		if (ret) {
-			dev_err(dev, "unable to enable pcie_aux clock\n");
-			break;
-		}
-
 		offset = imx6_pcie_grp_offset(imx6_pcie);
 		/*
 		 * Set the over ride low and enabled
@@ -615,9 +606,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
 {
 	switch (imx6_pcie->drvdata->variant) {
-	case IMX6SX:
-		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
-		break;
 	case IMX6QP:
 	case IMX6Q:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
@@ -631,14 +619,6 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
 				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
 				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
 		break;
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MQ:
-	case IMX8MQ_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		clk_disable_unprepare(imx6_pcie->pcie_aux);
-		break;
 	default:
 		break;
 	}
@@ -650,23 +630,9 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
 	struct device *dev = pci->dev;
 	int ret;
 
-	ret = clk_prepare_enable(imx6_pcie->pcie_phy);
-	if (ret) {
-		dev_err(dev, "unable to enable pcie_phy clock\n");
+	ret = clk_bulk_prepare_enable(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
+	if (ret)
 		return ret;
-	}
-
-	ret = clk_prepare_enable(imx6_pcie->pcie_bus);
-	if (ret) {
-		dev_err(dev, "unable to enable pcie_bus clock\n");
-		goto err_pcie_bus;
-	}
-
-	ret = clk_prepare_enable(imx6_pcie->pcie);
-	if (ret) {
-		dev_err(dev, "unable to enable pcie clock\n");
-		goto err_pcie;
-	}
 
 	ret = imx6_pcie_enable_ref_clk(imx6_pcie);
 	if (ret) {
@@ -679,11 +645,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
 	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);
+	clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
 
 	return ret;
 }
@@ -691,9 +653,7 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
 static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
 {
 	imx6_pcie_disable_ref_clk(imx6_pcie);
-	clk_disable_unprepare(imx6_pcie->pcie);
-	clk_disable_unprepare(imx6_pcie->pcie_bus);
-	clk_disable_unprepare(imx6_pcie->pcie_phy);
+	clk_bulk_disable_unprepare(imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
 }
 
 static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
@@ -1253,6 +1213,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	struct device_node *node = dev->of_node;
 	int ret;
 	u16 val;
+	int i;
 
 	imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
 	if (!imx6_pcie)
@@ -1306,32 +1267,20 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 		return imx6_pcie->reset_gpio;
 	}
 
-	/* Fetch clocks */
-	imx6_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus");
-	if (IS_ERR(imx6_pcie->pcie_bus))
-		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_bus),
-				     "pcie_bus clock source missing or invalid\n");
+	if (imx6_pcie->drvdata->clks_cnt >= IMX6_PCIE_MAX_CLKS)
+		return dev_err_probe(dev, -ENOMEM, "clks_cnt is too big\n");
 
-	imx6_pcie->pcie = devm_clk_get(dev, "pcie");
-	if (IS_ERR(imx6_pcie->pcie))
-		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie),
-				     "pcie clock source missing or invalid\n");
+	for (i = 0; i < imx6_pcie->drvdata->clks_cnt; i++)
+		imx6_pcie->clks[i].id = imx6_pcie->drvdata->clk_names[i];
+
+	/* Fetch clocks */
+	ret = devm_clk_bulk_get(dev, imx6_pcie->drvdata->clks_cnt, imx6_pcie->clks);
+	if (ret)
+		return ret;
 
 	switch (imx6_pcie->drvdata->variant) {
-	case IMX6SX:
-		imx6_pcie->pcie_inbound_axi = devm_clk_get(dev,
-							   "pcie_inbound_axi");
-		if (IS_ERR(imx6_pcie->pcie_inbound_axi))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_inbound_axi),
-					     "pcie_inbound_axi clock missing or invalid\n");
-		break;
 	case IMX8MQ:
 	case IMX8MQ_EP:
-		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
-		if (IS_ERR(imx6_pcie->pcie_aux))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
-					     "pcie_aux clock source missing or invalid\n");
-		fallthrough;
 	case IMX7D:
 		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
 			imx6_pcie->controller_id = 1;
@@ -1354,10 +1303,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	case IMX8MM_EP:
 	case IMX8MP:
 	case IMX8MP_EP:
-		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
-		if (IS_ERR(imx6_pcie->pcie_aux))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
-					     "pcie_aux clock source missing or invalid\n");
 		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
 									 "apps");
 		if (IS_ERR(imx6_pcie->apps_reset))
@@ -1373,14 +1318,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	default:
 		break;
 	}
-	/* Don't fetch the pcie_phy clock, if it has abstract PHY driver */
-	if (imx6_pcie->phy == NULL) {
-		imx6_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy");
-		if (IS_ERR(imx6_pcie->pcie_phy))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_phy),
-					     "pcie_phy clock source missing or invalid\n");
-	}
-
 
 	/* Grab turnoff reset */
 	imx6_pcie->turnoff_reset = devm_reset_control_get_optional_exclusive(dev, "turnoff");
@@ -1471,6 +1408,11 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
 	imx6_pcie_assert_core_reset(imx6_pcie);
 }
 
+static const char * const imx6q_clks[] = {"pcie_bus", "pcie", "pcie_phy"};
+static const char * const imx8mm_clks[] = {"pcie_bus", "pcie", "pcie_aux"};
+static const char * const imx8mq_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_aux"};
+static const char * const imx6sx_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_inbound_axi"};
+
 static const struct imx6_pcie_drvdata drvdata[] = {
 	[IMX6Q] = {
 		.variant = IMX6Q,
@@ -1478,6 +1420,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
 		.dbi_length = 0x200,
 		.gpr = "fsl,imx6q-iomuxc-gpr",
+		.clk_names = imx6q_clks,
+		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 	},
 	[IMX6SX] = {
 		.variant = IMX6SX,
@@ -1485,6 +1429,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE |
 			 IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
 		.gpr = "fsl,imx6q-iomuxc-gpr",
+		.clk_names = imx6sx_clks,
+		.clks_cnt = ARRAY_SIZE(imx6sx_clks),
 	},
 	[IMX6QP] = {
 		.variant = IMX6QP,
@@ -1493,40 +1439,56 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 			 IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
 		.dbi_length = 0x200,
 		.gpr = "fsl,imx6q-iomuxc-gpr",
+		.clk_names = imx6q_clks,
+		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 	},
 	[IMX7D] = {
 		.variant = IMX7D,
 		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
 		.gpr = "fsl,imx7d-iomuxc-gpr",
+		.clk_names = imx6q_clks,
+		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 	},
 	[IMX8MQ] = {
 		.variant = IMX8MQ,
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
+		.clk_names = imx8mq_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
 	},
 	[IMX8MM] = {
 		.variant = IMX8MM,
 		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
+		.clk_names = imx8mm_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 	[IMX8MP] = {
 		.variant = IMX8MP,
 		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
+		.clk_names = imx8mm_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 	[IMX8MQ_EP] = {
 		.variant = IMX8MQ_EP,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
+		.clk_names = imx8mq_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
 	},
 	[IMX8MM_EP] = {
 		.variant = IMX8MM_EP,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
+		.clk_names = imx8mm_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 	[IMX8MP_EP] = {
 		.variant = IMX8MP_EP,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
+		.clk_names = imx8mm_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 };
 
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:12 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:12 -0500
Subject: [PATCH v11 02/14] PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-3-Frank.Li@nxp.com>

Since some i.MX platforms make use of the separate PHY driver, use
IMX6_PCIE_FLAG_HAS_PHYDRV flag to identify them and get the reference to
PHY from DT. This simplifies the code.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v8 to v9:
    - change commit message according Manivannan's suggestion
    - Add Manivannan's review tag
    Change from v7 to v8:
    - renmae IMX6_PCIE_FLAG_HAS_PHY to IMX6_PCIE_FLAG_HAS_PHYDRV
    Change from v6 to v7:
    - none
    Change from v4 to v5:
    - none, Keep IMX6_PCIE_FLAG_HAS_PHY to indicate dts mismatch when platform
    require phy suppport.
    
    Change from v1 to v3:
    - none

 drivers/pci/controller/dwc/pci-imx6.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 93c304899bd6c..12a2bc76f0b39 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -60,6 +60,9 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_FLAG_IMX6_PHY			BIT(0)
 #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
 #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
+#define IMX6_PCIE_FLAG_HAS_PHYDRV			BIT(3)
+
+#define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
 
 #define IMX6_PCIE_MAX_CLKS       6
 
@@ -1278,6 +1281,13 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_PHYDRV)) {
+		imx6_pcie->phy = devm_phy_get(dev, "pcie-phy");
+		if (IS_ERR(imx6_pcie->phy))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->phy),
+					     "failed to get pcie phy\n");
+	}
+
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX8MQ:
 	case IMX8MQ_EP:
@@ -1309,11 +1319,6 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 			return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
 					     "failed to get pcie apps reset control\n");
 
-		imx6_pcie->phy = devm_phy_get(dev, "pcie-phy");
-		if (IS_ERR(imx6_pcie->phy))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->phy),
-					     "failed to get pcie phy\n");
-
 		break;
 	default:
 		break;
@@ -1457,14 +1462,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	},
 	[IMX8MM] = {
 		.variant = IMX8MM,
-		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
+		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
+			 IMX6_PCIE_FLAG_HAS_PHYDRV |
+			 IMX6_PCIE_FLAG_HAS_APP_RESET,
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 	[IMX8MP] = {
 		.variant = IMX8MP,
-		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
+		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
+			 IMX6_PCIE_FLAG_HAS_PHYDRV,
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
@@ -1478,6 +1486,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	},
 	[IMX8MM_EP] = {
 		.variant = IMX8MM_EP,
+		.flags = IMX6_PCIE_FLAG_HAS_PHYDRV,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
@@ -1485,6 +1494,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	},
 	[IMX8MP_EP] = {
 		.variant = IMX8MP_EP,
+		.flags = IMX6_PCIE_FLAG_HAS_PHYDRV,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:13 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:13 -0500
Subject: [PATCH v11 03/14] PCI: imx6: Simplify reset handling by using by using *_FLAG_HAS_*_RESET
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-4-Frank.Li@nxp.com>

Refactors the reset handling logic in the imx6 PCI driver by adding
IMX6_PCIE_FLAG_HAS_*_RESET bitmask define for drvdata::flags.

The drvdata::flags and a bitmask ensures a cleaner and more scalable
switch-case structure for handling reset.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v4 to v5:
    - Add Mani's Reviewed-by tag
    - Fixed MQ_EP's flags
    
    Chagne from v3 to v4:
    - none
    Change from v2 to v3:
    - add Philipp's Reviewed-by tag
    Change from v1 to v2:
    - remove condition check before reset_control_(de)assert() because it is
      none ops if a NULL pointer pass down.
    - still keep condition check at probe to help identify dts file mismatch
      problem.
    
    Change from v1 to v2:
    - remove condition check before reset_control_(de)assert() because it is
      none ops if a NULL pointer pass down.
    - still keep condition check at probe to help identify dts file mismatch
      problem.

 drivers/pci/controller/dwc/pci-imx6.c | 105 ++++++++++----------------
 1 file changed, 39 insertions(+), 66 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 12a2bc76f0b39..072601591fb4e 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -61,6 +61,8 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE	BIT(1)
 #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND		BIT(2)
 #define IMX6_PCIE_FLAG_HAS_PHYDRV			BIT(3)
+#define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
+#define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
 
 #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
 
@@ -661,18 +663,10 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
 
 static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
 {
+	reset_control_assert(imx6_pcie->pciephy_reset);
+	reset_control_assert(imx6_pcie->apps_reset);
+
 	switch (imx6_pcie->drvdata->variant) {
-	case IMX7D:
-	case IMX8MQ:
-	case IMX8MQ_EP:
-		reset_control_assert(imx6_pcie->pciephy_reset);
-		fallthrough;
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		reset_control_assert(imx6_pcie->apps_reset);
-		break;
 	case IMX6SX:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
@@ -693,6 +687,8 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
 				   IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
 		break;
+	default:
+		break;
 	}
 
 	/* Some boards don't have PCIe reset GPIO. */
@@ -706,14 +702,10 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 	struct dw_pcie *pci = imx6_pcie->pci;
 	struct device *dev = pci->dev;
 
+	reset_control_deassert(imx6_pcie->pciephy_reset);
+
 	switch (imx6_pcie->drvdata->variant) {
-	case IMX8MQ:
-	case IMX8MQ_EP:
-		reset_control_deassert(imx6_pcie->pciephy_reset);
-		break;
 	case IMX7D:
-		reset_control_deassert(imx6_pcie->pciephy_reset);
-
 		/* Workaround for ERR010728, failure of PCI-e PLL VCO to
 		 * oscillate, especially when cold.  This turns off "Duty-cycle
 		 * Corrector" and other mysterious undocumented things.
@@ -745,11 +737,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 
 		usleep_range(200, 500);
 		break;
-	case IMX6Q:		/* Nothing to do */
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
+	default:
 		break;
 	}
 
@@ -796,16 +784,11 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
 				   IMX6Q_GPR12_PCIE_CTL_2,
 				   IMX6Q_GPR12_PCIE_CTL_2);
 		break;
-	case IMX7D:
-	case IMX8MQ:
-	case IMX8MQ_EP:
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		reset_control_deassert(imx6_pcie->apps_reset);
+	default:
 		break;
 	}
+
+	reset_control_deassert(imx6_pcie->apps_reset);
 }
 
 static void imx6_pcie_ltssm_disable(struct device *dev)
@@ -819,16 +802,11 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				   IMX6Q_GPR12_PCIE_CTL_2, 0);
 		break;
-	case IMX7D:
-	case IMX8MQ:
-	case IMX8MQ_EP:
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		reset_control_assert(imx6_pcie->apps_reset);
+	default:
 		break;
 	}
+
+	reset_control_assert(imx6_pcie->apps_reset);
 }
 
 static int imx6_pcie_start_link(struct dw_pcie *pci)
@@ -1288,38 +1266,26 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 					     "failed to get pcie phy\n");
 	}
 
+	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_APP_RESET)) {
+		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev, "apps");
+		if (IS_ERR(imx6_pcie->apps_reset))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
+					     "failed to get pcie apps reset control\n");
+	}
+
+	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_PHY_RESET)) {
+		imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, "pciephy");
+		if (IS_ERR(imx6_pcie->pciephy_reset))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pciephy_reset),
+					     "Failed to get PCIEPHY reset control\n");
+	}
+
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX8MQ:
 	case IMX8MQ_EP:
 	case IMX7D:
 		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
 			imx6_pcie->controller_id = 1;
-
-		imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev,
-									    "pciephy");
-		if (IS_ERR(imx6_pcie->pciephy_reset)) {
-			dev_err(dev, "Failed to get PCIEPHY reset control\n");
-			return PTR_ERR(imx6_pcie->pciephy_reset);
-		}
-
-		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
-									 "apps");
-		if (IS_ERR(imx6_pcie->apps_reset)) {
-			dev_err(dev, "Failed to get PCIE APPS reset control\n");
-			return PTR_ERR(imx6_pcie->apps_reset);
-		}
-		break;
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev,
-									 "apps");
-		if (IS_ERR(imx6_pcie->apps_reset))
-			return dev_err_probe(dev, PTR_ERR(imx6_pcie->apps_reset),
-					     "failed to get pcie apps reset control\n");
-
-		break;
 	default:
 		break;
 	}
@@ -1449,13 +1415,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	},
 	[IMX7D] = {
 		.variant = IMX7D,
-		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
+		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
+			 IMX6_PCIE_FLAG_HAS_APP_RESET |
+			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
 		.gpr = "fsl,imx7d-iomuxc-gpr",
 		.clk_names = imx6q_clks,
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 	},
 	[IMX8MQ] = {
 		.variant = IMX8MQ,
+		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
+			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
 		.clk_names = imx8mq_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
@@ -1472,13 +1442,16 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 	[IMX8MP] = {
 		.variant = IMX8MP,
 		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
-			 IMX6_PCIE_FLAG_HAS_PHYDRV,
+			 IMX6_PCIE_FLAG_HAS_PHYDRV |
+			 IMX6_PCIE_FLAG_HAS_APP_RESET,
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 	},
 	[IMX8MQ_EP] = {
 		.variant = IMX8MQ_EP,
+		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
+			 IMX6_PCIE_FLAG_HAS_PHY_RESET,
 		.mode = DW_PCIE_EP_TYPE,
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
 		.clk_names = imx8mq_clks,
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:14 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:14 -0500
Subject: [PATCH v11 04/14] PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-5-Frank.Li@nxp.com>

Add drvdata::ltssm_off and drvdata::ltssm_mask to simple
imx6_pcie_ltssm_enable(disable)() logic.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8
    - Add Manivannan Sadhasivam's review tag
    Change from v1 to v7
    - none

 drivers/pci/controller/dwc/pci-imx6.c | 37 ++++++++++++---------------
 1 file changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 072601591fb4e..982aa982efd66 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -76,6 +76,8 @@ struct imx6_pcie_drvdata {
 	const char *gpr;
 	const char * const *clk_names;
 	const u32 clks_cnt;
+	const u32 ltssm_off;
+	const u32 ltssm_mask;
 };
 
 struct imx6_pcie {
@@ -775,18 +777,11 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
 static void imx6_pcie_ltssm_enable(struct device *dev)
 {
 	struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
+	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
 
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX6Q:
-	case IMX6SX:
-	case IMX6QP:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX6Q_GPR12_PCIE_CTL_2,
-				   IMX6Q_GPR12_PCIE_CTL_2);
-		break;
-	default:
-		break;
-	}
+	if (drvdata->ltssm_mask)
+		regmap_update_bits(imx6_pcie->iomuxc_gpr, drvdata->ltssm_off, drvdata->ltssm_mask,
+				   drvdata->ltssm_mask);
 
 	reset_control_deassert(imx6_pcie->apps_reset);
 }
@@ -794,17 +789,11 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
 static void imx6_pcie_ltssm_disable(struct device *dev)
 {
 	struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
+	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
 
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX6Q:
-	case IMX6SX:
-	case IMX6QP:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX6Q_GPR12_PCIE_CTL_2, 0);
-		break;
-	default:
-		break;
-	}
+	if (drvdata->ltssm_mask)
+		regmap_update_bits(imx6_pcie->iomuxc_gpr, drvdata->ltssm_off,
+				   drvdata->ltssm_mask, 0);
 
 	reset_control_assert(imx6_pcie->apps_reset);
 }
@@ -1393,6 +1382,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx6q-iomuxc-gpr",
 		.clk_names = imx6q_clks,
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
+		.ltssm_off = IOMUXC_GPR12,
+		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 	},
 	[IMX6SX] = {
 		.variant = IMX6SX,
@@ -1402,6 +1393,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx6q-iomuxc-gpr",
 		.clk_names = imx6sx_clks,
 		.clks_cnt = ARRAY_SIZE(imx6sx_clks),
+		.ltssm_off = IOMUXC_GPR12,
+		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 	},
 	[IMX6QP] = {
 		.variant = IMX6QP,
@@ -1412,6 +1405,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx6q-iomuxc-gpr",
 		.clk_names = imx6q_clks,
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
+		.ltssm_off = IOMUXC_GPR12,
+		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 	},
 	[IMX7D] = {
 		.variant = IMX7D,
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:15 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:15 -0500
Subject: [PATCH v11 05/14] PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-6-Frank.Li@nxp.com>

Add drvdata::mode_off and drvdata::mode_mask to simplify
imx6_pcie_configure_type() logic.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Chagne from v8 to v9
    - add Manivannan's review tag
    Change from v7 to v8
    - replace simple with simplify
    - remove reduntant comments about FILED_PREP
    Change from v3 to v7
    - none
    Change from v2 to v3
    - none
    Change from v1 to v2
    - use ffs() to fixe build error.
    
    Change from v2 to v3
    - none
    Change from v1 to v2
    - use ffs() to fixe build error.

 drivers/pci/controller/dwc/pci-imx6.c | 59 ++++++++++++++++++---------
 1 file changed, 39 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 982aa982efd66..6dcff345939e9 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -68,6 +68,7 @@ enum imx6_pcie_variants {
 
 #define IMX6_PCIE_MAX_CLKS       6
 
+#define IMX6_PCIE_MAX_INSTANCES			2
 struct imx6_pcie_drvdata {
 	enum imx6_pcie_variants variant;
 	enum dw_pcie_device_mode mode;
@@ -78,6 +79,8 @@ struct imx6_pcie_drvdata {
 	const u32 clks_cnt;
 	const u32 ltssm_off;
 	const u32 ltssm_mask;
+	const u32 mode_off[IMX6_PCIE_MAX_INSTANCES];
+	const u32 mode_mask[IMX6_PCIE_MAX_INSTANCES];
 };
 
 struct imx6_pcie {
@@ -174,32 +177,24 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
 
 static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
 {
-	unsigned int mask, val, mode;
+	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
+	unsigned int mask, val, mode, id;
 
-	if (imx6_pcie->drvdata->mode == DW_PCIE_EP_TYPE)
+	if (drvdata->mode == DW_PCIE_EP_TYPE)
 		mode = PCI_EXP_TYPE_ENDPOINT;
 	else
 		mode = PCI_EXP_TYPE_ROOT_PORT;
 
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX8MQ:
-	case IMX8MQ_EP:
-		if (imx6_pcie->controller_id == 1) {
-			mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE;
-			val  = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
-					  mode);
-		} else {
-			mask = IMX6Q_GPR12_DEVICE_TYPE;
-			val  = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode);
-		}
-		break;
-	default:
-		mask = IMX6Q_GPR12_DEVICE_TYPE;
-		val  = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode);
-		break;
-	}
+	id = imx6_pcie->controller_id;
+
+	/* If mode_mask[id] is zero, means each controller have its individual gpr */
+	if (!drvdata->mode_mask[id])
+		id = 0;
+
+	mask = drvdata->mode_mask[id];
+	val = mode << (ffs(mask) - 1);
 
-	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, mask, val);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, drvdata->mode_off[id], mask, val);
 }
 
 static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, bool exp_val)
@@ -1384,6 +1379,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 		.ltssm_off = IOMUXC_GPR12,
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX6SX] = {
 		.variant = IMX6SX,
@@ -1395,6 +1392,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx6sx_clks),
 		.ltssm_off = IOMUXC_GPR12,
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX6QP] = {
 		.variant = IMX6QP,
@@ -1407,6 +1406,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 		.ltssm_off = IOMUXC_GPR12,
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX7D] = {
 		.variant = IMX7D,
@@ -1416,6 +1417,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx7d-iomuxc-gpr",
 		.clk_names = imx6q_clks,
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX8MQ] = {
 		.variant = IMX8MQ,
@@ -1424,6 +1427,10 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
 		.clk_names = imx8mq_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.mode_off[1] = IOMUXC_GPR12,
+		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
 	},
 	[IMX8MM] = {
 		.variant = IMX8MM,
@@ -1433,6 +1440,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX8MP] = {
 		.variant = IMX8MP,
@@ -1442,6 +1451,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX8MQ_EP] = {
 		.variant = IMX8MQ_EP,
@@ -1451,6 +1462,10 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mq-iomuxc-gpr",
 		.clk_names = imx8mq_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.mode_off[1] = IOMUXC_GPR12,
+		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
 	},
 	[IMX8MM_EP] = {
 		.variant = IMX8MM_EP,
@@ -1459,6 +1474,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mm-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 	[IMX8MP_EP] = {
 		.variant = IMX8MP_EP,
@@ -1467,6 +1484,8 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.gpr = "fsl,imx8mp-iomuxc-gpr",
 		.clk_names = imx8mm_clks,
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
+		.mode_off[0] = IOMUXC_GPR12,
+		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
 };
 
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:16 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:16 -0500
Subject: [PATCH v11 06/14] PCI: imx6: Simplify switch-case logic by involve init_phy callback
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-7-Frank.Li@nxp.com>

Instead of using the switch case statement to initialize the PHY handled by
this driver itself, let's introduce a new callback init_phy() and define it
for platforms that require it. This simplifies the code.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8:
    - rework commit message
    - wrap comments to 100 chars
    - return 0 at imx7d_pcie_init_phy()
    
    change from v1 to v4:
    - none

 drivers/pci/controller/dwc/pci-imx6.c | 134 +++++++++++++-------------
 1 file changed, 69 insertions(+), 65 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 6dcff345939e9..71ce6b7ac1de0 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -69,6 +69,9 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_MAX_CLKS       6
 
 #define IMX6_PCIE_MAX_INSTANCES			2
+
+struct imx6_pcie;
+
 struct imx6_pcie_drvdata {
 	enum imx6_pcie_variants variant;
 	enum dw_pcie_device_mode mode;
@@ -81,6 +84,7 @@ struct imx6_pcie_drvdata {
 	const u32 ltssm_mask;
 	const u32 mode_off[IMX6_PCIE_MAX_INSTANCES];
 	const u32 mode_mask[IMX6_PCIE_MAX_INSTANCES];
+	int (*init_phy)(struct imx6_pcie *pcie);
 };
 
 struct imx6_pcie {
@@ -322,76 +326,66 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data)
 	return 0;
 }
 
-static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+static int imx8mq_pcie_init_phy(struct imx6_pcie *imx6_pcie)
 {
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX8MM:
-	case IMX8MM_EP:
-	case IMX8MP:
-	case IMX8MP_EP:
-		/*
-		 * The PHY initialization had been done in the PHY
-		 * driver, break here directly.
-		 */
-		break;
-	case IMX8MQ:
-	case IMX8MQ_EP:
-		/*
-		 * TODO: Currently this code assumes external
-		 * oscillator is being used
-		 */
+	/* TODO: Currently this code assumes external oscillator is being used */
+	regmap_update_bits(imx6_pcie->iomuxc_gpr,
+			   imx6_pcie_grp_offset(imx6_pcie),
+			   IMX8MQ_GPR_PCIE_REF_USE_PAD,
+			   IMX8MQ_GPR_PCIE_REF_USE_PAD);
+	/*
+	 * Regarding the datasheet, the PCIE_VPH is suggested to be 1.8V. If the PCIE_VPH is
+	 * supplied by 3.3V, the VREG_BYPASS should be cleared to zero.
+	 */
+	if (imx6_pcie->vph && regulator_get_voltage(imx6_pcie->vph) > 3000000)
 		regmap_update_bits(imx6_pcie->iomuxc_gpr,
 				   imx6_pcie_grp_offset(imx6_pcie),
-				   IMX8MQ_GPR_PCIE_REF_USE_PAD,
-				   IMX8MQ_GPR_PCIE_REF_USE_PAD);
-		/*
-		 * Regarding the datasheet, the PCIE_VPH is suggested
-		 * to be 1.8V. If the PCIE_VPH is supplied by 3.3V, the
-		 * VREG_BYPASS should be cleared to zero.
-		 */
-		if (imx6_pcie->vph &&
-		    regulator_get_voltage(imx6_pcie->vph) > 3000000)
-			regmap_update_bits(imx6_pcie->iomuxc_gpr,
-					   imx6_pcie_grp_offset(imx6_pcie),
-					   IMX8MQ_GPR_PCIE_VREG_BYPASS,
-					   0);
-		break;
-	case IMX7D:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
-		break;
-	case IMX6SX:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX6SX_GPR12_PCIE_RX_EQ_MASK,
-				   IMX6SX_GPR12_PCIE_RX_EQ_2);
-		fallthrough;
-	default:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+				   IMX8MQ_GPR_PCIE_VREG_BYPASS,
+				   0);
+
+	return 0;
+}
+
+static int imx7d_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+{
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
+
+	return 0;
+}
+
+static int imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+{
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				   IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
 
-		/* configure constant input signal to the pcie ctrl and phy */
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
-
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
-				   IMX6Q_GPR8_TX_DEEMPH_GEN1,
-				   imx6_pcie->tx_deemph_gen1 << 0);
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
-				   IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB,
-				   imx6_pcie->tx_deemph_gen2_3p5db << 6);
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
-				   IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB,
-				   imx6_pcie->tx_deemph_gen2_6db << 12);
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
-				   IMX6Q_GPR8_TX_SWING_FULL,
-				   imx6_pcie->tx_swing_full << 18);
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
-				   IMX6Q_GPR8_TX_SWING_LOW,
-				   imx6_pcie->tx_swing_low << 25);
-		break;
-	}
+	/* configure constant input signal to the pcie ctrl and phy */
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+			   IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
+
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+			   IMX6Q_GPR8_TX_DEEMPH_GEN1,
+			   imx6_pcie->tx_deemph_gen1 << 0);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+			   IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB,
+			   imx6_pcie->tx_deemph_gen2_3p5db << 6);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+			   IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB,
+			   imx6_pcie->tx_deemph_gen2_6db << 12);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+			   IMX6Q_GPR8_TX_SWING_FULL,
+			   imx6_pcie->tx_swing_full << 18);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
+			   IMX6Q_GPR8_TX_SWING_LOW,
+			   imx6_pcie->tx_swing_low << 25);
+	return 0;
+}
 
-	imx6_pcie_configure_type(imx6_pcie);
+static int imx6sx_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+{
+	regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+			   IMX6SX_GPR12_PCIE_RX_EQ_MASK, IMX6SX_GPR12_PCIE_RX_EQ_2);
+
+	return imx6_pcie_init_phy(imx6_pcie);
 }
 
 static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
@@ -902,7 +896,11 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
 	}
 
 	imx6_pcie_assert_core_reset(imx6_pcie);
-	imx6_pcie_init_phy(imx6_pcie);
+
+	if (imx6_pcie->drvdata->init_phy)
+		imx6_pcie->drvdata->init_phy(imx6_pcie);
+
+	imx6_pcie_configure_type(imx6_pcie);
 
 	ret = imx6_pcie_clk_enable(imx6_pcie);
 	if (ret) {
@@ -1381,6 +1379,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.init_phy = imx6_pcie_init_phy,
 	},
 	[IMX6SX] = {
 		.variant = IMX6SX,
@@ -1394,6 +1393,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.init_phy = imx6sx_pcie_init_phy,
 	},
 	[IMX6QP] = {
 		.variant = IMX6QP,
@@ -1408,6 +1408,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.init_phy = imx6_pcie_init_phy,
 	},
 	[IMX7D] = {
 		.variant = IMX7D,
@@ -1419,6 +1420,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx6q_clks),
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.init_phy = imx7d_pcie_init_phy,
 	},
 	[IMX8MQ] = {
 		.variant = IMX8MQ,
@@ -1431,6 +1433,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 		.mode_off[1] = IOMUXC_GPR12,
 		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
+		.init_phy = imx8mq_pcie_init_phy,
 	},
 	[IMX8MM] = {
 		.variant = IMX8MM,
@@ -1466,6 +1469,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 		.mode_off[1] = IOMUXC_GPR12,
 		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
+		.init_phy = imx8mq_pcie_init_phy,
 	},
 	[IMX8MM_EP] = {
 		.variant = IMX8MM_EP,
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:17 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:17 -0500
Subject: [PATCH v11 07/14] dt-bindings: imx6q-pcie: Clean up irrationality clocks check
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-8-Frank.Li@nxp.com>

The bindings referencing this file already define these constraints for
each of the variants, so the if not: then: is redundant.

Acked-by: Rob Herring <robh at kernel.org>
Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8
    - add Manivannan Sadhasiva's Ack tag
    Change from v6 to v7
    - rewrite git commit message by using simple words
    Change from v5 to v6
    - rewrite git commit message and explain why remove it safely.
    - Add Rob's Ack
    Change from v1 to v4
    - new patch at v4

 .../bindings/pci/fsl,imx6q-pcie-common.yaml      | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
index d91b639ae7ae7..0c50487a3866d 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
@@ -150,22 +150,6 @@ allOf:
             - {}
             - const: pcie_phy
             - const: pcie_aux
-  - if:
-      properties:
-        compatible:
-          not:
-            contains:
-              enum:
-                - fsl,imx6sx-pcie
-                - fsl,imx8mq-pcie
-                - fsl,imx6sx-pcie-ep
-                - fsl,imx8mq-pcie-ep
-    then:
-      properties:
-        clocks:
-          maxItems: 3
-        clock-names:
-          maxItems: 3
 
   - if:
       properties:
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:18 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:18 -0500
Subject: [PATCH v11 08/14] dt-bindings: imx6q-pcie: Restruct reg and reg-name
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-9-Frank.Li@nxp.com>

snps,dw-pcie.yaml already have reg and reg-name information. Needn't
duplciate here.

Add 'if' check for existed compatible string to restrict reg and reg-names.
This prepare to add new compatible string with difference reg-names sets.

Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8
    - Add Manivannan Sadhasivam's ACK tag
    Change from v6 to v7
    - add Krzysztof's review tag
    Change from v5 to v6
    - Add if check for existed compatible string
    Change from v4 to v5
    - add Rob's Acked
    Change from v1 to v4:
    - new patch at v4

 .../bindings/pci/fsl,imx6q-pcie.yaml          | 30 ++++++++++++-------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
index 81bbb8728f0f9..eeca6b7b540f9 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -30,16 +30,6 @@ properties:
       - fsl,imx8mm-pcie
       - fsl,imx8mp-pcie
 
-  reg:
-    items:
-      - description: Data Bus Interface (DBI) registers.
-      - description: PCIe configuration space region.
-
-  reg-names:
-    items:
-      - const: dbi
-      - const: config
-
   clocks:
     minItems: 3
     items:
@@ -90,6 +80,26 @@ required:
 allOf:
   - $ref: /schemas/pci/snps,dw-pcie.yaml#
   - $ref: /schemas/pci/fsl,imx6q-pcie-common.yaml#
+  - if:
+      properties:
+        compatible:
+          enum:
+            - fsl,imx6q-pcie
+            - fsl,imx6sx-pcie
+            - fsl,imx6qp-pcie
+            - fsl,imx7d-pcie
+            - fsl,imx8mq-pcie
+            - fsl,imx8mm-pcie
+            - fsl,imx8mp-pcie
+    then:
+      properties:
+        reg:
+          maxItems: 2
+        reg-names:
+          items:
+            - const: dbi
+            - const: config
+
   - if:
       properties:
         compatible:
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:19 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:19 -0500
Subject: [PATCH v11 09/14] dt-bindings: imx6q-pcie: Add imx95 pcie compatible string
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-10-Frank.Li@nxp.com>

From: Richard Zhu <hongxing.zhu at nxp.com>

Add i.MX95 PCIe "fsl,imx95-pcie" compatible string.
Add "atu" and "app" to reg-names.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v8 to v9
    - Added rob's review tag
    Change from v7 to v8
    -none
    Change from v6 to v7
    - Added my sign off
    
    Change from v5 to v6
    - move atu and app after config
    
    Change from v2 to v3
    - Remove krzy's ACK tag
    - Add condition check for imx95, which required more reg-names then old
    platform, so need Krzy review again,
    
    Change from v1 to v2
    - add Krzy's ACK tag

 .../bindings/pci/fsl,imx6q-pcie-common.yaml   |  1 +
 .../bindings/pci/fsl,imx6q-pcie.yaml          | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
index 0c50487a3866d..a8b34f58f8f49 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
@@ -207,6 +207,7 @@ allOf:
                 - fsl,imx6sx-pcie
                 - fsl,imx6q-pcie
                 - fsl,imx6qp-pcie
+                - fsl,imx95-pcie
                 - fsl,imx6sx-pcie-ep
                 - fsl,imx6q-pcie-ep
                 - fsl,imx6qp-pcie-ep
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
index eeca6b7b540f9..8b8d77b1154b5 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -29,6 +29,7 @@ properties:
       - fsl,imx8mq-pcie
       - fsl,imx8mm-pcie
       - fsl,imx8mp-pcie
+      - fsl,imx95-pcie
 
   clocks:
     minItems: 3
@@ -100,6 +101,23 @@ allOf:
             - const: dbi
             - const: config
 
+  - if:
+      properties:
+        compatible:
+          enum:
+            - fsl,imx95-pcie
+    then:
+      properties:
+        reg:
+          minItems: 4
+          maxItems: 4
+        reg-names:
+          items:
+            - const: dbi
+            - const: config
+            - const: atu
+            - const: app
+
   - if:
       properties:
         compatible:
@@ -121,6 +139,7 @@ allOf:
         compatible:
           enum:
             - fsl,imx8mq-pcie
+            - fsl,imx95-pcie
     then:
       properties:
         clocks:
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:20 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:20 -0500
Subject: [PATCH v11 10/14] PCI: imx6: Add iMX95 PCIe Root Complex support
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-11-Frank.Li@nxp.com>

Add iMX95 PCIe Root Complex support.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v8 to v9
    - Add mani's review tag
    
    Change from v7 to v8
    - Update commit subject
    - add const from regmap
    - remove unnessary logic in imx6_pcie_deassert_core_reset()
    
    Change from v4 to v7
    - none
    Change from v1 to v3
    - none

 drivers/pci/controller/dwc/pci-imx6.c | 82 +++++++++++++++++++++++++--
 1 file changed, 77 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 71ce6b7ac1de0..582ba00d628a1 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -42,6 +42,25 @@
 #define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE	GENMASK(11, 8)
 #define IMX8MQ_PCIE2_BASE_ADDR			0x33c00000
 
+#define IMX95_PCIE_PHY_GEN_CTRL			0x0
+#define IMX95_PCIE_REF_USE_PAD			BIT(17)
+
+#define IMX95_PCIE_PHY_MPLLA_CTRL		0x10
+#define IMX95_PCIE_PHY_MPLL_STATE		BIT(30)
+
+#define IMX95_PCIE_SS_RW_REG_0			0xf0
+#define IMX95_PCIE_REF_CLKEN			BIT(23)
+#define IMX95_PCIE_PHY_CR_PARA_SEL		BIT(9)
+
+#define IMX95_PE0_GEN_CTRL_1			0x1050
+#define IMX95_PCIE_DEVICE_TYPE			GENMASK(3, 0)
+
+#define IMX95_PE0_GEN_CTRL_3			0x1058
+#define IMX95_PCIE_LTSSM_EN			BIT(0)
+
+#define IMX95_PE0_PM_STS			0x1064
+#define IMX95_PCIE_PM_LINKST_IN_L2		BIT(14)
+
 #define to_imx6_pcie(x)	dev_get_drvdata((x)->dev)
 
 enum imx6_pcie_variants {
@@ -52,6 +71,7 @@ enum imx6_pcie_variants {
 	IMX8MQ,
 	IMX8MM,
 	IMX8MP,
+	IMX95,
 	IMX8MQ_EP,
 	IMX8MM_EP,
 	IMX8MP_EP,
@@ -63,6 +83,7 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_FLAG_HAS_PHYDRV			BIT(3)
 #define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
 #define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
+#define IMX6_PCIE_FLAG_HAS_SERDES		BIT(6)
 
 #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
 
@@ -179,6 +200,24 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
 	return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
 }
 
+static int imx95_pcie_init_phy(struct imx6_pcie *imx6_pcie)
+{
+	regmap_update_bits(imx6_pcie->iomuxc_gpr,
+			IMX95_PCIE_SS_RW_REG_0,
+			IMX95_PCIE_PHY_CR_PARA_SEL,
+			IMX95_PCIE_PHY_CR_PARA_SEL);
+
+	regmap_update_bits(imx6_pcie->iomuxc_gpr,
+			   IMX95_PCIE_PHY_GEN_CTRL,
+			   IMX95_PCIE_REF_USE_PAD, 0);
+	regmap_update_bits(imx6_pcie->iomuxc_gpr,
+			   IMX95_PCIE_SS_RW_REG_0,
+			   IMX95_PCIE_REF_CLKEN,
+			   IMX95_PCIE_REF_CLKEN);
+
+	return 0;
+}
+
 static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
 {
 	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
@@ -575,6 +614,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 				   IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
 		break;
 	case IMX7D:
+	case IMX95:
 		break;
 	case IMX8MM:
 	case IMX8MM_EP:
@@ -1279,12 +1319,32 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 		return PTR_ERR(imx6_pcie->turnoff_reset);
 	}
 
+	if (imx6_pcie->drvdata->gpr) {
 	/* Grab GPR config register range */
-	imx6_pcie->iomuxc_gpr =
-		 syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
-	if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
-		dev_err(dev, "unable to find iomuxc registers\n");
-		return PTR_ERR(imx6_pcie->iomuxc_gpr);
+		imx6_pcie->iomuxc_gpr =
+			 syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
+		if (IS_ERR(imx6_pcie->iomuxc_gpr))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
+					     "unable to find iomuxc registers\n");
+	}
+
+	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_SERDES)) {
+		void __iomem *off = devm_platform_ioremap_resource_byname(pdev, "app");
+
+		if (IS_ERR(off))
+			return dev_err_probe(dev, PTR_ERR(off),
+					     "unable to find serdes registers\n");
+
+		static const struct regmap_config regmap_config = {
+			.reg_bits = 32,
+			.val_bits = 32,
+			.reg_stride = 4,
+		};
+
+		imx6_pcie->iomuxc_gpr = devm_regmap_init_mmio(dev, off, &regmap_config);
+		if (IS_ERR(imx6_pcie->iomuxc_gpr))
+			return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
+					     "unable to find iomuxc registers\n");
 	}
 
 	/* Grab PCIe PHY Tx Settings */
@@ -1457,6 +1517,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 	},
+	[IMX95] = {
+		.variant = IMX95,
+		.flags = IMX6_PCIE_FLAG_HAS_SERDES,
+		.clk_names = imx8mq_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
+		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
+		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
+		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
+		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
+		.init_phy = imx95_pcie_init_phy,
+	},
 	[IMX8MQ_EP] = {
 		.variant = IMX8MQ_EP,
 		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
@@ -1501,6 +1572,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
 	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
 	{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
 	{ .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], },
+	{ .compatible = "fsl,imx95-pcie", .data = &drvdata[IMX95], },
 	{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
 	{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
 	{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:21 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:21 -0500
Subject: [PATCH v11 11/14] PCI: imx6: Clean up get addr_space code
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-12-Frank.Li@nxp.com>

Since the dw_pcie_ep_init() function is already fetching the 'addr_space'
region, no need to do the same in this driver.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8
    - update commit message
    - Add Manivannan Sadhasivam's review tag
    Change from v4 to v7
    - none
    Change from v1 to v3
    - new patches

 drivers/pci/controller/dwc/pci-imx6.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 582ba00d628a1..3009c3ffa1415 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1068,7 +1068,6 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
 	int ret;
 	unsigned int pcie_dbi2_offset;
 	struct dw_pcie_ep *ep;
-	struct resource *res;
 	struct dw_pcie *pci = imx6_pcie->pci;
 	struct dw_pcie_rp *pp = &pci->pp;
 	struct device *dev = pci->dev;
@@ -1087,14 +1086,8 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
 		pcie_dbi2_offset = SZ_4K;
 		break;
 	}
-	pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset;
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
-	if (!res)
-		return -EINVAL;
 
-	ep->phys_base = res->start;
-	ep->addr_size = resource_size(res);
-	ep->page_size = SZ_64K;
+	pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset;
 
 	ret = dw_pcie_ep_init(ep);
 	if (ret) {
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:22 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:22 -0500
Subject: [PATCH v11 12/14] PCI: imx6: Add epc_features in imx6_pcie_drvdata
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-13-Frank.Li@nxp.com>

The i.MX EP exhibits variations in epc_features among different EP
configurations. This introduces the addition of epc_features in
imx6_pcie_drvdata to accommodate these differences. It's important to note
that there are no functional changes in this commit; instead, it lays the
groundwork for supporting i.MX95 EP functions.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v7 to v8
    - Added  Manivannan Sadhasivam's review tag
    Change from v6 to v7
    - none
    Change from v5 to v6
    - add missed maxitems.
    - add comments about reuse linux,pci-domain as controller id.
    linux,pci-domain have not defined at PCI endpoint side.
    
    Change from v1 to v3
    - new patch at v3

 drivers/pci/controller/dwc/pci-imx6.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 3009c3ffa1415..b714edac6d566 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -105,6 +105,7 @@ struct imx6_pcie_drvdata {
 	const u32 ltssm_mask;
 	const u32 mode_off[IMX6_PCIE_MAX_INSTANCES];
 	const u32 mode_mask[IMX6_PCIE_MAX_INSTANCES];
+	const struct pci_epc_features *epc_features;
 	int (*init_phy)(struct imx6_pcie *pcie);
 };
 
@@ -1053,7 +1054,10 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
 static const struct pci_epc_features*
 imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
 {
-	return &imx8m_pcie_epc_features;
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+
+	return imx6_pcie->drvdata->epc_features;
 }
 
 static const struct dw_pcie_ep_ops pcie_ep_ops = {
@@ -1533,6 +1537,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 		.mode_off[1] = IOMUXC_GPR12,
 		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
+		.epc_features = &imx8m_pcie_epc_features,
 		.init_phy = imx8mq_pcie_init_phy,
 	},
 	[IMX8MM_EP] = {
@@ -1544,6 +1549,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.epc_features = &imx8m_pcie_epc_features,
 	},
 	[IMX8MP_EP] = {
 		.variant = IMX8MP_EP,
@@ -1554,6 +1560,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.clks_cnt = ARRAY_SIZE(imx8mm_clks),
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+		.epc_features = &imx8m_pcie_epc_features,
 	},
 };
 
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:23 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:23 -0500
Subject: [PATCH v11 13/14] dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-14-Frank.Li@nxp.com>

Add i.MX95 PCIe "fsl,imx95-pcie-ep" compatible string.
Add reg-name: "atu", "dbi2", "dma" and "app".

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v9 to v10
    - remove "pci-domain" part
    Change from v8 to v9
    - add rob's review tag
    Change from v3 to v8
    - none
    Change from v1 to v3
    - new patches at v3

 .../bindings/pci/fsl,imx6q-pcie-ep.yaml       | 46 +++++++++++++++----
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
index ee155ed5f1811..a06f75df8458a 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
@@ -22,14 +22,7 @@ properties:
       - fsl,imx8mm-pcie-ep
       - fsl,imx8mq-pcie-ep
       - fsl,imx8mp-pcie-ep
-
-  reg:
-    minItems: 2
-
-  reg-names:
-    items:
-      - const: dbi
-      - const: addr_space
+      - fsl,imx95-pcie-ep
 
   clocks:
     minItems: 3
@@ -62,11 +55,48 @@ required:
 allOf:
   - $ref: /schemas/pci/snps,dw-pcie-ep.yaml#
   - $ref: /schemas/pci/fsl,imx6q-pcie-common.yaml#
+  - if:
+      properties:
+        compatible:
+          enum:
+            - fsl,imx8mm-pcie-ep
+            - fsl,imx8mq-pcie-ep
+            - fsl,imx8mp-pcie-ep
+    then:
+      properties:
+        reg:
+          minItems: 2
+          maxItems: 2
+        reg-names:
+          items:
+            - const: dbi
+            - const: addr_space
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - fsl,imx95-pcie-ep
+    then:
+      properties:
+        reg:
+          minItems: 6
+          maxItems: 6
+        reg-names:
+          items:
+            - const: dbi
+            - const: atu
+            - const: dbi2
+            - const: app
+            - const: dma
+            - const: addr_space
+
   - if:
       properties:
         compatible:
           enum:
             - fsl,imx8mq-pcie-ep
+            - fsl,imx95-pcie-ep
     then:
       properties:
         clocks:
-- 
2.34.1



From Frank.Li at nxp.com  Tue Feb 20 08:19:24 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:19:24 -0500
Subject: [PATCH v11 14/14] PCI: imx6: Add iMX95 Endpoint (EP) support
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <20240220161924.3871774-15-Frank.Li@nxp.com>

Add iMX95 EP support and add 64bit address support. Internal bus bridge for
PCI support 64bit dma address in iMX95. Hence, call
dma_set_mask_and_coherent() to set 64 bit DMA mask.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---

Notes:
    Change from v10 to v11
    - rebase to linux-pci/endpoint.
    - move dma_set_mask_and_coherent() to imx6_add_pcie_ep() according to Robin
    Murphy's suggestion.
    
    Change from v9 to v10
    - using if (device_property_match_string(dev, "reg-names", "dbi2")) instead of
    	if (imx6_pcie->drvdata->variant == IMX95_EP)
    - so other platform can stat use "dbi2" in dts.
    
    @Mani: I change to check device_property_match_string(), so I can update
    other platform dts file, It should be better than
    	imx6_pcie->drvdata->variant == IMX95_EP
    
    Change from v8 to v9
    - update fixme comments
    - update BAR1 comments
    - Add mani's review tag
    Change from v7 to v8
    - Update commit message
    - Using Fixme
    - Update clks_cnts by ARRAY_SIZE
    
    Change from v4 to v7
    - none
    Change from v3 to v4
    - change align to 4k for imx95
    Change from v1 to v3
    - new patches at v3

 drivers/pci/controller/dwc/pci-imx6.c | 47 +++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index b714edac6d566..9c2ad803e1dbd 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -75,6 +75,7 @@ enum imx6_pcie_variants {
 	IMX8MQ_EP,
 	IMX8MM_EP,
 	IMX8MP_EP,
+	IMX95_EP,
 };
 
 #define IMX6_PCIE_FLAG_IMX6_PHY			BIT(0)
@@ -84,6 +85,7 @@ enum imx6_pcie_variants {
 #define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
 #define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
 #define IMX6_PCIE_FLAG_HAS_SERDES		BIT(6)
+#define IMX6_PCIE_FLAG_SUPPORT_64BIT		BIT(7)
 
 #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
 
@@ -616,6 +618,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 		break;
 	case IMX7D:
 	case IMX95:
+	case IMX95_EP:
 		break;
 	case IMX8MM:
 	case IMX8MM_EP:
@@ -1051,6 +1054,23 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
 	.align = SZ_64K,
 };
 
+/*
+ * BAR#	| Default BAR enable	| Default BAR Type	| Default BAR Size	| BAR Sizing Scheme
+ * ================================================================================================
+ * BAR0	| Enable		| 64-bit		| 1 MB			| Programmable Size
+ * BAR1	| Disable		| 32-bit		| 64 KB			| Fixed Size
+ *        BAR1 should be disabled if BAR0 is 64bit.
+ * BAR2	| Enable		| 32-bit		| 1 MB			| Programmable Size
+ * BAR3	| Enable		| 32-bit		| 64 KB			| Programmable Size
+ * BAR4	| Enable		| 32-bit		| 1M			| Programmable Size
+ * BAR5	| Enable		| 32-bit		| 64 KB			| Programmable Size
+ */
+static const struct pci_epc_features imx95_pcie_epc_features = {
+	.msi_capable = true,
+	.bar[BAR_1] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
+	.align = SZ_4K,
+};
+
 static const struct pci_epc_features*
 imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
 {
@@ -1093,6 +1113,18 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
 
 	pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset;
 
+	/*
+	 * FIXME: Ideally, dbi2 base address should come from DT. But since only IMX95 is defining
+	 * "dbi2" in DT, "dbi_base2" is set to NULL here for that platform alone so that the DWC
+	 * core code can fetch that from DT. But once all platform DTs were fixed, this and the
+	 * above "dbi_base2" setting should be removed.
+	 */
+	if (device_property_match_string(dev, "reg-names", "dbi2") >= 0)
+		pci->dbi_base2 = NULL;
+
+	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_SUPPORT_64BIT))
+		dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+
 	ret = dw_pcie_ep_init(ep);
 	if (ret) {
 		dev_err(dev, "failed to initialize endpoint\n");
@@ -1562,6 +1594,20 @@ static const struct imx6_pcie_drvdata drvdata[] = {
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 		.epc_features = &imx8m_pcie_epc_features,
 	},
+	[IMX95_EP] = {
+		.variant = IMX95_EP,
+		.flags = IMX6_PCIE_FLAG_HAS_SERDES |
+			 IMX6_PCIE_FLAG_SUPPORT_64BIT,
+		.clk_names = imx8mq_clks,
+		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
+		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
+		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
+		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
+		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
+		.init_phy = imx95_pcie_init_phy,
+		.epc_features = &imx95_pcie_epc_features,
+		.mode = DW_PCIE_EP_TYPE,
+	},
 };
 
 static const struct of_device_id imx6_pcie_of_match[] = {
@@ -1576,6 +1622,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
 	{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
 	{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
 	{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
+	{ .compatible = "fsl,imx95-pcie-ep", .data = &drvdata[IMX95_EP], },
 	{},
 };
 
-- 
2.34.1



From Frank.li at nxp.com  Tue Feb 20 08:21:28 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 11:21:28 -0500
Subject: [PATCH v10 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <ZdR6EUOv6hzLEmUa@lpieralisi>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>
 <20240219161208.GE3281@thinkpad>
 <ZdN/OyNpw0Xa7qXG@lizhi-Precision-Tower-5810>
 <ZdR2FRQ9Fe8hhK9I@x1-carbon>
 <ZdR6EUOv6hzLEmUa@lpieralisi>
Message-ID: <ZdTRiB9JdQSvBwKn@lizhi-Precision-Tower-5810>

On Tue, Feb 20, 2024 at 11:08:17AM +0100, Lorenzo Pieralisi wrote:
> On Tue, Feb 20, 2024 at 10:51:17AM +0100, Niklas Cassel wrote:
> > On Mon, Feb 19, 2024 at 11:18:03AM -0500, Frank Li wrote:
> > > On Mon, Feb 19, 2024 at 09:42:08PM +0530, Manivannan Sadhasivam wrote:
> > > > On Mon, Feb 19, 2024 at 10:11:45AM -0500, Frank Li wrote:
> > > > > On Mon, Feb 05, 2024 at 12:33:21PM -0500, Frank Li wrote:
> > > > > > first 6 patches use drvdata: flags to simplify some switch-case code.
> > > > > > Improve maintaince and easy to read code.
> > > > > > 
> > > > > 
> > > > > @Lorenzo Pieralisi:
> > > > > 
> > > > > 	Do you have chance to look other patches?
> > > > > 	Mani's apply EP side change. 
> > > > 
> > > > Even though the controller is for the endpoint, it is still a controller
> > > > driver. So all the patches should go through Lorenzo.
> > > > 
> > > > I only merge patches under drivers/pci/endpoint. Hope this clarifies.
> > > 
> > > Sorry. It confused everyone. My means was that Mani applied Niklas Cassel's
> > > patches, which cause my 14th patch build failure.
> > 
> > Hello Frank,
> > 
> > Patch 14, which adds this:
> > 
> > +static const struct pci_epc_features imx95_pcie_epc_features = {
> > +       .msi_capable = true,
> > +       .bar_fixed_size[1] = SZ_64K,
> > +       .align = SZ_4K,
> > +};
> > 
> > 
> > Should, after rebasing on Mani's pci/endpoint branch, instead look like this:
> > 
> > +static const struct pci_epc_features imx95_pcie_epc_features = {
> > +       .msi_capable = true,
> > +       .bar[BAR_1] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
> > +       .align = SZ_4K,
> > +};
> > 
> > 
> > > 
> > > I asked if I need update my 14th patch or applied 1-13 only. 
> > 
> > I see, you want the maintainers to apply 1-13, and simply drop patch 14
> > instead of you sending out a rebased series.
> > 
> > I assume that the maintainers will be fine with your suggested approach.
> 
> If patch 14 has no dependencies on 1-13 yes; if it does we need to
> coordinate the merge between branches in the PCI tree.

Keep it easy. I rebase to linux-pci/endpoint and v11 patch sent out.
https://lore.kernel.org/imx/20240220161924.3871774-1-Frank.Li at nxp.com/T/#t

Frank

> 
> Lorenzo


From Jonathan.Cameron at Huawei.com  Tue Feb 20 08:24:06 2024
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Tue, 20 Feb 2024 16:24:06 +0000
Subject: [PATCH RFC v4 02/15] ACPI: processor: Register all CPUs from
 acpi_processor_get_info()
In-Reply-To: <ZdTBtt0oR6Q1RcAB@shell.armlinux.org.uk>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk>
	<E1rVDmU-0027YP-Jz@rmk-PC.armlinux.org.uk>
	<CAJZ5v0iiJpUWq5GMSnKFWQTzn_bdwoQz9m=hDaXNg4Lj_ePF4g@mail.gmail.com>
	<ZdSMk93c1I6x973h@shell.armlinux.org.uk>
	<ZdTBtt0oR6Q1RcAB@shell.armlinux.org.uk>
Message-ID: <20240220162406.00005b59@Huawei.com>

On Tue, 20 Feb 2024 15:13:58 +0000
"Russell King (Oracle)" <linux at armlinux.org.uk> wrote:

> On Tue, Feb 20, 2024 at 11:27:15AM +0000, Russell King (Oracle) wrote:
> > On Thu, Feb 15, 2024 at 08:22:29PM +0100, Rafael J. Wysocki wrote:  
> > > On Wed, Jan 31, 2024 at 5:50?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:  
> > > > diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> > > > index cf7c1cca69dd..a68c475cdea5 100644
> > > > --- a/drivers/acpi/acpi_processor.c
> > > > +++ b/drivers/acpi/acpi_processor.c
> > > > @@ -314,6 +314,18 @@ static int acpi_processor_get_info(struct acpi_device *device)
> > > >                         cpufreq_add_device("acpi-cpufreq");
> > > >         }
> > > >
> > > > +       /*
> > > > +        * Register CPUs that are present. get_cpu_device() is used to skip
> > > > +        * duplicate CPU descriptions from firmware.
> > > > +        */
> > > > +       if (!invalid_logical_cpuid(pr->id) && cpu_present(pr->id) &&
> > > > +           !get_cpu_device(pr->id)) {
> > > > +               int ret = arch_register_cpu(pr->id);
> > > > +
> > > > +               if (ret)
> > > > +                       return ret;
> > > > +       }
> > > > +
> > > >         /*
> > > >          *  Extra Processor objects may be enumerated on MP systems with
> > > >          *  less than the max # of CPUs. They should be ignored _iff  
> > > 
> > > This is interesting, because right below there is the following code:
> > > 
> > >     if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
> > >         int ret = acpi_processor_hotadd_init(pr);
> > > 
> > >         if (ret)
> > >             return ret;
> > >     }
> > > 
> > > and acpi_processor_hotadd_init() essentially calls arch_register_cpu()
> > > with some extra things around it (more about that below).
> > > 
> > > I do realize that acpi_processor_hotadd_init() is defined under
> > > CONFIG_ACPI_HOTPLUG_CPU, so for the sake of the argument let's
> > > consider an architecture where CONFIG_ACPI_HOTPLUG_CPU is set.
> > > 
> > > So why are the two conditionals that almost contradict each other both
> > > needed?  It looks like the new code could be combined with
> > > acpi_processor_hotadd_init() to do the right thing in all cases.
> > > 
> > > Now, acpi_processor_hotadd_init() does some extra things that look
> > > like they should be done by the new code too.
> > > 
> > > 1. It checks invalid_phys_cpuid() which appears to be a good idea to me.
> > > 
> > > 2. It uses locking around arch_register_cpu() which doesn't seem
> > > unreasonable either.
> > > 
> > > 3. It calls acpi_map_cpu() and I'm not sure why this is not done by
> > > the new code.
> > > 
> > > The only thing that can be dropped from it is the _STA check AFAICS,
> > > because acpi_processor_add() won't even be called if the CPU is not
> > > present (and not enabled after the first patch).
> > > 
> > > So why does the code not do 1 - 3 above?  
> > 
> > Honestly, I'm out of my depth with this and can't answer your
> > questions - and I really don't want to try fiddling with this code
> > because it's just too icky (even in its current form in mainline)
> > to be understandable to anyone who hasn't gained a detailed knowledge
> > of this code.
> > 
> > It's going to require a lot of analysis - how acpi_map_cpuid() behaves
> > in all circumstances, what this means for invalid_logical_cpuid() and
> > invalid_phys_cpuid(), what paths will be taken in each case. This code
> > is already just too hairy for someone who isn't an experienced ACPI
> > hacker to be able to follow and I don't see an obvious way to make it
> > more readable.
> > 
> > James' additions make it even more complex and less readable.  
> 
> As an illustration of the problems I'm having here, I was just writing
> a reply to this with a suggestion of transforming this code ultimately
> to:
> 
> 	if (!get_cpu_device(pr->id)) {
> 		int ret;
> 
> 		if (!invalid_logical_cpuid(pr->id) && cpu_present(pr->id))
> 			ret = acpi_processor_make_enabled(pr);
> 		else
> 			ret = acpi_processor_make_present(pr);
> 
> 		if (ret)
> 			return ret;
> 	}
> 
> (acpi_processor_make_present() would be acpi_processor_hotadd_init()
> and acpi_processor_make_enabled() would be arch_register_cpu() at this
> point.)
> 
> Then I realised that's a bad idea - because we really need to check
> that pr->id is valid before calling get_cpu_device() on it, so this
> won't work. That leaves us with:
> 
> 	int ret;
> 
> 	if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
> 		/* x86 et.al. path */
> 		ret = acpi_processor_make_present(pr);
> 	} else if (!get_cpu_device(pr->id)) {
> 		/* Arm64 path */
> 		ret = acpi_processor_make_enabled(pr);
> 	} else {
> 		ret = 0;
> 	}
> 
> 	if (ret)
> 		return ret;
> 
> Now, the next transformation would be to move !get_cpu_device(pr->id)
> into acpi_processor_make_enabled() which would eliminate one of those
> if() legs.
> 
> Now, if we want to somehow make the call to arch_regster_cpu() common
> in these two paths, the next question is what are the _precise_
> semantics of acpi_map_cpu(), particularly with respect to it
> modifying pr->id. Is it guaranteed to always give the same result
> for the same processor described in ACPI? What acpi_map_cpu() anyway,
> I can find no documentation for it.
> 
> Then there's the question whether calling acpi_unmap_cpu() should be
> done on the failure path if arch_register_cpu() fails, which is done
> for the x86 path but not the Arm64 path. Should it be done for the
> Arm64 path? I've no idea, but as Arm64 doesn't implement either of
> these two functions, I guess they could be stubbed out and thus be
> no-ops - but then we open a hole where if pr->id is invalid, we
> end up passing that invalid value to arch_register_cpu() which I'm
> quite sure will explode with a negative CPU number.
> 
> So, to my mind, what you're effectively asking for is a total rewrite
> of all the code in and called by acpi_processor_get_info()... and that
> is not something I am willing to do (because it's too far outside of
> my knowledge area.)
> 
> As I said in my reply to patch 1, I think your comments on patch 2
> make Arm64 vcpu hotplug unachievable in a reasonable time frame, and
> certainly outside the bounds of what I can do to progress this.
> 
> So, at this point I'm going to stand down from further participation
> with this patch set as I believe I've reached the limit of what I can
> do to progress it.
> 

Thanks for your hard work on this Russell - we have moved forwards.

Short of anyone else stepping up I'll pick this up with
the help of some my colleagues. As such I'm keen on getting patch
1 upstream ASAP so that we can exclude the need for some of the
other workarounds from earlier versions of this series (the ones
dropped before now).

We will need a little time to get up to speed on the current status
and discussion points Russell raises above.

Jonathan




From sabiya.d at mistralsolutions.com  Tue Feb 20 08:25:25 2024
From: sabiya.d at mistralsolutions.com (sabiya.d at mistralsolutions.com)
Date: Tue, 20 Feb 2024 21:55:25 +0530
Subject: [PATCH V3 0/2] Add CAN and OSPI support for AM69-SK platform
Message-ID: <20240220162527.663394-1-sabiya.d@ti.com>

From: Dasnavis Sabiya <sabiya.d at ti.com>

Hi All,

This series adds support for the below interfaces on AM69-SK platform:
-  CAN support on both MCU and MAIN domains
-  OSPI NOR flash support

v3: Changelog:
1) Updated OSPI partition table to increase the tiboot3 partition to 1MB.
2) Rebase the sources to accommodate the latest merge.

v2: Changelog:
1) Removed CAN interface aliasing.
2) Updated bootph property on the leaf nodes.

Link to v1: https://lore.kernel.org/lkml/20240118153524.4135901-1-sabiya.d at ti.com/
Link to v2: https://lore.kernel.org/linux-arm-kernel/20240219111422.171315-1-sabiya.d at ti.com/

Dasnavis Sabiya (2):
  arm64: dts: ti: k3-am69-sk: Enable CAN interfaces for AM69 SK board
  arm64: dts: ti: k3-am69-sk: Add support for OSPI flash

 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 163 ++++++++++++++++++++++++++
 1 file changed, 163 insertions(+)

-- 
2.34.1



From sabiya.d at mistralsolutions.com  Tue Feb 20 08:25:26 2024
From: sabiya.d at mistralsolutions.com (sabiya.d at mistralsolutions.com)
Date: Tue, 20 Feb 2024 21:55:26 +0530
Subject: [PATCH V3 1/2] arm64: dts: ti: k3-am69-sk: Enable CAN interfaces for AM69 SK board
In-Reply-To: <20240220162527.663394-1-sabiya.d@ti.com>
References: <20240220162527.663394-1-sabiya.d@ti.com>
Message-ID: <20240220162527.663394-2-sabiya.d@ti.com>

From: Dasnavis Sabiya <sabiya.d at ti.com>

AM69 SK board has several CAN bus interfaces on both MCU and MAIN domains.
This enables the CAN interfaces on MCU and MAIN domain.

Signed-off-by: Dasnavis Sabiya <sabiya.d at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 82 +++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index aa770e82de27..7afdfbbe956d 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -330,6 +330,30 @@ csi_mux: mux-controller {
 		idle-state = <0>;
 	};
 
+	transceiver1: can-phy0 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver2: can-phy1 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver3: can-phy2 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
+	transceiver4: can-phy3 {
+		compatible = "ti,tcan1042";
+		#phy-cells = <0>;
+		max-bitrate = <5000000>;
+	};
+
 };
 
 &main_pmx0 {
@@ -445,6 +469,21 @@ hdmi_hpd_pins_default: hdmi-hpd-default-pins {
 			J784S4_IOPAD(0x000, PIN_INPUT, 7) /* (AN35) EXTINTN.GPIO0_0 */
 		>;
 	};
+
+	main_mcan6_pins_default: main-mcan6-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x098, PIN_INPUT, 0) /* (AH36) MCAN6_RX */
+			J784S4_IOPAD(0x094, PIN_OUTPUT, 0) /* (AG35) MCAN6_TX */
+		>;
+	};
+
+	main_mcan7_pins_default: main-mcan7-default-pins {
+		pinctrl-single,pins = <
+			J784S4_IOPAD(0x0A0, PIN_INPUT, 0) /* (AD34) MCAN7_RX */
+			J784S4_IOPAD(0x09C, PIN_OUTPUT, 0) /* (AF35) MCAN7_TX */
+		>;
+	};
+
 };
 
 &wkup_pmx2 {
@@ -541,6 +580,21 @@ hdmi_pdn_pins_default: hdmi-pdn-default-pins {
 			J784S4_WKUP_IOPAD(0x090, PIN_INPUT, 7) /* (H37) WKUP_GPIO0_14 */
 		>;
 	};
+
+	mcu_mcan0_pins_default: mcu-mcan0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x054, PIN_INPUT, 0) /* (F38) MCU_MCAN0_RX */
+			J784S4_WKUP_IOPAD(0x050, PIN_OUTPUT, 0) /* (K33) MCU_MCAN0_TX */
+		>;
+	};
+
+	mcu_mcan1_pins_default: mcu-mcan1-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (K36) WKUP_GPIO0_5.MCU_MCAN1_RX */
+			J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0)/* (H35) WKUP_GPIO0_4.MCU_MCAN1_TX */
+		>;
+	};
+
 };
 
 &wkup_pmx3 {
@@ -1040,3 +1094,31 @@ dp0_out: endpoint {
 		};
 	};
 };
+
+&mcu_mcan0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan0_pins_default>;
+	phys = <&transceiver1>;
+};
+
+&mcu_mcan1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_mcan1_pins_default>;
+	phys = <&transceiver2>;
+};
+
+&main_mcan6 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan6_pins_default>;
+	phys = <&transceiver3>;
+};
+
+&main_mcan7 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mcan7_pins_default>;
+	phys = <&transceiver4>;
+};
-- 
2.34.1



From sabiya.d at mistralsolutions.com  Tue Feb 20 08:25:27 2024
From: sabiya.d at mistralsolutions.com (sabiya.d at mistralsolutions.com)
Date: Tue, 20 Feb 2024 21:55:27 +0530
Subject: [PATCH V3 2/2] arm64: dts: ti: k3-am69-sk: Add support for OSPI flash
In-Reply-To: <20240220162527.663394-1-sabiya.d@ti.com>
References: <20240220162527.663394-1-sabiya.d@ti.com>
Message-ID: <20240220162527.663394-3-sabiya.d@ti.com>

From: Dasnavis Sabiya <sabiya.d at ti.com>

AM69 SK has S28HS512T OSPI flash connected to MCU OSPI0.
Enable support for the same. Also describe the partition
information according to the offsets in the bootloader.

Signed-off-by: Dasnavis Sabiya <sabiya.d at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am69-sk.dts | 81 +++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 7afdfbbe956d..50de2a448a3a 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -486,6 +486,25 @@ J784S4_IOPAD(0x09C, PIN_OUTPUT, 0) /* (AF35) MCAN7_TX */
 
 };
 
+&wkup_pmx0 {
+	bootph-all;
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-default-pins {
+		pinctrl-single,pins = <
+			J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (E32) MCU_OSPI0_CLK */
+			J784S4_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (A32) MCU_OSPI0_CSn0 */
+			J784S4_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (B33) MCU_OSPI0_D0 */
+			J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (B32) MCU_OSPI0_D1 */
+			J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (C33) MCU_OSPI0_D2 */
+			J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (C35) MCU_OSPI0_D3 */
+			J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (D33) MCU_OSPI0_D4 */
+			J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D34) MCU_OSPI0_D5 */
+			J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (E34) MCU_OSPI0_D6 */
+			J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (E33) MCU_OSPI0_D7 */
+			J784S4_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (C34) MCU_OSPI0_DQS */
+		>;
+	};
+};
+
 &wkup_pmx2 {
 	bootph-all;
 	pmic_irq_pins_default: pmic-irq-default-pins {
@@ -1122,3 +1141,65 @@ &main_mcan7 {
 	pinctrl-0 = <&main_mcan7_pins_default>;
 	phys = <&transceiver4>;
 };
+
+&ospi0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <4>;
+
+		partitions {
+			bootph-all;
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "ospi.tiboot3";
+				reg = <0x0 0x100000>;
+			};
+
+			partition at 100000 {
+				label = "ospi.tispl";
+				reg = <0x100000 0x200000>;
+			};
+
+			partition at 300000 {
+				label = "ospi.u-boot";
+				reg = <0x300000 0x400000>;
+			};
+
+			partition at 700000 {
+				label = "ospi.env";
+				reg = <0x700000 0x40000>;
+			};
+
+			partition at 740000 {
+				label = "ospi.env.backup";
+				reg = <0x740000 0x40000>;
+			};
+
+			partition at 800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition at 3fc0000 {
+				bootph-pre-ram;
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+};
-- 
2.34.1



From boqun.feng at gmail.com  Tue Feb 20 08:28:18 2024
From: boqun.feng at gmail.com (Boqun Feng)
Date: Tue, 20 Feb 2024 08:28:18 -0800
Subject: [RFC] efi: Add ACPI_MEMORY_NVS into the linear map
In-Reply-To: <CAMj1kXGzaUsgn0DGfy15c+Z5ECNqosjWbci-YZyUTsMWXte21A@mail.gmail.com>
References: <20240215225116.3435953-1-boqun.feng@gmail.com>
 <2024021718-dwindling-oval-8183@gregkh>
 <ZdQmCEepdOE2R7gS@boqun-archlinux>
 <CAMj1kXGzaUsgn0DGfy15c+Z5ECNqosjWbci-YZyUTsMWXte21A@mail.gmail.com>
Message-ID: <ZdTTIo6g8kklEryd@boqun-archlinux>

On Tue, Feb 20, 2024 at 09:27:54AM +0100, Ard Biesheuvel wrote:
> On Tue, 20 Feb 2024 at 05:10, Boqun Feng <boqun.feng at gmail.com> wrote:
> >
> > On Sat, Feb 17, 2024 at 08:49:32AM +0100, Greg KH wrote:
> > > On Thu, Feb 15, 2024 at 02:51:06PM -0800, Boqun Feng wrote:
> > > > Currently ACPI_MEMORY_NVS is omitted from the linear map, which causes
> > > > a trouble with the following firmware memory region setup:
> > > >
> > > >     [..] efi:   0x0000dfd62000-0x0000dfd83fff [ACPI Reclaim|...]
> > > >     [..] efi:   0x0000dfd84000-0x0000dfd87fff [ACPI Mem NVS|...]
> > > >
> > > > , on ARM64 with 64k page size, the whole 0x0000dfd80000-0x0000dfd8ffff
> > > > range will be omitted from the the linear map due to 64k round-up. And
> > > > a page fault happens when trying to access the ACPI_RECLAIM_MEMORY:
> > > >
> > > >     [...] Unable to handle kernel paging request at virtual address ffff0000dfd80000
> > > >
> > > > To fix this, add ACPI_MEMORY_NVS into the linear map.
> > > >
> > > > Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
> > > > Cc: stable at vger.kernel.org # 5.15+
> > >
> > > What commit id does this fix?  Can you include that as well?
> > >
> >
> > It should be 7aff79e297ee ("Drivers: hv: Enable Hyper-V code to be built
> > on ARM64"), but as Ard mentioned earlier, this could be fixed at the VM
> > firmware, and Oliver is working on that. Should the situation change, I
> > will send a V2 with more information and include the commit id.
> >
> 
> The patch as-is is not acceptable to me, so no need to send a v2 just
> to add more information.
> 
> Please consider the fix I proposed for arch_memremap_can_ram_remap()
> if fixing this in the firmware is not feasible.

Got it. Would do if necessary, thanks!

Regards,
Boqun


From dmitry.baryshkov at linaro.org  Tue Feb 20 08:30:19 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 20 Feb 2024 18:30:19 +0200
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk> <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
 <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk> <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>
Message-ID: <CAA8EJppzkuH=YTAHuJ3Og2RLHB93PSas004UDvpqepYbGepVPg@mail.gmail.com>

On Tue, 20 Feb 2024 at 13:16, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> On Mon, Feb 19, 2024 at 8:59?PM Mark Brown <broonie at kernel.org> wrote:
> >
> > On Mon, Feb 19, 2024 at 07:48:20PM +0100, Bartosz Golaszewski wrote:
> > > On Mon, Feb 19, 2024 at 7:03?PM Mark Brown <broonie at kernel.org> wrote:
> > > > On Fri, Feb 16, 2024 at 09:32:06PM +0100, Bartosz Golaszewski wrote:
> >
> > > > > +                     vreg_pmu_aon_0p59: ldo1 {
> > > > > +                             regulator-name = "vreg_pmu_aon_0p59";
> > > > > +                             regulator-min-microvolt = <540000>;
> > > > > +                             regulator-max-microvolt = <840000>;
> > > > > +                     };
> >
> > > > That's a *very* wide voltage range for a supply that's got a name ending
>
> Because it's an error, it should have been 640000. Thanks for spotting it.

According to the datasheet, VDD08_PMU_AON_O goes up to 0.85V then down
to 0.59V, which is the working voltage.

VDD08_PMU_RFA_CMN is normally at 0.8V, but goes to 0.4V during sleep.

>
> > > > in _0_p59 which sounds a lot like it should be fixed at 0.59V.
> > > > Similarly for a bunch of the other supplies, and I'm not seeing any
> > > > evidence that the consumers do any voltage changes here?  There doesn't
> > > > appear to be any logic here, I'm not convinced these are validated or
> > > > safe constraints.
> >
> > > No, the users don't request any regulators (or rather: software
> > > representations thereof) because - as per the cover letter - no
> > > regulators are created by the PMU driver. This is what is physically
> > > on the board - as the schematics and the datasheet define it. I took
> >
> > The above makes no sense.  How can constraints be "what is physically on
> > the board", particularly variable constrants when there isn't even a
> > consumer?  What values are you taking from which documentation?
> >
>
> The operating conditions for PMU outputs. I took them from a
> confidential datasheet. There's a table for input constraints and
> possible output values.
>
> And what do you mean by there not being any consumers? The WLAN and BT
> *are* the consumers.
>
> > The cover letter and binding both claimed (buried after large amounts of
> > changelog) that these PMUs were exposing regulators to consumers and the
> > DTS puports to do exactly that...
> >
>
> Yes, but I'm not sure what the question is.
>
> > > the values from the docs verbatim. In C, we create a power sequencing
> > > provider which doesn't use the regulator framework at all.
> >
> > For something that doesn't use the regulator framework at all what
> > appears to be a provider in patch 16 ("power: pwrseq: add a driver for
> > the QCA6390 PMU module") seems to have a lot of regualtor API calls?
>
> This driver is a power sequencing *provider* but also a regulator
> *consumer*. It gets regulators from the host and exposes a power
> sequencer to *its* consumers (WLAN and BT). On DT it exposes
> regulators (LDO outputs of the PMU) but we don't instantiate them in
> C.
>
> Bart



-- 
With best wishes
Dmitry


From apatel at ventanamicro.com  Tue Feb 20 08:33:31 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 22:03:31 +0530
Subject: [PATCH v13 06/13] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <87a5nvi8dv.ffs@tglx>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-7-apatel@ventanamicro.com> <87a5nvi8dv.ffs@tglx>
Message-ID: <CAK9=C2XQVnoEEzjwnb7ZSM90vbdTU=9yteAYXOhbkSoDcEGnKg@mail.gmail.com>

On Tue, Feb 20, 2024 at 6:45?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> > The RISC-V advanced interrupt architecture (AIA) specification
> > defines a new MSI controller called incoming message signalled
> > interrupt controller (IMSIC) which manages MSI on per-HART (or
> > per-CPU) basis. It also supports IPIs as software injected MSIs.
> > (For more details refer https://github.com/riscv/riscv-aia)
> >
> > Let us add an early irqchip driver for RISC-V IMSIC which sets
> > up the IMSIC state and provide IPIs.
>
> s/Let us add/Add/

Okay, I will update.

>
> > +#else
> > +static void imsic_ipi_starting_cpu(void)
> > +{
> > +}
> > +
> > +static void imsic_ipi_dying_cpu(void)
> > +{
> > +}
> > +
> > +static int __init imsic_ipi_domain_init(void)
> > +{
> > +     return 0;
> > +}
>
> Please condense this into
>
> static void imsic_ipi_starting_cpu(void) { }
> static void imsic_ipi_dying_cpu(void) { }
> static int __init imsic_ipi_domain_init(void) { return 0; }
>
> No point in wasting space for these stubs.

Sure, I will update.

>
> > + * To handle an interrupt, we read the TOPEI CSR and write zero in one
> > + * instruction. If TOPEI CSR is non-zero then we translate TOPEI.ID to
> > + * Linux interrupt number and let Linux IRQ subsystem handle it.
> > + */
> > +static void imsic_handle_irq(struct irq_desc *desc)
> > +{
> > +     struct irq_chip *chip = irq_desc_get_chip(desc);
> > +     int err, cpu = smp_processor_id();
> > +     struct imsic_vector *vec;
> > +     unsigned long local_id;
> > +
> > +     chained_irq_enter(chip, desc);
> > +
> > +     while ((local_id = csr_swap(CSR_TOPEI, 0))) {
> > +             local_id = local_id >> TOPEI_ID_SHIFT;
> > +
> > +             if (local_id == IMSIC_IPI_ID) {
> > +#ifdef CONFIG_SMP
>
>         if (IS_ENABLED(CONFIG_SMP))

Okay, I will update.

>
> > +                     ipi_mux_process();
> > +#endif
> > +                     continue;
> > +             }
>
> > +
> > +/* MUST be called with lpriv->lock held */
>
> Instead of a comment which cannot be enforced just have
>
>         lockdep_assert_held(&lpriv->lock);
>
> right at the top of the function. That documents the requirement and
> lets lockdep yell if not followed.
>
> > +#ifdef CONFIG_SMP
> > +static void imsic_local_timer_callback(struct timer_list *timer)
> > +{
> > +     struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +     __imsic_local_sync(lpriv);
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> > +}
> > +
> > +/* MUST be called with lpriv->lock held */
>
> Ditto
>
> > +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
>
> > +void imsic_vector_mask(struct imsic_vector *vec)
> > +{
> > +     struct imsic_local_priv *lpriv;
> > +
> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> > +     if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> > +             return;
>
> WARN_ON_ONCE(), no?
>
> > +bool imsic_vector_isenabled(struct imsic_vector *vec)
> > +{
> > +     struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> > +     unsigned long flags;
> > +     bool ret;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +     ret = vec->enable;
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
>
> I'm not sure what you are trying to protect here. vec->enable can
> obviously change right after the lock is dropped. So that's just a
> snapshot, which is not any better than using
>
>           READ_ONCE(vec->enable);
>
> and a corresponding WRITE_ONCE() at the update site, which obviously
> needs serialization.
>
> > +static void __init imsic_local_cleanup(void)
> > +{
> > +     int cpu;
> > +     struct imsic_local_priv *lpriv;
>
>         struct imsic_local_priv *lpriv;
>         int cpu;
>
> Please.
>
> > +void imsic_state_offline(void)
> > +{
> > +#ifdef CONFIG_SMP
> > +     struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> > +#endif
>
> You can move that into the #ifdef below.
>
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
> > +     irq_matrix_offline(imsic->matrix);
> > +     raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
> > +
> > +#ifdef CONFIG_SMP
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +     WARN_ON_ONCE(try_to_del_timer_sync(&lpriv->timer) < 0);
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> > +#endif
> > +}
>
>
> Thanks,
>
>         tglx


From alexandru.elisei at arm.com  Tue Feb 20 08:36:03 2024
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 20 Feb 2024 16:36:03 +0000
Subject: arm64 MTE tag storage reuse - alternatives to MIGRATE_CMA
In-Reply-To: <b10d52ba-4a8d-43bd-96c1-cde848bec143@redhat.com>
References: <ZdSMbjGf2Fj98diT@raptor>
 <70d77490-9036-48ac-afc9-4b976433070d@redhat.com>
 <ZdSojvNyaqli2rWE@raptor>
 <e0b7c884-4345-44b1-b8c0-2711a28a980e@redhat.com>
 <ZdTNOq9BoOoKo8bZ@raptor>
 <b10d52ba-4a8d-43bd-96c1-cde848bec143@redhat.com>
Message-ID: <ZdTU80xGHgpeGwk9@raptor>

Hi,

On Tue, Feb 20, 2024 at 05:16:26PM +0100, David Hildenbrand wrote:
> > > > > > I believe this is a very good fit for tag storage reuse, because it allows
> > > > > > tag storage to be allocated even in atomic contexts, which enables MTE in
> > > > > > the kernel. As a bonus, all of the changes to MM from the current approach
> > > > > > wouldn't be needed, as tag storage allocation can be handled entirely in
> > > > > > set_ptes_at(), copy_*highpage() or arch_swap_restore().
> > > > > > 
> > > > > > Is this a viable approach that would be upstreamable? Are there other
> > > > > > solutions that I haven't considered? I'm very much open to any alternatives
> > > > > > that would make tag storage reuse viable.
> > > > > 
> > > > > As raised recently, I had similar ideas with something like virtio-mem in
> > > > > the past (wanted to call it virtio-tmem back then), but didn't have time to
> > > > > look into it yet.
> > > > > 
> > > > > I considered both, using special device memory as "cleancache" backend, and
> > > > > using it as backend storage for something similar to zswap. We would not
> > > > > need a memmap/"struct page" for that special device memory, which reduces
> > > > > memory overhead and makes "adding more memory" a more reliable operation.
> > > > 
> > > > Hm... this might not work with tag storage memory, the kernel needs to
> > > > perform cache maintenance on the memory when it transitions to and from
> > > > storing tags and storing data, so the memory must be mapped by the kernel.
> > > 
> > > The direct map will definitely be required I think (copy in/out data). But
> > > memmap for tag memory will likely not be required. Of course, it depends how
> > > to manage tag storage. Likely we have to store some metadata, hopefully we
> > > can avoid the full memmap and just use something else.
> > 
> > So I guess instead of ZONE_DEVICE I should try to use arch_add_memory()
> > directly? That has the limitation that it cannot be used by a driver
> > (symbol not exported to modules).
> You can certainly start with something simple, and we can work on removing
> that memmap allocation later.
> 
> Maybe we have to expose new primitives in the context of such drivers.
> arch_add_memory() likely also doesn't do what you need.
> 
> I recall that we had a way of only messing with the direct map.
> 
> Last time I worked with that was in the context of memtrace
> (arch/powerpc/platforms/powernv/memtrace.c)
> 
> There, we call arch_create_linear_mapping()/arch_remove_linear_mapping().
> 
> ... and now my memory comes back: we never finished factoring out
> arch_create_linear_mapping/arch_remove_linear_mapping so they would be
> available on all architectures.
> 
> 
> Your driver will be very arm64 specific, so doing it in an arm64-special way
> might be good enough initially. For example, the arm64-core could detect
> that special memory region and just statically prepare the direct map and
> not expose the memory to the buddy/allocate a memmap. Similar to how we
> handle the crashkernel/kexec IIRC (we likely do not have a direct map for
> that, though; ).
> 
> [I was also wondering if we could simply dynamically map/unmap when required
> so you can just avoid creating the entire direct map; might bot be the best
> approach performance-wise, though]
> 
> There are a bunch of details to be sorted out, but I don't consider the
> directmap/memmap side of things a big problem.

Sounds reasonable, thank you for the feedback!

Thanks,
Alex

> 
> -- 
> Cheers,
> 
> David / dhildenb
> 


From sorear at fastmail.com  Tue Feb 20 08:36:33 2024
From: sorear at fastmail.com (Stefan O'Rear)
Date: Tue, 20 Feb 2024 11:36:33 -0500
Subject: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in userspace
In-Reply-To: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
Message-ID: <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>

On Sat, Feb 3, 2024, at 7:25 AM, Mark Brown wrote:
> The arm64 Guarded Control Stack (GCS) feature provides support for
> hardware protected stacks of return addresses, intended to provide
> hardening against return oriented programming (ROP) attacks and to make
> it easier to gather call stacks for applications such as profiling.
>
> When GCS is active a secondary stack called the Guarded Control Stack is
> maintained, protected with a memory attribute which means that it can
> only be written with specific GCS operations.  The current GCS pointer
> can not be directly written to by userspace.  When a BL is executed the
> value stored in LR is also pushed onto the GCS, and when a RET is
> executed the top of the GCS is popped and compared to LR with a fault
> being raised if the values do not match.  GCS operations may only be
> performed on GCS pages, a data abort is generated if they are not.
>
> The combination of hardware enforcement and lack of extra instructions
> in the function entry and exit paths should result in something which
> has less overhead and is more difficult to attack than a purely software
> implementation like clang's shadow stacks.
>
> This series implements support for use of GCS by userspace, along with
> support for use of GCS within KVM guests.  It does not enable use of GCS
> by either EL1 or EL2, this will be implemented separately.  Executables
> are started without GCS and must use a prctl() to enable it, it is
> expected that this will be done very early in application execution by
> the dynamic linker or other startup code.  For dynamic linking this will
> be done by checking that everything in the executable is marked as GCS
> compatible.
>
> x86 has an equivalent feature called shadow stacks, this series depends
> on the x86 patches for generic memory management support for the new
> guarded/shadow stack page type and shares APIs as much as possible.  As
> there has been extensive discussion with the wider community around the
> ABI for shadow stacks I have as far as practical kept implementation
> decisions close to those for x86, anticipating that review would lead to
> similar conclusions in the absence of strong reasoning for divergence.
>
> The main divergence I am concious of is that x86 allows shadow stack to
> be enabled and disabled repeatedly, freeing the shadow stack for the
> thread whenever disabled, while this implementation keeps the GCS
> allocated after disable but refuses to reenable it.  This is to avoid
> races with things actively walking the GCS during a disable, we do
> anticipate that some systems will wish to disable GCS at runtime but are
> not aware of any demand for subsequently reenabling it.
>
> x86 uses an arch_prctl() to manage enable and disable, since only x86
> and S/390 use arch_prctl() a generic prctl() was proposed[1] as part of a
> patch set for the equivalent RISC-V Zicfiss feature which I initially
> adopted fairly directly but following review feedback has been revised
> quite a bit.

While discussing the ABI implications of shadow stacks in the context of
Zicfiss and musl a few days ago, I had the following idea for how to solve
the source compatibility problems with shadow stacks in POSIX.1-2004 and
POSIX.1-2017:

1. Introduce a "flexible shadow stack handling" option.  For what follows,
   it doesn't matter if this is system-wide, per-mm, or per-vma.

2. Shadow stack faults on non-shadow stack pages, if flexible shadow stack
   handling is in effect, cause the affected page to become a shadow stack
   page.  When this happens, the page filled with invalid address tokens.

   Faults from non-shadow-stack accesses to a shadow-stack page which was
   created by the previous paragraph will cause the page to revert to
   non-shadow-stack usage, with or without clearing.

   Important: a shadow stack operation can only load a valid address from
   a page if that page has been in continuous shadow stack use since the
   address was written by another shadow stack operation; the flexibility
   delays error reporting in cases of stray writes but it never allows for
   corruption of shadow stack operation.

3. Standards-defined operations which use a user-provided stack
   (makecontext, sigaltstack, pthread_attr_setstack) use a subrange of the
   provided stack for shadow stack storage.  I propose to use a shadow
   stack size of 1/32 of the provided stack size, rounded up to a positive
   integer number of pages, and place the shadow stack allocation at the
   lowest page-aligned address inside the provided stack region.

   Since page usage is flexible, no change in page permissions is
   immediately needed; this merely sets the initial shadow stack pointer for
   the new context.

   If the shadow stack grew in the opposite direction to the architectural
   stack, it would not be necessary to pick a fixed direction.

4. SIGSTKSZ and MINSIGSTKSZ are increased by 2 pages to provide sufficient
   space for a minimum-sized shadow stack region and worst case alignment.

_Without_ doing this, sigaltstack cannot be used to recover from stack
overflows if the shadow stack limit is reached first, and makecontext
cannot be supported without memory leaks and unreportable error conditions.

Kernel-allocated shadow stacks with a unique VM type are still useful since
they allows stray writes to crash at the time the stray write is performed,
rather than delaying the crash until the next shadow stack read.

The pthread and makecontext changes could be purely libc side, but we would
need kernel support for sigaltstack and page usage changes.

Luckily, there is no need to support stacks which are simultaneously used
from more than one process, so "is this a shadow stack page" can be tracked
purely at the vma/pte level without any need to involve the inode.  POSIX
explicitly allows using mmap to obtain stack memory and does not forbid
MAP_SHARED; I consider this sufficiently perverse application behavior that
it is not necessary to ensure exclusive use of the underlying pages while
a shadow stack pte exists.  (Applications that use MAP_SHARED for stacks
do not get the full benefit of the shadow stack but they keep POSIX.1-2004
conformance, applications that allocate stacks exclusively in MAP_PRIVATE
memory lose no security.)

The largest complication of this scheme is likely to be that the shadow
stack usage property of a page needs to survive the page being swapped out
and back in, which likely means that it must be present in the swap PTE.

I am substantially less familiar with GCS and SHSTK than with Zicfiss.
It is likely that a syscall or other mechanism is needed to initialize the
shadow stack in flexible memory for makecontext.

Is there interest on the kernel side on having mechanisms to fully support
POSIX.1-2004 with GCS or Zicfiss enabled?

-s

> We currently maintain the x86 pattern of implicitly allocating a shadow
> stack for threads started with shadow stack enabled, there has been some
> discussion of removing this support and requiring the use of clone3()
> with explicit allocation of shadow stacks instead.  I have no strong
> feelings either way, implicit allocation is not really consistent with
> anything else we do and creates the potential for errors around thread
> exit but on the other hand it is existing ABI on x86 and minimises the
> changes needed in userspace code.
>
> There is an open issue with support for CRIU, on x86 this required the
> ability to set the GCS mode via ptrace.  This series supports
> configuring mode bits other than enable/disable via ptrace but it needs
> to be confirmed if this is sufficient.
>
> The series depends on support for shadow stacks in clone3(), that series
> includes the addition of ARCH_HAS_USER_SHADOW_STACK.
>
>    
> https://lore.kernel.org/r/20231120-clone3-shadow-stack-v3-0-a7b8ed3e2acc at kernel.org
>
> It also depends on the addition of more waitpid() flags to nolibc:
>
>    
> https://lore.kernel.org/r/20231023-nolibc-waitpid-flags-v2-1-b09d096f091f at kernel.org
>
> You can see a branch with the full set of dependencies against Linus'
> tree at:
>
>    https://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc.git arm64-gcs
>
> [1] https://lore.kernel.org/lkml/20230213045351.3945824-1-debug at rivosinc.com/
>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> Changes in v8:
> - Invalidate signal cap token on stack when consuming.
> - Typo and other trivial fixes.
> - Don't try to use process_vm_write() on GCS, it intentionally does not
>   work.
> - Fix leak of thread GCSs.
> - Rebase onto latest clone3() series.
> - Link to v7: 
> https://lore.kernel.org/r/20231122-arm64-gcs-v7-0-201c483bd775 at kernel.org
>
> Changes in v7:
> - Rebase onto v6.7-rc2 via the clone3() patch series.
> - Change the token used to cap the stack during signal handling to be
>   compatible with GCSPOPM.
> - Fix flags for new page types.
> - Fold in support for clone3().
> - Replace copy_to_user_gcs() with put_user_gcs().
> - Link to v6: 
> https://lore.kernel.org/r/20231009-arm64-gcs-v6-0-78e55deaa4dd at kernel.org
>
> Changes in v6:
> - Rebase onto v6.6-rc3.
> - Add some more gcsb_dsync() barriers following spec clarifications.
> - Due to ongoing discussion around clone()/clone3() I've not updated
>   anything there, the behaviour is the same as on previous versions.
> - Link to v5: 
> https://lore.kernel.org/r/20230822-arm64-gcs-v5-0-9ef181dd6324 at kernel.org
>
> Changes in v5:
> - Don't map any permissions for user GCSs, we always use EL0 accessors
>   or use a separate mapping of the page.
> - Reduce the standard size of the GCS to RLIMIT_STACK/2.
> - Enforce a PAGE_SIZE alignment requirement on map_shadow_stack().
> - Clarifications and fixes to documentation.
> - More tests.
> - Link to v4: 
> https://lore.kernel.org/r/20230807-arm64-gcs-v4-0-68cfa37f9069 at kernel.org
>
> Changes in v4:
> - Implement flags for map_shadow_stack() allowing the cap and end of
>   stack marker to be enabled independently or not at all.
> - Relax size and alignment requirements for map_shadow_stack().
> - Add more blurb explaining the advantages of hardware enforcement.
> - Link to v3: 
> https://lore.kernel.org/r/20230731-arm64-gcs-v3-0-cddf9f980d98 at kernel.org
>
> Changes in v3:
> - Rebase onto v6.5-rc4.
> - Add a GCS barrier on context switch.
> - Add a GCS stress test.
> - Link to v2: 
> https://lore.kernel.org/r/20230724-arm64-gcs-v2-0-dc2c1d44c2eb at kernel.org
>
> Changes in v2:
> - Rebase onto v6.5-rc3.
> - Rework prctl() interface to allow each bit to be locked independently.
> - map_shadow_stack() now places the cap token based on the size
>   requested by the caller not the actual space allocated.
> - Mode changes other than enable via ptrace are now supported.
> - Expand test coverage.
> - Various smaller fixes and adjustments.
> - Link to v1: 
> https://lore.kernel.org/r/20230716-arm64-gcs-v1-0-bf567f93bba6 at kernel.org
>
> ---
> Mark Brown (38):
>       arm64/mm: Restructure arch_validate_flags() for extensibility
>       prctl: arch-agnostic prctl for shadow stack
>       mman: Add map_shadow_stack() flags
>       arm64: Document boot requirements for Guarded Control Stacks
>       arm64/gcs: Document the ABI for Guarded Control Stacks
>       arm64/sysreg: Add definitions for architected GCS caps
>       arm64/gcs: Add manual encodings of GCS instructions
>       arm64/gcs: Provide put_user_gcs()
>       arm64/cpufeature: Runtime detection of Guarded Control Stack (GCS)
>       arm64/mm: Allocate PIE slots for EL0 guarded control stack
>       mm: Define VM_SHADOW_STACK for arm64 when we support GCS
>       arm64/mm: Map pages for guarded control stack
>       KVM: arm64: Manage GCS registers for guests
>       arm64/gcs: Allow GCS usage at EL0 and EL1
>       arm64/idreg: Add overrride for GCS
>       arm64/hwcap: Add hwcap for GCS
>       arm64/traps: Handle GCS exceptions
>       arm64/mm: Handle GCS data aborts
>       arm64/gcs: Context switch GCS state for EL0
>       arm64/gcs: Ensure that new threads have a GCS
>       arm64/gcs: Implement shadow stack prctl() interface
>       arm64/mm: Implement map_shadow_stack()
>       arm64/signal: Set up and restore the GCS context for signal handlers
>       arm64/signal: Expose GCS state in signal frames
>       arm64/ptrace: Expose GCS via ptrace and core files
>       arm64: Add Kconfig for Guarded Control Stack (GCS)
>       kselftest/arm64: Verify the GCS hwcap
>       kselftest/arm64: Add GCS as a detected feature in the signal tests
>       kselftest/arm64: Add framework support for GCS to signal handling tests
>       kselftest/arm64: Allow signals tests to specify an expected si_code
>       kselftest/arm64: Always run signals tests with GCS enabled
>       kselftest/arm64: Add very basic GCS test program
>       kselftest/arm64: Add a GCS test program built with the system libc
>       kselftest/arm64: Add test coverage for GCS mode locking
>       selftests/arm64: Add GCS signal tests
>       kselftest/arm64: Add a GCS stress test
>       kselftest/arm64: Enable GCS for the FP stress tests
>       kselftest: Provide shadow stack enable helpers for arm64
>
>  Documentation/admin-guide/kernel-parameters.txt    |   6 +
>  Documentation/arch/arm64/booting.rst               |  22 +
>  Documentation/arch/arm64/elf_hwcaps.rst            |   3 +
>  Documentation/arch/arm64/gcs.rst                   | 233 +++++++
>  Documentation/arch/arm64/index.rst                 |   1 +
>  Documentation/filesystems/proc.rst                 |   2 +-
>  arch/arm64/Kconfig                                 |  20 +
>  arch/arm64/include/asm/cpufeature.h                |   6 +
>  arch/arm64/include/asm/el2_setup.h                 |  17 +
>  arch/arm64/include/asm/esr.h                       |  28 +-
>  arch/arm64/include/asm/exception.h                 |   2 +
>  arch/arm64/include/asm/gcs.h                       | 107 +++
>  arch/arm64/include/asm/hwcap.h                     |   1 +
>  arch/arm64/include/asm/kvm_arm.h                   |   4 +-
>  arch/arm64/include/asm/kvm_host.h                  |  12 +
>  arch/arm64/include/asm/mman.h                      |  23 +-
>  arch/arm64/include/asm/pgtable-prot.h              |  14 +-
>  arch/arm64/include/asm/processor.h                 |   7 +
>  arch/arm64/include/asm/sysreg.h                    |  20 +
>  arch/arm64/include/asm/uaccess.h                   |  40 ++
>  arch/arm64/include/uapi/asm/hwcap.h                |   1 +
>  arch/arm64/include/uapi/asm/ptrace.h               |   8 +
>  arch/arm64/include/uapi/asm/sigcontext.h           |   9 +
>  arch/arm64/kernel/cpufeature.c                     |  19 +
>  arch/arm64/kernel/cpuinfo.c                        |   1 +
>  arch/arm64/kernel/entry-common.c                   |  23 +
>  arch/arm64/kernel/idreg-override.c                 |   2 +
>  arch/arm64/kernel/process.c                        |  85 +++
>  arch/arm64/kernel/ptrace.c                         |  59 ++
>  arch/arm64/kernel/signal.c                         | 242 ++++++-
>  arch/arm64/kernel/traps.c                          |  11 +
>  arch/arm64/kvm/emulate-nested.c                    |   4 +
>  arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h         |  17 +
>  arch/arm64/kvm/sys_regs.c                          |  22 +
>  arch/arm64/mm/Makefile                             |   1 +
>  arch/arm64/mm/fault.c                              |  79 ++-
>  arch/arm64/mm/gcs.c                                | 300 +++++++++
>  arch/arm64/mm/mmap.c                               |  13 +-
>  arch/arm64/tools/cpucaps                           |   1 +
>  arch/x86/include/uapi/asm/mman.h                   |   3 -
>  fs/proc/task_mmu.c                                 |   3 +
>  include/linux/mm.h                                 |  16 +-
>  include/uapi/asm-generic/mman.h                    |   4 +
>  include/uapi/linux/elf.h                           |   1 +
>  include/uapi/linux/prctl.h                         |  22 +
>  kernel/sys.c                                       |  30 +
>  tools/testing/selftests/arm64/Makefile             |   2 +-
>  tools/testing/selftests/arm64/abi/hwcap.c          |  19 +
>  tools/testing/selftests/arm64/fp/assembler.h       |  15 +
>  tools/testing/selftests/arm64/fp/fpsimd-test.S     |   2 +
>  tools/testing/selftests/arm64/fp/sve-test.S        |   2 +
>  tools/testing/selftests/arm64/fp/za-test.S         |   2 +
>  tools/testing/selftests/arm64/fp/zt-test.S         |   2 +
>  tools/testing/selftests/arm64/gcs/.gitignore       |   5 +
>  tools/testing/selftests/arm64/gcs/Makefile         |  24 +
>  tools/testing/selftests/arm64/gcs/asm-offsets.h    |   0
>  tools/testing/selftests/arm64/gcs/basic-gcs.c      | 428 ++++++++++++
>  tools/testing/selftests/arm64/gcs/gcs-locking.c    | 200 ++++++
>  .../selftests/arm64/gcs/gcs-stress-thread.S        | 311 +++++++++
>  tools/testing/selftests/arm64/gcs/gcs-stress.c     | 532 +++++++++++++++
>  tools/testing/selftests/arm64/gcs/gcs-util.h       | 100 +++
>  tools/testing/selftests/arm64/gcs/libc-gcs.c       | 736 +++++++++++++++++++++
>  tools/testing/selftests/arm64/signal/.gitignore    |   1 +
>  .../testing/selftests/arm64/signal/test_signals.c  |  17 +-
>  .../testing/selftests/arm64/signal/test_signals.h  |   6 +
>  .../selftests/arm64/signal/test_signals_utils.c    |  32 +-
>  .../selftests/arm64/signal/test_signals_utils.h    |  39 ++
>  .../arm64/signal/testcases/gcs_exception_fault.c   |  62 ++
>  .../selftests/arm64/signal/testcases/gcs_frame.c   |  88 +++
>  .../arm64/signal/testcases/gcs_write_fault.c       |  67 ++
>  .../selftests/arm64/signal/testcases/testcases.c   |   7 +
>  .../selftests/arm64/signal/testcases/testcases.h   |   1 +
>  tools/testing/selftests/ksft_shstk.h               |  37 ++
>  73 files changed, 4241 insertions(+), 40 deletions(-)
> ---
> base-commit: 50abefbf1bc07f5c4e403fd28f71dcee855100f7
> change-id: 20230303-arm64-gcs-e311ab0d8729
>
> Best regards,
> -- 
> Mark Brown <broonie at kernel.org>
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From apatel at ventanamicro.com  Tue Feb 20 08:39:46 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 22:09:46 +0530
Subject: [PATCH v13 07/13] irqchip/riscv-imsic: Add device MSI domain
 support for platform devices
In-Reply-To: <87cysrfj32.fsf@all.your.base.are.belong.to.us>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-8-apatel@ventanamicro.com> <87cysrfj32.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAK9=C2Umyc5KpZSQiAVxRA8NNqj3yuvqX4d8pMnc21jQjwZkWg@mail.gmail.com>

On Tue, Feb 20, 2024 at 5:23?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Anup Patel <apatel at ventanamicro.com> writes:
>
> > The Linux platform MSI support allows per-device MSI domains so let
> > us add a platform irqchip driver for RISC-V IMSIC which provides a
> > base IRQ domain with MSI parent support for platform device domains.
> >
> > This driver assumes that the IMSIC state is already initialized by
> > the IMSIC early driver.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  drivers/irqchip/Makefile                   |   2 +-
> >  drivers/irqchip/irq-riscv-imsic-platform.c | 346 +++++++++++++++++++++
> >  drivers/irqchip/irq-riscv-imsic-state.h    |   1 +
> >  3 files changed, 348 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c
> >
> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> > index d714724387ce..abca445a3229 100644
> > --- a/drivers/irqchip/Makefile
> > +++ b/drivers/irqchip/Makefile
> > @@ -95,7 +95,7 @@ obj-$(CONFIG_QCOM_MPM)                      += irq-qcom-mpm.o
> >  obj-$(CONFIG_CSKY_MPINTC)            += irq-csky-mpintc.o
> >  obj-$(CONFIG_CSKY_APB_INTC)          += irq-csky-apb-intc.o
> >  obj-$(CONFIG_RISCV_INTC)             += irq-riscv-intc.o
> > -obj-$(CONFIG_RISCV_IMSIC)            += irq-riscv-imsic-state.o irq-riscv-imsic-early.o
> > +obj-$(CONFIG_RISCV_IMSIC)            += irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
> >  obj-$(CONFIG_SIFIVE_PLIC)            += irq-sifive-plic.o
> >  obj-$(CONFIG_IMX_IRQSTEER)           += irq-imx-irqsteer.o
> >  obj-$(CONFIG_IMX_INTMUX)             += irq-imx-intmux.o
> > diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
> > new file mode 100644
> > index 000000000000..7ee44c493dbc
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-imsic-platform.c
> > @@ -0,0 +1,346 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
> > + */
> > +
> > +#define pr_fmt(fmt) "riscv-imsic: " fmt
> > +#include <linux/bitmap.h>
> > +#include <linux/cpu.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/irq.h>
> > +#include <linux/irqchip.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/module.h>
> > +#include <linux/msi.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/smp.h>
> > +
> > +#include "irq-riscv-imsic-state.h"
> > +
> > +static bool imsic_cpu_page_phys(unsigned int cpu, unsigned int guest_index,
> > +                             phys_addr_t *out_msi_pa)
> > +{
> > +     struct imsic_global_config *global;
> > +     struct imsic_local_config *local;
> > +
> > +     global = &imsic->global;
> > +     local = per_cpu_ptr(global->local, cpu);
> > +
> > +     if (BIT(global->guest_index_bits) <= guest_index)
> > +             return false;
> > +
> > +     if (out_msi_pa)
> > +             *out_msi_pa = local->msi_pa +
> > +                           (guest_index * IMSIC_MMIO_PAGE_SZ);
> > +
> > +     return true;
> > +}
> > +
> > +static void imsic_irq_mask(struct irq_data *d)
> > +{
> > +     imsic_vector_mask(irq_data_get_irq_chip_data(d));
> > +}
> > +
> > +static void imsic_irq_unmask(struct irq_data *d)
> > +{
> > +     imsic_vector_unmask(irq_data_get_irq_chip_data(d));
> > +}
> > +
> > +static int imsic_irq_retrigger(struct irq_data *d)
> > +{
> > +     struct imsic_vector *vec = irq_data_get_irq_chip_data(d);
> > +     struct imsic_local_config *local;
> > +
> > +     if (WARN_ON(vec == NULL))
>
> Checkpatch: use !vec

Okay, I will update.

>
> > +             return -ENOENT;
> > +
> > +     local = per_cpu_ptr(imsic->global.local, vec->cpu);
> > +     writel_relaxed(vec->local_id, local->msi_va);
> > +     return 0;
> > +}
> > +
> > +static void imsic_irq_compose_vector_msg(struct imsic_vector *vec, struct msi_msg *msg)
> > +{
> > +     phys_addr_t msi_addr;
> > +
> > +     if (WARN_ON(vec == NULL))
>
> Checkpatch: use !vec

Okay, I will update.

>
> > +             return;
> > +
> > +     if (WARN_ON(!imsic_cpu_page_phys(vec->cpu, 0, &msi_addr)))
> > +             return;
> > +
> > +     msg->address_hi = upper_32_bits(msi_addr);
> > +     msg->address_lo = lower_32_bits(msi_addr);
> > +     msg->data = vec->local_id;
> > +}
> > +
> > +static void imsic_irq_compose_msg(struct irq_data *d, struct msi_msg *msg)
> > +{
> > +     imsic_irq_compose_vector_msg(irq_data_get_irq_chip_data(d), msg);
> > +}
> > +
> > +#ifdef CONFIG_SMP
> > +static void imsic_msi_update_msg(struct irq_data *d, struct imsic_vector *vec)
> > +{
> > +     struct msi_msg msg[2] = { [1] = { }, };
> > +
> > +     imsic_irq_compose_vector_msg(vec, msg);
> > +     irq_data_get_irq_chip(d)->irq_write_msi_msg(d, msg);
> > +}
> > +
> > +static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
> > +                               bool force)
> > +{
> > +     struct imsic_vector *old_vec, *new_vec;
> > +     struct irq_data *pd = d->parent_data;
> > +
> > +     old_vec = irq_data_get_irq_chip_data(pd);
> > +     if (WARN_ON(old_vec == NULL))
>
> Checkpatch: use !old_vec

Okay, I will update.

>
> > +             return -ENOENT;
> > +
> > +     /* If old vector cpu belongs to the target cpumask then do nothing */
> > +     if (cpumask_test_cpu(old_vec->cpu, mask_val))
> > +             return IRQ_SET_MASK_OK_DONE;
> > +
> > +     /* If move is already in-flight then return failure */
> > +     if (imsic_vector_get_move(old_vec))
> > +             return -EBUSY;
> > +
> > +     /* Get a new vector on the desired set of CPUs */
> > +     new_vec = imsic_vector_alloc(old_vec->hwirq, mask_val);
> > +     if (!new_vec)
> > +             return -ENOSPC;
> > +
> > +     /* Point device to the new vector */
> > +     imsic_msi_update_msg(d, new_vec);
> > +
> > +     /* Update irq descriptors with the new vector */
> > +     pd->chip_data = new_vec;
> > +
> > +     /* Update effective affinity of parent irq data */
> > +     irq_data_update_effective_affinity(pd, cpumask_of(new_vec->cpu));
> > +
> > +     /* Move state of the old vector to the new vector */
> > +     imsic_vector_move(old_vec, new_vec);
> > +
> > +     return IRQ_SET_MASK_OK_DONE;
> > +}
> > +#endif
> > +
> > +static struct irq_chip imsic_irq_base_chip = {
> > +     .name                   = "IMSIC",
> > +     .irq_mask               = imsic_irq_mask,
> > +     .irq_unmask             = imsic_irq_unmask,
> > +     .irq_retrigger          = imsic_irq_retrigger,
> > +     .irq_compose_msi_msg    = imsic_irq_compose_msg,
> > +     .flags                  = IRQCHIP_SKIP_SET_WAKE |
> > +                               IRQCHIP_MASK_ON_SUSPEND,
> > +};
> > +
> > +static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> > +                               unsigned int nr_irqs, void *args)
> > +{
> > +     struct imsic_vector *vec;
> > +
> > +     /* Legacy-MSI or multi-MSI not supported yet. */
> > +     if (nr_irqs > 1)
> > +             return -ENOTSUPP;
>
> Checkpatch: WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP

Okay, I will update.

Regards,
Anup


From apatel at ventanamicro.com  Tue Feb 20 08:52:01 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 22:22:01 +0530
Subject: [PATCH v13 07/13] irqchip/riscv-imsic: Add device MSI domain
 support for platform devices
In-Reply-To: <875xyji7mc.ffs@tglx>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-8-apatel@ventanamicro.com> <875xyji7mc.ffs@tglx>
Message-ID: <CAK9=C2V3hQnpibHgHUpwRXWn4LSuGue0a7Sh9NFYPB6XOizjoA@mail.gmail.com>

On Tue, Feb 20, 2024 at 7:02?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> > +#ifdef CONFIG_SMP
> > +static void imsic_msi_update_msg(struct irq_data *d, struct imsic_vector *vec)
> > +{
> > +     struct msi_msg msg[2] = { [1] = { }, };
>
> That's a weird initializer and why do you need an array here?
>
>        struct msi_msg msg = { };
>
> Should be sufficient, no?

I had taken reference from irq_msi_update_msg() in
arch/x86/kernel/apic/msi.c

I tried "struct msi_msg msg = { };" and it works fine so
I will update.

>
> > +
> > +     imsic_irq_compose_vector_msg(vec, msg);
> > +     irq_data_get_irq_chip(d)->irq_write_msi_msg(d, msg);
> > +}
>
> > +static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> > +                               unsigned int nr_irqs, void *args)
> > +{
> > +     struct imsic_vector *vec;
> > +
> > +     /* Legacy-MSI or multi-MSI not supported yet. */
>
> Coming back to my earlier question:
>
> >> What's legacy MSI in that context?
> >
> > The legacy-MSI is the MSI support in PCI v2.2 where
> > number of MSIs allocated by device were either 1, 2, 4,
> > 8, 16, or 32 and the data written is <data_word> + <irqnum>.
>
> You talk about PCI/MSI, where more than one vector is named
> multi-MSI. Contrary to the modern v3.0 variant which is PCI/MSI-X.
>
> So this should be "Multi-MSI is not supported yet", no?

Yes, I agree. We should just call it "Multi-MSI is not supported yet"
to avoid confusion. I will update.

>
> > +     if (nr_irqs > 1)
> > +             return -ENOTSUPP;
> > +
> > +     vec = imsic_vector_alloc(virq, cpu_online_mask);
> > +     if (!vec)
> > +             return -ENOSPC;
> > +
> > +     irq_domain_set_info(domain, virq, virq,
> > +                         &imsic_irq_base_chip, vec,
> > +                         handle_simple_irq, NULL, NULL);
>
> Please utilize the 100 characters.

Okay, I will update.

>
> > +     irq_set_noprobe(virq);
> > +     irq_set_affinity(virq, cpu_online_mask);
> > +
> > +     return 0;
> > +}
>
> Thanks,
>
>         tglx

Thanks,
Anup


From tglx at linutronix.de  Tue Feb 20 09:12:41 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 20 Feb 2024 18:12:41 +0100
Subject: [PATCH v13 07/13] irqchip/riscv-imsic: Add device MSI domain
 support for platform devices
In-Reply-To: <CAK9=C2V3hQnpibHgHUpwRXWn4LSuGue0a7Sh9NFYPB6XOizjoA@mail.gmail.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-8-apatel@ventanamicro.com> <875xyji7mc.ffs@tglx>
 <CAK9=C2V3hQnpibHgHUpwRXWn4LSuGue0a7Sh9NFYPB6XOizjoA@mail.gmail.com>
Message-ID: <87msrvgiuu.ffs@tglx>

On Tue, Feb 20 2024 at 22:22, Anup Patel wrote:
> On Tue, Feb 20, 2024 at 7:02?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>>
>> On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
>> > +#ifdef CONFIG_SMP
>> > +static void imsic_msi_update_msg(struct irq_data *d, struct imsic_vector *vec)
>> > +{
>> > +     struct msi_msg msg[2] = { [1] = { }, };
>>
>> That's a weird initializer and why do you need an array here?
>>
>>        struct msi_msg msg = { };
>>
>> Should be sufficient, no?
>
> I had taken reference from irq_msi_update_msg() in
> arch/x86/kernel/apic/msi.c

Which is equally bogus :)

The charm of copy and pasta...

Thanks,

        tglx


From pmenzel at molgen.mpg.de  Tue Feb 20 09:16:37 2024
From: pmenzel at molgen.mpg.de (Paul Menzel)
Date: Tue, 20 Feb 2024 18:16:37 +0100
Subject: [PATCH] mmc: host: replace 1st argument to struct device * for
 mmc_of_parse_clk_phase()
In-Reply-To: <20240215-mmc_phase-v1-1-f27644ee13e4@outlook.com>
References: <20240215-mmc_phase-v1-1-f27644ee13e4@outlook.com>
Message-ID: <26acdacd-e63b-494f-bf7d-215b8643a0c5@molgen.mpg.de>

Dear Yang,


Thank you very much for your patch. Some nits from my side.

For the summary, I suggest:

 > mmc: host: mmc_of_parse_clk_phase(): Pass struct device * instead of 
mmc_host *

Am 15.02.24 um 12:03 schrieb Yang Xiwen via B4 Relay:
> From: Yang Xiwen <forbidden405 at outlook.com>
> 
> Parsing dt usaully happens very early, sometimes even bofore struct

1.  us*ua*lly
2.  b*e*fore

> mmc_host is allocated (e.g. dw_mci_probe() and dw_mci_parse_dt() in
> dw_mmc.c). Looking at the source of mmc_of_parse_clk_phase(), it's
> actually not mandatory to have a initialized mmc_host first, instead we

a*n*

> can pass struct device * to it directly.
> 
> Also fix the only current user (sdhci-of-aspeed.c).
> 
> Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
> ---
>   drivers/mmc/core/host.c            | 4 +---
>   drivers/mmc/host/sdhci-of-aspeed.c | 2 +-
>   include/linux/mmc/host.h           | 2 +-
>   3 files changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index cf396e8f34e9..8b2844ac5dc5 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -234,10 +234,8 @@ static void mmc_of_parse_timing_phase(struct device *dev, const char *prop,
>   }
>   
>   void
> -mmc_of_parse_clk_phase(struct mmc_host *host, struct mmc_clk_phase_map *map)
> +mmc_of_parse_clk_phase(struct device *dev, struct mmc_clk_phase_map *map)
>   {
> -	struct device *dev = host->parent;
> -
>   	mmc_of_parse_timing_phase(dev, "clk-phase-legacy",
>   				  &map->phase[MMC_TIMING_LEGACY]);
>   	mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs",
> diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
> index 42d54532cabe..430c1f90037b 100644
> --- a/drivers/mmc/host/sdhci-of-aspeed.c
> +++ b/drivers/mmc/host/sdhci-of-aspeed.c
> @@ -435,7 +435,7 @@ static int aspeed_sdhci_probe(struct platform_device *pdev)
>   		goto err_sdhci_add;
>   
>   	if (dev->phase_desc)
> -		mmc_of_parse_clk_phase(host->mmc, &dev->phase_map);
> +		mmc_of_parse_clk_phase(&pdev->dev, &dev->phase_map);
>   
>   	ret = sdhci_add_host(host);
>   	if (ret)
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 2f445c651742..5894bf912f7b 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -539,7 +539,7 @@ struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra);
>   int mmc_add_host(struct mmc_host *);
>   void mmc_remove_host(struct mmc_host *);
>   void mmc_free_host(struct mmc_host *);
> -void mmc_of_parse_clk_phase(struct mmc_host *host,
> +void mmc_of_parse_clk_phase(struct device *dev,
>   			    struct mmc_clk_phase_map *map);
>   int mmc_of_parse(struct mmc_host *host);
>   int mmc_of_parse_voltage(struct mmc_host *host, u32 *mask);

Reviewed-by: Paul Menzel <pmenzel at molgen.mpg.de>


Kind regards,

Paul


From kprateek.nayak at amd.com  Tue Feb 20 09:14:48 2024
From: kprateek.nayak at amd.com (K Prateek Nayak)
Date: Tue, 20 Feb 2024 22:44:48 +0530
Subject: [RFC PATCH 05/14] arm/thread_info: Introduce TIF_NOTIFY_IPI flag
In-Reply-To: <20240220171457.703-1-kprateek.nayak@amd.com>
References: <20240220171457.703-1-kprateek.nayak@amd.com>
Message-ID: <20240220171457.703-6-kprateek.nayak@amd.com>

Add support for TIF_NOTIFY_IPI on ARM. With TIF_NOTIFY_IPI, a sender
sending an IPI to an idle CPU in TIF_POLLING mode will set the
TIF_NOTIFY_IPI flag in the target's idle tasks's thread_info to pull the
CPU out of idle, as opposed to setting TIF_NEED_RESCHED previously. This
avoids spurious calls to schedule_idle() in cases where an IPI does not
necessarily wake up a task on the idle CPU.

IPI throughput measured using a modified version of Anton Blanchard's
ipistorm benchmark [1], configured to measure time taken to perform a
fixed number of smp_call_function_single() (with wait set to 1),
improves significantly with TIF_NOTIFY_IPI on a dual socket Ampere Server
(2 x 64C) with the benchmark time reducing to less than half for
100000 IPIs between two CPUs. (Note: Only WFI idle mode was left enabled
during testing to reduce variance)

cmdline: insmod ipistorm.ko numipi=100000 single=1 offset=8 cpulist=8 wait=1

  ==================================================================
  Test          : ipistorm (modified)
  Units         : Normalized runtime
  Interpretation: Lower is better
  Statistic     : AMean
  ==================================================================
  kernel:				time [pct imp]
  tip:sched/core			1.00 [0.00]
  tip:sched/core + TIF_NOTIFY_IPI	0.41 [59.29]

tip:sched/core was at tag "sched-core-2024-01-08" at the time of
testing.

Cc: Russell King <linux at armlinux.org.uk>
Cc: "Rafael J. Wysocki" <rafael at kernel.org>
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Juri Lelli <juri.lelli at redhat.com>
Cc: Vincent Guittot <vincent.guittot at linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann at arm.com>
Cc: Steven Rostedt <rostedt at goodmis.org>
Cc: Ben Segall <bsegall at google.com>
Cc: Mel Gorman <mgorman at suse.de>
Cc: Daniel Bristot de Oliveira <bristot at redhat.com>
Cc: Valentin Schneider <vschneid at redhat.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-pm at vger.kernel.org
Link: https://github.com/antonblanchard/ipistorm [1]
Signed-off-by: K Prateek Nayak <kprateek.nayak at amd.com>
---
 arch/arm/include/asm/thread_info.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 943ffcf069d2..324248d87c9e 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -136,6 +136,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
  * thread information flags:
  *  TIF_USEDFPU		- FPU was used by this task this quantum (SMP)
  *  TIF_POLLING_NRFLAG	- true if poll_idle() is polling TIF_NEED_RESCHED
+ *			  or TIF_NOTIFY_IPI
  *
  * Any bit in the range of 0..15 will cause do_work_pending() to be invoked.
  */
@@ -144,6 +145,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
 #define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
 #define TIF_UPROBE		3	/* breakpointed or singlestepping */
 #define TIF_NOTIFY_SIGNAL	4	/* signal notifications exist */
+#define TIF_NOTIFY_IPI		5	/* pending IPI on TIF_POLLLING idle CPU */
 
 #define TIF_USING_IWMMXT	17
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
@@ -164,6 +166,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_NOTIFY_SIGNAL	(1 << TIF_NOTIFY_SIGNAL)
 #define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)
+#define _TIF_NOTIFY_IPI		(1 << TIF_NOTIFY_IPI)
 
 /* Checks for any syscall work in entry-common.S */
 #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
-- 
2.34.1



From olsajiri at gmail.com  Tue Feb 20 09:18:30 2024
From: olsajiri at gmail.com (Jiri Olsa)
Date: Tue, 20 Feb 2024 18:18:30 +0100
Subject: [PATCH bpf-next 2/5] bpf: tracing: support to attach program to
 multi hooks
In-Reply-To: <20240220035105.34626-3-dongmenglong.8@bytedance.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
 <20240220035105.34626-3-dongmenglong.8@bytedance.com>
Message-ID: <ZdTe5pyV16y4wYzv@krava>

On Tue, Feb 20, 2024 at 11:51:02AM +0800, Menglong Dong wrote:

SNIP

> @@ -3228,7 +3260,9 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
>  	struct bpf_link_primer link_primer;
>  	struct bpf_prog *tgt_prog = NULL;
>  	struct bpf_trampoline *tr = NULL;
> +	struct btf *attach_btf = NULL;
>  	struct bpf_tracing_link *link;
> +	struct module *mod = NULL;
>  	u64 key = 0;
>  	int err;
>  
> @@ -3258,31 +3292,50 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
>  		goto out_put_prog;
>  	}
>  
> -	if (!!tgt_prog_fd != !!btf_id) {
> -		err = -EINVAL;
> -		goto out_put_prog;
> -	}
> -
>  	if (tgt_prog_fd) {
> -		/*
> -		 * For now we only allow new targets for BPF_PROG_TYPE_EXT. If this
> -		 * part would be changed to implement the same for
> -		 * BPF_PROG_TYPE_TRACING, do not forget to update the way how
> -		 * attach_tracing_prog flag is set.
> -		 */
> -		if (prog->type != BPF_PROG_TYPE_EXT) {
> +		if (!btf_id) {
>  			err = -EINVAL;
>  			goto out_put_prog;
>  		}
> -
>  		tgt_prog = bpf_prog_get(tgt_prog_fd);
>  		if (IS_ERR(tgt_prog)) {
> -			err = PTR_ERR(tgt_prog);
>  			tgt_prog = NULL;
> -			goto out_put_prog;
> +			/* tgt_prog_fd is the fd of the kernel module BTF */
> +			attach_btf = btf_get_by_fd(tgt_prog_fd);

I think we should pass the btf_fd through attr, like add
link_create.tracing_btf_fd instead, this seems confusing

> +			if (IS_ERR(attach_btf)) {
> +				attach_btf = NULL;
> +				err = -EINVAL;
> +				goto out_put_prog;
> +			}
> +			if (!btf_is_kernel(attach_btf)) {
> +				btf_put(attach_btf);
> +				err = -EOPNOTSUPP;
> +				goto out_put_prog;
> +			}
> +		} else if (prog->type == BPF_PROG_TYPE_TRACING &&
> +			   tgt_prog->type == BPF_PROG_TYPE_TRACING) {
> +			prog->aux->attach_tracing_prog = true;
>  		}

could you please add comment on why this check is in here?

> -
> -		key = bpf_trampoline_compute_key(tgt_prog, NULL, btf_id);
> +		key = bpf_trampoline_compute_key(tgt_prog, attach_btf,
> +						 btf_id);
> +	} else if (btf_id) {
> +		attach_btf = bpf_get_btf_vmlinux();
> +		if (IS_ERR(attach_btf)) {
> +			attach_btf = NULL;
> +			err = PTR_ERR(attach_btf);
> +			goto out_unlock;
> +		}
> +		if (!attach_btf) {
> +			err = -EINVAL;
> +			goto out_unlock;
> +		}
> +		btf_get(attach_btf);
> +		key = bpf_trampoline_compute_key(NULL, attach_btf, btf_id);
> +	} else {
> +		attach_btf = prog->aux->attach_btf;
> +		/* get the reference of the btf for bpf link */
> +		if (attach_btf)
> +			btf_get(attach_btf);
>  	}
>  
>  	link = kzalloc(sizeof(*link), GFP_USER);
> @@ -3319,7 +3372,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
>  	 *   are NULL, then program was already attached and user did not provide
>  	 *   tgt_prog_fd so we have no way to find out or create trampoline
>  	 */
> -	if (!prog->aux->dst_trampoline && !tgt_prog) {
> +	if (!prog->aux->dst_trampoline && !tgt_prog && !btf_id) {
>  		/*
>  		 * Allow re-attach for TRACING and LSM programs. If it's
>  		 * currently linked, bpf_trampoline_link_prog will fail.
> @@ -3346,17 +3399,27 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
>  		 * different from the destination specified at load time, we
>  		 * need a new trampoline and a check for compatibility
>  		 */
> +		struct btf *origin_btf = prog->aux->attach_btf;
>  		struct bpf_attach_target_info tgt_info = {};
>  
> +		/* use the new attach_btf to check the target */
> +		prog->aux->attach_btf = attach_btf;
>  		err = bpf_check_attach_target(NULL, prog, tgt_prog, btf_id,
>  					      &tgt_info);
> +		prog->aux->attach_btf = origin_btf;

could we pass the attach_btf as argument then?

jirka

>  		if (err)
>  			goto out_unlock;
>  
> -		if (tgt_info.tgt_mod) {
> -			module_put(prog->aux->mod);
> -			prog->aux->mod = tgt_info.tgt_mod;
> -		}
> +		mod = tgt_info.tgt_mod;
> +		/* the new target and the previous target are in the same
> +		 * module, release the reference once.
> +		 */
> +		if (mod && mod == prog->aux->mod)
> +			module_put(mod);
> +		err = bpf_tracing_check_multi(prog, tgt_prog, attach_btf,
> +					      tgt_info.tgt_type);
> +		if (err)
> +			goto out_unlock;
>  
>  		tr = bpf_trampoline_get(key, &tgt_info);
>  		if (!tr) {
> @@ -3373,6 +3436,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
>  		 */
>  		tr = prog->aux->dst_trampoline;
>  		tgt_prog = prog->aux->dst_prog;
> +		mod = prog->aux->mod;
>  	}
>  
>  	err = bpf_link_prime(&link->link.link, &link_primer);
> @@ -3388,6 +3452,8 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
>  
>  	link->tgt_prog = tgt_prog;
>  	link->trampoline = tr;
> +	link->attach_btf = attach_btf;
> +	link->mod = mod;
>  
>  	/* Always clear the trampoline and target prog from prog->aux to make
>  	 * sure the original attach destination is not kept alive after a
> @@ -3400,20 +3466,27 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
>  	if (prog->aux->dst_trampoline && tr != prog->aux->dst_trampoline)
>  		/* we allocated a new trampoline, so free the old one */
>  		bpf_trampoline_put(prog->aux->dst_trampoline);
> +	if (prog->aux->mod && mod != prog->aux->mod)
> +		/* the mod in prog is not used anywhere, move it to link */
> +		module_put(prog->aux->mod);
>  
>  	prog->aux->dst_prog = NULL;
>  	prog->aux->dst_trampoline = NULL;
> +	prog->aux->mod = NULL;
>  	mutex_unlock(&prog->aux->dst_mutex);
>  
>  	return bpf_link_settle(&link_primer);
>  out_unlock:
>  	if (tr && tr != prog->aux->dst_trampoline)
>  		bpf_trampoline_put(tr);
> +	if (mod && mod != prog->aux->mod)
> +		module_put(mod);
>  	mutex_unlock(&prog->aux->dst_mutex);
>  	kfree(link);
>  out_put_prog:
>  	if (tgt_prog_fd && tgt_prog)
>  		bpf_prog_put(tgt_prog);
> +	btf_put(attach_btf);
>  	return err;
>  }
>  
> -- 
> 2.39.2
> 


From olsajiri at gmail.com  Tue Feb 20 09:18:40 2024
From: olsajiri at gmail.com (Jiri Olsa)
Date: Tue, 20 Feb 2024 18:18:40 +0100
Subject: [PATCH bpf-next 1/5] bpf: tracing: add support to record and
 check the accessed args
In-Reply-To: <20240220035105.34626-2-dongmenglong.8@bytedance.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
 <20240220035105.34626-2-dongmenglong.8@bytedance.com>
Message-ID: <ZdTe8LteoqR43d4q@krava>

On Tue, Feb 20, 2024 at 11:51:01AM +0800, Menglong Dong wrote:

SNIP

> +static int get_ctx_arg_idx_aligned(struct btf *btf, const struct btf_type *t,
> +				   int off)
> +{
> +	const struct btf_param *args;
> +	u32 offset = 0, nr_args;
> +	int i;
> +
> +	nr_args = btf_type_vlen(t);
> +	args = (const struct btf_param *)(t + 1);
> +	for (i = 0; i < nr_args; i++) {
> +		if (offset == off)
> +			return i;
> +
> +		t = btf_type_skip_modifiers(btf, args[i].type, NULL);
> +		offset += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
> +		if (offset > off)
> +			return -1;
> +	}
> +	return -1;
> +}
> +
> +/* This function is similar to btf_check_func_type_match(), except that it
> + * only compare some function args of the function prototype t1 and t2.
> + */

could we reuse btf_check_func_type_match instead? perhaps just
adding extra argument with arguments bitmap to it?

jirka

> +int btf_check_func_part_match(struct btf *btf1, const struct btf_type *func1,
> +			      struct btf *btf2, const struct btf_type *func2,
> +			      u64 func_args)
> +{
> +	const struct btf_param *args1, *args2;
> +	u32 nargs1, i, offset = 0;
> +	const char *s1, *s2;
> +
> +	if (!btf_type_is_func_proto(func1) || !btf_type_is_func_proto(func2))
> +		return -EINVAL;
> +
> +	args1 = (const struct btf_param *)(func1 + 1);
> +	args2 = (const struct btf_param *)(func2 + 1);
> +	nargs1 = btf_type_vlen(func1);
> +
> +	for (i = 0; i <= nargs1; i++) {
> +		const struct btf_type *t1, *t2;
> +
> +		if (!(func_args & (1 << i)))
> +			goto next;
> +
> +		if (i < nargs1) {
> +			int t2_index;
> +
> +			/* get the index of the arg corresponding to args1[i]
> +			 * by the offset.
> +			 */
> +			t2_index = get_ctx_arg_idx_aligned(btf2, func2,
> +							   offset);
> +			if (t2_index < 0)
> +				return -EINVAL;
> +
> +			t1 = btf_type_skip_modifiers(btf1, args1[i].type, NULL);
> +			t2 = btf_type_skip_modifiers(btf2, args2[t2_index].type,
> +						     NULL);
> +		} else {
> +			/* i == nargs1, this is the index of return value of t1 */
> +			if (get_ctx_arg_total_size(btf1, func1) !=
> +			    get_ctx_arg_total_size(btf2, func2))
> +				return -EINVAL;
> +
> +			/* check the return type of t1 and t2 */
> +			t1 = btf_type_skip_modifiers(btf1, func1->type, NULL);
> +			t2 = btf_type_skip_modifiers(btf2, func2->type, NULL);
> +		}
> +
> +		if (t1->info != t2->info ||
> +		    (btf_type_has_size(t1) && t1->size != t2->size))
> +			return -EINVAL;
> +		if (btf_type_is_int(t1) || btf_is_any_enum(t1))
> +			goto next;
> +
> +		if (btf_type_is_struct(t1))
> +			goto on_struct;
> +
> +		if (!btf_type_is_ptr(t1))
> +			return -EINVAL;
> +
> +		t1 = btf_type_skip_modifiers(btf1, t1->type, NULL);
> +		t2 = btf_type_skip_modifiers(btf2, t2->type, NULL);
> +		if (!btf_type_is_struct(t1) || !btf_type_is_struct(t2))
> +			return -EINVAL;
> +
> +on_struct:
> +		s1 = btf_name_by_offset(btf1, t1->name_off);
> +		s2 = btf_name_by_offset(btf2, t2->name_off);
> +		if (strcmp(s1, s2))
> +			return -EINVAL;
> +next:
> +		if (i < nargs1) {
> +			t1 = btf_type_skip_modifiers(btf1, args1[i].type, NULL);
> +			offset += btf_type_is_ptr(t1) ? 8 : roundup(t1->size, 8);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static bool btf_is_dynptr_ptr(const struct btf *btf, const struct btf_type *t)
>  {
>  	const char *name;
> -- 
> 2.39.2
> 


From apatel at ventanamicro.com  Tue Feb 20 09:21:26 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Tue, 20 Feb 2024 22:51:26 +0530
Subject: [PATCH v13 08/13] irqchip/riscv-imsic: Add device MSI domain
 support for PCI devices
In-Reply-To: <8734tni7h3.ffs@tglx>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-9-apatel@ventanamicro.com> <8734tni7h3.ffs@tglx>
Message-ID: <CAK9=C2UgYpVtjFZ4NLzOCP6f3LQ=Fx7kPMywwQyFiNMcKmPyLw@mail.gmail.com>

On Tue, Feb 20, 2024 at 7:05?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> >  static bool imsic_init_dev_msi_info(struct device *dev,
> >                                   struct irq_domain *domain,
> >                                   struct irq_domain *real_parent,
> > @@ -218,6 +241,7 @@ static bool imsic_init_dev_msi_info(struct device *dev,
> >
> >       /* MSI parent domain specific settings */
> >       switch (real_parent->bus_token) {
> > +     case DOMAIN_BUS_PCI_MSI:
>
>         case DOMAIN_BUS_PCI_DEVICE_MSIX:
>
> ?

Actually, the DOMAIN_BUS_PCI_MSI is not needed because
the real parent domain is always the IMSIC base irq_domain
so DOMAIN_BUS_NEXUS is sufficient.

Better to just drop DOMAIN_BUS_PCI_MSI from this switch case ?

Regards,
Anup


From mgonzalez at freebox.fr  Tue Feb 20 09:29:49 2024
From: mgonzalez at freebox.fr (Marc Gonzalez)
Date: Tue, 20 Feb 2024 18:29:49 +0100
Subject: Calling OPTEE_SMC_CALL_GET_OS_UUID from driver code
Message-ID: <443901af-6abd-4a29-b6b6-f06b6d3ce34c@freebox.fr>

Hello,

The driver code I'm working on hard-codes

#define TEE_SMC_FAST_CALL_VAL(func_num) \
    ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
            ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))

#define TEE_SMC_FUNCID_CALLS_UID 0xFF01
#define TEE_SMC_CALLS_UID \
    ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
               ARM_SMCCC_OWNER_TRUSTED_OS_END, \
               TEE_SMC_FUNCID_CALLS_UID)

    arm_smccc_smc(TEE_SMC_CALLS_UID,
            0, 0, 0/*is_swap*/, 0, 0, 0, 0, &res);
    dev_err(dev, "TEE UID %x %x %x %x\n", res.a0, res.a1, res.a2, res.a3);


but it seems I would be required to somehow use
OPTEE_SMC_CALL_GET_OS_UUID

But it's not exported, and no code seems to use it...?

$ git grep OPTEE_SMC_CALL_GET_OS_UUID
Documentation/tee/op-tee.rst:- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
drivers/tee/optee/optee_smc.h:#define OPTEE_SMC_CALL_GET_OS_UUID \

How do I make calls to OP-TEE from driver code?

Regards,

Marc Gonzalez


From Frank.li at nxp.com  Tue Feb 20 09:38:55 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 12:38:55 -0500
Subject: [PATCH 1/1] dmaengine: mxs-dma: switch from dma_coherent to
 dma_pool
In-Reply-To: <CAOMZO5C4XFGoWYgexdFLgHiXAoAP7-aMdi=K6CG3adQE_mHAmA@mail.gmail.com>
References: <20240219155728.606497-1-Frank.Li@nxp.com>
 <CAOMZO5C4XFGoWYgexdFLgHiXAoAP7-aMdi=K6CG3adQE_mHAmA@mail.gmail.com>
Message-ID: <ZdTjrzYIiD8pwHk8@lizhi-Precision-Tower-5810>

On Mon, Feb 19, 2024 at 01:23:22PM -0300, Fabio Estevam wrote:
> On Mon, Feb 19, 2024 at 12:57?PM Frank Li <Frank.Li at nxp.com> wrote:
> >
> > From: Han Xu <han.xu at nxp.com>
> >
> > Using dma_pool to manage dma descriptor memory.
> 
> Please clearly describe the motivation for doing this.

This try to fix a cma_alloc failure. But it is not correct to use dma_pool.
let's work out a better method.

Frank


From brgl at bgdev.pl  Tue Feb 20 09:53:46 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 20 Feb 2024 18:53:46 +0100
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <CAA8EJppzkuH=YTAHuJ3Og2RLHB93PSas004UDvpqepYbGepVPg@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk> <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
 <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk> <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>
 <CAA8EJppzkuH=YTAHuJ3Og2RLHB93PSas004UDvpqepYbGepVPg@mail.gmail.com>
Message-ID: <CAMRc=MfXkG1bqGrtFWpoZo3fTY49TvU3sHOnX-zc2kjUiRfp3w@mail.gmail.com>

On Tue, Feb 20, 2024 at 5:30?PM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Tue, 20 Feb 2024 at 13:16, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> >
> > On Mon, Feb 19, 2024 at 8:59?PM Mark Brown <broonie at kernel.org> wrote:
> > >
> > > On Mon, Feb 19, 2024 at 07:48:20PM +0100, Bartosz Golaszewski wrote:
> > > > On Mon, Feb 19, 2024 at 7:03?PM Mark Brown <broonie at kernel.org> wrote:
> > > > > On Fri, Feb 16, 2024 at 09:32:06PM +0100, Bartosz Golaszewski wrote:
> > >
> > > > > > +                     vreg_pmu_aon_0p59: ldo1 {
> > > > > > +                             regulator-name = "vreg_pmu_aon_0p59";
> > > > > > +                             regulator-min-microvolt = <540000>;
> > > > > > +                             regulator-max-microvolt = <840000>;
> > > > > > +                     };
> > >
> > > > > That's a *very* wide voltage range for a supply that's got a name ending
> >
> > Because it's an error, it should have been 640000. Thanks for spotting it.
>
> According to the datasheet, VDD08_PMU_AON_O goes up to 0.85V then down
> to 0.59V, which is the working voltage.
>

Hmm indeed this is what figure 3.4 says but table 3-2 says the maximum is 0.64V.

> VDD08_PMU_RFA_CMN is normally at 0.8V, but goes to 0.4V during sleep.
>

Again figure 3.4 and table 3-2 disagree unless I'm missing something.

Bart

[snip]


From dmitry.baryshkov at linaro.org  Tue Feb 20 10:11:53 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 20 Feb 2024 20:11:53 +0200
Subject: [PATCH v5 09/18] arm64: dts: qcom: qrb5165-rb5: model the PMU of
 the QCA6391
In-Reply-To: <CAMRc=MfXkG1bqGrtFWpoZo3fTY49TvU3sHOnX-zc2kjUiRfp3w@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-10-brgl@bgdev.pl>
 <48164f18-34d0-4053-a416-2bb63aaae74b@sirena.org.uk> <CAMRc=Md7ymMTmF1OkydewF5C32jDNy0V+su7pcJPHKto6VLjLg@mail.gmail.com>
 <8e392aed-b5f7-486b-b5c0-5568e13796ec@sirena.org.uk> <CAMRc=MeAXEyV47nDO_WPQqEQxSYFWTrwVPAtLghkfONj56FGVA@mail.gmail.com>
 <CAA8EJppzkuH=YTAHuJ3Og2RLHB93PSas004UDvpqepYbGepVPg@mail.gmail.com> <CAMRc=MfXkG1bqGrtFWpoZo3fTY49TvU3sHOnX-zc2kjUiRfp3w@mail.gmail.com>
Message-ID: <CAA8EJpoY_2uNLXtC+xB9cOV5Tc5Bn5mEtJTf+sniWrN9HoEx4Q@mail.gmail.com>

On Tue, 20 Feb 2024 at 19:53, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> On Tue, Feb 20, 2024 at 5:30?PM Dmitry Baryshkov
> <dmitry.baryshkov at linaro.org> wrote:
> >
> > On Tue, 20 Feb 2024 at 13:16, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> > >
> > > On Mon, Feb 19, 2024 at 8:59?PM Mark Brown <broonie at kernel.org> wrote:
> > > >
> > > > On Mon, Feb 19, 2024 at 07:48:20PM +0100, Bartosz Golaszewski wrote:
> > > > > On Mon, Feb 19, 2024 at 7:03?PM Mark Brown <broonie at kernel.org> wrote:
> > > > > > On Fri, Feb 16, 2024 at 09:32:06PM +0100, Bartosz Golaszewski wrote:
> > > >
> > > > > > > +                     vreg_pmu_aon_0p59: ldo1 {
> > > > > > > +                             regulator-name = "vreg_pmu_aon_0p59";
> > > > > > > +                             regulator-min-microvolt = <540000>;
> > > > > > > +                             regulator-max-microvolt = <840000>;
> > > > > > > +                     };
> > > >
> > > > > > That's a *very* wide voltage range for a supply that's got a name ending
> > >
> > > Because it's an error, it should have been 640000. Thanks for spotting it.
> >
> > According to the datasheet, VDD08_PMU_AON_O goes up to 0.85V then down
> > to 0.59V, which is the working voltage.
> >
>
> Hmm indeed this is what figure 3.4 says but table 3-2 says the maximum is 0.64V.
>
> > VDD08_PMU_RFA_CMN is normally at 0.8V, but goes to 0.4V during sleep.
> >
>
> Again figure 3.4 and table 3-2 disagree unless I'm missing something.

I suspect that the table you have mentioned provides normal working
conditions for the PMU, while power-up and sleep might be outside of
'normal' conditions.

I suppose that these outputs are underspecified in the datasheet. I
think we can omit the values here.

-- 
With best wishes
Dmitry


From catalin.marinas at arm.com  Tue Feb 20 10:19:55 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 20 Feb 2024 18:19:55 +0000
Subject: [PATCH 0/3] arm64: cleanup DAIF handling for EL0 returns
In-Reply-To: <20240206123848.1696480-1-mark.rutland@arm.com>
References: <20240206123848.1696480-1-mark.rutland@arm.com>
Message-ID: <170845318453.792782.13779841930969118977.b4-ty@arm.com>

On Tue, 06 Feb 2024 12:38:45 +0000, Mark Rutland wrote:
> These patches rework DAIF handling when returning to EL0, simplifiying
> the logic in do_notify_resume() and allowing Debug + SError to be
> unmasked for a little longer during exception return.
> 
> My primary motivation for these changes is to centralize entry/exit DAIF
> management within entry-common.c, as this will allow entry/exit
> sequences to be specialised, and make it much easier to add support for
> FEAT_NMI. With specialized entry DAIF management, it will also be
> possible to simplify local_daif_{save,restore}() and
> local_irq_{save,restore}().
> 
> [...]

Applied to arm64 (for-next/daif-cleanup), thanks!

[1/3] arm64: Simplify do_notify_resume() DAIF masking
      https://git.kernel.org/arm64/c/270de609ae2a
[2/3] arm64: Move do_notify_resume() to entry-common.c
      https://git.kernel.org/arm64/c/997d79eb938e
[3/3] arm64: Unmask Debug + SError in do_notify_resume()
      https://git.kernel.org/arm64/c/97d935faacde

-- 
Catalin



From catalin.marinas at arm.com  Tue Feb 20 10:20:22 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 20 Feb 2024 18:20:22 +0000
Subject: [PATCH] arm64: io: permit offset addressing
In-Reply-To: <20240124111259.874975-1-mark.rutland@arm.com>
References: <20240124111259.874975-1-mark.rutland@arm.com>
Message-ID: <170845320583.794794.9144359816419029097.b4-ty@arm.com>

On Wed, 24 Jan 2024 11:12:59 +0000, Mark Rutland wrote:
> Currently our IO accessors all use register addressing without offsets,
> but we could safely use offset addressing (without writeback) to
> simplify and optimize the generated code.
> 
> To function correctly under a hypervisor which emulates IO accesses, we
> must ensure that any faulting/trapped IO access results in an ESR_ELx
> value with ESR_ELX.ISS.ISV=1 and with the tranfer register described in
> ESR_ELx.ISS.SRT. This means that we can only use loads/stores of a
> single general purpose register (or the zero register), and must avoid
> writeback addressing modes. However, we can use immediate offset
> addressing modes, as these still provide ESR_ELX.ISS.ISV=1 and a valid
> ESR_ELx.ISS.SRT when those accesses fault at Stage-2.
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: io: permit offset addressing
      https://git.kernel.org/arm64/c/d044d6ba6f02

-- 
Catalin



From catalin.marinas at arm.com  Tue Feb 20 10:20:35 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 20 Feb 2024 18:20:35 +0000
Subject: [PATCH] arm64: kretprobes: acquire the regs via a BRK exception
In-Reply-To: <20240208145916.2004154-1-mark.rutland@arm.com>
References: <20240208145916.2004154-1-mark.rutland@arm.com>
Message-ID: <170845320585.794794.15357244562847495105.b4-ty@arm.com>

On Thu, 08 Feb 2024 14:59:16 +0000, Mark Rutland wrote:
> On arm64, kprobes always take an exception and so create a struct
> pt_regs through the usual exception entry logic. Similarly kretprobes
> taskes and exception for function entry, but for function returns it
> uses a trampoline which attempts to create a struct pt_regs without
> taking an exception.
> 
> This is problematic for a few reasons, including:
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: kretprobes: acquire the regs via a BRK exception
      https://git.kernel.org/arm64/c/253751233b19

-- 
Catalin



From catalin.marinas at arm.com  Tue Feb 20 10:20:46 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 20 Feb 2024 18:20:46 +0000
Subject: [PATCH] arm64: errata: Don't enable workarounds for "rare" errata by default
In-Reply-To: <20240209183916.25860-1-will@kernel.org>
References: <20240209183916.25860-1-will@kernel.org>
Message-ID: <170845320579.794794.18390669087282562358.b4-ty@arm.com>

On Fri, 09 Feb 2024 18:39:16 +0000, Will Deacon wrote:
> Arm classifies some of its CPU errata as "rare", indicating that the
> hardware error is unlikely to occur in practice. Given that the cost of
> errata workarounds can often be significant in terms of power and
> performance, don't enable workarounds for "rare" errata by default and
> update our documentation to reflect that.
> 
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: errata: Don't enable workarounds for "rare" errata by default
      https://git.kernel.org/arm64/c/8c10cc104b73

-- 
Catalin



From sinquersw at gmail.com  Tue Feb 20 10:22:42 2024
From: sinquersw at gmail.com (Kui-Feng Lee)
Date: Tue, 20 Feb 2024 10:22:42 -0800
Subject: [PATCH bpf-next 1/5] bpf: tracing: add support to record and
 check the accessed args
In-Reply-To: <20240220035105.34626-2-dongmenglong.8@bytedance.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
 <20240220035105.34626-2-dongmenglong.8@bytedance.com>
Message-ID: <81431b5d-0e0f-485a-a3ce-af8e63169552@gmail.com>



On 2/19/24 19:51, Menglong Dong wrote:
> In this commit, we add the 'accessed_args' field to struct bpf_prog_aux,
> which is used to record the accessed index of the function args in
> btf_ctx_access().
> 
> Meanwhile, we add the function btf_check_func_part_match() to compare the
> accessed function args of two function prototype. This function will be
> used in the following commit.
> 
> Signed-off-by: Menglong Dong <dongmenglong.8 at bytedance.com>
> ---
>   include/linux/bpf.h |   4 ++
>   kernel/bpf/btf.c    | 121 ++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 125 insertions(+)
> 
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index c7aa99b44dbd..0225b8dbdd9d 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1464,6 +1464,7 @@ struct bpf_prog_aux {
>   	const struct btf_type *attach_func_proto;
>   	/* function name for valid attach_btf_id */
>   	const char *attach_func_name;
> +	u64 accessed_args;
>   	struct bpf_prog **func;
>   	void *jit_data; /* JIT specific data. arch dependent */
>   	struct bpf_jit_poke_descriptor *poke_tab;
> @@ -2566,6 +2567,9 @@ struct bpf_reg_state;
>   int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog);
>   int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *prog,
>   			 struct btf *btf, const struct btf_type *t);
> +int btf_check_func_part_match(struct btf *btf1, const struct btf_type *t1,
> +			      struct btf *btf2, const struct btf_type *t2,
> +			      u64 func_args);
>   const char *btf_find_decl_tag_value(const struct btf *btf, const struct btf_type *pt,
>   				    int comp_idx, const char *tag_key);
>   int btf_find_next_decl_tag(const struct btf *btf, const struct btf_type *pt,
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 6ff0bd1a91d5..3a6931402fe4 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -6203,6 +6203,9 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
>   		/* skip first 'void *__data' argument in btf_trace_##name typedef */
>   		args++;
>   		nr_args--;
> +		prog->aux->accessed_args |= (1 << (arg + 1));
> +	} else {
> +		prog->aux->accessed_args |= (1 << arg);
>   	}
>   
>   	if (arg > nr_args) {
> @@ -7010,6 +7013,124 @@ int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *pr
>   	return btf_check_func_type_match(log, btf1, t1, btf2, t2);
>   }
>   
> +static u32 get_ctx_arg_total_size(struct btf *btf, const struct btf_type *t)
> +{
> +	const struct btf_param *args;
> +	u32 size = 0, nr_args;
> +	int i;
> +
> +	nr_args = btf_type_vlen(t);
> +	args = (const struct btf_param *)(t + 1);
> +	for (i = 0; i < nr_args; i++) {
> +		t = btf_type_skip_modifiers(btf, args[i].type, NULL);
> +		size += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
> +	}
> +
> +	return size;
> +}
> +
> +static int get_ctx_arg_idx_aligned(struct btf *btf, const struct btf_type *t,
> +				   int off)
> +{
> +	const struct btf_param *args;
> +	u32 offset = 0, nr_args;
> +	int i;
> +
> +	nr_args = btf_type_vlen(t);
> +	args = (const struct btf_param *)(t + 1);
> +	for (i = 0; i < nr_args; i++) {
> +		if (offset == off)
> +			return i;
> +
> +		t = btf_type_skip_modifiers(btf, args[i].type, NULL);
> +		offset += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
> +		if (offset > off)
> +			return -1;
> +	}
> +	return -1;
> +}

This one is very similar to get_ctx_arg_idx().
How about to refactor get_ctx_arg_idx() and share the code
between get_ctx_arg_idx() and get_ctx_arg_idx_aligned().

For example,

-static u32 get_ctx_arg_idx(struct btf *btf, const struct btf_type 
*func_proto,
-                          int off)
+static u32 _get_ctx_arg_idx(struct btf *btf, const struct btf_type 
*func_proto,
+                          int off, u32 *arg_off)
  {
         const struct btf_param *args;
         const struct btf_type *t;
         u32 offset = 0, nr_args;
         int i;

         if (!func_proto)
                 return off / 8;

         nr_args = btf_type_vlen(func_proto);
         args = (const struct btf_param *)(func_proto + 1);
         for (i = 0; i < nr_args; i++) {
+               if (arg_off)
+                       *arg_off = offset;
                 t = btf_type_skip_modifiers(btf, args[i].type, NULL);
                 offset += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
                 if (off < offset)
                         return i;
         }

+       if (arg_off)
+               *arg_off = offset;
         t = btf_type_skip_modifiers(btf, func_proto->type, NULL);
         offset += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
         if (off < offset)
                 return nr_args;

         return nr_args + 1;
  }

+static u32 get_ctx_arg_idx(struct btf *btf, const struct btf_type 
*func_proto,
+                          int off)
+{
+       return _get_ctx_arg_idx(btf, func_proto, off, NULL);
+}
+
+static u32 get_ctx_arg_idx_aligned(struct btf *btf,
+                                  const struct btf_type *func_proto,
+                                  int off)
+{
+       u32 arg_off;
+       u32 arg_idx = _get_ctx_arg_idx(btf, func_proto, off, &arg_off);
+       return arg_off == off ? arg_idx : -1;
+}
+

> +
> +/* This function is similar to btf_check_func_type_match(), except that it
> + * only compare some function args of the function prototype t1 and t2.
> + */
> +int btf_check_func_part_match(struct btf *btf1, const struct btf_type *func1,
> +			      struct btf *btf2, const struct btf_type *func2,
> +			      u64 func_args)
> +{
> +	const struct btf_param *args1, *args2;
> +	u32 nargs1, i, offset = 0;
> +	const char *s1, *s2;
> +
> +	if (!btf_type_is_func_proto(func1) || !btf_type_is_func_proto(func2))
> +		return -EINVAL;
> +
> +	args1 = (const struct btf_param *)(func1 + 1);
> +	args2 = (const struct btf_param *)(func2 + 1);
> +	nargs1 = btf_type_vlen(func1);
> +
> +	for (i = 0; i <= nargs1; i++) {
> +		const struct btf_type *t1, *t2;
> +
> +		if (!(func_args & (1 << i)))
> +			goto next;
> +
> +		if (i < nargs1) {
> +			int t2_index;
> +
> +			/* get the index of the arg corresponding to args1[i]
> +			 * by the offset.
> +			 */
> +			t2_index = get_ctx_arg_idx_aligned(btf2, func2,
> +							   offset);
> +			if (t2_index < 0)
> +				return -EINVAL;
> +
> +			t1 = btf_type_skip_modifiers(btf1, args1[i].type, NULL);
> +			t2 = btf_type_skip_modifiers(btf2, args2[t2_index].type,
> +						     NULL);
> +		} else {
> +			/* i == nargs1, this is the index of return value of t1 */
> +			if (get_ctx_arg_total_size(btf1, func1) !=
> +			    get_ctx_arg_total_size(btf2, func2))
> +				return -EINVAL;
> +
> +			/* check the return type of t1 and t2 */
> +			t1 = btf_type_skip_modifiers(btf1, func1->type, NULL);
> +			t2 = btf_type_skip_modifiers(btf2, func2->type, NULL);
> +		}
> +
> +		if (t1->info != t2->info ||
> +		    (btf_type_has_size(t1) && t1->size != t2->size))
> +			return -EINVAL;
> +		if (btf_type_is_int(t1) || btf_is_any_enum(t1))
> +			goto next;
> +
> +		if (btf_type_is_struct(t1))
> +			goto on_struct;
> +
> +		if (!btf_type_is_ptr(t1))
> +			return -EINVAL;
> +
> +		t1 = btf_type_skip_modifiers(btf1, t1->type, NULL);
> +		t2 = btf_type_skip_modifiers(btf2, t2->type, NULL);
> +		if (!btf_type_is_struct(t1) || !btf_type_is_struct(t2))
> +			return -EINVAL;
> +
> +on_struct:
> +		s1 = btf_name_by_offset(btf1, t1->name_off);
> +		s2 = btf_name_by_offset(btf2, t2->name_off);
> +		if (strcmp(s1, s2))
> +			return -EINVAL;
> +next:
> +		if (i < nargs1) {
> +			t1 = btf_type_skip_modifiers(btf1, args1[i].type, NULL);
> +			offset += btf_type_is_ptr(t1) ? 8 : roundup(t1->size, 8);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>   static bool btf_is_dynptr_ptr(const struct btf *btf, const struct btf_type *t)
>   {
>   	const char *name;


From rick.p.edgecombe at intel.com  Tue Feb 20 10:41:05 2024
From: rick.p.edgecombe at intel.com (Edgecombe, Rick P)
Date: Tue, 20 Feb 2024 18:41:05 +0000
Subject: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in userspace
In-Reply-To: <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
	 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
Message-ID: <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>

Hi,

I worked on the x86 kernel shadow stack support. I think it is an
interesting suggestion. Some questions below, and I will think more on
it.

On Tue, 2024-02-20 at 11:36 -0500, Stefan O'Rear wrote:
> While discussing the ABI implications of shadow stacks in the context
> of
> Zicfiss and musl a few days ago, I had the following idea for how to
> solve
> the source compatibility problems with shadow stacks in POSIX.1-2004
> and
> POSIX.1-2017:
> 
> 1. Introduce a "flexible shadow stack handling" option.? For what
> follows,
> ?? it doesn't matter if this is system-wide, per-mm, or per-vma.
> 
> 2. Shadow stack faults on non-shadow stack pages, if flexible shadow
> stack
> ?? handling is in effect, cause the affected page to become a shadow
> stack
> ?? page.? When this happens, the page filled with invalid address
> tokens.

Hmm, could the shadow stack underflow onto the real stack then? Not
sure how bad that is. INCSSP (incrementing the SSP register on x86)
loops are not rare so it seems like something that could happen.

> 
> ?? Faults from non-shadow-stack accesses to a shadow-stack page which
> was
> ?? created by the previous paragraph will cause the page to revert to
> ?? non-shadow-stack usage, with or without clearing.

Won't this prevent catching stack overflows when they happen? An
overflow will just turn the shadow stack into normal stack and only get
detected when the shadow stack unwinds?

A related question would be how to handle the expanding nature of the
initial stack. I guess the initial stack could be special and have a
separate shadow stack.

> 
> ?? Important: a shadow stack operation can only load a valid address
> from
> ?? a page if that page has been in continuous shadow stack use since
> the
> ?? address was written by another shadow stack operation; the
> flexibility
> ?? delays error reporting in cases of stray writes but it never
> allows for
> ?? corruption of shadow stack operation.

Shadow stacks currently have automatic guard gaps to try to prevent one
thread from overflowing onto another thread's shadow stack. This would
somewhat opens that up, as the stack guard gaps are usually maintained
by userspace for new threads. It would have to be thought through if
these could still be enforced with checking at additional spots.

> 
> 3. Standards-defined operations which use a user-provided stack
> ?? (makecontext, sigaltstack, pthread_attr_setstack) use a subrange
> of the
> ?? provided stack for shadow stack storage.? I propose to use a
> shadow
> ?? stack size of 1/32 of the provided stack size, rounded up to a
> positive
> ?? integer number of pages, and place the shadow stack allocation at
> the
> ?? lowest page-aligned address inside the provided stack region.
> 
> ?? Since page usage is flexible, no change in page permissions is
> ?? immediately needed; this merely sets the initial shadow stack
> pointer for
> ?? the new context.
> 
> ?? If the shadow stack grew in the opposite direction to the
> architectural
> ?? stack, it would not be necessary to pick a fixed direction.
> 
> 4. SIGSTKSZ and MINSIGSTKSZ are increased by 2 pages to provide
> sufficient
> ?? space for a minimum-sized shadow stack region and worst case
> alignment.

Do all makecontext() callers ensure the size is greater than this?

I guess glibc's makecontext() could do this scheme to prevent leaking
without any changes to the kernel. Basically steal a little of the
stack address range and overwrite it with a shadow stack mapping. But
only if the apps leave enough room. If they need to be updated, then
they could be updated to manage their own shadow stacks too I think.

> 
> _Without_ doing this, sigaltstack cannot be used to recover from
> stack
> overflows if the shadow stack limit is reached first, and makecontext
> cannot be supported without memory leaks and unreportable error
> conditions.

FWIW, I think the makecontext() shadow stack leaking is a bad idea. I
would prefer the existing makecontext() interface just didn't support
shadow stack, rather than the leaking solution glibc does today.

The situation (for arm and riscv too I think?) is that some
applications will just not work automatically due to custom stack
switching implementations. (user level threading libraries, JITs, etc).
So?I think it should be ok to ask for apps to change to enable shadow
stack and we should avoid doing anything too awkward in pursuit of
getting it to work completely transparently.

For ucontext, there was some discussion about implementing changes to
the interface makecontext() interface that allows the app to allocate
and manage their own shadow stacks. So they would be responsible for
freeing and allocating the shadow stacks. It seems a little more
straightforward.


For x86, due to some existing GCC binaries that jumped ahead of the
kernel support, it will likely require an ABI opt-in to enable alt
shadow stacks. So alt shadow stack support design is still pretty open
on the x86 side. Very glad to get broader input on it.

> 
> Kernel-allocated shadow stacks with a unique VM type are still useful
> since
> they allows stray writes to crash at the time the stray write is
> performed,
> rather than delaying the crash until the next shadow stack read.
> 
> The pthread and makecontext changes could be purely libc side, but we
> would
> need kernel support for sigaltstack and page usage changes.
> 
> Luckily, there is no need to support stacks which are simultaneously
> used
> from more than one process, so "is this a shadow stack page" can be
> tracked
> purely at the vma/pte level without any need to involve the inode.?
> POSIX
> explicitly allows using mmap to obtain stack memory and does not
> forbid
> MAP_SHARED; I consider this sufficiently perverse application
> behavior that
> it is not necessary to ensure exclusive use of the underlying pages
> while
> a shadow stack pte exists.? (Applications that use MAP_SHARED for
> stacks
> do not get the full benefit of the shadow stack but they keep
> POSIX.1-2004
> conformance, applications that allocate stacks exclusively in
> MAP_PRIVATE
> memory lose no security.)

On x86 we don't support MAP_SHARED shadow stacks. There is a whole
snarl around the dirty bit in the PTE. I'm not sure it's impossible but
it was gladly avoided. There is also a benefit in avoiding having them
get mapped as writable in a different context.

> 
> The largest complication of this scheme is likely to be that the
> shadow
> stack usage property of a page needs to survive the page being
> swapped out
> and back in, which likely means that it must be present in the swap
> PTE.
> 
> I am substantially less familiar with GCS and SHSTK than with
> Zicfiss.
> It is likely that a syscall or other mechanism is needed to
> initialize the
> shadow stack in flexible memory for makecontext.

The ucontext stacks (and alt shadow stacks is the plan) need to have a
"restore token". So, yea, you would probably need some syscall to
"convert" the normal stack memory into shadow stack with a restore
token.

> 
> Is there interest on the kernel side on having mechanisms to fully
> support
> POSIX.1-2004 with GCS or Zicfiss enabled?

Can you clarify, is the goal to meet compatibility with the spec or try
to make more apps run with shadow stack automatically?

From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:06 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:06 +0100
Subject: [PATCH net-next v8 03/13] net: phy: add helpers to handle sfp phy connect/disconnect
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-4-maxime.chevallier@bootlin.com>

There are a few PHY drivers that can handle SFP modules through their
sfp_upstream_ops. Introduce Phylib helpers to keep track of connected
SFP PHYs in a netdevice's namespace, by adding the SFP PHY to the
upstream PHY's netdev's namespace.

By doing so, these SFP PHYs can be enumerated and exposed to users,
which will be able to use their capabilities.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V8: Took the at803x into account
V7: No changes
V6: Moved phy_get_link_topology() definition to this patch
V5: No Changes
V4: Rebased the at803x part with the newer version on net-next
V3: Renaming
V2: Renaming

 drivers/net/phy/marvell-88x2222.c |  2 ++
 drivers/net/phy/marvell.c         |  2 ++
 drivers/net/phy/marvell10g.c      |  2 ++
 drivers/net/phy/phy_device.c      | 48 +++++++++++++++++++++++++++++++
 drivers/net/phy/qcom/at803x.c     |  2 ++
 drivers/net/phy/qcom/qca807x.c    |  2 ++
 include/linux/phy.h               |  2 ++
 7 files changed, 60 insertions(+)

diff --git a/drivers/net/phy/marvell-88x2222.c b/drivers/net/phy/marvell-88x2222.c
index e3aa30dad2e6..3f77bbc7e04f 100644
--- a/drivers/net/phy/marvell-88x2222.c
+++ b/drivers/net/phy/marvell-88x2222.c
@@ -555,6 +555,8 @@ static const struct sfp_upstream_ops sfp_phy_ops = {
 	.link_down = mv2222_sfp_link_down,
 	.attach = phy_sfp_attach,
 	.detach = phy_sfp_detach,
+	.connect_phy = phy_sfp_connect_phy,
+	.disconnect_phy = phy_sfp_disconnect_phy,
 };
 
 static int mv2222_probe(struct phy_device *phydev)
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 1faa22f58366..c26d20bdac51 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -3254,6 +3254,8 @@ static const struct sfp_upstream_ops m88e1510_sfp_ops = {
 	.module_remove = m88e1510_sfp_remove,
 	.attach = phy_sfp_attach,
 	.detach = phy_sfp_detach,
+	.connect_phy = phy_sfp_connect_phy,
+	.disconnect_phy = phy_sfp_disconnect_phy,
 };
 
 static int m88e1510_probe(struct phy_device *phydev)
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index ad43e280930c..6642eb642d4b 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -503,6 +503,8 @@ static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
 static const struct sfp_upstream_ops mv3310_sfp_ops = {
 	.attach = phy_sfp_attach,
 	.detach = phy_sfp_detach,
+	.connect_phy = phy_sfp_connect_phy,
+	.disconnect_phy = phy_sfp_disconnect_phy,
 	.module_insert = mv3310_sfp_insert,
 };
 
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 8478199f2d89..d47a2aa6ce87 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -277,6 +277,14 @@ static void phy_mdio_device_remove(struct mdio_device *mdiodev)
 
 static struct phy_driver genphy_driver;
 
+static struct phy_link_topology *phy_get_link_topology(struct phy_device *phydev)
+{
+	if (phydev->attached_dev)
+		return phydev->attached_dev->link_topo;
+
+	return NULL;
+}
+
 static LIST_HEAD(phy_fixup_list);
 static DEFINE_MUTEX(phy_fixup_lock);
 
@@ -1370,6 +1378,46 @@ phy_standalone_show(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RO(phy_standalone);
 
+/**
+ * phy_sfp_connect_phy - Connect the SFP module's PHY to the upstream PHY
+ * @upstream: pointer to the upstream phy device
+ * @phy: pointer to the SFP module's phy device
+ *
+ * This helper allows keeping track of PHY devices on the link. It adds the
+ * SFP module's phy to the phy namespace of the upstream phy
+ */
+int phy_sfp_connect_phy(void *upstream, struct phy_device *phy)
+{
+	struct phy_device *phydev = upstream;
+	struct phy_link_topology *topo = phy_get_link_topology(phydev);
+
+	if (topo)
+		return phy_link_topo_add_phy(topo, phy, PHY_UPSTREAM_PHY, phydev);
+
+	return 0;
+}
+EXPORT_SYMBOL(phy_sfp_connect_phy);
+
+/**
+ * phy_sfp_disconnect_phy - Disconnect the SFP module's PHY from the upstream PHY
+ * @upstream: pointer to the upstream phy device
+ * @phy: pointer to the SFP module's phy device
+ *
+ * This helper allows keeping track of PHY devices on the link. It removes the
+ * SFP module's phy to the phy namespace of the upstream phy. As the module phy
+ * will be destroyed, re-inserting the same module will add a new phy with a
+ * new index.
+ */
+void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy)
+{
+	struct phy_device *phydev = upstream;
+	struct phy_link_topology *topo = phy_get_link_topology(phydev);
+
+	if (topo)
+		phy_link_topo_del_phy(topo, phy);
+}
+EXPORT_SYMBOL(phy_sfp_disconnect_phy);
+
 /**
  * phy_sfp_attach - attach the SFP bus to the PHY upstream network device
  * @upstream: pointer to the phy device
diff --git a/drivers/net/phy/qcom/at803x.c b/drivers/net/phy/qcom/at803x.c
index 4717c59d51d0..235d242076cb 100644
--- a/drivers/net/phy/qcom/at803x.c
+++ b/drivers/net/phy/qcom/at803x.c
@@ -769,6 +769,8 @@ static const struct sfp_upstream_ops at8031_sfp_ops = {
 	.attach = phy_sfp_attach,
 	.detach = phy_sfp_detach,
 	.module_insert = at8031_sfp_insert,
+	.connect_phy = phy_sfp_connect_phy,
+	.disconnect_phy = phy_sfp_disconnect_phy,
 };
 
 static int at8031_parse_dt(struct phy_device *phydev)
diff --git a/drivers/net/phy/qcom/qca807x.c b/drivers/net/phy/qcom/qca807x.c
index 780c28e2e4aa..0ff16122c3d9 100644
--- a/drivers/net/phy/qcom/qca807x.c
+++ b/drivers/net/phy/qcom/qca807x.c
@@ -699,6 +699,8 @@ static const struct sfp_upstream_ops qca807x_sfp_ops = {
 	.detach = phy_sfp_detach,
 	.module_insert = qca807x_sfp_insert,
 	.module_remove = qca807x_sfp_remove,
+	.connect_phy = phy_sfp_connect_phy,
+	.disconnect_phy = phy_sfp_disconnect_phy,
 };
 
 static int qca807x_probe(struct phy_device *phydev)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 236b95472865..eb505097bc9f 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1752,6 +1752,8 @@ int phy_suspend(struct phy_device *phydev);
 int phy_resume(struct phy_device *phydev);
 int __phy_resume(struct phy_device *phydev);
 int phy_loopback(struct phy_device *phydev, bool enable);
+int phy_sfp_connect_phy(void *upstream, struct phy_device *phy);
+void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy);
 void phy_sfp_attach(void *upstream, struct sfp_bus *bus);
 void phy_sfp_detach(void *upstream, struct sfp_bus *bus);
 int phy_sfp_probe(struct phy_device *phydev,
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:05 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:05 +0100
Subject: [PATCH net-next v8 02/13] net: sfp: pass the phy_device when disconnecting an sfp module's PHY
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-3-maxime.chevallier@bootlin.com>

Pass the phy_device as a parameter to the sfp upstream .disconnect_phy
operation. This is preparatory work to help track phy devices across
a net_device's link.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V8: No changes
V7: No changes
V6: Moved an incorrectly added hunk from the previous series to patch 0003
V5: No changes
V4: No changes
V3: No changes

 drivers/net/phy/phylink.c | 3 ++-
 drivers/net/phy/sfp-bus.c | 4 ++--
 include/linux/sfp.h       | 2 +-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 503fd7c40523..8a34883eb99b 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -3385,7 +3385,8 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
 	return ret;
 }
 
-static void phylink_sfp_disconnect_phy(void *upstream)
+static void phylink_sfp_disconnect_phy(void *upstream,
+				       struct phy_device *phydev)
 {
 	phylink_disconnect_phy(upstream);
 }
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index db39dec7f247..e05013aeecc3 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -486,7 +486,7 @@ static void sfp_unregister_bus(struct sfp_bus *bus)
 			bus->socket_ops->stop(bus->sfp);
 		bus->socket_ops->detach(bus->sfp);
 		if (bus->phydev && ops && ops->disconnect_phy)
-			ops->disconnect_phy(bus->upstream);
+			ops->disconnect_phy(bus->upstream, bus->phydev);
 	}
 	bus->registered = false;
 }
@@ -742,7 +742,7 @@ void sfp_remove_phy(struct sfp_bus *bus)
 	const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
 
 	if (ops && ops->disconnect_phy)
-		ops->disconnect_phy(bus->upstream);
+		ops->disconnect_phy(bus->upstream, bus->phydev);
 	bus->phydev = NULL;
 }
 EXPORT_SYMBOL_GPL(sfp_remove_phy);
diff --git a/include/linux/sfp.h b/include/linux/sfp.h
index 9346cd44814d..0573e53b0c11 100644
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -544,7 +544,7 @@ struct sfp_upstream_ops {
 	void (*link_down)(void *priv);
 	void (*link_up)(void *priv);
 	int (*connect_phy)(void *priv, struct phy_device *);
-	void (*disconnect_phy)(void *priv);
+	void (*disconnect_phy)(void *priv, struct phy_device *);
 };
 
 #if IS_ENABLED(CONFIG_SFP)
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:03 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:03 +0100
Subject: [PATCH net-next v8 00/13] Introduce PHY listing and link_topology tracking
Message-ID: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>

Hello everyone,

This is V8 for the link topology addition, allowing to track all PHYs
that are linked to netdevices. V8 is merely V7 rebased on net-next with
a few basic adaptations due to the at803x driver split. I'm leaving the
V7 explanations below still.

In V7 was introduced the protection of the main internal API
entrypoints (link_topo_init/cleanup, link_topo_add/del_phy) by
IS_REACHABLE(CONFIG_PHYLIB).

That's restrictive, but it looks difficult to do otherwise while still keep the
data structure opaque and not add dependency clutter with PHYLIB.

As you can tell, I'm unsure about this, so please don't hesitate to
comment on that part :)

The other changes are very minor, the only one is a call to netdev_put
in the .done() netlink callback.

As a remainder, here's what the PHY listings would look like :
 - eth0 has a 88x3310 acting as media converter, and an SFP module with
   an embedded 88e1111 PHY
 - eth2 has a 88e1510 PHY

# ethtool --show-phys *

PHY for eth0:
PHY index: 1
Driver name: mv88x3310
PHY device name: f212a600.mdio-mii:00
Downstream SFP bus name: sfp-eth0
PHY id: 0
Upstream type: MAC

PHY for eth0:
PHY index: 2
Driver name: Marvell 88E1111
PHY device name: i2c:sfp-eth0:16
PHY id: 21040322
Upstream type: PHY
Upstream PHY index: 1
Upstream SFP name: sfp-eth0

PHY for eth2:
PHY index: 1
Driver name: Marvell 88E1510
PHY device name: f212a200.mdio-mii:00
PHY id: 21040593
Upstream type: MAC

Ethtool patches : https://github.com/minimaxwell/ethtool/tree/link-topo-v6

Link to V7: https://lore.kernel.org/netdev/20240213150431.1796171-1-maxime.chevallier at bootlin.com/
Link to V6: https://lore.kernel.org/netdev/20240126183851.2081418-1-maxime.chevallier at bootlin.com/
Link to V5: https://lore.kernel.org/netdev/20231221180047.1924733-1-maxime.chevallier at bootlin.com/
Link to V4: https://lore.kernel.org/netdev/20231215171237.1152563-1-maxime.chevallier at bootlin.com/
Link to V3: https://lore.kernel.org/netdev/20231201163704.1306431-1-maxime.chevallier at bootlin.com/
Link to V2: https://lore.kernel.org/netdev/20231117162323.626979-1-maxime.chevallier at bootlin.com/
Link to V1: https://lore.kernel.org/netdev/20230907092407.647139-1-maxime.chevallier at bootlin.com/

Maxime Chevallier (13):
  net: phy: Introduce ethernet link topology representation
  net: sfp: pass the phy_device when disconnecting an sfp module's PHY
  net: phy: add helpers to handle sfp phy connect/disconnect
  net: sfp: Add helper to return the SFP bus name
  net: ethtool: Allow passing a phy index for some commands
  netlink: specs: add phy-index as a header parameter
  net: ethtool: Introduce a command to list PHYs on an interface
  netlink: specs: add ethnl PHY_GET command set
  net: ethtool: plca: Target the command to the requested PHY
  net: ethtool: pse-pd: Target the command to the requested PHY
  net: ethtool: cable-test: Target the command to the requested PHY
  net: ethtool: strset: Allow querying phy stats by index
  Documentation: networking: document phy_link_topology

 Documentation/netlink/specs/ethtool.yaml      |  62 ++++
 Documentation/networking/ethtool-netlink.rst  |  46 +++
 Documentation/networking/index.rst            |   1 +
 .../networking/phy-link-topology.rst          | 121 +++++++
 MAINTAINERS                                   |   2 +
 drivers/net/phy/Makefile                      |   2 +-
 drivers/net/phy/marvell-88x2222.c             |   2 +
 drivers/net/phy/marvell.c                     |   2 +
 drivers/net/phy/marvell10g.c                  |   2 +
 drivers/net/phy/phy_device.c                  |  55 ++++
 drivers/net/phy/phy_link_topology.c           | 105 +++++++
 drivers/net/phy/phylink.c                     |   3 +-
 drivers/net/phy/qcom/at803x.c                 |   2 +
 drivers/net/phy/qcom/qca807x.c                |   2 +
 drivers/net/phy/sfp-bus.c                     |  15 +-
 include/linux/netdevice.h                     |   4 +-
 include/linux/phy.h                           |   6 +
 include/linux/phy_link_topology.h             |  72 +++++
 include/linux/phy_link_topology_core.h        |  25 ++
 include/linux/sfp.h                           |   8 +-
 include/uapi/linux/ethtool.h                  |  16 +
 include/uapi/linux/ethtool_netlink.h          |  21 ++
 net/core/dev.c                                |   9 +
 net/ethtool/Makefile                          |   2 +-
 net/ethtool/cabletest.c                       |  16 +-
 net/ethtool/netlink.c                         |  53 +++-
 net/ethtool/netlink.h                         |  10 +
 net/ethtool/phy.c                             | 297 ++++++++++++++++++
 net/ethtool/plca.c                            |  19 +-
 net/ethtool/pse-pd.c                          |  13 +-
 net/ethtool/strset.c                          |  17 +-
 31 files changed, 967 insertions(+), 43 deletions(-)
 create mode 100644 Documentation/networking/phy-link-topology.rst
 create mode 100644 drivers/net/phy/phy_link_topology.c
 create mode 100644 include/linux/phy_link_topology.h
 create mode 100644 include/linux/phy_link_topology_core.h
 create mode 100644 net/ethtool/phy.c

-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:04 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:04 +0100
Subject: [PATCH net-next v8 01/13] net: phy: Introduce ethernet link topology representation
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-2-maxime.chevallier@bootlin.com>

Link topologies containing multiple network PHYs attached to the same
net_device can be found when using a PHY as a media converter for use
with an SFP connector, on which an SFP transceiver containing a PHY can
be used.

With the current model, the transceiver's PHY can't be used for
operations such as cable testing, timestamping, macsec offload, etc.

The reason being that most of the logic for these configuration, coming
from either ethtool netlink or ioctls tend to use netdev->phydev, which
in multi-phy systems will reference the PHY closest to the MAC.

Introduce a numbering scheme allowing to enumerate PHY devices that
belong to any netdev, which can in turn allow userspace to take more
precise decisions with regard to each PHY's configuration.

The numbering is maintained per-netdev, in a phy_device_list.
The numbering works similarly to a netdevice's ifindex, with
identifiers that are only recycled once INT_MAX has been reached.

This prevents races that could occur between PHY listing and SFP
transceiver removal/insertion.

The identifiers are assigned at phy_attach time, as the numbering
depends on the netdevice the phy is attached to. The PHY index can be
re-used for PHYs that are persistent.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V8: - Rebase on net-next and fixed conflicts
V7: - Protected the phy_link_topo helpers/stubs with IS_REACHABLE
V6: - Made link_topo a pointer
    - Reworked the init/cleanup sequence
    - Added phy_index recycling if possible
V5: - Dropped the ASSERT_RTNL()
    - Made the phy_link_topo_get_phy inline
V4: - Moved the phy_link_topo_init() code to an inline header function
    - Made the code build without phylib
V3: - Renamed to phy_link_topology
    - Added assertions for RTNL
    - Various cleanups of leftover, unused test code
    - Made the PHY index u32

 MAINTAINERS                            |   2 +
 drivers/net/phy/Makefile               |   2 +-
 drivers/net/phy/phy_device.c           |   7 ++
 drivers/net/phy/phy_link_topology.c    | 105 +++++++++++++++++++++++++
 include/linux/netdevice.h              |   4 +-
 include/linux/phy.h                    |   4 +
 include/linux/phy_link_topology.h      |  72 +++++++++++++++++
 include/linux/phy_link_topology_core.h |  25 ++++++
 include/uapi/linux/ethtool.h           |  16 ++++
 net/core/dev.c                         |   9 +++
 10 files changed, 244 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/phy/phy_link_topology.c
 create mode 100644 include/linux/phy_link_topology.h
 create mode 100644 include/linux/phy_link_topology_core.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ac771f6e4a3a..7f60f14a2be7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7948,6 +7948,8 @@ F:	include/linux/mii.h
 F:	include/linux/of_net.h
 F:	include/linux/phy.h
 F:	include/linux/phy_fixed.h
+F:	include/linux/phy_link_topology.h
+F:	include/linux/phy_link_topology_core.h
 F:	include/linux/phylib_stubs.h
 F:	include/linux/platform_data/mdio-bcm-unimac.h
 F:	include/linux/platform_data/mdio-gpio.h
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 197acfa0b412..9dff825145e4 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -2,7 +2,7 @@
 # Makefile for Linux PHY drivers
 
 libphy-y			:= phy.o phy-c45.o phy-core.o phy_device.o \
-				   linkmode.o
+				   linkmode.o phy_link_topology.o
 mdio-bus-y			+= mdio_bus.o mdio_device.o
 
 ifdef CONFIG_MDIO_DEVICE
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 2eefee970851..8478199f2d89 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -29,6 +29,7 @@
 #include <linux/phy.h>
 #include <linux/phylib_stubs.h>
 #include <linux/phy_led_triggers.h>
+#include <linux/phy_link_topology.h>
 #include <linux/pse-pd/pse.h>
 #include <linux/property.h>
 #include <linux/rtnetlink.h>
@@ -1511,6 +1512,11 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 
 		if (phydev->sfp_bus_attached)
 			dev->sfp_bus = phydev->sfp_bus;
+
+		err = phy_link_topo_add_phy(dev->link_topo, phydev,
+					    PHY_UPSTREAM_MAC, dev);
+		if (err)
+			goto error;
 	}
 
 	/* Some Ethernet drivers try to connect to a PHY device before
@@ -1938,6 +1944,7 @@ void phy_detach(struct phy_device *phydev)
 	if (dev) {
 		phydev->attached_dev->phydev = NULL;
 		phydev->attached_dev = NULL;
+		phy_link_topo_del_phy(dev->link_topo, phydev);
 	}
 	phydev->phylink = NULL;
 
diff --git a/drivers/net/phy/phy_link_topology.c b/drivers/net/phy/phy_link_topology.c
new file mode 100644
index 000000000000..985941c5c558
--- /dev/null
+++ b/drivers/net/phy/phy_link_topology.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Infrastructure to handle all PHY devices connected to a given netdev,
+ * either directly or indirectly attached.
+ *
+ * Copyright (c) 2023 Maxime Chevallier<maxime.chevallier at bootlin.com>
+ */
+
+#include <linux/phy_link_topology.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/rtnetlink.h>
+#include <linux/xarray.h>
+
+struct phy_link_topology *phy_link_topo_create(struct net_device *dev)
+{
+	struct phy_link_topology *topo;
+
+	topo = kzalloc(sizeof(*topo), GFP_KERNEL);
+	if (!topo)
+		return ERR_PTR(-ENOMEM);
+
+	xa_init_flags(&topo->phys, XA_FLAGS_ALLOC1);
+	topo->next_phy_index = 1;
+
+	return topo;
+}
+
+void phy_link_topo_destroy(struct phy_link_topology *topo)
+{
+	if (!topo)
+		return;
+
+	xa_destroy(&topo->phys);
+	kfree(topo);
+}
+
+int phy_link_topo_add_phy(struct phy_link_topology *topo,
+			  struct phy_device *phy,
+			  enum phy_upstream upt, void *upstream)
+{
+	struct phy_device_node *pdn;
+	int ret;
+
+	pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
+	if (!pdn)
+		return -ENOMEM;
+
+	pdn->phy = phy;
+	switch (upt) {
+	case PHY_UPSTREAM_MAC:
+		pdn->upstream.netdev = (struct net_device *)upstream;
+		if (phy_on_sfp(phy))
+			pdn->parent_sfp_bus = pdn->upstream.netdev->sfp_bus;
+		break;
+	case PHY_UPSTREAM_PHY:
+		pdn->upstream.phydev = (struct phy_device *)upstream;
+		if (phy_on_sfp(phy))
+			pdn->parent_sfp_bus = pdn->upstream.phydev->sfp_bus;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+	pdn->upstream_type = upt;
+
+	/* Attempt to re-use a previously allocated phy_index */
+	if (phy->phyindex) {
+		ret = xa_insert(&topo->phys, phy->phyindex, pdn, GFP_KERNEL);
+
+		/* Errors could be either -ENOMEM or -EBUSY. If the phy has an
+		 * index, and there's another entry at the same index, this is
+		 * unexpected and we still error-out
+		 */
+		if (ret)
+			goto err;
+		return 0;
+	}
+
+	ret = xa_alloc_cyclic(&topo->phys, &phy->phyindex, pdn, xa_limit_32b,
+			      &topo->next_phy_index, GFP_KERNEL);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	kfree(pdn);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(phy_link_topo_add_phy);
+
+void phy_link_topo_del_phy(struct phy_link_topology *topo,
+			   struct phy_device *phy)
+{
+	struct phy_device_node *pdn = xa_erase(&topo->phys, phy->phyindex);
+
+	/* We delete the PHY from the topology, however we don't re-set the
+	 * phy->phyindex field. If the PHY isn't gone, we can re-assign it the
+	 * same index next time it's added back to the topology
+	 */
+
+	kfree(pdn);
+}
+EXPORT_SYMBOL_GPL(phy_link_topo_del_phy);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f07c8374f29c..1e38cfd8f540 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -40,7 +40,6 @@
 #include <net/dcbnl.h>
 #endif
 #include <net/netprio_cgroup.h>
-
 #include <linux/netdev_features.h>
 #include <linux/neighbour.h>
 #include <uapi/linux/netdevice.h>
@@ -52,6 +51,7 @@
 #include <net/net_trackers.h>
 #include <net/net_debug.h>
 #include <net/dropreason-core.h>
+#include <linux/phy_link_topology_core.h>
 
 struct netpoll_info;
 struct device;
@@ -2056,6 +2056,7 @@ enum netdev_reg_state {
  *	@fcoe_ddp_xid:	Max exchange id for FCoE LRO by ddp
  *
  *	@priomap:	XXX: need comments on this one
+ *	@link_topo:	Physical link topology tracking attached PHYs
  *	@phydev:	Physical device may attach itself
  *			for hardware timestamping
  *	@sfp_bus:	attached &struct sfp_bus structure.
@@ -2444,6 +2445,7 @@ struct net_device {
 #if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
 	struct netprio_map __rcu *priomap;
 #endif
+	struct phy_link_topology	*link_topo;
 	struct phy_device	*phydev;
 	struct sfp_bus		*sfp_bus;
 	struct lock_class_key	*qdisc_tx_busylock;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index e3ab2c347a59..236b95472865 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -549,6 +549,9 @@ struct macsec_ops;
  * @drv: Pointer to the driver for this PHY instance
  * @devlink: Create a link between phy dev and mac dev, if the external phy
  *           used by current mac interface is managed by another mac interface.
+ * @phyindex: Unique id across the phy's parent tree of phys to address the PHY
+ *	      from userspace, similar to ifindex. A zero index means the PHY
+ *	      wasn't assigned an id yet.
  * @phy_id: UID for this device found during discovery
  * @c45_ids: 802.3-c45 Device Identifiers if is_c45.
  * @is_c45:  Set to true if this PHY uses clause 45 addressing.
@@ -647,6 +650,7 @@ struct phy_device {
 
 	struct device_link *devlink;
 
+	u32 phyindex;
 	u32 phy_id;
 
 	struct phy_c45_device_ids c45_ids;
diff --git a/include/linux/phy_link_topology.h b/include/linux/phy_link_topology.h
new file mode 100644
index 000000000000..6b79feb607e7
--- /dev/null
+++ b/include/linux/phy_link_topology.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PHY device list allow maintaining a list of PHY devices that are
+ * part of a netdevice's link topology. PHYs can for example be chained,
+ * as is the case when using a PHY that exposes an SFP module, on which an
+ * SFP transceiver that embeds a PHY is connected.
+ *
+ * This list can then be used by userspace to leverage individual PHY
+ * capabilities.
+ */
+#ifndef __PHY_LINK_TOPOLOGY_H
+#define __PHY_LINK_TOPOLOGY_H
+
+#include <linux/ethtool.h>
+#include <linux/phy_link_topology_core.h>
+
+struct xarray;
+struct phy_device;
+struct net_device;
+struct sfp_bus;
+
+struct phy_device_node {
+	enum phy_upstream upstream_type;
+
+	union {
+		struct net_device	*netdev;
+		struct phy_device	*phydev;
+	} upstream;
+
+	struct sfp_bus *parent_sfp_bus;
+
+	struct phy_device *phy;
+};
+
+struct phy_link_topology {
+	struct xarray phys;
+	u32 next_phy_index;
+};
+
+static inline struct phy_device *
+phy_link_topo_get_phy(struct phy_link_topology *topo, u32 phyindex)
+{
+	struct phy_device_node *pdn = xa_load(&topo->phys, phyindex);
+
+	if (pdn)
+		return pdn->phy;
+
+	return NULL;
+}
+
+#if IS_REACHABLE(CONFIG_PHYLIB)
+int phy_link_topo_add_phy(struct phy_link_topology *topo,
+			  struct phy_device *phy,
+			  enum phy_upstream upt, void *upstream);
+
+void phy_link_topo_del_phy(struct phy_link_topology *lt, struct phy_device *phy);
+
+#else
+static inline int phy_link_topo_add_phy(struct phy_link_topology *topo,
+					struct phy_device *phy,
+					enum phy_upstream upt, void *upstream)
+{
+	return 0;
+}
+
+static inline void phy_link_topo_del_phy(struct phy_link_topology *topo,
+					 struct phy_device *phy)
+{
+}
+#endif
+
+#endif /* __PHY_LINK_TOPOLOGY_H */
diff --git a/include/linux/phy_link_topology_core.h b/include/linux/phy_link_topology_core.h
new file mode 100644
index 000000000000..0a6479055745
--- /dev/null
+++ b/include/linux/phy_link_topology_core.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PHY_LINK_TOPOLOGY_CORE_H
+#define __PHY_LINK_TOPOLOGY_CORE_H
+
+struct phy_link_topology;
+
+#if IS_REACHABLE(CONFIG_PHYLIB)
+
+struct phy_link_topology *phy_link_topo_create(struct net_device *dev);
+void phy_link_topo_destroy(struct phy_link_topology *topo);
+
+#else
+
+static inline struct phy_link_topology *phy_link_topo_create(struct net_device *dev)
+{
+	return NULL;
+}
+
+static inline void phy_link_topo_destroy(struct phy_link_topology *topo)
+{
+}
+
+#endif
+
+#endif /* __PHY_LINK_TOPOLOGY_CORE_H */
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 06ef6b78b7de..01ba529dbb6d 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -2220,4 +2220,20 @@ struct ethtool_link_settings {
 	 * __u32 map_lp_advertising[link_mode_masks_nwords];
 	 */
 };
+
+/**
+ * enum phy_upstream - Represents the upstream component a given PHY device
+ * is connected to, as in what is on the other end of the MII bus. Most PHYs
+ * will be attached to an Ethernet MAC controller, but in some cases, there's
+ * an intermediate PHY used as a media-converter, which will driver another
+ * MII interface as its output.
+ * @PHY_UPSTREAM_MAC: Upstream component is a MAC (a switch port,
+ *		      or ethernet controller)
+ * @PHY_UPSTREAM_PHY: Upstream component is a PHY (likely a media converter)
+ */
+enum phy_upstream {
+	PHY_UPSTREAM_MAC,
+	PHY_UPSTREAM_PHY,
+};
+
 #endif /* _UAPI_LINUX_ETHTOOL_H */
diff --git a/net/core/dev.c b/net/core/dev.c
index c588808be77f..a92f49ad71d7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -155,6 +155,7 @@
 #include <net/netdev_rx_queue.h>
 #include <net/page_pool/types.h>
 #include <net/page_pool/helpers.h>
+#include <linux/phy_link_topology_core.h>
 
 #include "dev.h"
 #include "net-sysfs.h"
@@ -10920,6 +10921,12 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 #ifdef CONFIG_NET_SCHED
 	hash_init(dev->qdisc_hash);
 #endif
+	dev->link_topo = phy_link_topo_create(dev);
+	if (IS_ERR(dev->link_topo)) {
+		dev->link_topo = NULL;
+		goto free_all;
+	}
+
 	dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM;
 	setup(dev);
 
@@ -11008,6 +11015,8 @@ void free_netdev(struct net_device *dev)
 	free_percpu(dev->xdp_bulkq);
 	dev->xdp_bulkq = NULL;
 
+	phy_link_topo_destroy(dev->link_topo);
+
 	/*  Compatibility with error handling in drivers */
 	if (dev->reg_state == NETREG_UNINITIALIZED) {
 		netdev_freemem(dev);
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:09 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:09 +0100
Subject: [PATCH net-next v8 06/13] netlink: specs: add phy-index as a header parameter
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-7-maxime.chevallier@bootlin.com>

Update the spec to take the newly introduced phy-index as a generic
request parameter.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
---
V8: No changes
V7: No changes
V6: No changes
V5: Added Andrew's R-b
V4: Ditch the ethtool-user generated code
V3: New patch

 Documentation/netlink/specs/ethtool.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 197208f419dc..bb6e1dc6d1c5 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -30,6 +30,9 @@ attribute-sets:
       -
         name: flags
         type: u32
+      -
+        name: phy-index
+        type: u32
 
   -
     name: bitset-bit
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:10 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:10 +0100
Subject: [PATCH net-next v8 07/13] net: ethtool: Introduce a command to list PHYs on an interface
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-8-maxime.chevallier@bootlin.com>

As we have the ability to track the PHYs connected to a net_device
through the link_topology, we can expose this list to userspace. This
allows userspace to use these identifiers for phy-specific commands and
take the decision of which PHY to target by knowing the link topology.

Add PHY_GET and PHY_DUMP, which can be a filtered DUMP operation to list
devices on only one interface.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V8: - No Changes
V7: - Moved the netdev release into the .done() call for filtered DUMP
      requests
V6: - Removed un-needed nest
    - Fixed the DUMP code
    - Fixed the documentation formatting
V5: - Fixed xmas tree
    - Fixed uninitialized return variable (Simon)
V4: - Fixed errors when not having SFP enabled, resulting in null names
      being passed as parameters to strlen.
V3: - Fixed the documentation
    - Fixed the DUMP implementation
V2: New patch

 Documentation/networking/ethtool-netlink.rst |  39 +++
 include/uapi/linux/ethtool_netlink.h         |  20 ++
 net/ethtool/Makefile                         |   2 +-
 net/ethtool/netlink.c                        |   9 +
 net/ethtool/netlink.h                        |   5 +
 net/ethtool/phy.c                            | 297 +++++++++++++++++++
 6 files changed, 371 insertions(+), 1 deletion(-)
 create mode 100644 net/ethtool/phy.c

diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index 3ca6c21e74af..e498c3b0b28f 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -2011,6 +2011,44 @@ The attributes are propagated to the driver through the following structure:
 .. kernel-doc:: include/linux/ethtool.h
     :identifiers: ethtool_mm_cfg
 
+PHY_GET
+=======
+
+Retrieve information about a given Ethernet PHY sitting on the link. As there
+can be more than one PHY, the DUMP operation can be used to list the PHYs
+present on a given interface, by passing an interface index or name in
+the dump request
+
+Request contents:
+
+  ====================================  ======  ==========================
+  ``ETHTOOL_A_PHY_HEADER``              nested  request header
+  ====================================  ======  ==========================
+
+Kernel response contents:
+
+  ===================================== ======  ===============================
+  ``ETHTOOL_A_PHY_HEADER``              nested  request header
+  ``ETHTOOL_A_PHY_INDEX``               u32     the phy's unique index, that can
+                                                be used for phy-specific
+                                                requests
+  ``ETHTOOL_A_PHY_DRVNAME``             string  the phy driver name
+  ``ETHTOOL_A_PHY_NAME``                string  the phy device name
+  ``ETHTOOL_A_PHY_UPSTREAM_TYPE``       u32     the type of device this phy is
+                                                connected to
+  ``ETHTOOL_A_PHY_UPSTREAM_INDEX``      u32     the PHY index of the upstream
+                                                PHY
+  ``ETHTOOL_A_PHY_UPSTREAM_SFP_NAME``   string  if this PHY is connected to
+                                                it's parent PHY through an SFP
+                                                bus, the name of this sfp bus
+  ``ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME`` string  if the phy controls an sfp bus,
+                                                the name of the sfp bus
+  ``ETHTOOL_A_PHY_ID``                  u32     the phy id if the phy is C22
+  ===================================== ======  ===============================
+
+When ``ETHTOOL_A_PHY_UPSTREAM_TYPE`` is PHY_UPSTREAM_PHY, the PHY's parent is
+another PHY.
+
 Request translation
 ===================
 
@@ -2117,4 +2155,5 @@ are netlink only.
   n/a                                 ``ETHTOOL_MSG_PLCA_GET_STATUS``
   n/a                                 ``ETHTOOL_MSG_MM_GET``
   n/a                                 ``ETHTOOL_MSG_MM_SET``
+  n/a                                 ``ETHTOOL_MSG_PHY_GET``
   =================================== =====================================
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 422e8cfdd98c..f7a13e93ecb7 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -57,6 +57,7 @@ enum {
 	ETHTOOL_MSG_PLCA_GET_STATUS,
 	ETHTOOL_MSG_MM_GET,
 	ETHTOOL_MSG_MM_SET,
+	ETHTOOL_MSG_PHY_GET,
 
 	/* add new constants above here */
 	__ETHTOOL_MSG_USER_CNT,
@@ -109,6 +110,8 @@ enum {
 	ETHTOOL_MSG_PLCA_NTF,
 	ETHTOOL_MSG_MM_GET_REPLY,
 	ETHTOOL_MSG_MM_NTF,
+	ETHTOOL_MSG_PHY_GET_REPLY,
+	ETHTOOL_MSG_PHY_NTF,
 
 	/* add new constants above here */
 	__ETHTOOL_MSG_KERNEL_CNT,
@@ -977,6 +980,23 @@ enum {
 	ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_CNT - 1)
 };
 
+enum {
+	ETHTOOL_A_PHY_UNSPEC,
+	ETHTOOL_A_PHY_HEADER,			/* nest - _A_HEADER_* */
+	ETHTOOL_A_PHY_INDEX,			/* u32 */
+	ETHTOOL_A_PHY_DRVNAME,			/* string */
+	ETHTOOL_A_PHY_NAME,			/* string */
+	ETHTOOL_A_PHY_UPSTREAM_TYPE,		/* u32 */
+	ETHTOOL_A_PHY_UPSTREAM_INDEX,		/* u32 */
+	ETHTOOL_A_PHY_UPSTREAM_SFP_NAME,	/* string */
+	ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME,	/* string */
+	ETHTOOL_A_PHY_ID,			/* u32 */
+
+	/* add new constants above here */
+	__ETHTOOL_A_PHY_CNT,
+	ETHTOOL_A_PHY_MAX = (__ETHTOOL_A_PHY_CNT - 1)
+};
+
 /* generic netlink info */
 #define ETHTOOL_GENL_NAME "ethtool"
 #define ETHTOOL_GENL_VERSION 1
diff --git a/net/ethtool/Makefile b/net/ethtool/Makefile
index 504f954a1b28..0ccd0e9afd3f 100644
--- a/net/ethtool/Makefile
+++ b/net/ethtool/Makefile
@@ -8,4 +8,4 @@ ethtool_nl-y	:= netlink.o bitset.o strset.o linkinfo.o linkmodes.o rss.o \
 		   linkstate.o debug.o wol.o features.o privflags.o rings.o \
 		   channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \
 		   tunnels.o fec.o eeprom.o stats.o phc_vclocks.o mm.o \
-		   module.o pse-pd.o plca.o mm.o
+		   module.o pse-pd.o plca.o mm.o phy.o
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index b8f16398ea9d..1d684835821e 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -1165,6 +1165,15 @@ static const struct genl_ops ethtool_genl_ops[] = {
 		.policy = ethnl_mm_set_policy,
 		.maxattr = ARRAY_SIZE(ethnl_mm_set_policy) - 1,
 	},
+	{
+		.cmd	= ETHTOOL_MSG_PHY_GET,
+		.doit	= ethnl_phy_doit,
+		.start	= ethnl_phy_start,
+		.dumpit	= ethnl_phy_dumpit,
+		.done	= ethnl_phy_done,
+		.policy = ethnl_phy_get_policy,
+		.maxattr = ARRAY_SIZE(ethnl_phy_get_policy) - 1,
+	},
 };
 
 static const struct genl_multicast_group ethtool_nl_mcgrps[] = {
diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
index d57a890b5d9e..0e71b53bdb1c 100644
--- a/net/ethtool/netlink.h
+++ b/net/ethtool/netlink.h
@@ -446,6 +446,7 @@ extern const struct nla_policy ethnl_plca_set_cfg_policy[ETHTOOL_A_PLCA_MAX + 1]
 extern const struct nla_policy ethnl_plca_get_status_policy[ETHTOOL_A_PLCA_HEADER + 1];
 extern const struct nla_policy ethnl_mm_get_policy[ETHTOOL_A_MM_HEADER + 1];
 extern const struct nla_policy ethnl_mm_set_policy[ETHTOOL_A_MM_MAX + 1];
+extern const struct nla_policy ethnl_phy_get_policy[ETHTOOL_A_PHY_HEADER + 1];
 
 int ethnl_set_features(struct sk_buff *skb, struct genl_info *info);
 int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);
@@ -453,6 +454,10 @@ int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info);
 int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info);
 int ethnl_tunnel_info_start(struct netlink_callback *cb);
 int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
+int ethnl_phy_start(struct netlink_callback *cb);
+int ethnl_phy_doit(struct sk_buff *skb, struct genl_info *info);
+int ethnl_phy_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
+int ethnl_phy_done(struct netlink_callback *cb);
 
 extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN];
 extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN];
diff --git a/net/ethtool/phy.c b/net/ethtool/phy.c
new file mode 100644
index 000000000000..fb73bf51c683
--- /dev/null
+++ b/net/ethtool/phy.c
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2023 Bootlin
+ *
+ */
+#include "common.h"
+#include "netlink.h"
+
+#include <linux/phy.h>
+#include <linux/phy_link_topology.h>
+#include <linux/sfp.h>
+
+struct phy_req_info {
+	struct ethnl_req_info		base;
+	struct phy_device_node		pdn;
+};
+
+#define PHY_REQINFO(__req_base) \
+	container_of(__req_base, struct phy_req_info, base)
+
+const struct nla_policy ethnl_phy_get_policy[ETHTOOL_A_PHY_HEADER + 1] = {
+	[ETHTOOL_A_PHY_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
+};
+
+/* Caller holds rtnl */
+static ssize_t
+ethnl_phy_reply_size(const struct ethnl_req_info *req_base,
+		     struct netlink_ext_ack *extack)
+{
+	struct phy_req_info *req_info = PHY_REQINFO(req_base);
+	struct phy_device_node *pdn = &req_info->pdn;
+	struct phy_device *phydev = pdn->phy;
+	size_t size = 0;
+
+	ASSERT_RTNL();
+
+	/* ETHTOOL_A_PHY_INDEX */
+	size += nla_total_size(sizeof(u32));
+
+	/* ETHTOOL_A_DRVNAME */
+	if (phydev->drv)
+		size += nla_total_size(strlen(phydev->drv->name) + 1);
+
+	/* ETHTOOL_A_NAME */
+	size += nla_total_size(strlen(dev_name(&phydev->mdio.dev)) + 1);
+
+	/* ETHTOOL_A_PHY_UPSTREAM_TYPE */
+	size += nla_total_size(sizeof(u32));
+
+	/* ETHTOOL_A_PHY_ID */
+	size += nla_total_size(sizeof(u32));
+
+	if (phy_on_sfp(phydev)) {
+		const char *upstream_sfp_name = sfp_get_name(pdn->parent_sfp_bus);
+
+		/* ETHTOOL_A_PHY_UPSTREAM_SFP_NAME */
+		if (upstream_sfp_name)
+			size += nla_total_size(strlen(upstream_sfp_name) + 1);
+
+		/* ETHTOOL_A_PHY_UPSTREAM_INDEX */
+		size += nla_total_size(sizeof(u32));
+	}
+
+	/* ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME */
+	if (phydev->sfp_bus) {
+		const char *sfp_name = sfp_get_name(phydev->sfp_bus);
+
+		if (sfp_name)
+			size += nla_total_size(strlen(sfp_name) + 1);
+	}
+
+	return size;
+}
+
+static int
+ethnl_phy_fill_reply(const struct ethnl_req_info *req_base, struct sk_buff *skb)
+{
+	struct phy_req_info *req_info = PHY_REQINFO(req_base);
+	struct phy_device_node *pdn = &req_info->pdn;
+	struct phy_device *phydev = pdn->phy;
+	enum phy_upstream ptype;
+
+	ptype = pdn->upstream_type;
+
+	if (nla_put_u32(skb, ETHTOOL_A_PHY_INDEX, phydev->phyindex) ||
+	    nla_put_string(skb, ETHTOOL_A_PHY_NAME, dev_name(&phydev->mdio.dev)) ||
+	    nla_put_u32(skb, ETHTOOL_A_PHY_UPSTREAM_TYPE, ptype) ||
+	    nla_put_u32(skb, ETHTOOL_A_PHY_ID, phydev->phy_id))
+		return -EMSGSIZE;
+
+	if (phydev->drv && nla_put_string(skb, ETHTOOL_A_PHY_DRVNAME, phydev->drv->name))
+		return -EMSGSIZE;
+
+	if (ptype == PHY_UPSTREAM_PHY) {
+		struct phy_device *upstream = pdn->upstream.phydev;
+		const char *sfp_upstream_name;
+
+		/* Parent index */
+		if (nla_put_u32(skb, ETHTOOL_A_PHY_UPSTREAM_INDEX, upstream->phyindex))
+			return -EMSGSIZE;
+
+		if (pdn->parent_sfp_bus) {
+			sfp_upstream_name = sfp_get_name(pdn->parent_sfp_bus);
+			if (sfp_upstream_name && nla_put_string(skb,
+								ETHTOOL_A_PHY_UPSTREAM_SFP_NAME,
+								sfp_upstream_name))
+				return -EMSGSIZE;
+		}
+	}
+
+	if (phydev->sfp_bus) {
+		const char *sfp_name = sfp_get_name(phydev->sfp_bus);
+
+		if (sfp_name &&
+		    nla_put_string(skb, ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME,
+				   sfp_name))
+			return -EMSGSIZE;
+	}
+
+	return 0;
+}
+
+static int ethnl_phy_parse_request(struct ethnl_req_info *req_base,
+				   struct nlattr **tb)
+{
+	struct phy_link_topology *topo = req_base->dev->link_topo;
+	struct phy_req_info *req_info = PHY_REQINFO(req_base);
+	struct phy_device_node *pdn;
+
+	if (!req_base->phydev)
+		return 0;
+
+	pdn = xa_load(&topo->phys, req_base->phydev->phyindex);
+	memcpy(&req_info->pdn, pdn, sizeof(*pdn));
+
+	return 0;
+}
+
+int ethnl_phy_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct phy_req_info req_info = {};
+	struct nlattr **tb = info->attrs;
+	struct sk_buff *rskb;
+	void *reply_payload;
+	int reply_len;
+	int ret;
+
+	ret = ethnl_parse_header_dev_get(&req_info.base,
+					 tb[ETHTOOL_A_PHY_HEADER],
+					 genl_info_net(info), info->extack,
+					 true);
+	if (ret < 0)
+		return ret;
+
+	rtnl_lock();
+
+	ret = ethnl_phy_parse_request(&req_info.base, tb);
+	if (ret < 0)
+		goto err_unlock_rtnl;
+
+	/* No PHY, return early */
+	if (!req_info.pdn.phy)
+		goto err_unlock_rtnl;
+
+	ret = ethnl_phy_reply_size(&req_info.base, info->extack);
+	if (ret < 0)
+		goto err_unlock_rtnl;
+	reply_len = ret + ethnl_reply_header_size();
+
+	rskb = ethnl_reply_init(reply_len, req_info.base.dev,
+				ETHTOOL_MSG_PHY_GET_REPLY,
+				ETHTOOL_A_PHY_HEADER,
+				info, &reply_payload);
+	if (!rskb) {
+		ret = -ENOMEM;
+		goto err_unlock_rtnl;
+	}
+
+	ret = ethnl_phy_fill_reply(&req_info.base, rskb);
+	if (ret)
+		goto err_free_msg;
+
+	rtnl_unlock();
+	ethnl_parse_header_dev_put(&req_info.base);
+	genlmsg_end(rskb, reply_payload);
+
+	return genlmsg_reply(rskb, info);
+
+err_free_msg:
+	nlmsg_free(rskb);
+err_unlock_rtnl:
+	rtnl_unlock();
+	ethnl_parse_header_dev_put(&req_info.base);
+	return ret;
+}
+
+struct ethnl_phy_dump_ctx {
+	struct phy_req_info	*phy_req_info;
+	unsigned long ifindex;
+	unsigned long phy_index;
+};
+
+int ethnl_phy_start(struct netlink_callback *cb)
+{
+	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
+	struct ethnl_phy_dump_ctx *ctx = (void *)cb->ctx;
+	struct nlattr **tb = info->info.attrs;
+	int ret;
+
+	BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
+
+	ctx->phy_req_info = kzalloc(sizeof(*ctx->phy_req_info), GFP_KERNEL);
+	if (!ctx->phy_req_info)
+		return -ENOMEM;
+
+	ret = ethnl_parse_header_dev_get(&ctx->phy_req_info->base,
+					 tb[ETHTOOL_A_PHY_HEADER],
+					 sock_net(cb->skb->sk), cb->extack,
+					 false);
+	ctx->ifindex = 0;
+	ctx->phy_index = 0;
+	return ret;
+}
+
+int ethnl_phy_done(struct netlink_callback *cb)
+{
+	struct ethnl_phy_dump_ctx *ctx = (void *)cb->ctx;
+
+	ethnl_parse_header_dev_put(&ctx->phy_req_info->base);
+	kfree(ctx->phy_req_info);
+
+	return 0;
+}
+
+static int ethnl_phy_dump_one_dev(struct sk_buff *skb, struct net_device *dev,
+				  struct netlink_callback *cb)
+{
+	struct ethnl_phy_dump_ctx *ctx = (void *)cb->ctx;
+	struct phy_req_info *pri = ctx->phy_req_info;
+	struct phy_device_node *pdn;
+	int ret = 0;
+	void *ehdr;
+
+	pri->base.dev = dev;
+
+	xa_for_each_start(&dev->link_topo->phys, ctx->phy_index, pdn, ctx->phy_index) {
+		ehdr = ethnl_dump_put(skb, cb,
+				      ETHTOOL_MSG_PHY_GET_REPLY);
+		if (!ehdr) {
+			ret = -EMSGSIZE;
+			break;
+		}
+
+		ret = ethnl_fill_reply_header(skb, dev,
+					      ETHTOOL_A_PHY_HEADER);
+		if (ret < 0) {
+			genlmsg_cancel(skb, ehdr);
+			break;
+		}
+
+		memcpy(&pri->pdn, pdn, sizeof(*pdn));
+		ret = ethnl_phy_fill_reply(&pri->base, skb);
+
+		genlmsg_end(skb, ehdr);
+	}
+
+	return ret;
+}
+
+int ethnl_phy_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct ethnl_phy_dump_ctx *ctx = (void *)cb->ctx;
+	struct net *net = sock_net(skb->sk);
+	struct net_device *dev;
+	int ret = 0;
+
+	rtnl_lock();
+
+	if (ctx->phy_req_info->base.dev) {
+		ret = ethnl_phy_dump_one_dev(skb, ctx->phy_req_info->base.dev, cb);
+	} else {
+		for_each_netdev_dump(net, dev, ctx->ifindex) {
+			ret = ethnl_phy_dump_one_dev(skb, dev, cb);
+			if (ret)
+				break;
+
+			ctx->phy_index = 0;
+		}
+	}
+	rtnl_unlock();
+
+	if (ret == -EMSGSIZE && skb->len)
+		return skb->len;
+
+	return ret;
+}
+
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:11 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:11 +0100
Subject: [PATCH net-next v8 08/13] netlink: specs: add ethnl PHY_GET command set
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-9-maxime.chevallier@bootlin.com>

The PHY_GET command, supporting both DUMP and GET operations, is used to
retrieve the list of PHYs connected to a netdevice, and get topology
information to know where exactly it sits on the physical link.

Add the netlink specs corresponding to that command.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V8: No changes
V7: No changes
V6: Updated the spec according to the new attributes
V5: No changes
V4: Remove the ethtool-user generated code
V3: New patch

 Documentation/netlink/specs/ethtool.yaml | 59 ++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index bb6e1dc6d1c5..e98d78fbc2f3 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -16,6 +16,11 @@ definitions:
     name: stringset
     type: enum
     entries: []
+  -
+    name: phy-upstream-type
+    enum-name:
+    type: enum
+    entries: [ mac, phy ]
 
 attribute-sets:
   -
@@ -945,6 +950,38 @@ attribute-sets:
       -
         name: burst-tmr
         type: u32
+  -
+    name: phy
+    attributes:
+      -
+        name: header
+        type: nest
+        nested-attributes: header
+      -
+        name: index
+        type: u32
+      -
+        name: drvname
+        type: string
+      -
+        name: name
+        type: string
+      -
+        name: upstream-type
+        type: u32
+        enum: phy-upstream-type
+      -
+        name: upstream-phy-index
+        type: u32
+      -
+        name: upstream-sfp-name
+        type: string
+      -
+        name: downstream-sfp-name
+        type: string
+      -
+        name: id
+        type: u32
 
 operations:
   enum-model: directional
@@ -1696,3 +1733,25 @@ operations:
       name: mm-ntf
       doc: Notification for change in MAC Merge configuration.
       notify: mm-get
+    -
+      name: phy-get
+      doc: Get PHY devices attached to an interface
+
+      attribute-set: phy
+
+      do: &phy-get-op
+        request:
+          attributes:
+            - header
+        reply:
+          attributes:
+            - header
+            - index
+            - drvname
+            - name
+            - upstream-type
+            - upstream-phy-index
+            - upstream-sfp-name
+            - downstream-sfp-name
+            - id
+      dump: *phy-get-op
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:12 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:12 +0100
Subject: [PATCH net-next v8 09/13] net: ethtool: plca: Target the command to the requested PHY
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-10-maxime.chevallier@bootlin.com>

PLCA is a PHY-specific command. Instead of targeting the command
towards dev->phydev, use the request to pick the targeted PHY.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V8: No changes
V7: No changes
V6: Use dedicated policy
V5: Added Andrew's R-b
V4: No changes
V3: No changes
V2: New patch

 net/ethtool/plca.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/net/ethtool/plca.c b/net/ethtool/plca.c
index b1e2e3b5027f..43b31a4a164e 100644
--- a/net/ethtool/plca.c
+++ b/net/ethtool/plca.c
@@ -25,7 +25,7 @@ struct plca_reply_data {
 
 const struct nla_policy ethnl_plca_get_cfg_policy[] = {
 	[ETHTOOL_A_PLCA_HEADER]		=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 };
 
 static void plca_update_sint(int *dst, struct nlattr **tb, u32 attrid,
@@ -61,7 +61,7 @@ static int plca_get_cfg_prepare_data(const struct ethnl_req_info *req_base,
 	int ret;
 
 	// check that the PHY device is available and connected
-	if (!dev->phydev) {
+	if (!req_base->phydev) {
 		ret = -EOPNOTSUPP;
 		goto out;
 	}
@@ -80,7 +80,7 @@ static int plca_get_cfg_prepare_data(const struct ethnl_req_info *req_base,
 	memset(&data->plca_cfg, 0xff,
 	       sizeof_field(struct plca_reply_data, plca_cfg));
 
-	ret = ops->get_plca_cfg(dev->phydev, &data->plca_cfg);
+	ret = ops->get_plca_cfg(req_base->phydev, &data->plca_cfg);
 	ethnl_ops_complete(dev);
 
 out:
@@ -129,7 +129,7 @@ static int plca_get_cfg_fill_reply(struct sk_buff *skb,
 
 const struct nla_policy ethnl_plca_set_cfg_policy[] = {
 	[ETHTOOL_A_PLCA_HEADER]		=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 	[ETHTOOL_A_PLCA_ENABLED]	= NLA_POLICY_MAX(NLA_U8, 1),
 	[ETHTOOL_A_PLCA_NODE_ID]	= NLA_POLICY_MAX(NLA_U32, 255),
 	[ETHTOOL_A_PLCA_NODE_CNT]	= NLA_POLICY_RANGE(NLA_U32, 1, 255),
@@ -141,7 +141,6 @@ const struct nla_policy ethnl_plca_set_cfg_policy[] = {
 static int
 ethnl_set_plca(struct ethnl_req_info *req_info, struct genl_info *info)
 {
-	struct net_device *dev = req_info->dev;
 	const struct ethtool_phy_ops *ops;
 	struct nlattr **tb = info->attrs;
 	struct phy_plca_cfg plca_cfg;
@@ -149,7 +148,7 @@ ethnl_set_plca(struct ethnl_req_info *req_info, struct genl_info *info)
 	int ret;
 
 	// check that the PHY device is available and connected
-	if (!dev->phydev)
+	if (!req_info->phydev)
 		return -EOPNOTSUPP;
 
 	ops = ethtool_phy_ops;
@@ -168,7 +167,7 @@ ethnl_set_plca(struct ethnl_req_info *req_info, struct genl_info *info)
 	if (!mod)
 		return 0;
 
-	ret = ops->set_plca_cfg(dev->phydev, &plca_cfg, info->extack);
+	ret = ops->set_plca_cfg(req_info->phydev, &plca_cfg, info->extack);
 	return ret < 0 ? ret : 1;
 }
 
@@ -191,7 +190,7 @@ const struct ethnl_request_ops ethnl_plca_cfg_request_ops = {
 
 const struct nla_policy ethnl_plca_get_status_policy[] = {
 	[ETHTOOL_A_PLCA_HEADER]		=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 };
 
 static int plca_get_status_prepare_data(const struct ethnl_req_info *req_base,
@@ -204,7 +203,7 @@ static int plca_get_status_prepare_data(const struct ethnl_req_info *req_base,
 	int ret;
 
 	// check that the PHY device is available and connected
-	if (!dev->phydev) {
+	if (!req_base->phydev) {
 		ret = -EOPNOTSUPP;
 		goto out;
 	}
@@ -223,7 +222,7 @@ static int plca_get_status_prepare_data(const struct ethnl_req_info *req_base,
 	memset(&data->plca_st, 0xff,
 	       sizeof_field(struct plca_reply_data, plca_st));
 
-	ret = ops->get_plca_status(dev->phydev, &data->plca_st);
+	ret = ops->get_plca_status(req_base->phydev, &data->plca_st);
 	ethnl_ops_complete(dev);
 out:
 	return ret;
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:13 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:13 +0100
Subject: [PATCH net-next v8 10/13] net: ethtool: pse-pd: Target the command to the requested PHY
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-11-maxime.chevallier@bootlin.com>

PSE and PD configuration is a PHY-specific command. Instead of targeting
the command towards dev->phydev, use the request to pick the targeted
PHY device.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V8: No changes
V7: No changes
V6: Use dedicated policy
V5: Added-back an incorrectly removed check
V4: No changes
V3: No changes
V2: New patch

 net/ethtool/pse-pd.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index cc478af77111..be50d79122c4 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -28,15 +28,13 @@ struct pse_reply_data {
 /* PSE_GET */
 
 const struct nla_policy ethnl_pse_get_policy[ETHTOOL_A_PSE_HEADER + 1] = {
-	[ETHTOOL_A_PSE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
+	[ETHTOOL_A_PSE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy_phy),
 };
 
-static int pse_get_pse_attributes(struct net_device *dev,
+static int pse_get_pse_attributes(struct phy_device *phydev,
 				  struct netlink_ext_ack *extack,
 				  struct pse_reply_data *data)
 {
-	struct phy_device *phydev = dev->phydev;
-
 	if (!phydev) {
 		NL_SET_ERR_MSG(extack, "No PHY is attached");
 		return -EOPNOTSUPP;
@@ -64,7 +62,7 @@ static int pse_prepare_data(const struct ethnl_req_info *req_base,
 	if (ret < 0)
 		return ret;
 
-	ret = pse_get_pse_attributes(dev, info->extack, data);
+	ret = pse_get_pse_attributes(req_base->phydev, info->extack, data);
 
 	ethnl_ops_complete(dev);
 
@@ -109,7 +107,7 @@ static int pse_fill_reply(struct sk_buff *skb,
 /* PSE_SET */
 
 const struct nla_policy ethnl_pse_set_policy[ETHTOOL_A_PSE_MAX + 1] = {
-	[ETHTOOL_A_PSE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
+	[ETHTOOL_A_PSE_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy_phy),
 	[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] =
 		NLA_POLICY_RANGE(NLA_U32, ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED,
 				 ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED),
@@ -124,7 +122,6 @@ ethnl_set_pse_validate(struct ethnl_req_info *req_info, struct genl_info *info)
 static int
 ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info)
 {
-	struct net_device *dev = req_info->dev;
 	struct pse_control_config config = {};
 	struct nlattr **tb = info->attrs;
 	struct phy_device *phydev;
@@ -132,7 +129,7 @@ ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info)
 	/* this values are already validated by the ethnl_pse_set_policy */
 	config.admin_cotrol = nla_get_u32(tb[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL]);
 
-	phydev = dev->phydev;
+	phydev = req_info->phydev;
 	if (!phydev) {
 		NL_SET_ERR_MSG(info->extack, "No PHY is attached");
 		return -EOPNOTSUPP;
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:14 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:14 +0100
Subject: [PATCH net-next v8 11/13] net: ethtool: cable-test: Target the command to the requested PHY
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-12-maxime.chevallier@bootlin.com>

Cable testing is a PHY-specific command. Instead of targeting the command
towards dev->phydev, use the request to pick the targeted PHY.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V8: No changes
V7: No changes
V6: Use dedicated policy
V5: Added Andrew's R-b
V4: No changes
V3: No changes
V2: New patch

 net/ethtool/cabletest.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/net/ethtool/cabletest.c b/net/ethtool/cabletest.c
index 06a151165c31..536800bbc379 100644
--- a/net/ethtool/cabletest.c
+++ b/net/ethtool/cabletest.c
@@ -13,7 +13,7 @@
 
 const struct nla_policy ethnl_cable_test_act_policy[] = {
 	[ETHTOOL_A_CABLE_TEST_HEADER]		=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 };
 
 static int ethnl_cable_test_started(struct phy_device *phydev, u8 cmd)
@@ -69,7 +69,7 @@ int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info)
 		return ret;
 
 	dev = req_info.dev;
-	if (!dev->phydev) {
+	if (!req_info.phydev) {
 		ret = -EOPNOTSUPP;
 		goto out_dev_put;
 	}
@@ -85,12 +85,12 @@ int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info)
 	if (ret < 0)
 		goto out_rtnl;
 
-	ret = ops->start_cable_test(dev->phydev, info->extack);
+	ret = ops->start_cable_test(req_info.phydev, info->extack);
 
 	ethnl_ops_complete(dev);
 
 	if (!ret)
-		ethnl_cable_test_started(dev->phydev,
+		ethnl_cable_test_started(req_info.phydev,
 					 ETHTOOL_MSG_CABLE_TEST_NTF);
 
 out_rtnl:
@@ -220,7 +220,7 @@ static const struct nla_policy cable_test_tdr_act_cfg_policy[] = {
 
 const struct nla_policy ethnl_cable_test_tdr_act_policy[] = {
 	[ETHTOOL_A_CABLE_TEST_TDR_HEADER]	=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 	[ETHTOOL_A_CABLE_TEST_TDR_CFG]		= { .type = NLA_NESTED },
 };
 
@@ -321,7 +321,7 @@ int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info)
 		return ret;
 
 	dev = req_info.dev;
-	if (!dev->phydev) {
+	if (!req_info.phydev) {
 		ret = -EOPNOTSUPP;
 		goto out_dev_put;
 	}
@@ -342,12 +342,12 @@ int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info)
 	if (ret < 0)
 		goto out_rtnl;
 
-	ret = ops->start_cable_test_tdr(dev->phydev, info->extack, &cfg);
+	ret = ops->start_cable_test_tdr(req_info.phydev, info->extack, &cfg);
 
 	ethnl_ops_complete(dev);
 
 	if (!ret)
-		ethnl_cable_test_started(dev->phydev,
+		ethnl_cable_test_started(req_info.phydev,
 					 ETHTOOL_MSG_CABLE_TEST_TDR_NTF);
 
 out_rtnl:
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:07 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:07 +0100
Subject: [PATCH net-next v8 04/13] net: sfp: Add helper to return the SFP bus name
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-5-maxime.chevallier@bootlin.com>

Knowing the bus name is helpful when we want to expose the link topology
to userspace, add a helper to return the SFP bus name.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
---
V8: - No changes
V7: - No changes
V6: - No changes
V5: - Added Andrew's R-b
V4: - No changes
V3: - Added RTNL assert
    - Made the stub inline
V2: New patch
 drivers/net/phy/sfp-bus.c | 11 +++++++++++
 include/linux/sfp.h       |  6 ++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index e05013aeecc3..413021619afe 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -859,3 +859,14 @@ void sfp_unregister_socket(struct sfp_bus *bus)
 	sfp_bus_put(bus);
 }
 EXPORT_SYMBOL_GPL(sfp_unregister_socket);
+
+const char *sfp_get_name(struct sfp_bus *bus)
+{
+	ASSERT_RTNL();
+
+	if (bus->sfp_dev)
+		return dev_name(bus->sfp_dev);
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(sfp_get_name);
diff --git a/include/linux/sfp.h b/include/linux/sfp.h
index 0573e53b0c11..55c0ab17c9e2 100644
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -570,6 +570,7 @@ struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode);
 int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
 			 const struct sfp_upstream_ops *ops);
 void sfp_bus_del_upstream(struct sfp_bus *bus);
+const char *sfp_get_name(struct sfp_bus *bus);
 #else
 static inline int sfp_parse_port(struct sfp_bus *bus,
 				 const struct sfp_eeprom_id *id,
@@ -648,6 +649,11 @@ static inline int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
 static inline void sfp_bus_del_upstream(struct sfp_bus *bus)
 {
 }
+
+static inline const char *sfp_get_name(struct sfp_bus *bus)
+{
+	return NULL;
+}
 #endif
 
 #endif
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:08 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:08 +0100
Subject: [PATCH net-next v8 05/13] net: ethtool: Allow passing a phy index for some commands
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-6-maxime.chevallier@bootlin.com>

Some netlink commands are target towards ethernet PHYs, to control some
of their features. As there's several such commands, add the ability to
pass a PHY index in the ethnl request, which will populate the generic
ethnl_req_info with the relevant phydev when the command targets a PHY.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
---
V8: - No changes
V7: - No changes
V6: - Added dedicated policies when passing a PHY index
    - Dropped Andrew's R-b as there were changes
V5: - Added Andrew's R-b
    - Fix a typo reported by Simon
V4: - No Changes
V3: - Fixed the documentation
V2: - New patch

 Documentation/networking/ethtool-netlink.rst |  7 ++++
 include/uapi/linux/ethtool_netlink.h         |  1 +
 net/ethtool/netlink.c                        | 44 +++++++++++++++++++-
 net/ethtool/netlink.h                        |  5 +++
 4 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index d583d9abf2f8..3ca6c21e74af 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -57,6 +57,7 @@ Structure of this header is
   ``ETHTOOL_A_HEADER_DEV_INDEX``  u32     device ifindex
   ``ETHTOOL_A_HEADER_DEV_NAME``   string  device name
   ``ETHTOOL_A_HEADER_FLAGS``      u32     flags common for all requests
+  ``ETHTOOL_A_HEADER_PHY_INDEX``  u32     phy device index
   ==============================  ======  =============================
 
 ``ETHTOOL_A_HEADER_DEV_INDEX`` and ``ETHTOOL_A_HEADER_DEV_NAME`` identify the
@@ -81,6 +82,12 @@ the behaviour is backward compatible, i.e. requests from old clients not aware
 of the flag should be interpreted the way the client expects. A client must
 not set flags it does not understand.
 
+``ETHTOOL_A_HEADER_PHY_INDEX`` identify the ethernet PHY the message relates to.
+As there are numerous commands that are related to PHY configuration, and because
+we can have more than one PHY on the link, the PHY index can be passed in the
+request for the commands that needs it. It is however not mandatory, and if it
+is not passed for commands that target a PHY, the net_device.phydev pointer
+is used, as a fallback that keeps the legacy behaviour.
 
 Bit sets
 ========
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 3f89074aa06c..422e8cfdd98c 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -133,6 +133,7 @@ enum {
 	ETHTOOL_A_HEADER_DEV_INDEX,		/* u32 */
 	ETHTOOL_A_HEADER_DEV_NAME,		/* string */
 	ETHTOOL_A_HEADER_FLAGS,			/* u32 - ETHTOOL_FLAG_* */
+	ETHTOOL_A_HEADER_PHY_INDEX,		/* u32 */
 
 	/* add new constants above here */
 	__ETHTOOL_A_HEADER_CNT,
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index bd04f28d5cf4..b8f16398ea9d 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -4,6 +4,7 @@
 #include <linux/ethtool_netlink.h>
 #include <linux/pm_runtime.h>
 #include "netlink.h"
+#include <linux/phy_link_topology.h>
 
 static struct genl_family ethtool_genl_family;
 
@@ -30,6 +31,24 @@ const struct nla_policy ethnl_header_policy_stats[] = {
 							  ETHTOOL_FLAGS_STATS),
 };
 
+const struct nla_policy ethnl_header_policy_phy[] = {
+	[ETHTOOL_A_HEADER_DEV_INDEX]	= { .type = NLA_U32 },
+	[ETHTOOL_A_HEADER_DEV_NAME]	= { .type = NLA_NUL_STRING,
+					    .len = ALTIFNAMSIZ - 1 },
+	[ETHTOOL_A_HEADER_FLAGS]	= NLA_POLICY_MASK(NLA_U32,
+							  ETHTOOL_FLAGS_BASIC),
+	[ETHTOOL_A_HEADER_PHY_INDEX]		= NLA_POLICY_MIN(NLA_U32, 1),
+};
+
+const struct nla_policy ethnl_header_policy_phy_stats[] = {
+	[ETHTOOL_A_HEADER_DEV_INDEX]	= { .type = NLA_U32 },
+	[ETHTOOL_A_HEADER_DEV_NAME]	= { .type = NLA_NUL_STRING,
+					    .len = ALTIFNAMSIZ - 1 },
+	[ETHTOOL_A_HEADER_FLAGS]	= NLA_POLICY_MASK(NLA_U32,
+							  ETHTOOL_FLAGS_STATS),
+	[ETHTOOL_A_HEADER_PHY_INDEX]		= NLA_POLICY_MIN(NLA_U32, 1),
+};
+
 int ethnl_ops_begin(struct net_device *dev)
 {
 	int ret;
@@ -89,8 +108,9 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
 			       const struct nlattr *header, struct net *net,
 			       struct netlink_ext_ack *extack, bool require_dev)
 {
-	struct nlattr *tb[ARRAY_SIZE(ethnl_header_policy)];
+	struct nlattr *tb[ARRAY_SIZE(ethnl_header_policy_phy)];
 	const struct nlattr *devname_attr;
+	struct phy_device *phydev = NULL;
 	struct net_device *dev = NULL;
 	u32 flags = 0;
 	int ret;
@@ -104,7 +124,7 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
 	/* No validation here, command policy should have a nested policy set
 	 * for the header, therefore validation should have already been done.
 	 */
-	ret = nla_parse_nested(tb, ARRAY_SIZE(ethnl_header_policy) - 1, header,
+	ret = nla_parse_nested(tb, ARRAY_SIZE(ethnl_header_policy_phy) - 1, header,
 			       NULL, extack);
 	if (ret < 0)
 		return ret;
@@ -145,6 +165,26 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
 		return -EINVAL;
 	}
 
+	if (dev) {
+		if (tb[ETHTOOL_A_HEADER_PHY_INDEX]) {
+			u32 phy_index = nla_get_u32(tb[ETHTOOL_A_HEADER_PHY_INDEX]);
+
+			phydev = phy_link_topo_get_phy(dev->link_topo,
+						       phy_index);
+			if (!phydev) {
+				NL_SET_ERR_MSG_ATTR(extack, header,
+						    "no phy matches phy index");
+				return -EINVAL;
+			}
+		} else {
+			/* If we need a PHY but no phy index is specified, fallback
+			 * to dev->phydev
+			 */
+			phydev = dev->phydev;
+		}
+	}
+
+	req_info->phydev = phydev;
 	req_info->dev = dev;
 	req_info->flags = flags;
 	return 0;
diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
index 9a333a8d04c1..d57a890b5d9e 100644
--- a/net/ethtool/netlink.h
+++ b/net/ethtool/netlink.h
@@ -250,6 +250,7 @@ static inline unsigned int ethnl_reply_header_size(void)
  * @dev:   network device the request is for (may be null)
  * @dev_tracker: refcount tracker for @dev reference
  * @flags: request flags common for all request types
+ * @phydev: phy_device connected to @dev this request is for (may be null)
  *
  * This is a common base for request specific structures holding data from
  * parsed userspace request. These always embed struct ethnl_req_info at
@@ -259,6 +260,7 @@ struct ethnl_req_info {
 	struct net_device	*dev;
 	netdevice_tracker	dev_tracker;
 	u32			flags;
+	struct phy_device	*phydev;
 };
 
 static inline void ethnl_parse_header_dev_put(struct ethnl_req_info *req_info)
@@ -395,9 +397,12 @@ extern const struct ethnl_request_ops ethnl_rss_request_ops;
 extern const struct ethnl_request_ops ethnl_plca_cfg_request_ops;
 extern const struct ethnl_request_ops ethnl_plca_status_request_ops;
 extern const struct ethnl_request_ops ethnl_mm_request_ops;
+extern const struct ethnl_request_ops ethnl_phy_request_ops;
 
 extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];
 extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];
+extern const struct nla_policy ethnl_header_policy_phy[ETHTOOL_A_HEADER_PHY_INDEX + 1];
+extern const struct nla_policy ethnl_header_policy_phy_stats[ETHTOOL_A_HEADER_PHY_INDEX + 1];
 extern const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_COUNTS_ONLY + 1];
 extern const struct nla_policy ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_HEADER + 1];
 extern const struct nla_policy ethnl_linkinfo_set_policy[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL + 1];
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:15 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:15 +0100
Subject: [PATCH net-next v8 12/13] net: ethtool: strset: Allow querying phy stats by index
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-13-maxime.chevallier@bootlin.com>

The ETH_SS_PHY_STATS command gets PHY statistics. Use the phydev pointer
from the ethnl request to allow query phy stats from each PHY on the
link.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V8: No changes
V7: No changes
V6: Use dedicated policy
V5: Added Andrew's R-b
V4: No changes
V3: No changes
V2: New patch

 net/ethtool/strset.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/net/ethtool/strset.c b/net/ethtool/strset.c
index c678b484a079..edc826407564 100644
--- a/net/ethtool/strset.c
+++ b/net/ethtool/strset.c
@@ -126,7 +126,7 @@ struct strset_reply_data {
 
 const struct nla_policy ethnl_strset_get_policy[] = {
 	[ETHTOOL_A_STRSET_HEADER]	=
-		NLA_POLICY_NESTED(ethnl_header_policy),
+		NLA_POLICY_NESTED(ethnl_header_policy_phy),
 	[ETHTOOL_A_STRSET_STRINGSETS]	= { .type = NLA_NESTED },
 	[ETHTOOL_A_STRSET_COUNTS_ONLY]	= { .type = NLA_FLAG },
 };
@@ -233,17 +233,18 @@ static void strset_cleanup_data(struct ethnl_reply_data *reply_base)
 }
 
 static int strset_prepare_set(struct strset_info *info, struct net_device *dev,
-			      unsigned int id, bool counts_only)
+			      struct phy_device *phydev, unsigned int id,
+			      bool counts_only)
 {
 	const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
 	const struct ethtool_ops *ops = dev->ethtool_ops;
 	void *strings;
 	int count, ret;
 
-	if (id == ETH_SS_PHY_STATS && dev->phydev &&
+	if (id == ETH_SS_PHY_STATS && phydev &&
 	    !ops->get_ethtool_phy_stats && phy_ops &&
 	    phy_ops->get_sset_count)
-		ret = phy_ops->get_sset_count(dev->phydev);
+		ret = phy_ops->get_sset_count(phydev);
 	else if (ops->get_sset_count && ops->get_strings)
 		ret = ops->get_sset_count(dev, id);
 	else
@@ -258,10 +259,10 @@ static int strset_prepare_set(struct strset_info *info, struct net_device *dev,
 		strings = kcalloc(count, ETH_GSTRING_LEN, GFP_KERNEL);
 		if (!strings)
 			return -ENOMEM;
-		if (id == ETH_SS_PHY_STATS && dev->phydev &&
+		if (id == ETH_SS_PHY_STATS && phydev &&
 		    !ops->get_ethtool_phy_stats && phy_ops &&
 		    phy_ops->get_strings)
-			phy_ops->get_strings(dev->phydev, strings);
+			phy_ops->get_strings(phydev, strings);
 		else
 			ops->get_strings(dev, id, strings);
 		info->strings = strings;
@@ -305,8 +306,8 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,
 		    !data->sets[i].per_dev)
 			continue;
 
-		ret = strset_prepare_set(&data->sets[i], dev, i,
-					 req_info->counts_only);
+		ret = strset_prepare_set(&data->sets[i], dev, req_base->phydev,
+					 i, req_info->counts_only);
 		if (ret < 0)
 			goto err_ops;
 	}
-- 
2.43.2



From maxime.chevallier at bootlin.com  Tue Feb 20 10:42:16 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Tue, 20 Feb 2024 19:42:16 +0100
Subject: [PATCH net-next v8 13/13] Documentation: networking: document phy_link_topology
In-Reply-To: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
Message-ID: <20240220184217.3689988-14-maxime.chevallier@bootlin.com>

The newly introduced phy_link_topology tracks all ethernet PHYs that are
attached to a netdevice. Document the base principle, internal and
external APIs. As the phy_link_topology is expected to be extended, this
documentation will hold any further improvements and additions made
relative to topology handling.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
---
V8: No changes
V7: No changes
V6: No changes
V5: Fixed a lot of typos
V4: No changes
V3: New patch

 Documentation/networking/index.rst            |   1 +
 .../networking/phy-link-topology.rst          | 121 ++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100644 Documentation/networking/phy-link-topology.rst

diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst
index 69f3d6dcd9fd..a2c45a75a4a6 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -88,6 +88,7 @@ Contents:
    operstates
    packet_mmap
    phonet
+   phy-link-topology
    pktgen
    plip
    ppp_generic
diff --git a/Documentation/networking/phy-link-topology.rst b/Documentation/networking/phy-link-topology.rst
new file mode 100644
index 000000000000..1fd8e904ef4b
--- /dev/null
+++ b/Documentation/networking/phy-link-topology.rst
@@ -0,0 +1,121 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+PHY link topology
+=================
+
+Overview
+========
+
+The PHY link topology representation in the networking stack aims at representing
+the hardware layout for any given Ethernet link.
+
+An Ethernet Interface from userspace's point of view is nothing but a
+:c:type:`struct net_device <net_device>`, which exposes configuration options
+through the legacy ioctls and the ethool netlink commands. The base assumption
+when designing these configuration channels were that the link looked
+something like this ::
+
+  +-----------------------+        +----------+      +--------------+
+  | Ethernet Controller / |        | Ethernet |      | Connector /  |
+  |       MAC             | ------ |   PHY    | ---- |    Port      | ---... to LP
+  +-----------------------+        +----------+      +--------------+
+  struct net_device               struct phy_device
+
+Commands that needs to configure the PHY will go through the net_device.phydev
+field to reach the PHY and perform the relevant configuration.
+
+This assumption falls apart in more complex topologies that can arise when,
+for example, using SFP transceivers (although that's not the only specific case).
+
+Here, we have 2 basic scenarios. Either the MAC is able to output a serialized
+interface, that can directly be fed to an SFP cage, such as SGMII, 1000BaseX,
+10GBaseR, etc.
+
+The link topology then looks like this (when an SFP module is inserted) ::
+
+  +-----+  SGMII  +------------+
+  | MAC | ------- | SFP Module |
+  +-----+         +------------+
+
+Knowing that some modules embed a PHY, the actual link is more like ::
+
+  +-----+  SGMII   +--------------+
+  | MAC | -------- | PHY (on SFP) |
+  +-----+          +--------------+
+
+In this case, the SFP PHY is handled by phylib, and registered by phylink through
+its SFP upstream ops.
+
+Now some Ethernet controllers aren't able to output a serialized interface, so
+we can't directly connect them to an SFP cage. However, some PHYs can be used
+as media-converters, to translate the non-serialized MAC MII interface to a
+serialized MII interface fed to the SFP ::
+
+  +-----+  RGMII  +-----------------------+  SGMII  +--------------+
+  | MAC | ------- | PHY (media converter) | ------- | PHY (on SFP) |
+  +-----+         +-----------------------+         +--------------+
+
+This is where the model of having a single net_device.phydev pointer shows its
+limitations, as we now have 2 PHYs on the link.
+
+The phy_link topology framework aims at providing a way to keep track of every
+PHY on the link, for use by both kernel drivers and subsystems, but also to
+report the topology to userspace, allowing to target individual PHYs in configuration
+commands.
+
+API
+===
+
+The :c:type:`struct phy_link_topology <phy_link_topology>` is a per-netdevice
+resource, that gets initialized at netdevice creation. Once it's initialized,
+it is then possible to register PHYs to the topology through :
+
+:c:func:`phy_link_topo_add_phy`
+
+Besides registering the PHY to the topology, this call will also assign a unique
+index to the PHY, which can then be reported to userspace to refer to this PHY
+(akin to the ifindex). This index is a u32, ranging from 1 to U32_MAX. The value
+0 is reserved to indicate the PHY doesn't belong to any topology yet.
+
+The PHY can then be removed from the topology through
+
+:c:func:`phy_link_topo_del_phy`
+
+These function are already hooked into the phylib subsystem, so all PHYs that
+are linked to a net_device through :c:func:`phy_attach_direct` will automatically
+join the netdev's topology.
+
+PHYs that are on a SFP module will also be automatically registered IF the SFP
+upstream is phylink (so, no media-converter).
+
+PHY drivers that can be used as SFP upstream need to call :c:func:`phy_sfp_attach_phy`
+and :c:func:`phy_sfp_detach_phy`, which can be used as a
+.attach_phy / .detach_phy implementation for the
+:c:type:`struct sfp_upstream_ops <sfp_upstream_ops>`.
+
+UAPI
+====
+
+There exist a set of netlink commands to query the link topology from userspace,
+see ``Documentation/networking/ethtool-netlink.rst``.
+
+The whole point of having a topology representation is to assign the phyindex
+field in :c:type:`struct phy_device <phy_device>`. This index is reported to
+userspace using the ``ETHTOOL_MSG_PHY_GET`` ethtnl command. Performing a DUMP operation
+will result in all PHYs from all net_device being listed. The DUMP command
+accepts either a ``ETHTOOL_A_HEADER_DEV_INDEX`` or ``ETHTOOL_A_HEADER_DEV_NAME``
+to be passed in the request to filter the DUMP to a single net_device.
+
+The retrieved index can then be passed as a request parameter using the
+``ETHTOOL_A_HEADER_PHY_INDEX`` field in the following ethnl commands :
+
+* ``ETHTOOL_MSG_STRSET_GET`` to get the stats string set from a given PHY
+* ``ETHTOOL_MSG_CABLE_TEST_ACT`` and ``ETHTOOL_MSG_CABLE_TEST_ACT``, to perform
+  cable testing on a given PHY on the link (most likely the outermost PHY)
+* ``ETHTOOL_MSG_PSE_SET`` and ``ETHTOOL_MSG_PSE_GET`` for PHY-controlled PoE and PSE settings
+* ``ETHTOOL_MSG_PLCA_GET_CFG``, ``ETHTOOL_MSG_PLCA_SET_CFG`` and ``ETHTOOL_MSG_PLCA_GET_STATUS``
+  to set the PLCA (Physical Layer Collision Avoidance) parameters
+
+Note that the PHY index can be passed to other requests, which will silently
+ignore it if present and irrelevant.
-- 
2.43.2



From conor at kernel.org  Tue Feb 20 10:58:21 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 20 Feb 2024 18:58:21 +0000
Subject: [PATCH 04/14] media: dt-bindings: media: rockchip,px30-vip:
 allow for different variants
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-4-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
 <20240220-v6-8-topic-rk3568-vicap-v1-4-2680a1fa640b@wolfvision.net>
Message-ID: <20240220-catchy-cupcake-e600e5af7650@spud>

Hey,

On Tue, Feb 20, 2024 at 10:39:14AM +0100, Michael Riesch wrote:
> Move the documentation of clocks and resets to a allOf: structure in order
> to allow for different variants of the IP block.
> 
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
>  .../bindings/media/rockchip,px30-vip.yaml          | 58 ++++++++++++++--------
>  1 file changed, 37 insertions(+), 21 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
> index 675a1ea47210..7168f166798c 100644
> --- a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
> +++ b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
> @@ -24,32 +24,16 @@ properties:
>    interrupts:
>      maxItems: 1
>  
> -  clocks:
> -    items:
> -      - description: ACLK
> -      - description: HCLK
> -      - description: PCLK
> -
> -  clock-names:
> -    items:
> -      - const: aclk
> -      - const: hclk
> -      - const: pclk
> +  clocks: true
> +
> +  clock-names: true

This is, unfortunately, not how we like multiple soc support to be
handled. Instead, the widest constraints are added at the top level
and constrained by the allOf. If none of the names etc are shared, at
least the widest constraints for minItems and maxItems should be able to
be here.

That said, this patch should be squashed with the patch that actually
adds the other device to the binding.

Cheers,
Conor.

>  
>    iommus:
>      maxItems: 1
>  
> -  resets:
> -    items:
> -      - description: AXI
> -      - description: AHB
> -      - description: PCLK IN
> +  resets: true
>  
> -  reset-names:
> -    items:
> -      - const: axi
> -      - const: ahb
> -      - const: pclkin
> +  reset-names: true
>  
>    power-domains:
>      maxItems: 1
> @@ -85,6 +69,38 @@ required:
>    - clocks
>    - ports
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: rockchip,px30-vip
> +    then:
> +      properties:
> +        clocks:
> +          items:
> +            - description: ACLK
> +            - description: HCLK
> +            - description: PCLK
> +
> +        clock-names:
> +          items:
> +            - const: aclk
> +            - const: hclk
> +            - const: pclk
> +
> +        resets:
> +          items:
> +            - description: AXI
> +            - description: AHB
> +            - description: PCLK IN
> +
> +        reset-names:
> +          items:
> +            - const: axi
> +            - const: ahb
> +            - const: pclkin
> +
>  additionalProperties: false
>  
>  examples:
> 
> -- 
> 2.30.2
> 
-------------- 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/20240220/5dd849d7/attachment.sig>

From mathieu.poirier at linaro.org  Tue Feb 20 10:58:36 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 20 Feb 2024 11:58:36 -0700
Subject: [PATCH v3 1/7] remoteproc: Add TEE support
In-Reply-To: <20240214172127.1022199-2-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <20240214172127.1022199-2-arnaud.pouliquen@foss.st.com>
Message-ID: <ZdT2XHNpCaTnfvvR@p14s>

Good morning,

On Wed, Feb 14, 2024 at 06:21:21PM +0100, Arnaud Pouliquen wrote:
> From: Arnaud Pouliquen <arnaud.pouliquen at st.com>
> 
> Add a remoteproc TEE (Trusted Execution Environment) driver
> that will be probed by the TEE bus. If the associated Trusted
> application is supported on secure part this device offers a client
> interface to load a firmware in the secure part.
> This firmware could be authenticated and decrypted by the secure
> trusted application.
> 
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at st.com>
> ---
> update from V2
> - Use 'tee_rproc' prefix for all functions
> - rename tee_rproc_get_loaded_rsc_table to tee_rproc_find_loaded_rsc_table
> - redefine fonction to better match with the rproc_ops structure format
> 	- replace 'struct tee_rproc' parameter by 'struct rproc' parameter
> 	- rename 'rproc_tee_get_rsc_table()' to tee_rproc_get_loaded_rsc_table()
> 	  and rework it to remove the cached_table management.
> 	- introduce tee_rproc_get_context() to get the tee_rproc struct from the
>           rproc struct
> 	- rename tee_rproc_get_loaded_rsc_table() to tee_rproc_find_loaded_rsc_table()
> - remove useless check on tee_rproc_ctx structure in tee_rproc_register()
>   and tee_rproc_unregister()
> - fix test on the return of tee_rproc_ctx = devm_kzalloc()
> - remove useless includes and unused tee_rproc_mem structure.
> ---
>  drivers/remoteproc/Kconfig          |   9 +
>  drivers/remoteproc/Makefile         |   1 +
>  drivers/remoteproc/tee_remoteproc.c | 397 ++++++++++++++++++++++++++++
>  include/linux/tee_remoteproc.h      | 102 +++++++
>  4 files changed, 509 insertions(+)
>  create mode 100644 drivers/remoteproc/tee_remoteproc.c
>  create mode 100644 include/linux/tee_remoteproc.h
> 
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 48845dc8fa85..85299606806c 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -365,6 +365,15 @@ config XLNX_R5_REMOTEPROC
>  
>  	  It's safe to say N if not interested in using RPU r5f cores.
>  
> +
> +config TEE_REMOTEPROC
> +	tristate "trusted firmware support by a TEE application"

s/trusted/Trusted

And the wording will have to change a little, I will advise on this later.

> +	depends on OPTEE
> +	help
> +	  Support for trusted remote processors firmware. The firmware
> +	  authentication and/or decryption are managed by a trusted application.
> +	  This can be either built-in or a loadable module.
> +
>  endif # REMOTEPROC
>  
>  endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 91314a9b43ce..fa8daebce277 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -36,6 +36,7 @@ obj-$(CONFIG_RCAR_REMOTEPROC)		+= rcar_rproc.o
>  obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
>  obj-$(CONFIG_ST_SLIM_REMOTEPROC)	+= st_slim_rproc.o
>  obj-$(CONFIG_STM32_RPROC)		+= stm32_rproc.o
> +obj-$(CONFIG_TEE_REMOTEPROC)		+= tee_remoteproc.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_XLNX_R5_REMOTEPROC)	+= xlnx_r5_remoteproc.o
> diff --git a/drivers/remoteproc/tee_remoteproc.c b/drivers/remoteproc/tee_remoteproc.c
> new file mode 100644
> index 000000000000..ac727e062d00
> --- /dev/null
> +++ b/drivers/remoteproc/tee_remoteproc.c
> @@ -0,0 +1,397 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
> + * Author: Arnaud Pouliquen <arnaud.pouliquen at st.com>
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/remoteproc.h>
> +#include <linux/slab.h>
> +#include <linux/tee_drv.h>
> +#include <linux/tee_remoteproc.h>
> +
> +#include "remoteproc_internal.h"
> +
> +#define MAX_TEE_PARAM_ARRY_MEMBER	4
> +
> +/*
> + * Authentication of the firmware and load in the remote processor memory
> + *
> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
> + * [in]	 params[1].memref:	buffer containing the image of the buffer
> + */
> +#define TA_RPROC_FW_CMD_LOAD_FW		1
> +
> +/*
> + * Start the remote processor
> + *
> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
> + */
> +#define TA_RPROC_FW_CMD_START_FW	2
> +
> +/*
> + * Stop the remote processor
> + *
> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
> + */
> +#define TA_RPROC_FW_CMD_STOP_FW		3
> +
> +/*
> + * Return the address of the resource table, or 0 if not found
> + * No check is done to verify that the address returned is accessible by
> + * the non secure context. If the resource table is loaded in a protected
> + * memory the access by the non secure context will lead to a data abort.
> + *
> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
> + * [out]  params[1].value.a:	32bit LSB resource table memory address
> + * [out]  params[1].value.b:	32bit MSB resource table memory address
> + * [out]  params[2].value.a:	32bit LSB resource table memory size
> + * [out]  params[2].value.b:	32bit MSB resource table memory size
> + */
> +#define TA_RPROC_FW_CMD_GET_RSC_TABLE	4
> +
> +/*
> + * Return the address of the core dump
> + *
> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
> + * [out] params[1].memref:	address of the core dump image if exist,
> + *				else return Null
> + */
> +#define TA_RPROC_FW_CMD_GET_COREDUMP	5
> +
> +struct tee_rproc__context {

s/tee_rproc__context/tee_rproc_context

as it was in the previous patchset.

> +	struct list_head sessions;
> +	struct tee_context *tee_ctx;
> +	struct device *dev;
> +};
> +
> +static struct tee_rproc__context *tee_rproc_ctx;
> +
> +static void prepare_args(struct tee_rproc *trproc, int cmd,
> +			 struct tee_ioctl_invoke_arg *arg,
> +			 struct tee_param *param, unsigned int num_params)
> +{
> +	memset(arg, 0, sizeof(*arg));
> +	memset(param, 0, MAX_TEE_PARAM_ARRY_MEMBER * sizeof(*param));
> +
> +	arg->func = cmd;
> +	arg->session = trproc->session_id;
> +	arg->num_params = num_params + 1;
> +
> +	param[0] = (struct tee_param) {
> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
> +		.u.value.a = trproc->rproc_id,
> +	};
> +}
> +
> +static struct tee_rproc *tee_rproc_get_context(struct rproc *rproc)
> +{
> +	struct tee_rproc *entry, *tmp;
> +
> +	list_for_each_entry_safe(entry, tmp, &tee_rproc_ctx->sessions, node) {
> +		if (entry->rproc == rproc)
> +			return entry;
> +	}
> +
> +	return NULL;
> +}
> +
> +int tee_rproc_load_fw(struct rproc *rproc, const struct firmware *fw)
> +{
> +	struct tee_ioctl_invoke_arg arg;
> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
> +	struct tee_shm *fw_shm;
> +	int ret;
> +
> +	if (!trproc)
> +		return -EINVAL;
> +
> +	fw_shm = tee_shm_register_kernel_buf(tee_rproc_ctx->tee_ctx, (void *)fw->data, fw->size);
> +	if (IS_ERR(fw_shm))
> +		return PTR_ERR(fw_shm);
> +
> +	prepare_args(trproc, TA_RPROC_FW_CMD_LOAD_FW, &arg, param, 1);
> +
> +	/* Provide the address of the firmware image */
> +	param[1] = (struct tee_param) {
> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
> +		.u.memref = {
> +			.shm = fw_shm,
> +			.size = fw->size,
> +			.shm_offs = 0,
> +		},
> +	};
> +
> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
> +	if (ret < 0 || arg.ret != 0) {
> +		dev_err(tee_rproc_ctx->dev,
> +			"TA_RPROC_FW_CMD_LOAD_FW invoke failed TEE err: %x, ret:%x\n",
> +			arg.ret, ret);
> +		if (!ret)
> +			ret = -EIO;
> +	}
> +
> +	tee_shm_free(fw_shm);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_load_fw);
> +
> +struct resource_table *tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
> +{
> +	struct tee_ioctl_invoke_arg arg;
> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
> +	int ret;
> +
> +	if (!trproc)
> +		return ERR_PTR(-EINVAL);
> +
> +	prepare_args(trproc, TA_RPROC_FW_CMD_GET_RSC_TABLE, &arg, param, 2);
> +
> +	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
> +	param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
> +
> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
> +	if (ret < 0 || arg.ret != 0) {
> +		dev_err(tee_rproc_ctx->dev,
> +			"TA_RPROC_FW_CMD_GET_RSC_TABLE invoke failed TEE err: %x, ret:%x\n",
> +			arg.ret, ret);
> +		return ERR_PTR(-EIO);
> +	}
> +
> +	*table_sz = param[2].u.value.a;
> +
> +	/* If the size is null no resource table defined in the image */
> +	if (!*table_sz)
> +		return NULL;
> +
> +	/* Store the resource table address that would be updated by the remote core. */
> +	trproc->rsc_table = ioremap_wc(param[1].u.value.a, *table_sz);
> +	if (IS_ERR_OR_NULL(trproc->rsc_table)) {
> +		dev_err(tee_rproc_ctx->dev, "Unable to map memory region: %lld+%zx\n",
> +			param[1].u.value.a, *table_sz);
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	return trproc->rsc_table;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_get_loaded_rsc_table);
> +
> +struct resource_table *tee_rproc_find_loaded_rsc_table(struct rproc *rproc,
> +						       const struct firmware *fw)
> +{
> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
> +	size_t table_sz;
> +
> +	if (!trproc)
> +		return ERR_PTR(-EINVAL);
> +
> +	if (!trproc->rsc_table)
> +		trproc->rsc_table = tee_rproc_get_loaded_rsc_table(rproc, &table_sz);
> +
> +	return trproc->rsc_table;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_find_loaded_rsc_table);
> +
> +int tee_rproc_start(struct rproc *rproc)
> +{
> +	struct tee_ioctl_invoke_arg arg;
> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
> +	int ret;
> +
> +	if (!trproc)
> +		return -EINVAL;
> +
> +	prepare_args(trproc, TA_RPROC_FW_CMD_START_FW, &arg, param, 0);
> +
> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
> +	if (ret < 0 || arg.ret != 0) {
> +		dev_err(tee_rproc_ctx->dev,
> +			"TA_RPROC_FW_CMD_START_FW invoke failed TEE err: %x, ret:%x\n",
> +			arg.ret, ret);
> +		if (!ret)
> +			ret = -EIO;
> +	}
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_start);
> +
> +int tee_rproc_stop(struct rproc *rproc)
> +{
> +	struct tee_ioctl_invoke_arg arg;
> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
> +	int ret;
> +
> +	if (!trproc)
> +		return -EINVAL;
> +
> +	prepare_args(trproc, TA_RPROC_FW_CMD_STOP_FW, &arg, param, 0);
> +
> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
> +	if (ret < 0 || arg.ret != 0) {
> +		dev_err(tee_rproc_ctx->dev,
> +			"TA_RPROC_FW_CMD_STOP_FW invoke failed TEE err: %x, ret:%x\n",
> +			arg.ret, ret);
> +		if (!ret)
> +			ret = -EIO;
> +	}
> +	if (trproc->rsc_table)
> +		iounmap(trproc->rsc_table);
> +	trproc->rsc_table = NULL;
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_stop);
> 

I was wondering where this ID is coming from - Is it the ID of the remote
processor service in the secure world or the ID of the program that provides the
service?

More comments tomorrow.

Thanks,
Mathieu

+
> +static const struct tee_client_device_id stm32_tee_rproc_id_table[] = {
> +	{UUID_INIT(0x80a4c275, 0x0a47, 0x4905,
> +		   0x82, 0x85, 0x14, 0x86, 0xa9, 0x77, 0x1a, 0x08)},
> +	{}
> +};
> +
> +struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id)
> +{
> +	struct tee_client_device *tee_device;
> +	struct tee_ioctl_open_session_arg sess_arg;
> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
> +	struct tee_rproc *trproc;
> +	int ret;
> +
> +	/*
> +	 * The device is not probed by the TEE bus. We ignore the reason (bus could be not yet
> +	 * probed or service not available in the secure firmware)
> +	 * Assumption here is that the TEE bus is not probed.
> +	 */
> +	if (!tee_rproc_ctx)
> +		return ERR_PTR(-EPROBE_DEFER);
> +
> +	trproc =  devm_kzalloc(dev, sizeof(*trproc), GFP_KERNEL);
> +	if (!trproc)
> +		return ERR_PTR(-ENOMEM);
> +
> +	tee_device = to_tee_client_device(tee_rproc_ctx->dev);
> +	memset(&sess_arg, 0, sizeof(sess_arg));
> +
> +	/* Open session with rproc_tee load the OP-TEE Trusted Application */
> +	memcpy(sess_arg.uuid, tee_device->id.uuid.b, TEE_IOCTL_UUID_LEN);
> +
> +	sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
> +	sess_arg.num_params = 1;
> +
> +	param[0] = (struct tee_param) {
> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
> +		.u.value.a = rproc_id,
> +	};
> +
> +	ret = tee_client_open_session(tee_rproc_ctx->tee_ctx, &sess_arg, param);
> +	if (ret < 0 || sess_arg.ret != 0) {
> +		dev_err(dev, "tee_client_open_session failed, err: %x\n", sess_arg.ret);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	trproc->parent =  dev;
> +	trproc->rproc_id = rproc_id;
> +	trproc->session_id = sess_arg.session;
> +
> +	list_add_tail(&trproc->node, &tee_rproc_ctx->sessions);
> +
> +	return trproc;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_register);
> +
> +int tee_rproc_unregister(struct tee_rproc *trproc)
> +{
> +	int ret;
> +
> +	ret = tee_client_close_session(tee_rproc_ctx->tee_ctx, trproc->session_id);
> +	if (ret < 0)
> +		dev_err(trproc->parent,	"tee_client_close_session failed, err: %x\n", ret);
> +
> +	list_del(&trproc->node);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_unregister);
> +
> +static int tee_rproc_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
> +{
> +	/* Today we support only the OP-TEE, could be extend to other tees */
> +	return (ver->impl_id == TEE_IMPL_ID_OPTEE);
> +}
> +
> +static int tee_rproc_probe(struct device *dev)
> +{
> +	struct tee_context *tee_ctx;
> +	int ret;
> +
> +	/* Open context with TEE driver */
> +	tee_ctx = tee_client_open_context(NULL, tee_rproc_ctx_match, NULL, NULL);
> +	if (IS_ERR(tee_ctx))
> +		return PTR_ERR(tee_ctx);
> +
> +	tee_rproc_ctx = devm_kzalloc(dev, sizeof(*tee_ctx), GFP_KERNEL);
> +	if (!tee_rproc_ctx) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	tee_rproc_ctx->dev = dev;
> +	tee_rproc_ctx->tee_ctx = tee_ctx;
> +	INIT_LIST_HEAD(&tee_rproc_ctx->sessions);
> +
> +	return 0;
> +err:
> +	tee_client_close_context(tee_ctx);
> +
> +	return ret;
> +}
> +
> +static int tee_rproc_remove(struct device *dev)
> +{
> +	struct tee_rproc *entry, *tmp;
> +
> +	list_for_each_entry_safe(entry, tmp, &tee_rproc_ctx->sessions, node) {
> +		tee_client_close_session(tee_rproc_ctx->tee_ctx, entry->session_id);
> +		list_del(&entry->node);
> +		kfree(entry);
> +	}
> +
> +	tee_client_close_context(tee_rproc_ctx->tee_ctx);
> +
> +	return 0;
> +}
> +
> +MODULE_DEVICE_TABLE(tee, stm32_tee_rproc_id_table);
> +
> +static struct tee_client_driver tee_rproc_fw_driver = {
> +	.id_table	= stm32_tee_rproc_id_table,
> +	.driver		= {
> +		.name		= KBUILD_MODNAME,
> +		.bus		= &tee_bus_type,
> +		.probe		= tee_rproc_probe,
> +		.remove		= tee_rproc_remove,
> +	},
> +};
> +
> +static int __init tee_rproc_fw_mod_init(void)
> +{
> +	return driver_register(&tee_rproc_fw_driver.driver);
> +}
> +
> +static void __exit tee_rproc_fw_mod_exit(void)
> +{
> +	driver_unregister(&tee_rproc_fw_driver.driver);
> +}
> +
> +module_init(tee_rproc_fw_mod_init);
> +module_exit(tee_rproc_fw_mod_exit);
> +
> +MODULE_DESCRIPTION(" TEE remote processor control driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/tee_remoteproc.h b/include/linux/tee_remoteproc.h
> new file mode 100644
> index 000000000000..7c9e91e989ba
> --- /dev/null
> +++ b/include/linux/tee_remoteproc.h
> @@ -0,0 +1,102 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright(c) 2023 STMicroelectronics - All Rights Reserved
> + */
> +
> +#ifndef TEE_REMOTEPROC_H
> +#define TEE_REMOTEPROC_H
> +
> +#include <linux/tee_drv.h>
> +#include <linux/firmware.h>
> +#include <linux/remoteproc.h>
> +
> +struct rproc;
> +
> +/**
> + * struct tee_rproc - TEE remoteproc structure
> + * @node:		Reference in list
> + * @rproc:		Remoteproc reference
> + * @parent:		Parent device
> + * @rproc_id:		Identifier of the target firmware
> + * @session_id:		TEE session identifier
> + * @rsc_table:		Resource table virtual address.
> + */
> +struct tee_rproc {
> +	struct list_head node;
> +	struct rproc *rproc;
> +	struct device *parent;
> +	u32 rproc_id;
> +	u32 session_id;
> +	struct resource_table *rsc_table;
> +};
> +
> +#if IS_ENABLED(CONFIG_TEE_REMOTEPROC)
> +
> +struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id);
> +int tee_rproc_unregister(struct tee_rproc *trproc);
> +
> +int tee_rproc_load_fw(struct rproc *rproc, const struct firmware *fw);
> +struct resource_table *tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz);
> +struct resource_table *tee_rproc_find_loaded_rsc_table(struct rproc *rproc,
> +						       const struct firmware *fw);
> +int tee_rproc_start(struct rproc *rproc);
> +int tee_rproc_stop(struct rproc *rproc);
> +
> +#else
> +
> +static inline struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id)
> +{
> +	return ERR_PTR(-ENODEV);
> +}
> +
> +static inline int tee_rproc_unregister(struct tee_rproc *trproc)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return 0;
> +}
> +
> +static inline int tee_rproc_load_fw(struct rproc *rproc,  const struct firmware *fw)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return 0;
> +}
> +
> +static inline int tee_rproc_start(struct rproc *rproc)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return 0;
> +}
> +
> +static inline int tee_rproc_stop(struct rproc *rproc)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return 0;
> +}
> +
> +static inline struct resource_table *
> +tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return NULL;
> +}
> +
> +static inline struct resource_table *
> +tee_rproc_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return NULL;
> +}
> +#endif /* CONFIG_TEE_REMOTEPROC */
> +#endif /* TEE_REMOTEPROC_H */
> -- 
> 2.25.1
> 


From sean.anderson at seco.com  Tue Feb 20 11:12:52 2024
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 20 Feb 2024 14:12:52 -0500
Subject: [PATCH] arm64: ls1046ardb: Replace XGMII with 10GBASE-R phy mode
In-Reply-To: <20240220145037.kf3avnykjif24kkr@skbuf>
References: <20240220145037.kf3avnykjif24kkr@skbuf>
Message-ID: <191b4477-7b4b-47eb-bb3e-0e4d08b3b32e@seco.com>

On 2/20/24 09:50, Vladimir Oltean wrote:
> Hi Zachary,
>
> On Wed, Feb 14, 2024 at 05:21:54PM -0500, Zachary Goldstein via B4 Relay wrote:
>> From: Zachary Goldstein <zachary.goldstein at concurrent-rt.com>
>>
>> The AQR107 family does not support XGMII, but USXGMII and
>> 10GBASE-R instead. Since ce64c1f77a9d ("net: phy: aquantia: add USXGMII
>> support and warn if XGMII mode is set") the kernel warns about XGMII
>> being used. The LS1046A SoC does not support USXGMII, so use 10GBASE-R
>> instead.
>>
>> Signed-off-by: Zachary Goldstein <zachary.goldstein at concurrent-rt.com>
>> ---
>>  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
>> index 07f6cc6e354a..d2066f733dc5 100644
>> --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
>> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
>> @@ -149,7 +149,7 @@ ethernet at ea000 {
>>
>>      ethernet at f0000 { /* 10GEC1 */
>>              phy-handle = <&aqr106_phy>;
>> -            phy-connection-type = "xgmii";
>> +            phy-connection-type = "10gbase-r";
>>      };
>>
>>      ethernet at f2000 { /* 10GEC2 */
>>
>> ---
>> 2.40.1
>> base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de
>>
>>
>
> You do not need this patch in upstream, and I strongly advise against
> merging it as-is. I've just tested pure net-next on LS1046A-RDB, and I
> can bring up fm1-mac9 without any warning.
>
> You'll notice that commit 5d93cfcf7360 ("net: dpaa: Convert to phylink")
> did this in fman_memac.c:
>
>       /* The internal connection to the serdes is XGMII, but this isn't
>        * really correct for the phy mode (which is the external connection).
>        * However, this is how all older device trees say that they want
>        * 10GBASE-R (aka XFI), so just convert it for them.
>        */
>       if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
>               mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
>
> So, what gets passed to the Aquantia PHY is PHY_INTERFACE_MODE_10GBASER,
> even if in the device tree, phy-connection-type = "xgmii".
>
> Now, _if_ your patch were to be applied on top of upstream, it would
> actually break fm1-mac9 like this (WARN_ON added by me for a call stack
> of the phylink_validate() failure path):
>
> WARNING: CPU: 2 PID: 1 at drivers/net/phy/phylink.c:763 phylink_create+0x8f8/0x90c
> Modules linked in:
> CPU: 2 PID: 1 Comm: swapper/0 Tainted: G        W          6.8.0-rc4-01058-g9e1deba407fb #1812
> Hardware name: LS1046A RDB Board (DT)
> Call trace:
>  phylink_create+0x8f8/0x90c
>  dpaa_netdev_init+0x1a8/0x2c8
>  dpaa_eth_probe+0xd70/0xf64
>  platform_probe+0xa8/0xd0
>  really_probe+0x130/0x2e4
>  __driver_probe_device+0xa0/0x128
>  driver_probe_device+0x3c/0x200
>  __driver_attach+0xe8/0x1b4
>  bus_for_each_dev+0xec/0x144
>  driver_attach+0x24/0x30
>  bus_add_driver+0x154/0x244
>  driver_register+0x68/0x100
>  __platform_driver_register+0x24/0x30
>  dpaa_load+0x34/0x64
>  do_one_initcall+0xf8/0x34c
> ---[ end trace 0000000000000000 ]---
> fsl_dpaa_mac 1af0000.ethernet (unnamed net_device) (uninitialized): failed to validate link configuration for in-band status
> fsl_dpaa_mac 1af0000.ethernet: error -EINVAL: Could not create phylink
> fsl_dpa: probe of dpaa-ethernet.4 failed with error -22
>
> It fails because of this in phylink_validate():
>
>       if (!test_bit(state->interface, interfaces))
>               return -EINVAL;
>
> And state->interface (PHY_INTERFACE_MODE_10GBASER) is not in
> mac_dev->phylink_config.supported_interfaces, because the fman_memac
> code is not prepared to handle this combination.
>
> The device tree node for fm1-mac9 looks like this, generated by an
> awkward merge between the following:
>
>       ethernet at f0000 {
>               phy-connection-type = "xgmii";  // fsl-ls1046a-rdb.dts
>               local-mac-address = [...];      // U-Boot
>               cell-index = <0x8>;             // qoriq-fman3-0-10g-0.dtsi
>               pcsphy-handle = <0x31>;         // qoriq-fman3-0-10g-0.dtsi
>               compatible = "fsl,fman-memac";  // qoriq-fman3-0-10g-0.dtsi
>               reg = <0xf0000 0x1000>;         // qoriq-fman3-0-10g-0.dtsi
>               phy-handle = <&aqr106_phy>;     // fsl-ls1046a-rdb.dts
>               fsl,fman-ports = <0x2f 0x30>;   // qoriq-fman3-0-10g-0.dtsi
>       };
>
> Notice that unlike fm1-mac10 (node "ethernet at f2000"), there is no
> pcs-handle-names property (fm1-mac10 has it defined in fsl-ls1046-post.dtsi,
> whereas fm1-mac9 doesn't. Don't ask me why, I don't know....)

I think this is just because this ethernet is always XFI and never (Q)SGMII.

> So, knowing that of_property_match_string(mac_node, "pcs-handle-names", "xfi")
> will return an error code for fm1-mac9, now please walk through memac_initialization()
> and see what happens in the 2 cases:
>
> - mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII (current device tree). The
>   code creates a default PCS and assigns it to memac->xfi_pcs like this:
>       if (err == -EINVAL || err == -ENODATA)
>               pcs = memac_pcs_create(mac_node, 0);
>       (...)
>       if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
>               memac->xfi_pcs = pcs;
>
> - mac_dev->phy_if == PHY_INTERFACE_MODE_10GBASER (your modification).
>   The code will still create the default PCS, but assign it to
>   memac->sgmii_pcs instead!
>
>       if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) // not XGMII, but 10GBASER!
>               memac->xfi_pcs = pcs;
>       else
>               memac->sgmii_pcs = pcs;
>
> And this is why, with a NULL memac->xfi_pcs, PHY_INTERFACE_MODE_10GBASER
> will not be in phylink's supported_interfaces.
>
> To make your device tree patch work as intended with the current
> mainline code, what you want is to also modify the driver like this:
>
> From d6bda34b132d17d1c236d27436b9335fac22c062 Mon Sep 17 00:00:00 2001
> From: Vladimir Oltean <vladimir.oltean at nxp.com>
> Date: Tue, 20 Feb 2024 16:12:27 +0200
> Subject: [PATCH] net: dpaa: fman_memac: accept phy-interface-type =
>  "10gbase-r" in the device tree
>
> We support the phy-interface-mode = "xgmii" conversion to "10gbase-r"
> through code, but not actually through the device tree proper. This is
> because boards such as LS1046A-RDB do not define pcs-handle-names in the
> ethernet at f0000 device tree node, and the code only has fallback xfi_pcs
> determination logic for "xgmii".
>
> By reversing the order between the fallback xfi_pcs assignment and the
> "xgmii" overwrite with "10gbase-r", we are able to support both values
> in the device tree, with identical behavior.
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> ---
>  .../net/ethernet/freescale/fman/fman_memac.c   | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
> index e30bf75b1d48..0996759907a8 100644
> --- a/drivers/net/ethernet/freescale/fman/fman_memac.c
> +++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
> @@ -1076,6 +1076,14 @@ int memac_initialization(struct mac_device *mac_dev,
>       unsigned long            capabilities;
>       unsigned long           *supported;
>
> +     /* The internal connection to the serdes is XGMII, but this isn't
> +      * really correct for the phy mode (which is the external connection).
> +      * However, this is how all older device trees say that they want
> +      * 10GBASE-R (aka XFI), so just convert it for them.
> +      */
> +     if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
> +             mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
> +
>       mac_dev->phylink_ops            = &memac_mac_ops;
>       mac_dev->set_promisc            = memac_set_promiscuous;
>       mac_dev->change_addr            = memac_modify_mac_address;
> @@ -1142,7 +1150,7 @@ int memac_initialization(struct mac_device *mac_dev,
>        * (and therefore that xfi_pcs cannot be set). If we are defaulting to
>        * XGMII, assume this is for XFI. Otherwise, assume it is for SGMII.
>        */
> -     if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
> +     if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_10GBASER)
>               memac->xfi_pcs = pcs;
>       else
>               memac->sgmii_pcs = pcs;
> @@ -1156,14 +1164,6 @@ int memac_initialization(struct mac_device *mac_dev,
>               goto _return_fm_mac_free;
>       }
>
> -     /* The internal connection to the serdes is XGMII, but this isn't
> -      * really correct for the phy mode (which is the external connection).
> -      * However, this is how all older device trees say that they want
> -      * 10GBASE-R (aka XFI), so just convert it for them.
> -      */
> -     if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
> -             mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
> -
>       /* TODO: The following interface modes are supported by (some) hardware
>        * but not by this driver:
>        * - 1000BASE-KX

Can you please submit this patch? I noticed this but never had the chance to go
back and debug it.

--Sean

> But!
>
> Device tree is stable ABI, and changes made to the device tree file are
> meant to be backwards and forwards compatible with the code (it can be
> provided separately and not necessarily in lockstep with the kernel
> version. For example, I understand Arm SystemReady IR wants U-Boot to
> provide its own device tree to Linux through EFI). So, in general,
> device tree changes which only work with a corresponding kernel change
> are frowned upon (unless maybe if the kernel change is a bug fix that is
> backported to all relevant stable kernel branches).
>
> So at this stage we should take a step back and re-analyze the cost/benefit.
> You said there is a stack trace in the Aquantia PHY driver, which there
> is not (in current mainline kernels). I _think_ you are seeing the stack
> trace with LSDK, which is currently distributed on top of linux-6.1.y
> and has not yet integrated the fman_memac conversion to phylink - thus,
> it does not contain commit 5d93cfcf7360 ("net: dpaa: Convert to phylink").
> At least, I do see this stack trace there. I think it can also be seen
> with mainline kernels before the phylink conversion, but I did not test
> those.
>
> The main take-away is: ALWAYS test the patch you are submitting to the
> target kernel it is going to be applied to. Especially in the area of
> device tree bindings for DPAA1, things are rarely as simple as they
> appear :) If you don't, you will have an unintended negative effect
> upon current mainline kernels (which must still work), and not the
> intended effect upon LSDK (more below).
>
> There are a few options to go forward from here.
>
> As there is nothing broken in the mainline kernel where you are
> submitting this patch, the simplest one, as bland as it may sound, is
> simply to wait for a new LSDK release on top of linux-6.6.y. Even in
> lf-6.1.y, AFAICS, nothing is broken except for the stack trace. You can
> keep the patch in your local kernel tree copy to suppress that.
>
> The other option would be to submit the fman_memac change as a bug fix
> for stable, wait for a while for it to have time to propagate, then
> modify the device tree as well. But, it is much higher effort, and
> there is no procedure in place, AFAIK, for LSDK to integrate your patch
> (other than through upstream + a few months of waiting). The upcoming
> LSDK release will be on top of linux-6.6.y, it will make your effort
> irrelevant if it's only for suppressing the stack trace, and you are
> racing against it. This path is only worth it if you have the dedication
> to dig a bit deeper and tidy things up in the DPAA1 kernel support
> (which would be appreciated though).
>
> _If_ you are using an older linux-stable branch but not LSDK, yes, the
> feedback loop between your patch and its effect will close much sooner,
> but you will have to convince the linux-stable people that it's worth
> accepting your driver rework patches for a functional reason and not
> just aesthetic (see Documentation/process/stable-kernel-rules.rst for
> reference).
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> https://cas5-0-urlprotect.trendmicro.com:443/wis/clicktime/v1/query?url=http%3a%2f%2flists.infradead.org%2fmailman%2flistinfo%2flinux%2darm%2dkernel&umid=8bfcbf91-eb84-4daf-8653-378929ed0326&auth=d807158c60b7d2502abde8a2fc01f40662980862-d89d931594581c69e3bf19f86f11d6de905c5a8b


[Embedded World 2024, SECO SpA]<https://www.messe-ticket.de/Nuernberg/embeddedworld2024/Register/ew24517689>


From dalias at libc.org  Tue Feb 20 10:57:15 2024
From: dalias at libc.org (Rich Felker)
Date: Tue, 20 Feb 2024 13:57:15 -0500
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
Message-ID: <20240220185714.GO4163@brightrain.aerifal.cx>

On Tue, Feb 20, 2024 at 06:41:05PM +0000, Edgecombe, Rick P wrote:
> Hi,
> 
> I worked on the x86 kernel shadow stack support. I think it is an
> interesting suggestion. Some questions below, and I will think more on
> it.
> 
> On Tue, 2024-02-20 at 11:36 -0500, Stefan O'Rear wrote:
> > While discussing the ABI implications of shadow stacks in the context
> > of
> > Zicfiss and musl a few days ago, I had the following idea for how to
> > solve
> > the source compatibility problems with shadow stacks in POSIX.1-2004
> > and
> > POSIX.1-2017:
> > 
> > 1. Introduce a "flexible shadow stack handling" option.? For what
> > follows,
> > ?? it doesn't matter if this is system-wide, per-mm, or per-vma.
> > 
> > 2. Shadow stack faults on non-shadow stack pages, if flexible shadow
> > stack
> > ?? handling is in effect, cause the affected page to become a shadow
> > stack
> > ?? page.? When this happens, the page filled with invalid address
> > tokens.
> 
> Hmm, could the shadow stack underflow onto the real stack then? Not
> sure how bad that is. INCSSP (incrementing the SSP register on x86)
> loops are not rare so it seems like something that could happen.

Shadow stack underflow should fault on attempt to access
non-shadow-stack memory as shadow-stack, no?

> > ?? Faults from non-shadow-stack accesses to a shadow-stack page which
> > was
> > ?? created by the previous paragraph will cause the page to revert to
> > ?? non-shadow-stack usage, with or without clearing.
> 
> Won't this prevent catching stack overflows when they happen? An
> overflow will just turn the shadow stack into normal stack and only get
> detected when the shadow stack unwinds?

I don't think that's as big a problem as it sounds like. It might make
pinpointing the spot at which things went wrong take a little bit more
work, but it should not admit any wrong-execution.

> A related question would be how to handle the expanding nature of the
> initial stack. I guess the initial stack could be special and have a
> separate shadow stack.

That seems fine.

> > ?? Important: a shadow stack operation can only load a valid address
> > from
> > ?? a page if that page has been in continuous shadow stack use since
> > the
> > ?? address was written by another shadow stack operation; the
> > flexibility
> > ?? delays error reporting in cases of stray writes but it never
> > allows for
> > ?? corruption of shadow stack operation.
> 
> Shadow stacks currently have automatic guard gaps to try to prevent one
> thread from overflowing onto another thread's shadow stack. This would
> somewhat opens that up, as the stack guard gaps are usually maintained
> by userspace for new threads. It would have to be thought through if
> these could still be enforced with checking at additional spots.

I would think the existing guard pages would already do that if a
thread's shadow stack is contiguous with its own data stack.

> > 3. Standards-defined operations which use a user-provided stack
> > ?? (makecontext, sigaltstack, pthread_attr_setstack) use a subrange
> > of the
> > ?? provided stack for shadow stack storage.? I propose to use a
> > shadow
> > ?? stack size of 1/32 of the provided stack size, rounded up to a
> > positive
> > ?? integer number of pages, and place the shadow stack allocation at
> > the
> > ?? lowest page-aligned address inside the provided stack region.
> > 
> > ?? Since page usage is flexible, no change in page permissions is
> > ?? immediately needed; this merely sets the initial shadow stack
> > pointer for
> > ?? the new context.
> > 
> > ?? If the shadow stack grew in the opposite direction to the
> > architectural
> > ?? stack, it would not be necessary to pick a fixed direction.
> > 
> > 4. SIGSTKSZ and MINSIGSTKSZ are increased by 2 pages to provide
> > sufficient
> > ?? space for a minimum-sized shadow stack region and worst case
> > alignment.
> 
> Do all makecontext() callers ensure the size is greater than this?
> 
> I guess glibc's makecontext() could do this scheme to prevent leaking
> without any changes to the kernel. Basically steal a little of the
> stack address range and overwrite it with a shadow stack mapping. But
> only if the apps leave enough room. If they need to be updated, then
> they could be updated to manage their own shadow stacks too I think.

>From the musl side, I have always looked at the entirely of shadow
stack stuff with very heavy skepticism, and anything that breaks
existing interface contracts, introduced places where apps can get
auto-killed because a late resource allocation fails, or requires
applications to code around the existence of something that should be
an implementation detail, is a non-starter. To even consider shadow
stack support, it must truely be fully non-breaking.

> > _Without_ doing this, sigaltstack cannot be used to recover from
> > stack
> > overflows if the shadow stack limit is reached first, and makecontext
> > cannot be supported without memory leaks and unreportable error
> > conditions.
> 
> FWIW, I think the makecontext() shadow stack leaking is a bad idea. I
> would prefer the existing makecontext() interface just didn't support
> shadow stack, rather than the leaking solution glibc does today.

AIUI the proposal by Stefan makes it non-leaking because it's just
using normal memory that reverts to normal usage on any
non-shadow-stack access.

Rich


From b-brnich at ti.com  Tue Feb 20 11:14:09 2024
From: b-brnich at ti.com (Brandon Brnich)
Date: Tue, 20 Feb 2024 13:14:09 -0600
Subject: [PATCH v5 0/4] Add Support for Wave5 on TI Devices
Message-ID: <20240220191413.3355007-1-b-brnich@ti.com>

This series is responsible for adding support for Wave5 driver[0]
across numerous TI K3 platforms.

[0]: https://lore.kernel.org/all/ae6d2ad3-0b2a-462a-a9eb-9ce01e7a7f5e at xs4all.nl/

Changes since v4:
=================
* Remove clock-names from device tree nodes per Vignesh's request
  - "vcodec" clock-name is defined as macro in driver, but unused
  - no purpose to have it in dt node

Changes since v3:
=================

* Address Andrew's comments
  - remove disabled by default on all platforms
  - reorder addresses in 84s4 to be correctly sorted

Changes since v2:
=================

* Remove reference to k3 as requested
* Rebase on v6.8-rc2 where new bindings are present
* Remove am62a dts entry until hrtimer[1] patch gets merged

[1]: https://patchwork.kernel.org/project/linux-media/patch/20240125130833.1953617-1-devarsht at ti.com/

Changes since v1:
=================

* Remove sram parameters
  - sram-size property not included in bindings. Without this, size
  will default to 0 so no point in specifying until binding is added.
* Remove global CMA pools for each platform
  - This is something that has been added in TI backport of driver
  and does not yet have reliable support in upstream version.
  - Removing for now with intention to add back once 48-bit
  addressing is supported in upstream Wave5 driver.

Brandon Brnich (3):
  arm64: dts: ti: k3-j784s4: Add Wave5 Video Encoder/Decoder Node
  arm64: dts: ti: k3-am62p: Add Wave5 Video Encoder/Decoder Node
  arm64: defconfig: Enable Wave5 Video Encoder/Decoder

Darren Etheridge (1):
  arm64: dts: ti: k3-j721s2-main: Add Wave5 Video Encoder/Decoder Node

 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi  |  8 ++++++++
 arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi |  8 ++++++++
 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 16 ++++++++++++++++
 arch/arm64/boot/dts/ti/k3-j784s4.dtsi      |  2 ++
 arch/arm64/configs/defconfig               |  1 +
 5 files changed, 35 insertions(+)

-- 
2.34.1



From b-brnich at ti.com  Tue Feb 20 11:14:10 2024
From: b-brnich at ti.com (Brandon Brnich)
Date: Tue, 20 Feb 2024 13:14:10 -0600
Subject: [PATCH v5 1/4] arm64: dts: ti: k3-j784s4: Add Wave5 Video Encoder/Decoder Node
In-Reply-To: <20240220191413.3355007-1-b-brnich@ti.com>
References: <20240220191413.3355007-1-b-brnich@ti.com>
Message-ID: <20240220191413.3355007-2-b-brnich@ti.com>

This patch adds support for the Wave521cl on the J784S4-evm.

Signed-off-by: Brandon Brnich <b-brnich at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 16 ++++++++++++++++
 arch/arm64/boot/dts/ti/k3-j784s4.dtsi      |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
index f2b720ed1e4f..40dd2e8a9f98 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -662,6 +662,22 @@ main_i2c6: i2c at 2060000 {
 		status = "disabled";
 	};
 
+	vpu0: video-codec at 4210000 {
+		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+		reg = <0x00 0x4210000 0x00 0x10000>;
+		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&k3_clks 241 2>;
+		power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>;
+	};
+
+	vpu1: video-codec at 4220000 {
+		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+		reg = <0x00 0x4220000 0x00 0x10000>;
+		interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&k3_clks 242 2>;
+		power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
+	};
+
 	main_sdhci0: mmc at 4f80000 {
 		compatible = "ti,j721e-sdhci-8bit";
 		reg = <0x00 0x04f80000 0x00 0x1000>,
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
index 4398c3a463e1..2f633721a0c6 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
@@ -235,6 +235,8 @@ cbass_main: bus at 100000 {
 		ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
 			 <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
 			 <0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */
+			 <0x00 0x04210000 0x00 0x04210000 0x00 0x00010000>, /* VPU0 */
+			 <0x00 0x04220000 0x00 0x04220000 0x00 0x00010000>, /* VPU1 */
 			 <0x00 0x0d000000 0x00 0x0d000000 0x00 0x01000000>, /* PCIe Core*/
 			 <0x00 0x10000000 0x00 0x10000000 0x00 0x08000000>, /* PCIe0 DAT0 */
 			 <0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */
-- 
2.34.1



From b-brnich at ti.com  Tue Feb 20 11:14:11 2024
From: b-brnich at ti.com (Brandon Brnich)
Date: Tue, 20 Feb 2024 13:14:11 -0600
Subject: [PATCH v5 2/4] arm64: dts: ti: k3-j721s2-main: Add Wave5 Video Encoder/Decoder Node
In-Reply-To: <20240220191413.3355007-1-b-brnich@ti.com>
References: <20240220191413.3355007-1-b-brnich@ti.com>
Message-ID: <20240220191413.3355007-3-b-brnich@ti.com>

From: Darren Etheridge <detheridge at ti.com>

Add the Chips and Media wave521cl video decoder/encoder node on J721S2.

Signed-off-by: Darren Etheridge <detheridge at ti.com>
Signed-off-by: Brandon Brnich <b-brnich at ti.com>
---
 arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
index ea7f2b2ab165..d1e5cb26f317 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -716,6 +716,14 @@ main_i2c6: i2c at 2060000 {
 		status = "disabled";
 	};
 
+	vpu: video-codec at 4210000 {
+		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+		reg = <0x00 0x4210000 0x00 0x10000>;
+		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&k3_clks 179 2>;
+		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
+	};
+
 	main_sdhci0: mmc at 4f80000 {
 		compatible = "ti,j721e-sdhci-8bit";
 		reg = <0x00 0x04f80000 0x00 0x1000>,
-- 
2.34.1



From b-brnich at ti.com  Tue Feb 20 11:14:12 2024
From: b-brnich at ti.com (Brandon Brnich)
Date: Tue, 20 Feb 2024 13:14:12 -0600
Subject: [PATCH v5 3/4] arm64: dts: ti: k3-am62p: Add Wave5 Video Encoder/Decoder Node
In-Reply-To: <20240220191413.3355007-1-b-brnich@ti.com>
References: <20240220191413.3355007-1-b-brnich@ti.com>
Message-ID: <20240220191413.3355007-4-b-brnich@ti.com>

This patch adds support for the Wave521cl on the AM62P.

Signed-off-by: Brandon Brnich <b-brnich at ti.com>
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 4c51bae06b57..fd346e01e44e 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -891,4 +891,12 @@ mcasp2: audio-controller at 2b20000 {
 		power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
 		status = "disabled";
 	};
+
+	vpu: video-codec at 30210000 {
+		compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+		reg = <0x00 0x30210000 0x00 0x10000>;
+		interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&k3_clks 204 2>;
+		power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
+	};
 };
-- 
2.34.1



From b-brnich at ti.com  Tue Feb 20 11:14:13 2024
From: b-brnich at ti.com (Brandon Brnich)
Date: Tue, 20 Feb 2024 13:14:13 -0600
Subject: [PATCH v5 4/4] arm64: defconfig: Enable Wave5 Video Encoder/Decoder
In-Reply-To: <20240220191413.3355007-1-b-brnich@ti.com>
References: <20240220191413.3355007-1-b-brnich@ti.com>
Message-ID: <20240220191413.3355007-5-b-brnich@ti.com>

Enable Wave521c video decoder/encoder driver on all TI K3 platforms that
contain the IP.

Signed-off-by: Brandon Brnich <b-brnich at ti.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e6cf3e5d63c3..6fe4f2da4aca 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -795,6 +795,7 @@ CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_CADENCE_CSI2RX=m
 CONFIG_VIDEO_MEDIATEK_JPEG=m
 CONFIG_VIDEO_MEDIATEK_VCODEC=m
+CONFIG_VIDEO_WAVE_VPU=m
 CONFIG_VIDEO_IMX7_CSI=m
 CONFIG_VIDEO_IMX_MIPI_CSIS=m
 CONFIG_VIDEO_IMX8_ISI=m
-- 
2.34.1



From conor at kernel.org  Tue Feb 20 11:25:28 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 20 Feb 2024 19:25:28 +0000
Subject: [PATCH v3 2/3] ARM: dts: microchip: sama7g5: Add flexcom 10 node
In-Reply-To: <0798f21e-1ab6-4fd2-b7e3-18f35163fad1@tuxon.dev>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
 <20240215091524.14732-3-mihai.sain@microchip.com>
 <20240215-lustily-flick-69cb48b123c3@spud>
 <PH8PR11MB6804E9353A8EEBD2B829D8B3824C2@PH8PR11MB6804.namprd11.prod.outlook.com>
 <20240216075609e58aeee4@mail.local>
 <cfafd563-1387-4775-bcb0-434ce3774827@tuxon.dev>
 <20240216-eleven-exposure-dde558e63aaf@wendy>
 <0798f21e-1ab6-4fd2-b7e3-18f35163fad1@tuxon.dev>
Message-ID: <20240220-lapel-diaper-0914f6da3beb@spud>

On Mon, Feb 19, 2024 at 08:45:45PM +0200, claudiu beznea wrote:
> 
> 
> On 16.02.2024 11:35, Conor Dooley wrote:
> > On Fri, Feb 16, 2024 at 10:24:13AM +0200, claudiu beznea wrote:
> >> On 16.02.2024 09:56, Alexandre Belloni wrote:
> >>> On 16/02/2024 06:58:10+0000, Mihai.Sain at microchip.com wrote:
> >>>>> diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> >>>>> index 269e0a3ca269..c030b318985a 100644
> >>>>> --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
> >>>>> +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> >>>>> @@ -958,6 +958,30 @@ i2c9: i2c at 600 {
> >>>>>  			};
> >>>>>  		};
> >>>>>  
> >>>>> +		flx10: flexcom at e2820000 {
> >>>>> +			compatible = "atmel,sama5d2-flexcom";
> >>>>
> >>>> My comment here was ignored:
> >>>> https://lore.kernel.org/all/20240214-robe-pregnancy-a1b056c9fe14 at spud/
> >>>>
> >>>> The SAMA7G5 has the same flexcom controller as SAMA5D2 MPU.
> >>>>
> >>>
> >>> Still, it needs its own compatible plus a fallback to
> >>> atmel,sama5d2-flexcom
> >>
> >> I agree with this. Though, flexcom documentation is subject to YAML
> >> conversion (a patch has been re-posted these days [1] and *maybe* it will
> >> be integrated this time). And there are multiple SoC DTs that need to be
> >> updated with their own flexcom compatible (lan966x, sam9x60, sama7g5).
> >>
> >> To avoid conflicting with the work at [1] and postponing this series we may
> >> do the update after the [1] is done.
> >>
> >> Let me know your thoughts. Either way is fine by me.
> > 
> > I'd be inclined to say that if we are gonna take a shortcut here, then
> > this patch should add a specific compatible so that when the yaml
> > conversion goes through you'll get a warning about this being
> > undocumented rather than silence.
> 
> All the flexcom nodes from all flexcom capable SoCs (including SAMA7G5)
> have the same compatible introduced by Mihai.
> 
> I don't like the idea of updating only the DTSes, either update all DTSes
> and documentation or do it as it is already done (with sama5d2 compatible).
> 
> > 
> > A resend on the flexcom patch is required though, the rebase was not
> > done correctly, so maybe Balakrishnan could "atmel,sama7g5-flexcom"
> > add with a fallback to "atmel,sama5d2-flexcom" while they're fixing
> > it up?
> 
> I agree, and DTSes should also be updated along with documentation.

I'm biased, I'll almost never disagree with updating things to use
soc-specific compatibles...

> With this we can go forward with this patch and avoid conflicting with work
> that is currently in progress for flexcom.

I forgot to actually CC Balakrishnan, but Nicolas fortunately forwarded
it to them. They're added now though to make sure they see this.
-------------- 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/20240220/1ca0f02d/attachment.sig>

From conor at kernel.org  Tue Feb 20 11:32:53 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 20 Feb 2024 19:32:53 +0000
Subject: [PATCH v2] dt-bindings: interrupt-controller: Convert Atmel AIC
 to json-schema
In-Reply-To: <a97650cd-8e06-4df6-9757-826c00a4d7cc@microchip.com>
References: <20240209100122.61335-1-dharma.b@microchip.com>
 <20240212140824.GA107736-robh@kernel.org>
 <003d61c9-b914-4e1c-b3f8-1140ea640039@microchip.com>
 <20240213-estranged-charger-bf0372f367e0@spud>
 <a97650cd-8e06-4df6-9757-826c00a4d7cc@microchip.com>
Message-ID: <20240220-carmaker-subprime-112c44f4f2e6@spud>

On Mon, Feb 19, 2024 at 03:30:52PM +0000, Dharma.B at microchip.com wrote:
> Hi Rob and Conor,
> 
> On 14/02/24 12:43 am, Conor Dooley wrote:
> > On Tue, Feb 13, 2024 at 04:23:36AM +0000,Dharma.B at microchip.com  wrote:
> >> On 12/02/24 7:38 pm, Rob Herring wrote:
> >>> On Fri, Feb 09, 2024 at 03:31:22PM +0530, Dharma Balasubiramani wrote:
> >>>> +  atmel,external-irqs:
> >>>> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> >>>> +    description: u32 array of external irqs.
> >>> Constraints on the array size and/or entry values?
> >> The hardware's support for external IRQs may differ, which is why a u32
> >> array is utilized. This choice is based on the fact that IRQ numbers are
> >> commonly expressed as integers, and a 32-bit unsigned integer provides a
> >> standardized size capable of representing a broad range of numbers. This
> >> size is more than adequate for accommodating IRQ numbering.
> > I don't think Rob was questioning your use of u32s, but rather the fact
> > that you do not limit the values at all nor the number of values.
> 
> The peripheral identification defined at the product level corresponds 
> to the interrupt source number.
> 
> SoC           External Interrupts    Peripheral ID
> AT91RM9200    - IRQ0?IRQ6            25 - 31
> SAMA5D2       - IRQ0?IRQn            49
> SAMA5D3       - IRQ0?IRQn            47
> SAMA5D4       - IRQ0?IRQn            56
> SAM9x60       - IRQ0?IRQn            31
> 
> To reflect these constraints in bindings, I intend to make the following 
> changes.
> 
>    atmel,external-irqs:
>      $ref: /schemas/types.yaml#/definitions/uint32-array
>      description: u32 array of external irqs.

>      if:
>        properties:
>          compatible:
>            contains:
>              const: atmel,at91rm9200-aic
>      then:
>        minItems: 1
>        maxItems: 7
>      else:
>        minItems: 1
>        maxItems: 1

Just to point out, that if this is not psuedocode, the syntax here is
not quite right. It should be:

allOf:
- if:
    properties:
      compatible:
        contains:
          const: atmel,at91rm9200-aic
  then:
    properties:
      atmel,external-irqs:
        minItems: 1
        maxItems: 7
  else:
    properties:
      atmel,external-irqs:
        minItems: 1
        maxItems: 1

But you can simply this further by applying minItems: 1 & maxitems: 7
to the property directly and just setting maxItems: 1 when the
compatible is not atmel,at91rm9200-aic.

There should be plenty of examples in-tree for you to copy this sort of
thing from - clock-names is a property you often see this used for.

Cheers,
Conor.
-------------- 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/20240220/6407956f/attachment.sig>

From minyard at acm.org  Tue Feb 20 11:33:13 2024
From: minyard at acm.org (Corey Minyard)
Date: Tue, 20 Feb 2024 13:33:13 -0600
Subject: [PATCH] ipmi: kcs: Update OBF poll timeout to reduce latency
In-Reply-To: <a9169894-6972-49c0-a1d4-d80863f5b511@molgen.mpg.de>
References: <20240220123615.963916-1-geissonator@gmail.com>
 <a9169894-6972-49c0-a1d4-d80863f5b511@molgen.mpg.de>
Message-ID: <ZdT+eThnYqb3iawF@mail.minyard.net>

On Tue, Feb 20, 2024 at 04:51:21PM +0100, Paul Menzel wrote:
> Dear Andrew,
> 
> 
> Thank you for your patch. Some style suggestions.
> 
> Am 20.02.24 um 13:36 schrieb Andrew Geissler:
> > From: Andrew Geissler <geissonator at yahoo.com>
> 
> (Oh no, Yahoo. (ignore))
> 
> You could be more specific in the git commit message by using *Double*:
> 
> > ipmi: kcs: Double OBF poll timeout to reduce latency
> 
> > ipmi: kcs: Double OBF poll timeout to 200 us to reduce latency
> 
> > Commit f90bc0f97f2b ("ipmi: kcs: Poll OBF briefly to reduce OBE
> > latency") introduced an optimization to poll when the host has

I assume that removing that patch doesn't fix the issue, it would only
make it worse, right?

> > read the output data register (ODR). Testing has shown that the 100us
> > timeout was not always enough. When we miss that 100us window, it
> > results in 10x the time to get the next message from the BMC to the
> > host. When you're sending 100's of messages between the BMC and Host,
> 
> I do not understand, how this poll timeout can result in such an increase,
> and why a quite big timeout hurts, but I do not know the implementation.

It's because increasing that number causes it to poll longer for the
event, the host takes longer than 100us to generate the event, and if
the event is missed the time when it is checked again is very long.

Polling for 100us is already pretty extreme. 200us is really too long.

The real problem is that there is no interrupt for this.  I'd also guess
there is no interrupt on the host side, because that would solve this
problem, too, as it would certainly get around to handling the interupt
in 100us.  I'm assuming the host driver is not the Linux driver, as it
should also handle this in a timely manner, even when polling.

If people want hardware to perform well, they ought to design it and not
expect software to fix all the problems.

The right way to fix this is probably to do the same thing the host side
Linux driver does.  It has a kernel thread that is kicked off to do
this.  Unfortunately, that's more complicated to implement, but it
avoids polling in this location (which causes latency issues on the BMC
side) and lets you poll longer without causing issues.

I'll let the people who maintain that code comment.

-corey

> 
> > this results in a server boot taking 50% longer for IBM P10 machines.
> > 
> > Started with 1000 and worked it down until the issue started to reoccur.
> > 200 was the sweet spot in my testing. 150 showed the issue
> > intermittently.
> 
> I?d add a blank line here.
> 
> > Signed-off-by: Andrew Geissler <geissonator at yahoo.com>
> > ---
> >   drivers/char/ipmi/kcs_bmc_aspeed.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c
> > index 72640da55380..af1eae6153f6 100644
> > --- a/drivers/char/ipmi/kcs_bmc_aspeed.c
> > +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
> > @@ -422,7 +422,7 @@ static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask,
> >   			 * missed the event.
> >   			 */
> >   			rc = read_poll_timeout_atomic(aspeed_kcs_inb, str,
> > -						      !(str & KCS_BMC_STR_OBF), 1, 100, false,
> > +						      !(str & KCS_BMC_STR_OBF), 1, 200, false,
> >   						      &priv->kcs_bmc, priv->kcs_bmc.ioreg.str);
> >   			/* Time for the slow path? */
> >   			if (rc == -ETIMEDOUT)
> 
> 
> Kind regards,
> 
> Paul


From ryan.roberts at arm.com  Tue Feb 20 11:50:37 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 20 Feb 2024 20:50:37 +0100
Subject: [PATCH v6 12/18] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <f9fc2b31-11cb-4969-8961-9c89fea41b74@nvidia.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-13-ryan.roberts@arm.com> <Zc9UQy-mtYAzNWm2@arm.com>
 <892caa6a-e4fe-4009-aa33-0570526961c5@arm.com> <Zc-Tqqfksho3BHmU@arm.com>
 <f9fc2b31-11cb-4969-8961-9c89fea41b74@nvidia.com>
Message-ID: <061b8c8a-51cc-46b0-8a2d-90bf6c6ce5d8@arm.com>

On 16/02/2024 19:54, John Hubbard wrote:
> On 2/16/24 08:56, Catalin Marinas wrote:
> ...
>>> The problem is that the contpte_* symbols are called from the ptep_* inline
>>> functions. So where those inlines are called from modules, we need to make sure
>>> the contpte_* symbols are available.
>>>
>>> John Hubbard originally reported this problem against v1 and I enumerated all
>>> the drivers that call into the ptep_* inlines here:
>>> https://lore.kernel.org/linux-arm-kernel/b994ff89-1a1f-26ca-9479-b08c77f94be8 at arm.com/#t
>>>
>>> So they definitely need to be exported. Perhaps we can tighten it to
> 
> Yes. Let's keep the in-tree modules working.
> 
>>> EXPORT_SYMBOL_GPL(), but I was being cautious as I didn't want to break anything
>>> out-of-tree. I'm not sure what the normal policy is? arm64 seems to use ~equal
>>> amounts of both.
> 
> EXPORT_SYMBOL_GPL() seems appropriate and low risk. As Catalin says below,
> these really are deeply core mm routines, and any module operating at this
> level is not going to be able to survive on EXPORT_SYMBOL alone, IMHO.
> 
> Now, if only I could find an out of tree module to test that claim on... :)
> 
> 
>> I don't think we are consistent here. For example set_pte_at() can't be
>> called from non-GPL modules because of __sync_icache_dcache. OTOH, such
>> driver is probably doing something dodgy. Same with
>> apply_to_page_range(), it's GPL-only (called from i915).
>>
>> Let's see if others have any view over the next week or so, otherwise
>> I'd go for _GPL and relax it later if someone has a good use-case (can
>> be a patch on top adding _GPL).
> 
> I think going directly to _GPL for these is fine, actually.

OK I'll send out a patch to convert these to _GPL on my return on Monday.
Hopefully Andrew will be able to squash the patch into the existing series.

> 
> 
> thanks,



From ryan.roberts at arm.com  Tue Feb 20 11:58:49 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Tue, 20 Feb 2024 20:58:49 +0100
Subject: [PATCH v6 12/18] arm64/mm: Wire up PTE_CONT for user mappings
In-Reply-To: <ZdNxSRR9MgvtMVao@arm.com>
References: <20240215103205.2607016-1-ryan.roberts@arm.com>
 <20240215103205.2607016-13-ryan.roberts@arm.com> <Zc9UQy-mtYAzNWm2@arm.com>
 <892caa6a-e4fe-4009-aa33-0570526961c5@arm.com> <ZdNxSRR9MgvtMVao@arm.com>
Message-ID: <9cb2b8c6-aac8-4130-8558-6646817689e0@arm.com>

On 19/02/2024 15:18, Catalin Marinas wrote:
> On Fri, Feb 16, 2024 at 12:53:43PM +0000, Ryan Roberts wrote:
>> On 16/02/2024 12:25, Catalin Marinas wrote:
>>> On Thu, Feb 15, 2024 at 10:31:59AM +0000, Ryan Roberts wrote:
>>>> +pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
>>>> +{
>>>> +	/*
>>>> +	 * Gather access/dirty bits, which may be populated in any of the ptes
>>>> +	 * of the contig range. We may not be holding the PTL, so any contiguous
>>>> +	 * range may be unfolded/modified/refolded under our feet. Therefore we
>>>> +	 * ensure we read a _consistent_ contpte range by checking that all ptes
>>>> +	 * in the range are valid and have CONT_PTE set, that all pfns are
>>>> +	 * contiguous and that all pgprots are the same (ignoring access/dirty).
>>>> +	 * If we find a pte that is not consistent, then we must be racing with
>>>> +	 * an update so start again. If the target pte does not have CONT_PTE
>>>> +	 * set then that is considered consistent on its own because it is not
>>>> +	 * part of a contpte range.
>>>> +*/
> [...]
>>> After writing the comments above, I think I figured out that the whole
>>> point of this loop is to check that the ptes in the contig range are
>>> still consistent and the only variation allowed is the dirty/young
>>> state to be passed to the orig_pte returned. The original pte may have
>>> been updated by the time this loop finishes but I don't think it
>>> matters, it wouldn't be any different than reading a single pte and
>>> returning it while it is being updated.
>>
>> Correct. The pte can be updated at any time, before after or during the reads.
>> That was always the case. But now we have to cope with a whole contpte block
>> being repainted while we are reading it. So we are just checking to make sure
>> that all the ptes that we read from the contpte block are consistent with
>> eachother and therefore we can trust that the access/dirty bits we gathered are
>> consistent.
> 
> I've been thinking a bit more about this - do any of the callers of
> ptep_get_lockless() check the dirty/access bits? The only one that seems
> to care is ptdump but in that case I'd rather see the raw bits for
> debugging rather than propagating the dirty/access bits to the rest in
> the contig range.
> 
> So with some clearer documentation on the requirements, I think we don't
> need an arm64-specific ptep_get_lockless() (unless I missed something).

We've discussed similar at [1]. And I've posted an RFC series to convert all
ptep_get_lockless() to ptep_get_lockless_norecency() at [2]. The current spec
for ptep_get_lockless() is that it includes the access and dirty bits. So we
can't just read the single pte - if there is a tlb eviction followed by
re-population for the block, the access/dirty bits could move and that will
break pte_same() comparisons which are used in places.

So the previous conclusion was that we are ok to put this arm64-specific
ptep_get_lockless() in for now, but look to simplify by migrating to
ptep_get_lockless_norecency() in future. Are you ok with that approach?

[1]
https://lore.kernel.org/linux-mm/a91cfe1c-289e-4828-8cfc-be34eb69a71b at redhat.com/
[2] https://lore.kernel.org/linux-mm/20240215121756.2734131-1-ryan.roberts at arm.com/

Thanks,
Ryan



From rafael at kernel.org  Tue Feb 20 11:59:09 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Tue, 20 Feb 2024 20:59:09 +0100
Subject: [PATCH RFC v4 02/15] ACPI: processor: Register all CPUs from acpi_processor_get_info()
In-Reply-To: <20240220162406.00005b59@Huawei.com>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk> <E1rVDmU-0027YP-Jz@rmk-PC.armlinux.org.uk>
 <CAJZ5v0iiJpUWq5GMSnKFWQTzn_bdwoQz9m=hDaXNg4Lj_ePF4g@mail.gmail.com>
 <ZdSMk93c1I6x973h@shell.armlinux.org.uk> <ZdTBtt0oR6Q1RcAB@shell.armlinux.org.uk>
 <20240220162406.00005b59@Huawei.com>
Message-ID: <CAJZ5v0i0c3bg8E9yuRk00VAEW5isZ4N-mbnhRuTR8aiFLXo1_A@mail.gmail.com>

On Tue, Feb 20, 2024 at 5:24?PM Jonathan Cameron
<Jonathan.Cameron at huawei.com> wrote:
>
> On Tue, 20 Feb 2024 15:13:58 +0000
> "Russell King (Oracle)" <linux at armlinux.org.uk> wrote:
>
> > On Tue, Feb 20, 2024 at 11:27:15AM +0000, Russell King (Oracle) wrote:
> > > On Thu, Feb 15, 2024 at 08:22:29PM +0100, Rafael J. Wysocki wrote:
> > > > On Wed, Jan 31, 2024 at 5:50?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:
> > > > > diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> > > > > index cf7c1cca69dd..a68c475cdea5 100644
> > > > > --- a/drivers/acpi/acpi_processor.c
> > > > > +++ b/drivers/acpi/acpi_processor.c
> > > > > @@ -314,6 +314,18 @@ static int acpi_processor_get_info(struct acpi_device *device)
> > > > >                         cpufreq_add_device("acpi-cpufreq");
> > > > >         }
> > > > >
> > > > > +       /*
> > > > > +        * Register CPUs that are present. get_cpu_device() is used to skip
> > > > > +        * duplicate CPU descriptions from firmware.
> > > > > +        */
> > > > > +       if (!invalid_logical_cpuid(pr->id) && cpu_present(pr->id) &&
> > > > > +           !get_cpu_device(pr->id)) {
> > > > > +               int ret = arch_register_cpu(pr->id);
> > > > > +
> > > > > +               if (ret)
> > > > > +                       return ret;
> > > > > +       }
> > > > > +
> > > > >         /*
> > > > >          *  Extra Processor objects may be enumerated on MP systems with
> > > > >          *  less than the max # of CPUs. They should be ignored _iff
> > > >
> > > > This is interesting, because right below there is the following code:
> > > >
> > > >     if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
> > > >         int ret = acpi_processor_hotadd_init(pr);
> > > >
> > > >         if (ret)
> > > >             return ret;
> > > >     }
> > > >
> > > > and acpi_processor_hotadd_init() essentially calls arch_register_cpu()
> > > > with some extra things around it (more about that below).
> > > >
> > > > I do realize that acpi_processor_hotadd_init() is defined under
> > > > CONFIG_ACPI_HOTPLUG_CPU, so for the sake of the argument let's
> > > > consider an architecture where CONFIG_ACPI_HOTPLUG_CPU is set.
> > > >
> > > > So why are the two conditionals that almost contradict each other both
> > > > needed?  It looks like the new code could be combined with
> > > > acpi_processor_hotadd_init() to do the right thing in all cases.
> > > >
> > > > Now, acpi_processor_hotadd_init() does some extra things that look
> > > > like they should be done by the new code too.
> > > >
> > > > 1. It checks invalid_phys_cpuid() which appears to be a good idea to me.
> > > >
> > > > 2. It uses locking around arch_register_cpu() which doesn't seem
> > > > unreasonable either.
> > > >
> > > > 3. It calls acpi_map_cpu() and I'm not sure why this is not done by
> > > > the new code.
> > > >
> > > > The only thing that can be dropped from it is the _STA check AFAICS,
> > > > because acpi_processor_add() won't even be called if the CPU is not
> > > > present (and not enabled after the first patch).
> > > >
> > > > So why does the code not do 1 - 3 above?
> > >
> > > Honestly, I'm out of my depth with this and can't answer your
> > > questions - and I really don't want to try fiddling with this code
> > > because it's just too icky (even in its current form in mainline)
> > > to be understandable to anyone who hasn't gained a detailed knowledge
> > > of this code.
> > >
> > > It's going to require a lot of analysis - how acpi_map_cpuid() behaves
> > > in all circumstances, what this means for invalid_logical_cpuid() and
> > > invalid_phys_cpuid(), what paths will be taken in each case. This code
> > > is already just too hairy for someone who isn't an experienced ACPI
> > > hacker to be able to follow and I don't see an obvious way to make it
> > > more readable.
> > >
> > > James' additions make it even more complex and less readable.
> >
> > As an illustration of the problems I'm having here, I was just writing
> > a reply to this with a suggestion of transforming this code ultimately
> > to:
> >
> >       if (!get_cpu_device(pr->id)) {
> >               int ret;
> >
> >               if (!invalid_logical_cpuid(pr->id) && cpu_present(pr->id))
> >                       ret = acpi_processor_make_enabled(pr);
> >               else
> >                       ret = acpi_processor_make_present(pr);
> >
> >               if (ret)
> >                       return ret;
> >       }
> >
> > (acpi_processor_make_present() would be acpi_processor_hotadd_init()
> > and acpi_processor_make_enabled() would be arch_register_cpu() at this
> > point.)
> >
> > Then I realised that's a bad idea - because we really need to check
> > that pr->id is valid before calling get_cpu_device() on it, so this
> > won't work. That leaves us with:
> >
> >       int ret;
> >
> >       if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
> >               /* x86 et.al. path */
> >               ret = acpi_processor_make_present(pr);
> >       } else if (!get_cpu_device(pr->id)) {
> >               /* Arm64 path */
> >               ret = acpi_processor_make_enabled(pr);
> >       } else {
> >               ret = 0;
> >       }
> >
> >       if (ret)
> >               return ret;
> >
> > Now, the next transformation would be to move !get_cpu_device(pr->id)
> > into acpi_processor_make_enabled() which would eliminate one of those
> > if() legs.
> >
> > Now, if we want to somehow make the call to arch_regster_cpu() common
> > in these two paths, the next question is what are the _precise_
> > semantics of acpi_map_cpu(), particularly with respect to it
> > modifying pr->id. Is it guaranteed to always give the same result
> > for the same processor described in ACPI? What acpi_map_cpu() anyway,
> > I can find no documentation for it.
> >
> > Then there's the question whether calling acpi_unmap_cpu() should be
> > done on the failure path if arch_register_cpu() fails, which is done
> > for the x86 path but not the Arm64 path. Should it be done for the
> > Arm64 path? I've no idea, but as Arm64 doesn't implement either of
> > these two functions, I guess they could be stubbed out and thus be
> > no-ops - but then we open a hole where if pr->id is invalid, we
> > end up passing that invalid value to arch_register_cpu() which I'm
> > quite sure will explode with a negative CPU number.
> >
> > So, to my mind, what you're effectively asking for is a total rewrite
> > of all the code in and called by acpi_processor_get_info()... and that
> > is not something I am willing to do (because it's too far outside of
> > my knowledge area.)
> >
> > As I said in my reply to patch 1, I think your comments on patch 2
> > make Arm64 vcpu hotplug unachievable in a reasonable time frame, and
> > certainly outside the bounds of what I can do to progress this.
> >
> > So, at this point I'm going to stand down from further participation
> > with this patch set as I believe I've reached the limit of what I can
> > do to progress it.
> >
>
> Thanks for your hard work on this Russell - we have moved forwards.
>
> Short of anyone else stepping up I'll pick this up with
> the help of some my colleagues. As such I'm keen on getting patch
> 1 upstream ASAP so that we can exclude the need for some of the
> other workarounds from earlier versions of this series (the ones
> dropped before now).

Applied (as 6.9 material).

> We will need a little time to get up to speed on the current status
> and discussion points Russell raises above.

Sure.

I'm planning to send comments for some other patches in the series this week.

Thanks!


From tglx at linutronix.de  Tue Feb 20 12:03:43 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 20 Feb 2024 21:03:43 +0100
Subject: [PATCH v13 08/13] irqchip/riscv-imsic: Add device MSI domain
 support for PCI devices
In-Reply-To: <CAK9=C2UgYpVtjFZ4NLzOCP6f3LQ=Fx7kPMywwQyFiNMcKmPyLw@mail.gmail.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-9-apatel@ventanamicro.com> <8734tni7h3.ffs@tglx>
 <CAK9=C2UgYpVtjFZ4NLzOCP6f3LQ=Fx7kPMywwQyFiNMcKmPyLw@mail.gmail.com>
Message-ID: <87jzmyhpi8.ffs@tglx>

On Tue, Feb 20 2024 at 22:51, Anup Patel wrote:

> On Tue, Feb 20, 2024 at 7:05?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>>
>> On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
>> >  static bool imsic_init_dev_msi_info(struct device *dev,
>> >                                   struct irq_domain *domain,
>> >                                   struct irq_domain *real_parent,
>> > @@ -218,6 +241,7 @@ static bool imsic_init_dev_msi_info(struct device *dev,
>> >
>> >       /* MSI parent domain specific settings */
>> >       switch (real_parent->bus_token) {
>> > +     case DOMAIN_BUS_PCI_MSI:
>>
>>         case DOMAIN_BUS_PCI_DEVICE_MSIX:
>>
>> ?
>
> Actually, the DOMAIN_BUS_PCI_MSI is not needed because
> the real parent domain is always the IMSIC base irq_domain
> so DOMAIN_BUS_NEXUS is sufficient.

Indeed. Obviously I can't read.

> Better to just drop DOMAIN_BUS_PCI_MSI from this switch case ?

Yes. I actually would be a bug if that ends up as the real parent
domain.

Thanks,

       tglx


From broonie at kernel.org  Tue Feb 20 12:14:30 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 20:14:30 +0000
Subject: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in userspace
In-Reply-To: <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
Message-ID: <527e2b4d-5d2b-4993-a30a-834e77a23a40@sirena.org.uk>

On Tue, Feb 20, 2024 at 06:41:05PM +0000, Edgecombe, Rick P wrote:
> On Tue, 2024-02-20 at 11:36 -0500, Stefan O'Rear wrote:

> > 2. Shadow stack faults on non-shadow stack pages, if flexible shadow
> > stack
> > ?? handling is in effect, cause the affected page to become a shadow
> > stack
> > ?? page.? When this happens, the page filled with invalid address
> > tokens.

> Hmm, could the shadow stack underflow onto the real stack then? Not
> sure how bad that is. INCSSP (incrementing the SSP register on x86)
> loops are not rare so it seems like something that could happen.

Yes, they'd trash any pages of normal stack they touch as they do so but
otherwise seems similar to overflow.

> The situation (for arm and riscv too I think?) is that some
> applications will just not work automatically due to custom stack
> switching implementations. (user level threading libraries, JITs, etc).
> So?I think it should be ok to ask for apps to change to enable shadow
> stack and we should avoid doing anything too awkward in pursuit of
> getting it to work completely transparently.

Yes, on arm64 anything that rewrites or is otherwise clever with the
stack is going to have to understand that the GCS exists on arm64 and do
matching rewrites/updates for the GCS.  This includes anything that
switches stacks, it will need to use GCS specific instructions to change
the current shadow stack pointer.

> > MAP_SHARED; I consider this sufficiently perverse application
> > behavior that
> > it is not necessary to ensure exclusive use of the underlying pages
> > while
> > a shadow stack pte exists.? (Applications that use MAP_SHARED for
> > stacks
> > do not get the full benefit of the shadow stack but they keep
> > POSIX.1-2004
> > conformance, applications that allocate stacks exclusively in
> > MAP_PRIVATE
> > memory lose no security.)

> On x86 we don't support MAP_SHARED shadow stacks. There is a whole
> snarl around the dirty bit in the PTE. I'm not sure it's impossible but
> it was gladly avoided. There is also a benefit in avoiding having them
> get mapped as writable in a different context.

Similarly for arm64, I think we can physically do it IIRC but between
having to map via map_shadow_stack() for security reasons and it just
generally not seeming like a clever idea the implementation shouldn't
actually let you get a MAP_SHARED GCS it's not something that's been
considered.

> > I am substantially less familiar with GCS and SHSTK than with
> > Zicfiss.
> > It is likely that a syscall or other mechanism is needed to
> > initialize the
> > shadow stack in flexible memory for makecontext.

> The ucontext stacks (and alt shadow stacks is the plan) need to have a
> "restore token". So, yea, you would probably need some syscall to
> "convert" the normal stack memory into shadow stack with a restore
> token.

Similar considerations for GCS, we need tokens and we don't want
userspace to be able to write by itself in the normal case.
-------------- 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/20240220/60b44621/attachment.sig>

From tglx at linutronix.de  Tue Feb 20 12:59:11 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 20 Feb 2024 21:59:11 +0100
Subject: [PATCH RFC v4 02/15] ACPI: processor: Register all CPUs from
 acpi_processor_get_info()
In-Reply-To: <CAJZ5v0iiJpUWq5GMSnKFWQTzn_bdwoQz9m=hDaXNg4Lj_ePF4g@mail.gmail.com>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk>
 <E1rVDmU-0027YP-Jz@rmk-PC.armlinux.org.uk>
 <CAJZ5v0iiJpUWq5GMSnKFWQTzn_bdwoQz9m=hDaXNg4Lj_ePF4g@mail.gmail.com>
Message-ID: <87h6i2hmxs.ffs@tglx>

On Thu, Feb 15 2024 at 20:22, Rafael J. Wysocki wrote:
> On Wed, Jan 31, 2024 at 5:50?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:
>> diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
>> index 47de0f140ba6..13d052bf13f4 100644
>> --- a/drivers/base/cpu.c
>> +++ b/drivers/base/cpu.c
>> @@ -553,7 +553,11 @@ static void __init cpu_dev_register_generic(void)
>>  {
>>         int i, ret;
>>
>> -       if (!IS_ENABLED(CONFIG_GENERIC_CPU_DEVICES))
>> +       /*
>> +        * When ACPI is enabled, CPUs are registered via
>> +        * acpi_processor_get_info().
>> +        */
>> +       if (!IS_ENABLED(CONFIG_GENERIC_CPU_DEVICES) || !acpi_disabled)
>>                 return;
>
> Honestly, this looks like a quick hack to me and it absolutely
> requires an ACK from the x86 maintainers to go anywhere.

That should work, but yes I agree it's all but pretty.


From pvkumar5749404 at gmail.com  Tue Feb 20 13:14:24 2024
From: pvkumar5749404 at gmail.com (Prabhav Kumar Vaish)
Date: Wed, 21 Feb 2024 02:44:24 +0530
Subject: [PATCH] Spelling correction patch
Message-ID: <20240220211424.6005-1-pvkumar5749404@gmail.com>

Signed-off-by: Prabhav Kumar Vaish <pvkumar5749404 at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc | 2 +-
 Documentation/ABI/testing/sysfs-bus-cxl                   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
index 96aafa66b4a5..339cec3b2f1a 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
@@ -97,7 +97,7 @@ Date:		August 2023
 KernelVersion:	6.7
 Contact:	Anshuman Khandual <anshuman.khandual at arm.com>
 Description:	(Read) Shows all supported Coresight TMC-ETR buffer modes available
-		for the users to configure explicitly. This file is avaialble only
+		for the users to configure explicitly. This file is available only
 		for TMC ETR devices.
 
 What:		/sys/bus/coresight/devices/<memory_map>.tmc/buf_mode_preferred
diff --git a/Documentation/ABI/testing/sysfs-bus-cxl b/Documentation/ABI/testing/sysfs-bus-cxl
index fff2581b8033..bbf6de5a4ca1 100644
--- a/Documentation/ABI/testing/sysfs-bus-cxl
+++ b/Documentation/ABI/testing/sysfs-bus-cxl
@@ -224,7 +224,7 @@ Description:
 		decoding a Host Physical Address range. Note that this number
 		may be elevated without any regionX objects active or even
 		enumerated, as this may be due to decoders established by
-		platform firwmare or a previous kernel (kexec).
+		platform firmware or a previous kernel (kexec).
 
 
 What:		/sys/bus/cxl/devices/decoderX.Y
-- 
2.34.1



From konrad.dybcio at linaro.org  Tue Feb 20 13:21:04 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Tue, 20 Feb 2024 22:21:04 +0100
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for
 WCN7850
In-Reply-To: <ea08a286-ff53-4d58-ae41-38cca151508c@sirena.org.uk>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-15-brgl@bgdev.pl>
 <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk>
 <CAMRc=MeUjKPS3ANE6=7WZ3kbbGAdyE8HeXFN=75Jp-pVyBaWrQ@mail.gmail.com>
 <ea08a286-ff53-4d58-ae41-38cca151508c@sirena.org.uk>
Message-ID: <17bbd9ae-0282-430e-947b-e6fb08c53af7@linaro.org>

On 20.02.2024 13:47, Mark Brown wrote:
> On Tue, Feb 20, 2024 at 12:22:42PM +0100, Bartosz Golaszewski wrote:
>> On Mon, Feb 19, 2024 at 6:50?PM Mark Brown <broonie at kernel.org> wrote:
>>> On Fri, Feb 16, 2024 at 09:32:11PM +0100, Bartosz Golaszewski wrote:
> 
>>>> +static struct pci_pwrctl_wcn7850_vreg pci_pwrctl_wcn7850_vregs[] = {
>>>> +     {
>>>> +             .name = "vdd",
>>>> +             .load_uA = 16000,
>>>> +     },
> 
>>> I know a bunch of the QC stuff includes these load numbers but are they
>>> actually doing anything constructive?  It keeps coming up that they're
>>> causing a bunch of work and it's not clear that they have any great
>>> effect on modern systems.
> 
>> Yes, we have what is called a high-power mode and a low-power mode in
>> regulators and these values are used to determine which one to use.
> 
> Are you *sure* this actually happens (and that the regulators don't
> figure it out by themselves), especially given that the consumers are
> just specifying the load once rather than varying it dynamically at
> runtime which is supposed to be the use case for this API?  This API is
> intended to be used dynamically, if the regulator always needs to be in
> a particular mode just configure that statically.

*AFAIU*

The regulators aggregate the requested current (there may be
multiple consumers) and then it's decided if it's high enough
to jump into HPM.

Konrad



From quic_abchauha at quicinc.com  Tue Feb 20 13:22:19 2024
From: quic_abchauha at quicinc.com (Abhishek Chauhan (ABC))
Date: Tue, 20 Feb 2024 13:22:19 -0800
Subject: [PATCH net-next v5] net: stmmac: dwmac-qcom-ethqos: Add support
 for 2.5G SGMII
In-Reply-To: <20240220050735.29507-1-quic_snehshah@quicinc.com>
References: <20240220050735.29507-1-quic_snehshah@quicinc.com>
Message-ID: <e3688f73-2040-4cd2-965a-0ed5482aff2d@quicinc.com>



On 2/19/2024 9:07 PM, Sneh Shah wrote:
> Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000
> mode for 1G/100M/10M speed.
> Added changes to configure serdes phy and mac based on link speed.
> Changing serdes phy speed involves multiple register writes for
> serdes block. To avoid redundant write operations only update serdes
> phy when new speed is different.
> For 2500 speed MAC PCS autoneg needs to disabled. Added changes to
> disable MAC PCS autoneg if ANE parameter is not set.
> 
> Signed-off-by: Sneh Shah <quic_snehshah at quicinc.com>
Tested-by: Abhishek Chauhan <quic_abchauha at quicinc.com> # sa8775p-ride
Reviewed-by: Abhishek Chauhan <quic_abchauha at quicinc.com>
> ---
> v5 changelog:
> - Updated commit message with more details on MAC PCS autoneg disable
> v4 changelog:
> - Made cosmetic changes
> v3 changelog:
> - updated commit message
> ---
> v2 changelog:
> - updated stmmac_pcs_ane to support autoneg disable
> - Update serdes speed to 1000 for 100M and 10M also---
> ---
>  .../stmicro/stmmac/dwmac-qcom-ethqos.c        | 26 +++++++++++++++++++
>  .../net/ethernet/stmicro/stmmac/stmmac_pcs.h  |  2 ++
>  2 files changed, 28 insertions(+)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> index 31631e3f89d0..6bbdbb7bef44 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> @@ -106,6 +106,7 @@ struct qcom_ethqos {
>  	struct clk *link_clk;
>  	struct phy *serdes_phy;
>  	unsigned int speed;
> +	int serdes_speed;
>  	phy_interface_t phy_mode;
>  
>  	const struct ethqos_emac_por *por;
> @@ -606,19 +607,39 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos)
>   */
>  static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
>  {
> +	struct net_device *dev = platform_get_drvdata(ethqos->pdev);
> +	struct stmmac_priv *priv = netdev_priv(dev);
>  	int val;
>  
>  	val = readl(ethqos->mac_base + MAC_CTRL_REG);
>  
>  	switch (ethqos->speed) {
> +	case SPEED_2500:
> +		val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
> +		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
> +			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
> +			      RGMII_IO_MACRO_CONFIG2);
> +		if (ethqos->serdes_speed != SPEED_2500)
> +			phy_set_speed(ethqos->serdes_phy, SPEED_2500);
> +		ethqos->serdes_speed = SPEED_2500;
> +		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 0, 0, 0);
> +		break;
>  	case SPEED_1000:
>  		val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
>  		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
>  			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
>  			      RGMII_IO_MACRO_CONFIG2);
> +		if (ethqos->serdes_speed != SPEED_1000)
> +			phy_set_speed(ethqos->serdes_phy, SPEED_1000);
> +		ethqos->serdes_speed = SPEED_1000;
> +		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
>  		break;
>  	case SPEED_100:
>  		val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE;
> +		if (ethqos->serdes_speed != SPEED_1000)
> +			phy_set_speed(ethqos->serdes_phy, SPEED_1000);
> +		ethqos->serdes_speed = SPEED_1000;
> +		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
>  		break;
>  	case SPEED_10:
>  		val |= ETHQOS_MAC_CTRL_PORT_SEL;
> @@ -627,6 +648,10 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
>  			      FIELD_PREP(RGMII_CONFIG_SGMII_CLK_DVDR,
>  					 SGMII_10M_RX_CLK_DVDR),
>  			      RGMII_IO_MACRO_CONFIG);
> +		if (ethqos->serdes_speed != SPEED_1000)
> +			phy_set_speed(ethqos->serdes_phy, ethqos->speed);
> +		ethqos->serdes_speed = SPEED_1000;
> +		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
>  		break;
>  	}
>  
> @@ -799,6 +824,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
>  				     "Failed to get serdes phy\n");
>  
>  	ethqos->speed = SPEED_1000;
> +	ethqos->serdes_speed = SPEED_1000;
>  	ethqos_update_link_clk(ethqos, SPEED_1000);
>  	ethqos_set_func_clk_en(ethqos);
>  
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
> index aefc121464b5..13a30e6df4c1 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
> @@ -110,6 +110,8 @@ static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane,
>  	/* Enable and restart the Auto-Negotiation */
>  	if (ane)
>  		value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN;
> +	else
> +		value &= ~GMAC_AN_CTRL_ANE;
>  
>  	/* In case of MAC-2-MAC connection, block is configured to operate
>  	 * according to MAC conf register.


From Frank.li at nxp.com  Tue Feb 20 13:24:09 2024
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 20 Feb 2024 16:24:09 -0500
Subject: [PATCH v10 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <ZdTRiB9JdQSvBwKn@lizhi-Precision-Tower-5810>
References: <20240205173335.1120469-1-Frank.Li@nxp.com>
 <ZdNvsdao8jbB/52L@lizhi-Precision-Tower-5810>
 <20240219161208.GE3281@thinkpad>
 <ZdN/OyNpw0Xa7qXG@lizhi-Precision-Tower-5810>
 <ZdR2FRQ9Fe8hhK9I@x1-carbon>
 <ZdR6EUOv6hzLEmUa@lpieralisi>
 <ZdTRiB9JdQSvBwKn@lizhi-Precision-Tower-5810>
Message-ID: <ZdUYeYI4UJ4ApV2X@lizhi-Precision-Tower-5810>

On Tue, Feb 20, 2024 at 11:21:28AM -0500, Frank Li wrote:
> On Tue, Feb 20, 2024 at 11:08:17AM +0100, Lorenzo Pieralisi wrote:
> > On Tue, Feb 20, 2024 at 10:51:17AM +0100, Niklas Cassel wrote:
> > > On Mon, Feb 19, 2024 at 11:18:03AM -0500, Frank Li wrote:
> > > > On Mon, Feb 19, 2024 at 09:42:08PM +0530, Manivannan Sadhasivam wrote:
> > > > > On Mon, Feb 19, 2024 at 10:11:45AM -0500, Frank Li wrote:
> > > > > > On Mon, Feb 05, 2024 at 12:33:21PM -0500, Frank Li wrote:
> > > > > > > first 6 patches use drvdata: flags to simplify some switch-case code.
> > > > > > > Improve maintaince and easy to read code.
> > > > > > > 
> > > > > > 
> > > > > > @Lorenzo Pieralisi:
> > > > > > 
> > > > > > 	Do you have chance to look other patches?
> > > > > > 	Mani's apply EP side change. 
> > > > > 
> > > > > Even though the controller is for the endpoint, it is still a controller
> > > > > driver. So all the patches should go through Lorenzo.
> > > > > 
> > > > > I only merge patches under drivers/pci/endpoint. Hope this clarifies.
> > > > 
> > > > Sorry. It confused everyone. My means was that Mani applied Niklas Cassel's
> > > > patches, which cause my 14th patch build failure.
> > > 
> > > Hello Frank,
> > > 
> > > Patch 14, which adds this:
> > > 
> > > +static const struct pci_epc_features imx95_pcie_epc_features = {
> > > +       .msi_capable = true,
> > > +       .bar_fixed_size[1] = SZ_64K,
> > > +       .align = SZ_4K,
> > > +};
> > > 
> > > 
> > > Should, after rebasing on Mani's pci/endpoint branch, instead look like this:
> > > 
> > > +static const struct pci_epc_features imx95_pcie_epc_features = {
> > > +       .msi_capable = true,
> > > +       .bar[BAR_1] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
> > > +       .align = SZ_4K,
> > > +};
> > > 
> > > 
> > > > 
> > > > I asked if I need update my 14th patch or applied 1-13 only. 
> > > 
> > > I see, you want the maintainers to apply 1-13, and simply drop patch 14
> > > instead of you sending out a rebased series.
> > > 
> > > I assume that the maintainers will be fine with your suggested approach.
> > 
> > If patch 14 has no dependencies on 1-13 yes; if it does we need to
> > coordinate the merge between branches in the PCI tree.
> 
> Keep it easy. I rebase to linux-pci/endpoint and v11 patch sent out.
> https://lore.kernel.org/imx/20240220161924.3871774-1-Frank.Li at nxp.com/T/#t

Bjorn just merge endpoint to next. v11 will work with linux-pci/next.

Frank

> 
> Frank
> 
> > 
> > Lorenzo


From bot at kernelci.org  Tue Feb 20 13:34:12 2024
From: bot at kernelci.org (kernelci.org bot)
Date: Tue, 20 Feb 2024 13:34:12 -0800 (PST)
Subject: arm64/for-kernelci build: 1 build: 0 failed, 1 passed,
 1 warning (v6.8-rc5-63-ge6ac7c55d3ec0)
Message-ID: <65d51ad4.050a0220.1b769.3968@mx.google.com>

arm64/for-kernelci build: 1 build: 0 failed, 1 passed, 1 warning (v6.8-rc5-63-ge6ac7c55d3ec0)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v6.8-rc5-63-ge6ac7c55d3ec0/

Tree: arm64
Branch: for-kernelci
Git Describe: v6.8-rc5-63-ge6ac7c55d3ec0
Git Commit: e6ac7c55d3ec0f83f41bb44a224b82d4fba04be2
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

Warnings Detected:

arm64:
    defconfig (gcc-10): 1 warning


Warnings summary:

    1    security/security.c:811:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
defconfig (arm64, gcc-10) ? PASS, 0 errors, 1 warning, 0 section mismatches

Warnings:
    security/security.c:811:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

---
For more info write to <info at kernelci.org>


From pvkumar5749404 at gmail.com  Tue Feb 20 13:42:12 2024
From: pvkumar5749404 at gmail.com (Prabhav Kumar Vaish)
Date: Wed, 21 Feb 2024 03:12:12 +0530
Subject: [PATCH] Correcting the spelling mistakes in "Documentation/ABI/testing/sysfs-bus-cxl" and "Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc"
Message-ID: <20240220214212.10231-1-pvkumar5749404@gmail.com>

Signed-off-by: Prabhav Kumar Vaish <pvkumar5749404 at gmail.com>

Changes:
	- "avaialble" corrected to "available" in "Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc"
	- "firwmare" corrected to "firmware" in "Documentation/ABI/testing/sysfs-bus-cxl"
Signed-off-by: Prabhav Kumar Vaish <pvkumar5749404 at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc | 2 +-
 Documentation/ABI/testing/sysfs-bus-cxl                   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
index 96aafa66b4a5..339cec3b2f1a 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
@@ -97,7 +97,7 @@ Date:		August 2023
 KernelVersion:	6.7
 Contact:	Anshuman Khandual <anshuman.khandual at arm.com>
 Description:	(Read) Shows all supported Coresight TMC-ETR buffer modes available
-		for the users to configure explicitly. This file is avaialble only
+		for the users to configure explicitly. This file is available only
 		for TMC ETR devices.
 
 What:		/sys/bus/coresight/devices/<memory_map>.tmc/buf_mode_preferred
diff --git a/Documentation/ABI/testing/sysfs-bus-cxl b/Documentation/ABI/testing/sysfs-bus-cxl
index fff2581b8033..bbf6de5a4ca1 100644
--- a/Documentation/ABI/testing/sysfs-bus-cxl
+++ b/Documentation/ABI/testing/sysfs-bus-cxl
@@ -224,7 +224,7 @@ Description:
 		decoding a Host Physical Address range. Note that this number
 		may be elevated without any regionX objects active or even
 		enumerated, as this may be due to decoders established by
-		platform firwmare or a previous kernel (kexec).
+		platform firmware or a previous kernel (kexec).
 
 
 What:		/sys/bus/cxl/devices/decoderX.Y
-- 
2.34.1



From peter.griffin at linaro.org  Tue Feb 20 14:06:11 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 20 Feb 2024 22:06:11 +0000
Subject: [PATCH v6 0/2] Add regmap support to exynos-pmu for protected PMU regs
Message-ID: <20240220220613.797068-1-peter.griffin@linaro.org>

Hi folks,

This is a v6 of the series to add support for protected PMU registers found
on gs101 and derivative SoCs. In v2 and later it was re-worked to be based
on a regmap abstraction that I think leads to a much neater overall
solution.

The advantage of the regmap abstraction is that most leaf drivers that
read/write PMU registers need minimal changes.

Example of Exynos drivers that require PMU register access are:
* watchdog
* usb phy
* mipi phy
* ufs phy

This series has been tested on Pixel 6 Oriole / gs101 (by me), exynos850
(by Sam) and odroid xu3 (exynos 5422) by Alexey. That confirms that both
the regmap mmio parts and regmap SMC parts are working correctly.

The expectation is this series would be merged via Krzysztofs Samsung Exynos
tree.

regards,

Peter

Changes since v5:
 - Update kerneldoc comment property -> propname 

Changes since v4:
 - Use same argument names as in struct regmap_config
 - Remove inline keyword and rely on compiler
 - Update kerneldoc wording
 - property -> propname argument rename
 - reverse Xmas tree
 - Only call of_node_put() when of_parse_phandle() is called
 - Collect tags

Changes since v3:
 - Fix PMUALIVE_MASK
 - Add TENSOR_ prefix
 - clear SET_BITS bits on each loop iteration
 - change set_bit to set_bits func name
 - Fix some alignment
 - Add missing return on dev_err_probe
 - Reduce indentation in loop

Changes since v2
 - Add select REGMAP to Kconfig
 - Add constant for SET/CLEAR bits
 - Replace kerneldoc with one line comment
 - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
 - remove superfluous extern keyword
 - dev_err_probe() on probe error
 - shorten regmcfg name
 - no compatibles inside probe, use match data
 - don't mix declarations with/without initializations
 - tensor_sec_reg_read() use mmio to avoid access restrictions
 - Collect up Reviewed-by
 - const for regmap_config structs

Changes since v1:
 - Refactor to use custom regmap to abstract SMC register access (Sam / Guenter)
 - Add deferred probing support (Saravana / Krzysztof)

v5 lore: https://lore.kernel.org/all/20240219204238.356942-1-peter.griffin at linaro.org/
v4 lore: https://lore.kernel.org/all/20240208161700.268570-1-peter.griffin at linaro.org/
v3 lore: https://lore.kernel.org/all/20240202145731.4082033-1-peter.griffin at linaro.org/
v2 lore: https://lore.kernel.org/lkml/20240129211912.3068411-1-peter.griffin at linaro.org/
v1 lore: https://lore.kernel.org/all/20240122225710.1952066-1-peter.griffin at linaro.org/

Peter Griffin (2):
  soc: samsung: exynos-pmu: Add regmap support for SoCs that protect PMU
    regs
  watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU
    regs

 drivers/soc/samsung/Kconfig            |   1 +
 drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
 drivers/soc/samsung/exynos-pmu.h       |   1 +
 drivers/watchdog/Kconfig               |   1 -
 drivers/watchdog/s3c2410_wdt.c         |   8 +-
 include/linux/soc/samsung/exynos-pmu.h |  11 +-
 6 files changed, 249 insertions(+), 8 deletions(-)

-- 
2.44.0.rc0.258.g7320e95886-goog



From peter.griffin at linaro.org  Tue Feb 20 14:06:12 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 20 Feb 2024 22:06:12 +0000
Subject: [PATCH v6 1/2] soc: samsung: exynos-pmu: Add regmap support for SoCs that protect PMU regs
In-Reply-To: <20240220220613.797068-1-peter.griffin@linaro.org>
References: <20240220220613.797068-1-peter.griffin@linaro.org>
Message-ID: <20240220220613.797068-2-peter.griffin@linaro.org>

Some Exynos based SoCs like Tensor gs101 protect the PMU registers for
security hardening reasons so that they are only write accessible in el3
via an SMC call.

As most Exynos drivers that need to write PMU registers currently obtain a
regmap via syscon (phys, pinctrl, watchdog). Support for the above usecase
is implemented in this driver using a custom regmap similar to syscon to
handle the SMC call. Platforms that don't secure PMU registers, get a mmio
regmap like before. As regmaps abstract out the underlying register access
changes to the leaf drivers are minimal.

A new API exynos_get_pmu_regmap_by_phandle() is provided for leaf drivers
that currently use syscon_regmap_lookup_by_phandle(). This also handles
deferred probing.

Tested-by: Sam Protsenko <semen.protsenko at linaro.org>
Tested-by: Alexey Klimov <alexey.klimov at linaro.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
Changes since v5:
 - Update kerneldoc comment property -> propname

Changes since v4:
 - Use same argument names as in struct regmap_config
 - Remove inline keyword and rely on compiler
 - Update kerneldoc wording
 - property -> propname argument rename
 - reverse Xmas tree
 - Only call of_node_put() when of_parse_phandle is called
 - Collect tags

Changes since v3:
 - Fix PMUALIVE_MASK
 - Add TENSOR_ prefix
 - clear SET_BITS bits on each loop iteration
 - change set_bit to set_bits in func name
 - Fix some alignment
 - Add missing return on dev_err_probe
 - Reduce indentation in loop

Changes since v2
 - Add select REGMAP to Kconfig
 - Add constant for SET/CLEAR bits
 - Replace kerneldoc with one line comment
 - Fix kerneldoc for EXPORT_SYMBOL_GPL funcs
 - remove superfluous extern keyword
 - dev_err_probe() on probe error
 - shorten regmcfg name
 - no compatibles inside probe, use match data
 - don't mix declarations with/without initializations
 - tensor_sec_reg_read() use mmio to avoid access restrictions
 - Collect up Reviewed-by
 - const for regmap_config structs
---
 drivers/soc/samsung/Kconfig            |   1 +
 drivers/soc/samsung/exynos-pmu.c       | 235 ++++++++++++++++++++++++-
 drivers/soc/samsung/exynos-pmu.h       |   1 +
 include/linux/soc/samsung/exynos-pmu.h |  11 +-
 4 files changed, 245 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 27ec99af77e3..1a5dfdc978dc 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -42,6 +42,7 @@ config EXYNOS_PMU
 	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
 	select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS
 	select MFD_CORE
+	select REGMAP_MMIO
 
 # There is no need to enable these drivers for ARMv8
 config EXYNOS_PMU_ARM_DRIVERS
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index 250537d7cfd6..fd8b6ac06656 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -5,6 +5,7 @@
 //
 // Exynos - CPU PMU(Power Management Unit) support
 
+#include <linux/arm-smccc.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/mfd/core.h>
@@ -12,19 +13,134 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/regmap.h>
 
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/soc/samsung/exynos-pmu.h>
 
 #include "exynos-pmu.h"
 
+#define PMUALIVE_MASK			GENMASK(13, 0)
+#define TENSOR_SET_BITS			(BIT(15) | BIT(14))
+#define TENSOR_CLR_BITS			BIT(15)
+#define TENSOR_SMC_PMU_SEC_REG		0x82000504
+#define TENSOR_PMUREG_READ		0
+#define TENSOR_PMUREG_WRITE		1
+#define TENSOR_PMUREG_RMW		2
+
 struct exynos_pmu_context {
 	struct device *dev;
 	const struct exynos_pmu_data *pmu_data;
+	struct regmap *pmureg;
 };
 
 void __iomem *pmu_base_addr;
 static struct exynos_pmu_context *pmu_context;
+/* forward declaration */
+static struct platform_driver exynos_pmu_driver;
+
+/*
+ * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
+ * from EL3, but are still read accessible. As Linux needs to write some of
+ * these registers, the following functions are provided and exposed via
+ * regmap.
+ *
+ * Note: This SMC interface is known to be implemented on gs101 and derivative
+ * SoCs.
+ */
+
+/* Write to a protected PMU register. */
+static int tensor_sec_reg_write(void *context, unsigned int reg,
+				unsigned int val)
+{
+	struct arm_smccc_res res;
+	unsigned long pmu_base = (unsigned long)context;
+
+	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
+		      TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res);
+
+	/* returns -EINVAL if access isn't allowed or 0 */
+	if (res.a0)
+		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
+
+	return (int)res.a0;
+}
+
+/* Read/Modify/Write a protected PMU register. */
+static int tensor_sec_reg_rmw(void *context, unsigned int reg,
+			      unsigned int mask, unsigned int val)
+{
+	struct arm_smccc_res res;
+	unsigned long pmu_base = (unsigned long)context;
+
+	arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg,
+		      TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res);
+
+	/* returns -EINVAL if access isn't allowed or 0 */
+	if (res.a0)
+		pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0);
+
+	return (int)res.a0;
+}
+
+/*
+ * Read a protected PMU register. All PMU registers can be read by Linux.
+ * Note: The SMC read register is not used, as only registers that can be
+ * written are readable via SMC.
+ */
+static int tensor_sec_reg_read(void *context, unsigned int reg,
+			       unsigned int *val)
+{
+	*val = pmu_raw_readl(reg);
+	return 0;
+}
+
+/*
+ * For SoCs that have set/clear bit hardware this function can be used when
+ * the PMU register will be accessed by multiple masters.
+ *
+ * For example, to set bits 13:8 in PMU reg offset 0x3e80
+ * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00);
+ *
+ * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80
+ * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00);
+ */
+static int tensor_set_bits_atomic(void *ctx, unsigned int offset, u32 val,
+				  u32 mask)
+{
+	int ret;
+	unsigned int i;
+
+	for (i = 0; i < 32; i++) {
+		if (!(mask & BIT(i)))
+			continue;
+
+		offset &= ~TENSOR_SET_BITS;
+
+		if (val & BIT(i))
+			offset |= TENSOR_SET_BITS;
+		else
+			offset |= TENSOR_CLR_BITS;
+
+		ret = tensor_sec_reg_write(ctx, offset, i);
+		if (ret)
+			return ret;
+	}
+	return ret;
+}
+
+static int tensor_sec_update_bits(void *ctx, unsigned int reg,
+				  unsigned int mask, unsigned int val)
+{
+	/*
+	 * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
+	 * as the target registers can be accessed by multiple masters.
+	 */
+	if (reg > PMUALIVE_MASK)
+		return tensor_sec_reg_rmw(ctx, reg, mask, val);
+
+	return tensor_set_bits_atomic(ctx, reg, val, mask);
+}
 
 void pmu_raw_writel(u32 val, u32 offset)
 {
@@ -75,11 +191,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
 #define exynos_pmu_data_arm_ptr(data)	NULL
 #endif
 
+static const struct regmap_config regmap_smccfg = {
+	.name = "pmu_regs",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.use_single_read = true,
+	.use_single_write = true,
+	.reg_read = tensor_sec_reg_read,
+	.reg_write = tensor_sec_reg_write,
+	.reg_update_bits = tensor_sec_update_bits,
+};
+
+static const struct regmap_config regmap_mmiocfg = {
+	.name = "pmu_regs",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.use_single_read = true,
+	.use_single_write = true,
+};
+
+static const struct exynos_pmu_data gs101_pmu_data = {
+	.pmu_secure = true
+};
+
 /*
  * PMU platform driver and devicetree bindings.
  */
 static const struct of_device_id exynos_pmu_of_device_ids[] = {
 	{
+		.compatible = "google,gs101-pmu",
+		.data = &gs101_pmu_data,
+	}, {
 		.compatible = "samsung,exynos3250-pmu",
 		.data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data),
 	}, {
@@ -113,19 +259,75 @@ static const struct mfd_cell exynos_pmu_devs[] = {
 	{ .name = "exynos-clkout", },
 };
 
+/**
+ * exynos_get_pmu_regmap() - Obtain pmureg regmap
+ *
+ * Find the pmureg regmap previously configured in probe() and return regmap
+ * pointer.
+ *
+ * Return: A pointer to regmap if found or ERR_PTR error value.
+ */
 struct regmap *exynos_get_pmu_regmap(void)
 {
 	struct device_node *np = of_find_matching_node(NULL,
 						      exynos_pmu_of_device_ids);
 	if (np)
-		return syscon_node_to_regmap(np);
+		return exynos_get_pmu_regmap_by_phandle(np, NULL);
 	return ERR_PTR(-ENODEV);
 }
 EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
 
+/**
+ * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
+ * @np: Device node holding PMU phandle property
+ * @propname: Name of property holding phandle value
+ *
+ * Find the pmureg regmap previously configured in probe() and return regmap
+ * pointer.
+ *
+ * Return: A pointer to regmap if found or ERR_PTR error value.
+ */
+struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+						const char *propname)
+{
+	struct exynos_pmu_context *ctx;
+	struct device_node *pmu_np;
+	struct device *dev;
+
+	if (propname)
+		pmu_np = of_parse_phandle(np, propname, 0);
+	else
+		pmu_np = np;
+
+	if (!pmu_np)
+		return ERR_PTR(-ENODEV);
+
+	/*
+	 * Determine if exynos-pmu device has probed and therefore regmap
+	 * has been created and can be returned to the caller. Otherwise we
+	 * return -EPROBE_DEFER.
+	 */
+	dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
+					    (void *)pmu_np);
+
+	if (propname)
+		of_node_put(pmu_np);
+
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	ctx = dev_get_drvdata(dev);
+
+	return ctx->pmureg;
+}
+EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
+
 static int exynos_pmu_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct regmap_config pmu_regmcfg;
+	struct regmap *regmap;
+	struct resource *res;
 	int ret;
 
 	pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
@@ -137,9 +339,38 @@ static int exynos_pmu_probe(struct platform_device *pdev)
 			GFP_KERNEL);
 	if (!pmu_context)
 		return -ENOMEM;
-	pmu_context->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
 	pmu_context->pmu_data = of_device_get_match_data(dev);
 
+	/* For SoCs that secure PMU register writes use custom regmap */
+	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_secure) {
+		pmu_regmcfg = regmap_smccfg;
+		pmu_regmcfg.max_register = resource_size(res) -
+					   pmu_regmcfg.reg_stride;
+		/* Need physical address for SMC call */
+		regmap = devm_regmap_init(dev, NULL,
+					  (void *)(uintptr_t)res->start,
+					  &pmu_regmcfg);
+	} else {
+		/* All other SoCs use a MMIO regmap */
+		pmu_regmcfg = regmap_mmiocfg;
+		pmu_regmcfg.max_register = resource_size(res) -
+					   pmu_regmcfg.reg_stride;
+		regmap = devm_regmap_init_mmio(dev, pmu_base_addr,
+					       &pmu_regmcfg);
+	}
+
+	if (IS_ERR(regmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(regmap),
+				     "regmap init failed\n");
+
+	pmu_context->pmureg = regmap;
+	pmu_context->dev = dev;
+
 	if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init)
 		pmu_context->pmu_data->pmu_init();
 
diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
index 1c652ffd79b4..0a49a2c9a08e 100644
--- a/drivers/soc/samsung/exynos-pmu.h
+++ b/drivers/soc/samsung/exynos-pmu.h
@@ -21,6 +21,7 @@ struct exynos_pmu_conf {
 struct exynos_pmu_data {
 	const struct exynos_pmu_conf *pmu_config;
 	const struct exynos_pmu_conf *pmu_config_extra;
+	bool pmu_secure;
 
 	void (*pmu_init)(void);
 	void (*powerdown_conf)(enum sys_powerdown);
diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
index a4f5516cc956..2bd9d12d9a52 100644
--- a/include/linux/soc/samsung/exynos-pmu.h
+++ b/include/linux/soc/samsung/exynos-pmu.h
@@ -10,6 +10,7 @@
 #define __LINUX_SOC_EXYNOS_PMU_H
 
 struct regmap;
+struct device_node;
 
 enum sys_powerdown {
 	SYS_AFTR,
@@ -20,12 +21,20 @@ enum sys_powerdown {
 
 extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
 #ifdef CONFIG_EXYNOS_PMU
-extern struct regmap *exynos_get_pmu_regmap(void);
+struct regmap *exynos_get_pmu_regmap(void);
+struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+						const char *propname);
 #else
 static inline struct regmap *exynos_get_pmu_regmap(void)
 {
 	return ERR_PTR(-ENODEV);
 }
+
+static inline struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
+							      const char *propname)
+{
+	return ERR_PTR(-ENODEV);
+}
 #endif
 
 #endif /* __LINUX_SOC_EXYNOS_PMU_H */
-- 
2.44.0.rc0.258.g7320e95886-goog



From peter.griffin at linaro.org  Tue Feb 20 14:06:13 2024
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 20 Feb 2024 22:06:13 +0000
Subject: [PATCH v6 2/2] watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs
In-Reply-To: <20240220220613.797068-1-peter.griffin@linaro.org>
References: <20240220220613.797068-1-peter.griffin@linaro.org>
Message-ID: <20240220220613.797068-3-peter.griffin@linaro.org>

Obtain the PMU regmap using the new API added to exynos-pmu driver rather
than syscon_regmap_lookup_by_phandle(). As this driver no longer depends
on mfd syscon remove that header and Kconfig dependency.

Tested-by: Alexey Klimov <alexey.klimov at linaro.org>
Tested-by: Sam Protsenko <semen.protsenko at linaro.org>
Acked-by: Guenter Roeck <linux at roeck-us.net>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 drivers/watchdog/Kconfig       | 1 -
 drivers/watchdog/s3c2410_wdt.c | 8 ++++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7d22051b15a2..d78fe7137799 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -512,7 +512,6 @@ config S3C2410_WATCHDOG
 	tristate "S3C6410/S5Pv210/Exynos Watchdog"
 	depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
 	select WATCHDOG_CORE
-	select MFD_SYSCON if ARCH_EXYNOS
 	help
 	  Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos
 	  SoCs. This will reboot the system when the timer expires with
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 349d30462c8c..686cf544d0ae 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -24,9 +24,9 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/of.h>
-#include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/delay.h>
+#include <linux/soc/samsung/exynos-pmu.h>
 
 #define S3C2410_WTCON		0x00
 #define S3C2410_WTDAT		0x04
@@ -699,11 +699,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
 		return ret;
 
 	if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
-		wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
-						"samsung,syscon-phandle");
+		wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node,
+						 "samsung,syscon-phandle");
 		if (IS_ERR(wdt->pmureg))
 			return dev_err_probe(dev, PTR_ERR(wdt->pmureg),
-					     "syscon regmap lookup failed.\n");
+					     "PMU regmap lookup failed.\n");
 	}
 
 	wdt_irq = platform_get_irq(pdev, 0);
-- 
2.44.0.rc0.258.g7320e95886-goog



From memxor at gmail.com  Tue Feb 20 14:12:23 2024
From: memxor at gmail.com (Kumar Kartikeya Dwivedi)
Date: Tue, 20 Feb 2024 23:12:23 +0100
Subject: [PATCH bpf-next v3 0/2] bpf, arm64: Support Exceptions
In-Reply-To: <20240201125225.72796-1-puranjay12@gmail.com>
References: <20240201125225.72796-1-puranjay12@gmail.com>
Message-ID: <CAP01T77ttCeO_joYWqYxjyj_AdHEX34rk31H5y6voNJQz_dXFQ@mail.gmail.com>

On Thu, 1 Feb 2024 at 13:52, Puranjay Mohan <puranjay12 at gmail.com> wrote:
>
> Changes in V2->V3:
> V2: https://lore.kernel.org/all/20230917000045.56377-1-puranjay12 at gmail.com/
> - Use unwinder from stacktrace.c rather than open coding the unwind logic.
> - Fix a bug in the prologue related to BPF_FP (Xu Kuohai)
>
> Changes in V1->V2:
> V1: https://lore.kernel.org/all/20230912233942.6734-1-puranjay12 at gmail.com/
> - Remove exceptions from DENYLIST.aarch64 as they are supported now.
>
> The base support for exceptions was merged with [1] and it was enabled for
> x86-64.
>
> This patch set enables the support on ARM64, all sefltests are passing:
>
> # ./test_progs -a exceptions
> #74/1    exceptions/exception_throw_always_1:OK
> [...]

I think this looks ok, would be nice if it received acks from arm64 experts.

If you have cycles to spare, please also look into
https://lore.kernel.org/bpf/20240201042109.1150490-1-memxor at gmail.com
and let me know how architecture independent the cleanup code right
now in the x86 JIT should be made so that we can do the
same for arm64 as well later. That would be required to complete the
support for cleanups.

I guess we just need bpf_frame_spilled_caller_reg_off to be arch
specific and lift the rest out into the BPF core.
I will make that change in v2 in any case.

Just a note but based on our off-list discussion for supporting this
stuff on riscv as well (where a lot of registers would have to be
saved on entry),
the hidden subprog trampoline could be a way to avoid that. They can
be pushed by this subprog before entry into bpf_throw, and since the
BPF program does not touch the extra callee-saved registers, they
should be what the kernel had originally upon entry into the BPF
program itself. The same could be done on arm64 and x86, but the
returns would be diminishing. It would be nice to quantify how much
this saves in terms of costs of pushing extra registers, before doing
this.


From sfr at canb.auug.org.au  Tue Feb 20 14:28:26 2024
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Wed, 21 Feb 2024 09:28:26 +1100
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
Message-ID: <20240221092826.748e70c4@canb.auug.org.au>

Hi all,

After merging the arm-soc-fixes tree, today's linux-next build (arm
multi_v7_defconfig) produced this warning:

arch/arm/boot/dts/renesas/r8a7790-lager.dts:444.11-458.5: Warning (interrupt_provider): /i2c-mux4/pmic at 58: Missing '#interrupt-cells' in interrupt provider
arch/arm/boot/dts/renesas/r8a7790-lager.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/arm/boot/dts/renesas/r8a7792-blanche.dts:376.10-392.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
arch/arm/boot/dts/renesas/r8a7792-blanche.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/arm/boot/dts/renesas/r8a7790-stout.dts:344.10-362.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
arch/arm/boot/dts/renesas/r8a7790-stout.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/arm/boot/dts/renesas/r8a7791-koelsch.dts:816.10-830.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
arch/arm/boot/dts/renesas/r8a7791-koelsch.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/arm/boot/dts/renesas/r8a7791-porter.dts:410.10-420.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 5a: Missing '#interrupt-cells' in interrupt provider
arch/arm/boot/dts/renesas/r8a7791-porter.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/arm/boot/dts/renesas/r8a7794-alt.dts:450.10-464.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
arch/arm/boot/dts/renesas/r8a7794-alt.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/arm/boot/dts/renesas/r8a7794-silk.dts:436.10-454.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
arch/arm/boot/dts/renesas/r8a7794-silk.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/arm/boot/dts/renesas/r8a7793-gose.dts:756.10-770.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'

Introduced/exposed by commit

  78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")

I guess you missed some :-(

-- 
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/20240221/a95306bf/attachment.sig>

From andrew at codeconstruct.com.au  Tue Feb 20 14:36:29 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Wed, 21 Feb 2024 09:06:29 +1030
Subject: [PATCH] ipmi: kcs: Update OBF poll timeout to reduce latency
In-Reply-To: <ZdT+eThnYqb3iawF@mail.minyard.net>
References: <20240220123615.963916-1-geissonator@gmail.com>
	 <a9169894-6972-49c0-a1d4-d80863f5b511@molgen.mpg.de>
	 <ZdT+eThnYqb3iawF@mail.minyard.net>
Message-ID: <9680ad7d7a48fc36a0572dc2286a1229a29341fe.camel@codeconstruct.com.au>

On Tue, 2024-02-20 at 13:33 -0600, Corey Minyard wrote:
> On Tue, Feb 20, 2024 at 04:51:21PM +0100, Paul Menzel wrote:
> > Dear Andrew,
> > 
> > 
> > Thank you for your patch. Some style suggestions.
> > 
> > Am 20.02.24 um 13:36 schrieb Andrew Geissler:
> > > From: Andrew Geissler <geissonator at yahoo.com>
> > 
> > (Oh no, Yahoo. (ignore))
> > 
> > You could be more specific in the git commit message by using *Double*:
> > 
> > > ipmi: kcs: Double OBF poll timeout to reduce latency
> > 
> > > ipmi: kcs: Double OBF poll timeout to 200 us to reduce latency
> > 
> > > Commit f90bc0f97f2b ("ipmi: kcs: Poll OBF briefly to reduce OBE
> > > latency") introduced an optimization to poll when the host has
> 
> I assume that removing that patch doesn't fix the issue, it would only
> make it worse, right?

Yep.

> 
> > > read the output data register (ODR). Testing has shown that the 100us
> > > timeout was not always enough. When we miss that 100us window, it
> > > results in 10x the time to get the next message from the BMC to the
> > > host. When you're sending 100's of messages between the BMC and Host,
> > 
> > I do not understand, how this poll timeout can result in such an increase,
> > and why a quite big timeout hurts, but I do not know the implementation.
> 
> It's because increasing that number causes it to poll longer for the
> event, the host takes longer than 100us to generate the event, and if
> the event is missed the time when it is checked again is very long.
> 
> Polling for 100us is already pretty extreme. 200us is really too long.
> 
> The real problem is that there is no interrupt for this.  I'd also guess
> there is no interrupt on the host side, because that would solve this
> problem, too, as it would certainly get around to handling the interupt
> in 100us.  I'm assuming the host driver is not the Linux driver, as it
> should also handle this in a timely manner, even when polling.

I expect the issues Andrew G is observing are with the Power10 boot
firmware. The boot firmware only polls. The runtime firmware enables
interrupts.

> 
> If people want hardware to perform well, they ought to design it and not
> expect software to fix all the problems.

+1

> 
> The right way to fix this is probably to do the same thing the host side
> Linux driver does.  It has a kernel thread that is kicked off to do
> this.  Unfortunately, that's more complicated to implement, but it
> avoids polling in this location (which causes latency issues on the BMC
> side) and lets you poll longer without causing issues.

In Andrew G's case he's talking MCTP over KCS using a vendor-defined
transport binding (that also leverages LPC FWH cycles for bulk data
transfers)[1]. I think it could have taken more inspiration from the
IPMI KCS protocol: It might be worth an experiment to write the dummy
command value to IDR from the host side after each ODR read to signal
the host's clearing of OBF (no interrupt for the BMC) with an IBF
(which does interrupt the BMC). And doing the obverse for the BMC. Some
brief thought suggests that if the dummy value is read there's no need
to send a dummy value in reply (as it's an indicator to read the status
register). With that the need for the spin here (or on the host side)
is reduced at the cost of some constant protocol overhead.

[1]: https://github.com/openbmc/libmctp/blob/master/docs/bindings/vendor-ibm-astlpc.md


Andrew J


From vladimir.oltean at nxp.com  Tue Feb 20 14:37:06 2024
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Wed, 21 Feb 2024 00:37:06 +0200
Subject: [PATCH] arm64: ls1046ardb: Replace XGMII with 10GBASE-R phy mode
In-Reply-To: <191b4477-7b4b-47eb-bb3e-0e4d08b3b32e@seco.com>
References: <20240220145037.kf3avnykjif24kkr@skbuf>
 <191b4477-7b4b-47eb-bb3e-0e4d08b3b32e@seco.com>
Message-ID: <20240220223706.o7wc5r57omkmgtgh@skbuf>

On Tue, Feb 20, 2024 at 02:12:52PM -0500, Sean Anderson wrote:
> On 2/20/24 09:50, Vladimir Oltean wrote:
> > Notice that unlike fm1-mac10 (node "ethernet at f2000"), there is no
> > pcs-handle-names property (fm1-mac10 has it defined in fsl-ls1046-post.dtsi,
> > whereas fm1-mac9 doesn't. Don't ask me why, I don't know....)
> 
> I think this is just because this ethernet is always XFI and never (Q)SGMII.

Is that so? With SerDes protocol 0x3333, won't the PCS that's connected
to fm1-mac9 use SGMII/1000BASE-X (thus not 10GBASE-R)?

And as for QSGMII, what's the relevance of that? You can't have one
device tree good for all SerDes protocols and RCW pinmuxing options.
Either there are 4 MACs aggregated onto a single lane, or there is one
MAC per lane, but I've never encountered any use case for alternating
between these 2 configurations at runtime, or with same device tree for
that matter, have you? QSGMII seems to have been the original motivation
for listing all possible PCSes of a MAC in pcs-handle-names, but again, why?

> Can you please submit this patch? I noticed this but never had the chance to go
> back and debug it.

https://lore.kernel.org/netdev/20240220223442.1275946-1-vladimir.oltean at nxp.com/


From sean.anderson at seco.com  Tue Feb 20 14:52:36 2024
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 20 Feb 2024 17:52:36 -0500
Subject: [PATCH] arm64: ls1046ardb: Replace XGMII with 10GBASE-R phy mode
In-Reply-To: <20240220223706.o7wc5r57omkmgtgh@skbuf>
References: <20240220145037.kf3avnykjif24kkr@skbuf>
 <191b4477-7b4b-47eb-bb3e-0e4d08b3b32e@seco.com>
 <20240220223706.o7wc5r57omkmgtgh@skbuf>
Message-ID: <e39c811e-ad9d-4e90-8710-629b822944e0@seco.com>

On 2/20/24 17:37, Vladimir Oltean wrote:
> On Tue, Feb 20, 2024 at 02:12:52PM -0500, Sean Anderson wrote:
>> On 2/20/24 09:50, Vladimir Oltean wrote:
>> > Notice that unlike fm1-mac10 (node "ethernet at f2000"), there is no
>> > pcs-handle-names property (fm1-mac10 has it defined in fsl-ls1046-post.dtsi,
>> > whereas fm1-mac9 doesn't. Don't ask me why, I don't know....)
>>
>> I think this is just because this ethernet is always XFI and never (Q)SGMII.
>
> Is that so? With SerDes protocol 0x3333, won't the PCS that's connected
> to fm1-mac9 use SGMII/1000BASE-X (thus not 10GBASE-R)?

Yeah, so I guess it just can't be QSGMII.

> And as for QSGMII, what's the relevance of that? You can't have one
> device tree good for all SerDes protocols and RCW pinmuxing options.

The goal is for the "generic" includes to be generic. So the board-specific
stuff lives in the board-specific device tree source. And the only thing
board-specific is the phy interface, since the drivers can figure out
the rest.

> Either there are 4 MACs aggregated onto a single lane, or there is one
> MAC per lane, but I've never encountered any use case for alternating
> between these 2 configurations at runtime, or with same device tree for
> that matter, have you? QSGMII seems to have been the original motivation
> for listing all possible PCSes of a MAC in pcs-handle-names, but again, why?

With SGMII and XFI, the PCS sits on the MAC's MDIO bus. So for SGMII and
XFI if we don't have any labels we can just assume the PCS handle is for
the right PCS. But for QSGMII the PCSs sit on another MAC's MDIO bus. So
we need to tell the MAC where to find the PCS. This means we need to
supply multiple PCSs to the MAC, and thus we need names to differentiate
them. Since MAC9 doesn't have QSGMII, I suppose I never bothered to add
names.

--Sean

[Embedded World 2024, SECO SpA]<https://www.messe-ticket.de/Nuernberg/embeddedworld2024/Register/ew24517689>


From dmitry.baryshkov at linaro.org  Tue Feb 20 14:57:35 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 21 Feb 2024 00:57:35 +0200
Subject: [PATCH RESEND 0/2] ARM: implement cacheinfo support (for v7/v7m)
Message-ID: <20240221-armv7-cacheinfo-v1-0-69dbd7f20d04@linaro.org>

Follow the ARM64 platform and implement simple cache information driver.
As it reads data from CTR (ARMv6+) and CLIDR (ARMv7+) registers, it is
limited to the ARMv7 / ARMv7M, providing simple fallback or just
returning -EOPNOTSUPP in case of older platforms.

In theory we should be able to skip CLIDR reading and assume that Dcache
and Icache (or unified L1 cache) always exist if CTR is supported and
returns sensible value. However I think this better be handled by the
maintainers of corresponding platforms.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
Dmitry Baryshkov (2):
      ARM: add CLIDR accessor functions
      ARM: implement cacheinfo support

 arch/arm/Kconfig                 |   1 +
 arch/arm/include/asm/cache.h     |   6 ++
 arch/arm/include/asm/cachetype.h |  13 ++++
 arch/arm/kernel/Makefile         |   1 +
 arch/arm/kernel/cacheinfo.c      | 164 +++++++++++++++++++++++++++++++++++++++
 include/linux/cacheinfo.h        |   2 +-
 6 files changed, 186 insertions(+), 1 deletion(-)
---
base-commit: 39676dfe52331dba909c617f213fdb21015c8d10
change-id: 20231231-armv7-cacheinfo-9fa533ae371e

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov at linaro.org>



From dmitry.baryshkov at linaro.org  Tue Feb 20 14:57:36 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 21 Feb 2024 00:57:36 +0200
Subject: [PATCH RESEND 1/2] ARM: add CLIDR accessor functions
In-Reply-To: <20240221-armv7-cacheinfo-v1-0-69dbd7f20d04@linaro.org>
References: <20240221-armv7-cacheinfo-v1-0-69dbd7f20d04@linaro.org>
Message-ID: <20240221-armv7-cacheinfo-v1-1-69dbd7f20d04@linaro.org>

Add functions to read the CLIDR, Cache Level ID Register.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 arch/arm/include/asm/cachetype.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/include/asm/cachetype.h b/arch/arm/include/asm/cachetype.h
index e8c30430be33..90203a6d7270 100644
--- a/arch/arm/include/asm/cachetype.h
+++ b/arch/arm/include/asm/cachetype.h
@@ -81,6 +81,14 @@ static inline unsigned int read_ccsidr(void)
 	asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r" (val));
 	return val;
 }
+
+static inline unsigned int read_clidr(void)
+{
+	unsigned int val;
+
+	asm volatile("mrc p15, 1, %0, c0, c0, 1" : "=r" (val));
+	return val;
+}
 #else /* CONFIG_CPU_V7M */
 #include <linux/io.h>
 #include "asm/v7m.h"
@@ -94,6 +102,11 @@ static inline unsigned int read_ccsidr(void)
 {
 	return readl(BASEADDR_V7M_SCB + V7M_SCB_CCSIDR);
 }
+
+static inline unsigned int read_clidr(void)
+{
+	return readl(BASEADDR_V7M_SCB + V7M_SCB_CLIDR);
+}
 #endif
 
 #endif

-- 
2.39.2



From dmitry.baryshkov at linaro.org  Tue Feb 20 14:57:37 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 21 Feb 2024 00:57:37 +0200
Subject: [PATCH RESEND 2/2] ARM: implement cacheinfo support
In-Reply-To: <20240221-armv7-cacheinfo-v1-0-69dbd7f20d04@linaro.org>
References: <20240221-armv7-cacheinfo-v1-0-69dbd7f20d04@linaro.org>
Message-ID: <20240221-armv7-cacheinfo-v1-2-69dbd7f20d04@linaro.org>

On ARMv7 / v7m machines read CTR and CLIDR registers to provide
information regarding the cache topology. Earlier machines should
describe full cache topology in the device tree.

Note, this follows the ARM64 cacheinfo support and provides only minimal
support required to bootstrap cache info. All useful properties should
be decribed in Device Tree.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
 arch/arm/Kconfig             |   1 +
 arch/arm/include/asm/cache.h |   6 ++
 arch/arm/kernel/Makefile     |   1 +
 arch/arm/kernel/cacheinfo.c  | 164 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/cacheinfo.h    |   2 +-
 5 files changed, 173 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8f47d6762ea4..cb293ddae6bb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -5,6 +5,7 @@ config ARM
 	select ARCH_32BIT_OFF_T
 	select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND
 	select ARCH_HAS_BINFMT_FLAT
+	select ARCH_HAS_CACHE_LINE_SIZE if OF
 	select ARCH_HAS_CPU_FINALIZE_INIT if MMU
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL if MMU
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index e3ea34558ada..ecbc100d22a5 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -26,4 +26,10 @@
 
 #define __read_mostly __section(".data..read_mostly")
 
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_ARCH_HAS_CACHE_LINE_SIZE
+int cache_line_size(void);
+#endif
+#endif
+
 #endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 771264d4726a..b39c38ee9fdb 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -40,6 +40,7 @@ obj-y		+= entry-armv.o
 endif
 
 obj-$(CONFIG_MMU)		+= bugs.o
+obj-$(CONFIG_OF)		+= cacheinfo.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
 obj-$(CONFIG_FIQ)		+= fiq.o fiqasm.o
diff --git a/arch/arm/kernel/cacheinfo.c b/arch/arm/kernel/cacheinfo.c
new file mode 100644
index 000000000000..878ff4d10139
--- /dev/null
+++ b/arch/arm/kernel/cacheinfo.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  ARM cacheinfo support
+ *
+ *  Copyright (C) 2023 Linaro Ltd.
+ *  Copyright (C) 2015 ARM Ltd.
+ *  All Rights Reserved
+ */
+
+#include <linux/bitfield.h>
+#include <linux/cacheinfo.h>
+#include <linux/of.h>
+
+#include <asm/cachetype.h>
+#include <asm/cputype.h>
+#include <asm/system_info.h>
+
+/* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n = 1 to 7 */
+#define CLIDR_CTYPE_SHIFT(level)	(3 * (level - 1))
+#define CLIDR_CTYPE_MASK(level)		(7 << CLIDR_CTYPE_SHIFT(level))
+#define CLIDR_CTYPE(clidr, level)	\
+	(((clidr) & CLIDR_CTYPE_MASK(level)) >> CLIDR_CTYPE_SHIFT(level))
+
+#define MAX_CACHE_LEVEL			7	/* Max 7 level supported */
+
+#define CTR_FORMAT_MASK	GENMASK(27, 24)
+#define CTR_CWG_MASK	GENMASK(27, 24)
+#define CTR_DSIZE_LEN_MASK GENMASK(13, 12)
+#define CTR_ISIZE_LEN_MASK GENMASK(1, 0)
+
+/* Also valid for v7m */
+static inline int cache_line_size_cp15(void)
+{
+	u32 ctr = read_cpuid_cachetype();
+	u32 format = FIELD_GET(CTR_FORMAT_MASK, ctr);
+
+	if (format == 4) {
+		u32 cwg = FIELD_GET(CTR_CWG_MASK, ctr);
+
+		return cwg ? 4 << cwg : ARCH_DMA_MINALIGN;
+	} else if (WARN_ON_ONCE(format != 0)) {
+		return ARCH_DMA_MINALIGN;
+	}
+
+	return 8 << max(FIELD_GET(CTR_ISIZE_LEN_MASK, ctr),
+			FIELD_GET(CTR_DSIZE_LEN_MASK, ctr));
+}
+
+int cache_line_size(void)
+{
+	if (coherency_max_size != 0)
+		return coherency_max_size;
+
+	/* CP15 is optional / implementation defined before ARMv6 */
+	if (cpu_architecture() < CPU_ARCH_ARMv6)
+		return ARCH_DMA_MINALIGN;
+
+	return cache_line_size_cp15();
+}
+EXPORT_SYMBOL_GPL(cache_line_size);
+
+static inline enum cache_type get_cache_type(int level)
+{
+	u32 clidr;
+
+	if (level > MAX_CACHE_LEVEL)
+		return CACHE_TYPE_NOCACHE;
+
+	clidr = read_clidr();
+
+	return CLIDR_CTYPE(clidr, level);
+}
+
+static void ci_leaf_init(struct cacheinfo *this_leaf,
+			 enum cache_type type, unsigned int level)
+{
+	this_leaf->level = level;
+	this_leaf->type = type;
+}
+
+static int detect_cache_level(unsigned int *level_p, unsigned int *leaves_p)
+{
+	unsigned int ctype, level, leaves;
+
+	/* CLIDR is not present before ARMv7/v7m */
+	if (cpu_architecture() < CPU_ARCH_ARMv7)
+		return -EOPNOTSUPP;
+
+	for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) {
+		ctype = get_cache_type(level);
+		if (ctype == CACHE_TYPE_NOCACHE) {
+			level--;
+			break;
+		}
+		/* Separate instruction and data caches */
+		leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1;
+	}
+
+	*level_p = level;
+	*leaves_p = leaves;
+
+	return 0;
+}
+
+int early_cache_level(unsigned int cpu)
+{
+	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+
+	return detect_cache_level(&this_cpu_ci->num_levels, &this_cpu_ci->num_leaves);
+}
+
+int init_cache_level(unsigned int cpu)
+{
+	unsigned int level, leaves;
+	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+	int fw_level;
+	int ret;
+
+	ret = detect_cache_level(&level, &leaves);
+	if (ret)
+		return ret;
+
+	fw_level = of_find_last_cache_level(cpu);
+
+	if (level < fw_level) {
+		/*
+		 * some external caches not specified in CLIDR_EL1
+		 * the information may be available in the device tree
+		 * only unified external caches are considered here
+		 */
+		leaves += (fw_level - level);
+		level = fw_level;
+	}
+
+	this_cpu_ci->num_levels = level;
+	this_cpu_ci->num_leaves = leaves;
+	return 0;
+}
+
+int populate_cache_leaves(unsigned int cpu)
+{
+	unsigned int level, idx;
+	enum cache_type type;
+	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+	struct cacheinfo *this_leaf = this_cpu_ci->info_list;
+	unsigned int arch = cpu_architecture();
+
+	/* CLIDR is not present before ARMv7/v7m */
+	if (arch < CPU_ARCH_ARMv7)
+		return -EOPNOTSUPP;
+
+	for (idx = 0, level = 1; level <= this_cpu_ci->num_levels &&
+	     idx < this_cpu_ci->num_leaves; idx++, level++) {
+		type = get_cache_type(level);
+		if (type == CACHE_TYPE_SEPARATE) {
+			ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
+			ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
+		} else {
+			ci_leaf_init(this_leaf++, type, level);
+		}
+	}
+
+	return 0;
+}
diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h
index d504eb4b49ab..cb1222b8bbc8 100644
--- a/include/linux/cacheinfo.h
+++ b/include/linux/cacheinfo.h
@@ -132,7 +132,7 @@ static inline int get_cpu_cacheinfo_id(int cpu, int level)
 	return -1;
 }
 
-#ifdef CONFIG_ARM64
+#if defined(CONFIG_ARM64) || defined(CONFIG_ARM)
 #define use_arch_cache_info()	(true)
 #else
 #define use_arch_cache_info()	(false)

-- 
2.39.2



From atishp at atishpatra.org  Tue Feb 20 15:03:40 2024
From: atishp at atishpatra.org (Atish Patra)
Date: Tue, 20 Feb 2024 15:03:40 -0800
Subject: [PATCH v5 11/12] KVM: riscv: selftests: Change vcpu_has_ext to a
 common function
In-Reply-To: <68856b86a93a4188558e5d0ebac0dd6aac8e404c.1705916069.git.haibo1.xu@intel.com>
References: <cover.1705916069.git.haibo1.xu@intel.com> <68856b86a93a4188558e5d0ebac0dd6aac8e404c.1705916069.git.haibo1.xu@intel.com>
Message-ID: <CAOnJCULwRTSnrQkR2o1P53R=tJ3TAxX+y+XRBesW6OFEzgFv2g@mail.gmail.com>

On Mon, Jan 22, 2024 at 1:48?AM Haibo Xu <haibo1.xu at intel.com> wrote:
>
> Move vcpu_has_ext to the processor.c and rename it to __vcpu_has_ext
> so that other test cases can use it for vCPU extension check.
>
> Signed-off-by: Haibo Xu <haibo1.xu at intel.com>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> ---
>  tools/testing/selftests/kvm/include/riscv/processor.h |  2 ++
>  tools/testing/selftests/kvm/lib/riscv/processor.c     | 10 ++++++++++
>  tools/testing/selftests/kvm/riscv/get-reg-list.c      | 11 +----------
>  3 files changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> index b68b1b731a34..bd27e1c67579 100644
> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> @@ -42,6 +42,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
>  #define RISCV_ISA_EXT_REG(idx) __kvm_reg_id(KVM_REG_RISCV_ISA_EXT, \
>                                              idx, KVM_REG_SIZE_ULONG)
>
> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
> +
>  struct ex_regs {
>         unsigned long ra;
>         unsigned long sp;
> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> index 39a1e9902dec..dad73ce18164 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> @@ -15,6 +15,16 @@
>
>  static vm_vaddr_t exception_handlers;
>
> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> +{
> +       unsigned long value = 0;
> +       int ret;
> +
> +       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> +
> +       return !ret && !!value;
> +}
> +

Not sure what was the base patch on which this was rebased. The actual
commit in the queue branch looks different.

https://github.com/kvm-riscv/linux/commit/5563517cc2012e3326411b360c9924d3f2706c8d

Both seem to have the same bug though the tests fail now and require
the following fix.
The ext id should be uint64_t and we need to pass ext directly so that
SBI extension tests can also pass.


--- a/tools/testing/selftests/kvm/include/riscv/processor.h
+++ b/tools/testing/selftests/kvm/include/riscv/processor.h
@@ -48,7 +48,7 @@ static inline uint64_t __kvm_reg_id(uint64_t type,
uint64_t subtype,
KVM_REG_RISCV_SBI_SINGLE, \
idx, KVM_REG_SIZE_ULONG)

-bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
+bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext);

struct ex_regs {
unsigned long ra;
diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c
b/tools/testing/selftests/kvm/lib/riscv/processor.c
index 282587cd4bbc..ec66d331a127 100644
--- a/tools/testing/selftests/kvm/lib/riscv/processor.c
+++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
@@ -15,12 +15,12 @@

static vm_vaddr_t exception_handlers;

-bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
+bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext)
{
unsigned long value = 0;
int ret;

- ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
+ ret = __vcpu_get_reg(vcpu, ext, &value);

return !ret && !!value;
}

With the above the fix, Both SBI/ISA extension tests pass.
# ./get-reg-list
sbi-base: PASS
sbi-sta: PASS
sbi-pmu: PASS
sbi-dbcn: PASS
aia: PASS
fp_f: PASS
fp_d: PASS
1..0 # SKIP - h not available, skipping tests
smstateen: PASS
sscofpmf: PASS
sstc: PASS
1..0 # SKIP - svinval not available, skipping tests
1..0 # SKIP - svnapot not available, skipping tests
1..0 # SKIP - svpbmt not available, skipping tests
zba: PASS
zbb: PASS
zbc: PASS
1..0 # SKIP - zbkb not available, skipping tests
1..0 # SKIP - zbkc not available, skipping tests
1..0 # SKIP - zbkx not available, skipping tests
zbs: PASS
zfa: PASS
1..0 # SKIP - zfh not available, skipping tests
1..0 # SKIP - zfhmin not available, skipping tests
zicbom: PASS
zicboz: PASS
zicntr: PASS
1..0 # SKIP - zicond not available, skipping tests
zicsr: PASS
zifencei: PASS
zihintntl: PASS
zihintpause: PASS
zihpm: PASS


>  static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
>  {
>         return (v + vm->page_size) & ~(vm->page_size - 1);
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 25de4b8bc347..ed29ba45588c 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -75,15 +75,6 @@ bool check_reject_set(int err)
>         return err == EINVAL;
>  }
>
> -static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> -{
> -       int ret;
> -       unsigned long value;
> -
> -       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> -       return (ret) ? false : !!value;
> -}
> -
>  void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>  {
>         unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
> @@ -111,7 +102,7 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>                 __vcpu_set_reg(vcpu, RISCV_ISA_EXT_REG(s->feature), 1);
>
>                 /* Double check whether the desired extension was enabled */
> -               __TEST_REQUIRE(vcpu_has_ext(vcpu, s->feature),
> +               __TEST_REQUIRE(__vcpu_has_ext(vcpu, s->feature),
>                                "%s not available, skipping tests\n", s->name);
>         }
>  }
> --
> 2.34.1
>


-- 
Regards,
Atish


From linus.walleij at linaro.org  Tue Feb 20 15:03:59 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 00:03:59 +0100
Subject: [PATCH v2 0/4] PAN for ARM32 using LPAE
Message-ID: <20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org>

This is a patch set from Catalin that ended up on the back burner.

Since LPAE systems, i.e. ARM32 systems with a lot of physical memory,
will be with us for a while more, this is a pretty straight-forward
hardening measure that we should support.

The last patch explains the mechanism: since PAN using CPU domains
isn't available when using the LPAE MMU tables, we use the split
between the two translation base tables instead: TTBR0 is for
userspace pages and TTBR1 is for kernelspace tables. When executing
in kernelspace: we protect userspace by simply disabling page
walks in TTBR0.

The simplest way to test a PAN crash:
- Enable CONFIG_LKDTM
- echo "ACCESS_USERSPACE" | cat >/sys/kernel/debug/provoke-crash/DIRECT
- echo "EXEC_USERSPACE" | cat >/sys/kernel/debug/provoke-crash/DIRECT

This was also tested by a simple hack in the ELF loader:

create_elf_tables()
+       unsigned char *test;
(...)
        if (copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
                return -EFAULT;
+       /* Cause a kernelspace access to userspace memory */
+       test = (char *)u_rand_bytes;
+       pr_info("Some byte: %02x\n", *test);

This tries to read a byte from userspace memory right after the
first unconditional copy_to_user(), a function that carefully
switches access permissions if we're using PAN.

Without LPAE PAN this will just happily print these bytes from
userspace but with LPAE PAN it will cause a predictable
crash:

Run /init as init process
Some byte: ac
8<--- cut here ---
Unable to handle kernel paging request at virtual address 7ec59f6b when read
[7ec59f6b] *pgd=82c3b003, *pmd=82863003, *pte=e00000882f6f5f
Internal error: Oops: 206 [#1] SMP ARM
CPU: 0 PID: 47 Comm: rc.init Not tainted 6.7.0-rc1+ #25
Hardware name: ARM-Versatile Express
PC is at create_elf_tables+0x13c/0x608

Thus we can show that LPAE PAN does its job.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Changes in v1 (from Catalins original patch set):
- Use IS_ENABLED() to avoid some ifdefs
Changes in v2:
- Make the TTBCR a separate field in struct svc_pt_regs as requested
  by Russell. Adjust code accordingly.
- Push the MM page fault permission check into a local function
  and avoid the too generic uaccess_disabled() as requested by Ard.
- Link to v1: https://lore.kernel.org/r/20240123-arm32-lpae-pan-v1-0-7ea98a20514c at linaro.org

---
Catalin Marinas (4):
      ARM: Add TTBCR_* definitions to pgtable-3level-hwdef.h
      ARM: Move asm statements accessing TTBCR into C functions
      ARM: Reduce the number of #ifdef CONFIG_CPU_SW_DOMAIN_PAN
      ARM: Implement privileged no-access using TTBR0 page table walks disabling

 arch/arm/Kconfig                            | 22 +++++++++--
 arch/arm/include/asm/assembler.h            |  1 +
 arch/arm/include/asm/pgtable-3level-hwdef.h | 26 +++++++++++++
 arch/arm/include/asm/proc-fns.h             | 12 ++++++
 arch/arm/include/asm/ptrace.h               |  1 +
 arch/arm/include/asm/uaccess-asm.h          | 58 +++++++++++++++++++++++++++--
 arch/arm/include/asm/uaccess.h              | 51 ++++++++++++++++++++++---
 arch/arm/kernel/asm-offsets.c               |  1 +
 arch/arm/kernel/suspend.c                   |  8 ++++
 arch/arm/lib/csumpartialcopyuser.S          | 20 +++++++++-
 arch/arm/mm/fault.c                         | 29 +++++++++++++++
 arch/arm/mm/mmu.c                           |  7 ++--
 12 files changed, 218 insertions(+), 18 deletions(-)
---
base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
change-id: 20231216-arm32-lpae-pan-56125ab63d63

Best regards,
-- 
Linus Walleij <linus.walleij at linaro.org>



From linus.walleij at linaro.org  Tue Feb 20 15:04:00 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 00:04:00 +0100
Subject: [PATCH v2 1/4] ARM: Add TTBCR_* definitions to
 pgtable-3level-hwdef.h
In-Reply-To: <20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org>
References: <20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org>
Message-ID: <20240221-arm32-lpae-pan-v2-1-991096bba5d8@linaro.org>

From: Catalin Marinas <catalin.marinas at arm.com>

These macros will be used in a subsequent patch.

At one point these were part of the ARM32 KVM but that is no
longer the case.

Since these macros are only relevant to LPAE kernel builds, they
are added to pgtable-3level-hwdef.h

Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Reviewed-by: Kees Cook <keescook at chromium.org>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/include/asm/pgtable-3level-hwdef.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
index 2f35b4eddaa8..19da7753a0b8 100644
--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -94,4 +94,21 @@
 
 #define TTBR1_SIZE	(((PAGE_OFFSET >> 30) - 1) << 16)
 
+/*
+ * TTBCR register bits.
+ */
+#define TTBCR_EAE		(1 << 31)
+#define TTBCR_IMP		(1 << 30)
+#define TTBCR_SH1_MASK		(3 << 28)
+#define TTBCR_ORGN1_MASK	(3 << 26)
+#define TTBCR_IRGN1_MASK	(3 << 24)
+#define TTBCR_EPD1		(1 << 23)
+#define TTBCR_A1		(1 << 22)
+#define TTBCR_T1SZ_MASK		(7 << 16)
+#define TTBCR_SH0_MASK		(3 << 12)
+#define TTBCR_ORGN0_MASK	(3 << 10)
+#define TTBCR_IRGN0_MASK	(3 << 8)
+#define TTBCR_EPD0		(1 << 7)
+#define TTBCR_T0SZ_MASK		(7 << 0)
+
 #endif

-- 
2.34.1



From linus.walleij at linaro.org  Tue Feb 20 15:04:01 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 00:04:01 +0100
Subject: [PATCH v2 2/4] ARM: Move asm statements accessing TTBCR into C
 functions
In-Reply-To: <20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org>
References: <20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org>
Message-ID: <20240221-arm32-lpae-pan-v2-2-991096bba5d8@linaro.org>

From: Catalin Marinas <catalin.marinas at arm.com>

This patch implements cpu_get_ttbcr() and cpu_set_ttbcr() and replaces
the corresponding asm statements.

Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Reviewed-by: Kees Cook <keescook at chromium.org>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/include/asm/proc-fns.h | 12 ++++++++++++
 arch/arm/mm/mmu.c               |  7 +++----
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 280396483f5d..a13e5cf3d1ff 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -178,6 +178,18 @@ extern void cpu_resume(void);
 	})
 #endif
 
+static inline unsigned int cpu_get_ttbcr(void)
+{
+	unsigned int ttbcr;
+	asm("mrc p15, 0, %0, c2, c0, 2" : "=r" (ttbcr));
+	return ttbcr;
+}
+
+static inline void cpu_set_ttbcr(unsigned int ttbcr)
+{
+	asm volatile("mcr p15, 0, %0, c2, c0, 2" : : "r" (ttbcr));
+}
+
 #else	/*!CONFIG_MMU */
 
 #define cpu_switch_mm(pgd,mm)	{ }
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 674ed71573a8..9a780da6a4e1 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1687,9 +1687,8 @@ static void __init early_paging_init(const struct machine_desc *mdesc)
 	 */
 	cr = get_cr();
 	set_cr(cr & ~(CR_I | CR_C));
-	asm("mrc p15, 0, %0, c2, c0, 2" : "=r" (ttbcr));
-	asm volatile("mcr p15, 0, %0, c2, c0, 2"
-		: : "r" (ttbcr & ~(3 << 8 | 3 << 10)));
+	ttbcr = cpu_get_ttbcr();
+	cpu_set_ttbcr(ttbcr & ~(3 << 8 | 3 << 10));
 	flush_cache_all();
 
 	/*
@@ -1701,7 +1700,7 @@ static void __init early_paging_init(const struct machine_desc *mdesc)
 	lpae_pgtables_remap(offset, pa_pgd);
 
 	/* Re-enable the caches and cacheable TLB walks */
-	asm volatile("mcr p15, 0, %0, c2, c0, 2" : : "r" (ttbcr));
+	cpu_set_ttbcr(ttbcr);
 	set_cr(cr);
 }
 

-- 
2.34.1



From linus.walleij at linaro.org  Tue Feb 20 15:04:02 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 00:04:02 +0100
Subject: [PATCH v2 3/4] ARM: Reduce the number of #ifdef
 CONFIG_CPU_SW_DOMAIN_PAN
In-Reply-To: <20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org>
References: <20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org>
Message-ID: <20240221-arm32-lpae-pan-v2-3-991096bba5d8@linaro.org>

From: Catalin Marinas <catalin.marinas at arm.com>

This is a clean-up patch aimed at reducing the number of checks on
CONFIG_CPU_SW_DOMAIN_PAN, together with some empty lines for better
clarity once the CONFIG_CPU_TTBR0_PAN is introduced.

Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Reviewed-by: Kees Cook <keescook at chromium.org>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/include/asm/uaccess-asm.h | 16 ++++++++++++----
 arch/arm/include/asm/uaccess.h     | 21 +++++++++++++++------
 arch/arm/lib/csumpartialcopyuser.S |  6 +++++-
 3 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/uaccess-asm.h b/arch/arm/include/asm/uaccess-asm.h
index 65da32e1f1c1..ea42ba25920f 100644
--- a/arch/arm/include/asm/uaccess-asm.h
+++ b/arch/arm/include/asm/uaccess-asm.h
@@ -39,8 +39,9 @@
 #endif
 	.endm
 
-	.macro	uaccess_disable, tmp, isb=1
 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
+
+	.macro	uaccess_disable, tmp, isb=1
 	/*
 	 * Whenever we re-enter userspace, the domains should always be
 	 * set appropriately.
@@ -50,11 +51,9 @@
 	.if	\isb
 	instr_sync
 	.endif
-#endif
 	.endm
 
 	.macro	uaccess_enable, tmp, isb=1
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	/*
 	 * Whenever we re-enter userspace, the domains should always be
 	 * set appropriately.
@@ -64,9 +63,18 @@
 	.if	\isb
 	instr_sync
 	.endif
-#endif
 	.endm
 
+#else
+
+	.macro	uaccess_disable, tmp, isb=1
+	.endm
+
+	.macro	uaccess_enable, tmp, isb=1
+	.endm
+
+#endif
+
 #if defined(CONFIG_CPU_SW_DOMAIN_PAN) || defined(CONFIG_CPU_USE_DOMAINS)
 #define DACR(x...)	x
 #else
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 9556d04387f7..9b9234d1bb6a 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -24,9 +24,10 @@
  * perform such accesses (eg, via list poison values) which could then
  * be exploited for priviledge escalation.
  */
+#if defined(CONFIG_CPU_SW_DOMAIN_PAN)
+
 static __always_inline unsigned int uaccess_save_and_enable(void)
 {
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	unsigned int old_domain = get_domain();
 
 	/* Set the current domain access to permit user accesses */
@@ -34,19 +35,27 @@ static __always_inline unsigned int uaccess_save_and_enable(void)
 		   domain_val(DOMAIN_USER, DOMAIN_CLIENT));
 
 	return old_domain;
-#else
-	return 0;
-#endif
 }
 
 static __always_inline void uaccess_restore(unsigned int flags)
 {
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	/* Restore the user access mask */
 	set_domain(flags);
-#endif
 }
 
+#else
+
+static inline unsigned int uaccess_save_and_enable(void)
+{
+	return 0;
+}
+
+static inline void uaccess_restore(unsigned int flags)
+{
+}
+
+#endif
+
 /*
  * These two are intentionally not defined anywhere - if the kernel
  * code generates any references to them, that's a bug.
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index 6928781e6bee..04d8d9d741c7 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -13,7 +13,8 @@
 
 		.text
 
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+#if defined(CONFIG_CPU_SW_DOMAIN_PAN)
+
 		.macro	save_regs
 		mrc	p15, 0, ip, c3, c0, 0
 		stmfd	sp!, {r1, r2, r4 - r8, ip, lr}
@@ -25,7 +26,9 @@
 		mcr	p15, 0, ip, c3, c0, 0
 		ret	lr
 		.endm
+
 #else
+
 		.macro	save_regs
 		stmfd	sp!, {r1, r2, r4 - r8, lr}
 		.endm
@@ -33,6 +36,7 @@
 		.macro	load_regs
 		ldmfd	sp!, {r1, r2, r4 - r8, pc}
 		.endm
+
 #endif
 
 		.macro	load1b,	reg1

-- 
2.34.1



From linus.walleij at linaro.org  Tue Feb 20 15:04:03 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 00:04:03 +0100
Subject: [PATCH v2 4/4] ARM: Implement privileged no-access using TTBR0
 page table walks disabling
In-Reply-To: <20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org>
References: <20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org>
Message-ID: <20240221-arm32-lpae-pan-v2-4-991096bba5d8@linaro.org>

From: Catalin Marinas <catalin.marinas at arm.com>

With LPAE enabled, privileged no-access cannot be enforced using CPU
domains as such feature is not available. This patch implements PAN
by disabling TTBR0 page table walks while in kernel mode.

The ARM architecture allows page table walks to be split between TTBR0
and TTBR1. With LPAE enabled, the split is defined by a combination of
TTBCR T0SZ and T1SZ bits. Currently, an LPAE-enabled kernel uses TTBR0
for user addresses and TTBR1 for kernel addresses with the VMSPLIT_2G
and VMSPLIT_3G configurations. The main advantage for the 3:1 split is
that TTBR1 is reduced to 2 levels, so potentially faster TLB refill
(though usually the first level entries are already cached in the TLB).

The PAN support on LPAE-enabled kernels uses TTBR0 when running in user
space or in kernel space during user access routines (TTBCR T0SZ and
T1SZ are both 0). When running user accesses are disabled in kernel
mode, TTBR0 page table walks are disabled by setting TTBCR.EPD0. TTBR1
is used for kernel accesses (including loadable modules; anything
covered by swapper_pg_dir) by reducing the TTBCR.T0SZ to the minimum
(2^(32-7) = 32MB). To avoid user accesses potentially hitting stale TLB
entries, the ASID is switched to 0 (reserved) by setting TTBCR.A1 and
using the ASID value in TTBR1. The difference from a non-PAN kernel is
that with the 3:1 memory split, TTBR1 always uses 3 levels of page
tables.

Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Reviewed-by: Kees Cook <keescook at chromium.org>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
ChangeLog v1->v2:
- Make the SVC mode TTBCR a separate field in struct svc_pt_regs
  as requested by Russell.
- Push the MM page fault permission check into a local function
  and avoid the too generic uaccess_disabled() as requested by Ard.
---
 arch/arm/Kconfig                            | 22 ++++++++++++---
 arch/arm/include/asm/assembler.h            |  1 +
 arch/arm/include/asm/pgtable-3level-hwdef.h |  9 +++++++
 arch/arm/include/asm/ptrace.h               |  1 +
 arch/arm/include/asm/uaccess-asm.h          | 42 +++++++++++++++++++++++++++++
 arch/arm/include/asm/uaccess.h              | 30 +++++++++++++++++++++
 arch/arm/kernel/asm-offsets.c               |  1 +
 arch/arm/kernel/suspend.c                   |  8 ++++++
 arch/arm/lib/csumpartialcopyuser.S          | 14 ++++++++++
 arch/arm/mm/fault.c                         | 29 ++++++++++++++++++++
 10 files changed, 154 insertions(+), 3 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0af6709570d1..3d97a15a3e2d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1231,9 +1231,9 @@ config HIGHPTE
 	  consumed by page tables.  Setting this option will allow
 	  user-space 2nd level page tables to reside in high memory.
 
-config CPU_SW_DOMAIN_PAN
-	bool "Enable use of CPU domains to implement privileged no-access"
-	depends on MMU && !ARM_LPAE
+config ARM_PAN
+	bool "Enable privileged no-access"
+	depends on MMU
 	default y
 	help
 	  Increase kernel security by ensuring that normal kernel accesses
@@ -1242,10 +1242,26 @@ config CPU_SW_DOMAIN_PAN
 	  by ensuring that magic values (such as LIST_POISON) will always
 	  fault when dereferenced.
 
+	  The implementation uses CPU domains when !CONFIG_ARM_LPAE and
+	  disabling of TTBR0 page table walks with CONFIG_ARM_LPAE.
+
+config CPU_SW_DOMAIN_PAN
+	def_bool y
+	depends on ARM_PAN && !ARM_LPAE
+	help
+	  Enable use of CPU domains to implement privileged no-access.
+
 	  CPUs with low-vector mappings use a best-efforts implementation.
 	  Their lower 1MB needs to remain accessible for the vectors, but
 	  the remainder of userspace will become appropriately inaccessible.
 
+config CPU_TTBR0_PAN
+	def_bool y
+	depends on ARM_PAN && ARM_LPAE
+	help
+	  Enable privileged no-access by disabling TTBR0 page table walks when
+	  running in kernel mode.
+
 config HW_PERF_EVENTS
 	def_bool y
 	depends on ARM_PMU
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index aebe2c8f6a68..d33c1e24e00b 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -21,6 +21,7 @@
 #include <asm/opcodes-virt.h>
 #include <asm/asm-offsets.h>
 #include <asm/page.h>
+#include <asm/pgtable.h>
 #include <asm/thread_info.h>
 #include <asm/uaccess-asm.h>
 
diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
index 19da7753a0b8..323ad811732e 100644
--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -74,6 +74,7 @@
 #define PHYS_MASK_SHIFT		(40)
 #define PHYS_MASK		((1ULL << PHYS_MASK_SHIFT) - 1)
 
+#ifndef CONFIG_CPU_TTBR0_PAN
 /*
  * TTBR0/TTBR1 split (PAGE_OFFSET):
  *   0x40000000: T0SZ = 2, T1SZ = 0 (not used)
@@ -93,6 +94,14 @@
 #endif
 
 #define TTBR1_SIZE	(((PAGE_OFFSET >> 30) - 1) << 16)
+#else
+/*
+ * With CONFIG_CPU_TTBR0_PAN enabled, TTBR1 is only used during uaccess
+ * disabled regions when TTBR0 is disabled.
+ */
+#define TTBR1_OFFSET	0			/* pointing to swapper_pg_dir */
+#define TTBR1_SIZE	0			/* TTBR1 size controlled via TTBCR.T0SZ */
+#endif
 
 /*
  * TTBCR register bits.
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 7f44e88d1f25..f064252498c7 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -19,6 +19,7 @@ struct pt_regs {
 struct svc_pt_regs {
 	struct pt_regs regs;
 	u32 dacr;
+	u32 ttbcr;
 };
 
 #define to_svc_pt_regs(r) container_of(r, struct svc_pt_regs, regs)
diff --git a/arch/arm/include/asm/uaccess-asm.h b/arch/arm/include/asm/uaccess-asm.h
index ea42ba25920f..7c06040af078 100644
--- a/arch/arm/include/asm/uaccess-asm.h
+++ b/arch/arm/include/asm/uaccess-asm.h
@@ -65,6 +65,37 @@
 	.endif
 	.endm
 
+#elif defined(CONFIG_CPU_TTBR0_PAN)
+
+	.macro	uaccess_disable, tmp, isb=1
+	/*
+	 * Disable TTBR0 page table walks (EDP0 = 1), use the reserved ASID
+	 * from TTBR1 (A1 = 1) and enable TTBR1 page table walks for kernel
+	 * addresses by reducing TTBR0 range to 32MB (T0SZ = 7).
+	 */
+	mrc	p15, 0, \tmp, c2, c0, 2		@ read TTBCR
+	orr	\tmp, \tmp, #TTBCR_EPD0 | TTBCR_T0SZ_MASK
+	orr	\tmp, \tmp, #TTBCR_A1
+	mcr	p15, 0, \tmp, c2, c0, 2		@ write TTBCR
+	.if	\isb
+	instr_sync
+	.endif
+	.endm
+
+	.macro	uaccess_enable, tmp, isb=1
+	/*
+	 * Enable TTBR0 page table walks (T0SZ = 0, EDP0 = 0) and ASID from
+	 * TTBR0 (A1 = 0).
+	 */
+	mrc	p15, 0, \tmp, c2, c0, 2		@ read TTBCR
+	bic	\tmp, \tmp, #TTBCR_EPD0 | TTBCR_T0SZ_MASK
+	bic	\tmp, \tmp, #TTBCR_A1
+	mcr	p15, 0, \tmp, c2, c0, 2		@ write TTBCR
+	.if	\isb
+	instr_sync
+	.endif
+	.endm
+
 #else
 
 	.macro	uaccess_disable, tmp, isb=1
@@ -79,6 +110,12 @@
 #define DACR(x...)	x
 #else
 #define DACR(x...)
+#endif
+
+#ifdef CONFIG_CPU_TTBR0_PAN
+#define PAN(x...)	x
+#else
+#define PAN(x...)
 #endif
 
 	/*
@@ -94,6 +131,8 @@
 	.macro	uaccess_entry, tsk, tmp0, tmp1, tmp2, disable
  DACR(	mrc	p15, 0, \tmp0, c3, c0, 0)
  DACR(	str	\tmp0, [sp, #SVC_DACR])
+ PAN(	mrc	p15, 0, \tmp0, c2, c0, 2)
+ PAN(	str	\tmp0, [sp, #SVC_TTBCR])
 	.if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN)
 	/* kernel=client, user=no access */
 	mov	\tmp2, #DACR_UACCESS_DISABLE
@@ -112,8 +151,11 @@
 	.macro	uaccess_exit, tsk, tmp0, tmp1
  DACR(	ldr	\tmp0, [sp, #SVC_DACR])
  DACR(	mcr	p15, 0, \tmp0, c3, c0, 0)
+ PAN(	ldr	\tmp0, [sp, #SVC_TTBCR])
+ PAN(	mcr	p15, 0, \tmp0, c2, c0, 2)
 	.endm
 
 #undef DACR
+#undef PAN
 
 #endif /* __ASM_UACCESS_ASM_H__ */
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 9b9234d1bb6a..a4e86c5e03a2 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -14,6 +14,8 @@
 #include <asm/domain.h>
 #include <asm/unaligned.h>
 #include <asm/unified.h>
+#include <asm/pgtable.h>
+#include <asm/proc-fns.h>
 #include <asm/compiler.h>
 
 #include <asm/extable.h>
@@ -43,6 +45,28 @@ static __always_inline void uaccess_restore(unsigned int flags)
 	set_domain(flags);
 }
 
+#elif defined(CONFIG_CPU_TTBR0_PAN)
+
+static inline unsigned int uaccess_save_and_enable(void)
+{
+	unsigned int old_ttbcr = cpu_get_ttbcr();
+
+	/*
+	 * Enable TTBR0 page table walks (T0SZ = 0, EDP0 = 0) and ASID from
+	 * TTBR0 (A1 = 0).
+	 */
+	cpu_set_ttbcr(old_ttbcr & ~(TTBCR_A1 | TTBCR_EPD0 | TTBCR_T0SZ_MASK));
+	isb();
+
+	return old_ttbcr;
+}
+
+static inline void uaccess_restore(unsigned int flags)
+{
+	cpu_set_ttbcr(flags);
+	isb();
+}
+
 #else
 
 static inline unsigned int uaccess_save_and_enable(void)
@@ -54,6 +78,12 @@ static inline void uaccess_restore(unsigned int flags)
 {
 }
 
+static inline bool uaccess_disabled(struct pt_regs *regs)
+{
+	/* Without PAN userspace is always available */
+	return false;
+}
+
 #endif
 
 /*
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 219cbc7e5d13..dd2567ba987f 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -83,6 +83,7 @@ int main(void)
   DEFINE(S_OLD_R0,		offsetof(struct pt_regs, ARM_ORIG_r0));
   DEFINE(PT_REGS_SIZE,		sizeof(struct pt_regs));
   DEFINE(SVC_DACR,		offsetof(struct svc_pt_regs, dacr));
+  DEFINE(SVC_TTBCR,		offsetof(struct svc_pt_regs, ttbcr));
   DEFINE(SVC_REGS_SIZE,		sizeof(struct svc_pt_regs));
   BLANK();
   DEFINE(SIGFRAME_RC3_OFFSET,	offsetof(struct sigframe, retcode[3]));
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index c3ec3861dd07..58a6441b58c4 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -12,6 +12,7 @@
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 #include <asm/tlbflush.h>
+#include <asm/uaccess.h>
 
 extern int __cpu_suspend(unsigned long, int (*)(unsigned long), u32 cpuid);
 extern void cpu_resume_mmu(void);
@@ -26,6 +27,13 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
 	if (!idmap_pgd)
 		return -EINVAL;
 
+	/*
+	 * Needed for the MMU disabling/enabing code to be able to run from
+	 * TTBR0 addresses.
+	 */
+	if (IS_ENABLED(CONFIG_CPU_TTBR0_PAN))
+		uaccess_save_and_enable();
+
 	/*
 	 * Function graph tracer state gets incosistent when the kernel
 	 * calls functions that never return (aka suspend finishers) hence
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index 04d8d9d741c7..c289bde04743 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -27,6 +27,20 @@
 		ret	lr
 		.endm
 
+#elif defined(CONFIG_CPU_TTBR0_PAN)
+
+		.macro	save_regs
+		mrc	p15, 0, ip, c2, c0, 2		@ read TTBCR
+		stmfd	sp!, {r1, r2, r4 - r8, ip, lr}
+		uaccess_enable ip
+		.endm
+
+		.macro	load_regs
+		ldmfd	sp!, {r1, r2, r4 - r8, ip, lr}
+		mcr	p15, 0, ip, c2, c0, 2		@ restore TTBCR
+		ret	lr
+		.endm
+
 #else
 
 		.macro	save_regs
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index e96fb40b9cc3..7d262a819ad1 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -235,6 +235,27 @@ static inline bool is_permission_fault(unsigned int fsr)
 	return false;
 }
 
+#ifdef CONFIG_CPU_TTBR0_PAN
+static inline bool ttbr0_usermode_access_allowed(struct pt_regs *regs)
+{
+	struct svc_pt_regs *svcregs;
+
+	/* If we are in user mode: permission granted */
+	if (user_mode(regs))
+		return true;
+
+	/* uaccess state saved above pt_regs on SVC exception entry */
+	svcregs = to_svc_pt_regs(regs);
+
+	return !(svcregs->ttbcr & TTBCR_EPD0);
+}
+#else
+static inline bool ttbr0_usermode_access_allowed(struct pt_regs *regs)
+{
+	return true;
+}
+#endif
+
 static int __kprobes
 do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
@@ -278,6 +299,14 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
 
+	/*
+	 * Privileged access aborts with CONFIG_CPU_TTBR0_PAN enabled are
+	 * routed via the translation fault mechanism. Check whether uaccess
+	 * is disabled while in kernel mode.
+	 */
+	if (!ttbr0_usermode_access_allowed(regs))
+		goto no_context;
+
 	if (!(flags & FAULT_FLAG_USER))
 		goto lock_mmap;
 

-- 
2.34.1



From vladimir.oltean at nxp.com  Tue Feb 20 15:06:56 2024
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Wed, 21 Feb 2024 01:06:56 +0200
Subject: [PATCH] arm64: ls1046ardb: Replace XGMII with 10GBASE-R phy mode
In-Reply-To: <e39c811e-ad9d-4e90-8710-629b822944e0@seco.com>
References: <20240220145037.kf3avnykjif24kkr@skbuf>
 <191b4477-7b4b-47eb-bb3e-0e4d08b3b32e@seco.com>
 <20240220223706.o7wc5r57omkmgtgh@skbuf>
 <e39c811e-ad9d-4e90-8710-629b822944e0@seco.com>
Message-ID: <20240220230656.cefvrh6avji2elrd@skbuf>

On Tue, Feb 20, 2024 at 05:52:36PM -0500, Sean Anderson wrote:
> With SGMII and XFI, the PCS sits on the MAC's MDIO bus. So for SGMII and
> XFI if we don't have any labels we can just assume the PCS handle is for
> the right PCS. But for QSGMII the PCSs sit on another MAC's MDIO bus. So
> we need to tell the MAC where to find the PCS. This means we need to
> supply multiple PCSs to the MAC

So how did the other Layerscape devices with the same SerDes, PCS and
mEMAC manage to get by and support QSGMII without listing all possible
PCSes in pcs-handle-names? :-/ DPAA2 has the exact same situation with
the QSGMII PCS situated on the internal bus of another DPMAC.

It is unnecessary and buggy complexity, and it will only have to become
worse when I add support for C73 backplane autoneg in lynx-pcs and the
fman_memac driver, because I will need yet another PCS handle, this time
not even one that represents a phy-mode in particular, but a PCS handle
for C73 (with C73, the autoneg process determines the dynamic phy-mode).


From itaru.kitayama at linux.dev  Tue Feb 20 15:14:00 2024
From: itaru.kitayama at linux.dev (Itaru Kitayama)
Date: Wed, 21 Feb 2024 08:14:00 +0900
Subject: [PATCH] arm64: add early fixmap initialization flag
In-Reply-To: <ZdSTMgxcWYsT9ECs@FVFF77S0Q05N.cambridge.arm.com>
References: <20240217140326.2367186-1-skseofh@gmail.com>
 <ZdMx-svsHgrfguxX@FVFF77S0Q05N>
 <ZdPyWkOlUan5AI9r@vm3>
 <ZdSTMgxcWYsT9ECs@FVFF77S0Q05N.cambridge.arm.com>
Message-ID: <ZdUyOAQG0TK1UtTY@vm3>

On Tue, Feb 20, 2024 at 11:55:30AM +0000, Mark Rutland wrote:
> On Tue, Feb 20, 2024 at 09:29:14AM +0900, Itaru Kitayama wrote:
> > On Mon, Feb 19, 2024 at 10:48:26AM +0000, Mark Rutland wrote:
> > > On Sat, Feb 17, 2024 at 11:03:26PM +0900, skseofh at gmail.com wrote:
> > > > From: Daero Lee <skseofh at gmail.com>
> > > > 
> > > > early_fixmap_init may be called multiple times. Since there is no
> > > > change in the page table after early fixmap initialization, an
> > > > initialization flag was added.
> > > 
> > > Why is that better?
> > > 
> > > We call early_fixmap_init() in two places:
> > > 
> > > * early_fdt_map()
> > > * setup_arch()
> > > 
> > > ... and to get to setup_arch() we *must* have gone through early_fdt_map(),
> > > since __primary_switched() calls that before going to setup_arch().
> > > 
> > > So AFAICT we can remove the second call to early_fixmap_init() in setup_arch(),
> > > and rely on the earlier one in early_fdt_map().
> > 
> > Removing the second call makes the code base a bit harder to understand
> > as the functions related to DT and ACPI setup are not separated cleanly.
> > I prefer calling the early_fixmap_init() in setup_arch() as well.
> 
> I appreciate what you're saying here, but I don't think that it's better to
> keep the second call in setup_arch().
> 
> We rely on having a (stub) DT in order to find UEFI and ACPI tables, so the DT
> and ACPI setup can never be truly separated. We always need to map that DT in
> order to find the UEFI+ACPI tables, and in order to do that we must initialize
> the fixmap first.

Okay.

> 
> I don't think there's any good reason to keep a redundant call in setup_arch();
> that's just misleading and potentially problematic if we ever change
> early_fixmap_init() so that it's not idempotent.
> 
> I agree it's somewhat a layering violation for  early_fdt_map() to be
> responsible for initialising the fixmap, so how about we just pull that out,
> e.g. as below?
> 
> Mark.
> 
> ---->8----
> From 5f07f9c1d352f760fa7aba97f1b4f42d9cb99496 Mon Sep 17 00:00:00 2001
> From: Mark Rutland <mark.rutland at arm.com>
> Date: Tue, 20 Feb 2024 11:09:17 +0000
> Subject: [PATCH] arm64: clean up fixmap initalization
> 
> Currently we have redundant initialization of the fixmap, first in
> early_fdt_map(), and then again in setup_arch() before we call
> early_ioremap_init(). This redundant initialization isn't harmful, as
> early_fixmap_init() happens to be idempotent, but it's redundant and
> potentially confusing.
> 
> We need to call early_fixmap_init() before we map the FDT and before we
> call early_ioremap_init(). Ideally we'd place early_fixmap_init() and
> early_ioremap_init() in the same caller as early_ioremap_init() is
> somewhat coupled with the fixmap code.
> 
> Clean this up by moving the calls to early_fixmap_init() and
> early_ioremap_init() into a new early_mappings_init() function, and
> calling this once in __primary_switched() before we call
> early_fdt_map(). This means we initialize the fixmap once, and keep
> early_fixmap_init() and early_ioremap_init() together.
> 
> This is a cleanup, not a fix, and does not need to be backported to
> stable kernels.
> 
> Reported-by: Daero Lee <skseofh at gmail.com>
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Itaru Kitayama <itaru.kitayama at linux.dev>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/include/asm/setup.h |  1 +
>  arch/arm64/kernel/head.S       |  2 ++
>  arch/arm64/kernel/setup.c      | 11 ++++++-----
>  3 files changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
> index 2e4d7da74fb87..c8ba018bcc09f 100644
> --- a/arch/arm64/include/asm/setup.h
> +++ b/arch/arm64/include/asm/setup.h
> @@ -9,6 +9,7 @@
>  
>  void *get_early_fdt_ptr(void);
>  void early_fdt_map(u64 dt_phys);
> +void early_mappings_init(void);
>  
>  /*
>   * These two variables are used in the head.S file.
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index cab7f91949d8f..c60c5454c5704 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -510,6 +510,8 @@ SYM_FUNC_START_LOCAL(__primary_switched)
>  #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
>  	bl	kasan_early_init
>  #endif
> +	bl	early_mappings_init
> +
>  	mov	x0, x21				// pass FDT address in x0
>  	bl	early_fdt_map			// Try mapping the FDT early
>  	mov	x0, x20				// pass the full boot status
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 42c690bb2d608..7a539534ced78 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -176,8 +176,6 @@ void __init *get_early_fdt_ptr(void)
>  asmlinkage void __init early_fdt_map(u64 dt_phys)
>  {
>  	int fdt_size;
> -
> -	early_fixmap_init();
>  	early_fdt_ptr = fixmap_remap_fdt(dt_phys, &fdt_size, PAGE_KERNEL);
>  }
>  
> @@ -290,6 +288,12 @@ u64 cpu_logical_map(unsigned int cpu)
>  	return __cpu_logical_map[cpu];
>  }
>  
> +asmlinkage void __init early_mappings_init(void)
> +{
> +	early_fixmap_init();
> +	early_ioremap_init();
> +}
> +
>  void __init __no_sanitize_address setup_arch(char **cmdline_p)
>  {
>  	setup_initial_init_mm(_stext, _etext, _edata, _end);
> @@ -305,9 +309,6 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
>  	 */
>  	arm64_use_ng_mappings = kaslr_requires_kpti();
>  
> -	early_fixmap_init();
> -	early_ioremap_init();
> -
>  	setup_machine_fdt(__fdt_pointer);
>  
>  	/*

Thanks for this. Makes sense to me; would you post a proper patch
so I can build and do a boot test, just to make sure?

Reviewed-by: Itaru Kitayama <itaru.kitayama at fujitsu.com>

Thanks,
Itaru.

> -- 
> 2.30.2
> 


From sean.anderson at seco.com  Tue Feb 20 15:17:02 2024
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 20 Feb 2024 18:17:02 -0500
Subject: [PATCH] arm64: ls1046ardb: Replace XGMII with 10GBASE-R phy mode
In-Reply-To: <20240220230656.cefvrh6avji2elrd@skbuf>
References: <20240220145037.kf3avnykjif24kkr@skbuf>
 <191b4477-7b4b-47eb-bb3e-0e4d08b3b32e@seco.com>
 <20240220223706.o7wc5r57omkmgtgh@skbuf>
 <e39c811e-ad9d-4e90-8710-629b822944e0@seco.com>
 <20240220230656.cefvrh6avji2elrd@skbuf>
Message-ID: <bce5cff4-c1a5-4d71-b6cd-a89c55a628ba@seco.com>

On 2/20/24 18:06, Vladimir Oltean wrote:
> On Tue, Feb 20, 2024 at 05:52:36PM -0500, Sean Anderson wrote:
>> With SGMII and XFI, the PCS sits on the MAC's MDIO bus. So for SGMII and
>> XFI if we don't have any labels we can just assume the PCS handle is for
>> the right PCS. But for QSGMII the PCSs sit on another MAC's MDIO bus. So
>> we need to tell the MAC where to find the PCS. This means we need to
>> supply multiple PCSs to the MAC
>
> So how did the other Layerscape devices with the same SerDes, PCS and
> mEMAC manage to get by and support QSGMII without listing all possible
> PCSes in pcs-handle-names? :-/ DPAA2 has the exact same situation with
> the QSGMII PCS situated on the internal bus of another DPMAC.

I'm not familiar with them.

With DPAA we used to just try to configure the QSGMII PCSs on every
MAC's MDIO bus. This worked out since if you enabled all the MACs, the
right one would eventually configure the PCSs. But it also meant you
couldn't determine the link status (since you didn't know where your PCS
was).

> It is unnecessary and buggy complexity, and it will only have to become
> worse when I add support for C73 backplane autoneg in lynx-pcs and the
> fman_memac driver, because I will need yet another PCS handle, this time
> not even one that represents a phy-mode in particular, but a PCS handle
> for C73 (with C73, the autoneg process determines the dynamic phy-mode).

There are multiple physical PCSs there must also be multiple PCS
devices. Otherwise your software and hardware will get out of sync.

If you don't want the complexity, then don't design hardware with multiple
PCSs connected to the same MAC.

--Sean

[Embedded World 2024, SECO SpA]<https://www.messe-ticket.de/Nuernberg/embeddedworld2024/Register/ew24517689>


From rick.p.edgecombe at intel.com  Tue Feb 20 15:30:22 2024
From: rick.p.edgecombe at intel.com (Edgecombe, Rick P)
Date: Tue, 20 Feb 2024 23:30:22 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in
 userspace
In-Reply-To: <20240220185714.GO4163@brightrain.aerifal.cx>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
	 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
	 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
	 <20240220185714.GO4163@brightrain.aerifal.cx>
Message-ID: <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>

On Tue, 2024-02-20 at 13:57 -0500, Rich Felker wrote:
> On Tue, Feb 20, 2024 at 06:41:05PM +0000, Edgecombe, Rick P wrote:
> > Hmm, could the shadow stack underflow onto the real stack then? Not
> > sure how bad that is. INCSSP (incrementing the SSP register on x86)
> > loops are not rare so it seems like something that could happen.
> 
> Shadow stack underflow should fault on attempt to access
> non-shadow-stack memory as shadow-stack, no?

Maybe I'm misunderstanding. I thought the proposal included allowing
shadow stack access to convert normal address ranges to shadow stack,
and normal writes to convert shadow stack to normal.

> > 
> > Won't this prevent catching stack overflows when they happen? An
> > overflow will just turn the shadow stack into normal stack and only
> > get
> > detected when the shadow stack unwinds?
> 
> I don't think that's as big a problem as it sounds like. It might
> make
> pinpointing the spot at which things went wrong take a little bit
> more
> work, but it should not admit any wrong-execution.

Right, it's a point about debugging. I'm just trying to analyze the
pros and cons and not calling it a showstopper.

> > 
> > Shadow stacks currently have automatic guard gaps to try to prevent
> > one
> > thread from overflowing onto another thread's shadow stack. This
> > would
> > somewhat opens that up, as the stack guard gaps are usually
> > maintained
> > by userspace for new threads. It would have to be thought through
> > if
> > these could still be enforced with checking at additional spots.
> 
> I would think the existing guard pages would already do that if a
> thread's shadow stack is contiguous with its own data stack.

The difference is that the kernel provides the guard gaps, where this
would rely on userspace to do it. It is not a showstopper either.

I think my biggest question on this is how does it change the
capability for two threads to share a shadow stack. It might require
some special rules around the syscall that writes restore tokens. So
I'm not sure. It probably needs a POC.

> 
> From the musl side, I have always looked at the entirely of shadow
> stack stuff with very heavy skepticism, and anything that breaks
> existing interface contracts, introduced places where apps can get
> auto-killed because a late resource allocation fails, or requires
> applications to code around the existence of something that should be
> an implementation detail, is a non-starter. To even consider shadow
> stack support, it must truely be fully non-breaking.

The manual assembly stack switching and JIT code in the apps needs to
be updated. I don't think there is a way around it.

I agree though that the late allocation failures are not great. Mark is
working on clone3 support which should allow moving the shadow stack
allocation to happen in userspace with the normal stack. Even for riscv
though, doesn't it need to update a new register in stack switching?

BTW, x86 shadow stack has a mode where the shadow stack is writable
with a special instruction (WRSS). It enables the SSP to be set
arbitrarily by writing restore tokens. We discussed this as an option
to make the existing longjmp() and signal stuff work more transparently
for glibc.

> 
> > > _Without_ doing this, sigaltstack cannot be used to recover from
> > > stack
> > > overflows if the shadow stack limit is reached first, and
> > > makecontext
> > > cannot be supported without memory leaks and unreportable error
> > > conditions.
> > 
> > FWIW, I think the makecontext() shadow stack leaking is a bad idea.
> > I
> > would prefer the existing makecontext() interface just didn't
> > support
> > shadow stack, rather than the leaking solution glibc does today.
> 
> AIUI the proposal by Stefan makes it non-leaking because it's just
> using normal memory that reverts to normal usage on any
> non-shadow-stack access.
> 

Right, but does it break any existing apps anyway (because of small
ucontext stack sizes)?

BTW, when I talk about "not supporting" I don't mean the app should
crash. I mean it should instead run normally, just without shadow stack
enabled. Not sure if that was clear. Since shadow stack is not
essential for an application to function, it is only security hardening
on top.

Although determining if an application supports shadow stack has turned
out to be difficult in practice. Handling dlopen() is especially hard.

From rick.p.edgecombe at intel.com  Tue Feb 20 15:30:53 2024
From: rick.p.edgecombe at intel.com (Edgecombe, Rick P)
Date: Tue, 20 Feb 2024 23:30:53 +0000
Subject: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in userspace
In-Reply-To: <527e2b4d-5d2b-4993-a30a-834e77a23a40@sirena.org.uk>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
	 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
	 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
	 <527e2b4d-5d2b-4993-a30a-834e77a23a40@sirena.org.uk>
Message-ID: <feeb353566149eb807812ee74ba64d3238183b64.camel@intel.com>

On Tue, 2024-02-20 at 20:14 +0000, Mark Brown wrote:
> > Hmm, could the shadow stack underflow onto the real stack then? Not
> > sure how bad that is. INCSSP (incrementing the SSP register on x86)
> > loops are not rare so it seems like something that could happen.
> 
> Yes, they'd trash any pages of normal stack they touch as they do so
> but
> otherwise seems similar to overflow.

I was thinking in the normal buffer overflow case there is a guard gap
at the end of the stack, but in this case the shadow stack is directly
adjacent to the regular stack. It's probably a minor point.

From broonie at kernel.org  Tue Feb 20 15:44:14 2024
From: broonie at kernel.org (Mark Brown)
Date: Tue, 20 Feb 2024 23:44:14 +0000
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for
 WCN7850
In-Reply-To: <17bbd9ae-0282-430e-947b-e6fb08c53af7@linaro.org>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-15-brgl@bgdev.pl>
 <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk>
 <CAMRc=MeUjKPS3ANE6=7WZ3kbbGAdyE8HeXFN=75Jp-pVyBaWrQ@mail.gmail.com>
 <ea08a286-ff53-4d58-ae41-38cca151508c@sirena.org.uk>
 <17bbd9ae-0282-430e-947b-e6fb08c53af7@linaro.org>
Message-ID: <53f0956f-ee64-4bd6-b44f-cbebafd42e46@sirena.org.uk>

On Tue, Feb 20, 2024 at 10:21:04PM +0100, Konrad Dybcio wrote:
> On 20.02.2024 13:47, Mark Brown wrote:

> > Are you *sure* this actually happens (and that the regulators don't
> > figure it out by themselves), especially given that the consumers are
> > just specifying the load once rather than varying it dynamically at
> > runtime which is supposed to be the use case for this API?  This API is
> > intended to be used dynamically, if the regulator always needs to be in
> > a particular mode just configure that statically.

> *AFAIU*

> The regulators aggregate the requested current (there may be
> multiple consumers) and then it's decided if it's high enough
> to jump into HPM.

Yes, that's the theory - I just question if it actually does something
useful in practice.  Between regulators getting more and more able to
figure out mode switching autonomously based on load monitoring and them
getting more efficient it's become very unclear if this actually
accomplishes anything, the only usage is the Qualcomm stuff and that's
all really unsophisticated and has an air of something that's being
cut'n'pasted forwards rather than delivering practical results.  There
is some value at ultra low loads, but that's more for suspend modes than
for actual use.
-------------- 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/20240220/bc696fb2/attachment.sig>

From vladimir.oltean at nxp.com  Tue Feb 20 15:45:26 2024
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Wed, 21 Feb 2024 01:45:26 +0200
Subject: [PATCH] arm64: ls1046ardb: Replace XGMII with 10GBASE-R phy mode
In-Reply-To: <bce5cff4-c1a5-4d71-b6cd-a89c55a628ba@seco.com>
References: <20240220145037.kf3avnykjif24kkr@skbuf>
 <191b4477-7b4b-47eb-bb3e-0e4d08b3b32e@seco.com>
 <20240220223706.o7wc5r57omkmgtgh@skbuf>
 <e39c811e-ad9d-4e90-8710-629b822944e0@seco.com>
 <20240220230656.cefvrh6avji2elrd@skbuf>
 <bce5cff4-c1a5-4d71-b6cd-a89c55a628ba@seco.com>
Message-ID: <20240220234526.fkifmrt63qjcpz7v@skbuf>

On Tue, Feb 20, 2024 at 06:17:02PM -0500, Sean Anderson wrote:
> On 2/20/24 18:06, Vladimir Oltean wrote:
> > On Tue, Feb 20, 2024 at 05:52:36PM -0500, Sean Anderson wrote:
> >> With SGMII and XFI, the PCS sits on the MAC's MDIO bus. So for SGMII and
> >> XFI if we don't have any labels we can just assume the PCS handle is for
> >> the right PCS. But for QSGMII the PCSs sit on another MAC's MDIO bus. So
> >> we need to tell the MAC where to find the PCS. This means we need to
> >> supply multiple PCSs to the MAC
> >
> > So how did the other Layerscape devices with the same SerDes, PCS and
> > mEMAC manage to get by and support QSGMII without listing all possible
> > PCSes in pcs-handle-names? :-/ DPAA2 has the exact same situation with
> > the QSGMII PCS situated on the internal bus of another DPMAC.
> 
> I'm not familiar with them.

Take the LS1088A-RDB. It has 8 QSGMII ports (dpmac3-dpmac6 over one
lane, dpmac7-dpmac10 over another lane). In fsl-ls1088a-rdb.dts, there
are multiple references like this:

- dpmac3, dpmac4, dpmac5, dpmac6 all have references to a PCS situated
  on dpmac3's MDIO bus.
- dpmac7, dpmac8, dpmac9, dpmac10 all have references to a PCS situated
  on dpmac7's MDIO bus.

No limitation there that I know of. It's not as if the pcs-handle has to
be towards the internal MDIO bus of _that_ dpmac.

> With DPAA we used to just try to configure the QSGMII PCSs on every
> MAC's MDIO bus. This worked out since if you enabled all the MACs, the
> right one would eventually configure the PCSs. But it also meant you
> couldn't determine the link status (since you didn't know where your PCS
> was).

Yeah, the lack of link status reporting from the MAC's PCS is a true
design limitation with the old fman_memac approach. But it's not either-or.
It's not as if things can only be done like that or like you. See above.
Each MAC can talk, through a single pcs-handle, to just its PCS, on
whatever other bus it may be on. What is escaping me is the justification
for _multiple_ pcs-handles.

You accept that you need to have some components of the device tree
defined by the board (phy-mode/phy-connection-type), but based on some
philosophical notion, you maintain that all PCSes should be listed in
the device tree, even if one board could not possibly make use of them
all (and specifically not make use of those PCSes for which it cannot be
hidden from software that they are distinct, see below).

The argument doesn't make sense to me, sorry.

> > It is unnecessary and buggy complexity, and it will only have to become
> > worse when I add support for C73 backplane autoneg in lynx-pcs and the
> > fman_memac driver, because I will need yet another PCS handle, this time
> > not even one that represents a phy-mode in particular, but a PCS handle
> > for C73 (with C73, the autoneg process determines the dynamic phy-mode).
> 
> There are multiple physical PCSs there must also be multiple PCS
> devices. Otherwise your software and hardware will get out of sync.

"Must"? All the single-port-per-lane PCSes and all the multi-port-per-lane
PCSes can be made to appear to software at the same internal MDIO address.
So switching between the SGMII PCS and the 10GBASE-R PCS is never a problem,
even if you don't know they're distinct.

The only thing that's not possible with this simplification, and would
thus justify pcs-handle-names, is switching between a single-port-per-lane
PCS (like SGMII) and a multi-port-per-lane PCS (like QSGMII). But why
would you want that?

> If you don't want the complexity, then don't design hardware with multiple
> PCSs connected to the same MAC.

In case it wasn't clear, I was talking about unjustified software
complexity where there were existing models to follow at the time of
DPAA1's phylink conversion (i.e. DPAA2) which solved the same problems
in a much simpler way. If by making these choices, you've solved design
limitations that are unsolved with DPAA2, please let me know, I really
want to know.


From vladimir.oltean at nxp.com  Tue Feb 20 15:49:30 2024
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Wed, 21 Feb 2024 01:49:30 +0200
Subject: [PATCH] arm64: ls1046ardb: Replace XGMII with 10GBASE-R phy mode
In-Reply-To: <20240220234526.fkifmrt63qjcpz7v@skbuf>
References: <20240220145037.kf3avnykjif24kkr@skbuf>
 <191b4477-7b4b-47eb-bb3e-0e4d08b3b32e@seco.com>
 <20240220223706.o7wc5r57omkmgtgh@skbuf>
 <e39c811e-ad9d-4e90-8710-629b822944e0@seco.com>
 <20240220230656.cefvrh6avji2elrd@skbuf>
 <bce5cff4-c1a5-4d71-b6cd-a89c55a628ba@seco.com>
 <20240220234526.fkifmrt63qjcpz7v@skbuf>
Message-ID: <20240220234930.cl3b7yqk3cl6b6bc@skbuf>

On Wed, Feb 21, 2024 at 01:45:26AM +0200, Vladimir Oltean wrote:
> On Tue, Feb 20, 2024 at 06:17:02PM -0500, Sean Anderson wrote:
> > On 2/20/24 18:06, Vladimir Oltean wrote:
> > > So how did the other Layerscape devices with the same SerDes, PCS and
> > > mEMAC manage to get by and support QSGMII without listing all possible
> > > PCSes in pcs-handle-names? :-/ DPAA2 has the exact same situation with
> > > the QSGMII PCS situated on the internal bus of another DPMAC.
> > 
> > I'm not familiar with them.
> 
> Take the LS1088A-RDB.

Ah, wait a minute, why am I explaining the LS1088A-RDB to you? You've
submitted patches on its SerDes/PCS integration, you even said you
tested the QSGMII ports:
https://lore.kernel.org/linux-arm-kernel/20230321201313.2507539-14-sean.anderson at seco.com/


From dalias at libc.org  Tue Feb 20 15:54:16 2024
From: dalias at libc.org (dalias at libc.org)
Date: Tue, 20 Feb 2024 18:54:16 -0500
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
 <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
Message-ID: <20240220235415.GP4163@brightrain.aerifal.cx>

On Tue, Feb 20, 2024 at 11:30:22PM +0000, Edgecombe, Rick P wrote:
> On Tue, 2024-02-20 at 13:57 -0500, Rich Felker wrote:
> > On Tue, Feb 20, 2024 at 06:41:05PM +0000, Edgecombe, Rick P wrote:
> > > Hmm, could the shadow stack underflow onto the real stack then? Not
> > > sure how bad that is. INCSSP (incrementing the SSP register on x86)
> > > loops are not rare so it seems like something that could happen.
> > 
> > Shadow stack underflow should fault on attempt to access
> > non-shadow-stack memory as shadow-stack, no?
> 
> Maybe I'm misunderstanding. I thought the proposal included allowing
> shadow stack access to convert normal address ranges to shadow stack,
> and normal writes to convert shadow stack to normal.

As I understood the original discussion of the proposal on IRC, it was
only one-way (from shadow to normal). Unless I'm missing something,
making it one-way is necessary to catch situations where the shadow
stack would become compromised.

> > > Shadow stacks currently have automatic guard gaps to try to prevent
> > > one
> > > thread from overflowing onto another thread's shadow stack. This
> > > would
> > > somewhat opens that up, as the stack guard gaps are usually
> > > maintained
> > > by userspace for new threads. It would have to be thought through
> > > if
> > > these could still be enforced with checking at additional spots.
> > 
> > I would think the existing guard pages would already do that if a
> > thread's shadow stack is contiguous with its own data stack.
> 
> The difference is that the kernel provides the guard gaps, where this
> would rely on userspace to do it. It is not a showstopper either.
> 
> I think my biggest question on this is how does it change the
> capability for two threads to share a shadow stack. It might require
> some special rules around the syscall that writes restore tokens. So
> I'm not sure. It probably needs a POC.

Why would they be sharing a shadow stack?

> > From the musl side, I have always looked at the entirely of shadow
> > stack stuff with very heavy skepticism, and anything that breaks
> > existing interface contracts, introduced places where apps can get
> > auto-killed because a late resource allocation fails, or requires
> > applications to code around the existence of something that should be
> > an implementation detail, is a non-starter. To even consider shadow
> > stack support, it must truely be fully non-breaking.
> 
> The manual assembly stack switching and JIT code in the apps needs to
> be updated. I don't think there is a way around it.

Indeed, I'm not talking about programs with JIT/manual stack-switching
asm, just anything using existing APIs for control of stack --
pthread_setstack, makecontext, sigaltstack, etc.

> I agree though that the late allocation failures are not great. Mark is
> working on clone3 support which should allow moving the shadow stack
> allocation to happen in userspace with the normal stack. Even for riscv
> though, doesn't it need to update a new register in stack switching?

If clone is called with signals masked, it's probably not necessary
for the kernel to set the shadow stack register as part of clone3.

> BTW, x86 shadow stack has a mode where the shadow stack is writable
> with a special instruction (WRSS). It enables the SSP to be set
> arbitrarily by writing restore tokens. We discussed this as an option
> to make the existing longjmp() and signal stuff work more transparently
> for glibc.
> 
> > 
> > > > _Without_ doing this, sigaltstack cannot be used to recover from
> > > > stack
> > > > overflows if the shadow stack limit is reached first, and
> > > > makecontext
> > > > cannot be supported without memory leaks and unreportable error
> > > > conditions.
> > > 
> > > FWIW, I think the makecontext() shadow stack leaking is a bad idea.
> > > I
> > > would prefer the existing makecontext() interface just didn't
> > > support
> > > shadow stack, rather than the leaking solution glibc does today.
> > 
> > AIUI the proposal by Stefan makes it non-leaking because it's just
> > using normal memory that reverts to normal usage on any
> > non-shadow-stack access.
> > 
> 
> Right, but does it break any existing apps anyway (because of small
> ucontext stack sizes)?
> 
> BTW, when I talk about "not supporting" I don't mean the app should
> crash. I mean it should instead run normally, just without shadow stack
> enabled. Not sure if that was clear. Since shadow stack is not
> essential for an application to function, it is only security hardening
> on top.
> 
> Although determining if an application supports shadow stack has turned
> out to be difficult in practice. Handling dlopen() is especially hard.

One reasonable thing to do, that might be preferable to overengineered
solutions, is to disable shadow-stack process-wide if an interface
incompatible with it is used (sigaltstack, pthread_create with an
attribute setup using pthread_attr_setstack, makecontext, etc.), as
well as if an incompatible library is is dlopened. This is much more
acceptable than continuing to run with shadow stacks managed sloppily
by the kernel and async killing the process on OOM, and is probably
*more compatible* with apps than changing the minimum stack size
requirements out from under them.

The place where it's really needed to be able to allocate the shadow
stack synchronously under userspace control, in order to harden normal
applications that aren't doing funny things, is in pthread_create
without a caller-provided stack.

Rich


From megi at xff.cz  Tue Feb 20 15:56:34 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Wed, 21 Feb 2024 00:56:34 +0100
Subject: [PATCH] media: rkisp1: Allow higher input resolution
In-Reply-To: <ZdMpSLqYVFbU7sF0@pyrite.rasen.tech>
References: <20240217185202.1754750-1-megi@xff.cz>
 <20240218205908.GA12766@pendragon.ideasonboard.com>
 <pftafukuzq7qzbhlvwtmeg3mburnttylgy4246timlghtrdgx4@r6munvmj6oqt>
 <CAHCN7x+zi3WxnY-mxZFKePs1cS=-DprEmh_CnypJ4XK7xBzjMQ@mail.gmail.com>
 <b500676e-431f-40fc-868b-9f9bb359a109@ideasonboard.com>
 <ZdMpSLqYVFbU7sF0@pyrite.rasen.tech>
Message-ID: <amx55bzbmbuvuroulrsv5dxdlmsm7f32srut2e7ivpybl2lzze@ehonmk7wlowt>

On Mon, Feb 19, 2024 at 07:11:20PM +0900, Paul Elder wrote:
> On Mon, Feb 19, 2024 at 02:33:21PM +0530, Umang Jain wrote:
> > Hi All,
> > 
> > On 19/02/24 7:39 am, Adam Ford wrote:
> > > On Sun, Feb 18, 2024 at 3:02?PM Ond?ej Jirman <megi at xff.cz> wrote:
> > > > On Sun, Feb 18, 2024 at 10:59:08PM +0200, Laurent Pinchart wrote:
> > > > > Hi Ondrej,
> > > > > 
> > > > > (CC'ing Paul and Umang)
> > > > > 
> > > > > Thank you for the patch.
> > > > > 
> > > > > On Sat, Feb 17, 2024 at 07:51:58PM +0100, Ond?ej Jirman wrote:
> > > > > > From: Ondrej Jirman <megi at xff.cz>
> > > > > > 
> > > > > > In BSP driver, it is allowed, and it works in practice. Tested on
> > > > > > Pinephone Pro/RK3399 with IMX258 at full res.
> > > > > Paul, Umang, do I recall correctly that you have a similar change ?
> > > > > Could you review and test this (especially on the i.MX8MP) ?
> > > > It's also a limit from the datasheet, so the change should not be that
> > > > controversial:
> > > > 
> > > >    https://megous.com/dl/tmp/d2b333043ecebaf3.png
> > > > 
> > > > (so that it doesn't sound like I just copied the BSP values)
> > > > 
> > >  From what I see in the i.MX8M Plus reference manual, it has a max
> > > resolution of 4096x3072, so it might be necessary to move this off
> > 
> > This is what I (and I assume Paul too) have been working with on i.MX8M
> > Plus. So it's the known and tested value of max ISP input from out side.
> > > from a #define into a structure that varies by product family.
> 
> Yes, this is what needs to be done. Here's what I have in my notes:
> 
> - The RK3399 TRM says 4416x3312 max input and output on main path, with
>   1920x1080 max output on self path.
> - The PX30 datasheet [1] says 3264x2448 max input and output on main
>   path, with 1920x1080 max output on self path.
> - The RK3288 documentation [2] (under "Camera Interface and Image
>   Processor") says 4416x3312 max input and output on main path, with
>   1920x1080 max output on self path.
> - The i.MX8MP reference manual (the open one) [3] (in table 13-1) says
>   4096x3072 max resolution in single ISP mode

Yeah, RKISP1_RSZ_SP_SRC_MAX_HEIGHT in the driver also seems weird in
this respect:

  #define RKISP1_RSZ_SP_SRC_MAX_WIDTH             1920
  #define RKISP1_RSZ_SP_SRC_MAX_HEIGHT            1920

regards,
	o.

> The i.MX8M Plus seems to indeed be limited to 4096x3072, but the TPG is
> capable of generating 4416x3312, and the ISP works fine in bypass (and
> therefore raw) mode, so technically it has different maximum sizes
> depending on the format which makes this more exciting.
> 
> In any case, the PX30 (assuming the datasheet is correct) only supports
> up to 3264x2448, so the existing #define is incorrect anyway.
> 
> I don't have a PX30 nor an RK3288 so I can't test those, and I haven't
> set up my OV64A40 yet which (I've heard) can be used to test even bigger
> resolutions.
> 
> 
> Paul
> 
> [1] https://opensource.rock-chips.com/images/8/87/Rockchip_PX30_Datasheet_V1.4-20191227.pdf
> [2] https://opensource.rock-chips.com/images/4/49/Rockchip_RK3288_Datasheet_V2.7-20191227.pdf
> [3] (requires login) https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/i-mx-applications-processors/i-mx-8-applications-processors/i-mx-8m-plus-arm-cortex-a53-machine-learning-vision-multimedia-and-industrial-iot:IMX8MPLUS
> 
> 
> > 
> > Yeah!
> > > 
> > > adam
> > > > regards,
> > > >          o.
> > > > 
> > > > > > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > > > > > ---
> > > > > >   drivers/media/platform/rockchip/rkisp1/rkisp1-common.h | 4 ++--
> > > > > >   1 file changed, 2 insertions(+), 2 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > > index 4b6b28c05b89..74098ddbeeb3 100644
> > > > > > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > > @@ -33,8 +33,8 @@ struct dentry;
> > > > > >   #define RKISP1_ISP_SD_SINK                 BIT(1)
> > > > > > 
> > > > > >   /* min and max values for the widths and heights of the entities */
> > > > > > -#define RKISP1_ISP_MAX_WIDTH                       4032
> > > > > > -#define RKISP1_ISP_MAX_HEIGHT                      3024
> > > > > > +#define RKISP1_ISP_MAX_WIDTH                       4416
> > > > > > +#define RKISP1_ISP_MAX_HEIGHT                      3312
> > > > > >   #define RKISP1_ISP_MIN_WIDTH                       32
> > > > > >   #define RKISP1_ISP_MIN_HEIGHT                      32
> > > > > > 
> > > > > --
> > > > > Regards,
> > > > > 
> > > > > Laurent Pinchart
> > 


From megi at xff.cz  Tue Feb 20 15:57:17 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Wed, 21 Feb 2024 00:57:17 +0100
Subject: [PATCH] media: rkisp1: Adapt to different SoCs having different size limits
Message-ID: <20240220235720.3010608-1-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

- RK3399 has input/output limit of main path 4416 x 3312
- PX30 has input/output limit of main path 3264 x 2448

Use rkisp1_info struct to encode the limits.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 drivers/media/platform/rockchip/rkisp1/rkisp1-common.h  | 6 ++++--
 drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c     | 5 +++--
 drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c     | 4 ++++
 drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c     | 9 +++++----
 drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c | 4 ++--
 5 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index b757f75edecf..423e7932e7fd 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -33,8 +33,6 @@ struct dentry;
 #define RKISP1_ISP_SD_SINK			BIT(1)
 
 /* min and max values for the widths and heights of the entities */
-#define RKISP1_ISP_MAX_WIDTH			4032
-#define RKISP1_ISP_MAX_HEIGHT			3024
 #define RKISP1_ISP_MIN_WIDTH			32
 #define RKISP1_ISP_MIN_HEIGHT			32
 
@@ -128,6 +126,8 @@ enum rkisp1_feature {
  * @isr_size: number of entries in the @isrs array
  * @isp_ver: ISP version
  * @features: bitmask of rkisp1_feature features implemented by the ISP
+ * @max_width: maximum input frame width
+ * @max_height: maximum input frame height
  *
  * This structure contains information about the ISP specific to a particular
  * ISP model, version, or integration in a particular SoC.
@@ -139,6 +139,8 @@ struct rkisp1_info {
 	unsigned int isr_size;
 	enum rkisp1_cif_isp_version isp_ver;
 	unsigned int features;
+	unsigned int max_width;
+	unsigned int max_height;
 };
 
 /*
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c
index 4202642e0523..841e58c20f7f 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c
@@ -307,6 +307,7 @@ static int rkisp1_csi_set_fmt(struct v4l2_subdev *sd,
 			      struct v4l2_subdev_state *sd_state,
 			      struct v4l2_subdev_format *fmt)
 {
+	struct rkisp1_csi *csi = to_rkisp1_csi(sd);
 	const struct rkisp1_mbus_info *mbus_info;
 	struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
 
@@ -326,10 +327,10 @@ static int rkisp1_csi_set_fmt(struct v4l2_subdev *sd,
 
 	sink_fmt->width = clamp_t(u32, fmt->format.width,
 				  RKISP1_ISP_MIN_WIDTH,
-				  RKISP1_ISP_MAX_WIDTH);
+				  csi->rkisp1->info->max_width);
 	sink_fmt->height = clamp_t(u32, fmt->format.height,
 				   RKISP1_ISP_MIN_HEIGHT,
-				   RKISP1_ISP_MAX_HEIGHT);
+				   csi->rkisp1->info->max_height);
 
 	fmt->format = *sink_fmt;
 
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index 73cf08a74011..93296dbacfef 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -506,6 +506,8 @@ static const struct rkisp1_info px30_isp_info = {
 	.isr_size = ARRAY_SIZE(px30_isp_isrs),
 	.isp_ver = RKISP1_V12,
 	.features = RKISP1_FEATURE_MIPI_CSI2,
+	.max_width = 3264,
+	.max_height = 2448,
 };
 
 static const char * const rk3399_isp_clks[] = {
@@ -525,6 +527,8 @@ static const struct rkisp1_info rk3399_isp_info = {
 	.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
 	.isp_ver = RKISP1_V10,
 	.features = RKISP1_FEATURE_MIPI_CSI2,
+	.max_width = 4416,
+	.max_height = 3312,
 };
 
 static const struct of_device_id rkisp1_of_match[] = {
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
index 78a1f7a1499b..5e0a63d353e3 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
@@ -394,6 +394,7 @@ static int rkisp1_isp_enum_frame_size(struct v4l2_subdev *sd,
 				      struct v4l2_subdev_state *sd_state,
 				      struct v4l2_subdev_frame_size_enum *fse)
 {
+	struct rkisp1_isp *isp = to_rkisp1_isp(sd);
 	const struct rkisp1_mbus_info *mbus_info;
 
 	if (fse->pad == RKISP1_ISP_PAD_SINK_PARAMS ||
@@ -416,9 +417,9 @@ static int rkisp1_isp_enum_frame_size(struct v4l2_subdev *sd,
 		return -EINVAL;
 
 	fse->min_width = RKISP1_ISP_MIN_WIDTH;
-	fse->max_width = RKISP1_ISP_MAX_WIDTH;
+	fse->max_width = isp->rkisp1->info->max_width;
 	fse->min_height = RKISP1_ISP_MIN_HEIGHT;
-	fse->max_height = RKISP1_ISP_MAX_HEIGHT;
+	fse->max_height = isp->rkisp1->info->max_height;
 
 	return 0;
 }
@@ -649,10 +650,10 @@ static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp,
 
 	sink_fmt->width = clamp_t(u32, format->width,
 				  RKISP1_ISP_MIN_WIDTH,
-				  RKISP1_ISP_MAX_WIDTH);
+				  isp->rkisp1->info->max_width);
 	sink_fmt->height = clamp_t(u32, format->height,
 				   RKISP1_ISP_MIN_HEIGHT,
-				   RKISP1_ISP_MAX_HEIGHT);
+				   isp->rkisp1->info->max_height);
 
 	/*
 	 * Adjust the color space fields. Accept any color primaries and
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
index a8e377701302..34938fe8e812 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
@@ -493,10 +493,10 @@ static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
 
 	sink_fmt->width = clamp_t(u32, format->width,
 				  RKISP1_ISP_MIN_WIDTH,
-				  RKISP1_ISP_MAX_WIDTH);
+				  rsz->rkisp1->info->max_width);
 	sink_fmt->height = clamp_t(u32, format->height,
 				   RKISP1_ISP_MIN_HEIGHT,
-				   RKISP1_ISP_MAX_HEIGHT);
+				   rsz->rkisp1->info->max_height);
 
 	/*
 	 * Adjust the color space fields. Accept any color primaries and
-- 
2.43.0



From megi at xff.cz  Tue Feb 20 15:59:28 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Wed, 21 Feb 2024 00:59:28 +0100
Subject: [PATCH] media: rkisp1: Allow higher input resolution
In-Reply-To: <20240219115430.GC13043@pendragon.ideasonboard.com>
References: <20240217185202.1754750-1-megi@xff.cz>
 <20240218205908.GA12766@pendragon.ideasonboard.com>
 <pftafukuzq7qzbhlvwtmeg3mburnttylgy4246timlghtrdgx4@r6munvmj6oqt>
 <CAHCN7x+zi3WxnY-mxZFKePs1cS=-DprEmh_CnypJ4XK7xBzjMQ@mail.gmail.com>
 <b500676e-431f-40fc-868b-9f9bb359a109@ideasonboard.com>
 <ZdMpSLqYVFbU7sF0@pyrite.rasen.tech>
 <20240219115430.GC13043@pendragon.ideasonboard.com>
Message-ID: <va4xwavrvjkm7mydvu4jaikzthn3qjcox7ciudx334hdmp6op2@uoldcj4vyv2g>

Hello Laurent,

On Mon, Feb 19, 2024 at 01:54:30PM +0200, Laurent Pinchart wrote:
> On Mon, Feb 19, 2024 at 07:11:20PM +0900, Paul Elder wrote:
> > On Mon, Feb 19, 2024 at 02:33:21PM +0530, Umang Jain wrote:
> > > On 19/02/24 7:39 am, Adam Ford wrote:
> > > > On Sun, Feb 18, 2024 at 3:02?PM Ond?ej Jirman <megi at xff.cz> wrote:
> > > > > On Sun, Feb 18, 2024 at 10:59:08PM +0200, Laurent Pinchart wrote:
> > > > > > On Sat, Feb 17, 2024 at 07:51:58PM +0100, Ond?ej Jirman wrote:
> > > > > > > From: Ondrej Jirman <megi at xff.cz>
> > > > > > > 
> > > > > > > In BSP driver, it is allowed, and it works in practice. Tested on
> > > > > > > Pinephone Pro/RK3399 with IMX258 at full res.
> > > > > >
> > > > > > Paul, Umang, do I recall correctly that you have a similar change ?
> > > > > > Could you review and test this (especially on the i.MX8MP) ?
> > > > >
> > > > > It's also a limit from the datasheet, so the change should not be that
> > > > > controversial:
> > > > > 
> > > > >    https://megous.com/dl/tmp/d2b333043ecebaf3.png
> > > > > 
> > > > > (so that it doesn't sound like I just copied the BSP values)
> > > > > 
> > > >  From what I see in the i.MX8M Plus reference manual, it has a max
> > > > resolution of 4096x3072, so it might be necessary to move this off
> > > 
> > > This is what I (and I assume Paul too) have been working with on i.MX8M
> > > Plus. So it's the known and tested value of max ISP input from out side.
> > >
> > > > from a #define into a structure that varies by product family.
> > 
> > Yes, this is what needs to be done. Here's what I have in my notes:
> > 
> > - The RK3399 TRM says 4416x3312 max input and output on main path, with
> >   1920x1080 max output on self path.
> > - The PX30 datasheet [1] says 3264x2448 max input and output on main
> >   path, with 1920x1080 max output on self path.
> > - The RK3288 documentation [2] (under "Camera Interface and Image
> >   Processor") says 4416x3312 max input and output on main path, with
> >   1920x1080 max output on self path.
> > - The i.MX8MP reference manual (the open one) [3] (in table 13-1) says
> >   4096x3072 max resolution in single ISP mode
> > 
> > The i.MX8M Plus seems to indeed be limited to 4096x3072, but the TPG is
> > capable of generating 4416x3312, and the ISP works fine in bypass (and
> > therefore raw) mode, so technically it has different maximum sizes
> > depending on the format which makes this more exciting.
> > 
> > In any case, the PX30 (assuming the datasheet is correct) only supports
> > up to 3264x2448, so the existing #define is incorrect anyway.
> > 
> > I don't have a PX30 nor an RK3288 so I can't test those, and I haven't
> > set up my OV64A40 yet which (I've heard) can be used to test even bigger
> > resolutions.
> 
> Thanks for the summary Paul.
> 
> Ond?ej, would you be interested in implementing this ?

Something like this?

https://lore.kernel.org/lkml/20240220235720.3010608-1-megi at xff.cz/T/#u

Only the first two SoCs are supported by rkisp1 driver upstream, yet. So I
only have to deal with input and mainpath maximum ATM. So the patch is rather
simple.

kind regards,
	o.

> > [1] https://opensource.rock-chips.com/images/8/87/Rockchip_PX30_Datasheet_V1.4-20191227.pdf
> > [2] https://opensource.rock-chips.com/images/4/49/Rockchip_RK3288_Datasheet_V2.7-20191227.pdf
> > [3] (requires login) https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/i-mx-applications-processors/i-mx-8-applications-processors/i-mx-8m-plus-arm-cortex-a53-machine-learning-vision-multimedia-and-industrial-iot:IMX8MPLUS
> > 
> > > > > > > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > > > > > > ---
> > > > > > >   drivers/media/platform/rockchip/rkisp1/rkisp1-common.h | 4 ++--
> > > > > > >   1 file changed, 2 insertions(+), 2 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > > > index 4b6b28c05b89..74098ddbeeb3 100644
> > > > > > > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > > > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
> > > > > > > @@ -33,8 +33,8 @@ struct dentry;
> > > > > > >   #define RKISP1_ISP_SD_SINK                 BIT(1)
> > > > > > > 
> > > > > > >   /* min and max values for the widths and heights of the entities */
> > > > > > > -#define RKISP1_ISP_MAX_WIDTH                       4032
> > > > > > > -#define RKISP1_ISP_MAX_HEIGHT                      3024
> > > > > > > +#define RKISP1_ISP_MAX_WIDTH                       4416
> > > > > > > +#define RKISP1_ISP_MAX_HEIGHT                      3312
> > > > > > >   #define RKISP1_ISP_MIN_WIDTH                       32
> > > > > > >   #define RKISP1_ISP_MIN_HEIGHT                      32
> > > > > > > 
> 
> -- 
> Regards,
> 
> Laurent Pinchart


From sorear at fastmail.com  Tue Feb 20 15:59:58 2024
From: sorear at fastmail.com (Stefan O'Rear)
Date: Tue, 20 Feb 2024 18:59:58 -0500
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in
 userspace
In-Reply-To: <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
 <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
Message-ID: <063acc75-ea1d-4dd3-aecb-e5c8884005db@app.fastmail.com>

On Tue, Feb 20, 2024, at 6:30 PM, Edgecombe, Rick P wrote:
> On Tue, 2024-02-20 at 13:57 -0500, Rich Felker wrote:
>> On Tue, Feb 20, 2024 at 06:41:05PM +0000, Edgecombe, Rick P wrote:
>> > Hmm, could the shadow stack underflow onto the real stack then? Not
>> > sure how bad that is. INCSSP (incrementing the SSP register on x86)
>> > loops are not rare so it seems like something that could happen.
>> 
>> Shadow stack underflow should fault on attempt to access
>> non-shadow-stack memory as shadow-stack, no?
>
> Maybe I'm misunderstanding. I thought the proposal included allowing
> shadow stack access to convert normal address ranges to shadow stack,
> and normal writes to convert shadow stack to normal.

Ideally for riscv only writes would cause conversion, an incssp underflow
which performs shadow stack reads would be able to fault early.

For arm, since a syscall is needed anyway to set up the token in a new
shadow stack region, it would make sense for conversion from non-shadow
to shadow usage to never be automatic.

>> > 
>> > Won't this prevent catching stack overflows when they happen? An
>> > overflow will just turn the shadow stack into normal stack and only
>> > get
>> > detected when the shadow stack unwinds?
>> 
>> I don't think that's as big a problem as it sounds like. It might
>> make
>> pinpointing the spot at which things went wrong take a little bit
>> more
>> work, but it should not admit any wrong-execution.
>
> Right, it's a point about debugging. I'm just trying to analyze the
> pros and cons and not calling it a showstopper.

It's certainly undesirable, so I'd like to have both mechanisms available
(shadow stacks in ordinary memory to support several problematic APIs,
and in dedicated mappings with guard pages otherwise).

>> > 
>> > Shadow stacks currently have automatic guard gaps to try to prevent
>> > one
>> > thread from overflowing onto another thread's shadow stack. This
>> > would
>> > somewhat opens that up, as the stack guard gaps are usually
>> > maintained
>> > by userspace for new threads. It would have to be thought through
>> > if
>> > these could still be enforced with checking at additional spots.
>> 
>> I would think the existing guard pages would already do that if a
>> thread's shadow stack is contiguous with its own data stack.
>
> The difference is that the kernel provides the guard gaps, where this
> would rely on userspace to do it. It is not a showstopper either.
>
> I think my biggest question on this is how does it change the
> capability for two threads to share a shadow stack. It might require
> some special rules around the syscall that writes restore tokens. So
> I'm not sure. It probably needs a POC.

I'm not quite understanding what the property you're looking for here is.

>> From the musl side, I have always looked at the entirely of shadow
>> stack stuff with very heavy skepticism, and anything that breaks
>> existing interface contracts, introduced places where apps can get
>> auto-killed because a late resource allocation fails, or requires
>> applications to code around the existence of something that should be
>> an implementation detail, is a non-starter. To even consider shadow
>> stack support, it must truely be fully non-breaking.
>
> The manual assembly stack switching and JIT code in the apps needs to
> be updated. I don't think there is a way around it.

Naturally.  If an application uses nonportable functionality like JIT
and inline assembly, it's fine (within reason) for those nonportable
components to need changes for shadow stack support.

The objective of this proposal is to allow applications that do _not_
use inline assembly but rather only C APIs defined in POSIX.1-2004 to
execute correctly in an environment where shadow stacks are enabled
by default.

> I agree though that the late allocation failures are not great. Mark is
> working on clone3 support which should allow moving the shadow stack
> allocation to happen in userspace with the normal stack. Even for riscv
> though, doesn't it need to update a new register in stack switching?
>
> BTW, x86 shadow stack has a mode where the shadow stack is writable
> with a special instruction (WRSS). It enables the SSP to be set
> arbitrarily by writing restore tokens. We discussed this as an option
> to make the existing longjmp() and signal stuff work more transparently
> for glibc.
>
>> 
>> > > _Without_ doing this, sigaltstack cannot be used to recover from
>> > > stack
>> > > overflows if the shadow stack limit is reached first, and
>> > > makecontext
>> > > cannot be supported without memory leaks and unreportable error
>> > > conditions.
>> > 
>> > FWIW, I think the makecontext() shadow stack leaking is a bad idea.
>> > I
>> > would prefer the existing makecontext() interface just didn't
>> > support
>> > shadow stack, rather than the leaking solution glibc does today.
>> 
>> AIUI the proposal by Stefan makes it non-leaking because it's just
>> using normal memory that reverts to normal usage on any
>> non-shadow-stack access.
>> 
>
> Right, but does it break any existing apps anyway (because of small
> ucontext stack sizes)?

Possibly, but that's what SIGSTKSZ/MINSIGSTKSZ is for.  This is already
variable on several platforms due to variable-length vector extensions.

> BTW, when I talk about "not supporting" I don't mean the app should
> crash. I mean it should instead run normally, just without shadow stack
> enabled. Not sure if that was clear. Since shadow stack is not
> essential for an application to function, it is only security hardening
> on top.

I appreciate that.  How far can we go in that direction?  If we can
automatically disable shadow stacks on any call to makecontext, sigaltstack,
or pthread_attr_setstack without causing other threads to crash if they were
in the middle of shadow stack maintenance we can probably simplify this
proposal, although I need to think more about what's possible.

> Although determining if an application supports shadow stack has turned
> out to be difficult in practice. Handling dlopen() is especially hard.

How so?  Is the hard part figuring out if you need to do something, or
doing it?

-s


From lorenzo at kernel.org  Tue Feb 20 16:04:26 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 21 Feb 2024 01:04:26 +0100
Subject: [PATCH v2 0/4] arm64: Add support for Airoha EN7581 Soc
Message-ID: <cover.1708473083.git.lorenzo@kernel.org>

Introduce basic support for Airoha EN7581 Soc and EN7581 Evaluation Board.

Changes since v1:
- add missing en7581 entry in airoha binding
- fix checkpatch errors

Daniel Danzberger (3):
  arm64: dts: Add Airoha EN7581 SoC and EN7581 Evaluation Board
  arm64: add Airoha EN7581 platform
  arm64: defconfig: enable Airoha platform

Lorenzo Bianconi (1):
  dt-bindings: arm64: dts: airoha: Add en7581 series

 .../devicetree/bindings/arm/airoha.yaml       |   4 +
 arch/arm64/Kconfig.platforms                  |  13 ++
 arch/arm64/boot/dts/Makefile                  |   1 +
 arch/arm64/boot/dts/airoha/Makefile           |   2 +
 arch/arm64/boot/dts/airoha/en7581-evb.dts     |  27 ++++
 arch/arm64/boot/dts/airoha/en7581.dtsi        | 137 ++++++++++++++++++
 arch/arm64/configs/defconfig                  |   1 +
 7 files changed, 185 insertions(+)
 create mode 100644 arch/arm64/boot/dts/airoha/Makefile
 create mode 100644 arch/arm64/boot/dts/airoha/en7581-evb.dts
 create mode 100644 arch/arm64/boot/dts/airoha/en7581.dtsi

-- 
2.43.2



From lorenzo at kernel.org  Tue Feb 20 16:04:27 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 21 Feb 2024 01:04:27 +0100
Subject: [PATCH v2 1/4] dt-bindings: arm64: dts: airoha: Add en7581 series
In-Reply-To: <cover.1708473083.git.lorenzo@kernel.org>
References: <cover.1708473083.git.lorenzo@kernel.org>
Message-ID: <8589d9ca1469e73227af596852a9adf673ac50ad.1708473083.git.lorenzo@kernel.org>

Introduce Airoha EN7581 entry in Airoha dts binding.

Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 Documentation/devicetree/bindings/arm/airoha.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/airoha.yaml b/Documentation/devicetree/bindings/arm/airoha.yaml
index 3292c669ee11..7c38c08dbf3f 100644
--- a/Documentation/devicetree/bindings/arm/airoha.yaml
+++ b/Documentation/devicetree/bindings/arm/airoha.yaml
@@ -22,6 +22,10 @@ properties:
           - enum:
               - airoha,en7523-evb
           - const: airoha,en7523
+      - items:
+          - enum:
+              - airoha,en7581-evb
+          - const: airoha,en7581
 
 additionalProperties: true
 
-- 
2.43.2



From lorenzo at kernel.org  Tue Feb 20 16:04:28 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 21 Feb 2024 01:04:28 +0100
Subject: [PATCH v2 2/4] arm64: dts: Add Airoha EN7581 SoC and EN7581 Evaluation Board
In-Reply-To: <cover.1708473083.git.lorenzo@kernel.org>
References: <cover.1708473083.git.lorenzo@kernel.org>
Message-ID: <f59389838c741650f6ff05d984a9127545e4eb83.1708473083.git.lorenzo@kernel.org>

From: Daniel Danzberger <dd at embedd.com>

Introduce the Airoha EN7581 SoC's dtsi and the Airoha EN7581 Evaluation
Board's dts file, as well as the required Makefiles.

Signed-off-by: Daniel Danzberger <dd at embedd.com>
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 arch/arm64/boot/dts/Makefile              |   1 +
 arch/arm64/boot/dts/airoha/Makefile       |   2 +
 arch/arm64/boot/dts/airoha/en7581-evb.dts |  27 +++++
 arch/arm64/boot/dts/airoha/en7581.dtsi    | 137 ++++++++++++++++++++++
 4 files changed, 167 insertions(+)
 create mode 100644 arch/arm64/boot/dts/airoha/Makefile
 create mode 100644 arch/arm64/boot/dts/airoha/en7581-evb.dts
 create mode 100644 arch/arm64/boot/dts/airoha/en7581.dtsi

diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 30dd6347a929..21cd3a87f385 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 subdir-y += actions
+subdir-y += airoha
 subdir-y += allwinner
 subdir-y += altera
 subdir-y += amazon
diff --git a/arch/arm64/boot/dts/airoha/Makefile b/arch/arm64/boot/dts/airoha/Makefile
new file mode 100644
index 000000000000..ebea112ce1d7
--- /dev/null
+++ b/arch/arm64/boot/dts/airoha/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+dtb-$(CONFIG_ARCH_AIROHA) += en7581-evb.dtb
diff --git a/arch/arm64/boot/dts/airoha/en7581-evb.dts b/arch/arm64/boot/dts/airoha/en7581-evb.dts
new file mode 100644
index 000000000000..4eaa8ac431c3
--- /dev/null
+++ b/arch/arm64/boot/dts/airoha/en7581-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 "en7581.dtsi"
+
+/ {
+	model = "Airoha EN7581 Evaluation Board";
+	compatible = "airoha,en7581-evb", "airoha,en7581";
+
+	aliases {
+		serial0 = &uart1;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200 earlycon";
+		stdout-path = "serial0:115200n8";
+		linux,usable-memory-range = <0x0 0x80200000 0x0 0x1fe00000>;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x2 0x00000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/airoha/en7581.dtsi b/arch/arm64/boot/dts/airoha/en7581.dtsi
new file mode 100644
index 000000000000..7a3c0a45c03f
--- /dev/null
+++ b/arch/arm64/boot/dts/airoha/en7581.dtsi
@@ -0,0 +1,137 @@
+// 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 = <2>;
+	#size-cells = <2>;
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		npu_binary at 84000000 {
+			no-map;
+			reg = <0x0 0x84000000 0x0 0xA00000>;
+		};
+
+		npu_flag at 84B0000 {
+			no-map;
+			reg = <0x0 0x84B00000 0x0 0x100000>;
+		};
+
+		npu_pkt at 85000000 {
+			no-map;
+			reg = <0x0 0x85000000 0x0 0x1A00000>;
+		};
+
+		npu_phyaddr at 86B00000 {
+			no-map;
+			reg = <0x0 0x86B00000 0x0 0x100000>;
+		};
+
+		npu_rxdesc at 86D00000 {
+			no-map;
+			reg = <0x0 0x86D00000 0x0 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>;
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x2>;
+			enable-method = "psci";
+			clock-frequency = <80000000>;
+			next-level-cache = <&L2_0>;
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x3>;
+			enable-method = "psci";
+			clock-frequency = <80000000>;
+			next-level-cache = <&L2_0>;
+		};
+
+		L2_0: l2-cache0 {
+			compatible = "cache";
+			cache-level = <2>;
+			cache-unified;
+		};
+	};
+
+	gic: interrupt-controller at 9000000 {
+		compatible = "arm,gic-v3";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x0 0x09000000 0x0 0x20000>,
+		      <0x0 0x09080000 0x0 0x80000>,
+		      <0x0 0x09400000 0x0 0x2000>,
+		      <0x0 0x09500000 0x0 0x2000>,
+		      <0x0 0x09600000 0x0 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 = <0x0 0x1fbf0000 0x0 0x30>;
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+		clock-frequency = <1843200>;
+		status = "okay";
+	};
+};
-- 
2.43.2



From lorenzo at kernel.org  Tue Feb 20 16:04:29 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 21 Feb 2024 01:04:29 +0100
Subject: [PATCH v2 3/4] arm64: add Airoha EN7581 platform
In-Reply-To: <cover.1708473083.git.lorenzo@kernel.org>
References: <cover.1708473083.git.lorenzo@kernel.org>
Message-ID: <f5c987798bae710aea9ce1ece9c1a1cbd7bd3da9.1708473083.git.lorenzo@kernel.org>

From: Daniel Danzberger <dd at embedd.com>

Introduce the Kconfig entry for the Airoha EN7581 multicore architecture
available in the Airoha EN7581 evaluation board.

Signed-off-by: Daniel Danzberger <dd at embedd.com>
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 arch/arm64/Kconfig.platforms | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 24335565bad5..bbe61e233034 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -8,6 +8,19 @@ config ARCH_ACTIONS
 	help
 	  This enables support for the Actions Semiconductor S900 SoC family.
 
+config ARCH_AIROHA
+	bool "Airoha SoC Support"
+	select ARM_AMBA
+	select ARM_GIC
+	select ARM_GIC_V3
+	select ARM_PSCI
+	select HAVE_ARM_ARCH_TIMER
+	select COMMON_CLK
+	help
+	  This enables support for Airoha EN7581 multicore architecture
+	  available on the following SoCs:
+	   - Airoha EN7581 Evaluation Board
+
 config ARCH_SUNXI
 	bool "Allwinner sunxi 64-bit SoC Family"
 	select ARCH_HAS_RESET_CONTROLLER
-- 
2.43.2



From lorenzo at kernel.org  Tue Feb 20 16:04:30 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 21 Feb 2024 01:04:30 +0100
Subject: [PATCH v2 4/4] arm64: defconfig: enable Airoha platform
In-Reply-To: <cover.1708473083.git.lorenzo@kernel.org>
References: <cover.1708473083.git.lorenzo@kernel.org>
Message-ID: <baf5af70e4c42042528914179b701f3dafcc972b.1708473083.git.lorenzo@kernel.org>

From: Daniel Danzberger <dd at embedd.com>

Enables the ARCH_AIROHA config by default.

Signed-off-by: Daniel Danzberger <dd at embedd.com>
Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e6cf3e5d63c3..3966dbb79bb8 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -50,6 +50,7 @@ CONFIG_ARCH_LG1K=y
 CONFIG_ARCH_HISI=y
 CONFIG_ARCH_KEEMBAY=y
 CONFIG_ARCH_MEDIATEK=y
+CONFIG_ARCH_AIROHA=y
 CONFIG_ARCH_MESON=y
 CONFIG_ARCH_MVEBU=y
 CONFIG_ARCH_NXP=y
-- 
2.43.2



From rick.p.edgecombe at intel.com  Tue Feb 20 16:35:48 2024
From: rick.p.edgecombe at intel.com (Edgecombe, Rick P)
Date: Wed, 21 Feb 2024 00:35:48 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in
 userspace
In-Reply-To: <20240220235415.GP4163@brightrain.aerifal.cx>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
	 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
	 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
	 <20240220185714.GO4163@brightrain.aerifal.cx>
	 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
	 <20240220235415.GP4163@brightrain.aerifal.cx>
Message-ID: <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>

On Tue, 2024-02-20 at 18:54 -0500, dalias at libc.org wrote:
> On Tue, Feb 20, 2024 at 11:30:22PM +0000, Edgecombe, Rick P wrote:
> > On Tue, 2024-02-20 at 13:57 -0500, Rich Felker wrote:
> > > On Tue, Feb 20, 2024 at 06:41:05PM +0000, Edgecombe, Rick P
> > > wrote:
> > > > Hmm, could the shadow stack underflow onto the real stack then?
> > > > Not
> > > > sure how bad that is. INCSSP (incrementing the SSP register on
> > > > x86)
> > > > loops are not rare so it seems like something that could
> > > > happen.
> > > 
> > > Shadow stack underflow should fault on attempt to access
> > > non-shadow-stack memory as shadow-stack, no?
> > 
> > Maybe I'm misunderstanding. I thought the proposal included
> > allowing
> > shadow stack access to convert normal address ranges to shadow
> > stack,
> > and normal writes to convert shadow stack to normal.
> 
> As I understood the original discussion of the proposal on IRC, it
> was
> only one-way (from shadow to normal). Unless I'm missing something,
> making it one-way is necessary to catch situations where the shadow
> stack would become compromised.

The original post here:
https://lore.kernel.org/lkml/22a53b78-10d7-4a5a-a01e-b2f3a8c22e94 at app.fastmail.com/

...has:
"Shadow stack faults on non-shadow stack pages, if flexible shadow
stack handling is in effect, cause the affected page to become a shadow
stack page.  When this happens, the page filled with invalid address
tokens."

...and:
"Faults from non-shadow-stack accesses to a shadow-stack page which was
created by the previous paragraph will cause the page to revert to non-
shadow-stack usage, with or without clearing."

I see Stefan has clarified in another response. So I'll go try to
figure it out.

> 
> > > > Shadow stacks currently have automatic guard gaps to try to
> > > > prevent
> > > > one
> > > > thread from overflowing onto another thread's shadow stack.
> > > > This
> > > > would
> > > > somewhat opens that up, as the stack guard gaps are usually
> > > > maintained
> > > > by userspace for new threads. It would have to be thought
> > > > through
> > > > if
> > > > these could still be enforced with checking at additional
> > > > spots.
> > > 
> > > I would think the existing guard pages would already do that if a
> > > thread's shadow stack is contiguous with its own data stack.
> > 
> > The difference is that the kernel provides the guard gaps, where
> > this
> > would rely on userspace to do it. It is not a showstopper either.
> > 
> > I think my biggest question on this is how does it change the
> > capability for two threads to share a shadow stack. It might
> > require
> > some special rules around the syscall that writes restore tokens.
> > So
> > I'm not sure. It probably needs a POC.
> 
> Why would they be sharing a shadow stack?

The guard gap was introduced originally based on a suggestion that
overflowing a shadow stack onto an adjacent shadow stack could cause
corruption that could be used by an attacker to work around the
protection. There wasn't any concrete demonstrated attacks or
suggestion that all the protection was moot.

But when we talk about capabilities for converting memory to shadow
stack with simple memory accesses, and syscalls that can write restore
token to shadow stacks, it's not immediately clear to me that it
wouldn't open up something like that. Like if two restore tokens were
written to a shadow stack, or two shadow stacks were adjacent with
normal memory between them that later got converted to shadow stack.
Those sorts of scenarios, but I won't lean on those specific examples.
Sorry for being hand wavy. It's just where I'm at, at this point.

> 
> > > From the musl side, I have always looked at the entirely of
> > > shadow
> > > stack stuff with very heavy skepticism, and anything that breaks
> > > existing interface contracts, introduced places where apps can
> > > get
> > > auto-killed because a late resource allocation fails, or requires
> > > applications to code around the existence of something that
> > > should be
> > > an implementation detail, is a non-starter. To even consider
> > > shadow
> > > stack support, it must truely be fully non-breaking.
> > 
> > The manual assembly stack switching and JIT code in the apps needs
> > to
> > be updated. I don't think there is a way around it.
> 
> Indeed, I'm not talking about programs with JIT/manual stack-
> switching
> asm, just anything using existing APIs for control of stack --
> pthread_setstack, makecontext, sigaltstack, etc.

Then I think WRSS might fit your requirements better than what glibc
did. It was considered a reduced security mode that made libc's job
much easier and had better compatibility, but the last discussion was
to try to do it without WRSS.

> 
> > I agree though that the late allocation failures are not great.
> > Mark is
> > working on clone3 support which should allow moving the shadow
> > stack
> > allocation to happen in userspace with the normal stack. Even for
> > riscv
> > though, doesn't it need to update a new register in stack
> > switching?
> 
> If clone is called with signals masked, it's probably not necessary
> for the kernel to set the shadow stack register as part of clone3.

So you would want a mode of clone3 that basically leaves the shadow
stack bits alone? Mark was driving that effort, but it doesn't seem
horrible to me on first impression. If it would open up the possibility
of musl support.

> 
> > BTW, x86 shadow stack has a mode where the shadow stack is writable
> > with a special instruction (WRSS). It enables the SSP to be set
> > arbitrarily by writing restore tokens. We discussed this as an
> > option
> > to make the existing longjmp() and signal stuff work more
> > transparently
> > for glibc.
> > 
> > 
> > 
> > BTW, when I talk about "not supporting" I don't mean the app should
> > crash. I mean it should instead run normally, just without shadow
> > stack
> > enabled. Not sure if that was clear. Since shadow stack is not
> > essential for an application to function, it is only security
> > hardening
> > on top.
> > 
> > Although determining if an application supports shadow stack has
> > turned
> > out to be difficult in practice. Handling dlopen() is especially
> > hard.
> 
> One reasonable thing to do, that might be preferable to
> overengineered
> solutions, is to disable shadow-stack process-wide if an interface
> incompatible with it is used (sigaltstack, pthread_create with an
> attribute setup using pthread_attr_setstack, makecontext, etc.), as
> well as if an incompatible library is is dlopened.

I think it would be an interesting approach to determining
compatibility.?On x86 there has been cases of binaries getting
mismarked as supporting shadow stack. So an automated way of filtering
some of those out would be very useful I think. I guess the dynamic
linker could determine this based on some list of functions?

The dlopen() bit gets complicated though. You need to disable shadow
stack for all threads, which presumably the kernel could be coaxed into
doing. But those threads might be using shadow stack instructions
(INCSSP, RSTORSSP, etc). These are a collection of instructions that
allow limited control of the SSP. When shadow stack gets disabled,
these suddenly turn into #UD generating instructions. So any other
threads executing those instructions when shadow stack got disabled
would be in for a nasty surprise.

Glibc's permissive mode (that disables shadow stack when dlopen()ing a
DSO that doesn't support shadow stack) is quite limited because of
this. There was a POC for working around it, but I'll stop there for
now, to not spam you with the details. I'm not sure of arm and risc-v
details on this specific corner, but for x86.

>  This is much more
> acceptable than continuing to run with shadow stacks managed sloppily
> by the kernel and async killing the process on OOM, and is probably
> *more compatible* with apps than changing the minimum stack size
> requirements out from under them.

Yep.

> 
> The place where it's really needed to be able to allocate the shadow
> stack synchronously under userspace control, in order to harden
> normal
> applications that aren't doing funny things, is in pthread_create
> without a caller-provided stack.

Yea most apps don't do anything too tricky. Mostly shadow stack "just
works". But it's no excuse to just crash for the others.


From broonie at kernel.org  Tue Feb 20 16:40:16 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 21 Feb 2024 00:40:16 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <063acc75-ea1d-4dd3-aecb-e5c8884005db@app.fastmail.com>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
 <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
 <063acc75-ea1d-4dd3-aecb-e5c8884005db@app.fastmail.com>
Message-ID: <4be8dc73-4873-44e5-8ef6-62e55d5023a7@sirena.org.uk>

On Tue, Feb 20, 2024 at 06:59:58PM -0500, Stefan O'Rear wrote:
> On Tue, Feb 20, 2024, at 6:30 PM, Edgecombe, Rick P wrote:

> > Maybe I'm misunderstanding. I thought the proposal included allowing
> > shadow stack access to convert normal address ranges to shadow stack,
> > and normal writes to convert shadow stack to normal.

> Ideally for riscv only writes would cause conversion, an incssp underflow
> which performs shadow stack reads would be able to fault early.

> For arm, since a syscall is needed anyway to set up the token in a new
> shadow stack region, it would make sense for conversion from non-shadow
> to shadow usage to never be automatic.

Well, we only need the token to pivot in userspace so we could
*potentially* work something out as part of the conversion process.
It's not filling me with enthusiasm though, and I've certainly not
actually thought it through yet.

> > I agree though that the late allocation failures are not great. Mark is
> > working on clone3 support which should allow moving the shadow stack
> > allocation to happen in userspace with the normal stack. Even for riscv
> > though, doesn't it need to update a new register in stack switching?

> > BTW, x86 shadow stack has a mode where the shadow stack is writable
> > with a special instruction (WRSS). It enables the SSP to be set
> > arbitrarily by writing restore tokens. We discussed this as an option
> > to make the existing longjmp() and signal stuff work more transparently
> > for glibc.

We have this feature on arm64 too, plus a separately controllable push
instruction (though that's less useful here).

> > BTW, when I talk about "not supporting" I don't mean the app should
> > crash. I mean it should instead run normally, just without shadow stack
> > enabled. Not sure if that was clear. Since shadow stack is not
> > essential for an application to function, it is only security hardening
> > on top.

> I appreciate that.  How far can we go in that direction?  If we can
> automatically disable shadow stacks on any call to makecontext, sigaltstack,
> or pthread_attr_setstack without causing other threads to crash if they were
> in the middle of shadow stack maintenance we can probably simplify this
> proposal, although I need to think more about what's possible.

Aside from concerns about disabling over all the threads in the process
(which should be solvable if annoying) this would be incompatible with
policies which prevent disabling of shadow stacks, and it feels like it
might end up being a gadget people could use which will concern some
people.  There's a tension here between compatibility and the security
applications of these features.
-------------- 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/20240221/5cd3ad4e/attachment-0001.sig>

From broonie at kernel.org  Tue Feb 20 16:44:43 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 21 Feb 2024 00:44:43 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
 <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
 <20240220235415.GP4163@brightrain.aerifal.cx>
 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
Message-ID: <cffc9c7e-ba1c-4894-a455-8b2d687182cd@sirena.org.uk>

On Wed, Feb 21, 2024 at 12:35:48AM +0000, Edgecombe, Rick P wrote:

> doing. But those threads might be using shadow stack instructions
> (INCSSP, RSTORSSP, etc). These are a collection of instructions that
> allow limited control of the SSP. When shadow stack gets disabled,
> these suddenly turn into #UD generating instructions. So any other
> threads executing those instructions when shadow stack got disabled
> would be in for a nasty surprise.

> Glibc's permissive mode (that disables shadow stack when dlopen()ing a
> DSO that doesn't support shadow stack) is quite limited because of
> this. There was a POC for working around it, but I'll stop there for
> now, to not spam you with the details. I'm not sure of arm and risc-v
> details on this specific corner, but for x86.

We have the same issue with disabling GCS causing GCS instructions to
become undefined.
-------------- 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/20240221/03947e4b/attachment.sig>

From ychuang570808 at gmail.com  Tue Feb 20 16:51:43 2024
From: ychuang570808 at gmail.com (Jacky Huang)
Date: Wed, 21 Feb 2024 08:51:43 +0800
Subject: [PATCH v5 4/4] pinctrl: nuvoton: Add ma35d1 pinctrl and GPIO
 driver
In-Reply-To: <b40f5b2d-d41f-47fa-8aae-30290e0d2737@linaro.org>
References: <20240220004159.1580108-1-ychuang570808@gmail.com>
 <20240220004159.1580108-5-ychuang570808@gmail.com>
 <b40f5b2d-d41f-47fa-8aae-30290e0d2737@linaro.org>
Message-ID: <9c0f9285-4418-4ae9-9f72-ea74bfcf92cc@gmail.com>

Dear Krzysztof,


On 2024/2/20 ?? 04:28, Krzysztof Kozlowski wrote:
> On 20/02/2024 01:41, Jacky Huang wrote:
>> From: Jacky Huang <ychuang3 at nuvoton.com>
>>
>> Add common pinctrl and GPIO driver for Nuvoton MA35 series SoC, and
>> add support for ma35d1 pinctrl.
>>
>> Signed-off-by: Jacky Huang <ychuang3 at nuvoton.com>
>> ---
>>   drivers/pinctrl/nuvoton/Kconfig          |   19 +
>>   drivers/pinctrl/nuvoton/Makefile         |    2 +
>>   drivers/pinctrl/nuvoton/pinctrl-ma35.c   | 1211 +++++++++++++++
>>   drivers/pinctrl/nuvoton/pinctrl-ma35.h   |   51 +
>>   drivers/pinctrl/nuvoton/pinctrl-ma35d1.c | 1797 ++++++++++++++++++++++
>>   5 files changed, 3080 insertions(+)
>>   create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.c
>>   create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35.h
>>   create mode 100644 drivers/pinctrl/nuvoton/pinctrl-ma35d1.c
> Driver cannot depend on DTS, so please reorganize patchset so DTS is not
> in the middle or even split the DTS to separate patchset.
>
> Best regards,
> Krzysztof
>

Thank you for your explanation. In the next version, I will adjust the 
order and move the DTS to the end of this patchset. Best Regards, Jacky 
Huang


From cki-project at redhat.com  Tue Feb 20 17:10:09 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Wed, 21 Feb 2024 01:10:09 -0000
Subject: =?utf-8?b?4pyF?= PASS (MISSED 2 of 87): Test report for for-kernelci
 (6.8.0-rc5, arm-next, e6ac7c55)
Message-ID: <60555.124022020101001183@us-mta-138.us.mimecast.lan>

Hi, we tested your kernel and here are the results:

    Overall result: PASSED
             Merge: OK
           Compile: OK
              Test: OK

Tested-by: CKI Project <cki-project at redhat.com>

Kernel information:
    Commit message: Merge branch 'for-next/core' into for-kernelci

You can find all the details about the test run at
    https://datawarehouse.cki-project.org/kcidb/checkouts/130358

One or more kernel tests failed:
    We also see the following known issues which are not related to your changes:
        Issue: [rawhide] avc:  denied  { read write } for  pid=12364 comm="plymouthd" name="kmsg" dev="devtmpfs" ino=10 scontext=system_u:system_r:plymouthd_t:s0 tcontext=system_u:object_r:kmsg_device_t:s0 tclass=chr_file permissive=1
            URL: https://bugzilla.redhat.com/show_bug.cgi?id=2256442
            Affected tests:
                 aarch64 - Boot test
                 aarch64 - Reboot test
                 aarch64 - stress: stress-ng - cpu-cache
        Issue: [upstream] blktests tests nbd/001 failed
            URL: https://github.com/osandov/blktests/issues/132
            Affected tests:
                 aarch64 - Storage - blktests - blk - upstream
        Issue: [upstream] stress-ng: avc denial on secretmemory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1752
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: [upstream] blktests tests/zbd/010 failed
            URL: https://lore.kernel.org/linux-block/CAHj4cs-kfojYC9i0G73PRkYzcxCTex=-vugRFeP40g_URGvnfQ at mail.gmail.com/T/#u
            Affected tests:
                 aarch64 - Storage - blktests - blk - upstream
        Issue: stress: stress-ng - memory: (panic) Comm: systemd-oomd Not tainted 6.1.0-rc3
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1461
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: Firmware test suite: mv: cannot stat 'dtcompilerparser.tab.c': No such file or directory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1544
            Affected tests:
                 aarch64 - Hardware - Firmware test suite


Tests that were not ran because of internal issues: 
     aarch64 - Memory function: memfd_create
     aarch64 - Memory function: memfd_create


If you find a failure unrelated to your changes, please ask the test maintainer to review it.
This will prevent the failures from being incorrectly reported in the future.

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
           `-'
______________________________________________________________________________



From william.zhang at broadcom.com  Tue Feb 20 17:11:46 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Tue, 20 Feb 2024 17:11:46 -0800
Subject: [PATCH v5 11/12] mtd: rawnand: brcmnand: exec_op helper functions
 return type fixes
In-Reply-To: <20240220110240.1ad5b995@xps-13>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-12-william.zhang@broadcom.com>
 <20240220110240.1ad5b995@xps-13>
Message-ID: <c3db1ce5-771e-44e4-9712-440fd16f7a69@broadcom.com>

Hi Miquel,

On 2/20/24 02:02, Miquel Raynal wrote:
> 
> william.zhang at broadcom.com wrote on Wed,  7 Feb 2024 12:22:56 -0800:
> 
>> From: David Regan <dregan at broadcom.com>
>>
>> fix return type for exec_op reset and status detect helper functions
>>
>> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
>> Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
>> Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
>> Signed-off-by: David Regan <dregan at broadcom.com>
>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>> Reviewed-by: William Zhang <william.zhang at broadcom.com>
> 
> By the way, a Cc: stable tag might be useful as otherwise you may leak
Sorry I am not very familiar with these term and release procedure.  But 
I don't see exec_op patch is in the current stable release 6.7.5 and LTS 
release.  It is only in the mainline and linux-next.  Do you mean the 
stable tag will make it to the mainline?
> an error code in a status value (which is a bug). And move this patch
> first in your series so we're sure it does not conflict with any of the
> other patches and can be backported more easily.
> 
> Thanks,
> Miqu?l
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240220/c9a5f563/attachment-0001.p7s>

From jgg at nvidia.com  Tue Feb 20 17:17:10 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 20 Feb 2024 21:17:10 -0400
Subject: [PATCH 6/6] IB/mlx5: Use __iowrite64_copy() for write combining stores
In-Reply-To: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
Message-ID: <6-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>

mlx5 has a built in self-test at driver startup to evaluate if the
platform supports write combining to generate a 64 byte PCIe TLP or
not. This has proven necessary because a lot of common scenarios end up
with broken write combining (especially inside virtual machines) and there
is other way to learn this information.

This self test has been consistently failing on new ARM64 CPU
designs (specifically with NVIDIA Grace's implementation of Neoverse
V2). The C loop around writeq() generates some pretty terrible ARM64
assembly, but historically this has worked on a lot of existing ARM64 CPUs
till now.

We see it succeed about 1 time in 10,000 on the worst effected
systems. The CPU architects speculate that the load instructions
interspersed with the stores makes the WC buffers statistically flush too
often and thus the generation of large TLPs becomes infrequent. This makes
the boot up test unreliable in that it indicates no write-combining,
however userspace would be fine since it uses a ST4 instruction.

Further, S390 has similar issues where only the special zpci_memcpy_toio()
will actually generate large TLPs, and the open coded loop does not
trigger it at all.

Fix both ARM64 and S390 by switching to __iowrite64_copy() which now
provides architecture specific variants that have a high change of
generating a large TLP with write combining. x86 continues to use a
similar writeq loop in the generate __iowrite64_copy().

Fixes: 11f552e21755 ("IB/mlx5: Test write combining support")
Tested-by: Niklas Schnelle <schnelle at linux.ibm.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/infiniband/hw/mlx5/mem.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/mem.c b/drivers/infiniband/hw/mlx5/mem.c
index 96ffbbaf0a73d1..5a22be14d958f2 100644
--- a/drivers/infiniband/hw/mlx5/mem.c
+++ b/drivers/infiniband/hw/mlx5/mem.c
@@ -30,6 +30,7 @@
  * SOFTWARE.
  */
 
+#include <linux/io.h>
 #include <rdma/ib_umem_odp.h>
 #include "mlx5_ib.h"
 #include <linux/jiffies.h>
@@ -108,7 +109,6 @@ static int post_send_nop(struct mlx5_ib_dev *dev, struct ib_qp *ibqp, u64 wr_id,
 	__be32 mmio_wqe[16] = {};
 	unsigned long flags;
 	unsigned int idx;
-	int i;
 
 	if (unlikely(dev->mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR))
 		return -EIO;
@@ -148,10 +148,8 @@ static int post_send_nop(struct mlx5_ib_dev *dev, struct ib_qp *ibqp, u64 wr_id,
 	 * we hit doorbell
 	 */
 	wmb();
-	for (i = 0; i < 8; i++)
-		mlx5_write64(&mmio_wqe[i * 2],
-			     bf->bfreg->map + bf->offset + i * 8);
-	io_stop_wc();
+	__iowrite64_copy(bf->bfreg->map + bf->offset, mmio_wqe,
+			 sizeof(mmio_wqe) / 8);
 
 	bf->offset ^= bf->buf_size;
 
-- 
2.43.2



From jgg at nvidia.com  Tue Feb 20 17:17:09 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 20 Feb 2024 21:17:09 -0400
Subject: [PATCH 5/6] net: hns3: Remove io_stop_wc() calls after __iowrite64_copy()
In-Reply-To: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
Message-ID: <5-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>

Now that the ARM64 arch implementation does the DGH as part of
__iowrite64_copy() there is no reason to open code this in drivers.

Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index f1695c889d3a07..ff556c2b5bacb4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2068,8 +2068,6 @@ static void hns3_tx_push_bd(struct hns3_enet_ring *ring, int num)
 	__iowrite64_copy(ring->tqp->mem_base, desc,
 			 (sizeof(struct hns3_desc) * HNS3_MAX_PUSH_BD_NUM) /
 			 HNS3_BYTES_PER_64BIT);
-
-	io_stop_wc();
 }
 
 static void hns3_tx_mem_doorbell(struct hns3_enet_ring *ring)
@@ -2088,8 +2086,6 @@ static void hns3_tx_mem_doorbell(struct hns3_enet_ring *ring)
 	u64_stats_update_begin(&ring->syncp);
 	ring->stats.tx_mem_doorbell += ring->pending_buf;
 	u64_stats_update_end(&ring->syncp);
-
-	io_stop_wc();
 }
 
 static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num,
-- 
2.43.2



From jgg at nvidia.com  Tue Feb 20 17:17:07 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 20 Feb 2024 21:17:07 -0400
Subject: [PATCH 3/6] s390: Stop using weak symbols for __iowrite64_copy()
In-Reply-To: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
Message-ID: <3-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>

Complete switching the __iowriteXX_copy() routines over to use #define and
arch provided inline/macro functions instead of weak symbols.

S390 has an implementation that simply calls another memcpy
function. Inline this so the callers don't have to do two jumps.

Acked-by: Niklas Schnelle <schnelle at linux.ibm.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 arch/s390/include/asm/io.h | 7 +++++++
 arch/s390/pci/pci.c        | 6 ------
 include/linux/io.h         | 3 +++
 lib/iomap_copy.c           | 7 +++----
 4 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
index 00704fc8a54b30..0fbc992d7a5ea7 100644
--- a/arch/s390/include/asm/io.h
+++ b/arch/s390/include/asm/io.h
@@ -81,6 +81,13 @@ static inline void __iowrite32_copy(void __iomem *to, const void *from,
 }
 #define __iowrite32_copy __iowrite32_copy
 
+static inline void __iowrite64_copy(void __iomem *to, const void *from,
+				    size_t count)
+{
+	zpci_memcpy_toio(to, from, count * 8);
+}
+#define __iowrite64_copy __iowrite64_copy
+
 #endif /* CONFIG_PCI */
 
 #include <asm-generic/io.h>
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 52a44e353796c0..fb81337a73eaab 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -249,12 +249,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 	return 0;
 }
 
-/* combine single writes by using store-block insn */
-void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
-{
-	zpci_memcpy_toio(to, from, count * 8);
-}
-
 void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
 			   unsigned long prot)
 {
diff --git a/include/linux/io.h b/include/linux/io.h
index 68cd551b6af112..fe12be9de6f7a6 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -21,7 +21,10 @@ void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
 #endif
 
 void __ioread32_copy(void *to, const void __iomem *from, size_t count);
+
+#ifndef __iowrite64_copy
 void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
+#endif
 
 #ifdef CONFIG_MMU
 int ioremap_page_range(unsigned long addr, unsigned long end,
diff --git a/lib/iomap_copy.c b/lib/iomap_copy.c
index 8ddcbb53507dfe..2fd5712fb7c02b 100644
--- a/lib/iomap_copy.c
+++ b/lib/iomap_copy.c
@@ -60,9 +60,8 @@ EXPORT_SYMBOL_GPL(__ioread32_copy);
  * time.  Order of access is not guaranteed, nor is a memory barrier
  * performed afterwards.
  */
-void __attribute__((weak)) __iowrite64_copy(void __iomem *to,
-					    const void *from,
-					    size_t count)
+#ifndef __iowrite64_copy
+void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
 {
 #ifdef CONFIG_64BIT
 	u64 __iomem *dst = to;
@@ -75,5 +74,5 @@ void __attribute__((weak)) __iowrite64_copy(void __iomem *to,
 	__iowrite32_copy(to, from, count * 2);
 #endif
 }
-
 EXPORT_SYMBOL_GPL(__iowrite64_copy);
+#endif
-- 
2.43.2



From jgg at nvidia.com  Tue Feb 20 17:17:08 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 20 Feb 2024 21:17:08 -0400
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
Message-ID: <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>

The kernel provides driver support for using write combining IO memory
through the __iowriteXX_copy() API which is commonly used as an optional
optimization to generate 16/32/64 byte MemWr TLPs in a PCIe environment.

iomap_copy.c provides a generic implementation as a simple 4/8 byte at a
time copy loop that has worked well with past ARM64 CPUs, giving a high
frequency of large TLPs being successfully formed.

However modern ARM64 CPUs are quite sensitive to how the write combining
CPU HW is operated and a compiler generated loop with intermixed
load/store is not sufficient to frequently generate a large TLP. The CPUs
would like to see the entire TLP generated by consecutive store
instructions from registers. Compilers like gcc tend to intermix loads and
stores and have poor code generation, in part, due to the ARM64 situation
that writeq() does not codegen anything other than "[xN]". However even
with that resolved compilers like clang still do not have good code
generation.

This means on modern ARM64 CPUs the rate at which __iowriteXX_copy()
successfully generates large TLPs is very small (less than 1 in 10,000)
tries), to the point that the use of WC is pointless.

Implement __iowrite32/64_copy() specifically for ARM64 and use inline
assembly to build consecutive blocks of STR instructions. Provide direct
support for 64/32/16 large TLP generation in this manner. Optimize for
common constant lengths so that the compiler can directly inline the store
blocks.

This brings the frequency of large TLP generation up to a high level that
is comparable with older CPU generations.

As the __iowriteXX_copy() family of APIs is intended for use with WC
incorporate the DGH hint directly into the function.

Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: linux-arch at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 arch/arm64/include/asm/io.h | 132 ++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/io.c      |  42 ++++++++++++
 2 files changed, 174 insertions(+)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 3b694511b98f83..471ab46621e7d6 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -135,6 +135,138 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
 #define memcpy_fromio(a,c,l)	__memcpy_fromio((a),(c),(l))
 #define memcpy_toio(c,a,l)	__memcpy_toio((c),(a),(l))
 
+/*
+ * The ARM64 iowrite implementation is intended to support drivers that want to
+ * use write combining. For instance PCI drivers using write combining with a 64
+ * byte __iowrite64_copy() expect to get a 64 byte MemWr TLP on the PCIe bus.
+ *
+ * Newer ARM core have sensitive write combining buffers, it is important that
+ * the stores be contiguous blocks of store instructions. Normal memcpy
+ * approaches have a very low chance to generate write combining.
+ *
+ * Since this is the only API on ARM64 that should be used with write combining
+ * it also integrates the DGH hint which is supposed to lower the latency to
+ * emit the large TLP from the CPU.
+ */
+
+static inline void __const_memcpy_toio_aligned32(volatile u32 __iomem *to,
+						 const u32 *from, size_t count)
+{
+	switch (count) {
+	case 8:
+		asm volatile("str %w0, [%8, #4 * 0]\n"
+			     "str %w1, [%8, #4 * 1]\n"
+			     "str %w2, [%8, #4 * 2]\n"
+			     "str %w3, [%8, #4 * 3]\n"
+			     "str %w4, [%8, #4 * 4]\n"
+			     "str %w5, [%8, #4 * 5]\n"
+			     "str %w6, [%8, #4 * 6]\n"
+			     "str %w7, [%8, #4 * 7]\n"
+			     :
+			     : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
+			       "rZ"(from[3]), "rZ"(from[4]), "rZ"(from[5]),
+			       "rZ"(from[6]), "rZ"(from[7]), "r"(to));
+		break;
+	case 4:
+		asm volatile("str %w0, [%4, #4 * 0]\n"
+			     "str %w1, [%4, #4 * 1]\n"
+			     "str %w2, [%4, #4 * 2]\n"
+			     "str %w3, [%4, #4 * 3]\n"
+			     :
+			     : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
+			       "rZ"(from[3]), "r"(to));
+		break;
+	case 2:
+		asm volatile("str %w0, [%2, #4 * 0]\n"
+			     "str %w1, [%2, #4 * 1]\n"
+			     :
+			     : "rZ"(from[0]), "rZ"(from[1]), "r"(to));
+		break;
+	case 1:
+		__raw_writel(*from, to);
+		break;
+	default:
+		BUILD_BUG();
+	}
+}
+
+void __iowrite32_copy_full(void __iomem *to, const void *from, size_t count);
+
+static inline void __const_iowrite32_copy(void __iomem *to, const void *from,
+					  size_t count)
+{
+	if (count == 8 || count == 4 || count == 2 || count == 1) {
+		__const_memcpy_toio_aligned32(to, from, count);
+		dgh();
+	} else {
+		__iowrite32_copy_full(to, from, count);
+	}
+}
+
+#define __iowrite32_copy(to, from, count)                  \
+	(__builtin_constant_p(count) ?                     \
+		 __const_iowrite32_copy(to, from, count) : \
+		 __iowrite32_copy_full(to, from, count))
+
+static inline void __const_memcpy_toio_aligned64(volatile u64 __iomem *to,
+						 const u64 *from, size_t count)
+{
+	switch (count) {
+	case 8:
+		asm volatile("str %x0, [%8, #8 * 0]\n"
+			     "str %x1, [%8, #8 * 1]\n"
+			     "str %x2, [%8, #8 * 2]\n"
+			     "str %x3, [%8, #8 * 3]\n"
+			     "str %x4, [%8, #8 * 4]\n"
+			     "str %x5, [%8, #8 * 5]\n"
+			     "str %x6, [%8, #8 * 6]\n"
+			     "str %x7, [%8, #8 * 7]\n"
+			     :
+			     : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
+			       "rZ"(from[3]), "rZ"(from[4]), "rZ"(from[5]),
+			       "rZ"(from[6]), "rZ"(from[7]), "r"(to));
+		break;
+	case 4:
+		asm volatile("str %x0, [%4, #8 * 0]\n"
+			     "str %x1, [%4, #8 * 1]\n"
+			     "str %x2, [%4, #8 * 2]\n"
+			     "str %x3, [%4, #8 * 3]\n"
+			     :
+			     : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
+			       "rZ"(from[3]), "r"(to));
+		break;
+	case 2:
+		asm volatile("str %x0, [%2, #8 * 0]\n"
+			     "str %x1, [%2, #8 * 1]\n"
+			     :
+			     : "rZ"(from[0]), "rZ"(from[1]), "r"(to));
+		break;
+	case 1:
+		__raw_writel(*from, to);
+		break;
+	default:
+		BUILD_BUG();
+	}
+}
+
+void __iowrite64_copy_full(void __iomem *to, const void *from, size_t count);
+
+static inline void __const_iowrite64_copy(void __iomem *to, const void *from,
+					  size_t count)
+{
+	if (count == 8 || count == 4 || count == 2 || count == 1) {
+		__const_memcpy_toio_aligned64(to, from, count);
+		dgh();
+	} else {
+		__iowrite64_copy_full(to, from, count);
+	}
+}
+
+#define __iowrite64_copy(to, from, count)                  \
+	(__builtin_constant_p(count) ?                     \
+		 __const_iowrite64_copy(to, from, count) : \
+		 __iowrite64_copy_full(to, from, count))
+
 /*
  * I/O memory mapping functions.
  */
diff --git a/arch/arm64/kernel/io.c b/arch/arm64/kernel/io.c
index aa7a4ec6a3ae6f..ef48089fbfe1a4 100644
--- a/arch/arm64/kernel/io.c
+++ b/arch/arm64/kernel/io.c
@@ -37,6 +37,48 @@ void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
 }
 EXPORT_SYMBOL(__memcpy_fromio);
 
+/*
+ * This generates a memcpy that works on a from/to address which is aligned to
+ * bits. Count is in terms of the number of bits sized quantities to copy. It
+ * optimizes to use the STR groupings when possible so that it is WC friendly.
+ */
+#define memcpy_toio_aligned(to, from, count, bits)                        \
+	({                                                                \
+		volatile u##bits __iomem *_to = to;                       \
+		const u##bits *_from = from;                              \
+		size_t _count = count;                                    \
+		const u##bits *_end_from = _from + ALIGN_DOWN(_count, 8); \
+                                                                          \
+		for (; _from < _end_from; _from += 8, _to += 8)           \
+			__const_memcpy_toio_aligned##bits(_to, _from, 8); \
+		if ((_count % 8) >= 4) {                                  \
+			__const_memcpy_toio_aligned##bits(_to, _from, 4); \
+			_from += 4;                                       \
+			_to += 4;                                         \
+		}                                                         \
+		if ((_count % 4) >= 2) {                                  \
+			__const_memcpy_toio_aligned##bits(_to, _from, 2); \
+			_from += 2;                                       \
+			_to += 2;                                         \
+		}                                                         \
+		if (_count % 2)                                           \
+			__const_memcpy_toio_aligned##bits(_to, _from, 1); \
+	})
+
+void __iowrite64_copy_full(void __iomem *to, const void *from, size_t count)
+{
+	memcpy_toio_aligned(to, from, count, 64);
+	dgh();
+}
+EXPORT_SYMBOL(__iowrite64_copy_full);
+
+void __iowrite32_copy_full(void __iomem *to, const void *from, size_t count)
+{
+	memcpy_toio_aligned(to, from, count, 32);
+	dgh();
+}
+EXPORT_SYMBOL(__iowrite32_copy_full);
+
 /*
  * Copy data from "real" memory space to IO memory space.
  */
-- 
2.43.2



From jgg at nvidia.com  Tue Feb 20 17:17:06 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 20 Feb 2024 21:17:06 -0400
Subject: [PATCH 2/6] s390: Implement __iowrite32_copy()
In-Reply-To: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
Message-ID: <2-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>

It is trivial to implement an inline to do this, so provide it in the s390
headers. Like the 64 bit version it should just invoke zpci_memcpy_toio()
with the correct size.

Acked-by: Niklas Schnelle <schnelle at linux.ibm.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 arch/s390/include/asm/io.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
index 4453ad7c11aced..00704fc8a54b30 100644
--- a/arch/s390/include/asm/io.h
+++ b/arch/s390/include/asm/io.h
@@ -73,6 +73,14 @@ static inline void ioport_unmap(void __iomem *p)
 #define __raw_writel	zpci_write_u32
 #define __raw_writeq	zpci_write_u64
 
+/* combine single writes by using store-block insn */
+static inline void __iowrite32_copy(void __iomem *to, const void *from,
+				    size_t count)
+{
+	zpci_memcpy_toio(to, from, count * 4);
+}
+#define __iowrite32_copy __iowrite32_copy
+
 #endif /* CONFIG_PCI */
 
 #include <asm-generic/io.h>
-- 
2.43.2



From jgg at nvidia.com  Tue Feb 20 17:17:05 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 20 Feb 2024 21:17:05 -0400
Subject: [PATCH 1/6] x86: Stop using weak symbols for __iowrite32_copy()
In-Reply-To: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
Message-ID: <1-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>

Start switching iomap_copy routines over to use #define and arch provided
inline/macro functions instead of weak symbols.

Inline functions allow more compiler optimization and this is often a
driver hot path.

x86 has the only weak implementation for __iowrite32_copy(), so replace it
with a static inline containing the same single instruction inline
assembly. The compiler will generate the "mov edx,ecx" in a more optimal
way.

Remove iomap_copy_64.S

Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 arch/x86/include/asm/io.h    | 17 +++++++++++++++++
 arch/x86/lib/Makefile        |  1 -
 arch/x86/lib/iomap_copy_64.S | 15 ---------------
 include/linux/io.h           |  5 ++++-
 lib/iomap_copy.c             |  6 +++---
 5 files changed, 24 insertions(+), 20 deletions(-)
 delete mode 100644 arch/x86/lib/iomap_copy_64.S

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 3814a9263d64ea..2483988f0b7f7b 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -209,6 +209,23 @@ void memset_io(volatile void __iomem *, int, size_t);
 #define memcpy_toio memcpy_toio
 #define memset_io memset_io
 
+#ifdef CONFIG_X86_64
+/*
+ * Commit 0f07496144c2 ("[PATCH] Add faster __iowrite32_copy routine for
+ * x86_64") says that circa 2006 rep movsl is noticeably faster than a copy
+ * loop.
+ */
+static inline void __iowrite32_copy(void __iomem *to, const void *from,
+				    size_t count)
+{
+	asm volatile("rep ; movsl"
+		     : "=&c"(count), "=&D"(to), "=&S"(from)
+		     : "0"(count), "1"(to), "2"(from)
+		     : "memory");
+}
+#define __iowrite32_copy __iowrite32_copy
+#endif
+
 /*
  * ISA space is 'always mapped' on a typical x86 system, no need to
  * explicitly ioremap() it. The fact that the ISA IO space is mapped
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index ea3a28e7b613cc..af4ea3d83ba1f6 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -66,7 +66,6 @@ ifneq ($(CONFIG_X86_CMPXCHG64),y)
         lib-y += atomic64_386_32.o
 endif
 else
-        obj-y += iomap_copy_64.o
 ifneq ($(CONFIG_GENERIC_CSUM),y)
         lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o
 endif
diff --git a/arch/x86/lib/iomap_copy_64.S b/arch/x86/lib/iomap_copy_64.S
deleted file mode 100644
index 6ff2f56cb0f71a..00000000000000
--- a/arch/x86/lib/iomap_copy_64.S
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright 2006 PathScale, Inc.  All Rights Reserved.
- */
-
-#include <linux/linkage.h>
-
-/*
- * override generic version in lib/iomap_copy.c
- */
-SYM_FUNC_START(__iowrite32_copy)
-	movl %edx,%ecx
-	rep movsl
-	RET
-SYM_FUNC_END(__iowrite32_copy)
diff --git a/include/linux/io.h b/include/linux/io.h
index 7304f2a69960a3..68cd551b6af112 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -16,7 +16,10 @@
 struct device;
 struct resource;
 
-__visible void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
+#ifndef __iowrite32_copy
+void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
+#endif
+
 void __ioread32_copy(void *to, const void __iomem *from, size_t count);
 void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
 
diff --git a/lib/iomap_copy.c b/lib/iomap_copy.c
index 5de7c04e05ef56..8ddcbb53507dfe 100644
--- a/lib/iomap_copy.c
+++ b/lib/iomap_copy.c
@@ -16,9 +16,8 @@
  * time.  Order of access is not guaranteed, nor is a memory barrier
  * performed afterwards.
  */
-void __attribute__((weak)) __iowrite32_copy(void __iomem *to,
-					    const void *from,
-					    size_t count)
+#ifndef __iowrite32_copy
+void __iowrite32_copy(void __iomem *to, const void *from, size_t count)
 {
 	u32 __iomem *dst = to;
 	const u32 *src = from;
@@ -28,6 +27,7 @@ void __attribute__((weak)) __iowrite32_copy(void __iomem *to,
 		__raw_writel(*src++, dst++);
 }
 EXPORT_SYMBOL_GPL(__iowrite32_copy);
+#endif
 
 /**
  * __ioread32_copy - copy data from MMIO space, in 32-bit units
-- 
2.43.2



From jgg at nvidia.com  Tue Feb 20 17:17:04 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 20 Feb 2024 21:17:04 -0400
Subject: [PATCH 0/6] Fix mlx5 write combining support on new ARM64 cores
Message-ID: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>

mlx5 has a built in self-test at driver startup to evaluate if the
platform supports write combining to generate a 64 byte PCIe TLP or
not. This has proven necessary because a lot of common scenarios end up
with broken write combining (especially inside virtual machines) and there
is no other way to learn this information.

This self test has been consistently failing on new ARM64 CPU
designs (specifically with NVIDIA Grace's implementation of Neoverse
V2). The C loop around writeq() generates some pretty terrible ARM64
assembly, but historically this has worked on alot of existing ARM64 CPUs
till now.

We see it succeed about 1 time in 10,000 on the worst affected
systems. The CPU architects speculate that the load instructions
interspersed with the stores make the test unreliable.

Arrange things so that the ARM64 uses a predictable inline assembly block
of 8 STR instructions.

Catalin suggested implementing this in terms of the obscure
__iowrite64_copy() interface which was long ago added to optimize write
combining stores on Pathscale RDMA HW for x86. These copy routines have
the advantage of requiring the caller to supply alignment which allows an
optimal assembly implementation.

This is a good suggestion because it turns out that S390 has much the same
problem and already uses the __iowrite64_copy() to try to make its WC
operations work.

The first several patches modernize and improve the performance of
__iowriteXX_copy() so that an ARM64 implementation can be provided which
relies on __builtin_constant_p to generate fast inlined assembly code in a
few common cases.

It should come after the S390 fix:

https://lore.kernel.org/r/0-v1-9b1ea6869554+110c60-iommufd_ck_data_type_jgg at nvidia.com

With acks, I'd like to take this through the RDMA tree.

v2:
 - Rework everything to use __iowrite64_copy().
 - Don't use STP since that is not reliably supported in ARM VMs
 - New patches to tidy up __iowriteXX_copy() on x86 and s390
v1: https://lore.kernel.org/r/cover.1700766072.git.leon at kernel.org

Jason Gunthorpe (6):
  x86: Stop using weak symbols for __iowrite32_copy()
  s390: Implement __iowrite32_copy()
  s390: Stop using weak symbols for __iowrite64_copy()
  arm64/io: Provide a WC friendly __iowriteXX_copy()
  net: hns3: Remove io_stop_wc() calls after __iowrite64_copy()
  IB/mlx5: Use __iowrite64_copy() for write combining stores

 arch/arm64/include/asm/io.h                   | 132 ++++++++++++++++++
 arch/arm64/kernel/io.c                        |  42 ++++++
 arch/s390/include/asm/io.h                    |  15 ++
 arch/s390/pci/pci.c                           |   6 -
 arch/x86/include/asm/io.h                     |  17 +++
 arch/x86/lib/Makefile                         |   1 -
 arch/x86/lib/iomap_copy_64.S                  |  15 --
 drivers/infiniband/hw/mlx5/mem.c              |   8 +-
 .../net/ethernet/hisilicon/hns3/hns3_enet.c   |   4 -
 include/linux/io.h                            |   8 +-
 lib/iomap_copy.c                              |  13 +-
 11 files changed, 222 insertions(+), 39 deletions(-)
 delete mode 100644 arch/x86/lib/iomap_copy_64.S


base-commit: 3856559a378586366dc602f93febe1c57cdc366c
-- 
2.43.2



From alexei.starovoitov at gmail.com  Tue Feb 20 17:24:16 2024
From: alexei.starovoitov at gmail.com (Alexei Starovoitov)
Date: Tue, 20 Feb 2024 17:24:16 -0800
Subject: [PATCH bpf-next 0/5] bpf: make tracing program support multi-attach
In-Reply-To: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
Message-ID: <CAADnVQ+E4ygZV6dcs8wj5FdFz9bfrQ=61235uiRoxe9RqQvR9Q@mail.gmail.com>

On Mon, Feb 19, 2024 at 7:51?PM Menglong Dong
<dongmenglong.8 at bytedance.com> wrote:
>
> For now, the BPF program of type BPF_PROG_TYPE_TRACING is not allowed to
> be attached to multiple hooks, and we have to create a BPF program for
> each kernel function, for which we want to trace, even through all the
> program have the same (or similar) logic. This can consume extra memory,
> and make the program loading slow if we have plenty of kernel function to
> trace.

Should this be combined with multi link ?
(As was recently done for kprobe_multi and uprobe_multi).
Loading fentry prog once and attaching it through many bpf_links
to multiple places is a nice addition,
but we should probably add a multi link right away too.


From dalias at libc.org  Tue Feb 20 17:27:37 2024
From: dalias at libc.org (dalias at libc.org)
Date: Tue, 20 Feb 2024 20:27:37 -0500
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
 <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
 <20240220235415.GP4163@brightrain.aerifal.cx>
 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
Message-ID: <20240221012736.GQ4163@brightrain.aerifal.cx>

On Wed, Feb 21, 2024 at 12:35:48AM +0000, Edgecombe, Rick P wrote:
> On Tue, 2024-02-20 at 18:54 -0500, dalias at libc.org wrote:
> > On Tue, Feb 20, 2024 at 11:30:22PM +0000, Edgecombe, Rick P wrote:
> > > On Tue, 2024-02-20 at 13:57 -0500, Rich Felker wrote:
> > > > On Tue, Feb 20, 2024 at 06:41:05PM +0000, Edgecombe, Rick P
> > > > > Shadow stacks currently have automatic guard gaps to try to
> > > > > prevent
> > > > > one
> > > > > thread from overflowing onto another thread's shadow stack.
> > > > > This
> > > > > would
> > > > > somewhat opens that up, as the stack guard gaps are usually
> > > > > maintained
> > > > > by userspace for new threads. It would have to be thought
> > > > > through
> > > > > if
> > > > > these could still be enforced with checking at additional
> > > > > spots.
> > > > 
> > > > I would think the existing guard pages would already do that if a
> > > > thread's shadow stack is contiguous with its own data stack.
> > > 
> > > The difference is that the kernel provides the guard gaps, where
> > > this
> > > would rely on userspace to do it. It is not a showstopper either.
> > > 
> > > I think my biggest question on this is how does it change the
> > > capability for two threads to share a shadow stack. It might
> > > require
> > > some special rules around the syscall that writes restore tokens.
> > > So
> > > I'm not sure. It probably needs a POC.
> > 
> > Why would they be sharing a shadow stack?
> 
> The guard gap was introduced originally based on a suggestion that
> overflowing a shadow stack onto an adjacent shadow stack could cause
> corruption that could be used by an attacker to work around the
> protection. There wasn't any concrete demonstrated attacks or
> suggestion that all the protection was moot.

OK, so not sharing, just happening to be adjacent.

I was thinking from a standpoint of allocating them as part of the
same range as the main stack, just with different protections, where
that would never happen; you'd always have intervening non-shadowstack
pages. But when they're kernel-allocated, yes, they need their own
guard pages.

> But when we talk about capabilities for converting memory to shadow
> stack with simple memory accesses, and syscalls that can write restore
> token to shadow stacks, it's not immediately clear to me that it
> wouldn't open up something like that. Like if two restore tokens were
> written to a shadow stack, or two shadow stacks were adjacent with
> normal memory between them that later got converted to shadow stack.
> Those sorts of scenarios, but I won't lean on those specific examples.
> Sorry for being hand wavy. It's just where I'm at, at this point.

I don't think it's safe to have automatic conversions back and forth,
only for normal accesses to convert shadowstack to normal memory (in
which case, any subsequent attempt to operate on it as shadow stack
indicates a critical bug and should be trapped to terminate the
process).

> > > > From the musl side, I have always looked at the entirely of
> > > > shadow
> > > > stack stuff with very heavy skepticism, and anything that breaks
> > > > existing interface contracts, introduced places where apps can
> > > > get
> > > > auto-killed because a late resource allocation fails, or requires
> > > > applications to code around the existence of something that
> > > > should be
> > > > an implementation detail, is a non-starter. To even consider
> > > > shadow
> > > > stack support, it must truely be fully non-breaking.
> > > 
> > > The manual assembly stack switching and JIT code in the apps needs
> > > to
> > > be updated. I don't think there is a way around it.
> > 
> > Indeed, I'm not talking about programs with JIT/manual stack-
> > switching
> > asm, just anything using existing APIs for control of stack --
> > pthread_setstack, makecontext, sigaltstack, etc.
> 
> Then I think WRSS might fit your requirements better than what glibc
> did. It was considered a reduced security mode that made libc's job
> much easier and had better compatibility, but the last discussion was
> to try to do it without WRSS.

Where can I read more about this? Some searches I tried didn't turn up
much useful information.

> > > I agree though that the late allocation failures are not great.
> > > Mark is
> > > working on clone3 support which should allow moving the shadow
> > > stack
> > > allocation to happen in userspace with the normal stack. Even for
> > > riscv
> > > though, doesn't it need to update a new register in stack
> > > switching?
> > 
> > If clone is called with signals masked, it's probably not necessary
> > for the kernel to set the shadow stack register as part of clone3.
> 
> So you would want a mode of clone3 that basically leaves the shadow
> stack bits alone? Mark was driving that effort, but it doesn't seem
> horrible to me on first impression. If it would open up the possibility
> of musl support.

Well I'm not sure. That's what we're trying to figure out. But I don't
think modifying it is a hard requirement, since it can be modified
from userspace if needed as long as signals are masked.

> > One reasonable thing to do, that might be preferable to
> > overengineered
> > solutions, is to disable shadow-stack process-wide if an interface
> > incompatible with it is used (sigaltstack, pthread_create with an
> > attribute setup using pthread_attr_setstack, makecontext, etc.), as
> > well as if an incompatible library is is dlopened.
> 
> I think it would be an interesting approach to determining
> compatibility.?On x86 there has been cases of binaries getting
> mismarked as supporting shadow stack. So an automated way of filtering
> some of those out would be very useful I think. I guess the dynamic
> linker could determine this based on some list of functions?

I didn't follow this whole mess, but from our side (musl) it does not
seem relevant. There are no legacy binaries wrongly marked because we
have never supported shadow stacks so far.

> The dlopen() bit gets complicated though. You need to disable shadow
> stack for all threads, which presumably the kernel could be coaxed into
> doing. But those threads might be using shadow stack instructions
> (INCSSP, RSTORSSP, etc). These are a collection of instructions that
> allow limited control of the SSP. When shadow stack gets disabled,
> these suddenly turn into #UD generating instructions. So any other
> threads executing those instructions when shadow stack got disabled
> would be in for a nasty surprise.

This is the kernel's problem if that's happening. It should be
trapping these and returning immediately like a NOP if shadow stack
has been disabled, not generating SIGILL.

> > The place where it's really needed to be able to allocate the shadow
> > stack synchronously under userspace control, in order to harden
> > normal
> > applications that aren't doing funny things, is in pthread_create
> > without a caller-provided stack.
> 
> Yea most apps don't do anything too tricky. Mostly shadow stack "just
> works". But it's no excuse to just crash for the others.

One thing to note here is that, to enable this, we're going to need
some way to detect "new enough kernel that shadow stack semantics are
all right". If there are kernels that have shadow stack support but
with problems that make it unsafe to use (this sounds like the case),
we can't turn it on without a way to avoid trying to use it on those.

Rich


From jeremy.linton at arm.com  Tue Feb 20 18:02:58 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Tue, 20 Feb 2024 20:02:58 -0600
Subject: [RFC] arm64: syscall: Direct PRNG kstack randomization
Message-ID: <20240221020258.1210148-1-jeremy.linton@arm.com>

The existing arm64 stack randomization uses the kernel rng to acquire
5 bits of address space randomization. This is problematic because it
creates non determinism in the syscall path when the rng needs to be
generated or reseeded. This shows up as large tail latencies in some
benchmarks and directly affects the minimum RT latencies as seen by
cyclictest.

Other architectures are using timers/cycle counters for this function,
which is sketchy from a randomization perspective because it should be
possible to estimate this value from knowledge of the syscall return
time, and from reading the current value of the timer/counters.

So, a poor rng should be better than the cycle counter if it is hard
to extract the stack offsets sufficiently to be able to detect the
PRNG's period.

So, we can potentially choose a 'better' or larger PRNG, going as far
as using one of the CSPRNGs already in the kernel, but the overhead
increases appropriately. Further, there are a few options for
reseeding, possibly out of the syscall path, but is it even useful in
this case?

Reported-by: James Yang <james.yang at arm.com>
Reported-by: Shiyou Huang <shiyou.huang at arm.com>
Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 arch/arm64/kernel/syscall.c | 55 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 9a70d9746b66..70143cb8c7be 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -37,6 +37,59 @@ static long __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
 	return syscall_fn(regs);
 }
 
+#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
+DEFINE_PER_CPU(u32, kstackrng);
+static u32 xorshift32(u32 state)
+{
+	/*
+	 * From top of page 4 of Marsaglia, "Xorshift RNGs"
+	 * This algorithm is intended to have a period 2^32 -1
+	 * And should not be used anywhere else outside of this
+	 * code path.
+	 */
+	state ^= state << 13;
+	state ^= state >> 17;
+	state ^= state << 5;
+	return state;
+}
+
+static u16 kstack_rng(void)
+{
+	u32 rng = raw_cpu_read(kstackrng);
+
+	rng = xorshift32(rng);
+	raw_cpu_write(kstackrng, rng);
+	return rng & 0x1ff;
+}
+
+/* Should we reseed? */
+static int kstack_rng_setup(unsigned int cpu)
+{
+	u32 rng_seed;
+
+	do {
+		rng_seed = get_random_u32();
+	} while (!rng_seed);
+	raw_cpu_write(kstackrng, rng_seed);
+	return 0;
+}
+
+static int kstack_init(void)
+{
+	int ret;
+
+	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/cpuinfo:kstackrandomize",
+				kstack_rng_setup, NULL);
+	if (ret < 0)
+		pr_err("kstack: failed to register rng callbacks.\n");
+	return 0;
+}
+
+arch_initcall(kstack_init);
+#else
+static u16 kstack_rng(void) { return 0; }
+#endif /* CONFIG_RANDOMIZE_KSTACK_OFFSET */
+
 static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
 			   unsigned int sc_nr,
 			   const syscall_fn_t syscall_table[])
@@ -66,7 +119,7 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
 	 *
 	 * The resulting 5 bits of entropy is seen in SP[8:4].
 	 */
-	choose_random_kstack_offset(get_random_u16() & 0x1FF);
+	choose_random_kstack_offset(kstack_rng());
 }
 
 static inline bool has_syscall_work(unsigned long flags)
-- 
2.43.0



From rick.p.edgecombe at intel.com  Tue Feb 20 18:11:23 2024
From: rick.p.edgecombe at intel.com (Edgecombe, Rick P)
Date: Wed, 21 Feb 2024 02:11:23 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in
 userspace
In-Reply-To: <20240221012736.GQ4163@brightrain.aerifal.cx>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
	 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
	 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
	 <20240220185714.GO4163@brightrain.aerifal.cx>
	 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
	 <20240220235415.GP4163@brightrain.aerifal.cx>
	 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
	 <20240221012736.GQ4163@brightrain.aerifal.cx>
Message-ID: <6332963a828d247ef935b7d3352fa1fbd83b11b0.camel@intel.com>

On Tue, 2024-02-20 at 20:27 -0500, dalias at libc.org wrote:
> > Then I think WRSS might fit your requirements better than what
> > glibc
> > did. It was considered a reduced security mode that made libc's job
> > much easier and had better compatibility, but the last discussion
> > was
> > to try to do it without WRSS.
> 
> Where can I read more about this? Some searches I tried didn't turn
> up
> much useful information.

There never was any proposal written down AFAIK. In the past we have
had a couple "shadow stack meetup" calls where folks who are working on
shadow stack got together to hash out some things. We discussed it
there.

But briefly, in the Intel SDM (and other places) there is documentation
on the special shadow stack instructions. The two key ones for this are
WRSS and RSTORSSP. WRSS is an instruction which can be enabled by the
kernel (and there is upstream support for this). The instruction can
write through shadow stack memory.

RSTORSSP can be used to consume a restore token, which is a special
value on the shadow stack. When this operations happens the SSP is
moved adjacent to the token that was just consumed. So between the two
of them the SSP can be adjusted to specific spots on the shadow stack
or another shadow stack.

Today when you longjmp() with shadow stack in glibc, INCSSP is used to
move the SSP back to the spot on the shadow stack where the setjmp()
was called. But this algorithm doesn't always work, for example,
longjmp()ing between stacks. To work around this glibc uses a scheme
where it searches from the target SSP for a shadow stack token and then
consumes it and INCSSPs back to the target SPP. It just barely
miraculously worked in most cases.

Some specific cases that were still open were longjmp()ing off of a
custom userspace threading library stack, which may not have left a
token behind when it jumped to a new stack. And also, potentially off
of an alt shadow stack in the future, depending on whether it leaves a
restore token when handling a signal. (the problem there, is if there
is no room to leave it).

So that is how x86 glic works, and I think arm was thinking along the
same lines. But if you have WRSS (and arm's version), you could just
write a restore token or anything else you need to fixup on the shadow
stack. Then you could longjmp() in one go without any high wire acts.
It's much simpler and more robust and would prevent needing to leave a
restore token when handling a signal to an alt shadow stack. Although,
nothing was ever prototyped. So "in theory".

But that is all about moving the SSP where you need it. It doesn't
resolve any of the allocation lifecycle issues. I think for those the
solutions are:
1. Not supporting ucontext/sigaltstack and shadow stack
2. Stefan's idea
3. A new interface that takes user allocated shadow stacks for those
operations

My preference has been a combination of 1 and 3. For threads, I think
Mark's clone3 enhancements will help.

Anyway, there is an attempt at a summary. I'd also point you to HJ for
more glibc context, as I mostly worked on the kernel side.

From xiaobo55x at gmail.com  Tue Feb 20 18:13:08 2024
From: xiaobo55x at gmail.com (Haibo Xu)
Date: Wed, 21 Feb 2024 10:13:08 +0800
Subject: [PATCH v5 11/12] KVM: riscv: selftests: Change vcpu_has_ext to a
 common function
In-Reply-To: <CAOnJCULwRTSnrQkR2o1P53R=tJ3TAxX+y+XRBesW6OFEzgFv2g@mail.gmail.com>
References: <cover.1705916069.git.haibo1.xu@intel.com> <68856b86a93a4188558e5d0ebac0dd6aac8e404c.1705916069.git.haibo1.xu@intel.com>
 <CAOnJCULwRTSnrQkR2o1P53R=tJ3TAxX+y+XRBesW6OFEzgFv2g@mail.gmail.com>
Message-ID: <CAJve8om2oOLg5-wKX7m7cBTgzwqiMcb35x=nDi1edY8evXjyMw@mail.gmail.com>

On Wed, Feb 21, 2024 at 7:03?AM Atish Patra <atishp at atishpatra.org> wrote:
>
> On Mon, Jan 22, 2024 at 1:48?AM Haibo Xu <haibo1.xu at intel.com> wrote:
> >
> > Move vcpu_has_ext to the processor.c and rename it to __vcpu_has_ext
> > so that other test cases can use it for vCPU extension check.
> >
> > Signed-off-by: Haibo Xu <haibo1.xu at intel.com>
> > Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> > ---
> >  tools/testing/selftests/kvm/include/riscv/processor.h |  2 ++
> >  tools/testing/selftests/kvm/lib/riscv/processor.c     | 10 ++++++++++
> >  tools/testing/selftests/kvm/riscv/get-reg-list.c      | 11 +----------
> >  3 files changed, 13 insertions(+), 10 deletions(-)
> >
> > diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> > index b68b1b731a34..bd27e1c67579 100644
> > --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> > +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> > @@ -42,6 +42,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
> >  #define RISCV_ISA_EXT_REG(idx) __kvm_reg_id(KVM_REG_RISCV_ISA_EXT, \
> >                                              idx, KVM_REG_SIZE_ULONG)
> >
> > +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
> > +
> >  struct ex_regs {
> >         unsigned long ra;
> >         unsigned long sp;
> > diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> > index 39a1e9902dec..dad73ce18164 100644
> > --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> > +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> > @@ -15,6 +15,16 @@
> >
> >  static vm_vaddr_t exception_handlers;
> >
> > +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> > +{
> > +       unsigned long value = 0;
> > +       int ret;
> > +
> > +       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> > +
> > +       return !ret && !!value;
> > +}
> > +
>
> Not sure what was the base patch on which this was rebased. The actual
> commit in the queue branch looks different.
>

This patch set was based on 6.7-rc8.

> https://github.com/kvm-riscv/linux/commit/5563517cc2012e3326411b360c9924d3f2706c8d
>
> Both seem to have the same bug though the tests fail now and require
> the following fix.
> The ext id should be uint64_t and we need to pass ext directly so that
> SBI extension tests can also pass.
>

It's weird that 6.7-rc8 has already included Andrew's change on the ISA ext reg,
but this patch was not generated against his change.

commit bdf6aa328f137e184b0fce607fd585354c3742f1
Author: Andrew Jones <ajones at ventanamicro.com>
Date:   Wed Dec 13 18:09:58 2023 +0100

    RISC-V: KVM: selftests: Treat SBI ext regs like ISA ext regs

Anyway, your changes were right. Please go ahead to include them when merging.

Thanks,
Haibo

>
> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> @@ -48,7 +48,7 @@ static inline uint64_t __kvm_reg_id(uint64_t type,
> uint64_t subtype,
> KVM_REG_RISCV_SBI_SINGLE, \
> idx, KVM_REG_SIZE_ULONG)
>
> -bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext);
>
> struct ex_regs {
> unsigned long ra;
> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c
> b/tools/testing/selftests/kvm/lib/riscv/processor.c
> index 282587cd4bbc..ec66d331a127 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> @@ -15,12 +15,12 @@
>
> static vm_vaddr_t exception_handlers;
>
> -bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext)
> {
> unsigned long value = 0;
> int ret;
>
> - ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> + ret = __vcpu_get_reg(vcpu, ext, &value);
>
> return !ret && !!value;
> }
>
> With the above the fix, Both SBI/ISA extension tests pass.
> # ./get-reg-list
> sbi-base: PASS
> sbi-sta: PASS
> sbi-pmu: PASS
> sbi-dbcn: PASS
> aia: PASS
> fp_f: PASS
> fp_d: PASS
> 1..0 # SKIP - h not available, skipping tests
> smstateen: PASS
> sscofpmf: PASS
> sstc: PASS
> 1..0 # SKIP - svinval not available, skipping tests
> 1..0 # SKIP - svnapot not available, skipping tests
> 1..0 # SKIP - svpbmt not available, skipping tests
> zba: PASS
> zbb: PASS
> zbc: PASS
> 1..0 # SKIP - zbkb not available, skipping tests
> 1..0 # SKIP - zbkc not available, skipping tests
> 1..0 # SKIP - zbkx not available, skipping tests
> zbs: PASS
> zfa: PASS
> 1..0 # SKIP - zfh not available, skipping tests
> 1..0 # SKIP - zfhmin not available, skipping tests
> zicbom: PASS
> zicboz: PASS
> zicntr: PASS
> 1..0 # SKIP - zicond not available, skipping tests
> zicsr: PASS
> zifencei: PASS
> zihintntl: PASS
> zihintpause: PASS
> zihpm: PASS
>
>
> >  static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
> >  {
> >         return (v + vm->page_size) & ~(vm->page_size - 1);
> > diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > index 25de4b8bc347..ed29ba45588c 100644
> > --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > @@ -75,15 +75,6 @@ bool check_reject_set(int err)
> >         return err == EINVAL;
> >  }
> >
> > -static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> > -{
> > -       int ret;
> > -       unsigned long value;
> > -
> > -       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> > -       return (ret) ? false : !!value;
> > -}
> > -
> >  void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
> >  {
> >         unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
> > @@ -111,7 +102,7 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
> >                 __vcpu_set_reg(vcpu, RISCV_ISA_EXT_REG(s->feature), 1);
> >
> >                 /* Double check whether the desired extension was enabled */
> > -               __TEST_REQUIRE(vcpu_has_ext(vcpu, s->feature),
> > +               __TEST_REQUIRE(__vcpu_has_ext(vcpu, s->feature),
> >                                "%s not available, skipping tests\n", s->name);
> >         }
> >  }
> > --
> > 2.34.1
> >
>
>
> --
> Regards,
> Atish


From zhangzj at rock-chips.com  Tue Feb 20 18:29:01 2024
From: zhangzj at rock-chips.com (Elon Zhang)
Date: Wed, 21 Feb 2024 10:29:01 +0800
Subject: [PATCH v3 1/2] arm64: dts: rockchip: Add devicetree support for TB-RK3588X board
Message-ID: <20240221022902.751528-1-zhangzj@rock-chips.com>

Add board file for Rockchip Toybrick TB-RK3588X board.

Specification:
	Rockchip Rk3588 SoC
	4x ARM Cortex-A76, 4x ARM Cortex-A55
	8/16GB Memory LPDDR4x
	Mali G610MC4 GPU
	2? MIPI-CSI0 Connector
	1x 2Lanes PCIe3.0 Connector
	1x SATA3.0 Connector
	32GB eMMC Module
	2x USB 2.0, 2x USB 3.0
	1x HDMI Output, 1x HDMI Input
	2x Ethernet Port

Functions work normally:
	[1] USB2.0 Host
	[2] Ethernet0 with PHY RTL8211F

More information can be obtained from the following websites:
	[1] https://t.rock-chips.com/en/wiki/EN/tb-rk3588x_en/index.html
	[2] http://t.rock-chips.com/

Reviewed-by: Weizhao Ouyang <weizhao.ouyang at arm.com>
Signed-off-by: Elon Zhang <zhangzj at rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3588-toybrick-x0.dts  | 672 ++++++++++++++++++
 2 files changed, 673 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index a7b30e11beaf..e0722b6e2d99 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -110,6 +110,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-orangepi-5-plus.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-quartzpro64.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-toybrick-x0.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-turing-rk1.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-coolpi-4b.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
new file mode 100644
index 000000000000..f3f7c1d35ed2
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
@@ -0,0 +1,672 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588.dtsi"
+
+/ {
+	model = "Rockchip Toybrick TB-RK3588X Board";
+	compatible = "rockchip,rk3588-toybrick-x0", "rockchip,rk3588";
+
+	aliases {
+		mmc0 = &sdhci;
+		serial2 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-vol-up {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <17000>;
+		};
+
+		button-vol-down {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			press-threshold-microvolt = <417000>;
+		};
+
+		button-menu {
+			label = "Menu";
+			linux,code = <KEY_MENU>;
+			press-threshold-microvolt = <890000>;
+		};
+
+		button-escape {
+			label = "Escape";
+			linux,code = <KEY_ESC>;
+			press-threshold-microvolt = <1235000>;
+		};
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		power-supply = <&vcc12v_dcin>;
+		pwms = <&pwm2 0 25000 0>;
+	};
+
+	pcie20_avdd0v85: pcie20-avdd0v85-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie20_avdd0v85";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <850000>;
+		regulator-max-microvolt = <850000>;
+		vin-supply = <&vdd_0v85_s0>;
+	};
+
+	pcie20_avdd1v8: pcie20-avdd1v8-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie20_avdd1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&avcc_1v8_s0>;
+	};
+
+	pcie30_avdd0v75: pcie30-avdd0v75-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie30_avdd0v75";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <750000>;
+		regulator-max-microvolt = <750000>;
+		vin-supply = <&avdd_0v75_s0>;
+	};
+
+	pcie30_avdd1v8: pcie30-avdd1v8-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie30_avdd1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&avcc_1v8_s0>;
+	};
+
+	vcc12v_dcin: vcc12v-dcin-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc5v0_host: vcc5v0-host-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_host";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_host_en>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usbdcin: vcc5v0-usbdcin-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usbdcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usb: vcc5v0-usb-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usb";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usbdcin>;
+	};
+
+	vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v1_nldo_s3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+};
+
+&combphy0_ps {
+	status = "okay";
+};
+
+&combphy2_psu {
+	status = "okay";
+};
+
+&cpu_b0 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gmac0 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy>;
+	phy-mode = "rgmii-rxid";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+	pinctrl-names = "default";
+	rx_delay = <0x00>;
+	tx_delay = <0x43>;
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0m2_xfer>;
+	status = "okay";
+
+	vdd_cpu_big0_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu_big0_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	vdd_cpu_big1_s0: regulator at 43 {
+		compatible = "rockchip,rk8603", "rockchip,rk8602";
+		reg = <0x43>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu_big1_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	hym8563: rtc at 51 {
+		compatible = "haoyu,hym8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+		clock-output-names = "hym8563";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hym8563_int>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PD4 IRQ_TYPE_LEVEL_LOW>;
+		wakeup-source;
+	};
+};
+
+&mdio0 {
+	rgmii_phy: ethernet-phy at 1 {
+		/* RTL8211F */
+		compatible = "ethernet-phy-id001c.c916";
+		reg = <0x1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtl8211f_rst>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pinctrl {
+	rtl8211f {
+		rtl8211f_rst: rtl8211f-rst {
+			rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+	};
+
+	hym8563 {
+		hym8563_int: hym8563-int {
+			rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	usb {
+		vcc5v0_host_en: vcc5v0-host-en {
+			rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pwm2 {
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcc_1v8_s0>;
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	no-sdio;
+	no-sd;
+	non-removable;
+	mmc-hs400-1_8v;
+	mmc-hs400-enhanced-strobe;
+	status = "okay";
+};
+
+&spi2 {
+	status = "okay";
+	assigned-clocks = <&cru CLK_SPI2>;
+	assigned-clock-rates = <200000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+	num-cs = <1>;
+
+	pmic at 0 {
+		compatible = "rockchip,rk806";
+		spi-max-frequency = <1000000>;
+		reg = <0x0>;
+
+		interrupt-parent = <&gpio0>;
+		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+		system-power-controller;
+
+		vcc1-supply = <&vcc5v0_sys>;
+		vcc2-supply = <&vcc5v0_sys>;
+		vcc3-supply = <&vcc5v0_sys>;
+		vcc4-supply = <&vcc5v0_sys>;
+		vcc5-supply = <&vcc5v0_sys>;
+		vcc6-supply = <&vcc5v0_sys>;
+		vcc7-supply = <&vcc5v0_sys>;
+		vcc8-supply = <&vcc5v0_sys>;
+		vcc9-supply = <&vcc5v0_sys>;
+		vcc10-supply = <&vcc5v0_sys>;
+		vcc11-supply = <&vcc_2v0_pldo_s3>;
+		vcc12-supply = <&vcc5v0_sys>;
+		vcc13-supply = <&vcc_1v1_nldo_s3>;
+		vcc14-supply = <&vcc_1v1_nldo_s3>;
+		vcca-supply = <&vcc5v0_sys>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		rk806_dvs1_null: dvs1-null-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs2_null: dvs2-null-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs3_null: dvs3-null-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun0";
+		};
+
+		regulators {
+			vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_gpu_s0";
+				regulator-enable-ramp-delay = <400>;
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_cpu_lit_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_log_s0: dcdc-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <750000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_log_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-init-microvolt = <750000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_vdenc_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_ddr_s0: dcdc-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <900000>;
+				regulator-ramp-delay = <12500>;
+				regulator-name = "vdd_ddr_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vdd2_ddr_s3: dcdc-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vdd2_ddr_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_2v0_pldo_s3: dcdc-reg7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <2000000>;
+				regulator-max-microvolt = <2000000>;
+				regulator-name = "vdd_2v0_pldo_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <2000000>;
+				};
+			};
+
+			vcc_3v3_s3: dcdc-reg8 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_3v3_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vddq_ddr_s0: dcdc-reg9 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vddq_ddr_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s3: dcdc-reg10 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			avcc_1v8_s0: pldo-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "avcc_1v8_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s0: pldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			avdd_1v2_s0: pldo-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-name = "avdd_1v2_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3_s0: pldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc_3v3_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd_s0: pldo-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_sd_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			pldo6_s3: pldo-reg6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "pldo6_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_0v75_s3: nldo-reg1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdd_0v75_s3";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_ddr_pll_s0: nldo-reg2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdd_ddr_pll_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			avdd_0v75_s0: nldo-reg3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <837500>;
+				regulator-max-microvolt = <837500>;
+				regulator-name = "avdd_0v75_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_0v85_s0: nldo-reg4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-name = "vdd_0v85_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_0v75_s0: nldo-reg5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+				regulator-name = "vdd_0v75_s0";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&u2phy2 {
+	status = "okay";
+};
+
+&u2phy2_host {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+&u2phy3 {
+	status = "okay";
+};
+
+&u2phy3_host {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-0 = <&uart2m0_xfer>;
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
-- 
2.34.1



From zhangzj at rock-chips.com  Tue Feb 20 18:29:02 2024
From: zhangzj at rock-chips.com (Elon Zhang)
Date: Wed, 21 Feb 2024 10:29:02 +0800
Subject: [PATCH v3 2/2] dt-bindings: arm: rockchip: Add Toybrick TB-RK3588X
In-Reply-To: <20240221022902.751528-1-zhangzj@rock-chips.com>
References: <20240221022902.751528-1-zhangzj@rock-chips.com>
Message-ID: <20240221022902.751528-2-zhangzj@rock-chips.com>

Add devicetree binding for Toybrick TB-RK3588X board from Rockchip Toybrick.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Weizhao Ouyang <weizhao.ouyang at arm.com>
Signed-off-by: Elon Zhang <zhangzj at rock-chips.com>
---
 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 5cf5cbef2cf5..d29df97c7b25 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -878,6 +878,11 @@ properties:
           - const: rockchip,rv1108-evb
           - const: rockchip,rv1108
 
+      - description: Rockchip Toybrick TB-RK3588X board
+        items:
+          - const: rockchip,rk3588-toybrick-x0
+          - const: rockchip,rk3588
+
       - description: Theobroma Systems PX30-uQ7 with Haikou baseboard
         items:
           - const: tsd,px30-ringneck-haikou
-- 
2.34.1



From dongmenglong.8 at bytedance.com  Tue Feb 20 18:35:34 2024
From: dongmenglong.8 at bytedance.com (=?UTF-8?B?5qKm6b6Z6JGj?=)
Date: Wed, 21 Feb 2024 10:35:34 +0800
Subject: [External] Re: [PATCH bpf-next 0/5] bpf: make tracing program
 support multi-attach
In-Reply-To: <CAADnVQ+E4ygZV6dcs8wj5FdFz9bfrQ=61235uiRoxe9RqQvR9Q@mail.gmail.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com> <CAADnVQ+E4ygZV6dcs8wj5FdFz9bfrQ=61235uiRoxe9RqQvR9Q@mail.gmail.com>
Message-ID: <CALz3k9g__P+UdO2vLPrR5Y4sQonQJjOnGPNmhmxtRfhLKoV7Rg@mail.gmail.com>

Hello,

On Wed, Feb 21, 2024 at 9:24?AM Alexei Starovoitov
<alexei.starovoitov at gmail.com> wrote:
>
> On Mon, Feb 19, 2024 at 7:51?PM Menglong Dong
> <dongmenglong.8 at bytedance.com> wrote:
> >
> > For now, the BPF program of type BPF_PROG_TYPE_TRACING is not allowed to
> > be attached to multiple hooks, and we have to create a BPF program for
> > each kernel function, for which we want to trace, even through all the
> > program have the same (or similar) logic. This can consume extra memory,
> > and make the program loading slow if we have plenty of kernel function to
> > trace.
>
> Should this be combined with multi link ?
> (As was recently done for kprobe_multi and uprobe_multi).
> Loading fentry prog once and attaching it through many bpf_links
> to multiple places is a nice addition,
> but we should probably add a multi link right away too.

I was planning to implement the multi link for tracing after this
series in another series. I can do it together with this series
if you prefer.

Thanks!
Menglong Dong


From zhi.mao at mediatek.com  Tue Feb 20 18:37:27 2024
From: zhi.mao at mediatek.com (=?utf-8?B?WmhpIE1hbyAo5q+b5pm6KQ==?=)
Date: Wed, 21 Feb 2024 02:37:27 +0000
Subject: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <ZdRUB92gkbRGPyr_@kekkonen.localdomain>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
	 <20240204061538.2105-3-zhi.mao@mediatek.com>
	 <20240206184542.GE2827@pendragon.ideasonboard.com>
	 <598f62bbb55157eec1e23dd1dbc307fea3851b21.camel@mediatek.com>
	 <20240220030104.GF20376@pendragon.ideasonboard.com>
	 <115698c0c549e747026cc8841a3bd571533f8e6f.camel@mediatek.com>
	 <ZdRUB92gkbRGPyr_@kekkonen.localdomain>
Message-ID: <063fa9763efb1570295cfef385829714dd5e42cf.camel@mediatek.com>

Hi Laurent & sakari,

Thanks for your feedback.

On Tue, 2024-02-20 at 07:25 +0000, sakari.ailus at linux.intel.com wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  Hi Zhi,
> 
> On Tue, Feb 20, 2024 at 05:45:54AM +0000, Zhi Mao (??) wrote:
> > Hi Laurent,
> > 
> > Thanks for you reply.
> > I'd like to ask for advice about how to contrl "reset-pin", please
> > check the below comments.
> > 
> > On Tue, 2024-02-20 at 05:01 +0200, Laurent Pinchart wrote:
> > >   
> > > External email : Please do not click links or open attachments
> until
> > > you have verified the sender or the content.
> > >  Hi Zhi,
> > > 
> > > On Tue, Feb 20, 2024 at 02:12:26AM +0000, Zhi Mao (??) wrote:
> > > > On Tue, 2024-02-06 at 20:45 +0200, Laurent Pinchart wrote:
> > > > > On Sun, Feb 04, 2024 at 02:15:38PM +0800, Zhi Mao wrote:
> > > > > > Add a V4L2 sub-device driver for Galaxycore GC08A3 image
> > > sensor.
> > > > > >
> > > > > > Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> > > > > > ---
> > > > > >  drivers/media/i2c/Kconfig  |   10 +
> > > > > >  drivers/media/i2c/Makefile |    1 +
> > > > > >  drivers/media/i2c/gc08a3.c | 1448
> > > ++++++++++++++++++++++++++++++++++++
> > > > > >  3 files changed, 1459 insertions(+)
> > > > > >  create mode 100644 drivers/media/i2c/gc08a3.c
> > > 
> > > [snip]
> > > 
> > > > > > diff --git a/drivers/media/i2c/gc08a3.c
> > > b/drivers/media/i2c/gc08a3.c
> > > > > > new file mode 100644
> > > > > > index 000000000000..3fc7fffb815c
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/media/i2c/gc08a3.c
> > > > > > @@ -0,0 +1,1448 @@
> > > 
> > > [snip]
> > > 
> > > > > > +static int gc08a3_power_on(struct device *dev)
> > > > > > +{
> > > > > > +struct i2c_client *client = to_i2c_client(dev);
> > > > > > +struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > > > > > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > > > > > +int ret;
> > > > > > +
> > > > > > +ret =
> regulator_bulk_enable(ARRAY_SIZE(gc08a3_supply_name),
> > > > > > +    gc08a3->supplies);
> > > > > > +if (ret < 0) {
> > > > > > +dev_err(gc08a3->dev, "failed to enable regulators: %d\n",
> > > ret);
> > > > > > +return ret;
> > > > > > +}
> > > > > > +
> > > > > > +ret = clk_prepare_enable(gc08a3->xclk);
> > > > > > +if (ret < 0) {
> > > > > > +regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
> > > > > > +       gc08a3->supplies);
> > > > > > +dev_err(gc08a3->dev, "clk prepare enable failed\n");
> > > > > > +return ret;
> > > > > > +}
> > > > > > +
> > > > > > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > > > > > +
> > > > > > +gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > > > >
> > > > > Are you asserting reset when powering on ? That sounds wrong,
> you
> > > should
> > > > > de-assert reset here (and acquire the reset gpio in probe()
> with
> > > > > GPIOD_OUT_HIGH). Drivers should use logical levels for GPIOs,
> > > setting a
> > > > > GPIO named "reset" to 1 should assert the reset signal, even
> if
> > > the
> > > > > physical signal is active low. You may have the wrong
> polarity in
> > > the
> > > > > device tree.
> > > >
> > > > According to the sensor power sequence sepc, "reset" pin should
> be
> > > pull
> > > > from low to high after "dovdd/dvdd/avdd" power on, so I follow
> this
> > > > power sequece to pull "reset" pin high in software flow.
> > > 
> > > From a hardware point of view that's right, but the Linux kernel
> > > handles
> > > logical level of GPIOs. If a GPIO is named "reset", it is
> expected
> > > that
> > > calling
> > > 
> > > gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > > 
> > > will "assert" the reset signal, setting it to a logical "reset =
> > > true"
> > > level. This maps to the hardware 0V output level, as the signal
> is
> > > active-low. To achieve this, define the reset GPIO as active low
> in
> > > DT,
> > > and the GPIO framework will invert the signal for you. You should
> > > then
> > > call
> > > 
> > > gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > > 
> > > in the driver when you want to assert reset (set it to 0V), and
> > > 
> > > gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);
> > > 
> > > when you want to deassert it (set it to 3.3V, or whatever the I/O
> > > voltage for the signal is).
> > > 
> > > This way all driver use logical states, and the inversion is
> handled
> > > in
> > > DT.
> > > 
> > 
> > Sensor power sequence as below:
> >                       ------------------
> >                      | | |
> >                      | | | 
> > dvdd/avdd/dovdd  --------
> >                                ---------
> >                               |
> >                               |
> > reset-pin        -------------
> > 
> > In order to match this power sequece, "reset-pin" contrl flow is
> below:
> > 1. config the "reset-pin" is "active-high" in DTS:
> >     reset-gpios = <&pio 19 GPIO_ACTIVE_HIGH>;
> > 
> > 2. image sensor driver probe function:
> > gc08a3->reset_gpio = devm_gpiod_get(dev, "reset",
> > GPIOD_OUT_LOW);  //init "reset-pin" is low
> > 
> > 3. image sensor driver power_on function:
> > gpiod_set_value_cansleep(gc08a3->reset_gpio, 1); //pull "reset-pin"
> > high 
> > 
> > so, the expect state of "reset-pin" is from low to high.
> > If I am wrong, please correct me.
> 
> 
> From Documentation/driver-api/gpio/consumer.rst:
> 
> As a consumer should not have to care about the physical line
> level, all of the gpiod_set_value_xxx() or
> gpiod_set_array_value_xxx() functions operate with the *logical*
> value. With this they take the active low property into account.
> This means that they check whether the GPIO is configured to be
> active low, and if so, they manipulate the passed value before the
> physical line level is driven.
> 
> I.e. when you want to enable reset, you set the value to 1 in the
> driver. I
> think you're now setting the value to 0 in that case. The opposite
> for
> disabling it of course.
> 
After checking "Documentation/driver-api/gpio/consumer.rst":
To summarize::
  Function (example)                 line property          physical
line
...
  gpiod_set_value(desc, 1);          default (active high)  high
  gpiod_set_value(desc, 0);          active low             high
...


From my understanding, it seems that "reset-pin" is using the
following(active_high) case in current code: 
"gpiod_set_value(desc, 1);          default (active high)  high" 

Do you mean, we should use the "active_low" case:
"gpiod_set_value(desc, 0);          active low             high"
Code should be changed as below:
1. config the "reset-pin" is "active-low" in DTS:
   - reset-gpios = <&pio 19 GPIO_ACTIVE_LOW>
2. image sensor driver power_on function:
   - gpiod_set_value_cansleep(gc08a3->reset_gpio, 0); //pull high 
Is that so?


> -- 
> Regards,
> 
> Sakari Ailus

From andrew at codeconstruct.com.au  Tue Feb 20 18:41:35 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Wed, 21 Feb 2024 13:11:35 +1030
Subject: [PATCH] dt-bindings: gpio: Convert Aspeed binding to YAML schema
In-Reply-To: <0d1dd262-b6dd-4d71-9239-8b0aec8cceff@linaro.org>
References: <20240220052918.742793-1-andrew@codeconstruct.com.au>
	 <0d1dd262-b6dd-4d71-9239-8b0aec8cceff@linaro.org>
Message-ID: <18dfd5f2eff5049fa5e3a098490dc601cf146f96.camel@codeconstruct.com.au>

Hi Krzysztof, thanks for the feedback.

On Tue, 2024-02-20 at 09:27 +0100, Krzysztof Kozlowski wrote:
> > On 20/02/2024 06:29, Andrew Jeffery wrote:
> > > > Squash warnings such as:
> > > > 
> > 
> > Missing subject prefix: aspeed,ast2400-gpio
> > 
> > 
> > > > ```
> > > > arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-galaxy100.dtb: /ahb/apb at 1e600000/gpio at 1e780000: failed to match any schema with compatible: ['aspeed,ast2400-gpio']
> > > > ```
> > > > 
> > > > Signed-off-by: Andrew Jeffery <andrew at codeconstruct.com.au>
> > 
> > Thank you for your patch. There is something to discuss/improve.
> > 
> > 
> > > > ---
> > > >  .../bindings/gpio/aspeed,ast2400-gpio.yaml    | 64 +++++++++++++++++++
> > > >  .../devicetree/bindings/gpio/gpio-aspeed.txt  | 39 -----------
> > > >  2 files changed, 64 insertions(+), 39 deletions(-)
> > > >  create mode 100644 Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
> > > >  delete mode 100644 Documentation/devicetree/bindings/gpio/gpio-aspeed.txt
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
> > > > new file mode 100644
> > > > index 000000000000..353c7620013f
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
> > > > @@ -0,0 +1,64 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/gpio/aspeed,ast2400-gpio.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Aspeed GPIO controller
> > > > +
> > > > +maintainers:
> > > > +  - Andrew Jeffery <andrew at codeconstruct.com.au>
> > > > +
> > > > +allOf:
> > > > +  - $ref: /schemas/gpio/gpio.yaml#
> > 
> > From where did you take it? None of the bindings have such code. Start
> > from recent bindings in given category when writing new ones.

I didn't take it from anywhere so much as try to apply some reasoning
via the commentary in the example at [1]. Maybe I could have fought
that approach by contrasting what I wrote to a wider set of existing
binding documents (I did look at some and obviously didn't find
anything similar).

Anyway reflecting on the misunderstanding, is the ref unnecessary
because the gpio binding sets `select: true`[2] and so is applied to
the node regardless?

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/example-schema.yaml?h=v6.7#n238
[2]: https://github.com/devicetree-org/dt-schema/blob/v2023.11/dtschema/schemas/gpio/gpio.yaml#L12

> > 
> > Please drop it.

Ack.

> > 
> > > > +  - if:
> > > > +      properties:
> > > > +        compatible:
> > > > +          contains:
> > > > +            const: aspeed,ast2600-gpio
> > > > +    then:
> > > > +      required:
> > > > +        - ngpios
> > 
> > Please put entire allOf: after required: block. That's the convention
> > when it has something more than $ref, because we still want the most
> > important parts at the top of the file.

Ack.

> > 
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +    enum:
> > > > +      - aspeed,ast2400-gpio
> > > > +      - aspeed,ast2500-gpio
> > > > +      - aspeed,ast2600-gpio
> > > > +
> > > > +  reg:
> > > > +    maxItems: 1
> > > > +
> > > > +  clocks:
> > > > +    maxItems: 1
> > > > +    description: The clock to use for debounce timings
> > > > +
> > > > +  interrupts:
> > > > +    maxItems: 1
> > > > +
> > > > +  interrupt-controller: true
> > > > +
> > > > +  "#interrupt-cells":
> > > > +    const: 2
> > > > +
> > 
> > ngpios with some constraints

Is this just with regard to the constraints I have under allOf above?
Or something further (constrain the values of ngpios for the various
controllers across the Aspeed SoCs)?

Maybe I'll look at some more of the existing bindings for this as
well...

> > 
> > > > +required:
> > > > +  - compatible
> > > > +  - reg
> > > > +  - interrupts
> > > > +  - interrupt-controller
> > > > +  - "#gpio-cells"
> > > > +  - gpio-controller
> > > > +
> > > > +unevaluatedProperties: false
> > 
> > Instead additionalProperties: false.

Ack - this is the same misunderstanding as the gpio schema ref
discussed above.

Andrew



From dongmenglong.8 at bytedance.com  Tue Feb 20 18:45:47 2024
From: dongmenglong.8 at bytedance.com (=?UTF-8?B?5qKm6b6Z6JGj?=)
Date: Wed, 21 Feb 2024 10:45:47 +0800
Subject: [External] Re: [PATCH bpf-next 0/5] bpf: make tracing program
 support multi-attach
In-Reply-To: <CALz3k9g__P+UdO2vLPrR5Y4sQonQJjOnGPNmhmxtRfhLKoV7Rg@mail.gmail.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
 <CAADnVQ+E4ygZV6dcs8wj5FdFz9bfrQ=61235uiRoxe9RqQvR9Q@mail.gmail.com> <CALz3k9g__P+UdO2vLPrR5Y4sQonQJjOnGPNmhmxtRfhLKoV7Rg@mail.gmail.com>
Message-ID: <CALz3k9h8CoAP8+ZmNvNGeXL9D_Q83Ovrubz9zHECr6C0TXuoVg@mail.gmail.com>

On Wed, Feb 21, 2024 at 10:35?AM ??? <dongmenglong.8 at bytedance.com> wrote:
>
> Hello,
>
> On Wed, Feb 21, 2024 at 9:24?AM Alexei Starovoitov
> <alexei.starovoitov at gmail.com> wrote:
> >
> > On Mon, Feb 19, 2024 at 7:51?PM Menglong Dong
> > <dongmenglong.8 at bytedance.com> wrote:
> > >
> > > For now, the BPF program of type BPF_PROG_TYPE_TRACING is not allowed to
> > > be attached to multiple hooks, and we have to create a BPF program for
> > > each kernel function, for which we want to trace, even through all the
> > > program have the same (or similar) logic. This can consume extra memory,
> > > and make the program loading slow if we have plenty of kernel function to
> > > trace.
> >
> > Should this be combined with multi link ?
> > (As was recently done for kprobe_multi and uprobe_multi).
> > Loading fentry prog once and attaching it through many bpf_links
> > to multiple places is a nice addition,
> > but we should probably add a multi link right away too.
>
> I was planning to implement the multi link for tracing after this
> series in another series. I can do it together with this series
> if you prefer.
>

Should I introduce the multi link for tracing first, then this series?
(Furthermore, this series seems not necessary.)

> Thanks!
> Menglong Dong


From dongmenglong.8 at bytedance.com  Tue Feb 20 18:58:30 2024
From: dongmenglong.8 at bytedance.com (=?UTF-8?B?5qKm6b6Z6JGj?=)
Date: Wed, 21 Feb 2024 10:58:30 +0800
Subject: [External] Re: [PATCH bpf-next 1/5] bpf: tracing: add support to
 record and check the accessed args
In-Reply-To: <ZdTe8LteoqR43d4q@krava>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
 <20240220035105.34626-2-dongmenglong.8@bytedance.com> <ZdTe8LteoqR43d4q@krava>
Message-ID: <CALz3k9juJUBDV=wyCG7Ru6_OcMCpArL5MSGWrsb5xhx=u4+N2g@mail.gmail.com>

On Wed, Feb 21, 2024 at 1:18?AM Jiri Olsa <olsajiri at gmail.com> wrote:
>
> On Tue, Feb 20, 2024 at 11:51:01AM +0800, Menglong Dong wrote:
>
> SNIP
>
> > +static int get_ctx_arg_idx_aligned(struct btf *btf, const struct btf_type *t,
> > +                                int off)
> > +{
> > +     const struct btf_param *args;
> > +     u32 offset = 0, nr_args;
> > +     int i;
> > +
> > +     nr_args = btf_type_vlen(t);
> > +     args = (const struct btf_param *)(t + 1);
> > +     for (i = 0; i < nr_args; i++) {
> > +             if (offset == off)
> > +                     return i;
> > +
> > +             t = btf_type_skip_modifiers(btf, args[i].type, NULL);
> > +             offset += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
> > +             if (offset > off)
> > +                     return -1;
> > +     }
> > +     return -1;
> > +}
> > +
> > +/* This function is similar to btf_check_func_type_match(), except that it
> > + * only compare some function args of the function prototype t1 and t2.
> > + */
>
> could we reuse btf_check_func_type_match instead? perhaps just
> adding extra argument with arguments bitmap to it?
>

This is a little difficult, as the way we check the consistency of t1
and t2 is a little different.

in btf_check_func_type_match(), we check the args of t1 and t2
by index. But in btf_check_func_part_match(), we check the args
of t1 and t2 by offset. Reusing can make btf_check_func_type_match
become complex and hard to understand.

Anyway, let me have a try to see if it works to reuse
btf_check_func_type_match().

Thanks!
Menglong Dong

> jirka
>
> > +int btf_check_func_part_match(struct btf *btf1, const struct btf_type *func1,
> > +                           struct btf *btf2, const struct btf_type *func2,
> > +                           u64 func_args)
> > +{
> > +     const struct btf_param *args1, *args2;
> > +     u32 nargs1, i, offset = 0;
> > +     const char *s1, *s2;
> > +
> > +     if (!btf_type_is_func_proto(func1) || !btf_type_is_func_proto(func2))
> > +             return -EINVAL;
> > +
> > +     args1 = (const struct btf_param *)(func1 + 1);
> > +     args2 = (const struct btf_param *)(func2 + 1);
> > +     nargs1 = btf_type_vlen(func1);
> > +
> > +     for (i = 0; i <= nargs1; i++) {
> > +             const struct btf_type *t1, *t2;
> > +
> > +             if (!(func_args & (1 << i)))
> > +                     goto next;
> > +
> > +             if (i < nargs1) {
> > +                     int t2_index;
> > +
> > +                     /* get the index of the arg corresponding to args1[i]
> > +                      * by the offset.
> > +                      */
> > +                     t2_index = get_ctx_arg_idx_aligned(btf2, func2,
> > +                                                        offset);
> > +                     if (t2_index < 0)
> > +                             return -EINVAL;
> > +
> > +                     t1 = btf_type_skip_modifiers(btf1, args1[i].type, NULL);
> > +                     t2 = btf_type_skip_modifiers(btf2, args2[t2_index].type,
> > +                                                  NULL);
> > +             } else {
> > +                     /* i == nargs1, this is the index of return value of t1 */
> > +                     if (get_ctx_arg_total_size(btf1, func1) !=
> > +                         get_ctx_arg_total_size(btf2, func2))
> > +                             return -EINVAL;
> > +
> > +                     /* check the return type of t1 and t2 */
> > +                     t1 = btf_type_skip_modifiers(btf1, func1->type, NULL);
> > +                     t2 = btf_type_skip_modifiers(btf2, func2->type, NULL);
> > +             }
> > +
> > +             if (t1->info != t2->info ||
> > +                 (btf_type_has_size(t1) && t1->size != t2->size))
> > +                     return -EINVAL;
> > +             if (btf_type_is_int(t1) || btf_is_any_enum(t1))
> > +                     goto next;
> > +
> > +             if (btf_type_is_struct(t1))
> > +                     goto on_struct;
> > +
> > +             if (!btf_type_is_ptr(t1))
> > +                     return -EINVAL;
> > +
> > +             t1 = btf_type_skip_modifiers(btf1, t1->type, NULL);
> > +             t2 = btf_type_skip_modifiers(btf2, t2->type, NULL);
> > +             if (!btf_type_is_struct(t1) || !btf_type_is_struct(t2))
> > +                     return -EINVAL;
> > +
> > +on_struct:
> > +             s1 = btf_name_by_offset(btf1, t1->name_off);
> > +             s2 = btf_name_by_offset(btf2, t2->name_off);
> > +             if (strcmp(s1, s2))
> > +                     return -EINVAL;
> > +next:
> > +             if (i < nargs1) {
> > +                     t1 = btf_type_skip_modifiers(btf1, args1[i].type, NULL);
> > +                     offset += btf_type_is_ptr(t1) ? 8 : roundup(t1->size, 8);
> > +             }
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> >  static bool btf_is_dynptr_ptr(const struct btf *btf, const struct btf_type *t)
> >  {
> >       const char *name;
> > --
> > 2.39.2
> >


From alexei.starovoitov at gmail.com  Tue Feb 20 19:02:03 2024
From: alexei.starovoitov at gmail.com (Alexei Starovoitov)
Date: Tue, 20 Feb 2024 19:02:03 -0800
Subject: [External] Re: [PATCH bpf-next 0/5] bpf: make tracing program
 support multi-attach
In-Reply-To: <CALz3k9h8CoAP8+ZmNvNGeXL9D_Q83Ovrubz9zHECr6C0TXuoVg@mail.gmail.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
 <CAADnVQ+E4ygZV6dcs8wj5FdFz9bfrQ=61235uiRoxe9RqQvR9Q@mail.gmail.com>
 <CALz3k9g__P+UdO2vLPrR5Y4sQonQJjOnGPNmhmxtRfhLKoV7Rg@mail.gmail.com> <CALz3k9h8CoAP8+ZmNvNGeXL9D_Q83Ovrubz9zHECr6C0TXuoVg@mail.gmail.com>
Message-ID: <CAADnVQ+bOhh1R_eCoThyNg50dd4nA4-qhpXxOWheLeA_44npXg@mail.gmail.com>

On Tue, Feb 20, 2024 at 6:45?PM ??? <dongmenglong.8 at bytedance.com> wrote:
>
> On Wed, Feb 21, 2024 at 10:35?AM ??? <dongmenglong.8 at bytedance.com> wrote:
> >
> > Hello,
> >
> > On Wed, Feb 21, 2024 at 9:24?AM Alexei Starovoitov
> > <alexei.starovoitov at gmail.com> wrote:
> > >
> > > On Mon, Feb 19, 2024 at 7:51?PM Menglong Dong
> > > <dongmenglong.8 at bytedance.com> wrote:
> > > >
> > > > For now, the BPF program of type BPF_PROG_TYPE_TRACING is not allowed to
> > > > be attached to multiple hooks, and we have to create a BPF program for
> > > > each kernel function, for which we want to trace, even through all the
> > > > program have the same (or similar) logic. This can consume extra memory,
> > > > and make the program loading slow if we have plenty of kernel function to
> > > > trace.
> > >
> > > Should this be combined with multi link ?
> > > (As was recently done for kprobe_multi and uprobe_multi).
> > > Loading fentry prog once and attaching it through many bpf_links
> > > to multiple places is a nice addition,
> > > but we should probably add a multi link right away too.
> >
> > I was planning to implement the multi link for tracing after this
> > series in another series. I can do it together with this series
> > if you prefer.
> >
>
> Should I introduce the multi link for tracing first, then this series?
> (Furthermore, this series seems not necessary.)

What do you mean "not necessary" ?
Don't you want to still check that bpf prog access only N args
and BTF for these args matches across all attach points ?


From dongmenglong.8 at bytedance.com  Tue Feb 20 19:06:20 2024
From: dongmenglong.8 at bytedance.com (=?UTF-8?B?5qKm6b6Z6JGj?=)
Date: Wed, 21 Feb 2024 11:06:20 +0800
Subject: [External] Re: [PATCH bpf-next 0/5] bpf: make tracing program
 support multi-attach
In-Reply-To: <CAADnVQ+bOhh1R_eCoThyNg50dd4nA4-qhpXxOWheLeA_44npXg@mail.gmail.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
 <CAADnVQ+E4ygZV6dcs8wj5FdFz9bfrQ=61235uiRoxe9RqQvR9Q@mail.gmail.com>
 <CALz3k9g__P+UdO2vLPrR5Y4sQonQJjOnGPNmhmxtRfhLKoV7Rg@mail.gmail.com>
 <CALz3k9h8CoAP8+ZmNvNGeXL9D_Q83Ovrubz9zHECr6C0TXuoVg@mail.gmail.com> <CAADnVQ+bOhh1R_eCoThyNg50dd4nA4-qhpXxOWheLeA_44npXg@mail.gmail.com>
Message-ID: <CALz3k9jDsmNMrXdxdx152fgvBxDoY4Lj_xMf8z-pwPtpm75vXQ@mail.gmail.com>

On Wed, Feb 21, 2024 at 11:02?AM Alexei Starovoitov
<alexei.starovoitov at gmail.com> wrote:
>
> On Tue, Feb 20, 2024 at 6:45?PM ??? <dongmenglong.8 at bytedance.com> wrote:
> >
> > On Wed, Feb 21, 2024 at 10:35?AM ??? <dongmenglong.8 at bytedance.com> wrote:
> > >
> > > Hello,
> > >
> > > On Wed, Feb 21, 2024 at 9:24?AM Alexei Starovoitov
> > > <alexei.starovoitov at gmail.com> wrote:
> > > >
> > > > On Mon, Feb 19, 2024 at 7:51?PM Menglong Dong
> > > > <dongmenglong.8 at bytedance.com> wrote:
> > > > >
> > > > > For now, the BPF program of type BPF_PROG_TYPE_TRACING is not allowed to
> > > > > be attached to multiple hooks, and we have to create a BPF program for
> > > > > each kernel function, for which we want to trace, even through all the
> > > > > program have the same (or similar) logic. This can consume extra memory,
> > > > > and make the program loading slow if we have plenty of kernel function to
> > > > > trace.
> > > >
> > > > Should this be combined with multi link ?
> > > > (As was recently done for kprobe_multi and uprobe_multi).
> > > > Loading fentry prog once and attaching it through many bpf_links
> > > > to multiple places is a nice addition,
> > > > but we should probably add a multi link right away too.
> > >
> > > I was planning to implement the multi link for tracing after this
> > > series in another series. I can do it together with this series
> > > if you prefer.
> > >
> >
> > Should I introduce the multi link for tracing first, then this series?
> > (Furthermore, this series seems not necessary.)
>
> What do you mean "not necessary" ?
> Don't you want to still check that bpf prog access only N args
> and BTF for these args matches across all attach points ?

No, I means that if we should keep the

"Loading fentry prog once and attaching it through many bpf_links to
multiple places"

and only keep the multi link.

Both methods need to check the accessed args of the target.


From dongmenglong.8 at bytedance.com  Tue Feb 20 19:09:31 2024
From: dongmenglong.8 at bytedance.com (=?UTF-8?B?5qKm6b6Z6JGj?=)
Date: Wed, 21 Feb 2024 11:09:31 +0800
Subject: [External] Re: [PATCH bpf-next 1/5] bpf: tracing: add support to
 record and check the accessed args
In-Reply-To: <81431b5d-0e0f-485a-a3ce-af8e63169552@gmail.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
 <20240220035105.34626-2-dongmenglong.8@bytedance.com> <81431b5d-0e0f-485a-a3ce-af8e63169552@gmail.com>
Message-ID: <CALz3k9io7c6oGvCjfYr=1kb6Ndrh6RVgR5pHC5DzW-F_YGqjxA@mail.gmail.com>

On Wed, Feb 21, 2024 at 2:22?AM Kui-Feng Lee <sinquersw at gmail.com> wrote:
>
>
>
> On 2/19/24 19:51, Menglong Dong wrote:
> > In this commit, we add the 'accessed_args' field to struct bpf_prog_aux,
> > which is used to record the accessed index of the function args in
> > btf_ctx_access().
> >
> > Meanwhile, we add the function btf_check_func_part_match() to compare the
> > accessed function args of two function prototype. This function will be
> > used in the following commit.
> >
> > Signed-off-by: Menglong Dong <dongmenglong.8 at bytedance.com>
> > ---
> >   include/linux/bpf.h |   4 ++
> >   kernel/bpf/btf.c    | 121 ++++++++++++++++++++++++++++++++++++++++++++
> >   2 files changed, 125 insertions(+)
> >
> > diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> > index c7aa99b44dbd..0225b8dbdd9d 100644
> > --- a/include/linux/bpf.h
> > +++ b/include/linux/bpf.h
> > @@ -1464,6 +1464,7 @@ struct bpf_prog_aux {
> >       const struct btf_type *attach_func_proto;
> >       /* function name for valid attach_btf_id */
> >       const char *attach_func_name;
> > +     u64 accessed_args;
> >       struct bpf_prog **func;
> >       void *jit_data; /* JIT specific data. arch dependent */
> >       struct bpf_jit_poke_descriptor *poke_tab;
> > @@ -2566,6 +2567,9 @@ struct bpf_reg_state;
> >   int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog);
> >   int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *prog,
> >                        struct btf *btf, const struct btf_type *t);
> > +int btf_check_func_part_match(struct btf *btf1, const struct btf_type *t1,
> > +                           struct btf *btf2, const struct btf_type *t2,
> > +                           u64 func_args);
> >   const char *btf_find_decl_tag_value(const struct btf *btf, const struct btf_type *pt,
> >                                   int comp_idx, const char *tag_key);
> >   int btf_find_next_decl_tag(const struct btf *btf, const struct btf_type *pt,
> > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> > index 6ff0bd1a91d5..3a6931402fe4 100644
> > --- a/kernel/bpf/btf.c
> > +++ b/kernel/bpf/btf.c
> > @@ -6203,6 +6203,9 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
> >               /* skip first 'void *__data' argument in btf_trace_##name typedef */
> >               args++;
> >               nr_args--;
> > +             prog->aux->accessed_args |= (1 << (arg + 1));
> > +     } else {
> > +             prog->aux->accessed_args |= (1 << arg);
> >       }
> >
> >       if (arg > nr_args) {
> > @@ -7010,6 +7013,124 @@ int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *pr
> >       return btf_check_func_type_match(log, btf1, t1, btf2, t2);
> >   }
> >
> > +static u32 get_ctx_arg_total_size(struct btf *btf, const struct btf_type *t)
> > +{
> > +     const struct btf_param *args;
> > +     u32 size = 0, nr_args;
> > +     int i;
> > +
> > +     nr_args = btf_type_vlen(t);
> > +     args = (const struct btf_param *)(t + 1);
> > +     for (i = 0; i < nr_args; i++) {
> > +             t = btf_type_skip_modifiers(btf, args[i].type, NULL);
> > +             size += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
> > +     }
> > +
> > +     return size;
> > +}
> > +
> > +static int get_ctx_arg_idx_aligned(struct btf *btf, const struct btf_type *t,
> > +                                int off)
> > +{
> > +     const struct btf_param *args;
> > +     u32 offset = 0, nr_args;
> > +     int i;
> > +
> > +     nr_args = btf_type_vlen(t);
> > +     args = (const struct btf_param *)(t + 1);
> > +     for (i = 0; i < nr_args; i++) {
> > +             if (offset == off)
> > +                     return i;
> > +
> > +             t = btf_type_skip_modifiers(btf, args[i].type, NULL);
> > +             offset += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
> > +             if (offset > off)
> > +                     return -1;
> > +     }
> > +     return -1;
> > +}
>
> This one is very similar to get_ctx_arg_idx().
> How about to refactor get_ctx_arg_idx() and share the code
> between get_ctx_arg_idx() and get_ctx_arg_idx_aligned().
>

This seems to work, I'll combine them in the next version.

Thanks for the example code!
Menglong Dong

> For example,
>
> -static u32 get_ctx_arg_idx(struct btf *btf, const struct btf_type
> *func_proto,
> -                          int off)
> +static u32 _get_ctx_arg_idx(struct btf *btf, const struct btf_type
> *func_proto,
> +                          int off, u32 *arg_off)
>   {
>          const struct btf_param *args;
>          const struct btf_type *t;
>          u32 offset = 0, nr_args;
>          int i;
>
>          if (!func_proto)
>                  return off / 8;
>
>          nr_args = btf_type_vlen(func_proto);
>          args = (const struct btf_param *)(func_proto + 1);
>          for (i = 0; i < nr_args; i++) {
> +               if (arg_off)
> +                       *arg_off = offset;
>                  t = btf_type_skip_modifiers(btf, args[i].type, NULL);
>                  offset += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
>                  if (off < offset)
>                          return i;
>          }
>
> +       if (arg_off)
> +               *arg_off = offset;
>          t = btf_type_skip_modifiers(btf, func_proto->type, NULL);
>          offset += btf_type_is_ptr(t) ? 8 : roundup(t->size, 8);
>          if (off < offset)
>                  return nr_args;
>
>          return nr_args + 1;
>   }
>
> +static u32 get_ctx_arg_idx(struct btf *btf, const struct btf_type
> *func_proto,
> +                          int off)
> +{
> +       return _get_ctx_arg_idx(btf, func_proto, off, NULL);
> +}
> +
> +static u32 get_ctx_arg_idx_aligned(struct btf *btf,
> +                                  const struct btf_type *func_proto,
> +                                  int off)
> +{
> +       u32 arg_off;
> +       u32 arg_idx = _get_ctx_arg_idx(btf, func_proto, off, &arg_off);
> +       return arg_off == off ? arg_idx : -1;
> +}
> +
>
> > +
> > +/* This function is similar to btf_check_func_type_match(), except that it
> > + * only compare some function args of the function prototype t1 and t2.
> > + */
> > +int btf_check_func_part_match(struct btf *btf1, const struct btf_type *func1,
> > +                           struct btf *btf2, const struct btf_type *func2,
> > +                           u64 func_args)
> > +{
> > +     const struct btf_param *args1, *args2;
> > +     u32 nargs1, i, offset = 0;
> > +     const char *s1, *s2;
> > +
> > +     if (!btf_type_is_func_proto(func1) || !btf_type_is_func_proto(func2))
> > +             return -EINVAL;
> > +
> > +     args1 = (const struct btf_param *)(func1 + 1);
> > +     args2 = (const struct btf_param *)(func2 + 1);
> > +     nargs1 = btf_type_vlen(func1);
> > +
> > +     for (i = 0; i <= nargs1; i++) {
> > +             const struct btf_type *t1, *t2;
> > +
> > +             if (!(func_args & (1 << i)))
> > +                     goto next;
> > +
> > +             if (i < nargs1) {
> > +                     int t2_index;
> > +
> > +                     /* get the index of the arg corresponding to args1[i]
> > +                      * by the offset.
> > +                      */
> > +                     t2_index = get_ctx_arg_idx_aligned(btf2, func2,
> > +                                                        offset);
> > +                     if (t2_index < 0)
> > +                             return -EINVAL;
> > +
> > +                     t1 = btf_type_skip_modifiers(btf1, args1[i].type, NULL);
> > +                     t2 = btf_type_skip_modifiers(btf2, args2[t2_index].type,
> > +                                                  NULL);
> > +             } else {
> > +                     /* i == nargs1, this is the index of return value of t1 */
> > +                     if (get_ctx_arg_total_size(btf1, func1) !=
> > +                         get_ctx_arg_total_size(btf2, func2))
> > +                             return -EINVAL;
> > +
> > +                     /* check the return type of t1 and t2 */
> > +                     t1 = btf_type_skip_modifiers(btf1, func1->type, NULL);
> > +                     t2 = btf_type_skip_modifiers(btf2, func2->type, NULL);
> > +             }
> > +
> > +             if (t1->info != t2->info ||
> > +                 (btf_type_has_size(t1) && t1->size != t2->size))
> > +                     return -EINVAL;
> > +             if (btf_type_is_int(t1) || btf_is_any_enum(t1))
> > +                     goto next;
> > +
> > +             if (btf_type_is_struct(t1))
> > +                     goto on_struct;
> > +
> > +             if (!btf_type_is_ptr(t1))
> > +                     return -EINVAL;
> > +
> > +             t1 = btf_type_skip_modifiers(btf1, t1->type, NULL);
> > +             t2 = btf_type_skip_modifiers(btf2, t2->type, NULL);
> > +             if (!btf_type_is_struct(t1) || !btf_type_is_struct(t2))
> > +                     return -EINVAL;
> > +
> > +on_struct:
> > +             s1 = btf_name_by_offset(btf1, t1->name_off);
> > +             s2 = btf_name_by_offset(btf2, t2->name_off);
> > +             if (strcmp(s1, s2))
> > +                     return -EINVAL;
> > +next:
> > +             if (i < nargs1) {
> > +                     t1 = btf_type_skip_modifiers(btf1, args1[i].type, NULL);
> > +                     offset += btf_type_is_ptr(t1) ? 8 : roundup(t1->size, 8);
> > +             }
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> >   static bool btf_is_dynptr_ptr(const struct btf *btf, const struct btf_type *t)
> >   {
> >       const char *name;


From alexei.starovoitov at gmail.com  Tue Feb 20 19:18:25 2024
From: alexei.starovoitov at gmail.com (Alexei Starovoitov)
Date: Tue, 20 Feb 2024 19:18:25 -0800
Subject: [External] Re: [PATCH bpf-next 0/5] bpf: make tracing program
 support multi-attach
In-Reply-To: <CALz3k9jDsmNMrXdxdx152fgvBxDoY4Lj_xMf8z-pwPtpm75vXQ@mail.gmail.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
 <CAADnVQ+E4ygZV6dcs8wj5FdFz9bfrQ=61235uiRoxe9RqQvR9Q@mail.gmail.com>
 <CALz3k9g__P+UdO2vLPrR5Y4sQonQJjOnGPNmhmxtRfhLKoV7Rg@mail.gmail.com>
 <CALz3k9h8CoAP8+ZmNvNGeXL9D_Q83Ovrubz9zHECr6C0TXuoVg@mail.gmail.com>
 <CAADnVQ+bOhh1R_eCoThyNg50dd4nA4-qhpXxOWheLeA_44npXg@mail.gmail.com> <CALz3k9jDsmNMrXdxdx152fgvBxDoY4Lj_xMf8z-pwPtpm75vXQ@mail.gmail.com>
Message-ID: <CAADnVQLtHQO9X7EBxe4x6YyAdQi33aqzTirTJff5epTcBatd3g@mail.gmail.com>

On Tue, Feb 20, 2024 at 7:06?PM ??? <dongmenglong.8 at bytedance.com> wrote:
>
> On Wed, Feb 21, 2024 at 11:02?AM Alexei Starovoitov
> <alexei.starovoitov at gmail.com> wrote:
> >
> > On Tue, Feb 20, 2024 at 6:45?PM ??? <dongmenglong.8 at bytedance.com> wrote:
> > >
> > > On Wed, Feb 21, 2024 at 10:35?AM ??? <dongmenglong.8 at bytedance.com> wrote:
> > > >
> > > > Hello,
> > > >
> > > > On Wed, Feb 21, 2024 at 9:24?AM Alexei Starovoitov
> > > > <alexei.starovoitov at gmail.com> wrote:
> > > > >
> > > > > On Mon, Feb 19, 2024 at 7:51?PM Menglong Dong
> > > > > <dongmenglong.8 at bytedance.com> wrote:
> > > > > >
> > > > > > For now, the BPF program of type BPF_PROG_TYPE_TRACING is not allowed to
> > > > > > be attached to multiple hooks, and we have to create a BPF program for
> > > > > > each kernel function, for which we want to trace, even through all the
> > > > > > program have the same (or similar) logic. This can consume extra memory,
> > > > > > and make the program loading slow if we have plenty of kernel function to
> > > > > > trace.
> > > > >
> > > > > Should this be combined with multi link ?
> > > > > (As was recently done for kprobe_multi and uprobe_multi).
> > > > > Loading fentry prog once and attaching it through many bpf_links
> > > > > to multiple places is a nice addition,
> > > > > but we should probably add a multi link right away too.
> > > >
> > > > I was planning to implement the multi link for tracing after this
> > > > series in another series. I can do it together with this series
> > > > if you prefer.
> > > >
> > >
> > > Should I introduce the multi link for tracing first, then this series?
> > > (Furthermore, this series seems not necessary.)
> >
> > What do you mean "not necessary" ?
> > Don't you want to still check that bpf prog access only N args
> > and BTF for these args matches across all attach points ?
>
> No, I means that if we should keep the
>
> "Loading fentry prog once and attaching it through many bpf_links to
> multiple places"
>
> and only keep the multi link.

I suspect supporting multi link only is better,
since the amount of kernel code to maintain will be less.


From anshuman.khandual at arm.com  Tue Feb 20 19:39:41 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 21 Feb 2024 09:09:41 +0530
Subject: [PATCH] coresight: constify the struct device_type usage
In-Reply-To: <20240219-device_cleanup-coresight-v1-1-4a8a0b816183@marliere.net>
References: <20240219-device_cleanup-coresight-v1-1-4a8a0b816183@marliere.net>
Message-ID: <3b400f7d-f76c-4e54-92d9-7ece7f712ea8@arm.com>



On 2/19/24 19:13, Ricardo B. Marliere wrote:
> Since commit aed65af1cc2f ("drivers: make device_type const"), the driver
> core can properly handle constant struct device_type. Move the
> coresight_dev_type variable to be a constant structure as well, placing it
> into read-only memory which can not be modified at runtime.
> 
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Signed-off-by: Ricardo B. Marliere <ricardo at marliere.net>
> ---

Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>

>  drivers/hwtracing/coresight/coresight-priv.h  | 2 +-
>  drivers/hwtracing/coresight/coresight-sysfs.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
> index eb365236f9a9..ca3362cbdb70 100644
> --- a/drivers/hwtracing/coresight/coresight-priv.h
> +++ b/drivers/hwtracing/coresight/coresight-priv.h
> @@ -13,7 +13,7 @@
>  #include <linux/pm_runtime.h>
>  
>  extern struct mutex coresight_mutex;
> -extern struct device_type coresight_dev_type[];
> +extern const struct device_type coresight_dev_type[];
>  
>  /*
>   * Coresight management registers (0xf00-0xfcc)
> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
> index f9444e2cb1d9..1e67cc7758d7 100644
> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
> @@ -377,7 +377,7 @@ static struct attribute *coresight_source_attrs[] = {
>  };
>  ATTRIBUTE_GROUPS(coresight_source);
>  
> -struct device_type coresight_dev_type[] = {
> +const struct device_type coresight_dev_type[] = {
>  	[CORESIGHT_DEV_TYPE_SINK] = {
>  		.name = "sink",
>  		.groups = coresight_sink_groups,
> 
> ---
> base-commit: c099fdd218a0fedfe87e0b88d2ba0667eab3b3c8
> change-id: 20240219-device_cleanup-coresight-00ba00fd5f21
> 
> Best regards,


From dongmenglong.8 at bytedance.com  Tue Feb 20 19:57:58 2024
From: dongmenglong.8 at bytedance.com (=?UTF-8?B?5qKm6b6Z6JGj?=)
Date: Wed, 21 Feb 2024 11:57:58 +0800
Subject: [External] Re: [PATCH bpf-next 0/5] bpf: make tracing program
 support multi-attach
In-Reply-To: <CAADnVQLtHQO9X7EBxe4x6YyAdQi33aqzTirTJff5epTcBatd3g@mail.gmail.com>
References: <20240220035105.34626-1-dongmenglong.8@bytedance.com>
 <CAADnVQ+E4ygZV6dcs8wj5FdFz9bfrQ=61235uiRoxe9RqQvR9Q@mail.gmail.com>
 <CALz3k9g__P+UdO2vLPrR5Y4sQonQJjOnGPNmhmxtRfhLKoV7Rg@mail.gmail.com>
 <CALz3k9h8CoAP8+ZmNvNGeXL9D_Q83Ovrubz9zHECr6C0TXuoVg@mail.gmail.com>
 <CAADnVQ+bOhh1R_eCoThyNg50dd4nA4-qhpXxOWheLeA_44npXg@mail.gmail.com>
 <CALz3k9jDsmNMrXdxdx152fgvBxDoY4Lj_xMf8z-pwPtpm75vXQ@mail.gmail.com> <CAADnVQLtHQO9X7EBxe4x6YyAdQi33aqzTirTJff5epTcBatd3g@mail.gmail.com>
Message-ID: <CALz3k9gM9Leuztxs9ZrM5YgwLXFQ4FMnBxHr6P=Q+GppPv5d=g@mail.gmail.com>

On Wed, Feb 21, 2024 at 11:18?AM Alexei Starovoitov
<alexei.starovoitov at gmail.com> wrote:
>
> On Tue, Feb 20, 2024 at 7:06?PM ??? <dongmenglong.8 at bytedance.com> wrote:
> >
> > On Wed, Feb 21, 2024 at 11:02?AM Alexei Starovoitov
> > <alexei.starovoitov at gmail.com> wrote:
> > >
> > > On Tue, Feb 20, 2024 at 6:45?PM ??? <dongmenglong.8 at bytedance.com> wrote:
> > > >
> > > > On Wed, Feb 21, 2024 at 10:35?AM ??? <dongmenglong.8 at bytedance.com> wrote:
> > > > >
> > > > > Hello,
> > > > >
> > > > > On Wed, Feb 21, 2024 at 9:24?AM Alexei Starovoitov
> > > > > <alexei.starovoitov at gmail.com> wrote:
> > > > > >
> > > > > > On Mon, Feb 19, 2024 at 7:51?PM Menglong Dong
> > > > > > <dongmenglong.8 at bytedance.com> wrote:
> > > > > > >
> > > > > > > For now, the BPF program of type BPF_PROG_TYPE_TRACING is not allowed to
> > > > > > > be attached to multiple hooks, and we have to create a BPF program for
> > > > > > > each kernel function, for which we want to trace, even through all the
> > > > > > > program have the same (or similar) logic. This can consume extra memory,
> > > > > > > and make the program loading slow if we have plenty of kernel function to
> > > > > > > trace.
> > > > > >
> > > > > > Should this be combined with multi link ?
> > > > > > (As was recently done for kprobe_multi and uprobe_multi).
> > > > > > Loading fentry prog once and attaching it through many bpf_links
> > > > > > to multiple places is a nice addition,
> > > > > > but we should probably add a multi link right away too.
> > > > >
> > > > > I was planning to implement the multi link for tracing after this
> > > > > series in another series. I can do it together with this series
> > > > > if you prefer.
> > > > >
> > > >
> > > > Should I introduce the multi link for tracing first, then this series?
> > > > (Furthermore, this series seems not necessary.)
> > >
> > > What do you mean "not necessary" ?
> > > Don't you want to still check that bpf prog access only N args
> > > and BTF for these args matches across all attach points ?
> >
> > No, I means that if we should keep the
> >
> > "Loading fentry prog once and attaching it through many bpf_links to
> > multiple places"
> >
> > and only keep the multi link.
>
> I suspect supporting multi link only is better,
> since the amount of kernel code to maintain will be less.

Okay!


From rick.p.edgecombe at intel.com  Tue Feb 20 20:18:02 2024
From: rick.p.edgecombe at intel.com (Edgecombe, Rick P)
Date: Wed, 21 Feb 2024 04:18:02 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in
 userspace
In-Reply-To: <6332963a828d247ef935b7d3352fa1fbd83b11b0.camel@intel.com>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
	 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
	 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
	 <20240220185714.GO4163@brightrain.aerifal.cx>
	 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
	 <20240220235415.GP4163@brightrain.aerifal.cx>
	 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
	 <20240221012736.GQ4163@brightrain.aerifal.cx>
	 <6332963a828d247ef935b7d3352fa1fbd83b11b0.camel@intel.com>
Message-ID: <41b401d59b3846f44cee33f1d680b2534b7c0dea.camel@intel.com>

On Tue, 2024-02-20 at 18:11 -0800, Rick Edgecombe wrote:
> Some specific cases that were still open were longjmp()ing off of a
> custom userspace threading library stack, which may not have left a
> token behind when it jumped to a new stack. And also, potentially off
> of an alt shadow stack in the future, depending on whether it leaves
> a
> restore token when handling a signal. (the problem there, is if there
> is no room to leave it).

Ah, I remember the other one. If the token on the target shadow stack
is at the end of the shadow stack, it may not be able to handle pushing
a shadow stack signal frame if a signal hits while is unwinding through
the token. As in, where normal longjmp() is direct transition, in this
case the longjmp() operation can be temporarily in a place where a
signal cannot be handled.

From rick.p.edgecombe at intel.com  Tue Feb 20 20:30:49 2024
From: rick.p.edgecombe at intel.com (Edgecombe, Rick P)
Date: Wed, 21 Feb 2024 04:30:49 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in
 userspace
In-Reply-To: <063acc75-ea1d-4dd3-aecb-e5c8884005db@app.fastmail.com>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
	 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
	 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
	 <20240220185714.GO4163@brightrain.aerifal.cx>
	 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
	 <063acc75-ea1d-4dd3-aecb-e5c8884005db@app.fastmail.com>
Message-ID: <8d28fce4b0d1fc2c757621d9a0f82a5c2db8e78c.camel@intel.com>

On Tue, 2024-02-20 at 18:59 -0500, Stefan O'Rear wrote:
> 
> Ideally for riscv only writes would cause conversion, an incssp
> underflow
> which performs shadow stack reads would be able to fault early.

Why can't makecontext() just clobber part of the low address side of
the passed in stack with a shadow stack mapping? Like say it just
munmap()'s part of the passed stack, and map_shadow_stack() in it's
place.

Then you could still have the shadow stack->normal conversion process
triggered by normal writes. IIUC the concern there is to make sure the
caller can reuse it as normal memory when it is done with the
ucontext/sigaltstack stuff? So the normal->shadow stack part could be
explicit.

But the more I think about this, the more I think it is a hack, and a
proper fix is to use new interfaces. It also would be difficult to
sell, if the faulting conversion stuff is in any way complex.


From sfr at canb.auug.org.au  Tue Feb 20 21:30:10 2024
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Wed, 21 Feb 2024 16:30:10 +1100
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <20240221092826.748e70c4@canb.auug.org.au>
References: <20240221092826.748e70c4@canb.auug.org.au>
Message-ID: <20240221163010.5f81813a@canb.auug.org.au>

Hi all,

On Wed, 21 Feb 2024 09:28:26 +1100 Stephen Rothwell <sfr at canb.auug.org.au> wrote:
>
> After merging the arm-soc-fixes tree, today's linux-next build (arm
> multi_v7_defconfig) produced this warning:
> 
> arch/arm/boot/dts/renesas/r8a7790-lager.dts:444.11-458.5: Warning (interrupt_provider): /i2c-mux4/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7790-lager.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7792-blanche.dts:376.10-392.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7792-blanche.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7790-stout.dts:344.10-362.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7790-stout.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7791-koelsch.dts:816.10-830.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7791-koelsch.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7791-porter.dts:410.10-420.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 5a: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7791-porter.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7794-alt.dts:450.10-464.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7794-alt.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7794-silk.dts:436.10-454.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7794-silk.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7793-gose.dts:756.10-770.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> 
> Introduced/exposed by commit
> 
>   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
> 
> I guess you missed some :-(

Also these from the arm64 defconfig build:

arch/arm64/boot/dts/freescale/mba8xx.dtsi:233.20-249.4: Warning (interrupt_provider): /bus at 5a000000/i2c at 5a810000/gpio at 70: Missing '#interrupt-cells' in interrupt provider
arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/arm64/boot/dts/freescale/mba8xx.dtsi:233.20-249.4: Warning (interrupt_provider): /bus at 5a000000/i2c at 5a810000/gpio at 70: Missing '#interrupt-cells' in interrupt provider
arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp-mba8xx.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'

-- 
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/20240221/3bcc4274/attachment.sig>

From dan.carpenter at linaro.org  Tue Feb 20 21:31:08 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Wed, 21 Feb 2024 08:31:08 +0300
Subject: [PATCH bpf-next 2/5] bpf: tracing: support to attach program to
 multi hooks
In-Reply-To: <20240220035105.34626-3-dongmenglong.8@bytedance.com>
Message-ID: <d0607bff-b589-4548-98e1-a94d227b4e93@moroto.mountain>

Hi Menglong,

kernel test robot noticed the following build warnings:

url:    https://github.com/intel-lab-lkp/linux/commits/Menglong-Dong/bpf-tracing-add-support-to-record-and-check-the-accessed-args/20240220-115317
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/20240220035105.34626-3-dongmenglong.8%40bytedance.com
patch subject: [PATCH bpf-next 2/5] bpf: tracing: support to attach program to multi hooks
config: m68k-randconfig-r071-20240220 (https://download.01.org/0day-ci/archive/20240221/202402210534.siGKEfus-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 13.2.0

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
| Closes: https://lore.kernel.org/r/202402210534.siGKEfus-lkp at intel.com/

smatch warnings:
kernel/bpf/syscall.c:3325 bpf_tracing_prog_attach() warn: passing zero to 'PTR_ERR'
kernel/bpf/syscall.c:3485 bpf_tracing_prog_attach() error: uninitialized symbol 'link'.

vim +/PTR_ERR +3325 kernel/bpf/syscall.c

4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3255  static int bpf_tracing_prog_attach(struct bpf_prog *prog,
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3256  				   int tgt_prog_fd,
2fcc82411e74e5 Kui-Feng Lee           2022-05-10  3257  				   u32 btf_id,
2fcc82411e74e5 Kui-Feng Lee           2022-05-10  3258  				   u64 bpf_cookie)
fec56f5890d93f Alexei Starovoitov     2019-11-14  3259  {
a3b80e1078943d Andrii Nakryiko        2020-04-28  3260  	struct bpf_link_primer link_primer;
3aac1ead5eb6b7 Toke H?iland-J?rgensen 2020-09-29  3261  	struct bpf_prog *tgt_prog = NULL;
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3262  	struct bpf_trampoline *tr = NULL;
5f80eb32851d7a Menglong Dong          2024-02-20  3263  	struct btf *attach_btf = NULL;
70ed506c3bbcfa Andrii Nakryiko        2020-03-02  3264  	struct bpf_tracing_link *link;
5f80eb32851d7a Menglong Dong          2024-02-20  3265  	struct module *mod = NULL;
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3266  	u64 key = 0;
a3b80e1078943d Andrii Nakryiko        2020-04-28  3267  	int err;
fec56f5890d93f Alexei Starovoitov     2019-11-14  3268  
9e4e01dfd3254c KP Singh               2020-03-29  3269  	switch (prog->type) {
9e4e01dfd3254c KP Singh               2020-03-29  3270  	case BPF_PROG_TYPE_TRACING:
fec56f5890d93f Alexei Starovoitov     2019-11-14  3271  		if (prog->expected_attach_type != BPF_TRACE_FENTRY &&
be8704ff07d237 Alexei Starovoitov     2020-01-20  3272  		    prog->expected_attach_type != BPF_TRACE_FEXIT &&
9e4e01dfd3254c KP Singh               2020-03-29  3273  		    prog->expected_attach_type != BPF_MODIFY_RETURN) {
9e4e01dfd3254c KP Singh               2020-03-29  3274  			err = -EINVAL;
9e4e01dfd3254c KP Singh               2020-03-29  3275  			goto out_put_prog;
9e4e01dfd3254c KP Singh               2020-03-29  3276  		}
9e4e01dfd3254c KP Singh               2020-03-29  3277  		break;
9e4e01dfd3254c KP Singh               2020-03-29  3278  	case BPF_PROG_TYPE_EXT:
9e4e01dfd3254c KP Singh               2020-03-29  3279  		if (prog->expected_attach_type != 0) {
9e4e01dfd3254c KP Singh               2020-03-29  3280  			err = -EINVAL;
9e4e01dfd3254c KP Singh               2020-03-29  3281  			goto out_put_prog;
9e4e01dfd3254c KP Singh               2020-03-29  3282  		}
9e4e01dfd3254c KP Singh               2020-03-29  3283  		break;
9e4e01dfd3254c KP Singh               2020-03-29  3284  	case BPF_PROG_TYPE_LSM:
9e4e01dfd3254c KP Singh               2020-03-29  3285  		if (prog->expected_attach_type != BPF_LSM_MAC) {
9e4e01dfd3254c KP Singh               2020-03-29  3286  			err = -EINVAL;
9e4e01dfd3254c KP Singh               2020-03-29  3287  			goto out_put_prog;
9e4e01dfd3254c KP Singh               2020-03-29  3288  		}
9e4e01dfd3254c KP Singh               2020-03-29  3289  		break;
9e4e01dfd3254c KP Singh               2020-03-29  3290  	default:
fec56f5890d93f Alexei Starovoitov     2019-11-14  3291  		err = -EINVAL;
fec56f5890d93f Alexei Starovoitov     2019-11-14  3292  		goto out_put_prog;
fec56f5890d93f Alexei Starovoitov     2019-11-14  3293  	}
fec56f5890d93f Alexei Starovoitov     2019-11-14  3294  
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3295  	if (tgt_prog_fd) {
5f80eb32851d7a Menglong Dong          2024-02-20  3296  		if (!btf_id) {
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3297  			err = -EINVAL;
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3298  			goto out_put_prog;
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3299  		}
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3300  		tgt_prog = bpf_prog_get(tgt_prog_fd);
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3301  		if (IS_ERR(tgt_prog)) {
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3302  			tgt_prog = NULL;
5f80eb32851d7a Menglong Dong          2024-02-20  3303  			/* tgt_prog_fd is the fd of the kernel module BTF */
5f80eb32851d7a Menglong Dong          2024-02-20  3304  			attach_btf = btf_get_by_fd(tgt_prog_fd);
5f80eb32851d7a Menglong Dong          2024-02-20  3305  			if (IS_ERR(attach_btf)) {
5f80eb32851d7a Menglong Dong          2024-02-20  3306  				attach_btf = NULL;
5f80eb32851d7a Menglong Dong          2024-02-20  3307  				err = -EINVAL;
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3308  				goto out_put_prog;
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3309  			}
5f80eb32851d7a Menglong Dong          2024-02-20  3310  			if (!btf_is_kernel(attach_btf)) {
5f80eb32851d7a Menglong Dong          2024-02-20  3311  				btf_put(attach_btf);
5f80eb32851d7a Menglong Dong          2024-02-20  3312  				err = -EOPNOTSUPP;
5f80eb32851d7a Menglong Dong          2024-02-20  3313  				goto out_put_prog;
5f80eb32851d7a Menglong Dong          2024-02-20  3314  			}
5f80eb32851d7a Menglong Dong          2024-02-20  3315  		} else if (prog->type == BPF_PROG_TYPE_TRACING &&
5f80eb32851d7a Menglong Dong          2024-02-20  3316  			   tgt_prog->type == BPF_PROG_TYPE_TRACING) {
5f80eb32851d7a Menglong Dong          2024-02-20  3317  			prog->aux->attach_tracing_prog = true;
5f80eb32851d7a Menglong Dong          2024-02-20  3318  		}
5f80eb32851d7a Menglong Dong          2024-02-20  3319  		key = bpf_trampoline_compute_key(tgt_prog, attach_btf,
5f80eb32851d7a Menglong Dong          2024-02-20  3320  						 btf_id);
5f80eb32851d7a Menglong Dong          2024-02-20  3321  	} else if (btf_id) {
5f80eb32851d7a Menglong Dong          2024-02-20  3322  		attach_btf = bpf_get_btf_vmlinux();
5f80eb32851d7a Menglong Dong          2024-02-20  3323  		if (IS_ERR(attach_btf)) {
5f80eb32851d7a Menglong Dong          2024-02-20  3324  			attach_btf = NULL;
                                                                                ^^^^^^^^^^^^^^^^^^
This needs to be done after the "err = " assignment on the next line.

5f80eb32851d7a Menglong Dong          2024-02-20 @3325  			err = PTR_ERR(attach_btf);
                                                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^
Here.

5f80eb32851d7a Menglong Dong          2024-02-20  3326  			goto out_unlock;
5f80eb32851d7a Menglong Dong          2024-02-20  3327  		}
5f80eb32851d7a Menglong Dong          2024-02-20  3328  		if (!attach_btf) {
5f80eb32851d7a Menglong Dong          2024-02-20  3329  			err = -EINVAL;
5f80eb32851d7a Menglong Dong          2024-02-20  3330  			goto out_unlock;

"link" is not initialized on this goto path so it leads to an
uninitialized variable warning.

5f80eb32851d7a Menglong Dong          2024-02-20  3331  		}
5f80eb32851d7a Menglong Dong          2024-02-20  3332  		btf_get(attach_btf);
5f80eb32851d7a Menglong Dong          2024-02-20  3333  		key = bpf_trampoline_compute_key(NULL, attach_btf, btf_id);
5f80eb32851d7a Menglong Dong          2024-02-20  3334  	} else {
5f80eb32851d7a Menglong Dong          2024-02-20  3335  		attach_btf = prog->aux->attach_btf;
5f80eb32851d7a Menglong Dong          2024-02-20  3336  		/* get the reference of the btf for bpf link */
5f80eb32851d7a Menglong Dong          2024-02-20  3337  		if (attach_btf)
5f80eb32851d7a Menglong Dong          2024-02-20  3338  			btf_get(attach_btf);
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3339  	}
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3340  
70ed506c3bbcfa Andrii Nakryiko        2020-03-02  3341  	link = kzalloc(sizeof(*link), GFP_USER);
70ed506c3bbcfa Andrii Nakryiko        2020-03-02  3342  	if (!link) {
70ed506c3bbcfa Andrii Nakryiko        2020-03-02  3343  		err = -ENOMEM;
70ed506c3bbcfa Andrii Nakryiko        2020-03-02  3344  		goto out_put_prog;
70ed506c3bbcfa Andrii Nakryiko        2020-03-02  3345  	}
f7e0beaf39d386 Kui-Feng Lee           2022-05-10  3346  	bpf_link_init(&link->link.link, BPF_LINK_TYPE_TRACING,
f2e10bff16a0fd Andrii Nakryiko        2020-04-28  3347  		      &bpf_tracing_link_lops, prog);
f2e10bff16a0fd Andrii Nakryiko        2020-04-28  3348  	link->attach_type = prog->expected_attach_type;
2fcc82411e74e5 Kui-Feng Lee           2022-05-10  3349  	link->link.cookie = bpf_cookie;
70ed506c3bbcfa Andrii Nakryiko        2020-03-02  3350  

[ snip ]

3aac1ead5eb6b7 Toke H?iland-J?rgensen 2020-09-29  3474  	prog->aux->dst_trampoline = NULL;
5f80eb32851d7a Menglong Dong          2024-02-20  3475  	prog->aux->mod = NULL;
3aac1ead5eb6b7 Toke H?iland-J?rgensen 2020-09-29  3476  	mutex_unlock(&prog->aux->dst_mutex);
3aac1ead5eb6b7 Toke H?iland-J?rgensen 2020-09-29  3477  
a3b80e1078943d Andrii Nakryiko        2020-04-28  3478  	return bpf_link_settle(&link_primer);
3aac1ead5eb6b7 Toke H?iland-J?rgensen 2020-09-29  3479  out_unlock:
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3480  	if (tr && tr != prog->aux->dst_trampoline)
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3481  		bpf_trampoline_put(tr);
5f80eb32851d7a Menglong Dong          2024-02-20  3482  	if (mod && mod != prog->aux->mod)
5f80eb32851d7a Menglong Dong          2024-02-20  3483  		module_put(mod);
3aac1ead5eb6b7 Toke H?iland-J?rgensen 2020-09-29  3484  	mutex_unlock(&prog->aux->dst_mutex);
3aac1ead5eb6b7 Toke H?iland-J?rgensen 2020-09-29 @3485  	kfree(link);
                                                                      ^^^^

fec56f5890d93f Alexei Starovoitov     2019-11-14  3486  out_put_prog:
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3487  	if (tgt_prog_fd && tgt_prog)
4a1e7c0c63e02d Toke H?iland-J?rgensen 2020-09-29  3488  		bpf_prog_put(tgt_prog);
5f80eb32851d7a Menglong Dong          2024-02-20  3489  	btf_put(attach_btf);
fec56f5890d93f Alexei Starovoitov     2019-11-14  3490  	return err;
fec56f5890d93f Alexei Starovoitov     2019-11-14  3491  }

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki



From manikandan.m at microchip.com  Tue Feb 20 21:35:24 2024
From: manikandan.m at microchip.com (Manikandan Muralidharan)
Date: Wed, 21 Feb 2024 11:05:24 +0530
Subject: [PATCH v8 0/7] Add support for XLCDC to sam9x7 SoC family.
Message-ID: <20240221053531.12701-1-manikandan.m@microchip.com>

This patch series aims to add support for XLCDC IP of sam9x7 SoC family
to the DRM subsystem.XLCDC IP has additional registers and new
configuration bits compared to the existing register set of HLCDC IP.
The new compatible string "microchip,sam9x75-xlcdc" is defined for sam9x75
variant of the sam9x7 SoC family.The is_xlcdc flag under driver data and
IP specific driver ops helps to differentiate the XLCDC and existing HLCDC
code within the same driver.

changes in v8:
* Re-arrange the patch set to prepare and update the current HLCDC
code base with the new LCDC IP based driver ops and then add support
for XLCDC code changes.
* Fix Cosmetic issues.

changes in v7:
* LCDC IP driver ops functions are declared static and its 
declaration are removed.

changes in v6:
* Fixed Cosmetic defects.
* Added comments for readability.

changes in v5:
* return value of regmap_read_poll_timeout is checked in failure
case.
* HLCDC and XLCDC specific driver functions are now invoked
using its IP specific driver ops w/o the need of checking is_xlcdc flag.
* Removed empty spaces and blank lines.

changes in v4:
* fixed kernel warnings reported by kernel test robot.

changes in v3:
* Removed de-referencing the value of is_xlcdc flag multiple times in
a single function.
* Removed cpu_relax() call when using regmap_read_poll_timeout.
* Updated xfactor and yfactor equations using shift operators
* Defined CSC co-efficients in an array for code readability.

changes in v2:
* Change the driver compatible name from "microchip,sam9x7-xlcdc" to
"microchip,sam9x75-xlcdc".
* Move is_xlcdc flag to driver data.
* Remove unsed Macro definitions.
* Add co-developed-bys tags
* Replace regmap_read() with regmap_read_poll_timeout() call
* Split code into two helpers for code readablitity.
---

Durai Manickam KR (1):
  drm: atmel-hlcdc: Define XLCDC specific registers

Manikandan Muralidharan (6):
  drm: atmel-hlcdc: add driver ops to differentiate HLCDC and XLCDC IP
  drm: atmel_hlcdc: Add support for XLCDC using IP specific driver ops
  drm: atmel-hlcdc: add DPI mode support for XLCDC
  drm: atmel-hlcdc: add vertical and horizontal scaling support for
    XLCDC
  drm: atmel-hlcdc: add support for DSI output formats
  drm: atmel-hlcdc: add LCD controller layer definition for sam9x75

 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c    | 176 +++++++--
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c  | 105 +++++
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h  | 133 +++++--
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   | 369 +++++++++++++++---
 include/linux/mfd/atmel-hlcdc.h               |  10 +
 5 files changed, 678 insertions(+), 115 deletions(-)

-- 
2.25.1



From manikandan.m at microchip.com  Tue Feb 20 21:35:25 2024
From: manikandan.m at microchip.com (Manikandan Muralidharan)
Date: Wed, 21 Feb 2024 11:05:25 +0530
Subject: [PATCH v8 1/7] drm: atmel-hlcdc: add driver ops to differentiate HLCDC and XLCDC IP
In-Reply-To: <20240221053531.12701-1-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
Message-ID: <20240221053531.12701-2-manikandan.m@microchip.com>

Add LCD IP specific ops in driver data to differentiate
HLCDC and XLCDC code within the atmel-hlcdc driver files.
XLCDC in SAM9X7 has different sets of registers and additional
configuration bits when compared to previous HLCDC IP. Read/write
operation on the controller register and functionality is now
separated using the LCD IP specific ops.

Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c  |   5 +
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h  |  84 ++++++---
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   | 167 +++++++++++-------
 3 files changed, 173 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 84c54e8622d1..b09df821cbc0 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -58,6 +58,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9n12 = {
 	.conflicting_output_formats = true,
 	.nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9n12_layers),
 	.layers = atmel_hlcdc_at91sam9n12_layers,
+	.ops = &atmel_hlcdc_ops,
 };
 
 static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
@@ -151,6 +152,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9x5 = {
 	.conflicting_output_formats = true,
 	.nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9x5_layers),
 	.layers = atmel_hlcdc_at91sam9x5_layers,
+	.ops = &atmel_hlcdc_ops,
 };
 
 static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
@@ -269,6 +271,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d3 = {
 	.conflicting_output_formats = true,
 	.nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d3_layers),
 	.layers = atmel_hlcdc_sama5d3_layers,
+	.ops = &atmel_hlcdc_ops,
 };
 
 static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
@@ -364,6 +367,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d4 = {
 	.max_hpw = 0x3ff,
 	.nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d4_layers),
 	.layers = atmel_hlcdc_sama5d4_layers,
+	.ops = &atmel_hlcdc_ops,
 };
 
 static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sam9x60_layers[] = {
@@ -460,6 +464,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = {
 	.fixed_clksrc = true,
 	.nlayers = ARRAY_SIZE(atmel_hlcdc_sam9x60_layers),
 	.layers = atmel_hlcdc_sam9x60_layers,
+	.ops = &atmel_hlcdc_ops,
 };
 
 static const struct of_device_id atmel_hlcdc_of_match[] = {
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index 5b5c774e0edf..ad732edfef0b 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -288,6 +288,64 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer)
 	return container_of(layer, struct atmel_hlcdc_plane, layer);
 }
 
+/**
+ * Atmel HLCDC Display Controller.
+ *
+ * @desc: HLCDC Display Controller description
+ * @dscrpool: DMA coherent pool used to allocate DMA descriptors
+ * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device
+ * @fbdev: framebuffer device attached to the Display Controller
+ * @crtc: CRTC provided by the display controller
+ * @planes: instantiated planes
+ * @layers: active HLCDC layers
+ * @suspend: used to store the HLCDC state when entering suspend
+ */
+struct atmel_hlcdc_dc {
+	const struct atmel_hlcdc_dc_desc *desc;
+	struct dma_pool *dscrpool;
+	struct atmel_hlcdc *hlcdc;
+	struct drm_crtc *crtc;
+	struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS];
+	struct {
+		u32 imr;
+		struct drm_atomic_state *state;
+	} suspend;
+};
+
+struct atmel_hlcdc_plane_state;
+
+/**
+ * struct atmel_lcdc_dc_ops - describes atmel_lcdc ops group
+ * to differentiate HLCDC and XLCDC IP code support
+ * @plane_setup_scaler: update the vertical and horizontal scaling factors
+ * @update_lcdc_buffers: update the each LCDC layers DMA registers
+ * @lcdc_atomic_disable: disable LCDC interrupts and layers
+ * @lcdc_update_general_settings: update each LCDC layers general
+ * confiugration register
+ * @lcdc_atomic_update: enable the LCDC layers and interrupts
+ * @lcdc_csc_init: update the color space conversion co-efficient of
+ * High-end overlay register
+ * @lcdc_irq_dbg: to raise alert incase of interrupt overrun in any LCDC layer
+ */
+struct atmel_lcdc_dc_ops {
+	void (*plane_setup_scaler)(struct atmel_hlcdc_plane *plane,
+				   struct atmel_hlcdc_plane_state *state);
+	void (*update_lcdc_buffers)(struct atmel_hlcdc_plane *plane,
+				    struct atmel_hlcdc_plane_state *state,
+				    u32 sr, int i);
+	void (*lcdc_atomic_disable)(struct atmel_hlcdc_plane *plane);
+	void (*lcdc_update_general_settings)(struct atmel_hlcdc_plane *plane,
+					     struct atmel_hlcdc_plane_state *state);
+	void (*lcdc_atomic_update)(struct atmel_hlcdc_plane *plane,
+				   struct atmel_hlcdc_dc *dc);
+	void (*lcdc_csc_init)(struct atmel_hlcdc_plane *plane,
+			      const struct atmel_hlcdc_layer_desc *desc);
+	void (*lcdc_irq_dbg)(struct atmel_hlcdc_plane *plane,
+			     const struct atmel_hlcdc_layer_desc *desc);
+};
+
+extern const struct atmel_lcdc_dc_ops atmel_hlcdc_ops;
+
 /**
  * Atmel HLCDC Display Controller description structure.
  *
@@ -306,6 +364,7 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer)
  * @fixed_clksrc: true if clock source is fixed
  * @layers: a layer description table describing available layers
  * @nlayers: layer description table size
+ * @ops: atmel lcdc dc ops
  */
 struct atmel_hlcdc_dc_desc {
 	int min_width;
@@ -319,30 +378,7 @@ struct atmel_hlcdc_dc_desc {
 	bool fixed_clksrc;
 	const struct atmel_hlcdc_layer_desc *layers;
 	int nlayers;
-};
-
-/**
- * Atmel HLCDC Display Controller.
- *
- * @desc: HLCDC Display Controller description
- * @dscrpool: DMA coherent pool used to allocate DMA descriptors
- * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device
- * @fbdev: framebuffer device attached to the Display Controller
- * @crtc: CRTC provided by the display controller
- * @planes: instantiated planes
- * @layers: active HLCDC layers
- * @suspend: used to store the HLCDC state when entering suspend
- */
-struct atmel_hlcdc_dc {
-	const struct atmel_hlcdc_dc_desc *desc;
-	struct dma_pool *dscrpool;
-	struct atmel_hlcdc *hlcdc;
-	struct drm_crtc *crtc;
-	struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS];
-	struct {
-		u32 imr;
-		struct drm_atomic_state *state;
-	} suspend;
+	const struct atmel_lcdc_dc_ops *ops;
 };
 
 extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index daa508504f47..3427546cd58c 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -282,8 +282,9 @@ atmel_hlcdc_plane_scaler_set_phicoeff(struct atmel_hlcdc_plane *plane,
 					    coeff_tab[i]);
 }
 
-static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
-					   struct atmel_hlcdc_plane_state *state)
+static
+void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
+				    struct atmel_hlcdc_plane_state *state)
 {
 	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
 	u32 xfactor, yfactor;
@@ -335,6 +336,7 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
 				      struct atmel_hlcdc_plane_state *state)
 {
 	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
 
 	if (desc->layout.size)
 		atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.size,
@@ -352,12 +354,12 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
 					ATMEL_HLCDC_LAYER_POS(state->crtc_x,
 							      state->crtc_y));
 
-	atmel_hlcdc_plane_setup_scaler(plane, state);
+	dc->desc->ops->plane_setup_scaler(plane, state);
 }
 
-static void
-atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
-					struct atmel_hlcdc_plane_state *state)
+static
+void atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
+					       struct atmel_hlcdc_plane_state *state)
 {
 	unsigned int cfg = ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id;
 	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
@@ -437,10 +439,33 @@ static void atmel_hlcdc_plane_update_clut(struct atmel_hlcdc_plane *plane,
 	}
 }
 
+static void update_hlcdc_buffers(struct atmel_hlcdc_plane *plane,
+				 struct atmel_hlcdc_plane_state *state,
+				 u32 sr, int i)
+{
+	atmel_hlcdc_layer_write_reg(&plane->layer,
+				    ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
+				    state->dscrs[i]->self);
+
+	if (sr & ATMEL_HLCDC_LAYER_EN)
+		return;
+
+	atmel_hlcdc_layer_write_reg(&plane->layer,
+				    ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
+				    state->dscrs[i]->addr);
+	atmel_hlcdc_layer_write_reg(&plane->layer,
+				    ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
+				    state->dscrs[i]->ctrl);
+	atmel_hlcdc_layer_write_reg(&plane->layer,
+				    ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
+				    state->dscrs[i]->self);
+}
+
 static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
-					struct atmel_hlcdc_plane_state *state)
+					     struct atmel_hlcdc_plane_state *state)
 {
 	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
 	struct drm_framebuffer *fb = state->base.fb;
 	u32 sr;
 	int i;
@@ -452,21 +477,7 @@ static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
 
 		state->dscrs[i]->addr = gem->dma_addr + state->offsets[i];
 
-		atmel_hlcdc_layer_write_reg(&plane->layer,
-					    ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
-					    state->dscrs[i]->self);
-
-		if (!(sr & ATMEL_HLCDC_LAYER_EN)) {
-			atmel_hlcdc_layer_write_reg(&plane->layer,
-					ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
-					state->dscrs[i]->addr);
-			atmel_hlcdc_layer_write_reg(&plane->layer,
-					ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
-					state->dscrs[i]->ctrl);
-			atmel_hlcdc_layer_write_reg(&plane->layer,
-					ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
-					state->dscrs[i]->self);
-		}
+		dc->desc->ops->update_lcdc_buffers(plane, state, sr, i);
 
 		if (desc->layout.xstride[i])
 			atmel_hlcdc_layer_write_cfg(&plane->layer,
@@ -712,11 +723,8 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
 	return 0;
 }
 
-static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
-					     struct drm_atomic_state *state)
+static void hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
 {
-	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
-
 	/* Disable interrupts */
 	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IDR,
 				    0xffffffff);
@@ -731,6 +739,34 @@ static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
 	atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
 }
 
+static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
+					     struct drm_atomic_state *state)
+{
+	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
+	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
+
+	dc->desc->ops->lcdc_atomic_disable(plane);
+}
+
+static void hlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
+				struct atmel_hlcdc_dc *dc)
+{
+	u32 sr;
+
+	/* Enable the overrun interrupts. */
+	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
+				    ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
+				    ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
+				    ATMEL_HLCDC_LAYER_OVR_IRQ(2));
+
+	/* Apply the new config at the next SOF event. */
+	sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
+	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
+				    ATMEL_HLCDC_LAYER_UPDATE |
+				    (sr & ATMEL_HLCDC_LAYER_EN ?
+				    ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
+}
+
 static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
 					    struct drm_atomic_state *state)
 {
@@ -739,7 +775,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
 	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
 	struct atmel_hlcdc_plane_state *hstate =
 			drm_plane_state_to_atmel_hlcdc_plane_state(new_s);
-	u32 sr;
+	struct atmel_hlcdc_dc *dc = p->dev->dev_private;
 
 	if (!new_s->crtc || !new_s->fb)
 		return;
@@ -750,29 +786,39 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
 	}
 
 	atmel_hlcdc_plane_update_pos_and_size(plane, hstate);
-	atmel_hlcdc_plane_update_general_settings(plane, hstate);
+	dc->desc->ops->lcdc_update_general_settings(plane, hstate);
 	atmel_hlcdc_plane_update_format(plane, hstate);
 	atmel_hlcdc_plane_update_clut(plane, hstate);
 	atmel_hlcdc_plane_update_buffers(plane, hstate);
 	atmel_hlcdc_plane_update_disc_area(plane, hstate);
 
-	/* Enable the overrun interrupts. */
-	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
-				    ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
-				    ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
-				    ATMEL_HLCDC_LAYER_OVR_IRQ(2));
+	dc->desc->ops->lcdc_atomic_update(plane, dc);
+}
 
-	/* Apply the new config at the next SOF event. */
-	sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
-	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
-			ATMEL_HLCDC_LAYER_UPDATE |
-			(sr & ATMEL_HLCDC_LAYER_EN ?
-			 ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
+static void hlcdc_csc_init(struct atmel_hlcdc_plane *plane,
+			   const struct atmel_hlcdc_layer_desc *desc)
+{
+	/*
+	 * TODO: declare a "yuv-to-rgb-conv-factors" property to let
+	 * userspace modify these factors (using a BLOB property ?).
+	 */
+	static const u32 hlcdc_csc_coeffs[] = {
+		0x4c900091,
+		0x7a5f5090,
+		0x40040890
+	};
+
+	for (int i = 0; i < ARRAY_SIZE(hlcdc_csc_coeffs); i++) {
+		atmel_hlcdc_layer_write_cfg(&plane->layer,
+					    desc->layout.csc + i,
+					    hlcdc_csc_coeffs[i]);
+	}
 }
 
 static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
 {
 	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
 
 	if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
 	    desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
@@ -796,31 +842,16 @@ static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
 			return ret;
 	}
 
-	if (desc->layout.csc) {
-		/*
-		 * TODO: decare a "yuv-to-rgb-conv-factors" property to let
-		 * userspace modify these factors (using a BLOB property ?).
-		 */
-		atmel_hlcdc_layer_write_cfg(&plane->layer,
-					    desc->layout.csc,
-					    0x4c900091);
-		atmel_hlcdc_layer_write_cfg(&plane->layer,
-					    desc->layout.csc + 1,
-					    0x7a5f5090);
-		atmel_hlcdc_layer_write_cfg(&plane->layer,
-					    desc->layout.csc + 2,
-					    0x40040890);
-	}
+	if (desc->layout.csc)
+		dc->desc->ops->lcdc_csc_init(plane, desc);
 
 	return 0;
 }
 
-void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
+static void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
+			  const struct atmel_hlcdc_layer_desc *desc)
 {
-	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
-	u32 isr;
-
-	isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
+	u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
 
 	/*
 	 * There's not much we can do in case of overrun except informing
@@ -834,6 +865,24 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
 			desc->name);
 }
 
+void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
+{
+	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
+
+	dc->desc->ops->lcdc_irq_dbg(plane, desc);
+}
+
+const struct atmel_lcdc_dc_ops atmel_hlcdc_ops = {
+	.plane_setup_scaler = atmel_hlcdc_plane_setup_scaler,
+	.update_lcdc_buffers = update_hlcdc_buffers,
+	.lcdc_atomic_disable = hlcdc_atomic_disable,
+	.lcdc_update_general_settings = atmel_hlcdc_plane_update_general_settings,
+	.lcdc_atomic_update = hlcdc_atomic_update,
+	.lcdc_csc_init = hlcdc_csc_init,
+	.lcdc_irq_dbg = hlcdc_irq_dbg,
+};
+
 static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
 	.atomic_check = atmel_hlcdc_plane_atomic_check,
 	.atomic_update = atmel_hlcdc_plane_atomic_update,
-- 
2.25.1



From manikandan.m at microchip.com  Tue Feb 20 21:35:26 2024
From: manikandan.m at microchip.com (Manikandan Muralidharan)
Date: Wed, 21 Feb 2024 11:05:26 +0530
Subject: [PATCH v8 2/7] drm: atmel-hlcdc: Define XLCDC specific registers
In-Reply-To: <20240221053531.12701-1-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
Message-ID: <20240221053531.12701-3-manikandan.m@microchip.com>

From: Durai Manickam KR <durai.manickamkr at microchip.com>

The register address of the XLCDC IP used in SAM9X7 SoC family
are different from the previous HLCDC. Defining those address
space with valid macros.

Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
[manikandan.m at microchip.com: Remove unused macro definitions]
Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 42 ++++++++++++++++++++
 include/linux/mfd/atmel-hlcdc.h              | 10 +++++
 2 files changed, 52 insertions(+)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index ad732edfef0b..bc70a81b5275 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -15,6 +15,7 @@
 
 #include <drm/drm_plane.h>
 
+/* LCD controller common registers */
 #define ATMEL_HLCDC_LAYER_CHER			0x0
 #define ATMEL_HLCDC_LAYER_CHDR			0x4
 #define ATMEL_HLCDC_LAYER_CHSR			0x8
@@ -128,6 +129,47 @@
 
 #define ATMEL_HLCDC_MAX_LAYERS			6
 
+/* XLCDC controller specific registers */
+#define ATMEL_XLCDC_LAYER_ENR			0x10
+#define ATMEL_XLCDC_LAYER_EN			BIT(0)
+
+#define ATMEL_XLCDC_LAYER_IER			0x0
+#define ATMEL_XLCDC_LAYER_IDR			0x4
+#define ATMEL_XLCDC_LAYER_ISR			0xc
+#define ATMEL_XLCDC_LAYER_OVR_IRQ(p)		BIT(2 + (8 * (p)))
+
+#define ATMEL_XLCDC_LAYER_PLANE_ADDR(p)		(((p) * 0x4) + 0x18)
+
+#define ATMEL_XLCDC_LAYER_DMA_CFG		0
+
+#define ATMEL_XLCDC_LAYER_DMA			BIT(0)
+#define ATMEL_XLCDC_LAYER_REP			BIT(1)
+#define ATMEL_XLCDC_LAYER_DISCEN		BIT(4)
+
+#define ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS	(4 << 6)
+#define ATMEL_XLCDC_LAYER_SFACTA_ONE		BIT(9)
+#define ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS	(6 << 11)
+#define ATMEL_XLCDC_LAYER_DFACTA_ONE		BIT(14)
+
+#define ATMEL_XLCDC_LAYER_A0_SHIFT		16
+#define ATMEL_XLCDC_LAYER_A0(x)			\
+	((x) << ATMEL_XLCDC_LAYER_A0_SHIFT)
+
+#define ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE		BIT(0)
+#define ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE		BIT(1)
+#define ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE		BIT(4)
+#define ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE		BIT(5)
+
+#define ATMEL_XLCDC_LAYER_VXSYCFG_ONE		BIT(0)
+#define ATMEL_XLCDC_LAYER_VXSYTAP2_ENABLE	BIT(4)
+#define ATMEL_XLCDC_LAYER_VXSCCFG_ONE		BIT(16)
+#define ATMEL_XLCDC_LAYER_VXSCTAP2_ENABLE	BIT(20)
+
+#define ATMEL_XLCDC_LAYER_HXSYCFG_ONE		BIT(0)
+#define ATMEL_XLCDC_LAYER_HXSYTAP2_ENABLE	BIT(4)
+#define ATMEL_XLCDC_LAYER_HXSCCFG_ONE		BIT(16)
+#define ATMEL_XLCDC_LAYER_HXSCTAP2_ENABLE	BIT(20)
+
 /**
  * Atmel HLCDC Layer registers layout structure
  *
diff --git a/include/linux/mfd/atmel-hlcdc.h b/include/linux/mfd/atmel-hlcdc.h
index a186119a49b5..80d675a03b39 100644
--- a/include/linux/mfd/atmel-hlcdc.h
+++ b/include/linux/mfd/atmel-hlcdc.h
@@ -22,6 +22,8 @@
 #define ATMEL_HLCDC_DITHER		BIT(6)
 #define ATMEL_HLCDC_DISPDLY		BIT(7)
 #define ATMEL_HLCDC_MODE_MASK		GENMASK(9, 8)
+#define ATMEL_XLCDC_MODE_MASK		GENMASK(10, 8)
+#define ATMEL_XLCDC_DPI			BIT(11)
 #define ATMEL_HLCDC_PP			BIT(10)
 #define ATMEL_HLCDC_VSPSU		BIT(12)
 #define ATMEL_HLCDC_VSPHO		BIT(13)
@@ -34,6 +36,12 @@
 #define ATMEL_HLCDC_IDR			0x30
 #define ATMEL_HLCDC_IMR			0x34
 #define ATMEL_HLCDC_ISR			0x38
+#define ATMEL_XLCDC_ATTRE		0x3c
+
+#define ATMEL_XLCDC_BASE_UPDATE		BIT(0)
+#define ATMEL_XLCDC_OVR1_UPDATE		BIT(1)
+#define ATMEL_XLCDC_OVR3_UPDATE		BIT(2)
+#define ATMEL_XLCDC_HEO_UPDATE		BIT(3)
 
 #define ATMEL_HLCDC_CLKPOL		BIT(0)
 #define ATMEL_HLCDC_CLKSEL		BIT(2)
@@ -48,6 +56,8 @@
 #define ATMEL_HLCDC_DISP		BIT(2)
 #define ATMEL_HLCDC_PWM			BIT(3)
 #define ATMEL_HLCDC_SIP			BIT(4)
+#define ATMEL_XLCDC_SD			BIT(5)
+#define ATMEL_XLCDC_CM			BIT(6)
 
 #define ATMEL_HLCDC_SOF			BIT(0)
 #define ATMEL_HLCDC_SYNCDIS		BIT(1)
-- 
2.25.1



From manikandan.m at microchip.com  Tue Feb 20 21:35:27 2024
From: manikandan.m at microchip.com (Manikandan Muralidharan)
Date: Wed, 21 Feb 2024 11:05:27 +0530
Subject: [PATCH v8 3/7] drm: atmel_hlcdc: Add support for XLCDC using IP specific driver ops
In-Reply-To: <20240221053531.12701-1-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
Message-ID: <20240221053531.12701-4-manikandan.m@microchip.com>

Add XLCDC specific driver ops and is_xlcdc flag to separate the
functionality and to access the controller registers.
HEO scaling, window resampling, Alpha blending, YUV-to-RGB
conversion in XLCDC is derived and handled using additional
configuration bits and registers. Writing one to the Enable fields
of each layer in LCD_ATTRE is required to reflect the values set
in Configuration, FBA, Enable registers of each layer.

Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
Co-developed-by: Hari Prasath Gujulan Elango <Hari.PrasathGE at microchip.com>
Signed-off-by: Hari Prasath Gujulan Elango <Hari.PrasathGE at microchip.com>
Co-developed-by: Durai Manickam KR <durai.manickamkr at microchip.com>
Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
---
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c    |  81 +++++---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h  |   3 +
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   | 182 +++++++++++++++++-
 3 files changed, 242 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index cc5cf4c2faf7..98a98b5fca85 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -164,11 +164,13 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
 	state = drm_crtc_state_to_atmel_hlcdc_crtc_state(c->state);
 	cfg = state->output_mode << 8;
 
-	if (adj->flags & DRM_MODE_FLAG_NVSYNC)
-		cfg |= ATMEL_HLCDC_VSPOL;
+	if (!crtc->dc->desc->is_xlcdc) {
+		if (adj->flags & DRM_MODE_FLAG_NVSYNC)
+			cfg |= ATMEL_HLCDC_VSPOL;
 
-	if (adj->flags & DRM_MODE_FLAG_NHSYNC)
-		cfg |= ATMEL_HLCDC_HSPOL;
+		if (adj->flags & DRM_MODE_FLAG_NHSYNC)
+			cfg |= ATMEL_HLCDC_HSPOL;
+	}
 
 	regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5),
 			   ATMEL_HLCDC_HSPOL | ATMEL_HLCDC_VSPOL |
@@ -202,20 +204,37 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,
 
 	pm_runtime_get_sync(dev->dev);
 
+	if (crtc->dc->desc->is_xlcdc) {
+		regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_CM);
+		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+					     !(status & ATMEL_XLCDC_CM),
+					     10, 1000))
+			dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
+
+		regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_SD);
+		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+					     status & ATMEL_XLCDC_SD,
+					     10, 1000))
+			dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
+	}
+
 	regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_DISP);
-	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
-	       (status & ATMEL_HLCDC_DISP))
-		cpu_relax();
+	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+				     !(status & ATMEL_HLCDC_DISP),
+				    10, 1000))
+		dev_warn(dev->dev, "Atmel LCDC status register DISPSTS timeout\n");
 
 	regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_SYNC);
-	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
-	       (status & ATMEL_HLCDC_SYNC))
-		cpu_relax();
+	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+				     !(status & ATMEL_HLCDC_SYNC),
+				    10, 1000))
+		dev_warn(dev->dev, "Atmel LCDC status register LCDSTS timeout\n");
 
 	regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_PIXEL_CLK);
-	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
-	       (status & ATMEL_HLCDC_PIXEL_CLK))
-		cpu_relax();
+	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+				     !(status & ATMEL_HLCDC_PIXEL_CLK),
+				    10, 1000))
+		dev_warn(dev->dev, "Atmel LCDC status register CLKSTS timeout\n");
 
 	clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
 	pinctrl_pm_select_sleep_state(dev->dev);
@@ -241,20 +260,36 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
 	clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
 
 	regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PIXEL_CLK);
-	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
-	       !(status & ATMEL_HLCDC_PIXEL_CLK))
-		cpu_relax();
-
+	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+				     status & ATMEL_HLCDC_PIXEL_CLK,
+				     10, 1000))
+		dev_warn(dev->dev, "Atmel LCDC status register CLKSTS timeout\n");
 
 	regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_SYNC);
-	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
-	       !(status & ATMEL_HLCDC_SYNC))
-		cpu_relax();
+	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+				     status & ATMEL_HLCDC_SYNC,
+				     10, 1000))
+		dev_warn(dev->dev, "Atmel LCDC status register LCDSTS timeout\n");
 
 	regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_DISP);
-	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
-	       !(status & ATMEL_HLCDC_DISP))
-		cpu_relax();
+	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+				     status & ATMEL_HLCDC_DISP,
+				     10, 1000))
+		dev_warn(dev->dev, "Atmel LCDC status register DISPSTS timeout\n");
+
+	if (crtc->dc->desc->is_xlcdc) {
+		regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_CM);
+		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+					     status & ATMEL_XLCDC_CM,
+					     10, 1000))
+			dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
+
+		regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_SD);
+		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+					     !(status & ATMEL_XLCDC_SD),
+					     10, 1000))
+			dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
+	}
 
 	pm_runtime_put_sync(dev->dev);
 
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index bc70a81b5275..777987b7873d 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -387,6 +387,7 @@ struct atmel_lcdc_dc_ops {
 };
 
 extern const struct atmel_lcdc_dc_ops atmel_hlcdc_ops;
+extern const struct atmel_lcdc_dc_ops atmel_xlcdc_ops;
 
 /**
  * Atmel HLCDC Display Controller description structure.
@@ -404,6 +405,7 @@ extern const struct atmel_lcdc_dc_ops atmel_hlcdc_ops;
  * @conflicting_output_formats: true if RGBXXX output formats conflict with
  *				each other.
  * @fixed_clksrc: true if clock source is fixed
+ * @is_xlcdc: true if XLCDC IP is supported
  * @layers: a layer description table describing available layers
  * @nlayers: layer description table size
  * @ops: atmel lcdc dc ops
@@ -418,6 +420,7 @@ struct atmel_hlcdc_dc_desc {
 	int max_hpw;
 	bool conflicting_output_formats;
 	bool fixed_clksrc;
+	bool is_xlcdc;
 	const struct atmel_hlcdc_layer_desc *layers;
 	int nlayers;
 	const struct atmel_lcdc_dc_ops *ops;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 3427546cd58c..59ddd743ce92 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -331,6 +331,55 @@ void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
 								     yfactor));
 }
 
+static
+void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
+				    struct atmel_hlcdc_plane_state *state)
+{
+	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+	u32 xfactor, yfactor;
+
+	if (!desc->layout.scaler_config)
+		return;
+
+	if (state->crtc_w == state->src_w && state->crtc_h == state->src_h) {
+		atmel_hlcdc_layer_write_cfg(&plane->layer,
+					    desc->layout.scaler_config, 0);
+		return;
+	}
+
+	/* xfactor = round[(2^20 * XMEMSIZE)/XSIZE)] */
+	xfactor = (u32)(((1 << 20) * state->src_w) / state->crtc_w);
+
+	/* yfactor = round[(2^20 * YMEMSIZE)/YSIZE)] */
+	yfactor = (u32)(((1 << 20) * state->src_h) / state->crtc_h);
+
+	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config,
+				    ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE |
+				    ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE |
+				    ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE |
+				    ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE);
+
+	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 1,
+				    yfactor);
+	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 3,
+				    xfactor);
+
+	/*
+	 * With YCbCr 4:2:2 and YCbYcr 4:2:0 window resampling, configuration
+	 * register LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT is half
+	 * the value of yfactor and xfactor.
+	 */
+	if (state->base.fb->format->format == DRM_FORMAT_YUV420) {
+		yfactor /= 2;
+		xfactor /= 2;
+	}
+
+	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 2,
+				    yfactor);
+	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 4,
+				    xfactor);
+}
+
 static void
 atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
 				      struct atmel_hlcdc_plane_state *state)
@@ -395,6 +444,40 @@ void atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
 				    cfg);
 }
 
+static
+void atmel_xlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
+					       struct atmel_hlcdc_plane_state *state)
+{
+	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+	const struct drm_format_info *format = state->base.fb->format;
+	unsigned int cfg;
+
+	atmel_hlcdc_layer_write_cfg(&plane->layer, ATMEL_XLCDC_LAYER_DMA_CFG,
+				    ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id);
+
+	cfg = ATMEL_XLCDC_LAYER_DMA | ATMEL_XLCDC_LAYER_REP;
+
+	if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) {
+		/*
+		 * Alpha Blending bits specific to SAM9X7 SoC
+		 */
+		cfg |= ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS |
+		       ATMEL_XLCDC_LAYER_SFACTA_ONE |
+		       ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS |
+		       ATMEL_XLCDC_LAYER_DFACTA_ONE;
+		if (format->has_alpha)
+			cfg |= ATMEL_XLCDC_LAYER_A0(0xff);
+		else
+			cfg |= ATMEL_XLCDC_LAYER_A0(state->base.alpha);
+	}
+
+	if (state->disc_h && state->disc_w)
+		cfg |= ATMEL_XLCDC_LAYER_DISCEN;
+
+	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.general_config,
+				    cfg);
+}
+
 static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
 					struct atmel_hlcdc_plane_state *state)
 {
@@ -461,6 +544,15 @@ static void update_hlcdc_buffers(struct atmel_hlcdc_plane *plane,
 				    state->dscrs[i]->self);
 }
 
+static void update_xlcdc_buffers(struct atmel_hlcdc_plane *plane,
+				 struct atmel_hlcdc_plane_state *state,
+				 u32 sr, int i)
+{
+	atmel_hlcdc_layer_write_reg(&plane->layer,
+				    ATMEL_XLCDC_LAYER_PLANE_ADDR(i),
+				    state->dscrs[i]->addr);
+}
+
 static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
 					     struct atmel_hlcdc_plane_state *state)
 {
@@ -470,7 +562,8 @@ static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
 	u32 sr;
 	int i;
 
-	sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
+	if (!dc->desc->is_xlcdc)
+		sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
 
 	for (i = 0; i < state->nplanes; i++) {
 		struct drm_gem_dma_object *gem = drm_fb_dma_get_gem_obj(fb, i);
@@ -739,6 +832,20 @@ static void hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
 	atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
 }
 
+static void xlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
+{
+	/* Disable interrupts */
+	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IDR,
+				    0xffffffff);
+
+	/* Disable the layer */
+	atmel_hlcdc_layer_write_reg(&plane->layer,
+				    ATMEL_XLCDC_LAYER_ENR, 0);
+
+	/* Clear all pending interrupts */
+	atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
+}
+
 static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
 					     struct drm_atomic_state *state)
 {
@@ -767,6 +874,28 @@ static void hlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
 				    ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
 }
 
+static void xlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
+				struct atmel_hlcdc_dc *dc)
+{
+	/* Enable the overrun interrupts. */
+	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IER,
+				    ATMEL_XLCDC_LAYER_OVR_IRQ(0) |
+				    ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
+				    ATMEL_XLCDC_LAYER_OVR_IRQ(2));
+
+	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_ENR,
+				    ATMEL_XLCDC_LAYER_EN);
+
+	/*
+	 * Updating XLCDC_xxxCFGx, XLCDC_xxxFBA and XLCDC_xxxEN,
+	 * (where xxx indicates each layer) requires writing one to the
+	 * Update Attribute field for each layer in LCDC_ATTRE register for SAM9X7.
+	 */
+	regmap_write(dc->hlcdc->regmap, ATMEL_XLCDC_ATTRE, ATMEL_XLCDC_BASE_UPDATE |
+		     ATMEL_XLCDC_OVR1_UPDATE | ATMEL_XLCDC_OVR3_UPDATE |
+		     ATMEL_XLCDC_HEO_UPDATE);
+}
+
 static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
 					    struct drm_atomic_state *state)
 {
@@ -815,6 +944,30 @@ static void hlcdc_csc_init(struct atmel_hlcdc_plane *plane,
 	}
 }
 
+static void xlcdc_csc_init(struct atmel_hlcdc_plane *plane,
+			   const struct atmel_hlcdc_layer_desc *desc)
+{
+	/*
+	 * yuv-to-rgb-conv-factors are now defined from LCDC_HEOCFG16 to
+	 * LCDC_HEOCFG21 registers in SAM9X7.
+	 */
+	static const u32 xlcdc_csc_coeffs[] = {
+		0x00000488,
+		0x00000648,
+		0x1EA00480,
+		0x00001D28,
+		0x08100480,
+		0x00000000,
+		0x00000007
+	};
+
+	for (int i = 0; i < ARRAY_SIZE(xlcdc_csc_coeffs); i++) {
+		atmel_hlcdc_layer_write_cfg(&plane->layer,
+					    desc->layout.csc + i,
+					    xlcdc_csc_coeffs[i]);
+	}
+}
+
 static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
 {
 	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
@@ -865,6 +1018,23 @@ static void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
 			desc->name);
 }
 
+static void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
+			  const struct atmel_hlcdc_layer_desc *desc)
+{
+	u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
+
+	/*
+	 * There's not much we can do in case of overrun except informing
+	 * the user. However, we are in interrupt context here, hence the
+	 * use of dev_dbg().
+	 */
+	if (isr &
+	    (ATMEL_XLCDC_LAYER_OVR_IRQ(0) | ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
+	     ATMEL_XLCDC_LAYER_OVR_IRQ(2)))
+		dev_dbg(plane->base.dev->dev, "overrun on plane %s\n",
+			desc->name);
+}
+
 void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
 {
 	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
@@ -883,6 +1053,16 @@ const struct atmel_lcdc_dc_ops atmel_hlcdc_ops = {
 	.lcdc_irq_dbg = hlcdc_irq_dbg,
 };
 
+const struct atmel_lcdc_dc_ops atmel_xlcdc_ops = {
+	.plane_setup_scaler = atmel_xlcdc_plane_setup_scaler,
+	.update_lcdc_buffers = update_xlcdc_buffers,
+	.lcdc_atomic_disable = xlcdc_atomic_disable,
+	.lcdc_update_general_settings = atmel_xlcdc_plane_update_general_settings,
+	.lcdc_atomic_update = xlcdc_atomic_update,
+	.lcdc_csc_init = xlcdc_csc_init,
+	.lcdc_irq_dbg = xlcdc_irq_dbg,
+};
+
 static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
 	.atomic_check = atmel_hlcdc_plane_atomic_check,
 	.atomic_update = atmel_hlcdc_plane_atomic_update,
-- 
2.25.1



From manikandan.m at microchip.com  Tue Feb 20 21:35:28 2024
From: manikandan.m at microchip.com (Manikandan Muralidharan)
Date: Wed, 21 Feb 2024 11:05:28 +0530
Subject: [PATCH v8 4/7] drm: atmel-hlcdc: add DPI mode support for XLCDC
In-Reply-To: <20240221053531.12701-1-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
Message-ID: <20240221053531.12701-5-manikandan.m@microchip.com>

Add support for Display Pixel Interface (DPI) Compatible Mode
support in atmel-hlcdc driver for XLCDC IP along with legacy
pixel mapping. DPI mode BIT is configured in LCDC_CFG5 register.

Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
[durai.manickamkr at microchip.com: update DPI mode bit using is_xlcdc flag]
Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
---
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c    | 21 +++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index 98a98b5fca85..fdd3a6bc0f79 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -30,10 +30,12 @@
  *
  * @base: base CRTC state
  * @output_mode: RGBXXX output mode
+ * @dpi: output DPI mode
  */
 struct atmel_hlcdc_crtc_state {
 	struct drm_crtc_state base;
 	unsigned int output_mode;
+	u8 dpi;
 };
 
 static inline struct atmel_hlcdc_crtc_state *
@@ -170,6 +172,8 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
 
 		if (adj->flags & DRM_MODE_FLAG_NHSYNC)
 			cfg |= ATMEL_HLCDC_HSPOL;
+	} else {
+		cfg |= state->dpi << 11;
 	}
 
 	regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5),
@@ -177,7 +181,9 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
 			   ATMEL_HLCDC_VSPDLYS | ATMEL_HLCDC_VSPDLYE |
 			   ATMEL_HLCDC_DISPPOL | ATMEL_HLCDC_DISPDLY |
 			   ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO |
-			   ATMEL_HLCDC_GUARDTIME_MASK | ATMEL_HLCDC_MODE_MASK,
+			   ATMEL_HLCDC_GUARDTIME_MASK |
+			   (crtc->dc->desc->is_xlcdc ? ATMEL_XLCDC_MODE_MASK |
+			   ATMEL_XLCDC_DPI : ATMEL_HLCDC_MODE_MASK),
 			   cfg);
 
 	clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
@@ -380,7 +386,15 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
 
 	hstate = drm_crtc_state_to_atmel_hlcdc_crtc_state(state);
 	hstate->output_mode = fls(output_fmts) - 1;
-
+	if (crtc->dc->desc->is_xlcdc) {
+		/* check if MIPI DPI bit needs to be set */
+		if (fls(output_fmts) > 3) {
+			hstate->output_mode -= 4;
+			hstate->dpi = 1;
+		} else {
+			hstate->dpi = 0;
+		}
+	}
 	return 0;
 }
 
@@ -484,6 +498,7 @@ static struct drm_crtc_state *
 atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
 {
 	struct atmel_hlcdc_crtc_state *state, *cur;
+	struct atmel_hlcdc_crtc *c = drm_crtc_to_atmel_hlcdc_crtc(crtc);
 
 	if (WARN_ON(!crtc->state))
 		return NULL;
@@ -495,6 +510,8 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
 
 	cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
 	state->output_mode = cur->output_mode;
+	if (c->dc->desc->is_xlcdc)
+		state->dpi = cur->dpi;
 
 	return &state->base;
 }
-- 
2.25.1



From manikandan.m at microchip.com  Tue Feb 20 21:35:29 2024
From: manikandan.m at microchip.com (Manikandan Muralidharan)
Date: Wed, 21 Feb 2024 11:05:29 +0530
Subject: [PATCH v8 5/7] drm: atmel-hlcdc: add vertical and horizontal scaling support for XLCDC
In-Reply-To: <20240221053531.12701-1-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
Message-ID: <20240221053531.12701-6-manikandan.m@microchip.com>

Update the vertical and horizontal scaler registers of XLCDC IP
with Bilinear and Bicubic co-efficients taps for Chroma and
Luma componenets of the Pixel.

Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h  |  4 ++++
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   | 20 +++++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index 777987b7873d..fd9d9af4332c 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -198,6 +198,8 @@
  * @disc_pos: discard area position register
  * @disc_size: discard area size register
  * @csc: color space conversion register
+ * @vxs_config: vertical scalar filter taps control register
+ * @hxs_config: horizontal scalar filter taps control register
  */
 struct atmel_hlcdc_layer_cfg_layout {
 	int xstride[ATMEL_HLCDC_LAYER_MAX_PLANES];
@@ -217,6 +219,8 @@ struct atmel_hlcdc_layer_cfg_layout {
 	int disc_pos;
 	int disc_size;
 	int csc;
+	int vxs_config;
+	int hxs_config;
 };
 
 /**
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 59ddd743ce92..a527badf865d 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -966,6 +966,26 @@ static void xlcdc_csc_init(struct atmel_hlcdc_plane *plane,
 					    desc->layout.csc + i,
 					    xlcdc_csc_coeffs[i]);
 	}
+
+	if (desc->layout.vxs_config && desc->layout.hxs_config) {
+		/*
+		 * Updating vxs.config and hxs.config fixes the
+		 * Green Color Issue in SAM9X7 EGT Video Player App
+		 */
+		atmel_hlcdc_layer_write_cfg(&plane->layer,
+					    desc->layout.vxs_config,
+					    ATMEL_XLCDC_LAYER_VXSYCFG_ONE |
+					    ATMEL_XLCDC_LAYER_VXSYTAP2_ENABLE |
+					    ATMEL_XLCDC_LAYER_VXSCCFG_ONE |
+					    ATMEL_XLCDC_LAYER_VXSCTAP2_ENABLE);
+
+		atmel_hlcdc_layer_write_cfg(&plane->layer,
+					    desc->layout.hxs_config,
+					    ATMEL_XLCDC_LAYER_HXSYCFG_ONE |
+					    ATMEL_XLCDC_LAYER_HXSYTAP2_ENABLE |
+					    ATMEL_XLCDC_LAYER_HXSCCFG_ONE |
+					    ATMEL_XLCDC_LAYER_HXSCTAP2_ENABLE);
+	}
 }
 
 static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
-- 
2.25.1



From manikandan.m at microchip.com  Tue Feb 20 21:35:30 2024
From: manikandan.m at microchip.com (Manikandan Muralidharan)
Date: Wed, 21 Feb 2024 11:05:30 +0530
Subject: [PATCH v8 6/7] drm: atmel-hlcdc: add support for DSI output formats
In-Reply-To: <20240221053531.12701-1-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
Message-ID: <20240221053531.12701-7-manikandan.m@microchip.com>

Add support for the following DPI mode if the encoder type
is DSI as per the XLCDC IP datasheet:
- 16BPPCFG1
- 16BPPCFG2
- 16BPPCFG3
- 18BPPCFG1
- 18BPPCFG2
- 24BPP

Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
[durai.manickamkr at microchip.com: update output format using is_xlcdc flag]
Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
---
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c    | 74 +++++++++++++++++--
 1 file changed, 68 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index fdd3a6bc0f79..0dbe85686fc2 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -301,11 +301,64 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
 
 }
 
-#define ATMEL_HLCDC_RGB444_OUTPUT	BIT(0)
-#define ATMEL_HLCDC_RGB565_OUTPUT	BIT(1)
-#define ATMEL_HLCDC_RGB666_OUTPUT	BIT(2)
-#define ATMEL_HLCDC_RGB888_OUTPUT	BIT(3)
-#define ATMEL_HLCDC_OUTPUT_MODE_MASK	GENMASK(3, 0)
+#define ATMEL_HLCDC_RGB444_OUTPUT		BIT(0)
+#define ATMEL_HLCDC_RGB565_OUTPUT		BIT(1)
+#define ATMEL_HLCDC_RGB666_OUTPUT		BIT(2)
+#define ATMEL_HLCDC_RGB888_OUTPUT		BIT(3)
+#define ATMEL_HLCDC_DPI_RGB565C1_OUTPUT		BIT(4)
+#define ATMEL_HLCDC_DPI_RGB565C2_OUTPUT		BIT(5)
+#define ATMEL_HLCDC_DPI_RGB565C3_OUTPUT		BIT(6)
+#define ATMEL_HLCDC_DPI_RGB666C1_OUTPUT		BIT(7)
+#define ATMEL_HLCDC_DPI_RGB666C2_OUTPUT		BIT(8)
+#define ATMEL_HLCDC_DPI_RGB888_OUTPUT		BIT(9)
+#define ATMEL_HLCDC_OUTPUT_MODE_MASK		GENMASK(3, 0)
+#define ATMEL_XLCDC_OUTPUT_MODE_MASK		GENMASK(9, 0)
+
+static int atmel_hlcdc_connector_output_dsi(struct drm_encoder *encoder,
+					    struct drm_display_info *info)
+{
+	int j;
+	unsigned int supported_fmts = 0;
+
+	switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
+	case 0:
+		break;
+	case MEDIA_BUS_FMT_RGB565_1X16:
+		return ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
+	case MEDIA_BUS_FMT_RGB666_1X18:
+		return ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
+	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
+		return ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
+	case MEDIA_BUS_FMT_RGB888_1X24:
+		return ATMEL_HLCDC_DPI_RGB888_OUTPUT;
+	default:
+		return -EINVAL;
+	}
+
+	for (j = 0; j < info->num_bus_formats; j++) {
+		switch (info->bus_formats[j]) {
+		case MEDIA_BUS_FMT_RGB565_1X16:
+			supported_fmts |=
+				ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
+			break;
+		case MEDIA_BUS_FMT_RGB666_1X18:
+			supported_fmts |=
+				ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
+			break;
+		case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
+			supported_fmts |=
+				ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
+			break;
+		case MEDIA_BUS_FMT_RGB888_1X24:
+			supported_fmts |=
+				ATMEL_HLCDC_DPI_RGB888_OUTPUT;
+			break;
+		default:
+			break;
+		}
+	}
+	return supported_fmts;
+}
 
 static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
 {
@@ -318,6 +371,13 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
 	encoder = state->best_encoder;
 	if (!encoder)
 		encoder = connector->encoder;
+	/*
+	 * atmel-hlcdc to support DSI formats with DSI video pipeline
+	 * when DRM_MODE_ENCODER_DSI type is set by
+	 * connector driver component.
+	 */
+	if (encoder->encoder_type == DRM_MODE_ENCODER_DSI)
+		return atmel_hlcdc_connector_output_dsi(encoder, info);
 
 	switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
 	case 0:
@@ -358,7 +418,7 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
 
 static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
 {
-	unsigned int output_fmts = ATMEL_HLCDC_OUTPUT_MODE_MASK;
+	unsigned int output_fmts;
 	struct atmel_hlcdc_crtc_state *hstate;
 	struct drm_connector_state *cstate;
 	struct drm_connector *connector;
@@ -366,6 +426,8 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
 	int i;
 
 	crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc);
+	output_fmts = crtc->dc->desc->is_xlcdc ? ATMEL_XLCDC_OUTPUT_MODE_MASK :
+		      ATMEL_HLCDC_OUTPUT_MODE_MASK;
 
 	for_each_new_connector_in_state(state->state, connector, cstate, i) {
 		unsigned int supported_fmts = 0;
-- 
2.25.1



From manikandan.m at microchip.com  Tue Feb 20 21:35:31 2024
From: manikandan.m at microchip.com (Manikandan Muralidharan)
Date: Wed, 21 Feb 2024 11:05:31 +0530
Subject: [PATCH v8 7/7] drm: atmel-hlcdc: add LCD controller layer definition for sam9x75
In-Reply-To: <20240221053531.12701-1-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
Message-ID: <20240221053531.12701-8-manikandan.m@microchip.com>

Add the LCD controller layer definition and descriptor structure for
sam9x75 for the following layers:
- Base Layer
- Overlay1 Layer
- Overlay2 Layer
- High End Overlay

Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 100 +++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index b09df821cbc0..9ce429f889ca 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -467,6 +467,102 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = {
 	.ops = &atmel_hlcdc_ops,
 };
 
+static const struct atmel_hlcdc_layer_desc atmel_xlcdc_sam9x75_layers[] = {
+	{
+		.name = "base",
+		.formats = &atmel_hlcdc_plane_rgb_formats,
+		.regs_offset = 0x60,
+		.id = 0,
+		.type = ATMEL_HLCDC_BASE_LAYER,
+		.cfgs_offset = 0x1c,
+		.layout = {
+			.xstride = { 2 },
+			.default_color = 3,
+			.general_config = 4,
+			.disc_pos = 5,
+			.disc_size = 6,
+		},
+		.clut_offset = 0x700,
+	},
+	{
+		.name = "overlay1",
+		.formats = &atmel_hlcdc_plane_rgb_formats,
+		.regs_offset = 0x160,
+		.id = 1,
+		.type = ATMEL_HLCDC_OVERLAY_LAYER,
+		.cfgs_offset = 0x1c,
+		.layout = {
+			.pos = 2,
+			.size = 3,
+			.xstride = { 4 },
+			.pstride = { 5 },
+			.default_color = 6,
+			.chroma_key = 7,
+			.chroma_key_mask = 8,
+			.general_config = 9,
+		},
+		.clut_offset = 0xb00,
+	},
+	{
+		.name = "overlay2",
+		.formats = &atmel_hlcdc_plane_rgb_formats,
+		.regs_offset = 0x260,
+		.id = 2,
+		.type = ATMEL_HLCDC_OVERLAY_LAYER,
+		.cfgs_offset = 0x1c,
+		.layout = {
+			.pos = 2,
+			.size = 3,
+			.xstride = { 4 },
+			.pstride = { 5 },
+			.default_color = 6,
+			.chroma_key = 7,
+			.chroma_key_mask = 8,
+			.general_config = 9,
+		},
+		.clut_offset = 0xf00,
+	},
+	{
+		.name = "high-end-overlay",
+		.formats = &atmel_hlcdc_plane_rgb_and_yuv_formats,
+		.regs_offset = 0x360,
+		.id = 3,
+		.type = ATMEL_HLCDC_OVERLAY_LAYER,
+		.cfgs_offset = 0x30,
+		.layout = {
+			.pos = 2,
+			.size = 3,
+			.memsize = 4,
+			.xstride = { 5, 7 },
+			.pstride = { 6, 8 },
+			.default_color = 9,
+			.chroma_key = 10,
+			.chroma_key_mask = 11,
+			.general_config = 12,
+			.csc = 16,
+			.scaler_config = 23,
+			.vxs_config = 30,
+			.hxs_config = 31,
+		},
+		.clut_offset = 0x1300,
+	},
+};
+
+static const struct atmel_hlcdc_dc_desc atmel_xlcdc_dc_sam9x75 = {
+	.min_width = 0,
+	.min_height = 0,
+	.max_width = 2048,
+	.max_height = 2048,
+	.max_spw = 0x3ff,
+	.max_vpw = 0x3ff,
+	.max_hpw = 0x3ff,
+	.fixed_clksrc = true,
+	.is_xlcdc = true,
+	.nlayers = ARRAY_SIZE(atmel_xlcdc_sam9x75_layers),
+	.layers = atmel_xlcdc_sam9x75_layers,
+	.ops = &atmel_xlcdc_ops,
+};
+
 static const struct of_device_id atmel_hlcdc_of_match[] = {
 	{
 		.compatible = "atmel,at91sam9n12-hlcdc",
@@ -492,6 +588,10 @@ static const struct of_device_id atmel_hlcdc_of_match[] = {
 		.compatible = "microchip,sam9x60-hlcdc",
 		.data = &atmel_hlcdc_dc_sam9x60,
 	},
+	{
+		.compatible = "microchip,sam9x75-xlcdc",
+		.data = &atmel_xlcdc_dc_sam9x75,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, atmel_hlcdc_of_match);
-- 
2.25.1



From sfr at canb.auug.org.au  Tue Feb 20 21:38:54 2024
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Wed, 21 Feb 2024 16:38:54 +1100
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <20240221163010.5f81813a@canb.auug.org.au>
References: <20240221092826.748e70c4@canb.auug.org.au>
	<20240221163010.5f81813a@canb.auug.org.au>
Message-ID: <20240221163854.3ccca24d@canb.auug.org.au>

Hi all,

On Wed, 21 Feb 2024 16:30:10 +1100 Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> 
> On Wed, 21 Feb 2024 09:28:26 +1100 Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> >
> > After merging the arm-soc-fixes tree, today's linux-next build (arm
> > multi_v7_defconfig) produced this warning:
> > 
> > arch/arm/boot/dts/renesas/r8a7790-lager.dts:444.11-458.5: Warning (interrupt_provider): /i2c-mux4/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7790-lager.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7792-blanche.dts:376.10-392.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7792-blanche.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7790-stout.dts:344.10-362.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7790-stout.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7791-koelsch.dts:816.10-830.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7791-koelsch.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7791-porter.dts:410.10-420.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 5a: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7791-porter.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7794-alt.dts:450.10-464.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7794-alt.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7794-silk.dts:436.10-454.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7794-silk.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7793-gose.dts:756.10-770.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > 
> > Introduced/exposed by commit
> > 
> >   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
> > 
> > I guess you missed some :-(  
> 
> Also these from the arm64 defconfig build:
> 
> arch/arm64/boot/dts/freescale/mba8xx.dtsi:233.20-249.4: Warning (interrupt_provider): /bus at 5a000000/i2c at 5a810000/gpio at 70: Missing '#interrupt-cells' in interrupt provider
> arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm64/boot/dts/freescale/mba8xx.dtsi:233.20-249.4: Warning (interrupt_provider): /bus at 5a000000/i2c at 5a810000/gpio at 70: Missing '#interrupt-cells' in interrupt provider
> arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp-mba8xx.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'

And these from the powerpc ppc44x_defconfig build:

arch/powerpc/boot/dts/sam440ep.dts:266.22-287.5: Warning (interrupt_provider): /plb/pci at ec000000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/sam440ep.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'

And these from the powerpc allyesconfig build:

arch/powerpc/boot/dts/mpc5200b.dtsi:267.20-282.4: Warning (interrupt_provider): /pci at f0000d00: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/a3m071.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5121.dtsi:508.20-525.4: Warning (interrupt_provider): /pci at 80008500: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/ac14xx.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/amigaone.dts:57.9-163.5: Warning (interrupt_provider): /pci at 80000000/isa at 7: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/amigaone.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5200b.dtsi:267.20-282.4: Warning (interrupt_provider): /pci at f0000d00: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/cm5200.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/ep8248e.dts:101.13-190.5: Warning (interrupt_provider): /soc at f0000000/cpm at 119c0: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/ep8248e.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/ep88xc.dts:122.13-131.5: Warning (interrupt_provider): /soc at fa200000/pcmcia at 80: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/ep88xc.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsp2.dts:392.24-397.5: Warning (interrupt_provider): /plb4/plb6-system-hung-irq: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsp2.dts:399.16-404.5: Warning (interrupt_provider): /plb4/l2-error-irq: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsp2.dts:406.17-411.5: Warning (interrupt_provider): /plb4/plb6-plb4-irq: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsp2.dts:413.16-418.5: Warning (interrupt_provider): /plb4/plb4-ahb-irq: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsp2.dts:420.18-425.5: Warning (interrupt_provider): /plb4/opbd-error-irq: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsp2.dts:427.17-432.5: Warning (interrupt_provider): /plb4/cmu-error-irq: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsp2.dts:434.18-439.5: Warning (interrupt_provider): /plb4/conf-error-irq: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsp2.dts:441.13-446.5: Warning (interrupt_provider): /plb4/mc-ue-irq: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsp2.dts:448.21-453.5: Warning (interrupt_provider): /plb4/reset-warning-irq: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsp2.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/gef_ppc9a.dts:195.22-209.4: Warning (interrupt_provider): /pcie at fef08000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/gef_ppc9a.dts:211.22-213.4: Warning (interrupt_provider): /pcie at fef09000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/gef_ppc9a.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/gef_sbc310.dts:217.22-231.4: Warning (interrupt_provider): /pcie at fef09000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/gef_sbc310.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/gef_sbc610.dts:193.22-207.4: Warning (interrupt_provider): /pcie at fef08000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/gef_sbc610.dts:209.22-211.4: Warning (interrupt_provider): /pcie at fef09000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/gef_sbc610.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/mpc8544ds.dtsi:154.11-204.6: Warning (interrupt_provider): /pcie at e000b000/pcie at 0/uli1575 at 0/isa at 1e: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/mpc8544ds.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/mpc8572ds.dtsi:375.11-425.6: Warning (interrupt_provider): /pcie at ffe08000/pcie at 0/uli1575 at 0/isa at 1e: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/mpc8572ds.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/mpc8572ds.dtsi:375.11-425.6: Warning (interrupt_provider): /pcie at fffe08000/pcie at 0/uli1575 at 0/isa at 1e: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/mpc8572ds_36b.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/mpc8572ds.dtsi:375.11-425.6: Warning (interrupt_provider): /pcie at ffe08000/pcie at 0/uli1575 at 0/isa at 1e: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/mpc8572ds_camp_core0.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/mpc8572ds.dtsi:375.11-425.6: Warning (interrupt_provider): /pcie at ffe08000/pcie at 0/uli1575 at 0/isa at 1e: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/mpc8572ds_camp_core1.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5200b.dtsi:267.20-282.4: Warning (interrupt_provider): /pci at f0000d00: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/motionpro.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mgcoge.dts:105.13-230.5: Warning (interrupt_provider): /soc at f0000000/cpm at 119c0: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/mgcoge.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/mvme7100.dts:135.22-137.4: Warning (interrupt_provider): /pcie at f1008000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/mvme7100.dts:139.22-141.4: Warning (interrupt_provider): /pcie at f1009000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/mvme7100.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc885ads.dts:127.13-136.5: Warning (interrupt_provider): /soc at ff000000/pcmcia at 80: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/mpc885ads.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mvme5100.dts:155.7-177.5: Warning (interrupt_provider): /pci at feff0000/isa: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/mvme5100.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5200b.dtsi:267.20-282.4: Warning (interrupt_provider): /pci at f0000d00: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/o2d300.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5200b.dtsi:267.20-282.4: Warning (interrupt_provider): /pci at f0000d00: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/o2d.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5200b.dtsi:267.20-282.4: Warning (interrupt_provider): /pci at f0000d00: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/o2dnt2.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5200b.dtsi:267.20-282.4: Warning (interrupt_provider): /pci at f0000d00: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/o2i.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5200b.dtsi:267.20-282.4: Warning (interrupt_provider): /pci at f0000d00: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/o2mnt.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5200b.dtsi:267.20-282.4: Warning (interrupt_provider): /pci at f0000d00: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/o3dnt.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5121.dtsi:508.20-525.4: Warning (interrupt_provider): /pci at 80008500: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/pdm360ng.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/sam440ep.dts:266.22-287.5: Warning (interrupt_provider): /plb/pci at ec000000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/sam440ep.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/p2020ds.dtsi:274.11-324.6: Warning (interrupt_provider): /pcie at ffe09000/pcie at 0/uli1575 at 0/isa at 1e: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/p2020ds.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/fsl/ppa8548.dts:34.22-37.4: Warning (interrupt_provider): /pci at fe0008000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/ppa8548.dts:39.22-42.4: Warning (interrupt_provider): /pci at fe0009000: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/fsl/ppa8548.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
arch/powerpc/boot/dts/mpc5200b.dtsi:267.20-282.4: Warning (interrupt_provider): /pci at f0000d00: '#interrupt-cells' found, but node is not an interrupt provider
arch/powerpc/boot/dts/uc101.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'

-- 
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/20240221/8999266a/attachment-0001.sig>

From apatel at ventanamicro.com  Tue Feb 20 21:42:22 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 21 Feb 2024 11:12:22 +0530
Subject: [PATCH v13 10/13] irqchip: Add RISC-V advanced PLIC driver for direct-mode
In-Reply-To: <87zfvvgsnr.ffs@tglx>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-11-apatel@ventanamicro.com> <87zfvvgsnr.ffs@tglx>
Message-ID: <CAK9=C2XhUQtYqe2t3HvjxMZw3ffbUCfGfBVrFHf0_Bxtpz-E9g@mail.gmail.com>

On Tue, Feb 20, 2024 at 7:10?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> > +/*
> > + * To handle an APLIC direct interrupts, we just read the CLAIMI register
> > + * which will return highest priority pending interrupt and clear the
> > + * pending bit of the interrupt. This process is repeated until CLAIMI
> > + * register return zero value.
> > + */
> > +static void aplic_direct_handle_irq(struct irq_desc *desc)
> > +{
> > +     struct aplic_idc *idc = this_cpu_ptr(&aplic_idcs);
> > +     struct irq_domain *irqdomain = idc->direct->irqdomain;
> > +     struct irq_chip *chip = irq_desc_get_chip(desc);
> > +     irq_hw_number_t hw_irq;
> > +     int irq;
> > +
> > +     chained_irq_enter(chip, desc);
> > +
> > +     while ((hw_irq = readl(idc->regs + APLIC_IDC_CLAIMI))) {
> > +             hw_irq = hw_irq >> APLIC_IDC_TOPI_ID_SHIFT;
> > +             irq = irq_find_mapping(irqdomain, hw_irq);
> > +
> > +             if (unlikely(irq <= 0))
> > +                     dev_warn_ratelimited(idc->direct->priv.dev,
> > +                                          "hw_irq %lu mapping not found\n", hw_irq);
>
> Lacks brackets. See Documentation....

Okay, I will update.

>
> > +             else
> > +                     generic_handle_irq(irq);
> > +     }
> > +
> > +static int aplic_direct_starting_cpu(unsigned int cpu)
> > +{
> > +     if (aplic_direct_parent_irq)
> > +             enable_percpu_irq(aplic_direct_parent_irq,
> > +                               irq_get_trigger_type(aplic_direct_parent_irq));
>
> Ditto.

Okay, I will update.

>
> > +     return 0;
> > +}
>
> > +void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
> > +{
> > +     u32 val;
> > +#ifdef CONFIG_RISCV_M_MODE
> > +     u32 valH;
>
> No camel case please.

Okay.

>
> > +
> > +     if (msi_mode) {
> > +             val = lower_32_bits(priv->msicfg.base_ppn);
> > +             valH = FIELD_PREP(APLIC_xMSICFGADDRH_BAPPN, upper_32_bits(priv->msicfg.base_ppn));
> > +             valH |= FIELD_PREP(APLIC_xMSICFGADDRH_LHXW, priv->msicfg.lhxw);
> > +             valH |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXW, priv->msicfg.hhxw);
> > +             valH |= FIELD_PREP(APLIC_xMSICFGADDRH_LHXS, priv->msicfg.lhxs);
> > +             valH |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXS, priv->msicfg.hhxs);
> > +             writel(val, priv->regs + APLIC_xMSICFGADDR);
> > +             writel(valH, priv->regs + APLIC_xMSICFGADDRH);
> > +     }
>
> Thanks,
>
>         tglx

Regards,
Anup


From hbathini at linux.ibm.com  Tue Feb 20 21:45:00 2024
From: hbathini at linux.ibm.com (Hari Bathini)
Date: Wed, 21 Feb 2024 11:15:00 +0530
Subject: [PATCH v2 00/14] Split crash out from kexec and clean up related
 config items
In-Reply-To: <Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv>
References: <20240119145241.769622-1-bhe@redhat.com>
 <9101bb07-70f1-476c-bec9-ec67e9899744@linux.ibm.com>
 <Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv>
Message-ID: <559f2595-1477-4ef0-80e4-85ae8b426de7@linux.ibm.com>

Hi Baoquan,

On 04/02/24 8:56 am, Baoquan He wrote:
>>> Hope Hari and Pingfan can help have a look, see if
>>> it's doable. Now, I make it either have both kexec and crash enabled, or
>>> disable both of them altogether.
>>
>> Sure. I will take a closer look...
> Thanks a lot. Please feel free to post patches to make that, or I can do
> it with your support or suggestion.

Tested your changes and on top of these changes, came up with the below
changes to get it working for powerpc:

 
https://lore.kernel.org/all/20240213113150.1148276-1-hbathini at linux.ibm.com/

Please take a look.

Thanks
Hari


From ankita at nvidia.com  Tue Feb 20 22:01:10 2024
From: ankita at nvidia.com (Ankit Agrawal)
Date: Wed, 21 Feb 2024 06:01:10 +0000
Subject: [PATCH v8 1/4] kvm: arm64: introduce new flag for non-cacheable
 IO memory
In-Reply-To: <ZdS2yl1kzZv/h+vH@lpieralisi>
References: <20240220072926.6466-1-ankita@nvidia.com>
 <20240220072926.6466-2-ankita@nvidia.com> <ZdS2yl1kzZv/h+vH@lpieralisi>
Message-ID: <SA1PR12MB7199442B899E437A3ABA2950B0572@SA1PR12MB7199.namprd12.prod.outlook.com>


>> Lastly, adapt the stage2 PTE property setter function
>> (stage2_set_prot_attr) to handle the NormalNC attribute.
>>
>> [1] section D8.5.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
>> [2] section B2.8 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
>> [3] sections 1.7.7.3/1.8.5.2/appendix C - DEN0029H_SBSA_7.1.pdf
>>
>
> A couple of Link: tags would not hurt in my opinion, lest we forget:
>
> Link: https://lore.kernel.org/r/20230907181459.18145-2-ankita at nvidia.com/
> Link: https://lore.kernel.org/r/20231205033015.10044-1-ankita at nvidia.com

Agreed, will add.

From rppt at kernel.org  Tue Feb 20 22:12:14 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Wed, 21 Feb 2024 08:12:14 +0200
Subject: [PATCH v1 0/2] support NUMA emulation for genertic arch
In-Reply-To: <20240220113602.6943-1-rongwei.wang@linux.alibaba.com>
References: <20231012024842.99703-1-rongwei.wang@linux.alibaba.com>
 <20240220113602.6943-1-rongwei.wang@linux.alibaba.com>
Message-ID: <ZdWUPlqsxC_y3YFM@kernel.org>

On Tue, Feb 20, 2024 at 07:36:00PM +0800, Rongwei Wang wrote:
> A brief introduction
> ====================
> 
> The NUMA emulation can fake more node base on a single
> node system, e.g.

... 
 
> Lastly, it seems not a good choice to realize x86 and other genertic
> archs separately. But it can indeed avoid some architecture related
> APIs adjustments and alleviate future maintenance.

Why is it a good choice? Copying 1k lines from x86 to a new place and
having to maintain two copies does not sound like a good choice to me.

> The previous RFC link see [1].
> 
> Any advice are welcome, Thanks!
> 
> Change log
> ==========
> 
> RFC v1 -> v1
> * add new CONFIG_NUMA_FAKE for genertic archs.
> * keep x86 implementation, realize numa emulation in driver/base/ for
>   genertic arch, e.g, arm64.
> 
> [1] RFC v1: https://patchwork.kernel.org/project/linux-arm-kernel/cover/20231012024842.99703-1-rongwei.wang at linux.alibaba.com/
> 
> Rongwei Wang (2):
>   arch_numa: remove __init for early_cpu_to_node
>   numa: introduce numa emulation for genertic arch
> 
>  drivers/base/Kconfig          |   9 +
>  drivers/base/Makefile         |   1 +
>  drivers/base/arch_numa.c      |  32 +-
>  drivers/base/numa_emulation.c | 909 ++++++++++++++++++++++++++++++++++
>  drivers/base/numa_emulation.h |  41 ++
>  include/asm-generic/numa.h    |   2 +-
>  6 files changed, 992 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/base/numa_emulation.c
>  create mode 100644 drivers/base/numa_emulation.h
> 
> -- 
> 2.32.0.3.gf3a3e56d6
> 
> 

-- 
Sincerely yours,
Mike.


From dan.carpenter at linaro.org  Tue Feb 20 22:16:31 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Wed, 21 Feb 2024 09:16:31 +0300
Subject: [PATCH v5 11/12] mtd: rawnand: brcmnand: exec_op helper
 functions return type fixes
In-Reply-To: <20240220110240.1ad5b995@xps-13>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-12-william.zhang@broadcom.com>
 <20240220110240.1ad5b995@xps-13>
Message-ID: <f6e61482-b51a-4970-9257-8db7975148fa@moroto.mountain>

On Tue, Feb 20, 2024 at 11:02:40AM +0100, Miquel Raynal wrote:
> 
> william.zhang at broadcom.com wrote on Wed,  7 Feb 2024 12:22:56 -0800:
> 
> > From: David Regan <dregan at broadcom.com>
> > 
> > fix return type for exec_op reset and status detect helper functions
> > 
> > Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> > Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
> > Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
> > Signed-off-by: David Regan <dregan at broadcom.com>
> > Signed-off-by: William Zhang <william.zhang at broadcom.com>
> > Reviewed-by: William Zhang <william.zhang at broadcom.com>
> 
> By the way, a Cc: stable tag might be useful as otherwise you may leak
> an error code in a status value (which is a bug). And move this patch
> first in your series so we're sure it does not conflict with any of the
> other patches and can be backported more easily.

The original commit 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op
implementation") is not in stable so we should be okay on this.

regards,
dan carpenter



From rdunlap at infradead.org  Tue Feb 20 22:21:57 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Tue, 20 Feb 2024 22:21:57 -0800
Subject: [PATCH] firmware: arm_scmi: optee: fix struct kernel-doc warnings
Message-ID: <20240221062157.8694-1-rdunlap@infradead.org>

Fix the kernel-doc notation for the nested union in struct
scmi_optee_channel to eliminate kerenl-doc warnings:

optee.c:130: warning: Excess struct member 'shmem' description in 'scmi_optee_channel'
optee.c:131: warning: Function parameter or struct member 'req' not described in 'scmi_optee_channel'

Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Cristian Marussi <cristian.marussi at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
---
 drivers/firmware/arm_scmi/optee.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff -- a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c
--- a/drivers/firmware/arm_scmi/optee.c
+++ b/drivers/firmware/arm_scmi/optee.c
@@ -109,8 +109,10 @@ enum scmi_optee_pta_cmd {
  * @rx_len: Response size
  * @mu: Mutex protection on channel access
  * @cinfo: SCMI channel information
- * @shmem: Virtual base address of the shared memory
- * @req: Shared memory protocol handle for SCMI request and synchronous response
+ * @req: union for SCMI interface
+ * @req.shmem: Virtual base address of the shared memory
+ * @req.msg: Shared memory protocol handle for SCMI request and
+ *   synchronous response
  * @tee_shm: TEE shared memory handle @req or NULL if using IOMEM shmem
  * @link: Reference in agent's channel list
  */


From keescook at chromium.org  Tue Feb 20 22:33:39 2024
From: keescook at chromium.org (Kees Cook)
Date: Tue, 20 Feb 2024 22:33:39 -0800
Subject: [RFC] arm64: syscall: Direct PRNG kstack randomization
In-Reply-To: <20240221020258.1210148-1-jeremy.linton@arm.com>
References: <20240221020258.1210148-1-jeremy.linton@arm.com>
Message-ID: <202402202226.A6817927@keescook>

On Tue, Feb 20, 2024 at 08:02:58PM -0600, Jeremy Linton wrote:
> The existing arm64 stack randomization uses the kernel rng to acquire
> 5 bits of address space randomization. This is problematic because it
> creates non determinism in the syscall path when the rng needs to be
> generated or reseeded. This shows up as large tail latencies in some
> benchmarks and directly affects the minimum RT latencies as seen by
> cyclictest.

Some questions:

- for benchmarks, why not disable kstack randomization?
- if the existing pRNG reseeding is a problem here, why isn't it a
  problem in the many other places it's used?
- I though the pRNG already did out-of-line reseeding?

> Other architectures are using timers/cycle counters for this function,
> which is sketchy from a randomization perspective because it should be
> possible to estimate this value from knowledge of the syscall return
> time, and from reading the current value of the timer/counters.

The expectation is that it would be, at best, unstable.

> So, a poor rng should be better than the cycle counter if it is hard
> to extract the stack offsets sufficiently to be able to detect the
> PRNG's period.
> 
> So, we can potentially choose a 'better' or larger PRNG, going as far
> as using one of the CSPRNGs already in the kernel, but the overhead
> increases appropriately. Further, there are a few options for
> reseeding, possibly out of the syscall path, but is it even useful in
> this case?

I'd love to find a way to avoid an pRNG that could be reconstructed
given enough samples. (But perhaps this xorshift RNG resists that?)

-Kees

> Reported-by: James Yang <james.yang at arm.com>
> Reported-by: Shiyou Huang <shiyou.huang at arm.com>
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>  arch/arm64/kernel/syscall.c | 55 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 54 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> index 9a70d9746b66..70143cb8c7be 100644
> --- a/arch/arm64/kernel/syscall.c
> +++ b/arch/arm64/kernel/syscall.c
> @@ -37,6 +37,59 @@ static long __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
>  	return syscall_fn(regs);
>  }
>  
> +#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
> +DEFINE_PER_CPU(u32, kstackrng);
> +static u32 xorshift32(u32 state)
> +{
> +	/*
> +	 * From top of page 4 of Marsaglia, "Xorshift RNGs"
> +	 * This algorithm is intended to have a period 2^32 -1
> +	 * And should not be used anywhere else outside of this
> +	 * code path.
> +	 */
> +	state ^= state << 13;
> +	state ^= state >> 17;
> +	state ^= state << 5;
> +	return state;
> +}
> +
> +static u16 kstack_rng(void)
> +{
> +	u32 rng = raw_cpu_read(kstackrng);
> +
> +	rng = xorshift32(rng);
> +	raw_cpu_write(kstackrng, rng);
> +	return rng & 0x1ff;
> +}
> +
> +/* Should we reseed? */
> +static int kstack_rng_setup(unsigned int cpu)
> +{
> +	u32 rng_seed;
> +
> +	do {
> +		rng_seed = get_random_u32();
> +	} while (!rng_seed);
> +	raw_cpu_write(kstackrng, rng_seed);
> +	return 0;
> +}
> +
> +static int kstack_init(void)
> +{
> +	int ret;
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/cpuinfo:kstackrandomize",
> +				kstack_rng_setup, NULL);
> +	if (ret < 0)
> +		pr_err("kstack: failed to register rng callbacks.\n");
> +	return 0;
> +}
> +
> +arch_initcall(kstack_init);
> +#else
> +static u16 kstack_rng(void) { return 0; }
> +#endif /* CONFIG_RANDOMIZE_KSTACK_OFFSET */
> +
>  static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
>  			   unsigned int sc_nr,
>  			   const syscall_fn_t syscall_table[])
> @@ -66,7 +119,7 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
>  	 *
>  	 * The resulting 5 bits of entropy is seen in SP[8:4].
>  	 */
> -	choose_random_kstack_offset(get_random_u16() & 0x1FF);
> +	choose_random_kstack_offset(kstack_rng());
>  }
>  
>  static inline bool has_syscall_work(unsigned long flags)
> -- 
> 2.43.0
> 

-- 
Kees Cook


From keescook at chromium.org  Tue Feb 20 22:39:15 2024
From: keescook at chromium.org (Kees Cook)
Date: Tue, 20 Feb 2024 22:39:15 -0800
Subject: [PATCH] ARM: fault: Implement copy_from_kernel_nofault_allowed()
In-Reply-To: <20240123011238.work.301-kees@kernel.org>
References: <20240123011238.work.301-kees@kernel.org>
Message-ID: <202402202235.A77C9AD@keescook>

On Mon, Jan 22, 2024 at 05:12:38PM -0800, Kees Cook wrote:
> Under PAN emulation when dumping backtraces from things like the
> LKDTM EXEC_USERSPACE test[1], a double fault (which would hang a CPU)
> would happen because of dump_instr() attempting to read a userspace
> address. Make sure copy_from_kernel_nofault() does not attempt this
> any more.
> 
> Reported-by: Mark Brown <broonie at kernel.org>
> Link: https://lore.kernel.org/all/202401181125.D48DCB4C at keescook/ [1]
> Suggested-by: "Russell King (Oracle)" <linux at armlinux.org.uk>
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Wang Kefeng <wangkefeng.wang at huawei.com>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Cc: Ben Hutchings <ben at decadent.org.uk>
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Kees Cook <keescook at chromium.org>

Russell, do you mind if I carry in my tree the 3 ARM patches I sent?
They're mostly pretty trivial, and they've been in "Incoming"[1] for 2
weeks but haven't shown up in -next yet. I'd really like them to get
some soak time, and for them to reach the v6.9 merge window in time.

Please let me know what you think. :) Thanks!

-Kees

[1] https://www.arm.linux.org.uk/developer/patches/section.php?section=0

-- 
Kees Cook


From rdunlap at infradead.org  Tue Feb 20 22:41:04 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Tue, 20 Feb 2024 22:41:04 -0800
Subject: [PATCH] irqchip: vic: fix a kernel-doc warning
Message-ID: <20240221064104.7863-1-rdunlap@infradead.org>

Drop one extraneous struct member to quieten a warning:

drivers/irqchip/irq-vic.c:73: warning: Excess struct member 'parent_irq' description in 'vic_device'

Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: Thomas Gleixner <tglx at linutronix.de>
---
 drivers/irqchip/irq-vic.c |    1 -
 1 file changed, 1 deletion(-)

diff -- a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
--- a/drivers/irqchip/irq-vic.c
+++ b/drivers/irqchip/irq-vic.c
@@ -47,7 +47,6 @@
 
 /**
  * struct vic_device - VIC PM device
- * @parent_irq: The parent IRQ number of the VIC if cascaded, or 0.
  * @irq: The IRQ number for the base of the VIC.
  * @base: The register base for the VIC.
  * @valid_sources: A bitmask of valid interrupts


From xu.yang_2 at nxp.com  Wed Feb 21 06:58:38 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 22:58:38 +0800
Subject: [PATCH v6 1/9] dt-bindings: usb: usbmisc-imx: add fsl,imx8ulp-usbmisc compatible
Message-ID: <20240221145846.1611627-1-xu.yang_2@nxp.com>

Add "fsl,imx8ulp-usbmisc" compatible.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v3:
 - new patch due to missed this little one
Changes in v4:
 - no changes
Changes in v5:
 - add Acked-by tag
Changes in v6:
 - no changes
---
 Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml b/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml
index 2d3589d284b2..0a6e7ac1b37e 100644
--- a/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml
+++ b/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml
@@ -33,6 +33,7 @@ properties:
               - fsl,imx7ulp-usbmisc
               - fsl,imx8mm-usbmisc
               - fsl,imx8mn-usbmisc
+              - fsl,imx8ulp-usbmisc
           - const: fsl,imx7d-usbmisc
           - const: fsl,imx6q-usbmisc
       - items:
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 06:58:39 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 22:58:39 +0800
Subject: [PATCH v6 2/9] arm64: dts: imx8ulp: add usb nodes
In-Reply-To: <20240221145846.1611627-1-xu.yang_2@nxp.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
Message-ID: <20240221145846.1611627-2-xu.yang_2@nxp.com>

Add USB nodes on i.MX8ULP platform which has 2 USB controllers.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - no changes
Changes in v3:
 - no changes
Changes in v4:
 - no changes
Changes in v5:
 - no changes
Changes in v6:
 - drop usbphy aliases
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 62 ++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index c4a0082f30d3..7da9461a5745 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -472,6 +472,68 @@ usdhc2: mmc at 298f0000 {
 				status = "disabled";
 			};
 
+			usbotg1: usb at 29900000 {
+				compatible = "fsl,imx8ulp-usb", "fsl,imx7ulp-usb", "fsl,imx6ul-usb";
+				reg = <0x29900000 0x200>;
+				interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&pcc4 IMX8ULP_CLK_USB0>;
+				power-domains = <&scmi_devpd IMX8ULP_PD_USB0>;
+				phys = <&usbphy1>;
+				fsl,usbmisc = <&usbmisc1 0>;
+				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x8>;
+				rx-burst-size-dword = <0x8>;
+				status = "disabled";
+			};
+
+			usbmisc1: usbmisc at 29900200 {
+				compatible = "fsl,imx8ulp-usbmisc", "fsl,imx7d-usbmisc",
+						"fsl,imx6q-usbmisc";
+				#index-cells = <1>;
+				reg = <0x29900200 0x200>;
+				status = "disabled";
+			};
+
+			usbphy1: usb-phy at 29910000 {
+				compatible = "fsl,imx8ulp-usbphy", "fsl,imx7ulp-usbphy";
+				reg = <0x29910000 0x10000>;
+				interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&pcc4 IMX8ULP_CLK_USB0_PHY>;
+				#phy-cells = <0>;
+				status = "disabled";
+			};
+
+			usbotg2: usb at 29920000 {
+				compatible = "fsl,imx8ulp-usb", "fsl,imx7ulp-usb", "fsl,imx6ul-usb";
+				reg = <0x29920000 0x200>;
+				interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&pcc4 IMX8ULP_CLK_USB1>;
+				power-domains = <&scmi_devpd IMX8ULP_PD_USDHC2_USB1>;
+				phys = <&usbphy2>;
+				fsl,usbmisc = <&usbmisc2 0>;
+				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x8>;
+				rx-burst-size-dword = <0x8>;
+				status = "disabled";
+			};
+
+			usbmisc2: usbmisc at 29920200 {
+				compatible = "fsl,imx8ulp-usbmisc", "fsl,imx7d-usbmisc",
+						"fsl,imx6q-usbmisc";
+				#index-cells = <1>;
+				reg = <0x29920200 0x200>;
+				status = "disabled";
+			};
+
+			usbphy2: usb-phy at 29930000 {
+				compatible = "fsl,imx8ulp-usbphy", "fsl,imx7ulp-usbphy";
+				reg = <0x29930000 0x10000>;
+				interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&pcc4 IMX8ULP_CLK_USB1_PHY>;
+				#phy-cells = <0>;
+				status = "disabled";
+			};
+
 			fec: ethernet at 29950000 {
 				compatible = "fsl,imx8ulp-fec", "fsl,imx6ul-fec", "fsl,imx6q-fec";
 				reg = <0x29950000 0x10000>;
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 06:58:40 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 22:58:40 +0800
Subject: [PATCH v6 3/9] arm64: dts: imx8ulp-evk: enable usb nodes and add ptn5150 nodes
In-Reply-To: <20240221145846.1611627-1-xu.yang_2@nxp.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
Message-ID: <20240221145846.1611627-3-xu.yang_2@nxp.com>

Enable 2 USB nodes and add 2 PTN5150 nodes on i.MX8ULP evk board.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - fix format as suggusted by Fabio
 - add PTN5150 nodes
Changes in v3:
 - no changes
Changes in v4:
 - no changes
Changes in v5:
 - no changes
Changes in v6:
 - no changes
---
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts | 84 +++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index 69dd8e31027c..bf418af31039 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -133,6 +133,64 @@ pcal6408: gpio at 21 {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
+
+	ptn5150_1: typec at 1d {
+		compatible = "nxp,ptn5150";
+		reg = <0x1d>;
+		int-gpios = <&gpiof 3 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_typec1>;
+		status = "disabled";
+	};
+
+	ptn5150_2: typec at 3d {
+		compatible = "nxp,ptn5150";
+		reg = <0x3d>;
+		int-gpios = <&gpiof 5 IRQ_TYPE_EDGE_FALLING>;
+			pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_typec2>;
+		status = "disabled";
+	};
+};
+
+&usbotg1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb1>;
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	over-current-active-low;
+	status = "okay";
+};
+
+&usbphy1 {
+	fsl,tx-d-cal = <110>;
+	status = "okay";
+};
+
+&usbmisc1 {
+	status = "okay";
+};
+
+&usbotg2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb2>;
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	over-current-active-low;
+	status = "okay";
+};
+
+&usbphy2 {
+	fsl,tx-d-cal = <110>;
+	status = "okay";
+};
+
+&usbmisc2 {
+	status = "okay";
 };
 
 &usdhc0 {
@@ -224,6 +282,32 @@ MX8ULP_PAD_PTE13__LPI2C7_SDA	0x20
 		>;
 	};
 
+	pinctrl_typec1: typec1grp {
+		fsl,pins = <
+			MX8ULP_PAD_PTF3__PTF3           0x3
+		>;
+	};
+
+	pinctrl_typec2: typec2grp {
+		fsl,pins = <
+			MX8ULP_PAD_PTF5__PTF5           0x3
+		>;
+	};
+
+	pinctrl_usb1: usb1grp {
+		fsl,pins = <
+			MX8ULP_PAD_PTF2__USB0_ID	0x10003
+			MX8ULP_PAD_PTF4__USB0_OC	0x10003
+		>;
+	};
+
+	pinctrl_usb2: usb2grp {
+		fsl,pins = <
+			MX8ULP_PAD_PTD23__USB1_ID	0x10003
+			MX8ULP_PAD_PTF6__USB1_OC	0x10003
+		>;
+	};
+
 	pinctrl_usdhc0: usdhc0grp {
 		fsl,pins = <
 			MX8ULP_PAD_PTD1__SDHC0_CMD	0x3
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 06:58:41 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 22:58:41 +0800
Subject: [PATCH v6 4/9] dt-bindings: usb: add NXP ChipIdea USB2 Controller schema
In-Reply-To: <20240221145846.1611627-1-xu.yang_2@nxp.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
Message-ID: <20240221145846.1611627-4-xu.yang_2@nxp.com>

As more and more NXP i.MX chips come out, it becomes harder to maintain
ci-hdrc-usb2.yaml if more stuffs like property restrictions are added to
this file. This will separate i.MX parts out of ci-hdrc-usb2.yaml and add
a new schema for NXP ChipIdea USB2 Controller.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v6:
 - new patch
---
 .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 75 +++++++++++++++++++
 1 file changed, 75 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml

diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
new file mode 100644
index 000000000000..2ec62f564bf5
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/ci-hdrc-usb2-imx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP USB2 ChipIdea USB controller
+
+maintainers:
+  - Xu Yang <xu.yang_2 at nxp.com>
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - fsl,imx27-usb
+      - items:
+          - enum:
+              - fsl,imx23-usb
+              - fsl,imx25-usb
+              - fsl,imx28-usb
+              - fsl,imx35-usb
+              - fsl,imx50-usb
+              - fsl,imx51-usb
+              - fsl,imx53-usb
+              - fsl,imx6q-usb
+              - fsl,imx6sl-usb
+              - fsl,imx6sx-usb
+              - fsl,imx6ul-usb
+              - fsl,imx7d-usb
+              - fsl,vf610-usb
+          - const: fsl,imx27-usb
+      - items:
+          - enum:
+              - fsl,imx8dxl-usb
+              - fsl,imx8ulp-usb
+          - const: fsl,imx7ulp-usb
+          - const: fsl,imx6ul-usb
+      - items:
+          - enum:
+              - fsl,imx8mm-usb
+              - fsl,imx8mn-usb
+          - const: fsl,imx7d-usb
+          - const: fsl,imx27-usb
+      - items:
+          - enum:
+              - fsl,imx6sll-usb
+              - fsl,imx7ulp-usb
+          - const: fsl,imx6ul-usb
+          - const: fsl,imx27-usb
+
+allOf:
+  - $ref: ci-hdrc-usb2.yaml#
+
+required:
+  - compatible
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/imx7d-clock.h>
+
+    usb at 30b10000 {
+        compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
+        reg = <0x30b10000 0x200>;
+        interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX7D_USB_CTRL_CLK>;
+        fsl,usbphy = <&usbphynop1>;
+        fsl,usbmisc = <&usbmisc1 0>;
+        phy-clkgate-delay-us = <400>;
+    };
+
+...
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 06:58:42 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 22:58:42 +0800
Subject: [PATCH v6 5/9] dt-bindings: usb: ci-hdrc-usb2-imx: add restrictions for reg, interrupts, clock and clock-names properties
In-Reply-To: <20240221145846.1611627-1-xu.yang_2@nxp.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
Message-ID: <20240221145846.1611627-5-xu.yang_2@nxp.com>

Add restrictions for reg, interrupts, clock and clock-names properties
for imx Socs.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v4:
 - new patch since v3's discussion
 - split the reg, interrupts, clock and clock-names properties into
   common part and device-specific
Changes in v5:
 - keep common property unchanged
 - make if-then more readable
 - remove non imx part
Changes in v6:
 - new patch based on ci-hdrc-usb2-imx.yaml
---
 .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
index 2ec62f564bf5..20bb048938ff 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
@@ -49,11 +49,63 @@ properties:
           - const: fsl,imx6ul-usb
           - const: fsl,imx27-usb
 
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
 allOf:
   - $ref: ci-hdrc-usb2.yaml#
 
+  # imx27 Soc needs three clocks
+  - if:
+      properties:
+        compatible:
+          const: fsl,imx27-usb
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: ipg
+            - const: ahb
+            - const: per
+    else:
+      # imx25 and imx35 Soc need three clocks
+      if:
+        properties:
+          compatible:
+            contains:
+              enum:
+                - fsl,imx25-usb
+                - fsl,imx35-usb
+      then:
+        properties:
+          clocks:
+            minItems: 3
+            maxItems: 3
+          clock-names:
+            items:
+              - const: ipg
+              - const: ahb
+              - const: per
+      else:
+        # other imx Socs only need one clock
+        properties:
+          clocks:
+            minItems: 1
+            maxItems: 1
+          clock-names:
+            minItems: 1
+            maxItems: 1
+
 required:
   - compatible
+  - reg
+  - interrupts
 
 unevaluatedProperties: false
 
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 06:58:43 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 22:58:43 +0800
Subject: [PATCH v6 6/9] dt-bindings: usb: ci-hdrc-usb2-imx: add compatible and clock-names restriction for imx93
In-Reply-To: <20240221145846.1611627-1-xu.yang_2@nxp.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
Message-ID: <20240221145846.1611627-6-xu.yang_2@nxp.com>

The i.MX93 needs a wakup clock to work properly. This will add compatible
and restriction for i.MX93 platform.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - no changes
Changes in v3:
 - add clocks restriction
Changes in v4:
 - use 'contains' rather 'items'
Changes in v5:
 - rename clock name
Changes in v6:
 - new patch based on ci-hdrc-usb2-imx.yaml
---
 .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 34 ++++++++++++++-----
 .../devicetree/bindings/usb/ci-hdrc-usb2.yaml |  1 +
 2 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
index 20bb048938ff..d509cfbcf0d5 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
@@ -40,6 +40,7 @@ properties:
           - enum:
               - fsl,imx8mm-usb
               - fsl,imx8mn-usb
+              - fsl,imx93-usb
           - const: fsl,imx7d-usb
           - const: fsl,imx27-usb
       - items:
@@ -93,14 +94,31 @@ allOf:
               - const: ahb
               - const: per
       else:
-        # other imx Socs only need one clock
-        properties:
-          clocks:
-            minItems: 1
-            maxItems: 1
-          clock-names:
-            minItems: 1
-            maxItems: 1
+        # imx93 Soc needs two clocks
+        if:
+          properties:
+            compatible:
+              contains:
+                enum:
+                  - fsl,imx93-usb
+        then:
+          properties:
+            clocks:
+              minItems: 2
+              maxItems: 2
+            clock-names:
+              items:
+                - const: usb_ctrl_root
+                - const: usb_wakeup
+        else:
+          # other imx Socs only need one clock
+          properties:
+            clocks:
+              minItems: 1
+              maxItems: 1
+            clock-names:
+              minItems: 1
+              maxItems: 1
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
index 3b56e0edb1c6..ff826414bcb2 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
@@ -57,6 +57,7 @@ properties:
           - enum:
               - fsl,imx8mm-usb
               - fsl,imx8mn-usb
+              - fsl,imx93-usb
           - const: fsl,imx7d-usb
           - const: fsl,imx27-usb
       - items:
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 06:58:44 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 22:58:44 +0800
Subject: [PATCH v6 7/9] arm64: dts: imx93: add usb nodes
In-Reply-To: <20240221145846.1611627-1-xu.yang_2@nxp.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
Message-ID: <20240221145846.1611627-7-xu.yang_2@nxp.com>

There are 2 USB controllers on i.MX93. Add them.

Acked-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com> # TQMa9352LA/CA
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - fix format as suggested by Alexander
 - change compatible from fsl,imx8mm-usb to fsl,imx93-usb
Changes in v3:
 - replace deprecated fsl,usbphy with phys as suggested by Alexander
 - reorder nodes
Changes in v4:
 - fix the alignment
Changes in v5:
 - rename usb_wakeup_clk to usb_wakeup
Changes in v6:
 - rename usb_ctrl_root_clk to usb_ctrl_root
---
 arch/arm64/boot/dts/freescale/imx93.dtsi | 58 ++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
index 8f2e7c42ad6e..4a7efccb4f67 100644
--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -183,6 +183,20 @@ mqs2: mqs2 {
 		status = "disabled";
 	};
 
+	usbphynop1: usbphynop1 {
+		compatible = "usb-nop-xceiv";
+		#phy-cells = <0>;
+		clocks = <&clk IMX93_CLK_USB_PHY_BURUNIN>;
+		clock-names = "main_clk";
+	};
+
+	usbphynop2: usbphynop2 {
+		compatible = "usb-nop-xceiv";
+		#phy-cells = <0>;
+		clocks = <&clk IMX93_CLK_USB_PHY_BURUNIN>;
+		clock-names = "main_clk";
+	};
+
 	soc at 0 {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -1167,6 +1181,50 @@ media_blk_ctrl: system-controller at 4ac10000 {
 			status = "disabled";
 		};
 
+		usbotg1: usb at 4c100000 {
+			compatible = "fsl,imx93-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+			reg = <0x4c100000 0x200>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX93_CLK_USB_CONTROLLER_GATE>,
+				 <&clk IMX93_CLK_HSIO_32K_GATE>;
+			clock-names = "usb_ctrl_root", "usb_wakeup";
+			assigned-clocks = <&clk IMX93_CLK_HSIO>;
+			assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
+			assigned-clock-rates = <133000000>;
+			phys = <&usbphynop1>;
+			fsl,usbmisc = <&usbmisc1 0>;
+			status = "disabled";
+		};
+
+		usbmisc1: usbmisc at 4c100200 {
+			compatible = "fsl,imx8mm-usbmisc", "fsl,imx7d-usbmisc",
+				     "fsl,imx6q-usbmisc";
+			reg = <0x4c100200 0x200>;
+			#index-cells = <1>;
+		};
+
+		usbotg2: usb at 4c200000 {
+			compatible = "fsl,imx93-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+			reg = <0x4c200000 0x200>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX93_CLK_USB_CONTROLLER_GATE>,
+				 <&clk IMX93_CLK_HSIO_32K_GATE>;
+			clock-names = "usb_ctrl_root", "usb_wakeup";
+			assigned-clocks = <&clk IMX93_CLK_HSIO>;
+			assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
+			assigned-clock-rates = <133000000>;
+			phys = <&usbphynop2>;
+			fsl,usbmisc = <&usbmisc2 0>;
+			status = "disabled";
+		};
+
+		usbmisc2: usbmisc at 4c200200 {
+			compatible = "fsl,imx8mm-usbmisc", "fsl,imx7d-usbmisc",
+				     "fsl,imx6q-usbmisc";
+			reg = <0x4c200200 0x200>;
+			#index-cells = <1>;
+		};
+
 		ddr-pmu at 4e300dc0 {
 			compatible = "fsl,imx93-ddr-pmu";
 			reg = <0x4e300dc0 0x200>;
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 06:58:45 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 22:58:45 +0800
Subject: [PATCH v6 8/9] arm64: dts: imx93-11x11-evk: enable usb and typec nodes
In-Reply-To: <20240221145846.1611627-1-xu.yang_2@nxp.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
Message-ID: <20240221145846.1611627-8-xu.yang_2@nxp.com>

There are 2 Type-C ports and 2 USB controllers on i.MX93. Enable them.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - remove status property in ptn5110 nodes
 - fix dt-schema warnings
Changes in v3:
 - no changes
Changes in v4:
 - no changes
Changes in v5:
 - no changes
Changes in v6:
 - no changes
---
 .../boot/dts/freescale/imx93-11x11-evk.dts    | 118 ++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
index 9921ea13ab48..ec4cb50445fc 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/usb/pd.h>
 #include "imx93.dtsi"
 
 / {
@@ -104,6 +105,80 @@ &mu2 {
 	status = "okay";
 };
 
+&lpi2c3 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&pinctrl_lpi2c3>;
+	pinctrl-1 = <&pinctrl_lpi2c3>;
+	status = "okay";
+
+	ptn5110: tcpc at 50 {
+		compatible = "nxp,ptn5110";
+		reg = <0x50>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+
+		typec1_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			power-role = "dual";
+			data-role = "dual";
+			try-power-role = "sink";
+			source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+			sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
+				     PDO_VAR(5000, 20000, 3000)>;
+			op-sink-microwatt = <15000000>;
+			self-powered;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					typec1_dr_sw: endpoint {
+						remote-endpoint = <&usb1_drd_sw>;
+					};
+				};
+			};
+		};
+	};
+
+	ptn5110_2: tcpc at 51 {
+		compatible = "nxp,ptn5110";
+		reg = <0x51>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+
+		typec2_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			power-role = "dual";
+			data-role = "dual";
+			try-power-role = "sink";
+			source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+			sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
+				     PDO_VAR(5000, 20000, 3000)>;
+			op-sink-microwatt = <15000000>;
+			self-powered;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					typec2_dr_sw: endpoint {
+						remote-endpoint = <&usb2_drd_sw>;
+					};
+				};
+			};
+		};
+	};
+};
+
 &eqos {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_eqos>;
@@ -156,6 +231,42 @@ &lpuart5 {
 	status = "okay";
 };
 
+&usbotg1 {
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	usb-role-switch;
+	disable-over-current;
+	samsung,picophy-pre-emp-curr-control = <3>;
+	samsung,picophy-dc-vol-level-adjust = <7>;
+	status = "okay";
+
+	port {
+		usb1_drd_sw: endpoint {
+			remote-endpoint = <&typec1_dr_sw>;
+		};
+	};
+};
+
+&usbotg2 {
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	usb-role-switch;
+	disable-over-current;
+	samsung,picophy-pre-emp-curr-control = <3>;
+	samsung,picophy-dc-vol-level-adjust = <7>;
+	status = "okay";
+
+	port {
+		usb2_drd_sw: endpoint {
+			remote-endpoint = <&typec2_dr_sw>;
+		};
+	};
+};
+
 &usdhc1 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz";
 	pinctrl-0 = <&pinctrl_usdhc1>;
@@ -222,6 +333,13 @@ MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL	0x57e
 		>;
 	};
 
+	pinctrl_lpi2c3: lpi2c3grp {
+		fsl,pins = <
+			MX93_PAD_GPIO_IO28__LPI2C3_SDA			0x40000b9e
+			MX93_PAD_GPIO_IO29__LPI2C3_SCL			0x40000b9e
+		>;
+	};
+
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
 			MX93_PAD_UART1_RXD__LPUART1_RX			0x31e
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 06:58:46 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 22:58:46 +0800
Subject: [PATCH v6 9/9] usb: chipidea: ci_hdrc_imx: align usb wakeup clock name with dt-bindings
In-Reply-To: <20240221145846.1611627-1-xu.yang_2@nxp.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
Message-ID: <20240221145846.1611627-9-xu.yang_2@nxp.com>

The dt-bindings is going to use "usb_wakeup" as wakup clock name. This will
align the change with dt-bindings.

Acked-by: Peter Chen <peter.chen at kernel.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v5:
 - new patch
Changes in v6:
 - add Acked-by tag
---
 drivers/usb/chipidea/ci_hdrc_imx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index ae9a6a17ec6e..a17b6d619305 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -212,7 +212,7 @@ static int imx_get_clks(struct device *dev)
 		/* Get wakeup clock. Not all of the platforms need to
 		 * handle this clock. So make it optional.
 		 */
-		data->clk_wakeup = devm_clk_get_optional(dev, "usb_wakeup_clk");
+		data->clk_wakeup = devm_clk_get_optional(dev, "usb_wakeup");
 		if (IS_ERR(data->clk_wakeup))
 			ret = dev_err_probe(dev, PTR_ERR(data->clk_wakeup),
 					"Failed to get wakeup clk\n");
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Tue Feb 20 23:13:46 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 08:13:46 +0100
Subject: [PATCH v2] interconnect: constify of_phandle_args in xlate
In-Reply-To: <1d9b01da63f6$daeb0170$90c10450$@samsung.com>
References: <CGME20240220072224epcas5p4ff60556b0b5632abfc44d2b8ad932b8f@epcas5p4.samsung.com>
 <20240220072213.35779-1-krzysztof.kozlowski@linaro.org>
 <1d9b01da63f6$daeb0170$90c10450$@samsung.com>
Message-ID: <6c4bdd9f-6b1f-43a0-9baa-7c1eedd46f76@linaro.org>

On 20/02/2024 13:18, Alim Akhtar wrote:
> 
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>> Sent: Tuesday, February 20, 2024 12:52 PM
>> To: Georgi Djakov <djakov at kernel.org>; Bjorn Andersson
>> <andersson at kernel.org>; Konrad Dybcio <konrad.dybcio at linaro.org>;
>> Sylwester Nawrocki <s.nawrocki at samsung.com>; Artur ?wigo?
>> <a.swigon at samsung.com>; Krzysztof Kozlowski
>> <krzysztof.kozlowski at linaro.org>; Alim Akhtar
>> <alim.akhtar at samsung.com>; Thierry Reding <thierry.reding at gmail.com>;
>> Jonathan Hunter <jonathanh at nvidia.com>; linux-pm at vger.kernel.org;
>> linux-kernel at vger.kernel.org; linux-arm-msm at vger.kernel.org; linux-
>> samsung-soc at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
>> tegra at vger.kernel.org
>> Cc: Thierry Reding <treding at nvidia.com>
>> Subject: [PATCH v2] interconnect: constify of_phandle_args in xlate
>>
>> The xlate callbacks are supposed to translate of_phandle_args to proper
>> provider without modifying the of_phandle_args.  Make the argument
>> pointer to const for code safety and readability.
>>
>> Acked-by: Konrad Dybcio <konrad.dybcio at linaro.org>
>> Acked-by: Thierry Reding <treding at nvidia.com> # Tegra
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>
>> ---
>>
>> Changes in v2:
>> 1. Drop unrelated gpiolib changes (Konrad, Thierry).
>> 2. Add tags.
>> ---
>>  drivers/interconnect/core.c            |  4 ++--
>>  drivers/interconnect/qcom/icc-common.c |  3 ++-
>> drivers/interconnect/qcom/icc-common.h |  3 ++-
>> drivers/interconnect/samsung/exynos.c  |  2 +-
>>  drivers/memory/tegra/mc.c              |  2 +-
>>  drivers/memory/tegra/tegra124-emc.c    |  2 +-
>>  drivers/memory/tegra/tegra124.c        |  2 +-
>>  drivers/memory/tegra/tegra186-emc.c    |  2 +-
>>  drivers/memory/tegra/tegra20-emc.c     |  2 +-
>>  drivers/memory/tegra/tegra20.c         |  2 +-
>>  drivers/memory/tegra/tegra30-emc.c     |  2 +-
>>  drivers/memory/tegra/tegra30.c         |  2 +-
>>  include/linux/interconnect-provider.h  | 11 ++++++-----
>>  include/soc/tegra/mc.h                 |  7 ++++---
>>  14 files changed, 25 insertions(+), 21 deletions(-)
>>
> 
> For Samsung/Exynos
> Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

Review tags are per patch. You probably meant Acked-by.
https://elixir.bootlin.com/linux/v6.8-rc5/source/Documentation/process/submitting-patches.rst#L544

What is there anyway to review in Samsung? Adding one const in one driver?


Best regards,
Krzysztof



From srinivas.kandagatla at linaro.org  Tue Feb 20 23:17:35 2024
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Wed, 21 Feb 2024 07:17:35 +0000
Subject: [PATCH v2] nvmem: meson-efuse: fix function pointer type
 mismatch
In-Reply-To: <20240213142831.3069049-1-jbrunet@baylibre.com>
References: <20240213142831.3069049-1-jbrunet@baylibre.com>
Message-ID: <170849985550.23383.15344631998215438769.b4-ty@linaro.org>


On Tue, 13 Feb 2024 15:28:28 +0100, Jerome Brunet wrote:
> clang-16 warns about casting functions to incompatible types, as is done
> here to call clk_disable_unprepare:
> 
> drivers/nvmem/meson-efuse.c:78:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>    78 |                                        (void(*)(void *))clk_disable_unprepare,
> 
> The pattern of getting, enabling and setting a disable callback for a
> clock can be replaced with devm_clk_get_enabled(), which also fixes
> this warning.
> 
> [...]

Applied, thanks!

[1/1] nvmem: meson-efuse: fix function pointer type mismatch
      commit: 6b475e23544a560b4bf2acfab8dc54c4e7b1749e

Best regards,
-- 
Srinivas Kandagatla <srinivas.kandagatla at linaro.org>



From yangyicong at huawei.com  Tue Feb 20 23:19:08 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Wed, 21 Feb 2024 15:19:08 +0800
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <20240209135144.GA1498@debian-dev>
References: <20240208032518.25830-1-yangyicong@huawei.com>
 <20240209135144.GA1498@debian-dev>
Message-ID: <c290e695-08dd-fb14-e241-65e7e06fe086@huawei.com>

Hi Leo,

Thanks for the comments.

On 2024/2/9 21:51, Leo Yan wrote:
> Hi Yicong,
> 
> On Thu, Feb 08, 2024 at 11:25:18AM +0800, Yicong Yang wrote:
>> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
>> throughput and latency of PCIe traffic. With the support of PCIe PMU
>> we can enable the perf iostat mode.
>>
>> The HiSilicon PCIe PMU can support measuring the throughput of certain
>> TLP types and of certain root port. Totally 6 metrics are provided in
>> the unit of MB:
>>
>> - Inbound MWR: The memory write TLPs from the devices downstream the root port
> 
> I have no sufficient knowledge for PCI, but this description and below
> 2 lines are not clear for me. Should not it be: "The memory write TLPs
> from the downstream devices to the root port"?
> 

This is also the same meaning. Will reword it since you find it confusing.

>> - Inbound MRD: The memory read TLPs from the devices downstream the root port
>> - Inbound CPL: The completion TLPs from the devices downstream the root port
>> - Outbound MWR: The memory write TLPs from the CPU to the downstream devices
>> - Outbound MRD: The memory read TLPs from the CPU to the downstream devices
>> - Outbound CPL: The completions TLPs from the CPU to the downstream devices
>>
>> Since the PMU measures the throughput in DWords. So we need to calculate
>> the throughput in MB like:
>>   Count * 4B / 1024 / 1024
>>
>> Some of the display of the `perf iostat` will be like:
>> [root at localhost tmp]# ./perf iostat list
>> hisi_pcie0_core2<0000:40:00.0>
>> hisi_pcie2_core2<0000:5f:00.0>
>> hisi_pcie0_core1<0000:16:00.0>
>> hisi_pcie0_core1<0000:16:04.0>
>> [root at localhost tmp]# ./perf iostat --timeout 10000
>>
>>  Performance counter stats for 'system wide':
>>
>>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
>> 0000:40:00.0                    0                    0                    0                    0                    0                    0
>> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
>> 0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
>> 0000:16:04.0                    0                    0                    0                    0                    0                    0
>>
>>       10.008227512 seconds time elapsed
>>
>> [root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
>> -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
>> -norandommap -group_reporting -runtime=10 -time_based -bs=64k
>>
>>  Performance counter stats for 'system wide':
>>
>>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
>> 0000:40:00.0                    0                    0                    0                    0                    0                    0
>> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
>> 0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
>> 0000:16:04.0                    0                    0                    0                    0                    0                    0
>>
>>       10.168561767 seconds time elapsed
>>
>>        0.465373000 seconds user
>>        1.952948000 seconds sys
> 
> The command has specified the PCI port "0000:16:00.0", it still outputs
> stats for 'system wide'. And it also outputs results for other ports.
> This is confused.
> 

I may paste the wrong output here. should be like:

[root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=rw -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0 -norandommap -group_reporting -runtime=10 -time_based -bs=64k 2>&1 > /dev/null

 Performance counter stats for 'system wide':

    port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
0000:16:00.0                16614                  379                    0                   16                    0                16721

      10.180349717 seconds time elapsed

       0.558810000 seconds user
       2.495016000 seconds sys

Thanks for pointing it out. Will fix.


>> More information of the HiSilicon PCIe PMU can be found at
>> Documentation/admin-guide/perf/hisi-pcie-pmu.rst.
>>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
>> ---
>> Change since v1:
>> - Tweak the comments per Jonathan
>> - Use an enum to define the metrics and relevant command templates per Jonathan
>> Thanks!
>> Link: https://lore.kernel.org/linux-perf-users/20240123071201.30914-1-yangyicong at huawei.com/
>>
>>  tools/perf/arch/arm64/util/Build         |   1 +
>>  tools/perf/arch/arm64/util/hisi-iostat.c | 439 +++++++++++++++++++++++
>>  2 files changed, 440 insertions(+)
>>  create mode 100644 tools/perf/arch/arm64/util/hisi-iostat.c
>>
>> diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
>> index 78ef7115be3d..4e8dabf98b29 100644
>> --- a/tools/perf/arch/arm64/util/Build
>> +++ b/tools/perf/arch/arm64/util/Build
>> @@ -3,6 +3,7 @@ perf-y += machine.o
>>  perf-y += perf_regs.o
>>  perf-y += tsc.o
>>  perf-y += pmu.o
>> +perf-y += hisi-iostat.o
>>  perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
>>  perf-$(CONFIG_DWARF)     += dwarf-regs.o
>>  perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
>> diff --git a/tools/perf/arch/arm64/util/hisi-iostat.c b/tools/perf/arch/arm64/util/hisi-iostat.c
>> new file mode 100644
>> index 000000000000..43df43b83f3f
>> --- /dev/null
>> +++ b/tools/perf/arch/arm64/util/hisi-iostat.c
>> @@ -0,0 +1,439 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * perf iostat support for HiSilicon PCIe PMU.
>> + * Partly derived from tools/perf/arch/x86/util/iostat.c.
>> + *
>> + * Copyright (c) 2024 HiSilicon Technologies Co., Ltd.
>> + * Author: Yicong Yang <yangyicong at hisilicon.com>
>> + */
>> +
>> +#include <api/fs/fs.h>
>> +#include <linux/err.h>
>> +#include <linux/zalloc.h>
>> +#include <linux/limits.h>
>> +#include <dirent.h>
>> +#include <stdio.h>
>> +#include <errno.h>
>> +#include <stdint.h>
>> +#include <stdlib.h>
> 
> It's good to alphabet ordered for headers.
> 

will do.

>> +
>> +#include "util/counts.h"
>> +#include "util/cpumap.h"
>> +#include "util/debug.h"
>> +#include "util/iostat.h"
>> +#include "util/pmu.h"
>> +
>> +#define PCI_DEFAULT_DOMAIN		0
> 
> The macro is not used at all, remove it.
> 

will remove.

>> +#define PCI_DEVICE_NAME_PATTERN		"%04x:%02hhx:%02hhx.%hhu"
>> +#define PCI_ROOT_BUS_DEVICES_PATH	"bus/pci/devices"
>> +
>> +enum hisi_iostat_metric_type {
>> +	METRIC_IN_MWR,		/* Inbound Memory Write */
>> +	METRIC_IN_MRD,		/* Inbound Memory Read */
>> +	METRIC_IN_CPL,		/* Inbound Memory Completion */
>> +	METRIC_OUT_MWR,		/* Outbound Memory Write */
>> +	METRIC_OUT_MRD,		/* Outbound Memory Read */
>> +	METRIC_OUT_CPL,		/* Outbound Memory Completion */
>> +	METRIC_TYPE_MAX,
>> +};
>> +
>> +static const char * const hisi_iostat_metrics[] = {
>> +	[METRIC_IN_MWR] = "Inbound MWR(MB)",
>> +	[METRIC_IN_MRD] = "Inbound MRD(MB)",
>> +	[METRIC_IN_CPL] = "Inbound CPL(MB)",
>> +	[METRIC_OUT_MWR] = "Outbound MWR(MB)",
>> +	[METRIC_OUT_MRD] = "Outbound MRD(MB)",
>> +	[METRIC_OUT_CPL] = "Outbound CPL(MB)",
>> +};
>> +
>> +static const char * const hisi_iostat_cmd_template[] = {
>> +	[METRIC_IN_MWR] = "hisi_pcie%hu_core%hu/event=0x0104,port=0x%hx/",
>> +	[METRIC_IN_MRD] = "hisi_pcie%hu_core%hu/event=0x0804,port=0x%hx/",
>> +	[METRIC_IN_CPL] = "hisi_pcie%hu_core%hu/event=0x2004,port=0x%hx/",
>> +	[METRIC_OUT_MWR] = "hisi_pcie%hu_core%hu/event=0x0105,port=0x%hx/",
>> +	[METRIC_OUT_MRD] = "hisi_pcie%hu_core%hu/event=0x0405,port=0x%hx/",
>> +	[METRIC_OUT_CPL] = "hisi_pcie%hu_core%hu/event=0x1005,port=0x%hx/",
>> +};
>> +
>> +struct hisi_pcie_root_port {
>> +	struct list_head list;
>> +	/* Is this Root Port selected for monitoring */
>> +	bool selected;
>> +	/* IDs to locate the PMU */
>> +	u16 sicl_id;
>> +	u16 core_id;
>> +	/* Filter mask for this Root Port */
>> +	u16 mask;
>> +	/* PCIe Root Port's <domain>:<bus>:<device>.<function> */
>> +	u32 domain;
>> +	u8 bus;
>> +	u8 dev;
>> +	u8 fn;
>> +};
>> +
>> +LIST_HEAD(hisi_pcie_root_ports_list);
> 
> The list head can be 'static' type.
> 

will make it static.

>> +static int hisi_pcie_root_ports_num;
> 
> My feeling is 'hisi_pcie_root_ports_num' is redundant. You can check
> if the list is empty with list_empty() in below code, therefore, the
> variable 'hisi_pcie_root_ports_num' is not needed anymore.
> 

yes, checked the users of this it seems we don't need to know the exact
number of the root ports. Only to know whether there's available root port
is enough, which can be implemented by using list_empty().

>> +
>> +static void hisi_pcie_init_root_port_mask(struct hisi_pcie_root_port *rp)
>> +{
>> +	rp->mask = BIT(rp->dev << 1);
> 
> I also think 'rp->mask' is not necessary as it can be replaced by
> BIT(rp->dev << 1).
> 

ok, it's just used once.

> And it's not necessary to create hisi_pcie_init_root_port_mask(), as
> it's only used in a single place.
> 

I prefer to have this separately for better readability, since it's rather device specific.
It'll be hard to understand if just make it inline.

Maybe a macro if you find a function is redundant?

>> +}
>> +
>> +/*
>> + * Select specific Root Port to monitor. Return 0 if successfully find the
>> + * Root Port, Otherwise -EINVAL.
>> + */
>> +static int hisi_pcie_root_ports_select_one(u32 domain, u8 bus, u8 dev, u8 fn)
>> +{
>> +	struct hisi_pcie_root_port *rp;
>> +
>> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list)
>> +		if (domain == rp->domain && bus == rp->bus &&
>> +		    dev == rp->dev && fn == rp->fn) {
>> +			rp->selected = true;
> 
> 
> The code firstly creates PCI port lists for all Hisilicon PCIe ports,
> then it selects the port based on passed port name.
> 
> I am wandering why cannot create the PCI root port list based on the
> passed PCI port name, if so, the field 'rp->selected' is not needed
> anymore.
> 

We need to find the PMUs first, then get the root poots which supported by each PMU
based on the information provided by the PMU. It's hard and more complex to started
from the passed PCI port name since we still need to iterate the PMUs to find the one
can count this root port. When iterating the PMUs, we can already build the list.

x86 implements in a similiar way by starting finding the PMUs and related root ports.
Difference is that if user specifies some root port, they rebuild the root port list
with only user specified root ports from the complete root ports list(list with all the
root ports in the system), then free the complete root ports list. In my implementation,
list is not changed so no additional memory allocation/free. But need an additional
flags (rp->selected) to know which root port need to be counted.

>> +			return 0;
>> +		}
>> +
>> +	return -EINVAL;
>> +}
>>
>> +
>> +static void hisi_pcie_root_ports_select_all(void)
>> +{
>> +	struct hisi_pcie_root_port *rp;
>> +
>> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list)
>> +		rp->selected = true;
>> +}
> 
> Same as the comment above, the function
> hisi_pcie_root_ports_select_all() is not needed if a PCI list can be
> created properly in the first place.
> 
>> +
>> +static void hisi_pcie_root_ports_add(u16 sicl_id, u16 core_id, u8 target_bus)
>> +{
>> +	const char *sysfs = sysfs__mountpoint();
>> +	struct hisi_pcie_root_port *rp;
>> +	struct dirent *dent;
>> +	char path[PATH_MAX];
>> +	u8 bus, dev, fn;
>> +	u32 domain;
>> +	DIR *dir;
>> +	int ret;
>> +
>> +	snprintf(path, PATH_MAX, "%s/%s", sysfs, PCI_ROOT_BUS_DEVICES_PATH);
>> +	dir = opendir(path);
>> +	if (!dir)
>> +		return;
>> +
>> +	/* Scan the PCI root bus to find the match root port on @target_bus */
>> +	while ((dent = readdir(dir))) {
>> +		ret = sscanf(dent->d_name, PCI_DEVICE_NAME_PATTERN,
>> +			     &domain, &bus, &dev, &fn);
>> +		if (ret != 4 || bus != target_bus)
>> +			continue;
>> +
>> +		rp = zalloc(sizeof(*rp));
>> +		if (!rp)
>> +			continue;
>> +
>> +		rp->selected = false;
>> +		rp->sicl_id = sicl_id;
>> +		rp->core_id = core_id;
>> +		rp->domain = domain;
>> +		rp->bus = bus;
>> +		rp->dev = dev;
>> +		rp->fn = fn;
>> +
>> +		hisi_pcie_init_root_port_mask(rp);
>> +
>> +		list_add(&rp->list, &hisi_pcie_root_ports_list);
>> +		hisi_pcie_root_ports_num++;
>> +
>> +		pr_debug3("Found root port %s\n", dent->d_name);
>> +	}
>> +
>> +	closedir(dir);
>> +}
>> +
>> +/* Scan the PMUs and build the mapping of the Root Ports to the PMU */
>> +static int hisi_pcie_root_ports_init(void)
>> +{
>> +	char event_source[PATH_MAX], bus_path[PATH_MAX];
>> +	unsigned long long bus;
>> +	u16 sicl_id, core_id;
>> +	struct dirent *dent;
>> +	DIR *dir;
>> +
>> +	perf_pmu__event_source_devices_scnprintf(event_source, sizeof(event_source));
>> +	dir = opendir(event_source);
>> +	if (!dir)
>> +		return -ENOENT;
>> +
>> +	while ((dent = readdir(dir))) {
>> +		/*
>> +		 * This HiSilicon PCIe PMU will be named as:
>> +		 *   hisi_pcie<sicl_id>_core<core_id>
>> +		 */
>> +		if ((sscanf(dent->d_name, "hisi_pcie%hu_core%hu", &sicl_id, &core_id)) != 2)
>> +			continue;
>> +
>> +		/*
>> +		 * Driver will export the root port it can monitor through
>> +		 * the "bus" sysfs attribute.
>> +		 */
>> +		scnprintf(bus_path, sizeof(bus_path), "%s/hisi_pcie%hu_core%hu/bus",
>> +			  event_source, sicl_id, core_id);
>> +
>> +		/*
>> +		 * Per PCIe spec the bus should be 8bit, use unsigned long long
>> +		 * for the convience of the library function.
>> +		 */
>> +		if (filename__read_ull(bus_path, &bus))
>> +			continue;
>> +
>> +		pr_debug3("Found pmu %s bus 0x%llx\n", dent->d_name, bus);
>> +
>> +		hisi_pcie_root_ports_add(sicl_id, core_id, (u8)bus);
>> +	}
>> +
>> +	closedir(dir);
>> +	return hisi_pcie_root_ports_num > 0 ? 0 : -ENOENT;
>> +}
>> +
>> +static void hisi_pcie_root_ports_free(void)
>> +{
>> +	struct hisi_pcie_root_port *rp, *tmp;
>> +
>> +	if (hisi_pcie_root_ports_num == 0)
>> +		return;
>> +
>> +	list_for_each_entry_safe(rp, tmp, &hisi_pcie_root_ports_list, list) {
>> +		list_del(&rp->list);
>> +		zfree(&rp);
>> +		hisi_pcie_root_ports_num--;
>> +	}
>> +}
>> +
>> +static int hisi_iostat_add_events(struct evlist *evl)
>> +{
>> +	struct hisi_pcie_root_port *rp;
>> +	struct evsel *evsel;
>> +	unsigned int i, j;
>> +	char *iostat_cmd;
>> +	int pos = 0;
>> +	int ret;
>> +
>> +	if (!hisi_pcie_root_ports_num)
>> +		return -ENOENT;
>> +
>> +	iostat_cmd = zalloc(PATH_MAX);
>> +	if (!iostat_cmd)
>> +		return -ENOMEM;
>> +
>> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list) {
>> +		if (!rp->selected)
>> +			continue;
>> +
>> +		iostat_cmd[pos++] = '{';
>> +		for (j = 0; j < METRIC_TYPE_MAX; j++) {
>> +			pos += snprintf(iostat_cmd + pos, ARG_MAX - pos - 1,
>> +					hisi_iostat_cmd_template[j],
>> +					rp->sicl_id, rp->core_id, rp->mask);
>> +
>> +			if (j == METRIC_TYPE_MAX - 1)
>> +				iostat_cmd[pos++] = '}';
>> +			else
>> +				iostat_cmd[pos++] = ',';
>> +		}
> 
> Here is hard coded that every event must contains the all 6 metrics (
> IN_MWR/IN_MRD/IN_CPL/OUT_MWR/OUT_MRD/OUT_CPL). Thus, a user has no
> chance to specify metrics for statistics.
> 

A bit confused here. `perf iostat` forbids the usage of user specified metrics/events,
see the comment in iostat_prepare().

>> +
>> +		ret = parse_event(evl, iostat_cmd);
>> +		if (ret)
>> +			break;
>> +
>> +		i = 0;
>> +		evlist__for_each_entry_reverse(evl, evsel) {
>> +			if (i == METRIC_TYPE_MAX)
>> +				break;
>> +
>> +			evsel->priv = rp;
>> +			i++;
>> +		}
>> +
>> +		memset(iostat_cmd, 0, PATH_MAX);
>> +		pos = 0;
>> +	}
>> +
>> +	zfree(&iostat_cmd);
>> +	return ret;
>> +}
>> +
>> +int iostat_prepare(struct evlist *evlist,
>> +		   struct perf_stat_config *config)
>> +{
>> +	if (evlist->core.nr_entries > 0) {
>> +		pr_warning("The -e and -M options are not supported."
>> +			   "All chosen events/metrics will be dropped\n");
>> +		evlist__delete(evlist);
>> +		evlist = evlist__new();
>> +		if (!evlist)
>> +			return -ENOMEM;
>> +	}
>> +
>> +	config->metric_only = true;
>> +	config->aggr_mode = AGGR_GLOBAL;
>> +
>> +	return hisi_iostat_add_events(evlist);
> 
> As Robin mentioned in another email, PCI root port statistics should
> not bind to Arm architecture. After applying this code, it's binding
> iostat exclusively with Hisilicon PCI root ports on Arm, as a result,
> it is impossible to support other PMUs for iostat support.
> 
> I understand you saw the implementation 'arch/x86/util/iostat.c' which
> binds the iostat with x86 arch. And your code just studies it to bind
> PCI root port stats with Arm arch.
> 

The `perf iostat` binds on certain PMUs currently, so even the x86's iostat
cannot be used on AMD platforms since they don't have the PMU device.

I guess currently it's put under arch/ directory is because these certain
PMUs only appears on these certain architectures currently.

> Here, I think the methodology should be: we need take Hisilicon PCI
> root port as a general PMU for I/O stats, it should not bind to any
> CPU arch. We need to consider to extend 'perf iostat' for this
> purpose.
> 

ok, I think you mean not only HiSilicon PCIe PMU but also x86 related stuffs?
To extend `perf iostat` then it will do the counting if there're PMUs supported
counting PCIe on the system, regardless of the architecture?

I agree it will be the ideal solution for future PMUs support iostat. Do you
want me to do this along with this patch or after this one merged as a separate
refactoring?

> To be honest, I am not familiar with 'perf iostat', I will take a bit
> more time to look into it and share back if I have more finding.
> 

Thanks a lot. Looking forward to the comments :)

Thanks,
Yicong


From krzysztof.kozlowski at linaro.org  Tue Feb 20 23:22:27 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 08:22:27 +0100
Subject: [PATCH] dt-bindings: gpio: Convert Aspeed binding to YAML schema
In-Reply-To: <18dfd5f2eff5049fa5e3a098490dc601cf146f96.camel@codeconstruct.com.au>
References: <20240220052918.742793-1-andrew@codeconstruct.com.au>
 <0d1dd262-b6dd-4d71-9239-8b0aec8cceff@linaro.org>
 <18dfd5f2eff5049fa5e3a098490dc601cf146f96.camel@codeconstruct.com.au>
Message-ID: <9393d46b-6bb1-4aef-84ac-b22abeac7656@linaro.org>

On 21/02/2024 03:41, Andrew Jeffery wrote:
>>>>> +
>>>>> +properties:
>>>>> +  compatible:
>>>>> +    enum:
>>>>> +      - aspeed,ast2400-gpio
>>>>> +      - aspeed,ast2500-gpio
>>>>> +      - aspeed,ast2600-gpio
>>>>> +
>>>>> +  reg:
>>>>> +    maxItems: 1
>>>>> +
>>>>> +  clocks:
>>>>> +    maxItems: 1
>>>>> +    description: The clock to use for debounce timings
>>>>> +
>>>>> +  interrupts:
>>>>> +    maxItems: 1
>>>>> +
>>>>> +  interrupt-controller: true
>>>>> +
>>>>> +  "#interrupt-cells":
>>>>> +    const: 2
>>>>> +
>>>
>>> ngpios with some constraints
> 
> Is this just with regard to the constraints I have under allOf above?

You miss ngpios.



Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 20 23:28:47 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 08:28:47 +0100
Subject: [PATCH v6 1/9] dt-bindings: usb: usbmisc-imx: add
 fsl,imx8ulp-usbmisc compatible
In-Reply-To: <20240221145846.1611627-1-xu.yang_2@nxp.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
Message-ID: <214c03b8-7c5d-45db-8f14-c144751dd819@linaro.org>

On 21/02/2024 15:58, Xu Yang wrote:
> Add "fsl,imx8ulp-usbmisc" compatible.
> 
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 

Please fix your machine time, so this does not appear in +8 hours in the
future. It unnecessarily goes to the top of my inbox, so I will ignore
the patchset.

Best regards,
Krzysztof



From zajec5 at gmail.com  Tue Feb 20 23:35:20 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 21 Feb 2024 08:35:20 +0100
Subject: [PATCH 0/4] dts: mediatek: add Cudy WR3000 V1 wireless router
Message-ID: <20240221073524.20947-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Cudy WR3000 V1 is a MediaTek Filogic 820 based 802.11ax wireless router.

https://www.cudy.com/productinfo/1637722.html

Rafa? Mi?ecki (4):
  dt-bindings: vendor-prefixes: add Cudy
  dt-bindings: arm64: dts: mediatek: Add Cudy WR3000 V1 router
  arm64: dts: mediatek: mt7981: add pinctrl
  arm64: dts: mediatek: Add Cudy WR3000 V1

 .../devicetree/bindings/arm/mediatek.yaml     |  1 +
 .../devicetree/bindings/vendor-prefixes.yaml  |  2 +
 arch/arm64/boot/dts/mediatek/Makefile         |  1 +
 .../dts/mediatek/mt7981b-cudy-wr3000-v1.dts   | 74 +++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7981b.dtsi     | 37 ++++++++++
 5 files changed, 115 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts

-- 
2.35.3



From zajec5 at gmail.com  Tue Feb 20 23:35:21 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 21 Feb 2024 08:35:21 +0100
Subject: [PATCH 1/4] dt-bindings: vendor-prefixes: add Cudy
In-Reply-To: <20240221073524.20947-1-zajec5@gmail.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
Message-ID: <20240221073524.20947-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Cudy is a Chinese company providing networking products.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 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 2dbcdc5f5d7d..cb4dd176bf41 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -332,6 +332,8 @@ patternProperties:
     description: Czech Technical University in Prague
   "^cubietech,.*":
     description: Cubietech, Ltd.
+  "^cudy,.*":
+    description: Shenzhen Cudy Technology Co., Ltd.
   "^cui,.*":
     description: CUI Devices
   "^cypress,.*":
-- 
2.35.3



From zajec5 at gmail.com  Tue Feb 20 23:35:22 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 21 Feb 2024 08:35:22 +0100
Subject: [PATCH 2/4] dt-bindings: arm64: dts: mediatek: Add Cudy WR3000 V1 router
In-Reply-To: <20240221073524.20947-1-zajec5@gmail.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
Message-ID: <20240221073524.20947-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Cudy WR3000 V1 is an MT7981B (AKA Filogic 820) based wireless router.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 Documentation/devicetree/bindings/arm/mediatek.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 09f9ffd3ff7b..1cf47db94c57 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -85,6 +85,7 @@ properties:
           - const: mediatek,mt7629
       - items:
           - enum:
+              - cudy,wr3000-v1
               - xiaomi,ax3000t
           - const: mediatek,mt7981b
       - items:
-- 
2.35.3



From zajec5 at gmail.com  Tue Feb 20 23:35:23 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 21 Feb 2024 08:35:23 +0100
Subject: [PATCH 3/4] arm64: dts: mediatek: mt7981: add pinctrl
In-Reply-To: <20240221073524.20947-1-zajec5@gmail.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
Message-ID: <20240221073524.20947-4-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

MT7981 contains on-SoC PIN controller that is also a GPIO provider.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 37 +++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
index 4feff3d1c5f4..fdd5c22cfc9c 100644
--- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
@@ -86,6 +86,43 @@ pwm at 10048000 {
 			#pwm-cells = <2>;
 		};
 
+		pio: pinctrl at 11d00000 {
+			compatible = "mediatek,mt7981-pinctrl";
+			reg = <0 0x11d00000 0 0x1000>,
+			      <0 0x11c00000 0 0x1000>,
+			      <0 0x11c10000 0 0x1000>,
+			      <0 0x11d20000 0 0x1000>,
+			      <0 0x11e00000 0 0x1000>,
+			      <0 0x11e20000 0 0x1000>,
+			      <0 0x11f00000 0 0x1000>,
+			      <0 0x11f10000 0 0x1000>,
+			      <0 0x1000b000 0 0x1000>;
+			reg-names = "gpio", "iocfg_rt", "iocfg_rm", "iocfg_rb", "iocfg_lb",
+				    "iocfg_bl", "iocfg_tm", "iocfg_tl", "eint";
+			interrupt-controller;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&gic>;
+			gpio-ranges = <&pio 0 0 56>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			#interrupt-cells = <2>;
+
+			mdio-pins {
+				mux {
+					function = "eth";
+					groups = "smi_mdc_mdio";
+				};
+			};
+
+			spi0-pins {
+				mux {
+					function = "spi";
+					groups = "spi0", "spi0_wp_hold";
+				};
+			};
+
+		};
+
 		clock-controller at 15000000 {
 			compatible = "mediatek,mt7981-ethsys", "syscon";
 			reg = <0 0x15000000 0 0x1000>;
-- 
2.35.3



From zajec5 at gmail.com  Tue Feb 20 23:35:24 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 21 Feb 2024 08:35:24 +0100
Subject: [PATCH 4/4] arm64: dts: mediatek: Add Cudy WR3000 V1
In-Reply-To: <20240221073524.20947-1-zajec5@gmail.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
Message-ID: <20240221073524.20947-5-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Cudy WR3000 V1 is an MT7981B (AKA Filogic 820) based wireless router. It
has 256 MiB of RAM, some LEDs & buttons and (not described yet) 4
Ethernet ports.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/Makefile         |  1 +
 .../dts/mediatek/mt7981b-cudy-wr3000-v1.dts   | 74 +++++++++++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 37b4ca3a87c9..96da4ad640aa 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-cudy-wr3000-v1.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-xiaomi-ax3000t.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-acelink-ew-7886cax.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
new file mode 100644
index 000000000000..cb36a089518a
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+#include "mt7981b.dtsi"
+
+/ {
+	compatible = "cudy,wr3000-v1", "mediatek,mt7981b";
+	model = "Cudy WR3000 V1";
+
+	memory at 40000000 {
+		reg = <0 0x40000000 0 0x10000000>;
+		device_type = "memory";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		key-wps {
+			label = "WPS";
+			gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		key-reset {
+			label = "RESET";
+			gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			function = LED_FUNCTION_WAN;
+			color = <LED_COLOR_ID_BLUE>;
+			gpios = <&pio 5 GPIO_ACTIVE_LOW>;
+		};
+
+		led-1 {
+			function = LED_FUNCTION_WLAN_2GHZ;
+			color = <LED_COLOR_ID_BLUE>;
+			gpios = <&pio 6 GPIO_ACTIVE_LOW>;
+		};
+
+		led-2 {
+			function = LED_FUNCTION_WLAN_5GHZ;
+			color = <LED_COLOR_ID_BLUE>;
+			gpios = <&pio 7 GPIO_ACTIVE_LOW>;
+		};
+
+		led-3 {
+			function = LED_FUNCTION_LAN;
+			color = <LED_COLOR_ID_BLUE>;
+			gpios = <&pio 9 GPIO_ACTIVE_LOW>;
+		};
+
+		led-4 {
+			function = LED_FUNCTION_STATUS;
+			color = <LED_COLOR_ID_BLUE>;
+			gpios = <&pio 10 GPIO_ACTIVE_LOW>;
+		};
+
+		led-5 {
+			function = "online";
+			color = <LED_COLOR_ID_BLUE>;
+			gpios = <&pio 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
-- 
2.35.3



From sumit.garg at linaro.org  Tue Feb 20 23:40:28 2024
From: sumit.garg at linaro.org (Sumit Garg)
Date: Wed, 21 Feb 2024 13:10:28 +0530
Subject: Calling OPTEE_SMC_CALL_GET_OS_UUID from driver code
In-Reply-To: <443901af-6abd-4a29-b6b6-f06b6d3ce34c@freebox.fr>
References: <443901af-6abd-4a29-b6b6-f06b6d3ce34c@freebox.fr>
Message-ID: <CAFA6WYOMHEygroKGaV7Jw7c8=nrnVrW=Vqk5r1yuTR5rwFijCQ@mail.gmail.com>

Hi Marc,

On Tue, 20 Feb 2024 at 22:59, Marc Gonzalez <mgonzalez at freebox.fr> wrote:
>
> Hello,
>
> The driver code I'm working on hard-codes
>
> #define TEE_SMC_FAST_CALL_VAL(func_num) \
>     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
>             ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
>
> #define TEE_SMC_FUNCID_CALLS_UID 0xFF01
> #define TEE_SMC_CALLS_UID \
>     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
>                ARM_SMCCC_OWNER_TRUSTED_OS_END, \
>                TEE_SMC_FUNCID_CALLS_UID)
>
>     arm_smccc_smc(TEE_SMC_CALLS_UID,
>             0, 0, 0/*is_swap*/, 0, 0, 0, 0, &res);
>     dev_err(dev, "TEE UID %x %x %x %x\n", res.a0, res.a1, res.a2, res.a3);
>
>
> but it seems I would be required to somehow use
> OPTEE_SMC_CALL_GET_OS_UUID
>
> But it's not exported, and no code seems to use it...?
>

Can you describe your use-case to require direct
OPTEE_SMC_CALL_GET_OS_UUID invocation?

> $ git grep OPTEE_SMC_CALL_GET_OS_UUID
> Documentation/tee/op-tee.rst:- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
> drivers/tee/optee/optee_smc.h:#define OPTEE_SMC_CALL_GET_OS_UUID \
>
> How do I make calls to OP-TEE from driver code?

The TEE driver API documentation is here [1] and you can refer to the
existing OP-TEE RNG driver here for reference.

[1] https://docs.kernel.org/driver-api/tee.html
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/char/hw_random/optee-rng.c

-Sumit


From sakari.ailus at linux.intel.com  Tue Feb 20 23:43:31 2024
From: sakari.ailus at linux.intel.com (sakari.ailus at linux.intel.com)
Date: Wed, 21 Feb 2024 07:43:31 +0000
Subject: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver
In-Reply-To: <063fa9763efb1570295cfef385829714dd5e42cf.camel@mediatek.com>
References: <20240204061538.2105-1-zhi.mao@mediatek.com>
 <20240204061538.2105-3-zhi.mao@mediatek.com>
 <20240206184542.GE2827@pendragon.ideasonboard.com>
 <598f62bbb55157eec1e23dd1dbc307fea3851b21.camel@mediatek.com>
 <20240220030104.GF20376@pendragon.ideasonboard.com>
 <115698c0c549e747026cc8841a3bd571533f8e6f.camel@mediatek.com>
 <ZdRUB92gkbRGPyr_@kekkonen.localdomain>
 <063fa9763efb1570295cfef385829714dd5e42cf.camel@mediatek.com>
Message-ID: <ZdWpow0JIM18Hc4u@kekkonen.localdomain>

Hi Zhi,

On Wed, Feb 21, 2024 at 02:37:27AM +0000, Zhi Mao (??) wrote:
> Hi Laurent & sakari,
> 
> Thanks for your feedback.
> 
> On Tue, 2024-02-20 at 07:25 +0000, sakari.ailus at linux.intel.com wrote:
> >  	 
> > External email : Please do not click links or open attachments until
> > you have verified the sender or the content.
> >  Hi Zhi,
> > 
> > On Tue, Feb 20, 2024 at 05:45:54AM +0000, Zhi Mao (??) wrote:
> > > Hi Laurent,
> > > 
> > > Thanks for you reply.
> > > I'd like to ask for advice about how to contrl "reset-pin", please
> > > check the below comments.
> > > 
> > > On Tue, 2024-02-20 at 05:01 +0200, Laurent Pinchart wrote:
> > > >   
> > > > External email : Please do not click links or open attachments
> > until
> > > > you have verified the sender or the content.
> > > >  Hi Zhi,
> > > > 
> > > > On Tue, Feb 20, 2024 at 02:12:26AM +0000, Zhi Mao (??) wrote:
> > > > > On Tue, 2024-02-06 at 20:45 +0200, Laurent Pinchart wrote:
> > > > > > On Sun, Feb 04, 2024 at 02:15:38PM +0800, Zhi Mao wrote:
> > > > > > > Add a V4L2 sub-device driver for Galaxycore GC08A3 image
> > > > sensor.
> > > > > > >
> > > > > > > Signed-off-by: Zhi Mao <zhi.mao at mediatek.com>
> > > > > > > ---
> > > > > > >  drivers/media/i2c/Kconfig  |   10 +
> > > > > > >  drivers/media/i2c/Makefile |    1 +
> > > > > > >  drivers/media/i2c/gc08a3.c | 1448
> > > > ++++++++++++++++++++++++++++++++++++
> > > > > > >  3 files changed, 1459 insertions(+)
> > > > > > >  create mode 100644 drivers/media/i2c/gc08a3.c
> > > > 
> > > > [snip]
> > > > 
> > > > > > > diff --git a/drivers/media/i2c/gc08a3.c
> > > > b/drivers/media/i2c/gc08a3.c
> > > > > > > new file mode 100644
> > > > > > > index 000000000000..3fc7fffb815c
> > > > > > > --- /dev/null
> > > > > > > +++ b/drivers/media/i2c/gc08a3.c
> > > > > > > @@ -0,0 +1,1448 @@
> > > > 
> > > > [snip]
> > > > 
> > > > > > > +static int gc08a3_power_on(struct device *dev)
> > > > > > > +{
> > > > > > > +struct i2c_client *client = to_i2c_client(dev);
> > > > > > > +struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > > > > > > +struct gc08a3 *gc08a3 = to_gc08a3(sd);
> > > > > > > +int ret;
> > > > > > > +
> > > > > > > +ret =
> > regulator_bulk_enable(ARRAY_SIZE(gc08a3_supply_name),
> > > > > > > +    gc08a3->supplies);
> > > > > > > +if (ret < 0) {
> > > > > > > +dev_err(gc08a3->dev, "failed to enable regulators: %d\n",
> > > > ret);
> > > > > > > +return ret;
> > > > > > > +}
> > > > > > > +
> > > > > > > +ret = clk_prepare_enable(gc08a3->xclk);
> > > > > > > +if (ret < 0) {
> > > > > > > +regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
> > > > > > > +       gc08a3->supplies);
> > > > > > > +dev_err(gc08a3->dev, "clk prepare enable failed\n");
> > > > > > > +return ret;
> > > > > > > +}
> > > > > > > +
> > > > > > > +usleep_range(GC08A3_MIN_SLEEP_US, GC08A3_MAX_SLEEP_US);
> > > > > > > +
> > > > > > > +gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > > > > >
> > > > > > Are you asserting reset when powering on ? That sounds wrong,
> > you
> > > > should
> > > > > > de-assert reset here (and acquire the reset gpio in probe()
> > with
> > > > > > GPIOD_OUT_HIGH). Drivers should use logical levels for GPIOs,
> > > > setting a
> > > > > > GPIO named "reset" to 1 should assert the reset signal, even
> > if
> > > > the
> > > > > > physical signal is active low. You may have the wrong
> > polarity in
> > > > the
> > > > > > device tree.
> > > > >
> > > > > According to the sensor power sequence sepc, "reset" pin should
> > be
> > > > pull
> > > > > from low to high after "dovdd/dvdd/avdd" power on, so I follow
> > this
> > > > > power sequece to pull "reset" pin high in software flow.
> > > > 
> > > > From a hardware point of view that's right, but the Linux kernel
> > > > handles
> > > > logical level of GPIOs. If a GPIO is named "reset", it is
> > expected
> > > > that
> > > > calling
> > > > 
> > > > gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > > > 
> > > > will "assert" the reset signal, setting it to a logical "reset =
> > > > true"
> > > > level. This maps to the hardware 0V output level, as the signal
> > is
> > > > active-low. To achieve this, define the reset GPIO as active low
> > in
> > > > DT,
> > > > and the GPIO framework will invert the signal for you. You should
> > > > then
> > > > call
> > > > 
> > > > gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
> > > > 
> > > > in the driver when you want to assert reset (set it to 0V), and
> > > > 
> > > > gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);
> > > > 
> > > > when you want to deassert it (set it to 3.3V, or whatever the I/O
> > > > voltage for the signal is).
> > > > 
> > > > This way all driver use logical states, and the inversion is
> > handled
> > > > in
> > > > DT.
> > > > 
> > > 
> > > Sensor power sequence as below:
> > >                       ------------------
> > >                      | | |
> > >                      | | | 
> > > dvdd/avdd/dovdd  --------
> > >                                ---------
> > >                               |
> > >                               |
> > > reset-pin        -------------
> > > 
> > > In order to match this power sequece, "reset-pin" contrl flow is
> > below:
> > > 1. config the "reset-pin" is "active-high" in DTS:
> > >     reset-gpios = <&pio 19 GPIO_ACTIVE_HIGH>;
> > > 
> > > 2. image sensor driver probe function:
> > > gc08a3->reset_gpio = devm_gpiod_get(dev, "reset",
> > > GPIOD_OUT_LOW);  //init "reset-pin" is low
> > > 
> > > 3. image sensor driver power_on function:
> > > gpiod_set_value_cansleep(gc08a3->reset_gpio, 1); //pull "reset-pin"
> > > high 
> > > 
> > > so, the expect state of "reset-pin" is from low to high.
> > > If I am wrong, please correct me.
> > 
> > 
> > From Documentation/driver-api/gpio/consumer.rst:
> > 
> > As a consumer should not have to care about the physical line
> > level, all of the gpiod_set_value_xxx() or
> > gpiod_set_array_value_xxx() functions operate with the *logical*
> > value. With this they take the active low property into account.
> > This means that they check whether the GPIO is configured to be
> > active low, and if so, they manipulate the passed value before the
> > physical line level is driven.
> > 
> > I.e. when you want to enable reset, you set the value to 1 in the
> > driver. I
> > think you're now setting the value to 0 in that case. The opposite
> > for
> > disabling it of course.
> > 
> After checking "Documentation/driver-api/gpio/consumer.rst":
> To summarize::
>   Function (example)                 line property          physical
> line
> ...
>   gpiod_set_value(desc, 1);          default (active high)  high
>   gpiod_set_value(desc, 0);          active low             high
> ...
> 
> 
> From my understanding, it seems that "reset-pin" is using the
> following(active_high) case in current code: 
> "gpiod_set_value(desc, 1);          default (active high)  high" 
> 
> Do you mean, we should use the "active_low" case:
> "gpiod_set_value(desc, 0);          active low             high"
> Code should be changed as below:
> 1. config the "reset-pin" is "active-low" in DTS:
>    - reset-gpios = <&pio 19 GPIO_ACTIVE_LOW>
> 2. image sensor driver power_on function:
>    - gpiod_set_value_cansleep(gc08a3->reset_gpio, 0); //pull high 
> Is that so?

Correct.

-- 
Regards,

Sakari Ailus


From krzysztof.kozlowski at linaro.org  Tue Feb 20 23:43:52 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 08:43:52 +0100
Subject: [PATCH v2 1/4] dt-bindings: arm64: dts: airoha: Add en7581 series
In-Reply-To: <8589d9ca1469e73227af596852a9adf673ac50ad.1708473083.git.lorenzo@kernel.org>
References: <cover.1708473083.git.lorenzo@kernel.org>
 <8589d9ca1469e73227af596852a9adf673ac50ad.1708473083.git.lorenzo@kernel.org>
Message-ID: <c82d10cb-ab0c-4f1b-8492-3f8db3cc766e@linaro.org>

On 21/02/2024 01:04, Lorenzo Bianconi wrote:
> Introduce Airoha EN7581 entry in Airoha dts binding.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
> ---
>  Documentation/devicetree/bindings/arm/airoha.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 20 23:45:48 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 08:45:48 +0100
Subject: [PATCH v2 2/4] arm64: dts: Add Airoha EN7581 SoC and EN7581
 Evaluation Board
In-Reply-To: <f59389838c741650f6ff05d984a9127545e4eb83.1708473083.git.lorenzo@kernel.org>
References: <cover.1708473083.git.lorenzo@kernel.org>
 <f59389838c741650f6ff05d984a9127545e4eb83.1708473083.git.lorenzo@kernel.org>
Message-ID: <2e8e6a0a-44ce-45e4-8321-592f08852412@linaro.org>

On 21/02/2024 01:04, Lorenzo Bianconi wrote:
> From: Daniel Danzberger <dd at embedd.com>
> 
> Introduce the Airoha EN7581 SoC's dtsi and the Airoha EN7581 Evaluation
> Board's dts file, as well as the required Makefiles.
> 
> Signed-off-by: Daniel Danzberger <dd at embedd.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
> ---
>  arch/arm64/boot/dts/Makefile              |   1 +
>  arch/arm64/boot/dts/airoha/Makefile       |   2 +
>  arch/arm64/boot/dts/airoha/en7581-evb.dts |  27 +++++
>  arch/arm64/boot/dts/airoha/en7581.dtsi    | 137 ++++++++++++++++++++++
>  4 files changed, 167 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/airoha/Makefile
>  create mode 100644 arch/arm64/boot/dts/airoha/en7581-evb.dts
>  create mode 100644 arch/arm64/boot/dts/airoha/en7581.dtsi
> 
> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> index 30dd6347a929..21cd3a87f385 100644
> --- a/arch/arm64/boot/dts/Makefile
> +++ b/arch/arm64/boot/dts/Makefile
> @@ -1,5 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
>  subdir-y += actions
> +subdir-y += airoha
>  subdir-y += allwinner
>  subdir-y += altera
>  subdir-y += amazon
> diff --git a/arch/arm64/boot/dts/airoha/Makefile b/arch/arm64/boot/dts/airoha/Makefile
> new file mode 100644
> index 000000000000..ebea112ce1d7
> --- /dev/null
> +++ b/arch/arm64/boot/dts/airoha/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +dtb-$(CONFIG_ARCH_AIROHA) += en7581-evb.dtb
> diff --git a/arch/arm64/boot/dts/airoha/en7581-evb.dts b/arch/arm64/boot/dts/airoha/en7581-evb.dts
> new file mode 100644
> index 000000000000..4eaa8ac431c3
> --- /dev/null
> +++ b/arch/arm64/boot/dts/airoha/en7581-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 "en7581.dtsi"
> +
> +/ {
> +	model = "Airoha EN7581 Evaluation Board";
> +	compatible = "airoha,en7581-evb", "airoha,en7581";
> +
> +	aliases {
> +		serial0 = &uart1;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200 earlycon";

You have console below. You don't need earlycon for mainline, broad
usage, because it is purely debugging part, so drop entire bootargs.

> +		stdout-path = "serial0:115200n8";
> +		linux,usable-memory-range = <0x0 0x80200000 0x0 0x1fe00000>;
> +	};
> +
> +	memory at 80000000 {
> +		device_type = "memory";
> +		reg = <0x0 0x80000000 0x2 0x00000000>;
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/airoha/en7581.dtsi b/arch/arm64/boot/dts/airoha/en7581.dtsi
> new file mode 100644
> index 000000000000..7a3c0a45c03f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/airoha/en7581.dtsi
> @@ -0,0 +1,137 @@
> +// 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 = <2>;
> +	#size-cells = <2>;
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		npu_binary at 84000000 {

No underscores in nodenames.
...

> +
> +		L2_0: l2-cache0 {

Nodename: l2-cache

> +			compatible = "cache";
> +			cache-level = <2>;
> +			cache-unified;
> +		};
> +	};
> +
> +	gic: interrupt-controller at 9000000 {

Why this is outside of SoC? Where is your SoC node BTW?

It does not look like you tested the DTS against bindings. Please run
`make dtbs_check W=1` (see
Documentation/devicetree/bindings/writing-schema.rst or
https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
for instructions).

> +		compatible = "arm,gic-v3";
> +		interrupt-controller;
> +		#interrupt-cells = <3>;
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		reg = <0x0 0x09000000 0x0 0x20000>,
> +		      <0x0 0x09080000 0x0 0x80000>,
> +		      <0x0 0x09400000 0x0 0x2000>,
> +		      <0x0 0x09500000 0x0 0x2000>,
> +		      <0x0 0x09600000 0x0 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 {

This cannot be outside of SoC.

> +		compatible = "ns16550";
> +		reg = <0x0 0x1fbf0000 0x0 0x30>;
> +		reg-io-width = <4>;
> +		reg-shift = <2>;
> +		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
> +		clock-frequency = <1843200>;
> +		status = "okay";

Drop


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Tue Feb 20 23:46:45 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 08:46:45 +0100
Subject: [PATCH v2 4/4] arm64: defconfig: enable Airoha platform
In-Reply-To: <baf5af70e4c42042528914179b701f3dafcc972b.1708473083.git.lorenzo@kernel.org>
References: <cover.1708473083.git.lorenzo@kernel.org>
 <baf5af70e4c42042528914179b701f3dafcc972b.1708473083.git.lorenzo@kernel.org>
Message-ID: <5416be0b-79c8-4677-b7a7-a98f8e7160cd@linaro.org>

On 21/02/2024 01:04, Lorenzo Bianconi wrote:
> From: Daniel Danzberger <dd at embedd.com>
> 
> Enables the ARCH_AIROHA config by default.
> 
> Signed-off-by: Daniel Danzberger <dd at embedd.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
> ---
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index e6cf3e5d63c3..3966dbb79bb8 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -50,6 +50,7 @@ CONFIG_ARCH_LG1K=y
>  CONFIG_ARCH_HISI=y
>  CONFIG_ARCH_KEEMBAY=y
>  CONFIG_ARCH_MEDIATEK=y
> +CONFIG_ARCH_AIROHA=y

Are you sure it is placed in correct order? Looks a bit random, not
according to Kconfig ordering (savedefconfig).

Best regards,
Krzysztof



From sandor.yu at nxp.com  Tue Feb 20 23:46:46 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Wed, 21 Feb 2024 07:46:46 +0000
Subject: [PATCH v14 5/7] dt-bindings: phy: Add Freescale iMX8MQ DP and
 HDMI PHY
In-Reply-To: <10421561.nUPlyArG6x@steina-w>
References: <cover.1708395604.git.Sandor.yu@nxp.com>
 <8ddbb34b5f6bf2414bdb03f9e7cd9da70e4e7228.1708395604.git.Sandor.yu@nxp.com>
 <10421561.nUPlyArG6x@steina-w>
Message-ID: <PAXPR04MB9448F3065AE9F838C4553CB1F4572@PAXPR04MB9448.eurprd04.prod.outlook.com>

Hi Alexander,

Thanks for your comments,

>
>
> Hi,
>
> thanks for the update.
>
> Am Dienstag, 20. Februar 2024, 04:23:53 CET schrieb Sandor Yu:
> > Add bindings for Freescale iMX8MQ DP and HDMI PHY.
> >
> > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > Reviewed-by: Rob Herring <robh at kernel.org>
> > ---
> > v9->v14:
> >  *No change.
> >
> >  .../bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml  | 53
> > +++++++++++++++++++
> >  1 file changed, 53 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
> >
> > diff --git
> > a/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
> > b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yaml
> > new file mode 100644
> > index 0000000000000..917f113503dca
> > --- /dev/null
> > +++
> b/Documentation/devicetree/bindings/phy/fsl,imx8mq-dp-hdmi-phy.yam
> > +++ l
> > @@ -0,0 +1,53 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id:
> > +http://devi/
> >
> +cetree.org%2Fschemas%2Fphy%2Ffsl%2Cimx8mq-dp-hdmi-phy.yaml%23&da
> ta=05
> >
> +%7C02%7CSandor.yu%40nxp.com%7Ce79b4d15c204494963c508dc31fbab5d
> %7C686e
> >
> +a1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638440204190687801%7C
> Unknown%7
> >
> +CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWw
> iLCJX
> >
> +VCI6Mn0%3D%7C0%7C%7C%7C&sdata=rKWiYc1wbOvKMO%2BWnvT6agxo
> 9V%2B1ndZVTxh
> > +gLT0g7h8%3D&reserved=0
> > +$schema:
> > +http://devi/
> >
> +cetree.org%2Fmeta-schemas%2Fcore.yaml%23&data=05%7C02%7CSandor.y
> u%40n
> >
> +xp.com%7Ce79b4d15c204494963c508dc31fbab5d%7C686ea1d3bc2b4c6fa9
> 2cd99c5
> >
> +c301635%7C0%7C0%7C638440204190709341%7CUnknown%7CTWFpbGZsb
> 3d8eyJWIjoi
> >
> +MC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0
> %7C%7C%
> >
> +7C&sdata=%2FuCSz0aVVsRLorOqrorbZIyT7iU5BavPKCbA9qL9qDI%3D&reserv
> ed=0
> > +
> > +title: Cadence HDP-TX DP/HDMI PHY for Freescale i.MX8MQ SoC
> > +
> > +maintainers:
> > +  - Sandor Yu <sandor.yu at nxp.com>
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - fsl,imx8mq-dp-phy
> > +      - fsl,imx8mq-hdmi-phy
>
> While reading cdns-mhdp8501-core.c I'm not so sure about this. There is only
> a single PHY which can be configured for either DP or HDMI.
> Using separate compatibles for that somehow bugs me.
> Maybe the DT maintainers can add some input if this should be single or
> double compatibles.
>
When user enable MHDP8501 HDMI or DP, he should clearly know which type he want to enable,
>From board type, flash.bin(firmware) to dts(connector and phy type), they are all need align to HDMI or DP.

B.R
Sandor

> Thanks and best regards,
> Alexander
>
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    items:
> > +      - description: PHY reference clock.
> > +      - description: APB clock.
> > +
> > +  clock-names:
> > +    items:
> > +      - const: ref
> > +      - const: apb
> > +
> > +  "#phy-cells":
> > +    const: 0
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - clocks
> > +  - clock-names
> > +  - "#phy-cells"
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/imx8mq-clock.h>
> > +    #include <dt-bindings/phy/phy.h>
> > +    dp_phy: phy at 32c00000 {
> > +        compatible = "fsl,imx8mq-dp-phy";
> > +        reg = <0x32c00000 0x100000>;
> > +        #phy-cells = <0>;
> > +        clocks = <&hdmi_phy_27m>, <&clk
> IMX8MQ_CLK_DISP_APB_ROOT>;
> > +        clock-names = "ref", "apb";
> > +    };
> >
>
>
> --
> TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht M?nchen, HRB 105018
> Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> http://www.tq-/
> group.com%2F&data=05%7C02%7CSandor.yu%40nxp.com%7Ce79b4d15c2044
> 94963c508dc31fbab5d%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0
> %7C638440204190726471%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjA
> wMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7
> C&sdata=7xs1%2FC%2BK1cSFDc3rlBEZdNBsYw6Gc8AR6CWr2Djz4s0%3D&res
> erved=0
>



From sandor.yu at nxp.com  Tue Feb 20 23:47:52 2024
From: sandor.yu at nxp.com (Sandor Yu)
Date: Wed, 21 Feb 2024 07:47:52 +0000
Subject: [PATCH v14 7/7] phy: freescale: Add HDMI PHY driver for i.MX8MQ
In-Reply-To: <22191690.EfDdHjke4D@steina-w>
References: <cover.1708395604.git.Sandor.yu@nxp.com>
 <eb8c8aa5e5511d2bd462d05022764f67f7bb47c9.1708395604.git.Sandor.yu@nxp.com>
 <22191690.EfDdHjke4D@steina-w>
Message-ID: <PAXPR04MB9448DE5926B60C36D5BFC96AF4572@PAXPR04MB9448.eurprd04.prod.outlook.com>

Hi Alexander,

Thanks for your comments,

>
> Hi,
>
> thanks for the update.
>
> Am Dienstag, 20. Februar 2024, 04:23:55 CET schrieb Sandor Yu:
> > Add Cadence HDP-TX HDMI PHY driver for i.MX8MQ.
> >
> > Cadence HDP-TX PHY could be put in either DP mode or HDMI mode base
> on
> > the configuration chosen.
> > HDMI PHY mode is configurated in the driver.
> >
> > Signed-off-by: Sandor Yu <Sandor.yu at nxp.com>
> > Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com>
>
> This still works as before. I noticed there is a lot of code duplication with
> patch 6. IMHO these PHY drivers should be merged into a single one where
> the mode is configured using phy_set_mode() from cdns-mhdp8501-core.c.
> This nicely matches my concerns regarding patch 5.
>
Yes, there are some registers offset are same and the clock management function could be reused for DP and HDMI PHY driver.
But because of HDMI and DP PHY totally different work mode, the functions in struct phy_ops,
Such as ->init, ->power_on/off and ->configure could not combine into a single one,
So separate DP and HDMI PHY driver should be a better resolution.

B.R
Sandor


> Best regards,
> Alexander
>
> > ---
> > v13->v14:
> >  *No change.
> >
> > v12->v13:
> > - Fix build warning
> >
> > v11->v12:
> > - Adjust clk disable order.
> > - Return error code to replace -1 for function wait_for_ack().
> > - Use bool for variable pclk_in.
> > - Add year 2024 to copyright.
> >
> >  drivers/phy/freescale/Kconfig               |  10 +
> >  drivers/phy/freescale/Makefile              |   1 +
> >  drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c | 960
> > ++++++++++++++++++++
> >  3 files changed, 971 insertions(+)
> >  create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> >
> > diff --git a/drivers/phy/freescale/Kconfig
> > b/drivers/phy/freescale/Kconfig index c39709fd700ac..14f47b7cc77ab
> > 100644
> > --- a/drivers/phy/freescale/Kconfig
> > +++ b/drivers/phy/freescale/Kconfig
> > @@ -45,6 +45,16 @@ config PHY_FSL_IMX8MQ_DP
> >         Enable this to support the Cadence HDPTX DP PHY driver
> >         on i.MX8MQ SOC.
> >
> > +config PHY_FSL_IMX8MQ_HDMI
> > +     tristate "Freescale i.MX8MQ HDMI PHY support"
> > +     depends on OF && HAS_IOMEM
> > +     depends on COMMON_CLK
> > +     select GENERIC_PHY
> > +     select CDNS_MHDP_HELPER
> > +     help
> > +       Enable this to support the Cadence HDPTX HDMI PHY driver
> > +       on i.MX8MQ SOC.
> > +
> >  endif
> >
> >  config PHY_FSL_LYNX_28G
> > diff --git a/drivers/phy/freescale/Makefile
> > b/drivers/phy/freescale/Makefile index 47e5285209fa8..1380ac31c2ead
> > 100644
> > --- a/drivers/phy/freescale/Makefile
> > +++ b/drivers/phy/freescale/Makefile
> > @@ -1,5 +1,6 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >  obj-$(CONFIG_PHY_FSL_IMX8MQ_DP)              +=
> phy-fsl-imx8mq-dp.o
> > +obj-$(CONFIG_PHY_FSL_IMX8MQ_HDMI)    += phy-fsl-imx8mq-hdmi.o
> >  obj-$(CONFIG_PHY_FSL_IMX8MQ_USB)     += phy-fsl-imx8mq-usb.o
> >  obj-$(CONFIG_PHY_MIXEL_LVDS_PHY)     += phy-fsl-imx8qm-lvds-phy.o
> >  obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)    += phy-fsl-imx8-mipi-dphy.o
> > diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> > b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> > new file mode 100644
> > index 0000000000000..537b1f45c91cc
> > --- /dev/null
> > +++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> > @@ -0,0 +1,960 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Cadence High-Definition Multimedia Interface (HDMI) PHY driver
> > + *
> > + * Copyright (C) 2022-2024 NXP Semiconductor, Inc.
> > + */
> > +#include <asm/unaligned.h>
> > +#include <drm/bridge/cdns-mhdp-helper.h> #include <linux/clk.h>
> > +#include <linux/kernel.h> #include <linux/phy/phy.h> #include
> > +<linux/platform_device.h> #include <linux/io.h>
> > +
> > +#define ADDR_PHY_AFE 0x80000
> > +
> > +/* PHY registers */
> > +#define CMN_SSM_BIAS_TMR                     0x0022
> > +#define CMN_PLLSM0_USER_DEF_CTRL             0x002f
> > +#define CMN_PSM_CLK_CTRL                     0x0061
> > +#define CMN_CDIAG_REFCLK_CTRL                        0x0062
> > +#define CMN_PLL0_VCOCAL_START                        0x0081
> > +#define CMN_PLL0_VCOCAL_INIT_TMR             0x0084
> > +#define CMN_PLL0_VCOCAL_ITER_TMR             0x0085
> > +#define CMN_TXPUCAL_CTRL                     0x00e0
> > +#define CMN_TXPDCAL_CTRL                     0x00f0
> > +#define CMN_TXPU_ADJ_CTRL                    0x0108
> > +#define CMN_TXPD_ADJ_CTRL                    0x010c
> > +#define CMN_DIAG_PLL0_FBH_OVRD                       0x01c0
> > +#define CMN_DIAG_PLL0_FBL_OVRD                       0x01c1
> > +#define CMN_DIAG_PLL0_OVRD                   0x01c2
> > +#define CMN_DIAG_PLL0_TEST_MODE                      0x01c4
> > +#define CMN_DIAG_PLL0_V2I_TUNE                       0x01c5
> > +#define CMN_DIAG_PLL0_CP_TUNE                        0x01c6
> > +#define CMN_DIAG_PLL0_LF_PROG                        0x01c7
> > +#define CMN_DIAG_PLL0_PTATIS_TUNE1           0x01c8
> > +#define CMN_DIAG_PLL0_PTATIS_TUNE2           0x01c9
> > +#define CMN_DIAG_PLL0_INCLK_CTRL             0x01ca
> > +#define CMN_DIAG_PLL0_PXL_DIVH                       0x01cb
> > +#define CMN_DIAG_PLL0_PXL_DIVL                       0x01cc
> > +#define CMN_DIAG_HSCLK_SEL                   0x01e0
> > +#define XCVR_PSM_RCTRL                               0x4001
> > +#define TX_TXCC_CAL_SCLR_MULT_0                      0x4047
> > +#define TX_TXCC_CPOST_MULT_00_0                      0x404c
> > +#define XCVR_DIAG_PLLDRC_CTRL                        0x40e0
> > +#define XCVR_DIAG_PLLDRC_CTRL                        0x40e0
> > +#define XCVR_DIAG_HSCLK_SEL                  0x40e1
> > +#define XCVR_DIAG_BIDI_CTRL                  0x40e8
> > +#define TX_PSC_A0                            0x4100
> > +#define TX_PSC_A1                            0x4101
> > +#define TX_PSC_A2                            0x4102
> > +#define TX_PSC_A3                            0x4103
> > +#define TX_DIAG_TX_CTRL                              0x41e0
> > +#define TX_DIAG_TX_DRV                               0x41e1
> > +#define TX_DIAG_BGREF_PREDRV_DELAY           0x41e7
> > +#define TX_DIAG_ACYA_0                               0x41ff
> > +#define TX_DIAG_ACYA_1                               0x43ff
> > +#define TX_DIAG_ACYA_2                               0x45ff
> > +#define TX_DIAG_ACYA_3                               0x47ff
> > +#define TX_ANA_CTRL_REG_1                    0x5020
> > +#define TX_ANA_CTRL_REG_2                    0x5021
> > +#define TX_DIG_CTRL_REG_2                    0x5024
> > +#define TXDA_CYA_AUXDA_CYA                   0x5025
> > +#define TX_ANA_CTRL_REG_3                    0x5026
> > +#define TX_ANA_CTRL_REG_4                    0x5027
> > +#define TX_ANA_CTRL_REG_5                    0x5029
> > +#define RX_PSC_A0                            0x8000
> > +#define RX_PSC_CAL                           0x8006
> > +#define PHY_HDP_MODE_CTRL                    0xc008
> > +#define PHY_HDP_CLK_CTL                              0xc009
> > +#define PHY_ISO_CMN_CTRL                     0xc010
> > +#define PHY_PMA_CMN_CTRL1                    0xc800
> > +#define PHY_PMA_ISO_CMN_CTRL                 0xc810
> > +#define PHY_PMA_ISO_PLL_CTRL1                        0xc812
> > +#define PHY_PMA_ISOLATION_CTRL                       0xc81f
> > +
> > +/* PHY_HDP_CLK_CTL */
> > +#define PLL_DATA_RATE_CLK_DIV_MASK           GENMASK(15, 8)
> > +#define PLL_DATA_RATE_CLK_DIV_HBR            0x24
> > +#define PLL_DATA_RATE_CLK_DIV_HBR2           0x12
> > +#define PLL_CLK_EN_ACK_EN                    BIT(3)
> > +#define PLL_CLK_EN                           BIT(2)
> > +#define PLL_READY                            BIT(1)
> > +#define PLL_EN                                       BIT(0)
> > +
> > +/* PHY_PMA_CMN_CTRL1 */
> > +#define CMA_REF_CLK_DIG_DIV_MASK             GENMASK(13, 12)
> > +#define CMA_REF_CLK_SEL_MASK                 GENMASK(6, 4)
> > +#define CMA_REF_CLK_RCV_EN_MASK                      BIT(3)
> > +#define CMA_REF_CLK_RCV_EN                   1
> > +#define CMN_READY                            BIT(0)
> > +
> > +/* PHY_PMA_ISO_PLL_CTRL1 */
> > +#define CMN_PLL0_CLK_DATART_DIV_MASK         GENMASK(7, 0)
> > +
> > +/* TX_DIAG_TX_DRV */
> > +#define TX_DRIVER_PROG_BOOST_ENABLE          BIT(10)
> > +#define TX_DRIVER_PROG_BOOST_LEVEL_MASK
> GENMASK(9, 8)
> > +#define TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE        BIT(7)
> > +#define TX_DRIVER_LDO_BANDGAP_REF_ENABLE     BIT(6)
> > +
> > +/* TX_TXCC_CAL_SCLR_MULT_0 */
> > +#define SCALED_RESISTOR_CALIBRATION_CODE_ADD BIT(8)
> > +#define RESISTOR_CAL_MULT_VAL_32_128         BIT(5)
> > +
> > +/* CMN_CDIAG_REFCLK_CTRL */
> > +#define DIG_REF_CLK_DIV_SCALER_MASK          GENMASK(14, 12)
> > +#define REFCLK_TERMINATION_EN_OVERRIDE_EN    BIT(7)
> > +#define REFCLK_TERMINATION_EN_OVERRIDE               BIT(6)
> > +
> > +/* CMN_DIAG_HSCLK_SEL */
> > +#define HSCLK1_SEL_MASK
> GENMASK(5, 4)
> > +#define HSCLK0_SEL_MASK
> GENMASK(1, 0)
> > +
> > +/* XCVR_DIAG_HSCLK_SEL */
> > +#define HSCLK_SEL_MODE3_MASK                 GENMASK(13, 12)
> > +#define HSCLK_SEL_MODE3_HSCLK1                       1
> > +
> > +/* CMN_PLL0_VCOCAL_START */
> > +#define VCO_CALIB_CODE_START_POINT_VAL_MASK  GENMASK(8, 0)
> > +
> > +/* CMN_DIAG_PLL0_FBH_OVRD */
> > +#define PLL_FEEDBACK_DIV_HI_OVERRIDE_EN              BIT(15)
> > +
> > +/* CMN_DIAG_PLL0_FBL_OVRD */
> > +#define PLL_FEEDBACK_DIV_LO_OVERRIDE_EN              BIT(15)
> > +
> > +/* CMN_DIAG_PLL0_PXL_DIVH */
> > +#define PLL_PCLK_DIV_EN                              BIT(15)
> > +
> > +/* XCVR_DIAG_PLLDRC_CTRL */
> > +#define DPLL_CLK_SEL_MODE3                   BIT(14)
> > +
> > +/* TX_DIAG_TX_CTRL */
> > +#define TX_IF_SUBRATE_MODE3_MASK             GENMASK(7, 6)
> > +
> > +/* PHY_HDP_MODE_CTRL */
> > +#define POWER_STATE_A3_ACK                   BIT(7)
> > +#define POWER_STATE_A2_ACK                   BIT(6)
> > +#define POWER_STATE_A1_ACK                   BIT(5)
> > +#define POWER_STATE_A0_ACK                   BIT(4)
> > +#define POWER_STATE_A3                               BIT(3)
> > +#define POWER_STATE_A2                               BIT(2)
> > +#define POWER_STATE_A1                               BIT(1)
> > +#define POWER_STATE_A0                               BIT(0)
> > +
> > +/* PHY_PMA_ISO_CMN_CTRL */
> > +#define CMN_MACRO_PWR_EN_ACK                 BIT(5)
> > +
> > +#define KEEP_ALIVE           0x18
> > +
> > +#define REF_CLK_27MHZ                27000000
> > +
> > +/* HDMI TX clock control settings */
> > +struct hdptx_hdmi_ctrl {
> > +     u32 pixel_clk_freq_min;
> > +     u32 pixel_clk_freq_max;
> > +     u32 feedback_factor;
> > +     u32 data_range_kbps_min;
> > +     u32 data_range_kbps_max;
> > +     u32 cmnda_pll0_ip_div;
> > +     u32 cmn_ref_clk_dig_div;
> > +     u32 ref_clk_divider_scaler;
> > +     u32 pll_fb_div_total;
> > +     u32 cmnda_pll0_fb_div_low;
> > +     u32 cmnda_pll0_fb_div_high;
> > +     u32 pixel_div_total;
> > +     u32 cmnda_pll0_pxdiv_low;
> > +     u32 cmnda_pll0_pxdiv_high;
> > +     u32 vco_freq_min;
> > +     u32 vco_freq_max;
> > +     u32 vco_ring_select;
> > +     u32 cmnda_hs_clk_0_sel;
> > +     u32 cmnda_hs_clk_1_sel;
> > +     u32 hsclk_div_at_xcvr;
> > +     u32 hsclk_div_tx_sub_rate;
> > +     u32 cmnda_pll0_hs_sym_div_sel;
> > +     u32 cmnda_pll0_clk_freq_min;
> > +     u32 cmnda_pll0_clk_freq_max;
> > +};
> > +
> > +struct cdns_hdptx_hdmi_phy {
> > +     struct cdns_mhdp_base base;
> > +
> > +     void __iomem *regs;     /* DPTX registers base */
> > +     struct mutex mbox_mutex; /* mutex to protect mailbox */
> > +     struct device *dev;
> > +     struct phy *phy;
> > +     struct clk *ref_clk, *apb_clk;
> > +     u32 ref_clk_rate;
> > +     u32 pixel_clk_rate;
> > +     enum hdmi_colorspace color_space;
> > +     u32 bpc;
> > +};
> > +
> > +/* HDMI TX clock control settings, pixel clock is output */ static
> > +const struct hdptx_hdmi_ctrl pixel_clk_output_ctrl_table[] = {
> > +/*Minclk  Maxclk Fdbak  DR_min   DR_max  ip_d  dig  DS    Totl
> */
> > +{ 27000,  27000, 1000,  270000,  270000, 0x03, 0x1, 0x1,  240, 0x0bc,
> > +0x030,  80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x3,
> > +27000,  27000}, { 27000,  27000, 1250,  337500,  337500, 0x03, 0x1,
> > +0x1,  300, 0x0ec, 0x03c, 100, 0x030, 0x030, 2700000, 2700000, 0, 2,
> > +2, 2, 4, 0x3,  33750,  33750}, { 27000,  27000, 1500,  405000,
> > +405000, 0x03, 0x1, 0x1,  360, 0x11c, 0x048, 120, 0x03a, 0x03a,
> > +3240000, 3240000, 0, 2, 2, 2, 4, 0x3,  40500,  40500}, { 27000,
> > +27000, 2000,  540000,  540000, 0x03, 0x1, 0x1,  240, 0x0bc, 0x030,
> > +80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x2,  54000,
> > +54000}, { 54000,  54000, 1000,  540000,  540000, 0x03, 0x1, 0x1,
> > +480, 0x17c, 0x060,  80, 0x026, 0x026, 4320000, 4320000, 1, 2, 2, 2,
> > +4, 0x3,  54000,  54000}, { 54000,  54000, 1250,  675000,  675000,
> > +0x04, 0x1, 0x1,  400, 0x13c, 0x050,  50, 0x017, 0x017, 2700000,
> > +2700000, 0, 1, 1, 2, 4, 0x2,  67500,  67500}, { 54000,  54000, 1500,
> > +810000,  810000, 0x04, 0x1, 0x1,  480, 0x17c, 0x060,  60, 0x01c,
> > +0x01c, 3240000, 3240000, 0, 2, 2, 2, 2, 0x2,  81000,  81000}, {
> > +54000,  54000, 2000, 1080000, 1080000, 0x03, 0x1, 0x1,  240, 0x0bc,
> > +0x030,  40, 0x012, 0x012, 2160000, 2160000, 0, 2, 2, 2, 1, 0x1,
> > +108000, 108000}, { 74250,  74250, 1000,  742500,  742500, 0x03, 0x1,
> > +0x1,  660, 0x20c, 0x084,  80, 0x026, 0x026, 5940000, 5940000, 1, 2,
> > +2, 2, 4, 0x3,  74250,  74250}, { 74250,  74250, 1250,  928125,
> > +928125, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,  50, 0x017, 0x017,
> > +3712500, 3712500, 1, 1, 1, 2, 4, 0x2,  92812,  92812}, { 74250,
> > +74250, 1500, 1113750, 1113750, 0x04, 0x1, 0x1,  660, 0x20c, 0x084,
> > +60, 0x01c, 0x01c, 4455000, 4455000, 1, 2, 2, 2, 2, 0x2, 111375,
> > +111375}, { 74250,  74250, 2000, 1485000, 1485000, 0x03, 0x1, 0x1,
> > +330, 0x104, 0x042,  40, 0x012, 0x012, 2970000, 2970000, 0, 2, 2, 2,
> > +1, 0x1, 148500, 148500}, { 99000,  99000, 1000,  990000,  990000,
> > +0x03, 0x1, 0x1,  440, 0x15c, 0x058,  40, 0x012, 0x012, 3960000,
> > +3960000, 1, 2, 2, 2, 2, 0x2,  99000,  99000}, { 99000,  99000, 1250,
> > +1237500, 1237500, 0x03, 0x1, 0x1,  275, 0x0d8, 0x037,  25, 0x00b,
> > +0x00a, 2475000, 2475000, 0, 1, 1, 2, 2, 0x1, 123750, 123750}, {
> > +99000,  99000, 1500, 1485000, 1485000, 0x03, 0x1, 0x1,  330, 0x104,
> > +0x042,  30, 0x00d, 0x00d, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1,
> > +148500, 148500}, { 99000,  99000, 2000, 1980000, 1980000, 0x03, 0x1,
> > +0x1,  440, 0x15c, 0x058,  40, 0x012, 0x012, 3960000, 3960000, 1, 2,
> > +2, 2, 1, 0x1, 198000, 198000}, {148500, 148500, 1000, 1485000,
> > +1485000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  40, 0x012, 0x012,
> > +5940000, 5940000, 1, 2, 2, 2, 2, 0x2, 148500, 148500}, {148500,
> > +148500, 1250, 1856250, 1856250, 0x04, 0x1, 0x1,  550, 0x1b4, 0x06e,
> > +25, 0x00b, 0x00a, 3712500, 3712500, 1, 1, 1, 2, 2, 0x1, 185625,
> > +185625}, {148500, 148500, 1500, 2227500, 2227500, 0x03, 0x1, 0x1,
> > +495, 0x188, 0x063,  30, 0x00d, 0x00d, 4455000, 4455000, 1, 1, 1, 2,
> > +2, 0x1, 222750, 222750}, {148500, 148500, 2000, 2970000, 2970000,
> > +0x03, 0x1, 0x1,  660, 0x20c, 0x084,  40, 0x012, 0x012, 5940000,
> > +5940000, 1, 2, 2, 2, 1, 0x1, 297000, 297000}, {198000, 198000, 1000,
> > +1980000, 1980000, 0x03, 0x1, 0x1,  220, 0x0ac, 0x02c,  10, 0x003,
> > +0x003, 1980000, 1980000, 0, 1, 1, 2, 1, 0x0, 198000, 198000},
> > +{198000, 198000, 1250, 2475000, 2475000, 0x03, 0x1, 0x1,  550, 0x1b4,
> > +0x06e,  25, 0x00b, 0x00a, 4950000, 4950000, 1, 1, 1, 2, 2, 0x1,
> > +247500, 247500}, {198000, 198000, 1500, 2970000, 2970000, 0x03, 0x1,
> > +0x1,  330, 0x104, 0x042,  15, 0x006, 0x005, 2970000, 2970000, 0, 1,
> > +1, 2, 1, 0x0, 297000, 297000}, {198000, 198000, 2000, 3960000,
> > +3960000, 0x03, 0x1, 0x1,  440, 0x15c, 0x058,  20, 0x008, 0x008,
> > +3960000, 3960000, 1, 1, 1, 2, 1, 0x0, 396000, 396000}, {297000,
> > +297000, 1000, 2970000, 2970000, 0x03, 0x1, 0x1,  330, 0x104, 0x042,
> > +10, 0x003, 0x003, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000,
> > +297000}, {297000, 297000, 1500, 4455000, 4455000, 0x03, 0x1, 0x1,
> > +495, 0x188, 0x063,  15, 0x006, 0x005, 4455000, 4455000, 1, 1, 1, 2,
> > +1, 0x0, 445500, 445500}, {297000, 297000, 2000, 5940000, 5940000,
> > +0x03, 0x1, 0x1,  660, 0x20c, 0x084,  20, 0x008, 0x008, 5940000,
> > +5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000}, {594000, 594000, 1000,
> > +5940000, 5940000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  10, 0x003,
> > +0x003, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000},
> > +{594000, 594000,  750, 4455000, 4455000, 0x03, 0x1, 0x1,  495, 0x188,
> > +0x063,  10, 0x003, 0x003, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0,
> > +445500, 445500}, {594000, 594000,  625, 3712500, 3712500, 0x04, 0x1,
> > +0x1,  550, 0x1b4, 0x06e,  10, 0x003, 0x003, 3712500, 3712500, 1, 1,
> > +1, 2, 1, 0x0, 371250, 371250}, {594000, 594000,  500, 2970000,
> > +2970000, 0x03, 0x1, 0x1,  660, 0x20c, 0x084,  10, 0x003, 0x003,
> > +5940000, 5940000, 1, 1, 1, 2, 2, 0x1, 297000, 297000}, };
> > +
> > +/* HDMI TX PLL tuning settings */
> > +struct hdptx_hdmi_pll_tuning {
> > +     u32 vco_freq_bin;
> > +     u32 vco_freq_min;
> > +     u32 vco_freq_max;
> > +     u32 volt_to_current_coarse;
> > +     u32 volt_to_current;
> > +     u32 ndac_ctrl;
> > +     u32 pmos_ctrl;
> > +     u32 ptat_ndac_ctrl;
> > +     u32 feedback_div_total;
> > +     u32 charge_pump_gain;
> > +     u32 coarse_code;
> > +     u32 v2i_code;
> > +     u32 vco_cal_code;
> > +};
> > +
> > +/* HDMI TX PLL tuning settings, pixel clock is output */ static const
> > +struct hdptx_hdmi_pll_tuning pixel_clk_output_pll_table[] = { /*bin
> > +VCO_freq min/max  coar  cod NDAC  PMOS PTAT div-T P-Gain Coa V2I
> CAL
> > +*/ {  1, 1980000, 1980000, 0x4, 0x3, 0x0, 0x09, 0x09, 220, 0x42, 160,
> > +5, 183 }, {  2, 2160000, 2160000, 0x4, 0x3, 0x0, 0x09, 0x09, 240,
> > +0x42, 166, 6, 208 }, {  3, 2475000, 2475000, 0x5, 0x3, 0x1, 0x00,
> > +0x07, 275, 0x42, 167, 6, 209 }, {  4, 2700000, 2700000, 0x5, 0x3,
> > +0x1, 0x00, 0x07, 300, 0x42, 188, 6, 230 }, {  4, 2700000, 2700000,
> > +0x5, 0x3, 0x1, 0x00, 0x07, 400, 0x4c, 188, 6, 230 }, {  5, 2970000,
> > +2970000, 0x6, 0x3, 0x1, 0x00, 0x07, 330, 0x42, 183, 6, 225 }, {  6,
> > +3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 360, 0x42, 203, 7, 256
> > +}, {  6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 480, 0x4c, 203,
> > +7, 256 }, {  7, 3712500, 3712500, 0x4, 0x3, 0x0, 0x07, 0x0F, 550,
> > +0x4c, 212, 7, 257 }, {  8, 3960000, 3960000, 0x5, 0x3, 0x0, 0x07,
> > +0x0F, 440, 0x42, 184, 6, 226 }, {  9, 4320000, 4320000, 0x5, 0x3,
> > +0x1, 0x07, 0x0F, 480, 0x42, 205, 7, 258 }, { 10, 4455000, 4455000,
> > +0x5, 0x3, 0x0, 0x07, 0x0F, 495, 0x42, 219, 7, 272 }, { 10, 4455000,
> > +4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 660, 0x4c, 219, 7, 272 }, { 11,
> > +4950000, 4950000, 0x6, 0x3, 0x1, 0x00, 0x07, 550, 0x42, 213, 7, 258
> > +}, { 12, 5940000, 5940000, 0x7, 0x3, 0x1, 0x00, 0x07, 660, 0x42, 244,
> > +8, 292 }, };
> > +
> > +static int cdns_phy_reg_write(struct cdns_hdptx_hdmi_phy *cdns_phy,
> > +u32 addr, u32 val) {
> > +     return cdns_mhdp_reg_write(&cdns_phy->base, ADDR_PHY_AFE +
> (addr
> > +<< 2), val); }
> > +
> > +static u32 cdns_phy_reg_read(struct cdns_hdptx_hdmi_phy *cdns_phy,
> > +u32 addr) {
> > +     u32 reg32;
> > +
> > +     cdns_mhdp_reg_read(&cdns_phy->base, ADDR_PHY_AFE + (addr <<
> 2),
> > + &reg32);
> > +
> > +     return reg32;
> > +}
> > +
> > +static int wait_for_ack(struct cdns_hdptx_hdmi_phy *cdns_phy, u32 reg,
> u32 mask,
> > +                     const char *err_msg) {
> > +     u32 val, i;
> > +
> > +     for (i = 0; i < 10; i++) {
> > +             val = cdns_phy_reg_read(cdns_phy, reg);
> > +             if (val & mask)
> > +                     return 0;
> > +             msleep(20);
> > +     }
> > +
> > +     dev_err(cdns_phy->dev, "%s\n", err_msg);
> > +     return -ETIMEDOUT;
> > +}
> > +
> > +static bool hdptx_phy_check_alive(struct cdns_hdptx_hdmi_phy
> > +*cdns_phy) {
> > +     u32  alive, newalive;
> > +     u8 retries_left = 50;
> > +
> > +     alive = readl(cdns_phy->regs + KEEP_ALIVE);
> > +
> > +     while (retries_left--) {
> > +             udelay(2);
> > +
> > +             newalive = readl(cdns_phy->regs + KEEP_ALIVE);
> > +             if (alive == newalive)
> > +                     continue;
> > +             return true;
> > +     }
> > +     return false;
> > +}
> > +
> > +static int hdptx_hdmi_clk_enable(struct cdns_hdptx_hdmi_phy
> > +*cdns_phy) {
> > +     struct device *dev = cdns_phy->dev;
> > +     u32 ref_clk_rate;
> > +     int ret;
> > +
> > +     cdns_phy->ref_clk = devm_clk_get(dev, "ref");
> > +     if (IS_ERR(cdns_phy->ref_clk)) {
> > +             dev_err(dev, "phy ref clock not found\n");
> > +             return PTR_ERR(cdns_phy->ref_clk);
> > +     }
> > +
> > +     cdns_phy->apb_clk = devm_clk_get(dev, "apb");
> > +     if (IS_ERR(cdns_phy->apb_clk)) {
> > +             dev_err(dev, "phy apb clock not found\n");
> > +             return PTR_ERR(cdns_phy->apb_clk);
> > +     }
> > +
> > +     ret = clk_prepare_enable(cdns_phy->ref_clk);
> > +     if (ret) {
> > +             dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
> > +             return ret;
> > +     }
> > +
> > +     ref_clk_rate = clk_get_rate(cdns_phy->ref_clk);
> > +     if (!ref_clk_rate) {
> > +             dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
> > +             goto err_ref_clk;
> > +     }
> > +
> > +     if (ref_clk_rate == REF_CLK_27MHZ) {
> > +             cdns_phy->ref_clk_rate = ref_clk_rate;
> > +     } else {
> > +             dev_err(cdns_phy->dev, "Not support Ref Clock
> Rate(%dHz)\n", ref_clk_rate);
> > +             goto err_ref_clk;
> > +     }
> > +
> > +     ret = clk_prepare_enable(cdns_phy->apb_clk);
> > +     if (ret) {
> > +             dev_err(cdns_phy->dev, "Failed to prepare apb clock\n");
> > +             goto err_ref_clk;
> > +     }
> > +
> > +     return 0;
> > +
> > +err_ref_clk:
> > +     clk_disable_unprepare(cdns_phy->ref_clk);
> > +     return -EINVAL;
> > +}
> > +
> > +static void hdptx_hdmi_clk_disable(struct cdns_hdptx_hdmi_phy
> > +*cdns_phy) {
> > +     clk_disable_unprepare(cdns_phy->apb_clk);
> > +     clk_disable_unprepare(cdns_phy->ref_clk);
> > +}
> > +
> > +static void hdptx_hdmi_arc_config(struct cdns_hdptx_hdmi_phy
> > +*cdns_phy) {
> > +     u16 txpu_calib_code;
> > +     u16 txpd_calib_code;
> > +     u16 txpu_adj_calib_code;
> > +     u16 txpd_adj_calib_code;
> > +     u16 prev_calib_code;
> > +     u16 new_calib_code;
> > +     u16 rdata;
> > +
> > +     /* Power ARC */
> > +     cdns_phy_reg_write(cdns_phy, TXDA_CYA_AUXDA_CYA, 0x0001);
> > +
> > +     prev_calib_code = cdns_phy_reg_read(cdns_phy,
> TX_DIG_CTRL_REG_2);
> > +     txpu_calib_code = cdns_phy_reg_read(cdns_phy,
> CMN_TXPUCAL_CTRL);
> > +     txpd_calib_code = cdns_phy_reg_read(cdns_phy,
> CMN_TXPDCAL_CTRL);
> > +     txpu_adj_calib_code = cdns_phy_reg_read(cdns_phy,
> CMN_TXPU_ADJ_CTRL);
> > +     txpd_adj_calib_code = cdns_phy_reg_read(cdns_phy,
> > + CMN_TXPD_ADJ_CTRL);
> > +
> > +     new_calib_code = ((txpu_calib_code + txpd_calib_code) / 2)
> > +             + txpu_adj_calib_code + txpd_adj_calib_code;
> > +
> > +     if (new_calib_code != prev_calib_code) {
> > +             rdata = cdns_phy_reg_read(cdns_phy,
> TX_ANA_CTRL_REG_1);
> > +             rdata &= 0xdfff;
> > +             cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1,
> rdata);
> > +             cdns_phy_reg_write(cdns_phy, TX_DIG_CTRL_REG_2,
> new_calib_code);
> > +             mdelay(10);
> > +             rdata |= 0x2000;
> > +             cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1,
> rdata);
> > +             usleep_range(150, 250);
> > +     }
> > +
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0100);
> > +     usleep_range(100, 200);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x0300);
> > +     usleep_range(100, 200);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_3, 0x0000);
> > +     usleep_range(100, 200);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2008);
> > +     usleep_range(100, 200);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2018);
> > +     usleep_range(100, 200);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2098);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030c);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_5, 0x0010);
> > +     usleep_range(100, 200);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_4, 0x4001);
> > +     mdelay(5);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_1, 0x2198);
> > +     mdelay(5);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030d);
> > +     usleep_range(100, 200);
> > +     cdns_phy_reg_write(cdns_phy, TX_ANA_CTRL_REG_2, 0x030f); }
> > +
> > +static void hdptx_hdmi_phy_set_vswing(struct cdns_hdptx_hdmi_phy
> > +*cdns_phy) {
> > +     u32 k;
> > +     const u32 num_lanes = 4;
> > +
> > +     for (k = 0; k < num_lanes; k++) {
> > +             cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_DRV | (k <<
> 9)),
> > +
> TX_DRIVER_PROG_BOOST_ENABLE |
> > +
> FIELD_PREP(TX_DRIVER_PROG_BOOST_LEVEL_MASK, 3) |
> > +
> TX_DRIVER_LDO_BG_DEPENDENT_REF_ENABLE |
> > +
> TX_DRIVER_LDO_BANDGAP_REF_ENABLE);
> > +             cdns_phy_reg_write(cdns_phy,
> (TX_TXCC_CPOST_MULT_00_0 | (k << 9)), 0x0);
> > +             cdns_phy_reg_write(cdns_phy,
> (TX_TXCC_CAL_SCLR_MULT_0 | (k << 9)),
> > +
> SCALED_RESISTOR_CALIBRATION_CODE_ADD |
> > +
> RESISTOR_CAL_MULT_VAL_32_128);
> > +     }
> > +}
> > +
> > +static int hdptx_hdmi_feedback_factor(struct cdns_hdptx_hdmi_phy
> > +*cdns_phy) {
> > +     u32 feedback_factor;
> > +
> > +     switch (cdns_phy->color_space) {
> > +     case HDMI_COLORSPACE_YUV422:
> > +             feedback_factor = 1000;
> > +             break;
> > +
> > +     case HDMI_COLORSPACE_YUV420:
> > +             switch (cdns_phy->bpc) {
> > +             case 8:
> > +                     feedback_factor = 500;
> > +                     break;
> > +             case 10:
> > +                     feedback_factor = 625;
> > +                     break;
> > +             case 12:
> > +                     feedback_factor = 750;
> > +                     break;
> > +             case 16:
> > +                     feedback_factor = 1000;
> > +                     break;
> > +             default:
> > +                     dev_dbg(cdns_phy->dev, "Invalid
> ColorDepth\n");
> > +                     return 0;
> > +             }
> > +             break;
> > +
> > +     default:
> > +             /* Assume RGB/YUV444 */
> > +             switch (cdns_phy->bpc) {
> > +             case 10:
> > +                     feedback_factor = 1250;
> > +                     break;
> > +             case 12:
> > +                     feedback_factor = 1500;
> > +                     break;
> > +             case 16:
> > +                     feedback_factor = 2000;
> > +                     break;
> > +             default:
> > +                     feedback_factor = 1000;
> > +             }
> > +     }
> > +
> > +     return feedback_factor;
> > +}
> > +
> > +static int hdptx_hdmi_phy_config(struct cdns_hdptx_hdmi_phy *cdns_phy,
> > +                              const struct hdptx_hdmi_ctrl
> *p_ctrl_table,
> > +                              const struct hdptx_hdmi_pll_tuning
> *p_pll_table,
> > +                              bool pclk_in) {
> > +     const u32 num_lanes = 4;
> > +     u32 val, k;
> > +     int ret;
> > +
> > +     /* enable PHY isolation mode only for CMN */
> > +     cdns_phy_reg_write(cdns_phy, PHY_PMA_ISOLATION_CTRL,
> 0xd000);
> > +
> > +     /* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div dividers
> */
> > +     val = cdns_phy_reg_read(cdns_phy, PHY_PMA_ISO_PLL_CTRL1);
> > +     val &= ~CMN_PLL0_CLK_DATART_DIV_MASK;
> > +     val |= FIELD_PREP(CMN_PLL0_CLK_DATART_DIV_MASK, 0x12);
> > +     cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_PLL_CTRL1, val);
> > +
> > +     /* assert PHY reset from isolation register */
> > +     cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0000);
> > +     /* assert PMA CMN reset */
> > +     cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0000);
> > +
> > +     /* register XCVR_DIAG_BIDI_CTRL */
> > +     for (k = 0; k < num_lanes; k++)
> > +             cdns_phy_reg_write(cdns_phy, XCVR_DIAG_BIDI_CTRL |
> (k <<
> > + 9), 0x00ff);
> > +
> > +     /* Describing Task phy_cfg_hdp */
> > +     val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
> > +     val &= ~CMA_REF_CLK_RCV_EN_MASK;
> > +     val |= FIELD_PREP(CMA_REF_CLK_RCV_EN_MASK,
> CMA_REF_CLK_RCV_EN);
> > +     cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
> > +
> > +     /* PHY Registers */
> > +     val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
> > +     val &= ~CMA_REF_CLK_DIG_DIV_MASK;
> > +     val |= FIELD_PREP(CMA_REF_CLK_DIG_DIV_MASK,
> p_ctrl_table->cmn_ref_clk_dig_div);
> > +     cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
> > +
> > +     val = cdns_phy_reg_read(cdns_phy, PHY_HDP_CLK_CTL);
> > +     val &= ~PLL_DATA_RATE_CLK_DIV_MASK;
> > +     val |= FIELD_PREP(PLL_DATA_RATE_CLK_DIV_MASK,
> > +                       PLL_DATA_RATE_CLK_DIV_HBR2);
> > +     cdns_phy_reg_write(cdns_phy, PHY_HDP_CLK_CTL, val);
> > +
> > +     /* Common control module control and diagnostic registers */
> > +     val = cdns_phy_reg_read(cdns_phy, CMN_CDIAG_REFCLK_CTRL);
> > +     val &= ~DIG_REF_CLK_DIV_SCALER_MASK;
> > +     val |= FIELD_PREP(DIG_REF_CLK_DIV_SCALER_MASK,
> p_ctrl_table->ref_clk_divider_scaler);
> > +     val |= REFCLK_TERMINATION_EN_OVERRIDE_EN |
> REFCLK_TERMINATION_EN_OVERRIDE;
> > +     cdns_phy_reg_write(cdns_phy, CMN_CDIAG_REFCLK_CTRL, val);
> > +
> > +     /* High speed clock used */
> > +     val = cdns_phy_reg_read(cdns_phy, CMN_DIAG_HSCLK_SEL);
> > +     val &= ~(HSCLK1_SEL_MASK | HSCLK0_SEL_MASK);
> > +     val |= FIELD_PREP(HSCLK1_SEL_MASK,
> (p_ctrl_table->cmnda_hs_clk_1_sel >> 1));
> > +     val |= FIELD_PREP(HSCLK0_SEL_MASK,
> (p_ctrl_table->cmnda_hs_clk_0_sel >> 1));
> > +     cdns_phy_reg_write(cdns_phy, CMN_DIAG_HSCLK_SEL, val);
> > +
> > +     for (k = 0; k < num_lanes; k++) {
> > +             val = cdns_phy_reg_read(cdns_phy,
> (XCVR_DIAG_HSCLK_SEL | (k << 9)));
> > +             val &= ~HSCLK_SEL_MODE3_MASK;
> > +             val |= FIELD_PREP(HSCLK_SEL_MODE3_MASK,
> > +
> (p_ctrl_table->cmnda_hs_clk_0_sel >> 1));
> > +             cdns_phy_reg_write(cdns_phy, (XCVR_DIAG_HSCLK_SEL |
> (k << 9)), val);
> > +     }
> > +
> > +     /* PLL 0 control state machine registers */
> > +     val = p_ctrl_table->vco_ring_select << 12;
> > +     cdns_phy_reg_write(cdns_phy, CMN_PLLSM0_USER_DEF_CTRL,
> val);
> > +
> > +     if (pclk_in) {
> > +             val = 0x30a0;
> > +     } else {
> > +             val = cdns_phy_reg_read(cdns_phy,
> CMN_PLL0_VCOCAL_START);
> > +             val &= ~VCO_CALIB_CODE_START_POINT_VAL_MASK;
> > +             val |=
> FIELD_PREP(VCO_CALIB_CODE_START_POINT_VAL_MASK,
> > +                               p_pll_table->vco_cal_code);
> > +     }
> > +     cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_START, val);
> > +
> > +     cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_INIT_TMR,
> 0x0064);
> > +     cdns_phy_reg_write(cdns_phy, CMN_PLL0_VCOCAL_ITER_TMR,
> 0x000a);
> > +
> > +     /* Common functions control and diagnostics registers */
> > +     val = p_ctrl_table->cmnda_pll0_hs_sym_div_sel << 8;
> > +     val |= p_ctrl_table->cmnda_pll0_ip_div;
> > +     cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_INCLK_CTRL, val);
> > +
> > +     cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_OVRD, 0x0000);
> > +
> > +     val = p_ctrl_table->cmnda_pll0_fb_div_high;
> > +     val |= PLL_FEEDBACK_DIV_HI_OVERRIDE_EN;
> > +     cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBH_OVRD, val);
> > +
> > +     val = p_ctrl_table->cmnda_pll0_fb_div_low;
> > +     val |= PLL_FEEDBACK_DIV_LO_OVERRIDE_EN;
> > +     cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_FBL_OVRD, val);
> > +
> > +     if (!pclk_in) {
> > +             val = p_ctrl_table->cmnda_pll0_pxdiv_low;
> > +             cdns_phy_reg_write(cdns_phy,
> CMN_DIAG_PLL0_PXL_DIVL,
> > + val);
> > +
> > +             val = p_ctrl_table->cmnda_pll0_pxdiv_high;
> > +             val |= PLL_PCLK_DIV_EN;
> > +             cdns_phy_reg_write(cdns_phy,
> CMN_DIAG_PLL0_PXL_DIVH, val);
> > +     }
> > +
> > +     val = p_pll_table->volt_to_current_coarse;
> > +     val |= (p_pll_table->volt_to_current) << 4;
> > +     cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_V2I_TUNE, val);
> > +
> > +     val = p_pll_table->charge_pump_gain;
> > +     cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_CP_TUNE, val);
> > +
> > +     cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_LF_PROG,
> 0x0008);
> > +
> > +     val = p_pll_table->pmos_ctrl;
> > +     val |= (p_pll_table->ndac_ctrl) << 8;
> > +     cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE1,
> val);
> > +
> > +     val = p_pll_table->ptat_ndac_ctrl;
> > +     cdns_phy_reg_write(cdns_phy, CMN_DIAG_PLL0_PTATIS_TUNE2,
> val);
> > +
> > +     if (pclk_in)
> > +             cdns_phy_reg_write(cdns_phy,
> CMN_DIAG_PLL0_TEST_MODE, 0x0022);
> > +     else
> > +             cdns_phy_reg_write(cdns_phy,
> CMN_DIAG_PLL0_TEST_MODE,
> > + 0x0020);
> > +
> > +     cdns_phy_reg_write(cdns_phy, CMN_PSM_CLK_CTRL, 0x0016);
> > +
> > +     /* Transceiver control and diagnostic registers */
> > +     for (k = 0; k < num_lanes; k++) {
> > +             val = cdns_phy_reg_read(cdns_phy,
> (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
> > +             val &= ~DPLL_CLK_SEL_MODE3;
> > +             cdns_phy_reg_write(cdns_phy,
> (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val);
> > +     }
> > +
> > +     for (k = 0; k < num_lanes; k++) {
> > +             val = cdns_phy_reg_read(cdns_phy, (TX_DIAG_TX_CTRL |
> (k << 9)));
> > +             val &= ~TX_IF_SUBRATE_MODE3_MASK;
> > +             val |= FIELD_PREP(TX_IF_SUBRATE_MODE3_MASK,
> > +
> (p_ctrl_table->hsclk_div_tx_sub_rate >> 1));
> > +             cdns_phy_reg_write(cdns_phy, (TX_DIAG_TX_CTRL | (k <<
> 9)), val);
> > +     }
> > +
> > +     val = cdns_phy_reg_read(cdns_phy, PHY_PMA_CMN_CTRL1);
> > +     val &= ~CMA_REF_CLK_SEL_MASK;
> > +     /*
> > +      * single ended reference clock (val |= 0x0030);
> > +      * differential clock  (val |= 0x0000);
> > +      * for differential clock on the refclk_p and
> > +      * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1
> > +      * cdns_phy_reg_write(cdns_phy, CMN_DIAG_ACYA, 0x0100);
> > +      */
> > +     val |= FIELD_PREP(CMA_REF_CLK_SEL_MASK, 3);
> > +     cdns_phy_reg_write(cdns_phy, PHY_PMA_CMN_CTRL1, val);
> > +
> > +     /* Deassert PHY reset */
> > +     cdns_phy_reg_write(cdns_phy, PHY_ISO_CMN_CTRL, 0x0001);
> > +     cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0003);
> > +
> > +     /* Power state machine registers */
> > +     for (k = 0; k < num_lanes; k++)
> > +             cdns_phy_reg_write(cdns_phy, XCVR_PSM_RCTRL | (k <<
> 9),
> > + 0xfefc);
> > +
> > +     /* Assert cmn_macro_pwr_en */
> > +     cdns_phy_reg_write(cdns_phy, PHY_PMA_ISO_CMN_CTRL, 0x0013);
> > +
> > +     /* wait for cmn_macro_pwr_en_ack */
> > +     ret = wait_for_ack(cdns_phy, PHY_PMA_ISO_CMN_CTRL,
> CMN_MACRO_PWR_EN_ACK,
> > +                        "MA output macro power up failed");
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     /* wait for cmn_ready */
> > +     ret = wait_for_ack(cdns_phy, PHY_PMA_CMN_CTRL1, CMN_READY,
> > +                        "PMA output ready failed");
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     for (k = 0; k < num_lanes; k++) {
> > +             cdns_phy_reg_write(cdns_phy, TX_PSC_A0 | (k << 9),
> 0x6791);
> > +             cdns_phy_reg_write(cdns_phy, TX_PSC_A1 | (k << 9),
> 0x6790);
> > +             cdns_phy_reg_write(cdns_phy, TX_PSC_A2 | (k << 9),
> 0x0090);
> > +             cdns_phy_reg_write(cdns_phy, TX_PSC_A3 | (k << 9),
> > + 0x0090);
> > +
> > +             val = cdns_phy_reg_read(cdns_phy, RX_PSC_CAL | (k <<
> 9));
> > +             val &= 0xffbb;
> > +             cdns_phy_reg_write(cdns_phy, RX_PSC_CAL | (k << 9),
> > + val);
> > +
> > +             val = cdns_phy_reg_read(cdns_phy, RX_PSC_A0 | (k << 9));
> > +             val &= 0xffbb;
> > +             cdns_phy_reg_write(cdns_phy, RX_PSC_A0 | (k << 9), val);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int hdptx_hdmi_phy_cfg(struct cdns_hdptx_hdmi_phy *cdns_phy,
> > +u32 rate) {
> > +     const struct hdptx_hdmi_ctrl *p_ctrl_table;
> > +     const struct hdptx_hdmi_pll_tuning *p_pll_table;
> > +     const u32 refclk_freq_khz = cdns_phy->ref_clk_rate / 1000;
> > +     const bool pclk_in = false;
> > +     u32 pixel_freq = rate;
> > +     u32 vco_freq, char_freq;
> > +     u32 div_total, feedback_factor;
> > +     u32 i;
> > +
> > +     feedback_factor = hdptx_hdmi_feedback_factor(cdns_phy);
> > +
> > +     char_freq = pixel_freq * feedback_factor / 1000;
> > +
> > +     dev_dbg(cdns_phy->dev,
> > +             "Pixel clock: (%d KHz), character clock: %d, bpc is
> (%0d-bit)\n",
> > +             pixel_freq, char_freq, cdns_phy->bpc);
> > +
> > +     /* Get right row from the ctrl_table table.
> > +      * Check if 'pixel_freq_khz' value matches the PIXEL_CLK_FREQ
> column.
> > +      * Consider only the rows with FEEDBACK_FACTOR column
> matching feedback_factor.
> > +      */
> > +     for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++) {
> > +             if (feedback_factor ==
> pixel_clk_output_ctrl_table[i].feedback_factor &&
> > +                 pixel_freq ==
> pixel_clk_output_ctrl_table[i].pixel_clk_freq_min) {
> > +                     p_ctrl_table = &pixel_clk_output_ctrl_table[i];
> > +                     break;
> > +             }
> > +     }
> > +     if (i == ARRAY_SIZE(pixel_clk_output_ctrl_table)) {
> > +             dev_warn(cdns_phy->dev,
> > +                      "Pixel clk (%d KHz) not supported, bpc is
> (%0d-bit)\n",
> > +                      pixel_freq, cdns_phy->bpc);
> > +             return -EINVAL;
> > +     }
> > +
> > +     div_total = p_ctrl_table->pll_fb_div_total;
> > +     vco_freq = refclk_freq_khz * div_total /
> > + p_ctrl_table->cmnda_pll0_ip_div;
> > +
> > +     /* Get right row from the pixel_clk_output_pll_table table.
> > +      * Check if vco_freq_khz and feedback_div_total
> > +      * column matching with pixel_clk_output_pll_table.
> > +      */
> > +     for (i = 0; i < ARRAY_SIZE(pixel_clk_output_pll_table); i++) {
> > +             if (vco_freq == pixel_clk_output_pll_table[i].vco_freq_min
> &&
> > +                 div_total ==
> pixel_clk_output_pll_table[i].feedback_div_total) {
> > +                     p_pll_table = &pixel_clk_output_pll_table[i];
> > +                     break;
> > +             }
> > +     }
> > +     if (i == ARRAY_SIZE(pixel_clk_output_pll_table)) {
> > +             dev_warn(cdns_phy->dev, "VCO (%d KHz) not supported\n",
> vco_freq);
> > +             return -EINVAL;
> > +     }
> > +     dev_dbg(cdns_phy->dev, "VCO frequency is (%d KHz)\n", vco_freq);
> > +
> > +     return hdptx_hdmi_phy_config(cdns_phy, p_ctrl_table,
> > +p_pll_table, pclk_in); }
> > +
> > +static int hdptx_hdmi_phy_power_up(struct cdns_hdptx_hdmi_phy
> > +*cdns_phy) {
> > +     int ret = 0;
> > +
> > +     /* set Power State to A2 */
> > +     cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL,
> POWER_STATE_A2);
> > +
> > +     cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_0, 1);
> > +     cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_1, 1);
> > +     cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_2, 1);
> > +     cdns_phy_reg_write(cdns_phy, TX_DIAG_ACYA_3, 1);
> > +
> > +     ret = wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL,
> POWER_STATE_A2_ACK,
> > +                        "Wait A2 Ack failed");
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     /* Power up ARC */
> > +     hdptx_hdmi_arc_config(cdns_phy);
> > +
> > +     /* Configure PHY in A0 mode (PHY must be in the A0 power
> > +      * state in order to transmit data)
> > +      */
> > +     cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL,
> POWER_STATE_A0);
> > +
> > +     return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL,
> POWER_STATE_A0_ACK,
> > +                         "Wait A0 Ack failed"); }
> > +
> > +static int hdptx_hdmi_phy_power_down(struct cdns_hdptx_hdmi_phy
> > +*cdns_phy) {
> > +     u32 val;
> > +
> > +     val = cdns_phy_reg_read(cdns_phy, PHY_HDP_MODE_CTRL);
> > +     val &= ~(POWER_STATE_A0 | POWER_STATE_A1 |
> POWER_STATE_A2 | POWER_STATE_A3);
> > +     /* PHY_DP_MODE_CTL set to A3 power state */
> > +     cdns_phy_reg_write(cdns_phy, PHY_HDP_MODE_CTRL, val |
> > + POWER_STATE_A3);
> > +
> > +     return wait_for_ack(cdns_phy, PHY_HDP_MODE_CTRL,
> POWER_STATE_A3_ACK,
> > +                         "Wait A3 Ack failed"); }
> > +
> > +static int cdns_hdptx_hdmi_phy_on(struct phy *phy) {
> > +     struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
> > +
> > +     return hdptx_hdmi_phy_power_up(cdns_phy);
> > +}
> > +
> > +static int cdns_hdptx_hdmi_phy_off(struct phy *phy) {
> > +     struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
> > +
> > +     hdptx_hdmi_phy_power_down(cdns_phy);
> > +     return 0;
> > +}
> > +
> > +static int
> > +cdns_hdptx_hdmi_phy_valid(struct phy *phy, enum phy_mode mode,
> > +                       int submode, union phy_configure_opts *opts)
> {
> > +     u32 rate = opts->hdmi.pixel_clk_rate;
> > +     int i;
> > +
> > +     for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++)
> > +             if (rate ==
> pixel_clk_output_ctrl_table[i].pixel_clk_freq_min)
> > +                     return 0;
> > +
> > +     return -EINVAL;
> > +}
> > +
> > +static int cdns_hdptx_hdmi_phy_init(struct phy *phy) {
> > +     return 0;
> > +}
> > +
> > +static int cdns_hdptx_hdmi_configure(struct phy *phy,
> > +                                  union phy_configure_opts *opts)
> {
> > +     struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
> > +     int ret;
> > +
> > +     cdns_phy->pixel_clk_rate = opts->hdmi.pixel_clk_rate;
> > +     cdns_phy->color_space = opts->hdmi.color_space;
> > +     cdns_phy->bpc = opts->hdmi.bpc;
> > +
> > +     /* Check HDMI FW alive before HDMI PHY init */
> > +     ret = hdptx_phy_check_alive(cdns_phy);
> > +     if (!ret) {
> > +             dev_err(cdns_phy->dev, "NO HDMI FW running\n");
> > +             return -ENXIO;
> > +     }
> > +
> > +     /* Configure PHY */
> > +     if (hdptx_hdmi_phy_cfg(cdns_phy, cdns_phy->pixel_clk_rate) < 0) {
> > +             dev_err(cdns_phy->dev, "failed to set phy pclock\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = hdptx_hdmi_phy_power_up(cdns_phy);
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     hdptx_hdmi_phy_set_vswing(cdns_phy);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct phy_ops cdns_hdptx_hdmi_phy_ops = {
> > +     .init = cdns_hdptx_hdmi_phy_init,
> > +     .configure = cdns_hdptx_hdmi_configure,
> > +     .power_on = cdns_hdptx_hdmi_phy_on,
> > +     .power_off = cdns_hdptx_hdmi_phy_off,
> > +     .validate = cdns_hdptx_hdmi_phy_valid,
> > +     .owner = THIS_MODULE,
> > +};
> > +
> > +static int cdns_hdptx_hdmi_phy_probe(struct platform_device *pdev) {
> > +     struct cdns_hdptx_hdmi_phy *cdns_phy;
> > +     struct device *dev = &pdev->dev;
> > +     struct device_node *node = dev->of_node;
> > +     struct phy_provider *phy_provider;
> > +     struct resource *res;
> > +     struct phy *phy;
> > +     int ret;
> > +
> > +     cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
> > +     if (!cdns_phy)
> > +             return -ENOMEM;
> > +
> > +     dev_set_drvdata(dev, cdns_phy);
> > +     cdns_phy->dev = dev;
> > +     mutex_init(&cdns_phy->mbox_mutex);
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     if (!res)
> > +             return -ENODEV;
> > +     cdns_phy->regs = devm_ioremap(dev, res->start, resource_size(res));
> > +     if (IS_ERR(cdns_phy->regs))
> > +             return PTR_ERR(cdns_phy->regs);
> > +
> > +     phy = devm_phy_create(dev, node, &cdns_hdptx_hdmi_phy_ops);
> > +     if (IS_ERR(phy))
> > +             return PTR_ERR(phy);
> > +
> > +     phy->attrs.mode = PHY_MODE_HDMI;
> > +
> > +     cdns_phy->phy = phy;
> > +     phy_set_drvdata(phy, cdns_phy);
> > +
> > +     /* init base struct for access mhdp mailbox */
> > +     cdns_phy->base.dev = cdns_phy->dev;
> > +     cdns_phy->base.regs = cdns_phy->regs;
> > +     cdns_phy->base.mbox_mutex = &cdns_phy->mbox_mutex;
> > +
> > +     ret = hdptx_hdmi_clk_enable(cdns_phy);
> > +     if (ret) {
> > +             dev_err(dev, "Init clk fail\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     phy_provider = devm_of_phy_provider_register(dev,
> of_phy_simple_xlate);
> > +     if (IS_ERR(phy_provider)) {
> > +             ret = PTR_ERR(phy_provider);
> > +             goto clk_disable;
> > +     }
> > +
> > +     dev_dbg(dev, "probe success!\n");
> > +
> > +     return 0;
> > +
> > +clk_disable:
> > +     hdptx_hdmi_clk_disable(cdns_phy);
> > +
> > +     return -EINVAL;
> > +}
> > +
> > +static int cdns_hdptx_hdmi_phy_remove(struct platform_device *pdev) {
> > +     struct cdns_hdptx_hdmi_phy *cdns_phy =
> > +platform_get_drvdata(pdev);
> > +
> > +     hdptx_hdmi_clk_disable(cdns_phy);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct of_device_id cdns_hdptx_hdmi_phy_of_match[] = {
> > +     {.compatible = "fsl,imx8mq-hdmi-phy" },
> > +     { /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, cdns_hdptx_hdmi_phy_of_match);
> > +
> > +static struct platform_driver cdns_hdptx_hdmi_phy_driver = {
> > +     .probe = cdns_hdptx_hdmi_phy_probe,
> > +     .remove = cdns_hdptx_hdmi_phy_remove,
> > +     .driver = {
> > +             .name   = "cdns-hdptx-hdmi-phy",
> > +             .of_match_table = cdns_hdptx_hdmi_phy_of_match,
> > +     }
> > +};
> > +module_platform_driver(cdns_hdptx_hdmi_phy_driver);
> > +
> > +MODULE_AUTHOR("Sandor Yu <sandor.yu at nxp.com>");
> > +MODULE_DESCRIPTION("Cadence HDP-TX HDMI PHY driver");
> > +MODULE_LICENSE("GPL");
> >
>
>
> --
> TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht M?nchen, HRB 105018
> Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> http://www.tq-/
> group.com%2F&data=05%7C02%7CSandor.yu%40nxp.com%7C68abe9642bd9
> 4d237a4e08dc3200861a%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C
> 0%7C638440225041723926%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLj
> AwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%
> 7C&sdata=QVMdobK1UfMi1Pnjg5YLEvfLbPDjLm7xzIEV5Y97xEw%3D&reserve
> d=0
>



From xu.yang_2 at nxp.com  Tue Feb 20 23:53:28 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 07:53:28 +0000
Subject: [EXT] Re: [PATCH v6 1/9] dt-bindings: usb: usbmisc-imx: add
 fsl,imx8ulp-usbmisc compatible
In-Reply-To: <214c03b8-7c5d-45db-8f14-c144751dd819@linaro.org>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
 <214c03b8-7c5d-45db-8f14-c144751dd819@linaro.org>
Message-ID: <DU2PR04MB8822148AA2FE199AF64527738C572@DU2PR04MB8822.eurprd04.prod.outlook.com>


> 
> On 21/02/2024 15:58, Xu Yang wrote:
> > Add "fsl,imx8ulp-usbmisc" compatible.
> >
> > Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> >
> 
> Please fix your machine time, so this does not appear in +8 hours in the
> future. It unnecessarily goes to the top of my inbox, so I will ignore
> the patchset.

Thanks for reminder of the time offset. I'll resend the patchset later.

Thanks,
Xu Yang


From xu.yang_2 at nxp.com  Wed Feb 21 00:02:30 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 16:02:30 +0800
Subject: [RESEND v6 1/9] dt-bindings: usb: usbmisc-imx: add fsl,imx8ulp-usbmisc compatible
Message-ID: <20240221080238.1615536-1-xu.yang_2@nxp.com>

Add "fsl,imx8ulp-usbmisc" compatible.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v3:
 - new patch due to missed this little one
Changes in v4:
 - no changes
Changes in v5:
 - add Acked-by tag
Changes in v6:
 - no changes
---
 Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml b/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml
index 2d3589d284b2..0a6e7ac1b37e 100644
--- a/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml
+++ b/Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml
@@ -33,6 +33,7 @@ properties:
               - fsl,imx7ulp-usbmisc
               - fsl,imx8mm-usbmisc
               - fsl,imx8mn-usbmisc
+              - fsl,imx8ulp-usbmisc
           - const: fsl,imx7d-usbmisc
           - const: fsl,imx6q-usbmisc
       - items:
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 00:02:31 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 16:02:31 +0800
Subject: [RESEND v6 2/9] arm64: dts: imx8ulp: add usb nodes
In-Reply-To: <20240221080238.1615536-1-xu.yang_2@nxp.com>
References: <20240221080238.1615536-1-xu.yang_2@nxp.com>
Message-ID: <20240221080238.1615536-2-xu.yang_2@nxp.com>

Add USB nodes on i.MX8ULP platform which has 2 USB controllers.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - no changes
Changes in v3:
 - no changes
Changes in v4:
 - no changes
Changes in v5:
 - no changes
Changes in v6:
 - drop usbphy aliases
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 62 ++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index c4a0082f30d3..7da9461a5745 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -472,6 +472,68 @@ usdhc2: mmc at 298f0000 {
 				status = "disabled";
 			};
 
+			usbotg1: usb at 29900000 {
+				compatible = "fsl,imx8ulp-usb", "fsl,imx7ulp-usb", "fsl,imx6ul-usb";
+				reg = <0x29900000 0x200>;
+				interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&pcc4 IMX8ULP_CLK_USB0>;
+				power-domains = <&scmi_devpd IMX8ULP_PD_USB0>;
+				phys = <&usbphy1>;
+				fsl,usbmisc = <&usbmisc1 0>;
+				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x8>;
+				rx-burst-size-dword = <0x8>;
+				status = "disabled";
+			};
+
+			usbmisc1: usbmisc at 29900200 {
+				compatible = "fsl,imx8ulp-usbmisc", "fsl,imx7d-usbmisc",
+						"fsl,imx6q-usbmisc";
+				#index-cells = <1>;
+				reg = <0x29900200 0x200>;
+				status = "disabled";
+			};
+
+			usbphy1: usb-phy at 29910000 {
+				compatible = "fsl,imx8ulp-usbphy", "fsl,imx7ulp-usbphy";
+				reg = <0x29910000 0x10000>;
+				interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&pcc4 IMX8ULP_CLK_USB0_PHY>;
+				#phy-cells = <0>;
+				status = "disabled";
+			};
+
+			usbotg2: usb at 29920000 {
+				compatible = "fsl,imx8ulp-usb", "fsl,imx7ulp-usb", "fsl,imx6ul-usb";
+				reg = <0x29920000 0x200>;
+				interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&pcc4 IMX8ULP_CLK_USB1>;
+				power-domains = <&scmi_devpd IMX8ULP_PD_USDHC2_USB1>;
+				phys = <&usbphy2>;
+				fsl,usbmisc = <&usbmisc2 0>;
+				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x8>;
+				rx-burst-size-dword = <0x8>;
+				status = "disabled";
+			};
+
+			usbmisc2: usbmisc at 29920200 {
+				compatible = "fsl,imx8ulp-usbmisc", "fsl,imx7d-usbmisc",
+						"fsl,imx6q-usbmisc";
+				#index-cells = <1>;
+				reg = <0x29920200 0x200>;
+				status = "disabled";
+			};
+
+			usbphy2: usb-phy at 29930000 {
+				compatible = "fsl,imx8ulp-usbphy", "fsl,imx7ulp-usbphy";
+				reg = <0x29930000 0x10000>;
+				interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&pcc4 IMX8ULP_CLK_USB1_PHY>;
+				#phy-cells = <0>;
+				status = "disabled";
+			};
+
 			fec: ethernet at 29950000 {
 				compatible = "fsl,imx8ulp-fec", "fsl,imx6ul-fec", "fsl,imx6q-fec";
 				reg = <0x29950000 0x10000>;
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 00:02:32 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 16:02:32 +0800
Subject: [RESEND v6 3/9] arm64: dts: imx8ulp-evk: enable usb nodes and add ptn5150 nodes
In-Reply-To: <20240221080238.1615536-1-xu.yang_2@nxp.com>
References: <20240221080238.1615536-1-xu.yang_2@nxp.com>
Message-ID: <20240221080238.1615536-3-xu.yang_2@nxp.com>

Enable 2 USB nodes and add 2 PTN5150 nodes on i.MX8ULP evk board.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - fix format as suggusted by Fabio
 - add PTN5150 nodes
Changes in v3:
 - no changes
Changes in v4:
 - no changes
Changes in v5:
 - no changes
Changes in v6:
 - no changes
---
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts | 84 +++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index 69dd8e31027c..bf418af31039 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -133,6 +133,64 @@ pcal6408: gpio at 21 {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
+
+	ptn5150_1: typec at 1d {
+		compatible = "nxp,ptn5150";
+		reg = <0x1d>;
+		int-gpios = <&gpiof 3 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_typec1>;
+		status = "disabled";
+	};
+
+	ptn5150_2: typec at 3d {
+		compatible = "nxp,ptn5150";
+		reg = <0x3d>;
+		int-gpios = <&gpiof 5 IRQ_TYPE_EDGE_FALLING>;
+			pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_typec2>;
+		status = "disabled";
+	};
+};
+
+&usbotg1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb1>;
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	over-current-active-low;
+	status = "okay";
+};
+
+&usbphy1 {
+	fsl,tx-d-cal = <110>;
+	status = "okay";
+};
+
+&usbmisc1 {
+	status = "okay";
+};
+
+&usbotg2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb2>;
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	over-current-active-low;
+	status = "okay";
+};
+
+&usbphy2 {
+	fsl,tx-d-cal = <110>;
+	status = "okay";
+};
+
+&usbmisc2 {
+	status = "okay";
 };
 
 &usdhc0 {
@@ -224,6 +282,32 @@ MX8ULP_PAD_PTE13__LPI2C7_SDA	0x20
 		>;
 	};
 
+	pinctrl_typec1: typec1grp {
+		fsl,pins = <
+			MX8ULP_PAD_PTF3__PTF3           0x3
+		>;
+	};
+
+	pinctrl_typec2: typec2grp {
+		fsl,pins = <
+			MX8ULP_PAD_PTF5__PTF5           0x3
+		>;
+	};
+
+	pinctrl_usb1: usb1grp {
+		fsl,pins = <
+			MX8ULP_PAD_PTF2__USB0_ID	0x10003
+			MX8ULP_PAD_PTF4__USB0_OC	0x10003
+		>;
+	};
+
+	pinctrl_usb2: usb2grp {
+		fsl,pins = <
+			MX8ULP_PAD_PTD23__USB1_ID	0x10003
+			MX8ULP_PAD_PTF6__USB1_OC	0x10003
+		>;
+	};
+
 	pinctrl_usdhc0: usdhc0grp {
 		fsl,pins = <
 			MX8ULP_PAD_PTD1__SDHC0_CMD	0x3
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 00:02:33 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 16:02:33 +0800
Subject: [RESEND v6 4/9] dt-bindings: usb: add NXP ChipIdea USB2 Controller schema
In-Reply-To: <20240221080238.1615536-1-xu.yang_2@nxp.com>
References: <20240221080238.1615536-1-xu.yang_2@nxp.com>
Message-ID: <20240221080238.1615536-4-xu.yang_2@nxp.com>

As more and more NXP i.MX chips come out, it becomes harder to maintain
ci-hdrc-usb2.yaml if more stuffs like property restrictions are added to
this file. This will separate i.MX parts out of ci-hdrc-usb2.yaml and add
a new schema for NXP ChipIdea USB2 Controller.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v6:
 - new patch
---
 .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 75 +++++++++++++++++++
 1 file changed, 75 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml

diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
new file mode 100644
index 000000000000..2ec62f564bf5
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/ci-hdrc-usb2-imx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP USB2 ChipIdea USB controller
+
+maintainers:
+  - Xu Yang <xu.yang_2 at nxp.com>
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - fsl,imx27-usb
+      - items:
+          - enum:
+              - fsl,imx23-usb
+              - fsl,imx25-usb
+              - fsl,imx28-usb
+              - fsl,imx35-usb
+              - fsl,imx50-usb
+              - fsl,imx51-usb
+              - fsl,imx53-usb
+              - fsl,imx6q-usb
+              - fsl,imx6sl-usb
+              - fsl,imx6sx-usb
+              - fsl,imx6ul-usb
+              - fsl,imx7d-usb
+              - fsl,vf610-usb
+          - const: fsl,imx27-usb
+      - items:
+          - enum:
+              - fsl,imx8dxl-usb
+              - fsl,imx8ulp-usb
+          - const: fsl,imx7ulp-usb
+          - const: fsl,imx6ul-usb
+      - items:
+          - enum:
+              - fsl,imx8mm-usb
+              - fsl,imx8mn-usb
+          - const: fsl,imx7d-usb
+          - const: fsl,imx27-usb
+      - items:
+          - enum:
+              - fsl,imx6sll-usb
+              - fsl,imx7ulp-usb
+          - const: fsl,imx6ul-usb
+          - const: fsl,imx27-usb
+
+allOf:
+  - $ref: ci-hdrc-usb2.yaml#
+
+required:
+  - compatible
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/imx7d-clock.h>
+
+    usb at 30b10000 {
+        compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
+        reg = <0x30b10000 0x200>;
+        interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX7D_USB_CTRL_CLK>;
+        fsl,usbphy = <&usbphynop1>;
+        fsl,usbmisc = <&usbmisc1 0>;
+        phy-clkgate-delay-us = <400>;
+    };
+
+...
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 00:02:34 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 16:02:34 +0800
Subject: [RESEND v6 5/9] dt-bindings: usb: ci-hdrc-usb2-imx: add restrictions for reg, interrupts, clock and clock-names properties
In-Reply-To: <20240221080238.1615536-1-xu.yang_2@nxp.com>
References: <20240221080238.1615536-1-xu.yang_2@nxp.com>
Message-ID: <20240221080238.1615536-5-xu.yang_2@nxp.com>

Add restrictions for reg, interrupts, clock and clock-names properties
for imx Socs.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v4:
 - new patch since v3's discussion
 - split the reg, interrupts, clock and clock-names properties into
   common part and device-specific
Changes in v5:
 - keep common property unchanged
 - make if-then more readable
 - remove non imx part
Changes in v6:
 - new patch based on ci-hdrc-usb2-imx.yaml
---
 .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
index 2ec62f564bf5..20bb048938ff 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
@@ -49,11 +49,63 @@ properties:
           - const: fsl,imx6ul-usb
           - const: fsl,imx27-usb
 
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
 allOf:
   - $ref: ci-hdrc-usb2.yaml#
 
+  # imx27 Soc needs three clocks
+  - if:
+      properties:
+        compatible:
+          const: fsl,imx27-usb
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: ipg
+            - const: ahb
+            - const: per
+    else:
+      # imx25 and imx35 Soc need three clocks
+      if:
+        properties:
+          compatible:
+            contains:
+              enum:
+                - fsl,imx25-usb
+                - fsl,imx35-usb
+      then:
+        properties:
+          clocks:
+            minItems: 3
+            maxItems: 3
+          clock-names:
+            items:
+              - const: ipg
+              - const: ahb
+              - const: per
+      else:
+        # other imx Socs only need one clock
+        properties:
+          clocks:
+            minItems: 1
+            maxItems: 1
+          clock-names:
+            minItems: 1
+            maxItems: 1
+
 required:
   - compatible
+  - reg
+  - interrupts
 
 unevaluatedProperties: false
 
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 00:02:35 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 16:02:35 +0800
Subject: [RESEND v6 6/9] dt-bindings: usb: ci-hdrc-usb2-imx: add compatible and clock-names restriction for imx93
In-Reply-To: <20240221080238.1615536-1-xu.yang_2@nxp.com>
References: <20240221080238.1615536-1-xu.yang_2@nxp.com>
Message-ID: <20240221080238.1615536-6-xu.yang_2@nxp.com>

The i.MX93 needs a wakup clock to work properly. This will add compatible
and restriction for i.MX93 platform.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - no changes
Changes in v3:
 - add clocks restriction
Changes in v4:
 - use 'contains' rather 'items'
Changes in v5:
 - rename clock name
Changes in v6:
 - new patch based on ci-hdrc-usb2-imx.yaml
---
 .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 34 ++++++++++++++-----
 .../devicetree/bindings/usb/ci-hdrc-usb2.yaml |  1 +
 2 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
index 20bb048938ff..d509cfbcf0d5 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
@@ -40,6 +40,7 @@ properties:
           - enum:
               - fsl,imx8mm-usb
               - fsl,imx8mn-usb
+              - fsl,imx93-usb
           - const: fsl,imx7d-usb
           - const: fsl,imx27-usb
       - items:
@@ -93,14 +94,31 @@ allOf:
               - const: ahb
               - const: per
       else:
-        # other imx Socs only need one clock
-        properties:
-          clocks:
-            minItems: 1
-            maxItems: 1
-          clock-names:
-            minItems: 1
-            maxItems: 1
+        # imx93 Soc needs two clocks
+        if:
+          properties:
+            compatible:
+              contains:
+                enum:
+                  - fsl,imx93-usb
+        then:
+          properties:
+            clocks:
+              minItems: 2
+              maxItems: 2
+            clock-names:
+              items:
+                - const: usb_ctrl_root
+                - const: usb_wakeup
+        else:
+          # other imx Socs only need one clock
+          properties:
+            clocks:
+              minItems: 1
+              maxItems: 1
+            clock-names:
+              minItems: 1
+              maxItems: 1
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
index 3b56e0edb1c6..ff826414bcb2 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
@@ -57,6 +57,7 @@ properties:
           - enum:
               - fsl,imx8mm-usb
               - fsl,imx8mn-usb
+              - fsl,imx93-usb
           - const: fsl,imx7d-usb
           - const: fsl,imx27-usb
       - items:
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 00:02:36 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 16:02:36 +0800
Subject: [RESEND v6 7/9] arm64: dts: imx93: add usb nodes
In-Reply-To: <20240221080238.1615536-1-xu.yang_2@nxp.com>
References: <20240221080238.1615536-1-xu.yang_2@nxp.com>
Message-ID: <20240221080238.1615536-7-xu.yang_2@nxp.com>

There are 2 USB controllers on i.MX93. Add them.

Acked-by: Alexander Stein <alexander.stein at ew.tq-group.com>
Tested-by: Alexander Stein <alexander.stein at ew.tq-group.com> # TQMa9352LA/CA
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - fix format as suggested by Alexander
 - change compatible from fsl,imx8mm-usb to fsl,imx93-usb
Changes in v3:
 - replace deprecated fsl,usbphy with phys as suggested by Alexander
 - reorder nodes
Changes in v4:
 - fix the alignment
Changes in v5:
 - rename usb_wakeup_clk to usb_wakeup
Changes in v6:
 - rename usb_ctrl_root_clk to usb_ctrl_root
---
 arch/arm64/boot/dts/freescale/imx93.dtsi | 58 ++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
index 8f2e7c42ad6e..4a7efccb4f67 100644
--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -183,6 +183,20 @@ mqs2: mqs2 {
 		status = "disabled";
 	};
 
+	usbphynop1: usbphynop1 {
+		compatible = "usb-nop-xceiv";
+		#phy-cells = <0>;
+		clocks = <&clk IMX93_CLK_USB_PHY_BURUNIN>;
+		clock-names = "main_clk";
+	};
+
+	usbphynop2: usbphynop2 {
+		compatible = "usb-nop-xceiv";
+		#phy-cells = <0>;
+		clocks = <&clk IMX93_CLK_USB_PHY_BURUNIN>;
+		clock-names = "main_clk";
+	};
+
 	soc at 0 {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -1167,6 +1181,50 @@ media_blk_ctrl: system-controller at 4ac10000 {
 			status = "disabled";
 		};
 
+		usbotg1: usb at 4c100000 {
+			compatible = "fsl,imx93-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+			reg = <0x4c100000 0x200>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX93_CLK_USB_CONTROLLER_GATE>,
+				 <&clk IMX93_CLK_HSIO_32K_GATE>;
+			clock-names = "usb_ctrl_root", "usb_wakeup";
+			assigned-clocks = <&clk IMX93_CLK_HSIO>;
+			assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
+			assigned-clock-rates = <133000000>;
+			phys = <&usbphynop1>;
+			fsl,usbmisc = <&usbmisc1 0>;
+			status = "disabled";
+		};
+
+		usbmisc1: usbmisc at 4c100200 {
+			compatible = "fsl,imx8mm-usbmisc", "fsl,imx7d-usbmisc",
+				     "fsl,imx6q-usbmisc";
+			reg = <0x4c100200 0x200>;
+			#index-cells = <1>;
+		};
+
+		usbotg2: usb at 4c200000 {
+			compatible = "fsl,imx93-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+			reg = <0x4c200000 0x200>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX93_CLK_USB_CONTROLLER_GATE>,
+				 <&clk IMX93_CLK_HSIO_32K_GATE>;
+			clock-names = "usb_ctrl_root", "usb_wakeup";
+			assigned-clocks = <&clk IMX93_CLK_HSIO>;
+			assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
+			assigned-clock-rates = <133000000>;
+			phys = <&usbphynop2>;
+			fsl,usbmisc = <&usbmisc2 0>;
+			status = "disabled";
+		};
+
+		usbmisc2: usbmisc at 4c200200 {
+			compatible = "fsl,imx8mm-usbmisc", "fsl,imx7d-usbmisc",
+				     "fsl,imx6q-usbmisc";
+			reg = <0x4c200200 0x200>;
+			#index-cells = <1>;
+		};
+
 		ddr-pmu at 4e300dc0 {
 			compatible = "fsl,imx93-ddr-pmu";
 			reg = <0x4e300dc0 0x200>;
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 00:02:37 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 16:02:37 +0800
Subject: [RESEND v6 8/9] arm64: dts: imx93-11x11-evk: enable usb and typec nodes
In-Reply-To: <20240221080238.1615536-1-xu.yang_2@nxp.com>
References: <20240221080238.1615536-1-xu.yang_2@nxp.com>
Message-ID: <20240221080238.1615536-8-xu.yang_2@nxp.com>

There are 2 Type-C ports and 2 USB controllers on i.MX93. Enable them.

Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v2:
 - remove status property in ptn5110 nodes
 - fix dt-schema warnings
Changes in v3:
 - no changes
Changes in v4:
 - no changes
Changes in v5:
 - no changes
Changes in v6:
 - no changes
---
 .../boot/dts/freescale/imx93-11x11-evk.dts    | 118 ++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
index 9921ea13ab48..ec4cb50445fc 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/usb/pd.h>
 #include "imx93.dtsi"
 
 / {
@@ -104,6 +105,80 @@ &mu2 {
 	status = "okay";
 };
 
+&lpi2c3 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&pinctrl_lpi2c3>;
+	pinctrl-1 = <&pinctrl_lpi2c3>;
+	status = "okay";
+
+	ptn5110: tcpc at 50 {
+		compatible = "nxp,ptn5110";
+		reg = <0x50>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+
+		typec1_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			power-role = "dual";
+			data-role = "dual";
+			try-power-role = "sink";
+			source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+			sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
+				     PDO_VAR(5000, 20000, 3000)>;
+			op-sink-microwatt = <15000000>;
+			self-powered;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					typec1_dr_sw: endpoint {
+						remote-endpoint = <&usb1_drd_sw>;
+					};
+				};
+			};
+		};
+	};
+
+	ptn5110_2: tcpc at 51 {
+		compatible = "nxp,ptn5110";
+		reg = <0x51>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+
+		typec2_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			power-role = "dual";
+			data-role = "dual";
+			try-power-role = "sink";
+			source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+			sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
+				     PDO_VAR(5000, 20000, 3000)>;
+			op-sink-microwatt = <15000000>;
+			self-powered;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					typec2_dr_sw: endpoint {
+						remote-endpoint = <&usb2_drd_sw>;
+					};
+				};
+			};
+		};
+	};
+};
+
 &eqos {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_eqos>;
@@ -156,6 +231,42 @@ &lpuart5 {
 	status = "okay";
 };
 
+&usbotg1 {
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	usb-role-switch;
+	disable-over-current;
+	samsung,picophy-pre-emp-curr-control = <3>;
+	samsung,picophy-dc-vol-level-adjust = <7>;
+	status = "okay";
+
+	port {
+		usb1_drd_sw: endpoint {
+			remote-endpoint = <&typec1_dr_sw>;
+		};
+	};
+};
+
+&usbotg2 {
+	dr_mode = "otg";
+	hnp-disable;
+	srp-disable;
+	adp-disable;
+	usb-role-switch;
+	disable-over-current;
+	samsung,picophy-pre-emp-curr-control = <3>;
+	samsung,picophy-dc-vol-level-adjust = <7>;
+	status = "okay";
+
+	port {
+		usb2_drd_sw: endpoint {
+			remote-endpoint = <&typec2_dr_sw>;
+		};
+	};
+};
+
 &usdhc1 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz";
 	pinctrl-0 = <&pinctrl_usdhc1>;
@@ -222,6 +333,13 @@ MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL	0x57e
 		>;
 	};
 
+	pinctrl_lpi2c3: lpi2c3grp {
+		fsl,pins = <
+			MX93_PAD_GPIO_IO28__LPI2C3_SDA			0x40000b9e
+			MX93_PAD_GPIO_IO29__LPI2C3_SCL			0x40000b9e
+		>;
+	};
+
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
 			MX93_PAD_UART1_RXD__LPUART1_RX			0x31e
-- 
2.34.1



From xu.yang_2 at nxp.com  Wed Feb 21 00:02:38 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Wed, 21 Feb 2024 16:02:38 +0800
Subject: [RESEND v6 9/9] usb: chipidea: ci_hdrc_imx: align usb wakeup clock name with dt-bindings
In-Reply-To: <20240221080238.1615536-1-xu.yang_2@nxp.com>
References: <20240221080238.1615536-1-xu.yang_2@nxp.com>
Message-ID: <20240221080238.1615536-9-xu.yang_2@nxp.com>

The dt-bindings is going to use "usb_wakeup" as wakup clock name. This will
align the change with dt-bindings.

Acked-by: Peter Chen <peter.chen at kernel.org>
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>

---
Changes in v5:
 - new patch
Changes in v6:
 - add Acked-by tag
---
 drivers/usb/chipidea/ci_hdrc_imx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index ae9a6a17ec6e..a17b6d619305 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -212,7 +212,7 @@ static int imx_get_clks(struct device *dev)
 		/* Get wakeup clock. Not all of the platforms need to
 		 * handle this clock. So make it optional.
 		 */
-		data->clk_wakeup = devm_clk_get_optional(dev, "usb_wakeup_clk");
+		data->clk_wakeup = devm_clk_get_optional(dev, "usb_wakeup");
 		if (IS_ERR(data->clk_wakeup))
 			ret = dev_err_probe(dev, PTR_ERR(data->clk_wakeup),
 					"Failed to get wakeup clk\n");
-- 
2.34.1



From zajec5 at gmail.com  Wed Feb 21 00:12:38 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 21 Feb 2024 09:12:38 +0100
Subject: [PATCH] dt-bindings: net: wireless: mt76: allow all 4 interrupts for MT7981
Message-ID: <20240221081238.24775-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

MT7981 (Filogic 820) is a low cost version of MT7986 (Filogic 830) with
a similar wireless controller that also supports four interrupts.

Cc: Peter Chiu <chui-hao.chiu at mediatek.com>
Cc: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../devicetree/bindings/net/wireless/mediatek,mt76.yaml          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
index 0c6835db397f..eabceb849537 100644
--- a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
+++ b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
@@ -226,6 +226,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - mediatek,mt7981-wmac
               - mediatek,mt7986-wmac
     then:
       properties:
-- 
2.35.3



From yangyicong at huawei.com  Wed Feb 21 00:13:50 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Wed, 21 Feb 2024 16:13:50 +0800
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <ZcYtDHLr6NQ-BFbx@x1>
References: <20240208032518.25830-1-yangyicong@huawei.com>
 <ZcYtDHLr6NQ-BFbx@x1>
Message-ID: <3942d4f7-7282-6fcf-90d5-8f864e43dd19@huawei.com>

Hi Arnaldo,

Thanks for the comments.

On 2024/2/9 21:47, Arnaldo Carvalho de Melo wrote:
> On Thu, Feb 08, 2024 at 11:25:18AM +0800, Yicong Yang wrote:
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
>> throughput and latency of PCIe traffic. With the support of PCIe PMU
>> we can enable the perf iostat mode.
[...]
>> +static void hisi_pcie_root_ports_add(u16 sicl_id, u16 core_id, u8 target_bus)
>> +{
>> +	const char *sysfs = sysfs__mountpoint();
>> +	struct hisi_pcie_root_port *rp;
>> +	struct dirent *dent;
>> +	char path[PATH_MAX];
>> +	u8 bus, dev, fn;
>> +	u32 domain;
>> +	DIR *dir;
>> +	int ret;
>> +
>> +	snprintf(path, PATH_MAX, "%s/%s", sysfs, PCI_ROOT_BUS_DEVICES_PATH);
>> +	dir = opendir(path);
>> +	if (!dir)
>> +		return;
>> +
>> +	/* Scan the PCI root bus to find the match root port on @target_bus */
>> +	while ((dent = readdir(dir))) {
>> +		ret = sscanf(dent->d_name, PCI_DEVICE_NAME_PATTERN,
>> +			     &domain, &bus, &dev, &fn);
>> +		if (ret != 4 || bus != target_bus)
>> +			continue;
>> +
>> +		rp = zalloc(sizeof(*rp));
>> +		if (!rp)
>> +			continue;
> 
> shouldn't it emit some pr_debug message? Like you did with that
> pr_debug3() info message below.
> 

ok will complete the debug messages here and below. I didn't add it here may because
I didn't met the issue here when debugging..

>> +
>> +		rp->selected = false;
>> +		rp->sicl_id = sicl_id;
>> +		rp->core_id = core_id;
>> +		rp->domain = domain;
>> +		rp->bus = bus;
>> +		rp->dev = dev;
>> +		rp->fn = fn;
>> +
>> +		hisi_pcie_init_root_port_mask(rp);
>> +
>> +		list_add(&rp->list, &hisi_pcie_root_ports_list);
>> +		hisi_pcie_root_ports_num++;
>> +
>> +		pr_debug3("Found root port %s\n", dent->d_name);
>> +	}
>> +
>> +	closedir(dir);
>> +}
>> +
>> +/* Scan the PMUs and build the mapping of the Root Ports to the PMU */
>> +static int hisi_pcie_root_ports_init(void)
>> +{
>> +	char event_source[PATH_MAX], bus_path[PATH_MAX];
>> +	unsigned long long bus;
>> +	u16 sicl_id, core_id;
>> +	struct dirent *dent;
>> +	DIR *dir;
>> +
>> +	perf_pmu__event_source_devices_scnprintf(event_source, sizeof(event_source));
>> +	dir = opendir(event_source);
>> +	if (!dir)
>> +		return -ENOENT;
> 
> Is this the only possibility? I.e. if a non root user tries this and the
> file is there, shouldn't we inform that root permission is needed? Or
> any other access mechanism that may be used.
> 
> For instance, in perf we have things like kernel.perf_event_paranoid,
> capabilities, etc.
> 

Thanks for the information. Will have a check on it, didn't consider about the
permission things.

> Take a look at the evsel__open_strerror() function, to see how it tries
> to translate errors like the above to an informative message to help the
> user setup its system.
> 

Thanks for the hint. Will have a reference on that.

>> +
>> +	while ((dent = readdir(dir))) {
>> +		/*
>> +		 * This HiSilicon PCIe PMU will be named as:
>> +		 *   hisi_pcie<sicl_id>_core<core_id>
>> +		 */
>> +		if ((sscanf(dent->d_name, "hisi_pcie%hu_core%hu", &sicl_id, &core_id)) != 2)
>> +			continue;
>> +
>> +		/*
>> +		 * Driver will export the root port it can monitor through
>> +		 * the "bus" sysfs attribute.
>> +		 */
>> +		scnprintf(bus_path, sizeof(bus_path), "%s/hisi_pcie%hu_core%hu/bus",
>> +			  event_source, sicl_id, core_id);
>> +
>> +		/*
>> +		 * Per PCIe spec the bus should be 8bit, use unsigned long long
>> +		 * for the convience of the library function.
>> +		 */
>> +		if (filename__read_ull(bus_path, &bus))
> 
> Shouldn't we have a pr_debug3() here as well?
> 

will add.

>> +			continue;
> 
>> +
>> +		pr_debug3("Found pmu %s bus 0x%llx\n", dent->d_name, bus);
>> +
>> +		hisi_pcie_root_ports_add(sicl_id, core_id, (u8)bus);
>> +	}
>> +
>> +	closedir(dir);
>> +	return hisi_pcie_root_ports_num > 0 ? 0 : -ENOENT;
>> +}
>> +
>> +static void hisi_pcie_root_ports_free(void)
>> +{
>> +	struct hisi_pcie_root_port *rp, *tmp;
>> +
>> +	if (hisi_pcie_root_ports_num == 0)
>> +		return;
>> +
>> +	list_for_each_entry_safe(rp, tmp, &hisi_pcie_root_ports_list, list) {
>> +		list_del(&rp->list);
> 
> list_del_init()
> 

will use it.

>> +		zfree(&rp);
> 
> No need to use zfree here, its a local variable, not something that is
> in a data structure that may have some dangling connection somewhere and
> thus we better initialize to zero instead of reading random deleted
> memory.
> 

got it. Will use free() instead here.

>> +		hisi_pcie_root_ports_num--;
>> +	}
>> +}
>> +
>> +static int hisi_iostat_add_events(struct evlist *evl)
>> +{
>> +	struct hisi_pcie_root_port *rp;
>> +	struct evsel *evsel;
>> +	unsigned int i, j;
>> +	char *iostat_cmd;
>> +	int pos = 0;
>> +	int ret;
>> +
>> +	if (!hisi_pcie_root_ports_num)
>> +		return -ENOENT;
>> +
>> +	iostat_cmd = zalloc(PATH_MAX);
>> +	if (!iostat_cmd)
>> +		return -ENOMEM;
>> +
>> +	list_for_each_entry(rp, &hisi_pcie_root_ports_list, list) {
>> +		if (!rp->selected)
>> +			continue;
>> +
>> +		iostat_cmd[pos++] = '{';
>> +		for (j = 0; j < METRIC_TYPE_MAX; j++) {
>> +			pos += snprintf(iostat_cmd + pos, ARG_MAX - pos - 1,
>> +					hisi_iostat_cmd_template[j],
>> +					rp->sicl_id, rp->core_id, rp->mask);
>> +
>> +			if (j == METRIC_TYPE_MAX - 1)
>> +				iostat_cmd[pos++] = '}';
>> +			else
>> +				iostat_cmd[pos++] = ',';
>> +		}
>> +
>> +		ret = parse_event(evl, iostat_cmd);
>> +		if (ret)
> 
> pr_debug3()?
ok.

>> +			break;
>> +
>> +		i = 0;
>> +		evlist__for_each_entry_reverse(evl, evsel) {
>> +			if (i == METRIC_TYPE_MAX)
>> +				break;
>> +
>> +			evsel->priv = rp;
>> +			i++;
>> +		}
>> +
>> +		memset(iostat_cmd, 0, PATH_MAX);
>> +		pos = 0;
>> +	}
>> +
>> +	zfree(&iostat_cmd);
> 
> no need for zfree here, again its a local variable.
> 
>> +	return ret;
>> +}
>> +
>> +int iostat_prepare(struct evlist *evlist,
>> +		   struct perf_stat_config *config)
>> +{
>> +	if (evlist->core.nr_entries > 0) {
>> +		pr_warning("The -e and -M options are not supported."
>> +			   "All chosen events/metrics will be dropped\n");
>> +		evlist__delete(evlist);
>> +		evlist = evlist__new();
>> +		if (!evlist)
>> +			return -ENOMEM;
> 
> Can you explain how this works? Shouldn't we just bail out completely
> instead of creating an empty evlist?
> 

Here I just keep consistence with x86's implementation. For iostat only
iostat related evsels should be added and organized in certain order.

Warn the user and bail out completely with out continue may be another
choice.

Do you suggest to bail out here and also for x86 iostat for consistence?

>> +	}
>> +
>> +	config->metric_only = true;
>> +	config->aggr_mode = AGGR_GLOBAL;
>> +
>> +	return hisi_iostat_add_events(evlist);
>> +}
>> +
>> +static int hisi_pcie_root_ports_list_filter(const char *str)
>> +{
>> +	char *tok, *tmp, *copy = NULL;
>> +	u8 bus, dev, fn;
>> +	u32 domain;
>> +	int ret;
>> +
>> +	copy = strdup(str);
>> +	if (!copy)
>> +		return -ENOMEM;
>> +
>> +	for (tok = strtok_r(copy, ",", &tmp); tok; tok = strtok_r(NULL, ",", &tmp)) {
>> +		ret = sscanf(tok, PCI_DEVICE_NAME_PATTERN, &domain, &bus, &dev, &fn);
>> +		if (ret != 4) {
>> +			ret = -EINVAL;
>> +			break;
>> +		}
>> +
>> +		ret = hisi_pcie_root_ports_select_one(domain, bus, dev, fn);
>> +		if (ret)
>> +			break;
>> +	}
>> +
>> +	zfree(&copy);
> 
> No need for zfree()
> 

ok.

>> +	return ret;
>> +}
>> +
>> +int iostat_parse(const struct option *opt, const char *str, int unset __maybe_unused)
>> +{
>> +	struct perf_stat_config *config = (struct perf_stat_config *)opt->data;
>> +	int ret;
>> +
>> +	ret = hisi_pcie_root_ports_init();
>> +	if (!ret) {
>> +		config->iostat_run = true;
>> +
>> +		if (!str) {
>> +			iostat_mode = IOSTAT_RUN;
>> +			hisi_pcie_root_ports_select_all();
>> +		} else if (!strcmp(str, "list")) {
>> +			iostat_mode = IOSTAT_LIST;
>> +			hisi_pcie_root_ports_select_all();
>> +		} else {
>> +			iostat_mode = IOSTAT_RUN;
>> +			ret = hisi_pcie_root_ports_list_filter(str);
>> +		}
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static void hisi_pcie_root_port_show(FILE *output,
>> +				     const struct hisi_pcie_root_port * const rp)
>> +{
>> +	if (output && rp)
>> +		fprintf(output, "hisi_pcie%hu_core%hu<" PCI_DEVICE_NAME_PATTERN ">\n",
>> +			rp->sicl_id, rp->core_id, rp->domain, rp->bus, rp->dev, rp->fn);
> 
> Multi line if blocks should be enclosed in {}
> 

got it. will enclose it with {}.

>> +}
>> +
>> +void iostat_list(struct evlist *evlist __maybe_unused, struct perf_stat_config *config)
>> +{
>> +	struct hisi_pcie_root_port *rp = NULL;
>> +	struct evsel *evsel;
>> +
>> +	evlist__for_each_entry(evlist, evsel) {
> 
> Can you add a comment explaining this evsel->priv check? Probably we
> have multiple ports and some are shared with multiple evsels and we
> don't have a ports list, so we reuse the evsel list, etc.
> 
> Having a comment with the above info may help future reviewers?
> 

sure. will add comment here.

>> +		if (rp != evsel->priv) {
>> +			hisi_pcie_root_port_show(config->output, evsel->priv);
>> +			rp = evsel->priv;
>> +		}
>> +	}
>> +}
>> +
>> +void iostat_release(struct evlist *evlist)
>> +{
>> +	struct evsel *evsel;
>> +
>> +	evlist__for_each_entry(evlist, evsel)
>> +		evsel->priv = NULL;
>> +
> 
> But then here you zero out all the privs and still can iterate the list
> of ports in the following function:
> 
>> +	hisi_pcie_root_ports_free();
> 
> Why not iterate on hisi_pcie_root_ports_list in iostat_list()?
> 

I think you're right. For listing mode (`perf iostat list`) we don't need
to counting and adding evsels, so iterate hisi_pcie_root_ports_list will be
enough. Since no evsels added evlist will be empty.

>> +}
>> +
>> +void iostat_print_header_prefix(struct perf_stat_config *config)
>> +{
>> +	if (config->csv_output)
>> +		fputs("port,", config->output);
>> +	else if (config->interval)
>> +		fprintf(config->output, "#          time    port         ");
>> +	else
>> +		fprintf(config->output, "   port         ");
>> +}
>> +
>> +void iostat_print_metric(struct perf_stat_config *config, struct evsel *evsel,
>> +			 struct perf_stat_output_ctx *out)
>> +{
>> +	struct perf_counts_values *count;
>> +	const char *iostat_metric;
>> +	double iostat_value;
>> +
>> +	iostat_metric = hisi_iostat_metrics[evsel->core.idx % METRIC_TYPE_MAX];
>> +
>> +	/* We're using AGGR_GLOBAL so there's only one aggr counts aggr[0]. */
>> +	count = &evsel->stats->aggr[0].counts;
>> +
>> +	/* The counts has been scaled, we can use it directly. */
>> +	iostat_value = (double)count->val;
>> +
>> +	/*
>> +	 * Calculate the bandwidth in MiB since the PMU counts in DWord.
>> +	 * Display two digits after decimal point for better accuracy if the
>> +	 * value is non-zero.
>> +	 */
>> +	out->print_metric(config, out->ctx, NULL,
>> +			  iostat_value > 0 ? "%8.2f" : "%8.0f", iostat_metric,
>> +			  iostat_value * sizeof(uint32_t) / (1024 * 1024));
>> +}
>> +
>> +void iostat_prefix(struct evlist *evlist, struct perf_stat_config *config,
>> +		   char *prefix, struct timespec *ts)
>> +{
>> +	struct hisi_pcie_root_port *rp = evlist->selected->priv;
>> +
>> +	if (rp) {
>> +		if (ts)
>> +			sprintf(prefix, "%6lu.%09lu%s" PCI_DEVICE_NAME_PATTERN "%s",
> 
> Can you use scnprintf? and pass the size of prefix to iostat_prefix()?
> 

sure. will use scnprintf().

Thanks,
Yicong


From yangyicong at huawei.com  Wed Feb 21 00:16:30 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Wed, 21 Feb 2024 16:16:30 +0800
Subject: [PATCH v2] perf stat: Enable iostat mode for HiSilicon PCIe PMU
In-Reply-To: <20240208104642.000001ad@Huawei.com>
References: <20240208032518.25830-1-yangyicong@huawei.com>
 <20240208104642.000001ad@Huawei.com>
Message-ID: <b3c3a18d-2766-337c-c79e-d4ccfb2a1771@huawei.com>

On 2024/2/8 18:46, Jonathan Cameron wrote:
> On Thu, 8 Feb 2024 11:25:18 +0800
> Yicong Yang <yangyicong at huawei.com> wrote:
> 
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> Some HiSilicon platforms provide PCIe PMU devices for monitoring the
>> throughput and latency of PCIe traffic. With the support of PCIe PMU
>> we can enable the perf iostat mode.
>>
>> The HiSilicon PCIe PMU can support measuring the throughput of certain
>> TLP types and of certain root port. Totally 6 metrics are provided in
>> the unit of MB:
>>
>> - Inbound MWR: The memory write TLPs from the devices downstream the root port
>> - Inbound MRD: The memory read TLPs from the devices downstream the root port
>> - Inbound CPL: The completion TLPs from the devices downstream the root port
>> - Outbound MWR: The memory write TLPs from the CPU to the downstream devices
>> - Outbound MRD: The memory read TLPs from the CPU to the downstream devices
>> - Outbound CPL: The completions TLPs from the CPU to the downstream devices
>>
>> Since the PMU measures the throughput in DWords. So we need to calculate
>> the throughput in MB like:
>>   Count * 4B / 1024 / 1024
>>
>> Some of the display of the `perf iostat` will be like:
>> [root at localhost tmp]# ./perf iostat list
>> hisi_pcie0_core2<0000:40:00.0>
>> hisi_pcie2_core2<0000:5f:00.0>
>> hisi_pcie0_core1<0000:16:00.0>
>> hisi_pcie0_core1<0000:16:04.0>
>> [root at localhost tmp]# ./perf iostat --timeout 10000
>>
>>  Performance counter stats for 'system wide':
>>
>>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
>> 0000:40:00.0                    0                    0                    0                    0                    0                    0
>> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
>> 0000:16:00.0             16272.99               366.58                    0                15.09                    0             16156.85
>> 0000:16:04.0                    0                    0                    0                    0                    0                    0
>>
>>       10.008227512 seconds time elapsed
>>
>> [root at localhost tmp]# ./perf iostat 0000:16:00.0 -- fio -name=read
>> -numjobs=30 -filename=/dev/nvme0n1 -rw=rw -iodepth=128 -direct=1 -sync=0
>> -norandommap -group_reporting -runtime=10 -time_based -bs=64k
>>
>>  Performance counter stats for 'system wide':
>>
>>     port              Inbound MWR(MB)      Inbound MRD(MB)      Inbound CPL(MB)     Outbound MWR(MB)     Outbound MRD(MB)     Outbound CPL(MB)
>> 0000:40:00.0                    0                    0                    0                    0                    0                    0
>> 0000:5f:00.0                    0                    0                    0                    0                    0                    0
>> 0000:16:00.0             16314.30               371.22                    0                15.21                    0             16362.20
>> 0000:16:04.0                    0                    0                    0                    0                    0                    0
>>
>>       10.168561767 seconds time elapsed
>>
>>        0.465373000 seconds user
>>        1.952948000 seconds sys
>>
>> More information of the HiSilicon PCIe PMU can be found at
>> Documentation/admin-guide/perf/hisi-pcie-pmu.rst.
>>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> ---
> If you are doing a v3 for any reason, one trivial comment inline.
> 
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> 

Thanks.

>> +
>> +enum hisi_iostat_metric_type {
>> +	METRIC_IN_MWR,		/* Inbound Memory Write */
>> +	METRIC_IN_MRD,		/* Inbound Memory Read */
>> +	METRIC_IN_CPL,		/* Inbound Memory Completion */
>> +	METRIC_OUT_MWR,		/* Outbound Memory Write */
>> +	METRIC_OUT_MRD,		/* Outbound Memory Read */
>> +	METRIC_OUT_CPL,		/* Outbound Memory Completion */
>> +	METRIC_TYPE_MAX,
> 
> Given it is the terminator, no comma needed.
> 

Sure. Will drop the comma.

Thanks.



From krzysztof.kozlowski at linaro.org  Wed Feb 21 00:26:33 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 09:26:33 +0100
Subject: [PATCH] ARM: dts: exynos4212-tab3: limit usable memory range
In-Reply-To: <c2fde69d-48c2-446f-ac56-876651c06b51@gmail.com>
References: <20240217-tab3-limit-usable-memory-range-v1-1-49cc9c86a5cc@gmail.com>
 <15ab6aa6-fb30-4970-9c50-546afb933e03@linaro.org>
 <c2fde69d-48c2-446f-ac56-876651c06b51@gmail.com>
Message-ID: <5d67441e-df61-4894-ba52-2bed8a1143d6@linaro.org>

On 19/02/2024 20:49, Artur Weber wrote:
> On 19.02.2024 08:44, Krzysztof Kozlowski wrote:
>> On 17/02/2024 20:02, Artur Weber wrote:
>>> The stock bootloader on the Samsung Galaxy Tab 3 8.0 provides an
>>> incorrect available memory range over ATAG_MEM. Limit the usable
>>> memory in the DTS to prevent it from doing so, without having to
>>> disable ATAG support.
>>>
>>> Signed-off-by: Artur Weber <aweber.kernel at gmail.com>
>>> ---
>>>   arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi | 6 ++++++
>>>   1 file changed, 6 insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
>>> index e5254e32aa8f..9bc05961577d 100644
>>> --- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
>>> +++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
>>> @@ -45,6 +45,12 @@ chosen {
>>>   		/* Default S-BOOT bootloader loads initramfs here */
>>>   		linux,initrd-start = <0x42000000>;
>>>   		linux,initrd-end = <0x42800000>;
>>> +
>>> +		/*
>>> +		 * Stock bootloader provides incorrect memory size in ATAG_MEM;
>>> +		 * override it here
>>> +		 */
>>> +		linux,usable-memory-range = <0x40000000 0x3fc00000>;
>>
>> Applied and dropped:
>>   chosen: linux,usable-memory-range:0: [4611686019496935424] is too short
> 
> This seems to be a binding issue; the DT schema expects a 64-bit memory 
> address and size, and doesn't allow a 32-bit range. I've tested the DTS 
> on my device and this property seems to be handled fine, so I think this 
> should allow 32-bit values as well.

Regardless where is the issue: please test before sending.

> 
> I've opened a PR[1] against devicetree-org/dt-schema (where the schema 
> for the chosen node is stored) to try and fix this. If my approach is 
> incorrect, feel free to comment there as well.


According to Rob's comments, the DTS is the issue.

Best regards,
Krzysztof



From miquel.raynal at bootlin.com  Wed Feb 21 00:32:47 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 21 Feb 2024 09:32:47 +0100
Subject: [PATCH v5 11/12] mtd: rawnand: brcmnand: exec_op helper
 functions return type fixes
In-Reply-To: <f6e61482-b51a-4970-9257-8db7975148fa@moroto.mountain>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
	<20240207202257.271784-12-william.zhang@broadcom.com>
	<20240220110240.1ad5b995@xps-13>
	<f6e61482-b51a-4970-9257-8db7975148fa@moroto.mountain>
Message-ID: <20240221093247.5297f1f3@xps-13>

Hi,

dan.carpenter at linaro.org wrote on Wed, 21 Feb 2024 09:16:31 +0300:

> On Tue, Feb 20, 2024 at 11:02:40AM +0100, Miquel Raynal wrote:
> > 
> > william.zhang at broadcom.com wrote on Wed,  7 Feb 2024 12:22:56 -0800:
> >   
> > > From: David Regan <dregan at broadcom.com>
> > > 
> > > fix return type for exec_op reset and status detect helper functions
> > > 
> > > Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> > > Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
> > > Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
> > > Signed-off-by: David Regan <dregan at broadcom.com>
> > > Signed-off-by: William Zhang <william.zhang at broadcom.com>
> > > Reviewed-by: William Zhang <william.zhang at broadcom.com>  
> > 
> > By the way, a Cc: stable tag might be useful as otherwise you may leak
> > an error code in a status value (which is a bug). And move this patch
> > first in your series so we're sure it does not conflict with any of the
> > other patches and can be backported more easily.  
> 
> The original commit 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op
> implementation") is not in stable so we should be okay on this.

Right.

However please send again this patch quickly so I can queue it up
before the rest of the series.

Thanks,
Miqu?l


From atishp at rivosinc.com  Wed Feb 21 00:37:21 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Wed, 21 Feb 2024 00:37:21 -0800
Subject: [PATCH v5 11/12] KVM: riscv: selftests: Change vcpu_has_ext to a
 common function
In-Reply-To: <CAJve8om2oOLg5-wKX7m7cBTgzwqiMcb35x=nDi1edY8evXjyMw@mail.gmail.com>
References: <cover.1705916069.git.haibo1.xu@intel.com>
 <68856b86a93a4188558e5d0ebac0dd6aac8e404c.1705916069.git.haibo1.xu@intel.com>
 <CAOnJCULwRTSnrQkR2o1P53R=tJ3TAxX+y+XRBesW6OFEzgFv2g@mail.gmail.com>
 <CAJve8om2oOLg5-wKX7m7cBTgzwqiMcb35x=nDi1edY8evXjyMw@mail.gmail.com>
Message-ID: <2c96c61a-2685-4cee-9cef-963ed833bf92@rivosinc.com>

On 2/20/24 18:13, Haibo Xu wrote:
> On Wed, Feb 21, 2024 at 7:03?AM Atish Patra <atishp at atishpatra.org> wrote:
>>
>> On Mon, Jan 22, 2024 at 1:48?AM Haibo Xu <haibo1.xu at intel.com> wrote:
>>>
>>> Move vcpu_has_ext to the processor.c and rename it to __vcpu_has_ext
>>> so that other test cases can use it for vCPU extension check.
>>>
>>> Signed-off-by: Haibo Xu <haibo1.xu at intel.com>
>>> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
>>> ---
>>>   tools/testing/selftests/kvm/include/riscv/processor.h |  2 ++
>>>   tools/testing/selftests/kvm/lib/riscv/processor.c     | 10 ++++++++++
>>>   tools/testing/selftests/kvm/riscv/get-reg-list.c      | 11 +----------
>>>   3 files changed, 13 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
>>> index b68b1b731a34..bd27e1c67579 100644
>>> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
>>> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
>>> @@ -42,6 +42,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
>>>   #define RISCV_ISA_EXT_REG(idx) __kvm_reg_id(KVM_REG_RISCV_ISA_EXT, \
>>>                                               idx, KVM_REG_SIZE_ULONG)
>>>
>>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
>>> +
>>>   struct ex_regs {
>>>          unsigned long ra;
>>>          unsigned long sp;
>>> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
>>> index 39a1e9902dec..dad73ce18164 100644
>>> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
>>> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
>>> @@ -15,6 +15,16 @@
>>>
>>>   static vm_vaddr_t exception_handlers;
>>>
>>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
>>> +{
>>> +       unsigned long value = 0;
>>> +       int ret;
>>> +
>>> +       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
>>> +
>>> +       return !ret && !!value;
>>> +}
>>> +
>>
>> Not sure what was the base patch on which this was rebased. The actual
>> commit in the queue branch looks different.
>>
> 
> This patch set was based on 6.7-rc8.
> 
>> https://github.com/kvm-riscv/linux/commit/5563517cc2012e3326411b360c9924d3f2706c8d
>>
>> Both seem to have the same bug though the tests fail now and require
>> the following fix.
>> The ext id should be uint64_t and we need to pass ext directly so that
>> SBI extension tests can also pass.
>>
> 
> It's weird that 6.7-rc8 has already included Andrew's change on the ISA ext reg,
> but this patch was not generated against his change.
> 
> commit bdf6aa328f137e184b0fce607fd585354c3742f1
> Author: Andrew Jones <ajones at ventanamicro.com>
> Date:   Wed Dec 13 18:09:58 2023 +0100
> 
>      RISC-V: KVM: selftests: Treat SBI ext regs like ISA ext regs
> 
> Anyway, your changes were right. Please go ahead to include them when merging.
> 

I am not sure what happened. Probably, a merge conflict issue.

I just realized I forgot to copy paste another fix in arch timer

+++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
@@ -85,7 +85,7 @@ struct kvm_vm *test_vm_create(void)
         int nr_vcpus = test_args.nr_vcpus;

         vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
-       __TEST_REQUIRE(__vcpu_has_ext(vcpus[0], KVM_RISCV_ISA_EXT_SSTC),
+       __TEST_REQUIRE(__vcpu_has_ext(vcpus[0], 
RISCV_ISA_EXT_REG(KVM_RISCV_ISA_EXT_SSTC)),


> Thanks,
> Haibo
> 
>>
>> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
>> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
>> @@ -48,7 +48,7 @@ static inline uint64_t __kvm_reg_id(uint64_t type,
>> uint64_t subtype,
>> KVM_REG_RISCV_SBI_SINGLE, \
>> idx, KVM_REG_SIZE_ULONG)
>>
>> -bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext);
>>
>> struct ex_regs {
>> unsigned long ra;
>> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c
>> b/tools/testing/selftests/kvm/lib/riscv/processor.c
>> index 282587cd4bbc..ec66d331a127 100644
>> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
>> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
>> @@ -15,12 +15,12 @@
>>
>> static vm_vaddr_t exception_handlers;
>>
>> -bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext)
>> {
>> unsigned long value = 0;
>> int ret;
>>
>> - ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
>> + ret = __vcpu_get_reg(vcpu, ext, &value);
>>
>> return !ret && !!value;
>> }
>>
>> With the above the fix, Both SBI/ISA extension tests pass.
>> # ./get-reg-list
>> sbi-base: PASS
>> sbi-sta: PASS
>> sbi-pmu: PASS
>> sbi-dbcn: PASS
>> aia: PASS
>> fp_f: PASS
>> fp_d: PASS
>> 1..0 # SKIP - h not available, skipping tests
>> smstateen: PASS
>> sscofpmf: PASS
>> sstc: PASS
>> 1..0 # SKIP - svinval not available, skipping tests
>> 1..0 # SKIP - svnapot not available, skipping tests
>> 1..0 # SKIP - svpbmt not available, skipping tests
>> zba: PASS
>> zbb: PASS
>> zbc: PASS
>> 1..0 # SKIP - zbkb not available, skipping tests
>> 1..0 # SKIP - zbkc not available, skipping tests
>> 1..0 # SKIP - zbkx not available, skipping tests
>> zbs: PASS
>> zfa: PASS
>> 1..0 # SKIP - zfh not available, skipping tests
>> 1..0 # SKIP - zfhmin not available, skipping tests
>> zicbom: PASS
>> zicboz: PASS
>> zicntr: PASS
>> 1..0 # SKIP - zicond not available, skipping tests
>> zicsr: PASS
>> zifencei: PASS
>> zihintntl: PASS
>> zihintpause: PASS
>> zihpm: PASS
>>
>>
>>>   static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
>>>   {
>>>          return (v + vm->page_size) & ~(vm->page_size - 1);
>>> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
>>> index 25de4b8bc347..ed29ba45588c 100644
>>> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
>>> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
>>> @@ -75,15 +75,6 @@ bool check_reject_set(int err)
>>>          return err == EINVAL;
>>>   }
>>>
>>> -static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
>>> -{
>>> -       int ret;
>>> -       unsigned long value;
>>> -
>>> -       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
>>> -       return (ret) ? false : !!value;
>>> -}
>>> -
>>>   void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>>>   {
>>>          unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
>>> @@ -111,7 +102,7 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>>>                  __vcpu_set_reg(vcpu, RISCV_ISA_EXT_REG(s->feature), 1);
>>>
>>>                  /* Double check whether the desired extension was enabled */
>>> -               __TEST_REQUIRE(vcpu_has_ext(vcpu, s->feature),
>>> +               __TEST_REQUIRE(__vcpu_has_ext(vcpu, s->feature),
>>>                                 "%s not available, skipping tests\n", s->name);
>>>          }
>>>   }
>>> --
>>> 2.34.1
>>>
>>
>>
>> --
>> Regards,
>> Atish



From alexander.stein at ew.tq-group.com  Wed Feb 21 00:38:20 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 21 Feb 2024 09:38:20 +0100
Subject: [PATCH 2/2] arm64: dts: imx8mn: tqma8mqnl-mba8mx: Add missing USB PHY vbus supply
In-Reply-To: <20240220153334.2624873-2-alexander.stein@ew.tq-group.com>
References: <20240220153334.2624873-1-alexander.stein@ew.tq-group.com> <20240220153334.2624873-2-alexander.stein@ew.tq-group.com>
Message-ID: <2596915.Lt9SDvczpP@steina-w>

Am Dienstag, 20. Februar 2024, 16:33:34 CET schrieb Alexander Stein:
> VBUS 5V is statically provided to both USB host and on-bard USB-hub.
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> ---
>  arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
> index c07d59147ab55..5b682dd907578 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
> @@ -86,6 +86,10 @@ &usbotg1 {
>  	status = "okay";
>  };
>  
> +&usbphynop1 {
> +	vbus-supply = <&reg_hub_vbus>;
> +};
> +

Okay, this is kinda confusing. While checking imx8mm platform as well, it turns out
vbus-supply in drivers/usb/phy/phy-generic.c is not used at all, because i.MX
chipidea host doesn't use PHY vbus control at all.

Please drop this, thanks.
Alexander

>  &iomuxc {
>  	pinctrl_ecspi1: ecspi1grp {
>  		fsl,pins = <MX8MN_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK	0x00000146>,
> 


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From krzysztof.kozlowski at linaro.org  Wed Feb 21 00:40:46 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 09:40:46 +0100
Subject: [PATCH 1/4] dt-bindings: vendor-prefixes: add Cudy
In-Reply-To: <20240221073524.20947-2-zajec5@gmail.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
 <20240221073524.20947-2-zajec5@gmail.com>
Message-ID: <d1709385-e6f9-4305-8a82-6e21f7711579@linaro.org>

On 21/02/2024 08:35, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Cudy is a Chinese company providing networking products.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Wed Feb 21 00:40:55 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 09:40:55 +0100
Subject: [PATCH 2/4] dt-bindings: arm64: dts: mediatek: Add Cudy WR3000 V1
 router
In-Reply-To: <20240221073524.20947-3-zajec5@gmail.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
 <20240221073524.20947-3-zajec5@gmail.com>
Message-ID: <efff8ac2-5174-40b7-a15f-6ae0bc20a84a@linaro.org>

On 21/02/2024 08:35, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Cudy WR3000 V1 is an MT7981B (AKA Filogic 820) based wireless router.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From arnaud.pouliquen at foss.st.com  Wed Feb 21 00:39:51 2024
From: arnaud.pouliquen at foss.st.com (Arnaud POULIQUEN)
Date: Wed, 21 Feb 2024 09:39:51 +0100
Subject: [PATCH v3 1/7] remoteproc: Add TEE support
In-Reply-To: <ZdT2XHNpCaTnfvvR@p14s>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <20240214172127.1022199-2-arnaud.pouliquen@foss.st.com>
 <ZdT2XHNpCaTnfvvR@p14s>
Message-ID: <089f1e90-8564-4eb1-bd77-b5225189a86e@foss.st.com>

Hi Mathieu,

On 2/20/24 19:58, Mathieu Poirier wrote:
> Good morning,
> 
> On Wed, Feb 14, 2024 at 06:21:21PM +0100, Arnaud Pouliquen wrote:
>> From: Arnaud Pouliquen <arnaud.pouliquen at st.com>
>>
>> Add a remoteproc TEE (Trusted Execution Environment) driver
>> that will be probed by the TEE bus. If the associated Trusted
>> application is supported on secure part this device offers a client
>> interface to load a firmware in the secure part.
>> This firmware could be authenticated and decrypted by the secure
>> trusted application.
>>
>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at st.com>
>> ---
>> update from V2
>> - Use 'tee_rproc' prefix for all functions
>> - rename tee_rproc_get_loaded_rsc_table to tee_rproc_find_loaded_rsc_table
>> - redefine fonction to better match with the rproc_ops structure format
>> 	- replace 'struct tee_rproc' parameter by 'struct rproc' parameter
>> 	- rename 'rproc_tee_get_rsc_table()' to tee_rproc_get_loaded_rsc_table()
>> 	  and rework it to remove the cached_table management.
>> 	- introduce tee_rproc_get_context() to get the tee_rproc struct from the
>>           rproc struct
>> 	- rename tee_rproc_get_loaded_rsc_table() to tee_rproc_find_loaded_rsc_table()
>> - remove useless check on tee_rproc_ctx structure in tee_rproc_register()
>>   and tee_rproc_unregister()
>> - fix test on the return of tee_rproc_ctx = devm_kzalloc()
>> - remove useless includes and unused tee_rproc_mem structure.
>> ---
>>  drivers/remoteproc/Kconfig          |   9 +
>>  drivers/remoteproc/Makefile         |   1 +
>>  drivers/remoteproc/tee_remoteproc.c | 397 ++++++++++++++++++++++++++++
>>  include/linux/tee_remoteproc.h      | 102 +++++++
>>  4 files changed, 509 insertions(+)
>>  create mode 100644 drivers/remoteproc/tee_remoteproc.c
>>  create mode 100644 include/linux/tee_remoteproc.h
>>
>> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
>> index 48845dc8fa85..85299606806c 100644
>> --- a/drivers/remoteproc/Kconfig
>> +++ b/drivers/remoteproc/Kconfig
>> @@ -365,6 +365,15 @@ config XLNX_R5_REMOTEPROC
>>  
>>  	  It's safe to say N if not interested in using RPU r5f cores.
>>  
>> +
>> +config TEE_REMOTEPROC
>> +	tristate "trusted firmware support by a TEE application"
> 
> s/trusted/Trusted
> 
> And the wording will have to change a little, I will advise on this later.
> 
>> +	depends on OPTEE
>> +	help
>> +	  Support for trusted remote processors firmware. The firmware
>> +	  authentication and/or decryption are managed by a trusted application.
>> +	  This can be either built-in or a loadable module.
>> +
>>  endif # REMOTEPROC
>>  
>>  endmenu
>> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
>> index 91314a9b43ce..fa8daebce277 100644
>> --- a/drivers/remoteproc/Makefile
>> +++ b/drivers/remoteproc/Makefile
>> @@ -36,6 +36,7 @@ obj-$(CONFIG_RCAR_REMOTEPROC)		+= rcar_rproc.o
>>  obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
>>  obj-$(CONFIG_ST_SLIM_REMOTEPROC)	+= st_slim_rproc.o
>>  obj-$(CONFIG_STM32_RPROC)		+= stm32_rproc.o
>> +obj-$(CONFIG_TEE_REMOTEPROC)		+= tee_remoteproc.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_XLNX_R5_REMOTEPROC)	+= xlnx_r5_remoteproc.o
>> diff --git a/drivers/remoteproc/tee_remoteproc.c b/drivers/remoteproc/tee_remoteproc.c
>> new file mode 100644
>> index 000000000000..ac727e062d00
>> --- /dev/null
>> +++ b/drivers/remoteproc/tee_remoteproc.c
>> @@ -0,0 +1,397 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
>> + * Author: Arnaud Pouliquen <arnaud.pouliquen at st.com>
>> + */
>> +
>> +#include <linux/firmware.h>
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/remoteproc.h>
>> +#include <linux/slab.h>
>> +#include <linux/tee_drv.h>
>> +#include <linux/tee_remoteproc.h>
>> +
>> +#include "remoteproc_internal.h"
>> +
>> +#define MAX_TEE_PARAM_ARRY_MEMBER	4
>> +
>> +/*
>> + * Authentication of the firmware and load in the remote processor memory
>> + *
>> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
>> + * [in]	 params[1].memref:	buffer containing the image of the buffer
>> + */
>> +#define TA_RPROC_FW_CMD_LOAD_FW		1
>> +
>> +/*
>> + * Start the remote processor
>> + *
>> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
>> + */
>> +#define TA_RPROC_FW_CMD_START_FW	2
>> +
>> +/*
>> + * Stop the remote processor
>> + *
>> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
>> + */
>> +#define TA_RPROC_FW_CMD_STOP_FW		3
>> +
>> +/*
>> + * Return the address of the resource table, or 0 if not found
>> + * No check is done to verify that the address returned is accessible by
>> + * the non secure context. If the resource table is loaded in a protected
>> + * memory the access by the non secure context will lead to a data abort.
>> + *
>> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
>> + * [out]  params[1].value.a:	32bit LSB resource table memory address
>> + * [out]  params[1].value.b:	32bit MSB resource table memory address
>> + * [out]  params[2].value.a:	32bit LSB resource table memory size
>> + * [out]  params[2].value.b:	32bit MSB resource table memory size
>> + */
>> +#define TA_RPROC_FW_CMD_GET_RSC_TABLE	4
>> +
>> +/*
>> + * Return the address of the core dump
>> + *
>> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
>> + * [out] params[1].memref:	address of the core dump image if exist,
>> + *				else return Null
>> + */
>> +#define TA_RPROC_FW_CMD_GET_COREDUMP	5
>> +
>> +struct tee_rproc__context {
> 
> s/tee_rproc__context/tee_rproc_context

I updated to tee_rproc_interface in a first update,as you advised. But
regarding the implementation I propose in this version, keeping the initial
name seems to me better. I have introduced the issue coming back to initial name.

> 
> as it was in the previous patchset.
> 
>> +	struct list_head sessions;
>> +	struct tee_context *tee_ctx;
>> +	struct device *dev;
>> +};
>> +
>> +static struct tee_rproc__context *tee_rproc_ctx;
>> +
>> +static void prepare_args(struct tee_rproc *trproc, int cmd,
>> +			 struct tee_ioctl_invoke_arg *arg,
>> +			 struct tee_param *param, unsigned int num_params)
>> +{
>> +	memset(arg, 0, sizeof(*arg));
>> +	memset(param, 0, MAX_TEE_PARAM_ARRY_MEMBER * sizeof(*param));
>> +
>> +	arg->func = cmd;
>> +	arg->session = trproc->session_id;
>> +	arg->num_params = num_params + 1;
>> +
>> +	param[0] = (struct tee_param) {
>> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
>> +		.u.value.a = trproc->rproc_id,
>> +	};
>> +}
>> +
>> +static struct tee_rproc *tee_rproc_get_context(struct rproc *rproc)
>> +{
>> +	struct tee_rproc *entry, *tmp;
>> +
>> +	list_for_each_entry_safe(entry, tmp, &tee_rproc_ctx->sessions, node) {
>> +		if (entry->rproc == rproc)
>> +			return entry;
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +int tee_rproc_load_fw(struct rproc *rproc, const struct firmware *fw)
>> +{
>> +	struct tee_ioctl_invoke_arg arg;
>> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
>> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
>> +	struct tee_shm *fw_shm;
>> +	int ret;
>> +
>> +	if (!trproc)
>> +		return -EINVAL;
>> +
>> +	fw_shm = tee_shm_register_kernel_buf(tee_rproc_ctx->tee_ctx, (void *)fw->data, fw->size);
>> +	if (IS_ERR(fw_shm))
>> +		return PTR_ERR(fw_shm);
>> +
>> +	prepare_args(trproc, TA_RPROC_FW_CMD_LOAD_FW, &arg, param, 1);
>> +
>> +	/* Provide the address of the firmware image */
>> +	param[1] = (struct tee_param) {
>> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
>> +		.u.memref = {
>> +			.shm = fw_shm,
>> +			.size = fw->size,
>> +			.shm_offs = 0,
>> +		},
>> +	};
>> +
>> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
>> +	if (ret < 0 || arg.ret != 0) {
>> +		dev_err(tee_rproc_ctx->dev,
>> +			"TA_RPROC_FW_CMD_LOAD_FW invoke failed TEE err: %x, ret:%x\n",
>> +			arg.ret, ret);
>> +		if (!ret)
>> +			ret = -EIO;
>> +	}
>> +
>> +	tee_shm_free(fw_shm);
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(tee_rproc_load_fw);
>> +
>> +struct resource_table *tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
>> +{
>> +	struct tee_ioctl_invoke_arg arg;
>> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
>> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
>> +	int ret;
>> +
>> +	if (!trproc)
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	prepare_args(trproc, TA_RPROC_FW_CMD_GET_RSC_TABLE, &arg, param, 2);
>> +
>> +	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
>> +	param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
>> +
>> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
>> +	if (ret < 0 || arg.ret != 0) {
>> +		dev_err(tee_rproc_ctx->dev,
>> +			"TA_RPROC_FW_CMD_GET_RSC_TABLE invoke failed TEE err: %x, ret:%x\n",
>> +			arg.ret, ret);
>> +		return ERR_PTR(-EIO);
>> +	}
>> +
>> +	*table_sz = param[2].u.value.a;
>> +
>> +	/* If the size is null no resource table defined in the image */
>> +	if (!*table_sz)
>> +		return NULL;
>> +
>> +	/* Store the resource table address that would be updated by the remote core. */
>> +	trproc->rsc_table = ioremap_wc(param[1].u.value.a, *table_sz);
>> +	if (IS_ERR_OR_NULL(trproc->rsc_table)) {
>> +		dev_err(tee_rproc_ctx->dev, "Unable to map memory region: %lld+%zx\n",
>> +			param[1].u.value.a, *table_sz);
>> +		return ERR_PTR(-ENOMEM);
>> +	}
>> +
>> +	return trproc->rsc_table;
>> +}
>> +EXPORT_SYMBOL_GPL(tee_rproc_get_loaded_rsc_table);
>> +
>> +struct resource_table *tee_rproc_find_loaded_rsc_table(struct rproc *rproc,
>> +						       const struct firmware *fw)
>> +{
>> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
>> +	size_t table_sz;
>> +
>> +	if (!trproc)
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	if (!trproc->rsc_table)
>> +		trproc->rsc_table = tee_rproc_get_loaded_rsc_table(rproc, &table_sz);
>> +
>> +	return trproc->rsc_table;
>> +}
>> +EXPORT_SYMBOL_GPL(tee_rproc_find_loaded_rsc_table);
>> +
>> +int tee_rproc_start(struct rproc *rproc)
>> +{
>> +	struct tee_ioctl_invoke_arg arg;
>> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
>> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
>> +	int ret;
>> +
>> +	if (!trproc)
>> +		return -EINVAL;
>> +
>> +	prepare_args(trproc, TA_RPROC_FW_CMD_START_FW, &arg, param, 0);
>> +
>> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
>> +	if (ret < 0 || arg.ret != 0) {
>> +		dev_err(tee_rproc_ctx->dev,
>> +			"TA_RPROC_FW_CMD_START_FW invoke failed TEE err: %x, ret:%x\n",
>> +			arg.ret, ret);
>> +		if (!ret)
>> +			ret = -EIO;
>> +	}
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(tee_rproc_start);
>> +
>> +int tee_rproc_stop(struct rproc *rproc)
>> +{
>> +	struct tee_ioctl_invoke_arg arg;
>> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
>> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
>> +	int ret;
>> +
>> +	if (!trproc)
>> +		return -EINVAL;
>> +
>> +	prepare_args(trproc, TA_RPROC_FW_CMD_STOP_FW, &arg, param, 0);
>> +
>> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
>> +	if (ret < 0 || arg.ret != 0) {
>> +		dev_err(tee_rproc_ctx->dev,
>> +			"TA_RPROC_FW_CMD_STOP_FW invoke failed TEE err: %x, ret:%x\n",
>> +			arg.ret, ret);
>> +		if (!ret)
>> +			ret = -EIO;
>> +	}
>> +	if (trproc->rsc_table)
>> +		iounmap(trproc->rsc_table);
>> +	trproc->rsc_table = NULL;
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(tee_rproc_stop);
>>
> 
> I was wondering where this ID is coming from - Is it the ID of the remote
> processor service in the secure world or the ID of the program that provides the
> service?
> 
> More comments tomorrow.

I assume that you are speaking about trproc->rproc_id. Yes, it is an identifier.

The rproc_id must be common between the Linux and the secure world. It is used
by the secure world to identify the remote processor and is platform dependent.

The TEE application that provides the service is identified by a UUID defined in
stm32_tee_rproc_id_table[] below.

Thanks,
Arnaud

> 
> Thanks,
> Mathieu
> 
> +
>> +static const struct tee_client_device_id stm32_tee_rproc_id_table[] = {
>> +	{UUID_INIT(0x80a4c275, 0x0a47, 0x4905,
>> +		   0x82, 0x85, 0x14, 0x86, 0xa9, 0x77, 0x1a, 0x08)},
>> +	{}
>> +};
>> +
>> +struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id)
>> +{
>> +	struct tee_client_device *tee_device;
>> +	struct tee_ioctl_open_session_arg sess_arg;
>> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
>> +	struct tee_rproc *trproc;
>> +	int ret;
>> +
>> +	/*
>> +	 * The device is not probed by the TEE bus. We ignore the reason (bus could be not yet
>> +	 * probed or service not available in the secure firmware)
>> +	 * Assumption here is that the TEE bus is not probed.
>> +	 */
>> +	if (!tee_rproc_ctx)
>> +		return ERR_PTR(-EPROBE_DEFER);
>> +
>> +	trproc =  devm_kzalloc(dev, sizeof(*trproc), GFP_KERNEL);
>> +	if (!trproc)
>> +		return ERR_PTR(-ENOMEM);
>> +
>> +	tee_device = to_tee_client_device(tee_rproc_ctx->dev);
>> +	memset(&sess_arg, 0, sizeof(sess_arg));
>> +
>> +	/* Open session with rproc_tee load the OP-TEE Trusted Application */
>> +	memcpy(sess_arg.uuid, tee_device->id.uuid.b, TEE_IOCTL_UUID_LEN);
>> +
>> +	sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
>> +	sess_arg.num_params = 1;
>> +
>> +	param[0] = (struct tee_param) {
>> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
>> +		.u.value.a = rproc_id,
>> +	};
>> +
>> +	ret = tee_client_open_session(tee_rproc_ctx->tee_ctx, &sess_arg, param);
>> +	if (ret < 0 || sess_arg.ret != 0) {
>> +		dev_err(dev, "tee_client_open_session failed, err: %x\n", sess_arg.ret);
>> +		return ERR_PTR(-EINVAL);
>> +	}
>> +
>> +	trproc->parent =  dev;
>> +	trproc->rproc_id = rproc_id;
>> +	trproc->session_id = sess_arg.session;
>> +
>> +	list_add_tail(&trproc->node, &tee_rproc_ctx->sessions);
>> +
>> +	return trproc;
>> +}
>> +EXPORT_SYMBOL_GPL(tee_rproc_register);
>> +
>> +int tee_rproc_unregister(struct tee_rproc *trproc)
>> +{
>> +	int ret;
>> +
>> +	ret = tee_client_close_session(tee_rproc_ctx->tee_ctx, trproc->session_id);
>> +	if (ret < 0)
>> +		dev_err(trproc->parent,	"tee_client_close_session failed, err: %x\n", ret);
>> +
>> +	list_del(&trproc->node);
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(tee_rproc_unregister);
>> +
>> +static int tee_rproc_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
>> +{
>> +	/* Today we support only the OP-TEE, could be extend to other tees */
>> +	return (ver->impl_id == TEE_IMPL_ID_OPTEE);
>> +}
>> +
>> +static int tee_rproc_probe(struct device *dev)
>> +{
>> +	struct tee_context *tee_ctx;
>> +	int ret;
>> +
>> +	/* Open context with TEE driver */
>> +	tee_ctx = tee_client_open_context(NULL, tee_rproc_ctx_match, NULL, NULL);
>> +	if (IS_ERR(tee_ctx))
>> +		return PTR_ERR(tee_ctx);
>> +
>> +	tee_rproc_ctx = devm_kzalloc(dev, sizeof(*tee_ctx), GFP_KERNEL);
>> +	if (!tee_rproc_ctx) {
>> +		ret = -ENOMEM;
>> +		goto err;
>> +	}
>> +
>> +	tee_rproc_ctx->dev = dev;
>> +	tee_rproc_ctx->tee_ctx = tee_ctx;
>> +	INIT_LIST_HEAD(&tee_rproc_ctx->sessions);
>> +
>> +	return 0;
>> +err:
>> +	tee_client_close_context(tee_ctx);
>> +
>> +	return ret;
>> +}
>> +
>> +static int tee_rproc_remove(struct device *dev)
>> +{
>> +	struct tee_rproc *entry, *tmp;
>> +
>> +	list_for_each_entry_safe(entry, tmp, &tee_rproc_ctx->sessions, node) {
>> +		tee_client_close_session(tee_rproc_ctx->tee_ctx, entry->session_id);
>> +		list_del(&entry->node);
>> +		kfree(entry);
>> +	}
>> +
>> +	tee_client_close_context(tee_rproc_ctx->tee_ctx);
>> +
>> +	return 0;
>> +}
>> +
>> +MODULE_DEVICE_TABLE(tee, stm32_tee_rproc_id_table);
>> +
>> +static struct tee_client_driver tee_rproc_fw_driver = {
>> +	.id_table	= stm32_tee_rproc_id_table,
>> +	.driver		= {
>> +		.name		= KBUILD_MODNAME,
>> +		.bus		= &tee_bus_type,
>> +		.probe		= tee_rproc_probe,
>> +		.remove		= tee_rproc_remove,
>> +	},
>> +};
>> +
>> +static int __init tee_rproc_fw_mod_init(void)
>> +{
>> +	return driver_register(&tee_rproc_fw_driver.driver);
>> +}
>> +
>> +static void __exit tee_rproc_fw_mod_exit(void)
>> +{
>> +	driver_unregister(&tee_rproc_fw_driver.driver);
>> +}
>> +
>> +module_init(tee_rproc_fw_mod_init);
>> +module_exit(tee_rproc_fw_mod_exit);
>> +
>> +MODULE_DESCRIPTION(" TEE remote processor control driver");
>> +MODULE_LICENSE("GPL");
>> diff --git a/include/linux/tee_remoteproc.h b/include/linux/tee_remoteproc.h
>> new file mode 100644
>> index 000000000000..7c9e91e989ba
>> --- /dev/null
>> +++ b/include/linux/tee_remoteproc.h
>> @@ -0,0 +1,102 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * Copyright(c) 2023 STMicroelectronics - All Rights Reserved
>> + */
>> +
>> +#ifndef TEE_REMOTEPROC_H
>> +#define TEE_REMOTEPROC_H
>> +
>> +#include <linux/tee_drv.h>
>> +#include <linux/firmware.h>
>> +#include <linux/remoteproc.h>
>> +
>> +struct rproc;
>> +
>> +/**
>> + * struct tee_rproc - TEE remoteproc structure
>> + * @node:		Reference in list
>> + * @rproc:		Remoteproc reference
>> + * @parent:		Parent device
>> + * @rproc_id:		Identifier of the target firmware
>> + * @session_id:		TEE session identifier
>> + * @rsc_table:		Resource table virtual address.
>> + */
>> +struct tee_rproc {
>> +	struct list_head node;
>> +	struct rproc *rproc;
>> +	struct device *parent;
>> +	u32 rproc_id;
>> +	u32 session_id;
>> +	struct resource_table *rsc_table;
>> +};
>> +
>> +#if IS_ENABLED(CONFIG_TEE_REMOTEPROC)
>> +
>> +struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id);
>> +int tee_rproc_unregister(struct tee_rproc *trproc);
>> +
>> +int tee_rproc_load_fw(struct rproc *rproc, const struct firmware *fw);
>> +struct resource_table *tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz);
>> +struct resource_table *tee_rproc_find_loaded_rsc_table(struct rproc *rproc,
>> +						       const struct firmware *fw);
>> +int tee_rproc_start(struct rproc *rproc);
>> +int tee_rproc_stop(struct rproc *rproc);
>> +
>> +#else
>> +
>> +static inline struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id)
>> +{
>> +	return ERR_PTR(-ENODEV);
>> +}
>> +
>> +static inline int tee_rproc_unregister(struct tee_rproc *trproc)
>> +{
>> +	/* This shouldn't be possible */
>> +	WARN_ON(1);
>> +
>> +	return 0;
>> +}
>> +
>> +static inline int tee_rproc_load_fw(struct rproc *rproc,  const struct firmware *fw)
>> +{
>> +	/* This shouldn't be possible */
>> +	WARN_ON(1);
>> +
>> +	return 0;
>> +}
>> +
>> +static inline int tee_rproc_start(struct rproc *rproc)
>> +{
>> +	/* This shouldn't be possible */
>> +	WARN_ON(1);
>> +
>> +	return 0;
>> +}
>> +
>> +static inline int tee_rproc_stop(struct rproc *rproc)
>> +{
>> +	/* This shouldn't be possible */
>> +	WARN_ON(1);
>> +
>> +	return 0;
>> +}
>> +
>> +static inline struct resource_table *
>> +tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
>> +{
>> +	/* This shouldn't be possible */
>> +	WARN_ON(1);
>> +
>> +	return NULL;
>> +}
>> +
>> +static inline struct resource_table *
>> +tee_rproc_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
>> +{
>> +	/* This shouldn't be possible */
>> +	WARN_ON(1);
>> +
>> +	return NULL;
>> +}
>> +#endif /* CONFIG_TEE_REMOTEPROC */
>> +#endif /* TEE_REMOTEPROC_H */
>> -- 
>> 2.25.1
>>


From daniel.lezcano at linaro.org  Wed Feb 21 00:47:21 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 21 Feb 2024 09:47:21 +0100
Subject: [PATCH v3 0/3] clocksource: imx-sysctr: support i.MX95
In-Reply-To: <20240126-imx-sysctr-v3-0-33fe801d5f31@nxp.com>
References: <20240126-imx-sysctr-v3-0-33fe801d5f31@nxp.com>
Message-ID: <225c8489-0b81-402b-987a-09a46349c10d@linaro.org>

On 26/01/2024 08:09, Peng Fan (OSS) wrote:
> i.MX95 System Counter module control register space is blocked
> by SCMI firmware, so we use Read Register space to get the counter.
> 
> V2:
>    - imx95 is not compatible with the existing hardware, so add a
>      seperate entry for i.MX95 in dt-binding.
>    - Per Marco's comments, the global variables was removed except
>      to_sysctr. And add a new TIMER_OF_DECLARE entry for i.MX95
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---

Applied, thanks

-- 
<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 daniel.lezcano at linaro.org  Wed Feb 21 00:49:18 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 21 Feb 2024 09:49:18 +0100
Subject: [PATCH v3 0/3] clocksource: imx-sysctr: support i.MX95
In-Reply-To: <225c8489-0b81-402b-987a-09a46349c10d@linaro.org>
References: <20240126-imx-sysctr-v3-0-33fe801d5f31@nxp.com>
 <225c8489-0b81-402b-987a-09a46349c10d@linaro.org>
Message-ID: <ce571a9f-fe6c-4131-ab3b-cba39f537ab7@linaro.org>

On 21/02/2024 09:47, Daniel Lezcano wrote:
> On 26/01/2024 08:09, Peng Fan (OSS) wrote:
>> i.MX95 System Counter module control register space is blocked
>> by SCMI firmware, so we use Read Register space to get the counter.
>>
>> V2:
>> ?? - imx95 is not compatible with the existing hardware, so add a
>> ???? seperate entry for i.MX95 in dt-binding.
>> ?? - Per Marco's comments, the global variables was removed except
>> ???? to_sysctr. And add a new TIMER_OF_DECLARE entry for i.MX95
>>
>> Signed-off-by: Peng Fan <peng.fan at nxp.com>
>> ---
> 
> Applied, thanks

Never mind, I did a confusion with another series. V4 is actually applied.

-- 
<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 quic_bibekkum at quicinc.com  Wed Feb 21 00:55:26 2024
From: quic_bibekkum at quicinc.com (Bibek Kumar Patro)
Date: Wed, 21 Feb 2024 14:25:26 +0530
Subject: [PATCH v9 4/5] iommu/arm-smmu: add ACTLR data and support for
 SM8550
In-Reply-To: <20240213134714.GC28926@willie-the-truck>
References: <20240123144543.9405-1-quic_bibekkum@quicinc.com>
 <20240123144543.9405-5-quic_bibekkum@quicinc.com>
 <20240213134714.GC28926@willie-the-truck>
Message-ID: <201fef09-50ab-436b-af63-4535c7510d15@quicinc.com>



On 2/13/2024 7:17 PM, Will Deacon wrote:
> On Tue, Jan 23, 2024 at 08:15:42PM +0530, Bibek Kumar Patro wrote:
>> Add ACTLR data table for SM8550 along with support for
>> same including SM8550 specific implementation operations.
>>
>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
>> ---
>>   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 90 ++++++++++++++++++++++
>>   1 file changed, 90 insertions(+)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> index 6004c6d9a7b2..db15b1eade97 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> @@ -23,6 +23,86 @@
>>
>>   #define CPRE			(1 << 1)
>>   #define CMTLB			(1 << 0)
>> +#define PREFETCH_SHIFT		8
>> +#define PREFETCH_DEFAULT	0
>> +#define PREFETCH_SHALLOW	(1 << PREFETCH_SHIFT)
>> +#define PREFETCH_MODERATE	(2 << PREFETCH_SHIFT)
>> +#define PREFETCH_DEEP		(3 << PREFETCH_SHIFT)
>> +#define PREFETCH_SWITCH_GFX	(5 << 3)
>> +
>> +static const struct actlr_config sm8550_apps_actlr_cfg[] = {
>> +	{ 0x18a0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
>> +	{ 0x18e0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
>> +	{ 0x0800, 0x0020, PREFETCH_DEFAULT | CMTLB },
>> +	{ 0x1800, 0x00c0, PREFETCH_DEFAULT | CMTLB },
>> +	{ 0x1820, 0x0000, PREFETCH_DEFAULT | CMTLB },
>> +	{ 0x1860, 0x0000, PREFETCH_DEFAULT | CMTLB },
>> +	{ 0x0c01, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
>> +	{ 0x0c02, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
>> +	{ 0x0c03, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
>> +	{ 0x0c04, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
>> +	{ 0x0c05, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
>> +	{ 0x0c06, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> 
> [...]
> 
> Isn't this effectively hard-coding the topology of the SoC in the driver?
> Wouldn't it better describing higher-level prefetch properties in the DT
> nodes corresponding to the upstream devices?

Since prefetch data stored in this table represent settings for the
ACTLR register, and doesn't exactly define the hardware (So in this
manner prefetch data won't exactly be a part of soc topology ?).
So it seemed apt not to use the device tree for storing the prefetch
property. Hence we reverted from the DT approach (initial proposal in
RFC to piggyback on iommus property to store prefetch settings) back to 
use driver for storing this data.

Some drivers use the same approach for storing their platform specific
data. Examples being
drivers/phy/qualcomm/phy-qcom-qmp-combo.c
drivers/soc/qcom/llcc-qcom.c
These drivers were taken as reference for storing platform specific 
ACTLR data.

Thanks & regards,
Bibek

> 
> Looking back at the prior revisions of this series, it seems like others
> were in favour of this approach, so if that's the general consensus, then
> so be it. But is this _really_ what we want in the SMMU driver? It would
> be good to have an Ack from Robin and a DT maintainer on this mechanism.
>
> It just all feels a bit like a step back into the bad old world of
> platform data to me, where we end up trying to maintain a bunch of random
> constants that supposedly make things faster for somebody :/
> > Will


From zajec5 at gmail.com  Wed Feb 21 00:55:47 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 21 Feb 2024 09:55:47 +0100
Subject: [PATCH] arm64: dts: mediatek: mt7981: add watchdog & WiFi controllers
Message-ID: <20240221085547.27840-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

MT7981 (Filogic 820) is a low cost version of MT7986 (Filogic 830) with
the same watchdog controller. It also comes with on-SoC 802.11ax
wireless.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 26 ++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
index 2f89b18bab17..0dc49c47dfc2 100644
--- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
@@ -2,6 +2,7 @@
 
 #include <dt-bindings/clock/mediatek,mt7981-clk.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/mt7986-resets.h>
 
 / {
 	compatible = "mediatek,mt7981b";
@@ -62,12 +63,19 @@ infracfg: clock-controller at 10001000 {
 			#clock-cells = <1>;
 		};
 
-		clock-controller at 1001b000 {
+		topckgen: clock-controller at 1001b000 {
 			compatible = "mediatek,mt7981-topckgen", "syscon";
 			reg = <0 0x1001b000 0 0x1000>;
 			#clock-cells = <1>;
 		};
 
+		watchdog: watchdog at 1001c000 {
+			compatible = "mediatek,mt7986-wdt";
+			reg = <0 0x1001c000 0 0x1000>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			#reset-cells = <1>;
+		};
+
 		clock-controller at 1001e000 {
 			compatible = "mediatek,mt7981-apmixedsys";
 			reg = <0 0x1001e000 0 0x1000>;
@@ -142,6 +150,22 @@ clock-controller at 15000000 {
 			#clock-cells = <1>;
 			#reset-cells = <1>;
 		};
+
+		wifi at 18000000 {
+			compatible = "mediatek,mt7981-wmac";
+			reg = <0 0x18000000 0 0x1000000>,
+			      <0 0x10003000 0 0x1000>,
+			      <0 0x11d10000 0 0x1000>;
+			interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&topckgen CLK_TOP_NETSYS_MCU_SEL>,
+				 <&topckgen CLK_TOP_AP2CNN_HOST_SEL>;
+			clock-names = "mcu", "ap2conn";
+			resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>;
+			reset-names = "consys";
+		};
 	};
 
 	timer {
-- 
2.35.3



From hverkuil-cisco at xs4all.nl  Wed Feb 21 01:02:01 2024
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Wed, 21 Feb 2024 10:02:01 +0100
Subject: [PATCH] media: cec: core: remove length check of Timer Status
In-Reply-To: <089a5abf85fb3aaa57cb9436193b09eea47a03d2.camel@mediatek.com>
References: <20240125132850.10430-1-nini.song@mediatek.com>
 <8a4447ba-d4ac-40ac-9d6b-796db37f3100@xs4all.nl>
 <089a5abf85fb3aaa57cb9436193b09eea47a03d2.camel@mediatek.com>
Message-ID: <852dea56-336a-4484-8754-ee735af7bdaf@xs4all.nl>

Dear Nini,

Unfortunately I forgot to add a 'Fixes' tag to the patch, if I had, then it would
have happened automatically.

Please remind me of this once kernel 6.9-rc1 is released since that will contain
the fix. Then I can post the same patch to the stable mailinglist for inclusion in
older kernels.

It has to wait until 6.9-rc1 is release though, patches need to be in mainline first
before they can be backported.

Regards,

	Hans

On 21/02/2024 07:30, Nini Song (???) wrote:
> Dear Hans,
> 
> Thank your reply.
> Could you also help to marge solution into v5.15? Our customer used v5.15 for MP production, which requires this solution.
> 
> 
> BR,
> Nini Song
> On Mon, 2024-02-05 at 13:00 +0100, Hans Verkuil wrote:
>> 	
>>
>> External email : Please do not click links or open attachments until you have verified the sender or the content.
>>
>> On 25/01/2024 14:28, nini.song at mediatek.com wrote:
>> > From: "nini.song" <nini.song at mediatek.com>
>> > 
>> > The valid_la is used to check the length requirements,
>> > including special cases of Timer Status. If the length is
>> > shorter than 5, that means no Duration Available is returned,
>> > the message will be forced to be invalid.
>> > 
>> > However, the description of Duration Available in the spec
>> > is that this parameter may be returned when these cases, or
>> > that it can be optionally return when these cases. The key
>> > words in the spec description are flexible choices.
>>
>> Good catch, the spec indeed says 'may', so dropping the check
>> in this patch is the correct thing to do.
>>
>> It's merged in our staging tree and it will appear in v6.9.
>>
>> Regards,
>>
>> Hans
>>
>> > 
>> > Remove the special length check of Timer Status to fit the
>> > spec which is not compulsory about that.
>> > 
>> > Signed-off-by: Nini Song <nini.song at mediatek.com>
>> > ---
>> >  drivers/media/cec/core/cec-adap.c | 14 --------------
>> >  1 file changed, 14 deletions(-)
>> > 
>> > diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
>> > index 5741adf09a2e..559a172ebc6c 100644
>> > --- a/drivers/media/cec/core/cec-adap.c
>> > +++ b/drivers/media/cec/core/cec-adap.c
>> > @@ -1151,20 +1151,6 @@ void cec_received_msg_ts(struct cec_adapter *adap,
>> >  if (valid_la && min_len) {
>> >  /* These messages have special length requirements */
>> >  switch (cmd) {
>> > -case CEC_MSG_TIMER_STATUS:
>> > -if (msg->msg[2] & 0x10) {
>> > -switch (msg->msg[2] & 0xf) {
>> > -case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE:
>> > -case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE:
>> > -if (msg->len < 5)
>> > -valid_la = false;
>> > -break;
>> > -}
>> > -} else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) {
>> > -if (msg->len < 5)
>> > -valid_la = false;
>> > -}
>> > -break;
>> >  case CEC_MSG_RECORD_ON:
>> >  switch (msg->msg[2]) {
>> >  case CEC_OP_RECORD_SRC_OWN:
>>
>>



From daniel.lezcano at linaro.org  Wed Feb 21 01:04:16 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 21 Feb 2024 10:04:16 +0100
Subject: [PATCH] clocksource: arm_global_timer: fix non-kernel-doc comment
In-Reply-To: <20240115053641.29129-1-rdunlap@infradead.org>
References: <20240115053641.29129-1-rdunlap@infradead.org>
Message-ID: <4cbac15d-115b-437d-a622-f9aa40187ddd@linaro.org>

On 15/01/2024 06:36, Randy Dunlap wrote:
> Use a common C comment "/*" instead of a kernel-doc marker "/**"
> to prevent kernel-doc warnings:
> 
> arm_global_timer.c:92: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>   * To ensure that updates to comparator value register do not set the
> arm_global_timer.c:92: warning: missing initial short description on line:
>   * To ensure that updates to comparator value register do not set the
> 
> Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> ---

Applied, thanks

-- 
<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 peterx at redhat.com  Wed Feb 21 01:37:37 2024
From: peterx at redhat.com (Peter Xu)
Date: Wed, 21 Feb 2024 17:37:37 +0800
Subject: [PATCH v2 03/13] mm: Provide generic pmd_thp_or_huge()
In-Reply-To: <20240115175551.GP734935@nvidia.com>
References: <20240103091423.400294-1-peterx@redhat.com>
 <20240103091423.400294-4-peterx@redhat.com>
 <20240115175551.GP734935@nvidia.com>
Message-ID: <ZdXEYfs_xhS_9gRo@x1n>

On Mon, Jan 15, 2024 at 01:55:51PM -0400, Jason Gunthorpe wrote:
> On Wed, Jan 03, 2024 at 05:14:13PM +0800, peterx at redhat.com wrote:
> > From: Peter Xu <peterx at redhat.com>
> > 
> > ARM defines pmd_thp_or_huge(), detecting either a THP or a huge PMD.  It
> > can be a helpful helper if we want to merge more THP and hugetlb code
> > paths.  Make it a generic default implementation, only exist when
> > CONFIG_MMU.  Arch can overwrite it by defining its own version.
> > 
> > For example, ARM's pgtable-2level.h defines it to always return false.
> > 
> > Keep the macro declared with all config, it should be optimized to a false
> > anyway if !THP && !HUGETLB.
> > 
> > Signed-off-by: Peter Xu <peterx at redhat.com>
> > ---
> >  include/linux/pgtable.h | 4 ++++
> >  mm/gup.c                | 3 +--
> >  2 files changed, 5 insertions(+), 2 deletions(-)
> > 
> > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> > index 466cf477551a..2b42e95a4e3a 100644
> > --- a/include/linux/pgtable.h
> > +++ b/include/linux/pgtable.h
> > @@ -1362,6 +1362,10 @@ static inline int pmd_write(pmd_t pmd)
> >  #endif /* pmd_write */
> >  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
> >  
> > +#ifndef pmd_thp_or_huge
> > +#define pmd_thp_or_huge(pmd)	(pmd_huge(pmd) || pmd_trans_huge(pmd))
> > +#endif
> 
> Why not just use pmd_leaf() ?
> 
> This GUP case seems to me exactly like what pmd_leaf() should really
> do and be used for..

I think I mostly agree with you, and these APIs are indeed confusing.  IMHO
the challenge is about the risk of breaking others on small changes in the
details where evil resides.

> 
> eg x86 does:
> 
> #define pmd_leaf	pmd_large
> static inline int pmd_large(pmd_t pte)
> 	return pmd_flags(pte) & _PAGE_PSE;
> 
> static inline int pmd_trans_huge(pmd_t pmd)
> 	return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
> 
> int pmd_huge(pmd_t pmd)
>         return !pmd_none(pmd) &&
>                 (pmd_val(pmd) & (_PAGE_PRESENT|_PAGE_PSE)) != _PAGE_PRESENT;

For example, here I don't think it's strictly pmd_leaf()? As pmd_huge()
will return true if PRESENT=0 && PSE=0 (as long as none pte ruled out
first), while pmd_leaf() will return false; I think that came from
cbef8478bee5.  I'm not sure whether that is the best solution, e.g., from a
1st glance it seems better to me to process swap entries separately
(including both migration and poisoned entries)..

Sparc has similar things there, which in that case I'm not sure whether a
direct replace is always safe.

Besides that, there're also other cases where it's not clear of such direct
replacement, not until further investigated.  E.g., arm-3level has:

#define pmd_leaf(pmd)		pmd_sect(pmd)
#define pmd_sect(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
						 PMD_TYPE_SECT)
#define PMD_TYPE_SECT		(_AT(pmdval_t, 1) << 0)

While pmd_huge() there relies on PMD_TABLE_BIT ()

int pmd_huge(pmd_t pmd)
{
	return pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT);
}

#define PMD_TABLE_BIT		(_AT(pmdval_t, 1) << 1)

These are just the trivial details that I wanted to avoid to touch in this
series, so as to resolve the hugetlb issue separately from others.

The new pmd_huge_or_thp() is not ideal, but that easily isolates all these
trivial details / evils out of the picture, so that we can tackle them one
by one.  It is strictly an OR or huge||thp, so it's hopefully safe to not
break anything yet from that regard.

> 
> I spot checked a couple arches and it looks like it holds up.
> 
> Further, it looks to me like this site in GUP is the only core code
> caller..
> 
> So, I'd suggest a small series to go arch by arch and convert the arch
> to use pmd_huge() == pmd_leaf(). Then retire pmd_huge() as a public
> API.
> 
> > diff --git a/mm/gup.c b/mm/gup.c
> > index df83182ec72d..eebae70d2465 100644
> > --- a/mm/gup.c
> > +++ b/mm/gup.c
> > @@ -3004,8 +3004,7 @@ static int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr, unsigned lo
> >  		if (!pmd_present(pmd))
> >  			return 0;
> >  
> > -		if (unlikely(pmd_trans_huge(pmd) || pmd_huge(pmd) ||
> > -			     pmd_devmap(pmd))) {
> > +		if (unlikely(pmd_thp_or_huge(pmd) || pmd_devmap(pmd))) {
> >  			/* See gup_pte_range() */
> >  			if (pmd_protnone(pmd))
> >  				return 0;
> 
> And the devmap thing here doesn't make any sense either. The arch
> should ensure that pmd_devmap() implies pmd_leaf(). Since devmap is a
> purely SW construct it almost certainly does already anyhow.

Yep, but only if pmd_leaf() is safe to be put here. A pmd devmap should
always imply as a pmd_leaf() indeed.

Thanks,

-- 
Peter Xu



From yangyicong at huawei.com  Wed Feb 21 01:39:11 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Wed, 21 Feb 2024 17:39:11 +0800
Subject: [PATCH 1/7] drivers/perf: hisi_pcie: Introduce
 hisi_pcie_pmu_get_filter()
In-Reply-To: <20240208121800.000057a2@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
 <20240204074527.47110-2-yangyicong@huawei.com>
 <20240208120643.000042fa@Huawei.com> <20240208121800.000057a2@huawei.com>
Message-ID: <68d4382d-7b1a-f23e-3b33-c2fca708deaf@huawei.com>

On 2024/2/8 20:18, Jonathan Cameron wrote:
> On Thu, 8 Feb 2024 12:06:43 +0000
> Jonathan Cameron <Jonathan.Cameron at Huawei.com> wrote:
> 
>> On Sun, 4 Feb 2024 15:45:21 +0800
>> Yicong Yang <yangyicong at huawei.com> wrote:
>>
>>> From: Yicong Yang <yangyicong at hisilicon.com>
>>>
>>> Factor out retrieving of the register value for the
>>> corresponding event from hisi_pcie_config_filter() into a
>>> new function hisi_pcie_pmu_get_filter() allowing future reuse.
>>>
>>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>  
>>
>> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> 
> On second thoughts, this might benefit from a clearer name.
> Perhaps just call it exactly what it is
> hisi_pcie_pmu_get_ctrl_reg_val_to_set()
> 
> It incorporates the event code as well as the filter.
> Maybe we want to rename pmu_config_filter() as well to
> pmu_config_counter() which I think is the real meaning?
> 

make sense to me. we can simply use the reg name as the suffix,
it'll be more clearer:

hisi_pcie_pmu_get_event_ctrl_val()
hisi_pcie_pmu_config_event_ctrl()

> 
>>
>>> ---
>>>  drivers/perf/hisilicon/hisi_pcie_pmu.c | 13 ++++++++++---
>>>  1 file changed, 10 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>>> index b90ba8aca3fa..11a819cd07f2 100644
>>> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
>>> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>>> @@ -216,10 +216,8 @@ static void hisi_pcie_pmu_writeq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
>>>  	writeq_relaxed(val, pcie_pmu->base + offset);
>>>  }
>>>  
>>> -static void hisi_pcie_pmu_config_filter(struct perf_event *event)
>>> +static u64 hisi_pcie_pmu_get_filter(struct perf_event *event)
>>>  {
>>> -	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
>>> -	struct hw_perf_event *hwc = &event->hw;
>>>  	u64 port, trig_len, thr_len, len_mode;
>>>  	u64 reg = HISI_PCIE_INIT_SET;
>>>  
>>> @@ -256,6 +254,15 @@ static void hisi_pcie_pmu_config_filter(struct perf_event *event)
>>>  	else
>>>  		reg |= FIELD_PREP(HISI_PCIE_LEN_M, HISI_PCIE_LEN_M_DEFAULT);
>>>  
>>> +	return reg;
>>> +}
>>> +
>>> +static void hisi_pcie_pmu_config_filter(struct perf_event *event)
>>> +{
>>> +	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
>>> +	struct hw_perf_event *hwc = &event->hw;
>>> +	u64 reg = hisi_pcie_pmu_get_filter(event);
>>> +
>>>  	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
>>>  }
>>>    
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> .
> 


From romain.gantois at bootlin.com  Wed Feb 21 01:40:06 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Wed, 21 Feb 2024 10:40:06 +0100 (CET)
Subject: [PATCH net-next v3 7/7] net: pcs: rzn1-miic: Init RX clock early
 if MAC requires it
In-Reply-To: <20240212185332.2ebf2935@device-28.home>
References: <20240212-rxc_bugfix-v3-0-e9f2eb6b3b05@bootlin.com> <20240212-rxc_bugfix-v3-7-e9f2eb6b3b05@bootlin.com> <20240212185332.2ebf2935@device-28.home>
Message-ID: <cc90a3d2-4a6a-7274-4ede-cf6ff2f9db17@bootlin.com>

Hi Maxime,

On Mon, 12 Feb 2024, Maxime Chevallier wrote:

> > +static int miic_pre_init(struct phylink_pcs *pcs)
> > +{
> > +	struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs);
> > +	struct miic *miic = miic_port->miic;
> > +	u32 val;
> > +
> > +	/* Start RX clock if required */
> > +	if (pcs->rxc_always_on) {
> > +		/* In MII through mode, the clock signals will be driven by the
> > +		 * external PHY, which might not be initialized yet. Set RMII
> > +		 * as default mode to ensure that a reference clock signal is
> > +		 * generated.
> > +		 */
> > +		miic_port->interface = PHY_INTERFACE_MODE_RMII;
> 
> There's this check in miic_config :
> 
> 	if (interface != miic_port->interface) {
> 		val |= FIELD_PREP(MIIC_CONVCTRL_CONV_SPEED, speed);
> 		mask |= MIIC_CONVCTRL_CONV_SPEED;
> 		miic_port->interface = interface;
> 	}
> 
> As you set the interface to RMII and set the CONV_MODE below without
> really looking at the speed, is there any risk of a mismatch between
> the configured mode and the speed ?
Good point, it is probably necessary to set the default RMII speed in 
miic_pre_init(), since miic_config will not do it if the link mode hasn't 
changed in the meantime. However, this is only an issue if the link isn't 
already up when miic_config() is called. If the link is up, then that means that 
miic_link_up() has already been called and has set the appropriate speed anyway.

Thanks,

-- 
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From yangyicong at huawei.com  Wed Feb 21 01:40:14 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Wed, 21 Feb 2024 17:40:14 +0800
Subject: [PATCH 3/7] drivers/perf: hisi_pcie: Add more events for counting
 TLP bandwidth
In-Reply-To: <20240208122029.000005e1@Huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
 <20240204074527.47110-4-yangyicong@huawei.com>
 <20240208122029.000005e1@Huawei.com>
Message-ID: <9c033974-aa73-2b1d-c997-e3c38e38a859@huawei.com>

On 2024/2/8 20:20, Jonathan Cameron wrote:
> On Sun, 4 Feb 2024 15:45:23 +0800
> Yicong Yang <yangyicong at huawei.com> wrote:
> 
>> From: Yicong Yang <yangyicong at hisilicon.com>
>>
>> A typical PCIe transaction is consisted of various TLP packets in both
>> direction. For counting bandwidth only memory read events are exported
>> currently. Add memory write and completion counting events of both
>> direction to complementation.
> 
> complementation?
> 

sorry for the typo. will fix.

>>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> 
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

Thanks.

> 
>> ---
>>  drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>>
>> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> index 9623bed93876..83be3390686c 100644
>> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> @@ -726,10 +726,18 @@ static struct attribute *hisi_pcie_pmu_events_attr[] = {
>>  	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
>>  	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
>>  	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
>> +	HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_flux, 0x0104),
>> +	HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_time, 0x10104),
>>  	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x0804),
>>  	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x10804),
>> +	HISI_PCIE_PMU_EVENT_ATTR(rx_cpl_flux, 0x2004),
>> +	HISI_PCIE_PMU_EVENT_ATTR(rx_cpl_time, 0x12004),
>> +	HISI_PCIE_PMU_EVENT_ATTR(tx_mwr_flux, 0x0105),
>> +	HISI_PCIE_PMU_EVENT_ATTR(tx_mwr_time, 0x10105),
>>  	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x0405),
>>  	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x10405),
>> +	HISI_PCIE_PMU_EVENT_ATTR(tx_cpl_flux, 0x1005),
>> +	HISI_PCIE_PMU_EVENT_ATTR(tx_cpl_time, 0x11005),
>>  	NULL
>>  };
>>  
> 
> .
> 


From peteryin.openbmc at gmail.com  Wed Feb 21 01:39:15 2024
From: peteryin.openbmc at gmail.com (Peter Yin)
Date: Wed, 21 Feb 2024 17:39:15 +0800
Subject: [PATCH v3 0/9] Revise Meta(Facebook) Harma BMC(AST2600)
Message-ID: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>

Summary:
Revise linux device tree entry related to Meta(Facebook) Harma
specific devices connected to BMC(AST2600) SoC.

Base on : https://lore.kernel.org/all/CACPK8XePx+PvDKzPMjPRn_g9z8yrtAmLvP8Qbepm1AVjuCbaKw at mail.gmail.com/

Change log:

v2 -> v3
  - Patch 0007 - Revise max31790 address
  - Patch 0008 - Harma: Add NIC Fru device
  - Patch 0009 - Add ltc4286 device

v1 -> v2
  - Add infineon,slb9670 information for tpm.
  - Patch 0006 - Add PDB temperature.

v1
  - Patch 0001 - Revise SGPIO line name.
  - Patch 0002 - Mapping ttyS2 to UART4.
  - Patch 0003 - Remove Vuart.
  - Patch 0004 - Add cpu power good line name.
  - Patch 0005 - Add spi-gpio.

Peter Yin (9):
  ARM: dts: aspeed: Harma: Revise SGPIO line name.
  ARM: dts: aspeed: Harma: mapping ttyS2 to UART4.
  ARM: dts: aspeed: Harma: Remove Vuart
  ARM: dts: aspeed: Harma: Add cpu power good line name
  ARM: dts: aspeed: Harma: Add spi-gpio
  ARM: dts: aspeed: Harma: Add PDB temperature
  ARM: dts: aspeed: Harma: Revise max31790 address
  ARM: dts: aspeed: Harma: Add NIC Fru device
  ARM: dts: aspeed: Harma: Add ltc4286 device

 .../dts/aspeed/aspeed-bmc-facebook-harma.dts  | 59 +++++++++++++++----
 1 file changed, 47 insertions(+), 12 deletions(-)

-- 
2.25.1



From peteryin.openbmc at gmail.com  Wed Feb 21 01:39:16 2024
From: peteryin.openbmc at gmail.com (Peter Yin)
Date: Wed, 21 Feb 2024 17:39:16 +0800
Subject: [PATCH v3 1/9] ARM: dts: aspeed: Harma: Revise SGPIO line name.
In-Reply-To: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
References: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
Message-ID: <20240221093925.2393604-2-peteryin.openbmc@gmail.com>

The same name as reset-control-smb-e1s
change to reset-control-smb-e1s-0 and reset-control-smb-e1s-0.

Signed-off-by: Peter Yin <peteryin.openbmc at gmail.com>
---
Summary:
Revise linux device tree entry related to Meta(Facebook) Harma
specific devices connected to BMC(AST2600) SoC.

Base on : https://lore.kernel.org/all/CACPK8XePx+PvDKzPMjPRn_g9z8yrtAmLvP8Qbepm1AVjuCbaKw at mail.gmail.com/

Change log:

v2 -> v3
  - Patch 0007 - Revise max31790 address
  - Patch 0008 - Harma: Add NIC Fru device
  - Patch 0009 - Add ltc4286 device

v1 -> v2
  - Add infineon,slb9670 information for tpm.
  - Patch 0006 - Add PDB temperature.

v1
  - Patch 0001 - Revise SGPIO line name.
  - Patch 0002 - Mapping ttyS2 to UART4.
  - Patch 0003 - Remove Vuart.
  - Patch 0004 - Add cpu power good line name.
  - Patch 0005 - Add spi-gpio.
---

 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
index 7db3f9eb0016..8a173863ef24 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
@@ -505,9 +505,9 @@ &sgpiom0 {
 	"","reset-control-cpu0-p1-mux",
 	"","reset-control-e1s-mux",
 	"power-host-good","reset-control-mb-mux",
-	"","reset-control-smb-e1s",
+	"","reset-control-smb-e1s-0",
 	/*E0-E3 line 64-71*/
-	"","reset-control-smb-e1s",
+	"","reset-control-smb-e1s-1",
 	"host-ready-n","reset-control-srst",
 	"presence-e1s-0","reset-control-usb-hub",
 	"","reset-control",
-- 
2.25.1



From peteryin.openbmc at gmail.com  Wed Feb 21 01:39:17 2024
From: peteryin.openbmc at gmail.com (Peter Yin)
Date: Wed, 21 Feb 2024 17:39:17 +0800
Subject: [PATCH v3 2/9] ARM: dts: aspeed: Harma: mapping ttyS2 to UART4.
In-Reply-To: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
References: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
Message-ID: <20240221093925.2393604-3-peteryin.openbmc@gmail.com>

Change routing to match SOL(Serial Over LAN) settings.

Signed-off-by: Peter Yin <peteryin.openbmc at gmail.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
index 8a173863ef24..a0056d633eb1 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
@@ -12,8 +12,8 @@ / {
 
 	aliases {
 		serial0 = &uart1;
-		serial1 = &uart6;
-		serial2 = &uart2;
+		serial1 = &uart2;
+		serial2 = &uart4;
 		serial4 = &uart5;
 
 		i2c20 = &imux20;
-- 
2.25.1



From peteryin.openbmc at gmail.com  Wed Feb 21 01:39:18 2024
From: peteryin.openbmc at gmail.com (Peter Yin)
Date: Wed, 21 Feb 2024 17:39:18 +0800
Subject: [PATCH v3 3/9] ARM: dts: aspeed: Harma: Remove Vuart
In-Reply-To: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
References: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
Message-ID: <20240221093925.2393604-4-peteryin.openbmc@gmail.com>

Remove vuart to avoid port conflict with uart2

Signed-off-by: Peter Yin <peteryin.openbmc at gmail.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
index a0056d633eb1..5d692e9f541e 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
@@ -100,10 +100,6 @@ &uart_routing {
 	status = "okay";
 };
 
-&vuart1 {
-	status = "okay";
-};
-
 &wdt1 {
 	status = "okay";
 	pinctrl-names = "default";
-- 
2.25.1



From peteryin.openbmc at gmail.com  Wed Feb 21 01:39:19 2024
From: peteryin.openbmc at gmail.com (Peter Yin)
Date: Wed, 21 Feb 2024 17:39:19 +0800
Subject: [PATCH v3 4/9] ARM: dts: aspeed: Harma: Add cpu power good line name
In-Reply-To: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
References: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
Message-ID: <20240221093925.2393604-5-peteryin.openbmc@gmail.com>

Add a line name for cpu power good.

Signed-off-by: Peter Yin <peteryin.openbmc at gmail.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
index 5d692e9f541e..36aad01dda20 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
@@ -501,7 +501,7 @@ &sgpiom0 {
 	"","reset-control-cpu0-p1-mux",
 	"","reset-control-e1s-mux",
 	"power-host-good","reset-control-mb-mux",
-	"","reset-control-smb-e1s-0",
+	"power-cpu-good","reset-control-smb-e1s-0",
 	/*E0-E3 line 64-71*/
 	"","reset-control-smb-e1s-1",
 	"host-ready-n","reset-control-srst",
-- 
2.25.1



From peteryin.openbmc at gmail.com  Wed Feb 21 01:39:20 2024
From: peteryin.openbmc at gmail.com (Peter Yin)
Date: Wed, 21 Feb 2024 17:39:20 +0800
Subject: [PATCH v3 5/9] ARM: dts: aspeed: Harma: Add spi-gpio
In-Reply-To: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
References: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
Message-ID: <20240221093925.2393604-6-peteryin.openbmc@gmail.com>

Add spi-gpio for tpm device.

Signed-off-by: Peter Yin <peteryin.openbmc at gmail.com>
---
 .../dts/aspeed/aspeed-bmc-facebook-harma.dts  | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
index 36aad01dda20..ca3052cce0e0 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
@@ -28,6 +28,8 @@ aliases {
 		i2c29 = &imux29;
 		i2c30 = &imux30;
 		i2c31 = &imux31;
+
+		spi1 = &spi_gpio;
 	};
 
 	chosen {
@@ -67,6 +69,25 @@ led-2 {
 			gpios = <&gpio0 124 GPIO_ACTIVE_HIGH>;
 		};
 	};
+
+	spi_gpio: spi-gpio {
+		status = "okay";
+		compatible = "spi-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		gpio-sck = <&gpio0 ASPEED_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
+		gpio-mosi = <&gpio0 ASPEED_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
+		gpio-miso = <&gpio0 ASPEED_GPIO(Z, 5) GPIO_ACTIVE_HIGH>;
+		num-chipselects = <1>;
+		cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
+
+		tpmdev at 0 {
+			compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+			spi-max-frequency = <33000000>;
+			reg = <0>;
+		};
+	};
 };
 
 // HOST BIOS Debug
-- 
2.25.1



From peteryin.openbmc at gmail.com  Wed Feb 21 01:39:21 2024
From: peteryin.openbmc at gmail.com (Peter Yin)
Date: Wed, 21 Feb 2024 17:39:21 +0800
Subject: [PATCH v3 6/9] ARM: dts: aspeed: Harma: Add PDB temperature
In-Reply-To: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
References: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
Message-ID: <20240221093925.2393604-7-peteryin.openbmc@gmail.com>

Add PDB temperature sensor.

Signed-off-by: Peter Yin <peteryin.openbmc at gmail.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
index ca3052cce0e0..4d5d1c822fa3 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
@@ -260,6 +260,11 @@ delta_brick at 69 {
 		compatible = "pmbus";
 		reg = <0x69>;
 	};
+
+	tmp75 at 49 {
+		compatible = "ti,tmp75";
+		reg = <0x49>;
+	};
 };
 
 &i2c5 {
-- 
2.25.1



From peteryin.openbmc at gmail.com  Wed Feb 21 01:39:22 2024
From: peteryin.openbmc at gmail.com (Peter Yin)
Date: Wed, 21 Feb 2024 17:39:22 +0800
Subject: [PATCH v3 7/9] ARM: dts: aspeed: Harma: Revise max31790 address
In-Reply-To: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
References: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
Message-ID: <20240221093925.2393604-8-peteryin.openbmc@gmail.com>

Revise max31790 address from 0x30 to 0x5e

Signed-off-by: Peter Yin <peteryin.openbmc at gmail.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
index 4d5d1c822fa3..83da7e46bb42 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
@@ -192,9 +192,9 @@ &kcs3 {
 &i2c0 {
 	status = "okay";
 
-	max31790 at 30{
+	max31790 at 5e{
 		compatible = "max31790";
-		reg = <0x30>;
+		reg = <0x5e>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 	};
@@ -212,9 +212,9 @@ tmp75 at 4b {
 &i2c2 {
 	status = "okay";
 
-	max31790 at 30{
+	max31790 at 5e{
 		compatible = "max31790";
-		reg = <0x30>;
+		reg = <0x5e>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 	};
-- 
2.25.1



From peteryin.openbmc at gmail.com  Wed Feb 21 01:39:23 2024
From: peteryin.openbmc at gmail.com (Peter Yin)
Date: Wed, 21 Feb 2024 17:39:23 +0800
Subject: [PATCH v3 8/9] ARM: dts: aspeed: Harma: Add NIC Fru device
In-Reply-To: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
References: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
Message-ID: <20240221093925.2393604-9-peteryin.openbmc@gmail.com>

Add MB NIC Device

Signed-off-by: Peter Yin <peteryin.openbmc at gmail.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
index 83da7e46bb42..d5c5c5b3ab4b 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
@@ -207,6 +207,12 @@ tmp75 at 4b {
 		compatible = "ti,tmp75";
 		reg = <0x4b>;
 	};
+
+	// MB NIC FRU
+	eeprom at 50 {
+		compatible = "atmel,24c64";
+		reg = <0x50>;
+	};
 };
 
 &i2c2 {
-- 
2.25.1



From peteryin.openbmc at gmail.com  Wed Feb 21 01:39:24 2024
From: peteryin.openbmc at gmail.com (Peter Yin)
Date: Wed, 21 Feb 2024 17:39:24 +0800
Subject: [PATCH v3 9/9] ARM: dts: aspeed: Harma: Add ltc4286 device
In-Reply-To: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
References: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
Message-ID: <20240221093925.2393604-10-peteryin.openbmc@gmail.com>

Add ltc4286 device.

Signed-off-by: Peter Yin <peteryin.openbmc at gmail.com>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
index d5c5c5b3ab4b..bbbab8023cd6 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
@@ -271,6 +271,13 @@ tmp75 at 49 {
 		compatible = "ti,tmp75";
 		reg = <0x49>;
 	};
+
+	power-monitor at 22 {
+		compatible = "lltc,ltc4286";
+		reg = <0x22>;
+		adi,vrange-low-enable;
+		shunt-resistor-micro-ohms = <500>;
+	};
 };
 
 &i2c5 {
-- 
2.25.1



From yangyicong at huawei.com  Wed Feb 21 01:46:07 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Wed, 21 Feb 2024 17:46:07 +0800
Subject: [PATCH 4/7] drivers/perf: hisi_pcie: Check the target filter
 properly
In-Reply-To: <20240208122902.0000768f@Huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
 <20240204074527.47110-5-yangyicong@huawei.com>
 <20240208122902.0000768f@Huawei.com>
Message-ID: <03acfe6b-bcde-8a11-ea6d-add1998d5bd1@huawei.com>

On 2024/2/8 20:29, Jonathan Cameron wrote:
> On Sun, 4 Feb 2024 15:45:24 +0800
> Yicong Yang <yangyicong at huawei.com> wrote:
> 
>> From: Junhao He <hejunhao3 at huawei.com>
>>
>> The PMU can monitor traffic of certain target Root Port or downstream
>> target Endpoint. User can specify the target filter by the "port" or
>> "bdf" option respectively. The PMU can only monitor the Root Port or
>> Endpoint on the same PCIe core so the value of "port" or "bdf" should
>> be valid and will be checked by the driver.
>>
>> Currently at least and only one of "port" and "bdf" option must be set.
>> If "port" filter is not set or is set explicitly to zero (default),
>> driver will regard the user specifies a "bdf" option since "port" option
>> is a bitmask of the target Root Ports and zero is not a valid
>> value.
>>
>> If user not explicitly set "port" or "bdf" filter, the driver uses "bdf"
>> default value (zero) to set target filter, but driver will skip the
>> check of bdf=0, although it's a valid value (meaning 0000:000:00.0).
>> Then the user just gets zero.
>>
>> Therefore, we need to check if both "port" and "bdf" are invalid, then
>> return failure and report warning.
>>
>> Testing:
>> before the patch:
>>                    0      hisi_pcie0_core1/rx_mrd_flux/
>>                    0      hisi_pcie0_core1/rx_mrd_flux,port=0/
>>               24,124      hisi_pcie0_core1/rx_mrd_flux,port=1/
>>                    0      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
>>      <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/
> 
> Nice to include an example that works for bdf
> 			    hisi_pcie0_core1/rx_mrd_flux,bdf=1,port=0 
> or something like that?
>>
>> after the patch:
>>      <not supported>      hisi_pcie0_core1/rx_mrd_flux/
>>      <not supported>      hisi_pcie0_core1/rx_mrd_flux,port=0/
>>               24,153      hisi_pcie0_core1/rx_mrd_flux,port=1/
>>      <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
>>      <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/
>>
>> Signed-off-by: Junhao He <hejunhao3 at huawei.com>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> 
> Clearly the current situation is wrong, but perhaps we can
> have a more intuitive scheme (could be added as a follow up patch)
> and have the driver figure out which port the bdf lies below?
> 
> Maybe that's a job for userspace tooling rather than the driver, but
> the driver already has verification code and it wouldn't be hard
> to not just check the rp is ours, but also set the filter to specify
> that rp, or maybe just set the mask to include them all?
> 

To do a check should be simple, we can decode the bdf and find the target
endpoint and related root port for doing the check.

Another example is what we've done in hisi_ptt that we maintian a list of
supported root ports and endpoints, but that will be a bit more complex.

> Jonathan
> 
> 
>> ---
>>  drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++----
>>  1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> index 83be3390686c..b91f03c02c57 100644
>> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> @@ -306,10 +306,10 @@ static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
>>  	if (hisi_pcie_get_trig_len(event) > HISI_PCIE_TRIG_MAX_VAL)
>>  		return false;
>>  
>> -	if (requester_id) {
>> -		if (!hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
>> -			return false;
>> -	}
>> +	/* Need to explicitly set filter of "port" or "bdf" */
>> +	if (!hisi_pcie_get_port(event) &&
>> +	    !hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
>> +		return false;
>>  
>>  	return true;
>>  }
> 
> .
> 


From arnd at arndb.de  Wed Feb 21 01:48:12 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 21 Feb 2024 10:48:12 +0100
Subject: [RFC] arm64: syscall: Direct PRNG kstack randomization
In-Reply-To: <20240221020258.1210148-1-jeremy.linton@arm.com>
References: <20240221020258.1210148-1-jeremy.linton@arm.com>
Message-ID: <938f3418-fd88-476d-b67f-3f7ada98e444@app.fastmail.com>

On Wed, Feb 21, 2024, at 03:02, Jeremy Linton wrote:
> The existing arm64 stack randomization uses the kernel rng to acquire
> 5 bits of address space randomization. This is problematic because it
> creates non determinism in the syscall path when the rng needs to be
> generated or reseeded. This shows up as large tail latencies in some
> benchmarks and directly affects the minimum RT latencies as seen by
> cyclictest.

Hi Jeremy,

I think from your description it's clear that reseeding the
rng is a problem for predictable RT latencies, but at the same
time we have too many things going on to fix this by
special-casing kstack randomization on one architecture:

- if reseeding latency is a problem, can we be sure that
  none of the other ~500 files containing a call to
  get_random_{bytes,long,u8,u16,u32,u64} are in an equally
  critical path for RT? Maybe those are just harder to hit?

- CONFIG_RANDOMIZE_KSTACK_OFFSET can already be disabled
  at compile or at at boot time to avoid the overhead entirely,
  which may be the right thing to do for users that care more
  deeply about syscall latencies than the fairly weak stack
  randomization. Most architectures don't implement it at all.

- It looks like the unpredictable latency from reseeding
  started with f5b98461cb81 ("random: use chacha20 for
  get_random_int/long"), which was intended to make
  get_random() faster and better, but it could be seen
  as  regression for real-time latency guarantees. If this
  turns out to be a general problem for RT workloads,
  the answer might be to bring back an option to make
  get_random() have predictable overhead everywhere
  rather than special-casing the stack randomization.

> Other architectures are using timers/cycle counters for this function,
> which is sketchy from a randomization perspective because it should be
> possible to estimate this value from knowledge of the syscall return
> time, and from reading the current value of the timer/counters.
>
> So, a poor rng should be better than the cycle counter if it is hard
> to extract the stack offsets sufficiently to be able to detect the
> PRNG's period.

I'm not convinced by the argument that the implementation you
have here is less predictable than the cycle counter, but I
have not done any particular research here and would rely on
others to take a closer look. The 32 bit global state variable
does appear weak, and I know that 

OTOH if we can show that a particular implementation is in fact
better than a cycle counter, I strongly think we should
use the same one across all architectures that currently
use the cycle counter.

      Arnd


From u.kleine-koenig at pengutronix.de  Wed Feb 21 01:53:44 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 21 Feb 2024 10:53:44 +0100
Subject: [PATCH 00/11] misc: Convert to platform remove callback returning void
Message-ID: <cover.1708508896.git.u.kleine-koenig@pengutronix.de>

Hello,

this series converts all drivers below drivers/misc to struct
platform_driver::remove_new(). See commit 5c5a7680e67b ("platform:
Provide a remove callback that returns no value") for an extended
explanation and the eventual goal.

All conversations are trivial, because their .remove() callbacks
returned zero unconditionally.

There are no interdependencies between these patches, so they could be
picked up individually. But I'd hope that Greg or Arnd picks them up all
together.

Best regards
Uwe

Uwe Kleine-K?nig (11):
  misc: atmel-ssc: Convert to platform remove callback returning void
  cxl: Convert to platform remove callback returning void
  misc: fastrpc: Convert to platform remove callback returning void
  misc: hisi_hikey_usb: Convert to platform remove callback returning
    void
  mei: vsc: Convert to platform remove callback returning void
  misc: open-dice: Convert to platform remove callback returning void
  misc: sram: Convert to platform remove callback returning void
  misc: ti-st: st_kim: Convert to platform remove callback returning
    void
  misc: vcpu_stall_detector: Convert to platform remove callback
    returning void
  misc: xilinx_sdfec: Convert to platform remove callback returning void
  misc: xilinx_tmr_inject: Convert to platform remove callback returning
    void

 drivers/misc/atmel-ssc.c           | 6 ++----
 drivers/misc/cxl/of.c              | 5 ++---
 drivers/misc/fastrpc.c             | 6 ++----
 drivers/misc/hisi_hikey_usb.c      | 6 ++----
 drivers/misc/mei/platform-vsc.c    | 6 ++----
 drivers/misc/open-dice.c           | 5 ++---
 drivers/misc/sram.c                | 6 ++----
 drivers/misc/ti-st/st_kim.c        | 5 ++---
 drivers/misc/vcpu_stall_detector.c | 6 ++----
 drivers/misc/xilinx_sdfec.c        | 5 ++---
 drivers/misc/xilinx_tmr_inject.c   | 5 ++---
 11 files changed, 22 insertions(+), 39 deletions(-)


base-commit: 4893c639cc3659cefaa675bf1e59f4e7571afb5c
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 21 01:53:54 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 21 Feb 2024 10:53:54 +0100
Subject: [PATCH 10/11] misc: xilinx_sdfec: Convert to platform remove callback returning void
In-Reply-To: <cover.1708508896.git.u.kleine-koenig@pengutronix.de>
References: <cover.1708508896.git.u.kleine-koenig@pengutronix.de>
Message-ID: <705b89c3cd7c0a42ce3f482f202204f5e3377aa2.1708508896.git.u.kleine-koenig@pengutronix.de>

The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.

To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new(), which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().

Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/misc/xilinx_sdfec.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c
index 94a0ee19bf20..ea433695f4c4 100644
--- a/drivers/misc/xilinx_sdfec.c
+++ b/drivers/misc/xilinx_sdfec.c
@@ -1420,7 +1420,7 @@ static int xsdfec_probe(struct platform_device *pdev)
 	return err;
 }
 
-static int xsdfec_remove(struct platform_device *pdev)
+static void xsdfec_remove(struct platform_device *pdev)
 {
 	struct xsdfec_dev *xsdfec;
 
@@ -1428,7 +1428,6 @@ static int xsdfec_remove(struct platform_device *pdev)
 	misc_deregister(&xsdfec->miscdev);
 	ida_free(&dev_nrs, xsdfec->dev_id);
 	xsdfec_disable_all_clks(&xsdfec->clks);
-	return 0;
 }
 
 static const struct of_device_id xsdfec_of_match[] = {
@@ -1445,7 +1444,7 @@ static struct platform_driver xsdfec_driver = {
 		.of_match_table = xsdfec_of_match,
 	},
 	.probe = xsdfec_probe,
-	.remove =  xsdfec_remove,
+	.remove_new =  xsdfec_remove,
 };
 
 module_platform_driver(xsdfec_driver);
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 21 01:53:55 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 21 Feb 2024 10:53:55 +0100
Subject: [PATCH 11/11] misc: xilinx_tmr_inject: Convert to platform remove callback returning void
In-Reply-To: <cover.1708508896.git.u.kleine-koenig@pengutronix.de>
References: <cover.1708508896.git.u.kleine-koenig@pengutronix.de>
Message-ID: <198112757eac0fc004677a4757ce48ae7c7194ab.1708508896.git.u.kleine-koenig@pengutronix.de>

The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.

To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new(), which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().

Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/misc/xilinx_tmr_inject.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/xilinx_tmr_inject.c b/drivers/misc/xilinx_tmr_inject.c
index 9fc5835bfebc..73c6da7d0963 100644
--- a/drivers/misc/xilinx_tmr_inject.c
+++ b/drivers/misc/xilinx_tmr_inject.c
@@ -143,11 +143,10 @@ static int xtmr_inject_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int xtmr_inject_remove(struct platform_device *pdev)
+static void xtmr_inject_remove(struct platform_device *pdev)
 {
 	debugfs_remove_recursive(dbgfs_root);
 	dbgfs_root = NULL;
-	return 0;
 }
 
 static const struct of_device_id xtmr_inject_of_match[] = {
@@ -164,7 +163,7 @@ static struct platform_driver xtmr_inject_driver = {
 		.of_match_table = xtmr_inject_of_match,
 	},
 	.probe = xtmr_inject_probe,
-	.remove = xtmr_inject_remove,
+	.remove_new = xtmr_inject_remove,
 };
 module_platform_driver(xtmr_inject_driver);
 MODULE_AUTHOR("Advanced Micro Devices, Inc");
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Wed Feb 21 01:53:45 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Wed, 21 Feb 2024 10:53:45 +0100
Subject: [PATCH 01/11] misc: atmel-ssc: Convert to platform remove callback returning void
In-Reply-To: <cover.1708508896.git.u.kleine-koenig@pengutronix.de>
References: <cover.1708508896.git.u.kleine-koenig@pengutronix.de>
Message-ID: <45719fc31bb893bb9ab1450057e9cb7f399e9ee2.1708508896.git.u.kleine-koenig@pengutronix.de>

The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.

To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new(), which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().

Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/misc/atmel-ssc.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index ee590c4a1537..6eac0f335915 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -251,7 +251,7 @@ static int ssc_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int ssc_remove(struct platform_device *pdev)
+static void ssc_remove(struct platform_device *pdev)
 {
 	struct ssc_device *ssc = platform_get_drvdata(pdev);
 
@@ -260,8 +260,6 @@ static int ssc_remove(struct platform_device *pdev)
 	mutex_lock(&user_lock);
 	list_del(&ssc->list);
 	mutex_unlock(&user_lock);
-
-	return 0;
 }
 
 static struct platform_driver ssc_driver = {
@@ -271,7 +269,7 @@ static struct platform_driver ssc_driver = {
 	},
 	.id_table	= atmel_ssc_devtypes,
 	.probe		= ssc_probe,
-	.remove		= ssc_remove,
+	.remove_new	= ssc_remove,
 };
 module_platform_driver(ssc_driver);
 
-- 
2.43.0



From angelogioacchino.delregno at collabora.com  Wed Feb 21 01:54:50 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 21 Feb 2024 10:54:50 +0100
Subject: [PATCH v2 2/4] arm64: dts: Add Airoha EN7581 SoC and EN7581
 Evaluation Board
In-Reply-To: <f59389838c741650f6ff05d984a9127545e4eb83.1708473083.git.lorenzo@kernel.org>
References: <cover.1708473083.git.lorenzo@kernel.org>
 <f59389838c741650f6ff05d984a9127545e4eb83.1708473083.git.lorenzo@kernel.org>
Message-ID: <7a623f15-02cc-4508-88e2-da12aaeee242@collabora.com>

Il 21/02/24 01:04, Lorenzo Bianconi ha scritto:
> From: Daniel Danzberger <dd at embedd.com>
> 
> Introduce the Airoha EN7581 SoC's dtsi and the Airoha EN7581 Evaluation
> Board's dts file, as well as the required Makefiles.
> 
> Signed-off-by: Daniel Danzberger <dd at embedd.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
> ---
>   arch/arm64/boot/dts/Makefile              |   1 +
>   arch/arm64/boot/dts/airoha/Makefile       |   2 +
>   arch/arm64/boot/dts/airoha/en7581-evb.dts |  27 +++++
>   arch/arm64/boot/dts/airoha/en7581.dtsi    | 137 ++++++++++++++++++++++
>   4 files changed, 167 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/airoha/Makefile
>   create mode 100644 arch/arm64/boot/dts/airoha/en7581-evb.dts
>   create mode 100644 arch/arm64/boot/dts/airoha/en7581.dtsi
> 
> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> index 30dd6347a929..21cd3a87f385 100644
> --- a/arch/arm64/boot/dts/Makefile
> +++ b/arch/arm64/boot/dts/Makefile
> @@ -1,5 +1,6 @@
>   # SPDX-License-Identifier: GPL-2.0
>   subdir-y += actions
> +subdir-y += airoha
>   subdir-y += allwinner
>   subdir-y += altera
>   subdir-y += amazon
> diff --git a/arch/arm64/boot/dts/airoha/Makefile b/arch/arm64/boot/dts/airoha/Makefile
> new file mode 100644
> index 000000000000..ebea112ce1d7
> --- /dev/null
> +++ b/arch/arm64/boot/dts/airoha/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +dtb-$(CONFIG_ARCH_AIROHA) += en7581-evb.dtb
> diff --git a/arch/arm64/boot/dts/airoha/en7581-evb.dts b/arch/arm64/boot/dts/airoha/en7581-evb.dts
> new file mode 100644
> index 000000000000..4eaa8ac431c3
> --- /dev/null
> +++ b/arch/arm64/boot/dts/airoha/en7581-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 "en7581.dtsi"
> +
> +/ {
> +	model = "Airoha EN7581 Evaluation Board";
> +	compatible = "airoha,en7581-evb", "airoha,en7581";
> +
> +	aliases {
> +		serial0 = &uart1;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200 earlycon";
> +		stdout-path = "serial0:115200n8";
> +		linux,usable-memory-range = <0x0 0x80200000 0x0 0x1fe00000>;
> +	};
> +
> +	memory at 80000000 {
> +		device_type = "memory";
> +		reg = <0x0 0x80000000 0x2 0x00000000>;

Is your bootloader really not filling the size for the memory node?

Can you please verify?
If it doesn't, it's not a problem of course.

> +	};
> +};
> diff --git a/arch/arm64/boot/dts/airoha/en7581.dtsi b/arch/arm64/boot/dts/airoha/en7581.dtsi
> new file mode 100644
> index 000000000000..7a3c0a45c03f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/airoha/en7581.dtsi
> @@ -0,0 +1,137 @@
> +// 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 = <2>;
> +	#size-cells = <2>;
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		npu_binary at 84000000 {

npu-binary at ...

> +			no-map;
> +			reg = <0x0 0x84000000 0x0 0xA00000>;
> +		};
> +
> +		npu_flag at 84B0000 {
> +			no-map;
> +			reg = <0x0 0x84B00000 0x0 0x100000>;
> +		};
> +
> +		npu_pkt at 85000000 {
> +			no-map;
> +			reg = <0x0 0x85000000 0x0 0x1A00000>;
> +		};
> +
> +		npu_phyaddr at 86B00000 {
> +			no-map;
> +			reg = <0x0 0x86B00000 0x0 0x100000>;
> +		};
> +
> +		npu_rxdesc at 86D00000 {
> +			no-map;
> +			reg = <0x0 0x86D00000 0x0 0x100000>;
> +		};
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-0.2";

Not the first time I comment that (in general - not specifically to you): are you
sure that your platform supports PSCI v0.2 and not a later version?

Please check your kernel log, you should see a message like

[    0.000000] psci: PSCIv1.1 detected in firmware.

(with the right version)

...then use the right compatible string :-)

> +		method = "smc";
> +	};
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu-map {
> +			cluster0 {
> +				core0 {
> +					cpu = <&cpu0>;
> +				};
> +				core1 {
> +					cpu = <&cpu1>;
> +				};

Your cluster contains only two cores, this means that the other two are in a
parallel reality? :-P :-P

Jokes apart, this cpu-map looks wrong.

Check what the topology is supposed to be for real, clusterized or DynamIQ?
In the first case, you get X clusters with Y CPUs each - in the second case,
you get *one* single cluster with all CPUs inside.

> +			};
> +		};
> +
> +		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>;
> +		};
> +
> +		cpu2: cpu at 2 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a53";
> +			reg = <0x2>;
> +			enable-method = "psci";
> +			clock-frequency = <80000000>;
> +			next-level-cache = <&L2_0>;
> +		};
> +
> +		cpu3: cpu at 3 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a53";
> +			reg = <0x3>;
> +			enable-method = "psci";
> +			clock-frequency = <80000000>;
> +			next-level-cache = <&L2_0>;
> +		};
> +
> +		L2_0: l2-cache0 {
> +			compatible = "cache";
> +			cache-level = <2>;
> +			cache-unified;

Do you know what is the l2 cache size, line size, sets?
cache-size = < ... >
cache-line-size = < ... >
cache-sets = < ... >

> +		};
> +	};
> +

All iospace addressable nodes must go into a soc node, others go in the root node.

soc {
	gic: interrupt-controller at 9000000 {
		....
	}

	uart0: serial@ ....

};

> +	gic: interrupt-controller at 9000000 {
> +		compatible = "arm,gic-v3";
> +		interrupt-controller;
> +		#interrupt-cells = <3>;
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		reg = <0x0 0x09000000 0x0 0x20000>,
> +		      <0x0 0x09080000 0x0 0x80000>,
> +		      <0x0 0x09400000 0x0 0x2000>,
> +		      <0x0 0x09500000 0x0 0x2000>,
> +		      <0x0 0x09600000 0x0 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 = <0x0 0x1fbf0000 0x0 0x30>;
> +		reg-io-width = <4>;
> +		reg-shift = <2>;
> +		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
> +		clock-frequency = <1843200>;
> +		status = "okay";

status is okay by default, you don't need that.

> +	};
> +};

Cheers,
Angelo


From krzysztof.kozlowski at linaro.org  Wed Feb 21 01:54:54 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 10:54:54 +0100
Subject: [PATCH v3 6/9] ARM: dts: aspeed: Harma: Add PDB temperature
In-Reply-To: <20240221093925.2393604-7-peteryin.openbmc@gmail.com>
References: <20240221093925.2393604-1-peteryin.openbmc@gmail.com>
 <20240221093925.2393604-7-peteryin.openbmc@gmail.com>
Message-ID: <c532285c-6104-473f-be12-a5e833484bd3@linaro.org>

On 21/02/2024 10:39, Peter Yin wrote:
> Add PDB temperature sensor.
> 
> Signed-off-by: Peter Yin <peteryin.openbmc at gmail.com>
> ---
>  arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
> index ca3052cce0e0..4d5d1c822fa3 100644
> --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-harma.dts
> @@ -260,6 +260,11 @@ delta_brick at 69 {
>  		compatible = "pmbus";
>  		reg = <0x69>;
>  	};
> +
> +	tmp75 at 49 {

Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation

Best regards,
Krzysztof



From angelogioacchino.delregno at collabora.com  Wed Feb 21 01:57:28 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 21 Feb 2024 10:57:28 +0100
Subject: [PATCH 2/4] dt-bindings: arm64: dts: mediatek: Add Cudy WR3000 V1
 router
In-Reply-To: <20240221073524.20947-3-zajec5@gmail.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
 <20240221073524.20947-3-zajec5@gmail.com>
Message-ID: <8d80be8a-6ed4-48e3-b792-454e11b518c5@collabora.com>

Il 21/02/24 08:35, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Cudy WR3000 V1 is an MT7981B (AKA Filogic 820) based wireless router.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From balint.dobszay at arm.com  Wed Feb 21 01:58:50 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Wed, 21 Feb 2024 10:58:50 +0100
Subject: [PATCH 2/3] tee: tstee: Add Trusted Services TEE driver
In-Reply-To: <CAHUa44Fzr5zMRkMZUfPNOu+nbAkp+n2FcrgrJ-U8R__qS42fzw@mail.gmail.com>
References: <20240213145239.379875-1-balint.dobszay@arm.com>
 <20240213145239.379875-3-balint.dobszay@arm.com>
 <CAHUa44Fzr5zMRkMZUfPNOu+nbAkp+n2FcrgrJ-U8R__qS42fzw@mail.gmail.com>
Message-ID: <5258E36E-C30B-432F-A7CD-947BE764A463@arm.com>

Hi Jens,

Thanks for the feedback. I noticed that IDR is deprecated now so for the
next version I replaced it with XArray, which also addresses some of the
issues you found.

On 15 Feb 2024, at 11:00, Jens Wiklander wrote:

> Hi Balint,
>
> On Tue, Feb 13, 2024 at 3:54?PM Balint Dobszay <balint.dobszay at arm.com> wrote:
>>
>> The Trusted Services project provides a framework for developing and
>> deploying device Root of Trust services in FF-A Secure Partitions. The
>> FF-A SPs are accessible through the FF-A driver, but this doesn't
>> provide a user space interface. The goal of this TEE driver is to make
>> Trusted Services SPs accessible for user space clients.
>>
>> All TS SPs have the same FF-A UUID, it identifies the RPC protocol used
>> by TS. A TS SP can host one or more services, a service is identified by
>> its service UUID. The same type of service cannot be present twice in
>> the same SP. During SP boot each service in an SP is assigned an
>> interface ID, this is just a short ID to simplify message addressing.
>> There is 1:1 mapping between TS SPs and TEE devices, i.e. a separate TEE
>> device is registered for each TS SP. This is required since contrary to
>> the generic TEE design where memory is shared with the whole TEE
>> implementation, in case of FF-A, memory is shared with a specific SP. A
>> user space client has to be able to separately share memory with each SP
>> based on its endpoint ID.
>>
>> Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
>> ---
>>  drivers/tee/Kconfig               |   1 +
>>  drivers/tee/Makefile              |   1 +
>>  drivers/tee/tstee/Kconfig         |  11 +
>>  drivers/tee/tstee/Makefile        |   3 +
>>  drivers/tee/tstee/core.c          | 501 ++++++++++++++++++++++++++++++
>>  drivers/tee/tstee/tstee_private.h |  92 ++++++
>>  include/uapi/linux/tee.h          |   1 +
>>  7 files changed, 610 insertions(+)
>>  create mode 100644 drivers/tee/tstee/Kconfig
>>  create mode 100644 drivers/tee/tstee/Makefile
>>  create mode 100644 drivers/tee/tstee/core.c
>>  create mode 100644 drivers/tee/tstee/tstee_private.h
>>
>> diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig
>> index 73a147202e88..61b507c18780 100644
>> --- a/drivers/tee/Kconfig
>> +++ b/drivers/tee/Kconfig
>> @@ -15,5 +15,6 @@ if TEE
>>
>>  source "drivers/tee/optee/Kconfig"
>>  source "drivers/tee/amdtee/Kconfig"
>> +source "drivers/tee/tstee/Kconfig"
>>
>>  endif
>> diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
>> index 68da044afbfa..5488cba30bd2 100644
>> --- a/drivers/tee/Makefile
>> +++ b/drivers/tee/Makefile
>> @@ -5,3 +5,4 @@ tee-objs += tee_shm.o
>>  tee-objs += tee_shm_pool.o
>>  obj-$(CONFIG_OPTEE) += optee/
>>  obj-$(CONFIG_AMDTEE) += amdtee/
>> +obj-$(CONFIG_ARM_TSTEE) += tstee/
>> diff --git a/drivers/tee/tstee/Kconfig b/drivers/tee/tstee/Kconfig
>> new file mode 100644
>> index 000000000000..d32f91d47398
>> --- /dev/null
>> +++ b/drivers/tee/tstee/Kconfig
>> @@ -0,0 +1,11 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +config ARM_TSTEE
>> +       tristate "Arm Trusted Services TEE driver"
>> +       depends on ARM_FFA_TRANSPORT
>> +       default n
>> +       help
>> +         The Trusted Services project provides a framework for developing and
>> +         deploying device Root of Trust services in FF-A Secure Partitions.
>> +         This driver provides an interface to make Trusted Services Secure
>> +         Partitions accessible for user space clients, since the FF-A driver
>> +         doesn't implement a user space interface directly.
>> diff --git a/drivers/tee/tstee/Makefile b/drivers/tee/tstee/Makefile
>> new file mode 100644
>> index 000000000000..5227020ebd30
>> --- /dev/null
>> +++ b/drivers/tee/tstee/Makefile
>> @@ -0,0 +1,3 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +arm-tstee-objs := core.o
>> +obj-$(CONFIG_ARM_TSTEE) = arm-tstee.o
>> diff --git a/drivers/tee/tstee/core.c b/drivers/tee/tstee/core.c
>> new file mode 100644
>> index 000000000000..8d6bbe4d03ed
>> --- /dev/null
>> +++ b/drivers/tee/tstee/core.c
>> @@ -0,0 +1,501 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2023, Arm Limited
>> + */
>> +
>> +#define DRIVER_NAME "Arm TSTEE"
>> +#define pr_fmt(fmt) DRIVER_NAME ": " fmt
>> +
>> +#include <linux/arm_ffa.h>
>> +#include <linux/err.h>
>> +#include <linux/errno.h>
>> +#include <linux/kernel.h>
>> +#include <linux/limits.h>
>> +#include <linux/list.h>
>> +#include <linux/mm.h>
>> +#include <linux/module.h>
>> +#include <linux/scatterlist.h>
>> +#include <linux/slab.h>
>> +#include <linux/stat.h>
>> +#include <linux/tee_drv.h>
>> +#include <linux/types.h>
>> +#include <linux/uaccess.h>
>> +
>> +#include "tstee_private.h"
>> +
>> +#define FFA_DIRECT_REQ_ARG_NUM 5
>> +#define FFA_INVALID_MEM_HANDLE U64_MAX
>> +
>> +static void arg_list_to_ffa_data(const u32 *args, struct ffa_send_direct_data *data)
>
> The preferred limit on the length of a single line is 80 columns
> https://www.kernel.org/doc/html/latest/process/coding-style.html#breaking-long-lines-and-strings

Sure, I'll reformat.

>> +{
>> +       data->data0 = args[0];
>> +       data->data1 = args[1];
>> +       data->data2 = args[2];
>> +       data->data3 = args[3];
>> +       data->data4 = args[4];
>> +}
>> +
>> +static void arg_list_from_ffa_data(const struct ffa_send_direct_data *data, u32 *args)
>> +{
>> +       args[0] = lower_32_bits(data->data0);
>> +       args[1] = lower_32_bits(data->data1);
>> +       args[2] = lower_32_bits(data->data2);
>> +       args[3] = lower_32_bits(data->data3);
>> +       args[4] = lower_32_bits(data->data4);
>> +}
>> +
>> +static void tstee_get_version(struct tee_device *teedev, struct tee_ioctl_version_data *vers)
>> +{
>> +       struct tstee *tstee = tee_get_drvdata(teedev);
>> +       struct tee_ioctl_version_data v = {
>> +               .impl_id = TEE_IMPL_ID_TSTEE,
>> +               /* FF-A endpoint ID only uses the lower 16 bits */
>> +               .impl_caps = lower_16_bits(tstee->ffa_dev->vm_id),
>> +               .gen_caps = 0,
>> +       };
>> +
>> +       *vers = v;
>> +}
>> +
>> +static int tstee_open(struct tee_context *ctx)
>> +{
>> +       struct ts_context_data *ctxdata;
>> +
>> +       ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
>> +       if (!ctxdata)
>> +               return -ENOMEM;
>> +
>> +       mutex_init(&ctxdata->mutex);
>> +       idr_init(&ctxdata->sess_ids);
>> +       INIT_LIST_HEAD(&ctxdata->sess_list);
>> +
>> +       ctx->data = ctxdata;
>> +
>> +       return 0;
>> +}
>> +
>> +static void tstee_release(struct tee_context *ctx)
>> +{
>> +       struct ts_context_data *ctxdata = ctx->data;
>> +       struct ts_session *sess, *sess_tmp;
>> +
>> +       if (!ctxdata)
>> +               return;
>> +
>> +       list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list, list_node) {
>> +               list_del(&sess->list_node);
>> +               idr_remove(&ctxdata->sess_ids, sess->session_id);
>> +               kfree(sess);
>> +       }
>> +
>> +       idr_destroy(&ctxdata->sess_ids);
>> +       mutex_destroy(&ctxdata->mutex);
>> +
>> +       kfree(ctxdata);
>> +       ctx->data = NULL;
>> +}
>> +
>> +static struct ts_session *find_session(struct ts_context_data *ctxdata, u32 session_id)
>> +{
>> +       struct ts_session *sess;
>> +
>> +       list_for_each_entry(sess, &ctxdata->sess_list, list_node)
>> +               if (sess->session_id == session_id)
>> +                       return sess;
>
> Since you have an idr, why not use idr_find() instead?

Good point, anyway this got removed due to using XArray.

>> +
>> +       return NULL;
>> +}
>> +
>> +static int tstee_open_session(struct tee_context *ctx, struct tee_ioctl_open_session_arg *arg,
>> +                             struct tee_param *param __always_unused)
>> +{
>> +       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
>> +       struct ffa_device *ffa_dev = tstee->ffa_dev;
>> +       struct ts_context_data *ctxdata = ctx->data;
>> +       struct ffa_send_direct_data ffa_data;
>> +       struct ts_session *sess = NULL;
>> +       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
>> +       int sess_id;
>> +       int rc;
>> +
>> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
>> +                                                                 TS_RPC_OP_SERVICE_INFO);
>> +
>> +       memcpy((u8 *)(ffa_args + TS_RPC_SERVICE_INFO_UUID0), arg->uuid, UUID_SIZE);
>
> Is the cast needed?

It's not needed, removed.

>> +
>> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
>> +       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
>> +       if (rc)
>> +               return rc;
>> +
>> +       arg_list_from_ffa_data(&ffa_data, ffa_args);
>> +
>> +       if (ffa_args[TS_RPC_SERVICE_INFO_RPC_STATUS] != TS_RPC_OK)
>> +               return -ENODEV;
>> +
>> +       if (ffa_args[TS_RPC_SERVICE_INFO_IFACE] > U8_MAX)
>> +               return -EINVAL;
>> +
>> +       sess = kzalloc(sizeof(*sess), GFP_KERNEL);
>> +       if (!sess)
>> +               return -ENOMEM;
>> +
>> +       sess_id = idr_alloc(&ctxdata->sess_ids, sess, 1, 0, GFP_KERNEL);
>
> This needs to be protected by the mutex.

After replacing this with xa_alloc() my understanding is that the mutex
will not be needed here.

>> +       if (sess_id < 0) {
>> +               kfree(sess);
>> +               return sess_id;
>> +       }
>> +
>> +       sess->session_id = sess_id;
>> +       sess->iface_id = ffa_args[TS_RPC_SERVICE_INFO_IFACE];
>> +
>> +       mutex_lock(&ctxdata->mutex);
>> +       list_add(&sess->list_node, &ctxdata->sess_list);
>> +       mutex_unlock(&ctxdata->mutex);
>> +
>> +       arg->session = sess_id;
>> +       arg->ret = 0;
>> +
>> +       return 0;
>> +}
>> +
>> +static int tstee_close_session(struct tee_context *ctx, u32 session)
>> +{
>> +       struct ts_context_data *ctxdata = ctx->data;
>> +       struct ts_session *sess;
>> +
>> +       mutex_lock(&ctxdata->mutex);
>> +       sess = find_session(ctxdata, session);
>> +       if (sess)
>> +               list_del(&sess->list_node);
>> +
>> +       mutex_unlock(&ctxdata->mutex);
>> +
>> +       if (!sess)
>> +               return -EINVAL;
>> +
>> +       idr_remove(&ctxdata->sess_ids, sess->session_id);
>> +       kfree(sess);
>> +
>> +       return 0;
>> +}
>> +
>> +static int tstee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
>> +                            struct tee_param *param)
>> +{
>> +       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
>> +       struct ffa_device *ffa_dev = tstee->ffa_dev;
>> +       struct ts_context_data *ctxdata = ctx->data;
>> +       struct ffa_send_direct_data ffa_data;
>> +       struct tee_shm *shm = NULL;
>> +       struct ts_session *sess;
>> +       u32 req_len, ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
>> +       int shm_id, rc;
>> +       u8 iface_id;
>> +       u64 handle;
>> +       u16 opcode;
>> +
>> +       mutex_lock(&ctxdata->mutex);
>> +       sess = find_session(ctxdata, arg->session);
>> +
>> +       /* Do this while holding the mutex to make sure that the session wasn't closed meanwhile */
>> +       if (sess)
>> +               iface_id = sess->iface_id;
>> +
>> +       mutex_unlock(&ctxdata->mutex);
>> +       if (!sess)
>> +               return -EINVAL;
>> +
>> +       opcode = lower_16_bits(arg->func);
>> +       shm_id = lower_32_bits(param[0].u.value.a);
>> +       req_len = lower_32_bits(param[0].u.value.b);
>> +
>> +       if (shm_id != 0) {
>> +               shm = tee_shm_get_from_id(ctx, shm_id);
>> +               if (IS_ERR(shm))
>> +                       return PTR_ERR(shm);
>> +
>> +               if (shm->size < req_len) {
>> +                       pr_err("request doesn't fit into shared memory buffer\n");
>> +                       rc = -EINVAL;
>> +                       goto out;
>> +               }
>> +
>> +               handle = shm->sec_world_id;
>> +       } else {
>> +               handle = FFA_INVALID_MEM_HANDLE;
>> +       }
>> +
>> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(iface_id, opcode);
>> +       ffa_args[TS_RPC_SERVICE_MEM_HANDLE_LSW] = lower_32_bits(handle);
>> +       ffa_args[TS_RPC_SERVICE_MEM_HANDLE_MSW] = upper_32_bits(handle);
>> +       ffa_args[TS_RPC_SERVICE_REQ_LEN] = req_len;
>> +       ffa_args[TS_RPC_SERVICE_CLIENT_ID] = 0;
>> +
>> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
>> +       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
>> +       if (rc)
>> +               goto out;
>> +
>> +       arg_list_from_ffa_data(&ffa_data, ffa_args);
>> +
>> +       if (ffa_args[TS_RPC_SERVICE_RPC_STATUS] != TS_RPC_OK) {
>> +               pr_err("invoke_func rpc status: %d\n", ffa_args[TS_RPC_SERVICE_RPC_STATUS]);
>> +               rc = -EINVAL;
>> +               goto out;
>> +       }
>> +
>> +       arg->ret = ffa_args[TS_RPC_SERVICE_STATUS];
>> +       if (shm && shm->size >= ffa_args[TS_RPC_SERVICE_RESP_LEN])
>> +               param[0].u.value.a = ffa_args[TS_RPC_SERVICE_RESP_LEN];
>> +
>> +out:
>> +       if (shm)
>> +               tee_shm_put(shm);
>> +
>> +       return rc;
>> +}
>> +
>> +static int tstee_shm_register(struct tee_context *ctx, struct tee_shm *shm, struct page **pages,
>> +                             size_t num_pages, unsigned long start __always_unused)
>> +{
>> +       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
>> +       struct ffa_device *ffa_dev = tstee->ffa_dev;
>> +       struct ffa_mem_region_attributes mem_attr = {
>> +               .receiver = tstee->ffa_dev->vm_id,
>> +               .attrs = FFA_MEM_RW,
>> +               .flag = 0,
>> +       };
>> +       struct ffa_mem_ops_args mem_args = {
>> +               .attrs = &mem_attr,
>> +               .use_txbuf = true,
>> +               .nattrs = 1,
>> +               .flags = 0,
>> +       };
>> +       struct ffa_send_direct_data ffa_data;
>> +       struct sg_table sgt;
>> +       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
>> +       int rc;
>> +
>> +       rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0, num_pages * PAGE_SIZE,
>> +                                      GFP_KERNEL);
>> +       if (rc)
>> +               return rc;
>> +
>> +       mem_args.sg = sgt.sgl;
>> +       rc = ffa_dev->ops->mem_ops->memory_share(&mem_args);
>> +       sg_free_table(&sgt);
>> +       if (rc)
>> +               return rc;
>> +
>> +       shm->sec_world_id = mem_args.g_handle;
>> +
>> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
>> +                                                                 TS_RPC_OP_RETRIEVE_MEM);
>> +       ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_LSW] = lower_32_bits(shm->sec_world_id);
>> +       ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_MSW] = upper_32_bits(shm->sec_world_id);
>> +       ffa_args[TS_RPC_RETRIEVE_MEM_TAG_LSW] = 0;
>> +       ffa_args[TS_RPC_RETRIEVE_MEM_TAG_MSW] = 0;
>> +
>> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
>> +       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
>> +       if (rc) {
>> +               (void)ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
>> +               return rc;
>> +       }
>> +
>> +       arg_list_from_ffa_data(&ffa_data, ffa_args);
>> +
>> +       if (ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS] != TS_RPC_OK) {
>> +               pr_err("shm_register rpc status: %d\n", ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS]);
>> +               ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
>> +               return -EINVAL;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int tstee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
>> +{
>> +       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
>> +       struct ffa_device *ffa_dev = tstee->ffa_dev;
>> +       struct ffa_send_direct_data ffa_data;
>> +       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
>> +       int rc;
>> +
>> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
>> +                                                                 TS_RPC_OP_RELINQ_MEM);
>> +       ffa_args[TS_RPC_RELINQ_MEM_HANDLE_LSW] = lower_32_bits(shm->sec_world_id);
>> +       ffa_args[TS_RPC_RELINQ_MEM_HANDLE_MSW] = upper_32_bits(shm->sec_world_id);
>> +
>> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
>> +       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
>> +       if (rc)
>> +               return rc;
>> +       arg_list_from_ffa_data(&ffa_data, ffa_args);
>> +
>> +       if (ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS] != TS_RPC_OK) {
>> +               pr_err("shm_unregister rpc status: %d\n", ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS]);
>> +               return -EINVAL;
>> +       }
>> +
>> +       rc = ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
>> +
>> +       return rc;
>> +}
>> +
>> +static const struct tee_driver_ops tstee_ops = {
>> +       .get_version = tstee_get_version,
>> +       .open = tstee_open,
>> +       .release = tstee_release,
>> +       .open_session = tstee_open_session,
>> +       .close_session = tstee_close_session,
>> +       .invoke_func = tstee_invoke_func,
>> +       .shm_register = tstee_shm_register,
>> +       .shm_unregister = tstee_shm_unregister,
>> +};
>> +
>> +static const struct tee_desc tstee_desc = {
>> +       .name = "tstee-clnt",
>> +       .ops = &tstee_ops,
>> +       .owner = THIS_MODULE,
>> +};
>> +
>> +static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm, size_t size, size_t align)
>> +{
>> +       return tee_shm_pool_op_alloc_helper(pool, shm, size, align, tstee_shm_register);
>> +}
>> +
>> +static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm)
>> +{
>> +       tee_shm_pool_op_free_helper(pool, shm, tstee_shm_unregister);
>> +}
>> +
>> +static void pool_op_destroy_pool(struct tee_shm_pool *pool)
>> +{
>> +       kfree(pool);
>> +}
>> +
>> +static const struct tee_shm_pool_ops pool_ops = {
>> +       .alloc = pool_op_alloc,
>> +       .free = pool_op_free,
>> +       .destroy_pool = pool_op_destroy_pool,
>> +};
>> +
>> +static struct tee_shm_pool *tstee_create_shm_pool(void)
>> +{
>> +       struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
>> +
>> +       if (!pool)
>> +               return ERR_PTR(-ENOMEM);
>> +
>> +       pool->ops = &pool_ops;
>> +
>> +       return pool;
>> +}
>> +
>> +static bool tstee_check_rpc_compatible(struct ffa_device *ffa_dev)
>> +{
>> +       struct ffa_send_direct_data ffa_data;
>> +       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
>> +
>> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
>> +                                                                 TS_RPC_OP_GET_VERSION);
>> +
>> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
>> +       if (ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data))
>> +               return false;
>> +
>> +       arg_list_from_ffa_data(&ffa_data, ffa_args);
>> +
>> +       return ffa_args[TS_RPC_GET_VERSION_RESP] == TS_RPC_PROTOCOL_VERSION;
>> +}
>> +
>> +static void tstee_deinit_common(struct tstee *tstee)
>> +{
>> +       tee_device_unregister(tstee->teedev);
>> +       if (tstee->pool)
>> +               tee_shm_pool_free(tstee->pool);
>> +
>> +       kfree(tstee);
>> +}
>> +
>> +static int tstee_probe(struct ffa_device *ffa_dev)
>> +{
>> +       struct tstee *tstee;
>> +       int rc;
>> +
>> +       ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev);
>> +
>> +       if (!tstee_check_rpc_compatible(ffa_dev))
>> +               return -EINVAL;
>> +
>> +       tstee = kzalloc(sizeof(*tstee), GFP_KERNEL);
>> +       if (!tstee)
>> +               return -ENOMEM;
>> +
>> +       tstee->ffa_dev = ffa_dev;
>> +
>> +       tstee->pool = tstee_create_shm_pool();
>> +       if (IS_ERR(tstee->pool)) {
>> +               rc = PTR_ERR(tstee->pool);
>> +               tstee->pool = NULL;
>> +               goto err;
>> +       }
>> +
>> +       tstee->teedev = tee_device_alloc(&tstee_desc, NULL, tstee->pool, tstee);
>> +       if (IS_ERR(tstee->teedev)) {
>> +               rc = PTR_ERR(tstee->teedev);
>> +               tstee->teedev = NULL;
>> +               goto err;
>> +       }
>> +
>> +       rc = tee_device_register(tstee->teedev);
>> +       if (rc)
>> +               goto err;
>> +
>> +       ffa_dev_set_drvdata(ffa_dev, tstee);
>> +
>> +       pr_info("driver initialized for endpoint 0x%x\n", ffa_dev->vm_id);
>> +
>> +       return 0;
>> +
>> +err:
>> +       tstee_deinit_common(tstee);
>> +       return rc;
>> +}
>> +
>> +static void tstee_remove(struct ffa_device *ffa_dev)
>> +{
>> +       tstee_deinit_common(ffa_dev->dev.driver_data);
>> +}
>> +
>> +static const struct ffa_device_id tstee_device_ids[] = {
>> +       /* TS RPC protocol UUID: bdcd76d7-825e-4751-963b-86d4f84943ac */
>> +       { TS_RPC_UUID },
>> +       {}
>> +};
>> +
>> +static struct ffa_driver tstee_driver = {
>> +       .name = "arm_tstee",
>> +       .probe = tstee_probe,
>> +       .remove = tstee_remove,
>> +       .id_table = tstee_device_ids,
>> +};
>> +
>> +static int __init mod_init(void)
>> +{
>> +       return ffa_register(&tstee_driver);
>> +}
>> +module_init(mod_init)
>> +
>> +static void __exit mod_exit(void)
>> +{
>> +       ffa_unregister(&tstee_driver);
>> +}
>> +module_exit(mod_exit)
>> +
>> +MODULE_ALIAS("arm-tstee");
>> +MODULE_AUTHOR("Balint Dobszay <balint.dobszay at arm.com>");
>> +MODULE_DESCRIPTION("Arm Trusted Services TEE driver");
>> +MODULE_LICENSE("GPL");
>> diff --git a/drivers/tee/tstee/tstee_private.h b/drivers/tee/tstee/tstee_private.h
>> new file mode 100644
>> index 000000000000..81eeda220a5c
>> --- /dev/null
>> +++ b/drivers/tee/tstee/tstee_private.h
>> @@ -0,0 +1,92 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (c) 2023, Arm Limited
>> + */
>> +
>> +#ifndef TSTEE_PRIVATE_H
>> +#define TSTEE_PRIVATE_H
>> +
>> +#include <linux/arm_ffa.h>
>> +#include <linux/bitops.h>
>> +#include <linux/idr.h>
>> +#include <linux/tee_drv.h>
>> +#include <linux/types.h>
>> +#include <linux/uuid.h>
>> +
>> +/* UUID of this protocol */
>
> It would be nice to have a link or reference to the description of the ABI.

The link for the ABI definition is available in the documentation, but
I'll add it here too.

>> +#define TS_RPC_UUID UUID_INIT(0xbdcd76d7, 0x825e, 0x4751, \
>> +                             0x96, 0x3b, 0x86, 0xd4, 0xf8, 0x49, 0x43, 0xac)
>> +
>> +/* Protocol version*/
>> +#define TS_RPC_PROTOCOL_VERSION                (1)
>> +
>> +/* Status codes */
>> +#define TS_RPC_OK                      (0)
>> +
>> +/* RPC control register */
>> +#define TS_RPC_CTRL_REG                        (0)
>> +#define OPCODE_MASK                    GENMASK(15, 0)
>> +#define IFACE_ID_MASK                  GENMASK(23, 16)
>> +#define TS_RPC_CTRL_OPCODE(x)          ((u16)(FIELD_GET(OPCODE_MASK, (x))))
>> +#define TS_RPC_CTRL_IFACE_ID(x)                ((u8)(FIELD_GET(IFACE_ID_MASK, (x))))
>> +#define TS_RPC_CTRL_PACK_IFACE_OPCODE(i, o)    \
>> +       (FIELD_PREP(IFACE_ID_MASK, (i)) | FIELD_PREP(OPCODE_MASK, (o)))
>> +#define TS_RPC_CTRL_SAP_RC             BIT(30)
>> +#define TS_RPC_CTRL_SAP_ERR            BIT(31)
>> +
>> +/* Interface ID for RPC management operations */
>> +#define TS_RPC_MGMT_IFACE_ID           (0xff)
>> +
>> +/* Management calls */
>> +#define TS_RPC_OP_GET_VERSION          (0x0000)
>> +#define TS_RPC_GET_VERSION_RESP                (1)
>> +
>> +#define TS_RPC_OP_RETRIEVE_MEM         (0x0001)
>> +#define TS_RPC_RETRIEVE_MEM_HANDLE_LSW (1)
>> +#define TS_RPC_RETRIEVE_MEM_HANDLE_MSW (2)
>> +#define TS_RPC_RETRIEVE_MEM_TAG_LSW    (3)
>> +#define TS_RPC_RETRIEVE_MEM_TAG_MSW    (4)
>> +#define TS_RPC_RETRIEVE_MEM_RPC_STATUS (1)
>> +
>> +#define TS_RPC_OP_RELINQ_MEM           (0x0002)
>> +#define TS_RPC_RELINQ_MEM_HANDLE_LSW   (1)
>> +#define TS_RPC_RELINQ_MEM_HANDLE_MSW   (2)
>> +#define TS_RPC_RELINQ_MEM_RPC_STATUS   (1)
>> +
>> +#define TS_RPC_OP_SERVICE_INFO         (0x0003)
>> +#define TS_RPC_SERVICE_INFO_UUID0      (1)
>> +#define TS_RPC_SERVICE_INFO_UUID1      (2)
>> +#define TS_RPC_SERVICE_INFO_UUID2      (3)
>> +#define TS_RPC_SERVICE_INFO_UUID3      (4)
>> +#define TS_RPC_SERVICE_INFO_RPC_STATUS (1)
>> +#define TS_RPC_SERVICE_INFO_IFACE      (2)
>> +
>> +/* Service call */
>> +#define TS_RPC_SERVICE_MEM_HANDLE_LSW  (1)
>> +#define TS_RPC_SERVICE_MEM_HANDLE_MSW  (2)
>> +#define TS_RPC_SERVICE_REQ_LEN         (3)
>> +#define TS_RPC_SERVICE_CLIENT_ID       (4)
>> +#define TS_RPC_SERVICE_RPC_STATUS      (1)
>> +#define TS_RPC_SERVICE_STATUS          (2)
>> +#define TS_RPC_SERVICE_RESP_LEN                (3)
>> +
>> +struct tstee {
>> +       struct ffa_device *ffa_dev;
>> +       struct tee_device *teedev;
>> +       struct tee_shm_pool *pool;
>> +};
>> +
>> +struct ts_session {
>> +       struct list_head list_node;
>> +       u32 session_id;
>> +       u8 iface_id;
>> +};
>> +
>> +struct ts_context_data {
>> +       struct list_head sess_list;
>> +       struct idr sess_ids;
>
> Why do you need both a linked list and an IDR? Wouldn't the IDR be enough?

You're right, I added the IDR later and didn't realise this made the
linked list redundant. I removed both the linked list and IDR and just
use XArray instead.

Regards,
Balint

>> +       /* Serializes access to this struct */
>> +       struct mutex mutex;
>> +};
>> +
>> +#endif /* TSTEE_PRIVATE_H */
>> diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
>> index 23e57164693c..d0430bee8292 100644
>> --- a/include/uapi/linux/tee.h
>> +++ b/include/uapi/linux/tee.h
>> @@ -56,6 +56,7 @@
>>   */
>>  #define TEE_IMPL_ID_OPTEE      1
>>  #define TEE_IMPL_ID_AMDTEE     2
>> +#define TEE_IMPL_ID_TSTEE      3
>>
>>  /*
>>   * OP-TEE specific capabilities
>> --
>> 2.34.1
>>


From angelogioacchino.delregno at collabora.com  Wed Feb 21 02:00:44 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 21 Feb 2024 11:00:44 +0100
Subject: [PATCH 3/4] arm64: dts: mediatek: mt7981: add pinctrl
In-Reply-To: <20240221073524.20947-4-zajec5@gmail.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
 <20240221073524.20947-4-zajec5@gmail.com>
Message-ID: <770b23ec-7199-4202-888d-6a22b7f4af74@collabora.com>

Il 21/02/24 08:35, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7981 contains on-SoC PIN controller that is also a GPIO provider.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>   arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 37 +++++++++++++++++++++++
>   1 file changed, 37 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
> index 4feff3d1c5f4..fdd5c22cfc9c 100644
> --- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
> @@ -86,6 +86,43 @@ pwm at 10048000 {
>   			#pwm-cells = <2>;
>   		};
>   
> +		pio: pinctrl at 11d00000 {
> +			compatible = "mediatek,mt7981-pinctrl";
> +			reg = <0 0x11d00000 0 0x1000>,
> +			      <0 0x11c00000 0 0x1000>,
> +			      <0 0x11c10000 0 0x1000>,
> +			      <0 0x11d20000 0 0x1000>,
> +			      <0 0x11e00000 0 0x1000>,
> +			      <0 0x11e20000 0 0x1000>,
> +			      <0 0x11f00000 0 0x1000>,
> +			      <0 0x11f10000 0 0x1000>,
> +			      <0 0x1000b000 0 0x1000>;
> +			reg-names = "gpio", "iocfg_rt", "iocfg_rm", "iocfg_rb", "iocfg_lb",
> +				    "iocfg_bl", "iocfg_tm", "iocfg_tl", "eint";
> +			interrupt-controller;
> +			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-parent = <&gic>;
> +			gpio-ranges = <&pio 0 0 56>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			#interrupt-cells = <2>;
> +
> +			mdio-pins {
> +				mux {

That's board specific. MDIO and SPI0 pins can be used as GPIO instead of,
respectively, ETH and SPI.

Must go to your board devicetree, not here: please move both.

Cheers,
Angelo

> +					function = "eth";
> +					groups = "smi_mdc_mdio";
> +				};
> +			};
> +
> +			spi0-pins {
> +				mux {
> +					function = "spi";
> +					groups = "spi0", "spi0_wp_hold";
> +				};
> +			};
> +
> +		};
> +
>   		clock-controller at 15000000 {
>   			compatible = "mediatek,mt7981-ethsys", "syscon";
>   			reg = <0 0x15000000 0 0x1000>;



From james.clark at arm.com  Wed Feb 21 02:10:18 2024
From: james.clark at arm.com (James Clark)
Date: Wed, 21 Feb 2024 10:10:18 +0000
Subject: [PATCH v5 3/7] arm64/sysreg/tools: Move TRFCR definitions to
 sysreg
In-Reply-To: <18995343-e43e-4e92-a97d-3df74ec6ddb7@sirena.org.uk>
References: <20240220100924.2761706-1-james.clark@arm.com>
 <20240220100924.2761706-4-james.clark@arm.com>
 <18995343-e43e-4e92-a97d-3df74ec6ddb7@sirena.org.uk>
Message-ID: <c1e159b7-c884-e498-6b01-64a897117036@arm.com>



On 20/02/2024 16:11, Mark Brown wrote:
> On Tue, Feb 20, 2024 at 10:09:13AM +0000, James Clark wrote:
>> Add separate definitions for ELx and EL2 as TRFCR_EL1 doesn't have CX.
>> This also mirrors the previous definition so no code change is required.
> 
> This is also converting to automatic generation in the process.
> 
>> +SysregFields TRFCR_EL2
>> +Res0	63:7
>> +UnsignedEnum	6:5	TS
>> +	0b0000	USE_TRFCR_EL1_TS
>> +	0b0001	VIRTUAL
>> +	0b0010	GUEST_PHYSICAL
>> +	0b0011	PHYSICAL
>> +EndEnum
>> +Res0	4
>> +Field	3	CX
>> +Res0	2
>> +Field	1	E2TRE
>> +Field	0	E0HTRE
>> +EndSysregFields
> 
> This has exactly one user and I'd not expect more so why have a separate
> SysregFields?
> 

No reason, probably just a copy paste thing. I'll change it to a Sysreg.

>> +# TRFCR_EL1 doesn't have the CX bit so redefine it without CX instead of
>> +# using a shared definition between TRFCR_EL2 and TRFCR_EL1
> 
> This comment is reflecting the default state?
> 

True, will remove.

>> +Sysreg	TRFCR_EL1	3	0	1	2	1
>> +Fields	TRFCR_ELx
>> +EndSysreg
>> +
>> +Sysreg	TRFCR_EL2	3	4	1	2	1
>> +Fields	TRFCR_EL2
>> +EndSysreg
>> +
>> +Sysreg	TRFCR_EL12	3	5	1	2	1
>> +Fields	TRFCR_ELx
>> +EndSysreg
> 
> These are generally sorted by encoding (simiarly to how sysreg.h was
> sorted historically).

Ah I didn't know that. Can I add a comment to the top of the file saying
that it should be kept sorted?


From angelogioacchino.delregno at collabora.com  Wed Feb 21 02:11:14 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 21 Feb 2024 11:11:14 +0100
Subject: [PATCH 4/4] arm64: dts: mediatek: Add Cudy WR3000 V1
In-Reply-To: <20240221073524.20947-5-zajec5@gmail.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
 <20240221073524.20947-5-zajec5@gmail.com>
Message-ID: <2fdf724e-4994-4873-971a-56c19b9fc471@collabora.com>

Il 21/02/24 08:35, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Cudy WR3000 V1 is an MT7981B (AKA Filogic 820) based wireless router. It
> has 256 MiB of RAM, some LEDs & buttons and (not described yet) 4
> Ethernet ports.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>   arch/arm64/boot/dts/mediatek/Makefile         |  1 +
>   .../dts/mediatek/mt7981b-cudy-wr3000-v1.dts   | 74 +++++++++++++++++++
>   2 files changed, 75 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
> 
> diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
> index 37b4ca3a87c9..96da4ad640aa 100644
> --- a/arch/arm64/boot/dts/mediatek/Makefile
> +++ b/arch/arm64/boot/dts/mediatek/Makefile
> @@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-cudy-wr3000-v1.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-xiaomi-ax3000t.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-acelink-ew-7886cax.dtb
>   dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb
> diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
> new file mode 100644
> index 000000000000..cb36a089518a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
> @@ -0,0 +1,74 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +
> +/dts-v1/;
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/leds/common.h>
> +
> +#include "mt7981b.dtsi"
> +
> +/ {
> +	compatible = "cudy,wr3000-v1", "mediatek,mt7981b";
> +	model = "Cudy WR3000 V1";
> +
> +	memory at 40000000 {
> +		reg = <0 0x40000000 0 0x10000000>;
> +		device_type = "memory";
> +	};
> +
> +	keys {
> +		compatible = "gpio-keys";
> +
> +		key-wps {
> +			label = "WPS";
> +			gpios = <&pio 0 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_WPS_BUTTON>;
> +		};
> +
> +		key-reset {
> +			label = "RESET";
> +			gpios = <&pio 1 GPIO_ACTIVE_LOW>;
> +			linux,code = <KEY_RESTART>;
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		led-0 {
> +			function = LED_FUNCTION_WAN;
> +			color = <LED_COLOR_ID_BLUE>;
> +			gpios = <&pio 5 GPIO_ACTIVE_LOW>;

Can we please order those properties alphabetically, as it doesn't impact
on human readability in any way?
Just a nitpick, anyway.

color = <LED_COLOR_ID_BLUE>;
function = LED_FUNCTION_WAN;
gpios = <&pio 5 GPIO_ACTIVE_LOW>;

> +		};
> +
> +		led-1 {
> +			function = LED_FUNCTION_WLAN_2GHZ;
> +			color = <LED_COLOR_ID_BLUE>;
> +			gpios = <&pio 6 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		led-2 {
> +			function = LED_FUNCTION_WLAN_5GHZ;
> +			color = <LED_COLOR_ID_BLUE>;
> +			gpios = <&pio 7 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		led-3 {
> +			function = LED_FUNCTION_LAN;
> +			color = <LED_COLOR_ID_BLUE>;
> +			gpios = <&pio 9 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		led-4 {
> +			function = LED_FUNCTION_STATUS;
> +			color = <LED_COLOR_ID_BLUE>;
> +			gpios = <&pio 10 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		led-5 {
> +			function = "online";

Uhm, what does "online" mean?

Are you sure that you can't use any of the LED_FUNCTION_XXX standard definitions?

Cheers,
Angelo



From angelogioacchino.delregno at collabora.com  Wed Feb 21 02:15:09 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 21 Feb 2024 11:15:09 +0100
Subject: [PATCH] arm64: dts: mediatek: mt7981: add watchdog & WiFi
 controllers
In-Reply-To: <20240221085547.27840-1-zajec5@gmail.com>
References: <20240221085547.27840-1-zajec5@gmail.com>
Message-ID: <d5535a86-17d6-40c1-ae8e-df9fc0425866@collabora.com>

Il 21/02/24 09:55, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7981 (Filogic 820) is a low cost version of MT7986 (Filogic 830) with
> the same watchdog controller. It also comes with on-SoC 802.11ax
> wireless.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From maz at kernel.org  Wed Feb 21 02:17:11 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 21 Feb 2024 10:17:11 +0000
Subject: [GIT PULL] KVM/arm64 fixes for 6.8, take #3
Message-ID: <20240221101711.2105066-1-maz@kernel.org>

Hey Paolo,

Another week, another couple of fixes. This time, two fixes for the
ITS emulation that could result in non-existent LPIs being used, with
unpredictable consequences. Thanks to Oliver for spotting those as he
was reworking the ITS translation cache.

Please pull,

	M.

The following changes since commit c60d847be7b8e69e419e02a2b3d19c2842a3c35d:

  KVM: arm64: Fix double-free following kvm_pgtable_stage2_free_unlinked() (2024-02-13 19:22:03 +0000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-fixes-6.8-3

for you to fetch changes up to 85a71ee9a0700f6c18862ef3b0011ed9dad99aca:

  KVM: arm64: vgic-its: Test for valid IRQ in MOVALL handler (2024-02-21 10:06:41 +0000)

----------------------------------------------------------------
KVM/arm64 fixes for 6.8, take #3

- Check for the validity of interrupts handled by a MOVALL
  command

- Check for the validity of interrupts while reading the
  pending state on enabling LPIs.

----------------------------------------------------------------
Oliver Upton (2):
      KVM: arm64: vgic-its: Test for valid IRQ in its_sync_lpi_pending_table()
      KVM: arm64: vgic-its: Test for valid IRQ in MOVALL handler

 arch/arm64/kvm/vgic/vgic-its.c | 5 +++++
 1 file changed, 5 insertions(+)


From zajec5 at gmail.com  Wed Feb 21 02:18:50 2024
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Wed, 21 Feb 2024 11:18:50 +0100
Subject: [PATCH 4/4] arm64: dts: mediatek: Add Cudy WR3000 V1
In-Reply-To: <2fdf724e-4994-4873-971a-56c19b9fc471@collabora.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
 <20240221073524.20947-5-zajec5@gmail.com>
 <2fdf724e-4994-4873-971a-56c19b9fc471@collabora.com>
Message-ID: <b4e8d3c6-5113-4324-9af5-c4e89cd89349@gmail.com>

On 21.02.2024 11:11, AngeloGioacchino Del Regno wrote:
> Il 21/02/24 08:35, Rafa? Mi?ecki ha scritto:
>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>
>> Cudy WR3000 V1 is an MT7981B (AKA Filogic 820) based wireless router. It
>> has 256 MiB of RAM, some LEDs & buttons and (not described yet) 4
>> Ethernet ports.
>>
>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>> ---
>> ? arch/arm64/boot/dts/mediatek/Makefile???????? |? 1 +
>> ? .../dts/mediatek/mt7981b-cudy-wr3000-v1.dts?? | 74 +++++++++++++++++++
>> ? 2 files changed, 75 insertions(+)
>> ? create mode 100644 arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
>>
>> diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
>> index 37b4ca3a87c9..96da4ad640aa 100644
>> --- a/arch/arm64/boot/dts/mediatek/Makefile
>> +++ b/arch/arm64/boot/dts/mediatek/Makefile
>> @@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
>> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-cudy-wr3000-v1.dtb
>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-xiaomi-ax3000t.dtb
>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-acelink-ew-7886cax.dtb
>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb
>> diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
>> new file mode 100644
>> index 000000000000..cb36a089518a
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
>> @@ -0,0 +1,74 @@
>> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
>> +
>> +/dts-v1/;
>> +#include <dt-bindings/input/input.h>
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include <dt-bindings/leds/common.h>
>> +
>> +#include "mt7981b.dtsi"
>> +
>> +/ {
>> +??? compatible = "cudy,wr3000-v1", "mediatek,mt7981b";
>> +??? model = "Cudy WR3000 V1";
>> +
>> +??? memory at 40000000 {
>> +??????? reg = <0 0x40000000 0 0x10000000>;
>> +??????? device_type = "memory";
>> +??? };
>> +
>> +??? keys {
>> +??????? compatible = "gpio-keys";
>> +
>> +??????? key-wps {
>> +??????????? label = "WPS";
>> +??????????? gpios = <&pio 0 GPIO_ACTIVE_LOW>;
>> +??????????? linux,code = <KEY_WPS_BUTTON>;
>> +??????? };
>> +
>> +??????? key-reset {
>> +??????????? label = "RESET";
>> +??????????? gpios = <&pio 1 GPIO_ACTIVE_LOW>;
>> +??????????? linux,code = <KEY_RESTART>;
>> +??????? };
>> +??? };
>> +
>> +??? leds {
>> +??????? compatible = "gpio-leds";
>> +
>> +??????? led-0 {
>> +??????????? function = LED_FUNCTION_WAN;
>> +??????????? color = <LED_COLOR_ID_BLUE>;
>> +??????????? gpios = <&pio 5 GPIO_ACTIVE_LOW>;
> 
> Can we please order those properties alphabetically, as it doesn't impact
> on human readability in any way?
> Just a nitpick, anyway.
> 
> color = <LED_COLOR_ID_BLUE>;
> function = LED_FUNCTION_WAN;
> gpios = <&pio 5 GPIO_ACTIVE_LOW>;

If I understand [1] correctly alphabetical / alpha-numerical order
applies to non-addresses nodes only.

Here I put "function" first as that seemed more important than a color.

Perhaps you could suggest an addition to Devicetree Sources (DTS) Coding
Style or point me to the missed part, please?

[1] https://www.kernel.org/doc/html/next/devicetree/bindings/dts-coding-style.html#order-of-properties-in-device-node



>> +??????? };
>> +
>> +??????? led-1 {
>> +??????????? function = LED_FUNCTION_WLAN_2GHZ;
>> +??????????? color = <LED_COLOR_ID_BLUE>;
>> +??????????? gpios = <&pio 6 GPIO_ACTIVE_LOW>;
>> +??????? };
>> +
>> +??????? led-2 {
>> +??????????? function = LED_FUNCTION_WLAN_5GHZ;
>> +??????????? color = <LED_COLOR_ID_BLUE>;
>> +??????????? gpios = <&pio 7 GPIO_ACTIVE_LOW>;
>> +??????? };
>> +
>> +??????? led-3 {
>> +??????????? function = LED_FUNCTION_LAN;
>> +??????????? color = <LED_COLOR_ID_BLUE>;
>> +??????????? gpios = <&pio 9 GPIO_ACTIVE_LOW>;
>> +??????? };
>> +
>> +??????? led-4 {
>> +??????????? function = LED_FUNCTION_STATUS;
>> +??????????? color = <LED_COLOR_ID_BLUE>;
>> +??????????? gpios = <&pio 10 GPIO_ACTIVE_LOW>;
>> +??????? };
>> +
>> +??????? led-5 {
>> +??????????? function = "online";
> 
> Uhm, what does "online" mean?
> 
> Are you sure that you can't use any of the LED_FUNCTION_XXX standard definitions?

This device has:
1. "WAN Port" LED that indicates "WAN Port has connection" state
2. "Internet" LED that indicates "Connected to the Internet" state

I couldn't find any define that would fit Internet access LED case.


From pbonzini at redhat.com  Wed Feb 21 02:22:04 2024
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Wed, 21 Feb 2024 11:22:04 +0100
Subject: [GIT PULL] KVM/arm64 fixes for 6.8, take #3
In-Reply-To: <20240221101711.2105066-1-maz@kernel.org>
References: <20240221101711.2105066-1-maz@kernel.org>
Message-ID: <CABgObfYhVK+qF25h8+hhuyCvbgfpocDo0UDac3CTEHghRGww+w@mail.gmail.com>

On Wed, Feb 21, 2024 at 11:17?AM Marc Zyngier <maz at kernel.org> wrote:
>
> Hey Paolo,
>
> Another week, another couple of fixes. This time, two fixes for the
> ITS emulation that could result in non-existent LPIs being used, with
> unpredictable consequences. Thanks to Oliver for spotting those as he
> was reworking the ITS translation cache.

The consequences would really be NULL pointer dereferences, wouldn't they?

Pulled, thanks (not pushed so that I can adjust the merge commit message).

Paolo



From luca.ceresoli at bootlin.com  Wed Feb 21 02:22:44 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 21 Feb 2024 11:22:44 +0100
Subject: [PATCH v3 0/7] Add support for the internal RK3308 audio codec
Message-ID: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>

This series adds a driver for the internal audio codec of the Rockchip
RK3308 SoC, along with some related patches. This codec is internally
connected to the I2S peripherals on the same chip, and it has some
peculiarities arising from that interconnection.

For proper bidirectional operation with the internal codec at any possible
combination of sampling rates, the I2S peripheral needs two clock sources
(tx and rx), while connection with an external codec commonly needs only
one.

Since v5.16 there is a driver for the I2S in
sound/soc/rockchip/rockchip_i2s_tdm.c, but in some cases it does not
configure correctly the clocks, resulting in an unnecessarily inaccurate
rate. Patch 1 fixes this.

Patches 2-4 adds the codec driver along with the bindings and a new helper
macro.

Patches 5-7 add to the SoC DT file two I2S controllers (those which are
internally connected to the internal codec) and the codec itself and enable
the driver in the ARM64 defconfig.

Luca

Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
---

Changes in v3:
 - Add the I2S clock fix patch and remove a previous fix which is now superseded
 - Codec driver: fix silent playback until a given amplitude of sigital
   value, seen at >= 96 kHz rate
 - various other changes, listed per-patch
 - Link to v2: https://lore.kernel.org/r/20231219-rk3308-audio-codec-v2-0-c70d06021946 at bootlin.com

Changes in v2:
 - largely rewrote the codec driver to use DAPM and lots of improvements
   and cleanups
 - removed the RK3308 audio card and related patches
 - various other changes, listed per-patch
 - Link to v1: https://lore.kernel.org/all/20220907142124.2532620-1-luca.ceresoli at bootlin.com/

---
Luca Ceresoli (7):
      ASoC: rockchip: i2s-tdm: Fix inaccurate sampling rates
      ASoC: dt-bindings: Add Rockchip RK3308 internal audio codec
      ASoC: core: add SOC_DOUBLE_RANGE_TLV() helper macro
      ASoC: codecs: Add RK3308 internal audio codec driver
      arm64: defconfig: enable Rockchip RK3308 internal audio codec driver
      arm64: dts: rockchip: add i2s_8ch_2 and i2s_8ch_3
      arm64: dts: rockchip: add the internal audio codec

 .../bindings/sound/rockchip,rk3308-codec.yaml      |  98 ++
 MAINTAINERS                                        |   7 +
 arch/arm64/boot/dts/rockchip/rk3308.dtsi           |  56 ++
 arch/arm64/configs/defconfig                       |   1 +
 include/sound/soc.h                                |  12 +
 sound/soc/codecs/Kconfig                           |  11 +
 sound/soc/codecs/Makefile                          |   2 +
 sound/soc/codecs/rk3308_codec.c                    | 993 +++++++++++++++++++++
 sound/soc/codecs/rk3308_codec.h                    | 579 ++++++++++++
 sound/soc/rockchip/rockchip_i2s_tdm.c              | 352 +-------
 10 files changed, 1765 insertions(+), 346 deletions(-)
---
base-commit: 20fb305a716356265e9479719502b5a012e0d869
change-id: 20231219-rk3308-audio-codec-a5558ba8949d

Best regards,
-- 
Luca Ceresoli <luca.ceresoli at bootlin.com>



From luca.ceresoli at bootlin.com  Wed Feb 21 02:22:45 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 21 Feb 2024 11:22:45 +0100
Subject: [PATCH v3 1/7] ASoC: rockchip: i2s-tdm: Fix inaccurate sampling
 rates
In-Reply-To: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
References: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
Message-ID: <20240221-rk3308-audio-codec-v3-1-dfa34abfcef6@bootlin.com>

The sample rates set by the rockchip_i2s_tdm driver in master mode are
inaccurate up to 5% in several cases, due to the driver logic to configure
clocks and a nasty interaction with the Common Clock Framework.

To understand what happens, here is the relevant section of the clock tree
(slightly simplified), along with the names used in the driver:

       vpll0 _OR_ vpll1               "mclk_root"
          clk_i2s2_8ch_tx_src         "mclk_parent"
             clk_i2s2_8ch_tx_mux
                clk_i2s2_8ch_tx       "mclk" or "mclk_tx"

This is what happens when playing back e.g. at 192 kHz using
audio-graph-card (when recording the same applies, only s/tx/rx/):

 0. at probe, rockchip_i2s_tdm_set_sysclk() stores the passed frequency in
    i2s_tdm->mclk_tx_freq (*) which is 50176000, and that is never modified
    afterwards

 1. when playback is started, rockchip_i2s_tdm_hw_params() is called and
    does the following two calls

 2. rockchip_i2s_tdm_calibrate_mclk():

    2a. selects mclk_root0 (vpll0) as a parent for mclk_parent
        (mclk_tx_src), which is OK because the vpll0 rate is a good for
        192000 (and sumbultiple) rates

    2b. sets the mclk_root frequency based on ppm calibration computations

    2c. sets mclk_tx_src to 49152000 (= 256 * 192000), which is also OK as
        it is a multiple of the required bit clock

 3. rockchip_i2s_tdm_set_mclk()

    3a. calls clk_set_rate() to set the rate of mclk_tx (clk_i2s2_8ch_tx)
        to the value of i2s_tdm->mclk_tx_freq (*), i.e. 50176000 which is
        not a multiple of the sampling frequency -- this is not OK

        3a1. clk_set_rate() reacts by reparenting clk_i2s2_8ch_tx_src to
             vpll1 -- this is not OK because the default vpll1 rate can be
	     divided to get 44.1 kHz and related rates, not 192 kHz

The result is that the driver does a lot of ad-hoc decisions about clocks
and ends up in using the wrong parent at an unoptimal rate.

Step 0 is one part of the problem: unless the card driver calls set_sysclk
at each stream start, whatever rate is set in mclk_tx_freq during boot will
be taken and used until reboot. Moreover the driver does not care if its
value is not a multiple of any audio frequency.

Another part of the problem is that the whole reparenting and clock rate
setting logic is conflicting with the CCF algorithms to achieve largely the
same goal: selecting the best parent and setting the closest clock
rate. And it turns out that only calling once clk_set_rate() on
clk_i2s2_8ch_tx picks the correct vpll and sets the correct rate.

The fix is based on removing the custom logic in the driver to select the
parent and set the various clocks, and just let the Clock Framework do it
all. As a side effect, the set_sysclk() op becomes useless because we now
let the CCF compute the appropriate value for the sampling rate.  It also
implies that the whole calibration logic is now dead code and so it is
removed along with the "PCM Clock Compensation in PPM" kcontrol, which has
always been broken anyway. The handling of the 4 optional clocks also
becomes dead code and is removed.

The actual rates have been tested playing 30 seconds of audio at various
sampling rates before and after this change using sox:

    time play -r <sample_rate> -n synth 30 sine 950 gain -3

The time reported in the table below is the 'real' value reported by the
'time' command in the above command line.

     rate        before     after
   ---------     ------     ------
     8000 Hz     30.60s     30.63s
    11025 Hz     30.45s     30.51s
    16000 Hz     30.47s     30.50s
    22050 Hz     30.78s     30.41s
    32000 Hz     31.02s     30.43s
    44100 Hz     30.78s     30.41s
    48000 Hz     29.81s     30.45s
    88200 Hz     30.78s     30.41s
    96000 Hz     29.79s     30.42s
   176400 Hz     27.40s     30.41s
   192000 Hz     29.79s     30.42s

While the tests are running the clock tree confirms that:

 * without the patch, vpll1 is always used and clk_i2s2_8ch_tx always
   produces 50176000 Hz, which cannot be divided for most audio rates
   except the slowest ones, generating inaccurate rates
 * with the patch:
   - for 192000 Hz vpll0 is used
   - for 176400 Hz vpll1 is used
   - clk_i2s2_8ch_tx always produces (256 * <rate>) Hz

Fixes: 081068fd6414 ("ASoC: rockchip: add support for i2s-tdm controller")
Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

---

I don't know why such a complex yet incorrect logic is present, but it is
possibly a remnant of the downstream 4.19 driver
(https://github.com/rockchip-linux/kernel/blob/develop-4.19/sound/soc/rockchip/rockchip_i2s_tdm.c).
It might be that the CCF was not yet capable of optimally reparenting back
in 4.19, so it did make sense back then.

Changed in v3:
 - this patch is new in v3, and it replaces and supersedes the patch "ASoC:
   rockchip: i2s-tdm: Fix clk_id usage in .set_sysclk()"
---
 sound/soc/rockchip/rockchip_i2s_tdm.c | 352 +---------------------------------
 1 file changed, 6 insertions(+), 346 deletions(-)

diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
index 860e66ec85e8..9fa020ef7eab 100644
--- a/sound/soc/rockchip/rockchip_i2s_tdm.c
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
@@ -25,8 +25,6 @@
 #define DEFAULT_MCLK_FS				256
 #define CH_GRP_MAX				4  /* The max channel 8 / 2 */
 #define MULTIPLEX_CH_MAX			10
-#define CLK_PPM_MIN				-1000
-#define CLK_PPM_MAX				1000
 
 #define TRCM_TXRX 0
 #define TRCM_TX 1
@@ -53,20 +51,6 @@ struct rk_i2s_tdm_dev {
 	struct clk *hclk;
 	struct clk *mclk_tx;
 	struct clk *mclk_rx;
-	/* The mclk_tx_src is parent of mclk_tx */
-	struct clk *mclk_tx_src;
-	/* The mclk_rx_src is parent of mclk_rx */
-	struct clk *mclk_rx_src;
-	/*
-	 * The mclk_root0 and mclk_root1 are root parent and supplies for
-	 * the different FS.
-	 *
-	 * e.g:
-	 * mclk_root0 is VPLL0, used for FS=48000Hz
-	 * mclk_root1 is VPLL1, used for FS=44100Hz
-	 */
-	struct clk *mclk_root0;
-	struct clk *mclk_root1;
 	struct regmap *regmap;
 	struct regmap *grf;
 	struct snd_dmaengine_dai_dma_data capture_dma_data;
@@ -76,19 +60,11 @@ struct rk_i2s_tdm_dev {
 	const struct rk_i2s_soc_data *soc_data;
 	bool is_master_mode;
 	bool io_multiplex;
-	bool mclk_calibrate;
 	bool tdm_mode;
-	unsigned int mclk_rx_freq;
-	unsigned int mclk_tx_freq;
-	unsigned int mclk_root0_freq;
-	unsigned int mclk_root1_freq;
-	unsigned int mclk_root0_initial_freq;
-	unsigned int mclk_root1_initial_freq;
 	unsigned int frame_width;
 	unsigned int clk_trcm;
 	unsigned int i2s_sdis[CH_GRP_MAX];
 	unsigned int i2s_sdos[CH_GRP_MAX];
-	int clk_ppm;
 	int refcount;
 	spinlock_t lock; /* xfer lock */
 	bool has_playback;
@@ -114,12 +90,6 @@ static void i2s_tdm_disable_unprepare_mclk(struct rk_i2s_tdm_dev *i2s_tdm)
 {
 	clk_disable_unprepare(i2s_tdm->mclk_tx);
 	clk_disable_unprepare(i2s_tdm->mclk_rx);
-	if (i2s_tdm->mclk_calibrate) {
-		clk_disable_unprepare(i2s_tdm->mclk_tx_src);
-		clk_disable_unprepare(i2s_tdm->mclk_rx_src);
-		clk_disable_unprepare(i2s_tdm->mclk_root0);
-		clk_disable_unprepare(i2s_tdm->mclk_root1);
-	}
 }
 
 /**
@@ -142,29 +112,9 @@ static int i2s_tdm_prepare_enable_mclk(struct rk_i2s_tdm_dev *i2s_tdm)
 	ret = clk_prepare_enable(i2s_tdm->mclk_rx);
 	if (ret)
 		goto err_mclk_rx;
-	if (i2s_tdm->mclk_calibrate) {
-		ret = clk_prepare_enable(i2s_tdm->mclk_tx_src);
-		if (ret)
-			goto err_mclk_rx;
-		ret = clk_prepare_enable(i2s_tdm->mclk_rx_src);
-		if (ret)
-			goto err_mclk_rx_src;
-		ret = clk_prepare_enable(i2s_tdm->mclk_root0);
-		if (ret)
-			goto err_mclk_root0;
-		ret = clk_prepare_enable(i2s_tdm->mclk_root1);
-		if (ret)
-			goto err_mclk_root1;
-	}
 
 	return 0;
 
-err_mclk_root1:
-	clk_disable_unprepare(i2s_tdm->mclk_root0);
-err_mclk_root0:
-	clk_disable_unprepare(i2s_tdm->mclk_rx_src);
-err_mclk_rx_src:
-	clk_disable_unprepare(i2s_tdm->mclk_tx_src);
 err_mclk_rx:
 	clk_disable_unprepare(i2s_tdm->mclk_tx);
 err_mclk_tx:
@@ -564,159 +514,6 @@ static void rockchip_i2s_tdm_xfer_resume(struct snd_pcm_substream *substream,
 			   I2S_XFER_RXS_START);
 }
 
-static int rockchip_i2s_tdm_clk_set_rate(struct rk_i2s_tdm_dev *i2s_tdm,
-					 struct clk *clk, unsigned long rate,
-					 int ppm)
-{
-	unsigned long rate_target;
-	int delta, ret;
-
-	if (ppm == i2s_tdm->clk_ppm)
-		return 0;
-
-	if (ppm < 0)
-		delta = -1;
-	else
-		delta = 1;
-
-	delta *= (int)div64_u64((u64)rate * (u64)abs(ppm) + 500000,
-				1000000);
-
-	rate_target = rate + delta;
-
-	if (!rate_target)
-		return -EINVAL;
-
-	ret = clk_set_rate(clk, rate_target);
-	if (ret)
-		return ret;
-
-	i2s_tdm->clk_ppm = ppm;
-
-	return 0;
-}
-
-static int rockchip_i2s_tdm_calibrate_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
-					   struct snd_pcm_substream *substream,
-					   unsigned int lrck_freq)
-{
-	struct clk *mclk_root;
-	struct clk *mclk_parent;
-	unsigned int mclk_root_freq;
-	unsigned int mclk_root_initial_freq;
-	unsigned int mclk_parent_freq;
-	unsigned int div, delta;
-	u64 ppm;
-	int ret;
-
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		mclk_parent = i2s_tdm->mclk_tx_src;
-	else
-		mclk_parent = i2s_tdm->mclk_rx_src;
-
-	switch (lrck_freq) {
-	case 8000:
-	case 16000:
-	case 24000:
-	case 32000:
-	case 48000:
-	case 64000:
-	case 96000:
-	case 192000:
-		mclk_root = i2s_tdm->mclk_root0;
-		mclk_root_freq = i2s_tdm->mclk_root0_freq;
-		mclk_root_initial_freq = i2s_tdm->mclk_root0_initial_freq;
-		mclk_parent_freq = DEFAULT_MCLK_FS * 192000;
-		break;
-	case 11025:
-	case 22050:
-	case 44100:
-	case 88200:
-	case 176400:
-		mclk_root = i2s_tdm->mclk_root1;
-		mclk_root_freq = i2s_tdm->mclk_root1_freq;
-		mclk_root_initial_freq = i2s_tdm->mclk_root1_initial_freq;
-		mclk_parent_freq = DEFAULT_MCLK_FS * 176400;
-		break;
-	default:
-		dev_err(i2s_tdm->dev, "Invalid LRCK frequency: %u Hz\n",
-			lrck_freq);
-		return -EINVAL;
-	}
-
-	ret = clk_set_parent(mclk_parent, mclk_root);
-	if (ret)
-		return ret;
-
-	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, mclk_root,
-					    mclk_root_freq, 0);
-	if (ret)
-		return ret;
-
-	delta = abs(mclk_root_freq % mclk_parent_freq - mclk_parent_freq);
-	ppm = div64_u64((uint64_t)delta * 1000000, (uint64_t)mclk_root_freq);
-
-	if (ppm) {
-		div = DIV_ROUND_CLOSEST(mclk_root_initial_freq, mclk_parent_freq);
-		if (!div)
-			return -EINVAL;
-
-		mclk_root_freq = mclk_parent_freq * round_up(div, 2);
-
-		ret = clk_set_rate(mclk_root, mclk_root_freq);
-		if (ret)
-			return ret;
-
-		i2s_tdm->mclk_root0_freq = clk_get_rate(i2s_tdm->mclk_root0);
-		i2s_tdm->mclk_root1_freq = clk_get_rate(i2s_tdm->mclk_root1);
-	}
-
-	return clk_set_rate(mclk_parent, mclk_parent_freq);
-}
-
-static int rockchip_i2s_tdm_set_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
-				     struct snd_pcm_substream *substream,
-				     struct clk **mclk)
-{
-	unsigned int mclk_freq;
-	int ret;
-
-	if (i2s_tdm->clk_trcm) {
-		if (i2s_tdm->mclk_tx_freq != i2s_tdm->mclk_rx_freq) {
-			dev_err(i2s_tdm->dev,
-				"clk_trcm, tx: %d and rx: %d should be the same\n",
-				i2s_tdm->mclk_tx_freq,
-				i2s_tdm->mclk_rx_freq);
-			return -EINVAL;
-		}
-
-		ret = clk_set_rate(i2s_tdm->mclk_tx, i2s_tdm->mclk_tx_freq);
-		if (ret)
-			return ret;
-
-		ret = clk_set_rate(i2s_tdm->mclk_rx, i2s_tdm->mclk_rx_freq);
-		if (ret)
-			return ret;
-
-		/* mclk_rx is also ok. */
-		*mclk = i2s_tdm->mclk_tx;
-	} else {
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-			*mclk = i2s_tdm->mclk_tx;
-			mclk_freq = i2s_tdm->mclk_tx_freq;
-		} else {
-			*mclk = i2s_tdm->mclk_rx;
-			mclk_freq = i2s_tdm->mclk_rx_freq;
-		}
-
-		ret = clk_set_rate(*mclk, mclk_freq);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
 static int rockchip_i2s_ch_to_io(unsigned int ch, bool substream_capture)
 {
 	if (substream_capture) {
@@ -853,19 +650,17 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
 				      struct snd_soc_dai *dai)
 {
 	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
-	struct clk *mclk;
-	int ret = 0;
 	unsigned int val = 0;
 	unsigned int mclk_rate, bclk_rate, div_bclk = 4, div_lrck = 64;
+	int err;
 
 	if (i2s_tdm->is_master_mode) {
-		if (i2s_tdm->mclk_calibrate)
-			rockchip_i2s_tdm_calibrate_mclk(i2s_tdm, substream,
-							params_rate(params));
+		struct clk *mclk = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+			i2s_tdm->mclk_tx : i2s_tdm->mclk_rx;
 
-		ret = rockchip_i2s_tdm_set_mclk(i2s_tdm, substream, &mclk);
-		if (ret)
-			return ret;
+		err = clk_set_rate(mclk, DEFAULT_MCLK_FS * params_rate(params));
+		if (err)
+			return err;
 
 		mclk_rate = clk_get_rate(mclk);
 		bclk_rate = i2s_tdm->frame_width * params_rate(params);
@@ -973,96 +768,6 @@ static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static int rockchip_i2s_tdm_set_sysclk(struct snd_soc_dai *cpu_dai, int stream,
-				       unsigned int freq, int dir)
-{
-	struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
-
-	/* Put set mclk rate into rockchip_i2s_tdm_set_mclk() */
-	if (i2s_tdm->clk_trcm) {
-		i2s_tdm->mclk_tx_freq = freq;
-		i2s_tdm->mclk_rx_freq = freq;
-	} else {
-		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
-			i2s_tdm->mclk_tx_freq = freq;
-		else
-			i2s_tdm->mclk_rx_freq = freq;
-	}
-
-	dev_dbg(i2s_tdm->dev, "The target mclk_%s freq is: %d\n",
-		stream ? "rx" : "tx", freq);
-
-	return 0;
-}
-
-static int rockchip_i2s_tdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
-						  struct snd_ctl_elem_info *uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
-	uinfo->value.integer.min = CLK_PPM_MIN;
-	uinfo->value.integer.max = CLK_PPM_MAX;
-	uinfo->value.integer.step = 1;
-
-	return 0;
-}
-
-static int rockchip_i2s_tdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
-						 struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
-
-	ucontrol->value.integer.value[0] = i2s_tdm->clk_ppm;
-
-	return 0;
-}
-
-static int rockchip_i2s_tdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
-						 struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
-	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
-	int ret = 0, ppm = 0;
-	int changed = 0;
-	unsigned long old_rate;
-
-	if (ucontrol->value.integer.value[0] < CLK_PPM_MIN ||
-	    ucontrol->value.integer.value[0] > CLK_PPM_MAX)
-		return -EINVAL;
-
-	ppm = ucontrol->value.integer.value[0];
-
-	old_rate = clk_get_rate(i2s_tdm->mclk_root0);
-	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root0,
-					    i2s_tdm->mclk_root0_freq, ppm);
-	if (ret)
-		return ret;
-	if (old_rate != clk_get_rate(i2s_tdm->mclk_root0))
-		changed = 1;
-
-	if (clk_is_match(i2s_tdm->mclk_root0, i2s_tdm->mclk_root1))
-		return changed;
-
-	old_rate = clk_get_rate(i2s_tdm->mclk_root1);
-	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root1,
-					    i2s_tdm->mclk_root1_freq, ppm);
-	if (ret)
-		return ret;
-	if (old_rate != clk_get_rate(i2s_tdm->mclk_root1))
-		changed = 1;
-
-	return changed;
-}
-
-static struct snd_kcontrol_new rockchip_i2s_tdm_compensation_control = {
-	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
-	.name = "PCM Clock Compensation in PPM",
-	.info = rockchip_i2s_tdm_clk_compensation_info,
-	.get = rockchip_i2s_tdm_clk_compensation_get,
-	.put = rockchip_i2s_tdm_clk_compensation_put,
-};
-
 static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
 {
 	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
@@ -1072,9 +777,6 @@ static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
 	if (i2s_tdm->has_playback)
 		snd_soc_dai_dma_data_set_playback(dai, &i2s_tdm->playback_dma_data);
 
-	if (i2s_tdm->mclk_calibrate)
-		snd_soc_add_dai_controls(dai, &rockchip_i2s_tdm_compensation_control, 1);
-
 	return 0;
 }
 
@@ -1115,7 +817,6 @@ static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = {
 	.probe = rockchip_i2s_tdm_dai_probe,
 	.hw_params = rockchip_i2s_tdm_hw_params,
 	.set_bclk_ratio	= rockchip_i2s_tdm_set_bclk_ratio,
-	.set_sysclk = rockchip_i2s_tdm_set_sysclk,
 	.set_fmt = rockchip_i2s_tdm_set_fmt,
 	.set_tdm_slot = rockchip_dai_tdm_slot,
 	.trigger = rockchip_i2s_tdm_trigger,
@@ -1444,35 +1145,6 @@ static void rockchip_i2s_tdm_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
 		rockchip_i2s_tdm_tx_path_config(i2s_tdm, num);
 }
 
-static int rockchip_i2s_tdm_get_calibrate_mclks(struct rk_i2s_tdm_dev *i2s_tdm)
-{
-	int num_mclks = 0;
-
-	i2s_tdm->mclk_tx_src = devm_clk_get(i2s_tdm->dev, "mclk_tx_src");
-	if (!IS_ERR(i2s_tdm->mclk_tx_src))
-		num_mclks++;
-
-	i2s_tdm->mclk_rx_src = devm_clk_get(i2s_tdm->dev, "mclk_rx_src");
-	if (!IS_ERR(i2s_tdm->mclk_rx_src))
-		num_mclks++;
-
-	i2s_tdm->mclk_root0 = devm_clk_get(i2s_tdm->dev, "mclk_root0");
-	if (!IS_ERR(i2s_tdm->mclk_root0))
-		num_mclks++;
-
-	i2s_tdm->mclk_root1 = devm_clk_get(i2s_tdm->dev, "mclk_root1");
-	if (!IS_ERR(i2s_tdm->mclk_root1))
-		num_mclks++;
-
-	if (num_mclks < 4 && num_mclks != 0)
-		return -ENOENT;
-
-	if (num_mclks == 4)
-		i2s_tdm->mclk_calibrate = 1;
-
-	return 0;
-}
-
 static int rockchip_i2s_tdm_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
 					 struct device_node *np,
 					 bool is_rx_path)
@@ -1610,11 +1282,6 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
 	i2s_tdm->io_multiplex =
 		of_property_read_bool(node, "rockchip,io-multiplex");
 
-	ret = rockchip_i2s_tdm_get_calibrate_mclks(i2s_tdm);
-	if (ret)
-		return dev_err_probe(i2s_tdm->dev, ret,
-				     "mclk-calibrate clocks missing");
-
 	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(regs)) {
 		return dev_err_probe(i2s_tdm->dev, PTR_ERR(regs),
@@ -1667,13 +1334,6 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
 		goto err_disable_hclk;
 	}
 
-	if (i2s_tdm->mclk_calibrate) {
-		i2s_tdm->mclk_root0_initial_freq = clk_get_rate(i2s_tdm->mclk_root0);
-		i2s_tdm->mclk_root1_initial_freq = clk_get_rate(i2s_tdm->mclk_root1);
-		i2s_tdm->mclk_root0_freq = i2s_tdm->mclk_root0_initial_freq;
-		i2s_tdm->mclk_root1_freq = i2s_tdm->mclk_root1_initial_freq;
-	}
-
 	pm_runtime_enable(&pdev->dev);
 
 	regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,

-- 
2.34.1



From luca.ceresoli at bootlin.com  Wed Feb 21 02:22:47 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 21 Feb 2024 11:22:47 +0100
Subject: [PATCH v3 3/7] ASoC: core: add SOC_DOUBLE_RANGE_TLV() helper macro
In-Reply-To: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
References: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
Message-ID: <20240221-rk3308-audio-codec-v3-3-dfa34abfcef6@bootlin.com>

No macro currently allows handling a stereo control that has left and right
in the same register and whose minimum register value is not zero. Add one
that does that.

Note that even though the snd_soc_*_volsw_range() look more appropriate
given the _range suffix, they are not suitable because they don't honor the
two shift values. The snd_soc_*_volsw() look more generic and are suitable
for the task.

Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

---

Changed in v3: nothing

This patch is new in v2.
---
 include/sound/soc.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 6defc5547ff9..7492315ce0b8 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -149,6 +149,18 @@
 		{.reg = xreg, .rreg = xreg, \
 		.shift = shift_left, .rshift = shift_right, \
 		.max = xmax, .min = xmin} }
+#define SOC_DOUBLE_RANGE_TLV(xname, xreg, xshift_left, xshift_right, xmin, xmax, \
+			     xinvert, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+		  SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw, \
+	.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
+	.private_value = (unsigned long)&(struct soc_mixer_control) \
+		{.reg = xreg, .rreg = xreg, \
+		 .shift = xshift_left, .rshift = xshift_right, \
+		 .min = xmin, .max = xmax, .invert = xinvert} }
 #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\

-- 
2.34.1



From luca.ceresoli at bootlin.com  Wed Feb 21 02:22:46 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 21 Feb 2024 11:22:46 +0100
Subject: [PATCH v3 2/7] ASoC: dt-bindings: Add Rockchip RK3308 internal
 audio codec
In-Reply-To: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
References: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
Message-ID: <20240221-rk3308-audio-codec-v3-2-dfa34abfcef6@bootlin.com>

Add device tree bindings document for the internal audio codec of the
Rockchip RK3308 SoC.

Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

---

Changed in v3:
 - fix underscore in DT label

Changed in v2:
 - reword commit title
 - add maxItems to resets
 - remove quotes from reset-names
 - use percent values for rockchip,micbias-avdd-multiplier
 - use name compliant to the docs in the example
---
 .../bindings/sound/rockchip,rk3308-codec.yaml      | 98 ++++++++++++++++++++++
 MAINTAINERS                                        |  5 ++
 2 files changed, 103 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.yaml b/Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.yaml
new file mode 100644
index 000000000000..ecf3d7d968c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/rockchip,rk3308-codec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3308 Internal Codec
+
+description: |
+  This is the audio codec embedded in the Rockchip RK3308
+  SoC. It has 8 24-bit ADCs and 2 24-bit DACs. The maximum supported
+  sampling rate is 192 kHz.
+
+  It is connected internally to one out of a selection of the internal I2S
+  controllers.
+
+  The RK3308 audio codec has 8 independent capture channels, but some
+  features work on stereo pairs called groups:
+    * grp 0 -- MIC1 / MIC2
+    * grp 1 -- MIC3 / MIC4
+    * grp 2 -- MIC5 / MIC6
+    * grp 3 -- MIC7 / MIC8
+
+maintainers:
+  - Luca Ceresoli <luca.ceresoli at bootlin.com>
+
+properties:
+  compatible:
+    const: rockchip,rk3308-codec
+
+  reg:
+    maxItems: 1
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the General Register Files (GRF)
+
+  clocks:
+    items:
+      - description: clock for TX
+      - description: clock for RX
+      - description: AHB clock driving the interface
+
+  clock-names:
+    items:
+      - const: mclk_tx
+      - const: mclk_rx
+      - const: hclk
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    items:
+      - const: codec
+
+  "#sound-dai-cells":
+    const: 0
+
+  rockchip,micbias-avdd-percent:
+    description: |
+      Voltage setting for the MICBIAS pins expressed as a percentage of
+      AVDD.
+
+      E.g. if rockchip,micbias-avdd-percent = 85 and AVDD = 3v3, then the
+      MIC BIAS voltage will be 3.3 V * 85% = 2.805 V.
+
+    enum: [ 50, 55, 60, 65, 70, 75, 80, 85 ]
+
+required:
+  - compatible
+  - reg
+  - rockchip,grf
+  - clocks
+  - resets
+  - "#sound-dai-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3308-cru.h>
+
+    audio_codec: audio-codec at ff560000 {
+        compatible = "rockchip,rk3308-codec";
+        reg = <0xff560000 0x10000>;
+        rockchip,grf = <&grf>;
+        clock-names = "mclk_tx", "mclk_rx", "hclk";
+        clocks = <&cru SCLK_I2S2_8CH_TX_OUT>,
+                 <&cru SCLK_I2S2_8CH_RX_OUT>,
+                 <&cru PCLK_ACODEC>;
+        reset-names = "codec";
+        resets = <&cru SRST_ACODEC_P>;
+        #sound-dai-cells = <0>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 9ed4d3868539..b67835da3994 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18924,6 +18924,11 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/rockchip-rga.yaml
 F:	drivers/media/platform/rockchip/rga/
 
+ROCKCHIP RK3308 INTERNAL AUDIO CODEC
+M:	Luca Ceresoli <luca.ceresoli at bootlin.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.yaml
+
 ROCKCHIP VIDEO DECODER DRIVER
 M:	Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
 L:	linux-media at vger.kernel.org

-- 
2.34.1



From luca.ceresoli at bootlin.com  Wed Feb 21 02:22:50 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 21 Feb 2024 11:22:50 +0100
Subject: [PATCH v3 6/7] arm64: dts: rockchip: add i2s_8ch_2 and i2s_8ch_3
In-Reply-To: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
References: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
Message-ID: <20240221-rk3308-audio-codec-v3-6-dfa34abfcef6@bootlin.com>

These are I2S engines internally connected to the built-in audio codec.

Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

---

Changed in v3:
 - removed the 4 optional clocks

Changed in v2: nothing
---
 arch/arm64/boot/dts/rockchip/rk3308.dtsi | 42 ++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
index cfc0a87b5195..662c55fe9b77 100644
--- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
@@ -578,6 +578,48 @@ dmac1: dma-controller at ff2d0000 {
 		#dma-cells = <1>;
 	};
 
+	/*
+	 * - can be clock producer or consumer
+	 * - up to 8 capture channels and 2 playback channels
+	 * - connected internally to audio codec
+	 */
+	i2s_8ch_2: i2s at ff320000 {
+		compatible = "rockchip,rk3308-i2s-tdm";
+		reg = <0x0 0xff320000 0x0 0x1000>;
+		interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "mclk_tx", "mclk_rx", "hclk";
+		clocks = <&cru SCLK_I2S2_8CH_TX>,
+			 <&cru SCLK_I2S2_8CH_RX>,
+			 <&cru HCLK_I2S2_8CH>;
+		dmas = <&dmac1 5>, <&dmac1 4>;
+		dma-names = "rx", "tx";
+		resets = <&cru SRST_I2S2_8CH_TX_M>, <&cru SRST_I2S2_8CH_RX_M>;
+		reset-names = "tx-m", "rx-m";
+		rockchip,grf = <&grf>;
+		status = "disabled";
+	};
+
+	/*
+	 * - can be clock consumer only
+	 * - up to 4 capture channels, no playback
+	 * - connected internally to audio codec
+	 */
+	i2s_8ch_3: i2s at ff330000 {
+		compatible = "rockchip,rk3308-i2s-tdm";
+		reg = <0x0 0xff330000 0x0 0x1000>;
+		interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "mclk_tx", "mclk_rx", "hclk";
+		clocks = <&cru SCLK_I2S3_8CH_TX>,
+			 <&cru SCLK_I2S3_8CH_RX>,
+			 <&cru HCLK_I2S3_8CH>;
+		dmas = <&dmac1 7>;
+		dma-names = "rx";
+		resets = <&cru SRST_I2S3_8CH_TX_M>, <&cru SRST_I2S3_8CH_RX_M>;
+		reset-names = "tx-m", "rx-m";
+		rockchip,grf = <&grf>;
+		status = "disabled";
+	};
+
 	i2s_2ch_0: i2s at ff350000 {
 		compatible = "rockchip,rk3308-i2s", "rockchip,rk3066-i2s";
 		reg = <0x0 0xff350000 0x0 0x1000>;

-- 
2.34.1



From luca.ceresoli at bootlin.com  Wed Feb 21 02:22:49 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 21 Feb 2024 11:22:49 +0100
Subject: [PATCH v3 5/7] arm64: defconfig: enable Rockchip RK3308 internal
 audio codec driver
In-Reply-To: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
References: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
Message-ID: <20240221-rk3308-audio-codec-v3-5-dfa34abfcef6@bootlin.com>

This codec now has a driver.

Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

---

This patch is new in v3.
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e6cf3e5d63c3..20650b03d25c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -981,6 +981,7 @@ CONFIG_SND_SOC_GTM601=m
 CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
 CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
 CONFIG_SND_SOC_PCM3168A_I2C=m
+CONFIG_SND_SOC_RK3308=m
 CONFIG_SND_SOC_RK817=m
 CONFIG_SND_SOC_RT5640=m
 CONFIG_SND_SOC_RT5659=m

-- 
2.34.1



From luca.ceresoli at bootlin.com  Wed Feb 21 02:22:48 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 21 Feb 2024 11:22:48 +0100
Subject: [PATCH v3 4/7] ASoC: codecs: Add RK3308 internal audio codec
 driver
In-Reply-To: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
References: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
Message-ID: <20240221-rk3308-audio-codec-v3-4-dfa34abfcef6@bootlin.com>

Add driver for the internal audio codec of the Rockchip RK3308 SoC.

Initially based on the vendor kernel driver [0], with lots of cleanups,
fixes, improvements, conversion to DAPM and removal of some features.

[0] https://github.com/rockchip-linux/kernel/blob/develop-4.19/sound/soc/codecs/rk3308_codec.c

Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

---

Changed in v3:
 - fix silent playback until a given amplitude of sigital value, seen
   at >= 96 kHz rate
 - simplify capture setup by removing unneeded loop
 - use unsigned char for codec version
 - cleanup a few register defines
 - remove unused enums and defines
 - update copyright year

Changed in v2:
 - convert everything to DAPM support
 - move rk3308_codec_power_on/off() code to .set_bias_level
 - move MICBIAS setting from hw_params to probe
 - support silicon version C which differs in some registers
 - removed LINE IN code as LINE IN is not supported by the hardware
 - remove unneeded digital reset in in rk3308_codec_hw_params
 - rewrite on/off controls to be bool switches, not enums
 - fix _put() operations return value (1 if value changed)
 - fix RK3308_ADC_CURRENT_CHARGE_MSK power-down ramp (it was ramping up
   just like the power-up ramp)
 - enable zero-cross detection unconditionally
 - Remove AGC/ALC implementation
 - Add HPF controls (enable and cut-off frequency)
 - model HP output as a stereo control (requires new ASoC helper macro)
 - use ADC_CH*_MIC_MUTE for muting mics, not the BIST bits
 - fix uninitialized variable is_master
 - remove useless wrappers
 - remove .mute_stream callback
 - remove digital fade in/out for HPOUT volume
 - remove many unneeded register initializations to their reset values and
   documented the few places where open-coded initializations to values
   different from the reset value are needed
 - collapse various functions into rk3308_codec_adc_dig_config(), which
   simplified dramatically the hw_params code
 - various coding style and comments improvements, code reorganization
 - add error checking in several places
---
 MAINTAINERS                     |   2 +
 sound/soc/codecs/Kconfig        |  11 +
 sound/soc/codecs/Makefile       |   2 +
 sound/soc/codecs/rk3308_codec.c | 993 ++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/rk3308_codec.h | 579 +++++++++++++++++++++++
 5 files changed, 1587 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b67835da3994..23cff94abcf3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18928,6 +18928,8 @@ ROCKCHIP RK3308 INTERNAL AUDIO CODEC
 M:	Luca Ceresoli <luca.ceresoli at bootlin.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.yaml
+F:	sound/soc/codecs/rk3308_codec.c
+F:	sound/soc/codecs/rk3308_codec.h
 
 ROCKCHIP VIDEO DECODER DRIVER
 M:	Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 59f9742e9ff4..1c9d671a9848 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -179,6 +179,7 @@ config SND_SOC_ALL_CODECS
 	imply SND_SOC_PCM512x_I2C
 	imply SND_SOC_PCM512x_SPI
 	imply SND_SOC_PEB2466
+	imply SND_SOC_RK3308
 	imply SND_SOC_RK3328
 	imply SND_SOC_RK817
 	imply SND_SOC_RT274
@@ -1400,6 +1401,16 @@ config SND_SOC_PEB2466
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-soc-peb2466.
 
+config SND_SOC_RK3308
+	tristate "Rockchip RK3308 audio CODEC"
+	select REGMAP_MMIO
+	help
+	  This is a device driver for the audio codec embedded in the
+	  Rockchip RK3308 SoC.
+
+	  It has 8 24-bit ADCs and 2 24-bit DACs. The maximum supported
+	  sampling rate is 192 kHz.
+
 config SND_SOC_RK3328
 	tristate "Rockchip RK3328 audio CODEC"
 	select REGMAP_MMIO
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f53baa2b9565..563c5b404fb4 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -202,6 +202,7 @@ snd-soc-pcm512x-objs := pcm512x.o
 snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
 snd-soc-pcm512x-spi-objs := pcm512x-spi.o
 snd-soc-peb2466-objs := peb2466.o
+snd-soc-rk3308-objs := rk3308_codec.o
 snd-soc-rk3328-objs := rk3328_codec.o
 snd-soc-rk817-objs := rk817_codec.o
 snd-soc-rl6231-objs := rl6231.o
@@ -587,6 +588,7 @@ obj-$(CONFIG_SND_SOC_PCM512x)	+= snd-soc-pcm512x.o
 obj-$(CONFIG_SND_SOC_PCM512x_I2C)	+= snd-soc-pcm512x-i2c.o
 obj-$(CONFIG_SND_SOC_PCM512x_SPI)	+= snd-soc-pcm512x-spi.o
 obj-$(CONFIG_SND_SOC_PEB2466)	+= snd-soc-peb2466.o
+obj-$(CONFIG_SND_SOC_RK3308)	+= snd-soc-rk3308.o
 obj-$(CONFIG_SND_SOC_RK3328)	+= snd-soc-rk3328.o
 obj-$(CONFIG_SND_SOC_RK817)	+= snd-soc-rk817.o
 obj-$(CONFIG_SND_SOC_RL6231)	+= snd-soc-rl6231.o
diff --git a/sound/soc/codecs/rk3308_codec.c b/sound/soc/codecs/rk3308_codec.c
new file mode 100644
index 000000000000..61bfb75f92a3
--- /dev/null
+++ b/sound/soc/codecs/rk3308_codec.c
@@ -0,0 +1,993 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Rockchip RK3308 internal audio codec driver
+ *
+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
+ * Copyright (c) 2024, Vivax-Metrotech Ltd
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/util_macros.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include "rk3308_codec.h"
+
+#define ADC_LR_GROUP_MAX		4
+
+#define GRF_CHIP_ID			0x800
+
+enum {
+	ACODEC_VERSION_A = 'A',
+	ACODEC_VERSION_B,
+	ACODEC_VERSION_C,
+};
+
+struct rk3308_codec_priv {
+	const struct device *dev;
+	struct regmap *regmap;
+	struct regmap *grf;
+	struct reset_control *reset;
+	struct clk *hclk;
+	struct clk *mclk_rx;
+	struct clk *mclk_tx;
+	struct snd_soc_component *component;
+	unsigned char codec_ver;
+};
+
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_alc_gain_tlv,   -1800, 150, 0);
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpout_gain_tlv, -3900, 150, 0);
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpmix_gain_tlv,  -600, 600, 0);
+
+static const DECLARE_TLV_DB_RANGE(rk3308_codec_dac_lineout_gain_tlv,
+	0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0),
+	1, 1, TLV_DB_SCALE_ITEM(-300, 0, 0),
+	2, 2, TLV_DB_SCALE_ITEM(-150, 0, 0),
+	3, 3, TLV_DB_SCALE_ITEM(0,    0, 0),
+);
+
+static const char * const rk3308_codec_hpf_cutoff_text[] = {
+	"20 Hz", "245 Hz", "612 Hz"
+};
+
+static SOC_ENUM_SINGLE_DECL(rk3308_codec_hpf_cutoff_enum12, RK3308_ADC_DIG_CON04(0), 0,
+			    rk3308_codec_hpf_cutoff_text);
+static SOC_ENUM_SINGLE_DECL(rk3308_codec_hpf_cutoff_enum34, RK3308_ADC_DIG_CON04(1), 0,
+			    rk3308_codec_hpf_cutoff_text);
+static SOC_ENUM_SINGLE_DECL(rk3308_codec_hpf_cutoff_enum56, RK3308_ADC_DIG_CON04(2), 0,
+			    rk3308_codec_hpf_cutoff_text);
+static SOC_ENUM_SINGLE_DECL(rk3308_codec_hpf_cutoff_enum78, RK3308_ADC_DIG_CON04(3), 0,
+			    rk3308_codec_hpf_cutoff_text);
+
+static const struct snd_kcontrol_new rk3308_codec_controls[] = {
+	/* Despite the register names, these set the gain when AGC is OFF */
+	SOC_SINGLE_RANGE_TLV("MIC1 Capture Volume",
+			     RK3308_ADC_ANA_CON03(0),
+			     RK3308_ADC_CH1_ALC_GAIN_SFT,
+			     RK3308_ADC_CH1_ALC_GAIN_MIN,
+			     RK3308_ADC_CH1_ALC_GAIN_MAX,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("MIC2 Capture Volume",
+			     RK3308_ADC_ANA_CON04(0),
+			     RK3308_ADC_CH2_ALC_GAIN_SFT,
+			     RK3308_ADC_CH2_ALC_GAIN_MIN,
+			     RK3308_ADC_CH2_ALC_GAIN_MAX,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("MIC3 Capture Volume",
+			     RK3308_ADC_ANA_CON03(1),
+			     RK3308_ADC_CH1_ALC_GAIN_SFT,
+			     RK3308_ADC_CH1_ALC_GAIN_MIN,
+			     RK3308_ADC_CH1_ALC_GAIN_MAX,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("MIC4 Capture Volume",
+			     RK3308_ADC_ANA_CON04(1),
+			     RK3308_ADC_CH2_ALC_GAIN_SFT,
+			     RK3308_ADC_CH2_ALC_GAIN_MIN,
+			     RK3308_ADC_CH2_ALC_GAIN_MAX,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("MIC5 Capture Volume",
+			     RK3308_ADC_ANA_CON03(2),
+			     RK3308_ADC_CH1_ALC_GAIN_SFT,
+			     RK3308_ADC_CH1_ALC_GAIN_MIN,
+			     RK3308_ADC_CH1_ALC_GAIN_MAX,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("MIC6 Capture Volume",
+			     RK3308_ADC_ANA_CON04(2),
+			     RK3308_ADC_CH2_ALC_GAIN_SFT,
+			     RK3308_ADC_CH2_ALC_GAIN_MIN,
+			     RK3308_ADC_CH2_ALC_GAIN_MAX,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("MIC7 Capture Volume",
+			     RK3308_ADC_ANA_CON03(3),
+			     RK3308_ADC_CH1_ALC_GAIN_SFT,
+			     RK3308_ADC_CH1_ALC_GAIN_MIN,
+			     RK3308_ADC_CH1_ALC_GAIN_MAX,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("MIC8 Capture Volume",
+			     RK3308_ADC_ANA_CON04(3),
+			     RK3308_ADC_CH2_ALC_GAIN_SFT,
+			     RK3308_ADC_CH2_ALC_GAIN_MIN,
+			     RK3308_ADC_CH2_ALC_GAIN_MAX,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+
+	SOC_SINGLE("MIC1 Capture Switch", RK3308_ADC_ANA_CON00(0), 3, 1, 0),
+	SOC_SINGLE("MIC2 Capture Switch", RK3308_ADC_ANA_CON00(0), 7, 1, 0),
+	SOC_SINGLE("MIC3 Capture Switch", RK3308_ADC_ANA_CON00(1), 3, 1, 0),
+	SOC_SINGLE("MIC4 Capture Switch", RK3308_ADC_ANA_CON00(1), 7, 1, 0),
+	SOC_SINGLE("MIC5 Capture Switch", RK3308_ADC_ANA_CON00(2), 3, 1, 0),
+	SOC_SINGLE("MIC6 Capture Switch", RK3308_ADC_ANA_CON00(2), 7, 1, 0),
+	SOC_SINGLE("MIC7 Capture Switch", RK3308_ADC_ANA_CON00(3), 3, 1, 0),
+	SOC_SINGLE("MIC8 Capture Switch", RK3308_ADC_ANA_CON00(3), 7, 1, 0),
+
+	SOC_SINGLE("MIC12 HPF Capture Switch", RK3308_ADC_DIG_CON04(0), 2, 1, 1),
+	SOC_SINGLE("MIC34 HPF Capture Switch", RK3308_ADC_DIG_CON04(1), 2, 1, 1),
+	SOC_SINGLE("MIC56 HPF Capture Switch", RK3308_ADC_DIG_CON04(2), 2, 1, 1),
+	SOC_SINGLE("MIC78 HPF Capture Switch", RK3308_ADC_DIG_CON04(3), 2, 1, 1),
+
+	SOC_ENUM("MIC12 HPF Cutoff", rk3308_codec_hpf_cutoff_enum12),
+	SOC_ENUM("MIC34 HPF Cutoff", rk3308_codec_hpf_cutoff_enum34),
+	SOC_ENUM("MIC56 HPF Cutoff", rk3308_codec_hpf_cutoff_enum56),
+	SOC_ENUM("MIC78 HPF Cutoff", rk3308_codec_hpf_cutoff_enum78),
+
+	SOC_DOUBLE_TLV("Line Out Playback Volume",
+		       RK3308_DAC_ANA_CON04,
+		       RK3308_DAC_L_LINEOUT_GAIN_SFT,
+		       RK3308_DAC_R_LINEOUT_GAIN_SFT,
+		       RK3308_DAC_x_LINEOUT_GAIN_MAX,
+		       0, rk3308_codec_dac_lineout_gain_tlv),
+	SOC_DOUBLE("Line Out Playback Switch",
+		   RK3308_DAC_ANA_CON04,
+		   RK3308_DAC_L_LINEOUT_MUTE_SFT,
+		   RK3308_DAC_R_LINEOUT_MUTE_SFT, 1, 0),
+	SOC_DOUBLE_R_TLV("Headphone Playback Volume",
+			 RK3308_DAC_ANA_CON05,
+			 RK3308_DAC_ANA_CON06,
+			 RK3308_DAC_x_HPOUT_GAIN_SFT,
+			 RK3308_DAC_x_HPOUT_GAIN_MAX,
+			 0, rk3308_codec_dac_hpout_gain_tlv),
+	SOC_DOUBLE("Headphone Playback Switch",
+		   RK3308_DAC_ANA_CON03,
+		   RK3308_DAC_L_HPOUT_MUTE_SFT,
+		   RK3308_DAC_R_HPOUT_MUTE_SFT, 1, 0),
+	SOC_DOUBLE_RANGE_TLV("DAC HPMIX Playback Volume",
+			     RK3308_DAC_ANA_CON12,
+			     RK3308_DAC_L_HPMIX_GAIN_SFT,
+			     RK3308_DAC_R_HPMIX_GAIN_SFT,
+			     1, 2, 0, rk3308_codec_dac_hpmix_gain_tlv),
+};
+
+static int rk3308_codec_pop_sound_set(struct snd_soc_dapm_widget *w,
+				      struct snd_kcontrol *kcontrol,
+				      int event)
+{
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
+	unsigned int val = (event == SND_SOC_DAPM_POST_PMU) ?
+		RK3308_DAC_HPOUT_POP_SOUND_x_WORK :
+		RK3308_DAC_HPOUT_POP_SOUND_x_INIT;
+	unsigned int mask = RK3308_DAC_HPOUT_POP_SOUND_x_MSK;
+
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+			   mask << w->shift, val << w->shift);
+
+	return 0;
+}
+
+static const struct snd_soc_dapm_widget rk3308_codec_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("MIC1"),
+	SND_SOC_DAPM_INPUT("MIC2"),
+	SND_SOC_DAPM_INPUT("MIC3"),
+	SND_SOC_DAPM_INPUT("MIC4"),
+	SND_SOC_DAPM_INPUT("MIC5"),
+	SND_SOC_DAPM_INPUT("MIC6"),
+	SND_SOC_DAPM_INPUT("MIC7"),
+	SND_SOC_DAPM_INPUT("MIC8"),
+
+	SND_SOC_DAPM_SUPPLY("ADC_CURRENT_EN12", RK3308_ADC_ANA_CON06(0), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC_CURRENT_EN34", RK3308_ADC_ANA_CON06(1), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC_CURRENT_EN56", RK3308_ADC_ANA_CON06(2), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC_CURRENT_EN78", RK3308_ADC_ANA_CON06(3), 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC1_EN", RK3308_ADC_ANA_CON00(0), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC2_EN", RK3308_ADC_ANA_CON00(0), 5, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC3_EN", RK3308_ADC_ANA_CON00(1), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC4_EN", RK3308_ADC_ANA_CON00(1), 5, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC5_EN", RK3308_ADC_ANA_CON00(2), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC6_EN", RK3308_ADC_ANA_CON00(2), 5, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC7_EN", RK3308_ADC_ANA_CON00(3), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC8_EN", RK3308_ADC_ANA_CON00(3), 5, 1, 1, 0),
+
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC1_WORK", RK3308_ADC_ANA_CON00(0), 2, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC2_WORK", RK3308_ADC_ANA_CON00(0), 6, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC3_WORK", RK3308_ADC_ANA_CON00(1), 2, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC4_WORK", RK3308_ADC_ANA_CON00(1), 6, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC5_WORK", RK3308_ADC_ANA_CON00(2), 2, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC6_WORK", RK3308_ADC_ANA_CON00(2), 6, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC7_WORK", RK3308_ADC_ANA_CON00(3), 2, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC8_WORK", RK3308_ADC_ANA_CON00(3), 6, 1, 1, 0),
+
+	/*
+	 * In theory MIC1 and MIC2 can switch to LINE IN, but this is not
+	 * supported so all we can do is enabling the MIC input.
+	 */
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "CH1_IN_SEL", RK3308_ADC_ANA_CON07(0), 4, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "CH2_IN_SEL", RK3308_ADC_ANA_CON07(0), 6, 1, 1, 0),
+
+	SND_SOC_DAPM_SUPPLY("ADC1_BUF_REF_EN", RK3308_ADC_ANA_CON00(0), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC2_BUF_REF_EN", RK3308_ADC_ANA_CON00(0), 4, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC3_BUF_REF_EN", RK3308_ADC_ANA_CON00(1), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC4_BUF_REF_EN", RK3308_ADC_ANA_CON00(1), 4, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC5_BUF_REF_EN", RK3308_ADC_ANA_CON00(2), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC6_BUF_REF_EN", RK3308_ADC_ANA_CON00(2), 4, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC7_BUF_REF_EN", RK3308_ADC_ANA_CON00(3), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC8_BUF_REF_EN", RK3308_ADC_ANA_CON00(3), 4, 0, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("ADC_MCLK_GATE", RK3308_GLB_CON, 5, 1, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("ADC1_CLK_EN", RK3308_ADC_ANA_CON05(0), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC2_CLK_EN", RK3308_ADC_ANA_CON05(0), 4, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC3_CLK_EN", RK3308_ADC_ANA_CON05(1), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC4_CLK_EN", RK3308_ADC_ANA_CON05(1), 4, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC5_CLK_EN", RK3308_ADC_ANA_CON05(2), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC6_CLK_EN", RK3308_ADC_ANA_CON05(2), 4, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC7_CLK_EN", RK3308_ADC_ANA_CON05(3), 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC8_CLK_EN", RK3308_ADC_ANA_CON05(3), 4, 0, NULL, 0),
+
+	/* The "ALC" name from the TRM is misleading, these are needed even without ALC/AGC */
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC1_EN", RK3308_ADC_ANA_CON02(0), 0, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC2_EN", RK3308_ADC_ANA_CON02(0), 4, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC3_EN", RK3308_ADC_ANA_CON02(1), 0, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC4_EN", RK3308_ADC_ANA_CON02(1), 4, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC5_EN", RK3308_ADC_ANA_CON02(2), 0, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC6_EN", RK3308_ADC_ANA_CON02(2), 4, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC7_EN", RK3308_ADC_ANA_CON02(3), 0, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC8_EN", RK3308_ADC_ANA_CON02(3), 4, 1, 1, 0),
+
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC1_EN", RK3308_ADC_ANA_CON05(0), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC2_EN", RK3308_ADC_ANA_CON05(0), 5, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC3_EN", RK3308_ADC_ANA_CON05(1), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC4_EN", RK3308_ADC_ANA_CON05(1), 5, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC5_EN", RK3308_ADC_ANA_CON05(2), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC6_EN", RK3308_ADC_ANA_CON05(2), 5, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC7_EN", RK3308_ADC_ANA_CON05(3), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC8_EN", RK3308_ADC_ANA_CON05(3), 5, 1, 1, 0),
+
+	SND_SOC_DAPM_ADC("ADC1_WORK", "Capture", RK3308_ADC_ANA_CON05(0), 2, 0),
+	SND_SOC_DAPM_ADC("ADC2_WORK", "Capture", RK3308_ADC_ANA_CON05(0), 6, 0),
+	SND_SOC_DAPM_ADC("ADC3_WORK", "Capture", RK3308_ADC_ANA_CON05(1), 2, 0),
+	SND_SOC_DAPM_ADC("ADC4_WORK", "Capture", RK3308_ADC_ANA_CON05(1), 6, 0),
+	SND_SOC_DAPM_ADC("ADC5_WORK", "Capture", RK3308_ADC_ANA_CON05(2), 2, 0),
+	SND_SOC_DAPM_ADC("ADC6_WORK", "Capture", RK3308_ADC_ANA_CON05(2), 6, 0),
+	SND_SOC_DAPM_ADC("ADC7_WORK", "Capture", RK3308_ADC_ANA_CON05(3), 2, 0),
+	SND_SOC_DAPM_ADC("ADC8_WORK", "Capture", RK3308_ADC_ANA_CON05(3), 6, 0),
+
+	/* The "ALC" name from the TRM is misleading, these are needed even without ALC/AGC */
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC1_WORK", RK3308_ADC_ANA_CON02(0), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC2_WORK", RK3308_ADC_ANA_CON02(0), 5, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC3_WORK", RK3308_ADC_ANA_CON02(1), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC4_WORK", RK3308_ADC_ANA_CON02(1), 5, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC5_WORK", RK3308_ADC_ANA_CON02(2), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC6_WORK", RK3308_ADC_ANA_CON02(2), 5, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC7_WORK", RK3308_ADC_ANA_CON02(3), 1, 1, 1, 0),
+	SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC8_WORK", RK3308_ADC_ANA_CON02(3), 5, 1, 1, 0),
+
+	SND_SOC_DAPM_SUPPLY("MICBIAS Current", RK3308_ADC_ANA_CON08(0), 4, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("MICBIAS1", RK3308_ADC_ANA_CON07(1), 3, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("MICBIAS2", RK3308_ADC_ANA_CON07(2), 3, 0, NULL, 0),
+
+	SND_SOC_DAPM_OUT_DRV("DAC_L_HPMIX_EN",   RK3308_DAC_ANA_CON13, 0, 0, NULL, 0),
+	SND_SOC_DAPM_OUT_DRV("DAC_R_HPMIX_EN",   RK3308_DAC_ANA_CON13, 4, 0, NULL, 0),
+	SND_SOC_DAPM_OUT_DRV("DAC_L_HPMIX_WORK", RK3308_DAC_ANA_CON13, 1, 0, NULL, 0),
+	SND_SOC_DAPM_OUT_DRV("DAC_R_HPMIX_WORK", RK3308_DAC_ANA_CON13, 5, 0, NULL, 0),
+	/* HPMIX is not actually acting as a mixer as the only supported input is I2S */
+	SND_SOC_DAPM_OUT_DRV("DAC_L_HPMIX_SEL",  RK3308_DAC_ANA_CON12, 2, 0, NULL, 0),
+	SND_SOC_DAPM_OUT_DRV("DAC_R_HPMIX_SEL",  RK3308_DAC_ANA_CON12, 6, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("DAC HPMIX Left",     RK3308_DAC_ANA_CON13, 2, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("DAC HPMIX Right",    RK3308_DAC_ANA_CON13, 6, 0, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("DAC_MCLK_GATE", RK3308_GLB_CON, 4, 1, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("DAC_CURRENT_EN", RK3308_DAC_ANA_CON00, 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("DAC_L_REF_EN",   RK3308_DAC_ANA_CON02, 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("DAC_R_REF_EN",   RK3308_DAC_ANA_CON02, 4, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("DAC_L_CLK_EN",   RK3308_DAC_ANA_CON02, 1, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("DAC_R_CLK_EN",   RK3308_DAC_ANA_CON02, 5, 0, NULL, 0),
+	SND_SOC_DAPM_DAC("DAC_L_DAC_WORK", NULL, RK3308_DAC_ANA_CON02, 3, 0),
+	SND_SOC_DAPM_DAC("DAC_R_DAC_WORK", NULL, RK3308_DAC_ANA_CON02, 7, 0),
+
+	SND_SOC_DAPM_SUPPLY("DAC_BUF_REF_L", RK3308_DAC_ANA_CON01, 2, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("DAC_BUF_REF_R", RK3308_DAC_ANA_CON01, 6, 0, NULL, 0),
+	SND_SOC_DAPM_OUT_DRV_E("HPOUT_POP_SOUND_L", SND_SOC_NOPM, 0, 0, NULL, 0,
+			       rk3308_codec_pop_sound_set,
+			       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	SND_SOC_DAPM_OUT_DRV_E("HPOUT_POP_SOUND_R", SND_SOC_NOPM, 4, 0, NULL, 0,
+			       rk3308_codec_pop_sound_set,
+			       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	SND_SOC_DAPM_OUT_DRV("L_HPOUT_EN", RK3308_DAC_ANA_CON03, 1, 0, NULL, 0),
+	SND_SOC_DAPM_OUT_DRV("R_HPOUT_EN", RK3308_DAC_ANA_CON03, 5, 0, NULL, 0),
+	SND_SOC_DAPM_OUT_DRV("L_HPOUT_WORK", RK3308_DAC_ANA_CON03, 2, 0, NULL, 0),
+	SND_SOC_DAPM_OUT_DRV("R_HPOUT_WORK", RK3308_DAC_ANA_CON03, 6, 0, NULL, 0),
+	SND_SOC_DAPM_OUTPUT("HPOUT_L"),
+	SND_SOC_DAPM_OUTPUT("HPOUT_R"),
+
+	SND_SOC_DAPM_OUT_DRV("L_LINEOUT_EN", RK3308_DAC_ANA_CON04, 0, 0, NULL, 0),
+	SND_SOC_DAPM_OUT_DRV("R_LINEOUT_EN", RK3308_DAC_ANA_CON04, 4, 0, NULL, 0),
+	SND_SOC_DAPM_OUTPUT("LINEOUT_L"),
+	SND_SOC_DAPM_OUTPUT("LINEOUT_R"),
+};
+
+static const struct snd_soc_dapm_route rk3308_codec_dapm_routes[] = {
+	{ "MICBIAS1", NULL, "MICBIAS Current" },
+	{ "MICBIAS2", NULL, "MICBIAS Current" },
+
+	{ "MIC1_EN", NULL, "MIC1" },
+	{ "MIC2_EN", NULL, "MIC2" },
+	{ "MIC3_EN", NULL, "MIC3" },
+	{ "MIC4_EN", NULL, "MIC4" },
+	{ "MIC5_EN", NULL, "MIC5" },
+	{ "MIC6_EN", NULL, "MIC6" },
+	{ "MIC7_EN", NULL, "MIC7" },
+	{ "MIC8_EN", NULL, "MIC8" },
+
+	{ "MIC1_WORK", NULL, "MIC1_EN" },
+	{ "MIC2_WORK", NULL, "MIC2_EN" },
+	{ "MIC3_WORK", NULL, "MIC3_EN" },
+	{ "MIC4_WORK", NULL, "MIC4_EN" },
+	{ "MIC5_WORK", NULL, "MIC5_EN" },
+	{ "MIC6_WORK", NULL, "MIC6_EN" },
+	{ "MIC7_WORK", NULL, "MIC7_EN" },
+	{ "MIC8_WORK", NULL, "MIC8_EN" },
+
+	{ "CH1_IN_SEL", NULL, "MIC1_WORK" },
+	{ "CH2_IN_SEL", NULL, "MIC2_WORK" },
+
+	{ "ALC1_EN", NULL, "CH1_IN_SEL" },
+	{ "ALC2_EN", NULL, "CH2_IN_SEL" },
+	{ "ALC3_EN", NULL, "MIC3_WORK" },
+	{ "ALC4_EN", NULL, "MIC4_WORK" },
+	{ "ALC5_EN", NULL, "MIC5_WORK" },
+	{ "ALC6_EN", NULL, "MIC6_WORK" },
+	{ "ALC7_EN", NULL, "MIC7_WORK" },
+	{ "ALC8_EN", NULL, "MIC8_WORK" },
+
+	{ "ADC1_EN", NULL, "ALC1_EN" },
+	{ "ADC2_EN", NULL, "ALC2_EN" },
+	{ "ADC3_EN", NULL, "ALC3_EN" },
+	{ "ADC4_EN", NULL, "ALC4_EN" },
+	{ "ADC5_EN", NULL, "ALC5_EN" },
+	{ "ADC6_EN", NULL, "ALC6_EN" },
+	{ "ADC7_EN", NULL, "ALC7_EN" },
+	{ "ADC8_EN", NULL, "ALC8_EN" },
+
+	{ "ADC1_WORK", NULL, "ADC1_EN" },
+	{ "ADC2_WORK", NULL, "ADC2_EN" },
+	{ "ADC3_WORK", NULL, "ADC3_EN" },
+	{ "ADC4_WORK", NULL, "ADC4_EN" },
+	{ "ADC5_WORK", NULL, "ADC5_EN" },
+	{ "ADC6_WORK", NULL, "ADC6_EN" },
+	{ "ADC7_WORK", NULL, "ADC7_EN" },
+	{ "ADC8_WORK", NULL, "ADC8_EN" },
+
+	{ "ADC1_BUF_REF_EN", NULL, "ADC_CURRENT_EN12" },
+	{ "ADC2_BUF_REF_EN", NULL, "ADC_CURRENT_EN12" },
+	{ "ADC3_BUF_REF_EN", NULL, "ADC_CURRENT_EN34" },
+	{ "ADC4_BUF_REF_EN", NULL, "ADC_CURRENT_EN34" },
+	{ "ADC5_BUF_REF_EN", NULL, "ADC_CURRENT_EN56" },
+	{ "ADC6_BUF_REF_EN", NULL, "ADC_CURRENT_EN56" },
+	{ "ADC7_BUF_REF_EN", NULL, "ADC_CURRENT_EN78" },
+	{ "ADC8_BUF_REF_EN", NULL, "ADC_CURRENT_EN78" },
+
+	{ "ADC1_WORK", NULL, "ADC1_BUF_REF_EN" },
+	{ "ADC2_WORK", NULL, "ADC2_BUF_REF_EN" },
+	{ "ADC3_WORK", NULL, "ADC3_BUF_REF_EN" },
+	{ "ADC4_WORK", NULL, "ADC4_BUF_REF_EN" },
+	{ "ADC5_WORK", NULL, "ADC5_BUF_REF_EN" },
+	{ "ADC6_WORK", NULL, "ADC6_BUF_REF_EN" },
+	{ "ADC7_WORK", NULL, "ADC7_BUF_REF_EN" },
+	{ "ADC8_WORK", NULL, "ADC8_BUF_REF_EN" },
+
+	{ "ADC1_CLK_EN", NULL, "ADC_MCLK_GATE" },
+	{ "ADC2_CLK_EN", NULL, "ADC_MCLK_GATE" },
+	{ "ADC3_CLK_EN", NULL, "ADC_MCLK_GATE" },
+	{ "ADC4_CLK_EN", NULL, "ADC_MCLK_GATE" },
+	{ "ADC5_CLK_EN", NULL, "ADC_MCLK_GATE" },
+	{ "ADC6_CLK_EN", NULL, "ADC_MCLK_GATE" },
+	{ "ADC7_CLK_EN", NULL, "ADC_MCLK_GATE" },
+	{ "ADC8_CLK_EN", NULL, "ADC_MCLK_GATE" },
+
+	{ "ADC1_WORK", NULL, "ADC1_CLK_EN" },
+	{ "ADC2_WORK", NULL, "ADC2_CLK_EN" },
+	{ "ADC3_WORK", NULL, "ADC3_CLK_EN" },
+	{ "ADC4_WORK", NULL, "ADC4_CLK_EN" },
+	{ "ADC5_WORK", NULL, "ADC5_CLK_EN" },
+	{ "ADC6_WORK", NULL, "ADC6_CLK_EN" },
+	{ "ADC7_WORK", NULL, "ADC7_CLK_EN" },
+	{ "ADC8_WORK", NULL, "ADC8_CLK_EN" },
+
+	{ "ALC1_WORK", NULL, "ADC1_WORK" },
+	{ "ALC2_WORK", NULL, "ADC2_WORK" },
+	{ "ALC3_WORK", NULL, "ADC3_WORK" },
+	{ "ALC4_WORK", NULL, "ADC4_WORK" },
+	{ "ALC5_WORK", NULL, "ADC5_WORK" },
+	{ "ALC6_WORK", NULL, "ADC6_WORK" },
+	{ "ALC7_WORK", NULL, "ADC7_WORK" },
+	{ "ALC8_WORK", NULL, "ADC8_WORK" },
+
+	{ "HiFi Capture", NULL, "ALC1_WORK" },
+	{ "HiFi Capture", NULL, "ALC2_WORK" },
+	{ "HiFi Capture", NULL, "ALC3_WORK" },
+	{ "HiFi Capture", NULL, "ALC4_WORK" },
+	{ "HiFi Capture", NULL, "ALC5_WORK" },
+	{ "HiFi Capture", NULL, "ALC6_WORK" },
+	{ "HiFi Capture", NULL, "ALC7_WORK" },
+	{ "HiFi Capture", NULL, "ALC8_WORK" },
+
+	{ "DAC_L_HPMIX_EN", NULL, "HiFi Playback" },
+	{ "DAC_R_HPMIX_EN", NULL, "HiFi Playback" },
+	{ "DAC_L_HPMIX_WORK", NULL, "DAC_L_HPMIX_EN" },
+	{ "DAC_R_HPMIX_WORK", NULL, "DAC_R_HPMIX_EN" },
+	{ "DAC HPMIX Left",  NULL, "DAC_L_HPMIX_WORK" },
+	{ "DAC HPMIX Right", NULL, "DAC_R_HPMIX_WORK" },
+
+	{ "DAC_L_DAC_WORK", NULL, "DAC HPMIX Left"  },
+	{ "DAC_R_DAC_WORK", NULL, "DAC HPMIX Right" },
+
+	{ "DAC_L_REF_EN", NULL, "DAC_CURRENT_EN" },
+	{ "DAC_R_REF_EN", NULL, "DAC_CURRENT_EN" },
+	{ "DAC_L_CLK_EN", NULL, "DAC_L_REF_EN" },
+	{ "DAC_R_CLK_EN", NULL, "DAC_R_REF_EN" },
+	{ "DAC_L_CLK_EN", NULL, "DAC_MCLK_GATE" },
+	{ "DAC_R_CLK_EN", NULL, "DAC_MCLK_GATE" },
+	{ "DAC_L_DAC_WORK", NULL, "DAC_L_CLK_EN" },
+	{ "DAC_R_DAC_WORK", NULL, "DAC_R_CLK_EN" },
+	{ "DAC_L_HPMIX_SEL", NULL, "DAC_L_DAC_WORK" },
+	{ "DAC_R_HPMIX_SEL", NULL, "DAC_R_DAC_WORK" },
+
+	{ "HPOUT_L", NULL, "DAC_BUF_REF_L" },
+	{ "HPOUT_R", NULL, "DAC_BUF_REF_R" },
+	{ "L_HPOUT_EN", NULL, "DAC_L_HPMIX_SEL" },
+	{ "R_HPOUT_EN", NULL, "DAC_R_HPMIX_SEL" },
+	{ "L_HPOUT_WORK", NULL, "L_HPOUT_EN" },
+	{ "R_HPOUT_WORK", NULL, "R_HPOUT_EN" },
+	{ "HPOUT_POP_SOUND_L", NULL, "L_HPOUT_WORK" },
+	{ "HPOUT_POP_SOUND_R", NULL, "R_HPOUT_WORK" },
+	{ "HPOUT_L", NULL, "HPOUT_POP_SOUND_L" },
+	{ "HPOUT_R", NULL, "HPOUT_POP_SOUND_R" },
+
+	{ "L_LINEOUT_EN", NULL, "DAC_L_HPMIX_SEL" },
+	{ "R_LINEOUT_EN", NULL, "DAC_R_HPMIX_SEL" },
+	{ "LINEOUT_L", NULL, "L_LINEOUT_EN" },
+	{ "LINEOUT_R", NULL, "R_LINEOUT_EN" },
+};
+
+static int rk3308_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
+				    unsigned int fmt)
+{
+	struct snd_soc_component *component = codec_dai->component;
+	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
+	const unsigned int inv_bits = fmt & SND_SOC_DAIFMT_INV_MASK;
+	const bool inv_bitclk =
+		(inv_bits & SND_SOC_DAIFMT_IB_IF) ||
+		(inv_bits & SND_SOC_DAIFMT_IB_NF);
+	const bool inv_frmclk =
+		(inv_bits & SND_SOC_DAIFMT_IB_IF) ||
+		(inv_bits & SND_SOC_DAIFMT_NB_IF);
+	const unsigned int dac_master_bits = rk3308->codec_ver < ACODEC_VERSION_C ?
+		RK3308_DAC_IO_MODE_MASTER   | RK3308_DAC_MODE_MASTER  :
+		RK3308BS_DAC_IO_MODE_MASTER | RK3308BS_DAC_MODE_MASTER;
+	unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0;
+	bool is_master = false;
+	int grp;
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBC_CFC:
+		break;
+	case SND_SOC_DAIFMT_CBP_CFP:
+		adc_aif2 |= RK3308_ADC_IO_MODE_MASTER;
+		adc_aif2 |= RK3308_ADC_MODE_MASTER;
+		dac_aif2 |= dac_master_bits;
+		is_master = true;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_DSP_A:
+		adc_aif1 |= RK3308_ADC_I2S_MODE_PCM;
+		dac_aif1 |= RK3308_DAC_I2S_MODE_PCM;
+		break;
+	case SND_SOC_DAIFMT_I2S:
+		adc_aif1 |= RK3308_ADC_I2S_MODE_I2S;
+		dac_aif1 |= RK3308_DAC_I2S_MODE_I2S;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		adc_aif1 |= RK3308_ADC_I2S_MODE_RJ;
+		dac_aif1 |= RK3308_DAC_I2S_MODE_RJ;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		adc_aif1 |= RK3308_ADC_I2S_MODE_LJ;
+		dac_aif1 |= RK3308_DAC_I2S_MODE_LJ;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (inv_bitclk) {
+		adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL;
+		dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL;
+	}
+
+	if (inv_frmclk) {
+		adc_aif1 |= RK3308_ADC_I2S_LRC_POL_REVERSAL;
+		dac_aif1 |= RK3308_DAC_I2S_LRC_POL_REVERSAL;
+	}
+
+	/*
+	 * Hold ADC Digital registers start at master mode
+	 *
+	 * There are 8 ADCs which use the same internal SCLK and LRCK for
+	 * master mode. We need to make sure that they are in effect at the
+	 * same time, otherwise they will cause abnormal clocks.
+	 */
+	if (is_master)
+		regmap_clear_bits(rk3308->regmap, RK3308_GLB_CON, RK3308_ADC_DIG_WORK);
+
+	for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) {
+		regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(grp),
+				   RK3308_ADC_I2S_LRC_POL_REVERSAL |
+				   RK3308_ADC_I2S_MODE_MSK,
+				   adc_aif1);
+		regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(grp),
+				   RK3308_ADC_IO_MODE_MASTER |
+				   RK3308_ADC_MODE_MASTER |
+				   RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL,
+				   adc_aif2);
+	}
+
+	/* Hold ADC Digital registers end at master mode */
+	if (is_master)
+		regmap_set_bits(rk3308->regmap, RK3308_GLB_CON, RK3308_ADC_DIG_WORK);
+
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01,
+			   RK3308_DAC_I2S_LRC_POL_REVERSAL |
+			   RK3308_DAC_I2S_MODE_MSK,
+			   dac_aif1);
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02,
+			   dac_master_bits | RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL,
+			   dac_aif2);
+
+	return 0;
+}
+
+static int rk3308_codec_dac_dig_config(struct rk3308_codec_priv *rk3308,
+				       struct snd_pcm_hw_params *params)
+{
+	unsigned int dac_aif1 = 0;
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_16BITS;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_20BITS;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_24BITS;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_32BITS;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01,
+			   RK3308_DAC_I2S_VALID_LEN_MSK, dac_aif1);
+	regmap_set_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, RK3308_DAC_I2S_WORK);
+
+	return 0;
+}
+
+static int rk3308_codec_adc_dig_config(struct rk3308_codec_priv *rk3308,
+				       struct snd_pcm_hw_params *params)
+{
+	unsigned int adc_aif1 = 0;
+	/*
+	 * grp 0 = ADC1 and ADC2
+	 * grp 1 = ADC3 and ADC4
+	 * grp 2 = ADC5 and ADC6
+	 * grp 3 = ADC7 and ADC8
+	 */
+	u32 used_adc_grps;
+	int grp;
+
+	switch (params_channels(params)) {
+	case 1:
+		adc_aif1 |= RK3308_ADC_I2S_MONO;
+		used_adc_grps = 1;
+		break;
+	case 2:
+	case 4:
+	case 6:
+	case 8:
+		used_adc_grps = params_channels(params) / 2;
+		break;
+	default:
+		dev_err(rk3308->dev, "Invalid channel number %d\n", params_channels(params));
+		return -EINVAL;
+	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_16BITS;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_20BITS;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_24BITS;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_32BITS;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	for (grp = 0; grp < used_adc_grps; grp++) {
+		regmap_update_bits(rk3308->regmap,
+				   RK3308_ADC_DIG_CON03(grp),
+				   RK3308_ADC_L_CH_BIST_MSK | RK3308_ADC_R_CH_BIST_MSK,
+				   RK3308_ADC_L_CH_NORMAL_LEFT | RK3308_ADC_R_CH_NORMAL_RIGHT);
+		regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(grp),
+				   RK3308_ADC_I2S_VALID_LEN_MSK | RK3308_ADC_I2S_MONO, adc_aif1);
+		regmap_set_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(grp), RK3308_ADC_I2S_WORK);
+	}
+
+	return 0;
+}
+
+static int rk3308_codec_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *params,
+				  struct snd_soc_dai *dai)
+{
+	struct snd_soc_component *component = dai->component;
+	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
+
+	return (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+		rk3308_codec_dac_dig_config(rk3308, params) :
+		rk3308_codec_adc_dig_config(rk3308, params);
+}
+
+static const struct snd_soc_dai_ops rk3308_codec_dai_ops = {
+	.hw_params = rk3308_codec_hw_params,
+	.set_fmt = rk3308_codec_set_dai_fmt,
+};
+
+static struct snd_soc_dai_driver rk3308_codec_dai[] = {
+	{
+		.name = "rk3308-hifi",
+		.playback = {
+			.stream_name = "HiFi Playback",
+			.channels_min = 2,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+				    SNDRV_PCM_FMTBIT_S20_3LE |
+				    SNDRV_PCM_FMTBIT_S24_LE |
+				    SNDRV_PCM_FMTBIT_S32_LE),
+		},
+		.capture = {
+			.stream_name = "HiFi Capture",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+				    SNDRV_PCM_FMTBIT_S20_3LE |
+				    SNDRV_PCM_FMTBIT_S24_LE |
+				    SNDRV_PCM_FMTBIT_S32_LE),
+		},
+		.ops = &rk3308_codec_dai_ops,
+	},
+};
+
+static void rk3308_codec_reset(struct snd_soc_component *component)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
+
+	reset_control_assert(rk3308->reset);
+	usleep_range(10000, 11000);     /* estimated value */
+	reset_control_deassert(rk3308->reset);
+
+	regmap_write(rk3308->regmap, RK3308_GLB_CON, 0x00);
+	usleep_range(10000, 11000);     /* estimated value */
+	regmap_write(rk3308->regmap, RK3308_GLB_CON,
+		     RK3308_SYS_WORK |
+		     RK3308_DAC_DIG_WORK |
+		     RK3308_ADC_DIG_WORK);
+}
+
+/*
+ * Initialize register whose default after HW reset is problematic or which
+ * are never modified.
+ */
+static int rk3308_codec_initialize(struct rk3308_codec_priv *rk3308)
+{
+	int grp;
+
+	/*
+	 * Init ADC digital vol to 0 dB (reset value is 0xff, undocumented).
+	 * Range: -97dB ~ +32dB.
+	 */
+	if (rk3308->codec_ver == ACODEC_VERSION_C) {
+		for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) {
+			regmap_write(rk3308->regmap, RK3308_ADC_DIG_CON05(grp),
+					   RK3308_ADC_DIG_VOL_CON_x_0DB);
+			regmap_write(rk3308->regmap, RK3308_ADC_DIG_CON06(grp),
+					   RK3308_ADC_DIG_VOL_CON_x_0DB);
+		}
+	}
+
+	/* set HPMIX default gains (reset value is 0, which is illegal) */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12,
+			   RK3308_DAC_L_HPMIX_GAIN_MSK |
+			   RK3308_DAC_R_HPMIX_GAIN_MSK,
+			   RK3308_DAC_L_HPMIX_GAIN_NDB_6 |
+			   RK3308_DAC_R_HPMIX_GAIN_NDB_6);
+
+	/* recover DAC digital gain to 0 dB (reset value is 0xff, undocumented) */
+	if (rk3308->codec_ver == ACODEC_VERSION_C)
+		regmap_write(rk3308->regmap, RK3308_DAC_DIG_CON04,
+			     RK3308BS_DAC_DIG_GAIN_0DB);
+
+	/*
+	 * Unconditionally enable zero-cross detection (needed for AGC,
+	 * harmless without AGC)
+	 */
+	for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++)
+		regmap_set_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(grp),
+				RK3308_ADC_CH1_ZEROCROSS_DET_EN |
+				RK3308_ADC_CH2_ZEROCROSS_DET_EN);
+
+	return 0;
+}
+
+static int rk3308_codec_probe(struct snd_soc_component *component)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
+
+	rk3308->component = component;
+
+	rk3308_codec_reset(component);
+	rk3308_codec_initialize(rk3308);
+
+	return 0;
+}
+
+static int rk3308_codec_set_bias_level(struct snd_soc_component *component,
+				       enum snd_soc_bias_level level)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
+
+	switch (level) {
+	case SND_SOC_BIAS_ON:
+		break;
+	case SND_SOC_BIAS_PREPARE:
+		break;
+	case SND_SOC_BIAS_STANDBY:
+		if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_OFF)
+			break;
+
+		/* Sequence from TRM Section 8.6.3 "Power Up" */
+		regmap_set_bits(rk3308->regmap, RK3308_DAC_ANA_CON02,
+				RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN);
+		regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+				   RK3308_ADC_CURRENT_CHARGE_MSK, 1);
+		regmap_set_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+				RK3308_ADC_REF_EN);
+		regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+				   RK3308_ADC_CURRENT_CHARGE_MSK, 0x7f);
+		msleep(20);	/* estimated value */
+		break;
+	case SND_SOC_BIAS_OFF:
+		/* Sequence from TRM Section 8.6.4 "Power Down" */
+		regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+				   RK3308_ADC_CURRENT_CHARGE_MSK, 1);
+		regmap_clear_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+				  RK3308_ADC_REF_EN);
+		regmap_clear_bits(rk3308->regmap, RK3308_DAC_ANA_CON02,
+				  RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN);
+		msleep(20);	/* estimated value */
+		break;
+	}
+	return 0;
+}
+
+static const struct snd_soc_component_driver soc_codec_dev_rk3308 = {
+	.probe = rk3308_codec_probe,
+	.set_bias_level = rk3308_codec_set_bias_level,
+	.controls = rk3308_codec_controls,
+	.num_controls = ARRAY_SIZE(rk3308_codec_controls),
+	.dapm_widgets = rk3308_codec_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(rk3308_codec_dapm_widgets),
+	.dapm_routes = rk3308_codec_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(rk3308_codec_dapm_routes),
+};
+
+static const struct regmap_config rk3308_codec_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = RK3308_DAC_ANA_CON15,
+};
+
+static int rk3308_codec_get_version(struct rk3308_codec_priv *rk3308)
+{
+	unsigned int chip_id;
+	int err;
+
+	err = regmap_read(rk3308->grf, GRF_CHIP_ID, &chip_id);
+	if (err)
+		return err;
+
+	switch (chip_id) {
+	case 3306:
+		rk3308->codec_ver = ACODEC_VERSION_A;
+		break;
+	case 0x3308:
+		rk3308->codec_ver = ACODEC_VERSION_B;
+		return dev_err_probe(rk3308->dev, -EINVAL, "Chip version B not supported\n");
+	case 0x3308c:
+		rk3308->codec_ver = ACODEC_VERSION_C;
+		break;
+	default:
+		return dev_err_probe(rk3308->dev, -EINVAL, "Unknown chip_id: 0x%x\n", chip_id);
+	}
+
+	dev_info(rk3308->dev, "Found codec version %c\n", rk3308->codec_ver);
+	return 0;
+}
+
+static int rk3308_codec_set_micbias_level(struct rk3308_codec_priv *rk3308)
+{
+	struct device_node *np = rk3308->dev->of_node;
+	u32 percent;
+	u32 mult;
+	int err;
+
+	err = of_property_read_u32(np, "rockchip,micbias-avdd-percent", &percent);
+	if (err == -EINVAL)
+		return 0;
+	if (err)
+		return dev_err_probe(rk3308->dev, err,
+				     "Error reading 'rockchip,micbias-avdd-percent'\n");
+
+	/* Convert percent to register value, linerarly (50% -> 0, 5% step = +1) */
+	mult = (percent - 50) / 5;
+
+	/* Check range and that the percent was an exact value allowed */
+	if (mult > RK3308_ADC_LEVEL_RANGE_MICBIAS_MAX || mult * 5 + 50 != percent)
+		return dev_err_probe(rk3308->dev, -EINVAL,
+				     "Invalid value %u for 'rockchip,micbias-avdd-percent'\n",
+				     percent);
+
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(0),
+			   RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK,
+			   mult << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT);
+
+	return 0;
+}
+
+static int rk3308_codec_platform_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct rk3308_codec_priv *rk3308;
+	void __iomem *base;
+	int err;
+
+	rk3308 = devm_kzalloc(&pdev->dev, sizeof(*rk3308), GFP_KERNEL);
+	if (!rk3308)
+		return -ENOMEM;
+
+	rk3308->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(rk3308->grf))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rk3308->grf),
+			"Missing 'rockchip,grf' property\n");
+
+	rk3308->dev = &pdev->dev;
+
+	rk3308->reset = devm_reset_control_get(&pdev->dev, "codec");
+	if (IS_ERR(rk3308->reset)) {
+		err = PTR_ERR(rk3308->reset);
+		if (err != -ENOENT)
+			return err;
+
+		dev_dbg(&pdev->dev, "No reset control found\n");
+		rk3308->reset = NULL;
+	}
+
+	rk3308->hclk = devm_clk_get(&pdev->dev, "hclk");
+	if (IS_ERR(rk3308->hclk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rk3308->hclk), "Can't get hclk\n");
+
+	rk3308->mclk_rx = devm_clk_get(&pdev->dev, "mclk_rx");
+	if (IS_ERR(rk3308->mclk_rx))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rk3308->mclk_rx), "Can't get mclk_rx\n");
+
+	rk3308->mclk_tx = devm_clk_get(&pdev->dev, "mclk_tx");
+	if (IS_ERR(rk3308->mclk_tx))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rk3308->mclk_tx), "Can't get mclk_tx\n");
+
+	err = clk_prepare_enable(rk3308->hclk);
+	if (err)
+		return dev_err_probe(&pdev->dev, err, "Failed to enable hclk\n");
+
+	err = clk_prepare_enable(rk3308->mclk_rx);
+	if (err)
+		return dev_err_probe(&pdev->dev, err, "Failed to enable mclk_rx\n");
+
+	err = clk_prepare_enable(rk3308->mclk_tx);
+	if (err)
+		return dev_err_probe(&pdev->dev, err, "Failed to enable mclk_tx\n");
+
+	err = rk3308_codec_get_version(rk3308);
+	if (err)
+		return err;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	rk3308->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+					       &rk3308_codec_regmap_config);
+	if (IS_ERR(rk3308->regmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rk3308->regmap),
+				     "Failed to init regmap\n");
+
+	platform_set_drvdata(pdev, rk3308);
+
+	err = rk3308_codec_set_micbias_level(rk3308);
+	if (err)
+		return err;
+
+	err = devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_rk3308,
+					      rk3308_codec_dai, ARRAY_SIZE(rk3308_codec_dai));
+	if (err)
+		return dev_err_probe(&pdev->dev, err, "Failed to register codec\n");
+
+	return 0;
+}
+
+static const struct of_device_id rk3308_codec_of_match[] = {
+	{ .compatible = "rockchip,rk3308-codec", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, rk3308_codec_of_match);
+
+static struct platform_driver rk3308_codec_driver = {
+	.driver = {
+		.name = "rk3308-acodec",
+		.of_match_table = of_match_ptr(rk3308_codec_of_match),
+	},
+	.probe = rk3308_codec_platform_probe,
+};
+module_platform_driver(rk3308_codec_driver);
+
+MODULE_AUTHOR("Xing Zheng <zhengxing at rock-chips.com>");
+MODULE_AUTHOR("Luca Ceresoli <luca.ceresoli at bootlin.com>");
+MODULE_DESCRIPTION("ASoC RK3308 Codec Driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/rk3308_codec.h b/sound/soc/codecs/rk3308_codec.h
new file mode 100644
index 000000000000..a4226b235ab7
--- /dev/null
+++ b/sound/soc/codecs/rk3308_codec.h
@@ -0,0 +1,579 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Rockchip RK3308 internal audio codec driver -- register definitions
+ *
+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
+ * Copyright (c) 2022, Vivax-Metrotech Ltd
+ */
+
+#ifndef __RK3308_CODEC_H__
+#define __RK3308_CODEC_H__
+
+#define RK3308_GLB_CON				0x00
+
+/* ADC DIGITAL REGISTERS */
+
+/*
+ * The ADC group are 0 ~ 3, that control:
+ *
+ * CH0: left_0(ADC1) and right_0(ADC2)
+ * CH1: left_1(ADC3) and right_1(ADC4)
+ * CH2: left_2(ADC5) and right_2(ADC6)
+ * CH3: left_3(ADC7) and right_3(ADC8)
+ */
+#define RK3308_ADC_DIG_OFFSET(ch)		(((ch) & 0x3) * 0xc0 + 0x0)
+
+#define RK3308_ADC_DIG_CON01(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x04)
+#define RK3308_ADC_DIG_CON02(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x08)
+#define RK3308_ADC_DIG_CON03(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x0c)
+#define RK3308_ADC_DIG_CON04(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x10)
+#define RK3308_ADC_DIG_CON05(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x14) // ver.C only
+#define RK3308_ADC_DIG_CON06(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x18) // ver.C only
+#define RK3308_ADC_DIG_CON07(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x1c)
+
+#define RK3308_ALC_L_DIG_CON00(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x40)
+#define RK3308_ALC_L_DIG_CON01(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x44)
+#define RK3308_ALC_L_DIG_CON02(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x48)
+#define RK3308_ALC_L_DIG_CON03(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x4c)
+#define RK3308_ALC_L_DIG_CON04(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x50)
+#define RK3308_ALC_L_DIG_CON05(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x54)
+#define RK3308_ALC_L_DIG_CON06(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x58)
+#define RK3308_ALC_L_DIG_CON07(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x5c)
+#define RK3308_ALC_L_DIG_CON08(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x60)
+#define RK3308_ALC_L_DIG_CON09(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x64)
+#define RK3308_ALC_L_DIG_CON12(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x70)
+
+#define RK3308_ALC_R_DIG_CON00(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x80)
+#define RK3308_ALC_R_DIG_CON01(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x84)
+#define RK3308_ALC_R_DIG_CON02(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x88)
+#define RK3308_ALC_R_DIG_CON03(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x8c)
+#define RK3308_ALC_R_DIG_CON04(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x90)
+#define RK3308_ALC_R_DIG_CON05(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x94)
+#define RK3308_ALC_R_DIG_CON06(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x98)
+#define RK3308_ALC_R_DIG_CON07(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0x9c)
+#define RK3308_ALC_R_DIG_CON08(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0xa0)
+#define RK3308_ALC_R_DIG_CON09(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0xa4)
+#define RK3308_ALC_R_DIG_CON12(ch)		(RK3308_ADC_DIG_OFFSET((ch)) + 0xb0)
+
+/* DAC DIGITAL REGISTERS */
+#define RK3308_DAC_DIG_OFFSET			0x300
+#define RK3308_DAC_DIG_CON01			(RK3308_DAC_DIG_OFFSET + 0x04)
+#define RK3308_DAC_DIG_CON02			(RK3308_DAC_DIG_OFFSET + 0x08)
+#define RK3308_DAC_DIG_CON03			(RK3308_DAC_DIG_OFFSET + 0x0c)
+#define RK3308_DAC_DIG_CON04			(RK3308_DAC_DIG_OFFSET + 0x10)
+#define RK3308_DAC_DIG_CON05			(RK3308_DAC_DIG_OFFSET + 0x14)
+#define RK3308_DAC_DIG_CON10			(RK3308_DAC_DIG_OFFSET + 0x28)
+#define RK3308_DAC_DIG_CON11			(RK3308_DAC_DIG_OFFSET + 0x2c)
+#define RK3308_DAC_DIG_CON13			(RK3308_DAC_DIG_OFFSET + 0x34)
+#define RK3308_DAC_DIG_CON14			(RK3308_DAC_DIG_OFFSET + 0x38)
+
+/* ADC ANALOG REGISTERS */
+/*
+ * The ADC group are 0 ~ 3, that control:
+ *
+ * CH0: left_0(ADC1) and right_0(ADC2)
+ * CH1: left_1(ADC3) and right_1(ADC4)
+ * CH2: left_2(ADC5) and right_2(ADC6)
+ * CH3: left_3(ADC7) and right_3(ADC8)
+ */
+#define RK3308_ADC_ANA_OFFSET(ch)		(((ch) & 0x3) * 0x40 + 0x340)
+#define RK3308_ADC_ANA_CON00(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x00)
+#define RK3308_ADC_ANA_CON01(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x04)
+#define RK3308_ADC_ANA_CON02(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x08)
+#define RK3308_ADC_ANA_CON03(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x0c)
+#define RK3308_ADC_ANA_CON04(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x10)
+#define RK3308_ADC_ANA_CON05(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x14)
+#define RK3308_ADC_ANA_CON06(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x18)
+#define RK3308_ADC_ANA_CON07(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x1c)
+#define RK3308_ADC_ANA_CON08(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x20)
+#define RK3308_ADC_ANA_CON10(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x28)
+#define RK3308_ADC_ANA_CON11(ch)		(RK3308_ADC_ANA_OFFSET((ch)) + 0x2c)
+
+/* DAC ANALOG REGISTERS */
+#define RK3308_DAC_ANA_OFFSET			0x440
+#define RK3308_DAC_ANA_CON00			(RK3308_DAC_ANA_OFFSET + 0x00)
+#define RK3308_DAC_ANA_CON01			(RK3308_DAC_ANA_OFFSET + 0x04)
+#define RK3308_DAC_ANA_CON02			(RK3308_DAC_ANA_OFFSET + 0x08)
+#define RK3308_DAC_ANA_CON03			(RK3308_DAC_ANA_OFFSET + 0x0c)
+#define RK3308_DAC_ANA_CON04			(RK3308_DAC_ANA_OFFSET + 0x10)
+#define RK3308_DAC_ANA_CON05			(RK3308_DAC_ANA_OFFSET + 0x14)
+#define RK3308_DAC_ANA_CON06			(RK3308_DAC_ANA_OFFSET + 0x18)
+#define RK3308_DAC_ANA_CON07			(RK3308_DAC_ANA_OFFSET + 0x1c)
+#define RK3308_DAC_ANA_CON08			(RK3308_DAC_ANA_OFFSET + 0x20)
+#define RK3308_DAC_ANA_CON12			(RK3308_DAC_ANA_OFFSET + 0x30)
+#define RK3308_DAC_ANA_CON13			(RK3308_DAC_ANA_OFFSET + 0x34)
+#define RK3308_DAC_ANA_CON14			(RK3308_DAC_ANA_OFFSET + 0x38)
+#define RK3308_DAC_ANA_CON15			(RK3308_DAC_ANA_OFFSET + 0x3c)
+
+/*
+ * These are the bits for registers
+ */
+
+/* RK3308_GLB_CON - REG: 0x0000 */
+#define RK3308_ADC_BIST_WORK			BIT(7)
+#define RK3308_DAC_BIST_WORK			BIT(6)
+#define RK3308_ADC_MCLK_GATING			BIT(5)
+#define RK3308_DAC_MCLK_GATING			BIT(4)
+#define RK3308_ADC_DIG_WORK			BIT(2)
+#define RK3308_DAC_DIG_WORK			BIT(1)
+#define RK3308_SYS_WORK				BIT(0)
+
+/* RK3308_ADC_DIG_CON01 - REG: 0x0004 */
+#define RK3308_ADC_I2S_LRC_POL_REVERSAL		BIT(7)
+#define RK3308_ADC_I2S_VALID_LEN_SFT		5
+#define RK3308_ADC_I2S_VALID_LEN_MSK		(0x3 << RK3308_ADC_I2S_VALID_LEN_SFT)
+#define RK3308_ADC_I2S_VALID_LEN_32BITS		(0x3 << RK3308_ADC_I2S_VALID_LEN_SFT)
+#define RK3308_ADC_I2S_VALID_LEN_24BITS		(0x2 << RK3308_ADC_I2S_VALID_LEN_SFT)
+#define RK3308_ADC_I2S_VALID_LEN_20BITS		(0x1 << RK3308_ADC_I2S_VALID_LEN_SFT)
+#define RK3308_ADC_I2S_VALID_LEN_16BITS		(0x0 << RK3308_ADC_I2S_VALID_LEN_SFT)
+#define RK3308_ADC_I2S_MODE_SFT			3
+#define RK3308_ADC_I2S_MODE_MSK			(0x3 << RK3308_ADC_I2S_MODE_SFT)
+#define RK3308_ADC_I2S_MODE_PCM			(0x3 << RK3308_ADC_I2S_MODE_SFT)
+#define RK3308_ADC_I2S_MODE_I2S			(0x2 << RK3308_ADC_I2S_MODE_SFT)
+#define RK3308_ADC_I2S_MODE_LJ			(0x1 << RK3308_ADC_I2S_MODE_SFT)
+#define RK3308_ADC_I2S_MODE_RJ			(0x0 << RK3308_ADC_I2S_MODE_SFT)
+#define RK3308_ADC_I2S_LR_SWAP			BIT(1)
+#define RK3308_ADC_I2S_MONO			BIT(0)
+
+/* RK3308_ADC_DIG_CON02 - REG: 0x0008 */
+#define RK3308_ADC_IO_MODE_MASTER		BIT(5)
+#define RK3308_ADC_MODE_MASTER			BIT(4)
+#define RK3308_ADC_I2S_FRAME_LEN_SFT		2
+#define RK3308_ADC_I2S_FRAME_LEN_MSK		(0x3 << RK3308_ADC_I2S_FRAME_LEN_SFT)
+#define RK3308_ADC_I2S_FRAME_32BITS		(0x3 << RK3308_ADC_I2S_FRAME_LEN_SFT)
+#define RK3308_ADC_I2S_FRAME_24BITS		(0x2 << RK3308_ADC_I2S_FRAME_LEN_SFT)
+#define RK3308_ADC_I2S_FRAME_20BITS		(0x1 << RK3308_ADC_I2S_FRAME_LEN_SFT)
+#define RK3308_ADC_I2S_FRAME_16BITS		(0x0 << RK3308_ADC_I2S_FRAME_LEN_SFT)
+#define RK3308_ADC_I2S_WORK			BIT(1)
+#define RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL	BIT(0)
+
+/* RK3308_ADC_DIG_CON03 - REG: 0x000c */
+#define RK3308_ADC_L_CH_BIST_SFT		2
+#define RK3308_ADC_L_CH_BIST_MSK		(0x3 << RK3308_ADC_L_CH_BIST_SFT)
+#define RK3308_ADC_L_CH_NORMAL_RIGHT		(0x3 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */
+#define RK3308_ADC_L_CH_BIST_CUBE		(0x2 << RK3308_ADC_L_CH_BIST_SFT)
+#define RK3308_ADC_L_CH_BIST_SINE		(0x1 << RK3308_ADC_L_CH_BIST_SFT)
+#define RK3308_ADC_L_CH_NORMAL_LEFT		(0x0 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */
+#define RK3308_ADC_R_CH_BIST_SFT		0
+#define RK3308_ADC_R_CH_BIST_MSK		(0x3 << RK3308_ADC_R_CH_BIST_SFT)
+#define RK3308_ADC_R_CH_NORMAL_LEFT		(0x3 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */
+#define RK3308_ADC_R_CH_BIST_CUBE		(0x2 << RK3308_ADC_R_CH_BIST_SFT)
+#define RK3308_ADC_R_CH_BIST_SINE		(0x1 << RK3308_ADC_R_CH_BIST_SFT)
+#define RK3308_ADC_R_CH_NORMAL_RIGHT		(0x0 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */
+
+/* RK3308_ADC_DIG_CON04 - REG: 0x0010 */
+#define RK3308_ADC_HPF_PATH_DIS			BIT(2)
+#define RK3308_ADC_HPF_CUTOFF_SFT		0
+#define RK3308_ADC_HPF_CUTOFF_MSK		(0x3 << RK3308_ADC_HPF_CUTOFF_SFT)
+#define RK3308_ADC_HPF_CUTOFF_612HZ		(0x2 << RK3308_ADC_HPF_CUTOFF_SFT)
+#define RK3308_ADC_HPF_CUTOFF_245HZ		(0x1 << RK3308_ADC_HPF_CUTOFF_SFT)
+#define RK3308_ADC_HPF_CUTOFF_20HZ		(0x0 << RK3308_ADC_HPF_CUTOFF_SFT)
+
+/* RK3308_ADC_DIG_CON07 - REG: 0x001c */
+#define RK3308_ADCL_DATA_SFT			4
+#define RK3308_ADCR_DATA_SFT			2
+#define RK3308_ADCL_DATA_SEL_ADCL		BIT(1)
+#define RK3308_ADCR_DATA_SEL_ADCR		BIT(0)
+
+/*
+ * RK3308_ALC_L_DIG_CON00 - REG: 0x0040 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON00 - REG: 0x0080 + ch * 0xc0
+ */
+#define RK3308_GAIN_ATTACK_JACK			BIT(6)
+#define RK3308_CTRL_GEN_SFT			4
+#define RK3308_CTRL_GEN_MSK			(0x3 << RK3308_ALC_CTRL_GEN_SFT)
+#define RK3308_CTRL_GEN_JACK3			(0x3 << RK3308_ALC_CTRL_GEN_SFT)
+#define RK3308_CTRL_GEN_JACK2			(0x2 << RK3308_ALC_CTRL_GEN_SFT)
+#define RK3308_CTRL_GEN_JACK1			(0x1 << RK3308_ALC_CTRL_GEN_SFT)
+#define RK3308_CTRL_GEN_NORMAL			(0x0 << RK3308_ALC_CTRL_GEN_SFT)
+#define RK3308_AGC_HOLD_TIME_SFT		0
+#define RK3308_AGC_HOLD_TIME_MSK		(0xf << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_1S			(0xa << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_512MS		(0x9 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_256MS		(0x8 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_128MS		(0x7 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_64MS		(0x6 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_32MS		(0x5 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_16MS		(0x4 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_8MS		(0x3 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_4MS		(0x2 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_2MS		(0x1 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_0MS		(0x0 << RK3308_AGC_HOLD_TIME_SFT)
+
+/*
+ * RK3308_ALC_L_DIG_CON01 - REG: 0x0044 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON01 - REG: 0x0084 + ch * 0xc0
+ */
+#define RK3308_AGC_DECAY_TIME_SFT		4
+#define RK3308_AGC_ATTACK_TIME_SFT		0
+
+/*
+ * RK3308_ALC_L_DIG_CON02 - REG: 0x0048 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON02 - REG: 0x0088 + ch * 0xc0
+ */
+#define RK3308_AGC_MODE_LIMITER			BIT(7)
+#define RK3308_AGC_ZERO_CRO_EN			BIT(6)
+#define RK3308_AGC_AMP_RECOVER_GAIN		BIT(5)
+#define RK3308_AGC_FAST_DEC_EN			BIT(4)
+#define RK3308_AGC_NOISE_GATE_EN		BIT(3)
+#define RK3308_AGC_NOISE_GATE_THRESH_SFT	0
+#define RK3308_AGC_NOISE_GATE_THRESH_MSK	(0x7 << RK3308_AGC_NOISE_GATE_THRESH_SFT)
+
+/*
+ * RK3308_ALC_L_DIG_CON03 - REG: 0x004c + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON03 - REG: 0x008c + ch * 0xc0
+ */
+#define RK3308_AGC_PGA_ZERO_CRO_EN		BIT(5)
+#define RK3308_AGC_PGA_GAIN_MAX			0x1f
+#define RK3308_AGC_PGA_GAIN_MIN			0
+#define RK3308_AGC_PGA_GAIN_SFT			0
+
+/*
+ * RK3308_ALC_L_DIG_CON04 - REG: 0x0050 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON04 - REG: 0x0090 + ch * 0xc0
+ */
+#define RK3308_AGC_SLOW_CLK_EN			BIT(3)
+#define RK3308_AGC_APPROX_RATE_SFT		0
+#define RK3308_AGC_APPROX_RATE_MSK		(0x7 << RK3308_AGC_APPROX_RATE_SFT)
+
+/*
+ * RK3308_ALC_L_DIG_CON05 - REG: 0x0054 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON05 - REG: 0x0094 + ch * 0xc0
+ */
+#define RK3308_AGC_LO_8BITS_AGC_MAX_MSK		0xff
+
+/*
+ * RK3308_ALC_L_DIG_CON06 - REG: 0x0058 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON06 - REG: 0x0098 + ch * 0xc0
+ */
+#define RK3308_AGC_HI_8BITS_AGC_MAX_MSK		0xff
+
+/*
+ * RK3308_ALC_L_DIG_CON07 - REG: 0x005c + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON07 - REG: 0x009c + ch * 0xc0
+ */
+#define RK3308_AGC_LO_8BITS_AGC_MIN_MSK		0xff
+
+/*
+ * RK3308_ALC_L_DIG_CON08 - REG: 0x0060 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON08 - REG: 0x00a0 + ch * 0xc0
+ */
+#define RK3308_AGC_HI_8BITS_AGC_MIN_MSK		0xff
+
+/*
+ * RK3308_ALC_L_DIG_CON09 - REG: 0x0064 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON09 - REG: 0x00a4 + ch * 0xc0
+ */
+#define RK3308_AGC_FUNC_SEL			BIT(6)
+#define RK3308_AGC_MAX_GAIN_PGA_MAX		0x7
+#define RK3308_AGC_MAX_GAIN_PGA_MIN		0
+#define RK3308_AGC_MAX_GAIN_PGA_SFT		3
+#define RK3308_AGC_MAX_GAIN_PGA_MSK		(0x7 << RK3308_AGC_MAX_GAIN_PGA_SFT)
+#define RK3308_AGC_MIN_GAIN_PGA_MAX		0x7
+#define RK3308_AGC_MIN_GAIN_PGA_MIN		0
+#define RK3308_AGC_MIN_GAIN_PGA_SFT		0
+#define RK3308_AGC_MIN_GAIN_PGA_MSK		(0x7 << RK3308_AGC_MIN_GAIN_PGA_SFT)
+
+/*
+ * RK3308_ALC_L_DIG_CON12 - REG: 0x0068 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON12 - REG: 0x00a8 + ch * 0xc0
+ */
+#define RK3308_AGC_GAIN_MSK			0x1f
+
+/* RK3308_DAC_DIG_CON01 - REG: 0x0304 */
+#define RK3308_DAC_I2S_LRC_POL_REVERSAL		BIT(7)
+#define RK3308_DAC_I2S_VALID_LEN_SFT		5
+#define RK3308_DAC_I2S_VALID_LEN_MSK		(0x3 << RK3308_DAC_I2S_VALID_LEN_SFT)
+#define RK3308_DAC_I2S_VALID_LEN_32BITS		(0x3 << RK3308_DAC_I2S_VALID_LEN_SFT)
+#define RK3308_DAC_I2S_VALID_LEN_24BITS		(0x2 << RK3308_DAC_I2S_VALID_LEN_SFT)
+#define RK3308_DAC_I2S_VALID_LEN_20BITS		(0x1 << RK3308_DAC_I2S_VALID_LEN_SFT)
+#define RK3308_DAC_I2S_VALID_LEN_16BITS		(0x0 << RK3308_DAC_I2S_VALID_LEN_SFT)
+#define RK3308_DAC_I2S_MODE_SFT			3
+#define RK3308_DAC_I2S_MODE_MSK			(0x3 << RK3308_DAC_I2S_MODE_SFT)
+#define RK3308_DAC_I2S_MODE_PCM			(0x3 << RK3308_DAC_I2S_MODE_SFT)
+#define RK3308_DAC_I2S_MODE_I2S			(0x2 << RK3308_DAC_I2S_MODE_SFT)
+#define RK3308_DAC_I2S_MODE_LJ			(0x1 << RK3308_DAC_I2S_MODE_SFT)
+#define RK3308_DAC_I2S_MODE_RJ			(0x0 << RK3308_DAC_I2S_MODE_SFT)
+#define RK3308_DAC_I2S_LR_SWAP			BIT(2)
+
+/* RK3308_DAC_DIG_CON02 - REG: 0x0308 */
+#define RK3308BS_DAC_IO_MODE_MASTER		BIT(7)
+#define RK3308BS_DAC_MODE_MASTER		BIT(6)
+#define RK3308_DAC_IO_MODE_MASTER		BIT(5)
+#define RK3308_DAC_MODE_MASTER			BIT(4)
+#define RK3308_DAC_I2S_FRAME_LEN_SFT		2
+#define RK3308_DAC_I2S_FRAME_LEN_MSK		(0x3 << RK3308_DAC_I2S_FRAME_LEN_SFT)
+#define RK3308_DAC_I2S_FRAME_32BITS		(0x3 << RK3308_DAC_I2S_FRAME_LEN_SFT)
+#define RK3308_DAC_I2S_FRAME_24BITS		(0x2 << RK3308_DAC_I2S_FRAME_LEN_SFT)
+#define RK3308_DAC_I2S_FRAME_20BITS		(0x1 << RK3308_DAC_I2S_FRAME_LEN_SFT)
+#define RK3308_DAC_I2S_FRAME_16BITS		(0x0 << RK3308_DAC_I2S_FRAME_LEN_SFT)
+#define RK3308_DAC_I2S_WORK			BIT(1)
+#define RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL	BIT(0)
+
+/* RK3308_DAC_DIG_CON03 - REG: 0x030C */
+#define RK3308_DAC_L_CH_BIST_SFT		2
+#define RK3308_DAC_L_CH_BIST_MSK		(0x3 << RK3308_DAC_L_CH_BIST_SFT)
+#define RK3308_DAC_L_CH_BIST_LEFT		(0x3 << RK3308_DAC_L_CH_BIST_SFT) /* normal mode */
+#define RK3308_DAC_L_CH_BIST_CUBE		(0x2 << RK3308_DAC_L_CH_BIST_SFT)
+#define RK3308_DAC_L_CH_BIST_SINE		(0x1 << RK3308_DAC_L_CH_BIST_SFT)
+#define RK3308_DAC_L_CH_BIST_RIGHT		(0x0 << RK3308_DAC_L_CH_BIST_SFT) /* normal mode */
+#define RK3308_DAC_R_CH_BIST_SFT		0
+#define RK3308_DAC_R_CH_BIST_MSK		(0x3 << RK3308_DAC_R_CH_BIST_SFT)
+#define RK3308_DAC_R_CH_BIST_LEFT		(0x3 << RK3308_DAC_R_CH_BIST_SFT) /* normal mode */
+#define RK3308_DAC_R_CH_BIST_CUBE		(0x2 << RK3308_DAC_R_CH_BIST_SFT)
+#define RK3308_DAC_R_CH_BIST_SINE		(0x1 << RK3308_DAC_R_CH_BIST_SFT)
+#define RK3308_DAC_R_CH_BIST_RIGHT		(0x0 << RK3308_DAC_R_CH_BIST_SFT) /* normal mode */
+
+/* RK3308_DAC_DIG_CON04 - REG: 0x0310 */
+/* Versions up to B: */
+#define RK3308_DAC_MODULATOR_GAIN_SFT		4
+#define RK3308_DAC_MODULATOR_GAIN_MSK		(0x7 << RK3308_DAC_MODULATOR_GAIN_SFT)
+#define RK3308_DAC_CIC_IF_GAIN_SFT		0
+#define RK3308_DAC_CIC_IF_GAIN_MSK		(0x7 << RK3308_DAC_CIC_IF_GAIN_SFT)
+/* Version C: */
+#define RK3308BS_DAC_DIG_GAIN_SFT		0
+#define RK3308BS_DAC_DIG_GAIN_MSK		(0xff << RK3308BS_DAC_DIG_GAIN_SFT)
+#define RK3308BS_DAC_DIG_GAIN_0DB		(0xed << RK3308BS_DAC_DIG_GAIN_SFT)
+
+/* RK3308BS_ADC_DIG_CON05..06 (Version C only) */
+#define RK3308_ADC_DIG_VOL_CON_x_SFT		0
+#define RK3308_ADC_DIG_VOL_CON_x_MSK		(0xff << RK3308_ADC_DIG_VOL_CON_x_SFT)
+#define RK3308_ADC_DIG_VOL_CON_x_0DB		(0xc2 << RK3308_ADC_DIG_VOL_CON_x_SFT)
+
+/* RK3308_DAC_DIG_CON05 - REG: 0x0314 */
+#define RK3308_DAC_L_REG_CTL_INDATA		BIT(2)
+#define RK3308_DAC_R_REG_CTL_INDATA		BIT(1)
+
+/* RK3308_DAC_DIG_CON10 - REG: 0x0328 */
+#define RK3308_DAC_DATA_HI4(x)			((x) & 0xf)
+
+/* RK3308_DAC_DIG_CON11 - REG: 0x032c */
+#define RK3308_DAC_DATA_LO8(x)			((x) & 0xff)
+
+/* RK3308_ADC_ANA_CON00 - REG: 0x0340 */
+#define RK3308_ADC_CH1_CH2_MIC_ALL_MSK		(0xff << 0)
+#define RK3308_ADC_CH1_CH2_MIC_ALL		0xff
+#define RK3308_ADC_CH2_MIC_UNMUTE		BIT(7)
+#define RK3308_ADC_CH2_MIC_WORK			BIT(6)
+#define RK3308_ADC_CH2_MIC_EN			BIT(5)
+#define RK3308_ADC_CH2_BUF_REF_EN		BIT(4)
+#define RK3308_ADC_CH1_MIC_UNMUTE		BIT(3)
+#define RK3308_ADC_CH1_MIC_WORK			BIT(2)
+#define RK3308_ADC_CH1_MIC_EN			BIT(1)
+#define RK3308_ADC_CH1_BUF_REF_EN		BIT(0)
+
+/* RK3308_ADC_ANA_CON01 - REG: 0x0344
+ *
+ * The PGA of MIC-INs:
+ * - HW version A:
+ *   0x0 - MIC1~MIC8  0 dB (recommended when ADC used as loopback)
+ *   0x3 - MIC1~MIC8 20 dB (recommended when ADC used as MIC input)
+ * - HW version B:
+ *   0x0 - MIC1~MIC8   0 dB
+ *   0x1 - MIC1~MIC8 6.6 dB
+ *   0x2 - MIC1~MIC8  13 dB
+ *   0x3 - MIC1~MIC8  20 dB
+ */
+#define RK3308_ADC_CH2_MIC_GAIN_MAX		0x3
+#define RK3308_ADC_CH2_MIC_GAIN_MIN		0
+#define RK3308_ADC_CH2_MIC_GAIN_SFT		4
+#define RK3308_ADC_CH2_MIC_GAIN_MSK		(0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT)
+#define RK3308_ADC_CH2_MIC_GAIN_20DB		(0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT)
+#define RK3308_ADC_CH2_MIC_GAIN_13DB		(0x2 << RK3308_ADC_CH2_MIC_GAIN_SFT)
+#define RK3308_ADC_CH2_MIC_GAIN_6_6DB		(0x1 << RK3308_ADC_CH2_MIC_GAIN_SFT)
+#define RK3308_ADC_CH2_MIC_GAIN_0DB		(0x0 << RK3308_ADC_CH2_MIC_GAIN_SFT)
+
+#define RK3308_ADC_CH1_MIC_GAIN_MAX		0x3
+#define RK3308_ADC_CH1_MIC_GAIN_MIN		0
+#define RK3308_ADC_CH1_MIC_GAIN_SFT		0
+#define RK3308_ADC_CH1_MIC_GAIN_MSK		(0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT)
+#define RK3308_ADC_CH1_MIC_GAIN_20DB		(0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT)
+#define RK3308_ADC_CH1_MIC_GAIN_13DB		(0x2 << RK3308_ADC_CH1_MIC_GAIN_SFT)
+#define RK3308_ADC_CH1_MIC_GAIN_6_6DB		(0x1 << RK3308_ADC_CH1_MIC_GAIN_SFT)
+#define RK3308_ADC_CH1_MIC_GAIN_0DB		(0x0 << RK3308_ADC_CH1_MIC_GAIN_SFT)
+
+/* RK3308_ADC_ANA_CON02 - REG: 0x0348 */
+#define RK3308_ADC_CH2_ZEROCROSS_DET_EN		BIT(6)
+#define RK3308_ADC_CH2_ALC_WORK			BIT(5)
+#define RK3308_ADC_CH2_ALC_EN			BIT(4)
+#define RK3308_ADC_CH1_ZEROCROSS_DET_EN		BIT(2)
+#define RK3308_ADC_CH1_ALC_WORK			BIT(1)
+#define RK3308_ADC_CH1_ALC_EN			BIT(0)
+
+/* RK3308_ADC_ANA_CON03 - REG: 0x034c */
+#define RK3308_ADC_CH1_ALC_GAIN_MAX		0x1f
+#define RK3308_ADC_CH1_ALC_GAIN_MIN		0
+#define RK3308_ADC_CH1_ALC_GAIN_SFT		0
+#define RK3308_ADC_CH1_ALC_GAIN_MSK		(0x1f << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_0DB		(0x0c << RK3308_ADC_CH1_ALC_GAIN_SFT)
+
+/* RK3308_ADC_ANA_CON04 - REG: 0x0350 */
+#define RK3308_ADC_CH2_ALC_GAIN_MAX		0x1f
+#define RK3308_ADC_CH2_ALC_GAIN_MIN		0
+#define RK3308_ADC_CH2_ALC_GAIN_SFT		0
+#define RK3308_ADC_CH2_ALC_GAIN_MSK		(0x1f << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_0DB		(0x0c << RK3308_ADC_CH2_ALC_GAIN_SFT)
+
+/* RK3308_ADC_ANA_CON05 - REG: 0x0354 */
+#define RK3308_ADC_CH2_ADC_WORK			BIT(6)
+#define RK3308_ADC_CH2_ADC_EN			BIT(5)
+#define RK3308_ADC_CH2_CLK_EN			BIT(4)
+#define RK3308_ADC_CH1_ADC_WORK			BIT(2)
+#define RK3308_ADC_CH1_ADC_EN			BIT(1)
+#define RK3308_ADC_CH1_CLK_EN			BIT(0)
+
+/* RK3308_ADC_ANA_CON06 - REG: 0x0358 */
+#define RK3308_ADC_CURRENT_EN			BIT(0)
+
+/* RK3308_ADC_ANA_CON07 - REG: 0x035c */
+/* Note: The register configuration is only valid for ADC2 */
+#define RK3308_ADC_CH2_IN_SEL_SFT		6
+#define RK3308_ADC_CH2_IN_SEL_MSK		(0x3 << RK3308_ADC_CH2_IN_SEL_SFT)
+#define RK3308_ADC_CH2_IN_LINEIN_MIC		(0x3 << RK3308_ADC_CH2_IN_SEL_SFT)
+#define RK3308_ADC_CH2_IN_LINEIN		(0x2 << RK3308_ADC_CH2_IN_SEL_SFT)
+#define RK3308_ADC_CH2_IN_MIC			(0x1 << RK3308_ADC_CH2_IN_SEL_SFT)
+#define RK3308_ADC_CH2_IN_NONE			(0x0 << RK3308_ADC_CH2_IN_SEL_SFT)
+/* Note: The register configuration is only valid for ADC1 */
+#define RK3308_ADC_CH1_IN_SEL_SFT		4
+#define RK3308_ADC_CH1_IN_SEL_MSK		(0x3 << RK3308_ADC_CH1_IN_SEL_SFT)
+#define RK3308_ADC_CH1_IN_LINEIN_MIC		(0x3 << RK3308_ADC_CH1_IN_SEL_SFT)
+#define RK3308_ADC_CH1_IN_LINEIN		(0x2 << RK3308_ADC_CH1_IN_SEL_SFT)
+#define RK3308_ADC_CH1_IN_MIC			(0x1 << RK3308_ADC_CH1_IN_SEL_SFT)
+#define RK3308_ADC_CH1_IN_NONE			(0x0 << RK3308_ADC_CH1_IN_SEL_SFT)
+#define RK3308_ADC_MIC_BIAS_BUF_EN		BIT(3)
+#define RK3308_ADC_LEVEL_RANGE_MICBIAS_MAX	7
+#define RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT	0
+#define RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK	(0x7 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT)
+
+/* RK3308_ADC_ANA_CON08 - REG: 0x0360 */
+#define RK3308_ADC_MICBIAS_CURRENT_EN		BIT(4)
+
+/* RK3308_ADC_ANA_CON10 - REG: 0x0368 */
+#define RK3308_ADC_REF_EN			BIT(7)
+#define RK3308_ADC_CURRENT_CHARGE_SFT		0
+#define RK3308_ADC_CURRENT_CHARGE_MSK		(0x7f << RK3308_ADC_CURRENT_CHARGE_SFT)
+
+/* RK3308_ADC_ANA_CON11 - REG: 0x036c */
+#define RK3308_ADC_ALCR_CON_GAIN_PGAR_EN	BIT(1)
+#define RK3308_ADC_ALCL_CON_GAIN_PGAL_EN	BIT(0)
+
+/* RK3308_DAC_ANA_CON00 - REG: 0x0440 */
+#define RK3308_DAC_HEADPHONE_DET_EN		BIT(1)
+#define RK3308_DAC_CURRENT_EN			BIT(0)
+
+/* RK3308_DAC_ANA_CON01 - REG: 0x0444 */
+#define RK3308_DAC_BUF_REF_R_EN			BIT(6)
+#define RK3308_DAC_BUF_REF_L_EN			BIT(2)
+#define RK3308_DAC_HPOUT_POP_SOUND_R_SFT	4
+#define RK3308_DAC_HPOUT_POP_SOUND_L_SFT	0
+// unshifted values for both L and R:
+#define RK3308_DAC_HPOUT_POP_SOUND_x_MSK	0x3
+#define RK3308_DAC_HPOUT_POP_SOUND_x_WORK	0x2
+#define RK3308_DAC_HPOUT_POP_SOUND_x_INIT	0x1
+
+/* RK3308_DAC_ANA_CON02 - REG: 0x0448 */
+#define RK3308_DAC_R_DAC_WORK			BIT(7)
+#define RK3308_DAC_R_DAC_EN			BIT(6)
+#define RK3308_DAC_R_CLK_EN			BIT(5)
+#define RK3308_DAC_R_REF_EN			BIT(4)
+#define RK3308_DAC_L_DAC_WORK			BIT(3)
+#define RK3308_DAC_L_DAC_EN			BIT(2)
+#define RK3308_DAC_L_CLK_EN			BIT(1)
+#define RK3308_DAC_L_REF_EN			BIT(0)
+
+/* RK3308_DAC_ANA_CON03 - REG: 0x044c */
+#define RK3308_DAC_R_HPOUT_WORK			BIT(6)
+#define RK3308_DAC_R_HPOUT_EN			BIT(5)
+#define RK3308_DAC_R_HPOUT_MUTE_SFT		4
+#define RK3308_DAC_L_HPOUT_WORK			BIT(2)
+#define RK3308_DAC_L_HPOUT_EN			BIT(1)
+#define RK3308_DAC_L_HPOUT_MUTE_SFT		0
+
+/* RK3308_DAC_ANA_CON04 - REG: 0x0450 */
+#define RK3308_DAC_x_LINEOUT_GAIN_MAX		0x3
+#define RK3308_DAC_R_LINEOUT_GAIN_SFT		6
+#define RK3308_DAC_R_LINEOUT_GAIN_MSK		(0x3 << RK3308_DAC_R_LINEOUT_GAIN_SFT)
+#define RK3308_DAC_R_LINEOUT_GAIN_0DB		(0x3 << RK3308_DAC_R_LINEOUT_GAIN_SFT)
+#define RK3308_DAC_R_LINEOUT_GAIN_NDB_1_5	(0x2 << RK3308_DAC_R_LINEOUT_GAIN_SFT)
+#define RK3308_DAC_R_LINEOUT_GAIN_NDB_3		(0x1 << RK3308_DAC_R_LINEOUT_GAIN_SFT)
+#define RK3308_DAC_R_LINEOUT_GAIN_NDB_6		(0x0 << RK3308_DAC_R_LINEOUT_GAIN_SFT)
+#define RK3308_DAC_R_LINEOUT_MUTE_SFT		5
+#define RK3308_DAC_R_LINEOUT_EN			BIT(4)
+#define RK3308_DAC_L_LINEOUT_GAIN_SFT		2
+#define RK3308_DAC_L_LINEOUT_GAIN_MSK		(0x3 << RK3308_DAC_L_LINEOUT_GAIN_SFT)
+#define RK3308_DAC_L_LINEOUT_GAIN_0DB		(0x3 << RK3308_DAC_L_LINEOUT_GAIN_SFT)
+#define RK3308_DAC_L_LINEOUT_GAIN_NDB_1_5	(0x2 << RK3308_DAC_L_LINEOUT_GAIN_SFT)
+#define RK3308_DAC_L_LINEOUT_GAIN_NDB_3		(0x1 << RK3308_DAC_L_LINEOUT_GAIN_SFT)
+#define RK3308_DAC_L_LINEOUT_GAIN_NDB_6		(0x0 << RK3308_DAC_L_LINEOUT_GAIN_SFT)
+#define RK3308_DAC_L_LINEOUT_MUTE_SFT		1
+#define RK3308_DAC_L_LINEOUT_EN			BIT(0)
+
+/* RK3308_DAC_ANA_CON05 - REG: 0x0454, step is 1.5db */
+/* RK3308_DAC_ANA_CON06 - REG: 0x0458, step is 1.5db */
+#define RK3308_DAC_x_HPOUT_GAIN_MAX		0x1e
+#define RK3308_DAC_x_HPOUT_GAIN_SFT		0
+#define RK3308_DAC_x_HPOUT_GAIN_MSK		(0x1f << RK3308_DAC_x_HPOUT_GAIN_SFT)
+#define RK3308_DAC_x_HPOUT_GAIN_MIN		(0x00 << RK3308_DAC_x_HPOUT_GAIN_SFT)
+
+/* RK3308_DAC_ANA_CON07 - REG: 0x045c */
+#define RK3308_DAC_R_HPOUT_DRV_SFT		4
+#define RK3308_DAC_R_HPOUT_DRV_MSK		(0xf << RK3308_DAC_R_HPOUT_DRV_SFT)
+#define RK3308_DAC_L_HPOUT_DRV_SFT		0
+#define RK3308_DAC_L_HPOUT_DRV_MSK		(0xf << RK3308_DAC_L_HPOUT_DRV_SFT)
+
+/* RK3308_DAC_ANA_CON08 - REG: 0x0460 */
+#define RK3308_DAC_R_LINEOUT_DRV_SFT		4
+#define RK3308_DAC_R_LINEOUT_DRV_MSK		(0xf << RK3308_DAC_R_LINEOUT_DRV_SFT)
+#define RK3308_DAC_L_LINEOUT_DRV_SFT		0
+#define RK3308_DAC_L_LINEOUT_DRV_MSK		(0xf << RK3308_DAC_L_LINEOUT_DRV_SFT)
+
+/* RK3308_DAC_ANA_CON12 - REG: 0x0470 */
+#define RK3308_DAC_R_HPMIX_SEL_SFT		6
+#define RK3308_DAC_R_HPMIX_SEL_MSK		(0x3 << RK3308_DAC_R_HPMIX_SEL_SFT)
+#define RK3308_DAC_R_HPMIX_LINEIN_I2S		(0x3 << RK3308_DAC_R_HPMIX_SEL_SFT)
+#define RK3308_DAC_R_HPMIX_LINEIN		(0x2 << RK3308_DAC_R_HPMIX_SEL_SFT)
+#define RK3308_DAC_R_HPMIX_I2S			(0x1 << RK3308_DAC_R_HPMIX_SEL_SFT)
+#define RK3308_DAC_R_HPMIX_NONE			(0x0 << RK3308_DAC_R_HPMIX_SEL_SFT)
+#define RK3308_DAC_L_HPMIX_SEL_SFT		2
+#define RK3308_DAC_L_HPMIX_SEL_MSK		(0x3 << RK3308_DAC_L_HPMIX_SEL_SFT)
+#define RK3308_DAC_L_HPMIX_LINEIN_I2S		(0x3 << RK3308_DAC_L_HPMIX_SEL_SFT)
+#define RK3308_DAC_L_HPMIX_LINEIN		(0x2 << RK3308_DAC_L_HPMIX_SEL_SFT)
+#define RK3308_DAC_L_HPMIX_I2S			(0x1 << RK3308_DAC_L_HPMIX_SEL_SFT)
+#define RK3308_DAC_L_HPMIX_NONE			(0x0 << RK3308_DAC_L_HPMIX_SEL_SFT)
+#define RK3308_DAC_x_HPMIX_GAIN_MIN		0x1 /* 0x0 and 0x3 are reserved */
+#define RK3308_DAC_x_HPMIX_GAIN_MAX		0x2
+#define RK3308_DAC_R_HPMIX_GAIN_SFT		4
+#define RK3308_DAC_R_HPMIX_GAIN_MSK		(0x3 << RK3308_DAC_R_HPMIX_GAIN_SFT)
+#define RK3308_DAC_R_HPMIX_GAIN_0DB		(0x2 << RK3308_DAC_R_HPMIX_GAIN_SFT)
+#define RK3308_DAC_R_HPMIX_GAIN_NDB_6		(0x1 << RK3308_DAC_R_HPMIX_GAIN_SFT)
+#define RK3308_DAC_L_HPMIX_GAIN_SFT		0
+#define RK3308_DAC_L_HPMIX_GAIN_MSK		(0x3 << RK3308_DAC_L_HPMIX_GAIN_SFT)
+#define RK3308_DAC_L_HPMIX_GAIN_0DB		(0x2 << RK3308_DAC_L_HPMIX_GAIN_SFT)
+#define RK3308_DAC_L_HPMIX_GAIN_NDB_6		(0x1 << RK3308_DAC_L_HPMIX_GAIN_SFT)
+
+/* RK3308_DAC_ANA_CON13 - REG: 0x0474 */
+#define RK3308_DAC_R_HPMIX_UNMUTE		BIT(6)
+#define RK3308_DAC_R_HPMIX_WORK			BIT(5)
+#define RK3308_DAC_R_HPMIX_EN			BIT(4)
+#define RK3308_DAC_L_HPMIX_UNMUTE		BIT(2)
+#define RK3308_DAC_L_HPMIX_WORK			BIT(1)
+#define RK3308_DAC_L_HPMIX_EN			BIT(0)
+
+/* RK3308_DAC_ANA_CON14 - REG: 0x0478 */
+#define RK3308_DAC_VCM_LINEOUT_EN		(0x1 << 4)
+#define RK3308_DAC_CURRENT_CHARGE_SFT		0
+#define RK3308_DAC_CURRENT_CHARGE_MSK		(0xf << RK3308_DAC_CURRENT_CHARGE_SFT)
+
+/* RK3308_DAC_ANA_CON15 - REG: 0x047C */
+#define RK3308_DAC_LINEOUT_POP_SOUND_R_SFT	4
+#define RK3308_DAC_LINEOUT_POP_SOUND_R_MSK	(0x3 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT)
+#define RK3308_DAC_R_SEL_DC_FROM_INTERNAL	(0x2 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT)
+#define RK3308_DAC_R_SEL_DC_FROM_VCM		(0x1 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT)
+#define RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL	(0x0 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT)
+#define RK3308_DAC_LINEOUT_POP_SOUND_L_SFT	0
+#define RK3308_DAC_LINEOUT_POP_SOUND_L_MSK	(0x3 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT)
+#define RK3308_DAC_L_SEL_DC_FROM_INTERNAL	(0x2 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT)
+#define RK3308_DAC_L_SEL_DC_FROM_VCM		(0x1 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT)
+#define RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL	(0x0 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT)
+
+#endif /* __RK3308_CODEC_H__ */

-- 
2.34.1



From luca.ceresoli at bootlin.com  Wed Feb 21 02:22:51 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 21 Feb 2024 11:22:51 +0100
Subject: [PATCH v3 7/7] arm64: dts: rockchip: add the internal audio codec
In-Reply-To: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
References: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
Message-ID: <20240221-rk3308-audio-codec-v3-7-dfa34abfcef6@bootlin.com>

The RK3308 has a built-in audio codec that connects internally to i2s_8ch_2
or i2s_8ch_3.

Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

---

Changed in v3: nothing

Changed in v2:
 - use generic node name
---
 arch/arm64/boot/dts/rockchip/rk3308.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
index 662c55fe9b77..962ea893999b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
@@ -803,6 +803,20 @@ cru: clock-controller at ff500000 {
 		assigned-clock-rates = <32768>;
 	};
 
+	codec: codec at ff560000 {
+		compatible = "rockchip,rk3308-codec";
+		reg = <0x0 0xff560000 0x0 0x10000>;
+		rockchip,grf = <&grf>;
+		clock-names = "mclk_tx", "mclk_rx", "hclk";
+		clocks = <&cru SCLK_I2S2_8CH_TX_OUT>,
+			 <&cru SCLK_I2S2_8CH_RX_OUT>,
+			 <&cru PCLK_ACODEC>;
+		reset-names = "codec-reset";
+		resets = <&cru SRST_ACODEC_P>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
 	gic: interrupt-controller at ff580000 {
 		compatible = "arm,gic-400";
 		reg = <0x0 0xff581000 0x0 0x1000>,

-- 
2.34.1



From alim.akhtar at samsung.com  Wed Feb 21 02:28:38 2024
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Wed, 21 Feb 2024 15:58:38 +0530
Subject: [PATCH v2] interconnect: constify of_phandle_args in xlate
In-Reply-To: <6c4bdd9f-6b1f-43a0-9baa-7c1eedd46f76@linaro.org>
References: <CGME20240220072224epcas5p4ff60556b0b5632abfc44d2b8ad932b8f@epcas5p4.samsung.com>
	<20240220072213.35779-1-krzysztof.kozlowski@linaro.org>
	<1d9b01da63f6$daeb0170$90c10450$@samsung.com>
	<6c4bdd9f-6b1f-43a0-9baa-7c1eedd46f76@linaro.org>
Message-ID: <1f7401da64b0$bdba8430$392f8c90$@samsung.com>

Hi Krzysztof,

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Sent: Wednesday, February 21, 2024 12:44 PM
> To: Alim Akhtar <alim.akhtar at samsung.com>; 'Georgi Djakov'
> <djakov at kernel.org>; 'Bjorn Andersson' <andersson at kernel.org>; 'Konrad
> Dybcio' <konrad.dybcio at linaro.org>; 'Sylwester Nawrocki'
> <s.nawrocki at samsung.com>; 'Artur ?wigo?' <a.swigon at samsung.com>;
> 'Thierry Reding' <thierry.reding at gmail.com>; 'Jonathan Hunter'
> <jonathanh at nvidia.com>; linux-pm at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-msm at vger.kernel.org; linux-samsung-
> soc at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> tegra at vger.kernel.org
> Cc: 'Thierry Reding' <treding at nvidia.com>
> Subject: Re: [PATCH v2] interconnect: constify of_phandle_args in xlate
> 
> On 20/02/2024 13:18, Alim Akhtar wrote:
> >
> >
> >> -----Original Message-----
> >> From: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> >> Sent: Tuesday, February 20, 2024 12:52 PM
> >> To: Georgi Djakov <djakov at kernel.org>; Bjorn Andersson
> >> <andersson at kernel.org>; Konrad Dybcio <konrad.dybcio at linaro.org>;
> >> Sylwester Nawrocki <s.nawrocki at samsung.com>; Artur ?wigo?
> >> <a.swigon at samsung.com>; Krzysztof Kozlowski
> >> <krzysztof.kozlowski at linaro.org>; Alim Akhtar
> >> <alim.akhtar at samsung.com>; Thierry Reding
> <thierry.reding at gmail.com>;
> >> Jonathan Hunter <jonathanh at nvidia.com>; linux-pm at vger.kernel.org;
> >> linux-kernel at vger.kernel.org; linux-arm-msm at vger.kernel.org; linux-
> >> samsung-soc at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >> linux- tegra at vger.kernel.org
> >> Cc: Thierry Reding <treding at nvidia.com>
> >> Subject: [PATCH v2] interconnect: constify of_phandle_args in xlate
> >>
> >> The xlate callbacks are supposed to translate of_phandle_args to
> >> proper provider without modifying the of_phandle_args.  Make the
> >> argument pointer to const for code safety and readability.
> >>
> >> Acked-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> >> Acked-by: Thierry Reding <treding at nvidia.com> # Tegra
> >> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> >>
> >> ---
> >>
> >> Changes in v2:
> >> 1. Drop unrelated gpiolib changes (Konrad, Thierry).
> >> 2. Add tags.
> >> ---
> >>  drivers/interconnect/core.c            |  4 ++--
> >>  drivers/interconnect/qcom/icc-common.c |  3 ++-
> >> drivers/interconnect/qcom/icc-common.h |  3 ++-
> >> drivers/interconnect/samsung/exynos.c  |  2 +-
> >>  drivers/memory/tegra/mc.c              |  2 +-
> >>  drivers/memory/tegra/tegra124-emc.c    |  2 +-
> >>  drivers/memory/tegra/tegra124.c        |  2 +-
> >>  drivers/memory/tegra/tegra186-emc.c    |  2 +-
> >>  drivers/memory/tegra/tegra20-emc.c     |  2 +-
> >>  drivers/memory/tegra/tegra20.c         |  2 +-
> >>  drivers/memory/tegra/tegra30-emc.c     |  2 +-
> >>  drivers/memory/tegra/tegra30.c         |  2 +-
> >>  include/linux/interconnect-provider.h  | 11 ++++++-----
> >>  include/soc/tegra/mc.h                 |  7 ++++---
> >>  14 files changed, 25 insertions(+), 21 deletions(-)
> >>
> >
> > For Samsung/Exynos
> > Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
> 
> Review tags are per patch. You probably meant Acked-by.
if that is more appropriate in this case, feel free to add
Acked-by: Alim Akhtar <alim.akhtar at samsung.com>

> https://protect2.fireeye.com/v1/url?k=bc64ffdb-ddefeaed-bc657494-
> 74fe485cbff1-62590d464cd6269e&q=1&e=ec8047f9-eeac-446c-8ba5-
> 476f581d9cfa&u=https%3A%2F%2Felixir.bootlin.com%2Flinux%2Fv6.8-
> rc5%2Fsource%2FDocumentation%2Fprocess%2Fsubmitting-
> patches.rst%23L544
> 
> What is there anyway to review in Samsung? Adding one const in one driver?
> 
I my opinion, any changes coming in, has to be reviewed to see if there is/are any side effect because of the change,
even though the changes looks trivial.

> 
> Best regards,
> Krzysztof





From lorenzo at kernel.org  Wed Feb 21 02:30:44 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 21 Feb 2024 11:30:44 +0100
Subject: [PATCH v2 2/4] arm64: dts: Add Airoha EN7581 SoC and EN7581
 Evaluation Board
In-Reply-To: <2e8e6a0a-44ce-45e4-8321-592f08852412@linaro.org>
References: <cover.1708473083.git.lorenzo@kernel.org>
 <f59389838c741650f6ff05d984a9127545e4eb83.1708473083.git.lorenzo@kernel.org>
 <2e8e6a0a-44ce-45e4-8321-592f08852412@linaro.org>
Message-ID: <ZdXQ1OXjjyWOzSWD@lore-desk>

> On 21/02/2024 01:04, Lorenzo Bianconi wrote:
> > From: Daniel Danzberger <dd at embedd.com>
> > 
> > Introduce the Airoha EN7581 SoC's dtsi and the Airoha EN7581 Evaluation
> > Board's dts file, as well as the required Makefiles.
> > 
> > Signed-off-by: Daniel Danzberger <dd at embedd.com>
> > Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
> > ---
> >  arch/arm64/boot/dts/Makefile              |   1 +
> >  arch/arm64/boot/dts/airoha/Makefile       |   2 +
> >  arch/arm64/boot/dts/airoha/en7581-evb.dts |  27 +++++
> >  arch/arm64/boot/dts/airoha/en7581.dtsi    | 137 ++++++++++++++++++++++
> >  4 files changed, 167 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/airoha/Makefile
> >  create mode 100644 arch/arm64/boot/dts/airoha/en7581-evb.dts
> >  create mode 100644 arch/arm64/boot/dts/airoha/en7581.dtsi
> > 
> > diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> > index 30dd6347a929..21cd3a87f385 100644
> > --- a/arch/arm64/boot/dts/Makefile
> > +++ b/arch/arm64/boot/dts/Makefile
> > @@ -1,5 +1,6 @@
> >  # SPDX-License-Identifier: GPL-2.0
> >  subdir-y += actions
> > +subdir-y += airoha
> >  subdir-y += allwinner
> >  subdir-y += altera
> >  subdir-y += amazon
> > diff --git a/arch/arm64/boot/dts/airoha/Makefile b/arch/arm64/boot/dts/airoha/Makefile
> > new file mode 100644
> > index 000000000000..ebea112ce1d7
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/airoha/Makefile
> > @@ -0,0 +1,2 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +dtb-$(CONFIG_ARCH_AIROHA) += en7581-evb.dtb
> > diff --git a/arch/arm64/boot/dts/airoha/en7581-evb.dts b/arch/arm64/boot/dts/airoha/en7581-evb.dts
> > new file mode 100644
> > index 000000000000..4eaa8ac431c3
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/airoha/en7581-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 "en7581.dtsi"
> > +
> > +/ {
> > +	model = "Airoha EN7581 Evaluation Board";
> > +	compatible = "airoha,en7581-evb", "airoha,en7581";
> > +
> > +	aliases {
> > +		serial0 = &uart1;
> > +	};
> > +
> > +	chosen {
> > +		bootargs = "console=ttyS0,115200 earlycon";
> 
> You have console below. You don't need earlycon for mainline, broad
> usage, because it is purely debugging part, so drop entire bootargs.

ack, I will fix it in v3.

> 
> > +		stdout-path = "serial0:115200n8";
> > +		linux,usable-memory-range = <0x0 0x80200000 0x0 0x1fe00000>;
> > +	};
> > +
> > +	memory at 80000000 {
> > +		device_type = "memory";
> > +		reg = <0x0 0x80000000 0x2 0x00000000>;
> > +	};
> > +};
> > diff --git a/arch/arm64/boot/dts/airoha/en7581.dtsi b/arch/arm64/boot/dts/airoha/en7581.dtsi
> > new file mode 100644
> > index 000000000000..7a3c0a45c03f
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/airoha/en7581.dtsi
> > @@ -0,0 +1,137 @@
> > +// 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 = <2>;
> > +	#size-cells = <2>;
> > +
> > +	reserved-memory {
> > +		#address-cells = <2>;
> > +		#size-cells = <2>;
> > +		ranges;
> > +
> > +		npu_binary at 84000000 {
> 
> No underscores in nodenames.
> ...
> 

ack, I will fix it in v3.

> > +
> > +		L2_0: l2-cache0 {
> 
> Nodename: l2-cache
> 

ack, I will fix it in v3.

> > +			compatible = "cache";
> > +			cache-level = <2>;
> > +			cache-unified;
> > +		};
> > +	};
> > +
> > +	gic: interrupt-controller at 9000000 {
> 
> Why this is outside of SoC? Where is your SoC node BTW?

ack, I will fix it in v3.

> 
> It does not look like you tested the DTS against bindings. Please run
> `make dtbs_check W=1` (see
> Documentation/devicetree/bindings/writing-schema.rst or
> https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
> for instructions).
> 
> > +		compatible = "arm,gic-v3";
> > +		interrupt-controller;
> > +		#interrupt-cells = <3>;
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		reg = <0x0 0x09000000 0x0 0x20000>,
> > +		      <0x0 0x09080000 0x0 0x80000>,
> > +		      <0x0 0x09400000 0x0 0x2000>,
> > +		      <0x0 0x09500000 0x0 0x2000>,
> > +		      <0x0 0x09600000 0x0 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 {
> 
> This cannot be outside of SoC.

ack, I will fix it in v3.

> 
> > +		compatible = "ns16550";
> > +		reg = <0x0 0x1fbf0000 0x0 0x30>;
> > +		reg-io-width = <4>;
> > +		reg-shift = <2>;
> > +		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
> > +		clock-frequency = <1843200>;
> > +		status = "okay";
> 
> Drop

ack, I will fix it in v3.

Regards,
Lorenzo

> 
> 
> Best regards,
> Krzysztof
> 
-------------- 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/20240221/993627cb/attachment-0001.sig>

From maz at kernel.org  Wed Feb 21 02:34:20 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 21 Feb 2024 10:34:20 +0000
Subject: [GIT PULL] KVM/arm64 fixes for 6.8, take #3
In-Reply-To: <CABgObfYhVK+qF25h8+hhuyCvbgfpocDo0UDac3CTEHghRGww+w@mail.gmail.com>
References: <20240221101711.2105066-1-maz@kernel.org>
	<CABgObfYhVK+qF25h8+hhuyCvbgfpocDo0UDac3CTEHghRGww+w@mail.gmail.com>
Message-ID: <86ttm22jir.wl-maz@kernel.org>

On Wed, 21 Feb 2024 10:22:04 +0000,
Paolo Bonzini <pbonzini at redhat.com> wrote:
> 
> On Wed, Feb 21, 2024 at 11:17?AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > Hey Paolo,
> >
> > Another week, another couple of fixes. This time, two fixes for the
> > ITS emulation that could result in non-existent LPIs being used, with
> > unpredictable consequences. Thanks to Oliver for spotting those as he
> > was reworking the ITS translation cache.
> 
> The consequences would really be NULL pointer dereferences, wouldn't they?

That's the effect. The consequences depend on how the fault is
handled ('benign' oops, panic, or reboot...).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From frank at oltmanns.dev  Wed Feb 21 02:38:39 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Wed, 21 Feb 2024 11:38:39 +0100
Subject: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum
 rate
In-Reply-To: <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>
Message-ID: <8734tmhzkg.fsf@oltmanns.dev>

Hi Jernej,
hi Maxime,

On 2024-02-05 at 16:22:26 +0100, Frank Oltmanns <frank at oltmanns.dev> wrote:
> According to the Allwinner User Manual, the Allwinner A64 requires
> PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.

I should point out that limiting PLL-MIPI also fixes a regression
that was introduced in 6.5, specifically
ca1170b69968233b34d26432245eddf7d265186b "clk: sunxi-ng: a64: force
select PLL_MIPI in TCON0 mux". This has been bisected and reported by
Diego [1].

I don't know the procedure (yet), but probably the fix (if and when
accepted) should be backported at least to 6.6 (first broken LTS), 6.7
(stable), and 6.8 (next stable).

My suggestion:
 - In V3 of this series, I will reorder the patches, so that what is now
   PATCH 3 and 4 becomes 1 and 2 respectively, so that they can be
   applied to 6.6 more easily.
 - Maxime, IIUC you requested some refactoring for handling the rate
   limits [2]. I propose, we use my current proposal as-is, and I will
   do a follow-up series for the refactoring.

Please let me know how you would like me to proceed.

Thanks,
  Frank

[1]: https://groups.google.com/g/linux-sunxi/c/Rh-Uqqa66bw
[2]: https://lore.kernel.org/all/exb2lvjcozak5fayrgyenrd3ntii4jfxgvqork4klyz5pky2aq at dj2zyw5su6pv/

>
> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> ---
>  drivers/clk/sunxi-ng/ccu_nkm.c | 13 +++++++++++++
>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
>  2 files changed, 15 insertions(+)
>
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> index 1168d894d636..7d135908d6e0 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> @@ -181,6 +181,12 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
>  	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
>  		rate *= nkm->fixed_post_div;
>
> +	if (nkm->min_rate && rate < nkm->min_rate)
> +		rate = nkm->min_rate;
> +
> +	if (nkm->max_rate && rate > nkm->max_rate)
> +		rate = nkm->max_rate;
> +
>  	if (!clk_hw_can_set_rate_parent(&nkm->common.hw))
>  		rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm->common);
>  	else
> @@ -220,6 +226,13 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
>  	_nkm.min_m = 1;
>  	_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
>
> +
> +	if (nkm->min_rate && rate < nkm->min_rate)
> +		rate = nkm->min_rate;
> +
> +	if (nkm->max_rate && rate > nkm->max_rate)
> +		rate = nkm->max_rate;
> +
>  	ccu_nkm_find_best(parent_rate, rate, &_nkm, &nkm->common);
>
>  	spin_lock_irqsave(nkm->common.lock, flags);
> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
> index c409212ee40e..358a9df6b6a0 100644
> --- a/drivers/clk/sunxi-ng/ccu_nkm.h
> +++ b/drivers/clk/sunxi-ng/ccu_nkm.h
> @@ -27,6 +27,8 @@ struct ccu_nkm {
>  	struct ccu_mux_internal	mux;
>
>  	unsigned int		fixed_post_div;
> +	unsigned long		min_rate;
> +	unsigned long		max_rate;
>  	unsigned long		max_m_n_ratio;
>  	unsigned long		min_parent_m_ratio;


From billy_tsai at aspeedtech.com  Wed Feb 21 02:40:22 2024
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Wed, 21 Feb 2024 18:40:22 +0800
Subject: [PATCH v14 0/3] Support pwm/tach driver for aspeed ast26xx
Message-ID: <20240221104025.1306227-1-billy_tsai@aspeedtech.com>

Unlike the old design that the register setting of the TACH should based
on the configure of the PWM. In ast26xx, the dependency between pwm and
tach controller is eliminated and becomes a separate hardware block. One
is used to provide pwm output and another is used to monitor the frequency
of the input. This driver implements them by exposing two kernel
subsystems: PWM and HWMON. The PWM subsystem can be utilized alongside
existing drivers for controlling elements such as fans (pwm-fan.c),
beepers (pwm-beeper.c) and so on. Through the HWMON subsystem, the driver
provides sysfs interfaces for fan.

Changes since v13:
Restore Rob's "Reviewed-by" for fan-common.yaml.
Remove the compatible string in the dts example in aspeed,g6-pwm-tach.yaml.
Utilize devm_add_action_or_reset() to assert the reset.
Resolve the compiler error.

Changes since v12:
Merge the pwm-fan configure information into the fan node.
Add the of_platform_populate function to the driver to treat the child
node as a platform device.

Changes since v11:
Fix the compiler error of the driver.
The owner member has to be moved to struct pwm_chip.

Changes since v10:
Add the enum for the 'fan-driving-mode' properties in the fan-common.yaml.

Changes since v9:
Change the type of fan-driving-mode to string
Fix some typos and formatting issues.

Changes since v8:
Fix the fail of fan div register setting. (FIELD_GET -> FIELD_PREP)
Change the type of tach-ch from uint32_t to uint8-array
Add additional properties and apply constraints to certain properties.

Changes since v7:
Cherry-pick the fan-common.yaml and add the following properties:
- min-rpm
- div
- mode
- tach-ch
Fix the warning which is reported by the kernel test robot.

Changes since v6:
Consolidate the PWM and TACH functionalities into a unified driver.

Changes since v5:
- pwm/tach:
  - Remove the utilization of common resources from the parent node.
  - Change the concept to 16 PWM/TACH controllers, each with one channel,
  instead of 1 PWM/TACH controller with 16 channels.
- dt-binding:
  - Eliminate the usage of simple-mfd.

Changes since v4:
- pwm:
  - Fix the return type of get_status function.
- tach:
  - read clk source once and re-use it
  - Remove the constants variables
  - Allocate tach_channel as array
  - Use dev->parent
- dt-binding:
  - Fix the order of the patches
  - Add example and description for tach child node
  - Remove pwm extension property

Changes since v3:
- pwm:
  - Remove unnecessary include header
  - Fix warning Prefer "GPL" over "GPL v2"
- tach:
  - Remove the paremeter min_rpm and max_rpm and return the tach value 
  directly without any polling or delay.
  - Fix warning Prefer "GPL" over "GPL v2"
- dt-binding:
  - Replace underscore in node names with dashes
  - Split per subsystem

Changes since v2:
- pwm:
  - Use devm_* api to simplify the error cleanup
  - Fix the multi-line alignment problem
- tach:
  - Add tach-aspeed-ast2600 to index.rst
  - Fix the multi-line alignment problem
  - Remove the tach enable/disable when read the rpm
  - Fix some coding format issue

Changes since v1:
- tach:
  - Add the document tach-aspeed-ast2600.rst
  - Use devm_* api to simplify the error cleanup.
  - Change hwmon register api to devm_hwmon_device_register_with_info

Billy Tsai (2):
  dt-bindings: hwmon: Support Aspeed g6 PWM TACH Control
  hwmon: (aspeed-g6-pwm-tacho): Support for ASPEED g6 PWM/Fan tach

Naresh Solanki (1):
  dt-bindings: hwmon: fan: Add fan binding to schema

 .../bindings/hwmon/aspeed,g6-pwm-tach.yaml    |  71 +++
 .../devicetree/bindings/hwmon/fan-common.yaml |  79 +++
 Documentation/hwmon/aspeed-g6-pwm-tach.rst    |  26 +
 Documentation/hwmon/index.rst                 |   1 +
 drivers/hwmon/Kconfig                         |  11 +
 drivers/hwmon/Makefile                        |   1 +
 drivers/hwmon/aspeed-g6-pwm-tach.c            | 549 ++++++++++++++++++
 7 files changed, 738 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml
 create mode 100644 Documentation/devicetree/bindings/hwmon/fan-common.yaml
 create mode 100644 Documentation/hwmon/aspeed-g6-pwm-tach.rst
 create mode 100644 drivers/hwmon/aspeed-g6-pwm-tach.c

-- 
2.25.1



From billy_tsai at aspeedtech.com  Wed Feb 21 02:40:23 2024
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Wed, 21 Feb 2024 18:40:23 +0800
Subject: [PATCH v14 1/3] dt-bindings: hwmon: fan: Add fan binding to schema
In-Reply-To: <20240221104025.1306227-1-billy_tsai@aspeedtech.com>
References: <20240221104025.1306227-1-billy_tsai@aspeedtech.com>
Message-ID: <20240221104025.1306227-2-billy_tsai@aspeedtech.com>

From: Naresh Solanki <naresh.solanki at 9elements.com>

Add common fan properties bindings to a schema.

Bindings for fan controllers can reference the common schema for the
fan

child nodes:

  patternProperties:
    "^fan@[0-2]":
      type: object
      $ref: fan-common.yaml#
      unevaluatedProperties: false

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Naresh Solanki <naresh.solanki at 9elements.com>
Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 .../devicetree/bindings/hwmon/fan-common.yaml | 79 +++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/fan-common.yaml

diff --git a/Documentation/devicetree/bindings/hwmon/fan-common.yaml b/Documentation/devicetree/bindings/hwmon/fan-common.yaml
new file mode 100644
index 000000000000..0fb738081699
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/fan-common.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/fan-common.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Common Fan Properties
+
+maintainers:
+  - Naresh Solanki <naresh.solanki at 9elements.com>
+  - Billy Tsai <billy_tsai at aspeedtech.com>
+
+properties:
+  max-rpm:
+    description:
+      Max RPM supported by fan.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maximum: 100000
+
+  min-rpm:
+    description:
+      Min RPM supported by fan.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maximum: 1000
+
+  pulses-per-revolution:
+    description:
+      The number of pulse from fan sensor per revolution.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maximum: 4
+
+  tach-div:
+    description:
+      Divisor for the tach sampling clock, which determines the sensitivity of the tach pin.
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  target-rpm:
+    description:
+      The default desired fan speed in RPM.
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  fan-driving-mode:
+    description:
+      Select the driving mode of the fan.(DC, PWM and so on)
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [ dc, pwm ]
+
+  pwms:
+    description:
+      PWM provider.
+    maxItems: 1
+
+  "#cooling-cells":
+    const: 2
+
+  cooling-levels:
+    description:
+      The control value which correspond to thermal cooling states.
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+
+  tach-ch:
+    description:
+      The tach channel used for the fan.
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+
+  label:
+    description:
+      Optional fan label
+
+  fan-supply:
+    description:
+      Power supply for fan.
+
+  reg:
+    maxItems: 1
+
+additionalProperties: true
+
+...
-- 
2.25.1



From billy_tsai at aspeedtech.com  Wed Feb 21 02:40:24 2024
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Wed, 21 Feb 2024 18:40:24 +0800
Subject: [PATCH v14 2/3] dt-bindings: hwmon: Support Aspeed g6 PWM TACH Control
In-Reply-To: <20240221104025.1306227-1-billy_tsai@aspeedtech.com>
References: <20240221104025.1306227-1-billy_tsai@aspeedtech.com>
Message-ID: <20240221104025.1306227-3-billy_tsai@aspeedtech.com>

Document the compatible for aspeed,ast2600-pwm-tach device, which can
support up to 16 PWM outputs and 16 fan tach input.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 .../bindings/hwmon/aspeed,g6-pwm-tach.yaml    | 71 +++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml

diff --git a/Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml b/Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml
new file mode 100644
index 000000000000..9e5ed901ae54
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2023 Aspeed, Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/aspeed,g6-pwm-tach.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED G6 PWM and Fan Tach controller
+
+maintainers:
+  - Billy Tsai <billy_tsai at aspeedtech.com>
+
+description: |
+  The ASPEED PWM controller can support up to 16 PWM outputs.
+  The ASPEED Fan Tacho controller can support up to 16 fan tach input.
+  They are independent hardware blocks, which are different from the
+  previous version of the ASPEED chip.
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2600-pwm-tach
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 3
+
+patternProperties:
+  "^fan-[0-9]+$":
+    $ref: fan-common.yaml#
+    unevaluatedProperties: false
+    required:
+      - tach-ch
+
+required:
+  - reg
+  - clocks
+  - resets
+  - "#pwm-cells"
+  - compatible
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/aspeed-clock.h>
+    pwm_tach: pwm-tach-controller at 1e610000 {
+      compatible = "aspeed,ast2600-pwm-tach";
+      reg = <0x1e610000 0x100>;
+      clocks = <&syscon ASPEED_CLK_AHB>;
+      resets = <&syscon ASPEED_RESET_PWM>;
+      #pwm-cells = <3>;
+
+      fan-0 {
+        tach-ch = /bits/ 8 <0x0>;
+        pwms = <&pwm_tach 0 40000 0>;
+      };
+
+      fan-1 {
+        tach-ch = /bits/ 8 <0x1 0x2>;
+        pwms = <&pwm_tach 1 40000 0>;
+      };
+    };
-- 
2.25.1



From billy_tsai at aspeedtech.com  Wed Feb 21 02:40:25 2024
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Wed, 21 Feb 2024 18:40:25 +0800
Subject: [PATCH v14 3/3] hwmon: (aspeed-g6-pwm-tacho): Support for ASPEED g6 PWM/Fan tach
In-Reply-To: <20240221104025.1306227-1-billy_tsai@aspeedtech.com>
References: <20240221104025.1306227-1-billy_tsai@aspeedtech.com>
Message-ID: <20240221104025.1306227-4-billy_tsai@aspeedtech.com>

The driver support two functions: PWM and Tachometer. The PWM feature can
handle up to 16 output ports, while the Tachometer can monitor to up to 16
input ports as well. This driver implements them by exposing two kernel
subsystems: PWM and HWMON. The PWM subsystem can be utilized alongside
existing drivers for controlling elements such as fans (pwm-fan.c),
beepers (pwm-beeper.c) and so on. Through the HWMON subsystem, the driver
provides sysfs interfaces for fan.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 Documentation/hwmon/aspeed-g6-pwm-tach.rst |  26 +
 Documentation/hwmon/index.rst              |   1 +
 drivers/hwmon/Kconfig                      |  11 +
 drivers/hwmon/Makefile                     |   1 +
 drivers/hwmon/aspeed-g6-pwm-tach.c         | 549 +++++++++++++++++++++
 5 files changed, 588 insertions(+)
 create mode 100644 Documentation/hwmon/aspeed-g6-pwm-tach.rst
 create mode 100644 drivers/hwmon/aspeed-g6-pwm-tach.c

diff --git a/Documentation/hwmon/aspeed-g6-pwm-tach.rst b/Documentation/hwmon/aspeed-g6-pwm-tach.rst
new file mode 100644
index 000000000000..17398fe397fe
--- /dev/null
+++ b/Documentation/hwmon/aspeed-g6-pwm-tach.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver aspeed-g6-pwm-tach
+=================================
+
+Supported chips:
+	ASPEED AST2600
+
+Authors:
+	<billy_tsai at aspeedtech.com>
+
+Description:
+------------
+This driver implements support for ASPEED AST2600 Fan Tacho controller.
+The controller supports up to 16 tachometer inputs.
+
+The driver provides the following sensor accesses in sysfs:
+
+=============== ======= ======================================================
+fanX_input	ro	provide current fan rotation value in RPM as reported
+			by the fan to the device.
+fanX_div	rw	Fan divisor: Supported value are power of 4 (1, 4, 16
+                        64, ... 4194304)
+                        The larger divisor, the less rpm accuracy and the less
+                        affected by fan signal glitch.
+=============== ======= ======================================================
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index c7ed1f73ac06..746bc213bbf7 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -44,6 +44,7 @@ Hardware Monitoring Kernel Drivers
    aquacomputer_d5next
    asb100
    asc7621
+   aspeed-g6-pwm-tach
    aspeed-pwm-tacho
    asus_ec_sensors
    asus_wmi_sensors
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index a608264da87d..a32751e84b7b 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -412,6 +412,17 @@ config SENSORS_ASPEED
 	  This driver can also be built as a module. If so, the module
 	  will be called aspeed_pwm_tacho.
 
+config SENSORS_ASPEED_G6
+	tristate "ASPEED g6 PWM and Fan tach driver"
+	depends on ARCH_ASPEED || COMPILE_TEST
+	depends on PWM
+	help
+	  This driver provides support for ASPEED G6 PWM and Fan Tach
+	  controllers.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called aspeed_pwm_tacho.
+
 config SENSORS_ATXP1
 	tristate "Attansic ATXP1 VID controller"
 	depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 47be39af5c03..2a34d023502f 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_SENSORS_ARM_SCPI)	+= scpi-hwmon.o
 obj-$(CONFIG_SENSORS_AS370)	+= as370-hwmon.o
 obj-$(CONFIG_SENSORS_ASC7621)	+= asc7621.o
 obj-$(CONFIG_SENSORS_ASPEED)	+= aspeed-pwm-tacho.o
+obj-$(CONFIG_SENSORS_ASPEED_G6) += aspeed-g6-pwm-tach.o
 obj-$(CONFIG_SENSORS_ATXP1)	+= atxp1.o
 obj-$(CONFIG_SENSORS_AXI_FAN_CONTROL) += axi-fan-control.o
 obj-$(CONFIG_SENSORS_BT1_PVT)	+= bt1-pvt.o
diff --git a/drivers/hwmon/aspeed-g6-pwm-tach.c b/drivers/hwmon/aspeed-g6-pwm-tach.c
new file mode 100644
index 000000000000..597b3b019d49
--- /dev/null
+++ b/drivers/hwmon/aspeed-g6-pwm-tach.c
@@ -0,0 +1,549 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Aspeed Technology Inc.
+ *
+ * PWM/TACH controller driver for Aspeed ast2600 SoCs.
+ * This drivers doesn't support earlier version of the IP.
+ *
+ * The hardware operates in time quantities of length
+ * Q := (DIV_L + 1) << DIV_H / input-clk
+ * The length of a PWM period is (DUTY_CYCLE_PERIOD + 1) * Q.
+ * The maximal value for DUTY_CYCLE_PERIOD is used here to provide
+ * a fine grained selection for the duty cycle.
+ *
+ * This driver uses DUTY_CYCLE_RISING_POINT = 0, so from the start of a
+ * period the output is active until DUTY_CYCLE_FALLING_POINT * Q. Note
+ * that if DUTY_CYCLE_RISING_POINT = DUTY_CYCLE_FALLING_POINT the output is
+ * always active.
+ *
+ * Register usage:
+ * PIN_ENABLE: When it is unset the pwm controller will emit inactive level to the external.
+ * Use to determine whether the PWM channel is enabled or disabled
+ * CLK_ENABLE: When it is unset the pwm controller will assert the duty counter reset and
+ * emit inactive level to the PIN_ENABLE mux after that the driver can still change the pwm period
+ * and duty and the value will apply when CLK_ENABLE be set again.
+ * Use to determine whether duty_cycle bigger than 0.
+ * PWM_ASPEED_CTRL_INVERSE: When it is toggled the output value will inverse immediately.
+ * PWM_ASPEED_DUTY_CYCLE_FALLING_POINT/PWM_ASPEED_DUTY_CYCLE_RISING_POINT: When these two
+ * values are equal it means the duty cycle = 100%.
+ *
+ * The glitch may generate at:
+ * - Enabled changing when the duty_cycle bigger than 0% and less than 100%.
+ * - Polarity changing when the duty_cycle bigger than 0% and less than 100%.
+ *
+ * Limitations:
+ * - When changing both duty cycle and period, we cannot prevent in
+ *   software that the output might produce a period with mixed
+ *   settings.
+ * - Disabling the PWM doesn't complete the current period.
+ *
+ * Improvements:
+ * - When only changing one of duty cycle or period, our pwm controller will not
+ *   generate the glitch, the configure will change at next cycle of pwm.
+ *   This improvement can disable/enable through PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/hwmon.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/reset.h>
+#include <linux/sysfs.h>
+
+/* The channel number of Aspeed pwm controller */
+#define PWM_ASPEED_NR_PWMS			16
+/* PWM Control Register */
+#define PWM_ASPEED_CTRL(ch)			((ch) * 0x10 + 0x00)
+#define PWM_ASPEED_CTRL_LOAD_SEL_RISING_AS_WDT	BIT(19)
+#define PWM_ASPEED_CTRL_DUTY_LOAD_AS_WDT_ENABLE	BIT(18)
+#define PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE	BIT(17)
+#define PWM_ASPEED_CTRL_CLK_ENABLE		BIT(16)
+#define PWM_ASPEED_CTRL_LEVEL_OUTPUT		BIT(15)
+#define PWM_ASPEED_CTRL_INVERSE			BIT(14)
+#define PWM_ASPEED_CTRL_OPEN_DRAIN_ENABLE	BIT(13)
+#define PWM_ASPEED_CTRL_PIN_ENABLE		BIT(12)
+#define PWM_ASPEED_CTRL_CLK_DIV_H		GENMASK(11, 8)
+#define PWM_ASPEED_CTRL_CLK_DIV_L		GENMASK(7, 0)
+
+/* PWM Duty Cycle Register */
+#define PWM_ASPEED_DUTY_CYCLE(ch)		((ch) * 0x10 + 0x04)
+#define PWM_ASPEED_DUTY_CYCLE_PERIOD		GENMASK(31, 24)
+#define PWM_ASPEED_DUTY_CYCLE_POINT_AS_WDT	GENMASK(23, 16)
+#define PWM_ASPEED_DUTY_CYCLE_FALLING_POINT	GENMASK(15, 8)
+#define PWM_ASPEED_DUTY_CYCLE_RISING_POINT	GENMASK(7, 0)
+
+/* PWM fixed value */
+#define PWM_ASPEED_FIXED_PERIOD			FIELD_MAX(PWM_ASPEED_DUTY_CYCLE_PERIOD)
+
+/* The channel number of Aspeed tach controller */
+#define TACH_ASPEED_NR_TACHS		16
+/* TACH Control Register */
+#define TACH_ASPEED_CTRL(ch)		(((ch) * 0x10) + 0x08)
+#define TACH_ASPEED_IER			BIT(31)
+#define TACH_ASPEED_INVERS_LIMIT	BIT(30)
+#define TACH_ASPEED_LOOPBACK		BIT(29)
+#define TACH_ASPEED_ENABLE		BIT(28)
+#define TACH_ASPEED_DEBOUNCE_MASK	GENMASK(27, 26)
+#define TACH_ASPEED_DEBOUNCE_BIT	26
+#define TACH_ASPEED_IO_EDGE_MASK	GENMASK(25, 24)
+#define TACH_ASPEED_IO_EDGE_BIT		24
+#define TACH_ASPEED_CLK_DIV_T_MASK	GENMASK(23, 20)
+#define TACH_ASPEED_CLK_DIV_BIT		20
+#define TACH_ASPEED_THRESHOLD_MASK	GENMASK(19, 0)
+/* [27:26] */
+#define DEBOUNCE_3_CLK			0x00
+#define DEBOUNCE_2_CLK			0x01
+#define DEBOUNCE_1_CLK			0x02
+#define DEBOUNCE_0_CLK			0x03
+/* [25:24] */
+#define F2F_EDGES			0x00
+#define R2R_EDGES			0x01
+#define BOTH_EDGES			0x02
+/* [23:20] */
+/* divisor = 4 to the nth power, n = register value */
+#define DEFAULT_TACH_DIV		1024
+#define DIV_TO_REG(divisor)		(ilog2(divisor) >> 1)
+
+/* TACH Status Register */
+#define TACH_ASPEED_STS(ch)		(((ch) * 0x10) + 0x0C)
+
+/*PWM_TACH_STS */
+#define TACH_ASPEED_ISR			BIT(31)
+#define TACH_ASPEED_PWM_OUT		BIT(25)
+#define TACH_ASPEED_PWM_OEN		BIT(24)
+#define TACH_ASPEED_DEB_INPUT		BIT(23)
+#define TACH_ASPEED_RAW_INPUT		BIT(22)
+#define TACH_ASPEED_VALUE_UPDATE	BIT(21)
+#define TACH_ASPEED_FULL_MEASUREMENT	BIT(20)
+#define TACH_ASPEED_VALUE_MASK		GENMASK(19, 0)
+/**********************************************************
+ * Software setting
+ *********************************************************/
+#define DEFAULT_FAN_PULSE_PR		2
+
+struct aspeed_pwm_tach_data {
+	struct device *dev;
+	void __iomem *base;
+	struct clk *clk;
+	struct reset_control *reset;
+	unsigned long clk_rate;
+	struct pwm_chip chip;
+	bool tach_present[TACH_ASPEED_NR_TACHS];
+	u32 tach_divisor;
+};
+
+static inline struct aspeed_pwm_tach_data *
+aspeed_pwm_chip_to_data(struct pwm_chip *chip)
+{
+	return container_of(chip, struct aspeed_pwm_tach_data, chip);
+}
+
+static int aspeed_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+				struct pwm_state *state)
+{
+	struct aspeed_pwm_tach_data *priv = aspeed_pwm_chip_to_data(chip);
+	u32 hwpwm = pwm->hwpwm;
+	bool polarity, pin_en, clk_en;
+	u32 duty_pt, val;
+	u64 div_h, div_l, duty_cycle_period, dividend;
+
+	val = readl(priv->base + PWM_ASPEED_CTRL(hwpwm));
+	polarity = FIELD_GET(PWM_ASPEED_CTRL_INVERSE, val);
+	pin_en = FIELD_GET(PWM_ASPEED_CTRL_PIN_ENABLE, val);
+	clk_en = FIELD_GET(PWM_ASPEED_CTRL_CLK_ENABLE, val);
+	div_h = FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_H, val);
+	div_l = FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_L, val);
+	val = readl(priv->base + PWM_ASPEED_DUTY_CYCLE(hwpwm));
+	duty_pt = FIELD_GET(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT, val);
+	duty_cycle_period = FIELD_GET(PWM_ASPEED_DUTY_CYCLE_PERIOD, val);
+	/*
+	 * This multiplication doesn't overflow, the upper bound is
+	 * 1000000000 * 256 * 256 << 15 = 0x1dcd650000000000
+	 */
+	dividend = (u64)NSEC_PER_SEC * (div_l + 1) * (duty_cycle_period + 1)
+		       << div_h;
+	state->period = DIV_ROUND_UP_ULL(dividend, priv->clk_rate);
+
+	if (clk_en && duty_pt) {
+		dividend = (u64)NSEC_PER_SEC * (div_l + 1) * duty_pt
+				 << div_h;
+		state->duty_cycle = DIV_ROUND_UP_ULL(dividend, priv->clk_rate);
+	} else {
+		state->duty_cycle = clk_en ? state->period : 0;
+	}
+	state->polarity = polarity ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
+	state->enabled = pin_en;
+	return 0;
+}
+
+static int aspeed_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			    const struct pwm_state *state)
+{
+	struct aspeed_pwm_tach_data *priv = aspeed_pwm_chip_to_data(chip);
+	u32 hwpwm = pwm->hwpwm, duty_pt, val;
+	u64 div_h, div_l, divisor, expect_period;
+	bool clk_en;
+
+	expect_period = div64_u64(ULLONG_MAX, (u64)priv->clk_rate);
+	expect_period = min(expect_period, state->period);
+	dev_dbg(chip->dev, "expect period: %lldns, duty_cycle: %lldns",
+		expect_period, state->duty_cycle);
+	/*
+	 * Pick the smallest value for div_h so that div_l can be the biggest
+	 * which results in a finer resolution near the target period value.
+	 */
+	divisor = (u64)NSEC_PER_SEC * (PWM_ASPEED_FIXED_PERIOD + 1) *
+		  (FIELD_MAX(PWM_ASPEED_CTRL_CLK_DIV_L) + 1);
+	div_h = order_base_2(DIV64_U64_ROUND_UP(priv->clk_rate * expect_period, divisor));
+	if (div_h > 0xf)
+		div_h = 0xf;
+
+	divisor = ((u64)NSEC_PER_SEC * (PWM_ASPEED_FIXED_PERIOD + 1)) << div_h;
+	div_l = div64_u64(priv->clk_rate * expect_period, divisor);
+
+	if (div_l == 0)
+		return -ERANGE;
+
+	div_l -= 1;
+
+	if (div_l > 255)
+		div_l = 255;
+
+	dev_dbg(chip->dev, "clk source: %ld div_h %lld, div_l : %lld\n",
+		priv->clk_rate, div_h, div_l);
+	/* duty_pt = duty_cycle * (PERIOD + 1) / period */
+	duty_pt = div64_u64(state->duty_cycle * priv->clk_rate,
+			    (u64)NSEC_PER_SEC * (div_l + 1) << div_h);
+	dev_dbg(chip->dev, "duty_cycle = %lld, duty_pt = %d\n",
+		state->duty_cycle, duty_pt);
+
+	/*
+	 * Fixed DUTY_CYCLE_PERIOD to its max value to get a
+	 * fine-grained resolution for duty_cycle at the expense of a
+	 * coarser period resolution.
+	 */
+	val = readl(priv->base + PWM_ASPEED_DUTY_CYCLE(hwpwm));
+	val &= ~PWM_ASPEED_DUTY_CYCLE_PERIOD;
+	val |= FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_PERIOD,
+			  PWM_ASPEED_FIXED_PERIOD);
+	writel(val, priv->base + PWM_ASPEED_DUTY_CYCLE(hwpwm));
+
+	if (duty_pt == 0) {
+		/* emit inactive level and assert the duty counter reset */
+		clk_en = 0;
+	} else {
+		clk_en = 1;
+		if (duty_pt >= (PWM_ASPEED_FIXED_PERIOD + 1))
+			duty_pt = 0;
+		val = readl(priv->base + PWM_ASPEED_DUTY_CYCLE(hwpwm));
+		val &= ~(PWM_ASPEED_DUTY_CYCLE_RISING_POINT |
+			 PWM_ASPEED_DUTY_CYCLE_FALLING_POINT);
+		val |= FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT, duty_pt);
+		writel(val, priv->base + PWM_ASPEED_DUTY_CYCLE(hwpwm));
+	}
+
+	val = readl(priv->base + PWM_ASPEED_CTRL(hwpwm));
+	val &= ~(PWM_ASPEED_CTRL_CLK_DIV_H | PWM_ASPEED_CTRL_CLK_DIV_L |
+		 PWM_ASPEED_CTRL_PIN_ENABLE | PWM_ASPEED_CTRL_CLK_ENABLE |
+		 PWM_ASPEED_CTRL_INVERSE);
+	val |= FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_H, div_h) |
+	       FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_L, div_l) |
+	       FIELD_PREP(PWM_ASPEED_CTRL_PIN_ENABLE, state->enabled) |
+	       FIELD_PREP(PWM_ASPEED_CTRL_CLK_ENABLE, clk_en) |
+	       FIELD_PREP(PWM_ASPEED_CTRL_INVERSE, state->polarity);
+	writel(val, priv->base + PWM_ASPEED_CTRL(hwpwm));
+
+	return 0;
+}
+
+static const struct pwm_ops aspeed_pwm_ops = {
+	.apply = aspeed_pwm_apply,
+	.get_state = aspeed_pwm_get_state,
+};
+
+static void aspeed_tach_ch_enable(struct aspeed_pwm_tach_data *priv, u8 tach_ch,
+				  bool enable)
+{
+	if (enable)
+		writel(readl(priv->base + TACH_ASPEED_CTRL(tach_ch)) |
+			       TACH_ASPEED_ENABLE,
+		       priv->base + TACH_ASPEED_CTRL(tach_ch));
+	else
+		writel(readl(priv->base + TACH_ASPEED_CTRL(tach_ch)) &
+			       ~TACH_ASPEED_ENABLE,
+		       priv->base + TACH_ASPEED_CTRL(tach_ch));
+}
+
+static int aspeed_tach_val_to_rpm(struct aspeed_pwm_tach_data *priv, u32 tach_val)
+{
+	u64 rpm;
+	u32 tach_div;
+
+	tach_div = tach_val * priv->tach_divisor * DEFAULT_FAN_PULSE_PR;
+
+	dev_dbg(priv->dev, "clk %ld, tach_val %d , tach_div %d\n",
+		priv->clk_rate, tach_val, tach_div);
+
+	rpm = (u64)priv->clk_rate * 60;
+	do_div(rpm, tach_div);
+
+	return (int)rpm;
+}
+
+static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tach_data *priv,
+				      u8 fan_tach_ch)
+{
+	u32 val;
+
+	val = readl(priv->base + TACH_ASPEED_STS(fan_tach_ch));
+
+	if (!(val & TACH_ASPEED_FULL_MEASUREMENT))
+		return 0;
+	val = FIELD_GET(TACH_ASPEED_VALUE_MASK, val);
+	return aspeed_tach_val_to_rpm(priv, val);
+}
+
+static int aspeed_tach_hwmon_read(struct device *dev,
+				  enum hwmon_sensor_types type, u32 attr,
+				  int channel, long *val)
+{
+	struct aspeed_pwm_tach_data *priv = dev_get_drvdata(dev);
+	u32 reg_val;
+
+	switch (attr) {
+	case hwmon_fan_input:
+		*val = aspeed_get_fan_tach_ch_rpm(priv, channel);
+		break;
+	case hwmon_fan_div:
+		reg_val = readl(priv->base + TACH_ASPEED_CTRL(channel));
+		reg_val = FIELD_GET(TACH_ASPEED_CLK_DIV_T_MASK, reg_val);
+		*val = BIT(reg_val << 1);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+	return 0;
+}
+
+static int aspeed_tach_hwmon_write(struct device *dev,
+				   enum hwmon_sensor_types type, u32 attr,
+				   int channel, long val)
+{
+	struct aspeed_pwm_tach_data *priv = dev_get_drvdata(dev);
+	u32 reg_val;
+
+	switch (attr) {
+	case hwmon_fan_div:
+		if (!is_power_of_2(val) || (ilog2(val) % 2) ||
+		    DIV_TO_REG(val) > 0xb)
+			return -EINVAL;
+		priv->tach_divisor = val;
+		reg_val = readl(priv->base + TACH_ASPEED_CTRL(channel));
+		reg_val &= ~TACH_ASPEED_CLK_DIV_T_MASK;
+		reg_val |= FIELD_PREP(TACH_ASPEED_CLK_DIV_T_MASK,
+				      DIV_TO_REG(priv->tach_divisor));
+		writel(reg_val, priv->base + TACH_ASPEED_CTRL(channel));
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static umode_t aspeed_tach_dev_is_visible(const void *drvdata,
+					  enum hwmon_sensor_types type,
+					  u32 attr, int channel)
+{
+	const struct aspeed_pwm_tach_data *priv = drvdata;
+
+	if (!priv->tach_present[channel])
+		return 0;
+	switch (attr) {
+	case hwmon_fan_input:
+		return 0444;
+	case hwmon_fan_div:
+		return 0644;
+	}
+	return 0;
+}
+
+static const struct hwmon_ops aspeed_tach_ops = {
+	.is_visible = aspeed_tach_dev_is_visible,
+	.read = aspeed_tach_hwmon_read,
+	.write = aspeed_tach_hwmon_write,
+};
+
+static const struct hwmon_channel_info *aspeed_tach_info[] = {
+	HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV,
+			   HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV,
+			   HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV,
+			   HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV,
+			   HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV,
+			   HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV,
+			   HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV,
+			   HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV),
+	NULL
+};
+
+static const struct hwmon_chip_info aspeed_tach_chip_info = {
+	.ops = &aspeed_tach_ops,
+	.info = aspeed_tach_info,
+};
+
+static void aspeed_present_fan_tach(struct aspeed_pwm_tach_data *priv, u8 *tach_ch, int count)
+{
+	u8 ch, index;
+	u32 val;
+
+	for (index = 0; index < count; index++) {
+		ch = tach_ch[index];
+		priv->tach_present[ch] = true;
+		priv->tach_divisor = DEFAULT_TACH_DIV;
+
+		val = readl(priv->base + TACH_ASPEED_CTRL(ch));
+		val &= ~(TACH_ASPEED_INVERS_LIMIT | TACH_ASPEED_DEBOUNCE_MASK |
+			 TACH_ASPEED_IO_EDGE_MASK | TACH_ASPEED_CLK_DIV_T_MASK |
+			 TACH_ASPEED_THRESHOLD_MASK);
+		val |= (DEBOUNCE_3_CLK << TACH_ASPEED_DEBOUNCE_BIT) |
+		       F2F_EDGES |
+		       FIELD_PREP(TACH_ASPEED_CLK_DIV_T_MASK,
+				  DIV_TO_REG(priv->tach_divisor));
+		writel(val, priv->base + TACH_ASPEED_CTRL(ch));
+
+		aspeed_tach_ch_enable(priv, ch, true);
+	}
+}
+
+static int aspeed_create_fan_monitor(struct device *dev,
+				     struct device_node *child,
+				     struct aspeed_pwm_tach_data *priv)
+{
+	int ret, count;
+	u8 *tach_ch;
+
+	count = of_property_count_u8_elems(child, "tach-ch");
+	if (count < 1)
+		return -EINVAL;
+	tach_ch = devm_kcalloc(dev, count, sizeof(*tach_ch), GFP_KERNEL);
+	if (!tach_ch)
+		return -ENOMEM;
+	ret = of_property_read_u8_array(child, "tach-ch", tach_ch, count);
+	if (ret)
+		return ret;
+
+	aspeed_present_fan_tach(priv, tach_ch, count);
+
+	return 0;
+}
+
+static void aspeed_pwm_tach_reset_assert(void *data)
+{
+	struct reset_control *rst = data;
+
+	reset_control_assert(rst);
+}
+
+static int aspeed_pwm_tach_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev, *hwmon;
+	int ret;
+	struct device_node *child;
+	struct aspeed_pwm_tach_data *priv;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	priv->dev = dev;
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	priv->clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(priv->clk))
+		return dev_err_probe(dev, PTR_ERR(priv->clk),
+				     "Couldn't get clock\n");
+	priv->clk_rate = clk_get_rate(priv->clk);
+	priv->reset = devm_reset_control_get_exclusive(dev, NULL);
+	if (IS_ERR(priv->reset))
+		return dev_err_probe(dev, PTR_ERR(priv->reset),
+				     "Couldn't get reset control\n");
+
+	ret = reset_control_deassert(priv->reset);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Couldn't deassert reset control\n");
+	ret = devm_add_action_or_reset(dev, aspeed_pwm_tach_reset_assert,
+				       priv->reset);
+	if (ret)
+		return ret;
+
+	priv->chip.dev = dev;
+	priv->chip.ops = &aspeed_pwm_ops;
+	priv->chip.npwm = PWM_ASPEED_NR_PWMS;
+
+	ret = devm_pwmchip_add(dev, &priv->chip);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to add PWM chip\n");
+
+	for_each_child_of_node(dev->of_node, child) {
+		ret = aspeed_create_fan_monitor(dev, child, priv);
+		if (ret) {
+			of_node_put(child);
+			dev_warn(dev, "Failed to create fan %d", ret);
+			return 0;
+		}
+	}
+
+	hwmon = devm_hwmon_device_register_with_info(dev, "aspeed_tach", priv,
+						     &aspeed_tach_chip_info, NULL);
+	ret = PTR_ERR_OR_ZERO(hwmon);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to register hwmon device\n");
+
+	of_platform_populate(dev->of_node, NULL, NULL, dev);
+
+	return 0;
+}
+
+static int aspeed_pwm_tach_remove(struct platform_device *pdev)
+{
+	struct aspeed_pwm_tach_data *priv = platform_get_drvdata(pdev);
+
+	reset_control_assert(priv->reset);
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_pwm_tach_match[] = {
+	{
+		.compatible = "aspeed,ast2600-pwm-tach",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, aspeed_pwm_tach_match);
+
+static struct platform_driver aspeed_pwm_tach_driver = {
+	.probe = aspeed_pwm_tach_probe,
+	.remove = aspeed_pwm_tach_remove,
+	.driver	= {
+		.name = "aspeed-g6-pwm-tach",
+		.of_match_table = aspeed_pwm_tach_match,
+	},
+};
+
+module_platform_driver(aspeed_pwm_tach_driver);
+
+MODULE_AUTHOR("Billy Tsai <billy_tsai at aspeedtech.com>");
+MODULE_DESCRIPTION("Aspeed ast2600 PWM and Fan Tach device driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From lpieralisi at kernel.org  Wed Feb 21 02:42:41 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Wed, 21 Feb 2024 11:42:41 +0100
Subject: [PATCH v11 10/14] PCI: imx6: Add iMX95 PCIe Root Complex support
In-Reply-To: <20240220161924.3871774-11-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
 <20240220161924.3871774-11-Frank.Li@nxp.com>
Message-ID: <ZdXTof/fSOuBw4MW@lpieralisi>

On Tue, Feb 20, 2024 at 11:19:20AM -0500, Frank Li wrote:
> Add iMX95 PCIe Root Complex support.
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> 
> Notes:
>     Change from v8 to v9
>     - Add mani's review tag
>     
>     Change from v7 to v8
>     - Update commit subject
>     - add const from regmap
>     - remove unnessary logic in imx6_pcie_deassert_core_reset()
>     
>     Change from v4 to v7
>     - none
>     Change from v1 to v3
>     - none
> 
>  drivers/pci/controller/dwc/pci-imx6.c | 82 +++++++++++++++++++++++++--
>  1 file changed, 77 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 71ce6b7ac1de0..582ba00d628a1 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -42,6 +42,25 @@
>  #define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE	GENMASK(11, 8)
>  #define IMX8MQ_PCIE2_BASE_ADDR			0x33c00000
>  
> +#define IMX95_PCIE_PHY_GEN_CTRL			0x0
> +#define IMX95_PCIE_REF_USE_PAD			BIT(17)
> +
> +#define IMX95_PCIE_PHY_MPLLA_CTRL		0x10
> +#define IMX95_PCIE_PHY_MPLL_STATE		BIT(30)

These two defines are unused, I will remove them.

> +#define IMX95_PCIE_SS_RW_REG_0			0xf0
> +#define IMX95_PCIE_REF_CLKEN			BIT(23)
> +#define IMX95_PCIE_PHY_CR_PARA_SEL		BIT(9)
> +
> +#define IMX95_PE0_GEN_CTRL_1			0x1050
> +#define IMX95_PCIE_DEVICE_TYPE			GENMASK(3, 0)
> +
> +#define IMX95_PE0_GEN_CTRL_3			0x1058
> +#define IMX95_PCIE_LTSSM_EN			BIT(0)
> +
> +#define IMX95_PE0_PM_STS			0x1064
> +#define IMX95_PCIE_PM_LINKST_IN_L2		BIT(14)

These two defines are unused. I will remove them.

> +
>  #define to_imx6_pcie(x)	dev_get_drvdata((x)->dev)
>  
>  enum imx6_pcie_variants {
> @@ -52,6 +71,7 @@ enum imx6_pcie_variants {
>  	IMX8MQ,
>  	IMX8MM,
>  	IMX8MP,
> +	IMX95,
>  	IMX8MQ_EP,
>  	IMX8MM_EP,
>  	IMX8MP_EP,
> @@ -63,6 +83,7 @@ enum imx6_pcie_variants {
>  #define IMX6_PCIE_FLAG_HAS_PHYDRV			BIT(3)
>  #define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
>  #define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
> +#define IMX6_PCIE_FLAG_HAS_SERDES		BIT(6)
>  
>  #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
>  
> @@ -179,6 +200,24 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
>  	return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
>  }
>  
> +static int imx95_pcie_init_phy(struct imx6_pcie *imx6_pcie)
> +{
> +	regmap_update_bits(imx6_pcie->iomuxc_gpr,
> +			IMX95_PCIE_SS_RW_REG_0,
> +			IMX95_PCIE_PHY_CR_PARA_SEL,
> +			IMX95_PCIE_PHY_CR_PARA_SEL);
> +
> +	regmap_update_bits(imx6_pcie->iomuxc_gpr,
> +			   IMX95_PCIE_PHY_GEN_CTRL,
> +			   IMX95_PCIE_REF_USE_PAD, 0);
> +	regmap_update_bits(imx6_pcie->iomuxc_gpr,
> +			   IMX95_PCIE_SS_RW_REG_0,
> +			   IMX95_PCIE_REF_CLKEN,
> +			   IMX95_PCIE_REF_CLKEN);
> +
> +	return 0;
> +}
> +
>  static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
>  {
>  	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
> @@ -575,6 +614,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
>  				   IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
>  		break;
>  	case IMX7D:
> +	case IMX95:
>  		break;
>  	case IMX8MM:
>  	case IMX8MM_EP:
> @@ -1279,12 +1319,32 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>  		return PTR_ERR(imx6_pcie->turnoff_reset);
>  	}
>  
> +	if (imx6_pcie->drvdata->gpr) {
>  	/* Grab GPR config register range */
> -	imx6_pcie->iomuxc_gpr =
> -		 syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
> -	if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
> -		dev_err(dev, "unable to find iomuxc registers\n");
> -		return PTR_ERR(imx6_pcie->iomuxc_gpr);
> +		imx6_pcie->iomuxc_gpr =
> +			 syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
> +		if (IS_ERR(imx6_pcie->iomuxc_gpr))
> +			return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
> +					     "unable to find iomuxc registers\n");
> +	}
> +
> +	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_SERDES)) {
> +		void __iomem *off = devm_platform_ioremap_resource_byname(pdev, "app");
> +
> +		if (IS_ERR(off))
> +			return dev_err_probe(dev, PTR_ERR(off),
> +					     "unable to find serdes registers\n");
> +
> +		static const struct regmap_config regmap_config = {
> +			.reg_bits = 32,
> +			.val_bits = 32,
> +			.reg_stride = 4,
> +		};
> +
> +		imx6_pcie->iomuxc_gpr = devm_regmap_init_mmio(dev, off, &regmap_config);
> +		if (IS_ERR(imx6_pcie->iomuxc_gpr))
> +			return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
> +					     "unable to find iomuxc registers\n");
>  	}
>  
>  	/* Grab PCIe PHY Tx Settings */
> @@ -1457,6 +1517,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.mode_off[0] = IOMUXC_GPR12,
>  		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
>  	},
> +	[IMX95] = {
> +		.variant = IMX95,
> +		.flags = IMX6_PCIE_FLAG_HAS_SERDES,
> +		.clk_names = imx8mq_clks,
> +		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> +		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> +		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
> +		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
> +		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> +		.init_phy = imx95_pcie_init_phy,
> +	},
>  	[IMX8MQ_EP] = {
>  		.variant = IMX8MQ_EP,
>  		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
> @@ -1501,6 +1572,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
>  	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
>  	{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
>  	{ .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], },
> +	{ .compatible = "fsl,imx95-pcie", .data = &drvdata[IMX95], },
>  	{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
>  	{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
>  	{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
> -- 
> 2.34.1
> 


From lpieralisi at kernel.org  Wed Feb 21 02:49:27 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Wed, 21 Feb 2024 11:49:27 +0100
Subject: [PATCH v11 07/14] dt-bindings: imx6q-pcie: Clean up
 irrationality clocks check
In-Reply-To: <20240220161924.3871774-8-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
 <20240220161924.3871774-8-Frank.Li@nxp.com>
Message-ID: <ZdXVN17SogJG1RgZ@lpieralisi>

Irrationality ? I think you mean "duplicate" or "redundant" ?

Lorenzo

On Tue, Feb 20, 2024 at 11:19:17AM -0500, Frank Li wrote:
> The bindings referencing this file already define these constraints for
> each of the variants, so the if not: then: is redundant.
> 
> Acked-by: Rob Herring <robh at kernel.org>
> Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
> 
> Notes:
>     Change from v7 to v8
>     - add Manivannan Sadhasiva's Ack tag
>     Change from v6 to v7
>     - rewrite git commit message by using simple words
>     Change from v5 to v6
>     - rewrite git commit message and explain why remove it safely.
>     - Add Rob's Ack
>     Change from v1 to v4
>     - new patch at v4
> 
>  .../bindings/pci/fsl,imx6q-pcie-common.yaml      | 16 ----------------
>  1 file changed, 16 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
> index d91b639ae7ae7..0c50487a3866d 100644
> --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
> +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
> @@ -150,22 +150,6 @@ allOf:
>              - {}
>              - const: pcie_phy
>              - const: pcie_aux
> -  - if:
> -      properties:
> -        compatible:
> -          not:
> -            contains:
> -              enum:
> -                - fsl,imx6sx-pcie
> -                - fsl,imx8mq-pcie
> -                - fsl,imx6sx-pcie-ep
> -                - fsl,imx8mq-pcie-ep
> -    then:
> -      properties:
> -        clocks:
> -          maxItems: 3
> -        clock-names:
> -          maxItems: 3
>  
>    - if:
>        properties:
> -- 
> 2.34.1
> 


From cristian.marussi at arm.com  Wed Feb 21 02:52:33 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 21 Feb 2024 10:52:33 +0000
Subject: [PATCH] firmware: arm_scmi: optee: fix struct kernel-doc warnings
In-Reply-To: <20240221062157.8694-1-rdunlap@infradead.org>
References: <20240221062157.8694-1-rdunlap@infradead.org>
Message-ID: <ZdXV8Tlig2qeIGD2@pluto>

On Tue, Feb 20, 2024 at 10:21:57PM -0800, Randy Dunlap wrote:
> Fix the kernel-doc notation for the nested union in struct
> scmi_optee_channel to eliminate kerenl-doc warnings:
> 
> optee.c:130: warning: Excess struct member 'shmem' description in 'scmi_optee_channel'
> optee.c:131: warning: Function parameter or struct member 'req' not described in 'scmi_optee_channel'

Thanks for this, I've spotted it recently and didn't get time to address it.

Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>

Cristian

> 
> Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: Cristian Marussi <cristian.marussi at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> ---
>  drivers/firmware/arm_scmi/optee.c |    6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff -- a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c
> --- a/drivers/firmware/arm_scmi/optee.c
> +++ b/drivers/firmware/arm_scmi/optee.c
> @@ -109,8 +109,10 @@ enum scmi_optee_pta_cmd {
>   * @rx_len: Response size
>   * @mu: Mutex protection on channel access
>   * @cinfo: SCMI channel information
> - * @shmem: Virtual base address of the shared memory
> - * @req: Shared memory protocol handle for SCMI request and synchronous response
> + * @req: union for SCMI interface
> + * @req.shmem: Virtual base address of the shared memory
> + * @req.msg: Shared memory protocol handle for SCMI request and
> + *   synchronous response
>   * @tee_shm: TEE shared memory handle @req or NULL if using IOMEM shmem
>   * @link: Reference in agent's channel list
>   */


From angelogioacchino.delregno at collabora.com  Wed Feb 21 02:52:49 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 21 Feb 2024 11:52:49 +0100
Subject: [PATCH 4/4] arm64: dts: mediatek: Add Cudy WR3000 V1
In-Reply-To: <b4e8d3c6-5113-4324-9af5-c4e89cd89349@gmail.com>
References: <20240221073524.20947-1-zajec5@gmail.com>
 <20240221073524.20947-5-zajec5@gmail.com>
 <2fdf724e-4994-4873-971a-56c19b9fc471@collabora.com>
 <b4e8d3c6-5113-4324-9af5-c4e89cd89349@gmail.com>
Message-ID: <80e92209-5578-44e7-bd4b-603a29053ddf@collabora.com>

Il 21/02/24 11:18, Rafa? Mi?ecki ha scritto:
> On 21.02.2024 11:11, AngeloGioacchino Del Regno wrote:
>> Il 21/02/24 08:35, Rafa? Mi?ecki ha scritto:
>>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>>
>>> Cudy WR3000 V1 is an MT7981B (AKA Filogic 820) based wireless router. It
>>> has 256 MiB of RAM, some LEDs & buttons and (not described yet) 4
>>> Ethernet ports.
>>>
>>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>>> ---
>>> ? arch/arm64/boot/dts/mediatek/Makefile???????? |? 1 +
>>> ? .../dts/mediatek/mt7981b-cudy-wr3000-v1.dts?? | 74 +++++++++++++++++++
>>> ? 2 files changed, 75 insertions(+)
>>> ? create mode 100644 arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
>>>
>>> diff --git a/arch/arm64/boot/dts/mediatek/Makefile 
>>> b/arch/arm64/boot/dts/mediatek/Makefile
>>> index 37b4ca3a87c9..96da4ad640aa 100644
>>> --- a/arch/arm64/boot/dts/mediatek/Makefile
>>> +++ b/arch/arm64/boot/dts/mediatek/Makefile
>>> @@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
>>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
>>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
>>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
>>> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-cudy-wr3000-v1.dtb
>>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-xiaomi-ax3000t.dtb
>>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-acelink-ew-7886cax.dtb
>>> ? dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb
>>> diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts 
>>> b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
>>> new file mode 100644
>>> index 000000000000..cb36a089518a
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
>>> @@ -0,0 +1,74 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
>>> +
>>> +/dts-v1/;
>>> +#include <dt-bindings/input/input.h>
>>> +#include <dt-bindings/gpio/gpio.h>
>>> +#include <dt-bindings/leds/common.h>
>>> +
>>> +#include "mt7981b.dtsi"
>>> +
>>> +/ {
>>> +??? compatible = "cudy,wr3000-v1", "mediatek,mt7981b";
>>> +??? model = "Cudy WR3000 V1";
>>> +
>>> +??? memory at 40000000 {
>>> +??????? reg = <0 0x40000000 0 0x10000000>;
>>> +??????? device_type = "memory";
>>> +??? };
>>> +
>>> +??? keys {
>>> +??????? compatible = "gpio-keys";
>>> +
>>> +??????? key-wps {
>>> +??????????? label = "WPS";
>>> +??????????? gpios = <&pio 0 GPIO_ACTIVE_LOW>;
>>> +??????????? linux,code = <KEY_WPS_BUTTON>;
>>> +??????? };
>>> +
>>> +??????? key-reset {
>>> +??????????? label = "RESET";
>>> +??????????? gpios = <&pio 1 GPIO_ACTIVE_LOW>;
>>> +??????????? linux,code = <KEY_RESTART>;
>>> +??????? };
>>> +??? };
>>> +
>>> +??? leds {
>>> +??????? compatible = "gpio-leds";
>>> +
>>> +??????? led-0 {
>>> +??????????? function = LED_FUNCTION_WAN;
>>> +??????????? color = <LED_COLOR_ID_BLUE>;
>>> +??????????? gpios = <&pio 5 GPIO_ACTIVE_LOW>;
>>
>> Can we please order those properties alphabetically, as it doesn't impact
>> on human readability in any way?
>> Just a nitpick, anyway.
>>
>> color = <LED_COLOR_ID_BLUE>;
>> function = LED_FUNCTION_WAN;
>> gpios = <&pio 5 GPIO_ACTIVE_LOW>;
> 
> If I understand [1] correctly alphabetical / alpha-numerical order
> applies to non-addresses nodes only.
> 
> Here I put "function" first as that seemed more important than a color.
> 
> Perhaps you could suggest an addition to Devicetree Sources (DTS) Coding
> Style or point me to the missed part, please?
> 
> [1] 
> https://www.kernel.org/doc/html/next/devicetree/bindings/dts-coding-style.html#order-of-properties-in-device-node
> 
> 

I didn't say that this was *mandatory*, but since alphanumeric ordering in device
trees is actually a thing for nodes, this could be as well applied to properties
inside when this doesn't impact on human readability.

As far as I'm aware, I'm not the only maintainer asking for that (am I?!)

If you've got any *strong opinion* about having `function` as the first property,
I'm full ears, and I will be okay with that. No problem on my side, I'm open for
alternatives when those make sense.

> 
>>> +??????? };
>>> +
>>> +??????? led-1 {
>>> +??????????? function = LED_FUNCTION_WLAN_2GHZ;
>>> +??????????? color = <LED_COLOR_ID_BLUE>;
>>> +??????????? gpios = <&pio 6 GPIO_ACTIVE_LOW>;
>>> +??????? };
>>> +
>>> +??????? led-2 {
>>> +??????????? function = LED_FUNCTION_WLAN_5GHZ;
>>> +??????????? color = <LED_COLOR_ID_BLUE>;
>>> +??????????? gpios = <&pio 7 GPIO_ACTIVE_LOW>;
>>> +??????? };
>>> +
>>> +??????? led-3 {
>>> +??????????? function = LED_FUNCTION_LAN;
>>> +??????????? color = <LED_COLOR_ID_BLUE>;
>>> +??????????? gpios = <&pio 9 GPIO_ACTIVE_LOW>;
>>> +??????? };
>>> +
>>> +??????? led-4 {
>>> +??????????? function = LED_FUNCTION_STATUS;
>>> +??????????? color = <LED_COLOR_ID_BLUE>;
>>> +??????????? gpios = <&pio 10 GPIO_ACTIVE_LOW>;
>>> +??????? };
>>> +
>>> +??????? led-5 {
>>> +??????????? function = "online";
>>
>> Uhm, what does "online" mean?
>>
>> Are you sure that you can't use any of the LED_FUNCTION_XXX standard definitions?
> 
> This device has:
> 1. "WAN Port" LED that indicates "WAN Port has connection" state

Just a curiosity: is the WAN port ethernet, fiber or what?
(to entirely clarify in my brain if that LED is a carrier detect indicator,
but doesn't matter for this patch, it's really just a personal curiosity and
nothing else)

> 2. "Internet" LED that indicates "Connected to the Internet" state
> 
> I couldn't find any define that would fit Internet access LED case.

I was imagining something like that, but wasn't sure, so asking you was the best
choice.

I wonder if it makes sense to add a "wan-online" or "wan-connected" or .. I don't
know, some definition that makes common sense, to dt-bindings/leds/common.h to
somewhat standardize the function for that usecase?

One thing I'm (mostly) sure of, it makes sense to have the "wan-" prefix before
any word (because you can have sorts of authenticated LANs as well).

I don't think that there's anything hugely restrictive that would prevent you
from doing that: there are even "player-[1-5]" definitions for game controllers,
and yours is not the first router that I physically see with my own eyes that
has such a LED for that state.

After all, what's going to turn on that LED is userspace, and if we can get one
that works for all (without custom functions for each router), why not :-)




From thomas.richard at bootlin.com  Wed Feb 21 02:59:05 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Wed, 21 Feb 2024 11:59:05 +0100
Subject: [PATCH v3 05/18] mux: add mux_chip_resume() function
In-Reply-To: <Zc96Ke_iG_bHIvkP@smile.fi.intel.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-5-5c2e4a3fac1f@bootlin.com>
 <Zc4t82V9czlEqamL@smile.fi.intel.com>
 <f1d2c9b0-238d-4b09-8212-62e00a2192b2@bootlin.com>
 <Zc96Ke_iG_bHIvkP@smile.fi.intel.com>
Message-ID: <eb37a117-74bd-44fe-b677-89dc7c2aced8@bootlin.com>

On 2/16/24 16:07, Andy Shevchenko wrote:
> On Fri, Feb 16, 2024 at 08:52:17AM +0100, Thomas Richard wrote:
>> On 2/15/24 16:29, Andy Shevchenko wrote:
>>> On Thu, Feb 15, 2024 at 04:17:50PM +0100, Thomas Richard wrote:
> 
> ...
> 
>>>> +int mux_chip_resume(struct mux_chip *mux_chip)
>>>> +{
>>>> +	int global_ret = 0;
>>>> +	int ret, i;
>>>> +
>>>> +	for (i = 0; i < mux_chip->controllers; ++i) {
>>>> +		struct mux_control *mux = &mux_chip->mux[i];
>>>> +
>>>> +		if (mux->cached_state == MUX_CACHE_UNKNOWN)
>>>> +			continue;
>>>> +
>>>> +		ret = mux_control_set(mux, mux->cached_state);
>>>> +		if (ret < 0) {
>>>> +			dev_err(&mux_chip->dev, "unable to restore state\n");
>>>> +			if (!global_ret)
>>>> +				global_ret = ret;
>>>
>>> Hmm... This will record the first error and continue.
>>
>> In the v2 we talked about this with Peter Rosin.
>>
>> In fact, in the v1 (mux_chip_resume() didn't exists yet, everything was
>> done in the mmio driver) I had the same behavior: try to restore all
>> muxes and in case of error restore the first one.
>>
>> I don't know what is the right solution. I just restored the behavior I
>> had in v1.
> 
> Okay, I believe you know what you are doing, folks. But to me this approach
> sounds at bare minimum "unusual". Because the failures here are not fatal
> and recording the first one may or may not make sense and it's so fragile
> as it completely implementation-dependent.

I guess if there is an error, the resume is completely dead so no need
to continue.
If it's okay for Peter I can return on first failure.

Regards,

-- 
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From thomas.richard at bootlin.com  Wed Feb 21 03:01:43 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Wed, 21 Feb 2024 12:01:43 +0100
Subject: [PATCH v3 02/18] pinctrl: pinctrl-single: remove dead code in
 suspend() and resume() callbacks
In-Reply-To: <Zc96dSff5Y-dufrJ@smile.fi.intel.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-2-5c2e4a3fac1f@bootlin.com>
 <Zc4tedAhqYX3bQcw@smile.fi.intel.com>
 <78add459-a96a-46c6-83ff-e2657d4d3db4@bootlin.com>
 <Zc96dSff5Y-dufrJ@smile.fi.intel.com>
Message-ID: <a2c3c5b9-79a3-4793-892c-b1ab79b71c7d@bootlin.com>

On 2/16/24 16:08, Andy Shevchenko wrote:
> On Fri, Feb 16, 2024 at 08:59:47AM +0100, Thomas Richard wrote:
>> On 2/15/24 16:27, Andy Shevchenko wrote:
>>> On Thu, Feb 15, 2024 at 04:17:47PM +0100, Thomas Richard wrote:
>>>> No need to check the pointer returned by platform_get_drvdata(), as
>>>> platform_set_drvdata() is called during the probe.
>>>
>>> This patch should go _after_ the next one, otherwise the commit message doesn't
>>> tell full story and the code change bring a potential regression.
>>
>> Hello Andy,
>>
>> I'm ok to move this patch after the next one.
>> But for my understanding, could you explain me why changing the order is
>> important in this case ?
> 
> Old PM calls obviously can be called in different circumstances and these
> checks are important.
> 
> Just squash these two patches to avoid additional churn and we are done.

You mean invert the order instead of squash.

-- 
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From lkp at intel.com  Wed Feb 21 03:07:40 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 21 Feb 2024 19:07:40 +0800
Subject: [soc:soc/defconfig] BUILD SUCCESS
 641a6e6962a1388944c6494a9a9f5374fe6f9b90
Message-ID: <202402211937.IAn7z5Ng-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/defconfig
branch HEAD: 641a6e6962a1388944c6494a9a9f5374fe6f9b90  Merge tag 'renesas-arm-defconfig-for-v6.9-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/defconfig

elapsed time: 823m

configs tested: 101
configs skipped: 147

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                        nsimosci_defconfig   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm                   randconfig-001-20240221   clang
arm                   randconfig-002-20240221   clang
arm                   randconfig-003-20240221   gcc  
arm                   randconfig-004-20240221   clang
arm                           stm32_defconfig   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240221   gcc  
arm64                 randconfig-002-20240221   gcc  
arm64                 randconfig-003-20240221   gcc  
arm64                 randconfig-004-20240221   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
i386         buildonly-randconfig-002-20240221   clang
i386                                defconfig   clang
i386                  randconfig-002-20240221   clang
i386                  randconfig-003-20240221   clang
i386                  randconfig-006-20240221   clang
i386                  randconfig-012-20240221   clang
i386                  randconfig-014-20240221   clang
i386                  randconfig-016-20240221   clang
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                        allyesconfig   gcc  
loongarch                           defconfig   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                             allmodconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                       lemote2f_defconfig   gcc  
mips                          malta_defconfig   gcc  
mips                      pic32mzda_defconfig   gcc  
nios2                            alldefconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
openrisc                         allmodconfig   gcc  
openrisc                  or1klitex_defconfig   gcc  
powerpc                         wii_defconfig   gcc  
riscv                               defconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
sh                               allmodconfig   gcc  
sh                               allyesconfig   gcc  
sh                          sdk7780_defconfig   gcc  
sh                        sh7763rdp_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                            allyesconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-002-20240221   gcc  
x86_64       buildonly-randconfig-003-20240221   gcc  
x86_64                randconfig-001-20240221   gcc  
x86_64                randconfig-002-20240221   gcc  
x86_64                randconfig-003-20240221   gcc  
x86_64                randconfig-004-20240221   gcc  
x86_64                randconfig-005-20240221   gcc  
x86_64                randconfig-006-20240221   gcc  
x86_64                randconfig-012-20240221   gcc  
x86_64                randconfig-014-20240221   gcc  
x86_64                randconfig-015-20240221   gcc  
x86_64                randconfig-016-20240221   gcc  
x86_64                randconfig-071-20240221   gcc  
x86_64                randconfig-072-20240221   gcc  
x86_64                randconfig-073-20240221   gcc  
x86_64                randconfig-074-20240221   gcc  
x86_64                randconfig-076-20240221   gcc  
x86_64                          rhel-8.3-rust   clang
x86_64                               rhel-8.3   gcc  
xtensa                           allyesconfig   gcc  
xtensa                generic_kc705_defconfig   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From abel.vesa at linaro.org  Wed Feb 21 03:10:29 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 21 Feb 2024 13:10:29 +0200
Subject: [PATCH] iommu/arm-smmu-qcom: Add X1E80100 MDSS compatible
In-Reply-To: <20240213131952.GB28926@willie-the-truck>
References: <20240131-x1e80100-iommu-arm-smmu-qcom-v1-1-c1240419c718@linaro.org>
 <20240213131952.GB28926@willie-the-truck>
Message-ID: <ZdXaJQ5AfOiki1l5@linaro.org>

On 24-02-13 13:19:52, Will Deacon wrote:
> On Wed, Jan 31, 2024 at 02:35:16PM +0200, Abel Vesa wrote:
> > Add the X1E80100 MDSS compatible to clients compatible list, as it also
> > needs the workarounds.
> > 
> > Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> > ---
> >  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > index 8b04ece00420..5c7cfc51b57c 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > @@ -260,6 +260,7 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
> >  	{ .compatible = "qcom,sm6375-mdss" },
> >  	{ .compatible = "qcom,sm8150-mdss" },
> >  	{ .compatible = "qcom,sm8250-mdss" },
> > +	{ .compatible = "qcom,x1e80100-mdss" },
> 
> I think this needs adding to the bindings Documentation first.

It is documented here (once it gets merged):
https://lore.kernel.org/all/20240220-x1e80100-display-v4-2-971afd9de861 at linaro.org/

> 
> Will


From linux at armlinux.org.uk  Wed Feb 21 03:29:38 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 21 Feb 2024 11:29:38 +0000
Subject: [PATCH] ARM: fault: Implement copy_from_kernel_nofault_allowed()
In-Reply-To: <202402202235.A77C9AD@keescook>
References: <20240123011238.work.301-kees@kernel.org>
 <202402202235.A77C9AD@keescook>
Message-ID: <ZdXeopPukQGXUqoz@shell.armlinux.org.uk>

On Tue, Feb 20, 2024 at 10:39:15PM -0800, Kees Cook wrote:
> On Mon, Jan 22, 2024 at 05:12:38PM -0800, Kees Cook wrote:
> > Under PAN emulation when dumping backtraces from things like the
> > LKDTM EXEC_USERSPACE test[1], a double fault (which would hang a CPU)
> > would happen because of dump_instr() attempting to read a userspace
> > address. Make sure copy_from_kernel_nofault() does not attempt this
> > any more.
> > 
> > Reported-by: Mark Brown <broonie at kernel.org>
> > Link: https://lore.kernel.org/all/202401181125.D48DCB4C at keescook/ [1]
> > Suggested-by: "Russell King (Oracle)" <linux at armlinux.org.uk>
> > Cc: Russell King <linux at armlinux.org.uk>
> > Cc: Ard Biesheuvel <ardb at kernel.org>
> > Cc: Wang Kefeng <wangkefeng.wang at huawei.com>
> > Cc: Andrew Morton <akpm at linux-foundation.org>
> > Cc: Ben Hutchings <ben at decadent.org.uk>
> > Cc: linux-arm-kernel at lists.infradead.org
> > Signed-off-by: Kees Cook <keescook at chromium.org>
> 
> Russell, do you mind if I carry in my tree the 3 ARM patches I sent?
> They're mostly pretty trivial, and they've been in "Incoming"[1] for 2
> weeks but haven't shown up in -next yet. I'd really like them to get
> some soak time, and for them to reach the v6.9 merge window in time.

They can't show up in -next at the moment because the machine that hosts
my git tree is being moved between data centres. This was originally
flagged as a same-day (Tuesday) move, then next day, then it'll be back
online on Saturday. That's the last update that we've had.

As I don't believe my GPG key has the necessary signatures on, I don't
believe I can get a kernel.org account. I'm not even sure whether my
gpg key is even correct for that - and at the moment I just glaze over
reading the kernel.org gpg documentation.

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


From linux at armlinux.org.uk  Wed Feb 21 03:31:59 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 21 Feb 2024 11:31:59 +0000
Subject: [PATCH] ARM: fault: Implement copy_from_kernel_nofault_allowed()
In-Reply-To: <ZdXeopPukQGXUqoz@shell.armlinux.org.uk>
References: <20240123011238.work.301-kees@kernel.org>
 <202402202235.A77C9AD@keescook>
 <ZdXeopPukQGXUqoz@shell.armlinux.org.uk>
Message-ID: <ZdXfL8Kp4R/OT/VA@shell.armlinux.org.uk>

On Wed, Feb 21, 2024 at 11:29:38AM +0000, Russell King (Oracle) wrote:
> On Tue, Feb 20, 2024 at 10:39:15PM -0800, Kees Cook wrote:
> > On Mon, Jan 22, 2024 at 05:12:38PM -0800, Kees Cook wrote:
> > > Under PAN emulation when dumping backtraces from things like the
> > > LKDTM EXEC_USERSPACE test[1], a double fault (which would hang a CPU)
> > > would happen because of dump_instr() attempting to read a userspace
> > > address. Make sure copy_from_kernel_nofault() does not attempt this
> > > any more.
> > > 
> > > Reported-by: Mark Brown <broonie at kernel.org>
> > > Link: https://lore.kernel.org/all/202401181125.D48DCB4C at keescook/ [1]
> > > Suggested-by: "Russell King (Oracle)" <linux at armlinux.org.uk>
> > > Cc: Russell King <linux at armlinux.org.uk>
> > > Cc: Ard Biesheuvel <ardb at kernel.org>
> > > Cc: Wang Kefeng <wangkefeng.wang at huawei.com>
> > > Cc: Andrew Morton <akpm at linux-foundation.org>
> > > Cc: Ben Hutchings <ben at decadent.org.uk>
> > > Cc: linux-arm-kernel at lists.infradead.org
> > > Signed-off-by: Kees Cook <keescook at chromium.org>
> > 
> > Russell, do you mind if I carry in my tree the 3 ARM patches I sent?
> > They're mostly pretty trivial, and they've been in "Incoming"[1] for 2
> > weeks but haven't shown up in -next yet. I'd really like them to get
> > some soak time, and for them to reach the v6.9 merge window in time.
> 
> They can't show up in -next at the moment because the machine that hosts
> my git tree is being moved between data centres. This was originally
> flagged as a same-day (Tuesday) move, then next day, then it'll be back
> online on Saturday. That's the last update that we've had.
> 
> As I don't believe my GPG key has the necessary signatures on, I don't
> believe I can get a kernel.org account. I'm not even sure whether my
> gpg key is even correct for that - and at the moment I just glaze over
> reading the kernel.org gpg documentation.

I'll also point out that over the last two weeks, the first week I was
in Cambridge attending a conference at Arm Ltd, and then I went down
with full blown flu shortly there-after.

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


From p.zabel at pengutronix.de  Wed Feb 21 03:41:02 2024
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 21 Feb 2024 12:41:02 +0100
Subject: [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from
 drivers/pinctrl/nomadik/
In-Reply-To: <CAMRc=Me-oEx9S0w=XhwC4MzV9uzV0o0HnWBfNSstcqg5jpXyZg@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
	 <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>
	 <e031566a85ae0da0ee71dffba5d87c6414ef83e1.camel@pengutronix.de>
	 <CAMRc=Me-oEx9S0w=XhwC4MzV9uzV0o0HnWBfNSstcqg5jpXyZg@mail.gmail.com>
Message-ID: <f2e3d662e92b76e43b89a3c99669c3dadb2176b5.camel@pengutronix.de>

Hi Bartosz,

On Mo, 2024-02-19 at 16:33 +0100, Bartosz Golaszewski wrote:
> On Thu, Feb 15, 2024 at 11:03?AM Philipp Zabel <p.zabel at pengutronix.de> wrote:
> > 
> > On Mi, 2024-02-14 at 17:23 +0100, Th?o Lebrun wrote:
> > [...]
> > > diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
> > > new file mode 100644
> > > index 000000000000..e39477e1a58f
> > > --- /dev/null
> > > +++ b/drivers/gpio/gpio-nomadik.c
> > > @@ -0,0 +1,660 @@
> > [...]
> > > +static int nmk_gpio_probe(struct platform_device *dev)
> > > +{
> > [...]
> > > +     ret = gpiochip_add_data(chip, nmk_chip);
> > 
> > Use devm_gpiochip_add_data() to cleanup on unbind, before nmk_chip goes
> > away. Or make the driver un-unbindable via suppress_bind_attrs. In that
> > case you could drop devm_ prefixes everywhere for consistency.
> > 
> 
> No! Why? What about error paths in probe() where you want to undo everything?

Brain fog moment. I was triggered by the mixture of devm_ and non-devm_
calls and jumped to the wrong conclusion.

Yes, keeping devm_ for error cleanup is of course correct, and with
suppress_bind_attrs it'd even be ok to use non-devm_
gpiochip_add_data(), as long as there can be no error return
afterwards.

regards
Philipp


From peterx at redhat.com  Wed Feb 21 03:49:22 2024
From: peterx at redhat.com (Peter Xu)
Date: Wed, 21 Feb 2024 19:49:22 +0800
Subject: [PATCH v2 10/13] mm/gup: Handle huge pud for follow_pud_mask()
In-Reply-To: <20240115184900.GV734935@nvidia.com>
References: <20240103091423.400294-1-peterx@redhat.com>
 <20240103091423.400294-11-peterx@redhat.com>
 <20240115184900.GV734935@nvidia.com>
Message-ID: <ZdXjQjow4fa41ORD@x1n>

On Mon, Jan 15, 2024 at 02:49:00PM -0400, Jason Gunthorpe wrote:
> On Wed, Jan 03, 2024 at 05:14:20PM +0800, peterx at redhat.com wrote:
> > diff --git a/mm/gup.c b/mm/gup.c
> > index 63845b3ec44f..760406180222 100644
> > --- a/mm/gup.c
> > +++ b/mm/gup.c
> > @@ -525,6 +525,70 @@ static struct page *no_page_table(struct vm_area_struct *vma,
> >  	return NULL;
> >  }
> >  
> > +#ifdef CONFIG_PGTABLE_HAS_HUGE_LEAVES
> > +static struct page *follow_huge_pud(struct vm_area_struct *vma,
> > +				    unsigned long addr, pud_t *pudp,
> > +				    int flags, struct follow_page_context *ctx)
> > +{
> > +	struct mm_struct *mm = vma->vm_mm;
> > +	struct page *page;
> > +	pud_t pud = *pudp;
> > +	unsigned long pfn = pud_pfn(pud);
> > +	int ret;
> > +
> > +	assert_spin_locked(pud_lockptr(mm, pudp));
> > +
> > +	if ((flags & FOLL_WRITE) && !pud_write(pud))
> > +		return NULL;
> > +
> > +	if (!pud_present(pud))
> > +		return NULL;
> > +
> > +	pfn += (addr & ~PUD_MASK) >> PAGE_SHIFT;
> > +
> > +#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
> > +	if (pud_devmap(pud)) {
> 
> Can this use IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD) ?

Sure.

> 
> > +		/*
> > +		 * device mapped pages can only be returned if the caller
> > +		 * will manage the page reference count.
> > +		 *
> > +		 * At least one of FOLL_GET | FOLL_PIN must be set, so
> > +		 * assert that here:
> > +		 */
> > +		if (!(flags & (FOLL_GET | FOLL_PIN)))
> > +			return ERR_PTR(-EEXIST);
> > +
> > +		if (flags & FOLL_TOUCH)
> > +			touch_pud(vma, addr, pudp, flags & FOLL_WRITE);
> > +
> > +		ctx->pgmap = get_dev_pagemap(pfn, ctx->pgmap);
> > +		if (!ctx->pgmap)
> > +			return ERR_PTR(-EFAULT);
> > +	}
> > +#endif	/* CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
> > +	page = pfn_to_page(pfn);
> > +
> > +	if (!pud_devmap(pud) && !pud_write(pud) &&
> > +	    gup_must_unshare(vma, flags, page))
> > +		return ERR_PTR(-EMLINK);
> > +
> > +	ret = try_grab_page(page, flags);
> > +	if (ret)
> > +		page = ERR_PTR(ret);
> > +	else
> > +		ctx->page_mask = HPAGE_PUD_NR - 1;
> > +
> > +	return page;
> > +}
> > +#else  /* CONFIG_PGTABLE_HAS_HUGE_LEAVES */
> > +static struct page *follow_huge_pud(struct vm_area_struct *vma,
> > +				    unsigned long addr, pud_t *pudp,
> > +				    int flags, struct follow_page_context *ctx)
> > +{
> > +	return NULL;
> > +}
> > +#endif	/* CONFIG_PGTABLE_HAS_HUGE_LEAVES */
> > +
> >  static int follow_pfn_pte(struct vm_area_struct *vma, unsigned long address,
> >  		pte_t *pte, unsigned int flags)
> >  {
> > @@ -760,11 +824,11 @@ static struct page *follow_pud_mask(struct vm_area_struct *vma,
> >  
> >  	pudp = pud_offset(p4dp, address);
> >  	pud = READ_ONCE(*pudp);
> > -	if (pud_none(pud))
> > +	if (pud_none(pud) || !pud_present(pud))
> >  		return no_page_table(vma, flags, address);
> 
> Isn't 'pud_none() || !pud_present()' redundent? A none pud is
> non-present, by definition?

Hmm yes, seems redundant.  Let me drop it.

> 
> > -	if (pud_devmap(pud)) {
> > +	if (pud_huge(pud)) {
> >  		ptl = pud_lock(mm, pudp);
> > -		page = follow_devmap_pud(vma, address, pudp, flags, &ctx->pgmap);
> > +		page = follow_huge_pud(vma, address, pudp, flags, ctx);
> >  		spin_unlock(ptl);
> >  		if (page)
> >  			return page;
> 
> Otherwise it looks OK to me
> 
> Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>

Thanks!

-- 
Peter Xu



From peterx at redhat.com  Wed Feb 21 03:55:17 2024
From: peterx at redhat.com (Peter Xu)
Date: Wed, 21 Feb 2024 19:55:17 +0800
Subject: [PATCH v2 06/13] mm/gup: Drop folio_fast_pin_allowed() in hugepd
 processing
In-Reply-To: <20240115183748.GR734935@nvidia.com>
References: <20240103091423.400294-1-peterx@redhat.com>
 <20240103091423.400294-7-peterx@redhat.com>
 <20240115183748.GR734935@nvidia.com>
Message-ID: <ZdXkpYEuRAxoLtHI@x1n>

On Mon, Jan 15, 2024 at 02:37:48PM -0400, Jason Gunthorpe wrote:
> > Drop that check, not only because it'll never be true for hugepd per any
> > known plan, but also it paves way for reusing the function outside
> > fast-gup.
> 
> I didn't see any other caller of this function in this series? When
> does this re-use happen??

It's reused in patch 12 ("mm/gup: Handle hugepd for follow_page()").

Thanks,

-- 
Peter Xu



From bjorn at kernel.org  Wed Feb 21 03:59:22 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Wed, 21 Feb 2024 12:59:22 +0100
Subject: [PATCH v13 06/13] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <CAK9=C2Xnzg3KAVETXN+ZGLWhVtaJuU4uXs3WH2ZondkBJMHFcA@mail.gmail.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-7-apatel@ventanamicro.com>
 <87frxnfj3p.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2Xnzg3KAVETXN+ZGLWhVtaJuU4uXs3WH2ZondkBJMHFcA@mail.gmail.com>
Message-ID: <874je2yqn9.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

>> > +void imsic_vector_mask(struct imsic_vector *vec)
>> > +{
>> > +     struct imsic_local_priv *lpriv;
>> > +
>> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
>> > +     if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
>> > +             return;
>> > +
>> > +     /*
>> > +      * This function is called through Linux irq subsystem with
>> > +      * irqs disabled so no need to save/restore irq flags.
>> > +      */
>> > +
>> > +     raw_spin_lock(&lpriv->lock);
>> > +
>> > +     vec->enable = false;
>> > +     bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
>> > +     __imsic_remote_sync(lpriv, vec->cpu);
>> > +
>> > +     raw_spin_unlock(&lpriv->lock);
>> > +}
>>
>> Really nice that you're using a timer for the vector affinity change,
>> and got rid of the special/weird IMSIC/sync IPI. Can you really use a
>> timer for mask/unmask? That makes the mask/unmask operation
>> asynchronous!
>>
>> That was what I was trying to get though with this comment:
>> https://lore.kernel.org/linux-riscv/87sf24mo1g.fsf at all.your.base.are.belong.to.us/
>>
>> Also, using the smp_* IPI functions, you can pass arguments, so you
>> don't need the dirty_bitmap tracking the changes.
>
> The mask/unmask operations are called with irqs disabled so if
> CPU X does synchronous IPI to another CPU Y from mask/unmask
> operation then while CPU X is waiting for IPI to complete it cannot
> receive IPI from other CPUs which can lead to crashes and stalls.
>
> In general, we should not do any block/busy-wait work in
> mask/unmask operation of an irqchip driver.

Hmm, OK. Still, a bit odd that when the .irq_mask callback return, the
masking is not actually completed.

1. CPU 0 tries to mask an interrupt tried to CPU 1.
2. The timer is queued on CPU 1.
3. The call irq_mask returns on CPU 0
4. ...the irq is masked at some future point, determined by the callback
   at CPU 1

Is that the expected outcome?

There are .irq_mask implementation that does seem to go at length
(blocking) to perform the mask, e.g.: gic_mask_irq() which calls
gic_{re,}dist_wait_for_rwp that have sleep/retry loops. The GIC3 ITS
code has similar things going on.

I'm not saying you're wrong, I'm just trying to wrap my head around the
masking semantics.

> The AIA IMSIC spec allows setting ID pending bit using MSI write
> irrespective whether ID is enabled or not but the interrupt will be
> taken only after ID is enabled. In other words, there will be no
> loss of interrupt with delayed mask/unmask using async IPI or
> lazy timer.

No loss, but we might *get* an interrupt when we explicitly asked not to
get any. Maybe that's ok?


Bj?rn


From ghennadi.procopciuc at oss.nxp.com  Wed Feb 21 04:01:21 2024
From: ghennadi.procopciuc at oss.nxp.com (Ghennadi Procopciuc)
Date: Wed, 21 Feb 2024 14:01:21 +0200
Subject: [PATCH 0/1] MAINTAINERS: Add S32G SoC maintainer
Message-ID: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>

Add myself as co-maintainer for the S32G platform alongside Chester Lin, as I am
directly involved in developing and maintaining the downstream version of the
kernel and Linux BSP for this platform.

Ghennadi Procopciuc (1):
  MAINTAINERS: Add maintainer for NXP S32G boards

 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

-- 
2.43.2



From ghennadi.procopciuc at oss.nxp.com  Wed Feb 21 04:01:22 2024
From: ghennadi.procopciuc at oss.nxp.com (Ghennadi Procopciuc)
Date: Wed, 21 Feb 2024 14:01:22 +0200
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
References: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
Message-ID: <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>

From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>

Add myself as a maintainer of the NXP S32G DT files.

Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ed4d3868539..09d7a0489952 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2543,6 +2543,7 @@ F:	drivers/*/*wpcm*
 
 ARM/NXP S32G ARCHITECTURE
 M:	Chester Lin <chester62515 at gmail.com>
+M:	Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
 R:	Andreas F??rber <afaerber at suse.de>
 R:	Matthias Brugger <mbrugger at suse.com>
 R:	NXP S32 Linux Team <s32 at nxp.com>
-- 
2.43.2



From lkp at intel.com  Wed Feb 21 04:03:09 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 21 Feb 2024 20:03:09 +0800
Subject: [soc:soc/drivers] BUILD SUCCESS
 d22ee157fb2525fd0c35b9d18fd58ed2e4715f80
Message-ID: <202402212005.NX28c4mI-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/drivers
branch HEAD: d22ee157fb2525fd0c35b9d18fd58ed2e4715f80  Merge tag 'memory-controller-drv-6.9' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl into soc/drivers

elapsed time: 878m

configs tested: 173
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                        nsimosci_defconfig   gcc  
arc                   randconfig-001-20240221   gcc  
arc                   randconfig-002-20240221   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm                   randconfig-001-20240221   clang
arm                   randconfig-002-20240221   clang
arm                   randconfig-003-20240221   gcc  
arm                   randconfig-004-20240221   clang
arm                           stm32_defconfig   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240221   gcc  
arm64                 randconfig-002-20240221   gcc  
arm64                 randconfig-003-20240221   gcc  
arm64                 randconfig-004-20240221   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240221   gcc  
csky                  randconfig-002-20240221   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
hexagon               randconfig-001-20240221   clang
hexagon               randconfig-002-20240221   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-001-20240221   gcc  
i386         buildonly-randconfig-002-20240221   clang
i386         buildonly-randconfig-003-20240221   gcc  
i386         buildonly-randconfig-004-20240221   gcc  
i386         buildonly-randconfig-005-20240221   gcc  
i386         buildonly-randconfig-006-20240221   gcc  
i386                                defconfig   clang
i386                  randconfig-001-20240221   gcc  
i386                  randconfig-002-20240221   clang
i386                  randconfig-003-20240221   clang
i386                  randconfig-004-20240221   gcc  
i386                  randconfig-005-20240221   gcc  
i386                  randconfig-006-20240221   clang
i386                  randconfig-011-20240221   gcc  
i386                  randconfig-012-20240221   clang
i386                  randconfig-013-20240221   gcc  
i386                  randconfig-014-20240221   clang
i386                  randconfig-015-20240221   gcc  
i386                  randconfig-016-20240221   clang
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                        allyesconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240221   gcc  
loongarch             randconfig-002-20240221   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                             allmodconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                       lemote2f_defconfig   gcc  
mips                          malta_defconfig   gcc  
mips                      pic32mzda_defconfig   gcc  
nios2                            alldefconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240221   gcc  
nios2                 randconfig-002-20240221   gcc  
openrisc                         allmodconfig   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
openrisc                  or1klitex_defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                randconfig-001-20240221   gcc  
parisc                randconfig-002-20240221   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc               randconfig-001-20240221   gcc  
powerpc               randconfig-002-20240221   gcc  
powerpc               randconfig-003-20240221   gcc  
powerpc                         wii_defconfig   gcc  
powerpc64             randconfig-001-20240221   gcc  
powerpc64             randconfig-002-20240221   gcc  
powerpc64             randconfig-003-20240221   gcc  
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                 randconfig-001-20240221   clang
riscv                 randconfig-002-20240221   gcc  
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240221   clang
s390                  randconfig-002-20240221   clang
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                    randconfig-001-20240221   gcc  
sh                    randconfig-002-20240221   gcc  
sh                          sdk7780_defconfig   gcc  
sh                        sh7763rdp_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                            allyesconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240221   gcc  
sparc64               randconfig-002-20240221   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                    randconfig-001-20240221   gcc  
um                    randconfig-002-20240221   clang
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-002-20240221   gcc  
x86_64       buildonly-randconfig-003-20240221   gcc  
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240221   gcc  
x86_64                randconfig-002-20240221   gcc  
x86_64                randconfig-003-20240221   gcc  
x86_64                randconfig-004-20240221   gcc  
x86_64                randconfig-005-20240221   gcc  
x86_64                randconfig-006-20240221   gcc  
x86_64                randconfig-012-20240221   gcc  
x86_64                randconfig-014-20240221   gcc  
x86_64                randconfig-015-20240221   gcc  
x86_64                randconfig-016-20240221   gcc  
x86_64                randconfig-071-20240221   gcc  
x86_64                randconfig-072-20240221   gcc  
x86_64                randconfig-073-20240221   gcc  
x86_64                randconfig-074-20240221   gcc  
x86_64                randconfig-076-20240221   gcc  
x86_64                          rhel-8.3-rust   clang
x86_64                               rhel-8.3   gcc  
xtensa                            allnoconfig   gcc  
xtensa                           allyesconfig   gcc  
xtensa                generic_kc705_defconfig   gcc  
xtensa                randconfig-001-20240221   gcc  
xtensa                randconfig-002-20240221   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From rafael at kernel.org  Wed Feb 21 04:04:43 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Wed, 21 Feb 2024 13:04:43 +0100
Subject: [PATCH RFC v4 02/15] ACPI: processor: Register all CPUs from acpi_processor_get_info()
In-Reply-To: <CAJZ5v0i0c3bg8E9yuRk00VAEW5isZ4N-mbnhRuTR8aiFLXo1_A@mail.gmail.com>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk> <E1rVDmU-0027YP-Jz@rmk-PC.armlinux.org.uk>
 <CAJZ5v0iiJpUWq5GMSnKFWQTzn_bdwoQz9m=hDaXNg4Lj_ePF4g@mail.gmail.com>
 <ZdSMk93c1I6x973h@shell.armlinux.org.uk> <ZdTBtt0oR6Q1RcAB@shell.armlinux.org.uk>
 <20240220162406.00005b59@Huawei.com> <CAJZ5v0i0c3bg8E9yuRk00VAEW5isZ4N-mbnhRuTR8aiFLXo1_A@mail.gmail.com>
Message-ID: <CAJZ5v0hu32UCLPO6txptfn1DxCNqdYc+Ls-yNa09LdzhroyddQ@mail.gmail.com>

On Tue, Feb 20, 2024 at 8:59?PM Rafael J. Wysocki <rafael at kernel.org> wrote:
>
> On Tue, Feb 20, 2024 at 5:24?PM Jonathan Cameron
> <Jonathan.Cameron at huawei.com> wrote:
> >
> > On Tue, 20 Feb 2024 15:13:58 +0000
> > "Russell King (Oracle)" <linux at armlinux.org.uk> wrote:
> >
> > > On Tue, Feb 20, 2024 at 11:27:15AM +0000, Russell King (Oracle) wrote:
> > > > On Thu, Feb 15, 2024 at 08:22:29PM +0100, Rafael J. Wysocki wrote:
> > > > > On Wed, Jan 31, 2024 at 5:50?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:
> > > > > > diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> > > > > > index cf7c1cca69dd..a68c475cdea5 100644
> > > > > > --- a/drivers/acpi/acpi_processor.c
> > > > > > +++ b/drivers/acpi/acpi_processor.c
> > > > > > @@ -314,6 +314,18 @@ static int acpi_processor_get_info(struct acpi_device *device)
> > > > > >                         cpufreq_add_device("acpi-cpufreq");
> > > > > >         }
> > > > > >
> > > > > > +       /*
> > > > > > +        * Register CPUs that are present. get_cpu_device() is used to skip
> > > > > > +        * duplicate CPU descriptions from firmware.
> > > > > > +        */
> > > > > > +       if (!invalid_logical_cpuid(pr->id) && cpu_present(pr->id) &&
> > > > > > +           !get_cpu_device(pr->id)) {
> > > > > > +               int ret = arch_register_cpu(pr->id);
> > > > > > +
> > > > > > +               if (ret)
> > > > > > +                       return ret;
> > > > > > +       }
> > > > > > +
> > > > > >         /*
> > > > > >          *  Extra Processor objects may be enumerated on MP systems with
> > > > > >          *  less than the max # of CPUs. They should be ignored _iff
> > > > >
> > > > > This is interesting, because right below there is the following code:
> > > > >
> > > > >     if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
> > > > >         int ret = acpi_processor_hotadd_init(pr);
> > > > >
> > > > >         if (ret)
> > > > >             return ret;
> > > > >     }
> > > > >
> > > > > and acpi_processor_hotadd_init() essentially calls arch_register_cpu()
> > > > > with some extra things around it (more about that below).
> > > > >
> > > > > I do realize that acpi_processor_hotadd_init() is defined under
> > > > > CONFIG_ACPI_HOTPLUG_CPU, so for the sake of the argument let's
> > > > > consider an architecture where CONFIG_ACPI_HOTPLUG_CPU is set.
> > > > >
> > > > > So why are the two conditionals that almost contradict each other both
> > > > > needed?  It looks like the new code could be combined with
> > > > > acpi_processor_hotadd_init() to do the right thing in all cases.
> > > > >
> > > > > Now, acpi_processor_hotadd_init() does some extra things that look
> > > > > like they should be done by the new code too.
> > > > >
> > > > > 1. It checks invalid_phys_cpuid() which appears to be a good idea to me.
> > > > >
> > > > > 2. It uses locking around arch_register_cpu() which doesn't seem
> > > > > unreasonable either.
> > > > >
> > > > > 3. It calls acpi_map_cpu() and I'm not sure why this is not done by
> > > > > the new code.
> > > > >
> > > > > The only thing that can be dropped from it is the _STA check AFAICS,
> > > > > because acpi_processor_add() won't even be called if the CPU is not
> > > > > present (and not enabled after the first patch).
> > > > >
> > > > > So why does the code not do 1 - 3 above?
> > > >
> > > > Honestly, I'm out of my depth with this and can't answer your
> > > > questions - and I really don't want to try fiddling with this code
> > > > because it's just too icky (even in its current form in mainline)
> > > > to be understandable to anyone who hasn't gained a detailed knowledge
> > > > of this code.
> > > >
> > > > It's going to require a lot of analysis - how acpi_map_cpuid() behaves
> > > > in all circumstances, what this means for invalid_logical_cpuid() and
> > > > invalid_phys_cpuid(), what paths will be taken in each case. This code
> > > > is already just too hairy for someone who isn't an experienced ACPI
> > > > hacker to be able to follow and I don't see an obvious way to make it
> > > > more readable.
> > > >
> > > > James' additions make it even more complex and less readable.
> > >
> > > As an illustration of the problems I'm having here, I was just writing
> > > a reply to this with a suggestion of transforming this code ultimately
> > > to:
> > >
> > >       if (!get_cpu_device(pr->id)) {
> > >               int ret;
> > >
> > >               if (!invalid_logical_cpuid(pr->id) && cpu_present(pr->id))
> > >                       ret = acpi_processor_make_enabled(pr);
> > >               else
> > >                       ret = acpi_processor_make_present(pr);
> > >
> > >               if (ret)
> > >                       return ret;
> > >       }
> > >
> > > (acpi_processor_make_present() would be acpi_processor_hotadd_init()
> > > and acpi_processor_make_enabled() would be arch_register_cpu() at this
> > > point.)
> > >
> > > Then I realised that's a bad idea - because we really need to check
> > > that pr->id is valid before calling get_cpu_device() on it, so this
> > > won't work. That leaves us with:
> > >
> > >       int ret;
> > >
> > >       if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
> > >               /* x86 et.al. path */
> > >               ret = acpi_processor_make_present(pr);
> > >       } else if (!get_cpu_device(pr->id)) {
> > >               /* Arm64 path */
> > >               ret = acpi_processor_make_enabled(pr);
> > >       } else {
> > >               ret = 0;
> > >       }
> > >
> > >       if (ret)
> > >               return ret;
> > >
> > > Now, the next transformation would be to move !get_cpu_device(pr->id)
> > > into acpi_processor_make_enabled() which would eliminate one of those
> > > if() legs.
> > >
> > > Now, if we want to somehow make the call to arch_regster_cpu() common
> > > in these two paths, the next question is what are the _precise_
> > > semantics of acpi_map_cpu(), particularly with respect to it
> > > modifying pr->id. Is it guaranteed to always give the same result
> > > for the same processor described in ACPI? What acpi_map_cpu() anyway,
> > > I can find no documentation for it.
> > >
> > > Then there's the question whether calling acpi_unmap_cpu() should be
> > > done on the failure path if arch_register_cpu() fails, which is done
> > > for the x86 path but not the Arm64 path. Should it be done for the
> > > Arm64 path? I've no idea, but as Arm64 doesn't implement either of
> > > these two functions, I guess they could be stubbed out and thus be
> > > no-ops - but then we open a hole where if pr->id is invalid, we
> > > end up passing that invalid value to arch_register_cpu() which I'm
> > > quite sure will explode with a negative CPU number.
> > >
> > > So, to my mind, what you're effectively asking for is a total rewrite
> > > of all the code in and called by acpi_processor_get_info()... and that
> > > is not something I am willing to do (because it's too far outside of
> > > my knowledge area.)
> > >
> > > As I said in my reply to patch 1, I think your comments on patch 2
> > > make Arm64 vcpu hotplug unachievable in a reasonable time frame, and
> > > certainly outside the bounds of what I can do to progress this.
> > >
> > > So, at this point I'm going to stand down from further participation
> > > with this patch set as I believe I've reached the limit of what I can
> > > do to progress it.
> > >
> >
> > Thanks for your hard work on this Russell - we have moved forwards.
> >
> > Short of anyone else stepping up I'll pick this up with
> > the help of some my colleagues. As such I'm keen on getting patch
> > 1 upstream ASAP so that we can exclude the need for some of the
> > other workarounds from earlier versions of this series (the ones
> > dropped before now).
>
> Applied (as 6.9 material).

And I'm going to drop it, because it is not correct.

The problem is that it is going to affect non-processor devices, but
let me comment on that patch itself.


From apatel at ventanamicro.com  Wed Feb 21 04:23:59 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 21 Feb 2024 17:53:59 +0530
Subject: [PATCH v13 06/13] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <874je2yqn9.fsf@all.your.base.are.belong.to.us>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-7-apatel@ventanamicro.com> <87frxnfj3p.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2Xnzg3KAVETXN+ZGLWhVtaJuU4uXs3WH2ZondkBJMHFcA@mail.gmail.com> <874je2yqn9.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAK9=C2WXR49KZg3rstChqAHda+hUhPm3AEo6o2jh0NM3kvoSUA@mail.gmail.com>

On Wed, Feb 21, 2024 at 5:29?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Anup Patel <apatel at ventanamicro.com> writes:
>
> >> > +void imsic_vector_mask(struct imsic_vector *vec)
> >> > +{
> >> > +     struct imsic_local_priv *lpriv;
> >> > +
> >> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> >> > +     if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
> >> > +             return;
> >> > +
> >> > +     /*
> >> > +      * This function is called through Linux irq subsystem with
> >> > +      * irqs disabled so no need to save/restore irq flags.
> >> > +      */
> >> > +
> >> > +     raw_spin_lock(&lpriv->lock);
> >> > +
> >> > +     vec->enable = false;
> >> > +     bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> >> > +     __imsic_remote_sync(lpriv, vec->cpu);
> >> > +
> >> > +     raw_spin_unlock(&lpriv->lock);
> >> > +}
> >>
> >> Really nice that you're using a timer for the vector affinity change,
> >> and got rid of the special/weird IMSIC/sync IPI. Can you really use a
> >> timer for mask/unmask? That makes the mask/unmask operation
> >> asynchronous!
> >>
> >> That was what I was trying to get though with this comment:
> >> https://lore.kernel.org/linux-riscv/87sf24mo1g.fsf at all.your.base.are.belong.to.us/
> >>
> >> Also, using the smp_* IPI functions, you can pass arguments, so you
> >> don't need the dirty_bitmap tracking the changes.
> >
> > The mask/unmask operations are called with irqs disabled so if
> > CPU X does synchronous IPI to another CPU Y from mask/unmask
> > operation then while CPU X is waiting for IPI to complete it cannot
> > receive IPI from other CPUs which can lead to crashes and stalls.
> >
> > In general, we should not do any block/busy-wait work in
> > mask/unmask operation of an irqchip driver.
>
> Hmm, OK. Still, a bit odd that when the .irq_mask callback return, the
> masking is not actually completed.
>
> 1. CPU 0 tries to mask an interrupt tried to CPU 1.
> 2. The timer is queued on CPU 1.
> 3. The call irq_mask returns on CPU 0
> 4. ...the irq is masked at some future point, determined by the callback
>    at CPU 1
>
> Is that the expected outcome?

Yes, that's right.

>
> There are .irq_mask implementation that does seem to go at length
> (blocking) to perform the mask, e.g.: gic_mask_irq() which calls
> gic_{re,}dist_wait_for_rwp that have sleep/retry loops. The GIC3 ITS
> code has similar things going on.

The gic_{re,}dist_wait_for_rwp() polls on a HW register for completion
which will certainly complete in a predictable time whereas waiting
for IPI to be executed by another CPU is not predictable and fragile.

>
> I'm not saying you're wrong, I'm just trying to wrap my head around the
> masking semantics.
>
> > The AIA IMSIC spec allows setting ID pending bit using MSI write
> > irrespective whether ID is enabled or not but the interrupt will be
> > taken only after ID is enabled. In other words, there will be no
> > loss of interrupt with delayed mask/unmask using async IPI or
> > lazy timer.
>
> No loss, but we might *get* an interrupt when we explicitly asked not to
> get any. Maybe that's ok?
>

The delayed spurious interrupt after masking is avoided by additional
masking at the source of interrupt. For wired-to-MSI interrupts, we have
additional masking on the APLIC MSI-mode. For PCI MSI interrupts, we
have additional masking at PCI device level using pci_msi_mask_irq().

Regards,
Anup


From masahiroy at kernel.org  Wed Feb 21 04:37:41 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Wed, 21 Feb 2024 21:37:41 +0900
Subject: [PATCH v10 2/2] arm64: boot: Support Flat Image Tree
In-Reply-To: <20240202173034.221790-3-sjg@chromium.org>
References: <20240202173034.221790-1-sjg@chromium.org> <20240202173034.221790-3-sjg@chromium.org>
Message-ID: <CAK7LNARBC-zPHWDzhkMj90UBVaxHs0PJ9wfUKLRGAHxzBx=Bqg@mail.gmail.com>

On Sat, Feb 3, 2024 at 2:30?AM Simon Glass <sjg at chromium.org> wrote:
>
> Add a script which produces a Flat Image Tree (FIT), a single file
> containing the built kernel and associated devicetree files.
> Compression defaults to gzip which gives a good balance of size and
> performance.
>
> The files compress from about 86MB to 24MB using this approach.
>
> The FIT can be used by bootloaders which support it, such as U-Boot
> and Linuxboot. It permits automatic selection of the correct
> devicetree, matching the compatible string of the running board with
> the closest compatible string in the FIT. There is no need for
> filenames or other workarounds.
>
> Add a 'make image.fit' build target for arm64, as well.
>
> The FIT can be examined using 'dumpimage -l'.
>
> This uses the 'dtbs-list' file but processes only .dtb files, ignoring
> the overlay .dtbo files.
>
> This features requires pylibfdt (use 'pip install libfdt'). It also
> requires compression utilities for the algorithm being used. Supported
> compression options are the same as the Image.xxx files. Use
> FIT_COMPRESSION to select an algorithm other than gzip.
>
> While FIT supports a ramdisk / initrd, no attempt is made to support
> this here, since it must be built separately from the Linux build.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> Changes in v10:
> - Make use of dtbs-list file
> - Mention dtbs-list and FIT_COMPRESSION
> - Update copyright year
> - Update cover letter to take account of an applied patch
>
> Changes in v9:
> - Move the compression control into Makefile.lib
>
> Changes in v8:
> - Drop compatible string in FDT node
> - Correct sorting of MAINTAINERS to before ARM64 PORT
> - Turn compress part of the make_fit.py comment in to a sentence
> - Add two blank lines before parse_args() and setup_fit()
> - Use 'image.fit: dtbs' instead of BUILD_DTBS var
> - Use '$(<D)/dts' instead of '$(dir $<)dts'
> - Add 'mkimage' details Documentation/process/changes.rst
> - Allow changing the compression used
> - Tweak cover letter since there is only one clean-up patch
>
> Changes in v7:
> - Add Image as a dependency of image.fit
> - Drop kbuild tag
> - Add dependency on dtbs
> - Drop unnecessary path separator for dtbs
> - Rebase to -next
>
> Changes in v5:
> - Drop patch previously applied
> - Correct compression rule which was broken in v4
>
> Changes in v4:
> - Use single quotes for UIMAGE_NAME
>
> Changes in v3:
> - Drop temporary file image.itk
> - Drop patch 'Use double quotes for image name'
> - Drop double quotes in use of UIMAGE_NAME
> - Drop unnecessary CONFIG_EFI_ZBOOT condition for help
> - Avoid hard-coding "arm64" for the DT architecture
>
> Changes in v2:
> - Drop patch previously applied
> - Add .gitignore file
> - Move fit rule to Makefile.lib using an intermediate file
> - Drop dependency on CONFIG_EFI_ZBOOT
> - Pick up .dtb files separately from the kernel
> - Correct pylint too-many-args warning for write_kernel()
> - Include the kernel image in the file count
> - Add a pointer to the FIT spec and mention of its wide industry usage
> - Mention the kernel version in the FIT description
>
>  Documentation/process/changes.rst |   9 +
>  MAINTAINERS                       |   7 +
>  arch/arm64/Makefile               |   7 +-
>  arch/arm64/boot/.gitignore        |   1 +
>  arch/arm64/boot/Makefile          |   6 +-
>  scripts/Makefile.lib              |  16 ++
>  scripts/make_fit.py               | 298 ++++++++++++++++++++++++++++++
>  7 files changed, 341 insertions(+), 3 deletions(-)
>  create mode 100755 scripts/make_fit.py
>
> diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
> index 50b3d1cb1115..a8110965e4e1 100644
> --- a/Documentation/process/changes.rst
> +++ b/Documentation/process/changes.rst
> @@ -62,6 +62,7 @@ Sphinx\ [#f1]_         2.4.4            sphinx-build --version
>  cpio                   any              cpio --version
>  GNU tar                1.28             tar --version
>  gtags (optional)       6.6.5            gtags --version
> +mkimage (optional)     2017.01          mkimage --version
>  ====================== ===============  ========================================
>
>  .. [#f1] Sphinx is needed only to build the Kernel documentation
> @@ -189,6 +190,14 @@ The kernel build requires GNU GLOBAL version 6.6.5 or later to generate
>  tag files through ``make gtags``.  This is due to its use of the gtags
>  ``-C (--directory)`` flag.
>
> +mkimage
> +-------
> +
> +This tool is used when building a Flat Image Tree (FIT), commonly used on ARM
> +platforms. The tool is available via the ``u-boot-tools`` package or can be
> +built from the U-Boot source code. See the instructions at
> +https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
> +
>  System utilities
>  ****************
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 61117c3afa80..10c2753d7bcc 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3026,6 +3026,13 @@ F:       drivers/mmc/host/sdhci-of-arasan.c
>  N:     zynq
>  N:     xilinx
>
> +ARM64 FIT SUPPORT
> +M:     Simon Glass <sjg at chromium.org>
> +L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> +S:     Maintained
> +F:     arch/arm64/boot/Makefile
> +F:     scripts/make_fit.py
> +
>  ARM64 PORT (AARCH64 ARCHITECTURE)
>  M:     Catalin Marinas <catalin.marinas at arm.com>
>  M:     Will Deacon <will at kernel.org>
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index 83cd2b7234b9..5de2b02f549a 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -150,7 +150,7 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
>  # Default target when executing plain make
>  boot           := arch/arm64/boot
>
> -BOOT_TARGETS   := Image vmlinuz.efi
> +BOOT_TARGETS   := Image vmlinuz.efi image.fit
>
>  PHONY += $(BOOT_TARGETS)
>
> @@ -162,7 +162,9 @@ endif
>
>  all:   $(notdir $(KBUILD_IMAGE))
>
> -vmlinuz.efi: Image
> +image.fit: dtbs
> +
> +vmlinuz.efi image.fit: Image
>  $(BOOT_TARGETS): vmlinux
>         $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
>
> @@ -215,6 +217,7 @@ virtconfig:
>  define archhelp
>    echo  '* Image.gz      - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
>    echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
> +  echo  '  image.fit     - Flat Image Tree (arch/$(ARCH)/boot/image.fit)'
>    echo  '  install       - Install uncompressed kernel'
>    echo  '  zinstall      - Install compressed kernel'
>    echo  '                  Install using (your) ~/bin/installkernel or'
> diff --git a/arch/arm64/boot/.gitignore b/arch/arm64/boot/.gitignore
> index af5dc61f8b43..abaae9de1bdd 100644
> --- a/arch/arm64/boot/.gitignore
> +++ b/arch/arm64/boot/.gitignore
> @@ -2,3 +2,4 @@
>  Image
>  Image.gz
>  vmlinuz*
> +image.fit
> diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
> index a5a787371117..ab21af82913e 100644
> --- a/arch/arm64/boot/Makefile
> +++ b/arch/arm64/boot/Makefile
> @@ -16,7 +16,8 @@
>
>  OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
>
> -targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo Image.zst
> +targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo \
> +       Image.zst image.fit
>
>  $(obj)/Image: vmlinux FORCE
>         $(call if_changed,objcopy)
> @@ -39,6 +40,9 @@ $(obj)/Image.lzo: $(obj)/Image FORCE
>  $(obj)/Image.zst: $(obj)/Image FORCE
>         $(call if_changed,zstd)
>
> +$(obj)/image.fit: $(obj)/Image FORCE
> +       $(call cmd,fit)



The point for using dtbs-list is
to avoid rebuilding image.fit needlessly.


This should be:

$(obj)/image.fit: $(obj)/Image $(obj)/dts/dtbs-list FORCE
        $(call if_changed,fit)





> +
>  EFI_ZBOOT_PAYLOAD      := Image
>  EFI_ZBOOT_BFD_TARGET   := elf64-littleaarch64
>  EFI_ZBOOT_MACH_TYPE    := ARM64
> diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
> index b35d39022a30..4efb5ad07fd7 100644
> --- a/scripts/Makefile.lib
> +++ b/scripts/Makefile.lib
> @@ -502,6 +502,22 @@ quiet_cmd_uimage = UIMAGE  $@
>                         -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \
>                         -n '$(UIMAGE_NAME)' -d $< $@
>
> +# Flat Image Tree (FIT)
> +# This allows for packaging of a kernel and all devicetrees files, using
> +# compression.
> +# ---------------------------------------------------------------------------
> +
> +MAKE_FIT := $(srctree)/scripts/make_fit.py
> +
> +# Use this to override the compression algorithm
> +FIT_COMPRESSION ?= gzip
> +
> +quiet_cmd_fit = FIT     $@
> +      cmd_fit = $(MAKE_FIT) -f $@ --arch $(UIMAGE_ARCH) --os linux \
> +                       --name '$(UIMAGE_NAME)' \
> +                       --compress $(FIT_COMPRESSION) -k $< \
> +                       @arch/$(SRCARCH)/boot/dts/dtbs-list




cmd_fit = $(MAKE_FIT) -f $@ --arch $(UIMAGE_ARCH) --os linux \
                --name '$(UIMAGE_NAME)' \
                --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^)





> +
>  # XZ
>  # ---------------------------------------------------------------------------
>  # Use xzkern to compress the kernel image and xzmisc to compress other things.
> diff --git a/scripts/make_fit.py b/scripts/make_fit.py
> new file mode 100755
> index 000000000000..69eee32960ae
> --- /dev/null
> +++ b/scripts/make_fit.py
> @@ -0,0 +1,298 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +# Copyright 2024 Google LLC
> +# Written by Simon Glass <sjg at chromium.org>
> +#
> +
> +"""Build a FIT containing a lot of devicetree files
> +
> +Usage:
> +    make_fit.py -A arm64 -n 'Linux-6.6' -O linux
> +        -f arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk
> +        @arch/arm64/boot/dts/dtbs-list -E -c gzip
> +
> +Creates a FIT containing the supplied kernel and a set of devicetree files,
> +either specified individually or listed in a file (with an '@' prefix). Files
> +which don't end in '.dtb' are silently ignored.


Why do you need to check the suffix?



> +
> +Use -E to generate an external FIT (where the data is placed after the
> +FIT data structure). This allows parsing of the data without loading
> +the entire FIT.
> +
> +Use -c to compress the data, using bzip2, gzip, lz4, lzma, lzo and
> +zstd algorithms.
> +
> +The resulting FIT can be booted by bootloaders which support FIT, such
> +as U-Boot, Linuxboot, Tianocore, etc.
> +
> +Note that this tool does not yet support adding a ramdisk / initrd.
> +"""
> +
> +import argparse
> +import collections
> +import os
> +import subprocess
> +import sys
> +import tempfile
> +import time
> +
> +import libfdt
> +
> +
> +# Tool extension and the name of the command-line tools
> +CompTool = collections.namedtuple('CompTool', 'ext,tools')
> +
> +COMP_TOOLS = {
> +    'bzip2': CompTool('.bz2', 'bzip2'),
> +    'gzip': CompTool('.gz', 'pigz,gzip'),
> +    'lz4': CompTool('.lz4', 'lz4'),
> +    'lzma': CompTool('.lzma', 'lzma'),
> +    'lzo': CompTool('.lzo', 'lzop'),
> +    'zstd': CompTool('.zstd', 'zstd'),
> +}
> +
> +
> +def parse_args():
> +    """Parse the program ArgumentParser
> +
> +    Returns:
> +        Namespace object containing the arguments
> +    """
> +    epilog = 'Build a FIT from a directory tree containing .dtb files'
> +    parser = argparse.ArgumentParser(epilog=epilog)
> +    parser.add_argument('-A', '--arch', type=str, required=True,
> +          help='Specifies the architecture')
> +    parser.add_argument('-c', '--compress', type=str, default='none',
> +          help='Specifies the compression')
> +    parser.add_argument('-E', '--external', action='store_true',
> +          help='Convert the FIT to use external data')
> +    parser.add_argument('-n', '--name', type=str, required=True,
> +          help='Specifies the name')
> +    parser.add_argument('-O', '--os', type=str, required=True,
> +          help='Specifies the operating system')
> +    parser.add_argument('-f', '--fit', type=str, required=True,
> +          help='Specifies the output file (.fit)')



I like -o (--output) to specify the output file.



    parser.add_argument('-o', '--output', type=str, required=True,
             help='Specifies the output file (.fit)')





> +    parser.add_argument('-k', '--kernel', type=str, required=True,
> +          help='Specifies the (uncompressed) kernel input file (.itk)')
> +    parser.add_argument('srcdir', type=str, nargs='*',
> +          help='Specifies the directory tree that contains .dtb files')


srcdir?

You changed the positional parameters to take dtb files.






> +
> +    return parser.parse_args()
> +
> +
> +def setup_fit(fsw, name):
> +    """Make a start on writing the FIT
> +
> +    Outputs the root properties and the 'images' node
> +
> +    Args:
> +        fsw (libfdt.FdtSw): Object to use for writing
> +        name (str): Name of kernel image
> +    """
> +    fsw.INC_SIZE = 65536
> +    fsw.finish_reservemap()
> +    fsw.begin_node('')
> +    fsw.property_string('description', f'{name} with devicetree set')
> +    fsw.property_u32('#address-cells', 1)
> +
> +    fsw.property_u32('timestamp', int(time.time()))
> +    fsw.begin_node('images')
> +
> +
> +def write_kernel(fsw, data, args):
> +    """Write out the kernel image
> +
> +    Writes a kernel node along with the required properties
> +
> +    Args:
> +        fsw (libfdt.FdtSw): Object to use for writing
> +        data (bytes): Data to write (possibly compressed)
> +        args (Namespace): Contains necessary strings:
> +            arch: FIT architecture, e.g. 'arm64'
> +            fit_os: Operating Systems, e.g. 'linux'
> +            name: Name of OS, e.g. 'Linux-6.6.0-rc7'
> +            compress: Compression algorithm to use, e.g. 'gzip'
> +    """
> +    with fsw.add_node('kernel'):
> +        fsw.property_string('description', args.name)
> +        fsw.property_string('type', 'kernel_noload')
> +        fsw.property_string('arch', args.arch)
> +        fsw.property_string('os', args.os)
> +        fsw.property_string('compression', args.compress)
> +        fsw.property('data', data)
> +        fsw.property_u32('load', 0)
> +        fsw.property_u32('entry', 0)
> +
> +
> +def finish_fit(fsw, entries):
> +    """Finish the FIT ready for use
> +
> +    Writes the /configurations node and subnodes
> +
> +    Args:
> +        fsw (libfdt.FdtSw): Object to use for writing
> +        entries (list of tuple): List of configurations:
> +            str: Description of model
> +            str: Compatible stringlist
> +    """
> +    fsw.end_node()
> +    seq = 0
> +    with fsw.add_node('configurations'):
> +        for model, compat in entries:
> +            seq += 1
> +            with fsw.add_node(f'conf-{seq}'):
> +                fsw.property('compatible', bytes(compat))
> +                fsw.property_string('description', model)
> +                fsw.property_string('fdt', f'fdt-{seq}')
> +                fsw.property_string('kernel', 'kernel')
> +    fsw.end_node()
> +
> +
> +def compress_data(inf, compress):
> +    """Compress data using a selected algorithm
> +
> +    Args:
> +        inf (IOBase): Filename containing the data to compress
> +        compress (str): Compression algorithm, e.g. 'gzip'
> +
> +    Return:
> +        bytes: Compressed data
> +    """
> +    if compress == 'none':
> +        return inf.read()
> +
> +    comp = COMP_TOOLS.get(compress)
> +    if not comp:
> +        raise ValueError(f"Unknown compression algorithm '{compress}'")
> +
> +    with tempfile.NamedTemporaryFile() as comp_fname:
> +        with open(comp_fname.name, 'wb') as outf:
> +            done = False
> +            for tool in comp.tools.split(','):
> +                try:
> +                    subprocess.call([tool, '-c'], stdin=inf, stdout=outf)
> +                    done = True
> +                    break
> +                except FileNotFoundError:
> +                    pass
> +            if not done:
> +                raise ValueError(f'Missing tool(s): {comp.tools}\n')
> +            with open(comp_fname.name, 'rb') as compf:
> +                comp_data = compf.read()
> +    return comp_data
> +
> +
> +def output_dtb(fsw, seq, fname, arch, compress):
> +    """Write out a single devicetree to the FIT
> +
> +    Args:
> +        fsw (libfdt.FdtSw): Object to use for writing
> +        seq (int): Sequence number (1 for first)
> +        fmame (str): Filename containing the DTB
> +        arch: FIT architecture, e.g. 'arm64'
> +        compress (str): Compressed algorithm, e.g. 'gzip'
> +
> +    Returns:
> +        tuple:
> +            str: Model name
> +            bytes: Compatible stringlist
> +    """
> +    with fsw.add_node(f'fdt-{seq}'):
> +        # Get the compatible / model information
> +        with open(fname, 'rb') as inf:
> +            data = inf.read()
> +        fdt = libfdt.FdtRo(data)
> +        model = fdt.getprop(0, 'model').as_str()
> +        compat = fdt.getprop(0, 'compatible')
> +
> +        fsw.property_string('description', model)
> +        fsw.property_string('type', 'flat_dt')
> +        fsw.property_string('arch', arch)
> +        fsw.property_string('compression', compress)
> +        fsw.property('compatible', bytes(compat))
> +
> +        with open(fname, 'rb') as inf:
> +            compressed = compress_data(inf, compress)
> +        fsw.property('data', compressed)
> +    return model, compat
> +
> +
> +def build_fit(args):
> +    """Build the FIT from the provided files and arguments
> +
> +    Args:
> +        args (Namespace): Program arguments
> +
> +    Returns:
> +        tuple:
> +            bytes: FIT data
> +            int: Number of configurations generated
> +            size: Total uncompressed size of data
> +    """
> +    def add_file(fname):
> +        nonlocal seq, size
> +
> +        if os.path.splitext(fname)[1] == '.dtb':
> +            seq += 1
> +            size += os.path.getsize(fname)
> +            model, compat = output_dtb(fsw, seq, fname, args.arch,
> +                                       args.compress)
> +            entries.append([model, compat])
> +            return True
> +
> +    seq = 0
> +    size = 0
> +    fsw = libfdt.FdtSw()
> +    setup_fit(fsw, args.name)
> +    entries = []
> +
> +    # Handle the kernel
> +    with open(args.kernel, 'rb') as inf:
> +        comp_data = compress_data(inf, args.compress)
> +    size += os.path.getsize(args.kernel)
> +    write_kernel(fsw, comp_data, args)
> +
> +    for path in args.srcdir:
> +        # Handle a list of devicetree files
> +        if path.startswith('@'):
> +            with open(path[1:], 'r', encoding='utf-8') as inf:
> +                for fname in inf.read().splitlines():
> +                    add_file(fname)




You missed the point of my suggestion.


I did not mean the "@file" syntax
specifically for containing the device trees.


It is common for tools to support the "@file" syntax
to avoid "Argument list too long" error.



See "man ar", "man ld", etc. for example.


 @file
   Read command?line options from file. The options read are inserted in
   place of the original @file option. If file does not exist, or cannot
   be read, then the option will be treated literally, and not removed.




It must be generic enough to contain any command line parameters.


And, you do not even implement it yourself because
it is just a matter of adding fromfile_prefix_chars='@'


See the document.

  https://docs.python.org/3/library/argparse.html#fromfile-prefix-chars





> +        else:
> +            add_file(path)
> +
> +    finish_fit(fsw, entries)
> +
> +    # Include the kernel itself in the returned file count
> +    return fsw.as_fdt().as_bytearray(), seq + 1, size
> +
> +
> +def run_make_fit():
> +    """Run the tool's main logic"""
> +    args = parse_args()
> +
> +    out_data, count, size = build_fit(args)
> +    with open(args.fit, 'wb') as outf:
> +        outf.write(out_data)
> +
> +    ext_fit_size = None
> +    if args.external:
> +        mkimage = os.environ.get('MKIMAGE', 'mkimage')
> +        subprocess.check_call([mkimage, '-E', '-F', args.fit],
> +                              stdout=subprocess.DEVNULL)
> +
> +        with open(args.fit, 'rb') as inf:
> +            data = inf.read()
> +        ext_fit = libfdt.FdtRo(data)
> +        ext_fit_size = ext_fit.totalsize()



I still do not understand why mkimage is needed.


When external data is used, you can insert "data-size"
and "data-offset" to the dt structure,
and at the same time, concatenate the payload data.
Finally, you can combine the two.
Is it complex to implement?






> +
> +    comp_size = len(out_data)
> +    print(f'FIT size {comp_size:#x}/{comp_size / 1024 / 1024:.1f} MB', end='')
> +    if ext_fit_size:
> +        print(f', header {ext_fit_size:#x}/{ext_fit_size / 1024:.1f} KB', end='')
> +    print(f', {count} files, uncompressed {size / 1024 / 1024:.1f} MB')


Maybe, you can print this only when args.verbose == True ?







At last, I still do not know how to distinguish the nodes
when the compatible strings are the same.





> +
> +if __name__ == "__main__":
> +    sys.exit(run_make_fit())
> --
> 2.34.1
>


--
Best Regards


Masahiro Yamada


From lkp at intel.com  Wed Feb 21 04:39:46 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 21 Feb 2024 20:39:46 +0800
Subject: [soc:for-next] BUILD SUCCESS
 37156e9b997483f1d08db52ef298b9878394eef0
Message-ID: <202402212043.JJ2cc2sZ-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: 37156e9b997483f1d08db52ef298b9878394eef0  soc: document merges

elapsed time: 915m

configs tested: 173
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                        nsimosci_defconfig   gcc  
arc                   randconfig-001-20240221   gcc  
arc                   randconfig-002-20240221   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm                   randconfig-001-20240221   clang
arm                   randconfig-002-20240221   clang
arm                   randconfig-003-20240221   gcc  
arm                   randconfig-004-20240221   clang
arm                           stm32_defconfig   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240221   gcc  
arm64                 randconfig-002-20240221   gcc  
arm64                 randconfig-003-20240221   gcc  
arm64                 randconfig-004-20240221   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240221   gcc  
csky                  randconfig-002-20240221   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
hexagon               randconfig-001-20240221   clang
hexagon               randconfig-002-20240221   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-001-20240221   gcc  
i386         buildonly-randconfig-002-20240221   clang
i386         buildonly-randconfig-003-20240221   gcc  
i386         buildonly-randconfig-004-20240221   gcc  
i386         buildonly-randconfig-005-20240221   gcc  
i386         buildonly-randconfig-006-20240221   gcc  
i386                                defconfig   clang
i386                  randconfig-001-20240221   gcc  
i386                  randconfig-002-20240221   clang
i386                  randconfig-003-20240221   clang
i386                  randconfig-004-20240221   gcc  
i386                  randconfig-005-20240221   gcc  
i386                  randconfig-006-20240221   clang
i386                  randconfig-011-20240221   gcc  
i386                  randconfig-012-20240221   clang
i386                  randconfig-013-20240221   gcc  
i386                  randconfig-014-20240221   clang
i386                  randconfig-015-20240221   gcc  
i386                  randconfig-016-20240221   clang
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                        allyesconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240221   gcc  
loongarch             randconfig-002-20240221   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                             allmodconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                       lemote2f_defconfig   gcc  
mips                          malta_defconfig   gcc  
mips                      pic32mzda_defconfig   gcc  
nios2                            alldefconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240221   gcc  
nios2                 randconfig-002-20240221   gcc  
openrisc                         allmodconfig   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
openrisc                  or1klitex_defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                randconfig-001-20240221   gcc  
parisc                randconfig-002-20240221   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc               randconfig-001-20240221   gcc  
powerpc               randconfig-002-20240221   gcc  
powerpc               randconfig-003-20240221   gcc  
powerpc                         wii_defconfig   gcc  
powerpc64             randconfig-001-20240221   gcc  
powerpc64             randconfig-002-20240221   gcc  
powerpc64             randconfig-003-20240221   gcc  
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                 randconfig-001-20240221   clang
riscv                 randconfig-002-20240221   gcc  
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240221   clang
s390                  randconfig-002-20240221   clang
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                    randconfig-001-20240221   gcc  
sh                    randconfig-002-20240221   gcc  
sh                          sdk7780_defconfig   gcc  
sh                        sh7763rdp_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                            allyesconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240221   gcc  
sparc64               randconfig-002-20240221   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                    randconfig-001-20240221   gcc  
um                    randconfig-002-20240221   clang
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-002-20240221   gcc  
x86_64       buildonly-randconfig-003-20240221   gcc  
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240221   gcc  
x86_64                randconfig-002-20240221   gcc  
x86_64                randconfig-003-20240221   gcc  
x86_64                randconfig-004-20240221   gcc  
x86_64                randconfig-005-20240221   gcc  
x86_64                randconfig-006-20240221   gcc  
x86_64                randconfig-012-20240221   gcc  
x86_64                randconfig-014-20240221   gcc  
x86_64                randconfig-015-20240221   gcc  
x86_64                randconfig-016-20240221   gcc  
x86_64                randconfig-071-20240221   gcc  
x86_64                randconfig-072-20240221   gcc  
x86_64                randconfig-073-20240221   gcc  
x86_64                randconfig-074-20240221   gcc  
x86_64                randconfig-076-20240221   gcc  
x86_64                          rhel-8.3-rust   clang
x86_64                               rhel-8.3   gcc  
xtensa                            allnoconfig   gcc  
xtensa                           allyesconfig   gcc  
xtensa                generic_kc705_defconfig   gcc  
xtensa                randconfig-001-20240221   gcc  
xtensa                randconfig-002-20240221   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From Jason at zx2c4.com  Wed Feb 21 04:44:15 2024
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 21 Feb 2024 13:44:15 +0100
Subject: [RFC] arm64: syscall: Direct PRNG kstack randomization
In-Reply-To: <202402202226.A6817927@keescook>
References: <20240221020258.1210148-1-jeremy.linton@arm.com> <202402202226.A6817927@keescook>
Message-ID: <CAHmME9pYS=YZM1b0ftrjj_qjz_U4V8PsiLzB15JmBRr39Av2Ng@mail.gmail.com>

Hi,

On Wed, Feb 21, 2024 at 7:33?AM Kees Cook <keescook at chromium.org> wrote:
> > +#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
> > +DEFINE_PER_CPU(u32, kstackrng);
> > +static u32 xorshift32(u32 state)
> > +{
> > +     /*
> > +      * From top of page 4 of Marsaglia, "Xorshift RNGs"
> > +      * This algorithm is intended to have a period 2^32 -1
> > +      * And should not be used anywhere else outside of this
> > +      * code path.
> > +      */
> > +     state ^= state << 13;
> > +     state ^= state >> 17;
> > +     state ^= state << 5;
> > +     return state;
> > +}

Can we please *not* introduce yet another RNG? You can't just sprinkle
this stuff all over the place with no rhyme or reason.

If you need repeatable randomness, use prandom_u32_state() or similar.
If you need non-repeatable randomness, use get_random_bytes() or
similar.

If you think prandom_u32_state() is insufficient for some reason or
doesn't have some property or performance that you want, submit a
patch to make it better.

Looking at the actual intention here, of using repeatable randomness,
I find the intent pretty weird. Isn't the whole point of kstack
randomization that you can't predict it? If so, get_random_u*() is
what you want. If performance isn't sufficient, let's figure out some
way to improve performance. And as Kees said, if the point of this is
to have some repeatable benchmarks, maybe just don't enable the
security-intended code whose purpose is non-determinism? Both exploits
and now apparently benchmarks like determinism.

Jason


From devnull+forbidden405.outlook.com at kernel.org  Wed Feb 21 04:45:03 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Wed, 21 Feb 2024 20:45:03 +0800
Subject: [PATCH v6 1/5] mmc: host: mmc_of_parse_clk_phase(): Pass struct
 device * instead of mmc_host *
In-Reply-To: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>
References: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>
Message-ID: <20240221-b4-mmc-hi3798mv200-v6-1-bc41bf6a9769@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

Parsing dt usually happens very early, sometimes even before struct
mmc_host is allocated (e.g. dw_mci_probe() and dw_mci_parse_dt() in
dw_mmc.c). Looking at the source of mmc_of_parse_clk_phase(), it's
actually not mandatory to have an initialized mmc_host first, instead we
can pass struct device * to it directly.

Also fix the only current user (sdhci-of-aspeed.c).

Reviewed-by: Paul Menzel <pmenzel at molgen.mpg.de>
Acked-by: Andrew Jeffery <andrew at codeconstruct.com.au>
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 drivers/mmc/core/host.c            | 4 +---
 drivers/mmc/host/sdhci-of-aspeed.c | 2 +-
 include/linux/mmc/host.h           | 2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index cf396e8f34e9..8b2844ac5dc5 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -234,10 +234,8 @@ static void mmc_of_parse_timing_phase(struct device *dev, const char *prop,
 }
 
 void
-mmc_of_parse_clk_phase(struct mmc_host *host, struct mmc_clk_phase_map *map)
+mmc_of_parse_clk_phase(struct device *dev, struct mmc_clk_phase_map *map)
 {
-	struct device *dev = host->parent;
-
 	mmc_of_parse_timing_phase(dev, "clk-phase-legacy",
 				  &map->phase[MMC_TIMING_LEGACY]);
 	mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs",
diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
index 42d54532cabe..430c1f90037b 100644
--- a/drivers/mmc/host/sdhci-of-aspeed.c
+++ b/drivers/mmc/host/sdhci-of-aspeed.c
@@ -435,7 +435,7 @@ static int aspeed_sdhci_probe(struct platform_device *pdev)
 		goto err_sdhci_add;
 
 	if (dev->phase_desc)
-		mmc_of_parse_clk_phase(host->mmc, &dev->phase_map);
+		mmc_of_parse_clk_phase(&pdev->dev, &dev->phase_map);
 
 	ret = sdhci_add_host(host);
 	if (ret)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 2f445c651742..5894bf912f7b 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -539,7 +539,7 @@ struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra);
 int mmc_add_host(struct mmc_host *);
 void mmc_remove_host(struct mmc_host *);
 void mmc_free_host(struct mmc_host *);
-void mmc_of_parse_clk_phase(struct mmc_host *host,
+void mmc_of_parse_clk_phase(struct device *dev,
 			    struct mmc_clk_phase_map *map);
 int mmc_of_parse(struct mmc_host *host);
 int mmc_of_parse_voltage(struct mmc_host *host, u32 *mask);

-- 
2.43.0



From devnull+forbidden405.outlook.com at kernel.org  Wed Feb 21 04:45:05 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Wed, 21 Feb 2024 20:45:05 +0800
Subject: [PATCH v6 3/5] mmc: dw_mmc: add support for hi3798mv200
In-Reply-To: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>
References: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>
Message-ID: <20240221-b4-mmc-hi3798mv200-v6-3-bc41bf6a9769@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

Add support for Hi3798MV200 specific extension.

Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 drivers/mmc/host/Kconfig              |   9 ++
 drivers/mmc/host/Makefile             |   1 +
 drivers/mmc/host/dw_mmc-hi3798mv200.c | 239 ++++++++++++++++++++++++++++++++++
 3 files changed, 249 insertions(+)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 81f2c4e05287..aebc587f77a7 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -798,6 +798,15 @@ config MMC_DW_HI3798CV200
 	  Synopsys DesignWare Memory Card Interface driver. Select this option
 	  for platforms based on HiSilicon Hi3798CV200 SoC.
 
+config MMC_DW_HI3798MV200
+	tristate "Hi3798MV200 specific extensions for Synopsys DW Memory Card Interface"
+	depends on MMC_DW
+	select MMC_DW_PLTFM
+	help
+	  This selects support for HiSilicon Hi3798MV200 SoC specific extensions to the
+	  Synopsys DesignWare Memory Card Interface driver. Select this option
+	  for platforms based on HiSilicon Hi3798MV200 SoC.
+
 config MMC_DW_K3
 	tristate "K3 specific extensions for Synopsys DW Memory Card Interface"
 	depends on MMC_DW
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index d0be4465f3ec..f53f86d200ac 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_MMC_DW_PLTFM)	+= dw_mmc-pltfm.o
 obj-$(CONFIG_MMC_DW_BLUEFIELD)	+= dw_mmc-bluefield.o
 obj-$(CONFIG_MMC_DW_EXYNOS)	+= dw_mmc-exynos.o
 obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o
+obj-$(CONFIG_MMC_DW_HI3798MV200) += dw_mmc-hi3798mv200.o
 obj-$(CONFIG_MMC_DW_K3)		+= dw_mmc-k3.o
 obj-$(CONFIG_MMC_DW_PCI)	+= dw_mmc-pci.o
 obj-$(CONFIG_MMC_DW_ROCKCHIP)	+= dw_mmc-rockchip.o
diff --git a/drivers/mmc/host/dw_mmc-hi3798mv200.c b/drivers/mmc/host/dw_mmc-hi3798mv200.c
new file mode 100644
index 000000000000..73aaa21040ea
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-hi3798mv200.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Modified from dw_mmc-hi3798cv200.c
+ *
+ * Copyright (c) 2024 Yang Xiwen <forbidden405 at outlook.com>
+ * Copyright (c) 2018 HiSilicon Technologies Co., Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mmc/host.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "dw_mmc.h"
+#include "dw_mmc-pltfm.h"
+
+#define SDMMC_TUNING_CTRL	0x118
+#define SDMMC_TUNING_FIND_EDGE	BIT(5)
+
+#define ALL_INT_CLR		0x1ffff
+
+/* DLL ctrl reg */
+#define SAP_DLL_CTRL_DLLMODE	BIT(16)
+
+struct dw_mci_hi3798mv200_priv {
+	struct clk *sample_clk;
+	struct clk *drive_clk;
+	struct regmap *crg_reg;
+	u32 sap_dll_offset;
+	struct mmc_clk_phase_map phase_map;
+};
+
+static void dw_mci_hi3798mv200_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	struct dw_mci_hi3798mv200_priv *priv = host->priv;
+	struct mmc_clk_phase phase = priv->phase_map.phase[ios->timing];
+	u32 val;
+
+	val = mci_readl(host, ENABLE_SHIFT);
+	if (ios->timing == MMC_TIMING_MMC_DDR52
+	    || ios->timing == MMC_TIMING_UHS_DDR50)
+		val |= SDMMC_ENABLE_PHASE;
+	else
+		val &= ~SDMMC_ENABLE_PHASE;
+	mci_writel(host, ENABLE_SHIFT, val);
+
+	val = mci_readl(host, DDR_REG);
+	if (ios->timing == MMC_TIMING_MMC_HS400)
+		val |= SDMMC_DDR_HS400;
+	else
+		val &= ~SDMMC_DDR_HS400;
+	mci_writel(host, DDR_REG, val);
+
+	if (clk_set_rate(host->ciu_clk, ios->clock))
+		dev_warn(host->dev, "Failed to set rate to %u\n", ios->clock);
+	else
+		// CLK_MUX_ROUND_NEAREST is enabled for this clock
+		// The actual clock rate is not what we setted, but a rounded value
+		// so we should get the rate once again
+		host->bus_hz = clk_get_rate(host->ciu_clk);
+
+	if (phase.valid) {
+		clk_set_phase(priv->drive_clk, phase.out_deg);
+		clk_set_phase(priv->sample_clk, phase.in_deg);
+	} else {
+		dev_warn(host->dev,
+			 "The phase entry for timing mode %d is missing in device tree.\n",
+			 ios->timing);
+	}
+}
+
+static inline int dw_mci_hi3798mv200_enable_tuning(struct dw_mci_slot *slot)
+{
+	struct dw_mci_hi3798mv200_priv *priv = slot->host->priv;
+
+	return regmap_clear_bits(priv->crg_reg, priv->sap_dll_offset, SAP_DLL_CTRL_DLLMODE);
+}
+
+static inline int dw_mci_hi3798mv200_disable_tuning(struct dw_mci_slot *slot)
+{
+	struct dw_mci_hi3798mv200_priv *priv = slot->host->priv;
+
+	return regmap_set_bits(priv->crg_reg, priv->sap_dll_offset, SAP_DLL_CTRL_DLLMODE);
+}
+
+static int dw_mci_hi3798mv200_execute_tuning_mix_mode(struct dw_mci_slot *slot,
+					     u32 opcode)
+{
+	static const int degrees[] = { 0, 45, 90, 135, 180, 225, 270, 315 };
+	struct dw_mci *host = slot->host;
+	struct dw_mci_hi3798mv200_priv *priv = host->priv;
+	int raise_point = -1, fall_point = -1;
+	int err, prev_err = -1;
+	int found = 0;
+	int regval;
+	int i;
+	int ret;
+
+	// enable tuning
+	ret = dw_mci_hi3798mv200_enable_tuning(slot);
+	if (ret < 0)
+		return ret;
+	for (i = 0; i < ARRAY_SIZE(degrees); i++) {
+		clk_set_phase(priv->sample_clk, degrees[i]);
+		mci_writel(host, RINTSTS, ALL_INT_CLR);
+
+		err = mmc_send_tuning(slot->mmc, opcode, NULL);
+		if (!err) {
+			regval = mci_readl(host, TUNING_CTRL);
+			if (regval & SDMMC_TUNING_FIND_EDGE)
+				err = 1;
+			else
+				found = 1;
+		};
+
+		if (i > 0) {
+			if (err && !prev_err)
+				fall_point = i - 1;
+			if (!err && prev_err)
+				raise_point = i;
+		}
+
+		if (raise_point != -1 && fall_point != -1)
+			goto tuning_out;
+
+		prev_err = err;
+		err = 0;
+	}
+
+tuning_out:
+	ret = dw_mci_hi3798mv200_disable_tuning(slot);
+	if (ret < 0)
+		return ret;
+	if (found) {
+		if (raise_point == -1)
+			raise_point = 0;
+		if (fall_point == -1)
+			fall_point = ARRAY_SIZE(degrees) - 1;
+		if (fall_point < raise_point) {
+			if ((raise_point + fall_point) >
+			    (ARRAY_SIZE(degrees) - 1))
+				i = fall_point / 2;
+			else
+				i = (raise_point + ARRAY_SIZE(degrees) - 1) / 2;
+		} else {
+			i = (raise_point + fall_point) / 2;
+		}
+
+		// use the same phase table for both HS200 and HS400
+		priv->phase_map.phase[MMC_TIMING_MMC_HS200].in_deg = degrees[i];
+		priv->phase_map.phase[MMC_TIMING_MMC_HS400].in_deg = degrees[i];
+
+		clk_set_phase(priv->sample_clk, degrees[i]);
+		dev_dbg(host->dev, "Tuning clk_sample[%d, %d], set[%d]\n",
+			raise_point, fall_point, degrees[i]);
+		err = 0;
+	} else {
+		dev_err(host->dev, "No valid clk_sample shift! use default\n");
+		err = -EINVAL;
+	}
+
+	mci_writel(host, RINTSTS, ALL_INT_CLR);
+	return err;
+}
+
+static int dw_mci_hi3798mv200_init(struct dw_mci *host)
+{
+	struct dw_mci_hi3798mv200_priv *priv;
+	struct device_node *np = host->dev->of_node;
+	int ret;
+
+	priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	mmc_of_parse_clk_phase(host->dev, &priv->phase_map);
+
+	priv->sample_clk = devm_clk_get_enabled(host->dev, "ciu-sample");
+	if (IS_ERR(priv->sample_clk))
+		return dev_err_probe(host->dev, PTR_ERR(priv->sample_clk),
+				     "failed to get enabled ciu-sample clock\n");
+
+	priv->drive_clk = devm_clk_get_enabled(host->dev, "ciu-drive");
+	if (IS_ERR(priv->drive_clk))
+		return dev_err_probe(host->dev, PTR_ERR(priv->drive_clk),
+				     "failed to get enabled ciu-drive clock\n");
+
+	priv->crg_reg = syscon_regmap_lookup_by_phandle(np, "hisilicon,sap-dll-reg");
+	if (IS_ERR(priv->crg_reg))
+		return dev_err_probe(host->dev, PTR_ERR(priv->crg_reg),
+				     "failed to get CRG reg\n");
+
+	ret = of_property_read_u32_index(np, "hisilicon,sap-dll-reg", 1, &priv->sap_dll_offset);
+	if (ret)
+		return dev_err_probe(host->dev, ret, "failed to get sample DLL register offset\n");
+
+	host->priv = priv;
+	return 0;
+}
+
+static const struct dw_mci_drv_data hi3798mv200_data = {
+	.common_caps = MMC_CAP_CMD23,
+	.init = dw_mci_hi3798mv200_init,
+	.set_ios = dw_mci_hi3798mv200_set_ios,
+	.execute_tuning = dw_mci_hi3798mv200_execute_tuning_mix_mode,
+};
+
+static const struct of_device_id dw_mci_hi3798mv200_match[] = {
+	{ .compatible = "hisilicon,hi3798mv200-dw-mshc" },
+	{},
+};
+
+static int dw_mci_hi3798mv200_probe(struct platform_device *pdev)
+{
+	return dw_mci_pltfm_register(pdev, &hi3798mv200_data);
+}
+
+static void dw_mci_hi3798mv200_remove(struct platform_device *pdev)
+{
+	dw_mci_pltfm_remove(pdev);
+}
+
+MODULE_DEVICE_TABLE(of, dw_mci_hi3798mv200_match);
+static struct platform_driver dw_mci_hi3798mv200_driver = {
+	.probe = dw_mci_hi3798mv200_probe,
+	.remove_new = dw_mci_hi3798mv200_remove,
+	.driver = {
+		.name = "dwmmc_hi3798mv200",
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+		.of_match_table = dw_mci_hi3798mv200_match,
+	},
+};
+module_platform_driver(dw_mci_hi3798mv200_driver);
+
+MODULE_DESCRIPTION("HiSilicon Hi3798MV200 Specific DW-MSHC Driver Extension");
+MODULE_LICENSE("GPL");

-- 
2.43.0



From devnull+forbidden405.outlook.com at kernel.org  Wed Feb 21 04:45:04 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Wed, 21 Feb 2024 20:45:04 +0800
Subject: [PATCH v6 2/5] mmc: dw_mmc-hi3798cv200: remove MODULE_ALIAS()
In-Reply-To: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>
References: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>
Message-ID: <20240221-b4-mmc-hi3798mv200-v6-2-bc41bf6a9769@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

The alias is not used and should be removed.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 drivers/mmc/host/dw_mmc-hi3798cv200.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mmc/host/dw_mmc-hi3798cv200.c b/drivers/mmc/host/dw_mmc-hi3798cv200.c
index e9470c50a348..61923a518369 100644
--- a/drivers/mmc/host/dw_mmc-hi3798cv200.c
+++ b/drivers/mmc/host/dw_mmc-hi3798cv200.c
@@ -201,4 +201,3 @@ module_platform_driver(dw_mci_hi3798cv200_driver);
 
 MODULE_DESCRIPTION("HiSilicon Hi3798CV200 Specific DW-MSHC Driver Extension");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:dwmmc_hi3798cv200");

-- 
2.43.0



From devnull+forbidden405.outlook.com at kernel.org  Wed Feb 21 04:45:06 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Wed, 21 Feb 2024 20:45:06 +0800
Subject: [PATCH v6 4/5] dt-bindings: mmc: dw-mshc-hi3798cv200: convert to
 YAML
In-Reply-To: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>
References: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>
Message-ID: <20240221-b4-mmc-hi3798mv200-v6-4-bc41bf6a9769@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

convert the legacy txt binding to modern YAML and rename to
hisilicon,hi3798cv200-dw-mshc.yaml. No semantic change.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 .../bindings/mmc/hi3798cv200-dw-mshc.txt           | 40 ------------
 .../mmc/hisilicon,hi3798cv200-dw-mshc.yaml         | 75 ++++++++++++++++++++++
 2 files changed, 75 insertions(+), 40 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/hi3798cv200-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/hi3798cv200-dw-mshc.txt
deleted file mode 100644
index a0693b7145f2..000000000000
--- a/Documentation/devicetree/bindings/mmc/hi3798cv200-dw-mshc.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-* Hisilicon Hi3798CV200 specific extensions to the Synopsys Designware Mobile
-  Storage Host Controller
-
-Read synopsys-dw-mshc.txt for more details
-
-The Synopsys designware mobile storage host controller is used to interface
-a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
-differences between the core Synopsys dw mshc controller properties described
-by synopsys-dw-mshc.txt and the properties used by the Hisilicon Hi3798CV200
-specific extensions to the Synopsys Designware Mobile Storage Host Controller.
-
-Required Properties:
-- compatible: Should contain "hisilicon,hi3798cv200-dw-mshc".
-- clocks: A list of phandle + clock-specifier pairs for the clocks listed
-  in clock-names.
-- clock-names: Should contain the following:
-	"ciu" - The ciu clock described in synopsys-dw-mshc.txt.
-	"biu" - The biu clock described in synopsys-dw-mshc.txt.
-	"ciu-sample" - Hi3798CV200 extended phase clock for ciu sampling.
-	"ciu-drive"  - Hi3798CV200 extended phase clock for ciu driving.
-
-Example:
-
-	emmc: mmc at 9830000 {
-		compatible = "hisilicon,hi3798cv200-dw-mshc";
-		reg = <0x9830000 0x10000>;
-		interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&crg HISTB_MMC_CIU_CLK>,
-			 <&crg HISTB_MMC_BIU_CLK>,
-			 <&crg HISTB_MMC_SAMPLE_CLK>,
-			 <&crg HISTB_MMC_DRV_CLK>;
-		clock-names = "ciu", "biu", "ciu-sample", "ciu-drive";
-		fifo-depth = <256>;
-		clock-frequency = <200000000>;
-		cap-mmc-highspeed;
-		mmc-ddr-1_8v;
-		mmc-hs200-1_8v;
-		non-removable;
-		bus-width = <8>;
-	};
diff --git a/Documentation/devicetree/bindings/mmc/hisilicon,hi3798cv200-dw-mshc.yaml b/Documentation/devicetree/bindings/mmc/hisilicon,hi3798cv200-dw-mshc.yaml
new file mode 100644
index 000000000000..f3dc973cb490
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/hisilicon,hi3798cv200-dw-mshc.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mmc/hisilicon,hi3798cv200-dw-mshc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hisilicon Hi3798CV200 SoC specific extensions to the Synopsys DWMMC controller
+
+maintainers:
+  - Yang Xiwen <forbidden405 at outlook.com>
+
+properties:
+  compatible:
+    enum:
+      - hisilicon,hi3798cv200-dw-mshc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: bus interface unit clock
+      - description: card interface unit clock
+      - description: card input sample phase clock
+      - description: controller output drive phase clock
+
+  clock-names:
+    items:
+      - const: ciu
+      - const: biu
+      - const: ciu-sample
+      - const: ciu-drive
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+allOf:
+  - $ref: synopsys-dw-mshc-common.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/histb-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    mmc at 9830000 {
+        compatible = "hisilicon,hi3798cv200-dw-mshc";
+        reg = <0x9830000 0x10000>;
+        interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&crg HISTB_MMC_CIU_CLK>,
+                 <&crg HISTB_MMC_BIU_CLK>,
+                 <&crg HISTB_MMC_SAMPLE_CLK>,
+                 <&crg HISTB_MMC_DRV_CLK>;
+        clock-names = "ciu", "biu", "ciu-sample", "ciu-drive";
+        resets = <&crg 0xa0 4>;
+        reset-names = "reset";
+        pinctrl-names = "default";
+        pinctrl-0 = <&emmc_pins_1 &emmc_pins_2
+                     &emmc_pins_3 &emmc_pins_4>;
+        fifo-depth = <256>;
+        clock-frequency = <200000000>;
+        cap-mmc-highspeed;
+        mmc-ddr-1_8v;
+        mmc-hs200-1_8v;
+        non-removable;
+        bus-width = <8>;
+    };

-- 
2.43.0



From devnull+forbidden405.outlook.com at kernel.org  Wed Feb 21 04:45:02 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Wed, 21 Feb 2024 20:45:02 +0800
Subject: [PATCH v6 0/5] mmc: add hi3798mv200 specific extensions of DWMMC
Message-ID: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>

it's modified from hi3798cv200 driver, but quite a lot of code gets
rewritten because of the hardware differences. Actually cv200 DWMMC core
is called HIMCIV200 while mv200 DWMMC core is called HIMCIV300 in
downstream.

Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
Changes in v6:
- apply the comments to the first patch, add their trailers
- Link to v5: https://lore.kernel.org/r/20240220-b4-mmc-hi3798mv200-v5-0-f506c55f8e43 at outlook.com

Changes in v5:
- pick the dependant patch: https://lore.kernel.org/all/20240215-mmc_phase-v1-1-f27644ee13e4 at outlook.com/
  to fix the bot build error.
- edit the semantic meaning of hisilicon,sap-dll-reg property (Rob Herring)
  The suggestion is from the CRG driver side:
  https://lore.kernel.org/all/20240218205741.GA1561527-robh at kernel.org/
- Link to v4: https://lore.kernel.org/r/20240217-b4-mmc-hi3798mv200-v4-0-0fdd9bd48532 at outlook.com

Changes in v4:
- rename dw_mmc-hi3798 back to hi3798cv200 - Suggested by Krzysztof Kozlowski.
- add r-bs to patch 1 and 2 - Reviewed by Krzysztof Kozlowski.
- Link to v3: https://lore.kernel.org/r/20240217-b4-mmc-hi3798mv200-v3-0-f15464176947 at outlook.com

Changes in v3:
- dw_mmc-hi3798: fix bot error (Rob Herring)
- Link to v2: https://lore.kernel.org/r/20240216-b4-mmc-hi3798mv200-v2-0-010d63e6a1d5 at outlook.com

Changes in v2:
- dw_mmc-hi3798mv200: use dev_err_probe() helper - Suggested by Krzysztof Kozlowski.
- dw_mmc-hi3798mv200: add missing err=0;
- dw_mmc-hi3798c(m)v200: remove unused MODULE_ALIAS() - Suggested by Krzysztof Kozlowski.
- binding: rename the binding, a lot of tweaks suggested by Krzysztof Kozlowski.
- Link to v1: https://lore.kernel.org/r/20240216-b4-mmc-hi3798mv200-v1-0-7d46db845ae6 at outlook.com

---
Yang Xiwen (5):
      mmc: host: mmc_of_parse_clk_phase(): Pass struct device * instead of mmc_host *
      mmc: dw_mmc-hi3798cv200: remove MODULE_ALIAS()
      mmc: dw_mmc: add support for hi3798mv200
      dt-bindings: mmc: dw-mshc-hi3798cv200: convert to YAML
      dt-bindings: mmc: hisilicon,hi3798cv200-dw-mshc: add Hi3798MV200 binding

 .../bindings/mmc/hi3798cv200-dw-mshc.txt           |  40 ----
 .../mmc/hisilicon,hi3798cv200-dw-mshc.yaml         |  97 +++++++++
 drivers/mmc/core/host.c                            |   4 +-
 drivers/mmc/host/Kconfig                           |   9 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/dw_mmc-hi3798cv200.c              |   1 -
 drivers/mmc/host/dw_mmc-hi3798mv200.c              | 239 +++++++++++++++++++++
 drivers/mmc/host/sdhci-of-aspeed.c                 |   2 +-
 include/linux/mmc/host.h                           |   2 +-
 9 files changed, 349 insertions(+), 46 deletions(-)
---
base-commit: 8d3dea210042f54b952b481838c1e7dfc4ec751d
change-id: 20240121-b4-mmc-hi3798mv200-a5730edf122c

Best regards,
-- 
Yang Xiwen <forbidden405 at outlook.com>



From devnull+forbidden405.outlook.com at kernel.org  Wed Feb 21 04:45:07 2024
From: devnull+forbidden405.outlook.com at kernel.org (Yang Xiwen via B4 Relay)
Date: Wed, 21 Feb 2024 20:45:07 +0800
Subject: [PATCH v6 5/5] dt-bindings: mmc: hisilicon,hi3798cv200-dw-mshc:
 add Hi3798MV200 binding
In-Reply-To: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>
References: <20240221-b4-mmc-hi3798mv200-v6-0-bc41bf6a9769@outlook.com>
Message-ID: <20240221-b4-mmc-hi3798mv200-v6-5-bc41bf6a9769@outlook.com>

From: Yang Xiwen <forbidden405 at outlook.com>

Add binding and an extra property for Hi3798MV200 DWMMC specific extension.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
 .../mmc/hisilicon,hi3798cv200-dw-mshc.yaml         | 24 +++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/hisilicon,hi3798cv200-dw-mshc.yaml b/Documentation/devicetree/bindings/mmc/hisilicon,hi3798cv200-dw-mshc.yaml
index f3dc973cb490..41c9b22523e7 100644
--- a/Documentation/devicetree/bindings/mmc/hisilicon,hi3798cv200-dw-mshc.yaml
+++ b/Documentation/devicetree/bindings/mmc/hisilicon,hi3798cv200-dw-mshc.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/mmc/hisilicon,hi3798cv200-dw-mshc.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Hisilicon Hi3798CV200 SoC specific extensions to the Synopsys DWMMC controller
+title: Hisilicon HiSTB SoCs specific extensions to the Synopsys DWMMC controller
 
 maintainers:
   - Yang Xiwen <forbidden405 at outlook.com>
@@ -13,6 +13,7 @@ properties:
   compatible:
     enum:
       - hisilicon,hi3798cv200-dw-mshc
+      - hisilicon,hi3798mv200-dw-mshc
 
   reg:
     maxItems: 1
@@ -34,6 +35,15 @@ properties:
       - const: ciu-sample
       - const: ciu-drive
 
+  hisilicon,sap-dll-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      DWMMC core on Hi3798MV2x SoCs has a delay-locked-loop(DLL) attached to card data input path.
+      It is integrated into CRG core on the SoC and has to be controlled during tuning.
+    items:
+      - description: A phandle pointed to the CRG syscon node
+      - description: Sample DLL register offset in CRG address space
+
 required:
   - compatible
   - reg
@@ -44,6 +54,18 @@ required:
 allOf:
   - $ref: synopsys-dw-mshc-common.yaml#
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: hisilicon,hi3798mv200-dw-mshc
+    then:
+      required:
+        - hisilicon,sap-dll-reg
+    else:
+      properties:
+        hisilicon,sap-dll-reg: false
+
 unevaluatedProperties: false
 
 examples:

-- 
2.43.0



From forbidden405 at outlook.com  Wed Feb 21 04:48:25 2024
From: forbidden405 at outlook.com (Yang Xiwen)
Date: Wed, 21 Feb 2024 20:48:25 +0800
Subject: [PATCH] mmc: host: replace 1st argument to struct device * for
 mmc_of_parse_clk_phase()
In-Reply-To: <20240215-mmc_phase-v1-1-f27644ee13e4@outlook.com>
References: <20240215-mmc_phase-v1-1-f27644ee13e4@outlook.com>
Message-ID: <SEZPR06MB695941B73156497A7E73CE8596572@SEZPR06MB6959.apcprd06.prod.outlook.com>

On 2/15/2024 7:03 PM, Yang Xiwen via B4 Relay wrote:
> From: Yang Xiwen <forbidden405 at outlook.com>
>
> Parsing dt usaully happens very early, sometimes even bofore struct
> mmc_host is allocated (e.g. dw_mci_probe() and dw_mci_parse_dt() in
> dw_mmc.c). Looking at the source of mmc_of_parse_clk_phase(), it's
> actually not mandatory to have a initialized mmc_host first, instead we
> can pass struct device * to it directly.
>
> Also fix the only current user (sdhci-of-aspeed.c).
>
> Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
> ---
>   drivers/mmc/core/host.c            | 4 +---
>   drivers/mmc/host/sdhci-of-aspeed.c | 2 +-
>   include/linux/mmc/host.h           | 2 +-
>   3 files changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index cf396e8f34e9..8b2844ac5dc5 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -234,10 +234,8 @@ static void mmc_of_parse_timing_phase(struct device *dev, const char *prop,
>   }
>   
>   void
> -mmc_of_parse_clk_phase(struct mmc_host *host, struct mmc_clk_phase_map *map)
> +mmc_of_parse_clk_phase(struct device *dev, struct mmc_clk_phase_map *map)
>   {
> -	struct device *dev = host->parent;
> -
>   	mmc_of_parse_timing_phase(dev, "clk-phase-legacy",
>   				  &map->phase[MMC_TIMING_LEGACY]);
>   	mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs",
> diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
> index 42d54532cabe..430c1f90037b 100644
> --- a/drivers/mmc/host/sdhci-of-aspeed.c
> +++ b/drivers/mmc/host/sdhci-of-aspeed.c
> @@ -435,7 +435,7 @@ static int aspeed_sdhci_probe(struct platform_device *pdev)
>   		goto err_sdhci_add;
>   
>   	if (dev->phase_desc)
> -		mmc_of_parse_clk_phase(host->mmc, &dev->phase_map);
> +		mmc_of_parse_clk_phase(&pdev->dev, &dev->phase_map);
>   
>   	ret = sdhci_add_host(host);
>   	if (ret)
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 2f445c651742..5894bf912f7b 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -539,7 +539,7 @@ struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra);
>   int mmc_add_host(struct mmc_host *);
>   void mmc_remove_host(struct mmc_host *);
>   void mmc_free_host(struct mmc_host *);
> -void mmc_of_parse_clk_phase(struct mmc_host *host,
> +void mmc_of_parse_clk_phase(struct device *dev,
>   			    struct mmc_clk_phase_map *map);
>   int mmc_of_parse(struct mmc_host *host);
>   int mmc_of_parse_voltage(struct mmc_host *host, u32 *mask);
>
> ---
> base-commit: 9d64bf433c53cab2f48a3fff7a1f2a696bc5229a
> change-id: 20240215-mmc_phase-26e85511285d
>
> Best regards,


Dear maintainers, this patch has been absorbed by the patchset here:

https://lore.kernel.org/all/20240221-b4-mmc-hi3798mv200-v6-1-bc41bf6a9769 at outlook.com/


So do not apply this patch directly anymore.

-- 
Regards,
Yang Xiwen



From abel.vesa at linaro.org  Wed Feb 21 04:52:36 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 21 Feb 2024 14:52:36 +0200
Subject: [PATCH v5 0/4] spmi: pmic-arb: Add support for multiple buses
Message-ID: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org>

This RFC prepares for and adds support for 2 buses, which is supported
in HW starting with version 7. Until now, none of the currently
supported platforms in upstream have used the second bus. The X1E80100
platform, on the other hand, needs the second bus for the USB2.0 to work
as there are 3 SMB2360 PMICs which provide eUSB2 repeaters and they are
all found on the second bus.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
Changes in v5:
- Dropped the RFC as there aren't any concerns about the approach anymore
- Dropped the unused dev and res variables from pmic_arb_get_obsrvr_chnls_v2
- Link to v4: https://lore.kernel.org/r/20240220-spmi-multi-master-support-v4-0-dc813c878ba8 at linaro.org

Changes in v4:
- Fixed comment above pmic_arb_init_apid_v7 by dropping the extra "bus" word
- Swicthed to devm_platform_ioremap_resource_byname for obsrvr and chnls.
  The core remains with platform_get_resource_byname as we need the core size.
- Dropped comment from probe related to the need of platform_get_resource_byname
  as it not true anymore.
- Dropped the qcom,bus-id optional property.
- Link to v3: https://lore.kernel.org/r/20240214-spmi-multi-master-support-v3-0-0bae0ef04faf at linaro.org

Changes in v3:
- Split the change into 3 separate patches. First 2 patches are moving
  apid init and core resources into version specific ops. Third one is
  adding the support for 2 buses and dedicated compatible.
- Added separate bindings patch
- Link to v2: https://lore.kernel.org/r/20240213-spmi-multi-master-support-v2-1-b3b102326906 at linaro.org

Changes in v2:
- Reworked it so that it registers a spmi controller for each bus
  rather than relying on the generic framework to pass on the bus
  (master) id.
- Link to v1: https://lore.kernel.org/r/20240207-spmi-multi-master-support-v1-0-ce57f301c7fd at linaro.org

---
Abel Vesa (4):
      dt-bindings: spmi: Add PMIC ARB v7 schema
      spmi: pmic-arb: Make the APID init a version operation
      spmi: pmic-arb: Make core resources acquiring a version operation
      spmi: pmic-arb: Add multi bus support

 .../bindings/spmi/qcom,spmi-pmic-arb-v7.yaml       | 119 +++
 drivers/spmi/spmi-pmic-arb.c                       | 949 +++++++++++++--------
 2 files changed, 698 insertions(+), 370 deletions(-)
---
base-commit: 4893c639cc3659cefaa675bf1e59f4e7571afb5c
change-id: 20240207-spmi-multi-master-support-832a704b779b

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>



From abel.vesa at linaro.org  Wed Feb 21 04:52:37 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 21 Feb 2024 14:52:37 +0200
Subject: [PATCH v5 1/4] dt-bindings: spmi: Add PMIC ARB v7 schema
In-Reply-To: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org>
References: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org>
Message-ID: <20240221-spmi-multi-master-support-v5-1-3255ca413a0b@linaro.org>

Add dedicated schema for PMIC ARB v7 as it allows multiple
buses by declaring them as child nodes. These child nodes
will follow the generic spmi bus bindings.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 .../bindings/spmi/qcom,spmi-pmic-arb-v7.yaml       | 119 +++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml
new file mode 100644
index 000000000000..8a93d2145aa5
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spmi/qcom,spmi-pmic-arb-v7.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SPMI Controller v7 (PMIC Arbiter)
+
+maintainers:
+  - Stephen Boyd <sboyd at kernel.org>
+
+description: |
+  The SPMI PMIC Arbiter v7 is found on Snapdragon chipsets. It is an SPMI
+  controller with wrapping arbitration logic to allow for multiple on-chip
+  devices to control up to 2 SPMI separate buses.
+
+  The PMIC Arbiter can also act as an interrupt controller, providing interrupts
+  to slave devices.
+
+properties:
+  compatible:
+    const: qcom,spmi-pmic-arb-v7
+
+  reg:
+    items:
+      - description: core registers
+      - description: tx-channel per virtual slave regosters
+      - description: rx-channel (called observer) per virtual slave registers
+
+  reg-names:
+    items:
+      - const: core
+      - const: chnls
+      - const: obsrvr
+
+  ranges: true
+
+  '#address-cells':
+    const: 2
+
+  '#size-cells':
+    const: 2
+
+  qcom,ee:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 5
+    description: >
+      indicates the active Execution Environment identifier
+
+  qcom,channel:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 5
+    description: >
+      which of the PMIC Arb provided channels to use for accesses
+
+patternProperties:
+  "spmi@[0-1]$":
+    type: object
+    $ref: /schemas/spmi/spmi.yaml
+
+required:
+  - compatible
+  - reg-names
+  - qcom,ee
+  - qcom,channel
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    spmi: arbiter at c400000 {
+      compatible = "qcom,spmi-pmic-arb-v7";
+      reg = <0x0c400000 0x3000>,
+            <0x0c500000 0x4000000>,
+            <0x0c440000 0x80000>;
+      reg-names = "core", "chnls", "obsrvr";
+
+      qcom,ee = <0>;
+      qcom,channel = <0>;
+
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      spmi_bus0: spmi at 0 {
+        reg = <0 0x0c42d000 0 0x4000>,
+              <0 0x0c4c0000 0 0x10000>;
+        reg-names = "cnfg", "intr";
+
+        interrupt-names = "periph_irq";
+        interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-controller;
+        #interrupt-cells = <4>;
+
+        qcom,bus-id = <0>;
+
+        #address-cells = <2>;
+        #size-cells = <0>;
+      };
+
+      spmi_bus1: spmi at 1 {
+        reg = <0 0x0c432000 0 0x4000>,
+              <0 0x0c4d0000 0 0x10000>;
+        reg-names = "cnfg", "intr";
+
+        interrupt-names = "periph_irq";
+        interrupts-extended = <&pdc 3 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-controller;
+        #interrupt-cells = <4>;
+
+        qcom,bus-id = <1>;
+
+        #address-cells = <2>;
+        #size-cells = <0>;
+      };
+    };

-- 
2.34.1



From abel.vesa at linaro.org  Wed Feb 21 04:52:38 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 21 Feb 2024 14:52:38 +0200
Subject: [PATCH v5 2/4] spmi: pmic-arb: Make the APID init a version
 operation
In-Reply-To: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org>
References: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org>
Message-ID: <20240221-spmi-multi-master-support-v5-2-3255ca413a0b@linaro.org>

Rather than using conditionals in probe function, add the APID init
as a version specific operation. Due to v7, which supports multiple
buses, pass on the bus index to be used for sorting out the apid base
and count.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 199 +++++++++++++++++++++++++++----------------
 1 file changed, 124 insertions(+), 75 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 9ed1180fe31f..38fed8a585fe 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -183,6 +183,7 @@ struct spmi_pmic_arb {
  * struct pmic_arb_ver_ops - version dependent functionality.
  *
  * @ver_str:		version string.
+ * @init_apid:		finds the apid base and count
  * @ppid_to_apid:	finds the apid for a given ppid.
  * @non_data_cmd:	on v1 issues an spmi non-data command.
  *			on v2 no HW support, returns -EOPNOTSUPP.
@@ -202,6 +203,7 @@ struct spmi_pmic_arb {
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
+	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
 	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
 	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
@@ -942,6 +944,38 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 	return 0;
 }
 
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
+{
+	/*
+	 * Initialize max_apid/min_apid to the opposite bounds, during
+	 * the irq domain translation, we are sure to update these
+	 */
+	pmic_arb->max_apid = 0;
+	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
+
+	return 0;
+}
+
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	u32 *mapping_table;
+
+	if (index) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs,
+				     sizeof(*mapping_table), GFP_KERNEL);
+	if (!mapping_table)
+		return -ENOMEM;
+
+	pmic_arb->mapping_table = mapping_table;
+
+	return pmic_arb_init_apid_min_max(pmic_arb);
+}
+
 static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 {
 	u32 *mapping_table = pmic_arb->mapping_table;
@@ -1144,6 +1178,40 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0x1000 * pmic_arb->ee + 0x8000 * apid;
 }
 
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	int ret;
+
+	if (index) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	pmic_arb->base_apid = 0;
+	pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+					   PMIC_ARB_FEATURES_PERIPH_MASK;
+
+	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+			pmic_arb->base_apid + pmic_arb->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	if (ret) {
+		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v5 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
@@ -1178,6 +1246,49 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return offset;
 }
 
+/*
+ * Only v7 supports 2 buses. Each bus will get a different apid count, read
+ * from different registers.
+ */
+static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	int ret;
+
+	if (index == 0) {
+		pmic_arb->base_apid = 0;
+		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else if (index == 1) {
+		pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						  PMIC_ARB_FEATURES_PERIPH_MASK;
+		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+			pmic_arb->base_apid + pmic_arb->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	if (ret) {
+		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v7 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
@@ -1358,6 +1469,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v1,
 	.offset			= pmic_arb_offset_v1,
@@ -1372,6 +1484,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.ver_str		= "v2",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1386,6 +1499,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.ver_str		= "v3",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1400,6 +1514,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.ver_str		= "v5",
+	.init_apid		= pmic_arb_init_apid_v5,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v5,
@@ -1414,6 +1529,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.ver_str		= "v7",
+	.init_apid		= pmic_arb_init_apid_v7,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v7,
@@ -1439,7 +1555,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	struct spmi_controller *ctrl;
 	struct resource *res;
 	void __iomem *core;
-	u32 *mapping_table;
 	u32 channel, ee, hw_ver;
 	int err;
 
@@ -1467,12 +1582,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	pmic_arb->core_size = resource_size(res);
 
-	pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
-					      sizeof(*pmic_arb->ppid_to_apid),
-					      GFP_KERNEL);
-	if (!pmic_arb->ppid_to_apid)
-		return -ENOMEM;
-
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
 	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
@@ -1506,58 +1615,17 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 			return PTR_ERR(pmic_arb->wr_base);
 	}
 
-	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
+		 pmic_arb->ver_ops->ver_str, hw_ver);
 
-	if (hw_ver >= PMIC_ARB_VERSION_V7_MIN) {
+	if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+	else
 		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
-		/* Optional property for v7: */
-		of_property_read_u32(pdev->dev.of_node, "qcom,bus-id",
-					&pmic_arb->bus_instance);
-		if (pmic_arb->bus_instance > 1) {
-			dev_err(&pdev->dev, "invalid bus instance (%u) specified\n",
-				pmic_arb->bus_instance);
-			return -EINVAL;
-		}
-
-		if (pmic_arb->bus_instance == 0) {
-			pmic_arb->base_apid = 0;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		} else {
-			pmic_arb->base_apid =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES1) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		}
 
-		if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->base_apid + pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	} else if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		pmic_arb->base_apid = 0;
-		pmic_arb->apid_count = readl_relaxed(core + PMIC_ARB_FEATURES) &
-					PMIC_ARB_FEATURES_PERIPH_MASK;
-
-		if (pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	}
-
-	pmic_arb->apid_data = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					   sizeof(*pmic_arb->apid_data),
-					   GFP_KERNEL);
-	if (!pmic_arb->apid_data)
-		return -ENOMEM;
-
-	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
-		 pmic_arb->ver_ops->ver_str, hw_ver);
+	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
+	if (err)
+		return err;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
 	pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
@@ -1599,16 +1667,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	}
 
 	pmic_arb->ee = ee;
-	mapping_table = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					sizeof(*mapping_table), GFP_KERNEL);
-	if (!mapping_table)
-		return -ENOMEM;
-
-	pmic_arb->mapping_table = mapping_table;
-	/* Initialize max_apid/min_apid to the opposite bounds, during
-	 * the irq domain translation, we are sure to update these */
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
 
 	platform_set_drvdata(pdev, ctrl);
 	raw_spin_lock_init(&pmic_arb->lock);
@@ -1617,15 +1675,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	ctrl->read_cmd = pmic_arb_read_cmd;
 	ctrl->write_cmd = pmic_arb_write_cmd;
 
-	if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		err = pmic_arb_read_apid_map_v5(pmic_arb);
-		if (err) {
-			dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n",
-				err);
-			return err;
-		}
-	}
-
 	dev_dbg(&pdev->dev, "adding irq domain\n");
 	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
 					 &pmic_arb_irq_domain_ops, pmic_arb);

-- 
2.34.1



From abel.vesa at linaro.org  Wed Feb 21 04:52:39 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 21 Feb 2024 14:52:39 +0200
Subject: [PATCH v5 3/4] spmi: pmic-arb: Make core resources acquiring a
 version operation
In-Reply-To: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org>
References: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org>
Message-ID: <20240221-spmi-multi-master-support-v5-3-3255ca413a0b@linaro.org>

Rather than setting up the core, obsrv and chnls in probe by using
version specific conditionals, add a dedicated "get_core_resources"
version specific op and move the acquiring in there.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 113 +++++++++++++++++++++++++++----------------
 1 file changed, 70 insertions(+), 43 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 38fed8a585fe..188252bfb95f 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -203,6 +203,7 @@ struct spmi_pmic_arb {
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
+	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
 	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
 	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
@@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
 	return 0;
 }
 
+static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->wr_base = core;
+	pmic_arb->rd_base = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+	return 0;
+}
+
 static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
 {
 	u32 *mapping_table;
@@ -1063,6 +1077,33 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 	return apid;
 }
 
+static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->rd_base = devm_platform_ioremap_resource_byname(pdev, "obsrvr");
+	if (IS_ERR(pmic_arb->rd_base))
+		return PTR_ERR(pmic_arb->rd_base);
+
+	pmic_arb->wr_base = devm_platform_ioremap_resource_byname(pdev, "chnls");
+	if (IS_ERR(pmic_arb->wr_base))
+		return PTR_ERR(pmic_arb->wr_base);
+
+	return 0;
+}
+
+static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->core = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+	return pmic_arb_get_obsrvr_chnls_v2(pdev);
+}
+
 static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 {
 	u16 apid_valid;
@@ -1246,6 +1287,18 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return offset;
 }
 
+static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->core = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+
+	return pmic_arb_get_obsrvr_chnls_v2(pdev);
+}
+
 /*
  * Only v7 supports 2 buses. Each bus will get a different apid count, read
  * from different registers.
@@ -1469,6 +1522,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
+	.get_core_resources	= pmic_arb_get_core_resources_v1,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v1,
@@ -1484,6 +1538,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.ver_str		= "v2",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1499,6 +1554,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.ver_str		= "v3",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1514,6 +1570,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.ver_str		= "v5",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v5,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1529,6 +1586,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.ver_str		= "v7",
+	.get_core_resources	= pmic_arb_get_core_resources_v7,
 	.init_apid		= pmic_arb_init_apid_v7,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1565,16 +1623,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	pmic_arb = spmi_controller_get_drvdata(ctrl);
 	pmic_arb->spmic = ctrl;
 
-	/*
-	 * Please don't replace this with devm_platform_ioremap_resource() or
-	 * devm_ioremap_resource().  These both result in a call to
-	 * devm_request_mem_region() which prevents multiple mappings of this
-	 * register address range.  SoCs with PMIC arbiter v7 may define two
-	 * arbiter devices, for the two physical SPMI interfaces, which  share
-	 * some register address ranges (i.e. "core", "obsrvr", and "chnls").
-	 * Ensure that both devices probe successfully by calling devm_ioremap()
-	 * which does not result in a devm_request_mem_region() call.
-	 */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
 	core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
 	if (IS_ERR(core))
@@ -1584,44 +1632,23 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
-	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
+	if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
 		pmic_arb->ver_ops = &pmic_arb_v1;
-		pmic_arb->wr_base = core;
-		pmic_arb->rd_base = core;
-	} else {
-		pmic_arb->core = core;
-
-		if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v2;
-		else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v3;
-		else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v5;
-		else
-			pmic_arb->ver_ops = &pmic_arb_v7;
-
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   "obsrvr");
-		pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start,
-						 resource_size(res));
-		if (IS_ERR(pmic_arb->rd_base))
-			return PTR_ERR(pmic_arb->rd_base);
-
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   "chnls");
-		pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start,
-						 resource_size(res));
-		if (IS_ERR(pmic_arb->wr_base))
-			return PTR_ERR(pmic_arb->wr_base);
-	}
+	else if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v2;
+	else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v3;
+	else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v5;
+	else
+		pmic_arb->ver_ops = &pmic_arb_v7;
 
 	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
 		 pmic_arb->ver_ops->ver_str, hw_ver);
 
-	if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
-		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
-	else
-		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
+	if (err)
+		return err;
 
 	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
 	if (err)

-- 
2.34.1



From abel.vesa at linaro.org  Wed Feb 21 04:52:40 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Wed, 21 Feb 2024 14:52:40 +0200
Subject: [PATCH v5 4/4] spmi: pmic-arb: Add multi bus support
In-Reply-To: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org>
References: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org>
Message-ID: <20240221-spmi-multi-master-support-v5-4-3255ca413a0b@linaro.org>

Starting with HW version 7, there are actually two separate buses
(with two separate sets of wires). So in order to support both
buses, we need to register a separate spmi controller for each one.
Add a separate compatible for v7 only, but allow the legacy platforms
that have v7 to still work with the old one, for DT backwards
compatibility.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 727 +++++++++++++++++++++++++------------------
 1 file changed, 430 insertions(+), 297 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 188252bfb95f..c5eca85fae30 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -13,6 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spmi.h>
@@ -94,6 +96,8 @@ enum pmic_arb_channel {
 	PMIC_ARB_CHANNEL_OBS,
 };
 
+#define PMIC_ARB_MAX_BUSES		2
+
 /* Maximum number of support PMIC peripherals */
 #define PMIC_ARB_MAX_PERIPHS		512
 #define PMIC_ARB_MAX_PERIPHS_V7		1024
@@ -125,58 +129,68 @@ struct apid_data {
 	u8		irq_ee;
 };
 
+struct spmi_pmic_arb;
+
 /**
- * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ * struct spmi_pmic_arb_bus - SPMI PMIC Arbiter Bus object
  *
- * @rd_base:		on v1 "core", on v2 "observer" register base off DT.
- * @wr_base:		on v1 "core", on v2 "chnls"    register base off DT.
  * @intr:		address of the SPMI interrupt control registers.
  * @cnfg:		address of the PMIC Arbiter configuration registers.
- * @lock:		lock to synchronize accesses.
- * @channel:		execution environment channel to use for accesses.
- * @irq:		PMIC ARB interrupt.
- * @ee:			the current Execution Environment
- * @bus_instance:	on v7: 0 = primary SPMI bus, 1 = secondary SPMI bus
- * @min_apid:		minimum APID (used for bounding IRQ search)
- * @max_apid:		maximum APID
+ * @domain:		irq domain object for PMIC IRQ domain
  * @base_apid:		on v7: minimum APID associated with the particular SPMI
  *			bus instance
  * @apid_count:		on v5 and v7: number of APIDs associated with the
  *			particular SPMI bus instance
  * @mapping_table:	in-memory copy of PPID -> APID mapping table.
- * @domain:		irq domain object for PMIC IRQ domain
- * @spmic:		SPMI controller object
- * @ver_ops:		version dependent operations.
  * @ppid_to_apid:	in-memory copy of PPID -> APID mapping table.
- * @last_apid:		Highest value APID in use
  * @apid_data:		Table of data for all APIDs
+ * @last_apid:		Highest value APID in use
+ * @irq:		PMIC ARB interrupt.
+ */
+struct spmi_pmic_arb_bus {
+	struct spmi_pmic_arb	*pmic_arb;
+	struct irq_domain	*domain;
+	void __iomem		*intr;
+	void __iomem		*cnfg;
+	struct spmi_controller	*spmic;
+	u16			base_apid;
+	int			apid_count;
+	u32			*mapping_table;
+	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
+	u16			*ppid_to_apid;
+	u16			last_apid;
+	struct apid_data	*apid_data;
+	u16			min_apid;
+	u16			max_apid;
+	int			irq;
+	u8			id;
+};
+
+/**
+ * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ *
+ * @rd_base:		on v1 "core", on v2 "observer" register base off DT.
+ * @wr_base:		on v1 "core", on v2 "chnls"    register base off DT.
+ * @lock:		lock to synchronize accesses.
+ * @channel:		execution environment channel to use for accesses.
+ * @ee:			the current Execution Environment
+ * @min_apid:		minimum APID (used for bounding IRQ search)
+ * @max_apid:		maximum APID
+ * @ver_ops:		version dependent operations.
  * @max_periphs:	Number of elements in apid_data[]
  */
 struct spmi_pmic_arb {
 	void __iomem		*rd_base;
 	void __iomem		*wr_base;
-	void __iomem		*intr;
-	void __iomem		*cnfg;
 	void __iomem		*core;
 	resource_size_t		core_size;
 	raw_spinlock_t		lock;
 	u8			channel;
-	int			irq;
 	u8			ee;
-	u32			bus_instance;
-	u16			min_apid;
-	u16			max_apid;
-	u16			base_apid;
-	int			apid_count;
-	u32			*mapping_table;
-	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
-	struct irq_domain	*domain;
-	struct spmi_controller	*spmic;
 	const struct pmic_arb_ver_ops *ver_ops;
-	u16			*ppid_to_apid;
-	u16			last_apid;
-	struct apid_data	*apid_data;
 	int			max_periphs;
+	struct spmi_pmic_arb_bus buses[PMIC_ARB_MAX_BUSES];
+	int			buses_available;
 };
 
 /**
@@ -204,21 +218,21 @@ struct spmi_pmic_arb {
 struct pmic_arb_ver_ops {
 	const char *ver_str;
 	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
-	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
-	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
+	int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index);
+	int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
-	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type);
+	int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+		      enum pmic_arb_channel ch_type);
 	u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
 	int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
 	/* Interrupts controller functionality (offset of PIC registers) */
-	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb *pmic_arb, u8 m,
+	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb_bus *bus, u8 m,
 					  u16 n);
-	void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*acc_enable)(struct spmi_pmic_arb_bus *bus, u16 n);
+	void __iomem *(*irq_status)(struct spmi_pmic_arb_bus *bus, u16 n);
+	void __iomem *(*irq_clear)(struct spmi_pmic_arb_bus *bus, u16 n);
 	u32 (*apid_map_offset)(u16 n);
-	void __iomem *(*apid_owner)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*apid_owner)(struct spmi_pmic_arb_bus *bus, u16 n);
 };
 
 static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -266,13 +280,14 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 				  void __iomem *base, u8 sid, u16 addr,
 				  enum pmic_arb_channel ch_type)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 status = 0;
 	u32 timeout = PMIC_ARB_TIMEOUT_US;
 	u32 offset;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type);
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr, ch_type);
 	if (rc < 0)
 		return rc;
 
@@ -284,21 +299,21 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 
 		if (status & PMIC_ARB_STATUS_DONE) {
 			if (status & PMIC_ARB_STATUS_DENIED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction denied (%#x)\n",
+					__func__, bus->id, sid, addr, status);
 				return -EPERM;
 			}
 
 			if (status & PMIC_ARB_STATUS_FAILURE) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction failed (%#x) reg: 0x%x\n",
+					__func__, bus->id, sid, addr, status, offset);
 				WARN_ON(1);
 				return -EIO;
 			}
 
 			if (status & PMIC_ARB_STATUS_DROPPED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction dropped (%#x)\n",
+					__func__, bus->id, sid, addr, status);
 				return -EIO;
 			}
 
@@ -307,8 +322,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 		udelay(1);
 	}
 
-	dev_err(&ctrl->dev, "%s: %#x %#x: timeout, status %#x\n",
-		__func__, sid, addr, status);
+	dev_err(&ctrl->dev, "%s: %#x %#x %#x: timeout, status %#x\n",
+		__func__, bus->id, sid, addr, status);
 	return -ETIMEDOUT;
 }
 
@@ -316,12 +331,13 @@ static int
 pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[0];
 	unsigned long flags;
 	u32 cmd;
 	int rc;
 	u32 offset;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW);
+	rc = pmic_arb->ver_ops->offset(bus, sid, 0, PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
@@ -357,20 +373,21 @@ static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
 	return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid);
 }
 
-static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 sid,
+static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb_bus *bus, u8 opc, u8 sid,
 				 u16 addr, size_t len, u32 *cmd, u32 *offset)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr,
 				       PMIC_ARB_CHANNEL_OBS);
 	if (rc < 0)
 		return rc;
 
 	*offset = rc;
 	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-		dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+		dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
 			PMIC_ARB_MAX_TRANS_BYTES, len);
 		return  -EINVAL;
 	}
@@ -394,7 +411,8 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      u32 offset, u8 sid, u16 addr, u8 *buf,
 				      size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
@@ -416,12 +434,13 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 			     u16 addr, u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned long flags;
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_read_cmd(bus, opc, sid, addr, len, &cmd,
 				   &offset);
 	if (rc)
 		return rc;
@@ -433,21 +452,22 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 	return rc;
 }
 
-static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc,
+static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb_bus *bus, u8 opc,
 				  u8 sid, u16 addr, size_t len, u32 *cmd,
 				  u32 *offset)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr,
 					PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
 	*offset = rc;
 	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-		dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+		dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
 			PMIC_ARB_MAX_TRANS_BYTES, len);
 		return  -EINVAL;
 	}
@@ -473,7 +493,8 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      u32 offset, u8 sid, u16 addr,
 				      const u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 
 	/* Write data to FIFOs */
@@ -492,12 +513,13 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 			      u16 addr, const u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned long flags;
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_write_cmd(bus, opc, sid, addr, len, &cmd,
 				    &offset);
 	if (rc)
 		return rc;
@@ -513,18 +535,19 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr,
 				 const u8 *buf, const u8 *mask, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 read_cmd, read_offset, write_cmd, write_offset;
 	u8 temp[PMIC_ARB_MAX_TRANS_BYTES];
 	unsigned long flags;
 	int rc, i;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, SPMI_CMD_EXT_READL, sid, addr, len,
+	rc = pmic_arb_fmt_read_cmd(bus, SPMI_CMD_EXT_READL, sid, addr, len,
 				   &read_cmd, &read_offset);
 	if (rc)
 		return rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, SPMI_CMD_EXT_WRITEL, sid, addr,
+	rc = pmic_arb_fmt_write_cmd(bus, SPMI_CMD_EXT_WRITEL, sid, addr,
 				    len, &write_cmd, &write_offset);
 	if (rc)
 		return rc;
@@ -567,25 +590,25 @@ struct spmi_pmic_arb_qpnpint_type {
 static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
 			       size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
+	if (pmic_arb_write_cmd(bus->spmic, SPMI_CMD_EXT_WRITEL, sid,
 			       (per << 8) + reg, buf, len))
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
 }
 
 static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, sid,
+	if (pmic_arb_read_cmd(bus->spmic, SPMI_CMD_EXT_READL, sid,
 			      (per << 8) + reg, buf, len))
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
 }
 
@@ -593,47 +616,49 @@ static int qpnpint_spmi_masked_write(struct irq_data *d, u8 reg,
 				     const void *buf, const void *mask,
 				     size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 	int rc;
 
-	rc = pmic_arb_masked_write(pmic_arb->spmic, sid, (per << 8) + reg, buf,
+	rc = pmic_arb_masked_write(bus->spmic, sid, (per << 8) + reg, buf,
 				   mask, len);
 	if (rc)
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
 				    d->irq, rc);
 	return rc;
 }
 
-static void cleanup_irq(struct spmi_pmic_arb *pmic_arb, u16 apid, int id)
+static void cleanup_irq(struct spmi_pmic_arb_bus *bus, u16 apid, int id)
 {
-	u16 ppid = pmic_arb->apid_data[apid].ppid;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	u16 ppid = bus->apid_data[apid].ppid;
 	u8 sid = ppid >> 8;
 	u8 per = ppid & 0xFF;
 	u8 irq_mask = BIT(id);
 
-	dev_err_ratelimited(&pmic_arb->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
-			__func__, apid, sid, per, id);
-	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	dev_err_ratelimited(&bus->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
+			    __func__, apid, sid, per, id);
+	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(bus, apid));
 }
 
-static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
+static int periph_interrupt(struct spmi_pmic_arb_bus *bus, u16 apid)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned int irq;
 	u32 status, id;
 	int handled = 0;
-	u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF;
-	u8 per = pmic_arb->apid_data[apid].ppid & 0xFF;
+	u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF;
+	u8 per = bus->apid_data[apid].ppid & 0xFF;
 
-	status = readl_relaxed(pmic_arb->ver_ops->irq_status(pmic_arb, apid));
+	status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid));
 	while (status) {
 		id = ffs(status) - 1;
 		status &= ~BIT(id);
-		irq = irq_find_mapping(pmic_arb->domain,
-					spec_to_hwirq(sid, per, id, apid));
+		irq = irq_find_mapping(bus->domain,
+				       spec_to_hwirq(sid, per, id, apid));
 		if (irq == 0) {
-			cleanup_irq(pmic_arb, apid, id);
+			cleanup_irq(bus, apid, id);
 			continue;
 		}
 		generic_handle_irq(irq);
@@ -645,16 +670,17 @@ static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
 
 static void pmic_arb_chained_irq(struct irq_desc *desc)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb_bus *bus = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int first = pmic_arb->min_apid;
-	int last = pmic_arb->max_apid;
+	int first = bus->min_apid;
+	int last = bus->max_apid;
 	/*
 	 * acc_offset will be non-zero for the secondary SPMI bus instance on
 	 * v7 controllers.
 	 */
-	int acc_offset = pmic_arb->base_apid >> 5;
+	int acc_offset = bus->base_apid >> 5;
 	u8 ee = pmic_arb->ee;
 	u32 status, enable, handled = 0;
 	int i, id, apid;
@@ -665,7 +691,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	chained_irq_enter(chip, desc);
 
 	for (i = first >> 5; i <= last >> 5; ++i) {
-		status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i - acc_offset));
+		status = readl_relaxed(ver_ops->owner_acc_status(bus, ee, i - acc_offset));
 		if (status)
 			acc_valid = true;
 
@@ -679,9 +705,9 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 				continue;
 			}
 			enable = readl_relaxed(
-					ver_ops->acc_enable(pmic_arb, apid));
+					ver_ops->acc_enable(bus, apid));
 			if (enable & SPMI_PIC_ACC_ENABLE_BIT)
-				if (periph_interrupt(pmic_arb, apid) != 0)
+				if (periph_interrupt(bus, apid) != 0)
 					handled++;
 		}
 	}
@@ -690,19 +716,19 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	if (!acc_valid) {
 		for (i = first; i <= last; i++) {
 			/* skip if APPS is not irq owner */
-			if (pmic_arb->apid_data[i].irq_ee != pmic_arb->ee)
+			if (bus->apid_data[i].irq_ee != pmic_arb->ee)
 				continue;
 
 			irq_status = readl_relaxed(
-					     ver_ops->irq_status(pmic_arb, i));
+					     ver_ops->irq_status(bus, i));
 			if (irq_status) {
 				enable = readl_relaxed(
-					     ver_ops->acc_enable(pmic_arb, i));
+					     ver_ops->acc_enable(bus, i));
 				if (enable & SPMI_PIC_ACC_ENABLE_BIT) {
-					dev_dbg(&pmic_arb->spmic->dev,
+					dev_dbg(&bus->spmic->dev,
 						"Dispatching IRQ for apid=%d status=%x\n",
 						i, irq_status);
-					if (periph_interrupt(pmic_arb, i) != 0)
+					if (periph_interrupt(bus, i) != 0)
 						handled++;
 				}
 			}
@@ -717,12 +743,13 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 
 static void qpnpint_irq_ack(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 data;
 
-	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(bus, apid));
 
 	data = BIT(irq);
 	qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
@@ -738,14 +765,15 @@ static void qpnpint_irq_mask(struct irq_data *d)
 
 static void qpnpint_irq_unmask(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 buf[2];
 
 	writel_relaxed(SPMI_PIC_ACC_ENABLE_BIT,
-			ver_ops->acc_enable(pmic_arb, apid));
+			ver_ops->acc_enable(bus, apid));
 
 	qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1);
 	if (!(buf[0] & BIT(irq))) {
@@ -802,9 +830,9 @@ static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
 
 static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 
-	return irq_set_irq_wake(pmic_arb->irq, on);
+	return irq_set_irq_wake(bus->irq, on);
 }
 
 static int qpnpint_get_irqchip_state(struct irq_data *d,
@@ -826,17 +854,18 @@ static int qpnpint_get_irqchip_state(struct irq_data *d,
 static int qpnpint_irq_domain_activate(struct irq_domain *domain,
 				       struct irq_data *d, bool reserve)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 periph = hwirq_to_per(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u16 sid = hwirq_to_sid(d->hwirq);
 	u16 irq = hwirq_to_irq(d->hwirq);
 	u8 buf;
 
-	if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
+	if (bus->apid_data[apid].irq_ee != pmic_arb->ee) {
+		dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
 			sid, periph, irq, pmic_arb->ee,
-			pmic_arb->apid_data[apid].irq_ee);
+			bus->apid_data[apid].irq_ee);
 		return -ENODEV;
 	}
 
@@ -863,15 +892,16 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 					unsigned long *out_hwirq,
 					unsigned int *out_type)
 {
-	struct spmi_pmic_arb *pmic_arb = d->host_data;
+	struct spmi_pmic_arb_bus *bus = d->host_data;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 *intspec = fwspec->param;
 	u16 apid, ppid;
 	int rc;
 
-	dev_dbg(&pmic_arb->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
+	dev_dbg(&bus->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
 		intspec[0], intspec[1], intspec[2]);
 
-	if (irq_domain_get_of_node(d) != pmic_arb->spmic->dev.of_node)
+	if (irq_domain_get_of_node(d) != bus->spmic->dev.of_node)
 		return -EINVAL;
 	if (fwspec->param_count != 4)
 		return -EINVAL;
@@ -879,37 +909,38 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 		return -EINVAL;
 
 	ppid = intspec[0] << 8 | intspec[1];
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
 	if (rc < 0) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
-		intspec[0], intspec[1], intspec[2], rc);
+		dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
+			intspec[0], intspec[1], intspec[2], rc);
 		return rc;
 	}
 
 	apid = rc;
 	/* Keep track of {max,min}_apid for bounding search during interrupt */
-	if (apid > pmic_arb->max_apid)
-		pmic_arb->max_apid = apid;
-	if (apid < pmic_arb->min_apid)
-		pmic_arb->min_apid = apid;
+	if (apid > bus->max_apid)
+		bus->max_apid = apid;
+	if (apid < bus->min_apid)
+		bus->min_apid = apid;
 
 	*out_hwirq = spec_to_hwirq(intspec[0], intspec[1], intspec[2], apid);
 	*out_type  = intspec[3] & IRQ_TYPE_SENSE_MASK;
 
-	dev_dbg(&pmic_arb->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
+	dev_dbg(&bus->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
 
 	return 0;
 }
 
 static struct lock_class_key qpnpint_irq_lock_class, qpnpint_irq_request_class;
 
-static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb,
+static void qpnpint_irq_domain_map(struct spmi_pmic_arb_bus *bus,
 				   struct irq_domain *domain, unsigned int virq,
 				   irq_hw_number_t hwirq, unsigned int type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	irq_flow_handler_t handler;
 
-	dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
+	dev_dbg(&bus->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
 		virq, hwirq, type);
 
 	if (type & IRQ_TYPE_EDGE_BOTH)
@@ -928,7 +959,7 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 				    unsigned int virq, unsigned int nr_irqs,
 				    void *data)
 {
-	struct spmi_pmic_arb *pmic_arb = domain->host_data;
+	struct spmi_pmic_arb_bus *bus = domain->host_data;
 	struct irq_fwspec *fwspec = data;
 	irq_hw_number_t hwirq;
 	unsigned int type;
@@ -939,20 +970,22 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 		return ret;
 
 	for (i = 0; i < nr_irqs; i++)
-		qpnpint_irq_domain_map(pmic_arb, domain, virq + i, hwirq + i,
+		qpnpint_irq_domain_map(bus, domain, virq + i, hwirq + i,
 				       type);
 
 	return 0;
 }
 
-static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb_bus *bus)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+
 	/*
 	 * Initialize max_apid/min_apid to the opposite bounds, during
 	 * the irq domain translation, we are sure to update these
 	 */
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
+	bus->max_apid = 0;
+	bus->min_apid = pmic_arb->max_periphs - 1;
 
 	return 0;
 }
@@ -970,43 +1003,44 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
 	return 0;
 }
 
-static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 *mapping_table;
 
 	if (index) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
 			index);
 		return -EINVAL;
 	}
 
-	mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs,
+	mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs,
 				     sizeof(*mapping_table), GFP_KERNEL);
 	if (!mapping_table)
 		return -ENOMEM;
 
-	pmic_arb->mapping_table = mapping_table;
+	bus->mapping_table = mapping_table;
 
-	return pmic_arb_init_apid_min_max(pmic_arb);
+	return pmic_arb_init_apid_min_max(bus);
 }
 
-static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	u32 *mapping_table = pmic_arb->mapping_table;
+	u32 *mapping_table = bus->mapping_table;
 	int index = 0, i;
 	u16 apid_valid;
 	u16 apid;
 	u32 data;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = bus->ppid_to_apid[ppid];
 	if (apid_valid & PMIC_ARB_APID_VALID) {
 		apid = apid_valid & ~PMIC_ARB_APID_VALID;
 		return apid;
 	}
 
 	for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
-		if (!test_and_set_bit(index, pmic_arb->mapping_table_valid))
-			mapping_table[index] = readl_relaxed(pmic_arb->cnfg +
+		if (!test_and_set_bit(index, bus->mapping_table_valid))
+			mapping_table[index] = readl_relaxed(bus->cnfg +
 						SPMI_MAPPING_TABLE_REG(index));
 
 		data = mapping_table[index];
@@ -1016,9 +1050,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				bus->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				bus->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		} else {
@@ -1026,9 +1060,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				bus->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				bus->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		}
@@ -1038,24 +1072,26 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 }
 
 /* v1 offset per ee */
-static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v1(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return 0x800 + 0x80 * pmic_arb->channel;
 }
 
-static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static u16 pmic_arb_find_apid(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid];
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	struct apid_data *apidd = &bus->apid_data[bus->last_apid];
 	u32 regval, offset;
 	u16 id, apid;
 
-	for (apid = pmic_arb->last_apid; ; apid++, apidd++) {
+	for (apid = bus->last_apid; ; apid++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(apid);
 		if (offset >= pmic_arb->core_size)
 			break;
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus,
 								     apid));
 		apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 		apidd->write_ee = apidd->irq_ee;
@@ -1065,14 +1101,14 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 			continue;
 
 		id = (regval >> 8) & PMIC_ARB_PPID_MASK;
-		pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
+		bus->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
 		apidd->ppid = id;
 		if (id == ppid) {
 			apid |= PMIC_ARB_APID_VALID;
 			break;
 		}
 	}
-	pmic_arb->last_apid = apid & ~PMIC_ARB_APID_VALID;
+	bus->last_apid = apid & ~PMIC_ARB_APID_VALID;
 
 	return apid;
 }
@@ -1104,21 +1140,22 @@ static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
 	return pmic_arb_get_obsrvr_chnls_v2(pdev);
 }
 
-static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
 	u16 apid_valid;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = bus->ppid_to_apid[ppid];
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
-		apid_valid = pmic_arb_find_apid(pmic_arb, ppid);
+		apid_valid = pmic_arb_find_apid(bus, ppid);
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
 	return apid_valid & ~PMIC_ARB_APID_VALID;
 }
 
-static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	struct apid_data *apidd;
 	struct apid_data *prev_apidd;
 	u16 i, apid, ppid, apid_max;
@@ -1140,9 +1177,9 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 	 * where N = number of APIDs supported by the primary bus and
 	 *       M = number of APIDs supported by the secondary bus
 	 */
-	apidd = &pmic_arb->apid_data[pmic_arb->base_apid];
-	apid_max = pmic_arb->base_apid + pmic_arb->apid_count;
-	for (i = pmic_arb->base_apid; i < apid_max; i++, apidd++) {
+	apidd = &bus->apid_data[bus->base_apid];
+	apid_max = bus->base_apid + bus->apid_count;
+	for (i = bus->base_apid; i < apid_max; i++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(i);
 		if (offset >= pmic_arb->core_size)
 			break;
@@ -1153,19 +1190,18 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		ppid = (regval >> 8) & PMIC_ARB_PPID_MASK;
 		is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval);
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
-								     i));
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i));
 		apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 
 		apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE;
 
-		valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
-		apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
-		prev_apidd = &pmic_arb->apid_data[apid];
+		valid = bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
+		apid = bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+		prev_apidd = &bus->apid_data[apid];
 
 		if (!valid || apidd->write_ee == pmic_arb->ee) {
 			/* First PPID mapping or one for this EE */
-			pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+			bus->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
 		} else if (valid && is_irq_ee &&
 			   prev_apidd->write_ee == pmic_arb->ee) {
 			/*
@@ -1176,42 +1212,43 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		}
 
 		apidd->ppid = ppid;
-		pmic_arb->last_apid = i;
+		bus->last_apid = i;
 	}
 
 	/* Dump the mapping table for debug purposes. */
-	dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
+	dev_dbg(&bus->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
 	for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) {
-		apid = pmic_arb->ppid_to_apid[ppid];
+		apid = bus->ppid_to_apid[ppid];
 		if (apid & PMIC_ARB_APID_VALID) {
 			apid &= ~PMIC_ARB_APID_VALID;
-			apidd = &pmic_arb->apid_data[apid];
-			dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n",
-			      ppid, apid, apidd->write_ee, apidd->irq_ee);
+			apidd = &bus->apid_data[apid];
+			dev_dbg(&bus->spmic->dev, "%#03X %3u %2u %2u\n",
+				ppid, apid, apidd->write_ee, apidd->irq_ee);
 		}
 	}
 
 	return 0;
 }
 
-static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
+	if (!(bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
-	return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+	return bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
 }
 
 /* v2 offset per ppid and per ee */
-static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	u16 ppid;
 	int rc;
 
 	ppid = sid << 8 | ((addr >> 8) & 0xFF);
-	rc = pmic_arb_ppid_to_apid_v2(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v2(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1219,33 +1256,34 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0x1000 * pmic_arb->ee + 0x8000 * apid;
 }
 
-static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	int ret;
 
 	if (index) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
 			index);
 		return -EINVAL;
 	}
 
-	pmic_arb->base_apid = 0;
-	pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+	bus->base_apid = 0;
+	bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 					   PMIC_ARB_FEATURES_PERIPH_MASK;
 
-	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
-			pmic_arb->base_apid + pmic_arb->apid_count);
+	if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+		dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+			bus->base_apid + bus->apid_count);
 		return -EINVAL;
 	}
 
-	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	ret = pmic_arb_init_apid_min_max(bus);
 	if (ret)
 		return ret;
 
-	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	ret = pmic_arb_read_apid_map_v5(bus);
 	if (ret) {
-		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+		dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
 			ret);
 		return ret;
 	}
@@ -1257,15 +1295,16 @@ static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
  * v5 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v5(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v5(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1275,8 +1314,8 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
-			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+		if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+			dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
 		}
@@ -1303,38 +1342,39 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
  * Only v7 supports 2 buses. Each bus will get a different apid count, read
  * from different registers.
  */
-static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	int ret;
 
 	if (index == 0) {
-		pmic_arb->base_apid = 0;
-		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+		bus->base_apid = 0;
+		bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 						   PMIC_ARB_FEATURES_PERIPH_MASK;
 	} else if (index == 1) {
-		pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+		bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 						  PMIC_ARB_FEATURES_PERIPH_MASK;
-		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+		bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
 						   PMIC_ARB_FEATURES_PERIPH_MASK;
 	} else {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
-			index);
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
+			bus->id);
 		return -EINVAL;
 	}
 
-	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
-			pmic_arb->base_apid + pmic_arb->apid_count);
+	if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+		dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+			bus->base_apid + bus->apid_count);
 		return -EINVAL;
 	}
 
-	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	ret = pmic_arb_init_apid_min_max(bus);
 	if (ret)
 		return ret;
 
-	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	ret = pmic_arb_read_apid_map_v5(bus);
 	if (ret) {
-		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+		dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
 			ret);
 		return ret;
 	}
@@ -1346,15 +1386,16 @@ static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
  * v7 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v7(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1364,8 +1405,8 @@ static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x8000 * pmic_arb->ee + 0x20 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
-			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+		if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+			dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
 		}
@@ -1387,104 +1428,110 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x20 * m + 0x4 * n;
+	return bus->intr + 0x20 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x100000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x200000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x10000 * m + 0x4 * n;
+	return bus->intr + 0x10000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x200 + 0x4 * n;
+	return bus->intr + 0x200 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * n;
+	return bus->intr + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x600 + 0x4 * n;
+	return bus->intr + 0x600 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x4 + 0x1000 * n;
+	return bus->intr + 0x4 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0xA00 + 0x4 * n;
+	return bus->intr + 0xA00 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x8 + 0x1000 * n;
+	return bus->intr + 0x8 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x1000 * n;
 }
 
@@ -1504,9 +1551,9 @@ static u32 pmic_arb_apid_map_offset_v7(u16 n)
 }
 
 static void __iomem *
-pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->cnfg + 0x700 + 0x4 * n;
+	return bus->cnfg + 0x700 + 0x4 * n;
 }
 
 /*
@@ -1515,9 +1562,9 @@ pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
  * 0.
  */
 static void __iomem *
-pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->cnfg + 0x4 * (n - pmic_arb->base_apid);
+	return  bus->cnfg + 0x4 * (n - bus->base_apid);
 }
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
@@ -1607,29 +1654,160 @@ static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
 	.translate = qpnpint_irq_domain_translate,
 };
 
+static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
+				  struct device_node *node,
+				  struct spmi_pmic_arb *pmic_arb)
+{
+	int bus_index = pmic_arb->buses_available;
+	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[bus_index];
+	struct device *dev = &pdev->dev;
+	struct spmi_controller *ctrl;
+	void __iomem *intr;
+	void __iomem *cnfg;
+	int index, ret;
+	u32 irq;
+
+	ctrl = devm_spmi_controller_alloc(dev, sizeof(*ctrl));
+	if (IS_ERR(ctrl))
+		return PTR_ERR(ctrl);
+
+	ctrl->cmd = pmic_arb_cmd;
+	ctrl->read_cmd = pmic_arb_read_cmd;
+	ctrl->write_cmd = pmic_arb_write_cmd;
+
+	bus = spmi_controller_get_drvdata(ctrl);
+	bus->spmic = ctrl;
+
+	bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID,
+					 sizeof(*bus->ppid_to_apid),
+					 GFP_KERNEL);
+	if (!bus->ppid_to_apid)
+		return -ENOMEM;
+
+	bus->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs,
+				      sizeof(*bus->apid_data),
+				      GFP_KERNEL);
+	if (!bus->apid_data)
+		return -ENOMEM;
+
+	index = of_property_match_string(node, "reg-names", "cnfg");
+	if (index < 0) {
+		dev_err(dev, "cnfg reg region missing");
+		return -EINVAL;
+	}
+
+	cnfg = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(cnfg))
+		return PTR_ERR(cnfg);
+
+	index = of_property_match_string(node, "reg-names", "intr");
+	if (index < 0) {
+		dev_err(dev, "intr reg region missing");
+		return -EINVAL;
+	}
+
+	intr = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(intr))
+		return PTR_ERR(intr);
+
+	irq = of_irq_get_byname(node, "periph_irq");
+	if (irq < 0)
+		return irq;
+
+	bus->pmic_arb = pmic_arb;
+	bus->intr = intr;
+	bus->cnfg = cnfg;
+	bus->irq = irq;
+	bus->id = bus_index;
+
+	ret = pmic_arb->ver_ops->init_apid(bus, bus_index);
+	if (ret)
+		return ret;
+
+	dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index);
+
+	bus->domain = irq_domain_add_tree(dev->of_node,
+					  &pmic_arb_irq_domain_ops, bus);
+	if (!bus->domain) {
+		dev_err(&pdev->dev, "unable to create irq_domain\n");
+		return -ENOMEM;
+	}
+
+	irq_set_chained_handler_and_data(bus->irq,
+					 pmic_arb_chained_irq, bus);
+
+	bus->spmic->dev.of_node = node;
+	dev_set_name(&bus->spmic->dev, "spmi-%d", bus_index);
+
+	ret = devm_spmi_controller_add(dev, bus->spmic);
+	if (ret)
+		return ret;
+
+	pmic_arb->buses_available++;
+
+	return 0;
+}
+
+static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb,
+					struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct device_node *child;
+	int ret;
+
+	/* legacy mode doesn't provide child node for the bus */
+	if (of_device_is_compatible(node, "qcom,spmi-pmic-arb-v7")) {
+		for_each_available_child_of_node(node, child) {
+			if (of_node_name_eq(child, "spmi")) {
+				ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb);
+				if (ret)
+					return ret;
+			}
+		}
+	} else {
+		ret = spmi_pmic_arb_bus_init(pdev, node, pmic_arb);
+	}
+
+	return ret;
+}
+
+static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb)
+{
+	int i;
+
+	for (i = 0; i < PMIC_ARB_MAX_BUSES; i++) {
+		struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[i];
+
+		irq_set_chained_handler_and_data(bus->irq,
+						 NULL, NULL);
+		irq_domain_remove(bus->domain);
+	}
+}
+
 static int spmi_pmic_arb_probe(struct platform_device *pdev)
 {
 	struct spmi_pmic_arb *pmic_arb;
-	struct spmi_controller *ctrl;
+	struct device *dev = &pdev->dev;
 	struct resource *res;
 	void __iomem *core;
 	u32 channel, ee, hw_ver;
 	int err;
 
-	ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*pmic_arb));
-	if (IS_ERR(ctrl))
-		return PTR_ERR(ctrl);
-
-	pmic_arb = spmi_controller_get_drvdata(ctrl);
-	pmic_arb->spmic = ctrl;
+	pmic_arb = devm_kzalloc(dev, sizeof(*pmic_arb), GFP_KERNEL);
+	if (!pmic_arb)
+		return -ENOMEM;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
-	core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
+	core = devm_ioremap(dev, res->start, resource_size(res));
 	if (IS_ERR(core))
 		return PTR_ERR(core);
 
 	pmic_arb->core_size = resource_size(res);
 
+	platform_set_drvdata(pdev, pmic_arb);
+	raw_spin_lock_init(&pmic_arb->lock);
+
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
 	if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
@@ -1643,30 +1821,12 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	else
 		pmic_arb->ver_ops = &pmic_arb_v7;
 
-	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
-		 pmic_arb->ver_ops->ver_str, hw_ver);
-
 	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
 	if (err)
 		return err;
 
-	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
-	if (err)
-		return err;
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
-	pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->intr))
-		return PTR_ERR(pmic_arb->intr);
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
-	pmic_arb->cnfg = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->cnfg))
-		return PTR_ERR(pmic_arb->cnfg);
-
-	pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq");
-	if (pmic_arb->irq < 0)
-		return pmic_arb->irq;
+	dev_info(dev, "PMIC arbiter version %s (0x%x)\n",
+		 pmic_arb->ver_ops->ver_str, hw_ver);
 
 	err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
 	if (err) {
@@ -1695,46 +1855,19 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	pmic_arb->ee = ee;
 
-	platform_set_drvdata(pdev, ctrl);
-	raw_spin_lock_init(&pmic_arb->lock);
-
-	ctrl->cmd = pmic_arb_cmd;
-	ctrl->read_cmd = pmic_arb_read_cmd;
-	ctrl->write_cmd = pmic_arb_write_cmd;
-
-	dev_dbg(&pdev->dev, "adding irq domain\n");
-	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
-					 &pmic_arb_irq_domain_ops, pmic_arb);
-	if (!pmic_arb->domain) {
-		dev_err(&pdev->dev, "unable to create irq_domain\n");
-		return -ENOMEM;
-	}
-
-	irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq,
-					pmic_arb);
-	err = spmi_controller_add(ctrl);
-	if (err)
-		goto err_domain_remove;
-
-	return 0;
-
-err_domain_remove:
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
-	return err;
+	return spmi_pmic_arb_register_buses(pmic_arb, pdev);
 }
 
 static void spmi_pmic_arb_remove(struct platform_device *pdev)
 {
-	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
-	spmi_controller_remove(ctrl);
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	spmi_pmic_arb_deregister_buses(pmic_arb);
 }
 
 static const struct of_device_id spmi_pmic_arb_match_table[] = {
 	{ .compatible = "qcom,spmi-pmic-arb", },
+	{ .compatible = "qcom,spmi-pmic-arb-v7", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);

-- 
2.34.1



From broonie at kernel.org  Wed Feb 21 04:56:46 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 21 Feb 2024 12:56:46 +0000
Subject: [PATCH v5 3/7] arm64/sysreg/tools: Move TRFCR definitions to
 sysreg
In-Reply-To: <c1e159b7-c884-e498-6b01-64a897117036@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
 <20240220100924.2761706-4-james.clark@arm.com>
 <18995343-e43e-4e92-a97d-3df74ec6ddb7@sirena.org.uk>
 <c1e159b7-c884-e498-6b01-64a897117036@arm.com>
Message-ID: <d50cabc9-25ef-4992-99be-a2cdb55bc98e@sirena.org.uk>

On Wed, Feb 21, 2024 at 10:10:18AM +0000, James Clark wrote:
> On 20/02/2024 16:11, Mark Brown wrote:

> > These are generally sorted by encoding (simiarly to how sysreg.h was
> > sorted historically).

> Ah I didn't know that. Can I add a comment to the top of the file saying
> that it should be kept sorted?

Sure.
-------------- 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/20240221/29b8ed3d/attachment.sig>

From jgg at nvidia.com  Wed Feb 21 04:57:53 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Wed, 21 Feb 2024 08:57:53 -0400
Subject: [PATCH v2 03/13] mm: Provide generic pmd_thp_or_huge()
In-Reply-To: <ZdXEYfs_xhS_9gRo@x1n>
References: <20240103091423.400294-1-peterx@redhat.com>
 <20240103091423.400294-4-peterx@redhat.com>
 <20240115175551.GP734935@nvidia.com>
 <ZdXEYfs_xhS_9gRo@x1n>
Message-ID: <20240221125753.GQ13330@nvidia.com>

On Wed, Feb 21, 2024 at 05:37:37PM +0800, Peter Xu wrote:
> On Mon, Jan 15, 2024 at 01:55:51PM -0400, Jason Gunthorpe wrote:
> > On Wed, Jan 03, 2024 at 05:14:13PM +0800, peterx at redhat.com wrote:
> > > From: Peter Xu <peterx at redhat.com>
> > > 
> > > ARM defines pmd_thp_or_huge(), detecting either a THP or a huge PMD.  It
> > > can be a helpful helper if we want to merge more THP and hugetlb code
> > > paths.  Make it a generic default implementation, only exist when
> > > CONFIG_MMU.  Arch can overwrite it by defining its own version.
> > > 
> > > For example, ARM's pgtable-2level.h defines it to always return false.
> > > 
> > > Keep the macro declared with all config, it should be optimized to a false
> > > anyway if !THP && !HUGETLB.
> > > 
> > > Signed-off-by: Peter Xu <peterx at redhat.com>
> > > ---
> > >  include/linux/pgtable.h | 4 ++++
> > >  mm/gup.c                | 3 +--
> > >  2 files changed, 5 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> > > index 466cf477551a..2b42e95a4e3a 100644
> > > --- a/include/linux/pgtable.h
> > > +++ b/include/linux/pgtable.h
> > > @@ -1362,6 +1362,10 @@ static inline int pmd_write(pmd_t pmd)
> > >  #endif /* pmd_write */
> > >  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
> > >  
> > > +#ifndef pmd_thp_or_huge
> > > +#define pmd_thp_or_huge(pmd)	(pmd_huge(pmd) || pmd_trans_huge(pmd))
> > > +#endif
> > 
> > Why not just use pmd_leaf() ?
> > 
> > This GUP case seems to me exactly like what pmd_leaf() should really
> > do and be used for..
> 
> I think I mostly agree with you, and these APIs are indeed confusing.  IMHO
> the challenge is about the risk of breaking others on small changes in the
> details where evil resides.

These APIs are super confusing, which is why I brought it up.. Adding
even more subtly different variations is not helping.

I think pmd_leaf means the entry is present and refers to a physical
page not another radix level.

> > eg x86 does:
> > 
> > #define pmd_leaf	pmd_large
> > static inline int pmd_large(pmd_t pte)
> > 	return pmd_flags(pte) & _PAGE_PSE;
> > 
> > static inline int pmd_trans_huge(pmd_t pmd)
> > 	return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
> > 
> > int pmd_huge(pmd_t pmd)
> >         return !pmd_none(pmd) &&
> >                 (pmd_val(pmd) & (_PAGE_PRESENT|_PAGE_PSE)) != _PAGE_PRESENT;
> 
> For example, here I don't think it's strictly pmd_leaf()? As pmd_huge()
> will return true if PRESENT=0 && PSE=0 (as long as none pte ruled out
> first), while pmd_leaf() will return false; I think that came from
> cbef8478bee5. 

Yikes, but do you even want to handle non-present entries in GUP
world? Isn't everything gated by !present in the first place?

> Besides that, there're also other cases where it's not clear of such direct
> replacement, not until further investigated.  E.g., arm-3level has:
> 
> #define pmd_leaf(pmd)		pmd_sect(pmd)
> #define pmd_sect(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
> 						 PMD_TYPE_SECT)
> #define PMD_TYPE_SECT		(_AT(pmdval_t, 1) << 0)
> 
> While pmd_huge() there relies on PMD_TABLE_BIT ()

I looked at tht, it looked OK.. 

#define PMD_TYPE_MASK               (_AT(pmdval_t, 3) << 0)
#define PMD_TABLE_BIT               (_AT(pmdval_t, 1) << 1)

It is the same stuff, just a little confusingly written

Jason


From javierm at redhat.com  Wed Feb 21 04:59:17 2024
From: javierm at redhat.com (Javier Martinez Canillas)
Date: Wed, 21 Feb 2024 13:59:17 +0100
Subject: [PATCH] arm64: defconfig: Enable zram, xfs and loading compressed FW support
Message-ID: <20240221125928.3711050-1-javierm@redhat.com>

These options are needed by some Linux distributions (e.g: Fedora), so
let's enable them to make it easier for developers using such distros.

Signed-off-by: Javier Martinez Canillas <javierm at redhat.com>
---

 arch/arm64/configs/defconfig | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 056a6cc546a4..12aebbba814e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -241,6 +241,8 @@ CONFIG_PCI_EPF_TEST=m
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_FW_LOADER_USER_HELPER=y
+CONFIG_FW_LOADER_COMPRESS=y
+CONFIG_MODULE_COMPRESS_XZ=y
 CONFIG_HISILICON_LPC=y
 CONFIG_TEGRA_ACONNECT=m
 CONFIG_MHI_BUS_PCI_GENERIC=m
@@ -275,6 +277,8 @@ CONFIG_MTD_NAND_FSL_IFC=y
 CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_MTD_UBI=m
+CONFIG_ZRAM=m
+CONFIG_ZRAM_WRITEBACK=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
 CONFIG_VIRTIO_BLK=y
@@ -1595,6 +1599,7 @@ CONFIG_HTE_TEGRA194_TEST=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
 CONFIG_BTRFS_FS=m
 CONFIG_BTRFS_FS_POSIX_ACL=y
 CONFIG_FANOTIFY=y
-- 
2.43.0



From rafael at kernel.org  Wed Feb 21 05:01:25 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Wed, 21 Feb 2024 14:01:25 +0100
Subject: [PATCH RFC v4 01/15] ACPI: Only enumerate enabled (or functional)
 processor devices
In-Reply-To: <E1rVDmP-0027YJ-EW@rmk-PC.armlinux.org.uk>
References: <Zbp5xzmFhKDAgHws@shell.armlinux.org.uk> <E1rVDmP-0027YJ-EW@rmk-PC.armlinux.org.uk>
Message-ID: <CAJZ5v0gJHq41HzGadwSu7yxJF_tidiX09ZMMV3j4L3bhmPwhaQ@mail.gmail.com>

On Wed, Jan 31, 2024 at 5:49?PM Russell King <rmk+kernel at armlinux.org.uk> wrote:
>
> From: James Morse <james.morse at arm.com>
>
> Today the ACPI enumeration code 'visits' all devices that are present.
>
> This is a problem for arm64, where CPUs are always present, but not
> always enabled. When a device-check occurs because the firmware-policy
> has changed and a CPU is now enabled, the following error occurs:
> | acpi ACPI0007:48: Enumeration failure
>
> This is ultimately because acpi_dev_ready_for_enumeration() returns
> true for a device that is not enabled. The ACPI Processor driver
> will not register such CPUs as they are not 'decoding their resources'.
>
> ACPI allows a device to be functional instead of maintaining the
> present and enabled bit, but we can't simply check the enabled bit
> for all devices since firmware can be buggy.
>
> If ACPI indicates that the device is present and enabled, then all well
> and good, we can enumate it. However, if the device is present and not
> enabled, then we also check whether the device is a processor device
> to limit the impact of this new check to just processor devices.
>
> This avoids enumerating present && functional processor devices that
> are not enabled.
>
> Signed-off-by: James Morse <james.morse at arm.com>
> Co-developed-by: Rafael J. Wysocki <rjw at rjwysocki.net>
> Tested-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
> Changes since RFC v2:
>  * Incorporate comment suggestion by Gavin Shan.
> Changes since RFC v3:
>  * Fixed "sert" typo.
> Changes since RFC v3 (smaller series):
>  * Restrict checking the enabled bit to processor devices, update
>    commit comments.
>  * Use Rafael's suggestion in
>    https://lore.kernel.org/r/5760569.DvuYhMxLoT at kreacher
>  * Updated with a fix - see:
>    https://lore.kernel.org/all/Zbe8WQRASx6D6RaG at shell.armlinux.org.uk/
> ---
>  drivers/acpi/acpi_processor.c | 11 +++++++++
>  drivers/acpi/device_pm.c      |  2 +-
>  drivers/acpi/device_sysfs.c   |  2 +-
>  drivers/acpi/internal.h       |  4 ++-
>  drivers/acpi/property.c       |  2 +-
>  drivers/acpi/scan.c           | 46 +++++++++++++++++++++++++++--------
>  6 files changed, 53 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> index 4fe2ef54088c..cf7c1cca69dd 100644
> --- a/drivers/acpi/acpi_processor.c
> +++ b/drivers/acpi/acpi_processor.c
> @@ -626,6 +626,17 @@ static struct acpi_scan_handler processor_handler = {
>         },
>  };
>
> +bool acpi_device_is_processor(const struct acpi_device *adev)
> +{
> +       if (adev->device_type == ACPI_BUS_TYPE_PROCESSOR)
> +               return true;
> +
> +       if (adev->device_type != ACPI_BUS_TYPE_DEVICE)
> +               return false;
> +
> +       return acpi_scan_check_handler(adev, &processor_handler);
> +}
> +
>  static int acpi_processor_container_attach(struct acpi_device *dev,
>                                            const struct acpi_device_id *id)
>  {
> diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
> index 3b4d048c4941..e3c80f3b3b57 100644
> --- a/drivers/acpi/device_pm.c
> +++ b/drivers/acpi/device_pm.c
> @@ -313,7 +313,7 @@ int acpi_bus_init_power(struct acpi_device *device)
>                 return -EINVAL;
>
>         device->power.state = ACPI_STATE_UNKNOWN;
> -       if (!acpi_device_is_present(device)) {
> +       if (!acpi_dev_ready_for_enumeration(device)) {

Sorry for failing to catch this earlier, but this change affects
non-processor devices possibly adversely.

Namely, one of the differences between acpi_device_is_present() and
acpi_dev_ready_for_enumeration() is the (device->flags.honor_deps &&
device->dep_unmet) check in the latter which is not present in the
former which may cause the power_manageable flag to be unset for
devices with dependencies, although they are in fact power-manageable.

The replacement here cannot be made.

>                 device->flags.initialized = false;
>                 return -ENXIO;
>         }
> diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c
> index 23373faa35ec..a0256d2493a7 100644
> --- a/drivers/acpi/device_sysfs.c
> +++ b/drivers/acpi/device_sysfs.c
> @@ -141,7 +141,7 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia
>         struct acpi_hardware_id *id;
>
>         /* Avoid unnecessarily loading modules for non present devices. */
> -       if (!acpi_device_is_present(acpi_dev))
> +       if (!acpi_dev_ready_for_enumeration(acpi_dev))

The replacement here is incorrect for an analogous reason as above: it
may cause modalias creation to be skipped for devices with unmet
dependencies that are not processors and matching modules for them
should be loaded.

In fact, this replacement doesn't even have a functional effect on
processors, because there are no modules matching the processor device
ID AFAICS.

>                 return 0;
>
>         /*
> diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
> index 6588525c45ef..1bc8b6db60c5 100644
> --- a/drivers/acpi/internal.h
> +++ b/drivers/acpi/internal.h
> @@ -62,6 +62,8 @@ void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
>  int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler,
>                                        const char *hotplug_profile_name);
>  void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val);
> +bool acpi_scan_check_handler(const struct acpi_device *adev,
> +                            struct acpi_scan_handler *handler);
>
>  #ifdef CONFIG_DEBUG_FS
>  extern struct dentry *acpi_debugfs_dir;
> @@ -121,7 +123,6 @@ int acpi_device_setup_files(struct acpi_device *dev);
>  void acpi_device_remove_files(struct acpi_device *dev);
>  void acpi_device_add_finalize(struct acpi_device *device);
>  void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
> -bool acpi_device_is_present(const struct acpi_device *adev);
>  bool acpi_device_is_battery(struct acpi_device *adev);
>  bool acpi_device_is_first_physical_node(struct acpi_device *adev,
>                                         const struct device *dev);
> @@ -133,6 +134,7 @@ int acpi_bus_register_early_device(int type);
>  const struct acpi_device *acpi_companion_match(const struct device *dev);
>  int __acpi_device_uevent_modalias(const struct acpi_device *adev,
>                                   struct kobj_uevent_env *env);
> +bool acpi_device_is_processor(const struct acpi_device *adev);
>
>  /* --------------------------------------------------------------------------
>                                    Power Resource
> diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
> index a6ead5204046..9f8d54038770 100644
> --- a/drivers/acpi/property.c
> +++ b/drivers/acpi/property.c
> @@ -1486,7 +1486,7 @@ static bool acpi_fwnode_device_is_available(const struct fwnode_handle *fwnode)
>         if (!is_acpi_device_node(fwnode))
>                 return false;
>
> -       return acpi_device_is_present(to_acpi_device_node(fwnode));
> +       return acpi_dev_ready_for_enumeration(to_acpi_device_node(fwnode));

This, again, may break non-processor devices with dependencies in
subtle ways and it doesn't have a functional effect on processors
AFAICS.

>  }
>
>  static const void *
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index e6ed1ba91e5c..fd2e8b3a5749 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -304,7 +304,7 @@ static int acpi_scan_device_check(struct acpi_device *adev)
>         int error;
>
>         acpi_bus_get_status(adev);
> -       if (acpi_device_is_present(adev)) {
> +       if (acpi_dev_ready_for_enumeration(adev)) {

It looks to me like there are two purposes of this replacement.  One
is to handle the removal case which is analogous to the
acpi_scan_bus_check() case below.

The other purpose seems to be to avoid the dev_warn() message printed
when acpi_processor_add() does not return 1 for a processor device
that is not enabled.

However, this message arguably should not be printed at all so long as
acpi_bus_scan() succeeds, because hot-adding a device without a
matching scan handler is entirely valid.

I'll send a patch to fix this shortly.

In addition to that, it would suffice to make acpi_processor_add()
check the enabled bit and return 0 early when it is clear.  I'll send
a patch for this either.

>                 /*
>                  * This function is only called for device objects for which
>                  * matching scan handlers exist.  The only situation in which
> @@ -338,7 +338,7 @@ static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used)
>         int error;
>
>         acpi_bus_get_status(adev);
> -       if (!acpi_device_is_present(adev)) {
> +       if (!acpi_dev_ready_for_enumeration(adev)) {

Indeed, the enabled bit should be checked here, along with the present
and functional bits, but it would be better to move that check to
acpi_bus_trim_one() or even acpi_processor_remove(), so the
not-present-but-functional case is handled correctly.  And the
acpi_scan_device_check() case could then be handled analogously.
Another patch to be sent.

>                 acpi_scan_device_not_enumerated(adev);
>                 return 0;
>         }
> @@ -1917,11 +1917,6 @@ static bool acpi_device_should_be_hidden(acpi_handle handle)
>         return true;
>  }
>
> -bool acpi_device_is_present(const struct acpi_device *adev)
> -{
> -       return adev->status.present || adev->status.functional;
> -}
> -
>  static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
>                                        const char *idstr,
>                                        const struct acpi_device_id **matchid)
> @@ -1942,6 +1937,18 @@ static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
>         return false;
>  }
>
> +bool acpi_scan_check_handler(const struct acpi_device *adev,
> +                            struct acpi_scan_handler *handler)
> +{
> +       struct acpi_hardware_id *hwid;
> +
> +       list_for_each_entry(hwid, &adev->pnp.ids, list)
> +               if (acpi_scan_handler_matching(handler, hwid->id, NULL))
> +                       return true;
> +
> +       return false;
> +}
> +
>  static struct acpi_scan_handler *acpi_scan_match_handler(const char *idstr,
>                                         const struct acpi_device_id **matchid)
>  {
> @@ -2405,16 +2412,35 @@ EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
>   * acpi_dev_ready_for_enumeration - Check if the ACPI device is ready for enumeration
>   * @device: Pointer to the &struct acpi_device to check
>   *
> - * Check if the device is present and has no unmet dependencies.
> + * Check if the device is functional or enabled and has no unmet dependencies.
>   *
> - * Return true if the device is ready for enumeratino. Otherwise, return false.
> + * Return true if the device is ready for enumeration. Otherwise, return false.
>   */
>  bool acpi_dev_ready_for_enumeration(const struct acpi_device *device)
>  {
>         if (device->flags.honor_deps && device->dep_unmet)
>                 return false;
>
> -       return acpi_device_is_present(device);
> +       /*
> +        * ACPI 6.5's 6.3.7 "_STA (Device Status)" allows firmware to return
> +        * (!present && functional) for certain types of devices that should be
> +        * enumerated. Note that the enabled bit should not be set unless the
> +        * present bit is set.
> +        *
> +        * However, limit this only to processor devices to reduce possible
> +        * regressions with firmware.
> +        */
> +       if (!device->status.present)
> +               return device->status.functional;
> +
> +       /*
> +        * Fast path - if enabled is set, avoid the more expensive test to
> +        * check whether this device is a processor.
> +        */
> +       if (device->status.enabled)
> +               return true;
> +
> +       return !acpi_device_is_processor(device);
>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
>
> --


From romain.gantois at bootlin.com  Wed Feb 21 05:04:17 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Wed, 21 Feb 2024 14:04:17 +0100
Subject: [PATCH net-next v4 0/7] Fix missing PHY-to-MAC RX clock
Message-ID: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>

Hello everyone,

This is version four of my series that addresses the issue with some MAC/PHY
combinations.

Notable changes in v4:
  - Modified miic_pre_init() to also set the default RMII conversion speed.

Notable changes in v3:
  - Removed the "interface" argument from pcs_init().
  - Added a kernel doc for pcs_init().

Notable changes in v2:
  - Introduced a pcs op for initializing hardware required for MAC
    initialization, instead of using phylink_validate() for this purpose.
  - Refactored stmmac to use a generic PCS reference in mac_device_info
    instead of a model-specific field.

There is an issue with some stmmac/PHY combinations that has been reported
some time ago in a couple of different series:

Clark Wang's report:
https://lore.kernel.org/all/20230202081559.3553637-1-xiaoning.wang at nxp.com/
Cl?ment L?ger's report:
https://lore.kernel.org/linux-arm-kernel/20230116103926.276869-4-clement.leger at bootlin.com/

Stmmac controllers require an RX clock signal from the MII bus to perform
their hardware initialization successfully. This causes issues with some
PHY/PCS devices. If these devices do not bring the clock signal up before
the MAC driver initializes its hardware, then said initialization will
fail. This can happen at probe time or when the system wakes up from a
suspended state.

This series introduces new flags for phy_device and phylink_pcs. These
flags allow MAC drivers to signal to PHY/PCS drivers that the RX clock
signal should be enabled as soon as possible, and that it should always
stay enabled.

I have included specific uses of these flags that fix the RZN1 GMAC1 stmmac
driver that I am currently working on and that is not yet upstream. I have
also included changes to the at803x PHY driver that should fix the issue
that Clark Wang was having.

Clark, could you please confirm that this series fixes your issue with the
at803x PHY?

Best Regards,

Romain

Romain Gantois (2):
  net: phy: add rxc_always_on flag to phylink_pcs
  net: pcs: rzn1-miic: Init RX clock early if MAC requires it

Russell King (3):
  net: phy: add PHY_F_RXC_ALWAYS_ON to PHY dev flags
  net: stmmac: Signal to PHY/PCS drivers to keep RX clock on
  net: phy: at803x: Avoid hibernating if MAC requires RX clock

 .../net/ethernet/stmicro/stmmac/stmmac_main.c  |  5 +++++
 drivers/net/pcs/pcs-rzn1-miic.c                | 18 +++++++++++++-----
 drivers/net/phy/at803x.c                       |  3 ++-
 drivers/net/phy/phylink.c                      | 13 ++++++++++++-
 include/linux/phy.h                            |  1 +
 include/linux/phylink.h                        |  9 +++++++++
 6 files changed, 42 insertions(+), 7 deletions(-)

--
2.43.0

---
- Link to v2: https://lore.kernel.org/r/20240130-rxc_bugfix-v2-0-5e6c3168e5f0 at bootlin.com

---
- Link to v3: https://lore.kernel.org/r/20240212-rxc_bugfix-v3-0-e9f2eb6b3b05 at bootlin.com

---
Maxime Chevallier (1):
      net: stmmac: don't rely on lynx_pcs presence to check for a PHY

Romain Gantois (4):
      net: phylink: add rxc_always_on flag to phylink_pcs
      net: stmmac: Support a generic PCS field in mac_device_info
      net: stmmac: Signal to PHY/PCS drivers to keep RX clock on
      net: pcs: rzn1-miic: Init RX clock early if MAC requires it

Russell King (2):
      net: phylink: add PHY_F_RXC_ALWAYS_ON to PHY dev flags
      net: phy: qcom: at803x: Avoid hibernating if MAC requires RX clock

 drivers/net/ethernet/stmicro/stmmac/common.h       |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  8 ++---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 15 ++++----
 drivers/net/pcs/pcs-rzn1-miic.c                    | 28 +++++++++++++++
 drivers/net/phy/phylink.c                          | 24 ++++++++++++-
 drivers/net/phy/qcom/at803x.c                      |  3 +-
 include/linux/phy.h                                |  1 +
 include/linux/phylink.h                            | 42 ++++++++++++++++++++++
 8 files changed, 110 insertions(+), 13 deletions(-)
---
base-commit: 0f37666d87d2dea42ec21776c3d562b7cbd71612
change-id: 20240126-rxc_bugfix-d47b3b1a374f

Best regards,
-- 
Romain Gantois <romain.gantois at bootlin.com>



From romain.gantois at bootlin.com  Wed Feb 21 05:04:18 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Wed, 21 Feb 2024 14:04:18 +0100
Subject: [PATCH net-next v4 1/7] net: phylink: add PHY_F_RXC_ALWAYS_ON to
 PHY dev flags
In-Reply-To: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
References: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
Message-ID: <20240221-rxc_bugfix-v4-1-4883ee1cc7b1@bootlin.com>

From: Russell King <linux at armlinux.org.uk>

Some MAC controllers (e.g. stmmac) require their connected PHY to
continuously provide a receive clock signal. This can cause issues in two
cases:

  1. The clock signal hasn't been started yet by the time the MAC driver
     initializes its hardware. This can make the initialization fail, as in
      the case of the rzn1 GMAC1 driver.
  2. The clock signal is cut during a power saving event. By the time the
     MAC is brought back up, the clock signal is still not active since
     phylink_start hasn't been called yet. This brings us back to case 1.

If a PHY driver reads this flag, it should ensure that the receive clock
signal is started as soon as possible, and that it isn't brought down when
the PHY goes into suspend.

Signed-off-by: Russell King <linux at armlinux.org.uk>
[rgantois: commit log]
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/phy/phylink.c | 10 +++++++++-
 include/linux/phy.h       |  1 +
 include/linux/phylink.h   |  4 ++++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 503fd7c40523..2bb583543dea 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1923,6 +1923,8 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
 static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,
 			      phy_interface_t interface)
 {
+	u32 flags = 0;
+
 	if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED ||
 		    (pl->cfg_link_an_mode == MLO_AN_INBAND &&
 		     phy_interface_mode_is_8023z(interface) && !pl->sfp_bus)))
@@ -1931,7 +1933,10 @@ static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,
 	if (pl->phydev)
 		return -EBUSY;
 
-	return phy_attach_direct(pl->netdev, phy, 0, interface);
+	if (pl->config->mac_requires_rxc)
+		flags |= PHY_F_RXC_ALWAYS_ON;
+
+	return phy_attach_direct(pl->netdev, phy, flags, interface);
 }
 
 /**
@@ -2034,6 +2039,9 @@ int phylink_fwnode_phy_connect(struct phylink *pl,
 		pl->link_config.interface = pl->link_interface;
 	}
 
+	if (pl->config->mac_requires_rxc)
+		flags |= PHY_F_RXC_ALWAYS_ON;
+
 	ret = phy_attach_direct(pl->netdev, phy_dev, flags,
 				pl->link_interface);
 	phy_device_free(phy_dev);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 2249cdb5957a..1fef852634bd 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -771,6 +771,7 @@ struct phy_device {
 
 /* Generic phy_device::dev_flags */
 #define PHY_F_NO_IRQ		0x80000000
+#define PHY_F_RXC_ALWAYS_ON	0x40000000
 
 static inline struct phy_device *to_phy_device(const struct device *dev)
 {
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 6ba411732a0d..019993e5f570 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -138,6 +138,9 @@ enum phylink_op_type {
  * @poll_fixed_state: if true, starts link_poll,
  *		      if MAC link is at %MLO_AN_FIXED mode.
  * @mac_managed_pm: if true, indicate the MAC driver is responsible for PHY PM.
+ * @mac_requires_rxc: if true, the MAC always requires a receive clock from PHY.
+ *                    The PHY driver should start the clock signal as soon as
+ *                    possible and avoid stopping it during suspend events.
  * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND
  * @get_fixed_state: callback to execute to determine the fixed link state,
  *		     if MAC link is at %MLO_AN_FIXED mode.
@@ -150,6 +153,7 @@ struct phylink_config {
 	enum phylink_op_type type;
 	bool poll_fixed_state;
 	bool mac_managed_pm;
+	bool mac_requires_rxc;
 	bool ovr_an_inband;
 	void (*get_fixed_state)(struct phylink_config *config,
 				struct phylink_link_state *state);

-- 
2.43.0



From romain.gantois at bootlin.com  Wed Feb 21 05:04:20 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Wed, 21 Feb 2024 14:04:20 +0100
Subject: [PATCH net-next v4 3/7] net: stmmac: don't rely on lynx_pcs
 presence to check for a PHY
In-Reply-To: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
References: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
Message-ID: <20240221-rxc_bugfix-v4-3-4883ee1cc7b1@bootlin.com>

From: Maxime Chevallier <maxime.chevallier at bootlin.com>

When initializing attached PHYs, there are some cases where we don't expect
any PHY to be connected. The logic uses conditions based on various local
PCS configuration, but also calls-in phylink_expects_phy() via
stmmac_init_phy(), which is enough to ensure we don't try to initialize a
PHY when using a Lynx PCS, as long as we have the phy_interface set to a
802.3z mode and are using inband negociation.

Drop the lynx check, making the stmmac generic code more pcs_lynx-agnostic.

Signed-off-by: Maxime Chevallier <maxime.chevallier at bootlin.com>
[rgantois: commit log]
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9159d93ceb03..47cd8666af43 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3959,8 +3959,7 @@ static int __stmmac_open(struct net_device *dev,
 	if (priv->hw->pcs != STMMAC_PCS_TBI &&
 	    priv->hw->pcs != STMMAC_PCS_RTBI &&
 	    (!priv->hw->xpcs ||
-	     xpcs_get_an_mode(priv->hw->xpcs, mode) != DW_AN_C73) &&
-	    !priv->hw->lynx_pcs) {
+	     xpcs_get_an_mode(priv->hw->xpcs, mode) != DW_AN_C73)) {
 		ret = stmmac_init_phy(dev);
 		if (ret) {
 			netdev_err(priv->dev,

-- 
2.43.0



From romain.gantois at bootlin.com  Wed Feb 21 05:04:19 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Wed, 21 Feb 2024 14:04:19 +0100
Subject: [PATCH net-next v4 2/7] net: phylink: add rxc_always_on flag to
 phylink_pcs
In-Reply-To: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
References: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
Message-ID: <20240221-rxc_bugfix-v4-2-4883ee1cc7b1@bootlin.com>

Some MAC drivers (e.g. stmmac) require a continuous receive clock signal to
be generated by a PCS that is handled by a standalone PCS driver.

Such a PCS driver does not have access to a PHY device, thus cannot check
the PHY_F_RXC_ALWAYS_ON flag. They cannot check max_requires_rxc in the
phylink config either, since it is a private member. Therefore, a new flag
is needed to signal to the PCS that it should keep the RX clock signal up
at all times.

Suggested-by: Russell King <linux at armlinux.org.uk>
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/phy/phylink.c | 14 ++++++++++++++
 include/linux/phylink.h   | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 2bb583543dea..dad7462996ab 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1042,6 +1042,20 @@ static void phylink_pcs_poll_start(struct phylink *pl)
 		mod_timer(&pl->link_poll, jiffies + HZ);
 }
 
+int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs)
+{
+	int ret = 0;
+
+	/* Signal to PCS driver that MAC requires RX clock for init */
+	if (pl->config->mac_requires_rxc)
+		pcs->rxc_always_on = true;
+
+	if (pcs->ops->pcs_pre_init)
+		ret = pcs->ops->pcs_pre_init(pcs);
+
+	return ret;
+}
+
 static void phylink_mac_config(struct phylink *pl,
 			       const struct phylink_link_state *state)
 {
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 019993e5f570..f6ef5bc82179 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -396,6 +396,10 @@ struct phylink_pcs_ops;
  * @phylink: pointer to &struct phylink_config
  * @neg_mode: provide PCS neg mode via "mode" argument
  * @poll: poll the PCS for link changes
+ * @rxc_always_on: The MAC driver requires the reference clock
+ *                 to always be on. Standalone PCS drivers which
+ *                 do not have access to a PHY device can check
+ *                 this instead of PHY_F_RXC_ALWAYS_ON.
  *
  * This structure is designed to be embedded within the PCS private data,
  * and will be passed between phylink and the PCS.
@@ -408,6 +412,7 @@ struct phylink_pcs {
 	struct phylink *phylink;
 	bool neg_mode;
 	bool poll;
+	bool rxc_always_on;
 };
 
 /**
@@ -422,6 +427,8 @@ struct phylink_pcs {
  * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
  * @pcs_link_up: program the PCS for the resolved link configuration
  *               (where necessary).
+ * @pcs_pre_init: configure PCS components necessary for MAC hardware
+ *                initialization e.g. RX clock for stmmac.
  */
 struct phylink_pcs_ops {
 	int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
@@ -441,6 +448,7 @@ struct phylink_pcs_ops {
 	void (*pcs_an_restart)(struct phylink_pcs *pcs);
 	void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode,
 			    phy_interface_t interface, int speed, int duplex);
+	int (*pcs_pre_init)(struct phylink_pcs *pcs);
 };
 
 #if 0 /* For kernel-doc purposes only. */
@@ -549,6 +557,34 @@ void pcs_an_restart(struct phylink_pcs *pcs);
  */
 void pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
 		 phy_interface_t interface, int speed, int duplex);
+
+/**
+ * pcs_pre_init() - Configure PCS components necessary for MAC initialization
+ * @pcs: a pointer to a &struct phylink_pcs.
+ *
+ * This function can be called by MAC drivers through the
+ * phylink_pcs_pre_init() wrapper, before their hardware is initialized. It
+ * should not be called after the link is brought up, as reconfiguring the PCS
+ * at this point could break the link.
+ *
+ * Some MAC devices require specific hardware initialization to be performed by
+ * their associated PCS device before they can properly initialize their own
+ * hardware. An example of this is the initialization of stmmac controllers,
+ * which requires an active REF_CLK signal to be provided by the PHY/PCS.
+ *
+ * By calling phylink_pcs_pre_init(), MAC drivers can ensure that the PCS is
+ * setup in a way that allows for successful hardware initialization.
+ *
+ * The specific configuration performed by pcs_pre_init() is dependent on the
+ * model of PCS and the requirements of the MAC device attached to it. PCS
+ * driver authors should consider whether their target device is to be used in
+ * conjunction with a MAC device whose driver calls phylink_pcs_pre_init(). MAC
+ * driver authors should document their requirements for the PCS
+ * pre-initialization.
+ *
+ */
+int pcs_config(struct phylink_pcs *pcs);
+
 #endif
 
 struct phylink *phylink_create(struct phylink_config *,
@@ -568,6 +604,8 @@ void phylink_disconnect_phy(struct phylink *);
 void phylink_mac_change(struct phylink *, bool up);
 void phylink_pcs_change(struct phylink_pcs *, bool up);
 
+int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs);
+
 void phylink_start(struct phylink *);
 void phylink_stop(struct phylink *);
 

-- 
2.43.0



From romain.gantois at bootlin.com  Wed Feb 21 05:04:21 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Wed, 21 Feb 2024 14:04:21 +0100
Subject: [PATCH net-next v4 4/7] net: stmmac: Support a generic PCS field
 in mac_device_info
In-Reply-To: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
References: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
Message-ID: <20240221-rxc_bugfix-v4-4-4883ee1cc7b1@bootlin.com>

Global stmmac support for early initialization of PCS devices requires a
generic PCS reference that can be passed to phylink_pcs_pre_init().
Currently, the mac_device_info struct contains only one PCS field, which is
specific to the Lynx model.

As PCS models are hardware-specific, it is more appropriate to have a
generic PCS field in the mac_device_info struct.

Refactor the lynx_pcs field into a generic phylink_pcs field.

Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h        | 2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 8 ++++----
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c   | 5 +----
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index a6fefe675ef1..f55cf09f0783 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -593,7 +593,7 @@ struct mac_device_info {
 	const struct stmmac_mmc_ops *mmc;
 	const struct stmmac_est_ops *est;
 	struct dw_xpcs *xpcs;
-	struct phylink_pcs *lynx_pcs; /* Lynx external PCS */
+	struct phylink_pcs *phylink_pcs;
 	struct mii_regs mii;	/* MII register Addresses */
 	struct mac_link link;
 	void __iomem *pcsr;     /* vpointer to device CSRs */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 68f85e4605cb..12b4a80ea3aa 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -479,9 +479,9 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
 			goto err_dvr_remove;
 		}
 
-		stpriv->hw->lynx_pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
-		if (IS_ERR(stpriv->hw->lynx_pcs)) {
-			ret = PTR_ERR(stpriv->hw->lynx_pcs);
+		stpriv->hw->phylink_pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
+		if (IS_ERR(stpriv->hw->phylink_pcs)) {
+			ret = PTR_ERR(stpriv->hw->phylink_pcs);
 			goto err_dvr_remove;
 		}
 	}
@@ -498,7 +498,7 @@ static void socfpga_dwmac_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct stmmac_priv *priv = netdev_priv(ndev);
-	struct phylink_pcs *pcs = priv->hw->lynx_pcs;
+	struct phylink_pcs *pcs = priv->hw->phylink_pcs;
 
 	stmmac_pltfr_remove(pdev);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 47cd8666af43..ec4f6377b5ee 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -944,10 +944,7 @@ static struct phylink_pcs *stmmac_mac_select_pcs(struct phylink_config *config,
 	if (priv->hw->xpcs)
 		return &priv->hw->xpcs->pcs;
 
-	if (priv->hw->lynx_pcs)
-		return priv->hw->lynx_pcs;
-
-	return NULL;
+	return priv->hw->phylink_pcs;
 }
 
 static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,

-- 
2.43.0



From romain.gantois at bootlin.com  Wed Feb 21 05:04:22 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Wed, 21 Feb 2024 14:04:22 +0100
Subject: [PATCH net-next v4 5/7] net: stmmac: Signal to PHY/PCS drivers to
 keep RX clock on
In-Reply-To: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
References: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
Message-ID: <20240221-rxc_bugfix-v4-5-4883ee1cc7b1@bootlin.com>

There is a reocurring issue with stmmac controllers where the MAC fails to
initialize its hardware if an RX clock signal isn't provided on the MAC/PHY
link.

This causes issues when PHY or PCS devices either go into suspend while
cutting the RX clock or do not bring the clock signal up early enough for
the MAC to initialize successfully.

Set the mac_requires_rxc flag in the stmmac phylink config so that PHY/PCS
drivers know to keep the RX clock up at all times.

Reported-by: Clark Wang <xiaoning.wang at nxp.com>
Link: https://lore.kernel.org/all/20230202081559.3553637-1-xiaoning.wang at nxp.com/
Reported-by: Cl?ment L?ger <clement.leger at bootlin.com>
Link: https://lore.kernel.org/linux-arm-kernel/20230116103926.276869-4-clement.leger at bootlin.com/
Suggested-by: Russell King <linux at armlinux.org.uk>
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ec4f6377b5ee..caf71a502ff2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1218,6 +1218,9 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 	priv->phylink_config.type = PHYLINK_NETDEV;
 	priv->phylink_config.mac_managed_pm = true;
 
+	/* Stmmac always requires an RX clock for hardware initialization */
+	priv->phylink_config.mac_requires_rxc = true;
+
 	mdio_bus_data = priv->plat->mdio_bus_data;
 	if (mdio_bus_data)
 		priv->phylink_config.ovr_an_inband =
@@ -3407,6 +3410,10 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
 	u32 chan;
 	int ret;
 
+	/* Make sure RX clock is enabled */
+	if (priv->hw->phylink_pcs)
+		phylink_pcs_pre_init(priv->phylink, priv->hw->phylink_pcs);
+
 	/* DMA initialization and SW reset */
 	ret = stmmac_init_dma_engine(priv);
 	if (ret < 0) {

-- 
2.43.0



From romain.gantois at bootlin.com  Wed Feb 21 05:04:23 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Wed, 21 Feb 2024 14:04:23 +0100
Subject: [PATCH net-next v4 6/7] net: phy: qcom: at803x: Avoid hibernating
 if MAC requires RX clock
In-Reply-To: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
References: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
Message-ID: <20240221-rxc_bugfix-v4-6-4883ee1cc7b1@bootlin.com>

From: Russell King <linux at armlinux.org.uk>

Stmmac controllers connected to an at803x PHY cannot resume properly after
suspend when WoL is enabled. This happens because the MAC requires an RX
clock generated by the PHY to initialize its hardware properly. But the RX
clock is cut when the PHY suspends and isn't brought up until the MAC
driver resumes the phylink.

Prevent the at803x PHY driver from going into suspend if the attached MAC
driver always requires an RX clock signal.

Reported-by: Clark Wang <xiaoning.wang at nxp.com>
Link: https://lore.kernel.org/all/20230202081559.3553637-1-xiaoning.wang at nxp.com/
Signed-off-by: Russell King <linux at armlinux.org.uk>
[rgantois: commit log]
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/phy/qcom/at803x.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/qcom/at803x.c b/drivers/net/phy/qcom/at803x.c
index 4717c59d51d0..2a221b81cf37 100644
--- a/drivers/net/phy/qcom/at803x.c
+++ b/drivers/net/phy/qcom/at803x.c
@@ -426,7 +426,8 @@ static int at803x_hibernation_mode_config(struct phy_device *phydev)
 	/* The default after hardware reset is hibernation mode enabled. After
 	 * software reset, the value is retained.
 	 */
-	if (!(priv->flags & AT803X_DISABLE_HIBERNATION_MODE))
+	if (!(priv->flags & AT803X_DISABLE_HIBERNATION_MODE) &&
+	    !(phydev->dev_flags & PHY_F_RXC_ALWAYS_ON))
 		return 0;
 
 	return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,

-- 
2.43.0



From romain.gantois at bootlin.com  Wed Feb 21 05:04:24 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Wed, 21 Feb 2024 14:04:24 +0100
Subject: [PATCH net-next v4 7/7] net: pcs: rzn1-miic: Init RX clock early
 if MAC requires it
In-Reply-To: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
References: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
Message-ID: <20240221-rxc_bugfix-v4-7-4883ee1cc7b1@bootlin.com>

The GMAC1 controller in the RZN1 IP requires the RX MII clock signal to be
started before it initializes its own hardware, thus before it calls
phylink_start.

Implement the pcs_pre_init() callback so that the RX clock signal can be
enabled early if necessary.

Reported-by: Cl?ment L?ger <clement.leger at bootlin.com>
Link: https://lore.kernel.org/linux-arm-kernel/20230116103926.276869-4-clement.leger at bootlin.com/
Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>
---
 drivers/net/pcs/pcs-rzn1-miic.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c
index d93f84fbb1fd..8a683c76a0f2 100644
--- a/drivers/net/pcs/pcs-rzn1-miic.c
+++ b/drivers/net/pcs/pcs-rzn1-miic.c
@@ -279,10 +279,38 @@ static int miic_validate(struct phylink_pcs *pcs, unsigned long *supported,
 	return -EINVAL;
 }
 
+static int miic_pre_init(struct phylink_pcs *pcs)
+{
+	struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs);
+	struct miic *miic = miic_port->miic;
+	u32 val, mask;
+
+	/* Start RX clock if required */
+	if (pcs->rxc_always_on) {
+		/* In MII through mode, the clock signals will be driven by the
+		 * external PHY, which might not be initialized yet. Set RMII
+		 * as default mode to ensure that a reference clock signal is
+		 * generated.
+		 */
+		miic_port->interface = PHY_INTERFACE_MODE_RMII;
+
+		val = FIELD_PREP(MIIC_CONVCTRL_CONV_MODE, CONV_MODE_RMII) |
+		      FIELD_PREP(MIIC_CONVCTRL_CONV_SPEED, CONV_MODE_100MBPS);
+		mask = MIIC_CONVCTRL_CONV_MODE | MIIC_CONVCTRL_CONV_SPEED;
+
+		miic_reg_rmw(miic, MIIC_CONVCTRL(miic_port->port), mask, val);
+
+		miic_converter_enable(miic, miic_port->port, 1);
+	}
+
+	return 0;
+}
+
 static const struct phylink_pcs_ops miic_phylink_ops = {
 	.pcs_validate = miic_validate,
 	.pcs_config = miic_config,
 	.pcs_link_up = miic_link_up,
+	.pcs_pre_init = miic_pre_init,
 };
 
 struct phylink_pcs *miic_create(struct device *dev, struct device_node *np)

-- 
2.43.0



From xiaobo55x at gmail.com  Wed Feb 21 05:08:19 2024
From: xiaobo55x at gmail.com (Haibo Xu)
Date: Wed, 21 Feb 2024 21:08:19 +0800
Subject: [PATCH v5 11/12] KVM: riscv: selftests: Change vcpu_has_ext to a
 common function
In-Reply-To: <2c96c61a-2685-4cee-9cef-963ed833bf92@rivosinc.com>
References: <cover.1705916069.git.haibo1.xu@intel.com> <68856b86a93a4188558e5d0ebac0dd6aac8e404c.1705916069.git.haibo1.xu@intel.com>
 <CAOnJCULwRTSnrQkR2o1P53R=tJ3TAxX+y+XRBesW6OFEzgFv2g@mail.gmail.com>
 <CAJve8om2oOLg5-wKX7m7cBTgzwqiMcb35x=nDi1edY8evXjyMw@mail.gmail.com> <2c96c61a-2685-4cee-9cef-963ed833bf92@rivosinc.com>
Message-ID: <CAJve8omCZxsiP1jF0n5SBh0_U6q7Exj5A1ACFahWpdBoxohaMA@mail.gmail.com>

On Wed, Feb 21, 2024 at 4:37?PM Atish Patra <atishp at rivosinc.com> wrote:
>
> On 2/20/24 18:13, Haibo Xu wrote:
> > On Wed, Feb 21, 2024 at 7:03?AM Atish Patra <atishp at atishpatra.org> wrote:
> >>
> >> On Mon, Jan 22, 2024 at 1:48?AM Haibo Xu <haibo1.xu at intel.com> wrote:
> >>>
> >>> Move vcpu_has_ext to the processor.c and rename it to __vcpu_has_ext
> >>> so that other test cases can use it for vCPU extension check.
> >>>
> >>> Signed-off-by: Haibo Xu <haibo1.xu at intel.com>
> >>> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> >>> ---
> >>>   tools/testing/selftests/kvm/include/riscv/processor.h |  2 ++
> >>>   tools/testing/selftests/kvm/lib/riscv/processor.c     | 10 ++++++++++
> >>>   tools/testing/selftests/kvm/riscv/get-reg-list.c      | 11 +----------
> >>>   3 files changed, 13 insertions(+), 10 deletions(-)
> >>>
> >>> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> >>> index b68b1b731a34..bd27e1c67579 100644
> >>> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> >>> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> >>> @@ -42,6 +42,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
> >>>   #define RISCV_ISA_EXT_REG(idx) __kvm_reg_id(KVM_REG_RISCV_ISA_EXT, \
> >>>                                               idx, KVM_REG_SIZE_ULONG)
> >>>
> >>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
> >>> +
> >>>   struct ex_regs {
> >>>          unsigned long ra;
> >>>          unsigned long sp;
> >>> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> >>> index 39a1e9902dec..dad73ce18164 100644
> >>> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> >>> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> >>> @@ -15,6 +15,16 @@
> >>>
> >>>   static vm_vaddr_t exception_handlers;
> >>>
> >>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> >>> +{
> >>> +       unsigned long value = 0;
> >>> +       int ret;
> >>> +
> >>> +       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> >>> +
> >>> +       return !ret && !!value;
> >>> +}
> >>> +
> >>
> >> Not sure what was the base patch on which this was rebased. The actual
> >> commit in the queue branch looks different.
> >>
> >
> > This patch set was based on 6.7-rc8.
> >
> >> https://github.com/kvm-riscv/linux/commit/5563517cc2012e3326411b360c9924d3f2706c8d
> >>
> >> Both seem to have the same bug though the tests fail now and require
> >> the following fix.
> >> The ext id should be uint64_t and we need to pass ext directly so that
> >> SBI extension tests can also pass.
> >>
> >
> > It's weird that 6.7-rc8 has already included Andrew's change on the ISA ext reg,
> > but this patch was not generated against his change.
> >
> > commit bdf6aa328f137e184b0fce607fd585354c3742f1
> > Author: Andrew Jones <ajones at ventanamicro.com>
> > Date:   Wed Dec 13 18:09:58 2023 +0100
> >
> >      RISC-V: KVM: selftests: Treat SBI ext regs like ISA ext regs
> >
> > Anyway, your changes were right. Please go ahead to include them when merging.
> >
>
> I am not sure what happened. Probably, a merge conflict issue.
>
> I just realized I forgot to copy paste another fix in arch timer
>
> +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
> @@ -85,7 +85,7 @@ struct kvm_vm *test_vm_create(void)
>          int nr_vcpus = test_args.nr_vcpus;
>
>          vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
> -       __TEST_REQUIRE(__vcpu_has_ext(vcpus[0], KVM_RISCV_ISA_EXT_SSTC),
> +       __TEST_REQUIRE(__vcpu_has_ext(vcpus[0],
> RISCV_ISA_EXT_REG(KVM_RISCV_ISA_EXT_SSTC)),
>

Right Fix!
Please let me know if I need to rebase this patch series on your tree
and resent it.

Thanks,
Haibo


From will at kernel.org  Wed Feb 21 05:08:37 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 21 Feb 2024 13:08:37 +0000
Subject: [PATCH rc v2] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <20240217132446.GJ13330@nvidia.com>
References: <0-v2-7988c2682634+261-smmu_cd_atomic_jgg@nvidia.com>
 <20240216120512.GA1841@willie-the-truck>
 <20240216123606.GA13330@nvidia.com>
 <CAKHBV27eBnCrnXeaoqONWksh89tfX1b0=yvLfTkxviU_wKG_mw@mail.gmail.com>
 <20240217132446.GJ13330@nvidia.com>
Message-ID: <20240221130837.GA7273@willie-the-truck>

On Sat, Feb 17, 2024 at 09:24:46AM -0400, Jason Gunthorpe wrote:
> On Sat, Feb 17, 2024 at 08:25:36PM +0800, Michael Shavit wrote:
> 
> > Calling arm_smmu_write_ctx_desc requires the CD which we get from the
> > mmu_notifiers list...which makes it a bit more complicated than
> > that.
> 
> @@ -404,9 +384,15 @@ static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
>                 goto err_free_bond;
>         }
>  
> +       ret = arm_smmu_write_ctx_desc(master, pasid, bond->smmu_mn->cd);
> +       if (ret)
> +               goto err_put_notifier;
> +

Please can you spin a v3 with this folded in?

Will


From p.zabel at pengutronix.de  Wed Feb 21 05:09:45 2024
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 21 Feb 2024 14:09:45 +0100
Subject: [PATCH v3 14/18] phy: cadence-torrent: add suspend and resume
 support
In-Reply-To: <20240102-j7200-pcie-s2r-v3-14-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
	 <20240102-j7200-pcie-s2r-v3-14-5c2e4a3fac1f@bootlin.com>
Message-ID: <c105bfa8567f9e76731f2b018f4ca3176357204d.camel@pengutronix.de>

On Do, 2024-02-15 at 16:17 +0100, Thomas Richard wrote:
> Add suspend and resume support.
> 
> The already_configured flag is cleared during the suspend stage to force
> the PHY initialization during the resume stage.
> 
> Based on the work of Th?o Lebrun <theo.lebrun at bootlin.com>
> 
> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
> ---
>  drivers/phy/cadence/phy-cadence-torrent.c | 54 +++++++++++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
> 
> diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
> index 52cadca4c07b..f8945a11e7ca 100644
> --- a/drivers/phy/cadence/phy-cadence-torrent.c
> +++ b/drivers/phy/cadence/phy-cadence-torrent.c
> @@ -3005,6 +3005,59 @@ static void cdns_torrent_phy_remove(struct platform_device *pdev)
>  	cdns_torrent_clk_cleanup(cdns_phy);
>  }
>  
> +static int cdns_torrent_phy_suspend_noirq(struct device *dev)
> +{
> +	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
> +	int i;
> +
> +	reset_control_assert(cdns_phy->phy_rst);
> +	reset_control_assert(cdns_phy->apb_rst);
> +	for (i = 0; i < cdns_phy->nsubnodes; i++)
> +		reset_control_assert(cdns_phy->phys[i].lnk_rst);
> +
> +	if (cdns_phy->already_configured)
> +		cdns_phy->already_configured = 0;
> +	else
> +		clk_disable_unprepare(cdns_phy->clk);
> +
> +	return 0;
> +}
> +
> +static int cdns_torrent_phy_resume_noirq(struct device *dev)
> +{
> +	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
> +	int node = cdns_phy->nsubnodes;
> +	int ret, i;
> +
> +	ret = cdns_torrent_clk(cdns_phy);
> +	if (ret)
> +		goto clk_cleanup;
> +
> +	/* Enable APB */
> +	reset_control_deassert(cdns_phy->apb_rst);
> +
> +	if (cdns_phy->nsubnodes > 1) {
> +		ret = cdns_torrent_phy_configure_multilink(cdns_phy);
> +		if (ret)
> +			goto put_lnk_rst;
> +	}
> +
> +	return 0;
> +
> +put_lnk_rst:
> +	for (i = 0; i < node; i++)
> +		reset_control_assert(cdns_phy->phys[i].lnk_rst);

The same cleanup is found in probe. Would it be cleaner to move this
into cdns_torrent_phy_configure_multilink() instead of duplicating it
here?

> +	reset_control_assert(cdns_phy->apb_rst);
> +	clk_disable_unprepare(cdns_phy->clk);
> +clk_cleanup:
> +	cdns_torrent_clk_cleanup(cdns_phy);

This calls of_clk_del_provider(), seems misplaced here.

regards
Philipp



From andy at kernel.org  Wed Feb 21 05:13:20 2024
From: andy at kernel.org (Andy Shevchenko)
Date: Wed, 21 Feb 2024 15:13:20 +0200
Subject: [PATCH v3 02/18] pinctrl: pinctrl-single: remove dead code in
 suspend() and resume() callbacks
In-Reply-To: <a2c3c5b9-79a3-4793-892c-b1ab79b71c7d@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-2-5c2e4a3fac1f@bootlin.com>
 <Zc4tedAhqYX3bQcw@smile.fi.intel.com>
 <78add459-a96a-46c6-83ff-e2657d4d3db4@bootlin.com>
 <Zc96dSff5Y-dufrJ@smile.fi.intel.com>
 <a2c3c5b9-79a3-4793-892c-b1ab79b71c7d@bootlin.com>
Message-ID: <ZdX28EJ9LtDWfVmH@smile.fi.intel.com>

On Wed, Feb 21, 2024 at 12:01:43PM +0100, Thomas Richard wrote:
> On 2/16/24 16:08, Andy Shevchenko wrote:
> > On Fri, Feb 16, 2024 at 08:59:47AM +0100, Thomas Richard wrote:
> >> On 2/15/24 16:27, Andy Shevchenko wrote:
> >>> On Thu, Feb 15, 2024 at 04:17:47PM +0100, Thomas Richard wrote:
> >>>> No need to check the pointer returned by platform_get_drvdata(), as
> >>>> platform_set_drvdata() is called during the probe.
> >>>
> >>> This patch should go _after_ the next one, otherwise the commit message doesn't
> >>> tell full story and the code change bring a potential regression.
> >>
> >> Hello Andy,
> >>
> >> I'm ok to move this patch after the next one.
> >> But for my understanding, could you explain me why changing the order is
> >> important in this case ?
> > 
> > Old PM calls obviously can be called in different circumstances and these
> > checks are important.
> > 
> > Just squash these two patches to avoid additional churn and we are done.
> 
> You mean invert the order instead of squash.

Either would work, but see how much churn in terms of changing just changed
lines it adds.

-- 
With Best Regards,
Andy Shevchenko




From p.zabel at pengutronix.de  Wed Feb 21 05:14:51 2024
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 21 Feb 2024 14:14:51 +0100
Subject: [PATCH v14 3/3] hwmon: (aspeed-g6-pwm-tacho): Support for
 ASPEED g6 PWM/Fan tach
In-Reply-To: <20240221104025.1306227-4-billy_tsai@aspeedtech.com>
References: <20240221104025.1306227-1-billy_tsai@aspeedtech.com>
	 <20240221104025.1306227-4-billy_tsai@aspeedtech.com>
Message-ID: <d203819f09749f0ff9e08a80471b7fed3dad67a8.camel@pengutronix.de>

On Mi, 2024-02-21 at 18:40 +0800, Billy Tsai wrote:
> The driver support two functions: PWM and Tachometer. The PWM feature can
> handle up to 16 output ports, while the Tachometer can monitor to up to 16
> input ports as well. This driver implements them by exposing two kernel
> subsystems: PWM and HWMON. The PWM subsystem can be utilized alongside
> existing drivers for controlling elements such as fans (pwm-fan.c),
> beepers (pwm-beeper.c) and so on. Through the HWMON subsystem, the driver
> provides sysfs interfaces for fan.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  Documentation/hwmon/aspeed-g6-pwm-tach.rst |  26 +
>  Documentation/hwmon/index.rst              |   1 +
>  drivers/hwmon/Kconfig                      |  11 +
>  drivers/hwmon/Makefile                     |   1 +
>  drivers/hwmon/aspeed-g6-pwm-tach.c         | 549 +++++++++++++++++++++
>  5 files changed, 588 insertions(+)
>  create mode 100644 Documentation/hwmon/aspeed-g6-pwm-tach.rst
>  create mode 100644 drivers/hwmon/aspeed-g6-pwm-tach.c
> 
[...]
> diff --git a/drivers/hwmon/aspeed-g6-pwm-tach.c b/drivers/hwmon/aspeed-g6-pwm-tach.c
> new file mode 100644
> index 000000000000..597b3b019d49
> --- /dev/null
> +++ b/drivers/hwmon/aspeed-g6-pwm-tach.c
> @@ -0,0 +1,549 @@
[...]
> +static void aspeed_pwm_tach_reset_assert(void *data)
> +{
> +	struct reset_control *rst = data;
> +
> +	reset_control_assert(rst);
> +}
> +
> +static int aspeed_pwm_tach_probe(struct platform_device *pdev)
> +{
[...]
> +	priv->reset = devm_reset_control_get_exclusive(dev, NULL);
> +	if (IS_ERR(priv->reset))
> +		return dev_err_probe(dev, PTR_ERR(priv->reset),
> +				     "Couldn't get reset control\n");
> +
> +	ret = reset_control_deassert(priv->reset);
> +	if (ret)
> +		return dev_err_probe(dev, ret,
> +				     "Couldn't deassert reset control\n");
> +	ret = devm_add_action_or_reset(dev, aspeed_pwm_tach_reset_assert,
> +				       priv->reset);
[...]
> +}
> +
> +static int aspeed_pwm_tach_remove(struct platform_device *pdev)
> +{
> +	struct aspeed_pwm_tach_data *priv = platform_get_drvdata(pdev);
> +
> +	reset_control_assert(priv->reset);

This is already done by aspeed_pwm_tach_reset_assert(), looks like
aspeed_pwm_tach_remove() can be removed. With that, priv->reset can
become a local variable in aspeed_pwm_tach_probe().

regards
Philipp


From lkp at intel.com  Wed Feb 21 05:14:52 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 21 Feb 2024 21:14:52 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS
 78b6f8e7379b5399d1804f0852bb2ddabd049019
Message-ID: <202402212149.XwYiTHwh-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: 78b6f8e7379b5399d1804f0852bb2ddabd049019  dtc: Enable dtc interrupt_provider check

elapsed time: 950m

configs tested: 162
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                        nsimosci_defconfig   gcc  
arc                   randconfig-001-20240221   gcc  
arc                   randconfig-002-20240221   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                                 defconfig   clang
arm                   randconfig-001-20240221   clang
arm                   randconfig-002-20240221   clang
arm                   randconfig-003-20240221   gcc  
arm                   randconfig-004-20240221   clang
arm                           stm32_defconfig   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240221   gcc  
arm64                 randconfig-002-20240221   gcc  
arm64                 randconfig-003-20240221   gcc  
arm64                 randconfig-004-20240221   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240221   gcc  
csky                  randconfig-002-20240221   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
hexagon               randconfig-001-20240221   clang
hexagon               randconfig-002-20240221   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-002-20240221   clang
i386                                defconfig   clang
i386                  randconfig-002-20240221   clang
i386                  randconfig-003-20240221   clang
i386                  randconfig-006-20240221   clang
i386                  randconfig-012-20240221   clang
i386                  randconfig-014-20240221   clang
i386                  randconfig-016-20240221   clang
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                        allyesconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240221   gcc  
loongarch             randconfig-002-20240221   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                             allmodconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                       lemote2f_defconfig   gcc  
mips                          malta_defconfig   gcc  
mips                      pic32mzda_defconfig   gcc  
nios2                            alldefconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240221   gcc  
nios2                 randconfig-002-20240221   gcc  
openrisc                         allmodconfig   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
openrisc                  or1klitex_defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                randconfig-001-20240221   gcc  
parisc                randconfig-002-20240221   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc               randconfig-001-20240221   gcc  
powerpc               randconfig-002-20240221   gcc  
powerpc               randconfig-003-20240221   gcc  
powerpc                         wii_defconfig   gcc  
powerpc64             randconfig-001-20240221   gcc  
powerpc64             randconfig-002-20240221   gcc  
powerpc64             randconfig-003-20240221   gcc  
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                 randconfig-001-20240221   clang
riscv                 randconfig-002-20240221   gcc  
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240221   clang
s390                  randconfig-002-20240221   clang
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                    randconfig-001-20240221   gcc  
sh                    randconfig-002-20240221   gcc  
sh                          sdk7780_defconfig   gcc  
sh                        sh7763rdp_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                            allyesconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240221   gcc  
sparc64               randconfig-002-20240221   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                    randconfig-001-20240221   gcc  
um                    randconfig-002-20240221   clang
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-002-20240221   gcc  
x86_64       buildonly-randconfig-003-20240221   gcc  
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240221   gcc  
x86_64                randconfig-002-20240221   gcc  
x86_64                randconfig-003-20240221   gcc  
x86_64                randconfig-004-20240221   gcc  
x86_64                randconfig-005-20240221   gcc  
x86_64                randconfig-006-20240221   gcc  
x86_64                randconfig-012-20240221   gcc  
x86_64                randconfig-014-20240221   gcc  
x86_64                randconfig-015-20240221   gcc  
x86_64                randconfig-016-20240221   gcc  
x86_64                randconfig-071-20240221   gcc  
x86_64                randconfig-072-20240221   gcc  
x86_64                randconfig-073-20240221   gcc  
x86_64                randconfig-074-20240221   gcc  
x86_64                randconfig-076-20240221   gcc  
x86_64                          rhel-8.3-rust   clang
x86_64                               rhel-8.3   gcc  
xtensa                            allnoconfig   gcc  
xtensa                           allyesconfig   gcc  
xtensa                generic_kc705_defconfig   gcc  
xtensa                randconfig-001-20240221   gcc  
xtensa                randconfig-002-20240221   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From mripard at kernel.org  Wed Feb 21 05:16:18 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Wed, 21 Feb 2024 13:16:18 +0000
Subject: [PATCH 1/3] drm/sun4i: Unify sun8i_*_layer structs
In-Reply-To: <20240216190430.1374132-2-megi@xff.cz>
References: <20240216190430.1374132-2-megi@xff.cz>
Message-ID: <ae3aed3ae64fb4d3ba1f3a063c3b1733@kernel.org>

On Fri, 16 Feb 2024 20:04:24 +0100, Ond??ej Jirman wrote:
> From: Ondrej Jirman <megi at xff.cz>
> 
> These structs are identical, use a single struct to represent private
> data for the DRM plane. This is a preparation for configuring layer
> routing from the CRTC (mixer) instead of current approach of setting
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From mripard at kernel.org  Wed Feb 21 05:17:10 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Wed, 21 Feb 2024 13:17:10 +0000
Subject: [PATCH 2/3] drm/sun4i: Add more parameters to sunxi_engine
 commit callback
In-Reply-To: <20240216190430.1374132-3-megi@xff.cz>
References: <20240216190430.1374132-3-megi@xff.cz>
Message-ID: <ce9b5e36483676425eeff69c09b28671@kernel.org>

On Fri, 16 Feb 2024 20:04:25 +0100, Ond??ej Jirman wrote:
> From: Ondrej Jirman <megi at xff.cz>
> 
> These will be needed later on when we move layer configuration to
> crtc update.
> 
> 
> [ ... ]

Reviewed-by: Maxime Ripard <mripard at kernel.org>

Thanks!
Maxime


From will at kernel.org  Wed Feb 21 05:21:02 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 21 Feb 2024 13:21:02 +0000
Subject: [PATCH v9 4/5] iommu/arm-smmu: add ACTLR data and support for
 SM8550
In-Reply-To: <201fef09-50ab-436b-af63-4535c7510d15@quicinc.com>
References: <20240123144543.9405-1-quic_bibekkum@quicinc.com>
 <20240123144543.9405-5-quic_bibekkum@quicinc.com>
 <20240213134714.GC28926@willie-the-truck>
 <201fef09-50ab-436b-af63-4535c7510d15@quicinc.com>
Message-ID: <20240221132101.GB7273@willie-the-truck>

On Wed, Feb 21, 2024 at 02:25:26PM +0530, Bibek Kumar Patro wrote:
> On 2/13/2024 7:17 PM, Will Deacon wrote:
> > On Tue, Jan 23, 2024 at 08:15:42PM +0530, Bibek Kumar Patro wrote:
> > > Add ACTLR data table for SM8550 along with support for
> > > same including SM8550 specific implementation operations.
> > > 
> > > Signed-off-by: Bibek Kumar Patro <quic_bibekkum at quicinc.com>
> > > ---
> > >   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 90 ++++++++++++++++++++++
> > >   1 file changed, 90 insertions(+)
> > > 
> > > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > > index 6004c6d9a7b2..db15b1eade97 100644
> > > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > > @@ -23,6 +23,86 @@
> > > 
> > >   #define CPRE			(1 << 1)
> > >   #define CMTLB			(1 << 0)
> > > +#define PREFETCH_SHIFT		8
> > > +#define PREFETCH_DEFAULT	0
> > > +#define PREFETCH_SHALLOW	(1 << PREFETCH_SHIFT)
> > > +#define PREFETCH_MODERATE	(2 << PREFETCH_SHIFT)
> > > +#define PREFETCH_DEEP		(3 << PREFETCH_SHIFT)
> > > +#define PREFETCH_SWITCH_GFX	(5 << 3)
> > > +
> > > +static const struct actlr_config sm8550_apps_actlr_cfg[] = {
> > > +	{ 0x18a0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
> > > +	{ 0x18e0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
> > > +	{ 0x0800, 0x0020, PREFETCH_DEFAULT | CMTLB },
> > > +	{ 0x1800, 0x00c0, PREFETCH_DEFAULT | CMTLB },
> > > +	{ 0x1820, 0x0000, PREFETCH_DEFAULT | CMTLB },
> > > +	{ 0x1860, 0x0000, PREFETCH_DEFAULT | CMTLB },
> > > +	{ 0x0c01, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> > > +	{ 0x0c02, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> > > +	{ 0x0c03, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> > > +	{ 0x0c04, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> > > +	{ 0x0c05, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> > > +	{ 0x0c06, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
> > 
> > [...]
> > 
> > Isn't this effectively hard-coding the topology of the SoC in the driver?
> > Wouldn't it better describing higher-level prefetch properties in the DT
> > nodes corresponding to the upstream devices?
> 
> Since prefetch data stored in this table represent settings for the
> ACTLR register, and doesn't exactly define the hardware (So in this
> manner prefetch data won't exactly be a part of soc topology ?).

The first two columns of the table are StreamID/Mask pairs, no? How is that
_not_ the SoC topology? I really think it would be better to define some
high-level prefetch properties in the DT binding which can be put on the
master nodes.

> So it seemed apt not to use the device tree for storing the prefetch
> property. Hence we reverted from the DT approach (initial proposal in
> RFC to piggyback on iommus property to store prefetch settings) back to use
> driver for storing this data.
> 
> Some drivers use the same approach for storing their platform specific
> data. Examples being
> drivers/phy/qualcomm/phy-qcom-qmp-combo.c
> drivers/soc/qcom/llcc-qcom.c
> These drivers were taken as reference for storing platform specific ACTLR
> data.

I don't know anything about those drivers, but on the SMMU side we already
have ways to describe the topology in the DT and the driver is using them,
so I'm struggling to see the need to add these tables as well.

But as I said before, if Robin and the DT folks prefer this approach,
then I won't get in the way.

Will


From p.zabel at pengutronix.de  Wed Feb 21 05:21:23 2024
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 21 Feb 2024 14:21:23 +0100
Subject: [PATCH v3 4/7] ASoC: codecs: Add RK3308 internal audio codec
 driver
In-Reply-To: <20240221-rk3308-audio-codec-v3-4-dfa34abfcef6@bootlin.com>
References: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
	 <20240221-rk3308-audio-codec-v3-4-dfa34abfcef6@bootlin.com>
Message-ID: <09c275d0f0a1bf85f37635d9570514e8fc631e72.camel@pengutronix.de>

On Mi, 2024-02-21 at 11:22 +0100, Luca Ceresoli wrote:
> Add driver for the internal audio codec of the Rockchip RK3308 SoC.
> 
> Initially based on the vendor kernel driver [0], with lots of cleanups,
> fixes, improvements, conversion to DAPM and removal of some features.
> 
> [0] https://github.com/rockchip-linux/kernel/blob/develop-4.19/sound/soc/codecs/rk3308_codec.c
> 
> Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
>
[...]
> diff --git a/sound/soc/codecs/rk3308_codec.c b/sound/soc/codecs/rk3308_codec.c
> new file mode 100644
> index 000000000000..61bfb75f92a3
> --- /dev/null
> +++ b/sound/soc/codecs/rk3308_codec.c
> @@ -0,0 +1,993 @@
[...]
> +static int rk3308_codec_platform_probe(struct platform_device *pdev)
> +{
[...]
> +	rk3308->reset = devm_reset_control_get(&pdev->dev, "codec");
> +	if (IS_ERR(rk3308->reset)) {
> +		err = PTR_ERR(rk3308->reset);
> +		if (err != -ENOENT)
> +			return err;
> +
> +		dev_dbg(&pdev->dev, "No reset control found\n");
> +		rk3308->reset = NULL;
> +	}

Please use devm_reset_control_get_optional_exclusive(). That already
returns NULL instead of -ENOENT if the reset control is not specified
in the device tree. Then dev_err_probe() can be used to report errors.


regards
Philipp


From lukasz.luba at arm.com  Wed Feb 21 05:28:48 2024
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Wed, 21 Feb 2024 13:28:48 +0000
Subject: [PATCH v5 0/5] Rework system pressure interface to the scheduler
In-Reply-To: <20240220145947.1107937-1-vincent.guittot@linaro.org>
References: <20240220145947.1107937-1-vincent.guittot@linaro.org>
Message-ID: <4e9603e9-4127-43f1-92be-6c2b59ff2fe0@arm.com>

Hi Vincent,

On 2/20/24 14:59, Vincent Guittot wrote:
> Following the consolidation and cleanup of CPU capacity in [1], this serie
> reworks how the scheduler gets the pressures on CPUs. We need to take into
> account all pressures applied by cpufreq on the compute capacity of a CPU
> for dozens of ms or more and not only cpufreq cooling device or HW
> mitigiations. We split the pressure applied on CPU's capacity in 2 parts:
> - one from cpufreq and freq_qos
> - one from HW high freq mitigiation.
> 
> The next step will be to add a dedicated interface for long standing
> capping of the CPU capacity (i.e. for seconds or more) like the
> scaling_max_freq of cpufreq sysfs. The latter is already taken into
> account by this serie but as a temporary pressure which is not always the
> best choice when we know that it will happen for seconds or more.
> 
> [1] https://lore.kernel.org/lkml/20231211104855.558096-1-vincent.guittot at linaro.org/
> 
> Change since v4:
> - Add READ_ONCE() in cpufreq_get_pressure()
> - Add ack and reviewed tags
> 
> Change since v3:
> - Fix uninitialized variables in cpufreq_update_pressure()
> 
> Change since v2:
> - Rework cpufreq_update_pressure()
> 
> Change since v1:
> - Use struct cpufreq_policy as parameter of cpufreq_update_pressure()
> - Fix typos and comments
> - Make sched_thermal_decay_shift boot param as deprecated
> 
> Vincent Guittot (5):
>    cpufreq: Add a cpufreq pressure feedback for the scheduler
>    sched: Take cpufreq feedback into account
>    thermal/cpufreq: Remove arch_update_thermal_pressure()
>    sched: Rename arch_update_thermal_pressure into
>      arch_update_hw_pressure
>    sched/pelt: Remove shift of thermal clock
> 
>   .../admin-guide/kernel-parameters.txt         |  1 +
>   arch/arm/include/asm/topology.h               |  6 +-
>   arch/arm64/include/asm/topology.h             |  6 +-
>   drivers/base/arch_topology.c                  | 26 ++++----
>   drivers/cpufreq/cpufreq.c                     | 36 +++++++++++
>   drivers/cpufreq/qcom-cpufreq-hw.c             |  4 +-
>   drivers/thermal/cpufreq_cooling.c             |  3 -
>   include/linux/arch_topology.h                 |  8 +--
>   include/linux/cpufreq.h                       | 10 +++
>   include/linux/sched/topology.h                |  8 +--
>   .../{thermal_pressure.h => hw_pressure.h}     | 14 ++---
>   include/trace/events/sched.h                  |  2 +-
>   init/Kconfig                                  | 12 ++--
>   kernel/sched/core.c                           |  8 +--
>   kernel/sched/fair.c                           | 63 +++++++++----------
>   kernel/sched/pelt.c                           | 18 +++---
>   kernel/sched/pelt.h                           | 16 ++---
>   kernel/sched/sched.h                          | 22 +------
>   18 files changed, 144 insertions(+), 119 deletions(-)
>   rename include/trace/events/{thermal_pressure.h => hw_pressure.h} (55%)
> 


The code looks good and works as expected. The time delays in those
old mechanisms that were important to me are good now. The boost is
handled, cpufreq capping from sysfs - all good. Also the last patch
which removes the shift and makes it obsolete. Thanks!

Feel free to add to all patches:

Reviewed-by: Lukasz Luba <lukasz.luba at arm.com>
Tested-by: Lukasz Luba <lukasz.luba at arm.com>

Regards,
Lukasz


From linus.walleij at linaro.org  Wed Feb 21 05:29:37 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 14:29:37 +0100
Subject: [GIT PULL] Gemini DTS updates for v6.9
Message-ID: <CACRpkdYQv9cyCZyjgQB4FTrxek9Hfu4EZ3syfHqHF7P6gzddvA@mail.gmail.com>

Hi SoC folks,

these are some Gemini DTS updates for the v6.9 kernel.
Details in the signed tag!

Please pull it in.

Yours,
Linus Walleij

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git
tags/gemini-dts-v6.9

for you to fetch changes up to 5ee18186a0595a2327b71e5964ebf52834bbd047:

  ARM: dts: gemini: Fix switch node names on Vitesse switches
(2024-02-21 14:22:53 +0100)

----------------------------------------------------------------
Gemini DTS changes for the v6.9 kernel:

- Fix the node names of the DSA switch in DIR-685.
- Fix the node names of the Vitesse DSA switches.
- Fix up the Wiligear compatible strings
- Use KEY_RESTART where applicable.

----------------------------------------------------------------
Linus Walleij (4):
      ARM: dts: gemini: Fix switch node names in the DIR-685
      ARM: dts: gemini: Fix wiligear compatible strings
      ARM: dts: gemini: Map reset keys to KEY_RESTART
      ARM: dts: gemini: Fix switch node names on Vitesse switches

 arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts | 30 +++++++++++------------
 arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts |  4 +--
 arch/arm/boot/dts/gemini/gemini-sl93512r.dts      | 16 ++++++------
 arch/arm/boot/dts/gemini/gemini-sq201.dts         | 16 ++++++------
 arch/arm/boot/dts/gemini/gemini-wbd111.dts        |  6 ++---
 arch/arm/boot/dts/gemini/gemini-wbd222.dts        |  6 ++---
 6 files changed, 39 insertions(+), 39 deletions(-)


From apatel at ventanamicro.com  Wed Feb 21 05:32:37 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 21 Feb 2024 19:02:37 +0530
Subject: [PATCH v13 03/13] irqchip/riscv-intc: Add support for RISC-V AIA
In-Reply-To: <87cysrigud.ffs@tglx>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-4-apatel@ventanamicro.com> <87cysrigud.ffs@tglx>
Message-ID: <CAK9=C2VwFJG0XDkDt5zrUT-xYatZ7V7vRwvV=bhLx0P73RzzAw@mail.gmail.com>

On Tue, Feb 20, 2024 at 3:43?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
>
> > The RISC-V advanced interrupt architecture (AIA) extends the per-HART
> > local interrupts in following ways:
> > 1. Minimum 64 local interrupts for both RV32 and RV64
> > 2. Ability to process multiple pending local interrupts in same
> >    interrupt handler
> > 3. Priority configuration for each local interrupts
> > 4. Special CSRs to configure/access the per-HART MSI controller
> >
> > We add support for #1 and #2 described above in the RISC-V intc
> > driver.
>
> S/We add/Add/

Okay, I will update.

>
> > +static asmlinkage void riscv_intc_aia_irq(struct pt_regs *regs)
> > +{
> > +     unsigned long topi;
> > +
> > +     while ((topi = csr_read(CSR_TOPI)))
> > +             generic_handle_domain_irq(intc_domain,
> > +                                       topi >> TOPI_IID_SHIFT);
>
> Please let it stick out. You got 100 characters. All over the place.

Okay, I will update.

Regards,
Anup


From apatel at ventanamicro.com  Wed Feb 21 05:35:52 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 21 Feb 2024 19:05:52 +0530
Subject: [PATCH v13 02/13] irqchip/sifive-plic: Improve locking safety by
 using irqsave/irqrestore
In-Reply-To: <87frxnigxk.ffs@tglx>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-3-apatel@ventanamicro.com> <87frxnigxk.ffs@tglx>
Message-ID: <CAK9=C2VFksO054kVVHkrBRyZqte8Q4Gpup97VhLBRDCbOyQdqQ@mail.gmail.com>

On Tue, Feb 20, 2024 at 3:41?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> > Now that PLIC driver is probed as a regular platform driver, the lock
> > dependency validator complains about the safety of handler->enable_lock
> > usage:
> >
> > [    0.956775]  Possible interrupt unsafe locking scenario:
> >
> > [    0.956998]        CPU0                    CPU1
> > [    0.957247]        ----                    ----
> > [    0.957439]   lock(&handler->enable_lock);
> > [    0.957607]                                local_irq_disable();
> > [    0.957793]                                lock(&irq_desc_lock_class);
> > [    0.958021]                                lock(&handler->enable_lock);
> > [    0.958246]   <Interrupt>
> > [    0.958342]     lock(&irq_desc_lock_class);
> > [    0.958501]
> >                 *** DEADLOCK ***
> >
> > To address above, let's use raw_spin_lock_irqsave/unlock_irqrestore()
> > instead of raw_spin_lock/unlock().
>
> s/let's//

Okay, I will update.

Regards,
Anup


From gregkh at linuxfoundation.org  Wed Feb 21 05:05:02 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 21 Feb 2024 14:05:02 +0100
Subject: [PATCH 5.15 251/476] perf cs-etm: Bump minimum OpenCSD version to ensure a bugfix is present
In-Reply-To: <20240221130007.738356493@linuxfoundation.org>
References: <20240221130007.738356493@linuxfoundation.org>
Message-ID: <20240221130017.136027448@linuxfoundation.org>

5.15-stable review patch.  If anyone has any objections, please let me know.

------------------

From: James Clark <james.clark at arm.com>

[ Upstream commit 2dbba30fd69b604802a9535b74bddb5bcca23793 ]

Since commit d927ef5004ef ("perf cs-etm: Add exception level consistency
check"), the exception that was added to Perf will be triggered unless
the following bugfix from OpenCSD is present:

 - _Version 1.2.1_:
  - __Bugfix__:
    ETM4x / ETE - output of context elements to client can in some
    circumstances be delayed until after subsequent atoms have been
    processed leading to incorrect memory decode access via the client
    callbacks. Fixed to flush context elements immediately they are
    committed.

Rather than remove the assert and silently fail, just increase the
minimum version requirement to avoid hard to debug issues and
regressions.

Reviewed-by: Ian Rogers <irogers at google.com>
Signed-off-by: James Clark <james.clark at arm.com>
Tested-by: Leo Yan <leo.yan at linaro.org>
Cc: John Garry <john.g.garry at oracle.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Link: https://lore.kernel.org/r/20230901133716.677499-1-james.clark at arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme at redhat.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 tools/build/feature/test-libopencsd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/build/feature/test-libopencsd.c b/tools/build/feature/test-libopencsd.c
index eb6303ff446e..4cfcef9da3e4 100644
--- a/tools/build/feature/test-libopencsd.c
+++ b/tools/build/feature/test-libopencsd.c
@@ -4,9 +4,9 @@
 /*
  * Check OpenCSD library version is sufficient to provide required features
  */
-#define OCSD_MIN_VER ((1 << 16) | (1 << 8) | (1))
+#define OCSD_MIN_VER ((1 << 16) | (2 << 8) | (1))
 #if !defined(OCSD_VER_NUM) || (OCSD_VER_NUM < OCSD_MIN_VER)
-#error "OpenCSD >= 1.1.1 is required"
+#error "OpenCSD >= 1.2.1 is required"
 #endif
 
 int main(void)
-- 
2.43.0





From thomas.richard at bootlin.com  Wed Feb 21 05:41:12 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Wed, 21 Feb 2024 14:41:12 +0100
Subject: [PATCH v3 14/18] phy: cadence-torrent: add suspend and resume
 support
In-Reply-To: <c105bfa8567f9e76731f2b018f4ca3176357204d.camel@pengutronix.de>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-14-5c2e4a3fac1f@bootlin.com>
 <c105bfa8567f9e76731f2b018f4ca3176357204d.camel@pengutronix.de>
Message-ID: <113b7f2e-1313-4ebf-a403-e5fcae8f01ca@bootlin.com>

On 2/21/24 14:09, Philipp Zabel wrote:
> On Do, 2024-02-15 at 16:17 +0100, Thomas Richard wrote:
>> Add suspend and resume support.
>>
>> The already_configured flag is cleared during the suspend stage to force
>> the PHY initialization during the resume stage.
>>
>> Based on the work of Th?o Lebrun <theo.lebrun at bootlin.com>
>>
>> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
>> ---
>>  drivers/phy/cadence/phy-cadence-torrent.c | 54 +++++++++++++++++++++++++++++++
>>  1 file changed, 54 insertions(+)
>>
>> diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
>> index 52cadca4c07b..f8945a11e7ca 100644
>> --- a/drivers/phy/cadence/phy-cadence-torrent.c
>> +++ b/drivers/phy/cadence/phy-cadence-torrent.c
>> @@ -3005,6 +3005,59 @@ static void cdns_torrent_phy_remove(struct platform_device *pdev)
>>  	cdns_torrent_clk_cleanup(cdns_phy);
>>  }
>>  
>> +static int cdns_torrent_phy_suspend_noirq(struct device *dev)
>> +{
>> +	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
>> +	int i;
>> +
>> +	reset_control_assert(cdns_phy->phy_rst);
>> +	reset_control_assert(cdns_phy->apb_rst);
>> +	for (i = 0; i < cdns_phy->nsubnodes; i++)
>> +		reset_control_assert(cdns_phy->phys[i].lnk_rst);
>> +
>> +	if (cdns_phy->already_configured)
>> +		cdns_phy->already_configured = 0;
>> +	else
>> +		clk_disable_unprepare(cdns_phy->clk);
>> +
>> +	return 0;
>> +}
>> +
>> +static int cdns_torrent_phy_resume_noirq(struct device *dev)
>> +{
>> +	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
>> +	int node = cdns_phy->nsubnodes;
>> +	int ret, i;
>> +
>> +	ret = cdns_torrent_clk(cdns_phy);
>> +	if (ret)
>> +		goto clk_cleanup;
>> +
>> +	/* Enable APB */
>> +	reset_control_deassert(cdns_phy->apb_rst);
>> +
>> +	if (cdns_phy->nsubnodes > 1) {
>> +		ret = cdns_torrent_phy_configure_multilink(cdns_phy);
>> +		if (ret)
>> +			goto put_lnk_rst;
>> +	}
>> +
>> +	return 0;
>> +
>> +put_lnk_rst:
>> +	for (i = 0; i < node; i++)
>> +		reset_control_assert(cdns_phy->phys[i].lnk_rst);
> 
> The same cleanup is found in probe. Would it be cleaner to move this
> into cdns_torrent_phy_configure_multilink() instead of duplicating it
> here?

Hello Philipp,

Yes I could, but from my point of view, it would not be cleaner.
This cleanup is called from many places in the probe:
-
https://elixir.bootlin.com/linux/v6.8-rc5/source/drivers/phy/cadence/phy-cadence-torrent.c#L2948
-
https://elixir.bootlin.com/linux/v6.8-rc5/source/drivers/phy/cadence/phy-cadence-torrent.c#L2954
-
https://elixir.bootlin.com/linux/v6.8-rc5/source/drivers/phy/cadence/phy-cadence-torrent.c#L2960

If I add this cleanup in cdns_torrent_phy_configure_multilink(), yes I
could remove it from cdns_torrent_phy_resume_noirq(), but I should keep
it in the probe. And I should modify the probe to jump to clk_cleanup if
cdns_torrent_phy_configure_multilink() fails.

> 
>> +	reset_control_assert(cdns_phy->apb_rst);
>> +	clk_disable_unprepare(cdns_phy->clk);
>> +clk_cleanup:
>> +	cdns_torrent_clk_cleanup(cdns_phy);
> 
> This calls of_clk_del_provider(), seems misplaced here.

Yes you're right, it's called in cdns_torrent_phy_remove().
So I should not call it in the resume callback, this will cause some
issues during the remove.

Regards,

-- 
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From daniel.lezcano at linaro.org  Wed Feb 21 05:42:58 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 21 Feb 2024 14:42:58 +0100
Subject: [PATCH v5 0/7] add support for H616 thermal system
In-Reply-To: <20240219153639.179814-1-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
Message-ID: <13c957a9-6021-46a7-9243-b3658c26a333@linaro.org>

On 19/02/2024 16:36, Andre Przywara wrote:
> Hi,
> 
> this is v5 of this series originally by Martin, only some cosmetic
> changes this time, for instance  mentioning experiments with the SRAM
> controller registers to confirm that it's not an SRAM region which fixes
> the temperature reporting issue.
> See the Changelog below for more details.
> ==================
> 
> This series introduces support for the thermal sensors in the Allwinner
> H616 SoCs, which includes its siblings H618 and T507. The actual
> temperature reading turns out to be very similar to the H6 SoC, just
> with support for two more sensors. One nasty complication is caused
> by reports about temperatures above 200C, which are related to the
> firmware being run (because the vendor U-Boot contains a hack avoiding
> this problem). Some investigation and digging in BSP code later
> we identified that bit 16 in register 0x3000000 (SYS_CFG) needs to be
> cleared for the raw temperature register values to contain reasonable
> values.
> To achieve this, patch 1/7 exports this very register from the already
> existing SRAM/syscon device. Patch 5/7 then adds code to the thermal
> driver to find that device via a new DT property, and query its regmap
> to clear bit 16 in there.
> Patch 4/7 reworks the existing H6 calibration function to become
> compatible with the H616, many thanks to Maksim for figuring this out.
> This makes the actual enablement patch 6/7 very easy.
> 
> The rest of the patches are straightforward and build on Martin's
> original work, with some simplifications, resulting in more code sharing.
> 
> Please have a look!

Thanks for the detailed explanation.

I'm willing to pick the patches 1-6 and let the last one to go through 
the allwinner tree.

However I need the blessing from the different designed maintainers for 
the thermal driver and from the sunxi_sram

Thanks

-- 
<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 bhe at redhat.com  Wed Feb 21 05:44:04 2024
From: bhe at redhat.com (Baoquan He)
Date: Wed, 21 Feb 2024 21:44:04 +0800
Subject: [PATCH v2 00/14] Split crash out from kexec and clean up related
 config items
In-Reply-To: <559f2595-1477-4ef0-80e4-85ae8b426de7@linux.ibm.com>
References: <20240119145241.769622-1-bhe@redhat.com>
 <9101bb07-70f1-476c-bec9-ec67e9899744@linux.ibm.com>
 <Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv>
 <559f2595-1477-4ef0-80e4-85ae8b426de7@linux.ibm.com>
Message-ID: <ZdX+JMKsQWheE0B0@MiWiFi-R3L-srv>

On 02/21/24 at 11:15am, Hari Bathini wrote:
> Hi Baoquan,
> 
> On 04/02/24 8:56 am, Baoquan He wrote:
> > > > Hope Hari and Pingfan can help have a look, see if
> > > > it's doable. Now, I make it either have both kexec and crash enabled, or
> > > > disable both of them altogether.
> > > 
> > > Sure. I will take a closer look...
> > Thanks a lot. Please feel free to post patches to make that, or I can do
> > it with your support or suggestion.
> 
> Tested your changes and on top of these changes, came up with the below
> changes to get it working for powerpc:
> 
> 
> https://lore.kernel.org/all/20240213113150.1148276-1-hbathini at linux.ibm.com/
> 
> Please take a look.

I added a comment to the patch 1 consulting if the "struct crash_mem" is
appropriate to cover other cases except of kdump memory regions. I am
wondering if its name need be adjusted, or other kind of memory you
mentioned can use other structures or create a new one.

If it's has to be done like that, it's fine. 



From linus.walleij at linaro.org  Wed Feb 21 05:45:08 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 14:45:08 +0100
Subject: [PATCH 18/23] gpio: nomadik: support mobileye,eyeq5-gpio
In-Reply-To: <20240214-mbly-gpio-v1-18-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-18-f88c0ccf372b@bootlin.com>
Message-ID: <CACRpkdYb4V5EouMBYRRrZvLT1v6zKEtjHGPAs5orDKoo6dz6nA@mail.gmail.com>

Hi Theo,

thanks for your patch!

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> We create a custom compatible for the STA2X11 IP block as integrated
> into the Mobileye EyeQ5 platform. Its wake and alternate functions have
> been disabled, we want to avoid touching those registers.
>
> We both do: (1) early return in functions that do not support the
> platform, but with warnings, and (2) avoid calling those functions in
> the first place.
>
> We ensure that pinctrl-nomadik is not used with this STA2X11 variant.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
(...)
>+       bool quirk_mbly;

Compulsive abbreviation? I would just rename it:

bool is_mobileye_soc;

Nevermind the long name, it makes it crystal clear for readers
what is going on. (Rusty Russell's API naming guidelines.)

With that changed:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From mripard at kernel.org  Wed Feb 21 05:45:20 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Wed, 21 Feb 2024 14:45:20 +0100
Subject: [PATCH 3/3] drm/sun4i: Fix layer zpos change/atomic modesetting
In-Reply-To: <20240216190430.1374132-4-megi@xff.cz>
References: <20240216190430.1374132-1-megi@xff.cz>
 <20240216190430.1374132-4-megi@xff.cz>
Message-ID: <inuhwnlexpt6dpre4uailtvytjhms4uqeerzehbntczurhcxol@fc4nvkdwffdd>

Hi,

On Fri, Feb 16, 2024 at 08:04:26PM +0100, Ond?ej Jirman wrote:
> From: Ondrej Jirman <megi at xff.cz>
> 
> Identical configurations of planes can lead to different (and wrong)
> layer -> pipe routing at HW level, depending on the order of atomic
> plane changes.
> 
> For example:
> 
> - Layer 1 is configured to zpos 0 and thus uses pipe 0. No other layer
>   is enabled. This is a typical situation at boot.
> 
> - When a compositor takes over and layer 3 is enabled,
>   sun8i_ui_layer_enable() will get called with old_zpos=0 zpos=1, which
>   will lead to incorrect disabling of pipe 0 and enabling of pipe 1.
> 
> What happens is that sun8i_ui_layer_enable() function may disable
> blender pipes even if it is no longer assigned to its layer.
> 
> To correct this, move the routing setup out of individual plane's
> atomic_update into crtc's atomic_update, where it can be calculated
> and updated all at once.
> 
> Remove the atomic_disable callback because it is no longer needed.
> 
> Signed-off-by: Ondrej Jirman <megi at xff.cz>

I don't have enough knowledge about the mixers code to comment on your
patch, so I'll let Jernej review it. However, this feels to me like the
pipe assignment is typically the sort of things that should be dealt
with device-wide, and in atomic_check.

If I'm talking non-sense, it would be great to mention at least why that
can't be an option in the commit log.

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/20240221/9c5c0a67/attachment.sig>

From will at kernel.org  Wed Feb 21 05:49:23 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 21 Feb 2024 13:49:23 +0000
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <20240215160135.GL1088888@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240215134952.GA690@willie-the-truck>
 <20240215160135.GL1088888@nvidia.com>
Message-ID: <20240221134923.GA7362@willie-the-truck>

On Thu, Feb 15, 2024 at 12:01:35PM -0400, Jason Gunthorpe wrote:
> On Thu, Feb 15, 2024 at 01:49:53PM +0000, Will Deacon wrote:
> > On Tue, Feb 06, 2024 at 11:12:38AM -0400, Jason Gunthorpe wrote:
> > > @@ -48,6 +48,21 @@ enum arm_smmu_msi_index {
> > >  	ARM_SMMU_MAX_MSIS,
> > >  };
> > >  
> > > +struct arm_smmu_entry_writer_ops;
> > > +struct arm_smmu_entry_writer {
> > > +	const struct arm_smmu_entry_writer_ops *ops;
> > > +	struct arm_smmu_master *master;
> > > +};
> > > +
> > > +struct arm_smmu_entry_writer_ops {
> > > +	unsigned int num_entry_qwords;
> > > +	__le64 v_bit;
> > > +	void (*get_used)(const __le64 *entry, __le64 *used);
> > > +	void (*sync)(struct arm_smmu_entry_writer *writer);
> > > +};
> > 
> > Can we avoid the indirection for now, please? I'm sure we'll want it later
> > when you extend this to CDs, but for the initial support it just makes it
> > more difficult to follow the flow. Should be a trivial thing to drop, I
> > hope.
> 
> We can.

Thanks.

> > I think it also means we don't have a "hitless" transition from
> > stage-2 translation -> bypass.
> 
> Hmm, I didn't notice that. The kunit passed:
> 
> [    0.511483] 1..1
> [    0.511510]     KTAP version 1
> [    0.511551]     # Subtest: arm-smmu-v3-kunit-test
> [    0.511592]     # module: arm_smmu_v3_test
> [    0.511594]     1..10
> [    0.511910]     ok 1 arm_smmu_v3_write_ste_test_bypass_to_abort
> [    0.512110]     ok 2 arm_smmu_v3_write_ste_test_abort_to_bypass
> [    0.512386]     ok 3 arm_smmu_v3_write_ste_test_cdtable_to_abort
> [    0.512631]     ok 4 arm_smmu_v3_write_ste_test_abort_to_cdtable
> [    0.512874]     ok 5 arm_smmu_v3_write_ste_test_cdtable_to_bypass
> [    0.513075]     ok 6 arm_smmu_v3_write_ste_test_bypass_to_cdtable
> [    0.513275]     ok 7 arm_smmu_v3_write_ste_test_cdtable_s1dss_change
> [    0.513466]     ok 8 arm_smmu_v3_write_ste_test_s1dssbypass_to_stebypass
> [    0.513672]     ok 9 arm_smmu_v3_write_ste_test_stebypass_to_s1dssbypass
> [    0.514148]     ok 10 arm_smmu_v3_write_ste_test_non_hitless
> 
> Which I see is because it did not test the S2 case...

Oops!

> > Additionally, it looks like there's an existing buglet here in that we
> > shouldn't set SHCFG if SMMU_IDR1.ATTR_TYPES_OVR == 0.
> 
> Ah because the spec says RES0.. I'll add these two into the pile of
> random stuff in part 3

I don't think this needs to wait until part 3, but it also doesn't need to
be part of your series. I'll make a note that we can improve this.

> > > +	used_bits[0] |= cpu_to_le64(STRTAB_STE_0_CFG);
> > > +	switch (cfg) {
> > > +	case STRTAB_STE_0_CFG_ABORT:
> > > +	case STRTAB_STE_0_CFG_BYPASS:
> > > +		break;
> > > +	case STRTAB_STE_0_CFG_S1_TRANS:
> > > +		used_bits[0] |= cpu_to_le64(STRTAB_STE_0_S1FMT |
> > > +					    STRTAB_STE_0_S1CTXPTR_MASK |
> > > +					    STRTAB_STE_0_S1CDMAX);
> > > +		used_bits[1] |=
> > > +			cpu_to_le64(STRTAB_STE_1_S1DSS | STRTAB_STE_1_S1CIR |
> > > +				    STRTAB_STE_1_S1COR | STRTAB_STE_1_S1CSH |
> > > +				    STRTAB_STE_1_S1STALLD | STRTAB_STE_1_STRW);
> > > +		used_bits[1] |= cpu_to_le64(STRTAB_STE_1_EATS);
> > > +		used_bits[2] |= cpu_to_le64(STRTAB_STE_2_S2VMID);
> > > +		break;
> > > +	case STRTAB_STE_0_CFG_S2_TRANS:
> > > +		used_bits[1] |=
> > > +			cpu_to_le64(STRTAB_STE_1_EATS);
> > > +		used_bits[2] |=
> > > +			cpu_to_le64(STRTAB_STE_2_S2VMID | STRTAB_STE_2_VTCR |
> > > +				    STRTAB_STE_2_S2AA64 | STRTAB_STE_2_S2ENDI |
> > > +				    STRTAB_STE_2_S2PTW | STRTAB_STE_2_S2R);
> > > +		used_bits[3] |= cpu_to_le64(STRTAB_STE_3_S2TTB_MASK);
> > > +		break;
> > 
> > With SHCFG fixed, can we go a step further with this and simply identify
> > the live qwords directly, rather than on a field-by-field basis? I think
> > we should be able to do the same "hitless" transitions you want with the
> > coarser granularity.
> 
> Not naively, Michael's excellent unit test shows it.. My understanding
> of your idea was roughly thus:
> 
> void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
> {
> 	unsigned int cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(ent[0]));
> 
> 	used_bits[0] = U64_MAX;
> 	if (!(ent[0] & cpu_to_le64(STRTAB_STE_0_V)))
> 		return;
> 
> 	/*
> 	 * See 13.5 Summary of attribute/permission configuration fields for the
> 	 * SHCFG behavior. It is only used for BYPASS, including S1DSS BYPASS,
> 	 * and S2 only.
> 	 */
> 	if (cfg == STRTAB_STE_0_CFG_BYPASS ||
> 	    cfg == STRTAB_STE_0_CFG_S2_TRANS ||
> 	    (cfg == STRTAB_STE_0_CFG_S1_TRANS &&
> 	     FIELD_GET(STRTAB_STE_1_S1DSS, le64_to_cpu(ent[1])) ==
> 		     STRTAB_STE_1_S1DSS_BYPASS))
> 		used_bits[1] |= U64_MAX;
> 
> 	used_bits[0] |= U64_MAX;
> 	switch (cfg) {
> 	case STRTAB_STE_0_CFG_ABORT:
> 	case STRTAB_STE_0_CFG_BYPASS:
> 		break;
> 	case STRTAB_STE_0_CFG_S1_TRANS:
> 		used_bits[0] |= U64_MAX;
> 		used_bits[1] |= U64_MAX;
> 		used_bits[2] |= U64_MAX;
> 		break;
> 	case STRTAB_STE_0_CFG_NESTED:
> 		used_bits[0] |= U64_MAX;
> 		used_bits[1] |= U64_MAX;
> 		fallthrough;
> 	case STRTAB_STE_0_CFG_S2_TRANS:
> 		used_bits[1] |= U64_MAX;
> 		used_bits[2] |= U64_MAX;
> 		used_bits[3] |= U64_MAX;
> 		break;

Very roughly, yes, although I'd go further and just return a bitmap of
used qwords instead of tracking these bits. Basically, we could have some
#defines saying which qwords are used by which configs, and then we can
simplify the algorithm while retaining the ability to reject updates
to qwords which we're not expecting.

> And the failures:

[...]

> BYPASS -> S1 requires changing overlapping bits in qword 1. The
> programming sequence would look like this:
> 
> start qw[1] = SHCFG_INCOMING
>       qw[1] = SHCFG_INCOMING | S1DSS
>       qw[0] = S1 mode
>       qw[1] = S1DSS
> 
> The two states are sharing qw[1] and BYPASS ignores all of it except
> SHCFG_INCOMING. Since bypass would have its qw[1] marked as used due
> to the SHCFG there is no way to express that it is not looking at the
> other bits.
> 
> We'd have to really start doing really hacky things like remove the
> SHCFG as a used field entirely - but I think if you do that you break
> the entire logic of the design and also go backwards to having
> programming that only works if STEs are constructed in certain ways.

I would actually like to remove SHCFG as a used field. If the encoding
was less whacky (i.e. if 0b00 always meant "use incoming"), then it would
be easy, but it shouldn't be too hard to work around that.

Then BYPASS doesn't need to worry about qword 1 at all.

Will


From Nicolas.Ferre at microchip.com  Wed Feb 21 05:49:18 2024
From: Nicolas.Ferre at microchip.com (Nicolas.Ferre at microchip.com)
Date: Wed, 21 Feb 2024 13:49:18 +0000
Subject: [PATCH 01/11] misc: atmel-ssc: Convert to platform remove
 callback returning void
In-Reply-To: <45719fc31bb893bb9ab1450057e9cb7f399e9ee2.1708508896.git.u.kleine-koenig@pengutronix.de>
References: <cover.1708508896.git.u.kleine-koenig@pengutronix.de>
 <45719fc31bb893bb9ab1450057e9cb7f399e9ee2.1708508896.git.u.kleine-koenig@pengutronix.de>
Message-ID: <aa1338c9-0880-45fb-9ba0-9ce2025b1018@microchip.com>

On 21/02/2024 at 10:53, Uwe Kleine-K?nig wrote:
> The .remove() callback for a platform driver returns an int which makes
> many driver authors wrongly assume it's possible to do error handling by
> returning an error code. However the value returned is ignored (apart
> from emitting a warning) and this typically results in resource leaks.
> 
> To improve here there is a quest to make the remove callback return
> void. In the first step of this quest all drivers are converted to
> .remove_new(), which already returns void. Eventually after all drivers
> are converted, .remove_new() will be renamed to .remove().
> 
> Trivially convert this driver from always returning zero in the remove
> callback to the void returning variant.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
Thanks Uwe.

> ---
>   drivers/misc/atmel-ssc.c | 6 ++----
>   1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
> index ee590c4a1537..6eac0f335915 100644
> --- a/drivers/misc/atmel-ssc.c
> +++ b/drivers/misc/atmel-ssc.c
> @@ -251,7 +251,7 @@ static int ssc_probe(struct platform_device *pdev)
>          return 0;
>   }
> 
> -static int ssc_remove(struct platform_device *pdev)
> +static void ssc_remove(struct platform_device *pdev)
>   {
>          struct ssc_device *ssc = platform_get_drvdata(pdev);
> 
> @@ -260,8 +260,6 @@ static int ssc_remove(struct platform_device *pdev)
>          mutex_lock(&user_lock);
>          list_del(&ssc->list);
>          mutex_unlock(&user_lock);
> -
> -       return 0;
>   }
> 
>   static struct platform_driver ssc_driver = {
> @@ -271,7 +269,7 @@ static struct platform_driver ssc_driver = {
>          },
>          .id_table       = atmel_ssc_devtypes,
>          .probe          = ssc_probe,
> -       .remove         = ssc_remove,
> +       .remove_new     = ssc_remove,
>   };
>   module_platform_driver(ssc_driver);
> 
> --
> 2.43.0
> 


From mark.rutland at arm.com  Wed Feb 21 05:52:38 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 21 Feb 2024 13:52:38 +0000
Subject: [PATCH V16 1/8] arm64/sysreg: Add BRBE registers and fields
In-Reply-To: <20240125094119.2542332-2-anshuman.khandual@arm.com>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-2-anshuman.khandual@arm.com>
Message-ID: <ZdYAJvZf4Ut5f5Rf@FVFF77S0Q05N>

On Thu, Jan 25, 2024 at 03:11:12PM +0530, Anshuman Khandual 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: 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>
> ---
> Changes in V16:
> 
> - Updated BRBINFx_EL1.TYPE = 0b110000 as field IMPDEF_TRAP_EL3
> - Updated BRBCR_ELx[9] as field FZPSS
> - Updated BRBINFINJ_EL1 to use sysreg field BRBINFx_EL1
> 
>  arch/arm64/include/asm/sysreg.h | 109 ++++++++++++++++++++++++++
>  arch/arm64/tools/sysreg         | 131 ++++++++++++++++++++++++++++++++
>  2 files changed, 240 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index c3b19b376c86..72544b5c4951 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -272,6 +272,109 @@
>  
>  #define SYS_BRBCR_EL2			sys_reg(2, 4, 9, 0, 0)
>  
> +#define __SYS_BRBINF(n)			sys_reg(2, 1, 8, ((n) & 0xf), ((((n) & 0x10) >> 2) + 0))
> +#define __SYS_BRBSRC(n)			sys_reg(2, 1, 8, ((n) & 0xf), ((((n) & 0x10) >> 2) + 1))
> +#define __SYS_BRBTGT(n)			sys_reg(2, 1, 8, ((n) & 0xf), ((((n) & 0x10) >> 2) + 2))

We already have definitions for these since v6.5, added in commit:

  57596c8f991c9aac ("arm64: Add debug registers affected by HDFGxTR_EL2:)

That commit also added register encoding definitions:

| #define SYS_BRBINF_EL1(n)              sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 0))
| #define SYS_BRBINFINJ_EL1              sys_reg(2, 1, 9, 1, 0)
| #define SYS_BRBSRC_EL1(n)              sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 1))
| #define SYS_BRBSRCINJ_EL1              sys_reg(2, 1, 9, 1, 1)
| #define SYS_BRBTGT_EL1(n)              sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 2))
| #define SYS_BRBTGTINJ_EL1              sys_reg(2, 1, 9, 1, 2)
| #define SYS_BRBTS_EL1                  sys_reg(2, 1, 9, 0, 2)

I don't think we need to add new encoding definitions for BRBINF<n>_EL1,
BRBSRC<n>_EL1, or BRBTGT<n>_EL1; we can just use those existing defintions
directly. That also means we don't need to add all of the expanded 0..31
definitions; the driver can use SYS_BRBINF_EL1(n) and friends directly.

[...]

> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 4c9b67934367..caf851ba5dc0 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -1023,6 +1023,137 @@ UnsignedEnum	3:0	MTEPERM
>  EndEnum
>  EndSysreg
>  
> +
> +SysregFields BRBINFx_EL1
> +Res0	63:47
> +Field	46	CCU
> +Field	45:32	CC
> +Res0	31:18
> +Field	17	LASTFAILED
> +Field	16	T
> +Res0	15:14
> +Enum	13:8		TYPE
> +	0b000000	UNCOND_DIRECT
> +	0b000001	INDIRECT
> +	0b000010	DIRECT_LINK
> +	0b000011	INDIRECT_LINK
> +	0b000101	RET
> +	0b000111	ERET
> +	0b001000	COND_DIRECT

Minor nit, but for consistency with DIRECT_LINK, could we please use
DIRECT_UNCOND and DIRECT_COND?

> +	0b100001	DEBUG_HALT
> +	0b100010	CALL
> +	0b100011	TRAP
> +	0b100100	SERROR
> +	0b100110	INSN_DEBUG
> +	0b100111	DATA_DEBUG
> +	0b101010	ALIGN_FAULT
> +	0b101011	INSN_FAULT
> +	0b101100	DATA_FAULT
> +	0b101110	IRQ
> +	0b101111	FIQ
> +	0b110000	IMPDEF_TRAP_EL3
> +	0b111001	DEBUG_EXIT

That IMPDEF_TRAP_EL3 encoding doesn't seem to exist in the latest ARM ARM (ARM
DDI 0487J.a), and I see Mark Brown checked against the "Arm A-profile
Architecture Registers" document (ARM DDI 0601 ID121123, AKA 2023-12).

Could you please mention that in the commit message, and link to that version
of the document (https://developer.arm.com/documentation/ddi0601/2023-12/) ?
That'll make it easier for anyone else to review this, and it'll be good in
case anyone needs to figure out where this came from in future.

> +EndEnum
> +Enum	7:6	EL
> +	0b00	EL0
> +	0b01	EL1
> +	0b10	EL2
> +	0b11	EL3
> +EndEnum
> +Field	5	MPRED
> +Res0	4:2
> +Enum	1:0	VALID
> +	0b00	NONE
> +	0b01	TARGET
> +	0b10	SOURCE
> +	0b11	FULL
> +EndEnum
> +EndSysregFields

The other fields here all look good per the ARM ARM and sysreg document.

> +SysregFields	BRBCR_ELx
> +Res0	63:24
> +Field	23 	EXCEPTION
> +Field	22 	ERTN
> +Res0	21:10
> +Field	9	FZPSS
> +Field	8 	FZP
> +Res0	7
> +Enum	6:5	TS
> +	0b01	VIRTUAL
> +	0b10	GUEST_PHYSICAL
> +	0b11	PHYSICAL
> +EndEnum
> +Field	4	MPRED
> +Field	3	CC
> +Res0	2
> +Field	1	ExBRE
> +Field	0	E0BRE
> +EndSysregFields

This looks good per the ARM ARM and sysreg document.

> +Sysreg	BRBCR_EL2	2	4	9	0	0
> +Fields	BRBCR_ELx
> +EndSysreg
> +
> +Sysreg	BRBCR_EL1	2	1	9	0	0
> +Fields	BRBCR_ELx
> +EndSysreg
> +
> +Sysreg	BRBCR_EL12	2	5	9	0	0
> +Fields	BRBCR_ELx
> +EndSysreg

These all look good per the ARM ARM and sysreg document.

Minor nit, but could we please list thse in order:

	BRBCR_EL1
	BRBCR_EL12
	BRBCR_EL2

... since that way the names are ordered alphnumerically, which is what we've
done for other groups (e.g. PIR_EL{1,12,2}), and it's the way the ARM ARM
happens to be ordered.

> +Sysreg	BRBFCR_EL1	2	1	9	0	1
> +Res0	63:30
> +Enum	29:28	BANK
> +	0b0	FIRST
> +	0b1	SECOND

Nit: since this is a 2-bit field, please pad these as '0b00' and '0b01'.

Could we please use BANK_0 and BANK_1 rather than FIRST and SECOND?

That'd also be easier to use behind macros.

> +EndEnum
> +Res0	27:23
> +Field	22	CONDDIR
> +Field	21	DIRCALL
> +Field	20	INDCALL
> +Field	19	RTN
> +Field	18	INDIRECT
> +Field	17	DIRECT
> +Field	16	EnI
> +Res0	15:8
> +Field	7	PAUSED
> +Field	6	LASTFAILED
> +Res0	5:0
> +EndSysreg

Other than the nit, this looks good per the ARM ARM and sysreg document.

[...]

> +Sysreg	BRBIDR0_EL1	2	1	9	2	0
> +Res0	63:16
> +Enum	15:12	CC
> +	0b101	20_BIT
> +EndEnum
> +Enum	11:8	FORMAT
> +	0b0	0
> +EndEnum
> +Enum	7:0		NUMREC
> +	0b0001000	8
> +	0b0010000	16
> +	0b0100000	32
> +	0b1000000	64

This is an 8-bit field; please pad these to 8 bits (they all need a leading
'0').

> +EndEnum
> +EndSysreg

Aside from the comments above, this looks good to me.

Mark.


From arnd at arndb.de  Wed Feb 21 05:52:29 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 21 Feb 2024 14:52:29 +0100
Subject: [PATCH 00/11] misc: Convert to platform remove callback returning void
In-Reply-To: <cover.1708508896.git.u.kleine-koenig@pengutronix.de>
References: <cover.1708508896.git.u.kleine-koenig@pengutronix.de>
Message-ID: <d6c4ff9e-756a-4604-993a-cf14cfdbc53c@app.fastmail.com>

On Wed, Feb 21, 2024, at 10:53, Uwe Kleine-K?nig wrote:
> Hello,
>
> this series converts all drivers below drivers/misc to struct
> platform_driver::remove_new(). See commit 5c5a7680e67b ("platform:
> Provide a remove callback that returns no value") for an extended
> explanation and the eventual goal.
>
> All conversations are trivial, because their .remove() callbacks
> returned zero unconditionally.
>
> There are no interdependencies between these patches, so they could be
> picked up individually. But I'd hope that Greg or Arnd picks them up all
> together.

These all look good to me, whole series

Acked-by: Arnd Bergmann <arnd at arndb.de>


From broonie at kernel.org  Wed Feb 21 05:53:10 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 21 Feb 2024 13:53:10 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <20240221012736.GQ4163@brightrain.aerifal.cx>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
 <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
 <20240220235415.GP4163@brightrain.aerifal.cx>
 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx>
Message-ID: <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>

On Tue, Feb 20, 2024 at 08:27:37PM -0500, dalias at libc.org wrote:
> On Wed, Feb 21, 2024 at 12:35:48AM +0000, Edgecombe, Rick P wrote:

> > (INCSSP, RSTORSSP, etc). These are a collection of instructions that
> > allow limited control of the SSP. When shadow stack gets disabled,
> > these suddenly turn into #UD generating instructions. So any other
> > threads executing those instructions when shadow stack got disabled
> > would be in for a nasty surprise.

> This is the kernel's problem if that's happening. It should be
> trapping these and returning immediately like a NOP if shadow stack
> has been disabled, not generating SIGILL.

I'm not sure that's going to work out well, all it takes is some code
that's looking at the shadow stack and expecting something to happen as
a result of the instructions it's executing and we run into trouble.  A
lot of things won't notice and will just happily carry on but I expect
there are going to be things that care.  We also end up with an
additional state for threads that have had shadow stacks transparently
disabled, that's managable but still.

> > > The place where it's really needed to be able to allocate the shadow
> > > stack synchronously under userspace control, in order to harden
> > > normal
> > > applications that aren't doing funny things, is in pthread_create
> > > without a caller-provided stack.

> > Yea most apps don't do anything too tricky. Mostly shadow stack "just
> > works". But it's no excuse to just crash for the others.

> One thing to note here is that, to enable this, we're going to need
> some way to detect "new enough kernel that shadow stack semantics are
> all right". If there are kernels that have shadow stack support but
> with problems that make it unsafe to use (this sounds like the case),
> we can't turn it on without a way to avoid trying to use it on those.

If we have this automatic conversion of pages to shadow stack then we
should have an API for enabling it, userspace should be able to use the
presence of that API to determine if the feature is there.
-------------- 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/20240221/0a01422e/attachment.sig>

From robh at kernel.org  Wed Feb 21 05:53:51 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 21 Feb 2024 06:53:51 -0700
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <20240221092826.748e70c4@canb.auug.org.au>
References: <20240221092826.748e70c4@canb.auug.org.au>
Message-ID: <CAL_JsqKw9OXb=aOMni1qprzeWDBgmjdJef-6VAjwx0R--D+URw@mail.gmail.com>

On Tue, Feb 20, 2024 at 3:28?PM Stephen Rothwell <sfr at canb.auug.org.au> wrote:
>
> Hi all,
>
> After merging the arm-soc-fixes tree, today's linux-next build (arm
> multi_v7_defconfig) produced this warning:
>
> arch/arm/boot/dts/renesas/r8a7790-lager.dts:444.11-458.5: Warning (interrupt_provider): /i2c-mux4/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7790-lager.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7792-blanche.dts:376.10-392.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7792-blanche.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7790-stout.dts:344.10-362.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7790-stout.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7791-koelsch.dts:816.10-830.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7791-koelsch.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7791-porter.dts:410.10-420.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 5a: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7791-porter.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7794-alt.dts:450.10-464.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7794-alt.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7794-silk.dts:436.10-454.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7794-silk.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm/boot/dts/renesas/r8a7793-gose.dts:756.10-770.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
>
> Introduced/exposed by commit
>
>   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
>
> I guess you missed some :-(

No, Geert separately posted fixes for already.

Rob


From robh at kernel.org  Wed Feb 21 05:58:32 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 21 Feb 2024 06:58:32 -0700
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <20240221163010.5f81813a@canb.auug.org.au>
References: <20240221092826.748e70c4@canb.auug.org.au> <20240221163010.5f81813a@canb.auug.org.au>
Message-ID: <CAL_Jsq+2ri0JsmuU184YGj=p53jSxn+8EZq_FuBbMjsVyNLvtw@mail.gmail.com>

On Tue, Feb 20, 2024 at 10:30?PM Stephen Rothwell <sfr at canb.auug.org.au> wrote:
>
> Hi all,
>
> On Wed, 21 Feb 2024 09:28:26 +1100 Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> >
> > After merging the arm-soc-fixes tree, today's linux-next build (arm
> > multi_v7_defconfig) produced this warning:
> >
> > arch/arm/boot/dts/renesas/r8a7790-lager.dts:444.11-458.5: Warning (interrupt_provider): /i2c-mux4/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7790-lager.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7792-blanche.dts:376.10-392.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7792-blanche.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7790-stout.dts:344.10-362.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7790-stout.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7791-koelsch.dts:816.10-830.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7791-koelsch.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7791-porter.dts:410.10-420.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 5a: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7791-porter.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7794-alt.dts:450.10-464.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7794-alt.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7794-silk.dts:436.10-454.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7794-silk.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7793-gose.dts:756.10-770.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> >
> > Introduced/exposed by commit
> >
> >   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
> >
> > I guess you missed some :-(
>
> Also these from the arm64 defconfig build:
>
> arch/arm64/boot/dts/freescale/mba8xx.dtsi:233.20-249.4: Warning (interrupt_provider): /bus at 5a000000/i2c at 5a810000/gpio at 70: Missing '#interrupt-cells' in interrupt provider
> arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> arch/arm64/boot/dts/freescale/mba8xx.dtsi:233.20-249.4: Warning (interrupt_provider): /bus at 5a000000/i2c at 5a810000/gpio at 70: Missing '#interrupt-cells' in interrupt provider
> arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp-mba8xx.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'

Looks like a new platform in next.

Alexander, Can you fix these?

Rob


From p.zabel at pengutronix.de  Wed Feb 21 05:58:43 2024
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 21 Feb 2024 14:58:43 +0100
Subject: [PATCH v3 14/18] phy: cadence-torrent: add suspend and resume
 support
In-Reply-To: <113b7f2e-1313-4ebf-a403-e5fcae8f01ca@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
	 <20240102-j7200-pcie-s2r-v3-14-5c2e4a3fac1f@bootlin.com>
	 <c105bfa8567f9e76731f2b018f4ca3176357204d.camel@pengutronix.de>
	 <113b7f2e-1313-4ebf-a403-e5fcae8f01ca@bootlin.com>
Message-ID: <338419fd10ffcc62b135d924f766d66af8186346.camel@pengutronix.de>

On Mi, 2024-02-21 at 14:41 +0100, Thomas Richard wrote:
> On 2/21/24 14:09, Philipp Zabel wrote:
> > On Do, 2024-02-15 at 16:17 +0100, Thomas Richard wrote:
> > > Add suspend and resume support.
> > > 
> > > The already_configured flag is cleared during the suspend stage to force
> > > the PHY initialization during the resume stage.
> > > 
> > > Based on the work of Th?o Lebrun <theo.lebrun at bootlin.com>
> > > 
> > > Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>
> > > ---
> > >  drivers/phy/cadence/phy-cadence-torrent.c | 54 +++++++++++++++++++++++++++++++
> > >  1 file changed, 54 insertions(+)
> > > 
> > > diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
> > > index 52cadca4c07b..f8945a11e7ca 100644
> > > --- a/drivers/phy/cadence/phy-cadence-torrent.c
> > > +++ b/drivers/phy/cadence/phy-cadence-torrent.c
> > > @@ -3005,6 +3005,59 @@ static void cdns_torrent_phy_remove(struct platform_device *pdev)
> > >  	cdns_torrent_clk_cleanup(cdns_phy);
> > >  }
> > >  
> > > +static int cdns_torrent_phy_suspend_noirq(struct device *dev)
> > > +{
> > > +	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
> > > +	int i;
> > > +
> > > +	reset_control_assert(cdns_phy->phy_rst);
> > > +	reset_control_assert(cdns_phy->apb_rst);
> > > +	for (i = 0; i < cdns_phy->nsubnodes; i++)
> > > +		reset_control_assert(cdns_phy->phys[i].lnk_rst);
> > > +
> > > +	if (cdns_phy->already_configured)
> > > +		cdns_phy->already_configured = 0;
> > > +	else
> > > +		clk_disable_unprepare(cdns_phy->clk);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int cdns_torrent_phy_resume_noirq(struct device *dev)
> > > +{
> > > +	struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev);
> > > +	int node = cdns_phy->nsubnodes;
> > > +	int ret, i;
> > > +
> > > +	ret = cdns_torrent_clk(cdns_phy);
> > > +	if (ret)
> > > +		goto clk_cleanup;
> > > +
> > > +	/* Enable APB */
> > > +	reset_control_deassert(cdns_phy->apb_rst);
> > > +
> > > +	if (cdns_phy->nsubnodes > 1) {
> > > +		ret = cdns_torrent_phy_configure_multilink(cdns_phy);
> > > +		if (ret)
> > > +			goto put_lnk_rst;
> > > +	}
> > > +
> > > +	return 0;
> > > +
> > > +put_lnk_rst:
> > > +	for (i = 0; i < node; i++)
> > > +		reset_control_assert(cdns_phy->phys[i].lnk_rst);
> > 
> > The same cleanup is found in probe. Would it be cleaner to move this
> > into cdns_torrent_phy_configure_multilink() instead of duplicating it
> > here?
> 
> Hello Philipp,
> 
> Yes I could, but from my point of view, it would not be cleaner.
> This cleanup is called from many places in the probe:
> -
> https://elixir.bootlin.com/linux/v6.8-rc5/source/drivers/phy/cadence/phy-cadence-torrent.c#L2948
> -
> https://elixir.bootlin.com/linux/v6.8-rc5/source/drivers/phy/cadence/phy-cadence-torrent.c#L2954
> -
> https://elixir.bootlin.com/linux/v6.8-rc5/source/drivers/phy/cadence/phy-cadence-torrent.c#L2960
>
> If I add this cleanup in cdns_torrent_phy_configure_multilink(), yes I
> could remove it from cdns_torrent_phy_resume_noirq(), but I should keep
> it in the probe. And I should modify the probe to jump to clk_cleanup if
> cdns_torrent_phy_configure_multilink() fails.

I see it now. If it can't be consolidated, it's not useful to move it
around.

> 
regards
Philipp


From broonie at kernel.org  Wed Feb 21 05:59:03 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 21 Feb 2024 13:59:03 +0000
Subject: [PATCH V16 1/8] arm64/sysreg: Add BRBE registers and fields
In-Reply-To: <ZdYAJvZf4Ut5f5Rf@FVFF77S0Q05N>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-2-anshuman.khandual@arm.com>
 <ZdYAJvZf4Ut5f5Rf@FVFF77S0Q05N>
Message-ID: <e89ecbde-0967-4b8e-af77-3a72f207f3d7@sirena.org.uk>

On Wed, Feb 21, 2024 at 01:52:38PM +0000, Mark Rutland wrote:
> On Thu, Jan 25, 2024 at 03:11:12PM +0530, Anshuman Khandual wrote:

> Minor nit, but could we please list thse in order:

> 	BRBCR_EL1
> 	BRBCR_EL12
> 	BRBCR_EL2

> ... since that way the names are ordered alphnumerically, which is what we've
> done for other groups (e.g. PIR_EL{1,12,2}), and it's the way the ARM ARM
> happens to be ordered.

It's a good point about the sorting, though the file is currently mostly
sorted by encoding rather than alphanumerically (similarly to how
sysreg.h was done).
-------------- 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/20240221/9c5713be/attachment.sig>

From arnd at arndb.de  Wed Feb 21 05:59:36 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 21 Feb 2024 14:59:36 +0100
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <CAL_JsqKw9OXb=aOMni1qprzeWDBgmjdJef-6VAjwx0R--D+URw@mail.gmail.com>
References: <20240221092826.748e70c4@canb.auug.org.au>
 <CAL_JsqKw9OXb=aOMni1qprzeWDBgmjdJef-6VAjwx0R--D+URw@mail.gmail.com>
Message-ID: <ac9ddf79-6bc9-4daf-a271-82f8b3bca988@app.fastmail.com>

On Wed, Feb 21, 2024, at 14:53, Rob Herring wrote:
> On Tue, Feb 20, 2024 at 3:28?PM Stephen Rothwell <sfr at canb.auug.org.au> wrote:
>> arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
>>
>> Introduced/exposed by commit
>>
>>   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
>>
>> I guess you missed some :-(
>
> No, Geert separately posted fixes for already.

I did make the mistake of applying the final patch "dtc:
Enable dtc interrupt_provider check" to the arm/fixes branch
for 6.8 along with the other fixes.

Clearly that should be separate and only go into mainline
after there are no more regressions, but now I'm unsure
about the other patches -- did you intend the dts fixes
for 6.8 or for the coming merge window?

      Arnd


From geert at linux-m68k.org  Wed Feb 21 06:01:01 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 21 Feb 2024 15:01:01 +0100
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <CAL_JsqKw9OXb=aOMni1qprzeWDBgmjdJef-6VAjwx0R--D+URw@mail.gmail.com>
References: <20240221092826.748e70c4@canb.auug.org.au> <CAL_JsqKw9OXb=aOMni1qprzeWDBgmjdJef-6VAjwx0R--D+URw@mail.gmail.com>
Message-ID: <CAMuHMdXrxC6mydJ3MO5WurqE4uXbF+XBaoBe_9Sht9DotXxoDA@mail.gmail.com>

On Wed, Feb 21, 2024 at 2:54?PM Rob Herring <robh at kernel.org> wrote:
> On Tue, Feb 20, 2024 at 3:28?PM Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> > After merging the arm-soc-fixes tree, today's linux-next build (arm
> > multi_v7_defconfig) produced this warning:
> >
> > arch/arm/boot/dts/renesas/r8a7790-lager.dts:444.11-458.5: Warning (interrupt_provider): /i2c-mux4/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7790-lager.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7792-blanche.dts:376.10-392.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7792-blanche.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7790-stout.dts:344.10-362.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7790-stout.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7791-koelsch.dts:816.10-830.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7791-koelsch.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7791-porter.dts:410.10-420.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 5a: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7791-porter.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7794-alt.dts:450.10-464.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7794-alt.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7794-silk.dts:436.10-454.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7794-silk.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm/boot/dts/renesas/r8a7793-gose.dts:756.10-770.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> >
> > Introduced/exposed by commit
> >
> >   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
> >
> > I guess you missed some :-(
>
> No, Geert separately posted fixes for already.

Indeed, cfr. commit b4f97d1b5aeb6166
("ARM: dts: renesas: rcar-gen2: Add missing #interrupt-cells
to DA9063 nodes") in renesas-next (next-20240220 and later).
But that commit is not part of arm-soc-fixes.

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 mark.rutland at arm.com  Wed Feb 21 06:01:54 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 21 Feb 2024 14:01:54 +0000
Subject: [PATCH V16 2/8] KVM: arm64: Prevent guest accesses into BRBE
 system registers/instructions
In-Reply-To: <20240125094119.2542332-3-anshuman.khandual@arm.com>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-3-anshuman.khandual@arm.com>
Message-ID: <ZdYCUi9YVDNDz7fr@FVFF77S0Q05N>

On Thu, Jan 25, 2024 at 03:11:13PM +0530, Anshuman Khandual wrote:
> Currently BRBE feature is not supported in a guest environment. This hides
> BRBE feature availability via masking ID_AA64DFR0_EL1.BRBE field.

Does that means that a guest can currently see BRBE advertised in the
ID_AA64DFR0_EL1.BRB field, or is that hidden by the regular cpufeature code
today?

> This also blocks guest accesses into BRBE system registers and instructions
> as if the underlying hardware never implemented FEAT_BRBE feature.
> 
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oliver.upton at linux.dev>
> Cc: James Morse <james.morse at arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: kvmarm at lists.linux.dev
> 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>
> ---
> Changes in V16:
> 
> - Added BRB_INF_SRC_TGT_EL1 macro for corresponding BRB_[INF|SRC|TGT] expansion
> 
>  arch/arm64/kvm/sys_regs.c | 56 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 56 insertions(+)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 30253bd19917..6a06dc2f0c06 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1304,6 +1304,11 @@ static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
>  	return 0;
>  }
>  
> +#define BRB_INF_SRC_TGT_EL1(n)					\
> +	{ SYS_DESC(SYS_BRBINF##n##_EL1), undef_access },	\
> +	{ SYS_DESC(SYS_BRBSRC##n##_EL1), undef_access },	\
> +	{ SYS_DESC(SYS_BRBTGT##n##_EL1), undef_access }		\

With the changes suggested on the previous patch, this would need to change to be:

	#define BRB_INF_SRC_TGT_EL1(n)					\
		{ SYS_DESC(SYS_BRBINF_EL1(n)), undef_access },	\
		{ SYS_DESC(SYS_BRBSRC_EL1(n)), undef_access },	\
		{ SYS_DESC(SYS_BRBTGT_EL1(n)), undef_access }	\


... which would also be easier for backporting (if necessary), since those
definitions have existed for a while.

Otherwise (modulo Suzuki's comment about rebasing), this looks good to me.

Mark.

>  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
>  #define DBG_BCR_BVR_WCR_WVR_EL1(n)					\
>  	{ SYS_DESC(SYS_DBGBVRn_EL1(n)),					\
> @@ -1707,6 +1712,9 @@ static u64 read_sanitised_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
>  	/* Hide SPE from guests */
>  	val &= ~ID_AA64DFR0_EL1_PMSVer_MASK;
>  
> +	/* Hide BRBE from guests */
> +	val &= ~ID_AA64DFR0_EL1_BRBE_MASK;
> +
>  	return val;
>  }
>  
> @@ -2195,6 +2203,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
>  	{ SYS_DESC(SYS_DC_CIGSW), access_dcgsw },
>  	{ SYS_DESC(SYS_DC_CIGDSW), access_dcgsw },
> +	{ SYS_DESC(OP_BRB_IALL), undef_access },
> +	{ SYS_DESC(OP_BRB_INJ), undef_access },
>  
>  	DBG_BCR_BVR_WCR_WVR_EL1(0),
>  	DBG_BCR_BVR_WCR_WVR_EL1(1),
> @@ -2225,6 +2235,52 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_DBGCLAIMCLR_EL1), trap_raz_wi },
>  	{ SYS_DESC(SYS_DBGAUTHSTATUS_EL1), trap_dbgauthstatus_el1 },
>  
> +	/*
> +	 * BRBE branch record sysreg address space is interleaved between
> +	 * corresponding BRBINF<N>_EL1, BRBSRC<N>_EL1, and BRBTGT<N>_EL1.
> +	 */
> +	BRB_INF_SRC_TGT_EL1(0),
> +	BRB_INF_SRC_TGT_EL1(16),
> +	BRB_INF_SRC_TGT_EL1(1),
> +	BRB_INF_SRC_TGT_EL1(17),
> +	BRB_INF_SRC_TGT_EL1(2),
> +	BRB_INF_SRC_TGT_EL1(18),
> +	BRB_INF_SRC_TGT_EL1(3),
> +	BRB_INF_SRC_TGT_EL1(19),
> +	BRB_INF_SRC_TGT_EL1(4),
> +	BRB_INF_SRC_TGT_EL1(20),
> +	BRB_INF_SRC_TGT_EL1(5),
> +	BRB_INF_SRC_TGT_EL1(21),
> +	BRB_INF_SRC_TGT_EL1(6),
> +	BRB_INF_SRC_TGT_EL1(22),
> +	BRB_INF_SRC_TGT_EL1(7),
> +	BRB_INF_SRC_TGT_EL1(23),
> +	BRB_INF_SRC_TGT_EL1(8),
> +	BRB_INF_SRC_TGT_EL1(24),
> +	BRB_INF_SRC_TGT_EL1(9),
> +	BRB_INF_SRC_TGT_EL1(25),
> +	BRB_INF_SRC_TGT_EL1(10),
> +	BRB_INF_SRC_TGT_EL1(26),
> +	BRB_INF_SRC_TGT_EL1(11),
> +	BRB_INF_SRC_TGT_EL1(27),
> +	BRB_INF_SRC_TGT_EL1(12),
> +	BRB_INF_SRC_TGT_EL1(28),
> +	BRB_INF_SRC_TGT_EL1(13),
> +	BRB_INF_SRC_TGT_EL1(29),
> +	BRB_INF_SRC_TGT_EL1(14),
> +	BRB_INF_SRC_TGT_EL1(30),
> +	BRB_INF_SRC_TGT_EL1(15),
> +	BRB_INF_SRC_TGT_EL1(31),
> +
> +	/* Remaining BRBE sysreg addresses space */
> +	{ SYS_DESC(SYS_BRBCR_EL1), undef_access },
> +	{ SYS_DESC(SYS_BRBFCR_EL1), undef_access },
> +	{ SYS_DESC(SYS_BRBTS_EL1), undef_access },
> +	{ SYS_DESC(SYS_BRBINFINJ_EL1), undef_access },
> +	{ SYS_DESC(SYS_BRBSRCINJ_EL1), undef_access },
> +	{ SYS_DESC(SYS_BRBTGTINJ_EL1), undef_access },
> +	{ SYS_DESC(SYS_BRBIDR0_EL1), undef_access },
> +
>  	{ SYS_DESC(SYS_MDCCSR_EL0), trap_raz_wi },
>  	{ SYS_DESC(SYS_DBGDTR_EL0), trap_raz_wi },
>  	// DBGDTR[TR]X_EL0 share the same encoding
> -- 
> 2.25.1
> 


From bmasney at redhat.com  Wed Feb 21 06:02:52 2024
From: bmasney at redhat.com (Brian Masney)
Date: Wed, 21 Feb 2024 09:02:52 -0500
Subject: [PATCH] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <20240221125928.3711050-1-javierm@redhat.com>
References: <20240221125928.3711050-1-javierm@redhat.com>
Message-ID: <ZdYCjDPvEp4iFaZ1@x1>

On Wed, Feb 21, 2024 at 01:59:17PM +0100, Javier Martinez Canillas wrote:
> These options are needed by some Linux distributions (e.g: Fedora), so
> let's enable them to make it easier for developers using such distros.
> 
> Signed-off-by: Javier Martinez Canillas <javierm at redhat.com>

Reviewed-by: Brian Masney <bmasney at redhat.com>



From mark.rutland at arm.com  Wed Feb 21 06:05:24 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 21 Feb 2024 14:05:24 +0000
Subject: [PATCH V16 1/8] arm64/sysreg: Add BRBE registers and fields
In-Reply-To: <e89ecbde-0967-4b8e-af77-3a72f207f3d7@sirena.org.uk>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-2-anshuman.khandual@arm.com>
 <ZdYAJvZf4Ut5f5Rf@FVFF77S0Q05N>
 <e89ecbde-0967-4b8e-af77-3a72f207f3d7@sirena.org.uk>
Message-ID: <ZdYDJPe1n5-V-AnT@FVFF77S0Q05N>

On Wed, Feb 21, 2024 at 01:59:03PM +0000, Mark Brown wrote:
> On Wed, Feb 21, 2024 at 01:52:38PM +0000, Mark Rutland wrote:
> > On Thu, Jan 25, 2024 at 03:11:12PM +0530, Anshuman Khandual wrote:
> 
> > Minor nit, but could we please list thse in order:
> 
> > 	BRBCR_EL1
> > 	BRBCR_EL12
> > 	BRBCR_EL2
> 
> > ... since that way the names are ordered alphnumerically, which is what we've
> > done for other groups (e.g. PIR_EL{1,12,2}), and it's the way the ARM ARM
> > happens to be ordered.
> 
> It's a good point about the sorting, though the file is currently mostly
> sorted by encoding rather than alphanumerically (similarly to how
> sysreg.h was done).

Sure, we're inconsistent. I'd just prefer that there's *some* local ordering
here, as the patch is neither ordered as above nor by encoding:

Sysreg       BRBCR_EL2       2       4       9       0       0
...
Sysreg       BRBCR_EL1       2       1       9       0       0
...
Sysreg       BRBCR_EL12      2       5       9       0       0

Mark.


From dmitry.baryshkov at linaro.org  Wed Feb 21 06:05:51 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Wed, 21 Feb 2024 16:05:51 +0200
Subject: [PATCH v5 1/4] dt-bindings: spmi: Add PMIC ARB v7 schema
In-Reply-To: <20240221-spmi-multi-master-support-v5-1-3255ca413a0b@linaro.org>
References: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org> <20240221-spmi-multi-master-support-v5-1-3255ca413a0b@linaro.org>
Message-ID: <CAA8EJposY0uf2S98VoOr5pOhJq9_i15mVSiEFP_r4jk+rPB0Ow@mail.gmail.com>

On Wed, 21 Feb 2024 at 14:52, Abel Vesa <abel.vesa at linaro.org> wrote:
>
> Add dedicated schema for PMIC ARB v7 as it allows multiple
> buses by declaring them as child nodes. These child nodes
> will follow the generic spmi bus bindings.
>
> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> ---
>  .../bindings/spmi/qcom,spmi-pmic-arb-v7.yaml       | 119 +++++++++++++++++++++
>  1 file changed, 119 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml
> new file mode 100644
> index 000000000000..8a93d2145aa5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-v7.yaml
> @@ -0,0 +1,119 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/spmi/qcom,spmi-pmic-arb-v7.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm SPMI Controller v7 (PMIC Arbiter)
> +
> +maintainers:
> +  - Stephen Boyd <sboyd at kernel.org>
> +
> +description: |
> +  The SPMI PMIC Arbiter v7 is found on Snapdragon chipsets. It is an SPMI
> +  controller with wrapping arbitration logic to allow for multiple on-chip
> +  devices to control up to 2 SPMI separate buses.
> +
> +  The PMIC Arbiter can also act as an interrupt controller, providing interrupts
> +  to slave devices.
> +
> +properties:
> +  compatible:
> +    const: qcom,spmi-pmic-arb-v7
> +
> +  reg:
> +    items:
> +      - description: core registers
> +      - description: tx-channel per virtual slave regosters
> +      - description: rx-channel (called observer) per virtual slave registers
> +
> +  reg-names:
> +    items:
> +      - const: core
> +      - const: chnls
> +      - const: obsrvr
> +
> +  ranges: true
> +
> +  '#address-cells':
> +    const: 2
> +
> +  '#size-cells':
> +    const: 2
> +
> +  qcom,ee:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 0
> +    maximum: 5
> +    description: >
> +      indicates the active Execution Environment identifier
> +
> +  qcom,channel:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 0
> +    maximum: 5
> +    description: >
> +      which of the PMIC Arb provided channels to use for accesses
> +
> +patternProperties:
> +  "spmi@[0-1]$":
> +    type: object
> +    $ref: /schemas/spmi/spmi.yaml
> +
> +required:
> +  - compatible
> +  - reg-names
> +  - qcom,ee
> +  - qcom,channel
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    spmi: arbiter at c400000 {
> +      compatible = "qcom,spmi-pmic-arb-v7";
> +      reg = <0x0c400000 0x3000>,
> +            <0x0c500000 0x4000000>,
> +            <0x0c440000 0x80000>;
> +      reg-names = "core", "chnls", "obsrvr";
> +
> +      qcom,ee = <0>;
> +      qcom,channel = <0>;
> +
> +      #address-cells = <2>;
> +      #size-cells = <2>;

Shouldn't there be an empty 'ranges;' property?

> +
> +      spmi_bus0: spmi at 0 {
> +        reg = <0 0x0c42d000 0 0x4000>,
> +              <0 0x0c4c0000 0 0x10000>;

Shouldn't the node address  (@0, @1) match the first address from reg property?

> +        reg-names = "cnfg", "intr";
> +
> +        interrupt-names = "periph_irq";
> +        interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-controller;
> +        #interrupt-cells = <4>;
> +
> +        qcom,bus-id = <0>;

I thought the goal was to drop qcom,bus-id ?

> +
> +        #address-cells = <2>;
> +        #size-cells = <0>;
> +      };
> +
> +      spmi_bus1: spmi at 1 {
> +        reg = <0 0x0c432000 0 0x4000>,
> +              <0 0x0c4d0000 0 0x10000>;
> +        reg-names = "cnfg", "intr";
> +
> +        interrupt-names = "periph_irq";
> +        interrupts-extended = <&pdc 3 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-controller;
> +        #interrupt-cells = <4>;
> +
> +        qcom,bus-id = <1>;
> +
> +        #address-cells = <2>;
> +        #size-cells = <0>;
> +      };
> +    };
>
> --
> 2.34.1
>


-- 
With best wishes
Dmitry


From robh+dt at kernel.org  Wed Feb 21 06:06:08 2024
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 21 Feb 2024 07:06:08 -0700
Subject: [PATCH 2/7] of: Create of_root if no dtb provided by firmware
In-Reply-To: <20240217060843.GA16460@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>
References: <20240217060843.GA16460@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>
Message-ID: <CAL_Jsq+Feu9NnzTNx=XU5vgHhibGAQXvkuTeWbpu8gJ3rVrzcw@mail.gmail.com>

On Fri, Feb 16, 2024 at 11:08?PM Saurabh Singh Sengar
<ssengar at linux.microsoft.com> wrote:
>
> On Fri, Feb 16, 2024 at 05:05:51PM -0800, Frank Rowand wrote:
> > When enabling CONFIG_OF on a platform where 'of_root' is not populated
> > by firmware, we end up without a root node. In order to apply overlays
> > and create subnodes of the root node, we need one. Create this root node
> > by unflattening an empty builtin dtb.
> >
> > If firmware provides a flattened device tree (FDT) then the FDT is
> > unflattened via setup_arch(). Otherwise, the call to
> > unflatten(_and_copy)?_device_tree() will create an empty root node.
> >
> > We make of_have_populated_dt() return true only if the DTB was loaded by
> > firmware so that existing callers don't change behavior after this
> > patch. The call in the of platform code is removed because it prevents
> > overlays from creating platform devices when the empty root node is
> > used.
> >
> > [sboyd at kernel.org: Update of_have_populated_dt() to treat this empty dtb
> > as not populated. Drop setup_of() initcall]
> >
> > Signed-off-by: Frank Rowand <frowand.list at gmail.com>
> > Link: https://lore.kernel.org/r/20230317053415.2254616-2-frowand.list at gmail.com
> > Cc: Rob Herring <robh+dt at kernel.org>
> > Signed-off-by: Stephen Boyd <sboyd at kernel.org>
> > ---


> > @@ -1645,6 +1635,21 @@ static inline bool of_device_is_system_power_controller(const struct device_node
> >       return of_property_read_bool(np, "system-power-controller");
> >  }
> >
> > +/**
> > + * of_have_populated_dt() - Has DT been populated by bootloader
> > + *
> > + * Return: True if a DTB has been populated by the bootloader and it isn't the
> > + * empty builtin one. False otherwise.
> > + */
> > +static inline bool of_have_populated_dt(void)
> > +{
> > +#ifdef CONFIG_OF
> > +     return of_property_present(of_root, "compatible");
>
> This adds the strict check for compatible which makes compatible
> to be mandatory for root nodes. So far, DeviceTree without compatible
> property in root nodes can work. Do we want to make this documented
> somewhere ?

It already is in the DT spec and schemas.

Rob


From broonie at kernel.org  Wed Feb 21 06:07:27 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 21 Feb 2024 14:07:27 +0000
Subject: [PATCH V16 1/8] arm64/sysreg: Add BRBE registers and fields
In-Reply-To: <ZdYDJPe1n5-V-AnT@FVFF77S0Q05N>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-2-anshuman.khandual@arm.com>
 <ZdYAJvZf4Ut5f5Rf@FVFF77S0Q05N>
 <e89ecbde-0967-4b8e-af77-3a72f207f3d7@sirena.org.uk>
 <ZdYDJPe1n5-V-AnT@FVFF77S0Q05N>
Message-ID: <7fe52cb9-12b9-4b03-8e55-08e59b4bef27@sirena.org.uk>

On Wed, Feb 21, 2024 at 02:05:24PM +0000, Mark Rutland wrote:
> On Wed, Feb 21, 2024 at 01:59:03PM +0000, Mark Brown wrote:
> > On Wed, Feb 21, 2024 at 01:52:38PM +0000, Mark Rutland wrote:

> > It's a good point about the sorting, though the file is currently mostly
> > sorted by encoding rather than alphanumerically (similarly to how
> > sysreg.h was done).

> Sure, we're inconsistent. I'd just prefer that there's *some* local ordering
> here, as the patch is neither ordered as above nor by encoding:

I agree, I'm just saying that if we're going to fix the ordering it'd
probably be better to go along with what the rest of the file is doing.
-------------- 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/20240221/a5b395a7/attachment-0001.sig>

From jgg at nvidia.com  Wed Feb 21 06:08:18 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Wed, 21 Feb 2024 10:08:18 -0400
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <20240221134923.GA7362@willie-the-truck>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240215134952.GA690@willie-the-truck>
 <20240215160135.GL1088888@nvidia.com>
 <20240221134923.GA7362@willie-the-truck>
Message-ID: <20240221140818.GA2635804@nvidia.com>

On Wed, Feb 21, 2024 at 01:49:23PM +0000, Will Deacon wrote:

> Very roughly, yes, although I'd go further and just return a bitmap of
> used qwords instead of tracking these bits. Basically, we could have some
> #defines saying which qwords are used by which configs, 

I don't think this will work well for CD's EPD0 case..

static void arm_smmu_get_cd_used(const __le64 *ent, __le64 *used_bits)
{
	used_bits[0] = cpu_to_le64(CTXDESC_CD_0_V);
	if (!(ent[0] & cpu_to_le64(CTXDESC_CD_0_V)))
		return;
	memset(used_bits, 0xFF, sizeof(struct arm_smmu_cd));

	/* EPD0 means T0SZ/TG0/IR0/OR0/SH0/TTB0 are IGNORED */
	if (ent[0] & cpu_to_le64(CTXDESC_CD_0_TCR_EPD0)) {
		used_bits[0] &= ~cpu_to_le64(
			CTXDESC_CD_0_TCR_T0SZ | CTXDESC_CD_0_TCR_TG0 |
			CTXDESC_CD_0_TCR_IRGN0 | CTXDESC_CD_0_TCR_ORGN0 |
			CTXDESC_CD_0_TCR_SH0);
		used_bits[1] &= ~cpu_to_le64(CTXDESC_CD_1_TTB0_MASK);
	}
}

> and then we can
> simplify the algorithm while retaining the ability to reject updates
> to qwords which we're not expecting.

It is not much simplification. arm_smmu_entry_qword_diff() gets a bit
shorter (not that it is complex anyhow) and other stuff gets worse.

> > We'd have to really start doing really hacky things like remove the
> > SHCFG as a used field entirely - but I think if you do that you break
> > the entire logic of the design and also go backwards to having
> > programming that only works if STEs are constructed in certain ways.
> 
> I would actually like to remove SHCFG as a used field. If the encoding
> was less whacky (i.e. if 0b00 always meant "use incoming"), then it would
> be easy, but it shouldn't be too hard to work around that.

But why?

You throw away the entire logic of the design, go back to subtly
coupling the two parts, and *for what*? Exactly what are we trying to
achieve in return? You haven't explained why we are still discussing
this afer 7 months. It really isn't worthwhile.

Jason


From y.varakala at phytec.de  Wed Feb 21 06:12:31 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Wed, 21 Feb 2024 15:12:31 +0100
Subject: [PATCH 0/4] Update of phyBOARD-Pollux-i.MX8MP
Message-ID: <20240221141235.47639-1-y.varakala@phytec.de>

Hello,

These patches will update the imx8mp-phyboard-pollux devicetree 
with the Muxing and RTC properties.

Thankyou,
yashwanth.

Benjamin Hahn (3):
  arm64: dts: imx8mp-phyboard-pollux: Set debug uart muxing to 0x140
  arm64: dts: imx8mp-phyboard-pollux: Reduce drive strength for eqos tx
    lines
  arm64: dts: imx8mp-phyboard-pollux: Disable pull-up for CD GPIO

Yashwanth Varakala (1):
  arm64: dts: imx8mp-phyboard-pollux: Add and update rtc devicetree node

 .../freescale/imx8mp-phyboard-pollux-rdk.dts  | 33 ++++++++++++++-----
 .../dts/freescale/imx8mp-phycore-som.dtsi     |  1 -
 2 files changed, 24 insertions(+), 10 deletions(-)

-- 
2.34.1



From y.varakala at phytec.de  Wed Feb 21 06:12:32 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Wed, 21 Feb 2024 15:12:32 +0100
Subject: [PATCH 1/4] arm64: dts: imx8mp-phyboard-pollux: Add and update rtc devicetree node
In-Reply-To: <20240221141235.47639-1-y.varakala@phytec.de>
References: <20240221141235.47639-1-y.varakala@phytec.de>
Message-ID: <20240221141235.47639-2-y.varakala@phytec.de>

The interrupt of the rtc is connected on the carrierboard
phyBOARD-i.MX8MP-Pollux.

RTC trickle-charger and level-switching-mode device tree properties
are depended on the phyboard-pollux design.

Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
---
 .../dts/freescale/imx8mp-phyboard-pollux-rdk.dts  | 15 +++++++++++++++
 .../boot/dts/freescale/imx8mp-phycore-som.dtsi    |  1 -
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index c8640cac3edc..96754ce633ed 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -139,6 +139,15 @@ &snvs_pwrkey {
 	status = "okay";
 };
 
+&rv3028 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rtc>;
+	interrupt-parent = <&gpio4>;
+	interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+	wakeup-source;
+	trickle-resistor-ohms = <3000>;
+};
+
 /* debug console */
 &uart1 {
 	pinctrl-names = "default";
@@ -295,6 +304,12 @@ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40
 		>;
 	};
 
+	pinctrl_rtc: rtcgrp {
+		fsl,pins = <
+			MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19	0x1C0
+		>;
+	};
+
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
 			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x40
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
index c976c3b6cbc6..e6ffa6a6b68b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
@@ -175,7 +175,6 @@ eeprom at 51 {
 	rv3028: rtc at 52 {
 		compatible = "microcrystal,rv3028";
 		reg = <0x52>;
-		trickle-resistor-ohms = <3000>;
 	};
 };
 
-- 
2.34.1



From y.varakala at phytec.de  Wed Feb 21 06:12:33 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Wed, 21 Feb 2024 15:12:33 +0100
Subject: [PATCH 2/4] arm64: dts: imx8mp-phyboard-pollux: Set debug uart muxing to 0x140
In-Reply-To: <20240221141235.47639-1-y.varakala@phytec.de>
References: <20240221141235.47639-1-y.varakala@phytec.de>
Message-ID: <20240221141235.47639-3-y.varakala@phytec.de>

From: Benjamin Hahn <B.Hahn at phytec.de>

Set Pull Resistors Enable bit to put signal into a defined state.

Signed-off-by: Yannic Moog <y.moog at phytec.de>
Signed-off-by: Benjamin Hahn <B.Hahn at phytec.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index 96754ce633ed..36b59d0c67f7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -312,8 +312,8 @@ MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19	0x1C0
 
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x40
-			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x40
+			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x140
+			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x140
 		>;
 	};
 
-- 
2.34.1



From y.varakala at phytec.de  Wed Feb 21 06:12:34 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Wed, 21 Feb 2024 15:12:34 +0100
Subject: [PATCH 3/4] arm64: dts: imx8mp-phyboard-pollux: Reduce drive strength for eqos tx lines
In-Reply-To: <20240221141235.47639-1-y.varakala@phytec.de>
References: <20240221141235.47639-1-y.varakala@phytec.de>
Message-ID: <20240221141235.47639-4-y.varakala@phytec.de>

From: Benjamin Hahn <B.Hahn at phytec.de>

Reduce drive strength on eqos tx lines for signal quality improvements.

Signed-off-by: Teresa Remmet <t.remmet at phytec.de>
Signed-off-by: Benjamin Hahn <B.Hahn at phytec.de>
---
 .../dts/freescale/imx8mp-phyboard-pollux-rdk.dts     | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index 36b59d0c67f7..d36ce66f08ef 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -248,12 +248,12 @@ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2		0x90
 			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3		0x90
 			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x90
 			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL		0x90
-			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x16
-			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x16
-			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x16
-			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x16
-			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x16
-			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x16
+			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x12
+			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x12
+			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x12
+			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x12
+			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x12
+			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x12
 			MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20			0x10
 		>;
 	};
-- 
2.34.1



From y.varakala at phytec.de  Wed Feb 21 06:12:35 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Wed, 21 Feb 2024 15:12:35 +0100
Subject: [PATCH 4/4] arm64: dts: imx8mp-phyboard-pollux: Disable pull-up for CD GPIO
In-Reply-To: <20240221141235.47639-1-y.varakala@phytec.de>
References: <20240221141235.47639-1-y.varakala@phytec.de>
Message-ID: <20240221141235.47639-5-y.varakala@phytec.de>

From: Benjamin Hahn <B.Hahn at phytec.de>

Removes the pull-up resistor from the pad's settings to keep it
consistent for all boards. We have pull-ups in hardware on all boards so we
don't need to set the additional one from the iomux controller.

Signed-off-by: Dominik Haller <d.haller at phytec.de>
Signed-off-by: Benjamin Hahn <B.Hahn at phytec.de>
---
 arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index d36ce66f08ef..1dfc5f429981 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -334,7 +334,7 @@ MX8MP_IOMUXC_SAI3_RXD__UART2_DCE_RTS	0x140
 
 	pinctrl_usdhc2_pins: usdhc2-gpiogrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12	0x1c4
+			MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12	0x40
 		>;
 	};
 
-- 
2.34.1



From javierm at redhat.com  Wed Feb 21 06:13:47 2024
From: javierm at redhat.com (Javier Martinez Canillas)
Date: Wed, 21 Feb 2024 15:13:47 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading compressed FW support
Message-ID: <20240221141350.3740488-1-javierm@redhat.com>

These options are needed by some Linux distributions (e.g: Fedora), so
let's enable them to make it easier for developers using such distros.

Signed-off-by: Javier Martinez Canillas <javierm at redhat.com>
Reviewed-by: Brian Masney <bmasney at redhat.com>
---

Changes in v2:
- Add Brian Masney's Reviewed-by tag.
- Drop CONFIG_MODULE_COMPRESS_XZ, it's OK to build uncompressed kernel modules.

 arch/arm64/configs/defconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 056a6cc546a4..b062d6ca7f5e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -241,6 +241,7 @@ CONFIG_PCI_EPF_TEST=m
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_FW_LOADER_USER_HELPER=y
+CONFIG_FW_LOADER_COMPRESS=y
 CONFIG_HISILICON_LPC=y
 CONFIG_TEGRA_ACONNECT=m
 CONFIG_MHI_BUS_PCI_GENERIC=m
@@ -275,6 +276,8 @@ CONFIG_MTD_NAND_FSL_IFC=y
 CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_MTD_UBI=m
+CONFIG_ZRAM=m
+CONFIG_ZRAM_WRITEBACK=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
 CONFIG_VIRTIO_BLK=y
@@ -1595,6 +1598,7 @@ CONFIG_HTE_TEGRA194_TEST=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
 CONFIG_BTRFS_FS=m
 CONFIG_BTRFS_FS_POSIX_ACL=y
 CONFIG_FANOTIFY=y
-- 
2.43.0



From thomas.richard at bootlin.com  Wed Feb 21 06:19:14 2024
From: thomas.richard at bootlin.com (Thomas Richard)
Date: Wed, 21 Feb 2024 15:19:14 +0100
Subject: [PATCH v3 02/18] pinctrl: pinctrl-single: remove dead code in
 suspend() and resume() callbacks
In-Reply-To: <ZdX28EJ9LtDWfVmH@smile.fi.intel.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com>
 <20240102-j7200-pcie-s2r-v3-2-5c2e4a3fac1f@bootlin.com>
 <Zc4tedAhqYX3bQcw@smile.fi.intel.com>
 <78add459-a96a-46c6-83ff-e2657d4d3db4@bootlin.com>
 <Zc96dSff5Y-dufrJ@smile.fi.intel.com>
 <a2c3c5b9-79a3-4793-892c-b1ab79b71c7d@bootlin.com>
 <ZdX28EJ9LtDWfVmH@smile.fi.intel.com>
Message-ID: <b0220b02-5058-42ec-ba06-251caa4813dc@bootlin.com>

On 2/21/24 14:13, Andy Shevchenko wrote:
> On Wed, Feb 21, 2024 at 12:01:43PM +0100, Thomas Richard wrote:
>> On 2/16/24 16:08, Andy Shevchenko wrote:
>>> On Fri, Feb 16, 2024 at 08:59:47AM +0100, Thomas Richard wrote:
>>>> On 2/15/24 16:27, Andy Shevchenko wrote:
>>>>> On Thu, Feb 15, 2024 at 04:17:47PM +0100, Thomas Richard wrote:
>>>>>> No need to check the pointer returned by platform_get_drvdata(), as
>>>>>> platform_set_drvdata() is called during the probe.
>>>>>
>>>>> This patch should go _after_ the next one, otherwise the commit message doesn't
>>>>> tell full story and the code change bring a potential regression.
>>>>
>>>> Hello Andy,
>>>>
>>>> I'm ok to move this patch after the next one.
>>>> But for my understanding, could you explain me why changing the order is
>>>> important in this case ?
>>>
>>> Old PM calls obviously can be called in different circumstances and these
>>> checks are important.
>>>
>>> Just squash these two patches to avoid additional churn and we are done.
>>
>> You mean invert the order instead of squash.
> 
> Either would work, but see how much churn in terms of changing just changed
> lines it adds.

OK thanks.

I'll squash the two patches. And I'll add a comment which explains that
I dropped some dead code.

Regards,

-- 
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From megi at xff.cz  Wed Feb 21 06:22:30 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Wed, 21 Feb 2024 15:22:30 +0100
Subject: [PATCH 3/3] drm/sun4i: Fix layer zpos change/atomic modesetting
In-Reply-To: <inuhwnlexpt6dpre4uailtvytjhms4uqeerzehbntczurhcxol@fc4nvkdwffdd>
References: <20240216190430.1374132-1-megi@xff.cz>
 <20240216190430.1374132-4-megi@xff.cz>
 <inuhwnlexpt6dpre4uailtvytjhms4uqeerzehbntczurhcxol@fc4nvkdwffdd>
Message-ID: <6n6fnjl3dw4dnmoygh3u72ebbubotpqyg67cwkuataw2vw6lwm@bhxrtjewjso6>

Hi Maxime,

On Wed, Feb 21, 2024 at 02:45:20PM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Fri, Feb 16, 2024 at 08:04:26PM +0100, Ond?ej Jirman wrote:
> > From: Ondrej Jirman <megi at xff.cz>
> > 
> > Identical configurations of planes can lead to different (and wrong)
> > layer -> pipe routing at HW level, depending on the order of atomic
> > plane changes.
> > 
> > For example:
> > 
> > - Layer 1 is configured to zpos 0 and thus uses pipe 0. No other layer
> >   is enabled. This is a typical situation at boot.
> > 
> > - When a compositor takes over and layer 3 is enabled,
> >   sun8i_ui_layer_enable() will get called with old_zpos=0 zpos=1, which
> >   will lead to incorrect disabling of pipe 0 and enabling of pipe 1.
> > 
> > What happens is that sun8i_ui_layer_enable() function may disable
> > blender pipes even if it is no longer assigned to its layer.
> > 
> > To correct this, move the routing setup out of individual plane's
> > atomic_update into crtc's atomic_update, where it can be calculated
> > and updated all at once.
> > 
> > Remove the atomic_disable callback because it is no longer needed.
> > 
> > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> 
> I don't have enough knowledge about the mixers code to comment on your
> patch, so I'll let Jernej review it. However, this feels to me like the
> pipe assignment is typically the sort of things that should be dealt
> with device-wide, and in atomic_check.

Yes, this is what this patch does. It moves blender setup from individual
planes' attomic commits to a single place in crtc atomic commit.

kind regards,
	o.

> If I'm talking non-sense, it would be great to mention at least why that
> can't be an option in the commit log.
> 
> Maxime




From krzysztof.kozlowski at linaro.org  Wed Feb 21 06:22:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 15:22:38 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <20240221141350.3740488-1-javierm@redhat.com>
References: <20240221141350.3740488-1-javierm@redhat.com>
Message-ID: <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>

On 21/02/2024 15:13, Javier Martinez Canillas wrote:
> These options are needed by some Linux distributions (e.g: Fedora), so

How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
use on my arm64 boards, does not have any problem.

I kind of repeat comments from similar patch earlier:
https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/

About XFS: I don't think it is needed to boot anything.

This is a defconfig, not a distro config. Please don't make it distro.

I will gladly support things needed by systemd or equivalent, but not
unusual filesystems needed by distro.

Best regards,
Krzysztof



From robh at kernel.org  Wed Feb 21 06:27:04 2024
From: robh at kernel.org (Rob Herring)
Date: Wed, 21 Feb 2024 07:27:04 -0700
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <ac9ddf79-6bc9-4daf-a271-82f8b3bca988@app.fastmail.com>
References: <20240221092826.748e70c4@canb.auug.org.au> <CAL_JsqKw9OXb=aOMni1qprzeWDBgmjdJef-6VAjwx0R--D+URw@mail.gmail.com>
 <ac9ddf79-6bc9-4daf-a271-82f8b3bca988@app.fastmail.com>
Message-ID: <CAL_Jsq+L7uPimQfATs14EWCbqRO1vxDUmPie7=cChTLCf2od2g@mail.gmail.com>

On Wed, Feb 21, 2024 at 7:00?AM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Wed, Feb 21, 2024, at 14:53, Rob Herring wrote:
> > On Tue, Feb 20, 2024 at 3:28?PM Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> >> arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> >>
> >> Introduced/exposed by commit
> >>
> >>   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
> >>
> >> I guess you missed some :-(
> >
> > No, Geert separately posted fixes for already.
>
> I did make the mistake of applying the final patch "dtc:
> Enable dtc interrupt_provider check" to the arm/fixes branch
> for 6.8 along with the other fixes.
>
> Clearly that should be separate and only go into mainline
> after there are no more regressions, but now I'm unsure
> about the other patches -- did you intend the dts fixes
> for 6.8 or for the coming merge window?

Either is fine with me. My intent was the whole series plus the
Renesas fix to be applied together. Anything new that crops up we can
fix on top.

Yes, there are lots of powerpc warnings, but those are on top of lots
of existing powerpc warnings no one seems to care about. I suppose we
can turn them off for powerpc if desired.

Rob


From frieder.schrempf at kontron.de  Wed Feb 21 06:29:29 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 21 Feb 2024 15:29:29 +0100
Subject: [PATCH 1/4] arm64: dts: imx8mp-phyboard-pollux: Add and update
 rtc devicetree node
In-Reply-To: <20240221141235.47639-2-y.varakala@phytec.de>
References: <20240221141235.47639-1-y.varakala@phytec.de>
 <20240221141235.47639-2-y.varakala@phytec.de>
Message-ID: <bae6a26a-a46c-445f-b44f-32d50146e36e@kontron.de>

On 21.02.24 15:12, Yashwanth Varakala wrote:
> [Sie erhalten nicht h?ufig E-Mails von y.varakala at phytec.de. Weitere Informationen, warum dies wichtig ist, finden Sie unter https://aka.ms/LearnAboutSenderIdentification ]
> 
> The interrupt of the rtc is connected on the carrierboard

s/rtc/RTC/
s/carrierboard/carrier board/

> phyBOARD-i.MX8MP-Pollux.
> 
> RTC trickle-charger and level-switching-mode device tree properties
> are depended on the phyboard-pollux design.

There is no way to control the backup switching mode via devicetree, so
this description doesn't match the code.

Also "are depended on" should probably be "depend on" or "are dependent
on". And when you scratch the "level-switching-mode" it's singular of
course.

> 
> Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
> ---
>  .../dts/freescale/imx8mp-phyboard-pollux-rdk.dts  | 15 +++++++++++++++
>  .../boot/dts/freescale/imx8mp-phycore-som.dtsi    |  1 -
>  2 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
> index c8640cac3edc..96754ce633ed 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
> @@ -139,6 +139,15 @@ &snvs_pwrkey {
>         status = "okay";
>  };
> 
> +&rv3028 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pinctrl_rtc>;
> +       interrupt-parent = <&gpio4>;
> +       interrupts = <19 IRQ_TYPE_LEVEL_LOW>;

The RTC is on the SoM and the interrupt line is routed from the SoM to
the carrier board and then back to the SoC? Is this really the case? I
would expect the IRQ to be routed within the SoM.

> +       wakeup-source;
> +       trickle-resistor-ohms = <3000>;
> +};
> +
>  /* debug console */
>  &uart1 {
>         pinctrl-names = "default";
> @@ -295,6 +304,12 @@ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19       0x40
>                 >;
>         };
> 
> +       pinctrl_rtc: rtcgrp {
> +               fsl,pins = <
> +                       MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19      0x1C0
> +               >;
> +       };
> +
>         pinctrl_uart1: uart1grp {
>                 fsl,pins = <
>                         MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX    0x40
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
> index c976c3b6cbc6..e6ffa6a6b68b 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
> @@ -175,7 +175,6 @@ eeprom at 51 {
>         rv3028: rtc at 52 {
>                 compatible = "microcrystal,rv3028";
>                 reg = <0x52>;
> -               trickle-resistor-ohms = <3000>;
>         };
>  };
> 
> --
> 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 linus.walleij at linaro.org  Wed Feb 21 06:31:35 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 15:31:35 +0100
Subject: [PATCH 18/23] gpio: nomadik: support mobileye,eyeq5-gpio
In-Reply-To: <20240214-mbly-gpio-v1-18-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-18-f88c0ccf372b@bootlin.com>
Message-ID: <CACRpkdYLBGsphNkmWyPXQZvFaO2hHGHGTMt1eqz-HAa2k5F3bg@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> We create a custom compatible for the STA2X11 IP block as integrated
> into the Mobileye EyeQ5 platform. Its wake and alternate functions have
> been disabled, we want to avoid touching those registers.
>
> We both do: (1) early return in functions that do not support the
> platform, but with warnings, and (2) avoid calling those functions in
> the first place.
>
> We ensure that pinctrl-nomadik is not used with this STA2X11 variant.
>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>

When testing I noticed that this patch breaks Ux500 (up until patch 17
all works fine!).

But I don't know why.

Trying to figure it out...

Yours,
Linus Walleij


From adeep at lexina.in  Wed Feb 21 06:36:16 2024
From: adeep at lexina.in (Viacheslav Bocharov)
Date: Wed, 21 Feb 2024 17:36:16 +0300
Subject: [PATCH v2 3/3] soc: amlogic: meson-gx-socinfo: add new definition for Amlogic A113X package
In-Reply-To: <20240221143654.544444-1-adeep@lexina.in>
References: <20240221143654.544444-1-adeep@lexina.in>
Message-ID: <20240221143654.544444-4-adeep@lexina.in>

Add new definition for Amlogix A113X soc found in JetHub D1/D1+ devices.

Signed-off-by: Viacheslav Bocharov <adeep at lexina.in>
---
 drivers/soc/amlogic/meson-gx-socinfo-internal.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/amlogic/meson-gx-socinfo-internal.h b/drivers/soc/amlogic/meson-gx-socinfo-internal.h
index 3ebb80972fc7..2028101bb9b2 100644
--- a/drivers/soc/amlogic/meson-gx-socinfo-internal.h
+++ b/drivers/soc/amlogic/meson-gx-socinfo-internal.h
@@ -78,6 +78,7 @@ static const struct meson_gx_package_id {
 	{ "962X", 0x24, 0x10, 0xf0 },
 	{ "962E", 0x24, 0x20, 0xf0 },
 	{ "A113X", 0x25, 0x37, 0xff },
+	{ "A113X", 0x25, 0x43, 0xff },
 	{ "A113D", 0x25, 0x22, 0xff },
 	{ "S905D2", 0x28, 0x10, 0xf0 },
 	{ "S905Y2", 0x28, 0x30, 0xf0 },
-- 
2.43.2



From adeep at lexina.in  Wed Feb 21 06:36:13 2024
From: adeep at lexina.in (Viacheslav Bocharov)
Date: Wed, 21 Feb 2024 17:36:13 +0300
Subject: [PATCH v2 0/3] soc: amlogic: add new meson-gx-socinfo-sm driver
Message-ID: <20240221143654.544444-1-adeep@lexina.in>

The Amlogic Meson SoC Secure Monitor implements a call to retrieve an
unique SoC ID starting from the GX Family and all new families.
But GX-family chips (e.g. GXB, GXL and newer) supports also 128-bit
chip ID. 128-bit chip ID consists 32-bit SoC version and 96-bit OTP data.

This is the third attempt to publish data from the Amlogic secure monitor
chipid call. After discussions with Neil Armstrong, it was decided to
publish the chipid call results through the soc driver. Since
soc_device_match cannot wait for the soc driver to load, and the secure
monitor calls in turn depend on the sm driver, it was necessary to create
a new driver rather than expand an existing one.

In the patches, in addition to writing the driver:
- convert commonly used structures and functions of the meson-gx-socinfo
driver to a header file.
- add secure-monitor references for amlogic,meson-gx-ao-secure sections
in dts files of the a1, axg, g12, gx families.


---

Changes V1 -> V2 [1]:
 - create cpu_id structure for socinfo variable
 - create meson_sm_chip_id for result of sm call
 - remove shared functions
 - move from funcs for bit operations to C bit fields

Links:
 - [1] https://lore.kernel.org/linux-arm-kernel/202311242104.RjBPI3uI-lkp at intel.com/T/


Viacheslav Bocharov (3):
  soc: amlogic: meson-gx-socinfo: move common code to header file
  soc: amlogic: meson-gx-socinfo-sm: Add Amlogic secure-monitor SoC
    Information driver
  soc: amlogic: meson-gx-socinfo: add new definition for Amlogic A113X
    package

 drivers/soc/amlogic/Kconfig                   |  10 +
 drivers/soc/amlogic/Makefile                  |   1 +
 .../soc/amlogic/meson-gx-socinfo-internal.h   | 121 +++++++++++
 drivers/soc/amlogic/meson-gx-socinfo-sm.c     | 192 ++++++++++++++++++
 drivers/soc/amlogic/meson-gx-socinfo.c        | 136 ++-----------
 5 files changed, 338 insertions(+), 122 deletions(-)
 create mode 100644 drivers/soc/amlogic/meson-gx-socinfo-internal.h
 create mode 100644 drivers/soc/amlogic/meson-gx-socinfo-sm.c


base-commit: 9fc1ccccfd8d53dc7936fe6d633f2373fc9f62e8
-- 
2.43.2



From adeep at lexina.in  Wed Feb 21 06:36:14 2024
From: adeep at lexina.in (Viacheslav Bocharov)
Date: Wed, 21 Feb 2024 17:36:14 +0300
Subject: [PATCH v2 1/3] soc: amlogic: meson-gx-socinfo: move common code to header file
In-Reply-To: <20240221143654.544444-1-adeep@lexina.in>
References: <20240221143654.544444-1-adeep@lexina.in>
Message-ID: <20240221143654.544444-2-adeep@lexina.in>

Move common constants and inline functions from meson-gx-socinfo driver
to header file. Create new structures for store meson64 cpu_id and chip_id.

Signed-off-by: Viacheslav Bocharov <adeep at lexina.in>
---
 .../soc/amlogic/meson-gx-socinfo-internal.h   | 120 ++++++++++++++++
 drivers/soc/amlogic/meson-gx-socinfo.c        | 136 ++----------------
 2 files changed, 134 insertions(+), 122 deletions(-)
 create mode 100644 drivers/soc/amlogic/meson-gx-socinfo-internal.h

diff --git a/drivers/soc/amlogic/meson-gx-socinfo-internal.h b/drivers/soc/amlogic/meson-gx-socinfo-internal.h
new file mode 100644
index 000000000000..3ebb80972fc7
--- /dev/null
+++ b/drivers/soc/amlogic/meson-gx-socinfo-internal.h
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2017 BayLibre, SAS
+ * Copyright (c) 2024 JetHome
+ * Author: Neil Armstrong <neil.armstrong at linaro.org>
+ * Author: Viacheslav Bocharov <adeep at lexina.in>
+ *
+ */
+
+#ifndef _MESON_GX_SOCINFO_INTERNAL_H_
+#define _MESON_GX_SOCINFO_INTERNAL_H_
+
+#include <linux/types.h>
+
+#define AO_SEC_SD_CFG8		0xe0
+#define AO_SEC_SOCINFO_OFFSET	AO_SEC_SD_CFG8
+
+union meson_cpu_id {
+	struct { // cpu_id v1
+		u32 layout_ver:4;
+		u32 reserved:4;
+		u32 chip_rev:8;
+		u32 pack_id:8;
+		u32 major_id:8;
+	} v1;
+	struct { // cpu_id v2
+		u32 major_id:8;
+		u32 chip_rev:8;
+		u32 pack_id:8;
+		u32 reserved:4;
+		u32 layout_ver:4;
+	} v2;
+	u32	raw;
+};
+
+struct meson_sm_chip_id {
+	u32 version;
+	union meson_cpu_id cpu_id;
+	u8 serial[12];
+};
+
+static const struct meson_gx_soc_id {
+	const char *name;
+	unsigned int id;
+} soc_ids[] = {
+	{ "GXBB", 0x1f },
+	{ "GXTVBB", 0x20 },
+	{ "GXL", 0x21 },
+	{ "GXM", 0x22 },
+	{ "TXL", 0x23 },
+	{ "TXLX", 0x24 },
+	{ "AXG", 0x25 },
+	{ "GXLX", 0x26 },
+	{ "TXHD", 0x27 },
+	{ "G12A", 0x28 },
+	{ "G12B", 0x29 },
+	{ "SM1", 0x2b },
+	{ "A1", 0x2c },
+};
+
+static const struct meson_gx_package_id {
+	const char *name;
+	unsigned int major_id;
+	unsigned int pack_id;
+	unsigned int pack_mask;
+} soc_packages[] = {
+	{ "S905", 0x1f, 0, 0x20 }, /* pack_id != 0x20 */
+	{ "S905H", 0x1f, 0x3, 0xf }, /* pack_id & 0xf == 0x3 */
+	{ "S905M", 0x1f, 0x20, 0xf0 }, /* pack_id == 0x20 */
+	{ "S905D", 0x21, 0, 0xf0 },
+	{ "S905X", 0x21, 0x80, 0xf0 },
+	{ "S905W", 0x21, 0xa0, 0xf0 },
+	{ "S905L", 0x21, 0xc0, 0xf0 },
+	{ "S905M2", 0x21, 0xe0, 0xf0 },
+	{ "S805X", 0x21, 0x30, 0xf0 },
+	{ "S805Y", 0x21, 0xb0, 0xf0 },
+	{ "S912", 0x22, 0, 0x0 }, /* Only S912 is known for GXM */
+	{ "962X", 0x24, 0x10, 0xf0 },
+	{ "962E", 0x24, 0x20, 0xf0 },
+	{ "A113X", 0x25, 0x37, 0xff },
+	{ "A113D", 0x25, 0x22, 0xff },
+	{ "S905D2", 0x28, 0x10, 0xf0 },
+	{ "S905Y2", 0x28, 0x30, 0xf0 },
+	{ "S905X2", 0x28, 0x40, 0xf0 },
+	{ "A311D", 0x29, 0x10, 0xf0 },
+	{ "S922X", 0x29, 0x40, 0xf0 },
+	{ "S905D3", 0x2b, 0x4, 0xf5 },
+	{ "S905X3", 0x2b, 0x5, 0xf5 },
+	{ "S905X3", 0x2b, 0x10, 0x3f },
+	{ "S905D3", 0x2b, 0x30, 0x3f },
+	{ "A113L", 0x2c, 0x0, 0xf8 },
+};
+
+static inline const char *socinfo_v1_to_package_id(union meson_cpu_id socinfo)
+{
+	int i;
+
+	for (i = 0 ; i < ARRAY_SIZE(soc_packages) ; ++i) {
+		if (soc_packages[i].major_id == socinfo.v1.major_id &&
+		    soc_packages[i].pack_id ==
+				(socinfo.v1.pack_id & soc_packages[i].pack_mask))
+			return soc_packages[i].name;
+	}
+
+	return "Unknown";
+}
+
+static inline const char *socinfo_v1_to_soc_id(union meson_cpu_id socinfo)
+{
+	int i;
+
+	for (i = 0 ; i < ARRAY_SIZE(soc_ids) ; ++i) {
+		if (soc_ids[i].id == socinfo.v1.major_id)
+			return soc_ids[i].name;
+	}
+
+	return "Unknown";
+}
+
+#endif /* _MESON_GX_SOCINFO_INTERNAL_H_ */
diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c
index 6abb730344ab..006f3b09940d 100644
--- a/drivers/soc/amlogic/meson-gx-socinfo.c
+++ b/drivers/soc/amlogic/meson-gx-socinfo.c
@@ -12,118 +12,10 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/sys_soc.h>
-#include <linux/bitfield.h>
 #include <linux/regmap.h>
 #include <linux/mfd/syscon.h>
 
-#define AO_SEC_SD_CFG8		0xe0
-#define AO_SEC_SOCINFO_OFFSET	AO_SEC_SD_CFG8
-
-#define SOCINFO_MAJOR	GENMASK(31, 24)
-#define SOCINFO_PACK	GENMASK(23, 16)
-#define SOCINFO_MINOR	GENMASK(15, 8)
-#define SOCINFO_MISC	GENMASK(7, 0)
-
-static const struct meson_gx_soc_id {
-	const char *name;
-	unsigned int id;
-} soc_ids[] = {
-	{ "GXBB", 0x1f },
-	{ "GXTVBB", 0x20 },
-	{ "GXL", 0x21 },
-	{ "GXM", 0x22 },
-	{ "TXL", 0x23 },
-	{ "TXLX", 0x24 },
-	{ "AXG", 0x25 },
-	{ "GXLX", 0x26 },
-	{ "TXHD", 0x27 },
-	{ "G12A", 0x28 },
-	{ "G12B", 0x29 },
-	{ "SM1", 0x2b },
-	{ "A1", 0x2c },
-};
-
-static const struct meson_gx_package_id {
-	const char *name;
-	unsigned int major_id;
-	unsigned int pack_id;
-	unsigned int pack_mask;
-} soc_packages[] = {
-	{ "S905", 0x1f, 0, 0x20 }, /* pack_id != 0x20 */
-	{ "S905H", 0x1f, 0x3, 0xf }, /* pack_id & 0xf == 0x3 */
-	{ "S905M", 0x1f, 0x20, 0xf0 }, /* pack_id == 0x20 */
-	{ "S905D", 0x21, 0, 0xf0 },
-	{ "S905X", 0x21, 0x80, 0xf0 },
-	{ "S905W", 0x21, 0xa0, 0xf0 },
-	{ "S905L", 0x21, 0xc0, 0xf0 },
-	{ "S905M2", 0x21, 0xe0, 0xf0 },
-	{ "S805X", 0x21, 0x30, 0xf0 },
-	{ "S805Y", 0x21, 0xb0, 0xf0 },
-	{ "S912", 0x22, 0, 0x0 }, /* Only S912 is known for GXM */
-	{ "962X", 0x24, 0x10, 0xf0 },
-	{ "962E", 0x24, 0x20, 0xf0 },
-	{ "A113X", 0x25, 0x37, 0xff },
-	{ "A113D", 0x25, 0x22, 0xff },
-	{ "S905D2", 0x28, 0x10, 0xf0 },
-	{ "S905Y2", 0x28, 0x30, 0xf0 },
-	{ "S905X2", 0x28, 0x40, 0xf0 },
-	{ "A311D", 0x29, 0x10, 0xf0 },
-	{ "S922X", 0x29, 0x40, 0xf0 },
-	{ "S905D3", 0x2b, 0x4, 0xf5 },
-	{ "S905X3", 0x2b, 0x5, 0xf5 },
-	{ "S905X3", 0x2b, 0x10, 0x3f },
-	{ "S905D3", 0x2b, 0x30, 0x3f },
-	{ "A113L", 0x2c, 0x0, 0xf8 },
-};
-
-static inline unsigned int socinfo_to_major(u32 socinfo)
-{
-	return FIELD_GET(SOCINFO_MAJOR, socinfo);
-}
-
-static inline unsigned int socinfo_to_minor(u32 socinfo)
-{
-	return FIELD_GET(SOCINFO_MINOR, socinfo);
-}
-
-static inline unsigned int socinfo_to_pack(u32 socinfo)
-{
-	return FIELD_GET(SOCINFO_PACK, socinfo);
-}
-
-static inline unsigned int socinfo_to_misc(u32 socinfo)
-{
-	return FIELD_GET(SOCINFO_MISC, socinfo);
-}
-
-static const char *socinfo_to_package_id(u32 socinfo)
-{
-	unsigned int pack = socinfo_to_pack(socinfo);
-	unsigned int major = socinfo_to_major(socinfo);
-	int i;
-
-	for (i = 0 ; i < ARRAY_SIZE(soc_packages) ; ++i) {
-		if (soc_packages[i].major_id == major &&
-		    soc_packages[i].pack_id ==
-				(pack & soc_packages[i].pack_mask))
-			return soc_packages[i].name;
-	}
-
-	return "Unknown";
-}
-
-static const char *socinfo_to_soc_id(u32 socinfo)
-{
-	unsigned int id = socinfo_to_major(socinfo);
-	int i;
-
-	for (i = 0 ; i < ARRAY_SIZE(soc_ids) ; ++i) {
-		if (soc_ids[i].id == id)
-			return soc_ids[i].name;
-	}
-
-	return "Unknown";
-}
+#include "meson-gx-socinfo-internal.h"
 
 static int __init meson_gx_socinfo_init(void)
 {
@@ -131,7 +23,7 @@ static int __init meson_gx_socinfo_init(void)
 	struct soc_device *soc_dev;
 	struct device_node *np;
 	struct regmap *regmap;
-	unsigned int socinfo;
+	union meson_cpu_id socinfo;
 	struct device *dev;
 	int ret;
 
@@ -160,11 +52,11 @@ static int __init meson_gx_socinfo_init(void)
 		return -ENODEV;
 	}
 
-	ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo);
+	ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo.raw);
 	if (ret < 0)
 		return ret;
 
-	if (!socinfo) {
+	if (!socinfo.raw) {
 		pr_err("%s: invalid chipid value\n", __func__);
 		return -EINVAL;
 	}
@@ -175,13 +67,13 @@ static int __init meson_gx_socinfo_init(void)
 
 	soc_dev_attr->family = "Amlogic Meson";
 	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x:%x - %x:%x",
-					   socinfo_to_major(socinfo),
-					   socinfo_to_minor(socinfo),
-					   socinfo_to_pack(socinfo),
-					   socinfo_to_misc(socinfo));
+					   socinfo.v1.major_id,
+					   socinfo.v1.chip_rev,
+					   socinfo.v1.pack_id,
+					   (socinfo.v1.reserved<<4) + socinfo.v1.layout_ver);
 	soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%s (%s)",
-					 socinfo_to_soc_id(socinfo),
-					 socinfo_to_package_id(socinfo));
+					 socinfo_v1_to_soc_id(socinfo),
+					 socinfo_v1_to_package_id(socinfo));
 
 	soc_dev = soc_device_register(soc_dev_attr);
 	if (IS_ERR(soc_dev)) {
@@ -194,10 +86,10 @@ static int __init meson_gx_socinfo_init(void)
 
 	dev_info(dev, "Amlogic Meson %s Revision %x:%x (%x:%x) Detected\n",
 			soc_dev_attr->soc_id,
-			socinfo_to_major(socinfo),
-			socinfo_to_minor(socinfo),
-			socinfo_to_pack(socinfo),
-			socinfo_to_misc(socinfo));
+			socinfo.v1.major_id,
+			socinfo.v1.chip_rev,
+			socinfo.v1.pack_id,
+			(socinfo.v1.reserved<<4) + socinfo.v1.layout_ver);
 
 	return 0;
 }
-- 
2.43.2



From adeep at lexina.in  Wed Feb 21 06:36:15 2024
From: adeep at lexina.in (Viacheslav Bocharov)
Date: Wed, 21 Feb 2024 17:36:15 +0300
Subject: [PATCH v2 2/3] soc: amlogic: meson-gx-socinfo-sm: Add Amlogic secure-monitor SoC Information driver
In-Reply-To: <20240221143654.544444-1-adeep@lexina.in>
References: <20240221143654.544444-1-adeep@lexina.in>
Message-ID: <20240221143654.544444-3-adeep@lexina.in>

Amlogic SoCs have a SoC information secure-monitor call for SoC type,
package type, revision information and chipid.
This patchs adds support for secure-monitor call decoding and exposing
with the SoC bus infrastructure in addition to the previous SoC
Information driver.

Signed-off-by: Viacheslav Bocharov <adeep at lexina.in>
---
 drivers/soc/amlogic/Kconfig               |  10 ++
 drivers/soc/amlogic/Makefile              |   1 +
 drivers/soc/amlogic/meson-gx-socinfo-sm.c | 192 ++++++++++++++++++++++
 3 files changed, 203 insertions(+)
 create mode 100644 drivers/soc/amlogic/meson-gx-socinfo-sm.c

diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig
index d08e398bdad4..edb724e67968 100644
--- a/drivers/soc/amlogic/Kconfig
+++ b/drivers/soc/amlogic/Kconfig
@@ -26,6 +26,16 @@ config MESON_GX_SOCINFO
 	  Say yes to support decoding of Amlogic Meson GX SoC family
 	  information about the type, package and version.
 
+config MESON_GX_SOCINFO_SM
+	bool "Amlogic Meson GX SoC Information driver via Secure Monitor"
+	depends on (ARM64 && ARCH_MESON && MESON_GX_SOCINFO && MESON_SM) || COMPILE_TEST
+	default MESON_GX_SOCINFO && MESON_SM
+	select SOC_BUS
+	help
+	  Say yes to support decoding of Amlogic Meson GX SoC family
+	  information about the type, package and version via secure
+	  monitor call.
+
 config MESON_MX_SOCINFO
 	bool "Amlogic Meson MX SoC Information driver"
 	depends on (ARM && ARCH_MESON) || COMPILE_TEST
diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile
index c25f835e6a26..45d9d6f5904c 100644
--- a/drivers/soc/amlogic/Makefile
+++ b/drivers/soc/amlogic/Makefile
@@ -2,4 +2,5 @@
 obj-$(CONFIG_MESON_CANVAS) += meson-canvas.o
 obj-$(CONFIG_MESON_CLK_MEASURE) += meson-clk-measure.o
 obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
+obj-$(CONFIG_MESON_GX_SOCINFO_SM) += meson-gx-socinfo-sm.o
 obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o
diff --git a/drivers/soc/amlogic/meson-gx-socinfo-sm.c b/drivers/soc/amlogic/meson-gx-socinfo-sm.c
new file mode 100644
index 000000000000..e30e1d2feb61
--- /dev/null
+++ b/drivers/soc/amlogic/meson-gx-socinfo-sm.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2017 BayLibre, SAS
+ * Copyright (c) 2024 JetHome
+ * Author: Neil Armstrong <neil.armstrong at linaro.org>
+ * Author: Viacheslav Bocharov <adeep at lexina.in>
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#include <linux/firmware/meson/meson_sm.h>
+
+#include "meson-gx-socinfo-internal.h"
+
+static char *socinfo_get_chipid(struct device *dev, struct meson_sm_firmware *fw,
+			       union meson_cpu_id *socinfo)
+{
+	char *buf;
+	struct meson_sm_chip_id *id_buf;
+	int ret;
+
+	id_buf = devm_kzalloc(dev, sizeof(struct meson_sm_chip_id)+1, GFP_KERNEL);
+	if (!id_buf)
+		return NULL;
+
+	ret = meson_sm_call_read(fw, id_buf, sizeof(struct meson_sm_chip_id), SM_GET_CHIP_ID,
+				 2, 0, 0, 0, 0);
+	if (ret < 0) {
+		kfree(id_buf);
+		return NULL;
+	}
+	dev_info(dev, "got sm version call %i\n", id_buf->version);
+
+	if (id_buf->version != 2) {
+
+		u8 tmp;
+		/**
+		 * Legacy 12-byte chip ID read out, transform data
+		 * to expected order format
+		 */
+		memmove((void *)&id_buf->serial, (void *)&id_buf->cpu_id, 12);
+		for (int i = 0; i < 6; i++) {
+			tmp = id_buf->serial[i];
+			id_buf->serial[i] = id_buf->serial[11 - i];
+			id_buf->serial[11 - i] = tmp;
+		}
+		id_buf->cpu_id.v2.major_id = socinfo->v1.major_id;
+		id_buf->cpu_id.v2.pack_id = socinfo->v1.pack_id;
+		id_buf->cpu_id.v2.chip_rev = socinfo->v1.chip_rev;
+		id_buf->cpu_id.v2.reserved = socinfo->v1.reserved;
+		id_buf->cpu_id.v2.layout_ver = socinfo->v1.layout_ver;
+	} else {
+		/**
+		 * rewrite socinfo from regmap with value from secure monitor call
+		 */
+		socinfo->v1.major_id = id_buf->cpu_id.v2.major_id;
+		socinfo->v1.pack_id = id_buf->cpu_id.v2.pack_id;
+		socinfo->v1.chip_rev = id_buf->cpu_id.v2.chip_rev;
+		socinfo->v1.reserved = id_buf->cpu_id.v2.reserved;
+		socinfo->v1.layout_ver = id_buf->cpu_id.v2.layout_ver;
+	}
+
+	buf = kasprintf(GFP_KERNEL, "%4phN%12phN", &(id_buf->cpu_id), &(id_buf->serial));
+
+	kfree(id_buf);
+
+	return buf;
+}
+
+static int meson_gx_socinfo_sm_probe(struct platform_device *pdev)
+{
+	struct soc_device_attribute *soc_dev_attr;
+	struct soc_device *soc_dev;
+	struct device_node *sm_np;
+	struct meson_sm_firmware *fw;
+	struct regmap *regmap;
+	union meson_cpu_id socinfo;
+	struct device *dev;
+	int ret;
+
+	/* check if chip-id is available */
+	if (!of_property_read_bool(pdev->dev.of_node, "amlogic,has-chip-id"))
+		return -ENODEV;
+
+	/* node should be a syscon */
+	regmap = syscon_node_to_regmap(pdev->dev.of_node);
+	if (IS_ERR(regmap)) {
+		dev_err(&pdev->dev, "failed to get regmap\n");
+		return -ENODEV;
+	}
+
+	sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+	if (!sm_np) {
+		dev_err(&pdev->dev, "no secure-monitor node found\n");
+		return -ENODEV;
+	}
+
+	fw = meson_sm_get(sm_np);
+	of_node_put(sm_np);
+	if (!fw) {
+		dev_info(&pdev->dev, "secure-monitor device not ready, probe later\n");
+		return -EPROBE_DEFER;
+	}
+
+	ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo.raw);
+	if (ret < 0)
+		return ret;
+
+	if (!socinfo.raw) {
+		dev_err(&pdev->dev, "invalid regmap chipid value\n");
+		return -EINVAL;
+	}
+
+	soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr),
+				    GFP_KERNEL);
+	if (!soc_dev_attr)
+		return -ENOMEM;
+
+	soc_dev_attr->serial_number = socinfo_get_chipid(&pdev->dev, fw, &socinfo);
+
+	soc_dev_attr->family = "Amlogic Meson";
+	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x:%x - %x:%x",
+					   socinfo.v1.major_id,
+					   socinfo.v1.chip_rev,
+					   socinfo.v1.pack_id,
+					   (socinfo.v1.reserved<<4) + socinfo.v1.layout_ver);
+	soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%s (%s)",
+					 socinfo_v1_to_soc_id(socinfo),
+					 socinfo_v1_to_package_id(socinfo));
+
+	soc_dev = soc_device_register(soc_dev_attr);
+
+
+	if (IS_ERR(soc_dev)) {
+		kfree(soc_dev_attr->revision);
+		kfree_const(soc_dev_attr->soc_id);
+		kfree(soc_dev_attr);
+		return PTR_ERR(soc_dev);
+	}
+
+	dev = soc_device_to_device(soc_dev);
+	platform_set_drvdata(pdev, soc_dev);
+
+	dev_info(dev, "Amlogic Meson %s Revision %x:%x (%x:%x) Detected (SM)\n",
+			soc_dev_attr->soc_id,
+			socinfo.v1.major_id,
+			socinfo.v1.chip_rev,
+			socinfo.v1.pack_id,
+			(socinfo.v1.reserved<<4) + socinfo.v1.layout_ver);
+
+	return PTR_ERR_OR_ZERO(dev);
+}
+
+
+static int meson_gx_socinfo_sm_remove(struct platform_device *pdev)
+{
+	struct soc_device *soc_dev = platform_get_drvdata(pdev);
+
+	soc_device_unregister(soc_dev);
+	return 0;
+}
+
+static const struct of_device_id meson_gx_socinfo_match[] = {
+	{ .compatible = "amlogic,meson-gx-ao-secure", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, meson_gx_socinfo_match);
+
+static struct platform_driver meson_gx_socinfo_driver = {
+	.probe = meson_gx_socinfo_sm_probe,
+	.remove	= meson_gx_socinfo_sm_remove,
+	.driver = {
+		.name = "meson-gx-socinfo-sm",
+		.of_match_table = meson_gx_socinfo_match,
+	},
+};
+
+
+module_platform_driver(meson_gx_socinfo_driver);
+
+MODULE_AUTHOR("Viacheslav Bocharov <adeep at lexina.in>");
+MODULE_DESCRIPTION("Amlogic Meson GX SOC SM driver");
+MODULE_LICENSE("GPL");
-- 
2.43.2



From linus.walleij at linaro.org  Wed Feb 21 06:37:15 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 15:37:15 +0100
Subject: [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from drivers/pinctrl/nomadik/
In-Reply-To: <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com> <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>
Message-ID: <CACRpkdaSMJBFrmbTu+C1Ls8HkLH4FZsAQ6t7dC76+sVTXXHEyw@mail.gmail.com>

Hi Theo,

just a quick note here:

On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> +config GPIO_NOMADIK
> +       bool "Nomadik GPIO driver"
> +       depends on ARCH_U8500 || ARCH_NOMADIK || COMPILE_TEST
> +       select OF_GPIO
> +       select GPIOLIB_IRQCHIP

Could you add:

default PINCTRL_NOMADIK

so it is turned on by default when we have that, since they are jitted together
so closely.

Yours,
Linus Walleij


From alexander.stein at ew.tq-group.com  Wed Feb 21 06:40:12 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 21 Feb 2024 15:40:12 +0100
Subject: [PATCH 1/1] arm64: dts: mba8xx: Add missing #interrupt-cells
Message-ID: <20240221144012.533946-1-alexander.stein@ew.tq-group.com>

The GPIO expander is a interrupt-controller, so add the missing
 #interrupt-cells property as well.

Fixes: 71363a485ad0c ("arm64: dts: freescale: add initial device tree for TQMa8Xx")
Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm64/boot/dts/freescale/mba8xx.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/mba8xx.dtsi b/arch/arm64/boot/dts/freescale/mba8xx.dtsi
index 4a9986409947f..b06f7fe8f85c5 100644
--- a/arch/arm64/boot/dts/freescale/mba8xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8xx.dtsi
@@ -263,6 +263,7 @@ expander: gpio at 70 {
 		interrupt-parent = <&lsio_gpio4>;
 		interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-controller;
+		#interrupt-cells = <2>;
 		vcc-supply = <&reg_1v8>;
 
 		gpio-line-names = "", "LED_A",
-- 
2.34.1



From alexander.stein at ew.tq-group.com  Wed Feb 21 06:42:00 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 21 Feb 2024 15:42:00 +0100
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <CAL_Jsq+2ri0JsmuU184YGj=p53jSxn+8EZq_FuBbMjsVyNLvtw@mail.gmail.com>
References: <20240221092826.748e70c4@canb.auug.org.au> <20240221163010.5f81813a@canb.auug.org.au> <CAL_Jsq+2ri0JsmuU184YGj=p53jSxn+8EZq_FuBbMjsVyNLvtw@mail.gmail.com>
Message-ID: <13457561.uLZWGnKmhe@steina-w>

Hi Rob,

Am Mittwoch, 21. Februar 2024, 14:58:32 CET schrieb Rob Herring:
> On Tue, Feb 20, 2024 at 10:30?PM Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> >
> > Hi all,
> >
> > On Wed, 21 Feb 2024 09:28:26 +1100 Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> > >
> > > After merging the arm-soc-fixes tree, today's linux-next build (arm
> > > multi_v7_defconfig) produced this warning:
> > >
> > > arch/arm/boot/dts/renesas/r8a7790-lager.dts:444.11-458.5: Warning (interrupt_provider): /i2c-mux4/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > > arch/arm/boot/dts/renesas/r8a7790-lager.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > > arch/arm/boot/dts/renesas/r8a7792-blanche.dts:376.10-392.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > > arch/arm/boot/dts/renesas/r8a7792-blanche.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > > arch/arm/boot/dts/renesas/r8a7790-stout.dts:344.10-362.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > > arch/arm/boot/dts/renesas/r8a7790-stout.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > > arch/arm/boot/dts/renesas/r8a7791-koelsch.dts:816.10-830.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > > arch/arm/boot/dts/renesas/r8a7791-koelsch.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > > arch/arm/boot/dts/renesas/r8a7791-porter.dts:410.10-420.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 5a: Missing '#interrupt-cells' in interrupt provider
> > > arch/arm/boot/dts/renesas/r8a7791-porter.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > > arch/arm/boot/dts/renesas/r8a7794-alt.dts:450.10-464.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > > arch/arm/boot/dts/renesas/r8a7794-alt.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > > arch/arm/boot/dts/renesas/r8a7794-silk.dts:436.10-454.4: Warning (interrupt_provider): /soc/i2c at e6510000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > > arch/arm/boot/dts/renesas/r8a7794-silk.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > > arch/arm/boot/dts/renesas/r8a7793-gose.dts:756.10-770.4: Warning (interrupt_provider): /soc/i2c at e60b0000/pmic at 58: Missing '#interrupt-cells' in interrupt provider
> > > arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > >
> > > Introduced/exposed by commit
> > >
> > >   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
> > >
> > > I guess you missed some :-(
> >
> > Also these from the arm64 defconfig build:
> >
> > arch/arm64/boot/dts/freescale/mba8xx.dtsi:233.20-249.4: Warning (interrupt_provider): /bus at 5a000000/i2c at 5a810000/gpio at 70: Missing '#interrupt-cells' in interrupt provider
> > arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > arch/arm64/boot/dts/freescale/mba8xx.dtsi:233.20-249.4: Warning (interrupt_provider): /bus at 5a000000/i2c at 5a810000/gpio at 70: Missing '#interrupt-cells' in interrupt provider
> > arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp-mba8xx.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> 
> Looks like a new platform in next.
> 
> Alexander, Can you fix these?

Thanks for reminding me. This was already fixed on my queue.
Just send the patch, you are on CC as well.

Thanks and best regards,
Alexander
-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From krzysztof.kozlowski at linaro.org  Wed Feb 21 06:42:31 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 15:42:31 +0100
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
References: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
 <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
Message-ID: <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>

On 21/02/2024 13:01, Ghennadi Procopciuc wrote:
> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> 
> Add myself as a maintainer of the NXP S32G DT files.

No need for cover letters for single patches. OTOH, this commit msg is
empty...

Plus your patch looks corrupted (wrong encoding): F??rber

BTW, did you contribute anything to the upstream Linux kernel? Do you
know the process? Downstream does not really matter.


Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Wed Feb 21 06:45:20 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 15:45:20 +0100
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
References: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
 <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
Message-ID: <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>

On 21/02/2024 15:42, Krzysztof Kozlowski wrote:
> On 21/02/2024 13:01, Ghennadi Procopciuc wrote:
>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>
>> Add myself as a maintainer of the NXP S32G DT files.
> 
> No need for cover letters for single patches. OTOH, this commit msg is
> empty...
> 
> Plus your patch looks corrupted (wrong encoding): F??rber
> 
> BTW, did you contribute anything to the upstream Linux kernel? Do you
> know the process? Downstream does not really matter.

I found the answer:

From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>

Does not look like. Please get some upstream work experience first.

https://lore.kernel.org/all/?q=f%3Aghennadi.procopciuc%40oss.nxp.com

Best regards,
Krzysztof



From mripard at redhat.com  Wed Feb 21 06:48:33 2024
From: mripard at redhat.com (Maxime Ripard)
Date: Wed, 21 Feb 2024 15:48:33 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
Message-ID: <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>

On Wed, Feb 21, 2024 at 03:22:38PM +0100, Krzysztof Kozlowski wrote:
> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
> > These options are needed by some Linux distributions (e.g: Fedora), so
> 
> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
> use on my arm64 boards, does not have any problem.

Is it relevant in any way?

I'm sure Debian can boot without MEMORY_HOTREMOVE, or BRIDGE, or
NUMA_BALANCING, or BPF_JIT, or NFS_FS, yet all of them are enabled. Let
me know if you want hundreds more examples.

> I kind of repeat comments from similar patch earlier:
> https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/
> 
> About XFS: I don't think it is needed to boot anything.

Just like 9P_FS, NFS or UBIFS.

> This is a defconfig, not a distro config. Please don't make it distro.
> 
> I will gladly support things needed by systemd or equivalent, but not
> unusual filesystems needed by distro.

It's a defconfig. It's whatever people want it to be. Or we need to come
up with a clearly defined set of rules of what is acceptable in that
defconfig or not, and prune every option that isn't.

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/20240221/525234ff/attachment.sig>

From puranjay12 at gmail.com  Wed Feb 21 06:51:04 2024
From: puranjay12 at gmail.com (Puranjay Mohan)
Date: Wed, 21 Feb 2024 14:51:04 +0000
Subject: [PATCH bpf-next v8 0/2] bpf, arm64: use BPF prog pack allocator in BPF JIT
Message-ID: <20240221145106.105995-1-puranjay12@gmail.com>

Changes in V7 => V8:
V7: https://lore.kernel.org/bpf/20240125133159.85086-1-puranjay12 at gmail.com/
1. Rebase on bpf-next/master
2. Fix __text_poke() by removing usage of 'ret' that was never set.

Changes in V6 => V7:
V6: https://lore.kernel.org/all/20240124164917.119997-1-puranjay12 at gmail.com/
1. Rebase on bpf-next/master.

Changes in V5 => V6:
V5: https://lore.kernel.org/all/20230908144320.2474-1-puranjay12 at gmail.com/
1. Implement a text poke api to reduce code repeatition.
2. Use flush_icache_range() in place of caches_clean_inval_pou() in the
   functions that modify code.
3. Optimize the bpf_jit_free() by not copying the all instructions on
   the rw image to the ro_image

Changes in V4 => v5:
1. Remove the patch for making prog pack allocator portable as it will come
   through the RISCV tree[1].

2. Add a new function aarch64_insn_set() to be used in
   bpf_arch_text_invalidate() for putting illegal instructions after a
   program is removed. The earlier implementation of bpf_arch_text_invalidate()
   was calling aarch64_insn_patch_text_nosync() in a loop and making it slow
   because each call invalidated the cache.

   Here is test_tag now:
   [root at ip-172-31-6-176 bpf]# time ./test_tag
   test_tag: OK (40945 tests)

   real    0m19.695s
   user    0m1.514s
   sys     0m17.841s

   test_tag without these patches:
   [root at ip-172-31-6-176 bpf]# time ./test_tag
   test_tag: OK (40945 tests)

   real    0m21.487s
   user    0m1.647s
   sys     0m19.106s

   test_tag in the previous version was really slow > 2 minutes. see [2]

3. Add cache invalidation in aarch64_insn_copy() so other users can call the
   function without worrying about the cache. Currently only bpf_arch_text_copy()
   is using it, but there might be more users in the future.

Chanes in V3 => V4: Changes only in 3rd patch
1. Fix the I-cache maintenance: Clean the data cache and invalidate the i-Cache
   only *after* the instructions have been copied to the ROX region.

Chanes in V2 => V3: Changes only in 3rd patch
1. Set prog = orig_prog; in the failure path of bpf_jit_binary_pack_finalize()
call.
2. Add comments explaining the usage of the offsets in the exception table.

Changes in v1 => v2:
1. Make the naming consistent in the 3rd patch:
   ro_image and image
   ro_header and header
   ro_image_ptr and image_ptr
2. Use names dst/src in place of addr/opcode in second patch.
3. Add Acked-by: Song Liu <song at kernel.org> in 1st and 2nd patch.

BPF programs currently consume a page each on ARM64. For systems with many BPF
programs, this adds significant pressure to instruction TLB. High iTLB pressure
usually causes slow down for the whole system.

Song Liu introduced the BPF prog pack allocator[3] to mitigate the above issue.
It packs multiple BPF programs into a single huge page. It is currently only
enabled for the x86_64 BPF JIT.

This patch series enables the BPF prog pack allocator for the ARM64 BPF JIT.

====================================================
Performance Analysis of prog pack allocator on ARM64
====================================================

To test the performance of the BPF prog pack allocator on ARM64, a stresser
tool[4] was built. This tool loads 8 BPF programs on the system and triggers
5 of them in an infinite loop by doing system calls.

The runner script starts 20 instances of the above which loads 8*20=160 BPF
programs on the system, 5*20=100 of which are being constantly triggered.

In the above environment we try to build Python-3.8.4 and try to find different
iTLB metrics for the compilation done by gcc-12.2.0.

The source code[5] is  configured with the following command:
./configure --enable-optimizations --with-ensurepip=install

Then the runner script is executed with the following command:
./run.sh "perf stat -e ITLB_WALK,L1I_TLB,INST_RETIRED,iTLB-load-misses -a make -j32"

This builds Python while 160 BPF programs are loaded and 100 are being constantly
triggered and measures iTLB related metrics.

The output of the above command is discussed below before and after enabling the
BPF prog pack allocator.

The tests were run on qemu-system-aarch64 with 32 cpus, 4G memory, -machine virt,
-cpu host, and -enable-kvm.

Results
-------

Before enabling prog pack allocator:
------------------------------------

Performance counter stats for 'system wide':

         333278635      ITLB_WALK
     6762692976558      L1I_TLB
    25359571423901      INST_RETIRED
       15824054789      iTLB-load-misses

     189.029769053 seconds time elapsed

After enabling prog pack allocator:
-----------------------------------

Performance counter stats for 'system wide':

         190333544      ITLB_WALK
     6712712386528      L1I_TLB
    25278233304411      INST_RETIRED
        5716757866      iTLB-load-misses

     185.392650561 seconds time elapsed

Improvements in metrics
-----------------------

Compilation time                             ---> 1.92% faster
iTLB-load-misses/Sec (Less is better)        ---> 63.16% decrease
ITLB_WALK/1000 INST_RETIRED (Less is better) ---> 42.71% decrease
ITLB_Walk/L1I_TLB (Less is better)           ---> 42.47% decrease

[1] https://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git/commit/?h=for-next&id=20e490adea279d49d57b800475938f5b67926d98
[2] https://lore.kernel.org/all/CANk7y0gcP3dF2mESLp5JN1+9iDfgtiWRFGqLkCgZD6wby1kQOw at mail.gmail.com/
[3] https://lore.kernel.org/bpf/20220204185742.271030-1-song at kernel.org/
[4] https://github.com/puranjaymohan/BPF-Allocator-Bench
[5] https://www.python.org/ftp/python/3.8.4/Python-3.8.4.tgz

Puranjay Mohan (2):
  arm64: patching: implement text_poke API
  bpf, arm64: use bpf_prog_pack for memory management

 arch/arm64/include/asm/patching.h |   2 +
 arch/arm64/kernel/patching.c      |  75 ++++++++++++++++
 arch/arm64/net/bpf_jit_comp.c     | 139 ++++++++++++++++++++++++------
 3 files changed, 192 insertions(+), 24 deletions(-)

-- 
2.40.1



From puranjay12 at gmail.com  Wed Feb 21 06:51:05 2024
From: puranjay12 at gmail.com (Puranjay Mohan)
Date: Wed, 21 Feb 2024 14:51:05 +0000
Subject: [PATCH bpf-next v8 1/2] arm64: patching: implement text_poke API
In-Reply-To: <20240221145106.105995-1-puranjay12@gmail.com>
References: <20240221145106.105995-1-puranjay12@gmail.com>
Message-ID: <20240221145106.105995-2-puranjay12@gmail.com>

The text_poke API is used to implement functions like memcpy() and
memset() for instruction memory (RO+X). The implementation is similar to
the x86 version.

This will be used by the BPF JIT to write and modify BPF programs. There
could be more users of this in the future.

Signed-off-by: Puranjay Mohan <puranjay12 at gmail.com>
---
 arch/arm64/include/asm/patching.h |  2 +
 arch/arm64/kernel/patching.c      | 75 +++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+)

diff --git a/arch/arm64/include/asm/patching.h b/arch/arm64/include/asm/patching.h
index 68908b82b168..587bdb91ab7a 100644
--- a/arch/arm64/include/asm/patching.h
+++ b/arch/arm64/include/asm/patching.h
@@ -8,6 +8,8 @@ int aarch64_insn_read(void *addr, u32 *insnp);
 int aarch64_insn_write(void *addr, u32 insn);
 
 int aarch64_insn_write_literal_u64(void *addr, u64 val);
+void *aarch64_insn_set(void *dst, u32 insn, size_t len);
+void *aarch64_insn_copy(void *dst, void *src, size_t len);
 
 int aarch64_insn_patch_text_nosync(void *addr, u32 insn);
 int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
diff --git a/arch/arm64/kernel/patching.c b/arch/arm64/kernel/patching.c
index b4835f6d594b..255534930368 100644
--- a/arch/arm64/kernel/patching.c
+++ b/arch/arm64/kernel/patching.c
@@ -105,6 +105,81 @@ noinstr int aarch64_insn_write_literal_u64(void *addr, u64 val)
 	return ret;
 }
 
+typedef void text_poke_f(void *dst, void *src, size_t patched, size_t len);
+
+static void *__text_poke(text_poke_f func, void *addr, void *src, size_t len)
+{
+	unsigned long flags;
+	size_t patched = 0;
+	size_t size;
+	void *waddr;
+	void *ptr;
+
+	raw_spin_lock_irqsave(&patch_lock, flags);
+
+	while (patched < len) {
+		ptr = addr + patched;
+		size = min_t(size_t, PAGE_SIZE - offset_in_page(ptr),
+			     len - patched);
+
+		waddr = patch_map(ptr, FIX_TEXT_POKE0);
+		func(waddr, src, patched, size);
+		patch_unmap(FIX_TEXT_POKE0);
+
+		patched += size;
+	}
+	raw_spin_unlock_irqrestore(&patch_lock, flags);
+
+	flush_icache_range((uintptr_t)addr, (uintptr_t)addr + len);
+
+	return addr;
+}
+
+static void text_poke_memcpy(void *dst, void *src, size_t patched, size_t len)
+{
+	copy_to_kernel_nofault(dst, src + patched, len);
+}
+
+static void text_poke_memset(void *dst, void *src, size_t patched, size_t len)
+{
+	u32 c = *(u32 *)src;
+
+	memset32(dst, c, len / 4);
+}
+
+/**
+ * aarch64_insn_copy - Copy instructions into (an unused part of) RX memory
+ * @dst: address to modify
+ * @src: source of the copy
+ * @len: length to copy
+ *
+ * Useful for JITs to dump new code blocks into unused regions of RX memory.
+ */
+noinstr void *aarch64_insn_copy(void *dst, void *src, size_t len)
+{
+	/* A64 instructions must be word aligned */
+	if ((uintptr_t)dst & 0x3)
+		return NULL;
+
+	return __text_poke(text_poke_memcpy, dst, src, len);
+}
+
+/**
+ * aarch64_insn_set - memset for RX memory regions.
+ * @dst: address to modify
+ * @insn: value to set
+ * @len: length of memory region.
+ *
+ * Useful for JITs to fill regions of RX memory with illegal instructions.
+ */
+noinstr void *aarch64_insn_set(void *dst, u32 insn, size_t len)
+{
+	if ((uintptr_t)dst & 0x3)
+		return NULL;
+
+	return __text_poke(text_poke_memset, dst, &insn, len);
+}
+
 int __kprobes aarch64_insn_patch_text_nosync(void *addr, u32 insn)
 {
 	u32 *tp = addr;
-- 
2.40.1



From puranjay12 at gmail.com  Wed Feb 21 06:51:06 2024
From: puranjay12 at gmail.com (Puranjay Mohan)
Date: Wed, 21 Feb 2024 14:51:06 +0000
Subject: [PATCH bpf-next v8 2/2] bpf, arm64: use bpf_prog_pack for memory management
In-Reply-To: <20240221145106.105995-1-puranjay12@gmail.com>
References: <20240221145106.105995-1-puranjay12@gmail.com>
Message-ID: <20240221145106.105995-3-puranjay12@gmail.com>

Use bpf_jit_binary_pack_alloc for memory management of JIT binaries in
ARM64 BPF JIT. The bpf_jit_binary_pack_alloc creates a pair of RW and RX
buffers. The JIT writes the program into the RW buffer. When the JIT is
done, the program is copied to the final RX buffer
with bpf_jit_binary_pack_finalize.

Implement bpf_arch_text_copy() and bpf_arch_text_invalidate() for ARM64
JIT as these functions are required by bpf_jit_binary_pack allocator.

Signed-off-by: Puranjay Mohan <puranjay12 at gmail.com>
Acked-by: Song Liu <song at kernel.org>
---
 arch/arm64/net/bpf_jit_comp.c | 139 ++++++++++++++++++++++++++++------
 1 file changed, 115 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index cfd5434de483..58e54a1929c9 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -76,6 +76,7 @@ struct jit_ctx {
 	int *offset;
 	int exentry_idx;
 	__le32 *image;
+	__le32 *ro_image;
 	u32 stack_size;
 	int fpb_offset;
 };
@@ -205,6 +206,14 @@ static void jit_fill_hole(void *area, unsigned int size)
 		*ptr++ = cpu_to_le32(AARCH64_BREAK_FAULT);
 }
 
+int bpf_arch_text_invalidate(void *dst, size_t len)
+{
+	if (!aarch64_insn_set(dst, AARCH64_BREAK_FAULT, len))
+		return -EINVAL;
+
+	return 0;
+}
+
 static inline int epilogue_offset(const struct jit_ctx *ctx)
 {
 	int to = ctx->epilogue_offset;
@@ -707,7 +716,8 @@ static int add_exception_handler(const struct bpf_insn *insn,
 				 struct jit_ctx *ctx,
 				 int dst_reg)
 {
-	off_t offset;
+	off_t ins_offset;
+	off_t fixup_offset;
 	unsigned long pc;
 	struct exception_table_entry *ex;
 
@@ -724,12 +734,17 @@ static int add_exception_handler(const struct bpf_insn *insn,
 		return -EINVAL;
 
 	ex = &ctx->prog->aux->extable[ctx->exentry_idx];
-	pc = (unsigned long)&ctx->image[ctx->idx - 1];
+	pc = (unsigned long)&ctx->ro_image[ctx->idx - 1];
 
-	offset = pc - (long)&ex->insn;
-	if (WARN_ON_ONCE(offset >= 0 || offset < INT_MIN))
+	/*
+	 * This is the relative offset of the instruction that may fault from
+	 * the exception table itself. This will be written to the exception
+	 * table and if this instruction faults, the destination register will
+	 * be set to '0' and the execution will jump to the next instruction.
+	 */
+	ins_offset = pc - (long)&ex->insn;
+	if (WARN_ON_ONCE(ins_offset >= 0 || ins_offset < INT_MIN))
 		return -ERANGE;
-	ex->insn = offset;
 
 	/*
 	 * Since the extable follows the program, the fixup offset is always
@@ -738,12 +753,25 @@ static int add_exception_handler(const struct bpf_insn *insn,
 	 * bits. We don't need to worry about buildtime or runtime sort
 	 * modifying the upper bits because the table is already sorted, and
 	 * isn't part of the main exception table.
+	 *
+	 * The fixup_offset is set to the next instruction from the instruction
+	 * that may fault. The execution will jump to this after handling the
+	 * fault.
 	 */
-	offset = (long)&ex->fixup - (pc + AARCH64_INSN_SIZE);
-	if (!FIELD_FIT(BPF_FIXUP_OFFSET_MASK, offset))
+	fixup_offset = (long)&ex->fixup - (pc + AARCH64_INSN_SIZE);
+	if (!FIELD_FIT(BPF_FIXUP_OFFSET_MASK, fixup_offset))
 		return -ERANGE;
 
-	ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, offset) |
+	/*
+	 * The offsets above have been calculated using the RO buffer but we
+	 * need to use the R/W buffer for writes.
+	 * switch ex to rw buffer for writing.
+	 */
+	ex = (void *)ctx->image + ((void *)ex - (void *)ctx->ro_image);
+
+	ex->insn = ins_offset;
+
+	ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, fixup_offset) |
 		    FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg);
 
 	ex->type = EX_TYPE_BPF;
@@ -1511,7 +1539,8 @@ static inline void bpf_flush_icache(void *start, void *end)
 
 struct arm64_jit_data {
 	struct bpf_binary_header *header;
-	u8 *image;
+	u8 *ro_image;
+	struct bpf_binary_header *ro_header;
 	struct jit_ctx ctx;
 };
 
@@ -1520,12 +1549,14 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	int image_size, prog_size, extable_size, extable_align, extable_offset;
 	struct bpf_prog *tmp, *orig_prog = prog;
 	struct bpf_binary_header *header;
+	struct bpf_binary_header *ro_header;
 	struct arm64_jit_data *jit_data;
 	bool was_classic = bpf_prog_was_classic(prog);
 	bool tmp_blinded = false;
 	bool extra_pass = false;
 	struct jit_ctx ctx;
 	u8 *image_ptr;
+	u8 *ro_image_ptr;
 
 	if (!prog->jit_requested)
 		return orig_prog;
@@ -1552,8 +1583,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	}
 	if (jit_data->ctx.offset) {
 		ctx = jit_data->ctx;
-		image_ptr = jit_data->image;
+		ro_image_ptr = jit_data->ro_image;
+		ro_header = jit_data->ro_header;
 		header = jit_data->header;
+		image_ptr = (void *)header + ((void *)ro_image_ptr
+						 - (void *)ro_header);
 		extra_pass = true;
 		prog_size = sizeof(u32) * ctx.idx;
 		goto skip_init_ctx;
@@ -1598,18 +1632,27 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	/* also allocate space for plt target */
 	extable_offset = round_up(prog_size + PLT_TARGET_SIZE, extable_align);
 	image_size = extable_offset + extable_size;
-	header = bpf_jit_binary_alloc(image_size, &image_ptr,
-				      sizeof(u32), jit_fill_hole);
-	if (header == NULL) {
+	ro_header = bpf_jit_binary_pack_alloc(image_size, &ro_image_ptr,
+					      sizeof(u32), &header, &image_ptr,
+					      jit_fill_hole);
+	if (!ro_header) {
 		prog = orig_prog;
 		goto out_off;
 	}
 
 	/* 2. Now, the actual pass. */
 
+	/*
+	 * Use the image(RW) for writing the JITed instructions. But also save
+	 * the ro_image(RX) for calculating the offsets in the image. The RW
+	 * image will be later copied to the RX image from where the program
+	 * will run. The bpf_jit_binary_pack_finalize() will do this copy in the
+	 * final step.
+	 */
 	ctx.image = (__le32 *)image_ptr;
+	ctx.ro_image = (__le32 *)ro_image_ptr;
 	if (extable_size)
-		prog->aux->extable = (void *)image_ptr + extable_offset;
+		prog->aux->extable = (void *)ro_image_ptr + extable_offset;
 skip_init_ctx:
 	ctx.idx = 0;
 	ctx.exentry_idx = 0;
@@ -1617,9 +1660,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	build_prologue(&ctx, was_classic);
 
 	if (build_body(&ctx, extra_pass)) {
-		bpf_jit_binary_free(header);
 		prog = orig_prog;
-		goto out_off;
+		goto out_free_hdr;
 	}
 
 	build_epilogue(&ctx);
@@ -1627,34 +1669,44 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 
 	/* 3. Extra pass to validate JITed code. */
 	if (validate_ctx(&ctx)) {
-		bpf_jit_binary_free(header);
 		prog = orig_prog;
-		goto out_off;
+		goto out_free_hdr;
 	}
 
 	/* And we're done. */
 	if (bpf_jit_enable > 1)
 		bpf_jit_dump(prog->len, prog_size, 2, ctx.image);
 
-	bpf_flush_icache(header, ctx.image + ctx.idx);
-
 	if (!prog->is_func || extra_pass) {
 		if (extra_pass && ctx.idx != jit_data->ctx.idx) {
 			pr_err_once("multi-func JIT bug %d != %d\n",
 				    ctx.idx, jit_data->ctx.idx);
-			bpf_jit_binary_free(header);
 			prog->bpf_func = NULL;
 			prog->jited = 0;
 			prog->jited_len = 0;
+			goto out_free_hdr;
+		}
+		if (WARN_ON(bpf_jit_binary_pack_finalize(prog, ro_header,
+							 header))) {
+			/* ro_header has been freed */
+			ro_header = NULL;
+			prog = orig_prog;
 			goto out_off;
 		}
-		bpf_jit_binary_lock_ro(header);
+		/*
+		 * The instructions have now been copied to the ROX region from
+		 * where they will execute. Now the data cache has to be cleaned to
+		 * the PoU and the I-cache has to be invalidated for the VAs.
+		 */
+		bpf_flush_icache(ro_header, ctx.ro_image + ctx.idx);
 	} else {
 		jit_data->ctx = ctx;
-		jit_data->image = image_ptr;
+		jit_data->ro_image = ro_image_ptr;
 		jit_data->header = header;
+		jit_data->ro_header = ro_header;
 	}
-	prog->bpf_func = (void *)ctx.image;
+
+	prog->bpf_func = (void *)ctx.ro_image;
 	prog->jited = 1;
 	prog->jited_len = prog_size;
 
@@ -1675,6 +1727,14 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 		bpf_jit_prog_release_other(prog, prog == orig_prog ?
 					   tmp : orig_prog);
 	return prog;
+
+out_free_hdr:
+	if (header) {
+		bpf_arch_text_copy(&ro_header->size, &header->size,
+				   sizeof(header->size));
+		bpf_jit_binary_pack_free(ro_header, header);
+	}
+	goto out_off;
 }
 
 bool bpf_jit_supports_kfunc_call(void)
@@ -1682,6 +1742,13 @@ bool bpf_jit_supports_kfunc_call(void)
 	return true;
 }
 
+void *bpf_arch_text_copy(void *dst, void *src, size_t len)
+{
+	if (!aarch64_insn_copy(dst, src, len))
+		return ERR_PTR(-EINVAL);
+	return dst;
+}
+
 u64 bpf_jit_alloc_exec_limit(void)
 {
 	return VMALLOC_END - VMALLOC_START;
@@ -2310,3 +2377,27 @@ bool bpf_jit_supports_ptr_xchg(void)
 {
 	return true;
 }
+
+void bpf_jit_free(struct bpf_prog *prog)
+{
+	if (prog->jited) {
+		struct arm64_jit_data *jit_data = prog->aux->jit_data;
+		struct bpf_binary_header *hdr;
+
+		/*
+		 * If we fail the final pass of JIT (from jit_subprogs),
+		 * the program may not be finalized yet. Call finalize here
+		 * before freeing it.
+		 */
+		if (jit_data) {
+			bpf_arch_text_copy(&jit_data->ro_header->size, &jit_data->header->size,
+					   sizeof(jit_data->header->size));
+			kfree(jit_data);
+		}
+		hdr = bpf_jit_binary_pack_hdr(prog);
+		bpf_jit_binary_pack_free(hdr, NULL);
+		WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(prog));
+	}
+
+	bpf_prog_unlock_free(prog);
+}
-- 
2.40.1



From geert at linux-m68k.org  Wed Feb 21 06:51:50 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 21 Feb 2024 15:51:50 +0100
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <CAL_Jsq+L7uPimQfATs14EWCbqRO1vxDUmPie7=cChTLCf2od2g@mail.gmail.com>
References: <20240221092826.748e70c4@canb.auug.org.au> <CAL_JsqKw9OXb=aOMni1qprzeWDBgmjdJef-6VAjwx0R--D+URw@mail.gmail.com>
 <ac9ddf79-6bc9-4daf-a271-82f8b3bca988@app.fastmail.com> <CAL_Jsq+L7uPimQfATs14EWCbqRO1vxDUmPie7=cChTLCf2od2g@mail.gmail.com>
Message-ID: <CAMuHMdXNyU0eBcMe3EhhfahcRo2KtXzwdr+d_6AC-2529R3bmQ@mail.gmail.com>

Hi Rob, Arnd,

On Wed, Feb 21, 2024 at 3:27?PM Rob Herring <robh at kernel.org> wrote:
> On Wed, Feb 21, 2024 at 7:00?AM Arnd Bergmann <arnd at arndb.de> wrote:
> > On Wed, Feb 21, 2024, at 14:53, Rob Herring wrote:
> > > On Tue, Feb 20, 2024 at 3:28?PM Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> > >> arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > >>
> > >> Introduced/exposed by commit
> > >>
> > >>   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
> > >>
> > >> I guess you missed some :-(
> > >
> > > No, Geert separately posted fixes for already.
> >
> > I did make the mistake of applying the final patch "dtc:
> > Enable dtc interrupt_provider check" to the arm/fixes branch
> > for 6.8 along with the other fixes.
> >
> > Clearly that should be separate and only go into mainline
> > after there are no more regressions, but now I'm unsure
> > about the other patches -- did you intend the dts fixes
> > for 6.8 or for the coming merge window?
>
> Either is fine with me. My intent was the whole series plus the
> Renesas fix to be applied together. Anything new that crops up we can
> fix on top.

If you want me to move commit b4f97d1b5aeb6166 ("ARM: dts: renesas:
rcar-gen2: Add missing #interrupt-cells to DA9063 nodes") to
renesas-fixes, please tell me.

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 javierm at redhat.com  Wed Feb 21 06:55:04 2024
From: javierm at redhat.com (Javier Martinez Canillas)
Date: Wed, 21 Feb 2024 15:55:04 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
Message-ID: <87a5ntj29j.fsf@minerva.mail-host-address-is-not-set>

Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> writes:

> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
>> These options are needed by some Linux distributions (e.g: Fedora), so
>
> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
> use on my arm64 boards, does not have any problem.
>

I haven't used Debian in ages so I don't know why is not a problem there.

But Fedora is using zram by default and if is not enabled in the kernel,
the boot is delayed considerably due the systemd zram-generator.

> I kind of repeat comments from similar patch earlier:
> https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/
>

Ah! I forgot that posted the same change for exynos_defconfig some time
ago and I see that you nacked. Now I understand why all my Exynos boards
are in a drawer.

> About XFS: I don't think it is needed to boot anything.
>

How are you supposed to mount a XFS rootfs without at least have support
for it as a module?

> This is a defconfig, not a distro config. Please don't make it distro.
>

It seems that's a Debian distro config though, since you brought Debian as
an example.

> I will gladly support things needed by systemd or equivalent, but not
> unusual filesystems needed by distro.
>

Fair. But then you should probably remove all the other filesystems that are
already in the defconfig then?

$ grep "_FS=" arch/arm64/configs/defconfig | wc -l
15

Or it is OK to have support for btrfs, overlayfs, even plan9 fs but XFS is
where you draw the line??

> Best regards,
> Krzysztof
>

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



From u-kumar1 at ti.com  Wed Feb 21 06:55:09 2024
From: u-kumar1 at ti.com (Kumar, Udit)
Date: Wed, 21 Feb 2024 20:25:09 +0530
Subject: [PATCH V3 0/2] Add CAN and OSPI support for AM69-SK platform
In-Reply-To: <20240220162527.663394-1-sabiya.d@ti.com>
References: <20240220162527.663394-1-sabiya.d@ti.com>
Message-ID: <0801de56-f3f0-4564-9677-345eca5fef6e@ti.com>


On 2/20/2024 9:55 PM, sabiya.d at mistralsolutions.com wrote:
> From: Dasnavis Sabiya <sabiya.d at ti.com>
>
> Hi All,
>
> This series adds support for the below interfaces on AM69-SK platform:
> -  CAN support on both MCU and MAIN domains
> -  OSPI NOR flash support
>
> v3: Changelog:
> 1) Updated OSPI partition table to increase the tiboot3 partition to 1MB.
> 2) Rebase the sources to accommodate the latest merge.
>
> v2: Changelog:
> 1) Removed CAN interface aliasing.
> 2) Updated bootph property on the leaf nodes.
>
> Link to v1: https://lore.kernel.org/lkml/20240118153524.4135901-1-sabiya.d at ti.com/
> Link to v2: https://lore.kernel.org/linux-arm-kernel/20240219111422.171315-1-sabiya.d at ti.com/
>
> Dasnavis Sabiya (2):
>    arm64: dts: ti: k3-am69-sk: Enable CAN interfaces for AM69 SK board
>    arm64: dts: ti: k3-am69-sk: Add support for OSPI flash


For Series

Reviewed-by: Udit Kumar <u-kumar1 at ti.com>


>   arch/arm64/boot/dts/ti/k3-am69-sk.dts | 163 ++++++++++++++++++++++++++
>   1 file changed, 163 insertions(+)
>


From dalias at libc.org  Wed Feb 21 06:58:01 2024
From: dalias at libc.org (dalias at libc.org)
Date: Wed, 21 Feb 2024 09:58:01 -0500
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
 <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
 <20240220235415.GP4163@brightrain.aerifal.cx>
 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx>
 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
Message-ID: <20240221145800.GR4163@brightrain.aerifal.cx>

On Wed, Feb 21, 2024 at 01:53:10PM +0000, Mark Brown wrote:
> On Tue, Feb 20, 2024 at 08:27:37PM -0500, dalias at libc.org wrote:
> > On Wed, Feb 21, 2024 at 12:35:48AM +0000, Edgecombe, Rick P wrote:
> 
> > > (INCSSP, RSTORSSP, etc). These are a collection of instructions that
> > > allow limited control of the SSP. When shadow stack gets disabled,
> > > these suddenly turn into #UD generating instructions. So any other
> > > threads executing those instructions when shadow stack got disabled
> > > would be in for a nasty surprise.
> 
> > This is the kernel's problem if that's happening. It should be
> > trapping these and returning immediately like a NOP if shadow stack
> > has been disabled, not generating SIGILL.
> 
> I'm not sure that's going to work out well, all it takes is some code
> that's looking at the shadow stack and expecting something to happen as
> a result of the instructions it's executing and we run into trouble.  A
> lot of things won't notice and will just happily carry on but I expect
> there are going to be things that care.  We also end up with an
> additional state for threads that have had shadow stacks transparently
> disabled, that's managable but still.

I said NOP but there's no reason it strictly needs to be a NOP. It
could instead do something reasonable to convey the state of racing
with shadow stack being disabled.

> 
> > > > The place where it's really needed to be able to allocate the shadow
> > > > stack synchronously under userspace control, in order to harden
> > > > normal
> > > > applications that aren't doing funny things, is in pthread_create
> > > > without a caller-provided stack.
> 
> > > Yea most apps don't do anything too tricky. Mostly shadow stack "just
> > > works". But it's no excuse to just crash for the others.
> 
> > One thing to note here is that, to enable this, we're going to need
> > some way to detect "new enough kernel that shadow stack semantics are
> > all right". If there are kernels that have shadow stack support but
> > with problems that make it unsafe to use (this sounds like the case),
> > we can't turn it on without a way to avoid trying to use it on those.
> 
> If we have this automatic conversion of pages to shadow stack then we
> should have an API for enabling it, userspace should be able to use the
> presence of that API to determine if the feature is there.

Yes, or if a new prctl is needed to make disabling safe (see above)
that could probably be used.

Rich


From krzysztof.kozlowski at linaro.org  Wed Feb 21 07:10:12 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 16:10:12 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
Message-ID: <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>

On 21/02/2024 15:48, Maxime Ripard wrote:
> On Wed, Feb 21, 2024 at 03:22:38PM +0100, Krzysztof Kozlowski wrote:
>> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
>>> These options are needed by some Linux distributions (e.g: Fedora), so
>>
>> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
>> use on my arm64 boards, does not have any problem.
> 
> Is it relevant in any way?

Yes, because it is justification why we are doing it. Each commit is
supposed to explain "why" and the explanation here is not enough.

> 
> I'm sure Debian can boot without MEMORY_HOTREMOVE, or BRIDGE, or
> NUMA_BALANCING, or BPF_JIT, or NFS_FS, yet all of them are enabled. Let
> me know if you want hundreds more examples.

So if there is any bug, you are allowed to add new one? If there is any
silly option, you are allowed to add new one?

Feel free to propose dropping of any irrelevant options.

> 
>> I kind of repeat comments from similar patch earlier:
>> https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/
>>
>> About XFS: I don't think it is needed to boot anything.
> 
> Just like 9P_FS, NFS or UBIFS.

NFS is often used on targets, e.g. my board farm, but also by other people.

UBIFS was added recently because one device was using it - you needed
it. 9P_FS looks unnecessary.

> 
>> This is a defconfig, not a distro config. Please don't make it distro.
>>
>> I will gladly support things needed by systemd or equivalent, but not
>> unusual filesystems needed by distro.
> 
> It's a defconfig. It's whatever people want it to be. Or we need to come
> up with a clearly defined set of rules of what is acceptable in that
> defconfig or not, and prune every option that isn't.

So that's the rule I am commenting from time to time. defconfigs are not
distro configs. These are reference hardware configs and debugging
configs. I was working in distro so trust me - they do stuff differently
and they not need XFS in our defconfig for anything.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Wed Feb 21 07:14:21 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 16:14:21 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
Message-ID: <743c9df6-3a19-4204-9812-3c47e4cd8536@linaro.org>

On 21/02/2024 16:10, Krzysztof Kozlowski wrote:
> On 21/02/2024 15:48, Maxime Ripard wrote:
>> On Wed, Feb 21, 2024 at 03:22:38PM +0100, Krzysztof Kozlowski wrote:
>>> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
>>>> These options are needed by some Linux distributions (e.g: Fedora), so
>>>
>>> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
>>> use on my arm64 boards, does not have any problem.
>>
>> Is it relevant in any way?
> 
> Yes, because it is justification why we are doing it. Each commit is
> supposed to explain "why" and the explanation here is not enough.
> 
>>
>> I'm sure Debian can boot without MEMORY_HOTREMOVE, or BRIDGE, or
>> NUMA_BALANCING, or BPF_JIT, or NFS_FS, yet all of them are enabled. Let
>> me know if you want hundreds more examples.

BTW, each commit adding such options is supposed to explain why there
are needed, so please go to the git log and answer yourself why there
are there. I am pretty sure I will ack/review removal of every option
added without answering "why".

Don't twist the discussion of necessity of Kconfig options, because each
commit should stand on its own.

Best regards,
Krzysztof



From geert at linux-m68k.org  Wed Feb 21 07:20:52 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 21 Feb 2024 16:20:52 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
References: <20240221141350.3740488-1-javierm@redhat.com> <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t> <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
Message-ID: <CAMuHMdWYyDzzy1-arw=Yt=cTpJ-crx58oKdQsity2EaRtSNk1w@mail.gmail.com>

Hi Krzysztof,

On Wed, Feb 21, 2024 at 4:10?PM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
> UBIFS was added recently because one device was using it - you needed
> it. 9P_FS looks unnecessary.

9P_FS is used commonly for file transfer between host and guest, cfr.
commit af9b99647cd2a6a2 ("arm64: defconfig: add virtio support for
running as a kvm guest").

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 diogo.ivo at siemens.com  Wed Feb 21 07:24:07 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Wed, 21 Feb 2024 15:24:07 +0000
Subject: [PATCH net-next v3 01/10] dt-bindings: net: Add support for AM65x SR1.0 in ICSSG
In-Reply-To: <20240221152421.112324-1-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
Message-ID: <20240221152421.112324-2-diogo.ivo@siemens.com>

Silicon Revision 1.0 of the AM65x came with a slightly different ICSSG
support: Only 2 PRUs per slice are available and instead 2 additional
DMA channels are used for management purposes. We have no restrictions
on specified PRUs, but the DMA channels need to be adjusted.

Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
Changes in v3:
 - Fixed dt_binding_check error by moving allOf

Changes in v2:
 - Removed explicit reference to SR2.0
 - Moved sr1 to the SoC name
 - Expand dma-names list and adjust min/maxItems depending on SR1.0/2.0
 .../bindings/net/ti,icssg-prueth.yaml         | 35 +++++++++++++++----
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
index 229c8f32019f..e253fa786092 100644
--- a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
+++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml
@@ -13,14 +13,12 @@ description:
   Ethernet based on the Programmable Real-Time Unit and Industrial
   Communication Subsystem.
 
-allOf:
-  - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#
-
 properties:
   compatible:
     enum:
-      - ti,am642-icssg-prueth  # for AM64x SoC family
-      - ti,am654-icssg-prueth  # for AM65x SoC family
+      - ti,am642-icssg-prueth      # for AM64x SoC family
+      - ti,am654-icssg-prueth      # for AM65x SoC family
+      - ti,am654-sr1-icssg-prueth  # for AM65x SoC family, SR1.0
 
   sram:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -28,9 +26,11 @@ properties:
       phandle to MSMC SRAM node
 
   dmas:
-    maxItems: 10
+    minItems: 10
+    maxItems: 12
 
   dma-names:
+    minItems: 10
     items:
       - const: tx0-0
       - const: tx0-1
@@ -42,6 +42,8 @@ properties:
       - const: tx1-3
       - const: rx0
       - const: rx1
+      - const: rxmgm0
+      - const: rxmgm1
 
   ti,mii-g-rt:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -132,6 +134,27 @@ required:
   - interrupts
   - interrupt-names
 
+allOf:
+  - $ref: /schemas/remoteproc/ti,pru-consumer.yaml#
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: ti,am654-sr1-icssg-prueth
+    then:
+      properties:
+        dmas:
+          minItems: 12
+        dma-names:
+          minItems: 12
+    else:
+      properties:
+        dmas:
+          maxItems: 10
+        dma-names:
+          maxItems: 10
+
 unevaluatedProperties: false
 
 examples:
-- 
2.43.2



From diogo.ivo at siemens.com  Wed Feb 21 07:24:12 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Wed, 21 Feb 2024 15:24:12 +0000
Subject: [PATCH net-next v3 06/10] net: ti: icssg-prueth: Adjust IPG configuration for SR1.0
In-Reply-To: <20240221152421.112324-1-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
Message-ID: <20240221152421.112324-7-diogo.ivo@siemens.com>

Correctly adjust the IPG based on the Silicon Revision.

Based on the work of Roger Quadros, Vignesh Raghavendra
and Grygorii Strashko in TI's 5.10 SDK [1].

[1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y

Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
 drivers/net/ethernet/ti/icssg/icssg_config.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c
index 99de8a40ed60..15f2235bf90f 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_config.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.c
@@ -20,6 +20,8 @@
 /* IPG is in core_clk cycles */
 #define MII_RT_TX_IPG_100M	0x17
 #define MII_RT_TX_IPG_1G	0xb
+#define MII_RT_TX_IPG_100M_SR1	0x166
+#define MII_RT_TX_IPG_1G_SR1	0x1a
 
 #define	ICSSG_QUEUES_MAX		64
 #define	ICSSG_QUEUE_OFFSET		0xd00
@@ -202,23 +204,29 @@ void icssg_config_ipg(struct prueth_emac *emac)
 {
 	struct prueth *prueth = emac->prueth;
 	int slice = prueth_emac_slice(emac);
+	u32 ipg;
 
 	switch (emac->speed) {
 	case SPEED_1000:
-		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_1G);
+		ipg = emac->is_sr1 ? MII_RT_TX_IPG_1G_SR1 : MII_RT_TX_IPG_1G;
 		break;
 	case SPEED_100:
-		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M);
+		ipg = emac->is_sr1 ? MII_RT_TX_IPG_100M_SR1 : MII_RT_TX_IPG_100M;
 		break;
 	case SPEED_10:
+		/* Firmware hardcodes IPG for SR1.0 */
+		if (emac->is_sr1)
+			return;
 		/* IPG for 10M is same as 100M */
-		icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M);
+		ipg = MII_RT_TX_IPG_100M;
 		break;
 	default:
 		/* Other links speeds not supported */
 		netdev_err(emac->ndev, "Unsupported link speed\n");
 		return;
 	}
+
+	icssg_mii_update_ipg(prueth->mii_rt, slice, ipg);
 }
 
 static void emac_r30_cmd_init(struct prueth_emac *emac)
-- 
2.43.2



From diogo.ivo at siemens.com  Wed Feb 21 07:24:10 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Wed, 21 Feb 2024 15:24:10 +0000
Subject: [PATCH net-next v3 04/10] net: ti: icssg-prueth: Add SR1.0-specific configuration bits
In-Reply-To: <20240221152421.112324-1-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
Message-ID: <20240221152421.112324-5-diogo.ivo@siemens.com>

Define the firmware configuration structure and commands needed to
communicate with SR1.0 firmware, as well as SR1.0 buffer information
where it differs from SR2.0.

Based on the work of Roger Quadros, Murali Karicheri and
Grygorii Strashko in TI's 5.10 SDK [1].

[1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y

Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
Changes in v2:
 - Removed explicit references to SR2.0

 drivers/net/ethernet/ti/icssg/icssg_config.h | 56 ++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
index 43eb0922172a..cb465b3f5355 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_config.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
@@ -35,6 +35,23 @@ struct icssg_flow_cfg {
 	(2 * (PRUETH_EMAC_BUF_POOL_SIZE * PRUETH_NUM_BUF_POOLS + \
 	 PRUETH_EMAC_RX_CTX_BUF_SIZE * 2))
 
+/* SR1.0 defines */
+#define PRUETH_MAX_RX_FLOWS_SR1		4	/* excluding default flow */
+#define PRUETH_RX_FLOW_DATA_SR1		3       /* highest priority flow */
+#define PRUETH_MAX_RX_MGM_DESC		8
+#define PRUETH_MAX_RX_MGM_FLOWS		2	/* excluding default flow */
+#define PRUETH_RX_MGM_FLOW_RESPONSE	0
+#define PRUETH_RX_MGM_FLOW_TIMESTAMP	1
+
+#define PRUETH_NUM_BUF_POOLS_SR1		16
+#define PRUETH_EMAC_BUF_POOL_START_SR1		8
+#define PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1	128
+#define PRUETH_EMAC_BUF_SIZE_SR1		1536
+#define PRUETH_EMAC_NUM_BUF_SR1			4
+#define PRUETH_EMAC_BUF_POOL_SIZE_SR1	(PRUETH_EMAC_NUM_BUF_SR1 * \
+					 PRUETH_EMAC_BUF_SIZE_SR1)
+#define MSMC_RAM_SIZE_SR1	(SZ_64K + SZ_32K + SZ_2K) /* 0x1880 x 8 x 2 */
+
 struct icssg_rxq_ctx {
 	__le32 start[3];
 	__le32 end;
@@ -104,6 +121,45 @@ enum icssg_port_state_cmd {
 #define ICSSG_NUM_NORMAL_PDS	64
 #define ICSSG_NUM_SPECIAL_PDS	16
 
+struct icssg_sr1_config {
+	__le32 status;		/* Firmware status */
+	__le32 addr_lo;		/* MSMC Buffer pool base address low. */
+	__le32 addr_hi;		/* MSMC Buffer pool base address high. Must be 0 */
+	__le32 tx_buf_sz[16];	/* Array of buffer pool sizes */
+	__le32 num_tx_threads;	/* Number of active egress threads, 1 to 4 */
+	__le32 tx_rate_lim_en;	/* Bitmask: Egress rate limit en per thread */
+	__le32 rx_flow_id;	/* RX flow id for first rx ring */
+	__le32 rx_mgr_flow_id;	/* RX flow id for the first management ring */
+	__le32 flags;		/* TBD */
+	__le32 n_burst;		/* for debug */
+	__le32 rtu_status;	/* RTU status */
+	__le32 info;		/* reserved */
+	__le32 reserve;
+	__le32 rand_seed;	/* Used for the random number generation at fw */
+} __packed;
+
+/* SR1.0 shutdown command to stop processing at firmware.
+ * Command format: 0x8101ss00, where
+ *	- ss: sequence number. Currently not used by driver.
+ */
+#define ICSSG_SHUTDOWN_CMD		0x81010000
+
+/* SR1.0 pstate speed/duplex command to set speed and duplex settings
+ * in firmware.
+ * Command format: 0x8102ssPN, where
+ *	- ss: sequence number. Currently not used by driver.
+ *	- P: port number (for switch mode).
+ *	- N: Speed/Duplex state:
+ *		0x0 - 10Mbps/Half duplex;
+ *		0x8 - 10Mbps/Full duplex;
+ *		0x2 - 100Mbps/Half duplex;
+ *		0xa - 100Mbps/Full duplex;
+ *		0xc - 1Gbps/Full duplex;
+ *		NOTE: The above are the same value as bits [3..1](slice 0)
+ *		      or bits [7..5](slice 1) of RGMII CFG register.
+ */
+#define ICSSG_PSTATE_SPEED_DUPLEX_CMD	0x81020000
+
 #define ICSSG_NORMAL_PD_SIZE	8
 #define ICSSG_SPECIAL_PD_SIZE	20
 
-- 
2.43.2



From diogo.ivo at siemens.com  Wed Feb 21 07:24:11 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Wed, 21 Feb 2024 15:24:11 +0000
Subject: [PATCH net-next v3 05/10] net: ti: icssg-prueth: Add SR1.0-specific description bits
In-Reply-To: <20240221152421.112324-1-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
Message-ID: <20240221152421.112324-6-diogo.ivo@siemens.com>

Add a field to distinguish between SR1.0 and SR2.0 in the driver
as well as the necessary structures to program SR1.0.

Based on the work of Roger Quadros in TI's 5.10 SDK [1].

[1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y

Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
 drivers/net/ethernet/ti/icssg/icssg_prueth.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index 5d792e9bade0..a8192e408941 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -129,6 +129,7 @@ struct prueth_rx_chn {
 
 /* data for each emac port */
 struct prueth_emac {
+	bool is_sr1;
 	bool fw_running;
 	struct prueth *prueth;
 	struct net_device *ndev;
@@ -157,6 +158,10 @@ struct prueth_emac {
 	int rx_flow_id_base;
 	int tx_ch_num;
 
+	/* SR1.0 Management channel */
+	struct prueth_rx_chn rx_mgm_chn;
+	int rx_mgm_flow_id_base;
+
 	spinlock_t lock;	/* serialize access */
 
 	/* TX HW Timestamping */
@@ -251,6 +256,13 @@ struct emac_tx_ts_response {
 	u32 hi_ts;
 };
 
+struct emac_tx_ts_response_sr1 {
+	u32 lo_ts;
+	u32 hi_ts;
+	u32 reserved;
+	u32 cookie;
+};
+
 /* get PRUSS SLICE number from prueth_emac */
 static inline int prueth_emac_slice(struct prueth_emac *emac)
 {
-- 
2.43.2



From diogo.ivo at siemens.com  Wed Feb 21 07:24:06 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Wed, 21 Feb 2024 15:24:06 +0000
Subject: [PATCH net-next v3 00/10] Support ICSSG-based Ethernet on AM65x SR1.0 devices
Message-ID: <20240221152421.112324-1-diogo.ivo@siemens.com>

Hello,

This series extends the current ICSSG-based Ethernet driver to support
AM65x Silicon Revision 1.0 devices.

Notable differences between the Silicon Revisions are that there is
no TX core in SR1.0 with this being handled by the firmware, requiring
extra DMA channels to manage communication with the firmware (with the
firmware being different as well) and in the packet classifier.

The motivation behind it is that a significant number of Siemens
devices containing SR1.0 silicon have been deployed in the field
and need to be supported and updated to newer kernel versions
without losing functionality.

This series is based on TI's 5.10 SDK [1].

The second version of this patch series can be found in [2].

The main changes in this version are the introduction of a separate
driver for SR1.0 with its own Kconfig symbol and the refactoring of
functions that can be shared across Silicon Revisions into a common
location. A more detailed description of the changes can be found
in each commit's message.

Importantly, in its current form the driver has two problems:
 - Setting the link to 100Mbit/s and half duplex results in slower than
   expected speeds. We have identified that this comes from
   icssg_rgmii_get_fullduplex() misreporting a full duplex connection
   and thus we send the wrong command to the firmware.

 - When using 3 TX channels we observe a timeout on TX queue 0. We have
   made no real progress on this front in identifying the root cause.

For both of these topics help from someone more familiar with the hardware
would be greatly appreciated so that we can support these features rather
than disable them in the final driver version.

[1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y
[2]: https://lore.kernel.org/netdev/20240117161602.153233-1-diogo.ivo at siemens.com/

Diogo Ivo (10):
  dt-bindings: net: Add support for AM65x SR1.0 in ICSSG
  eth: Move IPv4/IPv6 multicast address bases to their own symbols
  net: ti: icssg-prueth: Move common functions into a separate file
  net: ti: icssg-prueth: Add SR1.0-specific configuration bits
  net: ti: icssg-prueth: Add SR1.0-specific description bits
  net: ti: icssg-prueth: Adjust IPG configuration for SR1.0
  net: ti: icssg-prueth: Adjust the number of TX channels for SR1.0
  net: ti: icssg-prueth: Add functions to configure SR1.0 packet
    classifier
  net: ti: icssg-prueth: Modify common functions for SR1.0
  net: ti: icssg-prueth: Add ICSSG Ethernet driver for AM65x SR1.0
    platforms

 .../bindings/net/ti,icssg-prueth.yaml         |   35 +-
 drivers/net/ethernet/ti/Kconfig               |   15 +
 drivers/net/ethernet/ti/Makefile              |    9 +
 .../net/ethernet/ti/icssg/icssg_classifier.c  |  113 +-
 drivers/net/ethernet/ti/icssg/icssg_common.c  | 1222 +++++++++++++++++
 drivers/net/ethernet/ti/icssg/icssg_config.c  |   14 +-
 drivers/net/ethernet/ti/icssg/icssg_config.h  |   56 +
 drivers/net/ethernet/ti/icssg/icssg_ethtool.c |   10 +
 drivers/net/ethernet/ti/icssg/icssg_prueth.c  | 1189 +---------------
 drivers/net/ethernet/ti/icssg/icssg_prueth.h  |   77 +-
 .../net/ethernet/ti/icssg/icssg_prueth_sr1.c  | 1173 ++++++++++++++++
 include/linux/etherdevice.h                   |   12 +-
 12 files changed, 2716 insertions(+), 1209 deletions(-)
 create mode 100644 drivers/net/ethernet/ti/icssg/icssg_common.c
 create mode 100644 drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c

-- 
2.43.2



From diogo.ivo at siemens.com  Wed Feb 21 07:24:13 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Wed, 21 Feb 2024 15:24:13 +0000
Subject: [PATCH net-next v3 07/10] net: ti: icssg-prueth: Adjust the number of TX channels for SR1.0
In-Reply-To: <20240221152421.112324-1-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
Message-ID: <20240221152421.112324-8-diogo.ivo@siemens.com>

As SR1.0 uses the current higher priority channel to send commands to
the firmware, take this into account when setting/getting the number
of channels to/from the user.

Based on the work of Roger Quadros in TI's 5.10 SDK [1].

[1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y

Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
Changes in v3:
 - Address Roger's comments on SR1.0 handling

 drivers/net/ethernet/ti/icssg/icssg_ethtool.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c
index 9a7dd7efcf69..688a148f32b4 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c
@@ -142,6 +142,9 @@ static int emac_set_channels(struct net_device *ndev,
 
 	emac->tx_ch_num = ch->tx_count;
 
+	if (emac->is_sr1)
+		emac->tx_ch_num++;
+
 	return 0;
 }
 
@@ -152,8 +155,15 @@ static void emac_get_channels(struct net_device *ndev,
 
 	ch->max_rx = 1;
 	ch->max_tx = PRUETH_MAX_TX_QUEUES;
+
+	if (emac->is_sr1)
+		ch->max_tx--;
+
 	ch->rx_count = 1;
 	ch->tx_count = emac->tx_ch_num;
+
+	if (emac->is_sr1)
+		ch->tx_count--;
 }
 
 static const struct ethtool_rmon_hist_range emac_rmon_ranges[] = {
-- 
2.43.2



From diogo.ivo at siemens.com  Wed Feb 21 07:24:14 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Wed, 21 Feb 2024 15:24:14 +0000
Subject: [PATCH net-next v3 08/10] net: ti: icssg-prueth: Add functions to configure SR1.0 packet classifier
In-Reply-To: <20240221152421.112324-1-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
Message-ID: <20240221152421.112324-9-diogo.ivo@siemens.com>

Add the functions to configure the SR1.0 packet classifier.

Based on the work of Roger Quadros in TI's 5.10 SDK [1].

[1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y

Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
Changes in v3:
 - Replace local variables in icssg_class_add_mcast_sr1()
   with eth_reserved_addr_base and eth_ipv4_mcast_addr_base

 .../net/ethernet/ti/icssg/icssg_classifier.c  | 113 ++++++++++++++++--
 drivers/net/ethernet/ti/icssg/icssg_prueth.c  |   2 +-
 drivers/net/ethernet/ti/icssg/icssg_prueth.h  |   6 +-
 3 files changed, 110 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_classifier.c b/drivers/net/ethernet/ti/icssg/icssg_classifier.c
index 6df53ab17fbc..71b2f89ccd8e 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_classifier.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_classifier.c
@@ -274,6 +274,16 @@ static void rx_class_set_or(struct regmap *miig_rt, int slice, int n,
 	regmap_write(miig_rt, offset, data);
 }
 
+static u32 rx_class_get_or(struct regmap *miig_rt, int slice, int n)
+{
+	u32 offset, val;
+
+	offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN);
+	regmap_read(miig_rt, offset, &val);
+
+	return val;
+}
+
 void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac)
 {
 	regmap_write(miig_rt, MAC_INTERFACE_0, (u32)(mac[0] | mac[1] << 8 |
@@ -288,6 +298,26 @@ void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac)
 	regmap_write(miig_rt, offs[slice].mac1, (u32)(mac[4] | mac[5] << 8));
 }
 
+static void icssg_class_ft1_add_mcast(struct regmap *miig_rt, int slice,
+				      int slot, const u8 *addr, const u8 *mask)
+{
+	int i;
+	u32 val;
+
+	WARN(slot >= FT1_NUM_SLOTS, "invalid slot: %d\n", slot);
+
+	rx_class_ft1_set_da(miig_rt, slice, slot, addr);
+	rx_class_ft1_set_da_mask(miig_rt, slice, slot, mask);
+	rx_class_ft1_cfg_set_type(miig_rt, slice, slot, FT1_CFG_TYPE_EQ);
+
+	/* Enable the FT1 slot in OR enable for all classifiers */
+	for (i = 0; i < ICSSG_NUM_CLASSIFIERS_IN_USE; i++) {
+		val = rx_class_get_or(miig_rt, slice, i);
+		val |= RX_CLASS_FT_FT1_MATCH(slot);
+		rx_class_set_or(miig_rt, slice, i, val);
+	}
+}
+
 /* disable all RX traffic */
 void icssg_class_disable(struct regmap *miig_rt, int slice)
 {
@@ -331,30 +361,95 @@ void icssg_class_disable(struct regmap *miig_rt, int slice)
 	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
 }
 
-void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti)
+void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti,
+			 bool is_sr1)
 {
+	int num_classifiers = is_sr1 ? ICSSG_NUM_CLASSIFIERS_IN_USE : 1;
 	u32 data;
+	int n;
 
 	/* defaults */
 	icssg_class_disable(miig_rt, slice);
 
 	/* Setup Classifier */
-	/* match on Broadcast or MAC_PRU address */
-	data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P;
+	for (n = 0; n < num_classifiers; n++) {
+		/* match on Broadcast or MAC_PRU address */
+		data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P;
 
-	/* multicast */
-	if (allmulti)
-		data |= RX_CLASS_FT_MC;
+		/* multicast */
+		if (allmulti)
+			data |= RX_CLASS_FT_MC;
 
-	rx_class_set_or(miig_rt, slice, 0, data);
+		rx_class_set_or(miig_rt, slice, n, data);
 
-	/* set CFG1 for OR_OR_AND for classifier */
-	rx_class_sel_set_type(miig_rt, slice, 0, RX_CLASS_SEL_TYPE_OR_OR_AND);
+		/* set CFG1 for OR_OR_AND for classifier */
+		rx_class_sel_set_type(miig_rt, slice, n,
+				      RX_CLASS_SEL_TYPE_OR_OR_AND);
+	}
 
 	/* clear CFG2 */
 	regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
 }
 
+void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice)
+{
+	u32 data, offset;
+	int n;
+
+	/* defaults */
+	icssg_class_disable(miig_rt, slice);
+
+	/* Setup Classifier */
+	for (n = 0; n < ICSSG_NUM_CLASSIFIERS_IN_USE; n++) {
+		/* set RAW_MASK to bypass filters */
+		offset = RX_CLASS_GATES_N_REG(slice, n);
+		regmap_read(miig_rt, offset, &data);
+		data |= RX_CLASS_GATES_RAW_MASK;
+		regmap_write(miig_rt, offset, data);
+	}
+}
+
+void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice,
+			       struct net_device *ndev)
+{
+	u8 mask_addr[6] = { 0, 0, 0, 0, 0, 0xff };
+	struct netdev_hw_addr *ha;
+	int slot = 2;
+
+	rx_class_ft1_set_start_len(miig_rt, slice, 0, 6);
+	/* reserve first 2 slots for
+	 *	1) 01-80-C2-00-00-XX Known Service Ethernet Multicast addresses
+	 *	2) 01-00-5e-00-00-XX Local Network Control Block
+	 *			      (224.0.0.0 - 224.0.0.255  (224.0.0/24))
+	 */
+	icssg_class_ft1_add_mcast(miig_rt, slice, 0,
+				  eth_reserved_addr_base, mask_addr);
+	icssg_class_ft1_add_mcast(miig_rt, slice, 1,
+				  eth_ipv4_mcast_addr_base, mask_addr);
+	mask_addr[5] = 0;
+	netdev_for_each_mc_addr(ha, ndev) {
+		/* skip addresses matching reserved slots */
+		if (!memcmp(eth_reserved_addr_base, ha->addr, 5) ||
+		    !memcmp(eth_ipv4_mcast_addr_base, ha->addr, 5)) {
+			netdev_dbg(ndev, "mcast skip %pM\n", ha->addr);
+			continue;
+		}
+
+		if (slot >= FT1_NUM_SLOTS) {
+			netdev_dbg(ndev,
+				   "can't add more than %d MC addresses, enabling allmulti\n",
+				   FT1_NUM_SLOTS);
+			icssg_class_default(miig_rt, slice, 1, true);
+			break;
+		}
+
+		netdev_dbg(ndev, "mcast add %pM\n", ha->addr);
+		icssg_class_ft1_add_mcast(miig_rt, slice, slot,
+					  ha->addr, mask_addr);
+		slot++;
+	}
+}
+
 /* required for SAV check */
 void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr)
 {
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index e6eac01f9f99..7d9db9683e18 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -437,7 +437,7 @@ static int emac_ndo_open(struct net_device *ndev)
 	icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
 	icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
 
-	icssg_class_default(prueth->miig_rt, slice, 0);
+	icssg_class_default(prueth->miig_rt, slice, 0, false);
 
 	/* Notify the stack of the actual queue counts. */
 	ret = netif_set_real_num_tx_queues(ndev, num_data_chn);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index a8192e408941..faefd9351c39 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -283,7 +283,11 @@ extern const struct dev_pm_ops prueth_dev_pm_ops;
 void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac);
 void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac);
 void icssg_class_disable(struct regmap *miig_rt, int slice);
-void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti);
+void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti,
+			 bool is_sr1);
+void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice);
+void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice,
+			       struct net_device *ndev);
 void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr);
 
 /* config helpers */
-- 
2.43.2



From diogo.ivo at siemens.com  Wed Feb 21 07:24:15 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Wed, 21 Feb 2024 15:24:15 +0000
Subject: [PATCH net-next v3 09/10] net: ti: icssg-prueth: Modify common functions for SR1.0
In-Reply-To: <20240221152421.112324-1-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
Message-ID: <20240221152421.112324-10-diogo.ivo@siemens.com>

Some parts of the logic differ only slightly between Silicon Revisions.
In these cases add the bits that differ to a common function that
executes those bits conditionally based on the Silicon Revision.

Based on the work of Roger Quadros, Vignesh Raghavendra and
Grygorii Strashko in TI's 5.10 SDK [1].

[1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y

Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
 drivers/net/ethernet/ti/icssg/icssg_common.c | 46 +++++++++++++++-----
 drivers/net/ethernet/ti/icssg/icssg_prueth.c |  4 +-
 drivers/net/ethernet/ti/icssg/icssg_prueth.h |  2 +-
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
index 99f27ecc9352..d4488cf5d7da 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_common.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
@@ -152,6 +152,13 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
 						     desc_dma);
 		swdata = cppi5_hdesc_get_swdata(desc_tx);
 
+		/* was this command's TX complete? */
+		if (emac->is_sr1 && *(swdata) == emac->cmd_data) {
+			prueth_xmit_free(tx_chn, desc_tx);
+			budget++;       /* not a data packet */
+			continue;
+		}
+
 		skb = *(swdata);
 		prueth_xmit_free(tx_chn, desc_tx);
 
@@ -327,6 +334,7 @@ int prueth_init_rx_chns(struct prueth_emac *emac,
 	struct net_device *ndev = emac->ndev;
 	u32 fdqring_id, hdesc_size;
 	int i, ret = 0, slice;
+	int flow_id_base;
 
 	slice = prueth_emac_slice(emac);
 	if (slice < 0)
@@ -367,8 +375,14 @@ int prueth_init_rx_chns(struct prueth_emac *emac,
 		goto fail;
 	}
 
-	emac->rx_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn);
-	netdev_dbg(ndev, "flow id base = %d\n", emac->rx_flow_id_base);
+	flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn);
+	if (!strcmp(name, "rxmgm")) {
+		emac->rx_mgm_flow_id_base = flow_id_base;
+		netdev_dbg(ndev, "mgm flow id base = %d\n", flow_id_base);
+	} else {
+		emac->rx_flow_id_base = flow_id_base;
+		netdev_dbg(ndev, "flow id base = %d\n", flow_id_base);
+	}
 
 	fdqring_id = K3_RINGACC_RING_ID_ANY;
 	for (i = 0; i < rx_cfg.flow_id_num; i++) {
@@ -477,10 +491,14 @@ void emac_rx_timestamp(struct prueth_emac *emac,
 	struct skb_shared_hwtstamps *ssh;
 	u64 ns;
 
-	u32 hi_sw = readl(emac->prueth->shram.va +
-			  TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET);
-	ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0],
-			    IEP_DEFAULT_CYCLE_TIME_NS);
+	if (emac->is_sr1) {
+		ns = (u64)psdata[1] << 32 | psdata[0];
+	} else {
+		u32 hi_sw = readl(emac->prueth->shram.va +
+				  TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET);
+		ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0],
+				    IEP_DEFAULT_CYCLE_TIME_NS);
+	}
 
 	ssh = skb_hwtstamps(skb);
 	memset(ssh, 0, sizeof(*ssh));
@@ -809,7 +827,8 @@ void prueth_emac_stop(struct prueth_emac *emac)
 	}
 
 	emac->fw_running = 0;
-	rproc_shutdown(prueth->txpru[slice]);
+	if (!emac->is_sr1)
+		rproc_shutdown(prueth->txpru[slice]);
 	rproc_shutdown(prueth->rtu[slice]);
 	rproc_shutdown(prueth->pru[slice]);
 }
@@ -829,8 +848,10 @@ void prueth_cleanup_tx_ts(struct prueth_emac *emac)
 int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget)
 {
 	struct prueth_emac *emac = prueth_napi_to_emac(napi_rx);
-	int rx_flow = PRUETH_RX_FLOW_DATA;
-	int flow = PRUETH_MAX_RX_FLOWS;
+	int rx_flow = emac->is_sr1 ?
+		PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA;
+	int flow = emac->is_sr1 ?
+		PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS;
 	int num_rx = 0;
 	int cur_budget;
 	int ret;
@@ -1082,7 +1103,7 @@ void prueth_netdev_exit(struct prueth *prueth,
 	prueth->emac[mac] = NULL;
 }
 
-int prueth_get_cores(struct prueth *prueth, int slice)
+int prueth_get_cores(struct prueth *prueth, int slice, bool is_sr1)
 {
 	struct device *dev = prueth->dev;
 	enum pruss_pru_id pruss_id;
@@ -1096,7 +1117,7 @@ int prueth_get_cores(struct prueth *prueth, int slice)
 		idx = 0;
 		break;
 	case ICSS_SLICE1:
-		idx = 3;
+		idx = is_sr1 ? 2 : 3;
 		break;
 	default:
 		return -EINVAL;
@@ -1118,6 +1139,9 @@ int prueth_get_cores(struct prueth *prueth, int slice)
 		return dev_err_probe(dev, ret, "unable to get RTU%d\n", slice);
 	}
 
+	if (is_sr1)
+		return 0;
+
 	idx++;
 	prueth->txpru[slice] = pru_rproc_get(np, idx, NULL);
 	if (IS_ERR(prueth->txpru[slice])) {
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index 7d9db9683e18..5eab0657494c 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -907,13 +907,13 @@ static int prueth_probe(struct platform_device *pdev)
 	}
 
 	if (eth0_node) {
-		ret = prueth_get_cores(prueth, ICSS_SLICE0);
+		ret = prueth_get_cores(prueth, ICSS_SLICE0, true);
 		if (ret)
 			goto put_cores;
 	}
 
 	if (eth1_node) {
-		ret = prueth_get_cores(prueth, ICSS_SLICE1);
+		ret = prueth_get_cores(prueth, ICSS_SLICE1, true);
 		if (ret)
 			goto put_cores;
 	}
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index faefd9351c39..d706460f2ca3 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -354,7 +354,7 @@ int prueth_node_port(struct device_node *eth_node);
 int prueth_node_mac(struct device_node *eth_node);
 void prueth_netdev_exit(struct prueth *prueth,
 			struct device_node *eth_node);
-int prueth_get_cores(struct prueth *prueth, int slice);
+int prueth_get_cores(struct prueth *prueth, int slice, bool is_sr1);
 void prueth_put_cores(struct prueth *prueth, int slice);
 
 /* Revision specific helper */
-- 
2.43.2



From diogo.ivo at siemens.com  Wed Feb 21 07:24:09 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Wed, 21 Feb 2024 15:24:09 +0000
Subject: [PATCH net-next v3 03/10] net: ti: icssg-prueth: Move common functions into a separate file
In-Reply-To: <20240221152421.112324-1-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
Message-ID: <20240221152421.112324-4-diogo.ivo@siemens.com>

In order to allow code sharing between Silicon Revisions 1.0 and 2.0
move all functions that can be shared into a common file. This commit
introduces no functional changes.

Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
 drivers/net/ethernet/ti/Makefile             |    1 +
 drivers/net/ethernet/ti/icssg/icssg_common.c | 1198 ++++++++++++++++++
 drivers/net/ethernet/ti/icssg/icssg_prueth.c | 1183 -----------------
 drivers/net/ethernet/ti/icssg/icssg_prueth.h |   59 +
 4 files changed, 1258 insertions(+), 1183 deletions(-)
 create mode 100644 drivers/net/ethernet/ti/icssg/icssg_common.c

diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile
index d8590304f3df..4876f20aa495 100644
--- a/drivers/net/ethernet/ti/Makefile
+++ b/drivers/net/ethernet/ti/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o
 
 obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg-prueth.o
 icssg-prueth-y := icssg/icssg_prueth.o \
+		  icssg/icssg_common.o \
 		  icssg/icssg_classifier.o \
 		  icssg/icssg_queues.o \
 		  icssg/icssg_config.o \
diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
new file mode 100644
index 000000000000..99f27ecc9352
--- /dev/null
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
@@ -0,0 +1,1198 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* Texas Instruments ICSSG Ethernet Driver
+ *
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) Siemens AG, 2024
+ *
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/dma/ti-cppi5.h>
+#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/remoteproc/pruss.h>
+#include <linux/regmap.h>
+#include <linux/remoteproc.h>
+
+#include "icssg_prueth.h"
+#include "../k3-cppi-desc-pool.h"
+
+/* Netif debug messages possible */
+#define PRUETH_EMAC_DEBUG       (NETIF_MSG_DRV | \
+				 NETIF_MSG_PROBE | \
+				 NETIF_MSG_LINK | \
+				 NETIF_MSG_TIMER | \
+				 NETIF_MSG_IFDOWN | \
+				 NETIF_MSG_IFUP | \
+				 NETIF_MSG_RX_ERR | \
+				 NETIF_MSG_TX_ERR | \
+				 NETIF_MSG_TX_QUEUED | \
+				 NETIF_MSG_INTR | \
+				 NETIF_MSG_TX_DONE | \
+				 NETIF_MSG_RX_STATUS | \
+				 NETIF_MSG_PKTDATA | \
+				 NETIF_MSG_HW | \
+				 NETIF_MSG_WOL)
+
+#define prueth_napi_to_emac(napi) container_of(napi, struct prueth_emac, napi_rx)
+
+void prueth_cleanup_rx_chns(struct prueth_emac *emac,
+			    struct prueth_rx_chn *rx_chn,
+			    int max_rflows)
+{
+	if (rx_chn->desc_pool)
+		k3_cppi_desc_pool_destroy(rx_chn->desc_pool);
+
+	if (rx_chn->rx_chn)
+		k3_udma_glue_release_rx_chn(rx_chn->rx_chn);
+}
+
+void prueth_cleanup_tx_chns(struct prueth_emac *emac)
+{
+	int i;
+
+	for (i = 0; i < emac->tx_ch_num; i++) {
+		struct prueth_tx_chn *tx_chn = &emac->tx_chns[i];
+
+		if (tx_chn->desc_pool)
+			k3_cppi_desc_pool_destroy(tx_chn->desc_pool);
+
+		if (tx_chn->tx_chn)
+			k3_udma_glue_release_tx_chn(tx_chn->tx_chn);
+
+		/* Assume prueth_cleanup_tx_chns() is called at the
+		 * end after all channel resources are freed
+		 */
+		memset(tx_chn, 0, sizeof(*tx_chn));
+	}
+}
+
+void prueth_ndev_del_tx_napi(struct prueth_emac *emac, int num)
+{
+	int i;
+
+	for (i = 0; i < num; i++) {
+		struct prueth_tx_chn *tx_chn = &emac->tx_chns[i];
+
+		if (tx_chn->irq)
+			free_irq(tx_chn->irq, tx_chn);
+		netif_napi_del(&tx_chn->napi_tx);
+	}
+}
+
+void prueth_xmit_free(struct prueth_tx_chn *tx_chn,
+		      struct cppi5_host_desc_t *desc)
+{
+	struct cppi5_host_desc_t *first_desc, *next_desc;
+	dma_addr_t buf_dma, next_desc_dma;
+	u32 buf_dma_len;
+
+	first_desc = desc;
+	next_desc = first_desc;
+
+	cppi5_hdesc_get_obuf(first_desc, &buf_dma, &buf_dma_len);
+	k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma);
+
+	dma_unmap_single(tx_chn->dma_dev, buf_dma, buf_dma_len,
+			 DMA_TO_DEVICE);
+
+	next_desc_dma = cppi5_hdesc_get_next_hbdesc(first_desc);
+	k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &next_desc_dma);
+	while (next_desc_dma) {
+		next_desc = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
+						       next_desc_dma);
+		cppi5_hdesc_get_obuf(next_desc, &buf_dma, &buf_dma_len);
+		k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma);
+
+		dma_unmap_page(tx_chn->dma_dev, buf_dma, buf_dma_len,
+			       DMA_TO_DEVICE);
+
+		next_desc_dma = cppi5_hdesc_get_next_hbdesc(next_desc);
+		k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &next_desc_dma);
+
+		k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc);
+	}
+
+	k3_cppi_desc_pool_free(tx_chn->desc_pool, first_desc);
+}
+
+int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
+			     int budget)
+{
+	struct net_device *ndev = emac->ndev;
+	struct cppi5_host_desc_t *desc_tx;
+	struct netdev_queue *netif_txq;
+	struct prueth_tx_chn *tx_chn;
+	unsigned int total_bytes = 0;
+	struct sk_buff *skb;
+	dma_addr_t desc_dma;
+	int res, num_tx = 0;
+	void **swdata;
+
+	tx_chn = &emac->tx_chns[chn];
+
+	while (true) {
+		res = k3_udma_glue_pop_tx_chn(tx_chn->tx_chn, &desc_dma);
+		if (res == -ENODATA)
+			break;
+
+		/* teardown completion */
+		if (cppi5_desc_is_tdcm(desc_dma)) {
+			if (atomic_dec_and_test(&emac->tdown_cnt))
+				complete(&emac->tdown_complete);
+			break;
+		}
+
+		desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
+						     desc_dma);
+		swdata = cppi5_hdesc_get_swdata(desc_tx);
+
+		skb = *(swdata);
+		prueth_xmit_free(tx_chn, desc_tx);
+
+		ndev = skb->dev;
+		ndev->stats.tx_packets++;
+		ndev->stats.tx_bytes += skb->len;
+		total_bytes += skb->len;
+		napi_consume_skb(skb, budget);
+		num_tx++;
+	}
+
+	if (!num_tx)
+		return 0;
+
+	netif_txq = netdev_get_tx_queue(ndev, chn);
+	netdev_tx_completed_queue(netif_txq, num_tx, total_bytes);
+
+	if (netif_tx_queue_stopped(netif_txq)) {
+		/* If the TX queue was stopped, wake it now
+		 * if we have enough room.
+		 */
+		__netif_tx_lock(netif_txq, smp_processor_id());
+		if (netif_running(ndev) &&
+		    (k3_cppi_desc_pool_avail(tx_chn->desc_pool) >=
+		     MAX_SKB_FRAGS))
+			netif_tx_wake_queue(netif_txq);
+		__netif_tx_unlock(netif_txq);
+	}
+
+	return num_tx;
+}
+
+static int emac_napi_tx_poll(struct napi_struct *napi_tx, int budget)
+{
+	struct prueth_tx_chn *tx_chn = prueth_napi_to_tx_chn(napi_tx);
+	struct prueth_emac *emac = tx_chn->emac;
+	int num_tx_packets;
+
+	num_tx_packets = emac_tx_complete_packets(emac, tx_chn->id, budget);
+
+	if (num_tx_packets >= budget)
+		return budget;
+
+	if (napi_complete_done(napi_tx, num_tx_packets))
+		enable_irq(tx_chn->irq);
+
+	return num_tx_packets;
+}
+
+static irqreturn_t prueth_tx_irq(int irq, void *dev_id)
+{
+	struct prueth_tx_chn *tx_chn = dev_id;
+
+	disable_irq_nosync(irq);
+	napi_schedule(&tx_chn->napi_tx);
+
+	return IRQ_HANDLED;
+}
+
+int prueth_ndev_add_tx_napi(struct prueth_emac *emac)
+{
+	struct prueth *prueth = emac->prueth;
+	int i, ret;
+
+	for (i = 0; i < emac->tx_ch_num; i++) {
+		struct prueth_tx_chn *tx_chn = &emac->tx_chns[i];
+
+		netif_napi_add_tx(emac->ndev, &tx_chn->napi_tx, emac_napi_tx_poll);
+		ret = request_irq(tx_chn->irq, prueth_tx_irq,
+				  IRQF_TRIGGER_HIGH, tx_chn->name,
+				  tx_chn);
+		if (ret) {
+			netif_napi_del(&tx_chn->napi_tx);
+			dev_err(prueth->dev, "unable to request TX IRQ %d\n",
+				tx_chn->irq);
+			goto fail;
+		}
+	}
+
+	return 0;
+fail:
+	prueth_ndev_del_tx_napi(emac, i);
+	return ret;
+}
+
+int prueth_init_tx_chns(struct prueth_emac *emac)
+{
+	static const struct k3_ring_cfg ring_cfg = {
+		.elm_size = K3_RINGACC_RING_ELSIZE_8,
+		.mode = K3_RINGACC_RING_MODE_RING,
+		.flags = 0,
+		.size = PRUETH_MAX_TX_DESC,
+	};
+	struct k3_udma_glue_tx_channel_cfg tx_cfg;
+	struct device *dev = emac->prueth->dev;
+	struct net_device *ndev = emac->ndev;
+	int ret, slice, i;
+	u32 hdesc_size;
+
+	slice = prueth_emac_slice(emac);
+	if (slice < 0)
+		return slice;
+
+	init_completion(&emac->tdown_complete);
+
+	hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE,
+					   PRUETH_NAV_SW_DATA_SIZE);
+	memset(&tx_cfg, 0, sizeof(tx_cfg));
+	tx_cfg.swdata_size = PRUETH_NAV_SW_DATA_SIZE;
+	tx_cfg.tx_cfg = ring_cfg;
+	tx_cfg.txcq_cfg = ring_cfg;
+
+	for (i = 0; i < emac->tx_ch_num; i++) {
+		struct prueth_tx_chn *tx_chn = &emac->tx_chns[i];
+
+		/* To differentiate channels for SLICE0 vs SLICE1 */
+		snprintf(tx_chn->name, sizeof(tx_chn->name),
+			 "tx%d-%d", slice, i);
+
+		tx_chn->emac = emac;
+		tx_chn->id = i;
+		tx_chn->descs_num = PRUETH_MAX_TX_DESC;
+
+		tx_chn->tx_chn =
+			k3_udma_glue_request_tx_chn(dev, tx_chn->name,
+						    &tx_cfg);
+		if (IS_ERR(tx_chn->tx_chn)) {
+			ret = PTR_ERR(tx_chn->tx_chn);
+			tx_chn->tx_chn = NULL;
+			netdev_err(ndev,
+				   "Failed to request tx dma ch: %d\n", ret);
+			goto fail;
+		}
+
+		tx_chn->dma_dev = k3_udma_glue_tx_get_dma_device(tx_chn->tx_chn);
+		tx_chn->desc_pool =
+			k3_cppi_desc_pool_create_name(tx_chn->dma_dev,
+						      tx_chn->descs_num,
+						      hdesc_size,
+						      tx_chn->name);
+		if (IS_ERR(tx_chn->desc_pool)) {
+			ret = PTR_ERR(tx_chn->desc_pool);
+			tx_chn->desc_pool = NULL;
+			netdev_err(ndev, "Failed to create tx pool: %d\n", ret);
+			goto fail;
+		}
+
+		ret = k3_udma_glue_tx_get_irq(tx_chn->tx_chn);
+		if (ret < 0) {
+			netdev_err(ndev, "failed to get tx irq\n");
+			goto fail;
+		}
+		tx_chn->irq = ret;
+
+		snprintf(tx_chn->name, sizeof(tx_chn->name), "%s-tx%d",
+			 dev_name(dev), tx_chn->id);
+	}
+
+	return 0;
+
+fail:
+	prueth_cleanup_tx_chns(emac);
+	return ret;
+}
+
+int prueth_init_rx_chns(struct prueth_emac *emac,
+			struct prueth_rx_chn *rx_chn,
+			char *name, u32 max_rflows,
+			u32 max_desc_num)
+{
+	struct k3_udma_glue_rx_channel_cfg rx_cfg;
+	struct device *dev = emac->prueth->dev;
+	struct net_device *ndev = emac->ndev;
+	u32 fdqring_id, hdesc_size;
+	int i, ret = 0, slice;
+
+	slice = prueth_emac_slice(emac);
+	if (slice < 0)
+		return slice;
+
+	/* To differentiate channels for SLICE0 vs SLICE1 */
+	snprintf(rx_chn->name, sizeof(rx_chn->name), "%s%d", name, slice);
+
+	hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE,
+					   PRUETH_NAV_SW_DATA_SIZE);
+	memset(&rx_cfg, 0, sizeof(rx_cfg));
+	rx_cfg.swdata_size = PRUETH_NAV_SW_DATA_SIZE;
+	rx_cfg.flow_id_num = max_rflows;
+	rx_cfg.flow_id_base = -1; /* udmax will auto select flow id base */
+
+	/* init all flows */
+	rx_chn->dev = dev;
+	rx_chn->descs_num = max_desc_num;
+
+	rx_chn->rx_chn = k3_udma_glue_request_rx_chn(dev, rx_chn->name,
+						     &rx_cfg);
+	if (IS_ERR(rx_chn->rx_chn)) {
+		ret = PTR_ERR(rx_chn->rx_chn);
+		rx_chn->rx_chn = NULL;
+		netdev_err(ndev, "Failed to request rx dma ch: %d\n", ret);
+		goto fail;
+	}
+
+	rx_chn->dma_dev = k3_udma_glue_rx_get_dma_device(rx_chn->rx_chn);
+	rx_chn->desc_pool = k3_cppi_desc_pool_create_name(rx_chn->dma_dev,
+							  rx_chn->descs_num,
+							  hdesc_size,
+							  rx_chn->name);
+	if (IS_ERR(rx_chn->desc_pool)) {
+		ret = PTR_ERR(rx_chn->desc_pool);
+		rx_chn->desc_pool = NULL;
+		netdev_err(ndev, "Failed to create rx pool: %d\n", ret);
+		goto fail;
+	}
+
+	emac->rx_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn);
+	netdev_dbg(ndev, "flow id base = %d\n", emac->rx_flow_id_base);
+
+	fdqring_id = K3_RINGACC_RING_ID_ANY;
+	for (i = 0; i < rx_cfg.flow_id_num; i++) {
+		struct k3_ring_cfg rxring_cfg = {
+			.elm_size = K3_RINGACC_RING_ELSIZE_8,
+			.mode = K3_RINGACC_RING_MODE_RING,
+			.flags = 0,
+		};
+		struct k3_ring_cfg fdqring_cfg = {
+			.elm_size = K3_RINGACC_RING_ELSIZE_8,
+			.flags = K3_RINGACC_RING_SHARED,
+		};
+		struct k3_udma_glue_rx_flow_cfg rx_flow_cfg = {
+			.rx_cfg = rxring_cfg,
+			.rxfdq_cfg = fdqring_cfg,
+			.ring_rxq_id = K3_RINGACC_RING_ID_ANY,
+			.src_tag_lo_sel =
+				K3_UDMA_GLUE_SRC_TAG_LO_USE_REMOTE_SRC_TAG,
+		};
+
+		rx_flow_cfg.ring_rxfdq0_id = fdqring_id;
+		rx_flow_cfg.rx_cfg.size = max_desc_num;
+		rx_flow_cfg.rxfdq_cfg.size = max_desc_num;
+		rx_flow_cfg.rxfdq_cfg.mode = emac->prueth->pdata.fdqring_mode;
+
+		ret = k3_udma_glue_rx_flow_init(rx_chn->rx_chn,
+						i, &rx_flow_cfg);
+		if (ret) {
+			netdev_err(ndev, "Failed to init rx flow%d %d\n",
+				   i, ret);
+			goto fail;
+		}
+		if (!i)
+			fdqring_id = k3_udma_glue_rx_flow_get_fdq_id(rx_chn->rx_chn,
+								     i);
+		rx_chn->irq[i] = k3_udma_glue_rx_get_irq(rx_chn->rx_chn, i);
+		if (rx_chn->irq[i] <= 0) {
+			ret = rx_chn->irq[i];
+			netdev_err(ndev, "Failed to get rx dma irq");
+			goto fail;
+		}
+	}
+
+	return 0;
+
+fail:
+	prueth_cleanup_rx_chns(emac, rx_chn, max_rflows);
+	return ret;
+}
+
+int prueth_dma_rx_push(struct prueth_emac *emac,
+		       struct sk_buff *skb,
+		       struct prueth_rx_chn *rx_chn)
+{
+	struct net_device *ndev = emac->ndev;
+	struct cppi5_host_desc_t *desc_rx;
+	u32 pkt_len = skb_tailroom(skb);
+	dma_addr_t desc_dma;
+	dma_addr_t buf_dma;
+	void **swdata;
+
+	desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool);
+	if (!desc_rx) {
+		netdev_err(ndev, "rx push: failed to allocate descriptor\n");
+		return -ENOMEM;
+	}
+	desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx);
+
+	buf_dma = dma_map_single(rx_chn->dma_dev, skb->data, pkt_len, DMA_FROM_DEVICE);
+	if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) {
+		k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
+		netdev_err(ndev, "rx push: failed to map rx pkt buffer\n");
+		return -EINVAL;
+	}
+
+	cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT,
+			 PRUETH_NAV_PS_DATA_SIZE);
+	k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chn, &buf_dma);
+	cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_tailroom(skb));
+
+	swdata = cppi5_hdesc_get_swdata(desc_rx);
+	*swdata = skb;
+
+	return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0,
+					desc_rx, desc_dma);
+}
+
+u64 icssg_ts_to_ns(u32 hi_sw, u32 hi, u32 lo, u32 cycle_time_ns)
+{
+	u32 iepcount_lo, iepcount_hi, hi_rollover_count;
+	u64 ns;
+
+	iepcount_lo = lo & GENMASK(19, 0);
+	iepcount_hi = (hi & GENMASK(11, 0)) << 12 | lo >> 20;
+	hi_rollover_count = hi >> 11;
+
+	ns = ((u64)hi_rollover_count) << 23 | (iepcount_hi + hi_sw);
+	ns = ns * cycle_time_ns + iepcount_lo;
+
+	return ns;
+}
+
+void emac_rx_timestamp(struct prueth_emac *emac,
+		       struct sk_buff *skb, u32 *psdata)
+{
+	struct skb_shared_hwtstamps *ssh;
+	u64 ns;
+
+	u32 hi_sw = readl(emac->prueth->shram.va +
+			  TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET);
+	ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0],
+			    IEP_DEFAULT_CYCLE_TIME_NS);
+
+	ssh = skb_hwtstamps(skb);
+	memset(ssh, 0, sizeof(*ssh));
+	ssh->hwtstamp = ns_to_ktime(ns);
+}
+
+static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id)
+{
+	struct prueth_rx_chn *rx_chn = &emac->rx_chns;
+	u32 buf_dma_len, pkt_len, port_id = 0;
+	struct net_device *ndev = emac->ndev;
+	struct cppi5_host_desc_t *desc_rx;
+	struct sk_buff *skb, *new_skb;
+	dma_addr_t desc_dma, buf_dma;
+	void **swdata;
+	u32 *psdata;
+	int ret;
+
+	ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma);
+	if (ret) {
+		if (ret != -ENODATA)
+			netdev_err(ndev, "rx pop: failed: %d\n", ret);
+		return ret;
+	}
+
+	if (cppi5_desc_is_tdcm(desc_dma)) /* Teardown ? */
+		return 0;
+
+	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
+
+	swdata = cppi5_hdesc_get_swdata(desc_rx);
+	skb = *swdata;
+
+	psdata = cppi5_hdesc_get_psdata(desc_rx);
+	/* RX HW timestamp */
+	if (emac->rx_ts_enabled)
+		emac_rx_timestamp(emac, skb, psdata);
+
+	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
+	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma);
+	pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
+	/* firmware adds 4 CRC bytes, strip them */
+	pkt_len -= 4;
+	cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL);
+
+	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
+	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
+
+	skb->dev = ndev;
+	new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE);
+	/* if allocation fails we drop the packet but push the
+	 * descriptor back to the ring with old skb to prevent a stall
+	 */
+	if (!new_skb) {
+		ndev->stats.rx_dropped++;
+		new_skb = skb;
+	} else {
+		/* send the filled skb up the n/w stack */
+		skb_put(skb, pkt_len);
+		skb->protocol = eth_type_trans(skb, ndev);
+		napi_gro_receive(&emac->napi_rx, skb);
+		ndev->stats.rx_bytes += pkt_len;
+		ndev->stats.rx_packets++;
+	}
+
+	/* queue another RX DMA */
+	ret = prueth_dma_rx_push(emac, new_skb, &emac->rx_chns);
+	if (WARN_ON(ret < 0)) {
+		dev_kfree_skb_any(new_skb);
+		ndev->stats.rx_errors++;
+		ndev->stats.rx_dropped++;
+	}
+
+	return ret;
+}
+
+static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma)
+{
+	struct prueth_rx_chn *rx_chn = data;
+	struct cppi5_host_desc_t *desc_rx;
+	struct sk_buff *skb;
+	dma_addr_t buf_dma;
+	u32 buf_dma_len;
+	void **swdata;
+
+	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
+	swdata = cppi5_hdesc_get_swdata(desc_rx);
+	skb = *swdata;
+	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
+	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma);
+
+	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len,
+			 DMA_FROM_DEVICE);
+	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
+
+	dev_kfree_skb_any(skb);
+}
+
+static int prueth_tx_ts_cookie_get(struct prueth_emac *emac)
+{
+	int i;
+
+	/* search and get the next free slot */
+	for (i = 0; i < PRUETH_MAX_TX_TS_REQUESTS; i++) {
+		if (!emac->tx_ts_skb[i]) {
+			emac->tx_ts_skb[i] = ERR_PTR(-EBUSY); /* reserve slot */
+			return i;
+		}
+	}
+
+	return -EBUSY;
+}
+
+/**
+ * emac_ndo_start_xmit - EMAC Transmit function
+ * @skb: SKB pointer
+ * @ndev: EMAC network adapter
+ *
+ * Called by the system to transmit a packet  - we queue the packet in
+ * EMAC hardware transmit queue
+ * Doesn't wait for completion we'll check for TX completion in
+ * emac_tx_complete_packets().
+ *
+ * Return: enum netdev_tx
+ */
+enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct cppi5_host_desc_t *first_desc, *next_desc, *cur_desc;
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct netdev_queue *netif_txq;
+	struct prueth_tx_chn *tx_chn;
+	dma_addr_t desc_dma, buf_dma;
+	int i, ret = 0, q_idx;
+	bool in_tx_ts = 0;
+	int tx_ts_cookie;
+	void **swdata;
+	u32 pkt_len;
+	u32 *epib;
+
+	pkt_len = skb_headlen(skb);
+	q_idx = skb_get_queue_mapping(skb);
+
+	tx_chn = &emac->tx_chns[q_idx];
+	netif_txq = netdev_get_tx_queue(ndev, q_idx);
+
+	/* Map the linear buffer */
+	buf_dma = dma_map_single(tx_chn->dma_dev, skb->data, pkt_len, DMA_TO_DEVICE);
+	if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) {
+		netdev_err(ndev, "tx: failed to map skb buffer\n");
+		ret = NETDEV_TX_OK;
+		goto drop_free_skb;
+	}
+
+	first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool);
+	if (!first_desc) {
+		netdev_dbg(ndev, "tx: failed to allocate descriptor\n");
+		dma_unmap_single(tx_chn->dma_dev, buf_dma, pkt_len, DMA_TO_DEVICE);
+		goto drop_stop_q_busy;
+	}
+
+	cppi5_hdesc_init(first_desc, CPPI5_INFO0_HDESC_EPIB_PRESENT,
+			 PRUETH_NAV_PS_DATA_SIZE);
+	cppi5_hdesc_set_pkttype(first_desc, 0);
+	epib = first_desc->epib;
+	epib[0] = 0;
+	epib[1] = 0;
+	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+	    emac->tx_ts_enabled) {
+		tx_ts_cookie = prueth_tx_ts_cookie_get(emac);
+		if (tx_ts_cookie >= 0) {
+			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+			/* Request TX timestamp */
+			epib[0] = (u32)tx_ts_cookie;
+			epib[1] = 0x80000000;	/* TX TS request */
+			emac->tx_ts_skb[tx_ts_cookie] = skb_get(skb);
+			in_tx_ts = 1;
+		}
+	}
+
+	/* set dst tag to indicate internal qid at the firmware which is at
+	 * bit8..bit15. bit0..bit7 indicates port num for directed
+	 * packets in case of switch mode operation
+	 */
+	cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8)));
+	k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma);
+	cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len);
+	swdata = cppi5_hdesc_get_swdata(first_desc);
+	*swdata = skb;
+
+	/* Handle the case where skb is fragmented in pages */
+	cur_desc = first_desc;
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		u32 frag_size = skb_frag_size(frag);
+
+		next_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool);
+		if (!next_desc) {
+			netdev_err(ndev,
+				   "tx: failed to allocate frag. descriptor\n");
+			goto free_desc_stop_q_busy_cleanup_tx_ts;
+		}
+
+		buf_dma = skb_frag_dma_map(tx_chn->dma_dev, frag, 0, frag_size,
+					   DMA_TO_DEVICE);
+		if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) {
+			netdev_err(ndev, "tx: Failed to map skb page\n");
+			k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc);
+			ret = NETDEV_TX_OK;
+			goto cleanup_tx_ts;
+		}
+
+		cppi5_hdesc_reset_hbdesc(next_desc);
+		k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma);
+		cppi5_hdesc_attach_buf(next_desc,
+				       buf_dma, frag_size, buf_dma, frag_size);
+
+		desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool,
+						      next_desc);
+		k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &desc_dma);
+		cppi5_hdesc_link_hbdesc(cur_desc, desc_dma);
+
+		pkt_len += frag_size;
+		cur_desc = next_desc;
+	}
+	WARN_ON_ONCE(pkt_len != skb->len);
+
+	/* report bql before sending packet */
+	netdev_tx_sent_queue(netif_txq, pkt_len);
+
+	cppi5_hdesc_set_pktlen(first_desc, pkt_len);
+	desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc);
+	/* cppi5_desc_dump(first_desc, 64); */
+
+	skb_tx_timestamp(skb);  /* SW timestamp if SKBTX_IN_PROGRESS not set */
+	ret = k3_udma_glue_push_tx_chn(tx_chn->tx_chn, first_desc, desc_dma);
+	if (ret) {
+		netdev_err(ndev, "tx: push failed: %d\n", ret);
+		goto drop_free_descs;
+	}
+
+	if (in_tx_ts)
+		atomic_inc(&emac->tx_ts_pending);
+
+	if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) < MAX_SKB_FRAGS) {
+		netif_tx_stop_queue(netif_txq);
+		/* Barrier, so that stop_queue visible to other cpus */
+		smp_mb__after_atomic();
+
+		if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) >=
+		    MAX_SKB_FRAGS)
+			netif_tx_wake_queue(netif_txq);
+	}
+
+	return NETDEV_TX_OK;
+
+cleanup_tx_ts:
+	if (in_tx_ts) {
+		dev_kfree_skb_any(emac->tx_ts_skb[tx_ts_cookie]);
+		emac->tx_ts_skb[tx_ts_cookie] = NULL;
+	}
+
+drop_free_descs:
+	prueth_xmit_free(tx_chn, first_desc);
+
+drop_free_skb:
+	dev_kfree_skb_any(skb);
+
+	/* error */
+	ndev->stats.tx_dropped++;
+	netdev_err(ndev, "tx: error: %d\n", ret);
+
+	return ret;
+
+free_desc_stop_q_busy_cleanup_tx_ts:
+	if (in_tx_ts) {
+		dev_kfree_skb_any(emac->tx_ts_skb[tx_ts_cookie]);
+		emac->tx_ts_skb[tx_ts_cookie] = NULL;
+	}
+	prueth_xmit_free(tx_chn, first_desc);
+
+drop_stop_q_busy:
+	netif_tx_stop_queue(netif_txq);
+	return NETDEV_TX_BUSY;
+}
+
+static void prueth_tx_cleanup(void *data, dma_addr_t desc_dma)
+{
+	struct prueth_tx_chn *tx_chn = data;
+	struct cppi5_host_desc_t *desc_tx;
+	struct sk_buff *skb;
+	void **swdata;
+
+	desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma);
+	swdata = cppi5_hdesc_get_swdata(desc_tx);
+	skb = *(swdata);
+	prueth_xmit_free(tx_chn, desc_tx);
+
+	dev_kfree_skb_any(skb);
+}
+
+irqreturn_t prueth_rx_irq(int irq, void *dev_id)
+{
+	struct prueth_emac *emac = dev_id;
+
+	disable_irq_nosync(irq);
+	napi_schedule(&emac->napi_rx);
+
+	return IRQ_HANDLED;
+}
+
+void prueth_emac_stop(struct prueth_emac *emac)
+{
+	struct prueth *prueth = emac->prueth;
+	int slice;
+
+	switch (emac->port_id) {
+	case PRUETH_PORT_MII0:
+		slice = ICSS_SLICE0;
+		break;
+	case PRUETH_PORT_MII1:
+		slice = ICSS_SLICE1;
+		break;
+	default:
+		netdev_err(emac->ndev, "invalid port\n");
+		return;
+	}
+
+	emac->fw_running = 0;
+	rproc_shutdown(prueth->txpru[slice]);
+	rproc_shutdown(prueth->rtu[slice]);
+	rproc_shutdown(prueth->pru[slice]);
+}
+
+void prueth_cleanup_tx_ts(struct prueth_emac *emac)
+{
+	int i;
+
+	for (i = 0; i < PRUETH_MAX_TX_TS_REQUESTS; i++) {
+		if (emac->tx_ts_skb[i]) {
+			dev_kfree_skb_any(emac->tx_ts_skb[i]);
+			emac->tx_ts_skb[i] = NULL;
+		}
+	}
+}
+
+int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget)
+{
+	struct prueth_emac *emac = prueth_napi_to_emac(napi_rx);
+	int rx_flow = PRUETH_RX_FLOW_DATA;
+	int flow = PRUETH_MAX_RX_FLOWS;
+	int num_rx = 0;
+	int cur_budget;
+	int ret;
+
+	while (flow--) {
+		cur_budget = budget - num_rx;
+
+		while (cur_budget--) {
+			ret = emac_rx_packet(emac, flow);
+			if (ret)
+				break;
+			num_rx++;
+		}
+
+		if (num_rx >= budget)
+			break;
+	}
+
+	if (num_rx < budget && napi_complete_done(napi_rx, num_rx))
+		enable_irq(emac->rx_chns.irq[rx_flow]);
+
+	return num_rx;
+}
+
+int prueth_prepare_rx_chan(struct prueth_emac *emac,
+			   struct prueth_rx_chn *chn,
+			   int buf_size)
+{
+	struct sk_buff *skb;
+	int i, ret;
+
+	for (i = 0; i < chn->descs_num; i++) {
+		skb = __netdev_alloc_skb_ip_align(NULL, buf_size, GFP_KERNEL);
+		if (!skb)
+			return -ENOMEM;
+
+		ret = prueth_dma_rx_push(emac, skb, chn);
+		if (ret < 0) {
+			netdev_err(emac->ndev,
+				   "cannot submit skb for rx chan %s ret %d\n",
+				   chn->name, ret);
+			kfree_skb(skb);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+void prueth_reset_tx_chan(struct prueth_emac *emac, int ch_num,
+			  bool free_skb)
+{
+	int i;
+
+	for (i = 0; i < ch_num; i++) {
+		if (free_skb)
+			k3_udma_glue_reset_tx_chn(emac->tx_chns[i].tx_chn,
+						  &emac->tx_chns[i],
+						  prueth_tx_cleanup);
+		k3_udma_glue_disable_tx_chn(emac->tx_chns[i].tx_chn);
+	}
+}
+
+void prueth_reset_rx_chan(struct prueth_rx_chn *chn,
+			  int num_flows, bool disable)
+{
+	int i;
+
+	for (i = 0; i < num_flows; i++)
+		k3_udma_glue_reset_rx_chn(chn->rx_chn, i, chn,
+					  prueth_rx_cleanup, !!i);
+	if (disable)
+		k3_udma_glue_disable_rx_chn(chn->rx_chn);
+}
+
+void emac_ndo_tx_timeout(struct net_device *ndev, unsigned int txqueue)
+{
+	ndev->stats.tx_errors++;
+}
+
+static int emac_set_ts_config(struct net_device *ndev, struct ifreq *ifr)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct hwtstamp_config config;
+
+	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+		return -EFAULT;
+
+	switch (config.tx_type) {
+	case HWTSTAMP_TX_OFF:
+		emac->tx_ts_enabled = 0;
+		break;
+	case HWTSTAMP_TX_ON:
+		emac->tx_ts_enabled = 1;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (config.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		emac->rx_ts_enabled = 0;
+		break;
+	case HWTSTAMP_FILTER_ALL:
+	case HWTSTAMP_FILTER_SOME:
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+	case HWTSTAMP_FILTER_NTP_ALL:
+		emac->rx_ts_enabled = 1;
+		config.rx_filter = HWTSTAMP_FILTER_ALL;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+		-EFAULT : 0;
+}
+
+static int emac_get_ts_config(struct net_device *ndev, struct ifreq *ifr)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct hwtstamp_config config;
+
+	config.flags = 0;
+	config.tx_type = emac->tx_ts_enabled ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+	config.rx_filter = emac->rx_ts_enabled ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE;
+
+	return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+			    -EFAULT : 0;
+}
+
+int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
+{
+	switch (cmd) {
+	case SIOCGHWTSTAMP:
+		return emac_get_ts_config(ndev, ifr);
+	case SIOCSHWTSTAMP:
+		return emac_set_ts_config(ndev, ifr);
+	default:
+		break;
+	}
+
+	return phy_do_ioctl(ndev, ifr, cmd);
+}
+
+void emac_ndo_get_stats64(struct net_device *ndev,
+			  struct rtnl_link_stats64 *stats)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+
+	emac_update_hardware_stats(emac);
+
+	stats->rx_packets     = emac_get_stat_by_name(emac, "rx_packets");
+	stats->rx_bytes       = emac_get_stat_by_name(emac, "rx_bytes");
+	stats->tx_packets     = emac_get_stat_by_name(emac, "tx_packets");
+	stats->tx_bytes       = emac_get_stat_by_name(emac, "tx_bytes");
+	stats->rx_crc_errors  = emac_get_stat_by_name(emac, "rx_crc_errors");
+	stats->rx_over_errors = emac_get_stat_by_name(emac, "rx_over_errors");
+	stats->multicast      = emac_get_stat_by_name(emac, "rx_multicast_frames");
+
+	stats->rx_errors  = ndev->stats.rx_errors;
+	stats->rx_dropped = ndev->stats.rx_dropped;
+	stats->tx_errors  = ndev->stats.tx_errors;
+	stats->tx_dropped = ndev->stats.tx_dropped;
+}
+
+int emac_ndo_get_phys_port_name(struct net_device *ndev, char *name,
+				size_t len)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	int ret;
+
+	ret = snprintf(name, len, "p%d", emac->port_id);
+	if (ret >= len)
+		return -EINVAL;
+
+	return 0;
+}
+
+/* get emac_port corresponding to eth_node name */
+int prueth_node_port(struct device_node *eth_node)
+{
+	u32 port_id;
+	int ret;
+
+	ret = of_property_read_u32(eth_node, "reg", &port_id);
+	if (ret)
+		return ret;
+
+	if (port_id == 0)
+		return PRUETH_PORT_MII0;
+	else if (port_id == 1)
+		return PRUETH_PORT_MII1;
+	else
+		return PRUETH_PORT_INVALID;
+}
+
+/* get MAC instance corresponding to eth_node name */
+int prueth_node_mac(struct device_node *eth_node)
+{
+	u32 port_id;
+	int ret;
+
+	ret = of_property_read_u32(eth_node, "reg", &port_id);
+	if (ret)
+		return ret;
+
+	if (port_id == 0)
+		return PRUETH_MAC0;
+	else if (port_id == 1)
+		return PRUETH_MAC1;
+	else
+		return PRUETH_MAC_INVALID;
+}
+
+void prueth_netdev_exit(struct prueth *prueth,
+			struct device_node *eth_node)
+{
+	struct prueth_emac *emac;
+	enum prueth_mac mac;
+
+	mac = prueth_node_mac(eth_node);
+	if (mac == PRUETH_MAC_INVALID)
+		return;
+
+	emac = prueth->emac[mac];
+	if (!emac)
+		return;
+
+	if (of_phy_is_fixed_link(emac->phy_node))
+		of_phy_deregister_fixed_link(emac->phy_node);
+
+	netif_napi_del(&emac->napi_rx);
+
+	pruss_release_mem_region(prueth->pruss, &emac->dram);
+	destroy_workqueue(emac->cmd_wq);
+	free_netdev(emac->ndev);
+	prueth->emac[mac] = NULL;
+}
+
+int prueth_get_cores(struct prueth *prueth, int slice)
+{
+	struct device *dev = prueth->dev;
+	enum pruss_pru_id pruss_id;
+	struct device_node *np;
+	int idx = -1, ret;
+
+	np = dev->of_node;
+
+	switch (slice) {
+	case ICSS_SLICE0:
+		idx = 0;
+		break;
+	case ICSS_SLICE1:
+		idx = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	prueth->pru[slice] = pru_rproc_get(np, idx, &pruss_id);
+	if (IS_ERR(prueth->pru[slice])) {
+		ret = PTR_ERR(prueth->pru[slice]);
+		prueth->pru[slice] = NULL;
+		return dev_err_probe(dev, ret, "unable to get PRU%d\n", slice);
+	}
+	prueth->pru_id[slice] = pruss_id;
+
+	idx++;
+	prueth->rtu[slice] = pru_rproc_get(np, idx, NULL);
+	if (IS_ERR(prueth->rtu[slice])) {
+		ret = PTR_ERR(prueth->rtu[slice]);
+		prueth->rtu[slice] = NULL;
+		return dev_err_probe(dev, ret, "unable to get RTU%d\n", slice);
+	}
+
+	idx++;
+	prueth->txpru[slice] = pru_rproc_get(np, idx, NULL);
+	if (IS_ERR(prueth->txpru[slice])) {
+		ret = PTR_ERR(prueth->txpru[slice]);
+		prueth->txpru[slice] = NULL;
+		return dev_err_probe(dev, ret, "unable to get TX_PRU%d\n", slice);
+	}
+
+	return 0;
+}
+
+void prueth_put_cores(struct prueth *prueth, int slice)
+{
+	if (prueth->txpru[slice])
+		pru_rproc_put(prueth->txpru[slice]);
+
+	if (prueth->rtu[slice])
+		pru_rproc_put(prueth->rtu[slice]);
+
+	if (prueth->pru[slice])
+		pru_rproc_put(prueth->pru[slice]);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int prueth_suspend(struct device *dev)
+{
+	struct prueth *prueth = dev_get_drvdata(dev);
+	struct net_device *ndev;
+	int i, ret;
+
+	for (i = 0; i < PRUETH_NUM_MACS; i++) {
+		ndev = prueth->registered_netdevs[i];
+
+		if (!ndev)
+			continue;
+
+		if (netif_running(ndev)) {
+			netif_device_detach(ndev);
+			ret = ndev->netdev_ops->ndo_stop(ndev);
+			if (ret < 0) {
+				netdev_err(ndev, "failed to stop: %d", ret);
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int prueth_resume(struct device *dev)
+{
+	struct prueth *prueth = dev_get_drvdata(dev);
+	struct net_device *ndev;
+	int i, ret;
+
+	for (i = 0; i < PRUETH_NUM_MACS; i++) {
+		ndev = prueth->registered_netdevs[i];
+
+		if (!ndev)
+			continue;
+
+		if (netif_running(ndev)) {
+			ret = ndev->netdev_ops->ndo_open(ndev);
+			if (ret < 0) {
+				netdev_err(ndev, "failed to start: %d", ret);
+				return ret;
+			}
+			netif_device_attach(ndev);
+		}
+	}
+
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+const struct dev_pm_ops prueth_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(prueth_suspend, prueth_resume)
+};
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index cf7b73f8f450..e6eac01f9f99 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -34,568 +34,9 @@
 
 #define PRUETH_MODULE_DESCRIPTION "PRUSS ICSSG Ethernet driver"
 
-/* Netif debug messages possible */
-#define PRUETH_EMAC_DEBUG       (NETIF_MSG_DRV | \
-				 NETIF_MSG_PROBE | \
-				 NETIF_MSG_LINK | \
-				 NETIF_MSG_TIMER | \
-				 NETIF_MSG_IFDOWN | \
-				 NETIF_MSG_IFUP | \
-				 NETIF_MSG_RX_ERR | \
-				 NETIF_MSG_TX_ERR | \
-				 NETIF_MSG_TX_QUEUED | \
-				 NETIF_MSG_INTR | \
-				 NETIF_MSG_TX_DONE | \
-				 NETIF_MSG_RX_STATUS | \
-				 NETIF_MSG_PKTDATA | \
-				 NETIF_MSG_HW | \
-				 NETIF_MSG_WOL)
-
-#define prueth_napi_to_emac(napi) container_of(napi, struct prueth_emac, napi_rx)
-
 /* CTRLMMR_ICSSG_RGMII_CTRL register bits */
 #define ICSSG_CTRL_RGMII_ID_MODE                BIT(24)
 
-#define IEP_DEFAULT_CYCLE_TIME_NS	1000000	/* 1 ms */
-
-static void prueth_cleanup_rx_chns(struct prueth_emac *emac,
-				   struct prueth_rx_chn *rx_chn,
-				   int max_rflows)
-{
-	if (rx_chn->desc_pool)
-		k3_cppi_desc_pool_destroy(rx_chn->desc_pool);
-
-	if (rx_chn->rx_chn)
-		k3_udma_glue_release_rx_chn(rx_chn->rx_chn);
-}
-
-static void prueth_cleanup_tx_chns(struct prueth_emac *emac)
-{
-	int i;
-
-	for (i = 0; i < emac->tx_ch_num; i++) {
-		struct prueth_tx_chn *tx_chn = &emac->tx_chns[i];
-
-		if (tx_chn->desc_pool)
-			k3_cppi_desc_pool_destroy(tx_chn->desc_pool);
-
-		if (tx_chn->tx_chn)
-			k3_udma_glue_release_tx_chn(tx_chn->tx_chn);
-
-		/* Assume prueth_cleanup_tx_chns() is called at the
-		 * end after all channel resources are freed
-		 */
-		memset(tx_chn, 0, sizeof(*tx_chn));
-	}
-}
-
-static void prueth_ndev_del_tx_napi(struct prueth_emac *emac, int num)
-{
-	int i;
-
-	for (i = 0; i < num; i++) {
-		struct prueth_tx_chn *tx_chn = &emac->tx_chns[i];
-
-		if (tx_chn->irq)
-			free_irq(tx_chn->irq, tx_chn);
-		netif_napi_del(&tx_chn->napi_tx);
-	}
-}
-
-static void prueth_xmit_free(struct prueth_tx_chn *tx_chn,
-			     struct cppi5_host_desc_t *desc)
-{
-	struct cppi5_host_desc_t *first_desc, *next_desc;
-	dma_addr_t buf_dma, next_desc_dma;
-	u32 buf_dma_len;
-
-	first_desc = desc;
-	next_desc = first_desc;
-
-	cppi5_hdesc_get_obuf(first_desc, &buf_dma, &buf_dma_len);
-	k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma);
-
-	dma_unmap_single(tx_chn->dma_dev, buf_dma, buf_dma_len,
-			 DMA_TO_DEVICE);
-
-	next_desc_dma = cppi5_hdesc_get_next_hbdesc(first_desc);
-	k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &next_desc_dma);
-	while (next_desc_dma) {
-		next_desc = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
-						       next_desc_dma);
-		cppi5_hdesc_get_obuf(next_desc, &buf_dma, &buf_dma_len);
-		k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma);
-
-		dma_unmap_page(tx_chn->dma_dev, buf_dma, buf_dma_len,
-			       DMA_TO_DEVICE);
-
-		next_desc_dma = cppi5_hdesc_get_next_hbdesc(next_desc);
-		k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &next_desc_dma);
-
-		k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc);
-	}
-
-	k3_cppi_desc_pool_free(tx_chn->desc_pool, first_desc);
-}
-
-static int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
-				    int budget)
-{
-	struct net_device *ndev = emac->ndev;
-	struct cppi5_host_desc_t *desc_tx;
-	struct netdev_queue *netif_txq;
-	struct prueth_tx_chn *tx_chn;
-	unsigned int total_bytes = 0;
-	struct sk_buff *skb;
-	dma_addr_t desc_dma;
-	int res, num_tx = 0;
-	void **swdata;
-
-	tx_chn = &emac->tx_chns[chn];
-
-	while (true) {
-		res = k3_udma_glue_pop_tx_chn(tx_chn->tx_chn, &desc_dma);
-		if (res == -ENODATA)
-			break;
-
-		/* teardown completion */
-		if (cppi5_desc_is_tdcm(desc_dma)) {
-			if (atomic_dec_and_test(&emac->tdown_cnt))
-				complete(&emac->tdown_complete);
-			break;
-		}
-
-		desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool,
-						     desc_dma);
-		swdata = cppi5_hdesc_get_swdata(desc_tx);
-
-		skb = *(swdata);
-		prueth_xmit_free(tx_chn, desc_tx);
-
-		ndev = skb->dev;
-		ndev->stats.tx_packets++;
-		ndev->stats.tx_bytes += skb->len;
-		total_bytes += skb->len;
-		napi_consume_skb(skb, budget);
-		num_tx++;
-	}
-
-	if (!num_tx)
-		return 0;
-
-	netif_txq = netdev_get_tx_queue(ndev, chn);
-	netdev_tx_completed_queue(netif_txq, num_tx, total_bytes);
-
-	if (netif_tx_queue_stopped(netif_txq)) {
-		/* If the TX queue was stopped, wake it now
-		 * if we have enough room.
-		 */
-		__netif_tx_lock(netif_txq, smp_processor_id());
-		if (netif_running(ndev) &&
-		    (k3_cppi_desc_pool_avail(tx_chn->desc_pool) >=
-		     MAX_SKB_FRAGS))
-			netif_tx_wake_queue(netif_txq);
-		__netif_tx_unlock(netif_txq);
-	}
-
-	return num_tx;
-}
-
-static int emac_napi_tx_poll(struct napi_struct *napi_tx, int budget)
-{
-	struct prueth_tx_chn *tx_chn = prueth_napi_to_tx_chn(napi_tx);
-	struct prueth_emac *emac = tx_chn->emac;
-	int num_tx_packets;
-
-	num_tx_packets = emac_tx_complete_packets(emac, tx_chn->id, budget);
-
-	if (num_tx_packets >= budget)
-		return budget;
-
-	if (napi_complete_done(napi_tx, num_tx_packets))
-		enable_irq(tx_chn->irq);
-
-	return num_tx_packets;
-}
-
-static irqreturn_t prueth_tx_irq(int irq, void *dev_id)
-{
-	struct prueth_tx_chn *tx_chn = dev_id;
-
-	disable_irq_nosync(irq);
-	napi_schedule(&tx_chn->napi_tx);
-
-	return IRQ_HANDLED;
-}
-
-static int prueth_ndev_add_tx_napi(struct prueth_emac *emac)
-{
-	struct prueth *prueth = emac->prueth;
-	int i, ret;
-
-	for (i = 0; i < emac->tx_ch_num; i++) {
-		struct prueth_tx_chn *tx_chn = &emac->tx_chns[i];
-
-		netif_napi_add_tx(emac->ndev, &tx_chn->napi_tx, emac_napi_tx_poll);
-		ret = request_irq(tx_chn->irq, prueth_tx_irq,
-				  IRQF_TRIGGER_HIGH, tx_chn->name,
-				  tx_chn);
-		if (ret) {
-			netif_napi_del(&tx_chn->napi_tx);
-			dev_err(prueth->dev, "unable to request TX IRQ %d\n",
-				tx_chn->irq);
-			goto fail;
-		}
-	}
-
-	return 0;
-fail:
-	prueth_ndev_del_tx_napi(emac, i);
-	return ret;
-}
-
-static int prueth_init_tx_chns(struct prueth_emac *emac)
-{
-	static const struct k3_ring_cfg ring_cfg = {
-		.elm_size = K3_RINGACC_RING_ELSIZE_8,
-		.mode = K3_RINGACC_RING_MODE_RING,
-		.flags = 0,
-		.size = PRUETH_MAX_TX_DESC,
-	};
-	struct k3_udma_glue_tx_channel_cfg tx_cfg;
-	struct device *dev = emac->prueth->dev;
-	struct net_device *ndev = emac->ndev;
-	int ret, slice, i;
-	u32 hdesc_size;
-
-	slice = prueth_emac_slice(emac);
-	if (slice < 0)
-		return slice;
-
-	init_completion(&emac->tdown_complete);
-
-	hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE,
-					   PRUETH_NAV_SW_DATA_SIZE);
-	memset(&tx_cfg, 0, sizeof(tx_cfg));
-	tx_cfg.swdata_size = PRUETH_NAV_SW_DATA_SIZE;
-	tx_cfg.tx_cfg = ring_cfg;
-	tx_cfg.txcq_cfg = ring_cfg;
-
-	for (i = 0; i < emac->tx_ch_num; i++) {
-		struct prueth_tx_chn *tx_chn = &emac->tx_chns[i];
-
-		/* To differentiate channels for SLICE0 vs SLICE1 */
-		snprintf(tx_chn->name, sizeof(tx_chn->name),
-			 "tx%d-%d", slice, i);
-
-		tx_chn->emac = emac;
-		tx_chn->id = i;
-		tx_chn->descs_num = PRUETH_MAX_TX_DESC;
-
-		tx_chn->tx_chn =
-			k3_udma_glue_request_tx_chn(dev, tx_chn->name,
-						    &tx_cfg);
-		if (IS_ERR(tx_chn->tx_chn)) {
-			ret = PTR_ERR(tx_chn->tx_chn);
-			tx_chn->tx_chn = NULL;
-			netdev_err(ndev,
-				   "Failed to request tx dma ch: %d\n", ret);
-			goto fail;
-		}
-
-		tx_chn->dma_dev = k3_udma_glue_tx_get_dma_device(tx_chn->tx_chn);
-		tx_chn->desc_pool =
-			k3_cppi_desc_pool_create_name(tx_chn->dma_dev,
-						      tx_chn->descs_num,
-						      hdesc_size,
-						      tx_chn->name);
-		if (IS_ERR(tx_chn->desc_pool)) {
-			ret = PTR_ERR(tx_chn->desc_pool);
-			tx_chn->desc_pool = NULL;
-			netdev_err(ndev, "Failed to create tx pool: %d\n", ret);
-			goto fail;
-		}
-
-		ret = k3_udma_glue_tx_get_irq(tx_chn->tx_chn);
-		if (ret < 0) {
-			netdev_err(ndev, "failed to get tx irq\n");
-			goto fail;
-		}
-		tx_chn->irq = ret;
-
-		snprintf(tx_chn->name, sizeof(tx_chn->name), "%s-tx%d",
-			 dev_name(dev), tx_chn->id);
-	}
-
-	return 0;
-
-fail:
-	prueth_cleanup_tx_chns(emac);
-	return ret;
-}
-
-static int prueth_init_rx_chns(struct prueth_emac *emac,
-			       struct prueth_rx_chn *rx_chn,
-			       char *name, u32 max_rflows,
-			       u32 max_desc_num)
-{
-	struct k3_udma_glue_rx_channel_cfg rx_cfg;
-	struct device *dev = emac->prueth->dev;
-	struct net_device *ndev = emac->ndev;
-	u32 fdqring_id, hdesc_size;
-	int i, ret = 0, slice;
-
-	slice = prueth_emac_slice(emac);
-	if (slice < 0)
-		return slice;
-
-	/* To differentiate channels for SLICE0 vs SLICE1 */
-	snprintf(rx_chn->name, sizeof(rx_chn->name), "%s%d", name, slice);
-
-	hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE,
-					   PRUETH_NAV_SW_DATA_SIZE);
-	memset(&rx_cfg, 0, sizeof(rx_cfg));
-	rx_cfg.swdata_size = PRUETH_NAV_SW_DATA_SIZE;
-	rx_cfg.flow_id_num = max_rflows;
-	rx_cfg.flow_id_base = -1; /* udmax will auto select flow id base */
-
-	/* init all flows */
-	rx_chn->dev = dev;
-	rx_chn->descs_num = max_desc_num;
-
-	rx_chn->rx_chn = k3_udma_glue_request_rx_chn(dev, rx_chn->name,
-						     &rx_cfg);
-	if (IS_ERR(rx_chn->rx_chn)) {
-		ret = PTR_ERR(rx_chn->rx_chn);
-		rx_chn->rx_chn = NULL;
-		netdev_err(ndev, "Failed to request rx dma ch: %d\n", ret);
-		goto fail;
-	}
-
-	rx_chn->dma_dev = k3_udma_glue_rx_get_dma_device(rx_chn->rx_chn);
-	rx_chn->desc_pool = k3_cppi_desc_pool_create_name(rx_chn->dma_dev,
-							  rx_chn->descs_num,
-							  hdesc_size,
-							  rx_chn->name);
-	if (IS_ERR(rx_chn->desc_pool)) {
-		ret = PTR_ERR(rx_chn->desc_pool);
-		rx_chn->desc_pool = NULL;
-		netdev_err(ndev, "Failed to create rx pool: %d\n", ret);
-		goto fail;
-	}
-
-	emac->rx_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn);
-	netdev_dbg(ndev, "flow id base = %d\n", emac->rx_flow_id_base);
-
-	fdqring_id = K3_RINGACC_RING_ID_ANY;
-	for (i = 0; i < rx_cfg.flow_id_num; i++) {
-		struct k3_ring_cfg rxring_cfg = {
-			.elm_size = K3_RINGACC_RING_ELSIZE_8,
-			.mode = K3_RINGACC_RING_MODE_RING,
-			.flags = 0,
-		};
-		struct k3_ring_cfg fdqring_cfg = {
-			.elm_size = K3_RINGACC_RING_ELSIZE_8,
-			.flags = K3_RINGACC_RING_SHARED,
-		};
-		struct k3_udma_glue_rx_flow_cfg rx_flow_cfg = {
-			.rx_cfg = rxring_cfg,
-			.rxfdq_cfg = fdqring_cfg,
-			.ring_rxq_id = K3_RINGACC_RING_ID_ANY,
-			.src_tag_lo_sel =
-				K3_UDMA_GLUE_SRC_TAG_LO_USE_REMOTE_SRC_TAG,
-		};
-
-		rx_flow_cfg.ring_rxfdq0_id = fdqring_id;
-		rx_flow_cfg.rx_cfg.size = max_desc_num;
-		rx_flow_cfg.rxfdq_cfg.size = max_desc_num;
-		rx_flow_cfg.rxfdq_cfg.mode = emac->prueth->pdata.fdqring_mode;
-
-		ret = k3_udma_glue_rx_flow_init(rx_chn->rx_chn,
-						i, &rx_flow_cfg);
-		if (ret) {
-			netdev_err(ndev, "Failed to init rx flow%d %d\n",
-				   i, ret);
-			goto fail;
-		}
-		if (!i)
-			fdqring_id = k3_udma_glue_rx_flow_get_fdq_id(rx_chn->rx_chn,
-								     i);
-		rx_chn->irq[i] = k3_udma_glue_rx_get_irq(rx_chn->rx_chn, i);
-		if (rx_chn->irq[i] <= 0) {
-			ret = rx_chn->irq[i];
-			netdev_err(ndev, "Failed to get rx dma irq");
-			goto fail;
-		}
-	}
-
-	return 0;
-
-fail:
-	prueth_cleanup_rx_chns(emac, rx_chn, max_rflows);
-	return ret;
-}
-
-static int prueth_dma_rx_push(struct prueth_emac *emac,
-			      struct sk_buff *skb,
-			      struct prueth_rx_chn *rx_chn)
-{
-	struct net_device *ndev = emac->ndev;
-	struct cppi5_host_desc_t *desc_rx;
-	u32 pkt_len = skb_tailroom(skb);
-	dma_addr_t desc_dma;
-	dma_addr_t buf_dma;
-	void **swdata;
-
-	desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool);
-	if (!desc_rx) {
-		netdev_err(ndev, "rx push: failed to allocate descriptor\n");
-		return -ENOMEM;
-	}
-	desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx);
-
-	buf_dma = dma_map_single(rx_chn->dma_dev, skb->data, pkt_len, DMA_FROM_DEVICE);
-	if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) {
-		k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
-		netdev_err(ndev, "rx push: failed to map rx pkt buffer\n");
-		return -EINVAL;
-	}
-
-	cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT,
-			 PRUETH_NAV_PS_DATA_SIZE);
-	k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chn, &buf_dma);
-	cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_tailroom(skb));
-
-	swdata = cppi5_hdesc_get_swdata(desc_rx);
-	*swdata = skb;
-
-	return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0,
-					desc_rx, desc_dma);
-}
-
-static u64 icssg_ts_to_ns(u32 hi_sw, u32 hi, u32 lo, u32 cycle_time_ns)
-{
-	u32 iepcount_lo, iepcount_hi, hi_rollover_count;
-	u64 ns;
-
-	iepcount_lo = lo & GENMASK(19, 0);
-	iepcount_hi = (hi & GENMASK(11, 0)) << 12 | lo >> 20;
-	hi_rollover_count = hi >> 11;
-
-	ns = ((u64)hi_rollover_count) << 23 | (iepcount_hi + hi_sw);
-	ns = ns * cycle_time_ns + iepcount_lo;
-
-	return ns;
-}
-
-static void emac_rx_timestamp(struct prueth_emac *emac,
-			      struct sk_buff *skb, u32 *psdata)
-{
-	struct skb_shared_hwtstamps *ssh;
-	u64 ns;
-
-	u32 hi_sw = readl(emac->prueth->shram.va +
-			  TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET);
-	ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0],
-			    IEP_DEFAULT_CYCLE_TIME_NS);
-
-	ssh = skb_hwtstamps(skb);
-	memset(ssh, 0, sizeof(*ssh));
-	ssh->hwtstamp = ns_to_ktime(ns);
-}
-
-static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id)
-{
-	struct prueth_rx_chn *rx_chn = &emac->rx_chns;
-	u32 buf_dma_len, pkt_len, port_id = 0;
-	struct net_device *ndev = emac->ndev;
-	struct cppi5_host_desc_t *desc_rx;
-	struct sk_buff *skb, *new_skb;
-	dma_addr_t desc_dma, buf_dma;
-	void **swdata;
-	u32 *psdata;
-	int ret;
-
-	ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma);
-	if (ret) {
-		if (ret != -ENODATA)
-			netdev_err(ndev, "rx pop: failed: %d\n", ret);
-		return ret;
-	}
-
-	if (cppi5_desc_is_tdcm(desc_dma)) /* Teardown ? */
-		return 0;
-
-	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
-
-	swdata = cppi5_hdesc_get_swdata(desc_rx);
-	skb = *swdata;
-
-	psdata = cppi5_hdesc_get_psdata(desc_rx);
-	/* RX HW timestamp */
-	if (emac->rx_ts_enabled)
-		emac_rx_timestamp(emac, skb, psdata);
-
-	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
-	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma);
-	pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
-	/* firmware adds 4 CRC bytes, strip them */
-	pkt_len -= 4;
-	cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL);
-
-	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
-	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
-
-	skb->dev = ndev;
-	new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE);
-	/* if allocation fails we drop the packet but push the
-	 * descriptor back to the ring with old skb to prevent a stall
-	 */
-	if (!new_skb) {
-		ndev->stats.rx_dropped++;
-		new_skb = skb;
-	} else {
-		/* send the filled skb up the n/w stack */
-		skb_put(skb, pkt_len);
-		skb->protocol = eth_type_trans(skb, ndev);
-		napi_gro_receive(&emac->napi_rx, skb);
-		ndev->stats.rx_bytes += pkt_len;
-		ndev->stats.rx_packets++;
-	}
-
-	/* queue another RX DMA */
-	ret = prueth_dma_rx_push(emac, new_skb, &emac->rx_chns);
-	if (WARN_ON(ret < 0)) {
-		dev_kfree_skb_any(new_skb);
-		ndev->stats.rx_errors++;
-		ndev->stats.rx_dropped++;
-	}
-
-	return ret;
-}
-
-static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma)
-{
-	struct prueth_rx_chn *rx_chn = data;
-	struct cppi5_host_desc_t *desc_rx;
-	struct sk_buff *skb;
-	dma_addr_t buf_dma;
-	u32 buf_dma_len;
-	void **swdata;
-
-	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
-	swdata = cppi5_hdesc_get_swdata(desc_rx);
-	skb = *swdata;
-	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
-	k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma);
-
-	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len,
-			 DMA_FROM_DEVICE);
-	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
-
-	dev_kfree_skb_any(skb);
-}
-
 static int emac_get_tx_ts(struct prueth_emac *emac,
 			  struct emac_tx_ts_response *rsp)
 {
@@ -661,208 +102,6 @@ static void tx_ts_work(struct prueth_emac *emac)
 	}
 }
 
-static int prueth_tx_ts_cookie_get(struct prueth_emac *emac)
-{
-	int i;
-
-	/* search and get the next free slot */
-	for (i = 0; i < PRUETH_MAX_TX_TS_REQUESTS; i++) {
-		if (!emac->tx_ts_skb[i]) {
-			emac->tx_ts_skb[i] = ERR_PTR(-EBUSY); /* reserve slot */
-			return i;
-		}
-	}
-
-	return -EBUSY;
-}
-
-/**
- * emac_ndo_start_xmit - EMAC Transmit function
- * @skb: SKB pointer
- * @ndev: EMAC network adapter
- *
- * Called by the system to transmit a packet  - we queue the packet in
- * EMAC hardware transmit queue
- * Doesn't wait for completion we'll check for TX completion in
- * emac_tx_complete_packets().
- *
- * Return: enum netdev_tx
- */
-static enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
-{
-	struct cppi5_host_desc_t *first_desc, *next_desc, *cur_desc;
-	struct prueth_emac *emac = netdev_priv(ndev);
-	struct netdev_queue *netif_txq;
-	struct prueth_tx_chn *tx_chn;
-	dma_addr_t desc_dma, buf_dma;
-	int i, ret = 0, q_idx;
-	bool in_tx_ts = 0;
-	int tx_ts_cookie;
-	void **swdata;
-	u32 pkt_len;
-	u32 *epib;
-
-	pkt_len = skb_headlen(skb);
-	q_idx = skb_get_queue_mapping(skb);
-
-	tx_chn = &emac->tx_chns[q_idx];
-	netif_txq = netdev_get_tx_queue(ndev, q_idx);
-
-	/* Map the linear buffer */
-	buf_dma = dma_map_single(tx_chn->dma_dev, skb->data, pkt_len, DMA_TO_DEVICE);
-	if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) {
-		netdev_err(ndev, "tx: failed to map skb buffer\n");
-		ret = NETDEV_TX_OK;
-		goto drop_free_skb;
-	}
-
-	first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool);
-	if (!first_desc) {
-		netdev_dbg(ndev, "tx: failed to allocate descriptor\n");
-		dma_unmap_single(tx_chn->dma_dev, buf_dma, pkt_len, DMA_TO_DEVICE);
-		goto drop_stop_q_busy;
-	}
-
-	cppi5_hdesc_init(first_desc, CPPI5_INFO0_HDESC_EPIB_PRESENT,
-			 PRUETH_NAV_PS_DATA_SIZE);
-	cppi5_hdesc_set_pkttype(first_desc, 0);
-	epib = first_desc->epib;
-	epib[0] = 0;
-	epib[1] = 0;
-	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
-	    emac->tx_ts_enabled) {
-		tx_ts_cookie = prueth_tx_ts_cookie_get(emac);
-		if (tx_ts_cookie >= 0) {
-			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
-			/* Request TX timestamp */
-			epib[0] = (u32)tx_ts_cookie;
-			epib[1] = 0x80000000;	/* TX TS request */
-			emac->tx_ts_skb[tx_ts_cookie] = skb_get(skb);
-			in_tx_ts = 1;
-		}
-	}
-
-	/* set dst tag to indicate internal qid at the firmware which is at
-	 * bit8..bit15. bit0..bit7 indicates port num for directed
-	 * packets in case of switch mode operation
-	 */
-	cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8)));
-	k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma);
-	cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len);
-	swdata = cppi5_hdesc_get_swdata(first_desc);
-	*swdata = skb;
-
-	/* Handle the case where skb is fragmented in pages */
-	cur_desc = first_desc;
-	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-		u32 frag_size = skb_frag_size(frag);
-
-		next_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool);
-		if (!next_desc) {
-			netdev_err(ndev,
-				   "tx: failed to allocate frag. descriptor\n");
-			goto free_desc_stop_q_busy_cleanup_tx_ts;
-		}
-
-		buf_dma = skb_frag_dma_map(tx_chn->dma_dev, frag, 0, frag_size,
-					   DMA_TO_DEVICE);
-		if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) {
-			netdev_err(ndev, "tx: Failed to map skb page\n");
-			k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc);
-			ret = NETDEV_TX_OK;
-			goto cleanup_tx_ts;
-		}
-
-		cppi5_hdesc_reset_hbdesc(next_desc);
-		k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma);
-		cppi5_hdesc_attach_buf(next_desc,
-				       buf_dma, frag_size, buf_dma, frag_size);
-
-		desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool,
-						      next_desc);
-		k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &desc_dma);
-		cppi5_hdesc_link_hbdesc(cur_desc, desc_dma);
-
-		pkt_len += frag_size;
-		cur_desc = next_desc;
-	}
-	WARN_ON_ONCE(pkt_len != skb->len);
-
-	/* report bql before sending packet */
-	netdev_tx_sent_queue(netif_txq, pkt_len);
-
-	cppi5_hdesc_set_pktlen(first_desc, pkt_len);
-	desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc);
-	/* cppi5_desc_dump(first_desc, 64); */
-
-	skb_tx_timestamp(skb);  /* SW timestamp if SKBTX_IN_PROGRESS not set */
-	ret = k3_udma_glue_push_tx_chn(tx_chn->tx_chn, first_desc, desc_dma);
-	if (ret) {
-		netdev_err(ndev, "tx: push failed: %d\n", ret);
-		goto drop_free_descs;
-	}
-
-	if (in_tx_ts)
-		atomic_inc(&emac->tx_ts_pending);
-
-	if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) < MAX_SKB_FRAGS) {
-		netif_tx_stop_queue(netif_txq);
-		/* Barrier, so that stop_queue visible to other cpus */
-		smp_mb__after_atomic();
-
-		if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) >=
-		    MAX_SKB_FRAGS)
-			netif_tx_wake_queue(netif_txq);
-	}
-
-	return NETDEV_TX_OK;
-
-cleanup_tx_ts:
-	if (in_tx_ts) {
-		dev_kfree_skb_any(emac->tx_ts_skb[tx_ts_cookie]);
-		emac->tx_ts_skb[tx_ts_cookie] = NULL;
-	}
-
-drop_free_descs:
-	prueth_xmit_free(tx_chn, first_desc);
-
-drop_free_skb:
-	dev_kfree_skb_any(skb);
-
-	/* error */
-	ndev->stats.tx_dropped++;
-	netdev_err(ndev, "tx: error: %d\n", ret);
-
-	return ret;
-
-free_desc_stop_q_busy_cleanup_tx_ts:
-	if (in_tx_ts) {
-		dev_kfree_skb_any(emac->tx_ts_skb[tx_ts_cookie]);
-		emac->tx_ts_skb[tx_ts_cookie] = NULL;
-	}
-	prueth_xmit_free(tx_chn, first_desc);
-
-drop_stop_q_busy:
-	netif_tx_stop_queue(netif_txq);
-	return NETDEV_TX_BUSY;
-}
-
-static void prueth_tx_cleanup(void *data, dma_addr_t desc_dma)
-{
-	struct prueth_tx_chn *tx_chn = data;
-	struct cppi5_host_desc_t *desc_tx;
-	struct sk_buff *skb;
-	void **swdata;
-
-	desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma);
-	swdata = cppi5_hdesc_get_swdata(desc_tx);
-	skb = *(swdata);
-	prueth_xmit_free(tx_chn, desc_tx);
-
-	dev_kfree_skb_any(skb);
-}
-
 static irqreturn_t prueth_tx_ts_irq(int irq, void *dev_id)
 {
 	struct prueth_emac *emac = dev_id;
@@ -873,22 +112,6 @@ static irqreturn_t prueth_tx_ts_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t prueth_rx_irq(int irq, void *dev_id)
-{
-	struct prueth_emac *emac = dev_id;
-
-	disable_irq_nosync(irq);
-	napi_schedule(&emac->napi_rx);
-
-	return IRQ_HANDLED;
-}
-
-struct icssg_firmwares {
-	char *pru;
-	char *rtu;
-	char *txpru;
-};
-
 static struct icssg_firmwares icssg_emac_firmwares[] = {
 	{
 		.pru = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
@@ -953,41 +176,6 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
 	return ret;
 }
 
-static void prueth_emac_stop(struct prueth_emac *emac)
-{
-	struct prueth *prueth = emac->prueth;
-	int slice;
-
-	switch (emac->port_id) {
-	case PRUETH_PORT_MII0:
-		slice = ICSS_SLICE0;
-		break;
-	case PRUETH_PORT_MII1:
-		slice = ICSS_SLICE1;
-		break;
-	default:
-		netdev_err(emac->ndev, "invalid port\n");
-		return;
-	}
-
-	emac->fw_running = 0;
-	rproc_shutdown(prueth->txpru[slice]);
-	rproc_shutdown(prueth->rtu[slice]);
-	rproc_shutdown(prueth->pru[slice]);
-}
-
-static void prueth_cleanup_tx_ts(struct prueth_emac *emac)
-{
-	int i;
-
-	for (i = 0; i < PRUETH_MAX_TX_TS_REQUESTS; i++) {
-		if (emac->tx_ts_skb[i]) {
-			dev_kfree_skb_any(emac->tx_ts_skb[i]);
-			emac->tx_ts_skb[i] = NULL;
-		}
-	}
-}
-
 /* called back by PHY layer if there is change in link state of hw port*/
 static void emac_adjust_link(struct net_device *ndev)
 {
@@ -1055,86 +243,6 @@ static void emac_adjust_link(struct net_device *ndev)
 	}
 }
 
-static int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget)
-{
-	struct prueth_emac *emac = prueth_napi_to_emac(napi_rx);
-	int rx_flow = PRUETH_RX_FLOW_DATA;
-	int flow = PRUETH_MAX_RX_FLOWS;
-	int num_rx = 0;
-	int cur_budget;
-	int ret;
-
-	while (flow--) {
-		cur_budget = budget - num_rx;
-
-		while (cur_budget--) {
-			ret = emac_rx_packet(emac, flow);
-			if (ret)
-				break;
-			num_rx++;
-		}
-
-		if (num_rx >= budget)
-			break;
-	}
-
-	if (num_rx < budget && napi_complete_done(napi_rx, num_rx))
-		enable_irq(emac->rx_chns.irq[rx_flow]);
-
-	return num_rx;
-}
-
-static int prueth_prepare_rx_chan(struct prueth_emac *emac,
-				  struct prueth_rx_chn *chn,
-				  int buf_size)
-{
-	struct sk_buff *skb;
-	int i, ret;
-
-	for (i = 0; i < chn->descs_num; i++) {
-		skb = __netdev_alloc_skb_ip_align(NULL, buf_size, GFP_KERNEL);
-		if (!skb)
-			return -ENOMEM;
-
-		ret = prueth_dma_rx_push(emac, skb, chn);
-		if (ret < 0) {
-			netdev_err(emac->ndev,
-				   "cannot submit skb for rx chan %s ret %d\n",
-				   chn->name, ret);
-			kfree_skb(skb);
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
-static void prueth_reset_tx_chan(struct prueth_emac *emac, int ch_num,
-				 bool free_skb)
-{
-	int i;
-
-	for (i = 0; i < ch_num; i++) {
-		if (free_skb)
-			k3_udma_glue_reset_tx_chn(emac->tx_chns[i].tx_chn,
-						  &emac->tx_chns[i],
-						  prueth_tx_cleanup);
-		k3_udma_glue_disable_tx_chn(emac->tx_chns[i].tx_chn);
-	}
-}
-
-static void prueth_reset_rx_chan(struct prueth_rx_chn *chn,
-				 int num_flows, bool disable)
-{
-	int i;
-
-	for (i = 0; i < num_flows; i++)
-		k3_udma_glue_reset_rx_chn(chn->rx_chn, i, chn,
-					  prueth_rx_cleanup, !!i);
-	if (disable)
-		k3_udma_glue_disable_rx_chn(chn->rx_chn);
-}
-
 static int emac_phy_connect(struct prueth_emac *emac)
 {
 	struct prueth *prueth = emac->prueth;
@@ -1508,11 +616,6 @@ static int emac_ndo_stop(struct net_device *ndev)
 	return 0;
 }
 
-static void emac_ndo_tx_timeout(struct net_device *ndev, unsigned int txqueue)
-{
-	ndev->stats.tx_errors++;
-}
-
 static void emac_ndo_set_rx_mode_work(struct work_struct *work)
 {
 	struct prueth_emac *emac = container_of(work, struct prueth_emac, rx_mode_work);
@@ -1558,116 +661,6 @@ static void emac_ndo_set_rx_mode(struct net_device *ndev)
 	queue_work(emac->cmd_wq, &emac->rx_mode_work);
 }
 
-static int emac_set_ts_config(struct net_device *ndev, struct ifreq *ifr)
-{
-	struct prueth_emac *emac = netdev_priv(ndev);
-	struct hwtstamp_config config;
-
-	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
-		return -EFAULT;
-
-	switch (config.tx_type) {
-	case HWTSTAMP_TX_OFF:
-		emac->tx_ts_enabled = 0;
-		break;
-	case HWTSTAMP_TX_ON:
-		emac->tx_ts_enabled = 1;
-		break;
-	default:
-		return -ERANGE;
-	}
-
-	switch (config.rx_filter) {
-	case HWTSTAMP_FILTER_NONE:
-		emac->rx_ts_enabled = 0;
-		break;
-	case HWTSTAMP_FILTER_ALL:
-	case HWTSTAMP_FILTER_SOME:
-	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
-	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
-	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
-	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
-	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
-	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
-	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
-	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
-	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
-	case HWTSTAMP_FILTER_PTP_V2_EVENT:
-	case HWTSTAMP_FILTER_PTP_V2_SYNC:
-	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
-	case HWTSTAMP_FILTER_NTP_ALL:
-		emac->rx_ts_enabled = 1;
-		config.rx_filter = HWTSTAMP_FILTER_ALL;
-		break;
-	default:
-		return -ERANGE;
-	}
-
-	return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-		-EFAULT : 0;
-}
-
-static int emac_get_ts_config(struct net_device *ndev, struct ifreq *ifr)
-{
-	struct prueth_emac *emac = netdev_priv(ndev);
-	struct hwtstamp_config config;
-
-	config.flags = 0;
-	config.tx_type = emac->tx_ts_enabled ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
-	config.rx_filter = emac->rx_ts_enabled ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE;
-
-	return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-			    -EFAULT : 0;
-}
-
-static int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
-{
-	switch (cmd) {
-	case SIOCGHWTSTAMP:
-		return emac_get_ts_config(ndev, ifr);
-	case SIOCSHWTSTAMP:
-		return emac_set_ts_config(ndev, ifr);
-	default:
-		break;
-	}
-
-	return phy_do_ioctl(ndev, ifr, cmd);
-}
-
-static void emac_ndo_get_stats64(struct net_device *ndev,
-				 struct rtnl_link_stats64 *stats)
-{
-	struct prueth_emac *emac = netdev_priv(ndev);
-
-	emac_update_hardware_stats(emac);
-
-	stats->rx_packets     = emac_get_stat_by_name(emac, "rx_packets");
-	stats->rx_bytes       = emac_get_stat_by_name(emac, "rx_bytes");
-	stats->tx_packets     = emac_get_stat_by_name(emac, "tx_packets");
-	stats->tx_bytes       = emac_get_stat_by_name(emac, "tx_bytes");
-	stats->rx_crc_errors  = emac_get_stat_by_name(emac, "rx_crc_errors");
-	stats->rx_over_errors = emac_get_stat_by_name(emac, "rx_over_errors");
-	stats->multicast      = emac_get_stat_by_name(emac, "rx_multicast_frames");
-
-	stats->rx_errors  = ndev->stats.rx_errors;
-	stats->rx_dropped = ndev->stats.rx_dropped;
-	stats->tx_errors  = ndev->stats.tx_errors;
-	stats->tx_dropped = ndev->stats.tx_dropped;
-}
-
-static int emac_ndo_get_phys_port_name(struct net_device *ndev, char *name,
-				       size_t len)
-{
-	struct prueth_emac *emac = netdev_priv(ndev);
-	int ret;
-
-	ret = snprintf(name, len, "p%d", emac->port_id);
-	if (ret >= len)
-		return -EINVAL;
-
-	return 0;
-}
-
 static const struct net_device_ops emac_netdev_ops = {
 	.ndo_open = emac_ndo_open,
 	.ndo_stop = emac_ndo_stop,
@@ -1681,42 +674,6 @@ static const struct net_device_ops emac_netdev_ops = {
 	.ndo_get_phys_port_name = emac_ndo_get_phys_port_name,
 };
 
-/* get emac_port corresponding to eth_node name */
-static int prueth_node_port(struct device_node *eth_node)
-{
-	u32 port_id;
-	int ret;
-
-	ret = of_property_read_u32(eth_node, "reg", &port_id);
-	if (ret)
-		return ret;
-
-	if (port_id == 0)
-		return PRUETH_PORT_MII0;
-	else if (port_id == 1)
-		return PRUETH_PORT_MII1;
-	else
-		return PRUETH_PORT_INVALID;
-}
-
-/* get MAC instance corresponding to eth_node name */
-static int prueth_node_mac(struct device_node *eth_node)
-{
-	u32 port_id;
-	int ret;
-
-	ret = of_property_read_u32(eth_node, "reg", &port_id);
-	if (ret)
-		return ret;
-
-	if (port_id == 0)
-		return PRUETH_MAC0;
-	else if (port_id == 1)
-		return PRUETH_MAC1;
-	else
-		return PRUETH_MAC_INVALID;
-}
-
 static int prueth_netdev_init(struct prueth *prueth,
 			      struct device_node *eth_node)
 {
@@ -1860,90 +817,6 @@ static int prueth_netdev_init(struct prueth *prueth,
 	return ret;
 }
 
-static void prueth_netdev_exit(struct prueth *prueth,
-			       struct device_node *eth_node)
-{
-	struct prueth_emac *emac;
-	enum prueth_mac mac;
-
-	mac = prueth_node_mac(eth_node);
-	if (mac == PRUETH_MAC_INVALID)
-		return;
-
-	emac = prueth->emac[mac];
-	if (!emac)
-		return;
-
-	if (of_phy_is_fixed_link(emac->phy_node))
-		of_phy_deregister_fixed_link(emac->phy_node);
-
-	netif_napi_del(&emac->napi_rx);
-
-	pruss_release_mem_region(prueth->pruss, &emac->dram);
-	destroy_workqueue(emac->cmd_wq);
-	free_netdev(emac->ndev);
-	prueth->emac[mac] = NULL;
-}
-
-static int prueth_get_cores(struct prueth *prueth, int slice)
-{
-	struct device *dev = prueth->dev;
-	enum pruss_pru_id pruss_id;
-	struct device_node *np;
-	int idx = -1, ret;
-
-	np = dev->of_node;
-
-	switch (slice) {
-	case ICSS_SLICE0:
-		idx = 0;
-		break;
-	case ICSS_SLICE1:
-		idx = 3;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	prueth->pru[slice] = pru_rproc_get(np, idx, &pruss_id);
-	if (IS_ERR(prueth->pru[slice])) {
-		ret = PTR_ERR(prueth->pru[slice]);
-		prueth->pru[slice] = NULL;
-		return dev_err_probe(dev, ret, "unable to get PRU%d\n", slice);
-	}
-	prueth->pru_id[slice] = pruss_id;
-
-	idx++;
-	prueth->rtu[slice] = pru_rproc_get(np, idx, NULL);
-	if (IS_ERR(prueth->rtu[slice])) {
-		ret = PTR_ERR(prueth->rtu[slice]);
-		prueth->rtu[slice] = NULL;
-		return dev_err_probe(dev, ret, "unable to get RTU%d\n", slice);
-	}
-
-	idx++;
-	prueth->txpru[slice] = pru_rproc_get(np, idx, NULL);
-	if (IS_ERR(prueth->txpru[slice])) {
-		ret = PTR_ERR(prueth->txpru[slice]);
-		prueth->txpru[slice] = NULL;
-		return dev_err_probe(dev, ret, "unable to get TX_PRU%d\n", slice);
-	}
-
-	return 0;
-}
-
-static void prueth_put_cores(struct prueth *prueth, int slice)
-{
-	if (prueth->txpru[slice])
-		pru_rproc_put(prueth->txpru[slice]);
-
-	if (prueth->rtu[slice])
-		pru_rproc_put(prueth->rtu[slice]);
-
-	if (prueth->pru[slice])
-		pru_rproc_put(prueth->pru[slice]);
-}
-
 static int prueth_probe(struct platform_device *pdev)
 {
 	struct device_node *eth_node, *eth_ports_node;
@@ -2273,62 +1146,6 @@ static void prueth_remove(struct platform_device *pdev)
 		prueth_put_cores(prueth, ICSS_SLICE0);
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int prueth_suspend(struct device *dev)
-{
-	struct prueth *prueth = dev_get_drvdata(dev);
-	struct net_device *ndev;
-	int i, ret;
-
-	for (i = 0; i < PRUETH_NUM_MACS; i++) {
-		ndev = prueth->registered_netdevs[i];
-
-		if (!ndev)
-			continue;
-
-		if (netif_running(ndev)) {
-			netif_device_detach(ndev);
-			ret = emac_ndo_stop(ndev);
-			if (ret < 0) {
-				netdev_err(ndev, "failed to stop: %d", ret);
-				return ret;
-			}
-		}
-	}
-
-	return 0;
-}
-
-static int prueth_resume(struct device *dev)
-{
-	struct prueth *prueth = dev_get_drvdata(dev);
-	struct net_device *ndev;
-	int i, ret;
-
-	for (i = 0; i < PRUETH_NUM_MACS; i++) {
-		ndev = prueth->registered_netdevs[i];
-
-		if (!ndev)
-			continue;
-
-		if (netif_running(ndev)) {
-			ret = emac_ndo_open(ndev);
-			if (ret < 0) {
-				netdev_err(ndev, "failed to start: %d", ret);
-				return ret;
-			}
-			netif_device_attach(ndev);
-		}
-	}
-
-	return 0;
-}
-#endif /* CONFIG_PM_SLEEP */
-
-static const struct dev_pm_ops prueth_dev_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(prueth_suspend, prueth_resume)
-};
-
 static const struct prueth_pdata am654_icssg_pdata = {
 	.fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE,
 	.quirk_10m_link_issue = 1,
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index 8b6d6b497010..5d792e9bade0 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -55,6 +55,8 @@
 #define ICSSG_NUM_STANDARD_STATS 31
 #define ICSSG_NUM_ETHTOOL_STATS (ICSSG_NUM_STATS - ICSSG_NUM_STANDARD_STATS)
 
+#define IEP_DEFAULT_CYCLE_TIME_NS	1000000	/* 1 ms */
+
 /* Firmware status codes */
 #define ICSS_HS_FW_READY 0x55555555
 #define ICSS_HS_FW_DEAD 0xDEAD0000	/* lower 16 bits contain error code */
@@ -188,6 +190,12 @@ struct prueth_pdata {
 	u32	quirk_10m_link_issue:1;
 };
 
+struct icssg_firmwares {
+	char *pru;
+	char *rtu;
+	char *txpru;
+};
+
 /**
  * struct prueth - PRUeth structure
  * @dev: device
@@ -257,6 +265,7 @@ static inline int prueth_emac_slice(struct prueth_emac *emac)
 }
 
 extern const struct ethtool_ops icssg_ethtool_ops;
+extern const struct dev_pm_ops prueth_dev_pm_ops;
 
 /* Classifier helpers */
 void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac);
@@ -285,4 +294,54 @@ u32 icssg_queue_level(struct prueth *prueth, int queue);
 void emac_stats_work_handler(struct work_struct *work);
 void emac_update_hardware_stats(struct prueth_emac *emac);
 int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name);
+
+/* Common functions */
+void prueth_cleanup_rx_chns(struct prueth_emac *emac,
+			    struct prueth_rx_chn *rx_chn,
+			    int max_rflows);
+void prueth_cleanup_tx_chns(struct prueth_emac *emac);
+void prueth_ndev_del_tx_napi(struct prueth_emac *emac, int num);
+void prueth_xmit_free(struct prueth_tx_chn *tx_chn,
+		      struct cppi5_host_desc_t *desc);
+int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
+			     int budget);
+int prueth_ndev_add_tx_napi(struct prueth_emac *emac);
+int prueth_init_tx_chns(struct prueth_emac *emac);
+int prueth_init_rx_chns(struct prueth_emac *emac,
+			struct prueth_rx_chn *rx_chn,
+			char *name, u32 max_rflows,
+			u32 max_desc_num);
+int prueth_dma_rx_push(struct prueth_emac *emac,
+		       struct sk_buff *skb,
+		       struct prueth_rx_chn *rx_chn);
+void emac_rx_timestamp(struct prueth_emac *emac,
+		       struct sk_buff *skb, u32 *psdata);
+enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev);
+irqreturn_t prueth_rx_irq(int irq, void *dev_id);
+void prueth_emac_stop(struct prueth_emac *emac);
+void prueth_cleanup_tx_ts(struct prueth_emac *emac);
+int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget);
+int prueth_prepare_rx_chan(struct prueth_emac *emac,
+			   struct prueth_rx_chn *chn,
+			   int buf_size);
+void prueth_reset_tx_chan(struct prueth_emac *emac, int ch_num,
+			  bool free_skb);
+void prueth_reset_rx_chan(struct prueth_rx_chn *chn,
+			  int num_flows, bool disable);
+void emac_ndo_tx_timeout(struct net_device *ndev, unsigned int txqueue);
+int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd);
+void emac_ndo_get_stats64(struct net_device *ndev,
+			  struct rtnl_link_stats64 *stats);
+int emac_ndo_get_phys_port_name(struct net_device *ndev, char *name,
+				size_t len);
+int prueth_node_port(struct device_node *eth_node);
+int prueth_node_mac(struct device_node *eth_node);
+void prueth_netdev_exit(struct prueth *prueth,
+			struct device_node *eth_node);
+int prueth_get_cores(struct prueth *prueth, int slice);
+void prueth_put_cores(struct prueth *prueth, int slice);
+
+/* Revision specific helper */
+u64 icssg_ts_to_ns(u32 hi_sw, u32 hi, u32 lo, u32 cycle_time_ns);
+
 #endif /* __NET_TI_ICSSG_PRUETH_H */
-- 
2.43.2



From diogo.ivo at siemens.com  Wed Feb 21 07:24:16 2024
From: diogo.ivo at siemens.com (Diogo Ivo)
Date: Wed, 21 Feb 2024 15:24:16 +0000
Subject: [PATCH net-next v3 10/10] net: ti: icssg-prueth: Add ICSSG Ethernet driver for AM65x SR1.0 platforms
In-Reply-To: <20240221152421.112324-1-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
Message-ID: <20240221152421.112324-11-diogo.ivo@siemens.com>

Add the PRUeth driver for the ICSSG subsystem found in AM65x SR1.0 devices.
The main differences that set SR1.0 and SR2.0 apart are the missing TXPRU
core in SR1.0, two extra DMA channels for management purposes and different
firmware that needs to be configured accordingly.

Based on the work of Roger Quadros, Vignesh Raghavendra and
Grygorii Strashko in TI's 5.10 SDK [1].

[1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y

Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
Changes in v3:
 - Remove full duplex check in icssg_config_set_speed_sr1(),
   allowing the firmware to be informed of half duplex operation.
   This eliminates the need to unconditionally remove half duplex
   modes from being advertised.
 - Remove call to icssg_config_half_duplex() in emac_adjust_link_sr1()
   as for SR1.0 icssg_config_sr1() already provides a rand_seed.

 drivers/net/ethernet/ti/Kconfig               |   15 +
 drivers/net/ethernet/ti/Makefile              |    8 +
 .../net/ethernet/ti/icssg/icssg_prueth_sr1.c  | 1171 +++++++++++++++++
 3 files changed, 1194 insertions(+)
 create mode 100644 drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c

diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index 1530d13984d4..deed1fc33e40 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -198,6 +198,21 @@ config TI_ICSSG_PRUETH
 	  to support the Ethernet operation. Currently, it supports Ethernet
 	  with 1G and 100M link speed.
 
+config TI_ICSSG_PRUETH_SR1
+	tristate "TI Gigabit PRU SR1.0 Ethernet driver"
+	select PHYLIB
+	select TI_ICSS_IEP
+	select TI_K3_CPPI_DESC_POOL
+	depends on PRU_REMOTEPROC
+	depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
+	help
+	  Support dual Gigabit Ethernet ports over the ICSSG PRU Subsystem.
+	  This subsystem is available on the AM65 SR1.0 platform.
+
+	  This driver requires firmware binaries which will run on the PRUs
+	  to support the Ethernet operation. Currently, it supports Ethernet
+	  with 1G, 100M and 10M link speed.
+
 config TI_ICSS_IEP
 	tristate "TI PRU ICSS IEP driver"
 	depends on PTP_1588_CLOCK_OPTIONAL
diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile
index 4876f20aa495..6e086b4c0384 100644
--- a/drivers/net/ethernet/ti/Makefile
+++ b/drivers/net/ethernet/ti/Makefile
@@ -40,4 +40,12 @@ icssg-prueth-y := icssg/icssg_prueth.o \
 		  icssg/icssg_mii_cfg.o \
 		  icssg/icssg_stats.o \
 		  icssg/icssg_ethtool.o
+obj-$(CONFIG_TI_ICSSG_PRUETH_SR1) += icssg-prueth-sr1.o
+icssg-prueth-sr1-y := icssg/icssg_prueth_sr1.o \
+		      icssg/icssg_common.o \
+		      icssg/icssg_classifier.o \
+		      icssg/icssg_config.o \
+		      icssg/icssg_mii_cfg.o \
+		      icssg/icssg_stats.o \
+		      icssg/icssg_ethtool.o
 obj-$(CONFIG_TI_ICSS_IEP) += icssg/icss_iep.o
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c
new file mode 100644
index 000000000000..0d552ca7d39e
--- /dev/null
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c
@@ -0,0 +1,1171 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* Texas Instruments ICSSG SR1.0 Ethernet Driver
+ *
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (c) Siemens AG, 2024
+ *
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/genalloc.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/phy.h>
+#include <linux/remoteproc/pruss.h>
+#include <linux/pruss_driver.h>
+
+#include "icssg_prueth.h"
+#include "icssg_mii_rt.h"
+#include "../k3-cppi-desc-pool.h"
+
+#define PRUETH_MODULE_DESCRIPTION "PRUSS ICSSG SR1.0 Ethernet driver"
+
+/* SR1: Set buffer sizes for the pools. There are 8 internal queues
+ * implemented in firmware, but only 4 tx channels/threads in the Egress
+ * direction to firmware. Need a high priority queue for management
+ * messages since they shouldn't be blocked even during high traffic
+ * situation. So use Q0-Q2 as data queues and Q3 as management queue
+ * in the max case. However for ease of configuration, use the max
+ * data queue + 1 for management message if we are not using max
+ * case.
+ *
+ * Allocate 4 MTU buffers per data queue.  Firmware requires
+ * pool sizes to be set for internal queues. Set the upper 5 queue
+ * pool size to min size of 128 bytes since there are only 3 tx
+ * data channels and management queue requires only minimum buffer.
+ * i.e lower queues are used by driver and highest priority queue
+ * from that is used for management message.
+ */
+
+static int emac_egress_buf_pool_size[] = {
+	PRUETH_EMAC_BUF_POOL_SIZE_SR1, PRUETH_EMAC_BUF_POOL_SIZE_SR1,
+	PRUETH_EMAC_BUF_POOL_SIZE_SR1, PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1,
+	PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1, PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1,
+	PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1, PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1
+};
+
+static void icssg_config_sr1(struct prueth *prueth, struct prueth_emac *emac,
+			     int slice)
+{
+	struct icssg_sr1_config config;
+	void __iomem *va;
+	int i, index;
+
+	memset(&config, 0, sizeof(config));
+	config.addr_lo = cpu_to_le32(lower_32_bits(prueth->msmcram.pa));
+	config.addr_hi = cpu_to_le32(upper_32_bits(prueth->msmcram.pa));
+	config.num_tx_threads = 0;
+	config.rx_flow_id = emac->rx_flow_id_base; /* flow id for host port */
+	config.rx_mgr_flow_id = emac->rx_mgm_flow_id_base; /* for mgm ch */
+	config.rand_seed = get_random_u32();
+
+	for (i = PRUETH_EMAC_BUF_POOL_START_SR1; i < PRUETH_NUM_BUF_POOLS_SR1; i++) {
+		index =  i - PRUETH_EMAC_BUF_POOL_START_SR1;
+		config.tx_buf_sz[i] = cpu_to_le32(emac_egress_buf_pool_size[index]);
+	}
+
+	va = prueth->shram.va + slice * ICSSG_CONFIG_OFFSET_SLICE1;
+	memcpy_toio(va, &config, sizeof(config));
+
+	emac->speed = SPEED_1000;
+	emac->duplex = DUPLEX_FULL;
+}
+
+static int emac_send_command_sr1(struct prueth_emac *emac, u32 cmd)
+{
+	dma_addr_t desc_dma, buf_dma;
+	struct prueth_tx_chn *tx_chn;
+	struct cppi5_host_desc_t *first_desc;
+	u32 *data = emac->cmd_data;
+	u32 pkt_len = sizeof(emac->cmd_data);
+	void **swdata;
+	int ret = 0;
+	u32 *epib;
+
+	netdev_dbg(emac->ndev, "Sending cmd %x\n", cmd);
+
+	/* only one command at a time allowed to firmware */
+	mutex_lock(&emac->cmd_lock);
+	data[0] = cpu_to_le32(cmd);
+
+	/* highest priority channel for management messages */
+	tx_chn = &emac->tx_chns[emac->tx_ch_num - 1];
+
+	/* Map the linear buffer */
+	buf_dma = dma_map_single(tx_chn->dma_dev, data, pkt_len, DMA_TO_DEVICE);
+	if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) {
+		netdev_err(emac->ndev, "cmd %x: failed to map cmd buffer\n", cmd);
+		ret = -EINVAL;
+		goto err_unlock;
+	}
+
+	first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool);
+	if (!first_desc) {
+		netdev_err(emac->ndev, "cmd %x: failed to allocate descriptor\n", cmd);
+		dma_unmap_single(tx_chn->dma_dev, buf_dma, pkt_len, DMA_TO_DEVICE);
+		ret = -ENOMEM;
+		goto err_unlock;
+	}
+
+	cppi5_hdesc_init(first_desc, CPPI5_INFO0_HDESC_EPIB_PRESENT,
+			 PRUETH_NAV_PS_DATA_SIZE);
+	cppi5_hdesc_set_pkttype(first_desc, PRUETH_PKT_TYPE_CMD);
+	epib = first_desc->epib;
+	epib[0] = 0;
+	epib[1] = 0;
+
+	cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len);
+	swdata = cppi5_hdesc_get_swdata(first_desc);
+	*swdata = data;
+
+	cppi5_hdesc_set_pktlen(first_desc, pkt_len);
+	desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc);
+
+	/* send command */
+	reinit_completion(&emac->cmd_complete);
+	ret = k3_udma_glue_push_tx_chn(tx_chn->tx_chn, first_desc, desc_dma);
+	if (ret) {
+		netdev_err(emac->ndev, "cmd %x: push failed: %d\n", cmd, ret);
+		goto free_desc;
+	}
+	ret = wait_for_completion_timeout(&emac->cmd_complete, msecs_to_jiffies(100));
+	if (!ret)
+		netdev_err(emac->ndev, "cmd %x: completion timeout\n", cmd);
+
+	mutex_unlock(&emac->cmd_lock);
+
+	return ret;
+free_desc:
+	prueth_xmit_free(tx_chn, first_desc);
+err_unlock:
+	mutex_unlock(&emac->cmd_lock);
+
+	return ret;
+}
+
+static void icssg_config_set_speed_sr1(struct prueth_emac *emac)
+{
+	u32 cmd = ICSSG_PSTATE_SPEED_DUPLEX_CMD, val;
+	struct prueth *prueth = emac->prueth;
+	int slice = prueth_emac_slice(emac);
+
+	val = icssg_rgmii_get_speed(prueth->miig_rt, slice);
+	/* firmware expects speed settings in bit 2-1 */
+	val <<= 1;
+	cmd |= val;
+
+	val = icssg_rgmii_get_fullduplex(prueth->miig_rt, slice);
+	/* firmware expects full duplex settings in bit 3 */
+	val <<= 3;
+	cmd |= val;
+
+	emac_send_command_sr1(emac, cmd);
+}
+
+/* called back by PHY layer if there is change in link state of hw port*/
+static void emac_adjust_link_sr1(struct net_device *ndev)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct phy_device *phydev = ndev->phydev;
+	struct prueth *prueth = emac->prueth;
+	bool new_state = false;
+	unsigned long flags;
+
+	if (phydev->link) {
+		/* check the mode of operation - full/half duplex */
+		if (phydev->duplex != emac->duplex) {
+			new_state = true;
+			emac->duplex = phydev->duplex;
+		}
+		if (phydev->speed != emac->speed) {
+			new_state = true;
+			emac->speed = phydev->speed;
+		}
+		if (!emac->link) {
+			new_state = true;
+			emac->link = 1;
+		}
+	} else if (emac->link) {
+		new_state = true;
+		emac->link = 0;
+
+		/* f/w should support 100 & 1000 */
+		emac->speed = SPEED_1000;
+
+		/* half duplex may not be supported by f/w */
+		emac->duplex = DUPLEX_FULL;
+	}
+
+	if (new_state) {
+		phy_print_status(phydev);
+
+		/* update RGMII and MII configuration based on PHY negotiated
+		 * values
+		 */
+		if (emac->link) {
+			/* Set the RGMII cfg for gig en and full duplex */
+			icssg_update_rgmii_cfg(prueth->miig_rt, emac);
+
+			/* update the Tx IPG based on 100M/1G speed */
+			spin_lock_irqsave(&emac->lock, flags);
+			icssg_config_ipg(emac);
+			spin_unlock_irqrestore(&emac->lock, flags);
+			icssg_config_set_speed_sr1(emac);
+		}
+	}
+
+	if (emac->link) {
+		/* reactivate the transmit queue */
+		netif_tx_wake_all_queues(ndev);
+	} else {
+		netif_tx_stop_all_queues(ndev);
+		prueth_cleanup_tx_ts(emac);
+	}
+}
+
+static int emac_phy_connect(struct prueth_emac *emac)
+{
+	struct prueth *prueth = emac->prueth;
+	struct net_device *ndev = emac->ndev;
+	/* connect PHY */
+	ndev->phydev = of_phy_connect(emac->ndev, emac->phy_node,
+				      &emac_adjust_link_sr1, 0,
+				      emac->phy_if);
+	if (!ndev->phydev) {
+		dev_err(prueth->dev, "couldn't connect to phy %s\n",
+			emac->phy_node->full_name);
+		return -ENODEV;
+	}
+
+	if (!emac->half_duplex) {
+		dev_dbg(prueth->dev, "half duplex mode is not supported\n");
+		phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
+		phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
+	}
+
+	/* remove unsupported modes */
+	phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
+	phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_Pause_BIT);
+	phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT);
+
+	if (emac->phy_if == PHY_INTERFACE_MODE_MII)
+		phy_set_max_speed(ndev->phydev, SPEED_100);
+
+	return 0;
+}
+
+/* get one packet from requested flow_id
+ *
+ * Returns skb pointer if packet found else NULL
+ * Caller must free the returned skb.
+ */
+static struct sk_buff *prueth_process_rx_mgm(struct prueth_emac *emac,
+					     u32 flow_id)
+{
+	struct prueth_rx_chn *rx_chn = &emac->rx_mgm_chn;
+	struct net_device *ndev = emac->ndev;
+	struct cppi5_host_desc_t *desc_rx;
+	struct sk_buff *skb, *new_skb;
+	dma_addr_t desc_dma, buf_dma;
+	u32 buf_dma_len, pkt_len;
+	void **swdata;
+	int ret;
+
+	ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma);
+	if (ret) {
+		if (ret != -ENODATA)
+			netdev_err(ndev, "rx mgm pop: failed: %d\n", ret);
+		return NULL;
+	}
+
+	if (cppi5_desc_is_tdcm(desc_dma)) /* Teardown */
+		return NULL;
+
+	desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma);
+
+	/* Fix FW bug about incorrect PSDATA size */
+	if (cppi5_hdesc_get_psdata_size(desc_rx) != PRUETH_NAV_PS_DATA_SIZE) {
+		cppi5_hdesc_update_psdata_size(desc_rx,
+					       PRUETH_NAV_PS_DATA_SIZE);
+	}
+
+	swdata = cppi5_hdesc_get_swdata(desc_rx);
+	skb = *swdata;
+	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
+	pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
+
+	dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE);
+	k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx);
+
+	new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE);
+	/* if allocation fails we drop the packet but push the
+	 * descriptor back to the ring with old skb to prevent a stall
+	 */
+	if (!new_skb) {
+		netdev_err(ndev,
+			   "skb alloc failed, dropped mgm pkt from flow %d\n",
+			   flow_id);
+		new_skb = skb;
+		skb = NULL;	/* return NULL */
+	} else {
+		/* return the filled skb */
+		skb_put(skb, pkt_len);
+	}
+
+	/* queue another DMA */
+	ret = prueth_dma_rx_push(emac, new_skb, &emac->rx_mgm_chn);
+	if (WARN_ON(ret < 0))
+		dev_kfree_skb_any(new_skb);
+
+	return skb;
+}
+
+static void prueth_tx_ts_sr1(struct prueth_emac *emac,
+			     struct emac_tx_ts_response_sr1 *tsr)
+{
+	u64 ns;
+	struct skb_shared_hwtstamps ssh;
+	struct sk_buff *skb;
+
+	ns = (u64)tsr->hi_ts << 32 | tsr->lo_ts;
+
+	if (tsr->cookie >= PRUETH_MAX_TX_TS_REQUESTS) {
+		netdev_dbg(emac->ndev, "Invalid TX TS cookie 0x%x\n",
+			   tsr->cookie);
+		return;
+	}
+
+	skb = emac->tx_ts_skb[tsr->cookie];
+	emac->tx_ts_skb[tsr->cookie] = NULL;	/* free slot */
+
+	memset(&ssh, 0, sizeof(ssh));
+	ssh.hwtstamp = ns_to_ktime(ns);
+
+	skb_tstamp_tx(skb, &ssh);
+	dev_consume_skb_any(skb);
+}
+
+static irqreturn_t prueth_rx_mgm_ts_thread_sr1(int irq, void *dev_id)
+{
+	struct prueth_emac *emac = dev_id;
+	struct sk_buff *skb;
+
+	skb = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_TIMESTAMP);
+	if (!skb)
+		return IRQ_NONE;
+
+	prueth_tx_ts_sr1(emac, (void *)skb->data);
+	dev_kfree_skb_any(skb);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t prueth_rx_mgm_rsp_thread(int irq, void *dev_id)
+{
+	struct prueth_emac *emac = dev_id;
+	struct sk_buff *skb;
+	u32 rsp;
+
+	skb = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_RESPONSE);
+	if (!skb)
+		return IRQ_NONE;
+
+	/* Process command response */
+	rsp = le32_to_cpu(*(u32 *)skb->data) & 0xffff0000;
+	if (rsp == ICSSG_SHUTDOWN_CMD) {
+		netdev_dbg(emac->ndev, "f/w Shutdown cmd resp %x\n", rsp);
+		complete(&emac->cmd_complete);
+	} else if (rsp == ICSSG_PSTATE_SPEED_DUPLEX_CMD) {
+		netdev_dbg(emac->ndev, "f/w Speed/Duplex cmd rsp %x\n", rsp);
+		complete(&emac->cmd_complete);
+	}
+
+	dev_kfree_skb_any(skb);
+
+	return IRQ_HANDLED;
+}
+
+static struct icssg_firmwares icssg_sr1_emac_firmwares[] = {
+	{
+		.pru = "ti-pruss/am65x-pru0-prueth-fw.elf",
+		.rtu = "ti-pruss/am65x-rtu0-prueth-fw.elf",
+	},
+	{
+		.pru = "ti-pruss/am65x-pru1-prueth-fw.elf",
+		.rtu = "ti-pruss/am65x-rtu1-prueth-fw.elf",
+	}
+};
+
+static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
+{
+	struct icssg_firmwares *firmwares;
+	struct device *dev = prueth->dev;
+	int slice, ret;
+
+	firmwares = icssg_sr1_emac_firmwares;
+
+	slice = prueth_emac_slice(emac);
+	if (slice < 0) {
+		netdev_err(emac->ndev, "invalid port\n");
+		return -EINVAL;
+	}
+
+	icssg_config_sr1(prueth, emac, slice);
+
+	ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru);
+	ret = rproc_boot(prueth->pru[slice]);
+	if (ret) {
+		dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret);
+		return -EINVAL;
+	}
+
+	ret = rproc_set_firmware(prueth->rtu[slice], firmwares[slice].rtu);
+	ret = rproc_boot(prueth->rtu[slice]);
+	if (ret) {
+		dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret);
+		goto halt_pru;
+	}
+
+	emac->fw_running = 1;
+	return 0;
+
+halt_pru:
+	rproc_shutdown(prueth->pru[slice]);
+
+	return ret;
+}
+
+/**
+ * emac_ndo_open - EMAC device open
+ * @ndev: network adapter device
+ *
+ * Called when system wants to start the interface.
+ *
+ * Return: 0 for a successful open, or appropriate error code
+ */
+static int emac_ndo_open(struct net_device *ndev)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	int ret, i, num_data_chn = emac->tx_ch_num - 1;
+	struct prueth *prueth = emac->prueth;
+	int slice = prueth_emac_slice(emac);
+	struct device *dev = prueth->dev;
+	int max_rx_flows;
+	int rx_flow;
+
+	/* clear SMEM and MSMC settings for all slices */
+	if (!prueth->emacs_initialized) {
+		memset_io(prueth->msmcram.va, 0, prueth->msmcram.size);
+		memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
+	}
+
+	/* set h/w MAC as user might have re-configured */
+	ether_addr_copy(emac->mac_addr, ndev->dev_addr);
+
+	icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
+
+	icssg_class_default(prueth->miig_rt, slice, 0, true);
+
+	/* Notify the stack of the actual queue counts. */
+	ret = netif_set_real_num_tx_queues(ndev, num_data_chn);
+	if (ret) {
+		dev_err(dev, "cannot set real number of tx queues\n");
+		return ret;
+	}
+
+	init_completion(&emac->cmd_complete);
+	ret = prueth_init_tx_chns(emac);
+	if (ret) {
+		dev_err(dev, "failed to init tx channel: %d\n", ret);
+		return ret;
+	}
+
+	max_rx_flows = PRUETH_MAX_RX_FLOWS_SR1;
+	ret = prueth_init_rx_chns(emac, &emac->rx_chns, "rx",
+				  max_rx_flows, PRUETH_MAX_RX_DESC);
+	if (ret) {
+		dev_err(dev, "failed to init rx channel: %d\n", ret);
+		goto cleanup_tx;
+	}
+
+	ret = prueth_init_rx_chns(emac, &emac->rx_mgm_chn, "rxmgm",
+				  PRUETH_MAX_RX_MGM_FLOWS,
+				  PRUETH_MAX_RX_MGM_DESC);
+	if (ret) {
+		dev_err(dev, "failed to init rx mgmt channel: %d\n",
+			ret);
+		goto cleanup_rx;
+	}
+
+	ret = prueth_ndev_add_tx_napi(emac);
+	if (ret)
+		goto cleanup_rx_mgm;
+
+	/* we use only the highest priority flow for now i.e. @irq[3] */
+	rx_flow = PRUETH_RX_FLOW_DATA_SR1;
+	ret = request_irq(emac->rx_chns.irq[rx_flow], prueth_rx_irq,
+			  IRQF_TRIGGER_HIGH, dev_name(dev), emac);
+	if (ret) {
+		dev_err(dev, "unable to request RX IRQ\n");
+		goto cleanup_napi;
+	}
+
+	ret = request_threaded_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_RESPONSE],
+				   NULL, prueth_rx_mgm_rsp_thread,
+				   IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
+				   dev_name(dev), emac);
+	if (ret) {
+		dev_err(dev, "unable to request RX Management RSP IRQ\n");
+		goto free_rx_irq;
+	}
+
+	ret = request_threaded_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP],
+				   NULL, prueth_rx_mgm_ts_thread_sr1,
+				   IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
+				   dev_name(dev), emac);
+	if (ret) {
+		dev_err(dev, "unable to request RX Management TS IRQ\n");
+		goto free_rx_mgm_rsp_irq;
+	}
+
+	/* reset and start PRU firmware */
+	ret = prueth_emac_start(prueth, emac);
+	if (ret)
+		goto free_rx_mgmt_ts_irq;
+
+	icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
+
+	/* Prepare RX */
+	ret = prueth_prepare_rx_chan(emac, &emac->rx_chns, PRUETH_MAX_PKT_SIZE);
+	if (ret)
+		goto stop;
+
+	ret = prueth_prepare_rx_chan(emac, &emac->rx_mgm_chn, 64);
+	if (ret)
+		goto reset_rx_chn;
+
+	ret = k3_udma_glue_enable_rx_chn(emac->rx_mgm_chn.rx_chn);
+	if (ret)
+		goto reset_rx_chn;
+
+	ret = k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn);
+	if (ret)
+		goto reset_rx_mgm_chn;
+
+	for (i = 0; i < emac->tx_ch_num; i++) {
+		ret = k3_udma_glue_enable_tx_chn(emac->tx_chns[i].tx_chn);
+		if (ret)
+			goto reset_tx_chan;
+	}
+
+	/* Enable NAPI in Tx and Rx direction */
+	for (i = 0; i < emac->tx_ch_num; i++)
+		napi_enable(&emac->tx_chns[i].napi_tx);
+	napi_enable(&emac->napi_rx);
+
+	/* start PHY */
+	phy_start(ndev->phydev);
+
+	prueth->emacs_initialized++;
+
+	queue_work(system_long_wq, &emac->stats_work.work);
+
+	return 0;
+
+reset_tx_chan:
+	/* Since interface is not yet up, there is wouldn't be
+	 * any SKB for completion. So set false to free_skb
+	 */
+	prueth_reset_tx_chan(emac, i, false);
+reset_rx_mgm_chn:
+	prueth_reset_rx_chan(&emac->rx_mgm_chn,
+			     PRUETH_MAX_RX_MGM_FLOWS, true);
+reset_rx_chn:
+	prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, false);
+stop:
+	prueth_emac_stop(emac);
+free_rx_mgmt_ts_irq:
+	free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP],
+		 emac);
+free_rx_mgm_rsp_irq:
+	free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_RESPONSE],
+		 emac);
+free_rx_irq:
+	free_irq(emac->rx_chns.irq[rx_flow], emac);
+cleanup_napi:
+	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
+cleanup_rx_mgm:
+	prueth_cleanup_rx_chns(emac, &emac->rx_mgm_chn,
+			       PRUETH_MAX_RX_MGM_FLOWS);
+cleanup_rx:
+	prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows);
+cleanup_tx:
+	prueth_cleanup_tx_chns(emac);
+
+	return ret;
+}
+
+/**
+ * emac_ndo_stop - EMAC device stop
+ * @ndev: network adapter device
+ *
+ * Called when system wants to stop or down the interface.
+ *
+ * Return: Always 0 (Success)
+ */
+static int emac_ndo_stop(struct net_device *ndev)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct prueth *prueth = emac->prueth;
+	int rx_flow = PRUETH_RX_FLOW_DATA_SR1;
+	int max_rx_flows;
+	int ret, i;
+
+	/* inform the upper layers. */
+	netif_tx_stop_all_queues(ndev);
+
+	/* block packets from wire */
+	if (ndev->phydev)
+		phy_stop(ndev->phydev);
+
+	icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
+
+	emac_send_command_sr1(emac, ICSSG_SHUTDOWN_CMD);
+
+	atomic_set(&emac->tdown_cnt, emac->tx_ch_num);
+	/* ensure new tdown_cnt value is visible */
+	smp_mb__after_atomic();
+	/* tear down and disable UDMA channels */
+	reinit_completion(&emac->tdown_complete);
+	for (i = 0; i < emac->tx_ch_num; i++)
+		k3_udma_glue_tdown_tx_chn(emac->tx_chns[i].tx_chn, false);
+
+	ret = wait_for_completion_timeout(&emac->tdown_complete,
+					  msecs_to_jiffies(1000));
+	if (!ret)
+		netdev_err(ndev, "tx teardown timeout\n");
+
+	prueth_reset_tx_chan(emac, emac->tx_ch_num, true);
+	for (i = 0; i < emac->tx_ch_num; i++)
+		napi_disable(&emac->tx_chns[i].napi_tx);
+
+	max_rx_flows = PRUETH_MAX_RX_FLOWS_SR1;
+	k3_udma_glue_tdown_rx_chn(emac->rx_chns.rx_chn, true);
+
+	prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, true);
+	/* Teardown RX MGM channel */
+	k3_udma_glue_tdown_rx_chn(emac->rx_mgm_chn.rx_chn, true);
+	prueth_reset_rx_chan(&emac->rx_mgm_chn,
+			     PRUETH_MAX_RX_MGM_FLOWS, true);
+
+	napi_disable(&emac->napi_rx);
+
+	/* Destroying the queued work in ndo_stop() */
+	cancel_delayed_work_sync(&emac->stats_work);
+
+	/* stop PRUs */
+	prueth_emac_stop(emac);
+
+	free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP], emac);
+	free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_RESPONSE], emac);
+	free_irq(emac->rx_chns.irq[rx_flow], emac);
+	prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
+	prueth_cleanup_tx_chns(emac);
+
+	prueth_cleanup_rx_chns(emac, &emac->rx_mgm_chn, PRUETH_MAX_RX_MGM_FLOWS);
+	prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows);
+
+	prueth->emacs_initialized--;
+
+	return 0;
+}
+
+static void emac_ndo_set_rx_mode_sr1(struct net_device *ndev)
+{
+	struct prueth_emac *emac = netdev_priv(ndev);
+	struct prueth *prueth = emac->prueth;
+	int slice = prueth_emac_slice(emac);
+	bool promisc = ndev->flags & IFF_PROMISC;
+	bool allmulti = ndev->flags & IFF_ALLMULTI;
+
+	if (promisc) {
+		icssg_class_promiscuous_sr1(prueth->miig_rt, slice);
+		return;
+	}
+
+	if (allmulti) {
+		icssg_class_default(prueth->miig_rt, slice, 1, true);
+		return;
+	}
+
+	icssg_class_default(prueth->miig_rt, slice, 0, true);
+	if (!netdev_mc_empty(ndev)) {
+		/* program multicast address list into Classifier */
+		icssg_class_add_mcast_sr1(prueth->miig_rt, slice, ndev);
+	}
+}
+
+static const struct net_device_ops emac_netdev_ops = {
+	.ndo_open = emac_ndo_open,
+	.ndo_stop = emac_ndo_stop,
+	.ndo_start_xmit = emac_ndo_start_xmit,
+	.ndo_set_mac_address = eth_mac_addr,
+	.ndo_validate_addr = eth_validate_addr,
+	.ndo_tx_timeout = emac_ndo_tx_timeout,
+	.ndo_set_rx_mode = emac_ndo_set_rx_mode_sr1,
+	.ndo_eth_ioctl = emac_ndo_ioctl,
+	.ndo_get_stats64 = emac_ndo_get_stats64,
+	.ndo_get_phys_port_name = emac_ndo_get_phys_port_name,
+};
+
+static int prueth_netdev_init(struct prueth *prueth,
+			      struct device_node *eth_node)
+{
+	int ret, num_tx_chn = PRUETH_MAX_TX_QUEUES - 1;
+	struct prueth_emac *emac;
+	struct net_device *ndev;
+	enum prueth_port port;
+	enum prueth_mac mac;
+
+	port = prueth_node_port(eth_node);
+	if (port == PRUETH_PORT_INVALID)
+		return -EINVAL;
+
+	mac = prueth_node_mac(eth_node);
+	if (mac == PRUETH_MAC_INVALID)
+		return -EINVAL;
+
+	ndev = alloc_etherdev_mq(sizeof(*emac), num_tx_chn);
+	if (!ndev)
+		return -ENOMEM;
+
+	emac = netdev_priv(ndev);
+	emac->is_sr1 = 1;
+	emac->prueth = prueth;
+	emac->ndev = ndev;
+	emac->port_id = port;
+	emac->cmd_wq = create_singlethread_workqueue("icssg_cmd_wq");
+	if (!emac->cmd_wq) {
+		ret = -ENOMEM;
+		goto free_ndev;
+	}
+
+	INIT_DELAYED_WORK(&emac->stats_work, emac_stats_work_handler);
+
+	ret = pruss_request_mem_region(prueth->pruss,
+				       port == PRUETH_PORT_MII0 ?
+				       PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1,
+				       &emac->dram);
+	if (ret) {
+		dev_err(prueth->dev, "unable to get DRAM: %d\n", ret);
+		ret = -ENOMEM;
+		goto free_wq;
+	}
+
+	/* SR1.0 uses a dedicated high priority channel
+	 * to send commands to the firmware
+	 */
+	emac->tx_ch_num = 2;
+
+	SET_NETDEV_DEV(ndev, prueth->dev);
+	spin_lock_init(&emac->lock);
+	mutex_init(&emac->cmd_lock);
+
+	emac->phy_node = of_parse_phandle(eth_node, "phy-handle", 0);
+	if (!emac->phy_node && !of_phy_is_fixed_link(eth_node)) {
+		dev_err(prueth->dev, "couldn't find phy-handle\n");
+		ret = -ENODEV;
+		goto free;
+	} else if (of_phy_is_fixed_link(eth_node)) {
+		ret = of_phy_register_fixed_link(eth_node);
+		if (ret) {
+			ret = dev_err_probe(prueth->dev, ret,
+					    "failed to register fixed-link phy\n");
+			goto free;
+		}
+
+		emac->phy_node = eth_node;
+	}
+
+	ret = of_get_phy_mode(eth_node, &emac->phy_if);
+	if (ret) {
+		dev_err(prueth->dev, "could not get phy-mode property\n");
+		goto free;
+	}
+
+	if (emac->phy_if != PHY_INTERFACE_MODE_MII &&
+	    !phy_interface_mode_is_rgmii(emac->phy_if)) {
+		dev_err(prueth->dev, "PHY mode unsupported %s\n", phy_modes(emac->phy_if));
+		ret = -EINVAL;
+		goto free;
+	}
+
+	/* AM65 SR2.0 has TX Internal delay always enabled by hardware
+	 * and it is not possible to disable TX Internal delay. The below
+	 * switch case block describes how we handle different phy modes
+	 * based on hardware restriction.
+	 */
+	switch (emac->phy_if) {
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		emac->phy_if = PHY_INTERFACE_MODE_RGMII_RXID;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		emac->phy_if = PHY_INTERFACE_MODE_RGMII;
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		dev_err(prueth->dev, "RGMII mode without TX delay is not supported");
+		ret = -EINVAL;
+		goto free;
+	default:
+		break;
+	}
+
+	/* get mac address from DT and set private and netdev addr */
+	ret = of_get_ethdev_address(eth_node, ndev);
+	if (!is_valid_ether_addr(ndev->dev_addr)) {
+		eth_hw_addr_random(ndev);
+		dev_warn(prueth->dev, "port %d: using random MAC addr: %pM\n",
+			 port, ndev->dev_addr);
+	}
+	ether_addr_copy(emac->mac_addr, ndev->dev_addr);
+
+	ndev->min_mtu = PRUETH_MIN_PKT_SIZE;
+	ndev->max_mtu = PRUETH_MAX_MTU;
+	ndev->netdev_ops = &emac_netdev_ops;
+	ndev->ethtool_ops = &icssg_ethtool_ops;
+	ndev->hw_features = NETIF_F_SG;
+	ndev->features = ndev->hw_features;
+
+	netif_napi_add(ndev, &emac->napi_rx, emac_napi_rx_poll);
+	prueth->emac[mac] = emac;
+
+	return 0;
+
+free:
+	pruss_release_mem_region(prueth->pruss, &emac->dram);
+free_wq:
+	destroy_workqueue(emac->cmd_wq);
+free_ndev:
+	emac->ndev = NULL;
+	prueth->emac[mac] = NULL;
+	free_netdev(ndev);
+
+	return ret;
+}
+
+static int prueth_probe(struct platform_device *pdev)
+{
+	struct device_node *eth_node, *eth_ports_node;
+	struct device_node  *eth0_node = NULL;
+	struct device_node  *eth1_node = NULL;
+	struct device *dev = &pdev->dev;
+	struct device_node *np;
+	struct prueth *prueth;
+	struct pruss *pruss;
+	u32 msmc_ram_size;
+	int i, ret;
+
+	np = dev->of_node;
+
+	prueth = devm_kzalloc(dev, sizeof(*prueth), GFP_KERNEL);
+	if (!prueth)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, prueth);
+	prueth->pdev = pdev;
+	prueth->pdata = *(const struct prueth_pdata *)device_get_match_data(dev);
+
+	prueth->dev = dev;
+	eth_ports_node = of_get_child_by_name(np, "ethernet-ports");
+	if (!eth_ports_node)
+		return -ENOENT;
+
+	for_each_child_of_node(eth_ports_node, eth_node) {
+		u32 reg;
+
+		if (strcmp(eth_node->name, "port"))
+			continue;
+		ret = of_property_read_u32(eth_node, "reg", &reg);
+		if (ret < 0) {
+			dev_err(dev, "%pOF error reading port_id %d\n",
+				eth_node, ret);
+		}
+
+		of_node_get(eth_node);
+
+		if (reg == 0) {
+			eth0_node = eth_node;
+			if (!of_device_is_available(eth0_node)) {
+				of_node_put(eth0_node);
+				eth0_node = NULL;
+			}
+		} else if (reg == 1) {
+			eth1_node = eth_node;
+			if (!of_device_is_available(eth1_node)) {
+				of_node_put(eth1_node);
+				eth1_node = NULL;
+			}
+		} else {
+			dev_err(dev, "port reg should be 0 or 1\n");
+		}
+	}
+
+	of_node_put(eth_ports_node);
+
+	/* At least one node must be present and available else we fail */
+	if (!eth0_node && !eth1_node) {
+		dev_err(dev, "neither port0 nor port1 node available\n");
+		return -ENODEV;
+	}
+
+	if (eth0_node == eth1_node) {
+		dev_err(dev, "port0 and port1 can't have same reg\n");
+		of_node_put(eth0_node);
+		return -ENODEV;
+	}
+
+	prueth->eth_node[PRUETH_MAC0] = eth0_node;
+	prueth->eth_node[PRUETH_MAC1] = eth1_node;
+
+	prueth->miig_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-g-rt");
+	if (IS_ERR(prueth->miig_rt)) {
+		dev_err(dev, "couldn't get ti,mii-g-rt syscon regmap\n");
+		return -ENODEV;
+	}
+
+	prueth->mii_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-rt");
+	if (IS_ERR(prueth->mii_rt)) {
+		dev_err(dev, "couldn't get ti,mii-rt syscon regmap\n");
+		return -ENODEV;
+	}
+
+	if (eth0_node) {
+		ret = prueth_get_cores(prueth, ICSS_SLICE0, true);
+		if (ret)
+			goto put_cores;
+	}
+
+	if (eth1_node) {
+		ret = prueth_get_cores(prueth, ICSS_SLICE1, true);
+		if (ret)
+			goto put_cores;
+	}
+
+	pruss = pruss_get(eth0_node ?
+			  prueth->pru[ICSS_SLICE0] : prueth->pru[ICSS_SLICE1]);
+	if (IS_ERR(pruss)) {
+		ret = PTR_ERR(pruss);
+		dev_err(dev, "unable to get pruss handle\n");
+		goto put_cores;
+	}
+
+	prueth->pruss = pruss;
+
+	ret = pruss_request_mem_region(pruss, PRUSS_MEM_SHRD_RAM2,
+				       &prueth->shram);
+	if (ret) {
+		dev_err(dev, "unable to get PRUSS SHRD RAM2: %d\n", ret);
+		goto put_pruss;
+	}
+
+	prueth->sram_pool = of_gen_pool_get(np, "sram", 0);
+	if (!prueth->sram_pool) {
+		dev_err(dev, "unable to get SRAM pool\n");
+		ret = -ENODEV;
+
+		goto put_mem;
+	}
+
+	msmc_ram_size = MSMC_RAM_SIZE_SR1;
+
+	prueth->msmcram.va = (void __iomem *)gen_pool_alloc(prueth->sram_pool,
+							    msmc_ram_size);
+
+	if (!prueth->msmcram.va) {
+		ret = -ENOMEM;
+		dev_err(dev, "unable to allocate MSMC resource\n");
+		goto put_mem;
+	}
+	prueth->msmcram.pa = gen_pool_virt_to_phys(prueth->sram_pool,
+						   (unsigned long)prueth->msmcram.va);
+	prueth->msmcram.size = msmc_ram_size;
+	memset_io(prueth->msmcram.va, 0, msmc_ram_size);
+	dev_dbg(dev, "sram: pa %llx va %p size %zx\n", prueth->msmcram.pa,
+		prueth->msmcram.va, prueth->msmcram.size);
+
+	if (eth0_node) {
+		ret = prueth_netdev_init(prueth, eth0_node);
+		if (ret) {
+			dev_err_probe(dev, ret, "netdev init %s failed\n",
+				      eth0_node->name);
+			goto free_pool;
+		}
+
+		if (of_find_property(eth0_node, "ti,half-duplex-capable", NULL))
+			prueth->emac[PRUETH_MAC0]->half_duplex = 1;
+	}
+
+	if (eth1_node) {
+		ret = prueth_netdev_init(prueth, eth1_node);
+		if (ret) {
+			dev_err_probe(dev, ret, "netdev init %s failed\n",
+				      eth1_node->name);
+			goto netdev_exit;
+		}
+
+		if (of_find_property(eth1_node, "ti,half-duplex-capable", NULL))
+			prueth->emac[PRUETH_MAC1]->half_duplex = 1;
+	}
+
+	/* register the network devices */
+	if (eth0_node) {
+		ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev);
+		if (ret) {
+			dev_err(dev, "can't register netdev for port MII0\n");
+			goto netdev_exit;
+		}
+
+		prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev;
+		emac_phy_connect(prueth->emac[PRUETH_MAC0]);
+		phy_attached_info(prueth->emac[PRUETH_MAC0]->ndev->phydev);
+	}
+
+	if (eth1_node) {
+		ret = register_netdev(prueth->emac[PRUETH_MAC1]->ndev);
+		if (ret) {
+			dev_err(dev, "can't register netdev for port MII1\n");
+			goto netdev_unregister;
+		}
+
+		prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev;
+		emac_phy_connect(prueth->emac[PRUETH_MAC1]);
+		phy_attached_info(prueth->emac[PRUETH_MAC1]->ndev->phydev);
+	}
+
+	dev_info(dev, "TI PRU SR1.0 ethernet driver initialized: %s EMAC mode\n",
+		 (!eth0_node || !eth1_node) ? "single" : "dual");
+
+	if (eth1_node)
+		of_node_put(eth1_node);
+	if (eth0_node)
+		of_node_put(eth0_node);
+
+	return 0;
+
+netdev_unregister:
+	for (i = 0; i < PRUETH_NUM_MACS; i++) {
+		if (!prueth->registered_netdevs[i])
+			continue;
+
+		if (prueth->emac[i]->ndev->phydev) {
+			phy_disconnect(prueth->emac[i]->ndev->phydev);
+			prueth->emac[i]->ndev->phydev = NULL;
+		}
+		unregister_netdev(prueth->registered_netdevs[i]);
+	}
+
+netdev_exit:
+	for (i = 0; i < PRUETH_NUM_MACS; i++) {
+		eth_node = prueth->eth_node[i];
+		if (!eth_node)
+			continue;
+
+		prueth_netdev_exit(prueth, eth_node);
+	}
+
+free_pool:
+	gen_pool_free(prueth->sram_pool,
+		      (unsigned long)prueth->msmcram.va, msmc_ram_size);
+
+put_mem:
+	pruss_release_mem_region(prueth->pruss, &prueth->shram);
+
+put_pruss:
+	pruss_put(prueth->pruss);
+
+put_cores:
+	if (eth1_node) {
+		prueth_put_cores(prueth, ICSS_SLICE1);
+		of_node_put(eth1_node);
+	}
+
+	if (eth0_node) {
+		prueth_put_cores(prueth, ICSS_SLICE0);
+		of_node_put(eth0_node);
+	}
+
+	return ret;
+}
+
+static void prueth_remove(struct platform_device *pdev)
+{
+	struct prueth *prueth = platform_get_drvdata(pdev);
+	struct device_node *eth_node;
+	int i;
+
+	for (i = 0; i < PRUETH_NUM_MACS; i++) {
+		if (!prueth->registered_netdevs[i])
+			continue;
+		phy_stop(prueth->emac[i]->ndev->phydev);
+		phy_disconnect(prueth->emac[i]->ndev->phydev);
+		prueth->emac[i]->ndev->phydev = NULL;
+		unregister_netdev(prueth->registered_netdevs[i]);
+	}
+
+	for (i = 0; i < PRUETH_NUM_MACS; i++) {
+		eth_node = prueth->eth_node[i];
+		if (!eth_node)
+			continue;
+
+		prueth_netdev_exit(prueth, eth_node);
+	}
+
+	gen_pool_free(prueth->sram_pool,
+		      (unsigned long)prueth->msmcram.va,
+		      MSMC_RAM_SIZE_SR1);
+
+	pruss_release_mem_region(prueth->pruss, &prueth->shram);
+
+	pruss_put(prueth->pruss);
+
+	if (prueth->eth_node[PRUETH_MAC1])
+		prueth_put_cores(prueth, ICSS_SLICE1);
+
+	if (prueth->eth_node[PRUETH_MAC0])
+		prueth_put_cores(prueth, ICSS_SLICE0);
+}
+
+static const struct prueth_pdata am654_sr1_icssg_pdata = {
+	.fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE,
+};
+
+static const struct of_device_id prueth_dt_match[] = {
+	{ .compatible = "ti,am654-sr1-icssg-prueth", .data = &am654_sr1_icssg_pdata },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, prueth_dt_match);
+
+static struct platform_driver prueth_driver = {
+	.probe = prueth_probe,
+	.remove_new = prueth_remove,
+	.driver = {
+		.name = "icssg-prueth-sr1",
+		.of_match_table = prueth_dt_match,
+		.pm = &prueth_dev_pm_ops,
+	},
+};
+module_platform_driver(prueth_driver);
+
+MODULE_AUTHOR("Roger Quadros <rogerq at ti.com>");
+MODULE_AUTHOR("Md Danish Anwar <danishanwar at ti.com>");
+MODULE_AUTHOR("Diogo Ivo <diogo.ivo at siemens.com>");
+MODULE_DESCRIPTION(PRUETH_MODULE_DESCRIPTION);
+MODULE_LICENSE("GPL");
-- 
2.43.2



From mripard at redhat.com  Wed Feb 21 07:24:51 2024
From: mripard at redhat.com (Maxime Ripard)
Date: Wed, 21 Feb 2024 16:24:51 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
Message-ID: <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>

On Wed, Feb 21, 2024 at 04:10:12PM +0100, Krzysztof Kozlowski wrote:
> On 21/02/2024 15:48, Maxime Ripard wrote:
> > On Wed, Feb 21, 2024 at 03:22:38PM +0100, Krzysztof Kozlowski wrote:
> >> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
> >>> These options are needed by some Linux distributions (e.g: Fedora), so
> >>
> >> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
> >> use on my arm64 boards, does not have any problem.
> > 
> > Is it relevant in any way?
> 
> Yes, because it is justification why we are doing it. Each commit is
> supposed to explain "why" and the explanation here is not enough.

There's a why though: it makes Fedora boot. It might not be enough for
you, but that's a different story. So, if it's not enough, please state
exactly what you expect from that patch description so Javier can
provide it.

> > I'm sure Debian can boot without MEMORY_HOTREMOVE, or BRIDGE, or
> > NUMA_BALANCING, or BPF_JIT, or NFS_FS, yet all of them are enabled. Let
> > me know if you want hundreds more examples.
> 
> So if there is any bug, you are allowed to add new one? If there is any
> silly option, you are allowed to add new one?
> 
> Feel free to propose dropping of any irrelevant options.

No, of course you aren't. My point is that Fedora is a distro just as
established and legitimate as Debian is. And apparently "it makes Debian
works" is a reasonable argument, since, well, it does.

If making Fedora boot with that defconfig is not a legitimate goal,
please state why, and document it (with the ack of all the maintainers
involved with that defconfig, obviously) so we don't have the same
argument over and over again.

> >> I kind of repeat comments from similar patch earlier:
> >> https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/
> >>
> >> About XFS: I don't think it is needed to boot anything.
> > 
> > Just like 9P_FS, NFS or UBIFS.
> 
> NFS is often used on targets, e.g. my board farm, but also by other people.
> 
> UBIFS was added recently because one device was using it - you needed
> it. 9P_FS looks unnecessary.

So all we need is one person or use case to require it? Sounds like
we've checked that mark here.

> >> This is a defconfig, not a distro config. Please don't make it distro.
> >>
> >> I will gladly support things needed by systemd or equivalent, but not
> >> unusual filesystems needed by distro.
> > 
> > It's a defconfig. It's whatever people want it to be. Or we need to come
> > up with a clearly defined set of rules of what is acceptable in that
> > defconfig or not, and prune every option that isn't.
> 
> So that's the rule I am commenting from time to time. defconfigs are not
> distro configs. These are reference hardware configs and debugging
> configs.

Supporting a board farm is hardly either.

And again, I've never heard of such rule for that defconfig in my ~10y
as an ARM platform maintainer. But what do I know, right?

> I was working in distro so trust me - they do stuff differently
> and they not need XFS in our defconfig for anything.

Sure, but you're not just arguing for XFS there.

What I really don't get is this: this makes the life of people easier.

Being able to test an upstream kernel quickly when you have a bug in a
downstream distro is super valuable for any distro developper. And on
the long run, if we don't make the switch from a kernel distro to a
mainline kernel relatively easy, we're the ones that will lose out.
Because people just won't bother, or be frustrated and thus super
reluctant to do that work.

That's the part I don't get. Why do we want to make the life of people
harder. This patch has never been about making the defconfig the main
Fedora kernel configuration: it won't be, just like it isn't the Debian
kernel configuration.

However, it works for your board farm because it's just so much more
convenient, you can get a kernel from all the auto-builder and boot that
and you know that it's supposed to work. And that's totally reasonable.

So if it's convenient for you and your board farm, why do you oppose
other people trying to make it reasonably convenient for them?

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/20240221/7d49fe67/attachment.sig>

From niliqiang.io at gmail.com  Wed Feb 21 07:26:29 2024
From: niliqiang.io at gmail.com (ni.liqiang)
Date: Wed, 21 Feb 2024 23:26:29 +0800
Subject: [PATCH] drivers/iommu: Ensure that the queue base address is successfully written during SMMU initialization.
In-Reply-To: <20240219091709.GA4105@willie-the-truck>
References: <20240219091709.GA4105@willie-the-truck>
Message-ID: <20240221152629.3656-1-niliqiang.io@gmail.com>

>>  The SMMU registers are accessed using Device-nGnRE attributes. It is
>> my understanding that, for Device-nGnRE, the Arm architecture requires
>> that writes to the same peripheral arrive at the endpoint in program
>> order.
>
> Yup, that's correct. The "nR" part means "non-Reordering", so something
> else is going on here.

Yes, the SMMU registers are accessed using Device-nGnRE attributes. 

One additional point to note is: in cases where there is a failure writing to the CMDQ base address register, the testing environment was a multi-die, multi-socket server. This issue has not been observed on a single-die server. I apologize for omitting this information in my initial patch submission. 

Over the past few days, I have referenced the kernel source code and ported the SMMU register initialization process. Through multiple stress tests, I have attempted to reproduce the CMDQ base address register write failure issue. The summarized results of my experiments are as follows:
1. When testing with one CPU core bound using taskset, the initialization process was executed 300,000 times without encountering the CMDQ base address register write failure issue. However, when not binding CPU using taskset, the issue was reproduced around 1,000 iterations into the test.
2. Without CPU binding, I inserted a memory barrier between accesses to the CMDQ_BASE register and CMDQEN register, similar to the modification made in the patch. After executing the initialization process 300,000 times, the CMDQ base address register write failure issue did not occur.

Based on these observations and joint analysis with CMN colleagues, we speculate that in the SMMU register initialization process, if the CPU core changes, and these CPUs are located on different dies, the underlying 4 CCG ports are utilized to perform die-to-die accesses. However, in our current strategy, these 4 CCG ports cannot guarantee ordering, resulting in the completion of CMDQEN writing before the completion of CMDQ base address writing.

>From the analysis above, it seems that modifying the die-to-die access strategy to achieve ordering of Device-nGnRE memory might be a better solution compared to adding a memory barrier?


From arnd at arndb.de  Wed Feb 21 07:31:29 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 21 Feb 2024 16:31:29 +0100
Subject: [PATCH] arm64: defconfig: Enable zram, xfs and loading compressed FW
 support
In-Reply-To: <20240221125928.3711050-1-javierm@redhat.com>
References: <20240221125928.3711050-1-javierm@redhat.com>
Message-ID: <9f419e86-6e14-42a1-84e1-31cab62d8ea2@app.fastmail.com>

On Wed, Feb 21, 2024, at 13:59, Javier Martinez Canillas wrote:
> These options are needed by some Linux distributions (e.g: Fedora), so
> let's enable them to make it easier for developers using such distros.
>
> Signed-off-by: Javier Martinez Canillas <javierm at redhat.com>
> ---

Acked-by: Arnd Bergmann <arnd at arndb.de>

> @@ -1595,6 +1599,7 @@ CONFIG_HTE_TEGRA194_TEST=m
>  CONFIG_EXT2_FS=y
>  CONFIG_EXT3_FS=y
>  CONFIG_EXT4_FS_POSIX_ACL=y
> +CONFIG_XFS_FS=m
>  CONFIG_BTRFS_FS=m
>  CONFIG_BTRFS_FS_POSIX_ACL=y

Unfortunately this will increase build time noticeably, but
I agree it is the right thing to do.

Can you send it (with any other acks) to soc at kernel.org so
I can merge it from there?

        Arnd


From Frank.li at nxp.com  Wed Feb 21 07:33:10 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 21 Feb 2024 10:33:10 -0500
Subject: [PATCH v11 07/14] dt-bindings: imx6q-pcie: Clean up
 irrationality clocks check
In-Reply-To: <ZdXVN17SogJG1RgZ@lpieralisi>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
 <20240220161924.3871774-8-Frank.Li@nxp.com>
 <ZdXVN17SogJG1RgZ@lpieralisi>
Message-ID: <ZdYXtmJgTQ63jq+C@lizhi-Precision-Tower-5810>

On Wed, Feb 21, 2024 at 11:49:27AM +0100, Lorenzo Pieralisi wrote:
> Irrationality ? I think you mean "duplicate" or "redundant" ?

I initially emphasized the negation logic code (*not*) below. I may have
used the wrong term.

I am okay simple said
"Clean up redundant clocks check"

Frank 

> 
> Lorenzo
> 
> On Tue, Feb 20, 2024 at 11:19:17AM -0500, Frank Li wrote:
> > The bindings referencing this file already define these constraints for
> > each of the variants, so the if not: then: is redundant.
> > 
> > Acked-by: Rob Herring <robh at kernel.org>
> > Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > 
> > Notes:
> >     Change from v7 to v8
> >     - add Manivannan Sadhasiva's Ack tag
> >     Change from v6 to v7
> >     - rewrite git commit message by using simple words
> >     Change from v5 to v6
> >     - rewrite git commit message and explain why remove it safely.
> >     - Add Rob's Ack
> >     Change from v1 to v4
> >     - new patch at v4
> > 
> >  .../bindings/pci/fsl,imx6q-pcie-common.yaml      | 16 ----------------
> >  1 file changed, 16 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
> > index d91b639ae7ae7..0c50487a3866d 100644
> > --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
> > +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
> > @@ -150,22 +150,6 @@ allOf:
> >              - {}
> >              - const: pcie_phy
> >              - const: pcie_aux
> > -  - if:
> > -      properties:
> > -        compatible:
> > -          not:
> > -            contains:
> > -              enum:
> > -                - fsl,imx6sx-pcie
> > -                - fsl,imx8mq-pcie
> > -                - fsl,imx6sx-pcie-ep
> > -                - fsl,imx8mq-pcie-ep
> > -    then:
> > -      properties:
> > -        clocks:
> > -          maxItems: 3
> > -        clock-names:
> > -          maxItems: 3
> >  
> >    - if:
> >        properties:
> > -- 
> > 2.34.1
> > 


From ghennadi.procopciuc at oss.nxp.com  Wed Feb 21 07:19:01 2024
From: ghennadi.procopciuc at oss.nxp.com (Ghennadi Procopciuc)
Date: Wed, 21 Feb 2024 17:19:01 +0200
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
References: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
 <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
Message-ID: <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>

On 2/21/24 16:45, Krzysztof Kozlowski wrote:
> On 21/02/2024 15:42, Krzysztof Kozlowski wrote:
>> On 21/02/2024 13:01, Ghennadi Procopciuc wrote:
>>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>>
>>> Add myself as a maintainer of the NXP S32G DT files.
>>
>> No need for cover letters for single patches. OTOH, this commit msg is
>> empty...
Thank you, I can correct that.

>> Plus your patch looks corrupted (wrong encoding): F??rber

Indeed, it is due to 'Content-Type: text/plain; charset="us-ascii"'.
I can fix this as part of v2.

>> BTW, did you contribute anything to the upstream Linux kernel? Do you
>> know the process? Downstream does not really matter.
> 
> I found the answer:
> 
> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
> 
> Does not look like. Please get some upstream work experience first.
> 
> https://lore.kernel.org/all/?q=f%3Aghennadi.procopciuc%40oss.nxp.com

Although I am new to upstream communities and may make mistakes, I am
eager to learn and improve.

After leaving SuSe[0], the current maintainer of the NXP S32G DT files
became inactive[1]. As a result, this area is not currently being
maintained. This is the actual reason why I attempted to add myself as a
maintainer of that area. Although I acknowledge that I may not have
enough experience to become a maintainer, I am concerned that the NXP
S32G DT patch submission may be blocked for everyone due to the current
situation.

Should someone else from MAINTAINERS take over this area, or are there
other alternatives?

[0] https://lore.kernel.org/all/20231115234508.11510-1-clin at suse.com/
[1]
https://lore.kernel.org/all/a7a55dc6-c204-4aad-adff-9806d3302b6b at oss.nxp.com/


> 
> Best regards,
> Krzysztof
> Regards,
Ghennadi



From Frank.li at nxp.com  Wed Feb 21 07:36:17 2024
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 21 Feb 2024 10:36:17 -0500
Subject: [PATCH v11 10/14] PCI: imx6: Add iMX95 PCIe Root Complex support
In-Reply-To: <ZdXTof/fSOuBw4MW@lpieralisi>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
 <20240220161924.3871774-11-Frank.Li@nxp.com>
 <ZdXTof/fSOuBw4MW@lpieralisi>
Message-ID: <ZdYYcf2fOkwl3oiM@lizhi-Precision-Tower-5810>

On Wed, Feb 21, 2024 at 11:42:41AM +0100, Lorenzo Pieralisi wrote:
> On Tue, Feb 20, 2024 at 11:19:20AM -0500, Frank Li wrote:
> > Add iMX95 PCIe Root Complex support.
> > 
> > Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > Signed-off-by: Frank Li <Frank.Li at nxp.com>
> > ---
> > 
> > Notes:
> >     Change from v8 to v9
> >     - Add mani's review tag
> >     
> >     Change from v7 to v8
> >     - Update commit subject
> >     - add const from regmap
> >     - remove unnessary logic in imx6_pcie_deassert_core_reset()
> >     
> >     Change from v4 to v7
> >     - none
> >     Change from v1 to v3
> >     - none
> > 
> >  drivers/pci/controller/dwc/pci-imx6.c | 82 +++++++++++++++++++++++++--
> >  1 file changed, 77 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> > index 71ce6b7ac1de0..582ba00d628a1 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -42,6 +42,25 @@
> >  #define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE	GENMASK(11, 8)
> >  #define IMX8MQ_PCIE2_BASE_ADDR			0x33c00000
> >  
> > +#define IMX95_PCIE_PHY_GEN_CTRL			0x0
> > +#define IMX95_PCIE_REF_USE_PAD			BIT(17)
> > +
> > +#define IMX95_PCIE_PHY_MPLLA_CTRL		0x10
> > +#define IMX95_PCIE_PHY_MPLL_STATE		BIT(30)
> 
> These two defines are unused, I will remove them.
> 
> > +#define IMX95_PCIE_SS_RW_REG_0			0xf0
> > +#define IMX95_PCIE_REF_CLKEN			BIT(23)
> > +#define IMX95_PCIE_PHY_CR_PARA_SEL		BIT(9)
> > +
> > +#define IMX95_PE0_GEN_CTRL_1			0x1050
> > +#define IMX95_PCIE_DEVICE_TYPE			GENMASK(3, 0)
> > +
> > +#define IMX95_PE0_GEN_CTRL_3			0x1058
> > +#define IMX95_PCIE_LTSSM_EN			BIT(0)
> > +
> > +#define IMX95_PE0_PM_STS			0x1064
> > +#define IMX95_PCIE_PM_LINKST_IN_L2		BIT(14)
> 
> These two defines are unused. I will remove them.

Thanks.
let me know if need me send out revised patches.

Frank

> 
> > +
> >  #define to_imx6_pcie(x)	dev_get_drvdata((x)->dev)
> >  
> >  enum imx6_pcie_variants {
> > @@ -52,6 +71,7 @@ enum imx6_pcie_variants {
> >  	IMX8MQ,
> >  	IMX8MM,
> >  	IMX8MP,
> > +	IMX95,
> >  	IMX8MQ_EP,
> >  	IMX8MM_EP,
> >  	IMX8MP_EP,
> > @@ -63,6 +83,7 @@ enum imx6_pcie_variants {
> >  #define IMX6_PCIE_FLAG_HAS_PHYDRV			BIT(3)
> >  #define IMX6_PCIE_FLAG_HAS_APP_RESET		BIT(4)
> >  #define IMX6_PCIE_FLAG_HAS_PHY_RESET		BIT(5)
> > +#define IMX6_PCIE_FLAG_HAS_SERDES		BIT(6)
> >  
> >  #define imx6_check_flag(pci, val)     (pci->drvdata->flags & val)
> >  
> > @@ -179,6 +200,24 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
> >  	return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
> >  }
> >  
> > +static int imx95_pcie_init_phy(struct imx6_pcie *imx6_pcie)
> > +{
> > +	regmap_update_bits(imx6_pcie->iomuxc_gpr,
> > +			IMX95_PCIE_SS_RW_REG_0,
> > +			IMX95_PCIE_PHY_CR_PARA_SEL,
> > +			IMX95_PCIE_PHY_CR_PARA_SEL);
> > +
> > +	regmap_update_bits(imx6_pcie->iomuxc_gpr,
> > +			   IMX95_PCIE_PHY_GEN_CTRL,
> > +			   IMX95_PCIE_REF_USE_PAD, 0);
> > +	regmap_update_bits(imx6_pcie->iomuxc_gpr,
> > +			   IMX95_PCIE_SS_RW_REG_0,
> > +			   IMX95_PCIE_REF_CLKEN,
> > +			   IMX95_PCIE_REF_CLKEN);
> > +
> > +	return 0;
> > +}
> > +
> >  static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
> >  {
> >  	const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
> > @@ -575,6 +614,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
> >  				   IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
> >  		break;
> >  	case IMX7D:
> > +	case IMX95:
> >  		break;
> >  	case IMX8MM:
> >  	case IMX8MM_EP:
> > @@ -1279,12 +1319,32 @@ static int imx6_pcie_probe(struct platform_device *pdev)
> >  		return PTR_ERR(imx6_pcie->turnoff_reset);
> >  	}
> >  
> > +	if (imx6_pcie->drvdata->gpr) {
> >  	/* Grab GPR config register range */
> > -	imx6_pcie->iomuxc_gpr =
> > -		 syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
> > -	if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
> > -		dev_err(dev, "unable to find iomuxc registers\n");
> > -		return PTR_ERR(imx6_pcie->iomuxc_gpr);
> > +		imx6_pcie->iomuxc_gpr =
> > +			 syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
> > +		if (IS_ERR(imx6_pcie->iomuxc_gpr))
> > +			return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
> > +					     "unable to find iomuxc registers\n");
> > +	}
> > +
> > +	if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_SERDES)) {
> > +		void __iomem *off = devm_platform_ioremap_resource_byname(pdev, "app");
> > +
> > +		if (IS_ERR(off))
> > +			return dev_err_probe(dev, PTR_ERR(off),
> > +					     "unable to find serdes registers\n");
> > +
> > +		static const struct regmap_config regmap_config = {
> > +			.reg_bits = 32,
> > +			.val_bits = 32,
> > +			.reg_stride = 4,
> > +		};
> > +
> > +		imx6_pcie->iomuxc_gpr = devm_regmap_init_mmio(dev, off, &regmap_config);
> > +		if (IS_ERR(imx6_pcie->iomuxc_gpr))
> > +			return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
> > +					     "unable to find iomuxc registers\n");
> >  	}
> >  
> >  	/* Grab PCIe PHY Tx Settings */
> > @@ -1457,6 +1517,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
> >  		.mode_off[0] = IOMUXC_GPR12,
> >  		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
> >  	},
> > +	[IMX95] = {
> > +		.variant = IMX95,
> > +		.flags = IMX6_PCIE_FLAG_HAS_SERDES,
> > +		.clk_names = imx8mq_clks,
> > +		.clks_cnt = ARRAY_SIZE(imx8mq_clks),
> > +		.ltssm_off = IMX95_PE0_GEN_CTRL_3,
> > +		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
> > +		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
> > +		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> > +		.init_phy = imx95_pcie_init_phy,
> > +	},
> >  	[IMX8MQ_EP] = {
> >  		.variant = IMX8MQ_EP,
> >  		.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
> > @@ -1501,6 +1572,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
> >  	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
> >  	{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
> >  	{ .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], },
> > +	{ .compatible = "fsl,imx95-pcie", .data = &drvdata[IMX95], },
> >  	{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
> >  	{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
> >  	{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
> > -- 
> > 2.34.1
> > 


From krzysztof.kozlowski at linaro.org  Wed Feb 21 07:38:06 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 16:38:06 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
Message-ID: <9083c414-62f2-4bff-93ee-13f8ff60eb34@linaro.org>

On 21/02/2024 16:24, Maxime Ripard wrote:
> On Wed, Feb 21, 2024 at 04:10:12PM +0100, Krzysztof Kozlowski wrote:
>> On 21/02/2024 15:48, Maxime Ripard wrote:
>>> On Wed, Feb 21, 2024 at 03:22:38PM +0100, Krzysztof Kozlowski wrote:
>>>> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
>>>>> These options are needed by some Linux distributions (e.g: Fedora), so
>>>>
>>>> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
>>>> use on my arm64 boards, does not have any problem.
>>>
>>> Is it relevant in any way?
>>
>> Yes, because it is justification why we are doing it. Each commit is
>> supposed to explain "why" and the explanation here is not enough.
> 
> There's a why though: it makes Fedora boot. It might not be enough for

I want to know to understand. Maybe it is not really neeed but "nice to
have"? People write various vague statements...

> you, but that's a different story. So, if it's not enough, please state
> exactly what you expect from that patch description so Javier can
> provide it.

Any explanation what ZRAM is necessary for Fedora to boot.

> 
>>> I'm sure Debian can boot without MEMORY_HOTREMOVE, or BRIDGE, or
>>> NUMA_BALANCING, or BPF_JIT, or NFS_FS, yet all of them are enabled. Let
>>> me know if you want hundreds more examples.
>>
>> So if there is any bug, you are allowed to add new one? If there is any
>> silly option, you are allowed to add new one?
>>
>> Feel free to propose dropping of any irrelevant options.
> 
> No, of course you aren't. My point is that Fedora is a distro just as
> established and legitimate as Debian is. And apparently "it makes Debian
> works" is a reasonable argument, since, well, it does.
> 
> If making Fedora boot with that defconfig is not a legitimate goal,

It is, but I asked for more information.

> please state why, and document it (with the ack of all the maintainers
> involved with that defconfig, obviously) so we don't have the same
> argument over and over again.
> 
>>>> I kind of repeat comments from similar patch earlier:
>>>> https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/
>>>>
>>>> About XFS: I don't think it is needed to boot anything.
>>>
>>> Just like 9P_FS, NFS or UBIFS.
>>
>> NFS is often used on targets, e.g. my board farm, but also by other people.
>>
>> UBIFS was added recently because one device was using it - you needed
>> it. 9P_FS looks unnecessary.
> 
> So all we need is one person or use case to require it? Sounds like
> we've checked that mark here.

Use case of given type. I would disagree for SMBFS because we have NFS.
UBIFS is hardware requirement. 9P_FS seems like virtio case.

> 
>>>> This is a defconfig, not a distro config. Please don't make it distro.
>>>>
>>>> I will gladly support things needed by systemd or equivalent, but not
>>>> unusual filesystems needed by distro.
>>>
>>> It's a defconfig. It's whatever people want it to be. Or we need to come
>>> up with a clearly defined set of rules of what is acceptable in that
>>> defconfig or not, and prune every option that isn't.
>>
>> So that's the rule I am commenting from time to time. defconfigs are not
>> distro configs. These are reference hardware configs and debugging
>> configs.
> 
> Supporting a board farm is hardly either.

Debugging purpose, but I agree we can drop it.

> 
> And again, I've never heard of such rule for that defconfig in my ~10y
> as an ARM platform maintainer. But what do I know, right?
> 
>> I was working in distro so trust me - they do stuff differently
>> and they not need XFS in our defconfig for anything.
> 
> Sure, but you're not just arguing for XFS there.

I raised need for "why" for ZRAM and un-necessity of XFS. What's wrong
with that? I should send separate emails or what?

> 
> What I really don't get is this: this makes the life of people easier.

Again: this makes my life harder. I cannot be buying new machines every
two years to be able to compile defconfig while testing/working.

> 
> Being able to test an upstream kernel quickly when you have a bug in a
> downstream distro is super valuable for any distro developper. And on

That's a distro need, not relevant. And even if it was, then your
argument would be "let's enable everything distro has!". This is not a
distro kernel.


> the long run, if we don't make the switch from a kernel distro to a
> mainline kernel relatively easy, we're the ones that will lose out.
> Because people just won't bother, or be frustrated and thus super
> reluctant to do that work.
> 
> That's the part I don't get. Why do we want to make the life of people
> harder. This patch has never been about making the defconfig the main

Because it makes my life harder and I don't see benefits. Quoting Arnd:
"Unfortunately this will increase build time noticeably, but"

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Wed Feb 21 07:39:18 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 16:39:18 +0100
Subject: [PATCH] arm64: defconfig: Enable zram, xfs and loading compressed
 FW support
In-Reply-To: <9f419e86-6e14-42a1-84e1-31cab62d8ea2@app.fastmail.com>
References: <20240221125928.3711050-1-javierm@redhat.com>
 <9f419e86-6e14-42a1-84e1-31cab62d8ea2@app.fastmail.com>
Message-ID: <205248ce-caeb-4090-998e-379f79639bec@linaro.org>

On 21/02/2024 16:31, Arnd Bergmann wrote:
> On Wed, Feb 21, 2024, at 13:59, Javier Martinez Canillas wrote:
>> These options are needed by some Linux distributions (e.g: Fedora), so
>> let's enable them to make it easier for developers using such distros.
>>
>> Signed-off-by: Javier Martinez Canillas <javierm at redhat.com>
>> ---
> 
> Acked-by: Arnd Bergmann <arnd at arndb.de>
> 
>> @@ -1595,6 +1599,7 @@ CONFIG_HTE_TEGRA194_TEST=m
>>  CONFIG_EXT2_FS=y
>>  CONFIG_EXT3_FS=y
>>  CONFIG_EXT4_FS_POSIX_ACL=y
>> +CONFIG_XFS_FS=m
>>  CONFIG_BTRFS_FS=m
>>  CONFIG_BTRFS_FS_POSIX_ACL=y
> 
> Unfortunately this will increase build time noticeably, but
> I agree it is the right thing to do.
> 
> Can you send it (with any other acks) to soc at kernel.org so
> I can merge it from there?

Due to XFS, please include:

Nacked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

so this will not be precedence used for further patches like this
(Maxime already used such argument, so I want to be sure it will not be
used against me in the future)

Best regards,
Krzysztof



From arnd at arndb.de  Wed Feb 21 07:41:38 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 21 Feb 2024 16:41:38 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading compressed FW
 support
In-Reply-To: <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
Message-ID: <56625c21-1b34-479b-b5b2-4c4d8b7a11b3@app.fastmail.com>

On Wed, Feb 21, 2024, at 16:24, Maxime Ripard wrote:
> On Wed, Feb 21, 2024 at 04:10:12PM +0100, Krzysztof Kozlowski wrote:
>> On 21/02/2024 15:48, Maxime Ripard wrote:
>> > On Wed, Feb 21, 2024 at 03:22:38PM +0100, Krzysztof Kozlowski wrote:
>> >> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
>> >>> These options are needed by some Linux distributions (e.g: Fedora), so
>> >>
>> >> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
>> >> use on my arm64 boards, does not have any problem.
>> > 
>> > Is it relevant in any way?
>> 
>> Yes, because it is justification why we are doing it. Each commit is
>> supposed to explain "why" and the explanation here is not enough.
>
> There's a why though: it makes Fedora boot. It might not be enough for
> you, but that's a different story. So, if it's not enough, please state
> exactly what you expect from that patch description so Javier can
> provide it.

It's definitely enough for me. It makes a lot of sense to have
a defconfig that boots common and popular distros.

I don't use ZRAM either, but I can see that being useful to
avoid swapping to SD cards or eMMC when that is the only
available swap device.

>> >> I kind of repeat comments from similar patch earlier:
>> >> https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/
>> >>
>> >> About XFS: I don't think it is needed to boot anything.
>> > 
>> > Just like 9P_FS, NFS or UBIFS.
>> 
>> NFS is often used on targets, e.g. my board farm, but also by other people.
>> 
>> UBIFS was added recently because one device was using it - you needed
>> it. 9P_FS looks unnecessary.
>
> So all we need is one person or use case to require it? Sounds like
> we've checked that mark here.

I think we want all of the above. We can probably drop ext2 since
we already need ext4, but that is a different question.

>> I was working in distro so trust me - they do stuff differently
>> and they not need XFS in our defconfig for anything.
>
> Sure, but you're not just arguing for XFS there.
>
> What I really don't get is this: this makes the life of people easier.
>
> Being able to test an upstream kernel quickly when you have a bug in a
> downstream distro is super valuable for any distro developper. And on
> the long run, if we don't make the switch from a kernel distro to a
> mainline kernel relatively easy, we're the ones that will lose out.
> Because people just won't bother, or be frustrated and thus super
> reluctant to do that work.

We had previously discussed adding config fragments for common
distros the way we have kvm_guest.config, but if the Javier's
patch is all that is actually needed for Fedora, that seems better
to me than the added complexity of fragments.

      Arnd


From krzysztof.kozlowski at linaro.org  Wed Feb 21 07:43:13 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 16:43:13 +0100
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
References: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
 <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
Message-ID: <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>

On 21/02/2024 16:19, Ghennadi Procopciuc wrote:
> On 2/21/24 16:45, Krzysztof Kozlowski wrote:
>> On 21/02/2024 15:42, Krzysztof Kozlowski wrote:
>>> On 21/02/2024 13:01, Ghennadi Procopciuc wrote:
>>>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>>>
>>>> Add myself as a maintainer of the NXP S32G DT files.
>>>
>>> No need for cover letters for single patches. OTOH, this commit msg is
>>> empty...
> Thank you, I can correct that.
> 
>>> Plus your patch looks corrupted (wrong encoding): F??rber
> 
> Indeed, it is due to 'Content-Type: text/plain; charset="us-ascii"'.
> I can fix this as part of v2.
> 
>>> BTW, did you contribute anything to the upstream Linux kernel? Do you
>>> know the process? Downstream does not really matter.
>>
>> I found the answer:
>>
>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
>>
>> Does not look like. Please get some upstream work experience first.
>>
>> https://lore.kernel.org/all/?q=f%3Aghennadi.procopciuc%40oss.nxp.com
> 
> Although I am new to upstream communities and may make mistakes, I am
> eager to learn and improve.
> 
> After leaving SuSe[0], the current maintainer of the NXP S32G DT files
> became inactive[1]. As a result, this area is not currently being
> maintained. This is the actual reason why I attempted to add myself as a
> maintainer of that area. Although I acknowledge that I may not have
> enough experience to become a maintainer, I am concerned that the NXP
> S32G DT patch submission may be blocked for everyone due to the current
> situation.

I would be just happy to see first actual contributions or any sort of
activity, like reviewing, before taking over something.

You do not need to become maintainer to provide reviews. By reviewing
patches you already reduce burden/work from the maintainers.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Wed Feb 21 07:46:21 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 16:46:21 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <56625c21-1b34-479b-b5b2-4c4d8b7a11b3@app.fastmail.com>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
 <56625c21-1b34-479b-b5b2-4c4d8b7a11b3@app.fastmail.com>
Message-ID: <908e6db9-0323-40b3-bda5-02b0a645e4d5@linaro.org>

On 21/02/2024 16:41, Arnd Bergmann wrote:
> On Wed, Feb 21, 2024, at 16:24, Maxime Ripard wrote:
>> On Wed, Feb 21, 2024 at 04:10:12PM +0100, Krzysztof Kozlowski wrote:
>>> On 21/02/2024 15:48, Maxime Ripard wrote:
>>>> On Wed, Feb 21, 2024 at 03:22:38PM +0100, Krzysztof Kozlowski wrote:
>>>>> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
>>>>>> These options are needed by some Linux distributions (e.g: Fedora), so
>>>>>
>>>>> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
>>>>> use on my arm64 boards, does not have any problem.
>>>>
>>>> Is it relevant in any way?
>>>
>>> Yes, because it is justification why we are doing it. Each commit is
>>> supposed to explain "why" and the explanation here is not enough.
>>
>> There's a why though: it makes Fedora boot. It might not be enough for
>> you, but that's a different story. So, if it's not enough, please state
>> exactly what you expect from that patch description so Javier can
>> provide it.
> 
> It's definitely enough for me. It makes a lot of sense to have
> a defconfig that boots common and popular distros.
> 
> I don't use ZRAM either, but I can see that being useful to
> avoid swapping to SD cards or eMMC when that is the only
> available swap device.
> 
>>>>> I kind of repeat comments from similar patch earlier:
>>>>> https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/
>>>>>
>>>>> About XFS: I don't think it is needed to boot anything.
>>>>
>>>> Just like 9P_FS, NFS or UBIFS.
>>>
>>> NFS is often used on targets, e.g. my board farm, but also by other people.
>>>
>>> UBIFS was added recently because one device was using it - you needed
>>> it. 9P_FS looks unnecessary.
>>
>> So all we need is one person or use case to require it? Sounds like
>> we've checked that mark here.
> 
> I think we want all of the above. We can probably drop ext2 since
> we already need ext4, but that is a different question.

I'll send a patch. Ext3 is there as well.

Best regards,
Krzysztof



From alexander.sverdlin at siemens.com  Wed Feb 21 07:45:50 2024
From: alexander.sverdlin at siemens.com (A. Sverdlin)
Date: Wed, 21 Feb 2024 16:45:50 +0100
Subject: [PATCH 1/2] ARM: AM33xx: PRM: Remove redundand defines
Message-ID: <20240221154614.3549951-1-alexander.sverdlin@siemens.com>

From: Alexander Sverdlin <alexander.sverdlin at siemens.com>

AM33XX_PRM_RSTCTRL_OFFSET is already defined in prm33xx.h and
AM33XX_RST_GLOBAL_WARM_SW_MASK in prm-regbits-33xx.h.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin at siemens.com>
---
 arch/arm/mach-omap2/prm33xx.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 4b65a0f9cf7d9..4a462310a4b09 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -15,10 +15,6 @@
 #include "prm33xx.h"
 #include "prm-regbits-33xx.h"
 
-#define AM33XX_PRM_RSTCTRL_OFFSET		0x0000
-
-#define AM33XX_RST_GLOBAL_WARM_SW_MASK		(1 << 0)
-
 /* Read a register in a PRM instance */
 static u32 am33xx_prm_read_reg(s16 inst, u16 idx)
 {
-- 
2.43.0



From mripard at redhat.com  Wed Feb 21 07:49:21 2024
From: mripard at redhat.com (Maxime Ripard)
Date: Wed, 21 Feb 2024 16:49:21 +0100
Subject: [PATCH] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <205248ce-caeb-4090-998e-379f79639bec@linaro.org>
References: <20240221125928.3711050-1-javierm@redhat.com>
 <9f419e86-6e14-42a1-84e1-31cab62d8ea2@app.fastmail.com>
 <205248ce-caeb-4090-998e-379f79639bec@linaro.org>
Message-ID: <bcmgu7y2aolyti7kzoitepcpvjj6omkmo7jro2qtv3d7xqyw3v@jy2qe2hkf7zf>

On Wed, Feb 21, 2024 at 04:39:18PM +0100, Krzysztof Kozlowski wrote:
> On 21/02/2024 16:31, Arnd Bergmann wrote:
> > On Wed, Feb 21, 2024, at 13:59, Javier Martinez Canillas wrote:
> >> These options are needed by some Linux distributions (e.g: Fedora), so
> >> let's enable them to make it easier for developers using such distros.
> >>
> >> Signed-off-by: Javier Martinez Canillas <javierm at redhat.com>
> >> ---
> > 
> > Acked-by: Arnd Bergmann <arnd at arndb.de>
> > 
> >> @@ -1595,6 +1599,7 @@ CONFIG_HTE_TEGRA194_TEST=m
> >>  CONFIG_EXT2_FS=y
> >>  CONFIG_EXT3_FS=y
> >>  CONFIG_EXT4_FS_POSIX_ACL=y
> >> +CONFIG_XFS_FS=m
> >>  CONFIG_BTRFS_FS=m
> >>  CONFIG_BTRFS_FS_POSIX_ACL=y
> > 
> > Unfortunately this will increase build time noticeably, but
> > I agree it is the right thing to do.
> > 
> > Can you send it (with any other acks) to soc at kernel.org so
> > I can merge it from there?
> 
> Due to XFS, please include:
> 
> Nacked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> so this will not be precedence used for further patches like this
> (Maxime already used such argument, so I want to be sure it will not be
> used against me in the future)

For the record, I didn't use anything against *you*. I'd just like
consistency over how defconfig rules are applied.

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/20240221/2c769dfb/attachment.sig>

From mripard at redhat.com  Wed Feb 21 07:51:20 2024
From: mripard at redhat.com (Maxime Ripard)
Date: Wed, 21 Feb 2024 16:51:20 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <56625c21-1b34-479b-b5b2-4c4d8b7a11b3@app.fastmail.com>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
 <56625c21-1b34-479b-b5b2-4c4d8b7a11b3@app.fastmail.com>
Message-ID: <724jnhrbs6r4q6whynr3aon5w7mhfvetlgcnts4nukvtxbuium@mrjv6apjqk7r>

On Wed, Feb 21, 2024 at 04:41:38PM +0100, Arnd Bergmann wrote:
> On Wed, Feb 21, 2024, at 16:24, Maxime Ripard wrote:
> > On Wed, Feb 21, 2024 at 04:10:12PM +0100, Krzysztof Kozlowski wrote:
> >> On 21/02/2024 15:48, Maxime Ripard wrote:
> >> > On Wed, Feb 21, 2024 at 03:22:38PM +0100, Krzysztof Kozlowski wrote:
> >> >> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
> >> >>> These options are needed by some Linux distributions (e.g: Fedora), so
> >> >>
> >> >> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
> >> >> use on my arm64 boards, does not have any problem.
> >> > 
> >> > Is it relevant in any way?
> >> 
> >> Yes, because it is justification why we are doing it. Each commit is
> >> supposed to explain "why" and the explanation here is not enough.
> >
> > There's a why though: it makes Fedora boot. It might not be enough for
> > you, but that's a different story. So, if it's not enough, please state
> > exactly what you expect from that patch description so Javier can
> > provide it.
> 
> It's definitely enough for me. It makes a lot of sense to have
> a defconfig that boots common and popular distros.
> 
> I don't use ZRAM either, but I can see that being useful to
> avoid swapping to SD cards or eMMC when that is the only
> available swap device.
> 
> >> >> I kind of repeat comments from similar patch earlier:
> >> >> https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/
> >> >>
> >> >> About XFS: I don't think it is needed to boot anything.
> >> > 
> >> > Just like 9P_FS, NFS or UBIFS.
> >> 
> >> NFS is often used on targets, e.g. my board farm, but also by other people.
> >> 
> >> UBIFS was added recently because one device was using it - you needed
> >> it. 9P_FS looks unnecessary.
> >
> > So all we need is one person or use case to require it? Sounds like
> > we've checked that mark here.
> 
> I think we want all of the above. We can probably drop ext2 since
> we already need ext4, but that is a different question.
> 
> >> I was working in distro so trust me - they do stuff differently
> >> and they not need XFS in our defconfig for anything.
> >
> > Sure, but you're not just arguing for XFS there.
> >
> > What I really don't get is this: this makes the life of people easier.
> >
> > Being able to test an upstream kernel quickly when you have a bug in a
> > downstream distro is super valuable for any distro developper. And on
> > the long run, if we don't make the switch from a kernel distro to a
> > mainline kernel relatively easy, we're the ones that will lose out.
> > Because people just won't bother, or be frustrated and thus super
> > reluctant to do that work.
> 
> We had previously discussed adding config fragments for common
> distros the way we have kvm_guest.config, but if the Javier's
> patch is all that is actually needed for Fedora, that seems better
> to me than the added complexity of fragments.

Oh, right. Fragments would be a great tool to reconcile the need for
minimal boot time and supporting reasonable use-cases.

I guess it's even more of a struggle with the single arm64 defconfig vs
the minimal vs batteries included defconfig setup we had for arm.

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/20240221/5e86062a/attachment-0001.sig>

From pierre.gondois at arm.com  Wed Feb 21 07:51:57 2024
From: pierre.gondois at arm.com (Pierre Gondois)
Date: Wed, 21 Feb 2024 16:51:57 +0100
Subject: [PATCH v1 0/2] support NUMA emulation for genertic arch
In-Reply-To: <ZdWUPlqsxC_y3YFM@kernel.org>
References: <20231012024842.99703-1-rongwei.wang@linux.alibaba.com>
 <20240220113602.6943-1-rongwei.wang@linux.alibaba.com>
 <ZdWUPlqsxC_y3YFM@kernel.org>
Message-ID: <6843f6b2-4c41-4649-9885-88fde7215e3f@arm.com>



On 2/21/24 07:12, Mike Rapoport wrote:
> On Tue, Feb 20, 2024 at 07:36:00PM +0800, Rongwei Wang wrote:
>> A brief introduction
>> ====================
>>
>> The NUMA emulation can fake more node base on a single
>> node system, e.g.
> 
> ...
>   
>> Lastly, it seems not a good choice to realize x86 and other genertic
>> archs separately. But it can indeed avoid some architecture related
>> APIs adjustments and alleviate future maintenance.
> 
> Why is it a good choice? Copying 1k lines from x86 to a new place and
> having to maintain two copies does not sound like a good choice to me.

I agree it would be better to avoid duplication and extract the common
code from the original x86 implementation. The RFC seemed to go more
in this direction.
Also NITs:
- genertic -> generic
- there is a 'ifdef CONFIG_X86' in drivers/base/numa_emulation.c,
   but the file should not be used by x86 as the arch doesn't set
   CONFIG_GENERIC_ARCH_NUMA

Regards,
Pierre

> 
>> The previous RFC link see [1].
>>
>> Any advice are welcome, Thanks!
>>
>> Change log
>> ==========
>>
>> RFC v1 -> v1
>> * add new CONFIG_NUMA_FAKE for genertic archs.
>> * keep x86 implementation, realize numa emulation in driver/base/ for
>>    genertic arch, e.g, arm64.
>>
>> [1] RFC v1: https://patchwork.kernel.org/project/linux-arm-kernel/cover/20231012024842.99703-1-rongwei.wang at linux.alibaba.com/
>>
>> Rongwei Wang (2):
>>    arch_numa: remove __init for early_cpu_to_node
>>    numa: introduce numa emulation for genertic arch
>>
>>   drivers/base/Kconfig          |   9 +
>>   drivers/base/Makefile         |   1 +
>>   drivers/base/arch_numa.c      |  32 +-
>>   drivers/base/numa_emulation.c | 909 ++++++++++++++++++++++++++++++++++
>>   drivers/base/numa_emulation.h |  41 ++
>>   include/asm-generic/numa.h    |   2 +-
>>   6 files changed, 992 insertions(+), 2 deletions(-)
>>   create mode 100644 drivers/base/numa_emulation.c
>>   create mode 100644 drivers/base/numa_emulation.h
>>
>> -- 
>> 2.32.0.3.gf3a3e56d6
>>
>>
> 


From arnd at arndb.de  Wed Feb 21 07:51:26 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 21 Feb 2024 16:51:26 +0100
Subject: [PATCH -next] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
In-Reply-To: <38c09a4b-69cc-4dc5-8a68-e5f5597613ac@huawei.com>
References: <20240220081527.23408-1-liuyuntao12@huawei.com>
 <1342759e-b967-4ec4-98d5-48146f81f695@app.fastmail.com>
 <38c09a4b-69cc-4dc5-8a68-e5f5597613ac@huawei.com>
Message-ID: <30b01c65-12f2-4ee0-81d5-c7a2da2c36b4@app.fastmail.com>

On Tue, Feb 20, 2024, at 10:53, liuyuntao (F) wrote:
> ? 2024/2/20 16:40, Arnd Bergmann ??:
>> On Tue, Feb 20, 2024, at 09:15, Yuntao Liu wrote:
> #
> # ARM discards the .data section because it disallows r/w data in the
> # decompressor. So move our .data to .data.efistub and .bss to .bss.efistub,
> # which are preserved explicitly by the decompressor linker script.
> #
> STUBCOPY_FLAGS-$(CONFIG_ARM)	+= --rename-section .data=.data.efistub	\
> 				   --rename-section .bss=.bss.efistub,load,alloc
>
> ---
>
> I think that .data.efistub represents the entire .data section, the same 
> applies to .bss as well,
>
> so i move all .data and .bss into the stub here.
>

Ok, I see. 

>> 
>> I guess this prevents discarding any function that has a reference
>> from pv_table or ex_table, even if there are no other references,
>> right?
>
> Indeed so, if not keep ex_table,  the compilation process will result in
>
> an error:
>
>      no __ex_table in file: vmlinux
>
>      Failed to sort kernel tables

Sure, and without the ex_table contents, it would not be able
to recover from a failed uaccess either.

> and if not keep pv_table, It can be compiled successfully, but the QEMU 
> boots will fail.

Right. The pv_table isn't technically necessary since it can
be disabled.  I think it was originally introduced in order
to avoid performance regressions when we introduced multiplatform
kernels that can run at arbitrary physical addresses rather than
having it as a build-time constant.

I don't know how much difference that actually makes for performance,
so turning it into a normal runtime lookup may or may not be
a good compromise when building with HAVE_LD_DEAD_CODE_DATA_ELIMINATION.

I have given your patch some build testing with random
configurations in my build setup and it seems to work
fine with gcc/binutils, but unfortunately I came across
a link failure using clang/lld:

ld.lld: error: ./arch/arm/kernel/vmlinux.lds:35: ( expected, but got }
>>>  __vectors_lma = .; OVERLAY 0xffff0000 : AT(__vectors_lma) { .vectors { KEEP(*(.vectors)) } .vectors.bhb.loop8 { KEEP(*(.vectors.bhb.loop8)) } .vectors.bhb.bpiall { KEEP(*(.vectors.bhb.bpiall)) } } __vectors_start = LOADADDR(.vectors); __vectors_end = LOADADDR(.vectors) + SIZEOF(.vectors); __vectors_bhb_loop8_start = LOADADDR(.vectors.bhb.loop8); __vectors_bhb_loop8_end = LOADADDR(.vectors.bhb.loop8) + SIZEOF(.vectors.bhb.loop8); __vectors_bhb_bpiall_start = LOADADDR(.vectors.bhb.bpiall); __vectors_bhb_bpiall_end = LOADADDR(.vectors.bhb.bpiall) + SIZEOF(.vectors.bhb.bpiall); . = __vectors_lma + SIZEOF(.vectors) + SIZEOF(.vectors.bhb.loop8) + SIZEOF(.vectors.bhb.bpiall); __stubs_lma = .; .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { *(.stubs) } __stubs_start = LOADADDR(.stubs); __stubs_end = LOADADDR(.stubs) + SIZEOF(.stubs); . = __stubs_lma + SIZEOF(.stubs); PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors));
>>>                                                                                           ^

I don't immediately see what the problem is here, I hope you
can address it before you send a v2.

     Arnd


From krzysztof.kozlowski at linaro.org  Wed Feb 21 07:52:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 16:52:26 +0100
Subject: [PATCH] arm64: defconfig: Enable zram, xfs and loading compressed
 FW support
In-Reply-To: <bcmgu7y2aolyti7kzoitepcpvjj6omkmo7jro2qtv3d7xqyw3v@jy2qe2hkf7zf>
References: <20240221125928.3711050-1-javierm@redhat.com>
 <9f419e86-6e14-42a1-84e1-31cab62d8ea2@app.fastmail.com>
 <205248ce-caeb-4090-998e-379f79639bec@linaro.org>
 <bcmgu7y2aolyti7kzoitepcpvjj6omkmo7jro2qtv3d7xqyw3v@jy2qe2hkf7zf>
Message-ID: <57ffc027-7870-4765-b837-4703c39c1236@linaro.org>

On 21/02/2024 16:49, Maxime Ripard wrote:
> On Wed, Feb 21, 2024 at 04:39:18PM +0100, Krzysztof Kozlowski wrote:
>> On 21/02/2024 16:31, Arnd Bergmann wrote:
>>> On Wed, Feb 21, 2024, at 13:59, Javier Martinez Canillas wrote:
>>>> These options are needed by some Linux distributions (e.g: Fedora), so
>>>> let's enable them to make it easier for developers using such distros.
>>>>
>>>> Signed-off-by: Javier Martinez Canillas <javierm at redhat.com>
>>>> ---
>>>
>>> Acked-by: Arnd Bergmann <arnd at arndb.de>
>>>
>>>> @@ -1595,6 +1599,7 @@ CONFIG_HTE_TEGRA194_TEST=m
>>>>  CONFIG_EXT2_FS=y
>>>>  CONFIG_EXT3_FS=y
>>>>  CONFIG_EXT4_FS_POSIX_ACL=y
>>>> +CONFIG_XFS_FS=m
>>>>  CONFIG_BTRFS_FS=m
>>>>  CONFIG_BTRFS_FS_POSIX_ACL=y
>>>
>>> Unfortunately this will increase build time noticeably, but
>>> I agree it is the right thing to do.
>>>
>>> Can you send it (with any other acks) to soc at kernel.org so
>>> I can merge it from there?
>>
>> Due to XFS, please include:
>>
>> Nacked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>
>> so this will not be precedence used for further patches like this
>> (Maxime already used such argument, so I want to be sure it will not be
>> used against me in the future)
> 
> For the record, I didn't use anything against *you*. I'd just like
> consistency over how defconfig rules are applied.

True, apologies if it seemed to harsh. I meant the discussion, so maybe
better:
"Maxime used such argument with discussion with me, so I want to be sure
there is no silent ack from me in the future."

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Wed Feb 21 07:53:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 16:53:26 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <724jnhrbs6r4q6whynr3aon5w7mhfvetlgcnts4nukvtxbuium@mrjv6apjqk7r>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
 <56625c21-1b34-479b-b5b2-4c4d8b7a11b3@app.fastmail.com>
 <724jnhrbs6r4q6whynr3aon5w7mhfvetlgcnts4nukvtxbuium@mrjv6apjqk7r>
Message-ID: <8ad96253-2053-4dc1-8dc1-d01d1fa36877@linaro.org>

On 21/02/2024 16:51, Maxime Ripard wrote:
>>> Sure, but you're not just arguing for XFS there.
>>>
>>> What I really don't get is this: this makes the life of people easier.
>>>
>>> Being able to test an upstream kernel quickly when you have a bug in a
>>> downstream distro is super valuable for any distro developper. And on
>>> the long run, if we don't make the switch from a kernel distro to a
>>> mainline kernel relatively easy, we're the ones that will lose out.
>>> Because people just won't bother, or be frustrated and thus super
>>> reluctant to do that work.
>>
>> We had previously discussed adding config fragments for common
>> distros the way we have kvm_guest.config, but if the Javier's
>> patch is all that is actually needed for Fedora, that seems better
>> to me than the added complexity of fragments.
> 
> Oh, right. Fragments would be a great tool to reconcile the need for
> minimal boot time and supporting reasonable use-cases.
> 
> I guess it's even more of a struggle with the single arm64 defconfig vs
> the minimal vs batteries included defconfig setup we had for arm.

It would be cool to group also all the per-SoC needs in dedicated
fragments...

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Wed Feb 21 07:50:33 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Wed, 21 Feb 2024 16:50:33 +0100
Subject: [PATCH] arm64: defconfig: drop ext2 filesystem and redundant ext3
Message-ID: <20240221155033.44160-1-krzysztof.kozlowski@linaro.org>

ext4 filesystem can mount ext2, so drop CONFIG_EXT2_FS to make builds a
bit faster.  Drop also redundant CONFIG_EXT3_FS, because it just
selectes EXT4_FS.

Suggested-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 arch/arm64/configs/defconfig | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e6cf3e5d63c3..08a4a3102f08 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1571,8 +1571,7 @@ CONFIG_RZ_MTU3_CNT=m
 CONFIG_HTE=y
 CONFIG_HTE_TEGRA194=y
 CONFIG_HTE_TEGRA194_TEST=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_BTRFS_FS=m
 CONFIG_BTRFS_FS_POSIX_ACL=y
-- 
2.34.1



From bmasney at redhat.com  Wed Feb 21 07:56:20 2024
From: bmasney at redhat.com (Brian Masney)
Date: Wed, 21 Feb 2024 10:56:20 -0500
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <8ad96253-2053-4dc1-8dc1-d01d1fa36877@linaro.org>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
 <56625c21-1b34-479b-b5b2-4c4d8b7a11b3@app.fastmail.com>
 <724jnhrbs6r4q6whynr3aon5w7mhfvetlgcnts4nukvtxbuium@mrjv6apjqk7r>
 <8ad96253-2053-4dc1-8dc1-d01d1fa36877@linaro.org>
Message-ID: <ZdYdJILy9_anIsrr@x1>

On Wed, Feb 21, 2024 at 04:53:26PM +0100, Krzysztof Kozlowski wrote:
> It would be cool to group also all the per-SoC needs in dedicated
> fragments...

It would also be nice to have a fragment to enable the various tracing
options.

Brian



From theo.lebrun at bootlin.com  Wed Feb 21 07:57:04 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 21 Feb 2024 16:57:04 +0100
Subject: [PATCH 13/23] gpio: nomadik: fix offset bug in nmk_pmx_set()
In-Reply-To: <CAMRc=MdwAQUgc=LP45r-j0UCtN1gzPg9_y3hrbQhCyH91D=W-g@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-13-f88c0ccf372b@bootlin.com>
 <CAMRc=MdwAQUgc=LP45r-j0UCtN1gzPg9_y3hrbQhCyH91D=W-g@mail.gmail.com>
Message-ID: <CZAVP96SON5X.2KDT24P963WZ9@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 4:54 PM CET, Bartosz Golaszewski wrote:
> On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
> >
> > Previously, the statement looked like:
> >
> >     slpm[x] &= ~BIT(g->pins[i]);
> >
> > Where:
> >  - slpm is a unsigned int pointer;
> >  - g->pins[i] is a pin number which can grow to more than 32.
> >
> > The expected shift amount is a pin bank offset.
> >
> > This bug does not occur on every group or pin: the altsetting must be
> > NMK_GPIO_ALT_C and the pin must be 32 or above. It is possible that it
> > occurred. For example, in pinctrl-nomadik-db8500.c, pin group i2c3_c_2
> > has the right altsetting and has pins 229 and 230.
> >
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
>
> Maybe add a Fixes: tag and put it at the beginning of the series so
> that it can go upstream earlier as a fix?

I'll see how it works out because the fix depends on helpers added in
this series. I'll be reworking that.

Regards,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From alexander.sverdlin at siemens.com  Wed Feb 21 07:45:51 2024
From: alexander.sverdlin at siemens.com (A. Sverdlin)
Date: Wed, 21 Feb 2024 16:45:51 +0100
Subject: [PATCH 2/2] ARM: AM33xx: PRM: Implement REBOOT_COLD
In-Reply-To: <20240221154614.3549951-1-alexander.sverdlin@siemens.com>
References: <20240221154614.3549951-1-alexander.sverdlin@siemens.com>
Message-ID: <20240221154614.3549951-2-alexander.sverdlin@siemens.com>

From: Alexander Sverdlin <alexander.sverdlin at siemens.com>

Historically AM33xx performed warm software reset even though requested
(and default) was REBOOT_COLD. Reflect the de-facto default mode in
/sys/kernel/reboot/mode correctly and implement the real REBOOT_COLD
(if configured explicitly).

Tested-by: Matthias Michel <matthias.michel at siemens.com>
Signed-off-by: Alexander Sverdlin <alexander.sverdlin at siemens.com>
---
 arch/arm/mach-omap2/am33xx-restart.c   |  3 ++-
 arch/arm/mach-omap2/board-generic.c    |  6 ++++++
 arch/arm/mach-omap2/prm-regbits-33xx.h |  1 +
 arch/arm/mach-omap2/prm.h              |  1 +
 arch/arm/mach-omap2/prm33xx.c          | 18 ++++++++++++++----
 arch/arm/mach-omap2/prm_common.c       |  6 ++++++
 6 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/am33xx-restart.c b/arch/arm/mach-omap2/am33xx-restart.c
index ef2f18a56b658..199845f4b12e4 100644
--- a/arch/arm/mach-omap2/am33xx-restart.c
+++ b/arch/arm/mach-omap2/am33xx-restart.c
@@ -18,7 +18,8 @@
  */
 void am33xx_restart(enum reboot_mode mode, const char *cmd)
 {
-	/* TODO: Handle mode and cmd if necessary */
+	/* TODO: Handle cmd if necessary */
+	prm_reboot_mode = mode;
 
 	omap_prm_reset_system();
 }
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index fde6ccb3df6eb..68e0baad2bbf6 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -246,6 +246,12 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
 	.init_time	= omap_init_time_of,
 	.dt_compat	= am33xx_boards_compat,
 	.restart	= am33xx_restart,
+	/*
+	 * Historically am33xx supported only REBOOT_WARM even though default
+	 * reboot_mode was REBOOT_COLD. Reflect legacy de-facto behaviour in
+	 * SYSFS.
+	 */
+	.reboot_mode	= REBOOT_WARM,
 MACHINE_END
 #endif
 
diff --git a/arch/arm/mach-omap2/prm-regbits-33xx.h b/arch/arm/mach-omap2/prm-regbits-33xx.h
index 3748c5266ae12..9b97f8c76cd17 100644
--- a/arch/arm/mach-omap2/prm-regbits-33xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-33xx.h
@@ -15,6 +15,7 @@
 #define AM33XX_GFX_MEM_STATEST_MASK			(0x3 << 4)
 #define AM33XX_GLOBAL_WARM_SW_RST_MASK			(1 << 1)
 #define AM33XX_RST_GLOBAL_WARM_SW_MASK			(1 << 0)
+#define AM33XX_RST_GLOBAL_COLD_SW_MASK			(1 << 1)
 #define AM33XX_PRUSS_MEM_ONSTATE_MASK			(0x3 << 5)
 #define AM33XX_PRUSS_MEM_RETSTATE_MASK			(1 << 7)
 #define AM33XX_PRUSS_MEM_STATEST_MASK			(0x3 << 23)
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index fc45a7ed09bb3..fc53a27eed013 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -15,6 +15,7 @@
 # ifndef __ASSEMBLER__
 extern struct omap_domain_base prm_base;
 extern u16 prm_features;
+extern enum reboot_mode prm_reboot_mode;
 int omap_prcm_init(void);
 int omap2_prcm_base_init(void);
 # endif
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 4a462310a4b09..505d685d6792e 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/reboot.h>
 
 #include "powerdomain.h"
 #include "prm33xx.h"
@@ -318,10 +319,19 @@ static int am33xx_check_vcvp(void)
  *
  * Immediately reboots the device through warm reset.
  */
-static void am33xx_prm_global_warm_sw_reset(void)
+static void am33xx_prm_global_sw_reset(void)
 {
-	am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK,
-				AM33XX_RST_GLOBAL_WARM_SW_MASK,
+	/*
+	 * Historically AM33xx performed warm reset for all requested reboot_mode.
+	 * Keep this behaviour unchanged for all except newly added REBOOT_COLD.
+	 */
+	u32 mask = AM33XX_RST_GLOBAL_WARM_SW_MASK;
+
+	if (prm_reboot_mode == REBOOT_COLD)
+		mask = AM33XX_RST_GLOBAL_COLD_SW_MASK;
+
+	am33xx_prm_rmw_reg_bits(mask,
+				mask,
 				AM33XX_PRM_DEVICE_MOD,
 				AM33XX_PRM_RSTCTRL_OFFSET);
 
@@ -382,7 +392,7 @@ static struct prm_ll_data am33xx_prm_ll_data = {
 	.assert_hardreset		= am33xx_prm_assert_hardreset,
 	.deassert_hardreset		= am33xx_prm_deassert_hardreset,
 	.is_hardreset_asserted		= am33xx_prm_is_hardreset_asserted,
-	.reset_system			= am33xx_prm_global_warm_sw_reset,
+	.reset_system			= am33xx_prm_global_sw_reset,
 };
 
 int __init am33xx_prm_init(const struct omap_prcm_init_data *data)
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index fd896f2295a11..f8771bdb5f068 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -66,6 +66,12 @@ struct omap_domain_base prm_base;
 
 u16 prm_features;
 
+/*
+ * Platforms that implement different reboot modes can store the requested
+ * mode here.
+ */
+enum reboot_mode prm_reboot_mode;
+
 /*
  * prm_ll_data: function pointers to SoC-specific implementations of
  * common PRM functions
-- 
2.43.0



From arnd at arndb.de  Wed Feb 21 07:58:29 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 21 Feb 2024 16:58:29 +0100
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <CAMuHMdXNyU0eBcMe3EhhfahcRo2KtXzwdr+d_6AC-2529R3bmQ@mail.gmail.com>
References: <20240221092826.748e70c4@canb.auug.org.au>
 <CAL_JsqKw9OXb=aOMni1qprzeWDBgmjdJef-6VAjwx0R--D+URw@mail.gmail.com>
 <ac9ddf79-6bc9-4daf-a271-82f8b3bca988@app.fastmail.com>
 <CAL_Jsq+L7uPimQfATs14EWCbqRO1vxDUmPie7=cChTLCf2od2g@mail.gmail.com>
 <CAMuHMdXNyU0eBcMe3EhhfahcRo2KtXzwdr+d_6AC-2529R3bmQ@mail.gmail.com>
Message-ID: <7178ea35-da8d-4f25-9193-78dd11902eef@app.fastmail.com>

On Wed, Feb 21, 2024, at 15:51, Geert Uytterhoeven wrote:
> On Wed, Feb 21, 2024 at 3:27?PM Rob Herring <robh at kernel.org> wrote:
>> On Wed, Feb 21, 2024 at 7:00?AM Arnd Bergmann <arnd at arndb.de> wrote:
>> > On Wed, Feb 21, 2024, at 14:53, Rob Herring wrote:
>> > > On Tue, Feb 20, 2024 at 3:28?PM Stephen Rothwell <sfr at canb.auug.org.au> wrote:
>> > >> arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
>> > >>
>> > >> Introduced/exposed by commit
>> > >>
>> > >>   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
>> > >>
>> > >> I guess you missed some :-(
>> > >
>> > > No, Geert separately posted fixes for already.
>> >
>> > I did make the mistake of applying the final patch "dtc:
>> > Enable dtc interrupt_provider check" to the arm/fixes branch
>> > for 6.8 along with the other fixes.
>> >
>> > Clearly that should be separate and only go into mainline
>> > after there are no more regressions, but now I'm unsure
>> > about the other patches -- did you intend the dts fixes
>> > for 6.8 or for the coming merge window?
>>
>> Either is fine with me. My intent was the whole series plus the
>> Renesas fix to be applied together. Anything new that crops up we can
>> fix on top.
>
> If you want me to move commit b4f97d1b5aeb6166 ("ARM: dts: renesas:
> rcar-gen2: Add missing #interrupt-cells to DA9063 nodes") to
> renesas-fixes, please tell me.

Up to you. I have done some merges yesterday but have not started
merging the dt branches, so you can still send an updated v2
if you prefer (or have this patch in both branches). Please
let me know how you decide.

I have now dropped the Makefile.lib patch from the arm/fixes
branch (it was the top patch, so I did not need to rebase)
and plan to apply it on top of the soc/dt branch instead.

     Arnd


From mwalle at kernel.org  Wed Feb 21 07:59:04 2024
From: mwalle at kernel.org (Michael Walle)
Date: Wed, 21 Feb 2024 16:59:04 +0100
Subject: [PATCH v3 1/2] dt-bindings: arm64: mediatek: add Kontron 3.5"-SBC-i1200
Message-ID: <20240221155905.1217340-1-mwalle@kernel.org>

Add the compatible string for the Kontron 3.5"-SBC-i1200 single board
computer.

Signed-off-by: Michael Walle <mwalle at kernel.org>
---
v3:
 - drop description and add to mt8395 existing entry

v2:
 - convert enum to const as there is only one specific board
---
 Documentation/devicetree/bindings/arm/mediatek.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 09f9ffd3ff7b..29ebe1f9c1d2 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -353,6 +353,7 @@ properties:
           - const: mediatek,mt8365
       - items:
           - enum:
+              - kontron,3-5-sbc-i1200
               - mediatek,mt8395-evk
               - radxa,nio-12l
           - const: mediatek,mt8395
-- 
2.39.2



From mwalle at kernel.org  Wed Feb 21 07:59:05 2024
From: mwalle at kernel.org (Michael Walle)
Date: Wed, 21 Feb 2024 16:59:05 +0100
Subject: [PATCH v3 2/2] arm64: dts: mediatek: add Kontron 3.5"-SBC-i1200
In-Reply-To: <20240221155905.1217340-1-mwalle@kernel.org>
References: <20240221155905.1217340-1-mwalle@kernel.org>
Message-ID: <20240221155905.1217340-2-mwalle@kernel.org>

Add basic support for the Kontron 3.5" single board computer featuring a
Mediatek i1200 SoC (MT8395/MT8195).

Signed-off-by: Michael Walle <mwalle at kernel.org>
---
v3:
- add vsys regulator
- correct the LDO input of the mt6360 regulator
- add missing interrupt-cells
- no underscores in node names
- dropped regulator-compatible everywhere and use the correc node name
  instead
- reordered mmc0 properties
- split mmc1 pinctrl properties, add no-mmc
- removed all MTK_DRIVE_8mA
- add i2c0 and i2c1
- add comments for spi and i2c busses
- add firmware-name property for scp (this should probably go into the
  base dtsi?!)
- add missing tpm compatible
- renamed thermal zones to something more meaningful
- add correct bias-pull-up to (some) i2c busses
- moved reset handling into the PHY node, also added a compatible string
  for the PHY.

Mh, my memory is hazy, but IIRC I run into the same problem which was
discussed on netdev some time ago. That is, the PHY driver cannot be
probed unless it is taken out of reset. Which will only happen if you
probe it. And the workaround/advise was to use the compatible string in
that case, which is unfortunate.
Just wanted to point out, that it is *not* the same as snps,reset-*
because the latter will work just fine without the compatible. I'll
go with the compatible for now.

I did *not* add the vbus to the USB ports, not even on the front port.
That is because of:
  dependencies:
    connector: [ usb-role-switch ]
and we just have a simple USB3.2 USB-A connector, no dual roles. IMHO
that is a bug in the driver, which should handle the vbus supply as
optional.

v2:
- none
---
 arch/arm64/boot/dts/mediatek/Makefile         |    1 +
 .../mediatek/mt8395-kontron-3-5-sbc-i1200.dts | 1127 +++++++++++++++++
 2 files changed, 1128 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 37b4ca3a87c9..697b6b5de3cb 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -76,5 +76,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-demo.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8365-evk.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-genio-1200-evk.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-kontron-3-5-sbc-i1200.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8395-radxa-nio-12l.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts b/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
new file mode 100644
index 000000000000..e4b2af9489a8
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8395-kontron-3-5-sbc-i1200.dts
@@ -0,0 +1,1127 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2024 Kontron Europe GmbH
+ *
+ * Author: Michael Walle <mwalle at kernel.org>
+ */
+/dts-v1/;
+
+#include "mt8195.dtsi"
+#include "mt6359.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
+#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+	model = "Kontron 3.5\"-SBC-i1200";
+	compatible = "kontron,3-5-sbc-i1200", "mediatek,mt8395", "mediatek,mt8195";
+
+	aliases {
+		mmc0 = &mmc0;
+		mmc1 = &mmc1;
+		serial0 = &uart1;
+		serial1 = &uart2;
+		serial2 = &uart3;
+		serial3 = &uart4;
+		serial4 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	firmware {
+		optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_keys_pins>;
+
+		key-0 {
+			gpios = <&pio 106 GPIO_ACTIVE_LOW>;
+			label = "volume_up";
+			linux,code = <KEY_VOLUMEUP>;
+			wakeup-source;
+			debounce-interval = <15>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins>;
+
+		led-0 {
+			gpios = <&pio 107 GPIO_ACTIVE_HIGH>;
+			default-state = "keep";
+			function = LED_FUNCTION_POWER;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+	};
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0x0 0x80000000>;
+	};
+
+	vsys: regulator-vsys {
+		compatible = "regulator-fixed";
+		regulator-name = "vsys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/*
+		 * 12 MiB reserved for OP-TEE (BL32)
+		 * +-----------------------+ 0x43e0_0000
+		 * |      SHMEM 2MiB       |
+		 * +-----------------------+ 0x43c0_0000
+		 * |        | TA_RAM  8MiB |
+		 * + TZDRAM +--------------+ 0x4340_0000
+		 * |        | TEE_RAM 2MiB |
+		 * +-----------------------+ 0x4320_0000
+		 */
+		optee_reserved: optee at 43200000 {
+			no-map;
+			reg = <0 0x43200000 0 0x00c00000>;
+		};
+
+		scp_mem: memory at 50000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x50000000 0 0x2900000>;
+			no-map;
+		};
+
+		vpu_mem: memory at 53000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x53000000 0 0x1400000>; /* 20 MB */
+		};
+
+		/* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+		bl31_secmon_mem: memory at 54600000 {
+			no-map;
+			reg = <0 0x54600000 0x0 0x200000>;
+		};
+
+		snd_dma_mem: memory at 60000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x60000000 0 0x1100000>;
+			no-map;
+		};
+
+		apu_mem: memory at 62000000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x62000000 0 0x1400000>; /* 20 MB */
+		};
+	};
+
+	thermal_sensor0: thermal-sensor-0 {
+		compatible = "generic-adc-thermal";
+		#thermal-sensor-cells = <0>;
+		io-channels = <&auxadc 0>;
+		io-channel-names = "sensor-channel";
+		temperature-lookup-table = <(-25000) 1474
+					    (-20000) 1374
+					    (-15000) 1260
+					    (-10000) 1134
+					     (-5000) 1004
+						   0 874
+						5000 750
+					       10000 635
+					       15000 532
+					       20000 443
+					       25000 367
+					       30000 303
+					       35000 250
+					       40000 206
+					       45000 170
+					       50000 141
+					       55000 117
+					       60000 97
+					       65000 81
+					       70000 68
+					       75000 57
+					       80000 48
+					       85000 41
+					       90000 35
+					       95000 30
+					      100000 25
+					      105000 22
+					      110000 19
+					      115000 16
+					      120000 14
+					      125000 12
+					      130000 10
+					      135000 9
+					      140000 8
+					      145000 7
+					      150000 6>;
+	};
+
+	thermal_sensor1: thermal-sensor-1 {
+		compatible = "generic-adc-thermal";
+		#thermal-sensor-cells = <0>;
+		io-channels = <&auxadc 1>;
+		io-channel-names = "sensor-channel";
+		temperature-lookup-table = <(-25000) 1474
+					    (-20000) 1374
+					    (-15000) 1260
+					    (-10000) 1134
+					     (-5000) 1004
+						   0 874
+						5000 750
+					       10000 635
+					       15000 532
+					       20000 443
+					       25000 367
+					       30000 303
+					       35000 250
+					       40000 206
+					       45000 170
+					       50000 141
+					       55000 117
+					       60000 97
+					       65000 81
+					       70000 68
+					       75000 57
+					       80000 48
+					       85000 41
+					       90000 35
+					       95000 30
+					      100000 25
+					      105000 22
+					      110000 19
+					      115000 16
+					      120000 14
+					      125000 12
+					      130000 10
+					      135000 9
+					      140000 8
+					      145000 7
+					      150000 6>;
+	};
+
+	thermal_sensor2: thermal-sensor-2 {
+		compatible = "generic-adc-thermal";
+		#thermal-sensor-cells = <0>;
+		io-channels = <&auxadc 2>;
+		io-channel-names = "sensor-channel";
+		temperature-lookup-table = <(-25000) 1474
+					    (-20000) 1374
+					    (-15000) 1260
+					    (-10000) 1134
+					     (-5000) 1004
+						   0 874
+						5000 750
+					       10000 635
+					       15000 532
+					       20000 443
+					       25000 367
+					       30000 303
+					       35000 250
+					       40000 206
+					       45000 170
+					       50000 141
+					       55000 117
+					       60000 97
+					       65000 81
+					       70000 68
+					       75000 57
+					       80000 48
+					       85000 41
+					       90000 35
+					       95000 30
+					      100000 25
+					      105000 22
+					      110000 19
+					      115000 16
+					      120000 14
+					      125000 12
+					      130000 10
+					      135000 9
+					      140000 8
+					      145000 7
+					      150000 6>;
+	};
+};
+
+&auxadc {
+	status = "okay";
+};
+
+&eth {
+	phy-mode ="rgmii-id";
+	phy-handle = <&ethernet_phy0>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&eth_default_pins>;
+	pinctrl-1 = <&eth_sleep_pins>;
+	status = "okay";
+
+	mdio {
+		ethernet_phy0: ethernet-phy at 1 {
+			compatible = "ethernet-phy-id001c.c916";
+			reg = <0x1>;
+			interrupts-extended = <&pio 94 IRQ_TYPE_LEVEL_LOW>;
+			reset-assert-us = <10000>;
+			reset-deassert-us = <80000>;
+			reset-gpios = <&pio 93 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpu {
+	status = "okay";
+	mali-supply = <&mt6315_7_vbuck1>;
+};
+
+/* CSI1/CSI2 connector */
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+/* CSI3 connector */
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	/* LVDS bridge @f */
+};
+
+/* Touch panel connector */
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_pins>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+/* B2B connector */
+&i2c4 {
+	clock-frequency = <100000>;
+	pinctrl-0 = <&i2c4_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&i2c6 {
+	clock-frequency = <400000>;
+	pinctrl-0 = <&i2c6_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	mt6360: pmic at 34 {
+		compatible = "mediatek,mt6360";
+		reg = <0x34>;
+		interrupt-controller;
+		interrupts-extended = <&pio 101 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-names = "IRQB";
+		#interrupt-cells = <1>;
+
+		regulator {
+			compatible = "mediatek,mt6360-regulator";
+			LDO_VIN1-supply = <&vsys>;
+			LDO_VIN2-supply = <&vsys>;
+			LDO_VIN3-supply = <&vsys>;
+
+			mt6360_buck1: BUCK1 {
+				regulator-name = "emi_vdd2";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP
+							   MT6360_OPMODE_ULP>;
+				regulator-always-on;
+			};
+
+			mt6360_buck2: BUCK2 {
+				regulator-name = "emi_vddq";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP
+							   MT6360_OPMODE_ULP>;
+				regulator-always-on;
+			};
+
+			mt6360_ldo1: LDO1 {
+				regulator-name = "mt6360_ldo1"; /* Test point */
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo2: LDO2 {
+				regulator-name = "panel1_p1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo3: LDO3 {
+				regulator-name = "vmc_pmu";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo5: LDO5 {
+				regulator-name = "vmch_pmu";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo6: LDO6 {
+				regulator-name = "mt6360_ldo6"; /* Test point */
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+			};
+
+			mt6360_ldo7: LDO7 {
+				regulator-name = "emi_vmddr_en";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+							   MT6360_OPMODE_LP>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc0_default_pins>;
+	pinctrl-1 = <&mmc0_uhs_pins>;
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	hs400-ds-delay = <0x14c11>;
+	cap-mmc-highspeed;
+	cap-mmc-hw-reset;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	no-sdio;
+	no-sd;
+	non-removable;
+	vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
+	vqmmc-supply = <&mt6359_vufs_ldo_reg>;
+	status = "okay";
+};
+
+&mmc1 {
+	pinctrl-names = "default", "state_uhs";
+	pinctrl-0 = <&mmc1_default_pins>, <&mmc1_detect_pins>;
+	pinctrl-1 = <&mmc1_default_pins>;
+	cd-gpios = <&pio 129 GPIO_ACTIVE_LOW>;
+	bus-width = <4>;
+	max-frequency = <200000000>;
+	cap-sd-highspeed;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	no-mmc;
+	vmmc-supply = <&mt6360_ldo5>;
+	vqmmc-supply = <&mt6360_ldo3>;
+	status = "okay";
+};
+
+&mt6359_vbbck_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vcore_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vgpu11_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vproc1_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vproc2_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vpu_buck_reg {
+	regulator-always-on;
+};
+
+&mt6359_vrf12_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vsram_md_ldo_reg {
+	regulator-always-on;
+};
+
+&mt6359_vsram_others_ldo_reg {
+	regulator-always-on;
+};
+
+&nor_flash {
+	pinctrl-names = "default";
+	pinctrl-0 = <&nor_pins_default>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <52000000>;
+		spi-rx-bus-width = <2>;
+		spi-tx-bus-width = <2>;
+	};
+};
+
+&pcie0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_pins_default>;
+	status = "okay";
+};
+
+&pcie1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_pins_default>;
+	status = "okay";
+};
+
+&pciephy {
+	status = "okay";
+};
+
+&pio {
+	eth_default_pins: eth-default-pins {
+		pins-txd {
+			pinmux = <PINMUX_GPIO77__FUNC_GBE_TXD3>,
+				 <PINMUX_GPIO78__FUNC_GBE_TXD2>,
+				 <PINMUX_GPIO79__FUNC_GBE_TXD1>,
+				 <PINMUX_GPIO80__FUNC_GBE_TXD0>;
+			drive-strength = <8>;
+		};
+
+		pins-rxd {
+			pinmux = <PINMUX_GPIO81__FUNC_GBE_RXD3>,
+				 <PINMUX_GPIO82__FUNC_GBE_RXD2>,
+				 <PINMUX_GPIO83__FUNC_GBE_RXD1>,
+				 <PINMUX_GPIO84__FUNC_GBE_RXD0>;
+		};
+
+		pins-cc {
+			pinmux = <PINMUX_GPIO85__FUNC_GBE_TXC>,
+				 <PINMUX_GPIO86__FUNC_GBE_RXC>,
+				 <PINMUX_GPIO87__FUNC_GBE_RXDV>,
+				 <PINMUX_GPIO88__FUNC_GBE_TXEN>;
+			drive-strength = <8>;
+		};
+
+		pins-mdio {
+			pinmux = <PINMUX_GPIO89__FUNC_GBE_MDC>,
+				 <PINMUX_GPIO90__FUNC_GBE_MDIO>;
+			input-enable;
+		};
+
+		pins-power {
+			pinmux = <PINMUX_GPIO91__FUNC_GPIO91>,
+				 <PINMUX_GPIO92__FUNC_GPIO92>;
+			output-high;
+		};
+
+		pins-reset {
+			pinmux = <PINMUX_GPIO93__FUNC_GPIO93>;
+			output-high;
+		};
+
+		pins-interrupt {
+			pinmux = <PINMUX_GPIO94__FUNC_GPIO94>;
+			input-enable;
+		};
+	};
+
+	eth_sleep_pins: eth-sleep-pins {
+		pins-txd {
+			pinmux = <PINMUX_GPIO77__FUNC_GPIO77>,
+				 <PINMUX_GPIO78__FUNC_GPIO78>,
+				 <PINMUX_GPIO79__FUNC_GPIO79>,
+				 <PINMUX_GPIO80__FUNC_GPIO80>;
+		};
+
+		pins-cc {
+			pinmux = <PINMUX_GPIO85__FUNC_GPIO85>,
+				 <PINMUX_GPIO88__FUNC_GPIO88>,
+				 <PINMUX_GPIO87__FUNC_GPIO87>,
+				 <PINMUX_GPIO86__FUNC_GPIO86>;
+		};
+
+		pins-rxd {
+			pinmux = <PINMUX_GPIO81__FUNC_GPIO81>,
+				 <PINMUX_GPIO82__FUNC_GPIO82>,
+				 <PINMUX_GPIO83__FUNC_GPIO83>,
+				 <PINMUX_GPIO84__FUNC_GPIO84>;
+		};
+
+		pins-mdio {
+			pinmux = <PINMUX_GPIO89__FUNC_GPIO89>,
+				 <PINMUX_GPIO90__FUNC_GPIO90>;
+			input-disable;
+			bias-disable;
+		};
+	};
+
+	gpio_keys_pins: gpio-keys-pins {
+		pins {
+			pinmux = <PINMUX_GPIO106__FUNC_GPIO106>;
+			input-enable;
+		};
+	};
+
+	i2c0_pins: i2c0-pins {
+		pins {
+			pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
+				 <PINMUX_GPIO9__FUNC_SCL0>;
+			bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+			drive-strength-microamp = <1000>;
+		};
+	};
+
+	i2c1_pins: i2c1-pins {
+		pins {
+			pinmux = <PINMUX_GPIO10__FUNC_SDA1>,
+				 <PINMUX_GPIO11__FUNC_SCL1>;
+			bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+			drive-strength-microamp = <1000>;
+		};
+	};
+
+	i2c2_pins: i2c2-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
+				 <PINMUX_GPIO13__FUNC_SCL2>;
+			bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+			drive-strength-microamp = <1000>;
+		};
+	};
+
+	i2c3_pins: i2c3-pins {
+		pins {
+			pinmux = <PINMUX_GPIO14__FUNC_SDA3>,
+				 <PINMUX_GPIO15__FUNC_SCL3>;
+			bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+			drive-strength-microamp = <1000>;
+		};
+	};
+
+	i2c4_pins: i2c4-pins {
+		pins {
+			pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
+				 <PINMUX_GPIO17__FUNC_SCL4>;
+			bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+			drive-strength-microamp = <1000>;
+		};
+	};
+
+	i2c6_pins: i2c6-pins {
+		pins {
+			pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
+				 <PINMUX_GPIO26__FUNC_SCL6>;
+			bias-pull-up;
+			drive-strength-microamp = <1000>;
+		};
+	};
+
+	mmc0_default_pins: mmc0-default-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+			drive-strength = <6>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+				 <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+				 <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+				 <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+				 <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+				 <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+				 <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+				 <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+				 <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+			input-enable;
+			drive-strength = <6>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins-rst {
+			pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+			drive-strength = <6>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	mmc0_uhs_pins: mmc0-uhs-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+			drive-strength = <8>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
+				 <PINMUX_GPIO125__FUNC_MSDC0_DAT1>,
+				 <PINMUX_GPIO124__FUNC_MSDC0_DAT2>,
+				 <PINMUX_GPIO123__FUNC_MSDC0_DAT3>,
+				 <PINMUX_GPIO119__FUNC_MSDC0_DAT4>,
+				 <PINMUX_GPIO118__FUNC_MSDC0_DAT5>,
+				 <PINMUX_GPIO117__FUNC_MSDC0_DAT6>,
+				 <PINMUX_GPIO116__FUNC_MSDC0_DAT7>,
+				 <PINMUX_GPIO121__FUNC_MSDC0_CMD>;
+			input-enable;
+			drive-strength = <8>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins-ds {
+			pinmux = <PINMUX_GPIO127__FUNC_MSDC0_DSL>;
+			drive-strength = <8>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-rst {
+			pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+			drive-strength = <8>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	mmc1_default_pins: mmc1-default-pins {
+		pins-clk {
+			pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
+			drive-strength = <8>;
+			bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+		};
+
+		pins-cmd-dat {
+			pinmux = <PINMUX_GPIO110__FUNC_MSDC1_CMD>,
+				 <PINMUX_GPIO112__FUNC_MSDC1_DAT0>,
+				 <PINMUX_GPIO113__FUNC_MSDC1_DAT1>,
+				 <PINMUX_GPIO114__FUNC_MSDC1_DAT2>,
+				 <PINMUX_GPIO115__FUNC_MSDC1_DAT3>;
+			input-enable;
+			drive-strength = <8>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	mmc1_detect_pins: mmc1-detect-pins {
+		pins-insert {
+			pinmux = <PINMUX_GPIO129__FUNC_GPIO129>;
+			bias-pull-up;
+		};
+	};
+
+	nor_pins_default: nor-default-pins {
+		pins-ck-io {
+			pinmux = <PINMUX_GPIO142__FUNC_SPINOR_IO0>,
+				 <PINMUX_GPIO141__FUNC_SPINOR_CK>,
+				 <PINMUX_GPIO143__FUNC_SPINOR_IO1>;
+			drive-strength = <6>;
+			bias-pull-down;
+		};
+
+		pins-cs {
+			pinmux = <PINMUX_GPIO140__FUNC_SPINOR_CS>;
+			drive-strength = <6>;
+			bias-pull-up;
+		};
+	};
+
+	pcie0_pins_default: pcie0-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO19__FUNC_WAKEN>,
+				 <PINMUX_GPIO20__FUNC_PERSTN>,
+				 <PINMUX_GPIO21__FUNC_CLKREQN>;
+			bias-pull-up;
+		};
+	};
+
+	pcie1_pins_default: pcie1-default-pins {
+		pins-bus {
+			pinmux = <PINMUX_GPIO0__FUNC_PERSTN_1>,
+				 <PINMUX_GPIO1__FUNC_CLKREQN_1>,
+				 <PINMUX_GPIO2__FUNC_WAKEN_1>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	led_pins: led-pins {
+		pins-power-en {
+			pinmux = <PINMUX_GPIO107__FUNC_GPIO107>;
+			output-high;
+		};
+	};
+
+	spi0_pins: spi0-default-pins {
+		pins-cs-mosi-clk {
+			pinmux = <PINMUX_GPIO132__FUNC_SPIM0_CSB>,
+				 <PINMUX_GPIO134__FUNC_SPIM0_MO>,
+				 <PINMUX_GPIO133__FUNC_SPIM0_CLK>;
+			bias-disable;
+		};
+
+		pins-miso {
+			pinmux = <PINMUX_GPIO135__FUNC_SPIM0_MI>;
+			bias-pull-down;
+		};
+	};
+
+	spi1_pins: spi1-default-pins {
+		pins-cs-mosi-clk {
+			pinmux = <PINMUX_GPIO136__FUNC_SPIM1_CSB>,
+				 <PINMUX_GPIO138__FUNC_SPIM1_MO>,
+				 <PINMUX_GPIO137__FUNC_SPIM1_CLK>;
+			bias-disable;
+		};
+
+		pins-miso {
+			pinmux = <PINMUX_GPIO139__FUNC_SPIM1_MI>;
+			bias-pull-down;
+		};
+	};
+
+	uart0_pins: uart0-pins {
+		pins-rx {
+			pinmux = <PINMUX_GPIO99__FUNC_URXD0>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins-tx {
+			pinmux = <PINMUX_GPIO98__FUNC_UTXD0>;
+		};
+	};
+
+	uart1_pins: uart1-pins {
+		pins-rx {
+			pinmux = <PINMUX_GPIO103__FUNC_URXD1>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins-tx {
+			pinmux = <PINMUX_GPIO102__FUNC_UTXD1>;
+		};
+
+		pins-rts {
+			pinmux = <PINMUX_GPIO100__FUNC_URTS1>;
+		};
+
+		pins-cts {
+			pinmux = <PINMUX_GPIO101__FUNC_UCTS1>;
+			input-enable;
+		};
+	};
+
+	uart2_pins: uart2-pins {
+		pins-rx {
+			pinmux = <PINMUX_GPIO68__FUNC_URXD2>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins-tx {
+			pinmux = <PINMUX_GPIO67__FUNC_UTXD2>;
+		};
+
+		pins-rts {
+			pinmux = <PINMUX_GPIO66__FUNC_URTS2>;
+		};
+
+		pins-cts {
+			pinmux = <PINMUX_GPIO65__FUNC_UCTS2>;
+			input-enable;
+		};
+	};
+
+	uart3_pins: uart3-pins {
+		pins-rx {
+			pinmux = <PINMUX_GPIO5__FUNC_URXD3>;
+			input-enable;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+
+		pins-tx {
+			pinmux = <PINMUX_GPIO4__FUNC_UTXD3>;
+		};
+	};
+
+	uart4_pins: uart4-pins {
+		pins-rx {
+			pinmux = <PINMUX_GPIO7__FUNC_URXD4>;
+			input-enable;
+			bias-pull-up;
+		};
+
+		pins-tx {
+			pinmux = <PINMUX_GPIO6__FUNC_UTXD4>;
+		};
+	};
+};
+
+&pmic {
+	interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&scp {
+	memory-region = <&scp_mem>;
+	firmware-name = "mediatek/mt8195/scp.img";
+	status = "okay";
+};
+
+&spmi {
+	#address-cells = <2>;
+	#size-cells = <0>;
+
+	mt6315 at 6 {
+		compatible = "mediatek,mt6315-regulator";
+		reg = <0x6 SPMI_USID>;
+
+		regulators {
+			mt6315_6_vbuck1: vbuck1 {
+				regulator-name = "Vbcpu";
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1193750>;
+				regulator-enable-ramp-delay = <256>;
+				regulator-ramp-delay = <6250>;
+				regulator-allowed-modes = <0 1 2>;
+				regulator-always-on;
+			};
+		};
+	};
+
+	mt6315 at 7 {
+		compatible = "mediatek,mt6315-regulator";
+		reg = <0x7 SPMI_USID>;
+
+		regulators {
+			mt6315_7_vbuck1: vbuck1 {
+				regulator-name = "Vgpu";
+				regulator-min-microvolt = <625000>;
+				regulator-max-microvolt = <1193750>;
+				regulator-enable-ramp-delay = <256>;
+				regulator-ramp-delay = <6250>;
+				regulator-allowed-modes = <0 1 2>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+/* USB3.2 front port */
+&ssusb0 {
+	dr_mode = "host";
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	status = "okay";
+};
+
+/* USB2.0 M.2 Key-E */
+&ssusb2 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	status = "okay";
+};
+
+/* USB2.0 to on-board usb hub */
+&ssusb3 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	status = "okay";
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_pins>;
+	mediatek,pad-select = <0>;
+	status = "okay";
+
+	tpm: tpm at 0 {
+		compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+		reg = <0>;
+		spi-max-frequency = <18500000>;
+	};
+};
+
+/* B2B connector */
+&spi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_pins>;
+	mediatek,pad-select = <0>;
+	status = "okay";
+};
+
+&thermal_zones {
+	cpu-thermal {
+		polling-delay = <1000>; /* milliseconds */
+		polling-delay-passive = <0>; /* milliseconds */
+		thermal-sensors = <&thermal_sensor0>;
+
+		trips {
+			trip-alert {
+				temperature = <85000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			trip-crit {
+				temperature = <95000>;
+				hysteresis = <2000>;
+				type = "critical";
+			};
+		};
+	};
+
+	pcb-top-thermal {
+		polling-delay = <1000>; /* milliseconds */
+		polling-delay-passive = <0>; /* milliseconds */
+		thermal-sensors = <&thermal_sensor1>;
+
+		trips {
+			trip-alert {
+				temperature = <75000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			trip-crit {
+				temperature = <85000>;
+				hysteresis = <2000>;
+				type = "critical";
+			};
+		};
+	};
+
+	pcb-bottom-thermal {
+		polling-delay = <1000>; /* milliseconds */
+		polling-delay-passive = <0>; /* milliseconds */
+		thermal-sensors = <&thermal_sensor2>;
+
+		trips {
+			trip-alert {
+				temperature = <75000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			trip-crit {
+				temperature = <85000>;
+				hysteresis = <2000>;
+				type = "critical";
+			};
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+	status = "okay";
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins>;
+	status = "okay";
+};
+
+/* USB3 */
+&u3phy0 {
+	status = "okay";
+};
+
+/* PCIe1/USB2 */
+&u3phy1 {
+	status = "okay";
+};
+
+/* USB2 */
+&u3phy2 {
+	status = "okay";
+};
+
+/* USB2 */
+&u3phy3 {
+	status = "okay";
+};
+
+/* USB3.2 front port */
+&xhci0 {
+	status = "okay";
+};
+
+/* USB2.0 M.2 Key-B */
+&xhci1 {
+	vusb33-supply = <&mt6359_vusb_ldo_reg>;
+	mediatek,u3p-dis-msk = <0x01>;
+	status = "okay";
+};
+
+/* USB2.0 M.2 Key-E */
+&xhci2 {
+	status = "okay";
+};
+
+/* USB2.0 to on-board usb hub */
+&xhci3 {
+	status = "okay";
+};
-- 
2.39.2



From florian.fainelli at broadcom.com  Wed Feb 21 08:01:02 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Wed, 21 Feb 2024 08:01:02 -0800
Subject: [PATCH v5 11/12] mtd: rawnand: brcmnand: exec_op helper functions
 return type fixes
In-Reply-To: <20240221093247.5297f1f3@xps-13>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-12-william.zhang@broadcom.com>
 <20240220110240.1ad5b995@xps-13>
 <f6e61482-b51a-4970-9257-8db7975148fa@moroto.mountain>
 <20240221093247.5297f1f3@xps-13>
Message-ID: <38a8b097-d5d1-433f-9735-512dce4b1b2e@broadcom.com>



On 2/21/2024 12:32 AM, 'Miquel Raynal' via BCM-KERNEL-FEEDBACK-LIST,PDL 
wrote:
> Hi,
> 
> dan.carpenter at linaro.org wrote on Wed, 21 Feb 2024 09:16:31 +0300:
> 
>> On Tue, Feb 20, 2024 at 11:02:40AM +0100, Miquel Raynal wrote:
>>>
>>> william.zhang at broadcom.com wrote on Wed,  7 Feb 2024 12:22:56 -0800:
>>>    
>>>> From: David Regan <dregan at broadcom.com>
>>>>
>>>> fix return type for exec_op reset and status detect helper functions
>>>>
>>>> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
>>>> Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
>>>> Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
>>>> Signed-off-by: David Regan <dregan at broadcom.com>
>>>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>>>> Reviewed-by: William Zhang <william.zhang at broadcom.com>
>>>
>>> By the way, a Cc: stable tag might be useful as otherwise you may leak
>>> an error code in a status value (which is a bug). And move this patch
>>> first in your series so we're sure it does not conflict with any of the
>>> other patches and can be backported more easily.
>>
>> The original commit 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op
>> implementation") is not in stable so we should be okay on this.
> 
> Right.
> 
> However please send again this patch quickly so I can queue it up
> before the rest of the series.

Also just to be clear, please do not omit the Fixes: tag, even if the 
commit being fixed is not yet in any released kernel, it is valuable to 
have that information, for say, people who might consider backporting 
features into specific kernel versions. The stable team's tooling should 
be able to figure out that it is not required to pick up that fix since 
the offending commit is not in a released kernel yet anyway.

Thanks!
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240221/718a8176/attachment.p7s>

From theo.lebrun at bootlin.com  Wed Feb 21 08:02:51 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 21 Feb 2024 17:02:51 +0100
Subject: [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from
 drivers/pinctrl/nomadik/
In-Reply-To: <CAMRc=MfXHbpq7vgw64pYGGAyQQnYyGa1ei5NAQ6swtH7o--R=w@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>
 <CAMRc=MfXHbpq7vgw64pYGGAyQQnYyGa1ei5NAQ6swtH7o--R=w@mail.gmail.com>
Message-ID: <CZAVTOOYBRY0.FH5RTPSXS8QN@bootlin.com>

Hello Bartosz,

On Mon Feb 19, 2024 at 5:08 PM CET, Bartosz Golaszewski wrote:
> On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
> >
> > Previously, drivers/pinctrl/nomadik/pinctrl-nomadik.c registered two
> > platform drivers: pinctrl & GPIO. Move the GPIO aspect to the
> > drivers/gpio/ folder, as would be expected.
> >
> > Both drivers are intertwined for a reason; pinctrl requires access to
> > GPIO registers for pinmuxing, pull-disable, disabling interrupts while
> > setting the muxing and wakeup control. Information sharing is done
> > through a shared array containing GPIO chips and a few helper
> > functions. That shared array is not touched from gpio-nomadik when
> > CONFIG_PINCTRL_NOMADIK is not defined.
> >
> > Make no change to the code that moved into gpio-nomadik; there should be
> > no behavior change following. A few functions are shared and header
> > comments are added. Checkpatch warnings are addressed. NUM_BANKS is
> > renamed to NMK_MAX_BANKS.
> >
> > It is supported to compile gpio-nomadik without pinctrl-nomadik. The
> > opposite is not true.
> >
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> > ---
> >  MAINTAINERS                                        |   1 +
> >  drivers/gpio/Kconfig                               |  12 +
> >  drivers/gpio/Makefile                              |   1 +
> >  drivers/gpio/gpio-nomadik.c                        | 660 +++++++++++++++++++
> >  drivers/pinctrl/nomadik/Kconfig                    |   5 +-
> >  drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c   |   3 +-
> >  drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c  |   3 +-
> >  drivers/pinctrl/nomadik/pinctrl-nomadik.c          | 722 +--------------------
> >  .../linux/gpio/gpio-nomadik.h                      | 122 +++-
> >  9 files changed, 804 insertions(+), 725 deletions(-)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 0cb2c459d1cf..3f864e773267 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2474,6 +2474,7 @@ F:        drivers/clk/clk-nomadik.c
> >  F:     drivers/clocksource/clksrc-dbx500-prcmu.c
> >  F:     drivers/dma/ste_dma40*
> >  F:     drivers/pmdomain/st/ste-ux500-pm-domain.c
> > +F:     drivers/gpio/gpio-nomadik.c
> >  F:     drivers/hwspinlock/u8500_hsem.c
> >  F:     drivers/i2c/busses/i2c-nomadik.c
> >  F:     drivers/iio/adc/ab8500-gpadc.c
> > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> > index 1301cec94f12..ff83371251c1 100644
> > --- a/drivers/gpio/Kconfig
> > +++ b/drivers/gpio/Kconfig
> > @@ -478,6 +478,18 @@ config GPIO_MXS
> >         select GPIO_GENERIC
> >         select GENERIC_IRQ_CHIP
> >
> > +config GPIO_NOMADIK
> > +       bool "Nomadik GPIO driver"
> > +       depends on ARCH_U8500 || ARCH_NOMADIK || COMPILE_TEST
> > +       select OF_GPIO
> > +       select GPIOLIB_IRQCHIP
> > +       help
> > +         Say yes here to support the Nomadik SoC GPIO block.
> > +
> > +         It handles up to 32 GPIOs per bank, that can all be interrupt sources.
> > +         It is deeply interconnected with the associated pinctrl driver as GPIO
> > +         registers handle muxing ("alternate functions") as well.
> > +
> >  config GPIO_NPCM_SGPIO
> >         bool "Nuvoton SGPIO support"
> >         depends on ARCH_NPCM || COMPILE_TEST
> > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> > index 9e40af196aae..9fc2f5931b22 100644
> > --- a/drivers/gpio/Makefile
> > +++ b/drivers/gpio/Makefile
> > @@ -116,6 +116,7 @@ obj-$(CONFIG_GPIO_MT7621)           += gpio-mt7621.o
> >  obj-$(CONFIG_GPIO_MVEBU)               += gpio-mvebu.o
> >  obj-$(CONFIG_GPIO_MXC)                 += gpio-mxc.o
> >  obj-$(CONFIG_GPIO_MXS)                 += gpio-mxs.o
> > +obj-$(CONFIG_GPIO_NOMADIK)             += gpio-nomadik.o
> >  obj-$(CONFIG_GPIO_NPCM_SGPIO)          += gpio-npcm-sgpio.o
> >  obj-$(CONFIG_GPIO_OCTEON)              += gpio-octeon.o
> >  obj-$(CONFIG_GPIO_OMAP)                        += gpio-omap.o
> > diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
> > new file mode 100644
> > index 000000000000..e39477e1a58f
> > --- /dev/null
> > +++ b/drivers/gpio/gpio-nomadik.c
> > @@ -0,0 +1,660 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * GPIO driver for the IP block found in the Nomadik SoC; it is an AMBA device,
> > + * managing 32 pins with alternate functions. It can also handle the STA2X11
> > + * block from ST.
> > + *
> > + * The GPIO chips are shared with pinctrl-nomadik if used; it needs access for
> > + * pinmuxing functionality and others.
> > + *
> > + * Copyright (C) 2008,2009 STMicroelectronics
> > + * Copyright (C) 2009 Alessandro Rubini <rubini at unipv.it>
> > + *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar at st.com>
> > + * Copyright (C) 2011-2013 Linus Walleij <linus.walleij at linaro.org>
> > + */
>
> Add a newline here.

This commit tries its best to not modify the file too much. It mostly is
a copy-and-paste. The goal is to have a sensible diff between old
drivers/pinctrl/nomadik/pinctrl-nomadik.c and new
drivers/gpio/gpio-nomadik.c. We wait until later commits to fix stuff.

Should below comments "avoid new calls to X" still be taken into
account, knowing that this is old code being moved around?

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

------------------------------------------------------------------------



From theo.lebrun at bootlin.com  Wed Feb 21 08:05:15 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 21 Feb 2024 17:05:15 +0100
Subject: [PATCH 13/23] gpio: nomadik: fix offset bug in nmk_pmx_set()
In-Reply-To: <CACRpkdbq_QxdftNGOv3+-SpfrV_qPTB-m-atdY0hCE_s8DK64A@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-13-f88c0ccf372b@bootlin.com>
 <CACRpkdbq_QxdftNGOv3+-SpfrV_qPTB-m-atdY0hCE_s8DK64A@mail.gmail.com>
Message-ID: <CZAVVISSTXS3.1ZTSEY6PV6LOT@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 10:56 PM CET, Linus Walleij wrote:
> On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> > Previously, the statement looked like:
> >
> >     slpm[x] &= ~BIT(g->pins[i]);
> >
> > Where:
> >  - slpm is a unsigned int pointer;
> >  - g->pins[i] is a pin number which can grow to more than 32.
> >
> > The expected shift amount is a pin bank offset.
> >
> > This bug does not occur on every group or pin: the altsetting must be
> > NMK_GPIO_ALT_C and the pin must be 32 or above. It is possible that it
> > occurred. For example, in pinctrl-nomadik-db8500.c, pin group i2c3_c_2
> > has the right altsetting and has pins 229 and 230.
> >
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
>
> Ah good catch!
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
>
> I this something I could just apply as a fix or are there
> dependencies on other patches?

There are dependencies. As Bartosz and you asked, I'll try my best to
avoid them and move this patch up in the series, with an appropriate
Fixes: trailer (to the initial driver commit I believe).

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From will at kernel.org  Wed Feb 21 08:08:50 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 21 Feb 2024 16:08:50 +0000
Subject: [PATCH] drivers/iommu: Ensure that the queue base address is
 successfully written during SMMU initialization.
In-Reply-To: <20240221152629.3656-1-niliqiang.io@gmail.com>
References: <20240219091709.GA4105@willie-the-truck>
 <20240221152629.3656-1-niliqiang.io@gmail.com>
Message-ID: <20240221160849.GB7362@willie-the-truck>

On Wed, Feb 21, 2024 at 11:26:29PM +0800, ni.liqiang wrote:
> >>  The SMMU registers are accessed using Device-nGnRE attributes. It is
> >> my understanding that, for Device-nGnRE, the Arm architecture requires
> >> that writes to the same peripheral arrive at the endpoint in program
> >> order.
> >
> > Yup, that's correct. The "nR" part means "non-Reordering", so something
> > else is going on here.
> 
> Yes, the SMMU registers are accessed using Device-nGnRE attributes. 
> 
> One additional point to note is: in cases where there is a failure writing
> to the CMDQ base address register, the testing environment was a
> multi-die, multi-socket server. This issue has not been observed on a
> single-die server. I apologize for omitting this information in my initial
> patch submission. 

Uh-oh, smells like a hardware issue ;p
I wonder if Device-nGnRnE behaves any differently?

> Over the past few days, I have referenced the kernel source code and
> ported the SMMU register initialization process. Through multiple stress
> tests, I have attempted to reproduce the CMDQ base address register write
> failure issue. The summarized results of my experiments are as follows:
> 1. When testing with one CPU core bound using taskset, the initialization
> process was executed 300,000 times without encountering the CMDQ base
> address register write failure issue. However, when not binding CPU using
> taskset, the issue was reproduced around 1,000 iterations into the test.
> 2. Without CPU binding, I inserted a memory barrier between accesses to
> the CMDQ_BASE register and CMDQEN register, similar to the modification
> made in the patch. After executing the initialization process 300,000
> times, the CMDQ base address register write failure issue did not occur.
> 
> Based on these observations and joint analysis with CMN colleagues, we
> speculate that in the SMMU register initialization process, if the CPU
> core changes, and these CPUs are located on different dies, the underlying
> 4 CCG ports are utilized to perform die-to-die accesses. However, in our
> current strategy, these 4 CCG ports cannot guarantee ordering, resulting
> in the completion of CMDQEN writing before the completion of CMDQ base
> address writing.

(Disclaimer: I don't know what a CCG port is)

Hmmm. The part that doesn't make sense to me here is that migrating between
CPUs implies context-switching, and we have a DSB on that path in
__switch_to(). So why would adding barriers to the driver help? Maybe it
just changes the timing?

> From the analysis above, it seems that modifying the die-to-die access
> strategy to achieve ordering of Device-nGnRE memory might be a better
> solution compared to adding a memory barrier?

I'm not sure what you're proposing, but I don't think Linux should be
changed to accomodate this.

Will


From tzimmermann at suse.de  Wed Feb 21 08:05:24 2024
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Wed, 21 Feb 2024 17:05:24 +0100
Subject: [PATCH 1/3] arch: Select fbdev helpers with CONFIG_VIDEO
In-Reply-To: <20240221161431.8245-1-tzimmermann@suse.de>
References: <20240221161431.8245-1-tzimmermann@suse.de>
Message-ID: <20240221161431.8245-2-tzimmermann@suse.de>

Various Kconfig options selected the per-architecture helpers for
fbdev. But none of the contained code depends on fbdev. Standardize
on CONFIG_VIDEO, which will allow to add more general helpers for
video functionality.

CONFIG_VIDEO protects each architecture's video/ directory. This
allows for the use of more fine-grained control for each directory's
files, such as the use of CONFIG_STI_CORE on parisc.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
Cc: "James E.J. Bottomley" <James.Bottomley at HansenPartnership.com>
Cc: Helge Deller <deller at gmx.de>
Cc: "David S. Miller" <davem at davemloft.net>
Cc: Andreas Larsson <andreas at gaisler.com>
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: x86 at kernel.org
Cc: "H. Peter Anvin" <hpa at zytor.com>
---
 arch/parisc/Makefile      | 2 +-
 arch/sparc/Makefile       | 4 ++--
 arch/sparc/video/Makefile | 2 +-
 arch/x86/Makefile         | 2 +-
 arch/x86/video/Makefile   | 3 ++-
 5 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 316f84f1d15c8..21b8166a68839 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -119,7 +119,7 @@ export LIBGCC
 
 libs-y	+= arch/parisc/lib/ $(LIBGCC)
 
-drivers-y += arch/parisc/video/
+drivers-$(CONFIG_VIDEO) += arch/parisc/video/
 
 boot	:= arch/parisc/boot
 
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index 5f60359361312..757451c3ea1df 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -59,8 +59,8 @@ endif
 libs-y                 += arch/sparc/prom/
 libs-y                 += arch/sparc/lib/
 
-drivers-$(CONFIG_PM) += arch/sparc/power/
-drivers-$(CONFIG_FB) += arch/sparc/video/
+drivers-$(CONFIG_PM)    += arch/sparc/power/
+drivers-$(CONFIG_VIDEO) += arch/sparc/video/
 
 boot := arch/sparc/boot
 
diff --git a/arch/sparc/video/Makefile b/arch/sparc/video/Makefile
index 6baddbd58e4db..9dd82880a027a 100644
--- a/arch/sparc/video/Makefile
+++ b/arch/sparc/video/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-obj-$(CONFIG_FB) += fbdev.o
+obj-y	+= fbdev.o
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 15a5f4f2ff0aa..c0ea612c62ebe 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -265,7 +265,7 @@ drivers-$(CONFIG_PCI)            += arch/x86/pci/
 # suspend and hibernation support
 drivers-$(CONFIG_PM) += arch/x86/power/
 
-drivers-$(CONFIG_FB_CORE) += arch/x86/video/
+drivers-$(CONFIG_VIDEO) += arch/x86/video/
 
 ####
 # boot loader support. Several targets are kept for legacy purposes
diff --git a/arch/x86/video/Makefile b/arch/x86/video/Makefile
index 5ebe48752ffc4..9dd82880a027a 100644
--- a/arch/x86/video/Makefile
+++ b/arch/x86/video/Makefile
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_FB_CORE)		+= fbdev.o
+
+obj-y	+= fbdev.o
-- 
2.43.0



From tzimmermann at suse.de  Wed Feb 21 08:05:25 2024
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Wed, 21 Feb 2024 17:05:25 +0100
Subject: [PATCH 2/3] arch: Remove struct fb_info from video helpers
In-Reply-To: <20240221161431.8245-1-tzimmermann@suse.de>
References: <20240221161431.8245-1-tzimmermann@suse.de>
Message-ID: <20240221161431.8245-3-tzimmermann@suse.de>

The per-architecture video helpers do not depend on struct fb_info
or anything else from fbdev. Remove it from the interface and replace
fb_is_primary_device() with video_is_primary_device(). The new helper
is similar in functionality, but can operate on non-fbdev devices.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
Cc: "James E.J. Bottomley" <James.Bottomley at HansenPartnership.com>
Cc: Helge Deller <deller at gmx.de>
Cc: "David S. Miller" <davem at davemloft.net>
Cc: Andreas Larsson <andreas at gaisler.com>
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: x86 at kernel.org
Cc: "H. Peter Anvin" <hpa at zytor.com>
---
 arch/parisc/include/asm/fb.h     |  8 +++++---
 arch/parisc/video/fbdev.c        |  9 +++++----
 arch/sparc/include/asm/fb.h      |  7 ++++---
 arch/sparc/video/fbdev.c         | 17 ++++++++---------
 arch/x86/include/asm/fb.h        |  8 +++++---
 arch/x86/video/fbdev.c           | 18 +++++++-----------
 drivers/video/fbdev/core/fbcon.c |  2 +-
 include/asm-generic/fb.h         | 11 ++++++-----
 8 files changed, 41 insertions(+), 39 deletions(-)

diff --git a/arch/parisc/include/asm/fb.h b/arch/parisc/include/asm/fb.h
index 658a8a7dc5312..ed2a195a3e762 100644
--- a/arch/parisc/include/asm/fb.h
+++ b/arch/parisc/include/asm/fb.h
@@ -2,11 +2,13 @@
 #ifndef _ASM_FB_H_
 #define _ASM_FB_H_
 
-struct fb_info;
+#include <linux/types.h>
+
+struct device;
 
 #if defined(CONFIG_STI_CORE)
-int fb_is_primary_device(struct fb_info *info);
-#define fb_is_primary_device fb_is_primary_device
+bool video_is_primary_device(struct device *dev);
+#define video_is_primary_device video_is_primary_device
 #endif
 
 #include <asm-generic/fb.h>
diff --git a/arch/parisc/video/fbdev.c b/arch/parisc/video/fbdev.c
index e4f8ac99fc9e0..540fa0c919d59 100644
--- a/arch/parisc/video/fbdev.c
+++ b/arch/parisc/video/fbdev.c
@@ -5,12 +5,13 @@
  * Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend at alpha.franken.de>
  */
 
-#include <linux/fb.h>
 #include <linux/module.h>
 
 #include <video/sticore.h>
 
-int fb_is_primary_device(struct fb_info *info)
+#include <asm/fb.h>
+
+bool video_is_primary_device(struct device *dev)
 {
 	struct sti_struct *sti;
 
@@ -21,6 +22,6 @@ int fb_is_primary_device(struct fb_info *info)
 		return true;
 
 	/* return true if it's the default built-in framebuffer driver */
-	return (sti->dev == info->device);
+	return (sti->dev == dev);
 }
-EXPORT_SYMBOL(fb_is_primary_device);
+EXPORT_SYMBOL(video_is_primary_device);
diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/fb.h
index 24440c0fda490..07f0325d6921c 100644
--- a/arch/sparc/include/asm/fb.h
+++ b/arch/sparc/include/asm/fb.h
@@ -3,10 +3,11 @@
 #define _SPARC_FB_H_
 
 #include <linux/io.h>
+#include <linux/types.h>
 
 #include <asm/page.h>
 
-struct fb_info;
+struct device;
 
 #ifdef CONFIG_SPARC32
 static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
@@ -18,8 +19,8 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
 #define pgprot_framebuffer pgprot_framebuffer
 #endif
 
-int fb_is_primary_device(struct fb_info *info);
-#define fb_is_primary_device fb_is_primary_device
+bool video_is_primary_device(struct device *dev);
+#define video_is_primary_device video_is_primary_device
 
 static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
 {
diff --git a/arch/sparc/video/fbdev.c b/arch/sparc/video/fbdev.c
index bff66dd1909a4..e46f0499c2774 100644
--- a/arch/sparc/video/fbdev.c
+++ b/arch/sparc/video/fbdev.c
@@ -1,26 +1,25 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <linux/console.h>
-#include <linux/fb.h>
+#include <linux/device.h>
 #include <linux/module.h>
 
+#include <asm/fb.h>
 #include <asm/prom.h>
 
-int fb_is_primary_device(struct fb_info *info)
+bool video_is_primary_device(struct device *dev)
 {
-	struct device *dev = info->device;
-	struct device_node *node;
+	struct device_node *node = dev->of_node;
 
 	if (console_set_on_cmdline)
-		return 0;
+		return false;
 
-	node = dev->of_node;
 	if (node && node == of_console_device)
-		return 1;
+		return true;
 
-	return 0;
+	return false;
 }
-EXPORT_SYMBOL(fb_is_primary_device);
+EXPORT_SYMBOL(video_is_primary_device);
 
 MODULE_DESCRIPTION("Sparc fbdev helpers");
 MODULE_LICENSE("GPL");
diff --git a/arch/x86/include/asm/fb.h b/arch/x86/include/asm/fb.h
index c3b9582de7efd..999db33792869 100644
--- a/arch/x86/include/asm/fb.h
+++ b/arch/x86/include/asm/fb.h
@@ -2,17 +2,19 @@
 #ifndef _ASM_X86_FB_H
 #define _ASM_X86_FB_H
 
+#include <linux/types.h>
+
 #include <asm/page.h>
 
-struct fb_info;
+struct device;
 
 pgprot_t pgprot_framebuffer(pgprot_t prot,
 			    unsigned long vm_start, unsigned long vm_end,
 			    unsigned long offset);
 #define pgprot_framebuffer pgprot_framebuffer
 
-int fb_is_primary_device(struct fb_info *info);
-#define fb_is_primary_device fb_is_primary_device
+bool video_is_primary_device(struct device *dev);
+#define video_is_primary_device video_is_primary_device
 
 #include <asm-generic/fb.h>
 
diff --git a/arch/x86/video/fbdev.c b/arch/x86/video/fbdev.c
index 1dd6528cc947c..4d87ce8e257fe 100644
--- a/arch/x86/video/fbdev.c
+++ b/arch/x86/video/fbdev.c
@@ -7,7 +7,6 @@
  *
  */
 
-#include <linux/fb.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/vgaarb.h>
@@ -25,20 +24,17 @@ pgprot_t pgprot_framebuffer(pgprot_t prot,
 }
 EXPORT_SYMBOL(pgprot_framebuffer);
 
-int fb_is_primary_device(struct fb_info *info)
+bool video_is_primary_device(struct device *dev)
 {
-	struct device *device = info->device;
-	struct pci_dev *pci_dev;
+	struct pci_dev *pdev;
 
-	if (!device || !dev_is_pci(device))
-		return 0;
+	if (!dev_is_pci(dev))
+		return false;
 
-	pci_dev = to_pci_dev(device);
+	pdev = to_pci_dev(dev);
 
-	if (pci_dev == vga_default_device())
-		return 1;
-	return 0;
+	return (pdev == vga_default_device());
 }
-EXPORT_SYMBOL(fb_is_primary_device);
+EXPORT_SYMBOL(video_is_primary_device);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 1183e7a871f8b..25277852f326d 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -2941,7 +2941,7 @@ void fbcon_remap_all(struct fb_info *info)
 static void fbcon_select_primary(struct fb_info *info)
 {
 	if (!map_override && primary_device == -1 &&
-	    fb_is_primary_device(info)) {
+	    video_is_primary_device(info->device)) {
 		int i;
 
 		printk(KERN_INFO "fbcon: %s (fb%i) is primary device\n",
diff --git a/include/asm-generic/fb.h b/include/asm-generic/fb.h
index 6ccabb400aa66..4788c1e1c6bc0 100644
--- a/include/asm-generic/fb.h
+++ b/include/asm-generic/fb.h
@@ -10,8 +10,9 @@
 #include <linux/io.h>
 #include <linux/mm_types.h>
 #include <linux/pgtable.h>
+#include <linux/types.h>
 
-struct fb_info;
+struct device;
 
 #ifndef pgprot_framebuffer
 #define pgprot_framebuffer pgprot_framebuffer
@@ -23,11 +24,11 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
 }
 #endif
 
-#ifndef fb_is_primary_device
-#define fb_is_primary_device fb_is_primary_device
-static inline int fb_is_primary_device(struct fb_info *info)
+#ifndef video_is_primary_device
+#define video_is_primary_device video_is_primary_device
+static inline bool video_is_primary_device(struct device *dev)
 {
-	return 0;
+	return false;
 }
 #endif
 
-- 
2.43.0



From tzimmermann at suse.de  Wed Feb 21 08:05:23 2024
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Wed, 21 Feb 2024 17:05:23 +0100
Subject: [PATCH 0/3] arch: Remove fbdev dependency from video helpers
Message-ID: <20240221161431.8245-1-tzimmermann@suse.de>

Make architecture helpers for display functionality depend on general
video functionality instead of fbdev. This avoid the dependency on
fbdev and makes the functionality available for non-fbdev code.

Patch 1 replaces the variety of Kconfig options that control the
Makefiles with CONFIG_VIDEO. More fine-grained control of the build
can then be done within each video/ directory; see sparc for an
example.

Patch 2 replaces fb_is_primary_device() with video_is_primary_device(),
which has no dependencies on fbdev. The implementation remains identical
on all affected platforms. There's one minor change in fbcon, which is
the only caller of fb_is_primary_device().

Patch 3 renames the source and files from fbdev to video.

Thomas Zimmermann (3):
  arch: Select fbdev helpers with CONFIG_VIDEO
  arch: Remove struct fb_info from video helpers
  arch: Rename fbdev header and source files

 arch/arc/include/asm/fb.h                    |  8 ------
 arch/arc/include/asm/video.h                 |  8 ++++++
 arch/arm/include/asm/fb.h                    |  6 -----
 arch/arm/include/asm/video.h                 |  6 +++++
 arch/arm64/include/asm/fb.h                  | 10 --------
 arch/arm64/include/asm/video.h               | 10 ++++++++
 arch/loongarch/include/asm/{fb.h => video.h} |  8 +++---
 arch/m68k/include/asm/{fb.h => video.h}      |  8 +++---
 arch/mips/include/asm/{fb.h => video.h}      | 12 ++++-----
 arch/parisc/Makefile                         |  2 +-
 arch/parisc/include/asm/fb.h                 | 14 -----------
 arch/parisc/include/asm/video.h              | 16 ++++++++++++
 arch/parisc/video/Makefile                   |  2 +-
 arch/parisc/video/{fbdev.c => video-sti.c}   |  9 ++++---
 arch/powerpc/include/asm/{fb.h => video.h}   |  8 +++---
 arch/powerpc/kernel/pci-common.c             |  2 +-
 arch/sh/include/asm/fb.h                     |  7 ------
 arch/sh/include/asm/video.h                  |  7 ++++++
 arch/sparc/Makefile                          |  4 +--
 arch/sparc/include/asm/{fb.h => video.h}     | 15 +++++------
 arch/sparc/video/Makefile                    |  2 +-
 arch/sparc/video/fbdev.c                     | 26 --------------------
 arch/sparc/video/video.c                     | 25 +++++++++++++++++++
 arch/x86/Makefile                            |  2 +-
 arch/x86/include/asm/fb.h                    | 19 --------------
 arch/x86/include/asm/video.h                 | 21 ++++++++++++++++
 arch/x86/video/Makefile                      |  3 ++-
 arch/x86/video/{fbdev.c => video.c}          | 21 +++++++---------
 drivers/video/fbdev/core/fbcon.c             |  2 +-
 include/asm-generic/Kbuild                   |  2 +-
 include/asm-generic/{fb.h => video.h}        | 17 +++++++------
 include/linux/fb.h                           |  2 +-
 32 files changed, 154 insertions(+), 150 deletions(-)
 delete mode 100644 arch/arc/include/asm/fb.h
 create mode 100644 arch/arc/include/asm/video.h
 delete mode 100644 arch/arm/include/asm/fb.h
 create mode 100644 arch/arm/include/asm/video.h
 delete mode 100644 arch/arm64/include/asm/fb.h
 create mode 100644 arch/arm64/include/asm/video.h
 rename arch/loongarch/include/asm/{fb.h => video.h} (86%)
 rename arch/m68k/include/asm/{fb.h => video.h} (86%)
 rename arch/mips/include/asm/{fb.h => video.h} (76%)
 delete mode 100644 arch/parisc/include/asm/fb.h
 create mode 100644 arch/parisc/include/asm/video.h
 rename arch/parisc/video/{fbdev.c => video-sti.c} (78%)
 rename arch/powerpc/include/asm/{fb.h => video.h} (76%)
 delete mode 100644 arch/sh/include/asm/fb.h
 create mode 100644 arch/sh/include/asm/video.h
 rename arch/sparc/include/asm/{fb.h => video.h} (75%)
 delete mode 100644 arch/sparc/video/fbdev.c
 create mode 100644 arch/sparc/video/video.c
 delete mode 100644 arch/x86/include/asm/fb.h
 create mode 100644 arch/x86/include/asm/video.h
 rename arch/x86/video/{fbdev.c => video.c} (66%)
 rename include/asm-generic/{fb.h => video.h} (89%)

-- 
2.43.0



From tzimmermann at suse.de  Wed Feb 21 08:05:26 2024
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Wed, 21 Feb 2024 17:05:26 +0100
Subject: [PATCH 3/3] arch: Rename fbdev header and source files
In-Reply-To: <20240221161431.8245-1-tzimmermann@suse.de>
References: <20240221161431.8245-1-tzimmermann@suse.de>
Message-ID: <20240221161431.8245-4-tzimmermann@suse.de>

The per-architecture fbdev code has no dependencies on fbdev and can
be used for any video-related subsystem. Rename the files to 'video'.
Use video-sti.c on parisc as the source file depends on CONFIG_STI_CORE.

Further update all includes statements, includ guards, and Makefiles.
Also update a few strings and comments to refer to video instead of
fbdev.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
Cc: Vineet Gupta <vgupta at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Huacai Chen <chenhuacai at kernel.org>
Cc: WANG Xuerui <kernel at xen0n.name>
Cc: Geert Uytterhoeven <geert at linux-m68k.org>
Cc: Thomas Bogendoerfer <tsbogend at alpha.franken.de>
Cc: "James E.J. Bottomley" <James.Bottomley at HansenPartnership.com>
Cc: Helge Deller <deller at gmx.de>
Cc: Michael Ellerman <mpe at ellerman.id.au>
Cc: Nicholas Piggin <npiggin at gmail.com>
Cc: Yoshinori Sato <ysato at users.sourceforge.jp>
Cc: Rich Felker <dalias at libc.org>
Cc: John Paul Adrian Glaubitz <glaubitz at physik.fu-berlin.de>
Cc: "David S. Miller" <davem at davemloft.net>
Cc: Andreas Larsson <andreas at gaisler.com>
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: x86 at kernel.org
Cc: "H. Peter Anvin" <hpa at zytor.com>
---
 arch/arc/include/asm/fb.h                    |  8 --------
 arch/arc/include/asm/video.h                 |  8 ++++++++
 arch/arm/include/asm/fb.h                    |  6 ------
 arch/arm/include/asm/video.h                 |  6 ++++++
 arch/arm64/include/asm/fb.h                  | 10 ----------
 arch/arm64/include/asm/video.h               | 10 ++++++++++
 arch/loongarch/include/asm/{fb.h => video.h} |  8 ++++----
 arch/m68k/include/asm/{fb.h => video.h}      |  8 ++++----
 arch/mips/include/asm/{fb.h => video.h}      | 12 ++++++------
 arch/parisc/include/asm/{fb.h => video.h}    |  8 ++++----
 arch/parisc/video/Makefile                   |  2 +-
 arch/parisc/video/{fbdev.c => video-sti.c}   |  2 +-
 arch/powerpc/include/asm/{fb.h => video.h}   |  8 ++++----
 arch/powerpc/kernel/pci-common.c             |  2 +-
 arch/sh/include/asm/fb.h                     |  7 -------
 arch/sh/include/asm/video.h                  |  7 +++++++
 arch/sparc/include/asm/{fb.h => video.h}     |  8 ++++----
 arch/sparc/video/Makefile                    |  2 +-
 arch/sparc/video/{fbdev.c => video.c}        |  4 ++--
 arch/x86/include/asm/{fb.h => video.h}       |  8 ++++----
 arch/x86/video/Makefile                      |  2 +-
 arch/x86/video/{fbdev.c => video.c}          |  3 ++-
 include/asm-generic/Kbuild                   |  2 +-
 include/asm-generic/{fb.h => video.h}        |  6 +++---
 include/linux/fb.h                           |  2 +-
 25 files changed, 75 insertions(+), 74 deletions(-)
 delete mode 100644 arch/arc/include/asm/fb.h
 create mode 100644 arch/arc/include/asm/video.h
 delete mode 100644 arch/arm/include/asm/fb.h
 create mode 100644 arch/arm/include/asm/video.h
 delete mode 100644 arch/arm64/include/asm/fb.h
 create mode 100644 arch/arm64/include/asm/video.h
 rename arch/loongarch/include/asm/{fb.h => video.h} (86%)
 rename arch/m68k/include/asm/{fb.h => video.h} (86%)
 rename arch/mips/include/asm/{fb.h => video.h} (76%)
 rename arch/parisc/include/asm/{fb.h => video.h} (68%)
 rename arch/parisc/video/{fbdev.c => video-sti.c} (96%)
 rename arch/powerpc/include/asm/{fb.h => video.h} (76%)
 delete mode 100644 arch/sh/include/asm/fb.h
 create mode 100644 arch/sh/include/asm/video.h
 rename arch/sparc/include/asm/{fb.h => video.h} (89%)
 rename arch/sparc/video/{fbdev.c => video.c} (86%)
 rename arch/x86/include/asm/{fb.h => video.h} (77%)
 rename arch/x86/video/{fbdev.c => video.c} (97%)
 rename include/asm-generic/{fb.h => video.h} (96%)

diff --git a/arch/arc/include/asm/fb.h b/arch/arc/include/asm/fb.h
deleted file mode 100644
index 9c2383d29cbb9..0000000000000
--- a/arch/arc/include/asm/fb.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <asm-generic/fb.h>
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/arc/include/asm/video.h b/arch/arc/include/asm/video.h
new file mode 100644
index 0000000000000..8ff7263727fe7
--- /dev/null
+++ b/arch/arc/include/asm/video.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
+
+#include <asm-generic/video.h>
+
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/arm/include/asm/fb.h b/arch/arm/include/asm/fb.h
deleted file mode 100644
index ce20a43c30339..0000000000000
--- a/arch/arm/include/asm/fb.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <asm-generic/fb.h>
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/arm/include/asm/video.h b/arch/arm/include/asm/video.h
new file mode 100644
index 0000000000000..f570565366e67
--- /dev/null
+++ b/arch/arm/include/asm/video.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
+
+#include <asm-generic/video.h>
+
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/arm64/include/asm/fb.h b/arch/arm64/include/asm/fb.h
deleted file mode 100644
index 1a495d8fb2ce0..0000000000000
--- a/arch/arm64/include/asm/fb.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2012 ARM Ltd.
- */
-#ifndef __ASM_FB_H_
-#define __ASM_FB_H_
-
-#include <asm-generic/fb.h>
-
-#endif /* __ASM_FB_H_ */
diff --git a/arch/arm64/include/asm/video.h b/arch/arm64/include/asm/video.h
new file mode 100644
index 0000000000000..fe0e74983f4d9
--- /dev/null
+++ b/arch/arm64/include/asm/video.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ */
+#ifndef __ASM_VIDEO_H_
+#define __ASM_VIDEO_H_
+
+#include <asm-generic/video.h>
+
+#endif /* __ASM_VIDEO_H_ */
diff --git a/arch/loongarch/include/asm/fb.h b/arch/loongarch/include/asm/video.h
similarity index 86%
rename from arch/loongarch/include/asm/fb.h
rename to arch/loongarch/include/asm/video.h
index 0b218b10a9ec3..9f76845f2d4fd 100644
--- a/arch/loongarch/include/asm/fb.h
+++ b/arch/loongarch/include/asm/video.h
@@ -2,8 +2,8 @@
 /*
  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  */
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
 
 #include <linux/compiler.h>
 #include <linux/string.h>
@@ -26,6 +26,6 @@ static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
 }
 #define fb_memset fb_memset_io
 
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
 
-#endif /* _ASM_FB_H_ */
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/m68k/include/asm/fb.h b/arch/m68k/include/asm/video.h
similarity index 86%
rename from arch/m68k/include/asm/fb.h
rename to arch/m68k/include/asm/video.h
index 9941b7434b696..6cf2194c413d8 100644
--- a/arch/m68k/include/asm/fb.h
+++ b/arch/m68k/include/asm/video.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
 
 #include <asm/page.h>
 #include <asm/setup.h>
@@ -27,6 +27,6 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
 }
 #define pgprot_framebuffer pgprot_framebuffer
 
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
 
-#endif /* _ASM_FB_H_ */
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/mips/include/asm/fb.h b/arch/mips/include/asm/video.h
similarity index 76%
rename from arch/mips/include/asm/fb.h
rename to arch/mips/include/asm/video.h
index d98d6681d64ec..007c106d980fd 100644
--- a/arch/mips/include/asm/fb.h
+++ b/arch/mips/include/asm/video.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
 
 #include <asm/page.h>
 
@@ -13,8 +13,8 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
 
 /*
  * MIPS doesn't define __raw_ I/O macros, so the helpers
- * in <asm-generic/fb.h> don't generate fb_readq() and
- * fb_write(). We have to provide them here.
+ * in <asm-generic/video.h> don't generate fb_readq() and
+ * fb_writeq(). We have to provide them here.
  *
  * TODO: Convert MIPS to generic I/O. The helpers below can
  *       then be removed.
@@ -33,6 +33,6 @@ static inline void fb_writeq(u64 b, volatile void __iomem *addr)
 #define fb_writeq fb_writeq
 #endif
 
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
 
-#endif /* _ASM_FB_H_ */
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/parisc/include/asm/fb.h b/arch/parisc/include/asm/video.h
similarity index 68%
rename from arch/parisc/include/asm/fb.h
rename to arch/parisc/include/asm/video.h
index ed2a195a3e762..c5dff3223194a 100644
--- a/arch/parisc/include/asm/fb.h
+++ b/arch/parisc/include/asm/video.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
 
 #include <linux/types.h>
 
@@ -11,6 +11,6 @@ bool video_is_primary_device(struct device *dev);
 #define video_is_primary_device video_is_primary_device
 #endif
 
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
 
-#endif /* _ASM_FB_H_ */
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/parisc/video/Makefile b/arch/parisc/video/Makefile
index 16a73cce46612..b5db5b42880f8 100644
--- a/arch/parisc/video/Makefile
+++ b/arch/parisc/video/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-obj-$(CONFIG_STI_CORE) += fbdev.o
+obj-$(CONFIG_STI_CORE) += video-sti.o
diff --git a/arch/parisc/video/fbdev.c b/arch/parisc/video/video-sti.c
similarity index 96%
rename from arch/parisc/video/fbdev.c
rename to arch/parisc/video/video-sti.c
index 540fa0c919d59..564661e87093c 100644
--- a/arch/parisc/video/fbdev.c
+++ b/arch/parisc/video/video-sti.c
@@ -9,7 +9,7 @@
 
 #include <video/sticore.h>
 
-#include <asm/fb.h>
+#include <asm/video.h>
 
 bool video_is_primary_device(struct device *dev)
 {
diff --git a/arch/powerpc/include/asm/fb.h b/arch/powerpc/include/asm/video.h
similarity index 76%
rename from arch/powerpc/include/asm/fb.h
rename to arch/powerpc/include/asm/video.h
index c0c5d1df7ad1e..e1770114ffc36 100644
--- a/arch/powerpc/include/asm/fb.h
+++ b/arch/powerpc/include/asm/video.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
 
 #include <asm/page.h>
 
@@ -12,6 +12,6 @@ static inline pgprot_t pgprot_framebuffer(pgprot_t prot,
 }
 #define pgprot_framebuffer pgprot_framebuffer
 
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
 
-#endif /* _ASM_FB_H_ */
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index d95a48eff412e..eac84d687b53f 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -517,7 +517,7 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma)
 }
 
 /*
- * This one is used by /dev/mem and fbdev who have no clue about the
+ * This one is used by /dev/mem and video who have no clue about the
  * PCI device, it tries to find the PCI device first and calls the
  * above routine
  */
diff --git a/arch/sh/include/asm/fb.h b/arch/sh/include/asm/fb.h
deleted file mode 100644
index 19df13ee9ca73..0000000000000
--- a/arch/sh/include/asm/fb.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <asm-generic/fb.h>
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/sh/include/asm/video.h b/arch/sh/include/asm/video.h
new file mode 100644
index 0000000000000..14f49934a247a
--- /dev/null
+++ b/arch/sh/include/asm/video.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_VIDEO_H_
+#define _ASM_VIDEO_H_
+
+#include <asm-generic/video.h>
+
+#endif /* _ASM_VIDEO_H_ */
diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/video.h
similarity index 89%
rename from arch/sparc/include/asm/fb.h
rename to arch/sparc/include/asm/video.h
index 07f0325d6921c..a6f48f52db584 100644
--- a/arch/sparc/include/asm/fb.h
+++ b/arch/sparc/include/asm/video.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _SPARC_FB_H_
-#define _SPARC_FB_H_
+#ifndef _SPARC_VIDEO_H_
+#define _SPARC_VIDEO_H_
 
 #include <linux/io.h>
 #include <linux/types.h>
@@ -40,6 +40,6 @@ static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
 }
 #define fb_memset fb_memset_io
 
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
 
-#endif /* _SPARC_FB_H_ */
+#endif /* _SPARC_VIDEO_H_ */
diff --git a/arch/sparc/video/Makefile b/arch/sparc/video/Makefile
index 9dd82880a027a..fdf83a408d750 100644
--- a/arch/sparc/video/Makefile
+++ b/arch/sparc/video/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-obj-y	+= fbdev.o
+obj-y	+= video.o
diff --git a/arch/sparc/video/fbdev.c b/arch/sparc/video/video.c
similarity index 86%
rename from arch/sparc/video/fbdev.c
rename to arch/sparc/video/video.c
index e46f0499c2774..2414380caadc9 100644
--- a/arch/sparc/video/fbdev.c
+++ b/arch/sparc/video/video.c
@@ -4,8 +4,8 @@
 #include <linux/device.h>
 #include <linux/module.h>
 
-#include <asm/fb.h>
 #include <asm/prom.h>
+#include <asm/video.h>
 
 bool video_is_primary_device(struct device *dev)
 {
@@ -21,5 +21,5 @@ bool video_is_primary_device(struct device *dev)
 }
 EXPORT_SYMBOL(video_is_primary_device);
 
-MODULE_DESCRIPTION("Sparc fbdev helpers");
+MODULE_DESCRIPTION("Sparc video helpers");
 MODULE_LICENSE("GPL");
diff --git a/arch/x86/include/asm/fb.h b/arch/x86/include/asm/video.h
similarity index 77%
rename from arch/x86/include/asm/fb.h
rename to arch/x86/include/asm/video.h
index 999db33792869..0950c9535fae9 100644
--- a/arch/x86/include/asm/fb.h
+++ b/arch/x86/include/asm/video.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_X86_FB_H
-#define _ASM_X86_FB_H
+#ifndef _ASM_X86_VIDEO_H
+#define _ASM_X86_VIDEO_H
 
 #include <linux/types.h>
 
@@ -16,6 +16,6 @@ pgprot_t pgprot_framebuffer(pgprot_t prot,
 bool video_is_primary_device(struct device *dev);
 #define video_is_primary_device video_is_primary_device
 
-#include <asm-generic/fb.h>
+#include <asm-generic/video.h>
 
-#endif /* _ASM_X86_FB_H */
+#endif /* _ASM_X86_VIDEO_H */
diff --git a/arch/x86/video/Makefile b/arch/x86/video/Makefile
index 9dd82880a027a..fdf83a408d750 100644
--- a/arch/x86/video/Makefile
+++ b/arch/x86/video/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-obj-y	+= fbdev.o
+obj-y	+= video.o
diff --git a/arch/x86/video/fbdev.c b/arch/x86/video/video.c
similarity index 97%
rename from arch/x86/video/fbdev.c
rename to arch/x86/video/video.c
index 4d87ce8e257fe..81fc97a2a837a 100644
--- a/arch/x86/video/fbdev.c
+++ b/arch/x86/video/video.c
@@ -10,7 +10,8 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/vgaarb.h>
-#include <asm/fb.h>
+
+#include <asm/video.h>
 
 pgprot_t pgprot_framebuffer(pgprot_t prot,
 			    unsigned long vm_start, unsigned long vm_end,
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index d436bee4d129d..b20fa25a7e8d8 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -22,7 +22,6 @@ mandatory-y += dma-mapping.h
 mandatory-y += dma.h
 mandatory-y += emergency-restart.h
 mandatory-y += exec.h
-mandatory-y += fb.h
 mandatory-y += ftrace.h
 mandatory-y += futex.h
 mandatory-y += hardirq.h
@@ -62,5 +61,6 @@ mandatory-y += uaccess.h
 mandatory-y += unaligned.h
 mandatory-y += vermagic.h
 mandatory-y += vga.h
+mandatory-y += video.h
 mandatory-y += word-at-a-time.h
 mandatory-y += xor.h
diff --git a/include/asm-generic/fb.h b/include/asm-generic/video.h
similarity index 96%
rename from include/asm-generic/fb.h
rename to include/asm-generic/video.h
index 4788c1e1c6bc0..b1da2309d9434 100644
--- a/include/asm-generic/fb.h
+++ b/include/asm-generic/video.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 
-#ifndef __ASM_GENERIC_FB_H_
-#define __ASM_GENERIC_FB_H_
+#ifndef __ASM_GENERIC_VIDEO_H_
+#define __ASM_GENERIC_VIDEO_H_
 
 /*
  * Only include this header file from your architecture's <asm/fb.h>.
@@ -133,4 +133,4 @@ static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
 #define fb_memset fb_memset_io
 #endif
 
-#endif /* __ASM_GENERIC_FB_H_ */
+#endif /* __ASM_GENERIC_VIDEO_H_ */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 2ce2f5c2fca9a..8fe9df5ae19da 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -16,7 +16,7 @@
 #include <linux/backlight.h>
 #include <linux/slab.h>
 
-#include <asm/fb.h>
+#include <asm/video.h>
 
 struct vm_area_struct;
 struct fb_info;
-- 
2.43.0



From theo.lebrun at bootlin.com  Wed Feb 21 08:16:36 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 21 Feb 2024 17:16:36 +0100
Subject: [PATCH 18/23] gpio: nomadik: support mobileye,eyeq5-gpio
In-Reply-To: <CACRpkdYLBGsphNkmWyPXQZvFaO2hHGHGTMt1eqz-HAa2k5F3bg@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-18-f88c0ccf372b@bootlin.com>
 <CACRpkdYLBGsphNkmWyPXQZvFaO2hHGHGTMt1eqz-HAa2k5F3bg@mail.gmail.com>
Message-ID: <CZAW47LJHQVD.1Z9GFT8UENYXT@bootlin.com>

Hello,

On Wed Feb 21, 2024 at 3:31 PM CET, Linus Walleij wrote:
> On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> > We create a custom compatible for the STA2X11 IP block as integrated
> > into the Mobileye EyeQ5 platform. Its wake and alternate functions have
> > been disabled, we want to avoid touching those registers.
> >
> > We both do: (1) early return in functions that do not support the
> > platform, but with warnings, and (2) avoid calling those functions in
> > the first place.
> >
> > We ensure that pinctrl-nomadik is not used with this STA2X11 variant.
> >
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
>
> When testing I noticed that this patch breaks Ux500 (up until patch 17
> all works fine!).
>
> But I don't know why.
>
> Trying to figure it out...

Can I help in the debugging process?

Reading the code once again I'd guess
of_device_get_match_data(&gpio_pdev->dev) could be the root cause. We
are accessing match data for the GPIO device while probing the pinctrl
device. Maybe something isn't initialised properly yet? The rest looks
rather harmless, I've checked all conditional expressions.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From mshavit at google.com  Wed Feb 21 08:19:06 2024
From: mshavit at google.com (Michael Shavit)
Date: Thu, 22 Feb 2024 00:19:06 +0800
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <20240221140818.GA2635804@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com> <20240215134952.GA690@willie-the-truck>
 <20240215160135.GL1088888@nvidia.com> <20240221134923.GA7362@willie-the-truck>
 <20240221140818.GA2635804@nvidia.com>
Message-ID: <CAKHBV25XrwOXyrYkjLZ7=5sNoFsM8VPS=HaJupswu6QDZ02LcQ@mail.gmail.com>

On Wed, Feb 21, 2024 at 10:08?PM Jason Gunthorpe <jgg at nvidia.com> wrote:
>
> On Wed, Feb 21, 2024 at 01:49:23PM +0000, Will Deacon wrote:
>
> > Very roughly, yes, although I'd go further and just return a bitmap of
> > used qwords instead of tracking these bits. Basically, we could have some
> > #defines saying which qwords are used by which configs,
>
> I don't think this will work well for CD's EPD0 case..
>
> static void arm_smmu_get_cd_used(const __le64 *ent, __le64 *used_bits)
> {
>         used_bits[0] = cpu_to_le64(CTXDESC_CD_0_V);
>         if (!(ent[0] & cpu_to_le64(CTXDESC_CD_0_V)))
>                 return;
>         memset(used_bits, 0xFF, sizeof(struct arm_smmu_cd));
>
>         /* EPD0 means T0SZ/TG0/IR0/OR0/SH0/TTB0 are IGNORED */
>         if (ent[0] & cpu_to_le64(CTXDESC_CD_0_TCR_EPD0)) {
>                 used_bits[0] &= ~cpu_to_le64(
>                         CTXDESC_CD_0_TCR_T0SZ | CTXDESC_CD_0_TCR_TG0 |
>                         CTXDESC_CD_0_TCR_IRGN0 | CTXDESC_CD_0_TCR_ORGN0 |
>                         CTXDESC_CD_0_TCR_SH0);
>                 used_bits[1] &= ~cpu_to_le64(CTXDESC_CD_1_TTB0_MASK);
>         }
> }
>
> > and then we can
> > simplify the algorithm while retaining the ability to reject updates
> > to qwords which we're not expecting.
>
> It is not much simplification. arm_smmu_entry_qword_diff() gets a bit
> shorter (not that it is complex anyhow) and other stuff gets worse.

I think the simplification here is in the first if branch of
arm_smmu_write_ste. With Will's proposal, we only perform a hitless
update if there's a single used qword that needs updating. There's no
longer a case where we first set unused bits in qwords whose other
bits are in use. I'd argue that setting unused bits of a q word was
very clever and removing the logic does conceptually simplify things,
although yes it's not much fewer lines of code. I also don't think
this throws away the entire logic of the current design, the idea of
counting the number of qwords that differ and writing qwords that are
unused first is still there.

But, it does mean that hitless updates are only possible under
narrower circumstances...We now have to figure out if there are
transitions where this is problematic where we could previously assume
that we'd always get the best behavior possible. Both in the present
(i.e this SHCFG discussion and EPD0 case) and in the future if new
parts of the configs start getting used. IMO not having to think about
this is a meaningful advantage of the current solution.

> > > We'd have to really start doing really hacky things like remove the
> > > SHCFG as a used field entirely - but I think if you do that you break
> > > the entire logic of the design and also go backwards to having
> > > programming that only works if STEs are constructed in certain ways.
> >
> > I would actually like to remove SHCFG as a used field. If the encoding
> > was less whacky (i.e. if 0b00 always meant "use incoming"), then it would
> > be easy, but it shouldn't be too hard to work around that.
>

What do you mean by removing SHCFG as a used field? Are we changing
the driver so that it only ever sets SHCFG to a single possible value?
Or are we talking about fudging things and pretending it's not used
when it is and might have different values?


From theo.lebrun at bootlin.com  Wed Feb 21 08:20:03 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 21 Feb 2024 17:20:03 +0100
Subject: [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from
 drivers/pinctrl/nomadik/
In-Reply-To: <CACRpkdaSMJBFrmbTu+C1Ls8HkLH4FZsAQ6t7dC76+sVTXXHEyw@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com>
 <CACRpkdaSMJBFrmbTu+C1Ls8HkLH4FZsAQ6t7dC76+sVTXXHEyw@mail.gmail.com>
Message-ID: <CZAW6UTMON6K.34LW7FDGNO1XC@bootlin.com>

Hello,

On Wed Feb 21, 2024 at 3:37 PM CET, Linus Walleij wrote:
> just a quick note here:
>
> On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> > +config GPIO_NOMADIK
> > +       bool "Nomadik GPIO driver"
> > +       depends on ARCH_U8500 || ARCH_NOMADIK || COMPILE_TEST
> > +       select OF_GPIO
> > +       select GPIOLIB_IRQCHIP
>
> Could you add:
>
> default PINCTRL_NOMADIK
>
> so it is turned on by default when we have that, since they are jitted together
> so closely.

Would that bring something more than what is currently present? I've set
PINCTRL_NOMADIK to select GPIO_NOMADIK. This means that if
PINCTRL_NOMADIK=y then GPIO_NOMADIK=y. If PINCTRL_NOMADIK=n then
GPIO_NOMADIK is free to be whatever.

This behavior sounds similar to what would happen if adding "default
PINCTRL_NOMADIK".

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From theo.lebrun at bootlin.com  Wed Feb 21 08:22:25 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 21 Feb 2024 17:22:25 +0100
Subject: [PATCH 18/23] gpio: nomadik: support mobileye,eyeq5-gpio
In-Reply-To: <CACRpkdYb4V5EouMBYRRrZvLT1v6zKEtjHGPAs5orDKoo6dz6nA@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-18-f88c0ccf372b@bootlin.com>
 <CACRpkdYb4V5EouMBYRRrZvLT1v6zKEtjHGPAs5orDKoo6dz6nA@mail.gmail.com>
Message-ID: <CZAW8NNS98TB.18RASC15YIRNB@bootlin.com>

Hello,

On Wed Feb 21, 2024 at 2:45 PM CET, Linus Walleij wrote:
> On Wed, Feb 14, 2024 at 5:24?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
> > We create a custom compatible for the STA2X11 IP block as integrated
> > into the Mobileye EyeQ5 platform. Its wake and alternate functions have
> > been disabled, we want to avoid touching those registers.
> >
> > We both do: (1) early return in functions that do not support the
> > platform, but with warnings, and (2) avoid calling those functions in
> > the first place.
> >
> > We ensure that pinctrl-nomadik is not used with this STA2X11 variant.
> >
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> (...)
> >+       bool quirk_mbly;
>
> Compulsive abbreviation? I would just rename it:
>
> bool is_mobileye_soc;
>
> Nevermind the long name, it makes it crystal clear for readers
> what is going on. (Rusty Russell's API naming guidelines.)
>
> With that changed:
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Makes complete sense. This is old heritage from my initial prototype
that should have long gone disappeared.

Thanks for your feedback & reviews!

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From jeremy.linton at arm.com  Wed Feb 21 08:35:39 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 21 Feb 2024 10:35:39 -0600
Subject: [RFC] arm64: syscall: Direct PRNG kstack randomization
In-Reply-To: <202402202226.A6817927@keescook>
References: <20240221020258.1210148-1-jeremy.linton@arm.com>
 <202402202226.A6817927@keescook>
Message-ID: <6a053c64-f226-4b6f-9099-c9eda563cd2f@arm.com>

Hi,

Thanks for looking at this!

On 2/21/24 00:33, Kees Cook wrote:
> On Tue, Feb 20, 2024 at 08:02:58PM -0600, Jeremy Linton wrote:
>> The existing arm64 stack randomization uses the kernel rng to acquire
>> 5 bits of address space randomization. This is problematic because it
>> creates non determinism in the syscall path when the rng needs to be
>> generated or reseeded. This shows up as large tail latencies in some
>> benchmarks and directly affects the minimum RT latencies as seen by
>> cyclictest.
> 
> Some questions:
> 
> - for benchmarks, why not disable kstack randomization?

Benchmark isn't the right word here, maybe workload characterization?

Its hard to justify disabling what is perceived as a security feature, 
and enabled by default in downstream distros in a production environment.


> - if the existing pRNG reseeding is a problem here, why isn't it a
>    problem in the many other places it's used?

I don't have an answer for this, maybe it is? Our workloads/perf team 
which analyses end user problems tripped over this again, and with a bit 
of digging noticed it had been seen more than once with differing 
workloads. Its maybe more of a problem here because it affects 
everything making syscalls rather than just the subset of users 
requesting things which rely on the rng? Some of it could be the HW. The 
machine most of these tests have been run on has lots of cores and can 
have fairly long cache line latency.

> - I though the pRNG already did out-of-line reseeding?

Yes in 6.2.

My understanding from some traces is that the latency in recent kernel 
is largely from crng_make_state grabbing that global lock and doing 
crng_fast_key_erasure() under it which is getting worse with more cores 
active in the system. But now i'm a bit worried my own test doesn't 
fully match the workload system although I don't think they have seen 
the crng_reseed() in the syscall path.


> 
>> Other architectures are using timers/cycle counters for this function,
>> which is sketchy from a randomization perspective because it should be
>> possible to estimate this value from knowledge of the syscall return
>> time, and from reading the current value of the timer/counters.
> 
> The expectation is that it would be, at best, unstable.
> 
>> So, a poor rng should be better than the cycle counter if it is hard
>> to extract the stack offsets sufficiently to be able to detect the
>> PRNG's period.
>>
>> So, we can potentially choose a 'better' or larger PRNG, going as far
>> as using one of the CSPRNGs already in the kernel, but the overhead
>> increases appropriately. Further, there are a few options for
>> reseeding, possibly out of the syscall path, but is it even useful in
>> this case?
> 
> I'd love to find a way to avoid an pRNG that could be reconstructed
> given enough samples. (But perhaps this xorshift RNG resists that?)

Agree. I don't think it does.


Thanks again,


> 
> -Kees
> 
>> Reported-by: James Yang <james.yang at arm.com>
>> Reported-by: Shiyou Huang <shiyou.huang at arm.com>
>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>> ---
>>   arch/arm64/kernel/syscall.c | 55 ++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 54 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
>> index 9a70d9746b66..70143cb8c7be 100644
>> --- a/arch/arm64/kernel/syscall.c
>> +++ b/arch/arm64/kernel/syscall.c
>> @@ -37,6 +37,59 @@ static long __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
>>   	return syscall_fn(regs);
>>   }
>>   
>> +#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
>> +DEFINE_PER_CPU(u32, kstackrng);
>> +static u32 xorshift32(u32 state)
>> +{
>> +	/*
>> +	 * From top of page 4 of Marsaglia, "Xorshift RNGs"
>> +	 * This algorithm is intended to have a period 2^32 -1
>> +	 * And should not be used anywhere else outside of this
>> +	 * code path.
>> +	 */
>> +	state ^= state << 13;
>> +	state ^= state >> 17;
>> +	state ^= state << 5;
>> +	return state;
>> +}
>> +
>> +static u16 kstack_rng(void)
>> +{
>> +	u32 rng = raw_cpu_read(kstackrng);
>> +
>> +	rng = xorshift32(rng);
>> +	raw_cpu_write(kstackrng, rng);
>> +	return rng & 0x1ff;
>> +}
>> +
>> +/* Should we reseed? */
>> +static int kstack_rng_setup(unsigned int cpu)
>> +{
>> +	u32 rng_seed;
>> +
>> +	do {
>> +		rng_seed = get_random_u32();
>> +	} while (!rng_seed);
>> +	raw_cpu_write(kstackrng, rng_seed);
>> +	return 0;
>> +}
>> +
>> +static int kstack_init(void)
>> +{
>> +	int ret;
>> +
>> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/cpuinfo:kstackrandomize",
>> +				kstack_rng_setup, NULL);
>> +	if (ret < 0)
>> +		pr_err("kstack: failed to register rng callbacks.\n");
>> +	return 0;
>> +}
>> +
>> +arch_initcall(kstack_init);
>> +#else
>> +static u16 kstack_rng(void) { return 0; }
>> +#endif /* CONFIG_RANDOMIZE_KSTACK_OFFSET */
>> +
>>   static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
>>   			   unsigned int sc_nr,
>>   			   const syscall_fn_t syscall_table[])
>> @@ -66,7 +119,7 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
>>   	 *
>>   	 * The resulting 5 bits of entropy is seen in SP[8:4].
>>   	 */
>> -	choose_random_kstack_offset(get_random_u16() & 0x1FF);
>> +	choose_random_kstack_offset(kstack_rng());
>>   }
>>   
>>   static inline bool has_syscall_work(unsigned long flags)
>> -- 
>> 2.43.0
>>
> 



From geert at linux-m68k.org  Wed Feb 21 08:36:48 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 21 Feb 2024 17:36:48 +0100
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <7178ea35-da8d-4f25-9193-78dd11902eef@app.fastmail.com>
References: <20240221092826.748e70c4@canb.auug.org.au> <CAL_JsqKw9OXb=aOMni1qprzeWDBgmjdJef-6VAjwx0R--D+URw@mail.gmail.com>
 <ac9ddf79-6bc9-4daf-a271-82f8b3bca988@app.fastmail.com> <CAL_Jsq+L7uPimQfATs14EWCbqRO1vxDUmPie7=cChTLCf2od2g@mail.gmail.com>
 <CAMuHMdXNyU0eBcMe3EhhfahcRo2KtXzwdr+d_6AC-2529R3bmQ@mail.gmail.com> <7178ea35-da8d-4f25-9193-78dd11902eef@app.fastmail.com>
Message-ID: <CAMuHMdX0G90D4ifV1OVpjPX6q0d0UyMa5iu7-s+12KiAD9zL8w@mail.gmail.com>

Hi Arnd,

On Wed, Feb 21, 2024 at 4:58?PM Arnd Bergmann <arnd at arndb.de> wrote:
> On Wed, Feb 21, 2024, at 15:51, Geert Uytterhoeven wrote:
> > On Wed, Feb 21, 2024 at 3:27?PM Rob Herring <robh at kernel.org> wrote:
> >> On Wed, Feb 21, 2024 at 7:00?AM Arnd Bergmann <arnd at arndb.de> wrote:
> >> > On Wed, Feb 21, 2024, at 14:53, Rob Herring wrote:
> >> > > On Tue, Feb 20, 2024 at 3:28?PM Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> >> > >> arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> >> > >>
> >> > >> Introduced/exposed by commit
> >> > >>
> >> > >>   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
> >> > >>
> >> > >> I guess you missed some :-(
> >> > >
> >> > > No, Geert separately posted fixes for already.
> >> >
> >> > I did make the mistake of applying the final patch "dtc:
> >> > Enable dtc interrupt_provider check" to the arm/fixes branch
> >> > for 6.8 along with the other fixes.
> >> >
> >> > Clearly that should be separate and only go into mainline
> >> > after there are no more regressions, but now I'm unsure
> >> > about the other patches -- did you intend the dts fixes
> >> > for 6.8 or for the coming merge window?
> >>
> >> Either is fine with me. My intent was the whole series plus the
> >> Renesas fix to be applied together. Anything new that crops up we can
> >> fix on top.
> >
> > If you want me to move commit b4f97d1b5aeb6166 ("ARM: dts: renesas:
> > rcar-gen2: Add missing #interrupt-cells to DA9063 nodes") to
> > renesas-fixes, please tell me.
>
> Up to you. I have done some merges yesterday but have not started
> merging the dt branches, so you can still send an updated v2
> if you prefer (or have this patch in both branches). Please
> let me know how you decide.

OK, will move it to renesas-fixes.
Note that b4f97d1b5aeb6166 was not included yet in the last PR
I sent to soc, so you can continue merging DT branches.

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 ahalaney at redhat.com  Wed Feb 21 08:50:02 2024
From: ahalaney at redhat.com (Andrew Halaney)
Date: Wed, 21 Feb 2024 10:50:02 -0600
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <ZdYdJILy9_anIsrr@x1>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
 <56625c21-1b34-479b-b5b2-4c4d8b7a11b3@app.fastmail.com>
 <724jnhrbs6r4q6whynr3aon5w7mhfvetlgcnts4nukvtxbuium@mrjv6apjqk7r>
 <8ad96253-2053-4dc1-8dc1-d01d1fa36877@linaro.org>
 <ZdYdJILy9_anIsrr@x1>
Message-ID: <zeg7z74rtvqkwofbvgdf4dysz75c7jb3o3tjar5abuob3x5dce@rvc5dttxynpz>

On Wed, Feb 21, 2024 at 10:56:20AM -0500, Brian Masney wrote:
> On Wed, Feb 21, 2024 at 04:53:26PM +0100, Krzysztof Kozlowski wrote:
> > It would be cool to group also all the per-SoC needs in dedicated
> > fragments...
> 
> It would also be nice to have a fragment to enable the various tracing
> options.

+1, I cannot tell you the number of times I've been burned by the
defconfig not having those enabled and me forgetting :)



From mshavit at google.com  Wed Feb 21 08:52:21 2024
From: mshavit at google.com (Michael Shavit)
Date: Thu, 22 Feb 2024 00:52:21 +0800
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <CAKHBV25XrwOXyrYkjLZ7=5sNoFsM8VPS=HaJupswu6QDZ02LcQ@mail.gmail.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com> <20240215134952.GA690@willie-the-truck>
 <20240215160135.GL1088888@nvidia.com> <20240221134923.GA7362@willie-the-truck>
 <20240221140818.GA2635804@nvidia.com> <CAKHBV25XrwOXyrYkjLZ7=5sNoFsM8VPS=HaJupswu6QDZ02LcQ@mail.gmail.com>
Message-ID: <CAKHBV25BMzLWM6xsqNyEYMhWH9GFwzYWQaTvTrXnmbsre8B_+A@mail.gmail.com>

On Thu, Feb 22, 2024 at 12:19?AM Michael Shavit <mshavit at google.com> wrote:
>
> On Wed, Feb 21, 2024 at 10:08?PM Jason Gunthorpe <jgg at nvidia.com> wrote:
> >
> > On Wed, Feb 21, 2024 at 01:49:23PM +0000, Will Deacon wrote:
> >
> > > Very roughly, yes, although I'd go further and just return a bitmap of
> > > used qwords instead of tracking these bits. Basically, we could have some
> > > #defines saying which qwords are used by which configs,
> >
> > I don't think this will work well for CD's EPD0 case..
> >
> > static void arm_smmu_get_cd_used(const __le64 *ent, __le64 *used_bits)
> > {
> >         used_bits[0] = cpu_to_le64(CTXDESC_CD_0_V);
> >         if (!(ent[0] & cpu_to_le64(CTXDESC_CD_0_V)))
> >                 return;
> >         memset(used_bits, 0xFF, sizeof(struct arm_smmu_cd));
> >
> >         /* EPD0 means T0SZ/TG0/IR0/OR0/SH0/TTB0 are IGNORED */
> >         if (ent[0] & cpu_to_le64(CTXDESC_CD_0_TCR_EPD0)) {
> >                 used_bits[0] &= ~cpu_to_le64(
> >                         CTXDESC_CD_0_TCR_T0SZ | CTXDESC_CD_0_TCR_TG0 |
> >                         CTXDESC_CD_0_TCR_IRGN0 | CTXDESC_CD_0_TCR_ORGN0 |
> >                         CTXDESC_CD_0_TCR_SH0);
> >                 used_bits[1] &= ~cpu_to_le64(CTXDESC_CD_1_TTB0_MASK);
> >         }
> > }
> >
> > > and then we can
> > > simplify the algorithm while retaining the ability to reject updates
> > > to qwords which we're not expecting.
> >
> > It is not much simplification. arm_smmu_entry_qword_diff() gets a bit
> > shorter (not that it is complex anyhow) and other stuff gets worse.
>
> I think the simplification here is in the first if branch of
> arm_smmu_write_ste. With Will's proposal, we only perform a hitless
> update if there's a single used qword that needs updating. There's no
> longer a case where we first set unused bits in qwords whose other
> bits are in use. I'd argue that setting unused bits of a q word was
> very clever and removing the logic does conceptually simplify things,
> although yes it's not much fewer lines of code. I also don't think
> this throws away the entire logic of the current design, the idea of
> counting the number of qwords that differ and writing qwords that are
> unused first is still there.
>
> But, it does mean that hitless updates are only possible under
> narrower circumstances...We now have to figure out if there are
> transitions where this is problematic where we could previously assume
> that we'd always get the best behavior possible. Both in the present
> (i.e this SHCFG discussion and EPD0 case) and in the future if new
> parts of the configs start getting used. IMO not having to think about
> this is a meaningful advantage of the current solution.

To be more explicit, I hope we can keep the current solution. The
tests we added mitigates the extra complexity, while there's no
certainty that the 1-bit-per-qword proposal will always be
satisfactory in the future (nor have we even reached consensus that it
is satisfactory in the present with the part 2 CD series)


From afd at ti.com  Wed Feb 21 08:53:14 2024
From: afd at ti.com (Andrew Davis)
Date: Wed, 21 Feb 2024 10:53:14 -0600
Subject: [PATCH] arm64: dts: ti: k3-j721e-evm-pcie0-ep: Extend overlay for
 PCIE1 in EP Mode
In-Reply-To: <20240220105006.1056824-1-s-vadapalli@ti.com>
References: <20240220105006.1056824-1-s-vadapalli@ti.com>
Message-ID: <415ee6d4-fe26-4582-80f3-9b503d308fdf@ti.com>

On 2/20/24 4:50 AM, Siddharth Vadapalli wrote:
> Update the existing overlay which configures PCIE0 instance of PCIe on
> J721E-EVM in Endpoint mode of operation, in order to configure PCIE1
> instance of PCIe as well in Endpoint mode of operation. Hence, change the
> name of the overlay to reflect its updated functionality.
> 

What if I only want PCIe0 to be in EP mode? Why not make a separate
DTBO for PCIe1, that way I can have one in EP and the other in RC,
and mix and match as needed.

Andrew

> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
> ---
> 
> Hello,
> 
> This patch is based on linux-next tagged next-20240220.
> 
> Regards,
> Siddharth.
> 
>   arch/arm64/boot/dts/ti/Makefile               |  8 ++---
>   ....dtso => k3-j721e-evm-pcie0-pcie1-ep.dtso} | 30 +++++++++++++++++--
>   2 files changed, 32 insertions(+), 6 deletions(-)
>   rename arch/arm64/boot/dts/ti/{k3-j721e-evm-pcie0-ep.dtso => k3-j721e-evm-pcie0-pcie1-ep.dtso} (60%)
> 
> diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
> index d601c52ab181..c7c9508e3980 100644
> --- a/arch/arm64/boot/dts/ti/Makefile
> +++ b/arch/arm64/boot/dts/ti/Makefile
> @@ -75,7 +75,7 @@ k3-j721e-evm-dtbs := k3-j721e-common-proc-board.dtb k3-j721e-evm-quad-port-eth-e
>   dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi-exp-board.dtbo
> -dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo
> +dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-pcie1-ep.dtbo
>   dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
>   dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-dual-imx219.dtbo
>   
> @@ -126,8 +126,8 @@ k3-am68-sk-base-board-csi2-dual-imx219-dtbs := k3-am68-sk-base-board.dtb \
>   	k3-j721e-sk-csi2-dual-imx219.dtbo
>   k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
>   	k3-j721e-sk-csi2-dual-imx219.dtbo
> -k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
> -	k3-j721e-evm-pcie0-ep.dtbo
> +k3-j721e-evm-pcie0-pcie1-ep-dtbs := k3-j721e-common-proc-board.dtb \
> +	k3-j721e-evm-pcie0-pcie1-ep.dtbo
>   k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
>   	k3-j721e-sk-csi2-dual-imx219.dtbo
>   k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
> @@ -147,7 +147,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
>   	k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
>   	k3-am68-sk-base-board-csi2-dual-imx219-dtbs \
>   	k3-am69-sk-csi2-dual-imx219-dtbs \
> -	k3-j721e-evm-pcie0-ep.dtb \
> +	k3-j721e-evm-pcie0-pcie1-ep.dtb \
>   	k3-j721e-sk-csi2-dual-imx219-dtbs \
>   	k3-j721s2-evm-pcie1-ep.dtb
>   
> diff --git a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-pcie1-ep.dtso
> similarity index 60%
> rename from arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso
> rename to arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-pcie1-ep.dtso
> index 4062709d6579..5eaf304e3102 100644
> --- a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso
> +++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-pcie1-ep.dtso
> @@ -1,7 +1,7 @@
>   // SPDX-License-Identifier: GPL-2.0-only OR MIT
>   /**
> - * DT Overlay for enabling PCIE0 instance in Endpoint Configuration with the
> - * J7 common processor board.
> + * DT Overlay for enabling PCIE0 and PCIE1 instances in Endpoint Configuration
> + * with the J7 common processor board.
>    *
>    * J7 Common Processor Board Product Link: https://www.ti.com/tool/J721EXCPXEVM
>    *
> @@ -24,6 +24,10 @@ &pcie0_rc {
>   	status = "disabled";
>   };
>   
> +&pcie1_rc {
> +	status = "disabled";
> +};
> +
>   &cbass_main {
>   	#address-cells = <2>;
>   	#size-cells = <2>;
> @@ -50,4 +54,26 @@ pcie0_ep: pcie-ep at 2900000 {
>   		phys = <&serdes0_pcie_link>;
>   		phy-names = "pcie-phy";
>   	};
> +
> +	pcie1_ep: pcie-ep at 2910000 {
> +		compatible = "ti,j721e-pcie-ep";
> +		reg = <0x00 0x02910000 0x00 0x1000>,
> +		      <0x00 0x02917000 0x00 0x400>,
> +		      <0x00 0x0d800000 0x00 0x00800000>,
> +		      <0x00 0x18000000 0x00 0x08000000>;
> +		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
> +		interrupt-names = "link_state";
> +		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
> +		ti,syscon-pcie-ctrl = <&scm_conf 0x4074>;
> +		max-link-speed = <3>;
> +		num-lanes = <2>;
> +		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
> +		clocks = <&k3_clks 240 1>;
> +		clock-names = "fck";
> +		max-functions = /bits/ 8 <6>;
> +		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
> +		dma-coherent;
> +		phys = <&serdes1_pcie_link>;
> +		phy-names = "pcie-phy";
> +	};
>   };


From jeremy.linton at arm.com  Wed Feb 21 08:54:58 2024
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 21 Feb 2024 10:54:58 -0600
Subject: [RFC] arm64: syscall: Direct PRNG kstack randomization
In-Reply-To: <CAHmME9pYS=YZM1b0ftrjj_qjz_U4V8PsiLzB15JmBRr39Av2Ng@mail.gmail.com>
References: <20240221020258.1210148-1-jeremy.linton@arm.com>
 <202402202226.A6817927@keescook>
 <CAHmME9pYS=YZM1b0ftrjj_qjz_U4V8PsiLzB15JmBRr39Av2Ng@mail.gmail.com>
Message-ID: <305d26ba-8738-4244-801f-939e1a9730a1@arm.com>

Hi,

Thanks for looking at this.

On 2/21/24 06:44, Jason A. Donenfeld wrote:
> Hi,
> 
> On Wed, Feb 21, 2024 at 7:33?AM Kees Cook <keescook at chromium.org> wrote:
>>> +#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
>>> +DEFINE_PER_CPU(u32, kstackrng);
>>> +static u32 xorshift32(u32 state)
>>> +{
>>> +     /*
>>> +      * From top of page 4 of Marsaglia, "Xorshift RNGs"
>>> +      * This algorithm is intended to have a period 2^32 -1
>>> +      * And should not be used anywhere else outside of this
>>> +      * code path.
>>> +      */
>>> +     state ^= state << 13;
>>> +     state ^= state >> 17;
>>> +     state ^= state << 5;
>>> +     return state;
>>> +}
> 
> Can we please *not* introduce yet another RNG? You can't just sprinkle
> this stuff all over the place with no rhyme or reason.
> 
> If you need repeatable randomness, use prandom_u32_state() or similar.
> If you need non-repeatable randomness, use get_random_bytes() or
> similar.

Sure prandom_u32_state() should have a similar effect being a bit 
slower, and a bit better due to the extra hidden state.

> 
> If you think prandom_u32_state() is insufficient for some reason or
> doesn't have some property or performance that you want, submit a
> patch to make it better.
> 
> Looking at the actual intention here, of using repeatable randomness,
> I find the intent pretty weird. Isn't the whole point of kstack
> randomization that you can't predict it? If so, get_random_u*() is
> what you want. If performance isn't sufficient, let's figure out some

There isn't anything wrong with get_random_u16 from a kstack 
randomization standpoint, except for the latency spikes of course.

> way to improve performance. And as Kees said, if the point of this is
> to have some repeatable benchmarks, maybe just don't enable the
> security-intended code whose purpose is non-determinism? Both exploits
> and now apparently benchmarks like determinism.

As I mentioned in the other email, benchmark is probably the wrong word. 
Its a better QoS response time distributions for a given workload. And 
its not strictly in RT kernel latency test types of things, but normal 
memcached style workloads on !RT kernels as well.




From ansuelsmth at gmail.com  Wed Feb 21 08:57:00 2024
From: ansuelsmth at gmail.com (Christian Marangi)
Date: Wed, 21 Feb 2024 17:57:00 +0100
Subject: [PATCH v2 0/2] ARM: decompressor: support AUTO_ZRELADDR and
 appended DTB
In-Reply-To: <20240121203009.9257-1-ansuelsmth@gmail.com>
References: <20240121203009.9257-1-ansuelsmth@gmail.com>
Message-ID: <65d62b60.050a0220.c7b96.614e@mx.google.com>

On Sun, Jan 21, 2024 at 09:29:32PM +0100, Christian Marangi wrote:
> This series try to address a long lasting problem with legacy device
> that require an appended DTB and the use of AUTO_ZRELADDR.
> 
> With these device AUTO_ZRELADDR is not possible if for some reason at
> the start of the RAM it's needed to reserve some space. (example qcom SoC
> that allocate reserved space for SMEM)
> 
> In the current implementation with appended DTB and AUTO_ZRELADDR,
> the memory start is only derived from the PC register and it can't be
> changed by declaring additional info in the DTS.
> 
> In a normal setup, we have an intentional undocumented chosen property
> to handle this and the memory node to declare the start of the memory.
> 
> With this applied and ARM_ATAG_DTB_COMPAT_IGNORE_MEM enabled (more 
> info in the related patch) ipq806x can boot right away with AUTO_ZRELADDR
> enabled and a correct memory node defined in DTS.
> 
> It's needed to ignore MEM ATAGs as most of the time the values from the
> bootloader are hardcoded and OEM didn't care to actually provide them
> resulting in funny situation where a Netgear R7800 with 512Mb of RAM
> have Uboot passing 1.7GB of RAM with ATAGS.
> 
> While MEM ATAG may be broken, other ATAG like serial number or bootargs
> might still be useful for partition declaration (cmdlinepart) or other
> info hence DTB_COMPAT is still needed in these case and can't be
> disabled.
> 
> I'm open to any suggestion on how this can be improved and I would love
> some additional testing on other legacy platform but I assume this will
> permit many legacy device to be correctly supported without having to
> hardcode address.
> 
> Changes v2:
> - Add Review and Ack Tags
> - Use IS_ENABLED instead of global variable
> 
> Christian Marangi (2):
>   ARM: decompressor: support memory start validation for appended DTB
>   ARM: decompressor: add option to ignore MEM ATAGs
> 
>  arch/arm/Kconfig                        | 12 ++++++++++++
>  arch/arm/boot/compressed/atags_to_fdt.c |  4 ++++
>  arch/arm/boot/compressed/head.S         | 22 ++++++++++++++++++++++
>  3 files changed, 38 insertions(+)
> 
>

Any news for this?

-- 
	Ansuel


From geissonator at gmail.com  Wed Feb 21 08:57:38 2024
From: geissonator at gmail.com (Andrew Geissler)
Date: Wed, 21 Feb 2024 10:57:38 -0600
Subject: [PATCH] ipmi: kcs: Update OBF poll timeout to reduce latency
In-Reply-To: <9680ad7d7a48fc36a0572dc2286a1229a29341fe.camel@codeconstruct.com.au>
References: <20240220123615.963916-1-geissonator@gmail.com>
 <a9169894-6972-49c0-a1d4-d80863f5b511@molgen.mpg.de>
 <ZdT+eThnYqb3iawF@mail.minyard.net>
 <9680ad7d7a48fc36a0572dc2286a1229a29341fe.camel@codeconstruct.com.au>
Message-ID: <527F52AB-0070-43EA-BE82-945280CA2AEE@gmail.com>



> On Feb 20, 2024, at 4:36?PM, Andrew Jeffery <andrew at codeconstruct.com.au> wrote:
> 
> On Tue, 2024-02-20 at 13:33 -0600, Corey Minyard wrote:
>> On Tue, Feb 20, 2024 at 04:51:21PM +0100, Paul Menzel wrote:
>>> Dear Andrew,
>> 
>> It's because increasing that number causes it to poll longer for the
>> event, the host takes longer than 100us to generate the event, and if
>> the event is missed the time when it is checked again is very long.
>> 
>> Polling for 100us is already pretty extreme. 200us is really too long.
>> 
>> The real problem is that there is no interrupt for this.  I'd also guess
>> there is no interrupt on the host side, because that would solve this
>> problem, too, as it would certainly get around to handling the interupt
>> in 100us.  I'm assuming the host driver is not the Linux driver, as it
>> should also handle this in a timely manner, even when polling.
> 
> I expect the issues Andrew G is observing are with the Power10 boot
> firmware. The boot firmware only polls. The runtime firmware enables
> interrupts.

Yep, this is with the low level host boot firmware.
Also, further testing over night showed that 200us wasn?t enough for
our larger Everest P10 machines, I needed to go to 300us. As we
were struggling to allow 200us, I assume 300us is going to be a no-go.

>> 
> 
>> 
>> The right way to fix this is probably to do the same thing the host side
>> Linux driver does.  It has a kernel thread that is kicked off to do
>> this.  Unfortunately, that's more complicated to implement, but it
>> avoids polling in this location (which causes latency issues on the BMC
>> side) and lets you poll longer without causing issues.
> 
> In Andrew G's case he's talking MCTP over KCS using a vendor-defined
> transport binding (that also leverages LPC FWH cycles for bulk data
> transfers)[1]. I think it could have taken more inspiration from the
> IPMI KCS protocol: It might be worth an experiment to write the dummy
> command value to IDR from the host side after each ODR read to signal
> the host's clearing of OBF (no interrupt for the BMC) with an IBF
> (which does interrupt the BMC). And doing the obverse for the BMC. Some
> brief thought suggests that if the dummy value is read there's no need
> to send a dummy value in reply (as it's an indicator to read the status
> register). With that the need for the spin here (or on the host side)
> is reduced at the cost of some constant protocol overhead.
> 

Thanks for the quick reviews and ideas.
I?ll see if I can find someone on the team to help out with Andrew J?s
thoughts and if that doesn?t work, look into the kernel thread idea.

> 
> 
> Andrew J




From theo.lebrun at bootlin.com  Wed Feb 21 08:58:13 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Wed, 21 Feb 2024 17:58:13 +0100
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <CZ94LGRSF9KN.15ZO1VRMIQVR8@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>
 <20240216022704.GB850600-robh@kernel.org>
 <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>
 <CACRpkdZZhhzg5SY7U5dv_OfLEVejRFom4V9nCfkQXunAw1ZXSw@mail.gmail.com>
 <CZ94LGRSF9KN.15ZO1VRMIQVR8@bootlin.com>
Message-ID: <CZAX02IL1N1J.2GQR9D73GLRZB@bootlin.com>

Hello,

On Mon Feb 19, 2024 at 3:29 PM CET, Th?o Lebrun wrote:
> On Mon Feb 19, 2024 at 3:06 PM CET, Linus Walleij wrote:
> > On Fri, Feb 16, 2024 at 10:16?AM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
> > > i2c-mpc (fsl,timeout) and i2c-gpio (i2c-gpio,timeout-ms). I agree this
> > > prop has no reason to be compatible-specific.
> > >
> > > Feedback from dt-bindings and I2C host maintainers would be useful: what
> > > should the property be named? Having the unit makes it self-descriptive,
> > > which sounds like a good idea to me. timeout-usecs, timeout-us, another
> > > option?
> >
> > Use i2c-transfer-timeout-ms in my opinion, so it us crystal clear
> > what that property is for.
>
> Using ?s (microseconds) would be OK? I'm not sure yet about the exact
> timeout desired but a one millisecond granularity might not be enough
> for the Mobileye usecase.
>
> Expect incoming patches to use the I2C controller in Fast Mode Plus
> (1Mbps) and High Speed Mode (3.4Mbps). Gotta go fast!
>
> > As Rob mentioned this isn't in the kernel schemas but in dtschema, so
> > you need to patch this:
> > https://github.com/robherring/dt-schema
>
> Indeed. The other question if we do microseconds is the
> suffix: -us, -usecs, -microseconds, etc? I picked -usecs for my v1, but
> a grep tells me I am the only user of this suffix. -us is much more
> common.
>
> BTW i2c-controller.yaml already has a ?s timeout:
> i2c-scl-clk-low-timeout-us

Note: I've sent a draft patch to dt-schema. See:
https://github.com/devicetree-org/dt-schema/pull/129

Feedback from I2C maintainers would confirm or infirm that this goes in
the right direction.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From mgonzalez at freebox.fr  Wed Feb 21 08:58:49 2024
From: mgonzalez at freebox.fr (Marc Gonzalez)
Date: Wed, 21 Feb 2024 17:58:49 +0100
Subject: Calling OPTEE_SMC_CALL_GET_OS_UUID from driver code
In-Reply-To: <CAFA6WYOMHEygroKGaV7Jw7c8=nrnVrW=Vqk5r1yuTR5rwFijCQ@mail.gmail.com>
References: <443901af-6abd-4a29-b6b6-f06b6d3ce34c@freebox.fr>
 <CAFA6WYOMHEygroKGaV7Jw7c8=nrnVrW=Vqk5r1yuTR5rwFijCQ@mail.gmail.com>
Message-ID: <5a2134d0-433f-4b6f-9fda-22edae74979e@freebox.fr>

On 21/02/2024 08:40, Sumit Garg wrote:

> Hi Marc,
> 
> On Tue, 20 Feb 2024 at 22:59, Marc Gonzalez wrote:
>>
>> Hello,
>>
>> The driver code I'm working on hard-codes
>>
>> #define TEE_SMC_FAST_CALL_VAL(func_num) \
>>     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
>>             ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
>>
>> #define TEE_SMC_FUNCID_CALLS_UID 0xFF01
>> #define TEE_SMC_CALLS_UID \
>>     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
>>                ARM_SMCCC_OWNER_TRUSTED_OS_END, \
>>                TEE_SMC_FUNCID_CALLS_UID)
>>
>>     arm_smccc_smc(TEE_SMC_CALLS_UID,
>>             0, 0, 0/*is_swap*/, 0, 0, 0, 0, &res);
>>     dev_err(dev, "TEE UID %x %x %x %x\n", res.a0, res.a1, res.a2, res.a3);
>>
>>
>> but it seems I would be required to somehow use
>> OPTEE_SMC_CALL_GET_OS_UUID
>>
>> But it's not exported, and no code seems to use it...?
> 
> Can you describe your use-case to require direct
> OPTEE_SMC_CALL_GET_OS_UUID invocation?

Turns out the GET_OS_UUID call was just debug code to make sure
we were getting the expected reply.

I have removed it from the production code.
Below is the current code.

diff --git a/drivers/staging/media/meson/vdec/vdec_1.c b/drivers/staging/media/meson/vdec/vdec_1.c
index 3fe2de0c9331f..120bb1847aa38 100644
--- a/drivers/staging/media/meson/vdec/vdec_1.c
+++ b/drivers/staging/media/meson/vdec/vdec_1.c
@@ -8,7 +8,10 @@
  */
 
 #include <linux/firmware.h>
+#include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/arm-smccc.h>
+#include <soc/amlogic/socinfo.h>
 
 #include "vdec_1.h"
 #include "vdec_helpers.h"
@@ -22,6 +25,45 @@
 
 #define MC_SIZE			(4096 * 4)
 
+static int
+vdec_1_load_firmware_optee(struct amvdec_session *sess)
+{
+	struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops;
+	struct amvdec_core *core = sess->core;
+	struct device *dev = core->dev_dec;
+	struct arm_smccc_res res;
+	u32 pixfmt = sess->fmt_out->pixfmt;
+	int fw_id = -1;
+
+#define TEE_SMC_FAST_CALL_VAL(func_num) \
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
+
+#define TEE_SMC_FUNCID_LOAD_VIDEO_FW 15
+#define TEE_SMC_LOAD_VIDEO_FW TEE_SMC_FAST_CALL_VAL(TEE_SMC_FUNCID_LOAD_VIDEO_FW)
+#define OPTEE_VDEC_LEGACY 0
+#define VIDEO_DEC_MPEG12 0
+#define VIDEO_DEC_H264 11
+
+	// Load wrong firmware, so that TA will reset hw component for us
+	arm_smccc_smc(TEE_SMC_LOAD_VIDEO_FW, 1, OPTEE_VDEC_LEGACY, 0, 0, 0, 0, 0, &res);
+
+	if (pixfmt == V4L2_PIX_FMT_H264)
+		fw_id = 11;
+
+	if (pixfmt == V4L2_PIX_FMT_MPEG1 || pixfmt == V4L2_PIX_FMT_MPEG2)
+		fw_id = 0;
+
+	arm_smccc_smc(TEE_SMC_LOAD_VIDEO_FW, fw_id, OPTEE_VDEC_LEGACY, 0, 0, 0, 0, 0, &res);
+	dev_info(dev, "Load firmware %d: ret=%d\n", fw_id, res.a0);
+
+	msleep(100);
+
+	if (codec_ops->load_extended_firmware)
+		codec_ops->load_extended_firmware(sess, 0, 0);
+
+	return 0;
+}
+
 static int
 vdec_1_load_firmware(struct amvdec_session *sess, const char *fwname)
 {
@@ -209,7 +251,11 @@ static int vdec_1_start(struct amvdec_session *sess)
 
 	vdec_1_stbuf_power_up(sess);
 
-	ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path);
+	if (meson_get_secure_boot_state() == 1)
+		ret = vdec_1_load_firmware_optee(sess);
+	else
+		ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path);
+
 	if (ret)
 		goto stop;
 
@@ -232,6 +278,13 @@ static int vdec_1_start(struct amvdec_session *sess)
 	/* Let the firmware settle */
 	usleep_range(10, 20);
 
+	/*
+	 * When running secure boot, it looks like the codec needs
+	 * more time to settle (perhaps to authenticate the image?)
+	 */
+	if (meson_get_secure_boot_state() == 1)
+		msleep(100);
+
 	return 0;
 
 stop:


>> $ git grep OPTEE_SMC_CALL_GET_OS_UUID
>> Documentation/tee/op-tee.rst:- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
>> drivers/tee/optee/optee_smc.h:#define OPTEE_SMC_CALL_GET_OS_UUID \
>>
>> How do I make calls to OP-TEE from driver code?
> 
> The TEE driver API documentation is here [1] and you can refer to the
> existing OP-TEE RNG driver here for reference.
> 
> [1] https://docs.kernel.org/driver-api/tee.html
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/char/hw_random/optee-rng.c

Wow, this looks very different from our code.

Are we not supposed to call arm_smccc_smc() from driver code?
Looks like no one else is calling arm_smccc_smc with an owner
equal to ARM_SMCCC_OWNER_TRUSTED_OS...

Regards



From lkp at intel.com  Wed Feb 21 08:57:52 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 22 Feb 2024 00:57:52 +0800
Subject: [PATCH 2/4] mm: pgalloc: support address-conditional pmd
 allocation
In-Reply-To: <20240220203256.31153-3-mbland@motorola.com>
References: <20240220203256.31153-3-mbland@motorola.com>
Message-ID: <202402220006.5v6axq6B-lkp@intel.com>

Hi Maxwell,

kernel test robot noticed the following build errors:

[auto build test ERROR on b401b621758e46812da61fa58a67c3fd8d91de0d]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxwell-Bland/mm-vmalloc-allow-arch-specific-vmalloc_node-overrides/20240221-043458
base:   b401b621758e46812da61fa58a67c3fd8d91de0d
patch link:    https://lore.kernel.org/r/20240220203256.31153-3-mbland%40motorola.com
patch subject: [PATCH 2/4] mm: pgalloc: support address-conditional pmd allocation
config: arm-defconfig (https://download.01.org/0day-ci/archive/20240222/202402220006.5v6axq6B-lkp at intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project.git f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240222/202402220006.5v6axq6B-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402220006.5v6axq6B-lkp at intel.com/

All errors (new ones prefixed by >>):

>> mm/memory.c:459:3: error: implicit declaration of function 'pmd_populate_kernel_at' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                   pmd_populate_kernel_at(&init_mm, pmd, new, address);
                   ^
   mm/memory.c:459:3: note: did you mean 'pmd_populate_kernel'?
   arch/arm/include/asm/pgalloc.h:125:1: note: 'pmd_populate_kernel' declared here
   pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
   ^
   1 error generated.


vim +/pmd_populate_kernel_at +459 mm/memory.c

   449	
   450	int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
   451	{
   452		pte_t *new = pte_alloc_one_kernel(&init_mm);
   453		if (!new)
   454			return -ENOMEM;
   455	
   456		spin_lock(&init_mm.page_table_lock);
   457		if (likely(pmd_none(*pmd))) {	/* Has another populated it ? */
   458			smp_wmb(); /* See comment in pmd_install() */
 > 459			pmd_populate_kernel_at(&init_mm, pmd, new, address);
   460			new = NULL;
   461		}
   462		spin_unlock(&init_mm.page_table_lock);
   463		if (new)
   464			pte_free_kernel(&init_mm, new);
   465		return 0;
   466	}
   467	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From ghennadi.procopciuc at oss.nxp.com  Wed Feb 21 09:00:10 2024
From: ghennadi.procopciuc at oss.nxp.com (Ghennadi Procopciuc)
Date: Wed, 21 Feb 2024 19:00:10 +0200
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
References: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
 <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
 <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
Message-ID: <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>

On 2/21/24 17:43, Krzysztof Kozlowski wrote:
> On 21/02/2024 16:19, Ghennadi Procopciuc wrote:
>> On 2/21/24 16:45, Krzysztof Kozlowski wrote:
>>> On 21/02/2024 15:42, Krzysztof Kozlowski wrote:
>>>> On 21/02/2024 13:01, Ghennadi Procopciuc wrote:
>>>>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>>>>
>>>>> Add myself as a maintainer of the NXP S32G DT files.
>>>>
>>>> No need for cover letters for single patches. OTOH, this commit msg is
>>>> empty...
>> Thank you, I can correct that.
>>
>>>> Plus your patch looks corrupted (wrong encoding): F??rber
>>
>> Indeed, it is due to 'Content-Type: text/plain; charset="us-ascii"'.
>> I can fix this as part of v2.
>>
>>>> BTW, did you contribute anything to the upstream Linux kernel? Do you
>>>> know the process? Downstream does not really matter.
>>>
>>> I found the answer:
>>>
>>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
>>>
>>> Does not look like. Please get some upstream work experience first.
>>>
>>> https://lore.kernel.org/all/?q=f%3Aghennadi.procopciuc%40oss.nxp.com
>>
>> Although I am new to upstream communities and may make mistakes, I am
>> eager to learn and improve.
>>
>> After leaving SuSe[0], the current maintainer of the NXP S32G DT files
>> became inactive[1]. As a result, this area is not currently being
>> maintained. This is the actual reason why I attempted to add myself as a
>> maintainer of that area. Although I acknowledge that I may not have
>> enough experience to become a maintainer, I am concerned that the NXP
>> S32G DT patch submission may be blocked for everyone due to the current
>> situation.
> 
> I would be just happy to see first actual contributions or any sort of
> activity, like reviewing, before taking over something.
> 
> You do not need to become maintainer to provide reviews. By reviewing
> patches you already reduce burden/work from the maintainers.
> 
> Best regards,
> Krzysztof
> 

I fully understand and agree with your perspective on this matter and
accept the fact that I will not be a maintainer as initially intended.
Furthermore, I am very willing to participate in any reviews related to
S32G SoCs.

Patches, including those I have created ([0], [1]), will likely be
submitted for this area. This is because each enabled driver for S32G
SoCs is expected to have at least one node in the device tree. These
patches will undergo review and receive feedback. However, the upstream
process will come to a halt at this point since there are no maintainers
to apply and integrate them.?

I do not know how this situation should be handled, given my lack of
experience in upstreaming maintenance. The documentation for the Linux
kernel is insufficient in providing guidance [2] on how to handle
inactive maintainers and it is unclear who should take over their
responsibilities. This is likely not the first time this has happened in
the kernel's history.

Could you please guide me on how these patches should be integrated into
a maintainer's? tree and by whom?

[0]
https://lore.kernel.org/all/94742ebd-bc3a-4726-9ba7-5954203e4da1 at suse.com/
[1]
https://lore.kernel.org/all/372ed255-85b7-4f18-a28e-82e18171f7e3 at suse.com/
[2]
https://docs.kernel.org/maintainer/feature-and-driver-maintainers.html#non-compliance

Best regards,
Ghennadi



From jgg at nvidia.com  Wed Feb 21 09:06:46 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Wed, 21 Feb 2024 13:06:46 -0400
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <CAKHBV25XrwOXyrYkjLZ7=5sNoFsM8VPS=HaJupswu6QDZ02LcQ@mail.gmail.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240215134952.GA690@willie-the-truck>
 <20240215160135.GL1088888@nvidia.com>
 <20240221134923.GA7362@willie-the-truck>
 <20240221140818.GA2635804@nvidia.com>
 <CAKHBV25XrwOXyrYkjLZ7=5sNoFsM8VPS=HaJupswu6QDZ02LcQ@mail.gmail.com>
Message-ID: <20240221170646.GX13330@nvidia.com>

On Thu, Feb 22, 2024 at 12:19:06AM +0800, Michael Shavit wrote:
> I think the simplification here is in the first if branch of
> arm_smmu_write_ste. With Will's proposal, we only perform a hitless
> update if there's a single used qword that needs updating.

The normal cases like BYPASS -> S1 still require updating QW[1,2]
before updating QW[0], and the reverse as well. That still needs the
three entry_set()'s to process the same way. 

>From what I can see if we did 1 bit per qw:

 - get_used becomes harder to explain but shorter (we ignore the used
   qw 1 for bypass/abort)
 - arm_smmu_entry_qword_diff becomes a bit simpler, less bitwise logic,
   no unused_update
 - arm_smmu_write_entry() has the same logic but unused_update is
   replaced by target
 - We have to hack something to make SHCFG=1 - change the make
   functions or have arm_smmu_write_ste() force SHCFG=1
 - We have to write a seperate programming logic for CD -
   always do V=0/1 for normal updates, and a special EPD0 flow.

All doable, but I don't see the benefit in aggregate..

Jason


From lkp at intel.com  Wed Feb 21 09:08:33 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 22 Feb 2024 01:08:33 +0800
Subject: [PATCH 2/4] mm: pgalloc: support address-conditional pmd
 allocation
In-Reply-To: <20240220203256.31153-3-mbland@motorola.com>
References: <20240220203256.31153-3-mbland@motorola.com>
Message-ID: <202402220052.S3IUgmez-lkp@intel.com>

Hi Maxwell,

kernel test robot noticed the following build errors:

[auto build test ERROR on b401b621758e46812da61fa58a67c3fd8d91de0d]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxwell-Bland/mm-vmalloc-allow-arch-specific-vmalloc_node-overrides/20240221-043458
base:   b401b621758e46812da61fa58a67c3fd8d91de0d
patch link:    https://lore.kernel.org/r/20240220203256.31153-3-mbland%40motorola.com
patch subject: [PATCH 2/4] mm: pgalloc: support address-conditional pmd allocation
config: um-allmodconfig (https://download.01.org/0day-ci/archive/20240222/202402220052.S3IUgmez-lkp at intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 36adfec155de366d722f2bac8ff9162289dcf06c)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240222/202402220052.S3IUgmez-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402220052.S3IUgmez-lkp at intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from kernel/fork.c:34:
   In file included from include/linux/mempolicy.h:15:
   In file included from include/linux/pagemap.h:11:
   In file included from include/linux/highmem.h:12:
   In file included from include/linux/hardirq.h:11:
   In file included from arch/um/include/asm/hardirq.h:5:
   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/um/include/asm/io.h:24:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     547 |         val = __raw_readb(PCI_IOBASE + addr);
         |                           ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     560 |         val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
      37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
         |                                                   ^
   In file included from kernel/fork.c:34:
   In file included from include/linux/mempolicy.h:15:
   In file included from include/linux/pagemap.h:11:
   In file included from include/linux/highmem.h:12:
   In file included from include/linux/hardirq.h:11:
   In file included from arch/um/include/asm/hardirq.h:5:
   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/um/include/asm/io.h:24:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     573 |         val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
      35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
         |                                                   ^
   In file included from kernel/fork.c:34:
   In file included from include/linux/mempolicy.h:15:
   In file included from include/linux/pagemap.h:11:
   In file included from include/linux/highmem.h:12:
   In file included from include/linux/hardirq.h:11:
   In file included from arch/um/include/asm/hardirq.h:5:
   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/um/include/asm/io.h:24:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     584 |         __raw_writeb(value, PCI_IOBASE + addr);
         |                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     594 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     604 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:692:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     692 |         readsb(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:700:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     700 |         readsw(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:708:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     708 |         readsl(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:717:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     717 |         writesb(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:726:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     726 |         writesw(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:735:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     735 |         writesl(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   In file included from kernel/fork.c:105:
   In file included from arch/um/include/asm/pgalloc.h:13:
>> include/asm-generic/pgalloc.h:149:20: warning: function 'pmd_populate_kernel' has internal linkage but is not defined [-Wundefined-internal]
     149 | static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
         |                    ^
   include/asm-generic/pgalloc.h:159:2: note: used here
     159 |         pmd_populate_kernel(mm, pmdp, ptep);
         |         ^
   13 warnings generated.
--
   In file included from mm/mremap.c:12:
   In file included from include/linux/mm_inline.h:8:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:26:
   In file included from include/linux/kernel_stat.h:9:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from arch/um/include/asm/hardirq.h:5:
   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/um/include/asm/io.h:24:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     547 |         val = __raw_readb(PCI_IOBASE + addr);
         |                           ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     560 |         val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
      37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
         |                                                   ^
   In file included from mm/mremap.c:12:
   In file included from include/linux/mm_inline.h:8:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:26:
   In file included from include/linux/kernel_stat.h:9:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from arch/um/include/asm/hardirq.h:5:
   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/um/include/asm/io.h:24:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     573 |         val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
      35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
         |                                                   ^
   In file included from mm/mremap.c:12:
   In file included from include/linux/mm_inline.h:8:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:26:
   In file included from include/linux/kernel_stat.h:9:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from arch/um/include/asm/hardirq.h:5:
   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/um/include/asm/io.h:24:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     584 |         __raw_writeb(value, PCI_IOBASE + addr);
         |                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     594 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     604 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:692:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     692 |         readsb(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:700:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     700 |         readsw(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:708:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     708 |         readsl(PCI_IOBASE + addr, buffer, count);
         |                ~~~~~~~~~~ ^
   include/asm-generic/io.h:717:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     717 |         writesb(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:726:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     726 |         writesw(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   include/asm-generic/io.h:735:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     735 |         writesl(PCI_IOBASE + addr, buffer, count);
         |                 ~~~~~~~~~~ ^
   In file included from mm/mremap.c:31:
   In file included from arch/um/include/asm/pgalloc.h:13:
>> include/asm-generic/pgalloc.h:149:20: warning: function 'pmd_populate_kernel' has internal linkage but is not defined [-Wundefined-internal]
     149 | static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
         |                    ^
   include/asm-generic/pgalloc.h:159:2: note: used here
     159 |         pmd_populate_kernel(mm, pmdp, ptep);
         |         ^
   mm/mremap.c:228:20: warning: unused function 'arch_supports_page_table_move' [-Wunused-function]
     228 | static inline bool arch_supports_page_table_move(void)
         |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   mm/mremap.c:227:39: note: expanded from macro 'arch_supports_page_table_move'
     227 | #define arch_supports_page_table_move arch_supports_page_table_move
         |                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   14 warnings generated.
--
   arch/um/kernel/skas/mmu.c:17:5: warning: no previous prototype for function 'init_new_context' [-Wmissing-prototypes]
      17 | int init_new_context(struct task_struct *task, struct mm_struct *mm)
         |     ^
   arch/um/kernel/skas/mmu.c:17:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
      17 | int init_new_context(struct task_struct *task, struct mm_struct *mm)
         | ^
         | static 
   arch/um/kernel/skas/mmu.c:60:6: warning: no previous prototype for function 'destroy_context' [-Wmissing-prototypes]
      60 | void destroy_context(struct mm_struct *mm)
         |      ^
   arch/um/kernel/skas/mmu.c:60:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
      60 | void destroy_context(struct mm_struct *mm)
         | ^
         | static 
   In file included from arch/um/kernel/skas/mmu.c:11:
   In file included from arch/um/include/asm/pgalloc.h:13:
>> include/asm-generic/pgalloc.h:149:20: warning: function 'pmd_populate_kernel' has internal linkage but is not defined [-Wundefined-internal]
     149 | static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
         |                    ^
   include/asm-generic/pgalloc.h:159:2: note: used here
     159 |         pmd_populate_kernel(mm, pmdp, ptep);
         |         ^
   3 warnings generated.
--
   /usr/bin/ld: warning: .tmp_vmlinux.kallsyms1 has a LOAD segment with RWX permissions
   /usr/bin/ld: mm/memory.o: in function `pmd_populate_kernel_at':
>> include/asm-generic/pgalloc.h:159: undefined reference to `pmd_populate_kernel'
   clang: error: linker command failed with exit code 1 (use -v to see invocation)


vim +159 include/asm-generic/pgalloc.h

   144	
   145	#ifdef __HAVE_ARCH_ADDR_COND_PMD
   146	static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
   147				pte_t *ptep, unsigned long address);
   148	#else
 > 149	static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
   150				pte_t *ptep);
   151	#endif
   152	
   153	static inline void pmd_populate_kernel_at(struct mm_struct *mm, pmd_t *pmdp,
   154				pte_t *ptep, unsigned long address)
   155	{
   156	#ifdef __HAVE_ARCH_ADDR_COND_PMD
   157		pmd_populate_kernel(mm, pmdp, ptep, address);
   158	#else
 > 159		pmd_populate_kernel(mm, pmdp, ptep);
   160	#endif
   161	}
   162	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From festevam at gmail.com  Wed Feb 21 09:16:57 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 21 Feb 2024 14:16:57 -0300
Subject: [PATCH v2] ARM: dts: imx53-qsb: add support for the HDMI expander
In-Reply-To: <20240206-imx53-qsb-hdmi-v2-1-a025fe0c4362@linaro.org>
References: <20240206-imx53-qsb-hdmi-v2-1-a025fe0c4362@linaro.org>
Message-ID: <CAOMZO5Ad7yZWwaBi5Ec9ufF4b_vWov5KX=k+c-FvVgbLUCf8NQ@mail.gmail.com>

On Tue, Feb 6, 2024 at 12:26?PM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> Add support for the MCIMXHDMICARD expansion card attached to the iMX53
> QSB / QSRB platforms. This enables HDMI output on those devices.
>
> Reviewed-by: Fabio Estevam <festevam at gmail.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Tested-by: Fabio Estevam <festevam at gmail.com>


From bjorn at kernel.org  Wed Feb 21 09:22:40 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Wed, 21 Feb 2024 18:22:40 +0100
Subject: [PATCH v13 06/13] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <CAK9=C2WXR49KZg3rstChqAHda+hUhPm3AEo6o2jh0NM3kvoSUA@mail.gmail.com>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-7-apatel@ventanamicro.com>
 <87frxnfj3p.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2Xnzg3KAVETXN+ZGLWhVtaJuU4uXs3WH2ZondkBJMHFcA@mail.gmail.com>
 <874je2yqn9.fsf@all.your.base.are.belong.to.us>
 <CAK9=C2WXR49KZg3rstChqAHda+hUhPm3AEo6o2jh0NM3kvoSUA@mail.gmail.com>
Message-ID: <87frxl3f6n.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

> On Wed, Feb 21, 2024 at 5:29?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>>
>> Anup Patel <apatel at ventanamicro.com> writes:
>>
>> >> > +void imsic_vector_mask(struct imsic_vector *vec)
>> >> > +{
>> >> > +     struct imsic_local_priv *lpriv;
>> >> > +
>> >> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
>> >> > +     if (WARN_ON(&lpriv->vectors[vec->local_id] != vec))
>> >> > +             return;
>> >> > +
>> >> > +     /*
>> >> > +      * This function is called through Linux irq subsystem with
>> >> > +      * irqs disabled so no need to save/restore irq flags.
>> >> > +      */
>> >> > +
>> >> > +     raw_spin_lock(&lpriv->lock);
>> >> > +
>> >> > +     vec->enable = false;
>> >> > +     bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
>> >> > +     __imsic_remote_sync(lpriv, vec->cpu);
>> >> > +
>> >> > +     raw_spin_unlock(&lpriv->lock);
>> >> > +}
>> >>
>> >> Really nice that you're using a timer for the vector affinity change,
>> >> and got rid of the special/weird IMSIC/sync IPI. Can you really use a
>> >> timer for mask/unmask? That makes the mask/unmask operation
>> >> asynchronous!
>> >>
>> >> That was what I was trying to get though with this comment:
>> >> https://lore.kernel.org/linux-riscv/87sf24mo1g.fsf at all.your.base.are.belong.to.us/
>> >>
>> >> Also, using the smp_* IPI functions, you can pass arguments, so you
>> >> don't need the dirty_bitmap tracking the changes.
>> >
>> > The mask/unmask operations are called with irqs disabled so if
>> > CPU X does synchronous IPI to another CPU Y from mask/unmask
>> > operation then while CPU X is waiting for IPI to complete it cannot
>> > receive IPI from other CPUs which can lead to crashes and stalls.
>> >
>> > In general, we should not do any block/busy-wait work in
>> > mask/unmask operation of an irqchip driver.
>>
>> Hmm, OK. Still, a bit odd that when the .irq_mask callback return, the
>> masking is not actually completed.
>>
>> 1. CPU 0 tries to mask an interrupt tried to CPU 1.
>> 2. The timer is queued on CPU 1.
>> 3. The call irq_mask returns on CPU 0
>> 4. ...the irq is masked at some future point, determined by the callback
>>    at CPU 1
>>
>> Is that the expected outcome?
>
> Yes, that's right.
>
>>
>> There are .irq_mask implementation that does seem to go at length
>> (blocking) to perform the mask, e.g.: gic_mask_irq() which calls
>> gic_{re,}dist_wait_for_rwp that have sleep/retry loops. The GIC3 ITS
>> code has similar things going on.
>
> The gic_{re,}dist_wait_for_rwp() polls on a HW register for completion
> which will certainly complete in a predictable time whereas waiting
> for IPI to be executed by another CPU is not predictable and fragile.
>
>>
>> I'm not saying you're wrong, I'm just trying to wrap my head around the
>> masking semantics.
>>
>> > The AIA IMSIC spec allows setting ID pending bit using MSI write
>> > irrespective whether ID is enabled or not but the interrupt will be
>> > taken only after ID is enabled. In other words, there will be no
>> > loss of interrupt with delayed mask/unmask using async IPI or
>> > lazy timer.
>>
>> No loss, but we might *get* an interrupt when we explicitly asked not to
>> get any. Maybe that's ok?
>>
>
> The delayed spurious interrupt after masking is avoided by additional
> masking at the source of interrupt. For wired-to-MSI interrupts, we have
> additional masking on the APLIC MSI-mode. For PCI MSI interrupts, we
> have additional masking at PCI device level using pci_msi_mask_irq().

Thanks for the clarifications, Anup! Much appreciated!


From mark.rutland at arm.com  Wed Feb 21 09:25:05 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 21 Feb 2024 17:25:05 +0000
Subject: [PATCH V16 3/8] drivers: perf: arm_pmuv3: Enable branch stack
 sampling framework
In-Reply-To: <20240125094119.2542332-4-anshuman.khandual@arm.com>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-4-anshuman.khandual@arm.com>
Message-ID: <ZdYx8cawn0sAbktv@FVFF77S0Q05N>

Hi Anshuman,

On Thu, Jan 25, 2024 at 03:11:14PM +0530, Anshuman Khandual wrote:
> Branch stack sampling support i.e capturing branch records during execution
> in core perf, rides along with normal HW events being scheduled on the PMU.
> This prepares ARMV8 PMU framework for branch stack support on relevant PMUs
> with required HW implementation.

Please can we start a bit more clearly, e.g.

| drivers: perf: arm_pmu: add instructure for branch stack sampling
| 
| In order to support the Branch Record Buffer Extension (BRBE), we need to
| extend the arm_pmu framework with some basic infrastructure for branch stack
| sampling which arm_pmu drivers can opt-in to using. Subsequent patches will
| use this to add support for BRBE in the PMUv3 driver.

> ARMV8 PMU hardware support for branch stack sampling is indicated via a new
> feature flag called 'has_branch_stack' that can be ascertained via probing.
> This modifies current gate in armpmu_event_init() which blocks branch stack
> sampling based perf events unconditionally. Instead allows such perf events
> getting initialized on supporting PMU hardware.

This paragraph can be deleted. The addition of 'has_branch_stack' and its use
in armpmu_event_init() is trivial and obvious in-context, and this distracts
from the important parts of this patch.

> Branch stack sampling is enabled and disabled along with regular PMU events
> . This adds required function callbacks in armv8pmu_branch_xxx() format, to
> drive the PMU branch stack hardware when supported. This also adds fallback
> stub definitions for these callbacks for PMUs which would not have required
> support.

Those additions to the PMUv3 driver should all be in the next patch.

We don't add anything for the other PMU drivers that don't support branch
sampling, so why do we need to do *anything* to the PMUv3 driver here, given we
add the support in the next patch? Those additions only make this patch bigger
and more confusing (and hence more painful to review).

> If a task gets scheduled out, the current branch records get saved in the
> task's context data, which can be later used to fill in the records upon an
> event overflow. Hence, we enable PERF_ATTACH_TASK_DATA (event->attach_state
> based flag) for branch stack requesting perf events. But this also requires
> adding support for pmu::sched_task() callback to arm_pmu.

I think what this is trying to say is:

| With BRBE, the hardware records branches into a hardware FIFO, which will be
| sampled by software when perf events overflow. A task may be context-switched
| an arbitrary number of times between overflows, and to avoid losing samples
| we need to save the current records when a task is context-switched out. To
| do these we'll need to use the pmu::sched_task() callback, and we'll need to
| allocate some per-task storage space using PERF_ATTACH_TASK_DATA.

> Cc: Catalin Marinas <catalin.marinas at arm.com>
> 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>
> ---
> Changes in V16:
> 
> - Renamed arm_brbe.h as arm_pmuv3_branch.h
> - Updated perf_sample_save_brstack()'s new argument requirements with NULL
> 
>  drivers/perf/arm_pmu.c          |  57 ++++++++++++-
>  drivers/perf/arm_pmuv3.c        | 141 +++++++++++++++++++++++++++++++-
>  drivers/perf/arm_pmuv3_branch.h |  50 +++++++++++
>  include/linux/perf/arm_pmu.h    |  29 ++++++-
>  include/linux/perf/arm_pmuv3.h  |   1 -
>  5 files changed, 273 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/perf/arm_pmuv3_branch.h
> 
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index 8458fe2cebb4..16f488ae7747 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -317,6 +317,15 @@ armpmu_del(struct perf_event *event, int flags)
>  	struct hw_perf_event *hwc = &event->hw;
>  	int idx = hwc->idx;
>  
> +	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;
> +			hw_events->brbe_sample_type = 0;
> +		}
> +	}
> +

If this is going to leak into the core arm_pmu code, use "branch_stack" rather
than "brbe" for these field names.

However, I reckon we could just have two new callbacks on arm_pmu:

	branch_stack_add(struct perf_event *event, ...);
	branch_stack_del(struct perf_event *event, ...);

... and hide all of the details in the PMUv3 (or BRBE) driver for now, and the
code above can just do:

	if (has_branch_stack(event))
		branch_stack_del(event, ...);

... and likewise in armpmu_add().

That way the actuel management logic for the context and so on can be added in
the next patch, where the lifetime would be *much* clearer.

>  	armpmu_stop(event, PERF_EF_UPDATE);
>  	hw_events->events[idx] = NULL;
>  	armpmu->clear_event_idx(hw_events, event);
> @@ -333,6 +342,38 @@ armpmu_add(struct perf_event *event, int flags)
>  	struct hw_perf_event *hwc = &event->hw;
>  	int idx;
>  
> +	if (has_branch_stack(event)) {
> +		/*
> +		 * Reset branch records buffer if a new CPU bound event
> +		 * gets scheduled on a PMU. Otherwise existing branch
> +		 * records present in the buffer might just leak into
> +		 * such events.
> +		 *
> +		 * Also reset current 'hw_events->brbe_context' because
> +		 * any previous task bound event now would have lost an
> +		 * opportunity for continuous branch records.
> +		 */

Doesn't this mean some user silently loses events? Why is that ok?

> +		if (!event->ctx->task) {
> +			hw_events->brbe_context = NULL;
> +			if (armpmu->branch_reset)
> +				armpmu->branch_reset();
> +		}
> +
> +		/*
> +		 * Reset branch records buffer if a new task event gets
> +		 * scheduled on a PMU which might have existing records.
> +		 * Otherwise older branch records present in the buffer
> +		 * might leak into the new task event.
> +		 */
> +		if (event->ctx->task && hw_events->brbe_context != event->ctx) {
> +			hw_events->brbe_context = event->ctx;
> +			if (armpmu->branch_reset)
> +				armpmu->branch_reset();
> +		}

Same question here.

How does this work on other architectures?

What do we do if the CPU-bound and task-bound events want different filters,
etc?

This is the sort of gnarly detail that should be explained (or at least
introduced) in the commit message.

> +		hw_events->brbe_users++;
> +		hw_events->brbe_sample_type = event->attr.branch_sample_type;

What exactly is brbe_sample_type, and why does it get overriden *every time* we
add a new event? What happens when events have different values for
brbe_sample_type? Or is that forbidden somehow?

> +	}
> +
>  	/* An event following a process won't be stopped earlier */
>  	if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus))
>  		return -ENOENT;

Unless this cpumask check has been made redundant, it means that the code above
it is obviously wrong, since that pokes the BRBE HW and increments brbe_users
*before* we decide whether the event can be installed on this CPU. That'll blow
up on big.LITTLE,  e.g. we try and install a 'big' CPU event on a 'little' CPU,
poke the BRBE HW and increment brbe_users, then *after* that we abort
installing the event.

Even ignoring big.LITTLE, we can fail immediately after this when we don't have
enough counters, since the following code is:

|        /* An event following a process won't be stopped earlier */
|        if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus))
|                return -ENOENT;
|
|        /* If we don't have a space for the counter then finish early. */
|        idx = armpmu->get_event_idx(hw_events, event);
|        if (idx < 0)
|                return idx;

... which'll go wrong if you try to open 1 more event than the CPU has
counters.

> @@ -511,13 +552,24 @@ 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))
> +	/*
> +	 * Branch stack sampling events are allowed
> +	 * only on PMU which has required support.
> +	 */
> +	if (has_branch_stack(event) && !armpmu->has_branch_stack)
>  		return -EOPNOTSUPP;
>  	return __hw_perf_event_init(event);
>  }
>  

I think we can delete the comment entirely here, but the code itself looks
fine here.

> +static void armpmu_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
> +{
> +	struct arm_pmu *armpmu = to_arm_pmu(pmu_ctx->pmu);
> +
> +	if (armpmu->sched_task)
> +		armpmu->sched_task(pmu_ctx, sched_in);
> +}

This looks fine.

>  static void armpmu_enable(struct pmu *pmu)
>  {
>  	struct arm_pmu *armpmu = to_arm_pmu(pmu);
> @@ -864,6 +916,7 @@ struct arm_pmu *armpmu_alloc(void)
>  	}
>  
>  	pmu->pmu = (struct pmu) {
> +		.sched_task	= armpmu_sched_task,
>  		.pmu_enable	= armpmu_enable,
>  		.pmu_disable	= armpmu_disable,
>  		.event_init	= armpmu_event_init,
> diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c
> index 23fa6c5da82c..9e17764a0929 100644
> --- a/drivers/perf/arm_pmuv3.c
> +++ b/drivers/perf/arm_pmuv3.c
> @@ -26,6 +26,7 @@
>  #include <linux/nmi.h>
>  
>  #include <asm/arm_pmuv3.h>
> +#include "arm_pmuv3_branch.h"

As above, I do not thing that the PMUv3 driver should change at all in this
patch. As of this patch it achieves nothing, and it makes it really hard to
understand what's going on because the important aspects are spread randomly
across this patch and the next patch which actually adds the BRBE management.

Please factor the PMUv3 changes out into the patch adding the actual BRBE code.

[...]

> diff --git a/include/linux/perf/arm_pmuv3.h b/include/linux/perf/arm_pmuv3.h
> index 46377e134d67..c3e7d2cfb737 100644
> --- a/include/linux/perf/arm_pmuv3.h
> +++ b/include/linux/perf/arm_pmuv3.h
> @@ -308,5 +308,4 @@
>  		default: WARN(1, "Invalid PMEV* index\n");	\
>  		}						\
>  	} while (0)
> -
>  #endif

Unrelated whitespace change.

Mark.


From sourabhjain at linux.ibm.com  Wed Feb 21 09:29:47 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Wed, 21 Feb 2024 22:59:47 +0530
Subject: [PATCH v2 01/14] kexec: split crashkernel reservation code out
 from crash_core.c
In-Reply-To: <20240119145241.769622-2-bhe@redhat.com>
References: <20240119145241.769622-1-bhe@redhat.com>
 <20240119145241.769622-2-bhe@redhat.com>
Message-ID: <e1bd53c6-ad9a-46d5-9f49-ecdd64d98f61@linux.ibm.com>

Hello Baoquan,

Thank you for reorganizing the kexec and kdump code with a well-defined
configuration structure.

While reviewing the patch series, I noticed a few typos.

On 19/01/24 20:22, Baoquan He wrote:
> Both kdump and fa_dump of ppc rely on crashkernel reservation. Move the
> relevant codes into separate files:
> crash_reserve.c, include/linux/crash_reserve.h.
>
> And also add config item CRASH_RESERVE to control its enabling of the
> codes. And update config items which has relationship with crashkernel
> reservation.
>
> And also change ifdeffery from CONFIG_CRASH_CORE to CONFIG_CRASH_RESERVE
> when those scopes are only crashkernel reservation related.
>
> And also rename arch/XXX/include/asm/{crash_core.h => crash_reserve.h}
> on arm64, x86 and risc-v because those architectures' crash_core.h
> is only related to crashkernel reservation.
>
> Signed-off-by: Baoquan He <bhe at redhat.com>
> ---
>   arch/arm64/Kconfig                            |   2 +-
>   .../asm/{crash_core.h => crash_reserve.h}     |   4 +-
>   arch/powerpc/Kconfig                          |   1 +
>   arch/powerpc/mm/nohash/kaslr_booke.c          |   4 +-
>   arch/riscv/Kconfig                            |   2 +-
>   .../asm/{crash_core.h => crash_reserve.h}     |   4 +-
>   arch/x86/Kconfig                              |   2 +-
>   .../asm/{crash_core.h => crash_reserve.h}     |   6 +-
>   include/linux/crash_core.h                    |  40 --
>   include/linux/crash_reserve.h                 |  48 ++
>   include/linux/kexec.h                         |   1 +
>   kernel/Kconfig.kexec                          |   5 +-
>   kernel/Makefile                               |   1 +
>   kernel/crash_core.c                           | 438 -----------------
>   kernel/crash_reserve.c                        | 464 ++++++++++++++++++
>   15 files changed, 531 insertions(+), 491 deletions(-)
>   rename arch/arm64/include/asm/{crash_core.h => crash_reserve.h} (81%)
>   rename arch/riscv/include/asm/{crash_core.h => crash_reserve.h} (78%)
>   rename arch/x86/include/asm/{crash_core.h => crash_reserve.h} (92%)
>   create mode 100644 include/linux/crash_reserve.h
>   create mode 100644 kernel/crash_reserve.c
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index ea01a2c43efa..d96bc3c67ec6 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1501,7 +1501,7 @@ config ARCH_SUPPORTS_CRASH_DUMP
>   	def_bool y
>   
>   config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
> -	def_bool CRASH_CORE
> +	def_bool CRASH_RESERVE
>   
>   config TRANS_TABLE
>   	def_bool y
> diff --git a/arch/arm64/include/asm/crash_core.h b/arch/arm64/include/asm/crash_reserve.h
> similarity index 81%
> rename from arch/arm64/include/asm/crash_core.h
> rename to arch/arm64/include/asm/crash_reserve.h
> index 9f5c8d339f44..4afe027a4e7b 100644
> --- a/arch/arm64/include/asm/crash_core.h
> +++ b/arch/arm64/include/asm/crash_reserve.h
> @@ -1,6 +1,6 @@
>   /* SPDX-License-Identifier: GPL-2.0-only */
> -#ifndef _ARM64_CRASH_CORE_H
> -#define _ARM64_CRASH_CORE_H
> +#ifndef _ARM64_CRASH_RESERVE_H
> +#define _ARM64_CRASH_RESERVE_H
>   
>   /* Current arm64 boot protocol requires 2MB alignment */
>   #define CRASH_ALIGN                     SZ_2M
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 414b978b8010..6aeab95f0edd 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -691,6 +691,7 @@ config FA_DUMP
>   	bool "Firmware-assisted dump"
>   	depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
>   	select CRASH_CORE
> +	select CRASH_RESERVE
>   	select CRASH_DUMP
>   	help
>   	  A robust mechanism to get reliable kernel crash dump with
> diff --git a/arch/powerpc/mm/nohash/kaslr_booke.c b/arch/powerpc/mm/nohash/kaslr_booke.c
> index b4f2786a7d2b..cdff129abb14 100644
> --- a/arch/powerpc/mm/nohash/kaslr_booke.c
> +++ b/arch/powerpc/mm/nohash/kaslr_booke.c
> @@ -13,7 +13,7 @@
>   #include <linux/delay.h>
>   #include <linux/memblock.h>
>   #include <linux/libfdt.h>
> -#include <linux/crash_core.h>
> +#include <linux/crash_reserve.h>
>   #include <linux/of.h>
>   #include <linux/of_fdt.h>
>   #include <asm/cacheflush.h>
> @@ -173,7 +173,7 @@ static __init bool overlaps_region(const void *fdt, u32 start,
>   
>   static void __init get_crash_kernel(void *fdt, unsigned long size)
>   {
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_CRASH_RESERVE
>   	unsigned long long crash_size, crash_base;
>   	int ret;
>   
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index b549499eb363..37a438c23deb 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -712,7 +712,7 @@ config ARCH_SUPPORTS_CRASH_DUMP
>   	def_bool y
>   
>   config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
> -	def_bool CRASH_CORE
> +	def_bool CRASH_RESERVE
>   
>   config COMPAT
>   	bool "Kernel support for 32-bit U-mode"
> diff --git a/arch/riscv/include/asm/crash_core.h b/arch/riscv/include/asm/crash_reserve.h
> similarity index 78%
> rename from arch/riscv/include/asm/crash_core.h
> rename to arch/riscv/include/asm/crash_reserve.h
> index e1874b23feaf..013962e63587 100644
> --- a/arch/riscv/include/asm/crash_core.h
> +++ b/arch/riscv/include/asm/crash_reserve.h
> @@ -1,6 +1,6 @@
>   /* SPDX-License-Identifier: GPL-2.0-only */
> -#ifndef _RISCV_CRASH_CORE_H
> -#define _RISCV_CRASH_CORE_H
> +#ifndef _RISCV_CRASH_RESERVE_H
> +#define _RISCV_CRASH_RESERVE_H
>   
>   #define CRASH_ALIGN			PMD_SIZE
>   
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 5edec175b9bf..71417c5b228c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2106,7 +2106,7 @@ config ARCH_SUPPORTS_CRASH_HOTPLUG
>   	def_bool y
>   
>   config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
> -	def_bool CRASH_CORE
> +	def_bool CRASH_RESEERVE

%s/CRASH_RESEERVE/CRASH_RESERVE? - Sourabh


From broonie at kernel.org  Wed Feb 21 09:36:12 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 21 Feb 2024 17:36:12 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <20240221145800.GR4163@brightrain.aerifal.cx>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
 <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
 <20240220235415.GP4163@brightrain.aerifal.cx>
 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx>
 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx>
Message-ID: <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>

On Wed, Feb 21, 2024 at 09:58:01AM -0500, dalias at libc.org wrote:
> On Wed, Feb 21, 2024 at 01:53:10PM +0000, Mark Brown wrote:
> > On Tue, Feb 20, 2024 at 08:27:37PM -0500, dalias at libc.org wrote:
> > > On Wed, Feb 21, 2024 at 12:35:48AM +0000, Edgecombe, Rick P wrote:

> > > > (INCSSP, RSTORSSP, etc). These are a collection of instructions that
> > > > allow limited control of the SSP. When shadow stack gets disabled,
> > > > these suddenly turn into #UD generating instructions. So any other
> > > > threads executing those instructions when shadow stack got disabled
> > > > would be in for a nasty surprise.

> > > This is the kernel's problem if that's happening. It should be
> > > trapping these and returning immediately like a NOP if shadow stack
> > > has been disabled, not generating SIGILL.

> > I'm not sure that's going to work out well, all it takes is some code
> > that's looking at the shadow stack and expecting something to happen as
> > a result of the instructions it's executing and we run into trouble.  A

> I said NOP but there's no reason it strictly needs to be a NOP. It
> could instead do something reasonable to convey the state of racing
> with shadow stack being disabled.

This feels like it's getting complicated and I fear it may be an uphill
struggle to get such code merged, at least for arm64.  My instinct is
that it's going to be much more robust and generally tractable to let
things run to some suitable synchronisation point and then disable
there, but if we're going to do that then userspace can hopefully
arrange to do the disabling itself through the standard disable
interface anyway.  Presumably it'll want to notice things being disabled
at some point anyway?  TBH that's been how all the prior proposals for
process wide disable I've seen were done.
-------------- 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/20240221/84ebe4c1/attachment.sig>

From lorenzo at kernel.org  Wed Feb 21 09:36:19 2024
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Wed, 21 Feb 2024 18:36:19 +0100
Subject: [PATCH v2 2/4] arm64: dts: Add Airoha EN7581 SoC and EN7581
 Evaluation Board
In-Reply-To: <7a623f15-02cc-4508-88e2-da12aaeee242@collabora.com>
References: <cover.1708473083.git.lorenzo@kernel.org>
 <f59389838c741650f6ff05d984a9127545e4eb83.1708473083.git.lorenzo@kernel.org>
 <7a623f15-02cc-4508-88e2-da12aaeee242@collabora.com>
Message-ID: <ZdY0k9t7u6McEIMC@lore-desk>

> > From: Daniel Danzberger <dd at embedd.com>
> > 
> > Introduce the Airoha EN7581 SoC's dtsi and the Airoha EN7581 Evaluation
> > Board's dts file, as well as the required Makefiles.
> > 
> > Signed-off-by: Daniel Danzberger <dd at embedd.com>
> > Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
> > ---
> >   arch/arm64/boot/dts/Makefile              |   1 +
> >   arch/arm64/boot/dts/airoha/Makefile       |   2 +
> >   arch/arm64/boot/dts/airoha/en7581-evb.dts |  27 +++++
> >   arch/arm64/boot/dts/airoha/en7581.dtsi    | 137 ++++++++++++++++++++++
> >   4 files changed, 167 insertions(+)
> >   create mode 100644 arch/arm64/boot/dts/airoha/Makefile
> >   create mode 100644 arch/arm64/boot/dts/airoha/en7581-evb.dts
> >   create mode 100644 arch/arm64/boot/dts/airoha/en7581.dtsi
> > 
> > diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> > index 30dd6347a929..21cd3a87f385 100644
> > --- a/arch/arm64/boot/dts/Makefile
> > +++ b/arch/arm64/boot/dts/Makefile
> > @@ -1,5 +1,6 @@
> >   # SPDX-License-Identifier: GPL-2.0
> >   subdir-y += actions
> > +subdir-y += airoha
> >   subdir-y += allwinner
> >   subdir-y += altera
> >   subdir-y += amazon
> > diff --git a/arch/arm64/boot/dts/airoha/Makefile b/arch/arm64/boot/dts/airoha/Makefile
> > new file mode 100644
> > index 000000000000..ebea112ce1d7
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/airoha/Makefile
> > @@ -0,0 +1,2 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +dtb-$(CONFIG_ARCH_AIROHA) += en7581-evb.dtb
> > diff --git a/arch/arm64/boot/dts/airoha/en7581-evb.dts b/arch/arm64/boot/dts/airoha/en7581-evb.dts
> > new file mode 100644
> > index 000000000000..4eaa8ac431c3
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/airoha/en7581-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 "en7581.dtsi"
> > +
> > +/ {
> > +	model = "Airoha EN7581 Evaluation Board";
> > +	compatible = "airoha,en7581-evb", "airoha,en7581";
> > +
> > +	aliases {
> > +		serial0 = &uart1;
> > +	};
> > +
> > +	chosen {
> > +		bootargs = "console=ttyS0,115200 earlycon";
> > +		stdout-path = "serial0:115200n8";
> > +		linux,usable-memory-range = <0x0 0x80200000 0x0 0x1fe00000>;
> > +	};
> > +
> > +	memory at 80000000 {
> > +		device_type = "memory";
> > +		reg = <0x0 0x80000000 0x2 0x00000000>;
> 
> Is your bootloader really not filling the size for the memory node?

is the size 0x200000000? Am I missing something?

> 
> Can you please verify?
> If it doesn't, it's not a problem of course.
> 
> > +	};
> > +};
> > diff --git a/arch/arm64/boot/dts/airoha/en7581.dtsi b/arch/arm64/boot/dts/airoha/en7581.dtsi
> > new file mode 100644
> > index 000000000000..7a3c0a45c03f
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/airoha/en7581.dtsi
> > @@ -0,0 +1,137 @@
> > +// 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 = <2>;
> > +	#size-cells = <2>;
> > +
> > +	reserved-memory {
> > +		#address-cells = <2>;
> > +		#size-cells = <2>;
> > +		ranges;
> > +
> > +		npu_binary at 84000000 {
> 
> npu-binary at ...

ack, I will fix it.

> 
> > +			no-map;
> > +			reg = <0x0 0x84000000 0x0 0xA00000>;
> > +		};
> > +
> > +		npu_flag at 84B0000 {
> > +			no-map;
> > +			reg = <0x0 0x84B00000 0x0 0x100000>;
> > +		};
> > +
> > +		npu_pkt at 85000000 {
> > +			no-map;
> > +			reg = <0x0 0x85000000 0x0 0x1A00000>;
> > +		};
> > +
> > +		npu_phyaddr at 86B00000 {
> > +			no-map;
> > +			reg = <0x0 0x86B00000 0x0 0x100000>;
> > +		};
> > +
> > +		npu_rxdesc at 86D00000 {
> > +			no-map;
> > +			reg = <0x0 0x86D00000 0x0 0x100000>;
> > +		};
> > +	};
> > +
> > +	psci {
> > +		compatible = "arm,psci-0.2";
> 
> Not the first time I comment that (in general - not specifically to you): are you
> sure that your platform supports PSCI v0.2 and not a later version?
> 
> Please check your kernel log, you should see a message like
> 
> [    0.000000] psci: PSCIv1.1 detected in firmware.
> 
> (with the right version)
> 
> ...then use the right compatible string :-)

ack, I will fix it.

> 
> > +		method = "smc";
> > +	};
> > +
> > +	cpus {
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +
> > +		cpu-map {
> > +			cluster0 {
> > +				core0 {
> > +					cpu = <&cpu0>;
> > +				};
> > +				core1 {
> > +					cpu = <&cpu1>;
> > +				};
> 
> Your cluster contains only two cores, this means that the other two are in a
> parallel reality? :-P :-P

I think this has been copied from vendor sdk. I will fix moving back 2 missing
cpu from the 'parallel reality' :)

> 
> Jokes apart, this cpu-map looks wrong.
> 
> Check what the topology is supposed to be for real, clusterized or DynamIQ?
> In the first case, you get X clusters with Y CPUs each - in the second case,
> you get *one* single cluster with all CPUs inside.

I think it is just a linear architecture, but I will check with airoha folks.

> 
> > +			};
> > +		};
> > +
> > +		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>;
> > +		};
> > +
> > +		cpu2: cpu at 2 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x2>;
> > +			enable-method = "psci";
> > +			clock-frequency = <80000000>;
> > +			next-level-cache = <&L2_0>;
> > +		};
> > +
> > +		cpu3: cpu at 3 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x3>;
> > +			enable-method = "psci";
> > +			clock-frequency = <80000000>;
> > +			next-level-cache = <&L2_0>;
> > +		};
> > +
> > +		L2_0: l2-cache0 {
> > +			compatible = "cache";
> > +			cache-level = <2>;
> > +			cache-unified;
> 
> Do you know what is the l2 cache size, line size, sets?
> cache-size = < ... >
> cache-line-size = < ... >
> cache-sets = < ... >

not sure about them, I will sync with airoha folks.

> 
> > +		};
> > +	};
> > +
> 
> All iospace addressable nodes must go into a soc node, others go in the root node.

ack, I will fix it.

> 
> soc {
> 	gic: interrupt-controller at 9000000 {
> 		....
> 	}
> 
> 	uart0: serial@ ....
> 
> };
> 
> > +	gic: interrupt-controller at 9000000 {
> > +		compatible = "arm,gic-v3";
> > +		interrupt-controller;
> > +		#interrupt-cells = <3>;
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		reg = <0x0 0x09000000 0x0 0x20000>,
> > +		      <0x0 0x09080000 0x0 0x80000>,
> > +		      <0x0 0x09400000 0x0 0x2000>,
> > +		      <0x0 0x09500000 0x0 0x2000>,
> > +		      <0x0 0x09600000 0x0 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 = <0x0 0x1fbf0000 0x0 0x30>;
> > +		reg-io-width = <4>;
> > +		reg-shift = <2>;
> > +		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
> > +		clock-frequency = <1843200>;
> > +		status = "okay";
> 
> status is okay by default, you don't need that.

ack, I will fix it.

Regards,
Lorenzo

> 
> > +	};
> > +};
> 
> Cheers,
> Angelo
-------------- 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/20240221/bdf6e488/attachment.sig>

From sourabhjain at linux.ibm.com  Wed Feb 21 09:37:39 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Wed, 21 Feb 2024 23:07:39 +0530
Subject: [PATCH v2 02/14] crash: split vmcoreinfo exporting code out from
 crash_core.c
In-Reply-To: <20240119145241.769622-3-bhe@redhat.com>
References: <20240119145241.769622-1-bhe@redhat.com>
 <20240119145241.769622-3-bhe@redhat.com>
Message-ID: <75c77583-6253-4d32-8daf-0e86a2cad226@linux.ibm.com>

Hello Baoquan,

On 19/01/24 20:22, Baoquan He wrote:
> Now move the relevant codes into separate files:
> kernel/crash_reserve.c, include/linux/crash_reserve.h.
>
> And add config item CRASH_RESERVE to control its enabling.

Feels like this patch is more about vmcore_info.[c|h] and CONFIG_VMCORE_INFO
then the above mentioned files and config.

- Sourabh

>
> And also update the old ifdeffery of CONFIG_CRASH_CORE, including of
> <linux/crash_core.h> and config item dependency on CRASH_CORE
> accordingly.
>
> And also do renaming as follows:
>   - arch/xxx/kernel/{crash_core.c => vmcore_info.c}
> because they are only related to vmcoreinfo exporting on x86, arm64,
> riscv.
>
> And also Remove config item CRASH_CORE, and rely on CONFIG_KEXEC_CORE to
> decide if build in crash_core.c.
>
> Signed-off-by: Baoquan He <bhe at redhat.com>
> ---
>   arch/arm64/kernel/Makefile                    |   2 +-
>   .../kernel/{crash_core.c => vmcore_info.c}    |   2 +-
>   arch/powerpc/Kconfig                          |   2 +-
>   arch/powerpc/kernel/setup-common.c            |   2 +-
>   arch/powerpc/platforms/powernv/opal-core.c    |   2 +-
>   arch/riscv/kernel/Makefile                    |   2 +-
>   .../kernel/{crash_core.c => vmcore_info.c}    |   2 +-
>   arch/x86/kernel/Makefile                      |   2 +-
>   .../{crash_core_32.c => vmcore_info_32.c}     |   2 +-
>   .../{crash_core_64.c => vmcore_info_64.c}     |   2 +-
>   drivers/firmware/qemu_fw_cfg.c                |  14 +-
>   fs/proc/Kconfig                               |   2 +-
>   fs/proc/kcore.c                               |   2 +-
>   include/linux/buildid.h                       |   2 +-
>   include/linux/crash_core.h                    |  73 ------
>   include/linux/kexec.h                         |   1 +
>   include/linux/vmcore_info.h                   |  81 ++++++
>   kernel/Kconfig.kexec                          |   4 +-
>   kernel/Makefile                               |   4 +-
>   kernel/crash_core.c                           | 208 ----------------
>   kernel/ksysfs.c                               |   6 +-
>   kernel/printk/printk.c                        |   4 +-
>   kernel/vmcore_info.c                          | 233 ++++++++++++++++++
>   lib/buildid.c                                 |   2 +-
>   24 files changed, 345 insertions(+), 311 deletions(-)
>   rename arch/arm64/kernel/{crash_core.c => vmcore_info.c} (97%)
>   rename arch/riscv/kernel/{crash_core.c => vmcore_info.c} (96%)
>   rename arch/x86/kernel/{crash_core_32.c => vmcore_info_32.c} (90%)
>   rename arch/x86/kernel/{crash_core_64.c => vmcore_info_64.c} (94%)
>   create mode 100644 include/linux/vmcore_info.h
>   create mode 100644 kernel/vmcore_info.c
>
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index d95b3d6b471a..bcf89587a549 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -66,7 +66,7 @@ obj-$(CONFIG_KEXEC_FILE)		+= machine_kexec_file.o kexec_image.o
>   obj-$(CONFIG_ARM64_RELOC_TEST)		+= arm64-reloc-test.o
>   arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
>   obj-$(CONFIG_CRASH_DUMP)		+= crash_dump.o
> -obj-$(CONFIG_CRASH_CORE)		+= crash_core.o
> +obj-$(CONFIG_VMCORE_INFO)		+= vmcore_info.o
>   obj-$(CONFIG_ARM_SDE_INTERFACE)		+= sdei.o
>   obj-$(CONFIG_ARM64_PTR_AUTH)		+= pointer_auth.o
>   obj-$(CONFIG_ARM64_MTE)			+= mte.o
> diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/vmcore_info.c
> similarity index 97%
> rename from arch/arm64/kernel/crash_core.c
> rename to arch/arm64/kernel/vmcore_info.c
> index 66cde752cd74..a5abf7186922 100644
> --- a/arch/arm64/kernel/crash_core.c
> +++ b/arch/arm64/kernel/vmcore_info.c
> @@ -4,7 +4,7 @@
>    * Copyright (C) Huawei Futurewei Technologies.
>    */
>   
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
>   #include <asm/cpufeature.h>
>   #include <asm/memory.h>
>   #include <asm/pgtable-hwdef.h>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 6aeab95f0edd..1520146d7c2c 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -690,7 +690,7 @@ config ARCH_SELECTS_CRASH_DUMP
>   config FA_DUMP
>   	bool "Firmware-assisted dump"
>   	depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
> -	select CRASH_CORE
> +	select VMCORE_INFO
>   	select CRASH_RESERVE
>   	select CRASH_DUMP
>   	help
> diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
> index 9b142b9d5187..733f210ffda1 100644
> --- a/arch/powerpc/kernel/setup-common.c
> +++ b/arch/powerpc/kernel/setup-common.c
> @@ -109,7 +109,7 @@ int ppc_do_canonicalize_irqs;
>   EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
>   #endif
>   
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
>   /* This keeps a track of which one is the crashing cpu. */
>   int crashing_cpu = -1;
>   #endif
> diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
> index bb7657115f1d..c9a9b759cc92 100644
> --- a/arch/powerpc/platforms/powernv/opal-core.c
> +++ b/arch/powerpc/platforms/powernv/opal-core.c
> @@ -16,7 +16,7 @@
>   #include <linux/kobject.h>
>   #include <linux/sysfs.h>
>   #include <linux/slab.h>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
>   #include <linux/of.h>
>   
>   #include <asm/page.h>
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index c92c623b311e..63a36539ea1a 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -91,7 +91,7 @@ obj-$(CONFIG_KGDB)		+= kgdb.o
>   obj-$(CONFIG_KEXEC_CORE)	+= kexec_relocate.o crash_save_regs.o machine_kexec.o
>   obj-$(CONFIG_KEXEC_FILE)	+= elf_kexec.o machine_kexec_file.o
>   obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
> -obj-$(CONFIG_CRASH_CORE)	+= crash_core.o
> +obj-$(CONFIG_VMCORE_INFO)	+= vmcore_info.o
>   
>   obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
>   
> diff --git a/arch/riscv/kernel/crash_core.c b/arch/riscv/kernel/vmcore_info.c
> similarity index 96%
> rename from arch/riscv/kernel/crash_core.c
> rename to arch/riscv/kernel/vmcore_info.c
> index 8706736fd4e2..e8ad57a60a2f 100644
> --- a/arch/riscv/kernel/crash_core.c
> +++ b/arch/riscv/kernel/vmcore_info.c
> @@ -1,6 +1,6 @@
>   // SPDX-License-Identifier: GPL-2.0-only
>   
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
>   #include <linux/pagemap.h>
>   
>   void arch_crash_save_vmcoreinfo(void)
> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> index 0000325ab98f..913d4022131e 100644
> --- a/arch/x86/kernel/Makefile
> +++ b/arch/x86/kernel/Makefile
> @@ -98,7 +98,7 @@ obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
>   obj-$(CONFIG_X86_TSC)		+= trace_clock.o
>   obj-$(CONFIG_TRACING)		+= trace.o
>   obj-$(CONFIG_RETHOOK)		+= rethook.o
> -obj-$(CONFIG_CRASH_CORE)	+= crash_core_$(BITS).o
> +obj-$(CONFIG_VMCORE_INFO)	+= vmcore_info_$(BITS).o
>   obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>   obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>   obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
> diff --git a/arch/x86/kernel/crash_core_32.c b/arch/x86/kernel/vmcore_info_32.c
> similarity index 90%
> rename from arch/x86/kernel/crash_core_32.c
> rename to arch/x86/kernel/vmcore_info_32.c
> index 8a89c109e20a..5995a749288a 100644
> --- a/arch/x86/kernel/crash_core_32.c
> +++ b/arch/x86/kernel/vmcore_info_32.c
> @@ -1,6 +1,6 @@
>   // SPDX-License-Identifier: GPL-2.0-only
>   
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
>   #include <linux/pgtable.h>
>   
>   #include <asm/setup.h>
> diff --git a/arch/x86/kernel/crash_core_64.c b/arch/x86/kernel/vmcore_info_64.c
> similarity index 94%
> rename from arch/x86/kernel/crash_core_64.c
> rename to arch/x86/kernel/vmcore_info_64.c
> index 7d255f882afe..0dec7d868754 100644
> --- a/arch/x86/kernel/crash_core_64.c
> +++ b/arch/x86/kernel/vmcore_info_64.c
> @@ -1,6 +1,6 @@
>   // SPDX-License-Identifier: GPL-2.0-only
>   
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
>   #include <linux/pgtable.h>
>   
>   #include <asm/setup.h>
> diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> index 03da9a4354f8..5f43dfa22f79 100644
> --- a/drivers/firmware/qemu_fw_cfg.c
> +++ b/drivers/firmware/qemu_fw_cfg.c
> @@ -37,7 +37,7 @@
>   #include <uapi/linux/qemu_fw_cfg.h>
>   #include <linux/delay.h>
>   #include <linux/crash_dump.h>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
>   
>   MODULE_AUTHOR("Gabriel L. Somlo <somlo at cmu.edu>");
>   MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
> @@ -67,7 +67,7 @@ static void fw_cfg_sel_endianness(u16 key)
>   		iowrite16(key, fw_cfg_reg_ctrl);
>   }
>   
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
>   static inline bool fw_cfg_dma_enabled(void)
>   {
>   	return (fw_cfg_rev & FW_CFG_VERSION_DMA) && fw_cfg_reg_dma;
> @@ -156,7 +156,7 @@ static ssize_t fw_cfg_read_blob(u16 key,
>   	return count;
>   }
>   
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
>   /* write chunk of given fw_cfg blob (caller responsible for sanity-check) */
>   static ssize_t fw_cfg_write_blob(u16 key,
>   				 void *buf, loff_t pos, size_t count)
> @@ -195,7 +195,7 @@ static ssize_t fw_cfg_write_blob(u16 key,
>   
>   	return ret;
>   }
> -#endif /* CONFIG_CRASH_CORE */
> +#endif /* CONFIG_VMCORE_INFO */
>   
>   /* clean up fw_cfg device i/o */
>   static void fw_cfg_io_cleanup(void)
> @@ -319,7 +319,7 @@ struct fw_cfg_sysfs_entry {
>   	struct list_head list;
>   };
>   
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
>   static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f)
>   {
>   	static struct fw_cfg_vmcoreinfo *data;
> @@ -343,7 +343,7 @@ static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f)
>   	kfree(data);
>   	return ret;
>   }
> -#endif /* CONFIG_CRASH_CORE */
> +#endif /* CONFIG_VMCORE_INFO */
>   
>   /* get fw_cfg_sysfs_entry from kobject member */
>   static inline struct fw_cfg_sysfs_entry *to_entry(struct kobject *kobj)
> @@ -583,7 +583,7 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f)
>   	int err;
>   	struct fw_cfg_sysfs_entry *entry;
>   
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
>   	if (fw_cfg_dma_enabled() &&
>   		strcmp(f->name, FW_CFG_VMCOREINFO_FILENAME) == 0 &&
>   		!is_kdump_kernel()) {
> diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
> index 32b1116ae137..d80a1431ef7b 100644
> --- a/fs/proc/Kconfig
> +++ b/fs/proc/Kconfig
> @@ -32,7 +32,7 @@ config PROC_FS
>   config PROC_KCORE
>   	bool "/proc/kcore support" if !ARM
>   	depends on PROC_FS && MMU
> -	select CRASH_CORE
> +	select VMCORE_INFO
>   	help
>   	  Provides a virtual ELF core file of the live kernel.  This can
>   	  be read with gdb and other ELF tools.  No modifications can be
> diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
> index 6422e569b080..8e08a9a1b7ed 100644
> --- a/fs/proc/kcore.c
> +++ b/fs/proc/kcore.c
> @@ -10,7 +10,7 @@
>    *	Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar <kanoj at sgi.com>
>    */
>   
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
>   #include <linux/mm.h>
>   #include <linux/proc_fs.h>
>   #include <linux/kcore.h>
> diff --git a/include/linux/buildid.h b/include/linux/buildid.h
> index 8a582d242f06..20aa3c2d89f7 100644
> --- a/include/linux/buildid.h
> +++ b/include/linux/buildid.h
> @@ -11,7 +11,7 @@ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
>   		   __u32 *size);
>   int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size);
>   
> -#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
> +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_VMCORE_INFO)
>   extern unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX];
>   void init_vmlinux_build_id(void);
>   #else
> diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
> index 1fde49246fa6..7f19f62018ef 100644
> --- a/include/linux/crash_core.h
> +++ b/include/linux/crash_core.h
> @@ -6,79 +6,6 @@
>   #include <linux/elfcore.h>
>   #include <linux/elf.h>
>   
> -#define CRASH_CORE_NOTE_NAME	   "CORE"
> -#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
> -#define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
> -#define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
> -
> -/*
> - * The per-cpu notes area is a list of notes terminated by a "NULL"
> - * note header.  For kdump, the code in vmcore.c runs in the context
> - * of the second kernel to combine them into one note.
> - */
> -#define CRASH_CORE_NOTE_BYTES	   ((CRASH_CORE_NOTE_HEAD_BYTES * 2) +	\
> -				     CRASH_CORE_NOTE_NAME_BYTES +	\
> -				     CRASH_CORE_NOTE_DESC_BYTES)
> -
> -#define VMCOREINFO_BYTES	   PAGE_SIZE
> -#define VMCOREINFO_NOTE_NAME	   "VMCOREINFO"
> -#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
> -#define VMCOREINFO_NOTE_SIZE	   ((CRASH_CORE_NOTE_HEAD_BYTES * 2) +	\
> -				     VMCOREINFO_NOTE_NAME_BYTES +	\
> -				     VMCOREINFO_BYTES)
> -
> -typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4];
> -/* Per cpu memory for storing cpu states in case of system crash. */
> -extern note_buf_t __percpu *crash_notes;
> -
> -void crash_update_vmcoreinfo_safecopy(void *ptr);
> -void crash_save_vmcoreinfo(void);
> -void arch_crash_save_vmcoreinfo(void);
> -__printf(1, 2)
> -void vmcoreinfo_append_str(const char *fmt, ...);
> -phys_addr_t paddr_vmcoreinfo_note(void);
> -
> -#define VMCOREINFO_OSRELEASE(value) \
> -	vmcoreinfo_append_str("OSRELEASE=%s\n", value)
> -#define VMCOREINFO_BUILD_ID()						\
> -	({								\
> -		static_assert(sizeof(vmlinux_build_id) == 20);		\
> -		vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \
> -	})
> -
> -#define VMCOREINFO_PAGESIZE(value) \
> -	vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
> -#define VMCOREINFO_SYMBOL(name) \
> -	vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
> -#define VMCOREINFO_SYMBOL_ARRAY(name) \
> -	vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name)
> -#define VMCOREINFO_SIZE(name) \
> -	vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> -			      (unsigned long)sizeof(name))
> -#define VMCOREINFO_STRUCT_SIZE(name) \
> -	vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> -			      (unsigned long)sizeof(struct name))
> -#define VMCOREINFO_OFFSET(name, field) \
> -	vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> -			      (unsigned long)offsetof(struct name, field))
> -#define VMCOREINFO_TYPE_OFFSET(name, field) \
> -	vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> -			      (unsigned long)offsetof(name, field))
> -#define VMCOREINFO_LENGTH(name, value) \
> -	vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
> -#define VMCOREINFO_NUMBER(name) \
> -	vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
> -#define VMCOREINFO_CONFIG(name) \
> -	vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
> -
> -extern unsigned char *vmcoreinfo_data;
> -extern size_t vmcoreinfo_size;
> -extern u32 *vmcoreinfo_note;
> -
> -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);
> -
>   /* Alignment required for elf header segment */
>   #define ELF_CORE_HEADER_ALIGN   4096
>   
> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> index 6d79bfb52e5b..9c7bb8b56ed6 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -16,6 +16,7 @@
>   #if !defined(__ASSEMBLY__)
>   
>   #include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
>   #include <linux/crash_reserve.h>
>   #include <asm/io.h>
>   #include <linux/range.h>
> diff --git a/include/linux/vmcore_info.h b/include/linux/vmcore_info.h
> new file mode 100644
> index 000000000000..e1dec1a6a749
> --- /dev/null
> +++ b/include/linux/vmcore_info.h
> @@ -0,0 +1,81 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef LINUX_VMCORE_INFO_H
> +#define LINUX_VMCORE_INFO_H
> +
> +#include <linux/linkage.h>
> +#include <linux/elfcore.h>
> +#include <linux/elf.h>
> +
> +#define CRASH_CORE_NOTE_NAME	   "CORE"
> +#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
> +#define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
> +#define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
> +
> +/*
> + * The per-cpu notes area is a list of notes terminated by a "NULL"
> + * note header.  For kdump, the code in vmcore.c runs in the context
> + * of the second kernel to combine them into one note.
> + */
> +#define CRASH_CORE_NOTE_BYTES	   ((CRASH_CORE_NOTE_HEAD_BYTES * 2) +	\
> +				     CRASH_CORE_NOTE_NAME_BYTES +	\
> +				     CRASH_CORE_NOTE_DESC_BYTES)
> +
> +#define VMCOREINFO_BYTES	   PAGE_SIZE
> +#define VMCOREINFO_NOTE_NAME	   "VMCOREINFO"
> +#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
> +#define VMCOREINFO_NOTE_SIZE	   ((CRASH_CORE_NOTE_HEAD_BYTES * 2) +	\
> +				     VMCOREINFO_NOTE_NAME_BYTES +	\
> +				     VMCOREINFO_BYTES)
> +
> +typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4];
> +/* Per cpu memory for storing cpu states in case of system crash. */
> +extern note_buf_t __percpu *crash_notes;
> +
> +void crash_update_vmcoreinfo_safecopy(void *ptr);
> +void crash_save_vmcoreinfo(void);
> +void arch_crash_save_vmcoreinfo(void);
> +__printf(1, 2)
> +void vmcoreinfo_append_str(const char *fmt, ...);
> +phys_addr_t paddr_vmcoreinfo_note(void);
> +
> +#define VMCOREINFO_OSRELEASE(value) \
> +	vmcoreinfo_append_str("OSRELEASE=%s\n", value)
> +#define VMCOREINFO_BUILD_ID()						\
> +	({								\
> +		static_assert(sizeof(vmlinux_build_id) == 20);		\
> +		vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \
> +	})
> +
> +#define VMCOREINFO_PAGESIZE(value) \
> +	vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
> +#define VMCOREINFO_SYMBOL(name) \
> +	vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
> +#define VMCOREINFO_SYMBOL_ARRAY(name) \
> +	vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name)
> +#define VMCOREINFO_SIZE(name) \
> +	vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> +			      (unsigned long)sizeof(name))
> +#define VMCOREINFO_STRUCT_SIZE(name) \
> +	vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> +			      (unsigned long)sizeof(struct name))
> +#define VMCOREINFO_OFFSET(name, field) \
> +	vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> +			      (unsigned long)offsetof(struct name, field))
> +#define VMCOREINFO_TYPE_OFFSET(name, field) \
> +	vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> +			      (unsigned long)offsetof(name, field))
> +#define VMCOREINFO_LENGTH(name, value) \
> +	vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
> +#define VMCOREINFO_NUMBER(name) \
> +	vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
> +#define VMCOREINFO_CONFIG(name) \
> +	vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
> +
> +extern unsigned char *vmcoreinfo_data;
> +extern size_t vmcoreinfo_size;
> +extern u32 *vmcoreinfo_note;
> +
> +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);
> +#endif /* LINUX_VMCORE_INFO_H */
> diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
> index 8b7be71edd85..8faf27043432 100644
> --- a/kernel/Kconfig.kexec
> +++ b/kernel/Kconfig.kexec
> @@ -5,11 +5,11 @@ menu "Kexec and crash features"
>   config CRASH_RESERVE
>   	bool
>   
> -config CRASH_CORE
> +config VMCORE_INFO
>   	bool
>   
>   config KEXEC_CORE
> -	select CRASH_CORE
> +	select VMCORE_INFO
>   	select CRASH_RESERVE
>   	bool
>   
> diff --git a/kernel/Makefile b/kernel/Makefile
> index 05fa88b3ab74..649272a1d6b9 100644
> --- a/kernel/Makefile
> +++ b/kernel/Makefile
> @@ -68,9 +68,9 @@ obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o
>   obj-$(CONFIG_KALLSYMS) += kallsyms.o
>   obj-$(CONFIG_KALLSYMS_SELFTEST) += kallsyms_selftest.o
>   obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
> -obj-$(CONFIG_CRASH_CORE) += crash_core.o
> +obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
>   obj-$(CONFIG_CRASH_RESERVE) += crash_reserve.o
> -obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
> +obj-$(CONFIG_KEXEC_CORE) += kexec_core.o crash_core.o
>   obj-$(CONFIG_KEXEC) += kexec.o
>   obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
>   obj-$(CONFIG_KEXEC_ELF) += kexec_elf.o
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 055859c62f19..2f4df1fe6f7a 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -26,14 +26,6 @@
>   /* Per cpu memory for storing cpu states in case of system crash. */
>   note_buf_t __percpu *crash_notes;
>   
> -/* vmcoreinfo stuff */
> -unsigned char *vmcoreinfo_data;
> -size_t vmcoreinfo_size;
> -u32 *vmcoreinfo_note;
> -
> -/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
> -static unsigned char *vmcoreinfo_data_safecopy;
> -
>   int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
>   			  void **addr, unsigned long *sz)
>   {
> @@ -195,206 +187,6 @@ int crash_exclude_mem_range(struct crash_mem *mem,
>   	return 0;
>   }
>   
> -Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> -			  void *data, size_t data_len)
> -{
> -	struct elf_note *note = (struct elf_note *)buf;
> -
> -	note->n_namesz = strlen(name) + 1;
> -	note->n_descsz = data_len;
> -	note->n_type   = type;
> -	buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
> -	memcpy(buf, name, note->n_namesz);
> -	buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
> -	memcpy(buf, data, data_len);
> -	buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
> -
> -	return buf;
> -}
> -
> -void final_note(Elf_Word *buf)
> -{
> -	memset(buf, 0, sizeof(struct elf_note));
> -}
> -
> -static void update_vmcoreinfo_note(void)
> -{
> -	u32 *buf = vmcoreinfo_note;
> -
> -	if (!vmcoreinfo_size)
> -		return;
> -	buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
> -			      vmcoreinfo_size);
> -	final_note(buf);
> -}
> -
> -void crash_update_vmcoreinfo_safecopy(void *ptr)
> -{
> -	if (ptr)
> -		memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
> -
> -	vmcoreinfo_data_safecopy = ptr;
> -}
> -
> -void crash_save_vmcoreinfo(void)
> -{
> -	if (!vmcoreinfo_note)
> -		return;
> -
> -	/* Use the safe copy to generate vmcoreinfo note if have */
> -	if (vmcoreinfo_data_safecopy)
> -		vmcoreinfo_data = vmcoreinfo_data_safecopy;
> -
> -	vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
> -	update_vmcoreinfo_note();
> -}
> -
> -void vmcoreinfo_append_str(const char *fmt, ...)
> -{
> -	va_list args;
> -	char buf[0x50];
> -	size_t r;
> -
> -	va_start(args, fmt);
> -	r = vscnprintf(buf, sizeof(buf), fmt, args);
> -	va_end(args);
> -
> -	r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
> -
> -	memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
> -
> -	vmcoreinfo_size += r;
> -
> -	WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
> -		  "vmcoreinfo data exceeds allocated size, truncating");
> -}
> -
> -/*
> - * provide an empty default implementation here -- architecture
> - * code may override this
> - */
> -void __weak arch_crash_save_vmcoreinfo(void)
> -{}
> -
> -phys_addr_t __weak paddr_vmcoreinfo_note(void)
> -{
> -	return __pa(vmcoreinfo_note);
> -}
> -EXPORT_SYMBOL(paddr_vmcoreinfo_note);
> -
> -static int __init crash_save_vmcoreinfo_init(void)
> -{
> -	vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
> -	if (!vmcoreinfo_data) {
> -		pr_warn("Memory allocation for vmcoreinfo_data failed\n");
> -		return -ENOMEM;
> -	}
> -
> -	vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
> -						GFP_KERNEL | __GFP_ZERO);
> -	if (!vmcoreinfo_note) {
> -		free_page((unsigned long)vmcoreinfo_data);
> -		vmcoreinfo_data = NULL;
> -		pr_warn("Memory allocation for vmcoreinfo_note failed\n");
> -		return -ENOMEM;
> -	}
> -
> -	VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
> -	VMCOREINFO_BUILD_ID();
> -	VMCOREINFO_PAGESIZE(PAGE_SIZE);
> -
> -	VMCOREINFO_SYMBOL(init_uts_ns);
> -	VMCOREINFO_OFFSET(uts_namespace, name);
> -	VMCOREINFO_SYMBOL(node_online_map);
> -#ifdef CONFIG_MMU
> -	VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
> -#endif
> -	VMCOREINFO_SYMBOL(_stext);
> -	VMCOREINFO_SYMBOL(vmap_area_list);
> -
> -#ifndef CONFIG_NUMA
> -	VMCOREINFO_SYMBOL(mem_map);
> -	VMCOREINFO_SYMBOL(contig_page_data);
> -#endif
> -#ifdef CONFIG_SPARSEMEM
> -	VMCOREINFO_SYMBOL_ARRAY(mem_section);
> -	VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
> -	VMCOREINFO_STRUCT_SIZE(mem_section);
> -	VMCOREINFO_OFFSET(mem_section, section_mem_map);
> -	VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
> -	VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
> -#endif
> -	VMCOREINFO_STRUCT_SIZE(page);
> -	VMCOREINFO_STRUCT_SIZE(pglist_data);
> -	VMCOREINFO_STRUCT_SIZE(zone);
> -	VMCOREINFO_STRUCT_SIZE(free_area);
> -	VMCOREINFO_STRUCT_SIZE(list_head);
> -	VMCOREINFO_SIZE(nodemask_t);
> -	VMCOREINFO_OFFSET(page, flags);
> -	VMCOREINFO_OFFSET(page, _refcount);
> -	VMCOREINFO_OFFSET(page, mapping);
> -	VMCOREINFO_OFFSET(page, lru);
> -	VMCOREINFO_OFFSET(page, _mapcount);
> -	VMCOREINFO_OFFSET(page, private);
> -	VMCOREINFO_OFFSET(page, compound_head);
> -	VMCOREINFO_OFFSET(pglist_data, node_zones);
> -	VMCOREINFO_OFFSET(pglist_data, nr_zones);
> -#ifdef CONFIG_FLATMEM
> -	VMCOREINFO_OFFSET(pglist_data, node_mem_map);
> -#endif
> -	VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
> -	VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
> -	VMCOREINFO_OFFSET(pglist_data, node_id);
> -	VMCOREINFO_OFFSET(zone, free_area);
> -	VMCOREINFO_OFFSET(zone, vm_stat);
> -	VMCOREINFO_OFFSET(zone, spanned_pages);
> -	VMCOREINFO_OFFSET(free_area, free_list);
> -	VMCOREINFO_OFFSET(list_head, next);
> -	VMCOREINFO_OFFSET(list_head, prev);
> -	VMCOREINFO_OFFSET(vmap_area, va_start);
> -	VMCOREINFO_OFFSET(vmap_area, list);
> -	VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
> -	log_buf_vmcoreinfo_setup();
> -	VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
> -	VMCOREINFO_NUMBER(NR_FREE_PAGES);
> -	VMCOREINFO_NUMBER(PG_lru);
> -	VMCOREINFO_NUMBER(PG_private);
> -	VMCOREINFO_NUMBER(PG_swapcache);
> -	VMCOREINFO_NUMBER(PG_swapbacked);
> -	VMCOREINFO_NUMBER(PG_slab);
> -#ifdef CONFIG_MEMORY_FAILURE
> -	VMCOREINFO_NUMBER(PG_hwpoison);
> -#endif
> -	VMCOREINFO_NUMBER(PG_head_mask);
> -#define PAGE_BUDDY_MAPCOUNT_VALUE	(~PG_buddy)
> -	VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
> -#ifdef CONFIG_HUGETLB_PAGE
> -	VMCOREINFO_NUMBER(PG_hugetlb);
> -#define PAGE_OFFLINE_MAPCOUNT_VALUE	(~PG_offline)
> -	VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
> -#endif
> -
> -#ifdef CONFIG_KALLSYMS
> -	VMCOREINFO_SYMBOL(kallsyms_names);
> -	VMCOREINFO_SYMBOL(kallsyms_num_syms);
> -	VMCOREINFO_SYMBOL(kallsyms_token_table);
> -	VMCOREINFO_SYMBOL(kallsyms_token_index);
> -#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
> -	VMCOREINFO_SYMBOL(kallsyms_offsets);
> -	VMCOREINFO_SYMBOL(kallsyms_relative_base);
> -#else
> -	VMCOREINFO_SYMBOL(kallsyms_addresses);
> -#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
> -#endif /* CONFIG_KALLSYMS */
> -
> -	arch_crash_save_vmcoreinfo();
> -	update_vmcoreinfo_note();
> -
> -	return 0;
> -}
> -
> -subsys_initcall(crash_save_vmcoreinfo_init);
> -
>   static int __init crash_notes_memory_init(void)
>   {
>   	/* Allocate memory for saving cpu registers. */
> diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
> index 1d4bc493b2f4..11526fc42bc2 100644
> --- a/kernel/ksysfs.c
> +++ b/kernel/ksysfs.c
> @@ -154,7 +154,7 @@ KERNEL_ATTR_RW(kexec_crash_size);
>   
>   #endif /* CONFIG_KEXEC_CORE */
>   
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
>   
>   static ssize_t vmcoreinfo_show(struct kobject *kobj,
>   			       struct kobj_attribute *attr, char *buf)
> @@ -177,7 +177,7 @@ KERNEL_ATTR_RO(crash_elfcorehdr_size);
>   
>   #endif
>   
> -#endif /* CONFIG_CRASH_CORE */
> +#endif /* CONFIG_VMCORE_INFO */
>   
>   /* whether file capabilities are enabled */
>   static ssize_t fscaps_show(struct kobject *kobj,
> @@ -265,7 +265,7 @@ static struct attribute * kernel_attrs[] = {
>   	&kexec_crash_loaded_attr.attr,
>   	&kexec_crash_size_attr.attr,
>   #endif
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
>   	&vmcoreinfo_attr.attr,
>   #ifdef CONFIG_CRASH_HOTPLUG
>   	&crash_elfcorehdr_size_attr.attr,
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index f2444b581e16..7d74b000b43a 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -34,7 +34,7 @@
>   #include <linux/security.h>
>   #include <linux/memblock.h>
>   #include <linux/syscalls.h>
> -#include <linux/crash_core.h>
> +#include <linux/vmcore_info.h>
>   #include <linux/ratelimit.h>
>   #include <linux/kmsg_dump.h>
>   #include <linux/syslog.h>
> @@ -951,7 +951,7 @@ const struct file_operations kmsg_fops = {
>   	.release = devkmsg_release,
>   };
>   
> -#ifdef CONFIG_CRASH_CORE
> +#ifdef CONFIG_VMCORE_INFO
>   /*
>    * This appends the listed symbols to /proc/vmcore
>    *
> diff --git a/kernel/vmcore_info.c b/kernel/vmcore_info.c
> new file mode 100644
> index 000000000000..84f3663530c8
> --- /dev/null
> +++ b/kernel/vmcore_info.c
> @@ -0,0 +1,233 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * crash.c - kernel crash support code.
> + * Copyright (C) 2002-2004 Eric Biederman  <ebiederm at xmission.com>
> + */
> +
> +#include <linux/buildid.h>
> +#include <linux/init.h>
> +#include <linux/utsname.h>
> +#include <linux/vmalloc.h>
> +#include <linux/sizes.h>
> +#include <linux/kexec.h>
> +#include <linux/memory.h>
> +#include <linux/cpuhotplug.h>
> +#include <linux/memblock.h>
> +#include <linux/kexec.h>
> +#include <linux/kmemleak.h>
> +
> +#include <asm/page.h>
> +#include <asm/sections.h>
> +
> +#include <crypto/sha1.h>
> +
> +#include "kallsyms_internal.h"
> +#include "kexec_internal.h"
> +
> +/* vmcoreinfo stuff */
> +unsigned char *vmcoreinfo_data;
> +size_t vmcoreinfo_size;
> +u32 *vmcoreinfo_note;
> +
> +/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
> +static unsigned char *vmcoreinfo_data_safecopy;
> +
> +Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> +			  void *data, size_t data_len)
> +{
> +	struct elf_note *note = (struct elf_note *)buf;
> +
> +	note->n_namesz = strlen(name) + 1;
> +	note->n_descsz = data_len;
> +	note->n_type   = type;
> +	buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
> +	memcpy(buf, name, note->n_namesz);
> +	buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
> +	memcpy(buf, data, data_len);
> +	buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
> +
> +	return buf;
> +}
> +
> +void final_note(Elf_Word *buf)
> +{
> +	memset(buf, 0, sizeof(struct elf_note));
> +}
> +
> +static void update_vmcoreinfo_note(void)
> +{
> +	u32 *buf = vmcoreinfo_note;
> +
> +	if (!vmcoreinfo_size)
> +		return;
> +	buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
> +			      vmcoreinfo_size);
> +	final_note(buf);
> +}
> +
> +void crash_update_vmcoreinfo_safecopy(void *ptr)
> +{
> +	if (ptr)
> +		memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
> +
> +	vmcoreinfo_data_safecopy = ptr;
> +}
> +
> +void crash_save_vmcoreinfo(void)
> +{
> +	if (!vmcoreinfo_note)
> +		return;
> +
> +	/* Use the safe copy to generate vmcoreinfo note if have */
> +	if (vmcoreinfo_data_safecopy)
> +		vmcoreinfo_data = vmcoreinfo_data_safecopy;
> +
> +	vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
> +	update_vmcoreinfo_note();
> +}
> +
> +void vmcoreinfo_append_str(const char *fmt, ...)
> +{
> +	va_list args;
> +	char buf[0x50];
> +	size_t r;
> +
> +	va_start(args, fmt);
> +	r = vscnprintf(buf, sizeof(buf), fmt, args);
> +	va_end(args);
> +
> +	r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
> +
> +	memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
> +
> +	vmcoreinfo_size += r;
> +
> +	WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
> +		  "vmcoreinfo data exceeds allocated size, truncating");
> +}
> +
> +/*
> + * provide an empty default implementation here -- architecture
> + * code may override this
> + */
> +void __weak arch_crash_save_vmcoreinfo(void)
> +{}
> +
> +phys_addr_t __weak paddr_vmcoreinfo_note(void)
> +{
> +	return __pa(vmcoreinfo_note);
> +}
> +EXPORT_SYMBOL(paddr_vmcoreinfo_note);
> +
> +static int __init crash_save_vmcoreinfo_init(void)
> +{
> +	vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
> +	if (!vmcoreinfo_data) {
> +		pr_warn("Memory allocation for vmcoreinfo_data failed\n");
> +		return -ENOMEM;
> +	}
> +
> +	vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
> +						GFP_KERNEL | __GFP_ZERO);
> +	if (!vmcoreinfo_note) {
> +		free_page((unsigned long)vmcoreinfo_data);
> +		vmcoreinfo_data = NULL;
> +		pr_warn("Memory allocation for vmcoreinfo_note failed\n");
> +		return -ENOMEM;
> +	}
> +
> +	VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
> +	VMCOREINFO_BUILD_ID();
> +	VMCOREINFO_PAGESIZE(PAGE_SIZE);
> +
> +	VMCOREINFO_SYMBOL(init_uts_ns);
> +	VMCOREINFO_OFFSET(uts_namespace, name);
> +	VMCOREINFO_SYMBOL(node_online_map);
> +#ifdef CONFIG_MMU
> +	VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
> +#endif
> +	VMCOREINFO_SYMBOL(_stext);
> +	VMCOREINFO_SYMBOL(vmap_area_list);
> +
> +#ifndef CONFIG_NUMA
> +	VMCOREINFO_SYMBOL(mem_map);
> +	VMCOREINFO_SYMBOL(contig_page_data);
> +#endif
> +#ifdef CONFIG_SPARSEMEM
> +	VMCOREINFO_SYMBOL_ARRAY(mem_section);
> +	VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
> +	VMCOREINFO_STRUCT_SIZE(mem_section);
> +	VMCOREINFO_OFFSET(mem_section, section_mem_map);
> +	VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
> +	VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
> +#endif
> +	VMCOREINFO_STRUCT_SIZE(page);
> +	VMCOREINFO_STRUCT_SIZE(pglist_data);
> +	VMCOREINFO_STRUCT_SIZE(zone);
> +	VMCOREINFO_STRUCT_SIZE(free_area);
> +	VMCOREINFO_STRUCT_SIZE(list_head);
> +	VMCOREINFO_SIZE(nodemask_t);
> +	VMCOREINFO_OFFSET(page, flags);
> +	VMCOREINFO_OFFSET(page, _refcount);
> +	VMCOREINFO_OFFSET(page, mapping);
> +	VMCOREINFO_OFFSET(page, lru);
> +	VMCOREINFO_OFFSET(page, _mapcount);
> +	VMCOREINFO_OFFSET(page, private);
> +	VMCOREINFO_OFFSET(page, compound_head);
> +	VMCOREINFO_OFFSET(pglist_data, node_zones);
> +	VMCOREINFO_OFFSET(pglist_data, nr_zones);
> +#ifdef CONFIG_FLATMEM
> +	VMCOREINFO_OFFSET(pglist_data, node_mem_map);
> +#endif
> +	VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
> +	VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
> +	VMCOREINFO_OFFSET(pglist_data, node_id);
> +	VMCOREINFO_OFFSET(zone, free_area);
> +	VMCOREINFO_OFFSET(zone, vm_stat);
> +	VMCOREINFO_OFFSET(zone, spanned_pages);
> +	VMCOREINFO_OFFSET(free_area, free_list);
> +	VMCOREINFO_OFFSET(list_head, next);
> +	VMCOREINFO_OFFSET(list_head, prev);
> +	VMCOREINFO_OFFSET(vmap_area, va_start);
> +	VMCOREINFO_OFFSET(vmap_area, list);
> +	VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
> +	log_buf_vmcoreinfo_setup();
> +	VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
> +	VMCOREINFO_NUMBER(NR_FREE_PAGES);
> +	VMCOREINFO_NUMBER(PG_lru);
> +	VMCOREINFO_NUMBER(PG_private);
> +	VMCOREINFO_NUMBER(PG_swapcache);
> +	VMCOREINFO_NUMBER(PG_swapbacked);
> +	VMCOREINFO_NUMBER(PG_slab);
> +#ifdef CONFIG_MEMORY_FAILURE
> +	VMCOREINFO_NUMBER(PG_hwpoison);
> +#endif
> +	VMCOREINFO_NUMBER(PG_head_mask);
> +#define PAGE_BUDDY_MAPCOUNT_VALUE	(~PG_buddy)
> +	VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
> +#ifdef CONFIG_HUGETLB_PAGE
> +	VMCOREINFO_NUMBER(PG_hugetlb);
> +#define PAGE_OFFLINE_MAPCOUNT_VALUE	(~PG_offline)
> +	VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
> +#endif
> +
> +#ifdef CONFIG_KALLSYMS
> +	VMCOREINFO_SYMBOL(kallsyms_names);
> +	VMCOREINFO_SYMBOL(kallsyms_num_syms);
> +	VMCOREINFO_SYMBOL(kallsyms_token_table);
> +	VMCOREINFO_SYMBOL(kallsyms_token_index);
> +#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
> +	VMCOREINFO_SYMBOL(kallsyms_offsets);
> +	VMCOREINFO_SYMBOL(kallsyms_relative_base);
> +#else
> +	VMCOREINFO_SYMBOL(kallsyms_addresses);
> +#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
> +#endif /* CONFIG_KALLSYMS */
> +
> +	arch_crash_save_vmcoreinfo();
> +	update_vmcoreinfo_note();
> +
> +	return 0;
> +}
> +
> +subsys_initcall(crash_save_vmcoreinfo_init);
> diff --git a/lib/buildid.c b/lib/buildid.c
> index e3a7acdeef0e..3e6868c86b45 100644
> --- a/lib/buildid.c
> +++ b/lib/buildid.c
> @@ -174,7 +174,7 @@ int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size)
>   	return parse_build_id_buf(build_id, NULL, buf, buf_size);
>   }
>   
> -#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
> +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_VMCORE_INFO)
>   unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX] __ro_after_init;
>   
>   /**



From wsa at kernel.org  Wed Feb 21 09:43:55 2024
From: wsa at kernel.org (Wolfram Sang)
Date: Wed, 21 Feb 2024 18:43:55 +0100
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <CZAX02IL1N1J.2GQR9D73GLRZB@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>
 <20240216022704.GB850600-robh@kernel.org>
 <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>
 <CACRpkdZZhhzg5SY7U5dv_OfLEVejRFom4V9nCfkQXunAw1ZXSw@mail.gmail.com>
 <CZ94LGRSF9KN.15ZO1VRMIQVR8@bootlin.com>
 <CZAX02IL1N1J.2GQR9D73GLRZB@bootlin.com>
Message-ID: <ZdY2WzKbElloXC4-@shikoro>

Hi,

> > > > i2c-mpc (fsl,timeout) and i2c-gpio (i2c-gpio,timeout-ms). I agree this
> > > > prop has no reason to be compatible-specific.

Anyone up to convert these drivers to the new binding and mark the old
ones as deprecated?

> > > As Rob mentioned this isn't in the kernel schemas but in dtschema, so
> > > you need to patch this:
> > > https://github.com/robherring/dt-schema

@Rob: My memory fails a little bit about these two schemas: we have the
github one for generic bindings, not strictly related to Linux, right?
But why do we have then i2c.txt in ther kernel tree? Why don't we sync
regularly with the generic schema?

> Note: I've sent a draft patch to dt-schema. See:
> https://github.com/devicetree-org/dt-schema/pull/129

I used to argue that you can set this timeout to any value in userspace.
I have been convinced that it might make sense to set it early so it is
in use already when booting. So, for this pull request:

Reviewed-by: Wolfram Sang <wsa+renesas at sang-engineering.com>

All the best,

   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/20240221/9997fa29/attachment.sig>

From tudor.ambarus at linaro.org  Wed Feb 21 09:56:16 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Wed, 21 Feb 2024 17:56:16 +0000
Subject: [PATCH v3 12/12] spi: s3c64xx: switch exynos850 to new port
 config data
In-Reply-To: <20240216070555.2483977-13-tudor.ambarus@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
 <20240216070555.2483977-13-tudor.ambarus@linaro.org>
Message-ID: <10f692ae-ac7a-4243-aadc-80712f781d39@linaro.org>


Hey, Sam,


On 2/16/24 07:05, Tudor Ambarus wrote:
> Exynos850 has the same version of USI SPI (v2.1) as GS101.

I tested GS101 and it worked, I guess exynos850 SPI shall work too as it
uses the same SPI version, v2.1. Can you run a test on your side too see
if works? If not, Mark can drop this patch I guess. Please let us know
your preference.

Cheers,
ta

> Drop the fifo_lvl_mask and rx_lvl_offset and switch to the new port
> config data.
> 
> Backward compatibility with DT is not broken because when alises are
> set:
> - the SPI core will set the bus number according to the alias ID
> - the FIFO depth is always the same size for exynos850 (64 bytes) no
>   matter the alias ID number.
> 
> Advantages of the change:
> - drop dependency on the OF alias ID.
> - FIFO depth is inferred from the compatible. Exynos850 integrates 3 SPI
>   IPs, all with 64 bytes FIFO depths.
> - use full mask for SPI_STATUS.{RX, TX}_FIFO_LVL fields. Using partial
>   masks is misleading and can hide problems of the driver logic.
> 
> Just compiled tested.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
>  drivers/spi/spi-s3c64xx.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index 784786407d2e..9fcbe040cb2f 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -1576,10 +1576,9 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
>  };
>  
>  static const struct s3c64xx_spi_port_config exynos850_spi_port_config = {
> -	/* fifo_lvl_mask is deprecated. Use {rx, tx}_fifomask instead. */
> -	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f },
> -	/* rx_lvl_offset is deprecated. Use {rx, tx}_fifomask instead. */
> -	.rx_lvl_offset	= 15,
> +	.fifo_depth	= 64,
> +	.rx_fifomask	= S3C64XX_SPI_ST_RX_FIFO_RDY_V2,
> +	.tx_fifomask	= S3C64XX_SPI_ST_TX_FIFO_RDY_V2,
>  	.tx_st_done	= 25,
>  	.clk_div	= 4,
>  	.high_speed	= true,


From dalias at libc.org  Wed Feb 21 09:57:19 2024
From: dalias at libc.org (dalias at libc.org)
Date: Wed, 21 Feb 2024 12:57:19 -0500
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
References: <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
 <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
 <20240220235415.GP4163@brightrain.aerifal.cx>
 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx>
 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx>
 <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
Message-ID: <20240221175717.GS4163@brightrain.aerifal.cx>

On Wed, Feb 21, 2024 at 05:36:12PM +0000, Mark Brown wrote:
> On Wed, Feb 21, 2024 at 09:58:01AM -0500, dalias at libc.org wrote:
> > On Wed, Feb 21, 2024 at 01:53:10PM +0000, Mark Brown wrote:
> > > On Tue, Feb 20, 2024 at 08:27:37PM -0500, dalias at libc.org wrote:
> > > > On Wed, Feb 21, 2024 at 12:35:48AM +0000, Edgecombe, Rick P wrote:
> 
> > > > > (INCSSP, RSTORSSP, etc). These are a collection of instructions that
> > > > > allow limited control of the SSP. When shadow stack gets disabled,
> > > > > these suddenly turn into #UD generating instructions. So any other
> > > > > threads executing those instructions when shadow stack got disabled
> > > > > would be in for a nasty surprise.
> 
> > > > This is the kernel's problem if that's happening. It should be
> > > > trapping these and returning immediately like a NOP if shadow stack
> > > > has been disabled, not generating SIGILL.
> 
> > > I'm not sure that's going to work out well, all it takes is some code
> > > that's looking at the shadow stack and expecting something to happen as
> > > a result of the instructions it's executing and we run into trouble.  A
> 
> > I said NOP but there's no reason it strictly needs to be a NOP. It
> > could instead do something reasonable to convey the state of racing
> > with shadow stack being disabled.
> 
> This feels like it's getting complicated and I fear it may be an uphill
> struggle to get such code merged, at least for arm64.  My instinct is
> that it's going to be much more robust and generally tractable to let
> things run to some suitable synchronisation point and then disable
> there, but if we're going to do that then userspace can hopefully
> arrange to do the disabling itself through the standard disable
> interface anyway.  Presumably it'll want to notice things being disabled
> at some point anyway?  TBH that's been how all the prior proposals for
> process wide disable I've seen were done.

If it's possible to disable per-thread rather than per-process, some
things are easier. Disabling on account of using alt stacks only needs
to be done on the threads using those stacks. However, for dlopen
purposes you need a way to disable shadow stack for the whole process.
Initially this is only needed for the thread that called dlopen, but
it needs to have propagated to any thread that synchronizes with
completion of the call to dlopen by the time that synchronization
occurs, and since that synchronization can happen in lots of different
ways that are purely userspace (thanks to futexes being userspace in
the uncontended case), I don't see any way to make it work without
extremely invasive, high-cost checks.

If folks on the kernel side are not going to be amenable to doing the
things that are easy for the kernel to make it work without breaking
compatibility with existing interfaces, but that are impossible or
near-impossible for userspace to do, this seems like a dead-end. And I
suspect an operation to "disable shadow stack, but without making
threads still in SS-critical sections crash" is going to be
necessary..

Rich


From minyard at acm.org  Wed Feb 21 10:08:16 2024
From: minyard at acm.org (Corey Minyard)
Date: Wed, 21 Feb 2024 12:08:16 -0600
Subject: [PATCH] ipmi: kcs: Update OBF poll timeout to reduce latency
In-Reply-To: <527F52AB-0070-43EA-BE82-945280CA2AEE@gmail.com>
References: <20240220123615.963916-1-geissonator@gmail.com>
 <a9169894-6972-49c0-a1d4-d80863f5b511@molgen.mpg.de>
 <ZdT+eThnYqb3iawF@mail.minyard.net>
 <9680ad7d7a48fc36a0572dc2286a1229a29341fe.camel@codeconstruct.com.au>
 <527F52AB-0070-43EA-BE82-945280CA2AEE@gmail.com>
Message-ID: <ZdY8EDfeePse3c1s@mail.minyard.net>

On Wed, Feb 21, 2024 at 10:57:38AM -0600, Andrew Geissler wrote:
> 
> 
> > On Feb 20, 2024, at 4:36?PM, Andrew Jeffery <andrew at codeconstruct.com.au> wrote:
> > 
> > On Tue, 2024-02-20 at 13:33 -0600, Corey Minyard wrote:
> >> On Tue, Feb 20, 2024 at 04:51:21PM +0100, Paul Menzel wrote:
> >>> Dear Andrew,
> >> 
> >> It's because increasing that number causes it to poll longer for the
> >> event, the host takes longer than 100us to generate the event, and if
> >> the event is missed the time when it is checked again is very long.
> >> 
> >> Polling for 100us is already pretty extreme. 200us is really too long.
> >> 
> >> The real problem is that there is no interrupt for this.  I'd also guess
> >> there is no interrupt on the host side, because that would solve this
> >> problem, too, as it would certainly get around to handling the interupt
> >> in 100us.  I'm assuming the host driver is not the Linux driver, as it
> >> should also handle this in a timely manner, even when polling.
> > 
> > I expect the issues Andrew G is observing are with the Power10 boot
> > firmware. The boot firmware only polls. The runtime firmware enables
> > interrupts.
> 
> Yep, this is with the low level host boot firmware.
> Also, further testing over night showed that 200us wasn?t enough for
> our larger Everest P10 machines, I needed to go to 300us. As we
> were struggling to allow 200us, I assume 300us is going to be a no-go.

It seems odd to me that firmware polling would be an issue.  Usually,
with firmware, you have it just spinning waiting for something.  At
least in the firmware I worked with.

I'm not familiar with this firmware, though, maybe it has timers and
such and parallel execution.  Can this be fixed on the firmware side?

> 
> >> 
> > 
> >> 
> >> The right way to fix this is probably to do the same thing the host side
> >> Linux driver does.  It has a kernel thread that is kicked off to do
> >> this.  Unfortunately, that's more complicated to implement, but it
> >> avoids polling in this location (which causes latency issues on the BMC
> >> side) and lets you poll longer without causing issues.
> > 
> > In Andrew G's case he's talking MCTP over KCS using a vendor-defined
> > transport binding (that also leverages LPC FWH cycles for bulk data
> > transfers)[1]. I think it could have taken more inspiration from the
> > IPMI KCS protocol: It might be worth an experiment to write the dummy
> > command value to IDR from the host side after each ODR read to signal
> > the host's clearing of OBF (no interrupt for the BMC) with an IBF
> > (which does interrupt the BMC). And doing the obverse for the BMC. Some
> > brief thought suggests that if the dummy value is read there's no need
> > to send a dummy value in reply (as it's an indicator to read the status
> > register). With that the need for the spin here (or on the host side)
> > is reduced at the cost of some constant protocol overhead.
> > 
> 
> Thanks for the quick reviews and ideas.
> I?ll see if I can find someone on the team to help out with Andrew J?s
> thoughts and if that doesn?t work, look into the kernel thread idea.

I don't really understand Andrew J's ideas very well, but hopefully they
help.  The kernel thread idea is fairly complicated to implement, and
there has been an impetus in the kernel to not create new kernel
threads.  But there just has to be a good reason, and this probably is
one.  We worked on it a lot in the IPMI host driver to tune it and got
it to a point where it provided decent performance without causing power
management issues.  When I first read the title I was worried it was
talking about this code; I'm lothe to touch it for fear of breaking
things.

-corey


From rick.p.edgecombe at intel.com  Wed Feb 21 10:12:30 2024
From: rick.p.edgecombe at intel.com (Edgecombe, Rick P)
Date: Wed, 21 Feb 2024 18:12:30 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in
 userspace
In-Reply-To: <20240221175717.GS4163@brightrain.aerifal.cx>
References: <22a53b78-10d7-4a5a-a01e-b2f3a8c22e94@app.fastmail.com>
	 <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
	 <20240220185714.GO4163@brightrain.aerifal.cx>
	 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
	 <20240220235415.GP4163@brightrain.aerifal.cx>
	 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
	 <20240221012736.GQ4163@brightrain.aerifal.cx>
	 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
	 <20240221145800.GR4163@brightrain.aerifal.cx>
	 <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
	 <20240221175717.GS4163@brightrain.aerifal.cx>
Message-ID: <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>

On Wed, 2024-02-21 at 12:57 -0500, dalias at libc.org wrote:
> > This feels like it's getting complicated and I fear it may be an
> > uphill
> > struggle to get such code merged, at least for arm64.? My instinct
> > is
> > that it's going to be much more robust and generally tractable to
> > let
> > things run to some suitable synchronisation point and then disable
> > there, but if we're going to do that then userspace can hopefully
> > arrange to do the disabling itself through the standard disable
> > interface anyway.? Presumably it'll want to notice things being
> > disabled
> > at some point anyway?? TBH that's been how all the prior proposals
> > for
> > process wide disable I've seen were done.
> 
> If it's possible to disable per-thread rather than per-process, some
> things are easier. Disabling on account of using alt stacks only
> needs
> to be done on the threads using those stacks. However, for dlopen
> purposes you need a way to disable shadow stack for the whole
> process.
> Initially this is only needed for the thread that called dlopen, but
> it needs to have propagated to any thread that synchronizes with
> completion of the call to dlopen by the time that synchronization
> occurs, and since that synchronization can happen in lots of
> different
> ways that are purely userspace (thanks to futexes being userspace in
> the uncontended case), I don't see any way to make it work without
> extremely invasive, high-cost checks.

For glibc's use, we talked about a couple of options.
1. A mode to start suppressing the #UD's from the shadow stack
instructions
2. A mode to start suppressing #CPs (the exception that happens when
the shadow stack doesn't match). So the shadow stack instructions
continue to operate normally, but if the shadow stack gets mismatched
due to lack of support, the ret is emulated. It probably is safer (but
still not perfect), but the performance penalty of emulating every RET
after things get screwed up would be a significant down side. There
also needs to be clean handling of shadow stack #PFs.
3. Per-thread locking that is used around all shadow stack operations
that could be sensitive to disabling. This could be maybe exposed to
apps in case they want to use shadow stack instructions manually. Then
during dlopen() it waits until it can cleanly disable shadow stack for
each thread. In each critical sections there are checks for whether
shadow stack is still enabled.

3 is the cleanest and safest I think, and it was thought it might not
need kernel help, due to a scheme Florian had to direct signals to
specific threads. It's my preference at this point.

1 and 2 are POCed here, if you are interested:
https://github.com/rpedgeco/linux/commits/shstk_suppress_rfc/

> 
> If folks on the kernel side are not going to be amenable to doing the
> things that are easy for the kernel to make it work without breaking
> compatibility with existing interfaces, but that are impossible or
> near-impossible for userspace to do, this seems like a dead-end. And
> I
> suspect an operation to "disable shadow stack, but without making
> threads still in SS-critical sections crash" is going to be
> necessary..

I think we have to work through all the alternative before we can
accuse the kernel of not being amenable. Is there something that you
would like to see out of this conversation that is not happening?

From broonie at kernel.org  Wed Feb 21 10:16:36 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 21 Feb 2024 18:16:36 +0000
Subject: [PATCH v8 20/38] arm64/gcs: Ensure that new threads have a GCS
In-Reply-To: <874je399ld.fsf@linaro.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <20240203-arm64-gcs-v8-20-c9fec77673ef@kernel.org>
 <874je399ld.fsf@linaro.org>
Message-ID: <9400cfc3-0e87-4abd-afbc-172736d77a1b@sirena.org.uk>

On Mon, Feb 19, 2024 at 11:02:22PM -0300, Thiago Jung Bauermann wrote:
> Mark Brown <broonie at kernel.org> writes:

> > +		gcspr_el0 = addr + size - (2 * sizeof(u64));
> > +		if (!gcs_consume_token(tsk, gcspr_el0)) {

> Should this code validate the end of stack marker? Or doesn't it matter
> whether the marker is correct or not?

I don't think we specifically care, we're just looking for a token 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/20240221/8a2fe095/attachment.sig>

From mark.rutland at arm.com  Wed Feb 21 10:23:28 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 21 Feb 2024 18:23:28 +0000
Subject: [PATCH V16 4/8] drivers: perf: arm_pmuv3: Enable branch stack
 sampling via FEAT_BRBE
In-Reply-To: <20240125094119.2542332-5-anshuman.khandual@arm.com>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-5-anshuman.khandual@arm.com>
Message-ID: <ZdY_oEYPGSj7nwvP@FVFF77S0Q05N>

On Thu, Jan 25, 2024 at 03:11:15PM +0530, Anshuman Khandual wrote:
> This extends recently added branch stack sampling framework in ARMV8 PMU to
> enable such events via new architecture feature called Branch Record Buffer
> Extension aka BRBE. This implements all the armv8pmu_branch_xxx() callbacks
> as expected at ARMV8 PMU level required to drive perf branch stack sampling
> events. This adds a new config option CONFIG_ARM64_BRBE to encapsulate this
> BRBE based implementation, available only on ARM64 platforms.
> 
> BRBE hardware captures a branch record via three distinct system registers
> representing branch source address, branch target address, and other branch
> information. A BRBE buffer implementation is organized as multiple banks of
> 32 branch records each, which is a collection of BRBSRC_EL1, BRBTGT_EL1 and
> BRBINF_EL1 registers. Though total BRBE record entries i.e BRBE_MAX_ENTRIES
> cannot exceed MAX_BRANCH_RECORDS as defined for ARM PMU.
> 
> BRBE hardware attributes get captured in a new reg_brbidr element in struct
> arm_pmu during armv8pmu_branch_probe() which is called from broader probing
> function __armv8pmu_probe_pmu(). Attributes such as number of branch record
> entries implemented in the hardware can be derived from armpmu->reg_brbidr.
> 
> BRBE gets enabled via armv8pmu_branch_enable() where it also derives branch
> filter, and additional requirements from event's 'attr.branch_sample_type'
> and configures them via BRBFCR_EL1 and BRBCR_EL1 registers.
> 
> PMU event overflow triggers IRQ, where current branch records get captured,
> stitched along with older records available in 'task_ctx', before getting
> processed for core perf ring buffer. Task context switch outs incrementally
> save current branch records in event's 'pmu_ctx->task_ctx_data' to optimize
> workload's branch record samples.
> 
> In case multiple events with different branch sample type requests converge
> on the same PMU, BRBE gets enabled for branch filters for the last event's
> branch sample type. No branch records will be captured and processed for an
> event if BRBE hardware config does not match its branch sample type, while
> handling the PMU IRQ.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> 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>
> ---
> Changes in V16:
> 
> - Added new PERF_SAMPLE_BRANCH_COUNTERS into BRBE_EXCLUDE_BRANCH_FILTERS
> - Fixed typo (s/informations/information) in Documentation/arch/arm64/brbe.rst
> - Added SPDX-License-Identifier in Documentation/arch/arm64/brbe.rst
> 
>  Documentation/arch/arm64/booting.rst |   6 +
>  Documentation/arch/arm64/brbe.rst    | 158 +++++
>  arch/arm64/include/asm/el2_setup.h   | 113 ++-
>  drivers/perf/Kconfig                 |  11 +
>  drivers/perf/Makefile                |   1 +
>  drivers/perf/arm_brbe.c              | 986 +++++++++++++++++++++++++++
>  drivers/perf/arm_pmuv3_branch.h      |  13 +
>  include/linux/perf/arm_pmu.h         |   5 +
>  8 files changed, 1290 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/arch/arm64/brbe.rst
>  create mode 100644 drivers/perf/arm_brbe.c
> 
> diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
> index b57776a68f15..2276df285e83 100644
> --- a/Documentation/arch/arm64/booting.rst
> +++ b/Documentation/arch/arm64/booting.rst
> @@ -349,6 +349,12 @@ Before jumping into the kernel, the following conditions must be met:
>  
>      - HWFGWTR_EL2.nSMPRI_EL1 (bit 54) must be initialised to 0b01.
>  
> +  For CPUs with feature Branch Record Buffer Extension (FEAT_BRBE):
> +
> +  - If the kernel is entered at EL1 and EL2 is present:
> +
> +    - BRBCR_EL2.CC (bit 3) must be initialised to 0b1.
> +

We don't care about any of the other bits? e.g. MPRED?

There are no EL3 controls or fine-grain traps we care about?

>    For CPUs with the Scalable Matrix Extension FA64 feature (FEAT_SME_FA64):
>  
>    - If EL3 is present:
> diff --git a/Documentation/arch/arm64/brbe.rst b/Documentation/arch/arm64/brbe.rst
> new file mode 100644
> index 000000000000..c6380db3b03a
> --- /dev/null
> +++ b/Documentation/arch/arm64/brbe.rst
> @@ -0,0 +1,158 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +============================================
> +Branch Record Buffer Extension aka FEAT_BRBE
> +============================================
> +
> +Author: Anshuman Khandual <anshuman.khandual at arm.com>
> +
> +FEAT_BRBE is an optional architecture feature, which creates branch records
> +containing information about change in control flow. The branch information
> +contains source address, target address, and some relevant metadata related
> +to that change in control flow. BRBE can be configured to filter out branch
> +records based on their type and privilege level.

Do we actually need this documentation?

The set of peopl writing kernel code can read the ARM ARM or the kernel code,
and there's not much here useful to users.

I think it may make sense to document what userspace and/or VMs can and cannot
do (which is why we describe the ID registers), and any 'gotchas' (e.g.
restrictions we have that other architectures don't, or vice-versa). I do not
think that we should try to describe the hardware beyond what is necessary to
describe that, and I do not think that we should describe the structure of the
perf code beyond what is necessary to desribe that.

Otherwise, this is just a maintenance burden.

[...]

> +BRBE Hardware
> +=============
> +
> +FEAT_BRBE support on a given implementation, can be determined from system
> +register field ID_AA64DFR0_EL1.BRBE, containing 'ID_AA64DFR0_EL1_BRBE_IMP'
> +or 'ID_AA64DFR0_EL1_BRBE_BRBE_V1P1'. All BRBE system registers, including
> +branch record banks are available for each CPU.

I do not think that we need to explain the system-register level interface
here. That's documented in the ARM ARM, and userspace doesn't care.

[...]


> +Perf Implementation
> +===================
> +
> +Perf branch stack sampling framework has been enabled on arm64 platform via
> +this new FEAT_BRBE feature. The following description explains how this has
> +been implemented in various levels of abstraction - from perf core all the
> +way to ARMv8 PMUv3 implementation.

This should be described in comments in the code. This will rapdily become
stale and it's just a maintenance burden.

[...]

> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> index b7afaa026842..649b926bf69d 100644
> --- a/arch/arm64/include/asm/el2_setup.h
> +++ b/arch/arm64/include/asm/el2_setup.h
> @@ -154,6 +154,51 @@
>  .Lskip_set_cptr_\@:
>  .endm
>  
> +#ifdef CONFIG_ARM64_BRBE
> +/*
> + * Enable BRBE cycle count
> + *
> + * BRBE requires both BRBCR_EL1.CC and BRBCR_EL2.CC fields, be set
> + * for the cycle counts to be available in BRBINF<N>_EL1.CC during
> + * branch record processing after a PMU interrupt. This enables CC
> + * field on both these registers while still executing inside EL2.
> + *
> + * BRBE driver would still be able to toggle branch records cycle
> + * count support via BRBCR_EL1.CC field regardless of whether the
> + * kernel ends up executing in EL1 or EL2.
> + */
> +.macro __init_el2_brbe
> +	mrs	x1, id_aa64dfr0_el1
> +	ubfx	x1, x1, #ID_AA64DFR0_EL1_BRBE_SHIFT, #4
> +	cbz	x1, .Lskip_brbe_cc_\@
> +
> +	mrs_s	x0, SYS_BRBCR_EL2
> +	orr	x0, x0, BRBCR_ELx_CC
> +	msr_s	SYS_BRBCR_EL2, x0

Please initialise this to a specific value rather than using a
read-modify-write.

> +
> +	/*
> +	 * Accessing BRBCR_EL1 register here does not require
> +	 * BRBCR_EL12 addressing mode as HCR_EL2.E2H is still
> +	 * clear. Regardless, check for HCR_E2H and be on the
> +	 * safer side.
> +	 */

Presumably this won't be the case for FEAT_E2H0, so the comment is going to be
misleading. So probably best to just delete the comment...

> +	mrs	x1, hcr_el2
> +	and	x1, x1, #HCR_E2H
> +	cbz	x1, .Lset_brbe_el1_direct_\@
> +
> +	mrs_s	x0, SYS_BRBCR_EL12
> +	orr	x0, x0, BRBCR_ELx_CC
> +	msr_s	SYS_BRBCR_EL12, x0
> +	b	.Lskip_brbe_cc_\@
> +
> +.Lset_brbe_el1_direct_\@:

Why 'direct'? This is just VHE vs nVHE.

Please look at the way finalise_el2_state() handles (h)VHE and nVHE, and do the
same thing here...

> +	mrs_s	x0, SYS_BRBCR_EL1
> +	orr	x0, x0, BRBCR_ELx_CC
> +	msr_s	SYS_BRBCR_EL1, x0
> +.Lskip_brbe_cc_\@:
> +.endm
> +#endif
> +
>  /* Disable any fine grained traps */
>  .macro __init_el2_fgt
>  	mrs	x1, id_aa64mmfr0_el1
> @@ -161,16 +206,62 @@
>  	cbz	x1, .Lskip_fgt_\@
>  
>  	mov	x0, xzr
> +	mov	x2, xzr
>  	mrs	x1, id_aa64dfr0_el1
>  	ubfx	x1, x1, #ID_AA64DFR0_EL1_PMSVer_SHIFT, #4
>  	cmp	x1, #3
>  	b.lt	.Lset_debug_fgt_\@
> +
>  	/* Disable PMSNEVFR_EL1 read and write traps */
> -	orr	x0, x0, #(1 << 62)
> +	orr	x0, x0, #HDFGRTR_EL2_nPMSNEVFR_EL1_MASK
> +	orr	x2, x2, #HDFGWTR_EL2_nPMSNEVFR_EL1_MASK
>  
>  .Lset_debug_fgt_\@:
> +	mrs	x1, id_aa64dfr0_el1
> +	ubfx	x1, x1, #ID_AA64DFR0_EL1_BRBE_SHIFT, #4
> +	cbz	x1, .Lskip_brbe_reg_fgt_\@
> +
> +	/*
> +	 * Disable read traps for the following BRBE related
> +	 * registers.
> +	 *
> +	 * BRBSRC_EL1
> +	 * BRBTGT_EL1
> +	 * BRBINF_EL1
> +	 * BRBSRCINJ_EL1
> +	 * BRBTGTINJ_EL1
> +	 * BRBINFINJ_EL1
> +	 * BRBTS_EL1
> +	 */
> +	orr	x0, x0, #HDFGRTR_EL2_nBRBDATA_MASK
> +
> +	/*
> +	 * Disable write traps for the following BRBE related
> +	 * registers.
> +	 *
> +	 * BRBSRCINJ_EL1
> +	 * BRBTGTINJ_EL1
> +	 * BRBINFINJ_EL1
> +	 * BRBTS_EL1
> +	 */
> +	orr	x2, x2, #HDFGWTR_EL2_nBRBDATA_MASK
> +
> +	/*
> +	 * Disable both read and write traps for the following
> +	 * BRBE related registers.
> +	 *
> +	 * BRBCR_EL1
> +	 * BRBFCR_EL1
> +	 */
> +	orr	x0, x0, #HDFGRTR_EL2_nBRBCTL_MASK
> +	orr	x2, x2, #HDFGWTR_EL2_nBRBCTL_MASK
> +
> +	/* Disable BRBIDR_EL1 read traps */
> +	orr	x0, x0, #HDFGRTR_EL2_nBRBIDR_MASK
> +
> +.Lskip_brbe_reg_fgt_\@:
>  	msr_s	SYS_HDFGRTR_EL2, x0
> -	msr_s	SYS_HDFGWTR_EL2, x0
> +	msr_s	SYS_HDFGWTR_EL2, x2
>  
>  	mov	x0, xzr
>  	mrs	x1, id_aa64pfr1_el1
> @@ -193,7 +284,20 @@
>  .Lset_fgt_\@:
>  	msr_s	SYS_HFGRTR_EL2, x0
>  	msr_s	SYS_HFGWTR_EL2, x0
> -	msr_s	SYS_HFGITR_EL2, xzr
> +
> +	mov	x0, xzr
> +	mrs	x1, id_aa64dfr0_el1
> +	ubfx	x1, x1, #ID_AA64DFR0_EL1_BRBE_SHIFT, #4
> +	cbz	x1, .Lskip_brbe_insn_fgt_\@
> +
> +	/* Disable traps for BRBIALL instruction */
> +	orr	x0, x0, #HFGITR_EL2_nBRBIALL_MASK
> +
> +	/* Disable traps for BRBINJ instruction */
> +	orr	x0, x0, #HFGITR_EL2_nBRBINJ_MASK
> +
> +.Lskip_brbe_insn_fgt_\@:
> +	msr_s	SYS_HFGITR_EL2, x0
>  
>  	mrs	x1, id_aa64pfr0_el1		// AMU traps UNDEF without AMU
>  	ubfx	x1, x1, #ID_AA64PFR0_EL1_AMU_SHIFT, #4

None of the fine-grain trap requirements were described in booting.rst, and
presumably should be, as we describe that for other features.

Can you split up the booting.rst and el2 setup code into a preparatory patch
jsut before the actual BRBE changes? It'll make it easier for people (e.g. KVM
folk) to review that in isolation, and we can settle that even if the actual
BRBE driver needs work.

[...]

> +enum brbe_bank_idx {
> +	BRBE_BANK_IDX_INVALID = -1,
> +	BRBE_BANK_IDX_0,
> +	BRBE_BANK_IDX_1,
> +	BRBE_BANK_IDX_MAX
> +};

AFAICT, this enum type isn't used anywhere in this series, nor so
BRBE_BANK_IDX_INVALID or BRBE_BANK_IDX_MAX. Please get rid of it, and just use
plain 0 and 1 for bank indices.v

[...]

> +/*
> + * A branch record with BRBINFx_EL1.LASTFAILED set, implies that all
> + * preceding consecutive branch records, that were in a transaction
> + * (i.e their BRBINFx_EL1.TX set) have been aborted.
> + *
> + * Similarly BRBFCR_EL1.LASTFAILED set, indicate that all preceding
> + * consecutive branch records up to the last record, which were in a
> + * transaction (i.e their BRBINFx_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
> + *
> + * BRBFCR_EL1.LASTFAILED fails all those consecutive, in transaction
> + * branches records near the end of the BRBE buffer.
> + *
> + * Architecture does not guarantee a non transaction (TX = 0) branch
> + * record between two different transactions. So it is possible that
> + * a subsequent lastfailed record (TX = 0, LF = 1) might erroneously
> + * mark more than required transactions as aborted.
> + */
> +static void process_branch_aborts(struct pmu_hw_events *cpuc)
> +{
> +	u64 brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
> +	bool lastfailed = !!(brbfcr & BRBFCR_EL1_LASTFAILED);
> +	int idx = brbe_get_numrec(cpuc->percpu_pmu->reg_brbidr) - 1;
> +	struct perf_branch_entry *entry;
> +
> +	do {
> +		entry = &cpuc->branches->branch_entries[idx];
> +		if (entry->in_tx) {
> +			entry->abort = lastfailed;
> +		} else {
> +			lastfailed = entry->abort;
> +			entry->abort = false;
> +		}
> +	} while (idx--, idx >= 0);
> +}

Please consider:

1) There are no extant CPU implementations with TME.
2) There are no plans for anyone to build TME.
3) The kernel doesn't support TME.

... so why are we tryting to handle this architectural edge-case (complete with
what is arguably an architectural bug!) that can only happen on a CPU with TME,
under a kernel that's using TME?

This cannot possibly have been tested, trivially by point 3.

This is purely a maintenance and review burden.

Please delete this and replace it with a comment somewhere that *if* we ever
add support for TME this will need to be handled somehow.

Mark.


From carlos.bilbao at amd.com  Wed Feb 21 10:23:25 2024
From: carlos.bilbao at amd.com (Carlos Bilbao)
Date: Wed, 21 Feb 2024 12:23:25 -0600
Subject: [PATCH v8 00/10] KVM: selftests: Add SEV smoke test
In-Reply-To: <20240203000917.376631-1-seanjc@google.com>
References: <20240203000917.376631-1-seanjc@google.com>
Message-ID: <cc9a1951-e76c-470d-a4d1-8ad67bae5794@amd.com>

Hello,

On 2/2/24 18:09, Sean Christopherson wrote:
> Add a basic SEV smoke test.  Unlike the intra-host migration tests, this
> one actually runs a small chunk of code in the guest.
> 
> v8:
>   - Undo the kvm.h uAPI breakage.
>   - Take advantage of "struct vm_shape", introduced by the guest_memfd
>     selftests, to simply tracking the SEV/SEV-ES subtypes.
>   - Rename the test to "sev_smoke_test" instead of "sev_all_boot_test",
>     as the "all" is rather nonsensical, and the test isn't booting anything
>     in the traditional sense of the word.
>   - Drop vm->protected and instead add an arch hook to query if the VM has
>     protected memory.
>   - Assert that the target memory region supports protected memory when
>     allocating protected memory.
>   - Allocate protected_phy_pages for memory regions if and only if the VM
>     supports protected memory.
>   - Rename kvm_host.h to kvm_util_arch.h, and move it to selftests/kvm where
>     it belongs.
>   - Fix up some SoB goofs.
>   - Convert the intrahost SEV/SEV-ES migration tests to use common ioctl()
>     wrappers.
> 
> V7
>   * https://lore.kernel.org/all/20231218161146.3554657-1-pgonda at google.com
>   * See https://github.com/sean-jc/linux/tree/x86/sev_selftests_for_peter.
>   * I kept is_pt_protected because without it the page tables are never
>   readable. Its used for the elf loading in kvm_vm_elf_load().
> 
> V6
>   * Updated SEV VM create function based on Seanjc's feedback and new
>     changes to VM creation functions.
>   * Removed pte_me_mask based on feedback.
>   * Fixed s_bit usage based on TDX
>   * Fixed bugs and took Ackerly's code for enc_region setup code.
> 
> V5
>   * Rebase onto seanjc@'s latest ucall pool series.
>   * More review changes based on seanjc:
>   ** use protected instead of encrypted outside of SEV specific files
>   ** Swap memcrypt struct for kvm_vm_arch arch specific struct
>   ** Make protected page table data agnostic of address bit stealing specifics
>      of SEV
>   ** Further clean up for SEV library to just vm_sev_create_one_vcpu()
>   * Due to large changes moved more authorships from mroth@ to pgonda at . Gave
>     originally-by tags to mroth@ as suggested by Seanjc for this.
> 
> V4
>   * Rebase ontop of seanjc@'s latest Ucall Pool series:
>     https://lore.kernel.org/linux-arm-kernel/20220825232522.3997340-8-seanjc at google.com/
>   * Fix up review comments from seanjc
>   * Switch authorship on 2 patches because of significant changes, added
>   * Michael as suggested-by or originally-by.
> 
> V3
>   * Addressed more of andrew.jones@ in ucall patches.
>   * Fix build in non-x86 archs.
> 
> V2
>   * Dropped RFC tag
>   * Correctly separated Sean's ucall patches into 2 as originally
>     intended.
>   * Addressed andrew.jones@ in ucall patches.
>   * Fixed ucall pool usage to work for other archs
> 
> V1
>   * https://lore.kernel.org/all/20220715192956.1873315-1-pgonda at google.com/
> 
> Ackerley Tng (1):
>    KVM: selftests: Add a macro to iterate over a sparsebit range
> 
> Michael Roth (2):
>    KVM: selftests: Make sparsebit structs const where appropriate
>    KVM: selftests: Add support for protected vm_vaddr_* allocations
> 
> Peter Gonda (5):
>    KVM: selftests: Add support for allocating/managing protected guest
>      memory
>    KVM: selftests: Explicitly ucall pool from shared memory
>    KVM: selftests: Allow tagging protected memory in guest page tables
>    KVM: selftests: Add library for creating and interacting with SEV
>      guests
>    KVM: selftests: Add a basic SEV smoke test
> 
> Sean Christopherson (2):
>    KVM: selftests: Extend VM creation's @shape to allow control of VM
>      subtype
>    KVM: selftests: Use the SEV library APIs in the intra-host migration
>      test
> 
>   tools/testing/selftests/kvm/Makefile          |   2 +
>   .../kvm/include/aarch64/kvm_util_arch.h       |   7 +
>   .../selftests/kvm/include/kvm_util_base.h     |  50 ++++++-
>   .../kvm/include/riscv/kvm_util_arch.h         |   7 +
>   .../kvm/include/s390x/kvm_util_arch.h         |   7 +
>   .../testing/selftests/kvm/include/sparsebit.h |  56 +++++---
>   .../kvm/include/x86_64/kvm_util_arch.h        |  23 ++++
>   .../selftests/kvm/include/x86_64/processor.h  |   8 ++
>   .../selftests/kvm/include/x86_64/sev.h        | 110 +++++++++++++++
>   tools/testing/selftests/kvm/lib/kvm_util.c    |  67 +++++++--
>   tools/testing/selftests/kvm/lib/sparsebit.c   |  48 +++----
>   .../testing/selftests/kvm/lib/ucall_common.c  |   3 +-
>   .../selftests/kvm/lib/x86_64/processor.c      |  32 ++++-
>   tools/testing/selftests/kvm/lib/x86_64/sev.c  | 128 ++++++++++++++++++
>   .../selftests/kvm/x86_64/sev_migrate_tests.c  |  67 +++------
>   .../selftests/kvm/x86_64/sev_smoke_test.c     |  58 ++++++++
>   16 files changed, 570 insertions(+), 103 deletions(-)
>   create mode 100644 tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
>   create mode 100644 tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
>   create mode 100644 tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
>   create mode 100644 tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
>   create mode 100644 tools/testing/selftests/kvm/include/x86_64/sev.h
>   create mode 100644 tools/testing/selftests/kvm/lib/x86_64/sev.c
>   create mode 100644 tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
> 
> 
> base-commit: 60eedcfceda9db46f1b333e5e1aa9359793f04fb

Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>

Tested including TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV)); in main() too.

Thanks,
Carlos


From catalin.marinas at arm.com  Wed Feb 21 10:24:00 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 21 Feb 2024 18:24:00 +0000
Subject: [PATCH v2 0/4] arm64/fp: Documentation cleanups and clarifications
In-Reply-To: <20240124-arm64-sve-sme-doc-v2-0-fe3964fb3c19@kernel.org>
References: <20240124-arm64-sve-sme-doc-v2-0-fe3964fb3c19@kernel.org>
Message-ID: <170853983553.1221430.7165446374929012835.b4-ty@arm.com>

On Wed, 24 Jan 2024 18:12:34 +0000, Mark Brown wrote:
> Edwin noticed some issues with the SVE and SME documentation which are
> corrected by this series.
> 
> 

Applied to arm64 (for-next/documentation), thanks!

[1/4] arm64/sve: Remove bitrotted comment about syscall behaviour
      https://git.kernel.org/arm64/c/b4725d3e4603
[2/4] arm64/sme: Fix cut'n'paste in ABI document
      https://git.kernel.org/arm64/c/ae35792764bc
[3/4] arm64/fp: Clarify effect of setting an unsupported system VL
      https://git.kernel.org/arm64/c/3fd97cf3234c
[4/4] arm64/sme: Remove spurious 'is' in SME documentation
      https://git.kernel.org/arm64/c/e47c18c3b25e

-- 
Catalin



From catalin.marinas at arm.com  Wed Feb 21 10:24:14 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 21 Feb 2024 18:24:14 +0000
Subject: [PATCH] kselftest/arm64: Test that ptrace takes effect in the target process
In-Reply-To: <20240122-arm64-test-ptrace-regs-v1-1-0897f822d73e@kernel.org>
References: <20240122-arm64-test-ptrace-regs-v1-1-0897f822d73e@kernel.org>
Message-ID: <170853984971.1222572.14523924916832010338.b4-ty@arm.com>

On Mon, 22 Jan 2024 21:05:03 +0000, Mark Brown wrote:
> While we have test coverage for the ptrace interface in our selftests
> the current programs have a number of gaps. The testing is done per
> regset so does not cover interactions and at no point do any of the
> tests actually run the traced processes meaning that there is no
> validation that anything we read or write corresponds to register values
> the process actually sees. Let's add a new program which attempts to cover
> these gaps.
> 
> [...]

Applied to arm64 (for-next/kselftest), thanks!

[1/1] kselftest/arm64: Test that ptrace takes effect in the target process
      https://git.kernel.org/arm64/c/c745b15c1f9c

-- 
Catalin



From catalin.marinas at arm.com  Wed Feb 21 10:24:34 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 21 Feb 2024 18:24:34 +0000
Subject: [PATCH V2] arm64/sysreg: Add register fields for ID_AA64DFR1_EL1
In-Reply-To: <20240220023203.3091229-1-anshuman.khandual@arm.com>
References: <20240220023203.3091229-1-anshuman.khandual@arm.com>
Message-ID: <170853986942.1224167.1095743361724562701.b4-ty@arm.com>

On Tue, 20 Feb 2024 08:02:03 +0530, Anshuman Khandual wrote:
> This adds register fields for ID_AA64DFR1_EL1 as per the definitions based
> on DDI0601 2023-12.
> 
> 

Applied to arm64 (for-next/sysreg), thanks!

[1/1] arm64/sysreg: Add register fields for ID_AA64DFR1_EL1
      https://git.kernel.org/arm64/c/fdd867fe9b32

-- 
Catalin



From catalin.marinas at arm.com  Wed Feb 21 10:24:44 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 21 Feb 2024 18:24:44 +0000
Subject: [PATCH V2] arm64/sysreg: Update ID_AA64DFR0_EL1 register
In-Reply-To: <20240220034829.3098373-1-anshuman.khandual@arm.com>
References: <20240220034829.3098373-1-anshuman.khandual@arm.com>
Message-ID: <170853986942.1224167.17230898618001754181.b4-ty@arm.com>

On Tue, 20 Feb 2024 09:18:29 +0530, Anshuman Khandual wrote:
> This updates ID_AA64DFR0_EL1.PMSVer and ID_AA64DFR0_EL1.DebugVer register
> fields as per the definitions based on DDI0601 2023-12.
> 
> 

Applied to arm64 (for-next/sysreg), thanks!

[1/1] arm64/sysreg: Update ID_AA64DFR0_EL1 register
      https://git.kernel.org/arm64/c/358fee291705

-- 
Catalin



From catalin.marinas at arm.com  Wed Feb 21 10:24:51 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 21 Feb 2024 18:24:51 +0000
Subject: [PATCH V2] arm64/sysreg: Update ID_DFR0_EL1 register fields
In-Reply-To: <20240220025343.3093955-1-anshuman.khandual@arm.com>
References: <20240220025343.3093955-1-anshuman.khandual@arm.com>
Message-ID: <170853986942.1224167.4579848259208066765.b4-ty@arm.com>

On Tue, 20 Feb 2024 08:23:43 +0530, Anshuman Khandual wrote:
> This updates ID_DFR0_EL1.PerfMon and ID_DFR0_EL1.CopDbg register fields as
> per the definitions based on DDI0601 2023-12.
> 
> 

Applied to arm64 (for-next/sysreg), thanks!

[1/1] arm64/sysreg: Update ID_DFR0_EL1 register fields
      https://git.kernel.org/arm64/c/7accfaad89d7

-- 
Catalin



From lkp at intel.com  Wed Feb 21 10:25:09 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 22 Feb 2024 02:25:09 +0800
Subject: [PATCH 1/4] mm/vmalloc: allow arch-specific vmalloc_node
 overrides
In-Reply-To: <20240220203256.31153-2-mbland@motorola.com>
References: <20240220203256.31153-2-mbland@motorola.com>
Message-ID: <202402220229.5xZWdZBK-lkp@intel.com>

Hi Maxwell,

kernel test robot noticed the following build errors:

[auto build test ERROR on b401b621758e46812da61fa58a67c3fd8d91de0d]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxwell-Bland/mm-vmalloc-allow-arch-specific-vmalloc_node-overrides/20240221-043458
base:   b401b621758e46812da61fa58a67c3fd8d91de0d
patch link:    https://lore.kernel.org/r/20240220203256.31153-2-mbland%40motorola.com
patch subject: [PATCH 1/4] mm/vmalloc: allow arch-specific vmalloc_node overrides
config: m68k-allnoconfig (https://download.01.org/0day-ci/archive/20240222/202402220229.5xZWdZBK-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240222/202402220229.5xZWdZBK-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402220229.5xZWdZBK-lkp at intel.com/

All errors (new ones prefixed by >>):

>> mm/nommu.c:160:7: error: conflicting types for '__vmalloc_node'; have 'void *(long unsigned int,  long unsigned int,  gfp_t,  int,  const void *)' {aka 'void *(long unsigned int,  long unsigned int,  unsigned int,  int,  const void *)'}
     160 | void *__vmalloc_node(unsigned long size, unsigned long align, gfp_t gfp_mask,
         |       ^~~~~~~~~~~~~~
   In file included from include/asm-generic/io.h:994,
                    from arch/m68k/include/asm/io.h:14,
                    from arch/m68k/include/asm/pgtable_no.h:14,
                    from arch/m68k/include/asm/pgtable.h:6,
                    from include/linux/pgtable.h:6,
                    from include/linux/mm.h:29,
                    from mm/nommu.c:20:
   include/linux/vmalloc.h:152:7: note: previous declaration of '__vmalloc_node' with type 'void *(long unsigned int,  long unsigned int,  gfp_t,  long unsigned int,  int,  const void *)' {aka 'void *(long unsigned int,  long unsigned int,  unsigned int,  long unsigned int,  int,  const void *)'}
     152 | void *__vmalloc_node(unsigned long size, unsigned long align, gfp_t gfp_mask,
         |       ^~~~~~~~~~~~~~


vim +160 mm/nommu.c

041de93ff86fc5 Christoph Hellwig 2020-06-01  159  
2b9059489c839e Christoph Hellwig 2020-06-01 @160  void *__vmalloc_node(unsigned long size, unsigned long align, gfp_t gfp_mask,
2b9059489c839e Christoph Hellwig 2020-06-01  161  		int node, const void *caller)
a7c3e901a46ff5 Michal Hocko      2017-05-08  162  {
2b9059489c839e Christoph Hellwig 2020-06-01  163  	return __vmalloc(size, gfp_mask);
a7c3e901a46ff5 Michal Hocko      2017-05-08  164  }
a7c3e901a46ff5 Michal Hocko      2017-05-08  165  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From dalias at libc.org  Wed Feb 21 10:30:55 2024
From: dalias at libc.org (dalias at libc.org)
Date: Wed, 21 Feb 2024 13:30:55 -0500
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>
References: <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
 <20240220235415.GP4163@brightrain.aerifal.cx>
 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx>
 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx>
 <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
 <20240221175717.GS4163@brightrain.aerifal.cx>
 <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>
Message-ID: <20240221183055.GT4163@brightrain.aerifal.cx>

On Wed, Feb 21, 2024 at 06:12:30PM +0000, Edgecombe, Rick P wrote:
> On Wed, 2024-02-21 at 12:57 -0500, dalias at libc.org wrote:
> > > This feels like it's getting complicated and I fear it may be an
> > > uphill
> > > struggle to get such code merged, at least for arm64.? My instinct
> > > is
> > > that it's going to be much more robust and generally tractable to
> > > let
> > > things run to some suitable synchronisation point and then disable
> > > there, but if we're going to do that then userspace can hopefully
> > > arrange to do the disabling itself through the standard disable
> > > interface anyway.? Presumably it'll want to notice things being
> > > disabled
> > > at some point anyway?? TBH that's been how all the prior proposals
> > > for
> > > process wide disable I've seen were done.
> > 
> > If it's possible to disable per-thread rather than per-process, some
> > things are easier. Disabling on account of using alt stacks only
> > needs
> > to be done on the threads using those stacks. However, for dlopen
> > purposes you need a way to disable shadow stack for the whole
> > process.
> > Initially this is only needed for the thread that called dlopen, but
> > it needs to have propagated to any thread that synchronizes with
> > completion of the call to dlopen by the time that synchronization
> > occurs, and since that synchronization can happen in lots of
> > different
> > ways that are purely userspace (thanks to futexes being userspace in
> > the uncontended case), I don't see any way to make it work without
> > extremely invasive, high-cost checks.
> 
> For glibc's use, we talked about a couple of options.
> 1. A mode to start suppressing the #UD's from the shadow stack
> instructions
> 2. A mode to start suppressing #CPs (the exception that happens when
> the shadow stack doesn't match). So the shadow stack instructions
> continue to operate normally, but if the shadow stack gets mismatched
> due to lack of support, the ret is emulated. It probably is safer (but
> still not perfect), but the performance penalty of emulating every RET
> after things get screwed up would be a significant down side. There
> also needs to be clean handling of shadow stack #PFs.
> 3. Per-thread locking that is used around all shadow stack operations
> that could be sensitive to disabling. This could be maybe exposed to
> apps in case they want to use shadow stack instructions manually. Then
> during dlopen() it waits until it can cleanly disable shadow stack for
> each thread. In each critical sections there are checks for whether
> shadow stack is still enabled.
> 
> 3 is the cleanest and safest I think, and it was thought it might not
> need kernel help, due to a scheme Florian had to direct signals to
> specific threads. It's my preference at this point.

The operations where the shadow stack has to be processed need to be
executable from async-signal context, so this imposes a requirement to
block all signals around the lock. This makes all longjmps a heavy,
multi-syscall operation rather than O(1) userspace operation. I do not
think this is an acceptable implementation, especially when there are
clearly superior alternatives without that cost or invasiveness.

> 1 and 2 are POCed here, if you are interested:
> https://github.com/rpedgeco/linux/commits/shstk_suppress_rfc/

I'm not clear why 2 (suppression of #CP) is desirable at all. If
shadow stack is being disabled, it should just be disabled, with
minimal fault handling to paper over any racing operations at the
moment it's disabled. Leaving it on with extreme slowness to make it
not actually do anything does not seem useful.

Is there some way folks have in mind to use option 2 to lazily disable
shadow stack once the first SS-incompatible code is executed, when
execution is then known not to be in the middle of a SS-critical
section, instead of doing it right away? I don't see how this could
work, since the SS-incompatible code could be running from a signal
handler that interrupted an SS-critical section.

> > If folks on the kernel side are not going to be amenable to doing the
> > things that are easy for the kernel to make it work without breaking
> > compatibility with existing interfaces, but that are impossible or
> > near-impossible for userspace to do, this seems like a dead-end. And
> > I
> > suspect an operation to "disable shadow stack, but without making
> > threads still in SS-critical sections crash" is going to be
> > necessary..
> 
> I think we have to work through all the alternative before we can
> accuse the kernel of not being amenable. Is there something that you
> would like to see out of this conversation that is not happening?

No, I was just interpreting "uphill battle". I really do not want to
engage in an uphill battle for the sake of making it practical to
support something that was never my goal to begin with. If I'm
misreading this, or if others are willing to put the effort into that
"battle", I'd be happy to be mistaken about "not amenable".

Rich


From broonie at kernel.org  Wed Feb 21 10:32:20 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 21 Feb 2024 18:32:20 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <20240221175717.GS4163@brightrain.aerifal.cx>
References: <4c7bdf8fde9cc45174f10b9221fa58ffb450b755.camel@intel.com>
 <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
 <20240220235415.GP4163@brightrain.aerifal.cx>
 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx>
 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx>
 <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
 <20240221175717.GS4163@brightrain.aerifal.cx>
Message-ID: <b41e39d1-29f9-4958-9728-6781e72230f8@sirena.org.uk>

On Wed, Feb 21, 2024 at 12:57:19PM -0500, dalias at libc.org wrote:
> On Wed, Feb 21, 2024 at 05:36:12PM +0000, Mark Brown wrote:

> > This feels like it's getting complicated and I fear it may be an uphill
> > struggle to get such code merged, at least for arm64.  My instinct is
> > that it's going to be much more robust and generally tractable to let
> > things run to some suitable synchronisation point and then disable
> > there, but if we're going to do that then userspace can hopefully
> > arrange to do the disabling itself through the standard disable
> > interface anyway.  Presumably it'll want to notice things being disabled
> > at some point anyway?  TBH that's been how all the prior proposals for
> > process wide disable I've seen were done.

> If it's possible to disable per-thread rather than per-process, some
> things are easier. Disabling on account of using alt stacks only needs

Both x86 and arm64 currently track shadow stack enablement per thread,
not per process, so it's not just possible to do per thread it's the
only thing we're currently implementing.  I think the same is true for
RISC-V but I didn't look as closely at that yet.

> to be done on the threads using those stacks. However, for dlopen
> purposes you need a way to disable shadow stack for the whole process.
> Initially this is only needed for the thread that called dlopen, but
> it needs to have propagated to any thread that synchronizes with
> completion of the call to dlopen by the time that synchronization
> occurs, and since that synchronization can happen in lots of different
> ways that are purely userspace (thanks to futexes being userspace in
> the uncontended case), I don't see any way to make it work without
> extremely invasive, high-cost checks.

Yeah, it's not particularly nice - any whole process disable is going to
have some nasty cases I think.  Rick's message about covered AFAIR the
discussion, there were also some proposals for more limited userspaces I
think.

> If folks on the kernel side are not going to be amenable to doing the
> things that are easy for the kernel to make it work without breaking
> compatibility with existing interfaces, but that are impossible or
> near-impossible for userspace to do, this seems like a dead-end. And I
> suspect an operation to "disable shadow stack, but without making
> threads still in SS-critical sections crash" is going to be
> necessary..

Could you be more specific as to the easy things that you're referencing
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/20240221/5af3b197/attachment-0001.sig>

From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:16 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:16 +0200
Subject: [rft, PATCH v1 00/14]  serial: Add a helper to parse device properties and more
Message-ID: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>

I have noticed that many drivers are using the subset of the common
properties and IRQ retrieval code. With the moving it to one place
we have got a common parser one for many.

Tested on Intel Apollo Lake with DesingWare 8250 UARTs.
The rest has been compile tested on x86_64 with clang.

Andy Shevchenko (14):
  serial: core: Move struct uart_port::quirks closer to possible values
  serial: core: Add UPIO_UNSET constant for unset port type
  serial: port: Introduce a common helper to read properties
  serial: 8250_aspeed_vuart: Switch to use uart_read_port_properties()
  serial: 8250_bcm2835aux: Switch to use uart_read_port_properties()
  serial: 8250_bcm7271: Switch to use uart_read_port_properties()
  serial: 8250_dw: Switch to use uart_read_port_properties()
  serial: 8250_ingenic: Switch to use uart_read_port_properties()
  serial: 8250_lpc18xx: Switch to use uart_read_port_properties()
  serial: 8250_of: Switch to use uart_read_port_properties()
  serial: 8250_omap: Switch to use uart_read_port_properties()
  serial: 8250_pxa: Switch to use uart_read_port_properties()
  serial: 8250_tegra: Switch to use uart_read_port_properties()
  serial: 8250_uniphier: Switch to use uart_read_port_properties()

 drivers/tty/serial/8250/8250_aspeed_vuart.c |  50 +++-----
 drivers/tty/serial/8250/8250_bcm2835aux.c   |  92 ++++++-------
 drivers/tty/serial/8250/8250_bcm7271.c      |  53 +++-----
 drivers/tty/serial/8250/8250_dw.c           |  67 ++++------
 drivers/tty/serial/8250/8250_ingenic.c      |  20 +--
 drivers/tty/serial/8250/8250_lpc18xx.c      |  20 ++-
 drivers/tty/serial/8250/8250_of.c           | 105 ++++-----------
 drivers/tty/serial/8250/8250_omap.c         |  29 ++---
 drivers/tty/serial/8250/8250_pxa.c          |  22 ++--
 drivers/tty/serial/8250/8250_tegra.c        |  26 ++--
 drivers/tty/serial/8250/8250_uniphier.c     |  17 +--
 drivers/tty/serial/serial_port.c            | 135 ++++++++++++++++++++
 include/linux/serial_core.h                 |  10 +-
 13 files changed, 313 insertions(+), 333 deletions(-)

-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:17 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:17 +0200
Subject: [PATCH v1 01/14] serial: core: Move struct uart_port::quirks closer to possible values
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-2-andriy.shevchenko@linux.intel.com>

Currently it's not crystal clear what UPIO_* and UPQ_* definitions
belong two. Reindent the code, so it will be easy to read and understand.
No functional changes intended.

Reviewed-by: Andi Shyti <andi.shyti at linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 include/linux/serial_core.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 55b1f3ba48ac..2d2ec99eca93 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -467,8 +467,8 @@ struct uart_port {
 	unsigned int		fifosize;		/* tx fifo size */
 	unsigned char		x_char;			/* xon/xoff char */
 	unsigned char		regshift;		/* reg offset shift */
+
 	unsigned char		iotype;			/* io access style */
-	unsigned char		quirks;			/* internal quirks */
 
 #define UPIO_PORT		(SERIAL_IO_PORT)	/* 8b I/O port access */
 #define UPIO_HUB6		(SERIAL_IO_HUB6)	/* Hub6 ISA card */
@@ -479,7 +479,9 @@ struct uart_port {
 #define UPIO_MEM32BE		(SERIAL_IO_MEM32BE)	/* 32b big endian */
 #define UPIO_MEM16		(SERIAL_IO_MEM16)	/* 16b little endian */
 
-	/* quirks must be updated while holding port mutex */
+	unsigned char		quirks;			/* internal quirks */
+
+	/* internal quirks must be updated while holding port mutex */
 #define UPQ_NO_TXEN_TEST	BIT(0)
 
 	unsigned int		read_status_mask;	/* driver specific */
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:18 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:18 +0200
Subject: [PATCH v1 02/14] serial: core: Add UPIO_UNSET constant for unset port type
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-3-andriy.shevchenko@linux.intel.com>

In some APIs we would like to assign the special value to iotype
and compare against it in another places. Introduce UPIO_UNSET
for this purpose.

Note, we can't use 0, because it's a valid value for IO port access.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 include/linux/serial_core.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 2d2ec99eca93..2b0526ae1fac 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -470,6 +470,7 @@ struct uart_port {
 
 	unsigned char		iotype;			/* io access style */
 
+#define UPIO_UNSET		((unsigned char)~0U)	/* UCHAR_MAX */
 #define UPIO_PORT		(SERIAL_IO_PORT)	/* 8b I/O port access */
 #define UPIO_HUB6		(SERIAL_IO_HUB6)	/* Hub6 ISA card */
 #define UPIO_MEM		(SERIAL_IO_MEM)		/* driver-specific */
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:24 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:24 +0200
Subject: [PATCH v1 08/14] serial: 8250_ingenic: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-9-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_ingenic.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c
index a12f737924c0..7603129f1c07 100644
--- a/drivers/tty/serial/8250/8250_ingenic.c
+++ b/drivers/tty/serial/8250/8250_ingenic.c
@@ -234,7 +234,7 @@ static int ingenic_uart_probe(struct platform_device *pdev)
 	struct ingenic_uart_data *data;
 	const struct ingenic_uart_config *cdata;
 	struct resource *regs;
-	int irq, err, line;
+	int err;
 
 	cdata = of_device_get_match_data(&pdev->dev);
 	if (!cdata) {
@@ -242,10 +242,6 @@ static int ingenic_uart_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!regs) {
 		dev_err(&pdev->dev, "no registers defined\n");
@@ -259,21 +255,19 @@ static int ingenic_uart_probe(struct platform_device *pdev)
 	spin_lock_init(&uart.port.lock);
 	uart.port.type = PORT_16550A;
 	uart.port.flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE;
-	uart.port.iotype = UPIO_MEM;
 	uart.port.mapbase = regs->start;
-	uart.port.regshift = 2;
 	uart.port.serial_out = ingenic_uart_serial_out;
 	uart.port.serial_in = ingenic_uart_serial_in;
-	uart.port.irq = irq;
 	uart.port.dev = &pdev->dev;
-	uart.port.fifosize = cdata->fifosize;
 	uart.tx_loadsz = cdata->tx_loadsz;
 	uart.capabilities = UART_CAP_FIFO | UART_CAP_RTOIE;
 
-	/* Check for a fixed line number */
-	line = of_alias_get_id(pdev->dev.of_node, "serial");
-	if (line >= 0)
-		uart.port.line = line;
+	err = uart_read_port_properties(&uart.port, true);
+	if (err)
+		return err;
+
+	uart.port.regshift = 2;
+	uart.port.fifosize = cdata->fifosize;
 
 	uart.port.membase = devm_ioremap(&pdev->dev, regs->start,
 					 resource_size(regs));
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:21 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:21 +0200
Subject: [PATCH v1 05/14] serial: 8250_bcm2835aux: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-6-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_bcm2835aux.c | 92 +++++++++++------------
 1 file changed, 42 insertions(+), 50 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c
index beac6b340ace..69c3c5ca77f7 100644
--- a/drivers/tty/serial/8250/8250_bcm2835aux.c
+++ b/drivers/tty/serial/8250/8250_bcm2835aux.c
@@ -45,10 +45,6 @@ struct bcm2835aux_data {
 	u32 cntl;
 };
 
-struct bcm2835_aux_serial_driver_data {
-	resource_size_t offset;
-};
-
 static void bcm2835aux_rs485_start_tx(struct uart_8250_port *up)
 {
 	if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) {
@@ -85,10 +81,9 @@ static void bcm2835aux_rs485_stop_tx(struct uart_8250_port *up)
 
 static int bcm2835aux_serial_probe(struct platform_device *pdev)
 {
-	const struct bcm2835_aux_serial_driver_data *bcm_data;
+	const struct software_node *bcm2835_swnode;
 	struct uart_8250_port up = { };
 	struct bcm2835aux_data *data;
-	resource_size_t offset = 0;
 	struct resource *res;
 	unsigned int uartclk;
 	int ret;
@@ -101,12 +96,8 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev)
 	/* initialize data */
 	up.capabilities = UART_CAP_FIFO | UART_CAP_MINI;
 	up.port.dev = &pdev->dev;
-	up.port.regshift = 2;
 	up.port.type = PORT_16550;
-	up.port.iotype = UPIO_MEM;
-	up.port.fifosize = 8;
-	up.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE |
-			UPF_SKIP_TEST | UPF_IOREMAP;
+	up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_SKIP_TEST | UPF_IOREMAP;
 	up.port.rs485_config = serial8250_em485_config;
 	up.port.rs485_supported = serial8250_em485_supported;
 	up.rs485_start_tx = bcm2835aux_rs485_start_tx;
@@ -122,12 +113,6 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev)
 	if (IS_ERR(data->clk))
 		return dev_err_probe(&pdev->dev, PTR_ERR(data->clk), "could not get clk\n");
 
-	/* get the interrupt */
-	ret = platform_get_irq(pdev, 0);
-	if (ret < 0)
-		return ret;
-	up.port.irq = ret;
-
 	/* map the main registers */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
@@ -135,52 +120,40 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	bcm_data = device_get_match_data(&pdev->dev);
+	up.port.mapbase = res->start;
+	up.port.mapsize = resource_size(res);
 
-	/* Some UEFI implementations (e.g. tianocore/edk2 for the Raspberry Pi)
-	 * describe the miniuart with a base address that encompasses the auxiliary
-	 * registers shared between the miniuart and spi.
-	 *
-	 * This is due to historical reasons, see discussion here :
-	 * https://edk2.groups.io/g/devel/topic/87501357#84349
-	 *
-	 * We need to add the offset between the miniuart and auxiliary
-	 * registers to get the real miniuart base address.
-	 */
-	if (bcm_data)
-		offset = bcm_data->offset;
+	bcm2835_swnode = device_get_match_data(&pdev->dev);
+	if (bcm2835_swnode) {
+		ret = device_add_software_node(&pdev->dev, bcm2835_swnode);
+		if (ret)
+			return ret;
+	}
 
-	up.port.mapbase = res->start + offset;
-	up.port.mapsize = resource_size(res) - offset;
+	ret = uart_read_port_properties(&up.port, true);
+	if (ret)
+		goto rm_swnode;
 
-	/* Check for a fixed line number */
-	ret = of_alias_get_id(pdev->dev.of_node, "serial");
-	if (ret >= 0)
-		up.port.line = ret;
+	up.port.regshift = 2;
+	up.port.fifosize = 8;
 
 	/* enable the clock as a last step */
 	ret = clk_prepare_enable(data->clk);
 	if (ret) {
-		dev_err(&pdev->dev, "unable to enable uart clock - %d\n",
-			ret);
-		return ret;
+		dev_err_probe(&pdev->dev, ret, "unable to enable uart clock\n");
+		goto rm_swnode;
 	}
 
 	uartclk = clk_get_rate(data->clk);
-	if (!uartclk) {
-		ret = device_property_read_u32(&pdev->dev, "clock-frequency", &uartclk);
-		if (ret) {
-			dev_err_probe(&pdev->dev, ret, "could not get clk rate\n");
-			goto dis_clk;
-		}
-	}
+	if (uartclk)
+		up.port.uartclk = uartclk;
 
 	/* the HW-clock divider for bcm2835aux is 8,
 	 * but 8250 expects a divider of 16,
 	 * so we have to multiply the actual clock by 2
 	 * to get identical baudrates.
 	 */
-	up.port.uartclk = uartclk * 2;
+	up.port.uartclk *= 2;
 
 	/* register the port */
 	ret = serial8250_register_8250_port(&up);
@@ -194,6 +167,8 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev)
 
 dis_clk:
 	clk_disable_unprepare(data->clk);
+rm_swnode:
+	device_remove_software_node(&pdev->dev);
 	return ret;
 }
 
@@ -203,10 +178,27 @@ static void bcm2835aux_serial_remove(struct platform_device *pdev)
 
 	serial8250_unregister_port(data->line);
 	clk_disable_unprepare(data->clk);
+	device_remove_software_node(&pdev->dev);
 }
 
-static const struct bcm2835_aux_serial_driver_data bcm2835_acpi_data = {
-	.offset = 0x40,
+/*
+ * Some UEFI implementations (e.g. tianocore/edk2 for the Raspberry Pi)
+ * describe the miniuart with a base address that encompasses the auxiliary
+ * registers shared between the miniuart and spi.
+ *
+ * This is due to historical reasons, see discussion here:
+ * https://edk2.groups.io/g/devel/topic/87501357#84349
+ *
+ * We need to add the offset between the miniuart and auxiliary registers
+ * to get the real miniuart base address.
+ */
+static const struct property_entry bcm2835_acpi_properties[] = {
+	PROPERTY_ENTRY_U32("reg-offset", 0x40),
+	{ }
+};
+
+static const struct software_node bcm2835_acpi_node = {
+	.properties = bcm2835_acpi_properties,
 };
 
 static const struct of_device_id bcm2835aux_serial_match[] = {
@@ -216,7 +208,7 @@ static const struct of_device_id bcm2835aux_serial_match[] = {
 MODULE_DEVICE_TABLE(of, bcm2835aux_serial_match);
 
 static const struct acpi_device_id bcm2835aux_serial_acpi_match[] = {
-	{ "BCM2836", (kernel_ulong_t)&bcm2835_acpi_data },
+	{ "BCM2836", (kernel_ulong_t)&bcm2835_acpi_node },
 	{ }
 };
 MODULE_DEVICE_TABLE(acpi, bcm2835aux_serial_acpi_match);
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:20 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:20 +0200
Subject: [PATCH v1 04/14] serial: 8250_aspeed_vuart: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-5-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Reviewed-by: Andi Shyti <andi.shyti at linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_aspeed_vuart.c | 50 +++++++--------------
 1 file changed, 15 insertions(+), 35 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c
index 8c2aaf7af7b7..2a4bc39b11af 100644
--- a/drivers/tty/serial/8250/8250_aspeed_vuart.c
+++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c
@@ -419,8 +419,8 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
 	struct aspeed_vuart *vuart;
 	struct device_node *np;
 	struct resource *res;
-	u32 clk, prop, sirq[2];
 	int rc, sirq_polarity;
+	u32 prop, sirq[2];
 	struct clk *vclk;
 
 	np = pdev->dev.of_node;
@@ -447,53 +447,35 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
 	port.port.status = UPSTAT_SYNC_FIFO;
 	port.port.dev = &pdev->dev;
 	port.port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE);
+	port.port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_FIXED_PORT | UPF_FIXED_TYPE |
+			  UPF_NO_THRE_TEST;
 	port.bugs |= UART_BUG_TXRACE;
 
 	rc = sysfs_create_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
 	if (rc < 0)
 		return rc;
 
-	if (of_property_read_u32(np, "clock-frequency", &clk)) {
+	rc = uart_read_port_properties(&port.port, true);
+	if (rc)
+		goto err_sysfs_remove;
+
+	/* Get clk rate through clk driver if present */
+	if (!port.port.uartclk) {
 		vclk = devm_clk_get_enabled(dev, NULL);
 		if (IS_ERR(vclk)) {
 			rc = dev_err_probe(dev, PTR_ERR(vclk), "clk or clock-frequency not defined\n");
 			goto err_sysfs_remove;
 		}
 
-		clk = clk_get_rate(vclk);
+		port.port.uartclk = clk_get_rate(vclk);
 	}
 
 	/* If current-speed was set, then try not to change it. */
 	if (of_property_read_u32(np, "current-speed", &prop) == 0)
-		port.port.custom_divisor = clk / (16 * prop);
+		port.port.custom_divisor = port.port.uartclk / (16 * prop);
 
-	/* Check for shifted address mapping */
-	if (of_property_read_u32(np, "reg-offset", &prop) == 0)
-		port.port.mapbase += prop;
-
-	/* Check for registers offset within the devices address range */
-	if (of_property_read_u32(np, "reg-shift", &prop) == 0)
-		port.port.regshift = prop;
-
-	/* Check for fifo size */
-	if (of_property_read_u32(np, "fifo-size", &prop) == 0)
-		port.port.fifosize = prop;
-
-	/* Check for a fixed line number */
-	rc = of_alias_get_id(np, "serial");
-	if (rc >= 0)
-		port.port.line = rc;
-
-	port.port.irq = irq_of_parse_and_map(np, 0);
 	port.port.handle_irq = aspeed_vuart_handle_irq;
-	port.port.iotype = UPIO_MEM;
 	port.port.type = PORT_ASPEED_VUART;
-	port.port.uartclk = clk;
-	port.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
-		| UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_NO_THRE_TEST;
-
-	if (of_property_read_bool(np, "no-loopback-test"))
-		port.port.flags |= UPF_SKIP_TEST;
 
 	if (port.port.fifosize)
 		port.capabilities = UART_CAP_FIFO;
@@ -503,7 +485,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
 
 	rc = serial8250_register_8250_port(&port);
 	if (rc < 0)
-		goto err_clk_disable;
+		goto err_sysfs_remove;
 
 	vuart->line = rc;
 	vuart->port = serial8250_get_port(vuart->line);
@@ -529,7 +511,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
 	rc = aspeed_vuart_set_lpc_address(vuart, prop);
 	if (rc < 0) {
 		dev_err_probe(dev, rc, "invalid value in aspeed,lpc-io-reg property\n");
-		goto err_clk_disable;
+		goto err_sysfs_remove;
 	}
 
 	rc = of_property_read_u32_array(np, "aspeed,lpc-interrupts", sirq, 2);
@@ -541,14 +523,14 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
 	rc = aspeed_vuart_set_sirq(vuart, sirq[0]);
 	if (rc < 0) {
 		dev_err_probe(dev, rc, "invalid sirq number in aspeed,lpc-interrupts property\n");
-		goto err_clk_disable;
+		goto err_sysfs_remove;
 	}
 
 	sirq_polarity = aspeed_vuart_map_irq_polarity(sirq[1]);
 	if (sirq_polarity < 0) {
 		rc = dev_err_probe(dev, sirq_polarity,
 				   "invalid sirq polarity in aspeed,lpc-interrupts property\n");
-		goto err_clk_disable;
+		goto err_sysfs_remove;
 	}
 
 	aspeed_vuart_set_sirq_polarity(vuart, sirq_polarity);
@@ -559,8 +541,6 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
 
 	return 0;
 
-err_clk_disable:
-	irq_dispose_mapping(port.port.irq);
 err_sysfs_remove:
 	sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
 	return rc;
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:22 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:22 +0200
Subject: [PATCH v1 06/14] serial: 8250_bcm7271: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-7-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_bcm7271.c | 53 +++++++++-----------------
 1 file changed, 18 insertions(+), 35 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c
index 1532fa2e8ec4..5a25e78857f7 100644
--- a/drivers/tty/serial/8250/8250_bcm7271.c
+++ b/drivers/tty/serial/8250/8250_bcm7271.c
@@ -942,10 +942,8 @@ static int brcmuart_probe(struct platform_device *pdev)
 	struct brcmuart_priv *priv;
 	struct clk *baud_mux_clk;
 	struct uart_8250_port up;
-	int irq;
 	void __iomem *membase = NULL;
 	resource_size_t mapbase = 0;
-	u32 clk_rate = 0;
 	int ret;
 	int x;
 	int dma_irq;
@@ -953,9 +951,6 @@ static int brcmuart_probe(struct platform_device *pdev)
 		"uart", "dma_rx", "dma_tx", "dma_intr2", "dma_arb"
 	};
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
 	priv = devm_kzalloc(dev, sizeof(struct brcmuart_priv),
 			GFP_KERNEL);
 	if (!priv)
@@ -1011,7 +1006,23 @@ static int brcmuart_probe(struct platform_device *pdev)
 		}
 	}
 
-	of_property_read_u32(np, "clock-frequency", &clk_rate);
+	dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not ");
+
+	memset(&up, 0, sizeof(up));
+	up.port.type = PORT_BCM7271;
+	up.port.dev = dev;
+	up.port.mapbase = mapbase;
+	up.port.membase = membase;
+	up.port.handle_irq = brcmuart_handle_irq;
+	up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_FIXED_TYPE;
+	up.port.private_data = priv;
+
+	ret = uart_read_port_properties(&up.port, true);
+	if (ret)
+		goto release_dma;
+
+	up.port.regshift = 2;
+	up.port.iotype = device_is_big_endian(dev) ? UPIO_MEM32BE : UPIO_MEM32;
 
 	/* See if a Baud clock has been specified */
 	baud_mux_clk = devm_clk_get_optional_enabled(dev, "sw_baud");
@@ -1023,39 +1034,11 @@ static int brcmuart_probe(struct platform_device *pdev)
 
 		priv->baud_mux_clk = baud_mux_clk;
 		init_real_clk_rates(dev, priv);
-		clk_rate = priv->default_mux_rate;
+		up.port.uartclk = priv->default_mux_rate;
 	} else {
 		dev_dbg(dev, "BAUD MUX clock not specified\n");
 	}
 
-	if (clk_rate == 0) {
-		ret = dev_err_probe(dev, -EINVAL, "clock-frequency or clk not defined\n");
-		goto release_dma;
-	}
-
-	dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not ");
-
-	memset(&up, 0, sizeof(up));
-	up.port.type = PORT_BCM7271;
-	up.port.uartclk = clk_rate;
-	up.port.dev = dev;
-	up.port.mapbase = mapbase;
-	up.port.membase = membase;
-	up.port.irq = irq;
-	up.port.handle_irq = brcmuart_handle_irq;
-	up.port.regshift = 2;
-	up.port.iotype = of_device_is_big_endian(np) ?
-		UPIO_MEM32BE : UPIO_MEM32;
-	up.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
-		| UPF_FIXED_PORT | UPF_FIXED_TYPE;
-	up.port.dev = dev;
-	up.port.private_data = priv;
-
-	/* Check for a fixed line number */
-	ret = of_alias_get_id(np, "serial");
-	if (ret >= 0)
-		up.port.line = ret;
-
 	/* setup HR timer */
 	hrtimer_init(&priv->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
 	priv->hrt.function = brcmuart_hrtimer_func;
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:28 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:28 +0200
Subject: [PATCH v1 12/14] serial: 8250_pxa: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-13-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_pxa.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c
index 77686da42ce8..0c9140b93414 100644
--- a/drivers/tty/serial/8250/8250_pxa.c
+++ b/drivers/tty/serial/8250/8250_pxa.c
@@ -92,11 +92,7 @@ static int serial_pxa_probe(struct platform_device *pdev)
 	struct uart_8250_port uart = {};
 	struct pxa8250_data *data;
 	struct resource *mmres;
-	int irq, ret;
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
+	int ret;
 
 	mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!mmres)
@@ -114,21 +110,21 @@ static int serial_pxa_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = of_alias_get_id(pdev->dev.of_node, "serial");
-	if (ret >= 0)
-		uart.port.line = ret;
-
 	uart.port.type = PORT_XSCALE;
-	uart.port.iotype = UPIO_MEM32;
 	uart.port.mapbase = mmres->start;
-	uart.port.regshift = 2;
-	uart.port.irq = irq;
-	uart.port.fifosize = 64;
 	uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST | UPF_FIXED_TYPE;
 	uart.port.dev = &pdev->dev;
 	uart.port.uartclk = clk_get_rate(data->clk);
 	uart.port.pm = serial_pxa_pm;
 	uart.port.private_data = data;
+
+	ret = uart_read_port_properties(&uart.port, true);
+	if (ret)
+		return ret;
+
+	uart.port.iotype = UPIO_MEM32;
+	uart.port.regshift = 2;
+	uart.port.fifosize = 64;
 	uart.dl_write = serial_pxa_dl_write;
 
 	ret = serial8250_register_8250_port(&uart);
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:23 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:23 +0200
Subject: [PATCH v1 07/14] serial: 8250_dw: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-8-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Reviewed-by: Andi Shyti <andi.shyti at linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_dw.c | 67 +++++++++++++------------------
 1 file changed, 27 insertions(+), 40 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 2d1f350a4bea..a1825e83231f 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -17,7 +17,6 @@
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/notifier.h>
-#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/property.h>
@@ -449,12 +448,7 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
 
 	if (np) {
 		unsigned int quirks = data->pdata->quirks;
-		int id;
 
-		/* get index of serial line, if found in DT aliases */
-		id = of_alias_get_id(np, "serial");
-		if (id >= 0)
-			p->line = id;
 #ifdef CONFIG_64BIT
 		if (quirks & DW_UART_QUIRK_OCTEON) {
 			p->serial_in = dw8250_serial_inq;
@@ -465,12 +459,6 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
 		}
 #endif
 
-		if (of_device_is_big_endian(np)) {
-			p->iotype = UPIO_MEM32BE;
-			p->serial_in = dw8250_serial_in32be;
-			p->serial_out = dw8250_serial_out32be;
-		}
-
 		if (quirks & DW_UART_QUIRK_ARMADA_38X)
 			p->serial_out = dw8250_serial_out38x;
 		if (quirks & DW_UART_QUIRK_SKIP_SET_RATE)
@@ -510,39 +498,21 @@ static int dw8250_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct dw8250_data *data;
 	struct resource *regs;
-	int irq;
 	int err;
-	u32 val;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!regs)
 		return dev_err_probe(dev, -EINVAL, "no registers defined\n");
 
-	irq = platform_get_irq_optional(pdev, 0);
-	/* no interrupt -> fall back to polling */
-	if (irq == -ENXIO)
-		irq = 0;
-	if (irq < 0)
-		return irq;
-
 	spin_lock_init(&p->lock);
-	p->mapbase	= regs->start;
-	p->irq		= irq;
 	p->handle_irq	= dw8250_handle_irq;
 	p->pm		= dw8250_do_pm;
 	p->type		= PORT_8250;
-	p->flags	= UPF_SHARE_IRQ | UPF_FIXED_PORT;
+	p->flags	= UPF_FIXED_PORT;
 	p->dev		= dev;
-	p->iotype	= UPIO_MEM;
-	p->serial_in	= dw8250_serial_in;
-	p->serial_out	= dw8250_serial_out;
 	p->set_ldisc	= dw8250_set_ldisc;
 	p->set_termios	= dw8250_set_termios;
 
-	p->membase = devm_ioremap(dev, regs->start, resource_size(regs));
-	if (!p->membase)
-		return -ENOMEM;
-
 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
@@ -554,15 +524,35 @@ static int dw8250_probe(struct platform_device *pdev)
 	data->uart_16550_compatible = device_property_read_bool(dev,
 						"snps,uart-16550-compatible");
 
-	err = device_property_read_u32(dev, "reg-shift", &val);
-	if (!err)
-		p->regshift = val;
+	p->mapbase = regs->start;
+	p->mapsize = resource_size(regs);
 
-	err = device_property_read_u32(dev, "reg-io-width", &val);
-	if (!err && val == 4) {
-		p->iotype = UPIO_MEM32;
+	p->membase = devm_ioremap(dev, p->mapbase, p->mapsize);
+	if (!p->membase)
+		return -ENOMEM;
+
+	err = uart_read_port_properties(p, true);
+	/* no interrupt -> fall back to polling */
+	if (err == -ENXIO)
+		err = 0;
+	if (err)
+		return err;
+
+	switch (p->iotype) {
+	case UPIO_MEM:
+		p->serial_in = dw8250_serial_in;
+		p->serial_out = dw8250_serial_out;
+		break;
+	case UPIO_MEM32:
 		p->serial_in = dw8250_serial_in32;
 		p->serial_out = dw8250_serial_out32;
+		break;
+	case UPIO_MEM32BE:
+		p->serial_in = dw8250_serial_in32be;
+		p->serial_out = dw8250_serial_out32be;
+		break;
+	default:
+		return -ENODEV;
 	}
 
 	if (device_property_read_bool(dev, "dcd-override")) {
@@ -589,9 +579,6 @@ static int dw8250_probe(struct platform_device *pdev)
 		data->msr_mask_off |= UART_MSR_TERI;
 	}
 
-	/* Always ask for fixed clock rate from a property. */
-	device_property_read_u32(dev, "clock-frequency", &p->uartclk);
-
 	/* If there is separate baudclk, get the rate from it. */
 	data->clk = devm_clk_get_optional_enabled(dev, "baudclk");
 	if (data->clk == NULL)
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:26 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:26 +0200
Subject: [PATCH v1 10/14] serial: 8250_of: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-11-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Reviewed-by: Andi Shyti <andi.shyti at linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_of.c | 105 +++++++-----------------------
 1 file changed, 22 insertions(+), 83 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
index 9dcc17e33269..1a699ce2e812 100644
--- a/drivers/tty/serial/8250/8250_of.c
+++ b/drivers/tty/serial/8250/8250_of.c
@@ -69,37 +69,22 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
 	struct device *dev = &ofdev->dev;
 	struct device_node *np = dev->of_node;
 	struct uart_port *port = &up->port;
-	u32 clk, spd, prop;
-	int ret, irq;
+	u32 spd;
+	int ret;
 
 	memset(port, 0, sizeof *port);
 
 	pm_runtime_enable(&ofdev->dev);
 	pm_runtime_get_sync(&ofdev->dev);
 
-	if (of_property_read_u32(np, "clock-frequency", &clk)) {
-
-		/* Get clk rate through clk driver if present */
-		info->clk = devm_clk_get_enabled(dev, NULL);
-		if (IS_ERR(info->clk)) {
-			ret = dev_err_probe(dev, PTR_ERR(info->clk), "failed to get clock\n");
-			goto err_pmruntime;
-		}
-
-		clk = clk_get_rate(info->clk);
-	}
-	/* If current-speed was set, then try not to change it. */
-	if (of_property_read_u32(np, "current-speed", &spd) == 0)
-		port->custom_divisor = clk / (16 * spd);
-
 	ret = of_address_to_resource(np, 0, &resource);
 	if (ret) {
 		dev_err_probe(dev, ret, "invalid address\n");
 		goto err_pmruntime;
 	}
 
-	port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT |
-				  UPF_FIXED_TYPE;
+	port->dev = &ofdev->dev;
+	port->flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_FIXED_TYPE;
 	spin_lock_init(&port->lock);
 
 	if (resource_type(&resource) == IORESOURCE_IO) {
@@ -108,70 +93,31 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
 	} else {
 		port->mapbase = resource.start;
 		port->mapsize = resource_size(&resource);
-
-		/* Check for shifted address mapping */
-		if (of_property_read_u32(np, "reg-offset", &prop) == 0) {
-			if (prop >= port->mapsize) {
-				ret = dev_err_probe(dev, -EINVAL, "reg-offset %u exceeds region size %pa\n",
-						    prop, &port->mapsize);
-				goto err_pmruntime;
-			}
-
-			port->mapbase += prop;
-			port->mapsize -= prop;
-		}
-
-		port->iotype = UPIO_MEM;
-		if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
-			switch (prop) {
-			case 1:
-				port->iotype = UPIO_MEM;
-				break;
-			case 2:
-				port->iotype = UPIO_MEM16;
-				break;
-			case 4:
-				port->iotype = of_device_is_big_endian(np) ?
-					       UPIO_MEM32BE : UPIO_MEM32;
-				break;
-			default:
-				ret = dev_err_probe(dev, -EINVAL, "unsupported reg-io-width (%u)\n",
-						    prop);
-				goto err_pmruntime;
-			}
-		}
 		port->flags |= UPF_IOREMAP;
 	}
 
+	ret = uart_read_port_properties(port, false);
+	if (ret)
+		goto err_pmruntime;
+
+	/* Get clk rate through clk driver if present */
+	if (!port->uartclk) {
+		info->clk = devm_clk_get_enabled(dev, NULL);
+		if (IS_ERR(info->clk)) {
+			ret = dev_err_probe(dev, PTR_ERR(info->clk), "failed to get clock\n");
+			goto err_pmruntime;
+		}
+
+		port->uartclk = clk_get_rate(info->clk);
+	}
+	/* If current-speed was set, then try not to change it. */
+	if (of_property_read_u32(np, "current-speed", &spd) == 0)
+		port->custom_divisor = port->uartclk / (16 * spd);
+
 	/* Compatibility with the deprecated pxa driver and 8250_pxa drivers. */
 	if (of_device_is_compatible(np, "mrvl,mmp-uart"))
 		port->regshift = 2;
 
-	/* Check for registers offset within the devices address range */
-	if (of_property_read_u32(np, "reg-shift", &prop) == 0)
-		port->regshift = prop;
-
-	/* Check for fifo size */
-	if (of_property_read_u32(np, "fifo-size", &prop) == 0)
-		port->fifosize = prop;
-
-	/* Check for a fixed line number */
-	ret = of_alias_get_id(np, "serial");
-	if (ret >= 0)
-		port->line = ret;
-
-	irq = of_irq_get(np, 0);
-	if (irq < 0) {
-		if (irq == -EPROBE_DEFER) {
-			ret = -EPROBE_DEFER;
-			goto err_pmruntime;
-		}
-		/* IRQ support not mandatory */
-		irq = 0;
-	}
-
-	port->irq = irq;
-
 	info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL);
 	if (IS_ERR(info->rst)) {
 		ret = PTR_ERR(info->rst);
@@ -183,12 +129,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
 		goto err_pmruntime;
 
 	port->type = type;
-	port->uartclk = clk;
-
-	if (of_property_read_bool(np, "no-loopback-test"))
-		port->flags |= UPF_SKIP_TEST;
-
-	port->dev = &ofdev->dev;
 	port->rs485_config = serial8250_em485_config;
 	port->rs485_supported = serial8250_em485_supported;
 	up->rs485_start_tx = serial8250_em485_start_tx;
@@ -280,7 +220,6 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
 	platform_set_drvdata(ofdev, info);
 	return 0;
 err_dispose:
-	irq_dispose_mapping(port8250.port.irq);
 	pm_runtime_put_sync(&ofdev->dev);
 	pm_runtime_disable(&ofdev->dev);
 err_free:
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:19 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:19 +0200
Subject: [PATCH v1 03/14] serial: port: Introduce a common helper to read properties
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-4-andriy.shevchenko@linux.intel.com>

Several serial drivers want to read the same or similar set of
the port properties. Make a common helper for them.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/serial_port.c | 135 +++++++++++++++++++++++++++++++
 include/linux/serial_core.h      |   1 +
 2 files changed, 136 insertions(+)

diff --git a/drivers/tty/serial/serial_port.c b/drivers/tty/serial/serial_port.c
index 88975a4df306..111e1f25fbc6 100644
--- a/drivers/tty/serial/serial_port.c
+++ b/drivers/tty/serial/serial_port.c
@@ -8,7 +8,10 @@
 
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/property.h>
 #include <linux/serial_core.h>
 #include <linux/spinlock.h>
 
@@ -82,6 +85,138 @@ void uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
 }
 EXPORT_SYMBOL(uart_remove_one_port);
 
+/**
+ * uart_read_port_properties - read firmware properties of the given UART port
+ * @port: corresponding port
+ * @use_defaults: apply defaults or validate the values
+ *
+ * The following device properties are supported:
+ *   - clock-frequency (optional)
+ *   - fifo-size (optional)
+ *   - no-loopback-test (optional)
+ *   - reg-shift (defaults may apply)
+ *   - reg-offset (value may be validated)
+ *   - reg-io-width (defaults may apply or value may be validated)
+ *   - interrupts (OF only)
+ *   - serial [alias ID] (OF only)
+ *
+ * If the port->dev is of struct platform_device type the interrupt line
+ * will be retrieved via platform_get_irq() call against that device.
+ * Otherwise it will be assigned by fwnode_irq_get() call. In both cases
+ * the index 0 of the resource is used.
+ *
+ * The caller is responsible to initialize the following fields of the @port
+ *   ->dev (must be valid)
+ *   ->flags
+ *   ->iotype (if @use_defaults is false)
+ *   ->mapbase
+ *   ->mapsize
+ *   ->regshift (if @use_defaults is false)
+ * before calling this function. Alternatively the above mentioned fields
+ * may be zeroed, in such case the only ones, that have associated properties
+ * found, will be set to the respective values.
+ *
+ * When @use_defaults is true and the respective property is not found
+ * the following values will be applied:
+ *   ->iotype = UPIO_MEM
+ *   ->regshift = 0
+ * In this case IRQ must be provided, otherwise an error will be returned.
+ *
+ * The ->irq, ->mapbase, ->mapsize are always altered if no error happened.
+ *
+ * When @use_defaults is false and the respective property is found
+ * the following values will be validated:
+ *   - reg-io-width (->iotype)
+ *   - reg-offset (->mapsize against ->mapbase)
+ *
+ * Returns: 0 on success or negative errno on failure
+ */
+int uart_read_port_properties(struct uart_port *port, bool use_defaults)
+{
+	struct device *dev = port->dev;
+	u32 value;
+	int ret;
+
+	/* Read optional UART functional clock frequency */
+	device_property_read_u32(dev, "clock-frequency", &port->uartclk);
+
+	/* Read the registers alignment (default: 8-bit) */
+	ret = device_property_read_u32(dev, "reg-shift", &value);
+	if (ret)
+		port->regshift = use_defaults ? 0 : port->regshift;
+	else
+		port->regshift = value;
+
+	/* Read the registers I/O access type (default: MMIO 8-bit) */
+	ret = device_property_read_u32(dev, "reg-io-width", &value);
+	if (ret) {
+		port->iotype = use_defaults ? UPIO_MEM : port->iotype;
+	} else {
+		switch (value) {
+		case 1:
+			port->iotype = UPIO_MEM;
+			break;
+		case 2:
+			port->iotype = UPIO_MEM16;
+			break;
+		case 4:
+			port->iotype = device_is_big_endian(dev) ? UPIO_MEM32BE : UPIO_MEM32;
+			break;
+		default:
+			if (!use_defaults) {
+				dev_err(dev, "Unsupported reg-io-width (%u)\n", value);
+				return -EINVAL;
+			}
+			port->iotype = UPIO_UNSET;
+			break;
+		}
+	}
+
+	/* Read the address mapping base offset (default: no offset) */
+	ret = device_property_read_u32(dev, "reg-offset", &value);
+	if (ret)
+		value = 0;
+
+	/* Check for shifted address mapping overflow */
+	if (!use_defaults && port->mapsize < value) {
+		dev_err(dev, "reg-offset %u exceeds region size %pa\n", value, &port->mapsize);
+		return -EINVAL;
+	}
+
+	port->mapbase += value;
+	port->mapsize -= value;
+
+	/* Read optional FIFO size */
+	device_property_read_u32(dev, "fifo-size", &port->fifosize);
+
+	if (device_property_read_bool(dev, "no-loopback-test"))
+		port->flags |= UPF_SKIP_TEST;
+
+	/* Get index of serial line, if found in DT aliases */
+	ret = of_alias_get_id(dev_of_node(dev), "serial");
+	if (ret >= 0)
+		port->line = ret;
+
+	if (dev_is_platform(dev))
+		ret = platform_get_irq(to_platform_device(dev), 0);
+	else
+		ret = fwnode_irq_get(dev_fwnode(dev), 0);
+	if (ret == -EPROBE_DEFER)
+		return ret;
+	if (ret > 0)
+		port->irq = ret;
+	else if (use_defaults)
+		/* By default IRQ support is mandatory */
+		return ret;
+	else
+		port->irq = 0;
+
+	port->flags |= UPF_SHARE_IRQ;
+
+	return 0;
+}
+EXPORT_SYMBOL(uart_read_port_properties);
+
 static struct device_driver serial_port_driver = {
 	.name = "port",
 	.suppress_bind_attrs = true,
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 2b0526ae1fac..c93d775fc8a8 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -962,6 +962,7 @@ int uart_register_driver(struct uart_driver *uart);
 void uart_unregister_driver(struct uart_driver *uart);
 int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
 void uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
+int uart_read_port_properties(struct uart_port *port, bool use_defaults);
 bool uart_match_port(const struct uart_port *port1,
 		const struct uart_port *port2);
 
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:25 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:25 +0200
Subject: [PATCH v1 09/14] serial: 8250_lpc18xx: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-10-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_lpc18xx.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_lpc18xx.c b/drivers/tty/serial/8250/8250_lpc18xx.c
index 8d728a6a5991..e4a6b7b4caf2 100644
--- a/drivers/tty/serial/8250/8250_lpc18xx.c
+++ b/drivers/tty/serial/8250/8250_lpc18xx.c
@@ -92,11 +92,7 @@ static int lpc18xx_serial_probe(struct platform_device *pdev)
 	struct lpc18xx_uart_data *data;
 	struct uart_8250_port uart;
 	struct resource *res;
-	int irq, ret;
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
+	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
@@ -139,19 +135,12 @@ static int lpc18xx_serial_probe(struct platform_device *pdev)
 		goto dis_clk_reg;
 	}
 
-	ret = of_alias_get_id(pdev->dev.of_node, "serial");
-	if (ret >= 0)
-		uart.port.line = ret;
-
 	data->dma.rx_param = data;
 	data->dma.tx_param = data;
 
 	spin_lock_init(&uart.port.lock);
 	uart.port.dev = &pdev->dev;
-	uart.port.irq = irq;
-	uart.port.iotype = UPIO_MEM32;
 	uart.port.mapbase = res->start;
-	uart.port.regshift = 2;
 	uart.port.type = PORT_16550A;
 	uart.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_SKIP_TEST;
 	uart.port.uartclk = clk_get_rate(data->clk_uart);
@@ -160,6 +149,13 @@ static int lpc18xx_serial_probe(struct platform_device *pdev)
 	uart.port.rs485_supported = lpc18xx_rs485_supported;
 	uart.port.serial_out = lpc18xx_uart_serial_out;
 
+	ret = uart_read_port_properties(&uart.port, true);
+	if (ret)
+		return ret;
+
+	uart.port.iotype = UPIO_MEM32;
+	uart.port.regshift = 2;
+
 	uart.dma = &data->dma;
 	uart.dma->rxconf.src_maxburst = 1;
 	uart.dma->txconf.dst_maxburst = 1;
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:30 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:30 +0200
Subject: [PATCH v1 14/14] serial: 8250_uniphier: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-15-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_uniphier.c | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c
index 6399a38ecce2..d3f270a191ee 100644
--- a/drivers/tty/serial/8250/8250_uniphier.c
+++ b/drivers/tty/serial/8250/8250_uniphier.c
@@ -162,7 +162,6 @@ static int uniphier_uart_probe(struct platform_device *pdev)
 	struct uniphier8250_priv *priv;
 	struct resource *regs;
 	void __iomem *membase;
-	int irq;
 	int ret;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -175,23 +174,12 @@ static int uniphier_uart_probe(struct platform_device *pdev)
 	if (!membase)
 		return -ENOMEM;
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
 	memset(&up, 0, sizeof(up));
 
-	ret = of_alias_get_id(dev->of_node, "serial");
-	if (ret < 0) {
-		dev_err(dev, "failed to get alias id\n");
-		return ret;
-	}
-	up.port.line = ret;
-
 	priv->clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(priv->clk)) {
 		dev_err(dev, "failed to get clock\n");
@@ -211,7 +199,10 @@ static int uniphier_uart_probe(struct platform_device *pdev)
 	up.port.mapbase = regs->start;
 	up.port.mapsize = resource_size(regs);
 	up.port.membase = membase;
-	up.port.irq = irq;
+
+	ret = uart_read_port_properties(&up.port, true);
+	if (ret)
+		return ret;
 
 	up.port.type = PORT_16550A;
 	up.port.iotype = UPIO_MEM32;
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:27 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:27 +0200
Subject: [PATCH v1 11/14] serial: 8250_omap: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-12-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_omap.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index 6942990a333c..173af575a43e 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -1394,11 +1394,7 @@ static int omap8250_probe(struct platform_device *pdev)
 	struct uart_8250_port up;
 	struct resource *regs;
 	void __iomem *membase;
-	int irq, ret;
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
+	int ret;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!regs) {
@@ -1419,7 +1415,6 @@ static int omap8250_probe(struct platform_device *pdev)
 	up.port.dev = &pdev->dev;
 	up.port.mapbase = regs->start;
 	up.port.membase = membase;
-	up.port.irq = irq;
 	/*
 	 * It claims to be 16C750 compatible however it is a little different.
 	 * It has EFR and has no FCR7_64byte bit. The AFE (which it claims to
@@ -1429,13 +1424,9 @@ static int omap8250_probe(struct platform_device *pdev)
 	 * or pm callback.
 	 */
 	up.port.type = PORT_8250;
-	up.port.iotype = UPIO_MEM;
-	up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_SOFT_FLOW |
-		UPF_HARD_FLOW;
+	up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_SOFT_FLOW | UPF_HARD_FLOW;
 	up.port.private_data = priv;
 
-	up.port.regshift = OMAP_UART_REGSHIFT;
-	up.port.fifosize = 64;
 	up.tx_loadsz = 64;
 	up.capabilities = UART_CAP_FIFO;
 #ifdef CONFIG_PM
@@ -1461,14 +1452,14 @@ static int omap8250_probe(struct platform_device *pdev)
 	up.rs485_stop_tx = serial8250_em485_stop_tx;
 	up.port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE);
 
-	ret = of_alias_get_id(np, "serial");
-	if (ret < 0) {
-		dev_err(&pdev->dev, "failed to get alias\n");
+	ret = uart_read_port_properties(&up.port, true);
+	if (ret)
 		return ret;
-	}
-	up.port.line = ret;
 
-	if (of_property_read_u32(np, "clock-frequency", &up.port.uartclk)) {
+	up.port.regshift = OMAP_UART_REGSHIFT;
+	up.port.fifosize = 64;
+
+	if (!up.port.uartclk) {
 		struct clk *clk;
 
 		clk = devm_clk_get(&pdev->dev, NULL);
@@ -1560,8 +1551,8 @@ static int omap8250_probe(struct platform_device *pdev)
 	}
 #endif
 
-	irq_set_status_flags(irq, IRQ_NOAUTOEN);
-	ret = devm_request_irq(&pdev->dev, irq, omap8250_irq, 0,
+	irq_set_status_flags(up.port.irq, IRQ_NOAUTOEN);
+	ret = devm_request_irq(&pdev->dev, up.port.irq, omap8250_irq, 0,
 			       dev_name(&pdev->dev), priv);
 	if (ret < 0)
 		return ret;
-- 
2.43.0.rc1.1.gbec44491f096



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:31:29 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:31:29 +0200
Subject: [PATCH v1 13/14] serial: 8250_tegra: Switch to use uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221183442.4124354-14-andriy.shevchenko@linux.intel.com>

Since we have now a common helper to read port properties
use it instead of sparse home grown solution.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/tty/serial/8250/8250_tegra.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_tegra.c b/drivers/tty/serial/8250/8250_tegra.c
index ba352262df75..ce48d02dfa0d 100644
--- a/drivers/tty/serial/8250/8250_tegra.c
+++ b/drivers/tty/serial/8250/8250_tegra.c
@@ -57,25 +57,11 @@ static int tegra_uart_probe(struct platform_device *pdev)
 	port = &port8250.port;
 	spin_lock_init(&port->lock);
 
-	port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT |
-		      UPF_FIXED_TYPE;
-	port->iotype = UPIO_MEM32;
-	port->regshift = 2;
+	port->flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_FIXED_TYPE;
 	port->type = PORT_TEGRA;
-	port->irqflags |= IRQF_SHARED;
 	port->dev = &pdev->dev;
 	port->handle_break = tegra_uart_handle_break;
 
-	ret = of_alias_get_id(pdev->dev.of_node, "serial");
-	if (ret >= 0)
-		port->line = ret;
-
-	ret = platform_get_irq(pdev, 0);
-	if (ret < 0)
-		return ret;
-
-	port->irq = ret;
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
@@ -88,12 +74,18 @@ static int tegra_uart_probe(struct platform_device *pdev)
 	port->mapbase = res->start;
 	port->mapsize = resource_size(res);
 
+	ret = uart_read_port_properties(port, true);
+	if (ret)
+		return ret;
+
+	port->iotype = UPIO_MEM32;
+	port->regshift = 2;
+
 	uart->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
 	if (IS_ERR(uart->rst))
 		return PTR_ERR(uart->rst);
 
-	if (device_property_read_u32(&pdev->dev, "clock-frequency",
-				     &port->uartclk)) {
+	if (!port->uartclk) {
 		uart->clk = devm_clk_get(&pdev->dev, NULL);
 		if (IS_ERR(uart->clk)) {
 			dev_err(&pdev->dev, "failed to get clock!\n");
-- 
2.43.0.rc1.1.gbec44491f096



From brgl at bgdev.pl  Wed Feb 21 10:39:19 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Wed, 21 Feb 2024 19:39:19 +0100
Subject: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
In-Reply-To: <tnylagkmj36lve2ub5voumtkqjdy6j3hr6yyk4mqkaabvc3gdv@voaiu2oqi73o>
References: <20240205182810.58382-1-brgl@bgdev.pl> <20240205182810.58382-3-brgl@bgdev.pl>
 <tnylagkmj36lve2ub5voumtkqjdy6j3hr6yyk4mqkaabvc3gdv@voaiu2oqi73o>
Message-ID: <CAMRc=McmfufqqEvouRCjY1ukVB_ie1r5QEocqRUK0VBheEq5Hg@mail.gmail.com>

On Sun, Feb 18, 2024 at 4:25?AM Bjorn Andersson <andersson at kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:00PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > Select the TrustZone memory allocator in Kconfig and create a pool of
> > memory shareable with the TrustZone when probing the SCM driver.
> >
> > This will allow a gradual conversion of all relevant SCM calls to using
> > the dedicated allocator.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
> > Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> > Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
> > Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
> > ---
> >  drivers/firmware/qcom/Kconfig    |  1 +
> >  drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
> >  2 files changed, 17 insertions(+)
> >
> > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > index f18686edf415..d24d83223867 100644
> > --- a/drivers/firmware/qcom/Kconfig
> > +++ b/drivers/firmware/qcom/Kconfig
> > @@ -7,6 +7,7 @@
> >  menu "Qualcomm firmware drivers"
> >
> >  config QCOM_SCM
> > +     select QCOM_TZMEM
> >       tristate
> >
> >  config QCOM_TZMEM
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 520de9b5633a..0d4c028be0c1 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -8,8 +8,10 @@
> >  #include <linux/completion.h>
> >  #include <linux/cpumask.h>
> >  #include <linux/dma-mapping.h>
> > +#include <linux/err.h>
> >  #include <linux/export.h>
> >  #include <linux/firmware/qcom/qcom_scm.h>
> > +#include <linux/firmware/qcom/qcom_tzmem.h>
> >  #include <linux/init.h>
> >  #include <linux/interconnect.h>
> >  #include <linux/interrupt.h>
> > @@ -20,9 +22,11 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/reset-controller.h>
> > +#include <linux/sizes.h>
> >  #include <linux/types.h>
> >
> >  #include "qcom_scm.h"
> > +#include "qcom_tzmem.h"
> >
> >  static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
> >  module_param(download_mode, bool, 0);
> > @@ -41,6 +45,8 @@ struct qcom_scm {
> >       int scm_vote_count;
> >
> >       u64 dload_mode_addr;
> > +
> > +     struct qcom_tzmem_pool *mempool;
> >  };
> >
> >  struct qcom_scm_current_perm_info {
> > @@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
> >       if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
> >               qcom_scm_disable_sdi();
> >
> > +     ret = qcom_tzmem_enable(__scm->dev);
> > +     if (ret)
> > +             return dev_err_probe(__scm->dev, ret,
> > +                                  "Failed to enable the TrustZone memory allocator\n");
> > +
> > +     __scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);
>
> As we're not moving from the callers freely allocating what they need,
> to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> so that we have something to fall back on when someone runs out of this
> space, or wonders "why not 128kb?".
>

If you worry about these pools being taken out of the total memory and
prefer to have a way to avoid it, I was thinking about another
build-time mode for the allocator - one where there's no pool but it
just allocates chunks using dma_alloc_coherent() like before and pool
size is ignored. Does it sound good?

Bart

> Regards,
> Bjorn
>
> > +     if (IS_ERR(__scm->mempool))
> > +             return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
> > +                                  "Failed to create the SCM memory pool\n");
> > +
> >       /*
> >        * Initialize the QSEECOM interface.
> >        *
> > --
> > 2.40.1
> >


From m.felsch at pengutronix.de  Wed Feb 21 10:46:02 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Wed, 21 Feb 2024 19:46:02 +0100
Subject: [PATCH] dt-bindings: mmc: fsl-imx-esdhc: add default and 100mhz state
Message-ID: <20240221184602.3639619-1-m.felsch@pengutronix.de>

Some devices support only the default and the 100MHz case, add the
support for this to the binding to avoid warnings.

Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
---
 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
index 82eb7a24c857..e47253e4eac4 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
@@ -173,6 +173,11 @@ properties:
           - const: state_100mhz
           - const: state_200mhz
           - const: sleep
+      - minItems: 2
+        items:
+          - const: default
+          - const: state_100mhz
+          - const: sleep
       - minItems: 1
         items:
           - const: default
-- 
2.39.2



From f.fainelli at gmail.com  Wed Feb 21 10:47:13 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 21 Feb 2024 10:47:13 -0800
Subject: [PATCH v1 02/14] serial: core: Add UPIO_UNSET constant for unset
 port type
In-Reply-To: <20240221183442.4124354-3-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-3-andriy.shevchenko@linux.intel.com>
Message-ID: <d18d4488-aa48-4156-8087-a117664cea7b@gmail.com>

On 2/21/24 10:31, Andy Shevchenko wrote:
> In some APIs we would like to assign the special value to iotype
> and compare against it in another places. Introduce UPIO_UNSET
> for this purpose.
> 
> Note, we can't use 0, because it's a valid value for IO port access.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> ---
>   include/linux/serial_core.h | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index 2d2ec99eca93..2b0526ae1fac 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -470,6 +470,7 @@ struct uart_port {
>   
>   	unsigned char		iotype;			/* io access style */
>   
> +#define UPIO_UNSET		((unsigned char)~0U)	/* UCHAR_MAX */

Nit: I would name this UPIO_UNKNOWN, or UPIO_NOTSET, unset means to me 
that it was previously set and we undid that action, whereas unknown or 
not set means we never did.
-- 
Florian



From andriy.shevchenko at linux.intel.com  Wed Feb 21 10:53:08 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 20:53:08 +0200
Subject: [PATCH v1 02/14] serial: core: Add UPIO_UNSET constant for unset
 port type
In-Reply-To: <d18d4488-aa48-4156-8087-a117664cea7b@gmail.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-3-andriy.shevchenko@linux.intel.com>
 <d18d4488-aa48-4156-8087-a117664cea7b@gmail.com>
Message-ID: <ZdZGlLoUd_R6JQJc@smile.fi.intel.com>

On Wed, Feb 21, 2024 at 10:47:13AM -0800, Florian Fainelli wrote:
> On 2/21/24 10:31, Andy Shevchenko wrote:

...

> >   	unsigned char		iotype;			/* io access style */
> > +#define UPIO_UNSET		((unsigned char)~0U)	/* UCHAR_MAX */
> 
> Nit: I would name this UPIO_UNKNOWN, or UPIO_NOTSET, unset means to me that
> it was previously set and we undid that action, whereas unknown or not set
> means we never did.

Works for me. I will wait for a few days / week to have more reviews and
likely testings to be collected. Would be nice if you be able to test on
(some of) the hardware in the list of modified drivers.

-- 
With Best Regards,
Andy Shevchenko




From rick.p.edgecombe at intel.com  Wed Feb 21 10:53:44 2024
From: rick.p.edgecombe at intel.com (Edgecombe, Rick P)
Date: Wed, 21 Feb 2024 18:53:44 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in
 userspace
In-Reply-To: <20240221183055.GT4163@brightrain.aerifal.cx>
References: <20240220185714.GO4163@brightrain.aerifal.cx>
	 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
	 <20240220235415.GP4163@brightrain.aerifal.cx>
	 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
	 <20240221012736.GQ4163@brightrain.aerifal.cx>
	 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
	 <20240221145800.GR4163@brightrain.aerifal.cx>
	 <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
	 <20240221175717.GS4163@brightrain.aerifal.cx>
	 <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>
	 <20240221183055.GT4163@brightrain.aerifal.cx>
Message-ID: <c3085fbe10193dfe59b25bc7da776e60779b0e8c.camel@intel.com>

On Wed, 2024-02-21 at 13:30 -0500, dalias at libc.org wrote:
> > 3 is the cleanest and safest I think, and it was thought it might
> > not
> > need kernel help, due to a scheme Florian had to direct signals to
> > specific threads. It's my preference at this point.
> 
> The operations where the shadow stack has to be processed need to be
> executable from async-signal context, so this imposes a requirement
> to
> block all signals around the lock. This makes all longjmps a heavy,
> multi-syscall operation rather than O(1) userspace operation. I do
> not
> think this is an acceptable implementation, especially when there are
> clearly superior alternatives without that cost or invasiveness.

That is a good point. Could the per-thread locks be nestable to address
this? We just need to know if a thread *might* be using shadow stacks.
So we really just need a per-thread count.

> 
> > 1 and 2 are POCed here, if you are interested:
> > https://github.com/rpedgeco/linux/commits/shstk_suppress_rfc/
> 
> I'm not clear why 2 (suppression of #CP) is desirable at all. If
> shadow stack is being disabled, it should just be disabled, with
> minimal fault handling to paper over any racing operations at the
> moment it's disabled. Leaving it on with extreme slowness to make it
> not actually do anything does not seem useful.

The benefit is that code that is using shadow stack instructions won't
crash if it relies on them working. For example RDSSP turns into a NOP
if shadow stack is disabled, and the intrinsic is written such that a
NULL pointer is returned if shadow stack is disabled. The shadow stack
is normally readable, and this happens in glibc sometimes. So if there
was code like:

   long foo = *(long *)_get_ssp();

...then it could suddenly read a NULL pointer if shadow stack got
disabled. (notice, it's not even a "shadow stack access" fault-wise. So
it was looked at as somewhat more robust. But neither 1 or 2 are
perfect for apps that are manually using shadow stack instructions.

> 
> Is there some way folks have in mind to use option 2 to lazily
> disable
> shadow stack once the first SS-incompatible code is executed, when
> execution is then known not to be in the middle of a SS-critical
> section, instead of doing it right away? I don't see how this could
> work, since the SS-incompatible code could be running from a signal
> handler that interrupted an SS-critical section.

The idea was to disable it without critical sections, and it could be
more robust, but not perfect. I was preferring option 1 between 1 and
2, which was closer to your original suggestion. But it has problems
like the example I gave above. I agree 1 is relatively simpler for the
kernel, between 1 and 2.

> 
> > > If folks on the kernel side are not going to be amenable to doing
> > > the
> > > things that are easy for the kernel to make it work without
> > > breaking
> > > compatibility with existing interfaces, but that are impossible
> > > or
> > > near-impossible for userspace to do, this seems like a dead-end.
> > > And
> > > I
> > > suspect an operation to "disable shadow stack, but without making
> > > threads still in SS-critical sections crash" is going to be
> > > necessary..
> > 
> > I think we have to work through all the alternative before we can
> > accuse the kernel of not being amenable. Is there something that
> > you
> > would like to see out of this conversation that is not happening?
> 
> No, I was just interpreting "uphill battle". I really do not want to
> engage in an uphill battle for the sake of making it practical to
> support something that was never my goal to begin with. If I'm
> misreading this, or if others are willing to put the effort into that
> "battle", I'd be happy to be mistaken about "not amenable".

I don't think x86 maintainers have put a foot down on anything around
this at least. They would normally have concerns about complexity and
maintainability. So if we have something that has lower value
(imperfect solution), and high complexity, it starts to look like less
promising path.

From hugo at hugovil.com  Wed Feb 21 10:54:52 2024
From: hugo at hugovil.com (Hugo Villeneuve)
Date: Wed, 21 Feb 2024 13:54:52 -0500
Subject: [PATCH v1 01/14] serial: core: Move struct uart_port::quirks
 closer to possible values
In-Reply-To: <20240221183442.4124354-2-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
	<20240221183442.4124354-2-andriy.shevchenko@linux.intel.com>
Message-ID: <20240221135452.6fdeb71e60509cca1be016c3@hugovil.com>

On Wed, 21 Feb 2024 20:31:17 +0200
Andy Shevchenko <andriy.shevchenko at linux.intel.com> wrote:

> Currently it's not crystal clear what UPIO_* and UPQ_* definitions
> belong two. Reindent the code, so it will be easy to read and understand.

two -> to.

Hugo V.


> No functional changes intended.
> 
> Reviewed-by: Andi Shyti <andi.shyti at linux.intel.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> ---
>  include/linux/serial_core.h | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index 55b1f3ba48ac..2d2ec99eca93 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -467,8 +467,8 @@ struct uart_port {
>  	unsigned int		fifosize;		/* tx fifo size */
>  	unsigned char		x_char;			/* xon/xoff char */
>  	unsigned char		regshift;		/* reg offset shift */
> +
>  	unsigned char		iotype;			/* io access style */
> -	unsigned char		quirks;			/* internal quirks */
>  
>  #define UPIO_PORT		(SERIAL_IO_PORT)	/* 8b I/O port access */
>  #define UPIO_HUB6		(SERIAL_IO_HUB6)	/* Hub6 ISA card */
> @@ -479,7 +479,9 @@ struct uart_port {
>  #define UPIO_MEM32BE		(SERIAL_IO_MEM32BE)	/* 32b big endian */
>  #define UPIO_MEM16		(SERIAL_IO_MEM16)	/* 16b little endian */
>  
> -	/* quirks must be updated while holding port mutex */
> +	unsigned char		quirks;			/* internal quirks */
> +
> +	/* internal quirks must be updated while holding port mutex */
>  #define UPQ_NO_TXEN_TEST	BIT(0)
>  
>  	unsigned int		read_status_mask;	/* driver specific */
> -- 
> 2.43.0.rc1.1.gbec44491f096
> 
> 


-- 
Hugo Villeneuve


From conor at kernel.org  Wed Feb 21 11:02:38 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 21 Feb 2024 19:02:38 +0000
Subject: [PATCH v3 1/2] dt-bindings: arm64: mediatek: add Kontron
 3.5"-SBC-i1200
In-Reply-To: <20240221155905.1217340-1-mwalle@kernel.org>
References: <20240221155905.1217340-1-mwalle@kernel.org>
Message-ID: <20240221-trance-handheld-59c5066aeca6@spud>

On Wed, Feb 21, 2024 at 04:59:04PM +0100, Michael Walle wrote:
> Add the compatible string for the Kontron 3.5"-SBC-i1200 single board
> computer.
> 
> Signed-off-by: Michael Walle <mwalle at kernel.org>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
> v3:
>  - drop description and add to mt8395 existing entry
> 
> v2:
>  - convert enum to const as there is only one specific board
> ---
>  Documentation/devicetree/bindings/arm/mediatek.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
> index 09f9ffd3ff7b..29ebe1f9c1d2 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
> @@ -353,6 +353,7 @@ properties:
>            - const: mediatek,mt8365
>        - items:
>            - enum:
> +              - kontron,3-5-sbc-i1200
>                - mediatek,mt8395-evk
>                - radxa,nio-12l
>            - const: mediatek,mt8395
> -- 
> 2.39.2
> 
-------------- 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/20240221/ed341c59/attachment.sig>

From andriy.shevchenko at linux.intel.com  Wed Feb 21 11:04:08 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 21 Feb 2024 21:04:08 +0200
Subject: [PATCH v1 01/14] serial: core: Move struct uart_port::quirks
 closer to possible values
In-Reply-To: <20240221135452.6fdeb71e60509cca1be016c3@hugovil.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-2-andriy.shevchenko@linux.intel.com>
 <20240221135452.6fdeb71e60509cca1be016c3@hugovil.com>
Message-ID: <ZdZJKIrkeasBwL3i@smile.fi.intel.com>

On Wed, Feb 21, 2024 at 01:54:52PM -0500, Hugo Villeneuve wrote:
> On Wed, 21 Feb 2024 20:31:17 +0200
> Andy Shevchenko <andriy.shevchenko at linux.intel.com> wrote:
> 
> > Currently it's not crystal clear what UPIO_* and UPQ_* definitions
> > belong two. Reindent the code, so it will be easy to read and understand.
> 
> two -> to.

Ah, thanks, will fix!

-- 
With Best Regards,
Andy Shevchenko




From javierm at redhat.com  Wed Feb 21 11:06:08 2024
From: javierm at redhat.com (Javier Martinez Canillas)
Date: Wed, 21 Feb 2024 20:06:08 +0100
Subject: [PATCH] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <205248ce-caeb-4090-998e-379f79639bec@linaro.org>
References: <20240221125928.3711050-1-javierm@redhat.com>
 <9f419e86-6e14-42a1-84e1-31cab62d8ea2@app.fastmail.com>
 <205248ce-caeb-4090-998e-379f79639bec@linaro.org>
Message-ID: <877cixiqn3.fsf@minerva.mail-host-address-is-not-set>

Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> writes:

> On 21/02/2024 16:31, Arnd Bergmann wrote:
>> On Wed, Feb 21, 2024, at 13:59, Javier Martinez Canillas wrote:
>>> These options are needed by some Linux distributions (e.g: Fedora), so
>>> let's enable them to make it easier for developers using such distros.
>>>
>>> Signed-off-by: Javier Martinez Canillas <javierm at redhat.com>
>>> ---
>> 
>> Acked-by: Arnd Bergmann <arnd at arndb.de>
>> 
>>> @@ -1595,6 +1599,7 @@ CONFIG_HTE_TEGRA194_TEST=m
>>>  CONFIG_EXT2_FS=y
>>>  CONFIG_EXT3_FS=y
>>>  CONFIG_EXT4_FS_POSIX_ACL=y
>>> +CONFIG_XFS_FS=m
>>>  CONFIG_BTRFS_FS=m
>>>  CONFIG_BTRFS_FS_POSIX_ACL=y
>> 
>> Unfortunately this will increase build time noticeably, but
>> I agree it is the right thing to do.
>> 
>> Can you send it (with any other acks) to soc at kernel.org so
>> I can merge it from there?
>
> Due to XFS, please include:
>
> Nacked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>

Don't worry, I won't to re-send anything if you disagree with the change.

> so this will not be precedence used for further patches like this
> (Maxime already used such argument, so I want to be sure it will not be
> used against me in the future)
>

I used the same argument and is a fair one in my opinion. Removing other
filesystems should send the correct message, if that is the agreegment.

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



From Zachary.Goldstein at concurrent-rt.com  Wed Feb 21 11:06:07 2024
From: Zachary.Goldstein at concurrent-rt.com (Zachary Goldstein)
Date: Wed, 21 Feb 2024 19:06:07 +0000
Subject: EXTERNAL: Re: [PATCH] arm64: ls1046ardb: Replace XGMII with
 10GBASE-R phy mode
In-Reply-To: <20240220145037.kf3avnykjif24kkr@skbuf>
References: <20240214-ls1046-dts-use-10gbase-r-v1-1-8c2d68547393@concurrent-rt.com>
 <20240220145037.kf3avnykjif24kkr@skbuf>
Message-ID: <AS2PR09MB598321A95CD8EF0264744498A4572@AS2PR09MB5983.eurprd09.prod.outlook.com>

On Tue, Feb 20, 2024 at 04:50:37PM +0200, Vladimir Oltean wrote:
> Hi Zachary,
> 
> On Wed, Feb 14, 2024 at 05:21:54PM -0500, Zachary Goldstein via B4 Relay wrote:
> > From: Zachary Goldstein <zachary.goldstein at concurrent-rt.com>
> > 
> > The AQR107 family does not support XGMII, but USXGMII and
> > 10GBASE-R instead. Since ce64c1f77a9d ("net: phy: aquantia: add USXGMII
> > support and warn if XGMII mode is set") the kernel warns about XGMII
> > being used. The LS1046A SoC does not support USXGMII, so use 10GBASE-R
> > instead.
> > 
> > Signed-off-by: Zachary Goldstein <zachary.goldstein at concurrent-rt.com>
> > ---
> >  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> > index 07f6cc6e354a..d2066f733dc5 100644
> > --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> > @@ -149,7 +149,7 @@ ethernet at ea000 {
> >  
> >  	ethernet at f0000 { /* 10GEC1 */
> >  		phy-handle = <&aqr106_phy>;
> > -		phy-connection-type = "xgmii";
> > +		phy-connection-type = "10gbase-r";
> >  	};
> >  
> >  	ethernet at f2000 { /* 10GEC2 */
> > 
> > ---
> > 2.40.1
> > base-commit: 841c35169323cd833294798e58b9bf63fa4fa1de
> > 
> > 
> 
> You do not need this patch in upstream, and I strongly advise against
> merging it as-is. I've just tested pure net-next on LS1046A-RDB, and I
> can bring up fm1-mac9 without any warning.
> 
> You'll notice that commit 5d93cfcf7360 ("net: dpaa: Convert to phylink")
> did this in fman_memac.c:
> 
> 	/* The internal connection to the serdes is XGMII, but this isn't
> 	 * really correct for the phy mode (which is the external connection).
> 	 * However, this is how all older device trees say that they want
> 	 * 10GBASE-R (aka XFI), so just convert it for them.
> 	 */
> 	if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
> 		mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
> 
> So, what gets passed to the Aquantia PHY is PHY_INTERFACE_MODE_10GBASER,
> even if in the device tree, phy-connection-type = "xgmii".
> 
> Now, _if_ your patch were to be applied on top of upstream, it would
> actually break fm1-mac9 like this (WARN_ON added by me for a call stack
> of the phylink_validate() failure path):
> 
> WARNING: CPU: 2 PID: 1 at drivers/net/phy/phylink.c:763 phylink_create+0x8f8/0x90c
> Modules linked in:
> CPU: 2 PID: 1 Comm: swapper/0 Tainted: G        W          6.8.0-rc4-01058-g9e1deba407fb #1812
> Hardware name: LS1046A RDB Board (DT)
> Call trace:
>  phylink_create+0x8f8/0x90c
>  dpaa_netdev_init+0x1a8/0x2c8
>  dpaa_eth_probe+0xd70/0xf64
>  platform_probe+0xa8/0xd0
>  really_probe+0x130/0x2e4
>  __driver_probe_device+0xa0/0x128
>  driver_probe_device+0x3c/0x200
>  __driver_attach+0xe8/0x1b4
>  bus_for_each_dev+0xec/0x144
>  driver_attach+0x24/0x30
>  bus_add_driver+0x154/0x244
>  driver_register+0x68/0x100
>  __platform_driver_register+0x24/0x30
>  dpaa_load+0x34/0x64
>  do_one_initcall+0xf8/0x34c
> ---[ end trace 0000000000000000 ]---
> fsl_dpaa_mac 1af0000.ethernet (unnamed net_device) (uninitialized): failed to validate link configuration for in-band status
> fsl_dpaa_mac 1af0000.ethernet: error -EINVAL: Could not create phylink
> fsl_dpa: probe of dpaa-ethernet.4 failed with error -22
> 
> It fails because of this in phylink_validate():
> 
> 	if (!test_bit(state->interface, interfaces))
> 		return -EINVAL;
> 
> And state->interface (PHY_INTERFACE_MODE_10GBASER) is not in
> mac_dev->phylink_config.supported_interfaces, because the fman_memac
> code is not prepared to handle this combination.
> 
> The device tree node for fm1-mac9 looks like this, generated by an
> awkward merge between the following:
> 
> 	ethernet at f0000 {
> 		phy-connection-type = "xgmii";	// fsl-ls1046a-rdb.dts
> 		local-mac-address = [...];	// U-Boot
> 		cell-index = <0x8>;		// qoriq-fman3-0-10g-0.dtsi
> 		pcsphy-handle = <0x31>;		// qoriq-fman3-0-10g-0.dtsi
> 		compatible = "fsl,fman-memac";	// qoriq-fman3-0-10g-0.dtsi
> 		reg = <0xf0000 0x1000>;		// qoriq-fman3-0-10g-0.dtsi
> 		phy-handle = <&aqr106_phy>;	// fsl-ls1046a-rdb.dts
> 		fsl,fman-ports = <0x2f 0x30>;	// qoriq-fman3-0-10g-0.dtsi
> 	};
> 
> Notice that unlike fm1-mac10 (node "ethernet at f2000"), there is no
> pcs-handle-names property (fm1-mac10 has it defined in fsl-ls1046-post.dtsi,
> whereas fm1-mac9 doesn't. Don't ask me why, I don't know....)
> 
> So, knowing that of_property_match_string(mac_node, "pcs-handle-names", "xfi")
> will return an error code for fm1-mac9, now please walk through memac_initialization()
> and see what happens in the 2 cases:
> 
> - mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII (current device tree). The
>   code creates a default PCS and assigns it to memac->xfi_pcs like this:
> 	if (err == -EINVAL || err == -ENODATA)
> 		pcs = memac_pcs_create(mac_node, 0);
> 	(...)
> 	if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
> 		memac->xfi_pcs = pcs;
> 
> - mac_dev->phy_if == PHY_INTERFACE_MODE_10GBASER (your modification).
>   The code will still create the default PCS, but assign it to
>   memac->sgmii_pcs instead!
> 
> 	if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) // not XGMII, but 10GBASER!
> 		memac->xfi_pcs = pcs;
> 	else
> 		memac->sgmii_pcs = pcs;
> 
> And this is why, with a NULL memac->xfi_pcs, PHY_INTERFACE_MODE_10GBASER
> will not be in phylink's supported_interfaces.
> 

Admittedly, I had made the wrong assumption from looking at the dpaa
driver code and fm1-mac10, that "xgmii" and "10gbase-r" were
interchangeable. 

> To make your device tree patch work as intended with the current
> mainline code, what you want is to also modify the driver like this:
> 
> >From d6bda34b132d17d1c236d27436b9335fac22c062 Mon Sep 17 00:00:00 2001
> From: Vladimir Oltean <vladimir.oltean at nxp.com>
> Date: Tue, 20 Feb 2024 16:12:27 +0200
> Subject: [PATCH] net: dpaa: fman_memac: accept phy-interface-type =
>  "10gbase-r" in the device tree
> 
> We support the phy-interface-mode = "xgmii" conversion to "10gbase-r"
> through code, but not actually through the device tree proper. This is
> because boards such as LS1046A-RDB do not define pcs-handle-names in the
> ethernet at f0000 device tree node, and the code only has fallback xfi_pcs
> determination logic for "xgmii".
> 
> By reversing the order between the fallback xfi_pcs assignment and the
> "xgmii" overwrite with "10gbase-r", we are able to support both values
> in the device tree, with identical behavior.
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> ---
>  .../net/ethernet/freescale/fman/fman_memac.c   | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
> index e30bf75b1d48..0996759907a8 100644
> --- a/drivers/net/ethernet/freescale/fman/fman_memac.c
> +++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
> @@ -1076,6 +1076,14 @@ int memac_initialization(struct mac_device *mac_dev,
>  	unsigned long		 capabilities;
>  	unsigned long		*supported;
>  
> +	/* The internal connection to the serdes is XGMII, but this isn't
> +	 * really correct for the phy mode (which is the external connection).
> +	 * However, this is how all older device trees say that they want
> +	 * 10GBASE-R (aka XFI), so just convert it for them.
> +	 */
> +	if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
> +		mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
> +
>  	mac_dev->phylink_ops		= &memac_mac_ops;
>  	mac_dev->set_promisc		= memac_set_promiscuous;
>  	mac_dev->change_addr		= memac_modify_mac_address;
> @@ -1142,7 +1150,7 @@ int memac_initialization(struct mac_device *mac_dev,
>  	 * (and therefore that xfi_pcs cannot be set). If we are defaulting to
>  	 * XGMII, assume this is for XFI. Otherwise, assume it is for SGMII.
>  	 */
> -	if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
> +	if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_10GBASER)
>  		memac->xfi_pcs = pcs;
>  	else
>  		memac->sgmii_pcs = pcs;
> @@ -1156,14 +1164,6 @@ int memac_initialization(struct mac_device *mac_dev,
>  		goto _return_fm_mac_free;
>  	}
>  
> -	/* The internal connection to the serdes is XGMII, but this isn't
> -	 * really correct for the phy mode (which is the external connection).
> -	 * However, this is how all older device trees say that they want
> -	 * 10GBASE-R (aka XFI), so just convert it for them.
> -	 */
> -	if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
> -		mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
> -
>  	/* TODO: The following interface modes are supported by (some) hardware
>  	 * but not by this driver:
>  	 * - 1000BASE-KX
> 
> But!
> 
> Device tree is stable ABI, and changes made to the device tree file are
> meant to be backwards and forwards compatible with the code (it can be
> provided separately and not necessarily in lockstep with the kernel
> version. For example, I understand Arm SystemReady IR wants U-Boot to
> provide its own device tree to Linux through EFI). So, in general,
> device tree changes which only work with a corresponding kernel change
> are frowned upon (unless maybe if the kernel change is a bug fix that is
> backported to all relevant stable kernel branches).
> 
> So at this stage we should take a step back and re-analyze the cost/benefit.
> You said there is a stack trace in the Aquantia PHY driver, which there
> is not (in current mainline kernels). I _think_ you are seeing the stack
> trace with LSDK, which is currently distributed on top of linux-6.1.y
> and has not yet integrated the fman_memac conversion to phylink - thus,
> it does not contain commit 5d93cfcf7360 ("net: dpaa: Convert to phylink").
> At least, I do see this stack trace there. I think it can also be seen
> with mainline kernels before the phylink conversion, but I did not test
> those.
> 
> The main take-away is: ALWAYS test the patch you are submitting to the
> target kernel it is going to be applied to. Especially in the area of
> device tree bindings for DPAA1, things are rarely as simple as they
> appear :) If you don't, you will have an unintended negative effect
> upon current mainline kernels (which must still work), and not the
> intended effect upon LSDK (more below).

This is my mistake, as at the time I had no way of testing this patch on
6.8. After looking at commit 5d93cfcf7360 ("net: dpaa: Convert to
phylink"), I had made the (wrong) assumption that changing to
"10gbase-r" was pretty harmless. 

> 
> There are a few options to go forward from here.
> 
> As there is nothing broken in the mainline kernel where you are
> submitting this patch, the simplest one, as bland as it may sound, is
> simply to wait for a new LSDK release on top of linux-6.6.y. Even in
> lf-6.1.y, AFAICS, nothing is broken except for the stack trace. You can
> keep the patch in your local kernel tree copy to suppress that.
> 
> The other option would be to submit the fman_memac change as a bug fix
> for stable, wait for a while for it to have time to propagate, then
> modify the device tree as well. But, it is much higher effort, and
> there is no procedure in place, AFAIK, for LSDK to integrate your patch
> (other than through upstream + a few months of waiting). The upcoming
> LSDK release will be on top of linux-6.6.y, it will make your effort
> irrelevant if it's only for suppressing the stack trace, and you are
> racing against it. This path is only worth it if you have the dedication
> to dig a bit deeper and tidy things up in the DPAA1 kernel support
> (which would be appreciated though).
> 
> _If_ you are using an older linux-stable branch but not LSDK, yes, the
> feedback loop between your patch and its effect will close much sooner,
> but you will have to convince the linux-stable people that it's worth
> accepting your driver rework patches for a functional reason and not
> just aesthetic (see Documentation/process/stable-kernel-rules.rst for
> reference).

Considering "xgmii" is a deprecated phy type for the AQR107 family, I
still think there is some value to this change beyond aesthetics if
support for "10gbase-r" is ever added.

From dalias at libc.org  Wed Feb 21 11:06:39 2024
From: dalias at libc.org (dalias at libc.org)
Date: Wed, 21 Feb 2024 14:06:39 -0500
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <c3085fbe10193dfe59b25bc7da776e60779b0e8c.camel@intel.com>
References: <20240220235415.GP4163@brightrain.aerifal.cx>
 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx>
 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx>
 <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
 <20240221175717.GS4163@brightrain.aerifal.cx>
 <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>
 <20240221183055.GT4163@brightrain.aerifal.cx>
 <c3085fbe10193dfe59b25bc7da776e60779b0e8c.camel@intel.com>
Message-ID: <20240221190639.GU4163@brightrain.aerifal.cx>

On Wed, Feb 21, 2024 at 06:53:44PM +0000, Edgecombe, Rick P wrote:
> On Wed, 2024-02-21 at 13:30 -0500, dalias at libc.org wrote:
> > > 3 is the cleanest and safest I think, and it was thought it might
> > > not
> > > need kernel help, due to a scheme Florian had to direct signals to
> > > specific threads. It's my preference at this point.
> > 
> > The operations where the shadow stack has to be processed need to be
> > executable from async-signal context, so this imposes a requirement
> > to
> > block all signals around the lock. This makes all longjmps a heavy,
> > multi-syscall operation rather than O(1) userspace operation. I do
> > not
> > think this is an acceptable implementation, especially when there are
> > clearly superior alternatives without that cost or invasiveness.
> 
> That is a good point. Could the per-thread locks be nestable to address
> this? We just need to know if a thread *might* be using shadow stacks.
> So we really just need a per-thread count.

Due to arbitrarily nestable signal frames, no, this does not suffice.
An interrupted operation using the lock could be arbitrarily delayed,
even never execute again, making any call to dlopen deadlock.

> > > 1 and 2 are POCed here, if you are interested:
> > > https://github.com/rpedgeco/linux/commits/shstk_suppress_rfc/
> > 
> > I'm not clear why 2 (suppression of #CP) is desirable at all. If
> > shadow stack is being disabled, it should just be disabled, with
> > minimal fault handling to paper over any racing operations at the
> > moment it's disabled. Leaving it on with extreme slowness to make it
> > not actually do anything does not seem useful.
> 
> The benefit is that code that is using shadow stack instructions won't
> crash if it relies on them working. For example RDSSP turns into a NOP
> if shadow stack is disabled, and the intrinsic is written such that a
> NULL pointer is returned if shadow stack is disabled. The shadow stack
> is normally readable, and this happens in glibc sometimes. So if there
> was code like:
> 
>    long foo = *(long *)_get_ssp();
> 
> ...then it could suddenly read a NULL pointer if shadow stack got
> disabled. (notice, it's not even a "shadow stack access" fault-wise. So
> it was looked at as somewhat more robust. But neither 1 or 2 are
> perfect for apps that are manually using shadow stack instructions.

It's fine to turn RDSSP into an actual emulated read of the SSP, or at
least an emulated load of zero so that uninitialized data is not left
in the target register. If doing the latter, code working with the
shadow stack just needs to be prepared for the possibility that it
could be async-disabled, and check the return value.

I have not looked at all the instructions that become #UD but I
suspect they all have reasonable trivial ways to implement a
"disabled" version of them that userspace can act upon reasonably.

Rich


From brgl at bgdev.pl  Wed Feb 21 11:06:29 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Wed, 21 Feb 2024 20:06:29 +0100
Subject: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
In-Reply-To: <7pybw4wxlzxfl65yuqxzks5w7uq52hosyq53etlzas6i6o5l6d@vxd4sykcxora>
References: <20240205182810.58382-1-brgl@bgdev.pl> <20240205182810.58382-11-brgl@bgdev.pl>
 <7pybw4wxlzxfl65yuqxzks5w7uq52hosyq53etlzas6i6o5l6d@vxd4sykcxora>
Message-ID: <CAMRc=MdAG7jehYbF1ZuEzpK5x9QpHNTvzxc6C=5wkCAP3OhGcQ@mail.gmail.com>

On Sun, Feb 18, 2024 at 4:41?AM Bjorn Andersson <andersson at kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > Add a new Kconfig option for selecting the SHM Bridge mode of operation
>
> The Kconfig option is the least significant bit of this patch. I guess
> there isn't really a problem to describe, but let's at least mention
> that we're switching TZ to shmbridge mode and all.
>
> > for the TrustZone memory allocator.
> >
> > If enabled at build-time, it will still be checked for availability at
> > run-time. If the architecture doesn't support SHM Bridge, the allocator
> > will work just like in the default mode.
>
> "default mode"...SHMBRIDGE is the default mode from this point onwards.
>

Well, it is starting with patch 12/12 and only with arm64 defconfig.
The Kconfig *default* is still the regular non-SHM bridge pool. I'll
work on the naming convention.

Bart

[snip]


From horms at kernel.org  Wed Feb 21 11:07:40 2024
From: horms at kernel.org (Simon Horman)
Date: Wed, 21 Feb 2024 19:07:40 +0000
Subject: [PATCH net-next v4 2/7] net: phylink: add rxc_always_on flag to
 phylink_pcs
In-Reply-To: <20240221-rxc_bugfix-v4-2-4883ee1cc7b1@bootlin.com>
References: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
 <20240221-rxc_bugfix-v4-2-4883ee1cc7b1@bootlin.com>
Message-ID: <20240221190740.GG722610@kernel.org>

On Wed, Feb 21, 2024 at 02:04:19PM +0100, Romain Gantois wrote:
> Some MAC drivers (e.g. stmmac) require a continuous receive clock signal to
> be generated by a PCS that is handled by a standalone PCS driver.
> 
> Such a PCS driver does not have access to a PHY device, thus cannot check
> the PHY_F_RXC_ALWAYS_ON flag. They cannot check max_requires_rxc in the
> phylink config either, since it is a private member. Therefore, a new flag
> is needed to signal to the PCS that it should keep the RX clock signal up
> at all times.
> 
> Suggested-by: Russell King <linux at armlinux.org.uk>
> Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>

...

> @@ -549,6 +557,34 @@ void pcs_an_restart(struct phylink_pcs *pcs);
>   */
>  void pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
>  		 phy_interface_t interface, int speed, int duplex);
> +
> +/**
> + * pcs_pre_init() - Configure PCS components necessary for MAC initialization
> + * @pcs: a pointer to a &struct phylink_pcs.
> + *
> + * This function can be called by MAC drivers through the
> + * phylink_pcs_pre_init() wrapper, before their hardware is initialized. It
> + * should not be called after the link is brought up, as reconfiguring the PCS
> + * at this point could break the link.
> + *
> + * Some MAC devices require specific hardware initialization to be performed by
> + * their associated PCS device before they can properly initialize their own
> + * hardware. An example of this is the initialization of stmmac controllers,
> + * which requires an active REF_CLK signal to be provided by the PHY/PCS.
> + *
> + * By calling phylink_pcs_pre_init(), MAC drivers can ensure that the PCS is
> + * setup in a way that allows for successful hardware initialization.
> + *
> + * The specific configuration performed by pcs_pre_init() is dependent on the
> + * model of PCS and the requirements of the MAC device attached to it. PCS
> + * driver authors should consider whether their target device is to be used in
> + * conjunction with a MAC device whose driver calls phylink_pcs_pre_init(). MAC
> + * driver authors should document their requirements for the PCS
> + * pre-initialization.
> + *
> + */
> +int pcs_config(struct phylink_pcs *pcs);

Hi Romain,

Should this be pcs_pre_init instead of pcs_config?

> +
>  #endif
>  
>  struct phylink *phylink_create(struct phylink_config *,

...


From dalias at libc.org  Wed Feb 21 11:10:39 2024
From: dalias at libc.org (dalias at libc.org)
Date: Wed, 21 Feb 2024 14:10:39 -0500
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <b41e39d1-29f9-4958-9728-6781e72230f8@sirena.org.uk>
References: <20240220185714.GO4163@brightrain.aerifal.cx>
 <9fc9c45ff6e14df80ad023e66ff7a978bd4ec91c.camel@intel.com>
 <20240220235415.GP4163@brightrain.aerifal.cx>
 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx>
 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx>
 <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
 <20240221175717.GS4163@brightrain.aerifal.cx>
 <b41e39d1-29f9-4958-9728-6781e72230f8@sirena.org.uk>
Message-ID: <20240221191039.GV4163@brightrain.aerifal.cx>

On Wed, Feb 21, 2024 at 06:32:20PM +0000, Mark Brown wrote:
> On Wed, Feb 21, 2024 at 12:57:19PM -0500, dalias at libc.org wrote:
> > On Wed, Feb 21, 2024 at 05:36:12PM +0000, Mark Brown wrote:
> 
> > > This feels like it's getting complicated and I fear it may be an uphill
> > > struggle to get such code merged, at least for arm64.  My instinct is
> > > that it's going to be much more robust and generally tractable to let
> > > things run to some suitable synchronisation point and then disable
> > > there, but if we're going to do that then userspace can hopefully
> > > arrange to do the disabling itself through the standard disable
> > > interface anyway.  Presumably it'll want to notice things being disabled
> > > at some point anyway?  TBH that's been how all the prior proposals for
> > > process wide disable I've seen were done.
> 
> > If it's possible to disable per-thread rather than per-process, some
> > things are easier. Disabling on account of using alt stacks only needs
> 
> Both x86 and arm64 currently track shadow stack enablement per thread,
> not per process, so it's not just possible to do per thread it's the
> only thing we're currently implementing.  I think the same is true for
> RISC-V but I didn't look as closely at that yet.

That's nice! It allows still keeping part of the benefit of SS in
programs which have some threads running with custom stacks. We do
however need a global-disable option for dlopen. In musl this could be
done via the same mechanism ("synccall") used for set*id -- it's
basically userspace IPI. But just having a native operation would be
nicer, and would probably help glibc where I don't think they
abstracted their set*id mechanism to do other things like this.

> > If folks on the kernel side are not going to be amenable to doing the
> > things that are easy for the kernel to make it work without breaking
> > compatibility with existing interfaces, but that are impossible or
> > near-impossible for userspace to do, this seems like a dead-end. And I
> > suspect an operation to "disable shadow stack, but without making
> > threads still in SS-critical sections crash" is going to be
> > necessary..
> 
> Could you be more specific as to the easy things that you're referencing
> here?

Basically the ARCH_SHSTK_SUPPRESS_UD proposal.

Rich


From conor at kernel.org  Wed Feb 21 11:13:28 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 21 Feb 2024 19:13:28 +0000
Subject: [PATCH] dt-bindings: net: wireless: mt76: allow all 4 interrupts
 for MT7981
In-Reply-To: <20240221081238.24775-1-zajec5@gmail.com>
References: <20240221081238.24775-1-zajec5@gmail.com>
Message-ID: <20240221-sanction-bunt-c109f5b590ad@spud>

On Wed, Feb 21, 2024 at 09:12:38AM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7981 (Filogic 820) is a low cost version of MT7986 (Filogic 830) with
> a similar wireless controller that also supports four interrupts.
> 
> Cc: Peter Chiu <chui-hao.chiu at mediatek.com>
> Cc: Felix Fietkau <nbd at nbd.name>
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
>  .../devicetree/bindings/net/wireless/mediatek,mt76.yaml          | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
> index 0c6835db397f..eabceb849537 100644
> --- a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
> +++ b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
> @@ -226,6 +226,7 @@ allOf:
>          compatible:
>            contains:
>              enum:
> +              - mediatek,mt7981-wmac
>                - mediatek,mt7986-wmac
>      then:
>        properties:
> -- 
> 2.35.3
> 
-------------- 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/20240221/72e09fe4/attachment-0001.sig>

From mka at chromium.org  Wed Feb 21 11:14:12 2024
From: mka at chromium.org (Matthias Kaehlcke)
Date: Wed, 21 Feb 2024 19:14:12 +0000
Subject: [PATCH v4 1/8] usb: misc: onboard_hub: rename to onboard_dev
In-Reply-To: <20240220-onboard_xvf3500-v4-1-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
 <20240220-onboard_xvf3500-v4-1-dc1617cc5dd4@wolfvision.net>
Message-ID: <ZdZLhMIEQ_dwG8_m@google.com>

On Tue, Feb 20, 2024 at 03:05:45PM +0100, Javier Carrasco wrote:
> This patch prepares onboad_hub to support non-hub devices by renaming
> the driver files and their content, the headers and their references.
> 
> The comments and descriptions have been slightly modified to keep
> coherence and account for the specific cases that only affect onboard
> hubs (e.g. peer-hub).
> 
> The "hub" variables in functions where "dev" (and similar names) variables
> already exist have been renamed to onboard_dev for clarity, which adds a
> few lines in cases where more than 80 characters are used.
> 
> No new functionality has been added.
> 
> Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
> ---
>  ...-usb-hub => sysfs-bus-platform-onboard-usb-dev} |   4 +-
>  MAINTAINERS                                        |   4 +-
>  drivers/usb/core/Makefile                          |   4 +-
>  drivers/usb/core/hub.c                             |   8 +-
>  drivers/usb/core/hub.h                             |   2 +-
>  drivers/usb/misc/Kconfig                           |  16 +-
>  drivers/usb/misc/Makefile                          |   2 +-
>  drivers/usb/misc/onboard_usb_dev.c                 | 518 +++++++++++++++++++++
>  .../misc/{onboard_usb_hub.h => onboard_usb_dev.h}  |  28 +-
>  ...ard_usb_hub_pdevs.c => onboard_usb_dev_pdevs.c} |  47 +-
>  drivers/usb/misc/onboard_usb_hub.c                 | 501 --------------------
>  include/linux/usb/onboard_dev.h                    |  18 +
>  include/linux/usb/onboard_hub.h                    |  18 -
>  13 files changed, 594 insertions(+), 576 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-hub b/Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-dev
> similarity index 67%
> rename from Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-hub
> rename to Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-dev
> index 42deb0552065..cd31f76362e7 100644
> --- a/Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-hub
> +++ b/Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-dev
> @@ -4,5 +4,5 @@ KernelVersion:	5.20
>  Contact:	Matthias Kaehlcke <matthias at kaehlcke.net>
>  		linux-usb at vger.kernel.org
>  Description:
> -		(RW) Controls whether the USB hub remains always powered
> -		during system suspend or not.
> \ No newline at end of file
> +		(RW) Controls whether the USB device remains always powered
> +		during system suspend or not.

With patch "[2/8] usb: misc: onboard_dev: add support for non-hub devices"
this attribute isn't honed for non-hub devices. With that I'd say leave
the existing comment unchanged, but add a note that this attribute only
exists for hubs. That will also require a change in the patch mentioned
above to omit the creation of the attribute for non-hub devices.

> diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
> new file mode 100644
> index 000000000000..2103af2cb2a6
> --- /dev/null
> +++ b/drivers/usb/misc/onboard_usb_dev.c
>
> ...
>
> +/*
> + * Returns the onboard_dev platform device that is associated with the USB
> + * device passed as parameter.
> + */
> +static struct onboard_dev *_find_onboard_dev(struct device *dev)
> +{
> +	struct platform_device *pdev;
> +	struct device_node *np;
> +	struct onboard_dev *onboard_dev;
> +
> +	pdev = of_find_device_by_node(dev->of_node);
> +	if (!pdev) {
> +		np = of_parse_phandle(dev->of_node, "peer-hub", 0);
> +		if (!np) {
> +			dev_err(dev, "failed to find device node for peer hub\n");
> +			return ERR_PTR(-EINVAL);
> +		}
> +
> +		pdev = of_find_device_by_node(np);
> +		of_node_put(np);
> +
> +		if (!pdev)
> +			return ERR_PTR(-ENODEV);
> +	}
> +
> +	onboard_dev = dev_get_drvdata(&pdev->dev);
> +	put_device(&pdev->dev);
> +
> +	/*
> +	 * The presence of drvdata ('hub') indicates that the platform driver

drop "('hub')"

> diff --git a/drivers/usb/misc/onboard_usb_hub_pdevs.c b/drivers/usb/misc/onboard_usb_dev_pdevs.c
> similarity index 69%
> rename from drivers/usb/misc/onboard_usb_hub_pdevs.c
> rename to drivers/usb/misc/onboard_usb_dev_pdevs.c
> index ed22a18f4ab7..ca56f67393f1 100644
> --- a/drivers/usb/misc/onboard_usb_hub_pdevs.c
> +++ b/drivers/usb/misc/onboard_usb_dev_pdevs.c
>
> ...
>
>  /**
> - * onboard_hub_create_pdevs -- create platform devices for onboard USB hubs
> - * @parent_hub	: parent hub to scan for connected onboard hubs
> - * @pdev_list	: list of onboard hub platform devices owned by the parent hub
> + * onboard_dev_create_pdevs -- create platform devices for onboard USB devices
> + * @parent_hub	: parent hub to scan for connected onboard devices
> + * @pdev_list	: list of onboard platform devices owned by the parent hub
>   *
> - * Creates a platform device for each supported onboard hub that is connected to
> - * the given parent hub. The platform device is in charge of initializing the
> - * hub (enable regulators, take the hub out of reset, ...) and can optionally
> - * control whether the hub remains powered during system suspend or not.
> + * Creates a platform device for each supported onboard device that is connected
> + * to the given parent hub. The platform device is in charge of initializing the
> + * device (enable regulators, take the device out of reset, ...) and can
> + * optionally control whether the device remains powered during system suspend
> + * or not.

The last part isn't/won't be true for non-hub devices. Please change it to
something like ". For onboard hubs the platform device can optionally control ..."



From kuba at kernel.org  Wed Feb 21 11:14:44 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Wed, 21 Feb 2024 11:14:44 -0800
Subject: [PATCH net-next v4 5/7] net: stmmac: Signal to PHY/PCS drivers
 to keep RX clock on
In-Reply-To: <20240221-rxc_bugfix-v4-5-4883ee1cc7b1@bootlin.com>
References: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com>
	<20240221-rxc_bugfix-v4-5-4883ee1cc7b1@bootlin.com>
Message-ID: <20240221111444.22fce1f7@kernel.org>

On Wed, 21 Feb 2024 14:04:22 +0100 Romain Gantois wrote:
> There is a reocurring issue with stmmac controllers where the MAC fails to
> initialize its hardware if an RX clock signal isn't provided on the MAC/PHY
> link.
> 
> This causes issues when PHY or PCS devices either go into suspend while
> cutting the RX clock or do not bring the clock signal up early enough for
> the MAC to initialize successfully.
> 
> Set the mac_requires_rxc flag in the stmmac phylink config so that PHY/PCS
> drivers know to keep the RX clock up at all times.
> 
> Reported-by: Clark Wang <xiaoning.wang at nxp.com>
> Link: https://lore.kernel.org/all/20230202081559.3553637-1-xiaoning.wang at nxp.com/
> Reported-by: Cl?ment L?ger <clement.leger at bootlin.com>
> Link: https://lore.kernel.org/linux-arm-kernel/20230116103926.276869-4-clement.leger at bootlin.com/
> Suggested-by: Russell King <linux at armlinux.org.uk>
> Signed-off-by: Romain Gantois <romain.gantois at bootlin.com>

breaks allmodconfig:

ERROR: modpost: "phylink_pcs_pre_init" [drivers/net/ethernet/stmicro/stmmac/stmmac.ko] undefined!
-- 
pw-bot: cr


From broonie at kernel.org  Wed Feb 21 11:20:11 2024
From: broonie at kernel.org (Mark Brown)
Date: Wed, 21 Feb 2024 19:20:11 +0000
Subject: [PATCH v8 33/38] kselftest/arm64: Add a GCS test program built
 with the system libc
In-Reply-To: <87sf1n7uea.fsf@linaro.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <20240203-arm64-gcs-v8-33-c9fec77673ef@kernel.org>
 <87sf1n7uea.fsf@linaro.org>
Message-ID: <084d97c0-a84c-49e1-a1e2-d864dbfcce0e@sirena.org.uk>

On Mon, Feb 19, 2024 at 11:15:57PM -0300, Thiago Jung Bauermann wrote:

> The only issue as can be seen above is that the can_call_function test
> is failing. The child is getting a GCS Segmentation fault when returning
> from fork().

> I tried debugging it with GDB, but I don't see what's wrong since the
> address in LR matches the first entry in GCSPR. Here is the
> debug session:

I'm simply not seeing this in my testing.  There's *something* going on
somewhere, I had another report of a similarish thing elsewhere, but not
in any way that I've ever been able to reproduce.  It smells like there
might be something missing with the page tables...
-------------- 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/20240221/4bc7a0ba/attachment.sig>

From will at kernel.org  Wed Feb 21 11:22:06 2024
From: will at kernel.org (Will Deacon)
Date: Wed, 21 Feb 2024 19:22:06 +0000
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
Message-ID: <20240221192205.GA7619@willie-the-truck>

On Tue, Feb 20, 2024 at 09:17:08PM -0400, Jason Gunthorpe wrote:
> +static inline void __const_memcpy_toio_aligned64(volatile u64 __iomem *to,
> +						 const u64 *from, size_t count)
> +{
> +	switch (count) {
> +	case 8:
> +		asm volatile("str %x0, [%8, #8 * 0]\n"
> +			     "str %x1, [%8, #8 * 1]\n"
> +			     "str %x2, [%8, #8 * 2]\n"
> +			     "str %x3, [%8, #8 * 3]\n"
> +			     "str %x4, [%8, #8 * 4]\n"
> +			     "str %x5, [%8, #8 * 5]\n"
> +			     "str %x6, [%8, #8 * 6]\n"
> +			     "str %x7, [%8, #8 * 7]\n"
> +			     :
> +			     : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
> +			       "rZ"(from[3]), "rZ"(from[4]), "rZ"(from[5]),
> +			       "rZ"(from[6]), "rZ"(from[7]), "r"(to));
> +		break;
> +	case 4:
> +		asm volatile("str %x0, [%4, #8 * 0]\n"
> +			     "str %x1, [%4, #8 * 1]\n"
> +			     "str %x2, [%4, #8 * 2]\n"
> +			     "str %x3, [%4, #8 * 3]\n"
> +			     :
> +			     : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
> +			       "rZ"(from[3]), "r"(to));
> +		break;
> +	case 2:
> +		asm volatile("str %x0, [%2, #8 * 0]\n"
> +			     "str %x1, [%2, #8 * 1]\n"
> +			     :
> +			     : "rZ"(from[0]), "rZ"(from[1]), "r"(to));
> +		break;
> +	case 1:
> +		__raw_writel(*from, to);

Shouldn't this be __raw_writeq?

Will


From rick.p.edgecombe at intel.com  Wed Feb 21 11:22:21 2024
From: rick.p.edgecombe at intel.com (Edgecombe, Rick P)
Date: Wed, 21 Feb 2024 19:22:21 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in
 userspace
In-Reply-To: <20240221190639.GU4163@brightrain.aerifal.cx>
References: <20240220235415.GP4163@brightrain.aerifal.cx>
	 <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
	 <20240221012736.GQ4163@brightrain.aerifal.cx>
	 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
	 <20240221145800.GR4163@brightrain.aerifal.cx>
	 <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
	 <20240221175717.GS4163@brightrain.aerifal.cx>
	 <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>
	 <20240221183055.GT4163@brightrain.aerifal.cx>
	 <c3085fbe10193dfe59b25bc7da776e60779b0e8c.camel@intel.com>
	 <20240221190639.GU4163@brightrain.aerifal.cx>
Message-ID: <e3a432c0fa9f5fe837e9d2fc7b36304709a34428.camel@intel.com>

On Wed, 2024-02-21 at 14:06 -0500, dalias at libc.org wrote:
> Due to arbitrarily nestable signal frames, no, this does not suffice.
> An interrupted operation using the lock could be arbitrarily delayed,
> even never execute again, making any call to dlopen deadlock.

Doh! Yep, it is not robust to this. The only thing that could be done
would be a timeout in dlopen(). Which would make the whole thing just
better than nothing.

> 
> > 
> 
> It's fine to turn RDSSP into an actual emulated read of the SSP, or
> at
> least an emulated load of zero so that uninitialized data is not left
> in the target register.

We can't intercept RDSSP, but it becomes a NOP by default. (disclaimer
x86-only knowledge).

>  If doing the latter, code working with the
> shadow stack just needs to be prepared for the possibility that it
> could be async-disabled, and check the return value.
> 
> I have not looked at all the instructions that become #UD but I
> suspect they all have reasonable trivial ways to implement a
> "disabled" version of them that userspace can act upon reasonably.

This would have to be thought through functionally and performance
wise. I'm not opposed if can come up with a fully fleshed out plan. How
serious are you in pursuing musl support, if we had something like
this?

HJ, any thoughts on whether glibc would use this as well?

It is probably worth mentioning that from the security side (as Mark
mentioned there is always tension in the tradeoffs on these features),
permissive mode is seen by some as something that weakens security too
much. Apps could call dlopen() on a known unsupported DSO before doing
ROP. I don't know if you have any musl users with specific shadow stack
use cases to ask about this.

From mka at chromium.org  Wed Feb 21 11:24:12 2024
From: mka at chromium.org (Matthias Kaehlcke)
Date: Wed, 21 Feb 2024 19:24:12 +0000
Subject: [PATCH v4 2/8] usb: misc: onboard_dev: add support for non-hub
 devices
In-Reply-To: <20240220-onboard_xvf3500-v4-2-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
 <20240220-onboard_xvf3500-v4-2-dc1617cc5dd4@wolfvision.net>
Message-ID: <ZdZN3FIS4zcKe4Kw@google.com>

On Tue, Feb 20, 2024 at 03:05:46PM +0100, Javier Carrasco wrote:
> Most of the functionality this driver provides can be used by non-hub
> devices as well.
> 
> To account for the hub-specific code, add a flag to the device data
> structure and check its value for hub-specific code.

Please mention that the driver doesn't power off non-hub devices
during system suspend.

> Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
> ---
>  drivers/usb/misc/onboard_usb_dev.c |  3 ++-
>  drivers/usb/misc/onboard_usb_dev.h | 10 ++++++++++
>  2 files changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
> index 2103af2cb2a6..f43130a6786f 100644
> --- a/drivers/usb/misc/onboard_usb_dev.c
> +++ b/drivers/usb/misc/onboard_usb_dev.c
> @@ -129,7 +129,8 @@ static int __maybe_unused onboard_dev_suspend(struct device *dev)
>  		if (!device_may_wakeup(node->udev->bus->controller))
>  			continue;
>  
> -		if (usb_wakeup_enabled_descendants(node->udev)) {
> +		if (usb_wakeup_enabled_descendants(node->udev) ||
> +		    !onboard_dev->pdata->is_hub) {


This check isn't dependent on characteristics of the USB devices processed
in this loop, therefore it can be performed at function entry. Please combine
it with the check of 'always_powered_in_suspend'. It's also an option to
omit the check completely, 'always_powered_in_suspend' will never be set for
non-hub devices (assuming the sysfs attribute isn't added).

>  			power_off = false;
>  			break;
>  		}

Without code context: please omit the creation of the 'always_powered_in_suspend'
attribute for non-hub devices. As per above we don't plan to hone it, so it
shouldn't exist.


From wsa+renesas at sang-engineering.com  Wed Feb 21 11:27:13 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Wed, 21 Feb 2024 20:27:13 +0100
Subject: [PATCH v3] i2c: imx: when being a target, mark the last read as processed
Message-ID: <20240221193013.14233-2-wsa+renesas@sang-engineering.com>

From: Corey Minyard <minyard at acm.org>

When being a target, NAK from the controller means that all bytes have
been transferred. So, the last byte needs also to be marked as
'processed'. Otherwise index registers of backends may not increase.

Signed-off-by: Corey Minyard <minyard at acm.org>
Tested-by: Andrew Manley <andrew.manley at sealingtech.com>
Reviewed-by: Andrew Manley <andrew.manley at sealingtech.com>
Reviewed-by: Oleksij Rempel <o.rempel at pengutronix.de>
[wsa: fixed comment and commit message to properly describe the case]
Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
---

Changes since v2:
* updated commit message and comment

In the stalled discussion[1], it seems I couldn't make my suggestions
clear. So, here are the changes how I meant them. I hope this can be
agreed on.

[1] http://patchwork.ozlabs.org/project/linux-i2c/patch/20211112133956.655179-3-minyard at acm.org/

 drivers/i2c/busses/i2c-imx.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 88a053987403..60e813137f84 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -803,6 +803,11 @@ static irqreturn_t i2c_imx_slave_handle(struct imx_i2c_struct *i2c_imx,
 		ctl &= ~I2CR_MTX;
 		imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
 		imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
+
+		/* flag the last byte as processed */
+		i2c_imx_slave_event(i2c_imx,
+				    I2C_SLAVE_READ_PROCESSED, &value);
+
 		i2c_imx_slave_finish_op(i2c_imx);
 		return IRQ_HANDLED;
 	}
-- 
2.43.0



From linus.walleij at linaro.org  Wed Feb 21 11:31:35 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 20:31:35 +0100
Subject: [PATCH 05/23] gpio: nomadik: extract GPIO platform driver from drivers/pinctrl/nomadik/
In-Reply-To: <CZAW6UTMON6K.34LW7FDGNO1XC@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-5-f88c0ccf372b@bootlin.com> <CACRpkdaSMJBFrmbTu+C1Ls8HkLH4FZsAQ6t7dC76+sVTXXHEyw@mail.gmail.com>
 <CZAW6UTMON6K.34LW7FDGNO1XC@bootlin.com>
Message-ID: <CACRpkdZPU2EuBjTA3_ZQN=apSSpUYg0sOZoskSnttkVBixAnhw@mail.gmail.com>

On Wed, Feb 21, 2024 at 5:20?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> > Could you add:
> >
> > default PINCTRL_NOMADIK
> >
> > so it is turned on by default when we have that, since they are jitted together
> > so closely.
>
> Would that bring something more than what is currently present? I've set
> PINCTRL_NOMADIK to select GPIO_NOMADIK.

I missed that!

OK no problem, all works fine.

Yours,
Linus Walleij


From javierm at redhat.com  Wed Feb 21 11:34:55 2024
From: javierm at redhat.com (Javier Martinez Canillas)
Date: Wed, 21 Feb 2024 20:34:55 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <9083c414-62f2-4bff-93ee-13f8ff60eb34@linaro.org>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
 <9083c414-62f2-4bff-93ee-13f8ff60eb34@linaro.org>
Message-ID: <874je1ipb4.fsf@minerva.mail-host-address-is-not-set>

Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> writes:

> On 21/02/2024 16:24, Maxime Ripard wrote:
>> On Wed, Feb 21, 2024 at 04:10:12PM +0100, Krzysztof Kozlowski wrote:
>>> On 21/02/2024 15:48, Maxime Ripard wrote:
>>>> On Wed, Feb 21, 2024 at 03:22:38PM +0100, Krzysztof Kozlowski wrote:
>>>>> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
>>>>>> These options are needed by some Linux distributions (e.g: Fedora), so
>>>>>
>>>>> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
>>>>> use on my arm64 boards, does not have any problem.
>>>>
>>>> Is it relevant in any way?
>>>
>>> Yes, because it is justification why we are doing it. Each commit is
>>> supposed to explain "why" and the explanation here is not enough.
>> 
>> There's a why though: it makes Fedora boot. It might not be enough for
>
> I want to know to understand. Maybe it is not really neeed but "nice to
> have"? People write various vague statements...
>

I usually try hard not to be vague. There was a why, it wasn't enough for
you and that's fair.

But I think the crux of the why was explained: I don't want to remember
each time that need to troubleshoot something, what options are missing
in order to boot Fedora.

>> you, but that's a different story. So, if it's not enough, please state
>> exactly what you expect from that patch description so Javier can
>> provide it.
>
> Any explanation what ZRAM is necessary for Fedora to boot.
>

I mentioned already in another email, Fedora is enabling the systemd
zram-generator and not having a /dev/zram0 slows down the boot to the
point of being unusable. One could disable that service but then is yet
another thing to remember when trying to boot an upstream kernel built.

Could had added all this information to the commit message but I thought
that it would be too much...

>> 
>>>> I'm sure Debian can boot without MEMORY_HOTREMOVE, or BRIDGE, or
>>>> NUMA_BALANCING, or BPF_JIT, or NFS_FS, yet all of them are enabled. Let
>>>> me know if you want hundreds more examples.
>>>
>>> So if there is any bug, you are allowed to add new one? If there is any
>>> silly option, you are allowed to add new one?
>>>
>>> Feel free to propose dropping of any irrelevant options.
>> 
>> No, of course you aren't. My point is that Fedora is a distro just as
>> established and legitimate as Debian is. And apparently "it makes Debian
>> works" is a reasonable argument, since, well, it does.
>> 
>> If making Fedora boot with that defconfig is not a legitimate goal,
>
> It is, but I asked for more information.
>
>> please state why, and document it (with the ack of all the maintainers
>> involved with that defconfig, obviously) so we don't have the same
>> argument over and over again.
>> 
>>>>> I kind of repeat comments from similar patch earlier:
>>>>> https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/
>>>>>
>>>>> About XFS: I don't think it is needed to boot anything.
>>>>
>>>> Just like 9P_FS, NFS or UBIFS.
>>>
>>> NFS is often used on targets, e.g. my board farm, but also by other people.
>>>
>>> UBIFS was added recently because one device was using it - you needed
>>> it. 9P_FS looks unnecessary.
>> 
>> So all we need is one person or use case to require it? Sounds like
>> we've checked that mark here.
>
> Use case of given type. I would disagree for SMBFS because we have NFS.
> UBIFS is hardware requirement. 9P_FS seems like virtio case.
>

So that means that for aarch64, some filesystems have more precedence over
others? It's OK to have ext4 or btrfs but no xfs? Honestly it seems quite
arbitrary and subjective for me.

>> 
>>>>> This is a defconfig, not a distro config. Please don't make it distro.
>>>>>
>>>>> I will gladly support things needed by systemd or equivalent, but not
>>>>> unusual filesystems needed by distro.
>>>>
>>>> It's a defconfig. It's whatever people want it to be. Or we need to come
>>>> up with a clearly defined set of rules of what is acceptable in that
>>>> defconfig or not, and prune every option that isn't.
>>>
>>> So that's the rule I am commenting from time to time. defconfigs are not
>>> distro configs. These are reference hardware configs and debugging
>>> configs.
>>
>> Supporting a board farm is hardly either.
>
> Debugging purpose, but I agree we can drop it.
>
>> 
>> And again, I've never heard of such rule for that defconfig in my ~10y
>> as an ARM platform maintainer. But what do I know, right?
>> 
>>> I was working in distro so trust me - they do stuff differently
>>> and they not need XFS in our defconfig for anything.
>>

Which distro? Every one uses a different filesystem. SUSE uses btrfs,
Debian I think ext4, Fedora uses xfs and so on. It's OK if the policy
is that the defconfig should only be compatible with Debian, but then
should be written somewhere.

>> Sure, but you're not just arguing for XFS there.
>
> I raised need for "why" for ZRAM and un-necessity of XFS. What's wrong
> with that? I should send separate emails or what?
>
>> 
>> What I really don't get is this: this makes the life of people easier.
>
> Again: this makes my life harder. I cannot be buying new machines every
> two years to be able to compile defconfig while testing/working.
>

And not having it enabled makes my life (and other fedora users) harder
because xfs needs to be enabled every time that an upstream kernel needs
to be tested.

>> 
>> Being able to test an upstream kernel quickly when you have a bug in a
>> downstream distro is super valuable for any distro developper. And on
>
> That's a distro need, not relevant. And even if it was, then your
> argument would be "let's enable everything distro has!". This is not a
> distro kernel.
>

It's not a distro need in my opinion but an upstream kernel developer
need. If I have had chosen xfs for personal preference, would that be
any different?

>
>> the long run, if we don't make the switch from a kernel distro to a
>> mainline kernel relatively easy, we're the ones that will lose out.
>> Because people just won't bother, or be frustrated and thus super
>> reluctant to do that work.
>> 
>> That's the part I don't get. Why do we want to make the life of people
>> harder. This patch has never been about making the defconfig the main
>
> Because it makes my life harder and I don't see benefits. Quoting Arnd:
> "Unfortunately this will increase build time noticeably, but"
>

The benefit is for developers who use Fedora to be able to boot their
kernels built using defconfig, just like developers using other distros
can now. We already have ext4 and btrfs, but somehow xfs is not OK.

> Best regards,
> Krzysztof
>

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



From linus.walleij at linaro.org  Wed Feb 21 11:36:39 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 20:36:39 +0100
Subject: [PATCH 18/23] gpio: nomadik: support mobileye,eyeq5-gpio
In-Reply-To: <CZAW47LJHQVD.1Z9GFT8UENYXT@bootlin.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-18-f88c0ccf372b@bootlin.com> <CACRpkdYLBGsphNkmWyPXQZvFaO2hHGHGTMt1eqz-HAa2k5F3bg@mail.gmail.com>
 <CZAW47LJHQVD.1Z9GFT8UENYXT@bootlin.com>
Message-ID: <CACRpkdZQ9LEqKvugDCMEXPPLMCUJ-f9rYQOpmsSEJhtW0zjNsg@mail.gmail.com>

On Wed, Feb 21, 2024 at 5:16?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:

> > Trying to figure it out...
>
> Can I help in the debugging process?

Nah, I found it :)

> Reading the code once again I'd guess
> of_device_get_match_data(&gpio_pdev->dev) could be the root cause. We
> are accessing match data for the GPIO device while probing the pinctrl
> device. Maybe something isn't initialised properly yet? The rest looks
> rather harmless, I've checked all conditional expressions.

Yep spot on. The nmk_gpio_populate_chip() is sometimes called from
the pinctrl driver before the gpio probe() has been called, so the match
data is NULL and we crash.

This looks like it does for historical reasons and there could be better
ways to fix it now that Saravana Kannan has fixed up the probe ordering
code.

The following is one way to fix it for now using device_is_compatible()
(illustrating some other changes I did as well):

diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c
index 21bb6d6363fc..11071a982ebb 100644
--- a/drivers/gpio/gpio-nomadik.c
+++ b/drivers/gpio/gpio-nomadik.c
@@ -27,6 +27,7 @@
 #include <linux/of_platform.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/reset.h>
 #include <linux/seq_file.h>
 #include <linux/types.h>
@@ -37,15 +38,13 @@
 static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
 #endif

-#define NMK_GPIO_FLAG_QUIRK_MBLY    BIT(0)
-
 void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset,
              enum nmk_gpio_slpm mode)
 {
     u32 slpm;

     /* We should NOT have been called. */
-    if (WARN_ON(nmk_chip->quirk_mbly))
+    if (WARN_ON(nmk_chip->is_mobileye_soc))
         return;

     slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
@@ -105,7 +104,7 @@ static void __nmk_gpio_irq_modify(struct
nmk_gpio_chip *nmk_chip,
         fimscval = &nmk_chip->fimsc;
     } else  {
         /* We should NOT have been called. */
-        if (WARN_ON(nmk_chip->quirk_mbly))
+        if (WARN_ON(nmk_chip->is_mobileye_soc))
             return;
         rimscreg = NMK_GPIO_RWIMSC;
         fimscreg = NMK_GPIO_FWIMSC;
@@ -134,7 +133,7 @@ static void __nmk_gpio_set_wake(struct
nmk_gpio_chip *nmk_chip,
                 int offset, bool on)
 {
     /* We should NOT have been called. */
-    if (WARN_ON(nmk_chip->quirk_mbly))
+    if (WARN_ON(nmk_chip->is_mobileye_soc))
         return;

     /*
@@ -161,7 +160,7 @@ static void nmk_gpio_irq_maskunmask(struct
nmk_gpio_chip *nmk_chip,

     __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);

-    if (!nmk_chip->quirk_mbly && !(nmk_chip->real_wake & BIT(d->hwirq)))
+    if (!nmk_chip->is_mobileye_soc && !(nmk_chip->real_wake & BIT(d->hwirq)))
         __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);

     spin_unlock(&nmk_chip->lock);
@@ -194,7 +193,7 @@ static int nmk_gpio_irq_set_wake(struct irq_data
*d, unsigned int on)
     unsigned long flags;

     /* Handler is registered in all cases. */
-    if (nmk_chip->quirk_mbly)
+    if (nmk_chip->is_mobileye_soc)
         return -ENXIO;

     clk_enable(nmk_chip->clk);
@@ -235,7 +234,7 @@ static int nmk_gpio_irq_set_type(struct irq_data
*d, unsigned int type)
     if (enabled)
         __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);

-    if (!nmk_chip->quirk_mbly && (enabled || wake))
+    if (!nmk_chip->is_mobileye_soc && (enabled || wake))
         __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);

     nmk_chip->edge_rising &= ~BIT(d->hwirq);
@@ -249,7 +248,7 @@ static int nmk_gpio_irq_set_type(struct irq_data
*d, unsigned int type)
     if (enabled)
         __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);

-    if (!nmk_chip->quirk_mbly && (enabled || wake))
+    if (!nmk_chip->is_mobileye_soc && (enabled || wake))
         __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);

     spin_unlock_irqrestore(&nmk_chip->lock, flags);
@@ -383,7 +382,7 @@ static int nmk_gpio_get_mode(struct nmk_gpio_chip
*nmk_chip, int offset)
     u32 afunc, bfunc;

     /* We don't support modes. */
-    if (nmk_chip->quirk_mbly)
+    if (nmk_chip->is_mobileye_soc)
         return NMK_GPIO_ALT_GPIO;

     clk_enable(nmk_chip->clk);
@@ -517,7 +516,6 @@ struct nmk_gpio_chip
*nmk_gpio_populate_chip(struct device_node *np,
     struct resource *res;
     struct clk *clk;
     void __iomem *base;
-    uintptr_t flags;
     u32 id, ngpio;

     gpio_pdev = of_find_device_by_node(np);
@@ -551,8 +549,7 @@ struct nmk_gpio_chip
*nmk_gpio_populate_chip(struct device_node *np,
         dev_dbg(&pdev->dev, "populate: using default ngpio (%d)\n", ngpio);
     }

-    flags = (uintptr_t)of_device_get_match_data(&gpio_pdev->dev);
-    nmk_chip->quirk_mbly = !!(flags & NMK_GPIO_FLAG_QUIRK_MBLY);
+    nmk_chip->is_mobileye_soc = device_is_compatible(&gpio_pdev->dev,
"mobileye,eyeq5-gpio");
     nmk_chip->bank = id;
     chip = &nmk_chip->chip;
     chip->base = -1;
@@ -667,7 +664,7 @@ static int nmk_gpio_probe(struct platform_device *pdev)
         return ret;
     }

-    if (!nmk_chip->quirk_mbly) {
+    if (!nmk_chip->is_mobileye_soc) {
         clk_enable(nmk_chip->clk);
         nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
         clk_disable(nmk_chip->clk);
@@ -690,7 +687,6 @@ static const struct of_device_id nmk_gpio_match[] = {
     },
     {
         .compatible = "mobileye,eyeq5-gpio",
-        .data = (void*)NMK_GPIO_FLAG_QUIRK_MBLY,
     },
     {}
 };
diff --git a/include/linux/gpio/gpio-nomadik.h
b/include/linux/gpio/gpio-nomadik.h
index 8d0134dd3771..ede16cdaa920 100644
--- a/include/linux/gpio/gpio-nomadik.h
+++ b/include/linux/gpio/gpio-nomadik.h
@@ -51,6 +51,7 @@ enum nmk_gpio_slpm {

 struct nmk_gpio_chip {
     struct gpio_chip chip;
+    bool is_mobileye_soc;
     void __iomem *addr;
     struct clk *clk;
     unsigned int bank;

Yours,
Linus Walleij


From charles.perry at savoirfairelinux.com  Wed Feb 21 11:50:46 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Wed, 21 Feb 2024 14:50:46 -0500
Subject: [PATCH v4 0/3] fpga: xilinx-selectmap: add new driver
Message-ID: <20240221195058.1281973-1-charles.perry@savoirfairelinux.com>

Hello,

This patchset adds a new driver for the 7 series FPGA's SelectMAP
interface.

The SelectMAP interface shares a common GPIO protocol with the SPI
interface which is already in the kernel (drivers/fpga/xilinx-spi.c).
The approach proposed in this patchset is to refactor xilinx-spi.c into
xilinx-core.c which would handle the common GPIO protocol. This is then
used to build two drivers, the already existing xilinx-spi.c driver and
a newly added xilinx-selectmap.c driver.

The SelectMAP driver proposed only supports 8 bit mode. This is because
the 16 and 32 bits mode have limitations with regards to compressed
bitstream support as well as introducing endianness considerations.

I'm testing xilinx-selectmap.c on a custom i.MX6 board connected to an
Artix 7 FPGA. Flashing a 913K bitstream takes 0.44 seconds.

Changes since v3: (from Rob Herring review)
 * Fix an error in the DT binding example compatible.
 * Drop the renaming of "prog_b" to "prog" and "init-b" to "init".
   Patches 2 and 3 are removed.

Changes since v2:
 * Inserted patch 2 and 3 which rename "prog_b" and "init-b" into "prog"
   and "init" for the SPI driver.
 * From Krzysztof Kozlowski review's:
   * Use more specific compatible names
   * Remove other missing occurences of the slave word missed in v2.
 * From Xu Yilun review's:
   * Fix vertical whitespace in get_done_gpio().
   * Combine write() and write_one_dummy_byte() together.
   * Eliminate most of the xilinx_core_probe() arguments, the driver
     needs to populate those directly into the xilinx_fpga_core struct.
     Added some documentation to struct xilinx_fpga_core to clarify
     this.
   * Removed typedefs from xilinx-core.h.
   * Moved null checks in xilinx_core_probe() to first patch.
   * Move csi_b and rdwr_b out of xilinx_selectmap_conf as they are not
     used out of the probe function.

Changes since v1: (from Krzysztof Kozlowski review's)
  * Use more conventional names for gpio DT bindings
  * fix example in DT bindings
  * add mc-peripheral-props.yaml to DT bindings
  * fix various formatting mistakes
  * Remove all occurences of the "slave" word.

Charles Perry (3):
  fpga: xilinx-spi: extract a common driver core
  dt-bindings: fpga: xlnx,fpga-selectmap: add DT schema
  fpga: xilinx-selectmap: add new driver

 .../bindings/fpga/xlnx,fpga-selectmap.yaml    |  86 +++++++
 drivers/fpga/Kconfig                          |  12 +
 drivers/fpga/Makefile                         |   2 +
 drivers/fpga/xilinx-core.c                    | 208 +++++++++++++++++
 drivers/fpga/xilinx-core.h                    |  28 +++
 drivers/fpga/xilinx-selectmap.c               |  97 ++++++++
 drivers/fpga/xilinx-spi.c                     | 212 ++----------------
 7 files changed, 446 insertions(+), 199 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
 create mode 100644 drivers/fpga/xilinx-core.c
 create mode 100644 drivers/fpga/xilinx-core.h
 create mode 100644 drivers/fpga/xilinx-selectmap.c

--
2.43.0


From charles.perry at savoirfairelinux.com  Wed Feb 21 11:50:48 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Wed, 21 Feb 2024 14:50:48 -0500
Subject: [PATCH v4 2/3] dt-bindings: fpga: xlnx,fpga-selectmap: add DT schema
In-Reply-To: <20240221195058.1281973-1-charles.perry@savoirfairelinux.com>
References: <20240221195058.1281973-1-charles.perry@savoirfairelinux.com>
Message-ID: <20240221195058.1281973-3-charles.perry@savoirfairelinux.com>

Document the SelectMAP interface of Xilinx 7 series FPGA.

Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
---
 .../bindings/fpga/xlnx,fpga-selectmap.yaml    | 86 +++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml

diff --git a/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
new file mode 100644
index 0000000000000..08a5e92781657
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/xlnx,fpga-selectmap.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/fpga/xlnx,fpga-selectmap.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xilinx SelectMAP FPGA interface
+
+maintainers:
+  - Charles Perry <charles.perry at savoirfairelinux.com>
+
+description: |
+  Xilinx 7 Series FPGAs support a method of loading the bitstream over a
+  parallel port named the SelectMAP interface in the documentation. Only
+  the x8 mode is supported where data is loaded at one byte per rising edge of
+  the clock, with the MSB of each byte presented to the D0 pin.
+
+  Datasheets:
+    https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf
+
+allOf:
+  - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml#
+
+properties:
+  compatible:
+    enum:
+      - xlnx,fpga-xc7s-selectmap
+      - xlnx,fpga-xc7a-selectmap
+      - xlnx,fpga-xc7k-selectmap
+      - xlnx,fpga-xc7v-selectmap
+
+  reg:
+    description:
+      At least 1 byte of memory mapped IO
+    maxItems: 1
+
+  prog_b-gpios:
+    description:
+      config pin (referred to as PROGRAM_B in the manual)
+    maxItems: 1
+
+  done-gpios:
+    description:
+      config status pin (referred to as DONE in the manual)
+    maxItems: 1
+
+  init-b-gpios:
+    description:
+      initialization status and configuration error pin
+      (referred to as INIT_B in the manual)
+    maxItems: 1
+
+  csi-gpios:
+    description:
+      chip select pin (referred to as CSI_B in the manual)
+      Optional gpio for if the bus controller does not provide a chip select.
+    maxItems: 1
+
+  rdwr-gpios:
+    description:
+      read/write select pin (referred to as RDWR_B in the manual)
+      Optional gpio for if the bus controller does not provide this pin.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - prog_b-gpios
+  - done-gpios
+  - init-b-gpios
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    fpga-mgr at 8000000 {
+      compatible = "xlnx,fpga-xc7s-selectmap";
+      reg = <0x8000000 0x4>;
+      prog_b-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>;
+      init-b-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
+      done-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>;
+      csi-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
+      rdwr-gpios = <&gpio3 10 GPIO_ACTIVE_LOW>;
+    };
+...
-- 
2.43.0



From charles.perry at savoirfairelinux.com  Wed Feb 21 11:50:47 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Wed, 21 Feb 2024 14:50:47 -0500
Subject: [PATCH v4 1/3] fpga: xilinx-spi: extract a common driver core
In-Reply-To: <20240221195058.1281973-1-charles.perry@savoirfairelinux.com>
References: <20240221195058.1281973-1-charles.perry@savoirfairelinux.com>
Message-ID: <20240221195058.1281973-2-charles.perry@savoirfairelinux.com>

Factor out the gpio handshaking (using PROGRAM_B, INIT_B and DONE)
protocol in xilinx-core so that it can be reused for another driver.
This commit does not change anything functionally to xilinx-spi.

xilinx-core expects drivers to provide a single operation:

 * ->write(const char* buf, size_t count): write to the device

As well as a struct device* for resource management.

Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
---
 drivers/fpga/Kconfig       |   4 +
 drivers/fpga/Makefile      |   1 +
 drivers/fpga/xilinx-core.c | 208 ++++++++++++++++++++++++++++++++++++
 drivers/fpga/xilinx-core.h |  28 +++++
 drivers/fpga/xilinx-spi.c  | 212 +++----------------------------------
 5 files changed, 254 insertions(+), 199 deletions(-)
 create mode 100644 drivers/fpga/xilinx-core.c
 create mode 100644 drivers/fpga/xilinx-core.h

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 2f689ac4ba3a3..d27a1ebf40838 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -64,9 +64,13 @@ config FPGA_MGR_STRATIX10_SOC
 	help
 	  FPGA manager driver support for the Intel Stratix10 SoC.
 
+config FPGA_MGR_XILINX_CORE
+	tristate
+
 config FPGA_MGR_XILINX_SPI
 	tristate "Xilinx Configuration over Slave Serial (SPI)"
 	depends on SPI
+	select FPGA_MGR_XILINX_CORE
 	help
 	  FPGA manager driver support for Xilinx FPGA configuration
 	  over slave serial interface.
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 352a2612623e0..7ec795b6a5a70 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
 obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
 obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC)	+= stratix10-soc.o
 obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
+obj-$(CONFIG_FPGA_MGR_XILINX_CORE)	+= xilinx-core.o
 obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
 obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
 obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA)	+= zynqmp-fpga.o
diff --git a/drivers/fpga/xilinx-core.c b/drivers/fpga/xilinx-core.c
new file mode 100644
index 0000000000000..597e8b7a530b7
--- /dev/null
+++ b/drivers/fpga/xilinx-core.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Common parts of the Xilinx Spartan6 and 7 Series FPGA manager drivers.
+ *
+ * Copyright (C) 2017 DENX Software Engineering
+ *
+ * Anatolij Gustschin <agust at denx.de>
+ */
+
+#include "xilinx-core.h"
+
+#include <linux/delay.h>
+#include <linux/fpga/fpga-mgr.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of.h>
+
+static int get_done_gpio(struct fpga_manager *mgr)
+{
+	struct xilinx_fpga_core *core = mgr->priv;
+	int ret;
+
+	ret = gpiod_get_value(core->done);
+	if (ret < 0)
+		dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret);
+
+	return ret;
+}
+
+static enum fpga_mgr_states xilinx_core_state(struct fpga_manager *mgr)
+{
+	if (!get_done_gpio(mgr))
+		return FPGA_MGR_STATE_RESET;
+
+	return FPGA_MGR_STATE_UNKNOWN;
+}
+
+/**
+ * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
+ * a given delay if the pin is unavailable
+ *
+ * @mgr:        The FPGA manager object
+ * @value:      Value INIT_B to wait for (1 = asserted = low)
+ * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
+ *
+ * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
+ * too much time passed waiting for that. If no INIT_B GPIO is available
+ * then always return 0.
+ */
+static int wait_for_init_b(struct fpga_manager *mgr, int value,
+			   unsigned long alt_udelay)
+{
+	struct xilinx_fpga_core *core = mgr->priv;
+	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+
+	if (core->init_b) {
+		while (time_before(jiffies, timeout)) {
+			int ret = gpiod_get_value(core->init_b);
+
+			if (ret == value)
+				return 0;
+
+			if (ret < 0) {
+				dev_err(&mgr->dev,
+					"Error reading INIT_B (%d)\n", ret);
+				return ret;
+			}
+
+			usleep_range(100, 400);
+		}
+
+		dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n",
+			value ? "assert" : "deassert");
+		return -ETIMEDOUT;
+	}
+
+	udelay(alt_udelay);
+
+	return 0;
+}
+
+static int xilinx_core_write_init(struct fpga_manager *mgr,
+				  struct fpga_image_info *info, const char *buf,
+				  size_t count)
+{
+	struct xilinx_fpga_core *core = mgr->priv;
+	int err;
+
+	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
+		dev_err(&mgr->dev, "Partial reconfiguration not supported\n");
+		return -EINVAL;
+	}
+
+	gpiod_set_value(core->prog_b, 1);
+
+	err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */
+	if (err) {
+		gpiod_set_value(core->prog_b, 0);
+		return err;
+	}
+
+	gpiod_set_value(core->prog_b, 0);
+
+	err = wait_for_init_b(mgr, 0, 0);
+	if (err)
+		return err;
+
+	if (get_done_gpio(mgr)) {
+		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
+		return -EIO;
+	}
+
+	/* program latency */
+	usleep_range(7500, 7600);
+	return 0;
+}
+
+static int xilinx_core_write(struct fpga_manager *mgr, const char *buf,
+			     size_t count)
+{
+	struct xilinx_fpga_core *core = mgr->priv;
+
+	return core->write(core, buf, count);
+}
+
+static int xilinx_core_write_complete(struct fpga_manager *mgr,
+				      struct fpga_image_info *info)
+{
+	struct xilinx_fpga_core *core = mgr->priv;
+	unsigned long timeout =
+		jiffies + usecs_to_jiffies(info->config_complete_timeout_us);
+	bool expired = false;
+	int done;
+	int ret;
+	const char padding[1] = { 0xff };
+
+	/*
+	 * This loop is carefully written such that if the driver is
+	 * scheduled out for more than 'timeout', we still check for DONE
+	 * before giving up and we apply 8 extra CCLK cycles in all cases.
+	 */
+	while (!expired) {
+		expired = time_after(jiffies, timeout);
+
+		done = get_done_gpio(mgr);
+		if (done < 0)
+			return done;
+
+		ret = core->write(core, padding, 1);
+		if (ret)
+			return ret;
+
+		if (done)
+			return 0;
+	}
+
+	if (core->init_b) {
+		ret = gpiod_get_value(core->init_b);
+
+		if (ret < 0) {
+			dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
+			return ret;
+		}
+
+		dev_err(&mgr->dev,
+			ret ? "CRC error or invalid device\n" :
+			      "Missing sync word or incomplete bitstream\n");
+	} else {
+		dev_err(&mgr->dev, "Timeout after config data transfer\n");
+	}
+
+	return -ETIMEDOUT;
+}
+
+static const struct fpga_manager_ops xilinx_core_ops = {
+	.state = xilinx_core_state,
+	.write_init = xilinx_core_write_init,
+	.write = xilinx_core_write,
+	.write_complete = xilinx_core_write_complete,
+};
+
+int xilinx_core_probe(struct xilinx_fpga_core *core)
+{
+	struct fpga_manager *mgr;
+
+	if (!core || !core->dev || !core->write)
+		return -EINVAL;
+
+	/* PROGRAM_B is active low */
+	core->prog_b = devm_gpiod_get(core->dev, "prog_b", GPIOD_OUT_LOW);
+	if (IS_ERR(core->prog_b))
+		return dev_err_probe(core->dev, PTR_ERR(core->prog_b),
+				     "Failed to get PROGRAM_B gpio\n");
+
+	core->init_b = devm_gpiod_get_optional(core->dev, "init-b", GPIOD_IN);
+	if (IS_ERR(core->init_b))
+		return dev_err_probe(core->dev, PTR_ERR(core->init_b),
+				     "Failed to get INIT_B gpio\n");
+
+	core->done = devm_gpiod_get(core->dev, "done", GPIOD_IN);
+	if (IS_ERR(core->done))
+		return dev_err_probe(core->dev, PTR_ERR(core->done),
+				     "Failed to get DONE gpio\n");
+
+	mgr = devm_fpga_mgr_register(core->dev,
+				     "Xilinx Slave Serial FPGA Manager",
+				     &xilinx_core_ops, core);
+	return PTR_ERR_OR_ZERO(mgr);
+}
diff --git a/drivers/fpga/xilinx-core.h b/drivers/fpga/xilinx-core.h
new file mode 100644
index 0000000000000..bea190287b403
--- /dev/null
+++ b/drivers/fpga/xilinx-core.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __XILINX_CORE_H
+#define __XILINX_CORE_H
+
+#include <linux/device.h>
+
+/**
+ * struct xilinx_fpga_core - interface between the driver and the core manager
+ *                           of Xilinx 7 Series FPGA manager
+ * @dev:       device node, must be set by the driver
+ * @write:     write callback of the driver, must be set by the driver
+ * @prog_b:    PROGRAM_B gpio, handled by the core manager
+ * @init_b:    INIT_B gpio, handled by the core manager
+ * @done:      DONE gpio, handled by the core manager
+ */
+struct xilinx_fpga_core {
+	struct device *dev;
+	int (*write)(struct xilinx_fpga_core *core, const char *buf,
+		     size_t count);
+	struct gpio_desc *prog_b;
+	struct gpio_desc *init_b;
+	struct gpio_desc *done;
+};
+
+int xilinx_core_probe(struct xilinx_fpga_core *core);
+
+#endif /* __XILINX_CORE_H */
diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c
index e1a227e7ff2ae..12f401502a53a 100644
--- a/drivers/fpga/xilinx-spi.c
+++ b/drivers/fpga/xilinx-spi.c
@@ -10,127 +10,24 @@
  * the slave serial configuration interface.
  */
 
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/fpga/fpga-mgr.h>
-#include <linux/gpio/consumer.h>
+#include "xilinx-core.h"
+
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
 #include <linux/of.h>
 #include <linux/spi/spi.h>
-#include <linux/sizes.h>
 
 struct xilinx_spi_conf {
+	struct xilinx_fpga_core core;
 	struct spi_device *spi;
-	struct gpio_desc *prog_b;
-	struct gpio_desc *init_b;
-	struct gpio_desc *done;
 };
 
-static int get_done_gpio(struct fpga_manager *mgr)
-{
-	struct xilinx_spi_conf *conf = mgr->priv;
-	int ret;
-
-	ret = gpiod_get_value(conf->done);
-
-	if (ret < 0)
-		dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret);
-
-	return ret;
-}
-
-static enum fpga_mgr_states xilinx_spi_state(struct fpga_manager *mgr)
-{
-	if (!get_done_gpio(mgr))
-		return FPGA_MGR_STATE_RESET;
-
-	return FPGA_MGR_STATE_UNKNOWN;
-}
-
-/**
- * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
- * a given delay if the pin is unavailable
- *
- * @mgr:        The FPGA manager object
- * @value:      Value INIT_B to wait for (1 = asserted = low)
- * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
- *
- * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
- * too much time passed waiting for that. If no INIT_B GPIO is available
- * then always return 0.
- */
-static int wait_for_init_b(struct fpga_manager *mgr, int value,
-			   unsigned long alt_udelay)
-{
-	struct xilinx_spi_conf *conf = mgr->priv;
-	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
-
-	if (conf->init_b) {
-		while (time_before(jiffies, timeout)) {
-			int ret = gpiod_get_value(conf->init_b);
-
-			if (ret == value)
-				return 0;
-
-			if (ret < 0) {
-				dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
-				return ret;
-			}
-
-			usleep_range(100, 400);
-		}
-
-		dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n",
-			value ? "assert" : "deassert");
-		return -ETIMEDOUT;
-	}
-
-	udelay(alt_udelay);
-
-	return 0;
-}
-
-static int xilinx_spi_write_init(struct fpga_manager *mgr,
-				 struct fpga_image_info *info,
-				 const char *buf, size_t count)
-{
-	struct xilinx_spi_conf *conf = mgr->priv;
-	int err;
-
-	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
-		dev_err(&mgr->dev, "Partial reconfiguration not supported\n");
-		return -EINVAL;
-	}
-
-	gpiod_set_value(conf->prog_b, 1);
-
-	err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */
-	if (err) {
-		gpiod_set_value(conf->prog_b, 0);
-		return err;
-	}
-
-	gpiod_set_value(conf->prog_b, 0);
+#define to_xilinx_spi_conf(obj) container_of(obj, struct xilinx_spi_conf, core)
 
-	err = wait_for_init_b(mgr, 0, 0);
-	if (err)
-		return err;
-
-	if (get_done_gpio(mgr)) {
-		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
-		return -EIO;
-	}
-
-	/* program latency */
-	usleep_range(7500, 7600);
-	return 0;
-}
-
-static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
+static int xilinx_spi_write(struct xilinx_fpga_core *core, const char *buf,
 			    size_t count)
 {
-	struct xilinx_spi_conf *conf = mgr->priv;
+	struct xilinx_spi_conf *conf = to_xilinx_spi_conf(core);
 	const char *fw_data = buf;
 	const char *fw_data_end = fw_data + count;
 
@@ -143,7 +40,7 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
 
 		ret = spi_write(conf->spi, fw_data, stride);
 		if (ret) {
-			dev_err(&mgr->dev, "SPI error in firmware write: %d\n",
+			dev_err(core->dev, "SPI error in firmware write: %d\n",
 				ret);
 			return ret;
 		}
@@ -153,109 +50,26 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
 	return 0;
 }
 
-static int xilinx_spi_apply_cclk_cycles(struct xilinx_spi_conf *conf)
-{
-	struct spi_device *spi = conf->spi;
-	const u8 din_data[1] = { 0xff };
-	int ret;
-
-	ret = spi_write(conf->spi, din_data, sizeof(din_data));
-	if (ret)
-		dev_err(&spi->dev, "applying CCLK cycles failed: %d\n", ret);
-
-	return ret;
-}
-
-static int xilinx_spi_write_complete(struct fpga_manager *mgr,
-				     struct fpga_image_info *info)
-{
-	struct xilinx_spi_conf *conf = mgr->priv;
-	unsigned long timeout = jiffies + usecs_to_jiffies(info->config_complete_timeout_us);
-	bool expired = false;
-	int done;
-	int ret;
-
-	/*
-	 * This loop is carefully written such that if the driver is
-	 * scheduled out for more than 'timeout', we still check for DONE
-	 * before giving up and we apply 8 extra CCLK cycles in all cases.
-	 */
-	while (!expired) {
-		expired = time_after(jiffies, timeout);
-
-		done = get_done_gpio(mgr);
-		if (done < 0)
-			return done;
-
-		ret = xilinx_spi_apply_cclk_cycles(conf);
-		if (ret)
-			return ret;
-
-		if (done)
-			return 0;
-	}
-
-	if (conf->init_b) {
-		ret = gpiod_get_value(conf->init_b);
-
-		if (ret < 0) {
-			dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
-			return ret;
-		}
-
-		dev_err(&mgr->dev,
-			ret ? "CRC error or invalid device\n"
-			: "Missing sync word or incomplete bitstream\n");
-	} else {
-		dev_err(&mgr->dev, "Timeout after config data transfer\n");
-	}
-
-	return -ETIMEDOUT;
-}
-
-static const struct fpga_manager_ops xilinx_spi_ops = {
-	.state = xilinx_spi_state,
-	.write_init = xilinx_spi_write_init,
-	.write = xilinx_spi_write,
-	.write_complete = xilinx_spi_write_complete,
-};
-
 static int xilinx_spi_probe(struct spi_device *spi)
 {
 	struct xilinx_spi_conf *conf;
-	struct fpga_manager *mgr;
 
 	conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL);
 	if (!conf)
 		return -ENOMEM;
 
+	conf->core.dev = &spi->dev;
+	conf->core.write = xilinx_spi_write;
 	conf->spi = spi;
 
-	/* PROGRAM_B is active low */
-	conf->prog_b = devm_gpiod_get(&spi->dev, "prog_b", GPIOD_OUT_LOW);
-	if (IS_ERR(conf->prog_b))
-		return dev_err_probe(&spi->dev, PTR_ERR(conf->prog_b),
-				     "Failed to get PROGRAM_B gpio\n");
-
-	conf->init_b = devm_gpiod_get_optional(&spi->dev, "init-b", GPIOD_IN);
-	if (IS_ERR(conf->init_b))
-		return dev_err_probe(&spi->dev, PTR_ERR(conf->init_b),
-				     "Failed to get INIT_B gpio\n");
-
-	conf->done = devm_gpiod_get(&spi->dev, "done", GPIOD_IN);
-	if (IS_ERR(conf->done))
-		return dev_err_probe(&spi->dev, PTR_ERR(conf->done),
-				     "Failed to get DONE gpio\n");
-
-	mgr = devm_fpga_mgr_register(&spi->dev,
-				     "Xilinx Slave Serial FPGA Manager",
-				     &xilinx_spi_ops, conf);
-	return PTR_ERR_OR_ZERO(mgr);
+	return xilinx_core_probe(&conf->core);
 }
 
 #ifdef CONFIG_OF
 static const struct of_device_id xlnx_spi_of_match[] = {
-	{ .compatible = "xlnx,fpga-slave-serial", },
+	{
+		.compatible = "xlnx,fpga-slave-serial",
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, xlnx_spi_of_match);
-- 
2.43.0



From charles.perry at savoirfairelinux.com  Wed Feb 21 11:50:49 2024
From: charles.perry at savoirfairelinux.com (Charles Perry)
Date: Wed, 21 Feb 2024 14:50:49 -0500
Subject: [PATCH v4 3/3] fpga: xilinx-selectmap: add new driver
In-Reply-To: <20240221195058.1281973-1-charles.perry@savoirfairelinux.com>
References: <20240221195058.1281973-1-charles.perry@savoirfairelinux.com>
Message-ID: <20240221195058.1281973-4-charles.perry@savoirfairelinux.com>

Xilinx 7 series FPGA can be programmed using a parallel port named
the SelectMAP interface in the datasheet. This interface is compatible
with the i.MX6 EIM bus controller but other types of external memory
mapped parallel bus might work.

xilinx-selectmap currently only supports the x8 mode where data is loaded
at one byte per rising edge of the clock, with the MSb of each byte
presented to the D0 pin.

Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
---
 drivers/fpga/Kconfig            |  8 +++
 drivers/fpga/Makefile           |  1 +
 drivers/fpga/xilinx-selectmap.c | 97 +++++++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+)
 create mode 100644 drivers/fpga/xilinx-selectmap.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index d27a1ebf40838..37b35f58f0dfb 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -67,6 +67,14 @@ config FPGA_MGR_STRATIX10_SOC
 config FPGA_MGR_XILINX_CORE
 	tristate
 
+config FPGA_MGR_XILINX_SELECTMAP
+	tristate "Xilinx Configuration over SelectMAP"
+	depends on HAS_IOMEM
+	select FPGA_MGR_XILINX_CORE
+	help
+	  FPGA manager driver support for Xilinx FPGA configuration
+	  over SelectMAP interface.
+
 config FPGA_MGR_XILINX_SPI
 	tristate "Xilinx Configuration over Slave Serial (SPI)"
 	depends on SPI
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 7ec795b6a5a70..aeb89bb13517e 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
 obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC)	+= stratix10-soc.o
 obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
 obj-$(CONFIG_FPGA_MGR_XILINX_CORE)	+= xilinx-core.o
+obj-$(CONFIG_FPGA_MGR_XILINX_SELECTMAP)	+= xilinx-selectmap.o
 obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
 obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
 obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA)	+= zynqmp-fpga.o
diff --git a/drivers/fpga/xilinx-selectmap.c b/drivers/fpga/xilinx-selectmap.c
new file mode 100644
index 0000000000000..b63f4623f8b2c
--- /dev/null
+++ b/drivers/fpga/xilinx-selectmap.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Xilinx Spartan6 and 7 Series SelectMAP interface driver
+ *
+ * (C) 2024 Charles Perry <charles.perry at savoirfairelinux.com>
+ *
+ * Manage Xilinx FPGA firmware loaded over the SelectMAP configuration
+ * interface.
+ */
+
+#include "xilinx-core.h"
+
+#include <linux/platform_device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/io.h>
+
+struct xilinx_selectmap_conf {
+	struct xilinx_fpga_core core;
+	void __iomem *base;
+};
+
+#define to_xilinx_selectmap_conf(obj) \
+	container_of(obj, struct xilinx_selectmap_conf, core)
+
+static int xilinx_selectmap_write(struct xilinx_fpga_core *core,
+				  const char *buf, size_t count)
+{
+	struct xilinx_selectmap_conf *conf = to_xilinx_selectmap_conf(core);
+	u32 i;
+
+	for (i = 0; i < count; ++i)
+		writeb(buf[i], conf->base);
+
+	return 0;
+}
+
+static int xilinx_selectmap_probe(struct platform_device *pdev)
+{
+	struct xilinx_selectmap_conf *conf;
+	struct resource *r;
+	void __iomem *base;
+	struct gpio_desc *csi_b;
+	struct gpio_desc *rdwr_b;
+
+	conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL);
+	if (!conf)
+		return -ENOMEM;
+
+	conf->core.dev = &pdev->dev;
+	conf->core.write = xilinx_selectmap_write;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
+	if (IS_ERR(base))
+		return dev_err_probe(&pdev->dev, PTR_ERR(base),
+				     "ioremap error\n");
+	conf->base = base;
+
+	/* CSI_B is active low */
+	csi_b = devm_gpiod_get_optional(&pdev->dev, "csi", GPIOD_OUT_HIGH);
+	if (IS_ERR(csi_b))
+		return dev_err_probe(&pdev->dev, PTR_ERR(csi_b),
+				     "Failed to get CSI_B gpio\n");
+
+	/* RDWR_B is active low */
+	rdwr_b = devm_gpiod_get_optional(&pdev->dev, "rdwr", GPIOD_OUT_HIGH);
+	if (IS_ERR(rdwr_b))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rdwr_b),
+				     "Failed to get RDWR_B gpio\n");
+
+	return xilinx_core_probe(&conf->core);
+}
+
+static const struct of_device_id xlnx_selectmap_of_match[] = {
+	{ .compatible = "xlnx,fpga-xc7s-selectmap", }, // Spartan-7
+	{ .compatible = "xlnx,fpga-xc7a-selectmap", }, // Artix-7
+	{ .compatible = "xlnx,fpga-xc7k-selectmap", }, // Kintex-7
+	{ .compatible = "xlnx,fpga-xc7v-selectmap", }, // Virtex-7
+	{},
+};
+MODULE_DEVICE_TABLE(of, xlnx_selectmap_of_match);
+
+static struct platform_driver xilinx_selectmap_driver = {
+	.driver = {
+		.name = "xilinx-selectmap",
+		.of_match_table = xlnx_selectmap_of_match,
+	},
+	.probe  = xilinx_selectmap_probe,
+};
+
+module_platform_driver(xilinx_selectmap_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Charles Perry <charles.perry at savoirfairelinux.com>");
+MODULE_DESCRIPTION("Load Xilinx FPGA firmware over SelectMap");
-- 
2.43.0



From akpm at linux-foundation.org  Wed Feb 21 12:12:05 2024
From: akpm at linux-foundation.org (Andrew Morton)
Date: Wed, 21 Feb 2024 12:12:05 -0800
Subject: [PATCH v2 01/14] kexec: split crashkernel reservation code out
 from crash_core.c
In-Reply-To: <e1bd53c6-ad9a-46d5-9f49-ecdd64d98f61@linux.ibm.com>
References: <20240119145241.769622-1-bhe@redhat.com>
	<20240119145241.769622-2-bhe@redhat.com>
	<e1bd53c6-ad9a-46d5-9f49-ecdd64d98f61@linux.ibm.com>
Message-ID: <20240221121205.00202fab8c1732bc433a845f@linux-foundation.org>

On Wed, 21 Feb 2024 22:59:47 +0530 Sourabh Jain <sourabhjain at linux.ibm.com> wrote:

> >   config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
> > -	def_bool CRASH_CORE
> > +	def_bool CRASH_RESEERVE
> 
> %s/CRASH_RESEERVE/CRASH_RESERVE? 

Yes, thanks, this has been addressed in a followon fixup patch
in the mm.git tree.


From dalias at libc.org  Wed Feb 21 12:18:37 2024
From: dalias at libc.org (dalias at libc.org)
Date: Wed, 21 Feb 2024 15:18:37 -0500
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <e3a432c0fa9f5fe837e9d2fc7b36304709a34428.camel@intel.com>
References: <20240221012736.GQ4163@brightrain.aerifal.cx>
 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx>
 <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
 <20240221175717.GS4163@brightrain.aerifal.cx>
 <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>
 <20240221183055.GT4163@brightrain.aerifal.cx>
 <c3085fbe10193dfe59b25bc7da776e60779b0e8c.camel@intel.com>
 <20240221190639.GU4163@brightrain.aerifal.cx>
 <e3a432c0fa9f5fe837e9d2fc7b36304709a34428.camel@intel.com>
Message-ID: <20240221201837.GW4163@brightrain.aerifal.cx>

On Wed, Feb 21, 2024 at 07:22:21PM +0000, Edgecombe, Rick P wrote:
> On Wed, 2024-02-21 at 14:06 -0500, dalias at libc.org wrote:
> > Due to arbitrarily nestable signal frames, no, this does not suffice.
> > An interrupted operation using the lock could be arbitrarily delayed,
> > even never execute again, making any call to dlopen deadlock.
> 
> Doh! Yep, it is not robust to this. The only thing that could be done
> would be a timeout in dlopen(). Which would make the whole thing just
> better than nothing.
> 
> > 
> > > 
> > 
> > It's fine to turn RDSSP into an actual emulated read of the SSP, or
> > at
> > least an emulated load of zero so that uninitialized data is not left
> > in the target register.
> 
> We can't intercept RDSSP, but it becomes a NOP by default. (disclaimer
> x86-only knowledge).

OK, then I think the contract just has to be that userspace, in a
process that might dynamically disable shadow stack, needs to do
something like xor %reg,%reg before rdssp so that the outcome is
deterministic in disabled case.

> >  If doing the latter, code working with the
> > shadow stack just needs to be prepared for the possibility that it
> > could be async-disabled, and check the return value.
> > 
> > I have not looked at all the instructions that become #UD but I
> > suspect they all have reasonable trivial ways to implement a
> > "disabled" version of them that userspace can act upon reasonably.
> 
> This would have to be thought through functionally and performance
> wise. I'm not opposed if can come up with a fully fleshed out plan. How
> serious are you in pursuing musl support, if we had something like
> this?

Up til this thread, my position was pretty much "nope" because it
looked like it could not be done in a way compatible with existing
interface requirements.

However, what's been discussed here, contingent on a dynamic-disable
(ideally allowing choice of per-thread or global, to minimize loss of
hardening properties),

Personally, I believe shadow stack has very low hardening value
relative to cost/complexity, and my leaning would be just to ignore
it. However, I also know it becomes marketing pressure, including
pressure on distros that use musl -- "Why doesn't [distro] do shadow
stack?? I thought you were security oriented!!!" -- and if it can be
done in a non-breaking and non-invasive way, I think it's reasonable
to pursue and make something work.

> HJ, any thoughts on whether glibc would use this as well?
> 
> It is probably worth mentioning that from the security side (as Mark
> mentioned there is always tension in the tradeoffs on these features),
> permissive mode is seen by some as something that weakens security too
> much. Apps could call dlopen() on a known unsupported DSO before doing
> ROP. I don't know if you have any musl users with specific shadow stack
> use cases to ask about this.

Yes, this is potentially an argument for something like the option 2,
if there's a way to leave SS enabled but then trap when something goes
wrong, detect if it went wrong via SS-incompatible library code, and
lazily disable SS, otherwise terminate.

But I just realized, I'm not even sure why shared libraries need to be
explicitly SS-compatible. Unless they're doing their own asm stack
switches, shouldn't they just work by default? And since I don't
understand this reason, I also don't understand what the failure mode
is when an incompatible library is loaded, and thus whether it would
be possible to detect and attribute the failure to the library, or
whether the library would induce failure somewhere else.

Anyway, a mechanism to allow the userspace implementation to disable
SS doesn't inherently expose a means to do that. A system integrator
doing maximum hardening might choose to build all libraries as
SS-compatible, or to patch the loader to refuse to load incompatible
libraries.

Rich


From hjl.tools at gmail.com  Wed Feb 21 12:18:37 2024
From: hjl.tools at gmail.com (H.J. Lu)
Date: Wed, 21 Feb 2024 12:18:37 -0800
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in userspace
In-Reply-To: <e3a432c0fa9f5fe837e9d2fc7b36304709a34428.camel@intel.com>
References: <20240220235415.GP4163@brightrain.aerifal.cx> <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx> <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx> <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
 <20240221175717.GS4163@brightrain.aerifal.cx> <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>
 <20240221183055.GT4163@brightrain.aerifal.cx> <c3085fbe10193dfe59b25bc7da776e60779b0e8c.camel@intel.com>
 <20240221190639.GU4163@brightrain.aerifal.cx> <e3a432c0fa9f5fe837e9d2fc7b36304709a34428.camel@intel.com>
Message-ID: <CAMe9rOoUO-D7Uoj9s3eq+w9pJBZ=iucEDpU4hqtJYtPmW5T4dQ@mail.gmail.com>

On Wed, Feb 21, 2024 at 11:22?AM Edgecombe, Rick P
<rick.p.edgecombe at intel.com> wrote:
>
> On Wed, 2024-02-21 at 14:06 -0500, dalias at libc.org wrote:
> > Due to arbitrarily nestable signal frames, no, this does not suffice.
> > An interrupted operation using the lock could be arbitrarily delayed,
> > even never execute again, making any call to dlopen deadlock.
>
> Doh! Yep, it is not robust to this. The only thing that could be done
> would be a timeout in dlopen(). Which would make the whole thing just
> better than nothing.
>
> >
> > >
> >
> > It's fine to turn RDSSP into an actual emulated read of the SSP, or
> > at
> > least an emulated load of zero so that uninitialized data is not left
> > in the target register.
>
> We can't intercept RDSSP, but it becomes a NOP by default. (disclaimer
> x86-only knowledge).
>
> >  If doing the latter, code working with the
> > shadow stack just needs to be prepared for the possibility that it
> > could be async-disabled, and check the return value.
> >
> > I have not looked at all the instructions that become #UD but I
> > suspect they all have reasonable trivial ways to implement a
> > "disabled" version of them that userspace can act upon reasonably.
>
> This would have to be thought through functionally and performance
> wise. I'm not opposed if can come up with a fully fleshed out plan. How
> serious are you in pursuing musl support, if we had something like
> this?
>
> HJ, any thoughts on whether glibc would use this as well?

Assuming that we are talking about permissive mode,  if kernel can
suppress UD, we don't need to disable SHSTK.   Glibc can enable
ARCH_SHSTK_SUPPRESS_UD instead.

> It is probably worth mentioning that from the security side (as Mark
> mentioned there is always tension in the tradeoffs on these features),
> permissive mode is seen by some as something that weakens security too
> much. Apps could call dlopen() on a known unsupported DSO before doing
> ROP. I don't know if you have any musl users with specific shadow stack
> use cases to ask about this.



-- 
H.J.


From irogers at google.com  Wed Feb 21 12:19:22 2024
From: irogers at google.com (Ian Rogers)
Date: Wed, 21 Feb 2024 12:19:22 -0800
Subject: [PATCH v2] perf print-events: make is_event_supported() more robust
In-Reply-To: <20240126145605.1005472-1-mark.rutland@arm.com>
References: <20240126145605.1005472-1-mark.rutland@arm.com>
Message-ID: <CAP-5=fURS0OQxHcukS1+NprgyMpAQSr3+BMiYPj5x7=+tcZ8hw@mail.gmail.com>

On Fri, Jan 26, 2024 at 6:56?AM Mark Rutland <mark.rutland at arm.com> wrote:
>
> Currently the perf tool doesn't detect support for extended event types
> on Apple M1/M2 systems, and will not auto-expand plain PERF_EVENT_TYPE
> hardware events into per-PMU events. This is due to the detection of
> extended event types not handling mandatory filters required by the
> M1/M2 PMU driver.
>
> PMU drivers and the core perf_events code can require that
> perf_event_attr::exclude_* filters are configured in a specific way and
> may reject certain configurations of filters, for example:
>
> (a) Many PMUs lack support for any event filtering, and require all
>     perf_event_attr::exclude_* bits to be clear. This includes Alpha's
>     CPU PMU, and ARM CPU PMUs prior to the introduction of PMUv2 in
>     ARMv7,
>
> (b) When /proc/sys/kernel/perf_event_paranoid >= 2, the perf core
>     requires that perf_event_attr::exclude_kernel is set.
>
> (c) The Apple M1/M2 PMU requires that perf_event_attr::exclude_guest is
>     set as the hardware PMU does not count while a guest is running (but
>     might be extended in future to do so).
>
> In is_event_supported(), we try to account for cases (a) and (b), first
> attempting to open an event without any filters, and if this fails,
> retrying with perf_event_attr::exclude_kernel set. We do not account for
> case (c), or any other filters that drivers could theoretically require
> to be set.
>
> Thus is_event_supported() will fail to detect support for any events
> targeting an Apple M1/M2 PMU, even where events would be supported with
> perf_event_attr:::exclude_guest set.
>
> Since commit:
>
>   82fe2e45cdb00de4 ("perf pmus: Check if we can encode the PMU number in perf_event_attr.type")
>
> ... we use is_event_supported() to detect support for extended types,
> with the PMU ID encoded into the perf_event_attr::type. As above, on an
> Apple M1/M2 system this will always fail to detect that the event is
> supported, and consequently we fail to detect support for extended types
> even when these are supported, as they have been since commit:
>
>   5c816728651ae425 ("arm_pmu: Add PERF_PMU_CAP_EXTENDED_HW_TYPE capability")
>
> Due to this, the perf tool will not automatically expand plain
> PERF_TYPE_HARDWARE events into per-PMU events, even when all the
> necessary kernel support is present.
>
> This patch updates is_event_supported() to additionally try opening
> events with perf_event_attr::exclude_guest set, allowing support for
> events to be detected on Apple M1/M2 systems. I believe that this is
> sufficient for all contemporary CPU PMU drivers, though in future it may
> be necessary to check for other combinations of filter bits.
>
> I've deliberately changed the check to not expect a specific error code
> for missing filters, as today ;the kernel may return a number of
> different error codes for missing filters (e.g. -EACCESS, -EINVAL, or
> -EOPNOTSUPP) depending on why and where the filter configuration is
> rejected, and retrying for any error is more robust.
>
> Note that this does not remove the need for commit:
>
>   a24d9d9dc096fc0d ("perf parse-events: Make legacy events lower priority than sysfs/JSON")
>
> ... which is still necessary so that named-pmu/event/ events work on
> kernels without extended type support, even if the event name happens to
> be the same as a PERF_EVENT_TYPE_HARDWARE event (e.g. as is the case for
> the M1/M2 PMU's 'cycles' and 'instructions' events).
>
> Fixes: 82fe2e45cdb00de4 ("perf pmus: Check if we can encode the PMU number in perf_event_attr.type")
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Tested-by: Ian Rogers <irogers at google.com>
> Tested-by: James Clark <james.clark at arm.com>
> Cc: Arnaldo Carvalho de Melo <acme at redhat.com>
> Cc: Hector Martin <marcan at marcan.st>
> Cc: Ian Rogers <irogers at google.com>
> Cc: James Clark <james.clark at arm.com>
> Cc: John Garry <john.g.garry at oracle.com>
> Cc: Leo Yan <leo.yan at linaro.org>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Namhyung Kim <namhyung at kernel.org>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Thomas Richter <tmricht at linux.ibm.com>
> Cc: Will Deacon <will at kernel.org>

Ping. Could we land this one?

Thanks,
Ian

> ---
>  tools/perf/util/print-events.c | 27 +++++++++++++++++++--------
>  1 file changed, 19 insertions(+), 8 deletions(-)
>
> Since v1 [1]:
> * Fix typos in commit message
> * Accumulate tags
>
> [1] https://lore.kernel.org/lkml/20240116170348.463479-1-mark.rutland at arm.com/
>
> Mark.
>
> diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
> index b0fc48be623f3..4f67e8f00a4d6 100644
> --- a/tools/perf/util/print-events.c
> +++ b/tools/perf/util/print-events.c
> @@ -232,7 +232,6 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
>  bool is_event_supported(u8 type, u64 config)
>  {
>         bool ret = true;
> -       int open_return;
>         struct evsel *evsel;
>         struct perf_event_attr attr = {
>                 .type = type,
> @@ -246,20 +245,32 @@ bool is_event_supported(u8 type, u64 config)
>
>         evsel = evsel__new(&attr);
>         if (evsel) {
> -               open_return = evsel__open(evsel, NULL, tmap);
> -               ret = open_return >= 0;
> +               ret = evsel__open(evsel, NULL, tmap) >= 0;
>
> -               if (open_return == -EACCES) {
> +               if (!ret) {
>                         /*
> -                        * This happens if the paranoid value
> +                        * The event may fail to open if the paranoid value
>                          * /proc/sys/kernel/perf_event_paranoid is set to 2
> -                        * Re-run with exclude_kernel set; we don't do that
> -                        * by default as some ARM machines do not support it.
> -                        *
> +                        * Re-run with exclude_kernel set; we don't do that by
> +                        * default as some ARM machines do not support it.
>                          */
>                         evsel->core.attr.exclude_kernel = 1;
>                         ret = evsel__open(evsel, NULL, tmap) >= 0;
>                 }
> +
> +               if (!ret) {
> +                       /*
> +                        * The event may fail to open if the PMU requires
> +                        * exclude_guest to be set (e.g. as the Apple M1 PMU
> +                        * requires).
> +                        * Re-run with exclude_guest set; we don't do that by
> +                        * default as it's equally legitimate for another PMU
> +                        * driver to require that exclude_guest is clear.
> +                        */
> +                       evsel->core.attr.exclude_guest = 1;
> +                       ret = evsel__open(evsel, NULL, tmap) >= 0;
> +               }
> +
>                 evsel__delete(evsel);
>         }
>
> --
> 2.30.2
>


From mka at chromium.org  Wed Feb 21 12:25:16 2024
From: mka at chromium.org (Matthias Kaehlcke)
Date: Wed, 21 Feb 2024 20:25:16 +0000
Subject: [PATCH v4 6/8] usb: misc: onboard_dev: use device supply names
In-Reply-To: <20240220-onboard_xvf3500-v4-6-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
 <20240220-onboard_xvf3500-v4-6-dc1617cc5dd4@wolfvision.net>
Message-ID: <ZdZcLOlSc3FScjLK@google.com>

On Tue, Feb 20, 2024 at 03:05:50PM +0100, Javier Carrasco wrote:
> The current mechanism uses generic names for the power supplies, which
> conflicts with proper name definitions in the device bindings.
> 
> Add a per-device property to include real supply names and keep generic
> names as a fallback mechanism for backward compatibility.
> 
> Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
> ---
>  drivers/usb/misc/onboard_usb_dev.c | 54 ++++++++++++++++++++------------------
>  drivers/usb/misc/onboard_usb_dev.h | 23 ++++++++++++++++
>  2 files changed, 52 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
> index f43130a6786f..e66fcac93006 100644
> --- a/drivers/usb/misc/onboard_usb_dev.c
> +++ b/drivers/usb/misc/onboard_usb_dev.c
> @@ -29,18 +29,6 @@
>  
>  #include "onboard_usb_dev.h"
>  
> -/*
> - * Use generic names, as the actual names might differ between devices. If a new
> - * device requires more than the currently supported supplies, add a new one
> - * here.
> - */
> -static const char * const supply_names[] = {
> -	"vdd",
> -	"vdd2",
> -};
> -
> -#define MAX_SUPPLIES ARRAY_SIZE(supply_names)
> -
>  static void onboard_dev_attach_usb_driver(struct work_struct *work);
>  
>  static struct usb_device_driver onboard_dev_usbdev_driver;
> @@ -66,6 +54,33 @@ struct onboard_dev {
>  	struct clk *clk;
>  };
>  
> +static int onboard_dev_get_regulator_bulk(struct device *dev,
> +					  struct onboard_dev *onboard_dev)
> +{
> +	unsigned int i;
> +	int err;
> +
> +	const char * const *supply_names = onboard_dev->pdata->supply_names;
> +
> +	if (onboard_dev->pdata->num_supplies > MAX_SUPPLIES)
> +		return dev_err_probe(dev, -EINVAL, "max %zu supplies supported!\n",
> +				     MAX_SUPPLIES);
> +
> +	if (!supply_names[0])
> +		supply_names = generic_supply_names;

Please change to 'if (!supply_names)' and omit the initialization of
.supply_names for devices that use the generic supply names.

> diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h
> index ebe83e19d818..59dced6bd339 100644
> --- a/drivers/usb/misc/onboard_usb_dev.h
> +++ b/drivers/usb/misc/onboard_usb_dev.h
> @@ -6,63 +6,86 @@
>  #ifndef _USB_MISC_ONBOARD_USB_DEV_H
>  #define _USB_MISC_ONBOARD_USB_DEV_H
>  
> +/*
> + * Fallback supply names for backwards compatibility. If the device requires
> + * more than the currently supported supplies, add a new one here, and if
> + * possible, the real name supplies to the device-specific data.
> + */
> +static const char * const generic_supply_names[] = {
> +	"vdd",
> +	"vdd2",
> +};
> +
> +#define MAX_SUPPLIES ARRAY_SIZE(generic_supply_names)

This will have to change when support for a device with more than 2 non-generic
supply names gets added. Please use a literal value for MAX_SUPPLIES instead of
ARRAY_SIZE. If the literal is 2 it would still need to change for future devices
with more supplies, but that change would be more straighforward.

> +
>  struct onboard_dev_pdata {
>  	unsigned long reset_us;		/* reset pulse width in us */
>  	unsigned int num_supplies;	/* number of supplies */
>  	bool is_hub;
> +	const char * const supply_names[MAX_SUPPLIES];
> +
>  };
>  
>  static const struct onboard_dev_pdata microchip_usb424_data = {
>  	.reset_us = 1,
>  	.num_supplies = 1,
> +	.supply_names = { NULL },
>  	.is_hub = true,
>  };
>
> ...


From hjl.tools at gmail.com  Wed Feb 21 12:25:06 2024
From: hjl.tools at gmail.com (H.J. Lu)
Date: Wed, 21 Feb 2024 12:25:06 -0800
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in userspace
In-Reply-To: <CAMe9rOoUO-D7Uoj9s3eq+w9pJBZ=iucEDpU4hqtJYtPmW5T4dQ@mail.gmail.com>
References: <20240220235415.GP4163@brightrain.aerifal.cx> <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx> <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx> <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
 <20240221175717.GS4163@brightrain.aerifal.cx> <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>
 <20240221183055.GT4163@brightrain.aerifal.cx> <c3085fbe10193dfe59b25bc7da776e60779b0e8c.camel@intel.com>
 <20240221190639.GU4163@brightrain.aerifal.cx> <e3a432c0fa9f5fe837e9d2fc7b36304709a34428.camel@intel.com>
 <CAMe9rOoUO-D7Uoj9s3eq+w9pJBZ=iucEDpU4hqtJYtPmW5T4dQ@mail.gmail.com>
Message-ID: <CAMe9rOr1frpnKSnVQrqeiKK3aAR3xpG=VAiPYLOR9OpHnHhYUw@mail.gmail.com>

On Wed, Feb 21, 2024 at 12:18?PM H.J. Lu <hjl.tools at gmail.com> wrote:
>
> On Wed, Feb 21, 2024 at 11:22?AM Edgecombe, Rick P
> <rick.p.edgecombe at intel.com> wrote:
> >
> > On Wed, 2024-02-21 at 14:06 -0500, dalias at libc.org wrote:
> > > Due to arbitrarily nestable signal frames, no, this does not suffice.
> > > An interrupted operation using the lock could be arbitrarily delayed,
> > > even never execute again, making any call to dlopen deadlock.
> >
> > Doh! Yep, it is not robust to this. The only thing that could be done
> > would be a timeout in dlopen(). Which would make the whole thing just
> > better than nothing.
> >
> > >
> > > >
> > >
> > > It's fine to turn RDSSP into an actual emulated read of the SSP, or
> > > at
> > > least an emulated load of zero so that uninitialized data is not left
> > > in the target register.
> >
> > We can't intercept RDSSP, but it becomes a NOP by default. (disclaimer
> > x86-only knowledge).
> >
> > >  If doing the latter, code working with the
> > > shadow stack just needs to be prepared for the possibility that it
> > > could be async-disabled, and check the return value.
> > >
> > > I have not looked at all the instructions that become #UD but I
> > > suspect they all have reasonable trivial ways to implement a
> > > "disabled" version of them that userspace can act upon reasonably.
> >
> > This would have to be thought through functionally and performance
> > wise. I'm not opposed if can come up with a fully fleshed out plan. How
> > serious are you in pursuing musl support, if we had something like
> > this?
> >
> > HJ, any thoughts on whether glibc would use this as well?
>
> Assuming that we are talking about permissive mode,  if kernel can
> suppress UD, we don't need to disable SHSTK.   Glibc can enable
> ARCH_SHSTK_SUPPRESS_UD instead.

Kernel must suppress all possible SHSTK UDs.

> > It is probably worth mentioning that from the security side (as Mark
> > mentioned there is always tension in the tradeoffs on these features),
> > permissive mode is seen by some as something that weakens security too
> > much. Apps could call dlopen() on a known unsupported DSO before doing
> > ROP. I don't know if you have any musl users with specific shadow stack
> > use cases to ask about this.
>
>
>
> --
> H.J.



-- 
H.J.


From atishp at rivosinc.com  Wed Feb 21 12:29:13 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Wed, 21 Feb 2024 12:29:13 -0800
Subject: [PATCH v5 11/12] KVM: riscv: selftests: Change vcpu_has_ext to a
 common function
In-Reply-To: <CAJve8omCZxsiP1jF0n5SBh0_U6q7Exj5A1ACFahWpdBoxohaMA@mail.gmail.com>
References: <cover.1705916069.git.haibo1.xu@intel.com>
 <68856b86a93a4188558e5d0ebac0dd6aac8e404c.1705916069.git.haibo1.xu@intel.com>
 <CAOnJCULwRTSnrQkR2o1P53R=tJ3TAxX+y+XRBesW6OFEzgFv2g@mail.gmail.com>
 <CAJve8om2oOLg5-wKX7m7cBTgzwqiMcb35x=nDi1edY8evXjyMw@mail.gmail.com>
 <2c96c61a-2685-4cee-9cef-963ed833bf92@rivosinc.com>
 <CAJve8omCZxsiP1jF0n5SBh0_U6q7Exj5A1ACFahWpdBoxohaMA@mail.gmail.com>
Message-ID: <b5673bce-09e7-4531-a074-e252aa9e38e8@rivosinc.com>

On 2/21/24 05:08, Haibo Xu wrote:
> On Wed, Feb 21, 2024 at 4:37?PM Atish Patra <atishp at rivosinc.com> wrote:
>>
>> On 2/20/24 18:13, Haibo Xu wrote:
>>> On Wed, Feb 21, 2024 at 7:03?AM Atish Patra <atishp at atishpatra.org> wrote:
>>>>
>>>> On Mon, Jan 22, 2024 at 1:48?AM Haibo Xu <haibo1.xu at intel.com> wrote:
>>>>>
>>>>> Move vcpu_has_ext to the processor.c and rename it to __vcpu_has_ext
>>>>> so that other test cases can use it for vCPU extension check.
>>>>>
>>>>> Signed-off-by: Haibo Xu <haibo1.xu at intel.com>
>>>>> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
>>>>> ---
>>>>>    tools/testing/selftests/kvm/include/riscv/processor.h |  2 ++
>>>>>    tools/testing/selftests/kvm/lib/riscv/processor.c     | 10 ++++++++++
>>>>>    tools/testing/selftests/kvm/riscv/get-reg-list.c      | 11 +----------
>>>>>    3 files changed, 13 insertions(+), 10 deletions(-)
>>>>>
>>>>> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
>>>>> index b68b1b731a34..bd27e1c67579 100644
>>>>> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
>>>>> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
>>>>> @@ -42,6 +42,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
>>>>>    #define RISCV_ISA_EXT_REG(idx) __kvm_reg_id(KVM_REG_RISCV_ISA_EXT, \
>>>>>                                                idx, KVM_REG_SIZE_ULONG)
>>>>>
>>>>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
>>>>> +
>>>>>    struct ex_regs {
>>>>>           unsigned long ra;
>>>>>           unsigned long sp;
>>>>> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
>>>>> index 39a1e9902dec..dad73ce18164 100644
>>>>> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
>>>>> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
>>>>> @@ -15,6 +15,16 @@
>>>>>
>>>>>    static vm_vaddr_t exception_handlers;
>>>>>
>>>>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
>>>>> +{
>>>>> +       unsigned long value = 0;
>>>>> +       int ret;
>>>>> +
>>>>> +       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
>>>>> +
>>>>> +       return !ret && !!value;
>>>>> +}
>>>>> +
>>>>
>>>> Not sure what was the base patch on which this was rebased. The actual
>>>> commit in the queue branch looks different.
>>>>
>>>
>>> This patch set was based on 6.7-rc8.
>>>
>>>> https://github.com/kvm-riscv/linux/commit/5563517cc2012e3326411b360c9924d3f2706c8d
>>>>
>>>> Both seem to have the same bug though the tests fail now and require
>>>> the following fix.
>>>> The ext id should be uint64_t and we need to pass ext directly so that
>>>> SBI extension tests can also pass.
>>>>
>>>
>>> It's weird that 6.7-rc8 has already included Andrew's change on the ISA ext reg,
>>> but this patch was not generated against his change.
>>>
>>> commit bdf6aa328f137e184b0fce607fd585354c3742f1
>>> Author: Andrew Jones <ajones at ventanamicro.com>
>>> Date:   Wed Dec 13 18:09:58 2023 +0100
>>>
>>>       RISC-V: KVM: selftests: Treat SBI ext regs like ISA ext regs
>>>
>>> Anyway, your changes were right. Please go ahead to include them when merging.
>>>
>>
>> I am not sure what happened. Probably, a merge conflict issue.
>>
>> I just realized I forgot to copy paste another fix in arch timer
>>
>> +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
>> @@ -85,7 +85,7 @@ struct kvm_vm *test_vm_create(void)
>>           int nr_vcpus = test_args.nr_vcpus;
>>
>>           vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
>> -       __TEST_REQUIRE(__vcpu_has_ext(vcpus[0], KVM_RISCV_ISA_EXT_SSTC),
>> +       __TEST_REQUIRE(__vcpu_has_ext(vcpus[0],
>> RISCV_ISA_EXT_REG(KVM_RISCV_ISA_EXT_SSTC)),
>>
> 
> Right Fix!
> Please let me know if I need to rebase this patch series on your tree
> and resent it.
> 

That's Anup's call.

> Thanks,
> Haibo
> 
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv



From javier.carrasco at wolfvision.net  Wed Feb 21 12:40:38 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Wed, 21 Feb 2024 21:40:38 +0100
Subject: [PATCH v4 6/8] usb: misc: onboard_dev: use device supply names
In-Reply-To: <ZdZcLOlSc3FScjLK@google.com>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
 <20240220-onboard_xvf3500-v4-6-dc1617cc5dd4@wolfvision.net>
 <ZdZcLOlSc3FScjLK@google.com>
Message-ID: <503d9ea9-9812-498b-a5ee-2579ba8a7ecf@wolfvision.net>

On 21.02.24 21:25, Matthias Kaehlcke wrote:
> On Tue, Feb 20, 2024 at 03:05:50PM +0100, Javier Carrasco wrote:
>> The current mechanism uses generic names for the power supplies, which
>> conflicts with proper name definitions in the device bindings.
>>
>> Add a per-device property to include real supply names and keep generic
>> names as a fallback mechanism for backward compatibility.
>>
>> Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
>> ---
>>  drivers/usb/misc/onboard_usb_dev.c | 54 ++++++++++++++++++++------------------
>>  drivers/usb/misc/onboard_usb_dev.h | 23 ++++++++++++++++
>>  2 files changed, 52 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
>> index f43130a6786f..e66fcac93006 100644
>> --- a/drivers/usb/misc/onboard_usb_dev.c
>> +++ b/drivers/usb/misc/onboard_usb_dev.c
>> @@ -29,18 +29,6 @@
>>  
>>  #include "onboard_usb_dev.h"
>>  
>> -/*
>> - * Use generic names, as the actual names might differ between devices. If a new
>> - * device requires more than the currently supported supplies, add a new one
>> - * here.
>> - */
>> -static const char * const supply_names[] = {
>> -	"vdd",
>> -	"vdd2",
>> -};
>> -
>> -#define MAX_SUPPLIES ARRAY_SIZE(supply_names)
>> -
>>  static void onboard_dev_attach_usb_driver(struct work_struct *work);
>>  
>>  static struct usb_device_driver onboard_dev_usbdev_driver;
>> @@ -66,6 +54,33 @@ struct onboard_dev {
>>  	struct clk *clk;
>>  };
>>  
>> +static int onboard_dev_get_regulator_bulk(struct device *dev,
>> +					  struct onboard_dev *onboard_dev)
>> +{
>> +	unsigned int i;
>> +	int err;
>> +
>> +	const char * const *supply_names = onboard_dev->pdata->supply_names;
>> +
>> +	if (onboard_dev->pdata->num_supplies > MAX_SUPPLIES)
>> +		return dev_err_probe(dev, -EINVAL, "max %zu supplies supported!\n",
>> +				     MAX_SUPPLIES);
>> +
>> +	if (!supply_names[0])
>> +		supply_names = generic_supply_names;
> 
> Please change to 'if (!supply_names)' and omit the initialization of
> .supply_names for devices that use the generic supply names.
> 

That looks much cleaner, I will apply it to the next version.

>> diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h
>> index ebe83e19d818..59dced6bd339 100644
>> --- a/drivers/usb/misc/onboard_usb_dev.h
>> +++ b/drivers/usb/misc/onboard_usb_dev.h
>> @@ -6,63 +6,86 @@
>>  #ifndef _USB_MISC_ONBOARD_USB_DEV_H
>>  #define _USB_MISC_ONBOARD_USB_DEV_H
>>  
>> +/*
>> + * Fallback supply names for backwards compatibility. If the device requires
>> + * more than the currently supported supplies, add a new one here, and if
>> + * possible, the real name supplies to the device-specific data.
>> + */
>> +static const char * const generic_supply_names[] = {
>> +	"vdd",
>> +	"vdd2",
>> +};
>> +
>> +#define MAX_SUPPLIES ARRAY_SIZE(generic_supply_names)
> 
> This will have to change when support for a device with more than 2 non-generic
> supply names gets added. Please use a literal value for MAX_SUPPLIES instead of
> ARRAY_SIZE. If the literal is 2 it would still need to change for future devices
> with more supplies, but that change would be more straighforward.
> 

I am not completely sure about this. Someone could increase MAX_SUPPLIES
without adding a generic name. Actually two modifications will be
necessary for every addition (name and MAX_SUPPLIES). If ARRAY_SIZE is
used, only new names are required, and MAX_SUPPLIES is automatically
increased.

I understand that the whole point of this is getting rid of the generic
names, but we still have to provide generic names for every extra
supply, at least for code consistency and to avoid size mismatches
between real an generic supply names.

>> +
>>  struct onboard_dev_pdata {
>>  	unsigned long reset_us;		/* reset pulse width in us */
>>  	unsigned int num_supplies;	/* number of supplies */
>>  	bool is_hub;
>> +	const char * const supply_names[MAX_SUPPLIES];
>> +
>>  };
>>  
>>  static const struct onboard_dev_pdata microchip_usb424_data = {
>>  	.reset_us = 1,
>>  	.num_supplies = 1,
>> +	.supply_names = { NULL },
>>  	.is_hub = true,
>>  };
>>
>> ...

Thanks again for your feedback.

Best regards,
Javier Carrasco



From shreeya.patel at collabora.com  Wed Feb 21 12:55:46 2024
From: shreeya.patel at collabora.com (Shreeya Patel)
Date: Wed, 21 Feb 2024 20:55:46 +0000
Subject: =?utf-8?q?Re=3A?= [PATCH 2/4] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_media=3A?= Document bindings for HDMI RX Controller
In-Reply-To: <fd3b7ab7-3702-412f-947a-95396dbe1f4c@linaro.org>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
 <20240216094922.257674-3-shreeya.patel@collabora.com> <fd3b7ab7-3702-412f-947a-95396dbe1f4c@linaro.org>
Message-ID: <1048c3-65d66380-b-49a25c80@188726434>

On Friday, February 16, 2024 15:31 IST, Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> wrote:

> On 16/02/2024 10:49, Shreeya Patel wrote:
> > Document bindings for the Synopsys DesignWare HDMI RX Controller.
> > 
> > Reviewed-by: Dmitry Osipenko <dmitry.osipenko at collabora.com>
> > Signed-off-by: Shreeya Patel <shreeya.patel at collabora.com>
> 
> A nit, subject: drop second/last, redundant "bindings for". The
> "dt-bindings" prefix is already stating that these are bindings.
> See also:
> https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18
> 
> > ---
> >  .../bindings/media/snps,dw-hdmi-rx.yaml       | 128 ++++++++++++++++++
> >  1 file changed, 128 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
> > new file mode 100644
> > index 000000000000..a70d96b548ee
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
> > @@ -0,0 +1,128 @@
> > +# SPDX-License-Identifier: (GPL-3.0 OR BSD-2-Clause)
> 
> Use license checkpatch tells you.
> 
> > +# Device Tree bindings for Synopsys DesignWare HDMI RX Controller
> > +
> > +---
> > +$id: http://devicetree.org/schemas/media/snps,dw-hdmi-rx.yaml#
> 
> Why this is a media, not display? Does RX means input? Lack of hardware
> description does not help?
> 

Yes, RX means input and this binding doc is for the HDMI INPUT controller.
I'll add some description in v2

> 
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Synopsys DesignWare HDMI RX Controller
> > +
> > +maintainers:
> > +  - Shreeya Patel <shreeya.patel at collabora.com>
> > +
> 
> description:
> 
> > +properties:
> > +  compatible:
> > +    items:
> > +      - const: rockchip,rk3588-hdmirx-ctrler
> > +      - const: snps,dw-hdmi-rx
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 3
> > +
> > +  interrupt-names:
> > +    items:
> > +      - const: cec
> > +      - const: hdmi
> > +      - const: dma
> > +
> > +  clocks:
> > +    maxItems: 7
> > +
> > +  clock-names:
> > +    items:
> > +      - const: aclk
> > +      - const: audio
> > +      - const: cr_para
> > +      - const: pclk
> > +      - const: ref
> > +      - const: hclk_s_hdmirx
> > +      - const: hclk_vo1
> > +
> > +  power-domains:
> > +    maxItems: 1
> > +
> > +  resets:
> > +    maxItems: 4
> > +
> > +  reset-names:
> > +    items:
> > +      - const: rst_a
> > +      - const: rst_p
> > +      - const: rst_ref
> > +      - const: rst_biu
> 
> Drop rest_ prefix
> 
> > +
> > +  pinctrl-names:
> > +    const: default
> 
> Drop
> 
> > +
> > +  memory-region:
> > +    maxItems: 1
> > +
> > +  hdmirx-5v-detection-gpios:
> > +    description: GPIO specifier for 5V detection.
> 
> Detection of what? Isn't this HPD?
> 
> > +    maxItems: 1
> > +
> > +  rockchip,grf:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description:
> > +      The phandle of the syscon node for the GRF register.
> 
> Instead describe what for. Basically 80% of your description is
> redundant and only "GRF register" brings some information.
> 
> 
> > +
> > +  rockchip,vo1_grf:
> 
> No underscores.
> 
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description:
> > +      The phandle of the syscon node for the VO1 GRF register.
> 
> Same problem.
> 
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - interrupt-names
> > +  - clocks
> > +  - clock-names
> > +  - power-domains
> > +  - resets
> > +  - pinctrl-0
> > +  - pinctrl-names
> 
> Why? Drop.
> 
> > +  - hdmirx-5v-detection-gpios
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/power/rk3588-power.h>
> > +    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
> > +    hdmirx_ctrler: hdmirx-controller at fdee0000 {
> 
> What is hdmirx-controller? Isn't this just hdmi@?
> 

Writing just hdmi would imply hdmi output I think so that name
will not be appropriate here.

> Node names should be generic. See also an explanation and list of
> examples (not exhaustive) in DT specification:
> https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
> 

This documentation doesn't have any generic name for HDMI INPUT
but maybe we can use the name hdmi-receiver like some other existing
binding has it here :-
Documentation/devicetree/bindings/media/i2c/tda1997x.txt

Thanks,
Shreeya Patel
> 
> > +      compatible = "rockchip,rk3588-hdmirx-ctrler", "snps,dw-hdmi-rx";
> > +      reg = <0x0 0xfdee0000 0x0 0x6000>;
> > +      interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>,
> > +                   <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH 0>,
> > +                   <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH 0>;
> 
> 
> 
> Best regards,
> Krzysztof
> 
> _______________________________________________
> Kernel mailing list -- kernel at mailman.collabora.com
> To unsubscribe send an email to kernel-leave at mailman.collabora.com
> This list is managed by https://mailman.collabora.com



From akpm at linux-foundation.org  Wed Feb 21 12:57:52 2024
From: akpm at linux-foundation.org (Andrew Morton)
Date: Wed, 21 Feb 2024 12:57:52 -0800
Subject: [PATCH v2 00/14] Split crash out from kexec and clean up
 related config items
In-Reply-To: <559f2595-1477-4ef0-80e4-85ae8b426de7@linux.ibm.com>
References: <20240119145241.769622-1-bhe@redhat.com>
	<9101bb07-70f1-476c-bec9-ec67e9899744@linux.ibm.com>
	<Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv>
	<559f2595-1477-4ef0-80e4-85ae8b426de7@linux.ibm.com>
Message-ID: <20240221125752.36fbfe9c307496313198b60f@linux-foundation.org>

On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini <hbathini at linux.ibm.com> wrote:

> On 04/02/24 8:56 am, Baoquan He wrote:
> >>> Hope Hari and Pingfan can help have a look, see if
> >>> it's doable. Now, I make it either have both kexec and crash enabled, or
> >>> disable both of them altogether.
> >>
> >> Sure. I will take a closer look...
> > Thanks a lot. Please feel free to post patches to make that, or I can do
> > it with your support or suggestion.
> 
> Tested your changes and on top of these changes, came up with the below
> changes to get it working for powerpc:
> 
>  
> https://lore.kernel.org/all/20240213113150.1148276-1-hbathini at linux.ibm.com/

So can we take it that you're OK with Baoquan's series as-is?

Baoquan, do you believe the patches in mm-unstable are ready for moving
into mm-stable in preparation for an upstream merge?





From andi.shyti at kernel.org  Wed Feb 21 12:58:23 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Wed, 21 Feb 2024 21:58:23 +0100
Subject: [PATCH v3] i2c: imx: when being a target, mark the last read as
 processed
In-Reply-To: <20240221193013.14233-2-wsa+renesas@sang-engineering.com>
References: <20240221193013.14233-2-wsa+renesas@sang-engineering.com>
Message-ID: <kgfagzj5vez56levwam6n6tzxl2lu7efnw5x3eadl3uophxism@ph2tghrvedg5>

Hi Wolfram and Corey,

On Wed, Feb 21, 2024 at 08:27:13PM +0100, Wolfram Sang wrote:
> From: Corey Minyard <minyard at acm.org>
> 
> When being a target, NAK from the controller means that all bytes have
> been transferred. So, the last byte needs also to be marked as
> 'processed'. Otherwise index registers of backends may not increase.
> 
> Signed-off-by: Corey Minyard <minyard at acm.org>
> Tested-by: Andrew Manley <andrew.manley at sealingtech.com>
> Reviewed-by: Andrew Manley <andrew.manley at sealingtech.com>
> Reviewed-by: Oleksij Rempel <o.rempel at pengutronix.de>
> [wsa: fixed comment and commit message to properly describe the case]
> Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>

is this a fix?

Andi

> ---
> 
> Changes since v2:
> * updated commit message and comment
> 
> In the stalled discussion[1], it seems I couldn't make my suggestions
> clear. So, here are the changes how I meant them. I hope this can be
> agreed on.
> 
> [1] http://patchwork.ozlabs.org/project/linux-i2c/patch/20211112133956.655179-3-minyard at acm.org/
> 
>  drivers/i2c/busses/i2c-imx.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index 88a053987403..60e813137f84 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -803,6 +803,11 @@ static irqreturn_t i2c_imx_slave_handle(struct imx_i2c_struct *i2c_imx,
>  		ctl &= ~I2CR_MTX;
>  		imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
>  		imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
> +
> +		/* flag the last byte as processed */
> +		i2c_imx_slave_event(i2c_imx,
> +				    I2C_SLAVE_READ_PROCESSED, &value);
> +
>  		i2c_imx_slave_finish_op(i2c_imx);
>  		return IRQ_HANDLED;
>  	}
> -- 
> 2.43.0
> 


From hjl.tools at gmail.com  Wed Feb 21 13:12:47 2024
From: hjl.tools at gmail.com (H.J. Lu)
Date: Wed, 21 Feb 2024 13:12:47 -0800
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS in userspace
In-Reply-To: <CAMe9rOr1frpnKSnVQrqeiKK3aAR3xpG=VAiPYLOR9OpHnHhYUw@mail.gmail.com>
References: <20240220235415.GP4163@brightrain.aerifal.cx> <a57d6c7eada4b9a7c35addbc8556f5b53a0c3e6f.camel@intel.com>
 <20240221012736.GQ4163@brightrain.aerifal.cx> <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx> <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
 <20240221175717.GS4163@brightrain.aerifal.cx> <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>
 <20240221183055.GT4163@brightrain.aerifal.cx> <c3085fbe10193dfe59b25bc7da776e60779b0e8c.camel@intel.com>
 <20240221190639.GU4163@brightrain.aerifal.cx> <e3a432c0fa9f5fe837e9d2fc7b36304709a34428.camel@intel.com>
 <CAMe9rOoUO-D7Uoj9s3eq+w9pJBZ=iucEDpU4hqtJYtPmW5T4dQ@mail.gmail.com> <CAMe9rOr1frpnKSnVQrqeiKK3aAR3xpG=VAiPYLOR9OpHnHhYUw@mail.gmail.com>
Message-ID: <CAMe9rOoo55aFHHuLf=zdc4PNvU+Tu9rtpWaMUdRL=JtHGbE3pA@mail.gmail.com>

On Wed, Feb 21, 2024 at 12:25?PM H.J. Lu <hjl.tools at gmail.com> wrote:
>
> On Wed, Feb 21, 2024 at 12:18?PM H.J. Lu <hjl.tools at gmail.com> wrote:
> >
> > On Wed, Feb 21, 2024 at 11:22?AM Edgecombe, Rick P
> > <rick.p.edgecombe at intel.com> wrote:
> > >
> > > On Wed, 2024-02-21 at 14:06 -0500, dalias at libc.org wrote:
> > > > Due to arbitrarily nestable signal frames, no, this does not suffice.
> > > > An interrupted operation using the lock could be arbitrarily delayed,
> > > > even never execute again, making any call to dlopen deadlock.
> > >
> > > Doh! Yep, it is not robust to this. The only thing that could be done
> > > would be a timeout in dlopen(). Which would make the whole thing just
> > > better than nothing.
> > >
> > > >
> > > > >
> > > >
> > > > It's fine to turn RDSSP into an actual emulated read of the SSP, or
> > > > at
> > > > least an emulated load of zero so that uninitialized data is not left
> > > > in the target register.
> > >
> > > We can't intercept RDSSP, but it becomes a NOP by default. (disclaimer
> > > x86-only knowledge).
> > >
> > > >  If doing the latter, code working with the
> > > > shadow stack just needs to be prepared for the possibility that it
> > > > could be async-disabled, and check the return value.
> > > >
> > > > I have not looked at all the instructions that become #UD but I
> > > > suspect they all have reasonable trivial ways to implement a
> > > > "disabled" version of them that userspace can act upon reasonably.
> > >
> > > This would have to be thought through functionally and performance
> > > wise. I'm not opposed if can come up with a fully fleshed out plan. How
> > > serious are you in pursuing musl support, if we had something like
> > > this?
> > >
> > > HJ, any thoughts on whether glibc would use this as well?
> >
> > Assuming that we are talking about permissive mode,  if kernel can
> > suppress UD, we don't need to disable SHSTK.   Glibc can enable
> > ARCH_SHSTK_SUPPRESS_UD instead.
>
> Kernel must suppress all possible SHSTK UDs.

If SHSTK is disabled by kernel, not by glibc,  there can be 2 issues:

1.  Glibc and kernel may be out of sync on SHSTK.
2.  When kernel disables SHSTK, glibc may be in the middle of reading
shadow stack in longjmp, searching for a restore token.

> > > It is probably worth mentioning that from the security side (as Mark
> > > mentioned there is always tension in the tradeoffs on these features),
> > > permissive mode is seen by some as something that weakens security too
> > > much. Apps could call dlopen() on a known unsupported DSO before doing
> > > ROP. I don't know if you have any musl users with specific shadow stack
> > > use cases to ask about this.
> >
> >
> >
> > --
> > H.J.
>
>
>
> --
> H.J.



-- 
H.J.


From andi.shyti at kernel.org  Wed Feb 21 13:14:46 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Wed, 21 Feb 2024 22:14:46 +0100
Subject: [PATCH] i2c: aspeed: Fix the dummy irq expected print
In-Reply-To: <20240216120455.4138642-1-tommy_huang@aspeedtech.com>
References: <20240216120455.4138642-1-tommy_huang@aspeedtech.com>
Message-ID: <nbkkaktcozbhly44hii3zwie7ivsra3qxzdibyzhyhooxrudvb@zik6skmkki2c>

Hi Tommy,

On Fri, Feb 16, 2024 at 08:04:55PM +0800, Tommy Huang wrote:
> When the i2c error condition occurred and master state was not idle,
> the master irq function will goto complete state without any other
> interrupt handling. It would cause dummy irq expected print. Under
> this condition, assign the irq_status into irq_handle.

I'm sorry, but I don't understand much from your log here.

Do you mean that irq_handled in aspeed_i2c_master_irq() is left
with some states that is not supposed to have and then you
end up printing here:

	dev_err(bus->dev,
		"irq handled != irq. expected 0x%08x, but was 0x%08x\n",
		irq_received, irq_handled);

Can you please explain better?

If that's the case, wouldn't it make more sense to check for 
bus->master_state != ASPEED_I2C_MASTER_INACTIVE) earlier?

And, still, If that's the case, I believe you might need the
Fixes tag. It's true that you are not really failing, but you are
not reporting a failure by mistake.

Thanks,
Andi

> Signed-off-by: Tommy Huang <tommy_huang at aspeedtech.com>
> ---
>  drivers/i2c/busses/i2c-aspeed.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
> index 5511fd46a65e..ce8c4846b7fa 100644
> --- a/drivers/i2c/busses/i2c-aspeed.c
> +++ b/drivers/i2c/busses/i2c-aspeed.c
> @@ -445,6 +445,7 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
>  			irq_status);
>  		irq_handled |= (irq_status & ASPEED_I2CD_INTR_MASTER_ERRORS);
>  		if (bus->master_state != ASPEED_I2C_MASTER_INACTIVE) {
> +			irq_handled = irq_status;
>  			bus->cmd_err = ret;
>  			bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
>  			goto out_complete;
> -- 
> 2.25.1
> 


From mka at chromium.org  Wed Feb 21 13:18:09 2024
From: mka at chromium.org (Matthias Kaehlcke)
Date: Wed, 21 Feb 2024 21:18:09 +0000
Subject: [PATCH v4 6/8] usb: misc: onboard_dev: use device supply names
In-Reply-To: <503d9ea9-9812-498b-a5ee-2579ba8a7ecf@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
 <20240220-onboard_xvf3500-v4-6-dc1617cc5dd4@wolfvision.net>
 <ZdZcLOlSc3FScjLK@google.com>
 <503d9ea9-9812-498b-a5ee-2579ba8a7ecf@wolfvision.net>
Message-ID: <ZdZokatitviYZ7rg@google.com>

Hi Javier,

On Wed, Feb 21, 2024 at 09:40:38PM +0100, Javier Carrasco wrote:
> On 21.02.24 21:25, Matthias Kaehlcke wrote:
> > On Tue, Feb 20, 2024 at 03:05:50PM +0100, Javier Carrasco wrote:
> >> The current mechanism uses generic names for the power supplies, which
> >> conflicts with proper name definitions in the device bindings.
> >>
> >> Add a per-device property to include real supply names and keep generic
> >> names as a fallback mechanism for backward compatibility.
> >>
> >> Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
> >> ---
> >>  drivers/usb/misc/onboard_usb_dev.c | 54 ++++++++++++++++++++------------------
> >>  drivers/usb/misc/onboard_usb_dev.h | 23 ++++++++++++++++
> >>  2 files changed, 52 insertions(+), 25 deletions(-)
> >>
> >> diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
> >> index f43130a6786f..e66fcac93006 100644
> >> --- a/drivers/usb/misc/onboard_usb_dev.c
> >> +++ b/drivers/usb/misc/onboard_usb_dev.c
> >> @@ -29,18 +29,6 @@
> >>  
> >>  #include "onboard_usb_dev.h"
> >>  
> >> -/*
> >> - * Use generic names, as the actual names might differ between devices. If a new
> >> - * device requires more than the currently supported supplies, add a new one
> >> - * here.
> >> - */
> >> -static const char * const supply_names[] = {
> >> -	"vdd",
> >> -	"vdd2",
> >> -};
> >> -
> >> -#define MAX_SUPPLIES ARRAY_SIZE(supply_names)
> >> -
> >>  static void onboard_dev_attach_usb_driver(struct work_struct *work);
> >>  
> >>  static struct usb_device_driver onboard_dev_usbdev_driver;
> >> @@ -66,6 +54,33 @@ struct onboard_dev {
> >>  	struct clk *clk;
> >>  };
> >>  
> >> +static int onboard_dev_get_regulator_bulk(struct device *dev,
> >> +					  struct onboard_dev *onboard_dev)
> >> +{
> >> +	unsigned int i;
> >> +	int err;
> >> +
> >> +	const char * const *supply_names = onboard_dev->pdata->supply_names;
> >> +
> >> +	if (onboard_dev->pdata->num_supplies > MAX_SUPPLIES)
> >> +		return dev_err_probe(dev, -EINVAL, "max %zu supplies supported!\n",
> >> +				     MAX_SUPPLIES);
> >> +
> >> +	if (!supply_names[0])
> >> +		supply_names = generic_supply_names;
> > 
> > Please change to 'if (!supply_names)' and omit the initialization of
> > .supply_names for devices that use the generic supply names.
> > 
> 
> That looks much cleaner, I will apply it to the next version.
> 
> >> diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h
> >> index ebe83e19d818..59dced6bd339 100644
> >> --- a/drivers/usb/misc/onboard_usb_dev.h
> >> +++ b/drivers/usb/misc/onboard_usb_dev.h
> >> @@ -6,63 +6,86 @@
> >>  #ifndef _USB_MISC_ONBOARD_USB_DEV_H
> >>  #define _USB_MISC_ONBOARD_USB_DEV_H
> >>  
> >> +/*
> >> + * Fallback supply names for backwards compatibility. If the device requires
> >> + * more than the currently supported supplies, add a new one here, and if
> >> + * possible, the real name supplies to the device-specific data.
> >> + */
> >> +static const char * const generic_supply_names[] = {
> >> +	"vdd",
> >> +	"vdd2",
> >> +};
> >> +
> >> +#define MAX_SUPPLIES ARRAY_SIZE(generic_supply_names)
> > 
> > This will have to change when support for a device with more than 2 non-generic
> > supply names gets added. Please use a literal value for MAX_SUPPLIES instead of
> > ARRAY_SIZE. If the literal is 2 it would still need to change for future devices
> > with more supplies, but that change would be more straighforward.
> > 
> 
> I am not completely sure about this. Someone could increase MAX_SUPPLIES
> without adding a generic name.

That's perfectly fine and intended. MAX_SUPPLIES is a max, any list
shorther than that is valid. Any longer list will result in probe()
being aborted with a clear error message.

> Actually two modifications will be necessary for every addition (name
> and MAX_SUPPLIES). If ARRAY_SIZE is used, only new names are required,
> and MAX_SUPPLIES is automatically increased.

As per above it's not necessary to add a new name when MAX_SUPPLIES is
increased to support more non-generic names. It would only be necessary
if more generic names were added, my understanding is that this
should not happen because any newly supported onboard devices are
supposed to use device specific supply names. I don't like to idea of
adding unused pseudo supply names to the list, just for the sake of
using ARRAY_SIZE.

> I understand that the whole point of this is getting rid of the generic
> names, but we still have to provide generic names for every extra
> supply, at least for code consistency and to avoid size mismatches
> between real an generic supply names.

Please let me know if you still think the extra names are needed.


From javier.carrasco at wolfvision.net  Wed Feb 21 13:33:53 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Wed, 21 Feb 2024 22:33:53 +0100
Subject: [PATCH v4 6/8] usb: misc: onboard_dev: use device supply names
In-Reply-To: <ZdZokatitviYZ7rg@google.com>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
 <20240220-onboard_xvf3500-v4-6-dc1617cc5dd4@wolfvision.net>
 <ZdZcLOlSc3FScjLK@google.com>
 <503d9ea9-9812-498b-a5ee-2579ba8a7ecf@wolfvision.net>
 <ZdZokatitviYZ7rg@google.com>
Message-ID: <6a4f1862-ccb1-4d6d-bab2-f22090a1a08b@wolfvision.net>

On 21.02.24 22:18, Matthias Kaehlcke wrote:
>>>> +/*
>>>> + * Fallback supply names for backwards compatibility. If the device requires
>>>> + * more than the currently supported supplies, add a new one here, and if
>>>> + * possible, the real name supplies to the device-specific data.
>>>> + */
>>>> +static const char * const generic_supply_names[] = {
>>>> +	"vdd",
>>>> +	"vdd2",
>>>> +};
>>>> +
>>>> +#define MAX_SUPPLIES ARRAY_SIZE(generic_supply_names)
>>>
>>> This will have to change when support for a device with more than 2 non-generic
>>> supply names gets added. Please use a literal value for MAX_SUPPLIES instead of
>>> ARRAY_SIZE. If the literal is 2 it would still need to change for future devices
>>> with more supplies, but that change would be more straighforward.
>>>
>>
>> I am not completely sure about this. Someone could increase MAX_SUPPLIES
>> without adding a generic name.
> 
> That's perfectly fine and intended. MAX_SUPPLIES is a max, any list
> shorther than that is valid. Any longer list will result in probe()
> being aborted with a clear error message.
> 
>> Actually two modifications will be necessary for every addition (name
>> and MAX_SUPPLIES). If ARRAY_SIZE is used, only new names are required,
>> and MAX_SUPPLIES is automatically increased.
> 
> As per above it's not necessary to add a new name when MAX_SUPPLIES is
> increased to support more non-generic names. It would only be necessary
> if more generic names were added, my understanding is that this
> should not happen because any newly supported onboard devices are
> supposed to use device specific supply names. I don't like to idea of
> adding unused pseudo supply names to the list, just for the sake of
> using ARRAY_SIZE.
> 
>> I understand that the whole point of this is getting rid of the generic
>> names, but we still have to provide generic names for every extra
>> supply, at least for code consistency and to avoid size mismatches
>> between real an generic supply names.
> 
> Please let me know if you still think the extra names are needed.

Not really, the only case I could come up is if an existing device that
uses generic names might end up requiring a third supply, which would
also be generic. But even such an unlikely event would be cover without
ARRAY_SIZE.

Actually one could argue that every existing device could have "vdd" and
"vdd2" as their supply names and remove checks and the generic array.

Best regards,
Javier Carrasco



From linus.walleij at linaro.org  Wed Feb 21 13:37:49 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 22:37:49 +0100
Subject: [PATCH 2/4] ARM: Move asm statements accessing TTBCR into C functions
In-Reply-To: <CAMj1kXGL_FLBuSCQpBsJt_2cJRS0+L1m-sdSuZZ_m1D0=57Tmg@mail.gmail.com>
References: <20240123-arm32-lpae-pan-v1-0-7ea98a20514c@linaro.org>
 <20240123-arm32-lpae-pan-v1-2-7ea98a20514c@linaro.org> <CAMj1kXGL_FLBuSCQpBsJt_2cJRS0+L1m-sdSuZZ_m1D0=57Tmg@mail.gmail.com>
Message-ID: <CACRpkdbYaxN4pCfSuYjAHwh7Qv8QOiP8vadMo+2T9yJ8Vb+xVw@mail.gmail.com>

On Wed, Feb 14, 2024 at 4:23?PM Ard Biesheuvel <ardb at kernel.org> wrote:
> On Tue, 23 Jan 2024 at 22:16, Linus Walleij <linus.walleij at linaro.org> wrote:

> > +static inline void cpu_set_ttbcr(unsigned int ttbcr)
> > +{
> > +       asm volatile("mcr p15, 0, %0, c2, c0, 2" : : "r" (ttbcr));
>
> Nit: the 'volatile' is unnecessary here - there are no output
> operands, so the compiler has to assume that the statement has side
> effects.

Somehow I missed this in my v2 patch set, I fixed it for v3 now.

Yours,
Linus Walleij


From alfredo.carlon at gmail.com  Wed Feb 21 13:38:37 2024
From: alfredo.carlon at gmail.com (Alfredo Cruz)
Date: Wed, 21 Feb 2024 22:38:37 +0100
Subject: [PATCH] ARM: sa1111: fix put_device() before device_add() in error path
Message-ID: <20240221213837.27605-1-alfredo.carlon@gmail.com>

When request_resource() fails, a jump is made to err_resource label which
calls put_device() on &dev->res without adding it first.
Kept the err_resource label and moved put_device() to err_add label.

Signed-off-by: Alfredo Cruz <alfredo.carlon at gmail.com>
---
 arch/arm/common/sa1111.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 1fbd7363cf11..76bf15da5115 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -779,8 +779,8 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
 
  err_add:
 	release_resource(&dev->res);
- err_resource:
 	put_device(&dev->dev);
+ err_resource:
  err_alloc:
 	return ret;
 }
-- 
2.43.2



From martin.blumenstingl at googlemail.com  Wed Feb 21 13:43:48 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Wed, 21 Feb 2024 22:43:48 +0100
Subject: [PATCH v1] clocksource/drivers/arm_global_timer: Simplify prescaler register access
Message-ID: <20240221214348.2299636-1-martin.blumenstingl@googlemail.com>

Use GENMASK() to define the prescaler mask and make the whole driver use
the mask (together with helpers such as FIELD_GET and FIELD_PREP)
instead of needed an additional shift and max value constant.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 drivers/clocksource/arm_global_timer.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index 8dd1e46b7176..1eb91fa00657 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -9,6 +9,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/bitfield.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/cpu.h>
@@ -31,10 +32,7 @@
 #define GT_CONTROL_COMP_ENABLE		BIT(1)	/* banked */
 #define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
 #define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
-#define GT_CONTROL_PRESCALER_SHIFT      8
-#define GT_CONTROL_PRESCALER_MAX        0xFF
-#define GT_CONTROL_PRESCALER_MASK       (GT_CONTROL_PRESCALER_MAX << \
-					 GT_CONTROL_PRESCALER_SHIFT)
+#define GT_CONTROL_PRESCALER_MASK	GENMASK(15, 8)
 
 #define GT_INT_STATUS	0x0c
 #define GT_INT_STATUS_EVENT_FLAG	BIT(0)
@@ -247,7 +245,7 @@ static void gt_write_presc(u32 psv)
 
 	reg = readl(gt_base + GT_CONTROL);
 	reg &= ~GT_CONTROL_PRESCALER_MASK;
-	reg |= psv << GT_CONTROL_PRESCALER_SHIFT;
+	reg |= FIELD_PREP(GT_CONTROL_PRESCALER_MASK, psv);
 	writel(reg, gt_base + GT_CONTROL);
 }
 
@@ -256,8 +254,7 @@ static u32 gt_read_presc(void)
 	u32 reg;
 
 	reg = readl(gt_base + GT_CONTROL);
-	reg &= GT_CONTROL_PRESCALER_MASK;
-	return reg >> GT_CONTROL_PRESCALER_SHIFT;
+	return FIELD_GET(GT_CONTROL_PRESCALER_MASK, reg);
 }
 
 static void __init gt_delay_timer_init(void)
@@ -272,9 +269,9 @@ static int __init gt_clocksource_init(void)
 	writel(0, gt_base + GT_COUNTER0);
 	writel(0, gt_base + GT_COUNTER1);
 	/* set prescaler and enable timer on all the cores */
-	writel(((CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) <<
-		GT_CONTROL_PRESCALER_SHIFT)
-	       | GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
+	writel(FIELD_PREP(GT_CONTROL_PRESCALER_MASK,
+			  CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) |
+	       GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
 
 #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 	sched_clock_register(gt_sched_clock_read, 64, gt_target_rate);
@@ -301,7 +298,7 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,
 		psv--;
 
 		/* prescaler within legal range? */
-		if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
+		if (psv < 0 || psv > FIELD_GET(GT_CONTROL_PRESCALER_MASK, ~0))
 			return NOTIFY_BAD;
 
 		/*
-- 
2.43.2



From mka at chromium.org  Wed Feb 21 13:46:38 2024
From: mka at chromium.org (Matthias Kaehlcke)
Date: Wed, 21 Feb 2024 21:46:38 +0000
Subject: [PATCH v4 6/8] usb: misc: onboard_dev: use device supply names
In-Reply-To: <6a4f1862-ccb1-4d6d-bab2-f22090a1a08b@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
 <20240220-onboard_xvf3500-v4-6-dc1617cc5dd4@wolfvision.net>
 <ZdZcLOlSc3FScjLK@google.com>
 <503d9ea9-9812-498b-a5ee-2579ba8a7ecf@wolfvision.net>
 <ZdZokatitviYZ7rg@google.com>
 <6a4f1862-ccb1-4d6d-bab2-f22090a1a08b@wolfvision.net>
Message-ID: <ZdZvPiEVKgciB-cg@google.com>

On Wed, Feb 21, 2024 at 10:33:53PM +0100, Javier Carrasco wrote:
> On 21.02.24 22:18, Matthias Kaehlcke wrote:
> >>>> +/*
> >>>> + * Fallback supply names for backwards compatibility. If the device requires
> >>>> + * more than the currently supported supplies, add a new one here, and if
> >>>> + * possible, the real name supplies to the device-specific data.
> >>>> + */
> >>>> +static const char * const generic_supply_names[] = {
> >>>> +	"vdd",
> >>>> +	"vdd2",
> >>>> +};
> >>>> +
> >>>> +#define MAX_SUPPLIES ARRAY_SIZE(generic_supply_names)
> >>>
> >>> This will have to change when support for a device with more than 2 non-generic
> >>> supply names gets added. Please use a literal value for MAX_SUPPLIES instead of
> >>> ARRAY_SIZE. If the literal is 2 it would still need to change for future devices
> >>> with more supplies, but that change would be more straighforward.
> >>>
> >>
> >> I am not completely sure about this. Someone could increase MAX_SUPPLIES
> >> without adding a generic name.
> > 
> > That's perfectly fine and intended. MAX_SUPPLIES is a max, any list
> > shorther than that is valid. Any longer list will result in probe()
> > being aborted with a clear error message.
> > 
> >> Actually two modifications will be necessary for every addition (name
> >> and MAX_SUPPLIES). If ARRAY_SIZE is used, only new names are required,
> >> and MAX_SUPPLIES is automatically increased.
> > 
> > As per above it's not necessary to add a new name when MAX_SUPPLIES is
> > increased to support more non-generic names. It would only be necessary
> > if more generic names were added, my understanding is that this
> > should not happen because any newly supported onboard devices are
> > supposed to use device specific supply names. I don't like to idea of
> > adding unused pseudo supply names to the list, just for the sake of
> > using ARRAY_SIZE.
> > 
> >> I understand that the whole point of this is getting rid of the generic
> >> names, but we still have to provide generic names for every extra
> >> supply, at least for code consistency and to avoid size mismatches
> >> between real an generic supply names.
> > 
> > Please let me know if you still think the extra names are needed.
> 
> Not really, the only case I could come up is if an existing device that
> uses generic names might end up requiring a third supply, which would
> also be generic. But even such an unlikely event would be cover without
> ARRAY_SIZE.
> 
> Actually one could argue that every existing device could have "vdd" and
> "vdd2" as their supply names and remove checks and the generic array.

Sounds good to me. Another similar option would be to assign
'generic_supply_names' to '.supply_names'. I don't have a strong
preference.


From anarsoul at gmail.com  Wed Feb 21 13:53:30 2024
From: anarsoul at gmail.com (Vasily Khoruzhick)
Date: Wed, 21 Feb 2024 13:53:30 -0800
Subject: [PATCH v5 0/7] add support for H616 thermal system
In-Reply-To: <13c957a9-6021-46a7-9243-b3658c26a333@linaro.org>
References: <20240219153639.179814-1-andre.przywara@arm.com> <13c957a9-6021-46a7-9243-b3658c26a333@linaro.org>
Message-ID: <CA+E=qVeMnQNrT8tNnHBnCL2Efy3VjbRAYQGMXstziCThRsiBDw@mail.gmail.com>

On Wed, Feb 21, 2024 at 5:43?AM Daniel Lezcano
<daniel.lezcano at linaro.org> wrote:
>
> On 19/02/2024 16:36, Andre Przywara wrote:
> > Hi,
> >
> > this is v5 of this series originally by Martin, only some cosmetic
> > changes this time, for instance  mentioning experiments with the SRAM
> > controller registers to confirm that it's not an SRAM region which fixes
> > the temperature reporting issue.
> > See the Changelog below for more details.
> > ==================
> >
> > This series introduces support for the thermal sensors in the Allwinner
> > H616 SoCs, which includes its siblings H618 and T507. The actual
> > temperature reading turns out to be very similar to the H6 SoC, just
> > with support for two more sensors. One nasty complication is caused
> > by reports about temperatures above 200C, which are related to the
> > firmware being run (because the vendor U-Boot contains a hack avoiding
> > this problem). Some investigation and digging in BSP code later
> > we identified that bit 16 in register 0x3000000 (SYS_CFG) needs to be
> > cleared for the raw temperature register values to contain reasonable
> > values.
> > To achieve this, patch 1/7 exports this very register from the already
> > existing SRAM/syscon device. Patch 5/7 then adds code to the thermal
> > driver to find that device via a new DT property, and query its regmap
> > to clear bit 16 in there.
> > Patch 4/7 reworks the existing H6 calibration function to become
> > compatible with the H616, many thanks to Maksim for figuring this out.
> > This makes the actual enablement patch 6/7 very easy.
> >
> > The rest of the patches are straightforward and build on Martin's
> > original work, with some simplifications, resulting in more code sharing.
> >
> > Please have a look!
>
> Thanks for the detailed explanation.
>
> I'm willing to pick the patches 1-6 and let the last one to go through
> the allwinner tree.
>
> However I need the blessing from the different designed maintainers for
> the thermal driver and from the sunxi_sram

For sun8i_thermal:

Acked-by: Vasily Khoruzhick <anarsoul at gmail.com>

> Thanks
>
> --
> <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 linus.walleij at linaro.org  Wed Feb 21 13:54:59 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 22:54:59 +0100
Subject: [PATCH v3 01/18] gpio: pca953x: move suspend()/resume() to suspend_noirq()/resume_noirq()
In-Reply-To: <20240102-j7200-pcie-s2r-v3-1-5c2e4a3fac1f@bootlin.com>
References: <20240102-j7200-pcie-s2r-v3-0-5c2e4a3fac1f@bootlin.com> <20240102-j7200-pcie-s2r-v3-1-5c2e4a3fac1f@bootlin.com>
Message-ID: <CACRpkdYSw5_70H4k5ZX-stCU=CH=v_0Ggm+R+FSBhdbk6mnhOA@mail.gmail.com>

On Thu, Feb 15, 2024 at 4:18?PM Thomas Richard
<thomas.richard at bootlin.com> wrote:

> Some IOs can be needed during suspend_noirq()/resume_noirq().
> So move suspend()/resume() to noirq.
>
> Reviewed-by: Andi Shyti <andi.shyti at kernel.org>
> Acked-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> Reviewed-by: Andy Shevchenko <andy.shevchenko at gmail.com>
> Signed-off-by: Thomas Richard <thomas.richard at bootlin.com>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From javierm at redhat.com  Wed Feb 21 13:56:30 2024
From: javierm at redhat.com (Javier Martinez Canillas)
Date: Wed, 21 Feb 2024 22:56:30 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <724jnhrbs6r4q6whynr3aon5w7mhfvetlgcnts4nukvtxbuium@mrjv6apjqk7r>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
 <56625c21-1b34-479b-b5b2-4c4d8b7a11b3@app.fastmail.com>
 <724jnhrbs6r4q6whynr3aon5w7mhfvetlgcnts4nukvtxbuium@mrjv6apjqk7r>
Message-ID: <87v86h7a7l.fsf@minerva.mail-host-address-is-not-set>

Maxime Ripard <mripard at redhat.com> writes:

> On Wed, Feb 21, 2024 at 04:41:38PM +0100, Arnd Bergmann wrote:
>> On Wed, Feb 21, 2024, at 16:24, Maxime Ripard wrote:

[...]

>> > Being able to test an upstream kernel quickly when you have a bug in a
>> > downstream distro is super valuable for any distro developper. And on
>> > the long run, if we don't make the switch from a kernel distro to a
>> > mainline kernel relatively easy, we're the ones that will lose out.
>> > Because people just won't bother, or be frustrated and thus super
>> > reluctant to do that work.
>> 
>> We had previously discussed adding config fragments for common
>> distros the way we have kvm_guest.config, but if the Javier's
>> patch is all that is actually needed for Fedora, that seems better
>> to me than the added complexity of fragments.
>
> Oh, right. Fragments would be a great tool to reconcile the need for
> minimal boot time and supporting reasonable use-cases.
>
> I guess it's even more of a struggle with the single arm64 defconfig vs
> the minimal vs batteries included defconfig setup we had for arm.
>

I'm OK with using fragments instead and propose a fedora.config or
whatever name is decided for this.

As long as the list is kept in the mainline repo, instead of every
Fedora developer having to make local changes in their .config, it
works for me.

> Maxime

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



From linux at armlinux.org.uk  Wed Feb 21 13:57:06 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 21 Feb 2024 21:57:06 +0000
Subject: [PATCH] ARM: sa1111: fix put_device() before device_add() in
 error path
In-Reply-To: <20240221213837.27605-1-alfredo.carlon@gmail.com>
References: <20240221213837.27605-1-alfredo.carlon@gmail.com>
Message-ID: <ZdZxsrhLNCt+bCOB@shell.armlinux.org.uk>

On Wed, Feb 21, 2024 at 10:38:37PM +0100, Alfredo Cruz wrote:
> When request_resource() fails, a jump is made to err_resource label which
> calls put_device() on &dev->res without adding it first.
> Kept the err_resource label and moved put_device() to err_add label.

You fail to explain why this is incorrect. I think this patch is
incorrect. The reason is as follows:

"dev" is allocated.
dev->dev is then initialised. This initialises the struct device,
setting its initial refcount to '1'.

We then request the resource. If this fails, then the device needs to
be released. As refcounting has been initialised, it is *not*
appropriate to simply kfree() "dev". The correct action, as noted by
the device_initialize() documentation is to call put_device() on it.
This is what the code does.

I _do_ hope you haven't submitted other patches like this, because if
you have, they could well also be wrong.

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


From cristian.marussi at arm.com  Wed Feb 21 14:04:26 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 21 Feb 2024 22:04:26 +0000
Subject: [PATCH] firmware: arm_scmi: Add support for multiple vendors custom protocols
Message-ID: <20240221220426.1205146-1-cristian.marussi@arm.com>

Add a mechanism to be able to tag vendor protocol modules at compile-time
with a vendor/sub_vendor string and an implementation version and then to
choose to load, at run-time, only those vendor protocol modules matching
as close as possible the vendor/subvendor identification advertised by
the SCMI platform server.

In this way, any in-tree existent vendor protocol module can be build and
shipped by default in a single kernel image, even when using the same
clashing protocol identification numbers, since the SCMI core will take
care at run-time to load only the ones pertinent to the running system.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
Hi all,

this is meant to address the possibility of having multiple vendors
implementing distinct SCMI vendor protocols with possibly the same
overlapping protocol number without the need of crafting the Kconfig
at compile time to include only wanted protos
(and without the need for a lottery :P)

Basic idea is simple:

- vendor protos HAS to be 'tagged' at build time with a vendor_id
- vendor protos COULD also optionally be tagged at build time with
sub_vendor_id and implemetation version

- at init all the build vendor protos are registerd with the SCMI core
  using a key derived from the above tags

- at SCMI probe time the platform is identified via Base protocol as
  usual and all the required vendor protos (i.e. IDs defined in the DT
  as usual) are loaded after a lookup process based on the following rules:

  + protocol DB is searched using the platform/Base runtime provided tags

  	<vendor> / <sub_vendor> / <impl_ver>

    using the the following search logic (keys), first match:

     1. proto_id / <vendor_id> / <sub_vendor_id> / <impl_ver>

     2. proto_id / <vendor_id> / <sub_vendor_id> / 0

     3. proto_id / <vendor_id> / NULL / 0

  IOW, closest match, depending on how much fine grained is your
  protocol tuned (tagged) for the platform.

  I am doubtful about the usage of <impl_ver>, and tempted to drop it
  since we have anyway protocol version and NEGOTIATE_PROTOCOL_VERSION
  to deal with slight difference in fw revision...

Based on sudeep/for-linux-next on top of

	1c2c88cfcb2b ("clk: scmi: Support get/set duty_cycle operations")

Minimally tested ....

  Any feedback welcome

  Thanks,
  Cristian
---
 drivers/firmware/arm_scmi/driver.c    | 166 ++++++++++++++++++++++----
 drivers/firmware/arm_scmi/protocols.h |   5 +
 2 files changed, 149 insertions(+), 22 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 34d77802c990..8fb2903698c9 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -33,6 +33,7 @@
 #include <linux/processor.h>
 #include <linux/refcount.h>
 #include <linux/slab.h>
+#include <linux/xarray.h>
 
 #include "common.h"
 #include "notify.h"
@@ -44,8 +45,7 @@
 
 static DEFINE_IDA(scmi_id);
 
-static DEFINE_IDR(scmi_protocols);
-static DEFINE_SPINLOCK(protocol_lock);
+static DEFINE_XARRAY(scmi_protocols);
 
 /* List of all SCMI devices active in system */
 static LIST_HEAD(scmi_list);
@@ -194,11 +194,90 @@ struct scmi_info {
 #define bus_nb_to_scmi_info(nb)	container_of(nb, struct scmi_info, bus_nb)
 #define req_nb_to_scmi_info(nb)	container_of(nb, struct scmi_info, dev_req_nb)
 
-static const struct scmi_protocol *scmi_protocol_get(int protocol_id)
+static unsigned long
+scmi_vendor_protocol_signature(unsigned protocol_id, char *vendor_id,
+			       char *sub_vendor_id, u32 impl_ver)
 {
-	const struct scmi_protocol *proto;
+	char *signature, *p;
+	unsigned long hash = 0;
 
-	proto = idr_find(&scmi_protocols, protocol_id);
+	/* vendor_id/sub_vendor_id guaranteed <= SCMI_SHORT_NAME_MAX_SIZE */
+	signature = kasprintf(GFP_KERNEL, "%02X|%s|%s|0x%08X", protocol_id,
+			      vendor_id ?: "", sub_vendor_id ?: "", impl_ver);
+	if (!signature)
+		return 0;
+
+	p = signature;
+	while (*p)
+		hash = partial_name_hash(tolower(*p++), hash);
+	hash = end_name_hash(hash);
+
+	kfree(signature);
+
+	return hash;
+}
+
+static unsigned long
+scmi_protocol_key_calculate(int protocol_id, char *vendor_id,
+			    char *sub_vendor_id, u32 impl_ver)
+{
+	if (protocol_id < SCMI_PROTOCOL_VENDOR)
+		return protocol_id;
+	else
+		return scmi_vendor_protocol_signature(protocol_id, vendor_id,
+						      sub_vendor_id, impl_ver);
+}
+
+static const struct scmi_protocol *
+scmi_vendor_protocol_lookup(int protocol_id, char *vendor_id,
+			    char *sub_vendor_id, u32 impl_ver)
+{
+	unsigned long key;
+	struct scmi_protocol *proto = NULL;
+
+	/* Searching for closest match ...*/
+	key = scmi_protocol_key_calculate(protocol_id, vendor_id,
+					  sub_vendor_id, impl_ver);
+	if (key)
+		proto = xa_load(&scmi_protocols, key);
+
+	if (proto)
+		return proto;
+
+	/* Any match on vendor/sub_vendor ? */
+	if (impl_ver) {
+		key = scmi_protocol_key_calculate(protocol_id, vendor_id,
+						  sub_vendor_id, 0);
+		if (key)
+			proto = xa_load(&scmi_protocols, key);
+
+		if (proto)
+			return proto;
+	}
+
+	/* Any match on just the vendor ? */
+	if (sub_vendor_id) {
+		key = scmi_protocol_key_calculate(protocol_id, vendor_id,
+						  NULL, 0);
+		if (key)
+			proto = xa_load(&scmi_protocols, key);
+	}
+
+	return proto;
+}
+
+static const struct scmi_protocol *
+scmi_protocol_get(int protocol_id, struct scmi_revision_info *version)
+{
+	const struct scmi_protocol *proto = NULL;
+
+	if (protocol_id < SCMI_PROTOCOL_VENDOR)
+		proto = xa_load(&scmi_protocols, protocol_id);
+	else
+		proto = scmi_vendor_protocol_lookup(protocol_id,
+						    version->vendor_id,
+						    version->sub_vendor_id,
+						    version->impl_ver);
 	if (!proto || !try_module_get(proto->owner)) {
 		pr_warn("SCMI Protocol 0x%x not found!\n", protocol_id);
 		return NULL;
@@ -206,21 +285,47 @@ static const struct scmi_protocol *scmi_protocol_get(int protocol_id)
 
 	pr_debug("Found SCMI Protocol 0x%x\n", protocol_id);
 
+	if (protocol_id >= SCMI_PROTOCOL_VENDOR)
+		pr_info("Loaded SCMI Vendor Protocol 0x%x - %s %s %X\n",
+			protocol_id, proto->vendor_id ?: "",
+			proto->sub_vendor_id ?: "", proto->impl_ver);
+
 	return proto;
 }
 
-static void scmi_protocol_put(int protocol_id)
+static void scmi_protocol_put(const struct scmi_protocol *proto)
 {
-	const struct scmi_protocol *proto;
-
-	proto = idr_find(&scmi_protocols, protocol_id);
 	if (proto)
 		module_put(proto->owner);
 }
 
+static int scmi_vendor_protocol_check(const struct scmi_protocol *proto)
+{
+	if (!proto->vendor_id) {
+		pr_err("missing vendor_id for protocol 0x%x\n", proto->id);
+		return -EINVAL;
+	}
+
+	if (proto->vendor_id &&
+	    strlen(proto->vendor_id) >= SCMI_SHORT_NAME_MAX_SIZE) {
+		pr_err("malformed vendor_id for protocol 0x%x\n", proto->id);
+		return -EINVAL;
+	}
+
+	if (proto->sub_vendor_id &&
+	    strlen(proto->sub_vendor_id) >= SCMI_SHORT_NAME_MAX_SIZE) {
+		pr_err("malformed sub_vendor_id for protocol 0x%x\n",
+		       proto->id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 int scmi_protocol_register(const struct scmi_protocol *proto)
 {
 	int ret;
+	unsigned long key;
 
 	if (!proto) {
 		pr_err("invalid protocol\n");
@@ -232,12 +337,23 @@ int scmi_protocol_register(const struct scmi_protocol *proto)
 		return -EINVAL;
 	}
 
-	spin_lock(&protocol_lock);
-	ret = idr_alloc(&scmi_protocols, (void *)proto,
-			proto->id, proto->id + 1, GFP_ATOMIC);
-	spin_unlock(&protocol_lock);
-	if (ret != proto->id) {
-		pr_err("unable to allocate SCMI idr slot for 0x%x - err %d\n",
+	if (proto->id >= SCMI_PROTOCOL_VENDOR &&
+	    scmi_vendor_protocol_check(proto))
+		return -EINVAL;
+
+	/*
+	 * Calculate a protocol key to register this protocol with the core;
+	 * key value 0 is considered invalid.
+	 */
+	key = scmi_protocol_key_calculate(proto->id, proto->vendor_id,
+					  proto->sub_vendor_id,
+					  proto->impl_ver);
+	if (!key)
+		return -EINVAL;
+
+	ret = xa_insert(&scmi_protocols, key, (void *)proto, GFP_KERNEL);
+	if (ret) {
+		pr_err("unable to allocate SCMI protocol slot for 0x%x - err %d\n",
 		       proto->id, ret);
 		return ret;
 	}
@@ -250,9 +366,15 @@ EXPORT_SYMBOL_GPL(scmi_protocol_register);
 
 void scmi_protocol_unregister(const struct scmi_protocol *proto)
 {
-	spin_lock(&protocol_lock);
-	idr_remove(&scmi_protocols, proto->id);
-	spin_unlock(&protocol_lock);
+	unsigned long key;
+
+	key = scmi_protocol_key_calculate(proto->id, proto->vendor_id,
+					  proto->sub_vendor_id,
+					  proto->impl_ver);
+	if (!key)
+		return;
+
+	xa_erase(&scmi_protocols, key);
 
 	pr_debug("Unregistered SCMI Protocol 0x%x\n", proto->id);
 }
@@ -1888,7 +2010,7 @@ scmi_alloc_init_protocol_instance(struct scmi_info *info,
 	/* Protocol specific devres group */
 	gid = devres_open_group(handle->dev, NULL, GFP_KERNEL);
 	if (!gid) {
-		scmi_protocol_put(proto->id);
+		scmi_protocol_put(pi->proto);
 		goto out;
 	}
 
@@ -1952,7 +2074,7 @@ scmi_alloc_init_protocol_instance(struct scmi_info *info,
 
 clean:
 	/* Take care to put the protocol module's owner before releasing all */
-	scmi_protocol_put(proto->id);
+	scmi_protocol_put(proto);
 	devres_release_group(handle->dev, gid);
 out:
 	return ERR_PTR(ret);
@@ -1986,7 +2108,7 @@ scmi_get_protocol_instance(const struct scmi_handle *handle, u8 protocol_id)
 		const struct scmi_protocol *proto;
 
 		/* Fails if protocol not registered on bus */
-		proto = scmi_protocol_get(protocol_id);
+		proto = scmi_protocol_get(protocol_id, &info->version);
 		if (proto)
 			pi = scmi_alloc_init_protocol_instance(info, proto);
 		else
@@ -2041,7 +2163,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id)
 
 		idr_remove(&info->protocols, protocol_id);
 
-		scmi_protocol_put(protocol_id);
+		scmi_protocol_put(pi->proto);
 
 		devres_release_group(handle->dev, gid);
 		dev_dbg(handle->dev, "De-Initialized protocol: 0x%X\n",
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index 693019fff0f6..cb8dbc93584b 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -29,6 +29,8 @@
 #define PROTOCOL_REV_MAJOR(x)	((u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x))))
 #define PROTOCOL_REV_MINOR(x)	((u16)(FIELD_GET(PROTOCOL_REV_MINOR_MASK, (x))))
 
+#define SCMI_PROTOCOL_VENDOR	0x80
+
 enum scmi_common_cmd {
 	PROTOCOL_VERSION = 0x0,
 	PROTOCOL_ATTRIBUTES = 0x1,
@@ -330,6 +332,9 @@ struct scmi_protocol {
 	const void				*ops;
 	const struct scmi_protocol_events	*events;
 	unsigned int				supported_version;
+	u32					impl_ver;
+	char					*vendor_id;
+	char					*sub_vendor_id;
 };
 
 #define DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(name, proto)	\
-- 
2.43.0



From linus.walleij at linaro.org  Wed Feb 21 14:07:11 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 23:07:11 +0100
Subject: [PATCH] phy: constify of_phandle_args in xlate
In-Reply-To: <20240217093937.58234-1-krzysztof.kozlowski@linaro.org>
References: <20240217093937.58234-1-krzysztof.kozlowski@linaro.org>
Message-ID: <CACRpkdajVH4Y2K5W+o5XAoiEr57ObVbaR+9QdFV=Cp765B+dfQ@mail.gmail.com>

On Sat, Feb 17, 2024 at 10:39?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:

> The xlate callbacks are supposed to translate of_phandle_args to proper
> provider without modifying the of_phandle_args.  Make the argument
> pointer to const for code safety and readability.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
(...)
>  drivers/pinctrl/tegra/pinctrl-tegra-xusb.c         |  2 +-

Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From f.fainelli at gmail.com  Wed Feb 21 14:12:45 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 21 Feb 2024 14:12:45 -0800
Subject: [PATCH] phy: constify of_phandle_args in xlate
In-Reply-To: <20240217093937.58234-1-krzysztof.kozlowski@linaro.org>
References: <20240217093937.58234-1-krzysztof.kozlowski@linaro.org>
Message-ID: <69a0df59-7d27-406b-b0a0-3e43f18b20bf@gmail.com>

On 2/17/24 01:39, Krzysztof Kozlowski wrote:
> The xlate callbacks are supposed to translate of_phandle_args to proper
> provider without modifying the of_phandle_args.  Make the argument
> pointer to const for code safety and readability.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Acked-by: Florian Fainelli <florian.fainelli at broadcom.com> #Broadcom
-- 
Florian



From Frank.Li at nxp.com  Wed Feb 21 14:15:09 2024
From: Frank.Li at nxp.com (Frank Li)
Date: Wed, 21 Feb 2024 17:15:09 -0500
Subject: [PATCH 1/1] ARM: dts: ls1021a: Enable usb3-lpm-capable for usb3 node
Message-ID: <20240221221510.3762096-1-Frank.Li@nxp.com>

From: Li Yang <leoyang.li at nxp.com>

Enable USB3 HW LPM feature.

Signed-off-by: Ran Wang <ran.wang_1 at nxp.com>
Signed-off-by: Li Yang <leoyang.li at nxp.com>
Signed-off-by: Frank Li <Frank.Li at nxp.com>
---
 arch/arm/boot/dts/nxp/ls/ls1021a.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi b/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi
index 95e2057d9213c..e86998ca77d6e 100644
--- a/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi
+++ b/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi
@@ -808,6 +808,7 @@ usb3: usb at 3100000 {
 			dr_mode = "host";
 			snps,quirk-frame-length-adjustment = <0x20>;
 			snps,dis_rxdet_inp3_quirk;
+			usb3-lpm-capable;
 			snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
 			snps,host-vbus-glitches;
 		};
-- 
2.34.1



From linus.walleij at linaro.org  Wed Feb 21 14:35:20 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 23:35:20 +0100
Subject: [GIT PULL] ARM Versatile DTS fixes for v6.9
Message-ID: <CACRpkdaL6j6OdixHFHoMms4e=tXEw_6ynBMFb6m8=7KkVgEedA@mail.gmail.com>

Hi SoC folks,

these are some ARM Versatile DTS fixes for v6.9.
Details in the signed tag!

Please pull it in.

Yours,
Linus Walleij

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git
tags/versatile-dts-v6.9

for you to fetch changes up to d41e4dfc316bbd9a4572df26f0d740d6cc685de1:

  dt-bindings: arm: realview: Spelling s/ARM 11/Arm11/, s/Cortex
A-/Cortex-A/ (2024-02-21 23:30:01 +0100)

----------------------------------------------------------------
DTS fixes for the ARM Versatile boards:

- Use the "mtd-rom" compatible for the Realview ROM
- Fix up two VGA connector cells and labels
- Fix up the Cortex spelling

----------------------------------------------------------------
Geert Uytterhoeven (2):
      ARM: dts: arm: realview: Fix development chip ROM compatible value
      dt-bindings: arm: realview: Spelling s/ARM 11/Arm11/, s/Cortex
A-/Cortex-A/

Linus Walleij (2):
      ARM: dts: versatile: Fix up VGA connector
      ARM: dts: integrator: Fix up VGA connector

 Documentation/devicetree/bindings/arm/arm,realview.yaml | 6 +++---
 arch/arm/boot/dts/arm/arm-realview-pb1176.dts           | 2 +-
 arch/arm/boot/dts/arm/integratorap-im-pd1.dts           | 3 +--
 arch/arm/boot/dts/arm/versatile-ab.dts                  | 3 +--
 4 files changed, 6 insertions(+), 8 deletions(-)


From linus.walleij at linaro.org  Wed Feb 21 14:36:25 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 21 Feb 2024 23:36:25 +0100
Subject: [PATCH v2] dt-bindings: arm: realview: Spelling s/ARM 11/Arm11/,
 s/Cortex A-/Cortex-A/
In-Reply-To: <CAMuHMdXftwMRPRb=U58XTOigo0Q0q_i+6M3hQfLdo88QXd2Ykg@mail.gmail.com>
References: <3d4b1bbc105ccb8cc0a4ea79b76c70df7d0683e6.1694768749.git.geert+renesas@glider.be>
 <CACRpkdYcyxQVjiMqoUJ1JbOLeywoeDGR8dY+ZLZT1kdmk1kSVA@mail.gmail.com> <CAMuHMdXftwMRPRb=U58XTOigo0Q0q_i+6M3hQfLdo88QXd2Ykg@mail.gmail.com>
Message-ID: <CACRpkdaYPe4abFQ1B2kpJB51buHdd_aZ==DHY-Lu3W5GdhxpnQ@mail.gmail.com>

On Wed, Feb 14, 2024 at 5:46?PM Geert Uytterhoeven <geert at linux-m68k.org> wrote:

> On Fri, Sep 15, 2023 at 1:34?PM Linus Walleij <linus.walleij at linaro.org> wrote:
> > On Fri, Sep 15, 2023 at 11:07?AM Geert Uytterhoeven
> > <geert+renesas at glider.be> wrote:
> > > Fix misspellings of "Arm11", "Cortex-A8", and "Cortex-A9".
> > >
> > > While at it, add a missing comma before "and", and reflow the paragraph.
> > >
> > > Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> > > Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> >
> > Picked up the patch and applied it on my versatile-dts branch,
> > thanks for cleaning this up Geert!
>
> Looks like this fell through the cracks?
> Should I resend?
> Thanks!

No I just forgot to send my pull request, I've sent it now, sorry!
(Same for the other patch!)

Yours,
Linus Walleij


From wsa+renesas at sang-engineering.com  Wed Feb 21 14:54:54 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Wed, 21 Feb 2024 23:54:54 +0100
Subject: [PATCH v3] i2c: imx: when being a target, mark the last read as
 processed
In-Reply-To: <kgfagzj5vez56levwam6n6tzxl2lu7efnw5x3eadl3uophxism@ph2tghrvedg5>
References: <20240221193013.14233-2-wsa+renesas@sang-engineering.com>
 <kgfagzj5vez56levwam6n6tzxl2lu7efnw5x3eadl3uophxism@ph2tghrvedg5>
Message-ID: <ZdZ_PsNhQ9S1Eab-@shikoro>

On Wed, Feb 21, 2024 at 09:58:23PM +0100, Andi Shyti wrote:
> Hi Wolfram and Corey,
> 
> On Wed, Feb 21, 2024 at 08:27:13PM +0100, Wolfram Sang wrote:
> > From: Corey Minyard <minyard at acm.org>
> > 
> > When being a target, NAK from the controller means that all bytes have
> > been transferred. So, the last byte needs also to be marked as
> > 'processed'. Otherwise index registers of backends may not increase.
> > 
> > Signed-off-by: Corey Minyard <minyard at acm.org>
> > Tested-by: Andrew Manley <andrew.manley at sealingtech.com>
> > Reviewed-by: Andrew Manley <andrew.manley at sealingtech.com>
> > Reviewed-by: Oleksij Rempel <o.rempel at pengutronix.de>
> > [wsa: fixed comment and commit message to properly describe the case]
> > Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
> 
> is this a fix?

In deed, it is:

Fixes: f7414cd6923f ("i2c: imx: support slave mode for imx I2C driver")

-------------- 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/20240221/3e867821/attachment.sig>

From heiko at sntech.de  Wed Feb 21 14:57:43 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 21 Feb 2024 23:57:43 +0100
Subject: [GIT PULL] Rockchip dts64 changes for 6.9 #1
Message-ID: <3622360.hdfAi7Kttb@diego>

Hi Arnd, Kevin, Olof,

please find below and in a subsequent pull-request
Rockchip changes for for 6.9 .

Some new boards, some new peripherals, nothing really stands out.


Please pull!

Thanks
Heiko


The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.9-rockchip-dts64-1

for you to fetch changes up to 4622485f005aaf0f7a684b69280d0494e0ea301e:

  arm64: dts: rockchip: Add USB3.0 to Indiedroid Nova (2024-02-13 20:28:08 +0100)

----------------------------------------------------------------
New boards: Powkiddy RGB10MAX3, Pine64 PineTab2, NanoPi R6C+R6S, Anbernic
RG-ARC S and RG-ARC D.
New peripherals: rs485 on Theobroma Systems boards, usb3 on Indidroid Nova,
Edgeble NCM6A (usb2, m.2, ethernet, wifi, cpu-regulator), Rock-5b rfkill
for wifi, cache information for rk3399.
Snmaller DT fixes (hdmi nodes, aliases, redundant card-detect gpios, max-
frequency for spi-flashes on rock-pi 4 boards, missing pmu-io-domains on
Ringneck)

----------------------------------------------------------------
Alexey Charkov (1):
      arm64: dts: rockchip: add rfkill node for M.2 Key E WiFi on rock-5b

Chris Morgan (8):
      arm64: dts: rockchip: Move device specific properties
      dt-bindings: arm: rockchip: Add Anbernic RG-Arc
      arm64: dts: rockchip: add Anbernic RG-ARC S and RG-ARC D
      arm64: dts: rockchip: Add Touch to Anbernic RG-ARC D
      arm64: dts: rockchip: Update powkiddy rk2023 dtsi for RGB10MAX3
      dt-bindings: arm: rockchip: Add Powkiddy RGB10MAX3
      arm64: dts: rockchip: Add Powkiddy RGB10MAX3
      arm64: dts: rockchip: Add USB3.0 to Indiedroid Nova

Dragan Simic (1):
      arm64: dts: rockchip: Add cache information to the SoC dtsi for RK3399

Farouk Bouabid (2):
      arm64: dts: rockchip: add rs485 support on uart2 of rk3399-puma-haikou
      arm64: dts: rockchip: add rs485 support on uart5 of px30-ringneck-haikou

Hugh Cole-Baker (1):
      arm64: dts: rockchip: enable NanoPC-T6 MiniPCIe power

Iskander Amara (1):
      arm64: dts: rockchip: add missing definition of pmu io domains 1 and 2 on ringneck

Jagan Teki (10):
      arm64: dts: rockchip: Drop edgeble-neu6b dcdc-reg4 regulator-init-microvolt
      arm64: dts: rockchip: Add edgeble-neu6a-common DT
      arm64: dts: rockchip: Add common DT for edgeble-neu6b-io
      arm64: dts: rockchip: Add Edgeble NCM6A WiFi6 Overlay
      arm64: dts: rockchip: Add vdd_cpu_big reg to rk3588-edgeble-ncm6
      arm64: dts: rockchip: Add Edgeble NCM6A-IO 2.5G ETH
      arm64: dts: rockchip: Add Edgeble NCM6A-IO M.2 M-Key
      arm64: dts: rockchip: Add Edgeble NCM6A-IO M.2 B-Key, E-Key
      arm64: dts: rockchip: Add Edgeble NCM6A-IO USB2
      arm64: dts: rockchip: Add LED_GREEN for edgeble-neu6a

Johan Jonker (2):
      arm64: dts: rockchip: fix rk3328 hdmi ports node
      arm64: dts: rockchip: fix rk3399 hdmi ports node

John Clark (2):
      arm64: dts: rockchip: add sdmmc card detect to the nanopc-t6
      arm64: dts: rockchip: fix nanopc-t6 sdmmc regulator

Kever Yang (1):
      arm64: dts: rockchip: remove redundant cd-gpios from rk3588 sdmmc nodes

Manuel Traut (2):
      dt-bindings: arm64: rockchip: Add Pine64 PineTab2
      arm64: dts: rockchip: Add devicetree for Pine64 PineTab2

Muhammed Efe Cetin (3):
      dt-bindings: arm: rockchip: Add NanoPi R6 series boards
      arm64: dts: rockchip: Add support for NanoPi R6S
      arm64: dts: rockchip: Add support for NanoPi R6C

Quentin Schulz (2):
      arm64: dts: rockchip: add spi controller aliases on rk3399
      arm64: dts: rockchip: remove duplicate SPI aliases for helios64

Stefan Nagy (1):
      arm64: dts: rockchip: Increase maximum frequency of SPI flash for ROCK Pi 4A/B/C

Trevor Woerner (1):
      arm64: dts: rockchip: adjust phy-handle name on rock-pi-e

 .../devicetree/bindings/arm/rockchip.yaml          |  47 +-
 arch/arm64/boot/dts/rockchip/Makefile              |   8 +
 .../boot/dts/rockchip/px30-ringneck-haikou.dts     |   1 +
 arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi    |   6 +
 arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts  |   4 +-
 arch/arm64/boot/dts/rockchip/rk3328.dtsi           |  11 +-
 .../boot/dts/rockchip/rk3399-kobol-helios64.dts    |   3 -
 .../arm64/boot/dts/rockchip/rk3399-puma-haikou.dts |   3 +-
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts |   2 +-
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts |   2 +-
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts |   2 +-
 arch/arm64/boot/dts/rockchip/rk3399.dtsi           |  82 +-
 .../boot/dts/rockchip/rk3566-anbernic-rg-arc-d.dts |  60 ++
 .../boot/dts/rockchip/rk3566-anbernic-rg-arc-s.dts |  19 +
 .../boot/dts/rockchip/rk3566-anbernic-rg-arc.dtsi  | 237 ++++++
 .../boot/dts/rockchip/rk3566-anbernic-rg353x.dtsi  |  74 ++
 .../boot/dts/rockchip/rk3566-anbernic-rg503.dts    |  74 ++
 .../boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi   |  74 --
 .../boot/dts/rockchip/rk3566-pinetab2-v0.1.dts     |  28 +
 .../boot/dts/rockchip/rk3566-pinetab2-v2.0.dts     |  48 ++
 arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi  | 943 +++++++++++++++++++++
 .../dts/rockchip/rk3566-powkiddy-rgb10max3.dts     |  87 ++
 .../boot/dts/rockchip/rk3566-powkiddy-rgb30.dts    |  18 +
 .../boot/dts/rockchip/rk3566-powkiddy-rk2023.dts   |  18 +
 .../boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi  |  18 +-
 .../dts/rockchip/rk3588-edgeble-neu6a-common.dtsi  | 466 ++++++++++
 .../boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts  |  10 +-
 .../boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi | 232 +++++
 .../dts/rockchip/rk3588-edgeble-neu6a-wifi.dtso    |  56 ++
 .../boot/dts/rockchip/rk3588-edgeble-neu6a.dtsi    |  25 +-
 .../boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts  |  76 +-
 .../boot/dts/rockchip/rk3588-edgeble-neu6b.dtsi    | 383 +--------
 arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts  |  31 +-
 .../boot/dts/rockchip/rk3588-orangepi-5-plus.dts   |   1 -
 .../arm64/boot/dts/rockchip/rk3588-quartzpro64.dts |   1 -
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts    |   8 +-
 .../boot/dts/rockchip/rk3588s-indiedroid-nova.dts  |   8 +
 .../arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts |  14 +
 .../arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts | 764 +++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts   |   1 -
 40 files changed, 3325 insertions(+), 620 deletions(-)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc-d.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc-s.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-pinetab2-v0.1.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-pinetab2-v2.0.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb10max3.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-wifi.dtso
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts





From heiko at sntech.de  Wed Feb 21 14:58:21 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 21 Feb 2024 23:58:21 +0100
Subject: [GIT PULL] Rockchip dts32 changes for 6.9 #1
Message-ID: <37970455.XM6RcZxFsP@diego>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.9-rockchip-dts32-1

for you to fetch changes up to 15a5ed03000cf61daf87d14628085cb1bc8ae72c:

  ARM: dts: rockchip: fix rk322x hdmi ports node (2024-02-13 20:22:34 +0100)

----------------------------------------------------------------
Display output for rk3128 and some adaptions to binding clarifications
for hdmi nodes on some older socs.

----------------------------------------------------------------
Alex Bee (3):
      ARM: dts: rockchip: Add display subsystem for RK3128
      ARM: dts: rockchip: Add HDMI node for RK3128
      ARM: dts: rockchip: Enable HDMI output for XPI-3128

Johan Jonker (2):
      ARM: dts: rockchip: fix rk3288 hdmi ports node
      ARM: dts: rockchip: fix rk322x hdmi ports node

 arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts | 29 +++++++++++++
 arch/arm/boot/dts/rockchip/rk3128.dtsi         | 60 ++++++++++++++++++++++++++
 arch/arm/boot/dts/rockchip/rk322x.dtsi         | 16 ++++---
 arch/arm/boot/dts/rockchip/rk3288.dtsi         | 16 +++++--
 4 files changed, 113 insertions(+), 8 deletions(-)





From heiko at sntech.de  Wed Feb 21 15:01:20 2024
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 22 Feb 2024 00:01:20 +0100
Subject: [GIT PULL] Rockchip driver changes for 6.9 #1
Message-ID: <5997473.alqRGMn8q6@diego>

Hi Arnd, Kevin, Olof,

in expectation of more real driver-related changes I had started these
binding additions in a driver-branch, but in hindsight they could've also
just lived in the dt branch. So sorry about the additional pull.

Heiko


The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.9-rockchip-drivers1

for you to fetch changes up to 85a33544afa8895803798553c7510658dcbd3546:

  dt-bindings: soc: rockchip: add rk3588 USB3 syscon (2024-02-13 19:37:15 +0100)

----------------------------------------------------------------
dt-binding additions for some syscons (rk3588 usb3, hdptxphy) and a
clock addition to the rk3588 VO syscon binding.
6#

----------------------------------------------------------------
Cristian Ciocaltea (1):
      dt-bindings: soc: rockchip: Add rk3588 hdptxphy syscon

Sebastian Reichel (2):
      dt-bindings: soc: rockchip: add clock to RK3588 VO grf
      dt-bindings: soc: rockchip: add rk3588 USB3 syscon

 .../devicetree/bindings/soc/rockchip/grf.yaml      | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)





From semen.protsenko at linaro.org  Wed Feb 21 15:07:50 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 17:07:50 -0600
Subject: [PATCH 00/16] clk: samsung: Add CPU clocks for Exynos850
In-Reply-To: <29090d97-9118-4765-a4fd-3bbe271a39bd@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org> <29090d97-9118-4765-a4fd-3bbe271a39bd@linaro.org>
Message-ID: <CAPLW+4kmoCoqO=+zXbVw7VsGc-VB2At91ZnJfyTDRtVFmN4aiQ@mail.gmail.com>

On Tue, Feb 20, 2024 at 5:07?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 16/02/2024 23:32, Sam Protsenko wrote:
> > The series implements CPU clock support for Exynos850, adds CPU CMUs to
> > the clock driver and enables those in dts. This is the first step
> > towards cpufreq implementation.
> >
> > The breakup by patch:
> >
> >   * Patch 01: Add bindings
> >   * Patches 02..12: Prepare clk-cpu.c for Exynos850 support
> >   * Patch 13: Add Exynos850 support
> >   * Patch 14: Init PLLs to be in manual mode
> >   * Patch 15: Add CPU CMUs in Exynos850 clock driver
> >   * Patch 16: Add CPU CMUs and clocks in Exynos850 dtsi
>
> This crossed the threshold for a patch bomb, which is in general fine
> for me, but then please put v2 changelog in each patch's changelog. If
> the patch did not change, annotate it as well. It's not possible to keep
> jumping between cover letter and individual patches.
>

The above list is not a change log, I just tried to show that patches
02..12 are cleanups. I'll reword this in v2 to make it less confusing.
And as usual I'll keep the changelog for each patch separately. Thanks
for the review!

> Best regards,
> Krzysztof
>


From jgg at nvidia.com  Wed Feb 21 15:28:39 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Wed, 21 Feb 2024 19:28:39 -0400
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <20240221192205.GA7619@willie-the-truck>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <20240221192205.GA7619@willie-the-truck>
Message-ID: <20240221232839.GY13330@nvidia.com>

On Wed, Feb 21, 2024 at 07:22:06PM +0000, Will Deacon wrote:
> On Tue, Feb 20, 2024 at 09:17:08PM -0400, Jason Gunthorpe wrote:
> > +static inline void __const_memcpy_toio_aligned64(volatile u64 __iomem *to,
> > +						 const u64 *from, size_t count)
> > +{
> > +	switch (count) {
> > +	case 8:
> > +		asm volatile("str %x0, [%8, #8 * 0]\n"
> > +			     "str %x1, [%8, #8 * 1]\n"
> > +			     "str %x2, [%8, #8 * 2]\n"
> > +			     "str %x3, [%8, #8 * 3]\n"
> > +			     "str %x4, [%8, #8 * 4]\n"
> > +			     "str %x5, [%8, #8 * 5]\n"
> > +			     "str %x6, [%8, #8 * 6]\n"
> > +			     "str %x7, [%8, #8 * 7]\n"
> > +			     :
> > +			     : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
> > +			       "rZ"(from[3]), "rZ"(from[4]), "rZ"(from[5]),
> > +			       "rZ"(from[6]), "rZ"(from[7]), "r"(to));
> > +		break;
> > +	case 4:
> > +		asm volatile("str %x0, [%4, #8 * 0]\n"
> > +			     "str %x1, [%4, #8 * 1]\n"
> > +			     "str %x2, [%4, #8 * 2]\n"
> > +			     "str %x3, [%4, #8 * 3]\n"
> > +			     :
> > +			     : "rZ"(from[0]), "rZ"(from[1]), "rZ"(from[2]),
> > +			       "rZ"(from[3]), "r"(to));
> > +		break;
> > +	case 2:
> > +		asm volatile("str %x0, [%2, #8 * 0]\n"
> > +			     "str %x1, [%2, #8 * 1]\n"
> > +			     :
> > +			     : "rZ"(from[0]), "rZ"(from[1]), "r"(to));
> > +		break;
> > +	case 1:
> > +		__raw_writel(*from, to);
> 
> Shouldn't this be __raw_writeq?

Yes! Thanks

Jason


From semen.protsenko at linaro.org  Wed Feb 21 15:41:34 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 17:41:34 -0600
Subject: [PATCH 07/16] clk: samsung: Pass actual clock controller base
 address to CPU_CLK()
In-Reply-To: <8c1f0a4f-8a8b-41e7-b7f1-4c5a38ec7c1a@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
 <20240216223245.12273-8-semen.protsenko@linaro.org> <8c1f0a4f-8a8b-41e7-b7f1-4c5a38ec7c1a@linaro.org>
Message-ID: <CAPLW+4n6zA9=1ZswySPE7MmpbV_f99bi8OM9zawgST=XRDSyZQ@mail.gmail.com>

On Tue, Feb 20, 2024 at 4:53?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 16/02/2024 23:32, Sam Protsenko wrote:
> > The documentation for struct exynos_cpuclk says .ctrl_base field should
> > contain the controller base address. But in reality all Exynos clock
> > drivers are passing CPU_SRC register address via CPU_CLK() macro, which
> > in turn gets assigned to mentioned .ctrl_base field. Because CPU_SRC
> > address usually already has 0x200 offset from controller's base, all
> > other register offsets in clk-cpu.c (like DIVs and MUXes) are specified
> > as offsets from CPU_SRC offset, and not from controller's base. That
> > makes things confusing and not consistent with register offsets provided
> > in Exynis clock drivers, also breaking the contract for .ctrl_base field
>
> Typo: Exynos
>

Will fix in v2.

> > as described in struct exynos_cpuclk doc. Rework all register offsets in
> > clk-cpu.c to be actual offsets from controller's base, and fix offsets
> > provided to CPU_CLK() macro in all Exynos clock drivers.
>
> Change is fine and makes sense on devices having separate CPU clock
> controller. That's not the case for:
> 1. Exynos3250: dedicated CPU clock controller space, but we merged it
> into one driver/binding.
> 2. Exynos4 and 5250: no obvious dedicated CPU clock controller, but
> register layout suggests that there is such, just not explicit.
>
> In all these cases you provide not the correct offset against explicit
> or implicit CPU base, but from main clock controller base.
>
> Mention it briefly in above commit msg.
>

Thanks, you are right. That also means the .ctrl_base field (and its
documentation) is incorrect. I'll rework the commit message and the
field naming to the best of my abilities in v2.

>
> Best regards,
> Krzysztof
>


From linus.walleij at linaro.org  Wed Feb 21 16:04:13 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 22 Feb 2024 01:04:13 +0100
Subject: [PATCH] irqchip: vic: fix a kernel-doc warning
In-Reply-To: <20240221064104.7863-1-rdunlap@infradead.org>
References: <20240221064104.7863-1-rdunlap@infradead.org>
Message-ID: <CACRpkdb6x4pPuSr1UEpjaXQ4hBk7bzRfJtSWQtftfpD_N8-2NQ@mail.gmail.com>

On Wed, Feb 21, 2024 at 7:41?AM Randy Dunlap <rdunlap at infradead.org> wrote:

> Drop one extraneous struct member to quieten a warning:
>
> drivers/irqchip/irq-vic.c:73: warning: Excess struct member 'parent_irq' description in 'vic_device'
>
> Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: Thomas Gleixner <tglx at linutronix.de>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From jgg at nvidia.com  Wed Feb 21 16:27:02 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Wed, 21 Feb 2024 20:27:02 -0400
Subject: [PATCH v3] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
Message-ID: <0-v3-11978fc67151+112-smmu_cd_atomic_jgg@nvidia.com>

If the SMMU is configured to use a two level CD table then
arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
GFP_KERNEL. Due to recent changes this is being done under a spinlock to
iterate over the device list - thus it will trigger a sleeping while
atomic warning:

  arm_smmu_sva_set_dev_pasid()
    mutex_lock(&sva_lock);
    __arm_smmu_sva_bind()
     arm_smmu_mmu_notifier_get()
      spin_lock_irqsave()
      arm_smmu_write_ctx_desc()
	arm_smmu_get_cd_ptr()
         arm_smmu_alloc_cd_leaf_table()
	  dmam_alloc_coherent(GFP_KERNEL)

This is a 64K high order allocation and really should not be done
atomically.

At the moment the rework of the SVA to follow the new API is half
finished. Recently the CD table memory was moved from the domain to the
master, however we have the confusing situation where the SVA code is
wrongly using the RID domains device's list to track which CD tables the
SVA is installed in.

Remove the logic to replicate the CD across all the domain's masters
during attach. We know which master and which CD table the PASID should be
installed in.

Right now SVA only works when dma-iommu.c is in control of the RID
translation, which means we have a single iommu_domain shared across the
entire group and that iommu_domain is not shared outside the group.

Critically this means that the iommu_group->devices list and RID's
smmu_domain->devices list describe the same set of masters.

For PCI cases the core code also insists on singleton groups so there is
only one entry in the smmu_domain->devices list that is equal to the
master being passed in to arm_smmu_sva_set_dev_pasid().

Only non-PCI cases may have multi-device groups. However, the core code
will repeat the calls to arm_smmu_sva_set_dev_pasid() across the entire
iommu_group->devices list.

Instead of having arm_smmu_mmu_notifier_get() indirectly loop over all the
devices in the group via the RID's smmu_domain, rely on
__arm_smmu_sva_bind() to be called for each device in the group and
install the repeated CD entry that way.

This avoids taking the spinlock to access the devices list and permits the
arm_smmu_write_ctx_desc() to use a sleeping allocation. Leave the
arm_smmu_mm_release() as a confusing situation, this requires tracking
attached masters inside the SVA domain.

Removing the loop allows arm_smmu_write_ctx_desc() to be called outside
the spinlock and thus is safe to use GFP_KERNEL.

Move the clearing of the CD into arm_smmu_sva_remove_dev_pasid() so that
arm_smmu_mmu_notifier_get/put() remain paired functions.

Fixes: 24503148c545 ("iommu/arm-smmu-v3: Refactor write_ctx_desc")
Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
Closes: https://lore.kernel.org/all/4e25d161-0cf8-4050-9aa3-dfa21cd63e56 at moroto.mountain/
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c   | 38 ++++++-------------
 1 file changed, 12 insertions(+), 26 deletions(-)

I suggest taking these two patches as well which will further help this code:

https://lore.kernel.org/linux-iommu/12-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg at nvidia.com/
https://lore.kernel.org/linux-iommu/2-v4-e7091cdd9e8d+43b1-smmuv3_newapi_p2_jgg at nvidia.com/

Michael should check it, and Nicolin or Shameer should do a quick sanity check
on their SVA HW.

v3:
  - Pull arm_smmu_write_ctx_desc() up into __arm_smmu_sva_bind() and
    arm_smmu_sva_remove_dev_pasid() to avoid the early exit in
    arm_smmu_mmu_notifier_get()
v2: https://lore.kernel.org/all/0-v2-7988c2682634+261-smmu_cd_atomic_jgg at nvidia.com/

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index 05722121f00e70..4a27fbdb2d8446 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -292,10 +292,8 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
 			  struct mm_struct *mm)
 {
 	int ret;
-	unsigned long flags;
 	struct arm_smmu_ctx_desc *cd;
 	struct arm_smmu_mmu_notifier *smmu_mn;
-	struct arm_smmu_master *master;
 
 	list_for_each_entry(smmu_mn, &smmu_domain->mmu_notifiers, list) {
 		if (smmu_mn->mn.mm == mm) {
@@ -325,28 +323,9 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
 		goto err_free_cd;
 	}
 
-	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
-	list_for_each_entry(master, &smmu_domain->devices, domain_head) {
-		ret = arm_smmu_write_ctx_desc(master, mm_get_enqcmd_pasid(mm),
-					      cd);
-		if (ret) {
-			list_for_each_entry_from_reverse(
-				master, &smmu_domain->devices, domain_head)
-				arm_smmu_write_ctx_desc(
-					master, mm_get_enqcmd_pasid(mm), NULL);
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
-	if (ret)
-		goto err_put_notifier;
-
 	list_add(&smmu_mn->list, &smmu_domain->mmu_notifiers);
 	return smmu_mn;
 
-err_put_notifier:
-	/* Frees smmu_mn */
-	mmu_notifier_put(&smmu_mn->mn);
 err_free_cd:
 	arm_smmu_free_shared_cd(cd);
 	return ERR_PTR(ret);
@@ -363,9 +342,6 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
 
 	list_del(&smmu_mn->list);
 
-	arm_smmu_update_ctx_desc_devices(smmu_domain, mm_get_enqcmd_pasid(mm),
-					 NULL);
-
 	/*
 	 * If we went through clear(), we've already invalidated, and no
 	 * new TLB entry can have been formed.
@@ -381,7 +357,8 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
 	arm_smmu_free_shared_cd(cd);
 }
 
-static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
+static int __arm_smmu_sva_bind(struct device *dev, ioasid_t pasid,
+			       struct mm_struct *mm)
 {
 	int ret;
 	struct arm_smmu_bond *bond;
@@ -404,9 +381,15 @@ static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
 		goto err_free_bond;
 	}
 
+	ret = arm_smmu_write_ctx_desc(master, pasid, bond->smmu_mn->cd);
+	if (ret)
+		goto err_put_notifier;
+
 	list_add(&bond->list, &master->bonds);
 	return 0;
 
+err_put_notifier:
+	arm_smmu_mmu_notifier_put(bond->smmu_mn);
 err_free_bond:
 	kfree(bond);
 	return ret;
@@ -568,6 +551,9 @@ void arm_smmu_sva_remove_dev_pasid(struct iommu_domain *domain,
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
 
 	mutex_lock(&sva_lock);
+
+	arm_smmu_write_ctx_desc(master, id, NULL);
+
 	list_for_each_entry(t, &master->bonds, list) {
 		if (t->mm == mm) {
 			bond = t;
@@ -590,7 +576,7 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
 	struct mm_struct *mm = domain->mm;
 
 	mutex_lock(&sva_lock);
-	ret = __arm_smmu_sva_bind(dev, mm);
+	ret = __arm_smmu_sva_bind(dev, id, mm);
 	mutex_unlock(&sva_lock);
 
 	return ret;

base-commit: c76c50cd425e574df5a071cd7e1805d0764aabff
-- 
2.43.2



From f.fainelli at gmail.com  Wed Feb 21 16:34:57 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 21 Feb 2024 16:34:57 -0800
Subject: [PATCH v5 01/12] dt-bindings: mtd: brcmnand: Updates for bcmbca
 SoCs
In-Reply-To: <20240207202257.271784-2-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-2-william.zhang@broadcom.com>
Message-ID: <e978801c-8bf6-4117-b44d-1c485e3d8769@gmail.com>

On 2/7/24 12:22, William Zhang wrote:
> Update the descriptions to reflect different families of broadband SoC and
> use the general name bcmbca for ARM based SoC.
> 
> Remove the requirement of interrupts property to reflect the driver
> code and only require interrupt-names when interrupts property present.
> 
> Also add myself to the list of maintainers.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>
> Reviewed-by: Rob Herring <robh at kernel.org>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian



From f.fainelli at gmail.com  Wed Feb 21 16:35:17 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 21 Feb 2024 16:35:17 -0800
Subject: [PATCH v5 02/12] dt-bindings: mtd: brcmnand: Add WP pin
 connection property
In-Reply-To: <20240207202257.271784-3-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-3-william.zhang@broadcom.com>
Message-ID: <7be28a94-f0f4-4098-aaa3-be3194fc14b0@gmail.com>

On 2/7/24 12:22, William Zhang wrote:
> Add brcm,wp-not-connected property to have an option for disabling this
> feature on broadband board design that does not connect WP pin.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian



From andrew at codeconstruct.com.au  Wed Feb 21 16:37:05 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Thu, 22 Feb 2024 11:07:05 +1030
Subject: [PATCH v1 10/14] serial: 8250_of: Switch to use
 uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-11-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
	 <20240221183442.4124354-11-andriy.shevchenko@linux.intel.com>
Message-ID: <0a828f2c50de712940fb9a881702ac1678a35b7c.camel@codeconstruct.com.au>

On Wed, 2024-02-21 at 20:31 +0200, Andy Shevchenko wrote:
> Since we have now a common helper to read port properties
> use it instead of sparse home grown solution.

I did some brief testing of the series for the Aspeed machines under
qemu, building them on top of v6.8-rc5:

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make aspeed_g5_defconfig
make -j$(nproc)
qemu-system-arm -M rainier-bmc -nographic -no-reboot -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dtb -initrd ...

I got an oops during boot, which bisected to this change:

[    0.314946] 8<--- cut here ---
[    0.315051] Unable to handle kernel paging request at virtual address fee00000 when write
[    0.315201] [fee00000] *pgd=00000000
[    0.315593] Internal error: Oops: 805 [#1] SMP ARM
[    0.315847] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc5-00010-g8a2c8fe174cf #13
[    0.316071] Hardware name: Generic DT based system
[    0.316216] PC is at io_serial_out+0x18/0x20
[    0.316677] LR is at serial8250_do_set_mctrl+0x54/0x90
[    0.316781] pc : [<8060eea8>]    lr : [<806108b0>]    psr: 40000093
[    0.316891] sp : bf815b08  ip : 00000000  fp : 00000026
[    0.316987] r10: 81698240  r9 : 40000013  r8 : 81cae600
[    0.317087] r7 : 81d7d1a8  r6 : 81d7d110  r5 : 81008158  r4 : 00000000
[    0.317197] r3 : fee00000  r2 : 00000000  r1 : 00000004  r0 : 81008158
[    0.317350] Flags: nZcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
[    0.317471] Control: 10c5387d  Table: 8000406a  DAC: 00000051
[    0.317593] Register r0 information: non-slab/vmalloc memory
[    0.317892] Register r1 information: non-paged memory
[    0.317996] Register r2 information: NULL pointer
[    0.318080] Register r3 information: vmalloc memory
[    0.318176] Register r4 information: NULL pointer
[    0.318264] Register r5 information: non-slab/vmalloc memory
[    0.318362] Register r6 information: slab kmalloc-2k start 81d7d000 pointer offset 272 size 2048
[    0.318701] Register r7 information: slab kmalloc-2k start 81d7d000 pointer offset 424 size 2048
[    0.318860] Register r8 information: slab kmalloc-512 start 81cae600 pointer offset 0 size 512
[    0.319095] Register r9 information: non-paged memory
[    0.319194] Register r10 information: slab kmalloc-64 start 81698240 pointer offset 0 size 64
[    0.319266] Freeing initrd memory: 13684K
[    0.319384] Register r11 information: non-paged memory
[    0.319593] Register r12 information: NULL pointer
[    0.319703] Process swapper/0 (pid: 1, stack limit = 0x(ptrval))
[    0.320006] Stack: (0xbf815b08 to 0xbf816000)
[    0.320157] 5b00:                   81008158 80f85a88 81d7d110 8060cb78 bf815b34 00000026
[    0.320313] 5b20: 0016e360 80cba110 81e65e80 80cfcdf4 00000003 204f2f49 00307830 00000000
[    0.320457] 5b40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.320600] 5b60: 00000000 00000000 00000000 00000000 00000000 ed1677db 81008158 81008158
[    0.320744] 5b80: bf815c00 81e5c5c0 81008304 81007f58 bf815d2c bf815dac 00000000 8060e1f4
[    0.320890] 5ba0: 80cba4ec 8081e2c4 bf815dfc 00000001 00000000 81cf5400 81cf5410 81e65e00
[    0.321030] 5bc0: 00000004 00000000 00000001 80616538 00000000 00000000 00000000 00000000
[    0.321176] 5be0: 1e784000 1e784fff bd7c1a94 00000200 00000000 00000000 00000000 00000000
[    0.321325] 5c00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.321469] 5c20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.321624] 5c40: 00000000 00000000 8060fb34 00000000 00000000 00000000 00000026 00000000
[    0.321777] 5c60: 016e3600 00000000 00000200 00000000 00000000 00000000 00000000 00000000
[    0.321920] 5c80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.322063] 5ca0: 00000000 00000000 b9000040 00000000 00000000 00000000 00000000 00000000
[    0.322204] 5cc0: 00000004 00000000 00000000 00000004 00000000 1e784000 00001000 81cf5410
[    0.322347] 5ce0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.322492] 5d00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000037
[    0.322640] 5d20: 00000001 00000001 00000000 00000000 00000000 00000000 00000000 00000000
[    0.322800] 5d40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.322957] 5d60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.323114] 5d80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.323271] 5da0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.323422] 5dc0: 00000000 00000000 806111c8 80610eb4 00000000 00000000 00000000 00000000
[    0.323573] 5de0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.323723] 5e00: 00000000 ed1677db 00000000 81cf5410 80f85cf8 00000000 00000000 81e5c638
[    0.323878] 5e20: 80e66f48 8067f888 81cf5410 00000000 80f85cf8 00000000 00000000 8067ca08
[    0.324029] 5e40: 81cf5410 00000000 81cf5410 81cf5410 80f85cf8 81cf5454 81cf5410 8067cda8
[    0.324181] 5e60: 60000013 81e5c638 81008d4c 81008d54 81cf5454 81cf5410 00000000 8067cf3c
[    0.324337] 5e80: 81cf5410 80f85cf8 81cf5454 814cec00 00000000 8067d21c 00000000 80f85cf8
[    0.324494] 5ea0: 8067d11c 8067aa04 814cec00 814cec58 816a4bb4 ed1677db 814cec00 81e5c600
[    0.324646] 5ec0: 00000000 80f85cf8 814cec00 8067bc6c 80cba524 00000000 00000006 80f85cf8
[    0.324795] 5ee0: 8158b480 00000006 bf815f14 00000000 80d19438 8067e284 80e221c4 8158b480
[    0.324945] 5f00: 00000006 80e01414 80d2d3b0 000000db 8173ad17 00000000 00000000 00000000
[    0.325096] 5f20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.325247] 5f40: 00000000 00000000 00000000 00000000 00000000 ed1677db 8173ad00 00000020
[    0.325403] 5f60: 00000006 80e3b83c 80e3b860 80e01750 00000006 00000006 00000000 80e004f8
[    0.325553] 5f80: 80f05cc0 80a50e18 00000000 00000000 00000000 00000000 00000000 80a50e34
[    0.325699] 5fa0: 00000000 80a50e18 00000000 8010016c 00000000 00000000 00000000 00000000
[    0.325848] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.325995] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
[    0.326531]  io_serial_out from serial8250_do_set_mctrl+0x54/0x90
[    0.326761]  serial8250_do_set_mctrl from serial_core_register_port+0x4c4/0x694
[    0.326917]  serial_core_register_port from serial8250_register_8250_port+0x310/0x4bc
[    0.327063]  serial8250_register_8250_port from of_platform_serial_probe+0x300/0x45c
[    0.327242]  of_platform_serial_probe from platform_probe+0x60/0xb8
[    0.327367]  platform_probe from really_probe+0xd4/0x3e4
[    0.327471]  really_probe from __driver_probe_device+0x90/0x1ec
[    0.327568]  __driver_probe_device from driver_probe_device+0x38/0xd0
[    0.327674]  driver_probe_device from __driver_attach+0x100/0x1dc
[    0.327793]  __driver_attach from bus_for_each_dev+0x84/0xd4
[    0.327906]  bus_for_each_dev from bus_add_driver+0xec/0x1f0
[    0.328015]  bus_add_driver from driver_register+0x84/0x11c
[    0.328126]  driver_register from do_one_initcall+0x84/0x1c8
[    0.328297]  do_one_initcall from kernel_init_freeable+0x19c/0x22c
[    0.328419]  kernel_init_freeable from kernel_init+0x1c/0x138
[    0.328534]  kernel_init from ret_from_fork+0x14/0x28
[    0.328656] Exception stack(0xbf815fb0 to 0xbf815ff8)
[    0.328755] 5fa0:                                     00000000 00000000 00000000 00000000
[    0.328901] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.329112] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[    0.329413] Code: e3a03000 ee073f9a e2433612 e6ef2072 (e5c32000)
[    0.329824] ---[ end trace 0000000000000000 ]---
[    0.336692] Kernel panic - not syncing: Fatal exception

Andrew



From florian.fainelli at broadcom.com  Wed Feb 21 16:37:55 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Wed, 21 Feb 2024 16:37:55 -0800
Subject: [PATCH v5 06/12] arm64: dts: broadcom: bcmbca: Update router boards
In-Reply-To: <20240207202257.271784-7-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com> <20240207202257.271784-7-william.zhang@broadcom.com>
Message-ID: <20240222003755.670359-1-florian.fainelli@broadcom.com>

From: Florian Fainelli <f.fainelli at gmail.com>

On Wed,  7 Feb 2024 12:22:51 -0800, William Zhang <william.zhang at broadcom.com> wrote:
> Enable the nand controller and add WP pin connection property in actual
> board dts as they are board level properties now that they are disabled
> and moved out from SoC dtsi.
> 
> Also remove the unnecessary brcm,nand-has-wp property from AC5300 board.
> This property is only needed for some old controller that this board
> does not apply.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree/next, thanks!
--
Florian


From f.fainelli at gmail.com  Wed Feb 21 16:39:05 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 21 Feb 2024 16:39:05 -0800
Subject: [PATCH v5 04/12] ARM: dts: broadcom: bcmbca: Add NAND controller
 node
In-Reply-To: <20240207202257.271784-5-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-5-william.zhang@broadcom.com>
Message-ID: <c145b90c-e9f0-4d82-94cc-baf7bfda5954@gmail.com>

On 2/7/24 12:22, William Zhang wrote:
> Add support for Broadcom STB NAND controller in BCMBCA ARMv7 chip dts
> files.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>

I would like to apply this and the next one, but the use of the 
brcm,nand-ecc-use-strap property which is still being discussed would 
require me to wait a bit, unless you want to split things up and add the 
NAND controller node(s), and then issue a subsequent patch which adds 
"brcm,nand-ecc-use-strap" where relevant.

You have a few days to decide before I send the pull request for 6.9.

Thanks!
-- 
Florian



From f.fainelli at gmail.com  Wed Feb 21 16:40:48 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 21 Feb 2024 16:40:48 -0800
Subject: [PATCH v5 06/12] arm64: dts: broadcom: bcmbca: Update router
 boards
In-Reply-To: <20240222003755.670359-1-florian.fainelli@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-7-william.zhang@broadcom.com>
 <20240222003755.670359-1-florian.fainelli@broadcom.com>
Message-ID: <1e636620-d456-4bb8-a5f0-742be3a9d6ad@gmail.com>

On 2/21/24 16:37, Florian Fainelli wrote:
> From: Florian Fainelli <f.fainelli at gmail.com>
> 
> On Wed,  7 Feb 2024 12:22:51 -0800, William Zhang <william.zhang at broadcom.com> wrote:
>> Enable the nand controller and add WP pin connection property in actual
>> board dts as they are board level properties now that they are disabled
>> and moved out from SoC dtsi.
>>
>> Also remove the unnecessary brcm,nand-has-wp property from AC5300 board.
>> This property is only needed for some old controller that this board
>> does not apply.
>>
>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>> ---
> 
> Applied to https://github.com/Broadcom/stblinux/commits/devicetree/next, thanks!
> --
> Florian

Actually no, cannot apply this just yet since this depends upon patch #5.
-- 
Florian



From semen.protsenko at linaro.org  Wed Feb 21 16:42:18 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 18:42:18 -0600
Subject: [PATCH 11/16] clk: samsung: Keep register offsets in chip
 specific structure
In-Reply-To: <ce515530-428a-4a21-8c56-5a497cc8130a@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
 <20240216223245.12273-12-semen.protsenko@linaro.org> <ce515530-428a-4a21-8c56-5a497cc8130a@linaro.org>
Message-ID: <CAPLW+4=kpk=Vg=nX-hVxcCS0OttC6xmyUcB005tmX+vtUF9TLA@mail.gmail.com>

On Tue, Feb 20, 2024 at 5:04?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 16/02/2024 23:32, Sam Protsenko wrote:
> > Abstract CPU clock registers by keeping their offsets in a dedicated
> > chip specific structure to accommodate for oncoming Exynos850 support,
> > which has different offsets for cluster 0 and cluster 1. This rework
> > also makes it possible to use exynos_set_safe_div() for all chips, so
> > exynos5433_set_safe_div() is removed here to reduce the code
> > duplication.
> >
>
> So that's the answer why you could not use flags anymore - you need an
> enum, not a bitmap. Such short explanation should be in previous commits
> justifying moving reg layout to new property.

Will do, thanks.

>
> > No functional change.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> >  drivers/clk/samsung/clk-cpu.c | 156 +++++++++++++++++++---------------
> >  1 file changed, 86 insertions(+), 70 deletions(-)
> >
> > diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
> > index 04394d2166c9..744b609c222d 100644
> > --- a/drivers/clk/samsung/clk-cpu.c
> > +++ b/drivers/clk/samsung/clk-cpu.c
> > @@ -44,12 +44,14 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
> >
> >  /**
> >   * struct exynos_cpuclk_chip - Chip specific data for CPU clock
> > + * @regs: register offsets for CPU related clocks
> >   * @pre_rate_cb: callback to run before CPU clock rate change
> >   * @post_rate_cb: callback to run after CPU clock rate change
> >   */
> >  struct exynos_cpuclk_chip {
> > -     exynos_rate_change_fn_t pre_rate_cb;
> > -     exynos_rate_change_fn_t post_rate_cb;
> > +     const void                              * const regs;
>
> Why this is void?
>

Different chips can have very different register layout. For example,
older Exynos chips usually keep multiple CPU divider ratios in one
single register, whereas more modern chips have a dedicated register
for each divider clock. Also, old chips usually split divider ratio vs
DIV clock status between different registers, but in modern chips they
both live in one single register. Having (void *) makes it possible to
keep pointers to different structures, and each function for the
particular chip can "know" which exactly structure is stored there,
casting (void *) to a needed type. Another way to do that would be to
have "one-size-fits-all" structure with all possible registers for all
possible chips. I don't know, I just didn't like that for a couple of
reasons, so decided to go with (void *).

I'll add some explanation in the commit message in v2.

> > +     exynos_rate_change_fn_t                 pre_rate_cb;
> > +     exynos_rate_change_fn_t                 post_rate_cb;
> >  };
> >
>
>
>
> Best regards,
> Krzysztof
>


From shaojijie at huawei.com  Wed Feb 21 16:57:12 2024
From: shaojijie at huawei.com (Jijie Shao)
Date: Thu, 22 Feb 2024 08:57:12 +0800
Subject: [PATCH 5/6] net: hns3: Remove io_stop_wc() calls after
 __iowrite64_copy()
In-Reply-To: <5-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
References: <5-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
Message-ID: <45ac5429-df48-489e-928f-8444aea127cd@huawei.com>

Reviewed-by: Jijie Shao<shaojijie at huawei.com>

on 2024/2/21 9:17, Jason Gunthorpe wrote:
> Now that the ARM64 arch implementation does the DGH as part of
> __iowrite64_copy() there is no reason to open code this in drivers.
>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>   drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 4 ----
>   1 file changed, 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
> index f1695c889d3a07..ff556c2b5bacb4 100644
> --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
> +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
> @@ -2068,8 +2068,6 @@ static void hns3_tx_push_bd(struct hns3_enet_ring *ring, int num)
>   	__iowrite64_copy(ring->tqp->mem_base, desc,
>   			 (sizeof(struct hns3_desc) * HNS3_MAX_PUSH_BD_NUM) /
>   			 HNS3_BYTES_PER_64BIT);
> -
> -	io_stop_wc();
>   }
>   
>   static void hns3_tx_mem_doorbell(struct hns3_enet_ring *ring)
> @@ -2088,8 +2086,6 @@ static void hns3_tx_mem_doorbell(struct hns3_enet_ring *ring)
>   	u64_stats_update_begin(&ring->syncp);
>   	ring->stats.tx_mem_doorbell += ring->pending_buf;
>   	u64_stats_update_end(&ring->syncp);
> -
> -	io_stop_wc();
>   }
>   
>   static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num,


From kuba at kernel.org  Wed Feb 21 17:00:23 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Wed, 21 Feb 2024 17:00:23 -0800
Subject: [PATCH net-next v8 08/13] netlink: specs: add ethnl PHY_GET
 command set
In-Reply-To: <20240220184217.3689988-9-maxime.chevallier@bootlin.com>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
	<20240220184217.3689988-9-maxime.chevallier@bootlin.com>
Message-ID: <20240221170023.452a01ca@kernel.org>

On Tue, 20 Feb 2024 19:42:11 +0100 Maxime Chevallier wrote:
> +      -
> +        name: upstream-phy-index
> +        type: u32

The C define appears to be called:

	ETHTOOL_A_PHY_UPSTREAM_INDEX,		/* u32 */

either it needs to gain the PHY_ or the spec needs to lose the phy-,
otherwise C code gen gets upset:

ethtool-user.c:689:10: error: ?ETHTOOL_A_PHY_UPSTREAM_PHY_INDEX? undeclared here (not in a function); did you mean ?ETHTOOL_A_PHY_UPSTREAM_INDEX??
  689 |         [ETHTOOL_A_PHY_UPSTREAM_PHY_INDEX] = { .name = "upstream-phy-index", .type = YNL_PT_U32, },
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |          ETHTOOL_A_PHY_UPSTREAM_INDEX

Unfortunately ethtool in the in-between state where we can auto-gen
user space code (or rather most of it) but the uAPI header is not
auto-generated so we need to take extra care to keep things in sync :(


From tommy_huang at aspeedtech.com  Wed Feb 21 17:10:39 2024
From: tommy_huang at aspeedtech.com (Tommy Huang)
Date: Thu, 22 Feb 2024 01:10:39 +0000
Subject: [PATCH] i2c: aspeed: Fix the dummy irq expected print
In-Reply-To: <nbkkaktcozbhly44hii3zwie7ivsra3qxzdibyzhyhooxrudvb@zik6skmkki2c>
References: <20240216120455.4138642-1-tommy_huang@aspeedtech.com>
 <nbkkaktcozbhly44hii3zwie7ivsra3qxzdibyzhyhooxrudvb@zik6skmkki2c>
Message-ID: <TYZPR06MB61911F076C8719C6A7D57B97E1562@TYZPR06MB6191.apcprd06.prod.outlook.com>

Hi Andy,

	Thanks for your comment.

> -----Original Message-----
> From: Andi Shyti <andi.shyti at kernel.org>
> Sent: Thursday, February 22, 2024 5:15 AM
> To: Tommy Huang <tommy_huang at aspeedtech.com>
> Cc: brendan.higgins at linux.dev; p.zabel at pengutronix.de;
> linux-i2c at vger.kernel.org; openbmc at lists.ozlabs.org;
> benh at kernel.crashing.org; joel at jms.id.au; andrew at aj.id.au;
> linux-arm-kernel at lists.infradead.org; linux-aspeed at lists.ozlabs.org;
> linux-kernel at vger.kernel.org; BMC-SW <BMC-SW at aspeedtech.com>
> Subject: Re: [PATCH] i2c: aspeed: Fix the dummy irq expected print
> 
> Hi Tommy,
> 
> On Fri, Feb 16, 2024 at 08:04:55PM +0800, Tommy Huang wrote:
> > When the i2c error condition occurred and master state was not idle,
> > the master irq function will goto complete state without any other
> > interrupt handling. It would cause dummy irq expected print. Under
> > this condition, assign the irq_status into irq_handle.
> 
> I'm sorry, but I don't understand much from your log here.
> 
> Do you mean that irq_handled in aspeed_i2c_master_irq() is left with some
> states that is not supposed to have and then you end up printing here:
> 
> 	dev_err(bus->dev,
> 		"irq handled != irq. expected 0x%08x, but was 0x%08x\n",
> 		irq_received, irq_handled);
> 
> Can you please explain better?
> 

Yes. If the platform met any irq error condition and the i2c wasn't stated under ASPEED_I2C_MASTER_INACTIVE.
Then the code flow would goto the end of aspeed_i2c_master_irq.

	ret = aspeed_i2c_is_irq_error(irq_status);
	if (ret) {
		...
		irq_handled |= (irq_status & ASPEED_I2CD_INTR_MASTER_ERRORS);
		if (bus->master_state != ASPEED_I2C_MASTER_INACTIVE) {
			bus->cmd_err = ret;
			bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
			goto out_complete;
		}
	}

Some master interrupt states were not handled under this situation.
The fake irq not equaled message would be filled into whole of demsg.
It's most like below example.

...
aspeed-i2c-bus 1e78a780. i2c-bus: irq handled != irq. expected 0x00000030, but was 0x00000020
aspeed-i2c-bus 1e78a780. i2c-bus: irq handled != irq. expected 0x00000030, but was 0x00000020
aspeed-i2c-bus 1e78a780. i2c-bus: irq handled != irq. expected 0x00000030, but was 0x00000020
...

I thought the bus->cmd_err has been filled error reason and it would be returned to upper layer.
So, I didn't think the print should be existed.

> If that's the case, wouldn't it make more sense to check for
> bus->master_state != ASPEED_I2C_MASTER_INACTIVE) earlier?
> 

Did you suggest to add "bus->master_state != ASPEED_I2C_MASTER_INACTIVE" judgement before print the irq not equal print?

> And, still, If that's the case, I believe you might need the Fixes tag. It's true that
> you are not really failing, but you are not reporting a failure by mistake.
> 
> Thanks,
> Andi
> 
> > Signed-off-by: Tommy Huang <tommy_huang at aspeedtech.com>
> > ---
> >  drivers/i2c/busses/i2c-aspeed.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/i2c/busses/i2c-aspeed.c
> > b/drivers/i2c/busses/i2c-aspeed.c index 5511fd46a65e..ce8c4846b7fa
> > 100644
> > --- a/drivers/i2c/busses/i2c-aspeed.c
> > +++ b/drivers/i2c/busses/i2c-aspeed.c
> > @@ -445,6 +445,7 @@ static u32 aspeed_i2c_master_irq(struct
> aspeed_i2c_bus *bus, u32 irq_status)
> >  			irq_status);
> >  		irq_handled |= (irq_status & ASPEED_I2CD_INTR_MASTER_ERRORS);
> >  		if (bus->master_state != ASPEED_I2C_MASTER_INACTIVE) {
> > +			irq_handled = irq_status;
> >  			bus->cmd_err = ret;
> >  			bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
> >  			goto out_complete;
> > --
> > 2.25.1
> >


From patchwork-bot+netdevbpf at kernel.org  Wed Feb 21 17:20:28 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Thu, 22 Feb 2024 01:20:28 +0000
Subject: [PATCH net v3] net: sparx5: Add spinlock for frame transmission from
 CPU
In-Reply-To: <20240219080043.1561014-1-horatiu.vultur@microchip.com>
References: <20240219080043.1561014-1-horatiu.vultur@microchip.com>
Message-ID: <170856482859.21333.7578746670670805119.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Mon, 19 Feb 2024 09:00:43 +0100 you wrote:
> Both registers used when doing manual injection or fdma injection are
> shared between all the net devices of the switch. It was noticed that
> when having two process which each of them trying to inject frames on
> different ethernet ports, that the HW started to behave strange, by
> sending out more frames then expected. When doing fdma injection it is
> required to set the frame in the DCB and then make sure that the next
> pointer of the last DCB is invalid. But because there is no locks for
> this, then easily this pointer between the DCB can be broken and then it
> would create a loop of DCBs. And that means that the HW will
> continuously transmit these frames in a loop. Until the SW will break
> this loop.
> Therefore to fix this issue, add a spin lock for when accessing the
> registers for manual or fdma injection.
> 
> [...]

Here is the summary with links:
  - [net,v3] net: sparx5: Add spinlock for frame transmission from CPU
    https://git.kernel.org/netdev/net/c/603ead96582d

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 Feb 21 17:20:28 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Thu, 22 Feb 2024 01:20:28 +0000
Subject: [PATCH net] net: stmmac: Fix EST offset for dwmac 5.10
In-Reply-To: <20240220-stmmac_est-v1-1-c41f9ae2e7b7@linutronix.de>
References: <20240220-stmmac_est-v1-1-c41f9ae2e7b7@linutronix.de>
Message-ID: <170856482864.21333.14662830246754937684.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Tue, 20 Feb 2024 09:22:46 +0100 you wrote:
> Fix EST offset for dwmac 5.10.
> 
> Currently configuring Qbv doesn't work as expected. The schedule is
> configured, but never confirmed:
> 
> |[  128.250219] imx-dwmac 428a0000.ethernet eth1: configured EST
> 
> [...]

Here is the summary with links:
  - [net] net: stmmac: Fix EST offset for dwmac 5.10
    https://git.kernel.org/netdev/net/c/90d07e36d400

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From hejunhao3 at huawei.com  Wed Feb 21 17:21:39 2024
From: hejunhao3 at huawei.com (hejunhao)
Date: Thu, 22 Feb 2024 09:21:39 +0800
Subject: [PATCH 4/7] drivers/perf: hisi_pcie: Check the target filter
 properly
In-Reply-To: <03acfe6b-bcde-8a11-ea6d-add1998d5bd1@huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
 <20240204074527.47110-5-yangyicong@huawei.com>
 <20240208122902.0000768f@Huawei.com>
 <03acfe6b-bcde-8a11-ea6d-add1998d5bd1@huawei.com>
Message-ID: <0ab7dae0-e132-2b8a-5a6c-1e517c92aa01@huawei.com>


On 2024/2/21 17:46, Yicong Yang wrote:
> On 2024/2/8 20:29, Jonathan Cameron wrote:
>> On Sun, 4 Feb 2024 15:45:24 +0800
>> Yicong Yang <yangyicong at huawei.com> wrote:
>>
>>> From: Junhao He <hejunhao3 at huawei.com>
>>>
>>> The PMU can monitor traffic of certain target Root Port or downstream
>>> target Endpoint. User can specify the target filter by the "port" or
>>> "bdf" option respectively. The PMU can only monitor the Root Port or
>>> Endpoint on the same PCIe core so the value of "port" or "bdf" should
>>> be valid and will be checked by the driver.
>>>
>>> Currently at least and only one of "port" and "bdf" option must be set.
>>> If "port" filter is not set or is set explicitly to zero (default),
>>> driver will regard the user specifies a "bdf" option since "port" option
>>> is a bitmask of the target Root Ports and zero is not a valid
>>> value.
>>>
>>> If user not explicitly set "port" or "bdf" filter, the driver uses "bdf"
>>> default value (zero) to set target filter, but driver will skip the
>>> check of bdf=0, although it's a valid value (meaning 0000:000:00.0).
>>> Then the user just gets zero.
>>>
>>> Therefore, we need to check if both "port" and "bdf" are invalid, then
>>> return failure and report warning.
>>>
>>> Testing:
>>> before the patch:
>>>                     0      hisi_pcie0_core1/rx_mrd_flux/
>>>                     0      hisi_pcie0_core1/rx_mrd_flux,port=0/
>>>                24,124      hisi_pcie0_core1/rx_mrd_flux,port=1/
>>>                     0      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
>>>       <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/
>> Nice to include an example that works for bdf
>> 			    hisi_pcie0_core1/rx_mrd_flux,bdf=1,port=0
>> or something like that?
>>> after the patch:
>>>       <not supported>      hisi_pcie0_core1/rx_mrd_flux/
>>>       <not supported>      hisi_pcie0_core1/rx_mrd_flux,port=0/
>>>                24,153      hisi_pcie0_core1/rx_mrd_flux,port=1/
>>>       <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
>>>       <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/
>>>
>>> Signed-off-by: Junhao He <hejunhao3 at huawei.com>
>>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> Clearly the current situation is wrong, but perhaps we can
>> have a more intuitive scheme (could be added as a follow up patch)
>> and have the driver figure out which port the bdf lies below?
>>
>> Maybe that's a job for userspace tooling rather than the driver, but
>> the driver already has verification code and it wouldn't be hard
>> to not just check the rp is ours, but also set the filter to specify
>> that rp, or maybe just set the mask to include them all?
>>
> To do a check should be simple, we can decode the bdf and find the target
> endpoint and related root port for doing the check.

The function hisi_pcie_pmu_valid_requester_id() already does this.
It can get the RP of the bdf, then check whether the RP is within
the RP range of the PCIe PMU.

> Another example is what we've done in hisi_ptt that we maintian a list of
> supported root ports and endpoints, but that will be a bit more complex.
>
>> Jonathan
>>
>>
>>> ---
>>>   drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++----
>>>   1 file changed, 4 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>>> index 83be3390686c..b91f03c02c57 100644
>>> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
>>> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>>> @@ -306,10 +306,10 @@ static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
>>>   	if (hisi_pcie_get_trig_len(event) > HISI_PCIE_TRIG_MAX_VAL)
>>>   		return false;
>>>   
>>> -	if (requester_id) {
>>> -		if (!hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
>>> -			return false;
>>> -	}
>>> +	/* Need to explicitly set filter of "port" or "bdf" */
>>> +	if (!hisi_pcie_get_port(event) &&
>>> +	    !hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
>>> +		return false;
>>>   
>>>   	return true;
>>>   }
>> .
>>



From hejunhao3 at huawei.com  Wed Feb 21 17:29:49 2024
From: hejunhao3 at huawei.com (hejunhao)
Date: Thu, 22 Feb 2024 09:29:49 +0800
Subject: [PATCH 4/7] drivers/perf: hisi_pcie: Check the target filter
 properly
In-Reply-To: <20240208122902.0000768f@Huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
 <20240204074527.47110-5-yangyicong@huawei.com>
 <20240208122902.0000768f@Huawei.com>
Message-ID: <181ca17c-a902-78e0-095f-5cc194dbc52e@huawei.com>


On 2024/2/8 20:29, Jonathan Cameron wrote:
> On Sun, 4 Feb 2024 15:45:24 +0800
> Yicong Yang <yangyicong at huawei.com> wrote:
>
>> From: Junhao He <hejunhao3 at huawei.com>
>>
>> The PMU can monitor traffic of certain target Root Port or downstream
>> target Endpoint. User can specify the target filter by the "port" or
>> "bdf" option respectively. The PMU can only monitor the Root Port or
>> Endpoint on the same PCIe core so the value of "port" or "bdf" should
>> be valid and will be checked by the driver.
>>
>> Currently at least and only one of "port" and "bdf" option must be set.
>> If "port" filter is not set or is set explicitly to zero (default),
>> driver will regard the user specifies a "bdf" option since "port" option
>> is a bitmask of the target Root Ports and zero is not a valid
>> value.
>>
>> If user not explicitly set "port" or "bdf" filter, the driver uses "bdf"
>> default value (zero) to set target filter, but driver will skip the
>> check of bdf=0, although it's a valid value (meaning 0000:000:00.0).
>> Then the user just gets zero.
>>
>> Therefore, we need to check if both "port" and "bdf" are invalid, then
>> return failure and report warning.
>>
>> Testing:
>> before the patch:
>>                     0      hisi_pcie0_core1/rx_mrd_flux/
>>                     0      hisi_pcie0_core1/rx_mrd_flux,port=0/
>>                24,124      hisi_pcie0_core1/rx_mrd_flux,port=1/
>>                     0      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
>>       <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/
> Nice to include an example that works for bdf
> 			    hisi_pcie0_core1/rx_mrd_flux,bdf=1,port=0
> or something like that?

Yes, I will do that.
These combined parameter test cases have been validated.

>> after the patch:
>>       <not supported>      hisi_pcie0_core1/rx_mrd_flux/
>>       <not supported>      hisi_pcie0_core1/rx_mrd_flux,port=0/
>>                24,153      hisi_pcie0_core1/rx_mrd_flux,port=1/
>>       <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
>>       <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/
>>
>> Signed-off-by: Junhao He <hejunhao3 at huawei.com>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> Clearly the current situation is wrong, but perhaps we can
> have a more intuitive scheme (could be added as a follow up patch)
> and have the driver figure out which port the bdf lies below?
>
> Maybe that's a job for userspace tooling rather than the driver, but
> the driver already has verification code and it wouldn't be hard
> to not just check the rp is ours, but also set the filter to specify
> that rp, or maybe just set the mask to include them all?
>
> Jonathan
>
>
>> ---
>>   drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++----
>>   1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> index 83be3390686c..b91f03c02c57 100644
>> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> @@ -306,10 +306,10 @@ static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
>>   	if (hisi_pcie_get_trig_len(event) > HISI_PCIE_TRIG_MAX_VAL)
>>   		return false;
>>   
>> -	if (requester_id) {
>> -		if (!hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
>> -			return false;
>> -	}
>> +	/* Need to explicitly set filter of "port" or "bdf" */
>> +	if (!hisi_pcie_get_port(event) &&
>> +	    !hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
>> +		return false;
>>   
>>   	return true;
>>   }
>



From mshavit at google.com  Wed Feb 21 18:37:56 2024
From: mshavit at google.com (Michael Shavit)
Date: Thu, 22 Feb 2024 10:37:56 +0800
Subject: [PATCH v3] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
In-Reply-To: <0-v3-11978fc67151+112-smmu_cd_atomic_jgg@nvidia.com>
References: <0-v3-11978fc67151+112-smmu_cd_atomic_jgg@nvidia.com>
Message-ID: <CAKHBV24y8p49cPJQhwDpRu0NYw74SjNCJo9MohwQ35NUJL92mg@mail.gmail.com>

On Thu, Feb 22, 2024 at 8:27?AM Jason Gunthorpe <jgg at nvidia.com> wrote:
>
> If the SMMU is configured to use a two level CD table then
> arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
> GFP_KERNEL. Due to recent changes this is being done under a spinlock to
> iterate over the device list - thus it will trigger a sleeping while
> atomic warning:
>
>   arm_smmu_sva_set_dev_pasid()
>     mutex_lock(&sva_lock);
>     __arm_smmu_sva_bind()
>      arm_smmu_mmu_notifier_get()
>       spin_lock_irqsave()
>       arm_smmu_write_ctx_desc()
>         arm_smmu_get_cd_ptr()
>          arm_smmu_alloc_cd_leaf_table()
>           dmam_alloc_coherent(GFP_KERNEL)
>
> This is a 64K high order allocation and really should not be done
> atomically.
>
> At the moment the rework of the SVA to follow the new API is half
> finished. Recently the CD table memory was moved from the domain to the
> master, however we have the confusing situation where the SVA code is
> wrongly using the RID domains device's list to track which CD tables the
> SVA is installed in.
>
> Remove the logic to replicate the CD across all the domain's masters
> during attach. We know which master and which CD table the PASID should be
> installed in.
>
> Right now SVA only works when dma-iommu.c is in control of the RID
> translation, which means we have a single iommu_domain shared across the
> entire group and that iommu_domain is not shared outside the group.
>
> Critically this means that the iommu_group->devices list and RID's
> smmu_domain->devices list describe the same set of masters.
>
> For PCI cases the core code also insists on singleton groups so there is
> only one entry in the smmu_domain->devices list that is equal to the
> master being passed in to arm_smmu_sva_set_dev_pasid().
>
> Only non-PCI cases may have multi-device groups. However, the core code
> will repeat the calls to arm_smmu_sva_set_dev_pasid() across the entire
> iommu_group->devices list.
>
> Instead of having arm_smmu_mmu_notifier_get() indirectly loop over all the
> devices in the group via the RID's smmu_domain, rely on
> __arm_smmu_sva_bind() to be called for each device in the group and
> install the repeated CD entry that way.
>
> This avoids taking the spinlock to access the devices list and permits the
> arm_smmu_write_ctx_desc() to use a sleeping allocation. Leave the
> arm_smmu_mm_release() as a confusing situation, this requires tracking
> attached masters inside the SVA domain.
>
> Removing the loop allows arm_smmu_write_ctx_desc() to be called outside
> the spinlock and thus is safe to use GFP_KERNEL.
>
> Move the clearing of the CD into arm_smmu_sva_remove_dev_pasid() so that
> arm_smmu_mmu_notifier_get/put() remain paired functions.
>
> Fixes: 24503148c545 ("iommu/arm-smmu-v3: Refactor write_ctx_desc")
> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> Closes: https://lore.kernel.org/all/4e25d161-0cf8-4050-9aa3-dfa21cd63e56 at moroto.mountain/
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c   | 38 ++++++-------------
>  1 file changed, 12 insertions(+), 26 deletions(-)
>
> I suggest taking these two patches as well which will further help this code:
>
> https://lore.kernel.org/linux-iommu/12-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg at nvidia.com/
> https://lore.kernel.org/linux-iommu/2-v4-e7091cdd9e8d+43b1-smmuv3_newapi_p2_jgg at nvidia.com/
>
> Michael should check it, and Nicolin or Shameer should do a quick sanity check
> on their SVA HW.
>
> v3:
>   - Pull arm_smmu_write_ctx_desc() up into __arm_smmu_sva_bind() and
>     arm_smmu_sva_remove_dev_pasid() to avoid the early exit in
>     arm_smmu_mmu_notifier_get()
> v2: https://lore.kernel.org/all/0-v2-7988c2682634+261-smmu_cd_atomic_jgg at nvidia.com/
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> index 05722121f00e70..4a27fbdb2d8446 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> @@ -292,10 +292,8 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
>                           struct mm_struct *mm)
>  {
>         int ret;
> -       unsigned long flags;
>         struct arm_smmu_ctx_desc *cd;
>         struct arm_smmu_mmu_notifier *smmu_mn;
> -       struct arm_smmu_master *master;
>
>         list_for_each_entry(smmu_mn, &smmu_domain->mmu_notifiers, list) {
>                 if (smmu_mn->mn.mm == mm) {
> @@ -325,28 +323,9 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
>                 goto err_free_cd;
>         }
>
> -       spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> -       list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> -               ret = arm_smmu_write_ctx_desc(master, mm_get_enqcmd_pasid(mm),
> -                                             cd);
> -               if (ret) {
> -                       list_for_each_entry_from_reverse(
> -                               master, &smmu_domain->devices, domain_head)
> -                               arm_smmu_write_ctx_desc(
> -                                       master, mm_get_enqcmd_pasid(mm), NULL);
> -                       break;
> -               }
> -       }
> -       spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
> -       if (ret)
> -               goto err_put_notifier;
> -
>         list_add(&smmu_mn->list, &smmu_domain->mmu_notifiers);
>         return smmu_mn;
>
> -err_put_notifier:
> -       /* Frees smmu_mn */
> -       mmu_notifier_put(&smmu_mn->mn);
>  err_free_cd:
>         arm_smmu_free_shared_cd(cd);
>         return ERR_PTR(ret);
> @@ -363,9 +342,6 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
>
>         list_del(&smmu_mn->list);
>
> -       arm_smmu_update_ctx_desc_devices(smmu_domain, mm_get_enqcmd_pasid(mm),
> -                                        NULL);
> -
>         /*
>          * If we went through clear(), we've already invalidated, and no
>          * new TLB entry can have been formed.
> @@ -381,7 +357,8 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
>         arm_smmu_free_shared_cd(cd);
>  }
>
> -static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
> +static int __arm_smmu_sva_bind(struct device *dev, ioasid_t pasid,
> +                              struct mm_struct *mm)
>  {
>         int ret;
>         struct arm_smmu_bond *bond;
> @@ -404,9 +381,15 @@ static int __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
>                 goto err_free_bond;
>         }
>
> +       ret = arm_smmu_write_ctx_desc(master, pasid, bond->smmu_mn->cd);
> +       if (ret)
> +               goto err_put_notifier;
> +
>         list_add(&bond->list, &master->bonds);
>         return 0;
>
> +err_put_notifier:
> +       arm_smmu_mmu_notifier_put(bond->smmu_mn);
>  err_free_bond:
>         kfree(bond);
>         return ret;
> @@ -568,6 +551,9 @@ void arm_smmu_sva_remove_dev_pasid(struct iommu_domain *domain,
>         struct arm_smmu_master *master = dev_iommu_priv_get(dev);
>
>         mutex_lock(&sva_lock);
> +
> +       arm_smmu_write_ctx_desc(master, id, NULL);
> +
>         list_for_each_entry(t, &master->bonds, list) {
>                 if (t->mm == mm) {
>                         bond = t;
> @@ -590,7 +576,7 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
>         struct mm_struct *mm = domain->mm;
>
>         mutex_lock(&sva_lock);
> -       ret = __arm_smmu_sva_bind(dev, mm);
> +       ret = __arm_smmu_sva_bind(dev, id, mm);
>         mutex_unlock(&sva_lock);
>
>         return ret;
>
> base-commit: c76c50cd425e574df5a071cd7e1805d0764aabff
> --
> 2.43.2
>
Reviewed-by: Michael Shavit <mshavit at google.com>


From Irui.Wang at mediatek.com  Wed Feb 21 18:49:06 2024
From: Irui.Wang at mediatek.com (=?utf-8?B?SXJ1aSBXYW5nICjnjovnkZ4p?=)
Date: Thu, 22 Feb 2024 02:49:06 +0000
Subject: [PATCH] media: mediatek: vcodec: Handle VP9 superframe bitstream
 with 8 sub-frames
In-Reply-To: <6bed645bc3ddd51092ed8f6e49672af40735c83d.camel@ndufresne.ca>
References: <20240218115954.4038-1-irui.wang@mediatek.com>
	 <6bed645bc3ddd51092ed8f6e49672af40735c83d.camel@ndufresne.ca>
Message-ID: <b1a4230964f3949e4f24747b53264f41721f4478.camel@mediatek.com>

Dear Nicolas,

Thanks for your reviewing.
Yes, this patch is just for the VP9 stateful decoder process, so the
super frame is handled in stateful driver.

On Mon, 2024-02-19 at 16:09 -0500, Nicolas Dufresne wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  Hi,
> 
> Le dimanche 18 f?vrier 2024 ? 19:59 +0800, Irui Wang a ?crit :
> > The VP9 bitstream has 8 sub-frames into one superframe, the
> superframe
> > index validate failed when reach 8, modify the index checking so
> that the
> > last sub-frame can be decoded normally.
> 
> When I first saw this patch I was concerned, since we don't allow
> bundling super
> frame into the stateless API, but now I realize that this is for the
> stateful
> decoder. Perhaps you can help me and possibly other reviewers with
> simply
> stating that this is for stateful decoders.
> 
> > 
> > Signed-off-by: Irui Wang <irui.wang at mediatek.com>
> > ---
> >  .../media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c | 4
> ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git
> a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c
> b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c
> > index 55355fa70090..4a9ced7348ee 100644
> > ---
> a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c
> > +++
> b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_if.c
> > @@ -526,7 +526,7 @@ static void vp9_swap_frm_bufs(struct
> vdec_vp9_inst *inst)
> >  /* if this super frame and it is not last sub-frame, get next fb
> for
> >   * sub-frame decode
> >   */
> > -if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt - 1)
> > +if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt)
> >  vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
> >  }
> >  
> > @@ -735,7 +735,7 @@ static void get_free_fb(struct vdec_vp9_inst
> *inst, struct vdec_fb **out_fb)
> >  
> >  static int validate_vsi_array_indexes(struct vdec_vp9_inst *inst,
> >  struct vdec_vp9_vsi *vsi) {
> > -if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM - 1) {
> > +if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM) {
> 
> nit: I'd propose to define a new maximum (contractions allowed):
> 
>   #define VP9_MAX_NUM_SUPER_FRAMES 8
> 
> This way you can revisit bunch of `VP9_MAX_FRM_BUF_NUM-1`, and make
> the overall
> code a bit more human readable. There is no relation between
> VP9_MAX_FRM_BUF_NUM
> and this maximum. The limits simply comes from the fact
> frames_in_superframe_minus_1 is expressed with 3 bits.
> 
> regards,
> Nicolas
> 
Yes, define a new maximum makes code more readable, we will check it.

Thanks
Best Regards

> p.s. your change looks good otherwise.
> 
> >  mtk_vdec_err(inst->ctx, "Invalid vsi->sf_frm_idx=%u.", vsi-
> >sf_frm_idx);
> >  return -EIO;
> >  }
> 

From hejunhao3 at huawei.com  Wed Feb 21 19:00:44 2024
From: hejunhao3 at huawei.com (hejunhao)
Date: Thu, 22 Feb 2024 11:00:44 +0800
Subject: [PATCH 6/7] drivers/perf: hisi_pcie: Merge
 find_related_event() and get_event_idx()
In-Reply-To: <20240208123946.00006618@Huawei.com>
References: <20240204074527.47110-1-yangyicong@huawei.com>
 <20240204074527.47110-7-yangyicong@huawei.com>
 <20240208123946.00006618@Huawei.com>
Message-ID: <1c14d50d-fc51-cc34-aa97-358466c19fe6@huawei.com>

Hi, Jonathan


On 2024/2/8 20:39, Jonathan Cameron wrote:
> On Sun, 4 Feb 2024 15:45:26 +0800
> Yicong Yang <yangyicong at huawei.com> wrote:
>
>> From: Junhao He <hejunhao3 at huawei.com>
>>
>> The function xxx_find_related_event() scan all working events to find
>> related events. During this process, we also can find the idle counters.
>> If not found related events, return the first idle counter to simplify
>> the code.
>>
>> Signed-off-by: Junhao He <hejunhao3 at huawei.com>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> A suggestion inline to avoid the magic HISI_PCIE_MAX_COUNTER value
> being used outside of the function.

Thanks for the comments, will fix in next version.

>
>> ---
>>   drivers/perf/hisilicon/hisi_pcie_pmu.c | 55 ++++++++++----------------
>>   1 file changed, 21 insertions(+), 34 deletions(-)
>>
>> diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> index 1b45aeb82859..2edde66675e7 100644
>> --- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> +++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
>> @@ -397,16 +397,24 @@ static u64 hisi_pcie_pmu_read_counter(struct perf_event *event)
>>   	return hisi_pcie_pmu_readq(pcie_pmu, event->hw.event_base, idx);
>>   }
>>   
>> -static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
>> -					    struct perf_event *event)
>> +/*
>> + * Check all work events, if a relevant event is found then we return it
>> + * first, otherwise return the first idle counter (need to reset).
>> + */
>> +static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu,
>> +					struct perf_event *event)
>>   {
>> +	int first_idle = HISI_PCIE_MAX_COUNTERS;
> 	int first_idle = -EAGAIN;

Yes, I will do that.

>>   	struct perf_event *sibling;
>>   	int idx;
>>   
>>   	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
>>   		sibling = pcie_pmu->hw_events[idx];
>> -		if (!sibling)
>> +		if (!sibling) {
>> +			if (first_idle == HISI_PCIE_MAX_COUNTERS)
> if (first_idle == -EAGAIN)

Ok, will fix it.

>
>> +				first_idle = idx;
>>   			continue;
>> +		}
>>   
>>   		/* Related events must be used in group */
>>   		if (hisi_pcie_pmu_cmp_event(sibling, event) &&
>> @@ -414,19 +422,7 @@ static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
>>   			return idx;
>>   	}
>>   
>> -	return idx;
>> -}
>> -
>> -static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu)
>> -{
>> -	int idx;
>> -
>> -	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
>> -		if (!pcie_pmu->hw_events[idx])
>> -			return idx;
>> -	}
>> -
>> -	return -EINVAL;
>> +	return first_idle;
> Then this will return -EAGAIN;

Okay

>>   }
>>   
>>   static void hisi_pcie_pmu_event_update(struct perf_event *event)
>> @@ -552,27 +548,18 @@ static int hisi_pcie_pmu_add(struct perf_event *event, int flags)
>>   
>>   	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
>>   
>> -	/* Check all working events to find a related event. */
>> -	idx = hisi_pcie_pmu_find_related_event(pcie_pmu, event);
>> -	if (idx < 0)
>> -		return idx;
>> -
>> -	/* Current event shares an enabled counter with the related event */
>> -	if (idx < HISI_PCIE_MAX_COUNTERS) {
>> -		hwc->idx = idx;
>> -		goto start_count;
>> -	}
>> -
>> -	idx = hisi_pcie_pmu_get_event_idx(pcie_pmu);
>> -	if (idx < 0)
>> -		return idx;
>> +	idx = hisi_pcie_pmu_get_event_idx(pcie_pmu, event);
>> +	if (idx == HISI_PCIE_MAX_COUNTERS)
>> +		return -EAGAIN;
> Perhaps simpler to handle first_idle == HISI_PCIE_MAX_COUNTERS as
> an error return in hisi_pcie_pmu_get_event_idx - see above.
>
>   	if (idx < 0)
> 		return idx;

Sure.

>
>>   
>>   	hwc->idx = idx;
>> -	pcie_pmu->hw_events[idx] = event;
>> -	/* Reset Counter to avoid previous statistic interference. */
>> -	hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
>>   
>> -start_count:
>> +	/* No enabled counter found with related event, reset it */
>> +	if (!pcie_pmu->hw_events[idx]) {
>> +		hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
>> +		pcie_pmu->hw_events[idx] = event;
>> +	}
>> +
>>   	if (flags & PERF_EF_START)
>>   		hisi_pcie_pmu_start(event, PERF_EF_RELOAD);
>>   
>



From semen.protsenko at linaro.org  Wed Feb 21 19:02:20 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:20 -0600
Subject: [PATCH v2 00/15] clk: samsung: Add CPU clocks for Exynos850
Message-ID: <20240222030235.27815-1-semen.protsenko@linaro.org>

The series implements CPU clock support for Exynos850, adds CPU CMUs to
the clock driver and enables those in dts. This is the first step
towards cpufreq implementation.

If possible, all patches should go through Krzysztof's tree. As
inter-series dependencies go:

  * All driver changes (patch 02..14) must be taken together following
    the order established in this series
  * Patch 15 (dts changes) depends on patch 01 (bindings additions)
  * Patch 14 (driver changes) depends on patch 01 (bindings additions)

The series was tested on E850-96 board, via DebugFS with
CLOCK_ALLOW_WRITE_DEBUGFS enabled, by setting different CPU clock rates,
like this:

  # cd /sys/kernel/debug/clk/cluster0_clk/
  # cat clk_rate
  1053000000
  # echo 10000000 > clk_rate
  # cat clk_rate
  130000000

Of course, DVFS/cpufreq is not implemented yet, so the CPU can't be
overclocked too much right now, and the cpufreq interface is not
available too. As per the TRM, the CPU operates at a voltage level of
0.65 V, 0.75 V, 0.85 V and 1.05 V. When the voltage is 0.85 V, A55
quad-core operates at 1.6 GHz and CoreSight at 200 MHz.

To check the actual frequency, the "perf" tool was used:

  # perf stat sleep 1

And to check that on a particular CPU core:

  # taskset -c 4 perf stat sleep 1

Some takeaways:

  * Max functional frequency right now is 1.586 GHz
  * 1.742 GHz or more leads to the system freeze, as it requires
    more voltage to be operational
  * Max possible frequency: 2.210 GHz
  * The lowest possible frequency: 130 MHz
  * Default boot up frequency: 1.053 GHz

Changes in v2:
- Removed confusing "breakup by patch" list from patch #0 commit message
- Dropped the patch for making clk.h a single included header
- Rebased the series on top of the latest linux-next

Sam Protsenko (15):
  dt-bindings: clock: exynos850: Add CMU_CPUCLK0 and CMU_CPUCL1
  clk: samsung: Improve clk-cpu.c style
  clk: samsung: Pull struct exynos_cpuclk into clk-cpu.c
  clk: samsung: Reduce params count in exynos_register_cpu_clock()
  clk: samsung: Use single CPU clock notifier callback for all chips
  clk: samsung: Group CPU clock functions by chip
  clk: samsung: Pass actual CPU clock registers base to CPU_CLK()
  clk: samsung: Pass register layout type explicitly to CLK_CPU()
  clk: samsung: Keep CPU clock chip specific data in a dedicated struct
  clk: samsung: Keep register offsets in chip specific structure
  clk: samsung: Pass mask to wait_until_mux_stable()
  clk: samsung: Add CPU clock support for Exynos850
  clk: samsung: Implement manual PLL control for ARM64 SoCs
  clk: samsung: exynos850: Add CMU_CPUCL0 and CMU_CPUCL1
  arm64: dts: exynos: Add CPU clocks for Exynos850

 .../clock/samsung,exynos850-clock.yaml        |  42 ++
 arch/arm64/boot/dts/exynos/exynos850.dtsi     |  26 +
 drivers/clk/samsung/clk-cpu.c                 | 562 +++++++++++++-----
 drivers/clk/samsung/clk-cpu.h                 |  53 +-
 drivers/clk/samsung/clk-exynos-arm64.c        |  44 +-
 drivers/clk/samsung/clk-exynos3250.c          |   2 +-
 drivers/clk/samsung/clk-exynos4.c             |   9 +-
 drivers/clk/samsung/clk-exynos5250.c          |   5 +-
 drivers/clk/samsung/clk-exynos5420.c          |  16 +-
 drivers/clk/samsung/clk-exynos5433.c          |  10 +-
 drivers/clk/samsung/clk-exynos850.c           | 440 +++++++++++++-
 drivers/clk/samsung/clk.h                     |   9 +-
 include/dt-bindings/clock/exynos850.h         |  54 ++
 13 files changed, 1040 insertions(+), 232 deletions(-)

-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:21 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:21 -0600
Subject: [PATCH v2 01/15] dt-bindings: clock: exynos850: Add CMU_CPUCLK0 and CMU_CPUCL1
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-2-semen.protsenko@linaro.org>

Document CPU clock management unit compatibles and add corresponding
clock indices. Exynos850 has two CPU clusters (CL0 and CL1), each
containing 4 Cortex-A55 cores. CPU PLLs are generating main CPU clocks
for each cluster, and there are alternate ("switch") clocks that can be
used temporarily while re-configuring the PLL for the new rate. ACLK,
ATCLK, PCLKDBG and PERIPHCLK clocks are driving corresponding buses.
CLK_CLUSTERx_SCLK are actual leaf CPU clocks and should be used to
change CPU rates. Also some CoreSight clocks can be derived from
DBG_USER (debug clock).

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - none

 .../clock/samsung,exynos850-clock.yaml        | 42 +++++++++++++++
 include/dt-bindings/clock/exynos850.h         | 54 +++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
index c752c8985a53..cdc5ded59fe5 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
@@ -36,6 +36,8 @@ properties:
       - samsung,exynos850-cmu-aud
       - samsung,exynos850-cmu-cmgp
       - samsung,exynos850-cmu-core
+      - samsung,exynos850-cmu-cpucl0
+      - samsung,exynos850-cmu-cpucl1
       - samsung,exynos850-cmu-dpu
       - samsung,exynos850-cmu-g3d
       - samsung,exynos850-cmu-hsi
@@ -152,6 +154,46 @@ allOf:
             - const: dout_core_mmc_embd
             - const: dout_core_sss
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-cpucl0
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CPUCL0 switch clock (from CMU_TOP)
+            - description: CPUCL0 debug clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_cpucl0_switch
+            - const: dout_cpucl0_dbg
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-cpucl1
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CPUCL1 switch clock (from CMU_TOP)
+            - description: CPUCL1 debug clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_cpucl1_switch
+            - const: dout_cpucl1_dbg
+
   - if:
       properties:
         compatible:
diff --git a/include/dt-bindings/clock/exynos850.h b/include/dt-bindings/clock/exynos850.h
index bc15108aa3c2..7666241520f8 100644
--- a/include/dt-bindings/clock/exynos850.h
+++ b/include/dt-bindings/clock/exynos850.h
@@ -88,6 +88,18 @@
 #define CLK_MOUT_G3D_SWITCH		76
 #define CLK_GOUT_G3D_SWITCH		77
 #define CLK_DOUT_G3D_SWITCH		78
+#define CLK_MOUT_CPUCL0_DBG		79
+#define CLK_MOUT_CPUCL0_SWITCH		80
+#define CLK_GOUT_CPUCL0_DBG		81
+#define CLK_GOUT_CPUCL0_SWITCH		82
+#define CLK_DOUT_CPUCL0_DBG		83
+#define CLK_DOUT_CPUCL0_SWITCH		84
+#define CLK_MOUT_CPUCL1_DBG		85
+#define CLK_MOUT_CPUCL1_SWITCH		86
+#define CLK_GOUT_CPUCL1_DBG		87
+#define CLK_GOUT_CPUCL1_SWITCH		88
+#define CLK_DOUT_CPUCL1_DBG		89
+#define CLK_DOUT_CPUCL1_SWITCH		90
 
 /* CMU_APM */
 #define CLK_RCO_I3C_PMIC		1
@@ -195,6 +207,48 @@
 #define CLK_GOUT_CMGP_USI1_PCLK		14
 #define CLK_GOUT_SYSREG_CMGP_PCLK	15
 
+/* CMU_CPUCL0 */
+#define CLK_FOUT_CPUCL0_PLL		1
+#define CLK_MOUT_PLL_CPUCL0		2
+#define CLK_MOUT_CPUCL0_SWITCH_USER	3
+#define CLK_MOUT_CPUCL0_DBG_USER	4
+#define CLK_MOUT_CPUCL0_PLL		5
+#define CLK_DOUT_CPUCL0_CPU		6
+#define CLK_DOUT_CPUCL0_CMUREF		7
+#define CLK_DOUT_CPUCL0_PCLK		8
+#define CLK_DOUT_CLUSTER0_ACLK		9
+#define CLK_DOUT_CLUSTER0_ATCLK		10
+#define CLK_DOUT_CLUSTER0_PCLKDBG	11
+#define CLK_DOUT_CLUSTER0_PERIPHCLK	12
+#define CLK_GOUT_CLUSTER0_ATCLK		13
+#define CLK_GOUT_CLUSTER0_PCLK		14
+#define CLK_GOUT_CLUSTER0_PERIPHCLK	15
+#define CLK_GOUT_CLUSTER0_SCLK		16
+#define CLK_GOUT_CPUCL0_CMU_CPUCL0_PCLK	17
+#define CLK_GOUT_CLUSTER0_CPU		18
+#define CLK_CLUSTER0_SCLK		19
+
+/* CMU_CPUCL1 */
+#define CLK_FOUT_CPUCL1_PLL		1
+#define CLK_MOUT_PLL_CPUCL1		2
+#define CLK_MOUT_CPUCL1_SWITCH_USER	3
+#define CLK_MOUT_CPUCL1_DBG_USER	4
+#define CLK_MOUT_CPUCL1_PLL		5
+#define CLK_DOUT_CPUCL1_CPU		6
+#define CLK_DOUT_CPUCL1_CMUREF		7
+#define CLK_DOUT_CPUCL1_PCLK		8
+#define CLK_DOUT_CLUSTER1_ACLK		9
+#define CLK_DOUT_CLUSTER1_ATCLK		10
+#define CLK_DOUT_CLUSTER1_PCLKDBG	11
+#define CLK_DOUT_CLUSTER1_PERIPHCLK	12
+#define CLK_GOUT_CLUSTER1_ATCLK		13
+#define CLK_GOUT_CLUSTER1_PCLK		14
+#define CLK_GOUT_CLUSTER1_PERIPHCLK	15
+#define CLK_GOUT_CLUSTER1_SCLK		16
+#define CLK_GOUT_CPUCL1_CMU_CPUCL1_PCLK	17
+#define CLK_GOUT_CLUSTER1_CPU		18
+#define CLK_CLUSTER1_SCLK		19
+
 /* CMU_G3D */
 #define CLK_FOUT_G3D_PLL		1
 #define CLK_MOUT_G3D_PLL		2
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:22 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:22 -0600
Subject: [PATCH v2 02/15] clk: samsung: Improve clk-cpu.c style
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-3-semen.protsenko@linaro.org>

clk-cpu.c has numerous style issues reported by checkpatch and easily
identified otherwise. Give it some love and fix those warnings where it
makes sense. Also make stabilization time a named constant to get rid of
the magic number in clk-cpu.c.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 65 ++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 32 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 3e62ade120c5..e02730776aaa 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -16,18 +16,18 @@
  * of the SoC or supplied after the SoC characterization.
  *
  * The below implementation of the CPU clock allows the rate changes of the CPU
- * clock and the corresponding rate changes of the auxillary clocks of the CPU
+ * clock and the corresponding rate changes of the auxiliary clocks of the CPU
  * domain. The platform clock driver provides a clock register configuration
  * for each configurable rate which is then used to program the clock hardware
- * registers to acheive a fast co-oridinated rate change for all the CPU domain
+ * registers to achieve a fast coordinated rate change for all the CPU domain
  * clocks.
  *
  * On a rate change request for the CPU clock, the rate change is propagated
- * upto the PLL supplying the clock to the CPU domain clock blocks. While the
+ * up to the PLL supplying the clock to the CPU domain clock blocks. While the
  * CPU domain PLL is reconfigured, the CPU domain clocks are driven using an
  * alternate clock source. If required, the alternate clock source is divided
  * down in order to keep the output clock rate within the previous OPP limits.
-*/
+ */
 
 #include <linux/errno.h>
 #include <linux/io.h>
@@ -50,17 +50,19 @@
 #define E5433_DIV_STAT_CPU0	0x500
 #define E5433_DIV_STAT_CPU1	0x504
 
-#define E4210_DIV0_RATIO0_MASK	0x7
-#define E4210_DIV1_HPM_MASK	(0x7 << 4)
-#define E4210_DIV1_COPY_MASK	(0x7 << 0)
-#define E4210_MUX_HPM_MASK	(1 << 20)
+#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
+#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
+#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
+#define E4210_MUX_HPM_MASK	BIT(20)
 #define E4210_DIV0_ATB_SHIFT	16
 #define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
 
+/* Divider stabilization time, msec */
+#define MAX_STAB_TIME		10
 #define MAX_DIV			8
-#define DIV_MASK		7
-#define DIV_MASK_ALL		0xffffffff
-#define MUX_MASK		7
+#define DIV_MASK		GENMASK(2, 0)
+#define DIV_MASK_ALL		GENMASK(31, 0)
+#define MUX_MASK		GENMASK(2, 0)
 
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
@@ -68,7 +70,7 @@
  */
 static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
 {
-	unsigned long timeout = jiffies + msecs_to_jiffies(10);
+	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);
 
 	do {
 		if (!(readl(div_reg) & mask))
@@ -86,9 +88,9 @@ static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
  * value was changed.
  */
 static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
-					unsigned long mux_value)
+				  unsigned long mux_value)
 {
-	unsigned long timeout = jiffies + msecs_to_jiffies(10);
+	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);
 
 	do {
 		if (((readl(mux_reg) >> mux_pos) & MUX_MASK) == mux_value)
@@ -101,18 +103,18 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
 }
 
-/* common round rate callback useable for all types of CPU clocks */
-static long exynos_cpuclk_round_rate(struct clk_hw *hw,
-			unsigned long drate, unsigned long *prate)
+/* common round rate callback usable for all types of CPU clocks */
+static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate,
+				     unsigned long *prate)
 {
 	struct clk_hw *parent = clk_hw_get_parent(hw);
 	*prate = clk_hw_round_rate(parent, drate);
 	return *prate;
 }
 
-/* common recalc rate callback useable for all types of CPU clocks */
+/* common recalc rate callback usable for all types of CPU clocks */
 static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw,
-			unsigned long parent_rate)
+					       unsigned long parent_rate)
 {
 	/*
 	 * The CPU clock output (armclk) rate is the same as its parent
@@ -135,7 +137,7 @@ static const struct clk_ops exynos_cpuclk_clk_ops = {
  * dividers to be programmed.
  */
 static void exynos_set_safe_div(void __iomem *base, unsigned long div,
-					unsigned long mask)
+				unsigned long mask)
 {
 	unsigned long div0;
 
@@ -151,7 +153,6 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
-	unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
 
@@ -187,6 +188,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	 */
 	if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) {
 		unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate);
+		unsigned long alt_div, alt_div_mask = DIV_MASK;
 
 		alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
 		WARN_ON(alt_div >= MAX_DIV);
@@ -215,7 +217,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
 		writel(div1, base + E4210_DIV_CPU1);
 		wait_until_divider_stable(base + E4210_DIV_STAT_CPU1,
-				DIV_MASK_ALL);
+					  DIV_MASK_ALL);
 	}
 
 	spin_unlock_irqrestore(cpuclk->lock, flags);
@@ -263,7 +265,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
  * dividers to be programmed.
  */
 static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
-					unsigned long mask)
+				    unsigned long mask)
 {
 	unsigned long div0;
 
@@ -279,7 +281,6 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
-	unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
 
@@ -309,6 +310,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	 */
 	if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) {
 		unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate);
+		unsigned long alt_div, alt_div_mask = DIV_MASK;
 
 		alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
 		WARN_ON(alt_div >= MAX_DIV);
@@ -358,7 +360,7 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
  * notifications of the parent clock of cpuclk.
  */
 static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
-				unsigned long event, void *data)
+				     unsigned long event, void *data)
 {
 	struct clk_notifier_data *ndata = data;
 	struct exynos_cpuclk *cpuclk;
@@ -381,7 +383,7 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
  * notifications of the parent clock of cpuclk.
  */
 static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
-				unsigned long event, void *data)
+					 unsigned long event, void *data)
 {
 	struct clk_notifier_data *ndata = data;
 	struct exynos_cpuclk *cpuclk;
@@ -438,11 +440,10 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	else
 		cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
 
-
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
 		pr_err("%s: failed to register clock notifier for %s\n",
-				__func__, name);
+		       __func__, name);
 		goto free_cpuclk;
 	}
 
@@ -454,7 +455,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	ret = clk_hw_register(NULL, &cpuclk->hw);
 	if (ret) {
-		pr_err("%s: could not register cpuclk %s\n", __func__,	name);
+		pr_err("%s: could not register cpuclk %s\n", __func__, name);
 		goto free_cpuclk_data;
 	}
 
@@ -482,8 +483,8 @@ void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
 		for (num_cfgs = 0; list->cfg[num_cfgs].prate != 0; )
 			num_cfgs++;
 
-		exynos_register_cpu_clock(ctx, list->id, list->name, hws[list->parent_id],
-				hws[list->alt_parent_id], list->offset, list->cfg, num_cfgs,
-				list->flags);
+		exynos_register_cpu_clock(ctx, list->id, list->name,
+			hws[list->parent_id], hws[list->alt_parent_id],
+			list->offset, list->cfg, num_cfgs, list->flags);
 	}
 }
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:23 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:23 -0600
Subject: [PATCH v2 03/15] clk: samsung: Pull struct exynos_cpuclk into clk-cpu.c
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-4-semen.protsenko@linaro.org>

Reduce the scope of struct exynos_cpuclk, as it's only used in clk-cpu.c
internally. All drivers using clk-pll.h already include clk.h as well,
so this change doesn't break anything.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 29 +++++++++++++++++++++++++
 drivers/clk/samsung/clk-cpu.h | 41 +++++------------------------------
 2 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index e02730776aaa..6412fd2580e0 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -34,6 +34,8 @@
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+
+#include "clk.h"
 #include "clk-cpu.h"
 
 #define E4210_SRC_CPU		0x0
@@ -64,6 +66,33 @@
 #define DIV_MASK_ALL		GENMASK(31, 0)
 #define MUX_MASK		GENMASK(2, 0)
 
+/**
+ * struct exynos_cpuclk - information about clock supplied to a CPU core
+ * @hw:		handle between CCF and CPU clock
+ * @alt_parent:	alternate parent clock to use when switching the speed
+ *		of the primary parent clock
+ * @ctrl_base:	base address of the clock controller
+ * @lock:	cpu clock domain register access lock
+ * @cfg:	cpu clock rate configuration data
+ * @num_cfgs:	number of array elements in @cfg array
+ * @clk_nb:	clock notifier registered for changes in clock speed of the
+ *		primary parent clock
+ * @flags:	configuration flags for the CPU clock
+ *
+ * This structure holds information required for programming the CPU clock for
+ * various clock speeds.
+ */
+struct exynos_cpuclk {
+	struct clk_hw				hw;
+	const struct clk_hw			*alt_parent;
+	void __iomem				*ctrl_base;
+	spinlock_t				*lock;
+	const struct exynos_cpuclk_cfg_data	*cfg;
+	const unsigned long			num_cfgs;
+	struct notifier_block			clk_nb;
+	unsigned long				flags;
+};
+
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
  * value has changed.
diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h
index 0164bd9ad021..ee57f3638fed 100644
--- a/drivers/clk/samsung/clk-cpu.h
+++ b/drivers/clk/samsung/clk-cpu.h
@@ -8,7 +8,12 @@
 #ifndef __SAMSUNG_CLK_CPU_H
 #define __SAMSUNG_CLK_CPU_H
 
-#include "clk.h"
+/* The CPU clock registers have DIV1 configuration register */
+#define CLK_CPU_HAS_DIV1		BIT(0)
+/* When ALT parent is active, debug clocks need safe divider values */
+#define CLK_CPU_NEEDS_DEBUG_ALT_DIV	BIT(1)
+/* The CPU clock registers have Exynos5433-compatible layout */
+#define CLK_CPU_HAS_E5433_REGS_LAYOUT	BIT(2)
 
 /**
  * struct exynos_cpuclk_cfg_data - config data to setup cpu clocks
@@ -28,38 +33,4 @@ struct exynos_cpuclk_cfg_data {
 	unsigned long	div1;
 };
 
-/**
- * struct exynos_cpuclk - information about clock supplied to a CPU core
- * @hw:		handle between CCF and CPU clock
- * @alt_parent:	alternate parent clock to use when switching the speed
- *		of the primary parent clock
- * @ctrl_base:	base address of the clock controller
- * @lock:	cpu clock domain register access lock
- * @cfg:	cpu clock rate configuration data
- * @num_cfgs:	number of array elements in @cfg array
- * @clk_nb:	clock notifier registered for changes in clock speed of the
- *		primary parent clock
- * @flags:	configuration flags for the CPU clock
- *
- * This structure holds information required for programming the CPU clock for
- * various clock speeds.
- */
-struct exynos_cpuclk {
-	struct clk_hw				hw;
-	const struct clk_hw			*alt_parent;
-	void __iomem				*ctrl_base;
-	spinlock_t				*lock;
-	const struct exynos_cpuclk_cfg_data	*cfg;
-	const unsigned long			num_cfgs;
-	struct notifier_block			clk_nb;
-	unsigned long				flags;
-
-/* The CPU clock registers have DIV1 configuration register */
-#define CLK_CPU_HAS_DIV1		(1 << 0)
-/* When ALT parent is active, debug clocks need safe divider values */
-#define CLK_CPU_NEEDS_DEBUG_ALT_DIV	(1 << 1)
-/* The CPU clock registers have Exynos5433-compatible layout */
-#define CLK_CPU_HAS_E5433_REGS_LAYOUT	(1 << 2)
-};
-
 #endif /* __SAMSUNG_CLK_CPU_H */
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:24 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:24 -0600
Subject: [PATCH v2 04/15] clk: samsung: Reduce params count in exynos_register_cpu_clock()
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-5-semen.protsenko@linaro.org>

Pass CPU clock data structure to exynos_register_cpu_clock() instead of
passing its fields separately there. That simplifies the signature of
exynos_register_cpu_clock() and makes it easier to add more fields to
struct samsung_cpu_clock later. This style follows the example of
samsung_clk_register_pll().

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 46 +++++++++++++++++------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 6412fd2580e0..7b6fd331a7ec 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -432,16 +432,19 @@ static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
 
 /* helper function to register a CPU clock */
 static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
-		unsigned int lookup_id, const char *name,
-		const struct clk_hw *parent, const struct clk_hw *alt_parent,
-		unsigned long offset, const struct exynos_cpuclk_cfg_data *cfg,
-		unsigned long num_cfgs, unsigned long flags)
+				const struct samsung_cpu_clock *clk_data)
 {
+	const struct clk_hw *parent, *alt_parent;
+	struct clk_hw **hws;
 	struct exynos_cpuclk *cpuclk;
 	struct clk_init_data init;
 	const char *parent_name;
+	unsigned int num_cfgs;
 	int ret = 0;
 
+	hws = ctx->clk_data.hws;
+	parent = hws[clk_data->parent_id];
+	alt_parent = hws[clk_data->alt_parent_id];
 	if (IS_ERR(parent) || IS_ERR(alt_parent)) {
 		pr_err("%s: invalid parent clock(s)\n", __func__);
 		return -EINVAL;
@@ -453,7 +456,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	parent_name = clk_hw_get_name(parent);
 
-	init.name = name;
+	init.name = clk_data->name;
 	init.flags = CLK_SET_RATE_PARENT;
 	init.parent_names = &parent_name;
 	init.num_parents = 1;
@@ -461,10 +464,10 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	cpuclk->alt_parent = alt_parent;
 	cpuclk->hw.init = &init;
-	cpuclk->ctrl_base = ctx->reg_base + offset;
+	cpuclk->ctrl_base = ctx->reg_base + clk_data->offset;
 	cpuclk->lock = &ctx->lock;
-	cpuclk->flags = flags;
-	if (flags & CLK_CPU_HAS_E5433_REGS_LAYOUT)
+	cpuclk->flags = clk_data->flags;
+	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT)
 		cpuclk->clk_nb.notifier_call = exynos5433_cpuclk_notifier_cb;
 	else
 		cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
@@ -472,11 +475,16 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
 		pr_err("%s: failed to register clock notifier for %s\n",
-		       __func__, name);
+		       __func__, clk_data->name);
 		goto free_cpuclk;
 	}
 
-	cpuclk->cfg = kmemdup(cfg, sizeof(*cfg) * num_cfgs, GFP_KERNEL);
+	/* Find count of configuration rates in cfg */
+	for (num_cfgs = 0; clk_data->cfg[num_cfgs].prate != 0; )
+		num_cfgs++;
+
+	cpuclk->cfg = kmemdup(clk_data->cfg, sizeof(*clk_data->cfg) * num_cfgs,
+			      GFP_KERNEL);
 	if (!cpuclk->cfg) {
 		ret = -ENOMEM;
 		goto unregister_clk_nb;
@@ -484,11 +492,12 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	ret = clk_hw_register(NULL, &cpuclk->hw);
 	if (ret) {
-		pr_err("%s: could not register cpuclk %s\n", __func__, name);
+		pr_err("%s: could not register cpuclk %s\n", __func__,
+		       clk_data->name);
 		goto free_cpuclk_data;
 	}
 
-	samsung_clk_add_lookup(ctx, &cpuclk->hw, lookup_id);
+	samsung_clk_add_lookup(ctx, &cpuclk->hw, clk_data->id);
 	return 0;
 
 free_cpuclk_data:
@@ -504,16 +513,7 @@ void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
 		const struct samsung_cpu_clock *list, unsigned int nr_clk)
 {
 	unsigned int idx;
-	unsigned int num_cfgs;
-	struct clk_hw **hws = ctx->clk_data.hws;
 
-	for (idx = 0; idx < nr_clk; idx++, list++) {
-		/* find count of configuration rates in cfg */
-		for (num_cfgs = 0; list->cfg[num_cfgs].prate != 0; )
-			num_cfgs++;
-
-		exynos_register_cpu_clock(ctx, list->id, list->name,
-			hws[list->parent_id], hws[list->alt_parent_id],
-			list->offset, list->cfg, num_cfgs, list->flags);
-	}
+	for (idx = 0; idx < nr_clk; idx++)
+		exynos_register_cpu_clock(ctx, &list[idx]);
 }
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:25 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:25 -0600
Subject: [PATCH v2 05/15] clk: samsung: Use single CPU clock notifier callback for all chips
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-6-semen.protsenko@linaro.org>

Reduce the code duplication by making all chips use a single version of
exynos_cpuclk_notifier_cb() function. That will prevent the code bloat
when adding new chips support too.

Also don't pass base address to pre/post rate change functions, as it
can be easily derived from already passed cpuclk param.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 63 ++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 35 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 7b6fd331a7ec..427018e8dd8c 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -66,6 +66,11 @@
 #define DIV_MASK_ALL		GENMASK(31, 0)
 #define MUX_MASK		GENMASK(2, 0)
 
+struct exynos_cpuclk;
+
+typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
+				       struct exynos_cpuclk *cpuclk);
+
 /**
  * struct exynos_cpuclk - information about clock supplied to a CPU core
  * @hw:		handle between CCF and CPU clock
@@ -78,6 +83,8 @@
  * @clk_nb:	clock notifier registered for changes in clock speed of the
  *		primary parent clock
  * @flags:	configuration flags for the CPU clock
+ * @pre_rate_cb: callback to run before CPU clock rate change
+ * @post_rate_cb: callback to run after CPU clock rate change
  *
  * This structure holds information required for programming the CPU clock for
  * various clock speeds.
@@ -91,6 +98,9 @@ struct exynos_cpuclk {
 	const unsigned long			num_cfgs;
 	struct notifier_block			clk_nb;
 	unsigned long				flags;
+
+	exynos_rate_change_fn_t			pre_rate_cb;
+	exynos_rate_change_fn_t			post_rate_cb;
 };
 
 /*
@@ -178,9 +188,10 @@ static void exynos_set_safe_div(void __iomem *base, unsigned long div,
 
 /* handler for pre-rate change notification from parent clock */
 static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					 struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
@@ -255,9 +266,10 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 
 /* handler for post-rate change notification from parent clock */
 static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					  struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
 	unsigned long flags;
@@ -306,9 +318,10 @@ static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
 
 /* handler for pre-rate change notification from parent clock */
 static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					     struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
@@ -366,8 +379,9 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 
 /* handler for post-rate change notification from parent clock */
 static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					      struct exynos_cpuclk *cpuclk)
 {
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
 	unsigned long flags;
@@ -393,39 +407,14 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
 {
 	struct clk_notifier_data *ndata = data;
 	struct exynos_cpuclk *cpuclk;
-	void __iomem *base;
 	int err = 0;
 
 	cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb);
-	base = cpuclk->ctrl_base;
 
 	if (event == PRE_RATE_CHANGE)
-		err = exynos_cpuclk_pre_rate_change(ndata, cpuclk, base);
+		err = cpuclk->pre_rate_cb(ndata, cpuclk);
 	else if (event == POST_RATE_CHANGE)
-		err = exynos_cpuclk_post_rate_change(ndata, cpuclk, base);
-
-	return notifier_from_errno(err);
-}
-
-/*
- * This notifier function is called for the pre-rate and post-rate change
- * notifications of the parent clock of cpuclk.
- */
-static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
-					 unsigned long event, void *data)
-{
-	struct clk_notifier_data *ndata = data;
-	struct exynos_cpuclk *cpuclk;
-	void __iomem *base;
-	int err = 0;
-
-	cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb);
-	base = cpuclk->ctrl_base;
-
-	if (event == PRE_RATE_CHANGE)
-		err = exynos5433_cpuclk_pre_rate_change(ndata, cpuclk, base);
-	else if (event == POST_RATE_CHANGE)
-		err = exynos5433_cpuclk_post_rate_change(ndata, cpuclk, base);
+		err = cpuclk->post_rate_cb(ndata, cpuclk);
 
 	return notifier_from_errno(err);
 }
@@ -467,10 +456,14 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	cpuclk->ctrl_base = ctx->reg_base + clk_data->offset;
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
-	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT)
-		cpuclk->clk_nb.notifier_call = exynos5433_cpuclk_notifier_cb;
-	else
-		cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
+	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
+	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT) {
+		cpuclk->pre_rate_cb = exynos5433_cpuclk_pre_rate_change;
+		cpuclk->post_rate_cb = exynos5433_cpuclk_post_rate_change;
+	} else {
+		cpuclk->pre_rate_cb = exynos_cpuclk_pre_rate_change;
+		cpuclk->post_rate_cb = exynos_cpuclk_post_rate_change;
+	}
 
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:26 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:26 -0600
Subject: [PATCH v2 06/15] clk: samsung: Group CPU clock functions by chip
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-7-semen.protsenko@linaro.org>

clk-cpu.c is going to get messy as new chips support is added.
Restructure the code by pulling related functions and definitions
together, grouping those by their relation to a particular chip or other
categories, to simplify the code navigation.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 114 ++++++++++++++++++----------------
 1 file changed, 61 insertions(+), 53 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 427018e8dd8c..d550a4bb632f 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -38,34 +38,6 @@
 #include "clk.h"
 #include "clk-cpu.h"
 
-#define E4210_SRC_CPU		0x0
-#define E4210_STAT_CPU		0x200
-#define E4210_DIV_CPU0		0x300
-#define E4210_DIV_CPU1		0x304
-#define E4210_DIV_STAT_CPU0	0x400
-#define E4210_DIV_STAT_CPU1	0x404
-
-#define E5433_MUX_SEL2		0x008
-#define E5433_MUX_STAT2		0x208
-#define E5433_DIV_CPU0		0x400
-#define E5433_DIV_CPU1		0x404
-#define E5433_DIV_STAT_CPU0	0x500
-#define E5433_DIV_STAT_CPU1	0x504
-
-#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
-#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
-#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
-#define E4210_MUX_HPM_MASK	BIT(20)
-#define E4210_DIV0_ATB_SHIFT	16
-#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
-
-/* Divider stabilization time, msec */
-#define MAX_STAB_TIME		10
-#define MAX_DIV			8
-#define DIV_MASK		GENMASK(2, 0)
-#define DIV_MASK_ALL		GENMASK(31, 0)
-#define MUX_MASK		GENMASK(2, 0)
-
 struct exynos_cpuclk;
 
 typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
@@ -103,6 +75,15 @@ struct exynos_cpuclk {
 	exynos_rate_change_fn_t			post_rate_cb;
 };
 
+/* ---- Common code --------------------------------------------------------- */
+
+/* Divider stabilization time, msec */
+#define MAX_STAB_TIME		10
+#define MAX_DIV			8
+#define DIV_MASK		GENMASK(2, 0)
+#define DIV_MASK_ALL		GENMASK(31, 0)
+#define MUX_MASK		GENMASK(2, 0)
+
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
  * value has changed.
@@ -142,33 +123,21 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
 }
 
-/* common round rate callback usable for all types of CPU clocks */
-static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate,
-				     unsigned long *prate)
-{
-	struct clk_hw *parent = clk_hw_get_parent(hw);
-	*prate = clk_hw_round_rate(parent, drate);
-	return *prate;
-}
+/* ---- Exynos 3/4/5 -------------------------------------------------------- */
 
-/* common recalc rate callback usable for all types of CPU clocks */
-static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw,
-					       unsigned long parent_rate)
-{
-	/*
-	 * The CPU clock output (armclk) rate is the same as its parent
-	 * rate. Although there exist certain dividers inside the CPU
-	 * clock block that could be used to divide the parent clock,
-	 * the driver does not make use of them currently, except during
-	 * frequency transitions.
-	 */
-	return parent_rate;
-}
+#define E4210_SRC_CPU		0x0
+#define E4210_STAT_CPU		0x200
+#define E4210_DIV_CPU0		0x300
+#define E4210_DIV_CPU1		0x304
+#define E4210_DIV_STAT_CPU0	0x400
+#define E4210_DIV_STAT_CPU1	0x404
 
-static const struct clk_ops exynos_cpuclk_clk_ops = {
-	.recalc_rate = exynos_cpuclk_recalc_rate,
-	.round_rate = exynos_cpuclk_round_rate,
-};
+#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
+#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
+#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
+#define E4210_MUX_HPM_MASK	BIT(20)
+#define E4210_DIV0_ATB_SHIFT	16
+#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
 
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
@@ -300,6 +269,15 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	return 0;
 }
 
+/* ---- Exynos5433 ---------------------------------------------------------- */
+
+#define E5433_MUX_SEL2		0x008
+#define E5433_MUX_STAT2		0x208
+#define E5433_DIV_CPU0		0x400
+#define E5433_DIV_CPU1		0x404
+#define E5433_DIV_STAT_CPU0	0x500
+#define E5433_DIV_STAT_CPU1	0x504
+
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
  * div and mask contain the divider value and the register bit mask of the
@@ -398,6 +376,36 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	return 0;
 }
 
+/* -------------------------------------------------------------------------- */
+
+/* Common round rate callback usable for all types of CPU clocks */
+static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate,
+				     unsigned long *prate)
+{
+	struct clk_hw *parent = clk_hw_get_parent(hw);
+	*prate = clk_hw_round_rate(parent, drate);
+	return *prate;
+}
+
+/* Common recalc rate callback usable for all types of CPU clocks */
+static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	/*
+	 * The CPU clock output (armclk) rate is the same as its parent
+	 * rate. Although there exist certain dividers inside the CPU
+	 * clock block that could be used to divide the parent clock,
+	 * the driver does not make use of them currently, except during
+	 * frequency transitions.
+	 */
+	return parent_rate;
+}
+
+static const struct clk_ops exynos_cpuclk_clk_ops = {
+	.recalc_rate = exynos_cpuclk_recalc_rate,
+	.round_rate = exynos_cpuclk_round_rate,
+};
+
 /*
  * This notifier function is called for the pre-rate and post-rate change
  * notifications of the parent clock of cpuclk.
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:27 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:27 -0600
Subject: [PATCH v2 07/15] clk: samsung: Pass actual CPU clock registers base to CPU_CLK()
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-8-semen.protsenko@linaro.org>

The documentation for struct exynos_cpuclk says .ctrl_base field should
contain the controller base address. There are two different problems
with that:

1. All Exynos clock drivers are actually passing CPU_SRC register offset
   via CPU_CLK() macro, which in turn gets assigned to mentioned
   .ctrl_base field. Because CPU_SRC register usually already has 0x200
   offset from controller's base, all other register offsets in
   clk-cpu.c (like DIVs and MUXes) are specified as offsets from CPU_SRC
   offset, and not from controller's base. That makes things confusing
   and inconsistent with register offsets provided in Exynos clock
   drivers, also breaking the contract for .ctrl_base field as described
   in struct exynos_cpuclk doc.

2. Furthermore, some Exynos chips have an additional offset for the
   start of CPU clock registers block (inside of the CMU). There might
   be different reasons for that, e.g.:

   - The CMU contains clocks for two different CPUs (like in Exynos5420)
   - The CMU contains also non-CPU clocks as well (like in Exynos4)
   - The CPU CMU exists as a dedicated hardware block in the SoC layout,
     but is modelled as a part of bigger CMU in the driver (like in case
     of Exynos3250)

   That means the .ctrl_base field is actually not a controller's base,
   but instead it's a start address of the CPU clock registers inside of
   the CMU.

Rework all register offsets in clk-cpu.c to be actual offsets from the
CPU clock register block start, and fix offsets provided to CPU_CLK()
macro in all Exynos clock drivers. Also clarify the .ctrl_base field
documentation and rename it to just .base, because it doesn't really
contain the CMU base.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - Renamed .ctrl_base field to .base and fixed its documentation
  - Fixed typo in commit message: Exynis -> Exynos
  - Improved the commit message: mentioned that .ctrl_base is actually a
    start address of the CPU clock register block, not the CMU base

 drivers/clk/samsung/clk-cpu.c        | 38 ++++++++++++++--------------
 drivers/clk/samsung/clk-exynos3250.c |  2 +-
 drivers/clk/samsung/clk-exynos4.c    |  9 ++++---
 drivers/clk/samsung/clk-exynos5250.c |  4 +--
 drivers/clk/samsung/clk-exynos5420.c | 16 ++++++------
 drivers/clk/samsung/clk-exynos5433.c | 10 +++-----
 6 files changed, 40 insertions(+), 39 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index d550a4bb632f..82d54b0c9040 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -48,7 +48,7 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
  * @hw:		handle between CCF and CPU clock
  * @alt_parent:	alternate parent clock to use when switching the speed
  *		of the primary parent clock
- * @ctrl_base:	base address of the clock controller
+ * @base:	start address of the CPU clock registers block
  * @lock:	cpu clock domain register access lock
  * @cfg:	cpu clock rate configuration data
  * @num_cfgs:	number of array elements in @cfg array
@@ -64,7 +64,7 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
 struct exynos_cpuclk {
 	struct clk_hw				hw;
 	const struct clk_hw			*alt_parent;
-	void __iomem				*ctrl_base;
+	void __iomem				*base;
 	spinlock_t				*lock;
 	const struct exynos_cpuclk_cfg_data	*cfg;
 	const unsigned long			num_cfgs;
@@ -125,12 +125,12 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 
 /* ---- Exynos 3/4/5 -------------------------------------------------------- */
 
-#define E4210_SRC_CPU		0x0
-#define E4210_STAT_CPU		0x200
-#define E4210_DIV_CPU0		0x300
-#define E4210_DIV_CPU1		0x304
-#define E4210_DIV_STAT_CPU0	0x400
-#define E4210_DIV_STAT_CPU1	0x404
+#define E4210_SRC_CPU		0x200
+#define E4210_STAT_CPU		0x400
+#define E4210_DIV_CPU0		0x500
+#define E4210_DIV_CPU1		0x504
+#define E4210_DIV_STAT_CPU0	0x600
+#define E4210_DIV_STAT_CPU1	0x604
 
 #define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
 #define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
@@ -160,7 +160,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 					 struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
-	void __iomem *base = cpuclk->ctrl_base;
+	void __iomem *base = cpuclk->base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
@@ -238,7 +238,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 					  struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
-	void __iomem *base = cpuclk->ctrl_base;
+	void __iomem *base = cpuclk->base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
 	unsigned long flags;
@@ -271,12 +271,12 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 
 /* ---- Exynos5433 ---------------------------------------------------------- */
 
-#define E5433_MUX_SEL2		0x008
-#define E5433_MUX_STAT2		0x208
-#define E5433_DIV_CPU0		0x400
-#define E5433_DIV_CPU1		0x404
-#define E5433_DIV_STAT_CPU0	0x500
-#define E5433_DIV_STAT_CPU1	0x504
+#define E5433_MUX_SEL2		0x208
+#define E5433_MUX_STAT2		0x408
+#define E5433_DIV_CPU0		0x600
+#define E5433_DIV_CPU1		0x604
+#define E5433_DIV_STAT_CPU0	0x700
+#define E5433_DIV_STAT_CPU1	0x704
 
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
@@ -299,7 +299,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 					     struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
-	void __iomem *base = cpuclk->ctrl_base;
+	void __iomem *base = cpuclk->base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
@@ -359,7 +359,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 					      struct exynos_cpuclk *cpuclk)
 {
-	void __iomem *base = cpuclk->ctrl_base;
+	void __iomem *base = cpuclk->base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
 	unsigned long flags;
@@ -461,7 +461,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	cpuclk->alt_parent = alt_parent;
 	cpuclk->hw.init = &init;
-	cpuclk->ctrl_base = ctx->reg_base + clk_data->offset;
+	cpuclk->base = ctx->reg_base + clk_data->offset;
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
 	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index a02461667664..bf149fae04c3 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -775,7 +775,7 @@ static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos3250_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-			CLK_CPU_HAS_DIV1, 0x14200, e3250_armclk_d),
+		CLK_CPU_HAS_DIV1, 0x14000, e3250_armclk_d),
 };
 
 static void __init exynos3_core_down_clock(void __iomem *reg_base)
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 4ec41221e68f..d5b1e9f49d8b 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1252,17 +1252,20 @@ static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos4210_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_SCLK_MPLL,
-			CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4210_armclk_d),
+		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
+		e4210_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4212_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4212_armclk_d),
+		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
+		e4212_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4412_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-			CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4412_armclk_d),
+		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
+		e4412_armclk_d),
 };
 
 /* register exynos4 clocks */
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 8ebe6155d8b7..58df80de52ef 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -776,8 +776,8 @@ static const struct exynos_cpuclk_cfg_data exynos5250_armclk_d[] __initconst = {
 };
 
 static const struct samsung_cpu_clock exynos5250_cpu_clks[] __initconst = {
-	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL, CLK_CPU_HAS_DIV1, 0x200,
-			exynos5250_armclk_d),
+	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL,
+		CLK_CPU_HAS_DIV1, 0x0, exynos5250_armclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 199843f12ae5..bd7b304d2c00 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -1555,17 +1555,17 @@ static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = {
 };
 
 static const struct samsung_cpu_clock exynos5420_cpu_clks[] __initconst = {
-	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200,
-			exynos5420_eglclk_d),
-	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200,
-			exynos5420_kfcclk_d),
+	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
+		0x0, exynos5420_eglclk_d),
+	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
+		0x28000, exynos5420_kfcclk_d),
 };
 
 static const struct samsung_cpu_clock exynos5800_cpu_clks[] __initconst = {
-	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200,
-			exynos5800_eglclk_d),
-	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200,
-			exynos5420_kfcclk_d),
+	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
+		0x0, exynos5800_eglclk_d),
+	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
+		0x28000, exynos5420_kfcclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index 6bfc5d0cd924..d3779eefb438 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -3700,9 +3700,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_apolloclk_d[] __initconst
 
 static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL,
-			CLK_MOUT_BUS_PLL_APOLLO_USER,
-			CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200,
-			exynos5433_apolloclk_d),
+		CLK_MOUT_BUS_PLL_APOLLO_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
+		0x0, exynos5433_apolloclk_d),
 };
 
 static const struct samsung_cmu_info apollo_cmu_info __initconst = {
@@ -3945,9 +3944,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_atlasclk_d[] __initconst =
 
 static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL,
-			CLK_MOUT_BUS_PLL_ATLAS_USER,
-			CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200,
-			exynos5433_atlasclk_d),
+		CLK_MOUT_BUS_PLL_ATLAS_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
+		0x0, exynos5433_atlasclk_d),
 };
 
 static const struct samsung_cmu_info atlas_cmu_info __initconst = {
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:28 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:28 -0600
Subject: [PATCH v2 08/15] clk: samsung: Pass register layout type explicitly to CLK_CPU()
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-9-semen.protsenko@linaro.org>

Use a dedicated enum field to explicitly specify which register layout
should be used for the CPU clock, instead of passing it as a bit flag.
This way it would be possible to keep the chip-specific data in some
array, where each chip structure could be accessed by its corresponding
layout index. It prepares clk-cpu.c for adding new chips support, which
might have different data for different CPU clusters.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - Improved the commit message: explained why enum is needed for
    specifying the layout (vs bit flag)
  - Included clk-cpu.h in clk.h as it uses enum exynos_cpuclk_layout
    from clk-cpu.h (it's needed because preceding patch adding headers
    was dropped)

 drivers/clk/samsung/clk-cpu.c        |  2 +-
 drivers/clk/samsung/clk-cpu.h        | 12 ++++++++++--
 drivers/clk/samsung/clk-exynos3250.c |  2 +-
 drivers/clk/samsung/clk-exynos4.c    |  6 +++---
 drivers/clk/samsung/clk-exynos5250.c |  3 ++-
 drivers/clk/samsung/clk-exynos5420.c |  8 ++++----
 drivers/clk/samsung/clk-exynos5433.c |  8 ++++----
 drivers/clk/samsung/clk.h            |  5 ++++-
 8 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 82d54b0c9040..635ab8cc54a2 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -465,7 +465,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
 	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
-	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT) {
+	if (clk_data->reg_layout == CPUCLK_LAYOUT_E5433) {
 		cpuclk->pre_rate_cb = exynos5433_cpuclk_pre_rate_change;
 		cpuclk->post_rate_cb = exynos5433_cpuclk_post_rate_change;
 	} else {
diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h
index ee57f3638fed..4382ab005ad3 100644
--- a/drivers/clk/samsung/clk-cpu.h
+++ b/drivers/clk/samsung/clk-cpu.h
@@ -12,8 +12,16 @@
 #define CLK_CPU_HAS_DIV1		BIT(0)
 /* When ALT parent is active, debug clocks need safe divider values */
 #define CLK_CPU_NEEDS_DEBUG_ALT_DIV	BIT(1)
-/* The CPU clock registers have Exynos5433-compatible layout */
-#define CLK_CPU_HAS_E5433_REGS_LAYOUT	BIT(2)
+
+/**
+ * enum exynos_cpuclk_layout - CPU clock registers layout compatibility
+ * @CPUCLK_LAYOUT_E4210: Exynos4210 compatible layout
+ * @CPUCLK_LAYOUT_E5433: Exynos5433 compatible layout
+ */
+enum exynos_cpuclk_layout {
+	CPUCLK_LAYOUT_E4210,
+	CPUCLK_LAYOUT_E5433,
+};
 
 /**
  * struct exynos_cpuclk_cfg_data - config data to setup cpu clocks
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index bf149fae04c3..cd4fec323a42 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -775,7 +775,7 @@ static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos3250_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-		CLK_CPU_HAS_DIV1, 0x14000, e3250_armclk_d),
+		CLK_CPU_HAS_DIV1, 0x14000, CPUCLK_LAYOUT_E4210, e3250_armclk_d),
 };
 
 static void __init exynos3_core_down_clock(void __iomem *reg_base)
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index d5b1e9f49d8b..a026ccca7315 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1253,19 +1253,19 @@ static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
 static const struct samsung_cpu_clock exynos4210_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_SCLK_MPLL,
 		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
-		e4210_armclk_d),
+		CPUCLK_LAYOUT_E4210, e4210_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4212_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
 		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
-		e4212_armclk_d),
+		CPUCLK_LAYOUT_E4210, e4212_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4412_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
 		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
-		e4412_armclk_d),
+		CPUCLK_LAYOUT_E4210, e4412_armclk_d),
 };
 
 /* register exynos4 clocks */
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 58df80de52ef..e02e7c013f3d 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -777,7 +777,8 @@ static const struct exynos_cpuclk_cfg_data exynos5250_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos5250_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL,
-		CLK_CPU_HAS_DIV1, 0x0, exynos5250_armclk_d),
+		CLK_CPU_HAS_DIV1, 0x0, CPUCLK_LAYOUT_E4210,
+		exynos5250_armclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index bd7b304d2c00..c630135c686b 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -1556,16 +1556,16 @@ static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos5420_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
-		0x0, exynos5420_eglclk_d),
+		0x0, CPUCLK_LAYOUT_E4210, exynos5420_eglclk_d),
 	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
-		0x28000, exynos5420_kfcclk_d),
+		0x28000, CPUCLK_LAYOUT_E4210, exynos5420_kfcclk_d),
 };
 
 static const struct samsung_cpu_clock exynos5800_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
-		0x0, exynos5800_eglclk_d),
+		0x0, CPUCLK_LAYOUT_E4210, exynos5800_eglclk_d),
 	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
-		0x28000, exynos5420_kfcclk_d),
+		0x28000, CPUCLK_LAYOUT_E4210, exynos5420_kfcclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index d3779eefb438..609d31a7aa52 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -3700,8 +3700,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_apolloclk_d[] __initconst
 
 static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL,
-		CLK_MOUT_BUS_PLL_APOLLO_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
-		0x0, exynos5433_apolloclk_d),
+		CLK_MOUT_BUS_PLL_APOLLO_USER, 0, 0x0,
+		CPUCLK_LAYOUT_E5433, exynos5433_apolloclk_d),
 };
 
 static const struct samsung_cmu_info apollo_cmu_info __initconst = {
@@ -3944,8 +3944,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_atlasclk_d[] __initconst =
 
 static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL,
-		CLK_MOUT_BUS_PLL_ATLAS_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
-		0x0, exynos5433_atlasclk_d),
+		CLK_MOUT_BUS_PLL_ATLAS_USER, 0, 0x0,
+		CPUCLK_LAYOUT_E5433, exynos5433_atlasclk_d),
 };
 
 static const struct samsung_cmu_info atlas_cmu_info __initconst = {
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 516b716407e5..a763309e6f12 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -12,6 +12,7 @@
 
 #include <linux/clk-provider.h>
 #include "clk-pll.h"
+#include "clk-cpu.h"
 
 /**
  * struct samsung_clk_provider - information about clock provider
@@ -282,10 +283,11 @@ struct samsung_cpu_clock {
 	unsigned int	alt_parent_id;
 	unsigned long	flags;
 	int		offset;
+	enum exynos_cpuclk_layout reg_layout;
 	const struct exynos_cpuclk_cfg_data *cfg;
 };
 
-#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \
+#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _layout, _cfg) \
 	{							\
 		.id		  = _id,			\
 		.name		  = _name,			\
@@ -293,6 +295,7 @@ struct samsung_cpu_clock {
 		.alt_parent_id	  = _apid,			\
 		.flags		  = _flags,			\
 		.offset		  = _offset,			\
+		.reg_layout	  = _layout,			\
 		.cfg		  = _cfg,			\
 	}
 
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:29 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:29 -0600
Subject: [PATCH v2 09/15] clk: samsung: Keep CPU clock chip specific data in a dedicated struct
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-10-semen.protsenko@linaro.org>

Keep chip specific data in the data structure, don't mix it with code.
It makes it easier to add more chip specific data further. Having all
chip specific data in the table eliminates possible code bloat when
adding more rate handlers for new chips, and also makes it possible to
keep some other chip related data in that array.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
- Improved the commit message: explained why it's beneficial for new
  chips to keep chip-specific data in one table

 drivers/clk/samsung/clk-cpu.c | 40 +++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 635ab8cc54a2..eb2b67d08f89 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -43,6 +43,16 @@ struct exynos_cpuclk;
 typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
 				       struct exynos_cpuclk *cpuclk);
 
+/**
+ * struct exynos_cpuclk_chip - Chip specific data for CPU clock
+ * @pre_rate_cb: callback to run before CPU clock rate change
+ * @post_rate_cb: callback to run after CPU clock rate change
+ */
+struct exynos_cpuclk_chip {
+	exynos_rate_change_fn_t	pre_rate_cb;
+	exynos_rate_change_fn_t	post_rate_cb;
+};
+
 /**
  * struct exynos_cpuclk - information about clock supplied to a CPU core
  * @hw:		handle between CCF and CPU clock
@@ -55,8 +65,7 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
  * @clk_nb:	clock notifier registered for changes in clock speed of the
  *		primary parent clock
  * @flags:	configuration flags for the CPU clock
- * @pre_rate_cb: callback to run before CPU clock rate change
- * @post_rate_cb: callback to run after CPU clock rate change
+ * @chip:	chip-specific data for the CPU clock
  *
  * This structure holds information required for programming the CPU clock for
  * various clock speeds.
@@ -70,9 +79,7 @@ struct exynos_cpuclk {
 	const unsigned long			num_cfgs;
 	struct notifier_block			clk_nb;
 	unsigned long				flags;
-
-	exynos_rate_change_fn_t			pre_rate_cb;
-	exynos_rate_change_fn_t			post_rate_cb;
+	const struct exynos_cpuclk_chip		*chip;
 };
 
 /* ---- Common code --------------------------------------------------------- */
@@ -420,13 +427,24 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
 	cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb);
 
 	if (event == PRE_RATE_CHANGE)
-		err = cpuclk->pre_rate_cb(ndata, cpuclk);
+		err = cpuclk->chip->pre_rate_cb(ndata, cpuclk);
 	else if (event == POST_RATE_CHANGE)
-		err = cpuclk->post_rate_cb(ndata, cpuclk);
+		err = cpuclk->chip->post_rate_cb(ndata, cpuclk);
 
 	return notifier_from_errno(err);
 }
 
+static const struct exynos_cpuclk_chip exynos_clkcpu_chips[] = {
+	[CPUCLK_LAYOUT_E4210] = {
+		.pre_rate_cb	= exynos_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos_cpuclk_post_rate_change,
+	},
+	[CPUCLK_LAYOUT_E5433] = {
+		.pre_rate_cb	= exynos5433_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos5433_cpuclk_post_rate_change,
+	},
+};
+
 /* helper function to register a CPU clock */
 static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 				const struct samsung_cpu_clock *clk_data)
@@ -465,13 +483,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
 	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
-	if (clk_data->reg_layout == CPUCLK_LAYOUT_E5433) {
-		cpuclk->pre_rate_cb = exynos5433_cpuclk_pre_rate_change;
-		cpuclk->post_rate_cb = exynos5433_cpuclk_post_rate_change;
-	} else {
-		cpuclk->pre_rate_cb = exynos_cpuclk_pre_rate_change;
-		cpuclk->post_rate_cb = exynos_cpuclk_post_rate_change;
-	}
+	cpuclk->chip = &exynos_clkcpu_chips[clk_data->reg_layout];
 
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:31 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:31 -0600
Subject: [PATCH v2 11/15] clk: samsung: Pass mask to wait_until_mux_stable()
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-12-semen.protsenko@linaro.org>

Make it possible to use wait_until_mux_stable() for MUX registers where
the mask is different from MUX_MASK (e.g. in upcoming CPU clock
implementation for Exynos850).

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 93e961855875..89b24fd5d0a9 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -135,16 +135,16 @@ static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
  * value was changed.
  */
 static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
-				  unsigned long mux_value)
+				  unsigned long mask, unsigned long mux_value)
 {
 	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);
 
 	do {
-		if (((readl(mux_reg) >> mux_pos) & MUX_MASK) == mux_value)
+		if (((readl(mux_reg) >> mux_pos) & mask) == mux_value)
 			return;
 	} while (time_before(jiffies, timeout));
 
-	if (((readl(mux_reg) >> mux_pos) & MUX_MASK) == mux_value)
+	if (((readl(mux_reg) >> mux_pos) & mask) == mux_value)
 		return;
 
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
@@ -249,7 +249,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	/* select sclk_mpll as the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg | (1 << 16), base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 16, 2);
+	wait_until_mux_stable(base + regs->mux_stat, 16, MUX_MASK, 2);
 
 	/* alternate parent is active now. set the dividers */
 	writel(div0, base + regs->div_cpu0);
@@ -290,7 +290,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	/* select mout_apll as the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg & ~(1 << 16), base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 16, 1);
+	wait_until_mux_stable(base + regs->mux_stat, 16, MUX_MASK, 1);
 
 	if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
 		div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK);
@@ -362,7 +362,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	/* select the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg | 1, base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 0, 2);
+	wait_until_mux_stable(base + regs->mux_stat, 0, MUX_MASK, 2);
 
 	/* alternate parent is active now. set the dividers */
 	writel(div0, base + regs->div_cpu0);
@@ -390,7 +390,7 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	/* select apll as the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg & ~1, base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 0, 1);
+	wait_until_mux_stable(base + regs->mux_stat, 0, MUX_MASK, 1);
 
 	exynos_set_safe_div(cpuclk, div, div_mask);
 	spin_unlock_irqrestore(cpuclk->lock, flags);
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:30 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:30 -0600
Subject: [PATCH v2 10/15] clk: samsung: Keep register offsets in chip specific structure
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-11-semen.protsenko@linaro.org>

Abstract CPU clock registers by keeping their offsets in a dedicated
chip specific structure to accommodate for oncoming Exynos850 support,
which has different offsets for cluster 0 and cluster 1. This rework
also makes it possible to use exynos_set_safe_div() for all chips, so
exynos5433_set_safe_div() is removed here to reduce the code
duplication. The ".regs" field has to be (void *) as different Exynos
chips can have very different register layout, so this way it's possible
for ".regs" to point to different structures, each representing its own
chip's layout.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - Improved the commit message: explained why .regs field has to be
    (void *)
  - Changed .ctrl_base field to .base to reflect changes in previous
    commits

 drivers/clk/samsung/clk-cpu.c | 156 +++++++++++++++++++---------------
 1 file changed, 86 insertions(+), 70 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index eb2b67d08f89..93e961855875 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -45,12 +45,14 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
 
 /**
  * struct exynos_cpuclk_chip - Chip specific data for CPU clock
+ * @regs: register offsets for CPU related clocks
  * @pre_rate_cb: callback to run before CPU clock rate change
  * @post_rate_cb: callback to run after CPU clock rate change
  */
 struct exynos_cpuclk_chip {
-	exynos_rate_change_fn_t	pre_rate_cb;
-	exynos_rate_change_fn_t	post_rate_cb;
+	const void				* const regs;
+	exynos_rate_change_fn_t			pre_rate_cb;
+	exynos_rate_change_fn_t			post_rate_cb;
 };
 
 /**
@@ -91,6 +93,24 @@ struct exynos_cpuclk {
 #define DIV_MASK_ALL		GENMASK(31, 0)
 #define MUX_MASK		GENMASK(2, 0)
 
+/**
+ * struct exynos_cpuclk_regs - Register offsets for CPU related clocks
+ * @mux_sel: offset of CPU MUX_SEL register (for selecting MUX clock parent)
+ * @mux_stat: offset of CPU MUX_STAT register (for checking MUX clock status)
+ * @div_cpu0: offset of CPU DIV0 register (for modifying divider values)
+ * @div_cpu1: offset of CPU DIV1 register (for modifying divider values)
+ * @div_stat_cpu0: offset of CPU DIV0_STAT register (for checking DIV status)
+ * @div_stat_cpu1: offset of CPU DIV1_STAT register (for checking DIV status)
+ */
+struct exynos_cpuclk_regs {
+	u32 mux_sel;
+	u32 mux_stat;
+	u32 div_cpu0;
+	u32 div_cpu1;
+	u32 div_stat_cpu0;
+	u32 div_stat_cpu1;
+};
+
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
  * value has changed.
@@ -130,43 +150,48 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
 }
 
-/* ---- Exynos 3/4/5 -------------------------------------------------------- */
-
-#define E4210_SRC_CPU		0x200
-#define E4210_STAT_CPU		0x400
-#define E4210_DIV_CPU0		0x500
-#define E4210_DIV_CPU1		0x504
-#define E4210_DIV_STAT_CPU0	0x600
-#define E4210_DIV_STAT_CPU1	0x604
-
-#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
-#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
-#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
-#define E4210_MUX_HPM_MASK	BIT(20)
-#define E4210_DIV0_ATB_SHIFT	16
-#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
-
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
  * div and mask contain the divider value and the register bit mask of the
  * dividers to be programmed.
  */
-static void exynos_set_safe_div(void __iomem *base, unsigned long div,
+static void exynos_set_safe_div(struct exynos_cpuclk *cpuclk, unsigned long div,
 				unsigned long mask)
 {
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
+	void __iomem *base = cpuclk->base;
 	unsigned long div0;
 
-	div0 = readl(base + E4210_DIV_CPU0);
+	div0 = readl(base + regs->div_cpu0);
 	div0 = (div0 & ~mask) | (div & mask);
-	writel(div0, base + E4210_DIV_CPU0);
-	wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, mask);
+	writel(div0, base + regs->div_cpu0);
+	wait_until_divider_stable(base + regs->div_stat_cpu0, mask);
 }
 
+/* ---- Exynos 3/4/5 -------------------------------------------------------- */
+
+#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
+#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
+#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
+#define E4210_MUX_HPM_MASK	BIT(20)
+#define E4210_DIV0_ATB_SHIFT	16
+#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
+
+static const struct exynos_cpuclk_regs e4210_cpuclk_regs = {
+	.mux_sel	= 0x200,
+	.mux_stat	= 0x400,
+	.div_cpu0	= 0x500,
+	.div_cpu1	= 0x504,
+	.div_stat_cpu0	= 0x600,
+	.div_stat_cpu1	= 0x604,
+};
+
 /* handler for pre-rate change notification from parent clock */
 static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 					 struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
@@ -189,8 +214,8 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	div0 = cfg_data->div0;
 	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
 		div1 = cfg_data->div1;
-		if (readl(base + E4210_SRC_CPU) & E4210_MUX_HPM_MASK)
-			div1 = readl(base + E4210_DIV_CPU1) &
+		if (readl(base + regs->mux_sel) & E4210_MUX_HPM_MASK)
+			div1 = readl(base + regs->div_cpu1) &
 				(E4210_DIV1_HPM_MASK | E4210_DIV1_COPY_MASK);
 	}
 
@@ -217,22 +242,22 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 			alt_div |= E4210_DIV0_ATB_MASK;
 			alt_div_mask |= E4210_DIV0_ATB_MASK;
 		}
-		exynos_set_safe_div(base, alt_div, alt_div_mask);
+		exynos_set_safe_div(cpuclk, alt_div, alt_div_mask);
 		div0 |= alt_div;
 	}
 
 	/* select sclk_mpll as the alternate parent */
-	mux_reg = readl(base + E4210_SRC_CPU);
-	writel(mux_reg | (1 << 16), base + E4210_SRC_CPU);
-	wait_until_mux_stable(base + E4210_STAT_CPU, 16, 2);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg | (1 << 16), base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 16, 2);
 
 	/* alternate parent is active now. set the dividers */
-	writel(div0, base + E4210_DIV_CPU0);
-	wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, DIV_MASK_ALL);
+	writel(div0, base + regs->div_cpu0);
+	wait_until_divider_stable(base + regs->div_stat_cpu0, DIV_MASK_ALL);
 
 	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
-		writel(div1, base + E4210_DIV_CPU1);
-		wait_until_divider_stable(base + E4210_DIV_STAT_CPU1,
+		writel(div1, base + regs->div_cpu1);
+		wait_until_divider_stable(base + regs->div_stat_cpu1,
 					  DIV_MASK_ALL);
 	}
 
@@ -245,6 +270,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 					  struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
@@ -262,50 +288,37 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	spin_lock_irqsave(cpuclk->lock, flags);
 
 	/* select mout_apll as the alternate parent */
-	mux_reg = readl(base + E4210_SRC_CPU);
-	writel(mux_reg & ~(1 << 16), base + E4210_SRC_CPU);
-	wait_until_mux_stable(base + E4210_STAT_CPU, 16, 1);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg & ~(1 << 16), base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 16, 1);
 
 	if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
 		div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK);
 		div_mask |= E4210_DIV0_ATB_MASK;
 	}
 
-	exynos_set_safe_div(base, div, div_mask);
+	exynos_set_safe_div(cpuclk, div, div_mask);
 	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
 }
 
 /* ---- Exynos5433 ---------------------------------------------------------- */
 
-#define E5433_MUX_SEL2		0x208
-#define E5433_MUX_STAT2		0x408
-#define E5433_DIV_CPU0		0x600
-#define E5433_DIV_CPU1		0x604
-#define E5433_DIV_STAT_CPU0	0x700
-#define E5433_DIV_STAT_CPU1	0x704
-
-/*
- * Helper function to set the 'safe' dividers for the CPU clock. The parameters
- * div and mask contain the divider value and the register bit mask of the
- * dividers to be programmed.
- */
-static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
-				    unsigned long mask)
-{
-	unsigned long div0;
-
-	div0 = readl(base + E5433_DIV_CPU0);
-	div0 = (div0 & ~mask) | (div & mask);
-	writel(div0, base + E5433_DIV_CPU0);
-	wait_until_divider_stable(base + E5433_DIV_STAT_CPU0, mask);
-}
+static const struct exynos_cpuclk_regs e5433_cpuclk_regs = {
+	.mux_sel	= 0x208,
+	.mux_stat	= 0x408,
+	.div_cpu0	= 0x600,
+	.div_cpu1	= 0x604,
+	.div_stat_cpu0	= 0x700,
+	.div_stat_cpu1	= 0x704,
+};
 
 /* handler for pre-rate change notification from parent clock */
 static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 					     struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
@@ -342,21 +355,21 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 		alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
 		WARN_ON(alt_div >= MAX_DIV);
 
-		exynos5433_set_safe_div(base, alt_div, alt_div_mask);
+		exynos_set_safe_div(cpuclk, alt_div, alt_div_mask);
 		div0 |= alt_div;
 	}
 
 	/* select the alternate parent */
-	mux_reg = readl(base + E5433_MUX_SEL2);
-	writel(mux_reg | 1, base + E5433_MUX_SEL2);
-	wait_until_mux_stable(base + E5433_MUX_STAT2, 0, 2);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg | 1, base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 0, 2);
 
 	/* alternate parent is active now. set the dividers */
-	writel(div0, base + E5433_DIV_CPU0);
-	wait_until_divider_stable(base + E5433_DIV_STAT_CPU0, DIV_MASK_ALL);
+	writel(div0, base + regs->div_cpu0);
+	wait_until_divider_stable(base + regs->div_stat_cpu0, DIV_MASK_ALL);
 
-	writel(div1, base + E5433_DIV_CPU1);
-	wait_until_divider_stable(base + E5433_DIV_STAT_CPU1, DIV_MASK_ALL);
+	writel(div1, base + regs->div_cpu1);
+	wait_until_divider_stable(base + regs->div_stat_cpu1, DIV_MASK_ALL);
 
 	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
@@ -366,6 +379,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 					      struct exynos_cpuclk *cpuclk)
 {
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
@@ -374,11 +388,11 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	spin_lock_irqsave(cpuclk->lock, flags);
 
 	/* select apll as the alternate parent */
-	mux_reg = readl(base + E5433_MUX_SEL2);
-	writel(mux_reg & ~1, base + E5433_MUX_SEL2);
-	wait_until_mux_stable(base + E5433_MUX_STAT2, 0, 1);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg & ~1, base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 0, 1);
 
-	exynos5433_set_safe_div(base, div, div_mask);
+	exynos_set_safe_div(cpuclk, div, div_mask);
 	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
 }
@@ -436,10 +450,12 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
 
 static const struct exynos_cpuclk_chip exynos_clkcpu_chips[] = {
 	[CPUCLK_LAYOUT_E4210] = {
+		.regs		= &e4210_cpuclk_regs,
 		.pre_rate_cb	= exynos_cpuclk_pre_rate_change,
 		.post_rate_cb	= exynos_cpuclk_post_rate_change,
 	},
 	[CPUCLK_LAYOUT_E5433] = {
+		.regs		= &e5433_cpuclk_regs,
 		.pre_rate_cb	= exynos5433_cpuclk_pre_rate_change,
 		.post_rate_cb	= exynos5433_cpuclk_post_rate_change,
 	},
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:32 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:32 -0600
Subject: [PATCH v2 12/15] clk: samsung: Add CPU clock support for Exynos850
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-13-semen.protsenko@linaro.org>

Implement CPU clock control for Exynos850 SoC. It follows the same
procedure which is already implemented for other SoCs in clk-cpu.c:

1. Set the correct rate for the alternate parent (if needed) before
   switching to use it as the CPU clock
2. Switch to the alternate parent, so the CPU continues to get clocked
   while the PLL is being re-configured
3. Adjust the dividers for the CPU related buses (ACLK, ATCLK, etc)
4. Re-configure the PLL for the new CPU clock rate. It's done
   automatically, as the CPU clock rate change propagates to the PLL
   clock, because the CPU clock has CLK_SET_RATE_PARENT flag set in
   exynos_register_cpu_clock()
5. Once the PLL is locked, set it back as the CPU clock source
6. Set alternate parent clock rate back to max speed

As in already existing clk-cpu.c code, the divider and mux clocks are
configured in a low-level fashion (using direct register access instead
of CCF API), to avoid affecting how DIV and MUX clock flags are declared
in the actual clock driver (clk-exynos850.c).

No functional change. This patch adds support for Exynos850 CPU clock,
but doesn't enable it per se.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - Changed .ctrl_base field to .base, to reflect changes made in
    previous commits

 drivers/clk/samsung/clk-cpu.c | 183 ++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-cpu.h |   4 +
 2 files changed, 187 insertions(+)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 89b24fd5d0a9..34c195a980b2 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -29,6 +29,7 @@
  * down in order to keep the output clock rate within the previous OPP limits.
  */
 
+#include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/slab.h>
@@ -397,6 +398,178 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	return 0;
 }
 
+/* ---- Exynos850 ----------------------------------------------------------- */
+
+#define E850_DIV_RATIO_MASK	GENMASK(3, 0)
+#define E850_BUSY_MASK		BIT(16)
+
+/* Max time for divider or mux to stabilize, usec */
+#define E850_DIV_MUX_STAB_TIME	100
+/* OSCCLK clock rate, Hz */
+#define E850_OSCCLK		(26 * MHZ)
+
+/**
+ * struct exynos850_cpuclk_regs - Register offsets for Exynos850 CPU clocks
+ * @mux:		offset of MUX register for choosing CPU clock source
+ * @divs:		offsets of DIV registers (ACLK, ATCLK, PCLKDBG and
+ *			PERIPHCLK)
+ */
+struct exynos850_cpuclk_regs {
+	u32 mux;
+	u32 divs[4];
+};
+
+static const struct exynos850_cpuclk_regs e850cl0_cpuclk_regs = {
+	.mux	= 0x100c,
+	.divs	= { 0x1800, 0x1808, 0x180c, 0x1810 },
+};
+
+static const struct exynos850_cpuclk_regs e850cl1_cpuclk_regs = {
+	.mux	= 0x1000,
+	.divs	= { 0x1800, 0x1808, 0x180c, 0x1810 },
+};
+
+/*
+ * Set alternate parent rate to "rate" value or less.
+ *
+ * rate: Desired alt_parent rate, or 0 for max alt_parent rate
+ *
+ * Exynos850 doesn't have CPU clock divider in CMU_CPUCLx block (CMUREF divider
+ * doesn't affect CPU speed). So CPUCLx_SWITCH divider from CMU_TOP is used
+ * instead to adjust alternate parent speed.
+ *
+ * It's possible to use clk_set_max_rate() instead of this function, but it
+ * would set overly pessimistic rate values to alternate parent.
+ */
+static int exynos850_alt_parent_set_max_rate(const struct clk_hw *alt_parent,
+					     unsigned long rate)
+{
+	struct clk_hw *clk_div, *clk_divp;
+	unsigned long divp_rate, div_rate, div;
+	int ret;
+
+	/* Divider from CMU_TOP */
+	clk_div = clk_hw_get_parent(alt_parent);
+	if (!clk_div)
+		return -ENOENT;
+	/* Divider's parent from CMU_TOP */
+	clk_divp = clk_hw_get_parent(clk_div);
+	if (!clk_divp)
+		return -ENOENT;
+	/* Divider input rate */
+	divp_rate = clk_hw_get_rate(clk_divp);
+	if (!divp_rate)
+		return -EINVAL;
+
+	/* Calculate new alt_parent rate for integer divider value */
+	if (rate == 0)
+		div = 1;
+	else
+		div = DIV_ROUND_UP(divp_rate, rate);
+	div_rate = DIV_ROUND_UP(divp_rate, div);
+	WARN_ON(div >= MAX_DIV);
+
+	/* alt_parent will propagate this change up to the divider */
+	ret = clk_set_rate(alt_parent->clk, div_rate);
+	if (ret)
+		return ret;
+	udelay(E850_DIV_MUX_STAB_TIME);
+
+	return 0;
+}
+
+/* Handler for pre-rate change notification from parent clock */
+static int exynos850_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
+					    struct exynos_cpuclk *cpuclk)
+{
+	const unsigned int shifts[4] = { 16, 12, 8, 4 }; /* E850_CPU_DIV0() */
+	const struct exynos850_cpuclk_regs * const regs = cpuclk->chip->regs;
+	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct clk_hw *alt_parent = cpuclk->alt_parent;
+	void __iomem *base = cpuclk->base;
+	unsigned long alt_prate = clk_hw_get_rate(alt_parent);
+	unsigned long flags;
+	u32 mux_reg;
+	size_t i;
+	int ret;
+
+	/* No actions are needed when switching to or from OSCCLK parent */
+	if (ndata->new_rate == E850_OSCCLK || ndata->old_rate == E850_OSCCLK)
+		return 0;
+
+	/* Find out the divider values to use for clock data */
+	while ((cfg_data->prate * 1000) != ndata->new_rate) {
+		if (cfg_data->prate == 0)
+			return -EINVAL;
+		cfg_data++;
+	}
+
+	/*
+	 * If the old parent clock speed is less than the clock speed of
+	 * the alternate parent, then it should be ensured that at no point
+	 * the armclk speed is more than the old_prate until the dividers are
+	 * set.  Also workaround the issue of the dividers being set to lower
+	 * values before the parent clock speed is set to new lower speed
+	 * (this can result in too high speed of armclk output clocks).
+	 */
+	if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) {
+		unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate);
+
+		ret = exynos850_alt_parent_set_max_rate(alt_parent, tmp_rate);
+		if (ret)
+			return ret;
+	}
+
+	spin_lock_irqsave(cpuclk->lock, flags);
+
+	/* Select the alternate parent */
+	mux_reg = readl(base + regs->mux);
+	writel(mux_reg | 1, base + regs->mux);
+	wait_until_mux_stable(base + regs->mux, 16, 1, 0);
+
+	/* Alternate parent is active now. Set the dividers */
+	for (i = 0; i < ARRAY_SIZE(shifts); ++i) {
+		unsigned long div = (cfg_data->div0 >> shifts[i]) & 0xf;
+		u32 val;
+
+		val = readl(base + regs->divs[i]);
+		val = (val & ~E850_DIV_RATIO_MASK) | div;
+		writel(val, base + regs->divs[i]);
+		wait_until_divider_stable(base + regs->divs[i], E850_BUSY_MASK);
+	}
+
+	spin_unlock_irqrestore(cpuclk->lock, flags);
+
+	return 0;
+}
+
+/* Handler for post-rate change notification from parent clock */
+static int exynos850_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
+					     struct exynos_cpuclk *cpuclk)
+{
+	const struct exynos850_cpuclk_regs * const regs = cpuclk->chip->regs;
+	const struct clk_hw *alt_parent = cpuclk->alt_parent;
+	void __iomem *base = cpuclk->base;
+	unsigned long flags;
+	u32 mux_reg;
+
+	/* No actions are needed when switching to or from OSCCLK parent */
+	if (ndata->new_rate == E850_OSCCLK || ndata->old_rate == E850_OSCCLK)
+		return 0;
+
+	spin_lock_irqsave(cpuclk->lock, flags);
+
+	/* Select main parent (PLL) for mux */
+	mux_reg = readl(base + regs->mux);
+	writel(mux_reg & ~1, base + regs->mux);
+	wait_until_mux_stable(base + regs->mux, 16, 1, 0);
+
+	spin_unlock_irqrestore(cpuclk->lock, flags);
+
+	/* Set alt_parent rate back to max */
+	return exynos850_alt_parent_set_max_rate(alt_parent, 0);
+}
+
 /* -------------------------------------------------------------------------- */
 
 /* Common round rate callback usable for all types of CPU clocks */
@@ -459,6 +632,16 @@ static const struct exynos_cpuclk_chip exynos_clkcpu_chips[] = {
 		.pre_rate_cb	= exynos5433_cpuclk_pre_rate_change,
 		.post_rate_cb	= exynos5433_cpuclk_post_rate_change,
 	},
+	[CPUCLK_LAYOUT_E850_CL0] = {
+		.regs		= &e850cl0_cpuclk_regs,
+		.pre_rate_cb	= exynos850_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos850_cpuclk_post_rate_change,
+	},
+	[CPUCLK_LAYOUT_E850_CL1] = {
+		.regs		= &e850cl1_cpuclk_regs,
+		.pre_rate_cb	= exynos850_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos850_cpuclk_post_rate_change,
+	},
 };
 
 /* helper function to register a CPU clock */
diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h
index 4382ab005ad3..892843611b0a 100644
--- a/drivers/clk/samsung/clk-cpu.h
+++ b/drivers/clk/samsung/clk-cpu.h
@@ -17,10 +17,14 @@
  * enum exynos_cpuclk_layout - CPU clock registers layout compatibility
  * @CPUCLK_LAYOUT_E4210: Exynos4210 compatible layout
  * @CPUCLK_LAYOUT_E5433: Exynos5433 compatible layout
+ * @CPUCLK_LAYOUT_E850_CL0: Exynos850 cluster 0 compatible layout
+ * @CPUCLK_LAYOUT_E850_CL1: Exynos850 cluster 1 compatible layout
  */
 enum exynos_cpuclk_layout {
 	CPUCLK_LAYOUT_E4210,
 	CPUCLK_LAYOUT_E5433,
+	CPUCLK_LAYOUT_E850_CL0,
+	CPUCLK_LAYOUT_E850_CL1,
 };
 
 /**
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:33 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:33 -0600
Subject: [PATCH v2 13/15] clk: samsung: Implement manual PLL control for ARM64 SoCs
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-14-semen.protsenko@linaro.org>

Some ARM64 Exynos chips are capable to control PLL clocks automatically.
For those chips, whether the PLL is controlled automatically or manually
is chosen in PLL_CON1 register with next bits:

    [28]  ENABLE_AUTOMATIC_CLKGATING
    [1]   MANUAL_PLL_CTRL
    [0]   AUTO_PLL_CTRL

The bl2 bootloader sets 0x10000001 value for some PLL_CON1 registers,
which means any attempt to control those PLLs manually (e.g.
disabling/enabling those PLLs or changing MUX parent clocks) would lead
to PLL lock timeout with error message like this:

    Could not lock PLL ...

At the moment, all Samsung clock drivers implement manual clock control.
So in order to make it possible to control PLLs, corresponding PLL_CON1
registers should be set to 0x2 first.

Some older ARM64 chips don't implement the automatic clock control
though. It also might be desirable to configure some PLLs for manual
control, while keeping the default configuration for the rest. So it'd
convenient to choose this PLL mode for each CMU separately. Introduce
.manual_plls field to CMU structure to choose the PLL control mode.
Because it'll be initialized with "false" in all existing CMU
structures by default, it won't affect any existing clock drivers,
allowing for this feature to be enabled gradually when it's needed with
no change for the rest of users. In case .manual_plls is set, set
PLL_CON1 registers to manual control, akin to what's already done for
gate clocks in exynos_arm64_init_clocks(). Of course, PLL_CON1 registers
should be added to corresponding struct samsung_cmu_info::clk_regs array
to make sure they get initialized.

No functional change. This patch adds a feature, but doesn't enable it
for any users.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - none

 drivers/clk/samsung/clk-exynos-arm64.c | 44 +++++++++++++++++---------
 drivers/clk/samsung/clk.h              |  4 +++
 2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos-arm64.c b/drivers/clk/samsung/clk-exynos-arm64.c
index 6fb7194df7ab..55490209b9a9 100644
--- a/drivers/clk/samsung/clk-exynos-arm64.c
+++ b/drivers/clk/samsung/clk-exynos-arm64.c
@@ -25,6 +25,19 @@
 #define GATE_OFF_START		0x2000
 #define GATE_OFF_END		0x2fff
 
+/* PLL CON register offsets range */
+#define PLL_CON_START		0x100
+#define PLL_CON_END		0x600
+
+/* PLL register bits */
+#define PLL_CON1_MANUAL		BIT(1)
+
+/* Helper macros to check for particular clock regiter by its offset */
+#define IS_GATE_REG(o)		((o) >= GATE_OFF_START && (o) <= GATE_OFF_END)
+#define IS_PLL_CONx_REG(o)	((o) >= PLL_CON_START && (o) <= PLL_CON_END)
+#define IS_PLL_CON1_REG(o)	\
+	(IS_PLL_CONx_REG(o) && ((o) & 0xf) == 0x4 && !((o) & 0x10))
+
 struct exynos_arm64_cmu_data {
 	struct samsung_clk_reg_dump *clk_save;
 	unsigned int nr_clk_save;
@@ -40,15 +53,16 @@ struct exynos_arm64_cmu_data {
 
 /**
  * exynos_arm64_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
+ * @np:		CMU device tree node with "reg" property (CMU addr)
+ * @cmu:	CMU data
  *
- * Set manual control mode for all gate clocks.
+ * Set manual control mode for all gate and PLL clocks.
  */
 static void __init exynos_arm64_init_clocks(struct device_node *np,
-		const unsigned long *reg_offs, size_t reg_offs_len)
+					    const struct samsung_cmu_info *cmu)
 {
+	const unsigned long *reg_offs = cmu->clk_regs;
+	size_t reg_offs_len = cmu->nr_clk_regs;
 	void __iomem *reg_base;
 	size_t i;
 
@@ -60,14 +74,14 @@ static void __init exynos_arm64_init_clocks(struct device_node *np,
 		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);
+		if (cmu->manual_plls && IS_PLL_CON1_REG(reg_offs[i])) {
+			writel(PLL_CON1_MANUAL, reg);
+		} else if (IS_GATE_REG(reg_offs[i])) {
+			val = readl(reg);
+			val |= GATE_MANUAL;
+			val &= ~GATE_ENABLE_HWACG;
+			writel(val, reg);
+		}
 	}
 
 	iounmap(reg_base);
@@ -177,7 +191,7 @@ void __init exynos_arm64_register_cmu(struct device *dev,
 		pr_err("%s: could not enable bus clock %s; err = %d\n",
 		       __func__, cmu->clk_name, err);
 
-	exynos_arm64_init_clocks(np, cmu->clk_regs, cmu->nr_clk_regs);
+	exynos_arm64_init_clocks(np, cmu);
 	samsung_cmu_register_one(np, cmu);
 }
 
@@ -224,7 +238,7 @@ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev,
 		       __func__, cmu->clk_name, ret);
 
 	if (set_manual)
-		exynos_arm64_init_clocks(np, cmu->clk_regs, cmu->nr_clk_regs);
+		exynos_arm64_init_clocks(np, cmu);
 
 	reg_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(reg_base))
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index a763309e6f12..a70bd7cce39f 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -330,6 +330,7 @@ struct samsung_clock_reg_cache {
  * @suspend_regs: list of clock registers to set before suspend
  * @nr_suspend_regs: count of clock registers in @suspend_regs
  * @clk_name: name of the parent clock needed for CMU register access
+ * @manual_plls: Enable manual control for PLL clocks
  */
 struct samsung_cmu_info {
 	const struct samsung_pll_clock *pll_clks;
@@ -354,6 +355,9 @@ struct samsung_cmu_info {
 	const struct samsung_clk_reg_dump *suspend_regs;
 	unsigned int nr_suspend_regs;
 	const char *clk_name;
+
+	/* ARM64 Exynos CMUs */
+	bool manual_plls;
 };
 
 struct samsung_clk_provider *samsung_clk_init(struct device *dev,
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:34 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:34 -0600
Subject: [PATCH v2 14/15] clk: samsung: exynos850: Add CMU_CPUCL0 and CMU_CPUCL1
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-15-semen.protsenko@linaro.org>

Implement support for CPU clock management units:
  - CMU_CPUCL0: clocks for cluster 0: 4 x Cortex-A55 (cpu0..cpu3)
  - CMU_CPUCL1: clocks for cluster 1: 4 x Cortex-A55 (cpu4..cpu7)

CPU PLLs are generating main CPU clocks for each cluster, and there are
alternate ("switch") clocks that can be used temporarily while
re-configuring the PLL for a new rate. ACLK, ATCLK, PCLKDBG and
PERIPHCLK clocks are driving corresponding buses. CLK_CLUSTERx_SCLK are
actual leaf CPU clocks and should be used to change CPU rates. Also some
CoreSight clocks can be derived from DBG_USER (debug clock).

PLL table was extracted from ECT table. ECT stands for "Exynos
Characteristic Table", it's a Samsung specific binary data populated by
BL2 bootloader in RAM at 0x90000000 address, containing PLL tables for
various CMUs and other hardware specific information.

The particular PLL type used in CMU_CPUCL0 and CMU_CPUCL1 (pll0822x) is
an integer PLL with middle FVCO. The equation to calculate its output
rate is:

    fout = fin * M / (P*2^S)

where:

    fin = 26 MHz (OSCCLK frequency)
    M = 64..1023
    P = 1..63
    S = 0..6

The PLL table tries to keep "P" value low to reduce the locking time,
which for pll0822x is "t = P * 150" (in OSCCLK cycles).

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - none

 drivers/clk/samsung/clk-exynos850.c | 440 +++++++++++++++++++++++++++-
 1 file changed, 439 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c
index 82cfa22c0788..6215471c4ac6 100644
--- a/drivers/clk/samsung/clk-exynos850.c
+++ b/drivers/clk/samsung/clk-exynos850.c
@@ -14,13 +14,16 @@
 #include <dt-bindings/clock/exynos850.h>
 
 #include "clk.h"
+#include "clk-cpu.h"
 #include "clk-exynos-arm64.h"
 
 /* NOTE: Must be equal to the last clock ID increased by one */
-#define CLKS_NR_TOP			(CLK_DOUT_G3D_SWITCH + 1)
+#define CLKS_NR_TOP			(CLK_DOUT_CPUCL1_SWITCH + 1)
 #define CLKS_NR_APM			(CLK_GOUT_SYSREG_APM_PCLK + 1)
 #define CLKS_NR_AUD			(CLK_GOUT_AUD_CMU_AUD_PCLK + 1)
 #define CLKS_NR_CMGP			(CLK_GOUT_SYSREG_CMGP_PCLK + 1)
+#define CLKS_NR_CPUCL0			(CLK_CLUSTER0_SCLK + 1)
+#define CLKS_NR_CPUCL1			(CLK_CLUSTER1_SCLK + 1)
 #define CLKS_NR_G3D			(CLK_GOUT_G3D_SYSREG_PCLK + 1)
 #define CLKS_NR_HSI			(CLK_GOUT_HSI_CMU_HSI_PCLK + 1)
 #define CLKS_NR_IS			(CLK_GOUT_IS_SYSREG_PCLK + 1)
@@ -47,6 +50,10 @@
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI		0x1018
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD	0x101c
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS		0x1020
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG	0x1024
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH	0x1028
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL1_DBG	0x102c
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH	0x1030
 #define CLK_CON_MUX_MUX_CLKCMU_DPU		0x1034
 #define CLK_CON_MUX_MUX_CLKCMU_G3D_SWITCH	0x1038
 #define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS		0x103c
@@ -69,6 +76,10 @@
 #define CLK_CON_DIV_CLKCMU_CORE_CCI		0x1824
 #define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD	0x1828
 #define CLK_CON_DIV_CLKCMU_CORE_SSS		0x182c
+#define CLK_CON_DIV_CLKCMU_CPUCL0_DBG		0x1830
+#define CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH	0x1834
+#define CLK_CON_DIV_CLKCMU_CPUCL1_DBG		0x1838
+#define CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH	0x183c
 #define CLK_CON_DIV_CLKCMU_DPU			0x1840
 #define CLK_CON_DIV_CLKCMU_G3D_SWITCH		0x1844
 #define CLK_CON_DIV_CLKCMU_HSI_BUS		0x1848
@@ -97,6 +108,10 @@
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI	0x2020
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD	0x2024
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS	0x2028
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG	0x202c
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH	0x2030
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL1_DBG	0x2034
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH	0x2038
 #define CLK_CON_GAT_GATE_CLKCMU_DPU		0x203c
 #define CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH	0x2040
 #define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS		0x2044
@@ -130,6 +145,10 @@ static const unsigned long top_clk_regs[] __initconst = {
 	CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
 	CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD,
 	CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL1_DBG,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
 	CLK_CON_MUX_MUX_CLKCMU_DPU,
 	CLK_CON_MUX_MUX_CLKCMU_G3D_SWITCH,
 	CLK_CON_MUX_MUX_CLKCMU_HSI_BUS,
@@ -152,6 +171,10 @@ static const unsigned long top_clk_regs[] __initconst = {
 	CLK_CON_DIV_CLKCMU_CORE_CCI,
 	CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD,
 	CLK_CON_DIV_CLKCMU_CORE_SSS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_DBG,
+	CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL1_DBG,
+	CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH,
 	CLK_CON_DIV_CLKCMU_DPU,
 	CLK_CON_DIV_CLKCMU_G3D_SWITCH,
 	CLK_CON_DIV_CLKCMU_HSI_BUS,
@@ -180,6 +203,10 @@ static const unsigned long top_clk_regs[] __initconst = {
 	CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
 	CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD,
 	CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL1_DBG,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
 	CLK_CON_GAT_GATE_CLKCMU_DPU,
 	CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
 	CLK_CON_GAT_GATE_CLKCMU_HSI_BUS,
@@ -234,6 +261,14 @@ PNAME(mout_core_mmc_embd_p)	= { "oscclk", "dout_shared0_div2",
 				    "oscclk", "oscclk" };
 PNAME(mout_core_sss_p)		= { "dout_shared0_div3", "dout_shared1_div3",
 				    "dout_shared0_div4", "dout_shared1_div4" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_CPUCL0 */
+PNAME(mout_cpucl0_switch_p)	= { "fout_shared0_pll", "fout_shared1_pll",
+				    "dout_shared0_div2", "dout_shared1_div2" };
+PNAME(mout_cpucl0_dbg_p)	= { "dout_shared0_div4", "dout_shared1_div4" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_CPUCL1 */
+PNAME(mout_cpucl1_switch_p)	= { "fout_shared0_pll", "fout_shared1_pll",
+				    "dout_shared0_div2", "dout_shared1_div2" };
+PNAME(mout_cpucl1_dbg_p)	= { "dout_shared0_div4", "dout_shared1_div4" };
 /* List of parent clocks for Muxes in CMU_TOP: for CMU_G3D */
 PNAME(mout_g3d_switch_p)	= { "dout_shared0_div2", "dout_shared1_div2",
 				    "dout_shared0_div3", "dout_shared1_div3" };
@@ -300,6 +335,18 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = {
 	MUX(CLK_MOUT_CORE_SSS, "mout_core_sss", mout_core_sss_p,
 	    CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 0, 2),
 
+	/* CPUCL0 */
+	MUX(CLK_MOUT_CPUCL0_DBG, "mout_cpucl0_dbg", mout_cpucl0_dbg_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG, 0, 1),
+	MUX(CLK_MOUT_CPUCL0_SWITCH, "mout_cpucl0_switch", mout_cpucl0_switch_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH, 0, 2),
+
+	/* CPUCL1 */
+	MUX(CLK_MOUT_CPUCL1_DBG, "mout_cpucl1_dbg", mout_cpucl1_dbg_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL1_DBG, 0, 1),
+	MUX(CLK_MOUT_CPUCL1_SWITCH, "mout_cpucl1_switch", mout_cpucl1_switch_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH, 0, 2),
+
 	/* DPU */
 	MUX(CLK_MOUT_DPU, "mout_dpu", mout_dpu_p,
 	    CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 2),
@@ -378,6 +425,18 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
 	DIV(CLK_DOUT_CORE_SSS, "dout_core_sss", "gout_core_sss",
 	    CLK_CON_DIV_CLKCMU_CORE_SSS, 0, 4),
 
+	/* CPUCL0 */
+	DIV(CLK_DOUT_CPUCL0_DBG, "dout_cpucl0_dbg", "gout_cpucl0_dbg",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_DBG, 0, 3),
+	DIV(CLK_DOUT_CPUCL0_SWITCH, "dout_cpucl0_switch", "gout_cpucl0_switch",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH, 0, 3),
+
+	/* CPUCL1 */
+	DIV(CLK_DOUT_CPUCL1_DBG, "dout_cpucl1_dbg", "gout_cpucl1_dbg",
+	    CLK_CON_DIV_CLKCMU_CPUCL1_DBG, 0, 3),
+	DIV(CLK_DOUT_CPUCL1_SWITCH, "dout_cpucl1_switch", "gout_cpucl1_switch",
+	    CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH, 0, 3),
+
 	/* DPU */
 	DIV(CLK_DOUT_DPU, "dout_dpu", "gout_dpu",
 	    CLK_CON_DIV_CLKCMU_DPU, 0, 4),
@@ -442,6 +501,18 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
 	GATE(CLK_GOUT_AUD, "gout_aud", "mout_aud",
 	     CLK_CON_GAT_GATE_CLKCMU_AUD, 21, 0, 0),
 
+	/* CPUCL0 */
+	GATE(CLK_GOUT_CPUCL0_DBG, "gout_cpucl0_dbg", "mout_cpucl0_dbg",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG, 21, 0, 0),
+	GATE(CLK_GOUT_CPUCL0_SWITCH, "gout_cpucl0_switch", "mout_cpucl0_switch",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH, 21, 0, 0),
+
+	/* CPUCL1 */
+	GATE(CLK_GOUT_CPUCL1_DBG, "gout_cpucl1_dbg", "mout_cpucl1_dbg",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL1_DBG, 21, 0, 0),
+	GATE(CLK_GOUT_CPUCL1_SWITCH, "gout_cpucl1_switch", "mout_cpucl1_switch",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH, 21, 0, 0),
+
 	/* DPU */
 	GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu",
 	     CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
@@ -1030,6 +1101,373 @@ static const struct samsung_cmu_info cmgp_cmu_info __initconst = {
 	.clk_name		= "gout_clkcmu_cmgp_bus",
 };
 
+/* ---- CMU_CPUCL0 ---------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_CPUCL0 (0x10900000) */
+#define PLL_LOCKTIME_PLL_CPUCL0				0x0000
+#define PLL_CON0_PLL_CPUCL0				0x0100
+#define PLL_CON1_PLL_CPUCL0				0x0104
+#define PLL_CON3_PLL_CPUCL0				0x010c
+#define PLL_CON0_MUX_CLKCMU_CPUCL0_DBG_USER		0x0600
+#define PLL_CON0_MUX_CLKCMU_CPUCL0_SWITCH_USER		0x0610
+#define CLK_CON_MUX_MUX_CLK_CPUCL0_PLL			0x100c
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_ACLK		0x1800
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_ATCLK		0x1808
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_PCLKDBG		0x180c
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_PERIPHCLK		0x1810
+#define CLK_CON_DIV_DIV_CLK_CPUCL0_CMUREF		0x1814
+#define CLK_CON_DIV_DIV_CLK_CPUCL0_CPU			0x1818
+#define CLK_CON_DIV_DIV_CLK_CPUCL0_PCLK			0x181c
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_ATCLK		0x2000
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PCLK		0x2004
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PERIPHCLK	0x2008
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_SCLK		0x200c
+#define CLK_CON_GAT_CLK_CPUCL0_CMU_CPUCL0_PCLK		0x2010
+#define CLK_CON_GAT_GATE_CLK_CPUCL0_CPU			0x2020
+
+static const unsigned long cpucl0_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CPUCL0,
+	PLL_CON0_PLL_CPUCL0,
+	PLL_CON1_PLL_CPUCL0,
+	PLL_CON3_PLL_CPUCL0,
+	PLL_CON0_MUX_CLKCMU_CPUCL0_DBG_USER,
+	PLL_CON0_MUX_CLKCMU_CPUCL0_SWITCH_USER,
+	CLK_CON_MUX_MUX_CLK_CPUCL0_PLL,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_ACLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_ATCLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_PCLKDBG,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_PERIPHCLK,
+	CLK_CON_DIV_DIV_CLK_CPUCL0_CMUREF,
+	CLK_CON_DIV_DIV_CLK_CPUCL0_CPU,
+	CLK_CON_DIV_DIV_CLK_CPUCL0_PCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_ATCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PERIPHCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_SCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CMU_CPUCL0_PCLK,
+	CLK_CON_GAT_GATE_CLK_CPUCL0_CPU,
+};
+
+/* List of parent clocks for Muxes in CMU_CPUCL0 */
+PNAME(mout_pll_cpucl0_p)		 = { "oscclk", "fout_cpucl0_pll" };
+PNAME(mout_cpucl0_switch_user_p)	 = { "oscclk", "dout_cpucl0_switch" };
+PNAME(mout_cpucl0_dbg_user_p)		 = { "oscclk", "dout_cpucl0_dbg" };
+PNAME(mout_cpucl0_pll_p)		 = { "mout_pll_cpucl0",
+					     "mout_cpucl0_switch_user" };
+
+static const struct samsung_pll_rate_table cpu_pll_rates[] __initconst = {
+	PLL_35XX_RATE(26 * MHZ, 2210000000U, 255, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 2106000000U, 243, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 2002000000U, 231, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1846000000U, 213, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1742000000U, 201, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1586000000U, 183, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1456000000U, 168, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1300000000U, 150, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1157000000U, 267, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 1053000000U, 243, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 949000000U,  219, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 806000000U,  186, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 650000000U,  150, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 546000000U,  252, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 442000000U,  204, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 351000000U,  162, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 247000000U,  114, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 182000000U,  168, 3, 3),
+	PLL_35XX_RATE(26 * MHZ, 130000000U,  120, 3, 3),
+};
+
+static const struct samsung_pll_clock cpucl0_pll_clks[] __initconst = {
+	PLL(pll_0822x, CLK_FOUT_CPUCL0_PLL, "fout_cpucl0_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_CPUCL0, PLL_CON3_PLL_CPUCL0, cpu_pll_rates),
+};
+
+static const struct samsung_mux_clock cpucl0_mux_clks[] __initconst = {
+	MUX_F(CLK_MOUT_PLL_CPUCL0, "mout_pll_cpucl0", mout_pll_cpucl0_p,
+	      PLL_CON0_PLL_CPUCL0, 4, 1,
+	      CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0),
+	MUX_F(CLK_MOUT_CPUCL0_SWITCH_USER, "mout_cpucl0_switch_user",
+	      mout_cpucl0_switch_user_p,
+	      PLL_CON0_MUX_CLKCMU_CPUCL0_SWITCH_USER, 4, 1,
+	      CLK_SET_RATE_PARENT, 0),
+	MUX(CLK_MOUT_CPUCL0_DBG_USER, "mout_cpucl0_dbg_user",
+	    mout_cpucl0_dbg_user_p,
+	    PLL_CON0_MUX_CLKCMU_CPUCL0_DBG_USER, 4, 1),
+	MUX_F(CLK_MOUT_CPUCL0_PLL, "mout_cpucl0_pll", mout_cpucl0_pll_p,
+	      CLK_CON_MUX_MUX_CLK_CPUCL0_PLL, 0, 1, CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_div_clock cpucl0_div_clks[] __initconst = {
+	DIV_F(CLK_DOUT_CPUCL0_CPU, "dout_cpucl0_cpu", "mout_cpucl0_pll",
+	      CLK_CON_DIV_DIV_CLK_CPUCL0_CPU, 0, 1,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL0_CMUREF, "dout_cpucl0_cmuref", "dout_cpucl0_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL0_CMUREF, 0, 3,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL0_PCLK, "dout_cpucl0_pclk", "dout_cpucl0_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL0_PCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+
+	/* EMBEDDED_CMU_CPUCL0 */
+	DIV_F(CLK_DOUT_CLUSTER0_ACLK, "dout_cluster0_aclk", "gout_cluster0_cpu",
+	      CLK_CON_DIV_DIV_CLK_CLUSTER0_ACLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER0_ATCLK, "dout_cluster0_atclk",
+	      "gout_cluster0_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER0_ATCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER0_PCLKDBG, "dout_cluster0_pclkdbg",
+	      "gout_cluster0_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER0_PCLKDBG, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER0_PERIPHCLK, "dout_cluster0_periphclk",
+	      "gout_cluster0_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER0_PERIPHCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+};
+
+static const struct samsung_gate_clock cpucl0_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_CPUCL0_CMU_CPUCL0_PCLK, "gout_cpucl0_cmu_cpucl0_pclk",
+	     "dout_cpucl0_pclk",
+	     CLK_CON_GAT_CLK_CPUCL0_CMU_CPUCL0_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+
+	/* EMBEDDED_CMU_CPUCL0 */
+	GATE(CLK_GOUT_CLUSTER0_CPU, "gout_cluster0_cpu", "dout_cpucl0_cpu",
+	     CLK_CON_GAT_GATE_CLK_CPUCL0_CPU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_SCLK, "gout_cluster0_sclk", "gout_cluster0_cpu",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_SCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_ATCLK, "gout_cluster0_atclk",
+	     "dout_cluster0_atclk",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_ATCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_PERIPHCLK, "gout_cluster0_periphclk",
+	     "dout_cluster0_periphclk",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PERIPHCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_PCLK, "gout_cluster0_pclk",
+	     "dout_cluster0_pclkdbg",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+/*
+ * Each parameter is going to be written into the corresponding DIV register. So
+ * the actual divider value for each parameter will be 1/(param+1). All these
+ * parameters must be in the range of 0..15, as the divider range for all of
+ * these DIV clocks is 1..16. The default values for these dividers is
+ * (1, 3, 3, 1).
+ */
+#define E850_CPU_DIV0(aclk, atclk, pclkdbg, periphclk) \
+	(((aclk) << 16) | ((atclk) << 12) | ((pclkdbg) << 8) | \
+	 ((periphclk) << 4))
+
+static const struct exynos_cpuclk_cfg_data exynos850_cluster_clk_d[] __initconst
+= {
+	{ 2210000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 2106000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 2002000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1846000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1742000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1586000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1456000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1300000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1157000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1053000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 949000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 806000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 650000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 546000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 442000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 351000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 247000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 182000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 130000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 0 }
+};
+
+static const struct samsung_cpu_clock cpucl0_cpu_clks[] __initconst = {
+	CPU_CLK(CLK_CLUSTER0_SCLK, "cluster0_clk", CLK_MOUT_PLL_CPUCL0,
+		CLK_MOUT_CPUCL0_SWITCH_USER, 0, 0x0, CPUCLK_LAYOUT_E850_CL0,
+		exynos850_cluster_clk_d),
+};
+
+static const struct samsung_cmu_info cpucl0_cmu_info __initconst = {
+	.pll_clks		= cpucl0_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cpucl0_pll_clks),
+	.mux_clks		= cpucl0_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cpucl0_mux_clks),
+	.div_clks		= cpucl0_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cpucl0_div_clks),
+	.gate_clks		= cpucl0_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cpucl0_gate_clks),
+	.cpu_clks		= cpucl0_cpu_clks,
+	.nr_cpu_clks		= ARRAY_SIZE(cpucl0_cpu_clks),
+	.nr_clk_ids		= CLKS_NR_CPUCL0,
+	.clk_regs		= cpucl0_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cpucl0_clk_regs),
+	.clk_name		= "dout_cpucl0_switch",
+	.manual_plls		= true,
+};
+
+static void __init exynos850_cmu_cpucl0_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &cpucl0_cmu_info);
+}
+
+/* Register CMU_CPUCL0 early, as CPU clocks should be available ASAP */
+CLK_OF_DECLARE(exynos850_cmu_cpucl0, "samsung,exynos850-cmu-cpucl0",
+	       exynos850_cmu_cpucl0_init);
+
+/* ---- CMU_CPUCL1 ---------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_CPUCL1 (0x10800000) */
+#define PLL_LOCKTIME_PLL_CPUCL1				0x0000
+#define PLL_CON0_PLL_CPUCL1				0x0100
+#define PLL_CON1_PLL_CPUCL1				0x0104
+#define PLL_CON3_PLL_CPUCL1				0x010c
+#define PLL_CON0_MUX_CLKCMU_CPUCL1_DBG_USER		0x0600
+#define PLL_CON0_MUX_CLKCMU_CPUCL1_SWITCH_USER		0x0610
+#define CLK_CON_MUX_MUX_CLK_CPUCL1_PLL			0x1000
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_ACLK		0x1800
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_ATCLK		0x1808
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_PCLKDBG		0x180c
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_PERIPHCLK		0x1810
+#define CLK_CON_DIV_DIV_CLK_CPUCL1_CMUREF		0x1814
+#define CLK_CON_DIV_DIV_CLK_CPUCL1_CPU			0x1818
+#define CLK_CON_DIV_DIV_CLK_CPUCL1_PCLK			0x181c
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_ATCLK		0x2000
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PCLK		0x2004
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PERIPHCLK	0x2008
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_SCLK		0x200c
+#define CLK_CON_GAT_CLK_CPUCL1_CMU_CPUCL1_PCLK		0x2010
+#define CLK_CON_GAT_GATE_CLK_CPUCL1_CPU			0x2020
+
+static const unsigned long cpucl1_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CPUCL1,
+	PLL_CON0_PLL_CPUCL1,
+	PLL_CON1_PLL_CPUCL1,
+	PLL_CON3_PLL_CPUCL1,
+	PLL_CON0_MUX_CLKCMU_CPUCL1_DBG_USER,
+	PLL_CON0_MUX_CLKCMU_CPUCL1_SWITCH_USER,
+	CLK_CON_MUX_MUX_CLK_CPUCL1_PLL,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_ACLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_ATCLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_PCLKDBG,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_PERIPHCLK,
+	CLK_CON_DIV_DIV_CLK_CPUCL1_CMUREF,
+	CLK_CON_DIV_DIV_CLK_CPUCL1_CPU,
+	CLK_CON_DIV_DIV_CLK_CPUCL1_PCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_ATCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PERIPHCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_SCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CMU_CPUCL1_PCLK,
+	CLK_CON_GAT_GATE_CLK_CPUCL1_CPU,
+};
+
+/* List of parent clocks for Muxes in CMU_CPUCL0 */
+PNAME(mout_pll_cpucl1_p)		 = { "oscclk", "fout_cpucl1_pll" };
+PNAME(mout_cpucl1_switch_user_p)	 = { "oscclk", "dout_cpucl1_switch" };
+PNAME(mout_cpucl1_dbg_user_p)		 = { "oscclk", "dout_cpucl1_dbg" };
+PNAME(mout_cpucl1_pll_p)		 = { "mout_pll_cpucl1",
+					     "mout_cpucl1_switch_user" };
+
+static const struct samsung_pll_clock cpucl1_pll_clks[] __initconst = {
+	PLL(pll_0822x, CLK_FOUT_CPUCL1_PLL, "fout_cpucl1_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_CPUCL1, PLL_CON3_PLL_CPUCL1, cpu_pll_rates),
+};
+
+static const struct samsung_mux_clock cpucl1_mux_clks[] __initconst = {
+	MUX_F(CLK_MOUT_PLL_CPUCL1, "mout_pll_cpucl1", mout_pll_cpucl1_p,
+	      PLL_CON0_PLL_CPUCL1, 4, 1,
+	      CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0),
+	MUX_F(CLK_MOUT_CPUCL1_SWITCH_USER, "mout_cpucl1_switch_user",
+	      mout_cpucl1_switch_user_p,
+	      PLL_CON0_MUX_CLKCMU_CPUCL1_SWITCH_USER, 4, 1,
+	      CLK_SET_RATE_PARENT, 0),
+	MUX(CLK_MOUT_CPUCL1_DBG_USER, "mout_cpucl1_dbg_user",
+	    mout_cpucl1_dbg_user_p,
+	    PLL_CON0_MUX_CLKCMU_CPUCL1_DBG_USER, 4, 1),
+	MUX_F(CLK_MOUT_CPUCL1_PLL, "mout_cpucl1_pll", mout_cpucl1_pll_p,
+	      CLK_CON_MUX_MUX_CLK_CPUCL1_PLL, 0, 1, CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_div_clock cpucl1_div_clks[] __initconst = {
+	DIV_F(CLK_DOUT_CPUCL1_CPU, "dout_cpucl1_cpu", "mout_cpucl1_pll",
+	      CLK_CON_DIV_DIV_CLK_CPUCL1_CPU, 0, 1,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL1_CMUREF, "dout_cpucl1_cmuref", "dout_cpucl1_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL1_CMUREF, 0, 3,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL1_PCLK, "dout_cpucl1_pclk", "dout_cpucl1_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL1_PCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+
+	/* EMBEDDED_CMU_CPUCL1 */
+	DIV_F(CLK_DOUT_CLUSTER1_ACLK, "dout_cluster1_aclk", "gout_cluster1_cpu",
+	      CLK_CON_DIV_DIV_CLK_CLUSTER1_ACLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER1_ATCLK, "dout_cluster1_atclk",
+	      "gout_cluster1_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER1_ATCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER1_PCLKDBG, "dout_cluster1_pclkdbg",
+	      "gout_cluster1_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER1_PCLKDBG, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER1_PERIPHCLK, "dout_cluster1_periphclk",
+	      "gout_cluster1_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER1_PERIPHCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+};
+
+static const struct samsung_gate_clock cpucl1_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_CPUCL1_CMU_CPUCL1_PCLK, "gout_cpucl1_cmu_cpucl1_pclk",
+	     "dout_cpucl1_pclk",
+	     CLK_CON_GAT_CLK_CPUCL1_CMU_CPUCL1_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+
+	/* EMBEDDED_CMU_CPUCL1 */
+	GATE(CLK_GOUT_CLUSTER1_CPU, "gout_cluster1_cpu", "dout_cpucl1_cpu",
+	     CLK_CON_GAT_GATE_CLK_CPUCL1_CPU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_SCLK, "gout_cluster1_sclk", "gout_cluster1_cpu",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_SCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_ATCLK, "gout_cluster1_atclk",
+	     "dout_cluster1_atclk",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_ATCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_PERIPHCLK, "gout_cluster1_periphclk",
+	     "dout_cluster1_periphclk",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PERIPHCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_PCLK, "gout_cluster1_pclk",
+	     "dout_cluster1_pclkdbg",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cpu_clock cpucl1_cpu_clks[] __initconst = {
+	CPU_CLK(CLK_CLUSTER1_SCLK, "cluster1_clk", CLK_MOUT_PLL_CPUCL1,
+		CLK_MOUT_CPUCL1_SWITCH_USER, 0, 0x0, CPUCLK_LAYOUT_E850_CL1,
+		exynos850_cluster_clk_d),
+};
+
+static const struct samsung_cmu_info cpucl1_cmu_info __initconst = {
+	.pll_clks		= cpucl1_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cpucl1_pll_clks),
+	.mux_clks		= cpucl1_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cpucl1_mux_clks),
+	.div_clks		= cpucl1_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cpucl1_div_clks),
+	.gate_clks		= cpucl1_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cpucl1_gate_clks),
+	.cpu_clks		= cpucl1_cpu_clks,
+	.nr_cpu_clks		= ARRAY_SIZE(cpucl1_cpu_clks),
+	.nr_clk_ids		= CLKS_NR_CPUCL1,
+	.clk_regs		= cpucl1_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cpucl1_clk_regs),
+	.clk_name		= "dout_cpucl1_switch",
+	.manual_plls		= true,
+};
+
+static void __init exynos850_cmu_cpucl1_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &cpucl1_cmu_info);
+}
+
+/* Register CMU_CPUCL1 early, as CPU clocks should be available ASAP */
+CLK_OF_DECLARE(exynos850_cmu_cpucl1, "samsung,exynos850-cmu-cpucl1",
+	       exynos850_cmu_cpucl1_init);
+
 /* ---- CMU_G3D ------------------------------------------------------------- */
 
 /* Register Offset definitions for CMU_G3D (0x11400000) */
-- 
2.39.2



From semen.protsenko at linaro.org  Wed Feb 21 19:02:35 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 21 Feb 2024 21:02:35 -0600
Subject: [PATCH v2 15/15] arm64: dts: exynos: Add CPU clocks for Exynos850
In-Reply-To: <20240222030235.27815-1-semen.protsenko@linaro.org>
References: <20240222030235.27815-1-semen.protsenko@linaro.org>
Message-ID: <20240222030235.27815-16-semen.protsenko@linaro.org>

Define CPU cluster 0 and CPU cluster 1 CMUs, which generate CPU clocks,
and add corresponding CPU clocks to CPU nodes.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - Add "for Exynos850" part to the commit title

 arch/arm64/boot/dts/exynos/exynos850.dtsi | 26 +++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
index 2ba67c3d0681..0706c8534ceb 100644
--- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -93,6 +93,8 @@ cpu0: cpu at 0 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0>;
 			enable-method = "psci";
+			clocks = <&cmu_cpucl0 CLK_CLUSTER0_SCLK>;
+			clock-names = "cluster0_clk";
 		};
 		cpu1: cpu at 1 {
 			device_type = "cpu";
@@ -117,6 +119,8 @@ cpu4: cpu at 100 {
 			compatible = "arm,cortex-a55";
 			reg = <0x100>;
 			enable-method = "psci";
+			clocks = <&cmu_cpucl1 CLK_CLUSTER1_SCLK>;
+			clock-names = "cluster1_clk";
 		};
 		cpu5: cpu at 101 {
 			device_type = "cpu";
@@ -254,6 +258,28 @@ cmu_peri: clock-controller at 10030000 {
 				      "dout_peri_uart", "dout_peri_ip";
 		};
 
+		cmu_cpucl1: clock-controller at 10800000 {
+			compatible = "samsung,exynos850-cmu-cpucl1";
+			reg = <0x10800000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_CPUCL1_SWITCH>,
+				 <&cmu_top CLK_DOUT_CPUCL1_DBG>;
+			clock-names = "oscclk", "dout_cpucl1_switch",
+				      "dout_cpucl1_dbg";
+		};
+
+		cmu_cpucl0: clock-controller at 10900000 {
+			compatible = "samsung,exynos850-cmu-cpucl0";
+			reg = <0x10900000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_CPUCL0_SWITCH>,
+				 <&cmu_top CLK_DOUT_CPUCL0_DBG>;
+			clock-names = "oscclk", "dout_cpucl0_switch",
+				      "dout_cpucl0_dbg";
+		};
+
 		cmu_g3d: clock-controller at 11400000 {
 			compatible = "samsung,exynos850-cmu-g3d";
 			reg = <0x11400000 0x8000>;
-- 
2.39.2



From ck.hu at mediatek.com  Wed Feb 21 19:11:26 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 22 Feb 2024 03:11:26 +0000
Subject: [PATCH 6/9] media: platform: mtk-mdp3: drop calling
 cmdq_pkt_finalize()
In-Reply-To: <b3c384b6-7c8f-4428-a62e-1036b78217cf@collabora.com>
References: <20240215004931.3808-1-chunkuang.hu@kernel.org>
	 <20240215004931.3808-7-chunkuang.hu@kernel.org>
	 <4dcfaf49-aaac-4980-a149-02fec3109f31@collabora.com>
	 <af4bfdd52f0ca022730aedcb456bb1a0b105ae3e.camel@mediatek.com>
	 <b3c384b6-7c8f-4428-a62e-1036b78217cf@collabora.com>
Message-ID: <143420847d70fd03763863c1a0a60751591d5240.camel@mediatek.com>

Hi, Moudy:

On Fri, 2024-02-16 at 08:56 +0100, AngeloGioacchino Del Regno wrote:
> Il 16/02/24 07:20, Moudy Ho (???) ha scritto:
> > On Thu, 2024-02-15 at 11:29 +0100, AngeloGioacchino Del Regno
> > wrote:
> > > Il 15/02/24 01:49, Chun-Kuang Hu ha scritto:
> > > > Because client driver has the information of struct
> > > > cmdq_client, so
> > > > it's not necessary to store struct cmdq_client in struct
> > > > cmdq_pkt.
> > > > cmdq_pkt_finalize() use struct cmdq_client in struct cmdq_pkt,
> > > > so
> > > > it's
> > > > going to be abandoned. Therefore, use cmdq_pkt_eoc() and
> > > > cmdq_pkt_nop()
> > > > to replace cmdq_pkt_finalize().
> > > 
> > > No, it's not because cmdq_pkt_finalize() has cmdq_client, but
> > > because
> > > we want
> > > finer grain control over the CMDQ packets, as not all cases
> > > require
> > > the NOP
> > > packet to be appended after EOC.
> > > 
> > > Besides, honestly I'm not even sure if the NOP is always required
> > > in
> > > MDP3, so...
> > > 
> > > ...Moudy, you know the MDP3 way better than anyone else - can you
> > > please
> > > check if NOP is actually needed here?
> > > 
> > > Thanks!
> > > Angelo
> > > 
> > 
> > Hi Angelo,
> > 
> > After confirming with the hardware designer and performing the
> > video
> > playback test, it was discovered that MDP3 is capable of excluding
> > the
> > NOP(jump) instruction.
> > 
> 
> Thank you for this extremely fast clarification.

As discuss with Jason, there is one precondition that mdp3 could drop
nop. mpd3 still need to append jump command in the end of packet. The
precondition is that if the jump command is append by mailbox
controller, then client driver is not necessary to append nop. But
currently, mailbox controller just modify nop to jump, not append jump.
Because this modification is not related to this series of removing
pkt->cl, so I would keep append nop in the end of packet for mdp3
driver.

Regards,
CK

> 
> Cheers,
> Angelo
> 
> > Sincerely,
> > Moudy
> > > > 
> > > > Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> > > > ---
> > > >    drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 3 ++-
> > > >    drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c | 2 ++
> > > >    drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h | 1 +
> > > >    3 files changed, 5 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-
> > > > cmdq.c
> > > > b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
> > > > index 6adac857a477..a420d492d879 100644
> > > > --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
> > > > +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
> > > > @@ -471,7 +471,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp,
> > > > struct
> > > > mdp_cmdq_param *param)
> > > >    		dev_err(dev, "mdp_path_config error\n");
> > > >    		goto err_free_path;
> > > >    	}
> > > > -	cmdq_pkt_finalize(&cmd->pkt);
> > > > +	cmdq_pkt_eoc(&cmd->pkt);
> > > > +	cmdq_pkt_nop(&cmd->pkt, mdp->cmdq_shift_pa);
> > > >    
> > > >    	for (i = 0; i < num_comp; i++)
> > > >    		memcpy(&comps[i], path->comps[i].comp,
> > > > diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-
> > > > core.c
> > > > b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
> > > > index 94f4ed78523b..2214744c937c 100644
> > > > --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
> > > > +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
> > > > @@ -231,6 +231,8 @@ static int mdp_probe(struct platform_device
> > > > *pdev)
> > > >    		goto err_put_scp;
> > > >    	}
> > > >    
> > > > +	mdp->cmdq_shift_pa = cmdq_get_shift_pa(mdp->cmdq_clt-
> > > > >chan);
> > > > +
> > > >    	init_waitqueue_head(&mdp->callback_wq);
> > > >    	ida_init(&mdp->mdp_ida);
> > > >    	platform_set_drvdata(pdev, mdp);
> > > > diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-
> > > > core.h
> > > > b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
> > > > index 7e21d226ceb8..ed61e0bb69ee 100644
> > > > --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
> > > > +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
> > > > @@ -83,6 +83,7 @@ struct mdp_dev {
> > > >    	u32					id_count;
> > > >    	struct ida				mdp_ida;
> > > >    	struct cmdq_client			*cmdq_clt;
> > > > +	u8					cmdq_shift_pa;
> > > >    	wait_queue_head_t			callback_wq;
> > > >    
> > > >    	struct v4l2_device			v4l2_dev;
> > > 
> > > 
> 
> 
> 
> 

From peterlin at andestech.com  Wed Feb 21 19:23:00 2024
From: peterlin at andestech.com (Yu-Chien Peter Lin)
Date: Thu, 22 Feb 2024 11:23:00 +0800
Subject: [PATCH v8 00/10] Support Andes PMU extension
In-Reply-To: <mhng-b85cfae6-43ef-42ac-94b4-d0f4ce2d0940@palmer-ri-x1c9a>
References: <20240129092553.2058043-1-peterlin@andestech.com>
 <mhng-b85cfae6-43ef-42ac-94b4-d0f4ce2d0940@palmer-ri-x1c9a>
Message-ID: <Zda-FE2FpyhbIJKd@APC323>

Hi Palmer,

On Wed, Feb 21, 2024 at 12:58:31PM -0800, Palmer Dabbelt wrote:
> On Mon, 29 Jan 2024 01:25:43 PST (-0800), peterlin at andestech.com wrote:
> > Hi All,
> > 
> > This patch series introduces the Andes PMU extension, which serves the
> > same purpose as Sscofpmf and Smcntrpmf. Its non-standard local interrupt
> > is assigned to bit 18 in the custom S-mode local interrupt enable and
> > pending registers (slie/slip), while the interrupt cause is (256 + 18).
> > 
> > Linux patches based on:
> > - ed5b7cf ("riscv: errata: andes: Probe for IOCP only once in boot stage")
> > It can be found on Andes Technology GitHub:
> > - https://github.com/andestech/linux/commits/andes-pmu-support-v8
> > 
> > The PMU device tree node used on AX45MP:
> > - https://github.com/riscv-software-src/opensbi/blob/master/docs/pmu_support.md#example-3
> > 
> > Locus Wei-Han Chen (1):
> >   riscv: andes: Support specifying symbolic firmware and hardware raw
> >     events
> > 
> > Yu Chien Peter Lin (9):
> >   riscv: errata: Rename defines for Andes
> >   irqchip/riscv-intc: Allow large non-standard interrupt number
> >   irqchip/riscv-intc: Introduce Andes hart-level interrupt controller
> >   dt-bindings: riscv: Add Andes interrupt controller compatible string
> >   riscv: dts: renesas: r9a07g043f: Update compatible string to use Andes
> >     INTC
> >   perf: RISC-V: Eliminate redundant interrupt enable/disable operations
> >   perf: RISC-V: Introduce Andes PMU to support perf event sampling
> >   dt-bindings: riscv: Add Andes PMU extension description
> >   riscv: dts: renesas: Add Andes PMU extension for r9a07g043f
> > 
> >  .../devicetree/bindings/riscv/cpus.yaml       |   6 +-
> >  .../devicetree/bindings/riscv/extensions.yaml |   7 +
> >  arch/riscv/boot/dts/renesas/r9a07g043f.dtsi   |   4 +-
> >  arch/riscv/errata/andes/errata.c              |  10 +-
> >  arch/riscv/include/asm/errata_list.h          |  13 +-
> >  arch/riscv/include/asm/hwcap.h                |   1 +
> >  arch/riscv/include/asm/vendorid_list.h        |   2 +-
> >  arch/riscv/kernel/alternative.c               |   2 +-
> >  arch/riscv/kernel/cpufeature.c                |   1 +
> >  drivers/irqchip/irq-riscv-intc.c              |  88 ++++++++++--
> >  drivers/perf/Kconfig                          |  14 ++
> >  drivers/perf/riscv_pmu_sbi.c                  |  37 ++++-
> >  include/linux/soc/andes/irq.h                 |  18 +++
> >  .../arch/riscv/andes/ax45/firmware.json       |  68 ++++++++++
> >  .../arch/riscv/andes/ax45/instructions.json   | 127 ++++++++++++++++++
> >  .../arch/riscv/andes/ax45/memory.json         |  57 ++++++++
> >  .../arch/riscv/andes/ax45/microarch.json      |  77 +++++++++++
> >  tools/perf/pmu-events/arch/riscv/mapfile.csv  |   1 +
> >  18 files changed, 494 insertions(+), 39 deletions(-)
> >  create mode 100644 include/linux/soc/andes/irq.h
> >  create mode 100644 tools/perf/pmu-events/arch/riscv/andes/ax45/firmware.json
> >  create mode 100644 tools/perf/pmu-events/arch/riscv/andes/ax45/instructions.json
> >  create mode 100644 tools/perf/pmu-events/arch/riscv/andes/ax45/memory.json
> >  create mode 100644 tools/perf/pmu-events/arch/riscv/andes/ax45/microarch.json
> 
> Acked-by: Palmer Dabbelt <palmer at rivosinc.com>
> 
> in case someone wants to take this via another tree.  I'm also OK taking it
> via the RISC-V tree, pending a resolution to Thomas' comments on patch 2.
> For now I'm going to assume there's a v9 coming.

Yes, I'm working on v9, please hold off taking the series, thanks.

Regards,
Peter Lin

> Thanks!


From ppighouse at gmail.com  Wed Feb 21 19:25:03 2024
From: ppighouse at gmail.com (Kelly Hung)
Date: Thu, 22 Feb 2024 11:25:03 +0800
Subject: [PATCH] ARM: dts: aspeed: x4tf: Add dts for asus x4tf project
Message-ID: <20240222032504.1147489-1-Kelly_Hung@asus.com>

Base on aspeed-g6.dtsi and can boot into BMC console.

Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
---
 arch/arm/boot/dts/aspeed/Makefile             |   3 +-
 .../boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts  | 651 ++++++++++++++++++
 2 files changed, 653 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts

diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
index d3ac20e316d0..f7cc69b636fc 100644
--- a/arch/arm/boot/dts/aspeed/Makefile
+++ b/arch/arm/boot/dts/aspeed/Makefile
@@ -62,4 +62,5 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-bmc-ufispace-ncplite.dtb \
 	aspeed-bmc-vegman-n110.dtb \
 	aspeed-bmc-vegman-rx20.dtb \
-	aspeed-bmc-vegman-sx20.dtb
+	aspeed-bmc-vegman-sx20.dtb \
+	aspeed-bmc-asus-x4tf.dtb
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
new file mode 100644
index 000000000000..fbe39eaec154
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
@@ -0,0 +1,651 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright 2024 ASUS Corp.
+
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include "aspeed-g6-pinctrl.dtsi"
+#include <dt-bindings/i2c/i2c.h>
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+	model = "ASUS-X4TF";
+	compatible = "asus,x4tf", "aspeed,ast2600";
+
+	aliases {
+		serial4 = &uart5;
+	};
+
+	chosen {
+		stdout-path = "serial4:115200n8";
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		video_engine_memory: video {
+			size = <0x04000000>;
+			alignment = <0x01000000>;
+			compatible = "shared-dma-pool";
+			reusable;
+		};
+	};
+
+	iio-hwmon {
+		compatible = "iio-hwmon";
+		io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+				<&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+				<&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>,
+				<&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-heartbeat {
+			gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		led-uid {
+			gpios = <&gpio0 ASPEED_GPIO(P, 1) (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+			default-state = "off";
+		};
+
+		led-status_Y {
+			gpios = <&gpio1 ASPEED_GPIO(B, 1) GPIO_ACTIVE_LOW>;
+			default-state = "off";
+		};
+
+		led-sys_boot_status {
+			gpios = <&gpio1 ASPEED_GPIO(B, 0) GPIO_ACTIVE_LOW>;
+			default-state = "off";
+		};
+	};
+};
+
+&adc0 {
+	vref = <2500>;
+	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>;
+};
+
+&adc1 {
+	vref = <2500>;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc9_default
+		&pinctrl_adc10_default &pinctrl_adc11_default
+		&pinctrl_adc12_default &pinctrl_adc13_default
+		&pinctrl_adc14_default &pinctrl_adc15_default>;
+};
+
+&peci0 {
+	status = "okay";
+};
+
+&lpc_snoop {
+	snoop-ports = <0x80>;
+	status = "okay";
+};
+
+&mdio2 {
+	status = "okay";
+
+	ethphy2: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0>;
+	};
+};
+
+&mdio3 {
+	status = "okay";
+
+	ethphy3: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0>;
+	};
+};
+
+&mac2 {
+	status = "okay";
+	phy-mode = "rmii";
+	use-ncsi;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rmii3_default>;
+};
+
+&mac3 {
+	status = "okay";
+	phy-mode = "rmii";
+	use-ncsi;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rmii4_default>;
+};
+
+&fmc {
+	status = "okay";
+
+	flash at 0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "bmc-spi";
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			bmc at 0 {
+				label = "bmc";
+				reg = <0x0 0x4000000>;
+			};
+
+			u-boot at 0 {
+				label = "u-boot";
+				reg = <0x0 0x200000>;
+			};
+
+			u-boot-env at 1f0000 {
+				label = "u-boot-env";
+				reg = <0x1f0000 0x10000>;
+			};
+
+			kernel at 200000 {
+				label = "kernel";
+				reg = <0x200000 0xc00000>;
+			};
+
+			rofs at a00000 {
+				label = "rofs";
+				reg = <0xa00000 0x2a00000>;
+			};
+
+			rwfs at 2a00000 {
+				label = "rwfs";
+				reg = <0x2a00000 0x43f0000>;
+			};
+		};
+	};
+};
+
+&spi1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1_default>;
+
+	flash at 0 {
+		status = "okay";
+		label = "bios-spi";
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			biosfullimg at 0 {
+				reg = <0x0 0x2000000>; //32768 *1024 = 32 MB
+				label = "biosfullimg";
+			};
+		};
+	};
+};
+
+&i2c0 {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c3 {
+	status = "okay";
+};
+
+&i2c4 {
+	status = "okay";
+
+	temperature-sensor at 48 {
+		compatible = "ti,tmp75";
+		reg = <0x48>;
+	};
+
+	temperature-sensor at 49 {
+		compatible = "ti,tmp75";
+		reg = <0x49>;
+	};
+
+	pca9555_4_20: gpio at 20 {
+		compatible = "nxp,pca9555";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	pca9555_4_22: gpio at 22 {
+		compatible = "nxp,pca9555";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	pca9555_4_24: gpio at 24 {
+		compatible = "nxp,pca9555";
+		reg = <0x24>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names =
+		/*A0 - A3 0*/	"", "STRAP_BMC_BATTERY_GPIO1", "", "",
+		/*A4 - A7 4*/	"", "", "", "",
+		/*B0 - B7 8*/	"", "", "", "", "", "", "", "";
+	};
+
+	pca9555_4_26: gpio at 26 {
+		compatible = "nxp,pca9555";
+		reg = <0x26>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9546";
+		status = "okay";
+		reg = <0x70>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		channel_1: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		channel_2: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		channel_3: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		channel_4: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+	};
+};
+
+&i2c5 {
+	status = "okay";
+
+	pca9555_5_24: gpio at 24 {
+		compatible = "nxp,pca9555";
+		reg = <0x24>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	i2c-mux at 70  {
+		compatible = "nxp,pca9546";
+		status = "okay";
+		reg = <0x70 >;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		channel_5: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			pca9555_5_5_20: gpio at 20 {
+				compatible = "nxp,pca9555";
+				reg = <0x20>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-line-names =
+					"", "", "", "", "", "", "", "",
+					"", "", "SYS_FAN6", "SYS_FAN5",
+					"SYS_FAN4", "SYS_FAN3",
+					"SYS_FAN2", "SYS_FAN1";
+			};
+
+			pca9555_5_5_21: gpio at 21 {
+				compatible = "nxp,pca9555";
+				reg = <0x21>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+
+			power-monitor at 44 {
+				compatible = "ti,ina219";
+				reg = <0x44>;
+				shunt-resistor = <2>;
+			};
+		};
+
+		channel_6: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		channel_7: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		channel_8: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+	};
+};
+
+&i2c6 {
+	status = "okay";
+
+	pca9555_6_27: gpio at 27 {
+		compatible = "nxp,pca9555";
+		reg = <0x27>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	pca9555_6_20: gpio at 20 {
+		compatible = "nxp,pca9555";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names =
+		/*A0 0*/	"", "", "", "", "", "", "", "",
+		/*B0 8*/	"Drive_NVMe1", "Drive_NVMe2", "", "",
+		/*B4 12*/	"", "", "", "";
+	};
+
+	pca9555_6_21: gpio at 21 {
+		compatible = "nxp,pca9555";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&i2c7 {
+	status = "okay";
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9546";
+		status = "okay";
+		reg = <0x70>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		idle-state = <1>;
+
+		channel_9: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			temperature-sensor at 48 {
+				compatible = "ti,tmp75";
+				reg = <0x48>;
+			};
+
+			temperature-sensor at 49 {
+				compatible = "ti,tmp75";
+				reg = <0x49>;
+			};
+
+			power-monitor at 40 {
+				compatible = "ti,ina219";
+				reg = <0x40>;
+				shunt-resistor = <2>;
+			};
+
+			power-monitor at 41 {
+				compatible = "ti,ina219";
+				reg = <0x41>;
+				shunt-resistor = <5>;
+			};
+		};
+
+		channel_10: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		channel_11: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		channel_12: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+	};
+
+	i2c-mux at 71 {
+		compatible = "nxp,pca9546";
+		status = "okay";
+		reg = <0x71>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		channel_13: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		channel_14: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		channel_15: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		channel_16: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+	};
+};
+
+&i2c8 {
+	status = "okay";
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9546";
+		status = "okay";
+		reg = <0x70>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		channel_17: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		channel_18: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			temperature-sensor at 48 {
+				compatible = "ti,tmp75";
+				reg = <0x48>;
+			};
+
+			power-monitor at 41 {
+				compatible = "ti,ina219";
+				reg = <0x41>;
+				shunt-resistor = <5>;
+			};
+		};
+
+		channel_19: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		channel_20: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+	};
+};
+
+&i2c9 {
+	status = "okay";
+};
+
+&i2c10 {
+	status = "okay";
+};
+
+&i2c11 {
+	status = "okay";
+};
+
+&i2c14 {
+	status = "okay";
+	multi-master;
+
+	eeprom at 50 {
+		compatible = "atmel,24c08";
+		reg = <0x50>;
+	};
+
+	eeprom at 51 {
+		compatible = "atmel,24c08";
+		reg = <0x51>;
+	};
+};
+
+&sgpiom0 {
+	status = "okay";
+	ngpios = <128>;
+};
+
+&video {
+	status = "okay";
+	memory-region = <&video_engine_memory>;
+};
+
+&sdc {
+	status = "okay";
+};
+
+&lpc_snoop {
+	status = "okay";
+	snoop-ports = <0x80>;
+};
+
+&kcs1 {
+	aspeed,lpc-io-reg = <0xca0>;
+	status = "okay";
+};
+
+&kcs2 {
+	aspeed,lpc-io-reg = <0xca8>;
+	status = "okay";
+};
+
+&kcs3 {
+	aspeed,lpc-io-reg = <0xca2>;
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&uart4 {
+	status = "okay";
+	/* GPIOB6 will be used in ASD function, do not set to be TXD4 */
+	pinctrl-0 = <&pinctrl_txd2_default &pinctrl_rxd2_default>;
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&uart_routing {
+	status = "okay";
+};
+
+&vhub {
+	status = "okay";
+};
+
+&gpio0 {
+	gpio-line-names =
+	/*A0 0*/	"", "", "", "", "", "", "", "",
+	/*B0 8*/	"", "", "", "", "", "", "PS_PWROK", "",
+	/*C0 16*/	"", "", "", "", "", "", "", "",
+	/*D0 24*/	"", "", "", "", "", "", "", "",
+	/*E0 32*/	"", "", "", "", "", "", "", "",
+	/*F0 40*/	"", "", "", "", "", "", "", "",
+	/*G0 48*/	"", "", "", "", "", "", "", "",
+	/*H0 56*/	"", "", "", "", "", "", "", "",
+	/*I0 64*/	"", "", "", "", "", "", "", "",
+	/*J0 72*/	"", "", "", "", "", "", "", "",
+	/*K0 80*/	"", "", "", "", "", "", "", "",
+	/*L0 88*/	"", "", "", "", "", "", "", "",
+	/*M0 96*/	"", "", "", "", "", "", "", "",
+	/*N0 104*/	"", "", "", "",
+	/*N4 108*/	"POST_COMPLETE", "ESR1_GPIO_AST_SPISEL", "", "",
+	/*O0 112*/	"", "", "", "", "", "", "", "",
+	/*P0 120*/	"ID_BUTTON", "ID_OUT", "POWER_BUTTON", "POWER_OUT",
+	/*P4 124*/	"RESET_BUTTON", "RESET_OUT", "", "HEARTBEAT",
+	/*Q0 128*/	"", "", "", "", "", "", "", "",
+	/*R0 136*/	"", "", "", "", "", "", "", "",
+	/*S0 144*/	"", "", "", "", "", "", "", "",
+	/*T0 152*/	"", "", "", "", "", "", "", "",
+	/*U0 160*/	"", "", "", "", "", "", "", "",
+	/*V0 168*/	"", "", "", "", "", "", "", "",
+	/*W0 176*/	"", "", "", "", "", "", "", "",
+	/*X0 184*/	"", "", "", "", "", "", "", "",
+	/*Y0 192*/	"", "", "", "", "", "", "", "",
+	/*Z0 200*/	"", "", "", "", "", "", "", "";
+};
-- 
2.25.1



From ppighouse at gmail.com  Wed Feb 21 19:25:04 2024
From: ppighouse at gmail.com (Kelly Hung)
Date: Thu, 22 Feb 2024 11:25:04 +0800
Subject: [PATCH] dt-bindings: arm: aspeed: add ASUS X4TF board
In-Reply-To: <20240222032504.1147489-1-Kelly_Hung@asus.com>
References: <20240222032504.1147489-1-Kelly_Hung@asus.com>
Message-ID: <20240222032504.1147489-2-Kelly_Hung@asus.com>

Document the new compatibles used on ASUS X4TF.

Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
---
 Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 749ee54a3ff8..60a494b7aaaf 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -74,6 +74,7 @@ properties:
               - ampere,mtmitchell-bmc
               - aspeed,ast2600-evb
               - aspeed,ast2600-evb-a1
+              - asus, x4tf
               - facebook,bletchley-bmc
               - facebook,cloudripper-bmc
               - facebook,elbert-bmc
-- 
2.25.1



From Dharma.B at microchip.com  Wed Feb 21 19:41:26 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Thu, 22 Feb 2024 03:41:26 +0000
Subject: [PATCH v2] dt-bindings: interrupt-controller: Convert Atmel AIC
 to json-schema
In-Reply-To: <20240220-carmaker-subprime-112c44f4f2e6@spud>
References: <20240209100122.61335-1-dharma.b@microchip.com>
 <20240212140824.GA107736-robh@kernel.org>
 <003d61c9-b914-4e1c-b3f8-1140ea640039@microchip.com>
 <20240213-estranged-charger-bf0372f367e0@spud>
 <a97650cd-8e06-4df6-9757-826c00a4d7cc@microchip.com>
 <20240220-carmaker-subprime-112c44f4f2e6@spud>
Message-ID: <4ca76047-2142-4b07-b34e-707f8b5c1f3c@microchip.com>

On 21/02/24 1:02 am, Conor Dooley wrote:
> On Mon, Feb 19, 2024 at 03:30:52PM +0000,Dharma.B at microchip.com  wrote:
>> Hi Rob and Conor,
>>
>> On 14/02/24 12:43 am, Conor Dooley wrote:
>>> On Tue, Feb 13, 2024 at 04:23:36AM +0000,Dharma.B at microchip.com   wrote:
>>>> On 12/02/24 7:38 pm, Rob Herring wrote:
>>>>> On Fri, Feb 09, 2024 at 03:31:22PM +0530, Dharma Balasubiramani wrote:
>>>>>> +  atmel,external-irqs:
>>>>>> +    $ref: /schemas/types.yaml#/definitions/uint32-array
>>>>>> +    description: u32 array of external irqs.
>>>>> Constraints on the array size and/or entry values?
>>>> The hardware's support for external IRQs may differ, which is why a u32
>>>> array is utilized. This choice is based on the fact that IRQ numbers are
>>>> commonly expressed as integers, and a 32-bit unsigned integer provides a
>>>> standardized size capable of representing a broad range of numbers. This
>>>> size is more than adequate for accommodating IRQ numbering.
>>> I don't think Rob was questioning your use of u32s, but rather the fact
>>> that you do not limit the values at all nor the number of values.
>> The peripheral identification defined at the product level corresponds
>> to the interrupt source number.
>>
>> SoC           External Interrupts    Peripheral ID
>> AT91RM9200    - IRQ0?IRQ6            25 - 31
>> SAMA5D2       - IRQ0?IRQn            49
>> SAMA5D3       - IRQ0?IRQn            47
>> SAMA5D4       - IRQ0?IRQn            56
>> SAM9x60       - IRQ0?IRQn            31
>>
>> To reflect these constraints in bindings, I intend to make the following
>> changes.
>>
>>     atmel,external-irqs:
>>       $ref: /schemas/types.yaml#/definitions/uint32-array
>>       description: u32 array of external irqs.
>>       if:
>>         properties:
>>           compatible:
>>             contains:
>>               const: atmel,at91rm9200-aic
>>       then:
>>         minItems: 1
>>         maxItems: 7
>>       else:
>>         minItems: 1
>>         maxItems: 1
> Just to point out, that if this is not psuedocode, the syntax here is
> not quite right. It should be:
> 
> allOf:
> - if:
>      properties:
>        compatible:
>          contains:
>            const: atmel,at91rm9200-aic
>    then:
>      properties:
>        atmel,external-irqs:
>          minItems: 1
>          maxItems: 7
>    else:
>      properties:
>        atmel,external-irqs:
>          minItems: 1
>          maxItems: 1
> 
> But you can simply this further by applying minItems: 1 & maxitems: 7
> to the property directly and just setting maxItems: 1 when the
> compatible is not atmel,at91rm9200-aic.
> 
> There should be plenty of examples in-tree for you to copy this sort of
> thing from - clock-names is a property you often see this used for.

Sure, Thanks for pointing it out.

I will address your previous suggestion "reg before
interrupt-controller." as well in v3.

> 
> Cheers,
> Conor.

-- 
With Best Regards,
Dharma B.


From dharma.b at microchip.com  Wed Feb 21 19:51:58 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Thu, 22 Feb 2024 09:21:58 +0530
Subject: [PATCH v3] dt-bindings: interrupt-controller: Convert Atmel AIC to json-schema
Message-ID: <20240222035158.195265-1-dharma.b@microchip.com>

Convert the Atmel AIC binding document to DT schema format using
json-schema.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
Changelog
v2 -> v3
- Add constraints to the "atmel,external-irqs" property.
- Move 'reg' before 'interrupt-controller' in the example.
v1 -> v2
- Drop the '|' as there is no formatting to preserve.
- Remove unnecessary marketing statement from description.
- Drop the description for interrupts and reg, it's obvious.
- Put reg after compatible.
- Drop comment in example.
- Drop the example of device that is wired to an AIC as it's(dma) binding is
  not yet available.
---
 .../interrupt-controller/atmel,aic.txt        | 43 ---------
 .../interrupt-controller/atmel,aic.yaml       | 89 +++++++++++++++++++
 2 files changed, 89 insertions(+), 43 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
deleted file mode 100644
index 7079d44bf3ba..000000000000
--- a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-* Advanced Interrupt Controller (AIC)
-
-Required properties:
-- compatible: Should be:
-    - "atmel,<chip>-aic" where  <chip> can be "at91rm9200", "sama5d2",
-      "sama5d3" or "sama5d4"
-    - "microchip,<chip>-aic" where <chip> can be "sam9x60"
-
-- interrupt-controller: Identifies the node as an interrupt controller.
-- #interrupt-cells: The number of cells to define the interrupts. It should be 3.
-  The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet).
-  The second cell is used to specify flags:
-    bits[3:0] trigger type and level flags:
-      1 = low-to-high edge triggered.
-      2 = high-to-low edge triggered.
-      4 = active high level-sensitive.
-      8 = active low level-sensitive.
-      Valid combinations are 1, 2, 3, 4, 8.
-      Default flag for internal sources should be set to 4 (active high).
-  The third cell is used to specify the irq priority from 0 (lowest) to 7
-  (highest).
-- reg: Should contain AIC registers location and length
-- atmel,external-irqs: u32 array of external irqs.
-
-Examples:
-	/*
-	 * AIC
-	 */
-	aic: interrupt-controller at fffff000 {
-		compatible = "atmel,at91rm9200-aic";
-		interrupt-controller;
-		#interrupt-cells = <3>;
-		reg = <0xfffff000 0x200>;
-	};
-
-	/*
-	 * An interrupt generating device that is wired to an AIC.
-	 */
-	dma: dma-controller at ffffec00 {
-		compatible = "atmel,at91sam9g45-dma";
-		reg = <0xffffec00 0x200>;
-		interrupts = <21 4 5>;
-	};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
new file mode 100644
index 000000000000..0d51bd78bf2b
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/atmel,aic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Advanced Interrupt Controller (AIC)
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Dharma balasubiramani <dharma.b at microchip.com>
+
+description:
+  The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
+  maskable, vectored interrupt controller providing handling of up to one
+  hundred and twenty-eight interrupt sources.
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: atmel,at91rm9200-aic
+    then:
+      properties:
+        atmel,external-irqs:
+          minItems: 1
+          maxItems: 7
+    else:
+      properties:
+        atmel,external-irqs:
+          minItems: 1
+          maxItems: 1
+
+properties:
+  compatible:
+    enum:
+      - atmel,at91rm9200-aic
+      - atmel,sama5d2-aic
+      - atmel,sama5d3-aic
+      - atmel,sama5d4-aic
+      - microchip,sam9x60-aic
+
+  reg:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 3
+    description: |
+      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
+      The 2nd cell specifies flags:
+        bits[3:0] trigger type and level flags:
+          1 = low-to-high edge triggered.
+          2 = high-to-low edge triggered.
+          4 = active high level-sensitive.
+          8 = active low level-sensitive.
+        Valid combinations: 1, 2, 3, 4, 8.
+        Default for internal sources: 4 (active high).
+      The 3rd cell specifies irq priority from 0 (lowest) to 7 (highest).
+
+  interrupts:
+    maxItems: 1
+
+  atmel,external-irqs:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: u32 array of external irqs.
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - "#interrupt-cells"
+  - atmel,external-irqs
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    interrupt-controller at fffff000 {
+      compatible = "atmel,at91rm9200-aic";
+      reg = <0xfffff000 0x200>;
+      interrupt-controller;
+      #interrupt-cells = <3>;
+      atmel,external-irqs = <31>;
+    };
+...

base-commit: 4f5e5092fdbf5cec6bedc19fbe69cce4f5f08372
-- 
2.25.1



From sboyd at kernel.org  Wed Feb 21 20:20:58 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 20:20:58 -0800
Subject: [PATCH] MAINTAINERS: drop Sekhar Nori
In-Reply-To: <20240201133841.qcerpmyo4xwc7zxu@volatile>
References: <20240131093434.55652-1-nsekhar@ti.com> <20240201133841.qcerpmyo4xwc7zxu@volatile>
Message-ID: <c0f42391eee797f1e5e59173b0502017.sboyd@kernel.org>

Quoting Nishanth Menon (2024-02-01 05:38:41)
> On 15:04-20240131, Sekhar Nori wrote:
> > My TI e-mail address will become inactive soon. Drop it.
> > Add an entry to CREDITS file for work done on TI DaVinci
> > family SoCs.
> > 
> > Signed-off-by: Sekhar Nori <nsekhar at ti.com>
> > ---

Applied to clk-next


From anshuman.khandual at arm.com  Wed Feb 21 20:45:51 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 10:15:51 +0530
Subject: [PATCH V4 01/11] coresight: etm4x: Fix unbalanced
 pm_runtime_enable()
In-Reply-To: <68eb9e4e-de77-4854-8212-816c66d5f657@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-2-anshuman.khandual@arm.com>
 <68eb9e4e-de77-4854-8212-816c66d5f657@arm.com>
Message-ID: <8c4165e1-e875-4a61-8935-1ae1e2099477@arm.com>



On 2/15/24 16:34, Suzuki K Poulose wrote:
> On 23/01/2024 05:45, Anshuman Khandual wrote:
>> There is an unbalanced pm_runtime_enable() in etm4_probe_platform_dev()
>> when etm4_probe() fails. This problem can be observed via the coresight
>> etm4 module's (load -> unload -> load) sequence when etm4_probe() fails
>> in etm4_probe_platform_dev().
>>
>> [?? 63.379943] coresight-etm4x 7040000.etm: Unbalanced pm_runtime_enable!
>> [?? 63.393630] coresight-etm4x 7140000.etm: Unbalanced pm_runtime_enable!
>> [?? 63.407455] coresight-etm4x 7240000.etm: Unbalanced pm_runtime_enable!
>> [?? 63.420983] coresight-etm4x 7340000.etm: Unbalanced pm_runtime_enable!
>> [?? 63.420999] coresight-etm4x 7440000.etm: Unbalanced pm_runtime_enable!
>> [?? 63.441209] coresight-etm4x 7540000.etm: Unbalanced pm_runtime_enable!
>> [?? 63.454689] coresight-etm4x 7640000.etm: Unbalanced pm_runtime_enable!
>> [?? 63.474982] coresight-etm4x 7740000.etm: Unbalanced pm_runtime_enable!
>>
>> This fixes the above problem - with an explicit pm_runtime_disable() call
>> when etm4_probe() fails during etm4_probe_platform_dev().
> 
> Fixes: 5214b563588e ("coresight: etm4x: Add support for sysreg only devices"

Sure, will add this 'Fixes' tag here.

> 
>>
>> Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
>> Cc: Hanjun Guo <guohanjun at huawei.com>
>> Cc: Sudeep Holla <sudeep.holla at arm.com>
>> Cc: "Rafael J. Wysocki" <rafael at kernel.org>
>> Cc: Len Brown <lenb at kernel.org>
>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Cc: Mike Leach <mike.leach at linaro.org>
>> Cc: James Clark <james.clark at arm.com>
>> Cc: Leo Yan <leo.yan at linaro.org>
>> Cc: linux-acpi at vger.kernel.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: coresight at lists.linaro.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> Changes in V4:
>>
>> - New patch in the series
>>
>> ? drivers/hwtracing/coresight/coresight-etm4x-core.c | 3 +++
>> ? 1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> index ce1995a2827f..7c693b45ac05 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> @@ -2217,6 +2217,9 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
>> ????? ret = etm4_probe(&pdev->dev);
>> ? ????? pm_runtime_put(&pdev->dev);
>> +??? if (ret)
>> +??????? pm_runtime_disable(&pdev->dev);
>> +
>> ????? return ret;
>> ? }
>> ? 
> 
> Looks good to me. I have glanced through the other platform device driver code in coresight subsystem and they all seem to be safe, except
> for Ultrasoc-smb, which doesn't do any power managment. It may be, because it is only supported on an ACPI system.

Understood.


From sboyd at kernel.org  Wed Feb 21 20:51:44 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 20:51:44 -0800
Subject: [PATCH] clk: mediatek: mt8135: Fix an error handling path in clk_mt8135_apmixed_probe()
In-Reply-To: <6cd6af61e5a91598068227f1f68cfcfde1507453.1704615011.git.christophe.jaillet@wanadoo.fr>
References: <6cd6af61e5a91598068227f1f68cfcfde1507453.1704615011.git.christophe.jaillet@wanadoo.fr>
Message-ID: <17ab00b5cbf2b9aefa7ee99daf305f46.sboyd@kernel.org>

Quoting Christophe JAILLET (2024-01-07 00:12:17)
> If an error occurs after mtk_alloc_clk_data(), mtk_free_clk_data() should
> be called, as already done in the remove function.
> 
> Fixes: 54b7026f011e ("clk: mediatek: mt8135-apmixedsys: Convert to platform_driver and module")
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Feb 21 20:52:04 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 20:52:04 -0800
Subject: [PATCH] clk: mediatek: mt7622-apmixedsys: Fix an error handling path in clk_mt8135_apmixed_probe()
In-Reply-To: <2c553c2a5077757e4f7af0bb895acc43881cf62c.1704616152.git.christophe.jaillet@wanadoo.fr>
References: <2c553c2a5077757e4f7af0bb895acc43881cf62c.1704616152.git.christophe.jaillet@wanadoo.fr>
Message-ID: <050cb3a63e606d40d32da0a1d4c3a61d.sboyd@kernel.org>

Quoting Christophe JAILLET (2024-01-07 00:29:28)
> 'clk_data' is allocated with mtk_devm_alloc_clk_data(). So calling
> mtk_free_clk_data() explicitly in the remove function would lead to a
> double-free.
> 
> Remove the redundant call.
> 
> Fixes: c50e2ea6507b ("clk: mediatek: mt7622-apmixedsys: Add .remove() callback for module build")
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Feb 21 20:55:35 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 20:55:35 -0800
Subject: [PATCH] clk: mediatek: mt8183: Correct parent of CLK_INFRA_SSPM_32K_SELF
In-Reply-To: <20240219105125.956278-1-wenst@chromium.org>
References: <20240219105125.956278-1-wenst@chromium.org>
Message-ID: <779e41e11d90cdf05ead7932de07192d.sboyd@kernel.org>

Quoting Chen-Yu Tsai (2024-02-19 02:51:24)
> CLK_INFRA_SSPM_32K_SELF has the "f_f26m_ck" clock assigned as its parent.
> This is inconsistent as the clock is part of a group that are all gates
> without dividers, and this makes the kernel think it runs at 26 MHz.
> 
> After clarification from MediaTek engineers, the correct parent is
> actually the system 32 KHz clock.
> 
> Fixes: 1eb8d61ac5c9 ("clk: mediatek: mt8183: Add back SSPM related clocks")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Feb 21 20:55:55 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 20:55:55 -0800
Subject: [PATCH] clk: mediatek: mt7981-topckgen: flag SGM_REG_SEL as critical
In-Reply-To: <fc157139e6b7f8dfb6430ac7191ba754027705e8.1708221995.git.daniel@makrotopia.org>
References: <fc157139e6b7f8dfb6430ac7191ba754027705e8.1708221995.git.daniel@makrotopia.org>
Message-ID: <f91b8141d7edab4d6cbd3cb464ccf3d7.sboyd@kernel.org>

Quoting Daniel Golle (2024-02-17 19:11:15)
> Without the SGM_REG_SEL clock enabled the cpu freezes if trying to
> access registers used by MT7981 clock drivers itself.
> Mark SGM_REG_SEL as critical to make sure it is always enabled to
> prevent freezes on boot even if the Ethernet driver which prepares
> and enables the clock is not loaded or probed at a later point.
> 
> Fixes: 813c3b53b55b ("clk: mediatek: add MT7981 clock support")
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Feb 21 20:57:16 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 20:57:16 -0800
Subject: [PATCH V4 1/3] dt-bindings: clock: mediatek: convert hifsys to the json-schema clock
In-Reply-To: <20240214061233.24645-2-zajec5@gmail.com>
References: <20240214061233.24645-1-zajec5@gmail.com> <20240214061233.24645-2-zajec5@gmail.com>
Message-ID: <f6ed0b3e66e346994003e4c3954e1edf.sboyd@kernel.org>

Quoting Rafa? Mi?ecki (2024-02-13 22:12:31)
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files. Introduced changes:
> 1. Documented "reg" property
> 2. Documented "#reset-cells" property
> 3. Dropped "syscon" as it was incorrectly used
> 4. Adjusted "compatible" and "reg" in example
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Feb 21 20:57:26 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 20:57:26 -0800
Subject: [PATCH V4 2/3] dt-bindings: clock: mediatek: convert PCIESYS to the json-schema clock
In-Reply-To: <20240214061233.24645-3-zajec5@gmail.com>
References: <20240214061233.24645-1-zajec5@gmail.com> <20240214061233.24645-3-zajec5@gmail.com>
Message-ID: <c04d314d9f934e986a53b33e71bc990f.sboyd@kernel.org>

Quoting Rafa? Mi?ecki (2024-02-13 22:12:32)
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files. Introduced changes:
> 1. Documented "reg" property
> 2. Dropped "syscon" as it was incorrectly used
> 3. Adjusted nodename, "compatible" and "reg" in example
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Feb 21 20:57:35 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 20:57:35 -0800
Subject: [PATCH V4 3/3] dt-bindings: clock: mediatek: convert SSUSBSYS to the json-schema clock
In-Reply-To: <20240214061233.24645-4-zajec5@gmail.com>
References: <20240214061233.24645-1-zajec5@gmail.com> <20240214061233.24645-4-zajec5@gmail.com>
Message-ID: <f631feddb58950b63ecb21e2353e5892.sboyd@kernel.org>

Quoting Rafa? Mi?ecki (2024-02-13 22:12:33)
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This helps validating DTS files. Introduced changes:
> 1. Documented "reg" property
> 2. Dropped "syscon" as it was incorrectly used
> 3. Adjusted nodename, "compatible" and "reg" in example
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Feb 21 21:02:32 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 21:02:32 -0800
Subject: [PATCH v4 2/2] clk: mediatek: add infracfg reset controller for mt7988
In-Reply-To: <20240201182409.39878-3-linux@fw-web.de>
References: <20240201182409.39878-1-linux@fw-web.de> <20240201182409.39878-3-linux@fw-web.de>
Message-ID: <d788965caa6347c989c1cc6f9d20d48e.sboyd@kernel.org>

Quoting Frank Wunderlich (2024-02-01 10:24:09)
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Infracfg can also operate as reset controller, add support for it.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Feb 21 21:02:42 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 21:02:42 -0800
Subject: [PATCH v4 1/2] dt-bindings: reset: mediatek: add MT7988 infracfg reset IDs
In-Reply-To: <20240201182409.39878-2-linux@fw-web.de>
References: <20240201182409.39878-1-linux@fw-web.de> <20240201182409.39878-2-linux@fw-web.de>
Message-ID: <e82d900ea88e0b63f14b0042677269d5.sboyd@kernel.org>

Quoting Frank Wunderlich (2024-02-01 10:24:08)
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> Add reset constants for using as index in driver and dts.
> 
> Value is starting again from 0 because resets are used in another device
> than existing constants.
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> ---

Applied to clk-next


From andrew at codeconstruct.com.au  Wed Feb 21 21:14:20 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Thu, 22 Feb 2024 15:44:20 +1030
Subject: [PATCH] dt-bindings: arm: aspeed: add ASUS X4TF board
In-Reply-To: <20240222032504.1147489-2-Kelly_Hung@asus.com>
References: <20240222032504.1147489-1-Kelly_Hung@asus.com>
	 <20240222032504.1147489-2-Kelly_Hung@asus.com>
Message-ID: <2ab9b3924dbe07039e934d4580ab7dd397a31728.camel@codeconstruct.com.au>

Hi Kelly,

On Thu, 2024-02-22 at 11:25 +0800, Kelly Hung wrote:
> Document the new compatibles used on ASUS X4TF.
> 
> Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
> ---
>  Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> index 749ee54a3ff8..60a494b7aaaf 100644
> --- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> +++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> @@ -74,6 +74,7 @@ properties:
>                - ampere,mtmitchell-bmc
>                - aspeed,ast2600-evb
>                - aspeed,ast2600-evb-a1
> +              - asus, x4tf

You need to remove the space after the comma. This should be
`asus,x4tf`.

Andrew


From sboyd at kernel.org  Wed Feb 21 21:15:51 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 21:15:51 -0800
Subject: [PATCH v6 1/2] clk: Provide managed helper to get and enable bulk clocks
In-Reply-To: <20240220084046.23786-2-shradha.t@samsung.com>
References: <20240220084046.23786-1-shradha.t@samsung.com> <CGME20240220084120epcas5p1e8980539667c3d9da20f49fc645d8f4c@epcas5p1.samsung.com> <20240220084046.23786-2-shradha.t@samsung.com>
Message-ID: <610d7c44517bfe3b218a6d057a08ac7a.sboyd@kernel.org>

Quoting Shradha Todi (2024-02-20 00:40:45)
> Provide a managed devm_clk_bulk* wrapper to get and enable all
> bulk clocks in order to simplify drivers that keeps all clocks
> enabled for the time of driver operation.
> 
> Suggested-by: Marek Szyprowski <m.szyprowski at samsung.com>
> Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> ---

Applied to clk-next


From hbathini at linux.ibm.com  Wed Feb 21 21:17:29 2024
From: hbathini at linux.ibm.com (Hari Bathini)
Date: Thu, 22 Feb 2024 10:47:29 +0530
Subject: [PATCH v2 00/14] Split crash out from kexec and clean up related
 config items
In-Reply-To: <20240221125752.36fbfe9c307496313198b60f@linux-foundation.org>
References: <20240119145241.769622-1-bhe@redhat.com>
 <9101bb07-70f1-476c-bec9-ec67e9899744@linux.ibm.com>
 <Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv>
 <559f2595-1477-4ef0-80e4-85ae8b426de7@linux.ibm.com>
 <20240221125752.36fbfe9c307496313198b60f@linux-foundation.org>
Message-ID: <3393a42f-d9b3-4031-bdef-78bb2ce758f1@linux.ibm.com>



On 22/02/24 2:27 am, Andrew Morton wrote:
> On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini <hbathini at linux.ibm.com> wrote:
> 
>> On 04/02/24 8:56 am, Baoquan He wrote:
>>>>> Hope Hari and Pingfan can help have a look, see if
>>>>> it's doable. Now, I make it either have both kexec and crash enabled, or
>>>>> disable both of them altogether.
>>>>
>>>> Sure. I will take a closer look...
>>> Thanks a lot. Please feel free to post patches to make that, or I can do
>>> it with your support or suggestion.
>>
>> Tested your changes and on top of these changes, came up with the below
>> changes to get it working for powerpc:
>>
>>   
>> https://lore.kernel.org/all/20240213113150.1148276-1-hbathini at linux.ibm.com/
> 
> So can we take it that you're OK with Baoquan's series as-is?

Hi Andrew,

If you mean

v3 (https://lore.kernel.org/all/20240124051254.67105-1-bhe at redhat.com/)
+
follow-up from Baoquan 
(https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z at MiWiFi-R3L-srv/)

Yes.

My changes are based on top of the above patches..

Thanks
Hari


From s-vadapalli at ti.com  Wed Feb 21 21:29:36 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 22 Feb 2024 10:59:36 +0530
Subject: [PATCH] arm64: dts: ti: k3-j721e-evm-pcie0-ep: Extend overlay
 for PCIE1 in EP Mode
In-Reply-To: <415ee6d4-fe26-4582-80f3-9b503d308fdf@ti.com>
References: <20240220105006.1056824-1-s-vadapalli@ti.com>
 <415ee6d4-fe26-4582-80f3-9b503d308fdf@ti.com>
Message-ID: <7709aff8-869e-4496-a734-702bcefb0993@ti.com>

On Wed, Feb 21, 2024 at 10:53:14AM -0600, Andrew Davis wrote:
> On 2/20/24 4:50 AM, Siddharth Vadapalli wrote:
> > Update the existing overlay which configures PCIE0 instance of PCIe on
> > J721E-EVM in Endpoint mode of operation, in order to configure PCIE1
> > instance of PCIe as well in Endpoint mode of operation. Hence, change the
> > name of the overlay to reflect its updated functionality.
> > 
> 
> What if I only want PCIe0 to be in EP mode? Why not make a separate
> DTBO for PCIe1, that way I can have one in EP and the other in RC,
> and mix and match as needed.

Thank you for reviewing the patch. I had planned to create a different
overlay initially but felt that I would be asked to combine it with the
existing PCIe0 overlay.. I will create a separate overlay since that
seems to be acceptable and post the v2 patch.

Regards,
Siddharth.


From anshuman.khandual at arm.com  Wed Feb 21 21:33:42 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 11:03:42 +0530
Subject: [PATCH V4 02/11] coresight: stm: Extract device name from AMBA
 pid based table lookup
In-Reply-To: <56d56f85-6172-4fb1-a002-fe82ffc8a66a@arm.com>
References: <20240123054608.1790189-1-anshuman.khandual@arm.com>
 <20240123054608.1790189-3-anshuman.khandual@arm.com>
 <56d56f85-6172-4fb1-a002-fe82ffc8a66a@arm.com>
Message-ID: <af8c690f-226b-4397-ad38-9f12f3c1bd15@arm.com>



On 2/15/24 16:25, Suzuki K Poulose wrote:
> On 23/01/2024 05:45, Anshuman Khandual wrote:
>> Instead of using AMBA private data field, extract the device name from AMBA
>> pid based table lookup using new coresight_get_uci_data_from_amba() helper.
>>
>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Cc: Mike Leach <mike.leach at linaro.org>
>> Cc: James Clark <james.clark at arm.com>
>> Cc: coresight at lists.linaro.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: linux-stm32 at st-md-mailman.stormreply.com
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> ? drivers/hwtracing/coresight/coresight-priv.h | 10 ++++++++++
>> ? drivers/hwtracing/coresight/coresight-stm.c? | 14 +++++++++++++-
>> ? 2 files changed, 23 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
>> index 767076e07970..68cbb036cec8 100644
>> --- a/drivers/hwtracing/coresight/coresight-priv.h
>> +++ b/drivers/hwtracing/coresight/coresight-priv.h
>> @@ -221,6 +221,16 @@ static inline void *coresight_get_uci_data(const struct amba_id *id)
>> ????? return uci_id->data;
>> ? }
>> ? +static inline void *coresight_get_uci_data_from_amba(const struct amba_id *table, u32 pid)
>> +{
>> +??? while (table->mask) {
>> +??????? if ((table->id & table->mask) == pid)
> 
> Why are we masking table->id ? table->id is a static value that the
> driver wants to check for "variants" of a given device. The table->mask
> is there to filter out the "irrelevant" bits of the PID that we read
> from the device. So this should instead be:
> 
> ??????? if ((table->mask & pid) == table->id)

Sure, will this change as suggested.

> 
>> +??????????? return coresight_get_uci_data(table);
>> +??????? table++;
>> +??? };
>> +??? return NULL;
>> +}
>> +
>> ? void coresight_release_platform_data(struct coresight_device *csdev,
>> ?????????????????????? struct device *dev,
>> ?????????????????????? struct coresight_platform_data *pdata);
>> diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
>> index a1c27c901ad1..9cdca4f86cab 100644
>> --- a/drivers/hwtracing/coresight/coresight-stm.c
>> +++ b/drivers/hwtracing/coresight/coresight-stm.c
>> @@ -804,6 +804,18 @@ static void stm_init_generic_data(struct stm_drvdata *drvdata,
>> ????? drvdata->stm.set_options = stm_generic_set_options;
>> ? }
>> ? +#define STM_AMBA_MASK 0xfffff
>> +
>> +static const struct amba_id stm_ids[];
>> +
>> +static char *stm_csdev_name(struct coresight_device *csdev)
>> +{
>> +??? u32 stm_pid = coresight_get_pid(&csdev->access) & STM_AMBA_MASK;
> 
> Similar to above:
> 
> Why do we apply a "custom" mask to the PID and later check the PID with
> that of the table->pid.
> 
> The way it is supposed work is :
> 
> ????(table->mask & dev_pid) == table->pid
> 
> the table->mask is there for a reason: i.e., to get the relevant bits from the device_pid and compare it against "the" expected value (table->pid).

Understood, will change the helper as follows

static inline void *coresight_get_uci_data_from_amba(const struct amba_id *table, u32 pid)
{
        while (table->mask) {
                if ((pid & table->mask) == table->id)
                        return coresight_get_uci_data(table);
                table++;
        };
        return NULL;
}

and also drop both the custom masks STM_AMBA_MASK and TMC_AMBA_MASK.


From lkp at intel.com  Wed Feb 21 21:35:56 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 22 Feb 2024 13:35:56 +0800
Subject: [PATCH v2 2/3] soc: amlogic: meson-gx-socinfo-sm: Add Amlogic
 secure-monitor SoC Information driver
In-Reply-To: <20240221143654.544444-3-adeep@lexina.in>
References: <20240221143654.544444-3-adeep@lexina.in>
Message-ID: <202402221322.ifGMGQa6-lkp@intel.com>

Hi Viacheslav,

kernel test robot noticed the following build errors:

[auto build test ERROR on 9fc1ccccfd8d53dc7936fe6d633f2373fc9f62e8]

url:    https://github.com/intel-lab-lkp/linux/commits/Viacheslav-Bocharov/soc-amlogic-meson-gx-socinfo-move-common-code-to-header-file/20240221-224803
base:   9fc1ccccfd8d53dc7936fe6d633f2373fc9f62e8
patch link:    https://lore.kernel.org/r/20240221143654.544444-3-adeep%40lexina.in
patch subject: [PATCH v2 2/3] soc: amlogic: meson-gx-socinfo-sm: Add Amlogic secure-monitor SoC Information driver
config: arm64-randconfig-002-20240222 (https://download.01.org/0day-ci/archive/20240222/202402221322.ifGMGQa6-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240222/202402221322.ifGMGQa6-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402221322.ifGMGQa6-lkp at intel.com/

All errors (new ones prefixed by >>):

   aarch64-linux-ld: Unexpected GOT/PLT entries detected!
   aarch64-linux-ld: Unexpected run-time procedure linkages detected!
   aarch64-linux-ld: drivers/soc/amlogic/meson-gx-socinfo-sm.o: in function `socinfo_get_chipid':
>> meson-gx-socinfo-sm.c:(.text+0xac): undefined reference to `meson_sm_call_read'
   aarch64-linux-ld: drivers/soc/amlogic/meson-gx-socinfo-sm.o: in function `meson_gx_socinfo_sm_probe':
>> meson-gx-socinfo-sm.c:(.text+0x438): undefined reference to `meson_sm_get'

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From quic_namajain at quicinc.com  Wed Feb 21 21:42:16 2024
From: quic_namajain at quicinc.com (Naman Jain)
Date: Thu, 22 Feb 2024 11:12:16 +0530
Subject: [PATCH v3 1/7] remoteproc: Add TEE support
In-Reply-To: <20240214172127.1022199-2-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <20240214172127.1022199-2-arnaud.pouliquen@foss.st.com>
Message-ID: <71a6eb2e-bb13-4b6b-82b6-f51bdb6d164e@quicinc.com>

On 2/14/2024 10:51 PM, Arnaud Pouliquen wrote:
> From: Arnaud Pouliquen <arnaud.pouliquen at st.com>
> 
> Add a remoteproc TEE (Trusted Execution Environment) driver
> that will be probed by the TEE bus. If the associated Trusted
> application is supported on secure part this device offers a client
> interface to load a firmware in the secure part.
> This firmware could be authenticated and decrypted by the secure
> trusted application.
> 
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at st.com>
> ---

<...>

> +};
> +
> +static struct tee_rproc__context *tee_rproc_ctx;
> +
> +static void prepare_args(struct tee_rproc *trproc, int cmd,
> +			 struct tee_ioctl_invoke_arg *arg,
> +			 struct tee_param *param, unsigned int num_params)

s/prepare_args/tee_rproc_prepare_args ?

please align function args in nextline with (.
Eg: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/remoteproc/remoteproc_sysfs.c?h=v6.8-rc5#n13

> +{
> +	memset(arg, 0, sizeof(*arg));
> +	memset(param, 0, MAX_TEE_PARAM_ARRY_MEMBER * sizeof(*param));
> +
> +	arg->func = cmd;

Regards,
Naman Jain



From quic_namajain at quicinc.com  Wed Feb 21 21:43:48 2024
From: quic_namajain at quicinc.com (Naman Jain)
Date: Thu, 22 Feb 2024 11:13:48 +0530
Subject: [PATCH v3 0/7] Introduction of a remoteproc tee to load signed
 firmware
In-Reply-To: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
Message-ID: <fe4ec29f-7521-4369-a382-bae50dbf0ee5@quicinc.com>

On 2/14/2024 10:51 PM, Arnaud Pouliquen wrote:
> Updates from the previous version [1]:
> 
> This version proposes another approach based on an alternate load and boot
> of the coprocessor. Therefore, the constraint introduced by tee_remoteproc
> is that the firmware has to be authenticated and loaded before the resource
> table can be obtained.
> 
> The existing boot sequence is: >
>    1) Get the resource table and store it in a cache,
>       calling rproc->ops->parse_fw().
>    2) Parse the resource table and handle resources,
>       calling rproc_handle_resources.
>    3) Load the firmware, calling rproc->ops->load().
>    4) Start the firmware, calling rproc->ops->start().
>   
> => Steps 1 and 2 are executed in rproc_fw_boot(), while steps 3 and 4 are
>     executed in rproc_start().
> => the use of rproc->ops->load() ops is mandatory
> 
> The boot sequence needed for TEE boot is:
> 
>    1) Load the firmware.
>    2) Get the loaded resource, no cache.
>    3) Parse the resource table and handle resources.
>    4) Start the firmware.

Hi,
What problem are we really addressing here by reordering load, parse of
FW resources?
Basically, what are the limitations of the current design you are 
referring to?
I understood that TEE is designed that way.

> 
> Then the crash recovery also has to be managed.For recovery, the cache is
> used to temporarily save the resource table and then reapply it on
> restart:
>    1) Stop the remote processor, calling rproc->ops->stop().
>    2) Load the firmware, calling rproc->ops->load().
>    3) Copy cached resource table.
>    4) Start the remote processor, calling rproc->ops->start().
> 
> => This sequence is also needed when TEE manages the boot of the remote
>     processor.
> => The rproc->ops->load() is also used in recovery sequence.
> 
> Based on the sequences described above, the proposal is to:
> 
> - Rework tee_rproc API to better match the rproc_ops structure.
>    This allows to simply map the function to implement the load ops, which
>    is not optional. The tee_rproc_load_fw() is updated in consequence.
> - Remove the call of rproc_load_segments from rproc_start() to dissociate
>    the load and the start. This is necessary to implement the boot sequence
>    requested for the TEE remote proc support.
> - Introduce an rproc_alt_fw_boot() function that is an alternative boot
>    sequence, which implements the sequence requested for the TEE remoteproc
>    support.
> 
> 
> [1] https://lore.kernel.org/lkml/20240118100433.3984196-1-arnaud.pouliquen at foss.st.com/T/
> 
> 
> Description of the feature:
> 
> This series proposes the implementation of a remoteproc tee driver to
> communicate with a TEE trusted application responsible for authenticating and
> loading the remoteproc firmware image in an Arm secure context.
> 
> 1) Principle:
> 
> The remoteproc tee driver provides services to communicate with the OP-TEE
> trusted application running on the Trusted Execution Context (TEE).

s/Context/Environment?

> The trusted application in TEE manages the remote processor lifecycle:
> 
> - authenticating and loading firmware images,
> - isolating and securing the remote processor memories,
> - supporting multi-firmware (e.g., TF-M + Zephyr on a Cortex-M33),
> - managing the start and stop of the firmware by the TEE.
> 

Regards,
Naman Jain



From sboyd at kernel.org  Wed Feb 21 21:44:14 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 21:44:14 -0800
Subject: [PATCH 6/7] clk: scmi: Allocate CLK operations dynamically
In-Reply-To: <20240214183006.3403207-7-cristian.marussi@arm.com>
References: <20240214183006.3403207-1-cristian.marussi@arm.com> <20240214183006.3403207-7-cristian.marussi@arm.com>
Message-ID: <500e265eb7c6a03a40e0067c8806e059.sboyd@kernel.org>

Quoting Cristian Marussi (2024-02-14 10:30:05)
> diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
> index 5747b6d651f0..b91a0dbd2fe0 100644
> --- a/drivers/clk/clk-scmi.c
> +++ b/drivers/clk/clk-scmi.c
> @@ -158,51 +158,6 @@ static int scmi_clk_atomic_is_enabled(struct clk_hw *hw)
>         return !!enabled;
>  }
>  
> -/*
> - * We can provide enable/disable/is_enabled 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,
> -       .prepare = scmi_clk_enable,
> -       .unprepare = scmi_clk_disable,
> -       .set_parent = scmi_clk_set_parent,
> -       .get_parent = scmi_clk_get_parent,
> -       .determine_rate = scmi_clk_determine_rate,
> -};
> -
> -static const struct clk_ops scmi_atomic_clk_ops = {

It's not great to move these function pointer structs out of RO memory
to RW. I'm also not convinced that it's any better to construct them at
runtime. Isn't there a constant set of possible clk configurations? Or
why can't we simply add some failures to the clk_ops functions instead?

> -       .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,
> -       .is_enabled = scmi_clk_atomic_is_enabled,


From sboyd at kernel.org  Wed Feb 21 21:44:51 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 21:44:51 -0800
Subject: [PATCH 7/7] clk: scmi: Support get/set duty_cycle operations
In-Reply-To: <20240214183006.3403207-8-cristian.marussi@arm.com>
References: <20240214183006.3403207-1-cristian.marussi@arm.com> <20240214183006.3403207-8-cristian.marussi@arm.com>
Message-ID: <02eee0653b0f3c944fa605fe4786d2cc.sboyd@kernel.org>

Quoting Cristian Marussi (2024-02-14 10:30:06)
> Provide the CLK framework callbacks related to get/set clock duty cycle if
> the relared SCMI clock supports OEM extended configurations.
> 
> 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>
> ---

Acked-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Wed Feb 21 21:47:52 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 21:47:52 -0800
Subject: [PATCH] clk: keystone: sci-clk: match func name comment to actual
In-Reply-To: <20240115001255.4124-1-rdunlap@infradead.org>
References: <20240115001255.4124-1-rdunlap@infradead.org>
Message-ID: <fec39068daedde34528aa987ded5d2d8.sboyd@kernel.org>

Quoting Randy Dunlap (2024-01-14 16:12:55)
> Correct the function name in the kernel-doc comment to match the
> actual function name to avoid a kernel-doc warning:
> 
> drivers/clk/keystone/sci-clk.c:287: warning: expecting prototype for _sci_clk_get(). Prototype was for _sci_clk_build() instead
> 
> Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
> Cc: Nishanth Menon <nm at ti.com>
> Cc: Tero Kristo <kristo at kernel.org>
> Cc: Santosh Shilimkar <ssantosh at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: Michael Turquette <mturquette at baylibre.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> ---

Applied to clk-next


From andrew at codeconstruct.com.au  Wed Feb 21 21:52:42 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Thu, 22 Feb 2024 16:22:42 +1030
Subject: [PATCH] ARM: dts: aspeed: x4tf: Add dts for asus x4tf project
In-Reply-To: <20240222032504.1147489-1-Kelly_Hung@asus.com>
References: <20240222032504.1147489-1-Kelly_Hung@asus.com>
Message-ID: <a4bb9821f672729941e988db20bf8bc275f37279.camel@codeconstruct.com.au>

On Thu, 2024-02-22 at 11:25 +0800, Kelly Hung wrote:
> Base on aspeed-g6.dtsi and can boot into BMC console.
> 
> Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
> ---
>  arch/arm/boot/dts/aspeed/Makefile             |   3 +-
>  .../boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts  | 651 ++++++++++++++++++
>  2 files changed, 653 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
> 
> diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
> index d3ac20e316d0..f7cc69b636fc 100644
> --- a/arch/arm/boot/dts/aspeed/Makefile
> +++ b/arch/arm/boot/dts/aspeed/Makefile
> @@ -62,4 +62,5 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
>  	aspeed-bmc-ufispace-ncplite.dtb \
>  	aspeed-bmc-vegman-n110.dtb \
>  	aspeed-bmc-vegman-rx20.dtb \
> -	aspeed-bmc-vegman-sx20.dtb
> +	aspeed-bmc-vegman-sx20.dtb \
> +	aspeed-bmc-asus-x4tf.dtb

Please keep the list sorted alphabetically.

> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
> new file mode 100644
> index 000000000000..fbe39eaec154
> --- /dev/null
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
> @@ -0,0 +1,651 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +// Copyright 2024 ASUS Corp.
> +
> +/dts-v1/;
> +
> +#include "aspeed-g6.dtsi"
> +#include "aspeed-g6-pinctrl.dtsi"
> +#include <dt-bindings/i2c/i2c.h>
> +#include <dt-bindings/gpio/aspeed-gpio.h>
> +
> +/ {
> +	model = "ASUS-X4TF";
> +	compatible = "asus,x4tf", "aspeed,ast2600";
> +
> +	aliases {
> +		serial4 = &uart5;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial4:115200n8";
> +	};
> +
> +	memory at 80000000 {
> +		device_type = "memory";
> +		reg = <0x80000000 0x40000000>;
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		video_engine_memory: video {
> +			size = <0x04000000>;
> +			alignment = <0x01000000>;
> +			compatible = "shared-dma-pool";
> +			reusable;
> +		};
> +	};
> +
> +	iio-hwmon {
> +		compatible = "iio-hwmon";
> +		io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
> +				<&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
> +				<&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>,
> +				<&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>;
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		led-heartbeat {
> +			gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
> +			linux,default-trigger = "heartbeat";
> +		};
> +
> +		led-uid {
> +			gpios = <&gpio0 ASPEED_GPIO(P, 1) (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
> +			default-state = "off";
> +		};
> +
> +		led-status_Y {
> +			gpios = <&gpio1 ASPEED_GPIO(B, 1) GPIO_ACTIVE_LOW>;
> +			default-state = "off";
> +		};
> +
> +		led-sys_boot_status {
> +			gpios = <&gpio1 ASPEED_GPIO(B, 0) GPIO_ACTIVE_LOW>;
> +			default-state = "off";
> +		};
> +	};
> +};
> +
> +&adc0 {
> +	vref = <2500>;
> +	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>;
> +};
> +
> +&adc1 {
> +	vref = <2500>;
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc9_default
> +		&pinctrl_adc10_default &pinctrl_adc11_default
> +		&pinctrl_adc12_default &pinctrl_adc13_default
> +		&pinctrl_adc14_default &pinctrl_adc15_default>;
> +};
> +
> +&peci0 {
> +	status = "okay";
> +};
> +
> +&lpc_snoop {
> +	snoop-ports = <0x80>;
> +	status = "okay";
> +};
> +
> +&mdio2 {
> +	status = "okay";
> +
> +	ethphy2: ethernet-phy at 0 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <0>;
> +	};
> +};
> +
> +&mdio3 {
> +	status = "okay";
> +
> +	ethphy3: ethernet-phy at 0 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <0>;
> +	};
> +};

Are these necessary given you have `use-ncsi` specified for the MACs
below?

> +
> +&mac2 {
> +	status = "okay";
> +	phy-mode = "rmii";
> +	use-ncsi;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_rmii3_default>;
> +};
> +
> +&mac3 {
> +	status = "okay";
> +	phy-mode = "rmii";
> +	use-ncsi;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_rmii4_default>;
> +};
> +
> +&fmc {
> +	status = "okay";
> +
> +	flash at 0 {
> +		status = "okay";
> +		m25p,fast-read;
> +		label = "bmc-spi";
> +		spi-max-frequency = <50000000>;
> +
> +		partitions {
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			bmc at 0 {
> +				label = "bmc";
> +				reg = <0x0 0x4000000>;
> +			};
> +
> +			u-boot at 0 {
> +				label = "u-boot";
> +				reg = <0x0 0x200000>;
> +			};
> +
> +			u-boot-env at 1f0000 {
> +				label = "u-boot-env";
> +				reg = <0x1f0000 0x10000>;
> +			};
> +
> +			kernel at 200000 {
> +				label = "kernel";
> +				reg = <0x200000 0xc00000>;
> +			};
> +
> +			rofs at a00000 {
> +				label = "rofs";
> +				reg = <0xa00000 0x2a00000>;
> +			};
> +
> +			rwfs at 2a00000 {
> +				label = "rwfs";
> +				reg = <0x2a00000 0x43f0000>;
> +			};

Is this different to the default OpenBMC layouts? Can you use the
appropriate DTSI?

> +		};
> +	};
> +};
> +
> +&spi1 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_spi1_default>;
> +
> +	flash at 0 {
> +		status = "okay";
> +		label = "bios-spi";
> +		spi-max-frequency = <50000000>;
> +
> +		partitions {
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			biosfullimg at 0 {
> +				reg = <0x0 0x2000000>; //32768 *1024 = 32 MB
> +				label = "biosfullimg";
> +			};
> +		};
> +	};
> +};
> +
> +&i2c0 {
> +	status = "okay";
> +};
> +
> +&i2c1 {
> +	status = "okay";
> +};
> +
> +&i2c2 {
> +	status = "okay";
> +};
> +
> +&i2c3 {
> +	status = "okay";
> +};
> +
> +&i2c4 {
> +	status = "okay";
> +
> +	temperature-sensor at 48 {
> +		compatible = "ti,tmp75";
> +		reg = <0x48>;
> +	};
> +
> +	temperature-sensor at 49 {
> +		compatible = "ti,tmp75";
> +		reg = <0x49>;
> +	};
> +
> +	pca9555_4_20: gpio at 20 {
> +		compatible = "nxp,pca9555";
> +		reg = <0x20>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +
> +	pca9555_4_22: gpio at 22 {
> +		compatible = "nxp,pca9555";
> +		reg = <0x22>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +
> +	pca9555_4_24: gpio at 24 {
> +		compatible = "nxp,pca9555";
> +		reg = <0x24>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +		gpio-line-names =
> +		/*A0 - A3 0*/	"", "STRAP_BMC_BATTERY_GPIO1", "", "",
> +		/*A4 - A7 4*/	"", "", "", "",
> +		/*B0 - B7 8*/	"", "", "", "", "", "", "", "";
> +	};
> +
> +	pca9555_4_26: gpio at 26 {
> +		compatible = "nxp,pca9555";
> +		reg = <0x26>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +
> +	i2c-mux at 70 {
> +		compatible = "nxp,pca9546";
> +		status = "okay";
> +		reg = <0x70>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		channel_1: i2c at 0 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0>;
> +		};
> +
> +		channel_2: i2c at 1 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <1>;
> +		};
> +
> +		channel_3: i2c at 2 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <2>;
> +		};
> +
> +		channel_4: i2c at 3 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <3>;
> +		};
> +	};
> +};
> +
> +&i2c5 {
> +	status = "okay";
> +
> +	pca9555_5_24: gpio at 24 {
> +		compatible = "nxp,pca9555";
> +		reg = <0x24>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +
> +	i2c-mux at 70  {
> +		compatible = "nxp,pca9546";
> +		status = "okay";
> +		reg = <0x70 >;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		channel_5: i2c at 0 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0>;
> +
> +			pca9555_5_5_20: gpio at 20 {
> +				compatible = "nxp,pca9555";
> +				reg = <0x20>;
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				gpio-line-names =
> +					"", "", "", "", "", "", "", "",
> +					"", "", "SYS_FAN6", "SYS_FAN5",
> +					"SYS_FAN4", "SYS_FAN3",
> +					"SYS_FAN2", "SYS_FAN1";
> +			};
> +
> +			pca9555_5_5_21: gpio at 21 {
> +				compatible = "nxp,pca9555";
> +				reg = <0x21>;
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +			};
> +
> +			power-monitor at 44 {
> +				compatible = "ti,ina219";
> +				reg = <0x44>;
> +				shunt-resistor = <2>;
> +			};
> +		};
> +
> +		channel_6: i2c at 1 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <1>;
> +		};
> +
> +		channel_7: i2c at 2 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <2>;
> +		};
> +
> +		channel_8: i2c at 3 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <3>;
> +		};
> +	};
> +};
> +
> +&i2c6 {
> +	status = "okay";
> +
> +	pca9555_6_27: gpio at 27 {
> +		compatible = "nxp,pca9555";
> +		reg = <0x27>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +
> +	pca9555_6_20: gpio at 20 {
> +		compatible = "nxp,pca9555";
> +		reg = <0x20>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +		gpio-line-names =
> +		/*A0 0*/	"", "", "", "", "", "", "", "",
> +		/*B0 8*/	"Drive_NVMe1", "Drive_NVMe2", "", "",
> +		/*B4 12*/	"", "", "", "";
> +	};
> +
> +	pca9555_6_21: gpio at 21 {
> +		compatible = "nxp,pca9555";
> +		reg = <0x21>;
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};
> +};
> +
> +&i2c7 {
> +	status = "okay";
> +
> +	i2c-mux at 70 {
> +		compatible = "nxp,pca9546";
> +		status = "okay";
> +		reg = <0x70>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		idle-state = <1>;
> +
> +		channel_9: i2c at 0 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0>;
> +
> +			temperature-sensor at 48 {
> +				compatible = "ti,tmp75";
> +				reg = <0x48>;
> +			};
> +
> +			temperature-sensor at 49 {
> +				compatible = "ti,tmp75";
> +				reg = <0x49>;
> +			};
> +
> +			power-monitor at 40 {
> +				compatible = "ti,ina219";
> +				reg = <0x40>;
> +				shunt-resistor = <2>;
> +			};
> +
> +			power-monitor at 41 {
> +				compatible = "ti,ina219";
> +				reg = <0x41>;
> +				shunt-resistor = <5>;
> +			};
> +		};
> +
> +		channel_10: i2c at 1 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <1>;
> +		};
> +
> +		channel_11: i2c at 2 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <2>;
> +		};
> +
> +		channel_12: i2c at 3 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <3>;
> +		};
> +	};
> +
> +	i2c-mux at 71 {
> +		compatible = "nxp,pca9546";
> +		status = "okay";
> +		reg = <0x71>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		i2c-mux-idle-disconnect;
> +
> +		channel_13: i2c at 0 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0>;
> +		};
> +
> +		channel_14: i2c at 1 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <1>;
> +		};
> +
> +		channel_15: i2c at 2 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <2>;
> +		};
> +
> +		channel_16: i2c at 3 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <3>;
> +		};
> +	};
> +};
> +
> +&i2c8 {
> +	status = "okay";
> +
> +	i2c-mux at 70 {
> +		compatible = "nxp,pca9546";
> +		status = "okay";
> +		reg = <0x70>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		i2c-mux-idle-disconnect;
> +
> +		channel_17: i2c at 0 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0>;
> +		};
> +
> +		channel_18: i2c at 1 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <1>;
> +
> +			temperature-sensor at 48 {
> +				compatible = "ti,tmp75";
> +				reg = <0x48>;
> +			};
> +
> +			power-monitor at 41 {
> +				compatible = "ti,ina219";
> +				reg = <0x41>;
> +				shunt-resistor = <5>;
> +			};
> +		};
> +
> +		channel_19: i2c at 2 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <2>;
> +		};
> +
> +		channel_20: i2c at 3 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <3>;
> +		};
> +	};
> +};
> +
> +&i2c9 {
> +	status = "okay";
> +};
> +
> +&i2c10 {
> +	status = "okay";
> +};
> +
> +&i2c11 {
> +	status = "okay";
> +};
> +
> +&i2c14 {
> +	status = "okay";
> +	multi-master;
> +
> +	eeprom at 50 {
> +		compatible = "atmel,24c08";
> +		reg = <0x50>;
> +	};
> +
> +	eeprom at 51 {
> +		compatible = "atmel,24c08";
> +		reg = <0x51>;
> +	};
> +};
> +
> +&sgpiom0 {
> +	status = "okay";
> +	ngpios = <128>;
> +};
> +
> +&video {
> +	status = "okay";
> +	memory-region = <&video_engine_memory>;
> +};
> +
> +&sdc {
> +	status = "okay";
> +};
> +
> +&lpc_snoop {
> +	status = "okay";
> +	snoop-ports = <0x80>;
> +};
> +
> +&kcs1 {
> +	aspeed,lpc-io-reg = <0xca0>;
> +	status = "okay";
> +};
> +
> +&kcs2 {
> +	aspeed,lpc-io-reg = <0xca8>;
> +	status = "okay";
> +};
> +
> +&kcs3 {
> +	aspeed,lpc-io-reg = <0xca2>;
> +	status = "okay";
> +};
> +
> +&uart3 {
> +	status = "okay";
> +};
> +
> +&uart4 {
> +	status = "okay";
> +	/* GPIOB6 will be used in ASD function, do not set to be TXD4 */
> +	pinctrl-0 = <&pinctrl_txd2_default &pinctrl_rxd2_default>;

Are you sure this works? You're configuring the pins for UART2 on the
node for UART4. Enable UART2 instead?

Andrew


From sboyd at kernel.org  Wed Feb 21 21:59:57 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 21 Feb 2024 21:59:57 -0800
Subject: [PATCH v4] clk: keystone: sci-clk: Adding support for non contiguous clocks
In-Reply-To: <20240213082640.457316-1-u-kumar1@ti.com>
References: <20240213082640.457316-1-u-kumar1@ti.com>
Message-ID: <689300ed3176274c5150cf101eb53ca3.sboyd@kernel.org>

Quoting Udit Kumar (2024-02-13 00:26:40)
> Most of clocks and their parents are defined in contiguous range,
> But in few cases, there is gap in clock numbers[0].
> Driver assumes clocks to be in contiguous range, and add their clock
> ids incrementally.
> 
> New firmware started returning error while calling get_freq and is_on
> API for non-available clock ids.
> 
> In this fix, driver checks and adds only valid clock ids.
> 
> [0] https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j7200/clocks.html
> Section Clocks for NAVSS0_CPTS_0 Device, clock id 12-15 not present.
> 
> Fixes: 3c13933c6033 ("clk: keystone: sci-clk: add support for dynamically probing clocks")
> Signed-off-by: Udit Kumar <u-kumar1 at ti.com>
> ---

Applied to clk-next


From sumit.garg at linaro.org  Wed Feb 21 22:05:09 2024
From: sumit.garg at linaro.org (Sumit Garg)
Date: Thu, 22 Feb 2024 11:35:09 +0530
Subject: Calling OPTEE_SMC_CALL_GET_OS_UUID from driver code
In-Reply-To: <5a2134d0-433f-4b6f-9fda-22edae74979e@freebox.fr>
References: <443901af-6abd-4a29-b6b6-f06b6d3ce34c@freebox.fr>
 <CAFA6WYOMHEygroKGaV7Jw7c8=nrnVrW=Vqk5r1yuTR5rwFijCQ@mail.gmail.com> <5a2134d0-433f-4b6f-9fda-22edae74979e@freebox.fr>
Message-ID: <CAFA6WYPOb03XOY3QSNJY3iiXKGKZ-7irHckXoen+swV-2E8djA@mail.gmail.com>

On Wed, 21 Feb 2024 at 22:28, Marc Gonzalez <mgonzalez at freebox.fr> wrote:
>
> On 21/02/2024 08:40, Sumit Garg wrote:
>
> > Hi Marc,
> >
> > On Tue, 20 Feb 2024 at 22:59, Marc Gonzalez wrote:
> >>
> >> Hello,
> >>
> >> The driver code I'm working on hard-codes
> >>
> >> #define TEE_SMC_FAST_CALL_VAL(func_num) \
> >>     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
> >>             ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
> >>
> >> #define TEE_SMC_FUNCID_CALLS_UID 0xFF01
> >> #define TEE_SMC_CALLS_UID \
> >>     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
> >>                ARM_SMCCC_OWNER_TRUSTED_OS_END, \
> >>                TEE_SMC_FUNCID_CALLS_UID)
> >>
> >>     arm_smccc_smc(TEE_SMC_CALLS_UID,
> >>             0, 0, 0/*is_swap*/, 0, 0, 0, 0, &res);
> >>     dev_err(dev, "TEE UID %x %x %x %x\n", res.a0, res.a1, res.a2, res.a3);
> >>
> >>
> >> but it seems I would be required to somehow use
> >> OPTEE_SMC_CALL_GET_OS_UUID
> >>
> >> But it's not exported, and no code seems to use it...?
> >
> > Can you describe your use-case to require direct
> > OPTEE_SMC_CALL_GET_OS_UUID invocation?
>
> Turns out the GET_OS_UUID call was just debug code to make sure
> we were getting the expected reply.
>
> I have removed it from the production code.
> Below is the current code.
>
> diff --git a/drivers/staging/media/meson/vdec/vdec_1.c b/drivers/staging/media/meson/vdec/vdec_1.c
> index 3fe2de0c9331f..120bb1847aa38 100644
> --- a/drivers/staging/media/meson/vdec/vdec_1.c
> +++ b/drivers/staging/media/meson/vdec/vdec_1.c
> @@ -8,7 +8,10 @@
>   */
>
>  #include <linux/firmware.h>
> +#include <linux/delay.h>
>  #include <linux/clk.h>
> +#include <linux/arm-smccc.h>
> +#include <soc/amlogic/socinfo.h>
>
>  #include "vdec_1.h"
>  #include "vdec_helpers.h"
> @@ -22,6 +25,45 @@
>
>  #define MC_SIZE                        (4096 * 4)
>
> +static int
> +vdec_1_load_firmware_optee(struct amvdec_session *sess)
> +{
> +       struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops;
> +       struct amvdec_core *core = sess->core;
> +       struct device *dev = core->dev_dec;
> +       struct arm_smccc_res res;
> +       u32 pixfmt = sess->fmt_out->pixfmt;
> +       int fw_id = -1;
> +
> +#define TEE_SMC_FAST_CALL_VAL(func_num) \
> +       ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
> +
> +#define TEE_SMC_FUNCID_LOAD_VIDEO_FW 15
> +#define TEE_SMC_LOAD_VIDEO_FW TEE_SMC_FAST_CALL_VAL(TEE_SMC_FUNCID_LOAD_VIDEO_FW)
> +#define OPTEE_VDEC_LEGACY 0
> +#define VIDEO_DEC_MPEG12 0
> +#define VIDEO_DEC_H264 11
> +
> +       // Load wrong firmware, so that TA will reset hw component for us
> +       arm_smccc_smc(TEE_SMC_LOAD_VIDEO_FW, 1, OPTEE_VDEC_LEGACY, 0, 0, 0, 0, 0, &res);
> +
> +       if (pixfmt == V4L2_PIX_FMT_H264)
> +               fw_id = 11;
> +
> +       if (pixfmt == V4L2_PIX_FMT_MPEG1 || pixfmt == V4L2_PIX_FMT_MPEG2)
> +               fw_id = 0;
> +
> +       arm_smccc_smc(TEE_SMC_LOAD_VIDEO_FW, fw_id, OPTEE_VDEC_LEGACY, 0, 0, 0, 0, 0, &res);
> +       dev_info(dev, "Load firmware %d: ret=%d\n", fw_id, res.a0);
> +
> +       msleep(100);
> +
> +       if (codec_ops->load_extended_firmware)
> +               codec_ops->load_extended_firmware(sess, 0, 0);
> +
> +       return 0;
> +}
> +
>  static int
>  vdec_1_load_firmware(struct amvdec_session *sess, const char *fwname)
>  {
> @@ -209,7 +251,11 @@ static int vdec_1_start(struct amvdec_session *sess)
>
>         vdec_1_stbuf_power_up(sess);
>
> -       ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path);
> +       if (meson_get_secure_boot_state() == 1)
> +               ret = vdec_1_load_firmware_optee(sess);
> +       else
> +               ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path);
> +
>         if (ret)
>                 goto stop;
>
> @@ -232,6 +278,13 @@ static int vdec_1_start(struct amvdec_session *sess)
>         /* Let the firmware settle */
>         usleep_range(10, 20);
>
> +       /*
> +        * When running secure boot, it looks like the codec needs
> +        * more time to settle (perhaps to authenticate the image?)
> +        */
> +       if (meson_get_secure_boot_state() == 1)
> +               msleep(100);
> +
>         return 0;
>
>  stop:
>
>
> >> $ git grep OPTEE_SMC_CALL_GET_OS_UUID
> >> Documentation/tee/op-tee.rst:- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
> >> drivers/tee/optee/optee_smc.h:#define OPTEE_SMC_CALL_GET_OS_UUID \
> >>
> >> How do I make calls to OP-TEE from driver code?
> >
> > The TEE driver API documentation is here [1] and you can refer to the
> > existing OP-TEE RNG driver here for reference.
> >
> > [1] https://docs.kernel.org/driver-api/tee.html
> > [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/char/hw_random/optee-rng.c
>
> Wow, this looks very different from our code.
>
> Are we not supposed to call arm_smccc_smc() from driver code?

Yes, all OP-TEE invocations are abstracted out via the TEE bus driver
framework. You can find other examples with a simple grep like:

$ git grep -nr "tee_bus_type"

> Looks like no one else is calling arm_smccc_smc with an owner
> equal to ARM_SMCCC_OWNER_TRUSTED_OS...
>

BTW, looking at your use-case it sounds somewhat similar (load a
firmware via OP-TEE) to this [1]. So you can take that as a reference
for your driver development.

[1] https://lore.kernel.org/linux-arm-kernel/20240214172127.1022199-3-arnaud.pouliquen at foss.st.com/T/

-Sumit


From bagasdotme at gmail.com  Wed Feb 21 22:26:05 2024
From: bagasdotme at gmail.com (Bagas Sanjaya)
Date: Thu, 22 Feb 2024 13:26:05 +0700
Subject: Qualcomm Snapdragon 8cx Gen 2 not supported yet?
Message-ID: <Zdbo_aXDZ8YLIiQh@archie.me>

Hi,

Aram M. <aram.minasyan at yahoo.com> opened Bugzilla ticket requesting devicetree
support for sc8180xp [1]. He wrote:

> The Linux kernel 6.7.5 only boots in ACPI mode on DELL Inspiron 14 3420
> with Qualcomm Snapdragon 8cx Gen 2 (sc8180xp).
> A lot of hardware is not functional, this maybe due to missing device tree?
> Built in keyboard and PCIe devices not working, only runs on USB connected disk, keyboard & peripherals.
> 
> Support for sc8180x & sc8280xp devices exist, but not for sc8180xp devices.
> 
> Under arch/arm64/boot/dts/qcom in source tree the files
> sc8180x-pmics.dtsi, sc8180x.dtsi, sc8280xp-pmics.dtsi, sc8280xp.dtsi.
> exist, but none for sc8180xp, which would be used for specific hardware dts 
> files?
> Maybe the hardware is similar enough to sc8180x? But of course I have no idea.
> 
> It would be nice for the keyboard to function without the device tree, seems like module i2c_qcom_geni doesn't work without dtb?
> 
> 
> I have attached dmesg output.

Aram, can you submit devicetree patch supporting your device?

Thanks.

[1]: https://bugzilla.kernel.org/show_bug.cgi?id=218512

-- 
An old man doll... just what I always wanted! - Clara
-------------- 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/20240222/7ff45568/attachment.sig>

From shengjiu.wang at nxp.com  Wed Feb 21 22:17:13 2024
From: shengjiu.wang at nxp.com (Shengjiu Wang)
Date: Thu, 22 Feb 2024 14:17:13 +0800
Subject: [PATCH] arm64: dts: imx8mm-evk: Add spdif sound card support
Message-ID: <1708582633-6969-1-git-send-email-shengjiu.wang@nxp.com>

Add spdif sound card support, configure the pinmux.

This sound card supports recording and playing sound
through spdif interface.

Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index 9b39458f3fa5..bd5b365867fd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -165,6 +165,14 @@ cpu {
 			};
 		};
 	};
+
+	sound-spdif {
+		compatible = "fsl,imx-audio-spdif";
+		model = "imx-spdif";
+		spdif-controller = <&spdif1>;
+		spdif-out;
+		spdif-in;
+	};
 };
 
 &A53_0 {
@@ -533,6 +541,24 @@ &snvs_pwrkey {
 	status = "okay";
 };
 
+&spdif1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spdif1>;
+	assigned-clocks = <&clk IMX8MM_CLK_SPDIF1>;
+	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+	assigned-clock-rates = <24576000>;
+	clocks = <&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_24M>,
+		 <&clk IMX8MM_CLK_SPDIF1>, <&clk IMX8MM_CLK_DUMMY>,
+		 <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
+		 <&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_DUMMY>,
+		 <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
+		 <&clk IMX8MM_AUDIO_PLL1_OUT>, <&clk IMX8MM_AUDIO_PLL2_OUT>;
+	clock-names = "core", "rxtx0", "rxtx1", "rxtx2", "rxtx3",
+		      "rxtx4", "rxtx5", "rxtx6", "rxtx7", "spba",
+		      "pll8k", "pll11k";
+	status = "okay";
+};
+
 &uart2 { /* console */
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart2>;
@@ -702,6 +728,13 @@ MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0     0xd6
 		>;
 	};
 
+	pinctrl_spdif1: spdif1grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SPDIF_TX_SPDIF1_OUT	0xd6
+			MX8MM_IOMUXC_SPDIF_RX_SPDIF1_IN		0xd6
+		>;
+	};
+
 	pinctrl_typec1: typec1grp {
 		fsl,pins = <
 			MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11	0x159
-- 
2.34.1



From s-vadapalli at ti.com  Wed Feb 21 22:57:33 2024
From: s-vadapalli at ti.com (Siddharth Vadapalli)
Date: Thu, 22 Feb 2024 12:27:33 +0530
Subject: [PATCH v2] arm64: dts: ti: k3-j721e-evm: Add overlay for PCIE1 Endpoint Mode
Message-ID: <20240222065733.1213434-1-s-vadapalli@ti.com>

Add overlay to enable the PCIE1 instance of PCIe on J721E-EVM in Endpoint
mode of operation. Additionally, in order to support both PCIE0 and PCIE1
in Endpoint Mode of operation, enable applying device-tree overlays on
"k3-j721e-evm-pcie0-ep.dtb", thereby allowing the overlay for PCIE1 in
Endpoint mode to be applied on the aforementioned DTB.

Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---

Hello,

This patch is based on linux-next tagged next-20240221.
The v1 of this patch is at:
https://lore.kernel.org/r/20240220105006.1056824-1-s-vadapalli at ti.com/
Changes since v1:
- Created a new overlay for PCIE1 based on Andrew's suggestion at:
  https://lore.kernel.org/r/415ee6d4-fe26-4582-80f3-9b503d308fdf at ti.com/
- Updated Makefile to allow applying overlay on
  "k3-j721e-evm-pcie0-ep.dtb"

Regards,
Siddharth.

 arch/arm64/boot/dts/ti/Makefile               |  5 ++
 .../boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso    | 53 +++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100644 arch/arm64/boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso

diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index d601c52ab181..d8a5db6db490 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -76,6 +76,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721e-beagleboneai64.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-gesi-exp-board.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie0-ep.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-evm-pcie1-ep.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-dual-imx219.dtbo
 
@@ -128,6 +129,8 @@ k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j721e-evm-pcie0-ep-dtbs := k3-j721e-common-proc-board.dtb \
 	k3-j721e-evm-pcie0-ep.dtbo
+k3-j721e-evm-pcie1-ep-dtbs := k3-j721e-common-proc-board.dtb \
+	k3-j721e-evm-pcie1-ep.dtbo
 k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \
 	k3-j721e-sk-csi2-dual-imx219.dtbo
 k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \
@@ -148,6 +151,7 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
 	k3-am68-sk-base-board-csi2-dual-imx219-dtbs \
 	k3-am69-sk-csi2-dual-imx219-dtbs \
 	k3-j721e-evm-pcie0-ep.dtb \
+	k3-j721e-evm-pcie1-ep.dtb \
 	k3-j721e-sk-csi2-dual-imx219-dtbs \
 	k3-j721s2-evm-pcie1-ep.dtb
 
@@ -162,5 +166,6 @@ DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
 DTC_FLAGS_k3-am68-sk-base-board += -@
 DTC_FLAGS_k3-am69-sk += -@
 DTC_FLAGS_k3-j721e-common-proc-board += -@
+DTC_FLAGS_k3-j721e-evm-pcie0-ep += -@
 DTC_FLAGS_k3-j721e-sk += -@
 DTC_FLAGS_k3-j721s2-common-proc-board += -@
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso
new file mode 100644
index 000000000000..b1d579e577ab
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie1-ep.dtso
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for enabling PCIE1 instance in Endpoint Configuration with the
+ * J7 common processor board.
+ *
+ * J7 Common Processor Board Product Link: https://www.ti.com/tool/J721EXCPXEVM
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-pinctrl.h"
+
+/*
+ * Since Root Complex and Endpoint modes are mutually exclusive
+ * disable Root Complex mode.
+ */
+&pcie1_rc {
+	status = "disabled";
+};
+
+&cbass_main {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic500>;
+
+	pcie1_ep: pcie-ep at 2910000 {
+		compatible = "ti,j721e-pcie-ep";
+		reg = <0x00 0x02910000 0x00 0x1000>,
+		      <0x00 0x02917000 0x00 0x400>,
+		      <0x00 0x0d800000 0x00 0x00800000>,
+		      <0x00 0x18000000 0x00 0x08000000>;
+		reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+		interrupt-names = "link_state";
+		interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
+		ti,syscon-pcie-ctrl = <&scm_conf 0x4074>;
+		max-link-speed = <3>;
+		num-lanes = <2>;
+		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 240 1>;
+		clock-names = "fck";
+		max-functions = /bits/ 8 <6>;
+		max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+		dma-coherent;
+		phys = <&serdes1_pcie_link>;
+		phy-names = "pcie-phy";
+	};
+};
-- 
2.34.1



From jirislaby at kernel.org  Wed Feb 21 22:58:32 2024
From: jirislaby at kernel.org (Jiri Slaby)
Date: Thu, 22 Feb 2024 07:58:32 +0100
Subject: [PATCH v1 02/14] serial: core: Add UPIO_UNSET constant for unset
 port type
In-Reply-To: <20240221183442.4124354-3-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-3-andriy.shevchenko@linux.intel.com>
Message-ID: <5aeee02f-45a6-48e5-a6f4-e55b76d4b959@kernel.org>

On 21. 02. 24, 19:31, Andy Shevchenko wrote:
> In some APIs we would like to assign the special value to iotype
> and compare against it in another places. Introduce UPIO_UNSET
> for this purpose.
> 
> Note, we can't use 0, because it's a valid value for IO port access.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> ---
>   include/linux/serial_core.h | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index 2d2ec99eca93..2b0526ae1fac 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -470,6 +470,7 @@ struct uart_port {
>   
>   	unsigned char		iotype;			/* io access style */
>   
> +#define UPIO_UNSET		((unsigned char)~0U)	/* UCHAR_MAX */

Perhaps making the var u8 and this U8_MAX then? It would make more sense 
to me.

>   #define UPIO_PORT		(SERIAL_IO_PORT)	/* 8b I/O port access */
>   #define UPIO_HUB6		(SERIAL_IO_HUB6)	/* Hub6 ISA card */
>   #define UPIO_MEM		(SERIAL_IO_MEM)		/* driver-specific */

thanks,
-- 
js
suse labs



From william.zhang at broadcom.com  Wed Feb 21 23:01:22 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed, 21 Feb 2024 23:01:22 -0800
Subject: [PATCH v5 04/12] ARM: dts: broadcom: bcmbca: Add NAND controller
 node
In-Reply-To: <c145b90c-e9f0-4d82-94cc-baf7bfda5954@gmail.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-5-william.zhang@broadcom.com>
 <c145b90c-e9f0-4d82-94cc-baf7bfda5954@gmail.com>
Message-ID: <c4710d19-e6ef-4a99-a10b-6fb41c87d410@broadcom.com>

Hi Florian,

On 2/21/24 16:39, Florian Fainelli wrote:
> On 2/7/24 12:22, William Zhang wrote:
>> Add support for Broadcom STB NAND controller in BCMBCA ARMv7 chip dts
>> files.
>>
>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>> Reviewed-by: David Regan <dregan at broadcom.com>
> 
> I would like to apply this and the next one, but the use of the 
> brcm,nand-ecc-use-strap property which is still being discussed would 
> require me to wait a bit, unless you want to split things up and add the 
> NAND controller node(s), and then issue a subsequent patch which adds 
> "brcm,nand-ecc-use-strap" where relevant.
> 
> You have a few days to decide before I send the pull request for 6.9.
> 
I will send out the v6 patches tomorrow based on Miquel's feedback.

> Thanks!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240221/50b6752c/attachment.p7s>

From william.zhang at broadcom.com  Wed Feb 21 23:02:00 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Wed, 21 Feb 2024 23:02:00 -0800
Subject: [PATCH v5 06/12] arm64: dts: broadcom: bcmbca: Update router
 boards
In-Reply-To: <1e636620-d456-4bb8-a5f0-742be3a9d6ad@gmail.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-7-william.zhang@broadcom.com>
 <20240222003755.670359-1-florian.fainelli@broadcom.com>
 <1e636620-d456-4bb8-a5f0-742be3a9d6ad@gmail.com>
Message-ID: <d6c4f087-4e25-43df-8187-7c7f9af2b6ca@broadcom.com>



On 2/21/24 16:40, Florian Fainelli wrote:
> On 2/21/24 16:37, Florian Fainelli wrote:
>> From: Florian Fainelli <f.fainelli at gmail.com>
>>
>> On Wed,? 7 Feb 2024 12:22:51 -0800, William Zhang 
>> <william.zhang at broadcom.com> wrote:
>>> Enable the nand controller and add WP pin connection property in actual
>>> board dts as they are board level properties now that they are disabled
>>> and moved out from SoC dtsi.
>>>
>>> Also remove the unnecessary brcm,nand-has-wp property from AC5300 board.
>>> This property is only needed for some old controller that this board
>>> does not apply.
>>>
>>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>>> ---
>>
>> Applied to 
>> https://github.com/Broadcom/stblinux/commits/devicetree/next, thanks!
>> -- 
>> Florian
> 
> Actually no, cannot apply this just yet since this depends upon patch #5.
Correct. Please wait for v6.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240221/bcf24e60/attachment-0001.p7s>

From sudeep.holla at arm.com  Wed Feb 21 23:04:43 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 07:04:43 +0000
Subject: [PATCH 1/1] ARM: dts: vexpress: Set stdout-path to serial0 in the chosen node
In-Reply-To: <20240209112807.1345164-2-ole.orhagen@northern.tech>
References: <20240209112807.1345164-2-ole.orhagen@northern.tech>
Message-ID: <170858541139.105402.16635187273883858613.b4-ty@arm.com>

On Fri, 09 Feb 2024 12:28:01 +0100, Ole P. Orhagen wrote:
> Specify v2m_serial0 as the device for boot console output through the
> stdout-path in the chosen node.

Applied to sudeep.holla/linux (for-next/vexpress/updates), thanks!

[1/1] ARM: dts: vexpress: Set stdout-path to serial0 in the chosen node
      https://git.kernel.org/sudeep.holla/c/bd2cb11fd765
--
Regards,
Sudeep



From bhe at redhat.com  Wed Feb 21 23:07:05 2024
From: bhe at redhat.com (Baoquan He)
Date: Thu, 22 Feb 2024 15:07:05 +0800
Subject: [PATCH v2 00/14] Split crash out from kexec and clean up related
 config items
In-Reply-To: <20240221125752.36fbfe9c307496313198b60f@linux-foundation.org>
References: <20240119145241.769622-1-bhe@redhat.com>
 <9101bb07-70f1-476c-bec9-ec67e9899744@linux.ibm.com>
 <Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv>
 <559f2595-1477-4ef0-80e4-85ae8b426de7@linux.ibm.com>
 <20240221125752.36fbfe9c307496313198b60f@linux-foundation.org>
Message-ID: <Zdbymex3ABImSwI3@MiWiFi-R3L-srv>

On 02/21/24 at 12:57pm, Andrew Morton wrote:
> On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini <hbathini at linux.ibm.com> wrote:
> 
> > On 04/02/24 8:56 am, Baoquan He wrote:
> > >>> Hope Hari and Pingfan can help have a look, see if
> > >>> it's doable. Now, I make it either have both kexec and crash enabled, or
> > >>> disable both of them altogether.
> > >>
> > >> Sure. I will take a closer look...
> > > Thanks a lot. Please feel free to post patches to make that, or I can do
> > > it with your support or suggestion.
> > 
> > Tested your changes and on top of these changes, came up with the below
> > changes to get it working for powerpc:
> > 
> >  
> > https://lore.kernel.org/all/20240213113150.1148276-1-hbathini at linux.ibm.com/
> 
> So can we take it that you're OK with Baoquan's series as-is?
> 
> Baoquan, do you believe the patches in mm-unstable are ready for moving
> into mm-stable in preparation for an upstream merge?

Yeah, I think they are ready to go for merging.

For Hari's patchset, the main part was planned before. And I am not
familiar with fadump in powerpc, the Kconfig fix from Hari is a good
guarantee with the expertise. Surely, I will await Hari's comment on
that.



From Kelly_Hung at asus.com  Wed Feb 21 23:32:34 2024
From: Kelly_Hung at asus.com (=?utf-8?B?S2VsbHkgSHVuZyjmtKrlmInojokp?=)
Date: Thu, 22 Feb 2024 07:32:34 +0000
Subject: [PATCH] dt-bindings: arm: aspeed: add ASUS X4TF board
In-Reply-To: <2ab9b3924dbe07039e934d4580ab7dd397a31728.camel@codeconstruct.com.au>
References: <20240222032504.1147489-1-Kelly_Hung@asus.com>
	 <20240222032504.1147489-2-Kelly_Hung@asus.com>
 <2ab9b3924dbe07039e934d4580ab7dd397a31728.camel@codeconstruct.com.au>
Message-ID: <TYZPR04MB6596F2EBAF65F7F53809C2259D562@TYZPR04MB6596.apcprd04.prod.outlook.com>

External email : Ensure your email is secure before opening links and attachments.

Document the new compatibles used on ASUS X4TF.

Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
---
 Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 749ee54a3ff8..60a494b7aaaf 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -74,6 +74,7 @@ properties:
               - ampere,mtmitchell-bmc
               - aspeed,ast2600-evb
               - aspeed,ast2600-evb-a1
+              - asus,x4tf
               - facebook,bletchley-bmc
               - facebook,cloudripper-bmc
               - facebook,elbert-bmc
--
2.25.1


<p></p>

-----Original Message-----
From: Andrew Jeffery <andrew at codeconstruct.com.au>
Sent: Thursday, February 22, 2024 1:14 PM
To: Kelly Hung <ppighouse at gmail.com>; robh+dt at kernel.org
Cc: krzysztof.kozlowski+dt at linaro.org; conor+dt at kernel.org; joel at jms.id.au; devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-aspeed at lists.ozlabs.org; linux-kernel at vger.kernel.org; openbmc at lists.ozlabs.org; Kelly Hung(???) <Kelly_Hung at asus.com>; AllenYY Hsu(???) <AllenYY_Hsu at asus.com>
Subject: Re: [PATCH] dt-bindings: arm: aspeed: add ASUS X4TF board

External email : Ensure your email is secure before opening links and attachments.

Hi Kelly,

On Thu, 2024-02-22 at 11:25 +0800, Kelly Hung wrote:
> Document the new compatibles used on ASUS X4TF.
>
> Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
> ---
>  Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> index 749ee54a3ff8..60a494b7aaaf 100644
> --- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> +++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> @@ -74,6 +74,7 @@ properties:
>                - ampere,mtmitchell-bmc
>                - aspeed,ast2600-evb
>                - aspeed,ast2600-evb-a1
> +              - asus, x4tf

You need to remove the space after the comma. This should be `asus,x4tf`.

Andrew

<p></p>
===================================================================================================================================
This email and any attachments to it contain confidential information and are intended solely for the use of the individual to whom it is addressed. If you are not the intended recipient or receive it accidentally, please immediately notify the sender by e-mail and delete the message and any attachments from your computer system, and destroy all hard copies. Please be advised that any unauthorized disclosure, copying, distribution or any action taken or omitted in reliance on this, is illegal and prohibited. Any views or opinions expressed are solely those of the author and do not represent those of ASUSTeK.

For pricing information, ASUS is only entitled to set a recommendation resale price. All customers are free to set their own price as they wish.
===================================================================================================================================

From lkp at intel.com  Wed Feb 21 23:27:29 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 22 Feb 2024 15:27:29 +0800
Subject: [PATCH v2 2/3] soc: amlogic: meson-gx-socinfo-sm: Add Amlogic
 secure-monitor SoC Information driver
In-Reply-To: <20240221143654.544444-3-adeep@lexina.in>
References: <20240221143654.544444-3-adeep@lexina.in>
Message-ID: <202402221557.ELxBYVKH-lkp@intel.com>

Hi Viacheslav,

kernel test robot noticed the following build errors:

[auto build test ERROR on 9fc1ccccfd8d53dc7936fe6d633f2373fc9f62e8]

url:    https://github.com/intel-lab-lkp/linux/commits/Viacheslav-Bocharov/soc-amlogic-meson-gx-socinfo-move-common-code-to-header-file/20240221-224803
base:   9fc1ccccfd8d53dc7936fe6d633f2373fc9f62e8
patch link:    https://lore.kernel.org/r/20240221143654.544444-3-adeep%40lexina.in
patch subject: [PATCH v2 2/3] soc: amlogic: meson-gx-socinfo-sm: Add Amlogic secure-monitor SoC Information driver
config: xtensa-randconfig-r071-20240222 (https://download.01.org/0day-ci/archive/20240222/202402221557.ELxBYVKH-lkp at intel.com/config)
compiler: xtensa-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240222/202402221557.ELxBYVKH-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402221557.ELxBYVKH-lkp at intel.com/

All errors (new ones prefixed by >>):

   xtensa-linux-ld: drivers/soc/amlogic/meson-gx-socinfo-sm.o: in function `meson_gx_socinfo_sm_remove':
   meson-gx-socinfo-sm.c:(.text+0x88): undefined reference to `meson_sm_get'
>> xtensa-linux-ld: meson-gx-socinfo-sm.c:(.text+0x8c): undefined reference to `meson_sm_call_read'
   xtensa-linux-ld: drivers/soc/amlogic/meson-gx-socinfo-sm.o: in function `meson_gx_socinfo_sm_probe':
   meson-gx-socinfo-sm.c:(.text+0x1b8): undefined reference to `meson_sm_get'
   xtensa-linux-ld: meson-gx-socinfo-sm.c:(.text+0x243): undefined reference to `meson_sm_call_read'

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From T.Remmet at phytec.de  Wed Feb 21 23:37:25 2024
From: T.Remmet at phytec.de (Teresa Remmet)
Date: Thu, 22 Feb 2024 07:37:25 +0000
Subject: [PATCH 1/4] arm64: dts: imx8mp-phyboard-pollux: Add and update
 rtc devicetree node
In-Reply-To: <bae6a26a-a46c-445f-b44f-32d50146e36e@kontron.de>
References: <20240221141235.47639-1-y.varakala@phytec.de>
	 <20240221141235.47639-2-y.varakala@phytec.de>
	 <bae6a26a-a46c-445f-b44f-32d50146e36e@kontron.de>
Message-ID: <79668325838f6699c74488cbe1f1717cb56d0c94.camel@phytec.de>

Hello Frieder,

Am Mittwoch, dem 21.02.2024 um 15:29 +0100 schrieb Frieder Schrempf:
> On 21.02.24 15:12, Yashwanth Varakala wrote:
> > [Sie erhalten nicht h?ufig E-Mails von y.varakala at phytec.de.
> > Weitere Informationen, warum dies wichtig ist, finden Sie unter
> > https://aka.ms/LearnAboutSenderIdentification?]
> > 
> > The interrupt of the rtc is connected on the carrierboard
> 
> s/rtc/RTC/
> s/carrierboard/carrier board/
> 
> > phyBOARD-i.MX8MP-Pollux.
> > 
> > RTC trickle-charger and level-switching-mode device tree properties
> > are depended on the phyboard-pollux design.
> 
> There is no way to control the backup switching mode via devicetree,
> so
> this description doesn't match the code.

this is correct. We had a down stream property handling this. 
This is why it probably sneaked in. It should be dropped.

> 
> Also "are depended on" should probably be "depend on" or "are
> dependent
> on". And when you scratch the "level-switching-mode" it's singular of
> course.
> 
> > 
> > Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
> > ---
> > ?.../dts/freescale/imx8mp-phyboard-pollux-rdk.dts? | 15
> > +++++++++++++++
> > ?.../boot/dts/freescale/imx8mp-phycore-som.dtsi??? |? 1 -
> > ?2 files changed, 15 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-
> > rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-
> > rdk.dts
> > index c8640cac3edc..96754ce633ed 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
> > +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
> > @@ -139,6 +139,15 @@ &snvs_pwrkey {
> > ??????? status = "okay";
> > ?};
> > 
> > +&rv3028 {
> > +?????? pinctrl-names = "default";
> > +?????? pinctrl-0 = <&pinctrl_rtc>;
> > +?????? interrupt-parent = <&gpio4>;
> > +?????? interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
> 
> The RTC is on the SoM and the interrupt line is routed from the SoM
> to
> the carrier board and then back to the SoC? Is this really the case?

Yes, this is really the case. 


> I
> would expect the IRQ to be routed within the SoM.


It was done to give the carrier board designer more freedom with the
alarm pin of the RTC.

Teresa

> 
> > +?????? wakeup-source;
> > +?????? trickle-resistor-ohms = <3000>;
> > +};
> > +
> > ?/* debug console */
> > ?&uart1 {
> > ??????? pinctrl-names = "default";
> > @@ -295,6 +304,12 @@ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19??????
> > 0x40
> > ??????????????? >;
> > ??????? };
> > 
> > +?????? pinctrl_rtc: rtcgrp {
> > +?????????????? fsl,pins = <
> > +?????????????????????? MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19?????
> > 0x1C0
> > +?????????????? >;
> > +?????? };
> > +
> > ??????? pinctrl_uart1: uart1grp {
> > ??????????????? fsl,pins = <
> > ??????????????????????? MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX???
> > 0x40
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
> > index c976c3b6cbc6..e6ffa6a6b68b 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
> > @@ -175,7 +175,6 @@ eeprom at 51 {
> > ??????? rv3028: rtc at 52 {
> > ??????????????? compatible = "microcrystal,rv3028";
> > ??????????????? reg = <0x52>;
> > -?????????????? trickle-resistor-ohms = <3000>;
> > ??????? };
> > ?};
> > 
> > --
> > 2.34.1
> > 
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> _______________________________________________

-- 
PHYTEC Messtechnik GmbH | Barcelona-Allee 1 | 55129 Mainz, Germany

Gesch?ftsf?hrer: Dipl.-Ing. Michael Mitezki, Dipl.-Ing. Bodo Huber,
Dipl.-Ing. (FH) Markus Lickes | Handelsregister Mainz HRB 4656 |
Finanzamt Mainz | St.Nr. 266500608, DE 149059855

From sudeep.holla at arm.com  Wed Feb 21 23:38:10 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 07:38:10 +0000
Subject: [PATCH 0/2] firmware: struct bus_type cleanup
In-Reply-To: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
References: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
Message-ID: <170858556491.105647.13334595992310350270.b4-ty@arm.com>

On Sun, 11 Feb 2024 12:51:28 -0300, Ricardo B. Marliere wrote:
> This series is part of an effort to cleanup the users of the driver
> core, as can be seen in many recent patches authored by Greg across the
> tree (e.g. [1]).
> 

Applied to sudeep.holla/linux (for-next/ffa/updates), thanks!

[1/2] firmware: arm_ffa: Make ffa_bus_type const
      https://git.kernel.org/sudeep.holla/c/989e8661dc45
--
Regards,
Sudeep



From T.Remmet at phytec.de  Wed Feb 21 23:43:45 2024
From: T.Remmet at phytec.de (Teresa Remmet)
Date: Thu, 22 Feb 2024 07:43:45 +0000
Subject: [PATCH 2/4] arm64: dts: imx8mp-phyboard-pollux: Set debug uart
 muxing to 0x140
In-Reply-To: <20240221141235.47639-3-y.varakala@phytec.de>
References: <20240221141235.47639-1-y.varakala@phytec.de>
	 <20240221141235.47639-3-y.varakala@phytec.de>
Message-ID: <e826fd3c7ee867bdc0de6c6f9c803f3f9ebf5063.camel@phytec.de>

Hello Yashwanth,

Am Mittwoch, dem 21.02.2024 um 15:12 +0100 schrieb Yashwanth Varakala:
> From: Benjamin Hahn <B.Hahn at phytec.de>
> 
> Set Pull Resistors Enable bit to put signal into a defined state.
> 
> Signed-off-by: Yannic Moog <y.moog at phytec.de>
> Signed-off-by: Benjamin Hahn <B.Hahn at phytec.de>

your Signed-off-by is missing here. Same with the other patches.

And somehow the authorship of the patch got messed up. Benjamin updated
the patch but this patch was actually created by Yannic. Same issue
with the other ones. 

Teresa

> ---
> ?arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 4 ++-
> -
> ?1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-
> rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-
> rdk.dts
> index 96754ce633ed..36b59d0c67f7 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
> @@ -312,8 +312,8 @@ MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19??0x1C0
> ?
> ????????pinctrl_uart1: uart1grp {
> ????????????????fsl,pins = <
> -???????????????????????MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX????0x40
> -???????????????????????MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX????0x40
> +???????????????????????MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX????0x140
> +???????????????????????MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX????0x140
> ????????????????>;
> ????????};
> ?

-- 
PHYTEC Messtechnik GmbH | Barcelona-Allee 1 | 55129 Mainz, Germany

Gesch?ftsf?hrer: Dipl.-Ing. Michael Mitezki, Dipl.-Ing. Bodo Huber,
Dipl.-Ing. (FH) Markus Lickes | Handelsregister Mainz HRB 4656 |
Finanzamt Mainz | St.Nr. 266500608, DE 149059855

From ck.hu at mediatek.com  Wed Feb 21 23:43:50 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 22 Feb 2024 07:43:50 +0000
Subject: [PATCH v2 2/3] Subject: [PATCH] drm/mediatek/dp: Add HDCP2.x
 feature for DisplayPort
In-Reply-To: <20240205055055.25340-3-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
	 <20240205055055.25340-3-mac.shen@mediatek.com>
Message-ID: <715a89642e1412a199ba07539666950794922faf.camel@mediatek.com>

Hi, Mac:

On Mon, 2024-02-05 at 13:50 +0800, mac.shen wrote:
> Add HDCP2.x feature for DisplayPort.
> When userspace request the kernel protect future content communicated
> over the link with Content_Protection property, the feature will do
> HDCP2.x authentication if the sink support HDCP2.X.
> 
> Changes in v2:
> - remove switch case, and refine code to make more clear
> - remove some definitions, and use the definitions in
>   include/drm/drm_hdcp.h
> - use the struct which defined in include/drm/drm_hdcp.h
> - do HDCP2.x authentication when userspace request the
>   kernel protect future content communicated
> per suggestion from the previous thread:
> https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
> 9218a545c46.camel at mediatek.com/
> 
> Signed-off-by: mac.shen <mac.shen at mediatek.com>
> ---

[snip]

> +
> +static bool dp_tx_hdcp2_write_msg(struct mtk_hdcp_info *hdcp_info,
> u8 cmd_ID)
> +{
> +	struct mtk_dp *mtk_dp = container_of(hdcp_info, struct mtk_dp,
> hdcp_info);
> +	bool ret = false;
> +

It seems no common part for each case, so I would like to separate each
case to an independent function.

Regards,
CK

> +	switch (cmd_ID) {
> +	case HDCP_2_2_AKE_INIT:
> +		tee_hdcp2_soft_rst(hdcp_info);
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_RTX_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.hdcp_tx.ake_init.r_tx, HDCP_2_2_RTX_LEN);
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_TXCAPS_OFFSET,
> +				  (void *)&hdcp_info-
> >hdcp2_info.hdcp_tx.tx_caps,
> +				  HDCP_2_2_TXCAPS_LEN);
> +
> +		ret = true;
> +		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_Init !\n");
> +		break;
> +
> +	case HDCP_2_2_AKE_NO_STORED_KM:
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_EKPUB_KM_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.hdcp_tx.no_stored_km.e_kpub_km,
> +				  HDCP_2_2_E_KPUB_KM_LEN);
> +
> +		ret = true;
> +
> +		DPTXHDCPMSG("2.x: HDCP_2_2_AKE_NO_STORED_KM !\n");
> +		break;
> +
> +	case HDCP_2_2_AKE_STORED_KM:
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_EKH_KM_WR_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.ake_stored_km.e_kh_km_m,
> +				  HDCP_2_2_E_KH_KM_LEN);
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_M_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.ake_stored_km.e_kh_km_m +
> +				  HDCP_2_2_E_KH_KM_LEN,
> +				  HDCP_2_2_E_KH_KM_M_LEN -
> HDCP_2_2_E_KH_KM_LEN);
> +
> +		ret = true;
> +
> +		DPTXHDCPMSG("2.x: DPTX_HDCP_2_2_AKE_STORED_KM !\n");
> +		break;
> +
> +	case HDCP_2_2_LC_INIT:
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_RN_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.hdcp_tx.lc_init.r_n, HDCP_2_2_RN_LEN);
> +
> +		hdcp_info->hdcp2_info.read_l_prime = true;
> +		ret = true;
> +
> +		DPTXHDCPMSG("2.x: HDCP_2_2_LC_INIT !\n");
> +		break;
> +
> +	case HDCP_2_2_SKE_SEND_EKS:
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_EDKEY_KS_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.hdcp_tx.send_eks.e_dkey_ks,
> +				  HDCP_2_2_E_DKEY_KS_LEN);
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_RIV_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.hdcp_tx.send_eks.riv, HDCP_2_2_RIV_LEN);
> +
> +		hdcp_info->hdcp2_info.ks_exchange_done = true;
> +
> +		ret = true;
> +		DPTXHDCPMSG("2.x: HDCP_2_2_SKE_SEND_EKS !\n");
> +		break;
> +
> +	case HDCP_2_2_STREAM_TYPE:
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.hdcp_tx.stream_id_type, 1);
> +
> +		ret = true;
> +		DPTXHDCPMSG("HDCP2_MSG_DP_STREAM_TYPE !\n");
> +		break;
> +
> +	case HDCP_2_2_REP_SEND_ACK:
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_V_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.hdcp_tx.send_ack.v,
> +				  HDCP_2_2_V_PRIME_HALF_LEN);
> +
> +		ret = true;
> +		DPTXHDCPMSG("2.x: HDCP_2_2_SEND_ACK !\n");
> +		break;
> +
> +	case HDCP_2_2_REP_STREAM_MANAGE:
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_SEQ_NUM_M_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.hdcp_tx.stream_manage.seq_num_m,
> +				  HDCP_2_2_SEQ_NUM_LEN);
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_K_OFFSET,
> +				  hdcp_info->hdcp2_info.hdcp_tx.k,
> HDCP2_K_LEN);
> +		drm_dp_dpcd_write(&mtk_dp->aux,
> DP_HDCP_2_2_REG_STREAM_ID_TYPE_OFFSET,
> +				  hdcp_info-
> >hdcp2_info.hdcp_tx.stream_id_type,
> +				  HDCP2_STREAMID_TYPE_LEN);
> +
> +		dp_tx_hdcp2_fill_stream_type(hdcp_info, hdcp_info-
> >hdcp2_info.stream_id_type);
> +
> +		ret = true;
> +		DPTXHDCPMSG("2.x: HDCP_2_2_STREAM_MANAGE !\n");
> +		break;
> +
> +	default:
> +		DPTXHDCPMSG("2.x: Invalid HDCP2_OffSETADDR_WriteMessage
> !\n");
> +		break;
> +	}
> +
> +	return ret;
> +}

From krzysztof.kozlowski at linaro.org  Wed Feb 21 23:45:24 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 08:45:24 +0100
Subject: [PATCH 00/16] clk: samsung: Add CPU clocks for Exynos850
In-Reply-To: <CAPLW+4kmoCoqO=+zXbVw7VsGc-VB2At91ZnJfyTDRtVFmN4aiQ@mail.gmail.com>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
 <29090d97-9118-4765-a4fd-3bbe271a39bd@linaro.org>
 <CAPLW+4kmoCoqO=+zXbVw7VsGc-VB2At91ZnJfyTDRtVFmN4aiQ@mail.gmail.com>
Message-ID: <5f1ae281-7b81-49a6-82a6-37be20ea43e3@linaro.org>

On 22/02/2024 00:07, Sam Protsenko wrote:
> On Tue, Feb 20, 2024 at 5:07?AM Krzysztof Kozlowski
> <krzysztof.kozlowski at linaro.org> wrote:
>>
>> On 16/02/2024 23:32, Sam Protsenko wrote:
>>> The series implements CPU clock support for Exynos850, adds CPU CMUs to
>>> the clock driver and enables those in dts. This is the first step
>>> towards cpufreq implementation.
>>>
>>> The breakup by patch:
>>>
>>>   * Patch 01: Add bindings
>>>   * Patches 02..12: Prepare clk-cpu.c for Exynos850 support
>>>   * Patch 13: Add Exynos850 support
>>>   * Patch 14: Init PLLs to be in manual mode
>>>   * Patch 15: Add CPU CMUs in Exynos850 clock driver
>>>   * Patch 16: Add CPU CMUs and clocks in Exynos850 dtsi
>>
>> This crossed the threshold for a patch bomb, which is in general fine
>> for me, but then please put v2 changelog in each patch's changelog. If
>> the patch did not change, annotate it as well. It's not possible to keep
>> jumping between cover letter and individual patches.
>>
> 
> The above list is not a change log, I just tried to show that patches
> 02..12 are cleanups. I'll reword this in v2 to make it less confusing.
> And as usual I'll keep the changelog for each patch separately. Thanks
> for the review!

I know. I just wanted to clarify my expectations for v2.

Best regards,
Krzysztof



From frieder.schrempf at kontron.de  Wed Feb 21 23:45:15 2024
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Thu, 22 Feb 2024 08:45:15 +0100
Subject: [PATCH 1/4] arm64: dts: imx8mp-phyboard-pollux: Add and update
 rtc devicetree node
In-Reply-To: <79668325838f6699c74488cbe1f1717cb56d0c94.camel@phytec.de>
References: <20240221141235.47639-1-y.varakala@phytec.de>
 <20240221141235.47639-2-y.varakala@phytec.de>
 <bae6a26a-a46c-445f-b44f-32d50146e36e@kontron.de>
 <79668325838f6699c74488cbe1f1717cb56d0c94.camel@phytec.de>
Message-ID: <f0bf8584-75c7-4dec-a9b3-ef86f03d7e37@kontron.de>

On 22.02.24 08:37, Teresa Remmet wrote:
> Hello Frieder,
> 
> Am Mittwoch, dem 21.02.2024 um 15:29 +0100 schrieb Frieder Schrempf:
>> On 21.02.24 15:12, Yashwanth Varakala wrote:
>>> [Sie erhalten nicht h?ufig E-Mails von y.varakala at phytec.de.
>>> Weitere Informationen, warum dies wichtig ist, finden Sie unter
>>> https://aka.ms/LearnAboutSenderIdentification?]
>>>
>>> The interrupt of the rtc is connected on the carrierboard
>>
>> s/rtc/RTC/
>> s/carrierboard/carrier board/
>>
>>> phyBOARD-i.MX8MP-Pollux.
>>>
>>> RTC trickle-charger and level-switching-mode device tree properties
>>> are depended on the phyboard-pollux design.
>>
>> There is no way to control the backup switching mode via devicetree,
>> so
>> this description doesn't match the code.
> 
> this is correct. We had a down stream property handling this. 
> This is why it probably sneaked in. It should be dropped.
> 
>>
>> Also "are depended on" should probably be "depend on" or "are
>> dependent
>> on". And when you scratch the "level-switching-mode" it's singular of
>> course.
>>
>>>
>>> Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
>>> ---
>>> ?.../dts/freescale/imx8mp-phyboard-pollux-rdk.dts? | 15
>>> +++++++++++++++
>>> ?.../boot/dts/freescale/imx8mp-phycore-som.dtsi??? |? 1 -
>>> ?2 files changed, 15 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-
>>> rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-
>>> rdk.dts
>>> index c8640cac3edc..96754ce633ed 100644
>>> --- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
>>> +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
>>> @@ -139,6 +139,15 @@ &snvs_pwrkey {
>>> ??????? status = "okay";
>>> ?};
>>>
>>> +&rv3028 {
>>> +?????? pinctrl-names = "default";
>>> +?????? pinctrl-0 = <&pinctrl_rtc>;
>>> +?????? interrupt-parent = <&gpio4>;
>>> +?????? interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
>>
>> The RTC is on the SoM and the interrupt line is routed from the SoM
>> to
>> the carrier board and then back to the SoC? Is this really the case?
> 
> Yes, this is really the case. 
> 
> 
>> I
>> would expect the IRQ to be routed within the SoM.
> 
> 
> It was done to give the carrier board designer more freedom with the
> alarm pin of the RTC.

Ok, thanks for confirming!


From krzysztof.kozlowski at linaro.org  Wed Feb 21 23:47:01 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 08:47:01 +0100
Subject: [PATCH 11/16] clk: samsung: Keep register offsets in chip
 specific structure
In-Reply-To: <CAPLW+4=kpk=Vg=nX-hVxcCS0OttC6xmyUcB005tmX+vtUF9TLA@mail.gmail.com>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
 <20240216223245.12273-12-semen.protsenko@linaro.org>
 <ce515530-428a-4a21-8c56-5a497cc8130a@linaro.org>
 <CAPLW+4=kpk=Vg=nX-hVxcCS0OttC6xmyUcB005tmX+vtUF9TLA@mail.gmail.com>
Message-ID: <c4f7e3cb-db9b-48be-883e-33878d2510e8@linaro.org>

On 22/02/2024 01:42, Sam Protsenko wrote:
> On Tue, Feb 20, 2024 at 5:04?AM Krzysztof Kozlowski
> <krzysztof.kozlowski at linaro.org> wrote:
>>
>> On 16/02/2024 23:32, Sam Protsenko wrote:
>>> Abstract CPU clock registers by keeping their offsets in a dedicated
>>> chip specific structure to accommodate for oncoming Exynos850 support,
>>> which has different offsets for cluster 0 and cluster 1. This rework
>>> also makes it possible to use exynos_set_safe_div() for all chips, so
>>> exynos5433_set_safe_div() is removed here to reduce the code
>>> duplication.
>>>
>>
>> So that's the answer why you could not use flags anymore - you need an
>> enum, not a bitmap. Such short explanation should be in previous commits
>> justifying moving reg layout to new property.
> 
> Will do, thanks.
> 
>>
>>> No functional change.
>>>
>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>>> ---
>>>  drivers/clk/samsung/clk-cpu.c | 156 +++++++++++++++++++---------------
>>>  1 file changed, 86 insertions(+), 70 deletions(-)
>>>
>>> diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
>>> index 04394d2166c9..744b609c222d 100644
>>> --- a/drivers/clk/samsung/clk-cpu.c
>>> +++ b/drivers/clk/samsung/clk-cpu.c
>>> @@ -44,12 +44,14 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
>>>
>>>  /**
>>>   * struct exynos_cpuclk_chip - Chip specific data for CPU clock
>>> + * @regs: register offsets for CPU related clocks
>>>   * @pre_rate_cb: callback to run before CPU clock rate change
>>>   * @post_rate_cb: callback to run after CPU clock rate change
>>>   */
>>>  struct exynos_cpuclk_chip {
>>> -     exynos_rate_change_fn_t pre_rate_cb;
>>> -     exynos_rate_change_fn_t post_rate_cb;
>>> +     const void                              * const regs;
>>
>> Why this is void?
>>
> 
> Different chips can have very different register layout. For example,
> older Exynos chips usually keep multiple CPU divider ratios in one
> single register, whereas more modern chips have a dedicated register
> for each divider clock. Also, old chips usually split divider ratio vs
> DIV clock status between different registers, but in modern chips they
> both live in one single register. Having (void *) makes it possible to
> keep pointers to different structures, and each function for the
> particular chip can "know" which exactly structure is stored there,
> casting (void *) to a needed type. Another way to do that would be to
> have "one-size-fits-all" structure with all possible registers for all
> possible chips. I don't know, I just didn't like that for a couple of
> reasons, so decided to go with (void *).
> 
> I'll add some explanation in the commit message in v2.

Currently the one-size-fits-all seems feasible, even if few fields are
not matching, so I would prefer to go this approach.

Best regards,
Krzysztof



From huqiang.qin at amlogic.com  Wed Feb 21 23:46:36 2024
From: huqiang.qin at amlogic.com (Huqiang Qin)
Date: Thu, 22 Feb 2024 15:46:36 +0800
Subject: [RESEND PATCH 0/3] Add GPIO interrupt support for Amlogic-T7 SoCs
Message-ID: <20240222074640.1866284-1-huqiang.qin@amlogic.com>

This patch adds GPIO interrupt support for Amloigc-T7 SoC (A311D2)

Huqiang Qin (3):
  dt-bindings: interrupt-controller: Add support for Amlogic-T7 SoCs
  irqchip: Add support for Amlogic-T7 SoCs
  arm64: dts: Add gpio_intc node for Amlogic-T7 SoCs

 .../interrupt-controller/amlogic,meson-gpio-intc.yaml  |  1 +
 arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi            | 10 ++++++++++
 drivers/irqchip/irq-meson-gpio.c                       |  5 +++++
 3 files changed, 16 insertions(+)

-- 
2.42.0



From huqiang.qin at amlogic.com  Wed Feb 21 23:46:37 2024
From: huqiang.qin at amlogic.com (Huqiang Qin)
Date: Thu, 22 Feb 2024 15:46:37 +0800
Subject: [RESEND PATCH 1/3] dt-bindings: interrupt-controller: Add support for Amlogic-T7 SoCs
In-Reply-To: <20240222074640.1866284-1-huqiang.qin@amlogic.com>
References: <20240222074640.1866284-1-huqiang.qin@amlogic.com>
Message-ID: <20240222074640.1866284-2-huqiang.qin@amlogic.com>

Update dt-binding document for GPIO interrupt controller
of Amlogic-T7 SoCs.

Signed-off-by: Huqiang Qin <huqiang.qin at amlogic.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
 .../bindings/interrupt-controller/amlogic,meson-gpio-intc.yaml   | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.yaml
index 3d06db98e978..a93744763787 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.yaml
@@ -36,6 +36,7 @@ properties:
               - amlogic,meson-a1-gpio-intc
               - amlogic,meson-s4-gpio-intc
               - amlogic,c3-gpio-intc
+              - amlogic,t7-gpio-intc
           - const: amlogic,meson-gpio-intc
 
   reg:
-- 
2.42.0



From huqiang.qin at amlogic.com  Wed Feb 21 23:46:38 2024
From: huqiang.qin at amlogic.com (Huqiang Qin)
Date: Thu, 22 Feb 2024 15:46:38 +0800
Subject: [RESEND PATCH 2/3] irqchip: Add support for Amlogic-T7 SoCs
In-Reply-To: <20240222074640.1866284-1-huqiang.qin@amlogic.com>
References: <20240222074640.1866284-1-huqiang.qin@amlogic.com>
Message-ID: <20240222074640.1866284-3-huqiang.qin@amlogic.com>

The Amlogic-T7 SoCs support 12 GPIO IRQ lines compared with previous
serial chips and have something different, details are as below.

IRQ Number:
- 156      1 pin  on bank TESTN
- 155:148  8 pins on bank H
- 147:129 19 pins on bank Y
- 128:115 14 pins on bank M
- 114:91  24 pins on bank T
- 90:77   14 pins on bank Z
- 76:70    7 pins on bank E
- 69:57   13 pins on bank D
- 56:40   17 pins on bank W
- 39:20   20 pins on bank X
- 19:13    7 pins on bank C
- 12:0    13 pins on bank B

Signed-off-by: Huqiang Qin <huqiang.qin at amlogic.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 drivers/irqchip/irq-meson-gpio.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index f88df39f4129..9a1791908598 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -154,6 +154,10 @@ static const struct meson_gpio_irq_params c3_params = {
 	INIT_MESON_S4_COMMON_DATA(55)
 };
 
+static const struct meson_gpio_irq_params t7_params = {
+	INIT_MESON_S4_COMMON_DATA(157)
+};
+
 static const struct of_device_id meson_irq_gpio_matches[] __maybe_unused = {
 	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
 	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
@@ -165,6 +169,7 @@ static const struct of_device_id meson_irq_gpio_matches[] __maybe_unused = {
 	{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
 	{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
 	{ .compatible = "amlogic,c3-gpio-intc", .data = &c3_params },
+	{ .compatible = "amlogic,t7-gpio-intc", .data = &t7_params },
 	{ }
 };
 
-- 
2.42.0



From huqiang.qin at amlogic.com  Wed Feb 21 23:46:39 2024
From: huqiang.qin at amlogic.com (Huqiang Qin)
Date: Thu, 22 Feb 2024 15:46:39 +0800
Subject: [RESEND PATCH 3/3] arm64: dts: Add gpio_intc node for Amlogic-T7 SoCs
In-Reply-To: <20240222074640.1866284-1-huqiang.qin@amlogic.com>
References: <20240222074640.1866284-1-huqiang.qin@amlogic.com>
Message-ID: <20240222074640.1866284-4-huqiang.qin@amlogic.com>

Add GPIO interrupt controller device.

Signed-off-by: Huqiang Qin <huqiang.qin at amlogic.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---
 arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index ad1cac42e9d8..5248bdf824ea 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -171,6 +171,16 @@ gpio: bank at 4000 {
 				};
 			};
 
+			gpio_intc: interrupt-controller at 4080 {
+				compatible = "amlogic,t7-gpio-intc",
+					     "amlogic,meson-gpio-intc";
+				reg = <0x0 0x4080 0x0 0x20>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				amlogic,channel-interrupts =
+					<10 11 12 13 14 15 16 17 18 19 20 21>;
+			};
+
 			uart_a: serial at 78000 {
 				compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
 				reg = <0x0 0x78000 0x0 0x18>;
-- 
2.42.0



From maxime.chevallier at bootlin.com  Wed Feb 21 23:49:48 2024
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Thu, 22 Feb 2024 08:49:48 +0100
Subject: [PATCH net-next v8 08/13] netlink: specs: add ethnl PHY_GET
 command set
In-Reply-To: <20240221170023.452a01ca@kernel.org>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
	<20240220184217.3689988-9-maxime.chevallier@bootlin.com>
	<20240221170023.452a01ca@kernel.org>
Message-ID: <20240222084948.16f33760@device-28.home>

Hello Jakub,

On Wed, 21 Feb 2024 17:00:23 -0800
Jakub Kicinski <kuba at kernel.org> wrote:

> On Tue, 20 Feb 2024 19:42:11 +0100 Maxime Chevallier wrote:
> > +      -
> > +        name: upstream-phy-index
> > +        type: u32  
> 
> The C define appears to be called:
> 
> 	ETHTOOL_A_PHY_UPSTREAM_INDEX,		/* u32 */
> 
> either it needs to gain the PHY_ or the spec needs to lose the phy-,
> otherwise C code gen gets upset:

I'll do it, sorry about that.

> 
> ethtool-user.c:689:10: error: ?ETHTOOL_A_PHY_UPSTREAM_PHY_INDEX? undeclared here (not in a function); did you mean ?ETHTOOL_A_PHY_UPSTREAM_INDEX??
>   689 |         [ETHTOOL_A_PHY_UPSTREAM_PHY_INDEX] = { .name = "upstream-phy-index", .type = YNL_PT_U32, },
>       |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>       |          ETHTOOL_A_PHY_UPSTREAM_INDEX
> 
> Unfortunately ethtool in the in-between state where we can auto-gen
> user space code (or rather most of it) but the uAPI header is not
> auto-generated so we need to take extra care to keep things in sync :(

Is there anything I run for testing, so that I can make sure this
doesn't happen again ?

Thanks,

Maxime



From sudeep.holla at arm.com  Wed Feb 21 23:50:35 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 07:50:35 +0000
Subject: [PATCH v2] firmware: arm_scmi: Warn if domain frequency multiplier is 0 or rounded off
In-Reply-To: <20240119152338.3047620-1-sudeep.holla@arm.com>
References: <20240119111033.3011853-1-sudeep.holla@arm.com> <20240119152338.3047620-1-sudeep.holla@arm.com>
Message-ID: <170858819226.106232.14171883379390230521.b4-ty@arm.com>

On Fri, 19 Jan 2024 15:23:37 +0000, Sudeep Holla wrote:
> When (sustained_freq_khz * 1000) is less than sustained_perf_level, the
> multiplier will be less than 1 and hence rounded down as 0. Similarly if
> it is not multiple of sustained_perf_level the dom_info->mult_factor will
> contain rounded down value and will end up impacting all the frequency
> calculations done using it.
>
> Add warning if and when the domain frequency multiplier is 0 or rounded
> down so that it gives a clue to get the firmware tables fixed.
>
> [...]

Applied to sudeep.holla/linux (for-next/scmi/updates), thanks!

[1/1] firmware: arm_scmi: Warn if domain frequency multiplier is 0 or rounded off
      https://git.kernel.org/sudeep.holla/c/534224b958df
--
Regards,
Sudeep



From ck.hu at mediatek.com  Wed Feb 21 23:51:34 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Thu, 22 Feb 2024 07:51:34 +0000
Subject: [PATCH v2 2/3] Subject: [PATCH] drm/mediatek/dp: Add HDCP2.x
 feature for DisplayPort
In-Reply-To: <20240205055055.25340-3-mac.shen@mediatek.com>
References: <20240205055055.25340-1-mac.shen@mediatek.com>
	 <20240205055055.25340-3-mac.shen@mediatek.com>
Message-ID: <3d96e1d4f851008d822e6bf978107530ef1e2841.camel@mediatek.com>

Hi, Mac:

On Mon, 2024-02-05 at 13:50 +0800, mac.shen wrote:
> Add HDCP2.x feature for DisplayPort.
> When userspace request the kernel protect future content communicated
> over the link with Content_Protection property, the feature will do
> HDCP2.x authentication if the sink support HDCP2.X.
> 
> Changes in v2:
> - remove switch case, and refine code to make more clear
> - remove some definitions, and use the definitions in
>   include/drm/drm_hdcp.h
> - use the struct which defined in include/drm/drm_hdcp.h
> - do HDCP2.x authentication when userspace request the
>   kernel protect future content communicated
> per suggestion from the previous thread:
> https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
> 9218a545c46.camel at mediatek.com/
> 
> Signed-off-by: mac.shen <mac.shen at mediatek.com>
> ---

[snip]

> +
> +static void dp_tx_hdcp2_err_handle(struct mtk_hdcp_info *hdcp_info,
> int err_msg, int line)
> +{
> +	pr_err("2.x: MainState:%d; SubState:%d;\n", hdcp_info-
> >hdcp2_info.hdcp_handler.main_state,
> +	       hdcp_info->hdcp2_info.hdcp_handler.sub_state);
> +
> +	switch (err_msg) {
> +	case HDCP_ERR_UNKNOWN_STATE:
> +		pr_err("2.x: Unknown State, line:%d\n", line);
> +		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_H1P1,
> HDCP_2_2_AUTH_FAIL);

For each case, you just print error message and set state. It seems not
necessary to group these cases. Where error happen, just print message
there and set state there. And not print line, you should print what
the error is.

Regards,
CK

> +		break;
> +
> +	case HDCP_ERR_SEND_MSG_FAIL:
> +		pr_err("2.x: Send Msg Fail, line:%d\n", line);
> +		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0,
> HDCP_2_2_NULL_MSG);
> +		break;
> +	case HDCP_ERR_RESPONSE_TIMEROUT:
> +		pr_err("2.x: Response Timeout, line:%d!\n", line);
> +		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0,
> HDCP_2_2_NULL_MSG);
> +		break;
> +
> +	case HDCP_ERR_PROCESS_FAIL:
> +		pr_err("2.x: Process Fail, line:%d!\n", line);
> +		dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A0F0,
> HDCP_2_2_NULL_MSG);
> +		break;
> +
> +	default:
> +		pr_err("2.x: NO ERROR!");
> +		break;
> +	}
> +}

From sudeep.holla at arm.com  Wed Feb 21 23:54:24 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 07:54:24 +0000
Subject: [PATCH] firmware: arm_scmi: Rework Clock domains info lookups
In-Reply-To: <20240110120916.2482603-1-cristian.marussi@arm.com>
References: <20240110120916.2482603-1-cristian.marussi@arm.com>
Message-ID: <170858826800.106333.5043612997177254784.b4-ty@arm.com>

On Wed, 10 Jan 2024 12:09:16 +0000, Cristian Marussi wrote:
> Accessing Clock domains descriptors by the index from the SCMI drivers
> can potentially lead to out-of-bound violations if the SCMI drivers
> misbehaves.
>
> Use a common helper to check the consistency of such accesses.
>
>
> [...]

Applied to sudeep.holla/linux (for-next/scmi/updates), thanks!

[1/1] firmware: arm_scmi: Rework Clock domains info lookups
      https://git.kernel.org/sudeep.holla/c/dea893a66cd5
--
Regards,
Sudeep



From sudeep.holla at arm.com  Wed Feb 21 23:55:33 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 07:55:33 +0000
Subject: [PATCH] firmware: arm_scmi: Add multiple protocols registration support
In-Reply-To: <20231221151129.325749-1-cristian.marussi@arm.com>
References: <20231221151129.325749-1-cristian.marussi@arm.com>
Message-ID: <170858849685.106442.17247883098371557562.b4-ty@arm.com>

On Thu, 21 Dec 2023 15:11:29 +0000, Cristian Marussi wrote:
> Add the capability for one SCMI driver to register with the core SCMI stack
> to use multiple SCMI protocols: in such a case the SCMI driver probe
> function will end up being called once for each registered protocol which
> have been also found as implemented on the platform.
>
> This is especially useful in testing scenarios.
>
> [...]

Applied to sudeep.holla/linux (for-next/scmi/updates), thanks!

[1/1] firmware: arm_scmi: Add multiple protocols registration support
      https://git.kernel.org/sudeep.holla/c/2858f6e5f064
--
Regards,
Sudeep



From o.rempel at pengutronix.de  Wed Feb 21 23:56:00 2024
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Thu, 22 Feb 2024 08:56:00 +0100
Subject: [PATCH v3] i2c: imx: when being a target, mark the last read as
 processed
In-Reply-To: <ZdZ_PsNhQ9S1Eab-@shikoro>
References: <20240221193013.14233-2-wsa+renesas@sang-engineering.com>
 <kgfagzj5vez56levwam6n6tzxl2lu7efnw5x3eadl3uophxism@ph2tghrvedg5>
 <ZdZ_PsNhQ9S1Eab-@shikoro>
Message-ID: <Zdb-EHnTiez6KP-K@pengutronix.de>

Hi Wolfram,

On Wed, Feb 21, 2024 at 11:54:54PM +0100, Wolfram Sang wrote:
> On Wed, Feb 21, 2024 at 09:58:23PM +0100, Andi Shyti wrote:
> > Hi Wolfram and Corey,
> > 
> > On Wed, Feb 21, 2024 at 08:27:13PM +0100, Wolfram Sang wrote:
> > > From: Corey Minyard <minyard at acm.org>
> > > 
> > > When being a target, NAK from the controller means that all bytes have
> > > been transferred. So, the last byte needs also to be marked as
> > > 'processed'. Otherwise index registers of backends may not increase.
> > > 
> > > Signed-off-by: Corey Minyard <minyard at acm.org>
> > > Tested-by: Andrew Manley <andrew.manley at sealingtech.com>
> > > Reviewed-by: Andrew Manley <andrew.manley at sealingtech.com>
> > > Reviewed-by: Oleksij Rempel <o.rempel at pengutronix.de>
> > > [wsa: fixed comment and commit message to properly describe the case]
> > > Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
> > 
> > is this a fix?
> 
> In deed, it is:
> 
> Fixes: f7414cd6923f ("i2c: imx: support slave mode for imx I2C driver")

Looks good :)
Are any action needed on my side?

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 sudeep.holla at arm.com  Wed Feb 21 23:57:27 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 07:57:27 +0000
Subject: [PATCH] firmware: arm_scmi: fix double free in smc cleanup path
In-Reply-To: <20240126122325.2039669-1-andre.przywara@arm.com>
References: <20240126122325.2039669-1-andre.przywara@arm.com>
Message-ID: <170858859374.106562.8183631887743483435.b4-ty@arm.com>

On Fri, 26 Jan 2024 12:23:25 +0000, Andre Przywara wrote:
> When the generic SCMI code tears down a channel, it calls the chan_free
> callback function, defined by each transport. Since multiple protocols
> might share the same transport_info member, chan_free() might want to
> clean up the same member multiple times. This will lead to a NULL
> pointer dereference at the second time:
> 
> [    9.788824] scmi_protocol scmi_dev.1: Enabled polling mode TX channel - prot_id:16
> [    9.813091] arm-scmi firmware:scmi: SCMI Notifications - Core Enabled.
> [    9.814485] arm-scmi firmware:scmi: unable to communicate with SCMI
> [    9.824996] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
> [    9.825586] Mem abort info:
> [    9.825863]   ESR = 0x0000000096000004
> [    9.826193]   EC = 0x25: DABT (current EL), IL = 32 bits
> [    9.827625]   SET = 0, FnV = 0
> [    9.827927]   EA = 0, S1PTW = 0
> [    9.828232]   FSC = 0x04: level 0 translation fault
> [    9.828628] Data abort info:
> [    9.828909]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
> [    9.829333]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> [    9.829745]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> [    9.830170] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000881ef8000
> [    9.830887] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000
> [    9.831763] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
> [    9.832177] Modules linked in:
> [    9.832440] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 6.7.0-rc2-00124-g455ef3d016c9-dirty #793
> [    9.832997] Hardware name: FVP Base RevC (DT)
> [    9.833302] pstate: 61400009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
> [    9.833775] pc : smc_chan_free+0x3c/0x6c
> [    9.834089] lr : smc_chan_free+0x3c/0x6c
> [    9.834401] sp : ffff8000839bba00
> [    9.834652] x29: ffff8000839bba00 x28: 00000000ffffffa1 x27: ffff0008024aa350
> [    9.835227] x26: ffff800083305898 x25: ffff0008004d4a18 x24: ffff000800328000
> [    9.835804] x23: ffff0008024aa1b0 x22: 0000000000000000 x21: 000000007fffffff
> [    9.836375] x20: 0000000000000000 x19: ffff000802639440 x18: 0000000000000010
> [    9.836945] x17: 73203e3d20293062 x16: 3161613432303830 x15: 303066666666202c
> [    9.837522] x14: 00000000000001f4 x13: ffff000800328488 x12: 00000000ffffffea
> [    9.838094] x11: 00000000ffff7fff x10: 00000000ffff7fff x9 : ffff800082f3b430
> [    9.838667] x8 : 00000000000bffe8 x7 : c0000000ffff7fff x6 : 000000000005fff4
> [    9.839237] x5 : 00000000002bffa8 x4 : 0000000000000000 x3 : 0000000000000000
> [    9.839803] x2 : 0000000000000000 x1 : 0000000000000000 x0 : 000000000000004a
> [    9.840368] Call trace:
> [    9.840571]  smc_chan_free+0x3c/0x6c
> [    9.840868]  idr_for_each+0x68/0xf8
> [    9.841164]  scmi_cleanup_channels.isra.0+0x2c/0x58
> [    9.841543]  scmi_probe+0x434/0x734
> [    9.841848]  platform_probe+0x68/0xd8
> [    9.842164]  really_probe+0x110/0x27c
> [    9.842464]  __driver_probe_device+0x78/0x12c
> [    9.842801]  driver_probe_device+0x3c/0x118
> [    9.843130]  __driver_attach+0x74/0x128
> [    9.843439]  bus_for_each_dev+0x78/0xe0
> [    9.843783]  driver_attach+0x24/0x30
> [    9.844121]  bus_add_driver+0xe4/0x1e8
> [    9.844466]  driver_register+0x60/0x128
> [    9.844778]  __platform_driver_register+0x28/0x34
> [    9.845149]  scmi_driver_init+0x84/0xc0
> [    9.845459]  do_one_initcall+0x78/0x33c
> [    9.845778]  kernel_init_freeable+0x2b8/0x51c
> [    9.846127]  kernel_init+0x24/0x130
> [    9.846426]  ret_from_fork+0x10/0x20
> [    9.846772] Code: f0004701 910a0021 aa1403e5 97b91c70 (b9400280)
> [    9.847172] ---[ end trace 0000000000000000 ]---
> [    9.847604] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
>
> [...]

Applied to sudeep.holla/linux (for-next/scmi/updates), thanks!

[1/1] firmware: arm_scmi: fix double free in smc cleanup path
      https://git.kernel.org/sudeep.holla/c/f1d71576d2c9
--
Regards,
Sudeep



From bhe at redhat.com  Wed Feb 21 23:57:30 2024
From: bhe at redhat.com (Baoquan He)
Date: Thu, 22 Feb 2024 15:57:30 +0800
Subject: [PATCH v2 02/14] crash: split vmcoreinfo exporting code out from
 crash_core.c
In-Reply-To: <75c77583-6253-4d32-8daf-0e86a2cad226@linux.ibm.com>
References: <20240119145241.769622-1-bhe@redhat.com>
 <20240119145241.769622-3-bhe@redhat.com>
 <75c77583-6253-4d32-8daf-0e86a2cad226@linux.ibm.com>
Message-ID: <Zdb+arQ6w2I5A8A2@MiWiFi-R3L-srv>

On 02/21/24 at 11:07pm, Sourabh Jain wrote:
> Hello Baoquan,
> 
> On 19/01/24 20:22, Baoquan He wrote:
> > Now move the relevant codes into separate files:
> > kernel/crash_reserve.c, include/linux/crash_reserve.h.
> > 
> > And add config item CRASH_RESERVE to control its enabling.
> 
> Feels like this patch is more about vmcore_info.[c|h] and CONFIG_VMCORE_INFO
> then the above mentioned files and config.

You are right. Above lines about crash_reserve should be removed. It's
from v1, and done in patch 1 of v2 and v3. I forgot removing them.

> 
> > 
> > And also update the old ifdeffery of CONFIG_CRASH_CORE, including of
> > <linux/crash_core.h> and config item dependency on CRASH_CORE
> > accordingly.
> > 
> > And also do renaming as follows:
> >   - arch/xxx/kernel/{crash_core.c => vmcore_info.c}
> > because they are only related to vmcoreinfo exporting on x86, arm64,
> > riscv.
> > 
> > And also Remove config item CRASH_CORE, and rely on CONFIG_KEXEC_CORE to
> > decide if build in crash_core.c.
> > 
> > Signed-off-by: Baoquan He <bhe at redhat.com>
> > ---
> >   arch/arm64/kernel/Makefile                    |   2 +-
> >   .../kernel/{crash_core.c => vmcore_info.c}    |   2 +-
> >   arch/powerpc/Kconfig                          |   2 +-
> >   arch/powerpc/kernel/setup-common.c            |   2 +-
> >   arch/powerpc/platforms/powernv/opal-core.c    |   2 +-
> >   arch/riscv/kernel/Makefile                    |   2 +-
> >   .../kernel/{crash_core.c => vmcore_info.c}    |   2 +-
> >   arch/x86/kernel/Makefile                      |   2 +-
> >   .../{crash_core_32.c => vmcore_info_32.c}     |   2 +-
> >   .../{crash_core_64.c => vmcore_info_64.c}     |   2 +-
> >   drivers/firmware/qemu_fw_cfg.c                |  14 +-
> >   fs/proc/Kconfig                               |   2 +-
> >   fs/proc/kcore.c                               |   2 +-
> >   include/linux/buildid.h                       |   2 +-
> >   include/linux/crash_core.h                    |  73 ------
> >   include/linux/kexec.h                         |   1 +
> >   include/linux/vmcore_info.h                   |  81 ++++++
> >   kernel/Kconfig.kexec                          |   4 +-
> >   kernel/Makefile                               |   4 +-
> >   kernel/crash_core.c                           | 208 ----------------
> >   kernel/ksysfs.c                               |   6 +-
> >   kernel/printk/printk.c                        |   4 +-
> >   kernel/vmcore_info.c                          | 233 ++++++++++++++++++
> >   lib/buildid.c                                 |   2 +-
> >   24 files changed, 345 insertions(+), 311 deletions(-)
> >   rename arch/arm64/kernel/{crash_core.c => vmcore_info.c} (97%)
> >   rename arch/riscv/kernel/{crash_core.c => vmcore_info.c} (96%)
> >   rename arch/x86/kernel/{crash_core_32.c => vmcore_info_32.c} (90%)
> >   rename arch/x86/kernel/{crash_core_64.c => vmcore_info_64.c} (94%)
> >   create mode 100644 include/linux/vmcore_info.h
> >   create mode 100644 kernel/vmcore_info.c
> > 
> > diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> > index d95b3d6b471a..bcf89587a549 100644
> > --- a/arch/arm64/kernel/Makefile
> > +++ b/arch/arm64/kernel/Makefile
> > @@ -66,7 +66,7 @@ obj-$(CONFIG_KEXEC_FILE)		+= machine_kexec_file.o kexec_image.o
> >   obj-$(CONFIG_ARM64_RELOC_TEST)		+= arm64-reloc-test.o
> >   arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
> >   obj-$(CONFIG_CRASH_DUMP)		+= crash_dump.o
> > -obj-$(CONFIG_CRASH_CORE)		+= crash_core.o
> > +obj-$(CONFIG_VMCORE_INFO)		+= vmcore_info.o
> >   obj-$(CONFIG_ARM_SDE_INTERFACE)		+= sdei.o
> >   obj-$(CONFIG_ARM64_PTR_AUTH)		+= pointer_auth.o
> >   obj-$(CONFIG_ARM64_MTE)			+= mte.o
> > diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/vmcore_info.c
> > similarity index 97%
> > rename from arch/arm64/kernel/crash_core.c
> > rename to arch/arm64/kernel/vmcore_info.c
> > index 66cde752cd74..a5abf7186922 100644
> > --- a/arch/arm64/kernel/crash_core.c
> > +++ b/arch/arm64/kernel/vmcore_info.c
> > @@ -4,7 +4,7 @@
> >    * Copyright (C) Huawei Futurewei Technologies.
> >    */
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> >   #include <asm/cpufeature.h>
> >   #include <asm/memory.h>
> >   #include <asm/pgtable-hwdef.h>
> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> > index 6aeab95f0edd..1520146d7c2c 100644
> > --- a/arch/powerpc/Kconfig
> > +++ b/arch/powerpc/Kconfig
> > @@ -690,7 +690,7 @@ config ARCH_SELECTS_CRASH_DUMP
> >   config FA_DUMP
> >   	bool "Firmware-assisted dump"
> >   	depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
> > -	select CRASH_CORE
> > +	select VMCORE_INFO
> >   	select CRASH_RESERVE
> >   	select CRASH_DUMP
> >   	help
> > diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
> > index 9b142b9d5187..733f210ffda1 100644
> > --- a/arch/powerpc/kernel/setup-common.c
> > +++ b/arch/powerpc/kernel/setup-common.c
> > @@ -109,7 +109,7 @@ int ppc_do_canonicalize_irqs;
> >   EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
> >   #endif
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> >   /* This keeps a track of which one is the crashing cpu. */
> >   int crashing_cpu = -1;
> >   #endif
> > diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
> > index bb7657115f1d..c9a9b759cc92 100644
> > --- a/arch/powerpc/platforms/powernv/opal-core.c
> > +++ b/arch/powerpc/platforms/powernv/opal-core.c
> > @@ -16,7 +16,7 @@
> >   #include <linux/kobject.h>
> >   #include <linux/sysfs.h>
> >   #include <linux/slab.h>
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> >   #include <linux/of.h>
> >   #include <asm/page.h>
> > diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> > index c92c623b311e..63a36539ea1a 100644
> > --- a/arch/riscv/kernel/Makefile
> > +++ b/arch/riscv/kernel/Makefile
> > @@ -91,7 +91,7 @@ obj-$(CONFIG_KGDB)		+= kgdb.o
> >   obj-$(CONFIG_KEXEC_CORE)	+= kexec_relocate.o crash_save_regs.o machine_kexec.o
> >   obj-$(CONFIG_KEXEC_FILE)	+= elf_kexec.o machine_kexec_file.o
> >   obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
> > -obj-$(CONFIG_CRASH_CORE)	+= crash_core.o
> > +obj-$(CONFIG_VMCORE_INFO)	+= vmcore_info.o
> >   obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
> > diff --git a/arch/riscv/kernel/crash_core.c b/arch/riscv/kernel/vmcore_info.c
> > similarity index 96%
> > rename from arch/riscv/kernel/crash_core.c
> > rename to arch/riscv/kernel/vmcore_info.c
> > index 8706736fd4e2..e8ad57a60a2f 100644
> > --- a/arch/riscv/kernel/crash_core.c
> > +++ b/arch/riscv/kernel/vmcore_info.c
> > @@ -1,6 +1,6 @@
> >   // SPDX-License-Identifier: GPL-2.0-only
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> >   #include <linux/pagemap.h>
> >   void arch_crash_save_vmcoreinfo(void)
> > diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> > index 0000325ab98f..913d4022131e 100644
> > --- a/arch/x86/kernel/Makefile
> > +++ b/arch/x86/kernel/Makefile
> > @@ -98,7 +98,7 @@ obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
> >   obj-$(CONFIG_X86_TSC)		+= trace_clock.o
> >   obj-$(CONFIG_TRACING)		+= trace.o
> >   obj-$(CONFIG_RETHOOK)		+= rethook.o
> > -obj-$(CONFIG_CRASH_CORE)	+= crash_core_$(BITS).o
> > +obj-$(CONFIG_VMCORE_INFO)	+= vmcore_info_$(BITS).o
> >   obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
> >   obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
> >   obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
> > diff --git a/arch/x86/kernel/crash_core_32.c b/arch/x86/kernel/vmcore_info_32.c
> > similarity index 90%
> > rename from arch/x86/kernel/crash_core_32.c
> > rename to arch/x86/kernel/vmcore_info_32.c
> > index 8a89c109e20a..5995a749288a 100644
> > --- a/arch/x86/kernel/crash_core_32.c
> > +++ b/arch/x86/kernel/vmcore_info_32.c
> > @@ -1,6 +1,6 @@
> >   // SPDX-License-Identifier: GPL-2.0-only
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> >   #include <linux/pgtable.h>
> >   #include <asm/setup.h>
> > diff --git a/arch/x86/kernel/crash_core_64.c b/arch/x86/kernel/vmcore_info_64.c
> > similarity index 94%
> > rename from arch/x86/kernel/crash_core_64.c
> > rename to arch/x86/kernel/vmcore_info_64.c
> > index 7d255f882afe..0dec7d868754 100644
> > --- a/arch/x86/kernel/crash_core_64.c
> > +++ b/arch/x86/kernel/vmcore_info_64.c
> > @@ -1,6 +1,6 @@
> >   // SPDX-License-Identifier: GPL-2.0-only
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> >   #include <linux/pgtable.h>
> >   #include <asm/setup.h>
> > diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> > index 03da9a4354f8..5f43dfa22f79 100644
> > --- a/drivers/firmware/qemu_fw_cfg.c
> > +++ b/drivers/firmware/qemu_fw_cfg.c
> > @@ -37,7 +37,7 @@
> >   #include <uapi/linux/qemu_fw_cfg.h>
> >   #include <linux/delay.h>
> >   #include <linux/crash_dump.h>
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> >   MODULE_AUTHOR("Gabriel L. Somlo <somlo at cmu.edu>");
> >   MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
> > @@ -67,7 +67,7 @@ static void fw_cfg_sel_endianness(u16 key)
> >   		iowrite16(key, fw_cfg_reg_ctrl);
> >   }
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> >   static inline bool fw_cfg_dma_enabled(void)
> >   {
> >   	return (fw_cfg_rev & FW_CFG_VERSION_DMA) && fw_cfg_reg_dma;
> > @@ -156,7 +156,7 @@ static ssize_t fw_cfg_read_blob(u16 key,
> >   	return count;
> >   }
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> >   /* write chunk of given fw_cfg blob (caller responsible for sanity-check) */
> >   static ssize_t fw_cfg_write_blob(u16 key,
> >   				 void *buf, loff_t pos, size_t count)
> > @@ -195,7 +195,7 @@ static ssize_t fw_cfg_write_blob(u16 key,
> >   	return ret;
> >   }
> > -#endif /* CONFIG_CRASH_CORE */
> > +#endif /* CONFIG_VMCORE_INFO */
> >   /* clean up fw_cfg device i/o */
> >   static void fw_cfg_io_cleanup(void)
> > @@ -319,7 +319,7 @@ struct fw_cfg_sysfs_entry {
> >   	struct list_head list;
> >   };
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> >   static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f)
> >   {
> >   	static struct fw_cfg_vmcoreinfo *data;
> > @@ -343,7 +343,7 @@ static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f)
> >   	kfree(data);
> >   	return ret;
> >   }
> > -#endif /* CONFIG_CRASH_CORE */
> > +#endif /* CONFIG_VMCORE_INFO */
> >   /* get fw_cfg_sysfs_entry from kobject member */
> >   static inline struct fw_cfg_sysfs_entry *to_entry(struct kobject *kobj)
> > @@ -583,7 +583,7 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f)
> >   	int err;
> >   	struct fw_cfg_sysfs_entry *entry;
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> >   	if (fw_cfg_dma_enabled() &&
> >   		strcmp(f->name, FW_CFG_VMCOREINFO_FILENAME) == 0 &&
> >   		!is_kdump_kernel()) {
> > diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
> > index 32b1116ae137..d80a1431ef7b 100644
> > --- a/fs/proc/Kconfig
> > +++ b/fs/proc/Kconfig
> > @@ -32,7 +32,7 @@ config PROC_FS
> >   config PROC_KCORE
> >   	bool "/proc/kcore support" if !ARM
> >   	depends on PROC_FS && MMU
> > -	select CRASH_CORE
> > +	select VMCORE_INFO
> >   	help
> >   	  Provides a virtual ELF core file of the live kernel.  This can
> >   	  be read with gdb and other ELF tools.  No modifications can be
> > diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
> > index 6422e569b080..8e08a9a1b7ed 100644
> > --- a/fs/proc/kcore.c
> > +++ b/fs/proc/kcore.c
> > @@ -10,7 +10,7 @@
> >    *	Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar <kanoj at sgi.com>
> >    */
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> >   #include <linux/mm.h>
> >   #include <linux/proc_fs.h>
> >   #include <linux/kcore.h>
> > diff --git a/include/linux/buildid.h b/include/linux/buildid.h
> > index 8a582d242f06..20aa3c2d89f7 100644
> > --- a/include/linux/buildid.h
> > +++ b/include/linux/buildid.h
> > @@ -11,7 +11,7 @@ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
> >   		   __u32 *size);
> >   int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size);
> > -#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
> > +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_VMCORE_INFO)
> >   extern unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX];
> >   void init_vmlinux_build_id(void);
> >   #else
> > diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
> > index 1fde49246fa6..7f19f62018ef 100644
> > --- a/include/linux/crash_core.h
> > +++ b/include/linux/crash_core.h
> > @@ -6,79 +6,6 @@
> >   #include <linux/elfcore.h>
> >   #include <linux/elf.h>
> > -#define CRASH_CORE_NOTE_NAME	   "CORE"
> > -#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
> > -#define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
> > -#define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
> > -
> > -/*
> > - * The per-cpu notes area is a list of notes terminated by a "NULL"
> > - * note header.  For kdump, the code in vmcore.c runs in the context
> > - * of the second kernel to combine them into one note.
> > - */
> > -#define CRASH_CORE_NOTE_BYTES	   ((CRASH_CORE_NOTE_HEAD_BYTES * 2) +	\
> > -				     CRASH_CORE_NOTE_NAME_BYTES +	\
> > -				     CRASH_CORE_NOTE_DESC_BYTES)
> > -
> > -#define VMCOREINFO_BYTES	   PAGE_SIZE
> > -#define VMCOREINFO_NOTE_NAME	   "VMCOREINFO"
> > -#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
> > -#define VMCOREINFO_NOTE_SIZE	   ((CRASH_CORE_NOTE_HEAD_BYTES * 2) +	\
> > -				     VMCOREINFO_NOTE_NAME_BYTES +	\
> > -				     VMCOREINFO_BYTES)
> > -
> > -typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4];
> > -/* Per cpu memory for storing cpu states in case of system crash. */
> > -extern note_buf_t __percpu *crash_notes;
> > -
> > -void crash_update_vmcoreinfo_safecopy(void *ptr);
> > -void crash_save_vmcoreinfo(void);
> > -void arch_crash_save_vmcoreinfo(void);
> > -__printf(1, 2)
> > -void vmcoreinfo_append_str(const char *fmt, ...);
> > -phys_addr_t paddr_vmcoreinfo_note(void);
> > -
> > -#define VMCOREINFO_OSRELEASE(value) \
> > -	vmcoreinfo_append_str("OSRELEASE=%s\n", value)
> > -#define VMCOREINFO_BUILD_ID()						\
> > -	({								\
> > -		static_assert(sizeof(vmlinux_build_id) == 20);		\
> > -		vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \
> > -	})
> > -
> > -#define VMCOREINFO_PAGESIZE(value) \
> > -	vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
> > -#define VMCOREINFO_SYMBOL(name) \
> > -	vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
> > -#define VMCOREINFO_SYMBOL_ARRAY(name) \
> > -	vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name)
> > -#define VMCOREINFO_SIZE(name) \
> > -	vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> > -			      (unsigned long)sizeof(name))
> > -#define VMCOREINFO_STRUCT_SIZE(name) \
> > -	vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> > -			      (unsigned long)sizeof(struct name))
> > -#define VMCOREINFO_OFFSET(name, field) \
> > -	vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> > -			      (unsigned long)offsetof(struct name, field))
> > -#define VMCOREINFO_TYPE_OFFSET(name, field) \
> > -	vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> > -			      (unsigned long)offsetof(name, field))
> > -#define VMCOREINFO_LENGTH(name, value) \
> > -	vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
> > -#define VMCOREINFO_NUMBER(name) \
> > -	vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
> > -#define VMCOREINFO_CONFIG(name) \
> > -	vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
> > -
> > -extern unsigned char *vmcoreinfo_data;
> > -extern size_t vmcoreinfo_size;
> > -extern u32 *vmcoreinfo_note;
> > -
> > -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);
> > -
> >   /* Alignment required for elf header segment */
> >   #define ELF_CORE_HEADER_ALIGN   4096
> > diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> > index 6d79bfb52e5b..9c7bb8b56ed6 100644
> > --- a/include/linux/kexec.h
> > +++ b/include/linux/kexec.h
> > @@ -16,6 +16,7 @@
> >   #if !defined(__ASSEMBLY__)
> >   #include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> >   #include <linux/crash_reserve.h>
> >   #include <asm/io.h>
> >   #include <linux/range.h>
> > diff --git a/include/linux/vmcore_info.h b/include/linux/vmcore_info.h
> > new file mode 100644
> > index 000000000000..e1dec1a6a749
> > --- /dev/null
> > +++ b/include/linux/vmcore_info.h
> > @@ -0,0 +1,81 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef LINUX_VMCORE_INFO_H
> > +#define LINUX_VMCORE_INFO_H
> > +
> > +#include <linux/linkage.h>
> > +#include <linux/elfcore.h>
> > +#include <linux/elf.h>
> > +
> > +#define CRASH_CORE_NOTE_NAME	   "CORE"
> > +#define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
> > +#define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4)
> > +#define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
> > +
> > +/*
> > + * The per-cpu notes area is a list of notes terminated by a "NULL"
> > + * note header.  For kdump, the code in vmcore.c runs in the context
> > + * of the second kernel to combine them into one note.
> > + */
> > +#define CRASH_CORE_NOTE_BYTES	   ((CRASH_CORE_NOTE_HEAD_BYTES * 2) +	\
> > +				     CRASH_CORE_NOTE_NAME_BYTES +	\
> > +				     CRASH_CORE_NOTE_DESC_BYTES)
> > +
> > +#define VMCOREINFO_BYTES	   PAGE_SIZE
> > +#define VMCOREINFO_NOTE_NAME	   "VMCOREINFO"
> > +#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
> > +#define VMCOREINFO_NOTE_SIZE	   ((CRASH_CORE_NOTE_HEAD_BYTES * 2) +	\
> > +				     VMCOREINFO_NOTE_NAME_BYTES +	\
> > +				     VMCOREINFO_BYTES)
> > +
> > +typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4];
> > +/* Per cpu memory for storing cpu states in case of system crash. */
> > +extern note_buf_t __percpu *crash_notes;
> > +
> > +void crash_update_vmcoreinfo_safecopy(void *ptr);
> > +void crash_save_vmcoreinfo(void);
> > +void arch_crash_save_vmcoreinfo(void);
> > +__printf(1, 2)
> > +void vmcoreinfo_append_str(const char *fmt, ...);
> > +phys_addr_t paddr_vmcoreinfo_note(void);
> > +
> > +#define VMCOREINFO_OSRELEASE(value) \
> > +	vmcoreinfo_append_str("OSRELEASE=%s\n", value)
> > +#define VMCOREINFO_BUILD_ID()						\
> > +	({								\
> > +		static_assert(sizeof(vmlinux_build_id) == 20);		\
> > +		vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \
> > +	})
> > +
> > +#define VMCOREINFO_PAGESIZE(value) \
> > +	vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
> > +#define VMCOREINFO_SYMBOL(name) \
> > +	vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
> > +#define VMCOREINFO_SYMBOL_ARRAY(name) \
> > +	vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name)
> > +#define VMCOREINFO_SIZE(name) \
> > +	vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> > +			      (unsigned long)sizeof(name))
> > +#define VMCOREINFO_STRUCT_SIZE(name) \
> > +	vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
> > +			      (unsigned long)sizeof(struct name))
> > +#define VMCOREINFO_OFFSET(name, field) \
> > +	vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> > +			      (unsigned long)offsetof(struct name, field))
> > +#define VMCOREINFO_TYPE_OFFSET(name, field) \
> > +	vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
> > +			      (unsigned long)offsetof(name, field))
> > +#define VMCOREINFO_LENGTH(name, value) \
> > +	vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
> > +#define VMCOREINFO_NUMBER(name) \
> > +	vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
> > +#define VMCOREINFO_CONFIG(name) \
> > +	vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
> > +
> > +extern unsigned char *vmcoreinfo_data;
> > +extern size_t vmcoreinfo_size;
> > +extern u32 *vmcoreinfo_note;
> > +
> > +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);
> > +#endif /* LINUX_VMCORE_INFO_H */
> > diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
> > index 8b7be71edd85..8faf27043432 100644
> > --- a/kernel/Kconfig.kexec
> > +++ b/kernel/Kconfig.kexec
> > @@ -5,11 +5,11 @@ menu "Kexec and crash features"
> >   config CRASH_RESERVE
> >   	bool
> > -config CRASH_CORE
> > +config VMCORE_INFO
> >   	bool
> >   config KEXEC_CORE
> > -	select CRASH_CORE
> > +	select VMCORE_INFO
> >   	select CRASH_RESERVE
> >   	bool
> > diff --git a/kernel/Makefile b/kernel/Makefile
> > index 05fa88b3ab74..649272a1d6b9 100644
> > --- a/kernel/Makefile
> > +++ b/kernel/Makefile
> > @@ -68,9 +68,9 @@ obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o
> >   obj-$(CONFIG_KALLSYMS) += kallsyms.o
> >   obj-$(CONFIG_KALLSYMS_SELFTEST) += kallsyms_selftest.o
> >   obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
> > -obj-$(CONFIG_CRASH_CORE) += crash_core.o
> > +obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
> >   obj-$(CONFIG_CRASH_RESERVE) += crash_reserve.o
> > -obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
> > +obj-$(CONFIG_KEXEC_CORE) += kexec_core.o crash_core.o
> >   obj-$(CONFIG_KEXEC) += kexec.o
> >   obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
> >   obj-$(CONFIG_KEXEC_ELF) += kexec_elf.o
> > diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> > index 055859c62f19..2f4df1fe6f7a 100644
> > --- a/kernel/crash_core.c
> > +++ b/kernel/crash_core.c
> > @@ -26,14 +26,6 @@
> >   /* Per cpu memory for storing cpu states in case of system crash. */
> >   note_buf_t __percpu *crash_notes;
> > -/* vmcoreinfo stuff */
> > -unsigned char *vmcoreinfo_data;
> > -size_t vmcoreinfo_size;
> > -u32 *vmcoreinfo_note;
> > -
> > -/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
> > -static unsigned char *vmcoreinfo_data_safecopy;
> > -
> >   int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
> >   			  void **addr, unsigned long *sz)
> >   {
> > @@ -195,206 +187,6 @@ int crash_exclude_mem_range(struct crash_mem *mem,
> >   	return 0;
> >   }
> > -Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> > -			  void *data, size_t data_len)
> > -{
> > -	struct elf_note *note = (struct elf_note *)buf;
> > -
> > -	note->n_namesz = strlen(name) + 1;
> > -	note->n_descsz = data_len;
> > -	note->n_type   = type;
> > -	buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
> > -	memcpy(buf, name, note->n_namesz);
> > -	buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
> > -	memcpy(buf, data, data_len);
> > -	buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
> > -
> > -	return buf;
> > -}
> > -
> > -void final_note(Elf_Word *buf)
> > -{
> > -	memset(buf, 0, sizeof(struct elf_note));
> > -}
> > -
> > -static void update_vmcoreinfo_note(void)
> > -{
> > -	u32 *buf = vmcoreinfo_note;
> > -
> > -	if (!vmcoreinfo_size)
> > -		return;
> > -	buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
> > -			      vmcoreinfo_size);
> > -	final_note(buf);
> > -}
> > -
> > -void crash_update_vmcoreinfo_safecopy(void *ptr)
> > -{
> > -	if (ptr)
> > -		memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
> > -
> > -	vmcoreinfo_data_safecopy = ptr;
> > -}
> > -
> > -void crash_save_vmcoreinfo(void)
> > -{
> > -	if (!vmcoreinfo_note)
> > -		return;
> > -
> > -	/* Use the safe copy to generate vmcoreinfo note if have */
> > -	if (vmcoreinfo_data_safecopy)
> > -		vmcoreinfo_data = vmcoreinfo_data_safecopy;
> > -
> > -	vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
> > -	update_vmcoreinfo_note();
> > -}
> > -
> > -void vmcoreinfo_append_str(const char *fmt, ...)
> > -{
> > -	va_list args;
> > -	char buf[0x50];
> > -	size_t r;
> > -
> > -	va_start(args, fmt);
> > -	r = vscnprintf(buf, sizeof(buf), fmt, args);
> > -	va_end(args);
> > -
> > -	r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
> > -
> > -	memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
> > -
> > -	vmcoreinfo_size += r;
> > -
> > -	WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
> > -		  "vmcoreinfo data exceeds allocated size, truncating");
> > -}
> > -
> > -/*
> > - * provide an empty default implementation here -- architecture
> > - * code may override this
> > - */
> > -void __weak arch_crash_save_vmcoreinfo(void)
> > -{}
> > -
> > -phys_addr_t __weak paddr_vmcoreinfo_note(void)
> > -{
> > -	return __pa(vmcoreinfo_note);
> > -}
> > -EXPORT_SYMBOL(paddr_vmcoreinfo_note);
> > -
> > -static int __init crash_save_vmcoreinfo_init(void)
> > -{
> > -	vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
> > -	if (!vmcoreinfo_data) {
> > -		pr_warn("Memory allocation for vmcoreinfo_data failed\n");
> > -		return -ENOMEM;
> > -	}
> > -
> > -	vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
> > -						GFP_KERNEL | __GFP_ZERO);
> > -	if (!vmcoreinfo_note) {
> > -		free_page((unsigned long)vmcoreinfo_data);
> > -		vmcoreinfo_data = NULL;
> > -		pr_warn("Memory allocation for vmcoreinfo_note failed\n");
> > -		return -ENOMEM;
> > -	}
> > -
> > -	VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
> > -	VMCOREINFO_BUILD_ID();
> > -	VMCOREINFO_PAGESIZE(PAGE_SIZE);
> > -
> > -	VMCOREINFO_SYMBOL(init_uts_ns);
> > -	VMCOREINFO_OFFSET(uts_namespace, name);
> > -	VMCOREINFO_SYMBOL(node_online_map);
> > -#ifdef CONFIG_MMU
> > -	VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
> > -#endif
> > -	VMCOREINFO_SYMBOL(_stext);
> > -	VMCOREINFO_SYMBOL(vmap_area_list);
> > -
> > -#ifndef CONFIG_NUMA
> > -	VMCOREINFO_SYMBOL(mem_map);
> > -	VMCOREINFO_SYMBOL(contig_page_data);
> > -#endif
> > -#ifdef CONFIG_SPARSEMEM
> > -	VMCOREINFO_SYMBOL_ARRAY(mem_section);
> > -	VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
> > -	VMCOREINFO_STRUCT_SIZE(mem_section);
> > -	VMCOREINFO_OFFSET(mem_section, section_mem_map);
> > -	VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
> > -	VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
> > -#endif
> > -	VMCOREINFO_STRUCT_SIZE(page);
> > -	VMCOREINFO_STRUCT_SIZE(pglist_data);
> > -	VMCOREINFO_STRUCT_SIZE(zone);
> > -	VMCOREINFO_STRUCT_SIZE(free_area);
> > -	VMCOREINFO_STRUCT_SIZE(list_head);
> > -	VMCOREINFO_SIZE(nodemask_t);
> > -	VMCOREINFO_OFFSET(page, flags);
> > -	VMCOREINFO_OFFSET(page, _refcount);
> > -	VMCOREINFO_OFFSET(page, mapping);
> > -	VMCOREINFO_OFFSET(page, lru);
> > -	VMCOREINFO_OFFSET(page, _mapcount);
> > -	VMCOREINFO_OFFSET(page, private);
> > -	VMCOREINFO_OFFSET(page, compound_head);
> > -	VMCOREINFO_OFFSET(pglist_data, node_zones);
> > -	VMCOREINFO_OFFSET(pglist_data, nr_zones);
> > -#ifdef CONFIG_FLATMEM
> > -	VMCOREINFO_OFFSET(pglist_data, node_mem_map);
> > -#endif
> > -	VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
> > -	VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
> > -	VMCOREINFO_OFFSET(pglist_data, node_id);
> > -	VMCOREINFO_OFFSET(zone, free_area);
> > -	VMCOREINFO_OFFSET(zone, vm_stat);
> > -	VMCOREINFO_OFFSET(zone, spanned_pages);
> > -	VMCOREINFO_OFFSET(free_area, free_list);
> > -	VMCOREINFO_OFFSET(list_head, next);
> > -	VMCOREINFO_OFFSET(list_head, prev);
> > -	VMCOREINFO_OFFSET(vmap_area, va_start);
> > -	VMCOREINFO_OFFSET(vmap_area, list);
> > -	VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
> > -	log_buf_vmcoreinfo_setup();
> > -	VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
> > -	VMCOREINFO_NUMBER(NR_FREE_PAGES);
> > -	VMCOREINFO_NUMBER(PG_lru);
> > -	VMCOREINFO_NUMBER(PG_private);
> > -	VMCOREINFO_NUMBER(PG_swapcache);
> > -	VMCOREINFO_NUMBER(PG_swapbacked);
> > -	VMCOREINFO_NUMBER(PG_slab);
> > -#ifdef CONFIG_MEMORY_FAILURE
> > -	VMCOREINFO_NUMBER(PG_hwpoison);
> > -#endif
> > -	VMCOREINFO_NUMBER(PG_head_mask);
> > -#define PAGE_BUDDY_MAPCOUNT_VALUE	(~PG_buddy)
> > -	VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
> > -#ifdef CONFIG_HUGETLB_PAGE
> > -	VMCOREINFO_NUMBER(PG_hugetlb);
> > -#define PAGE_OFFLINE_MAPCOUNT_VALUE	(~PG_offline)
> > -	VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
> > -#endif
> > -
> > -#ifdef CONFIG_KALLSYMS
> > -	VMCOREINFO_SYMBOL(kallsyms_names);
> > -	VMCOREINFO_SYMBOL(kallsyms_num_syms);
> > -	VMCOREINFO_SYMBOL(kallsyms_token_table);
> > -	VMCOREINFO_SYMBOL(kallsyms_token_index);
> > -#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
> > -	VMCOREINFO_SYMBOL(kallsyms_offsets);
> > -	VMCOREINFO_SYMBOL(kallsyms_relative_base);
> > -#else
> > -	VMCOREINFO_SYMBOL(kallsyms_addresses);
> > -#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
> > -#endif /* CONFIG_KALLSYMS */
> > -
> > -	arch_crash_save_vmcoreinfo();
> > -	update_vmcoreinfo_note();
> > -
> > -	return 0;
> > -}
> > -
> > -subsys_initcall(crash_save_vmcoreinfo_init);
> > -
> >   static int __init crash_notes_memory_init(void)
> >   {
> >   	/* Allocate memory for saving cpu registers. */
> > diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
> > index 1d4bc493b2f4..11526fc42bc2 100644
> > --- a/kernel/ksysfs.c
> > +++ b/kernel/ksysfs.c
> > @@ -154,7 +154,7 @@ KERNEL_ATTR_RW(kexec_crash_size);
> >   #endif /* CONFIG_KEXEC_CORE */
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> >   static ssize_t vmcoreinfo_show(struct kobject *kobj,
> >   			       struct kobj_attribute *attr, char *buf)
> > @@ -177,7 +177,7 @@ KERNEL_ATTR_RO(crash_elfcorehdr_size);
> >   #endif
> > -#endif /* CONFIG_CRASH_CORE */
> > +#endif /* CONFIG_VMCORE_INFO */
> >   /* whether file capabilities are enabled */
> >   static ssize_t fscaps_show(struct kobject *kobj,
> > @@ -265,7 +265,7 @@ static struct attribute * kernel_attrs[] = {
> >   	&kexec_crash_loaded_attr.attr,
> >   	&kexec_crash_size_attr.attr,
> >   #endif
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> >   	&vmcoreinfo_attr.attr,
> >   #ifdef CONFIG_CRASH_HOTPLUG
> >   	&crash_elfcorehdr_size_attr.attr,
> > diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> > index f2444b581e16..7d74b000b43a 100644
> > --- a/kernel/printk/printk.c
> > +++ b/kernel/printk/printk.c
> > @@ -34,7 +34,7 @@
> >   #include <linux/security.h>
> >   #include <linux/memblock.h>
> >   #include <linux/syscalls.h>
> > -#include <linux/crash_core.h>
> > +#include <linux/vmcore_info.h>
> >   #include <linux/ratelimit.h>
> >   #include <linux/kmsg_dump.h>
> >   #include <linux/syslog.h>
> > @@ -951,7 +951,7 @@ const struct file_operations kmsg_fops = {
> >   	.release = devkmsg_release,
> >   };
> > -#ifdef CONFIG_CRASH_CORE
> > +#ifdef CONFIG_VMCORE_INFO
> >   /*
> >    * This appends the listed symbols to /proc/vmcore
> >    *
> > diff --git a/kernel/vmcore_info.c b/kernel/vmcore_info.c
> > new file mode 100644
> > index 000000000000..84f3663530c8
> > --- /dev/null
> > +++ b/kernel/vmcore_info.c
> > @@ -0,0 +1,233 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * crash.c - kernel crash support code.
> > + * Copyright (C) 2002-2004 Eric Biederman  <ebiederm at xmission.com>
> > + */
> > +
> > +#include <linux/buildid.h>
> > +#include <linux/init.h>
> > +#include <linux/utsname.h>
> > +#include <linux/vmalloc.h>
> > +#include <linux/sizes.h>
> > +#include <linux/kexec.h>
> > +#include <linux/memory.h>
> > +#include <linux/cpuhotplug.h>
> > +#include <linux/memblock.h>
> > +#include <linux/kexec.h>
> > +#include <linux/kmemleak.h>
> > +
> > +#include <asm/page.h>
> > +#include <asm/sections.h>
> > +
> > +#include <crypto/sha1.h>
> > +
> > +#include "kallsyms_internal.h"
> > +#include "kexec_internal.h"
> > +
> > +/* vmcoreinfo stuff */
> > +unsigned char *vmcoreinfo_data;
> > +size_t vmcoreinfo_size;
> > +u32 *vmcoreinfo_note;
> > +
> > +/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
> > +static unsigned char *vmcoreinfo_data_safecopy;
> > +
> > +Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
> > +			  void *data, size_t data_len)
> > +{
> > +	struct elf_note *note = (struct elf_note *)buf;
> > +
> > +	note->n_namesz = strlen(name) + 1;
> > +	note->n_descsz = data_len;
> > +	note->n_type   = type;
> > +	buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
> > +	memcpy(buf, name, note->n_namesz);
> > +	buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
> > +	memcpy(buf, data, data_len);
> > +	buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
> > +
> > +	return buf;
> > +}
> > +
> > +void final_note(Elf_Word *buf)
> > +{
> > +	memset(buf, 0, sizeof(struct elf_note));
> > +}
> > +
> > +static void update_vmcoreinfo_note(void)
> > +{
> > +	u32 *buf = vmcoreinfo_note;
> > +
> > +	if (!vmcoreinfo_size)
> > +		return;
> > +	buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
> > +			      vmcoreinfo_size);
> > +	final_note(buf);
> > +}
> > +
> > +void crash_update_vmcoreinfo_safecopy(void *ptr)
> > +{
> > +	if (ptr)
> > +		memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
> > +
> > +	vmcoreinfo_data_safecopy = ptr;
> > +}
> > +
> > +void crash_save_vmcoreinfo(void)
> > +{
> > +	if (!vmcoreinfo_note)
> > +		return;
> > +
> > +	/* Use the safe copy to generate vmcoreinfo note if have */
> > +	if (vmcoreinfo_data_safecopy)
> > +		vmcoreinfo_data = vmcoreinfo_data_safecopy;
> > +
> > +	vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
> > +	update_vmcoreinfo_note();
> > +}
> > +
> > +void vmcoreinfo_append_str(const char *fmt, ...)
> > +{
> > +	va_list args;
> > +	char buf[0x50];
> > +	size_t r;
> > +
> > +	va_start(args, fmt);
> > +	r = vscnprintf(buf, sizeof(buf), fmt, args);
> > +	va_end(args);
> > +
> > +	r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
> > +
> > +	memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
> > +
> > +	vmcoreinfo_size += r;
> > +
> > +	WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
> > +		  "vmcoreinfo data exceeds allocated size, truncating");
> > +}
> > +
> > +/*
> > + * provide an empty default implementation here -- architecture
> > + * code may override this
> > + */
> > +void __weak arch_crash_save_vmcoreinfo(void)
> > +{}
> > +
> > +phys_addr_t __weak paddr_vmcoreinfo_note(void)
> > +{
> > +	return __pa(vmcoreinfo_note);
> > +}
> > +EXPORT_SYMBOL(paddr_vmcoreinfo_note);
> > +
> > +static int __init crash_save_vmcoreinfo_init(void)
> > +{
> > +	vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
> > +	if (!vmcoreinfo_data) {
> > +		pr_warn("Memory allocation for vmcoreinfo_data failed\n");
> > +		return -ENOMEM;
> > +	}
> > +
> > +	vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
> > +						GFP_KERNEL | __GFP_ZERO);
> > +	if (!vmcoreinfo_note) {
> > +		free_page((unsigned long)vmcoreinfo_data);
> > +		vmcoreinfo_data = NULL;
> > +		pr_warn("Memory allocation for vmcoreinfo_note failed\n");
> > +		return -ENOMEM;
> > +	}
> > +
> > +	VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
> > +	VMCOREINFO_BUILD_ID();
> > +	VMCOREINFO_PAGESIZE(PAGE_SIZE);
> > +
> > +	VMCOREINFO_SYMBOL(init_uts_ns);
> > +	VMCOREINFO_OFFSET(uts_namespace, name);
> > +	VMCOREINFO_SYMBOL(node_online_map);
> > +#ifdef CONFIG_MMU
> > +	VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
> > +#endif
> > +	VMCOREINFO_SYMBOL(_stext);
> > +	VMCOREINFO_SYMBOL(vmap_area_list);
> > +
> > +#ifndef CONFIG_NUMA
> > +	VMCOREINFO_SYMBOL(mem_map);
> > +	VMCOREINFO_SYMBOL(contig_page_data);
> > +#endif
> > +#ifdef CONFIG_SPARSEMEM
> > +	VMCOREINFO_SYMBOL_ARRAY(mem_section);
> > +	VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
> > +	VMCOREINFO_STRUCT_SIZE(mem_section);
> > +	VMCOREINFO_OFFSET(mem_section, section_mem_map);
> > +	VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
> > +	VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
> > +#endif
> > +	VMCOREINFO_STRUCT_SIZE(page);
> > +	VMCOREINFO_STRUCT_SIZE(pglist_data);
> > +	VMCOREINFO_STRUCT_SIZE(zone);
> > +	VMCOREINFO_STRUCT_SIZE(free_area);
> > +	VMCOREINFO_STRUCT_SIZE(list_head);
> > +	VMCOREINFO_SIZE(nodemask_t);
> > +	VMCOREINFO_OFFSET(page, flags);
> > +	VMCOREINFO_OFFSET(page, _refcount);
> > +	VMCOREINFO_OFFSET(page, mapping);
> > +	VMCOREINFO_OFFSET(page, lru);
> > +	VMCOREINFO_OFFSET(page, _mapcount);
> > +	VMCOREINFO_OFFSET(page, private);
> > +	VMCOREINFO_OFFSET(page, compound_head);
> > +	VMCOREINFO_OFFSET(pglist_data, node_zones);
> > +	VMCOREINFO_OFFSET(pglist_data, nr_zones);
> > +#ifdef CONFIG_FLATMEM
> > +	VMCOREINFO_OFFSET(pglist_data, node_mem_map);
> > +#endif
> > +	VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
> > +	VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
> > +	VMCOREINFO_OFFSET(pglist_data, node_id);
> > +	VMCOREINFO_OFFSET(zone, free_area);
> > +	VMCOREINFO_OFFSET(zone, vm_stat);
> > +	VMCOREINFO_OFFSET(zone, spanned_pages);
> > +	VMCOREINFO_OFFSET(free_area, free_list);
> > +	VMCOREINFO_OFFSET(list_head, next);
> > +	VMCOREINFO_OFFSET(list_head, prev);
> > +	VMCOREINFO_OFFSET(vmap_area, va_start);
> > +	VMCOREINFO_OFFSET(vmap_area, list);
> > +	VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
> > +	log_buf_vmcoreinfo_setup();
> > +	VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
> > +	VMCOREINFO_NUMBER(NR_FREE_PAGES);
> > +	VMCOREINFO_NUMBER(PG_lru);
> > +	VMCOREINFO_NUMBER(PG_private);
> > +	VMCOREINFO_NUMBER(PG_swapcache);
> > +	VMCOREINFO_NUMBER(PG_swapbacked);
> > +	VMCOREINFO_NUMBER(PG_slab);
> > +#ifdef CONFIG_MEMORY_FAILURE
> > +	VMCOREINFO_NUMBER(PG_hwpoison);
> > +#endif
> > +	VMCOREINFO_NUMBER(PG_head_mask);
> > +#define PAGE_BUDDY_MAPCOUNT_VALUE	(~PG_buddy)
> > +	VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
> > +#ifdef CONFIG_HUGETLB_PAGE
> > +	VMCOREINFO_NUMBER(PG_hugetlb);
> > +#define PAGE_OFFLINE_MAPCOUNT_VALUE	(~PG_offline)
> > +	VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
> > +#endif
> > +
> > +#ifdef CONFIG_KALLSYMS
> > +	VMCOREINFO_SYMBOL(kallsyms_names);
> > +	VMCOREINFO_SYMBOL(kallsyms_num_syms);
> > +	VMCOREINFO_SYMBOL(kallsyms_token_table);
> > +	VMCOREINFO_SYMBOL(kallsyms_token_index);
> > +#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
> > +	VMCOREINFO_SYMBOL(kallsyms_offsets);
> > +	VMCOREINFO_SYMBOL(kallsyms_relative_base);
> > +#else
> > +	VMCOREINFO_SYMBOL(kallsyms_addresses);
> > +#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
> > +#endif /* CONFIG_KALLSYMS */
> > +
> > +	arch_crash_save_vmcoreinfo();
> > +	update_vmcoreinfo_note();
> > +
> > +	return 0;
> > +}
> > +
> > +subsys_initcall(crash_save_vmcoreinfo_init);
> > diff --git a/lib/buildid.c b/lib/buildid.c
> > index e3a7acdeef0e..3e6868c86b45 100644
> > --- a/lib/buildid.c
> > +++ b/lib/buildid.c
> > @@ -174,7 +174,7 @@ int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size)
> >   	return parse_build_id_buf(build_id, NULL, buf, buf_size);
> >   }
> > -#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
> > +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_VMCORE_INFO)
> >   unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX] __ro_after_init;
> >   /**
> 



From peterx at redhat.com  Thu Feb 22 00:04:38 2024
From: peterx at redhat.com (Peter Xu)
Date: Thu, 22 Feb 2024 16:04:38 +0800
Subject: [PATCH v2 03/13] mm: Provide generic pmd_thp_or_huge()
In-Reply-To: <20240221125753.GQ13330@nvidia.com>
References: <20240103091423.400294-1-peterx@redhat.com>
 <20240103091423.400294-4-peterx@redhat.com>
 <20240115175551.GP734935@nvidia.com>
 <ZdXEYfs_xhS_9gRo@x1n>
 <20240221125753.GQ13330@nvidia.com>
Message-ID: <ZdcAFpRijQdaYV2A@x1n>

On Wed, Feb 21, 2024 at 08:57:53AM -0400, Jason Gunthorpe wrote:
> On Wed, Feb 21, 2024 at 05:37:37PM +0800, Peter Xu wrote:
> > On Mon, Jan 15, 2024 at 01:55:51PM -0400, Jason Gunthorpe wrote:
> > > On Wed, Jan 03, 2024 at 05:14:13PM +0800, peterx at redhat.com wrote:
> > > > From: Peter Xu <peterx at redhat.com>
> > > > 
> > > > ARM defines pmd_thp_or_huge(), detecting either a THP or a huge PMD.  It
> > > > can be a helpful helper if we want to merge more THP and hugetlb code
> > > > paths.  Make it a generic default implementation, only exist when
> > > > CONFIG_MMU.  Arch can overwrite it by defining its own version.
> > > > 
> > > > For example, ARM's pgtable-2level.h defines it to always return false.
> > > > 
> > > > Keep the macro declared with all config, it should be optimized to a false
> > > > anyway if !THP && !HUGETLB.
> > > > 
> > > > Signed-off-by: Peter Xu <peterx at redhat.com>
> > > > ---
> > > >  include/linux/pgtable.h | 4 ++++
> > > >  mm/gup.c                | 3 +--
> > > >  2 files changed, 5 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> > > > index 466cf477551a..2b42e95a4e3a 100644
> > > > --- a/include/linux/pgtable.h
> > > > +++ b/include/linux/pgtable.h
> > > > @@ -1362,6 +1362,10 @@ static inline int pmd_write(pmd_t pmd)
> > > >  #endif /* pmd_write */
> > > >  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
> > > >  
> > > > +#ifndef pmd_thp_or_huge
> > > > +#define pmd_thp_or_huge(pmd)	(pmd_huge(pmd) || pmd_trans_huge(pmd))
> > > > +#endif
> > > 
> > > Why not just use pmd_leaf() ?
> > > 
> > > This GUP case seems to me exactly like what pmd_leaf() should really
> > > do and be used for..
> > 
> > I think I mostly agree with you, and these APIs are indeed confusing.  IMHO
> > the challenge is about the risk of breaking others on small changes in the
> > details where evil resides.
> 
> These APIs are super confusing, which is why I brought it up.. Adding
> even more subtly different variations is not helping.
> 
> I think pmd_leaf means the entry is present and refers to a physical
> page not another radix level.
> 
> > > eg x86 does:
> > > 
> > > #define pmd_leaf	pmd_large
> > > static inline int pmd_large(pmd_t pte)
> > > 	return pmd_flags(pte) & _PAGE_PSE;
> > > 
> > > static inline int pmd_trans_huge(pmd_t pmd)
> > > 	return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
> > > 
> > > int pmd_huge(pmd_t pmd)
> > >         return !pmd_none(pmd) &&
> > >                 (pmd_val(pmd) & (_PAGE_PRESENT|_PAGE_PSE)) != _PAGE_PRESENT;
> > 
> > For example, here I don't think it's strictly pmd_leaf()? As pmd_huge()
> > will return true if PRESENT=0 && PSE=0 (as long as none pte ruled out
> > first), while pmd_leaf() will return false; I think that came from
> > cbef8478bee5. 
> 
> Yikes, but do you even want to handle non-present entries in GUP
> world? Isn't everything gated by !present in the first place?

I am as confused indeed.

> 
> > Besides that, there're also other cases where it's not clear of such direct
> > replacement, not until further investigated.  E.g., arm-3level has:
> > 
> > #define pmd_leaf(pmd)		pmd_sect(pmd)
> > #define pmd_sect(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
> > 						 PMD_TYPE_SECT)
> > #define PMD_TYPE_SECT		(_AT(pmdval_t, 1) << 0)
> > 
> > While pmd_huge() there relies on PMD_TABLE_BIT ()
> 
> I looked at tht, it looked OK.. 
> 
> #define PMD_TYPE_MASK               (_AT(pmdval_t, 3) << 0)
> #define PMD_TABLE_BIT               (_AT(pmdval_t, 1) << 1)
> 
> It is the same stuff, just a little confusingly written

True, my eyes decided to skip all the shifts. :-( Ok then, let me see
whether I can give it a stab on the pXd_huge() mess.

Thanks,

-- 
Peter Xu



From wsa+renesas at sang-engineering.com  Thu Feb 22 00:05:15 2024
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Thu, 22 Feb 2024 09:05:15 +0100
Subject: [PATCH v3] i2c: imx: when being a target, mark the last read as
 processed
In-Reply-To: <Zdb-EHnTiez6KP-K@pengutronix.de>
References: <20240221193013.14233-2-wsa+renesas@sang-engineering.com>
 <kgfagzj5vez56levwam6n6tzxl2lu7efnw5x3eadl3uophxism@ph2tghrvedg5>
 <ZdZ_PsNhQ9S1Eab-@shikoro>
 <Zdb-EHnTiez6KP-K@pengutronix.de>
Message-ID: <ZdcAOwHWWYQZe3wE@shikoro>

On Thu, Feb 22, 2024 at 08:56:00AM +0100, Oleksij Rempel wrote:

> > > > When being a target, NAK from the controller means that all bytes have
> > > > been transferred. So, the last byte needs also to be marked as
> > > > 'processed'. Otherwise index registers of backends may not increase.
> > > > 
> > > > Signed-off-by: Corey Minyard <minyard at acm.org>
> > > > Tested-by: Andrew Manley <andrew.manley at sealingtech.com>
> > > > Reviewed-by: Andrew Manley <andrew.manley at sealingtech.com>
> > > > Reviewed-by: Oleksij Rempel <o.rempel at pengutronix.de>
> > > > [wsa: fixed comment and commit message to properly describe the case]
> > > > Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
> > > 
> > > is this a fix?
> > 
> > In deed, it is:
> > 
> > Fixes: f7414cd6923f ("i2c: imx: support slave mode for imx I2C driver")
> 
> Looks good :)
> Are any action needed on my side?

Nope. All tags are still valid, I'd say, because I didn't change any code.

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/20240222/579af568/attachment.sig>

From krzysztof.kozlowski at linaro.org  Thu Feb 22 00:13:00 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 09:13:00 +0100
Subject: [PATCH] dt-bindings: arm: aspeed: add ASUS X4TF board
In-Reply-To: <TYZPR04MB6596F2EBAF65F7F53809C2259D562@TYZPR04MB6596.apcprd04.prod.outlook.com>
References: <20240222032504.1147489-1-Kelly_Hung@asus.com>
 <20240222032504.1147489-2-Kelly_Hung@asus.com>
 <2ab9b3924dbe07039e934d4580ab7dd397a31728.camel@codeconstruct.com.au>
 <TYZPR04MB6596F2EBAF65F7F53809C2259D562@TYZPR04MB6596.apcprd04.prod.outlook.com>
Message-ID: <40925c33-0b1d-4eb7-8f83-85efb6aeae4d@linaro.org>

On 22/02/2024 08:32, Kelly Hung(???) wrote:
> External email : Ensure your email is secure before opening links and attachments.

Please send proper patchsets. Patchset includes all necessary patches:
First binding then DTS.

Version your patches and provide changelog under ---.

> 
> Document the new compatibles used on ASUS X4TF.
> 
> Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>

...

> 
> Andrew
> 
> <p></p>
> ===================================================================================================================================
> This email and any attachments to it contain confidential information and are intended solely for the use of the individual to whom it is addressed. If you are not the 

Sorry, we cannot work with confidential information.


If you do not understand why, please also see:
https://www.youtube.com/live/fMeH7wqOwXA?si=GY7igfbda6vnjXlJ&t=835

Best regards,
Krzysztof



From luca.ceresoli at bootlin.com  Thu Feb 22 00:19:06 2024
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Thu, 22 Feb 2024 09:19:06 +0100
Subject: [PATCH V5 5/6] arm64: dts: imx8mp: add HDMI display pipeline
In-Reply-To: <20240218041649.1209173-6-aford173@gmail.com>
References: <20240218041649.1209173-1-aford173@gmail.com>
	<20240218041649.1209173-6-aford173@gmail.com>
Message-ID: <20240222091906.1bd13c03@booty>

Hi Adam,

On Sat, 17 Feb 2024 22:16:43 -0600
Adam Ford <aford173 at gmail.com> wrote:

> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the DT nodes for all the peripherals that make up the
> HDMI display pipeline.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Tested-by: Marek Vasut <marex at denx.de>
> Tested-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> ---
> V5:  No change
> 
> V3:  Re-ordered the HDMI parts to properly come after irqstree_hdmi
>      inside AIPS4.  Change size of LCDIF3 and PVI to match TRM sizes
>      of 4KB.
> 
> V2:  I took this from Lucas' original submission with the following:
>      Removed extra clock from HDMI-TX since it is now part of the
>      power domain
>      Added interrupt-parent to PVI
>      Changed the name of the HDMI tranmitter to fsl,imx8mp-hdmi-tx
>      Added ports to HDMI-tx
> ---
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 94 +++++++++++++++++++++++
>  1 file changed, 94 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> index cbb15ded4a74..433ea4ae6a16 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -1940,6 +1940,100 @@ irqsteer_hdmi: interrupt-controller at 32fc2000 {
>  				clock-names = "ipg";
>  				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>;
>  			};
> +
> +			hdmi_pvi: display-bridge at 32fc4000 {
> +				compatible = "fsl,imx8mp-hdmi-pvi";
> +				reg = <0x32fc4000 0x1000>;
> +				interrupt-parent = <&irqsteer_hdmi>;
> +				interrupts = <12>;
> +				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>;

After a small annoyance in my testing I realized here there should be:

  status = "disabled";

> +
> +				ports {
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +
> +					port at 0 {
> +						reg = <0>;
> +						pvi_from_lcdif3: endpoint {
> +							remote-endpoint = <&lcdif3_to_pvi>;
> +						};
> +					};
> +
> +					port at 1 {
> +						reg = <1>;
> +						pvi_to_hdmi_tx: endpoint {
> +							remote-endpoint = <&hdmi_tx_from_pvi>;
> +						};
> +					};
> +				};
> +			};
> +
> +			lcdif3: display-controller at 32fc6000 {
> +				compatible = "fsl,imx8mp-lcdif";
> +				reg = <0x32fc6000 0x1000>;
> +				interrupt-parent = <&irqsteer_hdmi>;
> +				interrupts = <8>;
> +				clocks = <&hdmi_tx_phy>,
> +					 <&clk IMX8MP_CLK_HDMI_APB>,
> +					 <&clk IMX8MP_CLK_HDMI_ROOT>;
> +				clock-names = "pix", "axi", "disp_axi";
> +				power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_LCDIF>;

Here as well:

  status = "disabled";

With those fixed you can add my:

 Reviewed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From anshuman.khandual at arm.com  Thu Feb 22 00:21:31 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:31 +0530
Subject: [PATCH V5 00/11] coresight: Move remaining AMBA ACPI devices into platform driver
Message-ID: <20240222082142.3663983-1-anshuman.khandual@arm.com>

This moves remaining AMBA ACPI devices into respective platform drivers for
enabling ACPI based power management support. This series applies on kernel
v6.8-rc5 release. This series has been built, and boot tested on a DT based
(RB5) and ACPI supported coresight platform (N1SDP).

https://git.gitlab.arm.com/linux-arm/linux-anshuman.git (amba_other_acpi_migration_v5)

Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: linux-acpi at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: coresight at lists.linaro.org
Cc: linux-stm32 at st-md-mailman.stormreply.com

Changes in V5:

- Used table->mask to filter out bits from pid in coresight_get_uci_data_from_amba()
- Dropped custom masks such as STM_AMBA_MASK and TMC_AMBA_MASK
- Modified tmc_etr_setup_caps() to accept struct csdev_access argument
- Reverted back tmc_etr_setup_caps() call site position in tmc_probe()
- Changed replicator and funnel devices to use the new helpers earlier in series
- Updated the commit messages regarding xxx_probe() refactoring and renaming

Changes in V4:

https://lore.kernel.org/all/20240123054608.1790189-1-anshuman.khandual at arm.com/

- Fixed PM imbalance in etm4_probe() error path with pm_runtime_disable()
- Restored back the pm_runtime_disable() on platform probe error paths
  in replicator, funnel, catu, tpiu, tmc and stm devices
- Dropped dev_caps argument from __tmc_probe()
- Changed xxxx_platform_remove() for platform_driver->remove_new() callback

Changes in V3:

https://lore.kernel.org/all/20231208053939.42901-1-anshuman.khandual at arm.com/

- Split coresight_init_driver/remove_driver() helpers into a separate patch
- Added 'drvdata->pclk' comments in replicator, funnel, tpiu, tmc, and stm devices
- Updated funnel, and replicator drivers to use these new helpers
- Check for drvdata instead of drvdata->pclk in suspend and resume paths in catu,
  tmc and debug devices
- Added patch to extract device name from AMBA pid based table lookup for stm
- Added patch to extract device properties from AMBA pid based table look for tmc
- Dropped pm_runtime_put() from common __probe() functions
- Handled pm_runtime_put() in AMBA driver in success path
- Handled pm_runtime_put() in platform driver in both success and error paths

Changes in V2:

https://lore.kernel.org/all/20231201062053.1268492-1-anshuman.khandual at arm.com/

- Dropped redundant devm_ioremap_resource() hunk from tmc_platform_probe()
- Defined coresight_[init|remove]_driver() for both AMBA/platform drivers
- Changed catu, tmc, tpiu, stm and debug coresight drivers to use the new
  helpers avoiding build issues arising from module_amba_driver(), and
  module_platform_driver() being on the same file

Changes in V1:

https://lore.kernel.org/all/20231027072943.3418997-1-anshuman.khandual at arm.com/

- Replaced all IS_ERR() instances with IS_ERR_OR_NULL() as per Suzuki

Changes in RFC:

https://lore.kernel.org/all/20230921042040.1334641-1-anshuman.khandual at arm.com/

Anshuman Khandual (11):
  coresight: etm4x: Fix unbalanced pm_runtime_enable()
  coresight: stm: Extract device name from AMBA pid based table lookup
  coresight: tmc: Extract device properties from AMBA pid based table lookup
  coresight: Add helpers registering/removing both AMBA and platform drivers
  coresight: replicator: Move ACPI support from AMBA driver to platform driver
  coresight: funnel: Move ACPI support from AMBA driver to platform driver
  coresight: catu: Move ACPI support from AMBA driver to platform driver
  coresight: tpiu: Move ACPI support from AMBA driver to platform driver
  coresight: tmc: Move ACPI support from AMBA driver to platform driver
  coresight: stm: Move ACPI support from AMBA driver to platform driver
  coresight: debug: Move ACPI support from AMBA driver to platform driver

 drivers/acpi/arm64/amba.c                     |   8 -
 drivers/hwtracing/coresight/coresight-catu.c  | 142 +++++++++++++---
 drivers/hwtracing/coresight/coresight-catu.h  |   1 +
 drivers/hwtracing/coresight/coresight-core.c  |  29 ++++
 .../hwtracing/coresight/coresight-cpu-debug.c | 141 ++++++++++++++--
 .../coresight/coresight-etm4x-core.c          |   3 +
 .../hwtracing/coresight/coresight-funnel.c    |  86 +++++-----
 drivers/hwtracing/coresight/coresight-priv.h  |  10 ++
 .../coresight/coresight-replicator.c          |  81 +++++-----
 drivers/hwtracing/coresight/coresight-stm.c   | 115 +++++++++++--
 .../hwtracing/coresight/coresight-tmc-core.c  | 153 +++++++++++++++---
 drivers/hwtracing/coresight/coresight-tmc.h   |   2 +
 drivers/hwtracing/coresight/coresight-tpiu.c  | 102 ++++++++++--
 include/linux/coresight.h                     |   7 +
 14 files changed, 721 insertions(+), 159 deletions(-)

-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:32 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:32 +0530
Subject: [PATCH V5 01/11] coresight: etm4x: Fix unbalanced pm_runtime_enable()
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-2-anshuman.khandual@arm.com>

There is an unbalanced pm_runtime_enable() in etm4_probe_platform_dev()
when etm4_probe() fails. This problem can be observed via the coresight
etm4 module's (load -> unload -> load) sequence when etm4_probe() fails
in etm4_probe_platform_dev().

[   63.379943] coresight-etm4x 7040000.etm: Unbalanced pm_runtime_enable!
[   63.393630] coresight-etm4x 7140000.etm: Unbalanced pm_runtime_enable!
[   63.407455] coresight-etm4x 7240000.etm: Unbalanced pm_runtime_enable!
[   63.420983] coresight-etm4x 7340000.etm: Unbalanced pm_runtime_enable!
[   63.420999] coresight-etm4x 7440000.etm: Unbalanced pm_runtime_enable!
[   63.441209] coresight-etm4x 7540000.etm: Unbalanced pm_runtime_enable!
[   63.454689] coresight-etm4x 7640000.etm: Unbalanced pm_runtime_enable!
[   63.474982] coresight-etm4x 7740000.etm: Unbalanced pm_runtime_enable!

This fixes the above problem - with an explicit pm_runtime_disable() call
when etm4_probe() fails during etm4_probe_platform_dev().

Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Hanjun Guo <guohanjun at huawei.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: "Rafael J. Wysocki" <rafael at kernel.org>
Cc: Len Brown <lenb at kernel.org>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: Leo Yan <leo.yan at linaro.org>
Cc: linux-acpi at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: coresight at lists.linaro.org
Fixes: 5214b563588e ("coresight: etm4x: Add support for sysreg only devices")
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Added "Fixes:" tag

 drivers/hwtracing/coresight/coresight-etm4x-core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index ce1995a2827f..7c693b45ac05 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2217,6 +2217,9 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
 	ret = etm4_probe(&pdev->dev);
 
 	pm_runtime_put(&pdev->dev);
+	if (ret)
+		pm_runtime_disable(&pdev->dev);
+
 	return ret;
 }
 
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:33 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:33 +0530
Subject: [PATCH V5 02/11] coresight: stm: Extract device name from AMBA pid based table lookup
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-3-anshuman.khandual@arm.com>

Instead of using AMBA private data field, extract the device name from AMBA
pid based table lookup using new coresight_get_uci_data_from_amba() helper.

Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Used table->mask to filter out bits from pid in coresight_get_uci_data_from_amba()
- Dropped custom mask STM_AMBA_MASK

 drivers/hwtracing/coresight/coresight-priv.h | 10 ++++++++++
 drivers/hwtracing/coresight/coresight-stm.c  | 12 +++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 767076e07970..a17b92787d50 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -221,6 +221,16 @@ static inline void *coresight_get_uci_data(const struct amba_id *id)
 	return uci_id->data;
 }
 
+static inline void *coresight_get_uci_data_from_amba(const struct amba_id *table, u32 pid)
+{
+	while (table->mask) {
+		if ((pid & table->mask) == table->id)
+			return coresight_get_uci_data(table);
+		table++;
+	};
+	return NULL;
+}
+
 void coresight_release_platform_data(struct coresight_device *csdev,
 				     struct device *dev,
 				     struct coresight_platform_data *pdata);
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index a1c27c901ad1..6737e7b5bfca 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -804,6 +804,16 @@ static void stm_init_generic_data(struct stm_drvdata *drvdata,
 	drvdata->stm.set_options = stm_generic_set_options;
 }
 
+static const struct amba_id stm_ids[];
+
+static char *stm_csdev_name(struct coresight_device *csdev)
+{
+	u32 stm_pid = coresight_get_pid(&csdev->access);
+	void *uci_data = coresight_get_uci_data_from_amba(stm_ids, stm_pid);
+
+	return uci_data ? (char *)uci_data : "STM";
+}
+
 static int stm_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret, trace_id;
@@ -900,7 +910,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
 	pm_runtime_put(&adev->dev);
 
 	dev_info(&drvdata->csdev->dev, "%s initialized\n",
-		 (char *)coresight_get_uci_data(id));
+		 stm_csdev_name(drvdata->csdev));
 	return 0;
 
 cs_unregister:
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:34 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:34 +0530
Subject: [PATCH V5 03/11] coresight: tmc: Extract device properties from AMBA pid based table lookup
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-4-anshuman.khandual@arm.com>

This extracts device properties from AMBA pid based table lookup. But first
this modifies tmc_etr_setup_caps() to accept csdev access.

Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Modified tmc_etr_setup_caps() to accept struct csdev_access argument
- Reverted back tmc_etr_setup_caps() call site position in tmc_probe()
- Dropped custom mask TMC_AMBA_MASK

 drivers/hwtracing/coresight/coresight-tmc-core.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 7ec5365e2b64..43874fa4def0 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -370,16 +370,23 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
 	return (auth & TMC_AUTH_NSID_MASK) == 0x3;
 }
 
+static const struct amba_id tmc_ids[];
+
 /* Detect and initialise the capabilities of a TMC ETR */
-static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
+static int tmc_etr_setup_caps(struct device *parent, u32 devid,
+			      struct csdev_access *access)
 {
 	int rc;
-	u32 dma_mask = 0;
+	u32 tmc_pid, dma_mask = 0;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
+	void *dev_caps;
 
 	if (!tmc_etr_has_non_secure_access(drvdata))
 		return -EACCES;
 
+	tmc_pid = coresight_get_pid(access);
+	dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid);
+
 	/* Set the unadvertised capabilities */
 	tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
 
@@ -497,8 +504,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 		desc.type = CORESIGHT_DEV_TYPE_SINK;
 		desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
 		desc.ops = &tmc_etr_cs_ops;
-		ret = tmc_etr_setup_caps(dev, devid,
-					 coresight_get_uci_data(id));
+		ret = tmc_etr_setup_caps(dev, devid, &desc.access);
 		if (ret)
 			goto out;
 		idr_init(&drvdata->idr);
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:35 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:35 +0530
Subject: [PATCH V5 04/11] coresight: Add helpers registering/removing both AMBA and platform drivers
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-5-anshuman.khandual@arm.com>

This adds two different helpers i.e coresight_init_driver()/remove_driver()
enabling coresight devices to register or remove AMBA and platform drivers.
This changes replicator and funnel devices to use above new helpers.

Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: Leo Yan <leo.yan at linaro.org>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: coresight at lists.linaro.org
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Changed replicator and funnel devices to use the new helpers

 drivers/hwtracing/coresight/coresight-core.c  | 29 +++++++++++++++++++
 .../hwtracing/coresight/coresight-funnel.c    | 19 ++----------
 .../coresight/coresight-replicator.c          | 20 ++-----------
 include/linux/coresight.h                     |  7 +++++
 4 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index d7f0e231feb9..4e897cc5da81 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1836,6 +1836,35 @@ static void __exit coresight_exit(void)
 module_init(coresight_init);
 module_exit(coresight_exit);
 
+int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
+			  struct platform_driver *pdev_drv)
+{
+	int ret;
+
+	ret = amba_driver_register(amba_drv);
+	if (ret) {
+		pr_err("%s: error registering AMBA driver\n", drv);
+		return ret;
+	}
+
+	ret = platform_driver_register(pdev_drv);
+	if (!ret)
+		return 0;
+
+	pr_err("%s: error registering platform driver\n", drv);
+	amba_driver_unregister(amba_drv);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(coresight_init_driver);
+
+void coresight_remove_driver(struct amba_driver *amba_drv,
+			     struct platform_driver *pdev_drv)
+{
+	amba_driver_unregister(amba_drv);
+	platform_driver_unregister(pdev_drv);
+}
+EXPORT_SYMBOL_GPL(coresight_remove_driver);
+
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
 MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier at linaro.org>");
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index a5b1fc787766..004cb63f9cbc 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -410,27 +410,12 @@ static struct amba_driver dynamic_funnel_driver = {
 
 static int __init funnel_init(void)
 {
-	int ret;
-
-	ret = platform_driver_register(&static_funnel_driver);
-	if (ret) {
-		pr_info("Error registering platform driver\n");
-		return ret;
-	}
-
-	ret = amba_driver_register(&dynamic_funnel_driver);
-	if (ret) {
-		pr_info("Error registering amba driver\n");
-		platform_driver_unregister(&static_funnel_driver);
-	}
-
-	return ret;
+	return coresight_init_driver("funnel", &dynamic_funnel_driver, &static_funnel_driver);
 }
 
 static void __exit funnel_exit(void)
 {
-	platform_driver_unregister(&static_funnel_driver);
-	amba_driver_unregister(&dynamic_funnel_driver);
+	coresight_remove_driver(&dynamic_funnel_driver, &static_funnel_driver);
 }
 
 module_init(funnel_init);
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 91d93060dda5..b82cf9906cfb 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -416,27 +416,13 @@ static struct amba_driver dynamic_replicator_driver = {
 
 static int __init replicator_init(void)
 {
-	int ret;
-
-	ret = platform_driver_register(&static_replicator_driver);
-	if (ret) {
-		pr_info("Error registering platform driver\n");
-		return ret;
-	}
-
-	ret = amba_driver_register(&dynamic_replicator_driver);
-	if (ret) {
-		pr_info("Error registering amba driver\n");
-		platform_driver_unregister(&static_replicator_driver);
-	}
-
-	return ret;
+	return coresight_init_driver("replicator", &dynamic_replicator_driver,
+				     &static_replicator_driver);
 }
 
 static void __exit replicator_exit(void)
 {
-	platform_driver_unregister(&static_replicator_driver);
-	amba_driver_unregister(&dynamic_replicator_driver);
+	coresight_remove_driver(&dynamic_replicator_driver, &static_replicator_driver);
 }
 
 module_init(replicator_init);
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index a4cb7dd6ca23..7e1646d4863c 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -12,6 +12,8 @@
 #include <linux/io.h>
 #include <linux/perf_event.h>
 #include <linux/sched.h>
+#include <linux/amba/bus.h>
+#include <linux/platform_device.h>
 
 /* Peripheral id registers (0xFD0-0xFEC) */
 #define CORESIGHT_PERIPHIDR4	0xfd0
@@ -598,6 +600,11 @@ void coresight_relaxed_write64(struct coresight_device *csdev,
 			       u64 val, u32 offset);
 void coresight_write64(struct coresight_device *csdev, u64 val, u32 offset);
 
+int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
+			  struct platform_driver *pdev_drv);
+
+void coresight_remove_driver(struct amba_driver *amba_drv,
+			     struct platform_driver *pdev_drv);
 #else
 static inline struct coresight_device *
 coresight_register(struct coresight_desc *desc) { return NULL; }
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:36 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:36 +0530
Subject: [PATCH V5 05/11] coresight: replicator: Move ACPI support from AMBA driver to platform driver
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-6-anshuman.khandual@arm.com>

Add support for the dynamic replicator device in the platform driver, which
can then be used on ACPI based platforms. This change would now allow
runtime power management for replicator devices on ACPI based systems.

The driver would try to enable the APB clock if available. Also, rename the
code to reflect the fact that it now handles both static and dynamic
replicators. But first this refactors replicator_probe() making sure it can
be used both for platform and AMBA drivers, by moving the pm_runtime_put()
to the callers.

Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: linux-acpi at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: coresight at lists.linaro.org
Tested-by: Sudeep Holla <sudeep.holla at arm.com> # Boot and driver probe only
Acked-by: Sudeep Holla <sudeep.holla at arm.com> # For ACPI related changes
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Updated the commit message regarding replicator_probe() refactoring
- coresight_[init|remove]_driver() replacement has been folded earlier

 drivers/acpi/arm64/amba.c                     |  1 -
 .../coresight/coresight-replicator.c          | 67 ++++++++++++-------
 2 files changed, 43 insertions(+), 25 deletions(-)

diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c
index 171b5c2c7edd..270f4e3819a2 100644
--- a/drivers/acpi/arm64/amba.c
+++ b/drivers/acpi/arm64/amba.c
@@ -27,7 +27,6 @@ static const struct acpi_device_id amba_id_list[] = {
 	{"ARMHC503", 0}, /* ARM CoreSight Debug */
 	{"ARMHC979", 0}, /* ARM CoreSight TPIU */
 	{"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
-	{"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
 	{"ARMHC9CA", 0}, /* ARM CoreSight CATU */
 	{"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */
 	{"", 0},
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index b82cf9906cfb..9b5f52725f43 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -31,6 +31,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator");
  * @base:	memory mapped base address for this component. Also indicates
  *		whether this one is programmable or not.
  * @atclk:	optional clock for the core parts of the replicator.
+ * @pclk:	APB clock if present, otherwise NULL
  * @csdev:	component vitals needed by the framework
  * @spinlock:	serialize enable/disable operations.
  * @check_idfilter_val: check if the context is lost upon clock removal.
@@ -38,6 +39,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator");
 struct replicator_drvdata {
 	void __iomem		*base;
 	struct clk		*atclk;
+	struct clk		*pclk;
 	struct coresight_device	*csdev;
 	spinlock_t		spinlock;
 	bool			check_idfilter_val;
@@ -243,6 +245,10 @@ static int replicator_probe(struct device *dev, struct resource *res)
 			return ret;
 	}
 
+	drvdata->pclk = coresight_get_enable_apb_pclk(dev);
+	if (IS_ERR(drvdata->pclk))
+		return -ENODEV;
+
 	/*
 	 * Map the device base for dynamic-replicator, which has been
 	 * validated by AMBA core
@@ -285,7 +291,6 @@ static int replicator_probe(struct device *dev, struct resource *res)
 	}
 
 	replicator_reset(drvdata);
-	pm_runtime_put(dev);
 
 out_disable_clk:
 	if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
@@ -301,29 +306,33 @@ static int replicator_remove(struct device *dev)
 	return 0;
 }
 
-static int static_replicator_probe(struct platform_device *pdev)
+static int replicator_platform_probe(struct platform_device *pdev)
 {
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	int ret;
 
 	pm_runtime_get_noresume(&pdev->dev);
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
-	/* Static replicators do not have programming base */
-	ret = replicator_probe(&pdev->dev, NULL);
-
-	if (ret) {
-		pm_runtime_put_noidle(&pdev->dev);
+	ret = replicator_probe(&pdev->dev, res);
+	pm_runtime_put(&pdev->dev);
+	if (ret)
 		pm_runtime_disable(&pdev->dev);
-	}
 
 	return ret;
 }
 
-static void static_replicator_remove(struct platform_device *pdev)
+static void replicator_platform_remove(struct platform_device *pdev)
 {
-	replicator_remove(&pdev->dev);
+	struct replicator_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+	if (drvdata)
+		replicator_remove(&pdev->dev);
+
 	pm_runtime_disable(&pdev->dev);
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_put(drvdata->pclk);
 }
 
 #ifdef CONFIG_PM
@@ -334,6 +343,8 @@ static int replicator_runtime_suspend(struct device *dev)
 	if (drvdata && !IS_ERR(drvdata->atclk))
 		clk_disable_unprepare(drvdata->atclk);
 
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_disable_unprepare(drvdata->pclk);
 	return 0;
 }
 
@@ -344,6 +355,8 @@ static int replicator_runtime_resume(struct device *dev)
 	if (drvdata && !IS_ERR(drvdata->atclk))
 		clk_prepare_enable(drvdata->atclk);
 
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_prepare_enable(drvdata->pclk);
 	return 0;
 }
 #endif
@@ -353,31 +366,32 @@ static const struct dev_pm_ops replicator_dev_pm_ops = {
 			   replicator_runtime_resume, NULL)
 };
 
-static const struct of_device_id static_replicator_match[] = {
+static const struct of_device_id replicator_match[] = {
 	{.compatible = "arm,coresight-replicator"},
 	{.compatible = "arm,coresight-static-replicator"},
 	{}
 };
 
-MODULE_DEVICE_TABLE(of, static_replicator_match);
+MODULE_DEVICE_TABLE(of, replicator_match);
 
 #ifdef CONFIG_ACPI
-static const struct acpi_device_id static_replicator_acpi_ids[] = {
+static const struct acpi_device_id replicator_acpi_ids[] = {
 	{"ARMHC985", 0}, /* ARM CoreSight Static Replicator */
+	{"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
 	{}
 };
 
-MODULE_DEVICE_TABLE(acpi, static_replicator_acpi_ids);
+MODULE_DEVICE_TABLE(acpi, replicator_acpi_ids);
 #endif
 
-static struct platform_driver static_replicator_driver = {
-	.probe          = static_replicator_probe,
-	.remove_new     = static_replicator_remove,
+static struct platform_driver replicator_driver = {
+	.probe          = replicator_platform_probe,
+	.remove_new     = replicator_platform_remove,
 	.driver         = {
-		.name   = "coresight-static-replicator",
+		.name   = "coresight-replicator",
 		/* THIS_MODULE is taken care of by platform_driver_register() */
-		.of_match_table = of_match_ptr(static_replicator_match),
-		.acpi_match_table = ACPI_PTR(static_replicator_acpi_ids),
+		.of_match_table = of_match_ptr(replicator_match),
+		.acpi_match_table = ACPI_PTR(replicator_acpi_ids),
 		.pm	= &replicator_dev_pm_ops,
 		.suppress_bind_attrs = true,
 	},
@@ -386,7 +400,13 @@ static struct platform_driver static_replicator_driver = {
 static int dynamic_replicator_probe(struct amba_device *adev,
 				    const struct amba_id *id)
 {
-	return replicator_probe(&adev->dev, &adev->res);
+	int ret;
+
+	ret = replicator_probe(&adev->dev, &adev->res);
+	if (!ret)
+		pm_runtime_put(&adev->dev);
+
+	return ret;
 }
 
 static void dynamic_replicator_remove(struct amba_device *adev)
@@ -416,13 +436,12 @@ static struct amba_driver dynamic_replicator_driver = {
 
 static int __init replicator_init(void)
 {
-	return coresight_init_driver("replicator", &dynamic_replicator_driver,
-				     &static_replicator_driver);
+	return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver);
 }
 
 static void __exit replicator_exit(void)
 {
-	coresight_remove_driver(&dynamic_replicator_driver, &static_replicator_driver);
+	coresight_remove_driver(&dynamic_replicator_driver, &replicator_driver);
 }
 
 module_init(replicator_init);
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:37 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:37 +0530
Subject: [PATCH V5 06/11] coresight: funnel: Move ACPI support from AMBA driver to platform driver
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-7-anshuman.khandual@arm.com>

Add support for the dynamic funnel device in the platform driver, which can
then be used on ACPI based platforms. This change would allow runtime power
management for ACPI based systems.

The driver would try to enable the APB clock if available. Also, rename the
code to reflect the fact that it now handles both static and dynamic
funnels. But first this refactors funnel_probe() making sure it can be used
both for platform and AMBA drivers, by moving the pm_runtime_put() to the
callers.

Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: linux-acpi at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: coresight at lists.linaro.org
Tested-by: Sudeep Holla <sudeep.holla at arm.com> # Boot and driver probe only
Acked-by: Sudeep Holla <sudeep.holla at arm.com> # For ACPI related changes
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Updated the commit message regarding funnel_probe() refactoring
- coresight_[init|remove]_driver() replacement has been folded earlier

 drivers/acpi/arm64/amba.c                     |  1 -
 .../hwtracing/coresight/coresight-funnel.c    | 71 ++++++++++++-------
 2 files changed, 46 insertions(+), 26 deletions(-)

diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c
index 270f4e3819a2..afb6afb66967 100644
--- a/drivers/acpi/arm64/amba.c
+++ b/drivers/acpi/arm64/amba.c
@@ -28,7 +28,6 @@ static const struct acpi_device_id amba_id_list[] = {
 	{"ARMHC979", 0}, /* ARM CoreSight TPIU */
 	{"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
 	{"ARMHC9CA", 0}, /* ARM CoreSight CATU */
-	{"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */
 	{"", 0},
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 004cb63f9cbc..88147465b129 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -36,6 +36,7 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel");
  * struct funnel_drvdata - specifics associated to a funnel component
  * @base:	memory mapped base address for this component.
  * @atclk:	optional clock for the core parts of the funnel.
+ * @pclk:	APB clock if present, otherwise NULL
  * @csdev:	component vitals needed by the framework.
  * @priority:	port selection order.
  * @spinlock:	serialize enable/disable operations.
@@ -43,6 +44,7 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel");
 struct funnel_drvdata {
 	void __iomem		*base;
 	struct clk		*atclk;
+	struct clk		*pclk;
 	struct coresight_device	*csdev;
 	unsigned long		priority;
 	spinlock_t		spinlock;
@@ -236,6 +238,10 @@ static int funnel_probe(struct device *dev, struct resource *res)
 			return ret;
 	}
 
+	drvdata->pclk = coresight_get_enable_apb_pclk(dev);
+	if (IS_ERR(drvdata->pclk))
+		return -ENODEV;
+
 	/*
 	 * Map the device base for dynamic-funnel, which has been
 	 * validated by AMBA core.
@@ -272,7 +278,6 @@ static int funnel_probe(struct device *dev, struct resource *res)
 		goto out_disable_clk;
 	}
 
-	pm_runtime_put(dev);
 	ret = 0;
 
 out_disable_clk:
@@ -298,6 +303,9 @@ static int funnel_runtime_suspend(struct device *dev)
 	if (drvdata && !IS_ERR(drvdata->atclk))
 		clk_disable_unprepare(drvdata->atclk);
 
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_disable_unprepare(drvdata->pclk);
+
 	return 0;
 }
 
@@ -308,6 +316,8 @@ static int funnel_runtime_resume(struct device *dev)
 	if (drvdata && !IS_ERR(drvdata->atclk))
 		clk_prepare_enable(drvdata->atclk);
 
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_prepare_enable(drvdata->pclk);
 	return 0;
 }
 #endif
@@ -316,55 +326,60 @@ static const struct dev_pm_ops funnel_dev_pm_ops = {
 	SET_RUNTIME_PM_OPS(funnel_runtime_suspend, funnel_runtime_resume, NULL)
 };
 
-static int static_funnel_probe(struct platform_device *pdev)
+static int funnel_platform_probe(struct platform_device *pdev)
 {
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	int ret;
 
 	pm_runtime_get_noresume(&pdev->dev);
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
-	/* Static funnel do not have programming base */
-	ret = funnel_probe(&pdev->dev, NULL);
-
-	if (ret) {
-		pm_runtime_put_noidle(&pdev->dev);
+	ret = funnel_probe(&pdev->dev, res);
+	pm_runtime_put(&pdev->dev);
+	if (ret)
 		pm_runtime_disable(&pdev->dev);
-	}
 
 	return ret;
 }
 
-static void static_funnel_remove(struct platform_device *pdev)
+static void funnel_platform_remove(struct platform_device *pdev)
 {
-	funnel_remove(&pdev->dev);
+	struct funnel_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+	if (drvdata)
+		funnel_remove(&pdev->dev);
+
 	pm_runtime_disable(&pdev->dev);
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_put(drvdata->pclk);
 }
 
-static const struct of_device_id static_funnel_match[] = {
+static const struct of_device_id funnel_match[] = {
 	{.compatible = "arm,coresight-static-funnel"},
 	{}
 };
 
-MODULE_DEVICE_TABLE(of, static_funnel_match);
+MODULE_DEVICE_TABLE(of, funnel_match);
 
 #ifdef CONFIG_ACPI
-static const struct acpi_device_id static_funnel_ids[] = {
-	{"ARMHC9FE", 0},
+static const struct acpi_device_id funnel_acpi_ids[] = {
+	{"ARMHC9FE", 0}, /* ARM Coresight Static Funnel */
+	{"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */
 	{},
 };
 
-MODULE_DEVICE_TABLE(acpi, static_funnel_ids);
+MODULE_DEVICE_TABLE(acpi, funnel_acpi_ids);
 #endif
 
-static struct platform_driver static_funnel_driver = {
-	.probe          = static_funnel_probe,
-	.remove_new      = static_funnel_remove,
-	.driver         = {
-		.name   = "coresight-static-funnel",
+static struct platform_driver funnel_driver = {
+	.probe		= funnel_platform_probe,
+	.remove_new	= funnel_platform_remove,
+	.driver		= {
+		.name   = "coresight-funnel",
 		/* THIS_MODULE is taken care of by platform_driver_register() */
-		.of_match_table = static_funnel_match,
-		.acpi_match_table = ACPI_PTR(static_funnel_ids),
+		.of_match_table = funnel_match,
+		.acpi_match_table = ACPI_PTR(funnel_acpi_ids),
 		.pm	= &funnel_dev_pm_ops,
 		.suppress_bind_attrs = true,
 	},
@@ -373,7 +388,13 @@ static struct platform_driver static_funnel_driver = {
 static int dynamic_funnel_probe(struct amba_device *adev,
 				const struct amba_id *id)
 {
-	return funnel_probe(&adev->dev, &adev->res);
+	int ret;
+
+	ret = funnel_probe(&adev->dev, &adev->res);
+	if (!ret)
+		pm_runtime_put(&adev->dev);
+
+	return ret;
 }
 
 static void dynamic_funnel_remove(struct amba_device *adev)
@@ -410,12 +431,12 @@ static struct amba_driver dynamic_funnel_driver = {
 
 static int __init funnel_init(void)
 {
-	return coresight_init_driver("funnel", &dynamic_funnel_driver, &static_funnel_driver);
+	return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver);
 }
 
 static void __exit funnel_exit(void)
 {
-	coresight_remove_driver(&dynamic_funnel_driver, &static_funnel_driver);
+	coresight_remove_driver(&dynamic_funnel_driver, &funnel_driver);
 }
 
 module_init(funnel_init);
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:38 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:38 +0530
Subject: [PATCH V5 07/11] coresight: catu: Move ACPI support from AMBA driver to platform driver
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-8-anshuman.khandual@arm.com>

Add support for the catu devices in a new platform driver, which can then
be used on ACPI based platforms. This change would now allow runtime power
management for ACPI based systems. The driver would try to enable the APB
clock if available. But first this renames and then refactors catu_probe()
and catu_remove(), making sure it can be used both for platform and AMBA
drivers. This also moves pm_runtime_put() from catu_probe() to the callers.

Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: linux-acpi at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: coresight at lists.linaro.org
Acked-by: Sudeep Holla <sudeep.holla at arm.com> # For ACPI related changes
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Updated commit message regarding catu_probe/remove() refactoring and renaming

 drivers/acpi/arm64/amba.c                    |   1 -
 drivers/hwtracing/coresight/coresight-catu.c | 142 ++++++++++++++++---
 drivers/hwtracing/coresight/coresight-catu.h |   1 +
 3 files changed, 124 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c
index afb6afb66967..587061b0fd2f 100644
--- a/drivers/acpi/arm64/amba.c
+++ b/drivers/acpi/arm64/amba.c
@@ -27,7 +27,6 @@ static const struct acpi_device_id amba_id_list[] = {
 	{"ARMHC503", 0}, /* ARM CoreSight Debug */
 	{"ARMHC979", 0}, /* ARM CoreSight TPIU */
 	{"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
-	{"ARMHC9CA", 0}, /* ARM CoreSight CATU */
 	{"", 0},
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index 3949ded0d4fa..a3ea46b53898 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -7,6 +7,8 @@
  * Author: Suzuki K Poulose <suzuki.poulose at arm.com>
  */
 
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
 #include <linux/amba/bus.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
@@ -502,28 +504,20 @@ static const struct coresight_ops catu_ops = {
 	.helper_ops = &catu_helper_ops,
 };
 
-static int catu_probe(struct amba_device *adev, const struct amba_id *id)
+static int __catu_probe(struct device *dev, struct resource *res)
 {
 	int ret = 0;
 	u32 dma_mask;
-	struct catu_drvdata *drvdata;
+	struct catu_drvdata *drvdata = dev_get_drvdata(dev);
 	struct coresight_desc catu_desc;
 	struct coresight_platform_data *pdata = NULL;
-	struct device *dev = &adev->dev;
 	void __iomem *base;
 
 	catu_desc.name = coresight_alloc_device_name(&catu_devs, dev);
 	if (!catu_desc.name)
 		return -ENOMEM;
 
-	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
-	if (!drvdata) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	dev_set_drvdata(dev, drvdata);
-	base = devm_ioremap_resource(dev, &adev->res);
+	base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(base)) {
 		ret = PTR_ERR(base);
 		goto out;
@@ -567,19 +561,39 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id)
 	drvdata->csdev = coresight_register(&catu_desc);
 	if (IS_ERR(drvdata->csdev))
 		ret = PTR_ERR(drvdata->csdev);
-	else
-		pm_runtime_put(&adev->dev);
 out:
 	return ret;
 }
 
-static void catu_remove(struct amba_device *adev)
+static int catu_probe(struct amba_device *adev, const struct amba_id *id)
 {
-	struct catu_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+	struct catu_drvdata *drvdata;
+	int ret;
+
+	drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	amba_set_drvdata(adev, drvdata);
+	ret = __catu_probe(&adev->dev, &adev->res);
+	if (!ret)
+		pm_runtime_put(&adev->dev);
+
+	return ret;
+}
+
+static void __catu_remove(struct device *dev)
+{
+	struct catu_drvdata *drvdata = dev_get_drvdata(dev);
 
 	coresight_unregister(drvdata->csdev);
 }
 
+static void catu_remove(struct amba_device *adev)
+{
+	__catu_remove(&adev->dev);
+}
+
 static struct amba_id catu_ids[] = {
 	CS_AMBA_ID(0x000bb9ee),
 	{},
@@ -598,13 +612,103 @@ static struct amba_driver catu_driver = {
 	.id_table			= catu_ids,
 };
 
+static int catu_platform_probe(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct catu_drvdata *drvdata;
+	int ret = 0;
+
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
+	if (IS_ERR(drvdata->pclk))
+		return -ENODEV;
+
+	if (res) {
+		drvdata->base = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(drvdata->base)) {
+			clk_put(drvdata->pclk);
+			return PTR_ERR(drvdata->base);
+		}
+	}
+
+	pm_runtime_get_noresume(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	dev_set_drvdata(&pdev->dev, drvdata);
+	ret = __catu_probe(&pdev->dev, res);
+	pm_runtime_put(&pdev->dev);
+	if (ret)
+		pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int catu_platform_remove(struct platform_device *pdev)
+{
+	struct catu_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+	if (drvdata)
+		__catu_remove(&pdev->dev);
+
+	pm_runtime_disable(&pdev->dev);
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_put(drvdata->pclk);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int catu_runtime_suspend(struct device *dev)
+{
+	struct catu_drvdata *drvdata = dev_get_drvdata(dev);
+
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_disable_unprepare(drvdata->pclk);
+	return 0;
+}
+
+static int catu_runtime_resume(struct device *dev)
+{
+	struct catu_drvdata *drvdata = dev_get_drvdata(dev);
+
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_prepare_enable(drvdata->pclk);
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops catu_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(catu_runtime_suspend, catu_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id catu_acpi_ids[] = {
+	{"ARMHC9CA", 0}, /* ARM CoreSight CATU */
+	{},
+};
+
+MODULE_DEVICE_TABLE(acpi, catu_acpi_ids);
+#endif
+
+static struct platform_driver catu_platform_driver = {
+	.probe	= catu_platform_probe,
+	.remove	= catu_platform_remove,
+	.driver	= {
+		.name			= "coresight-catu-platform",
+		.acpi_match_table	= ACPI_PTR(catu_acpi_ids),
+		.suppress_bind_attrs	= true,
+		.pm			= &catu_dev_pm_ops,
+	},
+};
+
 static int __init catu_init(void)
 {
 	int ret;
 
-	ret = amba_driver_register(&catu_driver);
-	if (ret)
-		pr_info("Error registering catu driver\n");
+	ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver);
 	tmc_etr_set_catu_ops(&etr_catu_buf_ops);
 	return ret;
 }
@@ -612,7 +716,7 @@ static int __init catu_init(void)
 static void __exit catu_exit(void)
 {
 	tmc_etr_remove_catu_ops();
-	amba_driver_unregister(&catu_driver);
+	coresight_remove_driver(&catu_driver, &catu_platform_driver);
 }
 
 module_init(catu_init);
diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h
index 442e034bbfba..141feac1c14b 100644
--- a/drivers/hwtracing/coresight/coresight-catu.h
+++ b/drivers/hwtracing/coresight/coresight-catu.h
@@ -61,6 +61,7 @@
 #define CATU_IRQEN_OFF		0x0
 
 struct catu_drvdata {
+	struct clk *pclk;
 	void __iomem *base;
 	struct coresight_device *csdev;
 	int irq;
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:39 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:39 +0530
Subject: [PATCH V5 08/11] coresight: tpiu: Move ACPI support from AMBA driver to platform driver
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-9-anshuman.khandual@arm.com>

Add support for the tpiu device in the platform driver, which can then be
used on ACPI based platforms. This change would now allow runtime power
management for ACPI based systems. The driver would try to enable the APB
clock if available. But first this renames and then refactors tpiu_probe()
and tpiu_remove(), making sure it can be used both for platform and AMBA
drivers. This also moves pm_runtime_put() from tpiu_probe() to the callers.

Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: linux-acpi at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: coresight at lists.linaro.org
Tested-by: Sudeep Holla <sudeep.holla at arm.com> # Boot and driver probe only
Acked-by: Sudeep Holla <sudeep.holla at arm.com> # For ACPI related changes
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Updated commit message regarding tpiu_probe/remove() refactoring and renaming

 drivers/acpi/arm64/amba.c                    |   1 -
 drivers/hwtracing/coresight/coresight-tpiu.c | 102 +++++++++++++++++--
 2 files changed, 92 insertions(+), 11 deletions(-)

diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c
index 587061b0fd2f..6d24a8f7914b 100644
--- a/drivers/acpi/arm64/amba.c
+++ b/drivers/acpi/arm64/amba.c
@@ -25,7 +25,6 @@ static const struct acpi_device_id amba_id_list[] = {
 	{"ARMHC501", 0}, /* ARM CoreSight ETR */
 	{"ARMHC502", 0}, /* ARM CoreSight STM */
 	{"ARMHC503", 0}, /* ARM CoreSight Debug */
-	{"ARMHC979", 0}, /* ARM CoreSight TPIU */
 	{"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
 	{"", 0},
 };
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 59eac93fd6bb..7a76bbd610bf 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -5,6 +5,8 @@
  * Description: CoreSight Trace Port Interface Unit driver
  */
 
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
 #include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -52,11 +54,13 @@ DEFINE_CORESIGHT_DEVLIST(tpiu_devs, "tpiu");
 /*
  * @base:	memory mapped base address for this component.
  * @atclk:	optional clock for the core parts of the TPIU.
+ * @pclk:	APB clock if present, otherwise NULL
  * @csdev:	component vitals needed by the framework.
  */
 struct tpiu_drvdata {
 	void __iomem		*base;
 	struct clk		*atclk;
+	struct clk		*pclk;
 	struct coresight_device	*csdev;
 };
 
@@ -114,14 +118,12 @@ static const struct coresight_ops tpiu_cs_ops = {
 	.sink_ops	= &tpiu_sink_ops,
 };
 
-static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
+static int __tpiu_probe(struct device *dev, struct resource *res)
 {
 	int ret;
 	void __iomem *base;
-	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
 	struct tpiu_drvdata *drvdata;
-	struct resource *res = &adev->res;
 	struct coresight_desc desc = { 0 };
 
 	desc.name = coresight_alloc_device_name(&tpiu_devs, dev);
@@ -132,12 +134,16 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
 	if (!drvdata)
 		return -ENOMEM;
 
-	drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+	drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
 	if (!IS_ERR(drvdata->atclk)) {
 		ret = clk_prepare_enable(drvdata->atclk);
 		if (ret)
 			return ret;
 	}
+
+	drvdata->pclk = coresight_get_enable_apb_pclk(dev);
+	if (IS_ERR(drvdata->pclk))
+		return -ENODEV;
 	dev_set_drvdata(dev, drvdata);
 
 	/* Validity for the resource is already checked by the AMBA core */
@@ -163,21 +169,34 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
 	desc.dev = dev;
 	drvdata->csdev = coresight_register(&desc);
 
-	if (!IS_ERR(drvdata->csdev)) {
-		pm_runtime_put(&adev->dev);
+	if (!IS_ERR(drvdata->csdev))
 		return 0;
-	}
 
 	return PTR_ERR(drvdata->csdev);
 }
 
-static void tpiu_remove(struct amba_device *adev)
+static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
 {
-	struct tpiu_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+	int ret;
+
+	ret = __tpiu_probe(&adev->dev, &adev->res);
+	if (!ret)
+		pm_runtime_put(&adev->dev);
+	return ret;
+}
+
+static void __tpiu_remove(struct device *dev)
+{
+	struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
 
 	coresight_unregister(drvdata->csdev);
 }
 
+static void tpiu_remove(struct amba_device *adev)
+{
+	__tpiu_remove(&adev->dev);
+}
+
 #ifdef CONFIG_PM
 static int tpiu_runtime_suspend(struct device *dev)
 {
@@ -186,6 +205,8 @@ static int tpiu_runtime_suspend(struct device *dev)
 	if (drvdata && !IS_ERR(drvdata->atclk))
 		clk_disable_unprepare(drvdata->atclk);
 
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_disable_unprepare(drvdata->pclk);
 	return 0;
 }
 
@@ -196,6 +217,8 @@ static int tpiu_runtime_resume(struct device *dev)
 	if (drvdata && !IS_ERR(drvdata->atclk))
 		clk_prepare_enable(drvdata->atclk);
 
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_prepare_enable(drvdata->pclk);
 	return 0;
 }
 #endif
@@ -235,7 +258,66 @@ static struct amba_driver tpiu_driver = {
 	.id_table	= tpiu_ids,
 };
 
-module_amba_driver(tpiu_driver);
+static int tpiu_platform_probe(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	int ret;
+
+	pm_runtime_get_noresume(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	ret = __tpiu_probe(&pdev->dev, res);
+	pm_runtime_put(&pdev->dev);
+	if (ret)
+		pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int tpiu_platform_remove(struct platform_device *pdev)
+{
+	struct tpiu_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+	if (drvdata)
+		__tpiu_remove(&pdev->dev);
+
+	pm_runtime_disable(&pdev->dev);
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_put(drvdata->pclk);
+	return 0;
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id tpiu_acpi_ids[] = {
+	{"ARMHC979", 0}, /* ARM CoreSight TPIU */
+	{}
+};
+MODULE_DEVICE_TABLE(acpi, tpiu_acpi_ids);
+#endif
+
+static struct platform_driver tpiu_platform_driver = {
+	.probe	= tpiu_platform_probe,
+	.remove	= tpiu_platform_remove,
+	.driver = {
+		.name			= "coresight-tpiu-platform",
+		.acpi_match_table	= ACPI_PTR(tpiu_acpi_ids),
+		.suppress_bind_attrs	= true,
+		.pm			= &tpiu_dev_pm_ops,
+	},
+};
+
+static int __init tpiu_init(void)
+{
+	return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver);
+}
+
+static void __exit tpiu_exit(void)
+{
+	coresight_remove_driver(&tpiu_driver, &tpiu_platform_driver);
+}
+module_init(tpiu_init);
+module_exit(tpiu_exit);
 
 MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
 MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier at linaro.org>");
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:40 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:40 +0530
Subject: [PATCH V5 09/11] coresight: tmc: Move ACPI support from AMBA driver to platform driver
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-10-anshuman.khandual@arm.com>

Add support for the tmc devices in the platform driver, which can then be
used on ACPI based platforms. This change would now allow runtime power
management for ACPI based systems. The driver would try to enable the APB
clock if available. But first this renames and then refactors tmc_probe()
and tmc_remove(), making sure it can be used both for platform and AMBA
drivers. This also moves pm_runtime_put() from tmc_probe() to the callers.

Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: linux-acpi at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: coresight at lists.linaro.org
Tested-by: Sudeep Holla <sudeep.holla at arm.com> # Boot and driver probe only
Acked-by: Sudeep Holla <sudeep.holla at arm.com> # For ACPI related changes
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Updated the commit message regarding tmc_probe/remove() refactoring and renaming

 drivers/acpi/arm64/amba.c                     |   2 -
 .../hwtracing/coresight/coresight-tmc-core.c  | 139 ++++++++++++++++--
 drivers/hwtracing/coresight/coresight-tmc.h   |   2 +
 3 files changed, 126 insertions(+), 17 deletions(-)

diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c
index 6d24a8f7914b..d3c1defa7bc8 100644
--- a/drivers/acpi/arm64/amba.c
+++ b/drivers/acpi/arm64/amba.c
@@ -22,10 +22,8 @@
 static const struct acpi_device_id amba_id_list[] = {
 	{"ARMH0061", 0}, /* PL061 GPIO Device */
 	{"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */
-	{"ARMHC501", 0}, /* ARM CoreSight ETR */
 	{"ARMHC502", 0}, /* ARM CoreSight STM */
 	{"ARMHC503", 0}, /* ARM CoreSight Debug */
-	{"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
 	{"", 0},
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 43874fa4def0..9711fdd74a15 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -24,6 +24,8 @@
 #include <linux/of.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
 
 #include "coresight-priv.h"
 #include "coresight-tmc.h"
@@ -444,24 +446,17 @@ static u32 tmc_etr_get_max_burst_size(struct device *dev)
 	return burst_size;
 }
 
-static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
+static int __tmc_probe(struct device *dev, struct resource *res)
 {
 	int ret = 0;
 	u32 devid;
 	void __iomem *base;
-	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
-	struct tmc_drvdata *drvdata;
-	struct resource *res = &adev->res;
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
 	struct coresight_desc desc = { 0 };
 	struct coresight_dev_list *dev_list = NULL;
 
 	ret = -ENOMEM;
-	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
-	if (!drvdata)
-		goto out;
-
-	dev_set_drvdata(dev, drvdata);
 
 	/* Validity for the resource is already checked by the AMBA core */
 	base = devm_ioremap_resource(dev, res);
@@ -536,7 +531,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 		ret = PTR_ERR(pdata);
 		goto out;
 	}
-	adev->dev.platform_data = pdata;
+	dev->platform_data = pdata;
 	desc.pdata = pdata;
 
 	drvdata->csdev = coresight_register(&desc);
@@ -551,12 +546,27 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 	ret = misc_register(&drvdata->miscdev);
 	if (ret)
 		coresight_unregister(drvdata->csdev);
-	else
-		pm_runtime_put(&adev->dev);
 out:
 	return ret;
 }
 
+static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
+{
+	struct tmc_drvdata *drvdata;
+	int ret;
+
+	drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	amba_set_drvdata(adev, drvdata);
+	ret = __tmc_probe(&adev->dev, &adev->res);
+	if (!ret)
+		pm_runtime_put(&adev->dev);
+
+	return ret;
+}
+
 static void tmc_shutdown(struct amba_device *adev)
 {
 	unsigned long flags;
@@ -579,9 +589,9 @@ static void tmc_shutdown(struct amba_device *adev)
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 }
 
-static void tmc_remove(struct amba_device *adev)
+static void __tmc_remove(struct device *dev)
 {
-	struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
 
 	/*
 	 * Since misc_open() holds a refcount on the f_ops, which is
@@ -592,6 +602,11 @@ static void tmc_remove(struct amba_device *adev)
 	coresight_unregister(drvdata->csdev);
 }
 
+static void tmc_remove(struct amba_device *adev)
+{
+	__tmc_remove(&adev->dev);
+}
+
 static const struct amba_id tmc_ids[] = {
 	CS_AMBA_ID(0x000bb961),
 	/* Coresight SoC 600 TMC-ETR/ETS */
@@ -617,7 +632,101 @@ static struct amba_driver tmc_driver = {
 	.id_table	= tmc_ids,
 };
 
-module_amba_driver(tmc_driver);
+static int tmc_platform_probe(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct tmc_drvdata *drvdata;
+	int ret = 0;
+
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
+	if (IS_ERR(drvdata->pclk))
+		return -ENODEV;
+
+	dev_set_drvdata(&pdev->dev, drvdata);
+	pm_runtime_get_noresume(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	ret = __tmc_probe(&pdev->dev, res);
+	pm_runtime_put(&pdev->dev);
+	if (ret)
+		pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int tmc_platform_remove(struct platform_device *pdev)
+{
+	struct tmc_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+	if (drvdata)
+		__tmc_remove(&pdev->dev);
+
+	pm_runtime_disable(&pdev->dev);
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_put(drvdata->pclk);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int tmc_runtime_suspend(struct device *dev)
+{
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
+
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_disable_unprepare(drvdata->pclk);
+	return 0;
+}
+
+static int tmc_runtime_resume(struct device *dev)
+{
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
+
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_prepare_enable(drvdata->pclk);
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops tmc_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(tmc_runtime_suspend, tmc_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id tmc_acpi_ids[] = {
+	{"ARMHC501", 0}, /* ARM CoreSight ETR */
+	{"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
+	{},
+};
+MODULE_DEVICE_TABLE(acpi, tmc_acpi_ids);
+#endif
+
+static struct platform_driver tmc_platform_driver = {
+	.probe	= tmc_platform_probe,
+	.remove	= tmc_platform_remove,
+	.driver	= {
+		.name			= "coresight-tmc-platform",
+		.acpi_match_table	= ACPI_PTR(tmc_acpi_ids),
+		.suppress_bind_attrs	= true,
+		.pm			= &tmc_dev_pm_ops,
+	},
+};
+
+static int __init tmc_init(void)
+{
+	return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver);
+}
+
+static void __exit tmc_exit(void)
+{
+	coresight_remove_driver(&tmc_driver, &tmc_platform_driver);
+}
+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 8dcb426ac3e7..cb5a0920c203 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -166,6 +166,7 @@ struct etr_buf {
 
 /**
  * struct tmc_drvdata - specifics associated to an TMC component
+ * @pclk:	APB clock if present, otherwise NULL
  * @base:	memory mapped base address for this component.
  * @csdev:	component vitals needed by the framework.
  * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
@@ -190,6 +191,7 @@ struct etr_buf {
  * @perf_buf:	PERF buffer for ETR.
  */
 struct tmc_drvdata {
+	struct clk		*pclk;
 	void __iomem		*base;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:41 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:41 +0530
Subject: [PATCH V5 10/11] coresight: stm: Move ACPI support from AMBA driver to platform driver
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-11-anshuman.khandual@arm.com>

Add support for the stm devices in the platform driver, which can then be
used on ACPI based platforms. This change would now allow runtime power
management for ACPI based systems. The driver would try to enable the APB
clock if available. But first this renames and then refactors stm_probe()
and stm_remove(), making sure it can be used both for platform and AMBA
drivers. Also this moves pm_runtime_put() from stm_probe() to the callers.

Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: linux-acpi at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: coresight at lists.linaro.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
Tested-by: Sudeep Holla <sudeep.holla at arm.com> # Boot and driver probe only
Acked-by: Sudeep Holla <sudeep.holla at arm.com> # For ACPI related changes
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Updated commit message regarding stm_probe/remove() refactoring and renaming

 drivers/acpi/arm64/amba.c                   |   1 -
 drivers/hwtracing/coresight/coresight-stm.c | 103 ++++++++++++++++++--
 2 files changed, 93 insertions(+), 11 deletions(-)

diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c
index d3c1defa7bc8..bec0976541da 100644
--- a/drivers/acpi/arm64/amba.c
+++ b/drivers/acpi/arm64/amba.c
@@ -22,7 +22,6 @@
 static const struct acpi_device_id amba_id_list[] = {
 	{"ARMH0061", 0}, /* PL061 GPIO Device */
 	{"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */
-	{"ARMHC502", 0}, /* ARM CoreSight STM */
 	{"ARMHC503", 0}, /* ARM CoreSight Debug */
 	{"", 0},
 };
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 6737e7b5bfca..13f9c7d10270 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -29,6 +29,8 @@
 #include <linux/perf_event.h>
 #include <linux/pm_runtime.h>
 #include <linux/stm.h>
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
 
 #include "coresight-priv.h"
 #include "coresight-trace-id.h"
@@ -115,6 +117,7 @@ DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm");
  * struct stm_drvdata - specifics associated to an STM component
  * @base:		memory mapped base address for this component.
  * @atclk:		optional clock for the core parts of the STM.
+ * @pclk:		APB clock if present, otherwise NULL
  * @csdev:		component vitals needed by the framework.
  * @spinlock:		only one at a time pls.
  * @chs:		the channels accociated to this STM.
@@ -132,6 +135,7 @@ DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm");
 struct stm_drvdata {
 	void __iomem		*base;
 	struct clk		*atclk;
+	struct clk		*pclk;
 	struct coresight_device	*csdev;
 	spinlock_t		spinlock;
 	struct channel_space	chs;
@@ -814,14 +818,12 @@ static char *stm_csdev_name(struct coresight_device *csdev)
 	return uci_data ? (char *)uci_data : "STM";
 }
 
-static int stm_probe(struct amba_device *adev, const struct amba_id *id)
+static int __stm_probe(struct device *dev, struct resource *res)
 {
 	int ret, trace_id;
 	void __iomem *base;
-	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
 	struct stm_drvdata *drvdata;
-	struct resource *res = &adev->res;
 	struct resource ch_res;
 	struct coresight_desc desc = { 0 };
 
@@ -833,12 +835,16 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
 	if (!drvdata)
 		return -ENOMEM;
 
-	drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+	drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
 	if (!IS_ERR(drvdata->atclk)) {
 		ret = clk_prepare_enable(drvdata->atclk);
 		if (ret)
 			return ret;
 	}
+
+	drvdata->pclk = coresight_get_enable_apb_pclk(dev);
+	if (IS_ERR(drvdata->pclk))
+		return -ENODEV;
 	dev_set_drvdata(dev, drvdata);
 
 	base = devm_ioremap_resource(dev, res);
@@ -886,7 +892,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
 		ret = PTR_ERR(pdata);
 		goto stm_unregister;
 	}
-	adev->dev.platform_data = pdata;
+	dev->platform_data = pdata;
 
 	desc.type = CORESIGHT_DEV_TYPE_SOURCE;
 	desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE;
@@ -907,8 +913,6 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
 	}
 	drvdata->traceid = (u8)trace_id;
 
-	pm_runtime_put(&adev->dev);
-
 	dev_info(&drvdata->csdev->dev, "%s initialized\n",
 		 stm_csdev_name(drvdata->csdev));
 	return 0;
@@ -921,9 +925,20 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
 	return ret;
 }
 
-static void stm_remove(struct amba_device *adev)
+static int stm_probe(struct amba_device *adev, const struct amba_id *id)
+{
+	int ret;
+
+	ret = __stm_probe(&adev->dev, &adev->res);
+	if (!ret)
+		pm_runtime_put(&adev->dev);
+
+	return ret;
+}
+
+static void __stm_remove(struct device *dev)
 {
-	struct stm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev);
 
 	coresight_trace_id_put_system_id(drvdata->traceid);
 	coresight_unregister(drvdata->csdev);
@@ -931,6 +946,11 @@ static void stm_remove(struct amba_device *adev)
 	stm_unregister_device(&drvdata->stm);
 }
 
+static void stm_remove(struct amba_device *adev)
+{
+	__stm_remove(&adev->dev);
+}
+
 #ifdef CONFIG_PM
 static int stm_runtime_suspend(struct device *dev)
 {
@@ -939,6 +959,8 @@ static int stm_runtime_suspend(struct device *dev)
 	if (drvdata && !IS_ERR(drvdata->atclk))
 		clk_disable_unprepare(drvdata->atclk);
 
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_disable_unprepare(drvdata->pclk);
 	return 0;
 }
 
@@ -949,6 +971,8 @@ static int stm_runtime_resume(struct device *dev)
 	if (drvdata && !IS_ERR(drvdata->atclk))
 		clk_prepare_enable(drvdata->atclk);
 
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_prepare_enable(drvdata->pclk);
 	return 0;
 }
 #endif
@@ -977,7 +1001,66 @@ static struct amba_driver stm_driver = {
 	.id_table	= stm_ids,
 };
 
-module_amba_driver(stm_driver);
+static int stm_platform_probe(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	int ret = 0;
+
+	pm_runtime_get_noresume(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	ret = __stm_probe(&pdev->dev, res);
+	pm_runtime_put(&pdev->dev);
+	if (ret)
+		pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int stm_platform_remove(struct platform_device *pdev)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+	if (drvdata)
+		__stm_remove(&pdev->dev);
+
+	pm_runtime_disable(&pdev->dev);
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_put(drvdata->pclk);
+	return 0;
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id stm_acpi_ids[] = {
+	{"ARMHC502", 0}, /* ARM CoreSight STM */
+	{},
+};
+MODULE_DEVICE_TABLE(acpi, stm_acpi_ids);
+#endif
+
+static struct platform_driver stm_platform_driver = {
+	.probe	= stm_platform_probe,
+	.remove	= stm_platform_remove,
+	.driver	= {
+		.name			= "coresight-stm-platform",
+		.acpi_match_table	= ACPI_PTR(stm_acpi_ids),
+		.suppress_bind_attrs	= true,
+		.pm			= &stm_dev_pm_ops,
+	},
+};
+
+static int __init stm_init(void)
+{
+	return coresight_init_driver("stm", &stm_driver, &stm_platform_driver);
+}
+
+static void __exit stm_exit(void)
+{
+	coresight_remove_driver(&stm_driver, &stm_platform_driver);
+}
+module_init(stm_init);
+module_exit(stm_exit);
 
 MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
 MODULE_DESCRIPTION("Arm CoreSight System Trace Macrocell driver");
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 00:21:42 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 22 Feb 2024 13:51:42 +0530
Subject: [PATCH V5 11/11] coresight: debug: Move ACPI support from AMBA driver to platform driver
In-Reply-To: <20240222082142.3663983-1-anshuman.khandual@arm.com>
References: <20240222082142.3663983-1-anshuman.khandual@arm.com>
Message-ID: <20240222082142.3663983-12-anshuman.khandual@arm.com>

Add support for the cpu debug devices in a new platform driver, which can
then be used on ACPI based platforms. This change would now allow runtime
power management for ACPI based systems. The driver would try to enable
the APB clock if available. But first this renames and then refactors
debug_probe() and debug_remove(), making sure they can be used both for
platform and AMBA drivers.

Cc: Lorenzo Pieralisi <lpieralisi at kernel.org>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: James Clark <james.clark at arm.com>
Cc: linux-acpi at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: coresight at lists.linaro.org
Acked-by: Sudeep Holla <sudeep.holla at arm.com> # For ACPI related changes
Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
Changes in V5:

- Updated commit message regarding debug_probe/remove() refactoring
- Replaced device name s/tmc/debug in coresight_init_driver()

 drivers/acpi/arm64/amba.c                     |   1 -
 .../hwtracing/coresight/coresight-cpu-debug.c | 141 ++++++++++++++++--
 2 files changed, 127 insertions(+), 15 deletions(-)

diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c
index bec0976541da..e1f0bbb8f393 100644
--- a/drivers/acpi/arm64/amba.c
+++ b/drivers/acpi/arm64/amba.c
@@ -22,7 +22,6 @@
 static const struct acpi_device_id amba_id_list[] = {
 	{"ARMH0061", 0}, /* PL061 GPIO Device */
 	{"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */
-	{"ARMHC503", 0}, /* ARM CoreSight Debug */
 	{"", 0},
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 1874df7c6a73..e56a4b9ebd22 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -23,6 +23,8 @@
 #include <linux/smp.h>
 #include <linux/types.h>
 #include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
 
 #include "coresight-priv.h"
 
@@ -84,6 +86,7 @@
 #define DEBUG_WAIT_TIMEOUT		32000
 
 struct debug_drvdata {
+	struct clk	*pclk;
 	void __iomem	*base;
 	struct device	*dev;
 	int		cpu;
@@ -557,18 +560,12 @@ static void debug_func_exit(void)
 	debugfs_remove_recursive(debug_debugfs_dir);
 }
 
-static int debug_probe(struct amba_device *adev, const struct amba_id *id)
+static int __debug_probe(struct device *dev, struct resource *res)
 {
+	struct debug_drvdata *drvdata = dev_get_drvdata(dev);
 	void __iomem *base;
-	struct device *dev = &adev->dev;
-	struct debug_drvdata *drvdata;
-	struct resource *res = &adev->res;
 	int ret;
 
-	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
-	if (!drvdata)
-		return -ENOMEM;
-
 	drvdata->cpu = coresight_get_cpu(dev);
 	if (drvdata->cpu < 0)
 		return drvdata->cpu;
@@ -579,8 +576,7 @@ static int debug_probe(struct amba_device *adev, const struct amba_id *id)
 		return -EBUSY;
 	}
 
-	drvdata->dev = &adev->dev;
-	amba_set_drvdata(adev, drvdata);
+	drvdata->dev = dev;
 
 	/* Validity for the resource is already checked by the AMBA core */
 	base = devm_ioremap_resource(dev, res);
@@ -629,10 +625,21 @@ static int debug_probe(struct amba_device *adev, const struct amba_id *id)
 	return ret;
 }
 
-static void debug_remove(struct amba_device *adev)
+static int debug_probe(struct amba_device *adev, const struct amba_id *id)
+{
+	struct debug_drvdata *drvdata;
+
+	drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	amba_set_drvdata(adev, drvdata);
+	return __debug_probe(&adev->dev, &adev->res);
+}
+
+static void __debug_remove(struct device *dev)
 {
-	struct device *dev = &adev->dev;
-	struct debug_drvdata *drvdata = amba_get_drvdata(adev);
+	struct debug_drvdata *drvdata = dev_get_drvdata(dev);
 
 	per_cpu(debug_drvdata, drvdata->cpu) = NULL;
 
@@ -646,6 +653,11 @@ static void debug_remove(struct amba_device *adev)
 		debug_func_exit();
 }
 
+static void debug_remove(struct amba_device *adev)
+{
+	__debug_remove(&adev->dev);
+}
+
 static const struct amba_cs_uci_id uci_id_debug[] = {
 	{
 		/*  CPU Debug UCI data */
@@ -677,7 +689,108 @@ static struct amba_driver debug_driver = {
 	.id_table	= debug_ids,
 };
 
-module_amba_driver(debug_driver);
+static int debug_platform_probe(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct debug_drvdata *drvdata;
+	int ret = 0;
+
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
+	if (IS_ERR(drvdata->pclk))
+		return -ENODEV;
+
+	if (res) {
+		drvdata->base = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(drvdata->base)) {
+			clk_put(drvdata->pclk);
+			return PTR_ERR(drvdata->base);
+		}
+	}
+
+	dev_set_drvdata(&pdev->dev, drvdata);
+	pm_runtime_get_noresume(&pdev->dev);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	ret = __debug_probe(&pdev->dev, res);
+	if (ret) {
+		pm_runtime_put_noidle(&pdev->dev);
+		pm_runtime_disable(&pdev->dev);
+	}
+	return ret;
+}
+
+static int debug_platform_remove(struct platform_device *pdev)
+{
+	struct debug_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+	if (drvdata)
+		__debug_remove(&pdev->dev);
+
+	pm_runtime_disable(&pdev->dev);
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_put(drvdata->pclk);
+	return 0;
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id debug_platform_ids[] = {
+	{"ARMHC503", 0}, /* ARM CoreSight Debug */
+	{},
+};
+MODULE_DEVICE_TABLE(acpi, debug_platform_ids);
+#endif
+
+#ifdef CONFIG_PM
+static int debug_runtime_suspend(struct device *dev)
+{
+	struct debug_drvdata *drvdata = dev_get_drvdata(dev);
+
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_disable_unprepare(drvdata->pclk);
+	return 0;
+}
+
+static int debug_runtime_resume(struct device *dev)
+{
+	struct debug_drvdata *drvdata = dev_get_drvdata(dev);
+
+	if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
+		clk_prepare_enable(drvdata->pclk);
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops debug_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(debug_runtime_suspend, debug_runtime_resume, NULL)
+};
+
+static struct platform_driver debug_platform_driver = {
+	.probe	= debug_platform_probe,
+	.remove	= debug_platform_remove,
+	.driver	= {
+		.name			= "coresight-debug-platform",
+		.acpi_match_table	= ACPI_PTR(debug_platform_ids),
+		.suppress_bind_attrs	= true,
+		.pm			= &debug_dev_pm_ops,
+	},
+};
+
+static int __init debug_init(void)
+{
+	return coresight_init_driver("debug", &debug_driver, &debug_platform_driver);
+}
+
+static void __exit debug_exit(void)
+{
+	coresight_remove_driver(&debug_driver, &debug_platform_driver);
+}
+module_init(debug_init);
+module_exit(debug_exit);
 
 MODULE_AUTHOR("Leo Yan <leo.yan at linaro.org>");
 MODULE_DESCRIPTION("ARM Coresight CPU Debug Driver");
-- 
2.25.1



From greena88 at gmail.com  Thu Feb 22 00:25:23 2024
From: greena88 at gmail.com (Adam Green)
Date: Thu, 22 Feb 2024 08:25:23 +0000
Subject: [PATCH] arm64: dts: meson-g12b-odroid-n2*: Add support for overclocking Hardkernel ODROID-N2 boards.
Message-ID: <20240222082523.1812-1-greena88@gmail.com>

Hardkernel actively supports overclocking these boards in their own
documentation. (https://wiki.odroid.com/odroid-n2/hardware/overclocking)

This aligns the SoC opps with those in the board vendors bsp source.

Signed-off-by: Adam Green <greena88 at gmail.com>
---
 .../dts/amlogic/meson-g12b-odroid-n2-plus.dts | 25 +++++++++++++++++++
 .../boot/dts/amlogic/meson-g12b-odroid-n2.dts | 17 +++++++++++++
 .../dts/amlogic/meson-g12b-odroid-n2l.dts     | 25 +++++++++++++++++++
 3 files changed, 67 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts
index ce1198ad34e4..1731d542a00c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts
@@ -15,6 +15,31 @@ / {
 	model = "Hardkernel ODROID-N2Plus";
 };
 
+&cpu_opp_table_0 {
+	opp-1908000000 {
+		opp-hz = /bits/ 64 <1908000000>;
+		opp-microvolt = <1030000>;
+	};
+	opp-2016000000 {
+		opp-hz = /bits/ 64 <2016000000>;
+		opp-microvolt = <1040000>;
+		turbo-mode;
+	};
+};
+
+&cpub_opp_table_1 {
+	opp-2304000000 {
+		opp-hz = /bits/ 64 <2304000000>;
+		opp-microvolt = <1030000>;
+		turbo-mode;
+	};
+	opp-2400000000 {
+		opp-hz = /bits/ 64 <2400000000>;
+		opp-microvolt = <1040000>;
+		turbo-mode;
+	};
+};
+
 &vddcpu_a {
 	regulator-min-microvolt = <680000>;
 	regulator-max-microvolt = <1040000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
index a198a91259ec..0c71e8bc0124 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
@@ -13,3 +13,20 @@ / {
 	compatible = "hardkernel,odroid-n2", "amlogic,s922x", "amlogic,g12b";
 	model = "Hardkernel ODROID-N2";
 };
+
+&cpu_opp_table_0 {
+	opp-1992000000 {
+		turbo-mode;
+	};
+};
+
+&cpub_opp_table_1 {
+	opp-1908000000 {
+		turbo-mode;
+	};
+	opp-2004000000 {
+		opp-hz = /bits/ 64 <2004000000>;
+		opp-microvolt = <1022000>;
+		turbo-mode;
+	};
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2l.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2l.dts
index e26f3e3258e1..b16a69d0cad6 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2l.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2l.dts
@@ -97,6 +97,31 @@ codec {
 	};
 };
 
+&cpu_opp_table_0 {
+	opp-1908000000 {
+		opp-hz = /bits/ 64 <1908000000>;
+		opp-microvolt = <1030000>;
+	};
+	opp-2016000000 {
+		opp-hz = /bits/ 64 <2016000000>;
+		opp-microvolt = <1040000>;
+		turbo-mode;
+	};
+};
+
+&cpub_opp_table_1 {
+	opp-2304000000 {
+		opp-hz = /bits/ 64 <2304000000>;
+		opp-microvolt = <1030000>;
+		turbo-mode;
+	};
+	opp-2400000000 {
+		opp-hz = /bits/ 64 <2400000000>;
+		opp-microvolt = <1040000>;
+		turbo-mode;
+	};
+};
+
 &eth_phy {
 	status = "disabled";
 };
-- 
2.34.1



From sudeep.holla at arm.com  Thu Feb 22 00:25:58 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 08:25:58 +0000
Subject: [PATCH] firmware: arm_scmi: optee: fix struct kernel-doc warnings
In-Reply-To: <20240221062157.8694-1-rdunlap@infradead.org>
References: <20240221062157.8694-1-rdunlap@infradead.org>
Message-ID: <170859029406.107193.1029353194533836071.b4-ty@arm.com>

On Tue, 20 Feb 2024 22:21:57 -0800, Randy Dunlap wrote:
> Fix the kernel-doc notation for the nested union in struct
> scmi_optee_channel to eliminate kerenl-doc warnings:
>
> optee.c:130: warning: Excess struct member 'shmem' description in 'scmi_optee_channel'
> optee.c:131: warning: Function parameter or struct member 'req' not described in 'scmi_optee_channel'
>
>
> [...]

Applied to sudeep.holla/linux (for-next/scmi/updates), thanks!

[1/1] firmware: arm_scmi: optee: fix struct kernel-doc warnings
      https://git.kernel.org/sudeep.holla/c/a9c049f47e06
--
Regards,
Sudeep



From rafal at milecki.pl  Thu Feb 22 00:27:30 2024
From: rafal at milecki.pl (=?UTF-8?Q?Rafa=C5=82_Mi=C5=82ecki?=)
Date: Thu, 22 Feb 2024 09:27:30 +0100
Subject: [PATCH v5 05/12] arm64: dts: broadcom: bcmbca: Add NAND
 controller node
In-Reply-To: <20240207202257.271784-6-william.zhang@broadcom.com>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-6-william.zhang@broadcom.com>
Message-ID: <cd32d304d740e3c1875e449d459c805a@milecki.pl>

On 2024-02-07 21:22, William Zhang wrote:
> diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
> b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
> index 2f124b027bbf..336016e334d9 100644
> --- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
> +++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
> @@ -589,7 +589,7 @@ hsspi: spi at 1000 {
>  			status = "disabled";
>  		};
> 
> -		nand-controller at 1800 {
> +		nand_controller: nand-controller at 1800 {
>  			#address-cells = <1>;
>  			#size-cells = <0>;
>  			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", 
> "brcm,brcmnand";
> @@ -597,7 +597,7 @@ nand-controller at 1800 {
>  			reg-names = "nand", "nand-int-base";
>  			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
>  			interrupt-names = "nand_ctlrdy";
> -			status = "okay";
> +			status = "disabled";
> 
>  			nandcs: nand at 0 {
>  				compatible = "brcm,nandcs";

You disable NAND controller here breaking support for all dependant
devices.

I see you fix it afterwards in PATCH 06/12 but it's still a poor way of
handling such change and this issue can be hit e.g. during git bisect.

Also: given that 99% of BCM4908 devices use NAND controller can we just
save ourselves efforts and keep it enabled in .dtsi?

-- 
Rafa? Mi?ecki


From cristian.marussi at arm.com  Thu Feb 22 00:28:41 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Thu, 22 Feb 2024 08:28:41 +0000
Subject: [PATCH 6/7] clk: scmi: Allocate CLK operations dynamically
In-Reply-To: <500e265eb7c6a03a40e0067c8806e059.sboyd@kernel.org>
References: <20240214183006.3403207-1-cristian.marussi@arm.com>
 <20240214183006.3403207-7-cristian.marussi@arm.com>
 <500e265eb7c6a03a40e0067c8806e059.sboyd@kernel.org>
Message-ID: <ZdcFuV0KQDXTH8L8@pluto>

On Wed, Feb 21, 2024 at 09:44:14PM -0800, Stephen Boyd wrote:
> Quoting Cristian Marussi (2024-02-14 10:30:05)
> > diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
> > index 5747b6d651f0..b91a0dbd2fe0 100644
> > --- a/drivers/clk/clk-scmi.c
> > +++ b/drivers/clk/clk-scmi.c
> > @@ -158,51 +158,6 @@ static int scmi_clk_atomic_is_enabled(struct clk_hw *hw)
> >         return !!enabled;
> >  }
> >  

Hi Stephen,

thanks for having a look.

> > -/*
> > - * We can provide enable/disable/is_enabled 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,
> > -       .prepare = scmi_clk_enable,
> > -       .unprepare = scmi_clk_disable,
> > -       .set_parent = scmi_clk_set_parent,
> > -       .get_parent = scmi_clk_get_parent,
> > -       .determine_rate = scmi_clk_determine_rate,
> > -};
> > -
> > -static const struct clk_ops scmi_atomic_clk_ops = {
> 
> It's not great to move these function pointer structs out of RO memory
> to RW. I'm also not convinced that it's any better to construct them at
> runtime. Isn't there a constant set of possible clk configurations? Or
> why can't we simply add some failures to the clk_ops functions instead?

Well, the real clock devices managed by the SCMI server can be a of
varying nature and so the minimum set of possible clk configurations
to cover will amount to all the possible combinations of supported ops
regarding the specific clock properties (i.e. .set_parent / .set_rate /
.enable / .get/set_duty_cycle / atomic_capability ... for now)...we
simply cannot know in advance what the backend SCMI server is handling.

These seemed to me too much in number (and growing) to be pre-allocated
in all possible combinations. (and mostly wasted since you dont really
probably use all combinations all the time)

Moreover, SCMI latest spec now exposes some clock properties (or not) to
be able avoid even sending an actual SCMI message that we know will be
denied all the time; one option is that we return an error,, as you said,
but what is the point (I thought) to provide at all a clk-callback that
we know upfront will fail to be executed every time ? (and some consumer
drivers have been reported by partners not to be happy with these errors)

What I think could be optimized here instead, and I will try in the next
respin, it is that now I am allocating one set of custom ops for each clock
at the end, even if exactly the same ops are provided since the clock
capabilities are the same; I could instead allocate dynamically and fill only
one single set of ops for each distinct set of combinations, so as to avoid
useless duplication and use only the miminum strict amount of RW memory
needed.

Thanks,
Cristian


From krzysztof.kozlowski at linaro.org  Thu Feb 22 00:30:16 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 09:30:16 +0100
Subject: [PATCH 2/4] dt-bindings: media: Document bindings for HDMI RX
 Controller
In-Reply-To: <1048c3-65d66380-b-49a25c80@188726434>
References: <20240216094922.257674-1-shreeya.patel@collabora.com>
 <20240216094922.257674-3-shreeya.patel@collabora.com>
 <fd3b7ab7-3702-412f-947a-95396dbe1f4c@linaro.org>
 <1048c3-65d66380-b-49a25c80@188726434>
Message-ID: <efee9c66-cb84-4f02-91b6-53f2db874b3b@linaro.org>

On 21/02/2024 21:55, Shreeya Patel wrote:
>>> +  - hdmirx-5v-detection-gpios
>>> +
>>> +additionalProperties: false
>>> +
>>> +examples:
>>> +  - |
>>> +    #include <dt-bindings/clock/rockchip,rk3588-cru.h>
>>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>>> +    #include <dt-bindings/interrupt-controller/irq.h>
>>> +    #include <dt-bindings/power/rk3588-power.h>
>>> +    #include <dt-bindings/reset/rockchip,rk3588-cru.h>
>>> +    hdmirx_ctrler: hdmirx-controller at fdee0000 {
>>
>> What is hdmirx-controller? Isn't this just hdmi@?
>>
> 
> Writing just hdmi would imply hdmi output I think so that name
> will not be appropriate here.
> 
>> Node names should be generic. See also an explanation and list of
>> examples (not exhaustive) in DT specification:
>> https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
>>
> 
> This documentation doesn't have any generic name for HDMI INPUT
> but maybe we can use the name hdmi-receiver like some other existing
> binding has it here :-
> Documentation/devicetree/bindings/media/i2c/tda1997x.txt

Yes, it is fine. You did not respond to other comments, so I assume you
agree with them.

Best regards,
Krzysztof



From romain.gantois at bootlin.com  Thu Feb 22 00:31:33 2024
From: romain.gantois at bootlin.com (Romain Gantois)
Date: Thu, 22 Feb 2024 09:31:33 +0100 (CET)
Subject: [PATCH net-next v4 2/7] net: phylink: add rxc_always_on flag to
 phylink_pcs
In-Reply-To: <20240221190740.GG722610@kernel.org>
References: <20240221-rxc_bugfix-v4-0-4883ee1cc7b1@bootlin.com> <20240221-rxc_bugfix-v4-2-4883ee1cc7b1@bootlin.com> <20240221190740.GG722610@kernel.org>
Message-ID: <46da0819-13f6-c44c-eee0-fb87468ffe51@bootlin.com>

Hello Simon,

On Wed, 21 Feb 2024, Simon Horman wrote:

> > + * driver authors should consider whether their target device is to be used in
> > + * conjunction with a MAC device whose driver calls phylink_pcs_pre_init(). MAC
> > + * driver authors should document their requirements for the PCS
> > + * pre-initialization.
> > + *
> > + */
> > +int pcs_config(struct phylink_pcs *pcs);
Yes it should, thank you for pointing that out.

Best Regards,

-- 
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From peng.fan at oss.nxp.com  Thu Feb 22 00:32:05 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 22 Feb 2024 08:32:05 +0000
Subject: [PATCH] firmware: arm_scmi: Add support for multiple vendors
 custom protocols
In-Reply-To: <20240221220426.1205146-1-cristian.marussi@arm.com>
References: <20240221220426.1205146-1-cristian.marussi@arm.com>
Message-ID: <DU0PR04MB941736B537D71D920C8434AA88562@DU0PR04MB9417.eurprd04.prod.outlook.com>

Hi Cristian,

> Subject: [PATCH] firmware: arm_scmi: Add support for multiple vendors
> custom protocols

Do you have an example how to test this? Could this be used for pinctrl imx?

Thanks,
Peng.

> 
> Add a mechanism to be able to tag vendor protocol modules at compile-time
> with a vendor/sub_vendor string and an implementation version and then to
> choose to load, at run-time, only those vendor protocol modules matching as
> close as possible the vendor/subvendor identification advertised by the SCMI
> platform server.
> 
> In this way, any in-tree existent vendor protocol module can be build and
> shipped by default in a single kernel image, even when using the same
> clashing protocol identification numbers, since the SCMI core will take care at
> run-time to load only the ones pertinent to the running system.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> ---
> Hi all,
> 
> this is meant to address the possibility of having multiple vendors
> implementing distinct SCMI vendor protocols with possibly the same
> overlapping protocol number without the need of crafting the Kconfig at
> compile time to include only wanted protos (and without the need for a
> lottery :P)
> 
> Basic idea is simple:
> 
> - vendor protos HAS to be 'tagged' at build time with a vendor_id
> - vendor protos COULD also optionally be tagged at build time with
> sub_vendor_id and implemetation version
> 
> - at init all the build vendor protos are registerd with the SCMI core
>   using a key derived from the above tags
> 
> - at SCMI probe time the platform is identified via Base protocol as
>   usual and all the required vendor protos (i.e. IDs defined in the DT
>   as usual) are loaded after a lookup process based on the following rules:
> 
>   + protocol DB is searched using the platform/Base runtime provided tags
> 
>   	<vendor> / <sub_vendor> / <impl_ver>
> 
>     using the the following search logic (keys), first match:
> 
>      1. proto_id / <vendor_id> / <sub_vendor_id> / <impl_ver>
> 
>      2. proto_id / <vendor_id> / <sub_vendor_id> / 0
> 
>      3. proto_id / <vendor_id> / NULL / 0
> 
>   IOW, closest match, depending on how much fine grained is your
>   protocol tuned (tagged) for the platform.
> 
>   I am doubtful about the usage of <impl_ver>, and tempted to drop it
>   since we have anyway protocol version and
> NEGOTIATE_PROTOCOL_VERSION
>   to deal with slight difference in fw revision...
> 
> Based on sudeep/for-linux-next on top of
> 
> 	1c2c88cfcb2b ("clk: scmi: Support get/set duty_cycle operations")
> 
> Minimally tested ....
> 
>   Any feedback welcome
> 
>   Thanks,
>   Cristian
> ---
>  drivers/firmware/arm_scmi/driver.c    | 166 ++++++++++++++++++++++----
>  drivers/firmware/arm_scmi/protocols.h |   5 +
>  2 files changed, 149 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/driver.c
> b/drivers/firmware/arm_scmi/driver.c
> index 34d77802c990..8fb2903698c9 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -33,6 +33,7 @@
>  #include <linux/processor.h>
>  #include <linux/refcount.h>
>  #include <linux/slab.h>
> +#include <linux/xarray.h>
> 
>  #include "common.h"
>  #include "notify.h"
> @@ -44,8 +45,7 @@
> 
>  static DEFINE_IDA(scmi_id);
> 
> -static DEFINE_IDR(scmi_protocols);
> -static DEFINE_SPINLOCK(protocol_lock);
> +static DEFINE_XARRAY(scmi_protocols);
> 
>  /* List of all SCMI devices active in system */  static LIST_HEAD(scmi_list);
> @@ -194,11 +194,90 @@ struct scmi_info {
>  #define bus_nb_to_scmi_info(nb)	container_of(nb, struct scmi_info,
> bus_nb)
>  #define req_nb_to_scmi_info(nb)	container_of(nb, struct scmi_info,
> dev_req_nb)
> 
> -static const struct scmi_protocol *scmi_protocol_get(int protocol_id)
> +static unsigned long
> +scmi_vendor_protocol_signature(unsigned protocol_id, char *vendor_id,
> +			       char *sub_vendor_id, u32 impl_ver)
>  {
> -	const struct scmi_protocol *proto;
> +	char *signature, *p;
> +	unsigned long hash = 0;
> 
> -	proto = idr_find(&scmi_protocols, protocol_id);
> +	/* vendor_id/sub_vendor_id guaranteed <=
> SCMI_SHORT_NAME_MAX_SIZE */
> +	signature = kasprintf(GFP_KERNEL, "%02X|%s|%s|0x%08X",
> protocol_id,
> +			      vendor_id ?: "", sub_vendor_id ?: "", impl_ver);
> +	if (!signature)
> +		return 0;
> +
> +	p = signature;
> +	while (*p)
> +		hash = partial_name_hash(tolower(*p++), hash);
> +	hash = end_name_hash(hash);
> +
> +	kfree(signature);
> +
> +	return hash;
> +}
> +
> +static unsigned long
> +scmi_protocol_key_calculate(int protocol_id, char *vendor_id,
> +			    char *sub_vendor_id, u32 impl_ver) {
> +	if (protocol_id < SCMI_PROTOCOL_VENDOR)
> +		return protocol_id;
> +	else
> +		return scmi_vendor_protocol_signature(protocol_id,
> vendor_id,
> +						      sub_vendor_id,
> impl_ver);
> +}
> +
> +static const struct scmi_protocol *
> +scmi_vendor_protocol_lookup(int protocol_id, char *vendor_id,
> +			    char *sub_vendor_id, u32 impl_ver) {
> +	unsigned long key;
> +	struct scmi_protocol *proto = NULL;
> +
> +	/* Searching for closest match ...*/
> +	key = scmi_protocol_key_calculate(protocol_id, vendor_id,
> +					  sub_vendor_id, impl_ver);
> +	if (key)
> +		proto = xa_load(&scmi_protocols, key);
> +
> +	if (proto)
> +		return proto;
> +
> +	/* Any match on vendor/sub_vendor ? */
> +	if (impl_ver) {
> +		key = scmi_protocol_key_calculate(protocol_id, vendor_id,
> +						  sub_vendor_id, 0);
> +		if (key)
> +			proto = xa_load(&scmi_protocols, key);
> +
> +		if (proto)
> +			return proto;
> +	}
> +
> +	/* Any match on just the vendor ? */
> +	if (sub_vendor_id) {
> +		key = scmi_protocol_key_calculate(protocol_id, vendor_id,
> +						  NULL, 0);
> +		if (key)
> +			proto = xa_load(&scmi_protocols, key);
> +	}
> +
> +	return proto;
> +}
> +
> +static const struct scmi_protocol *
> +scmi_protocol_get(int protocol_id, struct scmi_revision_info *version)
> +{
> +	const struct scmi_protocol *proto = NULL;
> +
> +	if (protocol_id < SCMI_PROTOCOL_VENDOR)
> +		proto = xa_load(&scmi_protocols, protocol_id);
> +	else
> +		proto = scmi_vendor_protocol_lookup(protocol_id,
> +						    version->vendor_id,
> +						    version->sub_vendor_id,
> +						    version->impl_ver);
>  	if (!proto || !try_module_get(proto->owner)) {
>  		pr_warn("SCMI Protocol 0x%x not found!\n", protocol_id);
>  		return NULL;
> @@ -206,21 +285,47 @@ static const struct scmi_protocol
> *scmi_protocol_get(int protocol_id)
> 
>  	pr_debug("Found SCMI Protocol 0x%x\n", protocol_id);
> 
> +	if (protocol_id >= SCMI_PROTOCOL_VENDOR)
> +		pr_info("Loaded SCMI Vendor Protocol 0x%x - %s %s %X\n",
> +			protocol_id, proto->vendor_id ?: "",
> +			proto->sub_vendor_id ?: "", proto->impl_ver);
> +
>  	return proto;
>  }
> 
> -static void scmi_protocol_put(int protocol_id)
> +static void scmi_protocol_put(const struct scmi_protocol *proto)
>  {
> -	const struct scmi_protocol *proto;
> -
> -	proto = idr_find(&scmi_protocols, protocol_id);
>  	if (proto)
>  		module_put(proto->owner);
>  }
> 
> +static int scmi_vendor_protocol_check(const struct scmi_protocol
> +*proto) {
> +	if (!proto->vendor_id) {
> +		pr_err("missing vendor_id for protocol 0x%x\n", proto->id);
> +		return -EINVAL;
> +	}
> +
> +	if (proto->vendor_id &&
> +	    strlen(proto->vendor_id) >= SCMI_SHORT_NAME_MAX_SIZE) {
> +		pr_err("malformed vendor_id for protocol 0x%x\n", proto-
> >id);
> +		return -EINVAL;
> +	}
> +
> +	if (proto->sub_vendor_id &&
> +	    strlen(proto->sub_vendor_id) >= SCMI_SHORT_NAME_MAX_SIZE) {
> +		pr_err("malformed sub_vendor_id for protocol 0x%x\n",
> +		       proto->id);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  int scmi_protocol_register(const struct scmi_protocol *proto)  {
>  	int ret;
> +	unsigned long key;
> 
>  	if (!proto) {
>  		pr_err("invalid protocol\n");
> @@ -232,12 +337,23 @@ int scmi_protocol_register(const struct
> scmi_protocol *proto)
>  		return -EINVAL;
>  	}
> 
> -	spin_lock(&protocol_lock);
> -	ret = idr_alloc(&scmi_protocols, (void *)proto,
> -			proto->id, proto->id + 1, GFP_ATOMIC);
> -	spin_unlock(&protocol_lock);
> -	if (ret != proto->id) {
> -		pr_err("unable to allocate SCMI idr slot for 0x%x - err %d\n",
> +	if (proto->id >= SCMI_PROTOCOL_VENDOR &&
> +	    scmi_vendor_protocol_check(proto))
> +		return -EINVAL;
> +
> +	/*
> +	 * Calculate a protocol key to register this protocol with the core;
> +	 * key value 0 is considered invalid.
> +	 */
> +	key = scmi_protocol_key_calculate(proto->id, proto->vendor_id,
> +					  proto->sub_vendor_id,
> +					  proto->impl_ver);
> +	if (!key)
> +		return -EINVAL;
> +
> +	ret = xa_insert(&scmi_protocols, key, (void *)proto, GFP_KERNEL);
> +	if (ret) {
> +		pr_err("unable to allocate SCMI protocol slot for 0x%x -
> err %d\n",
>  		       proto->id, ret);
>  		return ret;
>  	}
> @@ -250,9 +366,15 @@ EXPORT_SYMBOL_GPL(scmi_protocol_register);
> 
>  void scmi_protocol_unregister(const struct scmi_protocol *proto)  {
> -	spin_lock(&protocol_lock);
> -	idr_remove(&scmi_protocols, proto->id);
> -	spin_unlock(&protocol_lock);
> +	unsigned long key;
> +
> +	key = scmi_protocol_key_calculate(proto->id, proto->vendor_id,
> +					  proto->sub_vendor_id,
> +					  proto->impl_ver);
> +	if (!key)
> +		return;
> +
> +	xa_erase(&scmi_protocols, key);
> 
>  	pr_debug("Unregistered SCMI Protocol 0x%x\n", proto->id);  } @@ -
> 1888,7 +2010,7 @@ scmi_alloc_init_protocol_instance(struct scmi_info *info,
>  	/* Protocol specific devres group */
>  	gid = devres_open_group(handle->dev, NULL, GFP_KERNEL);
>  	if (!gid) {
> -		scmi_protocol_put(proto->id);
> +		scmi_protocol_put(pi->proto);
>  		goto out;
>  	}
> 
> @@ -1952,7 +2074,7 @@ scmi_alloc_init_protocol_instance(struct scmi_info
> *info,
> 
>  clean:
>  	/* Take care to put the protocol module's owner before releasing all
> */
> -	scmi_protocol_put(proto->id);
> +	scmi_protocol_put(proto);
>  	devres_release_group(handle->dev, gid);
>  out:
>  	return ERR_PTR(ret);
> @@ -1986,7 +2108,7 @@ scmi_get_protocol_instance(const struct
> scmi_handle *handle, u8 protocol_id)
>  		const struct scmi_protocol *proto;
> 
>  		/* Fails if protocol not registered on bus */
> -		proto = scmi_protocol_get(protocol_id);
> +		proto = scmi_protocol_get(protocol_id, &info->version);
>  		if (proto)
>  			pi = scmi_alloc_init_protocol_instance(info, proto);
>  		else
> @@ -2041,7 +2163,7 @@ void scmi_protocol_release(const struct
> scmi_handle *handle, u8 protocol_id)
> 
>  		idr_remove(&info->protocols, protocol_id);
> 
> -		scmi_protocol_put(protocol_id);
> +		scmi_protocol_put(pi->proto);
> 
>  		devres_release_group(handle->dev, gid);
>  		dev_dbg(handle->dev, "De-Initialized protocol: 0x%X\n", diff
> --git a/drivers/firmware/arm_scmi/protocols.h
> b/drivers/firmware/arm_scmi/protocols.h
> index 693019fff0f6..cb8dbc93584b 100644
> --- a/drivers/firmware/arm_scmi/protocols.h
> +++ b/drivers/firmware/arm_scmi/protocols.h
> @@ -29,6 +29,8 @@
>  #define PROTOCOL_REV_MAJOR(x)
> 	((u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x))))
>  #define PROTOCOL_REV_MINOR(x)
> 	((u16)(FIELD_GET(PROTOCOL_REV_MINOR_MASK, (x))))
> 
> +#define SCMI_PROTOCOL_VENDOR	0x80
> +
>  enum scmi_common_cmd {
>  	PROTOCOL_VERSION = 0x0,
>  	PROTOCOL_ATTRIBUTES = 0x1,
> @@ -330,6 +332,9 @@ struct scmi_protocol {
>  	const void				*ops;
>  	const struct scmi_protocol_events	*events;
>  	unsigned int				supported_version;
> +	u32					impl_ver;
> +	char					*vendor_id;
> +	char					*sub_vendor_id;
>  };
> 
>  #define DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(name, proto)	\
> --
> 2.43.0



From krzysztof.kozlowski at linaro.org  Thu Feb 22 00:40:08 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 09:40:08 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <874je1ipb4.fsf@minerva.mail-host-address-is-not-set>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
 <9083c414-62f2-4bff-93ee-13f8ff60eb34@linaro.org>
 <874je1ipb4.fsf@minerva.mail-host-address-is-not-set>
Message-ID: <bd071521-7f7b-41e8-8786-ad2eeb58b03e@linaro.org>

On 21/02/2024 20:34, Javier Martinez Canillas wrote:
> Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> writes:
> 
>> On 21/02/2024 16:24, Maxime Ripard wrote:
>>> On Wed, Feb 21, 2024 at 04:10:12PM +0100, Krzysztof Kozlowski wrote:
>>>> On 21/02/2024 15:48, Maxime Ripard wrote:
>>>>> On Wed, Feb 21, 2024 at 03:22:38PM +0100, Krzysztof Kozlowski wrote:
>>>>>> On 21/02/2024 15:13, Javier Martinez Canillas wrote:
>>>>>>> These options are needed by some Linux distributions (e.g: Fedora), so
>>>>>>
>>>>>> How ZRAM is needed? Why Fedora cannot boot without it? Debian, which I
>>>>>> use on my arm64 boards, does not have any problem.
>>>>>
>>>>> Is it relevant in any way?
>>>>
>>>> Yes, because it is justification why we are doing it. Each commit is
>>>> supposed to explain "why" and the explanation here is not enough.
>>>
>>> There's a why though: it makes Fedora boot. It might not be enough for
>>
>> I want to know to understand. Maybe it is not really neeed but "nice to
>> have"? People write various vague statements...
>>
> 
> I usually try hard not to be vague. There was a why, it wasn't enough for
> you and that's fair.
> 
> But I think the crux of the why was explained: I don't want to remember
> each time that need to troubleshoot something, what options are missing
> in order to boot Fedora.
> 
>>> you, but that's a different story. So, if it's not enough, please state
>>> exactly what you expect from that patch description so Javier can
>>> provide it.
>>
>> Any explanation what ZRAM is necessary for Fedora to boot.
>>
> 
> I mentioned already in another email, Fedora is enabling the systemd
> zram-generator and not having a /dev/zram0 slows down the boot to the
> point of being unusable. One could disable that service but then is yet

That one sentence would be enough for me.

> another thing to remember when trying to boot an upstream kernel built.
> 
> Could had added all this information to the commit message but I thought
> that it would be too much...
> 
>>>
>>>>> I'm sure Debian can boot without MEMORY_HOTREMOVE, or BRIDGE, or
>>>>> NUMA_BALANCING, or BPF_JIT, or NFS_FS, yet all of them are enabled. Let
>>>>> me know if you want hundreds more examples.
>>>>
>>>> So if there is any bug, you are allowed to add new one? If there is any
>>>> silly option, you are allowed to add new one?
>>>>
>>>> Feel free to propose dropping of any irrelevant options.
>>>
>>> No, of course you aren't. My point is that Fedora is a distro just as
>>> established and legitimate as Debian is. And apparently "it makes Debian
>>> works" is a reasonable argument, since, well, it does.
>>>
>>> If making Fedora boot with that defconfig is not a legitimate goal,
>>
>> It is, but I asked for more information.
>>
>>> please state why, and document it (with the ack of all the maintainers
>>> involved with that defconfig, obviously) so we don't have the same
>>> argument over and over again.
>>>
>>>>>> I kind of repeat comments from similar patch earlier:
>>>>>> https://lore.kernel.org/all/fe1e74a2-e933-7cd9-f740-86d871076191 at linaro.org/
>>>>>>
>>>>>> About XFS: I don't think it is needed to boot anything.
>>>>>
>>>>> Just like 9P_FS, NFS or UBIFS.
>>>>
>>>> NFS is often used on targets, e.g. my board farm, but also by other people.
>>>>
>>>> UBIFS was added recently because one device was using it - you needed
>>>> it. 9P_FS looks unnecessary.
>>>
>>> So all we need is one person or use case to require it? Sounds like
>>> we've checked that mark here.
>>
>> Use case of given type. I would disagree for SMBFS because we have NFS.
>> UBIFS is hardware requirement. 9P_FS seems like virtio case.
>>
> 
> So that means that for aarch64, some filesystems have more precedence over
> others? It's OK to have ext4 or btrfs but no xfs? Honestly it seems quite
> arbitrary and subjective for me.

Yes, subjective, but to be honest: I would drop Btrfs. I was thinking
about it, but since Arnd agrees on XFS I won't fight that battle.

> 
>>>
>>>>>> This is a defconfig, not a distro config. Please don't make it distro.
>>>>>>
>>>>>> I will gladly support things needed by systemd or equivalent, but not
>>>>>> unusual filesystems needed by distro.
>>>>>
>>>>> It's a defconfig. It's whatever people want it to be. Or we need to come
>>>>> up with a clearly defined set of rules of what is acceptable in that
>>>>> defconfig or not, and prune every option that isn't.
>>>>
>>>> So that's the rule I am commenting from time to time. defconfigs are not
>>>> distro configs. These are reference hardware configs and debugging
>>>> configs.
>>>
>>> Supporting a board farm is hardly either.
>>
>> Debugging purpose, but I agree we can drop it.
>>
>>>
>>> And again, I've never heard of such rule for that defconfig in my ~10y
>>> as an ARM platform maintainer. But what do I know, right?
>>>
>>>> I was working in distro so trust me - they do stuff differently
>>>> and they not need XFS in our defconfig for anything.
>>>
> 
> Which distro? Every one uses a different filesystem. SUSE uses btrfs,
> Debian I think ext4, Fedora uses xfs and so on. It's OK if the policy
> is that the defconfig should only be compatible with Debian, but then
> should be written somewhere.

Hm, don't all these distros support choosing the filesystem? I did not
propose Ext4 because Debian is more important or something, but because
we need to choose something and it is kind of default for many people.

> 
>>> Sure, but you're not just arguing for XFS there.
>>
>> I raised need for "why" for ZRAM and un-necessity of XFS. What's wrong
>> with that? I should send separate emails or what?
>>
>>>
>>> What I really don't get is this: this makes the life of people easier.
>>
>> Again: this makes my life harder. I cannot be buying new machines every
>> two years to be able to compile defconfig while testing/working.
>>
> 
> And not having it enabled makes my life (and other fedora users) harder
> because xfs needs to be enabled every time that an upstream kernel needs
> to be tested.

We can here disagree that we might have a bit different needs... I just
provided argument why I object.

> 
>>>
>>> Being able to test an upstream kernel quickly when you have a bug in a
>>> downstream distro is super valuable for any distro developper. And on
>>
>> That's a distro need, not relevant. And even if it was, then your
>> argument would be "let's enable everything distro has!". This is not a
>> distro kernel.
>>
> 
> It's not a distro need in my opinion but an upstream kernel developer
> need. If I have had chosen xfs for personal preference, would that be
> any different?
> 
>>
>>> the long run, if we don't make the switch from a kernel distro to a
>>> mainline kernel relatively easy, we're the ones that will lose out.
>>> Because people just won't bother, or be frustrated and thus super
>>> reluctant to do that work.
>>>
>>> That's the part I don't get. Why do we want to make the life of people
>>> harder. This patch has never been about making the defconfig the main
>>
>> Because it makes my life harder and I don't see benefits. Quoting Arnd:
>> "Unfortunately this will increase build time noticeably, but"
>>
> 
> The benefit is for developers who use Fedora to be able to boot their
> kernels built using defconfig, just like developers using other distros
> can now. We already have ext4 and btrfs, but somehow xfs is not OK.

I would drop btrfs :)

Best regards,
Krzysztof



From lkp at intel.com  Thu Feb 22 00:30:12 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 22 Feb 2024 16:30:12 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS
 704dccec0d490f2ad06f3f16ebed254d81906c3a
Message-ID: <202402221606.gLbDCT59-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: 704dccec0d490f2ad06f3f16ebed254d81906c3a  arm64: dts: qcom: Fix interrupt-map cell sizes

elapsed time: 947m

configs tested: 158
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                   randconfig-001-20240222   gcc  
arc                   randconfig-002-20240222   gcc  
arc                    vdk_hs38_smp_defconfig   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                     am200epdkit_defconfig   gcc  
arm                       aspeed_g5_defconfig   gcc  
arm                                 defconfig   clang
arm                        multi_v7_defconfig   gcc  
arm                        neponset_defconfig   gcc  
arm                       omap2plus_defconfig   gcc  
arm                   randconfig-001-20240222   gcc  
arm                   randconfig-002-20240222   gcc  
arm                           tegra_defconfig   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-002-20240222   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240222   gcc  
csky                  randconfig-002-20240222   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-001-20240222   gcc  
i386         buildonly-randconfig-002-20240222   clang
i386         buildonly-randconfig-003-20240222   clang
i386         buildonly-randconfig-004-20240222   gcc  
i386         buildonly-randconfig-005-20240222   clang
i386         buildonly-randconfig-006-20240222   gcc  
i386                                defconfig   clang
i386                  randconfig-001-20240222   clang
i386                  randconfig-002-20240222   clang
i386                  randconfig-003-20240222   gcc  
i386                  randconfig-004-20240222   clang
i386                  randconfig-005-20240222   gcc  
i386                  randconfig-006-20240222   clang
i386                  randconfig-011-20240222   gcc  
i386                  randconfig-012-20240222   clang
i386                  randconfig-013-20240222   gcc  
i386                  randconfig-014-20240222   gcc  
i386                  randconfig-015-20240222   clang
i386                  randconfig-016-20240222   gcc  
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240222   gcc  
loongarch             randconfig-002-20240222   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
m68k                          multi_defconfig   gcc  
m68k                        stmark2_defconfig   gcc  
microblaze                       alldefconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                      pic32mzda_defconfig   gcc  
nios2                         10m50_defconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240222   gcc  
nios2                 randconfig-002-20240222   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
parisc                           alldefconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                randconfig-001-20240222   gcc  
parisc                randconfig-002-20240222   gcc  
parisc64                            defconfig   gcc  
powerpc                    adder875_defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc                        cell_defconfig   gcc  
powerpc                      ppc64e_defconfig   gcc  
powerpc                         wii_defconfig   gcc  
powerpc64             randconfig-003-20240222   gcc  
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                 randconfig-002-20240222   gcc  
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240222   gcc  
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                         ap325rxa_defconfig   gcc  
sh                                  defconfig   gcc  
sh                 kfr2r09-romimage_defconfig   gcc  
sh                          polaris_defconfig   gcc  
sh                    randconfig-001-20240222   gcc  
sh                    randconfig-002-20240222   gcc  
sh                          rsk7264_defconfig   gcc  
sh                          sdk7780_defconfig   gcc  
sh                           se7705_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240222   gcc  
sparc64               randconfig-002-20240222   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-003-20240222   gcc  
x86_64       buildonly-randconfig-005-20240222   gcc  
x86_64       buildonly-randconfig-006-20240222   gcc  
x86_64                              defconfig   gcc  
x86_64                randconfig-005-20240222   gcc  
x86_64                randconfig-006-20240222   gcc  
x86_64                randconfig-012-20240222   gcc  
x86_64                randconfig-014-20240222   gcc  
x86_64                randconfig-074-20240222   gcc  
x86_64                randconfig-075-20240222   gcc  
x86_64                randconfig-076-20240222   gcc  
x86_64                          rhel-8.3-rust   clang
x86_64                               rhel-8.3   gcc  
xtensa                            allnoconfig   gcc  
xtensa                randconfig-001-20240222   gcc  
xtensa                randconfig-002-20240222   gcc  
xtensa                    xip_kc705_defconfig   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From bhargav.r at ltts.com  Thu Feb 22 00:43:09 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Thu, 22 Feb 2024 14:13:09 +0530
Subject: [RESEND PATCH v1 05/13] mfd: tps6594-spi: Add TI TPS65224 PMIC SPI
In-Reply-To: <7hcysy6ho6.fsf@baylibre.com>
References: <7hcysy6ho6.fsf@baylibre.com>
Message-ID: <20240222084309.6008-1-bhargav.r@ltts.com>

Hello Kevin,
On Wed, 14 Feb 2024 10:10:17 -0800, Kevin wrote:
> Bhargav Raviprakash <bhargav.r at ltts.com> writes:
> 
> > Add support for TPS65224 PMIC in the TPS6594 driver as they share
> > significant functional overlap.
> >
> > Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> > ---
> >  drivers/mfd/tps6594-spi.c | 16 ++++++++++------
> >  1 file changed, 10 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
> > index 5afb1736f..7ec66d31b 100644
> > --- a/drivers/mfd/tps6594-spi.c
> > +++ b/drivers/mfd/tps6594-spi.c
> > @@ -1,6 +1,6 @@
> >  // SPDX-License-Identifier: GPL-2.0
> >  /*
> > - * SPI access driver for TI TPS6594/TPS6593/LP8764 PMICs
> > + * SPI access driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
> >   *
> >   * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
> >   */
> > @@ -66,7 +66,7 @@ static int tps6594_spi_reg_write(void *context, unsigned int reg, unsigned int v
> >  	return spi_write(spi, buf, count);
> >  }
> >  
> > -static const struct regmap_config tps6594_spi_regmap_config = {
> > +static struct regmap_config tps6594_spi_regmap_config = {
> >  	.reg_bits = 16,
> >  	.val_bits = 8,
> >  	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
> > @@ -81,6 +81,7 @@ static const struct of_device_id tps6594_spi_of_match_table[] = {
> >  	{ .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
> >  	{ .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
> >  	{ .compatible = "ti,lp8764-q1",  .data = (void *)LP8764,  },
> > +	{ .compatible = "ti,tps65224-q1", .data = (void *)TPS65224, },
> >  	{}
> >  };
> >  MODULE_DEVICE_TABLE(of, tps6594_spi_of_match_table);
> > @@ -101,15 +102,18 @@ static int tps6594_spi_probe(struct spi_device *spi)
> >  	tps->reg = spi_get_chipselect(spi, 0);
> >  	tps->irq = spi->irq;
> >  
> > -	tps->regmap = devm_regmap_init(dev, NULL, spi, &tps6594_spi_regmap_config);
> > -	if (IS_ERR(tps->regmap))
> > -		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
> > -
> >  	match = of_match_device(tps6594_spi_of_match_table, dev);
> >  	if (!match)
> >  		return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n");
> >  	tps->chip_id = (unsigned long)match->data;
> >  
> > +	if (tps->chip_id == TPS65224)
> > +		tps6594_spi_regmap_config.volatile_table = &tps65224_volatile_table;
> 
> Similar to my comment on the i2c series, but to be more specific:
> 
> Rather than use the .data pointer in the of_match_table as simply a
> chip_id, instead make that into a struct that can contain chip-specific
> values/pointers etc, and then each compatible can have a custom struct
> (if needed.)
> 
> This way, at probe/match time, all the chip-specific data is setup using
> that struct, so that at runtime, there doesn't need to be any "if
> (chip_id)" checking.
> 
> Kevin

Thanks for the feedback!
We will implement the same in the next version.

Regards,
Bhargav


From adeep at lexina.in  Thu Feb 22 00:46:46 2024
From: adeep at lexina.in (Viacheslav)
Date: Thu, 22 Feb 2024 11:46:46 +0300
Subject: [PATCH v2 2/3] soc: amlogic: meson-gx-socinfo-sm: Add Amlogic
 secure-monitor SoC Information driver
In-Reply-To: <202402221322.ifGMGQa6-lkp@intel.com>
References: <20240221143654.544444-3-adeep@lexina.in>
 <202402221322.ifGMGQa6-lkp@intel.com>
Message-ID: <16891eb5-ee2e-4b0d-a82d-517adf028474@lexina.in>

Hi!

Will be fixed in next version with new Kconfig dependencies:

     depends on (ARM64 && ARCH_MESON || COMPILE_TEST) && MESON_SM=y
     default ARCH_MESON && MESON_SM

22/02/2024 08.35, kernel test robot wrote:
> Hi Viacheslav,
> 
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on 9fc1ccccfd8d53dc7936fe6d633f2373fc9f62e8]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Viacheslav-Bocharov/soc-amlogic-meson-gx-socinfo-move-common-code-to-header-file/20240221-224803
> base:   9fc1ccccfd8d53dc7936fe6d633f2373fc9f62e8
> patch link:    https://lore.kernel.org/r/20240221143654.544444-3-adeep%40lexina.in
> patch subject: [PATCH v2 2/3] soc: amlogic: meson-gx-socinfo-sm: Add Amlogic secure-monitor SoC Information driver
> config: arm64-randconfig-002-20240222 (https://download.01.org/0day-ci/archive/20240222/202402221322.ifGMGQa6-lkp at intel.com/config)
> compiler: aarch64-linux-gcc (GCC) 13.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240222/202402221322.ifGMGQa6-lkp at intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp at intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202402221322.ifGMGQa6-lkp at intel.com/
> 
> All errors (new ones prefixed by >>):
> 
>     aarch64-linux-ld: Unexpected GOT/PLT entries detected!
>     aarch64-linux-ld: Unexpected run-time procedure linkages detected!
>     aarch64-linux-ld: drivers/soc/amlogic/meson-gx-socinfo-sm.o: in function `socinfo_get_chipid':
>>> meson-gx-socinfo-sm.c:(.text+0xac): undefined reference to `meson_sm_call_read'
>     aarch64-linux-ld: drivers/soc/amlogic/meson-gx-socinfo-sm.o: in function `meson_gx_socinfo_sm_probe':
>>> meson-gx-socinfo-sm.c:(.text+0x438): undefined reference to `meson_sm_get'
> 


From andi.shyti at kernel.org  Thu Feb 22 00:47:23 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Thu, 22 Feb 2024 09:47:23 +0100
Subject: [PATCH v3] i2c: imx: when being a target, mark the last read
 as processed
In-Reply-To: <20240221193013.14233-2-wsa+renesas@sang-engineering.com>
References: <20240221193013.14233-2-wsa+renesas@sang-engineering.com>
Message-ID: <170859164340.336357.16059990973960196120.b4-ty@kernel.org>

Hi

On Wed, 21 Feb 2024 20:27:13 +0100, Wolfram Sang wrote:
> When being a target, NAK from the controller means that all bytes have
> been transferred. So, the last byte needs also to be marked as
> 'processed'. Otherwise index registers of backends may not increase.
> 
> 

Applied to i2c/i2c-host-fixes on

git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git

Thank you,
Andi

Patches applied
===============
[1/1] i2c: imx: when being a target, mark the last read as processed
      commit: cf8281b1aeab93a03c87033a741075c39ace80d4



From arnaud.pouliquen at foss.st.com  Thu Feb 22 00:47:51 2024
From: arnaud.pouliquen at foss.st.com (Arnaud POULIQUEN)
Date: Thu, 22 Feb 2024 09:47:51 +0100
Subject: [PATCH v3 0/7] Introduction of a remoteproc tee to load signed
 firmware
In-Reply-To: <fe4ec29f-7521-4369-a382-bae50dbf0ee5@quicinc.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <fe4ec29f-7521-4369-a382-bae50dbf0ee5@quicinc.com>
Message-ID: <adcf0c0d-f452-4285-8651-c147fcca001b@foss.st.com>

Hello Naman,

On 2/22/24 06:43, Naman Jain wrote:
> On 2/14/2024 10:51 PM, Arnaud Pouliquen wrote:
>> Updates from the previous version [1]:
>>
>> This version proposes another approach based on an alternate load and boot
>> of the coprocessor. Therefore, the constraint introduced by tee_remoteproc
>> is that the firmware has to be authenticated and loaded before the resource
>> table can be obtained.
>>
>> The existing boot sequence is: >
>> ?? 1) Get the resource table and store it in a cache,
>> ????? calling rproc->ops->parse_fw().
>> ?? 2) Parse the resource table and handle resources,
>> ????? calling rproc_handle_resources.
>> ?? 3) Load the firmware, calling rproc->ops->load().
>> ?? 4) Start the firmware, calling rproc->ops->start().
>> ? => Steps 1 and 2 are executed in rproc_fw_boot(), while steps 3 and 4 are
>> ??? executed in rproc_start().
>> => the use of rproc->ops->load() ops is mandatory
>>
>> The boot sequence needed for TEE boot is:
>>
>> ?? 1) Load the firmware.
>> ?? 2) Get the loaded resource, no cache.
>> ?? 3) Parse the resource table and handle resources.
>> ?? 4) Start the firmware.
> 
> Hi,
> What problem are we really addressing here by reordering load, parse of
> FW resources?

The feature introduced in TEE is the signature of the firmware images. That
means that before getting the resource table, we need to first authenticate the
firmware images.
Authenticating a firmware image means that we have to copy the firmware into
protected memory that cannot be corrupted by the non-secure and then verify the
signature.
The strategy implemented in OP-TEE is to load the firmware into destination
memory and then authenticate it.
This strategy avoids having a temporary copy of the whole images in a secure memory.
This strategy imposes loading the firmware images before retrieving the resource
table.

> Basically, what are the limitations of the current design you are referring to?
> I understood that TEE is designed that way.

The limitation of the current design is that we obtain the resource table before
loading the firmware. Following the current design would impose constraints in
TEE that are not straightforward. Step 1 (getting the resource table and storing
it in a cache) would require having a copy of the resource table in TEE after
authenticating the images. However, authenticating the firmware, as explained
before, depends on the strategy implemented. In TEE implementation, we load the
firmware to authenticate it in the destination memory.

Regards,
Arnaud

> 
>>
>> Then the crash recovery also has to be managed.For recovery, the cache is
>> used to temporarily save the resource table and then reapply it on
>> restart:
>> ?? 1) Stop the remote processor, calling rproc->ops->stop().
>> ?? 2) Load the firmware, calling rproc->ops->load().
>> ?? 3) Copy cached resource table.
>> ?? 4) Start the remote processor, calling rproc->ops->start().
>>
>> => This sequence is also needed when TEE manages the boot of the remote
>> ??? processor.
>> => The rproc->ops->load() is also used in recovery sequence.
>>
>> Based on the sequences described above, the proposal is to:
>>
>> - Rework tee_rproc API to better match the rproc_ops structure.
>> ?? This allows to simply map the function to implement the load ops, which
>> ?? is not optional. The tee_rproc_load_fw() is updated in consequence.
>> - Remove the call of rproc_load_segments from rproc_start() to dissociate
>> ?? the load and the start. This is necessary to implement the boot sequence
>> ?? requested for the TEE remote proc support.
>> - Introduce an rproc_alt_fw_boot() function that is an alternative boot
>> ?? sequence, which implements the sequence requested for the TEE remoteproc
>> ?? support.
>>
>>
>> [1]
>> https://lore.kernel.org/lkml/20240118100433.3984196-1-arnaud.pouliquen at foss.st.com/T/
>>
>>
>> Description of the feature:
>>
>> This series proposes the implementation of a remoteproc tee driver to
>> communicate with a TEE trusted application responsible for authenticating and
>> loading the remoteproc firmware image in an Arm secure context.
>>
>> 1) Principle:
>>
>> The remoteproc tee driver provides services to communicate with the OP-TEE
>> trusted application running on the Trusted Execution Context (TEE).
> 
> s/Context/Environment?
> 
>> The trusted application in TEE manages the remote processor lifecycle:
>>
>> - authenticating and loading firmware images,
>> - isolating and securing the remote processor memories,
>> - supporting multi-firmware (e.g., TF-M + Zephyr on a Cortex-M33),
>> - managing the start and stop of the firmware by the TEE.
>>
> 
> Regards,
> Naman Jain
> 


From krzysztof.kozlowski at linaro.org  Thu Feb 22 00:49:58 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 09:49:58 +0100
Subject: [PATCH v2 0/7] ARM: dts: samsung: specify the SPI FIFO depth
In-Reply-To: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
References: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
Message-ID: <be85edb1-4f65-4b5e-a137-76e4e92d8fe4@linaro.org>

On 16/02/2024 15:04, Tudor Ambarus wrote:
> Bindings patch sent but not yet integrated:
> https://lore.kernel.org/linux-spi/20240216070555.2483977-2-tudor.ambarus at linaro.org/

I still wait for bindings to be applied. This means it might be too late
to apply it for this cycle. Just letting you know, that I did not forget
about this patchset.

Best regards,
Krzysztof



From vigneshr at ti.com  Thu Feb 22 00:51:27 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 22 Feb 2024 14:21:27 +0530
Subject: [PATCH v4 1/3] dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl
 compatible
In-Reply-To: <20240205135908.54656-2-rogerq@kernel.org>
References: <20240205135908.54656-1-rogerq@kernel.org>
 <20240205135908.54656-2-rogerq@kernel.org>
Message-ID: <8a1efca0-9a63-472a-8c0f-0aeb3efa2baa@ti.com>

Hi Roger,

On 05/02/24 19:29, Roger Quadros wrote:
> Add the compatible for TI AM62 USB PHY Control register. This
> register is found in the TI AM62 WKUP_CTRL_MMR0 space [1]. It
> is used to indicate the USB PHY PLL reference clock rate and
> core voltage level to the USB controller.
> 
> [1] - https://www.ti.com/lit/pdf/spruiv7
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> Acked-by: Rob Herring <robh at kernel.org>
> ---
> 
> Notes:
>     Changelog:
>     
>     v4 - no change. Added Rob's Acked-by
>     
>     v3 - add compatibles in alphabetical order
>     https://lore.kernel.org/all/20240201120332.4811-2-rogerq at kernel.org/
>     
>     v2 - New patch
> 
>  Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml

You don't have right maintainer in CC for this file.

> index 084b5c2a2a3c..9437705af92f 100644
> --- a/Documentation/devicetree/bindings/mfd/syscon.yaml
> +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
> @@ -72,6 +72,7 @@ properties:
>                - rockchip,rk3588-qos
>                - rockchip,rv1126-qos
>                - starfive,jh7100-sysmain
> +              - ti,am62-usb-phy-ctrl
>                - ti,am654-dss-oldi-io-ctrl
>  
>            - const: syscon

-- 
Regards
Vignesh


From krzysztof.kozlowski at linaro.org  Thu Feb 22 00:55:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 09:55:26 +0100
Subject: [PATCH] MAINTAINERS: samsung: gs101: match patches touching
 Google Tensor SoC
In-Reply-To: <20240219125453.103692-1-krzysztof.kozlowski@linaro.org>
References: <20240219125453.103692-1-krzysztof.kozlowski@linaro.org>
Message-ID: <170859212673.12469.13497019748127862340.b4-ty@linaro.org>


On Mon, 19 Feb 2024 13:54:53 +0100, Krzysztof Kozlowski wrote:
> Maintainers of Google Tensor SoC should be aware of all driver patches
> having that name.
> 
> 

Applied, thanks!

[1/1] MAINTAINERS: samsung: gs101: match patches touching Google Tensor SoC
      https://git.kernel.org/krzk/linux/c/9690b9de81d1ad40a70b3d34b9d7e26486a5e83a

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From conor at kernel.org  Thu Feb 22 00:56:13 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 22 Feb 2024 08:56:13 +0000
Subject: [PATCH v3] dt-bindings: interrupt-controller: Convert Atmel AIC
 to json-schema
In-Reply-To: <20240222035158.195265-1-dharma.b@microchip.com>
References: <20240222035158.195265-1-dharma.b@microchip.com>
Message-ID: <20240222-stiffly-squeeze-b4ec2b49a4fe@spud>

> diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
> new file mode 100644
> index 000000000000..0d51bd78bf2b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
> @@ -0,0 +1,89 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interrupt-controller/atmel,aic.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Advanced Interrupt Controller (AIC)
> +
> +maintainers:
> +  - Nicolas Ferre <nicolas.ferre at microchip.com>
> +  - Dharma balasubiramani <dharma.b at microchip.com>
> +
> +description:
> +  The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
> +  maskable, vectored interrupt controller providing handling of up to one
> +  hundred and twenty-eight interrupt sources.
> +

> +allOf:
> +  - $ref: /schemas/interrupt-controller.yaml#
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: atmel,at91rm9200-aic
> +    then:
> +      properties:
> +        atmel,external-irqs:
> +          minItems: 1
> +          maxItems: 7
> +    else:
> +      properties:
> +        atmel,external-irqs:
> +          minItems: 1
> +          maxItems: 1

When there's property restrictions being applied, move the allof down
to...

> +
> +properties:
> +  compatible:
> +    enum:
> +      - atmel,at91rm9200-aic
> +      - atmel,sama5d2-aic
> +      - atmel,sama5d3-aic
> +      - atmel,sama5d4-aic
> +      - microchip,sam9x60-aic
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupt-controller: true
> +
> +  "#interrupt-cells":
> +    const: 3
> +    description: |
> +      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
> +      The 2nd cell specifies flags:
> +        bits[3:0] trigger type and level flags:
> +          1 = low-to-high edge triggered.
> +          2 = high-to-low edge triggered.
> +          4 = active high level-sensitive.
> +          8 = active low level-sensitive.
> +        Valid combinations: 1, 2, 3, 4, 8.
> +        Default for internal sources: 4 (active high).
> +      The 3rd cell specifies irq priority from 0 (lowest) to 7 (highest).
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  atmel,external-irqs:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description: u32 array of external irqs.

...here. Both work, but seeing the restrictions before you see any of
the properties is not the most understandable.

Cheers,
Conor.

> +required:
> +  - compatible
> +  - reg
> +  - interrupt-controller
> +  - "#interrupt-cells"
> +  - atmel,external-irqs
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    interrupt-controller at fffff000 {
> +      compatible = "atmel,at91rm9200-aic";
> +      reg = <0xfffff000 0x200>;
> +      interrupt-controller;
> +      #interrupt-cells = <3>;
> +      atmel,external-irqs = <31>;
> +    };
> +...
> 
> base-commit: 4f5e5092fdbf5cec6bedc19fbe69cce4f5f08372
> -- 
> 2.25.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/20240222/14a32cc8/attachment.sig>

From andi.shyti at kernel.org  Thu Feb 22 00:57:54 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Thu, 22 Feb 2024 09:57:54 +0100
Subject: [PATCH] i2c: aspeed: Fix the dummy irq expected print
In-Reply-To: <TYZPR06MB61911F076C8719C6A7D57B97E1562@TYZPR06MB6191.apcprd06.prod.outlook.com>
References: <20240216120455.4138642-1-tommy_huang@aspeedtech.com>
 <nbkkaktcozbhly44hii3zwie7ivsra3qxzdibyzhyhooxrudvb@zik6skmkki2c>
 <TYZPR06MB61911F076C8719C6A7D57B97E1562@TYZPR06MB6191.apcprd06.prod.outlook.com>
Message-ID: <v4nawwb4rwjiy2g7xv2sfyhc545mhk4izb3g22f7jupcevjuzb@nxmqgf2zjyqs>

Hi Tommy,

On Thu, Feb 22, 2024 at 01:10:39AM +0000, Tommy Huang wrote:
> > On Fri, Feb 16, 2024 at 08:04:55PM +0800, Tommy Huang wrote:
> > > When the i2c error condition occurred and master state was not idle,
> > > the master irq function will goto complete state without any other
> > > interrupt handling. It would cause dummy irq expected print. Under
> > > this condition, assign the irq_status into irq_handle.
> > 
> > I'm sorry, but I don't understand much from your log here.
> > 
> > Do you mean that irq_handled in aspeed_i2c_master_irq() is left with some
> > states that is not supposed to have and then you end up printing here:
> > 
> > 	dev_err(bus->dev,
> > 		"irq handled != irq. expected 0x%08x, but was 0x%08x\n",
> > 		irq_received, irq_handled);
> > 
> > Can you please explain better?
> > 
> 
> Yes. If the platform met any irq error condition and the i2c wasn't stated under ASPEED_I2C_MASTER_INACTIVE.
> Then the code flow would goto the end of aspeed_i2c_master_irq.
> 
> 	ret = aspeed_i2c_is_irq_error(irq_status);
> 	if (ret) {
> 		...
> 		irq_handled |= (irq_status & ASPEED_I2CD_INTR_MASTER_ERRORS);
> 		if (bus->master_state != ASPEED_I2C_MASTER_INACTIVE) {
> 			bus->cmd_err = ret;
> 			bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
> 			goto out_complete;
> 		}
> 	}
> 
> Some master interrupt states were not handled under this situation.
> The fake irq not equaled message would be filled into whole of demsg.
> It's most like below example.
> 
> ...
> aspeed-i2c-bus 1e78a780. i2c-bus: irq handled != irq. expected 0x00000030, but was 0x00000020
> aspeed-i2c-bus 1e78a780. i2c-bus: irq handled != irq. expected 0x00000030, but was 0x00000020
> aspeed-i2c-bus 1e78a780. i2c-bus: irq handled != irq. expected 0x00000030, but was 0x00000020
> ...
> 
> I thought the bus->cmd_err has been filled error reason and it would be returned to upper layer.
> So, I didn't think the print should be existed.

thanks! Can you please write a commit that explains better the
fix you are doing?

> > If that's the case, wouldn't it make more sense to check for
> > bus->master_state != ASPEED_I2C_MASTER_INACTIVE) earlier?
> 
> Did you suggest to add "bus->master_state != ASPEED_I2C_MASTER_INACTIVE" judgement before print the irq not equal print?

no, not really, but nevermind, on a second look, what I'm
suggesting doesn't make much sense.

If you want, please reword the commit message as reply to this
e-mail and I will take care of it.

> > And, still, If that's the case, I believe you might need the Fixes tag. It's true that
> > you are not really failing, but you are not reporting a failure by mistake.

Please, also consider adding the Fixes tag if you see it
necessary; I think you should, but it's borderline.

Andi


From ppighouse at gmail.com  Thu Feb 22 00:59:13 2024
From: ppighouse at gmail.com (Kelly Hung)
Date: Thu, 22 Feb 2024 16:59:13 +0800
Subject: [PATCH 1/2] dt-bindings: arm: aspeed: add ASUS X4TF board
Message-ID: <20240222085914.1218037-1-Kelly_Hung@asus.com>

Document the new compatibles used on ASUS X4TF.

Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
---
 Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 749ee54a3..80009948e 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -74,6 +74,7 @@ properties:
               - ampere,mtmitchell-bmc
               - aspeed,ast2600-evb
               - aspeed,ast2600-evb-a1
+              - asus,x4tf
               - facebook,bletchley-bmc
               - facebook,cloudripper-bmc
               - facebook,elbert-bmc
-- 
2.25.1



From ppighouse at gmail.com  Thu Feb 22 00:59:14 2024
From: ppighouse at gmail.com (Kelly Hung)
Date: Thu, 22 Feb 2024 16:59:14 +0800
Subject: [PATCH 2/2] ARM: dts: aspeed: x4tf: Add dts for asus x4tf project
In-Reply-To: <20240222085914.1218037-1-Kelly_Hung@asus.com>
References: <20240222085914.1218037-1-Kelly_Hung@asus.com>
Message-ID: <20240222085914.1218037-2-Kelly_Hung@asus.com>

Base on aspeed-g6.dtsi and can boot into BMC console.

Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
---
 arch/arm/boot/dts/aspeed/Makefile             |   1 +
 .../boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts  | 592 ++++++++++++++++++
 2 files changed, 593 insertions(+)
 create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts

diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
index d3ac20e31..32c41f3d9 100644
--- a/arch/arm/boot/dts/aspeed/Makefile
+++ b/arch/arm/boot/dts/aspeed/Makefile
@@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-bmc-arm-stardragon4800-rep2.dtb \
 	aspeed-bmc-asrock-e3c246d4i.dtb \
 	aspeed-bmc-asrock-romed8hm3.dtb \
+	aspeed-bmc-asus-x4tf.dtb \
 	aspeed-bmc-bytedance-g220a.dtb \
 	aspeed-bmc-delta-ahe50dc.dtb \
 	aspeed-bmc-facebook-bletchley.dtb \
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
new file mode 100644
index 000000000..1bda14a66
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
@@ -0,0 +1,592 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright 2024 ASUS Corp.
+
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include "aspeed-g6-pinctrl.dtsi"
+#include <dt-bindings/i2c/i2c.h>
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+	model = "ASUS-X4TF";
+	compatible = "asus,x4tf", "aspeed,ast2600";
+
+	aliases {
+		serial4 = &uart5;
+	};
+
+	chosen {
+		stdout-path = "serial4:115200n8";
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		video_engine_memory: video {
+			size = <0x04000000>;
+			alignment = <0x01000000>;
+			compatible = "shared-dma-pool";
+			reusable;
+		};
+	};
+
+	iio-hwmon {
+		compatible = "iio-hwmon";
+		io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+				<&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+				<&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>,
+				<&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-heartbeat {
+			gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		led-uid {
+			gpios = <&gpio0 ASPEED_GPIO(P, 1) (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+			default-state = "off";
+		};
+
+		led-status_Y {
+			gpios = <&gpio1 ASPEED_GPIO(B, 1) GPIO_ACTIVE_LOW>;
+			default-state = "off";
+		};
+
+		led-sys_boot_status {
+			gpios = <&gpio1 ASPEED_GPIO(B, 0) GPIO_ACTIVE_LOW>;
+			default-state = "off";
+		};
+	};
+};
+
+&adc0 {
+	vref = <2500>;
+	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>;
+};
+
+&adc1 {
+	vref = <2500>;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc9_default
+		&pinctrl_adc10_default &pinctrl_adc11_default
+		&pinctrl_adc12_default &pinctrl_adc13_default
+		&pinctrl_adc14_default &pinctrl_adc15_default>;
+};
+
+&peci0 {
+	status = "okay";
+};
+
+&lpc_snoop {
+	snoop-ports = <0x80>;
+	status = "okay";
+};
+
+&mac2 {
+	status = "okay";
+	phy-mode = "rmii";
+	use-ncsi;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rmii3_default>;
+};
+
+&mac3 {
+	status = "okay";
+	phy-mode = "rmii";
+	use-ncsi;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rmii4_default>;
+};
+
+&fmc {
+	status = "okay";
+
+	flash at 0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "bmc-spi";
+		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";
+		label = "bios-spi";
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			biosfullimg at 0 {
+				reg = <0x0 0x2000000>; //32768 *1024 = 32 MB
+				label = "biosfullimg";
+			};
+		};
+	};
+};
+
+&i2c0 {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c3 {
+	status = "okay";
+};
+
+&i2c4 {
+	status = "okay";
+
+	temperature-sensor at 48 {
+		compatible = "ti,tmp75";
+		reg = <0x48>;
+	};
+
+	temperature-sensor at 49 {
+		compatible = "ti,tmp75";
+		reg = <0x49>;
+	};
+
+	pca9555_4_20: gpio at 20 {
+		compatible = "nxp,pca9555";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	pca9555_4_22: gpio at 22 {
+		compatible = "nxp,pca9555";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	pca9555_4_24: gpio at 24 {
+		compatible = "nxp,pca9555";
+		reg = <0x24>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names =
+		/*A0 - A3 0*/	"", "STRAP_BMC_BATTERY_GPIO1", "", "",
+		/*A4 - A7 4*/	"", "", "", "",
+		/*B0 - B7 8*/	"", "", "", "", "", "", "", "";
+	};
+
+	pca9555_4_26: gpio at 26 {
+		compatible = "nxp,pca9555";
+		reg = <0x26>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9546";
+		status = "okay";
+		reg = <0x70>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		channel_1: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		channel_2: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		channel_3: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		channel_4: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+	};
+};
+
+&i2c5 {
+	status = "okay";
+
+	pca9555_5_24: gpio at 24 {
+		compatible = "nxp,pca9555";
+		reg = <0x24>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	i2c-mux at 70  {
+		compatible = "nxp,pca9546";
+		status = "okay";
+		reg = <0x70 >;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		channel_5: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			pca9555_5_5_20: gpio at 20 {
+				compatible = "nxp,pca9555";
+				reg = <0x20>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				gpio-line-names =
+					"", "", "", "", "", "", "", "",
+					"", "", "SYS_FAN6", "SYS_FAN5",
+					"SYS_FAN4", "SYS_FAN3",
+					"SYS_FAN2", "SYS_FAN1";
+			};
+
+			pca9555_5_5_21: gpio at 21 {
+				compatible = "nxp,pca9555";
+				reg = <0x21>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+
+			power-monitor at 44 {
+				compatible = "ti,ina219";
+				reg = <0x44>;
+				shunt-resistor = <2>;
+			};
+		};
+
+		channel_6: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		channel_7: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		channel_8: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+	};
+};
+
+&i2c6 {
+	status = "okay";
+
+	pca9555_6_27: gpio at 27 {
+		compatible = "nxp,pca9555";
+		reg = <0x27>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	pca9555_6_20: gpio at 20 {
+		compatible = "nxp,pca9555";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-line-names =
+		/*A0 0*/	"", "", "", "", "", "", "", "",
+		/*B0 8*/	"Drive_NVMe1", "Drive_NVMe2", "", "",
+		/*B4 12*/	"", "", "", "";
+	};
+
+	pca9555_6_21: gpio at 21 {
+		compatible = "nxp,pca9555";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&i2c7 {
+	status = "okay";
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9546";
+		status = "okay";
+		reg = <0x70>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		idle-state = <1>;
+
+		channel_9: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			temperature-sensor at 48 {
+				compatible = "ti,tmp75";
+				reg = <0x48>;
+			};
+
+			temperature-sensor at 49 {
+				compatible = "ti,tmp75";
+				reg = <0x49>;
+			};
+
+			power-monitor at 40 {
+				compatible = "ti,ina219";
+				reg = <0x40>;
+				shunt-resistor = <2>;
+			};
+
+			power-monitor at 41 {
+				compatible = "ti,ina219";
+				reg = <0x41>;
+				shunt-resistor = <5>;
+			};
+		};
+
+		channel_10: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		channel_11: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		channel_12: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+	};
+
+	i2c-mux at 71 {
+		compatible = "nxp,pca9546";
+		status = "okay";
+		reg = <0x71>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		channel_13: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		channel_14: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		channel_15: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		channel_16: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+	};
+};
+
+&i2c8 {
+	status = "okay";
+
+	i2c-mux at 70 {
+		compatible = "nxp,pca9546";
+		status = "okay";
+		reg = <0x70>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		channel_17: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		channel_18: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			temperature-sensor at 48 {
+				compatible = "ti,tmp75";
+				reg = <0x48>;
+			};
+
+			power-monitor at 41 {
+				compatible = "ti,ina219";
+				reg = <0x41>;
+				shunt-resistor = <5>;
+			};
+		};
+
+		channel_19: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		channel_20: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+	};
+};
+
+&i2c9 {
+	status = "okay";
+};
+
+&i2c10 {
+	status = "okay";
+};
+
+&i2c11 {
+	status = "okay";
+};
+
+&i2c14 {
+	status = "okay";
+	multi-master;
+
+	eeprom at 50 {
+		compatible = "atmel,24c08";
+		reg = <0x50>;
+	};
+
+	eeprom at 51 {
+		compatible = "atmel,24c08";
+		reg = <0x51>;
+	};
+};
+
+&sgpiom0 {
+	status = "okay";
+	ngpios = <128>;
+};
+
+&video {
+	status = "okay";
+	memory-region = <&video_engine_memory>;
+};
+
+&sdc {
+	status = "okay";
+};
+
+&lpc_snoop {
+	status = "okay";
+	snoop-ports = <0x80>;
+};
+
+&kcs1 {
+	aspeed,lpc-io-reg = <0xca0>;
+	status = "okay";
+};
+
+&kcs2 {
+	aspeed,lpc-io-reg = <0xca8>;
+	status = "okay";
+};
+
+&kcs3 {
+	aspeed,lpc-io-reg = <0xca2>;
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&uart_routing {
+	status = "okay";
+};
+
+&vhub {
+	status = "okay";
+};
+
+&gpio0 {
+	gpio-line-names =
+	/*A0 0*/	"", "", "", "", "", "", "", "",
+	/*B0 8*/	"", "", "", "", "", "", "PS_PWROK", "",
+	/*C0 16*/	"", "", "", "", "", "", "", "",
+	/*D0 24*/	"", "", "", "", "", "", "", "",
+	/*E0 32*/	"", "", "", "", "", "", "", "",
+	/*F0 40*/	"", "", "", "", "", "", "", "",
+	/*G0 48*/	"", "", "", "", "", "", "", "",
+	/*H0 56*/	"", "", "", "", "", "", "", "",
+	/*I0 64*/	"", "", "", "", "", "", "", "",
+	/*J0 72*/	"", "", "", "", "", "", "", "",
+	/*K0 80*/	"", "", "", "", "", "", "", "",
+	/*L0 88*/	"", "", "", "", "", "", "", "",
+	/*M0 96*/	"", "", "", "", "", "", "", "",
+	/*N0 104*/	"", "", "", "",
+	/*N4 108*/	"POST_COMPLETE", "ESR1_GPIO_AST_SPISEL", "", "",
+	/*O0 112*/	"", "", "", "", "", "", "", "",
+	/*P0 120*/	"ID_BUTTON", "ID_OUT", "POWER_BUTTON", "POWER_OUT",
+	/*P4 124*/	"RESET_BUTTON", "RESET_OUT", "", "HEARTBEAT",
+	/*Q0 128*/	"", "", "", "", "", "", "", "",
+	/*R0 136*/	"", "", "", "", "", "", "", "",
+	/*S0 144*/	"", "", "", "", "", "", "", "",
+	/*T0 152*/	"", "", "", "", "", "", "", "",
+	/*U0 160*/	"", "", "", "", "", "", "", "",
+	/*V0 168*/	"", "", "", "", "", "", "", "",
+	/*W0 176*/	"", "", "", "", "", "", "", "",
+	/*X0 184*/	"", "", "", "", "", "", "", "",
+	/*Y0 192*/	"", "", "", "", "", "", "", "",
+	/*Z0 200*/	"", "", "", "", "", "", "", "";
+};
-- 
2.25.1



From Dharma.B at microchip.com  Thu Feb 22 00:59:28 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Thu, 22 Feb 2024 08:59:28 +0000
Subject: [PATCH v3] dt-bindings: interrupt-controller: Convert Atmel AIC
 to json-schema
In-Reply-To: <20240222-stiffly-squeeze-b4ec2b49a4fe@spud>
References: <20240222035158.195265-1-dharma.b@microchip.com>
 <20240222-stiffly-squeeze-b4ec2b49a4fe@spud>
Message-ID: <01916920-5ad3-4f6b-a53d-649dccec6999@microchip.com>

On 22/02/24 2:26 pm, Conor Dooley wrote:
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
>> new file mode 100644
>> index 000000000000..0d51bd78bf2b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
>> @@ -0,0 +1,89 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id:http://devicetree.org/schemas/interrupt-controller/atmel,aic.yaml#
>> +$schema:http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Advanced Interrupt Controller (AIC)
>> +
>> +maintainers:
>> +  - Nicolas Ferre<nicolas.ferre at microchip.com>
>> +  - Dharma balasubiramani<dharma.b at microchip.com>
>> +
>> +description:
>> +  The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
>> +  maskable, vectored interrupt controller providing handling of up to one
>> +  hundred and twenty-eight interrupt sources.
>> +
>> +allOf:
>> +  - $ref: /schemas/interrupt-controller.yaml#
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: atmel,at91rm9200-aic
>> +    then:
>> +      properties:
>> +        atmel,external-irqs:
>> +          minItems: 1
>> +          maxItems: 7
>> +    else:
>> +      properties:
>> +        atmel,external-irqs:
>> +          minItems: 1
>> +          maxItems: 1
> When there's property restrictions being applied, move the allof down
> to...
> 
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - atmel,at91rm9200-aic
>> +      - atmel,sama5d2-aic
>> +      - atmel,sama5d3-aic
>> +      - atmel,sama5d4-aic
>> +      - microchip,sam9x60-aic
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  interrupt-controller: true
>> +
>> +  "#interrupt-cells":
>> +    const: 3
>> +    description: |
>> +      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
>> +      The 2nd cell specifies flags:
>> +        bits[3:0] trigger type and level flags:
>> +          1 = low-to-high edge triggered.
>> +          2 = high-to-low edge triggered.
>> +          4 = active high level-sensitive.
>> +          8 = active low level-sensitive.
>> +        Valid combinations: 1, 2, 3, 4, 8.
>> +        Default for internal sources: 4 (active high).
>> +      The 3rd cell specifies irq priority from 0 (lowest) to 7 (highest).
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  atmel,external-irqs:
>> +    $ref: /schemas/types.yaml#/definitions/uint32-array
>> +    description: u32 array of external irqs.
> ...here. Both work, but seeing the restrictions before you see any of
> the properties is not the most understandable.

Understood, I will move it here.

> 
> Cheers,
> Conor.
> 
>> +required:
>> +  - compatible
>> +  - reg
>> +  - interrupt-controller
>> +  - "#interrupt-cells"
>> +  - atmel,external-irqs
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    interrupt-controller at fffff000 {
>> +      compatible = "atmel,at91rm9200-aic";
>> +      reg = <0xfffff000 0x200>;
>> +      interrupt-controller;
>> +      #interrupt-cells = <3>;
>> +      atmel,external-irqs = <31>;
>> +    };
>> +...
>>
>> base-commit: 4f5e5092fdbf5cec6bedc19fbe69cce4f5f08372
>> -- 
>> 2.25.1

-- 
With Best Regards,
Dharma B.


From sudeep.holla at arm.com  Thu Feb 22 01:07:24 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 09:07:24 +0000
Subject: [PATCH 0/2] firmware: struct bus_type cleanup
In-Reply-To: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
References: <20240211-bus_cleanup-firmware2-v1-0-1851c92c7be7@marliere.net>
Message-ID: <170859038392.107308.7406544122897669269.b4-ty@arm.com>

On Sun, 11 Feb 2024 12:51:28 -0300, Ricardo B. Marliere wrote:
> This series is part of an effort to cleanup the users of the driver
> core, as can be seen in many recent patches authored by Greg across the
> tree (e.g. [1]).
> 

Applied to sudeep.holla/linux (for-next/scmi/updates), thanks!

[2/2] firmware: arm_scmi: make scmi_bus_type const
      https://git.kernel.org/sudeep.holla/c/961745b2c42e
--
Regards,
Sudeep



From dharma.b at microchip.com  Thu Feb 22 01:07:38 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Thu, 22 Feb 2024 14:37:38 +0530
Subject: [PATCH v4] dt-bindings: interrupt-controller: Convert Atmel AIC to json-schema
Message-ID: <20240222090738.41628-1-dharma.b@microchip.com>

Convert the Atmel AIC binding document to DT schema format using
json-schema.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
Changelog
v3 -> v4
- Move the allOf after "atmel,external-irqs" as it handles its restriction.
v2 -> v3
- Add constraints to the "atmel,external-irqs" property.
- Move 'reg' before 'interrupt-controller' in the example.
v1 -> v2
- Drop the '|' as there is no formatting to preserve.
- Remove unnecessary marketing statement from description.
- Drop the description for interrupts and reg, it's obvious.
- Put reg after compatible.
- Drop comment in example.
- Drop the example of device that is wired to an AIC as it's(dma) binding is
  not yet available.
---
 .../interrupt-controller/atmel,aic.txt        | 43 ---------
 .../interrupt-controller/atmel,aic.yaml       | 89 +++++++++++++++++++
 2 files changed, 89 insertions(+), 43 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
deleted file mode 100644
index 7079d44bf3ba..000000000000
--- a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-* Advanced Interrupt Controller (AIC)
-
-Required properties:
-- compatible: Should be:
-    - "atmel,<chip>-aic" where  <chip> can be "at91rm9200", "sama5d2",
-      "sama5d3" or "sama5d4"
-    - "microchip,<chip>-aic" where <chip> can be "sam9x60"
-
-- interrupt-controller: Identifies the node as an interrupt controller.
-- #interrupt-cells: The number of cells to define the interrupts. It should be 3.
-  The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet).
-  The second cell is used to specify flags:
-    bits[3:0] trigger type and level flags:
-      1 = low-to-high edge triggered.
-      2 = high-to-low edge triggered.
-      4 = active high level-sensitive.
-      8 = active low level-sensitive.
-      Valid combinations are 1, 2, 3, 4, 8.
-      Default flag for internal sources should be set to 4 (active high).
-  The third cell is used to specify the irq priority from 0 (lowest) to 7
-  (highest).
-- reg: Should contain AIC registers location and length
-- atmel,external-irqs: u32 array of external irqs.
-
-Examples:
-	/*
-	 * AIC
-	 */
-	aic: interrupt-controller at fffff000 {
-		compatible = "atmel,at91rm9200-aic";
-		interrupt-controller;
-		#interrupt-cells = <3>;
-		reg = <0xfffff000 0x200>;
-	};
-
-	/*
-	 * An interrupt generating device that is wired to an AIC.
-	 */
-	dma: dma-controller at ffffec00 {
-		compatible = "atmel,at91sam9g45-dma";
-		reg = <0xffffec00 0x200>;
-		interrupts = <21 4 5>;
-	};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
new file mode 100644
index 000000000000..d4658fe3867c
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/atmel,aic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Advanced Interrupt Controller (AIC)
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Dharma balasubiramani <dharma.b at microchip.com>
+
+description:
+  The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
+  maskable, vectored interrupt controller providing handling of up to one
+  hundred and twenty-eight interrupt sources.
+
+properties:
+  compatible:
+    enum:
+      - atmel,at91rm9200-aic
+      - atmel,sama5d2-aic
+      - atmel,sama5d3-aic
+      - atmel,sama5d4-aic
+      - microchip,sam9x60-aic
+
+  reg:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 3
+    description: |
+      The 1st cell is the IRQ number (Peripheral IDentifier on datasheet).
+      The 2nd cell specifies flags:
+        bits[3:0] trigger type and level flags:
+          1 = low-to-high edge triggered.
+          2 = high-to-low edge triggered.
+          4 = active high level-sensitive.
+          8 = active low level-sensitive.
+        Valid combinations: 1, 2, 3, 4, 8.
+        Default for internal sources: 4 (active high).
+      The 3rd cell specifies irq priority from 0 (lowest) to 7 (highest).
+
+  interrupts:
+    maxItems: 1
+
+  atmel,external-irqs:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: u32 array of external irqs.
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: atmel,at91rm9200-aic
+    then:
+      properties:
+        atmel,external-irqs:
+          minItems: 1
+          maxItems: 7
+    else:
+      properties:
+        atmel,external-irqs:
+          minItems: 1
+          maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - "#interrupt-cells"
+  - atmel,external-irqs
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    interrupt-controller at fffff000 {
+      compatible = "atmel,at91rm9200-aic";
+      reg = <0xfffff000 0x200>;
+      interrupt-controller;
+      #interrupt-cells = <3>;
+      atmel,external-irqs = <31>;
+    };
+...

base-commit: 4f5e5092fdbf5cec6bedc19fbe69cce4f5f08372
-- 
2.25.1



From sudeep.holla at arm.com  Thu Feb 22 01:09:23 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 09:09:23 +0000
Subject: [PATCH 00/11] Add SCMI core checks for notification support.
In-Reply-To: <20240212123233.1230090-1-cristian.marussi@arm.com>
References: <20240212123233.1230090-1-cristian.marussi@arm.com>
Message-ID: <170859289755.107527.12693501284171395498.b4-ty@arm.com>

On Mon, 12 Feb 2024 12:32:22 +0000, Cristian Marussi wrote:
> this small series adds a new logic into the SCMI core to implicitly check
> for notification support when some SCMI driver attempts to register for
> notifications.
> 
> Till now, trying to register a notifier for an unsuppported notification
> returned an error and this behaviour generated unneeded message exchanges:
> the only way to avoid this was to lookup in advance the specific protocol
> and resources available in order to avoid registering at all any notifier
> where not supported.
>
> [...]

Applied to sudeep.holla/linux (for-next/scmi/updates), thanks!

[01/11] firmware: arm_scmi: Check for notification support
        https://git.kernel.org/sudeep.holla/c/8733e86a80f5
[02/11] firmware: arm_scmi: Add a common helper to check if a message is supported
        https://git.kernel.org/sudeep.holla/c/637b6d6cae9c
[03/11] firmware: arm_scmi: Implement Perf .is_notify_supported callback
        https://git.kernel.org/sudeep.holla/c/120d26312abc
[04/11] firmware: arm_scmi: Implement Power .is_notify_supported callback
        https://git.kernel.org/sudeep.holla/c/b7e400bc2e2d
[05/11] firmware: arm_scmi: Implement SysPower .is_notify_supported callback
        https://git.kernel.org/sudeep.holla/c/9f5ddbc22225
[06/11] firmware: arm_scmi: Implement Clock .is_notify_supported callback
        https://git.kernel.org/sudeep.holla/c/cf1bba2775ec
[07/11] firmware: arm_scmi: Implement Sensor .is_notify_supported callback
        https://git.kernel.org/sudeep.holla/c/7ac7932df247
[08/11] firmware: arm_scmi: Implement Reset .is_notify_supported callback
        https://git.kernel.org/sudeep.holla/c/12d6a03f3224
[09/11] firmware: arm_scmi: Implement Powercap .is_notify_supported callback
        https://git.kernel.org/sudeep.holla/c/e85beaf76080
[10/11] firmware: arm_scmi: Use opps_by_lvl to store opps
        https://git.kernel.org/sudeep.holla/c/23443a3c7c0c
[11/11] firmware: arm_scmi: Report frequencies in Perf notifications
        https://git.kernel.org/sudeep.holla/c/22ffc748a647
--
Regards,
Sudeep



From javierm at redhat.com  Thu Feb 22 01:09:54 2024
From: javierm at redhat.com (Javier Martinez Canillas)
Date: Thu, 22 Feb 2024 10:09:54 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <bd071521-7f7b-41e8-8786-ad2eeb58b03e@linaro.org>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
 <9083c414-62f2-4bff-93ee-13f8ff60eb34@linaro.org>
 <874je1ipb4.fsf@minerva.mail-host-address-is-not-set>
 <bd071521-7f7b-41e8-8786-ad2eeb58b03e@linaro.org>
Message-ID: <87r0h47tlp.fsf@minerva.mail-host-address-is-not-set>

Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> writes:

> On 21/02/2024 20:34, Javier Martinez Canillas wrote:

[...]

>>>
>>> Any explanation what ZRAM is necessary for Fedora to boot.
>>>
>> 
>> I mentioned already in another email, Fedora is enabling the systemd
>> zram-generator and not having a /dev/zram0 slows down the boot to the
>> point of being unusable. One could disable that service but then is yet
>
> That one sentence would be enough for me.
>

I'll add that then to the commit message when proposing a config fragment.

[...]

>> 
>> So that means that for aarch64, some filesystems have more precedence over
>> others? It's OK to have ext4 or btrfs but no xfs? Honestly it seems quite
>> arbitrary and subjective for me.
>
> Yes, subjective, but to be honest: I would drop Btrfs. I was thinking

Fair. If the agreegment is to minimize defconfig (which AFAIU is your
point), then I'm on board with it. We can start splitting in separate
fragments, people can then mix and match for their specific use cases.

> about it, but since Arnd agrees on XFS I won't fight that battle.
>

Yeah, it was a strange hill for me to die on and is true that fragments
seems to be the best compromise, as Maxime said before in this thread.

By the way, I want to apologize for my harsh/rude comments yesterday. I
wasn't in the best mood and I got too emotional...

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



From patchwork-bot+netdevbpf at kernel.org  Thu Feb 22 01:10:25 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Thu, 22 Feb 2024 09:10:25 +0000
Subject: [PATCH net] net: phy: realtek: Fix rtl8211f_config_init() for
 RTL8211F(D)(I)-VD-CG PHY
In-Reply-To: <20240220070007.968762-1-s-vadapalli@ti.com>
References: <20240220070007.968762-1-s-vadapalli@ti.com>
Message-ID: <170859302599.11577.10322371469324921304.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni at redhat.com>:

On Tue, 20 Feb 2024 12:30:07 +0530 you wrote:
> Commit bb726b753f75 ("net: phy: realtek: add support for
> RTL8211F(D)(I)-VD-CG") extended support of the driver from the existing
> support for RTL8211F(D)(I)-CG PHY to the newer RTL8211F(D)(I)-VD-CG PHY.
> 
> While that commit indicated that the RTL8211F_PHYCR2 register is not
> supported by the "VD-CG" PHY model and therefore updated the corresponding
> section in rtl8211f_config_init() to be invoked conditionally, the call to
> "genphy_soft_reset()" was left as-is, when it should have also been invoked
> conditionally. This is because the call to "genphy_soft_reset()" was first
> introduced by the commit 0a4355c2b7f8 ("net: phy: realtek: add dt property
> to disable CLKOUT clock") since the RTL8211F guide indicates that a PHY
> reset should be issued after setting bits in the PHYCR2 register.
> 
> [...]

Here is the summary with links:
  - [net] net: phy: realtek: Fix rtl8211f_config_init() for RTL8211F(D)(I)-VD-CG PHY
    https://git.kernel.org/netdev/net/c/3489182b11d3

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From cristian.marussi at arm.com  Thu Feb 22 01:20:32 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Thu, 22 Feb 2024 09:20:32 +0000
Subject: [PATCH] firmware: arm_scmi: Add support for multiple vendors
 custom protocols
In-Reply-To: <DU0PR04MB941736B537D71D920C8434AA88562@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20240221220426.1205146-1-cristian.marussi@arm.com>
 <DU0PR04MB941736B537D71D920C8434AA88562@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <ZdcR4Auf0zMgBE7P@pluto>

On Thu, Feb 22, 2024 at 08:32:05AM +0000, Peng Fan (OSS) wrote:
> Hi Cristian,
> 
> > Subject: [PATCH] firmware: arm_scmi: Add support for multiple vendors
> > custom protocols
> 
> Do you have an example how to test this? Could this be used for pinctrl imx?

Hi Peng,

as an example usecase for this, you can consider your upcoming series
which adds 2 NXP SCMI vendor protocol (which I hope to review today)
that you numbered as 0x81, 0x84: in order to avoid clashes with other
vendors potentially registering in the future their own vendor protocols
while using the same numbers as yours, you will have to add a vendor_id
string specification to your scmi_protocol definition, so that it matches
the vendor_id string reported by your SCMI server at runtime via the Base
protocol.

This mechanism basically allows a vendor to own the whole space of
vendor protocols numbers, since the numbers are really now referred to a
specific vendor namespace at runtime.

You can also optionally add a sub_vendor_id and implementation version
if you want to use different protocols of you own with the same number
but different capabilties on different platform of yours...but I am
doubtful about the opprtunity of this further customization...lets see 
what the review process bring up...

BUT, all of this stands true for custom vendor protocols, pinctrl-imx does
use the standard 0x19 Pinctrl protocol, and the clash is really on the
device node underlying the device which is created...re-implementing and
duplicating fully a std protocol as a vendor one, just with a different
number to workaround this issue it is not something can go upstream...
...so at this point you will be better off with just that couple of
downstream pinctrl-imx patches that you have, until we get creative and
found a better way to support your specific usecase...or you move to the
generic Linux Pinctrl subsystem that is supported by the pinctrl-scmi
driver originally by Oleksii (but I understand this is problematic for you
in other ways too...)

Thanks,
Cristian


From brgl at bgdev.pl  Thu Feb 22 01:22:50 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 22 Feb 2024 10:22:50 +0100
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for WCN7850
In-Reply-To: <53f0956f-ee64-4bd6-b44f-cbebafd42e46@sirena.org.uk>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-15-brgl@bgdev.pl>
 <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk> <CAMRc=MeUjKPS3ANE6=7WZ3kbbGAdyE8HeXFN=75Jp-pVyBaWrQ@mail.gmail.com>
 <ea08a286-ff53-4d58-ae41-38cca151508c@sirena.org.uk> <17bbd9ae-0282-430e-947b-e6fb08c53af7@linaro.org>
 <53f0956f-ee64-4bd6-b44f-cbebafd42e46@sirena.org.uk>
Message-ID: <CAMRc=MedCX_TGGawMhr39oXtJPF4pOQF=Jh2z4uXkOxwhfJWRw@mail.gmail.com>

On Wed, Feb 21, 2024 at 12:44?AM Mark Brown <broonie at kernel.org> wrote:
>
> On Tue, Feb 20, 2024 at 10:21:04PM +0100, Konrad Dybcio wrote:
> > On 20.02.2024 13:47, Mark Brown wrote:
>
> > > Are you *sure* this actually happens (and that the regulators don't
> > > figure it out by themselves), especially given that the consumers are
> > > just specifying the load once rather than varying it dynamically at
> > > runtime which is supposed to be the use case for this API?  This API is
> > > intended to be used dynamically, if the regulator always needs to be in
> > > a particular mode just configure that statically.
>
> > *AFAIU*
>
> > The regulators aggregate the requested current (there may be
> > multiple consumers) and then it's decided if it's high enough
> > to jump into HPM.
>
> Yes, that's the theory - I just question if it actually does something
> useful in practice.  Between regulators getting more and more able to
> figure out mode switching autonomously based on load monitoring and them
> getting more efficient it's become very unclear if this actually
> accomplishes anything, the only usage is the Qualcomm stuff and that's
> all really unsophisticated and has an air of something that's being
> cut'n'pasted forwards rather than delivering practical results.  There
> is some value at ultra low loads, but that's more for suspend modes than
> for actual use.

Removing it would be out of scope for this series and I don't really
want to introduce any undefined behavior when doing a big development
like that. I'll think about it separately.

Bart


From apatel at ventanamicro.com  Thu Feb 22 01:25:41 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 14:55:41 +0530
Subject: [PATCH v13 01/13] irqchip/sifive-plic: Convert PLIC driver into a
 platform driver
In-Reply-To: <87il2jih04.ffs@tglx>
References: <20240220060718.823229-1-apatel@ventanamicro.com>
 <20240220060718.823229-2-apatel@ventanamicro.com> <87il2jih04.ffs@tglx>
Message-ID: <CAK9=C2V_SVWTuV_Yap_=X5RwgctUs7eWHGXSp8KFUz3bWNf9JQ@mail.gmail.com>

On Tue, Feb 20, 2024 at 3:39?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Tue, Feb 20 2024 at 11:37, Anup Patel wrote:
> > The PLIC driver does not require very early initialization so let
> > us convert it into a platform driver.
>
> s/let us convert/convert/
>
> Please us passive voice and imperative mood all over the changelogs. No
> we/us, let....

Okay, I will update.

>
> > As part of the conversion, the PLIC probing undergoes the following
> > changes:
> > 1. Use dev_info(), dev_err() and dev_warn() instead of pr_info(),
> >    pr_err() and pr_warn()
> > 2. Use devm_xyz() APIs wherever applicable
> > 3. PLIC is now probed after CPUs are brought-up so we have to
> >    setup cpuhp state after context handler of all online CPUs
> >    are initialized otherwise we see crash on multi-socket systems
>
> This patch is really doing too many things at once, which makes it hard
> to review. Can you split this into digestable pieces please?

Sure, I will split this into smaller granular patches.

>
> >               if (unlikely(err))
> > -                     pr_warn_ratelimited("can't find mapping for hwirq %lu\n",
> > +                     dev_warn_ratelimited(handler->priv->dev,
> > +                                     "can't find mapping for hwirq %lu\n",
> >                                       hwirq);
>
> Nit. Please use brackets around the condition. See:
>
> https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#bracket-rules
>
> for reasoning.

Okay, I will update.

Regards,
Anup


From yunfei.dong at mediatek.com  Thu Feb 22 01:26:08 2024
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 22 Feb 2024 17:26:08 +0800
Subject: [PATCH v3,1/2] media: mediatek: vcodec: adding lock to protect decoder context list
In-Reply-To: <20240222092609.31382-1-yunfei.dong@mediatek.com>
References: <20240222092609.31382-1-yunfei.dong@mediatek.com>
Message-ID: <20240222092609.31382-2-yunfei.dong@mediatek.com>

The ctx_list will be deleted when scp getting unexpected behavior, then the
ctx_list->next will be NULL, the kernel driver maybe access NULL pointer in
function vpu_dec_ipi_handler when going through each context, then reboot.

Need to add lock to protect the ctx_list to make sure the ctx_list->next isn't
NULL pointer.

Hardware name: Google juniper sku16 board (DT)
pstate: 20400005 (nzCv daif +PAN -UAO -TCO BTYPE=--)
pc : vpu_dec_ipi_handler+0x58/0x1f8 [mtk_vcodec_dec]
lr : scp_ipi_handler+0xd0/0x194 [mtk_scp]
sp : ffffffc0131dbbd0
x29: ffffffc0131dbbd0 x28: 0000000000000000
x27: ffffff9bb277f348 x26: ffffff9bb242ad00
x25: ffffffd2d440d3b8 x24: ffffffd2a13ff1d4
x23: ffffff9bb7fe85a0 x22: ffffffc0133fbdb0
x21: 0000000000000010 x20: ffffff9b050ea328
x19: ffffffc0131dbc08 x18: 0000000000001000
x17: 0000000000000000 x16: ffffffd2d461c6e0
x15: 0000000000000242 x14: 000000000000018f
x13: 000000000000004d x12: 0000000000000000
x11: 0000000000000001 x10: fffffffffffffff0
x9 : ffffff9bb6e793a8 x8 : 0000000000000000
x7 : 0000000000000000 x6 : 000000000000003f
x5 : 0000000000000040 x4 : fffffffffffffff0
x3 : 0000000000000020 x2 : ffffff9bb6e79080
x1 : 0000000000000010 x0 : ffffffc0131dbc08
Call trace:
vpu_dec_ipi_handler+0x58/0x1f8 [mtk_vcodec_dec (HASH:6c3f 2)]
scp_ipi_handler+0xd0/0x194 [mtk_scp (HASH:7046 3)]
mt8183_scp_irq_handler+0x44/0x88 [mtk_scp (HASH:7046 3)]
scp_irq_handler+0x48/0x90 [mtk_scp (HASH:7046 3)]
irq_thread_fn+0x38/0x94
irq_thread+0x100/0x1c0
kthread+0x140/0x1fc
ret_from_fork+0x10/0x30
Code: 54000088 f94ca50a eb14015f 54000060 (f9400108)
---[ end trace ace43ce36cbd5c93 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
Kernel Offset: 0x12c4000000 from 0xffffffc010000000
PHYS_OFFSET: 0xffffffe580000000
CPU features: 0x08240002,2188200c
Memory Limit: none

Fixes: 655b86e52eac ("media: mediatek: vcodec: Fix possible invalid memory access for decoder")
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c      | 4 ++--
 .../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c    | 5 +++++
 .../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h    | 2 ++
 drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c | 2 ++
 4 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
index 9f6e4b59455da..9a11a2c248045 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
@@ -58,12 +58,12 @@ static void mtk_vcodec_vpu_reset_dec_handler(void *priv)
 
 	dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
 
-	mutex_lock(&dev->dev_mutex);
+	mutex_lock(&dev->dev_ctx_lock);
 	list_for_each_entry(ctx, &dev->ctx_list, list) {
 		ctx->state = MTK_STATE_ABORT;
 		mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
 	}
-	mutex_unlock(&dev->dev_mutex);
+	mutex_unlock(&dev->dev_ctx_lock);
 }
 
 static void mtk_vcodec_vpu_reset_enc_handler(void *priv)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
index ad9b68380692f..d69c9fe2af6f3 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
@@ -267,7 +267,9 @@ static int fops_vcodec_open(struct file *file)
 
 	ctx->dev->vdec_pdata->init_vdec_params(ctx);
 
+	mutex_lock(&dev->dev_ctx_lock);
 	list_add(&ctx->list, &dev->ctx_list);
+	mutex_unlock(&dev->dev_ctx_lock);
 	mtk_vcodec_dbgfs_create(ctx);
 
 	mutex_unlock(&dev->dev_mutex);
@@ -310,7 +312,9 @@ static int fops_vcodec_release(struct file *file)
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 
 	mtk_vcodec_dbgfs_remove(dev, ctx->id);
+	mutex_lock(&dev->dev_ctx_lock);
 	list_del_init(&ctx->list);
+	mutex_unlock(&dev->dev_ctx_lock);
 	kfree(ctx);
 	mutex_unlock(&dev->dev_mutex);
 	return 0;
@@ -403,6 +407,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	mutex_init(&dev->dev_mutex);
+	mutex_init(&dev->dev_ctx_lock);
 	spin_lock_init(&dev->irqlock);
 
 	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
index 849b89dd205c2..85b2c0d3d8bcd 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
@@ -241,6 +241,7 @@ struct mtk_vcodec_dec_ctx {
  *
  * @dec_mutex: decoder hardware lock
  * @dev_mutex: video_device lock
+ * @dev_ctx_lock: the lock of context list
  * @decode_workqueue: decode work queue
  *
  * @irqlock: protect data access by irq handler and work thread
@@ -282,6 +283,7 @@ struct mtk_vcodec_dec_dev {
 	/* decoder hardware mutex lock */
 	struct mutex dec_mutex[MTK_VDEC_HW_MAX];
 	struct mutex dev_mutex;
+	struct mutex dev_ctx_lock;
 	struct workqueue_struct *decode_workqueue;
 
 	spinlock_t irqlock;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
index 82e57ae983d55..da6be556727bb 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
@@ -77,12 +77,14 @@ static bool vpu_dec_check_ap_inst(struct mtk_vcodec_dec_dev *dec_dev, struct vde
 	struct mtk_vcodec_dec_ctx *ctx;
 	int ret = false;
 
+	mutex_lock(&dec_dev->dev_ctx_lock);
 	list_for_each_entry(ctx, &dec_dev->ctx_list, list) {
 		if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
 			ret = true;
 			break;
 		}
 	}
+	mutex_unlock(&dec_dev->dev_ctx_lock);
 
 	return ret;
 }
-- 
2.18.0



From yunfei.dong at mediatek.com  Thu Feb 22 01:26:07 2024
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 22 Feb 2024 17:26:07 +0800
Subject: [PATCH v3,0/2] media: adding lock to protect the context list
Message-ID: <20240222092609.31382-1-yunfei.dong@mediatek.com>

From: Yunfei Dong <yunfei.dong at mediatek.corp-partner.google.com>

The ctx_list of each module will be deleted when scp getting unexpected
behavior, then the ctx_list->next will be set to NULL, the system reboot
when access the NULL pointer in function vpu_enc(dev)_ipi_handler to go
through each context.

---
Changed in v3:
- change 'Fixes' tag in patch 1/2
- add cover-letter for this patch series
---
Yunfei Dong (2):
  media: mediatek: vcodec: adding lock to protect decoder context list
  media: mediatek: vcodec: adding lock to protect encoder context list

 .../platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c   | 8 ++++----
 .../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c | 5 +++++
 .../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h | 2 ++
 .../media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c  | 2 ++
 .../platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c | 5 +++++
 .../platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h | 2 ++
 .../media/platform/mediatek/vcodec/encoder/venc_vpu_if.c  | 2 ++
 7 files changed, 22 insertions(+), 4 deletions(-)

-- 
2.18.0



From yunfei.dong at mediatek.com  Thu Feb 22 01:26:09 2024
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 22 Feb 2024 17:26:09 +0800
Subject: [PATCH v3,2/2] media: mediatek: vcodec: adding lock to protect encoder context list
In-Reply-To: <20240222092609.31382-1-yunfei.dong@mediatek.com>
References: <20240222092609.31382-1-yunfei.dong@mediatek.com>
Message-ID: <20240222092609.31382-3-yunfei.dong@mediatek.com>

The ctx_list will be deleted when scp getting unexpected behavior, then the
ctx_list->next will be NULL, the kernel driver maybe access NULL pointer in
function vpu_enc_ipi_handler when going through each context, then reboot.

Need to add lock to protect the ctx_list to make sure the ctx_list->next isn't
NULL pointer.

Fixes: 1972e32431ed ("media: mediatek: vcodec: Fix possible invalid memory access for encoder")
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c      | 4 ++--
 .../platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c    | 5 +++++
 .../platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h    | 2 ++
 drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c | 2 ++
 4 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
index 9a11a2c248045..8d578b6902148 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
@@ -73,12 +73,12 @@ static void mtk_vcodec_vpu_reset_enc_handler(void *priv)
 
 	dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
 
-	mutex_lock(&dev->dev_mutex);
+	mutex_lock(&dev->dev_ctx_lock);
 	list_for_each_entry(ctx, &dev->ctx_list, list) {
 		ctx->state = MTK_STATE_ABORT;
 		mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
 	}
-	mutex_unlock(&dev->dev_mutex);
+	mutex_unlock(&dev->dev_ctx_lock);
 }
 
 static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = {
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
index 5db2bf3db4c54..29524cd59ce8b 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
@@ -177,7 +177,9 @@ static int fops_vcodec_open(struct file *file)
 	mtk_v4l2_venc_dbg(2, ctx, "Create instance [%d]@%p m2m_ctx=%p ",
 			  ctx->id, ctx, ctx->m2m_ctx);
 
+	mutex_lock(&dev->dev_ctx_lock);
 	list_add(&ctx->list, &dev->ctx_list);
+	mutex_unlock(&dev->dev_ctx_lock);
 
 	mutex_unlock(&dev->dev_mutex);
 	mtk_v4l2_venc_dbg(0, ctx, "%s encoder [%d]", dev_name(&dev->plat_dev->dev),
@@ -212,7 +214,9 @@ static int fops_vcodec_release(struct file *file)
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 
+	mutex_lock(&dev->dev_ctx_lock);
 	list_del_init(&ctx->list);
+	mutex_unlock(&dev->dev_ctx_lock);
 	kfree(ctx);
 	mutex_unlock(&dev->dev_mutex);
 	return 0;
@@ -294,6 +298,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 
 	mutex_init(&dev->enc_mutex);
 	mutex_init(&dev->dev_mutex);
+	mutex_init(&dev->dev_ctx_lock);
 	spin_lock_init(&dev->irqlock);
 
 	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
index a042f607ed8d1..0bd85d0fb379a 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
@@ -178,6 +178,7 @@ struct mtk_vcodec_enc_ctx {
  *
  * @enc_mutex: encoder hardware lock.
  * @dev_mutex: video_device lock
+ * @dev_ctx_lock: the lock of context list
  * @encode_workqueue: encode work queue
  *
  * @enc_irq: h264 encoder irq resource
@@ -205,6 +206,7 @@ struct mtk_vcodec_enc_dev {
 	/* encoder hardware mutex lock */
 	struct mutex enc_mutex;
 	struct mutex dev_mutex;
+	struct mutex dev_ctx_lock;
 	struct workqueue_struct *encode_workqueue;
 
 	int enc_irq;
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
index 84ad1cc6ad171..51bb7ee141b9e 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
@@ -47,12 +47,14 @@ static bool vpu_enc_check_ap_inst(struct mtk_vcodec_enc_dev *enc_dev, struct ven
 	struct mtk_vcodec_enc_ctx *ctx;
 	int ret = false;
 
+	mutex_lock(&enc_dev->dev_ctx_lock);
 	list_for_each_entry(ctx, &enc_dev->ctx_list, list) {
 		if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
 			ret = true;
 			break;
 		}
 	}
+	mutex_unlock(&enc_dev->dev_ctx_lock);
 
 	return ret;
 }
-- 
2.18.0



From dawei.li at shingroup.cn  Thu Feb 22 01:27:57 2024
From: dawei.li at shingroup.cn (Dawei Li)
Date: Thu, 22 Feb 2024 17:27:57 +0800
Subject: [PATCH] arm64: remove unneeded BUILD_BUG_ON assertion
In-Reply-To: <20240202040211.3118918-1-dawei.li@shingroup.cn>
References: <20240202040211.3118918-1-dawei.li@shingroup.cn>
Message-ID: <A12F96370D84BE9F+ZdcTnYkBf/5n/DlT@centos8>

Hi,

On Fri, Feb 02, 2024 at 12:02:11PM +0800, Dawei Li wrote:
> Since commit c02433dd6de3 ("arm64: split thread_info from task stack"),
> CONFIG_THREAD_INFO_IN_TASK is enabled unconditionally for arm64. So
> remove this always-true assertion from arch_dup_task_struct.
> 
> Signed-off-by: Dawei Li <dawei.li at shingroup.cn>

Just a gentle remainder:).

Thanks,

    Dawei

> ---
>  arch/arm64/kernel/process.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 7387b68c745b..4ae31b7af6c3 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -290,9 +290,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
>  		fpsimd_preserve_current_state();
>  	*dst = *src;
>  
> -	/* We rely on the above assignment to initialize dst's thread_flags: */
> -	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 copies
> -- 
> 2.27.0
> 


From sudeep.holla at arm.com  Thu Feb 22 01:34:26 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 09:34:26 +0000
Subject: [PATCH V4 1/2] firmware: arm_scmi: Implement Clock get permissions
In-Reply-To: <20240121110901.1414856-1-peng.fan@oss.nxp.com>
References: <20240121110901.1414856-1-peng.fan@oss.nxp.com>
Message-ID: <170859423232.108904.12518027607345269340.b4-ty@arm.com>

On Sun, 21 Jan 2024 19:09:00 +0800, Peng Fan (OSS) wrote:
> ARM SCMI Spec 3.2 introduces Clock Get Permission command. This patch
> is to add the support. Add three bool entries to scmi_clock_info to
> indicate the operation is forbidden or not. If the CLOCK_GET_PERMISSIONS
> command is not supported, the three bool variables will default
> set to false, otherwise they will be set according to the return result
> of CLOCK_GET_PERMISSIONS.
> 
> [...]

When I was about to ask for Stephen's ack for 2/2, I noticed an issue
now, will repond to it directly.

Applied to sudeep.holla/linux (for-next/scmi/updates), thanks!

[1/2] firmware: arm_scmi: Implement Clock get permissions
      https://git.kernel.org/sudeep.holla/c/dc36561e1548

--
Regards,
Sudeep



From sudeep.holla at arm.com  Thu Feb 22 01:37:07 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 09:37:07 +0000
Subject: (subset) [PATCH 0/7] SCMI V3.2 Misc updates
In-Reply-To: <20240214183006.3403207-1-cristian.marussi@arm.com>
References: <20240214183006.3403207-1-cristian.marussi@arm.com>
Message-ID: <170859450806.109018.322936287404084370.b4-ty@arm.com>

On Wed, 14 Feb 2024 18:29:59 +0000, Cristian Marussi wrote:
> another round of updates related to the last v3.2 SCMI spec, mostly around
> Clock protocol.
>
> Note that the series is based on sudeep/for-next/scmi/updates on top of
>
>   7dd3d11f4dac ("clk: scmi: Add support for forbidden clock state controls")
>
> [...]

Applied to sudeep.holla/linux (for-next/scmi/updates), thanks!

[1/7] firmware: arm_scmi: Add a common helper to check if a message is supported
      https://git.kernel.org/sudeep.holla/c/637b6d6cae9c
[2/7] firmware: arm_scmi: Add support for v3.2 NEGOTIATE_PROTOCOL_VERSION
      https://git.kernel.org/sudeep.holla/c/8c80c42ad401
[3/7] firmware: arm_scmi: Add Clock check for extended config support
      https://git.kernel.org/sudeep.holla/c/e4ad2b0130ef
[4/7] firmware: arm_scmi: Add standard Clock OEM definitions
      https://git.kernel.org/sudeep.holla/c/62092c428fb5
[5/7] firmware: arm_scmi: Update supported Clock protocol version
      https://git.kernel.org/sudeep.holla/c/5e0d2fe70cb8

--
Regards,
Sudeep



From theo.lebrun at bootlin.com  Thu Feb 22 01:37:18 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 22 Feb 2024 10:37:18 +0100
Subject: [PATCH 18/23] gpio: nomadik: support mobileye,eyeq5-gpio
In-Reply-To: <CACRpkdZQ9LEqKvugDCMEXPPLMCUJ-f9rYQOpmsSEJhtW0zjNsg@mail.gmail.com>
References: <20240214-mbly-gpio-v1-0-f88c0ccf372b@bootlin.com>
 <20240214-mbly-gpio-v1-18-f88c0ccf372b@bootlin.com>
 <CACRpkdYLBGsphNkmWyPXQZvFaO2hHGHGTMt1eqz-HAa2k5F3bg@mail.gmail.com>
 <CZAW47LJHQVD.1Z9GFT8UENYXT@bootlin.com>
 <CACRpkdZQ9LEqKvugDCMEXPPLMCUJ-f9rYQOpmsSEJhtW0zjNsg@mail.gmail.com>
Message-ID: <CZBI90SFODAR.TZ3L2XO2F8IF@bootlin.com>

Hello,

On Wed Feb 21, 2024 at 8:36 PM CET, Linus Walleij wrote:
> On Wed, Feb 21, 2024 at 5:16?PM Th?o Lebrun <theo.lebrun at bootlin.com> wrote:
>
> > > Trying to figure it out...
> >
> > Can I help in the debugging process?
>
> Nah, I found it :)
>
> > Reading the code once again I'd guess
> > of_device_get_match_data(&gpio_pdev->dev) could be the root cause. We
> > are accessing match data for the GPIO device while probing the pinctrl
> > device. Maybe something isn't initialised properly yet? The rest looks
> > rather harmless, I've checked all conditional expressions.
>
> Yep spot on. The nmk_gpio_populate_chip() is sometimes called from
> the pinctrl driver before the gpio probe() has been called, so the match
> data is NULL and we crash.
>
> This looks like it does for historical reasons and there could be better
> ways to fix it now that Saravana Kannan has fixed up the probe ordering
> code.
>
> The following is one way to fix it for now using device_is_compatible()
> (illustrating some other changes I did as well):

Thanks for the debugging and the proposed fix. Indeed matching on
compatible to avoid match data for a bool makes sense.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From pabeni at redhat.com  Thu Feb 22 01:38:53 2024
From: pabeni at redhat.com (Paolo Abeni)
Date: Thu, 22 Feb 2024 10:38:53 +0100
Subject: [PATCH v2] net: stmmac: mmc_core: Drop interrupt registers from
 stats
In-Reply-To: <20240220-stmmac_stats-v2-1-0a78863bec70@axis.com>
References: <20240220-stmmac_stats-v2-1-0a78863bec70@axis.com>
Message-ID: <55c1527f778ada6458dfc3d626d36e5367886dbb.camel@redhat.com>

On Tue, 2024-02-20 at 13:00 +0100, Jesper Nilsson wrote:
> The MMC IPC interrupt status and interrupt mask registers are
> of little use as Ethernet statistics, but incrementing counters
> based on the current interrupt and interrupt mask registers
> makes them actively misleading.
> 
> For example, if the interrupt mask is set to 0x08420842,
> the current code will increment by that amount each iteration,
> leading to the following sequence of nonsense:
> 
> mmc_rx_ipc_intr_mask: 969816526
> mmc_rx_ipc_intr_mask: 1108361744
> 
> These registers have been included in the Ethernet statistics
> since the first version of MMC back in 2011 (commit 1c901a46d57).
> That commit also mentions the MMC interrupts as
> "something to add later (if actually useful)".
> 
> If the registers are actually useful, they should probably
> be part of the Ethernet register dump instead of statistics,
> but for now, drop the counters for mmc_rx_ipc_intr and
> mmc_rx_ipc_intr_mask completely.
> 
> Signed-off-by: Jesper Nilsson <jesper.nilsson at axis.com>

It looks like this could target the 'net' tree. Anyway it does not
apply cleanly to 'net' nor 'net-next'. Could you please rebase &&
repost, including Serge's tags and explicitly setting the target tree
into the subj prefix?

Thanks!

Paolo



From apatel at ventanamicro.com  Thu Feb 22 01:39:48 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:48 +0530
Subject: [PATCH v14 00/18] Linux RISC-V AIA Support
Message-ID: <20240222094006.1030709-1-apatel@ventanamicro.com>

The RISC-V AIA specification is ratified as-per the RISC-V international
process. The latest ratified AIA specifcation can be found at:
https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf

At a high-level, the AIA specification adds three things:
1) AIA CSRs
   - Improved local interrupt support
2) Incoming Message Signaled Interrupt Controller (IMSIC)
   - Per-HART MSI controller
   - Support MSI virtualization
   - Support IPI along with virtualization
3) Advanced Platform-Level Interrupt Controller (APLIC)
   - Wired interrupt controller
   - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
   - In Direct-mode, injects external interrupts directly into HARTs

For an overview of the AIA specification, refer the AIA virtualization
talk at KVM Forum 2022:
https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
https://www.youtube.com/watch?v=r071dL8Z0yo

To test this series, use QEMU v7.2 (or higher) and OpenSBI v1.2 (or higher).

This series depends upon per-device MSI domain patches merged by Thomas (tglx)
which are available in irq/msi branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git

These patches can also be found in the riscv_aia_v14 branch at:
https://github.com/avpatel/linux.git

Changes since v13:
 - Split PATCH1 into six granular patches
 - Addressed nit comments from Thomas and Bjorn

Changes since v12:
 - Rebased on Linux-6.8-rc5
 - Dropped per-device MSI domain patches which are already merged by Thomas (tglx)
 - Addressed nit comments from Thomas and Clement
 - Added a new patch2 to fix lock dependency warning
 - Replaced local sync IPI in the IMSIC driver with per-CPU timer
 - Simplified locking in the IMSIC driver to avoid lock dependency issues
 - Added a dirty bitmap in the IMSIC driver to optimize per-CPU local sync loop

Changes since v11:
 - Rebased on Linux-6.8-rc1
 - Included kernel/irq related patches from "genirq, irqchip: Convert ARM
   MSI handling to per device MSI domains" series by Thomas.
   (PATCH7, PATCH8, PATCH9, PATCH14, PATCH16, PATCH17, PATCH18, PATCH19,
    PATCH20, PATCH21, PATCH22, PATCH23, and PATCH32 of
    https://lore.kernel.org/linux-arm-kernel/20221121135653.208611233 at linutronix.de/)
 - Updated APLIC MSI-mode driver to use the new WIRED_TO_MSI mechanism.
 - Updated IMSIC driver to support per-device MSI domains for PCI and
   platform devices.

Changes since v10:
 - Rebased on Linux-6.6-rc7
 - Dropped PATCH3 of v10 series since this has been merged by MarcZ
   for Linux-6.6-rc7
 - Changed the IMSIC ID management strategy from 1-n approach to
   x86-style 1-1 approach

Changes since v9:
 - Rebased on Linux-6.6-rc4
 - Use builtin_platform_driver() in PATCH5, PATCH9, and PATCH12

Changes since v8:
 - Rebased on Linux-6.6-rc3
 - Dropped PATCH2 of v8 series since we won't be requiring
   riscv_get_intc_hartid() based on Marc Z's comments on ACPI AIA support.
 - Addressed Saravana's comments in PATCH3 of v8 series
 - Update PATCH9 and PATCH13 of v8 series based on comments from Sunil

Changes since v7:
 - Rebased on Linux-6.6-rc1
 - Addressed comments on PATCH1 of v7 series and split it into two PATCHes
 - Use DEFINE_SIMPLE_PROP() in PATCH2 of v7 series

Changes since v6:
 - Rebased on Linux-6.5-rc4
 - Updated PATCH2 to use IS_ENABLED(CONFIG_SPARC) instead of
   !IS_ENABLED(CONFIG_OF_IRQ)
 - Added new PATCH4 to fix syscore registration in PLIC driver
 - Update PATCH5 to convert PLIC driver into full-blown platform driver
   with a re-written probe function.

Changes since v5:
 - Rebased on Linux-6.5-rc2
 - Updated the overall series to ensure that only IPI, timer, and
   INTC drivers are probed very early whereas rest of the interrupt
   controllers (such as PLIC, APLIC, and IMISC) are probed as
   regular platform drivers.
 - Renamed riscv_fw_parent_hartid() to riscv_get_intc_hartid()
 - New PATCH1 to add fw_devlink support for msi-parent DT property
 - New PATCH2 to ensure all INTC suppliers are initialized which in-turn
   fixes the probing issue for PLIC, APLIC and IMSIC as platform driver
 - New PATCH3 to use platform driver probing for PLIC
 - Re-structured the IMSIC driver into two separate drivers: early and
   platform. The IMSIC early driver (PATCH7) only initialized IMSIC state
   and provides IPIs whereas the IMSIC platform driver (PATCH8) is probed
   provides MSI domain for platform devices.
 - Re-structure the APLIC platform driver into three separe sources: main,
   direct mode, and MSI mode.

Changes since v4:
 - Rebased on Linux-6.5-rc1
 - Added "Dependencies" in the APLIC bindings (PATCH6 in v4)
 - Dropped the PATCH6 which was changing the IOMMU DMA domain APIs
 - Dropped use of IOMMU DMA APIs in the IMSIC driver (PATCH4)

Changes since v3:
 - Rebased on Linux-6.4-rc6
 - Dropped PATCH2 of v3 series instead we now set FWNODE_FLAG_BEST_EFFORT via
   IRQCHIP_DECLARE()
 - Extend riscv_fw_parent_hartid() to support both DT and ACPI in PATCH1
 - Extend iommu_dma_compose_msi_msg() instead of adding iommu_dma_select_msi()
   in PATCH6
 - Addressed Conor's comments in PATCH3
 - Addressed Conor's and Rob's comments in PATCH7

Changes since v2:
 - Rebased on Linux-6.4-rc1
 - Addressed Rob's comments on DT bindings patches 4 and 8.
 - Addessed Marc's comments on IMSIC driver PATCH5
 - Replaced use of OF apis in APLIC and IMSIC drivers with FWNODE apis
   this makes both drivers easily portable for ACPI support. This also
   removes unnecessary indirection from the APLIC and IMSIC drivers.
 - PATCH1 is a new patch for portability with ACPI support
 - PATCH2 is a new patch to fix probing in APLIC drivers for APLIC-only systems.
 - PATCH7 is a new patch which addresses the IOMMU DMA domain issues pointed
   out by SiFive

Changes since v1:
 - Rebased on Linux-6.2-rc2
 - Addressed comments on IMSIC DT bindings for PATCH4
 - Use raw_spin_lock_irqsave() on ids_lock for PATCH5
 - Improved MMIO alignment checks in PATCH5 to allow MMIO regions
   with holes.
 - Addressed comments on APLIC DT bindings for PATCH6
 - Fixed warning splat in aplic_msi_write_msg() caused by
   zeroed MSI message in PATCH7
 - Dropped DT property riscv,slow-ipi instead will have module
   parameter in future.

Anup Patel (17):
  irqchip/sifive-plic: Convert PLIC driver into a platform driver
  irqchip/sifive-plic: Use dev_xyz() in-place of pr_xyz()
  irqchip/sifive-plic: Use devm_xyz() for managed allocation
  irqchip/sifive-plic: Use riscv_get_intc_hwnode() to get parent fwnode
  irqchip/sifive-plic: Cleanup PLIC contexts upon irqdomain creation
    failure
  irqchip/sifive-plic: Parse number of irqs and contexts early in
    plic_probe
  irqchip/sifive-plic: Improve locking safety by using
    irqsave/irqrestore
  irqchip/riscv-intc: Add support for RISC-V AIA
  dt-bindings: interrupt-controller: Add RISC-V incoming MSI controller
  irqchip: Add RISC-V incoming MSI controller early driver
  irqchip/riscv-imsic: Add device MSI domain support for platform
    devices
  irqchip/riscv-imsic: Add device MSI domain support for PCI devices
  dt-bindings: interrupt-controller: Add RISC-V advanced PLIC
  irqchip: Add RISC-V advanced PLIC driver for direct-mode
  irqchip/riscv-aplic: Add support for MSI-mode
  RISC-V: Select APLIC and IMSIC drivers
  MAINTAINERS: Add entry for RISC-V AIA drivers

Bj?rn T?pel (1):
  genirq/matrix: Dynamic bitmap allocation

 .../interrupt-controller/riscv,aplic.yaml     | 172 ++++
 .../interrupt-controller/riscv,imsics.yaml    | 172 ++++
 MAINTAINERS                                   |  14 +
 arch/riscv/Kconfig                            |   2 +
 arch/x86/include/asm/hw_irq.h                 |   2 -
 drivers/irqchip/Kconfig                       |  25 +
 drivers/irqchip/Makefile                      |   3 +
 drivers/irqchip/irq-riscv-aplic-direct.c      | 326 +++++++
 drivers/irqchip/irq-riscv-aplic-main.c        | 211 +++++
 drivers/irqchip/irq-riscv-aplic-main.h        |  52 ++
 drivers/irqchip/irq-riscv-aplic-msi.c         | 263 ++++++
 drivers/irqchip/irq-riscv-imsic-early.c       | 201 ++++
 drivers/irqchip/irq-riscv-imsic-platform.c    | 375 ++++++++
 drivers/irqchip/irq-riscv-imsic-state.c       | 870 ++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.h       | 108 +++
 drivers/irqchip/irq-riscv-intc.c              |  32 +-
 drivers/irqchip/irq-sifive-plic.c             | 269 ++++--
 include/linux/irqchip/riscv-aplic.h           | 145 +++
 include/linux/irqchip/riscv-imsic.h           |  87 ++
 kernel/irq/matrix.c                           |  28 +-
 20 files changed, 3235 insertions(+), 122 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
 create mode 100644 drivers/irqchip/irq-riscv-aplic-direct.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.h
 create mode 100644 drivers/irqchip/irq-riscv-aplic-msi.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-early.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.h
 create mode 100644 include/linux/irqchip/riscv-aplic.h
 create mode 100644 include/linux/irqchip/riscv-imsic.h

-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:39:49 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:49 +0530
Subject: [PATCH v14 01/18] irqchip/sifive-plic: Convert PLIC driver into a platform driver
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-2-apatel@ventanamicro.com>

The PLIC driver does not require very early initialization so convert
it into a platform driver.

After conversion, the PLIC driver is probed after CPUs are brought-up
so setup cpuhp state after context handler of all online CPUs are
initialized otherwise PLIC driver crashes for platforms with multiple
PLIC instances.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-sifive-plic.c | 101 ++++++++++++++++++------------
 1 file changed, 61 insertions(+), 40 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 5b7bc4fd9517..7400a07fc479 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -64,6 +64,7 @@
 #define PLIC_QUIRK_EDGE_INTERRUPT	0
 
 struct plic_priv {
+	struct device *dev;
 	struct cpumask lmask;
 	struct irq_domain *irqdomain;
 	void __iomem *regs;
@@ -406,30 +407,50 @@ static int plic_starting_cpu(unsigned int cpu)
 	return 0;
 }
 
-static int __init __plic_init(struct device_node *node,
-			      struct device_node *parent,
-			      unsigned long plic_quirks)
+static const struct of_device_id plic_match[] = {
+	{ .compatible = "sifive,plic-1.0.0" },
+	{ .compatible = "riscv,plic0" },
+	{ .compatible = "andestech,nceplic100",
+	  .data = (const void *)BIT(PLIC_QUIRK_EDGE_INTERRUPT) },
+	{ .compatible = "thead,c900-plic",
+	  .data = (const void *)BIT(PLIC_QUIRK_EDGE_INTERRUPT) },
+	{}
+};
+
+static int plic_probe(struct platform_device *pdev)
 {
 	int error = 0, nr_contexts, nr_handlers = 0, i;
-	u32 nr_irqs;
-	struct plic_priv *priv;
+	struct device *dev = &pdev->dev;
+	unsigned long plic_quirks = 0;
 	struct plic_handler *handler;
+	struct plic_priv *priv;
+	bool cpuhp_setup;
 	unsigned int cpu;
+	u32 nr_irqs;
+
+	if (is_of_node(dev->fwnode)) {
+		const struct of_device_id *id;
+
+		id = of_match_node(plic_match, to_of_node(dev->fwnode));
+		if (id)
+			plic_quirks = (unsigned long)id->data;
+	}
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
+	priv->dev = dev;
 	priv->plic_quirks = plic_quirks;
 
-	priv->regs = of_iomap(node, 0);
+	priv->regs = of_iomap(to_of_node(dev->fwnode), 0);
 	if (WARN_ON(!priv->regs)) {
 		error = -EIO;
 		goto out_free_priv;
 	}
 
 	error = -EINVAL;
-	of_property_read_u32(node, "riscv,ndev", &nr_irqs);
+	of_property_read_u32(to_of_node(dev->fwnode), "riscv,ndev", &nr_irqs);
 	if (WARN_ON(!nr_irqs))
 		goto out_iounmap;
 
@@ -439,13 +460,13 @@ static int __init __plic_init(struct device_node *node,
 	if (!priv->prio_save)
 		goto out_free_priority_reg;
 
-	nr_contexts = of_irq_count(node);
+	nr_contexts = of_irq_count(to_of_node(dev->fwnode));
 	if (WARN_ON(!nr_contexts))
 		goto out_free_priority_reg;
 
 	error = -ENOMEM;
-	priv->irqdomain = irq_domain_add_linear(node, nr_irqs + 1,
-			&plic_irqdomain_ops, priv);
+	priv->irqdomain = irq_domain_add_linear(to_of_node(dev->fwnode), nr_irqs + 1,
+						&plic_irqdomain_ops, priv);
 	if (WARN_ON(!priv->irqdomain))
 		goto out_free_priority_reg;
 
@@ -455,7 +476,7 @@ static int __init __plic_init(struct device_node *node,
 		int cpu;
 		unsigned long hartid;
 
-		if (of_irq_parse_one(node, i, &parent)) {
+		if (of_irq_parse_one(to_of_node(dev->fwnode), i, &parent)) {
 			pr_err("failed to parse parent for context %d.\n", i);
 			continue;
 		}
@@ -491,7 +512,7 @@ static int __init __plic_init(struct device_node *node,
 
 		/* Find parent domain and register chained handler */
 		if (!plic_parent_irq && irq_find_host(parent.np)) {
-			plic_parent_irq = irq_of_parse_and_map(node, i);
+			plic_parent_irq = irq_of_parse_and_map(to_of_node(dev->fwnode), i);
 			if (plic_parent_irq)
 				irq_set_chained_handler(plic_parent_irq,
 							plic_handle_irq);
@@ -533,20 +554,29 @@ static int __init __plic_init(struct device_node *node,
 
 	/*
 	 * We can have multiple PLIC instances so setup cpuhp state
-	 * and register syscore operations only when context handler
-	 * for current/boot CPU is present.
+	 * and register syscore operations only once after context
+	 * handlers of all online CPUs are initialized.
 	 */
-	handler = this_cpu_ptr(&plic_handlers);
-	if (handler->present && !plic_cpuhp_setup_done) {
-		cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
-				  "irqchip/sifive/plic:starting",
-				  plic_starting_cpu, plic_dying_cpu);
-		register_syscore_ops(&plic_irq_syscore_ops);
-		plic_cpuhp_setup_done = true;
+	if (!plic_cpuhp_setup_done) {
+		cpuhp_setup = true;
+		for_each_online_cpu(cpu) {
+			handler = per_cpu_ptr(&plic_handlers, cpu);
+			if (!handler->present) {
+				cpuhp_setup = false;
+				break;
+			}
+		}
+		if (cpuhp_setup) {
+			cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
+					  "irqchip/sifive/plic:starting",
+					  plic_starting_cpu, plic_dying_cpu);
+			register_syscore_ops(&plic_irq_syscore_ops);
+			plic_cpuhp_setup_done = true;
+		}
 	}
 
-	pr_info("%pOFP: mapped %d interrupts with %d handlers for"
-		" %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts);
+	pr_info("%pOFP: mapped %d interrupts with %d handlers for %d contexts.\n",
+		to_of_node(dev->fwnode), nr_irqs, nr_handlers, nr_contexts);
 	return 0;
 
 out_free_enable_reg:
@@ -563,20 +593,11 @@ static int __init __plic_init(struct device_node *node,
 	return error;
 }
 
-static int __init plic_init(struct device_node *node,
-			    struct device_node *parent)
-{
-	return __plic_init(node, parent, 0);
-}
-
-IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init);
-IRQCHIP_DECLARE(riscv_plic0, "riscv,plic0", plic_init); /* for legacy systems */
-
-static int __init plic_edge_init(struct device_node *node,
-				 struct device_node *parent)
-{
-	return __plic_init(node, parent, BIT(PLIC_QUIRK_EDGE_INTERRUPT));
-}
-
-IRQCHIP_DECLARE(andestech_nceplic100, "andestech,nceplic100", plic_edge_init);
-IRQCHIP_DECLARE(thead_c900_plic, "thead,c900-plic", plic_edge_init);
+static struct platform_driver plic_driver = {
+	.driver = {
+		.name		= "riscv-plic",
+		.of_match_table	= plic_match,
+	},
+	.probe = plic_probe,
+};
+builtin_platform_driver(plic_driver);
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:39:50 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:50 +0530
Subject: [PATCH v14 02/18] irqchip/sifive-plic: Use dev_xyz() in-place of pr_xyz()
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-3-apatel@ventanamicro.com>

Use dev_info(), dev_warn(), and dev_err() in-place of pr_info(),
pr_warn(), and pr_err().

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-sifive-plic.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 7400a07fc479..3d7a61c35572 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -3,7 +3,6 @@
  * Copyright (C) 2017 SiFive
  * Copyright (C) 2018 Christoph Hellwig
  */
-#define pr_fmt(fmt) "plic: " fmt
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -372,8 +371,8 @@ static void plic_handle_irq(struct irq_desc *desc)
 		int err = generic_handle_domain_irq(handler->priv->irqdomain,
 						    hwirq);
 		if (unlikely(err))
-			pr_warn_ratelimited("can't find mapping for hwirq %lu\n",
-					hwirq);
+			dev_warn_ratelimited(handler->priv->dev,
+					     "can't find mapping for hwirq %lu\n", hwirq);
 	}
 
 	chained_irq_exit(chip, desc);
@@ -401,7 +400,7 @@ static int plic_starting_cpu(unsigned int cpu)
 		enable_percpu_irq(plic_parent_irq,
 				  irq_get_trigger_type(plic_parent_irq));
 	else
-		pr_warn("cpu%d: parent irq not available\n", cpu);
+		dev_warn(handler->priv->dev, "cpu%d: parent irq not available\n", cpu);
 	plic_set_threshold(handler, PLIC_ENABLE_THRESHOLD);
 
 	return 0;
@@ -477,7 +476,7 @@ static int plic_probe(struct platform_device *pdev)
 		unsigned long hartid;
 
 		if (of_irq_parse_one(to_of_node(dev->fwnode), i, &parent)) {
-			pr_err("failed to parse parent for context %d.\n", i);
+			dev_err(dev, "failed to parse parent for context %d.\n", i);
 			continue;
 		}
 
@@ -500,13 +499,13 @@ static int plic_probe(struct platform_device *pdev)
 
 		error = riscv_of_parent_hartid(parent.np, &hartid);
 		if (error < 0) {
-			pr_warn("failed to parse hart ID for context %d.\n", i);
+			dev_warn(dev, "failed to parse hart ID for context %d.\n", i);
 			continue;
 		}
 
 		cpu = riscv_hartid_to_cpuid(hartid);
 		if (cpu < 0) {
-			pr_warn("Invalid cpuid for context %d\n", i);
+			dev_warn(dev, "Invalid cpuid for context %d\n", i);
 			continue;
 		}
 
@@ -525,7 +524,7 @@ static int plic_probe(struct platform_device *pdev)
 		 */
 		handler = per_cpu_ptr(&plic_handlers, cpu);
 		if (handler->present) {
-			pr_warn("handler already present for context %d.\n", i);
+			dev_warn(dev, "handler already present for context %d.\n", i);
 			plic_set_threshold(handler, PLIC_DISABLE_THRESHOLD);
 			goto done;
 		}
@@ -575,8 +574,8 @@ static int plic_probe(struct platform_device *pdev)
 		}
 	}
 
-	pr_info("%pOFP: mapped %d interrupts with %d handlers for %d contexts.\n",
-		to_of_node(dev->fwnode), nr_irqs, nr_handlers, nr_contexts);
+	dev_info(dev, "mapped %d interrupts with %d handlers for %d contexts.\n",
+		 nr_irqs, nr_handlers, nr_contexts);
 	return 0;
 
 out_free_enable_reg:
-- 
2.34.1



From jbrunet at baylibre.com  Thu Feb 22 01:37:28 2024
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 22 Feb 2024 10:37:28 +0100
Subject: [PATCH] arm64: dts: meson-g12b-odroid-n2*: Add support for
 overclocking Hardkernel ODROID-N2 boards.
In-Reply-To: <20240222082523.1812-1-greena88@gmail.com>
References: <20240222082523.1812-1-greena88@gmail.com>
Message-ID: <1j8r3cet0i.fsf@starbuckisacylon.baylibre.com>


On Thu 22 Feb 2024 at 08:25, Adam Green <greena88 at gmail.com> wrote:

> Hardkernel actively supports overclocking these boards in their own
> documentation. (https://wiki.odroid.com/odroid-n2/hardware/overclocking)
>
> This aligns the SoC opps with those in the board vendors bsp source.

Patch title is too long - checkpatch.pl should have given a you warning
for this.

Not sure it is wise support overclocking directly in mainline, not by
default at least. Maybe as an overlay ? even this I'm not too sure.

>
> Signed-off-by: Adam Green <greena88 at gmail.com>
> ---
>  .../dts/amlogic/meson-g12b-odroid-n2-plus.dts | 25 +++++++++++++++++++
>  .../boot/dts/amlogic/meson-g12b-odroid-n2.dts | 17 +++++++++++++
>  .../dts/amlogic/meson-g12b-odroid-n2l.dts     | 25 +++++++++++++++++++
>  3 files changed, 67 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts
> index ce1198ad34e4..1731d542a00c 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts
> @@ -15,6 +15,31 @@ / {
>  	model = "Hardkernel ODROID-N2Plus";
>  };
>  
> +&cpu_opp_table_0 {
> +	opp-1908000000 {
> +		opp-hz = /bits/ 64 <1908000000>;
> +		opp-microvolt = <1030000>;
> +	};
> +	opp-2016000000 {
> +		opp-hz = /bits/ 64 <2016000000>;
> +		opp-microvolt = <1040000>;
> +		turbo-mode;
> +	};
> +};
> +
> +&cpub_opp_table_1 {
> +	opp-2304000000 {
> +		opp-hz = /bits/ 64 <2304000000>;
> +		opp-microvolt = <1030000>;
> +		turbo-mode;
> +	};
> +	opp-2400000000 {
> +		opp-hz = /bits/ 64 <2400000000>;
> +		opp-microvolt = <1040000>;
> +		turbo-mode;
> +	};
> +};
> +
>  &vddcpu_a {
>  	regulator-min-microvolt = <680000>;
>  	regulator-max-microvolt = <1040000>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
> index a198a91259ec..0c71e8bc0124 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
> @@ -13,3 +13,20 @@ / {
>  	compatible = "hardkernel,odroid-n2", "amlogic,s922x", "amlogic,g12b";
>  	model = "Hardkernel ODROID-N2";
>  };
> +
> +&cpu_opp_table_0 {
> +	opp-1992000000 {
> +		turbo-mode;
> +	};
> +};
> +
> +&cpub_opp_table_1 {
> +	opp-1908000000 {
> +		turbo-mode;
> +	};
> +	opp-2004000000 {
> +		opp-hz = /bits/ 64 <2004000000>;
> +		opp-microvolt = <1022000>;
> +		turbo-mode;
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2l.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2l.dts
> index e26f3e3258e1..b16a69d0cad6 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2l.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2l.dts
> @@ -97,6 +97,31 @@ codec {
>  	};
>  };
>  
> +&cpu_opp_table_0 {
> +	opp-1908000000 {
> +		opp-hz = /bits/ 64 <1908000000>;
> +		opp-microvolt = <1030000>;
> +	};
> +	opp-2016000000 {
> +		opp-hz = /bits/ 64 <2016000000>;
> +		opp-microvolt = <1040000>;
> +		turbo-mode;
> +	};
> +};
> +
> +&cpub_opp_table_1 {
> +	opp-2304000000 {
> +		opp-hz = /bits/ 64 <2304000000>;
> +		opp-microvolt = <1030000>;
> +		turbo-mode;
> +	};
> +	opp-2400000000 {
> +		opp-hz = /bits/ 64 <2400000000>;
> +		opp-microvolt = <1040000>;
> +		turbo-mode;
> +	};
> +};
> +
>  &eth_phy {
>  	status = "disabled";
>  };


-- 
Jerome


From apatel at ventanamicro.com  Thu Feb 22 01:39:51 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:51 +0530
Subject: [PATCH v14 03/18] irqchip/sifive-plic: Use devm_xyz() for managed allocation
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-4-apatel@ventanamicro.com>

Use devm_xyz() for allocations and mappings managed by the
Linux device driver framework.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-sifive-plic.c | 49 ++++++++++---------------------
 1 file changed, 16 insertions(+), 33 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 3d7a61c35572..558ae63795d9 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -435,39 +435,30 @@ static int plic_probe(struct platform_device *pdev)
 			plic_quirks = (unsigned long)id->data;
 	}
 
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
 	priv->dev = dev;
 	priv->plic_quirks = plic_quirks;
 
-	priv->regs = of_iomap(to_of_node(dev->fwnode), 0);
-	if (WARN_ON(!priv->regs)) {
-		error = -EIO;
-		goto out_free_priv;
-	}
+	priv->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (WARN_ON(!priv->regs))
+		return -EIO;
 
-	error = -EINVAL;
 	of_property_read_u32(to_of_node(dev->fwnode), "riscv,ndev", &nr_irqs);
 	if (WARN_ON(!nr_irqs))
-		goto out_iounmap;
+		return -EINVAL;
 
 	priv->nr_irqs = nr_irqs;
 
-	priv->prio_save = bitmap_alloc(nr_irqs, GFP_KERNEL);
+	priv->prio_save = devm_bitmap_zalloc(dev, nr_irqs, GFP_KERNEL);
 	if (!priv->prio_save)
-		goto out_free_priority_reg;
+		return -ENOMEM;
 
 	nr_contexts = of_irq_count(to_of_node(dev->fwnode));
 	if (WARN_ON(!nr_contexts))
-		goto out_free_priority_reg;
-
-	error = -ENOMEM;
-	priv->irqdomain = irq_domain_add_linear(to_of_node(dev->fwnode), nr_irqs + 1,
-						&plic_irqdomain_ops, priv);
-	if (WARN_ON(!priv->irqdomain))
-		goto out_free_priority_reg;
+		return -EINVAL;
 
 	for (i = 0; i < nr_contexts; i++) {
 		struct of_phandle_args parent;
@@ -538,10 +529,10 @@ static int plic_probe(struct platform_device *pdev)
 			i * CONTEXT_ENABLE_SIZE;
 		handler->priv = priv;
 
-		handler->enable_save =  kcalloc(DIV_ROUND_UP(nr_irqs, 32),
-						sizeof(*handler->enable_save), GFP_KERNEL);
+		handler->enable_save = devm_kcalloc(dev, DIV_ROUND_UP(nr_irqs, 32),
+						    sizeof(*handler->enable_save), GFP_KERNEL);
 		if (!handler->enable_save)
-			goto out_free_enable_reg;
+			return -ENOMEM;
 done:
 		for (hwirq = 1; hwirq <= nr_irqs; hwirq++) {
 			plic_toggle(handler, hwirq, 0);
@@ -551,6 +542,11 @@ static int plic_probe(struct platform_device *pdev)
 		nr_handlers++;
 	}
 
+	priv->irqdomain = irq_domain_add_linear(to_of_node(dev->fwnode), nr_irqs + 1,
+						&plic_irqdomain_ops, priv);
+	if (WARN_ON(!priv->irqdomain))
+		return -ENOMEM;
+
 	/*
 	 * We can have multiple PLIC instances so setup cpuhp state
 	 * and register syscore operations only once after context
@@ -577,19 +573,6 @@ static int plic_probe(struct platform_device *pdev)
 	dev_info(dev, "mapped %d interrupts with %d handlers for %d contexts.\n",
 		 nr_irqs, nr_handlers, nr_contexts);
 	return 0;
-
-out_free_enable_reg:
-	for_each_cpu(cpu, cpu_present_mask) {
-		handler = per_cpu_ptr(&plic_handlers, cpu);
-		kfree(handler->enable_save);
-	}
-out_free_priority_reg:
-	kfree(priv->prio_save);
-out_iounmap:
-	iounmap(priv->regs);
-out_free_priv:
-	kfree(priv);
-	return error;
 }
 
 static struct platform_driver plic_driver = {
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:39:52 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:52 +0530
Subject: [PATCH v14 04/18] irqchip/sifive-plic: Use riscv_get_intc_hwnode() to get parent fwnode
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-5-apatel@ventanamicro.com>

The RISC-V INTC irqdomain is always the parent irqdomain of SiFive PLIC
so use riscv_get_intc_hwnode() to get the parent fwnode similar to other
RISC-V drivers which use local interrupts.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-sifive-plic.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 558ae63795d9..615498071b6e 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -422,6 +422,7 @@ static int plic_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	unsigned long plic_quirks = 0;
 	struct plic_handler *handler;
+	struct irq_domain *domain;
 	struct plic_priv *priv;
 	bool cpuhp_setup;
 	unsigned int cpu;
@@ -501,8 +502,9 @@ static int plic_probe(struct platform_device *pdev)
 		}
 
 		/* Find parent domain and register chained handler */
-		if (!plic_parent_irq && irq_find_host(parent.np)) {
-			plic_parent_irq = irq_of_parse_and_map(to_of_node(dev->fwnode), i);
+		domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS_ANY);
+		if (!plic_parent_irq && domain) {
+			plic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
 			if (plic_parent_irq)
 				irq_set_chained_handler(plic_parent_irq,
 							plic_handle_irq);
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:39:53 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:53 +0530
Subject: [PATCH v14 05/18] irqchip/sifive-plic: Cleanup PLIC contexts upon irqdomain creation failure
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-6-apatel@ventanamicro.com>

The SiFive PLIC contexts should not be left dangling if irqdomain creation
fails because plic_starting_cpu() can crash accessing unmapped registers.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-sifive-plic.c | 73 ++++++++++++++++++++++---------
 1 file changed, 53 insertions(+), 20 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 615498071b6e..f0df5d0cb76e 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -416,17 +416,45 @@ static const struct of_device_id plic_match[] = {
 	{}
 };
 
+static int plic_parse_context_parent(struct platform_device *pdev, u32 context,
+				     u32 *parent_hwirq, int *parent_cpu)
+{
+	struct device *dev = &pdev->dev;
+	struct of_phandle_args parent;
+	unsigned long hartid;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	rc = of_irq_parse_one(to_of_node(dev->fwnode), context, &parent);
+	if (rc)
+		return rc;
+
+	rc = riscv_of_parent_hartid(parent.np, &hartid);
+	if (rc)
+		return rc;
+
+	*parent_hwirq = parent.args[0];
+	*parent_cpu = riscv_hartid_to_cpuid(hartid);
+	return 0;
+}
+
 static int plic_probe(struct platform_device *pdev)
 {
-	int error = 0, nr_contexts, nr_handlers = 0, i;
+	int error = 0, nr_contexts, nr_handlers = 0, cpu, i;
 	struct device *dev = &pdev->dev;
 	unsigned long plic_quirks = 0;
 	struct plic_handler *handler;
+	u32 nr_irqs, parent_hwirq;
 	struct irq_domain *domain;
 	struct plic_priv *priv;
+	irq_hw_number_t hwirq;
 	bool cpuhp_setup;
-	unsigned int cpu;
-	u32 nr_irqs;
 
 	if (is_of_node(dev->fwnode)) {
 		const struct of_device_id *id;
@@ -462,13 +490,9 @@ static int plic_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	for (i = 0; i < nr_contexts; i++) {
-		struct of_phandle_args parent;
-		irq_hw_number_t hwirq;
-		int cpu;
-		unsigned long hartid;
-
-		if (of_irq_parse_one(to_of_node(dev->fwnode), i, &parent)) {
-			dev_err(dev, "failed to parse parent for context %d.\n", i);
+		error = plic_parse_context_parent(pdev, i, &parent_hwirq, &cpu);
+		if (error) {
+			dev_warn(dev, "hwirq for context%d not found\n", i);
 			continue;
 		}
 
@@ -476,7 +500,7 @@ static int plic_probe(struct platform_device *pdev)
 		 * Skip contexts other than external interrupts for our
 		 * privilege level.
 		 */
-		if (parent.args[0] != RV_IRQ_EXT) {
+		if (parent_hwirq != RV_IRQ_EXT) {
 			/* Disable S-mode enable bits if running in M-mode. */
 			if (IS_ENABLED(CONFIG_RISCV_M_MODE)) {
 				void __iomem *enable_base = priv->regs +
@@ -489,13 +513,6 @@ static int plic_probe(struct platform_device *pdev)
 			continue;
 		}
 
-		error = riscv_of_parent_hartid(parent.np, &hartid);
-		if (error < 0) {
-			dev_warn(dev, "failed to parse hart ID for context %d.\n", i);
-			continue;
-		}
-
-		cpu = riscv_hartid_to_cpuid(hartid);
 		if (cpu < 0) {
 			dev_warn(dev, "Invalid cpuid for context %d\n", i);
 			continue;
@@ -534,7 +551,7 @@ static int plic_probe(struct platform_device *pdev)
 		handler->enable_save = devm_kcalloc(dev, DIV_ROUND_UP(nr_irqs, 32),
 						    sizeof(*handler->enable_save), GFP_KERNEL);
 		if (!handler->enable_save)
-			return -ENOMEM;
+			goto fail_cleanup_contexts;
 done:
 		for (hwirq = 1; hwirq <= nr_irqs; hwirq++) {
 			plic_toggle(handler, hwirq, 0);
@@ -547,7 +564,7 @@ static int plic_probe(struct platform_device *pdev)
 	priv->irqdomain = irq_domain_add_linear(to_of_node(dev->fwnode), nr_irqs + 1,
 						&plic_irqdomain_ops, priv);
 	if (WARN_ON(!priv->irqdomain))
-		return -ENOMEM;
+		goto fail_cleanup_contexts;
 
 	/*
 	 * We can have multiple PLIC instances so setup cpuhp state
@@ -575,6 +592,22 @@ static int plic_probe(struct platform_device *pdev)
 	dev_info(dev, "mapped %d interrupts with %d handlers for %d contexts.\n",
 		 nr_irqs, nr_handlers, nr_contexts);
 	return 0;
+
+fail_cleanup_contexts:
+	for (i = 0; i < nr_contexts; i++) {
+		if (plic_parse_context_parent(pdev, i, &parent_hwirq, &cpu))
+			continue;
+		if (parent_hwirq != RV_IRQ_EXT || cpu < 0)
+			continue;
+
+		handler = per_cpu_ptr(&plic_handlers, cpu);
+		handler->present = false;
+		handler->hart_base = NULL;
+		handler->enable_base = NULL;
+		handler->enable_save = NULL;
+		handler->priv = NULL;
+	}
+	return -ENOMEM;
 }
 
 static struct platform_driver plic_driver = {
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:39:54 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:54 +0530
Subject: [PATCH v14 06/18] irqchip/sifive-plic: Parse number of irqs and contexts early in plic_probe
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-7-apatel@ventanamicro.com>

The SiFive PLIC driver needs to know the number of irqs and contexts
to complete initialization. Parse these details early in plic_probe()
to avoid unnecessary memory allocations and register mappings if these
details are not available.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-sifive-plic.c | 43 ++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index f0df5d0cb76e..e6d23fde51ed 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -416,6 +416,34 @@ static const struct of_device_id plic_match[] = {
 	{}
 };
 
+static int plic_parse_nr_irqs_and_contexts(struct platform_device *pdev,
+					   u32 *nr_irqs, u32 *nr_contexts)
+{
+	struct device *dev = &pdev->dev;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	rc = of_property_read_u32(to_of_node(dev->fwnode), "riscv,ndev", nr_irqs);
+	if (rc) {
+		dev_err(dev, "riscv,ndev property not available\n");
+		return rc;
+	}
+
+	*nr_contexts = of_irq_count(to_of_node(dev->fwnode));
+	if (WARN_ON(!(*nr_contexts))) {
+		dev_err(dev, "no PLIC context available\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int plic_parse_context_parent(struct platform_device *pdev, u32 context,
 				     u32 *parent_hwirq, int *parent_cpu)
 {
@@ -464,31 +492,26 @@ static int plic_probe(struct platform_device *pdev)
 			plic_quirks = (unsigned long)id->data;
 	}
 
+	error = plic_parse_nr_irqs_and_contexts(pdev, &nr_irqs, &nr_contexts);
+	if (error)
+		return error;
+
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
 	priv->dev = dev;
 	priv->plic_quirks = plic_quirks;
+	priv->nr_irqs = nr_irqs;
 
 	priv->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (WARN_ON(!priv->regs))
 		return -EIO;
 
-	of_property_read_u32(to_of_node(dev->fwnode), "riscv,ndev", &nr_irqs);
-	if (WARN_ON(!nr_irqs))
-		return -EINVAL;
-
-	priv->nr_irqs = nr_irqs;
-
 	priv->prio_save = devm_bitmap_zalloc(dev, nr_irqs, GFP_KERNEL);
 	if (!priv->prio_save)
 		return -ENOMEM;
 
-	nr_contexts = of_irq_count(to_of_node(dev->fwnode));
-	if (WARN_ON(!nr_contexts))
-		return -EINVAL;
-
 	for (i = 0; i < nr_contexts; i++) {
 		error = plic_parse_context_parent(pdev, i, &parent_hwirq, &cpu);
 		if (error) {
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:39:55 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:55 +0530
Subject: [PATCH v14 07/18] irqchip/sifive-plic: Improve locking safety by using irqsave/irqrestore
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-8-apatel@ventanamicro.com>

Now that PLIC driver is probed as a regular platform driver, the lock
dependency validator complains about the safety of handler->enable_lock
usage:

[    0.956775]  Possible interrupt unsafe locking scenario:

[    0.956998]        CPU0                    CPU1
[    0.957247]        ----                    ----
[    0.957439]   lock(&handler->enable_lock);
[    0.957607]                                local_irq_disable();
[    0.957793]                                lock(&irq_desc_lock_class);
[    0.958021]                                lock(&handler->enable_lock);
[    0.958246]   <Interrupt>
[    0.958342]     lock(&irq_desc_lock_class);
[    0.958501]
                *** DEADLOCK ***

To address above, use raw_spin_lock_irqsave/unlock_irqrestore() instead
of raw_spin_lock/unlock().

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-sifive-plic.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index e6d23fde51ed..175d02f7fd64 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -103,9 +103,11 @@ static void __plic_toggle(void __iomem *enable_base, int hwirq, int enable)
 
 static void plic_toggle(struct plic_handler *handler, int hwirq, int enable)
 {
-	raw_spin_lock(&handler->enable_lock);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&handler->enable_lock, flags);
 	__plic_toggle(handler->enable_base, hwirq, enable);
-	raw_spin_unlock(&handler->enable_lock);
+	raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
 }
 
 static inline void plic_irq_toggle(const struct cpumask *mask,
@@ -236,6 +238,7 @@ static int plic_irq_set_type(struct irq_data *d, unsigned int type)
 static int plic_irq_suspend(void)
 {
 	unsigned int i, cpu;
+	unsigned long flags;
 	u32 __iomem *reg;
 	struct plic_priv *priv;
 
@@ -253,12 +256,12 @@ static int plic_irq_suspend(void)
 		if (!handler->present)
 			continue;
 
-		raw_spin_lock(&handler->enable_lock);
+		raw_spin_lock_irqsave(&handler->enable_lock, flags);
 		for (i = 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) {
 			reg = handler->enable_base + i * sizeof(u32);
 			handler->enable_save[i] = readl(reg);
 		}
-		raw_spin_unlock(&handler->enable_lock);
+		raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
 	}
 
 	return 0;
@@ -267,6 +270,7 @@ static int plic_irq_suspend(void)
 static void plic_irq_resume(void)
 {
 	unsigned int i, index, cpu;
+	unsigned long flags;
 	u32 __iomem *reg;
 	struct plic_priv *priv;
 
@@ -284,12 +288,12 @@ static void plic_irq_resume(void)
 		if (!handler->present)
 			continue;
 
-		raw_spin_lock(&handler->enable_lock);
+		raw_spin_lock_irqsave(&handler->enable_lock, flags);
 		for (i = 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) {
 			reg = handler->enable_base + i * sizeof(u32);
 			writel(handler->enable_save[i], reg);
 		}
-		raw_spin_unlock(&handler->enable_lock);
+		raw_spin_unlock_irqrestore(&handler->enable_lock, flags);
 	}
 }
 
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:39:56 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:56 +0530
Subject: [PATCH v14 08/18] irqchip/riscv-intc: Add support for RISC-V AIA
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-9-apatel@ventanamicro.com>

The RISC-V advanced interrupt architecture (AIA) extends the per-HART
local interrupts in following ways:
1. Minimum 64 local interrupts for both RV32 and RV64
2. Ability to process multiple pending local interrupts in same
   interrupt handler
3. Priority configuration for each local interrupts
4. Special CSRs to configure/access the per-HART MSI controller

Add support for #1 and #2 described above in the RISC-V intc driver.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-intc.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
index e8d01b14ccdd..8997f6986f89 100644
--- a/drivers/irqchip/irq-riscv-intc.c
+++ b/drivers/irqchip/irq-riscv-intc.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/smp.h>
+#include <asm/hwcap.h>
 
 static struct irq_domain *intc_domain;
 
@@ -30,6 +31,14 @@ static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
 	generic_handle_domain_irq(intc_domain, cause);
 }
 
+static asmlinkage void riscv_intc_aia_irq(struct pt_regs *regs)
+{
+	unsigned long topi;
+
+	while ((topi = csr_read(CSR_TOPI)))
+		generic_handle_domain_irq(intc_domain, topi >> TOPI_IID_SHIFT);
+}
+
 /*
  * On RISC-V systems local interrupts are masked or unmasked by writing
  * the SIE (Supervisor Interrupt Enable) CSR.  As CSRs can only be written
@@ -39,12 +48,18 @@ static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
 
 static void riscv_intc_irq_mask(struct irq_data *d)
 {
-	csr_clear(CSR_IE, BIT(d->hwirq));
+	if (IS_ENABLED(CONFIG_32BIT) && d->hwirq >= BITS_PER_LONG)
+		csr_clear(CSR_IEH, BIT(d->hwirq - BITS_PER_LONG));
+	else
+		csr_clear(CSR_IE, BIT(d->hwirq));
 }
 
 static void riscv_intc_irq_unmask(struct irq_data *d)
 {
-	csr_set(CSR_IE, BIT(d->hwirq));
+	if (IS_ENABLED(CONFIG_32BIT) && d->hwirq >= BITS_PER_LONG)
+		csr_set(CSR_IEH, BIT(d->hwirq - BITS_PER_LONG));
+	else
+		csr_set(CSR_IE, BIT(d->hwirq));
 }
 
 static void riscv_intc_irq_eoi(struct irq_data *d)
@@ -115,16 +130,18 @@ static struct fwnode_handle *riscv_intc_hwnode(void)
 
 static int __init riscv_intc_init_common(struct fwnode_handle *fn)
 {
-	int rc;
+	int rc, nr_irqs = riscv_isa_extension_available(NULL, SxAIA) ? 64 : BITS_PER_LONG;
 
-	intc_domain = irq_domain_create_linear(fn, BITS_PER_LONG,
-					       &riscv_intc_domain_ops, NULL);
+	intc_domain = irq_domain_create_linear(fn, nr_irqs, &riscv_intc_domain_ops, NULL);
 	if (!intc_domain) {
 		pr_err("unable to add IRQ domain\n");
 		return -ENXIO;
 	}
 
-	rc = set_handle_irq(&riscv_intc_irq);
+	if (riscv_isa_extension_available(NULL, SxAIA))
+		rc = set_handle_irq(&riscv_intc_aia_irq);
+	else
+		rc = set_handle_irq(&riscv_intc_irq);
 	if (rc) {
 		pr_err("failed to set irq handler\n");
 		return rc;
@@ -132,7 +149,8 @@ static int __init riscv_intc_init_common(struct fwnode_handle *fn)
 
 	riscv_set_intc_hwnode_fn(riscv_intc_hwnode);
 
-	pr_info("%d local interrupts mapped\n", BITS_PER_LONG);
+	pr_info("%d local interrupts mapped%s\n", nr_irqs,
+		riscv_isa_extension_available(NULL, SxAIA) ? " using AIA" : "");
 
 	return 0;
 }
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:39:57 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:57 +0530
Subject: [PATCH v14 09/18] dt-bindings: interrupt-controller: Add RISC-V incoming MSI controller
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-10-apatel@ventanamicro.com>

Add DT bindings document for the RISC-V incoming MSI controller (IMSIC)
defined by the RISC-V advanced interrupt architecture (AIA) specification.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../interrupt-controller/riscv,imsics.yaml    | 172 ++++++++++++++++++
 1 file changed, 172 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml b/Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
new file mode 100644
index 000000000000..84976f17a4a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
@@ -0,0 +1,172 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/riscv,imsics.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Incoming MSI Controller (IMSIC)
+
+maintainers:
+  - Anup Patel <anup at brainfault.org>
+
+description: |
+  The RISC-V advanced interrupt architecture (AIA) defines a per-CPU incoming
+  MSI controller (IMSIC) for handling MSIs in a RISC-V platform. The RISC-V
+  AIA specification can be found at https://github.com/riscv/riscv-aia.
+
+  The IMSIC is a per-CPU (or per-HART) device with separate interrupt file
+  for each privilege level (machine or supervisor). The configuration of
+  a IMSIC interrupt file is done using AIA CSRs and it also has a 4KB MMIO
+  space to receive MSIs from devices. Each IMSIC interrupt file supports a
+  fixed number of interrupt identities (to distinguish MSIs from devices)
+  which is same for given privilege level across CPUs (or HARTs).
+
+  The device tree of a RISC-V platform will have one IMSIC device tree node
+  for each privilege level (machine or supervisor) which collectively describe
+  IMSIC interrupt files at that privilege level across CPUs (or HARTs).
+
+  The arrangement of IMSIC interrupt files in MMIO space of a RISC-V platform
+  follows a particular scheme defined by the RISC-V AIA specification. A IMSIC
+  group is a set of IMSIC interrupt files co-located in MMIO space and we can
+  have multiple IMSIC groups (i.e. clusters, sockets, chiplets, etc) in a
+  RISC-V platform. The MSI target address of a IMSIC interrupt file at given
+  privilege level (machine or supervisor) encodes group index, HART index,
+  and guest index (shown below).
+
+  XLEN-1            > (HART Index MSB)                  12    0
+  |                  |                                  |     |
+  -------------------------------------------------------------
+  |xxxxxx|Group Index|xxxxxxxxxxx|HART Index|Guest Index|  0  |
+  -------------------------------------------------------------
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+  - $ref: /schemas/interrupt-controller/msi-controller.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - qemu,imsics
+      - const: riscv,imsics
+
+  reg:
+    minItems: 1
+    maxItems: 16384
+    description:
+      Base address of each IMSIC group.
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 0
+
+  msi-controller: true
+
+  "#msi-cells":
+    const: 0
+
+  interrupts-extended:
+    minItems: 1
+    maxItems: 16384
+    description:
+      This property represents the set of CPUs (or HARTs) for which given
+      device tree node describes the IMSIC interrupt files. Each node pointed
+      to should be a riscv,cpu-intc node, which has a CPU node (i.e. RISC-V
+      HART) as parent.
+
+  riscv,num-ids:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 63
+    maximum: 2047
+    description:
+      Number of interrupt identities supported by IMSIC interrupt file.
+
+  riscv,num-guest-ids:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 63
+    maximum: 2047
+    description:
+      Number of interrupt identities are supported by IMSIC guest interrupt
+      file. When not specified it is assumed to be same as specified by the
+      riscv,num-ids property.
+
+  riscv,guest-index-bits:
+    minimum: 0
+    maximum: 7
+    default: 0
+    description:
+      Number of guest index bits in the MSI target address.
+
+  riscv,hart-index-bits:
+    minimum: 0
+    maximum: 15
+    description:
+      Number of HART index bits in the MSI target address. When not
+      specified it is calculated based on the interrupts-extended property.
+
+  riscv,group-index-bits:
+    minimum: 0
+    maximum: 7
+    default: 0
+    description:
+      Number of group index bits in the MSI target address.
+
+  riscv,group-index-shift:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 55
+    default: 24
+    description:
+      The least significant bit position of the group index bits in the
+      MSI target address.
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - msi-controller
+  - "#msi-cells"
+  - interrupts-extended
+  - riscv,num-ids
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    // Example 1 (Machine-level IMSIC files with just one group):
+
+    interrupt-controller at 24000000 {
+      compatible = "qemu,imsics", "riscv,imsics";
+      interrupts-extended = <&cpu1_intc 11>,
+                            <&cpu2_intc 11>,
+                            <&cpu3_intc 11>,
+                            <&cpu4_intc 11>;
+      reg = <0x28000000 0x4000>;
+      interrupt-controller;
+      #interrupt-cells = <0>;
+      msi-controller;
+      #msi-cells = <0>;
+      riscv,num-ids = <127>;
+    };
+
+  - |
+    // Example 2 (Supervisor-level IMSIC files with two groups):
+
+    interrupt-controller at 28000000 {
+      compatible = "qemu,imsics", "riscv,imsics";
+      interrupts-extended = <&cpu1_intc 9>,
+                            <&cpu2_intc 9>,
+                            <&cpu3_intc 9>,
+                            <&cpu4_intc 9>;
+      reg = <0x28000000 0x2000>, /* Group0 IMSICs */
+            <0x29000000 0x2000>; /* Group1 IMSICs */
+      interrupt-controller;
+      #interrupt-cells = <0>;
+      msi-controller;
+      #msi-cells = <0>;
+      riscv,num-ids = <127>;
+      riscv,group-index-bits = <1>;
+      riscv,group-index-shift = <24>;
+    };
+...
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:39:58 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:58 +0530
Subject: [PATCH v14 10/18] genirq/matrix: Dynamic bitmap allocation
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-11-apatel@ventanamicro.com>

From: Bj?rn T?pel <bjorn at rivosinc.com>

Some (future) users of the irq matrix allocator, do not know the size
of the matrix bitmaps at compile time.

To avoid wasting memory on unnecessary large bitmaps, size the bitmap
at matrix allocation time.

Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 arch/x86/include/asm/hw_irq.h |  2 --
 kernel/irq/matrix.c           | 28 +++++++++++++++++-----------
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index b02c3cd3c0f6..edebf1020e04 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -16,8 +16,6 @@
 
 #include <asm/irq_vectors.h>
 
-#define IRQ_MATRIX_BITS		NR_VECTORS
-
 #ifndef __ASSEMBLY__
 
 #include <linux/percpu.h>
diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c
index 75d0ae490e29..8f222d1cccec 100644
--- a/kernel/irq/matrix.c
+++ b/kernel/irq/matrix.c
@@ -8,8 +8,6 @@
 #include <linux/cpu.h>
 #include <linux/irq.h>
 
-#define IRQ_MATRIX_SIZE	(BITS_TO_LONGS(IRQ_MATRIX_BITS))
-
 struct cpumap {
 	unsigned int		available;
 	unsigned int		allocated;
@@ -17,8 +15,8 @@ struct cpumap {
 	unsigned int		managed_allocated;
 	bool			initialized;
 	bool			online;
-	unsigned long		alloc_map[IRQ_MATRIX_SIZE];
-	unsigned long		managed_map[IRQ_MATRIX_SIZE];
+	unsigned long		*managed_map;
+	unsigned long		alloc_map[];
 };
 
 struct irq_matrix {
@@ -32,8 +30,8 @@ struct irq_matrix {
 	unsigned int		total_allocated;
 	unsigned int		online_maps;
 	struct cpumap __percpu	*maps;
-	unsigned long		scratch_map[IRQ_MATRIX_SIZE];
-	unsigned long		system_map[IRQ_MATRIX_SIZE];
+	unsigned long		*system_map;
+	unsigned long		scratch_map[];
 };
 
 #define CREATE_TRACE_POINTS
@@ -50,24 +48,32 @@ __init struct irq_matrix *irq_alloc_matrix(unsigned int matrix_bits,
 					   unsigned int alloc_start,
 					   unsigned int alloc_end)
 {
+	unsigned int cpu, matrix_size = BITS_TO_LONGS(matrix_bits);
 	struct irq_matrix *m;
 
-	if (matrix_bits > IRQ_MATRIX_BITS)
-		return NULL;
-
-	m = kzalloc(sizeof(*m), GFP_KERNEL);
+	m = kzalloc(struct_size(m, scratch_map, matrix_size * 2), GFP_KERNEL);
 	if (!m)
 		return NULL;
 
+	m->system_map = &m->scratch_map[matrix_size];
+
 	m->matrix_bits = matrix_bits;
 	m->alloc_start = alloc_start;
 	m->alloc_end = alloc_end;
 	m->alloc_size = alloc_end - alloc_start;
-	m->maps = alloc_percpu(*m->maps);
+	m->maps = __alloc_percpu(struct_size(m->maps, alloc_map, matrix_size * 2),
+				 __alignof__(*m->maps));
 	if (!m->maps) {
 		kfree(m);
 		return NULL;
 	}
+
+	for_each_possible_cpu(cpu) {
+		struct cpumap *cm = per_cpu_ptr(m->maps, cpu);
+
+		cm->managed_map = &cm->alloc_map[matrix_size];
+	}
+
 	return m;
 }
 
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:39:59 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:09:59 +0530
Subject: [PATCH v14 11/18] irqchip: Add RISC-V incoming MSI controller early driver
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-12-apatel@ventanamicro.com>

The RISC-V advanced interrupt architecture (AIA) specification
defines a new MSI controller called incoming message signalled
interrupt controller (IMSIC) which manages MSI on per-HART (or
per-CPU) basis. It also supports IPIs as software injected MSIs.
(For more details refer https://github.com/riscv/riscv-aia)

Add an early irqchip driver for RISC-V IMSIC which sets up the
IMSIC state and provide IPIs.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                 |   7 +
 drivers/irqchip/Makefile                |   1 +
 drivers/irqchip/irq-riscv-imsic-early.c | 201 ++++++
 drivers/irqchip/irq-riscv-imsic-state.c | 870 ++++++++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.h | 107 +++
 include/linux/irqchip/riscv-imsic.h     |  87 +++
 6 files changed, 1273 insertions(+)
 create mode 100644 drivers/irqchip/irq-riscv-imsic-early.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.h
 create mode 100644 include/linux/irqchip/riscv-imsic.h

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index f7149d0f3d45..85f86e31c996 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -546,6 +546,13 @@ config SIFIVE_PLIC
 	select IRQ_DOMAIN_HIERARCHY
 	select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
 
+config RISCV_IMSIC
+	bool
+	depends on RISCV
+	select IRQ_DOMAIN_HIERARCHY
+	select GENERIC_IRQ_MATRIX_ALLOCATOR
+	select GENERIC_MSI_IRQ
+
 config EXYNOS_IRQ_COMBINER
 	bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
 	depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index ffd945fe71aa..d714724387ce 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
 obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
+obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
 obj-$(CONFIG_IMX_INTMUX)		+= irq-imx-intmux.o
diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
new file mode 100644
index 000000000000..079be5c0eec3
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "riscv-imsic: " fmt
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-imsic-state.h"
+
+static int imsic_parent_irq;
+
+#ifdef CONFIG_SMP
+static void imsic_ipi_send(unsigned int cpu)
+{
+	struct imsic_local_config *local = per_cpu_ptr(imsic->global.local, cpu);
+
+	writel_relaxed(IMSIC_IPI_ID, local->msi_va);
+}
+
+static void imsic_ipi_starting_cpu(void)
+{
+	/* Enable IPIs for current CPU. */
+	__imsic_id_set_enable(IMSIC_IPI_ID);
+}
+
+static void imsic_ipi_dying_cpu(void)
+{
+	/* Disable IPIs for current CPU. */
+	__imsic_id_clear_enable(IMSIC_IPI_ID);
+}
+
+static int __init imsic_ipi_domain_init(void)
+{
+	int virq;
+
+	/* Create IMSIC IPI multiplexing */
+	virq = ipi_mux_create(IMSIC_NR_IPI, imsic_ipi_send);
+	if (virq <= 0)
+		return virq < 0 ? virq : -ENOMEM;
+
+	/* Set vIRQ range */
+	riscv_ipi_set_virq_range(virq, IMSIC_NR_IPI, true);
+
+	/* Announce that IMSIC is providing IPIs */
+	pr_info("%pfwP: providing IPIs using interrupt %d\n", imsic->fwnode, IMSIC_IPI_ID);
+
+	return 0;
+}
+#else
+static void imsic_ipi_starting_cpu(void) { }
+static void imsic_ipi_dying_cpu(void) { }
+static int __init imsic_ipi_domain_init(void) { return 0; }
+#endif
+
+/*
+ * To handle an interrupt, we read the TOPEI CSR and write zero in one
+ * instruction. If TOPEI CSR is non-zero then we translate TOPEI.ID to
+ * Linux interrupt number and let Linux IRQ subsystem handle it.
+ */
+static void imsic_handle_irq(struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int err, cpu = smp_processor_id();
+	struct imsic_vector *vec;
+	unsigned long local_id;
+
+	chained_irq_enter(chip, desc);
+
+	while ((local_id = csr_swap(CSR_TOPEI, 0))) {
+		local_id >>= TOPEI_ID_SHIFT;
+
+		if (local_id == IMSIC_IPI_ID) {
+			if (IS_ENABLED(CONFIG_SMP))
+				ipi_mux_process();
+			continue;
+		}
+
+		if (unlikely(!imsic->base_domain))
+			continue;
+
+		vec = imsic_vector_from_local_id(cpu, local_id);
+		if (!vec) {
+			pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id);
+			continue;
+		}
+
+		err = generic_handle_domain_irq(imsic->base_domain, vec->hwirq);
+		if (unlikely(err))
+			pr_warn_ratelimited("hwirq 0x%x mapping not found\n", vec->hwirq);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static int imsic_starting_cpu(unsigned int cpu)
+{
+	/* Mark per-CPU IMSIC state as online */
+	imsic_state_online();
+
+	/* Enable per-CPU parent interrupt */
+	enable_percpu_irq(imsic_parent_irq, irq_get_trigger_type(imsic_parent_irq));
+
+	/* Setup IPIs */
+	imsic_ipi_starting_cpu();
+
+	/*
+	 * Interrupts identities might have been enabled/disabled while
+	 * this CPU was not running so sync-up local enable/disable state.
+	 */
+	imsic_local_sync_all();
+
+	/* Enable local interrupt delivery */
+	imsic_local_delivery(true);
+
+	return 0;
+}
+
+static int imsic_dying_cpu(unsigned int cpu)
+{
+	/* Cleanup IPIs */
+	imsic_ipi_dying_cpu();
+
+	/* Mark per-CPU IMSIC state as offline */
+	imsic_state_offline();
+
+	return 0;
+}
+
+static int __init imsic_early_probe(struct fwnode_handle *fwnode)
+{
+	struct irq_domain *domain;
+	int rc;
+
+	/* Find parent domain and register chained handler */
+	domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS_ANY);
+	if (!domain) {
+		pr_err("%pfwP: Failed to find INTC domain\n", fwnode);
+		return -ENOENT;
+	}
+	imsic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
+	if (!imsic_parent_irq) {
+		pr_err("%pfwP: Failed to create INTC mapping\n", fwnode);
+		return -ENOENT;
+	}
+
+	/* Initialize IPI domain */
+	rc = imsic_ipi_domain_init();
+	if (rc) {
+		pr_err("%pfwP: Failed to initialize IPI domain\n", fwnode);
+		return rc;
+	}
+
+	/* Setup chained handler to the parent domain interrupt */
+	irq_set_chained_handler(imsic_parent_irq, imsic_handle_irq);
+
+	/*
+	 * Setup cpuhp state (must be done after setting imsic_parent_irq)
+	 *
+	 * Don't disable per-CPU IMSIC file when CPU goes offline
+	 * because this affects IPI and the masking/unmasking of
+	 * virtual IPIs is done via generic IPI-Mux
+	 */
+	cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "irqchip/riscv/imsic:starting",
+			  imsic_starting_cpu, imsic_dying_cpu);
+
+	return 0;
+}
+
+static int __init imsic_early_dt_init(struct device_node *node, struct device_node *parent)
+{
+	struct fwnode_handle *fwnode = &node->fwnode;
+	int rc;
+
+	/* Setup IMSIC state */
+	rc = imsic_setup_state(fwnode);
+	if (rc) {
+		pr_err("%pfwP: failed to setup state (error %d)\n", fwnode, rc);
+		return rc;
+	}
+
+	/* Do early setup of IPIs */
+	rc = imsic_early_probe(fwnode);
+	if (rc)
+		return rc;
+
+	/* Ensure that OF platform device gets probed */
+	of_node_clear_flag(node, OF_POPULATED);
+	return 0;
+}
+
+IRQCHIP_DECLARE(riscv_imsic, "riscv,imsics", imsic_early_dt_init);
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
new file mode 100644
index 000000000000..0c19ffb9ca3e
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -0,0 +1,870 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "riscv-imsic: " fmt
+#include <linux/cpu.h>
+#include <linux/bitmap.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <asm/hwcap.h>
+
+#include "irq-riscv-imsic-state.h"
+
+#define IMSIC_DISABLE_EIDELIVERY		0
+#define IMSIC_ENABLE_EIDELIVERY			1
+#define IMSIC_DISABLE_EITHRESHOLD		1
+#define IMSIC_ENABLE_EITHRESHOLD		0
+
+static inline void imsic_csr_write(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	csr_write(CSR_IREG, val);
+}
+
+static inline unsigned long imsic_csr_read(unsigned long reg)
+{
+	csr_write(CSR_ISELECT, reg);
+	return csr_read(CSR_IREG);
+}
+
+static inline unsigned long imsic_csr_read_clear(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	return csr_read_clear(CSR_IREG, val);
+}
+
+static inline void imsic_csr_set(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	csr_set(CSR_IREG, val);
+}
+
+static inline void imsic_csr_clear(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	csr_clear(CSR_IREG, val);
+}
+
+struct imsic_priv *imsic;
+
+const struct imsic_global_config *imsic_get_global_config(void)
+{
+	return imsic ? &imsic->global : NULL;
+}
+EXPORT_SYMBOL_GPL(imsic_get_global_config);
+
+static bool __imsic_eix_read_clear(unsigned long id, bool pend)
+{
+	unsigned long isel, imask;
+
+	isel = id / BITS_PER_LONG;
+	isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
+	isel += pend ? IMSIC_EIP0 : IMSIC_EIE0;
+	imask = BIT(id & (__riscv_xlen - 1));
+
+	return !!(imsic_csr_read_clear(isel, imask) & imask);
+}
+
+static inline bool __imsic_id_read_clear_enabled(unsigned long id)
+{
+	return __imsic_eix_read_clear(id, false);
+}
+
+static inline bool __imsic_id_read_clear_pending(unsigned long id)
+{
+	return __imsic_eix_read_clear(id, true);
+}
+
+void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val)
+{
+	unsigned long id = base_id, last_id = base_id + num_id;
+	unsigned long i, isel, ireg;
+
+	while (id < last_id) {
+		isel = id / BITS_PER_LONG;
+		isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
+		isel += pend ? IMSIC_EIP0 : IMSIC_EIE0;
+
+		/*
+		 * Prepare the ID mask to be programmed in the
+		 * IMSIC EIEx and EIPx registers. These registers
+		 * are XLEN-wide and we must not touch IDs which
+		 * are < base_id and >= (base_id + num_id).
+		 */
+		ireg = 0;
+		for (i = id & (__riscv_xlen - 1); id < last_id && i < __riscv_xlen; i++) {
+			ireg |= BIT(i);
+			id++;
+		}
+
+		/*
+		 * The IMSIC EIEx and EIPx registers are indirectly
+		 * accessed via using ISELECT and IREG CSRs so we
+		 * need to access these CSRs without getting preempted.
+		 *
+		 * All existing users of this function call this
+		 * function with local IRQs disabled so we don't
+		 * need to do anything special here.
+		 */
+		if (val)
+			imsic_csr_set(isel, ireg);
+		else
+			imsic_csr_clear(isel, ireg);
+	}
+}
+
+static void __imsic_local_sync(struct imsic_local_priv *lpriv)
+{
+	struct imsic_local_config *mlocal;
+	struct imsic_vector *vec, *mvec;
+	int i;
+
+	lockdep_assert_held(&lpriv->lock);
+
+	/* This pairs with the barrier in __imsic_remote_sync(). */
+	smp_mb();
+
+	for_each_set_bit(i, lpriv->dirty_bitmap, imsic->global.nr_ids + 1) {
+		if (!i || i == IMSIC_IPI_ID)
+			goto skip;
+		vec = &lpriv->vectors[i];
+
+		if (READ_ONCE(vec->enable))
+			__imsic_id_set_enable(i);
+		else
+			__imsic_id_clear_enable(i);
+
+		/*
+		 * If the ID was being moved to a new ID on some other CPU
+		 * then we can get a MSI during the movement so check the
+		 * ID pending bit and re-trigger the new ID on other CPU
+		 * using MMIO write.
+		 */
+		mvec = READ_ONCE(vec->move);
+		WRITE_ONCE(vec->move, NULL);
+		if (mvec && mvec != vec) {
+			if (__imsic_id_read_clear_pending(i)) {
+				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
+				writel_relaxed(mvec->local_id, mlocal->msi_va);
+			}
+
+			imsic_vector_free(&lpriv->vectors[i]);
+		}
+
+skip:
+		bitmap_clear(lpriv->dirty_bitmap, i, 1);
+	}
+}
+
+void imsic_local_sync_all(void)
+{
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
+	__imsic_local_sync(lpriv);
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+}
+
+void imsic_local_delivery(bool enable)
+{
+	if (enable) {
+		imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
+		imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
+		return;
+	}
+
+	imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
+	imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
+}
+
+#ifdef CONFIG_SMP
+static void imsic_local_timer_callback(struct timer_list *timer)
+{
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	__imsic_local_sync(lpriv);
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+}
+
+static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
+{
+	lockdep_assert_held(&lpriv->lock);
+
+	/*
+	 * Ensure that changes to vector enable, vector move and
+	 * dirty bitmap are visible to the target CPU.
+	 *
+	 * This pairs with the barrier in __imsic_local_sync().
+	 */
+	smp_mb();
+
+	/*
+	 * We schedule a timer on the target CPU if the target CPU is not
+	 * same as the current CPU. An offline CPU will unconditionally
+	 * synchronize IDs through imsic_starting_cpu() when the
+	 * CPU is brought up.
+	 */
+	if (cpu_online(cpu)) {
+		if (cpu == smp_processor_id()) {
+			__imsic_local_sync(lpriv);
+			return;
+		}
+
+		if (!timer_pending(&lpriv->timer)) {
+			lpriv->timer.expires = jiffies + 1;
+			add_timer_on(&lpriv->timer, cpu);
+		}
+	}
+}
+#else
+static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
+{
+	lockdep_assert_held(&lpriv->lock);
+	__imsic_local_sync(lpriv);
+}
+#endif
+
+void imsic_vector_mask(struct imsic_vector *vec)
+{
+	struct imsic_local_priv *lpriv;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
+		return;
+
+	/*
+	 * This function is called through Linux irq subsystem with
+	 * irqs disabled so no need to save/restore irq flags.
+	 */
+
+	raw_spin_lock(&lpriv->lock);
+
+	vec->enable = false;
+	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
+	__imsic_remote_sync(lpriv, vec->cpu);
+
+	raw_spin_unlock(&lpriv->lock);
+}
+
+void imsic_vector_unmask(struct imsic_vector *vec)
+{
+	struct imsic_local_priv *lpriv;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
+		return;
+
+	/*
+	 * This function is called through Linux irq subsystem with
+	 * irqs disabled so no need to save/restore irq flags.
+	 */
+
+	raw_spin_lock(&lpriv->lock);
+
+	vec->enable = true;
+	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
+	__imsic_remote_sync(lpriv, vec->cpu);
+
+	raw_spin_unlock(&lpriv->lock);
+}
+
+static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, struct imsic_vector *vec,
+				     bool new_enable, struct imsic_vector *new_move)
+{
+	unsigned long flags;
+	bool enabled;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+
+	/* Update enable and move details */
+	enabled = READ_ONCE(vec->enable);
+	WRITE_ONCE(vec->enable, new_enable);
+	WRITE_ONCE(vec->move, new_move);
+
+	/* Mark the vector as dirty and synchronize */
+	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
+	__imsic_remote_sync(lpriv, vec->cpu);
+
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+
+	return enabled;
+}
+
+void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec)
+{
+	struct imsic_local_priv *old_lpriv, *new_lpriv;
+	bool enabled;
+
+	if (WARN_ON_ONCE(old_vec->cpu == new_vec->cpu))
+		return;
+
+	old_lpriv = per_cpu_ptr(imsic->lpriv, old_vec->cpu);
+	if (WARN_ON_ONCE(&old_lpriv->vectors[old_vec->local_id] != old_vec))
+		return;
+
+	new_lpriv = per_cpu_ptr(imsic->lpriv, new_vec->cpu);
+	if (WARN_ON_ONCE(&new_lpriv->vectors[new_vec->local_id] != new_vec))
+		return;
+
+	/*
+	 * Move and re-trigger the new vector based on the pending
+	 * state of the old vector because we might get a device
+	 * interrupt on the old vector while device was being moved
+	 * to the new vector.
+	 */
+	enabled = imsic_vector_move_update(old_lpriv, old_vec, false, new_vec);
+	imsic_vector_move_update(new_lpriv, new_vec, enabled, new_vec);
+}
+
+#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
+void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind)
+{
+	struct imsic_local_priv *lpriv;
+	struct imsic_vector *mvec;
+	bool is_enabled;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
+		return;
+
+	is_enabled = imsic_vector_isenabled(vec);
+	mvec = imsic_vector_get_move(vec);
+
+	seq_printf(m, "%*starget_cpu      : %5u\n", ind, "", vec->cpu);
+	seq_printf(m, "%*starget_local_id : %5u\n", ind, "", vec->local_id);
+	seq_printf(m, "%*sis_reserved     : %5u\n", ind, "",
+		   (vec->local_id <= IMSIC_IPI_ID) ? 1 : 0);
+	seq_printf(m, "%*sis_enabled      : %5u\n", ind, "", is_enabled ? 1 : 0);
+	seq_printf(m, "%*sis_move_pending : %5u\n", ind, "", mvec ? 1 : 0);
+	if (mvec) {
+		seq_printf(m, "%*smove_cpu        : %5u\n", ind, "", mvec->cpu);
+		seq_printf(m, "%*smove_local_id   : %5u\n", ind, "", mvec->local_id);
+	}
+}
+
+void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
+{
+	irq_matrix_debug_show(m, imsic->matrix, ind);
+}
+#endif
+
+struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
+{
+	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+
+	if (!lpriv || imsic->global.nr_ids < local_id)
+		return NULL;
+
+	return &lpriv->vectors[local_id];
+}
+
+struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask)
+{
+	struct imsic_vector *vec = NULL;
+	struct imsic_local_priv *lpriv;
+	unsigned long flags;
+	unsigned int cpu;
+	int local_id;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	local_id = irq_matrix_alloc(imsic->matrix, mask, false, &cpu);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+	if (local_id < 0)
+		return NULL;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+	vec = &lpriv->vectors[local_id];
+	vec->hwirq = hwirq;
+	vec->enable = false;
+	vec->move = NULL;
+
+	return vec;
+}
+
+void imsic_vector_free(struct imsic_vector *vec)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	vec->hwirq = UINT_MAX;
+	irq_matrix_free(imsic->matrix, vec->cpu, vec->local_id, false);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+}
+
+static void __init imsic_local_cleanup(void)
+{
+	struct imsic_local_priv *lpriv;
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+
+		bitmap_free(lpriv->dirty_bitmap);
+		kfree(lpriv->vectors);
+	}
+
+	free_percpu(imsic->lpriv);
+}
+
+static int __init imsic_local_init(void)
+{
+	struct imsic_global_config *global = &imsic->global;
+	struct imsic_local_priv *lpriv;
+	struct imsic_vector *vec;
+	int cpu, i;
+
+	/* Allocate per-CPU private state */
+	imsic->lpriv = alloc_percpu(typeof(*imsic->lpriv));
+	if (!imsic->lpriv)
+		return -ENOMEM;
+
+	/* Setup per-CPU private state */
+	for_each_possible_cpu(cpu) {
+		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+
+		raw_spin_lock_init(&lpriv->lock);
+
+		/* Allocate dirty bitmap */
+		lpriv->dirty_bitmap = bitmap_zalloc(global->nr_ids + 1, GFP_KERNEL);
+		if (!lpriv->dirty_bitmap)
+			goto fail_local_cleanup;
+
+#ifdef CONFIG_SMP
+		/* Setup lazy timer for synchronization */
+		timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
+#endif
+
+		/* Allocate vector array */
+		lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
+					 GFP_KERNEL);
+		if (!lpriv->vectors)
+			goto fail_local_cleanup;
+
+		/* Setup vector array */
+		for (i = 0; i <= global->nr_ids; i++) {
+			vec = &lpriv->vectors[i];
+			vec->cpu = cpu;
+			vec->local_id = i;
+			vec->hwirq = UINT_MAX;
+		}
+	}
+
+	return 0;
+
+fail_local_cleanup:
+	imsic_local_cleanup();
+	return -ENOMEM;
+}
+
+void imsic_state_online(void)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	irq_matrix_online(imsic->matrix);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+}
+
+void imsic_state_offline(void)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	irq_matrix_offline(imsic->matrix);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+
+#ifdef CONFIG_SMP
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	WARN_ON_ONCE(try_to_del_timer_sync(&lpriv->timer) < 0);
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+#endif
+}
+
+static int __init imsic_matrix_init(void)
+{
+	struct imsic_global_config *global = &imsic->global;
+
+	raw_spin_lock_init(&imsic->matrix_lock);
+	imsic->matrix = irq_alloc_matrix(global->nr_ids + 1,
+					 0, global->nr_ids + 1);
+	if (!imsic->matrix)
+		return -ENOMEM;
+
+	/* Reserve ID#0 because it is special and never implemented */
+	irq_matrix_assign_system(imsic->matrix, 0, false);
+
+	/* Reserve IPI ID because it is special and used internally */
+	irq_matrix_assign_system(imsic->matrix, IMSIC_IPI_ID, false);
+
+	return 0;
+}
+
+static int __init imsic_get_parent_hartid(struct fwnode_handle *fwnode,
+					  u32 index, unsigned long *hartid)
+{
+	struct of_phandle_args parent;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(fwnode))
+		return -EINVAL;
+
+	rc = of_irq_parse_one(to_of_node(fwnode), index, &parent);
+	if (rc)
+		return rc;
+
+	/*
+	 * Skip interrupts other than external interrupts for
+	 * current privilege level.
+	 */
+	if (parent.args[0] != RV_IRQ_EXT)
+		return -EINVAL;
+
+	return riscv_of_parent_hartid(parent.np, hartid);
+}
+
+static int __init imsic_get_mmio_resource(struct fwnode_handle *fwnode,
+					  u32 index, struct resource *res)
+{
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(fwnode))
+		return -EINVAL;
+
+	return of_address_to_resource(to_of_node(fwnode), index, res);
+}
+
+static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
+				     struct imsic_global_config *global,
+				     u32 *nr_parent_irqs,
+				     u32 *nr_mmios)
+{
+	unsigned long hartid;
+	struct resource res;
+	int rc;
+	u32 i;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(fwnode))
+		return -EINVAL;
+
+	*nr_parent_irqs = 0;
+	*nr_mmios = 0;
+
+	/* Find number of parent interrupts */
+	while (!imsic_get_parent_hartid(fwnode, *nr_parent_irqs, &hartid))
+		(*nr_parent_irqs)++;
+	if (!*nr_parent_irqs) {
+		pr_err("%pfwP: no parent irqs available\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Find number of guest index bits in MSI address */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,guest-index-bits",
+				  &global->guest_index_bits);
+	if (rc)
+		global->guest_index_bits = 0;
+
+	/* Find number of HART index bits */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,hart-index-bits",
+				  &global->hart_index_bits);
+	if (rc) {
+		/* Assume default value */
+		global->hart_index_bits = __fls(*nr_parent_irqs);
+		if (BIT(global->hart_index_bits) < *nr_parent_irqs)
+			global->hart_index_bits++;
+	}
+
+	/* Find number of group index bits */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-bits",
+				  &global->group_index_bits);
+	if (rc)
+		global->group_index_bits = 0;
+
+	/*
+	 * Find first bit position of group index.
+	 * If not specified assumed the default APLIC-IMSIC configuration.
+	 */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-shift",
+				  &global->group_index_shift);
+	if (rc)
+		global->group_index_shift = IMSIC_MMIO_PAGE_SHIFT * 2;
+
+	/* Find number of interrupt identities */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-ids",
+				  &global->nr_ids);
+	if (rc) {
+		pr_err("%pfwP: number of interrupt identities not found\n", fwnode);
+		return rc;
+	}
+
+	/* Find number of guest interrupt identities */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-guest-ids",
+				  &global->nr_guest_ids);
+	if (rc)
+		global->nr_guest_ids = global->nr_ids;
+
+	/* Sanity check guest index bits */
+	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT;
+	if (i < global->guest_index_bits) {
+		pr_err("%pfwP: guest index bits too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check HART index bits */
+	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT - global->guest_index_bits;
+	if (i < global->hart_index_bits) {
+		pr_err("%pfwP: HART index bits too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check group index bits */
+	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
+	    global->guest_index_bits - global->hart_index_bits;
+	if (i < global->group_index_bits) {
+		pr_err("%pfwP: group index bits too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check group index shift */
+	i = global->group_index_bits + global->group_index_shift - 1;
+	if (i >= BITS_PER_LONG) {
+		pr_err("%pfwP: group index shift too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check number of interrupt identities */
+	if (global->nr_ids < IMSIC_MIN_ID ||
+	    global->nr_ids >= IMSIC_MAX_ID ||
+	    (global->nr_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID) {
+		pr_err("%pfwP: invalid number of interrupt identities\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check number of guest interrupt identities */
+	if (global->nr_guest_ids < IMSIC_MIN_ID ||
+	    global->nr_guest_ids >= IMSIC_MAX_ID ||
+	    (global->nr_guest_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID) {
+		pr_err("%pfwP: invalid number of guest interrupt identities\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Compute base address */
+	rc = imsic_get_mmio_resource(fwnode, 0, &res);
+	if (rc) {
+		pr_err("%pfwP: first MMIO resource not found\n", fwnode);
+		return -EINVAL;
+	}
+	global->base_addr = res.start;
+	global->base_addr &= ~(BIT(global->guest_index_bits +
+				   global->hart_index_bits +
+				   IMSIC_MMIO_PAGE_SHIFT) - 1);
+	global->base_addr &= ~((BIT(global->group_index_bits) - 1) <<
+			       global->group_index_shift);
+
+	/* Find number of MMIO register sets */
+	while (!imsic_get_mmio_resource(fwnode, *nr_mmios, &res))
+		(*nr_mmios)++;
+
+	return 0;
+}
+
+int __init imsic_setup_state(struct fwnode_handle *fwnode)
+{
+	u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
+	struct imsic_global_config *global;
+	struct imsic_local_config *local;
+	void __iomem **mmios_va = NULL;
+	struct resource *mmios = NULL;
+	unsigned long reloff, hartid;
+	phys_addr_t base_addr;
+	int rc, cpu;
+
+	/*
+	 * Only one IMSIC instance allowed in a platform for clean
+	 * implementation of SMP IRQ affinity and per-CPU IPIs.
+	 *
+	 * This means on a multi-socket (or multi-die) platform we
+	 * will have multiple MMIO regions for one IMSIC instance.
+	 */
+	if (imsic) {
+		pr_err("%pfwP: already initialized hence ignoring\n", fwnode);
+		return -EALREADY;
+	}
+
+	if (!riscv_isa_extension_available(NULL, SxAIA)) {
+		pr_err("%pfwP: AIA support not available\n", fwnode);
+		return -ENODEV;
+	}
+
+	imsic = kzalloc(sizeof(*imsic), GFP_KERNEL);
+	if (!imsic)
+		return -ENOMEM;
+	imsic->fwnode = fwnode;
+	global = &imsic->global;
+
+	global->local = alloc_percpu(typeof(*global->local));
+	if (!global->local) {
+		rc = -ENOMEM;
+		goto out_free_priv;
+	}
+
+	/* Parse IMSIC fwnode */
+	rc = imsic_parse_fwnode(fwnode, global, &nr_parent_irqs, &nr_mmios);
+	if (rc)
+		goto out_free_local;
+
+	/* Allocate MMIO resource array */
+	mmios = kcalloc(nr_mmios, sizeof(*mmios), GFP_KERNEL);
+	if (!mmios) {
+		rc = -ENOMEM;
+		goto out_free_local;
+	}
+
+	/* Allocate MMIO virtual address array */
+	mmios_va = kcalloc(nr_mmios, sizeof(*mmios_va), GFP_KERNEL);
+	if (!mmios_va) {
+		rc = -ENOMEM;
+		goto out_iounmap;
+	}
+
+	/* Parse and map MMIO register sets */
+	for (i = 0; i < nr_mmios; i++) {
+		rc = imsic_get_mmio_resource(fwnode, i, &mmios[i]);
+		if (rc) {
+			pr_err("%pfwP: unable to parse MMIO regset %d\n", fwnode, i);
+			goto out_iounmap;
+		}
+
+		base_addr = mmios[i].start;
+		base_addr &= ~(BIT(global->guest_index_bits +
+				   global->hart_index_bits +
+				   IMSIC_MMIO_PAGE_SHIFT) - 1);
+		base_addr &= ~((BIT(global->group_index_bits) - 1) <<
+			       global->group_index_shift);
+		if (base_addr != global->base_addr) {
+			rc = -EINVAL;
+			pr_err("%pfwP: address mismatch for regset %d\n", fwnode, i);
+			goto out_iounmap;
+		}
+
+		mmios_va[i] = ioremap(mmios[i].start, resource_size(&mmios[i]));
+		if (!mmios_va[i]) {
+			rc = -EIO;
+			pr_err("%pfwP: unable to map MMIO regset %d\n", fwnode, i);
+			goto out_iounmap;
+		}
+	}
+
+	/* Initialize local (or per-CPU )state */
+	rc = imsic_local_init();
+	if (rc) {
+		pr_err("%pfwP: failed to initialize local state\n",
+		       fwnode);
+		goto out_iounmap;
+	}
+
+	/* Configure handlers for target CPUs */
+	for (i = 0; i < nr_parent_irqs; i++) {
+		rc = imsic_get_parent_hartid(fwnode, i, &hartid);
+		if (rc) {
+			pr_warn("%pfwP: hart ID for parent irq%d not found\n", fwnode, i);
+			continue;
+		}
+
+		cpu = riscv_hartid_to_cpuid(hartid);
+		if (cpu < 0) {
+			pr_warn("%pfwP: invalid cpuid for parent irq%d\n", fwnode, i);
+			continue;
+		}
+
+		/* Find MMIO location of MSI page */
+		index = nr_mmios;
+		reloff = i * BIT(global->guest_index_bits) *
+			 IMSIC_MMIO_PAGE_SZ;
+		for (j = 0; nr_mmios; j++) {
+			if (reloff < resource_size(&mmios[j])) {
+				index = j;
+				break;
+			}
+
+			/*
+			 * MMIO region size may not be aligned to
+			 * BIT(global->guest_index_bits) * IMSIC_MMIO_PAGE_SZ
+			 * if holes are present.
+			 */
+			reloff -= ALIGN(resource_size(&mmios[j]),
+			BIT(global->guest_index_bits) * IMSIC_MMIO_PAGE_SZ);
+		}
+		if (index >= nr_mmios) {
+			pr_warn("%pfwP: MMIO not found for parent irq%d\n", fwnode, i);
+			continue;
+		}
+
+		local = per_cpu_ptr(global->local, cpu);
+		local->msi_pa = mmios[index].start + reloff;
+		local->msi_va = mmios_va[index] + reloff;
+
+		nr_handlers++;
+	}
+
+	/* If no CPU handlers found then can't take interrupts */
+	if (!nr_handlers) {
+		pr_err("%pfwP: No CPU handlers found\n", fwnode);
+		rc = -ENODEV;
+		goto out_local_cleanup;
+	}
+
+	/* Initialize matrix allocator */
+	rc = imsic_matrix_init();
+	if (rc) {
+		pr_err("%pfwP: failed to create matrix allocator\n", fwnode);
+		goto out_local_cleanup;
+	}
+
+	/* We don't need MMIO arrays anymore so let's free-up */
+	kfree(mmios_va);
+	kfree(mmios);
+
+	return 0;
+
+out_local_cleanup:
+	imsic_local_cleanup();
+out_iounmap:
+	for (i = 0; i < nr_mmios; i++) {
+		if (mmios_va[i])
+			iounmap(mmios_va[i]);
+	}
+	kfree(mmios_va);
+	kfree(mmios);
+out_free_local:
+	free_percpu(imsic->global.local);
+out_free_priv:
+	kfree(imsic);
+	imsic = NULL;
+	return rc;
+}
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
new file mode 100644
index 000000000000..8ec9649d0d01
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#ifndef _IRQ_RISCV_IMSIC_STATE_H
+#define _IRQ_RISCV_IMSIC_STATE_H
+
+#include <linux/irqchip/riscv-imsic.h>
+#include <linux/irqdomain.h>
+#include <linux/fwnode.h>
+#include <linux/timer.h>
+
+#define IMSIC_IPI_ID				1
+#define IMSIC_NR_IPI				8
+
+struct imsic_vector {
+	/* Fixed details of the vector */
+	unsigned int				cpu;
+	unsigned int				local_id;
+	/* Details saved by driver in the vector */
+	unsigned int				hwirq;
+	/* Details accessed using local lock held */
+	bool					enable;
+	struct imsic_vector			*move;
+};
+
+struct imsic_local_priv {
+	/* Local lock to protect vector enable/move variables and dirty bitmap */
+	raw_spinlock_t				lock;
+
+	/* Local dirty bitmap for synchronization */
+	unsigned long				*dirty_bitmap;
+
+#ifdef CONFIG_SMP
+	/* Local timer for synchronization */
+	struct timer_list			timer;
+#endif
+
+	/* Local vector table */
+	struct imsic_vector			*vectors;
+};
+
+struct imsic_priv {
+	/* Device details */
+	struct fwnode_handle			*fwnode;
+
+	/* Global configuration common for all HARTs */
+	struct imsic_global_config		global;
+
+	/* Per-CPU state */
+	struct imsic_local_priv __percpu	*lpriv;
+
+	/* State of IRQ matrix allocator */
+	raw_spinlock_t				matrix_lock;
+	struct irq_matrix			*matrix;
+
+	/* IRQ domains (created by platform driver) */
+	struct irq_domain			*base_domain;
+};
+
+extern struct imsic_priv *imsic;
+
+void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val);
+
+static inline void __imsic_id_set_enable(unsigned long id)
+{
+	__imsic_eix_update(id, 1, false, true);
+}
+
+static inline void __imsic_id_clear_enable(unsigned long id)
+{
+	__imsic_eix_update(id, 1, false, false);
+}
+
+void imsic_local_sync_all(void);
+void imsic_local_delivery(bool enable);
+
+void imsic_vector_mask(struct imsic_vector *vec);
+void imsic_vector_unmask(struct imsic_vector *vec);
+
+static inline bool imsic_vector_isenabled(struct imsic_vector *vec)
+{
+	return READ_ONCE(vec->enable);
+}
+
+static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec)
+{
+	return READ_ONCE(vec->move);
+}
+
+void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec);
+
+struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id);
+
+struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask);
+void imsic_vector_free(struct imsic_vector *vector);
+
+void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind);
+void imsic_vector_debug_show_summary(struct seq_file *m, int ind);
+
+void imsic_state_online(void);
+void imsic_state_offline(void);
+int imsic_setup_state(struct fwnode_handle *fwnode);
+
+#endif
diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
new file mode 100644
index 000000000000..faf0b800b1b0
--- /dev/null
+++ b/include/linux/irqchip/riscv-imsic.h
@@ -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.
+ */
+#ifndef __LINUX_IRQCHIP_RISCV_IMSIC_H
+#define __LINUX_IRQCHIP_RISCV_IMSIC_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <asm/csr.h>
+
+#define IMSIC_MMIO_PAGE_SHIFT		12
+#define IMSIC_MMIO_PAGE_SZ		BIT(IMSIC_MMIO_PAGE_SHIFT)
+#define IMSIC_MMIO_PAGE_LE		0x00
+#define IMSIC_MMIO_PAGE_BE		0x04
+
+#define IMSIC_MIN_ID			63
+#define IMSIC_MAX_ID			2048
+
+#define IMSIC_EIDELIVERY		0x70
+
+#define IMSIC_EITHRESHOLD		0x72
+
+#define IMSIC_EIP0			0x80
+#define IMSIC_EIP63			0xbf
+#define IMSIC_EIPx_BITS			32
+
+#define IMSIC_EIE0			0xc0
+#define IMSIC_EIE63			0xff
+#define IMSIC_EIEx_BITS			32
+
+#define IMSIC_FIRST			IMSIC_EIDELIVERY
+#define IMSIC_LAST			IMSIC_EIE63
+
+#define IMSIC_MMIO_SETIPNUM_LE		0x00
+#define IMSIC_MMIO_SETIPNUM_BE		0x04
+
+struct imsic_local_config {
+	phys_addr_t				msi_pa;
+	void __iomem				*msi_va;
+};
+
+struct imsic_global_config {
+	/*
+	 * MSI Target Address Scheme
+	 *
+	 * XLEN-1                                                12     0
+	 * |                                                     |     |
+	 * -------------------------------------------------------------
+	 * |xxxxxx|Group Index|xxxxxxxxxxx|HART Index|Guest Index|  0  |
+	 * -------------------------------------------------------------
+	 */
+
+	/* Bits representing Guest index, HART index, and Group index */
+	u32					guest_index_bits;
+	u32					hart_index_bits;
+	u32					group_index_bits;
+	u32					group_index_shift;
+
+	/* Global base address matching all target MSI addresses */
+	phys_addr_t				base_addr;
+
+	/* Number of interrupt identities */
+	u32					nr_ids;
+
+	/* Number of guest interrupt identities */
+	u32					nr_guest_ids;
+
+	/* Per-CPU IMSIC addresses */
+	struct imsic_local_config __percpu	*local;
+};
+
+#ifdef CONFIG_RISCV_IMSIC
+
+const struct imsic_global_config *imsic_get_global_config(void);
+
+#else
+
+static inline const struct imsic_global_config *imsic_get_global_config(void)
+{
+	return NULL;
+}
+
+#endif
+
+#endif
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:40:00 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:10:00 +0530
Subject: [PATCH v14 12/18] irqchip/riscv-imsic: Add device MSI domain support for platform devices
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-13-apatel@ventanamicro.com>

The Linux platform MSI support allows per-device MSI domains so add
a platform irqchip driver for RISC-V IMSIC which provides a base IRQ
domain with MSI parent support for platform device domains.

The IMSIC platform driver assumes that the IMSIC state is already
initialized by the IMSIC early driver.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Makefile                   |   2 +-
 drivers/irqchip/irq-riscv-imsic-platform.c | 344 +++++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.h    |   1 +
 3 files changed, 346 insertions(+), 1 deletion(-)
 create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index d714724387ce..abca445a3229 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -95,7 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
 obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
-obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o
+obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
 obj-$(CONFIG_IMX_INTMUX)		+= irq-imx-intmux.o
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
new file mode 100644
index 000000000000..e2344fc08dca
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "riscv-imsic: " fmt
+#include <linux/bitmap.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-imsic-state.h"
+
+static bool imsic_cpu_page_phys(unsigned int cpu, unsigned int guest_index,
+				phys_addr_t *out_msi_pa)
+{
+	struct imsic_global_config *global;
+	struct imsic_local_config *local;
+
+	global = &imsic->global;
+	local = per_cpu_ptr(global->local, cpu);
+
+	if (BIT(global->guest_index_bits) <= guest_index)
+		return false;
+
+	if (out_msi_pa)
+		*out_msi_pa = local->msi_pa +
+			      (guest_index * IMSIC_MMIO_PAGE_SZ);
+
+	return true;
+}
+
+static void imsic_irq_mask(struct irq_data *d)
+{
+	imsic_vector_mask(irq_data_get_irq_chip_data(d));
+}
+
+static void imsic_irq_unmask(struct irq_data *d)
+{
+	imsic_vector_unmask(irq_data_get_irq_chip_data(d));
+}
+
+static int imsic_irq_retrigger(struct irq_data *d)
+{
+	struct imsic_vector *vec = irq_data_get_irq_chip_data(d);
+	struct imsic_local_config *local;
+
+	if (WARN_ON(!vec))
+		return -ENOENT;
+
+	local = per_cpu_ptr(imsic->global.local, vec->cpu);
+	writel_relaxed(vec->local_id, local->msi_va);
+	return 0;
+}
+
+static void imsic_irq_compose_vector_msg(struct imsic_vector *vec, struct msi_msg *msg)
+{
+	phys_addr_t msi_addr;
+
+	if (WARN_ON(!vec))
+		return;
+
+	if (WARN_ON(!imsic_cpu_page_phys(vec->cpu, 0, &msi_addr)))
+		return;
+
+	msg->address_hi = upper_32_bits(msi_addr);
+	msg->address_lo = lower_32_bits(msi_addr);
+	msg->data = vec->local_id;
+}
+
+static void imsic_irq_compose_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	imsic_irq_compose_vector_msg(irq_data_get_irq_chip_data(d), msg);
+}
+
+#ifdef CONFIG_SMP
+static void imsic_msi_update_msg(struct irq_data *d, struct imsic_vector *vec)
+{
+	struct msi_msg msg = { };
+
+	imsic_irq_compose_vector_msg(vec, &msg);
+	irq_data_get_irq_chip(d)->irq_write_msi_msg(d, &msg);
+}
+
+static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+				  bool force)
+{
+	struct imsic_vector *old_vec, *new_vec;
+	struct irq_data *pd = d->parent_data;
+
+	old_vec = irq_data_get_irq_chip_data(pd);
+	if (WARN_ON(!old_vec))
+		return -ENOENT;
+
+	/* If old vector cpu belongs to the target cpumask then do nothing */
+	if (cpumask_test_cpu(old_vec->cpu, mask_val))
+		return IRQ_SET_MASK_OK_DONE;
+
+	/* If move is already in-flight then return failure */
+	if (imsic_vector_get_move(old_vec))
+		return -EBUSY;
+
+	/* Get a new vector on the desired set of CPUs */
+	new_vec = imsic_vector_alloc(old_vec->hwirq, mask_val);
+	if (!new_vec)
+		return -ENOSPC;
+
+	/* Point device to the new vector */
+	imsic_msi_update_msg(d, new_vec);
+
+	/* Update irq descriptors with the new vector */
+	pd->chip_data = new_vec;
+
+	/* Update effective affinity of parent irq data */
+	irq_data_update_effective_affinity(pd, cpumask_of(new_vec->cpu));
+
+	/* Move state of the old vector to the new vector */
+	imsic_vector_move(old_vec, new_vec);
+
+	return IRQ_SET_MASK_OK_DONE;
+}
+#endif
+
+static struct irq_chip imsic_irq_base_chip = {
+	.name			= "IMSIC",
+	.irq_mask		= imsic_irq_mask,
+	.irq_unmask		= imsic_irq_unmask,
+	.irq_retrigger		= imsic_irq_retrigger,
+	.irq_compose_msi_msg	= imsic_irq_compose_msg,
+	.flags			= IRQCHIP_SKIP_SET_WAKE |
+				  IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				  unsigned int nr_irqs, void *args)
+{
+	struct imsic_vector *vec;
+
+	/* Multi-MSI is not supported yet. */
+	if (nr_irqs > 1)
+		return -EOPNOTSUPP;
+
+	vec = imsic_vector_alloc(virq, cpu_online_mask);
+	if (!vec)
+		return -ENOSPC;
+
+	irq_domain_set_info(domain, virq, virq, &imsic_irq_base_chip, vec,
+			    handle_simple_irq, NULL, NULL);
+	irq_set_noprobe(virq);
+	irq_set_affinity(virq, cpu_online_mask);
+
+	return 0;
+}
+
+static void imsic_irq_domain_free(struct irq_domain *domain, unsigned int virq,
+				  unsigned int nr_irqs)
+{
+	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+
+	imsic_vector_free(irq_data_get_irq_chip_data(d));
+	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+}
+
+static int imsic_irq_domain_select(struct irq_domain *domain, struct irq_fwspec *fwspec,
+				   enum irq_domain_bus_token bus_token)
+{
+	const struct msi_parent_ops *ops = domain->msi_parent_ops;
+	u32 busmask = BIT(bus_token);
+
+	if (fwspec->fwnode != domain->fwnode || fwspec->param_count != 0)
+		return 0;
+
+	/* Handle pure domain searches */
+	if (bus_token == ops->bus_select_token)
+		return 1;
+
+	return !!(ops->bus_select_mask & busmask);
+}
+
+#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
+static void imsic_irq_debug_show(struct seq_file *m, struct irq_domain *d,
+				 struct irq_data *irqd, int ind)
+{
+	if (!irqd) {
+		imsic_vector_debug_show_summary(m, ind);
+		return;
+	}
+
+	imsic_vector_debug_show(m, irq_data_get_irq_chip_data(irqd), ind);
+}
+#endif
+
+static const struct irq_domain_ops imsic_base_domain_ops = {
+	.alloc		= imsic_irq_domain_alloc,
+	.free		= imsic_irq_domain_free,
+	.select		= imsic_irq_domain_select,
+#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
+	.debug_show	= imsic_irq_debug_show,
+#endif
+};
+
+static bool imsic_init_dev_msi_info(struct device *dev,
+				    struct irq_domain *domain,
+				    struct irq_domain *real_parent,
+				    struct msi_domain_info *info)
+{
+	const struct msi_parent_ops *pops = real_parent->msi_parent_ops;
+
+	/* MSI parent domain specific settings */
+	switch (real_parent->bus_token) {
+	case DOMAIN_BUS_NEXUS:
+		if (WARN_ON_ONCE(domain != real_parent))
+			return false;
+#ifdef CONFIG_SMP
+		info->chip->irq_set_affinity = imsic_irq_set_affinity;
+#endif
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return false;
+	}
+
+	/* Is the target supported? */
+	switch (info->bus_token) {
+	case DOMAIN_BUS_DEVICE_MSI:
+		/*
+		 * Per-device MSI should never have any MSI feature bits
+		 * set. It's sole purpose is to create a dumb interrupt
+		 * chip which has a device specific irq_write_msi_msg()
+		 * callback.
+		 */
+		if (WARN_ON_ONCE(info->flags))
+			return false;
+
+		/* Core managed MSI descriptors */
+		info->flags |= MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS |
+			       MSI_FLAG_FREE_MSI_DESCS;
+		break;
+	case DOMAIN_BUS_WIRED_TO_MSI:
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return false;
+	}
+
+	/* Use hierarchial chip operations re-trigger */
+	info->chip->irq_retrigger = irq_chip_retrigger_hierarchy;
+
+	/*
+	 * Mask out the domain specific MSI feature flags which are not
+	 * supported by the real parent.
+	 */
+	info->flags &= pops->supported_flags;
+
+	/* Enforce the required flags */
+	info->flags |= pops->required_flags;
+
+	return true;
+}
+
+#define MATCH_PLATFORM_MSI		BIT(DOMAIN_BUS_PLATFORM_MSI)
+
+static const struct msi_parent_ops imsic_msi_parent_ops = {
+	.supported_flags	= MSI_GENERIC_FLAGS_MASK,
+	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
+				  MSI_FLAG_USE_DEF_CHIP_OPS,
+	.bus_select_token	= DOMAIN_BUS_NEXUS,
+	.bus_select_mask	= MATCH_PLATFORM_MSI,
+	.init_dev_msi_info	= imsic_init_dev_msi_info,
+};
+
+int imsic_irqdomain_init(void)
+{
+	struct imsic_global_config *global;
+
+	if (!imsic || !imsic->fwnode) {
+		pr_err("early driver not probed\n");
+		return -ENODEV;
+	}
+
+	if (imsic->base_domain) {
+		pr_err("%pfwP: irq domain already created\n", imsic->fwnode);
+		return -ENODEV;
+	}
+
+	/* Create Base IRQ domain */
+	imsic->base_domain = irq_domain_create_tree(imsic->fwnode,
+						    &imsic_base_domain_ops, imsic);
+	if (!imsic->base_domain) {
+		pr_err("%pfwP: failed to create IMSIC base domain\n", imsic->fwnode);
+		return -ENOMEM;
+	}
+	imsic->base_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
+	imsic->base_domain->msi_parent_ops = &imsic_msi_parent_ops;
+
+	irq_domain_update_bus_token(imsic->base_domain, DOMAIN_BUS_NEXUS);
+
+	global = &imsic->global;
+	pr_info("%pfwP:  hart-index-bits: %d,  guest-index-bits: %d\n",
+		imsic->fwnode, global->hart_index_bits, global->guest_index_bits);
+	pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n",
+		imsic->fwnode, global->group_index_bits, global->group_index_shift);
+	pr_info("%pfwP: per-CPU IDs %d at base PPN %pa\n",
+		imsic->fwnode, global->nr_ids, &global->base_addr);
+	pr_info("%pfwP: total %d interrupts available\n",
+		imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1));
+
+	return 0;
+}
+
+static int imsic_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	if (imsic && imsic->fwnode != dev->fwnode) {
+		dev_err(dev, "fwnode mismatch\n");
+		return -ENODEV;
+	}
+
+	return imsic_irqdomain_init();
+}
+
+static const struct of_device_id imsic_platform_match[] = {
+	{ .compatible = "riscv,imsics" },
+	{}
+};
+
+static struct platform_driver imsic_platform_driver = {
+	.driver = {
+		.name		= "riscv-imsic",
+		.of_match_table	= imsic_platform_match,
+	},
+	.probe = imsic_platform_probe,
+};
+builtin_platform_driver(imsic_platform_driver);
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 8ec9649d0d01..5ae2f69b035b 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -103,5 +103,6 @@ void imsic_vector_debug_show_summary(struct seq_file *m, int ind);
 void imsic_state_online(void);
 void imsic_state_offline(void);
 int imsic_setup_state(struct fwnode_handle *fwnode);
+int imsic_irqdomain_init(void);
 
 #endif
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:40:01 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:10:01 +0530
Subject: [PATCH v14 13/18] irqchip/riscv-imsic: Add device MSI domain support for PCI devices
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-14-apatel@ventanamicro.com>

The Linux PCI framework supports per-device MSI domains for PCI devices
so extend the IMSIC driver to allow PCI per-device MSI domains.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                    |  7 +++++
 drivers/irqchip/irq-riscv-imsic-platform.c | 35 ++++++++++++++++++++--
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 85f86e31c996..2fc0cb32341a 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -553,6 +553,13 @@ config RISCV_IMSIC
 	select GENERIC_IRQ_MATRIX_ALLOCATOR
 	select GENERIC_MSI_IRQ
 
+config RISCV_IMSIC_PCI
+	bool
+	depends on RISCV_IMSIC
+	depends on PCI
+	depends on PCI_MSI
+	default RISCV_IMSIC
+
 config EXYNOS_IRQ_COMBINER
 	bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
 	depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index e2344fc08dca..90ddcdd0bba5 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -14,6 +14,7 @@
 #include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/msi.h>
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/smp.h>
@@ -208,6 +209,28 @@ static const struct irq_domain_ops imsic_base_domain_ops = {
 #endif
 };
 
+#ifdef CONFIG_RISCV_IMSIC_PCI
+
+static void imsic_pci_mask_irq(struct irq_data *d)
+{
+	pci_msi_mask_irq(d);
+	irq_chip_mask_parent(d);
+}
+
+static void imsic_pci_unmask_irq(struct irq_data *d)
+{
+	irq_chip_unmask_parent(d);
+	pci_msi_unmask_irq(d);
+}
+
+#define MATCH_PCI_MSI		BIT(DOMAIN_BUS_PCI_MSI)
+
+#else
+
+#define MATCH_PCI_MSI		0
+
+#endif
+
 static bool imsic_init_dev_msi_info(struct device *dev,
 				    struct irq_domain *domain,
 				    struct irq_domain *real_parent,
@@ -231,6 +254,13 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 
 	/* Is the target supported? */
 	switch (info->bus_token) {
+#ifdef CONFIG_RISCV_IMSIC_PCI
+	case DOMAIN_BUS_PCI_DEVICE_MSI:
+	case DOMAIN_BUS_PCI_DEVICE_MSIX:
+		info->chip->irq_mask = imsic_pci_mask_irq;
+		info->chip->irq_unmask = imsic_pci_unmask_irq;
+		break;
+#endif
 	case DOMAIN_BUS_DEVICE_MSI:
 		/*
 		 * Per-device MSI should never have any MSI feature bits
@@ -270,11 +300,12 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 #define MATCH_PLATFORM_MSI		BIT(DOMAIN_BUS_PLATFORM_MSI)
 
 static const struct msi_parent_ops imsic_msi_parent_ops = {
-	.supported_flags	= MSI_GENERIC_FLAGS_MASK,
+	.supported_flags	= MSI_GENERIC_FLAGS_MASK |
+				  MSI_FLAG_PCI_MSIX,
 	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
 				  MSI_FLAG_USE_DEF_CHIP_OPS,
 	.bus_select_token	= DOMAIN_BUS_NEXUS,
-	.bus_select_mask	= MATCH_PLATFORM_MSI,
+	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
 	.init_dev_msi_info	= imsic_init_dev_msi_info,
 };
 
-- 
2.34.1



From sudeep.holla at arm.com  Thu Feb 22 01:41:53 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 22 Feb 2024 09:41:53 +0000
Subject: [PATCH V4 2/2] clk: scmi: support state_ctrl_forbidden
In-Reply-To: <20240121110901.1414856-2-peng.fan@oss.nxp.com>
References: <20240121110901.1414856-1-peng.fan@oss.nxp.com>
 <20240121110901.1414856-2-peng.fan@oss.nxp.com>
Message-ID: <20240222094153.2nxvefa44y5ikutm@bogus>

On Sun, Jan 21, 2024 at 07:09:01PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Some clocks may exported to linux, while those clocks are not allowed
> to configure by Linux. For example:
> 
> SYS_CLK1-----
>              \
> 	     --MUX--->MMC1_CLK
>              /
> SYS_CLK2-----
> 
> MMC1 needs set parent, so SYS_CLK1 and SYS_CLK2 are exported to Linux,
> then the clk propagation will touch SYS_CLK1 or SYS_CLK2.
> So we need bypass the failure for SYS_CLK1 or SYS_CLK2 when enable
> the clock of MMC1, adding scmi_no_state_ctrl_clk_ops to use software
> enable counter, while not calling scmi api.
> 
> Co-developed-by: Cristian Marussi <cristian.marussi at arm.com>
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
> 
> V4:
>  Add scmi_no_state_ctrl_clk_ops per Cristian
>  Add Cristian's tag
> 
> V3:
>  Add check in atomic enable
> 
> V2:
>  New. Take Cristian's suggestion
> 
>  drivers/clk/clk-scmi.c | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
> index 8cbe24789c24..5747b6d651f0 100644
> --- a/drivers/clk/clk-scmi.c
> +++ b/drivers/clk/clk-scmi.c
> @@ -194,6 +194,15 @@ static const struct clk_ops scmi_atomic_clk_ops = {
>  	.determine_rate = scmi_clk_determine_rate,
>  };
>  
> +static const struct clk_ops scmi_no_state_ctrl_clk_ops = {
> +	.recalc_rate = scmi_clk_recalc_rate,
> +	.round_rate = scmi_clk_round_rate,
> +	.set_rate = scmi_clk_set_rate,
> +	.set_parent = scmi_clk_set_parent,
> +	.get_parent = scmi_clk_get_parent,
> +	.determine_rate = scmi_clk_determine_rate,
> +};
> +
>  static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
>  			     const struct clk_ops *scmi_ops)
>  {
> @@ -290,8 +299,10 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
>  		 * 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)
> +		if (sclk->info->state_ctrl_forbidden)
> +			scmi_ops = &scmi_no_state_ctrl_clk_ops;

With this, even if is_atomic and latency matches, we won't allow
atomic operations ? One reason why it gets tricky and as Cristian 
mentioned elsewhere we need dynamic assignment of these ops IMO.
Let me know if I am getting things wrong here ?

-- 
Regards,
Sudeep


From apatel at ventanamicro.com  Thu Feb 22 01:40:02 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:10:02 +0530
Subject: [PATCH v14 14/18] dt-bindings: interrupt-controller: Add RISC-V advanced PLIC
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-15-apatel@ventanamicro.com>

Add DT bindings document for RISC-V advanced platform level interrupt
controller (APLIC) defined by the RISC-V advanced interrupt architecture
(AIA) specification.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 .../interrupt-controller/riscv,aplic.yaml     | 172 ++++++++++++++++++
 1 file changed, 172 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml b/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
new file mode 100644
index 000000000000..190a6499c932
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
@@ -0,0 +1,172 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/riscv,aplic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Advanced Platform Level Interrupt Controller (APLIC)
+
+maintainers:
+  - Anup Patel <anup at brainfault.org>
+
+description:
+  The RISC-V advanced interrupt architecture (AIA) defines an advanced
+  platform level interrupt controller (APLIC) for handling wired interrupts
+  in a RISC-V platform. The RISC-V AIA specification can be found at
+  https://github.com/riscv/riscv-aia.
+
+  The RISC-V APLIC is implemented as hierarchical APLIC domains where all
+  interrupt sources connect to the root APLIC domain and a parent APLIC
+  domain can delegate interrupt sources to it's child APLIC domains. There
+  is one device tree node for each APLIC domain.
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - qemu,aplic
+      - const: riscv,aplic
+
+  reg:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+  interrupts-extended:
+    minItems: 1
+    maxItems: 16384
+    description:
+      Given APLIC domain directly injects external interrupts to a set of
+      RISC-V HARTS (or CPUs). Each node pointed to should be a riscv,cpu-intc
+      node, which has a CPU node (i.e. RISC-V HART) as parent.
+
+  msi-parent:
+    description:
+      Given APLIC domain forwards wired interrupts as MSIs to a AIA incoming
+      message signaled interrupt controller (IMSIC). If both "msi-parent" and
+      "interrupts-extended" properties are present then it means the APLIC
+      domain supports both MSI mode and Direct mode in HW. In this case, the
+      APLIC driver has to choose between MSI mode or Direct mode.
+
+  riscv,num-sources:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 1023
+    description:
+      Specifies the number of wired interrupt sources supported by this
+      APLIC domain.
+
+  riscv,children:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 1024
+    items:
+      maxItems: 1
+    description:
+      A list of child APLIC domains for the given APLIC domain. Each child
+      APLIC domain is assigned a child index in increasing order, with the
+      first child APLIC domain assigned child index 0. The APLIC domain child
+      index is used by firmware to delegate interrupts from the given APLIC
+      domain to a particular child APLIC domain.
+
+  riscv,delegation:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 1024
+    items:
+      items:
+        - description: child APLIC domain phandle
+        - description: first interrupt number of the parent APLIC domain (inclusive)
+        - description: last interrupt number of the parent APLIC domain (inclusive)
+    description:
+      A interrupt delegation list where each entry is a triple consisting
+      of child APLIC domain phandle, first interrupt number of the parent
+      APLIC domain, and last interrupt number of the parent APLIC domain.
+      Firmware must configure interrupt delegation registers based on
+      interrupt delegation list.
+
+dependencies:
+  riscv,delegation: [ "riscv,children" ]
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - "#interrupt-cells"
+  - riscv,num-sources
+
+anyOf:
+  - required:
+      - interrupts-extended
+  - required:
+      - msi-parent
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    // Example 1 (APLIC domains directly injecting interrupt to HARTs):
+
+    interrupt-controller at c000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      interrupts-extended = <&cpu1_intc 11>,
+                            <&cpu2_intc 11>,
+                            <&cpu3_intc 11>,
+                            <&cpu4_intc 11>;
+      reg = <0xc000000 0x4080>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+      riscv,children = <&aplic1>, <&aplic2>;
+      riscv,delegation = <&aplic1 1 63>;
+    };
+
+    aplic1: interrupt-controller at d000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      interrupts-extended = <&cpu1_intc 9>,
+                            <&cpu2_intc 9>;
+      reg = <0xd000000 0x4080>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+    };
+
+    aplic2: interrupt-controller at e000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      interrupts-extended = <&cpu3_intc 9>,
+                            <&cpu4_intc 9>;
+      reg = <0xe000000 0x4080>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+    };
+
+  - |
+    // Example 2 (APLIC domains forwarding interrupts as MSIs):
+
+    interrupt-controller at c000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      msi-parent = <&imsic_mlevel>;
+      reg = <0xc000000 0x4000>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+      riscv,children = <&aplic3>;
+      riscv,delegation = <&aplic3 1 63>;
+    };
+
+    aplic3: interrupt-controller at d000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      msi-parent = <&imsic_slevel>;
+      reg = <0xd000000 0x4000>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+    };
+...
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:40:03 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:10:03 +0530
Subject: [PATCH v14 15/18] irqchip: Add RISC-V advanced PLIC driver for direct-mode
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-16-apatel@ventanamicro.com>

The RISC-V advanced interrupt architecture (AIA) specification defines
advanced platform-level interrupt controller (APLIC) which has two modes
of operation: 1) Direct mode and 2) MSI mode.
(For more details, refer https://github.com/riscv/riscv-aia)

In APLIC direct-mode, wired interrupts are forwared to CPUs (or HARTs)
as a local external interrupt.

Add a platform irqchip driver for the RISC-V APLIC direct-mode to
support RISC-V platforms having only wired interrupts.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                  |   5 +
 drivers/irqchip/Makefile                 |   1 +
 drivers/irqchip/irq-riscv-aplic-direct.c | 326 +++++++++++++++++++++++
 drivers/irqchip/irq-riscv-aplic-main.c   | 211 +++++++++++++++
 drivers/irqchip/irq-riscv-aplic-main.h   |  44 +++
 include/linux/irqchip/riscv-aplic.h      | 145 ++++++++++
 6 files changed, 732 insertions(+)
 create mode 100644 drivers/irqchip/irq-riscv-aplic-direct.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.h
 create mode 100644 include/linux/irqchip/riscv-aplic.h

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 2fc0cb32341a..dbc8811d3764 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -546,6 +546,11 @@ config SIFIVE_PLIC
 	select IRQ_DOMAIN_HIERARCHY
 	select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
 
+config RISCV_APLIC
+	bool
+	depends on RISCV
+	select IRQ_DOMAIN_HIERARCHY
+
 config RISCV_IMSIC
 	bool
 	depends on RISCV
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index abca445a3229..7f8289790ed8 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
 obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
+obj-$(CONFIG_RISCV_APLIC)		+= irq-riscv-aplic-main.o irq-riscv-aplic-direct.o
 obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
diff --git a/drivers/irqchip/irq-riscv-aplic-direct.c b/drivers/irqchip/irq-riscv-aplic-direct.c
new file mode 100644
index 000000000000..06bace9b7497
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-direct.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/riscv-aplic.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/printk.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-aplic-main.h"
+
+#define APLIC_DISABLE_IDELIVERY		0
+#define APLIC_ENABLE_IDELIVERY		1
+#define APLIC_DISABLE_ITHRESHOLD	1
+#define APLIC_ENABLE_ITHRESHOLD		0
+
+struct aplic_direct {
+	struct aplic_priv	priv;
+	struct irq_domain	*irqdomain;
+	struct cpumask		lmask;
+};
+
+struct aplic_idc {
+	unsigned int		hart_index;
+	void __iomem		*regs;
+	struct aplic_direct	*direct;
+};
+
+static unsigned int aplic_direct_parent_irq;
+static DEFINE_PER_CPU(struct aplic_idc, aplic_idcs);
+
+static void aplic_direct_irq_eoi(struct irq_data *d)
+{
+	/*
+	 * The fasteoi_handler requires irq_eoi() callback hence
+	 * provide a dummy handler.
+	 */
+}
+
+#ifdef CONFIG_SMP
+static int aplic_direct_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+				     bool force)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	struct aplic_direct *direct = container_of(priv, struct aplic_direct, priv);
+	struct aplic_idc *idc;
+	unsigned int cpu, val;
+	struct cpumask amask;
+	void __iomem *target;
+
+	cpumask_and(&amask, &direct->lmask, mask_val);
+
+	if (force)
+		cpu = cpumask_first(&amask);
+	else
+		cpu = cpumask_any_and(&amask, cpu_online_mask);
+
+	if (cpu >= nr_cpu_ids)
+		return -EINVAL;
+
+	idc = per_cpu_ptr(&aplic_idcs, cpu);
+	target = priv->regs + APLIC_TARGET_BASE + (d->hwirq - 1) * sizeof(u32);
+	val = FIELD_PREP(APLIC_TARGET_HART_IDX, idc->hart_index);
+	val |= FIELD_PREP(APLIC_TARGET_IPRIO, APLIC_DEFAULT_PRIORITY);
+	writel(val, target);
+
+	irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
+	return IRQ_SET_MASK_OK_DONE;
+}
+#endif
+
+static struct irq_chip aplic_direct_chip = {
+	.name		= "APLIC-DIRECT",
+	.irq_mask	= aplic_irq_mask,
+	.irq_unmask	= aplic_irq_unmask,
+	.irq_set_type	= aplic_irq_set_type,
+	.irq_eoi	= aplic_direct_irq_eoi,
+#ifdef CONFIG_SMP
+	.irq_set_affinity = aplic_direct_set_affinity,
+#endif
+	.flags		= IRQCHIP_SET_TYPE_MASKED |
+			  IRQCHIP_SKIP_SET_WAKE |
+			  IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static int aplic_direct_irqdomain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
+					    unsigned long *hwirq, unsigned int *type)
+{
+	struct aplic_priv *priv = d->host_data;
+
+	return aplic_irqdomain_translate(fwspec, priv->gsi_base, hwirq, type);
+}
+
+static int aplic_direct_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
+					unsigned int nr_irqs, void *arg)
+{
+	struct aplic_priv *priv = domain->host_data;
+	struct aplic_direct *direct = container_of(priv, struct aplic_direct, priv);
+	struct irq_fwspec *fwspec = arg;
+	irq_hw_number_t hwirq;
+	unsigned int type;
+	int i, ret;
+
+	ret = aplic_irqdomain_translate(fwspec, priv->gsi_base, &hwirq, &type);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nr_irqs; i++) {
+		irq_domain_set_info(domain, virq + i, hwirq + i, &aplic_direct_chip,
+				    priv, handle_fasteoi_irq, NULL, NULL);
+		irq_set_affinity(virq + i, &direct->lmask);
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops aplic_direct_irqdomain_ops = {
+	.translate	= aplic_direct_irqdomain_translate,
+	.alloc		= aplic_direct_irqdomain_alloc,
+	.free		= irq_domain_free_irqs_top,
+};
+
+/*
+ * To handle an APLIC direct interrupts, we just read the CLAIMI register
+ * which will return highest priority pending interrupt and clear the
+ * pending bit of the interrupt. This process is repeated until CLAIMI
+ * register return zero value.
+ */
+static void aplic_direct_handle_irq(struct irq_desc *desc)
+{
+	struct aplic_idc *idc = this_cpu_ptr(&aplic_idcs);
+	struct irq_domain *irqdomain = idc->direct->irqdomain;
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	irq_hw_number_t hw_irq;
+	int irq;
+
+	chained_irq_enter(chip, desc);
+
+	while ((hw_irq = readl(idc->regs + APLIC_IDC_CLAIMI))) {
+		hw_irq = hw_irq >> APLIC_IDC_TOPI_ID_SHIFT;
+		irq = irq_find_mapping(irqdomain, hw_irq);
+
+		if (unlikely(irq <= 0)) {
+			dev_warn_ratelimited(idc->direct->priv.dev,
+					     "hw_irq %lu mapping not found\n", hw_irq);
+		} else {
+			generic_handle_irq(irq);
+		}
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static void aplic_idc_set_delivery(struct aplic_idc *idc, bool en)
+{
+	u32 de = (en) ? APLIC_ENABLE_IDELIVERY : APLIC_DISABLE_IDELIVERY;
+	u32 th = (en) ? APLIC_ENABLE_ITHRESHOLD : APLIC_DISABLE_ITHRESHOLD;
+
+	/* Priority must be less than threshold for interrupt triggering */
+	writel(th, idc->regs + APLIC_IDC_ITHRESHOLD);
+
+	/* Delivery must be set to 1 for interrupt triggering */
+	writel(de, idc->regs + APLIC_IDC_IDELIVERY);
+}
+
+static int aplic_direct_dying_cpu(unsigned int cpu)
+{
+	if (aplic_direct_parent_irq)
+		disable_percpu_irq(aplic_direct_parent_irq);
+
+	return 0;
+}
+
+static int aplic_direct_starting_cpu(unsigned int cpu)
+{
+	if (aplic_direct_parent_irq) {
+		enable_percpu_irq(aplic_direct_parent_irq,
+				  irq_get_trigger_type(aplic_direct_parent_irq));
+	}
+
+	return 0;
+}
+
+static int aplic_direct_parse_parent_hwirq(struct device *dev, u32 index,
+					   u32 *parent_hwirq, unsigned long *parent_hartid)
+{
+	struct of_phandle_args parent;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	rc = of_irq_parse_one(to_of_node(dev->fwnode), index, &parent);
+	if (rc)
+		return rc;
+
+	rc = riscv_of_parent_hartid(parent.np, parent_hartid);
+	if (rc)
+		return rc;
+
+	*parent_hwirq = parent.args[0];
+	return 0;
+}
+
+int aplic_direct_setup(struct device *dev, void __iomem *regs)
+{
+	int i, j, rc, cpu, current_cpu, setup_count = 0;
+	struct aplic_direct *direct;
+	struct irq_domain *domain;
+	struct aplic_priv *priv;
+	struct aplic_idc *idc;
+	unsigned long hartid;
+	u32 v, hwirq;
+
+	direct = devm_kzalloc(dev, sizeof(*direct), GFP_KERNEL);
+	if (!direct)
+		return -ENOMEM;
+	priv = &direct->priv;
+
+	rc = aplic_setup_priv(priv, dev, regs);
+	if (rc) {
+		dev_err(dev, "failed to create APLIC context\n");
+		return rc;
+	}
+
+	/* Setup per-CPU IDC and target CPU mask */
+	current_cpu = get_cpu();
+	for (i = 0; i < priv->nr_idcs; i++) {
+		rc = aplic_direct_parse_parent_hwirq(dev, i, &hwirq, &hartid);
+		if (rc) {
+			dev_warn(dev, "parent irq for IDC%d not found\n", i);
+			continue;
+		}
+
+		/*
+		 * Skip interrupts other than external interrupts for
+		 * current privilege level.
+		 */
+		if (hwirq != RV_IRQ_EXT)
+			continue;
+
+		cpu = riscv_hartid_to_cpuid(hartid);
+		if (cpu < 0) {
+			dev_warn(dev, "invalid cpuid for IDC%d\n", i);
+			continue;
+		}
+
+		cpumask_set_cpu(cpu, &direct->lmask);
+
+		idc = per_cpu_ptr(&aplic_idcs, cpu);
+		idc->hart_index = i;
+		idc->regs = priv->regs + APLIC_IDC_BASE + i * APLIC_IDC_SIZE;
+		idc->direct = direct;
+
+		aplic_idc_set_delivery(idc, true);
+
+		/*
+		 * Boot cpu might not have APLIC hart_index = 0 so check
+		 * and update target registers of all interrupts.
+		 */
+		if (cpu == current_cpu && idc->hart_index) {
+			v = FIELD_PREP(APLIC_TARGET_HART_IDX, idc->hart_index);
+			v |= FIELD_PREP(APLIC_TARGET_IPRIO, APLIC_DEFAULT_PRIORITY);
+			for (j = 1; j <= priv->nr_irqs; j++)
+				writel(v, priv->regs + APLIC_TARGET_BASE + (j - 1) * sizeof(u32));
+		}
+
+		setup_count++;
+	}
+	put_cpu();
+
+	/* Find parent domain and register chained handler */
+	domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(),
+					  DOMAIN_BUS_ANY);
+	if (!aplic_direct_parent_irq && domain) {
+		aplic_direct_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
+		if (aplic_direct_parent_irq) {
+			irq_set_chained_handler(aplic_direct_parent_irq,
+						aplic_direct_handle_irq);
+
+			/*
+			 * Setup CPUHP notifier to enable parent
+			 * interrupt on all CPUs
+			 */
+			cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
+					  "irqchip/riscv/aplic:starting",
+					  aplic_direct_starting_cpu,
+					  aplic_direct_dying_cpu);
+		}
+	}
+
+	/* Fail if we were not able to setup IDC for any CPU */
+	if (!setup_count)
+		return -ENODEV;
+
+	/* Setup global config and interrupt delivery */
+	aplic_init_hw_global(priv, false);
+
+	/* Create irq domain instance for the APLIC */
+	direct->irqdomain = irq_domain_create_linear(dev->fwnode, priv->nr_irqs + 1,
+						     &aplic_direct_irqdomain_ops, priv);
+	if (!direct->irqdomain) {
+		dev_err(dev, "failed to create direct irq domain\n");
+		return -ENOMEM;
+	}
+
+	/* Advertise the interrupt controller */
+	dev_info(dev, "%d interrupts directly connected to %d CPUs\n",
+		 priv->nr_irqs, priv->nr_idcs);
+
+	return 0;
+}
diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
new file mode 100644
index 000000000000..160ff99d6979
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/irqchip/riscv-aplic.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+
+#include "irq-riscv-aplic-main.h"
+
+void aplic_irq_unmask(struct irq_data *d)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+
+	writel(d->hwirq, priv->regs + APLIC_SETIENUM);
+}
+
+void aplic_irq_mask(struct irq_data *d)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+
+	writel(d->hwirq, priv->regs + APLIC_CLRIENUM);
+}
+
+int aplic_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	void __iomem *sourcecfg;
+	u32 val = 0;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		val = APLIC_SOURCECFG_SM_INACTIVE;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		val = APLIC_SOURCECFG_SM_LEVEL_LOW;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		val = APLIC_SOURCECFG_SM_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		val = APLIC_SOURCECFG_SM_EDGE_FALL;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		val = APLIC_SOURCECFG_SM_EDGE_RISE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sourcecfg = priv->regs + APLIC_SOURCECFG_BASE;
+	sourcecfg += (d->hwirq - 1) * sizeof(u32);
+	writel(val, sourcecfg);
+
+	return 0;
+}
+
+int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
+			      unsigned long *hwirq, unsigned int *type)
+{
+	if (WARN_ON(fwspec->param_count < 2))
+		return -EINVAL;
+	if (WARN_ON(!fwspec->param[0]))
+		return -EINVAL;
+
+	/* For DT, gsi_base is always zero. */
+	*hwirq = fwspec->param[0] - gsi_base;
+	*type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
+
+	WARN_ON(*type == IRQ_TYPE_NONE);
+
+	return 0;
+}
+
+void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
+{
+	u32 val;
+#ifdef CONFIG_RISCV_M_MODE
+	u32 valh;
+
+	if (msi_mode) {
+		val = lower_32_bits(priv->msicfg.base_ppn);
+		valh = FIELD_PREP(APLIC_xMSICFGADDRH_BAPPN, upper_32_bits(priv->msicfg.base_ppn));
+		valh |= FIELD_PREP(APLIC_xMSICFGADDRH_LHXW, priv->msicfg.lhxw);
+		valh |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXW, priv->msicfg.hhxw);
+		valh |= FIELD_PREP(APLIC_xMSICFGADDRH_LHXS, priv->msicfg.lhxs);
+		valh |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXS, priv->msicfg.hhxs);
+		writel(val, priv->regs + APLIC_xMSICFGADDR);
+		writel(valh, priv->regs + APLIC_xMSICFGADDRH);
+	}
+#endif
+
+	/* Setup APLIC domaincfg register */
+	val = readl(priv->regs + APLIC_DOMAINCFG);
+	val |= APLIC_DOMAINCFG_IE;
+	if (msi_mode)
+		val |= APLIC_DOMAINCFG_DM;
+	writel(val, priv->regs + APLIC_DOMAINCFG);
+	if (readl(priv->regs + APLIC_DOMAINCFG) != val)
+		dev_warn(priv->dev, "unable to write 0x%x in domaincfg\n", val);
+}
+
+static void aplic_init_hw_irqs(struct aplic_priv *priv)
+{
+	int i;
+
+	/* Disable all interrupts */
+	for (i = 0; i <= priv->nr_irqs; i += 32)
+		writel(-1U, priv->regs + APLIC_CLRIE_BASE + (i / 32) * sizeof(u32));
+
+	/* Set interrupt type and default priority for all interrupts */
+	for (i = 1; i <= priv->nr_irqs; i++) {
+		writel(0, priv->regs + APLIC_SOURCECFG_BASE + (i - 1) * sizeof(u32));
+		writel(APLIC_DEFAULT_PRIORITY,
+		       priv->regs + APLIC_TARGET_BASE + (i - 1) * sizeof(u32));
+	}
+
+	/* Clear APLIC domaincfg */
+	writel(0, priv->regs + APLIC_DOMAINCFG);
+}
+
+int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs)
+{
+	struct of_phandle_args parent;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	/* Save device pointer and register base */
+	priv->dev = dev;
+	priv->regs = regs;
+
+	/* Find out number of interrupt sources */
+	rc = of_property_read_u32(to_of_node(dev->fwnode), "riscv,num-sources",
+				  &priv->nr_irqs);
+	if (rc) {
+		dev_err(dev, "failed to get number of interrupt sources\n");
+		return rc;
+	}
+
+	/*
+	 * Find out number of IDCs based on parent interrupts
+	 *
+	 * If "msi-parent" property is present then we ignore the
+	 * APLIC IDCs which forces the APLIC driver to use MSI mode.
+	 */
+	if (!of_property_present(to_of_node(dev->fwnode), "msi-parent")) {
+		while (!of_irq_parse_one(to_of_node(dev->fwnode), priv->nr_idcs, &parent))
+			priv->nr_idcs++;
+	}
+
+	/* Setup initial state APLIC interrupts */
+	aplic_init_hw_irqs(priv);
+
+	return 0;
+}
+
+static int aplic_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	bool msi_mode = false;
+	void __iomem *regs;
+	int rc;
+
+	/* Map the MMIO registers */
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (!regs) {
+		dev_err(dev, "failed map MMIO registers\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * If msi-parent property is present then setup APLIC MSI
+	 * mode otherwise setup APLIC direct mode.
+	 */
+	if (is_of_node(dev->fwnode))
+		msi_mode = of_property_present(to_of_node(dev->fwnode), "msi-parent");
+	if (msi_mode)
+		rc = -ENODEV;
+	else
+		rc = aplic_direct_setup(dev, regs);
+	if (rc)
+		dev_err(dev, "failed to setup APLIC in %s mode\n", msi_mode ? "MSI" : "direct");
+
+	return rc;
+}
+
+static const struct of_device_id aplic_match[] = {
+	{ .compatible = "riscv,aplic" },
+	{}
+};
+
+static struct platform_driver aplic_driver = {
+	.driver = {
+		.name		= "riscv-aplic",
+		.of_match_table	= aplic_match,
+	},
+	.probe = aplic_probe,
+};
+builtin_platform_driver(aplic_driver);
diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h
new file mode 100644
index 000000000000..4cfbadf37ddc
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-main.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#ifndef _IRQ_RISCV_APLIC_MAIN_H
+#define _IRQ_RISCV_APLIC_MAIN_H
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/fwnode.h>
+
+#define APLIC_DEFAULT_PRIORITY		1
+
+struct aplic_msicfg {
+	phys_addr_t		base_ppn;
+	u32			hhxs;
+	u32			hhxw;
+	u32			lhxs;
+	u32			lhxw;
+};
+
+struct aplic_priv {
+	struct device		*dev;
+	u32			gsi_base;
+	u32			nr_irqs;
+	u32			nr_idcs;
+	void __iomem		*regs;
+	struct aplic_msicfg	msicfg;
+};
+
+void aplic_irq_unmask(struct irq_data *d);
+void aplic_irq_mask(struct irq_data *d);
+int aplic_irq_set_type(struct irq_data *d, unsigned int type);
+int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
+			      unsigned long *hwirq, unsigned int *type);
+void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode);
+int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs);
+int aplic_direct_setup(struct device *dev, void __iomem *regs);
+
+#endif
diff --git a/include/linux/irqchip/riscv-aplic.h b/include/linux/irqchip/riscv-aplic.h
new file mode 100644
index 000000000000..ec8f7df50583
--- /dev/null
+++ b/include/linux/irqchip/riscv-aplic.h
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+#ifndef __LINUX_IRQCHIP_RISCV_APLIC_H
+#define __LINUX_IRQCHIP_RISCV_APLIC_H
+
+#include <linux/bitops.h>
+
+#define APLIC_MAX_IDC			BIT(14)
+#define APLIC_MAX_SOURCE		1024
+
+#define APLIC_DOMAINCFG			0x0000
+#define APLIC_DOMAINCFG_RDONLY		0x80000000
+#define APLIC_DOMAINCFG_IE		BIT(8)
+#define APLIC_DOMAINCFG_DM		BIT(2)
+#define APLIC_DOMAINCFG_BE		BIT(0)
+
+#define APLIC_SOURCECFG_BASE		0x0004
+#define APLIC_SOURCECFG_D		BIT(10)
+#define APLIC_SOURCECFG_CHILDIDX_MASK	0x000003ff
+#define APLIC_SOURCECFG_SM_MASK	0x00000007
+#define APLIC_SOURCECFG_SM_INACTIVE	0x0
+#define APLIC_SOURCECFG_SM_DETACH	0x1
+#define APLIC_SOURCECFG_SM_EDGE_RISE	0x4
+#define APLIC_SOURCECFG_SM_EDGE_FALL	0x5
+#define APLIC_SOURCECFG_SM_LEVEL_HIGH	0x6
+#define APLIC_SOURCECFG_SM_LEVEL_LOW	0x7
+
+#define APLIC_MMSICFGADDR		0x1bc0
+#define APLIC_MMSICFGADDRH		0x1bc4
+#define APLIC_SMSICFGADDR		0x1bc8
+#define APLIC_SMSICFGADDRH		0x1bcc
+
+#ifdef CONFIG_RISCV_M_MODE
+#define APLIC_xMSICFGADDR		APLIC_MMSICFGADDR
+#define APLIC_xMSICFGADDRH		APLIC_MMSICFGADDRH
+#else
+#define APLIC_xMSICFGADDR		APLIC_SMSICFGADDR
+#define APLIC_xMSICFGADDRH		APLIC_SMSICFGADDRH
+#endif
+
+#define APLIC_xMSICFGADDRH_L		BIT(31)
+#define APLIC_xMSICFGADDRH_HHXS_MASK	0x1f
+#define APLIC_xMSICFGADDRH_HHXS_SHIFT	24
+#define APLIC_xMSICFGADDRH_HHXS		(APLIC_xMSICFGADDRH_HHXS_MASK << \
+					 APLIC_xMSICFGADDRH_HHXS_SHIFT)
+#define APLIC_xMSICFGADDRH_LHXS_MASK	0x7
+#define APLIC_xMSICFGADDRH_LHXS_SHIFT	20
+#define APLIC_xMSICFGADDRH_LHXS		(APLIC_xMSICFGADDRH_LHXS_MASK << \
+					 APLIC_xMSICFGADDRH_LHXS_SHIFT)
+#define APLIC_xMSICFGADDRH_HHXW_MASK	0x7
+#define APLIC_xMSICFGADDRH_HHXW_SHIFT	16
+#define APLIC_xMSICFGADDRH_HHXW		(APLIC_xMSICFGADDRH_HHXW_MASK << \
+					 APLIC_xMSICFGADDRH_HHXW_SHIFT)
+#define APLIC_xMSICFGADDRH_LHXW_MASK	0xf
+#define APLIC_xMSICFGADDRH_LHXW_SHIFT	12
+#define APLIC_xMSICFGADDRH_LHXW		(APLIC_xMSICFGADDRH_LHXW_MASK << \
+					 APLIC_xMSICFGADDRH_LHXW_SHIFT)
+#define APLIC_xMSICFGADDRH_BAPPN_MASK	0xfff
+#define APLIC_xMSICFGADDRH_BAPPN_SHIFT	0
+#define APLIC_xMSICFGADDRH_BAPPN	(APLIC_xMSICFGADDRH_BAPPN_MASK << \
+					 APLIC_xMSICFGADDRH_BAPPN_SHIFT)
+
+#define APLIC_xMSICFGADDR_PPN_SHIFT	12
+
+#define APLIC_xMSICFGADDR_PPN_HART(__lhxs) \
+	(BIT(__lhxs) - 1)
+
+#define APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) \
+	(BIT(__lhxw) - 1)
+#define APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs) \
+	((__lhxs))
+#define APLIC_xMSICFGADDR_PPN_LHX(__lhxw, __lhxs) \
+	(APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) << \
+	 APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs))
+
+#define APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) \
+	(BIT(__hhxw) - 1)
+#define APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs) \
+	((__hhxs) + APLIC_xMSICFGADDR_PPN_SHIFT)
+#define APLIC_xMSICFGADDR_PPN_HHX(__hhxw, __hhxs) \
+	(APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) << \
+	 APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs))
+
+#define APLIC_IRQBITS_PER_REG		32
+
+#define APLIC_SETIP_BASE		0x1c00
+#define APLIC_SETIPNUM			0x1cdc
+
+#define APLIC_CLRIP_BASE		0x1d00
+#define APLIC_CLRIPNUM			0x1ddc
+
+#define APLIC_SETIE_BASE		0x1e00
+#define APLIC_SETIENUM			0x1edc
+
+#define APLIC_CLRIE_BASE		0x1f00
+#define APLIC_CLRIENUM			0x1fdc
+
+#define APLIC_SETIPNUM_LE		0x2000
+#define APLIC_SETIPNUM_BE		0x2004
+
+#define APLIC_GENMSI			0x3000
+
+#define APLIC_TARGET_BASE		0x3004
+#define APLIC_TARGET_HART_IDX_SHIFT	18
+#define APLIC_TARGET_HART_IDX_MASK	0x3fff
+#define APLIC_TARGET_HART_IDX		(APLIC_TARGET_HART_IDX_MASK << \
+					 APLIC_TARGET_HART_IDX_SHIFT)
+#define APLIC_TARGET_GUEST_IDX_SHIFT	12
+#define APLIC_TARGET_GUEST_IDX_MASK	0x3f
+#define APLIC_TARGET_GUEST_IDX		(APLIC_TARGET_GUEST_IDX_MASK << \
+					 APLIC_TARGET_GUEST_IDX_SHIFT)
+#define APLIC_TARGET_IPRIO_SHIFT	0
+#define APLIC_TARGET_IPRIO_MASK		0xff
+#define APLIC_TARGET_IPRIO		(APLIC_TARGET_IPRIO_MASK << \
+					 APLIC_TARGET_IPRIO_SHIFT)
+#define APLIC_TARGET_EIID_SHIFT		0
+#define APLIC_TARGET_EIID_MASK		0x7ff
+#define APLIC_TARGET_EIID		(APLIC_TARGET_EIID_MASK << \
+					 APLIC_TARGET_EIID_SHIFT)
+
+#define APLIC_IDC_BASE			0x4000
+#define APLIC_IDC_SIZE			32
+
+#define APLIC_IDC_IDELIVERY		0x00
+
+#define APLIC_IDC_IFORCE		0x04
+
+#define APLIC_IDC_ITHRESHOLD		0x08
+
+#define APLIC_IDC_TOPI			0x18
+#define APLIC_IDC_TOPI_ID_SHIFT		16
+#define APLIC_IDC_TOPI_ID_MASK		0x3ff
+#define APLIC_IDC_TOPI_ID		(APLIC_IDC_TOPI_ID_MASK << \
+					 APLIC_IDC_TOPI_ID_SHIFT)
+#define APLIC_IDC_TOPI_PRIO_SHIFT	0
+#define APLIC_IDC_TOPI_PRIO_MASK	0xff
+#define APLIC_IDC_TOPI_PRIO		(APLIC_IDC_TOPI_PRIO_MASK << \
+					 APLIC_IDC_TOPI_PRIO_SHIFT)
+
+#define APLIC_IDC_CLAIMI		0x1c
+
+#endif
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:40:04 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:10:04 +0530
Subject: [PATCH v14 16/18] irqchip/riscv-aplic: Add support for MSI-mode
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-17-apatel@ventanamicro.com>

The RISC-V advanced platform-level interrupt controller (APLIC) has
two modes of operation: 1) Direct mode and 2) MSI mode.
(For more details, refer https://github.com/riscv/riscv-aia)

In APLIC MSI-mode, wired interrupts are forwared as message signaled
interrupts (MSIs) to CPUs via IMSIC.

Extend the existing APLIC irqchip driver to support MSI-mode for
RISC-V platforms having both wired interrupts and MSIs.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                |   6 +
 drivers/irqchip/Makefile               |   1 +
 drivers/irqchip/irq-riscv-aplic-main.c |   2 +-
 drivers/irqchip/irq-riscv-aplic-main.h |   8 +
 drivers/irqchip/irq-riscv-aplic-msi.c  | 263 +++++++++++++++++++++++++
 5 files changed, 279 insertions(+), 1 deletion(-)
 create mode 100644 drivers/irqchip/irq-riscv-aplic-msi.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index dbc8811d3764..806b5fccb3e8 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -551,6 +551,12 @@ config RISCV_APLIC
 	depends on RISCV
 	select IRQ_DOMAIN_HIERARCHY
 
+config RISCV_APLIC_MSI
+	bool
+	depends on RISCV_APLIC
+	select GENERIC_MSI_IRQ
+	default RISCV_APLIC
+
 config RISCV_IMSIC
 	bool
 	depends on RISCV
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 7f8289790ed8..47995fdb2c60 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
 obj-$(CONFIG_RISCV_APLIC)		+= irq-riscv-aplic-main.o irq-riscv-aplic-direct.o
+obj-$(CONFIG_RISCV_APLIC_MSI)		+= irq-riscv-aplic-msi.o
 obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
index 160ff99d6979..774a0c97fdab 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.c
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -187,7 +187,7 @@ static int aplic_probe(struct platform_device *pdev)
 	if (is_of_node(dev->fwnode))
 		msi_mode = of_property_present(to_of_node(dev->fwnode), "msi-parent");
 	if (msi_mode)
-		rc = -ENODEV;
+		rc = aplic_msi_setup(dev, regs);
 	else
 		rc = aplic_direct_setup(dev, regs);
 	if (rc)
diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h
index 4cfbadf37ddc..4393927d8c80 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.h
+++ b/drivers/irqchip/irq-riscv-aplic-main.h
@@ -40,5 +40,13 @@ int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
 void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode);
 int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs);
 int aplic_direct_setup(struct device *dev, void __iomem *regs);
+#ifdef CONFIG_RISCV_APLIC_MSI
+int aplic_msi_setup(struct device *dev, void __iomem *regs);
+#else
+static inline int aplic_msi_setup(struct device *dev, void __iomem *regs)
+{
+	return -ENODEV;
+}
+#endif
 
 #endif
diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
new file mode 100644
index 000000000000..b2a25e011bb2
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-msi.c
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/riscv-aplic.h>
+#include <linux/irqchip/riscv-imsic.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-aplic-main.h"
+
+static void aplic_msi_irq_unmask(struct irq_data *d)
+{
+	aplic_irq_unmask(d);
+	irq_chip_unmask_parent(d);
+}
+
+static void aplic_msi_irq_mask(struct irq_data *d)
+{
+	irq_chip_mask_parent(d);
+	aplic_irq_mask(d);
+}
+
+static void aplic_msi_irq_eoi(struct irq_data *d)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	u32 reg_off, reg_mask;
+
+	/*
+	 * EOI handling is required only for level-triggered interrupts
+	 * when APLIC is in MSI mode.
+	 */
+
+	reg_off = APLIC_CLRIP_BASE + ((d->hwirq / APLIC_IRQBITS_PER_REG) * 4);
+	reg_mask = BIT(d->hwirq % APLIC_IRQBITS_PER_REG);
+	switch (irqd_get_trigger_type(d)) {
+	case IRQ_TYPE_LEVEL_LOW:
+		/*
+		 * If the rectified input value of the source is still low
+		 * then set the interrupt pending bit so that interrupt is
+		 * re-triggered via MSI.
+		 */
+		if (!(readl(priv->regs + reg_off) & reg_mask))
+			writel(d->hwirq, priv->regs + APLIC_SETIPNUM_LE);
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		/*
+		 * If the rectified input value of the source is still high
+		 * then set the interrupt pending bit so that interrupt is
+		 * re-triggered via MSI.
+		 */
+		if (readl(priv->regs + reg_off) & reg_mask)
+			writel(d->hwirq, priv->regs + APLIC_SETIPNUM_LE);
+		break;
+	}
+}
+
+static void aplic_msi_write_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	unsigned int group_index, hart_index, guest_index, val;
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	struct aplic_msicfg *mc = &priv->msicfg;
+	phys_addr_t tppn, tbppn, msg_addr;
+	void __iomem *target;
+
+	/* For zeroed MSI, simply write zero into the target register */
+	if (!msg->address_hi && !msg->address_lo && !msg->data) {
+		target = priv->regs + APLIC_TARGET_BASE;
+		target += (d->hwirq - 1) * sizeof(u32);
+		writel(0, target);
+		return;
+	}
+
+	/* Sanity check on message data */
+	WARN_ON(msg->data > APLIC_TARGET_EIID_MASK);
+
+	/* Compute target MSI address */
+	msg_addr = (((u64)msg->address_hi) << 32) | msg->address_lo;
+	tppn = msg_addr >> APLIC_xMSICFGADDR_PPN_SHIFT;
+
+	/* Compute target HART Base PPN */
+	tbppn = tppn;
+	tbppn &= ~APLIC_xMSICFGADDR_PPN_HART(mc->lhxs);
+	tbppn &= ~APLIC_xMSICFGADDR_PPN_LHX(mc->lhxw, mc->lhxs);
+	tbppn &= ~APLIC_xMSICFGADDR_PPN_HHX(mc->hhxw, mc->hhxs);
+	WARN_ON(tbppn != mc->base_ppn);
+
+	/* Compute target group and hart indexes */
+	group_index = (tppn >> APLIC_xMSICFGADDR_PPN_HHX_SHIFT(mc->hhxs)) &
+		     APLIC_xMSICFGADDR_PPN_HHX_MASK(mc->hhxw);
+	hart_index = (tppn >> APLIC_xMSICFGADDR_PPN_LHX_SHIFT(mc->lhxs)) &
+		     APLIC_xMSICFGADDR_PPN_LHX_MASK(mc->lhxw);
+	hart_index |= (group_index << mc->lhxw);
+	WARN_ON(hart_index > APLIC_TARGET_HART_IDX_MASK);
+
+	/* Compute target guest index */
+	guest_index = tppn & APLIC_xMSICFGADDR_PPN_HART(mc->lhxs);
+	WARN_ON(guest_index > APLIC_TARGET_GUEST_IDX_MASK);
+
+	/* Update IRQ TARGET register */
+	target = priv->regs + APLIC_TARGET_BASE;
+	target += (d->hwirq - 1) * sizeof(u32);
+	val = FIELD_PREP(APLIC_TARGET_HART_IDX, hart_index);
+	val |= FIELD_PREP(APLIC_TARGET_GUEST_IDX, guest_index);
+	val |= FIELD_PREP(APLIC_TARGET_EIID, msg->data);
+	writel(val, target);
+}
+
+static void aplic_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+	arg->desc = desc;
+	arg->hwirq = (u32)desc->data.icookie.value;
+}
+
+static int aplic_msi_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
+			       unsigned long *hwirq, unsigned int *type)
+{
+	struct msi_domain_info *info = d->host_data;
+	struct aplic_priv *priv = info->data;
+
+	return aplic_irqdomain_translate(fwspec, priv->gsi_base, hwirq, type);
+}
+
+static const struct msi_domain_template aplic_msi_template = {
+	.chip = {
+		.name			= "APLIC-MSI",
+		.irq_mask		= aplic_msi_irq_mask,
+		.irq_unmask		= aplic_msi_irq_unmask,
+		.irq_set_type		= aplic_irq_set_type,
+		.irq_eoi		= aplic_msi_irq_eoi,
+#ifdef CONFIG_SMP
+		.irq_set_affinity	= irq_chip_set_affinity_parent,
+#endif
+		.irq_write_msi_msg	= aplic_msi_write_msg,
+		.flags			= IRQCHIP_SET_TYPE_MASKED |
+					  IRQCHIP_SKIP_SET_WAKE |
+					  IRQCHIP_MASK_ON_SUSPEND,
+	},
+
+	.ops = {
+		.set_desc		= aplic_msi_set_desc,
+		.msi_translate		= aplic_msi_translate,
+	},
+
+	.info = {
+		.bus_token		= DOMAIN_BUS_WIRED_TO_MSI,
+		.flags			= MSI_FLAG_USE_DEV_FWNODE,
+		.handler		= handle_fasteoi_irq,
+	},
+};
+
+int aplic_msi_setup(struct device *dev, void __iomem *regs)
+{
+	const struct imsic_global_config *imsic_global;
+	struct aplic_priv *priv;
+	struct aplic_msicfg *mc;
+	phys_addr_t pa;
+	int rc;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	rc = aplic_setup_priv(priv, dev, regs);
+	if (rc) {
+		dev_err(dev, "failed to create APLIC context\n");
+		return rc;
+	}
+	mc = &priv->msicfg;
+
+	/*
+	 * The APLIC outgoing MSI config registers assume target MSI
+	 * controller to be RISC-V AIA IMSIC controller.
+	 */
+	imsic_global = imsic_get_global_config();
+	if (!imsic_global) {
+		dev_err(dev, "IMSIC global config not found\n");
+		return -ENODEV;
+	}
+
+	/* Find number of guest index bits (LHXS) */
+	mc->lhxs = imsic_global->guest_index_bits;
+	if (APLIC_xMSICFGADDRH_LHXS_MASK < mc->lhxs) {
+		dev_err(dev, "IMSIC guest index bits big for APLIC LHXS\n");
+		return -EINVAL;
+	}
+
+	/* Find number of HART index bits (LHXW) */
+	mc->lhxw = imsic_global->hart_index_bits;
+	if (APLIC_xMSICFGADDRH_LHXW_MASK < mc->lhxw) {
+		dev_err(dev, "IMSIC hart index bits big for APLIC LHXW\n");
+		return -EINVAL;
+	}
+
+	/* Find number of group index bits (HHXW) */
+	mc->hhxw = imsic_global->group_index_bits;
+	if (APLIC_xMSICFGADDRH_HHXW_MASK < mc->hhxw) {
+		dev_err(dev, "IMSIC group index bits big for APLIC HHXW\n");
+		return -EINVAL;
+	}
+
+	/* Find first bit position of group index (HHXS) */
+	mc->hhxs = imsic_global->group_index_shift;
+	if (mc->hhxs < (2 * APLIC_xMSICFGADDR_PPN_SHIFT)) {
+		dev_err(dev, "IMSIC group index shift should be >= %d\n",
+			(2 * APLIC_xMSICFGADDR_PPN_SHIFT));
+		return -EINVAL;
+	}
+	mc->hhxs -= (2 * APLIC_xMSICFGADDR_PPN_SHIFT);
+	if (APLIC_xMSICFGADDRH_HHXS_MASK < mc->hhxs) {
+		dev_err(dev, "IMSIC group index shift big for APLIC HHXS\n");
+		return -EINVAL;
+	}
+
+	/* Compute PPN base */
+	mc->base_ppn = imsic_global->base_addr >> APLIC_xMSICFGADDR_PPN_SHIFT;
+	mc->base_ppn &= ~APLIC_xMSICFGADDR_PPN_HART(mc->lhxs);
+	mc->base_ppn &= ~APLIC_xMSICFGADDR_PPN_LHX(mc->lhxw, mc->lhxs);
+	mc->base_ppn &= ~APLIC_xMSICFGADDR_PPN_HHX(mc->hhxw, mc->hhxs);
+
+	/* Setup global config and interrupt delivery */
+	aplic_init_hw_global(priv, true);
+
+	/* Set the APLIC device MSI domain if not available */
+	if (!dev_get_msi_domain(dev)) {
+		/*
+		 * The device MSI domain for OF devices is only set at the
+		 * time of populating/creating OF device. If the device MSI
+		 * domain is discovered later after the OF device is created
+		 * then we need to set it explicitly before using any platform
+		 * MSI functions.
+		 *
+		 * In case of APLIC device, the parent MSI domain is always
+		 * IMSIC and the IMSIC MSI domains are created later through
+		 * the platform driver probing so we set it explicitly here.
+		 */
+		if (is_of_node(dev->fwnode))
+			of_msi_configure(dev, to_of_node(dev->fwnode));
+	}
+
+	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, &aplic_msi_template,
+					  priv->nr_irqs + 1, priv, priv)) {
+		dev_err(dev, "failed to create MSI irq domain\n");
+		return -ENOMEM;
+	}
+
+	/* Advertise the interrupt controller */
+	pa = priv->msicfg.base_ppn << APLIC_xMSICFGADDR_PPN_SHIFT;
+	dev_info(dev, "%d interrupts forwared to MSI base %pa\n", priv->nr_irqs, &pa);
+
+	return 0;
+}
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:40:05 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:10:05 +0530
Subject: [PATCH v14 17/18] RISC-V: Select APLIC and IMSIC drivers
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-18-apatel@ventanamicro.com>

The QEMU virt machine supports AIA emulation and quite a few RISC-V
platforms with AIA support are under development so select APLIC and
IMSIC drivers for all RISC-V platforms.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 arch/riscv/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index bffbd869a068..569f2b6fd60a 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -162,6 +162,8 @@ config RISCV
 	select PCI_DOMAINS_GENERIC if PCI
 	select PCI_MSI if PCI
 	select RISCV_ALTERNATIVE if !XIP_KERNEL
+	select RISCV_APLIC
+	select RISCV_IMSIC
 	select RISCV_INTC
 	select RISCV_TIMER if RISCV_SBI
 	select SIFIVE_PLIC
-- 
2.34.1



From apatel at ventanamicro.com  Thu Feb 22 01:40:06 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Thu, 22 Feb 2024 15:10:06 +0530
Subject: [PATCH v14 18/18] MAINTAINERS: Add entry for RISC-V AIA drivers
In-Reply-To: <20240222094006.1030709-1-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
Message-ID: <20240222094006.1030709-19-apatel@ventanamicro.com>

Add myself as maintainer for RISC-V AIA drivers including the
RISC-V INTC driver which supports both AIA and non-AIA platforms.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 MAINTAINERS | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ed4d3868539..d948f9210f1b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18801,6 +18801,20 @@ S:	Maintained
 F:	drivers/mtd/nand/raw/r852.c
 F:	drivers/mtd/nand/raw/r852.h
 
+RISC-V AIA DRIVERS
+M:	Anup Patel <anup at brainfault.org>
+L:	linux-riscv at lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
+F:	Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
+F:	drivers/irqchip/irq-riscv-aplic-*.c
+F:	drivers/irqchip/irq-riscv-aplic-*.h
+F:	drivers/irqchip/irq-riscv-imsic-*.c
+F:	drivers/irqchip/irq-riscv-imsic-*.h
+F:	drivers/irqchip/irq-riscv-intc.c
+F:	include/linux/irqchip/riscv-aplic.h
+F:	include/linux/irqchip/riscv-imsic.h
+
 RISC-V ARCHITECTURE
 M:	Paul Walmsley <paul.walmsley at sifive.com>
 M:	Palmer Dabbelt <palmer at dabbelt.com>
-- 
2.34.1



From kurt at linutronix.de  Thu Feb 22 01:45:24 2024
From: kurt at linutronix.de (Kurt Kanzenbach)
Date: Thu, 22 Feb 2024 10:45:24 +0100
Subject: [PATCH net] net: stmmac: Complete meta data only when enabled
Message-ID: <20240222-stmmac_xdp-v1-1-e8d2d2b79ff0@linutronix.de>

Currently using XDP/ZC sockets on stmmac results in a kernel crash:

|[  255.822584] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
|[...]
|[  255.822764] Call trace:
|[  255.822766]  stmmac_tx_clean.constprop.0+0x848/0xc38

The program counter indicates xsk_tx_metadata_complete(). However, this
function shouldn't be called unless metadata is actually enabled.

Tested on imx93 without XDP, with XDP and with XDP/ZC.

Fixes: 1347b419318d ("net: stmmac: Add Tx HWTS support to XDP ZC")
Suggested-by: Serge Semin <fancer.lancer at gmail.com>
Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
Tested-by: Serge Semin <fancer.lancer at gmail.com>
Link: https://lore.kernel.org/netdev/87r0h7wg8u.fsf at kurt.kurt.home/
---
 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 e80d77bd9f1f..8b77c0952071 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2672,7 +2672,8 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue,
 			}
 			if (skb) {
 				stmmac_get_tx_hwtstamp(priv, p, skb);
-			} else {
+			} else if (tx_q->xsk_pool &&
+				   xp_tx_metadata_enabled(tx_q->xsk_pool)) {
 				struct stmmac_xsk_tx_complete tx_compl = {
 					.priv = priv,
 					.desc = p,

---
base-commit: 603ead96582d85903baec2d55f021b8dac5c25d2
change-id: 20240222-stmmac_xdp-585ebf1680b3

Best regards,
-- 
Kurt Kanzenbach <kurt at linutronix.de>



From shameerali.kolothum.thodi at huawei.com  Thu Feb 22 01:49:19 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 22 Feb 2024 09:49:19 +0000
Subject: [PATCH v2 0/4] iommu/smmuv3: Add IOMMUFD dirty tracking support for SMMUv3
Message-ID: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>

Hi,

This is revisiting the earlier attempts [1, 2] to use SMMUv3 HTTU feature
for dirty page tracking. The Intel/AMD support is already mainline.

The code is now based on the new IOMMUFD APIs and is rebased on
Jason's SMMUv3 driver refactor series[3].

Basic sanity tests are done using an emulation setup and on a test
hardware setup. Block page split/merge(BBML) is not part of this
series. I am planning to send it separately.

v1 --> v2:
https://lore.kernel.org/linux-iommu/20231128094940.1344-1-shameerali.kolothum.thodi at huawei.com/

Addressed review comments from Jason and Joao(Thanks)
? ?-Moved dirty_ops setting to domain finalise(patch #3)
? ?-Only enable DBM for stage 1 if domain_alloc_user() requests it.
? ?-Changed IO page table walker(patch #2) and tested with 4KB/16KB/64KB
    with l1/l2/l3 traversal.(The earlier one had a bug where it fails to
    walk L3 level).
? ?-Rearranged patches a bit to improve bi-sectability.
? ?-Rebased on top of Jason's v5 of SMMUv3 new API series git.

Please take a look and let me know your feedback.
Thanks,
Shameer

1. https://lore.kernel.org/lkml/20210413085457.25400-1-zhukeqian1 at huawei.com/
2. https://lore.kernel.org/linux-iommu/20230518204650.14541-1-joao.m.martins at oracle.com/
3. https://github.com/jgunthorpe/linux/commits/smmuv3_newapi

Jean-Philippe Brucker (1):
  iommu/arm-smmu-v3: Add feature detection for HTTU

Joao Martins (1):
  iommu/arm-smmu-v3: Add support for dirty tracking in domain alloc

Kunkun Jiang (1):
  iommu/arm-smmu-v3: Enable HTTU for stage1 with io-pgtable mapping

Shameer Kolothum (1):
  iommu/io-pgtable-arm: Add read_and_clear_dirty() support

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 142 +++++++++++++++++---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |   8 ++
 drivers/iommu/io-pgtable-arm.c              | 133 +++++++++++++++++-
 include/linux/io-pgtable.h                  |   4 +
 4 files changed, 263 insertions(+), 24 deletions(-)

-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb 22 01:49:20 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 22 Feb 2024 09:49:20 +0000
Subject: [PATCH v2 1/4] iommu/arm-smmu-v3: Add feature detection for HTTU
In-Reply-To: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
References: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240222094923.33104-2-shameerali.kolothum.thodi@huawei.com>

From: Jean-Philippe Brucker <jean-philippe at linaro.org>

If the SMMU supports it and the kernel was built with HTTU support,
Probe support for Hardware Translation Table Update (HTTU) which is
essentially to enable hardware update of access and dirty flags.

Probe and set the smmu::features for Hardware Dirty and Hardware Access
bits. This is in preparation, to enable it on the context descriptors of
stage 1 format.

Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 32 +++++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  5 ++++
 2 files changed, 37 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 0606166a8781..bd30739e3588 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4196,6 +4196,28 @@ static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
 	}
 }
 
+static void arm_smmu_get_httu(struct arm_smmu_device *smmu, u32 reg)
+{
+	u32 fw_features = smmu->features & (ARM_SMMU_FEAT_HA | ARM_SMMU_FEAT_HD);
+	u32 features = 0;
+
+	switch (FIELD_GET(IDR0_HTTU, reg)) {
+	case IDR0_HTTU_ACCESS_DIRTY:
+		features |= ARM_SMMU_FEAT_HD;
+		fallthrough;
+	case IDR0_HTTU_ACCESS:
+		features |= ARM_SMMU_FEAT_HA;
+	}
+
+	if (smmu->dev->of_node)
+		smmu->features |= features;
+	else if (features != fw_features)
+		/* ACPI IORT sets the HTTU bits */
+		dev_warn(smmu->dev,
+			 "IDR0.HTTU overridden by FW configuration (0x%x)\n",
+			 fw_features);
+}
+
 static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 {
 	u32 reg;
@@ -4256,6 +4278,8 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 			smmu->features |= ARM_SMMU_FEAT_E2H;
 	}
 
+	arm_smmu_get_httu(smmu, reg);
+
 	/*
 	 * The coherency feature as set by FW is used in preference to the ID
 	 * register, but warn on mismatch.
@@ -4448,6 +4472,14 @@ static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
 	if (iort_smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE)
 		smmu->features |= ARM_SMMU_FEAT_COHERENCY;
 
+	switch (FIELD_GET(ACPI_IORT_SMMU_V3_HTTU_OVERRIDE, iort_smmu->flags)) {
+	case IDR0_HTTU_ACCESS_DIRTY:
+		smmu->features |= ARM_SMMU_FEAT_HD;
+		fallthrough;
+	case IDR0_HTTU_ACCESS:
+		smmu->features |= ARM_SMMU_FEAT_HA;
+	}
+
 	return 0;
 }
 #else
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 45bcd72fcda4..5e51a6c1d55f 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -33,6 +33,9 @@
 #define IDR0_ASID16			(1 << 12)
 #define IDR0_ATS			(1 << 10)
 #define IDR0_HYP			(1 << 9)
+#define IDR0_HTTU			GENMASK(7, 6)
+#define IDR0_HTTU_ACCESS		1
+#define IDR0_HTTU_ACCESS_DIRTY		2
 #define IDR0_COHACC			(1 << 4)
 #define IDR0_TTF			GENMASK(3, 2)
 #define IDR0_TTF_AARCH64		2
@@ -668,6 +671,8 @@ struct arm_smmu_device {
 #define ARM_SMMU_FEAT_SVA		(1 << 17)
 #define ARM_SMMU_FEAT_E2H		(1 << 18)
 #define ARM_SMMU_FEAT_NESTING		(1 << 19)
+#define ARM_SMMU_FEAT_HA		(1 << 20)
+#define ARM_SMMU_FEAT_HD		(1 << 21)
 	u32				features;
 
 #define ARM_SMMU_OPT_SKIP_PREFETCH	(1 << 0)
-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb 22 01:49:21 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 22 Feb 2024 09:49:21 +0000
Subject: [PATCH v2 2/4] iommu/io-pgtable-arm: Add read_and_clear_dirty() support
In-Reply-To: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
References: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240222094923.33104-3-shameerali.kolothum.thodi@huawei.com>

.read_and_clear_dirty() IOMMU domain op takes care of reading the dirty
bits (i.e. PTE has both DBM and AP[2] set) and marshalling into a bitmap of
a given page size.

While reading the dirty bits we also clear the PTE AP[2] bit to mark it as
writable-clean depending on read_and_clear_dirty() flags.

Structure it in a way that the IOPTE walker is generic, and so we pass a
function pointer over what to do on a per-PTE basis.

Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/io-pgtable-arm.c | 128 ++++++++++++++++++++++++++++++++-
 1 file changed, 127 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index f7828a7aad41..1ce7b7a3c1e8 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -75,6 +75,7 @@
 
 #define ARM_LPAE_PTE_NSTABLE		(((arm_lpae_iopte)1) << 63)
 #define ARM_LPAE_PTE_XN			(((arm_lpae_iopte)3) << 53)
+#define ARM_LPAE_PTE_DBM		(((arm_lpae_iopte)1) << 51)
 #define ARM_LPAE_PTE_AF			(((arm_lpae_iopte)1) << 10)
 #define ARM_LPAE_PTE_SH_NS		(((arm_lpae_iopte)0) << 8)
 #define ARM_LPAE_PTE_SH_OS		(((arm_lpae_iopte)2) << 8)
@@ -84,7 +85,7 @@
 
 #define ARM_LPAE_PTE_ATTR_LO_MASK	(((arm_lpae_iopte)0x3ff) << 2)
 /* Ignore the contiguous bit for block splitting */
-#define ARM_LPAE_PTE_ATTR_HI_MASK	(((arm_lpae_iopte)6) << 52)
+#define ARM_LPAE_PTE_ATTR_HI_MASK	(((arm_lpae_iopte)0xd) << 51)
 #define ARM_LPAE_PTE_ATTR_MASK		(ARM_LPAE_PTE_ATTR_LO_MASK |	\
 					 ARM_LPAE_PTE_ATTR_HI_MASK)
 /* Software bit for solving coherency races */
@@ -93,6 +94,9 @@
 /* Stage-1 PTE */
 #define ARM_LPAE_PTE_AP_UNPRIV		(((arm_lpae_iopte)1) << 6)
 #define ARM_LPAE_PTE_AP_RDONLY		(((arm_lpae_iopte)2) << 6)
+#define ARM_LPAE_PTE_AP_RDONLY_BIT	7
+#define ARM_LPAE_PTE_AP_WRITABLE	(ARM_LPAE_PTE_AP_RDONLY | \
+					 ARM_LPAE_PTE_DBM)
 #define ARM_LPAE_PTE_ATTRINDX_SHIFT	2
 #define ARM_LPAE_PTE_nG			(((arm_lpae_iopte)1) << 11)
 
@@ -729,6 +733,127 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
 	return iopte_to_paddr(pte, data) | iova;
 }
 
+struct arm_lpae_iopte_read_dirty {
+	unsigned long flags;
+	struct iommu_dirty_bitmap *dirty;
+};
+
+typedef int (*io_pgtable_visit_fn_t)(unsigned long iova, size_t size,
+				     arm_lpae_iopte *ptep, void *opaque);
+struct io_pgtable_walk_data {
+	const io_pgtable_visit_fn_t	fn;
+	void				*opaque;
+	u64				addr;
+	const u64			end;
+};
+
+static int __arm_lpae_iopte_walk(struct arm_lpae_io_pgtable *data,
+				 struct io_pgtable_walk_data *walk_data,
+				 arm_lpae_iopte *ptep,
+				 int lvl);
+
+static int __arm_lpae_read_and_clear_dirty(unsigned long iova, size_t size,
+					   arm_lpae_iopte *ptep, void *opaque)
+{
+	struct arm_lpae_iopte_read_dirty *arg = opaque;
+	struct iommu_dirty_bitmap *dirty = arg->dirty;
+	arm_lpae_iopte pte;
+
+	pte = READ_ONCE(*ptep);
+	if (WARN_ON(!pte))
+		return -EINVAL;
+
+	if ((pte & ARM_LPAE_PTE_AP_WRITABLE) == ARM_LPAE_PTE_AP_WRITABLE)
+		return 0;
+
+	iommu_dirty_bitmap_record(dirty, iova, size);
+	if (!(arg->flags & IOMMU_DIRTY_NO_CLEAR))
+		set_bit(ARM_LPAE_PTE_AP_RDONLY_BIT, (unsigned long *)ptep);
+	return 0;
+}
+
+static int io_pgtable_visit(struct arm_lpae_io_pgtable *data,
+			    struct io_pgtable_walk_data *walk_data,
+			    arm_lpae_iopte *ptep, int lvl)
+{
+	struct io_pgtable *iop = &data->iop;
+	arm_lpae_iopte pte = READ_ONCE(*ptep);
+
+	if (WARN_ON(!pte))
+		return -EINVAL;
+
+	if (iopte_leaf(pte, lvl, iop->fmt)) {
+		size_t size = ARM_LPAE_BLOCK_SIZE(lvl, data);
+
+		walk_data->fn(walk_data->addr, size, ptep, walk_data->opaque);
+		walk_data->addr += size;
+		return 0;
+	}
+
+	ptep = iopte_deref(pte, data);
+	return __arm_lpae_iopte_walk(data, walk_data, ptep, lvl + 1);
+}
+
+static int __arm_lpae_iopte_walk(struct arm_lpae_io_pgtable *data,
+				 struct io_pgtable_walk_data *walk_data,
+				 arm_lpae_iopte *ptep,
+				 int lvl)
+{
+	u32 idx;
+	int max_entries, ret;
+
+	if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS))
+		return -EINVAL;
+
+	if (lvl == data->start_level)
+		max_entries = ARM_LPAE_PGD_SIZE(data) / sizeof(arm_lpae_iopte);
+	else
+		max_entries = ARM_LPAE_PTES_PER_TABLE(data);
+
+	for (idx = ARM_LPAE_LVL_IDX(walk_data->addr, lvl, data);
+	     (idx < max_entries) && (walk_data->addr < walk_data->end); ++idx) {
+		arm_lpae_iopte *pteref = &ptep[idx];
+
+		ret = io_pgtable_visit(data, walk_data, pteref, lvl);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
+					 unsigned long iova, size_t size,
+					 unsigned long flags,
+					 struct iommu_dirty_bitmap *dirty)
+{
+	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+	struct arm_lpae_iopte_read_dirty arg = {
+		.flags = flags, .dirty = dirty,
+	};
+	struct io_pgtable_walk_data walk_data = {
+		.fn = __arm_lpae_read_and_clear_dirty,
+		.opaque = &arg,
+		.addr = iova,
+		.end = iova + size - 1,
+	};
+	arm_lpae_iopte *ptep = data->pgd;
+	int lvl = data->start_level;
+	long iaext = (s64)iova >> cfg->ias;
+
+	if (WARN_ON(!size))
+		return -EINVAL;
+
+	if (WARN_ON(iaext))
+		return -EINVAL;
+
+	if (data->iop.fmt != ARM_64_LPAE_S1)
+		return -EINVAL;
+
+	return __arm_lpae_iopte_walk(data, &walk_data, ptep, lvl);
+}
+
 static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
 {
 	unsigned long granule, page_sizes;
@@ -807,6 +932,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
 		.map_pages	= arm_lpae_map_pages,
 		.unmap_pages	= arm_lpae_unmap_pages,
 		.iova_to_phys	= arm_lpae_iova_to_phys,
+		.read_and_clear_dirty = arm_lpae_read_and_clear_dirty,
 	};
 
 	return data;
-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb 22 01:49:22 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 22 Feb 2024 09:49:22 +0000
Subject: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty tracking in domain alloc
In-Reply-To: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
References: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240222094923.33104-4-shameerali.kolothum.thodi@huawei.com>

From: Joao Martins <joao.m.martins at oracle.com>

This provides all the infrastructure to enable dirty tracking if the
hardware has the capability and domain alloc request for it.

Please note, we still report no support for IOMMU_CAP_DIRTY_TRACKING
as it will finally be enabled in a subsequent patch.

Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 95 ++++++++++++++++-----
 include/linux/io-pgtable.h                  |  4 +
 2 files changed, 77 insertions(+), 22 deletions(-)

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 bd30739e3588..058bbb0dbe2e 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -43,6 +43,7 @@ MODULE_PARM_DESC(disable_msipolling,
 	"Disable MSI-based polling for CMD_SYNC completion.");
 
 static struct iommu_ops arm_smmu_ops;
+static struct iommu_dirty_ops arm_smmu_dirty_ops;
 
 enum arm_smmu_msi_index {
 	EVTQ_MSI_INDEX,
@@ -86,7 +87,8 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
 
 static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu);
 static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
-				    struct arm_smmu_device *smmu);
+				    struct arm_smmu_device *smmu,
+				    bool enable_dirty);
 static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
 static void arm_smmu_tlb_inv_all_s2(struct arm_smmu_domain *smmu_domain);
 
@@ -2378,7 +2380,7 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
 		struct arm_smmu_master *master = dev_iommu_priv_get(dev);
 		int ret;
 
-		ret = arm_smmu_domain_finalise(smmu_domain, master->smmu);
+		ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, false);
 		if (ret) {
 			kfree(smmu_domain);
 			return ERR_PTR(ret);
@@ -2445,10 +2447,11 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 }
 
 static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
-				    struct arm_smmu_device *smmu)
+				    struct arm_smmu_device *smmu,
+				    bool enable_dirty)
 {
 	int ret;
-	unsigned long ias, oas;
+	unsigned long ias;
 	enum io_pgtable_fmt fmt;
 	struct io_pgtable_cfg pgtbl_cfg;
 	struct io_pgtable_ops *pgtbl_ops;
@@ -2459,31 +2462,31 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
 	if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
 		smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
 
+	pgtbl_cfg = (struct io_pgtable_cfg) {
+		.pgsize_bitmap	= smmu->pgsize_bitmap,
+		.coherent_walk	= smmu->features & ARM_SMMU_FEAT_COHERENCY,
+		.tlb		= &arm_smmu_flush_ops,
+		.iommu_dev	= smmu->dev,
+	};
+
 	switch (smmu_domain->stage) {
 	case ARM_SMMU_DOMAIN_S1:
 		ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
-		ias = min_t(unsigned long, ias, VA_BITS);
-		oas = smmu->ias;
+		pgtbl_cfg.ias = min_t(unsigned long, ias, VA_BITS);
+		pgtbl_cfg.oas = smmu->ias;
+		if (enable_dirty)
+			pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_HD;
 		fmt = ARM_64_LPAE_S1;
 		break;
 	case ARM_SMMU_DOMAIN_S2:
-		ias = smmu->ias;
-		oas = smmu->oas;
+		pgtbl_cfg.ias = smmu->ias;
+		pgtbl_cfg.oas = smmu->oas;
 		fmt = ARM_64_LPAE_S2;
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	pgtbl_cfg = (struct io_pgtable_cfg) {
-		.pgsize_bitmap	= smmu->pgsize_bitmap,
-		.ias		= ias,
-		.oas		= oas,
-		.coherent_walk	= smmu->features & ARM_SMMU_FEAT_COHERENCY,
-		.tlb		= &arm_smmu_flush_ops,
-		.iommu_dev	= smmu->dev,
-	};
-
 	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
 	if (!pgtbl_ops)
 		return -ENOMEM;
@@ -2491,7 +2494,8 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
 	smmu_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
 	smmu_domain->domain.geometry.aperture_end = (1UL << pgtbl_cfg.ias) - 1;
 	smmu_domain->domain.geometry.force_aperture = true;
-
+	if (enable_dirty && smmu_domain->stage == ARM_SMMU_DOMAIN_S1)
+		smmu_domain->domain.dirty_ops = &arm_smmu_dirty_ops;
 	ret = arm_smmu_domain_alloc_id(smmu, smmu_domain);
 	if (ret < 0) {
 		free_io_pgtable_ops(pgtbl_ops);
@@ -2811,7 +2815,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	mutex_lock(&smmu_domain->init_mutex);
 
 	if (!smmu_domain->smmu) {
-		ret = arm_smmu_domain_finalise(smmu_domain, smmu);
+		ret = arm_smmu_domain_finalise(smmu_domain, smmu, false);
 	} else if (smmu_domain->smmu != smmu)
 		ret = -EINVAL;
 
@@ -2876,7 +2880,7 @@ static int arm_smmu_s1_set_dev_pasid(struct iommu_domain *domain,
 
 	mutex_lock(&smmu_domain->init_mutex);
 	if (!smmu_domain->smmu)
-		ret = arm_smmu_domain_finalise(smmu_domain, smmu);
+		ret = arm_smmu_domain_finalise(smmu_domain, smmu, false);
 	else if (smmu_domain->smmu != smmu)
 		ret = -EINVAL;
 	mutex_unlock(&smmu_domain->init_mutex);
@@ -3193,7 +3197,9 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
 			   const struct iommu_user_data *user_data)
 {
 	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
-	const u32 paging_flags = IOMMU_HWPT_ALLOC_NEST_PARENT;
+	const u32 paging_flags = IOMMU_HWPT_ALLOC_NEST_PARENT |
+				 IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
+	bool enforce_dirty = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
 	struct arm_smmu_domain *smmu_domain;
 	int ret;
 
@@ -3206,6 +3212,10 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
 	if (user_data)
 		return ERR_PTR(-EINVAL);
 
+	if (enforce_dirty &&
+	    !device_iommu_capable(dev, IOMMU_CAP_DIRTY_TRACKING))
+		return ERR_PTR(-EOPNOTSUPP);
+
 	smmu_domain = arm_smmu_domain_alloc();
 	if (!smmu_domain)
 		return ERR_PTR(-ENOMEM);
@@ -3221,7 +3231,7 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
 
 	smmu_domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
 	smmu_domain->domain.ops = arm_smmu_ops.default_domain_ops;
-	ret = arm_smmu_domain_finalise(smmu_domain, master->smmu);
+	ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, enforce_dirty);
 	if (ret)
 		goto err_free;
 	return &smmu_domain->domain;
@@ -3470,6 +3480,42 @@ static void arm_smmu_release_device(struct device *dev)
 	kfree(master);
 }
 
+static int arm_smmu_read_and_clear_dirty(struct iommu_domain *domain,
+					 unsigned long iova, size_t size,
+					 unsigned long flags,
+					 struct iommu_dirty_bitmap *dirty)
+{
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+	struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
+
+	if (smmu_domain->stage != ARM_SMMU_DOMAIN_S1)
+		return -EINVAL;
+
+	if (WARN_ON_ONCE(!ops || !ops->read_and_clear_dirty))
+		return -ENODEV;
+
+	return ops->read_and_clear_dirty(ops, iova, size, flags, dirty);
+}
+
+static int arm_smmu_set_dirty_tracking(struct iommu_domain *domain,
+				       bool enabled)
+{
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+	struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
+
+	if (smmu_domain->stage != ARM_SMMU_DOMAIN_S1)
+		return -EINVAL;
+
+	if (WARN_ON_ONCE(!ops))
+		return -ENODEV;
+
+	/*
+	 * Always enabled and the dirty bitmap is cleared prior to
+	 * set_dirty_tracking().
+	 */
+	return 0;
+}
+
 static struct iommu_group *arm_smmu_device_group(struct device *dev)
 {
 	struct iommu_group *group;
@@ -3612,6 +3658,11 @@ static struct iommu_ops arm_smmu_ops = {
 	}
 };
 
+static struct iommu_dirty_ops arm_smmu_dirty_ops = {
+	.read_and_clear_dirty	= arm_smmu_read_and_clear_dirty,
+	.set_dirty_tracking     = arm_smmu_set_dirty_tracking,
+};
+
 /* Probing and initialisation functions */
 static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
 				   struct arm_smmu_queue *q,
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index 86cf1f7ae389..8e75f944f07a 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -85,6 +85,8 @@ struct io_pgtable_cfg {
 	 *
 	 * IO_PGTABLE_QUIRK_ARM_OUTER_WBWA: Override the outer-cacheability
 	 *	attributes set in the TCR for a non-coherent page-table walker.
+	 *
+	 * IO_PGTABLE_QUIRK_ARM_HD: Enables dirty tracking in stage 1 pagetable.
 	 */
 	#define IO_PGTABLE_QUIRK_ARM_NS			BIT(0)
 	#define IO_PGTABLE_QUIRK_NO_PERMS		BIT(1)
@@ -92,6 +94,8 @@ struct io_pgtable_cfg {
 	#define IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT	BIT(4)
 	#define IO_PGTABLE_QUIRK_ARM_TTBR1		BIT(5)
 	#define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA		BIT(6)
+	#define IO_PGTABLE_QUIRK_ARM_HD			BIT(7)
+
 	unsigned long			quirks;
 	unsigned long			pgsize_bitmap;
 	unsigned int			ias;
-- 
2.34.1



From shameerali.kolothum.thodi at huawei.com  Thu Feb 22 01:49:23 2024
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 22 Feb 2024 09:49:23 +0000
Subject: [PATCH v2 4/4] iommu/arm-smmu-v3: Enable HTTU for stage1 with io-pgtable mapping
In-Reply-To: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
References: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20240222094923.33104-5-shameerali.kolothum.thodi@huawei.com>

From: Kunkun Jiang <jiangkunkun at huawei.com>

If io-pgtable quirk flag indicates support for hardware update of
dirty state, enable HA/HD bits in the SMMU?CD and also set the DBM
bit in the page descriptor.

And now report the dirty page tracking capability of SMMUv3.

Co-developed-by: Keqian Zhu <zhukeqian1 at huawei.com>
Signed-off-by: Keqian Zhu <zhukeqian1 at huawei.com>
Signed-off-by: Kunkun Jiang <jiangkunkun at huawei.com>
Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 +++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  3 +++
 drivers/iommu/io-pgtable-arm.c              |  5 ++++-
 3 files changed, 22 insertions(+), 1 deletion(-)

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 058bbb0dbe2e..4423cc7e48cf 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1271,6 +1271,12 @@ void arm_smmu_make_s1_cd(struct arm_smmu_cd *target,
 		CTXDESC_CD_0_ASET |
 		FIELD_PREP(CTXDESC_CD_0_ASID, smmu_domain->asid)
 		);
+
+	/* To enable dirty flag update, set both Access flag and dirty state update */
+	if (pgtbl_cfg->quirks & IO_PGTABLE_QUIRK_ARM_HD)
+		target->data[0] |= cpu_to_le64(CTXDESC_CD_0_TCR_HA |
+					       CTXDESC_CD_0_TCR_HD);
+
 	target->data[1] = cpu_to_le64(pgtbl_cfg->arm_lpae_s1_cfg.ttbr &
 				      CTXDESC_CD_1_TTB0_MASK);
 	target->data[3] = cpu_to_le64(pgtbl_cfg->arm_lpae_s1_cfg.mair);
@@ -2307,6 +2313,13 @@ static const struct iommu_flush_ops arm_smmu_flush_ops = {
 	.tlb_add_page	= arm_smmu_tlb_inv_page_nosync,
 };
 
+static bool arm_smmu_dbm_capable(struct arm_smmu_device *smmu)
+{
+	u32 features = (ARM_SMMU_FEAT_HD | ARM_SMMU_FEAT_COHERENCY);
+
+	return (smmu->features & features) == features;
+}
+
 /* IOMMU API */
 static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
 {
@@ -2319,6 +2332,8 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
 	case IOMMU_CAP_NOEXEC:
 	case IOMMU_CAP_DEFERRED_FLUSH:
 		return true;
+	case IOMMU_CAP_DIRTY_TRACKING:
+		return arm_smmu_dbm_capable(master->smmu);
 	default:
 		return false;
 	}
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 5e51a6c1d55f..a9cd805e5a1b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -313,6 +313,9 @@ struct arm_smmu_cd {
 #define CTXDESC_CD_0_TCR_IPS		GENMASK_ULL(34, 32)
 #define CTXDESC_CD_0_TCR_TBI0		(1ULL << 38)
 
+#define CTXDESC_CD_0_TCR_HA            (1UL << 43)
+#define CTXDESC_CD_0_TCR_HD            (1UL << 42)
+
 #define CTXDESC_CD_0_AA64		(1UL << 41)
 #define CTXDESC_CD_0_S			(1UL << 44)
 #define CTXDESC_CD_0_R			(1UL << 45)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 1ce7b7a3c1e8..56e88e555fc7 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -429,6 +429,8 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
 		pte = ARM_LPAE_PTE_nG;
 		if (!(prot & IOMMU_WRITE) && (prot & IOMMU_READ))
 			pte |= ARM_LPAE_PTE_AP_RDONLY;
+		else if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_HD)
+			pte |= ARM_LPAE_PTE_AP_WRITABLE;
 		if (!(prot & IOMMU_PRIV))
 			pte |= ARM_LPAE_PTE_AP_UNPRIV;
 	} else {
@@ -948,7 +950,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 
 	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
 			    IO_PGTABLE_QUIRK_ARM_TTBR1 |
-			    IO_PGTABLE_QUIRK_ARM_OUTER_WBWA))
+			    IO_PGTABLE_QUIRK_ARM_OUTER_WBWA |
+			    IO_PGTABLE_QUIRK_ARM_HD))
 		return NULL;
 
 	data = arm_lpae_alloc_pgtable(cfg);
-- 
2.34.1



From arnd at arndb.de  Thu Feb 22 01:52:10 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 22 Feb 2024 10:52:10 +0100
Subject: [PATCH -next] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
In-Reply-To: <30b01c65-12f2-4ee0-81d5-c7a2da2c36b4@app.fastmail.com>
References: <20240220081527.23408-1-liuyuntao12@huawei.com>
 <1342759e-b967-4ec4-98d5-48146f81f695@app.fastmail.com>
 <38c09a4b-69cc-4dc5-8a68-e5f5597613ac@huawei.com>
 <30b01c65-12f2-4ee0-81d5-c7a2da2c36b4@app.fastmail.com>
Message-ID: <f5326293-b446-49e5-9cc0-78c9009af136@app.fastmail.com>

On Wed, Feb 21, 2024, at 16:51, Arnd Bergmann wrote:
> I have given your patch some build testing with random
> configurations in my build setup and it seems to work
> fine with gcc/binutils, but unfortunately I came across
> a link failure using clang/lld:

I ran into another bug now, this time with CONFIG_XIP_KERNEL=y:

no __ex_table in file: vmlinux
Failed to sort kernel tables
make[4]: *** [scripts/Makefile.vmlinux:37: vmlinux] Error 1

Essentially you have to modify arch/arm/kernel/vmlinux-xip.lds.S
the same way as vmlinux.lds.S:

--- a/arch/arm/kernel/vmlinux-xip.lds.S
+++ b/arch/arm/kernel/vmlinux-xip.lds.S
@@ -63,7 +63,7 @@ SECTIONS
        . = ALIGN(4);
        __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
                __start___ex_table = .;
-               ARM_MMU_KEEP(*(__ex_table))
+               ARM_MMU_KEEP(KEEP(*(__ex_table)))
                __stop___ex_table = .;
        }
 
@@ -83,7 +83,7 @@ SECTIONS
        }
        .init.arch.info : {
                __arch_info_begin = .;
-               *(.arch.info.init)
+               KEEP(*(.arch.info.init))
                __arch_info_end = .;
        }
        .init.tagtable : {


The pv_table is not needed for XIP_KERNEL=y because that
requires not patching the kernel.

    Arnd


From cristian.marussi at arm.com  Thu Feb 22 01:55:25 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Thu, 22 Feb 2024 09:55:25 +0000
Subject: [PATCH V4 2/2] clk: scmi: support state_ctrl_forbidden
In-Reply-To: <20240222094153.2nxvefa44y5ikutm@bogus>
References: <20240121110901.1414856-1-peng.fan@oss.nxp.com>
 <20240121110901.1414856-2-peng.fan@oss.nxp.com>
 <20240222094153.2nxvefa44y5ikutm@bogus>
Message-ID: <ZdcaDYqWcF2XWoLE@pluto>

On Thu, Feb 22, 2024 at 09:41:53AM +0000, Sudeep Holla wrote:
> On Sun, Jan 21, 2024 at 07:09:01PM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> > 
> > Some clocks may exported to linux, while those clocks are not allowed
> > to configure by Linux. For example:
> > 
> > SYS_CLK1-----
> >              \
> > 	     --MUX--->MMC1_CLK
> >              /
> > SYS_CLK2-----
> > 
> > MMC1 needs set parent, so SYS_CLK1 and SYS_CLK2 are exported to Linux,
> > then the clk propagation will touch SYS_CLK1 or SYS_CLK2.
> > So we need bypass the failure for SYS_CLK1 or SYS_CLK2 when enable
> > the clock of MMC1, adding scmi_no_state_ctrl_clk_ops to use software
> > enable counter, while not calling scmi api.
> > 
> > Co-developed-by: Cristian Marussi <cristian.marussi at arm.com>
> > Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> > 
> > V4:
> >  Add scmi_no_state_ctrl_clk_ops per Cristian
> >  Add Cristian's tag
> > 
> > V3:
> >  Add check in atomic enable
> > 
> > V2:
> >  New. Take Cristian's suggestion
> > 
> >  drivers/clk/clk-scmi.c | 15 +++++++++++++--
> >  1 file changed, 13 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
> > index 8cbe24789c24..5747b6d651f0 100644
> > --- a/drivers/clk/clk-scmi.c
> > +++ b/drivers/clk/clk-scmi.c
> > @@ -194,6 +194,15 @@ static const struct clk_ops scmi_atomic_clk_ops = {
> >  	.determine_rate = scmi_clk_determine_rate,
> >  };
> >  
> > +static const struct clk_ops scmi_no_state_ctrl_clk_ops = {
> > +	.recalc_rate = scmi_clk_recalc_rate,
> > +	.round_rate = scmi_clk_round_rate,
> > +	.set_rate = scmi_clk_set_rate,
> > +	.set_parent = scmi_clk_set_parent,
> > +	.get_parent = scmi_clk_get_parent,
> > +	.determine_rate = scmi_clk_determine_rate,
> > +};
> > +
> >  static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
> >  			     const struct clk_ops *scmi_ops)
> >  {
> > @@ -290,8 +299,10 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
> >  		 * 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)
> > +		if (sclk->info->state_ctrl_forbidden)
> > +			scmi_ops = &scmi_no_state_ctrl_clk_ops;
> 
> With this, even if is_atomic and latency matches, we won't allow
> atomic operations ? One reason why it gets tricky and as Cristian 
> mentioned elsewhere we need dynamic assignment of these ops IMO.
> Let me know if I am getting things wrong here ?

It is fine that we wont allow atomic ops either since state_ctrl_forbidden
means the server will reject any enable/disable action, atomic or
not...what I missed here, though, is that we lost also is_enabled indeed,
which could be provided even if state_ctrl_forbidden BUT only if atomic
is supported...so yes this will need an additional atomic/non_atomic
split of this static ops...and so the need for dynamic allocation I was
saying elsewhere....indeed the is_enabled case is handled correctly
again with my pending clk dynamic allocation of ops patch.

My bad, thanks for spotting this Sudeep!
Cristian


From quic_namajain at quicinc.com  Thu Feb 22 01:55:11 2024
From: quic_namajain at quicinc.com (Naman Jain)
Date: Thu, 22 Feb 2024 15:25:11 +0530
Subject: [PATCH v3 0/7] Introduction of a remoteproc tee to load signed
 firmware
In-Reply-To: <adcf0c0d-f452-4285-8651-c147fcca001b@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <fe4ec29f-7521-4369-a382-bae50dbf0ee5@quicinc.com>
 <adcf0c0d-f452-4285-8651-c147fcca001b@foss.st.com>
Message-ID: <8af59b01-53cf-4fc4-9946-6c630fb7b38e@quicinc.com>

On 2/22/2024 2:17 PM, Arnaud POULIQUEN wrote:
> Hello Naman,
> 
> On 2/22/24 06:43, Naman Jain wrote:
>> On 2/14/2024 10:51 PM, Arnaud Pouliquen wrote:
>>> Updates from the previous version [1]:
>>>
>>> This version proposes another approach based on an alternate load and boot
>>> of the coprocessor. Therefore, the constraint introduced by tee_remoteproc
>>> is that the firmware has to be authenticated and loaded before the resource
>>> table can be obtained.
>>>
>>> The existing boot sequence is: >
>>>  ?? 1) Get the resource table and store it in a cache,
>>>  ????? calling rproc->ops->parse_fw().
>>>  ?? 2) Parse the resource table and handle resources,
>>>  ????? calling rproc_handle_resources.
>>>  ?? 3) Load the firmware, calling rproc->ops->load().
>>>  ?? 4) Start the firmware, calling rproc->ops->start().
>>>  ? => Steps 1 and 2 are executed in rproc_fw_boot(), while steps 3 and 4 are
>>>  ??? executed in rproc_start().
>>> => the use of rproc->ops->load() ops is mandatory
>>>
>>> The boot sequence needed for TEE boot is:
>>>
>>>  ?? 1) Load the firmware.
>>>  ?? 2) Get the loaded resource, no cache.
>>>  ?? 3) Parse the resource table and handle resources.
>>>  ?? 4) Start the firmware.
>>
>> Hi,
>> What problem are we really addressing here by reordering load, parse of
>> FW resources?
> 
> The feature introduced in TEE is the signature of the firmware images. That
> means that before getting the resource table, we need to first authenticate the
> firmware images.
> Authenticating a firmware image means that we have to copy the firmware into
> protected memory that cannot be corrupted by the non-secure and then verify the
> signature.
> The strategy implemented in OP-TEE is to load the firmware into destination
> memory and then authenticate it.
> This strategy avoids having a temporary copy of the whole images in a secure memory.
> This strategy imposes loading the firmware images before retrieving the resource
> table.
> 
>> Basically, what are the limitations of the current design you are referring to?
>> I understood that TEE is designed that way.
> 
> The limitation of the current design is that we obtain the resource table before
> loading the firmware. Following the current design would impose constraints in
> TEE that are not straightforward. Step 1 (getting the resource table and storing
> it in a cache) would require having a copy of the resource table in TEE after
> authenticating the images. However, authenticating the firmware, as explained
> before, depends on the strategy implemented. In TEE implementation, we load the
> firmware to authenticate it in the destination memory.
> 
> Regards,
> Arnaud


Hello Arnaud,
I think now I got your point. In TEE, you don't want to do anything(read
resource table) with FW images, until its loaded and authenticated.
Since current design was not allowing you to do it, you had to 
reorganize the code so that this can be achieved.

Generally speaking, in current design, if authentication fails for some
reason later, one can handle it, but it depends on the implementation of
parse_fw op if the damage is already done.

Please correct me if this is wrong assumption.
Patch looks good to me.

Regards,
Naman Jain


From szymon.jankowski at thrivehub.pl  Wed Feb 21 00:45:49 2024
From: szymon.jankowski at thrivehub.pl (Szymon Jankowski)
Date: Wed, 21 Feb 2024 08:45:49 GMT
Subject: Zapytanie ofertowe 
Message-ID: <20240221074500-0.1.4r.233gv.0.e928u56p6f@thrivehub.pl>

Dzie? dobry,

Pozwoli?em sobie na kontakt, poniewa? jestem zainteresowany weryfikacj? mo?liwo?ci nawi?zania wsp??pracy.

Wspieramy firmy w pozyskiwaniu nowych klient?w biznesowych.

Czy mo?emy porozmawia? w celu przedstawienia szczeg??owych informacji? 


Pozdrawiam
Szymon Jankowski


From daniel.lezcano at linaro.org  Thu Feb 22 02:02:21 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Thu, 22 Feb 2024 11:02:21 +0100
Subject: [PATCH v1] clocksource/drivers/arm_global_timer: Simplify
 prescaler register access
In-Reply-To: <20240221214348.2299636-1-martin.blumenstingl@googlemail.com>
References: <20240221214348.2299636-1-martin.blumenstingl@googlemail.com>
Message-ID: <a4f8fa60-7c03-4946-a135-a405d53f361b@linaro.org>


Hi Martin,

thank you for providing these cleanups.

One question below:


On 21/02/2024 22:43, Martin Blumenstingl wrote:

[ ... ]

>   		/* prescaler within legal range? */
> -		if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
> +		if (psv < 0 || psv > FIELD_GET(GT_CONTROL_PRESCALER_MASK, ~0))

		FIELD_MAX() ?

[ ... ]

-- 
<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 greena88 at gmail.com  Thu Feb 22 02:17:41 2024
From: greena88 at gmail.com (Adam Green)
Date: Thu, 22 Feb 2024 10:17:41 +0000
Subject: [PATCH] arm64: dts: meson-g12b-odroid-n2*: Add support for
 overclocking Hardkernel ODROID-N2 boards.
In-Reply-To: <1j8r3cet0i.fsf@starbuckisacylon.baylibre.com>
References: <20240222082523.1812-1-greena88@gmail.com>
 <1j8r3cet0i.fsf@starbuckisacylon.baylibre.com>
Message-ID: <32098130-cd5e-4bed-9bcd-155227c6008d@gmail.com>

On 22/02/2024 09:37, Jerome Brunet wrote:
> Patch title is too long - checkpatch.pl should have given a you warning
> for this.
> 
> Not sure it is wise support overclocking directly in mainline, not by
> default at least. Maybe as an overlay ? even this I'm not too sure.

Hi Jerome,

Appologies for this but checkpatch did not raise any issues re the
length of the commit message.

Overclocking is not enabled by default due to the turbo-mode bit
being set, it still requires the user to issue the following
command to activate.

echo "1" > /sys/devices/system/cpu/cpufreq/boost

It's also worth noting that regulator voltages have not been
upped to achieve this.

Lastly if the HK wiki is to be believed then the N2 (non-plus) is 
already overclocked in mainline.

Best regards,

Adam


From mripard at kernel.org  Thu Feb 22 02:26:03 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 11:26:03 +0100
Subject: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum
 rate
In-Reply-To: <874je6b2g4.fsf@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>
 <exb2lvjcozak5fayrgyenrd3ntii4jfxgvqork4klyz5pky2aq@dj2zyw5su6pv>
 <874je6b2g4.fsf@oltmanns.dev>
Message-ID: <3kbqdgbfn2nioch3gvofvj7pzx7f5gkuwx77u5nkgxao6qo654@3nvjifkrxcjb>

Hi,

On Sun, Feb 18, 2024 at 09:29:15AM +0100, Frank Oltmanns wrote:
> Hi Maxime,
> 
> On 2024-02-08 at 13:16:27 +0100, Maxime Ripard <mripard at kernel.org> wrote:
> > [[PGP Signed Part:Undecided]]
> > On Mon, Feb 05, 2024 at 04:22:26PM +0100, Frank Oltmanns wrote:
> >> According to the Allwinner User Manual, the Allwinner A64 requires
> >> PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.
> >>
> >> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> >> ---
> >>  drivers/clk/sunxi-ng/ccu_nkm.c | 13 +++++++++++++
> >>  drivers/clk/sunxi-ng/ccu_nkm.h |  2 ++
> >>  2 files changed, 15 insertions(+)
> >>
> >> diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> index 1168d894d636..7d135908d6e0 100644
> >> --- a/drivers/clk/sunxi-ng/ccu_nkm.c
> >> +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
> >> @@ -181,6 +181,12 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
> >>  	if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
> >>  		rate *= nkm->fixed_post_div;
> >>
> >> +	if (nkm->min_rate && rate < nkm->min_rate)
> >> +		rate = nkm->min_rate;
> >> +
> >> +	if (nkm->max_rate && rate > nkm->max_rate)
> >> +		rate = nkm->max_rate;
> >> +
> >
> > This is provided by the clock range already. If you call
> > clk_hw_set_rate_range, it should work just fine.
> 
> I have to admit, that I don't know that much about sunxi-ng or the CCF
> and therefore humbly request some guidance.
> 
> I've looked at other examples of clk_hw_set_rate_range() usage and it
> seems there is not a lot of adoption for this functionality even though
> it was already introduced mid-2015. This makes me wonder, why that is.

There's no reason, really. I would expect a big part of it to be "if it
works don't fix it" :)

> Anyhow, it seems in all examples I found, clk_hw_set_rate_range() is
> called immediately after registering the clk_hw. So, in the case of
> sunxi-ng, we'd need to do that in sunxi_ccu_probe, which is a common
> function for all sunxi-ng clock types. Correct?

Yup.

> If so, surely, you don't want me to introduce clock type specific code
> to a common function, so I assume you want min_rate and max_rate to
> become members of struct ccu_common. Correct?

Yes, that would be reasonable indeed.

> If so, since there already are some clock types in sunxi-ng that support
> having a minimum and maximum rate, these clocks should be refactored
> eventually. Correct?

I guess. I don't consider it to be a pre-requisite to your patch though.

> Finally, in sunxi-ng there is a feature of having a fixed_post_div (see,
> e.g., the first to lines of the diff above). It seems to me that CCF
> cannot know about these post_divs, so we'd also need to transfer the
> fixed_post_div to ccu_common and use that when calling
> clk_hw_set_rate_range. Correct?

Not really, no. The fixed post divider is an additional divider that
needs to be considered for the clock rate.

See the A64's periph0 PLL for example. Its fixed post divider is 2, and
its rate is 24MHz * N * K / 2. The rate should be bounded by its minimal
and maximal rate taking the post divider into account. The CCF doesn't
have to know about it.

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/20240222/0edf7234/attachment.sig>

From mripard at kernel.org  Thu Feb 22 02:28:02 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 11:28:02 +0100
Subject: [PATCH v2 3/6] clk: sunxi-ng: nkm: Support minimum and maximum
 rate
In-Reply-To: <8734tmhzkg.fsf@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-3-96a46a2d8c9b@oltmanns.dev>
 <8734tmhzkg.fsf@oltmanns.dev>
Message-ID: <ng2xdo7icjshbwlwy4sgaofibkg3e7qaotd2dnaq5zfizgub7s@b7egn5kd3ejf>

On Wed, Feb 21, 2024 at 11:38:39AM +0100, Frank Oltmanns wrote:
> Hi Jernej,
> hi Maxime,
> 
> On 2024-02-05 at 16:22:26 +0100, Frank Oltmanns <frank at oltmanns.dev> wrote:
> > According to the Allwinner User Manual, the Allwinner A64 requires
> > PLL-MIPI to run at 500MHz-1.4GHz. Add support for that to ccu_nkm.
> 
> I should point out that limiting PLL-MIPI also fixes a regression
> that was introduced in 6.5, specifically
> ca1170b69968233b34d26432245eddf7d265186b "clk: sunxi-ng: a64: force
> select PLL_MIPI in TCON0 mux". This has been bisected and reported by
> Diego [1].
> 
> I don't know the procedure (yet), but probably the fix (if and when
> accepted) should be backported at least to 6.6 (first broken LTS), 6.7
> (stable), and 6.8 (next stable).

https://www.kernel.org/doc/html/next/process/stable-kernel-rules.html#procedure-for-submitting-patches-to-the-stable-tree

> My suggestion:
>  - In V3 of this series, I will reorder the patches, so that what is now
>    PATCH 3 and 4 becomes 1 and 2 respectively, so that they can be
>    applied to 6.6 more easily.
>  - Maxime, IIUC you requested some refactoring for handling the rate
>    limits [2]. I propose, we use my current proposal as-is, and I will
>    do a follow-up series for the refactoring.

I'd really like to not introduce a new ad-hoc implementation of range
handling. It's fine for older users to not be converted yet, but we
shouldn't introduce more users.

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/20240222/f31c5c84/attachment-0001.sig>

From jesper.nilsson at axis.com  Thu Feb 22 02:28:08 2024
From: jesper.nilsson at axis.com (Jesper Nilsson)
Date: Thu, 22 Feb 2024 11:28:08 +0100
Subject: [PATCH v2] net: stmmac: mmc_core: Drop interrupt registers from
 stats
In-Reply-To: <55c1527f778ada6458dfc3d626d36e5367886dbb.camel@redhat.com>
References: <20240220-stmmac_stats-v2-1-0a78863bec70@axis.com>
 <55c1527f778ada6458dfc3d626d36e5367886dbb.camel@redhat.com>
Message-ID: <20240222102808.GY22484@axis.com>

On Thu, Feb 22, 2024 at 10:38:53AM +0100, Paolo Abeni wrote:
> On Tue, 2024-02-20 at 13:00 +0100, Jesper Nilsson wrote:
> > The MMC IPC interrupt status and interrupt mask registers are
> > of little use as Ethernet statistics, but incrementing counters
> > based on the current interrupt and interrupt mask registers
> > makes them actively misleading.
> > 
> > For example, if the interrupt mask is set to 0x08420842,
> > the current code will increment by that amount each iteration,
> > leading to the following sequence of nonsense:
> > 
> > mmc_rx_ipc_intr_mask: 969816526
> > mmc_rx_ipc_intr_mask: 1108361744
> > 
> > These registers have been included in the Ethernet statistics
> > since the first version of MMC back in 2011 (commit 1c901a46d57).
> > That commit also mentions the MMC interrupts as
> > "something to add later (if actually useful)".
> > 
> > If the registers are actually useful, they should probably
> > be part of the Ethernet register dump instead of statistics,
> > but for now, drop the counters for mmc_rx_ipc_intr and
> > mmc_rx_ipc_intr_mask completely.
> > 
> > Signed-off-by: Jesper Nilsson <jesper.nilsson at axis.com>
> 
> It looks like this could target the 'net' tree. Anyway it does not
> apply cleanly to 'net' nor 'net-next'. Could you please rebase &&
> repost, including Serge's tags and explicitly setting the target tree
> into the subj prefix?

Yeah, will do. My v1 patch applied cleanly to net-next,
but I didn't check the v2. My bad.

> Thanks!
> 
> Paolo

/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson at axis.com


From mripard at kernel.org  Thu Feb 22 02:29:51 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 11:29:51 +0100
Subject: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher
 clock rate
In-Reply-To: <87sf1zxb0s.fsf@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-5-96a46a2d8c9b@oltmanns.dev>
 <poua4bzyciiwt65sqjf2whqfdumvoe4h3bkjpf64px2vwgumrf@sai73byg2iju>
 <87sf1zxb0s.fsf@oltmanns.dev>
Message-ID: <ia7e7gqozltl5wkfdvwtf2rw2ko2dt67qxtuqbavsroyv4ifys@x4mbulqhhri5>

On Sun, Feb 11, 2024 at 04:42:43PM +0100, Frank Oltmanns wrote:
> 
> On 2024-02-08 at 20:05:08 +0100, Maxime Ripard <mripard at kernel.org> wrote:
> > [[PGP Signed Part:Undecided]]
> > Hi Frank,
> >
> > On Mon, Feb 05, 2024 at 04:22:28PM +0100, Frank Oltmanns wrote:
> >> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
> >> The SOC requires pll-mipi to run at more than 500 MHz.
> >>
> >> This is the relevant clock tree:
> >>  pll-mipi
> >>     tcon0
> >>        tcon-data-clock
> >>
> >> tcon-data-clock has to run at 1/4 the DSI per-lane bit rate. The XBD599
> >> has 24 bpp and 4 lanes. Therefore, the resulting requested
> >> tcon-data-clock rate is:
> >>     crtc_clock * 1000 * (24 / 4) / 4
> >>
> >> tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it requests a
> >> parent rate of
> >>     4 * (crtc_clock * 1000 * (24 / 4) / 4)
> >>
> >> Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate of pll-mipi.
> >>
> >> pll-mipi's constraint to run at 500MHz or higher forces us to have a
> >> crtc_clock >= 83333 kHz if we want a 60 Hz vertical refresh rate.
> >>
> >> Change [hv]sync_(start|end) so that we reach a clock rate of 83502 kHz
> >> so that it is high enough to align with pll-pipi limits.
> >>
> >> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> >
> > That commit log is great, but it's kind of off-topic. It's a panel
> > driver, it can be used on any MIPI-DSI controller, the only relevant
> > information there should be the panel timings required in the datasheet.
> >
> > The PLL setup is something for the MIPI-DSI driver to adjust, not for
> > the panel to care for.
> >
> 
> I absolutely agree. It even was the reason for my submission of a
> sunxi-ng patch series last year that was accepted, to make pll-mipi more
> flexible. :)
> 
> The only remaining option I currently see for adjusting the sunxi-ng
> driver to further accomodate the panel, is trying to use a higher
> divisor than 4 for calculating tcon-data-clock from tcon0. I remember
> reading a discussion about this, but as far as I remember that proposal
> was rejected (by you, IIRC).
> 
> While I appreciate other suggestion as well, I'll look into options for
> using a different divisor than 4.

Like I said, I'm not against the patch at all, it looks great to me on
principle. I just think you should completely rephrase the commit log
using the datasheet as the only reliable source of the display timings.
Whether sun4i can work around the panel requirements is something
completely orthogonal to the discussion, and thus the commit log.

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/20240222/f3febf9d/attachment.sig>

From geert+renesas at glider.be  Thu Feb 22 02:42:51 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 22 Feb 2024 11:42:51 +0100
Subject: [GIT PULL] Renesas fixes for v6.8
Message-ID: <cover.1708597150.git.geert+renesas@glider.be>

	Hi SoC folks,

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-fixes-for-v6.8-tag1

for you to fetch changes up to 8c987693dc2d292d777f1be63cb35233049ae25e:

  ARM: dts: renesas: rcar-gen2: Add missing #interrupt-cells to DA9063 nodes (2024-02-22 10:55:03 +0100)

----------------------------------------------------------------
Renesas fixes for v6.8

  - Add missing #interrupt-cells to DA9063 nodes.

Fast-tracked to avoid new dtc interrupt_provider warnings.

Thanks for pulling!

----------------------------------------------------------------
Geert Uytterhoeven (1):
      ARM: dts: renesas: rcar-gen2: Add missing #interrupt-cells to DA9063 nodes

 arch/arm/boot/dts/renesas/r8a7790-lager.dts   | 1 +
 arch/arm/boot/dts/renesas/r8a7790-stout.dts   | 1 +
 arch/arm/boot/dts/renesas/r8a7791-koelsch.dts | 1 +
 arch/arm/boot/dts/renesas/r8a7791-porter.dts  | 1 +
 arch/arm/boot/dts/renesas/r8a7792-blanche.dts | 1 +
 arch/arm/boot/dts/renesas/r8a7793-gose.dts    | 1 +
 arch/arm/boot/dts/renesas/r8a7794-alt.dts     | 1 +
 arch/arm/boot/dts/renesas/r8a7794-silk.dts    | 1 +
 8 files changed, 8 insertions(+)

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 geert at linux-m68k.org  Thu Feb 22 02:45:14 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 22 Feb 2024 11:45:14 +0100
Subject: linux-next: build warning after merge of the arm-soc-fixes tree
In-Reply-To: <CAMuHMdX0G90D4ifV1OVpjPX6q0d0UyMa5iu7-s+12KiAD9zL8w@mail.gmail.com>
References: <20240221092826.748e70c4@canb.auug.org.au> <CAL_JsqKw9OXb=aOMni1qprzeWDBgmjdJef-6VAjwx0R--D+URw@mail.gmail.com>
 <ac9ddf79-6bc9-4daf-a271-82f8b3bca988@app.fastmail.com> <CAL_Jsq+L7uPimQfATs14EWCbqRO1vxDUmPie7=cChTLCf2od2g@mail.gmail.com>
 <CAMuHMdXNyU0eBcMe3EhhfahcRo2KtXzwdr+d_6AC-2529R3bmQ@mail.gmail.com>
 <7178ea35-da8d-4f25-9193-78dd11902eef@app.fastmail.com> <CAMuHMdX0G90D4ifV1OVpjPX6q0d0UyMa5iu7-s+12KiAD9zL8w@mail.gmail.com>
Message-ID: <CAMuHMdU4qk0xY228uNoDpB5oQESc_MZzVf8hwXVL3penneBPKQ@mail.gmail.com>

Hi Arnd,

On Wed, Feb 21, 2024 at 5:36?PM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> On Wed, Feb 21, 2024 at 4:58?PM Arnd Bergmann <arnd at arndb.de> wrote:
> > On Wed, Feb 21, 2024, at 15:51, Geert Uytterhoeven wrote:
> > > On Wed, Feb 21, 2024 at 3:27?PM Rob Herring <robh at kernel.org> wrote:
> > >> On Wed, Feb 21, 2024 at 7:00?AM Arnd Bergmann <arnd at arndb.de> wrote:
> > >> > On Wed, Feb 21, 2024, at 14:53, Rob Herring wrote:
> > >> > > On Tue, Feb 20, 2024 at 3:28?PM Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> > >> > >> arch/arm/boot/dts/renesas/r8a7793-gose.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
> > >> > >>
> > >> > >> Introduced/exposed by commit
> > >> > >>
> > >> > >>   78b6f8e7379b ("dtc: Enable dtc interrupt_provider check")
> > >> > >>
> > >> > >> I guess you missed some :-(
> > >> > >
> > >> > > No, Geert separately posted fixes for already.
> > >> >
> > >> > I did make the mistake of applying the final patch "dtc:
> > >> > Enable dtc interrupt_provider check" to the arm/fixes branch
> > >> > for 6.8 along with the other fixes.
> > >> >
> > >> > Clearly that should be separate and only go into mainline
> > >> > after there are no more regressions, but now I'm unsure
> > >> > about the other patches -- did you intend the dts fixes
> > >> > for 6.8 or for the coming merge window?
> > >>
> > >> Either is fine with me. My intent was the whole series plus the
> > >> Renesas fix to be applied together. Anything new that crops up we can
> > >> fix on top.
> > >
> > > If you want me to move commit b4f97d1b5aeb6166 ("ARM: dts: renesas:
> > > rcar-gen2: Add missing #interrupt-cells to DA9063 nodes") to
> > > renesas-fixes, please tell me.
> >
> > Up to you. I have done some merges yesterday but have not started
> > merging the dt branches, so you can still send an updated v2
> > if you prefer (or have this patch in both branches). Please
> > let me know how you decide.
>
> OK, will move it to renesas-fixes.
> Note that b4f97d1b5aeb6166 was not included yet in the last PR
> I sent to soc, so you can continue merging DT branches.

Moved to renesas-fixes, and PR sent.

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 mripard at kernel.org  Thu Feb 22 02:54:04 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 11:54:04 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB property
In-Reply-To: <20240219140144.GB1956149@toolbox>
References: <hez2m57ogqx3yyqk45tzdkvxvhrbdepgm244i4m2aty2xhf5b5@acqgvmxhmmvr>
 <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
 <20240212170618.GA1372043@toolbox>
 <2mih3humepuedtli7ge52ncom4uffkqravdpalncgfyucmwdzc@bp5o7i3ky77a>
 <20240219140144.GB1956149@toolbox>
Message-ID: <euaujtp4jyyoud3ccg5qhyvixyq2p6vir4ojlzoky6kep754rj@wruidyfxssry>

On Mon, Feb 19, 2024 at 03:01:44PM +0100, Sebastian Wick wrote:
> On Thu, Feb 15, 2024 at 12:00:01PM +0100, Maxime Ripard wrote:
> > On Mon, Feb 12, 2024 at 06:06:18PM +0100, Sebastian Wick wrote:
> > > On Mon, Feb 12, 2024 at 05:53:48PM +0100, Maxime Ripard wrote:
> > > > On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> > > > > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > > > > > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > > > > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > > > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > > > > > Hi,
> > > > > > > > > > > > 
> > > > > > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > > > > > >  /**
> > > > > > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > > > > > >   *
> > > > > > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > + *      Full:
> > > > > > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > > > > > different things being affected:
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > > > > > signalling, what happens?
> > > > > > > > > > > > > 
> > > > > > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > > > > > YCbCr?
> > > > > > > > > > > > 
> > > > > > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > > > > > vc4 will follow the value of the property.
> > > > > > > > > > > 
> > > > > > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > > > > > That should explain why it's only affecting RGB.
> > > > > > > > > > 
> > > > > > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > > > > > itself.
> > > > > > > > > > 
> > > > > > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > > > > > to enable it.
> > > > > > > > > > 
> > > > > > > > > > vc4 supports it.
> > > > > > > > > 
> > > > > > > > > Someone implemented it incorrectly then.
> > > > > > > > 
> > > > > > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > > > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > > > > > document any of it, and when people try to clean things up they get told
> > > > > > > > that we got it all wrong.
> > > > > > > 
> > > > > > > FWIW, this was an i915 property and if another driver uses the same
> > > > > > > property name it must have the same behavior. Yes, it isn't standardized
> > > > > > > and yes, it's not documented (hence this effort here) but it's still on
> > > > > > > vc4 to make the property compatible.
> > > > > > 
> > > > > > How is it not compatible? It's a superset of what i915 provides, but
> > > > > > it's strictly compatible with it.
> > > > > 
> > > > > No it is not.
> > > > 
> > > > The property is compatible with i915 interpretation of it, whether you
> > > > like it or not. And that's what Sebastian was referring to.
> > > > 
> > > > > Eg. what happens if you set the thing to full range for RGB (which you
> > > > > must on many broken monitors), and then the kernel automagically
> > > > > switches to YCbCr (for whatever reason) but the monitor doesn't
> > > > > support full range YCbCr? Answer: you get crap output.
> > > > 
> > > > And that part is just moving goalposts.
> > > 
> > > But it's really not.
> > 
> > It really is. This whole discussion started by "well it would be nice if
> > we made that property handled by the core", and we're now at the "we
> > need to deal with broken YCbCr displays and i915 opinion about them"
> > stage. After creating documentation, unit tests, etc. It's the textbook
> > definition of moving goalposts. And while i915 won't be affected by all
> > that work.
> 
> Sorry, but what you're saying is just not true.
> 
> The Broadcast RGB property is an Intel specific property.

No, it's not. vc4 has been using it for a year now.

> It lacked documentation but the user space contract exists and it
> based on how i915 implemented it. By changing the semantics you're
> breaking user space. The documentation has to document the current
> contract between i915 and user space, not whatever you want the
> property to be like.
> 
> I get that you're frustrated that you have to do work while i915 doesn't
> but none of that is relevant for what the property is and how user space
> expects it to work.

That's not it, really. I don't mind doing the work. I do mind losing
functionalities on something that was working fine. And getting the
blame for something that is, at best, just as much of an documentation
issue on i915 devs.

> > That series has been stuck for multiple iterations on pointless and
> > mundane debates while the biggest part and whole point of it is not
> > getting any review. So yeah, sorry, it's frustrating.
> 
> I'm reviewing the parts that I can, and that's the uAPI. I find it
> really offensive that you're saying that this is pointless and mundate.

I'm sorry I offended you, but I was talking about the whole debate
itself, not the uAPI. The uAPI itself exists. It's already there, it's
used in the wild on several drivers, and several user-space components.

What that patch does is trying to document it, and test it. It's a net
benefit. Is it perfect? Probably not.

It's a net benefit nonetheless. The part where I mostly disagree with
you I guess (and what we've actually been arguing obut) is trying to get
something perfect (to the best of our knowledge) out of it.

Anyway, I'll just shut up and to do the work I guess.

> The uAPI is your end product, if it can't be used, everything you do in
> your driver is utterly pointless.
> 
> > > The Broadcast RGB property kind of works from a user space perspective
> > > because it's a workaround for broken sinks. If a sink expects limited
> > > range we can force full range. If this however affects YCbCr modes as
> > > well, then this isn't a workaround for broken RGB range anymore
> > > because it now breaks YCbCr.
> > 
> > Or, you know, it's a workaround for broken YCbCr display.
> 
> Displays can accept both RGB and YCbCr signals, drivers can chose
> whichever they want, and user space can not influence or even know which
> one is being used.
> 
> The automatic selection of the range is very different between RGB and
> YCbCr. If user space forces the range to a specific value and the driver
> for whatever reason switches from RGB to YCbCr or the other way around,
> this forcing of the range will most likely be incorrect.
> 
> This is what we're talking about when we say that the semantics of the
> vc4 Broadcast RGB property is broken. User space literally cannot use it
> consistenly. By restricting it to RGB signals, user space can user it
> consistently and fix monitors that do not follow the automatic
> quantization range algorithm correctly. Yes, if there is an issue with
> the quantization range of a YCbCr signal then this property doesn't
> help, but it never tried to help those cases.

Ack, 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/20240222/7d01c8bc/attachment.sig>

From mark.rutland at arm.com  Thu Feb 22 02:59:51 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 22 Feb 2024 10:59:51 +0000
Subject: [PATCH] arm64: add early fixmap initialization flag
In-Reply-To: <ZdUyOAQG0TK1UtTY@vm3>
References: <20240217140326.2367186-1-skseofh@gmail.com>
 <ZdMx-svsHgrfguxX@FVFF77S0Q05N>
 <ZdPyWkOlUan5AI9r@vm3>
 <ZdSTMgxcWYsT9ECs@FVFF77S0Q05N.cambridge.arm.com>
 <ZdUyOAQG0TK1UtTY@vm3>
Message-ID: <ZdcpJ2zoyHJuNkSD@FVFF77S0Q05N>

On Wed, Feb 21, 2024 at 08:14:00AM +0900, Itaru Kitayama wrote:
> On Tue, Feb 20, 2024 at 11:55:30AM +0000, Mark Rutland wrote:
> > From 5f07f9c1d352f760fa7aba97f1b4f42d9cb99496 Mon Sep 17 00:00:00 2001
> > From: Mark Rutland <mark.rutland at arm.com>
> > Date: Tue, 20 Feb 2024 11:09:17 +0000
> > Subject: [PATCH] arm64: clean up fixmap initalization
> > 
> > Currently we have redundant initialization of the fixmap, first in
> > early_fdt_map(), and then again in setup_arch() before we call
> > early_ioremap_init(). This redundant initialization isn't harmful, as
> > early_fixmap_init() happens to be idempotent, but it's redundant and
> > potentially confusing.
> > 
> > We need to call early_fixmap_init() before we map the FDT and before we
> > call early_ioremap_init(). Ideally we'd place early_fixmap_init() and
> > early_ioremap_init() in the same caller as early_ioremap_init() is
> > somewhat coupled with the fixmap code.
> > 
> > Clean this up by moving the calls to early_fixmap_init() and
> > early_ioremap_init() into a new early_mappings_init() function, and
> > calling this once in __primary_switched() before we call
> > early_fdt_map(). This means we initialize the fixmap once, and keep
> > early_fixmap_init() and early_ioremap_init() together.

> Thanks for this. Makes sense to me; would you post a proper patch
> so I can build and do a boot test, just to make sure?

I took a look, and Ard's recent changes to the boot code have removed the
duplicate call to early_fixmap_init() by other means, so we don't need to do
anything, and can forget about this patch. :)

Mark.


From brgl at bgdev.pl  Thu Feb 22 03:00:14 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 22 Feb 2024 12:00:14 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAA8EJppWY8c-pF75WaMadWtEuaAyCc5A1VLEq=JmB2Ngzk-zyw@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org> <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org> <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
 <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
 <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com>
 <b9a31374-8ea9-407e-9ec3-008a95e2b18b@linaro.org> <CAA8EJppWY8c-pF75WaMadWtEuaAyCc5A1VLEq=JmB2Ngzk-zyw@mail.gmail.com>
Message-ID: <CAMRc=Md6SoXukoGb4bW-CSYgjpO4RL+0Uu3tYrZzgSgVtFH6Sw@mail.gmail.com>

On Mon, Feb 19, 2024 at 11:21?PM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Mon, 19 Feb 2024 at 19:18, <neil.armstrong at linaro.org> wrote:
> >
> > On 19/02/2024 13:33, Dmitry Baryshkov wrote:
> > > On Mon, 19 Feb 2024 at 14:23, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> > >>
> > >> On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
> > >> <dmitry.baryshkov at linaro.org> wrote:
> > >>>
> > >>
> > >> [snip]
> > >>
> > >>>>>>>>
> > >>>>>>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> > >>>>>>>> necessary. The BT and WLAN devices on the device-tree are represented as
> > >>>>>>>> consuming the inputs (relevant to the functionality of each) of the PMU
> > >>>>>>>> directly.
> > >>>>>>>
> > >>>>>>> We are describing the hardware. From the hardware point of view, there
> > >>>>>>> is a PMU. I think at some point we would really like to describe all
> > >>>>>>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> > >>>>>>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
> > >>>>>>
> > >>>>>> While I agree with older WiFi+BT units, I don't think it's needed for
> > >>>>>> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
> > >>>>>> transparent.
> > >>>>>
> > >>>>> I don't see any significant difference between WCN6750/WCN6855 and
> > >>>>> WCN7850 from the PMU / power up point of view. Could you please point
> > >>>>> me to the difference?
> > >>>>>
> > >>>>
> > >>>> The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
> > >>>> and BT_EN ordering and the only requirement is to have all input regulators
> > >>>> up before pulling up WLAN_EN and/or BT_EN.
> > >>>>
> > >>>> This makes the PMU transparent and BT and WLAN can be described as independent.
> > >>>
> > >>>  From the hardware perspective, there is a PMU. It has several LDOs. So
> > >>> the device tree should have the same style as the previous
> > >>> generations.
> > >>>
> > >>
> > >> My thinking was this: yes, there is a PMU but describing it has no
> > >> benefit (unlike QCA6x90). If we do describe, then we'll end up having
> > >> to use pwrseq here despite it not being needed because now we won't be
> > >> able to just get regulators from WLAN/BT drivers directly.
> > >>
> > >> So I also vote for keeping it this way. Let's go into the package
> > >> detail only if it's required.
> > >
> > > The WiFi / BT parts are not powered up by the board regulators. They
> > > are powered up by the PSU. So we are not describing it in the accurate
> > > way.
> >
> > I disagree, the WCN7850 can also be used as a discrete PCIe M.2 card, and in
> > this situation the PCIe part is powered with the M.2 slot and the BT side
> > is powered separately as we currently do it now.
>
> QCA6390 can also be used as a discrete M.2 card.
>
> > So yes there's a PMU, but it's not an always visible hardware part, from the
> > SoC PoV, only the separate PCIe and BT subsystems are visible/controllable/powerable.
>
> From the hardware point:
> - There is a PMU
> - The PMU is connected to the board supplies
> - Both WiFi and BT parts are connected to the PMU
> - The BT_EN / WLAN_EN pins are not connected to the PMU
>
> So, not representing the PMU in the device tree is a simplification.
>

What about the existing WLAN and BT users of similar packages? We
would have to deprecate a lot of existing bindings. I don't think it's
worth it.

The WCN7850 is already described in bindings as consuming what is PMUs
inputs and not its outputs.

Bart

> >
> > Neil
> >
> > >
> > > Moreover, I think we definitely want to move BT driver to use only the
> > > pwrseq power up method. Doing it in the other way results in the code
> > > duplication and possible issues because of the regulator / pwrseq
> > > taking different code paths.
>
> --
> With best wishes
> Dmitry


From joao.m.martins at oracle.com  Thu Feb 22 03:04:07 2024
From: joao.m.martins at oracle.com (Joao Martins)
Date: Thu, 22 Feb 2024 11:04:07 +0000
Subject: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty tracking
 in domain alloc
In-Reply-To: <20240222094923.33104-4-shameerali.kolothum.thodi@huawei.com>
References: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
 <20240222094923.33104-4-shameerali.kolothum.thodi@huawei.com>
Message-ID: <a47699c9-4f3d-4cd0-94f4-f19e117ea6a3@oracle.com>

On 22/02/2024 09:49, Shameer Kolothum wrote:
> From: Joao Martins <joao.m.martins at oracle.com>
> 
> This provides all the infrastructure to enable dirty tracking if the
> hardware has the capability and domain alloc request for it.
> 
> Please note, we still report no support for IOMMU_CAP_DIRTY_TRACKING
> as it will finally be enabled in a subsequent patch.
> 
> Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 95 ++++++++++++++++-----
>  include/linux/io-pgtable.h                  |  4 +
>  2 files changed, 77 insertions(+), 22 deletions(-)
> 
> 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 bd30739e3588..058bbb0dbe2e 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -43,6 +43,7 @@ MODULE_PARM_DESC(disable_msipolling,
>  	"Disable MSI-based polling for CMD_SYNC completion.");
>  
>  static struct iommu_ops arm_smmu_ops;
> +static struct iommu_dirty_ops arm_smmu_dirty_ops;
>  
>  enum arm_smmu_msi_index {
>  	EVTQ_MSI_INDEX,
> @@ -86,7 +87,8 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
>  
>  static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu);
>  static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
> -				    struct arm_smmu_device *smmu);
> +				    struct arm_smmu_device *smmu,
> +				    bool enable_dirty);
>  static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
>  static void arm_smmu_tlb_inv_all_s2(struct arm_smmu_domain *smmu_domain);
>  
> @@ -2378,7 +2380,7 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
>  		struct arm_smmu_master *master = dev_iommu_priv_get(dev);
>  		int ret;
>  
> -		ret = arm_smmu_domain_finalise(smmu_domain, master->smmu);
> +		ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, false);
>  		if (ret) {
>  			kfree(smmu_domain);
>  			return ERR_PTR(ret);
> @@ -2445,10 +2447,11 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
>  }
>  
>  static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
> -				    struct arm_smmu_device *smmu)
> +				    struct arm_smmu_device *smmu,
> +				    bool enable_dirty)
>  {
>  	int ret;
> -	unsigned long ias, oas;
> +	unsigned long ias;
>  	enum io_pgtable_fmt fmt;
>  	struct io_pgtable_cfg pgtbl_cfg;
>  	struct io_pgtable_ops *pgtbl_ops;
> @@ -2459,31 +2462,31 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
>  	if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
>  		smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
>  
> +	pgtbl_cfg = (struct io_pgtable_cfg) {
> +		.pgsize_bitmap	= smmu->pgsize_bitmap,
> +		.coherent_walk	= smmu->features & ARM_SMMU_FEAT_COHERENCY,
> +		.tlb		= &arm_smmu_flush_ops,
> +		.iommu_dev	= smmu->dev,
> +	};
> +
>  	switch (smmu_domain->stage) {
>  	case ARM_SMMU_DOMAIN_S1:
>  		ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
> -		ias = min_t(unsigned long, ias, VA_BITS);
> -		oas = smmu->ias;
> +		pgtbl_cfg.ias = min_t(unsigned long, ias, VA_BITS);
> +		pgtbl_cfg.oas = smmu->ias;
> +		if (enable_dirty)
> +			pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_HD;
>  		fmt = ARM_64_LPAE_S1;
>  		break;
>  	case ARM_SMMU_DOMAIN_S2:
> -		ias = smmu->ias;
> -		oas = smmu->oas;
> +		pgtbl_cfg.ias = smmu->ias;
> +		pgtbl_cfg.oas = smmu->oas;
>  		fmt = ARM_64_LPAE_S2;
>  		break;
>  	default:
>  		return -EINVAL;
>  	}
>  
> -	pgtbl_cfg = (struct io_pgtable_cfg) {
> -		.pgsize_bitmap	= smmu->pgsize_bitmap,
> -		.ias		= ias,
> -		.oas		= oas,
> -		.coherent_walk	= smmu->features & ARM_SMMU_FEAT_COHERENCY,
> -		.tlb		= &arm_smmu_flush_ops,
> -		.iommu_dev	= smmu->dev,
> -	};
> -
>  	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
>  	if (!pgtbl_ops)
>  		return -ENOMEM;
> @@ -2491,7 +2494,8 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
>  	smmu_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
>  	smmu_domain->domain.geometry.aperture_end = (1UL << pgtbl_cfg.ias) - 1;
>  	smmu_domain->domain.geometry.force_aperture = true;
> -
> +	if (enable_dirty && smmu_domain->stage == ARM_SMMU_DOMAIN_S1)
> +		smmu_domain->domain.dirty_ops = &arm_smmu_dirty_ops;
>  	ret = arm_smmu_domain_alloc_id(smmu, smmu_domain);
>  	if (ret < 0) {
>  		free_io_pgtable_ops(pgtbl_ops);
> @@ -2811,7 +2815,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
>  	mutex_lock(&smmu_domain->init_mutex);
>  
>  	if (!smmu_domain->smmu) {
> -		ret = arm_smmu_domain_finalise(smmu_domain, smmu);
> +		ret = arm_smmu_domain_finalise(smmu_domain, smmu, false);
>  	} else if (smmu_domain->smmu != smmu)
>  		ret = -EINVAL;
>  


I think we are missing the domain attach_dev check for dirty tracking.

Something like:

if (domain->dirty_ops && !arm_smmu_dbm_capable(smmu))
	return -EINVAL;

But that helper is only introduced in the last patch, so maybe:

if (domain->dirty_ops &&
    !device_iommu_capable(dev, IOMMU_CAP_DIRTY_TRACKING))
	return -EINVAL;

> @@ -2876,7 +2880,7 @@ static int arm_smmu_s1_set_dev_pasid(struct iommu_domain *domain,
>  
>  	mutex_lock(&smmu_domain->init_mutex);
>  	if (!smmu_domain->smmu)
> -		ret = arm_smmu_domain_finalise(smmu_domain, smmu);
> +		ret = arm_smmu_domain_finalise(smmu_domain, smmu, false);
>  	else if (smmu_domain->smmu != smmu)
>  		ret = -EINVAL;
>  	mutex_unlock(&smmu_domain->init_mutex);
> @@ -3193,7 +3197,9 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
>  			   const struct iommu_user_data *user_data)
>  {
>  	struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> -	const u32 paging_flags = IOMMU_HWPT_ALLOC_NEST_PARENT;
> +	const u32 paging_flags = IOMMU_HWPT_ALLOC_NEST_PARENT |
> +				 IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
> +	bool enforce_dirty = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
>  	struct arm_smmu_domain *smmu_domain;
>  	int ret;
>  
> @@ -3206,6 +3212,10 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
>  	if (user_data)
>  		return ERR_PTR(-EINVAL);
>  
> +	if (enforce_dirty &&
> +	    !device_iommu_capable(dev, IOMMU_CAP_DIRTY_TRACKING))
> +		return ERR_PTR(-EOPNOTSUPP);
> +
>  	smmu_domain = arm_smmu_domain_alloc();
>  	if (!smmu_domain)
>  		return ERR_PTR(-ENOMEM);
> @@ -3221,7 +3231,7 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
>  
>  	smmu_domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
>  	smmu_domain->domain.ops = arm_smmu_ops.default_domain_ops;
> -	ret = arm_smmu_domain_finalise(smmu_domain, master->smmu);
> +	ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, enforce_dirty);
>  	if (ret)
>  		goto err_free;
>  	return &smmu_domain->domain;
> @@ -3470,6 +3480,42 @@ static void arm_smmu_release_device(struct device *dev)
>  	kfree(master);
>  }
>  
> +static int arm_smmu_read_and_clear_dirty(struct iommu_domain *domain,
> +					 unsigned long iova, size_t size,
> +					 unsigned long flags,
> +					 struct iommu_dirty_bitmap *dirty)
> +{
> +	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> +	struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
> +
> +	if (smmu_domain->stage != ARM_SMMU_DOMAIN_S1)
> +		return -EINVAL;
> +
> +	if (WARN_ON_ONCE(!ops || !ops->read_and_clear_dirty))
> +		return -ENODEV;
> +
> +	return ops->read_and_clear_dirty(ops, iova, size, flags, dirty);
> +}
> +
> +static int arm_smmu_set_dirty_tracking(struct iommu_domain *domain,
> +				       bool enabled)
> +{
> +	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> +	struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
> +
> +	if (smmu_domain->stage != ARM_SMMU_DOMAIN_S1)
> +		return -EINVAL;
> +
> +	if (WARN_ON_ONCE(!ops))
> +		return -ENODEV;
> +
> +	/*
> +	 * Always enabled and the dirty bitmap is cleared prior to
> +	 * set_dirty_tracking().
> +	 */
> +	return 0;
> +}
> +
>  static struct iommu_group *arm_smmu_device_group(struct device *dev)
>  {
>  	struct iommu_group *group;
> @@ -3612,6 +3658,11 @@ static struct iommu_ops arm_smmu_ops = {
>  	}
>  };
>  
> +static struct iommu_dirty_ops arm_smmu_dirty_ops = {
> +	.read_and_clear_dirty	= arm_smmu_read_and_clear_dirty,
> +	.set_dirty_tracking     = arm_smmu_set_dirty_tracking,
> +};
> +
>  /* Probing and initialisation functions */
>  static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
>  				   struct arm_smmu_queue *q,
> diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
> index 86cf1f7ae389..8e75f944f07a 100644
> --- a/include/linux/io-pgtable.h
> +++ b/include/linux/io-pgtable.h
> @@ -85,6 +85,8 @@ struct io_pgtable_cfg {
>  	 *
>  	 * IO_PGTABLE_QUIRK_ARM_OUTER_WBWA: Override the outer-cacheability
>  	 *	attributes set in the TCR for a non-coherent page-table walker.
> +	 *
> +	 * IO_PGTABLE_QUIRK_ARM_HD: Enables dirty tracking in stage 1 pagetable.
>  	 */
>  	#define IO_PGTABLE_QUIRK_ARM_NS			BIT(0)
>  	#define IO_PGTABLE_QUIRK_NO_PERMS		BIT(1)
> @@ -92,6 +94,8 @@ struct io_pgtable_cfg {
>  	#define IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT	BIT(4)
>  	#define IO_PGTABLE_QUIRK_ARM_TTBR1		BIT(5)
>  	#define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA		BIT(6)
> +	#define IO_PGTABLE_QUIRK_ARM_HD			BIT(7)
> +
>  	unsigned long			quirks;
>  	unsigned long			pgsize_bitmap;
>  	unsigned int			ias;



From joey.gouly at arm.com  Thu Feb 22 03:05:10 2024
From: joey.gouly at arm.com (Joey Gouly)
Date: Thu, 22 Feb 2024 11:05:10 +0000
Subject: [PATCH 05/13] KVM: arm64: nv: Add trap forwarding for ERET and
 SMC
In-Reply-To: <20240219092014.783809-6-maz@kernel.org>
References: <20240219092014.783809-1-maz@kernel.org>
 <20240219092014.783809-6-maz@kernel.org>
Message-ID: <20240222110510.GA945329@e124191.cambridge.arm.com>

On Mon, Feb 19, 2024 at 09:20:06AM +0000, Marc Zyngier wrote:
> Honor the trap forwarding bits for both ERET and SMC, using a new
> helper that checks for common conditions.
> 
> Co-developed-by: Jintack Lim <jintack.lim at linaro.org>
> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---

Reviewed-by: Joey Gouly <joey.gouly at arm.com>

>  arch/arm64/include/asm/kvm_nested.h |  1 +
>  arch/arm64/kvm/emulate-nested.c     | 27 +++++++++++++++++++++++++++
>  arch/arm64/kvm/handle_exit.c        |  7 +++++++
>  3 files changed, 35 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> index c77d795556e1..dbc4e3a67356 100644
> --- a/arch/arm64/include/asm/kvm_nested.h
> +++ b/arch/arm64/include/asm/kvm_nested.h
> @@ -60,6 +60,7 @@ static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
>  	return ttbr0 & ~GENMASK_ULL(63, 48);
>  }
>  
> +extern bool forward_smc_trap(struct kvm_vcpu *vcpu);
>  
>  int kvm_init_nv_sysregs(struct kvm *kvm);
>  
> diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
> index 4697ba41b3a9..2d80e81ae650 100644
> --- a/arch/arm64/kvm/emulate-nested.c
> +++ b/arch/arm64/kvm/emulate-nested.c
> @@ -2117,6 +2117,26 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
>  	return true;
>  }
>  
> +static 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 (!is_hyp_ctxt(vcpu) && control_bit_set) {
> +		kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
> +		return true;
> +	}
> +	return false;
> +}
> +
> +bool forward_smc_trap(struct kvm_vcpu *vcpu)
> +{
> +	return forward_traps(vcpu, HCR_TSC);
> +}
> +
>  static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)
>  {
>  	u64 mode = spsr & PSR_MODE_MASK;
> @@ -2155,6 +2175,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_traps(vcpu, HCR_NV))
> +		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 0646c623d1da..1ccdfe40c691 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -55,6 +55,13 @@ static int handle_hvc(struct kvm_vcpu *vcpu)
>  
>  static int handle_smc(struct kvm_vcpu *vcpu)
>  {
> +	/*
> +	 * Forward this trapped smc instruction to the virtual EL2 if
> +	 * the guest has asked for it.
> +	 */
> +	if (forward_smc_trap(vcpu))
> +		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

Thanks,
Joey


From krzysztof.kozlowski at linaro.org  Thu Feb 22 03:13:39 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 12:13:39 +0100
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>
References: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
 <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
 <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
 <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>
Message-ID: <e6f6070e-8355-4a0b-a904-1a24970f249b@linaro.org>

On 21/02/2024 18:00, Ghennadi Procopciuc wrote:
> On 2/21/24 17:43, Krzysztof Kozlowski wrote:
>> On 21/02/2024 16:19, Ghennadi Procopciuc wrote:
>>> On 2/21/24 16:45, Krzysztof Kozlowski wrote:
>>>> On 21/02/2024 15:42, Krzysztof Kozlowski wrote:
>>>>> On 21/02/2024 13:01, Ghennadi Procopciuc wrote:
>>>>>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>>>>>
>>>>>> Add myself as a maintainer of the NXP S32G DT files.
>>>>>
>>>>> No need for cover letters for single patches. OTOH, this commit msg is
>>>>> empty...
>>> Thank you, I can correct that.
>>>
>>>>> Plus your patch looks corrupted (wrong encoding): F??rber
>>>
>>> Indeed, it is due to 'Content-Type: text/plain; charset="us-ascii"'.
>>> I can fix this as part of v2.
>>>
>>>>> BTW, did you contribute anything to the upstream Linux kernel? Do you
>>>>> know the process? Downstream does not really matter.
>>>>
>>>> I found the answer:
>>>>
>>>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>>> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
>>>>
>>>> Does not look like. Please get some upstream work experience first.
>>>>
>>>> https://lore.kernel.org/all/?q=f%3Aghennadi.procopciuc%40oss.nxp.com
>>>
>>> Although I am new to upstream communities and may make mistakes, I am
>>> eager to learn and improve.
>>>
>>> After leaving SuSe[0], the current maintainer of the NXP S32G DT files
>>> became inactive[1]. As a result, this area is not currently being
>>> maintained. This is the actual reason why I attempted to add myself as a
>>> maintainer of that area. Although I acknowledge that I may not have
>>> enough experience to become a maintainer, I am concerned that the NXP
>>> S32G DT patch submission may be blocked for everyone due to the current
>>> situation.
>>
>> I would be just happy to see first actual contributions or any sort of
>> activity, like reviewing, before taking over something.
>>
>> You do not need to become maintainer to provide reviews. By reviewing
>> patches you already reduce burden/work from the maintainers.
>>
>> Best regards,
>> Krzysztof
>>
> 
> I fully understand and agree with your perspective on this matter and
> accept the fact that I will not be a maintainer as initially intended.
> Furthermore, I am very willing to participate in any reviews related to
> S32G SoCs.

Just give it some time...

> 
> Patches, including those I have created ([0], [1]), will likely be
> submitted for this area. This is because each enabled driver for S32G
> SoCs is expected to have at least one node in the device tree. These
> patches will undergo review and receive feedback. However, the upstream
> process will come to a halt at this point since there are no maintainers
> to apply and integrate them.?

Indeed that's a problem.

> 
> I do not know how this situation should be handled, given my lack of
> experience in upstreaming maintenance. The documentation for the Linux
> kernel is insufficient in providing guidance [2] on how to handle
> inactive maintainers and it is unclear who should take over their
> responsibilities. This is likely not the first time this has happened in
> the kernel's history.
> 
> Could you please guide me on how these patches should be integrated into
> a maintainer's? tree and by whom?

Chester left Suse, so maybe this also means less interest in maintaining
it? Stepping up in such case, so your proposal, is reasonable, so in
general I agree and thank you for trying to do something here.

Andreas or Matthias,
Maybe you could change your R: into M: and take s32g patches?

If not, then I will ack this patch making Ghennadi the maintainer.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb 22 03:17:36 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 12:17:36 +0100
Subject: [PATCH v2] arm64: defconfig: Enable zram, xfs and loading
 compressed FW support
In-Reply-To: <87r0h47tlp.fsf@minerva.mail-host-address-is-not-set>
References: <20240221141350.3740488-1-javierm@redhat.com>
 <1f28256c-e436-4add-aa67-2cfb2248b220@linaro.org>
 <6scz7iti3tzzrd4ph3gnuc2pvkcbtuuicgfgujh3pa3c34kdkt@bhfa4xbxeu7t>
 <cb8bf006-57df-494e-80f3-947582ec71f1@linaro.org>
 <fy3wffb2jwv4veo3golfn5olri77clxywbuwuokese7sbobixd@mird5k66cl2w>
 <9083c414-62f2-4bff-93ee-13f8ff60eb34@linaro.org>
 <874je1ipb4.fsf@minerva.mail-host-address-is-not-set>
 <bd071521-7f7b-41e8-8786-ad2eeb58b03e@linaro.org>
 <87r0h47tlp.fsf@minerva.mail-host-address-is-not-set>
Message-ID: <87f2c94b-fbda-4a7d-8570-2c5a15964546@linaro.org>

On 22/02/2024 10:09, Javier Martinez Canillas wrote:
> Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org> writes:
> 
>> On 21/02/2024 20:34, Javier Martinez Canillas wrote:
> 
> [...]
> 
>>>>
>>>> Any explanation what ZRAM is necessary for Fedora to boot.
>>>>
>>>
>>> I mentioned already in another email, Fedora is enabling the systemd
>>> zram-generator and not having a /dev/zram0 slows down the boot to the
>>> point of being unusable. One could disable that service but then is yet
>>
>> That one sentence would be enough for me.
>>
> 
> I'll add that then to the commit message when proposing a config fragment.
> 
> [...]

Thanks.

> 
>>>
>>> So that means that for aarch64, some filesystems have more precedence over
>>> others? It's OK to have ext4 or btrfs but no xfs? Honestly it seems quite
>>> arbitrary and subjective for me.
>>
>> Yes, subjective, but to be honest: I would drop Btrfs. I was thinking
> 
> Fair. If the agreegment is to minimize defconfig (which AFAIU is your
> point), then I'm on board with it. We can start splitting in separate
> fragments, people can then mix and match for their specific use cases.
> 
>> about it, but since Arnd agrees on XFS I won't fight that battle.
>>
> 
> Yeah, it was a strange hill for me to die on and is true that fragments
> seems to be the best compromise, as Maxime said before in this thread.
> 
> By the way, I want to apologize for my harsh/rude comments yesterday. I
> wasn't in the best mood and I got too emotional...

No worries, I did not notice. Everything seemed fine for me.

Best regards,
Krzysztof



From liuyuntao12 at huawei.com  Thu Feb 22 03:24:30 2024
From: liuyuntao12 at huawei.com (liuyuntao (F))
Date: Thu, 22 Feb 2024 19:24:30 +0800
Subject: [PATCH -next] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
In-Reply-To: <30b01c65-12f2-4ee0-81d5-c7a2da2c36b4@app.fastmail.com>
References: <20240220081527.23408-1-liuyuntao12@huawei.com>
 <1342759e-b967-4ec4-98d5-48146f81f695@app.fastmail.com>
 <38c09a4b-69cc-4dc5-8a68-e5f5597613ac@huawei.com>
 <30b01c65-12f2-4ee0-81d5-c7a2da2c36b4@app.fastmail.com>
Message-ID: <4e9396ca-460b-49ca-818e-73f0a8997b15@huawei.com>



On 2024/2/21 23:51, Arnd Bergmann wrote:
> I have given your patch some build testing with random
> configurations in my build setup and it seems to work
> fine with gcc/binutils, but unfortunately I came across
> a link failure using clang/lld:
> 
> ld.lld: error: ./arch/arm/kernel/vmlinux.lds:35: ( expected, but got }
>>>>   __vectors_lma = .; OVERLAY 0xffff0000 : AT(__vectors_lma) { .vectors { KEEP(*(.vectors)) } .vectors.bhb.loop8 { KEEP(*(.vectors.bhb.loop8)) } .vectors.bhb.bpiall { KEEP(*(.vectors.bhb.bpiall)) } } __vectors_start = LOADADDR(.vectors); __vectors_end = LOADADDR(.vectors) + SIZEOF(.vectors); __vectors_bhb_loop8_start = LOADADDR(.vectors.bhb.loop8); __vectors_bhb_loop8_end = LOADADDR(.vectors.bhb.loop8) + SIZEOF(.vectors.bhb.loop8); __vectors_bhb_bpiall_start = LOADADDR(.vectors.bhb.bpiall); __vectors_bhb_bpiall_end = LOADADDR(.vectors.bhb.bpiall) + SIZEOF(.vectors.bhb.bpiall); . = __vectors_lma + SIZEOF(.vectors) + SIZEOF(.vectors.bhb.loop8) + SIZEOF(.vectors.bhb.bpiall); __stubs_lma = .; .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { *(.stubs) } __stubs_start = LOADADDR(.stubs); __stubs_end = LOADADDR(.stubs) + SIZEOF(.stubs); . = __stubs_lma + SIZEOF(.stubs); PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors));
>>>>                                                                                            ^
> 
> I don't immediately see what the problem is here, I hope you
> can address it before you send a v2.
> 
>       Arnd

I reproduced this issue with make LLVM=1 ARCH=arm -j320 > ../make.txt.
Based on the position of the caret, I speculate that the issue arises from
lld's inability to recognize the KEEP() command preceding the OUTPUT
section in the OVERLAY command.
 >
The full syntax of the OVERLAY command is as follows: OVERLAY [start] : 
[NOCROSSREFS] [AT ( ldaddr )] { secname1 { output-section-command 
output-section-command ? } [:phdr?] [=fill] secname2 { 
output-section-command output-section-command ? } [:phdr?] [=fill] ? } 
[>region] [:phdr?] [=fill] [,]
 >
I attempted to modify KEEP(*(.vectors)) to KEEP(*(.vectors))(.vectors),
and received the following error message:
ld.lld: error: ./arch/arm/kernel/vmlinux.lds:36: ( expected, but got } > 
__vectors_lma = .; OVERLAY 0xffff0000 : AT(__vectors_lma) { .vectors { 
KEEP(*(.vectors))(.vectors) } .vectors.bhb.loop8 { 
KEEP(*(.vectors.bhb.loop8)) } .vectors.bhb.bpiall { 
KEEP(*(.vectors.bhb.bpiall)) } } __vectors_start = LOADADDR(.vectors); 
__vectors_end = LOADADDR(.vectors) + SIZEOF(.vectors); 
__vectors_bhb_loop8_start = LOADADDR(.vectors.bhb.loop8); 
__vectors_bhb_loop8_end = LOADADDR(.vectors.bhb.loop8) + 
SIZEOF(.vectors.bhb.loop8); __vectors_bhb_bpiall_start = 
LOADADDR(.vectors.bhb.bpiall); __vectors_bhb_bpiall_end = 
LOADADDR(.vectors.bhb.bpiall) + SIZEOF(.vectors.bhb.bpiall); . = 
__vectors_lma + SIZEOF(.vectors) + SIZEOF(.vectors.bhb.loop8) + 
SIZEOF(.vectors.bhb.bpiall); __stubs_lma = .; .stubs ADDR(.vectors) + 
0x1000 : AT(__stubs_lma) { *(.stubs) } __stubs_start = LOADADDR(.stubs); 
__stubs_end = LOADADDR(.stubs) + SIZEOF(.stubs); . = __stubs_lma + 
SIZEOF(.stubs); PROVIDE(vector_fiq_offset = vector_fiq - 
ADDR(.vectors)); > ^
The position of the caret has been moved below the right brace
of { KEEP(*(.vectors.bhb.loop8)) }, indicating that lld is treating
the entire `KEEP(*(.vectors))` as a file name. This could potentially be 
a bug in lld. Perhaps we can temporarily
enable the DCE option only when option LD_IS_LLD is disabled,
like risc-v:
`select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if !LD_IS_LLD`.


From dmitry.baryshkov at linaro.org  Thu Feb 22 03:26:59 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 22 Feb 2024 13:26:59 +0200
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAMRc=Md6SoXukoGb4bW-CSYgjpO4RL+0Uu3tYrZzgSgVtFH6Sw@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org> <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org> <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
 <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
 <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com>
 <b9a31374-8ea9-407e-9ec3-008a95e2b18b@linaro.org> <CAA8EJppWY8c-pF75WaMadWtEuaAyCc5A1VLEq=JmB2Ngzk-zyw@mail.gmail.com>
 <CAMRc=Md6SoXukoGb4bW-CSYgjpO4RL+0Uu3tYrZzgSgVtFH6Sw@mail.gmail.com>
Message-ID: <CAA8EJprUM6=ZqTwWLB8rW8WRDqwncafa-szSsTvPQCOOSXUn_w@mail.gmail.com>

On Thu, 22 Feb 2024 at 13:00, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> On Mon, Feb 19, 2024 at 11:21?PM Dmitry Baryshkov
> <dmitry.baryshkov at linaro.org> wrote:
> >
> > On Mon, 19 Feb 2024 at 19:18, <neil.armstrong at linaro.org> wrote:
> > >
> > > On 19/02/2024 13:33, Dmitry Baryshkov wrote:
> > > > On Mon, 19 Feb 2024 at 14:23, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> > > >>
> > > >> On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
> > > >> <dmitry.baryshkov at linaro.org> wrote:
> > > >>>
> > > >>
> > > >> [snip]
> > > >>
> > > >>>>>>>>
> > > >>>>>>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> > > >>>>>>>> necessary. The BT and WLAN devices on the device-tree are represented as
> > > >>>>>>>> consuming the inputs (relevant to the functionality of each) of the PMU
> > > >>>>>>>> directly.
> > > >>>>>>>
> > > >>>>>>> We are describing the hardware. From the hardware point of view, there
> > > >>>>>>> is a PMU. I think at some point we would really like to describe all
> > > >>>>>>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> > > >>>>>>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
> > > >>>>>>
> > > >>>>>> While I agree with older WiFi+BT units, I don't think it's needed for
> > > >>>>>> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
> > > >>>>>> transparent.
> > > >>>>>
> > > >>>>> I don't see any significant difference between WCN6750/WCN6855 and
> > > >>>>> WCN7850 from the PMU / power up point of view. Could you please point
> > > >>>>> me to the difference?
> > > >>>>>
> > > >>>>
> > > >>>> The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
> > > >>>> and BT_EN ordering and the only requirement is to have all input regulators
> > > >>>> up before pulling up WLAN_EN and/or BT_EN.
> > > >>>>
> > > >>>> This makes the PMU transparent and BT and WLAN can be described as independent.
> > > >>>
> > > >>>  From the hardware perspective, there is a PMU. It has several LDOs. So
> > > >>> the device tree should have the same style as the previous
> > > >>> generations.
> > > >>>
> > > >>
> > > >> My thinking was this: yes, there is a PMU but describing it has no
> > > >> benefit (unlike QCA6x90). If we do describe, then we'll end up having
> > > >> to use pwrseq here despite it not being needed because now we won't be
> > > >> able to just get regulators from WLAN/BT drivers directly.
> > > >>
> > > >> So I also vote for keeping it this way. Let's go into the package
> > > >> detail only if it's required.
> > > >
> > > > The WiFi / BT parts are not powered up by the board regulators. They
> > > > are powered up by the PSU. So we are not describing it in the accurate
> > > > way.
> > >
> > > I disagree, the WCN7850 can also be used as a discrete PCIe M.2 card, and in
> > > this situation the PCIe part is powered with the M.2 slot and the BT side
> > > is powered separately as we currently do it now.
> >
> > QCA6390 can also be used as a discrete M.2 card.
> >
> > > So yes there's a PMU, but it's not an always visible hardware part, from the
> > > SoC PoV, only the separate PCIe and BT subsystems are visible/controllable/powerable.
> >
> > From the hardware point:
> > - There is a PMU
> > - The PMU is connected to the board supplies
> > - Both WiFi and BT parts are connected to the PMU
> > - The BT_EN / WLAN_EN pins are not connected to the PMU
> >
> > So, not representing the PMU in the device tree is a simplification.
> >
>
> What about the existing WLAN and BT users of similar packages? We
> would have to deprecate a lot of existing bindings. I don't think it's
> worth it.

We have bindings that are not reflecting the hardware. So yes, we
should gradually update them once the powerseq is merged.

> The WCN7850 is already described in bindings as consuming what is PMUs
> inputs and not its outputs.

So do WCN6855 and QCA6391 BlueTooth parts.

>
> Bart
>
> > >
> > > Neil
> > >
> > > >
> > > > Moreover, I think we definitely want to move BT driver to use only the
> > > > pwrseq power up method. Doing it in the other way results in the code
> > > > duplication and possible issues because of the regulator / pwrseq
> > > > taking different code paths.
> >
> > --
> > With best wishes
> > Dmitry



-- 
With best wishes
Dmitry


From shameerali.kolothum.thodi at huawei.com  Thu Feb 22 03:31:18 2024
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Thu, 22 Feb 2024 11:31:18 +0000
Subject: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty tracking
 in domain alloc
In-Reply-To: <a47699c9-4f3d-4cd0-94f4-f19e117ea6a3@oracle.com>
References: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
 <20240222094923.33104-4-shameerali.kolothum.thodi@huawei.com>
 <a47699c9-4f3d-4cd0-94f4-f19e117ea6a3@oracle.com>
Message-ID: <dfdc7daf8bd14b04b9bd29faaa1e6a96@huawei.com>



> -----Original Message-----
> From: Joao Martins <joao.m.martins at oracle.com>
> Sent: Thursday, February 22, 2024 11:04 AM
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: joro at 8bytes.org; jgg at nvidia.com; kevin.tian at intel.com;
> nicolinc at nvidia.com; iommu at lists.linux.dev; mshavit at google.com;
> robin.murphy at arm.com; will at kernel.org; jiangkunkun
> <jiangkunkun at huawei.com>; zhukeqian <zhukeqian1 at huawei.com>;
> Linuxarm <linuxarm at huawei.com>; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty
> tracking in domain alloc
> 
> On 22/02/2024 09:49, Shameer Kolothum wrote:
> > From: Joao Martins <joao.m.martins at oracle.com>
> >
> > This provides all the infrastructure to enable dirty tracking if the
> > hardware has the capability and domain alloc request for it.
> >
> > Please note, we still report no support for IOMMU_CAP_DIRTY_TRACKING
> > as it will finally be enabled in a subsequent patch.
> >
> > Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
> > Signed-off-by: Shameer Kolothum
> <shameerali.kolothum.thodi at huawei.com>
> > ---
> >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 95
> ++++++++++++++++-----
> >  include/linux/io-pgtable.h                  |  4 +
> >  2 files changed, 77 insertions(+), 22 deletions(-)
> >
> > 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 bd30739e3588..058bbb0dbe2e 100644
> > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > @@ -43,6 +43,7 @@ MODULE_PARM_DESC(disable_msipolling,
> >  	"Disable MSI-based polling for CMD_SYNC completion.");
> >
> >  static struct iommu_ops arm_smmu_ops;
> > +static struct iommu_dirty_ops arm_smmu_dirty_ops;
> >
> >  enum arm_smmu_msi_index {
> >  	EVTQ_MSI_INDEX,
> > @@ -86,7 +87,8 @@ static struct arm_smmu_option_prop
> > arm_smmu_options[] = {
> >
> >  static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device
> > *smmu);  static int arm_smmu_domain_finalise(struct arm_smmu_domain
> *smmu_domain,
> > -				    struct arm_smmu_device *smmu);
> > +				    struct arm_smmu_device *smmu,
> > +				    bool enable_dirty);
> >  static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
> > static void arm_smmu_tlb_inv_all_s2(struct arm_smmu_domain
> > *smmu_domain);
> >
> > @@ -2378,7 +2380,7 @@ static struct iommu_domain
> *arm_smmu_domain_alloc_paging(struct device *dev)
> >  		struct arm_smmu_master *master =
> dev_iommu_priv_get(dev);
> >  		int ret;
> >
> > -		ret = arm_smmu_domain_finalise(smmu_domain, master-
> >smmu);
> > +		ret = arm_smmu_domain_finalise(smmu_domain, master-
> >smmu, false);
> >  		if (ret) {
> >  			kfree(smmu_domain);
> >  			return ERR_PTR(ret);
> > @@ -2445,10 +2447,11 @@ static void arm_smmu_domain_free(struct
> > iommu_domain *domain)  }
> >
> >  static int arm_smmu_domain_finalise(struct arm_smmu_domain
> *smmu_domain,
> > -				    struct arm_smmu_device *smmu)
> > +				    struct arm_smmu_device *smmu,
> > +				    bool enable_dirty)
> >  {
> >  	int ret;
> > -	unsigned long ias, oas;
> > +	unsigned long ias;
> >  	enum io_pgtable_fmt fmt;
> >  	struct io_pgtable_cfg pgtbl_cfg;
> >  	struct io_pgtable_ops *pgtbl_ops;
> > @@ -2459,31 +2462,31 @@ static int arm_smmu_domain_finalise(struct
> arm_smmu_domain *smmu_domain,
> >  	if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
> >  		smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
> >
> > +	pgtbl_cfg = (struct io_pgtable_cfg) {
> > +		.pgsize_bitmap	= smmu->pgsize_bitmap,
> > +		.coherent_walk	= smmu->features &
> ARM_SMMU_FEAT_COHERENCY,
> > +		.tlb		= &arm_smmu_flush_ops,
> > +		.iommu_dev	= smmu->dev,
> > +	};
> > +
> >  	switch (smmu_domain->stage) {
> >  	case ARM_SMMU_DOMAIN_S1:
> >  		ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
> > -		ias = min_t(unsigned long, ias, VA_BITS);
> > -		oas = smmu->ias;
> > +		pgtbl_cfg.ias = min_t(unsigned long, ias, VA_BITS);
> > +		pgtbl_cfg.oas = smmu->ias;
> > +		if (enable_dirty)
> > +			pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_HD;
> >  		fmt = ARM_64_LPAE_S1;
> >  		break;
> >  	case ARM_SMMU_DOMAIN_S2:
> > -		ias = smmu->ias;
> > -		oas = smmu->oas;
> > +		pgtbl_cfg.ias = smmu->ias;
> > +		pgtbl_cfg.oas = smmu->oas;
> >  		fmt = ARM_64_LPAE_S2;
> >  		break;
> >  	default:
> >  		return -EINVAL;
> >  	}
> >
> > -	pgtbl_cfg = (struct io_pgtable_cfg) {
> > -		.pgsize_bitmap	= smmu->pgsize_bitmap,
> > -		.ias		= ias,
> > -		.oas		= oas,
> > -		.coherent_walk	= smmu->features &
> ARM_SMMU_FEAT_COHERENCY,
> > -		.tlb		= &arm_smmu_flush_ops,
> > -		.iommu_dev	= smmu->dev,
> > -	};
> > -
> >  	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
> >  	if (!pgtbl_ops)
> >  		return -ENOMEM;
> > @@ -2491,7 +2494,8 @@ static int arm_smmu_domain_finalise(struct
> arm_smmu_domain *smmu_domain,
> >  	smmu_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
> >  	smmu_domain->domain.geometry.aperture_end = (1UL <<
> pgtbl_cfg.ias) - 1;
> >  	smmu_domain->domain.geometry.force_aperture = true;
> > -
> > +	if (enable_dirty && smmu_domain->stage ==
> ARM_SMMU_DOMAIN_S1)
> > +		smmu_domain->domain.dirty_ops =
> &arm_smmu_dirty_ops;
> >  	ret = arm_smmu_domain_alloc_id(smmu, smmu_domain);
> >  	if (ret < 0) {
> >  		free_io_pgtable_ops(pgtbl_ops);
> > @@ -2811,7 +2815,7 @@ static int arm_smmu_attach_dev(struct
> iommu_domain *domain, struct device *dev)
> >  	mutex_lock(&smmu_domain->init_mutex);
> >
> >  	if (!smmu_domain->smmu) {
> > -		ret = arm_smmu_domain_finalise(smmu_domain, smmu);
> > +		ret = arm_smmu_domain_finalise(smmu_domain, smmu,
> false);
> >  	} else if (smmu_domain->smmu != smmu)
> >  		ret = -EINVAL;
> >
> 
> 
> I think we are missing the domain attach_dev check for dirty tracking.
> 
> Something like:
> 
> if (domain->dirty_ops && !arm_smmu_dbm_capable(smmu))
> 	return -EINVAL;
> 
> But that helper is only introduced in the last patch, so maybe:
> 
> if (domain->dirty_ops &&
>     !device_iommu_capable(dev, IOMMU_CAP_DIRTY_TRACKING))
> 	return -EINVAL;

Ok. But do we really need to check this in attach()? As dirty_ops are added only
if it is requested in alloc_user() and there we return err when hardware doesn't 
have the capability.  So not sure how this matters in attach() path. May be I am 
missing something.

Thanks,
Shameer


From liuyuntao12 at huawei.com  Thu Feb 22 03:32:03 2024
From: liuyuntao12 at huawei.com (liuyuntao (F))
Date: Thu, 22 Feb 2024 19:32:03 +0800
Subject: [PATCH -next] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
In-Reply-To: <f5326293-b446-49e5-9cc0-78c9009af136@app.fastmail.com>
References: <20240220081527.23408-1-liuyuntao12@huawei.com>
 <1342759e-b967-4ec4-98d5-48146f81f695@app.fastmail.com>
 <38c09a4b-69cc-4dc5-8a68-e5f5597613ac@huawei.com>
 <30b01c65-12f2-4ee0-81d5-c7a2da2c36b4@app.fastmail.com>
 <f5326293-b446-49e5-9cc0-78c9009af136@app.fastmail.com>
Message-ID: <1ae25437-b190-418d-a4e0-aa17d6de59bf@huawei.com>



On 2024/2/22 17:52, Arnd Bergmann wrote:
> On Wed, Feb 21, 2024, at 16:51, Arnd Bergmann wrote:
>> I have given your patch some build testing with random
>> configurations in my build setup and it seems to work
>> fine with gcc/binutils, but unfortunately I came across
>> a link failure using clang/lld:
> 
> I ran into another bug now, this time with CONFIG_XIP_KERNEL=y:
> 
> no __ex_table in file: vmlinux
> Failed to sort kernel tables
> make[4]: *** [scripts/Makefile.vmlinux:37: vmlinux] Error 1
> 
> Essentially you have to modify arch/arm/kernel/vmlinux-xip.lds.S
> the same way as vmlinux.lds.S:
>
Thanks a lot. I didn't consider this situation. I will take your advice. 
Thanks again.

> --- a/arch/arm/kernel/vmlinux-xip.lds.S
> +++ b/arch/arm/kernel/vmlinux-xip.lds.S
> @@ -63,7 +63,7 @@ SECTIONS
>          . = ALIGN(4);
>          __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
>                  __start___ex_table = .;
> -               ARM_MMU_KEEP(*(__ex_table))
> +               ARM_MMU_KEEP(KEEP(*(__ex_table)))
>                  __stop___ex_table = .;
>          }
>   
> @@ -83,7 +83,7 @@ SECTIONS
>          }
>          .init.arch.info : {
>                  __arch_info_begin = .;
> -               *(.arch.info.init)
> +               KEEP(*(.arch.info.init))
>                  __arch_info_end = .;
>          }
>          .init.tagtable : {
> 
> 
> The pv_table is not needed for XIP_KERNEL=y because that
> requires not patching the kernel.
> 
>      Arnd


From joao.m.martins at oracle.com  Thu Feb 22 03:37:51 2024
From: joao.m.martins at oracle.com (Joao Martins)
Date: Thu, 22 Feb 2024 11:37:51 +0000
Subject: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty tracking
 in domain alloc
In-Reply-To: <dfdc7daf8bd14b04b9bd29faaa1e6a96@huawei.com>
References: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
 <20240222094923.33104-4-shameerali.kolothum.thodi@huawei.com>
 <a47699c9-4f3d-4cd0-94f4-f19e117ea6a3@oracle.com>
 <dfdc7daf8bd14b04b9bd29faaa1e6a96@huawei.com>
Message-ID: <5607ece8-ce00-4834-9ae9-f4aa16fc4886@oracle.com>

On 22/02/2024 11:31, Shameerali Kolothum Thodi wrote:
> 
> 
>> -----Original Message-----
>> From: Joao Martins <joao.m.martins at oracle.com>
>> Sent: Thursday, February 22, 2024 11:04 AM
>> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
>> Cc: joro at 8bytes.org; jgg at nvidia.com; kevin.tian at intel.com;
>> nicolinc at nvidia.com; iommu at lists.linux.dev; mshavit at google.com;
>> robin.murphy at arm.com; will at kernel.org; jiangkunkun
>> <jiangkunkun at huawei.com>; zhukeqian <zhukeqian1 at huawei.com>;
>> Linuxarm <linuxarm at huawei.com>; linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty
>> tracking in domain alloc
>>
>> On 22/02/2024 09:49, Shameer Kolothum wrote:
>>> From: Joao Martins <joao.m.martins at oracle.com>
>>>
>>> This provides all the infrastructure to enable dirty tracking if the
>>> hardware has the capability and domain alloc request for it.
>>>
>>> Please note, we still report no support for IOMMU_CAP_DIRTY_TRACKING
>>> as it will finally be enabled in a subsequent patch.
>>>
>>> Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
>>> Signed-off-by: Shameer Kolothum
>> <shameerali.kolothum.thodi at huawei.com>
>>> ---
>>>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 95
>> ++++++++++++++++-----
>>>  include/linux/io-pgtable.h                  |  4 +
>>>  2 files changed, 77 insertions(+), 22 deletions(-)
>>>
>>> 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 bd30739e3588..058bbb0dbe2e 100644
>>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>> @@ -43,6 +43,7 @@ MODULE_PARM_DESC(disable_msipolling,
>>>  	"Disable MSI-based polling for CMD_SYNC completion.");
>>>
>>>  static struct iommu_ops arm_smmu_ops;
>>> +static struct iommu_dirty_ops arm_smmu_dirty_ops;
>>>
>>>  enum arm_smmu_msi_index {
>>>  	EVTQ_MSI_INDEX,
>>> @@ -86,7 +87,8 @@ static struct arm_smmu_option_prop
>>> arm_smmu_options[] = {
>>>
>>>  static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device
>>> *smmu);  static int arm_smmu_domain_finalise(struct arm_smmu_domain
>> *smmu_domain,
>>> -				    struct arm_smmu_device *smmu);
>>> +				    struct arm_smmu_device *smmu,
>>> +				    bool enable_dirty);
>>>  static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
>>> static void arm_smmu_tlb_inv_all_s2(struct arm_smmu_domain
>>> *smmu_domain);
>>>
>>> @@ -2378,7 +2380,7 @@ static struct iommu_domain
>> *arm_smmu_domain_alloc_paging(struct device *dev)
>>>  		struct arm_smmu_master *master =
>> dev_iommu_priv_get(dev);
>>>  		int ret;
>>>
>>> -		ret = arm_smmu_domain_finalise(smmu_domain, master-
>>> smmu);
>>> +		ret = arm_smmu_domain_finalise(smmu_domain, master-
>>> smmu, false);
>>>  		if (ret) {
>>>  			kfree(smmu_domain);
>>>  			return ERR_PTR(ret);
>>> @@ -2445,10 +2447,11 @@ static void arm_smmu_domain_free(struct
>>> iommu_domain *domain)  }
>>>
>>>  static int arm_smmu_domain_finalise(struct arm_smmu_domain
>> *smmu_domain,
>>> -				    struct arm_smmu_device *smmu)
>>> +				    struct arm_smmu_device *smmu,
>>> +				    bool enable_dirty)
>>>  {
>>>  	int ret;
>>> -	unsigned long ias, oas;
>>> +	unsigned long ias;
>>>  	enum io_pgtable_fmt fmt;
>>>  	struct io_pgtable_cfg pgtbl_cfg;
>>>  	struct io_pgtable_ops *pgtbl_ops;
>>> @@ -2459,31 +2462,31 @@ static int arm_smmu_domain_finalise(struct
>> arm_smmu_domain *smmu_domain,
>>>  	if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
>>>  		smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
>>>
>>> +	pgtbl_cfg = (struct io_pgtable_cfg) {
>>> +		.pgsize_bitmap	= smmu->pgsize_bitmap,
>>> +		.coherent_walk	= smmu->features &
>> ARM_SMMU_FEAT_COHERENCY,
>>> +		.tlb		= &arm_smmu_flush_ops,
>>> +		.iommu_dev	= smmu->dev,
>>> +	};
>>> +
>>>  	switch (smmu_domain->stage) {
>>>  	case ARM_SMMU_DOMAIN_S1:
>>>  		ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
>>> -		ias = min_t(unsigned long, ias, VA_BITS);
>>> -		oas = smmu->ias;
>>> +		pgtbl_cfg.ias = min_t(unsigned long, ias, VA_BITS);
>>> +		pgtbl_cfg.oas = smmu->ias;
>>> +		if (enable_dirty)
>>> +			pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_HD;
>>>  		fmt = ARM_64_LPAE_S1;
>>>  		break;
>>>  	case ARM_SMMU_DOMAIN_S2:
>>> -		ias = smmu->ias;
>>> -		oas = smmu->oas;
>>> +		pgtbl_cfg.ias = smmu->ias;
>>> +		pgtbl_cfg.oas = smmu->oas;
>>>  		fmt = ARM_64_LPAE_S2;
>>>  		break;
>>>  	default:
>>>  		return -EINVAL;
>>>  	}
>>>
>>> -	pgtbl_cfg = (struct io_pgtable_cfg) {
>>> -		.pgsize_bitmap	= smmu->pgsize_bitmap,
>>> -		.ias		= ias,
>>> -		.oas		= oas,
>>> -		.coherent_walk	= smmu->features &
>> ARM_SMMU_FEAT_COHERENCY,
>>> -		.tlb		= &arm_smmu_flush_ops,
>>> -		.iommu_dev	= smmu->dev,
>>> -	};
>>> -
>>>  	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
>>>  	if (!pgtbl_ops)
>>>  		return -ENOMEM;
>>> @@ -2491,7 +2494,8 @@ static int arm_smmu_domain_finalise(struct
>> arm_smmu_domain *smmu_domain,
>>>  	smmu_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
>>>  	smmu_domain->domain.geometry.aperture_end = (1UL <<
>> pgtbl_cfg.ias) - 1;
>>>  	smmu_domain->domain.geometry.force_aperture = true;
>>> -
>>> +	if (enable_dirty && smmu_domain->stage ==
>> ARM_SMMU_DOMAIN_S1)
>>> +		smmu_domain->domain.dirty_ops =
>> &arm_smmu_dirty_ops;
>>>  	ret = arm_smmu_domain_alloc_id(smmu, smmu_domain);
>>>  	if (ret < 0) {
>>>  		free_io_pgtable_ops(pgtbl_ops);
>>> @@ -2811,7 +2815,7 @@ static int arm_smmu_attach_dev(struct
>> iommu_domain *domain, struct device *dev)
>>>  	mutex_lock(&smmu_domain->init_mutex);
>>>
>>>  	if (!smmu_domain->smmu) {
>>> -		ret = arm_smmu_domain_finalise(smmu_domain, smmu);
>>> +		ret = arm_smmu_domain_finalise(smmu_domain, smmu,
>> false);
>>>  	} else if (smmu_domain->smmu != smmu)
>>>  		ret = -EINVAL;
>>>
>>
>>
>> I think we are missing the domain attach_dev check for dirty tracking.
>>
>> Something like:
>>
>> if (domain->dirty_ops && !arm_smmu_dbm_capable(smmu))
>> 	return -EINVAL;
>>
>> But that helper is only introduced in the last patch, so maybe:
>>
>> if (domain->dirty_ops &&
>>     !device_iommu_capable(dev, IOMMU_CAP_DIRTY_TRACKING))
>> 	return -EINVAL;
> 
> Ok. But do we really need to check this in attach()? As dirty_ops are added only
> if it is requested in alloc_user() and there we return err when hardware doesn't 
> have the capability.  So not sure how this matters in attach() path. May be I am 
> missing something.

That's when you create the domain with dev A. Afterwards that dev A is attached,
but later on you can attach another device B to the domain. So this check is
there such that a domain with dirty tracking ops set will only have devices in
there that support dirty tracking.

	Joao


From krzysztof.kozlowski at linaro.org  Thu Feb 22 04:05:46 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 13:05:46 +0100
Subject: [PATCH v3 2/7] dt-bindings: arm-smmu: fix SM8[45]50 GPU SMMU if
 condition
In-Reply-To: <20240216-topic-sm8650-gpu-v3-2-eb1f4b86d8d3@linaro.org>
References: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
 <20240216-topic-sm8650-gpu-v3-2-eb1f4b86d8d3@linaro.org>
Message-ID: <bd13fb09-8602-45e3-8d03-db7a8a0afb7e@linaro.org>

On 16/02/2024 12:03, Neil Armstrong wrote:
> The if condition for the SM8[45]50 GPU SMMU is too large,
> add the other compatible strings to the condition to only
> allow the clocks for the GPU SMMU nodes.
> 
> Fixes: 4fff78dc2490 ("dt-bindings: arm-smmu: Document SM8[45]50 GPU SMMU")
> Suggested-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Thu Feb 22 04:06:28 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 13:06:28 +0100
Subject: [PATCH v3 3/7] dt-bindings: arm-smmu: Document SM8650 GPU SMMU
In-Reply-To: <20240216-topic-sm8650-gpu-v3-3-eb1f4b86d8d3@linaro.org>
References: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
 <20240216-topic-sm8650-gpu-v3-3-eb1f4b86d8d3@linaro.org>
Message-ID: <4a812d27-26e4-4358-a9f5-33ac66086769@linaro.org>

On 16/02/2024 12:03, Neil Armstrong wrote:
> Document the GPU SMMU found on the SM8650 platform.
> 
> Signed-off-by: Neil Armstrong <neil.armstrong at linaro.org>
> ---
>  Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From linus.walleij at linaro.org  Thu Feb 22 04:07:56 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 22 Feb 2024 13:07:56 +0100
Subject: [PATCH v2 0/2] ARM: decompressor: support AUTO_ZRELADDR and
 appended DTB
In-Reply-To: <65d62b60.050a0220.c7b96.614e@mx.google.com>
References: <20240121203009.9257-1-ansuelsmth@gmail.com> <65d62b60.050a0220.c7b96.614e@mx.google.com>
Message-ID: <CACRpkdYZSr0Kif+q-DBZi7v7qZ=_tedONEP-OPhOHg4yHmwkhg@mail.gmail.com>

On Wed, Feb 21, 2024 at 5:57?PM Christian Marangi <ansuelsmth at gmail.com> wrote:

> Any news for this?

Can you please put the patches into Russell's patch tracker so he can
apply them?
https://www.arm.linux.org.uk/developer/patches/

If you run into any problems, ping me on IRC and I'll help out.

Yours,
Linus Walleij


From krzysztof.kozlowski at linaro.org  Thu Feb 22 04:14:35 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 13:14:35 +0100
Subject: [PATCH v5 1/4] dt-bindings: spmi: Add PMIC ARB v7 schema
In-Reply-To: <20240221-spmi-multi-master-support-v5-1-3255ca413a0b@linaro.org>
References: <20240221-spmi-multi-master-support-v5-0-3255ca413a0b@linaro.org>
 <20240221-spmi-multi-master-support-v5-1-3255ca413a0b@linaro.org>
Message-ID: <dd86117e-0196-499b-b8b3-efe4013cbc07@linaro.org>

On 21/02/2024 13:52, Abel Vesa wrote:
> Add dedicated schema for PMIC ARB v7 as it allows multiple
> buses by declaring them as child nodes. These child nodes
> will follow the generic spmi bus bindings.
> 
> Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
> ---


> +
> +description: |
> +  The SPMI PMIC Arbiter v7 is found on Snapdragon chipsets. It is an SPMI
> +  controller with wrapping arbitration logic to allow for multiple on-chip
> +  devices to control up to 2 SPMI separate buses.
> +
> +  The PMIC Arbiter can also act as an interrupt controller, providing interrupts
> +  to slave devices.
> +
> +properties:
> +  compatible:
> +    const: qcom,spmi-pmic-arb-v7

I dislike the versioning. Previous PMIC ARB binding said "it will cover
everything" and now it turns out that everything is not everything. I
would suggest SoC specific compatibles.

> +
> +  reg:
> +    items:
> +      - description: core registers
> +      - description: tx-channel per virtual slave regosters
> +      - description: rx-channel (called observer) per virtual slave registers
> +
> +  reg-names:
> +    items:
> +      - const: core
> +      - const: chnls
> +      - const: obsrvr
> +
> +  ranges: true
> +
> +  '#address-cells':
> +    const: 2
> +
> +  '#size-cells':
> +    const: 2
> +
> +  qcom,ee:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 0
> +    maximum: 5
> +    description: >
> +      indicates the active Execution Environment identifier
> +
> +  qcom,channel:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 0
> +    maximum: 5
> +    description: >
> +      which of the PMIC Arb provided channels to use for accesses

We should probably deprecate qcom,bus-id in qcom,spmi-pmic-arb.yaml.

> +
> +patternProperties:
> +  "spmi@[0-1]$":
> +    type: object
> +    $ref: /schemas/spmi/spmi.yaml

On this level:
unevaluatedProperties: false

> +
> +required:
> +  - compatible
> +  - reg-names
> +  - qcom,ee
> +  - qcom,channel
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    spmi: arbiter at c400000 {
> +      compatible = "qcom,spmi-pmic-arb-v7";
> +      reg = <0x0c400000 0x3000>,
> +            <0x0c500000 0x4000000>,
> +            <0x0c440000 0x80000>;
> +      reg-names = "core", "chnls", "obsrvr";
> +
> +      qcom,ee = <0>;
> +      qcom,channel = <0>;
> +
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      spmi_bus0: spmi at 0 {
> +        reg = <0 0x0c42d000 0 0x4000>,
> +              <0 0x0c4c0000 0 0x10000>;
> +        reg-names = "cnfg", "intr";
> +
> +        interrupt-names = "periph_irq";
> +        interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-controller;
> +        #interrupt-cells = <4>;
> +
> +        qcom,bus-id = <0>;

Please drop. Same in second instance.


Best regards,
Krzysztof



From will at kernel.org  Thu Feb 22 04:18:38 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 12:18:38 +0000
Subject: [PATCH v4 2/6] perf: imx_perf: refactor driver for imx93
In-Reply-To: <20240131055811.3035741-2-xu.yang_2@nxp.com>
References: <20240131055811.3035741-1-xu.yang_2@nxp.com>
 <20240131055811.3035741-2-xu.yang_2@nxp.com>
Message-ID: <20240222121838.GA8308@willie-the-truck>

On Wed, Jan 31, 2024 at 01:58:07PM +0800, Xu Yang wrote:
> This driver is initinally used to support imx93 Soc and now it's time to
> add support for imx95 Soc. However, some macro definitions and events are
> different on these two Socs. For preparing imx95 supports, this will
> refactor driver for imx93.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v4:
>  - new patch
> ---
>  drivers/perf/fsl_imx9_ddr_perf.c | 121 ++++++++++++++++++++++---------
>  1 file changed, 87 insertions(+), 34 deletions(-)

[...]

> @@ -476,12 +490,12 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
>  	hwc->idx = counter;
>  	hwc->state |= PERF_HES_STOPPED;
>  
> +	/* read trans, write trans, read beat */
> +	imx93_ddr_perf_monitor_config(pmu, cfg, cfg1, cfg2);
> +
>  	if (flags & PERF_EF_START)
>  		ddr_perf_event_start(event, flags);
>  
> -	/* read trans, write trans, read beat */
> -	ddr_perf_monitor_config(pmu, cfg, cfg1, cfg2);
> -
>  	return 0;

This change looks like more than just refactoring and should probably be a
separate patch. Is it a bug fix for the existing code?

> +static int ddr_perf_add_events(struct ddr_pmu *pmu)
> +{
> +	int i, ret;
> +	struct attribute **attrs = pmu->devtype_data->attrs;
> +	struct device *pmu_dev = pmu->pmu.dev;
> +
> +	if (!attrs)
> +		return 0;
> +
> +	for (i = 0; attrs[i]; i++) {
> +		ret = sysfs_add_file_to_group(&pmu_dev->kobj, attrs[i], "events");
> +		if (ret) {
> +			dev_warn(pmu->dev, "i.MX9 DDR Perf add events failed (%d)\n", ret);
> +			return ret;

Can you use the '.is_visible' callback in 'struct attribute_group' to avoid
having to manipulate sysfs directly like this? For example, create separate
groups for the imx93 and imx95-specific events and only make them visible
if we're on the appropriate hardware.

Will


From broonie at kernel.org  Thu Feb 22 04:21:36 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 22 Feb 2024 12:21:36 +0000
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for
 WCN7850
In-Reply-To: <CAMRc=MedCX_TGGawMhr39oXtJPF4pOQF=Jh2z4uXkOxwhfJWRw@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-15-brgl@bgdev.pl>
 <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk>
 <CAMRc=MeUjKPS3ANE6=7WZ3kbbGAdyE8HeXFN=75Jp-pVyBaWrQ@mail.gmail.com>
 <ea08a286-ff53-4d58-ae41-38cca151508c@sirena.org.uk>
 <17bbd9ae-0282-430e-947b-e6fb08c53af7@linaro.org>
 <53f0956f-ee64-4bd6-b44f-cbebafd42e46@sirena.org.uk>
 <CAMRc=MedCX_TGGawMhr39oXtJPF4pOQF=Jh2z4uXkOxwhfJWRw@mail.gmail.com>
Message-ID: <52fba837-989b-4213-8af7-f02cd8cb48c8@sirena.org.uk>

On Thu, Feb 22, 2024 at 10:22:50AM +0100, Bartosz Golaszewski wrote:
> On Wed, Feb 21, 2024 at 12:44?AM Mark Brown <broonie at kernel.org> wrote:

> > Yes, that's the theory - I just question if it actually does something
> > useful in practice.  Between regulators getting more and more able to
> > figure out mode switching autonomously based on load monitoring and them
> > getting more efficient it's become very unclear if this actually
> > accomplishes anything, the only usage is the Qualcomm stuff and that's
> > all really unsophisticated and has an air of something that's being
> > cut'n'pasted forwards rather than delivering practical results.  There
> > is some value at ultra low loads, but that's more for suspend modes than
> > for actual use.

> Removing it would be out of scope for this series and I don't really
> want to introduce any undefined behavior when doing a big development
> like that. I'll think about it separately.

This is new code?
-------------- 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/20240222/38a96215/attachment.sig>

From will at kernel.org  Thu Feb 22 04:22:54 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 12:22:54 +0000
Subject: [PATCH v4 3/6] perf: imx_perf: add support for i.MX95 platform
In-Reply-To: <20240131055811.3035741-3-xu.yang_2@nxp.com>
References: <20240131055811.3035741-1-xu.yang_2@nxp.com>
 <20240131055811.3035741-3-xu.yang_2@nxp.com>
Message-ID: <20240222122253.GB8308@willie-the-truck>

On Wed, Jan 31, 2024 at 01:58:08PM +0800, Xu Yang wrote:
> i.MX95 has a DDR PMU which is almostly same as i.MX93, it now supports
> read beat and write beat filter capabilities. This will add support for
> i.MX95 and enhance the driver to support specific filter handling for it.
> 
> Usage:
> 
> For read beat:
> ~# perf stat -a -I 1000 -e imx9_ddr0/eddrtq_pm_rd_beat_filt2,counter=3,axi_mask=ID_MASK,axi_id=ID/
> ~# perf stat -a -I 1000 -e imx9_ddr0/eddrtq_pm_rd_beat_filt1,counter=4,axi_mask=ID_MASK,axi_id=ID/
> ~# perf stat -a -I 1000 -e imx9_ddr0/eddrtq_pm_rd_beat_filt0,counter=5,axi_mask=ID_MASK,axi_id=ID/
> eg: For edma2: perf stat -a -I 1000 -e imx9_ddr0/eddrtq_pm_rd_beat_filt0,counter=5,axi_mask=0x00f,axi_id=0x00c/
> 
> For write beat:
> ~# perf stat -a -I 1000 -e imx9_ddr0/eddrtq_pm_wr_beat_filt,counter=2,axi_mask=ID_MASK,axi_id=ID/
> eg: For edma2: perf stat -a -I 1000 -e imx9_ddr0/eddrtq_pm_wr_beat_filt,counter=2,axi_mask=0x00f,axi_id=0x00c/
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v2:
>  - put soc spefific axi filter events to drvdata according
>    to franks suggestions.
>  - adjust pmcfg axi_id and axi_mask config
> Changes in v3:
>  - no changes
> Changes in v4:
>  - only contain imx95 parts
> ---
>  drivers/perf/fsl_imx9_ddr_perf.c | 86 +++++++++++++++++++++++++++++++-
>  1 file changed, 84 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
> index b1a58e9e1617..85aaaef7212f 100644
> --- a/drivers/perf/fsl_imx9_ddr_perf.c
> +++ b/drivers/perf/fsl_imx9_ddr_perf.c
> @@ -17,9 +17,19 @@
>  #define MX93_PMCFG1_RD_BT_FILT_EN	BIT(29)
>  #define MX93_PMCFG1_ID_MASK		GENMASK(17, 0)
>  
> +#define MX95_PMCFG1_WR_BEAT_FILT_EN	BIT(31)
> +#define MX95_PMCFG1_RD_BEAT_FILT_EN	BIT(30)
> +
>  #define PMCFG2				0x04
>  #define MX93_PMCFG2_ID			GENMASK(17, 0)
>  
> +#define PMCFG3				0x08
> +#define PMCFG4				0x0C
> +#define PMCFG5				0x10
> +#define PMCFG6				0x14
> +#define MX95_PMCFG_ID_MASK		GENMASK(9, 0)
> +#define MX95_PMCFG_ID			GENMASK(25, 16)
> +
>  /* Global control register affects all counters and takes priority over local control registers */
>  #define PMGC0		0x40
>  /* Global control register bits */
> @@ -240,6 +250,18 @@ static struct attribute *imx93_ddr_perf_events_attrs[] = {
>  	NULL,
>  };
>  
> +static struct attribute *imx95_ddr_perf_events_attrs[] = {
> +	/* counter2 specific events */
> +	IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pm_wr_beat_filt, 73),
> +	/* counter3 specific events */
> +	IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pm_rd_beat_filt2, 73),
> +	/* counter4 specific events */
> +	IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pm_rd_beat_filt1, 73),
> +	/* counter5 specific events */
> +	IMX9_DDR_PMU_EVENT_ATTR(eddrtq_pm_rd_beat_filt0, 73),
> +	NULL,
> +};
> +
>  PMU_FORMAT_ATTR(event, "config:0-7");
>  PMU_FORMAT_ATTR(counter, "config:8-15");
>  PMU_FORMAT_ATTR(axi_id, "config1:0-17");
> @@ -271,8 +293,14 @@ static const struct imx_ddr_devtype_data imx93_devtype_data = {
>  	.attrs = imx93_ddr_perf_events_attrs,
>  };
>  
> +static const struct imx_ddr_devtype_data imx95_devtype_data = {
> +	.identifier = "imx95",
> +	.attrs = imx95_ddr_perf_events_attrs,
> +};
> +
>  static const struct of_device_id imx_ddr_pmu_dt_ids[] = {
>  	{ .compatible = "fsl,imx93-ddr-pmu", .data = &imx93_devtype_data },
> +	{ .compatible = "fsl,imx95-ddr-pmu", .data = &imx95_devtype_data },
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, imx_ddr_pmu_dt_ids);
> @@ -410,6 +438,56 @@ static void imx93_ddr_perf_monitor_config(struct ddr_pmu *pmu, int cfg, int cfg1
>  	writel(pmcfg2, pmu->base + PMCFG2);
>  }
>  
> +static void imx95_ddr_perf_monitor_config(struct ddr_pmu *pmu, int cfg, int cfg1, int cfg2)
> +{
> +	u32 pmcfg1, pmcfg, offset = 0;
> +	int event, counter;
> +
> +	event = cfg & 0x000000FF;
> +	counter = (cfg & 0x0000FF00) >> 8;
> +
> +	pmcfg1 = readl_relaxed(pmu->base + PMCFG1);
> +
> +	if (counter == 2 && event == 73) {
> +		pmcfg1 |= MX95_PMCFG1_WR_BEAT_FILT_EN;
> +		offset = PMCFG3;
> +	} else if (counter == 2 && event != 73) {
> +		pmcfg1 &= ~MX95_PMCFG1_WR_BEAT_FILT_EN;
> +	}
> +
> +	if (counter == 3 && event == 73) {
> +		pmcfg1 |= MX95_PMCFG1_RD_BEAT_FILT_EN;
> +		offset = PMCFG4;
> +	} else if (counter == 3 && event != 73) {
> +		pmcfg1 &= ~MX95_PMCFG1_RD_BEAT_FILT_EN;
> +	}
> +
> +	if (counter == 4 && event == 73) {
> +		pmcfg1 |= MX95_PMCFG1_RD_BEAT_FILT_EN;
> +		offset = PMCFG5;
> +	} else if (counter == 4 && event != 73) {
> +		pmcfg1 &= ~MX95_PMCFG1_RD_BEAT_FILT_EN;
> +	}
> +
> +	if (counter == 5 && event == 73) {
> +		pmcfg1 |= MX95_PMCFG1_RD_BEAT_FILT_EN;
> +		offset = PMCFG6;
> +	} else if (counter == 5 && event != 73) {
> +		pmcfg1 &= ~MX95_PMCFG1_RD_BEAT_FILT_EN;
> +	}

I think this would be much easier to read if you rewrote it as:

	switch (counter) {
	case 2:
		...
		break;
	case 3:


etc.

> +	writel(pmcfg1, pmu->base + PMCFG1);

writel_relaxed()? (since you're already using readl_relaxed()).

> +
> +	if (offset) {
> +		pmcfg = readl_relaxed(pmu->base + offset);
> +		pmcfg &= ~(FIELD_PREP(MX95_PMCFG_ID_MASK, 0x3FF) |
> +			   FIELD_PREP(MX95_PMCFG_ID, 0x3FF));
> +		pmcfg |= (FIELD_PREP(MX95_PMCFG_ID_MASK, cfg2) |
> +			  FIELD_PREP(MX95_PMCFG_ID, cfg1));
> +		writel(pmcfg, pmu->base + offset);

Similarly.

Will


From will at kernel.org  Thu Feb 22 04:23:41 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 12:23:41 +0000
Subject: [PATCH v4 4/6] perf: imx_perf: add macro definitions for parsing
 config attr
In-Reply-To: <20240131055811.3035741-4-xu.yang_2@nxp.com>
References: <20240131055811.3035741-1-xu.yang_2@nxp.com>
 <20240131055811.3035741-4-xu.yang_2@nxp.com>
Message-ID: <20240222122341.GC8308@willie-the-truck>

On Wed, Jan 31, 2024 at 01:58:09PM +0800, Xu Yang wrote:
> The user can set event and counter in cmdline and the driver need to parse
> it using 'config' attr value. This will add macro definitions to avoid
> hard-code in driver.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v4:
>  - new patch
> ---
>  drivers/perf/fsl_imx9_ddr_perf.c | 19 +++++++++++++------
>  1 file changed, 13 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
> index 85aaaef7212f..94041f06c152 100644
> --- a/drivers/perf/fsl_imx9_ddr_perf.c
> +++ b/drivers/perf/fsl_imx9_ddr_perf.c
> @@ -52,6 +52,11 @@
>  #define NUM_COUNTERS		11
>  #define CYCLES_COUNTER		0
>  
> +#define CONFIG_EVENT_MASK	0x00FF
> +#define CONFIG_EVENT_OFFSET	0
> +#define CONFIG_COUNTER_MASK	0xFF00
> +#define CONFIG_COUNTER_OFFSET	8

Can you move this patch earlier, please, so that the imx95 support can use
these new definitions immediately?

Will


From shameerali.kolothum.thodi at huawei.com  Thu Feb 22 04:24:06 2024
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Thu, 22 Feb 2024 12:24:06 +0000
Subject: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty tracking
 in domain alloc
In-Reply-To: <5607ece8-ce00-4834-9ae9-f4aa16fc4886@oracle.com>
References: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
 <20240222094923.33104-4-shameerali.kolothum.thodi@huawei.com>
 <a47699c9-4f3d-4cd0-94f4-f19e117ea6a3@oracle.com>
 <dfdc7daf8bd14b04b9bd29faaa1e6a96@huawei.com>
 <5607ece8-ce00-4834-9ae9-f4aa16fc4886@oracle.com>
Message-ID: <d6442be07c9d4f999286e073ed221984@huawei.com>



> -----Original Message-----
> From: Joao Martins <joao.m.martins at oracle.com>
> Sent: Thursday, February 22, 2024 11:38 AM
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: joro at 8bytes.org; jgg at nvidia.com; kevin.tian at intel.com;
> nicolinc at nvidia.com; iommu at lists.linux.dev; mshavit at google.com;
> robin.murphy at arm.com; will at kernel.org; jiangkunkun
> <jiangkunkun at huawei.com>; zhukeqian <zhukeqian1 at huawei.com>; Linuxarm
> <linuxarm at huawei.com>; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty tracking
> in domain alloc
> 
> On 22/02/2024 11:31, Shameerali Kolothum Thodi wrote:
> >
> >
> >> -----Original Message-----
> >> From: Joao Martins <joao.m.martins at oracle.com>
> >> Sent: Thursday, February 22, 2024 11:04 AM
> >> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> >> Cc: joro at 8bytes.org; jgg at nvidia.com; kevin.tian at intel.com;
> >> nicolinc at nvidia.com; iommu at lists.linux.dev; mshavit at google.com;
> >> robin.murphy at arm.com; will at kernel.org; jiangkunkun
> >> <jiangkunkun at huawei.com>; zhukeqian <zhukeqian1 at huawei.com>;
> >> Linuxarm <linuxarm at huawei.com>; linux-arm-kernel at lists.infradead.org
> >> Subject: Re: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty
> >> tracking in domain alloc
> >>
> >> On 22/02/2024 09:49, Shameer Kolothum wrote:
> >>> From: Joao Martins <joao.m.martins at oracle.com>
> >>>
> >>> This provides all the infrastructure to enable dirty tracking if the
> >>> hardware has the capability and domain alloc request for it.
> >>>
> >>> Please note, we still report no support for IOMMU_CAP_DIRTY_TRACKING
> >>> as it will finally be enabled in a subsequent patch.
> >>>
> >>> Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
> >>> Signed-off-by: Shameer Kolothum
> >> <shameerali.kolothum.thodi at huawei.com>
> >>> ---
> >>>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 95
> >> ++++++++++++++++-----
> >>>  include/linux/io-pgtable.h                  |  4 +
> >>>  2 files changed, 77 insertions(+), 22 deletions(-)
> >>>
> >>> 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 bd30739e3588..058bbb0dbe2e 100644
> >>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> >>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> >>> @@ -43,6 +43,7 @@ MODULE_PARM_DESC(disable_msipolling,
> >>>  	"Disable MSI-based polling for CMD_SYNC completion.");
> >>>
> >>>  static struct iommu_ops arm_smmu_ops;
> >>> +static struct iommu_dirty_ops arm_smmu_dirty_ops;
> >>>
> >>>  enum arm_smmu_msi_index {
> >>>  	EVTQ_MSI_INDEX,
> >>> @@ -86,7 +87,8 @@ static struct arm_smmu_option_prop
> >>> arm_smmu_options[] = {
> >>>
> >>>  static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device
> >>> *smmu);  static int arm_smmu_domain_finalise(struct arm_smmu_domain
> >> *smmu_domain,
> >>> -				    struct arm_smmu_device *smmu);
> >>> +				    struct arm_smmu_device *smmu,
> >>> +				    bool enable_dirty);
> >>>  static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
> >>> static void arm_smmu_tlb_inv_all_s2(struct arm_smmu_domain
> >>> *smmu_domain);
> >>>
> >>> @@ -2378,7 +2380,7 @@ static struct iommu_domain
> >> *arm_smmu_domain_alloc_paging(struct device *dev)
> >>>  		struct arm_smmu_master *master =
> >> dev_iommu_priv_get(dev);
> >>>  		int ret;
> >>>
> >>> -		ret = arm_smmu_domain_finalise(smmu_domain, master-
> >>> smmu);
> >>> +		ret = arm_smmu_domain_finalise(smmu_domain, master-
> >>> smmu, false);
> >>>  		if (ret) {
> >>>  			kfree(smmu_domain);
> >>>  			return ERR_PTR(ret);
> >>> @@ -2445,10 +2447,11 @@ static void arm_smmu_domain_free(struct
> >>> iommu_domain *domain)  }
> >>>
> >>>  static int arm_smmu_domain_finalise(struct arm_smmu_domain
> >> *smmu_domain,
> >>> -				    struct arm_smmu_device *smmu)
> >>> +				    struct arm_smmu_device *smmu,
> >>> +				    bool enable_dirty)
> >>>  {
> >>>  	int ret;
> >>> -	unsigned long ias, oas;
> >>> +	unsigned long ias;
> >>>  	enum io_pgtable_fmt fmt;
> >>>  	struct io_pgtable_cfg pgtbl_cfg;
> >>>  	struct io_pgtable_ops *pgtbl_ops;
> >>> @@ -2459,31 +2462,31 @@ static int arm_smmu_domain_finalise(struct
> >> arm_smmu_domain *smmu_domain,
> >>>  	if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
> >>>  		smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
> >>>
> >>> +	pgtbl_cfg = (struct io_pgtable_cfg) {
> >>> +		.pgsize_bitmap	= smmu->pgsize_bitmap,
> >>> +		.coherent_walk	= smmu->features &
> >> ARM_SMMU_FEAT_COHERENCY,
> >>> +		.tlb		= &arm_smmu_flush_ops,
> >>> +		.iommu_dev	= smmu->dev,
> >>> +	};
> >>> +
> >>>  	switch (smmu_domain->stage) {
> >>>  	case ARM_SMMU_DOMAIN_S1:
> >>>  		ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
> >>> -		ias = min_t(unsigned long, ias, VA_BITS);
> >>> -		oas = smmu->ias;
> >>> +		pgtbl_cfg.ias = min_t(unsigned long, ias, VA_BITS);
> >>> +		pgtbl_cfg.oas = smmu->ias;
> >>> +		if (enable_dirty)
> >>> +			pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_HD;
> >>>  		fmt = ARM_64_LPAE_S1;
> >>>  		break;
> >>>  	case ARM_SMMU_DOMAIN_S2:
> >>> -		ias = smmu->ias;
> >>> -		oas = smmu->oas;
> >>> +		pgtbl_cfg.ias = smmu->ias;
> >>> +		pgtbl_cfg.oas = smmu->oas;
> >>>  		fmt = ARM_64_LPAE_S2;
> >>>  		break;
> >>>  	default:
> >>>  		return -EINVAL;
> >>>  	}
> >>>
> >>> -	pgtbl_cfg = (struct io_pgtable_cfg) {
> >>> -		.pgsize_bitmap	= smmu->pgsize_bitmap,
> >>> -		.ias		= ias,
> >>> -		.oas		= oas,
> >>> -		.coherent_walk	= smmu->features &
> >> ARM_SMMU_FEAT_COHERENCY,
> >>> -		.tlb		= &arm_smmu_flush_ops,
> >>> -		.iommu_dev	= smmu->dev,
> >>> -	};
> >>> -
> >>>  	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
> >>>  	if (!pgtbl_ops)
> >>>  		return -ENOMEM;
> >>> @@ -2491,7 +2494,8 @@ static int arm_smmu_domain_finalise(struct
> >> arm_smmu_domain *smmu_domain,
> >>>  	smmu_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
> >>>  	smmu_domain->domain.geometry.aperture_end = (1UL <<
> >> pgtbl_cfg.ias) - 1;
> >>>  	smmu_domain->domain.geometry.force_aperture = true;
> >>> -
> >>> +	if (enable_dirty && smmu_domain->stage ==
> >> ARM_SMMU_DOMAIN_S1)
> >>> +		smmu_domain->domain.dirty_ops =
> >> &arm_smmu_dirty_ops;
> >>>  	ret = arm_smmu_domain_alloc_id(smmu, smmu_domain);
> >>>  	if (ret < 0) {
> >>>  		free_io_pgtable_ops(pgtbl_ops);
> >>> @@ -2811,7 +2815,7 @@ static int arm_smmu_attach_dev(struct
> >> iommu_domain *domain, struct device *dev)
> >>>  	mutex_lock(&smmu_domain->init_mutex);
> >>>
> >>>  	if (!smmu_domain->smmu) {
> >>> -		ret = arm_smmu_domain_finalise(smmu_domain, smmu);
> >>> +		ret = arm_smmu_domain_finalise(smmu_domain, smmu,
> >> false);
> >>>  	} else if (smmu_domain->smmu != smmu)
> >>>  		ret = -EINVAL;
> >>>
> >>
> >>
> >> I think we are missing the domain attach_dev check for dirty tracking.
> >>
> >> Something like:
> >>
> >> if (domain->dirty_ops && !arm_smmu_dbm_capable(smmu))
> >> 	return -EINVAL;
> >>
> >> But that helper is only introduced in the last patch, so maybe:
> >>
> >> if (domain->dirty_ops &&
> >>     !device_iommu_capable(dev, IOMMU_CAP_DIRTY_TRACKING))
> >> 	return -EINVAL;
> >
> > Ok. But do we really need to check this in attach()? As dirty_ops are added only
> > if it is requested in alloc_user() and there we return err when hardware doesn't
> > have the capability.  So not sure how this matters in attach() path. May be I am
> > missing something.
> 
> That's when you create the domain with dev A. Afterwards that dev A is
> attached,
> but later on you can attach another device B to the domain. So this check is
> there such that a domain with dirty tracking ops set will only have devices in
> there that support dirty tracking.

But that only matters if dev B is on  different smmu without dbm capability, right?
In that case we already fail the attach with,

>>>  	} else if (smmu_domain->smmu != smmu)
> >>>  		ret = -EINVAL;
> >>>

Is that right?

Thanks,
Shameer
 

From will at kernel.org  Thu Feb 22 04:24:38 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 12:24:38 +0000
Subject: [PATCH v4 5/6] perf: imx_perf: limit counter ID from user space
 and optimize counter usage
In-Reply-To: <20240131055811.3035741-5-xu.yang_2@nxp.com>
References: <20240131055811.3035741-1-xu.yang_2@nxp.com>
 <20240131055811.3035741-5-xu.yang_2@nxp.com>
Message-ID: <20240222122438.GD8308@willie-the-truck>

On Wed, Jan 31, 2024 at 01:58:10PM +0800, Xu Yang wrote:
> The user can pass any counter ID to perf app. However, current pmu driver
> doesn't judge the validity of the counter ID. This will add necessary
> check for counter ID from user space. Besides, this pmu has 10 counters
> except cycle counter which can be used to count reference events and
> counter specific evnets. This will also add supports to auto allocate
> counter if the user doesn't pass it the perf. Then, the usage of counter
> will be optimized.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v2:
>  - limit counter ID from user to 0-10
>  - combine dynamic and static allocation of counter
> Changes in v3:
>  - no changes
> Changes in v4:
>  - rename ddr_perf_is_specific_event()
>  - use macro definitions to parse config attr
> ---
>  drivers/perf/fsl_imx9_ddr_perf.c | 72 +++++++++++++++++++++++++++++++-
>  1 file changed, 71 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c
> index 94041f06c152..e71496809c52 100644
> --- a/drivers/perf/fsl_imx9_ddr_perf.c
> +++ b/drivers/perf/fsl_imx9_ddr_perf.c
> @@ -51,6 +51,7 @@
>  
>  #define NUM_COUNTERS		11
>  #define CYCLES_COUNTER		0
> +#define CYCLES_EVENT_ID		0
>  
>  #define CONFIG_EVENT_MASK	0x00FF
>  #define CONFIG_EVENT_OFFSET	0
> @@ -240,6 +241,19 @@ static struct attribute *ddr_perf_events_attrs[] = {
>  	NULL,
>  };
>  
> +/*
> + * An event is either reference evnet or counter specific event.
> + * For counter specific event, the event count will only be incremented
> + * on the corresponding counter.
> + */
> +static bool ddr_perf_is_counter_specific_event(int event)
> +{
> +	if (event >= 64 && event <= 73)
> +		return true;
> +	else
> +		return false;

Just collapse this to 'return event >= 64 && event <= 73;'

Will


From will at kernel.org  Thu Feb 22 04:25:33 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 12:25:33 +0000
Subject: [PATCH v4 6/6] perf vendor events arm64:: Add i.MX95 DDR
 Performane Monitor metrics
In-Reply-To: <20240131055811.3035741-6-xu.yang_2@nxp.com>
References: <20240131055811.3035741-1-xu.yang_2@nxp.com>
 <20240131055811.3035741-6-xu.yang_2@nxp.com>
Message-ID: <20240222122533.GE8308@willie-the-truck>

On Wed, Jan 31, 2024 at 01:58:11PM +0800, Xu Yang wrote:
> Add JSON metrics for i.MX95 DDR Performane Monitor.

(nit: "Performane" => "Performance" here and in the subject)

Will


From brgl at bgdev.pl  Thu Feb 22 04:26:59 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 22 Feb 2024 13:26:59 +0100
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for WCN7850
In-Reply-To: <52fba837-989b-4213-8af7-f02cd8cb48c8@sirena.org.uk>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-15-brgl@bgdev.pl>
 <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk> <CAMRc=MeUjKPS3ANE6=7WZ3kbbGAdyE8HeXFN=75Jp-pVyBaWrQ@mail.gmail.com>
 <ea08a286-ff53-4d58-ae41-38cca151508c@sirena.org.uk> <17bbd9ae-0282-430e-947b-e6fb08c53af7@linaro.org>
 <53f0956f-ee64-4bd6-b44f-cbebafd42e46@sirena.org.uk> <CAMRc=MedCX_TGGawMhr39oXtJPF4pOQF=Jh2z4uXkOxwhfJWRw@mail.gmail.com>
 <52fba837-989b-4213-8af7-f02cd8cb48c8@sirena.org.uk>
Message-ID: <CAMRc=MeF7xVjRKetg1A3MNO4yMasPA2GC7MLCBrOiwO5UBv6LA@mail.gmail.com>

On Thu, Feb 22, 2024 at 1:21?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Thu, Feb 22, 2024 at 10:22:50AM +0100, Bartosz Golaszewski wrote:
> > On Wed, Feb 21, 2024 at 12:44?AM Mark Brown <broonie at kernel.org> wrote:
>
> > > Yes, that's the theory - I just question if it actually does something
> > > useful in practice.  Between regulators getting more and more able to
> > > figure out mode switching autonomously based on load monitoring and them
> > > getting more efficient it's become very unclear if this actually
> > > accomplishes anything, the only usage is the Qualcomm stuff and that's
> > > all really unsophisticated and has an air of something that's being
> > > cut'n'pasted forwards rather than delivering practical results.  There
> > > is some value at ultra low loads, but that's more for suspend modes than
> > > for actual use.
>
> > Removing it would be out of scope for this series and I don't really
> > want to introduce any undefined behavior when doing a big development
> > like that. I'll think about it separately.
>
> This is new code?

It's a new driver but Qualcomm standard has been to provide the load
values. If it's really unnecessary then maybe let's consider it
separately and possibly rework globally?

Bart


From brgl at bgdev.pl  Thu Feb 22 04:27:38 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 22 Feb 2024 13:27:38 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAA8EJprUM6=ZqTwWLB8rW8WRDqwncafa-szSsTvPQCOOSXUn_w@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org> <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org> <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
 <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
 <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com>
 <b9a31374-8ea9-407e-9ec3-008a95e2b18b@linaro.org> <CAA8EJppWY8c-pF75WaMadWtEuaAyCc5A1VLEq=JmB2Ngzk-zyw@mail.gmail.com>
 <CAMRc=Md6SoXukoGb4bW-CSYgjpO4RL+0Uu3tYrZzgSgVtFH6Sw@mail.gmail.com> <CAA8EJprUM6=ZqTwWLB8rW8WRDqwncafa-szSsTvPQCOOSXUn_w@mail.gmail.com>
Message-ID: <CAMRc=Metemd=24t0RJw-O9Z0-cg4mESouOfvMVLs_rJDCwRBPQ@mail.gmail.com>

On Thu, Feb 22, 2024 at 12:27?PM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Thu, 22 Feb 2024 at 13:00, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> >
> > On Mon, Feb 19, 2024 at 11:21?PM Dmitry Baryshkov
> > <dmitry.baryshkov at linaro.org> wrote:
> > >
> > > On Mon, 19 Feb 2024 at 19:18, <neil.armstrong at linaro.org> wrote:
> > > >
> > > > On 19/02/2024 13:33, Dmitry Baryshkov wrote:
> > > > > On Mon, 19 Feb 2024 at 14:23, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> > > > >>
> > > > >> On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
> > > > >> <dmitry.baryshkov at linaro.org> wrote:
> > > > >>>
> > > > >>
> > > > >> [snip]
> > > > >>
> > > > >>>>>>>>
> > > > >>>>>>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> > > > >>>>>>>> necessary. The BT and WLAN devices on the device-tree are represented as
> > > > >>>>>>>> consuming the inputs (relevant to the functionality of each) of the PMU
> > > > >>>>>>>> directly.
> > > > >>>>>>>
> > > > >>>>>>> We are describing the hardware. From the hardware point of view, there
> > > > >>>>>>> is a PMU. I think at some point we would really like to describe all
> > > > >>>>>>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> > > > >>>>>>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
> > > > >>>>>>
> > > > >>>>>> While I agree with older WiFi+BT units, I don't think it's needed for
> > > > >>>>>> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
> > > > >>>>>> transparent.
> > > > >>>>>
> > > > >>>>> I don't see any significant difference between WCN6750/WCN6855 and
> > > > >>>>> WCN7850 from the PMU / power up point of view. Could you please point
> > > > >>>>> me to the difference?
> > > > >>>>>
> > > > >>>>
> > > > >>>> The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
> > > > >>>> and BT_EN ordering and the only requirement is to have all input regulators
> > > > >>>> up before pulling up WLAN_EN and/or BT_EN.
> > > > >>>>
> > > > >>>> This makes the PMU transparent and BT and WLAN can be described as independent.
> > > > >>>
> > > > >>>  From the hardware perspective, there is a PMU. It has several LDOs. So
> > > > >>> the device tree should have the same style as the previous
> > > > >>> generations.
> > > > >>>
> > > > >>
> > > > >> My thinking was this: yes, there is a PMU but describing it has no
> > > > >> benefit (unlike QCA6x90). If we do describe, then we'll end up having
> > > > >> to use pwrseq here despite it not being needed because now we won't be
> > > > >> able to just get regulators from WLAN/BT drivers directly.
> > > > >>
> > > > >> So I also vote for keeping it this way. Let's go into the package
> > > > >> detail only if it's required.
> > > > >
> > > > > The WiFi / BT parts are not powered up by the board regulators. They
> > > > > are powered up by the PSU. So we are not describing it in the accurate
> > > > > way.
> > > >
> > > > I disagree, the WCN7850 can also be used as a discrete PCIe M.2 card, and in
> > > > this situation the PCIe part is powered with the M.2 slot and the BT side
> > > > is powered separately as we currently do it now.
> > >
> > > QCA6390 can also be used as a discrete M.2 card.
> > >
> > > > So yes there's a PMU, but it's not an always visible hardware part, from the
> > > > SoC PoV, only the separate PCIe and BT subsystems are visible/controllable/powerable.
> > >
> > > From the hardware point:
> > > - There is a PMU
> > > - The PMU is connected to the board supplies
> > > - Both WiFi and BT parts are connected to the PMU
> > > - The BT_EN / WLAN_EN pins are not connected to the PMU
> > >
> > > So, not representing the PMU in the device tree is a simplification.
> > >
> >
> > What about the existing WLAN and BT users of similar packages? We
> > would have to deprecate a lot of existing bindings. I don't think it's
> > worth it.
>
> We have bindings that are not reflecting the hardware. So yes, we
> should gradually update them once the powerseq is merged.
>
> > The WCN7850 is already described in bindings as consuming what is PMUs
> > inputs and not its outputs.
>
> So do WCN6855 and QCA6391 BlueTooth parts.
>

That is not true for the latter, this series is adding regulators for it.

Bart

> >
> > Bart
> >
> > > >
> > > > Neil
> > > >
> > > > >
> > > > > Moreover, I think we definitely want to move BT driver to use only the
> > > > > pwrseq power up method. Doing it in the other way results in the code
> > > > > duplication and possible issues because of the regulator / pwrseq
> > > > > taking different code paths.
> > >
> > > --
> > > With best wishes
> > > Dmitry
>
>
>
> --
> With best wishes
> Dmitry


From y.varakala at phytec.de  Thu Feb 22 04:28:49 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Thu, 22 Feb 2024 13:28:49 +0100
Subject: [PATCH v2 0/4] Update of phyBOARD-Pollux-i.MX8MP
Message-ID: <20240222122853.41753-1-y.varakala@phytec.de>

Hello,

These patches will update the imx8mp-phyboard-pollux devicetree
with the Muxing and RTC properties.
 
Thankyou,
yashwanth.

Changes in v2: 
-Corrected the commit message.
-Corrected the authorship.

Dominik Haller (1):
  arm64: dts: imx8mp-phyboard-pollux: Disable pull-up for CD GPIO

Teresa Remmet (1):
  arm64: dts: imx8mp-phyboard-pollux: Reduce drive strength for eqos tx
    lines

Yannic Moog (1):
  arm64: dts: imx8mp-phyboard-pollux: Set debug uart muxing to 0x140

Yashwanth Varakala (1):
  arm64: dts: imx8mp-phyboard-pollux: Add and update rtc devicetree node

 .../freescale/imx8mp-phyboard-pollux-rdk.dts  | 33 ++++++++++++++-----
 .../dts/freescale/imx8mp-phycore-som.dtsi     |  1 -
 2 files changed, 24 insertions(+), 10 deletions(-)

-- 
2.34.1



From y.varakala at phytec.de  Thu Feb 22 04:28:51 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Thu, 22 Feb 2024 13:28:51 +0100
Subject: [PATCH v2 2/4] arm64: dts: imx8mp-phyboard-pollux: Set debug uart muxing to 0x140
In-Reply-To: <20240222122853.41753-1-y.varakala@phytec.de>
References: <20240222122853.41753-1-y.varakala@phytec.de>
Message-ID: <20240222122853.41753-3-y.varakala@phytec.de>

From: Yannic Moog <y.moog at phytec.de>

Set Pull Resistors Enable bit to put signal into a defined state.

Signed-off-by: Yannic Moog <y.moog at phytec.de>
Signed-off-by: Benjamin Hahn <B.Hahn at phytec.de>
Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
---
Changes in v2:
-Corrected the Authorship.

 arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index 96754ce633ed..36b59d0c67f7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -312,8 +312,8 @@ MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19	0x1C0
 
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x40
-			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x40
+			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x140
+			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x140
 		>;
 	};
 
-- 
2.34.1



From y.varakala at phytec.de  Thu Feb 22 04:28:52 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Thu, 22 Feb 2024 13:28:52 +0100
Subject: [PATCH v2 3/4] arm64: dts: imx8mp-phyboard-pollux: Reduce drive strength for eqos tx lines
In-Reply-To: <20240222122853.41753-1-y.varakala@phytec.de>
References: <20240222122853.41753-1-y.varakala@phytec.de>
Message-ID: <20240222122853.41753-4-y.varakala@phytec.de>

From: Teresa Remmet <t.remmet at phytec.de>

Reduce drive strength on eqos tx lines for signal quality improvements.

Signed-off-by: Teresa Remmet <t.remmet at phytec.de>
Signed-off-by: Benjamin Hahn <B.Hahn at phytec.de>
Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
---
Changes in v2:
-Corrected the Authorship.

 .../dts/freescale/imx8mp-phyboard-pollux-rdk.dts     | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index 36b59d0c67f7..d36ce66f08ef 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -248,12 +248,12 @@ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2		0x90
 			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3		0x90
 			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x90
 			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL		0x90
-			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x16
-			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x16
-			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x16
-			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x16
-			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x16
-			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x16
+			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x12
+			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x12
+			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x12
+			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x12
+			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x12
+			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x12
 			MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20			0x10
 		>;
 	};
-- 
2.34.1



From y.varakala at phytec.de  Thu Feb 22 04:28:50 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Thu, 22 Feb 2024 13:28:50 +0100
Subject: [PATCH v2 1/4] arm64: dts: imx8mp-phyboard-pollux: Add and update rtc devicetree node
In-Reply-To: <20240222122853.41753-1-y.varakala@phytec.de>
References: <20240222122853.41753-1-y.varakala@phytec.de>
Message-ID: <20240222122853.41753-2-y.varakala@phytec.de>

The interrupt of the RTC is connected on the carrier board
phyBOARD-i.MX8MP-Pollux.

RTC trickle-charger devicetree property is dependent on the
phyboard-pollux design.

Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
---
Changes in v2:
-Corrected the commit message.

 .../dts/freescale/imx8mp-phyboard-pollux-rdk.dts  | 15 +++++++++++++++
 .../boot/dts/freescale/imx8mp-phycore-som.dtsi    |  1 -
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index c8640cac3edc..96754ce633ed 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -139,6 +139,15 @@ &snvs_pwrkey {
 	status = "okay";
 };
 
+&rv3028 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rtc>;
+	interrupt-parent = <&gpio4>;
+	interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+	wakeup-source;
+	trickle-resistor-ohms = <3000>;
+};
+
 /* debug console */
 &uart1 {
 	pinctrl-names = "default";
@@ -295,6 +304,12 @@ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40
 		>;
 	};
 
+	pinctrl_rtc: rtcgrp {
+		fsl,pins = <
+			MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19	0x1C0
+		>;
+	};
+
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
 			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x40
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
index c976c3b6cbc6..e6ffa6a6b68b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
@@ -175,7 +175,6 @@ eeprom at 51 {
 	rv3028: rtc at 52 {
 		compatible = "microcrystal,rv3028";
 		reg = <0x52>;
-		trickle-resistor-ohms = <3000>;
 	};
 };
 
-- 
2.34.1



From y.varakala at phytec.de  Thu Feb 22 04:28:53 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Thu, 22 Feb 2024 13:28:53 +0100
Subject: [PATCH v2 4/4] arm64: dts: imx8mp-phyboard-pollux: Disable pull-up for CD GPIO
In-Reply-To: <20240222122853.41753-1-y.varakala@phytec.de>
References: <20240222122853.41753-1-y.varakala@phytec.de>
Message-ID: <20240222122853.41753-5-y.varakala@phytec.de>

From: Dominik Haller <d.haller at phytec.de>

Removes the pull-up resistor from the pad's settings to keep it
consistent for all boards. We have pull-ups in hardware on all boards so we
don't need to set the additional one from the iomux controller.

Signed-off-by: Dominik Haller <d.haller at phytec.de>
Signed-off-by: Benjamin Hahn <B.Hahn at phytec.de>
Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
---
Changes in v2:
-Corrected the Authorship.

 arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index d36ce66f08ef..1dfc5f429981 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -334,7 +334,7 @@ MX8MP_IOMUXC_SAI3_RXD__UART2_DCE_RTS	0x140
 
 	pinctrl_usdhc2_pins: usdhc2-gpiogrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12	0x1c4
+			MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12	0x40
 		>;
 	};
 
-- 
2.34.1



From sashal at kernel.org  Thu Feb 22 04:37:46 2024
From: sashal at kernel.org (Sasha Levin)
Date: Thu, 22 Feb 2024 07:37:46 -0500
Subject: [PATCH AUTOSEL 6.1 27/27] i2c: rk3x: Adjust mask/value offset
 for i2c2 on rv1126
In-Reply-To: <030766c0-a6b9-401d-9e9a-fe5d11c5d381@feathertop.org>
References: <20240128161424.203600-1-sashal@kernel.org>
 <20240128161424.203600-27-sashal@kernel.org>
 <030766c0-a6b9-401d-9e9a-fe5d11c5d381@feathertop.org>
Message-ID: <ZddAGs9pKyLV37zP@sashalap>

On Mon, Jan 29, 2024 at 10:19:35AM +1100, Tim Lunn wrote:
>Hi Sasha,
>
>? Support for the rv1126 SoC was only added around linux 6.2 and 6.3, 
>thus doesnt make sense to pick this patch up in 6.1

I'll drop it from 6.1 (and older), thanks!

-- 
Thanks,
Sasha


From vidyas at nvidia.com  Thu Feb 22 04:41:10 2024
From: vidyas at nvidia.com (Vidya Sagar)
Date: Thu, 22 Feb 2024 18:11:10 +0530
Subject: [PATCH V3] PCI: Add support for preserving boot configuration
In-Reply-To: <20240110030725.710547-3-vidyas@nvidia.com>
References: <20240110030725.710547-3-vidyas@nvidia.com>
Message-ID: <20240222124110.2681455-1-vidyas@nvidia.com>

Add support for preserving the boot configuration done by the
platform firmware per host bridge basis, based on the presence of
'linux,pci-probe-only' property in the respective PCIe host bridge
device-tree node. It also unifies the ACPI and DT based boot flows
in this regard.

Signed-off-by: Vidya Sagar <vidyas at nvidia.com>
---
V3:
* Unified ACPI and DT flows as part of addressing Bjorn's review comments

V2:
* Addressed issues reported by kernel test robot <lkp at intel.com>

 drivers/acpi/pci_root.c                  | 12 -------
 drivers/pci/controller/pci-host-common.c |  4 ---
 drivers/pci/of.c                         | 22 ++++++++++++
 drivers/pci/probe.c                      | 46 ++++++++++++++++++------
 include/linux/of_pci.h                   |  6 ++++
 5 files changed, 63 insertions(+), 27 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 84030804a763..ddc2b3e89111 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -1008,7 +1008,6 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	int node = acpi_get_node(device->handle);
 	struct pci_bus *bus;
 	struct pci_host_bridge *host_bridge;
-	union acpi_object *obj;
 
 	info->root = root;
 	info->bridge = device;
@@ -1050,17 +1049,6 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	if (!(root->osc_ext_control_set & OSC_CXL_ERROR_REPORTING_CONTROL))
 		host_bridge->native_cxl_error = 0;
 
-	/*
-	 * Evaluate the "PCI Boot Configuration" _DSM Function.  If it
-	 * exists and returns 0, we must preserve any PCI resource
-	 * assignments made by firmware for this host bridge.
-	 */
-	obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 1,
-				DSM_PCI_PRESERVE_BOOT_CONFIG, NULL);
-	if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0)
-		host_bridge->preserve_config = 1;
-	ACPI_FREE(obj);
-
 	acpi_dev_power_up_children_with_adr(device);
 
 	pci_scan_child_bus(bus);
diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index 6be3266cd7b5..e2602e38ae45 100644
--- a/drivers/pci/controller/pci-host-common.c
+++ b/drivers/pci/controller/pci-host-common.c
@@ -73,10 +73,6 @@ int pci_host_common_probe(struct platform_device *pdev)
 	if (IS_ERR(cfg))
 		return PTR_ERR(cfg);
 
-	/* Do not reassign resources if probe only */
-	if (!pci_has_flag(PCI_PROBE_ONLY))
-		pci_add_flags(PCI_REASSIGN_ALL_BUS);
-
 	bridge->sysdata = cfg;
 	bridge->ops = (struct pci_ops *)&ops->pci_ops;
 	bridge->msi_domain = true;
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 51e3dd0ea5ab..7b553dd83587 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -258,6 +258,28 @@ void of_pci_check_probe_only(void)
 }
 EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
 
+/**
+ * of_pci_bridge_check_probe_only - Return true if the boot configuration
+ *                                  needs to be preserved
+ * @node: Device tree node with the domain information.
+ *
+ * This function looks for "linux,pci-probe-only" property for a given
+ * PCIe controller's node and returns true if found. Having this property
+ * for a PCIe controller ensures that the kernel doesn't re-enumerate and
+ * reconfigure the BAR resources that are already done by the platform firmware.
+ * NOTE: The scope of "linux,pci-probe-only" defined within a PCIe bridge device
+ *       is limited to the hierarchy under that particular bridge device. whereas
+ *       the scope of "linux,pci-probe-only" defined within chosen node is
+ *       system wide.
+ *
+ * Return: true if the property exists false otherwise.
+ */
+bool of_pci_bridge_check_probe_only(struct device_node *node)
+{
+	return of_property_read_bool(node, "linux,pci-probe-only");
+}
+EXPORT_SYMBOL_GPL(of_pci_bridge_check_probe_only);
+
 /**
  * devm_of_pci_get_host_bridge_resources() - Resource-managed parsing of PCI
  *                                           host bridge resources from DT
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 795534589b98..d62d1f151ba9 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -15,6 +15,7 @@
 #include <linux/cpumask.h>
 #include <linux/aer.h>
 #include <linux/acpi.h>
+#include <linux/pci-acpi.h>
 #include <linux/hypervisor.h>
 #include <linux/irqdomain.h>
 #include <linux/pm_runtime.h>
@@ -877,6 +878,28 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus)
 	dev_set_msi_domain(&bus->dev, d);
 }
 
+static void pci_check_config_preserve(struct pci_host_bridge *host_bridge)
+{
+	if (&host_bridge->dev) {
+		union acpi_object *obj;
+
+		/*
+		 * Evaluate the "PCI Boot Configuration" _DSM Function.  If it
+		 * exists and returns 0, we must preserve any PCI resource
+		 * assignments made by firmware for this host bridge.
+		 */
+		obj = acpi_evaluate_dsm(ACPI_HANDLE(&host_bridge->dev), &pci_acpi_dsm_guid, 1,
+					DSM_PCI_PRESERVE_BOOT_CONFIG, NULL);
+		if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0)
+			host_bridge->preserve_config = 1;
+		ACPI_FREE(obj);
+	}
+
+	if (host_bridge->dev.parent && host_bridge->dev.parent->of_node)
+		host_bridge->preserve_config =
+			of_pci_bridge_check_probe_only(host_bridge->dev.parent->of_node);
+}
+
 static int pci_register_host_bridge(struct pci_host_bridge *bridge)
 {
 	struct device *parent = bridge->dev.parent;
@@ -971,6 +994,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
 	if (nr_node_ids > 1 && pcibus_to_node(bus) == NUMA_NO_NODE)
 		dev_warn(&bus->dev, "Unknown NUMA node; performance will be reduced\n");
 
+	/* Check if the boot configuration by FW needs to be preserved */
+	pci_check_config_preserve(bridge);
+
 	/* Coalesce contiguous windows */
 	resource_list_for_each_entry_safe(window, n, &resources) {
 		if (list_is_last(&window->node, &resources))
@@ -3080,20 +3106,18 @@ int pci_host_probe(struct pci_host_bridge *bridge)
 
 	bus = bridge->bus;
 
+	/* If we must preserve the resource configuration, claim now */
+	if (pci_has_flag(PCI_PROBE_ONLY) || bridge->preserve_config)
+		pci_bus_claim_resources(bus);
+
 	/*
-	 * We insert PCI resources into the iomem_resource and
-	 * ioport_resource trees in either pci_bus_claim_resources()
-	 * or pci_bus_assign_resources().
+	 * Assign whatever was left unassigned. If we didn't claim above,
+	 * this will reassign everything.
 	 */
-	if (pci_has_flag(PCI_PROBE_ONLY)) {
-		pci_bus_claim_resources(bus);
-	} else {
-		pci_bus_size_bridges(bus);
-		pci_bus_assign_resources(bus);
+	pci_assign_unassigned_root_bus_resources(bus);
 
-		list_for_each_entry(child, &bus->children, node)
-			pcie_bus_configure_settings(child);
-	}
+	list_for_each_entry(child, &bus->children, node)
+		pcie_bus_configure_settings(child);
 
 	pci_bus_add_devices(bus);
 	return 0;
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 29658c0ee71f..9e045de3be44 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -13,6 +13,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
 					     unsigned int devfn);
 int of_pci_get_devfn(struct device_node *np);
 void of_pci_check_probe_only(void);
+bool of_pci_bridge_check_probe_only(struct device_node *node);
 #else
 static inline struct device_node *of_pci_find_child_device(struct device_node *parent,
 					     unsigned int devfn)
@@ -26,6 +27,11 @@ static inline int of_pci_get_devfn(struct device_node *np)
 }
 
 static inline void of_pci_check_probe_only(void) { }
+
+static inline bool of_pci_bridge_check_probe_only(struct device_node *node)
+{
+	return false;
+}
 #endif
 
 #if IS_ENABLED(CONFIG_OF_IRQ)
-- 
2.25.1



From prabhakar.csengg at gmail.com  Thu Feb 22 04:44:55 2024
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Thu, 22 Feb 2024 12:44:55 +0000
Subject: [PATCH 2/4] dt-bindings: arm: renesas: Document Renesas RZ/V2H{P}
 System Controller
In-Reply-To: <47c8bbe3-610d-40cc-b505-e9ce9a371ef7@linaro.org>
References: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20240219160912.1206647-3-prabhakar.mahadev-lad.rj@bp.renesas.com> <47c8bbe3-610d-40cc-b505-e9ce9a371ef7@linaro.org>
Message-ID: <CA+V-a8uPY8hwJc4xv7=K4eazTTVpvOwteRKnnFmXhHGyCsM6qA@mail.gmail.com>

Hi Krzysztof,

Thank you for the review.

On Tue, Feb 20, 2024 at 9:51?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 19/02/2024 17:09, Prabhakar wrote:
> > From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> >
> > Add DT binding documentation for System Controller (SYS) found on
> > RZ/V2H{P} ("R9A09G057") SoC's.
> >
> > SYS block contains the SYS_LSI_DEVID register which can be used to
> > retrieve SoC version information.
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> > Reviewed-by: Fabrizio Castro <fabrizio.castro.jz at renesas.com>
>
>
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    extal_clk: extal-clk {
> > +        compatible = "fixed-clock";
> > +        #clock-cells = <0>;
> > +        clock-frequency = <24000000>;
> > +    };
>
> Drop the node, not relevant.
>
OK, I'll drop the clock node in the next version.

Cheers,
Prabhakar


From dmitry.baryshkov at linaro.org  Thu Feb 22 04:47:20 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 22 Feb 2024 14:47:20 +0200
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAMRc=Metemd=24t0RJw-O9Z0-cg4mESouOfvMVLs_rJDCwRBPQ@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org> <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org> <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
 <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
 <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com>
 <b9a31374-8ea9-407e-9ec3-008a95e2b18b@linaro.org> <CAA8EJppWY8c-pF75WaMadWtEuaAyCc5A1VLEq=JmB2Ngzk-zyw@mail.gmail.com>
 <CAMRc=Md6SoXukoGb4bW-CSYgjpO4RL+0Uu3tYrZzgSgVtFH6Sw@mail.gmail.com>
 <CAA8EJprUM6=ZqTwWLB8rW8WRDqwncafa-szSsTvPQCOOSXUn_w@mail.gmail.com> <CAMRc=Metemd=24t0RJw-O9Z0-cg4mESouOfvMVLs_rJDCwRBPQ@mail.gmail.com>
Message-ID: <CAA8EJprJTj7o0ATrQbF_38tW+kLspF1nBySg+_y_RWmadVnV9A@mail.gmail.com>

On Thu, 22 Feb 2024 at 14:27, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> On Thu, Feb 22, 2024 at 12:27?PM Dmitry Baryshkov
> <dmitry.baryshkov at linaro.org> wrote:
> >
> > On Thu, 22 Feb 2024 at 13:00, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> > >
> > > On Mon, Feb 19, 2024 at 11:21?PM Dmitry Baryshkov
> > > <dmitry.baryshkov at linaro.org> wrote:
> > > >
> > > > On Mon, 19 Feb 2024 at 19:18, <neil.armstrong at linaro.org> wrote:
> > > > >
> > > > > On 19/02/2024 13:33, Dmitry Baryshkov wrote:
> > > > > > On Mon, 19 Feb 2024 at 14:23, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> > > > > >>
> > > > > >> On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
> > > > > >> <dmitry.baryshkov at linaro.org> wrote:
> > > > > >>>
> > > > > >>
> > > > > >> [snip]
> > > > > >>
> > > > > >>>>>>>>
> > > > > >>>>>>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> > > > > >>>>>>>> necessary. The BT and WLAN devices on the device-tree are represented as
> > > > > >>>>>>>> consuming the inputs (relevant to the functionality of each) of the PMU
> > > > > >>>>>>>> directly.
> > > > > >>>>>>>
> > > > > >>>>>>> We are describing the hardware. From the hardware point of view, there
> > > > > >>>>>>> is a PMU. I think at some point we would really like to describe all
> > > > > >>>>>>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> > > > > >>>>>>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
> > > > > >>>>>>
> > > > > >>>>>> While I agree with older WiFi+BT units, I don't think it's needed for
> > > > > >>>>>> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
> > > > > >>>>>> transparent.
> > > > > >>>>>
> > > > > >>>>> I don't see any significant difference between WCN6750/WCN6855 and
> > > > > >>>>> WCN7850 from the PMU / power up point of view. Could you please point
> > > > > >>>>> me to the difference?
> > > > > >>>>>
> > > > > >>>>
> > > > > >>>> The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
> > > > > >>>> and BT_EN ordering and the only requirement is to have all input regulators
> > > > > >>>> up before pulling up WLAN_EN and/or BT_EN.
> > > > > >>>>
> > > > > >>>> This makes the PMU transparent and BT and WLAN can be described as independent.
> > > > > >>>
> > > > > >>>  From the hardware perspective, there is a PMU. It has several LDOs. So
> > > > > >>> the device tree should have the same style as the previous
> > > > > >>> generations.
> > > > > >>>
> > > > > >>
> > > > > >> My thinking was this: yes, there is a PMU but describing it has no
> > > > > >> benefit (unlike QCA6x90). If we do describe, then we'll end up having
> > > > > >> to use pwrseq here despite it not being needed because now we won't be
> > > > > >> able to just get regulators from WLAN/BT drivers directly.
> > > > > >>
> > > > > >> So I also vote for keeping it this way. Let's go into the package
> > > > > >> detail only if it's required.
> > > > > >
> > > > > > The WiFi / BT parts are not powered up by the board regulators. They
> > > > > > are powered up by the PSU. So we are not describing it in the accurate
> > > > > > way.
> > > > >
> > > > > I disagree, the WCN7850 can also be used as a discrete PCIe M.2 card, and in
> > > > > this situation the PCIe part is powered with the M.2 slot and the BT side
> > > > > is powered separately as we currently do it now.
> > > >
> > > > QCA6390 can also be used as a discrete M.2 card.
> > > >
> > > > > So yes there's a PMU, but it's not an always visible hardware part, from the
> > > > > SoC PoV, only the separate PCIe and BT subsystems are visible/controllable/powerable.
> > > >
> > > > From the hardware point:
> > > > - There is a PMU
> > > > - The PMU is connected to the board supplies
> > > > - Both WiFi and BT parts are connected to the PMU
> > > > - The BT_EN / WLAN_EN pins are not connected to the PMU
> > > >
> > > > So, not representing the PMU in the device tree is a simplification.
> > > >
> > >
> > > What about the existing WLAN and BT users of similar packages? We
> > > would have to deprecate a lot of existing bindings. I don't think it's
> > > worth it.
> >
> > We have bindings that are not reflecting the hardware. So yes, we
> > should gradually update them once the powerseq is merged.
> >
> > > The WCN7850 is already described in bindings as consuming what is PMUs
> > > inputs and not its outputs.
> >
> > So do WCN6855 and QCA6391 BlueTooth parts.
> >
>
> That is not true for the latter, this series is adding regulators for it.

But the bindings exist already, so you still have to extend it,
deprecating regulator-less bindings.

Bartosz, I really don't understand what is the issue there. There is a
PMU. As such it should be represented in the DT and it can be handled
by the same driver as you are adding for QCA6390.

>
> Bart
>
> > >
> > > Bart
> > >
> > > > >
> > > > > Neil
> > > > >
> > > > > >
> > > > > > Moreover, I think we definitely want to move BT driver to use only the
> > > > > > pwrseq power up method. Doing it in the other way results in the code
> > > > > > duplication and possible issues because of the regulator / pwrseq
> > > > > > taking different code paths.
> > > >
> > > > --
> > > > With best wishes
> > > > Dmitry
> >
> >
> >
> > --
> > With best wishes
> > Dmitry



-- 
With best wishes
Dmitry


From brgl at bgdev.pl  Thu Feb 22 04:50:40 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 22 Feb 2024 13:50:40 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAA8EJprJTj7o0ATrQbF_38tW+kLspF1nBySg+_y_RWmadVnV9A@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl> <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org> <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org> <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
 <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
 <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com>
 <b9a31374-8ea9-407e-9ec3-008a95e2b18b@linaro.org> <CAA8EJppWY8c-pF75WaMadWtEuaAyCc5A1VLEq=JmB2Ngzk-zyw@mail.gmail.com>
 <CAMRc=Md6SoXukoGb4bW-CSYgjpO4RL+0Uu3tYrZzgSgVtFH6Sw@mail.gmail.com>
 <CAA8EJprUM6=ZqTwWLB8rW8WRDqwncafa-szSsTvPQCOOSXUn_w@mail.gmail.com>
 <CAMRc=Metemd=24t0RJw-O9Z0-cg4mESouOfvMVLs_rJDCwRBPQ@mail.gmail.com> <CAA8EJprJTj7o0ATrQbF_38tW+kLspF1nBySg+_y_RWmadVnV9A@mail.gmail.com>
Message-ID: <CAMRc=MfkQuaJ3FnVwbVKQRQEgmJKbZh7SJoK3Kbmb5ebzE2rKA@mail.gmail.com>

On Thu, Feb 22, 2024 at 1:47?PM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On Thu, 22 Feb 2024 at 14:27, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> >
> > On Thu, Feb 22, 2024 at 12:27?PM Dmitry Baryshkov
> > <dmitry.baryshkov at linaro.org> wrote:
> > >
> > > On Thu, 22 Feb 2024 at 13:00, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> > > >
> > > > On Mon, Feb 19, 2024 at 11:21?PM Dmitry Baryshkov
> > > > <dmitry.baryshkov at linaro.org> wrote:
> > > > >
> > > > > On Mon, 19 Feb 2024 at 19:18, <neil.armstrong at linaro.org> wrote:
> > > > > >
> > > > > > On 19/02/2024 13:33, Dmitry Baryshkov wrote:
> > > > > > > On Mon, 19 Feb 2024 at 14:23, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> > > > > > >>
> > > > > > >> On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
> > > > > > >> <dmitry.baryshkov at linaro.org> wrote:
> > > > > > >>>
> > > > > > >>
> > > > > > >> [snip]
> > > > > > >>
> > > > > > >>>>>>>>
> > > > > > >>>>>>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
> > > > > > >>>>>>>> necessary. The BT and WLAN devices on the device-tree are represented as
> > > > > > >>>>>>>> consuming the inputs (relevant to the functionality of each) of the PMU
> > > > > > >>>>>>>> directly.
> > > > > > >>>>>>>
> > > > > > >>>>>>> We are describing the hardware. From the hardware point of view, there
> > > > > > >>>>>>> is a PMU. I think at some point we would really like to describe all
> > > > > > >>>>>>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
> > > > > > >>>>>>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
> > > > > > >>>>>>
> > > > > > >>>>>> While I agree with older WiFi+BT units, I don't think it's needed for
> > > > > > >>>>>> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
> > > > > > >>>>>> transparent.
> > > > > > >>>>>
> > > > > > >>>>> I don't see any significant difference between WCN6750/WCN6855 and
> > > > > > >>>>> WCN7850 from the PMU / power up point of view. Could you please point
> > > > > > >>>>> me to the difference?
> > > > > > >>>>>
> > > > > > >>>>
> > > > > > >>>> The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
> > > > > > >>>> and BT_EN ordering and the only requirement is to have all input regulators
> > > > > > >>>> up before pulling up WLAN_EN and/or BT_EN.
> > > > > > >>>>
> > > > > > >>>> This makes the PMU transparent and BT and WLAN can be described as independent.
> > > > > > >>>
> > > > > > >>>  From the hardware perspective, there is a PMU. It has several LDOs. So
> > > > > > >>> the device tree should have the same style as the previous
> > > > > > >>> generations.
> > > > > > >>>
> > > > > > >>
> > > > > > >> My thinking was this: yes, there is a PMU but describing it has no
> > > > > > >> benefit (unlike QCA6x90). If we do describe, then we'll end up having
> > > > > > >> to use pwrseq here despite it not being needed because now we won't be
> > > > > > >> able to just get regulators from WLAN/BT drivers directly.
> > > > > > >>
> > > > > > >> So I also vote for keeping it this way. Let's go into the package
> > > > > > >> detail only if it's required.
> > > > > > >
> > > > > > > The WiFi / BT parts are not powered up by the board regulators. They
> > > > > > > are powered up by the PSU. So we are not describing it in the accurate
> > > > > > > way.
> > > > > >
> > > > > > I disagree, the WCN7850 can also be used as a discrete PCIe M.2 card, and in
> > > > > > this situation the PCIe part is powered with the M.2 slot and the BT side
> > > > > > is powered separately as we currently do it now.
> > > > >
> > > > > QCA6390 can also be used as a discrete M.2 card.
> > > > >
> > > > > > So yes there's a PMU, but it's not an always visible hardware part, from the
> > > > > > SoC PoV, only the separate PCIe and BT subsystems are visible/controllable/powerable.
> > > > >
> > > > > From the hardware point:
> > > > > - There is a PMU
> > > > > - The PMU is connected to the board supplies
> > > > > - Both WiFi and BT parts are connected to the PMU
> > > > > - The BT_EN / WLAN_EN pins are not connected to the PMU
> > > > >
> > > > > So, not representing the PMU in the device tree is a simplification.
> > > > >
> > > >
> > > > What about the existing WLAN and BT users of similar packages? We
> > > > would have to deprecate a lot of existing bindings. I don't think it's
> > > > worth it.
> > >
> > > We have bindings that are not reflecting the hardware. So yes, we
> > > should gradually update them once the powerseq is merged.
> > >
> > > > The WCN7850 is already described in bindings as consuming what is PMUs
> > > > inputs and not its outputs.
> > >
> > > So do WCN6855 and QCA6391 BlueTooth parts.
> > >
> >
> > That is not true for the latter, this series is adding regulators for it.
>
> But the bindings exist already, so you still have to extend it,
> deprecating regulator-less bindings.
>
> Bartosz, I really don't understand what is the issue there. There is a
> PMU. As such it should be represented in the DT and it can be handled
> by the same driver as you are adding for QCA6390.
>

The issue is that we'll pull in the pwrseq subsystem for WCN7850 which
clearly does not require it in practice.

I'd like to hear Krzysztof, Conor or Rob chime in here and make the
decision on how to proceed.

Bart

> >
> > Bart
> >
> > > >
> > > > Bart
> > > >
> > > > > >
> > > > > > Neil
> > > > > >
> > > > > > >
> > > > > > > Moreover, I think we definitely want to move BT driver to use only the
> > > > > > > pwrseq power up method. Doing it in the other way results in the code
> > > > > > > duplication and possible issues because of the regulator / pwrseq
> > > > > > > taking different code paths.
> > > > >
> > > > > --
> > > > > With best wishes
> > > > > Dmitry
> > >
> > >
> > >
> > > --
> > > With best wishes
> > > Dmitry
>
>
>
> --
> With best wishes
> Dmitry


From will at kernel.org  Thu Feb 22 04:57:08 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 12:57:08 +0000
Subject: [PATCH v6 0/4] StarFive's StarLink PMU Support
In-Reply-To: <20240129095141.3262366-1-jisheng.teoh@starfivetech.com>
References: <20240129095141.3262366-1-jisheng.teoh@starfivetech.com>
Message-ID: <20240222125707.GA8589@willie-the-truck>

On Mon, Jan 29, 2024 at 05:51:37PM +0800, Ji Sheng Teoh wrote:
> This patch series adds support for StarFive's Starlink Performance
> Monitor Unit(PMU).
> StarFive's StarLink PMU integrates one or more CPU cores with
> a shared L3 memory system. The PMU supports overflow interrupt,
> up to 16 programmable 64bit event counters, and an independent
> 64bit cycle counter.
> StarLink PMU is accessed via MMIO.
> 
> Example Perf stat output:
> [root at user]# perf stat -a -e /starfive_starlink_pmu/cycles/ \
>         -e /starfive_starlink_pmu/read_miss/ \
>         -e /starfive_starlink_pmu/read_hit/ \
>         -e /starfive_starlink_pmu/release_request/  \
>         -e /starfive_starlink_pmu/write_hit/ \
>         -e /starfive_starlink_pmu/write_miss/ \
>         -e /starfive_starlink_pmu/write_request/ \
>         -e /starfive_starlink_pmu/writeback/ \
>         -e /starfive_starlink_pmu/read_request/ \
>         -- openssl speed rsa2048
> Doing 2048 bits private rsa's for 10s: 5 2048 bits private RSA's in
> 2.84s
> Doing 2048 bits public rsa's for 10s: 169 2048 bits public RSA's in
> 2.42s
> version: 3.0.11
> built on: Tue Sep 19 13:02:31 2023 UTC
> options: bn(64,64)
> CPUINFO: N/A
>                   sign    verify    sign/s verify/s
> rsa 2048 bits 0.568000s 0.014320s      1.8     69.8
> /////////
>  Performance counter stats for 'system wide':
> 
>          649991998      starfive_starlink_pmu/cycles/
>            1009690      starfive_starlink_pmu/read_miss/
>            1079750      starfive_starlink_pmu/read_hit/
>            2089405      starfive_starlink_pmu/release_request/
>                129      starfive_starlink_pmu/write_hit/
>                 70      starfive_starlink_pmu/write_miss/
>                194      starfive_starlink_pmu/write_request/
>             150080      starfive_starlink_pmu/writeback/
>            2089423      starfive_starlink_pmu/read_request/
> 
>       27.062755678 seconds time elapsed
> 
> Ji Sheng Teoh (4):
>   perf: starfive: Add StarLink PMU support
>   dt-bindings: perf: starfive: Add JH8100 StarLink PMU
>   docs: perf: Add description for StarFive's StarLink PMU
>   MAINTAINERS: Add entry for StarFive StarLink PMU
> 
>  Documentation/admin-guide/perf/index.rst      |   1 +
>  .../perf/starfive_starlink_pmu.rst            |  46 ++
>  .../perf/starfive,jh8100-starlink-pmu.yaml    |  46 ++
>  MAINTAINERS                                   |   7 +
>  drivers/perf/Kconfig                          |   9 +
>  drivers/perf/Makefile                         |   1 +
>  drivers/perf/starfive_starlink_pmu.c          | 643 ++++++++++++++++++
>  7 files changed, 753 insertions(+)
>  create mode 100644 Documentation/admin-guide/perf/starfive_starlink_pmu.rst
>  create mode 100644 Documentation/devicetree/bindings/perf/starfive,jh8100-starlink-pmu.yaml
>  create mode 100644 drivers/perf/starfive_starlink_pmu.c

Palmer, are you ok with me taking this via the perf tree? I usually
leave the Risc-V stuff for you, but this one doesn't touch the arch code
at all.

Cheers,

Will


From ville.syrjala at linux.intel.com  Thu Feb 22 04:58:45 2024
From: ville.syrjala at linux.intel.com (Ville =?iso-8859-1?Q?Syrj=E4l=E4?=)
Date: Thu, 22 Feb 2024 14:58:45 +0200
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB property
In-Reply-To: <euaujtp4jyyoud3ccg5qhyvixyq2p6vir4ojlzoky6kep754rj@wruidyfxssry>
References: <Zb0aYAapkxQ2kopt@intel.com>
 <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
 <20240212170618.GA1372043@toolbox>
 <2mih3humepuedtli7ge52ncom4uffkqravdpalncgfyucmwdzc@bp5o7i3ky77a>
 <20240219140144.GB1956149@toolbox>
 <euaujtp4jyyoud3ccg5qhyvixyq2p6vir4ojlzoky6kep754rj@wruidyfxssry>
Message-ID: <ZddFBe4A-galsO91@intel.com>

On Thu, Feb 22, 2024 at 11:54:04AM +0100, Maxime Ripard wrote:
> On Mon, Feb 19, 2024 at 03:01:44PM +0100, Sebastian Wick wrote:
> > On Thu, Feb 15, 2024 at 12:00:01PM +0100, Maxime Ripard wrote:
> > > On Mon, Feb 12, 2024 at 06:06:18PM +0100, Sebastian Wick wrote:
> > > > On Mon, Feb 12, 2024 at 05:53:48PM +0100, Maxime Ripard wrote:
> > > > > On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> > > > > > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > > > > > > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > > > > > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > > > > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > > > > > > Hi,
> > > > > > > > > > > > > 
> > > > > > > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > > > > > > >  /**
> > > > > > > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > > > > > > >   *
> > > > > > > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > + *      Full:
> > > > > > > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > > > > > > different things being affected:
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > > > > > > signalling, what happens?
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > > > > > > YCbCr?
> > > > > > > > > > > > > 
> > > > > > > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > > > > > > vc4 will follow the value of the property.
> > > > > > > > > > > > 
> > > > > > > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > > > > > > That should explain why it's only affecting RGB.
> > > > > > > > > > > 
> > > > > > > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > > > > > > itself.
> > > > > > > > > > > 
> > > > > > > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > > > > > > to enable it.
> > > > > > > > > > > 
> > > > > > > > > > > vc4 supports it.
> > > > > > > > > > 
> > > > > > > > > > Someone implemented it incorrectly then.
> > > > > > > > > 
> > > > > > > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > > > > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > > > > > > document any of it, and when people try to clean things up they get told
> > > > > > > > > that we got it all wrong.
> > > > > > > > 
> > > > > > > > FWIW, this was an i915 property and if another driver uses the same
> > > > > > > > property name it must have the same behavior. Yes, it isn't standardized
> > > > > > > > and yes, it's not documented (hence this effort here) but it's still on
> > > > > > > > vc4 to make the property compatible.
> > > > > > > 
> > > > > > > How is it not compatible? It's a superset of what i915 provides, but
> > > > > > > it's strictly compatible with it.
> > > > > > 
> > > > > > No it is not.
> > > > > 
> > > > > The property is compatible with i915 interpretation of it, whether you
> > > > > like it or not. And that's what Sebastian was referring to.
> > > > > 
> > > > > > Eg. what happens if you set the thing to full range for RGB (which you
> > > > > > must on many broken monitors), and then the kernel automagically
> > > > > > switches to YCbCr (for whatever reason) but the monitor doesn't
> > > > > > support full range YCbCr? Answer: you get crap output.
> > > > > 
> > > > > And that part is just moving goalposts.
> > > > 
> > > > But it's really not.
> > > 
> > > It really is. This whole discussion started by "well it would be nice if
> > > we made that property handled by the core", and we're now at the "we
> > > need to deal with broken YCbCr displays and i915 opinion about them"
> > > stage. After creating documentation, unit tests, etc. It's the textbook
> > > definition of moving goalposts. And while i915 won't be affected by all
> > > that work.
> > 
> > Sorry, but what you're saying is just not true.
> > 
> > The Broadcast RGB property is an Intel specific property.
> 
> No, it's not. vc4 has been using it for a year now.
> 
> > It lacked documentation but the user space contract exists and it
> > based on how i915 implemented it. By changing the semantics you're
> > breaking user space. The documentation has to document the current
> > contract between i915 and user space, not whatever you want the
> > property to be like.
> > 
> > I get that you're frustrated that you have to do work while i915 doesn't
> > but none of that is relevant for what the property is and how user space
> > expects it to work.
> 
> That's not it, really. I don't mind doing the work. I do mind losing
> functionalities on something that was working fine. And getting the
> blame for something that is, at best, just as much of an documentation
> issue on i915 devs.

We've had a couple of these cases recently where people have taken
some old property implemented by i915 and implemented it differently
in some other driver. Dunno if the reason was that people didn't try
to understand what i915 is doing and why, or they misundestood it,
or they understood it but decided to ignore it anyway.

Unfortunately having undocumented corners in the uapi is simply
a fact of life when dealing with a >15 year old legacy codebase.
Also there were basically no rules regarding properties in the
past, so everyone just added random properties whenever they 
felt like it.

I think going forward we should probably lay down some extra
ground rules; if an old undocumented uapi is being extended
to cover more than one driver we must first figure out what
the de facto semantics are, and document things properly
before anything else gets done.

-- 
Ville Syrj?l?
Intel


From aishwarya.tcv at arm.com  Thu Feb 22 05:01:32 2024
From: aishwarya.tcv at arm.com (Aishwarya TCV)
Date: Thu, 22 Feb 2024 13:01:32 +0000
Subject: [PATCH v12 02/25] genirq/irqdomain: Remove the param count
 restriction from select()
In-Reply-To: <20240127161753.114685-3-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-3-apatel@ventanamicro.com>
Message-ID: <e42b76a9-fc5f-4ab7-96a2-629261a9c983@arm.com>



On 27/01/2024 16:17, Anup Patel wrote:
> From: Thomas Gleixner <tglx at linutronix.de>
> 
> Now that the GIC-v3 callback can handle invocation with a fwspec parameter
> count of 0 lift the restriction in the core code and invoke select()
> unconditionally when the domain provides it.
> 
> Preparatory change for per device MSI domains.
> 
> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> ---

Hi Thomas/Anup

Currently when booting the kernel against next-master(next-20240222)
with Arm64 on Qualcomm boards RB5/DB845C, the kernel is resulting in
boot failures for our CI. I can send the full logs if required. Most
other boards seem to be fine.

A bisect (full log below) identified this patch as introducing the
failure. Bisected it on the tag "next-20240220" at repo
"https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git".

This works fine on Linux v6.8-rc5


Sample log from failure against run on RB5:
------
07:03:06.985934  <6>[    1.727034] Trying to probe devices needed for
running init ...
07:03:16.905972  <6>[   11.624040] platform 998000.serial: deferred
probe pending: platform: wait for supplier
/soc at 0/pinctrl at f100000/qup-uart6-default-state
07:03:16.906250  <6>[   11.636743] platform 1c08000.pcie: deferred probe
pending: platform: wait for supplier
/soc at 0/pinctrl at f100000/pcie1-default-state
07:03:16.906400  <6>[   11.648976] platform a90000.serial: deferred
probe pending: (reason unknown)
07:03:16.945462  <6>[   11.656490] platform 1c10000.pcie: deferred probe
pending: platform: wait for supplier
/soc at 0/pinctrl at f100000/pcie2-default-state
07:03:16.950476  <6>[   11.668723] platform c440000.spmi: deferred probe
pending: platform: supplier b220000.interrupt-controller not ready
07:03:16.950635  <6>[   11.679800] platform a6f8800.usb: deferred probe
pending: platform: supplier b220000.interrupt-controller not ready
07:03:16.950781  <6>[   11.690778] platform a8f8800.usb: deferred probe
pending: platform: supplier b220000.interrupt-controller not ready
07:03:16.950923  <6>[   11.701761] platform leds: deferred probe
pending: leds-gpio: Failed to get GPIO '/leds/led-user4'
07:03:16.989720  <6>[   11.711226] platform f100000.pinctrl: deferred
probe pending: platform: supplier b220000.interrupt-controller not ready
07:03:16.994769  <6>[   11.722567] platform 18591000.cpufreq: deferred
probe pending: qcom-cpufreq-hw: Failed to find icc paths
07:03:16.994929  <6>[   11.732573] platform
b220000.interrupt-controller: deferred probe pending: (reason unknown)
07:03:16.995076  <4>[   11.741438] qnoc-sm8250 1500000.interconnect:
sync_state() pending due to 1d84000.ufshc
07:03:17.034092  <4>[   11.749935] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to 1d84000.ufshc
07:03:17.034331  <4>[   11.758430] qnoc-sm8250 16e0000.interconnect:
sync_state() pending due to 1d84000.ufshc
07:03:17.039326  <4>[   11.766916] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to 1dfa000.crypto
07:03:17.039482  <4>[   11.775495] qnoc-sm8250 1700000.interconnect:
sync_state() pending due to 1dfa000.crypto
07:03:17.039623  <4>[   11.784081] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to 9091000.pmu
07:03:17.039759  <4>[   11.792389] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to 90b6400.pmu
07:03:17.078467  <4>[   11.800705] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to 1d84000.ufshc
07:03:17.083560  <4>[   11.809198] qnoc-sm8250 1500000.interconnect:
sync_state() pending due to a6f8800.usb
07:03:17.083720  <4>[   11.817508] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to a6f8800.usb
07:03:17.083866  <4>[   11.825825] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to a6f8800.usb
07:03:17.084006  <4>[   11.834140] qnoc-sm8250 16e0000.interconnect:
sync_state() pending due to a6f8800.usb
07:03:17.122721  <4>[   11.842456] qnoc-sm8250 1500000.interconnect:
sync_state() pending due to a8f8800.usb
07:03:17.127829  <4>[   11.850766] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to a8f8800.usb
07:03:17.127989  <4>[   11.859076] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to a8f8800.usb
07:03:17.128144  <4>[   11.867388] qnoc-sm8250 16e0000.interconnect:
sync_state() pending due to a8f8800.usb
07:03:17.128286  <4>[   11.875706] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to aa00000.video-codec
07:03:17.167089  <4>[   11.884733] qnoc-sm8250 1740000.interconnect:
sync_state() pending due to aa00000.video-codec
07:03:17.172232  <4>[   11.893760] qnoc-sm8250 1500000.interconnect:
sync_state() pending due to aa00000.video-codec
07:03:17.172404  <4>[   11.902780] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to aa00000.video-codec
07:03:17.172564  <4>[   11.911805] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to ae00000.display-subsystem
07:03:17.172705  <4>[   11.921359] qnoc-sm8250 1740000.interconnect:
sync_state() pending due to ae00000.display-subsystem
07:03:17.211346  <4>[   11.930932] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to
17300000.remoteproc
07:03:17.216527  <4>[   11.940758] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to
ae00000.display-subsystem
07:03:17.216694  <4>[   11.951113] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to
aa00000.video-codec
07:03:17.216840  <4>[   11.960935] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to 8804000.mmc
07:03:17.255721  <4>[   11.970059] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to
8300000.remoteproc
07:03:17.255962  <4>[   11.979795] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to 884000.i2c
07:03:17.261054  <4>[   11.988021] qnoc-sm8250 16e0000.interconnect:
sync_state() pending due to 884000.i2c
07:03:17.261220  <4>[   11.996242] qnoc-sm8250 1500000.interconnect:
sync_state() pending due to 884000.i2c
07:03:17.261366  <4>[   12.004465] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to 884000.i2c
07:03:17.261506  <4>[   12.012691] qnoc-sm8250 interconnect-qup-virt:
sync_state() pending due to 884000.i2c
07:03:17.300099  <4>[   12.021008] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to 884000.i2c
07:03:17.305306  <4>[   12.030029] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to 980000.spi
07:03:17.305467  <4>[   12.038254] qnoc-sm8250 1700000.interconnect:
sync_state() pending due to 980000.spi
07:03:17.305613  <4>[   12.046479] qnoc-sm8250 1500000.interconnect:
sync_state() pending due to 980000.spi
07:03:17.305754  <4>[   12.054705] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to 980000.spi
07:03:17.344314  <4>[   12.062927] qnoc-sm8250 interconnect-qup-virt:
sync_state() pending due to 980000.spi
07:03:17.349541  <4>[   12.071244] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to 980000.spi
07:03:17.349701  <4>[   12.080272] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to 990000.i2c
07:03:17.349846  <4>[   12.088494] qnoc-sm8250 1700000.interconnect:
sync_state() pending due to 990000.i2c
07:03:17.349986  <4>[   12.096713] qnoc-sm8250 1500000.interconnect:
sync_state() pending due to 990000.i2c
07:03:17.388758  <4>[   12.104937] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to 990000.i2c
07:03:17.388993  <4>[   12.113158] qnoc-sm8250 interconnect-qup-virt:
sync_state() pending due to 990000.i2c
07:03:17.394156  <4>[   12.121473] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to 990000.i2c
07:03:17.394314  <4>[   12.130504] qnoc-sm8250 163d000.interconnect:
sync_state() pending due to 994000.i2c
07:03:17.394458  <4>[   12.138733] qnoc-sm8250 1700000.interconnect:
sync_state() pending due to 994000.i2c
07:03:17.394598  <4>[   12.146958] qnoc-sm8250 1500000.interconnect:
sync_state() pending due to 994000.i2c
07:03:17.433035  <4>[   12.155179] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to 994000.i2c
07:03:17.438301  <4>[   12.163405] qnoc-sm8250 interconnect-qup-virt:
sync_state() pending due to 994000.i2c
07:03:17.438461  <4>[   12.171722] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to 994000.i2c
07:03:17.438607  <4>[   12.180742] qnoc-sm8250 1500000.interconnect:
sync_state() pending due to 998000.serial
07:03:17.438748  <4>[   12.189235] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to 998000.serial
07:03:17.477464  <4>[   12.197719] qnoc-sm8250 interconnect-qup-virt:
sync_state() pending due to 998000.serial
07:03:17.482759  <4>[   12.206299] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to 998000.serial
07:03:17.482918  <4>[   12.215592] qnoc-sm8250 1500000.interconnect:
sync_state() pending due to a90000.serial
07:03:17.483065  <4>[   12.224084] qnoc-sm8250 9100000.interconnect:
sync_state() pending due to a90000.serial
07:03:17.483207  <4>[   12.232576] qnoc-sm8250 interconnect-qup-virt:
sync_state() pending due to a90000.serial
07:03:17.503624  <4>[   12.241158] qcom-rpmhpd
18200000.rsc:power-controller: sync_state() pending due to a90000.serial
------


Bisect log:
------
git bisect start
# good: [b401b621758e46812da61fa58a67c3fd8d91de0d] Linux 6.8-rc5
git bisect good b401b621758e46812da61fa58a67c3fd8d91de0d
# bad: [2d5c7b7eb345249cb34d42cbc2b97b4c57ea944e] Add linux-next
specific files for 20240220
git bisect bad 2d5c7b7eb345249cb34d42cbc2b97b4c57ea944e
# good: [d0427d6bc95f2dae2595859f39c2de343479c909] Merge branch
'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
git bisect good d0427d6bc95f2dae2595859f39c2de343479c909
# good: [4c165a847139a6564d28e0f4d8e9fc9c67f22359] Merge branch
'for-next' of
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
git bisect good 4c165a847139a6564d28e0f4d8e9fc9c67f22359
# bad: [4dfc8ee8540b799d604551c41c82a9e07089e20e] Merge branch
'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
git bisect bad 4dfc8ee8540b799d604551c41c82a9e07089e20e
# bad: [1fad63263f1650f15d5bd174391a53d3e600c327] Merge branch
'rcu/next' of
git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
git bisect bad 1fad63263f1650f15d5bd174391a53d3e600c327
# bad: [0ced0254dca0bc06b09cfe31d6af411856379ea0] Merge branch into
tip/master: 'x86/vdso'
git bisect bad 0ced0254dca0bc06b09cfe31d6af411856379ea0
# good: [218b13db258c091e646857fc962ef45fe2163054] Merge branch
'x86/core' into x86/merge, to ease integration testing
git bisect good 218b13db258c091e646857fc962ef45fe2163054
# bad: [0b1902960678524b91f9ee3c94fc6561cfa1ead9] Merge branch into
tip/master: 'timers/ptp'
git bisect bad 0b1902960678524b91f9ee3c94fc6561cfa1ead9
# bad: [fa4d750326d50e3cc7801ada3d641daf14a4cb9d] Merge branch into
tip/master: 'irq/msi'
git bisect bad fa4d750326d50e3cc7801ada3d641daf14a4cb9d
# good: [9e04f6432c7ebaf33d5ce9a6e15bc544da316e54] Merge branch into
tip/master: 'irq/core'
git bisect good 9e04f6432c7ebaf33d5ce9a6e15bc544da316e54
# bad: [1a4671ff7a903e87e4e76213e200bb8bcfa942e4] platform-msi: Remove
unused interfaces
git bisect bad 1a4671ff7a903e87e4e76213e200bb8bcfa942e4
# bad: [ac81e94ab001c2882e89c9b61417caea64b800df] genirq/msi: Extend
msi_parent_ops
git bisect bad ac81e94ab001c2882e89c9b61417caea64b800df
# bad: [de1ff306dcf4546d6a8863b1f956335e0d3fbb9b] genirq/irqdomain:
Remove the param count restriction from select()
git bisect bad de1ff306dcf4546d6a8863b1f956335e0d3fbb9b
# good: [15137825100422c4c393c87af5aa5a8fa297b1f3] irqchip/gic-v3: Make
gic_irq_domain_select() robust for zero parameter count
git bisect good 15137825100422c4c393c87af5aa5a8fa297b1f3
# first bad commit: [de1ff306dcf4546d6a8863b1f956335e0d3fbb9b]
genirq/irqdomain: Remove the param count restriction from select()
------

Thanks,
Aishwarya


From jgg at nvidia.com  Thu Feb 22 05:11:01 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 22 Feb 2024 09:11:01 -0400
Subject: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty tracking
 in domain alloc
In-Reply-To: <d6442be07c9d4f999286e073ed221984@huawei.com>
References: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
 <20240222094923.33104-4-shameerali.kolothum.thodi@huawei.com>
 <a47699c9-4f3d-4cd0-94f4-f19e117ea6a3@oracle.com>
 <dfdc7daf8bd14b04b9bd29faaa1e6a96@huawei.com>
 <5607ece8-ce00-4834-9ae9-f4aa16fc4886@oracle.com>
 <d6442be07c9d4f999286e073ed221984@huawei.com>
Message-ID: <20240222131101.GZ13330@nvidia.com>

On Thu, Feb 22, 2024 at 12:24:06PM +0000, Shameerali Kolothum Thodi wrote:

> > > Ok. But do we really need to check this in attach()? As dirty_ops are added only
> > > if it is requested in alloc_user() and there we return err when hardware doesn't
> > > have the capability.  So not sure how this matters in attach() path. May be I am
> > > missing something.
> > 
> > That's when you create the domain with dev A. Afterwards that dev A is
> > attached,
> > but later on you can attach another device B to the domain. So this check is
> > there such that a domain with dirty tracking ops set will only have devices in
> > there that support dirty tracking.
> 
> But that only matters if dev B is on  different smmu without dbm capability, right?
> In that case we already fail the attach with,
> 
> >>>  	} else if (smmu_domain->smmu != smmu)
> > >>>  		ret = -EINVAL;
> > >>>
> 
> Is that right?

Right. Relaxing this is on my list :\

The other two drivers don't have this limitation so needed the check
that Joao described.

Jason


From bjorn at kernel.org  Thu Feb 22 05:13:33 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Thu, 22 Feb 2024 14:13:33 +0100
Subject: [PATCH v14 11/18] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <20240222094006.1030709-12-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
 <20240222094006.1030709-12-apatel@ventanamicro.com>
Message-ID: <87r0h4tzeq.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

> diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> new file mode 100644
> index 000000000000..0c19ffb9ca3e
> --- /dev/null
> +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> @@ -0,0 +1,870 @@

[...]

> +static void __imsic_local_sync(struct imsic_local_priv *lpriv)
> +{
> +	struct imsic_local_config *mlocal;
> +	struct imsic_vector *vec, *mvec;
> +	int i;
> +
> +	lockdep_assert_held(&lpriv->lock);
> +
> +	/* This pairs with the barrier in __imsic_remote_sync(). */
> +	smp_mb();

I'm trying to figure out why this barrier is needed? All the updates are
done behind the spinlocks. If there're some ordering constraints that
I'm missing, please document them.

> +
> +	for_each_set_bit(i, lpriv->dirty_bitmap, imsic->global.nr_ids + 1) {
> +		if (!i || i == IMSIC_IPI_ID)
> +			goto skip;
> +		vec = &lpriv->vectors[i];
> +
> +		if (READ_ONCE(vec->enable))
> +			__imsic_id_set_enable(i);
> +		else
> +			__imsic_id_clear_enable(i);
> +
> +		/*
> +		 * If the ID was being moved to a new ID on some other CPU
> +		 * then we can get a MSI during the movement so check the
> +		 * ID pending bit and re-trigger the new ID on other CPU
> +		 * using MMIO write.
> +		 */
> +		mvec = READ_ONCE(vec->move);
> +		WRITE_ONCE(vec->move, NULL);

mvec = xchg(&vec->move, NULL) ?

> +		if (mvec && mvec != vec) {
> +			if (__imsic_id_read_clear_pending(i)) {
> +				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
> +				writel_relaxed(mvec->local_id, mlocal->msi_va);
> +			}
> +
> +			imsic_vector_free(&lpriv->vectors[i]);
> +		}
> +
> +skip:
> +		bitmap_clear(lpriv->dirty_bitmap, i, 1);
> +	}
> +}
> +
> +void imsic_local_sync_all(void)
> +{
> +	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +	bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
> +	__imsic_local_sync(lpriv);
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> +}
> +
> +void imsic_local_delivery(bool enable)
> +{
> +	if (enable) {
> +		imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
> +		imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
> +		return;
> +	}
> +
> +	imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
> +	imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
> +}
> +
> +#ifdef CONFIG_SMP
> +static void imsic_local_timer_callback(struct timer_list *timer)
> +{
> +	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +	__imsic_local_sync(lpriv);
> +	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> +}
> +
> +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
> +{
> +	lockdep_assert_held(&lpriv->lock);
> +
> +	/*
> +	 * Ensure that changes to vector enable, vector move and
> +	 * dirty bitmap are visible to the target CPU.

...which case the spinlock(s) are enough, no?

> +	 *
> +	 * This pairs with the barrier in __imsic_local_sync().
> +	 */
> +	smp_mb();
> +
> +	/*
> +	 * We schedule a timer on the target CPU if the target CPU is not
> +	 * same as the current CPU. An offline CPU will unconditionally
> +	 * synchronize IDs through imsic_starting_cpu() when the
> +	 * CPU is brought up.
> +	 */
> +	if (cpu_online(cpu)) {
> +		if (cpu == smp_processor_id()) {
> +			__imsic_local_sync(lpriv);
> +			return;
> +		}

Maybe move this if-clause out from the cpu_online(), and only have
something like
  if (cpu_online(cpu) && !timer_pending(&lpriv->timer)) { ... }
inside the CONFIG_SMP guard...

> +
> +		if (!timer_pending(&lpriv->timer)) {
> +			lpriv->timer.expires = jiffies + 1;
> +			add_timer_on(&lpriv->timer, cpu);
> +		}
> +	}
> +}
> +#else
> +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
> +{
> +	lockdep_assert_held(&lpriv->lock);
> +	__imsic_local_sync(lpriv);
> +}
> +#endif

...where we can get rid of this special !SMP all together for this
function.

> +
> +void imsic_vector_mask(struct imsic_vector *vec)
> +{
> +	struct imsic_local_priv *lpriv;
> +
> +	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> +	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
> +		return;
> +
> +	/*
> +	 * This function is called through Linux irq subsystem with
> +	 * irqs disabled so no need to save/restore irq flags.
> +	 */
> +
> +	raw_spin_lock(&lpriv->lock);
> +
> +	vec->enable = false;

Should have WRITE_ONCE to make the checkers happy.

> +	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> +	__imsic_remote_sync(lpriv, vec->cpu);
> +
> +	raw_spin_unlock(&lpriv->lock);
> +}
> +
> +void imsic_vector_unmask(struct imsic_vector *vec)
> +{
> +	struct imsic_local_priv *lpriv;
> +
> +	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> +	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
> +		return;
> +
> +	/*
> +	 * This function is called through Linux irq subsystem with
> +	 * irqs disabled so no need to save/restore irq flags.
> +	 */
> +
> +	raw_spin_lock(&lpriv->lock);
> +
> +	vec->enable = true;

Dito.

> +	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> +	__imsic_remote_sync(lpriv, vec->cpu);
> +
> +	raw_spin_unlock(&lpriv->lock);
> +}
> +
> +static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, struct imsic_vector *vec,
> +				     bool new_enable, struct imsic_vector *new_move)
> +{
> +	unsigned long flags;
> +	bool enabled;
> +
> +	raw_spin_lock_irqsave(&lpriv->lock, flags);
> +
> +	/* Update enable and move details */
> +	enabled = READ_ONCE(vec->enable);
> +	WRITE_ONCE(vec->enable, new_enable);

Again, xchg() would be easier to read.


Bj?rn


From sebastian.wick at redhat.com  Thu Feb 22 05:12:10 2024
From: sebastian.wick at redhat.com (Sebastian Wick)
Date: Thu, 22 Feb 2024 14:12:10 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB property
In-Reply-To: <ZddFBe4A-galsO91@intel.com>
References: <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
 <20240212170618.GA1372043@toolbox>
 <2mih3humepuedtli7ge52ncom4uffkqravdpalncgfyucmwdzc@bp5o7i3ky77a>
 <20240219140144.GB1956149@toolbox>
 <euaujtp4jyyoud3ccg5qhyvixyq2p6vir4ojlzoky6kep754rj@wruidyfxssry>
 <ZddFBe4A-galsO91@intel.com>
Message-ID: <20240222131210.GA2405678@toolbox>

On Thu, Feb 22, 2024 at 02:58:45PM +0200, Ville Syrj?l? wrote:
> On Thu, Feb 22, 2024 at 11:54:04AM +0100, Maxime Ripard wrote:
> > On Mon, Feb 19, 2024 at 03:01:44PM +0100, Sebastian Wick wrote:
> > > On Thu, Feb 15, 2024 at 12:00:01PM +0100, Maxime Ripard wrote:
> > > > On Mon, Feb 12, 2024 at 06:06:18PM +0100, Sebastian Wick wrote:
> > > > > On Mon, Feb 12, 2024 at 05:53:48PM +0100, Maxime Ripard wrote:
> > > > > > On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> > > > > > > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > > > > > > > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > > > > > > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > > > > > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > > > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > > > > > > > Hi,
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > > > > > > > >  /**
> > > > > > > > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > > > > > > > >   *
> > > > > > > > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > > + *      Full:
> > > > > > > > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > > > > > > > different things being affected:
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > > > > > > > signalling, what happens?
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > > > > > > > YCbCr?
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > > > > > > > vc4 will follow the value of the property.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > > > > > > > That should explain why it's only affecting RGB.
> > > > > > > > > > > > 
> > > > > > > > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > > > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > > > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > > > > > > > itself.
> > > > > > > > > > > > 
> > > > > > > > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > > > > > > > to enable it.
> > > > > > > > > > > > 
> > > > > > > > > > > > vc4 supports it.
> > > > > > > > > > > 
> > > > > > > > > > > Someone implemented it incorrectly then.
> > > > > > > > > > 
> > > > > > > > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > > > > > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > > > > > > > document any of it, and when people try to clean things up they get told
> > > > > > > > > > that we got it all wrong.
> > > > > > > > > 
> > > > > > > > > FWIW, this was an i915 property and if another driver uses the same
> > > > > > > > > property name it must have the same behavior. Yes, it isn't standardized
> > > > > > > > > and yes, it's not documented (hence this effort here) but it's still on
> > > > > > > > > vc4 to make the property compatible.
> > > > > > > > 
> > > > > > > > How is it not compatible? It's a superset of what i915 provides, but
> > > > > > > > it's strictly compatible with it.
> > > > > > > 
> > > > > > > No it is not.
> > > > > > 
> > > > > > The property is compatible with i915 interpretation of it, whether you
> > > > > > like it or not. And that's what Sebastian was referring to.
> > > > > > 
> > > > > > > Eg. what happens if you set the thing to full range for RGB (which you
> > > > > > > must on many broken monitors), and then the kernel automagically
> > > > > > > switches to YCbCr (for whatever reason) but the monitor doesn't
> > > > > > > support full range YCbCr? Answer: you get crap output.
> > > > > > 
> > > > > > And that part is just moving goalposts.
> > > > > 
> > > > > But it's really not.
> > > > 
> > > > It really is. This whole discussion started by "well it would be nice if
> > > > we made that property handled by the core", and we're now at the "we
> > > > need to deal with broken YCbCr displays and i915 opinion about them"
> > > > stage. After creating documentation, unit tests, etc. It's the textbook
> > > > definition of moving goalposts. And while i915 won't be affected by all
> > > > that work.
> > > 
> > > Sorry, but what you're saying is just not true.
> > > 
> > > The Broadcast RGB property is an Intel specific property.
> > 
> > No, it's not. vc4 has been using it for a year now.
> > 
> > > It lacked documentation but the user space contract exists and it
> > > based on how i915 implemented it. By changing the semantics you're
> > > breaking user space. The documentation has to document the current
> > > contract between i915 and user space, not whatever you want the
> > > property to be like.
> > > 
> > > I get that you're frustrated that you have to do work while i915 doesn't
> > > but none of that is relevant for what the property is and how user space
> > > expects it to work.
> > 
> > That's not it, really. I don't mind doing the work. I do mind losing
> > functionalities on something that was working fine. And getting the
> > blame for something that is, at best, just as much of an documentation
> > issue on i915 devs.
> 
> We've had a couple of these cases recently where people have taken
> some old property implemented by i915 and implemented it differently
> in some other driver. Dunno if the reason was that people didn't try
> to understand what i915 is doing and why, or they misundestood it,
> or they understood it but decided to ignore it anyway.
> 
> Unfortunately having undocumented corners in the uapi is simply
> a fact of life when dealing with a >15 year old legacy codebase.
> Also there were basically no rules regarding properties in the
> past, so everyone just added random properties whenever they 
> felt like it.
> 
> I think going forward we should probably lay down some extra
> ground rules; if an old undocumented uapi is being extended
> to cover more than one driver we must first figure out what
> the de facto semantics are, and document things properly
> before anything else gets done.

That would be great. The documentation already has requirements for new
properties. Adding the requirement for extending driver-specific
properties to more drivers there would be great and make it "official".

> 
> -- 
> Ville Syrj?l?
> Intel
> 



From bjorn at kernel.org  Thu Feb 22 05:14:51 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Thu, 22 Feb 2024 14:14:51 +0100
Subject: [PATCH v14 13/18] irqchip/riscv-imsic: Add device MSI domain
 support for PCI devices
In-Reply-To: <20240222094006.1030709-14-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
 <20240222094006.1030709-14-apatel@ventanamicro.com>
Message-ID: <87msrstzck.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

> The Linux PCI framework supports per-device MSI domains for PCI devices
> so extend the IMSIC driver to allow PCI per-device MSI domains.
>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> ---
>  drivers/irqchip/Kconfig                    |  7 +++++
>  drivers/irqchip/irq-riscv-imsic-platform.c | 35 ++++++++++++++++++++--
>  2 files changed, 40 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 85f86e31c996..2fc0cb32341a 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -553,6 +553,13 @@ config RISCV_IMSIC
>  	select GENERIC_IRQ_MATRIX_ALLOCATOR
>  	select GENERIC_MSI_IRQ
>  
> +config RISCV_IMSIC_PCI
> +	bool
> +	depends on RISCV_IMSIC
> +	depends on PCI
> +	depends on PCI_MSI
> +	default RISCV_IMSIC
> +
>  config EXYNOS_IRQ_COMBINER
>  	bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
>  	depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
> diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
> index e2344fc08dca..90ddcdd0bba5 100644
> --- a/drivers/irqchip/irq-riscv-imsic-platform.c
> +++ b/drivers/irqchip/irq-riscv-imsic-platform.c
> @@ -14,6 +14,7 @@
>  #include <linux/irqdomain.h>
>  #include <linux/module.h>
>  #include <linux/msi.h>
> +#include <linux/pci.h>
>  #include <linux/platform_device.h>
>  #include <linux/spinlock.h>
>  #include <linux/smp.h>
> @@ -208,6 +209,28 @@ static const struct irq_domain_ops imsic_base_domain_ops = {
>  #endif
>  };
>  
> +#ifdef CONFIG_RISCV_IMSIC_PCI
> +
> +static void imsic_pci_mask_irq(struct irq_data *d)
> +{
> +	pci_msi_mask_irq(d);
> +	irq_chip_mask_parent(d);
> +}
> +
> +static void imsic_pci_unmask_irq(struct irq_data *d)
> +{
> +	irq_chip_unmask_parent(d);
> +	pci_msi_unmask_irq(d);
> +}
> +
> +#define MATCH_PCI_MSI		BIT(DOMAIN_BUS_PCI_MSI)
> +
> +#else
> +
> +#define MATCH_PCI_MSI		0
> +
> +#endif
> +
>  static bool imsic_init_dev_msi_info(struct device *dev,
>  				    struct irq_domain *domain,
>  				    struct irq_domain *real_parent,
> @@ -231,6 +254,13 @@ static bool imsic_init_dev_msi_info(struct device *dev,
>  
>  	/* Is the target supported? */
>  	switch (info->bus_token) {
> +#ifdef CONFIG_RISCV_IMSIC_PCI
> +	case DOMAIN_BUS_PCI_DEVICE_MSI:
> +	case DOMAIN_BUS_PCI_DEVICE_MSIX:
> +		info->chip->irq_mask = imsic_pci_mask_irq;
> +		info->chip->irq_unmask = imsic_pci_unmask_irq;

irq_set_affinity()?


Bj?rn


From bjorn at kernel.org  Thu Feb 22 05:15:19 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Thu, 22 Feb 2024 14:15:19 +0100
Subject: [PATCH v14 12/18] irqchip/riscv-imsic: Add device MSI domain
 support for platform devices
In-Reply-To: <20240222094006.1030709-13-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
 <20240222094006.1030709-13-apatel@ventanamicro.com>
Message-ID: <87jzmwtzbs.fsf@all.your.base.are.belong.to.us>

Anup Patel <apatel at ventanamicro.com> writes:

> The Linux platform MSI support allows per-device MSI domains so add
> a platform irqchip driver for RISC-V IMSIC which provides a base IRQ
> domain with MSI parent support for platform device domains.
>
> The IMSIC platform driver assumes that the IMSIC state is already
> initialized by the IMSIC early driver.
>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> ---
>  drivers/irqchip/Makefile                   |   2 +-
>  drivers/irqchip/irq-riscv-imsic-platform.c | 344 +++++++++++++++++++++
>  drivers/irqchip/irq-riscv-imsic-state.h    |   1 +
>  3 files changed, 346 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c
>
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index d714724387ce..abca445a3229 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -95,7 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
>  obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
>  obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
>  obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
> -obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o
> +obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
>  obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
>  obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
>  obj-$(CONFIG_IMX_INTMUX)		+= irq-imx-intmux.o
> diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
> new file mode 100644
> index 000000000000..e2344fc08dca
> --- /dev/null
> +++ b/drivers/irqchip/irq-riscv-imsic-platform.c
> @@ -0,0 +1,344 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> + * Copyright (C) 2022 Ventana Micro Systems Inc.
> + */
> +
> +#define pr_fmt(fmt) "riscv-imsic: " fmt
> +#include <linux/bitmap.h>
> +#include <linux/cpu.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip.h>
> +#include <linux/irqdomain.h>
> +#include <linux/module.h>
> +#include <linux/msi.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +#include <linux/smp.h>
> +
> +#include "irq-riscv-imsic-state.h"
> +
> +static bool imsic_cpu_page_phys(unsigned int cpu, unsigned int guest_index,
> +				phys_addr_t *out_msi_pa)
> +{
> +	struct imsic_global_config *global;
> +	struct imsic_local_config *local;
> +
> +	global = &imsic->global;
> +	local = per_cpu_ptr(global->local, cpu);
> +
> +	if (BIT(global->guest_index_bits) <= guest_index)
> +		return false;
> +
> +	if (out_msi_pa)
> +		*out_msi_pa = local->msi_pa +
> +			      (guest_index * IMSIC_MMIO_PAGE_SZ);

Nit: And one more redundant parenthesis and 100 char! ;-)


Bj?rn


From broonie at kernel.org  Thu Feb 22 05:15:13 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 22 Feb 2024 13:15:13 +0000
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for
 WCN7850
In-Reply-To: <CAMRc=MeF7xVjRKetg1A3MNO4yMasPA2GC7MLCBrOiwO5UBv6LA@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-15-brgl@bgdev.pl>
 <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk>
 <CAMRc=MeUjKPS3ANE6=7WZ3kbbGAdyE8HeXFN=75Jp-pVyBaWrQ@mail.gmail.com>
 <ea08a286-ff53-4d58-ae41-38cca151508c@sirena.org.uk>
 <17bbd9ae-0282-430e-947b-e6fb08c53af7@linaro.org>
 <53f0956f-ee64-4bd6-b44f-cbebafd42e46@sirena.org.uk>
 <CAMRc=MedCX_TGGawMhr39oXtJPF4pOQF=Jh2z4uXkOxwhfJWRw@mail.gmail.com>
 <52fba837-989b-4213-8af7-f02cd8cb48c8@sirena.org.uk>
 <CAMRc=MeF7xVjRKetg1A3MNO4yMasPA2GC7MLCBrOiwO5UBv6LA@mail.gmail.com>
Message-ID: <68e401c6-6e59-4c35-8f05-40f6c5eb6849@sirena.org.uk>

On Thu, Feb 22, 2024 at 01:26:59PM +0100, Bartosz Golaszewski wrote:
> On Thu, Feb 22, 2024 at 1:21?PM Mark Brown <broonie at kernel.org> wrote:
> > On Thu, Feb 22, 2024 at 10:22:50AM +0100, Bartosz Golaszewski wrote:

> > > Removing it would be out of scope for this series and I don't really
> > > want to introduce any undefined behavior when doing a big development
> > > like that. I'll think about it separately.

> > This is new code?

> It's a new driver but Qualcomm standard has been to provide the load
> values. If it's really unnecessary then maybe let's consider it
> separately and possibly rework globally?

That doesn't seem a great reason to add more instances of this - it's
more instances that need to be removed later, and somewhere else people
can cut'n'paste from to introduce new usage.
-------------- 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/20240222/12d3b101/attachment.sig>

From mripard at kernel.org  Thu Feb 22 05:20:49 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 14:20:49 +0100
Subject: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB property
In-Reply-To: <ZddFBe4A-galsO91@intel.com>
References: <zml6j27skvjmbrfyz7agy5waxajv4p4asbemeexelm3wuv4o7j@xkd2wvnxhbuc>
 <20240209203435.GB996172@toolbox>
 <ahfl6f72lpgpsbnrbgvbsh4db4npr2hh36kua2c6krh544hv5r@dndw4hz2mu2g>
 <Zco-DQaXqae7B1jt@intel.com>
 <yx2t7xltxxgsngdsxamsfq6y7dze3wzegxcqwmsb5yrxen73x6@u3vilqhpci4w>
 <20240212170618.GA1372043@toolbox>
 <2mih3humepuedtli7ge52ncom4uffkqravdpalncgfyucmwdzc@bp5o7i3ky77a>
 <20240219140144.GB1956149@toolbox>
 <euaujtp4jyyoud3ccg5qhyvixyq2p6vir4ojlzoky6kep754rj@wruidyfxssry>
 <ZddFBe4A-galsO91@intel.com>
Message-ID: <cf6mfm7naqdgnr3ab2tkix7b2s2frpsamlgylwiwcgbsy6ngd7@iq6ezpdnehbf>

On Thu, Feb 22, 2024 at 02:58:45PM +0200, Ville Syrj?l? wrote:
> On Thu, Feb 22, 2024 at 11:54:04AM +0100, Maxime Ripard wrote:
> > On Mon, Feb 19, 2024 at 03:01:44PM +0100, Sebastian Wick wrote:
> > > On Thu, Feb 15, 2024 at 12:00:01PM +0100, Maxime Ripard wrote:
> > > > On Mon, Feb 12, 2024 at 06:06:18PM +0100, Sebastian Wick wrote:
> > > > > On Mon, Feb 12, 2024 at 05:53:48PM +0100, Maxime Ripard wrote:
> > > > > > On Mon, Feb 12, 2024 at 05:49:33PM +0200, Ville Syrj?l? wrote:
> > > > > > > On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
> > > > > > > > On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
> > > > > > > > > On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
> > > > > > > > > > On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > > > On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
> > > > > > > > > > > > On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrj?l? wrote:
> > > > > > > > > > > > > On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
> > > > > > > > > > > > > > Hi,
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
> > > > > > > > > > > > > > > > >  /**
> > > > > > > > > > > > > > > > >   * DOC: HDMI connector properties
> > > > > > > > > > > > > > > > >   *
> > > > > > > > > > > > > > > > > + * Broadcast RGB
> > > > > > > > > > > > > > > > > + *      Indicates the RGB Quantization Range (Full vs Limited) used.
> > > > > > > > > > > > > > > > > + *      Infoframes will be generated according to that value.
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > > + *      The value of this property can be one of the following:
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > > + *      Automatic:
> > > > > > > > > > > > > > > > > + *              RGB Range is selected automatically based on the mode
> > > > > > > > > > > > > > > > > + *              according to the HDMI specifications.
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > > + *      Full:
> > > > > > > > > > > > > > > > > + *              Full RGB Range is forced.
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > > + *      Limited 16:235:
> > > > > > > > > > > > > > > > > + *              Limited RGB Range is forced. Unlike the name suggests,
> > > > > > > > > > > > > > > > > + *              this works for any number of bits-per-component.
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > > + *      Drivers can set up this property by calling
> > > > > > > > > > > > > > > > > + *      drm_connector_attach_broadcast_rgb_property().
> > > > > > > > > > > > > > > > > + *
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > This is a good time to document this in more detail. There might be two
> > > > > > > > > > > > > > > > different things being affected:
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > 1. The signalling (InfoFrame/SDP/...)
> > > > > > > > > > > > > > > > 2. The color pipeline processing
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > All values of Broadcast RGB always affect the color pipeline processing
> > > > > > > > > > > > > > > > such that a full-range input to the CRTC is converted to either full- or
> > > > > > > > > > > > > > > > limited-range, depending on what the monitor is supposed to accept.
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > When automatic is selected, does that mean that there is no signalling,
> > > > > > > > > > > > > > > > or that the signalling matches what the monitor is supposed to accept
> > > > > > > > > > > > > > > > according to the spec? Also, is this really HDMI specific?
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > When full or limited is selected and the monitor doesn't support the
> > > > > > > > > > > > > > > > signalling, what happens?
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > Forgot to mention: user-space still has no control over RGB vs YCbCr on
> > > > > > > > > > > > > > > the cable, so is this only affecting RGB? If not, how does it affect
> > > > > > > > > > > > > > > YCbCr?
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > So I dug a bit into both the i915 and vc4 drivers, and it looks like if
> > > > > > > > > > > > > > we're using a YCbCr format, i915 will always use a limited range while
> > > > > > > > > > > > > > vc4 will follow the value of the property.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > The property is literally called "Broadcast *RGB*".
> > > > > > > > > > > > > That should explain why it's only affecting RGB.
> > > > > > > > > > > > 
> > > > > > > > > > > > Right. And the limited range option is called "Limited 16:235" despite
> > > > > > > > > > > > being usable on bpc > 8 bits. Naming errors occurs, and history happens
> > > > > > > > > > > > to make names inconsistent too, that's fine and not an argument in
> > > > > > > > > > > > itself.
> > > > > > > > > > > > 
> > > > > > > > > > > > > Full range YCbCr is a much rarer beast so we've never bothered
> > > > > > > > > > > > > to enable it.
> > > > > > > > > > > > 
> > > > > > > > > > > > vc4 supports it.
> > > > > > > > > > > 
> > > > > > > > > > > Someone implemented it incorrectly then.
> > > > > > > > > > 
> > > > > > > > > > Incorrectly according to what documentation / specification? I'm sorry,
> > > > > > > > > > but I find it super ironic that i915 gets to do its own thing, not
> > > > > > > > > > document any of it, and when people try to clean things up they get told
> > > > > > > > > > that we got it all wrong.
> > > > > > > > > 
> > > > > > > > > FWIW, this was an i915 property and if another driver uses the same
> > > > > > > > > property name it must have the same behavior. Yes, it isn't standardized
> > > > > > > > > and yes, it's not documented (hence this effort here) but it's still on
> > > > > > > > > vc4 to make the property compatible.
> > > > > > > > 
> > > > > > > > How is it not compatible? It's a superset of what i915 provides, but
> > > > > > > > it's strictly compatible with it.
> > > > > > > 
> > > > > > > No it is not.
> > > > > > 
> > > > > > The property is compatible with i915 interpretation of it, whether you
> > > > > > like it or not. And that's what Sebastian was referring to.
> > > > > > 
> > > > > > > Eg. what happens if you set the thing to full range for RGB (which you
> > > > > > > must on many broken monitors), and then the kernel automagically
> > > > > > > switches to YCbCr (for whatever reason) but the monitor doesn't
> > > > > > > support full range YCbCr? Answer: you get crap output.
> > > > > > 
> > > > > > And that part is just moving goalposts.
> > > > > 
> > > > > But it's really not.
> > > > 
> > > > It really is. This whole discussion started by "well it would be nice if
> > > > we made that property handled by the core", and we're now at the "we
> > > > need to deal with broken YCbCr displays and i915 opinion about them"
> > > > stage. After creating documentation, unit tests, etc. It's the textbook
> > > > definition of moving goalposts. And while i915 won't be affected by all
> > > > that work.
> > > 
> > > Sorry, but what you're saying is just not true.
> > > 
> > > The Broadcast RGB property is an Intel specific property.
> > 
> > No, it's not. vc4 has been using it for a year now.
> > 
> > > It lacked documentation but the user space contract exists and it
> > > based on how i915 implemented it. By changing the semantics you're
> > > breaking user space. The documentation has to document the current
> > > contract between i915 and user space, not whatever you want the
> > > property to be like.
> > > 
> > > I get that you're frustrated that you have to do work while i915 doesn't
> > > but none of that is relevant for what the property is and how user space
> > > expects it to work.
> > 
> > That's not it, really. I don't mind doing the work. I do mind losing
> > functionalities on something that was working fine. And getting the
> > blame for something that is, at best, just as much of an documentation
> > issue on i915 devs.
> 
> We've had a couple of these cases recently where people have taken
> some old property implemented by i915 and implemented it differently
> in some other driver. Dunno if the reason was that people didn't try
> to understand what i915 is doing and why, or they misundestood it,
> or they understood it but decided to ignore it anyway.

I can't tell for the other cases, but in this particular case it's
definitely in the misunderstanding category. And implying that we didn't
even try to understand it, or that we didn't consult anyone when the
patches were posted on the ML for months doesn't seem fair either.

> Unfortunately having undocumented corners in the uapi is simply
> a fact of life when dealing with a >15 year old legacy codebase.
> Also there were basically no rules regarding properties in the
> past, so everyone just added random properties whenever they 
> felt like it.
> 
> I think going forward we should probably lay down some extra
> ground rules; if an old undocumented uapi is being extended
> to cover more than one driver we must first figure out what
> the de facto semantics are, and document things properly
> before anything else gets done.

That sounds reasonable, but you (not you personally, but the i915 team
in general) also have to engage, you can't just impose that on everyone
else, and then just hope they will figure it out perfectly without your
help.

I think that whole story is a testament to that.

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/20240222/9c7da4b5/attachment.sig>

From will at kernel.org  Thu Feb 22 05:21:09 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 13:21:09 +0000
Subject: [PATCH v3] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
In-Reply-To: <0-v3-11978fc67151+112-smmu_cd_atomic_jgg@nvidia.com>
References: <0-v3-11978fc67151+112-smmu_cd_atomic_jgg@nvidia.com>
Message-ID: <170860525230.21606.13716127943718563315.b4-ty@kernel.org>

On Wed, 21 Feb 2024 20:27:02 -0400, Jason Gunthorpe wrote:
> If the SMMU is configured to use a two level CD table then
> arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
> GFP_KERNEL. Due to recent changes this is being done under a spinlock to
> iterate over the device list - thus it will trigger a sleeping while
> atomic warning:
> 
>   arm_smmu_sva_set_dev_pasid()
>     mutex_lock(&sva_lock);
>     __arm_smmu_sva_bind()
>      arm_smmu_mmu_notifier_get()
>       spin_lock_irqsave()
>       arm_smmu_write_ctx_desc()
> 	arm_smmu_get_cd_ptr()
>          arm_smmu_alloc_cd_leaf_table()
> 	  dmam_alloc_coherent(GFP_KERNEL)
> 
> [...]

Thanks guys, this looks really good now.

Applied to will (for-joerg/arm-smmu/fixes), thanks!

[1/1] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
      https://git.kernel.org/will/c/b5bf7778b722

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From andriy.shevchenko at linux.intel.com  Thu Feb 22 05:21:45 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 22 Feb 2024 15:21:45 +0200
Subject: [PATCH v1 02/14] serial: core: Add UPIO_UNSET constant for unset
 port type
In-Reply-To: <5aeee02f-45a6-48e5-a6f4-e55b76d4b959@kernel.org>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-3-andriy.shevchenko@linux.intel.com>
 <5aeee02f-45a6-48e5-a6f4-e55b76d4b959@kernel.org>
Message-ID: <ZddKaaB7HO0CyldD@smile.fi.intel.com>

On Thu, Feb 22, 2024 at 07:58:32AM +0100, Jiri Slaby wrote:
> On 21. 02. 24, 19:31, Andy Shevchenko wrote:

...

> >   	unsigned char		iotype;			/* io access style */
> > +#define UPIO_UNSET		((unsigned char)~0U)	/* UCHAR_MAX */
> 
> Perhaps making the var u8 and this U8_MAX then? It would make more sense to
> me.

WFM, should it be a separate change? Btw, how can I justify it?

-- 
With Best Regards,
Andy Shevchenko




From vigneshr at ti.com  Thu Feb 22 05:22:28 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 22 Feb 2024 18:52:28 +0530
Subject: [PATCH v2 0/2] Add OSPI and Ethernet support on J722S EVM
In-Reply-To: <20240219090435.934383-1-vaishnav.a@ti.com>
References: <20240219090435.934383-1-vaishnav.a@ti.com>
Message-ID: <170860805562.1966114.3015232602049266823.b4-ty@ti.com>

Hi Vaishnav Achath,

On Mon, 19 Feb 2024 14:34:33 +0530, Vaishnav Achath wrote:
> This series adds support for Ethernet and OSPI NOR flash on J722S EVM.
> 
> V1: https://lore.kernel.org/all/20240216135533.904130-1-vaishnav.a at ti.com/
> 
> Changelog:
> V1->V2:
>   * Update comments indicating PAD numbers.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/2] arm64: dts: ti: k3-j722s-evm: Enable CPSW3G RGMII1
      commit: 9aa197b64df4c382763f032a31b35cad92cbce17
[2/2] arm64: dts: ti: k3-j722s-evm: Enable OSPI NOR support
      commit: 2e53b9c05a1589577565625fdb45cf918b54eb39

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Thu Feb 22 05:22:54 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 22 Feb 2024 18:52:54 +0530
Subject: [PATCH v2 0/4] arm64: dts: ti: Enable camera for SK-AM62P
In-Reply-To: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>
References: <20240220-am62p_csi-v2-0-3e71d9945571@ti.com>
Message-ID: <170860805564.1966114.7021966559574978180.b4-ty@ti.com>

Hi Jai Luthra,

On Tue, 20 Feb 2024 11:48:01 +0530, Jai Luthra wrote:
> This series enables support for camera sensors using CSI-RX ports on
> AM62P family of SoCs.
> 
> Particularly, it enables OV5640 and IMX219 sensors via the 22-pin FFC
> CSI-RX connector on SK-AM62P [1] using the existing common overlays for
> SK-AM62* family of boards.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/4] arm64: dts: ti: k3-am62p: Fix memory ranges for DMSS
      commit: 90a67583171f213711de662fab9f8d24a2d291a9
[2/4] arm64: dts: ti: k3-am62p: Add DMASS1 for CSI
      commit: 091e2e05228fa3fd424b1d775b04fb4734d5275b
[3/4] arm64: dts: ti: k3-am62p: Add nodes for CSI-RX
      commit: a8787f4fd29a43c5351daf3059a6156ff089a441
[4/4] arm64: dts: ti: Enable overlays for SK-AM62P
      commit: 598139b8c7c56cc6fb30ef8b4cf34b53a7fa5d0f

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From andriy.shevchenko at linux.intel.com  Thu Feb 22 05:23:24 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 22 Feb 2024 15:23:24 +0200
Subject: [PATCH v1 10/14] serial: 8250_of: Switch to use
 uart_read_port_properties()
In-Reply-To: <0a828f2c50de712940fb9a881702ac1678a35b7c.camel@codeconstruct.com.au>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-11-andriy.shevchenko@linux.intel.com>
 <0a828f2c50de712940fb9a881702ac1678a35b7c.camel@codeconstruct.com.au>
Message-ID: <ZddKzHplwOX7naLv@smile.fi.intel.com>

On Thu, Feb 22, 2024 at 11:07:05AM +1030, Andrew Jeffery wrote:
> On Wed, 2024-02-21 at 20:31 +0200, Andy Shevchenko wrote:
> > Since we have now a common helper to read port properties
> > use it instead of sparse home grown solution.
> 
> I did some brief testing of the series for the Aspeed machines under
> qemu, building them on top of v6.8-rc5:
> 
> export ARCH=arm
> export CROSS_COMPILE=arm-linux-gnueabihf-
> make aspeed_g5_defconfig
> make -j$(nproc)
> qemu-system-arm -M rainier-bmc -nographic -no-reboot -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dtb -initrd ...
> 
> I got an oops during boot, which bisected to this change:

Thank you for prompt testing! I will look at it.

-- 
With Best Regards,
Andy Shevchenko




From joao.m.martins at oracle.com  Thu Feb 22 05:23:26 2024
From: joao.m.martins at oracle.com (Joao Martins)
Date: Thu, 22 Feb 2024 13:23:26 +0000
Subject: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty tracking
 in domain alloc
In-Reply-To: <d6442be07c9d4f999286e073ed221984@huawei.com>
References: <20240222094923.33104-1-shameerali.kolothum.thodi@huawei.com>
 <20240222094923.33104-4-shameerali.kolothum.thodi@huawei.com>
 <a47699c9-4f3d-4cd0-94f4-f19e117ea6a3@oracle.com>
 <dfdc7daf8bd14b04b9bd29faaa1e6a96@huawei.com>
 <5607ece8-ce00-4834-9ae9-f4aa16fc4886@oracle.com>
 <d6442be07c9d4f999286e073ed221984@huawei.com>
Message-ID: <5beb0b15-04d2-4cc3-821f-c6ca445e5c0b@oracle.com>

On 22/02/2024 12:24, Shameerali Kolothum Thodi wrote:
> 
> 
>> -----Original Message-----
>> From: Joao Martins <joao.m.martins at oracle.com>
>> Sent: Thursday, February 22, 2024 11:38 AM
>> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
>> Cc: joro at 8bytes.org; jgg at nvidia.com; kevin.tian at intel.com;
>> nicolinc at nvidia.com; iommu at lists.linux.dev; mshavit at google.com;
>> robin.murphy at arm.com; will at kernel.org; jiangkunkun
>> <jiangkunkun at huawei.com>; zhukeqian <zhukeqian1 at huawei.com>; Linuxarm
>> <linuxarm at huawei.com>; linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty tracking
>> in domain alloc
>>
>> On 22/02/2024 11:31, Shameerali Kolothum Thodi wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Joao Martins <joao.m.martins at oracle.com>
>>>> Sent: Thursday, February 22, 2024 11:04 AM
>>>> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
>>>> Cc: joro at 8bytes.org; jgg at nvidia.com; kevin.tian at intel.com;
>>>> nicolinc at nvidia.com; iommu at lists.linux.dev; mshavit at google.com;
>>>> robin.murphy at arm.com; will at kernel.org; jiangkunkun
>>>> <jiangkunkun at huawei.com>; zhukeqian <zhukeqian1 at huawei.com>;
>>>> Linuxarm <linuxarm at huawei.com>; linux-arm-kernel at lists.infradead.org
>>>> Subject: Re: [PATCH v2 3/4] iommu/arm-smmu-v3: Add support for dirty
>>>> tracking in domain alloc
>>>>
>>>> On 22/02/2024 09:49, Shameer Kolothum wrote:
>>>>> From: Joao Martins <joao.m.martins at oracle.com>
>>>>>
>>>>> This provides all the infrastructure to enable dirty tracking if the
>>>>> hardware has the capability and domain alloc request for it.
>>>>>
>>>>> Please note, we still report no support for IOMMU_CAP_DIRTY_TRACKING
>>>>> as it will finally be enabled in a subsequent patch.
>>>>>
>>>>> Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
>>>>> Signed-off-by: Shameer Kolothum
>>>> <shameerali.kolothum.thodi at huawei.com>
>>>>> ---
>>>>>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 95
>>>> ++++++++++++++++-----
>>>>>  include/linux/io-pgtable.h                  |  4 +
>>>>>  2 files changed, 77 insertions(+), 22 deletions(-)
>>>>>
>>>>> 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 bd30739e3588..058bbb0dbe2e 100644
>>>>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>>> @@ -43,6 +43,7 @@ MODULE_PARM_DESC(disable_msipolling,
>>>>>  	"Disable MSI-based polling for CMD_SYNC completion.");
>>>>>
>>>>>  static struct iommu_ops arm_smmu_ops;
>>>>> +static struct iommu_dirty_ops arm_smmu_dirty_ops;
>>>>>
>>>>>  enum arm_smmu_msi_index {
>>>>>  	EVTQ_MSI_INDEX,
>>>>> @@ -86,7 +87,8 @@ static struct arm_smmu_option_prop
>>>>> arm_smmu_options[] = {
>>>>>
>>>>>  static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device
>>>>> *smmu);  static int arm_smmu_domain_finalise(struct arm_smmu_domain
>>>> *smmu_domain,
>>>>> -				    struct arm_smmu_device *smmu);
>>>>> +				    struct arm_smmu_device *smmu,
>>>>> +				    bool enable_dirty);
>>>>>  static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
>>>>> static void arm_smmu_tlb_inv_all_s2(struct arm_smmu_domain
>>>>> *smmu_domain);
>>>>>
>>>>> @@ -2378,7 +2380,7 @@ static struct iommu_domain
>>>> *arm_smmu_domain_alloc_paging(struct device *dev)
>>>>>  		struct arm_smmu_master *master =
>>>> dev_iommu_priv_get(dev);
>>>>>  		int ret;
>>>>>
>>>>> -		ret = arm_smmu_domain_finalise(smmu_domain, master-
>>>>> smmu);
>>>>> +		ret = arm_smmu_domain_finalise(smmu_domain, master-
>>>>> smmu, false);
>>>>>  		if (ret) {
>>>>>  			kfree(smmu_domain);
>>>>>  			return ERR_PTR(ret);
>>>>> @@ -2445,10 +2447,11 @@ static void arm_smmu_domain_free(struct
>>>>> iommu_domain *domain)  }
>>>>>
>>>>>  static int arm_smmu_domain_finalise(struct arm_smmu_domain
>>>> *smmu_domain,
>>>>> -				    struct arm_smmu_device *smmu)
>>>>> +				    struct arm_smmu_device *smmu,
>>>>> +				    bool enable_dirty)
>>>>>  {
>>>>>  	int ret;
>>>>> -	unsigned long ias, oas;
>>>>> +	unsigned long ias;
>>>>>  	enum io_pgtable_fmt fmt;
>>>>>  	struct io_pgtable_cfg pgtbl_cfg;
>>>>>  	struct io_pgtable_ops *pgtbl_ops;
>>>>> @@ -2459,31 +2462,31 @@ static int arm_smmu_domain_finalise(struct
>>>> arm_smmu_domain *smmu_domain,
>>>>>  	if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
>>>>>  		smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
>>>>>
>>>>> +	pgtbl_cfg = (struct io_pgtable_cfg) {
>>>>> +		.pgsize_bitmap	= smmu->pgsize_bitmap,
>>>>> +		.coherent_walk	= smmu->features &
>>>> ARM_SMMU_FEAT_COHERENCY,
>>>>> +		.tlb		= &arm_smmu_flush_ops,
>>>>> +		.iommu_dev	= smmu->dev,
>>>>> +	};
>>>>> +
>>>>>  	switch (smmu_domain->stage) {
>>>>>  	case ARM_SMMU_DOMAIN_S1:
>>>>>  		ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
>>>>> -		ias = min_t(unsigned long, ias, VA_BITS);
>>>>> -		oas = smmu->ias;
>>>>> +		pgtbl_cfg.ias = min_t(unsigned long, ias, VA_BITS);
>>>>> +		pgtbl_cfg.oas = smmu->ias;
>>>>> +		if (enable_dirty)
>>>>> +			pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_HD;
>>>>>  		fmt = ARM_64_LPAE_S1;
>>>>>  		break;
>>>>>  	case ARM_SMMU_DOMAIN_S2:
>>>>> -		ias = smmu->ias;
>>>>> -		oas = smmu->oas;
>>>>> +		pgtbl_cfg.ias = smmu->ias;
>>>>> +		pgtbl_cfg.oas = smmu->oas;
>>>>>  		fmt = ARM_64_LPAE_S2;
>>>>>  		break;
>>>>>  	default:
>>>>>  		return -EINVAL;
>>>>>  	}
>>>>>
>>>>> -	pgtbl_cfg = (struct io_pgtable_cfg) {
>>>>> -		.pgsize_bitmap	= smmu->pgsize_bitmap,
>>>>> -		.ias		= ias,
>>>>> -		.oas		= oas,
>>>>> -		.coherent_walk	= smmu->features &
>>>> ARM_SMMU_FEAT_COHERENCY,
>>>>> -		.tlb		= &arm_smmu_flush_ops,
>>>>> -		.iommu_dev	= smmu->dev,
>>>>> -	};
>>>>> -
>>>>>  	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
>>>>>  	if (!pgtbl_ops)
>>>>>  		return -ENOMEM;
>>>>> @@ -2491,7 +2494,8 @@ static int arm_smmu_domain_finalise(struct
>>>> arm_smmu_domain *smmu_domain,
>>>>>  	smmu_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
>>>>>  	smmu_domain->domain.geometry.aperture_end = (1UL <<
>>>> pgtbl_cfg.ias) - 1;
>>>>>  	smmu_domain->domain.geometry.force_aperture = true;
>>>>> -
>>>>> +	if (enable_dirty && smmu_domain->stage ==
>>>> ARM_SMMU_DOMAIN_S1)
>>>>> +		smmu_domain->domain.dirty_ops =
>>>> &arm_smmu_dirty_ops;
>>>>>  	ret = arm_smmu_domain_alloc_id(smmu, smmu_domain);
>>>>>  	if (ret < 0) {
>>>>>  		free_io_pgtable_ops(pgtbl_ops);
>>>>> @@ -2811,7 +2815,7 @@ static int arm_smmu_attach_dev(struct
>>>> iommu_domain *domain, struct device *dev)
>>>>>  	mutex_lock(&smmu_domain->init_mutex);
>>>>>
>>>>>  	if (!smmu_domain->smmu) {
>>>>> -		ret = arm_smmu_domain_finalise(smmu_domain, smmu);
>>>>> +		ret = arm_smmu_domain_finalise(smmu_domain, smmu,
>>>> false);
>>>>>  	} else if (smmu_domain->smmu != smmu)
>>>>>  		ret = -EINVAL;
>>>>>
>>>>
>>>>
>>>> I think we are missing the domain attach_dev check for dirty tracking.
>>>>
>>>> Something like:
>>>>
>>>> if (domain->dirty_ops && !arm_smmu_dbm_capable(smmu))
>>>> 	return -EINVAL;
>>>>
>>>> But that helper is only introduced in the last patch, so maybe:
>>>>
>>>> if (domain->dirty_ops &&
>>>>     !device_iommu_capable(dev, IOMMU_CAP_DIRTY_TRACKING))
>>>> 	return -EINVAL;
>>>
>>> Ok. But do we really need to check this in attach()? As dirty_ops are added only
>>> if it is requested in alloc_user() and there we return err when hardware doesn't
>>> have the capability.  So not sure how this matters in attach() path. May be I am
>>> missing something.
>>
>> That's when you create the domain with dev A. Afterwards that dev A is
>> attached,
>> but later on you can attach another device B to the domain. So this check is
>> there such that a domain with dirty tracking ops set will only have devices in
>> there that support dirty tracking.
> 
> But that only matters if dev B is on  different smmu without dbm capability, right?
> In that case we already fail the attach with,
> 
>>>>  	} else if (smmu_domain->smmu != smmu)
>>>>>  		ret = -EINVAL;
>>>>>
> 
> Is that right?
> 

Oh yes, I missed that. That looks indeed to do the equivalent.

Perhaps a comment there at least to remind to reader in the event that such
check being lifted.


From vigneshr at ti.com  Thu Feb 22 05:25:25 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 22 Feb 2024 18:55:25 +0530
Subject: [PATCH v5 0/4] Add Support for Wave5 on TI Devices
In-Reply-To: <20240220191413.3355007-1-b-brnich@ti.com>
References: <20240220191413.3355007-1-b-brnich@ti.com>
Message-ID: <170860824003.1969506.11520093746235278886.b4-ty@ti.com>

Hi Brandon Brnich,

On Tue, 20 Feb 2024 13:14:09 -0600, Brandon Brnich wrote:
> This series is responsible for adding support for Wave5 driver[0]
> across numerous TI K3 platforms.
> 
> [0]: https://lore.kernel.org/all/ae6d2ad3-0b2a-462a-a9eb-9ce01e7a7f5e at xs4all.nl/
> 
> Changes since v4:
> =================
> * Remove clock-names from device tree nodes per Vignesh's request
>   - "vcodec" clock-name is defined as macro in driver, but unused
>   - no purpose to have it in dt node
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/4] arm64: dts: ti: k3-j784s4: Add Wave5 Video Encoder/Decoder Node
      commit: 7805623df1ff50e69fa66e91f7305144e9ef5c31
[2/4] arm64: dts: ti: k3-j721s2-main: Add Wave5 Video Encoder/Decoder Node
      commit: 8caaf735b9114f77895608acde21a5163b1bf02e
[3/4] arm64: dts: ti: k3-am62p: Add Wave5 Video Encoder/Decoder Node
      commit: ab480b8036fde8c1ea628bb1027919bf399468e9

I have applied the following to branch ti-k3-config-next on [1].
Thank you!

[4/4] arm64: defconfig: Enable Wave5 Video Encoder/Decoder
      commit: 02b645583e26f38261711f2a8b36c5db06862527

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From brgl at bgdev.pl  Thu Feb 22 05:26:59 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 22 Feb 2024 14:26:59 +0100
Subject: [PATCH v5 14/18] PCI/pwrctl: add a power control driver for WCN7850
In-Reply-To: <68e401c6-6e59-4c35-8f05-40f6c5eb6849@sirena.org.uk>
References: <20240216203215.40870-1-brgl@bgdev.pl> <20240216203215.40870-15-brgl@bgdev.pl>
 <d5d603dc-ec66-4e21-aa41-3b25557f1fb7@sirena.org.uk> <CAMRc=MeUjKPS3ANE6=7WZ3kbbGAdyE8HeXFN=75Jp-pVyBaWrQ@mail.gmail.com>
 <ea08a286-ff53-4d58-ae41-38cca151508c@sirena.org.uk> <17bbd9ae-0282-430e-947b-e6fb08c53af7@linaro.org>
 <53f0956f-ee64-4bd6-b44f-cbebafd42e46@sirena.org.uk> <CAMRc=MedCX_TGGawMhr39oXtJPF4pOQF=Jh2z4uXkOxwhfJWRw@mail.gmail.com>
 <52fba837-989b-4213-8af7-f02cd8cb48c8@sirena.org.uk> <CAMRc=MeF7xVjRKetg1A3MNO4yMasPA2GC7MLCBrOiwO5UBv6LA@mail.gmail.com>
 <68e401c6-6e59-4c35-8f05-40f6c5eb6849@sirena.org.uk>
Message-ID: <CAMRc=Mfi6wgGSsH=pS68-GFWZwHB98YnH4+6LiBFprTEHntdcQ@mail.gmail.com>

On Thu, Feb 22, 2024 at 2:15?PM Mark Brown <broonie at kernel.org> wrote:
>
> On Thu, Feb 22, 2024 at 01:26:59PM +0100, Bartosz Golaszewski wrote:
> > On Thu, Feb 22, 2024 at 1:21?PM Mark Brown <broonie at kernel.org> wrote:
> > > On Thu, Feb 22, 2024 at 10:22:50AM +0100, Bartosz Golaszewski wrote:
>
> > > > Removing it would be out of scope for this series and I don't really
> > > > want to introduce any undefined behavior when doing a big development
> > > > like that. I'll think about it separately.
>
> > > This is new code?
>
> > It's a new driver but Qualcomm standard has been to provide the load
> > values. If it's really unnecessary then maybe let's consider it
> > separately and possibly rework globally?
>
> That doesn't seem a great reason to add more instances of this - it's
> more instances that need to be removed later, and somewhere else people
> can cut'n'paste from to introduce new usage.

Ok, whatever, I'll drop these until they're needed.

Bartosz


From vigneshr at ti.com  Thu Feb 22 05:28:07 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 22 Feb 2024 18:58:07 +0530
Subject: [PATCH V3 0/2] Add CAN and OSPI support for AM69-SK platform
In-Reply-To: <20240220162527.663394-1-sabiya.d@ti.com>
References: <20240220162527.663394-1-sabiya.d@ti.com>
Message-ID: <170860805565.1966114.18241653060912010768.b4-ty@ti.com>

Hi sabiya.d at mistralsolutions.com,

On Tue, 20 Feb 2024 21:55:25 +0530, sabiya.d at mistralsolutions.com wrote:
> This series adds support for the below interfaces on AM69-SK platform:
> -  CAN support on both MCU and MAIN domains
> -  OSPI NOR flash support
> 
> v3: Changelog:
> 1) Updated OSPI partition table to increase the tiboot3 partition to 1MB.
> 2) Rebase the sources to accommodate the latest merge.
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/2] arm64: dts: ti: k3-am69-sk: Enable CAN interfaces for AM69 SK board
      commit: daa2eb7f30eeb7127b6050e18f491326d278b836
[2/2] arm64: dts: ti: k3-am69-sk: Add support for OSPI flash
      commit: fabd934c6df2fb0c351144e424727fead261f333

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From vigneshr at ti.com  Thu Feb 22 05:29:17 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Thu, 22 Feb 2024 18:59:17 +0530
Subject: [PATCH] arm64: dts: ti: k3-j721e: Fix mux-reg-masks in hbmc_mux
In-Reply-To: <20240215141957.13775-1-afd@ti.com>
References: <20240215141957.13775-1-afd@ti.com>
Message-ID: <170860805561.1966114.12049702081667007759.b4-ty@ti.com>

Hi Andrew Davis,

On Thu, 15 Feb 2024 08:19:57 -0600, Andrew Davis wrote:
> Change offset in mux-reg-masks property for hbmc_mux node
> since reg-mux property is used in compatible.
> 
> While here, update the reg region to include 4 bytes as this
> is a 32bit register.
> 
> 
> [...]

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: k3-j721e: Fix mux-reg-masks in hbmc_mux
      commit: 3d585389d454e147187684e492a0eb8f56adf311

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From anup at brainfault.org  Thu Feb 22 05:30:25 2024
From: anup at brainfault.org (Anup Patel)
Date: Thu, 22 Feb 2024 19:00:25 +0530
Subject: [PATCH v14 13/18] irqchip/riscv-imsic: Add device MSI domain
 support for PCI devices
In-Reply-To: <87msrstzck.fsf@all.your.base.are.belong.to.us>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
 <20240222094006.1030709-14-apatel@ventanamicro.com> <87msrstzck.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAAhSdy3DtDFnZKQLXXJ2OPPSv5s8bbGvm8Mmqhg_F2rPneQ3sw@mail.gmail.com>

On Thu, Feb 22, 2024 at 6:44?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Anup Patel <apatel at ventanamicro.com> writes:
>
> > The Linux PCI framework supports per-device MSI domains for PCI devices
> > so extend the IMSIC driver to allow PCI per-device MSI domains.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  drivers/irqchip/Kconfig                    |  7 +++++
> >  drivers/irqchip/irq-riscv-imsic-platform.c | 35 ++++++++++++++++++++--
> >  2 files changed, 40 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> > index 85f86e31c996..2fc0cb32341a 100644
> > --- a/drivers/irqchip/Kconfig
> > +++ b/drivers/irqchip/Kconfig
> > @@ -553,6 +553,13 @@ config RISCV_IMSIC
> >       select GENERIC_IRQ_MATRIX_ALLOCATOR
> >       select GENERIC_MSI_IRQ
> >
> > +config RISCV_IMSIC_PCI
> > +     bool
> > +     depends on RISCV_IMSIC
> > +     depends on PCI
> > +     depends on PCI_MSI
> > +     default RISCV_IMSIC
> > +
> >  config EXYNOS_IRQ_COMBINER
> >       bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
> >       depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
> > diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
> > index e2344fc08dca..90ddcdd0bba5 100644
> > --- a/drivers/irqchip/irq-riscv-imsic-platform.c
> > +++ b/drivers/irqchip/irq-riscv-imsic-platform.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/irqdomain.h>
> >  #include <linux/module.h>
> >  #include <linux/msi.h>
> > +#include <linux/pci.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/spinlock.h>
> >  #include <linux/smp.h>
> > @@ -208,6 +209,28 @@ static const struct irq_domain_ops imsic_base_domain_ops = {
> >  #endif
> >  };
> >
> > +#ifdef CONFIG_RISCV_IMSIC_PCI
> > +
> > +static void imsic_pci_mask_irq(struct irq_data *d)
> > +{
> > +     pci_msi_mask_irq(d);
> > +     irq_chip_mask_parent(d);
> > +}
> > +
> > +static void imsic_pci_unmask_irq(struct irq_data *d)
> > +{
> > +     irq_chip_unmask_parent(d);
> > +     pci_msi_unmask_irq(d);
> > +}
> > +
> > +#define MATCH_PCI_MSI                BIT(DOMAIN_BUS_PCI_MSI)
> > +
> > +#else
> > +
> > +#define MATCH_PCI_MSI                0
> > +
> > +#endif
> > +
> >  static bool imsic_init_dev_msi_info(struct device *dev,
> >                                   struct irq_domain *domain,
> >                                   struct irq_domain *real_parent,
> > @@ -231,6 +254,13 @@ static bool imsic_init_dev_msi_info(struct device *dev,
> >
> >       /* Is the target supported? */
> >       switch (info->bus_token) {
> > +#ifdef CONFIG_RISCV_IMSIC_PCI
> > +     case DOMAIN_BUS_PCI_DEVICE_MSI:
> > +     case DOMAIN_BUS_PCI_DEVICE_MSIX:
> > +             info->chip->irq_mask = imsic_pci_mask_irq;
> > +             info->chip->irq_unmask = imsic_pci_unmask_irq;
>
> irq_set_affinity()?

It's already set by the switch-case above.

Regards,
Anup


From horms at kernel.org  Thu Feb 22 05:31:03 2024
From: horms at kernel.org (Simon Horman)
Date: Thu, 22 Feb 2024 13:31:03 +0000
Subject: [PATCH net-next v3 10/10] net: ti: icssg-prueth: Add ICSSG
 Ethernet driver for AM65x SR1.0 platforms
In-Reply-To: <20240221152421.112324-11-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
 <20240221152421.112324-11-diogo.ivo@siemens.com>
Message-ID: <20240222133103.GB960874@kernel.org>

On Wed, Feb 21, 2024 at 03:24:16PM +0000, Diogo Ivo wrote:
> Add the PRUeth driver for the ICSSG subsystem found in AM65x SR1.0 devices.
> The main differences that set SR1.0 and SR2.0 apart are the missing TXPRU
> core in SR1.0, two extra DMA channels for management purposes and different
> firmware that needs to be configured accordingly.
> 
> Based on the work of Roger Quadros, Vignesh Raghavendra and
> Grygorii Strashko in TI's 5.10 SDK [1].
> 
> [1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y
> 
> Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
> Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
> Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>

...

> diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c b/drivers/net/ethernet/ti/icssg/icssg_prueth_sr1.c

...

> +static void icssg_config_sr1(struct prueth *prueth, struct prueth_emac *emac,
> +			     int slice)
> +{
> +	struct icssg_sr1_config config;
> +	void __iomem *va;
> +	int i, index;
> +
> +	memset(&config, 0, sizeof(config));
> +	config.addr_lo = cpu_to_le32(lower_32_bits(prueth->msmcram.pa));
> +	config.addr_hi = cpu_to_le32(upper_32_bits(prueth->msmcram.pa));
> +	config.num_tx_threads = 0;
> +	config.rx_flow_id = emac->rx_flow_id_base; /* flow id for host port */
> +	config.rx_mgr_flow_id = emac->rx_mgm_flow_id_base; /* for mgm ch */
> +	config.rand_seed = get_random_u32();

Hi Diogo and Jan,

The fields of config above are all __le32.
However the last three lines above assign host byte-order values to these
fields. This does not seem correct.

This is flagged by Sparse along with some problems.
Please ensure that new Sparse warnings are not introduced.


> +
> +	for (i = PRUETH_EMAC_BUF_POOL_START_SR1; i < PRUETH_NUM_BUF_POOLS_SR1; i++) {
> +		index =  i - PRUETH_EMAC_BUF_POOL_START_SR1;
> +		config.tx_buf_sz[i] = cpu_to_le32(emac_egress_buf_pool_size[index]);
> +	}
> +
> +	va = prueth->shram.va + slice * ICSSG_CONFIG_OFFSET_SLICE1;
> +	memcpy_toio(va, &config, sizeof(config));
> +
> +	emac->speed = SPEED_1000;
> +	emac->duplex = DUPLEX_FULL;
> +}
> +
> +static int emac_send_command_sr1(struct prueth_emac *emac, u32 cmd)
> +{
> +	dma_addr_t desc_dma, buf_dma;
> +	struct prueth_tx_chn *tx_chn;
> +	struct cppi5_host_desc_t *first_desc;
> +	u32 *data = emac->cmd_data;
> +	u32 pkt_len = sizeof(emac->cmd_data);
> +	void **swdata;
> +	int ret = 0;
> +	u32 *epib;

In new Networking code please express local variables in reverse xmas tree
order - longest line to shortest.

Something like this (completely untested!):

	struct cppi5_host_desc_t *first_desc;
	u32 pkt_len = sizeof(emac->cmd_data);
	dma_addr_t desc_dma, buf_dma;
	struct prueth_tx_chn *tx_chn;
	u32 *data = emac->cmd_data;
	void **swdata;
	int ret = 0;
	u32 *epib;

There is also one such problem in Patch 06/10.
These problems can be detected using:

	https://github.com/ecree-solarflare/xmastree

...


From anup at brainfault.org  Thu Feb 22 05:42:34 2024
From: anup at brainfault.org (Anup Patel)
Date: Thu, 22 Feb 2024 19:12:34 +0530
Subject: [PATCH v14 11/18] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <87r0h4tzeq.fsf@all.your.base.are.belong.to.us>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
 <20240222094006.1030709-12-apatel@ventanamicro.com> <87r0h4tzeq.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAAhSdy3R9TCHG13vFk=sF0MvA60LtxOs9NbjSB7XBk+v1+XH4w@mail.gmail.com>

On Thu, Feb 22, 2024 at 6:43?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Anup Patel <apatel at ventanamicro.com> writes:
>
> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
> > new file mode 100644
> > index 000000000000..0c19ffb9ca3e
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
> > @@ -0,0 +1,870 @@
>
> [...]
>
> > +static void __imsic_local_sync(struct imsic_local_priv *lpriv)
> > +{
> > +     struct imsic_local_config *mlocal;
> > +     struct imsic_vector *vec, *mvec;
> > +     int i;
> > +
> > +     lockdep_assert_held(&lpriv->lock);
> > +
> > +     /* This pairs with the barrier in __imsic_remote_sync(). */
> > +     smp_mb();
>
> I'm trying to figure out why this barrier is needed? All the updates are
> done behind the spinlocks. If there're some ordering constraints that
> I'm missing, please document them.
>
> > +
> > +     for_each_set_bit(i, lpriv->dirty_bitmap, imsic->global.nr_ids + 1) {
> > +             if (!i || i == IMSIC_IPI_ID)
> > +                     goto skip;
> > +             vec = &lpriv->vectors[i];
> > +
> > +             if (READ_ONCE(vec->enable))
> > +                     __imsic_id_set_enable(i);
> > +             else
> > +                     __imsic_id_clear_enable(i);
> > +
> > +             /*
> > +              * If the ID was being moved to a new ID on some other CPU
> > +              * then we can get a MSI during the movement so check the
> > +              * ID pending bit and re-trigger the new ID on other CPU
> > +              * using MMIO write.
> > +              */
> > +             mvec = READ_ONCE(vec->move);
> > +             WRITE_ONCE(vec->move, NULL);
>
> mvec = xchg(&vec->move, NULL) ?

The __imsic_local_sync() is called with spinlock held.

>
> > +             if (mvec && mvec != vec) {
> > +                     if (__imsic_id_read_clear_pending(i)) {
> > +                             mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
> > +                             writel_relaxed(mvec->local_id, mlocal->msi_va);
> > +                     }
> > +
> > +                     imsic_vector_free(&lpriv->vectors[i]);
> > +             }
> > +
> > +skip:
> > +             bitmap_clear(lpriv->dirty_bitmap, i, 1);
> > +     }
> > +}
> > +
> > +void imsic_local_sync_all(void)
> > +{
> > +     struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +     bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
> > +     __imsic_local_sync(lpriv);
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> > +}
> > +
> > +void imsic_local_delivery(bool enable)
> > +{
> > +     if (enable) {
> > +             imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
> > +             imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
> > +             return;
> > +     }
> > +
> > +     imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
> > +     imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
> > +}
> > +
> > +#ifdef CONFIG_SMP
> > +static void imsic_local_timer_callback(struct timer_list *timer)
> > +{
> > +     struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
> > +     unsigned long flags;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +     __imsic_local_sync(lpriv);
> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
> > +}
> > +
> > +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
> > +{
> > +     lockdep_assert_held(&lpriv->lock);
> > +
> > +     /*
> > +      * Ensure that changes to vector enable, vector move and
> > +      * dirty bitmap are visible to the target CPU.
>
> ...which case the spinlock(s) are enough, no?

spinlocks are not fences.

If the timer wheel on the target cpu is already running and we don't
have a fence here then the target cpu might not see the changes
done by this cpu.

>
> > +      *
> > +      * This pairs with the barrier in __imsic_local_sync().
> > +      */
> > +     smp_mb();
> > +
> > +     /*
> > +      * We schedule a timer on the target CPU if the target CPU is not
> > +      * same as the current CPU. An offline CPU will unconditionally
> > +      * synchronize IDs through imsic_starting_cpu() when the
> > +      * CPU is brought up.
> > +      */
> > +     if (cpu_online(cpu)) {
> > +             if (cpu == smp_processor_id()) {
> > +                     __imsic_local_sync(lpriv);
> > +                     return;
> > +             }
>
> Maybe move this if-clause out from the cpu_online(), and only have
> something like
>   if (cpu_online(cpu) && !timer_pending(&lpriv->timer)) { ... }
> inside the CONFIG_SMP guard...
>
> > +
> > +             if (!timer_pending(&lpriv->timer)) {
> > +                     lpriv->timer.expires = jiffies + 1;
> > +                     add_timer_on(&lpriv->timer, cpu);
> > +             }
> > +     }
> > +}
> > +#else
> > +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
> > +{
> > +     lockdep_assert_held(&lpriv->lock);
> > +     __imsic_local_sync(lpriv);
> > +}
> > +#endif
>
> ...where we can get rid of this special !SMP all together for this
> function.

I failed to understand what is wrong the current code.

>
> > +
> > +void imsic_vector_mask(struct imsic_vector *vec)
> > +{
> > +     struct imsic_local_priv *lpriv;
> > +
> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> > +     if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
> > +             return;
> > +
> > +     /*
> > +      * This function is called through Linux irq subsystem with
> > +      * irqs disabled so no need to save/restore irq flags.
> > +      */
> > +
> > +     raw_spin_lock(&lpriv->lock);
> > +
> > +     vec->enable = false;
>
> Should have WRITE_ONCE to make the checkers happy.

Okay, I will update.

>
> > +     bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> > +     __imsic_remote_sync(lpriv, vec->cpu);
> > +
> > +     raw_spin_unlock(&lpriv->lock);
> > +}
> > +
> > +void imsic_vector_unmask(struct imsic_vector *vec)
> > +{
> > +     struct imsic_local_priv *lpriv;
> > +
> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
> > +     if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
> > +             return;
> > +
> > +     /*
> > +      * This function is called through Linux irq subsystem with
> > +      * irqs disabled so no need to save/restore irq flags.
> > +      */
> > +
> > +     raw_spin_lock(&lpriv->lock);
> > +
> > +     vec->enable = true;
>
> Dito.

Okay, I will update.

>
> > +     bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
> > +     __imsic_remote_sync(lpriv, vec->cpu);
> > +
> > +     raw_spin_unlock(&lpriv->lock);
> > +}
> > +
> > +static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, struct imsic_vector *vec,
> > +                                  bool new_enable, struct imsic_vector *new_move)
> > +{
> > +     unsigned long flags;
> > +     bool enabled;
> > +
> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
> > +
> > +     /* Update enable and move details */
> > +     enabled = READ_ONCE(vec->enable);
> > +     WRITE_ONCE(vec->enable, new_enable);
>
> Again, xchg() would be easier to read.

why ? spinlock is not enough?

Regards,
Anup


From anup at brainfault.org  Thu Feb 22 05:44:43 2024
From: anup at brainfault.org (Anup Patel)
Date: Thu, 22 Feb 2024 19:14:43 +0530
Subject: [PATCH v14 12/18] irqchip/riscv-imsic: Add device MSI domain
 support for platform devices
In-Reply-To: <87jzmwtzbs.fsf@all.your.base.are.belong.to.us>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
 <20240222094006.1030709-13-apatel@ventanamicro.com> <87jzmwtzbs.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAAhSdy1V5yqO3kqs7+wOb34oSDgdo=QRT-i2XG+okFtHTgyMrQ@mail.gmail.com>

On Thu, Feb 22, 2024 at 6:45?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> Anup Patel <apatel at ventanamicro.com> writes:
>
> > The Linux platform MSI support allows per-device MSI domains so add
> > a platform irqchip driver for RISC-V IMSIC which provides a base IRQ
> > domain with MSI parent support for platform device domains.
> >
> > The IMSIC platform driver assumes that the IMSIC state is already
> > initialized by the IMSIC early driver.
> >
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> >  drivers/irqchip/Makefile                   |   2 +-
> >  drivers/irqchip/irq-riscv-imsic-platform.c | 344 +++++++++++++++++++++
> >  drivers/irqchip/irq-riscv-imsic-state.h    |   1 +
> >  3 files changed, 346 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c
> >
> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> > index d714724387ce..abca445a3229 100644
> > --- a/drivers/irqchip/Makefile
> > +++ b/drivers/irqchip/Makefile
> > @@ -95,7 +95,7 @@ obj-$(CONFIG_QCOM_MPM)                      += irq-qcom-mpm.o
> >  obj-$(CONFIG_CSKY_MPINTC)            += irq-csky-mpintc.o
> >  obj-$(CONFIG_CSKY_APB_INTC)          += irq-csky-apb-intc.o
> >  obj-$(CONFIG_RISCV_INTC)             += irq-riscv-intc.o
> > -obj-$(CONFIG_RISCV_IMSIC)            += irq-riscv-imsic-state.o irq-riscv-imsic-early.o
> > +obj-$(CONFIG_RISCV_IMSIC)            += irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
> >  obj-$(CONFIG_SIFIVE_PLIC)            += irq-sifive-plic.o
> >  obj-$(CONFIG_IMX_IRQSTEER)           += irq-imx-irqsteer.o
> >  obj-$(CONFIG_IMX_INTMUX)             += irq-imx-intmux.o
> > diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
> > new file mode 100644
> > index 000000000000..e2344fc08dca
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-riscv-imsic-platform.c
> > @@ -0,0 +1,344 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2021 Western Digital Corporation or its affiliates.
> > + * Copyright (C) 2022 Ventana Micro Systems Inc.
> > + */
> > +
> > +#define pr_fmt(fmt) "riscv-imsic: " fmt
> > +#include <linux/bitmap.h>
> > +#include <linux/cpu.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/irq.h>
> > +#include <linux/irqchip.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/module.h>
> > +#include <linux/msi.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/smp.h>
> > +
> > +#include "irq-riscv-imsic-state.h"
> > +
> > +static bool imsic_cpu_page_phys(unsigned int cpu, unsigned int guest_index,
> > +                             phys_addr_t *out_msi_pa)
> > +{
> > +     struct imsic_global_config *global;
> > +     struct imsic_local_config *local;
> > +
> > +     global = &imsic->global;
> > +     local = per_cpu_ptr(global->local, cpu);
> > +
> > +     if (BIT(global->guest_index_bits) <= guest_index)
> > +             return false;
> > +
> > +     if (out_msi_pa)
> > +             *out_msi_pa = local->msi_pa +
> > +                           (guest_index * IMSIC_MMIO_PAGE_SZ);
>
> Nit: And one more redundant parenthesis and 100 char! ;-)

Ahh, I missed updating this line. I will update in the next revision.

Regards,
Anup


From neil.armstrong at linaro.org  Thu Feb 22 05:46:11 2024
From: neil.armstrong at linaro.org (neil.armstrong at linaro.org)
Date: Thu, 22 Feb 2024 14:46:11 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAMRc=MfkQuaJ3FnVwbVKQRQEgmJKbZh7SJoK3Kbmb5ebzE2rKA@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org>
 <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org>
 <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
 <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
 <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com>
 <b9a31374-8ea9-407e-9ec3-008a95e2b18b@linaro.org>
 <CAA8EJppWY8c-pF75WaMadWtEuaAyCc5A1VLEq=JmB2Ngzk-zyw@mail.gmail.com>
 <CAMRc=Md6SoXukoGb4bW-CSYgjpO4RL+0Uu3tYrZzgSgVtFH6Sw@mail.gmail.com>
 <CAA8EJprUM6=ZqTwWLB8rW8WRDqwncafa-szSsTvPQCOOSXUn_w@mail.gmail.com>
 <CAMRc=Metemd=24t0RJw-O9Z0-cg4mESouOfvMVLs_rJDCwRBPQ@mail.gmail.com>
 <CAA8EJprJTj7o0ATrQbF_38tW+kLspF1nBySg+_y_RWmadVnV9A@mail.gmail.com>
 <CAMRc=MfkQuaJ3FnVwbVKQRQEgmJKbZh7SJoK3Kbmb5ebzE2rKA@mail.gmail.com>
Message-ID: <aaa20b12-6625-43ae-a07c-9d601e5da391@linaro.org>

On 22/02/2024 13:50, Bartosz Golaszewski wrote:
> On Thu, Feb 22, 2024 at 1:47?PM Dmitry Baryshkov
> <dmitry.baryshkov at linaro.org> wrote:
>>
>> On Thu, 22 Feb 2024 at 14:27, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>>>
>>> On Thu, Feb 22, 2024 at 12:27?PM Dmitry Baryshkov
>>> <dmitry.baryshkov at linaro.org> wrote:
>>>>
>>>> On Thu, 22 Feb 2024 at 13:00, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>>>>>
>>>>> On Mon, Feb 19, 2024 at 11:21?PM Dmitry Baryshkov
>>>>> <dmitry.baryshkov at linaro.org> wrote:
>>>>>>
>>>>>> On Mon, 19 Feb 2024 at 19:18, <neil.armstrong at linaro.org> wrote:
>>>>>>>
>>>>>>> On 19/02/2024 13:33, Dmitry Baryshkov wrote:
>>>>>>>> On Mon, 19 Feb 2024 at 14:23, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>>>>>>>>>
>>>>>>>>> On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
>>>>>>>>> <dmitry.baryshkov at linaro.org> wrote:
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> [snip]
>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
>>>>>>>>>>>>>>> necessary. The BT and WLAN devices on the device-tree are represented as
>>>>>>>>>>>>>>> consuming the inputs (relevant to the functionality of each) of the PMU
>>>>>>>>>>>>>>> directly.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> We are describing the hardware. From the hardware point of view, there
>>>>>>>>>>>>>> is a PMU. I think at some point we would really like to describe all
>>>>>>>>>>>>>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
>>>>>>>>>>>>>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
>>>>>>>>>>>>>
>>>>>>>>>>>>> While I agree with older WiFi+BT units, I don't think it's needed for
>>>>>>>>>>>>> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
>>>>>>>>>>>>> transparent.
>>>>>>>>>>>>
>>>>>>>>>>>> I don't see any significant difference between WCN6750/WCN6855 and
>>>>>>>>>>>> WCN7850 from the PMU / power up point of view. Could you please point
>>>>>>>>>>>> me to the difference?
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
>>>>>>>>>>> and BT_EN ordering and the only requirement is to have all input regulators
>>>>>>>>>>> up before pulling up WLAN_EN and/or BT_EN.
>>>>>>>>>>>
>>>>>>>>>>> This makes the PMU transparent and BT and WLAN can be described as independent.
>>>>>>>>>>
>>>>>>>>>>   From the hardware perspective, there is a PMU. It has several LDOs. So
>>>>>>>>>> the device tree should have the same style as the previous
>>>>>>>>>> generations.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> My thinking was this: yes, there is a PMU but describing it has no
>>>>>>>>> benefit (unlike QCA6x90). If we do describe, then we'll end up having
>>>>>>>>> to use pwrseq here despite it not being needed because now we won't be
>>>>>>>>> able to just get regulators from WLAN/BT drivers directly.
>>>>>>>>>
>>>>>>>>> So I also vote for keeping it this way. Let's go into the package
>>>>>>>>> detail only if it's required.
>>>>>>>>
>>>>>>>> The WiFi / BT parts are not powered up by the board regulators. They
>>>>>>>> are powered up by the PSU. So we are not describing it in the accurate
>>>>>>>> way.
>>>>>>>
>>>>>>> I disagree, the WCN7850 can also be used as a discrete PCIe M.2 card, and in
>>>>>>> this situation the PCIe part is powered with the M.2 slot and the BT side
>>>>>>> is powered separately as we currently do it now.
>>>>>>
>>>>>> QCA6390 can also be used as a discrete M.2 card.
>>>>>>
>>>>>>> So yes there's a PMU, but it's not an always visible hardware part, from the
>>>>>>> SoC PoV, only the separate PCIe and BT subsystems are visible/controllable/powerable.
>>>>>>
>>>>>>  From the hardware point:
>>>>>> - There is a PMU
>>>>>> - The PMU is connected to the board supplies
>>>>>> - Both WiFi and BT parts are connected to the PMU
>>>>>> - The BT_EN / WLAN_EN pins are not connected to the PMU
>>>>>>
>>>>>> So, not representing the PMU in the device tree is a simplification.
>>>>>>
>>>>>
>>>>> What about the existing WLAN and BT users of similar packages? We
>>>>> would have to deprecate a lot of existing bindings. I don't think it's
>>>>> worth it.
>>>>
>>>> We have bindings that are not reflecting the hardware. So yes, we
>>>> should gradually update them once the powerseq is merged.
>>>>
>>>>> The WCN7850 is already described in bindings as consuming what is PMUs
>>>>> inputs and not its outputs.
>>>>
>>>> So do WCN6855 and QCA6391 BlueTooth parts.
>>>>
>>>
>>> That is not true for the latter, this series is adding regulators for it.
>>
>> But the bindings exist already, so you still have to extend it,
>> deprecating regulator-less bindings.
>>
>> Bartosz, I really don't understand what is the issue there. There is a
>> PMU. As such it should be represented in the DT and it can be handled
>> by the same driver as you are adding for QCA6390.
>>
> 
> The issue is that we'll pull in the pwrseq subsystem for WCN7850 which
> clearly does not require it in practice.
> 
> I'd like to hear Krzysztof, Conor or Rob chime in here and make the
> decision on how to proceed.

For WCN7850 we'll be describing the PMU which is basically discrete, so we
could also add dummy fixed regulators, and it would be the same.

Neil

> 
> Bart
> 
>>>
>>> Bart
>>>
>>>>>
>>>>> Bart
>>>>>
>>>>>>>
>>>>>>> Neil
>>>>>>>
>>>>>>>>
>>>>>>>> Moreover, I think we definitely want to move BT driver to use only the
>>>>>>>> pwrseq power up method. Doing it in the other way results in the code
>>>>>>>> duplication and possible issues because of the regulator / pwrseq
>>>>>>>> taking different code paths.
>>>>>>
>>>>>> --
>>>>>> With best wishes
>>>>>> Dmitry
>>>>
>>>>
>>>>
>>>> --
>>>> With best wishes
>>>> Dmitry
>>
>>
>>
>> --
>> With best wishes
>> Dmitry



From vkoul at kernel.org  Thu Feb 22 05:47:03 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Thu, 22 Feb 2024 19:17:03 +0530
Subject: [PATCH 1/1] dmaengine: mxs-dma: switch from dma_coherent to
 dma_pool
In-Reply-To: <ZdTjrzYIiD8pwHk8@lizhi-Precision-Tower-5810>
References: <20240219155728.606497-1-Frank.Li@nxp.com>
 <CAOMZO5C4XFGoWYgexdFLgHiXAoAP7-aMdi=K6CG3adQE_mHAmA@mail.gmail.com>
 <ZdTjrzYIiD8pwHk8@lizhi-Precision-Tower-5810>
Message-ID: <ZddQVzs-VvjraJAf@matsya>

On 20-02-24, 12:38, Frank Li wrote:
> On Mon, Feb 19, 2024 at 01:23:22PM -0300, Fabio Estevam wrote:
> > On Mon, Feb 19, 2024 at 12:57?PM Frank Li <Frank.Li at nxp.com> wrote:
> > >
> > > From: Han Xu <han.xu at nxp.com>
> > >
> > > Using dma_pool to manage dma descriptor memory.
> > 
> > Please clearly describe the motivation for doing this.
> 
> This try to fix a cma_alloc failure. But it is not correct to use dma_pool.
> let's work out a better method.

Good one, but this should be in log :-)

> 
> Frank

-- 
~Vinod


From abel.vesa at linaro.org  Thu Feb 22 05:52:01 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Thu, 22 Feb 2024 15:52:01 +0200
Subject: [PATCH v6 0/5] spmi: pmic-arb: Add support for multiple buses
Message-ID: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>

This RFC prepares for and adds support for 2 buses, which is supported
in HW starting with version 7. Until now, none of the currently
supported platforms in upstream have used the second bus. The X1E80100
platform, on the other hand, needs the second bus for the USB2.0 to work
as there are 3 SMB2360 PMICs which provide eUSB2 repeaters and they are
all found on the second bus.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
Changes in v6:
- Changed the compatible to platform specific (X1E80100) along with the
  schema. Fixed the spmi buses unit addresses and added the empty ranges
  property. Added missing properties to the spmi buses and the
  "unevaluatedProperties: false".
- Deprecated the "qcom,bus-id" in the legacy schema.
- Changed the driver to check for legacy compatible first
- Link to v5: https://lore.kernel.org/r/20240221-spmi-multi-master-support-v5-0-3255ca413a0b at linaro.org

Changes in v5:
- Dropped the RFC as there aren't any concerns about the approach anymore
- Dropped the unused dev and res variables from pmic_arb_get_obsrvr_chnls_v2
- Link to v4: https://lore.kernel.org/r/20240220-spmi-multi-master-support-v4-0-dc813c878ba8 at linaro.org

Changes in v4:
- Fixed comment above pmic_arb_init_apid_v7 by dropping the extra "bus" word
- Swicthed to devm_platform_ioremap_resource_byname for obsrvr and chnls.
  The core remains with platform_get_resource_byname as we need the core size.
- Dropped comment from probe related to the need of platform_get_resource_byname
  as it not true anymore.
- Dropped the qcom,bus-id optional property.
- Link to v3: https://lore.kernel.org/r/20240214-spmi-multi-master-support-v3-0-0bae0ef04faf at linaro.org

Changes in v3:
- Split the change into 3 separate patches. First 2 patches are moving
  apid init and core resources into version specific ops. Third one is
  adding the support for 2 buses and dedicated compatible.
- Added separate bindings patch
- Link to v2: https://lore.kernel.org/r/20240213-spmi-multi-master-support-v2-1-b3b102326906 at linaro.org

Changes in v2:
- Reworked it so that it registers a spmi controller for each bus
  rather than relying on the generic framework to pass on the bus
  (master) id.
- Link to v1: https://lore.kernel.org/r/20240207-spmi-multi-master-support-v1-0-ce57f301c7fd at linaro.org

---
Abel Vesa (5):
      dt-bindings: spmi: Add X1E80100 SPMI PMIC ARB schema
      dt-bindings: spmi: Deprecate qcom,bus-id
      spmi: pmic-arb: Make the APID init a version operation
      spmi: pmic-arb: Make core resources acquiring a version operation
      spmi: pmic-arb: Add multi bus support

 .../bindings/spmi/qcom,spmi-pmic-arb.yaml          |   1 +
 .../bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml | 136 +++
 drivers/spmi/spmi-pmic-arb.c                       | 948 +++++++++++++--------
 3 files changed, 715 insertions(+), 370 deletions(-)
---
base-commit: 4893c639cc3659cefaa675bf1e59f4e7571afb5c
change-id: 20240207-spmi-multi-master-support-832a704b779b

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>



From abel.vesa at linaro.org  Thu Feb 22 05:52:02 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Thu, 22 Feb 2024 15:52:02 +0200
Subject: [PATCH v6 1/5] dt-bindings: spmi: Add X1E80100 SPMI PMIC ARB
 schema
In-Reply-To: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>
References: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>
Message-ID: <20240222-spmi-multi-master-support-v6-1-bc34ea9561da@linaro.org>

Add dedicated schema for X1E80100 PMIC ARB (v7) as it allows multiple
buses by declaring them as child nodes.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 .../bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml | 136 +++++++++++++++++++++
 1 file changed, 136 insertions(+)

diff --git a/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml
new file mode 100644
index 000000000000..bdf362c4a147
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml
@@ -0,0 +1,136 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spmi/qcom,x1e80100-spmi-pmic-arb.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm X1E80100 SPMI Controller (PMIC Arbiter v7)
+
+maintainers:
+  - Stephen Boyd <sboyd at kernel.org>
+
+description: |
+  The X1E80100 SPMI PMIC Arbiter implements HW version 7 and it's an SPMI
+  controller with wrapping arbitration logic to allow for multiple on-chip
+  devices to control up to 2 SPMI separate buses.
+
+  The PMIC Arbiter can also act as an interrupt controller, providing interrupts
+  to slave devices.
+
+properties:
+  compatible:
+    const: qcom,x1e80100-spmi-pmic-arb
+
+  reg:
+    items:
+      - description: core registers
+      - description: tx-channel per virtual slave regosters
+      - description: rx-channel (called observer) per virtual slave registers
+
+  reg-names:
+    items:
+      - const: core
+      - const: chnls
+      - const: obsrvr
+
+  ranges: true
+
+  '#address-cells':
+    const: 2
+
+  '#size-cells':
+    const: 2
+
+  qcom,ee:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 5
+    description: >
+      indicates the active Execution Environment identifier
+
+  qcom,channel:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 5
+    description: >
+      which of the PMIC Arb provided channels to use for accesses
+
+patternProperties:
+  "spmi@[a-f0-9]+$":
+    type: object
+    $ref: /schemas/spmi/spmi.yaml
+    unevaluatedProperties: false
+
+    properties:
+      reg:
+        items:
+          - description: configuration registers
+          - description: interrupt controller registers
+
+      reg-names:
+        items:
+          - const: cnfg
+          - const: intr
+
+      interrupts:
+        maxItems: 1
+
+      interrupt-names:
+        const: periph_irq
+
+      interrupt-controller: true
+
+      '#interrupt-cells':
+        const: 4
+        description: |
+          cell 1: slave ID for the requested interrupt (0-15)
+          cell 2: peripheral ID for requested interrupt (0-255)
+          cell 3: the requested peripheral interrupt (0-7)
+          cell 4: interrupt flags indicating level-sense information,
+                  as defined in dt-bindings/interrupt-controller/irq.h
+
+required:
+  - compatible
+  - reg-names
+  - qcom,ee
+  - qcom,channel
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      spmi: arbiter at c400000 {
+        compatible = "qcom,x1e80100-spmi-pmic-arb";
+        reg = <0 0x0c400000 0 0x3000>,
+              <0 0x0c500000 0 0x4000000>,
+              <0 0x0c440000 0 0x80000>;
+        reg-names = "core", "chnls", "obsrvr";
+
+        qcom,ee = <0>;
+        qcom,channel = <0>;
+
+        #address-cells = <2>;
+        #size-cells = <2>;
+        ranges;
+
+        spmi_bus0: spmi at c42d000 {
+          reg = <0 0x0c42d000 0 0x4000>,
+                <0 0x0c4c0000 0 0x10000>;
+          reg-names = "cnfg", "intr";
+
+          interrupt-names = "periph_irq";
+          interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+          interrupt-controller;
+          #interrupt-cells = <4>;
+
+          #address-cells = <2>;
+          #size-cells = <0>;
+        };
+      };
+    };

-- 
2.34.1



From abel.vesa at linaro.org  Thu Feb 22 05:52:03 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Thu, 22 Feb 2024 15:52:03 +0200
Subject: [PATCH v6 2/5] dt-bindings: spmi: Deprecate qcom,bus-id
In-Reply-To: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>
References: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>
Message-ID: <20240222-spmi-multi-master-support-v6-2-bc34ea9561da@linaro.org>

As it is optional and no platform is actually using the secondary bus,
deprecate the qcom,bus-id property. For newer platforms that implement
SPMI PMIC ARB v7 in HW, the X1E80100 approach should be used.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml
index f983b4af6db9..51daf1b847a9 100644
--- a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml
+++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml
@@ -92,6 +92,7 @@ properties:
     description: >
       SPMI bus instance. only applicable to PMIC arbiter version 7 and beyond.
       Supported values, 0 = primary bus, 1 = secondary bus
+    deprecated: true
 
 required:
   - compatible

-- 
2.34.1



From abel.vesa at linaro.org  Thu Feb 22 05:52:04 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Thu, 22 Feb 2024 15:52:04 +0200
Subject: [PATCH v6 3/5] spmi: pmic-arb: Make the APID init a version
 operation
In-Reply-To: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>
References: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>
Message-ID: <20240222-spmi-multi-master-support-v6-3-bc34ea9561da@linaro.org>

Rather than using conditionals in probe function, add the APID init
as a version specific operation. Due to v7, which supports multiple
buses, pass on the bus index to be used for sorting out the apid base
and count.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 199 +++++++++++++++++++++++++++----------------
 1 file changed, 124 insertions(+), 75 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 9ed1180fe31f..38fed8a585fe 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -183,6 +183,7 @@ struct spmi_pmic_arb {
  * struct pmic_arb_ver_ops - version dependent functionality.
  *
  * @ver_str:		version string.
+ * @init_apid:		finds the apid base and count
  * @ppid_to_apid:	finds the apid for a given ppid.
  * @non_data_cmd:	on v1 issues an spmi non-data command.
  *			on v2 no HW support, returns -EOPNOTSUPP.
@@ -202,6 +203,7 @@ struct spmi_pmic_arb {
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
+	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
 	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
 	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
@@ -942,6 +944,38 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 	return 0;
 }
 
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
+{
+	/*
+	 * Initialize max_apid/min_apid to the opposite bounds, during
+	 * the irq domain translation, we are sure to update these
+	 */
+	pmic_arb->max_apid = 0;
+	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
+
+	return 0;
+}
+
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	u32 *mapping_table;
+
+	if (index) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs,
+				     sizeof(*mapping_table), GFP_KERNEL);
+	if (!mapping_table)
+		return -ENOMEM;
+
+	pmic_arb->mapping_table = mapping_table;
+
+	return pmic_arb_init_apid_min_max(pmic_arb);
+}
+
 static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 {
 	u32 *mapping_table = pmic_arb->mapping_table;
@@ -1144,6 +1178,40 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0x1000 * pmic_arb->ee + 0x8000 * apid;
 }
 
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	int ret;
+
+	if (index) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	pmic_arb->base_apid = 0;
+	pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+					   PMIC_ARB_FEATURES_PERIPH_MASK;
+
+	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+			pmic_arb->base_apid + pmic_arb->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	if (ret) {
+		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v5 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
@@ -1178,6 +1246,49 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return offset;
 }
 
+/*
+ * Only v7 supports 2 buses. Each bus will get a different apid count, read
+ * from different registers.
+ */
+static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
+{
+	int ret;
+
+	if (index == 0) {
+		pmic_arb->base_apid = 0;
+		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else if (index == 1) {
+		pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+						  PMIC_ARB_FEATURES_PERIPH_MASK;
+		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+						   PMIC_ARB_FEATURES_PERIPH_MASK;
+	} else {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+			index);
+		return -EINVAL;
+	}
+
+	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
+		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
+			pmic_arb->base_apid + pmic_arb->apid_count);
+		return -EINVAL;
+	}
+
+	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	if (ret)
+		return ret;
+
+	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	if (ret) {
+		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /*
  * v7 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
@@ -1358,6 +1469,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v1,
 	.offset			= pmic_arb_offset_v1,
@@ -1372,6 +1484,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.ver_str		= "v2",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1386,6 +1499,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.ver_str		= "v3",
+	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v2,
@@ -1400,6 +1514,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.ver_str		= "v5",
+	.init_apid		= pmic_arb_init_apid_v5,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v5,
@@ -1414,6 +1529,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.ver_str		= "v7",
+	.init_apid		= pmic_arb_init_apid_v7,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
 	.offset			= pmic_arb_offset_v7,
@@ -1439,7 +1555,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	struct spmi_controller *ctrl;
 	struct resource *res;
 	void __iomem *core;
-	u32 *mapping_table;
 	u32 channel, ee, hw_ver;
 	int err;
 
@@ -1467,12 +1582,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	pmic_arb->core_size = resource_size(res);
 
-	pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
-					      sizeof(*pmic_arb->ppid_to_apid),
-					      GFP_KERNEL);
-	if (!pmic_arb->ppid_to_apid)
-		return -ENOMEM;
-
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
 	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
@@ -1506,58 +1615,17 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 			return PTR_ERR(pmic_arb->wr_base);
 	}
 
-	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
+		 pmic_arb->ver_ops->ver_str, hw_ver);
 
-	if (hw_ver >= PMIC_ARB_VERSION_V7_MIN) {
+	if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+	else
 		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
-		/* Optional property for v7: */
-		of_property_read_u32(pdev->dev.of_node, "qcom,bus-id",
-					&pmic_arb->bus_instance);
-		if (pmic_arb->bus_instance > 1) {
-			dev_err(&pdev->dev, "invalid bus instance (%u) specified\n",
-				pmic_arb->bus_instance);
-			return -EINVAL;
-		}
-
-		if (pmic_arb->bus_instance == 0) {
-			pmic_arb->base_apid = 0;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		} else {
-			pmic_arb->base_apid =
-				readl_relaxed(core + PMIC_ARB_FEATURES) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-			pmic_arb->apid_count =
-				readl_relaxed(core + PMIC_ARB_FEATURES1) &
-				PMIC_ARB_FEATURES_PERIPH_MASK;
-		}
 
-		if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->base_apid + pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	} else if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		pmic_arb->base_apid = 0;
-		pmic_arb->apid_count = readl_relaxed(core + PMIC_ARB_FEATURES) &
-					PMIC_ARB_FEATURES_PERIPH_MASK;
-
-		if (pmic_arb->apid_count > pmic_arb->max_periphs) {
-			dev_err(&pdev->dev, "Unsupported APID count %d detected\n",
-				pmic_arb->apid_count);
-			return -EINVAL;
-		}
-	}
-
-	pmic_arb->apid_data = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					   sizeof(*pmic_arb->apid_data),
-					   GFP_KERNEL);
-	if (!pmic_arb->apid_data)
-		return -ENOMEM;
-
-	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
-		 pmic_arb->ver_ops->ver_str, hw_ver);
+	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
+	if (err)
+		return err;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
 	pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
@@ -1599,16 +1667,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	}
 
 	pmic_arb->ee = ee;
-	mapping_table = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs,
-					sizeof(*mapping_table), GFP_KERNEL);
-	if (!mapping_table)
-		return -ENOMEM;
-
-	pmic_arb->mapping_table = mapping_table;
-	/* Initialize max_apid/min_apid to the opposite bounds, during
-	 * the irq domain translation, we are sure to update these */
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
 
 	platform_set_drvdata(pdev, ctrl);
 	raw_spin_lock_init(&pmic_arb->lock);
@@ -1617,15 +1675,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	ctrl->read_cmd = pmic_arb_read_cmd;
 	ctrl->write_cmd = pmic_arb_write_cmd;
 
-	if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
-		err = pmic_arb_read_apid_map_v5(pmic_arb);
-		if (err) {
-			dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n",
-				err);
-			return err;
-		}
-	}
-
 	dev_dbg(&pdev->dev, "adding irq domain\n");
 	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
 					 &pmic_arb_irq_domain_ops, pmic_arb);

-- 
2.34.1



From abel.vesa at linaro.org  Thu Feb 22 05:52:05 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Thu, 22 Feb 2024 15:52:05 +0200
Subject: [PATCH v6 4/5] spmi: pmic-arb: Make core resources acquiring a
 version operation
In-Reply-To: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>
References: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>
Message-ID: <20240222-spmi-multi-master-support-v6-4-bc34ea9561da@linaro.org>

Rather than setting up the core, obsrv and chnls in probe by using
version specific conditionals, add a dedicated "get_core_resources"
version specific op and move the acquiring in there.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 113 +++++++++++++++++++++++++++----------------
 1 file changed, 70 insertions(+), 43 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 38fed8a585fe..188252bfb95f 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -203,6 +203,7 @@ struct spmi_pmic_arb {
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
+	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
 	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
 	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
@@ -956,6 +957,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
 	return 0;
 }
 
+static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->wr_base = core;
+	pmic_arb->rd_base = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+	return 0;
+}
+
 static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
 {
 	u32 *mapping_table;
@@ -1063,6 +1077,33 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 	return apid;
 }
 
+static int pmic_arb_get_obsrvr_chnls_v2(struct platform_device *pdev)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->rd_base = devm_platform_ioremap_resource_byname(pdev, "obsrvr");
+	if (IS_ERR(pmic_arb->rd_base))
+		return PTR_ERR(pmic_arb->rd_base);
+
+	pmic_arb->wr_base = devm_platform_ioremap_resource_byname(pdev, "chnls");
+	if (IS_ERR(pmic_arb->wr_base))
+		return PTR_ERR(pmic_arb->wr_base);
+
+	return 0;
+}
+
+static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->core = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
+
+	return pmic_arb_get_obsrvr_chnls_v2(pdev);
+}
+
 static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 {
 	u16 apid_valid;
@@ -1246,6 +1287,18 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return offset;
 }
 
+static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
+					  void __iomem *core)
+{
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	pmic_arb->core = core;
+
+	pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+
+	return pmic_arb_get_obsrvr_chnls_v2(pdev);
+}
+
 /*
  * Only v7 supports 2 buses. Each bus will get a different apid count, read
  * from different registers.
@@ -1469,6 +1522,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
+	.get_core_resources	= pmic_arb_get_core_resources_v1,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v1,
@@ -1484,6 +1538,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 	.ver_str		= "v2",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1499,6 +1554,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 	.ver_str		= "v3",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v1,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v2,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1514,6 +1570,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 	.ver_str		= "v5",
+	.get_core_resources	= pmic_arb_get_core_resources_v2,
 	.init_apid		= pmic_arb_init_apid_v5,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1529,6 +1586,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
 
 static const struct pmic_arb_ver_ops pmic_arb_v7 = {
 	.ver_str		= "v7",
+	.get_core_resources	= pmic_arb_get_core_resources_v7,
 	.init_apid		= pmic_arb_init_apid_v7,
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
 	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
@@ -1565,16 +1623,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	pmic_arb = spmi_controller_get_drvdata(ctrl);
 	pmic_arb->spmic = ctrl;
 
-	/*
-	 * Please don't replace this with devm_platform_ioremap_resource() or
-	 * devm_ioremap_resource().  These both result in a call to
-	 * devm_request_mem_region() which prevents multiple mappings of this
-	 * register address range.  SoCs with PMIC arbiter v7 may define two
-	 * arbiter devices, for the two physical SPMI interfaces, which  share
-	 * some register address ranges (i.e. "core", "obsrvr", and "chnls").
-	 * Ensure that both devices probe successfully by calling devm_ioremap()
-	 * which does not result in a devm_request_mem_region() call.
-	 */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
 	core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
 	if (IS_ERR(core))
@@ -1584,44 +1632,23 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
-	if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
+	if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
 		pmic_arb->ver_ops = &pmic_arb_v1;
-		pmic_arb->wr_base = core;
-		pmic_arb->rd_base = core;
-	} else {
-		pmic_arb->core = core;
-
-		if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v2;
-		else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v3;
-		else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
-			pmic_arb->ver_ops = &pmic_arb_v5;
-		else
-			pmic_arb->ver_ops = &pmic_arb_v7;
-
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   "obsrvr");
-		pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start,
-						 resource_size(res));
-		if (IS_ERR(pmic_arb->rd_base))
-			return PTR_ERR(pmic_arb->rd_base);
-
-		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						   "chnls");
-		pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start,
-						 resource_size(res));
-		if (IS_ERR(pmic_arb->wr_base))
-			return PTR_ERR(pmic_arb->wr_base);
-	}
+	else if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v2;
+	else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v3;
+	else if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
+		pmic_arb->ver_ops = &pmic_arb_v5;
+	else
+		pmic_arb->ver_ops = &pmic_arb_v7;
 
 	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
 		 pmic_arb->ver_ops->ver_str, hw_ver);
 
-	if (hw_ver < PMIC_ARB_VERSION_V7_MIN)
-		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS;
-	else
-		pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7;
+	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
+	if (err)
+		return err;
 
 	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
 	if (err)

-- 
2.34.1



From abel.vesa at linaro.org  Thu Feb 22 05:52:06 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Thu, 22 Feb 2024 15:52:06 +0200
Subject: [PATCH v6 5/5] spmi: pmic-arb: Add multi bus support
In-Reply-To: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>
References: <20240222-spmi-multi-master-support-v6-0-bc34ea9561da@linaro.org>
Message-ID: <20240222-spmi-multi-master-support-v6-5-bc34ea9561da@linaro.org>

Starting with HW version 7, there are actually two separate buses
(with two separate sets of wires). So in order to support both
buses, we need to register a separate spmi controller for each one.
Add a separate compatible for v7 only, but allow the legacy platforms
that have v7 to still work with the old one, for DT backwards
compatibility.

Signed-off-by: Abel Vesa <abel.vesa at linaro.org>
---
 drivers/spmi/spmi-pmic-arb.c | 726 +++++++++++++++++++++++++------------------
 1 file changed, 429 insertions(+), 297 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 188252bfb95f..ca0f42952445 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -13,6 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spmi.h>
@@ -94,6 +96,8 @@ enum pmic_arb_channel {
 	PMIC_ARB_CHANNEL_OBS,
 };
 
+#define PMIC_ARB_MAX_BUSES		2
+
 /* Maximum number of support PMIC peripherals */
 #define PMIC_ARB_MAX_PERIPHS		512
 #define PMIC_ARB_MAX_PERIPHS_V7		1024
@@ -125,58 +129,68 @@ struct apid_data {
 	u8		irq_ee;
 };
 
+struct spmi_pmic_arb;
+
 /**
- * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ * struct spmi_pmic_arb_bus - SPMI PMIC Arbiter Bus object
  *
- * @rd_base:		on v1 "core", on v2 "observer" register base off DT.
- * @wr_base:		on v1 "core", on v2 "chnls"    register base off DT.
  * @intr:		address of the SPMI interrupt control registers.
  * @cnfg:		address of the PMIC Arbiter configuration registers.
- * @lock:		lock to synchronize accesses.
- * @channel:		execution environment channel to use for accesses.
- * @irq:		PMIC ARB interrupt.
- * @ee:			the current Execution Environment
- * @bus_instance:	on v7: 0 = primary SPMI bus, 1 = secondary SPMI bus
- * @min_apid:		minimum APID (used for bounding IRQ search)
- * @max_apid:		maximum APID
+ * @domain:		irq domain object for PMIC IRQ domain
  * @base_apid:		on v7: minimum APID associated with the particular SPMI
  *			bus instance
  * @apid_count:		on v5 and v7: number of APIDs associated with the
  *			particular SPMI bus instance
  * @mapping_table:	in-memory copy of PPID -> APID mapping table.
- * @domain:		irq domain object for PMIC IRQ domain
- * @spmic:		SPMI controller object
- * @ver_ops:		version dependent operations.
  * @ppid_to_apid:	in-memory copy of PPID -> APID mapping table.
- * @last_apid:		Highest value APID in use
  * @apid_data:		Table of data for all APIDs
+ * @last_apid:		Highest value APID in use
+ * @irq:		PMIC ARB interrupt.
+ */
+struct spmi_pmic_arb_bus {
+	struct spmi_pmic_arb	*pmic_arb;
+	struct irq_domain	*domain;
+	void __iomem		*intr;
+	void __iomem		*cnfg;
+	struct spmi_controller	*spmic;
+	u16			base_apid;
+	int			apid_count;
+	u32			*mapping_table;
+	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
+	u16			*ppid_to_apid;
+	u16			last_apid;
+	struct apid_data	*apid_data;
+	u16			min_apid;
+	u16			max_apid;
+	int			irq;
+	u8			id;
+};
+
+/**
+ * struct spmi_pmic_arb - SPMI PMIC Arbiter object
+ *
+ * @rd_base:		on v1 "core", on v2 "observer" register base off DT.
+ * @wr_base:		on v1 "core", on v2 "chnls"    register base off DT.
+ * @lock:		lock to synchronize accesses.
+ * @channel:		execution environment channel to use for accesses.
+ * @ee:			the current Execution Environment
+ * @min_apid:		minimum APID (used for bounding IRQ search)
+ * @max_apid:		maximum APID
+ * @ver_ops:		version dependent operations.
  * @max_periphs:	Number of elements in apid_data[]
  */
 struct spmi_pmic_arb {
 	void __iomem		*rd_base;
 	void __iomem		*wr_base;
-	void __iomem		*intr;
-	void __iomem		*cnfg;
 	void __iomem		*core;
 	resource_size_t		core_size;
 	raw_spinlock_t		lock;
 	u8			channel;
-	int			irq;
 	u8			ee;
-	u32			bus_instance;
-	u16			min_apid;
-	u16			max_apid;
-	u16			base_apid;
-	int			apid_count;
-	u32			*mapping_table;
-	DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
-	struct irq_domain	*domain;
-	struct spmi_controller	*spmic;
 	const struct pmic_arb_ver_ops *ver_ops;
-	u16			*ppid_to_apid;
-	u16			last_apid;
-	struct apid_data	*apid_data;
 	int			max_periphs;
+	struct spmi_pmic_arb_bus buses[PMIC_ARB_MAX_BUSES];
+	int			buses_available;
 };
 
 /**
@@ -204,21 +218,21 @@ struct spmi_pmic_arb {
 struct pmic_arb_ver_ops {
 	const char *ver_str;
 	int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
-	int (*init_apid)(struct spmi_pmic_arb *pmic_arb, int index);
-	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
+	int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index);
+	int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
-	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type);
+	int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+		      enum pmic_arb_channel ch_type);
 	u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
 	int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
 	/* Interrupts controller functionality (offset of PIC registers) */
-	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb *pmic_arb, u8 m,
+	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb_bus *bus, u8 m,
 					  u16 n);
-	void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
-	void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*acc_enable)(struct spmi_pmic_arb_bus *bus, u16 n);
+	void __iomem *(*irq_status)(struct spmi_pmic_arb_bus *bus, u16 n);
+	void __iomem *(*irq_clear)(struct spmi_pmic_arb_bus *bus, u16 n);
 	u32 (*apid_map_offset)(u16 n);
-	void __iomem *(*apid_owner)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*apid_owner)(struct spmi_pmic_arb_bus *bus, u16 n);
 };
 
 static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -266,13 +280,14 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 				  void __iomem *base, u8 sid, u16 addr,
 				  enum pmic_arb_channel ch_type)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 status = 0;
 	u32 timeout = PMIC_ARB_TIMEOUT_US;
 	u32 offset;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type);
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr, ch_type);
 	if (rc < 0)
 		return rc;
 
@@ -284,21 +299,21 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 
 		if (status & PMIC_ARB_STATUS_DONE) {
 			if (status & PMIC_ARB_STATUS_DENIED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction denied (%#x)\n",
+					__func__, bus->id, sid, addr, status);
 				return -EPERM;
 			}
 
 			if (status & PMIC_ARB_STATUS_FAILURE) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction failed (%#x) reg: 0x%x\n",
+					__func__, bus->id, sid, addr, status, offset);
 				WARN_ON(1);
 				return -EIO;
 			}
 
 			if (status & PMIC_ARB_STATUS_DROPPED) {
-				dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n",
-					__func__, sid, addr, status);
+				dev_err(&ctrl->dev, "%s: %#x %#x %#x: transaction dropped (%#x)\n",
+					__func__, bus->id, sid, addr, status);
 				return -EIO;
 			}
 
@@ -307,8 +322,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 		udelay(1);
 	}
 
-	dev_err(&ctrl->dev, "%s: %#x %#x: timeout, status %#x\n",
-		__func__, sid, addr, status);
+	dev_err(&ctrl->dev, "%s: %#x %#x %#x: timeout, status %#x\n",
+		__func__, bus->id, sid, addr, status);
 	return -ETIMEDOUT;
 }
 
@@ -316,12 +331,13 @@ static int
 pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[0];
 	unsigned long flags;
 	u32 cmd;
 	int rc;
 	u32 offset;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW);
+	rc = pmic_arb->ver_ops->offset(bus, sid, 0, PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
@@ -357,20 +373,21 @@ static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
 	return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid);
 }
 
-static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc, u8 sid,
+static int pmic_arb_fmt_read_cmd(struct spmi_pmic_arb_bus *bus, u8 opc, u8 sid,
 				 u16 addr, size_t len, u32 *cmd, u32 *offset)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr,
 				       PMIC_ARB_CHANNEL_OBS);
 	if (rc < 0)
 		return rc;
 
 	*offset = rc;
 	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-		dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+		dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
 			PMIC_ARB_MAX_TRANS_BYTES, len);
 		return  -EINVAL;
 	}
@@ -394,7 +411,8 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      u32 offset, u8 sid, u16 addr, u8 *buf,
 				      size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
@@ -416,12 +434,13 @@ static int pmic_arb_read_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 			     u16 addr, u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned long flags;
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_read_cmd(bus, opc, sid, addr, len, &cmd,
 				   &offset);
 	if (rc)
 		return rc;
@@ -433,21 +452,22 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 	return rc;
 }
 
-static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb *pmic_arb, u8 opc,
+static int pmic_arb_fmt_write_cmd(struct spmi_pmic_arb_bus *bus, u8 opc,
 				  u8 sid, u16 addr, size_t len, u32 *cmd,
 				  u32 *offset)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+	rc = pmic_arb->ver_ops->offset(bus, sid, addr,
 					PMIC_ARB_CHANNEL_RW);
 	if (rc < 0)
 		return rc;
 
 	*offset = rc;
 	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-		dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
+		dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
 			PMIC_ARB_MAX_TRANS_BYTES, len);
 		return  -EINVAL;
 	}
@@ -473,7 +493,8 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 				      u32 offset, u8 sid, u16 addr,
 				      const u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 bc = len - 1;
 
 	/* Write data to FIFOs */
@@ -492,12 +513,13 @@ static int pmic_arb_write_cmd_unlocked(struct spmi_controller *ctrl, u32 cmd,
 static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 			      u16 addr, const u8 *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned long flags;
 	u32 cmd, offset;
 	int rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, opc, sid, addr, len, &cmd,
+	rc = pmic_arb_fmt_write_cmd(bus, opc, sid, addr, len, &cmd,
 				    &offset);
 	if (rc)
 		return rc;
@@ -513,18 +535,19 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 static int pmic_arb_masked_write(struct spmi_controller *ctrl, u8 sid, u16 addr,
 				 const u8 *buf, const u8 *mask, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 read_cmd, read_offset, write_cmd, write_offset;
 	u8 temp[PMIC_ARB_MAX_TRANS_BYTES];
 	unsigned long flags;
 	int rc, i;
 
-	rc = pmic_arb_fmt_read_cmd(pmic_arb, SPMI_CMD_EXT_READL, sid, addr, len,
+	rc = pmic_arb_fmt_read_cmd(bus, SPMI_CMD_EXT_READL, sid, addr, len,
 				   &read_cmd, &read_offset);
 	if (rc)
 		return rc;
 
-	rc = pmic_arb_fmt_write_cmd(pmic_arb, SPMI_CMD_EXT_WRITEL, sid, addr,
+	rc = pmic_arb_fmt_write_cmd(bus, SPMI_CMD_EXT_WRITEL, sid, addr,
 				    len, &write_cmd, &write_offset);
 	if (rc)
 		return rc;
@@ -567,25 +590,25 @@ struct spmi_pmic_arb_qpnpint_type {
 static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
 			       size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
+	if (pmic_arb_write_cmd(bus->spmic, SPMI_CMD_EXT_WRITEL, sid,
 			       (per << 8) + reg, buf, len))
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
 }
 
 static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 
-	if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, sid,
+	if (pmic_arb_read_cmd(bus->spmic, SPMI_CMD_EXT_READL, sid,
 			      (per << 8) + reg, buf, len))
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n",
 				    d->irq);
 }
 
@@ -593,47 +616,49 @@ static int qpnpint_spmi_masked_write(struct irq_data *d, u8 reg,
 				     const void *buf, const void *mask,
 				     size_t len)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 	u8 sid = hwirq_to_sid(d->hwirq);
 	u8 per = hwirq_to_per(d->hwirq);
 	int rc;
 
-	rc = pmic_arb_masked_write(pmic_arb->spmic, sid, (per << 8) + reg, buf,
+	rc = pmic_arb_masked_write(bus->spmic, sid, (per << 8) + reg, buf,
 				   mask, len);
 	if (rc)
-		dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
+		dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x rc=%d\n",
 				    d->irq, rc);
 	return rc;
 }
 
-static void cleanup_irq(struct spmi_pmic_arb *pmic_arb, u16 apid, int id)
+static void cleanup_irq(struct spmi_pmic_arb_bus *bus, u16 apid, int id)
 {
-	u16 ppid = pmic_arb->apid_data[apid].ppid;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	u16 ppid = bus->apid_data[apid].ppid;
 	u8 sid = ppid >> 8;
 	u8 per = ppid & 0xFF;
 	u8 irq_mask = BIT(id);
 
-	dev_err_ratelimited(&pmic_arb->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
-			__func__, apid, sid, per, id);
-	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	dev_err_ratelimited(&bus->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n",
+			    __func__, apid, sid, per, id);
+	writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(bus, apid));
 }
 
-static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
+static int periph_interrupt(struct spmi_pmic_arb_bus *bus, u16 apid)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	unsigned int irq;
 	u32 status, id;
 	int handled = 0;
-	u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF;
-	u8 per = pmic_arb->apid_data[apid].ppid & 0xFF;
+	u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF;
+	u8 per = bus->apid_data[apid].ppid & 0xFF;
 
-	status = readl_relaxed(pmic_arb->ver_ops->irq_status(pmic_arb, apid));
+	status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid));
 	while (status) {
 		id = ffs(status) - 1;
 		status &= ~BIT(id);
-		irq = irq_find_mapping(pmic_arb->domain,
-					spec_to_hwirq(sid, per, id, apid));
+		irq = irq_find_mapping(bus->domain,
+				       spec_to_hwirq(sid, per, id, apid));
 		if (irq == 0) {
-			cleanup_irq(pmic_arb, apid, id);
+			cleanup_irq(bus, apid, id);
 			continue;
 		}
 		generic_handle_irq(irq);
@@ -645,16 +670,17 @@ static int periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
 
 static void pmic_arb_chained_irq(struct irq_desc *desc)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb_bus *bus = irq_desc_get_handler_data(desc);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int first = pmic_arb->min_apid;
-	int last = pmic_arb->max_apid;
+	int first = bus->min_apid;
+	int last = bus->max_apid;
 	/*
 	 * acc_offset will be non-zero for the secondary SPMI bus instance on
 	 * v7 controllers.
 	 */
-	int acc_offset = pmic_arb->base_apid >> 5;
+	int acc_offset = bus->base_apid >> 5;
 	u8 ee = pmic_arb->ee;
 	u32 status, enable, handled = 0;
 	int i, id, apid;
@@ -665,7 +691,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	chained_irq_enter(chip, desc);
 
 	for (i = first >> 5; i <= last >> 5; ++i) {
-		status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i - acc_offset));
+		status = readl_relaxed(ver_ops->owner_acc_status(bus, ee, i - acc_offset));
 		if (status)
 			acc_valid = true;
 
@@ -679,9 +705,9 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 				continue;
 			}
 			enable = readl_relaxed(
-					ver_ops->acc_enable(pmic_arb, apid));
+					ver_ops->acc_enable(bus, apid));
 			if (enable & SPMI_PIC_ACC_ENABLE_BIT)
-				if (periph_interrupt(pmic_arb, apid) != 0)
+				if (periph_interrupt(bus, apid) != 0)
 					handled++;
 		}
 	}
@@ -690,19 +716,19 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	if (!acc_valid) {
 		for (i = first; i <= last; i++) {
 			/* skip if APPS is not irq owner */
-			if (pmic_arb->apid_data[i].irq_ee != pmic_arb->ee)
+			if (bus->apid_data[i].irq_ee != pmic_arb->ee)
 				continue;
 
 			irq_status = readl_relaxed(
-					     ver_ops->irq_status(pmic_arb, i));
+					     ver_ops->irq_status(bus, i));
 			if (irq_status) {
 				enable = readl_relaxed(
-					     ver_ops->acc_enable(pmic_arb, i));
+					     ver_ops->acc_enable(bus, i));
 				if (enable & SPMI_PIC_ACC_ENABLE_BIT) {
-					dev_dbg(&pmic_arb->spmic->dev,
+					dev_dbg(&bus->spmic->dev,
 						"Dispatching IRQ for apid=%d status=%x\n",
 						i, irq_status);
-					if (periph_interrupt(pmic_arb, i) != 0)
+					if (periph_interrupt(bus, i) != 0)
 						handled++;
 				}
 			}
@@ -717,12 +743,13 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 
 static void qpnpint_irq_ack(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 data;
 
-	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
+	writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(bus, apid));
 
 	data = BIT(irq);
 	qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
@@ -738,14 +765,15 @@ static void qpnpint_irq_mask(struct irq_data *d)
 
 static void qpnpint_irq_unmask(struct irq_data *d)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 buf[2];
 
 	writel_relaxed(SPMI_PIC_ACC_ENABLE_BIT,
-			ver_ops->acc_enable(pmic_arb, apid));
+			ver_ops->acc_enable(bus, apid));
 
 	qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1);
 	if (!(buf[0] & BIT(irq))) {
@@ -802,9 +830,9 @@ static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
 
 static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
 
-	return irq_set_irq_wake(pmic_arb->irq, on);
+	return irq_set_irq_wake(bus->irq, on);
 }
 
 static int qpnpint_get_irqchip_state(struct irq_data *d,
@@ -826,17 +854,18 @@ static int qpnpint_get_irqchip_state(struct irq_data *d,
 static int qpnpint_irq_domain_activate(struct irq_domain *domain,
 				       struct irq_data *d, bool reserve)
 {
-	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb_bus *bus = irq_data_get_irq_chip_data(d);
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 periph = hwirq_to_per(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u16 sid = hwirq_to_sid(d->hwirq);
 	u16 irq = hwirq_to_irq(d->hwirq);
 	u8 buf;
 
-	if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
+	if (bus->apid_data[apid].irq_ee != pmic_arb->ee) {
+		dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
 			sid, periph, irq, pmic_arb->ee,
-			pmic_arb->apid_data[apid].irq_ee);
+			bus->apid_data[apid].irq_ee);
 		return -ENODEV;
 	}
 
@@ -863,15 +892,16 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 					unsigned long *out_hwirq,
 					unsigned int *out_type)
 {
-	struct spmi_pmic_arb *pmic_arb = d->host_data;
+	struct spmi_pmic_arb_bus *bus = d->host_data;
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 *intspec = fwspec->param;
 	u16 apid, ppid;
 	int rc;
 
-	dev_dbg(&pmic_arb->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
+	dev_dbg(&bus->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
 		intspec[0], intspec[1], intspec[2]);
 
-	if (irq_domain_get_of_node(d) != pmic_arb->spmic->dev.of_node)
+	if (irq_domain_get_of_node(d) != bus->spmic->dev.of_node)
 		return -EINVAL;
 	if (fwspec->param_count != 4)
 		return -EINVAL;
@@ -879,37 +909,38 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d,
 		return -EINVAL;
 
 	ppid = intspec[0] << 8 | intspec[1];
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
 	if (rc < 0) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
-		intspec[0], intspec[1], intspec[2], rc);
+		dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
+			intspec[0], intspec[1], intspec[2], rc);
 		return rc;
 	}
 
 	apid = rc;
 	/* Keep track of {max,min}_apid for bounding search during interrupt */
-	if (apid > pmic_arb->max_apid)
-		pmic_arb->max_apid = apid;
-	if (apid < pmic_arb->min_apid)
-		pmic_arb->min_apid = apid;
+	if (apid > bus->max_apid)
+		bus->max_apid = apid;
+	if (apid < bus->min_apid)
+		bus->min_apid = apid;
 
 	*out_hwirq = spec_to_hwirq(intspec[0], intspec[1], intspec[2], apid);
 	*out_type  = intspec[3] & IRQ_TYPE_SENSE_MASK;
 
-	dev_dbg(&pmic_arb->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
+	dev_dbg(&bus->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
 
 	return 0;
 }
 
 static struct lock_class_key qpnpint_irq_lock_class, qpnpint_irq_request_class;
 
-static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb,
+static void qpnpint_irq_domain_map(struct spmi_pmic_arb_bus *bus,
 				   struct irq_domain *domain, unsigned int virq,
 				   irq_hw_number_t hwirq, unsigned int type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	irq_flow_handler_t handler;
 
-	dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
+	dev_dbg(&bus->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
 		virq, hwirq, type);
 
 	if (type & IRQ_TYPE_EDGE_BOTH)
@@ -928,7 +959,7 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 				    unsigned int virq, unsigned int nr_irqs,
 				    void *data)
 {
-	struct spmi_pmic_arb *pmic_arb = domain->host_data;
+	struct spmi_pmic_arb_bus *bus = domain->host_data;
 	struct irq_fwspec *fwspec = data;
 	irq_hw_number_t hwirq;
 	unsigned int type;
@@ -939,20 +970,22 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
 		return ret;
 
 	for (i = 0; i < nr_irqs; i++)
-		qpnpint_irq_domain_map(pmic_arb, domain, virq + i, hwirq + i,
+		qpnpint_irq_domain_map(bus, domain, virq + i, hwirq + i,
 				       type);
 
 	return 0;
 }
 
-static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb_bus *bus)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+
 	/*
 	 * Initialize max_apid/min_apid to the opposite bounds, during
 	 * the irq domain translation, we are sure to update these
 	 */
-	pmic_arb->max_apid = 0;
-	pmic_arb->min_apid = pmic_arb->max_periphs - 1;
+	bus->max_apid = 0;
+	bus->min_apid = pmic_arb->max_periphs - 1;
 
 	return 0;
 }
@@ -970,43 +1003,44 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
 	return 0;
 }
 
-static int pmic_arb_init_apid_v1(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u32 *mapping_table;
 
 	if (index) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
 			index);
 		return -EINVAL;
 	}
 
-	mapping_table = devm_kcalloc(&pmic_arb->spmic->dev, pmic_arb->max_periphs,
+	mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs,
 				     sizeof(*mapping_table), GFP_KERNEL);
 	if (!mapping_table)
 		return -ENOMEM;
 
-	pmic_arb->mapping_table = mapping_table;
+	bus->mapping_table = mapping_table;
 
-	return pmic_arb_init_apid_min_max(pmic_arb);
+	return pmic_arb_init_apid_min_max(bus);
 }
 
-static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	u32 *mapping_table = pmic_arb->mapping_table;
+	u32 *mapping_table = bus->mapping_table;
 	int index = 0, i;
 	u16 apid_valid;
 	u16 apid;
 	u32 data;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = bus->ppid_to_apid[ppid];
 	if (apid_valid & PMIC_ARB_APID_VALID) {
 		apid = apid_valid & ~PMIC_ARB_APID_VALID;
 		return apid;
 	}
 
 	for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
-		if (!test_and_set_bit(index, pmic_arb->mapping_table_valid))
-			mapping_table[index] = readl_relaxed(pmic_arb->cnfg +
+		if (!test_and_set_bit(index, bus->mapping_table_valid))
+			mapping_table[index] = readl_relaxed(bus->cnfg +
 						SPMI_MAPPING_TABLE_REG(index));
 
 		data = mapping_table[index];
@@ -1016,9 +1050,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				bus->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				bus->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		} else {
@@ -1026,9 +1060,9 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 				index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
 			} else {
 				apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
-				pmic_arb->ppid_to_apid[ppid]
+				bus->ppid_to_apid[ppid]
 					= apid | PMIC_ARB_APID_VALID;
-				pmic_arb->apid_data[apid].ppid = ppid;
+				bus->apid_data[apid].ppid = ppid;
 				return apid;
 			}
 		}
@@ -1038,24 +1072,26 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 }
 
 /* v1 offset per ee */
-static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v1(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return 0x800 + 0x80 * pmic_arb->channel;
 }
 
-static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static u16 pmic_arb_find_apid(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid];
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	struct apid_data *apidd = &bus->apid_data[bus->last_apid];
 	u32 regval, offset;
 	u16 id, apid;
 
-	for (apid = pmic_arb->last_apid; ; apid++, apidd++) {
+	for (apid = bus->last_apid; ; apid++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(apid);
 		if (offset >= pmic_arb->core_size)
 			break;
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus,
 								     apid));
 		apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 		apidd->write_ee = apidd->irq_ee;
@@ -1065,14 +1101,14 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 			continue;
 
 		id = (regval >> 8) & PMIC_ARB_PPID_MASK;
-		pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
+		bus->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
 		apidd->ppid = id;
 		if (id == ppid) {
 			apid |= PMIC_ARB_APID_VALID;
 			break;
 		}
 	}
-	pmic_arb->last_apid = apid & ~PMIC_ARB_APID_VALID;
+	bus->last_apid = apid & ~PMIC_ARB_APID_VALID;
 
 	return apid;
 }
@@ -1104,21 +1140,22 @@ static int pmic_arb_get_core_resources_v2(struct platform_device *pdev,
 	return pmic_arb_get_obsrvr_chnls_v2(pdev);
 }
 
-static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
 	u16 apid_valid;
 
-	apid_valid = pmic_arb->ppid_to_apid[ppid];
+	apid_valid = bus->ppid_to_apid[ppid];
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
-		apid_valid = pmic_arb_find_apid(pmic_arb, ppid);
+		apid_valid = pmic_arb_find_apid(bus, ppid);
 	if (!(apid_valid & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
 	return apid_valid & ~PMIC_ARB_APID_VALID;
 }
 
-static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	struct apid_data *apidd;
 	struct apid_data *prev_apidd;
 	u16 i, apid, ppid, apid_max;
@@ -1140,9 +1177,9 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 	 * where N = number of APIDs supported by the primary bus and
 	 *       M = number of APIDs supported by the secondary bus
 	 */
-	apidd = &pmic_arb->apid_data[pmic_arb->base_apid];
-	apid_max = pmic_arb->base_apid + pmic_arb->apid_count;
-	for (i = pmic_arb->base_apid; i < apid_max; i++, apidd++) {
+	apidd = &bus->apid_data[bus->base_apid];
+	apid_max = bus->base_apid + bus->apid_count;
+	for (i = bus->base_apid; i < apid_max; i++, apidd++) {
 		offset = pmic_arb->ver_ops->apid_map_offset(i);
 		if (offset >= pmic_arb->core_size)
 			break;
@@ -1153,19 +1190,18 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		ppid = (regval >> 8) & PMIC_ARB_PPID_MASK;
 		is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval);
 
-		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb,
-								     i));
+		regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i));
 		apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
 
 		apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE;
 
-		valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
-		apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
-		prev_apidd = &pmic_arb->apid_data[apid];
+		valid = bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
+		apid = bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+		prev_apidd = &bus->apid_data[apid];
 
 		if (!valid || apidd->write_ee == pmic_arb->ee) {
 			/* First PPID mapping or one for this EE */
-			pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+			bus->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
 		} else if (valid && is_irq_ee &&
 			   prev_apidd->write_ee == pmic_arb->ee) {
 			/*
@@ -1176,42 +1212,43 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
 		}
 
 		apidd->ppid = ppid;
-		pmic_arb->last_apid = i;
+		bus->last_apid = i;
 	}
 
 	/* Dump the mapping table for debug purposes. */
-	dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
+	dev_dbg(&bus->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
 	for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) {
-		apid = pmic_arb->ppid_to_apid[ppid];
+		apid = bus->ppid_to_apid[ppid];
 		if (apid & PMIC_ARB_APID_VALID) {
 			apid &= ~PMIC_ARB_APID_VALID;
-			apidd = &pmic_arb->apid_data[apid];
-			dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n",
-			      ppid, apid, apidd->write_ee, apidd->irq_ee);
+			apidd = &bus->apid_data[apid];
+			dev_dbg(&bus->spmic->dev, "%#03X %3u %2u %2u\n",
+				ppid, apid, apidd->write_ee, apidd->irq_ee);
 		}
 	}
 
 	return 0;
 }
 
-static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb_bus *bus, u16 ppid)
 {
-	if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
+	if (!(bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
 		return -ENODEV;
 
-	return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+	return bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
 }
 
 /* v2 offset per ppid and per ee */
-static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	u16 ppid;
 	int rc;
 
 	ppid = sid << 8 | ((addr >> 8) & 0xFF);
-	rc = pmic_arb_ppid_to_apid_v2(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v2(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1219,33 +1256,34 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0x1000 * pmic_arb->ee + 0x8000 * apid;
 }
 
-static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	int ret;
 
 	if (index) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
 			index);
 		return -EINVAL;
 	}
 
-	pmic_arb->base_apid = 0;
-	pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+	bus->base_apid = 0;
+	bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 					   PMIC_ARB_FEATURES_PERIPH_MASK;
 
-	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
-			pmic_arb->base_apid + pmic_arb->apid_count);
+	if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+		dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+			bus->base_apid + bus->apid_count);
 		return -EINVAL;
 	}
 
-	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	ret = pmic_arb_init_apid_min_max(bus);
 	if (ret)
 		return ret;
 
-	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	ret = pmic_arb_read_apid_map_v5(bus);
 	if (ret) {
-		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+		dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
 			ret);
 		return ret;
 	}
@@ -1257,15 +1295,16 @@ static int pmic_arb_init_apid_v5(struct spmi_pmic_arb *pmic_arb, int index)
  * v5 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v5(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
+	rc = pmic_arb_ppid_to_apid_v5(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1275,8 +1314,8 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
-			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+		if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+			dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
 		}
@@ -1303,38 +1342,39 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
  * Only v7 supports 2 buses. Each bus will get a different apid count, read
  * from different registers.
  */
-static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
+static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	int ret;
 
 	if (index == 0) {
-		pmic_arb->base_apid = 0;
-		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+		bus->base_apid = 0;
+		bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 						   PMIC_ARB_FEATURES_PERIPH_MASK;
 	} else if (index == 1) {
-		pmic_arb->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
+		bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
 						  PMIC_ARB_FEATURES_PERIPH_MASK;
-		pmic_arb->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
+		bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
 						   PMIC_ARB_FEATURES_PERIPH_MASK;
 	} else {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported buses count %d detected\n",
-			index);
+		dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
+			bus->id);
 		return -EINVAL;
 	}
 
-	if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) {
-		dev_err(&pmic_arb->spmic->dev, "Unsupported APID count %d detected\n",
-			pmic_arb->base_apid + pmic_arb->apid_count);
+	if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
+		dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
+			bus->base_apid + bus->apid_count);
 		return -EINVAL;
 	}
 
-	ret = pmic_arb_init_apid_min_max(pmic_arb);
+	ret = pmic_arb_init_apid_min_max(bus);
 	if (ret)
 		return ret;
 
-	ret = pmic_arb_read_apid_map_v5(pmic_arb);
+	ret = pmic_arb_read_apid_map_v5(bus);
 	if (ret) {
-		dev_err(&pmic_arb->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
+		dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
 			ret);
 		return ret;
 	}
@@ -1346,15 +1386,16 @@ static int pmic_arb_init_apid_v7(struct spmi_pmic_arb *pmic_arb, int index)
  * v7 offset per ee and per apid for observer channels and per apid for
  * read/write channels.
  */
-static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-			   enum pmic_arb_channel ch_type)
+static int pmic_arb_offset_v7(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
+			      enum pmic_arb_channel ch_type)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	u16 apid;
 	int rc;
 	u32 offset = 0;
 	u16 ppid = (sid << 8) | (addr >> 8);
 
-	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
+	rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid);
 	if (rc < 0)
 		return rc;
 
@@ -1364,8 +1405,8 @@ static int pmic_arb_offset_v7(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 		offset = 0x8000 * pmic_arb->ee + 0x20 * apid;
 		break;
 	case PMIC_ARB_CHANNEL_RW:
-		if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) {
-			dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
+		if (bus->apid_data[apid].write_ee != pmic_arb->ee) {
+			dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n",
 				sid, addr);
 			return -EPERM;
 		}
@@ -1387,104 +1428,110 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x20 * m + 0x4 * n;
+	return bus->intr + 0x20 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x100000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x200000 + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x10000 * m + 0x4 * n;
+	return bus->intr + 0x10000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+pmic_arb_owner_acc_status_v7(struct spmi_pmic_arb_bus *bus, u8 m, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * m + 0x4 * n;
+	return bus->intr + 0x1000 * m + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x200 + 0x4 * n;
+	return bus->intr + 0x200 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x1000 * n;
+	return bus->intr + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_acc_enable_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_acc_enable_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x100 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x600 + 0x4 * n;
+	return bus->intr + 0x600 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x4 + 0x1000 * n;
+	return bus->intr + 0x4 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_status_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_status_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x104 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v1(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0xA00 + 0x4 * n;
+	return bus->intr + 0xA00 + 0x4 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->intr + 0x8 + 0x1000 * n;
+	return bus->intr + 0x8 + 0x1000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v5(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x10000 * n;
 }
 
 static void __iomem *
-pmic_arb_irq_clear_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_irq_clear_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
+	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
 	return pmic_arb->wr_base + 0x108 + 0x1000 * n;
 }
 
@@ -1504,9 +1551,9 @@ static u32 pmic_arb_apid_map_offset_v7(u16 n)
 }
 
 static void __iomem *
-pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->cnfg + 0x700 + 0x4 * n;
+	return bus->cnfg + 0x700 + 0x4 * n;
 }
 
 /*
@@ -1515,9 +1562,9 @@ pmic_arb_apid_owner_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
  * 0.
  */
 static void __iomem *
-pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
+pmic_arb_apid_owner_v7(struct spmi_pmic_arb_bus *bus, u16 n)
 {
-	return pmic_arb->cnfg + 0x4 * (n - pmic_arb->base_apid);
+	return  bus->cnfg + 0x4 * (n - bus->base_apid);
 }
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
@@ -1607,29 +1654,159 @@ static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
 	.translate = qpnpint_irq_domain_translate,
 };
 
+static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
+				  struct device_node *node,
+				  struct spmi_pmic_arb *pmic_arb)
+{
+	int bus_index = pmic_arb->buses_available;
+	struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[bus_index];
+	struct device *dev = &pdev->dev;
+	struct spmi_controller *ctrl;
+	void __iomem *intr;
+	void __iomem *cnfg;
+	int index, ret;
+	u32 irq;
+
+	ctrl = devm_spmi_controller_alloc(dev, sizeof(*ctrl));
+	if (IS_ERR(ctrl))
+		return PTR_ERR(ctrl);
+
+	ctrl->cmd = pmic_arb_cmd;
+	ctrl->read_cmd = pmic_arb_read_cmd;
+	ctrl->write_cmd = pmic_arb_write_cmd;
+
+	bus = spmi_controller_get_drvdata(ctrl);
+	bus->spmic = ctrl;
+
+	bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID,
+					 sizeof(*bus->ppid_to_apid),
+					 GFP_KERNEL);
+	if (!bus->ppid_to_apid)
+		return -ENOMEM;
+
+	bus->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs,
+				      sizeof(*bus->apid_data),
+				      GFP_KERNEL);
+	if (!bus->apid_data)
+		return -ENOMEM;
+
+	index = of_property_match_string(node, "reg-names", "cnfg");
+	if (index < 0) {
+		dev_err(dev, "cnfg reg region missing");
+		return -EINVAL;
+	}
+
+	cnfg = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(cnfg))
+		return PTR_ERR(cnfg);
+
+	index = of_property_match_string(node, "reg-names", "intr");
+	if (index < 0) {
+		dev_err(dev, "intr reg region missing");
+		return -EINVAL;
+	}
+
+	intr = devm_of_iomap(dev, node, index, NULL);
+	if (IS_ERR(intr))
+		return PTR_ERR(intr);
+
+	irq = of_irq_get_byname(node, "periph_irq");
+	if (irq < 0)
+		return irq;
+
+	bus->pmic_arb = pmic_arb;
+	bus->intr = intr;
+	bus->cnfg = cnfg;
+	bus->irq = irq;
+	bus->id = bus_index;
+
+	ret = pmic_arb->ver_ops->init_apid(bus, bus_index);
+	if (ret)
+		return ret;
+
+	dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index);
+
+	bus->domain = irq_domain_add_tree(dev->of_node,
+					  &pmic_arb_irq_domain_ops, bus);
+	if (!bus->domain) {
+		dev_err(&pdev->dev, "unable to create irq_domain\n");
+		return -ENOMEM;
+	}
+
+	irq_set_chained_handler_and_data(bus->irq,
+					 pmic_arb_chained_irq, bus);
+
+	bus->spmic->dev.of_node = node;
+	dev_set_name(&bus->spmic->dev, "spmi-%d", bus_index);
+
+	ret = devm_spmi_controller_add(dev, bus->spmic);
+	if (ret)
+		return ret;
+
+	pmic_arb->buses_available++;
+
+	return 0;
+}
+
+static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb,
+					struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct device_node *child;
+	int ret;
+
+	/* legacy mode doesn't provide child node for the bus */
+	if (of_device_is_compatible(node, "qcom,spmi-pmic-arb"))
+		return spmi_pmic_arb_bus_init(pdev, node, pmic_arb);
+
+	for_each_available_child_of_node(node, child) {
+		if (of_node_name_eq(child, "spmi")) {
+			ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb)
+{
+	int i;
+
+	for (i = 0; i < PMIC_ARB_MAX_BUSES; i++) {
+		struct spmi_pmic_arb_bus *bus = &pmic_arb->buses[i];
+
+		irq_set_chained_handler_and_data(bus->irq,
+						 NULL, NULL);
+		irq_domain_remove(bus->domain);
+	}
+}
+
 static int spmi_pmic_arb_probe(struct platform_device *pdev)
 {
 	struct spmi_pmic_arb *pmic_arb;
-	struct spmi_controller *ctrl;
+	struct device *dev = &pdev->dev;
 	struct resource *res;
 	void __iomem *core;
 	u32 channel, ee, hw_ver;
 	int err;
 
-	ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*pmic_arb));
-	if (IS_ERR(ctrl))
-		return PTR_ERR(ctrl);
-
-	pmic_arb = spmi_controller_get_drvdata(ctrl);
-	pmic_arb->spmic = ctrl;
+	pmic_arb = devm_kzalloc(dev, sizeof(*pmic_arb), GFP_KERNEL);
+	if (!pmic_arb)
+		return -ENOMEM;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
-	core = devm_ioremap(&ctrl->dev, res->start, resource_size(res));
+	core = devm_ioremap(dev, res->start, resource_size(res));
 	if (IS_ERR(core))
 		return PTR_ERR(core);
 
 	pmic_arb->core_size = resource_size(res);
 
+	platform_set_drvdata(pdev, pmic_arb);
+	raw_spin_lock_init(&pmic_arb->lock);
+
 	hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
 
 	if (hw_ver < PMIC_ARB_VERSION_V2_MIN)
@@ -1643,30 +1820,12 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	else
 		pmic_arb->ver_ops = &pmic_arb_v7;
 
-	dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
-		 pmic_arb->ver_ops->ver_str, hw_ver);
-
 	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
 	if (err)
 		return err;
 
-	err = pmic_arb->ver_ops->init_apid(pmic_arb, 0);
-	if (err)
-		return err;
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
-	pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->intr))
-		return PTR_ERR(pmic_arb->intr);
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
-	pmic_arb->cnfg = devm_ioremap_resource(&ctrl->dev, res);
-	if (IS_ERR(pmic_arb->cnfg))
-		return PTR_ERR(pmic_arb->cnfg);
-
-	pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq");
-	if (pmic_arb->irq < 0)
-		return pmic_arb->irq;
+	dev_info(dev, "PMIC arbiter version %s (0x%x)\n",
+		 pmic_arb->ver_ops->ver_str, hw_ver);
 
 	err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
 	if (err) {
@@ -1695,46 +1854,19 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 	pmic_arb->ee = ee;
 
-	platform_set_drvdata(pdev, ctrl);
-	raw_spin_lock_init(&pmic_arb->lock);
-
-	ctrl->cmd = pmic_arb_cmd;
-	ctrl->read_cmd = pmic_arb_read_cmd;
-	ctrl->write_cmd = pmic_arb_write_cmd;
-
-	dev_dbg(&pdev->dev, "adding irq domain\n");
-	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
-					 &pmic_arb_irq_domain_ops, pmic_arb);
-	if (!pmic_arb->domain) {
-		dev_err(&pdev->dev, "unable to create irq_domain\n");
-		return -ENOMEM;
-	}
-
-	irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq,
-					pmic_arb);
-	err = spmi_controller_add(ctrl);
-	if (err)
-		goto err_domain_remove;
-
-	return 0;
-
-err_domain_remove:
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
-	return err;
+	return spmi_pmic_arb_register_buses(pmic_arb, pdev);
 }
 
 static void spmi_pmic_arb_remove(struct platform_device *pdev)
 {
-	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
-	spmi_controller_remove(ctrl);
-	irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
-	irq_domain_remove(pmic_arb->domain);
+	struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
+
+	spmi_pmic_arb_deregister_buses(pmic_arb);
 }
 
 static const struct of_device_id spmi_pmic_arb_match_table[] = {
 	{ .compatible = "qcom,spmi-pmic-arb", },
+	{ .compatible = "qcom,x1e80100-spmi-pmic-arb", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);

-- 
2.34.1



From rohan.g.thomas at intel.com  Thu Feb 22 05:52:22 2024
From: rohan.g.thomas at intel.com (Rohan G Thomas)
Date: Thu, 22 Feb 2024 21:52:22 +0800
Subject: [PATCH net] net: stmmac: Fix EST offset for dwmac 5.10
In-Reply-To: <20240220-stmmac_est-v1-1-c41f9ae2e7b7@linutronix.de>
References: <20240220-stmmac_est-v1-1-c41f9ae2e7b7@linutronix.de>
Message-ID: <20240222135222.7332-1-rohan.g.thomas@intel.com>

Hi Kurt,

On Tue, Feb 20, 2024 at 09:22:46AM +0100, Kurt Kanzenbach wrote:
> Fix EST offset for dwmac 5.10.
> 
> Currently configuring Qbv doesn't work as expected. The schedule is
> configured, but never confirmed:
> 
> |[  128.250219] imx-dwmac 428a0000.ethernet eth1: configured EST
> 
> The reason seems to be the refactoring of the EST code which set the wrong
> EST offset for the dwmac 5.10. After fixing this it works as before:
> 
> |[  106.359577] imx-dwmac 428a0000.ethernet eth1: configured EST [
> |128.430715] imx-dwmac 428a0000.ethernet eth1: EST: SWOL has been
> |switched
> 
> Tested on imx93.
> 
> Fixes: c3f3b97238f6 ("net: stmmac: Refactor EST implementation")
> Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
> ---

Thanks for fixing this. Sorry for the typo.

Best Regards,
Rohan



From brgl at bgdev.pl  Thu Feb 22 05:54:23 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 22 Feb 2024 14:54:23 +0100
Subject: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
In-Reply-To: <CAMRc=McmfufqqEvouRCjY1ukVB_ie1r5QEocqRUK0VBheEq5Hg@mail.gmail.com>
References: <20240205182810.58382-1-brgl@bgdev.pl> <20240205182810.58382-3-brgl@bgdev.pl>
 <tnylagkmj36lve2ub5voumtkqjdy6j3hr6yyk4mqkaabvc3gdv@voaiu2oqi73o> <CAMRc=McmfufqqEvouRCjY1ukVB_ie1r5QEocqRUK0VBheEq5Hg@mail.gmail.com>
Message-ID: <CAMRc=Mc_iwMzKznfUknm+RwS3jN_GimpirdTDVCPtnYYS_1PNg@mail.gmail.com>

On Wed, Feb 21, 2024 at 7:39?PM Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> On Sun, Feb 18, 2024 at 4:25?AM Bjorn Andersson <andersson at kernel.org> wrote:
> >
> > On Mon, Feb 05, 2024 at 07:28:00PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > >
> > > Select the TrustZone memory allocator in Kconfig and create a pool of
> > > memory shareable with the TrustZone when probing the SCM driver.
> > >
> > > This will allow a gradual conversion of all relevant SCM calls to using
> > > the dedicated allocator.
> > >
> > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > > Reviewed-by: Andrew Halaney <ahalaney at redhat.com>
> > > Tested-by: Andrew Halaney <ahalaney at redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> > > Tested-by: Deepti Jaggi <quic_djaggi at quicinc.com> #sa8775p-ride
> > > Reviewed-by: Elliot Berman <quic_eberman at quicinc.com>
> > > ---
> > >  drivers/firmware/qcom/Kconfig    |  1 +
> > >  drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
> > >  2 files changed, 17 insertions(+)
> > >
> > > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > > index f18686edf415..d24d83223867 100644
> > > --- a/drivers/firmware/qcom/Kconfig
> > > +++ b/drivers/firmware/qcom/Kconfig
> > > @@ -7,6 +7,7 @@
> > >  menu "Qualcomm firmware drivers"
> > >
> > >  config QCOM_SCM
> > > +     select QCOM_TZMEM
> > >       tristate
> > >
> > >  config QCOM_TZMEM
> > > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > > index 520de9b5633a..0d4c028be0c1 100644
> > > --- a/drivers/firmware/qcom/qcom_scm.c
> > > +++ b/drivers/firmware/qcom/qcom_scm.c
> > > @@ -8,8 +8,10 @@
> > >  #include <linux/completion.h>
> > >  #include <linux/cpumask.h>
> > >  #include <linux/dma-mapping.h>
> > > +#include <linux/err.h>
> > >  #include <linux/export.h>
> > >  #include <linux/firmware/qcom/qcom_scm.h>
> > > +#include <linux/firmware/qcom/qcom_tzmem.h>
> > >  #include <linux/init.h>
> > >  #include <linux/interconnect.h>
> > >  #include <linux/interrupt.h>
> > > @@ -20,9 +22,11 @@
> > >  #include <linux/of_platform.h>
> > >  #include <linux/platform_device.h>
> > >  #include <linux/reset-controller.h>
> > > +#include <linux/sizes.h>
> > >  #include <linux/types.h>
> > >
> > >  #include "qcom_scm.h"
> > > +#include "qcom_tzmem.h"
> > >
> > >  static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
> > >  module_param(download_mode, bool, 0);
> > > @@ -41,6 +45,8 @@ struct qcom_scm {
> > >       int scm_vote_count;
> > >
> > >       u64 dload_mode_addr;
> > > +
> > > +     struct qcom_tzmem_pool *mempool;
> > >  };
> > >
> > >  struct qcom_scm_current_perm_info {
> > > @@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
> > >       if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
> > >               qcom_scm_disable_sdi();
> > >
> > > +     ret = qcom_tzmem_enable(__scm->dev);
> > > +     if (ret)
> > > +             return dev_err_probe(__scm->dev, ret,
> > > +                                  "Failed to enable the TrustZone memory allocator\n");
> > > +
> > > +     __scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);
> >
> > As we're not moving from the callers freely allocating what they need,
> > to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> > so that we have something to fall back on when someone runs out of this
> > space, or wonders "why not 128kb?".
> >
>
> If you worry about these pools being taken out of the total memory and
> prefer to have a way to avoid it, I was thinking about another
> build-time mode for the allocator - one where there's no pool but it
> just allocates chunks using dma_alloc_coherent() like before and pool
> size is ignored. Does it sound good?
>

Or we could even have an argument for the initial size of the pool and
then once it's exhausted, we'd add a new chunk (maybe twice the size?)
and so on.

Bart

> Bart
>
> > Regards,
> > Bjorn
> >
> > > +     if (IS_ERR(__scm->mempool))
> > > +             return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
> > > +                                  "Failed to create the SCM memory pool\n");
> > > +
> > >       /*
> > >        * Initialize the QSEECOM interface.
> > >        *
> > > --
> > > 2.40.1
> > >


From pierre.gondois at arm.com  Thu Feb 22 05:56:58 2024
From: pierre.gondois at arm.com (Pierre Gondois)
Date: Thu, 22 Feb 2024 14:56:58 +0100
Subject: [PATCH 0/3]  scmi-cpufreq: Set transition_delay_us
Message-ID: <20240222135702.2005635-1-pierre.gondois@arm.com>

policy's fields definitions:
`transition_delay_us`:
The minimum amount of time between two consecutive freq. requests
for one policy.
`transition_latency`:
Delta between freq. change request and effective freq. change on
the hardware.

cpufreq_policy_transition_delay_us() uses the `transition_delay_us`
value if available. Otherwise a value is induced from the policy's
`transition_latency`.

The scmi-cpufreq driver doesn't populate the `transition_delay_us`.
Values matching the definition are available through the SCMI
specification.
Add support to fetch these values and use them in the scmi-cpufreq
driver.

Pierre Gondois (3):
  firmware: arm_scmi: Populate perf commands rate_limit
  firmware: arm_scmi: Populate fast channel rate_limit
  cpufreq: scmi: Set transition_delay_us

 drivers/cpufreq/scmi-cpufreq.c        | 26 +++++++++++++
 drivers/firmware/arm_scmi/driver.c    |  5 ++-
 drivers/firmware/arm_scmi/perf.c      | 53 +++++++++++++++++++++++++--
 drivers/firmware/arm_scmi/powercap.c  | 12 ++++--
 drivers/firmware/arm_scmi/protocols.h |  4 +-
 include/linux/scmi_protocol.h         |  8 ++++
 6 files changed, 98 insertions(+), 10 deletions(-)

-- 
2.25.1



From pierre.gondois at arm.com  Thu Feb 22 05:56:59 2024
From: pierre.gondois at arm.com (Pierre Gondois)
Date: Thu, 22 Feb 2024 14:56:59 +0100
Subject: [PATCH 1/3] firmware: arm_scmi: Populate perf commands rate_limit
In-Reply-To: <20240222135702.2005635-1-pierre.gondois@arm.com>
References: <20240222135702.2005635-1-pierre.gondois@arm.com>
Message-ID: <20240222135702.2005635-2-pierre.gondois@arm.com>

Arm SCMI spec. v3.2, s4.5.3.4 PERFORMANCE_DOMAIN_ATTRIBUTES
defines a per-domain rate_limit for performance requests:
"""
Rate Limit in microseconds, indicating the minimum time
required between successive requests. A value of 0
indicates that this field is not supported by the
platform. This field does not apply to FastChannels.
""""
The field is first defined in SCMI v1.0.

Add support to fetch this value and advertise it through
a rate_limit_get() callback.

Signed-off-by: Pierre Gondois <pierre.gondois at arm.com>
---
 drivers/firmware/arm_scmi/perf.c | 21 +++++++++++++++++++++
 include/linux/scmi_protocol.h    |  4 ++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index 211e8e0aef2c..37c80376bd0a 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -153,6 +153,7 @@ struct perf_dom_info {
 	bool perf_fastchannels;
 	bool level_indexing_mode;
 	u32 opp_count;
+	u32 rate_limit_us;
 	u32 sustained_freq_khz;
 	u32 sustained_perf_level;
 	unsigned long mult_factor;
@@ -266,6 +267,8 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
 		if (PROTOCOL_REV_MAJOR(version) >= 0x4)
 			dom_info->level_indexing_mode =
 				SUPPORTS_LEVEL_INDEXING(flags);
+		dom_info->rate_limit_us = le32_to_cpu(attr->rate_limit_us) &
+						GENMASK(19, 0);
 		dom_info->sustained_freq_khz =
 					le32_to_cpu(attr->sustained_freq_khz);
 		dom_info->sustained_perf_level =
@@ -855,6 +858,23 @@ scmi_dvfs_transition_latency_get(const struct scmi_protocol_handle *ph,
 	return dom->opp[dom->opp_count - 1].trans_latency_us * 1000;
 }
 
+static int
+scmi_dvfs_rate_limit_get(const struct scmi_protocol_handle *ph,
+			 u32 domain, u32 *rate_limit)
+{
+	struct perf_dom_info *dom;
+
+	if (!rate_limit)
+		return -EINVAL;
+
+	dom = scmi_perf_domain_lookup(ph, domain);
+	if (IS_ERR(dom))
+		return PTR_ERR(dom);
+
+	*rate_limit = dom->rate_limit_us;
+	return 0;
+}
+
 static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 domain,
 			      unsigned long freq, bool poll)
 {
@@ -970,6 +990,7 @@ static const struct scmi_perf_proto_ops perf_proto_ops = {
 	.level_set = scmi_perf_level_set,
 	.level_get = scmi_perf_level_get,
 	.transition_latency_get = scmi_dvfs_transition_latency_get,
+	.rate_limit_get = scmi_dvfs_rate_limit_get,
 	.device_opps_add = scmi_dvfs_device_opps_add,
 	.freq_set = scmi_dvfs_freq_set,
 	.freq_get = scmi_dvfs_freq_get,
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index f2f05fb42d28..acd956ffcb84 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -128,6 +128,8 @@ struct scmi_perf_domain_info {
  * @level_set: sets the performance level of a domain
  * @level_get: gets the performance level of a domain
  * @transition_latency_get: gets the DVFS transition latency for a given device
+ * @rate_limit_get: gets the minimum time (us) required between successive
+ *	requests
  * @device_opps_add: adds all the OPPs for a given device
  * @freq_set: sets the frequency for a given device using sustained frequency
  *	to sustained performance level mapping
@@ -154,6 +156,8 @@ struct scmi_perf_proto_ops {
 			 u32 *level, bool poll);
 	int (*transition_latency_get)(const struct scmi_protocol_handle *ph,
 				      u32 domain);
+	int (*rate_limit_get)(const struct scmi_protocol_handle *ph,
+			      u32 domain, u32 *rate_limit);
 	int (*device_opps_add)(const struct scmi_protocol_handle *ph,
 			       struct device *dev, u32 domain);
 	int (*freq_set)(const struct scmi_protocol_handle *ph, u32 domain,
-- 
2.25.1



From pierre.gondois at arm.com  Thu Feb 22 05:57:00 2024
From: pierre.gondois at arm.com (Pierre Gondois)
Date: Thu, 22 Feb 2024 14:57:00 +0100
Subject: [PATCH 2/3] firmware: arm_scmi: Populate fast channel rate_limit
In-Reply-To: <20240222135702.2005635-1-pierre.gondois@arm.com>
References: <20240222135702.2005635-1-pierre.gondois@arm.com>
Message-ID: <20240222135702.2005635-3-pierre.gondois@arm.com>

Arm SCMI spec. v3.2, s4.5.3.12 PERFORMANCE_DESCRIBE_FASTCHANNEL
defines a per-domain rate_limit for performance requests:
"""
Rate Limit in microseconds, indicating the minimum time
required between successive requests. A value of 0
indicates that this field is not applicable or supported
on the platform.
""""
The field is first defined in SCMI v2.0.

Add support to fetch this value and advertise it through
a fast_switch_rate_limit() callback.

Signed-off-by: Pierre Gondois <pierre.gondois at arm.com>
---
 drivers/firmware/arm_scmi/driver.c    |  5 ++++-
 drivers/firmware/arm_scmi/perf.c      | 32 +++++++++++++++++++++++----
 drivers/firmware/arm_scmi/powercap.c  | 12 ++++++----
 drivers/firmware/arm_scmi/protocols.h |  4 +++-
 include/linux/scmi_protocol.h         |  4 ++++
 5 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 3ea64b22cf0d..1d38ecfafc59 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1617,7 +1617,7 @@ static void
 scmi_common_fastchannel_init(const struct scmi_protocol_handle *ph,
 			     u8 describe_id, u32 message_id, u32 valid_size,
 			     u32 domain, void __iomem **p_addr,
-			     struct scmi_fc_db_info **p_db)
+			     struct scmi_fc_db_info **p_db, u32 *rate_limit)
 {
 	int ret;
 	u32 flags;
@@ -1661,6 +1661,9 @@ scmi_common_fastchannel_init(const struct scmi_protocol_handle *ph,
 		goto err_xfer;
 	}
 
+	if (rate_limit)
+		*rate_limit = le32_to_cpu(resp->rate_limit) & GENMASK(19, 0);
+
 	phys_addr = le32_to_cpu(resp->chan_addr_low);
 	phys_addr |= (u64)le32_to_cpu(resp->chan_addr_high) << 32;
 	addr = devm_ioremap(ph->dev, phys_addr, size);
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index 37c80376bd0a..fbcbd703198a 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -789,23 +789,27 @@ static void scmi_perf_domain_init_fc(const struct scmi_protocol_handle *ph,
 
 	ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
 				   PERF_LEVEL_GET, 4, dom->id,
-				   &fc[PERF_FC_LEVEL].get_addr, NULL);
+				   &fc[PERF_FC_LEVEL].get_addr, NULL,
+				   &fc[PERF_FC_LEVEL].rate_limit);
 
 	ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
 				   PERF_LIMITS_GET, 8, dom->id,
-				   &fc[PERF_FC_LIMIT].get_addr, NULL);
+				   &fc[PERF_FC_LIMIT].get_addr, NULL,
+				   &fc[PERF_FC_LIMIT].rate_limit);
 
 	if (dom->info.set_perf)
 		ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
 					   PERF_LEVEL_SET, 4, dom->id,
 					   &fc[PERF_FC_LEVEL].set_addr,
-					   &fc[PERF_FC_LEVEL].set_db);
+					   &fc[PERF_FC_LEVEL].set_db,
+					   &fc[PERF_FC_LEVEL].rate_limit);
 
 	if (dom->set_limits)
 		ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
 					   PERF_LIMITS_SET, 8, dom->id,
 					   &fc[PERF_FC_LIMIT].set_addr,
-					   &fc[PERF_FC_LIMIT].set_db);
+					   &fc[PERF_FC_LIMIT].set_db,
+					   &fc[PERF_FC_LIMIT].rate_limit);
 
 	dom->fc_info = fc;
 }
@@ -974,6 +978,25 @@ static bool scmi_fast_switch_possible(const struct scmi_protocol_handle *ph,
 	return dom->fc_info && dom->fc_info[PERF_FC_LEVEL].set_addr;
 }
 
+static int scmi_fast_switch_rate_limit(const struct scmi_protocol_handle *ph,
+				       u32 domain, u32 *rate_limit)
+{
+	struct perf_dom_info *dom;
+
+	if (!rate_limit)
+		return -EINVAL;
+
+	dom = scmi_perf_domain_lookup(ph, domain);
+	if (IS_ERR(dom))
+		return PTR_ERR(dom);
+
+	if (!dom->fc_info)
+		return -EINVAL;
+
+	*rate_limit = dom->fc_info[PERF_FC_LEVEL].rate_limit;
+	return 0;
+}
+
 static enum scmi_power_scale
 scmi_power_scale_get(const struct scmi_protocol_handle *ph)
 {
@@ -996,6 +1019,7 @@ static const struct scmi_perf_proto_ops perf_proto_ops = {
 	.freq_get = scmi_dvfs_freq_get,
 	.est_power_get = scmi_dvfs_est_power_get,
 	.fast_switch_possible = scmi_fast_switch_possible,
+	.fast_switch_rate_limit = scmi_fast_switch_rate_limit,
 	.power_scale_get = scmi_power_scale_get,
 };
 
diff --git a/drivers/firmware/arm_scmi/powercap.c b/drivers/firmware/arm_scmi/powercap.c
index a4c6cd4716fe..604184c044ff 100644
--- a/drivers/firmware/arm_scmi/powercap.c
+++ b/drivers/firmware/arm_scmi/powercap.c
@@ -703,20 +703,24 @@ static void scmi_powercap_domain_init_fc(const struct scmi_protocol_handle *ph,
 	ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
 				   POWERCAP_CAP_SET, 4, domain,
 				   &fc[POWERCAP_FC_CAP].set_addr,
-				   &fc[POWERCAP_FC_CAP].set_db);
+				   &fc[POWERCAP_FC_CAP].set_db,
+				   &fc[POWERCAP_FC_CAP].rate_limit);
 
 	ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
 				   POWERCAP_CAP_GET, 4, domain,
-				   &fc[POWERCAP_FC_CAP].get_addr, NULL);
+				   &fc[POWERCAP_FC_CAP].get_addr, NULL,
+				   &fc[POWERCAP_FC_CAP].rate_limit);
 
 	ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
 				   POWERCAP_PAI_SET, 4, domain,
 				   &fc[POWERCAP_FC_PAI].set_addr,
-				   &fc[POWERCAP_FC_PAI].set_db);
+				   &fc[POWERCAP_FC_PAI].set_db,
+				   &fc[POWERCAP_FC_PAI].rate_limit);
 
 	ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
 				   POWERCAP_PAI_GET, 4, domain,
-				   &fc[POWERCAP_FC_PAI].get_addr, NULL);
+				   &fc[POWERCAP_FC_PAI].get_addr, NULL,
+				   &fc[POWERCAP_PAI_GET].rate_limit);
 
 	*p_fc = fc;
 }
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index e683c26f24eb..8b5d9ce4a33a 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -234,6 +234,7 @@ struct scmi_fc_info {
 	void __iomem *set_addr;
 	void __iomem *get_addr;
 	struct scmi_fc_db_info *set_db;
+	u32 rate_limit;
 };
 
 /**
@@ -268,7 +269,8 @@ struct scmi_proto_helpers_ops {
 				 u8 describe_id, u32 message_id,
 				 u32 valid_size, u32 domain,
 				 void __iomem **p_addr,
-				 struct scmi_fc_db_info **p_db);
+				 struct scmi_fc_db_info **p_db,
+				 u32 *rate_limit);
 	void (*fastchannel_db_ring)(struct scmi_fc_db_info *db);
 };
 
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index acd956ffcb84..fafedb3b6604 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -139,6 +139,8 @@ struct scmi_perf_domain_info {
  *	at a given frequency
  * @fast_switch_possible: indicates if fast DVFS switching is possible or not
  *	for a given device
+ * @fast_switch_rate_limit: gets the minimum time (us) required between
+ *	successive fast_switching requests
  * @power_scale_mw_get: indicates if the power values provided are in milliWatts
  *	or in some other (abstract) scale
  */
@@ -168,6 +170,8 @@ struct scmi_perf_proto_ops {
 			     unsigned long *rate, unsigned long *power);
 	bool (*fast_switch_possible)(const struct scmi_protocol_handle *ph,
 				     u32 domain);
+	int (*fast_switch_rate_limit)(const struct scmi_protocol_handle *ph,
+				      u32 domain, u32 *rate_limit);
 	enum scmi_power_scale (*power_scale_get)(const struct scmi_protocol_handle *ph);
 };
 
-- 
2.25.1



From pierre.gondois at arm.com  Thu Feb 22 05:57:01 2024
From: pierre.gondois at arm.com (Pierre Gondois)
Date: Thu, 22 Feb 2024 14:57:01 +0100
Subject: [PATCH 3/3] cpufreq: scmi: Set transition_delay_us
In-Reply-To: <20240222135702.2005635-1-pierre.gondois@arm.com>
References: <20240222135702.2005635-1-pierre.gondois@arm.com>
Message-ID: <20240222135702.2005635-4-pierre.gondois@arm.com>

Make use of the newly added callbacks:
- rate_limit_get()
- fast_switch_rate_limit()
to populate policies's `transition_delay_us`, defined as the
'Preferred average time interval between consecutive
invocations of the driver to set the frequency for this policy.'

Signed-off-by: Pierre Gondois <pierre.gondois at arm.com>
---
 drivers/cpufreq/scmi-cpufreq.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index 4ee23f4ebf4a..0b483bd0d3ca 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -144,6 +144,29 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
 	return 0;
 }
 
+static int
+scmi_get_rate_limit(u32 domain, bool has_fast_switch)
+{
+	int ret, rate_limit;
+
+	if (has_fast_switch) {
+		/*
+		 * Fast channels are used whenever available,
+		 * so use their rate_limit value if populated.
+		 */
+		ret = perf_ops->fast_switch_rate_limit(ph, domain,
+						       &rate_limit);
+		if (!ret && rate_limit)
+			return rate_limit;
+	}
+
+	ret = perf_ops->rate_limit_get(ph, domain, &rate_limit);
+	if (ret)
+		return 0;
+
+	return rate_limit;
+}
+
 static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 {
 	int ret, nr_opp, domain;
@@ -250,6 +273,9 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 	policy->fast_switch_possible =
 		perf_ops->fast_switch_possible(ph, domain);
 
+	policy->transition_delay_us =
+		scmi_get_rate_limit(domain, policy->fast_switch_possible);
+
 	return 0;
 
 out_free_opp:
-- 
2.25.1



From broonie at kernel.org  Thu Feb 22 05:57:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 22 Feb 2024 13:57:53 +0000
Subject: [musl] Re: [PATCH v8 00/38] arm64/gcs: Provide support for GCS
 in userspace
In-Reply-To: <e3a432c0fa9f5fe837e9d2fc7b36304709a34428.camel@intel.com>
References: <20240221012736.GQ4163@brightrain.aerifal.cx>
 <d18f060d-37ac-48b1-9f67-a5c5db79b34e@sirena.org.uk>
 <20240221145800.GR4163@brightrain.aerifal.cx>
 <4a3809e8-61b2-4341-a868-292ba6e64e8a@sirena.org.uk>
 <20240221175717.GS4163@brightrain.aerifal.cx>
 <f4a54297767eb098d903404cbe8860d655d79bed.camel@intel.com>
 <20240221183055.GT4163@brightrain.aerifal.cx>
 <c3085fbe10193dfe59b25bc7da776e60779b0e8c.camel@intel.com>
 <20240221190639.GU4163@brightrain.aerifal.cx>
 <e3a432c0fa9f5fe837e9d2fc7b36304709a34428.camel@intel.com>
Message-ID: <c2426b69-5411-45fe-851a-219e1f4f9d3b@sirena.org.uk>

On Wed, Feb 21, 2024 at 07:22:21PM +0000, Edgecombe, Rick P wrote:
> On Wed, 2024-02-21 at 14:06 -0500, dalias at libc.org wrote:

> > It's fine to turn RDSSP into an actual emulated read of the SSP, or
> > at
> > least an emulated load of zero so that uninitialized data is not left
> > in the target register.

> We can't intercept RDSSP, but it becomes a NOP by default. (disclaimer
> x86-only knowledge).

For arm64 we have a separate control GCSCRE0_EL1.nTR for access to
GCSPR_EL0 (our SSP equivalent) we can use.

> > I have not looked at all the instructions that become #UD but I
> > suspect they all have reasonable trivial ways to implement a
> > "disabled" version of them that userspace can act upon reasonably.

> This would have to be thought through functionally and performance
> wise. I'm not opposed if can come up with a fully fleshed out plan. How
> serious are you in pursuing musl support, if we had something like
> this?

Same here, we have to be careful since it's defining ABI in a way that
we don't normally provide ABI but if there's a clear case for doing it
then...
-------------- 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/20240222/cf163f24/attachment.sig>

From festevam at gmail.com  Thu Feb 22 06:01:27 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 22 Feb 2024 11:01:27 -0300
Subject: [PATCH] ARM: dts: imx28-evk: Use 'eeprom' as the node name
Message-ID: <20240222140127.967528-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

Per at24.yaml, the node name should be 'eeprom'.

Change it accordingly to fix the following schema warning:

imx28-evk.dtb: at24 at 51: $nodename:0: 'at24 at 51' does not match '^eeprom@[0-9a-f]{1,2}$'
	from schema $id: http://devicetree.org/schemas/eeprom/at24.yaml#

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
 arch/arm/boot/dts/nxp/mxs/imx28-evk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts b/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts
index 9ebb7371e235..330d3aff6b6c 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts
@@ -198,7 +198,7 @@ sgtl5000: codec at a {
 		clocks = <&saif0>;
 	};
 
-	at24 at 51 {
+	eeprom at 51 {
 		compatible = "atmel,24c32";
 		pagesize = <32>;
 		reg = <0x51>;
-- 
2.34.1



From liuyongqiang13 at huawei.com  Thu Feb 22 06:01:47 2024
From: liuyongqiang13 at huawei.com (Yongqiang Liu)
Date: Thu, 22 Feb 2024 22:01:47 +0800
Subject: [PATCH] arm: flush: check if the folio is reserved for IMO addresses
Message-ID: <20240222140147.1880357-1-liuyongqiang13@huawei.com>

Since commit a4d5613c4dc6 ("arm: extend pfn_valid to take into account
freed memory map alignment") changes the semantics of pfn_valid() to check
presence of the memory map for a PFN. A valid page for an address which
is reserved but not mapped by the kernel[1].In Some uio case we will get
a crash on a system with the following memory layout:

 node   0: [mem 0x00000000c0a00000-0x00000000cc8fffff]
 node   0: [mem 0x00000000d0000000-0x00000000da1fffff]
 the uio layout is?0xc0900000, 0x100000

the crash backtrace like:

  Unable to handle kernel paging request at virtual address bff00000
  [...]
  CPU: 1 PID: 465 Comm: startapp.bin Tainted: G           O      5.10.0 #1
  Hardware name: Generic DT based system
  PC is at b15_flush_kern_dcache_area+0x24/0x3c
  LR is at __sync_icache_dcache+0x6c/0x98
  [...]
   (b15_flush_kern_dcache_area) from (__sync_icache_dcache+0x6c/0x98)
   (__sync_icache_dcache) from (set_pte_at+0x28/0x54)
   (set_pte_at) from (remap_pfn_range+0x1a0/0x274)
   (remap_pfn_range) from (uio_mmap+0x184/0x1b8 [uio])
   (uio_mmap [uio]) from (__mmap_region+0x264/0x5f4)
   (__mmap_region) from (__do_mmap_mm+0x3ec/0x440)
   (__do_mmap_mm) from (do_mmap+0x50/0x58)
   (do_mmap) from (vm_mmap_pgoff+0xfc/0x188)
   (vm_mmap_pgoff) from (ksys_mmap_pgoff+0xac/0xc4)
   (ksys_mmap_pgoff) from (ret_fast_syscall+0x0/0x5c)
  Code: e0801001 e2423001 e1c00003 f57ff04f (ee070f3e)
  ---[ end trace 09cf0734c3805d52 ]---
  Kernel panic - not syncing: Fatal exception

So check if PG_reserved was set to solve this issue.

[1]: https://lore.kernel.org/lkml/Zbtdue57RO0QScJM at linux.ibm.com/

Fixes: a4d5613c4dc6 ("arm: extend pfn_valid to take into account freed memory map alignment")
Suggested-by: Mike Rapoport <rppt at linux.ibm.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13 at huawei.com>
---
 arch/arm/mm/flush.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index d19d140a10c7..f2b99223a0ab 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -15,6 +15,7 @@
 #include <asm/smp_plat.h>
 #include <asm/tlbflush.h>
 #include <linux/hugetlb.h>
+#include <linux/memblock.h>
 
 #include "mm.h"
 
@@ -296,6 +297,9 @@ void __sync_icache_dcache(pte_t pteval)
 		return;
 
 	folio = page_folio(pfn_to_page(pfn));
+	if (test_bit(PG_reserved, &folio->flags))
+		return;
+
 	if (cache_is_vipt_aliasing())
 		mapping = folio_flush_mapping(folio);
 	else
-- 
2.25.1



From willy at infradead.org  Thu Feb 22 06:05:32 2024
From: willy at infradead.org (Matthew Wilcox)
Date: Thu, 22 Feb 2024 14:05:32 +0000
Subject: [PATCH] arm: flush: check if the folio is reserved for IMO
 addresses
In-Reply-To: <20240222140147.1880357-1-liuyongqiang13@huawei.com>
References: <20240222140147.1880357-1-liuyongqiang13@huawei.com>
Message-ID: <ZddUrO7i5KZn57FY@casper.infradead.org>

On Thu, Feb 22, 2024 at 10:01:47PM +0800, Yongqiang Liu wrote:
> @@ -296,6 +297,9 @@ void __sync_icache_dcache(pte_t pteval)
>  		return;
>  
>  	folio = page_folio(pfn_to_page(pfn));
> +	if (test_bit(PG_reserved, &folio->flags))
> +		return;

Why are you using PG_foo directly instead of the helpers?

	if (folio_test_reserved(folio))


From bjorn at kernel.org  Thu Feb 22 06:05:41 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Thu, 22 Feb 2024 15:05:41 +0100
Subject: [PATCH v14 13/18] irqchip/riscv-imsic: Add device MSI domain
 support for PCI devices
In-Reply-To: <CAAhSdy3DtDFnZKQLXXJ2OPPSv5s8bbGvm8Mmqhg_F2rPneQ3sw@mail.gmail.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
 <20240222094006.1030709-14-apatel@ventanamicro.com>
 <87msrstzck.fsf@all.your.base.are.belong.to.us>
 <CAAhSdy3DtDFnZKQLXXJ2OPPSv5s8bbGvm8Mmqhg_F2rPneQ3sw@mail.gmail.com>
Message-ID: <87edd4twzu.fsf@all.your.base.are.belong.to.us>

Anup Patel <anup at brainfault.org> writes:

> On Thu, Feb 22, 2024 at 6:44?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>>
>> Anup Patel <apatel at ventanamicro.com> writes:
>>
>> > The Linux PCI framework supports per-device MSI domains for PCI devices
>> > so extend the IMSIC driver to allow PCI per-device MSI domains.
>> >
>> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
>> > ---
>> >  drivers/irqchip/Kconfig                    |  7 +++++
>> >  drivers/irqchip/irq-riscv-imsic-platform.c | 35 ++++++++++++++++++++--
>> >  2 files changed, 40 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
>> > index 85f86e31c996..2fc0cb32341a 100644
>> > --- a/drivers/irqchip/Kconfig
>> > +++ b/drivers/irqchip/Kconfig
>> > @@ -553,6 +553,13 @@ config RISCV_IMSIC
>> >       select GENERIC_IRQ_MATRIX_ALLOCATOR
>> >       select GENERIC_MSI_IRQ
>> >
>> > +config RISCV_IMSIC_PCI
>> > +     bool
>> > +     depends on RISCV_IMSIC
>> > +     depends on PCI
>> > +     depends on PCI_MSI
>> > +     default RISCV_IMSIC
>> > +
>> >  config EXYNOS_IRQ_COMBINER
>> >       bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
>> >       depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
>> > diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
>> > index e2344fc08dca..90ddcdd0bba5 100644
>> > --- a/drivers/irqchip/irq-riscv-imsic-platform.c
>> > +++ b/drivers/irqchip/irq-riscv-imsic-platform.c
>> > @@ -14,6 +14,7 @@
>> >  #include <linux/irqdomain.h>
>> >  #include <linux/module.h>
>> >  #include <linux/msi.h>
>> > +#include <linux/pci.h>
>> >  #include <linux/platform_device.h>
>> >  #include <linux/spinlock.h>
>> >  #include <linux/smp.h>
>> > @@ -208,6 +209,28 @@ static const struct irq_domain_ops imsic_base_domain_ops = {
>> >  #endif
>> >  };
>> >
>> > +#ifdef CONFIG_RISCV_IMSIC_PCI
>> > +
>> > +static void imsic_pci_mask_irq(struct irq_data *d)
>> > +{
>> > +     pci_msi_mask_irq(d);
>> > +     irq_chip_mask_parent(d);
>> > +}
>> > +
>> > +static void imsic_pci_unmask_irq(struct irq_data *d)
>> > +{
>> > +     irq_chip_unmask_parent(d);
>> > +     pci_msi_unmask_irq(d);
>> > +}
>> > +
>> > +#define MATCH_PCI_MSI                BIT(DOMAIN_BUS_PCI_MSI)
>> > +
>> > +#else
>> > +
>> > +#define MATCH_PCI_MSI                0
>> > +
>> > +#endif
>> > +
>> >  static bool imsic_init_dev_msi_info(struct device *dev,
>> >                                   struct irq_domain *domain,
>> >                                   struct irq_domain *real_parent,
>> > @@ -231,6 +254,13 @@ static bool imsic_init_dev_msi_info(struct device *dev,
>> >
>> >       /* Is the target supported? */
>> >       switch (info->bus_token) {
>> > +#ifdef CONFIG_RISCV_IMSIC_PCI
>> > +     case DOMAIN_BUS_PCI_DEVICE_MSI:
>> > +     case DOMAIN_BUS_PCI_DEVICE_MSIX:
>> > +             info->chip->irq_mask = imsic_pci_mask_irq;
>> > +             info->chip->irq_unmask = imsic_pci_unmask_irq;
>>
>> irq_set_affinity()?
>
> It's already set by the switch-case above.

Ah, right -- the new .bus_select_token! Thank you!


From wangkefeng.wang at huawei.com  Thu Feb 22 06:06:04 2024
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Thu, 22 Feb 2024 22:06:04 +0800
Subject: [PATCH] arm: flush: check if the folio is reserved for IMO
 addresses
In-Reply-To: <20240222140147.1880357-1-liuyongqiang13@huawei.com>
References: <20240222140147.1880357-1-liuyongqiang13@huawei.com>
Message-ID: <f795228c-9795-4449-abcb-b7ff0cb486fb@huawei.com>



On 2024/2/22 22:01, Yongqiang Liu wrote:
> Since commit a4d5613c4dc6 ("arm: extend pfn_valid to take into account
> freed memory map alignment") changes the semantics of pfn_valid() to check
> presence of the memory map for a PFN. A valid page for an address which
> is reserved but not mapped by the kernel[1].In Some uio case we will get
> a crash on a system with the following memory layout:
> 
>   node   0: [mem 0x00000000c0a00000-0x00000000cc8fffff]
>   node   0: [mem 0x00000000d0000000-0x00000000da1fffff]
>   the uio layout is?0xc0900000, 0x100000
> 
> the crash backtrace like:
> 
>    Unable to handle kernel paging request at virtual address bff00000
>    [...]
>    CPU: 1 PID: 465 Comm: startapp.bin Tainted: G           O      5.10.0 #1
>    Hardware name: Generic DT based system
>    PC is at b15_flush_kern_dcache_area+0x24/0x3c
>    LR is at __sync_icache_dcache+0x6c/0x98
>    [...]
>     (b15_flush_kern_dcache_area) from (__sync_icache_dcache+0x6c/0x98)
>     (__sync_icache_dcache) from (set_pte_at+0x28/0x54)
>     (set_pte_at) from (remap_pfn_range+0x1a0/0x274)
>     (remap_pfn_range) from (uio_mmap+0x184/0x1b8 [uio])
>     (uio_mmap [uio]) from (__mmap_region+0x264/0x5f4)
>     (__mmap_region) from (__do_mmap_mm+0x3ec/0x440)
>     (__do_mmap_mm) from (do_mmap+0x50/0x58)
>     (do_mmap) from (vm_mmap_pgoff+0xfc/0x188)
>     (vm_mmap_pgoff) from (ksys_mmap_pgoff+0xac/0xc4)
>     (ksys_mmap_pgoff) from (ret_fast_syscall+0x0/0x5c)
>    Code: e0801001 e2423001 e1c00003 f57ff04f (ee070f3e)
>    ---[ end trace 09cf0734c3805d52 ]---
>    Kernel panic - not syncing: Fatal exception
> 
> So check if PG_reserved was set to solve this issue.
> 
> [1]: https://lore.kernel.org/lkml/Zbtdue57RO0QScJM at linux.ibm.com/
> 
> Fixes: a4d5613c4dc6 ("arm: extend pfn_valid to take into account freed memory map alignment")
> Suggested-by: Mike Rapoport <rppt at linux.ibm.com>
> Signed-off-by: Yongqiang Liu <liuyongqiang13 at huawei.com>
> ---
>   arch/arm/mm/flush.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
> index d19d140a10c7..f2b99223a0ab 100644
> --- a/arch/arm/mm/flush.c
> +++ b/arch/arm/mm/flush.c
> @@ -15,6 +15,7 @@
>   #include <asm/smp_plat.h>
>   #include <asm/tlbflush.h>
>   #include <linux/hugetlb.h>
> +#include <linux/memblock.h>
??????????
>   
>   #include "mm.h"
>   
> @@ -296,6 +297,9 @@ void __sync_icache_dcache(pte_t pteval)
>   		return;
>   
>   	folio = page_folio(pfn_to_page(pfn));
> +	if (test_bit(PG_reserved, &folio->flags))
> +		return;
> +
>   	if (cache_is_vipt_aliasing())
>   		mapping = folio_flush_mapping(folio);
>   	else


From bjorn at kernel.org  Thu Feb 22 06:15:24 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Thu, 22 Feb 2024 15:15:24 +0100
Subject: [PATCH v14 11/18] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <CAAhSdy3R9TCHG13vFk=sF0MvA60LtxOs9NbjSB7XBk+v1+XH4w@mail.gmail.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
 <20240222094006.1030709-12-apatel@ventanamicro.com>
 <87r0h4tzeq.fsf@all.your.base.are.belong.to.us>
 <CAAhSdy3R9TCHG13vFk=sF0MvA60LtxOs9NbjSB7XBk+v1+XH4w@mail.gmail.com>
Message-ID: <874je0twjn.fsf@all.your.base.are.belong.to.us>

Anup Patel <anup at brainfault.org> writes:

> On Thu, Feb 22, 2024 at 6:43?PM Bj?rn T?pel <bjorn at kernel.org> wrote:
>>
>> Anup Patel <apatel at ventanamicro.com> writes:
>>
>> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
>> > new file mode 100644
>> > index 000000000000..0c19ffb9ca3e
>> > --- /dev/null
>> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c
>> > @@ -0,0 +1,870 @@
>>
>> [...]
>>
>> > +static void __imsic_local_sync(struct imsic_local_priv *lpriv)
>> > +{
>> > +     struct imsic_local_config *mlocal;
>> > +     struct imsic_vector *vec, *mvec;
>> > +     int i;
>> > +
>> > +     lockdep_assert_held(&lpriv->lock);
>> > +
>> > +     /* This pairs with the barrier in __imsic_remote_sync(). */
>> > +     smp_mb();
>>
>> I'm trying to figure out why this barrier is needed? All the updates are
>> done behind the spinlocks. If there're some ordering constraints that
>> I'm missing, please document them.
>>
>> > +
>> > +     for_each_set_bit(i, lpriv->dirty_bitmap, imsic->global.nr_ids + 1) {
>> > +             if (!i || i == IMSIC_IPI_ID)
>> > +                     goto skip;
>> > +             vec = &lpriv->vectors[i];
>> > +
>> > +             if (READ_ONCE(vec->enable))
>> > +                     __imsic_id_set_enable(i);
>> > +             else
>> > +                     __imsic_id_clear_enable(i);
>> > +
>> > +             /*
>> > +              * If the ID was being moved to a new ID on some other CPU
>> > +              * then we can get a MSI during the movement so check the
>> > +              * ID pending bit and re-trigger the new ID on other CPU
>> > +              * using MMIO write.
>> > +              */
>> > +             mvec = READ_ONCE(vec->move);
>> > +             WRITE_ONCE(vec->move, NULL);
>>
>> mvec = xchg(&vec->move, NULL) ?
>
> The __imsic_local_sync() is called with spinlock held.

Yeah, this was a readability comment.

>> > +             if (mvec && mvec != vec) {
>> > +                     if (__imsic_id_read_clear_pending(i)) {
>> > +                             mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
>> > +                             writel_relaxed(mvec->local_id, mlocal->msi_va);
>> > +                     }
>> > +
>> > +                     imsic_vector_free(&lpriv->vectors[i]);
>> > +             }
>> > +
>> > +skip:
>> > +             bitmap_clear(lpriv->dirty_bitmap, i, 1);
>> > +     }
>> > +}
>> > +
>> > +void imsic_local_sync_all(void)
>> > +{
>> > +     struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
>> > +     unsigned long flags;
>> > +
>> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
>> > +     bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
>> > +     __imsic_local_sync(lpriv);
>> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
>> > +}
>> > +
>> > +void imsic_local_delivery(bool enable)
>> > +{
>> > +     if (enable) {
>> > +             imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
>> > +             imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
>> > +             return;
>> > +     }
>> > +
>> > +     imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
>> > +     imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
>> > +}
>> > +
>> > +#ifdef CONFIG_SMP
>> > +static void imsic_local_timer_callback(struct timer_list *timer)
>> > +{
>> > +     struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
>> > +     unsigned long flags;
>> > +
>> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
>> > +     __imsic_local_sync(lpriv);
>> > +     raw_spin_unlock_irqrestore(&lpriv->lock, flags);
>> > +}
>> > +
>> > +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
>> > +{
>> > +     lockdep_assert_held(&lpriv->lock);
>> > +
>> > +     /*
>> > +      * Ensure that changes to vector enable, vector move and
>> > +      * dirty bitmap are visible to the target CPU.
>>
>> ...which case the spinlock(s) are enough, no?
>
> spinlocks are not fences.

They are indeed, and it would be hard to use them as locks otherwise
(acq/rel -- good ol' Documentation/memory-barriers.txt).

> If the timer wheel on the target cpu is already running and we don't
> have a fence here then the target cpu might not see the changes
> done by this cpu.

Remove the smp_mb() pair, the spinlocks are enough for this scenario!

>> > +      *
>> > +      * This pairs with the barrier in __imsic_local_sync().
>> > +      */
>> > +     smp_mb();
>> > +
>> > +     /*
>> > +      * We schedule a timer on the target CPU if the target CPU is not
>> > +      * same as the current CPU. An offline CPU will unconditionally
>> > +      * synchronize IDs through imsic_starting_cpu() when the
>> > +      * CPU is brought up.
>> > +      */
>> > +     if (cpu_online(cpu)) {
>> > +             if (cpu == smp_processor_id()) {
>> > +                     __imsic_local_sync(lpriv);
>> > +                     return;
>> > +             }
>>
>> Maybe move this if-clause out from the cpu_online(), and only have
>> something like
>>   if (cpu_online(cpu) && !timer_pending(&lpriv->timer)) { ... }
>> inside the CONFIG_SMP guard...
>>
>> > +
>> > +             if (!timer_pending(&lpriv->timer)) {
>> > +                     lpriv->timer.expires = jiffies + 1;
>> > +                     add_timer_on(&lpriv->timer, cpu);
>> > +             }
>> > +     }
>> > +}
>> > +#else
>> > +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
>> > +{
>> > +     lockdep_assert_held(&lpriv->lock);
>> > +     __imsic_local_sync(lpriv);
>> > +}
>> > +#endif
>>
>> ...where we can get rid of this special !SMP all together for this
>> function.
>
> I failed to understand what is wrong the current code.

Oh, nothing is wrong. Just trying to get rid of some ifdeffery.

>> > +void imsic_vector_mask(struct imsic_vector *vec)
>> > +{
>> > +     struct imsic_local_priv *lpriv;
>> > +
>> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
>> > +     if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
>> > +             return;
>> > +
>> > +     /*
>> > +      * This function is called through Linux irq subsystem with
>> > +      * irqs disabled so no need to save/restore irq flags.
>> > +      */
>> > +
>> > +     raw_spin_lock(&lpriv->lock);
>> > +
>> > +     vec->enable = false;
>>
>> Should have WRITE_ONCE to make the checkers happy.
>
> Okay, I will update.
>
>>
>> > +     bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
>> > +     __imsic_remote_sync(lpriv, vec->cpu);
>> > +
>> > +     raw_spin_unlock(&lpriv->lock);
>> > +}
>> > +
>> > +void imsic_vector_unmask(struct imsic_vector *vec)
>> > +{
>> > +     struct imsic_local_priv *lpriv;
>> > +
>> > +     lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
>> > +     if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
>> > +             return;
>> > +
>> > +     /*
>> > +      * This function is called through Linux irq subsystem with
>> > +      * irqs disabled so no need to save/restore irq flags.
>> > +      */
>> > +
>> > +     raw_spin_lock(&lpriv->lock);
>> > +
>> > +     vec->enable = true;
>>
>> Dito.
>
> Okay, I will update.
>
>>
>> > +     bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
>> > +     __imsic_remote_sync(lpriv, vec->cpu);
>> > +
>> > +     raw_spin_unlock(&lpriv->lock);
>> > +}
>> > +
>> > +static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, struct imsic_vector *vec,
>> > +                                  bool new_enable, struct imsic_vector *new_move)
>> > +{
>> > +     unsigned long flags;
>> > +     bool enabled;
>> > +
>> > +     raw_spin_lock_irqsave(&lpriv->lock, flags);
>> > +
>> > +     /* Update enable and move details */
>> > +     enabled = READ_ONCE(vec->enable);
>> > +     WRITE_ONCE(vec->enable, new_enable);
>>
>> Again, xchg() would be easier to read.
>
> why ? spinlock is not enough?

They're enough! Just readbaility/personal taste.


I'm running tests for this series now! Would be awesome to have the
series land for 6.9!

Cheers,
Bj?rn


From festevam at gmail.com  Thu Feb 22 06:34:49 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 22 Feb 2024 11:34:49 -0300
Subject: [PATCH] ARM: dts: imx1-apf9328: Fix Ethernet node name
Message-ID: <20240222143449.978519-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

Per davicom,dm9000.yaml, the Ethernet node name should be 'ethernet'.

Change it to fix the following schema warning:

imx1-apf9328.dtb: eth at 4,c00000: $nodename:0: 'eth at 4,c00000' does not match '^ethernet(@.*)?$'
	from schema $id: http://devicetree.org/schemas/net/davicom,dm9000.yaml#

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
 arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts b/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts
index e66eef87a7a4..058e9435524f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts
@@ -54,7 +54,7 @@ nor: flash at 0,0 {
 		#size-cells = <1>;
 	};
 
-	eth: eth at 4,c00000 {
+	eth: ethernet at 4,c00000 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_eth>;
 		compatible = "davicom,dm9000";
-- 
2.34.1



From linux at armlinux.org.uk  Thu Feb 22 06:38:01 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 22 Feb 2024 14:38:01 +0000
Subject: [PATCH] arm: flush: check if the folio is reserved for IMO
 addresses
In-Reply-To: <f795228c-9795-4449-abcb-b7ff0cb486fb@huawei.com>
References: <20240222140147.1880357-1-liuyongqiang13@huawei.com>
 <f795228c-9795-4449-abcb-b7ff0cb486fb@huawei.com>
Message-ID: <ZddcSai76/KWxlMc@shell.armlinux.org.uk>

On Thu, Feb 22, 2024 at 10:06:04PM +0800, Kefeng Wang wrote:
> 
> 
> On 2024/2/22 22:01, Yongqiang Liu wrote:
> > Since commit a4d5613c4dc6 ("arm: extend pfn_valid to take into account
> > freed memory map alignment") changes the semantics of pfn_valid() to check
> > presence of the memory map for a PFN. A valid page for an address which
> > is reserved but not mapped by the kernel[1].In Some uio case we will get
> > a crash on a system with the following memory layout:
> > 
> >   node   0: [mem 0x00000000c0a00000-0x00000000cc8fffff]
> >   node   0: [mem 0x00000000d0000000-0x00000000da1fffff]
> >   the uio layout is?0xc0900000, 0x100000
> > 
> > the crash backtrace like:
> > 
> >    Unable to handle kernel paging request at virtual address bff00000
> >    [...]
> >    CPU: 1 PID: 465 Comm: startapp.bin Tainted: G           O      5.10.0 #1
> >    Hardware name: Generic DT based system
> >    PC is at b15_flush_kern_dcache_area+0x24/0x3c
> >    LR is at __sync_icache_dcache+0x6c/0x98
> >    [...]
> >     (b15_flush_kern_dcache_area) from (__sync_icache_dcache+0x6c/0x98)
> >     (__sync_icache_dcache) from (set_pte_at+0x28/0x54)
> >     (set_pte_at) from (remap_pfn_range+0x1a0/0x274)
> >     (remap_pfn_range) from (uio_mmap+0x184/0x1b8 [uio])
> >     (uio_mmap [uio]) from (__mmap_region+0x264/0x5f4)
> >     (__mmap_region) from (__do_mmap_mm+0x3ec/0x440)
> >     (__do_mmap_mm) from (do_mmap+0x50/0x58)
> >     (do_mmap) from (vm_mmap_pgoff+0xfc/0x188)
> >     (vm_mmap_pgoff) from (ksys_mmap_pgoff+0xac/0xc4)
> >     (ksys_mmap_pgoff) from (ret_fast_syscall+0x0/0x5c)
> >    Code: e0801001 e2423001 e1c00003 f57ff04f (ee070f3e)
> >    ---[ end trace 09cf0734c3805d52 ]---
> >    Kernel panic - not syncing: Fatal exception
> > 
> > So check if PG_reserved was set to solve this issue.
> > 
> > [1]: https://lore.kernel.org/lkml/Zbtdue57RO0QScJM at linux.ibm.com/
> > 
> > Fixes: a4d5613c4dc6 ("arm: extend pfn_valid to take into account freed memory map alignment")
> > Suggested-by: Mike Rapoport <rppt at linux.ibm.com>
> > Signed-off-by: Yongqiang Liu <liuyongqiang13 at huawei.com>
> > ---
> >   arch/arm/mm/flush.c | 4 ++++
> >   1 file changed, 4 insertions(+)
> > 
> > diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
> > index d19d140a10c7..f2b99223a0ab 100644
> > --- a/arch/arm/mm/flush.c
> > +++ b/arch/arm/mm/flush.c
> > @@ -15,6 +15,7 @@
> >   #include <asm/smp_plat.h>
> >   #include <asm/tlbflush.h>
> >   #include <linux/hugetlb.h>
> > +#include <linux/memblock.h>
> ??????????

Speak English so that everyone knows what you are saying. You are
participating in an international community where English is the
language that we use to communicate between ourselves.

Thanks.

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


From zhangfei.gao at linaro.org  Thu Feb 22 06:38:39 2024
From: zhangfei.gao at linaro.org (Zhangfei Gao)
Date: Thu, 22 Feb 2024 22:38:39 +0800
Subject: [PATCH v3] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock
In-Reply-To: <0-v3-11978fc67151+112-smmu_cd_atomic_jgg@nvidia.com>
References: <0-v3-11978fc67151+112-smmu_cd_atomic_jgg@nvidia.com>
Message-ID: <CABQgh9F3dWpE+2g14qq=fhdRNWgs4huBOgiDTQXQXuG=UzNv-g@mail.gmail.com>

On Thu, 22 Feb 2024 at 08:27, Jason Gunthorpe <jgg at nvidia.com> wrote:
>
> If the SMMU is configured to use a two level CD table then
> arm_smmu_write_ctx_desc() allocates a CD table leaf internally using
> GFP_KERNEL. Due to recent changes this is being done under a spinlock to
> iterate over the device list - thus it will trigger a sleeping while
> atomic warning:
>
>   arm_smmu_sva_set_dev_pasid()
>     mutex_lock(&sva_lock);
>     __arm_smmu_sva_bind()
>      arm_smmu_mmu_notifier_get()
>       spin_lock_irqsave()
>       arm_smmu_write_ctx_desc()
>         arm_smmu_get_cd_ptr()
>          arm_smmu_alloc_cd_leaf_table()
>           dmam_alloc_coherent(GFP_KERNEL)
>
> This is a 64K high order allocation and really should not be done
> atomically.
>
> At the moment the rework of the SVA to follow the new API is half
> finished. Recently the CD table memory was moved from the domain to the
> master, however we have the confusing situation where the SVA code is
> wrongly using the RID domains device's list to track which CD tables the
> SVA is installed in.
>
> Remove the logic to replicate the CD across all the domain's masters
> during attach. We know which master and which CD table the PASID should be
> installed in.
>
> Right now SVA only works when dma-iommu.c is in control of the RID
> translation, which means we have a single iommu_domain shared across the
> entire group and that iommu_domain is not shared outside the group.
>
> Critically this means that the iommu_group->devices list and RID's
> smmu_domain->devices list describe the same set of masters.
>
> For PCI cases the core code also insists on singleton groups so there is
> only one entry in the smmu_domain->devices list that is equal to the
> master being passed in to arm_smmu_sva_set_dev_pasid().
>
> Only non-PCI cases may have multi-device groups. However, the core code
> will repeat the calls to arm_smmu_sva_set_dev_pasid() across the entire
> iommu_group->devices list.
>
> Instead of having arm_smmu_mmu_notifier_get() indirectly loop over all the
> devices in the group via the RID's smmu_domain, rely on
> __arm_smmu_sva_bind() to be called for each device in the group and
> install the repeated CD entry that way.
>
> This avoids taking the spinlock to access the devices list and permits the
> arm_smmu_write_ctx_desc() to use a sleeping allocation. Leave the
> arm_smmu_mm_release() as a confusing situation, this requires tracking
> attached masters inside the SVA domain.
>
> Removing the loop allows arm_smmu_write_ctx_desc() to be called outside
> the spinlock and thus is safe to use GFP_KERNEL.
>
> Move the clearing of the CD into arm_smmu_sva_remove_dev_pasid() so that
> arm_smmu_mmu_notifier_get/put() remain paired functions.
>
> Fixes: 24503148c545 ("iommu/arm-smmu-v3: Refactor write_ctx_desc")
> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> Closes: https://lore.kernel.org/all/4e25d161-0cf8-4050-9aa3-dfa21cd63e56 at moroto.mountain/
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c   | 38 ++++++-------------
>  1 file changed, 12 insertions(+), 26 deletions(-)
>
> I suggest taking these two patches as well which will further help this code:
>
> https://lore.kernel.org/linux-iommu/12-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg at nvidia.com/
> https://lore.kernel.org/linux-iommu/2-v4-e7091cdd9e8d+43b1-smmuv3_newapi_p2_jgg at nvidia.com/
>
> Michael should check it, and Nicolin or Shameer should do a quick sanity check
> on their SVA HW.

Just tested on SVA HW, and NO issue.

Thanks


From javier.carrasco at wolfvision.net  Thu Feb 22 06:42:26 2024
From: javier.carrasco at wolfvision.net (Javier Carrasco)
Date: Thu, 22 Feb 2024 15:42:26 +0100
Subject: [PATCH v4 2/8] usb: misc: onboard_dev: add support for non-hub
 devices
In-Reply-To: <ZdZN3FIS4zcKe4Kw@google.com>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
 <20240220-onboard_xvf3500-v4-2-dc1617cc5dd4@wolfvision.net>
 <ZdZN3FIS4zcKe4Kw@google.com>
Message-ID: <174ce57a-3197-4251-831f-205ec5cfeae9@wolfvision.net>

On 21.02.24 20:24, Matthias Kaehlcke wrote:
> On Tue, Feb 20, 2024 at 03:05:46PM +0100, Javier Carrasco wrote:
>> Most of the functionality this driver provides can be used by non-hub
>> devices as well.
>>
>> To account for the hub-specific code, add a flag to the device data
>> structure and check its value for hub-specific code.
> 
> Please mention that the driver doesn't power off non-hub devices
> during system suspend.
> 
>> Signed-off-by: Javier Carrasco <javier.carrasco at wolfvision.net>
>> ---
>>  drivers/usb/misc/onboard_usb_dev.c |  3 ++-
>>  drivers/usb/misc/onboard_usb_dev.h | 10 ++++++++++
>>  2 files changed, 12 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c
>> index 2103af2cb2a6..f43130a6786f 100644
>> --- a/drivers/usb/misc/onboard_usb_dev.c
>> +++ b/drivers/usb/misc/onboard_usb_dev.c
>> @@ -129,7 +129,8 @@ static int __maybe_unused onboard_dev_suspend(struct device *dev)
>>  		if (!device_may_wakeup(node->udev->bus->controller))
>>  			continue;
>>  
>> -		if (usb_wakeup_enabled_descendants(node->udev)) {
>> +		if (usb_wakeup_enabled_descendants(node->udev) ||
>> +		    !onboard_dev->pdata->is_hub) {
> 
> 
> This check isn't dependent on characteristics of the USB devices processed
> in this loop, therefore it can be performed at function entry. Please combine
> it with the check of 'always_powered_in_suspend'. It's also an option to
> omit the check completely, 'always_powered_in_suspend' will never be set for
> non-hub devices (assuming the sysfs attribute isn't added).
> 

The attribute will not be available for non-hub devices in v5. However,
if the check is completely removed, will power_off not stay true at the
end of the function, always leading to a device power off? As you said,
'always_powered_in_suspend' will not be set for non-hub devices.

>>  			power_off = false;
>>  			break;
>>  		}
> 
> Without code context: please omit the creation of the 'always_powered_in_suspend'
> attribute for non-hub devices. As per above we don't plan to hone it, so it
> shouldn't exist.

Best regards,
Javier Carrasco



From wangkefeng.wang at huawei.com  Thu Feb 22 06:47:27 2024
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Thu, 22 Feb 2024 22:47:27 +0800
Subject: [PATCH] arm: flush: check if the folio is reserved for IMO
 addresses
In-Reply-To: <ZddcSai76/KWxlMc@shell.armlinux.org.uk>
References: <20240222140147.1880357-1-liuyongqiang13@huawei.com>
 <f795228c-9795-4449-abcb-b7ff0cb486fb@huawei.com>
 <ZddcSai76/KWxlMc@shell.armlinux.org.uk>
Message-ID: <fe85397a-ae81-49a2-9376-2166274d7337@huawei.com>



On 2024/2/22 22:38, Russell King (Oracle) wrote:
> On Thu, Feb 22, 2024 at 10:06:04PM +0800, Kefeng Wang wrote:
>>
>>
>> On 2024/2/22 22:01, Yongqiang Liu wrote:
>>> Since commit a4d5613c4dc6 ("arm: extend pfn_valid to take into account
>>> freed memory map alignment") changes the semantics of pfn_valid() to check
>>> presence of the memory map for a PFN. A valid page for an address which
>>> is reserved but not mapped by the kernel[1].In Some uio case we will get
>>> a crash on a system with the following memory layout:
>>>
>>>    node   0: [mem 0x00000000c0a00000-0x00000000cc8fffff]
>>>    node   0: [mem 0x00000000d0000000-0x00000000da1fffff]
>>>    the uio layout is?0xc0900000, 0x100000
>>>
>>> the crash backtrace like:
>>>
>>>     Unable to handle kernel paging request at virtual address bff00000
>>>     [...]
>>>     CPU: 1 PID: 465 Comm: startapp.bin Tainted: G           O      5.10.0 #1
>>>     Hardware name: Generic DT based system
>>>     PC is at b15_flush_kern_dcache_area+0x24/0x3c
>>>     LR is at __sync_icache_dcache+0x6c/0x98
>>>     [...]
>>>      (b15_flush_kern_dcache_area) from (__sync_icache_dcache+0x6c/0x98)
>>>      (__sync_icache_dcache) from (set_pte_at+0x28/0x54)
>>>      (set_pte_at) from (remap_pfn_range+0x1a0/0x274)
>>>      (remap_pfn_range) from (uio_mmap+0x184/0x1b8 [uio])
>>>      (uio_mmap [uio]) from (__mmap_region+0x264/0x5f4)
>>>      (__mmap_region) from (__do_mmap_mm+0x3ec/0x440)
>>>      (__do_mmap_mm) from (do_mmap+0x50/0x58)
>>>      (do_mmap) from (vm_mmap_pgoff+0xfc/0x188)
>>>      (vm_mmap_pgoff) from (ksys_mmap_pgoff+0xac/0xc4)
>>>      (ksys_mmap_pgoff) from (ret_fast_syscall+0x0/0x5c)
>>>     Code: e0801001 e2423001 e1c00003 f57ff04f (ee070f3e)
>>>     ---[ end trace 09cf0734c3805d52 ]---
>>>     Kernel panic - not syncing: Fatal exception
>>>
>>> So check if PG_reserved was set to solve this issue.
>>>
>>> [1]: https://lore.kernel.org/lkml/Zbtdue57RO0QScJM at linux.ibm.com/
>>>
>>> Fixes: a4d5613c4dc6 ("arm: extend pfn_valid to take into account freed memory map alignment")
>>> Suggested-by: Mike Rapoport <rppt at linux.ibm.com>
>>> Signed-off-by: Yongqiang Liu <liuyongqiang13 at huawei.com>
>>> ---
>>>    arch/arm/mm/flush.c | 4 ++++
>>>    1 file changed, 4 insertions(+)
>>>
>>> diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
>>> index d19d140a10c7..f2b99223a0ab 100644
>>> --- a/arch/arm/mm/flush.c
>>> +++ b/arch/arm/mm/flush.c
>>> @@ -15,6 +15,7 @@
>>>    #include <asm/smp_plat.h>
>>>    #include <asm/tlbflush.h>
>>>    #include <linux/hugetlb.h>
>>> +#include <linux/memblock.h>
>> ??????????
> 
> Speak English so that everyone knows what you are saying. You are
> participating in an international community where English is the
> language that we use to communicate between ourselves.
> 
Sorry, I mistake for a internal mail

To Yongqiang, please drop the unnecessary include and as Matthew said,
please consider to use folio helper.

> Thanks.
> 


From fancer.lancer at gmail.com  Thu Feb 22 06:55:58 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 17:55:58 +0300
Subject: [PATCH v9 1/4] serial: 8250: Add 8250 port clock update method
In-Reply-To: <ZdNvBtOlxo4FlLUH@smile.fi.intel.com>
References: <20200723003357.26897-1-Sergey.Semin@baikalelectronics.ru>
 <20200723003357.26897-2-Sergey.Semin@baikalelectronics.ru>
 <ZczD7KPbeRnY4CFc@black.fi.intel.com>
 <raryiklwhctwxcfj3ulbnjcl32owagiccmxpwzmszlh3vm343y@h2ehupm7uiga>
 <Zc5oYJY6W_MCpwhN@smile.fi.intel.com>
 <ow5mvkxa4g7mub3faiytsij4cyaaralcbzyn675jny5355han7@azw65mhkpwjz>
 <ZdNvBtOlxo4FlLUH@smile.fi.intel.com>
Message-ID: <v26ilx3hggj37wlsgoeyzcedv2doa54vevjqlhmklambdvzkzt@xa2gsjoselyc>

On Mon, Feb 19, 2024 at 05:08:54PM +0200, Andy Shevchenko wrote:
> On Fri, Feb 16, 2024 at 08:19:37PM +0300, Serge Semin wrote:
> > On Thu, Feb 15, 2024 at 09:39:12PM +0200, Andy Shevchenko wrote:
> 
> ...
> 
> (thanks for the detailed explanation why you have done it that way)
> 
> > If what you suggest is to replace the serial8250_update_uartclk() body
> > with a direct uart_port::set_termios() invocation then I don't find it
> > being much clearer really. The serial8250_update_uartclk() is
> > currently specialized on doing one thing: adjusting the divider in
> > case of the UART-clock change. If instead the entire
> > serial8250_set_termios() method is called then for a reader it won't
> > be easy to understand what is really required for a 8250 serial port
> > to perceive the ref-clock change. But from the maintainability point
> > of view I guess that it might be safer to just call
> > serial8250_set_termios() indeed, since among the other things the
> > later method implies the divider update too. Thus the maintainer won't
> > need to support the two clock divider update implementations.
> 
> > From that perspective I agree, directly calling serial8250_set_termios()
> > might be more suitable despite of it' doing more than required.
> 
> Would it be possible for you to cook the patch (and test on your HW,
> since it seems the only user of that)?

Agreed. The patch should have been just landed on your work and
private inboxes.
Link: https://lore.kernel.org/linux-serial/20240222145058.28307-1-fancer.lancer at gmail.com

-Serge(y)

> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
> 


From kabel at kernel.org  Thu Feb 22 06:58:37 2024
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Thu, 22 Feb 2024 15:58:37 +0100
Subject: [PATCH 1/2] devm-helpers: Add resource managed version of mutex init
Message-ID: <20240222145838.12916-1-kabel@kernel.org>

A few drivers are doing resource-managed mutex initialization by
implementing ad-hoc one-liner mutex dropping functions and using them
with devm_add_action_or_reset(). Help drivers avoid these repeated
one-liners by adding managed version of mutex initialization.

Use the new function devm_mutex_init() in the following drivers:
  drivers/gpio/gpio-pisosr.c
  drivers/gpio/gpio-sim.c
  drivers/gpu/drm/xe/xe_hwmon.c
  drivers/hwmon/nzxt-smart2.c
  drivers/leds/leds-is31fl319x.c
  drivers/power/supply/mt6370-charger.c
  drivers/power/supply/rt9467-charger.c

Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/gpio/gpio-pisosr.c            |  9 ++-----
 drivers/gpio/gpio-sim.c               | 12 ++--------
 drivers/gpu/drm/xe/xe_hwmon.c         | 11 ++-------
 drivers/hwmon/nzxt-smart2.c           |  9 ++-----
 drivers/leds/leds-is31fl319x.c        |  9 ++-----
 drivers/power/supply/mt6370-charger.c | 11 +--------
 drivers/power/supply/rt9467-charger.c | 34 ++++-----------------------
 include/linux/devm-helpers.h          | 32 +++++++++++++++++++++++++
 8 files changed, 47 insertions(+), 80 deletions(-)

diff --git a/drivers/gpio/gpio-pisosr.c b/drivers/gpio/gpio-pisosr.c
index e3013e778e15..dddbf37e855f 100644
--- a/drivers/gpio/gpio-pisosr.c
+++ b/drivers/gpio/gpio-pisosr.c
@@ -7,6 +7,7 @@
 #include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/devm-helpers.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
 #include <linux/module.h>
@@ -116,11 +117,6 @@ static const struct gpio_chip template_chip = {
 	.can_sleep		= true,
 };
 
-static void pisosr_mutex_destroy(void *lock)
-{
-	mutex_destroy(lock);
-}
-
 static int pisosr_gpio_probe(struct spi_device *spi)
 {
 	struct device *dev = &spi->dev;
@@ -147,8 +143,7 @@ static int pisosr_gpio_probe(struct spi_device *spi)
 		return dev_err_probe(dev, PTR_ERR(gpio->load_gpio),
 				     "Unable to allocate load GPIO\n");
 
-	mutex_init(&gpio->lock);
-	ret = devm_add_action_or_reset(dev, pisosr_mutex_destroy, &gpio->lock);
+	ret = devm_mutex_init(dev, &gpio->lock);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c
index c4106e37e6db..fcfcaa4efe70 100644
--- a/drivers/gpio/gpio-sim.c
+++ b/drivers/gpio/gpio-sim.c
@@ -12,6 +12,7 @@
 #include <linux/completion.h>
 #include <linux/configfs.h>
 #include <linux/device.h>
+#include <linux/devm-helpers.h>
 #include <linux/err.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
@@ -307,13 +308,6 @@ static ssize_t gpio_sim_sysfs_pull_store(struct device *dev,
 	return len;
 }
 
-static void gpio_sim_mutex_destroy(void *data)
-{
-	struct mutex *lock = data;
-
-	mutex_destroy(lock);
-}
-
 static void gpio_sim_put_device(void *data)
 {
 	struct device *dev = data;
@@ -457,9 +451,7 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev)
 	if (ret)
 		return ret;
 
-	mutex_init(&chip->lock);
-	ret = devm_add_action_or_reset(dev, gpio_sim_mutex_destroy,
-				       &chip->lock);
+	ret = devm_mutex_init(dev, &chip->lock);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
index 174ed2185481..bb88ae1c196c 100644
--- a/drivers/gpu/drm/xe/xe_hwmon.c
+++ b/drivers/gpu/drm/xe/xe_hwmon.c
@@ -3,6 +3,7 @@
  * Copyright ? 2023 Intel Corporation
  */
 
+#include <linux/devm-helpers.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/hwmon.h>
 #include <linux/types.h>
@@ -729,13 +730,6 @@ xe_hwmon_get_preregistration_info(struct xe_device *xe)
 		xe_hwmon_energy_get(hwmon, &energy);
 }
 
-static void xe_hwmon_mutex_destroy(void *arg)
-{
-	struct xe_hwmon *hwmon = arg;
-
-	mutex_destroy(&hwmon->hwmon_lock);
-}
-
 void xe_hwmon_register(struct xe_device *xe)
 {
 	struct device *dev = xe->drm.dev;
@@ -751,8 +745,7 @@ void xe_hwmon_register(struct xe_device *xe)
 
 	xe->hwmon = hwmon;
 
-	mutex_init(&hwmon->hwmon_lock);
-	if (devm_add_action_or_reset(dev, xe_hwmon_mutex_destroy, hwmon))
+	if (devm_mutex_init(dev, &hwmon->hwmon_lock))
 		return;
 
 	/* primary GT to access device level properties */
diff --git a/drivers/hwmon/nzxt-smart2.c b/drivers/hwmon/nzxt-smart2.c
index 7aa586eb74be..00bc89607673 100644
--- a/drivers/hwmon/nzxt-smart2.c
+++ b/drivers/hwmon/nzxt-smart2.c
@@ -5,6 +5,7 @@
  * Copyright (c) 2021 Aleksandr Mezin
  */
 
+#include <linux/devm-helpers.h>
 #include <linux/hid.h>
 #include <linux/hwmon.h>
 #include <linux/math.h>
@@ -721,11 +722,6 @@ static int __maybe_unused nzxt_smart2_hid_reset_resume(struct hid_device *hdev)
 	return init_device(drvdata, drvdata->update_interval);
 }
 
-static void mutex_fini(void *lock)
-{
-	mutex_destroy(lock);
-}
-
 static int nzxt_smart2_hid_probe(struct hid_device *hdev,
 				 const struct hid_device_id *id)
 {
@@ -741,8 +737,7 @@ static int nzxt_smart2_hid_probe(struct hid_device *hdev,
 
 	init_waitqueue_head(&drvdata->wq);
 
-	mutex_init(&drvdata->mutex);
-	ret = devm_add_action_or_reset(&hdev->dev, mutex_fini, &drvdata->mutex);
+	ret = devm_mutex_init(&hdev->dev, &drvdata->mutex);
 	if (ret)
 		return ret;
 
diff --git a/drivers/leds/leds-is31fl319x.c b/drivers/leds/leds-is31fl319x.c
index 66c65741202e..e9d7cf6a386c 100644
--- a/drivers/leds/leds-is31fl319x.c
+++ b/drivers/leds/leds-is31fl319x.c
@@ -8,6 +8,7 @@
  * effect LEDs.
  */
 
+#include <linux/devm-helpers.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/leds.h>
@@ -495,11 +496,6 @@ static inline int is31fl3196_db_to_gain(u32 dezibel)
 	return dezibel / IS31FL3196_AUDIO_GAIN_DB_STEP;
 }
 
-static void is31f1319x_mutex_destroy(void *lock)
-{
-	mutex_destroy(lock);
-}
-
 static int is31fl319x_probe(struct i2c_client *client)
 {
 	struct is31fl319x_chip *is31;
@@ -515,8 +511,7 @@ static int is31fl319x_probe(struct i2c_client *client)
 	if (!is31)
 		return -ENOMEM;
 
-	mutex_init(&is31->lock);
-	err = devm_add_action_or_reset(dev, is31f1319x_mutex_destroy, &is31->lock);
+	err = devm_mutex_init(dev, &is31->lock);
 	if (err)
 		return err;
 
diff --git a/drivers/power/supply/mt6370-charger.c b/drivers/power/supply/mt6370-charger.c
index e24fce087d80..fa0517d0352d 100644
--- a/drivers/power/supply/mt6370-charger.c
+++ b/drivers/power/supply/mt6370-charger.c
@@ -766,13 +766,6 @@ static int mt6370_chg_init_psy(struct mt6370_priv *priv)
 	return PTR_ERR_OR_ZERO(priv->psy);
 }
 
-static void mt6370_chg_destroy_attach_lock(void *data)
-{
-	struct mutex *attach_lock = data;
-
-	mutex_destroy(attach_lock);
-}
-
 static void mt6370_chg_destroy_wq(void *data)
 {
 	struct workqueue_struct *wq = data;
@@ -900,9 +893,7 @@ static int mt6370_chg_probe(struct platform_device *pdev)
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to init psy\n");
 
-	mutex_init(&priv->attach_lock);
-	ret = devm_add_action_or_reset(dev, mt6370_chg_destroy_attach_lock,
-				       &priv->attach_lock);
+	ret = devm_mutex_init(dev, &priv->attach_lock);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to init attach lock\n");
 
diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c
index fdfdc83ab045..84f07c22077f 100644
--- a/drivers/power/supply/rt9467-charger.c
+++ b/drivers/power/supply/rt9467-charger.c
@@ -10,6 +10,7 @@
 #include <linux/bitfield.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/devm-helpers.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
@@ -1149,27 +1150,6 @@ static int rt9467_reset_chip(struct rt9467_chg_data *data)
 	return regmap_field_write(data->rm_field[F_RST], 1);
 }
 
-static void rt9467_chg_destroy_adc_lock(void *data)
-{
-	struct mutex *adc_lock = data;
-
-	mutex_destroy(adc_lock);
-}
-
-static void rt9467_chg_destroy_attach_lock(void *data)
-{
-	struct mutex *attach_lock = data;
-
-	mutex_destroy(attach_lock);
-}
-
-static void rt9467_chg_destroy_ichg_ieoc_lock(void *data)
-{
-	struct mutex *ichg_ieoc_lock = data;
-
-	mutex_destroy(ichg_ieoc_lock);
-}
-
 static void rt9467_chg_complete_aicl_done(void *data)
 {
 	struct completion *aicl_done = data;
@@ -1222,21 +1202,15 @@ static int rt9467_charger_probe(struct i2c_client *i2c)
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to add irq chip\n");
 
-	mutex_init(&data->adc_lock);
-	ret = devm_add_action_or_reset(dev, rt9467_chg_destroy_adc_lock,
-				       &data->adc_lock);
+	ret = devm_mutex_init(dev, &data->adc_lock);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to init ADC lock\n");
 
-	mutex_init(&data->attach_lock);
-	ret = devm_add_action_or_reset(dev, rt9467_chg_destroy_attach_lock,
-				       &data->attach_lock);
+	ret = devm_mutex_init(dev, &data->attach_lock);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to init attach lock\n");
 
-	mutex_init(&data->ichg_ieoc_lock);
-	ret = devm_add_action_or_reset(dev, rt9467_chg_destroy_ichg_ieoc_lock,
-				       &data->ichg_ieoc_lock);
+	ret = devm_mutex_init(dev, &data->ichg_ieoc_lock);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to init ICHG/IEOC lock\n");
 
diff --git a/include/linux/devm-helpers.h b/include/linux/devm-helpers.h
index 74891802200d..70640fb96117 100644
--- a/include/linux/devm-helpers.h
+++ b/include/linux/devm-helpers.h
@@ -24,6 +24,8 @@
  */
 
 #include <linux/device.h>
+#include <linux/kconfig.h>
+#include <linux/mutex.h>
 #include <linux/workqueue.h>
 
 static inline void devm_delayed_work_drop(void *res)
@@ -76,4 +78,34 @@ static inline int devm_work_autocancel(struct device *dev,
 	return devm_add_action(dev, devm_work_drop, w);
 }
 
+static inline void devm_mutex_drop(void *res)
+{
+	mutex_destroy(res);
+}
+
+/**
+ * devm_mutex_init - Resource managed mutex initialization
+ * @dev:	Device which lifetime mutex is bound to
+ * @lock:	Mutex to be initialized (and automatically destroyed)
+ *
+ * Initialize mutex which is automatically destroyed when driver is detached.
+ * A few drivers initialize mutexes which they want destroyed before driver is
+ * detached, for debugging purposes.
+ * devm_mutex_init() can be used to omit the explicit mutex_destroy() call when
+ * driver is detached.
+ */
+static inline int devm_mutex_init(struct device *dev, struct mutex *lock)
+{
+	mutex_init(lock);
+
+	/*
+	 * mutex_destroy() is an empty function if CONFIG_DEBUG_MUTEXES is
+	 * disabled. No need to allocate an action in that case.
+	 */
+	if (IS_ENABLED(CONFIG_DEBUG_MUTEXES))
+		return devm_add_action_or_reset(dev, devm_mutex_drop, lock);
+	else
+		return 0;
+}
+
 #endif
-- 
2.43.0



From krzysztof.kozlowski at linaro.org  Thu Feb 22 07:02:07 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 16:02:07 +0100
Subject: [PATCH v4 7/8] ASoC: dt-bindings: xmos,xvf3500: add XMOS XVF3500
 voice processor
In-Reply-To: <20240220-onboard_xvf3500-v4-7-dc1617cc5dd4@wolfvision.net>
References: <20240220-onboard_xvf3500-v4-0-dc1617cc5dd4@wolfvision.net>
 <20240220-onboard_xvf3500-v4-7-dc1617cc5dd4@wolfvision.net>
Message-ID: <40a97700-15b8-4fb0-8636-d8de18e2d8a5@linaro.org>

On 20/02/2024 15:05, Javier Carrasco wrote:
> The XMOS XVF3500 VocalFusion Voice Processor[1] is a low-latency, 32-bit
> multicore controller for voice processing.
> 
> Add new bindings to define the device properties.
> 
> [1] https://www.xmos.com/xvf3500/

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From brgl at bgdev.pl  Thu Feb 22 07:11:11 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 22 Feb 2024 16:11:11 +0100
Subject: [PATCH 1/2] devm-helpers: Add resource managed version of mutex init
In-Reply-To: <20240222145838.12916-1-kabel@kernel.org>
References: <20240222145838.12916-1-kabel@kernel.org>
Message-ID: <CAMRc=McWhC0ZdR55TMkkdVov=dwT0=H-4_c4J-bq0quRpvyoBw@mail.gmail.com>

On Thu, Feb 22, 2024 at 3:58?PM Marek Beh?n <kabel at kernel.org> wrote:
>
> A few drivers are doing resource-managed mutex initialization by
> implementing ad-hoc one-liner mutex dropping functions and using them
> with devm_add_action_or_reset(). Help drivers avoid these repeated
> one-liners by adding managed version of mutex initialization.
>
> Use the new function devm_mutex_init() in the following drivers:
>   drivers/gpio/gpio-pisosr.c
>   drivers/gpio/gpio-sim.c

Yes, please!

For GPIO part:

Acked-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>


From sebastianene at google.com  Thu Feb 22 07:17:02 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Thu, 22 Feb 2024 15:17:02 +0000
Subject: [PATCH v6 4/6] KVM: arm64: Register ptdump with debugfs on guest
 creation
In-Reply-To: <20240220151035.327199-5-sebastianene@google.com>
References: <20240220151035.327199-1-sebastianene@google.com>
 <20240220151035.327199-5-sebastianene@google.com>
Message-ID: <ZddlbkG9j8UjhaWs@google.com>

On Tue, Feb 20, 2024 at 03:10:33PM +0000, Sebastian Ene wrote:
> While arch/*/mem/ptdump handles the kernel pagetable dumping code,
> introduce KVM/ptdump which shows the guest stage-2 pagetables. The
> separation is necessary because most of the definitions from the
> stage-2 pagetable reside in the KVM path and we will be invoking
> functionality **specific** to KVM.
> 
> When a guest is created, register a new file entry under the guest
> debugfs dir which allows userspace to show the contents of the guest
> stage-2 pagetables when accessed.
> 
> Signed-off-by: Sebastian Ene <sebastianene at google.com>
> ---
>  arch/arm64/kvm/Kconfig      | 13 ++++++
>  arch/arm64/kvm/Makefile     |  1 +
>  arch/arm64/kvm/debug.c      |  8 ++++
>  arch/arm64/kvm/kvm_ptdump.h | 20 +++++++++
>  arch/arm64/kvm/ptdump.c     | 88 +++++++++++++++++++++++++++++++++++++
>  5 files changed, 130 insertions(+)
>  create mode 100644 arch/arm64/kvm/kvm_ptdump.h
>  create mode 100644 arch/arm64/kvm/ptdump.c
> 
> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> index 27ca89b628a0..83ca07d16cf4 100644
> --- a/arch/arm64/kvm/Kconfig
> +++ b/arch/arm64/kvm/Kconfig
> @@ -67,4 +67,17 @@ config PROTECTED_NVHE_STACKTRACE
>  
>  	  If unsure, or not using protected nVHE (pKVM), say N.
>  
> +config PTDUMP_STAGE2_DEBUGFS
> +       bool "Present the stage-2 pagetables to debugfs"
> +       depends on PTDUMP_DEBUGFS && KVM
> +       default n
> +       help
> +         Say Y here if you want to show the stage-2 kernel pagetables
> +         layout in a debugfs file. This information is only useful for kernel developers
> +         who are working in architecture specific areas of the kernel.
> +         It is probably not a good idea to enable this feature in a production
> +         kernel.
> +
> +         If in doubt, say N.
> +
>  endif # VIRTUALIZATION
> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> index c0c050e53157..190eac17538c 100644
> --- a/arch/arm64/kvm/Makefile
> +++ b/arch/arm64/kvm/Makefile
> @@ -23,6 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
>  	 vgic/vgic-its.o vgic/vgic-debug.o
>  
>  kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
> +kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
>  
>  always-y := hyp_constants.h hyp-constants.s
>  
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index 8725291cb00a..ff97af2c0513 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -14,6 +14,8 @@
>  #include <asm/kvm_arm.h>
>  #include <asm/kvm_emulate.h>
>  
> +#include <kvm_ptdump.h>
> +
>  #include "trace.h"
>  
>  /* These are the bits of MDSCR_EL1 we may manipulate */
> @@ -342,3 +344,9 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
>  	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
>  	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
>  }
> +
> +int kvm_arch_create_vm_debugfs(struct kvm *kvm)
> +{
> +	kvm_ptdump_guest_register(kvm);
> +	return 0;
> +}
> diff --git a/arch/arm64/kvm/kvm_ptdump.h b/arch/arm64/kvm/kvm_ptdump.h
> new file mode 100644
> index 000000000000..5e8a655605f1
> --- /dev/null
> +++ b/arch/arm64/kvm/kvm_ptdump.h
> @@ -0,0 +1,20 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) Google, 2023
> + * Author: Sebastian Ene <sebastianene at google.com>
> + */
> +
> +#ifndef __KVM_PTDUMP_H
> +#define __KVM_PTDUMP_H
> +
> +#include <linux/kvm_host.h>
> +#include <asm/ptdump.h>
> +
> +
> +#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
> +void kvm_ptdump_guest_register(struct kvm *kvm);
> +#else
> +static inline void kvm_ptdump_guest_register(struct kvm *kvm) {}
> +#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
> +
> +#endif /* __KVM_PTDUMP_H */
> diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> new file mode 100644
> index 000000000000..9b04c24bb9be
> --- /dev/null
> +++ b/arch/arm64/kvm/ptdump.c
> @@ -0,0 +1,88 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Debug helper used to dump the stage-2 pagetables of the system and their
> + * associated permissions.
> + *
> + * Copyright (C) Google, 2023
> + * Author: Sebastian Ene <sebastianene at google.com>
> + */
> +#include <linux/debugfs.h>
> +#include <linux/kvm_host.h>
> +#include <linux/seq_file.h>
> +
> +#include <asm/kvm_pgtable.h>
> +#include <kvm_ptdump.h>
> +
> +
> +static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
> +			      enum kvm_pgtable_walk_flags visit)
> +{
> +	struct pg_state *st = ctx->arg;
> +	struct ptdump_state *pt_st = &st->ptdump;
> +
> +	note_page(pt_st, ctx->addr, ctx->level, ctx->old);
> +	return 0;
> +}
> +
> +static int kvm_ptdump_show_common(struct seq_file *m,
> +				  struct kvm_pgtable *pgtable,
> +				  struct pg_state *parser_state)
> +{
> +	struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker) {
> +		.cb     = kvm_ptdump_visitor,
> +		.arg	= parser_state,
> +		.flags	= KVM_PGTABLE_WALK_LEAF,
> +	};
> +
> +	return kvm_pgtable_walk(pgtable, 0, BIT(pgtable->ia_bits), &walker);
> +}
> +
> +static int kvm_ptdump_guest_show(struct seq_file *m, void *)
							^
FIXME: Here I need to specify an argument name as building with clang
complaints about this.

> +{
> +	struct kvm *kvm = m->private;
> +	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> +	struct pg_state parser_state = {0};
> +	int ret;
> +
> +	write_lock(&kvm->mmu_lock);
> +	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
> +	write_unlock(&kvm->mmu_lock);
> +
> +	return ret;
> +}
> +
> +static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
> +{
> +	struct kvm *kvm = m->i_private;
> +	int ret;
> +
> +	if (!kvm_get_kvm_safe(kvm))
> +		return -ENOENT;
> +
> +	ret = single_open(file, kvm_ptdump_guest_show, m->i_private);
> +	if (ret < 0)
> +		kvm_put_kvm(kvm);
> +
> +	return ret;
> +}
> +
> +static int kvm_ptdump_guest_close(struct inode *m, struct file *file)
> +{
> +	struct kvm *kvm = m->i_private;
> +
> +	kvm_put_kvm(kvm);
> +	return single_release(m, file);
> +}
> +
> +static const struct file_operations kvm_ptdump_guest_fops = {
> +	.open		= kvm_ptdump_guest_open,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +	.release	= kvm_ptdump_guest_close,
> +};
> +
> +void kvm_ptdump_guest_register(struct kvm *kvm)
> +{
> +	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
> +			    kvm, &kvm_ptdump_guest_fops);
> +}
> -- 
> 2.44.0.rc0.258.g7320e95886-goog
> 


From jgg at nvidia.com  Thu Feb 22 07:17:29 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 22 Feb 2024 11:17:29 -0400
Subject: [PATCH v3] iommu/arm-smmu-v3: Do not use GFP_KERNEL under as
 spinlock
In-Reply-To: <CABQgh9F3dWpE+2g14qq=fhdRNWgs4huBOgiDTQXQXuG=UzNv-g@mail.gmail.com>
References: <0-v3-11978fc67151+112-smmu_cd_atomic_jgg@nvidia.com>
 <CABQgh9F3dWpE+2g14qq=fhdRNWgs4huBOgiDTQXQXuG=UzNv-g@mail.gmail.com>
Message-ID: <20240222151729.GB13330@nvidia.com>

On Thu, Feb 22, 2024 at 10:38:39PM +0800, Zhangfei Gao wrote:

> > I suggest taking these two patches as well which will further help this code:
> >
> > https://lore.kernel.org/linux-iommu/12-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg at nvidia.com/
> > https://lore.kernel.org/linux-iommu/2-v4-e7091cdd9e8d+43b1-smmuv3_newapi_p2_jgg at nvidia.com/
> >
> > Michael should check it, and Nicolin or Shameer should do a quick sanity check
> > on their SVA HW.
> 
> Just tested on SVA HW, and NO issue.

Great, thanks for checking!

Jason


From sebastianene at google.com  Thu Feb 22 07:19:23 2024
From: sebastianene at google.com (Sebastian Ene)
Date: Thu, 22 Feb 2024 15:19:23 +0000
Subject: [PATCH v6 5/6] KVM: arm64: Initialize the ptdump parser with
 stage-2 attributes
In-Reply-To: <20240220151035.327199-6-sebastianene@google.com>
References: <20240220151035.327199-1-sebastianene@google.com>
 <20240220151035.327199-6-sebastianene@google.com>
Message-ID: <Zddl-_Em-pFteJXW@google.com>

On Tue, Feb 20, 2024 at 03:10:34PM +0000, Sebastian Ene wrote:
> Define a set of attributes used by the ptdump parser to display the
> properties of a guest memory region covered by a pagetable descriptor.
> Build a description of the pagetable levels and initialize the parser
> with this configuration.
> 
> Signed-off-by: Sebastian Ene <sebastianene at google.com>
> ---
>  arch/arm64/kvm/ptdump.c | 146 ++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 139 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> index 9b04c24bb9be..2c4e0c122d23 100644
> --- a/arch/arm64/kvm/ptdump.c
> +++ b/arch/arm64/kvm/ptdump.c
> @@ -14,6 +14,61 @@
>  #include <kvm_ptdump.h>
>  
>  
> +#define MARKERS_LEN		(2)
> +#define KVM_PGTABLE_LEVELS	(KVM_PGTABLE_LAST_LEVEL + 1)
> +
> +struct kvm_ptdump_guest_state {
> +	struct kvm		*kvm;
> +	struct pg_state		parser_state;
> +	struct addr_marker	ipa_marker[MARKERS_LEN];
> +	struct pg_level		level[KVM_PGTABLE_LEVELS];
> +	struct ptdump_range	range[MARKERS_LEN];
> +};
> +
> +static const struct prot_bits stage2_pte_bits[] = {
> +	{
> +		.mask	= PTE_VALID,
> +		.val	= PTE_VALID,
> +		.set	= " ",
> +		.clear	= "F",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
> +		.set	= "XN",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> +		.set	= "R",
> +		.clear	= " ",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> +		.set	= "W",
> +		.clear	= " ",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> +		.set	= "AF",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PTE_NG,
> +		.val	= PTE_NG,
> +		.set	= "FnXS",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PTE_CONT | PTE_VALID,
> +		.val	= PTE_CONT | PTE_VALID,
> +		.set	= "CON",
> +		.clear	= "   ",
> +	}, {
> +		.mask	= PTE_TABLE_BIT,
> +		.val	= PTE_TABLE_BIT,
> +		.set	= "   ",
> +		.clear	= "BLK",
> +	},
> +};
> +
>  static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
>  			      enum kvm_pgtable_walk_flags visit)
>  {
> @@ -37,15 +92,78 @@ static int kvm_ptdump_show_common(struct seq_file *m,
>  	return kvm_pgtable_walk(pgtable, 0, BIT(pgtable->ia_bits), &walker);
>  }
>  
> +static int kvm_ptdump_build_levels(struct pg_level *level, u32 start_lvl)
> +{
> +	static const char * const level_names[] = {"PGD", "PUD", "PMD", "PTE"};
> +	u32 i = 0;
> +	u64 mask = 0;
> +
> +	if (start_lvl > 2) {
> +		pr_err("invalid start_lvl %u\n", start_lvl);
> +		return -EINVAL;
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(stage2_pte_bits); i++)
> +		mask |= stage2_pte_bits[i].mask;
> +
> +	for (i = start_lvl; i <= KVM_PGTABLE_LAST_LEVEL; i++) {
> +		level[i].name	= level_names[i];
> +		level[i].num	= ARRAY_SIZE(stage2_pte_bits);
> +		level[i].bits	= stage2_pte_bits;
> +		level[i].mask	= mask;
> +	}
> +
> +	if (start_lvl > 0)
> +		level[start_lvl].name = level_names[0];
> +
> +	return 0;
> +}
> +
> +static struct kvm_ptdump_guest_state
> +*kvm_ptdump_parser_init(struct kvm *kvm)
> +{
> +	struct kvm_ptdump_guest_state *st;
> +	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> +	struct kvm_pgtable *pgtable = mmu->pgt;
> +	int ret;
> +
> +	st = kzalloc(sizeof(struct kvm_ptdump_guest_state), GFP_KERNEL_ACCOUNT);
> +	if (!st)
> +		return NULL;
> +
> +	ret = kvm_ptdump_build_levels(&st->level[0], pgtable->start_level);
> +	if (ret)
> +		goto free_with_state;
> +
> +	st->ipa_marker[0].name		= "Guest IPA";
> +	st->ipa_marker[1].start_address = BIT(pgtable->ia_bits);
> +	st->range[0].end		= BIT(pgtable->ia_bits);
> +
> +	st->kvm				= kvm;
> +	st->parser_state = (struct pg_state) {
> +		.marker		= &st->ipa_marker[0],
> +		.level		= -1,
> +		.pg_level	= &st->level[0],
> +		.ptdump.range	= &st->range[0],
> +	};
> +
> +	return st;
> +free_with_state:
> +	kfree(st);
> +	return NULL;
> +}
> +
>  static int kvm_ptdump_guest_show(struct seq_file *m, void *)
>  {
> -	struct kvm *kvm = m->private;
> +	struct kvm_ptdump_guest_state *st = m->private;
> +	struct kvm *kvm = st->kvm;
>  	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> -	struct pg_state parser_state = {0};
>  	int ret;
>  
> +	st->parser_state.seq = m;
> +
>  	write_lock(&kvm->mmu_lock);
> -	ret = kvm_ptdump_show_common(m, mmu->pgt, &parser_state);
> +	ret = kvm_ptdump_show_common(m, mmu->pgt, &st->parser_state);
>  	write_unlock(&kvm->mmu_lock);
>  
>  	return ret;
> @@ -54,22 +172,36 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *)
>  static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
>  {
>  	struct kvm *kvm = m->i_private;
> +	struct kvm_ptdump_guest_state *st;
>  	int ret;
>  
> -	if (!kvm_get_kvm_safe(kvm))
> -		return -ENOENT;

FIXME: Keep kvm_get_kvm_safe before invoking kvm_ptdump_parser_init to
avoid UAF if kvm gets destroyed.

> +	st = kvm_ptdump_parser_init(kvm);
> +	if (!st)
> +		return -ENOMEM;
>  
> -	ret = single_open(file, kvm_ptdump_guest_show, m->i_private);
> +	if (!kvm_get_kvm_safe(kvm)) {
> +		ret = -ENOENT;
> +		goto free_with_state;
> +	}
> +
> +	ret = single_open(file, kvm_ptdump_guest_show, st);
>  	if (ret < 0)
> -		kvm_put_kvm(kvm);
> +		goto free_with_kvm_ref;
>  
>  	return ret;
> +free_with_kvm_ref:
> +	kvm_put_kvm(kvm);
> +free_with_state:
> +	kfree(st);
> +	return ret;
>  }
>  
>  static int kvm_ptdump_guest_close(struct inode *m, struct file *file)
>  {
>  	struct kvm *kvm = m->i_private;
> +	void *st = ((struct seq_file *)file->private_data)->private;
>  
> +	kfree(st);
>  	kvm_put_kvm(kvm);
>  	return single_release(m, file);
>  }
> -- 
> 2.44.0.rc0.258.g7320e95886-goog
> 


From linux at roeck-us.net  Thu Feb 22 07:24:52 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 22 Feb 2024 07:24:52 -0800
Subject: [PATCH 1/2] devm-helpers: Add resource managed version of mutex
 init
In-Reply-To: <20240222145838.12916-1-kabel@kernel.org>
References: <20240222145838.12916-1-kabel@kernel.org>
Message-ID: <4a545c16-7518-49d2-b158-7fcabe3508c5@roeck-us.net>

On 2/22/24 06:58, Marek Beh?n wrote:
> A few drivers are doing resource-managed mutex initialization by
> implementing ad-hoc one-liner mutex dropping functions and using them
> with devm_add_action_or_reset(). Help drivers avoid these repeated
> one-liners by adding managed version of mutex initialization.
> 
> Use the new function devm_mutex_init() in the following drivers:
>    drivers/gpio/gpio-pisosr.c
>    drivers/gpio/gpio-sim.c
>    drivers/gpu/drm/xe/xe_hwmon.c
>    drivers/hwmon/nzxt-smart2.c
>    drivers/leds/leds-is31fl319x.c
>    drivers/power/supply/mt6370-charger.c
>    drivers/power/supply/rt9467-charger.c
> 
> Signed-off-by: Marek Beh?n <kabel at kernel.org>
> ---
>   drivers/gpio/gpio-pisosr.c            |  9 ++-----
>   drivers/gpio/gpio-sim.c               | 12 ++--------
>   drivers/gpu/drm/xe/xe_hwmon.c         | 11 ++-------
>   drivers/hwmon/nzxt-smart2.c           |  9 ++-----
>   drivers/leds/leds-is31fl319x.c        |  9 ++-----
>   drivers/power/supply/mt6370-charger.c | 11 +--------
>   drivers/power/supply/rt9467-charger.c | 34 ++++-----------------------
>   include/linux/devm-helpers.h          | 32 +++++++++++++++++++++++++
>   8 files changed, 47 insertions(+), 80 deletions(-)
> 
> diff --git a/drivers/gpio/gpio-pisosr.c b/drivers/gpio/gpio-pisosr.c
> index e3013e778e15..dddbf37e855f 100644
> --- a/drivers/gpio/gpio-pisosr.c
> +++ b/drivers/gpio/gpio-pisosr.c
> @@ -7,6 +7,7 @@
>   #include <linux/bitmap.h>
>   #include <linux/bitops.h>
>   #include <linux/delay.h>
> +#include <linux/devm-helpers.h>
>   #include <linux/gpio/consumer.h>
>   #include <linux/gpio/driver.h>
>   #include <linux/module.h>
> @@ -116,11 +117,6 @@ static const struct gpio_chip template_chip = {
>   	.can_sleep		= true,
>   };
>   
> -static void pisosr_mutex_destroy(void *lock)
> -{
> -	mutex_destroy(lock);
> -}
> -
>   static int pisosr_gpio_probe(struct spi_device *spi)
>   {
>   	struct device *dev = &spi->dev;
> @@ -147,8 +143,7 @@ static int pisosr_gpio_probe(struct spi_device *spi)
>   		return dev_err_probe(dev, PTR_ERR(gpio->load_gpio),
>   				     "Unable to allocate load GPIO\n");
>   
> -	mutex_init(&gpio->lock);
> -	ret = devm_add_action_or_reset(dev, pisosr_mutex_destroy, &gpio->lock);
> +	ret = devm_mutex_init(dev, &gpio->lock);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c
> index c4106e37e6db..fcfcaa4efe70 100644
> --- a/drivers/gpio/gpio-sim.c
> +++ b/drivers/gpio/gpio-sim.c
> @@ -12,6 +12,7 @@
>   #include <linux/completion.h>
>   #include <linux/configfs.h>
>   #include <linux/device.h>
> +#include <linux/devm-helpers.h>
>   #include <linux/err.h>
>   #include <linux/gpio/consumer.h>
>   #include <linux/gpio/driver.h>
> @@ -307,13 +308,6 @@ static ssize_t gpio_sim_sysfs_pull_store(struct device *dev,
>   	return len;
>   }
>   
> -static void gpio_sim_mutex_destroy(void *data)
> -{
> -	struct mutex *lock = data;
> -
> -	mutex_destroy(lock);
> -}
> -
>   static void gpio_sim_put_device(void *data)
>   {
>   	struct device *dev = data;
> @@ -457,9 +451,7 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev)
>   	if (ret)
>   		return ret;
>   
> -	mutex_init(&chip->lock);
> -	ret = devm_add_action_or_reset(dev, gpio_sim_mutex_destroy,
> -				       &chip->lock);
> +	ret = devm_mutex_init(dev, &chip->lock);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
> index 174ed2185481..bb88ae1c196c 100644
> --- a/drivers/gpu/drm/xe/xe_hwmon.c
> +++ b/drivers/gpu/drm/xe/xe_hwmon.c
> @@ -3,6 +3,7 @@
>    * Copyright ? 2023 Intel Corporation
>    */
>   
> +#include <linux/devm-helpers.h>
>   #include <linux/hwmon-sysfs.h>
>   #include <linux/hwmon.h>
>   #include <linux/types.h>
> @@ -729,13 +730,6 @@ xe_hwmon_get_preregistration_info(struct xe_device *xe)
>   		xe_hwmon_energy_get(hwmon, &energy);
>   }
>   
> -static void xe_hwmon_mutex_destroy(void *arg)
> -{
> -	struct xe_hwmon *hwmon = arg;
> -
> -	mutex_destroy(&hwmon->hwmon_lock);
> -}
> -
>   void xe_hwmon_register(struct xe_device *xe)
>   {
>   	struct device *dev = xe->drm.dev;
> @@ -751,8 +745,7 @@ void xe_hwmon_register(struct xe_device *xe)
>   
>   	xe->hwmon = hwmon;
>   
> -	mutex_init(&hwmon->hwmon_lock);
> -	if (devm_add_action_or_reset(dev, xe_hwmon_mutex_destroy, hwmon))
> +	if (devm_mutex_init(dev, &hwmon->hwmon_lock))
>   		return;
>   
>   	/* primary GT to access device level properties */
> diff --git a/drivers/hwmon/nzxt-smart2.c b/drivers/hwmon/nzxt-smart2.c
> index 7aa586eb74be..00bc89607673 100644
> --- a/drivers/hwmon/nzxt-smart2.c
> +++ b/drivers/hwmon/nzxt-smart2.c
> @@ -5,6 +5,7 @@
>    * Copyright (c) 2021 Aleksandr Mezin
>    */
>   
> +#include <linux/devm-helpers.h>
>   #include <linux/hid.h>
>   #include <linux/hwmon.h>
>   #include <linux/math.h>
> @@ -721,11 +722,6 @@ static int __maybe_unused nzxt_smart2_hid_reset_resume(struct hid_device *hdev)
>   	return init_device(drvdata, drvdata->update_interval);
>   }
>   
> -static void mutex_fini(void *lock)
> -{
> -	mutex_destroy(lock);
> -}
> -
>   static int nzxt_smart2_hid_probe(struct hid_device *hdev,
>   				 const struct hid_device_id *id)
>   {
> @@ -741,8 +737,7 @@ static int nzxt_smart2_hid_probe(struct hid_device *hdev,
>   
>   	init_waitqueue_head(&drvdata->wq);
>   
> -	mutex_init(&drvdata->mutex);
> -	ret = devm_add_action_or_reset(&hdev->dev, mutex_fini, &drvdata->mutex);
> +	ret = devm_mutex_init(&hdev->dev, &drvdata->mutex);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/leds/leds-is31fl319x.c b/drivers/leds/leds-is31fl319x.c
> index 66c65741202e..e9d7cf6a386c 100644
> --- a/drivers/leds/leds-is31fl319x.c
> +++ b/drivers/leds/leds-is31fl319x.c
> @@ -8,6 +8,7 @@
>    * effect LEDs.
>    */
>   
> +#include <linux/devm-helpers.h>
>   #include <linux/err.h>
>   #include <linux/i2c.h>
>   #include <linux/leds.h>
> @@ -495,11 +496,6 @@ static inline int is31fl3196_db_to_gain(u32 dezibel)
>   	return dezibel / IS31FL3196_AUDIO_GAIN_DB_STEP;
>   }
>   
> -static void is31f1319x_mutex_destroy(void *lock)
> -{
> -	mutex_destroy(lock);
> -}
> -
>   static int is31fl319x_probe(struct i2c_client *client)
>   {
>   	struct is31fl319x_chip *is31;
> @@ -515,8 +511,7 @@ static int is31fl319x_probe(struct i2c_client *client)
>   	if (!is31)
>   		return -ENOMEM;
>   
> -	mutex_init(&is31->lock);
> -	err = devm_add_action_or_reset(dev, is31f1319x_mutex_destroy, &is31->lock);
> +	err = devm_mutex_init(dev, &is31->lock);
>   	if (err)
>   		return err;
>   
> diff --git a/drivers/power/supply/mt6370-charger.c b/drivers/power/supply/mt6370-charger.c
> index e24fce087d80..fa0517d0352d 100644
> --- a/drivers/power/supply/mt6370-charger.c
> +++ b/drivers/power/supply/mt6370-charger.c
> @@ -766,13 +766,6 @@ static int mt6370_chg_init_psy(struct mt6370_priv *priv)
>   	return PTR_ERR_OR_ZERO(priv->psy);
>   }
>   
> -static void mt6370_chg_destroy_attach_lock(void *data)
> -{
> -	struct mutex *attach_lock = data;
> -
> -	mutex_destroy(attach_lock);
> -}
> -
>   static void mt6370_chg_destroy_wq(void *data)
>   {
>   	struct workqueue_struct *wq = data;
> @@ -900,9 +893,7 @@ static int mt6370_chg_probe(struct platform_device *pdev)
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to init psy\n");
>   
> -	mutex_init(&priv->attach_lock);
> -	ret = devm_add_action_or_reset(dev, mt6370_chg_destroy_attach_lock,
> -				       &priv->attach_lock);
> +	ret = devm_mutex_init(dev, &priv->attach_lock);
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to init attach lock\n");
>   
> diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c
> index fdfdc83ab045..84f07c22077f 100644
> --- a/drivers/power/supply/rt9467-charger.c
> +++ b/drivers/power/supply/rt9467-charger.c
> @@ -10,6 +10,7 @@
>   #include <linux/bitfield.h>
>   #include <linux/completion.h>
>   #include <linux/delay.h>
> +#include <linux/devm-helpers.h>
>   #include <linux/gpio/consumer.h>
>   #include <linux/i2c.h>
>   #include <linux/interrupt.h>
> @@ -1149,27 +1150,6 @@ static int rt9467_reset_chip(struct rt9467_chg_data *data)
>   	return regmap_field_write(data->rm_field[F_RST], 1);
>   }
>   
> -static void rt9467_chg_destroy_adc_lock(void *data)
> -{
> -	struct mutex *adc_lock = data;
> -
> -	mutex_destroy(adc_lock);
> -}
> -
> -static void rt9467_chg_destroy_attach_lock(void *data)
> -{
> -	struct mutex *attach_lock = data;
> -
> -	mutex_destroy(attach_lock);
> -}
> -
> -static void rt9467_chg_destroy_ichg_ieoc_lock(void *data)
> -{
> -	struct mutex *ichg_ieoc_lock = data;
> -
> -	mutex_destroy(ichg_ieoc_lock);
> -}
> -
>   static void rt9467_chg_complete_aicl_done(void *data)
>   {
>   	struct completion *aicl_done = data;
> @@ -1222,21 +1202,15 @@ static int rt9467_charger_probe(struct i2c_client *i2c)
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to add irq chip\n");
>   
> -	mutex_init(&data->adc_lock);
> -	ret = devm_add_action_or_reset(dev, rt9467_chg_destroy_adc_lock,
> -				       &data->adc_lock);
> +	ret = devm_mutex_init(dev, &data->adc_lock);
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to init ADC lock\n");
>   
> -	mutex_init(&data->attach_lock);
> -	ret = devm_add_action_or_reset(dev, rt9467_chg_destroy_attach_lock,
> -				       &data->attach_lock);
> +	ret = devm_mutex_init(dev, &data->attach_lock);
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to init attach lock\n");
>   
> -	mutex_init(&data->ichg_ieoc_lock);
> -	ret = devm_add_action_or_reset(dev, rt9467_chg_destroy_ichg_ieoc_lock,
> -				       &data->ichg_ieoc_lock);
> +	ret = devm_mutex_init(dev, &data->ichg_ieoc_lock);
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to init ICHG/IEOC lock\n");
>   
> diff --git a/include/linux/devm-helpers.h b/include/linux/devm-helpers.h
> index 74891802200d..70640fb96117 100644
> --- a/include/linux/devm-helpers.h
> +++ b/include/linux/devm-helpers.h
> @@ -24,6 +24,8 @@
>    */
>   
>   #include <linux/device.h>
> +#include <linux/kconfig.h>
> +#include <linux/mutex.h>
>   #include <linux/workqueue.h>
>   
>   static inline void devm_delayed_work_drop(void *res)
> @@ -76,4 +78,34 @@ static inline int devm_work_autocancel(struct device *dev,
>   	return devm_add_action(dev, devm_work_drop, w);
>   }
>   
> +static inline void devm_mutex_drop(void *res)
> +{
> +	mutex_destroy(res);
> +}
> +
> +/**
> + * devm_mutex_init - Resource managed mutex initialization
> + * @dev:	Device which lifetime mutex is bound to
> + * @lock:	Mutex to be initialized (and automatically destroyed)
> + *
> + * Initialize mutex which is automatically destroyed when driver is detached.
> + * A few drivers initialize mutexes which they want destroyed before driver is
> + * detached, for debugging purposes.
> + * devm_mutex_init() can be used to omit the explicit mutex_destroy() call when
> + * driver is detached.
> + */
> +static inline int devm_mutex_init(struct device *dev, struct mutex *lock)
> +{
> +	mutex_init(lock);
> +
> +	/*
> +	 * mutex_destroy() is an empty function if CONFIG_DEBUG_MUTEXES is
> +	 * disabled. No need to allocate an action in that case.
> +	 */
> +	if (IS_ENABLED(CONFIG_DEBUG_MUTEXES))
> +		return devm_add_action_or_reset(dev, devm_mutex_drop, lock);
> +	else

else after return is unnecessary.

> +		return 0;
> +}
> +
>   #endif



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:09 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:09 +0000
Subject: [PATCH v2 01/12] soc: mediatek: cmdq: Fix typo of CMDQ_JUMP_RELATIVE
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-2-chunkuang.hu@kernel.org>

For cmdq jump command, offset 0 means relative jump and offset 1
means absolute jump. cmdq_pkt_jump() is absolute jump, so fix the
typo of CMDQ_JUMP_RELATIVE in cmdq_pkt_jump().

Fixes: 946f1792d3d7 ("soc: mediatek: cmdq: add jump function")
Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index b0cd071c4719..0b2e5690dacf 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -14,7 +14,8 @@
 #define CMDQ_POLL_ENABLE_MASK	BIT(0)
 #define CMDQ_EOC_IRQ_EN		BIT(0)
 #define CMDQ_REG_TYPE		1
-#define CMDQ_JUMP_RELATIVE	1
+#define CMDQ_JUMP_RELATIVE	0
+#define CMDQ_JUMP_ABSOLUTE	1
 
 struct cmdq_instruction {
 	union {
@@ -397,7 +398,7 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
 	struct cmdq_instruction inst = {};
 
 	inst.op = CMDQ_CODE_JUMP;
-	inst.offset = CMDQ_JUMP_RELATIVE;
+	inst.offset = CMDQ_JUMP_ABSOLUTE;
 	inst.value = addr >>
 		cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
 	return cmdq_pkt_append_command(pkt, inst);
-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:10 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:10 +0000
Subject: [PATCH v2 02/12] soc: mediatek: cmdq: Add parameter shift_pa to cmdq_pkt_jump()
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-3-chunkuang.hu@kernel.org>

In original design, cmdq_pkt_jump() call cmdq_get_shift_pa() every
time to get shift_pa. But the shift_pa is constant value for each
SoC, so client driver just need to call cmdq_get_shift_pa() once
and pass shift_pa to cmdq_pkt_jump() to prevent frequent function
call.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 5 ++---
 include/linux/soc/mediatek/mtk-cmdq.h  | 6 ++++--
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 0b2e5690dacf..3380e56dd69b 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -393,14 +393,13 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
-int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 {
 	struct cmdq_instruction inst = {};
 
 	inst.op = CMDQ_CODE_JUMP;
 	inst.offset = CMDQ_JUMP_ABSOLUTE;
-	inst.value = addr >>
-		cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
+	inst.value = addr >> shift_pa;
 	return cmdq_pkt_append_command(pkt, inst);
 }
 EXPORT_SYMBOL(cmdq_pkt_jump);
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 649955d2cf5c..72adfd867cd9 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -253,10 +253,12 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
  *		     a physical address which should contains more instruction.
  * @pkt:        the CMDQ packet
  * @addr:       physical address of target instruction buffer
+ * @shift_pa:	shift bits of physical address in CMDQ instruction. This value
+ *		is got by cmdq_get_shift_pa().
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
 
 /**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
@@ -374,7 +376,7 @@ static inline int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
 	return -EINVAL;
 }
 
-static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 {
 	return -EINVAL;
 }
-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:08 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:08 +0000
Subject: [PATCH v2 00/12] Remove cl in struct cmdq_pkt
Message-ID: <20240222154120.16959-1-chunkuang.hu@kernel.org>

cl in struct cmdq_pkt is used to store struct cmdq_client, but every client
driver has the struct cmdq_client information, so it's not necessary to
store struct cmdq_client in struct cmdq_pkt. Because mailbox maintainer
do not like to mix mailbox patch with other patches in a series, so
mailbox patch [1] would be sent independently.

Changes in v2:
1. Fix typo of CMDQ_JUMP_RELATIVE
2. Refine cmdq_pkt_create() and cmdq_pkt_destroy()
3. Rename cmdq_pkt_jump() to cmdq_pkt_jump_abs()
4. Add cmdq_pkt_jump_rel() helper function
5. drm/mediatek: Use cmdq_pkt_create() and cmdq_pkt_destroy()
6. mtk-mdp3: Get fine-grain control of cmdq_pkt_finalize()
7. mtk-mdp3: Use cmdq_pkt_create() and cmdq_pkt_destroy()

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/commit/?h=mediatek-cmdq8&id=a1b2f7a7488285975c1f439086f1c4cc51a13bb9

Chun-Kuang Hu (12):
  soc: mediatek: cmdq: Fix typo of CMDQ_JUMP_RELATIVE
  soc: mediatek: cmdq: Add parameter shift_pa to cmdq_pkt_jump()
  soc: mediatek: cmdq: Rename cmdq_pkt_jump() to cmdq_pkt_jump_abs()
  soc: mediatek: cmdq: Add cmdq_pkt_jump_rel() helper function
  soc: mediatek: cmdq: Add cmdq_pkt_eoc() helper function
  soc: mediatek: cmdq: Remove cmdq_pkt_flush_async() helper function
  soc: mediatek: cmdq: Refine cmdq_pkt_create() and cmdq_pkt_destroy()
  drm/mediatek: Use cmdq_pkt_eoc() instead of cmdq_pkt_finalize()
  drm/mediatek: Use cmdq_pkt_create() and cmdq_pkt_destroy()
  media: platform: mtk-mdp3: Get fine-grain control of
    cmdq_pkt_finalize()
  media: platform: mtk-mdp3: Use cmdq_pkt_create() and
    cmdq_pkt_destroy()
  soc: mediatek: cmdq: Remove cmdq_pkt_finalize() helper function

 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 48 ++----------
 .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c    | 48 ++----------
 .../platform/mediatek/mdp3/mtk-mdp3-core.c    |  2 +
 .../platform/mediatek/mdp3/mtk-mdp3-core.h    |  1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c        | 73 ++++++-------------
 include/linux/soc/mediatek/mtk-cmdq.h         | 60 +++++++++------
 6 files changed, 73 insertions(+), 159 deletions(-)

-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:12 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:12 +0000
Subject: [PATCH v2 04/12] soc: mediatek: cmdq: Add cmdq_pkt_jump_rel() helper function
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-5-chunkuang.hu@kernel.org>

cmdq_pkt_jump_rel() append relative jump command to the packet.
Relative jump change PC to the target address with offset from
current PC.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 10 ++++++++++
 include/linux/soc/mediatek/mtk-cmdq.h  | 19 +++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 38d9077725d2..678db09983d4 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -404,6 +404,16 @@ int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 }
 EXPORT_SYMBOL(cmdq_pkt_jump_abs);
 
+int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa)
+{
+	struct cmdq_instruction inst = { {0} };
+
+	inst.op = CMDQ_CODE_JUMP;
+	inst.value = (u32)offset >> shift_pa;
+	return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_jump_rel);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
 	struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index f9b8608cb5d9..a935cd69d80f 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -261,6 +261,20 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
  */
 int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
 
+/**
+ * cmdq_pkt_jump_rel() - Append jump command to the CMDQ packet, ask GCE
+ *			 to execute an instruction that change current thread
+ *			 PC to a physical address with relative offset. The
+ *			 target address should contains more instruction.
+ * @pkt:	the CMDQ packet
+ * @offset:	relative offset of target instruction buffer from current PC.
+ * @shift_pa:	shift bits of physical address in CMDQ instruction. This value
+ *		is got by cmdq_get_shift_pa().
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa);
+
 /**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:	the CMDQ packet
@@ -382,6 +396,11 @@ static inline int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 sh
 	return -EINVAL;
 }
 
+static inline int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa)
+{
+	return -EINVAL;
+}
+
 static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
 	return -EINVAL;
-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:11 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:11 +0000
Subject: [PATCH v2 03/12] soc: mediatek: cmdq: Rename cmdq_pkt_jump() to cmdq_pkt_jump_abs()
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-4-chunkuang.hu@kernel.org>

In order to distinguish absolute jump and relative jump,
cmdq_pkt_jump() append absolute jump command, so rename it to
cmdq_pkt_jump_abs().

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |  4 ++--
 include/linux/soc/mediatek/mtk-cmdq.h  | 13 +++++++------
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 3380e56dd69b..38d9077725d2 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -393,7 +393,7 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
-int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
+int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 {
 	struct cmdq_instruction inst = {};
 
@@ -402,7 +402,7 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 	inst.value = addr >> shift_pa;
 	return cmdq_pkt_append_command(pkt, inst);
 }
-EXPORT_SYMBOL(cmdq_pkt_jump);
+EXPORT_SYMBOL(cmdq_pkt_jump_abs);
 
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 72adfd867cd9..f9b8608cb5d9 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -248,17 +248,18 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
 /**
- * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
- *		     to execute an instruction that change current thread PC to
- *		     a physical address which should contains more instruction.
+ * cmdq_pkt_jump_abs() - Append jump command to the CMDQ packet, ask GCE
+ *			 to execute an instruction that change current thread
+ *			 PC to a absolute physical address which should
+ *			 contains more instruction.
  * @pkt:        the CMDQ packet
- * @addr:       physical address of target instruction buffer
+ * @addr:       absolute physical address of target instruction buffer
  * @shift_pa:	shift bits of physical address in CMDQ instruction. This value
  *		is got by cmdq_get_shift_pa().
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
+int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
 
 /**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
@@ -376,7 +377,7 @@ static inline int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
 	return -EINVAL;
 }
 
-static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
+static inline int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 {
 	return -EINVAL;
 }
-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:13 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:13 +0000
Subject: [PATCH v2 05/12] soc: mediatek: cmdq: Add cmdq_pkt_eoc() helper function
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-6-chunkuang.hu@kernel.org>

cmdq_pkt_eoc() append eoc command to CMDQ packet. eoc command
would ask GCE to generate IRQ. It's usually appended to the end
of packet to notify all command in the packet is done.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 10 ++++++++++
 include/linux/soc/mediatek/mtk-cmdq.h  | 19 +++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 678db09983d4..766dbafaef62 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -414,6 +414,16 @@ int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa)
 }
 EXPORT_SYMBOL(cmdq_pkt_jump_rel);
 
+int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
+{
+	struct cmdq_instruction inst = { {0} };
+
+	inst.op = CMDQ_CODE_EOC;
+	inst.value = CMDQ_EOC_IRQ_EN;
+	return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_eoc);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
 	struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index a935cd69d80f..45110494ee9d 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -275,6 +275,20 @@ int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
  */
 int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa);
 
+/**
+ * cmdq_pkt_eoc() - Append EOC and ask GCE to generate an IRQ at end of execution
+ * @pkt:	The CMDQ packet
+ *
+ * Appends an End Of Code (EOC) command to the CMDQ packet and asks the GCE
+ * to generate an interrupt at the end of the execution of all commands in
+ * the pipeline.
+ * The EOC command is usually appended to the end of the pipeline to notify
+ * that all commands are done.
+ *
+ * Return: 0 for success or negative error number
+ */
+int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
+
 /**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:	the CMDQ packet
@@ -401,6 +415,11 @@ static inline int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_p
 	return -EINVAL;
 }
 
+static inline int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
+{
+	return -EINVAL;
+}
+
 static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
 	return -EINVAL;
-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:15 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:15 +0000
Subject: [PATCH v2 07/12] soc: mediatek: cmdq: Refine cmdq_pkt_create() and cmdq_pkt_destroy()
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-8-chunkuang.hu@kernel.org>

cmdq_pkt_create() and cmdq_pkt_destroy() is not suitable for
client drivers so each client driver has implement its own
function. This refinement would pass struct cmdq_pkt pointer into
cmdq_pkt_create(). In addition, client driver has the struct
cmdq_client information, so it's not necessary to store this
information in struct cmdq_pkt. After this refinement, client
drivers could use these helper funciton instead of implementing
its own version.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 24 +++++++-----------------
 include/linux/soc/mediatek/mtk-cmdq.h  | 14 ++++++++------
 2 files changed, 15 insertions(+), 23 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index bbe41302210a..1a1f1b260a06 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -106,22 +106,16 @@ void cmdq_mbox_destroy(struct cmdq_client *client)
 }
 EXPORT_SYMBOL(cmdq_mbox_destroy);
 
-struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t size)
 {
-	struct cmdq_pkt *pkt;
 	struct device *dev;
 	dma_addr_t dma_addr;
 
-	pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
-	if (!pkt)
-		return ERR_PTR(-ENOMEM);
 	pkt->va_base = kzalloc(size, GFP_KERNEL);
-	if (!pkt->va_base) {
-		kfree(pkt);
-		return ERR_PTR(-ENOMEM);
-	}
+	if (!pkt->va_base)
+		return -ENOMEM;
+
 	pkt->buf_size = size;
-	pkt->cl = (void *)client;
 
 	dev = client->chan->mbox->dev;
 	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
@@ -129,24 +123,20 @@ struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
 	if (dma_mapping_error(dev, dma_addr)) {
 		dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
 		kfree(pkt->va_base);
-		kfree(pkt);
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 	}
 
 	pkt->pa_base = dma_addr;
 
-	return pkt;
+	return 0;
 }
 EXPORT_SYMBOL(cmdq_pkt_create);
 
-void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt)
 {
-	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
-
 	dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
 			 DMA_TO_DEVICE);
 	kfree(pkt->va_base);
-	kfree(pkt);
 }
 EXPORT_SYMBOL(cmdq_pkt_destroy);
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index f82e789550ae..d9d0ee5ecb7a 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -62,17 +62,19 @@ void cmdq_mbox_destroy(struct cmdq_client *client);
 /**
  * cmdq_pkt_create() - create a CMDQ packet
  * @client:	the CMDQ mailbox client
+ * @pkt:	the CMDQ packet
  * @size:	required CMDQ buffer size
  *
- * Return: CMDQ packet pointer
+ * Return: 0 for success; else the error code is returned
  */
-struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size);
+int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t size);
 
 /**
  * cmdq_pkt_destroy() - destroy the CMDQ packet
+ * @client:	the CMDQ mailbox client
  * @pkt:	the CMDQ packet
  */
-void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
+void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt);
 
 /**
  * cmdq_pkt_write() - append write command to the CMDQ packet
@@ -312,12 +314,12 @@ static inline struct cmdq_client *cmdq_mbox_create(struct device *dev, int index
 
 static inline void cmdq_mbox_destroy(struct cmdq_client *client) { }
 
-static inline  struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+static inline int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t size)
 {
-	return ERR_PTR(-EINVAL);
+	return -EINVAL;
 }
 
-static inline void cmdq_pkt_destroy(struct cmdq_pkt *pkt) { }
+static inline void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt) { }
 
 static inline int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
 {
-- 
2.34.1



From will at kernel.org  Thu Feb 22 07:41:47 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 15:41:47 +0000
Subject: [PATCH 05/10] arm64/vdso: Use generic union vdso_data_store
In-Reply-To: <20240219153939.75719-6-anna-maria@linutronix.de>
References: <20240219153939.75719-1-anna-maria@linutronix.de>
 <20240219153939.75719-6-anna-maria@linutronix.de>
Message-ID: <20240222154146.GA8949@willie-the-truck>

On Mon, Feb 19, 2024 at 04:39:34PM +0100, Anna-Maria Behnsen wrote:
> There is already a generic union definition for vdso_data_store in vdso
> datapage header.
> 
> Use this definition to prevent code duplication.
> 
> Signed-off-by: Anna-Maria Behnsen <anna-maria at linutronix.de>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> ---
>  arch/arm64/kernel/vdso.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index 5562daf38a22..89b6e7840002 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -69,10 +69,7 @@ static struct vdso_abi_info vdso_info[] __ro_after_init = {
>  /*
>   * The vDSO data page.
>   */
> -static union {
> -	struct vdso_data	data[CS_BASES];
> -	u8			page[PAGE_SIZE];
> -} vdso_data_store __page_aligned_data;
> +static union vdso_data_store vdso_data_store __page_aligned_data;
>  struct vdso_data *vdso_data = vdso_data_store.data;
>  
>  static int vdso_mremap(const struct vm_special_mapping *sm,
> -- 
> 2.39.2

Acked-by: Will Deacon <will at kernel.org>

Will


From chunkuang.hu at kernel.org  Thu Feb 22 07:41:16 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:16 +0000
Subject: [PATCH v2 08/12] drm/mediatek: Use cmdq_pkt_eoc() instead of cmdq_pkt_finalize()
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-9-chunkuang.hu@kernel.org>

For some client driver, it want to reduce latency between excuting
previous packet command and next packet command, so append jump
command to the end of previous packet and the jump destination
address is the start address of next packet command buffer. Before
next packet exist, the previous packet has no information of where
to jump to, so append nop command first. When next packet exist,
change nop command to jump command. For mediatek drm driver, it
never has next packet, so appending nop command is redundant.
Because cmdq_pkt_finalize() would append nop command, so change
calling cmdq_pkt_finalize() to cmdq_pkt_eoc() to prevent append
redundant nop command.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index c729af3b9822..df693fa268ce 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -593,7 +593,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
 		cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
 		cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
 		mtk_crtc_ddp_config(crtc, cmdq_handle);
-		cmdq_pkt_finalize(cmdq_handle);
+		cmdq_pkt_eoc(cmdq_handle);
 		dma_sync_single_for_device(mtk_crtc->cmdq_client.chan->mbox->dev,
 					   cmdq_handle->pa_base,
 					   cmdq_handle->cmd_buf_size,
-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:19 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:19 +0000
Subject: [PATCH v2 11/12] media: platform: mtk-mdp3: Use cmdq_pkt_create() and cmdq_pkt_destroy()
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-12-chunkuang.hu@kernel.org>

Use cmdq_pkt_create() and cmdq_pkt_destroy() common function
instead of implementing mdp3 version.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c    | 45 ++-----------------
 1 file changed, 4 insertions(+), 41 deletions(-)

diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
index b720e69b341d..c7a9f142102d 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
@@ -287,43 +287,6 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd,
 	return 0;
 }
 
-static int mdp_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
-			       size_t size)
-{
-	struct device *dev;
-	dma_addr_t dma_addr;
-
-	pkt->va_base = kzalloc(size, GFP_KERNEL);
-	if (!pkt->va_base)
-		return -ENOMEM;
-
-	pkt->buf_size = size;
-	pkt->cl = (void *)client;
-
-	dev = client->chan->mbox->dev;
-	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
-				  DMA_TO_DEVICE);
-	if (dma_mapping_error(dev, dma_addr)) {
-		dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
-		kfree(pkt->va_base);
-		return -ENOMEM;
-	}
-
-	pkt->pa_base = dma_addr;
-
-	return 0;
-}
-
-static void mdp_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
-{
-	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
-
-	dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
-			 DMA_TO_DEVICE);
-	kfree(pkt->va_base);
-	pkt->va_base = NULL;
-}
-
 static void mdp_auto_release_work(struct work_struct *work)
 {
 	struct mdp_cmdq_cmd *cmd;
@@ -341,7 +304,7 @@ static void mdp_auto_release_work(struct work_struct *work)
 	atomic_dec(&mdp->job_count);
 	wake_up(&mdp->callback_wq);
 
-	mdp_cmdq_pkt_destroy(&cmd->pkt);
+	cmdq_pkt_destroy(mdp->cmdq_clt, &cmd->pkt);
 	kfree(cmd->comps);
 	cmd->comps = NULL;
 	kfree(cmd);
@@ -388,7 +351,7 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg)
 		atomic_dec(&mdp->job_count);
 		wake_up(&mdp->callback_wq);
 
-		mdp_cmdq_pkt_destroy(&cmd->pkt);
+		cmdq_pkt_destroy(mdp->cmdq_clt, &cmd->pkt);
 		kfree(cmd->comps);
 		cmd->comps = NULL;
 		kfree(cmd);
@@ -418,7 +381,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 		goto err_cancel_job;
 	}
 
-	ret = mdp_cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K);
+	ret = cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K);
 	if (ret)
 		goto err_free_cmd;
 
@@ -513,7 +476,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 err_free_comps:
 	kfree(comps);
 err_destroy_pkt:
-	mdp_cmdq_pkt_destroy(&cmd->pkt);
+	cmdq_pkt_destroy(mdp->cmdq_clt, &cmd->pkt);
 err_free_cmd:
 	kfree(cmd);
 err_cancel_job:
-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:20 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:20 +0000
Subject: [PATCH v2 12/12] soc: mediatek: cmdq: Remove cmdq_pkt_finalize() helper function
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-13-chunkuang.hu@kernel.org>

In order to have fine-grained control, use cmdq_pkt_eoc() and
cmdq_pkt_jump_rel() to replace cmdq_pkt_finalize().

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 22 ----------------------
 include/linux/soc/mediatek/mtk-cmdq.h  | 13 -------------
 2 files changed, 35 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 1a1f1b260a06..d8fe98338bf2 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -414,26 +414,4 @@ int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
 }
 EXPORT_SYMBOL(cmdq_pkt_eoc);
 
-int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
-{
-	struct cmdq_instruction inst = { {0} };
-	int err;
-
-	/* insert EOC and generate IRQ for each command iteration */
-	inst.op = CMDQ_CODE_EOC;
-	inst.value = CMDQ_EOC_IRQ_EN;
-	err = cmdq_pkt_append_command(pkt, inst);
-	if (err < 0)
-		return err;
-
-	/* JUMP to end */
-	inst.op = CMDQ_CODE_JUMP;
-	inst.value = CMDQ_JUMP_PASS >>
-		cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
-	err = cmdq_pkt_append_command(pkt, inst);
-
-	return err;
-}
-EXPORT_SYMBOL(cmdq_pkt_finalize);
-
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index d9d0ee5ecb7a..6bdb9c0d6a29 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -291,14 +291,6 @@ int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa);
  */
 int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
 
-/**
- * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
- * @pkt:	the CMDQ packet
- *
- * Return: 0 for success; else the error code is returned
- */
-int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
-
 #else /* IS_ENABLED(CONFIG_MTK_CMDQ) */
 
 static inline int cmdq_dev_get_client_reg(struct device *dev,
@@ -409,11 +401,6 @@ static inline int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
 	return -EINVAL;
 }
 
-static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
-{
-	return -EINVAL;
-}
-
 #endif /* IS_ENABLED(CONFIG_MTK_CMDQ) */
 
 #endif	/* __MTK_CMDQ_H__ */
-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:14 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:14 +0000
Subject: [PATCH v2 06/12] soc: mediatek: cmdq: Remove cmdq_pkt_flush_async() helper function
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-7-chunkuang.hu@kernel.org>

cmdq_pkt_flush_async() is not used by all client drivers (MediaTek
drm driver and MediaTek mdp3 driver), so remove it.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 15 ---------------
 include/linux/soc/mediatek/mtk-cmdq.h  | 18 ------------------
 2 files changed, 33 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 766dbafaef62..bbe41302210a 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -446,19 +446,4 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 }
 EXPORT_SYMBOL(cmdq_pkt_finalize);
 
-int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
-{
-	int err;
-	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
-
-	err = mbox_send_message(client->chan, pkt);
-	if (err < 0)
-		return err;
-	/* We can send next packet immediately, so just call txdone. */
-	mbox_client_txdone(client->chan, 0);
-
-	return 0;
-}
-EXPORT_SYMBOL(cmdq_pkt_flush_async);
-
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 45110494ee9d..f82e789550ae 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -297,19 +297,6 @@ int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
  */
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
 
-/**
- * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
- *                          packet and call back at the end of done packet
- * @pkt:	the CMDQ packet
- *
- * Return: 0 for success; else the error code is returned
- *
- * Trigger CMDQ to asynchronously execute the CMDQ packet and call back
- * at the end of done packet. Note that this is an ASYNC function. When the
- * function returned, it may or may not be finished.
- */
-int cmdq_pkt_flush_async(struct cmdq_pkt *pkt);
-
 #else /* IS_ENABLED(CONFIG_MTK_CMDQ) */
 
 static inline int cmdq_dev_get_client_reg(struct device *dev,
@@ -425,11 +412,6 @@ static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 	return -EINVAL;
 }
 
-static inline int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
-{
-	return -EINVAL;
-}
-
 #endif /* IS_ENABLED(CONFIG_MTK_CMDQ) */
 
 #endif	/* __MTK_CMDQ_H__ */
-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:17 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:17 +0000
Subject: [PATCH v2 09/12] drm/mediatek: Use cmdq_pkt_create() and cmdq_pkt_destroy()
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-10-chunkuang.hu@kernel.org>

Use cmdq_pkt_create() and cmdq_pkt_destroy() common function
instead of implementing drm version.

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 46 +++----------------------
 1 file changed, 4 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index df693fa268ce..96c0db44dc79 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -111,44 +111,6 @@ static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
 	}
 }
 
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
-static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
-				   size_t size)
-{
-	struct device *dev;
-	dma_addr_t dma_addr;
-
-	pkt->va_base = kzalloc(size, GFP_KERNEL);
-	if (!pkt->va_base)
-		return -ENOMEM;
-
-	pkt->buf_size = size;
-	pkt->cl = (void *)client;
-
-	dev = client->chan->mbox->dev;
-	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
-				  DMA_TO_DEVICE);
-	if (dma_mapping_error(dev, dma_addr)) {
-		dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
-		kfree(pkt->va_base);
-		return -ENOMEM;
-	}
-
-	pkt->pa_base = dma_addr;
-
-	return 0;
-}
-
-static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
-{
-	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
-
-	dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
-			 DMA_TO_DEVICE);
-	kfree(pkt->va_base);
-}
-#endif
-
 static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
@@ -156,7 +118,7 @@ static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
 
 	mtk_mutex_put(mtk_crtc->mutex);
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-	mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle);
+	cmdq_pkt_destroy(&mtk_crtc->cmdq_client, &mtk_crtc->cmdq_handle);
 
 	if (mtk_crtc->cmdq_client.chan) {
 		mbox_free_channel(mtk_crtc->cmdq_client.chan);
@@ -1083,9 +1045,9 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 			mbox_free_channel(mtk_crtc->cmdq_client.chan);
 			mtk_crtc->cmdq_client.chan = NULL;
 		} else {
-			ret = mtk_drm_cmdq_pkt_create(&mtk_crtc->cmdq_client,
-						      &mtk_crtc->cmdq_handle,
-						      PAGE_SIZE);
+			ret = cmdq_pkt_create(&mtk_crtc->cmdq_client,
+					      &mtk_crtc->cmdq_handle,
+					      PAGE_SIZE);
 			if (ret) {
 				dev_dbg(dev, "mtk_crtc %d failed to create cmdq packet\n",
 					drm_crtc_index(&mtk_crtc->base));
-- 
2.34.1



From chunkuang.hu at kernel.org  Thu Feb 22 07:41:18 2024
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 22 Feb 2024 15:41:18 +0000
Subject: [PATCH v2 10/12] media: platform: mtk-mdp3: Get fine-grain control of cmdq_pkt_finalize()
In-Reply-To: <20240222154120.16959-1-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
Message-ID: <20240222154120.16959-11-chunkuang.hu@kernel.org>

In order to have fine-grained control, use cmdq_pkt_eoc() and
cmdq_pkt_jump_rel() to replace cmdq_pkt_finalize().

Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 3 ++-
 drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c | 2 ++
 drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h | 1 +
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
index 6adac857a477..b720e69b341d 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
@@ -471,7 +471,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 		dev_err(dev, "mdp_path_config error\n");
 		goto err_free_path;
 	}
-	cmdq_pkt_finalize(&cmd->pkt);
+	cmdq_pkt_eoc(&cmd->pkt);
+	cmdq_pkt_jump_rel(&cmd->pkt, CMDQ_INST_SIZE, mdp->cmdq_shift_pa);
 
 	for (i = 0; i < num_comp; i++)
 		memcpy(&comps[i], path->comps[i].comp,
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
index 94f4ed78523b..2214744c937c 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
@@ -231,6 +231,8 @@ static int mdp_probe(struct platform_device *pdev)
 		goto err_put_scp;
 	}
 
+	mdp->cmdq_shift_pa = cmdq_get_shift_pa(mdp->cmdq_clt->chan);
+
 	init_waitqueue_head(&mdp->callback_wq);
 	ida_init(&mdp->mdp_ida);
 	platform_set_drvdata(pdev, mdp);
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
index 7e21d226ceb8..ed61e0bb69ee 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
@@ -83,6 +83,7 @@ struct mdp_dev {
 	u32					id_count;
 	struct ida				mdp_ida;
 	struct cmdq_client			*cmdq_clt;
+	u8					cmdq_shift_pa;
 	wait_queue_head_t			callback_wq;
 
 	struct v4l2_device			v4l2_dev;
-- 
2.34.1



From krzysztof.kozlowski at linaro.org  Thu Feb 22 07:55:02 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Thu, 22 Feb 2024 16:55:02 +0100
Subject: [PATCH] ARM: dts: exynos4212-tab3: limit usable memory range
In-Reply-To: <5d67441e-df61-4894-ba52-2bed8a1143d6@linaro.org>
References: <20240217-tab3-limit-usable-memory-range-v1-1-49cc9c86a5cc@gmail.com>
 <15ab6aa6-fb30-4970-9c50-546afb933e03@linaro.org>
 <c2fde69d-48c2-446f-ac56-876651c06b51@gmail.com>
 <5d67441e-df61-4894-ba52-2bed8a1143d6@linaro.org>
Message-ID: <d41b7281-5f44-4de0-9ea6-5dcae26ac295@linaro.org>

On 21/02/2024 09:26, Krzysztof Kozlowski wrote:
> On 19/02/2024 20:49, Artur Weber wrote:
>> On 19.02.2024 08:44, Krzysztof Kozlowski wrote:
>>> On 17/02/2024 20:02, Artur Weber wrote:
>>>> The stock bootloader on the Samsung Galaxy Tab 3 8.0 provides an
>>>> incorrect available memory range over ATAG_MEM. Limit the usable
>>>> memory in the DTS to prevent it from doing so, without having to
>>>> disable ATAG support.
>>>>
>>>> Signed-off-by: Artur Weber <aweber.kernel at gmail.com>
>>>> ---
>>>>   arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi | 6 ++++++
>>>>   1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
>>>> index e5254e32aa8f..9bc05961577d 100644
>>>> --- a/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
>>>> +++ b/arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
>>>> @@ -45,6 +45,12 @@ chosen {
>>>>   		/* Default S-BOOT bootloader loads initramfs here */
>>>>   		linux,initrd-start = <0x42000000>;
>>>>   		linux,initrd-end = <0x42800000>;
>>>> +
>>>> +		/*
>>>> +		 * Stock bootloader provides incorrect memory size in ATAG_MEM;
>>>> +		 * override it here
>>>> +		 */
>>>> +		linux,usable-memory-range = <0x40000000 0x3fc00000>;
>>>
>>> Applied and dropped:
>>>   chosen: linux,usable-memory-range:0: [4611686019496935424] is too short
>>
>> This seems to be a binding issue; the DT schema expects a 64-bit memory 
>> address and size, and doesn't allow a 32-bit range. I've tested the DTS 
>> on my device and this property seems to be handled fine, so I think this 
>> should allow 32-bit values as well.
> 
> Regardless where is the issue: please test before sending.
> 
>>
>> I've opened a PR[1] against devicetree-org/dt-schema (where the schema 
>> for the chosen node is stored) to try and fix this. If my approach is 
>> incorrect, feel free to comment there as well.
> 
> 
> According to Rob's comments, the DTS is the issue.

With updated dtschema I still see the same warning. Is something else
missing?

Best regards,
Krzysztof



From conor at kernel.org  Thu Feb 22 08:02:07 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 22 Feb 2024 16:02:07 +0000
Subject: [PATCH 1/2] dt-bindings: arm: aspeed: add ASUS X4TF board
In-Reply-To: <20240222085914.1218037-1-Kelly_Hung@asus.com>
References: <20240222085914.1218037-1-Kelly_Hung@asus.com>
Message-ID: <20240222-getting-nebulizer-8f75ba8063b1@spud>

On Thu, Feb 22, 2024 at 04:59:13PM +0800, Kelly Hung wrote:
> Document the new compatibles used on ASUS X4TF.

It would be good to mention here what the x4tf is - is it a bmc or
an sbc etc.

Otherwise,
Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> 
> Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
> ---
>  Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> index 749ee54a3..80009948e 100644
> --- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> +++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> @@ -74,6 +74,7 @@ properties:
>                - ampere,mtmitchell-bmc
>                - aspeed,ast2600-evb
>                - aspeed,ast2600-evb-a1
> +              - asus,x4tf
>                - facebook,bletchley-bmc
>                - facebook,cloudripper-bmc
>                - facebook,elbert-bmc
> -- 
> 2.25.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/20240222/4d77c794/attachment-0001.sig>

From linux at roeck-us.net  Thu Feb 22 08:03:09 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 22 Feb 2024 08:03:09 -0800
Subject: [PATCH 1/2] devm-helpers: Add resource managed version of mutex
 init
In-Reply-To: <4a545c16-7518-49d2-b158-7fcabe3508c5@roeck-us.net>
References: <20240222145838.12916-1-kabel@kernel.org>
 <4a545c16-7518-49d2-b158-7fcabe3508c5@roeck-us.net>
Message-ID: <e610c9b6-0491-42ac-90a1-00c547741773@roeck-us.net>

Oops, sorry for the noise. Shortened reply below.

On 2/22/24 07:24, Guenter Roeck wrote:
> On 2/22/24 06:58, Marek Beh?n wrote:
>> A few drivers are doing resource-managed mutex initialization by
>> implementing ad-hoc one-liner mutex dropping functions and using them
>> with devm_add_action_or_reset(). Help drivers avoid these repeated
>> one-liners by adding managed version of mutex initialization.
>>

[ ... ]

>> +static inline int devm_mutex_init(struct device *dev, struct mutex *lock)
>> +{
>> +??? mutex_init(lock);
>> +
>> +??? /*
>> +???? * mutex_destroy() is an empty function if CONFIG_DEBUG_MUTEXES is
>> +???? * disabled. No need to allocate an action in that case.
>> +???? */
>> +??? if (IS_ENABLED(CONFIG_DEBUG_MUTEXES))
>> +??????? return devm_add_action_or_reset(dev, devm_mutex_drop, lock);
>> +??? else
> 
> else after return is unnecessary.
> 
>> +??????? return 0;
>> +}
>> +
>> ? #endif
> 
> 



From arnd at arndb.de  Thu Feb 22 08:04:43 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 22 Feb 2024 17:04:43 +0100
Subject: [PATCH -next] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
In-Reply-To: <4e9396ca-460b-49ca-818e-73f0a8997b15@huawei.com>
References: <20240220081527.23408-1-liuyuntao12@huawei.com>
 <1342759e-b967-4ec4-98d5-48146f81f695@app.fastmail.com>
 <38c09a4b-69cc-4dc5-8a68-e5f5597613ac@huawei.com>
 <30b01c65-12f2-4ee0-81d5-c7a2da2c36b4@app.fastmail.com>
 <4e9396ca-460b-49ca-818e-73f0a8997b15@huawei.com>
Message-ID: <58297ee9-4f33-4b3b-bd00-b44e86965892@app.fastmail.com>

On Thu, Feb 22, 2024, at 12:24, liuyuntao (F) wrote:
>
> The position of the caret has been moved below the right brace
> of { KEEP(*(.vectors.bhb.loop8)) }, indicating that lld is treating
> the entire `KEEP(*(.vectors))` as a file name. This could potentially be 
> a bug in lld. Perhaps we can temporarily
> enable the DCE option only when option LD_IS_LLD is disabled,
> like risc-v:
>
> `select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if !LD_IS_LLD`.

I would really like to see this working with lld if at all
possible, as it allows the combination of gc-sections with
lto and CONFIG_TRIM_UNUSED_KSYMS.

I experimented with lld myself now and I did get a booting
kernel even without the the KEEP() on the vectors. I also
see that this is the only use of OVERLAY in the kernel, so
I hope that we can find a way to make it work with existing
lld after all, either without the KEEP or without the OVERLAY.

Did you see any problems without the KEEP() on the vectors?

     Arnd


From balint.dobszay at arm.com  Thu Feb 22 08:20:33 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Thu, 22 Feb 2024 17:20:33 +0100
Subject: [PATCH 2/3] tee: tstee: Add Trusted Services TEE driver
In-Reply-To: <ed8aaee7-be14-43ab-981c-d2ac04f4fc71@kernel.org>
References: <20240213145239.379875-1-balint.dobszay@arm.com>
 <20240213145239.379875-3-balint.dobszay@arm.com>
 <ed8aaee7-be14-43ab-981c-d2ac04f4fc71@kernel.org>
Message-ID: <D4EFA956-1E7B-4DDD-AC0A-D2F3217D46F0@arm.com>

Hi Krzysztof,

Thanks for the feedback.

On 15 Feb 2024, at 9:59, Krzysztof Kozlowski wrote:

> On 13/02/2024 15:52, Balint Dobszay wrote:
>> The Trusted Services project provides a framework for developing and
>> deploying device Root of Trust services in FF-A Secure Partitions. The
>> FF-A SPs are accessible through the FF-A driver, but this doesn't
>> provide a user space interface. The goal of this TEE driver is to make
>> Trusted Services SPs accessible for user space clients.
>>
>> All TS SPs have the same FF-A UUID, it identifies the RPC protocol used
>> by TS. A TS SP can host one or more services, a service is identified by
>> its service UUID. The same type of service cannot be present twice in
>> the same SP. During SP boot each service in an SP is assigned an
>> interface ID, this is just a short ID to simplify message addressing.
>> There is 1:1 mapping between TS SPs and TEE devices, i.e. a separate TEE
>> device is registered for each TS SP. This is required since contrary to
>> the generic TEE design where memory is shared with the whole TEE
>> implementation, in case of FF-A, memory is shared with a specific SP. A
>> user space client has to be able to separately share memory with each SP
>> based on its endpoint ID.
>>
>> Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
>> ---
>
>
>> +static int tstee_probe(struct ffa_device *ffa_dev)
>> +{
>> +	struct tstee *tstee;
>> +	int rc;
>> +
>> +	ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev);
>> +
>> +	if (!tstee_check_rpc_compatible(ffa_dev))
>> +		return -EINVAL;
>> +
>> +	tstee = kzalloc(sizeof(*tstee), GFP_KERNEL);
>> +	if (!tstee)
>> +		return -ENOMEM;
>> +
>> +	tstee->ffa_dev = ffa_dev;
>> +
>> +	tstee->pool = tstee_create_shm_pool();
>> +	if (IS_ERR(tstee->pool)) {
>> +		rc = PTR_ERR(tstee->pool);
>> +		tstee->pool = NULL;
>> +		goto err;
>
> Is it logically correct to call here tee_device_unregister()?

As Jens mentioned it doesn't cause any issues. But I see you point, it's
not logically correct. I'll refactor this.

>> +	}
>> +
>> +	tstee->teedev = tee_device_alloc(&tstee_desc, NULL, tstee->pool, tstee);
>> +	if (IS_ERR(tstee->teedev)) {
>> +		rc = PTR_ERR(tstee->teedev);
>> +		tstee->teedev = NULL;
>> +		goto err;
>> +	}
>> +
>> +	rc = tee_device_register(tstee->teedev);
>> +	if (rc)
>> +		goto err;
>> +
>> +	ffa_dev_set_drvdata(ffa_dev, tstee);
>> +
>> +	pr_info("driver initialized for endpoint 0x%x\n", ffa_dev->vm_id);
>
> Don't print simple probe success messages. Anyway all prints in device
> context should be dev_*.

Okay, I'll remove this.

>> +
>> +	return 0;
>> +
>> +err:
>> +	tstee_deinit_common(tstee);
>> +	return rc;
>> +}
>> +
>> +static void tstee_remove(struct ffa_device *ffa_dev)
>> +{
>> +	tstee_deinit_common(ffa_dev->dev.driver_data);
>> +}
>> +
>> +static const struct ffa_device_id tstee_device_ids[] = {
>> +	/* TS RPC protocol UUID: bdcd76d7-825e-4751-963b-86d4f84943ac */
>> +	{ TS_RPC_UUID },
>> +	{}
>> +};
>> +
>> +static struct ffa_driver tstee_driver = {
>> +	.name = "arm_tstee",
>> +	.probe = tstee_probe,
>> +	.remove = tstee_remove,
>> +	.id_table = tstee_device_ids,
>> +};
>> +
>> +static int __init mod_init(void)
>> +{
>> +	return ffa_register(&tstee_driver);
>> +}
>> +module_init(mod_init)
>> +
>> +static void __exit mod_exit(void)
>> +{
>> +	ffa_unregister(&tstee_driver);
>> +}
>> +module_exit(mod_exit)
>> +
>> +MODULE_ALIAS("arm-tstee");
>
> Why do you need this alias? I don't see MODULE_DEVICE_TABLE, so how this
> bus handles module loading?

You're right, the alias is not needed, I'll remove it.
Regarding MODULE_DEVICE_TABLE, AFAIK this mechanism is currently not
supported for the arm_ffa bus type. Maybe Sudeep can chime in on this?

Regards,
Balint


From william.zhang at broadcom.com  Thu Feb 22 08:21:10 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 08:21:10 -0800
Subject: [PATCH v5 05/12] arm64: dts: broadcom: bcmbca: Add NAND
 controller node
In-Reply-To: <cd32d304d740e3c1875e449d459c805a@milecki.pl>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-6-william.zhang@broadcom.com>
 <cd32d304d740e3c1875e449d459c805a@milecki.pl>
Message-ID: <e32c59d7-62bd-4a8d-b2ae-0d73d2f6d90c@broadcom.com>

Hi Rafal,

On 2/22/24 00:27, Rafa? Mi?ecki wrote:
> On 2024-02-07 21:22, William Zhang wrote:
>> diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
>> b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
>> index 2f124b027bbf..336016e334d9 100644
>> --- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
>> +++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
>> @@ -589,7 +589,7 @@ hsspi: spi at 1000 {
>> ???????????? status = "disabled";
>> ???????? };
>>
>> -??????? nand-controller at 1800 {
>> +??????? nand_controller: nand-controller at 1800 {
>> ???????????? #address-cells = <1>;
>> ???????????? #size-cells = <0>;
>> ???????????? compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", 
>> "brcm,brcmnand";
>> @@ -597,7 +597,7 @@ nand-controller at 1800 {
>> ???????????? reg-names = "nand", "nand-int-base";
>> ???????????? interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
>> ???????????? interrupt-names = "nand_ctlrdy";
>> -??????????? status = "okay";
>> +??????????? status = "disabled";
>>
>> ???????????? nandcs: nand at 0 {
>> ???????????????? compatible = "brcm,nandcs";
> 
> You disable NAND controller here breaking support for all dependant
> devices.
> 
> I see you fix it afterwards in PATCH 06/12 but it's still a poor way of
> handling such change and this issue can be hit e.g. during git bisect.
> 
> Also: given that 99% of BCM4908 devices use NAND controller can we just
> save ourselves efforts and keep it enabled in .dtsi?
> 
I was trying to fix this according to the dts convention per 
maintainers' requirement(only enable the node in the board dts, not soc 
include). We have 100% of BCMBCA devices use strap for ecc but we still 
have to put the property in board dts.
I understand if someone try to bisect the commits, it may hit the 
problem but this will be very obvious that controller is not even shown 
in the boot up so hopefully it is easy to figure out.  Anyway if 
maintainer(Minque and/or anyone from device tree side) is okay with your 
request, I can change it back to enable in the dtsi.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240222/6b9cbcfc/attachment-0001.p7s>

From brgl at bgdev.pl  Thu Feb 22 08:24:19 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 22 Feb 2024 17:24:19 +0100
Subject: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
In-Reply-To: <7pybw4wxlzxfl65yuqxzks5w7uq52hosyq53etlzas6i6o5l6d@vxd4sykcxora>
References: <20240205182810.58382-1-brgl@bgdev.pl> <20240205182810.58382-11-brgl@bgdev.pl>
 <7pybw4wxlzxfl65yuqxzks5w7uq52hosyq53etlzas6i6o5l6d@vxd4sykcxora>
Message-ID: <CAMRc=MfTtcFb=7vDfkFiaPYvb+o6o4zd_RnYd2om+cAiaKY2dQ@mail.gmail.com>

On Sun, Feb 18, 2024 at 4:41?AM Bjorn Andersson <andersson at kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >

[snip]

> >
> > +config QCOM_TZMEM_MODE_SHMBRIDGE
> > +     bool "SHM Bridge"
> > +     help
> > +       Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
> > +       in the 'Default' allocator but is also explicitly marked as an SHM Bridge
> > +       buffer.
> > +
> > +       With this selected, all buffers passed to the TrustZone must be allocated
> > +       using the TZMem allocator or else the TrustZone will refuse to use them.
>
> It's funny how this is the only place in the whole series I can find
> this mentioned. One could from this statement guess that the eluding
> scminvoke requires shmbridge and that this patch series exists solely
> to facilitate the requirement stated in this paragraph.
>

Yes, scminvoke *requires* SHM bridge. So does the wrapped key support.
No, this is not the only reason as - as stated by Srini - it improves
overall safety of the system for all users.

> Either this guess is correct and this should have been made clear in
> the commit messages, or I'm guessing wrong here, in which case I need
> some help to figure out why this series exists.
>

This series exists and IMO should get upstream soon to facilitate
adding new security features (in addition to improving existing ones).
As there are at least two such features in development (mentioned
above) pushing this series upstream will make it easier to develop
them independently.

Bart

[snip]


From lkp at intel.com  Thu Feb 22 08:25:23 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 23 Feb 2024 00:25:23 +0800
Subject: [PATCH 3/3] arch: Rename fbdev header and source files
In-Reply-To: <20240221161431.8245-4-tzimmermann@suse.de>
References: <20240221161431.8245-4-tzimmermann@suse.de>
Message-ID: <202402230023.xa2jjwui-lkp@intel.com>

Hi Thomas,

kernel test robot noticed the following build errors:

[auto build test ERROR on tip/x86/core]
[also build test ERROR on deller-parisc/for-next arnd-asm-generic/master linus/master v6.8-rc5 next-20240221]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Thomas-Zimmermann/arch-Select-fbdev-helpers-with-CONFIG_VIDEO/20240222-001622
base:   tip/x86/core
patch link:    https://lore.kernel.org/r/20240221161431.8245-4-tzimmermann%40suse.de
patch subject: [PATCH 3/3] arch: Rename fbdev header and source files
config: um-randconfig-r052-20240222 (https://download.01.org/0day-ci/archive/20240223/202402230023.xa2jjwui-lkp at intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240223/202402230023.xa2jjwui-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402230023.xa2jjwui-lkp at intel.com/

All errors (new ones prefixed by >>):

   /usr/bin/ld: drivers/video/fbdev/core/fb_io_fops.o: in function `fb_io_mmap':
>> fb_io_fops.c:(.text+0x591): undefined reference to `pgprot_framebuffer'
   collect2: error: ld returned 1 exit status

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From maz at kernel.org  Thu Feb 22 08:28:27 2024
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 22 Feb 2024 16:28:27 +0000
Subject: [PATCH v12 02/25] genirq/irqdomain: Remove the param count restriction from select()
In-Reply-To: <e42b76a9-fc5f-4ab7-96a2-629261a9c983@arm.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
	<20240127161753.114685-3-apatel@ventanamicro.com>
	<e42b76a9-fc5f-4ab7-96a2-629261a9c983@arm.com>
Message-ID: <87edd4a2fo.wl-maz@kernel.org>

On Thu, 22 Feb 2024 13:01:32 +0000,
Aishwarya TCV <aishwarya.tcv at arm.com> wrote:
> 
> 
> 
> On 27/01/2024 16:17, Anup Patel wrote:
> > From: Thomas Gleixner <tglx at linutronix.de>
> > 
> > Now that the GIC-v3 callback can handle invocation with a fwspec parameter
> > count of 0 lift the restriction in the core code and invoke select()
> > unconditionally when the domain provides it.
> > 
> > Preparatory change for per device MSI domains.
> > 
> > Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> > ---
> 
> Hi Thomas/Anup
> 
> Currently when booting the kernel against next-master(next-20240222)
> with Arm64 on Qualcomm boards RB5/DB845C, the kernel is resulting in
> boot failures for our CI. I can send the full logs if required. Most
> other boards seem to be fine.
> 
> A bisect (full log below) identified this patch as introducing the
> failure. Bisected it on the tag "next-20240220" at repo
> "https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git".
> 
> This works fine on Linux v6.8-rc5

Can you please try [1]?

	M.

[1] https://lore.kernel.org/linux-kernel/20240220114731.1898534-1-maz at kernel.org

-- 
Without deviation from the norm, progress is not possible.


From sam at ravnborg.org  Thu Feb 22 08:35:26 2024
From: sam at ravnborg.org (Sam Ravnborg)
Date: Thu, 22 Feb 2024 17:35:26 +0100
Subject: [PATCH v8 0/7] Add support for XLCDC to sam9x7 SoC family.
In-Reply-To: <20240221053531.12701-1-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
Message-ID: <20240222163526.GA2576040@ravnborg.org>

On Wed, Feb 21, 2024 at 11:05:24AM +0530, Manikandan Muralidharan wrote:
> This patch series aims to add support for XLCDC IP of sam9x7 SoC family
> to the DRM subsystem.XLCDC IP has additional registers and new
> configuration bits compared to the existing register set of HLCDC IP.
> The new compatible string "microchip,sam9x75-xlcdc" is defined for sam9x75
> variant of the sam9x7 SoC family.The is_xlcdc flag under driver data and
> IP specific driver ops helps to differentiate the XLCDC and existing HLCDC
> code within the same driver.
> 
> changes in v8:
> * Re-arrange the patch set to prepare and update the current HLCDC
> code base with the new LCDC IP based driver ops and then add support
> for XLCDC code changes.
> * Fix Cosmetic issues.
> 
> changes in v7:
> * LCDC IP driver ops functions are declared static and its 
> declaration are removed.
> 
> changes in v6:
> * Fixed Cosmetic defects.
> * Added comments for readability.
> 
> changes in v5:
> * return value of regmap_read_poll_timeout is checked in failure
> case.
> * HLCDC and XLCDC specific driver functions are now invoked
> using its IP specific driver ops w/o the need of checking is_xlcdc flag.
> * Removed empty spaces and blank lines.
> 
> changes in v4:
> * fixed kernel warnings reported by kernel test robot.
> 
> changes in v3:
> * Removed de-referencing the value of is_xlcdc flag multiple times in
> a single function.
> * Removed cpu_relax() call when using regmap_read_poll_timeout.
> * Updated xfactor and yfactor equations using shift operators
> * Defined CSC co-efficients in an array for code readability.
> 
> changes in v2:
> * Change the driver compatible name from "microchip,sam9x7-xlcdc" to
> "microchip,sam9x75-xlcdc".
> * Move is_xlcdc flag to driver data.
> * Remove unsed Macro definitions.
> * Add co-developed-bys tags
> * Replace regmap_read() with regmap_read_poll_timeout() call
> * Split code into two helpers for code readablitity.
> ---
> 
> Durai Manickam KR (1):
>   drm: atmel-hlcdc: Define XLCDC specific registers
> 
> Manikandan Muralidharan (6):
>   drm: atmel-hlcdc: add driver ops to differentiate HLCDC and XLCDC IP
>   drm: atmel_hlcdc: Add support for XLCDC using IP specific driver ops
>   drm: atmel-hlcdc: add DPI mode support for XLCDC
>   drm: atmel-hlcdc: add vertical and horizontal scaling support for
>     XLCDC
>   drm: atmel-hlcdc: add support for DSI output formats
>   drm: atmel-hlcdc: add LCD controller layer definition for sam9x75

Hi Manikandan

thanks for your paitent follow-up on this patch set.
Everything looks good and all patches are:
Acked-by: Sam Ravnborg <sam at ravnborg.org>

We are at v8 now and if there are additional comments we can handle them
in-tree.
I have asked Thomas Zimmermann to apply the patches to drm-misc as I
have lost my push infrastructure atm.

	Sam


From andriy.shevchenko at linux.intel.com  Thu Feb 22 08:43:07 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 22 Feb 2024 18:43:07 +0200
Subject: [PATCH v1 10/14] serial: 8250_of: Switch to use
 uart_read_port_properties()
In-Reply-To: <ZddKzHplwOX7naLv@smile.fi.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-11-andriy.shevchenko@linux.intel.com>
 <0a828f2c50de712940fb9a881702ac1678a35b7c.camel@codeconstruct.com.au>
 <ZddKzHplwOX7naLv@smile.fi.intel.com>
Message-ID: <Zdd5m2xIPlGI0_Qv@smile.fi.intel.com>

On Thu, Feb 22, 2024 at 03:23:24PM +0200, Andy Shevchenko wrote:
> On Thu, Feb 22, 2024 at 11:07:05AM +1030, Andrew Jeffery wrote:
> > On Wed, 2024-02-21 at 20:31 +0200, Andy Shevchenko wrote:
> > > Since we have now a common helper to read port properties
> > > use it instead of sparse home grown solution.
> > 
> > I did some brief testing of the series for the Aspeed machines under
> > qemu, building them on top of v6.8-rc5:
> > 
> > export ARCH=arm
> > export CROSS_COMPILE=arm-linux-gnueabihf-
> > make aspeed_g5_defconfig
> > make -j$(nproc)
> > qemu-system-arm -M rainier-bmc -nographic -no-reboot -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dtb -initrd ...
> > 
> > I got an oops during boot, which bisected to this change:
> 
> Thank you for prompt testing! I will look at it.

I found the issue, will be fixed in next version.

-- 
With Best Regards,
Andy Shevchenko




From matthew.auld at intel.com  Thu Feb 22 08:44:06 2024
From: matthew.auld at intel.com (Matthew Auld)
Date: Thu, 22 Feb 2024 16:44:06 +0000
Subject: [PATCH 1/2] devm-helpers: Add resource managed version of mutex
 init
In-Reply-To: <20240222145838.12916-1-kabel@kernel.org>
References: <20240222145838.12916-1-kabel@kernel.org>
Message-ID: <03e62bcf-137c-4947-8f34-0cbfcba92a30@intel.com>

On 22/02/2024 14:58, Marek Beh?n wrote:
> A few drivers are doing resource-managed mutex initialization by
> implementing ad-hoc one-liner mutex dropping functions and using them
> with devm_add_action_or_reset(). Help drivers avoid these repeated
> one-liners by adding managed version of mutex initialization.
> 
> Use the new function devm_mutex_init() in the following drivers:
>    drivers/gpio/gpio-pisosr.c
>    drivers/gpio/gpio-sim.c
>    drivers/gpu/drm/xe/xe_hwmon.c
>    drivers/hwmon/nzxt-smart2.c
>    drivers/leds/leds-is31fl319x.c
>    drivers/power/supply/mt6370-charger.c
>    drivers/power/supply/rt9467-charger.c
> 
> Signed-off-by: Marek Beh?n <kabel at kernel.org>
> ---
>   drivers/gpio/gpio-pisosr.c            |  9 ++-----
>   drivers/gpio/gpio-sim.c               | 12 ++--------
>   drivers/gpu/drm/xe/xe_hwmon.c         | 11 ++-------
>   drivers/hwmon/nzxt-smart2.c           |  9 ++-----
>   drivers/leds/leds-is31fl319x.c        |  9 ++-----
>   drivers/power/supply/mt6370-charger.c | 11 +--------
>   drivers/power/supply/rt9467-charger.c | 34 ++++-----------------------
>   include/linux/devm-helpers.h          | 32 +++++++++++++++++++++++++
>   8 files changed, 47 insertions(+), 80 deletions(-)
> 
> diff --git a/drivers/gpio/gpio-pisosr.c b/drivers/gpio/gpio-pisosr.c
> index e3013e778e15..dddbf37e855f 100644
> --- a/drivers/gpio/gpio-pisosr.c
> +++ b/drivers/gpio/gpio-pisosr.c
> @@ -7,6 +7,7 @@
>   #include <linux/bitmap.h>
>   #include <linux/bitops.h>
>   #include <linux/delay.h>
> +#include <linux/devm-helpers.h>
>   #include <linux/gpio/consumer.h>
>   #include <linux/gpio/driver.h>
>   #include <linux/module.h>
> @@ -116,11 +117,6 @@ static const struct gpio_chip template_chip = {
>   	.can_sleep		= true,
>   };
>   
> -static void pisosr_mutex_destroy(void *lock)
> -{
> -	mutex_destroy(lock);
> -}
> -
>   static int pisosr_gpio_probe(struct spi_device *spi)
>   {
>   	struct device *dev = &spi->dev;
> @@ -147,8 +143,7 @@ static int pisosr_gpio_probe(struct spi_device *spi)
>   		return dev_err_probe(dev, PTR_ERR(gpio->load_gpio),
>   				     "Unable to allocate load GPIO\n");
>   
> -	mutex_init(&gpio->lock);
> -	ret = devm_add_action_or_reset(dev, pisosr_mutex_destroy, &gpio->lock);
> +	ret = devm_mutex_init(dev, &gpio->lock);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c
> index c4106e37e6db..fcfcaa4efe70 100644
> --- a/drivers/gpio/gpio-sim.c
> +++ b/drivers/gpio/gpio-sim.c
> @@ -12,6 +12,7 @@
>   #include <linux/completion.h>
>   #include <linux/configfs.h>
>   #include <linux/device.h>
> +#include <linux/devm-helpers.h>
>   #include <linux/err.h>
>   #include <linux/gpio/consumer.h>
>   #include <linux/gpio/driver.h>
> @@ -307,13 +308,6 @@ static ssize_t gpio_sim_sysfs_pull_store(struct device *dev,
>   	return len;
>   }
>   
> -static void gpio_sim_mutex_destroy(void *data)
> -{
> -	struct mutex *lock = data;
> -
> -	mutex_destroy(lock);
> -}
> -
>   static void gpio_sim_put_device(void *data)
>   {
>   	struct device *dev = data;
> @@ -457,9 +451,7 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev)
>   	if (ret)
>   		return ret;
>   
> -	mutex_init(&chip->lock);
> -	ret = devm_add_action_or_reset(dev, gpio_sim_mutex_destroy,
> -				       &chip->lock);
> +	ret = devm_mutex_init(dev, &chip->lock);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
> index 174ed2185481..bb88ae1c196c 100644
> --- a/drivers/gpu/drm/xe/xe_hwmon.c
> +++ b/drivers/gpu/drm/xe/xe_hwmon.c
> @@ -3,6 +3,7 @@
>    * Copyright ? 2023 Intel Corporation
>    */
>   
> +#include <linux/devm-helpers.h>
>   #include <linux/hwmon-sysfs.h>
>   #include <linux/hwmon.h>
>   #include <linux/types.h>
> @@ -729,13 +730,6 @@ xe_hwmon_get_preregistration_info(struct xe_device *xe)
>   		xe_hwmon_energy_get(hwmon, &energy);
>   }
>   
> -static void xe_hwmon_mutex_destroy(void *arg)
> -{
> -	struct xe_hwmon *hwmon = arg;
> -
> -	mutex_destroy(&hwmon->hwmon_lock);
> -}
> -
>   void xe_hwmon_register(struct xe_device *xe)
>   {
>   	struct device *dev = xe->drm.dev;
> @@ -751,8 +745,7 @@ void xe_hwmon_register(struct xe_device *xe)
>   
>   	xe->hwmon = hwmon;
>   
> -	mutex_init(&hwmon->hwmon_lock);
> -	if (devm_add_action_or_reset(dev, xe_hwmon_mutex_destroy, hwmon))
> +	if (devm_mutex_init(dev, &hwmon->hwmon_lock))
>   		return;
>   
>   	/* primary GT to access device level properties */
> diff --git a/drivers/hwmon/nzxt-smart2.c b/drivers/hwmon/nzxt-smart2.c
> index 7aa586eb74be..00bc89607673 100644
> --- a/drivers/hwmon/nzxt-smart2.c
> +++ b/drivers/hwmon/nzxt-smart2.c
> @@ -5,6 +5,7 @@
>    * Copyright (c) 2021 Aleksandr Mezin
>    */
>   
> +#include <linux/devm-helpers.h>
>   #include <linux/hid.h>
>   #include <linux/hwmon.h>
>   #include <linux/math.h>
> @@ -721,11 +722,6 @@ static int __maybe_unused nzxt_smart2_hid_reset_resume(struct hid_device *hdev)
>   	return init_device(drvdata, drvdata->update_interval);
>   }
>   
> -static void mutex_fini(void *lock)
> -{
> -	mutex_destroy(lock);
> -}
> -
>   static int nzxt_smart2_hid_probe(struct hid_device *hdev,
>   				 const struct hid_device_id *id)
>   {
> @@ -741,8 +737,7 @@ static int nzxt_smart2_hid_probe(struct hid_device *hdev,
>   
>   	init_waitqueue_head(&drvdata->wq);
>   
> -	mutex_init(&drvdata->mutex);
> -	ret = devm_add_action_or_reset(&hdev->dev, mutex_fini, &drvdata->mutex);
> +	ret = devm_mutex_init(&hdev->dev, &drvdata->mutex);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/leds/leds-is31fl319x.c b/drivers/leds/leds-is31fl319x.c
> index 66c65741202e..e9d7cf6a386c 100644
> --- a/drivers/leds/leds-is31fl319x.c
> +++ b/drivers/leds/leds-is31fl319x.c
> @@ -8,6 +8,7 @@
>    * effect LEDs.
>    */
>   
> +#include <linux/devm-helpers.h>
>   #include <linux/err.h>
>   #include <linux/i2c.h>
>   #include <linux/leds.h>
> @@ -495,11 +496,6 @@ static inline int is31fl3196_db_to_gain(u32 dezibel)
>   	return dezibel / IS31FL3196_AUDIO_GAIN_DB_STEP;
>   }
>   
> -static void is31f1319x_mutex_destroy(void *lock)
> -{
> -	mutex_destroy(lock);
> -}
> -
>   static int is31fl319x_probe(struct i2c_client *client)
>   {
>   	struct is31fl319x_chip *is31;
> @@ -515,8 +511,7 @@ static int is31fl319x_probe(struct i2c_client *client)
>   	if (!is31)
>   		return -ENOMEM;
>   
> -	mutex_init(&is31->lock);
> -	err = devm_add_action_or_reset(dev, is31f1319x_mutex_destroy, &is31->lock);
> +	err = devm_mutex_init(dev, &is31->lock);
>   	if (err)
>   		return err;
>   
> diff --git a/drivers/power/supply/mt6370-charger.c b/drivers/power/supply/mt6370-charger.c
> index e24fce087d80..fa0517d0352d 100644
> --- a/drivers/power/supply/mt6370-charger.c
> +++ b/drivers/power/supply/mt6370-charger.c
> @@ -766,13 +766,6 @@ static int mt6370_chg_init_psy(struct mt6370_priv *priv)
>   	return PTR_ERR_OR_ZERO(priv->psy);
>   }
>   
> -static void mt6370_chg_destroy_attach_lock(void *data)
> -{
> -	struct mutex *attach_lock = data;
> -
> -	mutex_destroy(attach_lock);
> -}
> -
>   static void mt6370_chg_destroy_wq(void *data)
>   {
>   	struct workqueue_struct *wq = data;
> @@ -900,9 +893,7 @@ static int mt6370_chg_probe(struct platform_device *pdev)
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to init psy\n");
>   
> -	mutex_init(&priv->attach_lock);
> -	ret = devm_add_action_or_reset(dev, mt6370_chg_destroy_attach_lock,
> -				       &priv->attach_lock);
> +	ret = devm_mutex_init(dev, &priv->attach_lock);
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to init attach lock\n");
>   
> diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c
> index fdfdc83ab045..84f07c22077f 100644
> --- a/drivers/power/supply/rt9467-charger.c
> +++ b/drivers/power/supply/rt9467-charger.c
> @@ -10,6 +10,7 @@
>   #include <linux/bitfield.h>
>   #include <linux/completion.h>
>   #include <linux/delay.h>
> +#include <linux/devm-helpers.h>
>   #include <linux/gpio/consumer.h>
>   #include <linux/i2c.h>
>   #include <linux/interrupt.h>
> @@ -1149,27 +1150,6 @@ static int rt9467_reset_chip(struct rt9467_chg_data *data)
>   	return regmap_field_write(data->rm_field[F_RST], 1);
>   }
>   
> -static void rt9467_chg_destroy_adc_lock(void *data)
> -{
> -	struct mutex *adc_lock = data;
> -
> -	mutex_destroy(adc_lock);
> -}
> -
> -static void rt9467_chg_destroy_attach_lock(void *data)
> -{
> -	struct mutex *attach_lock = data;
> -
> -	mutex_destroy(attach_lock);
> -}
> -
> -static void rt9467_chg_destroy_ichg_ieoc_lock(void *data)
> -{
> -	struct mutex *ichg_ieoc_lock = data;
> -
> -	mutex_destroy(ichg_ieoc_lock);
> -}
> -
>   static void rt9467_chg_complete_aicl_done(void *data)
>   {
>   	struct completion *aicl_done = data;
> @@ -1222,21 +1202,15 @@ static int rt9467_charger_probe(struct i2c_client *i2c)
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to add irq chip\n");
>   
> -	mutex_init(&data->adc_lock);
> -	ret = devm_add_action_or_reset(dev, rt9467_chg_destroy_adc_lock,
> -				       &data->adc_lock);
> +	ret = devm_mutex_init(dev, &data->adc_lock);
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to init ADC lock\n");
>   
> -	mutex_init(&data->attach_lock);
> -	ret = devm_add_action_or_reset(dev, rt9467_chg_destroy_attach_lock,
> -				       &data->attach_lock);
> +	ret = devm_mutex_init(dev, &data->attach_lock);
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to init attach lock\n");
>   
> -	mutex_init(&data->ichg_ieoc_lock);
> -	ret = devm_add_action_or_reset(dev, rt9467_chg_destroy_ichg_ieoc_lock,
> -				       &data->ichg_ieoc_lock);
> +	ret = devm_mutex_init(dev, &data->ichg_ieoc_lock);
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Failed to init ICHG/IEOC lock\n");
>   
> diff --git a/include/linux/devm-helpers.h b/include/linux/devm-helpers.h
> index 74891802200d..70640fb96117 100644
> --- a/include/linux/devm-helpers.h
> +++ b/include/linux/devm-helpers.h
> @@ -24,6 +24,8 @@
>    */
>   
>   #include <linux/device.h>
> +#include <linux/kconfig.h>
> +#include <linux/mutex.h>
>   #include <linux/workqueue.h>
>   
>   static inline void devm_delayed_work_drop(void *res)
> @@ -76,4 +78,34 @@ static inline int devm_work_autocancel(struct device *dev,
>   	return devm_add_action(dev, devm_work_drop, w);
>   }
>   
> +static inline void devm_mutex_drop(void *res)
> +{
> +	mutex_destroy(res);
> +}
> +
> +/**
> + * devm_mutex_init - Resource managed mutex initialization
> + * @dev:	Device which lifetime mutex is bound to
> + * @lock:	Mutex to be initialized (and automatically destroyed)
> + *
> + * Initialize mutex which is automatically destroyed when driver is detached.
> + * A few drivers initialize mutexes which they want destroyed before driver is
> + * detached, for debugging purposes.
> + * devm_mutex_init() can be used to omit the explicit mutex_destroy() call when
> + * driver is detached.
> + */
> +static inline int devm_mutex_init(struct device *dev, struct mutex *lock)
> +{
> +	mutex_init(lock);

Do you know if this this needs __always_inline? The static lockdep key 
in mutex_init() should be different for each caller class. See 
c21f11d182c2 ("drm: fix drmm_mutex_init()").

> +
> +	/*
> +	 * mutex_destroy() is an empty function if CONFIG_DEBUG_MUTEXES is
> +	 * disabled. No need to allocate an action in that case.
> +	 */
> +	if (IS_ENABLED(CONFIG_DEBUG_MUTEXES))
> +		return devm_add_action_or_reset(dev, devm_mutex_drop, lock);
> +	else
> +		return 0;
> +}
> +
>   #endif


From andriy.shevchenko at linux.intel.com  Thu Feb 22 08:47:18 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 22 Feb 2024 18:47:18 +0200
Subject: [PATCH v1 10/14] serial: 8250_of: Switch to use
 uart_read_port_properties()
In-Reply-To: <Zdd5m2xIPlGI0_Qv@smile.fi.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-11-andriy.shevchenko@linux.intel.com>
 <0a828f2c50de712940fb9a881702ac1678a35b7c.camel@codeconstruct.com.au>
 <ZddKzHplwOX7naLv@smile.fi.intel.com>
 <Zdd5m2xIPlGI0_Qv@smile.fi.intel.com>
Message-ID: <Zdd6lnXwvpPPUhRR@smile.fi.intel.com>

On Thu, Feb 22, 2024 at 06:43:08PM +0200, Andy Shevchenko wrote:
> On Thu, Feb 22, 2024 at 03:23:24PM +0200, Andy Shevchenko wrote:
> > On Thu, Feb 22, 2024 at 11:07:05AM +1030, Andrew Jeffery wrote:
> > > On Wed, 2024-02-21 at 20:31 +0200, Andy Shevchenko wrote:
> > > > Since we have now a common helper to read port properties
> > > > use it instead of sparse home grown solution.
> > > 
> > > I did some brief testing of the series for the Aspeed machines under
> > > qemu, building them on top of v6.8-rc5:
> > > 
> > > export ARCH=arm
> > > export CROSS_COMPILE=arm-linux-gnueabihf-
> > > make aspeed_g5_defconfig
> > > make -j$(nproc)
> > > qemu-system-arm -M rainier-bmc -nographic -no-reboot -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dtb -initrd ...
> > > 
> > > I got an oops during boot, which bisected to this change:
> > 
> > Thank you for prompt testing! I will look at it.
> 
> I found the issue, will be fixed in next version.

Whoever is going to test this series, the

-		port->iotype = use_defaults ? UPIO_MEM : port->iotype;
+		port->iotype = UPIO_MEM;

should be applied to uart_read_port_properties() implementation.

-- 
With Best Regards,
Andy Shevchenko




From namhyung at kernel.org  Thu Feb 22 09:02:04 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Thu, 22 Feb 2024 09:02:04 -0800
Subject: [PATCH v2] perf print-events: make is_event_supported() more robust
In-Reply-To: <CAP-5=fURS0OQxHcukS1+NprgyMpAQSr3+BMiYPj5x7=+tcZ8hw@mail.gmail.com>
References: <20240126145605.1005472-1-mark.rutland@arm.com> <CAP-5=fURS0OQxHcukS1+NprgyMpAQSr3+BMiYPj5x7=+tcZ8hw@mail.gmail.com>
Message-ID: <CAM9d7cj=tN8ACGFMmkdL_RE5R-4SCd8Zg3trJ15TvOJKpcXABQ@mail.gmail.com>

Hector and Marc, can you please take a look?

Thanks,
Namhyung


On Wed, Feb 21, 2024 at 12:19?PM Ian Rogers <irogers at google.com> wrote:
>
> On Fri, Jan 26, 2024 at 6:56?AM Mark Rutland <mark.rutland at arm.com> wrote:
> >
> > Currently the perf tool doesn't detect support for extended event types
> > on Apple M1/M2 systems, and will not auto-expand plain PERF_EVENT_TYPE
> > hardware events into per-PMU events. This is due to the detection of
> > extended event types not handling mandatory filters required by the
> > M1/M2 PMU driver.
> >
> > PMU drivers and the core perf_events code can require that
> > perf_event_attr::exclude_* filters are configured in a specific way and
> > may reject certain configurations of filters, for example:
> >
> > (a) Many PMUs lack support for any event filtering, and require all
> >     perf_event_attr::exclude_* bits to be clear. This includes Alpha's
> >     CPU PMU, and ARM CPU PMUs prior to the introduction of PMUv2 in
> >     ARMv7,
> >
> > (b) When /proc/sys/kernel/perf_event_paranoid >= 2, the perf core
> >     requires that perf_event_attr::exclude_kernel is set.
> >
> > (c) The Apple M1/M2 PMU requires that perf_event_attr::exclude_guest is
> >     set as the hardware PMU does not count while a guest is running (but
> >     might be extended in future to do so).
> >
> > In is_event_supported(), we try to account for cases (a) and (b), first
> > attempting to open an event without any filters, and if this fails,
> > retrying with perf_event_attr::exclude_kernel set. We do not account for
> > case (c), or any other filters that drivers could theoretically require
> > to be set.
> >
> > Thus is_event_supported() will fail to detect support for any events
> > targeting an Apple M1/M2 PMU, even where events would be supported with
> > perf_event_attr:::exclude_guest set.
> >
> > Since commit:
> >
> >   82fe2e45cdb00de4 ("perf pmus: Check if we can encode the PMU number in perf_event_attr.type")
> >
> > ... we use is_event_supported() to detect support for extended types,
> > with the PMU ID encoded into the perf_event_attr::type. As above, on an
> > Apple M1/M2 system this will always fail to detect that the event is
> > supported, and consequently we fail to detect support for extended types
> > even when these are supported, as they have been since commit:
> >
> >   5c816728651ae425 ("arm_pmu: Add PERF_PMU_CAP_EXTENDED_HW_TYPE capability")
> >
> > Due to this, the perf tool will not automatically expand plain
> > PERF_TYPE_HARDWARE events into per-PMU events, even when all the
> > necessary kernel support is present.
> >
> > This patch updates is_event_supported() to additionally try opening
> > events with perf_event_attr::exclude_guest set, allowing support for
> > events to be detected on Apple M1/M2 systems. I believe that this is
> > sufficient for all contemporary CPU PMU drivers, though in future it may
> > be necessary to check for other combinations of filter bits.
> >
> > I've deliberately changed the check to not expect a specific error code
> > for missing filters, as today ;the kernel may return a number of
> > different error codes for missing filters (e.g. -EACCESS, -EINVAL, or
> > -EOPNOTSUPP) depending on why and where the filter configuration is
> > rejected, and retrying for any error is more robust.
> >
> > Note that this does not remove the need for commit:
> >
> >   a24d9d9dc096fc0d ("perf parse-events: Make legacy events lower priority than sysfs/JSON")
> >
> > ... which is still necessary so that named-pmu/event/ events work on
> > kernels without extended type support, even if the event name happens to
> > be the same as a PERF_EVENT_TYPE_HARDWARE event (e.g. as is the case for
> > the M1/M2 PMU's 'cycles' and 'instructions' events).
> >
> > Fixes: 82fe2e45cdb00de4 ("perf pmus: Check if we can encode the PMU number in perf_event_attr.type")
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > Tested-by: Ian Rogers <irogers at google.com>
> > Tested-by: James Clark <james.clark at arm.com>
> > Cc: Arnaldo Carvalho de Melo <acme at redhat.com>
> > Cc: Hector Martin <marcan at marcan.st>
> > Cc: Ian Rogers <irogers at google.com>
> > Cc: James Clark <james.clark at arm.com>
> > Cc: John Garry <john.g.garry at oracle.com>
> > Cc: Leo Yan <leo.yan at linaro.org>
> > Cc: Marc Zyngier <maz at kernel.org>
> > Cc: Mike Leach <mike.leach at linaro.org>
> > Cc: Namhyung Kim <namhyung at kernel.org>
> > Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> > Cc: Thomas Richter <tmricht at linux.ibm.com>
> > Cc: Will Deacon <will at kernel.org>
>
> Ping. Could we land this one?
>
> Thanks,
> Ian
>
> > ---
> >  tools/perf/util/print-events.c | 27 +++++++++++++++++++--------
> >  1 file changed, 19 insertions(+), 8 deletions(-)
> >
> > Since v1 [1]:
> > * Fix typos in commit message
> > * Accumulate tags
> >
> > [1] https://lore.kernel.org/lkml/20240116170348.463479-1-mark.rutland at arm.com/
> >
> > Mark.
> >
> > diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
> > index b0fc48be623f3..4f67e8f00a4d6 100644
> > --- a/tools/perf/util/print-events.c
> > +++ b/tools/perf/util/print-events.c
> > @@ -232,7 +232,6 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
> >  bool is_event_supported(u8 type, u64 config)
> >  {
> >         bool ret = true;
> > -       int open_return;
> >         struct evsel *evsel;
> >         struct perf_event_attr attr = {
> >                 .type = type,
> > @@ -246,20 +245,32 @@ bool is_event_supported(u8 type, u64 config)
> >
> >         evsel = evsel__new(&attr);
> >         if (evsel) {
> > -               open_return = evsel__open(evsel, NULL, tmap);
> > -               ret = open_return >= 0;
> > +               ret = evsel__open(evsel, NULL, tmap) >= 0;
> >
> > -               if (open_return == -EACCES) {
> > +               if (!ret) {
> >                         /*
> > -                        * This happens if the paranoid value
> > +                        * The event may fail to open if the paranoid value
> >                          * /proc/sys/kernel/perf_event_paranoid is set to 2
> > -                        * Re-run with exclude_kernel set; we don't do that
> > -                        * by default as some ARM machines do not support it.
> > -                        *
> > +                        * Re-run with exclude_kernel set; we don't do that by
> > +                        * default as some ARM machines do not support it.
> >                          */
> >                         evsel->core.attr.exclude_kernel = 1;
> >                         ret = evsel__open(evsel, NULL, tmap) >= 0;
> >                 }
> > +
> > +               if (!ret) {
> > +                       /*
> > +                        * The event may fail to open if the PMU requires
> > +                        * exclude_guest to be set (e.g. as the Apple M1 PMU
> > +                        * requires).
> > +                        * Re-run with exclude_guest set; we don't do that by
> > +                        * default as it's equally legitimate for another PMU
> > +                        * driver to require that exclude_guest is clear.
> > +                        */
> > +                       evsel->core.attr.exclude_guest = 1;
> > +                       ret = evsel__open(evsel, NULL, tmap) >= 0;
> > +               }
> > +
> >                 evsel__delete(evsel);
> >         }
> >
> > --
> > 2.30.2
> >


From helgaas at kernel.org  Thu Feb 22 09:06:41 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 22 Feb 2024 11:06:41 -0600
Subject: [PATCH V3] PCI: Add support for preserving boot configuration
In-Reply-To: <20240222124110.2681455-1-vidyas@nvidia.com>
Message-ID: <20240222170641.GA15593@bhelgaas>

On Thu, Feb 22, 2024 at 06:11:10PM +0530, Vidya Sagar wrote:
> Add support for preserving the boot configuration done by the
> platform firmware per host bridge basis, based on the presence of
> 'linux,pci-probe-only' property in the respective PCIe host bridge
> device-tree node. It also unifies the ACPI and DT based boot flows
> in this regard.

> +/**
> + * of_pci_bridge_check_probe_only - Return true if the boot configuration
> + *                                  needs to be preserved

I don't like the "check_probe_only" name because it's a boolean
function but the name doesn't tell me what a true/false return value
means.  Something like "preserve_resources" would be better.  If you
want "probe_only", even removing the "check" would help.

> + * @node: Device tree node with the domain information.
> + *
> + * This function looks for "linux,pci-probe-only" property for a given
> + * PCIe controller's node and returns true if found. Having this property
> + * for a PCIe controller ensures that the kernel doesn't re-enumerate and
> + * reconfigure the BAR resources that are already done by the platform firmware.

This is generic PCI, not PCIe-specific (also in commit log and comment
below).

I think "enumeration" specifically refers to discovering what devices
are present, and the kernel always does that, so drop that part.
Reconfiguring BARs and bridge windows is what we want to prevent.

> + * NOTE: The scope of "linux,pci-probe-only" defined within a PCIe bridge device
> + *       is limited to the hierarchy under that particular bridge device. whereas
> + *       the scope of "linux,pci-probe-only" defined within chosen node is
> + *       system wide.
> + *
> + * Return: true if the property exists false otherwise.
> + */

> +bool of_pci_bridge_check_probe_only(struct device_node *node)
> +{
> +	return of_property_read_bool(node, "linux,pci-probe-only");
> +}
> +EXPORT_SYMBOL_GPL(of_pci_bridge_check_probe_only);

Why does this need to be exported for modules and exposed via
include/linux/pci.h?

> +static void pci_check_config_preserve(struct pci_host_bridge *host_bridge)
> +{
> +	if (&host_bridge->dev) {

Checking &host_bridge->dev doesn't seem like the right way to
determine whether this is an ACPI host bridge.

> +		union acpi_object *obj;
> +
> +		/*
> +		 * Evaluate the "PCI Boot Configuration" _DSM Function.  If it
> +		 * exists and returns 0, we must preserve any PCI resource
> +		 * assignments made by firmware for this host bridge.
> +		 */
> +		obj = acpi_evaluate_dsm(ACPI_HANDLE(&host_bridge->dev), &pci_acpi_dsm_guid, 1,
> +					DSM_PCI_PRESERVE_BOOT_CONFIG, NULL);
> +		if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0)
> +			host_bridge->preserve_config = 1;
> +		ACPI_FREE(obj);
> +	}


From sean.anderson at linux.dev  Thu Feb 22 09:07:49 2024
From: sean.anderson at linux.dev (Sean Anderson)
Date: Thu, 22 Feb 2024 12:07:49 -0500
Subject: [RESEND2 PATCH net v4 2/2] soc: fsl: qbman: Use raw spinlock for cgr_lock
In-Reply-To: <20240222170749.2607485-1-sean.anderson@linux.dev>
References: <20240222170749.2607485-1-sean.anderson@linux.dev>
Message-ID: <20240222170749.2607485-2-sean.anderson@linux.dev>

cgr_lock may be locked with interrupts already disabled by
smp_call_function_single. As such, we must use a raw spinlock to avoid
problems on PREEMPT_RT kernels. Although this bug has existed for a
while, it was not apparent until commit ef2a8d5478b9 ("net: dpaa: Adjust
queue depth on rate change") which invokes smp_call_function_single via
qman_update_cgr_safe every time a link goes up or down.

Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
CC: stable at vger.kernel.org
Reported-by: Vladimir Oltean <vladimir.oltean at nxp.com>
Closes: https://lore.kernel.org/all/20230323153935.nofnjucqjqnz34ej at skbuf/
Reported-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
Closes: https://lore.kernel.org/linux-arm-kernel/87wmsyvclu.fsf at pengutronix.de/
Signed-off-by: Sean Anderson <sean.anderson at linux.dev>
Reviewed-by: Camelia Groza <camelia.groza at nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean at nxp.com>

---

Changes in v4:
- Add a note about how raw spinlocks aren't quite right

Changes in v3:
- Change blamed commit to something more appropriate

 drivers/soc/fsl/qbman/qman.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 1bf1f1ea67f0..7e9074519ad2 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -991,7 +991,7 @@ struct qman_portal {
 	/* linked-list of CSCN handlers. */
 	struct list_head cgr_cbs;
 	/* list lock */
-	spinlock_t cgr_lock;
+	raw_spinlock_t cgr_lock;
 	struct work_struct congestion_work;
 	struct work_struct mr_work;
 	char irqname[MAX_IRQNAME];
@@ -1281,7 +1281,7 @@ static int qman_create_portal(struct qman_portal *portal,
 		/* if the given mask is NULL, assume all CGRs can be seen */
 		qman_cgrs_fill(&portal->cgrs[0]);
 	INIT_LIST_HEAD(&portal->cgr_cbs);
-	spin_lock_init(&portal->cgr_lock);
+	raw_spin_lock_init(&portal->cgr_lock);
 	INIT_WORK(&portal->congestion_work, qm_congestion_task);
 	INIT_WORK(&portal->mr_work, qm_mr_process_task);
 	portal->bits = 0;
@@ -1456,11 +1456,14 @@ static void qm_congestion_task(struct work_struct *work)
 	union qm_mc_result *mcr;
 	struct qman_cgr *cgr;
 
-	spin_lock_irq(&p->cgr_lock);
+	/*
+	 * FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock!
+	 */
+	raw_spin_lock_irq(&p->cgr_lock);
 	qm_mc_start(&p->p);
 	qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
 	if (!qm_mc_result_timeout(&p->p, &mcr)) {
-		spin_unlock_irq(&p->cgr_lock);
+		raw_spin_unlock_irq(&p->cgr_lock);
 		dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
 		qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 		return;
@@ -1476,7 +1479,7 @@ static void qm_congestion_task(struct work_struct *work)
 	list_for_each_entry(cgr, &p->cgr_cbs, node)
 		if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
 			cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
-	spin_unlock_irq(&p->cgr_lock);
+	raw_spin_unlock_irq(&p->cgr_lock);
 	qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 }
 
@@ -2440,7 +2443,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
 	preempt_enable();
 
 	cgr->chan = p->config->channel;
-	spin_lock_irq(&p->cgr_lock);
+	raw_spin_lock_irq(&p->cgr_lock);
 
 	if (opts) {
 		struct qm_mcc_initcgr local_opts = *opts;
@@ -2477,7 +2480,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
 	    qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
 		cgr->cb(p, cgr, 1);
 out:
-	spin_unlock_irq(&p->cgr_lock);
+	raw_spin_unlock_irq(&p->cgr_lock);
 	put_affine_portal();
 	return ret;
 }
@@ -2512,7 +2515,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
 		return -EINVAL;
 
 	memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
-	spin_lock_irqsave(&p->cgr_lock, irqflags);
+	raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
 	list_del(&cgr->node);
 	/*
 	 * If there are no other CGR objects for this CGRID in the list,
@@ -2537,7 +2540,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
 		/* add back to the list */
 		list_add(&cgr->node, &p->cgr_cbs);
 release_lock:
-	spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+	raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
 	put_affine_portal();
 	return ret;
 }
@@ -2577,9 +2580,9 @@ static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
 	if (!p)
 		return -EINVAL;
 
-	spin_lock_irqsave(&p->cgr_lock, irqflags);
+	raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
 	ret = qm_modify_cgr(cgr, 0, opts);
-	spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+	raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
 	put_affine_portal();
 	return ret;
 }
-- 
2.35.1.1320.gc452695387.dirty



From sean.anderson at linux.dev  Thu Feb 22 09:07:48 2024
From: sean.anderson at linux.dev (Sean Anderson)
Date: Thu, 22 Feb 2024 12:07:48 -0500
Subject: [RESEND2 PATCH net v4 1/2] soc: fsl: qbman: Always disable interrupts when taking cgr_lock
Message-ID: <20240222170749.2607485-1-sean.anderson@linux.dev>

smp_call_function_single disables IRQs when executing the callback. To
prevent deadlocks, we must disable IRQs when taking cgr_lock elsewhere.
This is already done by qman_update_cgr and qman_delete_cgr; fix the
other lockers.

Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
CC: stable at vger.kernel.org
Signed-off-by: Sean Anderson <sean.anderson at linux.dev>
Reviewed-by: Camelia Groza <camelia.groza at nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
Resent from a non-mangling email.

(no changes since v3)

Changes in v3:
- Change blamed commit to something more appropriate

Changes in v2:
- Fix one additional call to spin_unlock

 drivers/soc/fsl/qbman/qman.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 739e4eee6b75..1bf1f1ea67f0 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -1456,11 +1456,11 @@ static void qm_congestion_task(struct work_struct *work)
 	union qm_mc_result *mcr;
 	struct qman_cgr *cgr;
 
-	spin_lock(&p->cgr_lock);
+	spin_lock_irq(&p->cgr_lock);
 	qm_mc_start(&p->p);
 	qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
 	if (!qm_mc_result_timeout(&p->p, &mcr)) {
-		spin_unlock(&p->cgr_lock);
+		spin_unlock_irq(&p->cgr_lock);
 		dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
 		qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 		return;
@@ -1476,7 +1476,7 @@ static void qm_congestion_task(struct work_struct *work)
 	list_for_each_entry(cgr, &p->cgr_cbs, node)
 		if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
 			cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
-	spin_unlock(&p->cgr_lock);
+	spin_unlock_irq(&p->cgr_lock);
 	qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 }
 
@@ -2440,7 +2440,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
 	preempt_enable();
 
 	cgr->chan = p->config->channel;
-	spin_lock(&p->cgr_lock);
+	spin_lock_irq(&p->cgr_lock);
 
 	if (opts) {
 		struct qm_mcc_initcgr local_opts = *opts;
@@ -2477,7 +2477,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
 	    qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
 		cgr->cb(p, cgr, 1);
 out:
-	spin_unlock(&p->cgr_lock);
+	spin_unlock_irq(&p->cgr_lock);
 	put_affine_portal();
 	return ret;
 }
-- 
2.35.1.1320.gc452695387.dirty



From florian.fainelli at broadcom.com  Thu Feb 22 09:39:06 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Thu, 22 Feb 2024 09:39:06 -0800
Subject: [PATCH v1 10/14] serial: 8250_of: Switch to use
 uart_read_port_properties()
In-Reply-To: <Zdd6lnXwvpPPUhRR@smile.fi.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-11-andriy.shevchenko@linux.intel.com>
 <0a828f2c50de712940fb9a881702ac1678a35b7c.camel@codeconstruct.com.au>
 <ZddKzHplwOX7naLv@smile.fi.intel.com> <Zdd5m2xIPlGI0_Qv@smile.fi.intel.com>
 <Zdd6lnXwvpPPUhRR@smile.fi.intel.com>
Message-ID: <e5fd9d8b-84eb-4ef9-82ab-ff4ecc41c0d5@broadcom.com>

On 2/22/24 08:47, Andy Shevchenko wrote:
> On Thu, Feb 22, 2024 at 06:43:08PM +0200, Andy Shevchenko wrote:
>> On Thu, Feb 22, 2024 at 03:23:24PM +0200, Andy Shevchenko wrote:
>>> On Thu, Feb 22, 2024 at 11:07:05AM +1030, Andrew Jeffery wrote:
>>>> On Wed, 2024-02-21 at 20:31 +0200, Andy Shevchenko wrote:
>>>>> Since we have now a common helper to read port properties
>>>>> use it instead of sparse home grown solution.
>>>>
>>>> I did some brief testing of the series for the Aspeed machines under
>>>> qemu, building them on top of v6.8-rc5:
>>>>
>>>> export ARCH=arm
>>>> export CROSS_COMPILE=arm-linux-gnueabihf-
>>>> make aspeed_g5_defconfig
>>>> make -j$(nproc)
>>>> qemu-system-arm -M rainier-bmc -nographic -no-reboot -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dtb -initrd ...
>>>>
>>>> I got an oops during boot, which bisected to this change:
>>>
>>> Thank you for prompt testing! I will look at it.
>>
>> I found the issue, will be fixed in next version.
> 
> Whoever is going to test this series, the
> 
> -		port->iotype = use_defaults ? UPIO_MEM : port->iotype;
> +		port->iotype = UPIO_MEM;
> 
> should be applied to uart_read_port_properties() implementation.
> 

Thanks, on 8250_bcm7271.c with the above hunk applied, I did not spot 
any differences between the values returned by stty or a cat 
/sys/class/tty/ttyS0/* before or after, the console remained fully 
functional. I will see if I can run an additional test where I removed 
the DT's "clocks" property and confirm that the fall back to 
"clock-frequency" works.

Thanks Andy!
-- 
Florian

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240222/4867ce96/attachment-0001.p7s>

From will at kernel.org  Thu Feb 22 09:40:22 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 17:40:22 +0000
Subject: [PATCH v5 02/17] iommu/arm-smmu-v3: Consolidate the STE
 generation for abort/bypass
In-Reply-To: <2ca7f64e-a9e3-4d47-b04f-726c86223fd6@arm.com>
References: <2-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <2ca7f64e-a9e3-4d47-b04f-726c86223fd6@arm.com>
Message-ID: <20240222174022.GA9488@willie-the-truck>

On Thu, Feb 15, 2024 at 05:27:09PM +0000, Robin Murphy wrote:
> On 06/02/2024 3:12 pm, Jason Gunthorpe wrote:
> > +/*
> > + * This can safely directly manipulate the STE memory without a sync sequence
> > + * because the STE table has not been installed in the SMMU yet.
> > + */
> >   static void arm_smmu_init_bypass_stes(struct arm_smmu_ste *strtab,
> 
> This name is long out-of-date - if we're refreshing this area, please rename
> to something relevant to what it actually does, e.g. s/bypass/initial/.
> 
> Although frankly I also think that at this point we should just get rid of
> the disable_bypass parameter altogether - it's been almost entirely
> meaningless since default domain support was added, and any tenuous cases
> for wanting inital STEs to be bypass should probably be using RMRs now
> anyway.

We probably can't drop it for SMMUv2, but I'd be more than happy to do so
on SMMUv3. I think one of the reasons for keeping it in the new driver was
that the Arm Fast Model used to need it for legacy virtio devices that were
downsteam of the SMMU but couldn't advertise F_ACCESS_PLATFORM. Was that
fixed?

Will


From will at kernel.org  Thu Feb 22 09:43:46 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 17:43:46 +0000
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <20240221140818.GA2635804@nvidia.com>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240215134952.GA690@willie-the-truck>
 <20240215160135.GL1088888@nvidia.com>
 <20240221134923.GA7362@willie-the-truck>
 <20240221140818.GA2635804@nvidia.com>
Message-ID: <20240222174346.GB9488@willie-the-truck>

On Wed, Feb 21, 2024 at 10:08:18AM -0400, Jason Gunthorpe wrote:
> On Wed, Feb 21, 2024 at 01:49:23PM +0000, Will Deacon wrote:
> 
> > Very roughly, yes, although I'd go further and just return a bitmap of
> > used qwords instead of tracking these bits. Basically, we could have some
> > #defines saying which qwords are used by which configs, 
> 
> I don't think this will work well for CD's EPD0 case..
> 
> static void arm_smmu_get_cd_used(const __le64 *ent, __le64 *used_bits)
> {
> 	used_bits[0] = cpu_to_le64(CTXDESC_CD_0_V);
> 	if (!(ent[0] & cpu_to_le64(CTXDESC_CD_0_V)))
> 		return;
> 	memset(used_bits, 0xFF, sizeof(struct arm_smmu_cd));
> 
> 	/* EPD0 means T0SZ/TG0/IR0/OR0/SH0/TTB0 are IGNORED */
> 	if (ent[0] & cpu_to_le64(CTXDESC_CD_0_TCR_EPD0)) {
> 		used_bits[0] &= ~cpu_to_le64(
> 			CTXDESC_CD_0_TCR_T0SZ | CTXDESC_CD_0_TCR_TG0 |
> 			CTXDESC_CD_0_TCR_IRGN0 | CTXDESC_CD_0_TCR_ORGN0 |
> 			CTXDESC_CD_0_TCR_SH0);
> 		used_bits[1] &= ~cpu_to_le64(CTXDESC_CD_1_TTB0_MASK);
> 	}
> }

Please can you explain more about the issue here? I know what EPDx are,
but I'm not understanding why they're problematic. This presumably
involves a hitless transition to/from an aborting CD?

> > and then we can
> > simplify the algorithm while retaining the ability to reject updates
> > to qwords which we're not expecting.
> 
> It is not much simplification. arm_smmu_entry_qword_diff() gets a bit
> shorter (not that it is complex anyhow) and other stuff gets worse.
> 
> > > We'd have to really start doing really hacky things like remove the
> > > SHCFG as a used field entirely - but I think if you do that you break
> > > the entire logic of the design and also go backwards to having
> > > programming that only works if STEs are constructed in certain ways.
> > 
> > I would actually like to remove SHCFG as a used field. If the encoding
> > was less whacky (i.e. if 0b00 always meant "use incoming"), then it would
> > be easy, but it shouldn't be too hard to work around that.
> 
> But why?
> 
> You throw away the entire logic of the design, go back to subtly
> coupling the two parts, and *for what*? Exactly what are we trying to
> achieve in return? You haven't explained why we are still discussing
> this afer 7 months. It really isn't worthwhile.

I'm just trying to avoid introducing dynamic behaviours to the driver
which aren't actually used, and per-qword tracking feels like an easier
way to maintain the hitless updates for the cases you care about. It's
really not about throwing away the entire logic of the design -- as I
said, I think this is looking pretty good. I'm also absolutely open to
being convinced that per-field makes more sense and per-qword is terrible,
so I'd really like to understand the E0PD case more.

As an aside: is this per-field/per-qword discussion the only thing holding
up a v6? With the rest of the feedback addressed and a version of Michael's
selftest that exercises stage-2 translating domains, I'd like to think
we could get it queued up soon.

Cheers,

Will


From robh at kernel.org  Thu Feb 22 09:14:04 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 10:14:04 -0700
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <ZdY2WzKbElloXC4-@shikoro>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>
 <20240216022704.GB850600-robh@kernel.org>
 <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>
 <CACRpkdZZhhzg5SY7U5dv_OfLEVejRFom4V9nCfkQXunAw1ZXSw@mail.gmail.com>
 <CZ94LGRSF9KN.15ZO1VRMIQVR8@bootlin.com>
 <CZAX02IL1N1J.2GQR9D73GLRZB@bootlin.com>
 <ZdY2WzKbElloXC4-@shikoro>
Message-ID: <20240222171404.GA3334332-robh@kernel.org>

On Wed, Feb 21, 2024 at 06:43:55PM +0100, Wolfram Sang wrote:
> Hi,
> 
> > > > > i2c-mpc (fsl,timeout) and i2c-gpio (i2c-gpio,timeout-ms). I agree this
> > > > > prop has no reason to be compatible-specific.
> 
> Anyone up to convert these drivers to the new binding and mark the old
> ones as deprecated?
> 
> > > > As Rob mentioned this isn't in the kernel schemas but in dtschema, so
> > > > you need to patch this:
> > > > https://github.com/robherring/dt-schema
> 
> @Rob: My memory fails a little bit about these two schemas: we have the
> github one for generic bindings, not strictly related to Linux, right?

Well, NONE of the bindings are strictly related to linux unless they say 
'linux,' prefix.

> But why do we have then i2c.txt in ther kernel tree? Why don't we sync
> regularly with the generic schema?

We need to remove i2c.txt. Often that hasn't happened because we need to 
relicense the text from GPL only to dual licensed. From a quick look, 
i2c/i2c-controller.yaml appears to have everything in i2c.txt, so I 
think we can go ahead and remove it. There's only a few references to 
i2c.txt to update with that. I'll send a patch, but please double check 
whether you think i2c-controller.yaml is missing anything.

Rob


From conor at kernel.org  Thu Feb 22 09:57:44 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 22 Feb 2024 17:57:44 +0000
Subject: [PATCH net-next v3 01/10] dt-bindings: net: Add support for
 AM65x SR1.0 in ICSSG
In-Reply-To: <20240221152421.112324-2-diogo.ivo@siemens.com>
References: <20240221152421.112324-1-diogo.ivo@siemens.com>
 <20240221152421.112324-2-diogo.ivo@siemens.com>
Message-ID: <20240222-rebate-squiggle-d6801d506994@spud>

On Wed, Feb 21, 2024 at 03:24:07PM +0000, Diogo Ivo wrote:
> Silicon Revision 1.0 of the AM65x came with a slightly different ICSSG
> support: Only 2 PRUs per slice are available and instead 2 additional
> DMA channels are used for management purposes. We have no restrictions
> on specified PRUs, but the DMA channels need to be adjusted.
> 
> Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
> Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
> Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.
-------------- 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/20240222/ce298381/attachment.sig>

From will at kernel.org  Thu Feb 22 10:06:23 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 18:06:23 +0000
Subject: [PATCH] iommu/arm-smmu-qcom: Add X1E80100 MDSS compatible
In-Reply-To: <20240131-x1e80100-iommu-arm-smmu-qcom-v1-1-c1240419c718@linaro.org>
References: <20240131-x1e80100-iommu-arm-smmu-qcom-v1-1-c1240419c718@linaro.org>
Message-ID: <170861674966.1924480.16417881961597163115.b4-ty@kernel.org>

On Wed, 31 Jan 2024 14:35:16 +0200, Abel Vesa wrote:
> Add the X1E80100 MDSS compatible to clients compatible list, as it also
> needs the workarounds.
> 
> 

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/1] iommu/arm-smmu-qcom: Add X1E80100 MDSS compatible
      https://git.kernel.org/will/c/12721e660057

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Thu Feb 22 10:06:24 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 18:06:24 +0000
Subject: [PATCH 0/8] A702 support
In-Reply-To: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
Message-ID: <170861662823.1923805.14686424405847288477.b4-ty@kernel.org>

On Mon, 19 Feb 2024 14:35:45 +0100, Konrad Dybcio wrote:
> Bit of a megaseries, bunched together for your testing convenience..
> Needs mesa!27665 [1] on the userland part, kmscube happily spins.
> 
> I'm feeling quite lukewarm about the memory barriers in patch 3..
> 
> Patch 1 for Will/smmu, 5-6 for drm/msm, rest for qcom
> 
> [...]

Applied SMMU bindings patch to will (for-joerg/arm-smmu/bindings), thanks!

[1/8] dt-bindings: arm-smmu: Add QCM2290 GPU SMMU
      https://git.kernel.org/will/c/0eca305f8e0d

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Thu Feb 22 10:06:25 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 22 Feb 2024 18:06:25 +0000
Subject: [PATCH v3 0/7] drm/msm: Add support for the A750 GPU found on the SM8650 platform
In-Reply-To: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
References: <20240216-topic-sm8650-gpu-v3-0-eb1f4b86d8d3@linaro.org>
Message-ID: <170861684323.1924954.5000298340107956205.b4-ty@kernel.org>

On Fri, 16 Feb 2024 12:03:47 +0100, Neil Armstrong wrote:
> Unlike the the very close A740 GPU on the SM8550 SoC, the A750 GPU
> doesn't have an HWCFG block but a separate register set.
> 
> The missing registers are added in the a6xx.xml.h file that would
> require a subsequent sync and the non-existent hwcfg is handled
> in a6xx_set_hwcg().
> 
> [...]

Applied SMMU binding changes to will (for-joerg/arm-smmu/bindings), thanks!

[2/7] dt-bindings: arm-smmu: Fix SM8[45]50 GPU SMMU 'if' condition
      https://git.kernel.org/will/c/2777781ca9b6
[3/7] dt-bindings: arm-smmu: Document SM8650 GPU SMMU
      https://git.kernel.org/will/c/8a05f74d567a

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From robh at kernel.org  Thu Feb 22 10:07:47 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 11:07:47 -0700
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240216-caboose-poison-3052a4bb9eaf@spud>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <20240214142825.GA7873@pendragon.ideasonboard.com>
 <20240214-velcro-pushy-0cbd18b23361@spud>
 <20240215110205.GD7873@pendragon.ideasonboard.com>
 <e06b0792-187d-454b-aa62-d9c1e797df17@ideasonboard.com>
 <20240216132755.GA20376@pendragon.ideasonboard.com>
 <f5e63a8b-fb6c-449f-8ec3-26aed5b11b95@ideasonboard.com>
 <20240216-caboose-poison-3052a4bb9eaf@spud>
Message-ID: <20240222180747.GA3518860-robh@kernel.org>

On Fri, Feb 16, 2024 at 07:07:58PM +0000, Conor Dooley wrote:
> On Fri, Feb 16, 2024 at 02:45:31PM +0000, Dan Scally wrote:
> 
> > > > > > > > +      - description: ISP AXI clock
> > > > > > > > +      - description: ISP AHB-lite clock
> > > > > > > These two other clocks look good to me.
> > > > > > > 
> > > > > > > > +
> > > > > > > > +  clock-names:
> > > > > > > > +    items:
> > > > > > > > +      - const: vclk
> > > > > > > > +      - const: aclk
> > > > > > > > +      - const: hclk
> > > > > > Why not "video" "axi" "ahb-lite"? There's 3 useful letters between the
> > > > > > tree clock names you've provided - they're all clocks, so having "clk"
> > > > > > in them is just noise :)
> > > > > As far as I understand, the names proposed by Dan come directly from the
> > > > > IP core documentation.
> > > > This is the case, but I do take Conor's point that more descriptive names might be nicer - if I'm
> > > > honest I just didn't think about it particularly given "Xclk" is such a common name for them
> > > > already, but having been poked into thinking about it I do agree.
> > > Isn't the usual practice in DT bindings is to name GPIOs, clocks and reset
> > > signals based on the hardware documentation ?
> > 
> > 
> > Ah - I don't know honestly. If that's so then yeah - these are the names the documentation prescribes.
> 
> If a direct doc match is what you're going for, then sure, keep it.

pclk, aclk, and hclk are generally the names used for APB, AXI, and AHB 
bus clocks, so I'd stick with them. Though we also have cases of the bus 
names used... 

Rob


From palmer at dabbelt.com  Thu Feb 22 10:12:13 2024
From: palmer at dabbelt.com (Palmer Dabbelt)
Date: Thu, 22 Feb 2024 10:12:13 -0800 (PST)
Subject: [PATCH v6 0/4] StarFive's StarLink PMU Support
In-Reply-To: <20240222125707.GA8589@willie-the-truck>
Message-ID: <mhng-008f9a14-40fe-4522-93f1-e7ebb1233931@palmer-ri-x1c9a>

On Thu, 22 Feb 2024 04:57:08 PST (-0800), Will Deacon wrote:
> On Mon, Jan 29, 2024 at 05:51:37PM +0800, Ji Sheng Teoh wrote:
>> This patch series adds support for StarFive's Starlink Performance
>> Monitor Unit(PMU).
>> StarFive's StarLink PMU integrates one or more CPU cores with
>> a shared L3 memory system. The PMU supports overflow interrupt,
>> up to 16 programmable 64bit event counters, and an independent
>> 64bit cycle counter.
>> StarLink PMU is accessed via MMIO.
>>
>> Example Perf stat output:
>> [root at user]# perf stat -a -e /starfive_starlink_pmu/cycles/ \
>>         -e /starfive_starlink_pmu/read_miss/ \
>>         -e /starfive_starlink_pmu/read_hit/ \
>>         -e /starfive_starlink_pmu/release_request/  \
>>         -e /starfive_starlink_pmu/write_hit/ \
>>         -e /starfive_starlink_pmu/write_miss/ \
>>         -e /starfive_starlink_pmu/write_request/ \
>>         -e /starfive_starlink_pmu/writeback/ \
>>         -e /starfive_starlink_pmu/read_request/ \
>>         -- openssl speed rsa2048
>> Doing 2048 bits private rsa's for 10s: 5 2048 bits private RSA's in
>> 2.84s
>> Doing 2048 bits public rsa's for 10s: 169 2048 bits public RSA's in
>> 2.42s
>> version: 3.0.11
>> built on: Tue Sep 19 13:02:31 2023 UTC
>> options: bn(64,64)
>> CPUINFO: N/A
>>                   sign    verify    sign/s verify/s
>> rsa 2048 bits 0.568000s 0.014320s      1.8     69.8
>> /////////
>>  Performance counter stats for 'system wide':
>>
>>          649991998      starfive_starlink_pmu/cycles/
>>            1009690      starfive_starlink_pmu/read_miss/
>>            1079750      starfive_starlink_pmu/read_hit/
>>            2089405      starfive_starlink_pmu/release_request/
>>                129      starfive_starlink_pmu/write_hit/
>>                 70      starfive_starlink_pmu/write_miss/
>>                194      starfive_starlink_pmu/write_request/
>>             150080      starfive_starlink_pmu/writeback/
>>            2089423      starfive_starlink_pmu/read_request/
>>
>>       27.062755678 seconds time elapsed
>>
>> Ji Sheng Teoh (4):
>>   perf: starfive: Add StarLink PMU support
>>   dt-bindings: perf: starfive: Add JH8100 StarLink PMU
>>   docs: perf: Add description for StarFive's StarLink PMU
>>   MAINTAINERS: Add entry for StarFive StarLink PMU
>>
>>  Documentation/admin-guide/perf/index.rst      |   1 +
>>  .../perf/starfive_starlink_pmu.rst            |  46 ++
>>  .../perf/starfive,jh8100-starlink-pmu.yaml    |  46 ++
>>  MAINTAINERS                                   |   7 +
>>  drivers/perf/Kconfig                          |   9 +
>>  drivers/perf/Makefile                         |   1 +
>>  drivers/perf/starfive_starlink_pmu.c          | 643 ++++++++++++++++++
>>  7 files changed, 753 insertions(+)
>>  create mode 100644 Documentation/admin-guide/perf/starfive_starlink_pmu.rst
>>  create mode 100644 Documentation/devicetree/bindings/perf/starfive,jh8100-starlink-pmu.yaml
>>  create mode 100644 drivers/perf/starfive_starlink_pmu.c
>
> Palmer, are you ok with me taking this via the perf tree? I usually
> leave the Risc-V stuff for you, but this one doesn't touch the arch code
> at all.

Sorry I missed these

Acked-by: Palmer Dabbelt <palmer at rivosinc.com>

> Cheers,
>
> Will


From fancer.lancer at gmail.com  Thu Feb 22 10:12:46 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:46 +0300
Subject: [PATCH v5 01/20] EDAC/synopsys: Fix ECC status data and IRQ disable race condition
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-2-fancer.lancer@gmail.com>

The race condition around the ECCCLR register access happens in the IRQ
disable method called in the device remove() procedure and in the ECC IRQ
handler:
1. Enable IRQ:
   a. ECCCLR = EN_CE | EN_UE
2. Disable IRQ:
   a. ECCCLR = 0
3. IRQ handler:
   a. ECCCLR = CLR_CE | CLR_CE_CNT | CLR_CE | CLR_CE_CNT
   b. ECCCLR = 0
   c. ECCCLR = EN_CE | EN_UE
So if the IRQ disabling procedure is called concurrently with the IRQ
handler method the IRQ might be actually left enabled due to the
statement 3c.

The root cause of the problem is that ECCCLR register (which since v3.10a
has been called as ECCCTL) has intermixed ECC status data clear flags and
the IRQ enable/disable flags. Thus the IRQ disabling (clear EN flags) and
handling (write 1 to clear ECC status data) procedures must be serialised
around the ECCCTL register modification to prevent the race.

So fix the problem described above by adding the spin-lock around the
ECCCLR modifications and preventing the IRQ-handler from modifying the
IRQs enable flags (there is no point in disabling the IRQ and then
re-enabling it again within a single IRQ handler call, see the statements
3a/3b and 3c above).

Fixes: f7824ded4149 ("EDAC/synopsys: Add support for version 3 of the Synopsys EDAC DDR")
Signed-off-by: Serge Semin <fancer.lancer at gmail.com>

---

Cc: Sherry Sun <sherry.sun at nxp.com>

Changelog v4:
- This is a new patch detached from
  [PATCH v3 01/17] EDAC/synopsys: Fix native uMCTL2 IRQs handling procedure
- Rename lock to reglock (Borislav)
---
 drivers/edac/synopsys_edac.c | 50 ++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 709babce43ba..0168b05e3ca1 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -9,6 +9,7 @@
 #include <linux/edac.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
 
@@ -299,6 +300,7 @@ struct synps_ecc_status {
 /**
  * struct synps_edac_priv - DDR memory controller private instance data.
  * @baseaddr:		Base address of the DDR controller.
+ * @reglock:		Concurrent CSRs access lock.
  * @message:		Buffer for framing the event specific info.
  * @stat:		ECC status information.
  * @p_data:		Platform data.
@@ -313,6 +315,7 @@ struct synps_ecc_status {
  */
 struct synps_edac_priv {
 	void __iomem *baseaddr;
+	spinlock_t reglock;
 	char message[SYNPS_EDAC_MSG_SIZE];
 	struct synps_ecc_status stat;
 	const struct synps_platform_data *p_data;
@@ -408,7 +411,8 @@ static int zynq_get_error_info(struct synps_edac_priv *priv)
 static int zynqmp_get_error_info(struct synps_edac_priv *priv)
 {
 	struct synps_ecc_status *p;
-	u32 regval, clearval = 0;
+	u32 regval, clearval;
+	unsigned long flags;
 	void __iomem *base;
 
 	base = priv->baseaddr;
@@ -452,10 +456,14 @@ static int zynqmp_get_error_info(struct synps_edac_priv *priv)
 	p->ueinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
 	p->ueinfo.data = readl(base + ECC_UESYND0_OFST);
 out:
-	clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT;
-	clearval |= ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
+	spin_lock_irqsave(&priv->reglock, flags);
+
+	clearval = readl(base + ECC_CLR_OFST) |
+		   ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT |
+		   ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
 	writel(clearval, base + ECC_CLR_OFST);
-	writel(0x0, base + ECC_CLR_OFST);
+
+	spin_unlock_irqrestore(&priv->reglock, flags);
 
 	return 0;
 }
@@ -515,24 +523,41 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 
 static void enable_intr(struct synps_edac_priv *priv)
 {
+	unsigned long flags;
+
 	/* Enable UE/CE Interrupts */
-	if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
-		writel(DDR_UE_MASK | DDR_CE_MASK,
-		       priv->baseaddr + ECC_CLR_OFST);
-	else
+	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
 		writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
 		       priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
 
+		return;
+	}
+
+	spin_lock_irqsave(&priv->reglock, flags);
+
+	writel(DDR_UE_MASK | DDR_CE_MASK,
+	       priv->baseaddr + ECC_CLR_OFST);
+
+	spin_unlock_irqrestore(&priv->reglock, flags);
 }
 
 static void disable_intr(struct synps_edac_priv *priv)
 {
+	unsigned long flags;
+
 	/* Disable UE/CE Interrupts */
-	if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
-		writel(0x0, priv->baseaddr + ECC_CLR_OFST);
-	else
+	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
 		writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
 		       priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
+
+		return;
+	}
+
+	spin_lock_irqsave(&priv->reglock, flags);
+
+	writel(0, priv->baseaddr + ECC_CLR_OFST);
+
+	spin_unlock_irqrestore(&priv->reglock, flags);
 }
 
 /**
@@ -576,8 +601,6 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
 	/* v3.0 of the controller does not have this register */
 	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
 		writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
-	else
-		enable_intr(priv);
 
 	return IRQ_HANDLED;
 }
@@ -1359,6 +1382,7 @@ static int mc_probe(struct platform_device *pdev)
 	priv = mci->pvt_info;
 	priv->baseaddr = baseaddr;
 	priv->p_data = p_data;
+	spin_lock_init(&priv->reglock);
 
 	mc_init(mci, pdev);
 
-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:12:47 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:47 +0300
Subject: [PATCH v5 02/20] EDAC/synopsys: Fix generic device type detection procedure
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-3-fancer.lancer@gmail.com>

First of all the enum dev_type constants describe the memory DRAM chips
used at the stick, not the entire DQ-bus width (see the enumeration kdoc
for details). So what is returned from the zynqmp_get_dtype() function and
then specified to the dimm_info->dtype field is definitely incorrect.
Secondly the DRAM chips type has nothing to do with the data bus width
specified in the MSTR.data_bus_width CSR field. That CSR field just
determines the part of the whole DQ-bus currently used to access the data
from the all DRAM memory chips. So it doesn't indicate the individual
chips type. Thirdly the DRAM chips type can be determined only in case of
the DDR4 protocol by means of the MSTR.device_config field state (it is
supposed to be set by the system firmware). Finally the DW uMCTL2 DDRC ECC
capability doesn't depend on the memory chips type. Moreover it doesn't
depend on the utilized data bus width in runtime either. The IP-core
reference manual says in [1,2] that the ECC support can't be enabled
during the IP-core synthesizes for the DRAM data bus widths other than 16,
32 or 64.  At the same time the bus width mode (MSTR.data_bus_width)
doesn't change the ECC feature availability. Thus it was wrong to
determine the ECC state with respect to the DQ-bus width mode.

Fix all of the mistakes described above in the zynqmp_get_dtype() and
zynqmp_get_ecc_state() methods: specify actual DRAM chips data width only
for the DDR4 protocol and return that it's UNKNOWN in the rest of the
cases; determine ECC availability by the ECCCFG0.ecc_mode field state
only (that field can't be modified anyway if the IP-core was synthesized
with no ECC support).

[1] DesignWare? Cores Enhanced Universal DDR Memory Controller (uMCTL2)
Databook, Version 3.91a, October 2020, p. 421.
[2] DesignWare? Cores Enhanced Universal DDR Memory Controller (uMCTL2)
Databook, Version 3.91a, October 2020, p. 633.

Fixes: b500b4a029d5 ("EDAC, synopsys: Add ECC support for ZynqMP DDR controller")
Signed-off-by: Serge Semin <fancer.lancer at gmail.com>

---

Changelog v2:
- Include "linux/bitfield.h" header file to get the FIELD_GET macro
  definition. (@tbot)
---
 drivers/edac/synopsys_edac.c | 49 +++++++++++++++---------------------
 1 file changed, 20 insertions(+), 29 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 0168b05e3ca1..455d2fcfd8c1 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -674,26 +674,25 @@ static enum dev_type zynq_get_dtype(const void __iomem *base)
  */
 static enum dev_type zynqmp_get_dtype(const void __iomem *base)
 {
-	enum dev_type dt;
-	u32 width;
-
-	width = readl(base + CTRL_OFST);
-	width = (width & ECC_CTRL_BUSWIDTH_MASK) >> ECC_CTRL_BUSWIDTH_SHIFT;
-	switch (width) {
-	case DDRCTL_EWDTH_16:
-		dt = DEV_X2;
-		break;
-	case DDRCTL_EWDTH_32:
-		dt = DEV_X4;
-		break;
-	case DDRCTL_EWDTH_64:
-		dt = DEV_X8;
-		break;
-	default:
-		dt = DEV_UNKNOWN;
+	u32 regval;
+
+	regval = readl(base + CTRL_OFST);
+	if (!(regval & MEM_TYPE_DDR4))
+		return DEV_UNKNOWN;
+
+	regval = (regval & DDRC_MSTR_CFG_MASK) >> DDRC_MSTR_CFG_SHIFT;
+	switch (regval) {
+	case DDRC_MSTR_CFG_X4_MASK:
+		return DEV_X4;
+	case DDRC_MSTR_CFG_X8_MASK:
+		return DEV_X8;
+	case DDRC_MSTR_CFG_X16_MASK:
+		return DEV_X16;
+	case DDRC_MSTR_CFG_X32_MASK:
+		return DEV_X32;
 	}
 
-	return dt;
+	return DEV_UNKNOWN;
 }
 
 /**
@@ -730,19 +729,11 @@ static bool zynq_get_ecc_state(void __iomem *base)
  */
 static bool zynqmp_get_ecc_state(void __iomem *base)
 {
-	enum dev_type dt;
-	u32 ecctype;
+	u32 regval;
 
-	dt = zynqmp_get_dtype(base);
-	if (dt == DEV_UNKNOWN)
-		return false;
+	regval = readl(base + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
 
-	ecctype = readl(base + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
-	if ((ecctype == SCRUB_MODE_SECDED) &&
-	    ((dt == DEV_X2) || (dt == DEV_X4) || (dt == DEV_X8)))
-		return true;
-
-	return false;
+	return (regval == SCRUB_MODE_SECDED);
 }
 
 /**
-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:12:45 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:45 +0300
Subject: [PATCH v5 00/20] EDAC/mc/synopsys: Various fixes and cleanups
Message-ID: <20240222181324.28242-1-fancer.lancer@gmail.com>

This patchset is a first one in the series created in the framework of
my Synopsys DW uMCTL2 DDRC-related work:

[1: In-progress v5] EDAC/mc/synopsys: Various fixes and cleanups
Link: ---you are looking at it---
[2: In-progress v4] EDAC/synopsys: Add generic DDRC info and address mapping
Link: https://lore.kernel.org/linux-edac/20230920192806.29960-1-fancer.lancer at gmail.com
[3: In-progress v4] EDAC/synopsys: Add generic resources and Scrub support
Link: https://lore.kernel.org/linux-edac/20230920195720.32047-1-fancer.lancer at gmail.com

Note the patchsets above must be merged in the same order as they are
placed in the list in order to prevent conflicts. Nothing prevents them
from being reviewed synchronously though. Any tests are very welcome.
Thanks in advance.

The main goal of the entire set of the changes provided in the mentioned
patchsets is to as much as possible specialise the synopsys_edac.c driver
to be working with the Synopsys DW uMCTL2 DDR controllers of various
versions and synthesized parameters, and add useful error-detection
features.

Regarding this series content. It's an initial patchset which
traditionally provides various fixes, cleanups and modifications required
for the more comfortable further features development. The main goal of it
though is to detach the Xilinx Zynq A05 DDRC related code into the
dedicated driver since first it has nothing to do with the Synopsys DW
uMCTL2 DDR controller and second it will be a great deal obstacle on the
way of extending the Synopsys-part functionality.

The series starts with the fixes patches, which in short concern the next
aspects: touching the ZynqMP-specific CSRs on the Xilinx ZinqMP platform
only, serializing an access to the ECCCLR/ECCCTL register, adding correct memory
devices type detection, setting a correct value to the
mem_ctl_info.scrub_cap field, dropping an erroneous ADDRMAP[4] parsing and
getting back a correct order of the ECC errors info detection procedure.

Afterwards the patchset provides several cleanup patches required for the
more coherent code splitting up (Xilinx Zynq A05 and Synopsys DW uMCTL2
DDRCs) so the provided modifications would be useful in both drivers.
First the platform resource open-coded IO-space remapping is replaced with
the devm_platform_ioremap_resource() method call for the sake of the code
simplification. Secondly the next redundant entities are dropped: internal
CE/UE errors counters, local to_mci() macros definition, some redundant
ecc_error_info structure fields and redundant info from the error message,
duplicated dimm->nr_pages debug printout and spaces from the MEM_TYPE
flags declarations. (The later two updates concern the MCI core part.)
Thirdly before detaching the Zynq A05-related code an unique MC index
allocation infrastructure is added to the MCI core. It's required since
after splitting the driver up both supported types of memory devices could
be correctly probed on the same platform. Note even though it's currently
unsupported by the synsopsys_edac.c driver it's claimed to be possible by
the original driver author (it was a reason of having two unrelated
devices supported in a single driver). Finally the Xilinx Zynq A05 part of
the driver is moved out to a dedicated driver. After that the
platform-specific setups API is removed from the Synopsys DW uMCTL2 DDRC
driver since it's no longer required.

Finally as the cherry on the cake a set of the local coding style
cleanups are provided: unify the DW uMCTL2 DDRC driver entities naming and
replace the open-coded "shift/mask" pattern with the kernel helpers like
BIT/GENMASK/FIELD_x in there. It shall significantly improve the code
readability.

Changelog v2:
- Move Synopsys DW uMCTL2 DDRC bindings file renaming to a separate patch.
  (@Krzysztof)
- Introduce a new compatible string "snps,dw-umctl2-ddrc" matching the new
  DT-schema name.
- Forgot to fix some of the prefix of the SYNPS_ZYNQMP_IRQ_REGS macro
  in several places. (@tbot)
- Drop the no longer used "priv" pointer from the mc_init() function.
  (@tbot)
- Include "linux/bitfield.h" header file to get the FIELD_GET macro
  definition. (@tbot)
- Drop the already merged in patches:
[PATCH 12/20] EDAC/mc: Replace spaces with tabs in memtype flags definition
[PATCH 13/20] EDAC/mc: Drop duplicated dimm->nr_pages debug printout

Changelog v3:
- Drop the no longer used "priv" pointer from the mc_init() function.
  (@tbot)
- Drop the merged in patches:
[PATCH v2 14/19] dt-bindings: memory: snps: Detach Zynq DDRC controller support
[PATCH v2 15/19] dt-bindings: memory: snps: Use more descriptive device name
  (@Krzysztof)

Changelog v4:
- Remove Rob, Krzysztof and DT-mailing list from Cc since the respective
  patches have already been merged in.
- Add a new patch
  [PATCH v4 6/20] EDAC/synopsys: Fix misleading IRQ self-cleared quirk flag
  detached from the very first patch of the series.
- Add a new patch
  [PATCH v4 15/20] EDAC/mc: Re-use generic unique MC index allocation procedure
- Add a new patch
  [PATCH v4 18/20] EDAC/synopsys: Unify CSRs macro declarations
  collecting the changes from various patches of the series.
- Drop redundant empty lines left by mistake.
- Drop private counters access from the check_errors() method too.
- Rebase onto the kernel v6.6-rcX.

Link: https://lore.kernel.org/linux-edac/20230920191059.28395-1-fancer.lancer at gmail.com
Changelog v5:
- Fix function names in the zynq_edac.c kdoc.
- Rebase onto the kernel 6.8-rc3.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
Cc: Punnaiah Choudary Kalluri <punnaiah.choudary.kalluri at xilinx.com>
Cc: Dinh Nguyen <dinguyen at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-edac at vger.kernel.org
Cc: linux-kernel at vger.kernel.org

Serge Semin (20):
  EDAC/synopsys: Fix ECC status data and IRQ disable race condition
  EDAC/synopsys: Fix generic device type detection procedure
  EDAC/synopsys: Fix mci->scrub_cap field setting
  EDAC/synopsys: Drop erroneous ADDRMAP4.addrmap_col_b10 parse
  EDAC/synopsys: Fix reading errors count before ECC status
  EDAC/synopsys: Fix misleading IRQ self-cleared quirk flag
  EDAC/synopsys: Use platform device devm ioremap method
  EDAC/synopsys: Drop internal CE and UE counters
  EDAC/synopsys: Drop local to_mci() macro definition
  EDAC/synopsys: Drop struct ecc_error_info.blknr field
  EDAC/synopsys: Shorten out struct ecc_error_info.bankgrpnr field name
  EDAC/synopsys: Drop redundant info from the error messages
  EDAC/mc: Init DIMM labels in MC registration method
  EDAC/mc: Add generic unique MC index allocation procedure
  EDAC/mc: Re-use generic unique MC index allocation procedure
  EDAC/synopsys: Detach Zynq A05 DDRC support to separate driver
  EDAC/synopsys: Drop unused platform-specific setup API
  EDAC/synopsys: Unify CSRs macro declarations
  EDAC/synopsys: Unify struct/macro/function prefixes
  EDAC/synopsys: Convert to using BIT/GENMASK/FIELD_x macros

 MAINTAINERS                  |   1 +
 drivers/edac/Kconfig         |   9 +-
 drivers/edac/Makefile        |   1 +
 drivers/edac/dmc520_edac.c   |   4 +-
 drivers/edac/edac_mc.c       | 135 ++++-
 drivers/edac/edac_mc.h       |   4 +
 drivers/edac/pasemi_edac.c   |   5 +-
 drivers/edac/ppc4xx_edac.c   |   5 +-
 drivers/edac/synopsys_edac.c | 967 ++++++++++++-----------------------
 drivers/edac/zynq_edac.c     | 501 ++++++++++++++++++
 10 files changed, 963 insertions(+), 669 deletions(-)
 create mode 100644 drivers/edac/zynq_edac.c

-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:12:48 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:48 +0300
Subject: [PATCH v5 03/20] EDAC/synopsys: Fix mci->scrub_cap field setting
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-4-fancer.lancer@gmail.com>

The mem_ctl_info.scrub_cap field is supposed to be set with the ECC
scrub-related flags. Instead the driver erroneously initializes it with
the SCRUB_HW_SRC flag ID. It's definitely wrong, though it hasn't caused
any problem so far since the structure field isn't used by the EDAC core.
Fix it anyway by using the SCRUB_FLAG_HW_SRC macro to initialize the
field.

Fixes: ae9b56e3996d ("EDAC, synps: Add EDAC support for zynq ddr ecc controller")
Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
---
 drivers/edac/synopsys_edac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 455d2fcfd8c1..7c57c43b4d31 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -855,7 +855,7 @@ static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
 	/* Initialize controller capabilities and configuration */
 	mci->mtype_cap = MEM_FLAG_DDR3 | MEM_FLAG_DDR2;
 	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
-	mci->scrub_cap = SCRUB_HW_SRC;
+	mci->scrub_cap = SCRUB_FLAG_HW_SRC;
 	mci->scrub_mode = SCRUB_NONE;
 
 	mci->edac_cap = EDAC_FLAG_SECDED;
-- 
2.43.0



From mripard at kernel.org  Thu Feb 22 10:13:46 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:46 +0100
Subject: [PATCH v7 00/36] drm/connector: Create HDMI Connector
 infrastructure
Message-ID: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>

Hi,

Here's a series that creates some extra infrastructure specifically
targeted at HDMI controllers.

The idea behind this series came from a recent discussion on IRC during
which we discussed infoframes generation of i915 vs everything else.

Infoframes generation code still requires some decent boilerplate, with
each driver doing some variation of it.

In parallel, while working on vc4, we ended up converting a lot of i915
logic (mostly around format / bpc selection, and scrambler setup) to
apply on top of a driver that relies only on helpers.

While currently sitting in the vc4 driver, none of that logic actually
relies on any driver or hardware-specific behaviour.

The only missing piece to make it shareable are a bunch of extra
variables stored in a state (current bpc, format, RGB range selection,
etc.).

The initial implementation was relying on some generic subclass of
drm_connector to address HDMI connectors, with a bunch of helpers that
will take care of all the "HDMI Spec" related code. Scrambler setup is
missing at the moment but can easily be plugged in.

The feedback was that creating a connector subclass like was done for
writeback would prevent the adoption of those helpers since it couldn't
be used in all situations (like when the connector driver can implement
multiple output) and required more churn to cast between the
drm_connector and its subclass. The decision was thus to provide a set
of helper and to store the required variables in drm_connector and
drm_connector_state. This what has been implemented now.

Hans Verkuil also expressed interest in implementing a mechanism in v4l2
to retrieve infoframes from HDMI receiver and implementing a tool to
decode (and eventually check) infoframes. His current work on
edid-decode to enable that based on that series can be found here:
https://git.linuxtv.org/hverkuil/edid-decode.git/log/?h=hverkuil

And some more context here:
https://lore.kernel.org/dri-devel/50db7366-cd3d-4675-aaad-b857202234de at xs4all.nl/

This series thus leverages the infoframe generation code to expose it
through debugfs.

I also used the occasion to unit-test everything but the infoframe
generation, which can come later once I get a proper understanding of
what the infoframe are supposed to look like. This required to add some
extra kunit helpers and infrastructure to have multiple EDIDs and allow
each test to run with a particular set of capabilities.

This entire series has been tested on a Pi4, passes all its unittests
(125 new tests), and has only been build-tested for sunxi and rockchip.

Let me know what you think,
Maxime

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
Changes in v7:
- Rebased on top of current next
- Only consider the Broadcast RGB property if the output format is RGB,
  and use a limited range otherwise
- Document the fact that Broadcast RGB only applies if the output format
  is RGB
- Add some test to make sure we always get a limited range if we have a
  YCbCr output format.
- Link to v6: https://lore.kernel.org/r/20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f at kernel.org

Changes in v6:
- Rebased on top of current next
- Split the tests into separate patches
- Improve the Broadcast RGB documentation
- Link to v5: https://lore.kernel.org/r/20231207-kms-hdmi-connector-state-v5-0-6538e19d634d at kernel.org

Changes in v5:
- Dropped the connector init arg checking patch, and the related kunit
  tests
- Dropped HDMI Vendor infoframes in rockchip inno_hdmi
- Fixed the build warnings
- Link to v4: https://lore.kernel.org/r/20231128-kms-hdmi-connector-state-v4-0-c7602158306e at kernel.org

Changes in v4:
- Create unit tests for everything but infoframes
- Fix a number of bugs identified by the unit tests
- Rename DRM (Dynamic Range and Mastering) infoframe file to HDR_DRM
- Drop RFC status
- Link to v3: https://lore.kernel.org/r/20231031-kms-hdmi-connector-state-v3-0-328b0fae43a7 at kernel.org

Changes in v3:
- Made sure the series work on the RaspberryPi4
- Handle YUV420 in the char clock rate computation
- Use the maximum bpc value the connector allows at reset
- Expose the RGB Limited vs Full Range value in the connector state
  instead of through a helper
- Fix Broadcast RGB documentation
- Add more debug logging
- Small fixes here and there
- Link to v2: https://lore.kernel.org/r/20230920-kms-hdmi-connector-state-v2-0-17932daddd7d at kernel.org

Changes in v2:
- Change from a subclass to a set of helpers for drm_connector and
  drm_connector state
- Don't assume that all drivers support RGB, YUV420 and YUV422 but make
  them provide a bitfield instead.
- Don't assume that all drivers support the Broadcast RGB property but
  make them call the registration helper.
- Document the Broacast RGB property
- Convert the inno_hdmi and sun4i_hdmi driver.
- Link to v1: https://lore.kernel.org/r/20230814-kms-hdmi-connector-state-v1-0-048054df3654 at kernel.org

---
Maxime Ripard (36):
      drm/tests: helpers: Include missing drm_drv header
      drm/tests: helpers: Add atomic helpers
      drm/tests: Add helper to create mock plane
      drm/tests: Add helper to create mock crtc
      drm/tests: connector: Add tests for drmm_connector_init
      drm/connector: Introduce an HDMI connector initialization function
      drm/tests: connector: Add tests for drmm_connector_hdmi_init
      drm/connector: hdmi: Create an HDMI sub-state
      drm/connector: hdmi: Add output BPC to the connector state
      drm/tests: Add output bpc tests
      drm/connector: hdmi: Add support for output format
      drm/tests: Add output formats tests
      drm/connector: hdmi: Add HDMI compute clock helper
      drm/tests: Add HDMI TDMS character rate tests
      drm/connector: hdmi: Calculate TMDS character rate
      drm/tests: Add TDMS character rate connector state tests
      drm/connector: hdmi: Add custom hook to filter TMDS character rate
      drm/tests: Add HDMI connector rate filter hook tests
      drm/connector: hdmi: Compute bpc and format automatically
      drm/tests: Add HDMI connector bpc and format tests
      drm/connector: hdmi: Add Broadcast RGB property
      drm/tests: Add tests for Broadcast RGB property
      drm/connector: hdmi: Add RGB Quantization Range to the connector state
      drm/tests: Add RGB Quantization tests
      drm/connector: hdmi: Add Infoframes generation
      drm/tests: Add infoframes test
      drm/connector: hdmi: Create Infoframe DebugFS entries
      drm/vc4: hdmi: Switch to HDMI connector
      drm/vc4: tests: Remove vc4_dummy_plane structure
      drm/vc4: tests: Convert to plane creation helper
      drm/rockchip: inno_hdmi: Switch to HDMI connector
      drm/sun4i: hdmi: Convert encoder to atomic
      drm/sun4i: hdmi: Move mode_set into enable
      drm/sun4i: hdmi: Switch to container_of_const
      drm/sun4i: hdmi: Consolidate atomic_check and mode_valid
      drm/sun4i: hdmi: Switch to HDMI connector

 Documentation/gpu/kms-properties.csv               |    1 -
 drivers/gpu/drm/Kconfig                            |    1 +
 drivers/gpu/drm/drm_atomic.c                       |   11 +
 drivers/gpu/drm/drm_atomic_state_helper.c          |  667 +++++++
 drivers/gpu/drm/drm_atomic_uapi.c                  |    4 +
 drivers/gpu/drm/drm_connector.c                    |  268 +++
 drivers/gpu/drm/drm_debugfs.c                      |  110 ++
 drivers/gpu/drm/rockchip/inno_hdmi.c               |  123 +-
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c             |  203 +-
 drivers/gpu/drm/tests/Makefile                     |    1 +
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 1944 ++++++++++++++++++++
 drivers/gpu/drm/tests/drm_connector_test.c         | 1227 +++++++++++-
 drivers/gpu/drm/tests/drm_kunit_edid.h             |  482 +++++
 drivers/gpu/drm/tests/drm_kunit_helpers.c          |  150 ++
 drivers/gpu/drm/vc4/tests/vc4_mock.c               |    6 +-
 drivers/gpu/drm/vc4/tests/vc4_mock.h               |    9 +-
 drivers/gpu/drm/vc4/tests/vc4_mock_plane.c         |   44 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c                     |  638 +------
 drivers/gpu/drm/vc4/vc4_hdmi.h                     |   44 +-
 drivers/gpu/drm/vc4/vc4_hdmi_phy.c                 |    6 +-
 include/drm/drm_atomic_state_helper.h              |   12 +
 include/drm/drm_connector.h                        |  257 +++
 include/drm/drm_kunit_helpers.h                    |   23 +
 23 files changed, 5414 insertions(+), 817 deletions(-)
---
base-commit: e31185ce00a96232308300008db193416ceb9769
change-id: 20230814-kms-hdmi-connector-state-616787e67927

Best regards,
-- 
Maxime Ripard <mripard at kernel.org>



From fancer.lancer at gmail.com  Thu Feb 22 10:12:49 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:49 +0300
Subject: [PATCH v5 04/20] EDAC/synopsys: Drop erroneous ADDRMAP4.addrmap_col_b10 parse
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-5-fancer.lancer@gmail.com>

Currently the ADDRMAP4.addrmap_col_b10 field gets to be parsed in case of
the LPDDR3 memory and Quarter DQ bus width mode. It's wrong since that
field is marked as unused for that mode in all the available DW uMCTL2
DDRC releases (up to IP-core v3.91a). Most likely the field parsing was
added by mistake as a result of the copy-paste from the Half DQ bus width
mode part of the same function. Even though the field is supposed to be
always set to the UNUSED value (0x1F) drop parsing it anyway so to
simplify the setup_column_address_map() method a tiny bit.

Fixes: 1a81361f75d8 ("EDAC, synopsys: Add Error Injection support for ZynqMP DDR controller")
Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
---
 drivers/edac/synopsys_edac.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 7c57c43b4d31..bd6e52db68bc 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -1236,10 +1236,6 @@ static void setup_column_address_map(struct synps_edac_priv *priv, u32 *addrmap)
 				COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 :
 				(((addrmap[3] >> 24) & COL_MAX_VAL_MASK) +
 				 COL_B9_BASE);
-			priv->col_shift[13] = ((addrmap[4] &
-				COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 :
-				((addrmap[4] & COL_MAX_VAL_MASK) +
-				 COL_B10_BASE);
 		} else {
 			priv->col_shift[11] = (((addrmap[3] >> 16) &
 				COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 :
-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:12:50 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:50 +0300
Subject: [PATCH v5 05/20] EDAC/synopsys: Fix reading errors count before ECC status
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-6-fancer.lancer@gmail.com>

Aside with fixing the errors count CSR usage the commit e2932d1f6f05
("EDAC/synopsys: Read the error count from the correct register") all of
the sudden has also changed the order of the errors status check
procedure. So now the errors handler method first reads the number of CE
and UE and only then makes sure that any of these errors have actually
happened. It doesn't make sense. Fix that by getting back the correct
procedures order: first check the ECC status, then read the number of
errors.

Fixes: e2932d1f6f05 ("EDAC/synopsys: Read the error count from the correct register")
Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
Reviewed-by: Shubhrajyoti Datta <shubhrajyoti.datta at amd.com>
---
 drivers/edac/synopsys_edac.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index bd6e52db68bc..fbaf3d9ad517 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -418,18 +418,18 @@ static int zynqmp_get_error_info(struct synps_edac_priv *priv)
 	base = priv->baseaddr;
 	p = &priv->stat;
 
-	regval = readl(base + ECC_ERRCNT_OFST);
-	p->ce_cnt = regval & ECC_ERRCNT_CECNT_MASK;
-	p->ue_cnt = (regval & ECC_ERRCNT_UECNT_MASK) >> ECC_ERRCNT_UECNT_SHIFT;
-	if (!p->ce_cnt)
-		goto ue_err;
-
 	regval = readl(base + ECC_STAT_OFST);
 	if (!regval)
 		return 1;
 
 	p->ceinfo.bitpos = (regval & ECC_STAT_BITNUM_MASK);
 
+	regval = readl(base + ECC_ERRCNT_OFST);
+	p->ce_cnt = regval & ECC_ERRCNT_CECNT_MASK;
+	p->ue_cnt = (regval & ECC_ERRCNT_UECNT_MASK) >> ECC_ERRCNT_UECNT_SHIFT;
+	if (!p->ce_cnt)
+		goto ue_err;
+
 	regval = readl(base + ECC_CEADDR0_OFST);
 	p->ceinfo.row = (regval & ECC_CEADDR0_RW_MASK);
 	regval = readl(base + ECC_CEADDR1_OFST);
-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:13:00 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:13:00 +0300
Subject: [PATCH v5 15/20] EDAC/mc: Re-use generic unique MC index allocation procedure
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-16-fancer.lancer@gmail.com>

The EDAC drivers locally maintaining a statically defined
memory-controllers counter don't care much about the MC index assigned as
long as it's unique so the EDAC core perceives it. Convert these drivers
to be using the generic MC index allocation procedure recently added to
the EDAC core.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>

---

Changelog v4:
- Initial patch introduction.
---
 drivers/edac/dmc520_edac.c | 4 +---
 drivers/edac/pasemi_edac.c | 5 +----
 drivers/edac/ppc4xx_edac.c | 5 +----
 3 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/edac/dmc520_edac.c b/drivers/edac/dmc520_edac.c
index 4e30b989a1a4..93734a97a67b 100644
--- a/drivers/edac/dmc520_edac.c
+++ b/drivers/edac/dmc520_edac.c
@@ -173,8 +173,6 @@ struct dmc520_edac {
 	int masks[NUMBER_OF_IRQS];
 };
 
-static int dmc520_mc_idx;
-
 static u32 dmc520_read_reg(struct dmc520_edac *pvt, u32 offset)
 {
 	return readl(pvt->reg_base + offset);
@@ -517,7 +515,7 @@ static int dmc520_edac_probe(struct platform_device *pdev)
 	layers[0].size = dmc520_get_rank_count(reg_base);
 	layers[0].is_virt_csrow = true;
 
-	mci = edac_mc_alloc(dmc520_mc_idx++, ARRAY_SIZE(layers), layers, sizeof(*pvt));
+	mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers, sizeof(*pvt));
 	if (!mci) {
 		edac_printk(KERN_ERR, EDAC_MOD_NAME,
 			    "Failed to allocate memory for mc instance\n");
diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c
index 1a1c3296ccc8..afebfbda1ea0 100644
--- a/drivers/edac/pasemi_edac.c
+++ b/drivers/edac/pasemi_edac.c
@@ -57,8 +57,6 @@
 #define PASEMI_EDAC_ERROR_GRAIN			64
 
 static int last_page_in_mmc;
-static int system_mmc_id;
-
 
 static u32 pasemi_edac_get_error_info(struct mem_ctl_info *mci)
 {
@@ -203,8 +201,7 @@ static int pasemi_edac_probe(struct pci_dev *pdev,
 	layers[1].type = EDAC_MC_LAYER_CHANNEL;
 	layers[1].size = PASEMI_EDAC_NR_CHANS;
 	layers[1].is_virt_csrow = false;
-	mci = edac_mc_alloc(system_mmc_id++, ARRAY_SIZE(layers), layers,
-			    0);
+	mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers, 0);
 	if (mci == NULL)
 		return -ENOMEM;
 
diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c
index 1eea3341a916..06d267d40a6a 100644
--- a/drivers/edac/ppc4xx_edac.c
+++ b/drivers/edac/ppc4xx_edac.c
@@ -1214,7 +1214,6 @@ static int ppc4xx_edac_probe(struct platform_device *op)
 	const struct device_node *np = op->dev.of_node;
 	struct mem_ctl_info *mci = NULL;
 	struct edac_mc_layer layers[2];
-	static int ppc4xx_edac_instance;
 
 	/*
 	 * At this point, we only support the controller realized on
@@ -1265,7 +1264,7 @@ static int ppc4xx_edac_probe(struct platform_device *op)
 	layers[1].type = EDAC_MC_LAYER_CHANNEL;
 	layers[1].size = ppc4xx_edac_nr_chans;
 	layers[1].is_virt_csrow = false;
-	mci = edac_mc_alloc(ppc4xx_edac_instance, ARRAY_SIZE(layers), layers,
+	mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers,
 			    sizeof(struct ppc4xx_edac_pdata));
 	if (mci == NULL) {
 		ppc4xx_edac_printk(KERN_ERR, "%pOF: "
@@ -1303,8 +1302,6 @@ static int ppc4xx_edac_probe(struct platform_device *op)
 			goto fail1;
 	}
 
-	ppc4xx_edac_instance++;
-
 	return 0;
 
  fail1:
-- 
2.43.0



From mripard at kernel.org  Thu Feb 22 10:13:51 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:51 +0100
Subject: [PATCH v7 05/36] drm/tests: connector: Add tests for
 drmm_connector_init
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-5-8f4af575fce2@kernel.org>

drmm_connector_init is the preferred function to initialize a
drm_connector structure. Let's add a bunch of unit tests for it.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_connector_test.c | 170 ++++++++++++++++++++++++++++-
 1 file changed, 169 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index c66aa2dc8d9d..a268847be8d1 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -3,10 +3,175 @@
  * Kunit test for drm_modes functions
  */
 
+#include <linux/i2c.h>
+
+#include <drm/drm_atomic_state_helper.h>
 #include <drm/drm_connector.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_kunit_helpers.h>
 
 #include <kunit/test.h>
 
+struct drm_connector_init_priv {
+	struct drm_device drm;
+	struct drm_connector connector;
+	struct i2c_adapter ddc;
+};
+
+static const struct drm_connector_funcs dummy_funcs = {
+	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
+	.reset			= drm_atomic_helper_connector_reset,
+};
+
+static int dummy_ddc_xfer(struct i2c_adapter *adapter,
+			  struct i2c_msg *msgs, int num)
+{
+	return num;
+}
+
+static u32 dummy_ddc_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm dummy_ddc_algorithm = {
+	.master_xfer = dummy_ddc_xfer,
+	.functionality = dummy_ddc_func,
+};
+
+static void i2c_del_adapter_wrapper(void *ptr)
+{
+	struct i2c_adapter *adap = ptr;
+
+	i2c_del_adapter(adap);
+}
+
+static int drm_test_connector_init(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv;
+	struct device *dev;
+	int ret;
+
+	dev = drm_kunit_helper_alloc_device(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+	priv = drm_kunit_helper_alloc_drm_device(test, dev,
+						 struct drm_connector_init_priv, drm,
+						 DRIVER_MODESET | DRIVER_ATOMIC);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+
+	strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name));
+	priv->ddc.owner = THIS_MODULE;
+	priv->ddc.algo = &dummy_ddc_algorithm;
+	priv->ddc.dev.parent = dev;
+
+	ret = i2c_add_adapter(&priv->ddc);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	test->priv = priv;
+	return 0;
+}
+
+/*
+ * Test that the registration of a bog standard connector works as
+ * expected and doesn't report any error.
+ */
+static void drm_test_drmm_connector_init(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_init(&priv->drm, &priv->connector,
+				  &dummy_funcs,
+				  DRM_MODE_CONNECTOR_HDMIA,
+				  &priv->ddc);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector without a DDC adapter
+ * doesn't report any error.
+ */
+static void drm_test_drmm_connector_init_null_ddc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_init(&priv->drm, &priv->connector,
+				  &dummy_funcs,
+				  DRM_MODE_CONNECTOR_HDMIA,
+				  NULL);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector succeeds for all possible
+ * connector types.
+ */
+static void drm_test_drmm_connector_init_type_valid(struct kunit *test)
+{
+       struct drm_connector_init_priv *priv = test->priv;
+       unsigned int connector_type = *(unsigned int *)test->param_value;
+       int ret;
+
+       ret = drmm_connector_init(&priv->drm, &priv->connector,
+				 &dummy_funcs,
+				 connector_type,
+				 &priv->ddc);
+       KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static const unsigned int drm_connector_init_type_valid_tests[] = {
+	DRM_MODE_CONNECTOR_Unknown,
+	DRM_MODE_CONNECTOR_VGA,
+	DRM_MODE_CONNECTOR_DVII,
+	DRM_MODE_CONNECTOR_DVID,
+	DRM_MODE_CONNECTOR_DVIA,
+	DRM_MODE_CONNECTOR_Composite,
+	DRM_MODE_CONNECTOR_SVIDEO,
+	DRM_MODE_CONNECTOR_LVDS,
+	DRM_MODE_CONNECTOR_Component,
+	DRM_MODE_CONNECTOR_9PinDIN,
+	DRM_MODE_CONNECTOR_DisplayPort,
+	DRM_MODE_CONNECTOR_HDMIA,
+	DRM_MODE_CONNECTOR_HDMIB,
+	DRM_MODE_CONNECTOR_TV,
+	DRM_MODE_CONNECTOR_eDP,
+	DRM_MODE_CONNECTOR_VIRTUAL,
+	DRM_MODE_CONNECTOR_DSI,
+	DRM_MODE_CONNECTOR_DPI,
+	DRM_MODE_CONNECTOR_WRITEBACK,
+	DRM_MODE_CONNECTOR_SPI,
+	DRM_MODE_CONNECTOR_USB,
+};
+
+static void drm_connector_init_type_desc(const unsigned int *type, char *desc)
+{
+	sprintf(desc, "%s", drm_get_connector_type_name(*type));
+}
+
+KUNIT_ARRAY_PARAM(drm_connector_init_type_valid,
+		  drm_connector_init_type_valid_tests,
+		  drm_connector_init_type_desc);
+
+static struct kunit_case drmm_connector_init_tests[] = {
+	KUNIT_CASE(drm_test_drmm_connector_init),
+	KUNIT_CASE(drm_test_drmm_connector_init_null_ddc),
+	KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid,
+			 drm_connector_init_type_valid_gen_params),
+	{ }
+};
+
+static struct kunit_suite drmm_connector_init_test_suite = {
+	.name = "drmm_connector_init",
+	.init = drm_test_connector_init,
+	.test_cases = drmm_connector_init_tests,
+};
+
 struct drm_get_tv_mode_from_name_test {
 	const char *name;
 	enum drm_connector_tv_mode expected_mode;
@@ -70,7 +235,10 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
 	.test_cases = drm_get_tv_mode_from_name_tests,
 };
 
-kunit_test_suite(drm_get_tv_mode_from_name_test_suite);
+kunit_test_suites(
+	&drmm_connector_init_test_suite,
+	&drm_get_tv_mode_from_name_test_suite
+);
 
 MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");
 MODULE_LICENSE("GPL");

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:13:53 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:53 +0100
Subject: [PATCH v7 07/36] drm/tests: connector: Add tests for
 drmm_connector_hdmi_init
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-7-8f4af575fce2@kernel.org>

We just introduced a new initialization function for our connectors, so
let's build a kunit test suite for it as well.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_connector_test.c | 123 +++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index a268847be8d1..8f070cacab3b 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -172,6 +172,128 @@ static struct kunit_suite drmm_connector_init_test_suite = {
 	.test_cases = drmm_connector_init_tests,
 };
 
+/*
+ * Test that the registration of a bog standard connector works as
+ * expected and doesn't report any error.
+ */
+static void drm_test_connector_hdmi_init_valid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector without a DDC adapter
+ * doesn't report any error.
+ */
+static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       NULL);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector with an HDMI
+ * connector type succeeds.
+ */
+static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	unsigned int connector_type = *(unsigned int *)test->param_value;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       connector_type,
+				       &priv->ddc);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = {
+	DRM_MODE_CONNECTOR_HDMIA,
+	DRM_MODE_CONNECTOR_HDMIB,
+};
+
+static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc)
+{
+	sprintf(desc, "%s", drm_get_connector_type_name(*type));
+}
+
+KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid,
+		  drm_connector_hdmi_init_type_valid_tests,
+		  drm_connector_hdmi_init_type_desc);
+
+/*
+ * Test that the registration of an HDMI connector with an !HDMI
+ * connector type fails.
+ */
+static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	unsigned int connector_type = *(unsigned int *)test->param_value;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       connector_type,
+				       &priv->ddc);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = {
+	DRM_MODE_CONNECTOR_Unknown,
+	DRM_MODE_CONNECTOR_VGA,
+	DRM_MODE_CONNECTOR_DVII,
+	DRM_MODE_CONNECTOR_DVID,
+	DRM_MODE_CONNECTOR_DVIA,
+	DRM_MODE_CONNECTOR_Composite,
+	DRM_MODE_CONNECTOR_SVIDEO,
+	DRM_MODE_CONNECTOR_LVDS,
+	DRM_MODE_CONNECTOR_Component,
+	DRM_MODE_CONNECTOR_9PinDIN,
+	DRM_MODE_CONNECTOR_DisplayPort,
+	DRM_MODE_CONNECTOR_TV,
+	DRM_MODE_CONNECTOR_eDP,
+	DRM_MODE_CONNECTOR_VIRTUAL,
+	DRM_MODE_CONNECTOR_DSI,
+	DRM_MODE_CONNECTOR_DPI,
+	DRM_MODE_CONNECTOR_WRITEBACK,
+	DRM_MODE_CONNECTOR_SPI,
+	DRM_MODE_CONNECTOR_USB,
+};
+
+KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
+		  drm_connector_hdmi_init_type_invalid_tests,
+		  drm_connector_hdmi_init_type_desc);
+
+static struct kunit_case drmm_connector_hdmi_init_tests[] = {
+	KUNIT_CASE(drm_test_connector_hdmi_init_valid),
+	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
+	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
+			 drm_connector_hdmi_init_type_valid_gen_params),
+	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,
+			 drm_connector_hdmi_init_type_invalid_gen_params),
+	{ }
+};
+
+static struct kunit_suite drmm_connector_hdmi_init_test_suite = {
+	.name = "drmm_connector_hdmi_init",
+	.init = drm_test_connector_init,
+	.test_cases = drmm_connector_hdmi_init_tests,
+};
+
 struct drm_get_tv_mode_from_name_test {
 	const char *name;
 	enum drm_connector_tv_mode expected_mode;
@@ -236,6 +358,7 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
 };
 
 kunit_test_suites(
+	&drmm_connector_hdmi_init_test_suite,
 	&drmm_connector_init_test_suite,
 	&drm_get_tv_mode_from_name_test_suite
 );

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:13:57 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:57 +0100
Subject: [PATCH v7 11/36] drm/connector: hdmi: Add support for output
 format
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-11-8f4af575fce2@kernel.org>

Just like BPC, we'll add support for automatic selection of the output
format for HDMI connectors.

Let's add the needed defaults and fields for now.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic.c                       |  2 ++
 drivers/gpu/drm/drm_atomic_state_helper.c          |  3 ++-
 drivers/gpu/drm/drm_connector.c                    | 31 ++++++++++++++++++++++
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 22 +++++++++++----
 drivers/gpu/drm/tests/drm_connector_test.c         |  9 +++++++
 include/drm/drm_connector.h                        | 20 ++++++++++++++
 6 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 4e11cfb4518b..8730137baa86 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1146,6 +1146,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 	if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
 	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
 		drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
+		drm_printf(p, "\toutput_format=%s\n",
+			   drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
 	}
 
 	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 460454904fe3..ae99765c45de 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -660,7 +660,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 	struct drm_connector_state *new_state =
 		drm_atomic_get_new_connector_state(state, connector);
 
-	if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc) {
+	if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
+	    old_state->hdmi.output_format != new_state->hdmi.output_format) {
 		struct drm_crtc *crtc = new_state->crtc;
 		struct drm_crtc_state *crtc_state;
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index da51a2bcb978..b629c8e990f4 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -459,6 +459,7 @@ EXPORT_SYMBOL(drmm_connector_init);
  * @funcs: callbacks for this connector
  * @connector_type: user visible type of the connector
  * @ddc: optional pointer to the associated ddc adapter
+ * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats
  * @max_bpc: Maximum bits per char the HDMI connector supports
  *
  * Initialises a preallocated HDMI connector. Connectors can be
@@ -477,6 +478,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     const struct drm_connector_funcs *funcs,
 			     int connector_type,
 			     struct i2c_adapter *ddc,
+			     unsigned long supported_formats,
 			     unsigned int max_bpc)
 {
 	int ret;
@@ -485,6 +487,9 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 	      connector_type == DRM_MODE_CONNECTOR_HDMIB))
 		return -EINVAL;
 
+	if (!supported_formats || !(supported_formats & BIT(HDMI_COLORSPACE_RGB)))
+		return -EINVAL;
+
 	if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12))
 		return -EINVAL;
 
@@ -492,6 +497,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 	if (ret)
 		return ret;
 
+	connector->hdmi.supported_formats = supported_formats;
+
 	/*
 	 * drm_connector_attach_max_bpc_property() requires the
 	 * connector to have a state.
@@ -1201,6 +1208,30 @@ static const u32 dp_colorspaces =
 	BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) |
 	BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);
 
+static const char * const output_format_str[] = {
+	[HDMI_COLORSPACE_RGB]		= "RGB",
+	[HDMI_COLORSPACE_YUV420]	= "YUV 4:2:0",
+	[HDMI_COLORSPACE_YUV422]	= "YUV 4:2:2",
+	[HDMI_COLORSPACE_YUV444]	= "YUV 4:4:4",
+};
+
+/*
+ * drm_hdmi_connector_get_output_format_name() - Return a string for HDMI connector output format
+ * @fmt: Output format to compute name of
+ *
+ * Returns: the name of the output format, or NULL if the type is not
+ * valid.
+ */
+const char *
+drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt)
+{
+	if (fmt >= ARRAY_SIZE(output_format_str))
+		return NULL;
+
+	return output_format_str[fmt];
+}
+EXPORT_SYMBOL(drm_hdmi_connector_get_output_format_name);
+
 /**
  * DOC: standard connector properties
  *
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 5d1a1dbff433..a129ea5f014c 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -147,6 +147,7 @@ static const struct drm_connector_funcs dummy_connector_funcs = {
 static
 struct drm_atomic_helper_connector_hdmi_priv *
 drm_atomic_helper_connector_hdmi_init(struct kunit *test,
+				      unsigned int formats,
 				      unsigned int max_bpc)
 {
 	struct drm_atomic_helper_connector_hdmi_priv *priv;
@@ -190,6 +191,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test,
 				       &dummy_connector_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       NULL,
+				       formats,
 				       max_bpc);
 	KUNIT_ASSERT_EQ(test, ret, 0);
 
@@ -225,7 +227,9 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     10);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
@@ -292,7 +296,9 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 	struct drm_crtc *crtc;
 	int ret;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     10);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
@@ -361,7 +367,9 @@ static void drm_test_check_bpc_8_value(struct kunit *test)
 	struct drm_connector_state *conn_state;
 	struct drm_connector *conn;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -383,7 +391,9 @@ static void drm_test_check_bpc_10_value(struct kunit *test)
 	struct drm_connector_state *conn_state;
 	struct drm_connector *conn;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     10);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
@@ -405,7 +415,9 @@ static void drm_test_check_bpc_12_value(struct kunit *test)
 	struct drm_connector_state *conn_state;
 	struct drm_connector *conn;
 
-	priv = drm_atomic_helper_connector_hdmi_init(test, 12);
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     12);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
 	conn = &priv->connector;
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 20da290abff3..a9a57cb23235 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -187,6 +187,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
@@ -204,6 +205,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       NULL,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
@@ -221,6 +223,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       9);
 	KUNIT_EXPECT_LT(test, ret, 0);
 }
@@ -238,6 +241,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       0);
 	KUNIT_EXPECT_LT(test, ret, 0);
 }
@@ -259,6 +263,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
@@ -292,6 +297,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       10);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
@@ -325,6 +331,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       12);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
@@ -355,6 +362,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
 				       &dummy_funcs,
 				       connector_type,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
@@ -387,6 +395,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
 				       &dummy_funcs,
 				       connector_type,
 				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
 				       8);
 	KUNIT_EXPECT_LT(test, ret, 0);
 }
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index d4d2ae15bc1e..29883e6f8e50 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -368,6 +368,9 @@ enum drm_panel_orientation {
 	DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
 };
 
+const char *
+drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt);
+
 /**
  * struct drm_monitor_range_info - Panel's Monitor range in EDID for
  * &drm_display_info
@@ -1041,6 +1044,11 @@ struct drm_connector_state {
 		 * @output_bpc: Bits per color channel to output.
 		 */
 		unsigned int output_bpc;
+
+		/**
+		 * @output_format: Pixel format to output in.
+		 */
+		enum hdmi_colorspace output_format;
 	} hdmi;
 };
 
@@ -1902,6 +1910,17 @@ struct drm_connector {
 
 	/** @hdr_sink_metadata: HDR Metadata Information read from sink */
 	struct hdr_sink_metadata hdr_sink_metadata;
+
+	/**
+	 * @hdmi: HDMI-related variable and properties.
+	 */
+	struct {
+		/**
+		 * @supported_formats: Bitmask of @hdmi_colorspace
+		 * supported by the controller.
+		 */
+		unsigned long supported_formats;
+	} hdmi;
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -1925,6 +1944,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     const struct drm_connector_funcs *funcs,
 			     int connector_type,
 			     struct i2c_adapter *ddc,
+			     unsigned long supported_formats,
 			     unsigned int max_bpc);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:04 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:04 +0100
Subject: [PATCH v7 18/36] drm/tests: Add HDMI connector rate filter hook
 tests
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-18-8f4af575fce2@kernel.org>

The previous patch adds a new hook for HDMI connectors to filter out
configurations based on the TMDS character rate. Let's add some tests to
make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 65 ++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 989661ad3aee..5a8750153510 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -113,6 +113,18 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto
 static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
 };
 
+static enum drm_mode_status
+reject_connector_tmds_char_rate_valid(const struct drm_connector *connector,
+				       const struct drm_display_mode *mode,
+				       unsigned long long tmds_rate)
+{
+	return MODE_BAD;
+}
+
+static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = {
+	.tmds_char_rate_valid	= reject_connector_tmds_char_rate_valid,
+};
+
 static int dummy_connector_get_modes(struct drm_connector *connector)
 {
 	struct drm_atomic_helper_connector_hdmi_priv *priv =
@@ -491,7 +503,60 @@ static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500);
 }
 
+/*
+ * Test that if we filter a rate through our hook, it's indeed rejected
+ * by the whole atomic_check logic.
+ *
+ * We do so by first doing a commit on the pipeline to make sure that it
+ * works, change the HDMI helpers pointer, and then try the same commit
+ * again to see if it fails as it should.
+ */
+static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	conn = &priv->connector;
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	/* You shouldn't be doing that at home. */
+	conn->hdmi.funcs = &reject_connector_hdmi_funcs;
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+	crtc_state->connectors_changed = true;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
+	KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:03 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:03 +0100
Subject: [PATCH v7 17/36] drm/connector: hdmi: Add custom hook to filter
 TMDS character rate
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-17-8f4af575fce2@kernel.org>

Most of the HDMI controllers have an upper TMDS character rate limit
they can't exceed. On "embedded"-grade display controllers, it will
typically be lower than what high-grade monitors can provide these days,
so drivers will filter the TMDS character rate based on the controller
capabilities.

To make that easier to handle for drivers, let's provide an optional
hook to be implemented by drivers so they can tell the HDMI controller
helpers if a given TMDS character rate is reachable for them or not.

This will then be useful to figure out the best format and bpc count for
a given mode.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c          |  9 +++++++
 drivers/gpu/drm/drm_connector.c                    |  4 +++
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  4 +++
 drivers/gpu/drm/tests/drm_connector_test.c         | 14 ++++++++++
 include/drm/drm_connector.h                        | 30 ++++++++++++++++++++++
 5 files changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 63a96c691460..448b4a73d1c8 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -667,11 +667,20 @@ hdmi_clock_valid(const struct drm_connector *connector,
 		 const struct drm_display_mode *mode,
 		 unsigned long long clock)
 {
+	const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
 	const struct drm_display_info *info = &connector->display_info;
 
 	if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000)
 		return MODE_CLOCK_HIGH;
 
+	if (funcs && funcs->tmds_char_rate_valid) {
+		enum drm_mode_status status;
+
+		status = funcs->tmds_char_rate_valid(connector, mode, clock);
+		if (status != MODE_OK)
+			return status;
+	}
+
 	return MODE_OK;
 }
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 8cc1332f11c2..591d2d500f61 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -457,6 +457,7 @@ EXPORT_SYMBOL(drmm_connector_init);
  * @dev: DRM device
  * @connector: A pointer to the HDMI connector to init
  * @funcs: callbacks for this connector
+ * @hdmi_funcs: HDMI-related callbacks for this connector
  * @connector_type: user visible type of the connector
  * @ddc: optional pointer to the associated ddc adapter
  * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats
@@ -476,6 +477,7 @@ EXPORT_SYMBOL(drmm_connector_init);
 int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
 			     const struct drm_connector_funcs *funcs,
+			     const struct drm_connector_hdmi_funcs *hdmi_funcs,
 			     int connector_type,
 			     struct i2c_adapter *ddc,
 			     unsigned long supported_formats,
@@ -512,6 +514,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 	if (max_bpc > 8)
 		drm_connector_attach_hdr_output_metadata_property(connector);
 
+	connector->hdmi.funcs = hdmi_funcs;
+
 	return 0;
 }
 EXPORT_SYMBOL(drmm_connector_hdmi_init);
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index dfed45b250a5..989661ad3aee 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -110,6 +110,9 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto
 	return 0;
 }
 
+static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
+};
+
 static int dummy_connector_get_modes(struct drm_connector *connector)
 {
 	struct drm_atomic_helper_connector_hdmi_priv *priv =
@@ -192,6 +195,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test,
 	conn = &priv->connector;
 	ret = drmm_connector_hdmi_init(drm, conn,
 				       &dummy_connector_funcs,
+				       &dummy_connector_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       NULL,
 				       formats,
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 882b9269148e..732c59a1d4d5 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -22,6 +22,9 @@ struct drm_connector_init_priv {
 	struct i2c_adapter ddc;
 };
 
+static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = {
+};
+
 static const struct drm_connector_funcs dummy_funcs = {
 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
 	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
@@ -187,6 +190,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -205,6 +209,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       NULL,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -223,6 +228,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -241,6 +247,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -263,6 +270,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -297,6 +305,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -331,6 +340,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -361,6 +371,7 @@ static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       0,
@@ -379,6 +390,7 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_YUV422),
@@ -398,6 +410,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       connector_type,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
@@ -431,6 +444,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
 				       connector_type,
 				       &priv->ddc,
 				       BIT(HDMI_COLORSPACE_RGB),
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index e3917ea93986..8cda902934cd 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1058,6 +1058,30 @@ struct drm_connector_state {
 	} hdmi;
 };
 
+/**
+ * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
+ */
+struct drm_connector_hdmi_funcs {
+	/**
+	 * @tmds_char_rate_valid:
+	 *
+	 * This callback is invoked at atomic_check time to figure out
+	 * whether a particular TMDS character rate is supported by the
+	 * driver.
+	 *
+	 * The @tmds_char_rate_valid callback is optional.
+	 *
+	 * Returns:
+	 *
+	 * Either &drm_mode_status.MODE_OK or one of the failure reasons
+	 * in &enum drm_mode_status.
+	 */
+	enum drm_mode_status
+	(*tmds_char_rate_valid)(const struct drm_connector *connector,
+				const struct drm_display_mode *mode,
+				unsigned long long tmds_rate);
+};
+
 /**
  * struct drm_connector_funcs - control connectors on a given device
  *
@@ -1926,6 +1950,11 @@ struct drm_connector {
 		 * supported by the controller.
 		 */
 		unsigned long supported_formats;
+
+		/**
+		 * @funcs: HDMI connector Control Functions
+		 */
+		const struct drm_connector_hdmi_funcs *funcs;
 	} hdmi;
 };
 
@@ -1948,6 +1977,7 @@ int drmm_connector_init(struct drm_device *dev,
 int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
 			     const struct drm_connector_funcs *funcs,
+			     const struct drm_connector_hdmi_funcs *hdmi_funcs,
 			     int connector_type,
 			     struct i2c_adapter *ddc,
 			     unsigned long supported_formats,

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:02 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:02 +0100
Subject: [PATCH v7 16/36] drm/tests: Add TDMS character rate connector
 state tests
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-16-8f4af575fce2@kernel.org>

The previous patch stores in the connector state the expected TMDS
character rate matching the configuration of the HDMI connector. Let's
add a few tests to make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 166 ++++++++++++++++
 drivers/gpu/drm/tests/drm_kunit_edid.h             | 216 +++++++++++++++++++++
 2 files changed, 382 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index f2acbd4c216c..dfed45b250a5 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -347,9 +347,152 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 }
 
+/*
+ * Test that when doing a commit which would use RGB 8bpc, the TMDS
+ * clock rate stored in the connector state is equal to the mode clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8);
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000);
+}
+
+/*
+ * Test that when doing a commit which would use RGB 10bpc, the TMDS
+ * clock rate stored in the connector state is equal to 1.25 times the
+ * mode pixel clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     10);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10);
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
+}
+
+/*
+ * Test that when doing a commit which would use RGB 12bpc, the TMDS
+ * clock rate stored in the connector state is equal to 1.5 times the
+ * mode pixel clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12);
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
+	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
+	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
+	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
 	/*
 	 * TODO: We should have tests to check that a change in the
 	 * format triggers a CRTC mode change just like we do for the
@@ -461,11 +604,34 @@ static void drm_test_check_format_value(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
 }
 
+/*
+ * Test that the value of the output format property out of reset is set
+ * to 0, and will be computed at atomic_check time.
+ */
+static void drm_test_check_tmds_char_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, 0);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
 	KUNIT_CASE(drm_test_check_bpc_8_value),
 	KUNIT_CASE(drm_test_check_bpc_10_value),
 	KUNIT_CASE(drm_test_check_bpc_12_value),
 	KUNIT_CASE(drm_test_check_format_value),
+	KUNIT_CASE(drm_test_check_tmds_char_value),
 	{ }
 };
 
diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h
index 2bba316de064..24f3377ef0f0 100644
--- a/drivers/gpu/drm/tests/drm_kunit_edid.h
+++ b/drivers/gpu/drm/tests/drm_kunit_edid.h
@@ -103,4 +103,220 @@ const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {
   0x00, 0x00, 0x00, 0xd0
 };
 
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 1a 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 7a
+ *
+ * 02 03 1b b1 e3 05 00 20 41 10 e2 00 ca 6d 03 0c
+ * 00 12 34 78 28 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a8
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ *   EDID Structure Version & Revision: 1.3
+ *   Vendor & Product Identification:
+ *     Manufacturer: LNX
+ *     Model: 42
+ *     Made in: 2023
+ *   Basic Display Parameters & Features:
+ *     Digital display
+ *     DFP 1.x compatible TMDS
+ *     Maximum image size: 160 cm x 90 cm
+ *     Gamma: 2.20
+ *     Undefined display color type
+ *     First detailed timing is the preferred timing
+ *   Color Characteristics:
+ *     Red  : 0.0000, 0.0000
+ *     Green: 0.0000, 0.0000
+ *     Blue : 0.0000, 0.0000
+ *     White: 0.0000, 0.0000
+ *   Established Timings I & II:
+ *     DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
+ *   Standard Timings: none
+ *   Detailed Timing Descriptors:
+ *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (1600 mm x 900 mm)
+ *                  Hfront   88 Hsync  44 Hback  148 Hpol P
+ *                  Vfront    4 Vsync   5 Vback   36 Vpol P
+ *     Display Product Name: 'Test EDID'
+ *     Display Range Limits:
+ *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ *     Dummy Descriptor:
+ *   Extension blocks: 1
+ * Checksum: 0x7a
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ *   Revision: 3
+ *   Underscans IT Video Formats by default
+ *   Supports YCbCr 4:4:4
+ *   Supports YCbCr 4:2:2
+ *   Native detailed modes: 1
+ *   Colorimetry Data Block:
+ *     sRGB
+ *   Video Data Block:
+ *     VIC  16:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz
+ *   Video Capability Data Block:
+ *     YCbCr quantization: Selectable (via AVI YQ)
+ *     RGB quantization: Selectable (via AVI Q)
+ *     PT scan behavior: No Data
+ *     IT scan behavior: Always Underscanned
+ *     CE scan behavior: Always Underscanned
+ *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ *     Source physical address: 1.2.3.4
+ *     DC_48bit
+ *     DC_36bit
+ *     DC_30bit
+ *     DC_Y444
+ *     Maximum TMDS clock: 200 MHz
+ *     Extended HDMI video details:
+ * Checksum: 0xa8  Unused space in Extension Block: 100 bytes
+ */
+const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz[] = {
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+  0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+  0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+  0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+  0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7a, 0x02, 0x03, 0x1b, 0xb1,
+  0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x6d, 0x03, 0x0c,
+  0x00, 0x12, 0x34, 0x78, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xa8
+};
+
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 0a 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 8a
+ *
+ * 02 03 1b b1 e3 05 00 20 41 10 e2 00 ca 6d 03 0c
+ * 00 12 34 78 44 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8c
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ *   EDID Structure Version & Revision: 1.3
+ *   Vendor & Product Identification:
+ *     Manufacturer: LNX
+ *     Model: 42
+ *     Made in: 2023
+ *   Basic Display Parameters & Features:
+ *     Digital display
+ *     DFP 1.x compatible TMDS
+ *     Maximum image size: 160 cm x 90 cm
+ *     Gamma: 2.20
+ *     RGB color display
+ *     First detailed timing is the preferred timing
+ *   Color Characteristics:
+ *     Red  : 0.0000, 0.0000
+ *     Green: 0.0000, 0.0000
+ *     Blue : 0.0000, 0.0000
+ *     White: 0.0000, 0.0000
+ *   Established Timings I & II:
+ *     DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
+ *   Standard Timings: none
+ *   Detailed Timing Descriptors:
+ *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (1600 mm x 900 mm)
+ *                  Hfront   88 Hsync  44 Hback  148 Hpol P
+ *                  Vfront    4 Vsync   5 Vback   36 Vpol P
+ *     Display Product Name: 'Test EDID'
+ *     Display Range Limits:
+ *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ *     Dummy Descriptor:
+ *   Extension blocks: 1
+ * Checksum: 0x8a
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ *   Revision: 3
+ *   Underscans IT Video Formats by default
+ *   Supports YCbCr 4:4:4
+ *   Supports YCbCr 4:2:2
+ *   Native detailed modes: 1
+ *   Colorimetry Data Block:
+ *     sRGB
+ *   Video Data Block:
+ *     VIC  16:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz
+ *   Video Capability Data Block:
+ *     YCbCr quantization: Selectable (via AVI YQ)
+ *     RGB quantization: Selectable (via AVI Q)
+ *     PT scan behavior: No Data
+ *     IT scan behavior: Always Underscanned
+ *     CE scan behavior: Always Underscanned
+ *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ *     Source physical address: 1.2.3.4
+ *     DC_48bit
+ *     DC_36bit
+ *     DC_30bit
+ *     DC_Y444
+ *     Maximum TMDS clock: 340 MHz
+ *     Extended HDMI video details:
+ * Checksum: 0x8c  Unused space in Extension Block: 100 bytes
+ */
+const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz[] = {
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+  0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+  0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+  0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+  0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8a, 0x02, 0x03, 0x1b, 0xb1,
+  0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x6d, 0x03, 0x0c,
+  0x00, 0x12, 0x34, 0x78, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x8c
+};
+
 #endif // DRM_KUNIT_EDID_H_

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:13:59 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:59 +0100
Subject: [PATCH v7 13/36] drm/connector: hdmi: Add HDMI compute clock
 helper
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-13-8f4af575fce2@kernel.org>

A lot of HDMI drivers have some variation of the formula to calculate
the TMDS character rate from a mode, but few of them actually take all
parameters into account.

Let's create a helper to provide that rate taking all parameters into
account.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_connector.c | 71 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     |  5 +++
 2 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b629c8e990f4..8cc1332f11c2 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2897,6 +2897,77 @@ void drm_connector_update_privacy_screen(const struct drm_connector_state *conne
 }
 EXPORT_SYMBOL(drm_connector_update_privacy_screen);
 
+/**
+ * drm_connector_hdmi_compute_mode_clock() - Computes the TMDS Character Rate
+ * @mode: Display mode to compute the clock for
+ * @bpc: Bits per character
+ * @fmt: Output Pixel Format used
+ *
+ * Returns the TMDS Character Rate for a given mode, bpc count and output format.
+ *
+ * RETURNS:
+ * The TMDS Character Rate, in Hertz, or 0 on error.
+ */
+unsigned long long
+drm_connector_hdmi_compute_mode_clock(const struct drm_display_mode *mode,
+				      unsigned int bpc,
+				      enum hdmi_colorspace fmt)
+{
+	unsigned long long clock = mode->clock * 1000ULL;
+	unsigned int vic = drm_match_cea_mode(mode);
+
+	/*
+	 * CTA-861-G Spec, section 5.4 - Color Coding and Quantization
+	 * mandates that VIC 1 always uses 8 bpc.
+	 */
+	if (vic == 1 && bpc != 8)
+		return 0;
+
+	/*
+	 * HDMI 2.0 Spec, section 7.1 - YCbCr 4:2:0 Pixel Encoding
+	 * specifies that YUV420 encoding is only available for those
+	 * VICs.
+	 */
+	if (fmt == HDMI_COLORSPACE_YUV420 &&
+	    !(vic == 96 || vic == 97 || vic == 101 ||
+	      vic == 102 || vic == 106 || vic == 107))
+		return 0;
+
+	if (fmt == HDMI_COLORSPACE_YUV422) {
+		/*
+		 * HDMI 1.4b Spec, section 6.2.3 - Pixel Encoding Requirements
+		 * specifies that YUV422 is 36-bit only.
+		 */
+		if (bpc != 12)
+			return 0;
+
+		/*
+		 * HDMI 1.0 Spec, section 6.5 - Pixel Encoding
+		 * specifies that YUV422 requires two 12-bits components per
+		 * pixel clock, which is equivalent in our calculation to three
+		 * 8-bits components
+		 */
+		bpc = 8;
+	}
+
+	/*
+	 * HDMI 2.0 Spec, Section 7.1 - YCbCr 4:2:0 Pixel Encoding
+	 * specifies that YUV420 encoding is carried at a TMDS Character Rate
+	 * equal to half the pixel clock rate.
+	 */
+	if (fmt == HDMI_COLORSPACE_YUV420)
+		clock = clock / 2;
+
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		clock = clock * 2;
+
+	clock = clock * bpc;
+	do_div(clock, 8);
+
+	return clock;
+}
+EXPORT_SYMBOL(drm_connector_hdmi_compute_mode_clock);
+
 int drm_connector_set_obj_prop(struct drm_mode_object *obj,
 				    struct drm_property *property,
 				    uint64_t value)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 29883e6f8e50..a859ad7ee04b 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -38,6 +38,7 @@ struct drm_connector_helper_funcs;
 struct drm_modeset_acquire_ctx;
 struct drm_device;
 struct drm_crtc;
+struct drm_display_mode;
 struct drm_encoder;
 struct drm_panel;
 struct drm_property;
@@ -2094,6 +2095,10 @@ void drm_connector_attach_privacy_screen_properties(struct drm_connector *conn);
 void drm_connector_attach_privacy_screen_provider(
 	struct drm_connector *connector, struct drm_privacy_screen *priv);
 void drm_connector_update_privacy_screen(const struct drm_connector_state *connector_state);
+unsigned long long
+drm_connector_hdmi_compute_mode_clock(const struct drm_display_mode *mode,
+				      unsigned int bpc,
+				      enum hdmi_colorspace fmt);
 
 /**
  * struct drm_tile_group - Tile group metadata

-- 
2.43.2



From fancer.lancer at gmail.com  Thu Feb 22 10:13:05 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:13:05 +0300
Subject: [PATCH v5 20/20] EDAC/synopsys: Convert to using BIT/GENMASK/FIELD_x macros
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-21-fancer.lancer@gmail.com>

Instead of using the very handy helpers denoted in the subject the driver
has been created with the open-coded {mask,shift} statements. It makes the
code bulky, prone to mistakes and much harder to read. Seeing there are
many places in the driver implementing the CSR fields get/set pattern use
the FIELD_GET()/FIELD_PREP() macros introduced in the kernel specifically
for that case. In addition use the BIT() and GENMASK() macros to generate
the CSR flags/masks. While at it unify the row, column, rank, bank and
bank group macros names to be having a suffix similar to the
snps_ecc_error_info structure fields name.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
---
 drivers/edac/synopsys_edac.c | 137 +++++++++++++++++------------------
 1 file changed, 67 insertions(+), 70 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index c46cee035c0d..f181cd7b4447 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -6,6 +6,8 @@
  * Copyright (C) 2012 - 2014 Xilinx, Inc.
  */
 
+#include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/edac.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -89,33 +91,29 @@
 #define ZYNQMP_DDR_QOS_IRQ_DB_OFST	0x2020C
 
 /* DDR Master register definitions */
-#define DDR_MSTR_DEV_CFG_MASK		0xC0000000
-#define DDR_MSTR_DEV_CFG_SHIFT		30
+#define DDR_MSTR_DEV_CFG_MASK		GENMASK(31, 30)
 #define DDR_MSTR_DEV_X4			0
 #define DDR_MSTR_DEV_X8			1
 #define DDR_MSTR_DEV_X16		2
 #define DDR_MSTR_DEV_X32		3
-#define DDR_MSTR_BUSWIDTH_MASK		0x3000
-#define DDR_MSTR_BUSWIDTH_SHIFT		12
+#define DDR_MSTR_BUSWIDTH_MASK		GENMASK(13, 12)
 #define DDR_MSTR_BUSWIDTH_16		2
 #define DDR_MSTR_BUSWIDTH_32		1
 #define DDR_MSTR_BUSWIDTH_64		0
-#define DDR_MSTR_MEM_LPDDR4		0x20
-#define DDR_MSTR_MEM_DDR4		0x10
-#define DDR_MSTR_MEM_LPDDR3		0x8
-#define DDR_MSTR_MEM_DDR2		0x4
-#define DDR_MSTR_MEM_DDR3		0x1
+#define DDR_MSTR_MEM_LPDDR4		BIT(5)
+#define DDR_MSTR_MEM_DDR4		BIT(4)
+#define DDR_MSTR_MEM_LPDDR3		BIT(3)
+#define DDR_MSTR_MEM_DDR2		BIT(2)
+#define DDR_MSTR_MEM_DDR3		BIT(0)
 
 /* ECC CFG0 register definitions */
-#define ECC_CFG0_MODE_MASK		0x7
+#define ECC_CFG0_MODE_MASK		GENMASK(2, 0)
 #define ECC_CFG0_MODE_SECDED		0x4
 
 /* ECC status register definitions */
-#define ECC_STAT_UECNT_MASK		0xF0000
-#define ECC_STAT_UECNT_SHIFT		16
-#define ECC_STAT_CECNT_MASK		0xF00
-#define ECC_STAT_CECNT_SHIFT		8
-#define ECC_STAT_BITNUM_MASK		0x7F
+#define ECC_STAT_UE_MASK		GENMASK(23, 16)
+#define ECC_STAT_CE_MASK		GENMASK(15, 8)
+#define ECC_STAT_BITNUM_MASK		GENMASK(6, 0)
 
 /* ECC control/clear register definitions */
 #define ECC_CTRL_CLR_CE_ERR		BIT(0)
@@ -126,34 +124,26 @@
 #define ECC_CTRL_EN_UE_IRQ		BIT(9)
 
 /* ECC error count register definitions */
-#define ECC_ERRCNT_UECNT_MASK		0xFFFF0000
-#define ECC_ERRCNT_UECNT_SHIFT		16
-#define ECC_ERRCNT_CECNT_MASK		0xFFFF
-
-/* ECC Corrected Error Register Mask and Shifts*/
-#define ECC_CEADDR0_RW_MASK		0x3FFFF
-#define ECC_CEADDR0_RNK_MASK		BIT(24)
-#define ECC_CEADDR1_BNKGRP_MASK		0x3000000
-#define ECC_CEADDR1_BNKNR_MASK		0x70000
-#define ECC_CEADDR1_COL_MASK		0xFFF
-#define ECC_CEADDR1_BNKGRP_SHIFT	24
-#define ECC_CEADDR1_BNKNR_SHIFT		16
-
-/* ECC Poison register shifts */
-#define ECC_POISON0_RANK_SHIFT		24
-#define ECC_POISON0_RANK_MASK		BIT(24)
-#define ECC_POISON0_COLUMN_SHIFT	0
-#define ECC_POISON0_COLUMN_MASK		0xFFF
-#define ECC_POISON1_BG_SHIFT		28
-#define ECC_POISON1_BG_MASK		0x30000000
-#define ECC_POISON1_BANKNR_SHIFT	24
-#define ECC_POISON1_BANKNR_MASK		0x7000000
-#define ECC_POISON1_ROW_SHIFT		0
-#define ECC_POISON1_ROW_MASK		0x3FFFF
+#define ECC_ERRCNT_UECNT_MASK		GENMASK(31, 16)
+#define ECC_ERRCNT_CECNT_MASK		GENMASK(15, 0)
+
+/* ECC Corrected Error register definitions */
+#define ECC_CEADDR0_RANK_MASK		GENMASK(27, 24)
+#define ECC_CEADDR0_ROW_MASK		GENMASK(17, 0)
+#define ECC_CEADDR1_BANKGRP_MASK	GENMASK(25, 24)
+#define ECC_CEADDR1_BANK_MASK		GENMASK(23, 16)
+#define ECC_CEADDR1_COL_MASK		GENMASK(11, 0)
+
+/* ECC Poison register definitions */
+#define ECC_POISON0_RANK_MASK		GENMASK(27, 24)
+#define ECC_POISON0_COL_MASK		GENMASK(11, 0)
+#define ECC_POISON1_BANKGRP_MASK	GENMASK(29, 28)
+#define ECC_POISON1_BANK_MASK		GENMASK(26, 24)
+#define ECC_POISON1_ROW_MASK		GENMASK(17, 0)
 
 /* DDRC ECC CE & UE poison mask */
-#define ECC_CEPOISON_MASK		0x3
-#define ECC_UEPOISON_MASK		0x1
+#define ECC_CEPOISON_MASK		GENMASK(1, 0)
+#define ECC_UEPOISON_MASK		BIT(0)
 
 /* DDRC Device config shifts/masks */
 #define DDR_MAX_ROW_SHIFT		18
@@ -209,9 +199,9 @@
 #define RANK_B0_BASE			6
 
 /* ZynqMP DDR QOS Interrupt register definitions */
-#define ZYNQMP_DDR_QOS_UE_MASK		0x4
-#define ZYNQMP_DDR_QOS_CE_MASK		0x2
-#define ZYNQMP_DDR_QOS_IRQ_MASK		0x6
+#define ZYNQMP_DDR_QOS_UE_MASK		BIT(2)
+#define ZYNQMP_DDR_QOS_CE_MASK		BIT(1)
+#define ZYNQMP_DDR_QOS_IRQ_MASK		(ZYNQMP_DDR_QOS_UE_MASK | ZYNQMP_DDR_QOS_CE_MASK)
 
 /**
  * struct snps_ecc_error_info - ECC error log information.
@@ -303,38 +293,40 @@ static int snps_get_error_info(struct snps_edac_priv *priv)
 	if (!regval)
 		return 1;
 
-	p->ceinfo.bitpos = (regval & ECC_STAT_BITNUM_MASK);
+	p->ceinfo.bitpos = FIELD_GET(ECC_STAT_BITNUM_MASK, regval);
 
 	regval = readl(base + ECC_ERRCNT_OFST);
-	p->ce_cnt = regval & ECC_ERRCNT_CECNT_MASK;
-	p->ue_cnt = (regval & ECC_ERRCNT_UECNT_MASK) >> ECC_ERRCNT_UECNT_SHIFT;
+	p->ce_cnt = FIELD_GET(ECC_ERRCNT_CECNT_MASK, regval);
+	p->ue_cnt = FIELD_GET(ECC_ERRCNT_UECNT_MASK, regval);
 	if (!p->ce_cnt)
 		goto ue_err;
 
 	regval = readl(base + ECC_CEADDR0_OFST);
-	p->ceinfo.row = (regval & ECC_CEADDR0_RW_MASK);
+	p->ceinfo.row = FIELD_GET(ECC_CEADDR0_ROW_MASK, regval);
+
 	regval = readl(base + ECC_CEADDR1_OFST);
-	p->ceinfo.bank = (regval & ECC_CEADDR1_BNKNR_MASK) >>
-					ECC_CEADDR1_BNKNR_SHIFT;
-	p->ceinfo.bankgrp = (regval & ECC_CEADDR1_BNKGRP_MASK) >>
-					ECC_CEADDR1_BNKGRP_SHIFT;
-	p->ceinfo.col = (regval & ECC_CEADDR1_COL_MASK);
+	p->ceinfo.bank = FIELD_GET(ECC_CEADDR1_BANK_MASK, regval);
+	p->ceinfo.bankgrp = FIELD_GET(ECC_CEADDR1_BANKGRP_MASK, regval);
+	p->ceinfo.col = FIELD_GET(ECC_CEADDR1_COL_MASK, regval);
+
 	p->ceinfo.data = readl(base + ECC_CSYND0_OFST);
+
 	edac_dbg(2, "ECCCSYN0: 0x%08X ECCCSYN1: 0x%08X ECCCSYN2: 0x%08X\n",
 		 readl(base + ECC_CSYND0_OFST), readl(base + ECC_CSYND1_OFST),
 		 readl(base + ECC_CSYND2_OFST));
+
 ue_err:
 	if (!p->ue_cnt)
 		goto out;
 
 	regval = readl(base + ECC_UEADDR0_OFST);
-	p->ueinfo.row = (regval & ECC_CEADDR0_RW_MASK);
+	p->ueinfo.row = FIELD_GET(ECC_CEADDR0_ROW_MASK, regval);
+
 	regval = readl(base + ECC_UEADDR1_OFST);
-	p->ueinfo.bankgrp = (regval & ECC_CEADDR1_BNKGRP_MASK) >>
-					ECC_CEADDR1_BNKGRP_SHIFT;
-	p->ueinfo.bank = (regval & ECC_CEADDR1_BNKNR_MASK) >>
-					ECC_CEADDR1_BNKNR_SHIFT;
-	p->ueinfo.col = (regval & ECC_CEADDR1_COL_MASK);
+	p->ueinfo.bankgrp = FIELD_GET(ECC_CEADDR1_BANKGRP_MASK, regval);
+	p->ueinfo.bank = FIELD_GET(ECC_CEADDR1_BANK_MASK, regval);
+	p->ueinfo.col = FIELD_GET(ECC_CEADDR1_COL_MASK, regval);
+
 	p->ueinfo.data = readl(base + ECC_UESYND0_OFST);
 out:
 	spin_lock_irqsave(&priv->reglock, flags);
@@ -483,7 +475,7 @@ static enum dev_type snps_get_dtype(const void __iomem *base)
 	if (!(regval & DDR_MSTR_MEM_DDR4))
 		return DEV_UNKNOWN;
 
-	regval = (regval & DDR_MSTR_DEV_CFG_MASK) >> DDR_MSTR_DEV_CFG_SHIFT;
+	regval = FIELD_GET(DDR_MSTR_DEV_CFG_MASK, regval);
 	switch (regval) {
 	case DDR_MSTR_DEV_X4:
 		return DEV_X4;
@@ -510,7 +502,8 @@ static bool snps_get_ecc_state(void __iomem *base)
 {
 	u32 regval;
 
-	regval = readl(base + ECC_CFG0_OFST) & ECC_CFG0_MODE_MASK;
+	regval = readl(base + ECC_CFG0_OFST);
+	regval = FIELD_GET(ECC_CFG0_MODE_MASK, regval);
 
 	return (regval == ECC_CFG0_MODE_SECDED);
 }
@@ -697,13 +690,13 @@ static void snps_data_poison_setup(struct snps_edac_priv *priv)
 	if (priv->rank_shift[0])
 		rank = (hif_addr >> priv->rank_shift[0]) & BIT(0);
 
-	regval = (rank << ECC_POISON0_RANK_SHIFT) & ECC_POISON0_RANK_MASK;
-	regval |= (col << ECC_POISON0_COLUMN_SHIFT) & ECC_POISON0_COLUMN_MASK;
+	regval = FIELD_PREP(ECC_POISON0_RANK_MASK, rank) |
+		 FIELD_PREP(ECC_POISON0_COL_MASK, col);
 	writel(regval, priv->baseaddr + ECC_POISON0_OFST);
 
-	regval = (bankgrp << ECC_POISON1_BG_SHIFT) & ECC_POISON1_BG_MASK;
-	regval |= (bank << ECC_POISON1_BANKNR_SHIFT) & ECC_POISON1_BANKNR_MASK;
-	regval |= (row << ECC_POISON1_ROW_SHIFT) & ECC_POISON1_ROW_MASK;
+	regval = FIELD_PREP(ECC_POISON1_BANKGRP_MASK, bankgrp) |
+		 FIELD_PREP(ECC_POISON1_BANK_MASK, bank) |
+		 FIELD_PREP(ECC_POISON1_ROW_MASK, row);
 	writel(regval, priv->baseaddr + ECC_POISON1_OFST);
 }
 
@@ -742,10 +735,14 @@ static ssize_t inject_data_poison_show(struct device *dev,
 {
 	struct mem_ctl_info *mci = to_mci(dev);
 	struct snps_edac_priv *priv = mci->pvt_info;
+	const char *errstr;
+	u32 regval;
+
+	regval = readl(priv->baseaddr + ECC_CFG1_OFST);
+	errstr = FIELD_GET(ECC_CEPOISON_MASK, regval) == ECC_CEPOISON_MASK ?
+		 "Correctable Error" : "UnCorrectable Error";
 
-	return sprintf(data, "Data Poisoning: %s\n\r",
-			(((readl(priv->baseaddr + ECC_CFG1_OFST)) & 0x3) == 0x3)
-			? ("Correctable Error") : ("UnCorrectable Error"));
+	return sprintf(data, "Data Poisoning: %s\n\r", errstr);
 }
 
 static ssize_t inject_data_poison_store(struct device *dev,
@@ -852,7 +849,7 @@ static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addr
 	int index;
 
 	memtype = readl(priv->baseaddr + DDR_MSTR_OFST);
-	width = (memtype & DDR_MSTR_BUSWIDTH_MASK) >> DDR_MSTR_BUSWIDTH_SHIFT;
+	width = FIELD_GET(DDR_MSTR_BUSWIDTH_MASK, memtype);
 
 	priv->col_shift[0] = 0;
 	priv->col_shift[1] = 1;
-- 
2.43.0



From mripard at kernel.org  Thu Feb 22 10:14:00 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:00 +0100
Subject: [PATCH v7 14/36] drm/tests: Add HDMI TDMS character rate tests
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-14-8f4af575fce2@kernel.org>

The previous patch added an helper to compute the TMDS character rate on
an HDMI connector. Let's add a few tests to make sure it works as
expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_connector_test.c | 323 +++++++++++++++++++++++++++++
 1 file changed, 323 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 5bff67fbed87..882b9269148e 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -8,7 +8,9 @@
 #include <drm/drm_atomic_state_helper.h>
 #include <drm/drm_connector.h>
 #include <drm/drm_drv.h>
+#include <drm/drm_edid.h>
 #include <drm/drm_kunit_helpers.h>
+#include <drm/drm_modes.h>
 
 #include <kunit/test.h>
 
@@ -606,9 +608,330 @@ static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite =
 	.test_cases = drm_hdmi_connector_get_output_format_name_tests,
 };
 
+/*
+ * Test that for a given mode, with 8bpc and an RGB output the TMDS
+ * character rate is equal to the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate);
+}
+
+/*
+ * Test that for a given mode, with 10bpc and an RGB output the TMDS
+ * character rate is equal to 1.25 times the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate);
+}
+
+/*
+ * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS
+ * character rate computation fails.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a given mode, with 12bpc and an RGB output the TMDS
+ * character rate is equal to 1.5 times the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate);
+}
+
+/*
+ * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS
+ * character rate computation fails.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a mode with the pixel repetition flag, the TMDS
+ * character rate is indeed double the mode pixel clock.
+ */
+static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_double(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_device *drm = &priv->drm;
+
+	mode = drm_display_mode_from_cea_vic(drm, 6);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate);
+}
+
+/*
+ * Test that the TMDS character rate computation for the VIC modes
+ * explicitly listed in the spec as supporting YUV420 succeed and return
+ * half the mode pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned long long rate;
+	unsigned int vic = *(unsigned int *)test->param_value;
+
+	mode = drm_display_mode_from_cea_vic(drm, vic);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate);
+}
+
+static const unsigned int drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = {
+	96, 97, 101, 102, 106, 107,
+};
+
+static void drm_connector_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc)
+{
+	sprintf(desc, "VIC %u", *vic);
+}
+
+KUNIT_ARRAY_PARAM(drm_connector_hdmi_compute_mode_clock_yuv420_valid,
+		  drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests,
+		  drm_connector_hdmi_compute_mode_clock_yuv420_vic_desc);
+
+/*
+ * Test that trying to compute the TMDS char rate with the YUV420 format
+ * for a mode that doesn't support the YUV420 encoding returns an error.
+ *
+ * TODO: We should probably test this with all the VIC but the
+ * explicitly supported ones. Since the list of VIC is quite long and
+ * not linear, the best way to support it at the moment would be to
+ * create a custom gen_params function that would only return valid
+ * VICs. At the moment, that function expects to get a pointer back
+ * however, and compilers don't really like casting between integer and
+ * pointers.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_invalid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, 42);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420);
+	KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a given mode listed supporting it and an YUV420 output
+ * with 10bpc, the TMDS character rate is equal to 0.625 times the mode
+ * pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned int vic =
+		drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, vic);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420);
+	KUNIT_ASSERT_GT(test, rate, 0);
+
+	KUNIT_EXPECT_EQ(test, mode->clock * 625, rate);
+}
+
+/*
+ * Test that for a given mode listed supporting it and an YUV420 output
+ * with 12bpc, the TMDS character rate is equal to 0.75 times the mode
+ * pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned int vic =
+		drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, vic);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420);
+	KUNIT_ASSERT_GT(test, rate, 0);
+
+	KUNIT_EXPECT_EQ(test, mode->clock * 750, rate);
+}
+
+/*
+ * Test that for a given mode, the computation of the TMDS character
+ * rate with 8bpc and a YUV422 output fails.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422);
+	KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a given mode, the computation of the TMDS character
+ * rate with 10bpc and a YUV422 output fails.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422);
+	KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a given mode, the computation of the TMDS character
+ * rate with 12bpc and a YUV422 output succeeds and returns a rate equal
+ * to the mode pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const struct drm_display_mode *mode;
+	struct drm_device *drm = &priv->drm;
+	unsigned long long rate;
+
+	mode = drm_display_mode_from_cea_vic(drm, 16);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_GT(test, rate, 0);
+	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
+}
+
+static struct kunit_case drm_connector_hdmi_compute_mode_clock_tests[] = {
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb),
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc),
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc_vic_1),
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc),
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc_vic_1),
+	KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_double),
+	KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid,
+			 drm_connector_hdmi_compute_mode_clock_yuv420_valid_gen_params),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_invalid),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc),
+	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc),
+	{ }
+};
+
+static struct kunit_suite drm_connector_hdmi_compute_mode_clock_test_suite = {
+	.name = "drm_test_connector_hdmi_compute_mode_clock",
+	.init = drm_test_connector_init,
+	.test_cases = drm_connector_hdmi_compute_mode_clock_tests,
+};
+
 kunit_test_suites(
 	&drmm_connector_hdmi_init_test_suite,
 	&drmm_connector_init_test_suite,
+	&drm_connector_hdmi_compute_mode_clock_test_suite,
 	&drm_get_tv_mode_from_name_test_suite,
 	&drm_hdmi_connector_get_output_format_name_test_suite
 );

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:06 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:06 +0100
Subject: [PATCH v7 20/36] drm/tests: Add HDMI connector bpc and format
 tests
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-20-8f4af575fce2@kernel.org>

The previous patch added the bpc and format an HDMI connector needs to
be set up with for a given connector state.

Let's add a few tests to make sure it works as expected.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 504 +++++++++++++++++++++
 drivers/gpu/drm/tests/drm_kunit_edid.h             | 160 +++++++
 2 files changed, 664 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index f010fde0eb69..c0f26422e925 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -370,6 +370,56 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 }
 
+/*
+ * Test that if we have an HDMI connector but a !HDMI display, we always
+ * output RGB with 8 bpc.
+ */
+static void drm_test_check_output_bpc_dvi(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_dvi_1080p,
+				 ARRAY_SIZE(test_edid_dvi_1080p));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_FALSE(test, info->is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
 /*
  * Test that when doing a commit which would use RGB 8bpc, the TMDS
  * clock rate stored in the connector state is equal to the mode clock
@@ -562,10 +612,464 @@ static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
 	KUNIT_EXPECT_LT(test, ret, 0);
 }
 
+/*
+ * Test that if:
+ * - We have an HDMI connector supporting RGB only
+ * - The chosen mode has a TMDS character rate higher than the display
+ *   supports in RGB/12bpc
+ * - The chosen mode has a TMDS character rate lower than the display
+ *   supports in RGB/10bpc.
+ *
+ * Then we will pick the latter, and the computed TMDS character rate
+ * will be equal to 1.25 times the mode pixel clock.
+ */
+static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
+}
+
+/*
+ * Test that if:
+ * - We have an HDMI connector supporting both RGB and YUV422 and up to
+ *   12 bpc
+ * - The chosen mode has a TMDS character rate higher than the display
+ *   supports in RGB/12bpc
+ * - The chosen mode has a TMDS character rate lower than the display
+ *   supports in YUV422/12bpc.
+ *
+ * Then we will pick the latter, and the computed TMDS character rate
+ * will be equal to the mode pixel clock.
+ */
+static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 12);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV422);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000);
+}
+
+/*
+ * Test that if a driver and screen supports RGB and YUV formats, and we
+ * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could
+ * have had a higher bpc.
+ */
+static void drm_test_check_output_bpc_format_vic_1(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *mode;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	/*
+	 * NOTE: We can't use drm_connector_hdmi_compute_mode_clock()
+	 * here because we're trying to get the rate of an invalid
+	 * configuration.
+	 *
+	 * Thus, we have to calculate the rate by hand.
+	 */
+	rate = mode->clock * 1500;
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a driver supports only RGB but the screen also supports
+ * YUV formats, we only end up with an RGB format.
+ */
+static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	/*
+	 * We're making sure that YUV422 would be the preferred option
+	 * here: we're always favouring higher bpc, we can't have RGB
+	 * because the TMDS character rate exceeds the maximum supported
+	 * by the display, and YUV422 works for that display.
+	 *
+	 * But since the driver only supports RGB, we should fallback to
+	 * a lower bpc with RGB.
+	 */
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a screen supports only RGB but the driver also supports
+ * YUV formats, we only end up with an RGB format.
+ */
+static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	/*
+	 * We're making sure that YUV422 would be the preferred option
+	 * here: we're always favouring higher bpc, we can't have RGB
+	 * because the TMDS character rate exceeds the maximum supported
+	 * by the display, and YUV422 works for that display.
+	 *
+	 * But since the display only supports RGB, we should fallback to
+	 * a lower bpc with RGB.
+	 */
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a display supports higher bpc but the driver only
+ * supports 8 bpc, we only end up with 8 bpc even if we could have had a
+ * higher bpc.
+ */
+static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	/*
+	 * We're making sure that we have headroom on the TMDS character
+	 * clock to actually use 12bpc.
+	 */
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a driver supports higher bpc but the display only
+ * supports 8 bpc, we only end up with 8 bpc even if we could have had a
+ * higher bpc.
+ */
+static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_max_340mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	/*
+	 * We're making sure that we have headroom on the TMDS character
+	 * clock to actually use 12bpc.
+	 */
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	conn_state = conn->state;
+	KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
+	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback),
+	KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
+	KUNIT_CASE(drm_test_check_output_bpc_dvi),
+	KUNIT_CASE(drm_test_check_output_bpc_format_vic_1),
+	KUNIT_CASE(drm_test_check_output_bpc_format_display_8bpc_only),
+	KUNIT_CASE(drm_test_check_output_bpc_format_display_rgb_only),
+	KUNIT_CASE(drm_test_check_output_bpc_format_driver_8bpc_only),
+	KUNIT_CASE(drm_test_check_output_bpc_format_driver_rgb_only),
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h
index 24f3377ef0f0..3e3527c58c31 100644
--- a/drivers/gpu/drm/tests/drm_kunit_edid.h
+++ b/drivers/gpu/drm/tests/drm_kunit_edid.h
@@ -1,6 +1,64 @@
 #ifndef DRM_KUNIT_EDID_H_
 #define DRM_KUNIT_EDID_H_
 
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 0a 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ab
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ *   EDID Structure Version & Revision: 1.3
+ *   Vendor & Product Identification:
+ *     Manufacturer: LNX
+ *     Model: 42
+ *     Made in: 2023
+ *   Basic Display Parameters & Features:
+ *     Digital display
+ *     DFP 1.x compatible TMDS
+ *     Maximum image size: 160 cm x 90 cm
+ *     Gamma: 2.20
+ *     RGB color display
+ *     First detailed timing is the preferred timing
+ *   Color Characteristics:
+ *     Red  : 0.0000, 0.0000
+ *     Green: 0.0000, 0.0000
+ *     Blue : 0.0000, 0.0000
+ *     White: 0.0000, 0.0000
+ *   Established Timings I & II: none
+ *   Standard Timings: none
+ *   Detailed Timing Descriptors:
+ *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (1600 mm x 900 mm)
+ *                  Hfront   88 Hsync  44 Hback  148 Hpol P
+ *                  Vfront    4 Vsync   5 Vback   36 Vpol P
+ *     Display Product Name: 'Test EDID'
+ *     Display Range Limits:
+ *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ *     Dummy Descriptor:
+ * Checksum: 0xab
+ */
+const unsigned char test_edid_dvi_1080p[] = {
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+  0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+  0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+  0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+  0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab
+};
+
 /*
  * edid-decode (hex):
  *
@@ -103,6 +161,108 @@ const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {
   0x00, 0x00, 0x00, 0xd0
 };
 
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92
+ *
+ * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c
+ * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ *   EDID Structure Version & Revision: 1.3
+ *   Vendor & Product Identification:
+ *     Manufacturer: LNX
+ *     Model: 42
+ *     Made in: 2023
+ *   Basic Display Parameters & Features:
+ *     Digital display
+ *     DFP 1.x compatible TMDS
+ *     Maximum image size: 160 cm x 90 cm
+ *     Gamma: 2.20
+ *     Monochrome or grayscale display
+ *     First detailed timing is the preferred timing
+ *   Color Characteristics:
+ *     Red  : 0.0000, 0.0000
+ *     Green: 0.0000, 0.0000
+ *     Blue : 0.0000, 0.0000
+ *     White: 0.0000, 0.0000
+ *   Established Timings I & II:
+ *     DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
+ *   Standard Timings: none
+ *   Detailed Timing Descriptors:
+ *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (1600 mm x 900 mm)
+ *                  Hfront   88 Hsync  44 Hback  148 Hpol P
+ *                  Vfront    4 Vsync   5 Vback   36 Vpol P
+ *     Display Product Name: 'Test EDID'
+ *     Display Range Limits:
+ *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ *     Dummy Descriptor:
+ *   Extension blocks: 1
+ * Checksum: 0x92
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ *   Revision: 3
+ *   Underscans IT Video Formats by default
+ *   Native detailed modes: 1
+ *   Colorimetry Data Block:
+ *     sRGB
+ *   Video Data Block:
+ *     VIC  16:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz
+ *   Video Capability Data Block:
+ *     YCbCr quantization: No Data
+ *     RGB quantization: Selectable (via AVI Q)
+ *     PT scan behavior: No Data
+ *     IT scan behavior: Always Underscanned
+ *     CE scan behavior: Always Underscanned
+ *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ *     Source physical address: 1.2.3.4
+ *     Maximum TMDS clock: 340 MHz
+ *     Extended HDMI video details:
+ * Checksum: 0xd0  Unused space in Extension Block: 100 bytes
+ */
+const unsigned char test_edid_hdmi_1080p_rgb_max_340mhz[] = {
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+  0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+  0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+  0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81,
+  0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c,
+  0x00, 0x12, 0x34, 0x00, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xd0
+};
+
 /*
  * edid-decode (hex):
  *

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:13:49 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:49 +0100
Subject: [PATCH v7 03/36] drm/tests: Add helper to create mock plane
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-3-8f4af575fce2@kernel.org>

We're going to need a full-blown, functional, KMS device to test more
components of the atomic modesetting infrastructure.

Let's add a new helper to create a dumb, mocked, primary plane. By
default, it will create a linear XRGB8888 plane, using the default
helpers.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_kunit_helpers.c | 85 +++++++++++++++++++++++++++++++
 include/drm/drm_kunit_helpers.h           | 11 ++++
 2 files changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index 4fb11b938bc1..32dc8354641a 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -3,6 +3,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_drv.h>
+#include <drm/drm_fourcc.h>
 #include <drm/drm_kunit_helpers.h>
 #include <drm/drm_managed.h>
 
@@ -164,5 +165,89 @@ drm_kunit_helper_atomic_state_alloc(struct kunit *test,
 }
 EXPORT_SYMBOL_GPL(drm_kunit_helper_atomic_state_alloc);
 
+static const uint32_t default_plane_formats[] = {
+	DRM_FORMAT_XRGB8888,
+};
+
+static const uint64_t default_plane_modifiers[] = {
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID
+};
+
+static const struct drm_plane_helper_funcs default_plane_helper_funcs = {
+};
+
+static const struct drm_plane_funcs default_plane_funcs = {
+	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
+	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
+	.reset			= drm_atomic_helper_plane_reset,
+};
+
+/**
+ * drm_kunit_helper_create_primary_plane - Creates a mock primary plane for a KUnit test
+ * @test: The test context object
+ * @drm: The device to alloc the plane for
+ * @funcs: Callbacks for the new plane. Optional.
+ * @helper_funcs: Helpers callbacks for the new plane. Optional.
+ * @formats: array of supported formats (DRM_FORMAT\_\*). Optional.
+ * @num_formats: number of elements in @formats
+ * @modifiers: array of struct drm_format modifiers terminated by
+ *             DRM_FORMAT_MOD_INVALID. Optional.
+ *
+ * This allocates and initializes a mock struct &drm_plane meant to be
+ * part of a mock device for a KUnit test.
+ *
+ * Resources will be cleaned up automatically.
+ *
+ * @funcs will default to the default helpers implementations.
+ * @helper_funcs will default to an empty implementation. @formats will
+ * default to XRGB8888 only. @modifiers will default to a linear
+ * modifier only.
+ *
+ * Returns:
+ * A pointer to the new plane, or an ERR_PTR() otherwise.
+ */
+struct drm_plane *
+drm_kunit_helper_create_primary_plane(struct kunit *test,
+				      struct drm_device *drm,
+				      const struct drm_plane_funcs *funcs,
+				      const struct drm_plane_helper_funcs *helper_funcs,
+				      const uint32_t *formats,
+				      unsigned int num_formats,
+				      const uint64_t *modifiers)
+{
+	struct drm_plane *plane;
+
+	if (!funcs)
+		funcs = &default_plane_funcs;
+
+	if (!helper_funcs)
+		helper_funcs = &default_plane_helper_funcs;
+
+	if (!formats || !num_formats) {
+		formats = default_plane_formats;
+		num_formats = ARRAY_SIZE(default_plane_formats);
+	}
+
+	if (!modifiers)
+		modifiers = default_plane_modifiers;
+
+	plane = __drmm_universal_plane_alloc(drm,
+					     sizeof(struct drm_plane), 0,
+					     0,
+					     funcs,
+					     formats,
+					     num_formats,
+					     default_plane_modifiers,
+					     DRM_PLANE_TYPE_PRIMARY,
+					     NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
+
+	drm_plane_helper_add(plane, helper_funcs);
+
+	return plane;
+}
+EXPORT_SYMBOL_GPL(drm_kunit_helper_create_primary_plane);
+
 MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");
 MODULE_LICENSE("GPL");
diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
index 3ae19892229d..38667d624aa8 100644
--- a/include/drm/drm_kunit_helpers.h
+++ b/include/drm/drm_kunit_helpers.h
@@ -10,6 +10,8 @@
 #include <kunit/test.h>
 
 struct drm_device;
+struct drm_plane_funcs;
+struct drm_plane_helper_funcs;
 struct kunit;
 
 struct device *drm_kunit_helper_alloc_device(struct kunit *test);
@@ -99,4 +101,13 @@ drm_kunit_helper_atomic_state_alloc(struct kunit *test,
 				    struct drm_device *drm,
 				    struct drm_modeset_acquire_ctx *ctx);
 
+struct drm_plane *
+drm_kunit_helper_create_primary_plane(struct kunit *test,
+				      struct drm_device *drm,
+				      const struct drm_plane_funcs *funcs,
+				      const struct drm_plane_helper_funcs *helper_funcs,
+				      const uint32_t *formats,
+				      unsigned int num_formats,
+				      const uint64_t *modifiers);
+
 #endif // DRM_KUNIT_HELPERS_H_

-- 
2.43.2



From fancer.lancer at gmail.com  Thu Feb 22 10:12:58 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:58 +0300
Subject: [PATCH v5 13/20] EDAC/mc: Init DIMM labels in MC registration method
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-14-fancer.lancer@gmail.com>

Move the DIMM labels initialization to the memory controller registration
method as a preparation before adding the generic procedure to allocate an
unique MC index. It's required because the DIMM labels contain the MC
index as the "mc%u" part of the string, which in case of the
auto-generated index isn't available at the moment of the MCI/csrow/dimms
descriptor allocation.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
---
 drivers/edac/edac_mc.c | 48 +++++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index d6eed727b0cd..c0b36349999f 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -257,7 +257,6 @@ static int edac_mc_alloc_dimms(struct mem_ctl_info *mci)
 	unsigned int pos[EDAC_MAX_LAYERS];
 	unsigned int row, chn, idx;
 	int layer;
-	void *p;
 
 	/*
 	 * Allocate and fill the dimm structs
@@ -272,7 +271,6 @@ static int edac_mc_alloc_dimms(struct mem_ctl_info *mci)
 	for (idx = 0; idx < mci->tot_dimms; idx++) {
 		struct dimm_info *dimm;
 		struct rank_info *chan;
-		int n, len;
 
 		chan = mci->csrows[row]->channels[chn];
 
@@ -283,22 +281,9 @@ static int edac_mc_alloc_dimms(struct mem_ctl_info *mci)
 		dimm->mci = mci;
 		dimm->idx = idx;
 
-		/*
-		 * Copy DIMM location and initialize it.
-		 */
-		len = sizeof(dimm->label);
-		p = dimm->label;
-		n = scnprintf(p, len, "mc#%u", mci->mc_idx);
-		p += n;
-		len -= n;
-		for (layer = 0; layer < mci->n_layers; layer++) {
-			n = scnprintf(p, len, "%s#%u",
-				      edac_layer_name[mci->layers[layer].type],
-				      pos[layer]);
-			p += n;
-			len -= n;
+		/* Copy DIMM location */
+		for (layer = 0; layer < mci->n_layers; layer++)
 			dimm->location[layer] = pos[layer];
-		}
 
 		/* Link it to the csrows old API data */
 		chan->dimm = dimm;
@@ -511,6 +496,33 @@ void edac_mc_reset_delay_period(unsigned long value)
 
 
 
+/**
+ * edac_mc_init_labels() - Initialize DIMM labels
+ *
+ * @mci: pointer to the mci structure which DIMM labels need to be initialized
+ *
+ * .. note::
+ *	locking model: must be called with the mem_ctls_mutex lock held
+ */
+static void edac_mc_init_labels(struct mem_ctl_info *mci)
+{
+	int n, len, layer;
+	unsigned int idx;
+	char *p;
+
+	for (idx = 0; idx < mci->tot_dimms; idx++) {
+		len = sizeof(mci->dimms[idx]->label);
+		p = mci->dimms[idx]->label;
+
+		n = scnprintf(p, len, "mc#%u", mci->mc_idx);
+		for (layer = 0; layer < mci->n_layers; layer++) {
+			n += scnprintf(p + n, len - n, "%s#%u",
+				      edac_layer_name[mci->layers[layer].type],
+				      mci->dimms[idx]->location[layer]);
+		}
+	}
+}
+
 /* Return 0 on success, 1 on failure.
  * Before calling this function, caller must
  * assign a unique value to mci->mc_idx.
@@ -638,6 +650,8 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
 		goto fail0;
 	}
 
+	edac_mc_init_labels(mci);
+
 	if (add_mc_to_global_list(mci))
 		goto fail0;
 
-- 
2.43.0



From mripard at kernel.org  Thu Feb 22 10:13:52 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:52 +0100
Subject: [PATCH v7 06/36] drm/connector: Introduce an HDMI connector
 initialization function
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-6-8f4af575fce2@kernel.org>

A lot of the various HDMI drivers duplicate some logic that depends on
the HDMI spec itself and not really a particular hardware
implementation.

Output BPC or format selection, infoframe generation are good examples
of such areas.

This creates a lot of boilerplate, with a lot of variations, which makes
it hard for userspace to rely on, and makes it difficult to get it right
for drivers.

In the next patches, we'll add a lot of infrastructure around the
drm_connector and drm_connector_state structures, which will allow to
abstract away the duplicated logic. This infrastructure comes with a few
requirements though, and thus we need a new initialization function.

Hopefully, this will make drivers simpler to handle, and their behaviour
more consistent.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_connector.c | 39 +++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     |  5 +++++
 2 files changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b0516505f7ae..d9961cce8245 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -452,6 +452,45 @@ int drmm_connector_init(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drmm_connector_init);
 
+/**
+ * drmm_connector_hdmi_init - Init a preallocated HDMI connector
+ * @dev: DRM device
+ * @connector: A pointer to the HDMI connector to init
+ * @funcs: callbacks for this connector
+ * @connector_type: user visible type of the connector
+ * @ddc: optional pointer to the associated ddc adapter
+ *
+ * Initialises a preallocated HDMI connector. Connectors can be
+ * subclassed as part of driver connector objects.
+ *
+ * Cleanup is automatically handled with a call to
+ * drm_connector_cleanup() in a DRM-managed action.
+ *
+ * The connector structure should be allocated with drmm_kzalloc().
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_connector_hdmi_init(struct drm_device *dev,
+			     struct drm_connector *connector,
+			     const struct drm_connector_funcs *funcs,
+			     int connector_type,
+			     struct i2c_adapter *ddc)
+{
+	int ret;
+
+	if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+	      connector_type == DRM_MODE_CONNECTOR_HDMIB))
+		return -EINVAL;
+
+	ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(drmm_connector_hdmi_init);
+
 /**
  * drm_connector_attach_edid_property - attach edid property.
  * @connector: the connector
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index fe88d7fc6b8f..4491c4c2fb6e 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1904,6 +1904,11 @@ int drmm_connector_init(struct drm_device *dev,
 			const struct drm_connector_funcs *funcs,
 			int connector_type,
 			struct i2c_adapter *ddc);
+int drmm_connector_hdmi_init(struct drm_device *dev,
+			     struct drm_connector *connector,
+			     const struct drm_connector_funcs *funcs,
+			     int connector_type,
+			     struct i2c_adapter *ddc);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);
 void drm_connector_unregister(struct drm_connector *connector);

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:13:55 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:55 +0100
Subject: [PATCH v7 09/36] drm/connector: hdmi: Add output BPC to the
 connector state
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-9-8f4af575fce2@kernel.org>

We'll add automatic selection of the output BPC in a following patch,
but let's add it to the HDMI connector state already.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic.c               |  5 +++++
 drivers/gpu/drm/drm_atomic_state_helper.c  | 20 ++++++++++++++++++++
 drivers/gpu/drm/drm_connector.c            | 20 +++++++++++++++++++-
 drivers/gpu/drm/tests/drm_connector_test.c | 12 ++++++++----
 include/drm/drm_connector.h                | 12 +++++++++++-
 5 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index a91737adf8e7..4e11cfb4518b 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1143,6 +1143,11 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 	drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc);
 	drm_printf(p, "\tcolorspace=%s\n", drm_get_colorspace_name(state->colorspace));
 
+	if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
+		drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
+	}
+
 	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
 		if (state->writeback_job && state->writeback_job->fb)
 			drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id);
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 7ad1dffe66d9..460454904fe3 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -584,6 +584,10 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
 void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
 					      struct drm_connector_state *new_state)
 {
+	unsigned int max_bpc = connector->max_bpc;
+
+	new_state->max_bpc = max_bpc;
+	new_state->max_requested_bpc = max_bpc;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
 
@@ -651,6 +655,22 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
 int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 					   struct drm_atomic_state *state)
 {
+	struct drm_connector_state *old_state =
+		drm_atomic_get_old_connector_state(state, connector);
+	struct drm_connector_state *new_state =
+		drm_atomic_get_new_connector_state(state, connector);
+
+	if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc) {
+		struct drm_crtc *crtc = new_state->crtc;
+		struct drm_crtc_state *crtc_state;
+
+		crtc_state = drm_atomic_get_crtc_state(state, crtc);
+		if (IS_ERR(crtc_state))
+			return PTR_ERR(crtc_state);
+
+		crtc_state->mode_changed = true;
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index d9961cce8245..da51a2bcb978 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -459,6 +459,7 @@ EXPORT_SYMBOL(drmm_connector_init);
  * @funcs: callbacks for this connector
  * @connector_type: user visible type of the connector
  * @ddc: optional pointer to the associated ddc adapter
+ * @max_bpc: Maximum bits per char the HDMI connector supports
  *
  * Initialises a preallocated HDMI connector. Connectors can be
  * subclassed as part of driver connector objects.
@@ -475,7 +476,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
 			     const struct drm_connector_funcs *funcs,
 			     int connector_type,
-			     struct i2c_adapter *ddc)
+			     struct i2c_adapter *ddc,
+			     unsigned int max_bpc)
 {
 	int ret;
 
@@ -483,10 +485,26 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 	      connector_type == DRM_MODE_CONNECTOR_HDMIB))
 		return -EINVAL;
 
+	if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12))
+		return -EINVAL;
+
 	ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);
 	if (ret)
 		return ret;
 
+	/*
+	 * drm_connector_attach_max_bpc_property() requires the
+	 * connector to have a state.
+	 */
+	if (connector->funcs->reset)
+		connector->funcs->reset(connector);
+
+	drm_connector_attach_max_bpc_property(connector, 8, max_bpc);
+	connector->max_bpc = max_bpc;
+
+	if (max_bpc > 8)
+		drm_connector_attach_hdr_output_metadata_property(connector);
+
 	return 0;
 }
 EXPORT_SYMBOL(drmm_connector_hdmi_init);
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 8f070cacab3b..d8d30aea9fdc 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -184,7 +184,8 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test)
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
-				       &priv->ddc);
+				       &priv->ddc,
+				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
@@ -200,7 +201,8 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
-				       NULL);
+				       NULL,
+				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
@@ -217,7 +219,8 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
 				       connector_type,
-				       &priv->ddc);
+				       &priv->ddc,
+				       8);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
@@ -248,7 +251,8 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
 				       &dummy_funcs,
 				       connector_type,
-				       &priv->ddc);
+				       &priv->ddc,
+				       8);
 	KUNIT_EXPECT_LT(test, ret, 0);
 }
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 000a2a156619..d4d2ae15bc1e 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1037,6 +1037,10 @@ struct drm_connector_state {
 	 * @drm_atomic_helper_connector_hdmi_check().
 	 */
 	struct {
+		/**
+		 * @output_bpc: Bits per color channel to output.
+		 */
+		unsigned int output_bpc;
 	} hdmi;
 };
 
@@ -1682,6 +1686,11 @@ struct drm_connector {
 	 */
 	struct drm_property_blob *path_blob_ptr;
 
+	/**
+	 * @max_bpc: Maximum bits per color channel the connector supports.
+	 */
+	unsigned int max_bpc;
+
 	/**
 	 * @max_bpc_property: Default connector property for the max bpc to be
 	 * driven out of the connector.
@@ -1915,7 +1924,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
 			     const struct drm_connector_funcs *funcs,
 			     int connector_type,
-			     struct i2c_adapter *ddc);
+			     struct i2c_adapter *ddc,
+			     unsigned int max_bpc);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);
 void drm_connector_unregister(struct drm_connector *connector);

-- 
2.43.2



From fancer.lancer at gmail.com  Thu Feb 22 10:12:52 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:52 +0300
Subject: [PATCH v5 07/20] EDAC/synopsys: Use platform device devm ioremap method
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-8-fancer.lancer@gmail.com>

DW DDRs CSRs resource descriptor is used by the devm_ioremap_resource()
function invocation only in the driver probe method. Thus convert the
platform_get_resource() and devm_ioremap_resource() couple to just a
single devm_platform_ioremap_resource() method call.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
---
 drivers/edac/synopsys_edac.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 9f79f14e57b2..6976ef84e952 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -1334,11 +1334,9 @@ static int mc_probe(struct platform_device *pdev)
 	struct synps_edac_priv *priv;
 	struct mem_ctl_info *mci;
 	void __iomem *baseaddr;
-	struct resource *res;
 	int rc;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	baseaddr = devm_ioremap_resource(&pdev->dev, res);
+	baseaddr = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(baseaddr))
 		return PTR_ERR(baseaddr);
 
-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:12:56 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:56 +0300
Subject: [PATCH v5 11/20] EDAC/synopsys: Shorten out struct ecc_error_info.bankgrpnr field name
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-12-fancer.lancer@gmail.com>

None of the ecc_error_info structure fields have "nr" suffix even though
each of them do represent some number (row number, column number, bank
number). Drop the suffix from the bankgrpnr field name for the sake of
unification then. Similarly drop the word "Number" from the CE/UE error
messages too since it doesn't give any helpful info there.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
---
 drivers/edac/synopsys_edac.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 6ca119459bd3..b0ff831287f5 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -268,17 +268,17 @@
  * @row:	Row number.
  * @col:	Column number.
  * @bank:	Bank number.
+ * @bankgrp:	Bank group number.
  * @bitpos:	Bit position.
  * @data:	Data causing the error.
- * @bankgrpnr:	Bank group number.
  */
 struct ecc_error_info {
 	u32 row;
 	u32 col;
 	u32 bank;
+	u32 bankgrp;
 	u32 bitpos;
 	u32 data;
-	u32 bankgrpnr;
 };
 
 /**
@@ -429,7 +429,7 @@ static int zynqmp_get_error_info(struct synps_edac_priv *priv)
 	regval = readl(base + ECC_CEADDR1_OFST);
 	p->ceinfo.bank = (regval & ECC_CEADDR1_BNKNR_MASK) >>
 					ECC_CEADDR1_BNKNR_SHIFT;
-	p->ceinfo.bankgrpnr = (regval &	ECC_CEADDR1_BNKGRP_MASK) >>
+	p->ceinfo.bankgrp = (regval & ECC_CEADDR1_BNKGRP_MASK) >>
 					ECC_CEADDR1_BNKGRP_SHIFT;
 	p->ceinfo.col = (regval & ECC_CEADDR1_COL_MASK);
 	p->ceinfo.data = readl(base + ECC_CSYND0_OFST);
@@ -443,7 +443,7 @@ static int zynqmp_get_error_info(struct synps_edac_priv *priv)
 	regval = readl(base + ECC_UEADDR0_OFST);
 	p->ueinfo.row = (regval & ECC_CEADDR0_RW_MASK);
 	regval = readl(base + ECC_UEADDR1_OFST);
-	p->ueinfo.bankgrpnr = (regval & ECC_CEADDR1_BNKGRP_MASK) >>
+	p->ueinfo.bankgrp = (regval & ECC_CEADDR1_BNKGRP_MASK) >>
 					ECC_CEADDR1_BNKGRP_SHIFT;
 	p->ueinfo.bank = (regval & ECC_CEADDR1_BNKNR_MASK) >>
 					ECC_CEADDR1_BNKNR_SHIFT;
@@ -478,9 +478,9 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 		pinf = &p->ceinfo;
 		if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "DDR ECC error type:%s Row %d Col %d Bank %d BankGroup Number %d Bit Position: %d Data: 0x%08x",
+				 "DDR ECC error type:%s Row %d Col %d Bank %d Bank Group %d Bit Position: %d Data: 0x%08x",
 				 "CE", pinf->row, pinf->col, pinf->bank,
-				 pinf->bankgrpnr, pinf->bitpos, pinf->data);
+				 pinf->bankgrp, pinf->bitpos, pinf->data);
 		} else {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
 				 "DDR ECC error type:%s Row %d Bank %d Col %d Bit Position: %d Data: 0x%08x",
@@ -497,9 +497,9 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 		pinf = &p->ueinfo;
 		if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "DDR ECC error type :%s Row %d Col %d Bank %d BankGroup Number %d",
+				 "DDR ECC error type :%s Row %d Col %d Bank %d Bank Group %d",
 				 "UE", pinf->row, pinf->col, pinf->bank,
-				 pinf->bankgrpnr);
+				 pinf->bankgrp);
 		} else {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
 				 "DDR ECC error type :%s Row %d Bank %d Col %d ",
-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:12:55 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:55 +0300
Subject: [PATCH v5 10/20] EDAC/synopsys: Drop struct ecc_error_info.blknr field
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-11-fancer.lancer@gmail.com>

Even though the ECC(C|U)ADDR1 CSR description indeed says it's a "Block
number" in the DW uMCTL2 DDRC IP-core databooks, the corresponding
register field is named as ECC(C|U)ADDR1.ecc_(un)corr_col (which means ECC
(un)corrected column) and in the rest of the document it's referred as the
SDRAM address column. Thus use the already available ecc_error_info.col
field to read the column number to and drop the questionable
ecc_error_info.blknr field for good.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
---
 drivers/edac/synopsys_edac.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 21b0d791cb8b..6ca119459bd3 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -173,7 +173,7 @@
 #define ECC_CEADDR0_RNK_MASK		BIT(24)
 #define ECC_CEADDR1_BNKGRP_MASK		0x3000000
 #define ECC_CEADDR1_BNKNR_MASK		0x70000
-#define ECC_CEADDR1_BLKNR_MASK		0xFFF
+#define ECC_CEADDR1_COL_MASK		0xFFF
 #define ECC_CEADDR1_BNKGRP_SHIFT	24
 #define ECC_CEADDR1_BNKNR_SHIFT		16
 
@@ -271,7 +271,6 @@
  * @bitpos:	Bit position.
  * @data:	Data causing the error.
  * @bankgrpnr:	Bank group number.
- * @blknr:	Block number.
  */
 struct ecc_error_info {
 	u32 row;
@@ -280,7 +279,6 @@ struct ecc_error_info {
 	u32 bitpos;
 	u32 data;
 	u32 bankgrpnr;
-	u32 blknr;
 };
 
 /**
@@ -433,7 +431,7 @@ static int zynqmp_get_error_info(struct synps_edac_priv *priv)
 					ECC_CEADDR1_BNKNR_SHIFT;
 	p->ceinfo.bankgrpnr = (regval &	ECC_CEADDR1_BNKGRP_MASK) >>
 					ECC_CEADDR1_BNKGRP_SHIFT;
-	p->ceinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
+	p->ceinfo.col = (regval & ECC_CEADDR1_COL_MASK);
 	p->ceinfo.data = readl(base + ECC_CSYND0_OFST);
 	edac_dbg(2, "ECCCSYN0: 0x%08X ECCCSYN1: 0x%08X ECCCSYN2: 0x%08X\n",
 		 readl(base + ECC_CSYND0_OFST), readl(base + ECC_CSYND1_OFST),
@@ -449,7 +447,7 @@ static int zynqmp_get_error_info(struct synps_edac_priv *priv)
 					ECC_CEADDR1_BNKGRP_SHIFT;
 	p->ueinfo.bank = (regval & ECC_CEADDR1_BNKNR_MASK) >>
 					ECC_CEADDR1_BNKNR_SHIFT;
-	p->ueinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
+	p->ueinfo.col = (regval & ECC_CEADDR1_COL_MASK);
 	p->ueinfo.data = readl(base + ECC_UESYND0_OFST);
 out:
 	spin_lock_irqsave(&priv->reglock, flags);
@@ -480,10 +478,9 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 		pinf = &p->ceinfo;
 		if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "DDR ECC error type:%s Row %d Bank %d BankGroup Number %d Block Number %d Bit Position: %d Data: 0x%08x",
-				 "CE", pinf->row, pinf->bank,
-				 pinf->bankgrpnr, pinf->blknr,
-				 pinf->bitpos, pinf->data);
+				 "DDR ECC error type:%s Row %d Col %d Bank %d BankGroup Number %d Bit Position: %d Data: 0x%08x",
+				 "CE", pinf->row, pinf->col, pinf->bank,
+				 pinf->bankgrpnr, pinf->bitpos, pinf->data);
 		} else {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
 				 "DDR ECC error type:%s Row %d Bank %d Col %d Bit Position: %d Data: 0x%08x",
@@ -500,9 +497,9 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 		pinf = &p->ueinfo;
 		if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "DDR ECC error type :%s Row %d Bank %d BankGroup Number %d Block Number %d",
-				 "UE", pinf->row, pinf->bank,
-				 pinf->bankgrpnr, pinf->blknr);
+				 "DDR ECC error type :%s Row %d Col %d Bank %d BankGroup Number %d",
+				 "UE", pinf->row, pinf->col, pinf->bank,
+				 pinf->bankgrpnr);
 		} else {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
 				 "DDR ECC error type :%s Row %d Bank %d Col %d ",
-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:12:54 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:54 +0300
Subject: [PATCH v5 09/20] EDAC/synopsys: Drop local to_mci() macro definition
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-10-fancer.lancer@gmail.com>

The to_mci() macro was added in commit 1a81361f75d8 ("EDAC, synopsys: Add
Error Injection support for ZynqMP DDR controller") together with the
errors injection debug feature. It turns out the absolutely the same
macro-function has already been defined in the edac_mc.h (former
edac_core.h) header file. No idea why it was needed to have a local
version of the macro, but there is no point in it now. Drop the local
macro-function definition for good.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
---
 drivers/edac/synopsys_edac.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 5099246db90e..21b0d791cb8b 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -940,7 +940,6 @@ static const struct of_device_id synps_edac_match[] = {
 MODULE_DEVICE_TABLE(of, synps_edac_match);
 
 #ifdef CONFIG_EDAC_DEBUG
-#define to_mci(k) container_of(k, struct mem_ctl_info, dev)
 
 /**
  * ddr_poison_setup -	Update poison registers.
-- 
2.43.0



From mripard at kernel.org  Thu Feb 22 10:14:10 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:10 +0100
Subject: [PATCH v7 24/36] drm/tests: Add RGB Quantization tests
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-24-8f4af575fce2@kernel.org>

The previous commit added the infrastructure to the connector state to
track what RGB Quantization should be used in a given state for an HDMI
connector.

Let's add some kunit tests to make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 563 +++++++++++++++++++++
 1 file changed, 563 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 3de15cec2f5f..dcc0f7486f49 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -352,6 +352,560 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes
 	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
 }
 
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to auto with a mode that isn't the
+ * VIC-1 mode, we will get a limited RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_AUTO);
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to auto with a VIC-1 mode, we will get
+ * a full RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *mode;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_AUTO);
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to full with a mode that isn't the
+ * VIC-1 mode, we will get a full RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_FULL);
+
+	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to full with a VIC-1 mode, we will get
+ * a full RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *mode;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_FULL);
+
+	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to limited with a mode that isn't the
+ * VIC-1 mode, we will get a limited RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_LIMITED);
+
+	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to limited with a VIC-1 mode, we will
+ * get a limited RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *mode;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	mode = drm_display_mode_from_cea_vic(drm, 1);
+	KUNIT_ASSERT_NOT_NULL(test, mode);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			conn_state->hdmi.broadcast_rgb,
+			DRM_HDMI_BROADCAST_RGB_LIMITED);
+
+	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that if we have an HDMI connector that would use a YUV output,
+ * we always get a limited quantization range with the Broadcast RGB
+ * property set to auto.
+ */
+static void drm_test_check_broadcast_rgb_auto_yuv(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV422);
+	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that if we have an HDMI connector that would use a YUV output,
+ * we always get a limited quantization range even if we have the
+ * Broadcast RGB property set to full.
+ */
+static void drm_test_check_broadcast_rgb_full_yuv(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV422);
+	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
+}
+
+/*
+ * Test that if we have an HDMI connector that would use a YUV output,
+ * we always get a limited quantization range even if we have the
+ * Broadcast RGB property set to full.
+ */
+static void drm_test_check_broadcast_rgb_limited_yuv(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *conn_state;
+	struct drm_atomic_state *state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	unsigned long long rate;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422),
+						     12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	info = &conn->display_info;
+	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+	rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV422);
+	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range);
+}
+
 /*
  * Test that if we change the maximum bpc property to a different value,
  * we trigger a mode change on the connector's CRTC, which will in turn
@@ -1187,6 +1741,15 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes
 }
 
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
+	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_yuv),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_full_yuv),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_yuv),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
 	KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:15 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:15 +0100
Subject: [PATCH v7 29/36] drm/vc4: tests: Remove vc4_dummy_plane structure
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-29-8f4af575fce2@kernel.org>

The vc4_dummy_plane structure is an exact equivalent to vc4_plane, so we
don't need it.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/vc4/tests/vc4_mock.c       |  6 ++----
 drivers/gpu/drm/vc4/tests/vc4_mock.h       |  9 ++-------
 drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 14 +++++---------
 3 files changed, 9 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.c b/drivers/gpu/drm/vc4/tests/vc4_mock.c
index becb3dbaa548..0731a7d85d7a 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock.c
@@ -109,16 +109,14 @@ static const struct vc4_mock_desc vc5_mock =
 static int __build_one_pipe(struct kunit *test, struct drm_device *drm,
 			    const struct vc4_mock_pipe_desc *pipe)
 {
-	struct vc4_dummy_plane *dummy_plane;
 	struct drm_plane *plane;
 	struct vc4_dummy_crtc *dummy_crtc;
 	struct drm_crtc *crtc;
 	unsigned int i;
 
-	dummy_plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
+	plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
 
-	plane = &dummy_plane->plane.base;
 	dummy_crtc = vc4_mock_pv(test, drm, plane, pipe->data);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc);
 
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.h b/drivers/gpu/drm/vc4/tests/vc4_mock.h
index 2d0b339bd9f3..002b6218960c 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock.h
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock.h
@@ -21,13 +21,8 @@ struct drm_crtc *vc4_find_crtc_for_encoder(struct kunit *test,
 	return NULL;
 }
 
-struct vc4_dummy_plane {
-	struct vc4_plane plane;
-};
-
-struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
-					struct drm_device *drm,
-					enum drm_plane_type type);
+struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
+				  enum drm_plane_type type);
 
 struct vc4_dummy_crtc {
 	struct vc4_crtc crtc;
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
index 62b18f5f41db..973f5f929097 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
@@ -22,15 +22,12 @@ static const uint32_t vc4_dummy_plane_formats[] = {
 	DRM_FORMAT_XRGB8888,
 };
 
-struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
-					struct drm_device *drm,
-					enum drm_plane_type type)
+struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
+				  enum drm_plane_type type)
 {
-	struct vc4_dummy_plane *dummy_plane;
 	struct drm_plane *plane;
 
-	dummy_plane = drmm_universal_plane_alloc(drm,
-						 struct vc4_dummy_plane, plane.base,
+	plane = __drmm_universal_plane_alloc(drm, sizeof(struct drm_plane), 0,
 						 0,
 						 &vc4_dummy_plane_funcs,
 						 vc4_dummy_plane_formats,
@@ -38,10 +35,9 @@ struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
 						 NULL,
 						 DRM_PLANE_TYPE_PRIMARY,
 						 NULL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
 
-	plane = &dummy_plane->plane.base;
 	drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs);
 
-	return dummy_plane;
+	return plane;
 }

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:11 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:11 +0100
Subject: [PATCH v7 25/36] drm/connector: hdmi: Add Infoframes generation
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-25-8f4af575fce2@kernel.org>

Infoframes in KMS is usually handled by a bunch of low-level helpers
that require quite some boilerplate for drivers. This leads to
discrepancies with how drivers generate them, and which are actually
sent.

Now that we have everything needed to generate them in the HDMI
connector state, we can generate them in our common logic so that
drivers can simply reuse what we precomputed.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/Kconfig                            |   1 +
 drivers/gpu/drm/drm_atomic_state_helper.c          | 327 +++++++++++++++++++++
 drivers/gpu/drm/drm_connector.c                    |  16 +
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |   1 +
 drivers/gpu/drm/tests/drm_connector_test.c         |  12 +
 include/drm/drm_atomic_state_helper.h              |   8 +
 include/drm/drm_connector.h                        | 133 +++++++++
 7 files changed, 498 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 872edb47bb53..ad9c467e20ce 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -99,6 +99,7 @@ config DRM_KUNIT_TEST
 config DRM_KMS_HELPER
 	tristate
 	depends on DRM
+	select DRM_DISPLAY_HDMI_HELPER
 	help
 	  CRTC helpers for KMS drivers.
 
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index e66272c0d006..46d9fd2ea8fa 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -38,6 +38,8 @@
 #include <drm/drm_vblank.h>
 #include <drm/drm_writeback.h>
 
+#include <drm/display/drm_hdmi_helper.h>
+
 #include <linux/slab.h>
 #include <linux/dma-fence.h>
 
@@ -914,6 +916,142 @@ hdmi_compute_config(const struct drm_connector *connector,
 	return -EINVAL;
 }
 
+static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
+				       struct drm_connector_state *state)
+{
+	const struct drm_display_mode *mode =
+		connector_state_get_mode(state);
+	struct drm_connector_hdmi_infoframe *infoframe =
+		&state->hdmi.infoframes.avi;
+	struct hdmi_avi_infoframe *frame =
+		&infoframe->data.avi;
+	bool is_full_range = state->hdmi.is_full_range;
+	enum hdmi_quantization_range rgb_quant_range =
+		is_full_range ? HDMI_QUANTIZATION_RANGE_FULL : HDMI_QUANTIZATION_RANGE_LIMITED;
+	int ret;
+
+	ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode);
+	if (ret)
+		return ret;
+
+	frame->colorspace = state->hdmi.output_format;
+
+	drm_hdmi_avi_infoframe_quant_range(frame, connector, mode, rgb_quant_range);
+	drm_hdmi_avi_infoframe_colorimetry(frame, state);
+	drm_hdmi_avi_infoframe_bars(frame, state);
+
+	infoframe->set = true;
+
+	return 0;
+}
+
+static int hdmi_generate_spd_infoframe(const struct drm_connector *connector,
+				       struct drm_connector_state *state)
+{
+	struct drm_connector_hdmi_infoframe *infoframe =
+		&state->hdmi.infoframes.spd;
+	struct hdmi_spd_infoframe *frame =
+		&infoframe->data.spd;
+	int ret;
+
+	ret = hdmi_spd_infoframe_init(frame,
+				      connector->hdmi.vendor,
+				      connector->hdmi.product);
+	if (ret)
+		return ret;
+
+	frame->sdi = HDMI_SPD_SDI_PC;
+
+	infoframe->set = true;
+
+	return 0;
+}
+
+static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector,
+				       struct drm_connector_state *state)
+{
+	struct drm_connector_hdmi_infoframe *infoframe =
+		&state->hdmi.infoframes.hdr_drm;
+	struct hdmi_drm_infoframe *frame =
+		&infoframe->data.drm;
+	int ret;
+
+	if (connector->max_bpc < 10)
+		return 0;
+
+	if (!state->hdr_output_metadata)
+		return 0;
+
+	ret = drm_hdmi_infoframe_set_hdr_metadata(frame, state);
+	if (ret)
+		return ret;
+
+	infoframe->set = true;
+
+	return 0;
+}
+
+static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector *connector,
+					       struct drm_connector_state *state)
+{
+	const struct drm_display_mode *mode =
+		connector_state_get_mode(state);
+	struct drm_connector_hdmi_infoframe *infoframe =
+		&state->hdmi.infoframes.hdmi;
+	struct hdmi_vendor_infoframe *frame =
+		&infoframe->data.vendor.hdmi;
+	int ret;
+
+	ret = drm_hdmi_vendor_infoframe_from_display_mode(frame, connector, mode);
+	if (ret) {
+		if (ret == -EINVAL)
+			return 0;
+
+		return ret;
+	}
+
+	infoframe->set = true;
+
+	return 0;
+}
+
+static int
+hdmi_generate_infoframes(const struct drm_connector *connector,
+			 struct drm_connector_state *state)
+{
+	const struct drm_display_info *info = &connector->display_info;
+	int ret;
+
+	if (!info->is_hdmi)
+		return 0;
+
+	if (!info->has_hdmi_infoframe)
+		return 0;
+
+	ret = hdmi_generate_avi_infoframe(connector, state);
+	if (ret)
+		return ret;
+
+	ret = hdmi_generate_spd_infoframe(connector, state);
+	if (ret)
+		return ret;
+
+	/*
+	 * Audio Infoframes will be generated by ALSA, and updated by
+	 * drm_atomic_helper_connector_hdmi_update_audio_infoframe().
+	 */
+
+	ret = hdmi_generate_hdr_infoframe(connector, state);
+	if (ret)
+		return ret;
+
+	ret = hdmi_generate_hdmi_vendor_infoframe(connector, state);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 /**
  * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
  * @connector: DRM Connector
@@ -943,6 +1081,10 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 	if (ret)
 		return ret;
 
+	ret = hdmi_generate_infoframes(connector, new_state);
+	if (ret)
+		return ret;
+
 	if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb ||
 	    old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
 	    old_state->hdmi.output_format != new_state->hdmi.output_format) {
@@ -960,6 +1102,191 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
 
+#define HDMI_MAX_INFOFRAME_SIZE		29
+
+static int clear_device_infoframe(struct drm_connector *connector,
+				  enum hdmi_infoframe_type type)
+{
+	const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
+
+	if (!funcs || !funcs->clear_infoframe)
+		return 0;
+
+	return funcs->clear_infoframe(connector, type);
+}
+
+static int clear_infoframe(struct drm_connector *connector,
+			   struct drm_connector_hdmi_infoframe *conn_frame,
+			   struct drm_connector_hdmi_infoframe *old_frame)
+{
+	int ret;
+
+	ret = clear_device_infoframe(connector, old_frame->data.any.type);
+	if (ret)
+		return ret;
+
+	memset(old_frame, 0, sizeof(*old_frame));
+
+	return 0;
+}
+
+static int write_device_infoframe(struct drm_connector *connector,
+				  union hdmi_infoframe *frame)
+{
+	const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
+	u8 buffer[HDMI_MAX_INFOFRAME_SIZE];
+	int len;
+
+	if (!funcs || !funcs->write_infoframe)
+		return -ENOSYS;
+
+	len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer));
+	if (len < 0)
+		return len;
+
+	return funcs->write_infoframe(connector, frame->any.type, buffer, len);
+}
+
+static int write_infoframe(struct drm_connector *connector,
+			   struct drm_connector_hdmi_infoframe *conn_frame,
+			   struct drm_connector_hdmi_infoframe *new_frame)
+{
+	int ret;
+
+	ret = write_device_infoframe(connector, &new_frame->data);
+	if (ret)
+		return ret;
+
+	if (conn_frame)
+		memcpy(conn_frame, new_frame, sizeof(*conn_frame));
+
+	return 0;
+}
+
+static int write_or_clear_infoframe(struct drm_connector *connector,
+				    struct drm_connector_hdmi_infoframe *conn_frame,
+				    struct drm_connector_hdmi_infoframe *old_frame,
+				    struct drm_connector_hdmi_infoframe *new_frame)
+{
+	if (new_frame->set)
+		return write_infoframe(connector, conn_frame, new_frame);
+
+	if (old_frame->set && !new_frame->set)
+		return clear_infoframe(connector, conn_frame, old_frame);
+
+	return 0;
+}
+
+#define UPDATE_INFOFRAME(c, os, ns, i)				\
+	write_or_clear_infoframe(c,				\
+				 &(c)->hdmi.infoframes.i,	\
+				 &(os)->hdmi.infoframes.i,	\
+				 &(ns)->hdmi.infoframes.i)
+
+/**
+ * drm_atomic_helper_connector_hdmi_update_infoframes - Update the Infoframes
+ * @connector: A pointer to the HDMI connector
+ * @state: The HDMI connector state to generate the infoframe from
+ *
+ * This function is meant for HDMI connector drivers to write their
+ * infoframes. It will typically be used in a
+ * @drm_connector_helper_funcs.atomic_enable implementation.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
+						       struct drm_atomic_state *state)
+{
+	struct drm_connector_state *old_state =
+		drm_atomic_get_old_connector_state(state, connector);
+	struct drm_connector_state *new_state =
+		drm_atomic_get_new_connector_state(state, connector);
+	struct drm_display_info *info = &connector->display_info;
+	int ret;
+
+	if (!info->is_hdmi)
+		return 0;
+
+	if (!info->has_hdmi_infoframe)
+		return 0;
+
+	mutex_lock(&connector->hdmi.infoframes.lock);
+
+	ret = UPDATE_INFOFRAME(connector, old_state, new_state, avi);
+	if (ret)
+		goto out;
+
+	if (connector->hdmi.infoframes.audio.set) {
+		ret = write_infoframe(connector,
+				      NULL,
+				      &connector->hdmi.infoframes.audio);
+		if (ret)
+			goto out;
+	}
+
+	ret = UPDATE_INFOFRAME(connector, old_state, new_state, hdr_drm);
+	if (ret)
+		goto out;
+
+	ret = UPDATE_INFOFRAME(connector, old_state, new_state, spd);
+	if (ret)
+		goto out;
+
+	ret = UPDATE_INFOFRAME(connector, old_state, new_state, hdmi);
+	if (ret)
+		goto out;
+
+out:
+	mutex_unlock(&connector->hdmi.infoframes.lock);
+	return ret;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_infoframes);
+
+#undef UPDATE_INFOFRAME
+#undef UPDATE_INFOFRAME_TOGGLE
+
+/**
+ * drm_atomic_helper_connector_hdmi_update_audio_infoframe - Update the Audio Infoframe
+ * @connector: A pointer to the HDMI connector
+ * @frame: A pointer to the audio infoframe to write
+ *
+ * This function is meant for HDMI connector drivers to update their
+ * audio infoframe. It will typically be used in one of the ALSA hooks
+ * (most likely prepare).
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int
+drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector,
+							struct hdmi_audio_infoframe *frame)
+{
+	struct drm_connector_hdmi_infoframe infoframe = {};
+	struct drm_display_info *info = &connector->display_info;
+	int ret;
+
+	if (!info->is_hdmi)
+		return 0;
+
+	if (!info->has_hdmi_infoframe)
+		return 0;
+
+	memcpy(&infoframe.data, frame, sizeof(infoframe.data));
+	infoframe.set = true;
+
+	mutex_lock(&connector->hdmi.infoframes.lock);
+
+	ret = write_infoframe(connector,
+			      &connector->hdmi.infoframes.audio,
+			      &infoframe);
+
+	mutex_unlock(&connector->hdmi.infoframes.lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe);
+
 /**
  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
  * @connector: connector object
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 6ffe59d01698..6cfc301096ef 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -456,6 +456,8 @@ EXPORT_SYMBOL(drmm_connector_init);
  * drmm_connector_hdmi_init - Init a preallocated HDMI connector
  * @dev: DRM device
  * @connector: A pointer to the HDMI connector to init
+ * @vendor: HDMI Controller Vendor name
+ * @product: HDMI Controller Product name
  * @funcs: callbacks for this connector
  * @hdmi_funcs: HDMI-related callbacks for this connector
  * @connector_type: user visible type of the connector
@@ -476,6 +478,7 @@ EXPORT_SYMBOL(drmm_connector_init);
  */
 int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
+			     const char *vendor, const char *product,
 			     const struct drm_connector_funcs *funcs,
 			     const struct drm_connector_hdmi_funcs *hdmi_funcs,
 			     int connector_type,
@@ -485,6 +488,13 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 {
 	int ret;
 
+	if (!vendor || !product)
+		return -EINVAL;
+
+	if ((strlen(vendor) > DRM_CONNECTOR_HDMI_VENDOR_LEN) ||
+	    (strlen(product) > DRM_CONNECTOR_HDMI_PRODUCT_LEN))
+		return -EINVAL;
+
 	if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||
 	      connector_type == DRM_MODE_CONNECTOR_HDMIB))
 		return -EINVAL;
@@ -500,6 +510,12 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 		return ret;
 
 	connector->hdmi.supported_formats = supported_formats;
+	strtomem_pad(connector->hdmi.vendor, vendor, 0);
+	strtomem_pad(connector->hdmi.product, product, 0);
+
+	ret = drmm_mutex_init(dev, &connector->hdmi.infoframes.lock);
+	if (ret)
+		return ret;
 
 	/*
 	 * drm_connector_attach_max_bpc_property() requires the
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index dcc0f7486f49..b28409fe65dd 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -203,6 +203,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test,
 
 	conn = &priv->connector;
 	ret = drmm_connector_hdmi_init(drm, conn,
+				       "Vendor", "Product",
 				       &dummy_connector_funcs,
 				       &dummy_connector_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 6a3651b08c81..b9c80d282380 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -189,6 +189,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -208,6 +209,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -227,6 +229,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -246,6 +249,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -269,6 +273,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -304,6 +309,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -339,6 +345,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -370,6 +377,7 @@ static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -389,6 +397,7 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
@@ -409,6 +418,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       connector_type,
@@ -443,6 +453,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       connector_type,
@@ -708,6 +719,7 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(
 	int ret;
 
 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       "Vendor", "Product",
 				       &dummy_funcs,
 				       &dummy_hdmi_funcs,
 				       DRM_MODE_CONNECTOR_HDMIA,
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index d59d2b3aef9a..22f083968aa8 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -40,6 +40,8 @@ struct drm_private_state;
 struct drm_modeset_acquire_ctx;
 struct drm_device;
 
+struct hdmi_audio_infoframe;
+
 void __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *state,
 					  struct drm_crtc *crtc);
 void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
@@ -88,6 +90,12 @@ void
 __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state);
 void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
 					  struct drm_connector_state *state);
+
+int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector,
+							    struct hdmi_audio_infoframe *frame);
+int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
+						       struct drm_atomic_state *state);
+
 void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
 						     struct drm_private_state *state);
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 3eaf4d54364d..5964ef283022 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -914,6 +914,21 @@ struct drm_tv_connector_state {
 	unsigned int hue;
 };
 
+/**
+ * struct drm_connector_hdmi_infoframe - HDMI Infoframe container
+ */
+struct drm_connector_hdmi_infoframe {
+	/**
+	 * @data: HDMI Infoframe structure
+	 */
+	union hdmi_infoframe data;
+
+	/**
+	 * @set: Is the content of @data valid?
+	 */
+	bool set;
+};
+
 /**
  * struct drm_connector_state - mutable connector state
  */
@@ -1070,6 +1085,35 @@ struct drm_connector_state {
 		 */
 		enum drm_hdmi_broadcast_rgb broadcast_rgb;
 
+		/**
+		 * @infoframes: HDMI Infoframes matching that state
+		 */
+		struct {
+			/**
+			 * @avi: AVI Infoframes structure matching our
+			 * state.
+			 */
+			struct drm_connector_hdmi_infoframe avi;
+
+			/**
+			 * @hdr_drm: DRM (Dynamic Range and Mastering)
+			 * Infoframes structure matching our state.
+			 */
+			struct drm_connector_hdmi_infoframe hdr_drm;
+
+			/**
+			 * @spd: SPD Infoframes structure matching our
+			 * state.
+			 */
+			struct drm_connector_hdmi_infoframe spd;
+
+			/**
+			 * @vendor: HDMI Vendor Infoframes structure
+			 * matching our state.
+			 */
+			struct drm_connector_hdmi_infoframe hdmi;
+		} infoframes;
+
 		/**
 		 * @is_full_range: Is the output supposed to use a full
 		 * RGB Quantization Range or not?
@@ -1115,6 +1159,41 @@ struct drm_connector_hdmi_funcs {
 	(*tmds_char_rate_valid)(const struct drm_connector *connector,
 				const struct drm_display_mode *mode,
 				unsigned long long tmds_rate);
+
+	/**
+	 * @clear_infoframe:
+	 *
+	 * This callback is invoked through
+	 * @drm_atomic_helper_hdmi_connector_update_infoframes during a
+	 * commit to clear the infoframes into the hardware. It will be
+	 * called multiple times, once for every disabled infoframe
+	 * type.
+	 *
+	 * The @clear_infoframe callback is optional.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*clear_infoframe)(struct drm_connector *connector,
+			       enum hdmi_infoframe_type type);
+
+	/**
+	 * @write_infoframe:
+	 *
+	 * This callback is invoked through
+	 * @drm_atomic_helper_hdmi_connector_update_infoframes during a
+	 * commit to program the infoframes into the hardware. It will
+	 * be called multiple times, once for every updated infoframe
+	 * type.
+	 *
+	 * The @write_infoframe callback is mandatory.
+	 *
+	 * Returns:
+	 * 0 on success, a negative error code otherwise
+	 */
+	int (*write_infoframe)(struct drm_connector *connector,
+			       enum hdmi_infoframe_type type,
+			       const u8 *buffer, size_t len);
 };
 
 /**
@@ -1986,6 +2065,18 @@ struct drm_connector {
 	 * @hdmi: HDMI-related variable and properties.
 	 */
 	struct {
+#define DRM_CONNECTOR_HDMI_VENDOR_LEN	8
+		/**
+		 * @vendor: HDMI Controller Vendor Name
+		 */
+		unsigned char vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] __nonstring;
+
+#define DRM_CONNECTOR_HDMI_PRODUCT_LEN	16
+		/**
+		 * @product: HDMI Controller Product Name
+		 */
+		unsigned char product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] __nonstring;
+
 		/**
 		 * @supported_formats: Bitmask of @hdmi_colorspace
 		 * supported by the controller.
@@ -1996,6 +2087,47 @@ struct drm_connector {
 		 * @funcs: HDMI connector Control Functions
 		 */
 		const struct drm_connector_hdmi_funcs *funcs;
+
+		/**
+		 * @infoframes: Current Infoframes output by the connector
+		 */
+		struct {
+			/**
+			 * @lock: Mutex protecting against concurrent access to
+			 * the infoframes, most notably between KMS and ALSA.
+			 */
+			struct mutex lock;
+
+			/**
+			 * @audio: Current Audio Infoframes structure. Protected
+			 * by @lock.
+			 */
+			struct drm_connector_hdmi_infoframe audio;
+
+			/**
+			 * @avi: Current AVI Infoframes structure. Protected by
+			 * @lock.
+			 */
+			struct drm_connector_hdmi_infoframe avi;
+
+			/**
+			 * @hdr_drm: Current DRM (Dynamic Range and Mastering)
+			 * Infoframes structure. Protected by @lock.
+			 */
+			struct drm_connector_hdmi_infoframe hdr_drm;
+
+			/**
+			 * @spd: Current SPD Infoframes structure. Protected by
+			 * @lock.
+			 */
+			struct drm_connector_hdmi_infoframe spd;
+
+			/**
+			 * @vendor: Current HDMI Vendor Infoframes structure.
+			 * Protected by @lock.
+			 */
+			struct drm_connector_hdmi_infoframe hdmi;
+		} infoframes;
 	} hdmi;
 };
 
@@ -2017,6 +2149,7 @@ int drmm_connector_init(struct drm_device *dev,
 			struct i2c_adapter *ddc);
 int drmm_connector_hdmi_init(struct drm_device *dev,
 			     struct drm_connector *connector,
+			     const char *vendor, const char *product,
 			     const struct drm_connector_funcs *funcs,
 			     const struct drm_connector_hdmi_funcs *hdmi_funcs,
 			     int connector_type,

-- 
2.43.2



From fancer.lancer at gmail.com  Thu Feb 22 10:12:53 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:53 +0300
Subject: [PATCH v5 08/20] EDAC/synopsys: Drop internal CE and UE counters
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-9-fancer.lancer@gmail.com>

First of all these counters aren't exposed anyhow from the driver.
Secondly the EDAC core already tracks the total amount of the correctable
and uncorrectable errors (see mem_ctl_info.{ce_mc,ue_mc} fields usage).
Drop the useless internal counters then for good.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>

---

Changelog v4:
- Drop redundant empty line.
- Drop private counters access from the check_errors() method too.
---
 drivers/edac/synopsys_edac.c | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 6976ef84e952..5099246db90e 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -304,8 +304,6 @@ struct synps_ecc_status {
  * @message:		Buffer for framing the event specific info.
  * @stat:		ECC status information.
  * @p_data:		Platform data.
- * @ce_cnt:		Correctable Error count.
- * @ue_cnt:		Uncorrectable Error count.
  * @poison_addr:	Data poison address.
  * @row_shift:		Bit shifts for row bit.
  * @col_shift:		Bit shifts for column bit.
@@ -319,8 +317,6 @@ struct synps_edac_priv {
 	char message[SYNPS_EDAC_MSG_SIZE];
 	struct synps_ecc_status stat;
 	const struct synps_platform_data *p_data;
-	u32 ce_cnt;
-	u32 ue_cnt;
 #ifdef CONFIG_EDAC_DEBUG
 	ulong poison_addr;
 	u32 row_shift[18];
@@ -592,13 +588,8 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
 	if (status)
 		return IRQ_NONE;
 
-	priv->ce_cnt += priv->stat.ce_cnt;
-	priv->ue_cnt += priv->stat.ue_cnt;
 	handle_error(mci, &priv->stat);
 
-	edac_dbg(3, "Total error count CE %d UE %d\n",
-		 priv->ce_cnt, priv->ue_cnt);
-
 	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS)
 		writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
 
@@ -624,12 +615,7 @@ static void check_errors(struct mem_ctl_info *mci)
 	if (status)
 		return;
 
-	priv->ce_cnt += priv->stat.ce_cnt;
-	priv->ue_cnt += priv->stat.ue_cnt;
 	handle_error(mci, &priv->stat);
-
-	edac_dbg(3, "Total error count CE %d UE %d\n",
-		 priv->ce_cnt, priv->ue_cnt);
 }
 
 /**
-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:13:01 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:13:01 +0300
Subject: [PATCH v5 16/20] EDAC/synopsys: Detach Zynq A05 DDRC support to separate driver
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-17-fancer.lancer@gmail.com>

The synopsys_edac.c driver currently supports three memory-controllers:
1. Synopsys DW uMCTL2 DDRC v3.80 (with the ZynqMP-specific params).
2. Xilinx ZynqMP DDRC Synopsys DW uMCTL2 DDRC v2.40.
3. Xilinx Zynq A05 DDR controller.
If the first two devices are based on the Synopsys DW uMCTL2 IP-cores
(ZynqMP MC is based on the DW uMCTL2 v2.40) the later device has
absolutely nothing in common with the Synopsys DW uMCTL2 DDR controllers:
the CSRs map is absolutely different; it doesn't support IRQs unlike
the Synopsys memory controllers. Having the driver to support so different
devices caused implementing an additional level of abstraction, which will
be a great deal of obstacle in about to be added comprehensive set of the
Synopsys DDR-controller features (DW uCMTL2 IP-core parameters
auto-detection, common SDRAM<->phys address translation, multi-ranked
memory, ECC scrubber, individual IRQs, DFI alert_n IRQ, and so on).
Moreover the original reason of having these devices support living in a
single driver hasn't been introduced for all these years: the
synopsys_edac.c driver currently supports only a single memory controller
detected on the system.

So in order to make the Synopsys driver ready for the new features added
move the Xilinx Zynq A05 DDRC support into a separate driver: detach the
Zynq-specific callbacks, init/probe/remove methods and move them into the
new zynq_edac.c driver. The resultant driver will mostly look similar to
the code submitted in the initial commit ae9b56e3996d ("EDAC, synps: Add
EDAC support for zynq ddr ecc controller") except a few fixes added
afterwards.

Note several Zynq-specific macros have been used in the DW uMCTL2
DDRC-specific functions. These macros just for a mere coincident have
values suitable for the DW uMCTL2 code but their names either partly or
fully unrelated with the Synopsys memory controllers. Since these macros
are now moved to another driver introduce a new Synopsys-specific ones and
fix the places where the macros have been improperly utilized.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>

---

Changelog v3:
- Drop the no longer used "priv" pointer from the zynq_mc_init() function.
  (@tbot)

Changelog v5:
- Rename handle_error and check_errors to zynq_handle_error and
  zynq_check_errors in the kdoc comments (@tbot)
---
 MAINTAINERS                  |   1 +
 drivers/edac/Kconfig         |   9 +-
 drivers/edac/Makefile        |   1 +
 drivers/edac/synopsys_edac.c | 239 ++---------------
 drivers/edac/zynq_edac.c     | 501 +++++++++++++++++++++++++++++++++++
 5 files changed, 531 insertions(+), 220 deletions(-)
 create mode 100644 drivers/edac/zynq_edac.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 960512bec428..baca1e55cf49 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3020,6 +3020,7 @@ F:	arch/arm/mach-zynq/
 F:	drivers/clocksource/timer-cadence-ttc.c
 F:	drivers/cpuidle/cpuidle-zynq.c
 F:	drivers/edac/synopsys_edac.c
+F:	drivers/edac/zynq_edac.c
 F:	drivers/i2c/busses/i2c-cadence.c
 F:	drivers/i2c/busses/i2c-xiic.c
 F:	drivers/mmc/host/sdhci-of-arasan.c
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 5a7f3fabee22..6e411376d2bb 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -487,7 +487,7 @@ config EDAC_ARMADA_XP
 
 config EDAC_SYNOPSYS
 	tristate "Synopsys DDR Memory Controller"
-	depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_INTEL_SOCFPGA || ARCH_MXC
+	depends on ARCH_ZYNQMP || ARCH_INTEL_SOCFPGA || ARCH_MXC
 	help
 	  Support for error detection and correction on the Synopsys DDR
 	  memory controller.
@@ -542,6 +542,13 @@ config EDAC_DMC520
 	  Support for error detection and correction on the
 	  SoCs with ARM DMC-520 DRAM controller.
 
+config EDAC_ZYNQ
+	tristate "Xilinx Zynq A05 DDR Memory Controller"
+	depends on ARCH_ZYNQ || COMPILE_TEST
+	help
+	  Support for error detection and correction on the Xilinx Zynq A05
+	  DDR memory controller.
+
 config EDAC_ZYNQMP
 	tristate "Xilinx ZynqMP OCM Controller"
 	depends on ARCH_ZYNQMP || COMPILE_TEST
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 9c09893695b7..2829036f8468 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -85,5 +85,6 @@ obj-$(CONFIG_EDAC_ASPEED)		+= aspeed_edac.o
 obj-$(CONFIG_EDAC_BLUEFIELD)		+= bluefield_edac.o
 obj-$(CONFIG_EDAC_DMC520)		+= dmc520_edac.o
 obj-$(CONFIG_EDAC_NPCM)			+= npcm_edac.o
+obj-$(CONFIG_EDAC_ZYNQ)			+= zynq_edac.o
 obj-$(CONFIG_EDAC_ZYNQMP)		+= zynqmp_edac.o
 obj-$(CONFIG_EDAC_VERSAL)		+= versal_edac.o
diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index dfe1abe7c86c..6ea1eaaa7d6f 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -29,68 +29,16 @@
 #define SYNPS_EDAC_MOD_STRING		"synps_edac"
 #define SYNPS_EDAC_MOD_VER		"1"
 
-/* Synopsys DDR memory controller registers that are relevant to ECC */
-#define CTRL_OFST			0x0
-#define T_ZQ_OFST			0xA4
-
-/* ECC control register */
-#define ECC_CTRL_OFST			0xC4
-/* ECC log register */
-#define CE_LOG_OFST			0xC8
-/* ECC address register */
-#define CE_ADDR_OFST			0xCC
-/* ECC data[31:0] register */
-#define CE_DATA_31_0_OFST		0xD0
-
-/* Uncorrectable error info registers */
-#define UE_LOG_OFST			0xDC
-#define UE_ADDR_OFST			0xE0
-#define UE_DATA_31_0_OFST		0xE4
-
-#define STAT_OFST			0xF0
-#define SCRUB_OFST			0xF4
-
-/* Control register bit field definitions */
-#define CTRL_BW_MASK			0xC
-#define CTRL_BW_SHIFT			2
-
-#define DDRCTL_WDTH_16			1
-#define DDRCTL_WDTH_32			0
-
-/* ZQ register bit field definitions */
-#define T_ZQ_DDRMODE_MASK		0x2
-
-/* ECC control register bit field definitions */
-#define ECC_CTRL_CLR_CE_ERR		0x2
-#define ECC_CTRL_CLR_UE_ERR		0x1
-
-/* ECC correctable/uncorrectable error log register definitions */
-#define LOG_VALID			0x1
-#define CE_LOG_BITPOS_MASK		0xFE
-#define CE_LOG_BITPOS_SHIFT		1
-
-/* ECC correctable/uncorrectable error address register definitions */
-#define ADDR_COL_MASK			0xFFF
-#define ADDR_ROW_MASK			0xFFFF000
-#define ADDR_ROW_SHIFT			12
-#define ADDR_BANK_MASK			0x70000000
-#define ADDR_BANK_SHIFT			28
-
-/* ECC statistic register definitions */
-#define STAT_UECNT_MASK			0xFF
-#define STAT_CECNT_MASK			0xFF00
-#define STAT_CECNT_SHIFT		8
-
-/* ECC scrub register definitions */
-#define SCRUB_MODE_MASK			0x7
-#define SCRUB_MODE_SECDED		0x4
-
 /* DDR ECC Quirks */
 #define DDR_ECC_INTR_SUPPORT		BIT(0)
 #define DDR_ECC_DATA_POISON_SUPPORT	BIT(1)
 #define SYNPS_ZYNQMP_IRQ_REGS		BIT(2)
 
-/* ZynqMP Enhanced DDR memory controller registers that are relevant to ECC */
+/* Synopsys DDR memory controller registers that are relevant to ECC */
+
+/* DDRC Master 0 Register */
+#define DDR_MSTR_OFST			0x0
+
 /* ECC Configuration Registers */
 #define ECC_CFG0_OFST			0x70
 #define ECC_CFG1_OFST			0x74
@@ -134,16 +82,22 @@
 #define ECC_ADDRMAP0_OFFSET		0x200
 
 /* Control register bitfield definitions */
-#define ECC_CTRL_BUSWIDTH_MASK		0x3000
-#define ECC_CTRL_BUSWIDTH_SHIFT		12
+#define ECC_CTRL_CLR_CE_ERR		BIT(0)
+#define ECC_CTRL_CLR_UE_ERR		BIT(1)
 #define ECC_CTRL_CLR_CE_ERRCNT		BIT(2)
 #define ECC_CTRL_CLR_UE_ERRCNT		BIT(3)
 
 /* DDR Control Register width definitions  */
+#define DDR_MSTR_BUSWIDTH_MASK		0x3000
+#define DDR_MSTR_BUSWIDTH_SHIFT		12
 #define DDRCTL_EWDTH_16			2
 #define DDRCTL_EWDTH_32			1
 #define DDRCTL_EWDTH_64			0
 
+/* ECC CFG0 register definitions */
+#define ECC_CFG0_MODE_MASK		0x7
+#define ECC_CFG0_MODE_SECDED		0x4
+
 /* ECC status register definitions */
 #define ECC_STAT_UECNT_MASK		0xF0000
 #define ECC_STAT_UECNT_SHIFT		16
@@ -341,61 +295,6 @@ struct synps_platform_data {
 	int quirks;
 };
 
-/**
- * zynq_get_error_info - Get the current ECC error info.
- * @priv:	DDR memory controller private instance data.
- *
- * Return: one if there is no error, otherwise zero.
- */
-static int zynq_get_error_info(struct synps_edac_priv *priv)
-{
-	struct synps_ecc_status *p;
-	u32 regval, clearval = 0;
-	void __iomem *base;
-
-	base = priv->baseaddr;
-	p = &priv->stat;
-
-	regval = readl(base + STAT_OFST);
-	if (!regval)
-		return 1;
-
-	p->ce_cnt = (regval & STAT_CECNT_MASK) >> STAT_CECNT_SHIFT;
-	p->ue_cnt = regval & STAT_UECNT_MASK;
-
-	regval = readl(base + CE_LOG_OFST);
-	if (!(p->ce_cnt && (regval & LOG_VALID)))
-		goto ue_err;
-
-	p->ceinfo.bitpos = (regval & CE_LOG_BITPOS_MASK) >> CE_LOG_BITPOS_SHIFT;
-	regval = readl(base + CE_ADDR_OFST);
-	p->ceinfo.row = (regval & ADDR_ROW_MASK) >> ADDR_ROW_SHIFT;
-	p->ceinfo.col = regval & ADDR_COL_MASK;
-	p->ceinfo.bank = (regval & ADDR_BANK_MASK) >> ADDR_BANK_SHIFT;
-	p->ceinfo.data = readl(base + CE_DATA_31_0_OFST);
-	edac_dbg(3, "CE bit position: %d data: %d\n", p->ceinfo.bitpos,
-		 p->ceinfo.data);
-	clearval = ECC_CTRL_CLR_CE_ERR;
-
-ue_err:
-	regval = readl(base + UE_LOG_OFST);
-	if (!(p->ue_cnt && (regval & LOG_VALID)))
-		goto out;
-
-	regval = readl(base + UE_ADDR_OFST);
-	p->ueinfo.row = (regval & ADDR_ROW_MASK) >> ADDR_ROW_SHIFT;
-	p->ueinfo.col = regval & ADDR_COL_MASK;
-	p->ueinfo.bank = (regval & ADDR_BANK_MASK) >> ADDR_BANK_SHIFT;
-	p->ueinfo.data = readl(base + UE_DATA_31_0_OFST);
-	clearval |= ECC_CTRL_CLR_UE_ERR;
-
-out:
-	writel(clearval, base + ECC_CTRL_OFST);
-	writel(0x0, base + ECC_CTRL_OFST);
-
-	return 0;
-}
-
 /**
  * zynqmp_get_error_info - Get the current ECC error info.
  * @priv:	DDR memory controller private instance data.
@@ -614,37 +513,6 @@ static void check_errors(struct mem_ctl_info *mci)
 	handle_error(mci, &priv->stat);
 }
 
-/**
- * zynq_get_dtype - Return the controller memory width.
- * @base:	DDR memory controller base address.
- *
- * Get the EDAC device type width appropriate for the current controller
- * configuration.
- *
- * Return: a device type width enumeration.
- */
-static enum dev_type zynq_get_dtype(const void __iomem *base)
-{
-	enum dev_type dt;
-	u32 width;
-
-	width = readl(base + CTRL_OFST);
-	width = (width & CTRL_BW_MASK) >> CTRL_BW_SHIFT;
-
-	switch (width) {
-	case DDRCTL_WDTH_16:
-		dt = DEV_X2;
-		break;
-	case DDRCTL_WDTH_32:
-		dt = DEV_X4;
-		break;
-	default:
-		dt = DEV_UNKNOWN;
-	}
-
-	return dt;
-}
-
 /**
  * zynqmp_get_dtype - Return the controller memory width.
  * @base:	DDR memory controller base address.
@@ -658,7 +526,7 @@ static enum dev_type zynqmp_get_dtype(const void __iomem *base)
 {
 	u32 regval;
 
-	regval = readl(base + CTRL_OFST);
+	regval = readl(base + DDR_MSTR_OFST);
 	if (!(regval & MEM_TYPE_DDR4))
 		return DEV_UNKNOWN;
 
@@ -677,30 +545,6 @@ static enum dev_type zynqmp_get_dtype(const void __iomem *base)
 	return DEV_UNKNOWN;
 }
 
-/**
- * zynq_get_ecc_state - Return the controller ECC enable/disable status.
- * @base:	DDR memory controller base address.
- *
- * Get the ECC enable/disable status of the controller.
- *
- * Return: true if enabled, otherwise false.
- */
-static bool zynq_get_ecc_state(void __iomem *base)
-{
-	enum dev_type dt;
-	u32 ecctype;
-
-	dt = zynq_get_dtype(base);
-	if (dt == DEV_UNKNOWN)
-		return false;
-
-	ecctype = readl(base + SCRUB_OFST) & SCRUB_MODE_MASK;
-	if ((ecctype == SCRUB_MODE_SECDED) && (dt == DEV_X2))
-		return true;
-
-	return false;
-}
-
 /**
  * zynqmp_get_ecc_state - Return the controller ECC enable/disable status.
  * @base:	DDR memory controller base address.
@@ -713,9 +557,9 @@ static bool zynqmp_get_ecc_state(void __iomem *base)
 {
 	u32 regval;
 
-	regval = readl(base + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
+	regval = readl(base + ECC_CFG0_OFST) & ECC_CFG0_MODE_MASK;
 
-	return (regval == SCRUB_MODE_SECDED);
+	return (regval == ECC_CFG0_MODE_SECDED);
 }
 
 /**
@@ -732,30 +576,6 @@ static u32 get_memsize(void)
 	return inf.totalram * inf.mem_unit;
 }
 
-/**
- * zynq_get_mtype - Return the controller memory type.
- * @base:	Synopsys ECC status structure.
- *
- * Get the EDAC memory type appropriate for the current controller
- * configuration.
- *
- * Return: a memory type enumeration.
- */
-static enum mem_type zynq_get_mtype(const void __iomem *base)
-{
-	enum mem_type mt;
-	u32 memtype;
-
-	memtype = readl(base + T_ZQ_OFST);
-
-	if (memtype & T_ZQ_DDRMODE_MASK)
-		mt = MEM_DDR3;
-	else
-		mt = MEM_DDR2;
-
-	return mt;
-}
-
 /**
  * zynqmp_get_mtype - Returns controller memory type.
  * @base:	Synopsys ECC status structure.
@@ -770,7 +590,7 @@ static enum mem_type zynqmp_get_mtype(const void __iomem *base)
 	enum mem_type mt;
 	u32 memtype;
 
-	memtype = readl(base + CTRL_OFST);
+	memtype = readl(base + DDR_MSTR_OFST);
 
 	if ((memtype & MEM_TYPE_DDR3) || (memtype & MEM_TYPE_LPDDR3))
 		mt = MEM_DDR3;
@@ -882,14 +702,6 @@ static int setup_irq(struct mem_ctl_info *mci,
 	return 0;
 }
 
-static const struct synps_platform_data zynq_edac_def = {
-	.get_error_info	= zynq_get_error_info,
-	.get_mtype	= zynq_get_mtype,
-	.get_dtype	= zynq_get_dtype,
-	.get_ecc_state	= zynq_get_ecc_state,
-	.quirks		= 0,
-};
-
 static const struct synps_platform_data zynqmp_edac_def = {
 	.get_error_info	= zynqmp_get_error_info,
 	.get_mtype	= zynqmp_get_mtype,
@@ -916,10 +728,6 @@ static const struct synps_platform_data synopsys_edac_def = {
 
 
 static const struct of_device_id synps_edac_match[] = {
-	{
-		.compatible = "xlnx,zynq-ddrc-a05",
-		.data = (void *)&zynq_edac_def
-	},
 	{
 		.compatible = "xlnx,zynqmp-ddrc-2.40a",
 		.data = (void *)&zynqmp_edac_def
@@ -1141,8 +949,8 @@ static void setup_column_address_map(struct synps_edac_priv *priv, u32 *addrmap)
 	u32 width, memtype;
 	int index;
 
-	memtype = readl(priv->baseaddr + CTRL_OFST);
-	width = (memtype & ECC_CTRL_BUSWIDTH_MASK) >> ECC_CTRL_BUSWIDTH_SHIFT;
+	memtype = readl(priv->baseaddr + DDR_MSTR_OFST);
+	width = (memtype & DDR_MSTR_BUSWIDTH_MASK) >> DDR_MSTR_BUSWIDTH_SHIFT;
 
 	priv->col_shift[0] = 0;
 	priv->col_shift[1] = 1;
@@ -1337,7 +1145,7 @@ static int mc_probe(struct platform_device *pdev)
 	layers[1].size = SYNPS_EDAC_NR_CHANS;
 	layers[1].is_virt_csrow = false;
 
-	mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
+	mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers,
 			    sizeof(struct synps_edac_priv));
 	if (!mci) {
 		edac_printk(KERN_ERR, EDAC_MC,
@@ -1379,13 +1187,6 @@ static int mc_probe(struct platform_device *pdev)
 		setup_address_map(priv);
 #endif
 
-	/*
-	 * Start capturing the correctable and uncorrectable errors. A write of
-	 * 0 starts the counters.
-	 */
-	if (!(priv->p_data->quirks & DDR_ECC_INTR_SUPPORT))
-		writel(0x0, baseaddr + ECC_CTRL_OFST);
-
 	return rc;
 
 free_edac_mc:
diff --git a/drivers/edac/zynq_edac.c b/drivers/edac/zynq_edac.c
new file mode 100644
index 000000000000..be26934a9c20
--- /dev/null
+++ b/drivers/edac/zynq_edac.c
@@ -0,0 +1,501 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Zynq DDR ECC Driver
+ * This driver is based on ppc4xx_edac.c drivers
+ *
+ * Copyright (C) 2012 - 2014 Xilinx, Inc.
+ */
+
+#include <linux/edac.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "edac_module.h"
+
+/* Number of cs_rows needed per memory controller */
+#define ZYNQ_EDAC_NR_CSROWS		1
+
+/* Number of channels per memory controller */
+#define ZYNQ_EDAC_NR_CHANS		1
+
+/* Granularity of reported error in bytes */
+#define ZYNQ_EDAC_ERR_GRAIN		1
+
+#define ZYNQ_EDAC_MSG_SIZE		256
+
+#define ZYNQ_EDAC_MOD_STRING		"zynq_edac"
+#define ZYNQ_EDAC_MOD_VER		"1"
+
+/* Zynq DDR memory controller ECC registers */
+#define ZYNQ_CTRL_OFST			0x0
+#define ZYNQ_T_ZQ_OFST			0xA4
+
+/* ECC control register */
+#define ZYNQ_ECC_CTRL_OFST		0xC4
+/* ECC log register */
+#define ZYNQ_CE_LOG_OFST		0xC8
+/* ECC address register */
+#define ZYNQ_CE_ADDR_OFST		0xCC
+/* ECC data[31:0] register */
+#define ZYNQ_CE_DATA_31_0_OFST		0xD0
+
+/* Uncorrectable error info registers */
+#define ZYNQ_UE_LOG_OFST		0xDC
+#define ZYNQ_UE_ADDR_OFST		0xE0
+#define ZYNQ_UE_DATA_31_0_OFST		0xE4
+
+#define ZYNQ_STAT_OFST			0xF0
+#define ZYNQ_SCRUB_OFST			0xF4
+
+/* Control register bit field definitions */
+#define ZYNQ_CTRL_BW_MASK		0xC
+#define ZYNQ_CTRL_BW_SHIFT		2
+
+#define ZYNQ_DDRCTL_WDTH_16		1
+#define ZYNQ_DDRCTL_WDTH_32		0
+
+/* ZQ register bit field definitions */
+#define ZYNQ_T_ZQ_DDRMODE_MASK		0x2
+
+/* ECC control register bit field definitions */
+#define ZYNQ_ECC_CTRL_CLR_CE_ERR	0x2
+#define ZYNQ_ECC_CTRL_CLR_UE_ERR	0x1
+
+/* ECC correctable/uncorrectable error log register definitions */
+#define ZYNQ_LOG_VALID			0x1
+#define ZYNQ_CE_LOG_BITPOS_MASK		0xFE
+#define ZYNQ_CE_LOG_BITPOS_SHIFT	1
+
+/* ECC correctable/uncorrectable error address register definitions */
+#define ZYNQ_ADDR_COL_MASK		0xFFF
+#define ZYNQ_ADDR_ROW_MASK		0xFFFF000
+#define ZYNQ_ADDR_ROW_SHIFT		12
+#define ZYNQ_ADDR_BANK_MASK		0x70000000
+#define ZYNQ_ADDR_BANK_SHIFT		28
+
+/* ECC statistic register definitions */
+#define ZYNQ_STAT_UECNT_MASK		0xFF
+#define ZYNQ_STAT_CECNT_MASK		0xFF00
+#define ZYNQ_STAT_CECNT_SHIFT		8
+
+/* ECC scrub register definitions */
+#define ZYNQ_SCRUB_MODE_MASK		0x7
+#define ZYNQ_SCRUB_MODE_SECDED		0x4
+
+/**
+ * struct zynq_ecc_error_info - ECC error log information.
+ * @row:	Row number.
+ * @col:	Column number.
+ * @bank:	Bank number.
+ * @bitpos:	Bit position.
+ * @data:	Data causing the error.
+ */
+struct zynq_ecc_error_info {
+	u32 row;
+	u32 col;
+	u32 bank;
+	u32 bitpos;
+	u32 data;
+};
+
+/**
+ * struct zynq_ecc_status - ECC status information to report.
+ * @ce_cnt:	Correctable error count.
+ * @ue_cnt:	Uncorrectable error count.
+ * @ceinfo:	Correctable error log information.
+ * @ueinfo:	Uncorrectable error log information.
+ */
+struct zynq_ecc_status {
+	u32 ce_cnt;
+	u32 ue_cnt;
+	struct zynq_ecc_error_info ceinfo;
+	struct zynq_ecc_error_info ueinfo;
+};
+
+/**
+ * struct zynq_edac_priv - DDR memory controller private instance data.
+ * @baseaddr:	Base address of the DDR controller.
+ * @message:	Buffer for framing the event specific info.
+ * @stat:	ECC status information.
+ */
+struct zynq_edac_priv {
+	void __iomem *baseaddr;
+	char message[ZYNQ_EDAC_MSG_SIZE];
+	struct zynq_ecc_status stat;
+};
+
+/**
+ * zynq_get_error_info - Get the current ECC error info.
+ * @priv:	DDR memory controller private instance data.
+ *
+ * Return: one if there is no error, otherwise zero.
+ */
+static int zynq_get_error_info(struct zynq_edac_priv *priv)
+{
+	struct zynq_ecc_status *p;
+	u32 regval, clearval = 0;
+	void __iomem *base;
+
+	base = priv->baseaddr;
+	p = &priv->stat;
+
+	regval = readl(base + ZYNQ_STAT_OFST);
+	if (!regval)
+		return 1;
+
+	p->ce_cnt = (regval & ZYNQ_STAT_CECNT_MASK) >> ZYNQ_STAT_CECNT_SHIFT;
+	p->ue_cnt = regval & ZYNQ_STAT_UECNT_MASK;
+
+	regval = readl(base + ZYNQ_CE_LOG_OFST);
+	if (!(p->ce_cnt && (regval & ZYNQ_LOG_VALID)))
+		goto ue_err;
+
+	p->ceinfo.bitpos = (regval & ZYNQ_CE_LOG_BITPOS_MASK) >> ZYNQ_CE_LOG_BITPOS_SHIFT;
+	regval = readl(base + ZYNQ_CE_ADDR_OFST);
+	p->ceinfo.row = (regval & ZYNQ_ADDR_ROW_MASK) >> ZYNQ_ADDR_ROW_SHIFT;
+	p->ceinfo.col = regval & ZYNQ_ADDR_COL_MASK;
+	p->ceinfo.bank = (regval & ZYNQ_ADDR_BANK_MASK) >> ZYNQ_ADDR_BANK_SHIFT;
+	p->ceinfo.data = readl(base + ZYNQ_CE_DATA_31_0_OFST);
+	edac_dbg(3, "CE bit position: %d data: %d\n", p->ceinfo.bitpos,
+		 p->ceinfo.data);
+	clearval = ZYNQ_ECC_CTRL_CLR_CE_ERR;
+
+ue_err:
+	regval = readl(base + ZYNQ_UE_LOG_OFST);
+	if (!(p->ue_cnt && (regval & ZYNQ_LOG_VALID)))
+		goto out;
+
+	regval = readl(base + ZYNQ_UE_ADDR_OFST);
+	p->ueinfo.row = (regval & ZYNQ_ADDR_ROW_MASK) >> ZYNQ_ADDR_ROW_SHIFT;
+	p->ueinfo.col = regval & ZYNQ_ADDR_COL_MASK;
+	p->ueinfo.bank = (regval & ZYNQ_ADDR_BANK_MASK) >> ZYNQ_ADDR_BANK_SHIFT;
+	p->ueinfo.data = readl(base + ZYNQ_UE_DATA_31_0_OFST);
+	clearval |= ZYNQ_ECC_CTRL_CLR_UE_ERR;
+
+out:
+	writel(clearval, base + ZYNQ_ECC_CTRL_OFST);
+	writel(0x0, base + ZYNQ_ECC_CTRL_OFST);
+
+	return 0;
+}
+
+/**
+ * zynq_handle_error - Handle Correctable and Uncorrectable errors.
+ * @mci:	EDAC memory controller instance.
+ * @p:		Zynq ECC status structure.
+ *
+ * Handles ECC correctable and uncorrectable errors.
+ */
+static void zynq_handle_error(struct mem_ctl_info *mci, struct zynq_ecc_status *p)
+{
+	struct zynq_edac_priv *priv = mci->pvt_info;
+	struct zynq_ecc_error_info *pinf;
+
+	if (p->ce_cnt) {
+		pinf = &p->ceinfo;
+
+		snprintf(priv->message, ZYNQ_EDAC_MSG_SIZE,
+			 "Row %d Bank %d Col %d Bit %d Data 0x%08x",
+			 pinf->row, pinf->bank, pinf->col,
+			 pinf->bitpos, pinf->data);
+
+		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
+				     p->ce_cnt, 0, 0, 0, 0, 0, -1,
+				     priv->message, "");
+	}
+
+	if (p->ue_cnt) {
+		pinf = &p->ueinfo;
+
+		snprintf(priv->message, ZYNQ_EDAC_MSG_SIZE,
+			 "Row %d Bank %d Col %d",
+			 pinf->row, pinf->bank, pinf->col);
+
+		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
+				     p->ue_cnt, 0, 0, 0, 0, 0, -1,
+				     priv->message, "");
+	}
+
+	memset(p, 0, sizeof(*p));
+}
+
+/**
+ * zynq_check_errors - Check controller for ECC errors.
+ * @mci:	EDAC memory controller instance.
+ *
+ * Check and post ECC errors. Called by the polling thread.
+ */
+static void zynq_check_errors(struct mem_ctl_info *mci)
+{
+	struct zynq_edac_priv *priv = mci->pvt_info;
+	int status;
+
+	status = zynq_get_error_info(priv);
+	if (status)
+		return;
+
+	zynq_handle_error(mci, &priv->stat);
+}
+
+/**
+ * zynq_get_dtype - Return the controller memory width.
+ * @base:	DDR memory controller base address.
+ *
+ * Get the EDAC device type width appropriate for the current controller
+ * configuration.
+ *
+ * Return: a device type width enumeration.
+ */
+static enum dev_type zynq_get_dtype(const void __iomem *base)
+{
+	enum dev_type dt;
+	u32 width;
+
+	width = readl(base + ZYNQ_CTRL_OFST);
+	width = (width & ZYNQ_CTRL_BW_MASK) >> ZYNQ_CTRL_BW_SHIFT;
+
+	switch (width) {
+	case ZYNQ_DDRCTL_WDTH_16:
+		dt = DEV_X2;
+		break;
+	case ZYNQ_DDRCTL_WDTH_32:
+		dt = DEV_X4;
+		break;
+	default:
+		dt = DEV_UNKNOWN;
+	}
+
+	return dt;
+}
+
+/**
+ * zynq_get_ecc_state - Return the controller ECC enable/disable status.
+ * @base:	DDR memory controller base address.
+ *
+ * Get the ECC enable/disable status of the controller.
+ *
+ * Return: true if enabled, otherwise false.
+ */
+static bool zynq_get_ecc_state(void __iomem *base)
+{
+	enum dev_type dt;
+	u32 ecctype;
+
+	dt = zynq_get_dtype(base);
+	if (dt == DEV_UNKNOWN)
+		return false;
+
+	ecctype = readl(base + ZYNQ_SCRUB_OFST) & ZYNQ_SCRUB_MODE_MASK;
+	if ((ecctype == ZYNQ_SCRUB_MODE_SECDED) && (dt == DEV_X2))
+		return true;
+
+	return false;
+}
+
+/**
+ * zynq_get_memsize - Read the size of the attached memory device.
+ *
+ * Return: the memory size in bytes.
+ */
+static u32 zynq_get_memsize(void)
+{
+	struct sysinfo inf;
+
+	si_meminfo(&inf);
+
+	return inf.totalram * inf.mem_unit;
+}
+
+/**
+ * zynq_get_mtype - Return the controller memory type.
+ * @base:	Zynq ECC status structure.
+ *
+ * Get the EDAC memory type appropriate for the current controller
+ * configuration.
+ *
+ * Return: a memory type enumeration.
+ */
+static enum mem_type zynq_get_mtype(const void __iomem *base)
+{
+	enum mem_type mt;
+	u32 memtype;
+
+	memtype = readl(base + ZYNQ_T_ZQ_OFST);
+
+	if (memtype & ZYNQ_T_ZQ_DDRMODE_MASK)
+		mt = MEM_DDR3;
+	else
+		mt = MEM_DDR2;
+
+	return mt;
+}
+
+/**
+ * zynq_init_csrows - Initialize the csrow data.
+ * @mci:	EDAC memory controller instance.
+ *
+ * Initialize the chip select rows associated with the EDAC memory
+ * controller instance.
+ */
+static void zynq_init_csrows(struct mem_ctl_info *mci)
+{
+	struct zynq_edac_priv *priv = mci->pvt_info;
+	struct csrow_info *csi;
+	struct dimm_info *dimm;
+	u32 size, row;
+	int j;
+
+	for (row = 0; row < mci->nr_csrows; row++) {
+		csi = mci->csrows[row];
+		size = zynq_get_memsize();
+
+		for (j = 0; j < csi->nr_channels; j++) {
+			dimm		= csi->channels[j]->dimm;
+			dimm->edac_mode	= EDAC_SECDED;
+			dimm->mtype	= zynq_get_mtype(priv->baseaddr);
+			dimm->nr_pages	= (size >> PAGE_SHIFT) / csi->nr_channels;
+			dimm->grain	= ZYNQ_EDAC_ERR_GRAIN;
+			dimm->dtype	= zynq_get_dtype(priv->baseaddr);
+		}
+	}
+}
+
+/**
+ * zynq_mc_init - Initialize one driver instance.
+ * @mci:	EDAC memory controller instance.
+ * @pdev:	platform device.
+ *
+ * Perform initialization of the EDAC memory controller instance and
+ * related driver-private data associated with the memory controller the
+ * instance is bound to.
+ */
+static void zynq_mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
+{
+	mci->pdev = &pdev->dev;
+	platform_set_drvdata(pdev, mci);
+
+	/* Initialize controller capabilities and configuration */
+	mci->mtype_cap = MEM_FLAG_DDR3 | MEM_FLAG_DDR2;
+	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
+	mci->scrub_cap = SCRUB_FLAG_HW_SRC;
+	mci->scrub_mode = SCRUB_NONE;
+
+	mci->edac_cap = EDAC_FLAG_SECDED;
+	mci->ctl_name = "zynq_ddr_controller";
+	mci->dev_name = ZYNQ_EDAC_MOD_STRING;
+	mci->mod_name = ZYNQ_EDAC_MOD_VER;
+
+	edac_op_state = EDAC_OPSTATE_POLL;
+	mci->edac_check = zynq_check_errors;
+
+	mci->ctl_page_to_phys = NULL;
+
+	zynq_init_csrows(mci);
+}
+
+/**
+ * zynq_mc_probe - Check controller and bind driver.
+ * @pdev:	platform device.
+ *
+ * Probe a specific controller instance for binding with the driver.
+ *
+ * Return: 0 if the controller instance was successfully bound to the
+ * driver; otherwise, < 0 on error.
+ */
+static int zynq_mc_probe(struct platform_device *pdev)
+{
+	struct edac_mc_layer layers[2];
+	struct zynq_edac_priv *priv;
+	struct mem_ctl_info *mci;
+	void __iomem *baseaddr;
+	int rc;
+
+	baseaddr = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(baseaddr))
+		return PTR_ERR(baseaddr);
+
+	if (!zynq_get_ecc_state(baseaddr)) {
+		edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
+		return -ENXIO;
+	}
+
+	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
+	layers[0].size = ZYNQ_EDAC_NR_CSROWS;
+	layers[0].is_virt_csrow = true;
+	layers[1].type = EDAC_MC_LAYER_CHANNEL;
+	layers[1].size = ZYNQ_EDAC_NR_CHANS;
+	layers[1].is_virt_csrow = false;
+
+	mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers,
+			    sizeof(struct zynq_edac_priv));
+	if (!mci) {
+		edac_printk(KERN_ERR, EDAC_MC,
+			    "Failed memory allocation for mc instance\n");
+		return -ENOMEM;
+	}
+
+	priv = mci->pvt_info;
+	priv->baseaddr = baseaddr;
+
+	zynq_mc_init(mci, pdev);
+
+	rc = edac_mc_add_mc(mci);
+	if (rc) {
+		edac_printk(KERN_ERR, EDAC_MC,
+			    "Failed to register with EDAC core\n");
+		goto free_edac_mc;
+	}
+
+	/*
+	 * Start capturing the correctable and uncorrectable errors. A write of
+	 * 0 starts the counters.
+	 */
+	writel(0x0, baseaddr + ZYNQ_ECC_CTRL_OFST);
+
+	return 0;
+
+free_edac_mc:
+	edac_mc_free(mci);
+
+	return rc;
+}
+
+/**
+ * zynq_mc_remove - Unbind driver from controller.
+ * @pdev:	Platform device.
+ *
+ * Return: Unconditionally 0
+ */
+static int zynq_mc_remove(struct platform_device *pdev)
+{
+	struct mem_ctl_info *mci = platform_get_drvdata(pdev);
+
+	edac_mc_del_mc(&pdev->dev);
+	edac_mc_free(mci);
+
+	return 0;
+}
+
+static const struct of_device_id zynq_edac_match[] = {
+	{ .compatible = "xlnx,zynq-ddrc-a05" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, zynq_edac_match);
+
+static struct platform_driver zynq_edac_mc_driver = {
+	.driver = {
+		   .name = "zynq-edac",
+		   .of_match_table = zynq_edac_match,
+		   },
+	.probe = zynq_mc_probe,
+	.remove = zynq_mc_remove,
+};
+module_platform_driver(zynq_edac_mc_driver);
+
+MODULE_AUTHOR("Xilinx Inc");
+MODULE_DESCRIPTION("Zynq DDR ECC driver");
+MODULE_LICENSE("GPL v2");
-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:12:59 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:59 +0300
Subject: [PATCH v5 14/20] EDAC/mc: Add generic unique MC index allocation procedure
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-15-fancer.lancer@gmail.com>

Currently the EDAC subsystem relies on the low-level device drivers to
select an unique index for each memory controller available in the system.
Here are the already implemented approaches:
1. Fixed zero id. The vast majority of the drivers expect to have a single
memory controller in the system.
2. Calculate based on a platform-specific way (Pre-defined devices order,
PCIe-bus address, Numa node ID + PCIe-function number, etc).
3. Use platform_device->id.
4. Use custom ACPI/OF property value.
5. Use locally maintained static MC counter.

Create a generic method of the MC index allocation which could be utilized
for the case 5 (it doesn't imply any strict memory controller order) and
which would prevent the new MC EDAC drivers re-implementing the approaches
3 and 4. Moreover it will be useful for the cases when a platform is
equipped with memory-controllers of different types [1] and which are
probed by different drivers [2].

[1] Link: https://lore.kernel.org/all/9dc2a947-d2ab-4f00-8ed3-d2499cb6fdfd at BN1BFFO11FD002.protection.gbl/
[2] Link: https://lore.kernel.org/linux-edac/BY5PR12MB4258CB67B70D71F107EC1E9DDB3E9 at BY5PR12MB4258.namprd12.prod.outlook.com

The suggested implementation is based on the IDA kernel API and implies
the next semantics:
1. If a particular MC index is specified it will be registered in the
IDR pool unless the specified ID has already been reserved.
2. If a special MC index is specified (EDAC_AUTO_MC_NUM) the EDAC
core will check whether there is a "mcID" alias is defined in the device
tree and use the ID from there if it's found.
3. Otherwise a next free index will be allocated and assigned to the
registered memory controller.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>

---

Note the approach implemented here has been partly ported from the SPI
core driver using IDA to track/allocate SPI bus numbers.
Link: https://elixir.bootlin.com/linux/latest/source/drivers/spi/spi.c#L2957
---
 drivers/edac/edac_mc.c | 89 +++++++++++++++++++++++++++++++++++++++---
 drivers/edac/edac_mc.h |  4 ++
 2 files changed, 87 insertions(+), 6 deletions(-)

diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index c0b36349999f..2144e0615679 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -29,6 +29,9 @@
 #include <linux/edac.h>
 #include <linux/bitops.h>
 #include <linux/uaccess.h>
+#include <linux/idr.h>
+#include <linux/of.h>
+
 #include <asm/page.h>
 #include "edac_mc.h"
 #include "edac_module.h"
@@ -46,6 +49,7 @@ EXPORT_SYMBOL_GPL(edac_op_state);
 /* lock to memory controller's control array */
 static DEFINE_MUTEX(mem_ctls_mutex);
 static LIST_HEAD(mc_devices);
+static DEFINE_IDR(mc_idr);
 
 /*
  * Used to lock EDAC MC to just one module, avoiding two drivers e. g.
@@ -494,7 +498,64 @@ void edac_mc_reset_delay_period(unsigned long value)
 	mutex_unlock(&mem_ctls_mutex);
 }
 
+/**
+ * edac_mc_alloc_id() - Allocate unique Memory Controller identifier
+ *
+ * @mci: pointer to the mci structure to allocate ID for
+ *
+ * Use edac_mc_free_id() to coherently free the MC identifier.
+ *
+ * .. note::
+ *	locking model: must be called with the mem_ctls_mutex lock held
+ *
+ * Returns:
+ *	0 on Success, or an error code on failure
+ */
+static int edac_mc_alloc_id(struct mem_ctl_info *mci)
+{
+	struct device_node *np = dev_of_node(mci->pdev);
+	int ret, min, max;
+
+	if (mci->mc_idx == EDAC_AUTO_MC_NUM) {
+		ret = of_alias_get_id(np, "mc");
+		if (ret >= 0) {
+			min = ret;
+			max = ret + 1;
+		} else {
+			min = of_alias_get_highest_id("mc");
+			if (min >= 0)
+				min++;
+			else
+				min = 0;
+
+			max = 0;
+		}
+	} else {
+		min = mci->mc_idx;
+		max = mci->mc_idx + 1;
+	}
+
+	ret = idr_alloc(&mc_idr, mci, min, max, GFP_KERNEL);
+	if (ret < 0)
+		return ret == -ENOSPC ? -EBUSY : ret;
+
+	mci->mc_idx = ret;
+
+	return 0;
+}
 
+/**
+ * edac_mc_free_id() - Free Memory Controller identifier
+ *
+ * @mci: pointer to the mci structure to free ID from
+ *
+ * .. note::
+ *	locking model: must be called with the mem_ctls_mutex lock held
+ */
+static void edac_mc_free_id(struct mem_ctl_info *mci)
+{
+	idr_remove(&mc_idr, mci->mc_idx);
+}
 
 /**
  * edac_mc_init_labels() - Initialize DIMM labels
@@ -613,7 +674,8 @@ EXPORT_SYMBOL_GPL(edac_get_owner);
 int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
 			       const struct attribute_group **groups)
 {
-	int ret = -EINVAL;
+	int ret;
+
 	edac_dbg(0, "\n");
 
 #ifdef CONFIG_EDAC_DEBUG
@@ -650,20 +712,30 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
 		goto fail0;
 	}
 
+	ret = edac_mc_alloc_id(mci);
+	if (ret) {
+		edac_printk(KERN_ERR, EDAC_MC, "failed to allocate MC idx %u\n",
+			    mci->mc_idx);
+		goto fail0;
+	}
+
 	edac_mc_init_labels(mci);
 
-	if (add_mc_to_global_list(mci))
-		goto fail0;
+	if (add_mc_to_global_list(mci)) {
+		ret = -EINVAL;
+		goto fail1;
+	}
 
 	/* set load time so that error rate can be tracked */
 	mci->start_time = jiffies;
 
 	mci->bus = edac_get_sysfs_subsys();
 
-	if (edac_create_sysfs_mci_device(mci, groups)) {
+	ret = edac_create_sysfs_mci_device(mci, groups);
+	if (ret) {
 		edac_mc_printk(mci, KERN_WARNING,
 			"failed to create sysfs device\n");
-		goto fail1;
+		goto fail2;
 	}
 
 	if (mci->edac_check) {
@@ -687,9 +759,12 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
 	mutex_unlock(&mem_ctls_mutex);
 	return 0;
 
-fail1:
+fail2:
 	del_mc_from_global_list(mci);
 
+fail1:
+	edac_mc_free_id(mci);
+
 fail0:
 	mutex_unlock(&mem_ctls_mutex);
 	return ret;
@@ -717,6 +792,8 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev)
 	if (del_mc_from_global_list(mci))
 		edac_mc_owner = NULL;
 
+	edac_mc_free_id(mci);
+
 	mutex_unlock(&mem_ctls_mutex);
 
 	if (mci->edac_check)
diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h
index 881b00eadf7a..4b6676235b1b 100644
--- a/drivers/edac/edac_mc.h
+++ b/drivers/edac/edac_mc.h
@@ -23,6 +23,7 @@
 #define _EDAC_MC_H_
 
 #include <linux/kernel.h>
+#include <linux/limits.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
@@ -37,6 +38,9 @@
 #include <linux/workqueue.h>
 #include <linux/edac.h>
 
+/* Generate MC identifier automatically */
+#define EDAC_AUTO_MC_NUM	UINT_MAX
+
 #if PAGE_SHIFT < 20
 #define PAGES_TO_MiB(pages)	((pages) >> (20 - PAGE_SHIFT))
 #define MiB_TO_PAGES(mb)	((mb) << (20 - PAGE_SHIFT))
-- 
2.43.0



From mripard at kernel.org  Thu Feb 22 10:13:48 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:48 +0100
Subject: [PATCH v7 02/36] drm/tests: helpers: Add atomic helpers
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-2-8f4af575fce2@kernel.org>

The mock device we were creating was missing any of the driver-wide
helpers. That was fine before since we weren't testing the atomic state
path, but we're going to start, so let's use the default
implementations.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_kunit_helpers.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index ca4f8e4c5d5d..4fb11b938bc1 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_kunit_helpers.h>
 #include <drm/drm_managed.h>
@@ -14,6 +15,8 @@
 #define KUNIT_DEVICE_NAME	"drm-kunit-mock-device"
 
 static const struct drm_mode_config_funcs drm_mode_config_funcs = {
+	.atomic_check	= drm_atomic_helper_check,
+	.atomic_commit	= drm_atomic_helper_commit,
 };
 
 /**

-- 
2.43.2



From fancer.lancer at gmail.com  Thu Feb 22 10:12:51 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:51 +0300
Subject: [PATCH v5 06/20] EDAC/synopsys: Fix misleading IRQ self-cleared quirk flag
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-7-fancer.lancer@gmail.com>

The DDR_ECC_INTR_SELF_CLEAR quirk flag was initially added in the commit
f7824ded4149 ("EDAC/synopsys: Add support for version 3 of the Synopsys
EDAC DDR") in order to distinguish the ZynqMP DDRC (based on DW uMCTL2
DDRC v2.40a) and the announced in that commit Synopsys DDR controller
v3.80a. The selected name is misleading for the next reasons:

1. None of the Synopsys DW uMCTL2 DDR IP-core has the UE/CE IRQs
auto or self cleared. The IRQ signals (ecc_corrected_err_intr and
ecc_uncorrected_err_intr) are cleared together with the rest of the ECC
error data by means of writing 1's to the respective ECCCLR bits. It
worked like that in DW uMCTL2 DDRC v2.x IP-core and it's still true for
the modern DW uMCTL2 DDRC v3.x.

2. The IRQ-related registers accessed unless the denoted quirk is
specified are actually Xilinx Zynq-specific. None of the Synopsys DW uMCTL
DDRC IP-core have any registers at the offsets 0x20200/0x20208/0x2020C.
The most modern DW uMCTL2 DDRC v3.91a IP-core available has CSRs space end
at the 0x43dc offset. The older IP-cores have even smaller registers
space.

3. What was actually introduced in the DW uMCTL2 DDRC v3.10 by Synopsys is
the IRQ enable flags which older DW uMCTL2 DDRC IP-core didn't have. They
were added to the ECCCLR register (the CSR was also renamed to ECCCTL in
the v3.10 IP-core HW databook). So since then there have been no point in
having a vendor-specific IRQs masking solution like described in 2. and
the IRQ signal can be now shared even for the native DW uMCTL2 DDR
controllers.

So let's harmonize the quirked IRQs code based on the statements above:
rename the DDR_ECC_INTR_SELF_CLEAR quirk flag to SYNPS_ZYNQMP_IRQ_REGS
thus indicating the ZynqMP-specific IRQ CSRs; add the new quirk flag to
the ZynqMP platform data; drop the misleading comments about the
auto-cleared ue/ce flags; add a comment about the new IRQ enable flags
added in v3.10 IP-core.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>

---

Changelog v4:
- This is a new patch detached from
  [PATCH v3 01/17] EDAC/synopsys: Fix native uMCTL2 IRQs handling procedure
---
 drivers/edac/synopsys_edac.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index fbaf3d9ad517..9f79f14e57b2 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -88,7 +88,7 @@
 /* DDR ECC Quirks */
 #define DDR_ECC_INTR_SUPPORT		BIT(0)
 #define DDR_ECC_DATA_POISON_SUPPORT	BIT(1)
-#define DDR_ECC_INTR_SELF_CLEAR		BIT(2)
+#define SYNPS_ZYNQMP_IRQ_REGS		BIT(2)
 
 /* ZynqMP Enhanced DDR memory controller registers that are relevant to ECC */
 /* ECC Configuration Registers */
@@ -526,7 +526,7 @@ static void enable_intr(struct synps_edac_priv *priv)
 	unsigned long flags;
 
 	/* Enable UE/CE Interrupts */
-	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
+	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) {
 		writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
 		       priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
 
@@ -535,6 +535,10 @@ static void enable_intr(struct synps_edac_priv *priv)
 
 	spin_lock_irqsave(&priv->reglock, flags);
 
+	/*
+	 * IRQs Enable/Disable flags have been available since v3.10a.
+	 * This is noop for the older controllers.
+	 */
 	writel(DDR_UE_MASK | DDR_CE_MASK,
 	       priv->baseaddr + ECC_CLR_OFST);
 
@@ -546,7 +550,7 @@ static void disable_intr(struct synps_edac_priv *priv)
 	unsigned long flags;
 
 	/* Disable UE/CE Interrupts */
-	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
+	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) {
 		writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
 		       priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
 
@@ -577,11 +581,7 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
 	priv = mci->pvt_info;
 	p_data = priv->p_data;
 
-	/*
-	 * v3.0 of the controller has the ce/ue bits cleared automatically,
-	 * so this condition does not apply.
-	 */
-	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
+	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) {
 		regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
 		regval &= (DDR_QOSCE_MASK | DDR_QOSUE_MASK);
 		if (!(regval & ECC_CE_UE_INTR_MASK))
@@ -598,8 +598,8 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
 
 	edac_dbg(3, "Total error count CE %d UE %d\n",
 		 priv->ce_cnt, priv->ue_cnt);
-	/* v3.0 of the controller does not have this register */
-	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
+
+	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS)
 		writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
 
 	return IRQ_HANDLED;
@@ -913,7 +913,7 @@ static const struct synps_platform_data zynqmp_edac_def = {
 	.get_mtype	= zynqmp_get_mtype,
 	.get_dtype	= zynqmp_get_dtype,
 	.get_ecc_state	= zynqmp_get_ecc_state,
-	.quirks         = (DDR_ECC_INTR_SUPPORT
+	.quirks         = (DDR_ECC_INTR_SUPPORT | SYNPS_ZYNQMP_IRQ_REGS
 #ifdef CONFIG_EDAC_DEBUG
 			  | DDR_ECC_DATA_POISON_SUPPORT
 #endif
@@ -925,7 +925,7 @@ static const struct synps_platform_data synopsys_edac_def = {
 	.get_mtype	= zynqmp_get_mtype,
 	.get_dtype	= zynqmp_get_dtype,
 	.get_ecc_state	= zynqmp_get_ecc_state,
-	.quirks         = (DDR_ECC_INTR_SUPPORT | DDR_ECC_INTR_SELF_CLEAR
+	.quirks         = (DDR_ECC_INTR_SUPPORT
 #ifdef CONFIG_EDAC_DEBUG
 			  | DDR_ECC_DATA_POISON_SUPPORT
 #endif
-- 
2.43.0



From mripard at kernel.org  Thu Feb 22 10:13:47 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:47 +0100
Subject: [PATCH v7 01/36] drm/tests: helpers: Include missing drm_drv
 header
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-1-8f4af575fce2@kernel.org>

We have a few functions declared in our kunit helpers header, some of
them dereferencing the struct drm_driver.

However, we don't include the drm_drv.h header file defining that
structure, leading to compilation errors if we don't include both
headers.

Fixes: d98780310719 ("drm/tests: helpers: Allow to pass a custom drm_driver")
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 include/drm/drm_kunit_helpers.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
index ba483c87f0e7..3ae19892229d 100644
--- a/include/drm/drm_kunit_helpers.h
+++ b/include/drm/drm_kunit_helpers.h
@@ -3,6 +3,8 @@
 #ifndef DRM_KUNIT_HELPERS_H_
 #define DRM_KUNIT_HELPERS_H_
 
+#include <drm/drm_drv.h>
+
 #include <linux/device.h>
 
 #include <kunit/test.h>

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:13:50 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:50 +0100
Subject: [PATCH v7 04/36] drm/tests: Add helper to create mock crtc
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-4-8f4af575fce2@kernel.org>

We're going to need a full-blown, functional, KMS device to test more
components of the atomic modesetting infrastructure.

Let's add a new helper to create a dumb, mocked, CRTC. By default it
will create a CRTC relying only on the default helpers, but drivers are
free to deviate from that.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_kunit_helpers.c | 62 +++++++++++++++++++++++++++++++
 include/drm/drm_kunit_helpers.h           | 10 +++++
 2 files changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index 32dc8354641a..d5317d13d3fc 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -249,5 +249,67 @@ drm_kunit_helper_create_primary_plane(struct kunit *test,
 }
 EXPORT_SYMBOL_GPL(drm_kunit_helper_create_primary_plane);
 
+static const struct drm_crtc_helper_funcs default_crtc_helper_funcs = {
+};
+
+static const struct drm_crtc_funcs default_crtc_funcs = {
+	.atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.reset                  = drm_atomic_helper_crtc_reset,
+};
+
+/**
+ * drm_kunit_helper_create_crtc - Creates a mock CRTC for a KUnit test
+ * @test: The test context object
+ * @drm: The device to alloc the plane for
+ * @primary: Primary plane for CRTC
+ * @cursor: Cursor plane for CRTC. Optional.
+ * @funcs: Callbacks for the new plane. Optional.
+ * @helper_funcs: Helpers callbacks for the new plane. Optional.
+ *
+ * This allocates and initializes a mock struct &drm_crtc meant to be
+ * part of a mock device for a KUnit test.
+ *
+ * Resources will be cleaned up automatically.
+ *
+ * @funcs will default to the default helpers implementations.
+ * @helper_funcs will default to an empty implementation.
+ *
+ * Returns:
+ * A pointer to the new CRTC, or an ERR_PTR() otherwise.
+ */
+struct drm_crtc *
+drm_kunit_helper_create_crtc(struct kunit *test,
+			     struct drm_device *drm,
+			     struct drm_plane *primary,
+			     struct drm_plane *cursor,
+			     const struct drm_crtc_funcs *funcs,
+			     const struct drm_crtc_helper_funcs *helper_funcs)
+{
+	struct drm_crtc *crtc;
+	int ret;
+
+	if (!funcs)
+		funcs = &default_crtc_funcs;
+
+	if (!helper_funcs)
+		helper_funcs = &default_crtc_helper_funcs;
+
+	crtc = drmm_kzalloc(drm, sizeof(*crtc), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, crtc);
+
+	ret = drmm_crtc_init_with_planes(drm, crtc,
+					 primary,
+					 cursor,
+					 funcs,
+					 NULL);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	drm_crtc_helper_add(crtc, helper_funcs);
+
+	return crtc;
+}
+EXPORT_SYMBOL_GPL(drm_kunit_helper_create_crtc);
+
 MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");
 MODULE_LICENSE("GPL");
diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
index 38667d624aa8..6e99627edf45 100644
--- a/include/drm/drm_kunit_helpers.h
+++ b/include/drm/drm_kunit_helpers.h
@@ -9,6 +9,8 @@
 
 #include <kunit/test.h>
 
+struct drm_crtc_funcs;
+struct drm_crtc_helper_funcs;
 struct drm_device;
 struct drm_plane_funcs;
 struct drm_plane_helper_funcs;
@@ -110,4 +112,12 @@ drm_kunit_helper_create_primary_plane(struct kunit *test,
 				      unsigned int num_formats,
 				      const uint64_t *modifiers);
 
+struct drm_crtc *
+drm_kunit_helper_create_crtc(struct kunit *test,
+			     struct drm_device *drm,
+			     struct drm_plane *primary,
+			     struct drm_plane *cursor,
+			     const struct drm_crtc_funcs *funcs,
+			     const struct drm_crtc_helper_funcs *helper_funcs);
+
 #endif // DRM_KUNIT_HELPERS_H_

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:13:58 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:58 +0100
Subject: [PATCH v7 12/36] drm/tests: Add output formats tests
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-12-8f4af575fce2@kernel.org>

Now that we track the HDMI output format as part of the connector state,
let's add a few tests to make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 32 +++++++
 drivers/gpu/drm/tests/drm_connector_test.c         | 99 +++++++++++++++++++++-
 2 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index a129ea5f014c..1c3dd8a98fb0 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -347,6 +347,15 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
+	/*
+	 * TODO: We should have tests to check that a change in the
+	 * format triggers a CRTC mode change just like we do for the
+	 * RGB Quantization and BPC.
+	 *
+	 * However, we don't have any way to control which format gets
+	 * picked up aside from changing the BPC or mode which would
+	 * already trigger a mode change.
+	 */
 	{ }
 };
 
@@ -427,10 +436,33 @@ static void drm_test_check_bpc_12_value(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
 }
 
+/*
+ * Test that the value of the output format property out of reset is set
+ * to RGB, even if the driver supports more than that.
+ */
+static void drm_test_check_format_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB) |
+						     BIT(HDMI_COLORSPACE_YUV422) |
+						     BIT(HDMI_COLORSPACE_YUV444),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
 	KUNIT_CASE(drm_test_check_bpc_8_value),
 	KUNIT_CASE(drm_test_check_bpc_10_value),
 	KUNIT_CASE(drm_test_check_bpc_12_value),
+	KUNIT_CASE(drm_test_check_format_value),
 	{ }
 };
 
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index a9a57cb23235..5bff67fbed87 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -348,6 +348,42 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
 }
 
+/*
+ * Test that the registration of an HDMI connector with no supported
+ * format fails.
+ */
+static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       0,
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector not listing RGB as a
+ * supported format fails.
+ */
+static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_YUV422),
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
 /*
  * Test that the registration of an HDMI connector with an HDMI
  * connector type succeeds.
@@ -433,6 +469,8 @@ static struct kunit_case drmm_connector_hdmi_init_tests[] = {
 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12),
 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid),
 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null),
+	KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty),
+	KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb),
 	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
 			 drm_connector_hdmi_init_type_valid_gen_params),
@@ -510,10 +548,69 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
 	.test_cases = drm_get_tv_mode_from_name_tests,
 };
 
+struct drm_hdmi_connector_get_output_format_name_test {
+	unsigned int kind;
+	const char *expected_name;
+};
+
+#define OUTPUT_FORMAT_TEST(_kind, _name)	\
+	{					\
+		.kind = _kind,			\
+		.expected_name = _name,		\
+	}
+
+static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test)
+{
+	const struct drm_hdmi_connector_get_output_format_name_test *params =
+		test->param_value;
+
+	KUNIT_EXPECT_STREQ(test,
+			   drm_hdmi_connector_get_output_format_name(params->kind),
+			   params->expected_name);
+}
+
+static const
+struct drm_hdmi_connector_get_output_format_name_test
+drm_hdmi_connector_get_output_format_name_valid_tests[] = {
+	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"),
+	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"),
+	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"),
+	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"),
+};
+
+static void
+drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t,
+						     char *desc)
+{
+	sprintf(desc, "%s", t->expected_name);
+}
+
+KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid,
+		  drm_hdmi_connector_get_output_format_name_valid_tests,
+		  drm_hdmi_connector_get_output_format_name_valid_desc);
+
+static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test)
+{
+	KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4));
+};
+
+static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = {
+	KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name,
+			 drm_hdmi_connector_get_output_format_name_valid_gen_params),
+	KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid),
+	{ }
+};
+
+static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = {
+	.name = "drm_hdmi_connector_get_output_format_name",
+	.test_cases = drm_hdmi_connector_get_output_format_name_tests,
+};
+
 kunit_test_suites(
 	&drmm_connector_hdmi_init_test_suite,
 	&drmm_connector_init_test_suite,
-	&drm_get_tv_mode_from_name_test_suite
+	&drm_get_tv_mode_from_name_test_suite,
+	&drm_hdmi_connector_get_output_format_name_test_suite
 );
 
 MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:01 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:01 +0100
Subject: [PATCH v7 15/36] drm/connector: hdmi: Calculate TMDS character
 rate
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-15-8f4af575fce2@kernel.org>

Most HDMI drivers have some code to calculate the TMDS character rate,
usually to adjust an internal clock to match what the mode requires.

Since the TMDS character rates mostly depends on the resolution, whether
we need to repeat pixels or not, the bpc count and the format, we can
now derive it from the HDMI connector state that stores all those infos
and remove the duplication from drivers.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic.c                       |  1 +
 drivers/gpu/drm/drm_atomic_state_helper.c          | 66 ++++++++++++++++++++++
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  3 +
 include/drm/drm_connector.h                        |  5 ++
 4 files changed, 75 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 8730137baa86..26f9e525c0a0 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1148,6 +1148,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 		drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
 		drm_printf(p, "\toutput_format=%s\n",
 			   drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
+		drm_printf(p, "\ttmds_char_rate=%llu\n", state->hdmi.tmds_char_rate);
 	}
 
 	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index ae99765c45de..63a96c691460 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -640,6 +640,63 @@ int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
 
+static const struct drm_display_mode *
+connector_state_get_mode(const struct drm_connector_state *conn_state)
+{
+	struct drm_atomic_state *state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+
+	state = conn_state->state;
+	if (!state)
+		return NULL;
+
+	crtc = conn_state->crtc;
+	if (!crtc)
+		return NULL;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	if (!crtc_state)
+		return NULL;
+
+	return &crtc_state->mode;
+}
+
+static enum drm_mode_status
+hdmi_clock_valid(const struct drm_connector *connector,
+		 const struct drm_display_mode *mode,
+		 unsigned long long clock)
+{
+	const struct drm_display_info *info = &connector->display_info;
+
+	if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static int
+hdmi_compute_clock(const struct drm_connector *connector,
+		   struct drm_connector_state *state,
+		   const struct drm_display_mode *mode,
+		   unsigned int bpc, enum hdmi_colorspace fmt)
+{
+	enum drm_mode_status status;
+	unsigned long long clock;
+
+	clock = drm_connector_hdmi_compute_mode_clock(mode, bpc, fmt);
+	if (!clock)
+		return -EINVAL;
+
+	status = hdmi_clock_valid(connector, mode, clock);
+	if (status != MODE_OK)
+		return -EINVAL;
+
+	state->hdmi.tmds_char_rate = clock;
+
+	return 0;
+}
+
 /**
  * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
  * @connector: DRM Connector
@@ -659,6 +716,15 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 		drm_atomic_get_old_connector_state(state, connector);
 	struct drm_connector_state *new_state =
 		drm_atomic_get_new_connector_state(state, connector);
+	const struct drm_display_mode *mode =
+		connector_state_get_mode(new_state);
+	int ret;
+
+	ret = hdmi_compute_clock(connector, new_state, mode,
+				 new_state->hdmi.output_bpc,
+				 new_state->hdmi.output_format);
+	if (ret)
+		return ret;
 
 	if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
 	    old_state->hdmi.output_format != new_state->hdmi.output_format) {
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 1c3dd8a98fb0..f2acbd4c216c 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -70,6 +70,9 @@ static int light_up_connector(struct kunit *test,
 	conn_state = drm_atomic_get_connector_state(state, connector);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 
+	conn_state->hdmi.output_bpc = connector->max_bpc;
+	conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB;
+
 	ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index a859ad7ee04b..e3917ea93986 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1050,6 +1050,11 @@ struct drm_connector_state {
 		 * @output_format: Pixel format to output in.
 		 */
 		enum hdmi_colorspace output_format;
+
+		/**
+		 * @tmds_char_rate: TMDS Character Rate, in Hz.
+		 */
+		unsigned long long tmds_char_rate;
 	} hdmi;
 };
 

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:13:56 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:56 +0100
Subject: [PATCH v7 10/36] drm/tests: Add output bpc tests
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-10-8f4af575fce2@kernel.org>

Now that we're tracking the output bpc count in the connector state,
let's add a few tests to make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/Makefile                     |   1 +
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 436 +++++++++++++++++++++
 drivers/gpu/drm/tests/drm_connector_test.c         | 140 +++++++
 drivers/gpu/drm/tests/drm_kunit_edid.h             | 106 +++++
 4 files changed, 683 insertions(+)

diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile
index d6183b3d7688..b29ddfd90596 100644
--- a/drivers/gpu/drm/tests/Makefile
+++ b/drivers/gpu/drm/tests/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST_HELPERS) += \
 	drm_kunit_helpers.o
 
 obj-$(CONFIG_DRM_KUNIT_TEST) += \
+	drm_atomic_state_helper_test.o \
 	drm_buddy_test.o \
 	drm_cmdline_parser_test.o \
 	drm_connector_test.o \
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
new file mode 100644
index 000000000000..5d1a1dbff433
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Kunit test for drm_atomic_state_helper functions
+ */
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_atomic_uapi.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_kunit_helpers.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_probe_helper.h>
+
+#include <drm/drm_print.h>
+#include "../drm_crtc_internal.h"
+
+#include <kunit/test.h>
+
+#include "drm_kunit_edid.h"
+
+struct drm_atomic_helper_connector_hdmi_priv {
+	struct drm_device drm;
+	struct drm_plane *plane;
+	struct drm_crtc *crtc;
+	struct drm_encoder encoder;
+	struct drm_connector connector;
+
+	const char *current_edid;
+	size_t current_edid_len;
+};
+
+#define connector_to_priv(c) \
+	container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector)
+
+static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector)
+{
+	struct drm_device *drm = connector->dev;
+	struct drm_display_mode *mode, *preferred;
+
+	mutex_lock(&drm->mode_config.mutex);
+	preferred = list_first_entry(&connector->modes, struct drm_display_mode, head);
+	list_for_each_entry(mode, &connector->modes, head)
+		if (mode->type & DRM_MODE_TYPE_PREFERRED)
+			preferred = mode;
+	mutex_unlock(&drm->mode_config.mutex);
+
+	return preferred;
+}
+
+static int light_up_connector(struct kunit *test,
+			      struct drm_device *drm,
+			      struct drm_crtc *crtc,
+			      struct drm_connector *connector,
+			      struct drm_display_mode *mode,
+			      struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_atomic_state *state;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc_state *crtc_state;
+	int ret;
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	conn_state = drm_atomic_get_connector_state(state, connector);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+	ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+	ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	crtc_state->enable = true;
+	crtc_state->active = true;
+
+	ret = drm_atomic_commit(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	return 0;
+}
+
+static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
+			      const char *edid, size_t edid_len)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv =
+		connector_to_priv(connector);
+	struct drm_device *drm = connector->dev;
+	int ret;
+
+	priv->current_edid = edid;
+	priv->current_edid_len = edid_len;
+
+	mutex_lock(&drm->mode_config.mutex);
+	ret = connector->funcs->fill_modes(connector, 4096, 4096);
+	mutex_unlock(&drm->mode_config.mutex);
+	KUNIT_ASSERT_GT(test, ret, 0);
+
+	return 0;
+}
+
+static int dummy_connector_get_modes(struct drm_connector *connector)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv =
+		connector_to_priv(connector);
+	const struct drm_edid *edid;
+	unsigned int num_modes;
+
+	edid = drm_edid_alloc(priv->current_edid, priv->current_edid_len);
+	if (!edid)
+		return -EINVAL;
+
+	drm_edid_connector_update(connector, edid);
+	num_modes = drm_edid_connector_add_modes(connector);
+
+	drm_edid_free(edid);
+
+	return num_modes;
+}
+
+static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = {
+	.atomic_check	= drm_atomic_helper_connector_hdmi_check,
+	.get_modes	= dummy_connector_get_modes,
+};
+
+static void dummy_hdmi_connector_reset(struct drm_connector *connector)
+{
+	drm_atomic_helper_connector_reset(connector);
+	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
+}
+
+static const struct drm_connector_funcs dummy_connector_funcs = {
+	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
+	.fill_modes		= drm_helper_probe_single_connector_modes,
+	.reset			= dummy_hdmi_connector_reset,
+};
+
+static
+struct drm_atomic_helper_connector_hdmi_priv *
+drm_atomic_helper_connector_hdmi_init(struct kunit *test,
+				      unsigned int max_bpc)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector *conn;
+	struct drm_encoder *enc;
+	struct drm_device *drm;
+	struct device *dev;
+	int ret;
+
+	dev = drm_kunit_helper_alloc_device(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+	priv = drm_kunit_helper_alloc_drm_device(test, dev,
+						 struct drm_atomic_helper_connector_hdmi_priv, drm,
+						 DRIVER_MODESET | DRIVER_ATOMIC);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+	test->priv = priv;
+
+	drm = &priv->drm;
+	priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
+							    NULL,
+							    NULL,
+							    NULL, 0,
+							    NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->plane);
+
+	priv->crtc = drm_kunit_helper_create_crtc(test, drm,
+						  priv->plane, NULL,
+						  NULL,
+						  NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->crtc);
+
+	enc = &priv->encoder;
+	ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	enc->possible_crtcs = drm_crtc_mask(priv->crtc);
+
+	conn = &priv->connector;
+	ret = drmm_connector_hdmi_init(drm, conn,
+				       &dummy_connector_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       NULL,
+				       max_bpc);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	drm_connector_helper_add(conn, &dummy_connector_helper_funcs);
+	drm_connector_attach_encoder(conn, enc);
+
+	drm_mode_config_reset(drm);
+
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	return priv;
+}
+
+/*
+ * Test that if we change the maximum bpc property to a different value,
+ * we trigger a mode change on the connector's CRTC, which will in turn
+ * disable/enable the connector.
+ */
+static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector_state *new_conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	conn = &priv->connector;
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	new_conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state->hdmi.output_bpc = 8;
+
+	KUNIT_ASSERT_NE(test,
+			old_conn_state->hdmi.output_bpc,
+			new_conn_state->hdmi.output_bpc);
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	KUNIT_ASSERT_NE(test,
+			old_conn_state->hdmi.output_bpc,
+			new_conn_state->hdmi.output_bpc);
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+	KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
+}
+
+/*
+ * Test that if we set the output bpc property to the same value, we
+ * don't trigger a mode change on the connector's CRTC and leave the
+ * connector unaffected.
+ */
+static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector_state *new_conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	conn = &priv->connector;
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	new_conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	KUNIT_ASSERT_EQ(test,
+			new_conn_state->hdmi.output_bpc,
+			old_conn_state->hdmi.output_bpc);
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	KUNIT_EXPECT_EQ(test,
+			old_conn_state->hdmi.output_bpc,
+			new_conn_state->hdmi.output_bpc);
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
+}
+
+static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
+	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
+	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
+	{ }
+};
+
+static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = {
+	.name		= "drm_atomic_helper_connector_hdmi_check",
+	.test_cases	= drm_atomic_helper_connector_hdmi_check_tests,
+};
+
+/*
+ * Test that if the connector was initialised with a maximum bpc of 8,
+ * the value of the max_bpc and max_requested_bpc properties out of
+ * reset are also set to 8, and output_bpc is set to 0 and will be
+ * filled at atomic_check time.
+ */
+static void drm_test_check_bpc_8_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test, 8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 8);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
+}
+
+/*
+ * Test that if the connector was initialised with a maximum bpc of 10,
+ * the value of the max_bpc and max_requested_bpc properties out of
+ * reset are also set to 10, and output_bpc is set to 0 and will be
+ * filled at atomic_check time.
+ */
+static void drm_test_check_bpc_10_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test, 10);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 10);
+	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 10);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
+}
+
+/*
+ * Test that if the connector was initialised with a maximum bpc of 12,
+ * the value of the max_bpc and max_requested_bpc properties out of
+ * reset are also set to 12, and output_bpc is set to 0 and will be
+ * filled at atomic_check time.
+ */
+static void drm_test_check_bpc_12_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test, 12);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 12);
+	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 12);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
+}
+
+static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
+	KUNIT_CASE(drm_test_check_bpc_8_value),
+	KUNIT_CASE(drm_test_check_bpc_10_value),
+	KUNIT_CASE(drm_test_check_bpc_12_value),
+	{ }
+};
+
+static struct kunit_suite drm_atomic_helper_connector_hdmi_reset_test_suite = {
+	.name		= "drm_atomic_helper_connector_hdmi_reset",
+	.test_cases 	= drm_atomic_helper_connector_hdmi_reset_tests,
+};
+
+kunit_test_suites(
+	&drm_atomic_helper_connector_hdmi_check_test_suite,
+	&drm_atomic_helper_connector_hdmi_reset_test_suite,
+);
+
+MODULE_AUTHOR("Maxime Ripard <mripard at kernel.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index d8d30aea9fdc..20da290abff3 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -12,6 +12,8 @@
 
 #include <kunit/test.h>
 
+#include "../drm_crtc_internal.h"
+
 struct drm_connector_init_priv {
 	struct drm_device drm;
 	struct drm_connector connector;
@@ -206,6 +208,139 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
+/*
+ * Test that the registration of a connector with an invalid maximum bpc
+ * count fails.
+ */
+static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       9);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a null maximum bpc
+ * count fails.
+ */
+static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       0);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a maximum bpc count of
+ * 8 succeeds, registers the max bpc property, but doesn't register the
+ * HDR output metadata one.
+ */
+static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	struct drm_connector *connector = &priv->connector;
+	struct drm_property *prop;
+	uint64_t val;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	prop = connector->max_bpc_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+
+	ret = drm_object_property_get_value(&connector->base, prop, &val);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, val, 8);
+
+	prop = priv->drm.mode_config.hdr_output_metadata_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+/*
+ * Test that the registration of a connector with a maximum bpc count of
+ * 10 succeeds and registers the max bpc and HDR output metadata
+ * properties.
+ */
+static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	struct drm_connector *connector = &priv->connector;
+	struct drm_property *prop;
+	uint64_t val;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       10);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	prop = connector->max_bpc_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+
+	ret = drm_object_property_get_value(&connector->base, prop, &val);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, val, 10);
+
+	prop = priv->drm.mode_config.hdr_output_metadata_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+/*
+ * Test that the registration of a connector with a maximum bpc count of
+ * 12 succeeds and registers the max bpc and HDR output metadata
+ * properties.
+ */
+static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	struct drm_connector *connector = &priv->connector;
+	struct drm_property *prop;
+	uint64_t val;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       &dummy_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       12);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	prop = connector->max_bpc_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+
+	ret = drm_object_property_get_value(&connector->base, prop, &val);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, val, 12);
+
+	prop = priv->drm.mode_config.hdr_output_metadata_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
 /*
  * Test that the registration of an HDMI connector with an HDMI
  * connector type succeeds.
@@ -284,6 +419,11 @@ KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
 
 static struct kunit_case drmm_connector_hdmi_init_tests[] = {
 	KUNIT_CASE(drm_test_connector_hdmi_init_valid),
+	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8),
+	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10),
+	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12),
+	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid),
+	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null),
 	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
 			 drm_connector_hdmi_init_type_valid_gen_params),
diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h
new file mode 100644
index 000000000000..2bba316de064
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_kunit_edid.h
@@ -0,0 +1,106 @@
+#ifndef DRM_KUNIT_EDID_H_
+#define DRM_KUNIT_EDID_H_
+
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92
+ *
+ * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c
+ * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ *   EDID Structure Version & Revision: 1.3
+ *   Vendor & Product Identification:
+ *     Manufacturer: LNX
+ *     Model: 42
+ *     Made in: 2023
+ *   Basic Display Parameters & Features:
+ *     Digital display
+ *     DFP 1.x compatible TMDS
+ *     Maximum image size: 160 cm x 90 cm
+ *     Gamma: 2.20
+ *     Monochrome or grayscale display
+ *     First detailed timing is the preferred timing
+ *   Color Characteristics:
+ *     Red  : 0.0000, 0.0000
+ *     Green: 0.0000, 0.0000
+ *     Blue : 0.0000, 0.0000
+ *     White: 0.0000, 0.0000
+ *   Established Timings I & II:
+ *     DMT 0x04:   640x480    59.940476 Hz   4:3     31.469 kHz     25.175000 MHz
+ *   Standard Timings: none
+ *   Detailed Timing Descriptors:
+ *     DTD 1:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz (1600 mm x 900 mm)
+ *                  Hfront   88 Hsync  44 Hback  148 Hpol P
+ *                  Vfront    4 Vsync   5 Vback   36 Vpol P
+ *     Display Product Name: 'Test EDID'
+ *     Display Range Limits:
+ *       Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ *     Dummy Descriptor:
+ *   Extension blocks: 1
+ * Checksum: 0x92
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ *   Revision: 3
+ *   Underscans IT Video Formats by default
+ *   Native detailed modes: 1
+ *   Colorimetry Data Block:
+ *     sRGB
+ *   Video Data Block:
+ *     VIC  16:  1920x1080   60.000000 Hz  16:9     67.500 kHz    148.500000 MHz
+ *   Video Capability Data Block:
+ *     YCbCr quantization: No Data
+ *     RGB quantization: Selectable (via AVI Q)
+ *     PT scan behavior: No Data
+ *     IT scan behavior: Always Underscanned
+ *     CE scan behavior: Always Underscanned
+ *   Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ *     Source physical address: 1.2.3.4
+ *     Maximum TMDS clock: 200 MHz
+ *     Extended HDMI video details:
+ * Checksum: 0xd0  Unused space in Extension Block: 100 bytes
+ */
+const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {
+  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+  0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+  0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+  0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+  0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81,
+  0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c,
+  0x00, 0x12, 0x34, 0x00, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xd0
+};
+
+#endif // DRM_KUNIT_EDID_H_

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:05 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:05 +0100
Subject: [PATCH v7 19/36] drm/connector: hdmi: Compute bpc and format
 automatically
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-19-8f4af575fce2@kernel.org>

Now that we have all the infrastructure needed, we can add some code
that will, for a given connector state and mode, compute the best output
format and bpc.

The algorithm is equivalent to the one already found in i915 and vc4.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c          | 184 ++++++++++++++++++++-
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  25 ++-
 2 files changed, 197 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 448b4a73d1c8..9f517599f117 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -31,6 +31,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_device.h>
+#include <drm/drm_edid.h>
 #include <drm/drm_framebuffer.h>
 #include <drm/drm_plane.h>
 #include <drm/drm_print.h>
@@ -662,6 +663,96 @@ connector_state_get_mode(const struct drm_connector_state *conn_state)
 	return &crtc_state->mode;
 }
 
+static bool
+sink_supports_format_bpc(const struct drm_connector *connector,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode,
+			 unsigned int format, unsigned int bpc)
+{
+	struct drm_device *dev = connector->dev;
+	u8 vic = drm_match_cea_mode(mode);
+
+	if (vic == 1 && bpc != 8) {
+		drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
+		return false;
+	}
+
+	if (!info->is_hdmi &&
+	    (format != HDMI_COLORSPACE_RGB || bpc != 8)) {
+		drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
+		return false;
+	}
+
+	if (!(connector->hdmi.supported_formats & BIT(format))) {
+		drm_dbg(dev, "%s format unsupported by the connector.\n",
+			drm_hdmi_connector_get_output_format_name(format));
+		return false;
+	}
+
+	switch (format) {
+	case HDMI_COLORSPACE_RGB:
+		drm_dbg(dev, "RGB Format, checking the constraints.\n");
+
+		if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
+			return false;
+
+		if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {
+			drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
+			return false;
+		}
+
+		if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {
+			drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
+			return false;
+		}
+
+		drm_dbg(dev, "RGB format supported in that configuration.\n");
+
+		return true;
+
+	case HDMI_COLORSPACE_YUV422:
+		drm_dbg(dev, "YUV422 format, checking the constraints.\n");
+
+		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
+			drm_dbg(dev, "Sink doesn't support YUV422.\n");
+			return false;
+		}
+
+		if (bpc != 12) {
+			drm_dbg(dev, "YUV422 only supports 12 bpc.\n");
+			return false;
+		}
+
+		drm_dbg(dev, "YUV422 format supported in that configuration.\n");
+
+		return true;
+
+	case HDMI_COLORSPACE_YUV444:
+		drm_dbg(dev, "YUV444 format, checking the constraints.\n");
+
+		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {
+			drm_dbg(dev, "Sink doesn't support YUV444.\n");
+			return false;
+		}
+
+		if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_30)) {
+			drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
+			return false;
+		}
+
+		if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_36)) {
+			drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
+			return false;
+		}
+
+		drm_dbg(dev, "YUV444 format supported in that configuration.\n");
+
+		return true;
+	}
+
+	return false;
+}
+
 static enum drm_mode_status
 hdmi_clock_valid(const struct drm_connector *connector,
 		 const struct drm_display_mode *mode,
@@ -706,6 +797,95 @@ hdmi_compute_clock(const struct drm_connector *connector,
 	return 0;
 }
 
+static bool
+hdmi_try_format_bpc(const struct drm_connector *connector,
+		    struct drm_connector_state *state,
+		    const struct drm_display_mode *mode,
+		    unsigned int bpc, enum hdmi_colorspace fmt)
+{
+	const struct drm_display_info *info = &connector->display_info;
+	struct drm_device *dev = connector->dev;
+	int ret;
+
+	drm_dbg(dev, "Trying %s output format\n",
+		drm_hdmi_connector_get_output_format_name(fmt));
+
+	if (!sink_supports_format_bpc(connector, info, mode, fmt, bpc)) {
+		drm_dbg(dev, "%s output format not supported with %u bpc\n",
+			drm_hdmi_connector_get_output_format_name(fmt), bpc);
+		return false;
+	}
+
+	ret = hdmi_compute_clock(connector, state, mode, bpc, fmt);
+	if (ret) {
+		drm_dbg(dev, "Couldn't compute clock for %s output format and %u bpc\n",
+			drm_hdmi_connector_get_output_format_name(fmt), bpc);
+		return false;
+	}
+
+	drm_dbg(dev, "%s output format supported with %u (TMDS char rate: %llu Hz)\n",
+		drm_hdmi_connector_get_output_format_name(fmt), bpc, state->hdmi.tmds_char_rate);
+
+	return true;
+}
+
+static int
+hdmi_compute_format(const struct drm_connector *connector,
+		    struct drm_connector_state *state,
+		    const struct drm_display_mode *mode,
+		    unsigned int bpc)
+{
+	struct drm_device *dev = connector->dev;
+
+	if (hdmi_try_format_bpc(connector, state, mode, bpc, HDMI_COLORSPACE_RGB)) {
+		state->hdmi.output_format = HDMI_COLORSPACE_RGB;
+		return 0;
+	}
+
+	if (hdmi_try_format_bpc(connector, state, mode, bpc, HDMI_COLORSPACE_YUV422)) {
+		state->hdmi.output_format = HDMI_COLORSPACE_YUV422;
+		return 0;
+	}
+
+	drm_dbg(dev, "Failed. No Format Supported for that bpc count.\n");
+
+	return -EINVAL;
+}
+
+static int
+hdmi_compute_config(const struct drm_connector *connector,
+		    struct drm_connector_state *state,
+		    const struct drm_display_mode *mode)
+{
+	struct drm_device *dev = connector->dev;
+	unsigned int max_bpc = clamp_t(unsigned int,
+				       state->max_bpc,
+				       8, connector->max_bpc);
+	unsigned int bpc;
+	int ret;
+
+	for (bpc = max_bpc; bpc >= 8; bpc -= 2) {
+		drm_dbg(dev, "Trying with a %d bpc output\n", bpc);
+
+		ret = hdmi_compute_format(connector, state, mode, bpc);
+		if (ret)
+			continue;
+
+		state->hdmi.output_bpc = bpc;
+
+		drm_dbg(dev,
+			"Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n",
+			mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
+			state->hdmi.output_bpc,
+			drm_hdmi_connector_get_output_format_name(state->hdmi.output_format),
+			state->hdmi.tmds_char_rate);
+
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 /**
  * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
  * @connector: DRM Connector
@@ -729,9 +909,7 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 		connector_state_get_mode(new_state);
 	int ret;
 
-	ret = hdmi_compute_clock(connector, new_state, mode,
-				 new_state->hdmi.output_bpc,
-				 new_state->hdmi.output_format);
+	ret = hdmi_compute_config(connector, new_state, mode);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index 5a8750153510..f010fde0eb69 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -70,9 +70,6 @@ static int light_up_connector(struct kunit *test,
 	conn_state = drm_atomic_get_connector_state(state, connector);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 
-	conn_state->hdmi.output_bpc = connector->max_bpc;
-	conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB;
-
 	ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
@@ -251,10 +248,15 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
 						     10);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 
-	conn = &priv->connector;
 	preferred = find_preferred_mode(conn);
 	KUNIT_ASSERT_NOT_NULL(test, preferred);
 
@@ -272,11 +274,11 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
 
-	new_conn_state->hdmi.output_bpc = 8;
+	new_conn_state->max_requested_bpc = 8;
 
 	KUNIT_ASSERT_NE(test,
-			old_conn_state->hdmi.output_bpc,
-			new_conn_state->hdmi.output_bpc);
+			old_conn_state->max_requested_bpc,
+			new_conn_state->max_requested_bpc);
 
 	ret = drm_atomic_check_only(state);
 	KUNIT_ASSERT_EQ(test, ret, 0);
@@ -320,10 +322,15 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
 						     10);
 	KUNIT_ASSERT_NOT_NULL(test, priv);
 
+	conn = &priv->connector;
+	ret = set_connector_edid(test, conn,
+				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 
-	conn = &priv->connector;
 	preferred = find_preferred_mode(conn);
 	KUNIT_ASSERT_NOT_NULL(test, preferred);
 
@@ -670,7 +677,7 @@ static void drm_test_check_format_value(struct kunit *test)
 
 	conn = &priv->connector;
 	conn_state = conn->state;
-	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 0);
 }
 
 /*

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:09 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:09 +0100
Subject: [PATCH v7 23/36] drm/connector: hdmi: Add RGB Quantization Range
 to the connector state
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-23-8f4af575fce2@kernel.org>

HDMI controller drivers will need to figure out the RGB range they need
to configure based on a mode and property values. Let's expose that in
the HDMI connector state so drivers can just use that value.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic.c              |  1 +
 drivers/gpu/drm/drm_atomic_state_helper.c | 29 +++++++++++++++++++++++++++++
 include/drm/drm_connector.h               |  6 ++++++
 3 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3e57d98d8418..ec6c6beda5c9 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1147,6 +1147,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
 		drm_printf(p, "\tbroadcast_rgb=%s\n",
 			   drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb));
+		drm_printf(p, "\tis_full_range=%c\n", state->hdmi.is_full_range ? 'y' : 'n');
 		drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
 		drm_printf(p, "\toutput_format=%s\n",
 			   drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 0e8fb653965a..e66272c0d006 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -664,6 +664,33 @@ connector_state_get_mode(const struct drm_connector_state *conn_state)
 	return &crtc_state->mode;
 }
 
+static bool hdmi_is_full_range(const struct drm_connector *connector,
+			       const struct drm_connector_state *state)
+{
+	const struct drm_display_info *display = &connector->display_info;
+	const struct drm_display_mode *mode =
+		connector_state_get_mode(state);
+
+	/*
+	 * The Broadcast RGB property only applies to RGB format, and
+	 * i915 just assumes limited range for YCbCr output, so let's
+	 * just do the same.
+	 */
+	if (state->hdmi.output_format != HDMI_COLORSPACE_RGB)
+		return false;
+
+	if (state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_FULL)
+		return true;
+
+	if (state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED)
+		return false;
+
+	if (!display->is_hdmi)
+		return true;
+
+	return drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL ? true : false;
+}
+
 static bool
 sink_supports_format_bpc(const struct drm_connector *connector,
 			 const struct drm_display_info *info,
@@ -910,6 +937,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 		connector_state_get_mode(new_state);
 	int ret;
 
+	new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state);
+
 	ret = hdmi_compute_config(connector, new_state, mode);
 	if (ret)
 		return ret;
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index bb6b6a36ade3..3eaf4d54364d 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1070,6 +1070,12 @@ struct drm_connector_state {
 		 */
 		enum drm_hdmi_broadcast_rgb broadcast_rgb;
 
+		/**
+		 * @is_full_range: Is the output supposed to use a full
+		 * RGB Quantization Range or not?
+		 */
+		bool is_full_range;
+
 		/**
 		 * @output_bpc: Bits per color channel to output.
 		 */

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:08 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:08 +0100
Subject: [PATCH v7 22/36] drm/tests: Add tests for Broadcast RGB property
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-22-8f4af575fce2@kernel.org>

This had a bunch of kunit tests to make sure our code to handle the
Broadcast RGB property behaves properly.

This requires bringing a bit of infrastructure to create mock HDMI
connectors, with custom EDIDs.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 .../gpu/drm/tests/drm_atomic_state_helper_test.c   | 151 +++++++++++++++++++++
 drivers/gpu/drm/tests/drm_connector_test.c         | 116 ++++++++++++++++
 2 files changed, 267 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
index c0f26422e925..3de15cec2f5f 100644
--- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
@@ -224,6 +224,134 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test,
 	return priv;
 }
 
+/*
+ * Test that if we change the RGB quantization property to a different
+ * value, we trigger a mode change on the connector's CRTC, which will
+ * in turn disable/enable the connector.
+ */
+static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector_state *new_conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	conn = &priv->connector;
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	new_conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+	KUNIT_ASSERT_NE(test,
+			old_conn_state->hdmi.broadcast_rgb,
+			new_conn_state->hdmi.broadcast_rgb);
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+	KUNIT_EXPECT_EQ(test, new_conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_FULL);
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+	KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
+}
+
+/*
+ * Test that if we set the RGB quantization property to the same value,
+ * we don't trigger a mode change on the connector's CRTC and leave the
+ * connector unaffected.
+ */
+static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_modeset_acquire_ctx *ctx;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector_state *new_conn_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_atomic_state *state;
+	struct drm_display_mode *preferred;
+	struct drm_connector *conn;
+	struct drm_device *drm;
+	struct drm_crtc *crtc;
+	int ret;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+	conn = &priv->connector;
+	preferred = find_preferred_mode(conn);
+	KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+	drm = &priv->drm;
+	crtc = priv->crtc;
+	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+	new_conn_state = drm_atomic_get_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state->hdmi.broadcast_rgb = old_conn_state->hdmi.broadcast_rgb;
+
+	ret = drm_atomic_check_only(state);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+	KUNIT_EXPECT_EQ(test,
+			old_conn_state->hdmi.broadcast_rgb,
+			new_conn_state->hdmi.broadcast_rgb);
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
+}
+
 /*
  * Test that if we change the maximum bpc property to a different value,
  * we trigger a mode change on the connector's CRTC, which will in turn
@@ -1059,6 +1187,8 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes
 }
 
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
+	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
+	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
 	KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
 	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback),
 	KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback),
@@ -1090,6 +1220,26 @@ static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = {
 	.test_cases	= drm_atomic_helper_connector_hdmi_check_tests,
 };
 
+/*
+ * Test that the value of the Broadcast RGB property out of reset is set
+ * to auto.
+ */
+static void drm_test_check_broadcast_rgb_value(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+
+	priv = drm_atomic_helper_connector_hdmi_init(test,
+						     BIT(HDMI_COLORSPACE_RGB),
+						     8);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn = &priv->connector;
+	conn_state = conn->state;
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO);
+}
+
 /*
  * Test that if the connector was initialised with a maximum bpc of 8,
  * the value of the max_bpc and max_requested_bpc properties out of
@@ -1207,6 +1357,7 @@ static void drm_test_check_tmds_char_value(struct kunit *test)
 }
 
 static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
+	KUNIT_CASE(drm_test_check_broadcast_rgb_value),
 	KUNIT_CASE(drm_test_check_bpc_8_value),
 	KUNIT_CASE(drm_test_check_bpc_10_value),
 	KUNIT_CASE(drm_test_check_bpc_12_value),
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 732c59a1d4d5..6a3651b08c81 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -564,6 +564,63 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
 	.test_cases = drm_get_tv_mode_from_name_tests,
 };
 
+struct drm_hdmi_connector_get_broadcast_rgb_name_test {
+	unsigned int kind;
+	const char *expected_name;
+};
+
+#define BROADCAST_RGB_TEST(_kind, _name)	\
+	{					\
+		.kind = _kind,			\
+		.expected_name = _name,		\
+	}
+
+static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test)
+{
+	const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params =
+		test->param_value;
+
+	KUNIT_EXPECT_STREQ(test,
+			   drm_hdmi_connector_get_broadcast_rgb_name(params->kind),
+			   params->expected_name);
+}
+
+static const
+struct drm_hdmi_connector_get_broadcast_rgb_name_test
+drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = {
+	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"),
+	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"),
+	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"),
+};
+
+static void
+drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t,
+						     char *desc)
+{
+	sprintf(desc, "%s", t->expected_name);
+}
+
+KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid,
+		  drm_hdmi_connector_get_broadcast_rgb_name_valid_tests,
+		  drm_hdmi_connector_get_broadcast_rgb_name_valid_desc);
+
+static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test)
+{
+	KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3));
+};
+
+static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = {
+	KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name,
+			 drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params),
+	KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid),
+	{ }
+};
+
+static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = {
+	.name = "drm_hdmi_connector_get_broadcast_rgb_name",
+	.test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests,
+};
+
 struct drm_hdmi_connector_get_output_format_name_test {
 	unsigned int kind;
 	const char *expected_name;
@@ -622,6 +679,63 @@ static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite =
 	.test_cases = drm_hdmi_connector_get_output_format_name_tests,
 };
 
+static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	struct drm_connector *connector = &priv->connector;
+	struct drm_property *prop;
+	int ret;
+
+	ret = drmm_connector_init(&priv->drm, connector,
+				  &dummy_funcs,
+				  DRM_MODE_CONNECTOR_HDMIA,
+				  &priv->ddc);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = drm_connector_attach_broadcast_rgb_property(connector);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	prop = connector->broadcast_rgb_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	struct drm_connector *connector = &priv->connector;
+	struct drm_property *prop;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, connector,
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+
+	ret = drm_connector_attach_broadcast_rgb_property(connector);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	prop = connector->broadcast_rgb_property;
+	KUNIT_ASSERT_NOT_NULL(test, prop);
+	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = {
+	KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property),
+	KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector),
+	{ }
+};
+
+static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = {
+	.name = "drm_connector_attach_broadcast_rgb_property",
+	.init = drm_test_connector_init,
+	.test_cases = drm_connector_attach_broadcast_rgb_property_tests,
+};
+
 /*
  * Test that for a given mode, with 8bpc and an RGB output the TMDS
  * character rate is equal to the mode pixel clock.
@@ -945,8 +1059,10 @@ static struct kunit_suite drm_connector_hdmi_compute_mode_clock_test_suite = {
 kunit_test_suites(
 	&drmm_connector_hdmi_init_test_suite,
 	&drmm_connector_init_test_suite,
+	&drm_connector_attach_broadcast_rgb_property_test_suite,
 	&drm_connector_hdmi_compute_mode_clock_test_suite,
 	&drm_get_tv_mode_from_name_test_suite,
+	&drm_hdmi_connector_get_broadcast_rgb_name_test_suite,
 	&drm_hdmi_connector_get_output_format_name_test_suite
 );
 

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:07 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:07 +0100
Subject: [PATCH v7 21/36] drm/connector: hdmi: Add Broadcast RGB property
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-21-8f4af575fce2@kernel.org>

The i915 driver has a property to force the RGB range of an HDMI output.
The vc4 driver then implemented the same property with the same
semantics. KWin has support for it, and a PR for mutter is also there to
support it.

Both drivers implementing the same property with the same semantics,
plus the userspace having support for it, is proof enough that it's
pretty much a de-facto standard now and we can provide helpers for it.

Let's plumb it into the newly created HDMI connector.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 Documentation/gpu/kms-properties.csv      |  1 -
 drivers/gpu/drm/drm_atomic.c              |  2 +
 drivers/gpu/drm/drm_atomic_state_helper.c |  4 +-
 drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
 drivers/gpu/drm/drm_connector.c           | 89 +++++++++++++++++++++++++++++++
 include/drm/drm_connector.h               | 36 +++++++++++++
 6 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv
index 0f9590834829..caef14c532d4 100644
--- a/Documentation/gpu/kms-properties.csv
+++ b/Documentation/gpu/kms-properties.csv
@@ -17,7 +17,6 @@ Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,De
 ,Virtual GPU,?suggested X?,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an X offset for a connector
 ,,?suggested Y?,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an Y offset for a connector
 ,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" }",Connector,TDB
-i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normally in the range 0..1.0 are remapped to the range 16/255..235/255."
 ,,?audio?,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD
 ,SDVO-TV,?mode?,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD
 ,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 26f9e525c0a0..3e57d98d8418 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1145,6 +1145,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 
 	if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
 	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
+		drm_printf(p, "\tbroadcast_rgb=%s\n",
+			   drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb));
 		drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
 		drm_printf(p, "\toutput_format=%s\n",
 			   drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 9f517599f117..0e8fb653965a 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -589,6 +589,7 @@ void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
 
 	new_state->max_bpc = max_bpc;
 	new_state->max_requested_bpc = max_bpc;
+	new_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
 
@@ -913,7 +914,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 	if (ret)
 		return ret;
 
-	if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
+	if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb ||
+	    old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
 	    old_state->hdmi.output_format != new_state->hdmi.output_format) {
 		struct drm_crtc *crtc = new_state->crtc;
 		struct drm_crtc_state *crtc_state;
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 29d4940188d4..2b415b4ed506 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -776,6 +776,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 		state->max_requested_bpc = val;
 	} else if (property == connector->privacy_screen_sw_state_property) {
 		state->privacy_screen_sw_state = val;
+	} else if (property == connector->broadcast_rgb_property) {
+		state->hdmi.broadcast_rgb = val;
 	} else if (connector->funcs->atomic_set_property) {
 		return connector->funcs->atomic_set_property(connector,
 				state, property, val);
@@ -859,6 +861,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->max_requested_bpc;
 	} else if (property == connector->privacy_screen_sw_state_property) {
 		*val = state->privacy_screen_sw_state;
+	} else if (property == connector->broadcast_rgb_property) {
+		*val = state->hdmi.broadcast_rgb;
 	} else if (connector->funcs->atomic_get_property) {
 		return connector->funcs->atomic_get_property(connector,
 				state, property, val);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 591d2d500f61..6ffe59d01698 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1212,6 +1212,29 @@ static const u32 dp_colorspaces =
 	BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) |
 	BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);
 
+static const struct drm_prop_enum_list broadcast_rgb_names[] = {
+	{ DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic" },
+	{ DRM_HDMI_BROADCAST_RGB_FULL, "Full" },
+	{ DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" },
+};
+
+/*
+ * drm_hdmi_connector_get_broadcast_rgb_name - Return a string for HDMI connector RGB broadcast selection
+ * @broadcast_rgb: Broadcast RGB selection to compute name of
+ *
+ * Returns: the name of the Broadcast RGB selection, or NULL if the type
+ * is not valid.
+ */
+const char *
+drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb)
+{
+	if (broadcast_rgb > DRM_HDMI_BROADCAST_RGB_LIMITED)
+		return NULL;
+
+	return broadcast_rgb_names[broadcast_rgb].name;
+}
+EXPORT_SYMBOL(drm_hdmi_connector_get_broadcast_rgb_name);
+
 static const char * const output_format_str[] = {
 	[HDMI_COLORSPACE_RGB]		= "RGB",
 	[HDMI_COLORSPACE_YUV420]	= "YUV 4:2:0",
@@ -1708,6 +1731,39 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
 /**
  * DOC: HDMI connector properties
  *
+ * Broadcast RGB (HDMI specific)
+ *      Indicates the Quantization Range (Full vs Limited) used. The color
+ *      processing pipeline will be adjusted to match the value of the
+ *      property, and the Infoframes will be generated and sent accordingly.
+ *
+ *      This property is only relevant if the HDMI output format is RGB. If
+ *      it's one of the YCbCr variant, it will be ignored and the output will
+ *      use a limited quantization range.
+ *
+ *      The CRTC attached to the connector must be configured by user-space to
+ *      always produce full-range pixels.
+ *
+ *      The value of this property can be one of the following:
+ *
+ *      Automatic:
+ *              The quantization range is selected automatically based on the
+ *              mode according to the HDMI specifications (HDMI 1.4b - Section
+ *              6.6 - Video Quantization Ranges).
+ *
+ *      Full:
+ *              Full quantization range is forced.
+ *
+ *      Limited 16:235:
+ *              Limited quantization range is forced. Unlike the name suggests,
+ *              this works for any number of bits-per-component.
+ *
+ *      Property values other than Automatic can result in colors being off (if
+ *      limited is selected but the display expects full), or a black screen
+ *      (if full is selected but the display expects limited).
+ *
+ *      Drivers can set up this property by calling
+ *      drm_connector_attach_broadcast_rgb_property().
+ *
  * content type (HDMI specific):
  *	Indicates content type setting to be used in HDMI infoframes to indicate
  *	content type for the external device, so that it adjusts its display
@@ -2570,6 +2626,39 @@ int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *conn
 }
 EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property);
 
+/**
+ * drm_connector_attach_broadcast_rgb_property - attach "Broadcast RGB" property
+ * @connector: connector to attach the property on.
+ *
+ * This is used to add support for forcing the RGB range on a connector
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_property *prop;
+
+	prop = connector->broadcast_rgb_property;
+	if (!prop) {
+		prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
+						"Broadcast RGB",
+						broadcast_rgb_names,
+						ARRAY_SIZE(broadcast_rgb_names));
+		if (!prop)
+			return -EINVAL;
+
+		connector->broadcast_rgb_property = prop;
+	}
+
+	drm_object_attach_property(&connector->base, prop,
+				   DRM_HDMI_BROADCAST_RGB_AUTO);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_broadcast_rgb_property);
+
 /**
  * drm_connector_attach_colorspace_property - attach "Colorspace" property
  * @connector: connector to attach the property on.
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 8cda902934cd..bb6b6a36ade3 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -369,6 +369,29 @@ enum drm_panel_orientation {
 	DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
 };
 
+/**
+ * enum drm_hdmi_broadcast_rgb - Broadcast RGB Selection for an HDMI @drm_connector
+ */
+enum drm_hdmi_broadcast_rgb {
+	/**
+	 * @DRM_HDMI_BROADCAST_RGB_AUTO: The RGB range is selected
+	 * automatically based on the mode.
+	 */
+	DRM_HDMI_BROADCAST_RGB_AUTO,
+
+	/**
+	 * @DRM_HDMI_BROADCAST_RGB_FULL: Full range RGB is forced.
+	 */
+	DRM_HDMI_BROADCAST_RGB_FULL,
+
+	/**
+	 * @DRM_HDMI_BROADCAST_RGB_LIMITED: Limited range RGB is forced.
+	 */
+	DRM_HDMI_BROADCAST_RGB_LIMITED,
+};
+
+const char *
+drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb);
 const char *
 drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt);
 
@@ -1041,6 +1064,12 @@ struct drm_connector_state {
 	 * @drm_atomic_helper_connector_hdmi_check().
 	 */
 	struct {
+		/**
+		 * @broadcast_rgb: Connector property to pass the
+		 * Broadcast RGB selection value.
+		 */
+		enum drm_hdmi_broadcast_rgb broadcast_rgb;
+
 		/**
 		 * @output_bpc: Bits per color channel to output.
 		 */
@@ -1753,6 +1782,12 @@ struct drm_connector {
 	 */
 	struct drm_property *privacy_screen_hw_state_property;
 
+	/**
+	 * @broadcast_rgb_property: Connector property to set the
+	 * Broadcast RGB selection to output with.
+	 */
+	struct drm_property *broadcast_rgb_property;
+
 #define DRM_CONNECTOR_POLL_HPD (1 << 0)
 #define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
 #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
@@ -2092,6 +2127,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
 					       u32 scaling_mode_mask);
 int drm_connector_attach_vrr_capable_property(
 		struct drm_connector *connector);
+int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector);
 int drm_connector_attach_colorspace_property(struct drm_connector *connector);
 int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector);
 bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state,

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:13 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:13 +0100
Subject: [PATCH v7 27/36] drm/connector: hdmi: Create Infoframe DebugFS
 entries
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-27-8f4af575fce2@kernel.org>

There has been some discussions recently about the infoframes sent by
drivers and if they were properly generated.

In parallel, there's been some interest in creating an infoframe-decode
tool similar to edid-decode.

Both would be much easier if we were to expose the infoframes programmed
in the hardware. It won't be perfect since we have no guarantee that
it's actually what goes through the wire, but it's the best we can do.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_debugfs.c | 110 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 08fcefd804bc..160389f3d84b 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -520,6 +520,114 @@ static const struct file_operations drm_connector_fops = {
 	.write = connector_write
 };
 
+struct debugfs_wrapper {
+	struct drm_connector *connector;
+	struct drm_connector_hdmi_infoframe *frame;
+};
+
+#define HDMI_MAX_INFOFRAME_SIZE		29
+
+static ssize_t
+infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos)
+{
+	const struct debugfs_wrapper *wrapper = filp->private_data;
+	struct drm_connector *connector = wrapper->connector;
+	struct drm_connector_hdmi_infoframe *infoframe = wrapper->frame;
+	union hdmi_infoframe *frame = &infoframe->data;
+	u8 buf[HDMI_MAX_INFOFRAME_SIZE];
+	ssize_t len = 0;
+
+	mutex_lock(&connector->hdmi.infoframes.lock);
+
+	if (!infoframe->set)
+		goto out;
+
+	len = hdmi_infoframe_pack(frame, buf, sizeof(buf));
+	if (len < 0)
+		goto out;
+
+	len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+
+out:
+	mutex_unlock(&connector->hdmi.infoframes.lock);
+	return len;
+}
+
+static const struct file_operations infoframe_fops = {
+	.owner   = THIS_MODULE,
+	.open    = simple_open,
+	.read    = infoframe_read,
+};
+
+static int create_hdmi_infoframe_file(struct drm_connector *connector,
+				      struct dentry *parent,
+				      const char *filename,
+				      struct drm_connector_hdmi_infoframe *frame)
+{
+	struct drm_device *dev = connector->dev;
+	struct debugfs_wrapper *wrapper;
+	struct dentry *file;
+
+	wrapper = drmm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
+	if (!wrapper)
+		return -ENOMEM;
+
+	wrapper->connector = connector;
+	wrapper->frame = frame;
+
+	file = debugfs_create_file(filename, 0400, parent, wrapper, &infoframe_fops);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	return 0;
+}
+
+#define CREATE_HDMI_INFOFRAME_FILE(c, p, i)		\
+	create_hdmi_infoframe_file(c, p, #i, &(c)->hdmi.infoframes.i)
+
+static int create_hdmi_infoframe_files(struct drm_connector *connector,
+				       struct dentry *parent)
+{
+	int ret;
+
+	ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, audio);
+	if (ret)
+		return ret;
+
+	ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, avi);
+	if (ret)
+		return ret;
+
+	ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, hdr_drm);
+	if (ret)
+		return ret;
+
+	ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, spd);
+	if (ret)
+		return ret;
+
+	ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, hdmi);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void hdmi_debugfs_add(struct drm_connector *connector)
+{
+	struct dentry *dir;
+
+	if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+	      connector->connector_type == DRM_MODE_CONNECTOR_HDMIB))
+		return;
+
+	dir = debugfs_create_dir("infoframes", connector->debugfs_entry);
+	if (IS_ERR(dir))
+		return;
+
+	create_hdmi_infoframe_files(connector, dir);
+}
+
 void drm_debugfs_connector_add(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
@@ -547,6 +655,8 @@ void drm_debugfs_connector_add(struct drm_connector *connector)
 	debugfs_create_file("output_bpc", 0444, root, connector,
 			    &output_bpc_fops);
 
+	hdmi_debugfs_add(connector);
+
 	if (connector->funcs->debugfs_init)
 		connector->funcs->debugfs_init(connector, root);
 }

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:14 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:14 +0100
Subject: [PATCH v7 28/36] drm/vc4: hdmi: Switch to HDMI connector
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-28-8f4af575fce2@kernel.org>

The new HDMI connector infrastructure allows us to remove a lot of
boilerplate, so let's switch to it.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c     | 638 +++++--------------------------------
 drivers/gpu/drm/vc4/vc4_hdmi.h     |  44 +--
 drivers/gpu/drm/vc4/vc4_hdmi_phy.c |   6 +-
 3 files changed, 86 insertions(+), 602 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 34f807ed1c31..1f489cbe0c90 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -110,25 +110,6 @@
 
 #define HDMI_14_MAX_TMDS_CLK   (340 * 1000 * 1000)
 
-static const char * const output_format_str[] = {
-	[VC4_HDMI_OUTPUT_RGB]		= "RGB",
-	[VC4_HDMI_OUTPUT_YUV420]	= "YUV 4:2:0",
-	[VC4_HDMI_OUTPUT_YUV422]	= "YUV 4:2:2",
-	[VC4_HDMI_OUTPUT_YUV444]	= "YUV 4:4:4",
-};
-
-static const char *vc4_hdmi_output_fmt_str(enum vc4_hdmi_output_format fmt)
-{
-	if (fmt >= ARRAY_SIZE(output_format_str))
-		return "invalid";
-
-	return output_format_str[fmt];
-}
-
-static unsigned long long
-vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode,
-				    unsigned int bpc, enum vc4_hdmi_output_format fmt);
-
 static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi)
 {
 	struct drm_display_info *display = &vc4_hdmi->connector.display_info;
@@ -147,28 +128,13 @@ static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi)
 
 static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode,
 					   unsigned int bpc,
-					   enum vc4_hdmi_output_format fmt)
+					   enum hdmi_colorspace fmt)
 {
-	unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt);
+	unsigned long long clock = drm_connector_hdmi_compute_mode_clock(mode, bpc, fmt);
 
 	return clock > HDMI_14_MAX_TMDS_CLK;
 }
 
-static bool vc4_hdmi_is_full_range(struct vc4_hdmi *vc4_hdmi,
-				   struct vc4_hdmi_connector_state *vc4_state)
-{
-	const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
-	struct drm_display_info *display = &vc4_hdmi->connector.display_info;
-
-	if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_LIMITED)
-		return false;
-	else if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_FULL)
-		return true;
-
-	return !display->is_hdmi ||
-		drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL;
-}
-
 static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
 {
 	struct drm_debugfs_entry *entry = m->private;
@@ -520,7 +486,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
 		const struct drm_display_mode *mode;
 
 		list_for_each_entry(mode, &connector->probed_modes, head) {
-			if (vc4_hdmi_mode_needs_scrambling(mode, 8, VC4_HDMI_OUTPUT_RGB)) {
+			if (vc4_hdmi_mode_needs_scrambling(mode, 8, HDMI_COLORSPACE_RGB)) {
 				drm_warn_once(drm, "The core clock cannot reach frequencies high enough to support 4k @ 60Hz.");
 				drm_warn_once(drm, "Please change your config.txt file to add hdmi_enable_4kp60.");
 			}
@@ -535,12 +501,8 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
 {
 	struct drm_connector_state *old_state =
 		drm_atomic_get_old_connector_state(state, connector);
-	struct vc4_hdmi_connector_state *old_vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(old_state);
 	struct drm_connector_state *new_state =
 		drm_atomic_get_new_connector_state(state, connector);
-	struct vc4_hdmi_connector_state *new_vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(new_state);
 	struct drm_crtc *crtc = new_state->crtc;
 
 	if (!crtc)
@@ -572,9 +534,7 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
 			return ret;
 	}
 
-	if (old_state->colorspace != new_state->colorspace ||
-	    old_vc4_state->broadcast_rgb != new_vc4_state->broadcast_rgb ||
-	    !drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) {
+	if (old_state->colorspace != new_state->colorspace) {
 		struct drm_crtc_state *crtc_state;
 
 		crtc_state = drm_atomic_get_crtc_state(state, crtc);
@@ -584,112 +544,21 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
 		crtc_state->mode_changed = true;
 	}
 
-	return 0;
-}
-
-static int vc4_hdmi_connector_get_property(struct drm_connector *connector,
-					   const struct drm_connector_state *state,
-					   struct drm_property *property,
-					   uint64_t *val)
-{
-	struct drm_device *drm = connector->dev;
-	struct vc4_hdmi *vc4_hdmi =
-		connector_to_vc4_hdmi(connector);
-	const struct vc4_hdmi_connector_state *vc4_conn_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
-
-	if (property == vc4_hdmi->broadcast_rgb_property) {
-		*val = vc4_conn_state->broadcast_rgb;
-	} else {
-		drm_dbg(drm, "Unknown property [PROP:%d:%s]\n",
-			property->base.id, property->name);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int vc4_hdmi_connector_set_property(struct drm_connector *connector,
-					   struct drm_connector_state *state,
-					   struct drm_property *property,
-					   uint64_t val)
-{
-	struct drm_device *drm = connector->dev;
-	struct vc4_hdmi *vc4_hdmi =
-		connector_to_vc4_hdmi(connector);
-	struct vc4_hdmi_connector_state *vc4_conn_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
-
-	if (property == vc4_hdmi->broadcast_rgb_property) {
-		vc4_conn_state->broadcast_rgb = val;
-		return 0;
-	}
-
-	drm_dbg(drm, "Unknown property [PROP:%d:%s]\n",
-		property->base.id, property->name);
-	return -EINVAL;
+	return drm_atomic_helper_connector_hdmi_check(connector, state);
 }
 
 static void vc4_hdmi_connector_reset(struct drm_connector *connector)
 {
-	struct vc4_hdmi_connector_state *old_state =
-		conn_state_to_vc4_hdmi_conn_state(connector->state);
-	struct vc4_hdmi_connector_state *new_state =
-		kzalloc(sizeof(*new_state), GFP_KERNEL);
-
-	if (connector->state)
-		__drm_atomic_helper_connector_destroy_state(connector->state);
-
-	kfree(old_state);
-	__drm_atomic_helper_connector_reset(connector, &new_state->base);
-
-	if (!new_state)
-		return;
-
-	new_state->base.max_bpc = 8;
-	new_state->base.max_requested_bpc = 8;
-	new_state->output_format = VC4_HDMI_OUTPUT_RGB;
-	new_state->broadcast_rgb = VC4_HDMI_BROADCAST_RGB_AUTO;
+	drm_atomic_helper_connector_reset(connector);
+	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
 	drm_atomic_helper_connector_tv_margins_reset(connector);
 }
 
-static struct drm_connector_state *
-vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
-{
-	struct drm_connector_state *conn_state = connector->state;
-	struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state);
-	struct vc4_hdmi_connector_state *new_state;
-
-	new_state = kzalloc(sizeof(*new_state), GFP_KERNEL);
-	if (!new_state)
-		return NULL;
-
-	new_state->tmds_char_rate = vc4_state->tmds_char_rate;
-	new_state->output_bpc = vc4_state->output_bpc;
-	new_state->output_format = vc4_state->output_format;
-	new_state->broadcast_rgb = vc4_state->broadcast_rgb;
-	__drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
-
-	return &new_state->base;
-}
-
-static void vc4_hdmi_connector_destroy_state(struct drm_connector *connector,
-					     struct drm_connector_state *state)
-{
-	struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
-
-	__drm_atomic_helper_connector_destroy_state(state);
-	kfree(vc4_state);
-}
-
 static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.reset = vc4_hdmi_connector_reset,
-	.atomic_duplicate_state = vc4_hdmi_connector_duplicate_state,
-	.atomic_destroy_state = vc4_hdmi_connector_destroy_state,
-	.atomic_get_property = vc4_hdmi_connector_get_property,
-	.atomic_set_property = vc4_hdmi_connector_set_property,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
@@ -698,32 +567,7 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
 	.atomic_check = vc4_hdmi_connector_atomic_check,
 };
 
-static const struct drm_prop_enum_list broadcast_rgb_names[] = {
-	{ VC4_HDMI_BROADCAST_RGB_AUTO, "Automatic" },
-	{ VC4_HDMI_BROADCAST_RGB_FULL, "Full" },
-	{ VC4_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" },
-};
-
-static void
-vc4_hdmi_attach_broadcast_rgb_property(struct drm_device *dev,
-				       struct vc4_hdmi *vc4_hdmi)
-{
-	struct drm_property *prop = vc4_hdmi->broadcast_rgb_property;
-
-	if (!prop) {
-		prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
-						"Broadcast RGB",
-						broadcast_rgb_names,
-						ARRAY_SIZE(broadcast_rgb_names));
-		if (!prop)
-			return;
-
-		vc4_hdmi->broadcast_rgb_property = prop;
-	}
-
-	drm_object_attach_property(&vc4_hdmi->connector.base, prop,
-				   VC4_HDMI_BROADCAST_RGB_AUTO);
-}
+static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs;
 
 static int vc4_hdmi_connector_init(struct drm_device *dev,
 				   struct vc4_hdmi *vc4_hdmi)
@@ -732,10 +576,16 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
 	struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
 	int ret;
 
-	ret = drmm_connector_init(dev, connector,
-				  &vc4_hdmi_connector_funcs,
-				  DRM_MODE_CONNECTOR_HDMIA,
-				  vc4_hdmi->ddc);
+	ret = drmm_connector_hdmi_init(dev, connector,
+				       "Broadcom", "Videocore",
+				       &vc4_hdmi_connector_funcs,
+				       &vc4_hdmi_hdmi_connector_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       vc4_hdmi->ddc,
+				       BIT(HDMI_COLORSPACE_RGB) |
+				       BIT(HDMI_COLORSPACE_YUV422) |
+				       BIT(HDMI_COLORSPACE_YUV444),
+				       12);
 	if (ret)
 		return ret;
 
@@ -759,7 +609,6 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
 
 	drm_connector_attach_colorspace_property(connector);
 	drm_connector_attach_tv_margin_properties(connector);
-	drm_connector_attach_max_bpc_property(connector, 8, 12);
 
 	connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
 			     DRM_CONNECTOR_POLL_DISCONNECT);
@@ -768,21 +617,19 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
 	connector->doublescan_allowed = 0;
 	connector->stereo_allowed = 1;
 
-	if (vc4_hdmi->variant->supports_hdr)
-		drm_connector_attach_hdr_output_metadata_property(connector);
-
-	vc4_hdmi_attach_broadcast_rgb_property(dev, vc4_hdmi);
+	ret = drm_connector_attach_broadcast_rgb_property(connector);
+	if (ret)
+		return ret;
 
 	drm_connector_attach_encoder(connector, encoder);
 
 	return 0;
 }
 
-static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
+static int vc4_hdmi_stop_packet(struct vc4_hdmi *vc4_hdmi,
 				enum hdmi_infoframe_type type,
 				bool poll)
 {
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	u32 packet_id = type - 0x80;
 	unsigned long flags;
@@ -806,12 +653,13 @@ static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
 	return ret;
 }
 
-static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
-				     union hdmi_infoframe *frame)
+static int vc4_hdmi_write_infoframe(struct drm_connector *connector,
+				    enum hdmi_infoframe_type type,
+				    const u8 *infoframe, size_t len)
 {
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct drm_device *drm = vc4_hdmi->connector.dev;
-	u32 packet_id = frame->any.type - 0x80;
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
+	struct drm_device *drm = connector->dev;
+	u32 packet_id = type - 0x80;
 	const struct vc4_hdmi_register *ram_packet_start =
 		&vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START];
 	u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id;
@@ -821,22 +669,25 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
 						       ram_packet_start->reg);
 	uint8_t buffer[VC4_HDMI_PACKET_STRIDE] = {};
 	unsigned long flags;
-	ssize_t len, i;
+	ssize_t i;
 	int ret;
 	int idx;
 
 	if (!drm_dev_enter(drm, &idx))
-		return;
+		return 0;
+
+	if (len > sizeof(buffer)) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(buffer, infoframe, len);
 
 	WARN_ONCE(!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
 		    VC4_HDMI_RAM_PACKET_ENABLE),
 		  "Packet RAM has to be on to store the packet.");
 
-	len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer));
-	if (len < 0)
-		goto out;
-
-	ret = vc4_hdmi_stop_packet(encoder, frame->any.type, true);
+	ret = vc4_hdmi_stop_packet(vc4_hdmi, type, true);
 	if (ret) {
 		DRM_ERROR("Failed to wait for infoframe to go idle: %d\n", ret);
 		goto out;
@@ -878,130 +729,7 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
 
 out:
 	drm_dev_exit(idx);
-}
-
-static void vc4_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame,
-					      enum vc4_hdmi_output_format fmt)
-{
-	switch (fmt) {
-	case VC4_HDMI_OUTPUT_RGB:
-		frame->colorspace = HDMI_COLORSPACE_RGB;
-		break;
-
-	case VC4_HDMI_OUTPUT_YUV420:
-		frame->colorspace = HDMI_COLORSPACE_YUV420;
-		break;
-
-	case VC4_HDMI_OUTPUT_YUV422:
-		frame->colorspace = HDMI_COLORSPACE_YUV422;
-		break;
-
-	case VC4_HDMI_OUTPUT_YUV444:
-		frame->colorspace = HDMI_COLORSPACE_YUV444;
-		break;
-
-	default:
-		break;
-	}
-}
-
-static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
-{
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct drm_connector *connector = &vc4_hdmi->connector;
-	struct drm_connector_state *cstate = connector->state;
-	struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(cstate);
-	const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
-	union hdmi_infoframe frame;
-	int ret;
-
-	lockdep_assert_held(&vc4_hdmi->mutex);
-
-	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
-						       connector, mode);
-	if (ret < 0) {
-		DRM_ERROR("couldn't fill AVI infoframe\n");
-		return;
-	}
-
-	drm_hdmi_avi_infoframe_quant_range(&frame.avi,
-					   connector, mode,
-					   vc4_hdmi_is_full_range(vc4_hdmi, vc4_state) ?
-					   HDMI_QUANTIZATION_RANGE_FULL :
-					   HDMI_QUANTIZATION_RANGE_LIMITED);
-	drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate);
-	vc4_hdmi_avi_infoframe_colorspace(&frame.avi, vc4_state->output_format);
-	drm_hdmi_avi_infoframe_bars(&frame.avi, cstate);
-
-	vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
-{
-	union hdmi_infoframe frame;
-	int ret;
-
-	ret = hdmi_spd_infoframe_init(&frame.spd, "Broadcom", "Videocore");
-	if (ret < 0) {
-		DRM_ERROR("couldn't fill SPD infoframe\n");
-		return;
-	}
-
-	frame.spd.sdi = HDMI_SPD_SDI_PC;
-
-	vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder)
-{
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct hdmi_audio_infoframe *audio = &vc4_hdmi->audio.infoframe;
-	union hdmi_infoframe frame;
-
-	memcpy(&frame.audio, audio, sizeof(*audio));
-
-	if (vc4_hdmi->packet_ram_enabled)
-		vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_hdr_infoframe(struct drm_encoder *encoder)
-{
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct drm_connector *connector = &vc4_hdmi->connector;
-	struct drm_connector_state *conn_state = connector->state;
-	union hdmi_infoframe frame;
-
-	lockdep_assert_held(&vc4_hdmi->mutex);
-
-	if (!vc4_hdmi->variant->supports_hdr)
-		return;
-
-	if (!conn_state->hdr_output_metadata)
-		return;
-
-	if (drm_hdmi_infoframe_set_hdr_metadata(&frame.drm, conn_state))
-		return;
-
-	vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder)
-{
-	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-
-	lockdep_assert_held(&vc4_hdmi->mutex);
-
-	vc4_hdmi_set_avi_infoframe(encoder);
-	vc4_hdmi_set_spd_infoframe(encoder);
-	/*
-	 * If audio was streaming, then we need to reenabled the audio
-	 * infoframe here during encoder_enable.
-	 */
-	if (vc4_hdmi->audio.streaming)
-		vc4_hdmi_set_audio_infoframe(encoder);
-
-	vc4_hdmi_set_hdr_infoframe(encoder);
+	return ret;
 }
 
 #define SCRAMBLING_POLLING_DELAY_MS	1000
@@ -1170,9 +898,8 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 			       struct drm_connector_state *state,
 			       const struct drm_display_mode *mode)
 {
-	struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
+	bool is_lim_range = !state->hdmi.is_full_range;
 	unsigned long flags;
 	u32 csc_ctl;
 	int idx;
@@ -1185,7 +912,7 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 	csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
 				VC4_HD_CSC_CTL_ORDER);
 
-	if (!vc4_hdmi_is_full_range(vc4_hdmi, vc4_state)) {
+	if (is_lim_range) {
 		/* CEA VICs other than #1 requre limited range RGB
 		 * output unless overridden by an AVI infoframe.
 		 * Apply a colorspace conversion to squash 0-255 down
@@ -1408,9 +1135,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 			       const struct drm_display_mode *mode)
 {
 	struct drm_device *drm = vc4_hdmi->connector.dev;
-	struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
-	unsigned int lim_range = vc4_hdmi_is_full_range(vc4_hdmi, vc4_state) ? 0 : 1;
+	unsigned int lim_range = state->hdmi.is_full_range ? 0 : 1;
 	unsigned long flags;
 	const u16 (*csc)[4];
 	u32 if_cfg = 0;
@@ -1425,14 +1150,14 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 
 	spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 
-	switch (vc4_state->output_format) {
-	case VC4_HDMI_OUTPUT_YUV444:
+	switch (state->hdmi.output_format) {
+	case HDMI_COLORSPACE_YUV444:
 		csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range);
 
 		vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, csc);
 		break;
 
-	case VC4_HDMI_OUTPUT_YUV422:
+	case HDMI_COLORSPACE_YUV422:
 		csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range);
 
 		csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD,
@@ -1449,7 +1174,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 		vc5_hdmi_set_csc_coeffs(vc4_hdmi, csc);
 		break;
 
-	case VC4_HDMI_OUTPUT_RGB:
+	case HDMI_COLORSPACE_RGB:
 		if_xbar = 0x354021;
 
 		vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_rgb[lim_range]);
@@ -1538,8 +1263,6 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
 				 const struct drm_display_mode *mode)
 {
 	struct drm_device *drm = vc4_hdmi->connector.dev;
-	const struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(state);
 	bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
 	bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
 	bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
@@ -1591,7 +1314,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
 	HDMI_WRITE(HDMI_VERTB0, vertb_even);
 	HDMI_WRITE(HDMI_VERTB1, vertb);
 
-	switch (vc4_state->output_bpc) {
+	switch (state->hdmi.output_bpc) {
 	case 12:
 		gcp = 6;
 		break;
@@ -1608,7 +1331,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
 	 * YCC422 is always 36-bit and not considered deep colour so
 	 * doesn't signal in GCP.
 	 */
-	if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) {
+	if (state->hdmi.output_format == HDMI_COLORSPACE_YUV422) {
 		gcp = 0;
 	}
 
@@ -1692,10 +1415,8 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
 	struct drm_connector *connector = &vc4_hdmi->connector;
 	struct drm_connector_state *conn_state =
 		drm_atomic_get_new_connector_state(state, connector);
-	struct vc4_hdmi_connector_state *vc4_conn_state =
-		conn_state_to_vc4_hdmi_conn_state(conn_state);
 	const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
-	unsigned long tmds_char_rate = vc4_conn_state->tmds_char_rate;
+	unsigned long tmds_char_rate = conn_state->hdmi.tmds_char_rate;
 	unsigned long bvb_rate, hsm_rate;
 	unsigned long flags;
 	int ret;
@@ -1772,7 +1493,7 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
 	}
 
 	if (vc4_hdmi->variant->phy_init)
-		vc4_hdmi->variant->phy_init(vc4_hdmi, vc4_conn_state);
+		vc4_hdmi->variant->phy_init(vc4_hdmi, conn_state);
 
 	spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 
@@ -1837,7 +1558,8 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
 					      struct drm_atomic_state *state)
 {
 	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct drm_device *drm = vc4_hdmi->connector.dev;
+	struct drm_connector *connector = &vc4_hdmi->connector;
+	struct drm_device *drm = connector->dev;
 	const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
 	struct drm_display_info *display = &vc4_hdmi->connector.display_info;
 	bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
@@ -1903,7 +1625,7 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
 		spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 		vc4_hdmi->packet_ram_enabled = true;
 
-		vc4_hdmi_set_infoframes(encoder);
+		drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
 	}
 
 	vc4_hdmi_recenter_fifo(vc4_hdmi);
@@ -1920,108 +1642,21 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
 					     struct drm_connector_state *conn_state)
 {
 	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct vc4_hdmi_connector_state *vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(conn_state);
 
 	mutex_lock(&vc4_hdmi->mutex);
 	drm_mode_copy(&vc4_hdmi->saved_adjusted_mode,
 		      &crtc_state->adjusted_mode);
-	vc4_hdmi->output_bpc = vc4_state->output_bpc;
-	vc4_hdmi->output_format = vc4_state->output_format;
+	vc4_hdmi->output_bpc = conn_state->hdmi.output_bpc;
+	vc4_hdmi->output_format = conn_state->hdmi.output_format;
 	mutex_unlock(&vc4_hdmi->mutex);
 }
 
-static bool
-vc4_hdmi_sink_supports_format_bpc(const struct vc4_hdmi *vc4_hdmi,
-				  const struct drm_display_info *info,
-				  const struct drm_display_mode *mode,
-				  unsigned int format, unsigned int bpc)
-{
-	struct drm_device *dev = vc4_hdmi->connector.dev;
-	u8 vic = drm_match_cea_mode(mode);
-
-	if (vic == 1 && bpc != 8) {
-		drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
-		return false;
-	}
-
-	if (!info->is_hdmi &&
-	    (format != VC4_HDMI_OUTPUT_RGB || bpc != 8)) {
-		drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
-		return false;
-	}
-
-	switch (format) {
-	case VC4_HDMI_OUTPUT_RGB:
-		drm_dbg(dev, "RGB Format, checking the constraints.\n");
-
-		if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
-			return false;
-
-		if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {
-			drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
-			return false;
-		}
-
-		if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {
-			drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
-			return false;
-		}
-
-		drm_dbg(dev, "RGB format supported in that configuration.\n");
-
-		return true;
-
-	case VC4_HDMI_OUTPUT_YUV422:
-		drm_dbg(dev, "YUV422 format, checking the constraints.\n");
-
-		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
-			drm_dbg(dev, "Sink doesn't support YUV422.\n");
-			return false;
-		}
-
-		if (bpc != 12) {
-			drm_dbg(dev, "YUV422 only supports 12 bpc.\n");
-			return false;
-		}
-
-		drm_dbg(dev, "YUV422 format supported in that configuration.\n");
-
-		return true;
-
-	case VC4_HDMI_OUTPUT_YUV444:
-		drm_dbg(dev, "YUV444 format, checking the constraints.\n");
-
-		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {
-			drm_dbg(dev, "Sink doesn't support YUV444.\n");
-			return false;
-		}
-
-		if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_30)) {
-			drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
-			return false;
-		}
-
-		if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_36)) {
-			drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
-			return false;
-		}
-
-		drm_dbg(dev, "YUV444 format supported in that configuration.\n");
-
-		return true;
-	}
-
-	return false;
-}
-
 static enum drm_mode_status
-vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
-			     const struct drm_display_mode *mode,
-			     unsigned long long clock)
+vc4_hdmi_connector_clock_valid(const struct drm_connector *connector,
+			       const struct drm_display_mode *mode,
+			       unsigned long long clock)
 {
-	const struct drm_connector *connector = &vc4_hdmi->connector;
-	const struct drm_display_info *info = &connector->display_info;
+	const struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
 
 	if (clock > vc4_hdmi->variant->max_pixel_clock)
@@ -2036,125 +1671,13 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
 	    drm_mode_vrefresh(mode) >= 50)
 		return MODE_CLOCK_HIGH;
 
-	if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
-		return MODE_CLOCK_HIGH;
-
 	return MODE_OK;
 }
 
-static unsigned long long
-vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode,
-				    unsigned int bpc,
-				    enum vc4_hdmi_output_format fmt)
-{
-	unsigned long long clock = mode->clock * 1000ULL;
-
-	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
-		clock = clock * 2;
-
-	if (fmt == VC4_HDMI_OUTPUT_YUV422)
-		bpc = 8;
-
-	clock = clock * bpc;
-	do_div(clock, 8);
-
-	return clock;
-}
-
-static int
-vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi,
-			       struct vc4_hdmi_connector_state *vc4_state,
-			       const struct drm_display_mode *mode,
-			       unsigned int bpc, unsigned int fmt)
-{
-	unsigned long long clock;
-
-	clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt);
-	if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, clock) != MODE_OK)
-		return -EINVAL;
-
-	vc4_state->tmds_char_rate = clock;
-
-	return 0;
-}
-
-static int
-vc4_hdmi_encoder_compute_format(const struct vc4_hdmi *vc4_hdmi,
-				struct vc4_hdmi_connector_state *vc4_state,
-				const struct drm_display_mode *mode,
-				unsigned int bpc)
-{
-	struct drm_device *dev = vc4_hdmi->connector.dev;
-	const struct drm_connector *connector = &vc4_hdmi->connector;
-	const struct drm_display_info *info = &connector->display_info;
-	unsigned int format;
-
-	drm_dbg(dev, "Trying with an RGB output\n");
-
-	format = VC4_HDMI_OUTPUT_RGB;
-	if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) {
-		int ret;
-
-		ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state,
-						     mode, bpc, format);
-		if (!ret) {
-			vc4_state->output_format = format;
-			return 0;
-		}
-	}
-
-	drm_dbg(dev, "Failed, Trying with an YUV422 output\n");
-
-	format = VC4_HDMI_OUTPUT_YUV422;
-	if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) {
-		int ret;
-
-		ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state,
-						     mode, bpc, format);
-		if (!ret) {
-			vc4_state->output_format = format;
-			return 0;
-		}
-	}
-
-	drm_dbg(dev, "Failed. No Format Supported for that bpc count.\n");
-
-	return -EINVAL;
-}
-
-static int
-vc4_hdmi_encoder_compute_config(const struct vc4_hdmi *vc4_hdmi,
-				struct vc4_hdmi_connector_state *vc4_state,
-				const struct drm_display_mode *mode)
-{
-	struct drm_device *dev = vc4_hdmi->connector.dev;
-	struct drm_connector_state *conn_state = &vc4_state->base;
-	unsigned int max_bpc = clamp_t(unsigned int, conn_state->max_bpc, 8, 12);
-	unsigned int bpc;
-	int ret;
-
-	for (bpc = max_bpc; bpc >= 8; bpc -= 2) {
-		drm_dbg(dev, "Trying with a %d bpc output\n", bpc);
-
-		ret = vc4_hdmi_encoder_compute_format(vc4_hdmi, vc4_state,
-						      mode, bpc);
-		if (ret)
-			continue;
-
-		vc4_state->output_bpc = bpc;
-
-		drm_dbg(dev,
-			"Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n",
-			mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
-			vc4_state->output_bpc,
-			vc4_hdmi_output_fmt_str(vc4_state->output_format),
-			vc4_state->tmds_char_rate);
-
-		break;
-	}
-
-	return ret;
-}
+static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs = {
+	.tmds_char_rate_valid	= vc4_hdmi_connector_clock_valid,
+	.write_infoframe	= vc4_hdmi_write_infoframe,
+};
 
 #define WIFI_2_4GHz_CH1_MIN_FREQ	2400000000ULL
 #define WIFI_2_4GHz_CH1_MAX_FREQ	2422000000ULL
@@ -2164,16 +1687,9 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 					 struct drm_connector_state *conn_state)
 {
 	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-	struct drm_connector *connector = &vc4_hdmi->connector;
-	struct drm_connector_state *old_conn_state =
-		drm_atomic_get_old_connector_state(conn_state->state, connector);
-	struct vc4_hdmi_connector_state *old_vc4_state =
-		conn_state_to_vc4_hdmi_conn_state(old_conn_state);
-	struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state);
 	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 	unsigned long long tmds_char_rate = mode->clock * 1000;
 	unsigned long long tmds_bit_rate;
-	int ret;
 
 	if (vc4_hdmi->variant->unsupported_odd_h_timings) {
 		if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
@@ -2209,15 +1725,6 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 		tmds_char_rate = mode->clock * 1000;
 	}
 
-	ret = vc4_hdmi_encoder_compute_config(vc4_hdmi, vc4_state, mode);
-	if (ret)
-		return ret;
-
-	/* vc4_hdmi_encoder_compute_config may have changed output_bpc and/or output_format */
-	if (vc4_state->output_bpc != old_vc4_state->output_bpc ||
-	    vc4_state->output_format != old_vc4_state->output_format)
-		crtc_state->mode_changed = true;
-
 	return 0;
 }
 
@@ -2226,6 +1733,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
 			    const struct drm_display_mode *mode)
 {
 	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
+	unsigned long long rate;
 
 	if (vc4_hdmi->variant->unsupported_odd_h_timings &&
 	    !(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
@@ -2233,7 +1741,8 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
 	     (mode->hsync_end % 2) || (mode->htotal % 2)))
 		return MODE_H_ILLEGAL;
 
-	return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, mode->clock * 1000);
+	rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+	return vc4_hdmi_connector_clock_valid(&vc4_hdmi->connector, mode, rate);
 }
 
 static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
@@ -2425,7 +1934,6 @@ static int vc4_hdmi_audio_startup(struct device *dev, void *data)
 
 static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 {
-	struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
 	struct device *dev = &vc4_hdmi->pdev->dev;
 	unsigned long flags;
 	int ret;
@@ -2433,7 +1941,7 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 	lockdep_assert_held(&vc4_hdmi->mutex);
 
 	vc4_hdmi->audio.streaming = false;
-	ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO, false);
+	ret = vc4_hdmi_stop_packet(vc4_hdmi, HDMI_INFOFRAME_TYPE_AUDIO, false);
 	if (ret)
 		dev_err(dev, "Failed to stop audio infoframe: %d\n", ret);
 
@@ -2524,7 +2032,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
 {
 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
-	struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
+	struct drm_connector *connector = &vc4_hdmi->connector;
 	unsigned int sample_rate = params->sample_rate;
 	unsigned int channels = params->channels;
 	unsigned long flags;
@@ -2601,8 +2109,10 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
 
 	spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
 
-	memcpy(&vc4_hdmi->audio.infoframe, &params->cea, sizeof(params->cea));
-	vc4_hdmi_set_audio_infoframe(encoder);
+	ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector,
+								      &params->cea);
+	if (ret)
+		goto out_dev_exit;
 
 out_dev_exit:
 	drm_dev_exit(idx);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 934d5d61485a..b37f1d2c3fe5 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -10,7 +10,6 @@
 
 struct vc4_hdmi;
 struct vc4_hdmi_register;
-struct vc4_hdmi_connector_state;
 
 enum vc4_hdmi_phy_channel {
 	PHY_LANE_0 = 0,
@@ -76,7 +75,7 @@ struct vc4_hdmi_variant {
 
 	/* Callback to initialize the PHY according to the connector state */
 	void (*phy_init)(struct vc4_hdmi *vc4_hdmi,
-			 struct vc4_hdmi_connector_state *vc4_conn_state);
+			 struct drm_connector_state *conn_state);
 
 	/* Callback to disable the PHY */
 	void (*phy_disable)(struct vc4_hdmi *vc4_hdmi);
@@ -110,19 +109,6 @@ struct vc4_hdmi_audio {
 	bool streaming;
 };
 
-enum vc4_hdmi_output_format {
-	VC4_HDMI_OUTPUT_RGB,
-	VC4_HDMI_OUTPUT_YUV422,
-	VC4_HDMI_OUTPUT_YUV444,
-	VC4_HDMI_OUTPUT_YUV420,
-};
-
-enum vc4_hdmi_broadcast_rgb {
-	VC4_HDMI_BROADCAST_RGB_AUTO,
-	VC4_HDMI_BROADCAST_RGB_FULL,
-	VC4_HDMI_BROADCAST_RGB_LIMITED,
-};
-
 /* General HDMI hardware state. */
 struct vc4_hdmi {
 	struct vc4_hdmi_audio audio;
@@ -135,8 +121,6 @@ struct vc4_hdmi {
 
 	struct delayed_work scrambling_work;
 
-	struct drm_property *broadcast_rgb_property;
-
 	struct i2c_adapter *ddc;
 	void __iomem *hdmicore_regs;
 	void __iomem *hd_regs;
@@ -218,16 +202,17 @@ struct vc4_hdmi {
 	bool scdc_enabled;
 
 	/**
-	 * @output_bpc: Copy of @vc4_connector_state.output_bpc for use
-	 * outside of KMS hooks. Protected by @mutex.
+	 * @output_bpc: Copy of @drm_connector_state.hdmi.output_bpc for
+	 * use outside of KMS hooks. Protected by @mutex.
 	 */
 	unsigned int output_bpc;
 
 	/**
-	 * @output_format: Copy of @vc4_connector_state.output_format
-	 * for use outside of KMS hooks. Protected by @mutex.
+	 * @output_format: Copy of
+	 * @drm_connector_state.hdmi.output_format for use outside of
+	 * KMS hooks. Protected by @mutex.
 	 */
-	enum vc4_hdmi_output_format output_format;
+	enum hdmi_colorspace output_format;
 };
 
 #define connector_to_vc4_hdmi(_connector)				\
@@ -240,25 +225,14 @@ encoder_to_vc4_hdmi(struct drm_encoder *encoder)
 	return container_of_const(_encoder, struct vc4_hdmi, encoder);
 }
 
-struct vc4_hdmi_connector_state {
-	struct drm_connector_state	base;
-	unsigned long long		tmds_char_rate;
-	unsigned int 			output_bpc;
-	enum vc4_hdmi_output_format	output_format;
-	enum vc4_hdmi_broadcast_rgb	broadcast_rgb;
-};
-
-#define conn_state_to_vc4_hdmi_conn_state(_state)			\
-	container_of_const(_state, struct vc4_hdmi_connector_state, base)
-
 void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
-		       struct vc4_hdmi_connector_state *vc4_conn_state);
+		       struct drm_connector_state *conn_state);
 void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
 void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
 void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
 
 void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
-		       struct vc4_hdmi_connector_state *vc4_conn_state);
+		       struct drm_connector_state *conn_state);
 void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
 void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
 void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
index ec24999bf96d..1f5507fc7a03 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
@@ -128,7 +128,7 @@
 #define OSCILLATOR_FREQUENCY	54000000
 
 void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
-		       struct vc4_hdmi_connector_state *conn_state)
+		       struct drm_connector_state *conn_state)
 {
 	unsigned long flags;
 
@@ -361,11 +361,11 @@ static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi)
 }
 
 void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
-		       struct vc4_hdmi_connector_state *conn_state)
+		       struct drm_connector_state *conn_state)
 {
 	const struct phy_lane_settings *chan0_settings, *chan1_settings, *chan2_settings, *clock_settings;
 	const struct vc4_hdmi_variant *variant = vc4_hdmi->variant;
-	unsigned long long pixel_freq = conn_state->tmds_char_rate;
+	unsigned long long pixel_freq = conn_state->hdmi.tmds_char_rate;
 	unsigned long long vco_freq;
 	unsigned char word_sel;
 	unsigned long flags;

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:12 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:12 +0100
Subject: [PATCH v7 26/36] drm/tests: Add infoframes test
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-26-8f4af575fce2@kernel.org>

The previous patch added the generation of the infoframes matching an
HDMI connector state. Let's add a few tests to make sure it works as
expected.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/tests/drm_connector_test.c | 219 +++++++++++++++++++++++++++++
 1 file changed, 219 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index b9c80d282380..07066b704b36 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -219,6 +219,217 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, ret, 0);
 }
 
+/*
+ * Test that the registration of an HDMI connector with a NULL vendor
+ * fails.
+ */
+static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       NULL, "Product",
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector with a NULL product
+ * fails.
+ */
+static void drm_test_connector_hdmi_init_null_product(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	int ret;
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", NULL,
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a valid, shorter than
+ * the max length, product name succeeds, and is stored padded with 0.
+ */
+static void drm_test_connector_hdmi_init_product_valid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
+		'P', 'r', 'o', 'd',
+	};
+	const char *product_name = "Prod";
+	int ret;
+
+	KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", product_name,
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_MEMEQ(test,
+			   priv->connector.hdmi.product,
+			   expected_product,
+			   sizeof(priv->connector.hdmi.product));
+}
+
+/*
+ * Test that the registration of a connector with a valid, at max
+ * length, product name succeeds, and is stored padded without any
+ * trailing \0.
+ */
+static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
+		'P', 'r', 'o', 'd', 'u', 'c', 't',
+		'P', 'r', 'o', 'd', 'u', 'c', 't',
+		'P', 'r',
+	};
+	const char *product_name = "ProductProductPr";
+	int ret;
+
+	KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", product_name,
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_MEMEQ(test,
+			   priv->connector.hdmi.product,
+			   expected_product,
+			   sizeof(priv->connector.hdmi.product));
+}
+
+/*
+ * Test that the registration of a connector with a product name larger
+ * than the maximum length fails.
+ */
+static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const char *product_name = "ProductProductProduct";
+	int ret;
+
+	KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       "Vendor", product_name,
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a vendor name smaller
+ * than the maximum length succeeds, and is stored padded with zeros.
+ */
+static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
+		'V', 'e', 'n', 'd',
+	};
+	const char *vendor_name = "Vend";
+	int ret;
+
+	KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       vendor_name, "Product",
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_MEMEQ(test,
+			   priv->connector.hdmi.vendor,
+			   expected_vendor,
+			   sizeof(priv->connector.hdmi.vendor));
+}
+
+/*
+ * Test that the registration of a connector with a vendor name at the
+ * maximum length succeeds, and is stored padded without the trailing
+ * zero.
+ */
+static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
+		'V', 'e', 'n', 'd', 'o', 'r',
+		'V', 'e',
+	};
+	const char *vendor_name = "VendorVe";
+	int ret;
+
+	KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       vendor_name, "Product",
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_MEMEQ(test,
+			   priv->connector.hdmi.vendor,
+			   expected_vendor,
+			   sizeof(priv->connector.hdmi.vendor));
+}
+
+/*
+ * Test that the registration of a connector with a vendor name larger
+ * than the maximum length fails.
+ */
+static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test)
+{
+	struct drm_connector_init_priv *priv = test->priv;
+	const char *vendor_name = "VendorVendor";
+	int ret;
+
+	KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
+
+	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+				       vendor_name, "Product",
+				       &dummy_funcs,
+				       &dummy_hdmi_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       &priv->ddc,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
+	KUNIT_EXPECT_LT(test, ret, 0);
+}
+
 /*
  * Test that the registration of a connector with an invalid maximum bpc
  * count fails.
@@ -499,6 +710,14 @@ static struct kunit_case drmm_connector_hdmi_init_tests[] = {
 	KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty),
 	KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb),
 	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
+	KUNIT_CASE(drm_test_connector_hdmi_init_null_product),
+	KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor),
+	KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact),
+	KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long),
+	KUNIT_CASE(drm_test_connector_hdmi_init_product_valid),
+	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact),
+	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long),
+	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid),
 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
 			 drm_connector_hdmi_init_type_valid_gen_params),
 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:22 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:22 +0100
Subject: [PATCH v7 36/36] drm/sun4i: hdmi: Switch to HDMI connector
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-36-8f4af575fce2@kernel.org>

The new HDMI connector infrastructure allows to remove some boilerplate,
especially to generate infoframes. Let's switch to it.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 80 ++++++++++++++++++++++------------
 1 file changed, 51 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index b7cf369b1906..8a9106a39f23 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -36,30 +36,24 @@
 #define drm_connector_to_sun4i_hdmi(c)		\
 	container_of_const(c, struct sun4i_hdmi, connector)
 
-static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
-					   struct drm_display_mode *mode)
+static int sun4i_hdmi_write_infoframe(struct drm_connector *connector,
+				      enum hdmi_infoframe_type type,
+				      const u8 *buffer, size_t len)
 {
-	struct hdmi_avi_infoframe frame;
-	u8 buffer[17];
-	int i, ret;
+	struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
+	int i;
 
-	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
-						       &hdmi->connector, mode);
-	if (ret < 0) {
-		DRM_ERROR("Failed to get infoframes from mode\n");
-		return ret;
+	if (type != HDMI_INFOFRAME_TYPE_AVI) {
+		drm_err(connector->dev,
+			"Unsupported infoframe type: %u\n", type);
+		return 0;
 	}
 
-	ret = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
-	if (ret < 0) {
-		DRM_ERROR("Failed to pack infoframes\n");
-		return ret;
-	}
-
-	for (i = 0; i < sizeof(buffer); i++)
+	for (i = 0; i < len; i++)
 		writeb(buffer[i], hdmi->base + SUN4I_HDMI_AVI_INFOFRAME_REG(i));
 
 	return 0;
+
 }
 
 static void sun4i_hdmi_disable(struct drm_encoder *encoder,
@@ -82,14 +76,18 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
 {
 	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
-	struct drm_display_info *display = &hdmi->connector.display_info;
+	struct drm_connector *connector = &hdmi->connector;
+	struct drm_display_info *display = &connector->display_info;
+	struct drm_connector_state *conn_state =
+		drm_atomic_get_new_connector_state(state, connector);
+	unsigned long long tmds_rate = conn_state->hdmi.tmds_char_rate;
 	unsigned int x, y;
 	u32 val = 0;
 
 	DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
 
-	clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
-	clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
+	clk_set_rate(hdmi->mod_clk, tmds_rate);
+	clk_set_rate(hdmi->tmds_clk, tmds_rate);
 
 	/* Set input sync enable */
 	writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC,
@@ -142,7 +140,8 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
 
 	clk_prepare_enable(hdmi->tmds_clk);
 
-	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
+	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
+
 	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
 	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
 	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
@@ -195,7 +194,7 @@ static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector,
 	enum drm_mode_status status;
 
 	status = sun4i_hdmi_connector_clock_valid(connector, mode,
-						  mode->clock * 1000);
+						  conn_state->hdmi.tmds_char_rate);
 	if (status != MODE_OK)
 		return -EINVAL;
 
@@ -206,8 +205,11 @@ static enum drm_mode_status
 sun4i_hdmi_connector_mode_valid(struct drm_connector *connector,
 				struct drm_display_mode *mode)
 {
-	return sun4i_hdmi_connector_clock_valid(connector, mode,
-						mode->clock * 1000);
+	unsigned long long rate =
+		drm_connector_hdmi_compute_mode_clock(mode, 8,
+						      HDMI_COLORSPACE_RGB);
+
+	return sun4i_hdmi_connector_clock_valid(connector, mode, rate);
 }
 
 static int sun4i_hdmi_get_modes(struct drm_connector *connector)
@@ -253,6 +255,11 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev)
 	return ddc;
 }
 
+static const struct drm_connector_hdmi_funcs sun4i_hdmi_hdmi_connector_funcs = {
+	.tmds_char_rate_valid	= sun4i_hdmi_connector_clock_valid,
+	.write_infoframe	= sun4i_hdmi_write_infoframe,
+};
+
 static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = {
 	.atomic_check	= sun4i_hdmi_connector_atomic_check,
 	.mode_valid	= sun4i_hdmi_connector_mode_valid,
@@ -274,11 +281,17 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	return connector_status_connected;
 }
 
+static void sun4i_hdmi_connector_reset(struct drm_connector *connector)
+{
+	drm_atomic_helper_connector_reset(connector);
+	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
+}
+
 static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
 	.detect			= sun4i_hdmi_connector_detect,
 	.fill_modes		= drm_helper_probe_single_connector_modes,
 	.destroy		= drm_connector_cleanup,
-	.reset			= drm_atomic_helper_connector_reset,
+	.reset			= sun4i_hdmi_connector_reset,
 	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
 };
@@ -637,10 +650,19 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &sun4i_hdmi_connector_helper_funcs);
-	ret = drm_connector_init_with_ddc(drm, &hdmi->connector,
-					  &sun4i_hdmi_connector_funcs,
-					  DRM_MODE_CONNECTOR_HDMIA,
-					  hdmi->ddc_i2c);
+	ret = drmm_connector_hdmi_init(drm, &hdmi->connector,
+				       /*
+					* NOTE: Those are likely to be
+					* wrong, but I couldn't find the
+					* actual ones in the BSP.
+					*/
+				       "AW", "HDMI",
+				       &sun4i_hdmi_connector_funcs,
+				       &sun4i_hdmi_hdmi_connector_funcs,
+				       DRM_MODE_CONNECTOR_HDMIA,
+				       hdmi->ddc_i2c,
+				       BIT(HDMI_COLORSPACE_RGB),
+				       8);
 	if (ret) {
 		dev_err(dev,
 			"Couldn't initialise the HDMI connector\n");

-- 
2.43.2



From megi at xff.cz  Thu Feb 22 10:18:46 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Thu, 22 Feb 2024 19:18:46 +0100
Subject: [PATCH 3/4] ASoC: sun50i-codec-analog: Enable jack detection on startup
In-Reply-To: <20240222181851.3398254-1-megi@xff.cz>
References: <20240222181851.3398254-1-megi@xff.cz>
Message-ID: <20240222181851.3398254-4-megi@xff.cz>

From: Arnaud Ferraris <arnaud.ferraris at collabora.com>

This commit adds the necessary setup to enable jack detection on startup
as well as the callback function enabling the microphone ADC when
headset bias is enabled. The microphone ADC is also disabled in suspend.

Signed-off-by: Arnaud Ferraris <arnaud.ferraris at collabora.com>
[Samuel: Moved MICADCEN setup to HBIAS event, added bias hooks]
Signed-off-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Ond?ej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun50i-codec-analog.c | 32 ++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index cedd4de42d1a..2081721a8ff2 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -116,8 +116,10 @@
 #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN	7
 
 #define SUN50I_ADDA_JACK_MIC_CTRL	0x1d
+#define SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN	7
 #define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN	6
 #define SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN	5
+#define SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN	4
 
 /* mixer controls */
 static const struct snd_kcontrol_new sun50i_a64_codec_mixer_controls[] = {
@@ -296,6 +298,19 @@ static const struct snd_kcontrol_new sun50i_codec_earpiece_switch[] = {
 			SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE, 1, 0),
 };
 
+static int sun50i_codec_hbias_event(struct snd_soc_dapm_widget *w,
+				    struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	u32 value = !!SND_SOC_DAPM_EVENT_ON(event);
+
+	regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
+			   BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN),
+			   value << SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN);
+
+	return 0;
+}
+
 static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
 	/* DAC */
 	SND_SOC_DAPM_DAC("Left DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL,
@@ -367,7 +382,8 @@ static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
 	/* Microphone Bias */
 	SND_SOC_DAPM_SUPPLY("HBIAS", SUN50I_ADDA_JACK_MIC_CTRL,
 			    SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN,
-			    0, NULL, 0),
+			    0, sun50i_codec_hbias_event,
+			    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
 	/* Mic input path */
 	SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN50I_ADDA_MIC2_CTRL,
@@ -474,14 +490,28 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
 static int sun50i_a64_codec_set_bias_level(struct snd_soc_component *component,
 					   enum snd_soc_bias_level level)
 {
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	int hbias;
+
 	switch (level) {
 	case SND_SOC_BIAS_OFF:
+		regmap_clear_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) |
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN));
+
 		regmap_set_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
 				BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		regmap_clear_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
 				   BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
+
+		hbias = snd_soc_dapm_get_pin_status(dapm, "HBIAS");
+		regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) |
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN),
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) |
+				   hbias << SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN);
 		break;
 	default:
 		break;
-- 
2.43.0



From megi at xff.cz  Thu Feb 22 10:18:45 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Thu, 22 Feb 2024 19:18:45 +0100
Subject: [PATCH 2/4] ASoC: sun8i-codec: Enable bus clock at STANDBY and higher bias
In-Reply-To: <20240222181851.3398254-1-megi@xff.cz>
References: <20240222181851.3398254-1-megi@xff.cz>
Message-ID: <20240222181851.3398254-3-megi@xff.cz>

From: Samuel Holland <samuel at sholland.org>

For codec variants that have a bus clock, that clock must be running to
receive interrupts. Since jack and mic accessory detection should work
even when no audio is playing, that means the bus clock should be
enabled any time the system is on.

Accomplish that by tying the bus clock to the runtime PM state, which is
then tied to the bias level not being OFF. Since the codec sets
idle_bias_on, bias will generally never be OFF. However, we can set
suspend_bias_off to maintain the power savings of gating the bus clock
during suspend, when we don't expect jack/accessory detection to work.

Signed-off-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Ond?ej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun8i-codec.c | 41 ++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 7b45ddffe990..2a46b96b03cc 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -177,12 +177,14 @@ struct sun8i_codec_aif {
 };
 
 struct sun8i_codec_quirks {
-	bool legacy_widgets	: 1;
-	bool lrck_inversion	: 1;
+	bool	bus_clock	: 1;
+	bool	legacy_widgets	: 1;
+	bool	lrck_inversion	: 1;
 };
 
 struct sun8i_codec {
 	struct regmap			*regmap;
+	struct clk			*clk_bus;
 	struct clk			*clk_module;
 	const struct sun8i_codec_quirks	*quirks;
 	struct sun8i_codec_aif		aifs[SUN8I_CODEC_NAIFS];
@@ -197,6 +199,14 @@ static int sun8i_codec_runtime_resume(struct device *dev)
 	struct sun8i_codec *scodec = dev_get_drvdata(dev);
 	int ret;
 
+	if (scodec->clk_bus) {
+		ret = clk_prepare_enable(scodec->clk_bus);
+		if (ret) {
+			dev_err(dev, "Failed to enable the bus clock\n");
+			return ret;
+		}
+	}
+
 	regcache_cache_only(scodec->regmap, false);
 
 	ret = regcache_sync(scodec->regmap);
@@ -215,6 +225,9 @@ static int sun8i_codec_runtime_suspend(struct device *dev)
 	regcache_cache_only(scodec->regmap, true);
 	regcache_mark_dirty(scodec->regmap);
 
+	if (scodec->clk_bus)
+		clk_disable_unprepare(scodec->clk_bus);
+
 	return 0;
 }
 
@@ -1277,6 +1290,7 @@ static const struct snd_soc_component_driver sun8i_soc_component = {
 	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
 	.probe			= sun8i_codec_component_probe,
 	.idle_bias_on		= 1,
+	.suspend_bias_off	= 1,
 	.endianness		= 1,
 };
 
@@ -1299,6 +1313,18 @@ static int sun8i_codec_probe(struct platform_device *pdev)
 	if (!scodec)
 		return -ENOMEM;
 
+	scodec->quirks = of_device_get_match_data(&pdev->dev);
+
+	platform_set_drvdata(pdev, scodec);
+
+	if (scodec->quirks->bus_clock) {
+		scodec->clk_bus = devm_clk_get(&pdev->dev, "bus");
+		if (IS_ERR(scodec->clk_bus)) {
+			dev_err(&pdev->dev, "Failed to get the bus clock\n");
+			return PTR_ERR(scodec->clk_bus);
+		}
+	}
+
 	scodec->clk_module = devm_clk_get(&pdev->dev, "mod");
 	if (IS_ERR(scodec->clk_module)) {
 		dev_err(&pdev->dev, "Failed to get the module clock\n");
@@ -1311,17 +1337,14 @@ static int sun8i_codec_probe(struct platform_device *pdev)
 		return PTR_ERR(base);
 	}
 
-	scodec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "bus", base,
-						   &sun8i_codec_regmap_config);
+	scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+					       &sun8i_codec_regmap_config);
 	if (IS_ERR(scodec->regmap)) {
 		dev_err(&pdev->dev, "Failed to create our regmap\n");
 		return PTR_ERR(scodec->regmap);
 	}
 
-	scodec->quirks = of_device_get_match_data(&pdev->dev);
-
-	platform_set_drvdata(pdev, scodec);
-
+	regcache_cache_only(scodec->regmap, true);
 	pm_runtime_enable(&pdev->dev);
 	if (!pm_runtime_enabled(&pdev->dev)) {
 		ret = sun8i_codec_runtime_resume(&pdev->dev);
@@ -1357,11 +1380,13 @@ static void sun8i_codec_remove(struct platform_device *pdev)
 }
 
 static const struct sun8i_codec_quirks sun8i_a33_quirks = {
+	.bus_clock	= true,
 	.legacy_widgets	= true,
 	.lrck_inversion	= true,
 };
 
 static const struct sun8i_codec_quirks sun50i_a64_quirks = {
+	.bus_clock	= true,
 };
 
 static const struct of_device_id sun8i_codec_of_match[] = {
-- 
2.43.0



From mripard at kernel.org  Thu Feb 22 10:13:54 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:13:54 +0100
Subject: [PATCH v7 08/36] drm/connector: hdmi: Create an HDMI sub-state
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-8-8f4af575fce2@kernel.org>

The next features we will need to share across drivers will need to
store some parameters for drivers to use, such as the selected output
format.

Let's create a new connector sub-state dedicated to HDMI controllers,
that will eventually store everything we need.

Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c | 35 +++++++++++++++++++++++++++++++
 include/drm/drm_atomic_state_helper.h     |  4 ++++
 include/drm/drm_connector.h               |  7 +++++++
 3 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 519228eb1095..7ad1dffe66d9 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -571,6 +571,22 @@ void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
 
+/**
+ * __drm_atomic_helper_connector_hdmi_reset() - Initializes all HDMI @drm_connector_state resources
+ * @connector: DRM connector
+ * @new_state: connector state to reset
+ *
+ * Initializes all HDMI resources from a @drm_connector_state without
+ * actually allocating it. This is useful for HDMI drivers, in
+ * combination with __drm_atomic_helper_connector_reset() or
+ * drm_atomic_helper_connector_reset().
+ */
+void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
+					      struct drm_connector_state *new_state)
+{
+}
+EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
+
 /**
  * drm_atomic_helper_connector_tv_check - Validate an analog TV connector state
  * @connector: DRM Connector
@@ -620,6 +636,25 @@ int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
 
+/**
+ * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
+ * @connector: DRM Connector
+ * @state: the DRM State object
+ *
+ * Provides a default connector state check handler for HDMI connectors.
+ * Checks that a desired connector update is valid, and updates various
+ * fields of derived state.
+ *
+ * RETURNS:
+ * Zero on success, or an errno code otherwise.
+ */
+int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
+					   struct drm_atomic_state *state)
+{
+	return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
+
 /**
  * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
  * @connector: connector object
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index b9740edb2658..d59d2b3aef9a 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -71,7 +71,11 @@ void __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_
 void __drm_atomic_helper_connector_reset(struct drm_connector *connector,
 					 struct drm_connector_state *conn_state);
 void drm_atomic_helper_connector_reset(struct drm_connector *connector);
+void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
+					      struct drm_connector_state *new_state);
 void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector);
+int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
+					   struct drm_atomic_state *state);
 int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
 					 struct drm_atomic_state *state);
 void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 4491c4c2fb6e..000a2a156619 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1031,6 +1031,13 @@ struct drm_connector_state {
 	 * DRM blob property for HDR output metadata
 	 */
 	struct drm_property_blob *hdr_output_metadata;
+
+	/**
+	 * @hdmi: HDMI-related variable and properties. Filled by
+	 * @drm_atomic_helper_connector_hdmi_check().
+	 */
+	struct {
+	} hdmi;
 };
 
 /**

-- 
2.43.2



From robh at kernel.org  Thu Feb 22 10:24:30 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 12:24:30 -0600
Subject: [PATCH v3 5/7] dt-bindings: remoteproc: Add compatibility for
 TEE support
In-Reply-To: <20240214172127.1022199-6-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <20240214172127.1022199-6-arnaud.pouliquen@foss.st.com>
Message-ID: <170862626977.3652711.10744856298270939089.robh@kernel.org>


On Wed, 14 Feb 2024 18:21:25 +0100, Arnaud Pouliquen wrote:
> The "st,stm32mp1-m4-tee" compatible is utilized in a system configuration
> where the Cortex-M4 firmware is loaded by the Trusted execution Environment
> (TEE).
> For instance, this compatible is used in both the Linux and OP-TEE
> device-tree:
> - In OP-TEE, a node is defined in the device tree with the
>   st,stm32mp1-m4-tee to support signed remoteproc firmware.
>   Based on DT properties, OP-TEE authenticates, loads, starts, and stops
>   the firmware.
> - On Linux, when the compatibility is set, the Cortex-M resets should not
>   be declared in the device tree.
> 
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
> ---
> V1 to V2 updates
> - update "st,stm32mp1-m4" compatible description to generalize
> - remove the 'reset-names' requirement in one conditional branch, as the
>   property is already part of the condition test.
> ---
>  .../bindings/remoteproc/st,stm32-rproc.yaml   | 51 ++++++++++++++++---
>  1 file changed, 43 insertions(+), 8 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From jernej.skrabec at gmail.com  Thu Feb 22 10:26:08 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 19:26:08 +0100
Subject: [PATCH v5 1/7] soc: sunxi: sram: export register 0 for THS on H616
In-Reply-To: <20240219153639.179814-2-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
 <20240219153639.179814-2-andre.przywara@arm.com>
Message-ID: <2717467.mvXUDI8C0e@jernej-laptop>

Dne ponedeljek, 19. februar 2024 ob 16:36:33 CET je Andre Przywara napisal(a):
> The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
> in the SRAM control block. If bit 16 is set (the reset value), the
> temperature readings of the THS are way off, leading to reports about
> 200C, at normal ambient temperatures. Clearing this bits brings the
> reported values down to the expected values.
> The BSP code clears this bit in firmware (U-Boot), and has an explicit
> comment about this, but offers no real explanation.
> 
> Experiments in U-Boot show that register 0x0 has no effect on the SRAM C
> visibility: all tested bit settings still allow full read and write
> access by the CPU to the whole of SRAM C. Only bit 24 of the register at
> offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling
> the THS switch functionality as an SRAM region would not reflect reality.
> 
> Since we should not rely on firmware settings, allow other code (the THS
> driver) to access this register, by exporting it through the already
> existing regmap. This mimics what we already do for the LDO control and
> the EMAC register.
> 
> To avoid concurrent accesses to the same register at the same time, by
> the SRAM switch code and the regmap code, use the same lock to protect
> the access. The regmap subsystem allows to use an existing lock, so we
> just need to hook in there.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

I guess this one goes through sunxi tree, right?

Best regards,
Jernej

> ---
>  drivers/soc/sunxi/sunxi_sram.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
> index 4458b2e0562b0..6eb6cf06278e6 100644
> --- a/drivers/soc/sunxi/sunxi_sram.c
> +++ b/drivers/soc/sunxi/sunxi_sram.c
> @@ -287,6 +287,7 @@ EXPORT_SYMBOL(sunxi_sram_release);
>  struct sunxi_sramc_variant {
>  	int num_emac_clocks;
>  	bool has_ldo_ctrl;
> +	bool has_ths_offset;
>  };
>  
>  static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
> @@ -308,8 +309,10 @@ static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
>  
>  static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
>  	.num_emac_clocks = 2,
> +	.has_ths_offset = true,
>  };
>  
> +#define SUNXI_SRAM_THS_OFFSET_REG	0x0
>  #define SUNXI_SRAM_EMAC_CLOCK_REG	0x30
>  #define SUNXI_SYS_LDO_CTRL_REG		0x150
>  
> @@ -318,6 +321,8 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
>  {
>  	const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
>  
> +	if (reg == SUNXI_SRAM_THS_OFFSET_REG && variant->has_ths_offset)
> +		return true;
>  	if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG &&
>  	    reg <  SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
>  		return true;
> @@ -327,6 +332,20 @@ static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
>  	return false;
>  }
>  
> +static void sunxi_sram_lock(void *_lock)
> +{
> +	spinlock_t *lock = _lock;
> +
> +	spin_lock(lock);
> +}
> +
> +static void sunxi_sram_unlock(void *_lock)
> +{
> +	spinlock_t *lock = _lock;
> +
> +	spin_unlock(lock);
> +}
> +
>  static struct regmap_config sunxi_sram_regmap_config = {
>  	.reg_bits       = 32,
>  	.val_bits       = 32,
> @@ -336,6 +355,9 @@ static struct regmap_config sunxi_sram_regmap_config = {
>  	/* other devices have no business accessing other registers */
>  	.readable_reg	= sunxi_sram_regmap_accessible_reg,
>  	.writeable_reg	= sunxi_sram_regmap_accessible_reg,
> +	.lock		= sunxi_sram_lock,
> +	.unlock		= sunxi_sram_unlock,
> +	.lock_arg	= &sram_lock,
>  };
>  
>  static int __init sunxi_sram_probe(struct platform_device *pdev)
> 






From jernej.skrabec at gmail.com  Thu Feb 22 10:27:49 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 19:27:49 +0100
Subject: [PATCH v5 7/7] arm64: dts: allwinner: h616: Add thermal sensor and zones
In-Reply-To: <20240219153639.179814-8-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
 <20240219153639.179814-8-andre.przywara@arm.com>
Message-ID: <6017340.lOV4Wx5bFT@jernej-laptop>

Dne ponedeljek, 19. februar 2024 ob 16:36:39 CET je Andre Przywara napisal(a):
> From: Martin Botka <martin.botka at somainline.org>
> 
> There are four thermal sensors:
> - CPU
> - GPU
> - VE
> - DRAM
> 
> Add the thermal sensor configuration and the thermal zones.
> 
> Signed-off-by: Martin Botka <martin.botka at somainline.org>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 88 +++++++++++++++++++
>  1 file changed, 88 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> index 12ffabc79bcde..7c7d7c285505c 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> @@ -9,6 +9,7 @@
>  #include <dt-bindings/clock/sun6i-rtc.h>
>  #include <dt-bindings/reset/sun50i-h616-ccu.h>
>  #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
> +#include <dt-bindings/thermal/thermal.h>
>  
>  / {
>  	interrupt-parent = <&gic>;
> @@ -138,6 +139,10 @@ sid: efuse at 3006000 {
>  			reg = <0x03006000 0x1000>;
>  			#address-cells = <1>;
>  			#size-cells = <1>;
> +
> +			ths_calibration: thermal-sensor-calibration at 14 {
> +				reg = <0x14 0x8>;
> +			};
>  		};
>  
>  		watchdog: watchdog at 30090a0 {
> @@ -517,6 +522,19 @@ mdio0: mdio {
>  			};
>  		};
>  
> +		ths: thermal-sensor at 5070400 {
> +			compatible = "allwinner,sun50i-h616-ths";
> +			reg = <0x05070400 0x400>;
> +			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&ccu CLK_BUS_THS>;
> +			clock-names = "bus";
> +			resets = <&ccu RST_BUS_THS>;
> +			nvmem-cells = <&ths_calibration>;
> +			nvmem-cell-names = "calibration";
> +			allwinner,sram = <&syscon>;
> +			#thermal-sensor-cells = <1>;
> +		};
> +
>  		usbotg: usb at 5100000 {
>  			compatible = "allwinner,sun50i-h616-musb",
>  				     "allwinner,sun8i-h3-musb";
> @@ -761,4 +779,74 @@ r_rsb: rsb at 7083000 {
>  			#size-cells = <0>;
>  		};
>  	};
> +
> +	thermal-zones {
> +		cpu-thermal {
> +			polling-delay-passive = <500>;
> +			polling-delay = <1000>;
> +			thermal-sensors = <&ths 2>;
> +			sustainable-power = <1000>;
> +
> +			trips {
> +				cpu_threshold: cpu-trip-0 {
> +					temperature = <60000>;
> +					type = "passive";
> +					hysteresis = <0>;
> +				};
> +				cpu_target: cpu-trip-1 {
> +					temperature = <70000>;
> +					type = "passive";
> +					hysteresis = <0>;
> +				};
> +				cpu_critical: cpu-trip-2 {
> +					temperature = <110000>;
> +					type = "critical";
> +					hysteresis = <0>;
> +				};
> +			};
> +		};
> +
> +		gpu-thermal {
> +			polling-delay-passive = <500>;
> +			polling-delay = <1000>;
> +			thermal-sensors = <&ths 0>;
> +			sustainable-power = <1100>;
> +
> +			trips {
> +				gpu_temp_critical: gpu-trip-0 {
> +					temperature = <110000>;
> +					type = "critical";
> +					hysteresis = <0>;
> +				};
> +			};
> +		};
> +
> +		ve-thermal {
> +			polling-delay-passive = <0>;
> +			polling-delay = <0>;
> +			thermal-sensors = <&ths 1>;
> +
> +			trips {
> +				ve_temp_critical: ve-trip-0 {
> +					temperature = <110000>;
> +					type = "critical";
> +					hysteresis = <0>;
> +				};
> +			};
> +		};
> +
> +		ddr-thermal {
> +			polling-delay-passive = <0>;
> +			polling-delay = <0>;
> +			thermal-sensors = <&ths 3>;
> +
> +			trips {
> +				ddr_temp_critical: ddr-trip-0 {
> +					temperature = <110000>;
> +					type = "critical";
> +					hysteresis = <0>;
> +				};
> +			};
> +		};
> +	};
>  };
> 






From hdegoede at redhat.com  Thu Feb 22 10:33:15 2024
From: hdegoede at redhat.com (Hans de Goede)
Date: Thu, 22 Feb 2024 19:33:15 +0100
Subject: [PATCH 1/2] devm-helpers: Add resource managed version of mutex
 init
In-Reply-To: <03e62bcf-137c-4947-8f34-0cbfcba92a30@intel.com>
References: <20240222145838.12916-1-kabel@kernel.org>
 <03e62bcf-137c-4947-8f34-0cbfcba92a30@intel.com>
Message-ID: <7013bf9e-2663-4613-ae61-61872e81355b@redhat.com>

Hi,

On 2/22/24 17:44, Matthew Auld wrote:
> On 22/02/2024 14:58, Marek Beh?n wrote:
>> A few drivers are doing resource-managed mutex initialization by
>> implementing ad-hoc one-liner mutex dropping functions and using them
>> with devm_add_action_or_reset(). Help drivers avoid these repeated
>> one-liners by adding managed version of mutex initialization.

<snip>

>> index 74891802200d..70640fb96117 100644
>> --- a/include/linux/devm-helpers.h
>> +++ b/include/linux/devm-helpers.h
>> @@ -24,6 +24,8 @@
>> ?? */
>> ? ? #include <linux/device.h>
>> +#include <linux/kconfig.h>
>> +#include <linux/mutex.h>
>> ? #include <linux/workqueue.h>
>> ? ? static inline void devm_delayed_work_drop(void *res)
>> @@ -76,4 +78,34 @@ static inline int devm_work_autocancel(struct device *dev,
>> ????? return devm_add_action(dev, devm_work_drop, w);
>> ? }
>> ? +static inline void devm_mutex_drop(void *res)
>> +{
>> +??? mutex_destroy(res);
>> +}
>> +
>> +/**
>> + * devm_mutex_init - Resource managed mutex initialization
>> + * @dev:??? Device which lifetime mutex is bound to
>> + * @lock:??? Mutex to be initialized (and automatically destroyed)
>> + *
>> + * Initialize mutex which is automatically destroyed when driver is detached.
>> + * A few drivers initialize mutexes which they want destroyed before driver is
>> + * detached, for debugging purposes.
>> + * devm_mutex_init() can be used to omit the explicit mutex_destroy() call when
>> + * driver is detached.
>> + */
>> +static inline int devm_mutex_init(struct device *dev, struct mutex *lock)
>> +{
>> +??? mutex_init(lock);
> 
> Do you know if this this needs __always_inline? The static lockdep key in mutex_init() should be
> different for each caller class. See c21f11d182c2 ("drm: fix drmm_mutex_init()").

That is a very good point. I believe that this should mirror mutex_init() and
the actual static inline function should be __devm_mutex_init() which takes
the key as extra argument (and calls __mutex_init()) and then make
devm_mutex_init() itself a macro mirroring the mutex_init() macro.

Regards,

Hans






> 
>> +
>> +??? /*
>> +???? * mutex_destroy() is an empty function if CONFIG_DEBUG_MUTEXES is
>> +???? * disabled. No need to allocate an action in that case.
>> +???? */
>> +??? if (IS_ENABLED(CONFIG_DEBUG_MUTEXES))
>> +??????? return devm_add_action_or_reset(dev, devm_mutex_drop, lock);
>> +??? else
>> +??????? return 0;
>> +}
>> +
>> ? #endif
> 



From fancer.lancer at gmail.com  Thu Feb 22 10:13:03 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:13:03 +0300
Subject: [PATCH v5 18/20] EDAC/synopsys: Unify CSRs macro declarations
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-19-fancer.lancer@gmail.com>

Originally the device CSR macros were supposed to be defined following the
next local convention: first CSR offsets are listed, then their fields and
flags are described in the same order; CSRs offset macros are supposed to
have _OFST suffix; ECC-related macros shall have ECC_ prefix, generic
DDR-related macros - DDR_ prefix. After all the years the driver has been
living in kernel the CSRs macros have turned to be partly deviated away
from the denoted convention. Fix all the related inconsistencies: move
several CSRs offset macros to be defined before the CSRs fields and flags
macros; replace OFFSET suffix with OFST; replace DDRC_ prefix with DDR_
and ECC_ with DDR_ where it's appropriate; group DDR_MSTR and ECC_CTRL
(ECC_CLR) sibling fields macros together and make sure their prefixes
match to the CSRs offset macros. In addition to that drop _MASK suffix
from the macros which aren't used as masks and add ZYNQMP_ prefix to the
ZYNQMP-specific macros to distinguish them from the generic Synopsys
memory controller macros.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>

---

Changelog v4:
- This is a new patch collected from the rest of the series to simplify
  the review process.
---
 drivers/edac/synopsys_edac.c | 134 +++++++++++++++++------------------
 1 file changed, 66 insertions(+), 68 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 1cd02859e2b9..1de9f3f86d5a 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -77,20 +77,34 @@
 #define ECC_POISON0_OFST		0xB8
 #define ECC_POISON1_OFST		0xBC
 
-#define ECC_ADDRMAP0_OFFSET		0x200
-
-/* Control register bitfield definitions */
-#define ECC_CTRL_CLR_CE_ERR		BIT(0)
-#define ECC_CTRL_CLR_UE_ERR		BIT(1)
-#define ECC_CTRL_CLR_CE_ERRCNT		BIT(2)
-#define ECC_CTRL_CLR_UE_ERRCNT		BIT(3)
-
-/* DDR Control Register width definitions  */
+/* DDR Address Map Registers */
+#define DDR_ADDRMAP0_OFST		0x200
+
+/* DDR Software Control Register */
+#define DDR_SWCTL			0x320
+
+/* ZynqMP DDR QOS Registers */
+#define ZYNQMP_DDR_QOS_IRQ_STAT_OFST	0x20200
+#define ZYNQMP_DDR_QOS_IRQ_EN_OFST	0x20208
+#define ZYNQMP_DDR_QOS_IRQ_DB_OFST	0x2020C
+
+/* DDR Master register definitions */
+#define DDR_MSTR_DEV_CFG_MASK		0xC0000000
+#define DDR_MSTR_DEV_CFG_SHIFT		30
+#define DDR_MSTR_DEV_X4			0
+#define DDR_MSTR_DEV_X8			1
+#define DDR_MSTR_DEV_X16		2
+#define DDR_MSTR_DEV_X32		3
 #define DDR_MSTR_BUSWIDTH_MASK		0x3000
 #define DDR_MSTR_BUSWIDTH_SHIFT		12
-#define DDRCTL_EWDTH_16			2
-#define DDRCTL_EWDTH_32			1
-#define DDRCTL_EWDTH_64			0
+#define DDR_MSTR_BUSWIDTH_16		2
+#define DDR_MSTR_BUSWIDTH_32		1
+#define DDR_MSTR_BUSWIDTH_64		0
+#define DDR_MSTR_MEM_LPDDR4		0x20
+#define DDR_MSTR_MEM_DDR4		0x10
+#define DDR_MSTR_MEM_LPDDR3		0x8
+#define DDR_MSTR_MEM_DDR2		0x4
+#define DDR_MSTR_MEM_DDR3		0x1
 
 /* ECC CFG0 register definitions */
 #define ECC_CFG0_MODE_MASK		0x7
@@ -103,23 +117,19 @@
 #define ECC_STAT_CECNT_SHIFT		8
 #define ECC_STAT_BITNUM_MASK		0x7F
 
+/* ECC control/clear register definitions */
+#define ECC_CTRL_CLR_CE_ERR		BIT(0)
+#define ECC_CTRL_CLR_UE_ERR		BIT(1)
+#define ECC_CTRL_CLR_CE_ERRCNT		BIT(2)
+#define ECC_CTRL_CLR_UE_ERRCNT		BIT(3)
+#define ECC_CTRL_EN_CE_IRQ		BIT(8)
+#define ECC_CTRL_EN_UE_IRQ		BIT(9)
+
 /* ECC error count register definitions */
 #define ECC_ERRCNT_UECNT_MASK		0xFFFF0000
 #define ECC_ERRCNT_UECNT_SHIFT		16
 #define ECC_ERRCNT_CECNT_MASK		0xFFFF
 
-/* DDR QOS Interrupt register definitions */
-#define DDR_QOS_IRQ_STAT_OFST		0x20200
-#define DDR_QOSUE_MASK			0x4
-#define	DDR_QOSCE_MASK			0x2
-#define	ECC_CE_UE_INTR_MASK		0x6
-#define DDR_QOS_IRQ_EN_OFST		0x20208
-#define DDR_QOS_IRQ_DB_OFST		0x2020C
-
-/* DDR QOS Interrupt register definitions */
-#define DDR_UE_MASK			BIT(9)
-#define DDR_CE_MASK			BIT(8)
-
 /* ECC Corrected Error Register Mask and Shifts*/
 #define ECC_CEADDR0_RW_MASK		0x3FFFF
 #define ECC_CEADDR0_RNK_MASK		BIT(24)
@@ -141,28 +151,11 @@
 #define ECC_POISON1_ROW_SHIFT		0
 #define ECC_POISON1_ROW_MASK		0x3FFFF
 
-/* DDR Memory type defines */
-#define MEM_TYPE_DDR3			0x1
-#define MEM_TYPE_LPDDR3			0x8
-#define MEM_TYPE_DDR2			0x4
-#define MEM_TYPE_DDR4			0x10
-#define MEM_TYPE_LPDDR4			0x20
-
-/* DDRC Software control register */
-#define DDRC_SWCTL			0x320
-
 /* DDRC ECC CE & UE poison mask */
 #define ECC_CEPOISON_MASK		0x3
 #define ECC_UEPOISON_MASK		0x1
 
-/* DDRC Device config masks */
-#define DDRC_MSTR_CFG_MASK		0xC0000000
-#define DDRC_MSTR_CFG_SHIFT		30
-#define DDRC_MSTR_CFG_X4_MASK		0x0
-#define DDRC_MSTR_CFG_X8_MASK		0x1
-#define DDRC_MSTR_CFG_X16_MASK		0x2
-#define DDRC_MSTR_CFG_X32_MASK		0x3
-
+/* DDRC Device config shifts/masks */
 #define DDR_MAX_ROW_SHIFT		18
 #define DDR_MAX_COL_SHIFT		14
 #define DDR_MAX_BANK_SHIFT		3
@@ -215,6 +208,11 @@
 
 #define RANK_B0_BASE			6
 
+/* ZynqMP DDR QOS Interrupt register definitions */
+#define ZYNQMP_DDR_QOS_UE_MASK		0x4
+#define ZYNQMP_DDR_QOS_CE_MASK		0x2
+#define ZYNQMP_DDR_QOS_IRQ_MASK		0x6
+
 /**
  * struct ecc_error_info - ECC error log information.
  * @row:	Row number.
@@ -397,8 +395,8 @@ static void enable_intr(struct synps_edac_priv *priv)
 
 	/* Enable UE/CE Interrupts */
 	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) {
-		writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
-		       priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
+		writel(ZYNQMP_DDR_QOS_UE_MASK | ZYNQMP_DDR_QOS_CE_MASK,
+		       priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_EN_OFST);
 
 		return;
 	}
@@ -409,7 +407,7 @@ static void enable_intr(struct synps_edac_priv *priv)
 	 * IRQs Enable/Disable flags have been available since v3.10a.
 	 * This is noop for the older controllers.
 	 */
-	writel(DDR_UE_MASK | DDR_CE_MASK,
+	writel(ECC_CTRL_EN_CE_IRQ | ECC_CTRL_EN_UE_IRQ,
 	       priv->baseaddr + ECC_CLR_OFST);
 
 	spin_unlock_irqrestore(&priv->reglock, flags);
@@ -421,8 +419,8 @@ static void disable_intr(struct synps_edac_priv *priv)
 
 	/* Disable UE/CE Interrupts */
 	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) {
-		writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
-		       priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
+		writel(ZYNQMP_DDR_QOS_UE_MASK | ZYNQMP_DDR_QOS_CE_MASK,
+		       priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_DB_OFST);
 
 		return;
 	}
@@ -450,9 +448,9 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
 	priv = mci->pvt_info;
 
 	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) {
-		regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
-		regval &= (DDR_QOSCE_MASK | DDR_QOSUE_MASK);
-		if (!(regval & ECC_CE_UE_INTR_MASK))
+		regval = readl(priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_STAT_OFST);
+		regval &= (ZYNQMP_DDR_QOS_CE_MASK | ZYNQMP_DDR_QOS_UE_MASK);
+		if (!(regval & ZYNQMP_DDR_QOS_IRQ_MASK))
 			return IRQ_NONE;
 	}
 
@@ -463,7 +461,7 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
 	handle_error(mci, &priv->stat);
 
 	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS)
-		writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
+		writel(regval, priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_STAT_OFST);
 
 	return IRQ_HANDLED;
 }
@@ -482,18 +480,18 @@ static enum dev_type synps_get_dtype(const void __iomem *base)
 	u32 regval;
 
 	regval = readl(base + DDR_MSTR_OFST);
-	if (!(regval & MEM_TYPE_DDR4))
+	if (!(regval & DDR_MSTR_MEM_DDR4))
 		return DEV_UNKNOWN;
 
-	regval = (regval & DDRC_MSTR_CFG_MASK) >> DDRC_MSTR_CFG_SHIFT;
+	regval = (regval & DDR_MSTR_DEV_CFG_MASK) >> DDR_MSTR_DEV_CFG_SHIFT;
 	switch (regval) {
-	case DDRC_MSTR_CFG_X4_MASK:
+	case DDR_MSTR_DEV_X4:
 		return DEV_X4;
-	case DDRC_MSTR_CFG_X8_MASK:
+	case DDR_MSTR_DEV_X8:
 		return DEV_X8;
-	case DDRC_MSTR_CFG_X16_MASK:
+	case DDR_MSTR_DEV_X16:
 		return DEV_X16;
-	case DDRC_MSTR_CFG_X32_MASK:
+	case DDR_MSTR_DEV_X32:
 		return DEV_X32;
 	}
 
@@ -547,11 +545,11 @@ static enum mem_type synps_get_mtype(const void __iomem *base)
 
 	memtype = readl(base + DDR_MSTR_OFST);
 
-	if ((memtype & MEM_TYPE_DDR3) || (memtype & MEM_TYPE_LPDDR3))
+	if ((memtype & DDR_MSTR_MEM_DDR3) || (memtype & DDR_MSTR_MEM_LPDDR3))
 		mt = MEM_DDR3;
-	else if (memtype & MEM_TYPE_DDR2)
+	else if (memtype & DDR_MSTR_MEM_DDR2)
 		mt = MEM_RDDR2;
-	else if ((memtype & MEM_TYPE_LPDDR4) || (memtype & MEM_TYPE_DDR4))
+	else if ((memtype & DDR_MSTR_MEM_LPDDR4) || (memtype & DDR_MSTR_MEM_DDR4))
 		mt = MEM_DDR4;
 	else
 		mt = MEM_EMPTY;
@@ -756,12 +754,12 @@ static ssize_t inject_data_poison_store(struct device *dev,
 	struct mem_ctl_info *mci = to_mci(dev);
 	struct synps_edac_priv *priv = mci->pvt_info;
 
-	writel(0, priv->baseaddr + DDRC_SWCTL);
+	writel(0, priv->baseaddr + DDR_SWCTL);
 	if (strncmp(data, "CE", 2) == 0)
 		writel(ECC_CEPOISON_MASK, priv->baseaddr + ECC_CFG1_OFST);
 	else
 		writel(ECC_UEPOISON_MASK, priv->baseaddr + ECC_CFG1_OFST);
-	writel(1, priv->baseaddr + DDRC_SWCTL);
+	writel(1, priv->baseaddr + DDR_SWCTL);
 
 	return count;
 }
@@ -878,8 +876,8 @@ static void setup_column_address_map(struct synps_edac_priv *priv, u32 *addrmap)
 	priv->col_shift[9] = (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) ==
 			COL_MAX_VAL_MASK) ? 0 : (((addrmap[3] >> 24) &
 					COL_MAX_VAL_MASK) + COL_B9_BASE);
-	if (width == DDRCTL_EWDTH_64) {
-		if (memtype & MEM_TYPE_LPDDR3) {
+	if (width == DDR_MSTR_BUSWIDTH_64) {
+		if (memtype & DDR_MSTR_MEM_LPDDR3) {
 			priv->col_shift[10] = ((addrmap[4] &
 				COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 :
 				((addrmap[4] & COL_MAX_VAL_MASK) +
@@ -898,8 +896,8 @@ static void setup_column_address_map(struct synps_edac_priv *priv, u32 *addrmap)
 				(((addrmap[4] >> 8) & COL_MAX_VAL_MASK) +
 				 COL_B11_BASE);
 		}
-	} else if (width == DDRCTL_EWDTH_32) {
-		if (memtype & MEM_TYPE_LPDDR3) {
+	} else if (width == DDR_MSTR_BUSWIDTH_32) {
+		if (memtype & DDR_MSTR_MEM_LPDDR3) {
 			priv->col_shift[10] = (((addrmap[3] >> 24) &
 				COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 :
 				(((addrmap[3] >> 24) & COL_MAX_VAL_MASK) +
@@ -919,7 +917,7 @@ static void setup_column_address_map(struct synps_edac_priv *priv, u32 *addrmap)
 				 COL_B10_BASE);
 		}
 	} else {
-		if (memtype & MEM_TYPE_LPDDR3) {
+		if (memtype & DDR_MSTR_MEM_LPDDR3) {
 			priv->col_shift[10] = (((addrmap[3] >> 16) &
 				COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 :
 				(((addrmap[3] >> 16) & COL_MAX_VAL_MASK) +
@@ -994,7 +992,7 @@ static void setup_address_map(struct synps_edac_priv *priv)
 	for (index = 0; index < 12; index++) {
 		u32 addrmap_offset;
 
-		addrmap_offset = ECC_ADDRMAP0_OFFSET + (index * 4);
+		addrmap_offset = DDR_ADDRMAP0_OFST + (index * 4);
 		addrmap[index] = readl(priv->baseaddr + addrmap_offset);
 	}
 
-- 
2.43.0



From fancer.lancer at gmail.com  Thu Feb 22 10:13:02 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:13:02 +0300
Subject: [PATCH v5 17/20] EDAC/synopsys: Drop unused platform-specific setup API
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-18-fancer.lancer@gmail.com>

The driver now works with the Synopsys DW uMCTL2 DDRC IP-core-based
devices only (Xilinx Zynq A05 DDRC support has been moved to the separate
driver). All the currently available IP-core revisions have got almost the
same ECC and main part of the DDR-config CSRs map. Thus there is no point
in supporting the no longer used internal abstraction layer like the
callbacks responsible for getting the ECC errors info, memory and device
types, ECC state. All of that data can be retrieved in the same way from
all the Synopys DW uMCTL2 DDR controller versions. Similarly there is no
longer need in the DDR_ECC_INTR_SUPPORT and DDR_ECC_DATA_POISON_SUPPORT
quirk flags since DW uMCTL2 always supports IRQs and data poisoning (as
long as the ECC is supported). Drop that infrastructure for good then.

While at it move the module device table to being defined at the bottom of
the file, above the platform driver descriptor definition.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>

---

Changelog v2:
- Drop the no longer used "priv" pointer from the mc_init() function.
  (@tbot)
---
 drivers/edac/synopsys_edac.c | 192 ++++++++++-------------------------
 1 file changed, 51 insertions(+), 141 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 6ea1eaaa7d6f..1cd02859e2b9 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -30,9 +30,7 @@
 #define SYNPS_EDAC_MOD_VER		"1"
 
 /* DDR ECC Quirks */
-#define DDR_ECC_INTR_SUPPORT		BIT(0)
-#define DDR_ECC_DATA_POISON_SUPPORT	BIT(1)
-#define SYNPS_ZYNQMP_IRQ_REGS		BIT(2)
+#define SYNPS_ZYNQMP_IRQ_REGS		BIT(0)
 
 /* Synopsys DDR memory controller registers that are relevant to ECC */
 
@@ -280,28 +278,20 @@ struct synps_edac_priv {
 };
 
 /**
- * struct synps_platform_data -  synps platform data structure.
- * @get_error_info:	Get EDAC error info.
- * @get_mtype:		Get mtype.
- * @get_dtype:		Get dtype.
- * @get_ecc_state:	Get ECC state.
- * @quirks:		To differentiate IPs.
+ * struct synps_platform_data - Synopsys uMCTL2 DDRC platform data.
+ * @quirks:	IP-core specific quirks.
  */
 struct synps_platform_data {
-	int (*get_error_info)(struct synps_edac_priv *priv);
-	enum mem_type (*get_mtype)(const void __iomem *base);
-	enum dev_type (*get_dtype)(const void __iomem *base);
-	bool (*get_ecc_state)(void __iomem *base);
-	int quirks;
+	u32 quirks;
 };
 
 /**
- * zynqmp_get_error_info - Get the current ECC error info.
+ * synps_get_error_info - Get the current ECC error info.
  * @priv:	DDR memory controller private instance data.
  *
  * Return: one if there is no error otherwise returns zero.
  */
-static int zynqmp_get_error_info(struct synps_edac_priv *priv)
+static int synps_get_error_info(struct synps_edac_priv *priv)
 {
 	struct synps_ecc_status *p;
 	u32 regval, clearval;
@@ -375,17 +365,11 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 
 	if (p->ce_cnt) {
 		pinf = &p->ceinfo;
-		if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
-			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "Row %d Col %d Bank %d Bank Group %d Bit %d Data 0x%08x",
-				 pinf->row, pinf->col, pinf->bank, pinf->bankgrp,
-				 pinf->bitpos, pinf->data);
-		} else {
-			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "Row %d Bank %d Col %d Bit: %d Data: 0x%08x",
-				 pinf->row, pinf->bank, pinf->col,
-				 pinf->bitpos, pinf->data);
-		}
+
+		snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
+			 "Row %d Col %d Bank %d Bank Group %d Bit %d Data 0x%08x",
+			 pinf->row, pinf->col, pinf->bank, pinf->bankgrp,
+			 pinf->bitpos, pinf->data);
 
 		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
 				     p->ce_cnt, 0, 0, 0, 0, 0, -1,
@@ -394,15 +378,10 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 
 	if (p->ue_cnt) {
 		pinf = &p->ueinfo;
-		if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
-			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "Row %d Col %d Bank %d Bank Group %d",
-				 pinf->row, pinf->col, pinf->bank, pinf->bankgrp);
-		} else {
-			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "Row %d Bank %d Col %d",
-				 pinf->row, pinf->bank, pinf->col);
-		}
+
+		snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
+			 "Row %d Col %d Bank %d Bank Group %d",
+			 pinf->row, pinf->col, pinf->bank, pinf->bankgrp);
 
 		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
 				     p->ue_cnt, 0, 0, 0, 0, 0, -1,
@@ -464,13 +443,11 @@ static void disable_intr(struct synps_edac_priv *priv)
  */
 static irqreturn_t intr_handler(int irq, void *dev_id)
 {
-	const struct synps_platform_data *p_data;
 	struct mem_ctl_info *mci = dev_id;
 	struct synps_edac_priv *priv;
 	int status, regval;
 
 	priv = mci->pvt_info;
-	p_data = priv->p_data;
 
 	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) {
 		regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
@@ -479,7 +456,7 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
 			return IRQ_NONE;
 	}
 
-	status = p_data->get_error_info(priv);
+	status = synps_get_error_info(priv);
 	if (status)
 		return IRQ_NONE;
 
@@ -492,29 +469,7 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
 }
 
 /**
- * check_errors - Check controller for ECC errors.
- * @mci:	EDAC memory controller instance.
- *
- * Check and post ECC errors. Called by the polling thread.
- */
-static void check_errors(struct mem_ctl_info *mci)
-{
-	const struct synps_platform_data *p_data;
-	struct synps_edac_priv *priv;
-	int status;
-
-	priv = mci->pvt_info;
-	p_data = priv->p_data;
-
-	status = p_data->get_error_info(priv);
-	if (status)
-		return;
-
-	handle_error(mci, &priv->stat);
-}
-
-/**
- * zynqmp_get_dtype - Return the controller memory width.
+ * synps_get_dtype - Return the controller memory width.
  * @base:	DDR memory controller base address.
  *
  * Get the EDAC device type width appropriate for the current controller
@@ -522,7 +477,7 @@ static void check_errors(struct mem_ctl_info *mci)
  *
  * Return: a device type width enumeration.
  */
-static enum dev_type zynqmp_get_dtype(const void __iomem *base)
+static enum dev_type synps_get_dtype(const void __iomem *base)
 {
 	u32 regval;
 
@@ -546,14 +501,14 @@ static enum dev_type zynqmp_get_dtype(const void __iomem *base)
 }
 
 /**
- * zynqmp_get_ecc_state - Return the controller ECC enable/disable status.
+ * synps_get_ecc_state - Return the controller ECC enable/disable status.
  * @base:	DDR memory controller base address.
  *
  * Get the ECC enable/disable status for the controller.
  *
  * Return: a ECC status boolean i.e true/false - enabled/disabled.
  */
-static bool zynqmp_get_ecc_state(void __iomem *base)
+static bool synps_get_ecc_state(void __iomem *base)
 {
 	u32 regval;
 
@@ -577,7 +532,7 @@ static u32 get_memsize(void)
 }
 
 /**
- * zynqmp_get_mtype - Returns controller memory type.
+ * synps_get_mtype - Returns controller memory type.
  * @base:	Synopsys ECC status structure.
  *
  * Get the EDAC memory type appropriate for the current controller
@@ -585,7 +540,7 @@ static u32 get_memsize(void)
  *
  * Return: a memory type enumeration.
  */
-static enum mem_type zynqmp_get_mtype(const void __iomem *base)
+static enum mem_type synps_get_mtype(const void __iomem *base)
 {
 	enum mem_type mt;
 	u32 memtype;
@@ -614,14 +569,11 @@ static enum mem_type zynqmp_get_mtype(const void __iomem *base)
 static void init_csrows(struct mem_ctl_info *mci)
 {
 	struct synps_edac_priv *priv = mci->pvt_info;
-	const struct synps_platform_data *p_data;
 	struct csrow_info *csi;
 	struct dimm_info *dimm;
 	u32 size, row;
 	int j;
 
-	p_data = priv->p_data;
-
 	for (row = 0; row < mci->nr_csrows; row++) {
 		csi = mci->csrows[row];
 		size = get_memsize();
@@ -629,10 +581,10 @@ static void init_csrows(struct mem_ctl_info *mci)
 		for (j = 0; j < csi->nr_channels; j++) {
 			dimm		= csi->channels[j]->dimm;
 			dimm->edac_mode	= EDAC_SECDED;
-			dimm->mtype	= p_data->get_mtype(priv->baseaddr);
+			dimm->mtype	= synps_get_mtype(priv->baseaddr);
 			dimm->nr_pages	= (size >> PAGE_SHIFT) / csi->nr_channels;
 			dimm->grain	= SYNPS_EDAC_ERR_GRAIN;
-			dimm->dtype	= p_data->get_dtype(priv->baseaddr);
+			dimm->dtype	= synps_get_dtype(priv->baseaddr);
 		}
 	}
 }
@@ -648,10 +600,7 @@ static void init_csrows(struct mem_ctl_info *mci)
  */
 static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
 {
-	struct synps_edac_priv *priv;
-
 	mci->pdev = &pdev->dev;
-	priv = mci->pvt_info;
 	platform_set_drvdata(pdev, mci);
 
 	/* Initialize controller capabilities and configuration */
@@ -665,12 +614,7 @@ static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
 	mci->dev_name = SYNPS_EDAC_MOD_STRING;
 	mci->mod_name = SYNPS_EDAC_MOD_VER;
 
-	if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
-		edac_op_state = EDAC_OPSTATE_INT;
-	} else {
-		edac_op_state = EDAC_OPSTATE_POLL;
-		mci->edac_check = check_errors;
-	}
+	edac_op_state = EDAC_OPSTATE_INT;
 
 	mci->ctl_page_to_phys = NULL;
 
@@ -702,47 +646,6 @@ static int setup_irq(struct mem_ctl_info *mci,
 	return 0;
 }
 
-static const struct synps_platform_data zynqmp_edac_def = {
-	.get_error_info	= zynqmp_get_error_info,
-	.get_mtype	= zynqmp_get_mtype,
-	.get_dtype	= zynqmp_get_dtype,
-	.get_ecc_state	= zynqmp_get_ecc_state,
-	.quirks         = (DDR_ECC_INTR_SUPPORT | SYNPS_ZYNQMP_IRQ_REGS
-#ifdef CONFIG_EDAC_DEBUG
-			  | DDR_ECC_DATA_POISON_SUPPORT
-#endif
-			  ),
-};
-
-static const struct synps_platform_data synopsys_edac_def = {
-	.get_error_info	= zynqmp_get_error_info,
-	.get_mtype	= zynqmp_get_mtype,
-	.get_dtype	= zynqmp_get_dtype,
-	.get_ecc_state	= zynqmp_get_ecc_state,
-	.quirks         = (DDR_ECC_INTR_SUPPORT
-#ifdef CONFIG_EDAC_DEBUG
-			  | DDR_ECC_DATA_POISON_SUPPORT
-#endif
-			  ),
-};
-
-
-static const struct of_device_id synps_edac_match[] = {
-	{
-		.compatible = "xlnx,zynqmp-ddrc-2.40a",
-		.data = (void *)&zynqmp_edac_def
-	},
-	{
-		.compatible = "snps,ddrc-3.80a",
-		.data = (void *)&synopsys_edac_def
-	},
-	{
-		/* end of table */
-	}
-};
-
-MODULE_DEVICE_TABLE(of, synps_edac_match);
-
 #ifdef CONFIG_EDAC_DEBUG
 
 /**
@@ -1133,7 +1036,7 @@ static int mc_probe(struct platform_device *pdev)
 	if (!p_data)
 		return -ENODEV;
 
-	if (!p_data->get_ecc_state(baseaddr)) {
+	if (!synps_get_ecc_state(baseaddr)) {
 		edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
 		return -ENXIO;
 	}
@@ -1160,11 +1063,9 @@ static int mc_probe(struct platform_device *pdev)
 
 	mc_init(mci, pdev);
 
-	if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
-		rc = setup_irq(mci, pdev);
-		if (rc)
-			goto free_edac_mc;
-	}
+	rc = setup_irq(mci, pdev);
+	if (rc)
+		goto free_edac_mc;
 
 	rc = edac_mc_add_mc(mci);
 	if (rc) {
@@ -1174,17 +1075,13 @@ static int mc_probe(struct platform_device *pdev)
 	}
 
 #ifdef CONFIG_EDAC_DEBUG
-	if (priv->p_data->quirks & DDR_ECC_DATA_POISON_SUPPORT) {
-		rc = edac_create_sysfs_attributes(mci);
-		if (rc) {
-			edac_printk(KERN_ERR, EDAC_MC,
-					"Failed to create sysfs entries\n");
-			goto free_edac_mc;
-		}
+	rc = edac_create_sysfs_attributes(mci);
+	if (rc) {
+		edac_printk(KERN_ERR, EDAC_MC, "Failed to create sysfs entries\n");
+		goto free_edac_mc;
 	}
 
-	if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT)
-		setup_address_map(priv);
+	setup_address_map(priv);
 #endif
 
 	return rc;
@@ -1206,18 +1103,31 @@ static void mc_remove(struct platform_device *pdev)
 	struct mem_ctl_info *mci = platform_get_drvdata(pdev);
 	struct synps_edac_priv *priv = mci->pvt_info;
 
-	if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT)
-		disable_intr(priv);
+	disable_intr(priv);
 
 #ifdef CONFIG_EDAC_DEBUG
-	if (priv->p_data->quirks & DDR_ECC_DATA_POISON_SUPPORT)
-		edac_remove_sysfs_attributes(mci);
+	edac_remove_sysfs_attributes(mci);
 #endif
 
 	edac_mc_del_mc(&pdev->dev);
 	edac_mc_free(mci);
 }
 
+static const struct synps_platform_data zynqmp_edac_def = {
+	.quirks = SYNPS_ZYNQMP_IRQ_REGS,
+};
+
+static const struct synps_platform_data synopsys_edac_def = {
+	.quirks = 0,
+};
+
+static const struct of_device_id synps_edac_match[] = {
+	{ .compatible = "xlnx,zynqmp-ddrc-2.40a", .data = &zynqmp_edac_def },
+	{ .compatible = "snps,ddrc-3.80a", .data = &synopsys_edac_def },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, synps_edac_match);
+
 static struct platform_driver synps_edac_mc_driver = {
 	.driver = {
 		   .name = "synopsys-edac",
-- 
2.43.0



From megi at xff.cz  Thu Feb 22 10:18:44 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Thu, 22 Feb 2024 19:18:44 +0100
Subject: [PATCH 1/4] ASoC: sun50i-codec-analog: Move suspend/resume to set_bias_level
In-Reply-To: <20240222181851.3398254-1-megi@xff.cz>
References: <20240222181851.3398254-1-megi@xff.cz>
Message-ID: <20240222181851.3398254-2-megi@xff.cz>

From: Samuel Holland <samuel at sholland.org>

With idle_bias_on and suspend_bias_off, there are bias level transitions
that match the suspend/resume callbacks. However, there are also
transitions during probe (OFF => STANDBY) and removal (STANDBY => OFF).

By using the set_bias_level hook, the driver can have one copy of code
that would otherwise be duplicated between the probe/resume and
suspend/remove hooks.

Signed-off-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Ond?ej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun50i-codec-analog.c | 29 +++++++++++++++++----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index 8a32d05e23e1..cedd4de42d1a 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -471,17 +471,23 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
 	{ "EARPIECE", NULL, "Earpiece Amp" },
 };
 
-static int sun50i_a64_codec_suspend(struct snd_soc_component *component)
+static int sun50i_a64_codec_set_bias_level(struct snd_soc_component *component,
+					   enum snd_soc_bias_level level)
 {
-	return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
-				  BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE),
-				  BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
-}
+	switch (level) {
+	case SND_SOC_BIAS_OFF:
+		regmap_set_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
+				BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
+		break;
+	case SND_SOC_BIAS_STANDBY:
+		regmap_clear_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
+				   BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
+		break;
+	default:
+		break;
+	}
 
-static int sun50i_a64_codec_resume(struct snd_soc_component *component)
-{
-	return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
-				  BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE), 0);
+	return 0;
 }
 
 static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = {
@@ -491,8 +497,9 @@ static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = {
 	.num_dapm_widgets	= ARRAY_SIZE(sun50i_a64_codec_widgets),
 	.dapm_routes		= sun50i_a64_codec_routes,
 	.num_dapm_routes	= ARRAY_SIZE(sun50i_a64_codec_routes),
-	.suspend		= sun50i_a64_codec_suspend,
-	.resume			= sun50i_a64_codec_resume,
+	.set_bias_level		= sun50i_a64_codec_set_bias_level,
+	.idle_bias_on		= true,
+	.suspend_bias_off	= true,
 };
 
 static const struct of_device_id sun50i_codec_analog_of_match[] = {
-- 
2.43.0



From megi at xff.cz  Thu Feb 22 10:18:47 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Thu, 22 Feb 2024 19:18:47 +0100
Subject: [PATCH 4/4] ASoC: sun8i-codec: Implement jack and accessory detection
In-Reply-To: <20240222181851.3398254-1-megi@xff.cz>
References: <20240222181851.3398254-1-megi@xff.cz>
Message-ID: <20240222181851.3398254-5-megi@xff.cz>

From: Arnaud Ferraris <arnaud.ferraris at collabora.com>

Add support for the jack detection functionality in the A64 variant,
which uses a pair of IRQs; and microphone accessory (button) detection,
which uses an ADC with an IRQ trigger.

Since not all users of this component have a headphone or headset jack,
only enable jack pins where the corresponding widget exists. Similarly,
only enable microphone accessory detection when the microphone is hooked
up to a headset jack.

IRQs will only be triggered if the JACKDETEN, HMICBIASEN, and MICADCEN
bits are set appropriately in the analog codec component, but there is
no direct software dependency between the two components.

Setup ADC so that it samples with period of 16ms, disable smoothing
and enable MDATA threshold (should be below idle voltage/HMIC_DATA
value). Also enable HMIC_N, which makes sure we get HMIC_N samples
after HMIC_DATA crosses the threshold.

This allows us to perform steady state detection of HMIC_DATA, by
comparing current and previous ADC samples, to detect end of the
transient when the user de-presses the button. Otherwise ADC could
sample anywhere within the transient, and the driver may mis-issue
key-press events for other buttons attached to the resistor ladder.

Signed-off-by: Arnaud Ferraris <arnaud.ferraris at collabora.com>
[Samuel: Decouple from analog codec, automatic pin detection, fixes]
Co-developed-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Samuel Holland <samuel at sholland.org>
[Ondrej: Re-work the sampling mechanism to prevent mis-detection of
button presses due to slow transient change of mic line DC voltage.
Completely rewritten interrupt handling, to debounce plugin
plugout interrupt events properly.]
Co-developed-by: Ondrej Jirman <megi at xff.cz>
Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun50i-codec-analog.c |  12 +
 sound/soc/sunxi/sun8i-codec.c         | 351 ++++++++++++++++++++++++++
 2 files changed, 363 insertions(+)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index 2081721a8ff2..2dcdf113b66e 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -115,6 +115,11 @@
 #define SUN50I_ADDA_HS_MBIAS_CTRL	0x0e
 #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN	7
 
+#define SUN50I_ADDA_MDET_CTRL		0x1c
+#define SUN50I_ADDA_MDET_CTRL_SELDETADC_FS	4
+#define SUN50I_ADDA_MDET_CTRL_SELDETADC_DB	2
+#define SUN50I_ADDA_MDET_CTRL_SELDETADC_BF	0
+
 #define SUN50I_ADDA_JACK_MIC_CTRL	0x1d
 #define SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN	7
 #define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN	6
@@ -564,6 +569,13 @@ static int sun50i_codec_analog_probe(struct platform_device *pdev)
 			   BIT(SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN),
 			   enable << SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN);
 
+	/* Select sample interval of the ADC sample to 16ms */
+	regmap_update_bits(regmap, SUN50I_ADDA_MDET_CTRL,
+			   0x7 << SUN50I_ADDA_MDET_CTRL_SELDETADC_FS |
+			   0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_BF,
+			   0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_FS |
+			   0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_BF);
+
 	return devm_snd_soc_register_component(&pdev->dev,
 					       &sun50i_codec_analog_cmpnt_drv,
 					       NULL, 0);
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 2a46b96b03cc..9b78b6226012 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -12,12 +12,16 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/input.h>
 #include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/log2.h>
 
+#include <sound/jack.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
@@ -118,6 +122,23 @@
 #define SUN8I_ADC_VOL_CTRL				0x104
 #define SUN8I_ADC_VOL_CTRL_ADCL_VOL			8
 #define SUN8I_ADC_VOL_CTRL_ADCR_VOL			0
+#define SUN8I_HMIC_CTRL1				0x110
+#define SUN8I_HMIC_CTRL1_HMIC_M				12
+#define SUN8I_HMIC_CTRL1_HMIC_N				8
+#define SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB		5
+#define SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN		4
+#define SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN			3
+#define SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN		0
+#define SUN8I_HMIC_CTRL2				0x114
+#define SUN8I_HMIC_CTRL2_HMIC_SAMPLE			14
+#define SUN8I_HMIC_CTRL2_HMIC_MDATA_THRESHOLD		8
+#define SUN8I_HMIC_CTRL2_HMIC_SF			6
+#define SUN8I_HMIC_STS					0x118
+#define SUN8I_HMIC_STS_MDATA_DISCARD			13
+#define SUN8I_HMIC_STS_HMIC_DATA			8
+#define SUN8I_HMIC_STS_JACK_OUT_IRQ_ST			4
+#define SUN8I_HMIC_STS_JACK_IN_IRQ_ST			3
+#define SUN8I_HMIC_STS_HMIC_DATA_IRQ_ST			0
 #define SUN8I_DAC_DIG_CTRL				0x120
 #define SUN8I_DAC_DIG_CTRL_ENDA				15
 #define SUN8I_DAC_VOL_CTRL				0x124
@@ -143,6 +164,17 @@
 #define SUN8I_AIF_CLK_CTRL_WORD_SIZ_MASK	GENMASK(5, 4)
 #define SUN8I_AIF_CLK_CTRL_DATA_FMT_MASK	GENMASK(3, 2)
 #define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK	GENMASK(1, 0)
+#define SUN8I_HMIC_CTRL1_HMIC_M_MASK		GENMASK(15, 12)
+#define SUN8I_HMIC_CTRL1_HMIC_N_MASK		GENMASK(11, 8)
+#define SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB_MASK GENMASK(6, 5)
+#define SUN8I_HMIC_CTRL2_HMIC_SAMPLE_MASK	GENMASK(15, 14)
+#define SUN8I_HMIC_CTRL2_HMIC_SF_MASK		GENMASK(7, 6)
+#define SUN8I_HMIC_STS_HMIC_DATA_MASK		GENMASK(12, 8)
+
+#define SUN8I_CODEC_BUTTONS	(SND_JACK_BTN_0|\
+				 SND_JACK_BTN_1|\
+				 SND_JACK_BTN_2|\
+				 SND_JACK_BTN_3)
 
 #define SUN8I_CODEC_PASSTHROUGH_SAMPLE_RATE 48000
 
@@ -178,16 +210,33 @@ struct sun8i_codec_aif {
 
 struct sun8i_codec_quirks {
 	bool	bus_clock	: 1;
+	bool	jack_detection	: 1;
 	bool	legacy_widgets	: 1;
 	bool	lrck_inversion	: 1;
 };
 
+enum {
+	SUN8I_JACK_STATUS_DISCONNECTED,
+	SUN8I_JACK_STATUS_WAITING_HBIAS,
+	SUN8I_JACK_STATUS_CONNECTED,
+};
+
 struct sun8i_codec {
 	struct regmap			*regmap;
+	struct snd_soc_card		*card;
 	struct clk			*clk_bus;
 	struct clk			*clk_module;
 	const struct sun8i_codec_quirks	*quirks;
 	struct sun8i_codec_aif		aifs[SUN8I_CODEC_NAIFS];
+	struct snd_soc_jack		jack;
+	struct delayed_work		jack_work;
+	int				jack_irq;
+	int				jack_status;
+	int				jack_last_sample;
+	ktime_t				jack_hbias_ready;
+	int				jack_type;
+	int				last_hmic_irq;
+	struct mutex			jack_mutex;
 	unsigned int			sysclk_rate;
 	int				sysclk_refcnt;
 };
@@ -1239,12 +1288,79 @@ static const struct snd_soc_dapm_route sun8i_codec_legacy_routes[] = {
 	{ "AIF1 Slot 0 Right", NULL, "DACR" },
 };
 
+static struct snd_soc_jack_pin sun8i_codec_jack_pins[] = {
+	{
+		.pin	= "Headphone Jack",
+		.mask	= SND_JACK_HEADPHONE,
+	},
+	{
+		.pin	= "Headset Microphone",
+		.mask	= SND_JACK_MICROPHONE,
+	},
+};
+
+static int sun8i_codec_jack_init(struct sun8i_codec *scodec)
+{
+	int pins = 0;
+	int type = 0;
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(sun8i_codec_jack_pins); ++i) {
+		struct snd_soc_jack_pin *pin = &sun8i_codec_jack_pins[i];
+		struct snd_soc_dapm_widget *w;
+
+		for_each_card_widgets(scodec->card, w) {
+			if (!strcmp(pin->pin, w->name)) {
+				pins |= BIT(i);
+				type |= pin->mask;
+				break;
+			}
+		}
+	}
+
+	if (!type)
+		return 0;
+
+	if (type & SND_JACK_MICROPHONE)
+		type |= SUN8I_CODEC_BUTTONS;
+
+	ret = snd_soc_card_jack_new(scodec->card, "Headset Jack", type,
+				    &scodec->jack);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(sun8i_codec_jack_pins); ++i) {
+		struct snd_soc_jack_pin *pin = &sun8i_codec_jack_pins[i];
+
+		if (pins & BIT(i)) {
+			ret = snd_soc_jack_add_pins(&scodec->jack, 1, pin);
+			if (ret)
+				return ret;
+		}
+	}
+
+	if (type & SND_JACK_MICROPHONE) {
+		struct snd_jack *jack = scodec->jack.jack;
+
+		snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+		snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
+		snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
+		snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
+	}
+
+	scodec->jack_type = type;
+
+	return 0;
+}
+
 static int sun8i_codec_component_probe(struct snd_soc_component *component)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
 	int ret;
 
+	scodec->card = component->card;
+
 	/* Add widgets for backward compatibility with old device trees. */
 	if (scodec->quirks->legacy_widgets) {
 		ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_legacy_widgets,
@@ -1278,9 +1394,53 @@ static int sun8i_codec_component_probe(struct snd_soc_component *component)
 	/* Program the default sample rate. */
 	sun8i_codec_update_sample_rate(scodec);
 
+	if (scodec->quirks->jack_detection) {
+		ret = sun8i_codec_jack_init(scodec);
+		if (ret)
+			return ret;
+	}
+
+	if (scodec->jack_type) {
+		/* Reserved value required for jack IRQs to trigger. */
+		regmap_write(scodec->regmap, SUN8I_HMIC_CTRL1,
+				   0xf << SUN8I_HMIC_CTRL1_HMIC_N |
+				   0x0 << SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB |
+				   0x4 << SUN8I_HMIC_CTRL1_HMIC_M);
+
+		/* Sample the ADC at 128 Hz; bypass smooth filter. */
+		regmap_write(scodec->regmap, SUN8I_HMIC_CTRL2,
+				   0x0 << SUN8I_HMIC_CTRL2_HMIC_SAMPLE |
+				   0x17 << SUN8I_HMIC_CTRL2_HMIC_MDATA_THRESHOLD |
+				   0x0 << SUN8I_HMIC_CTRL2_HMIC_SF);
+
+		/* Do not discard any MDATA, enable user written MDATA threshold. */
+		regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0);
+
+		regmap_set_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
+				BIT(SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN) |
+				BIT(SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN));
+
+		enable_irq(scodec->jack_irq);
+	}
+
 	return 0;
 }
 
+static void sun8i_codec_component_remove(struct snd_soc_component *component)
+{
+	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
+
+	if (scodec->jack_type) {
+		disable_irq(scodec->jack_irq);
+		cancel_delayed_work_sync(&scodec->jack_work);
+
+		regmap_clear_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
+				  BIT(SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN) |
+				  BIT(SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN) |
+				  BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN));
+	}
+}
+
 static const struct snd_soc_component_driver sun8i_soc_component = {
 	.controls		= sun8i_codec_controls,
 	.num_controls		= ARRAY_SIZE(sun8i_codec_controls),
@@ -1289,20 +1449,194 @@ static const struct snd_soc_component_driver sun8i_soc_component = {
 	.dapm_routes		= sun8i_codec_dapm_routes,
 	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
 	.probe			= sun8i_codec_component_probe,
+	.remove			= sun8i_codec_component_remove,
 	.idle_bias_on		= 1,
 	.suspend_bias_off	= 1,
 	.endianness		= 1,
 };
 
+static bool sun8i_codec_volatile_reg(struct device *dev, unsigned int reg)
+{
+	return reg == SUN8I_HMIC_STS;
+}
+
 static const struct regmap_config sun8i_codec_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
 	.val_bits	= 32,
+	.volatile_reg	= sun8i_codec_volatile_reg,
 	.max_register	= SUN8I_DAC_MXR_SRC,
 
 	.cache_type	= REGCACHE_FLAT,
 };
 
+static void sun8i_codec_set_hmic_bias(struct sun8i_codec *scodec, bool enable)
+{
+	struct snd_soc_dapm_context *dapm = &scodec->card->dapm;
+	int irq_mask = BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN);
+
+	if (enable)
+		snd_soc_dapm_force_enable_pin(dapm, "HBIAS");
+	else
+		snd_soc_dapm_disable_pin(dapm, "HBIAS");
+
+	snd_soc_dapm_sync(dapm);
+
+	regmap_update_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
+			   irq_mask, enable ? irq_mask : 0);
+}
+
+static void sun8i_codec_jack_work(struct work_struct *work)
+{
+	struct sun8i_codec *scodec = container_of(work, struct sun8i_codec,
+						  jack_work.work);
+	unsigned int mdata;
+	int type;
+
+	guard(mutex)(&scodec->jack_mutex);
+
+	if (scodec->jack_status == SUN8I_JACK_STATUS_DISCONNECTED) {
+		if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_IN_IRQ_ST)
+			return;
+
+		scodec->jack_last_sample = -1;
+
+		if (scodec->jack_type & SND_JACK_MICROPHONE) {
+			/*
+			 * If we were in disconnected state, we enable HBIAS and
+			 * wait 600ms before reading initial HDATA value.
+			 */
+			scodec->jack_hbias_ready = ktime_add_ms(ktime_get(), 600);
+			sun8i_codec_set_hmic_bias(scodec, true);
+			queue_delayed_work(system_power_efficient_wq,
+					   &scodec->jack_work,
+					   msecs_to_jiffies(610));
+			scodec->jack_status = SUN8I_JACK_STATUS_WAITING_HBIAS;
+		} else {
+			snd_soc_jack_report(&scodec->jack, SND_JACK_HEADPHONE,
+					    scodec->jack_type);
+			scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED;
+		}
+	} else if (scodec->jack_status == SUN8I_JACK_STATUS_WAITING_HBIAS) {
+		/*
+		 * If we're waiting for HBIAS to stabilize, and we get plug-out
+		 * interrupt and nothing more for > 100ms, just cancel the
+		 * initialization.
+		 */
+		if (scodec->last_hmic_irq == SUN8I_HMIC_STS_JACK_OUT_IRQ_ST) {
+			scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED;
+			sun8i_codec_set_hmic_bias(scodec, false);
+			return;
+		}
+
+		/*
+		 * If we're not done waiting for HBIAS to stabilize, wait more.
+		 */
+		if (!ktime_after(ktime_get(), scodec->jack_hbias_ready)) {
+			s64 msecs = ktime_ms_delta(scodec->jack_hbias_ready,
+						   ktime_get());
+
+			queue_delayed_work(system_power_efficient_wq,
+					   &scodec->jack_work,
+					   msecs_to_jiffies(msecs + 10));
+			return;
+		}
+
+		/*
+		 * Everything is stabilized, determine jack type and report it.
+		 */
+		regmap_read(scodec->regmap, SUN8I_HMIC_STS, &mdata);
+		mdata &= SUN8I_HMIC_STS_HMIC_DATA_MASK;
+		mdata >>= SUN8I_HMIC_STS_HMIC_DATA;
+
+		regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0);
+
+		type = mdata < 16 ? SND_JACK_HEADPHONE : SND_JACK_HEADSET;
+		if (type == SND_JACK_HEADPHONE)
+			sun8i_codec_set_hmic_bias(scodec, false);
+
+		snd_soc_jack_report(&scodec->jack, type, scodec->jack_type);
+		scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED;
+	} else if (scodec->jack_status == SUN8I_JACK_STATUS_CONNECTED) {
+		if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_OUT_IRQ_ST)
+			return;
+
+		scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED;
+		if (scodec->jack_type & SND_JACK_MICROPHONE)
+			sun8i_codec_set_hmic_bias(scodec, false);
+
+		snd_soc_jack_report(&scodec->jack, 0, scodec->jack_type);
+	}
+}
+
+static irqreturn_t sun8i_codec_jack_irq(int irq, void *dev_id)
+{
+	struct sun8i_codec *scodec = dev_id;
+	int type = SND_JACK_HEADSET;
+	unsigned int status, value;
+
+	guard(mutex)(&scodec->jack_mutex);
+
+	regmap_read(scodec->regmap, SUN8I_HMIC_STS, &status);
+	regmap_write(scodec->regmap, SUN8I_HMIC_STS, status);
+
+	/*
+	 * De-bounce in/out interrupts via a delayed work re-scheduling to
+	 * 100ms after each interrupt..
+	 */
+	if (status & BIT(SUN8I_HMIC_STS_JACK_OUT_IRQ_ST)) {
+		/*
+		 * Out interrupt has priority over in interrupt so that if
+		 * we get both, we assume the disconnected state, which is
+		 * safer.
+		 */
+		scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_OUT_IRQ_ST;
+		mod_delayed_work(system_power_efficient_wq, &scodec->jack_work,
+				 msecs_to_jiffies(100));
+	} else if (status & BIT(SUN8I_HMIC_STS_JACK_IN_IRQ_ST)) {
+		scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_IN_IRQ_ST;
+		mod_delayed_work(system_power_efficient_wq, &scodec->jack_work,
+				 msecs_to_jiffies(100));
+	} else if (status & BIT(SUN8I_HMIC_STS_HMIC_DATA_IRQ_ST)) {
+		/*
+		 * Ignore data interrupts until jack status turns to connected
+		 * state, which is after HMIC enable stabilization is completed.
+		 * Until then tha data are bogus.
+		 */
+		if (scodec->jack_status != SUN8I_JACK_STATUS_CONNECTED)
+			return IRQ_HANDLED;
+
+		value = (status & SUN8I_HMIC_STS_HMIC_DATA_MASK) >>
+			SUN8I_HMIC_STS_HMIC_DATA;
+
+		/*
+		 * Assumes 60 mV per ADC LSB increment, 2V bias voltage, 2.2kOhm
+		 * bias resistor.
+		 */
+		if (value == 0)
+			type |= SND_JACK_BTN_0;
+		else if (value == 1)
+			type |= SND_JACK_BTN_3;
+		else if (value <= 3)
+			type |= SND_JACK_BTN_1;
+		else if (value <= 8)
+			type |= SND_JACK_BTN_2;
+
+		/*
+		 * De-bounce. Only report button after two consecutive A/D
+		 * samples are identical.
+		 */
+		if (scodec->jack_last_sample >= 0 &&
+		    scodec->jack_last_sample == value)
+			snd_soc_jack_report(&scodec->jack, type,
+					    scodec->jack_type);
+
+		scodec->jack_last_sample = value;
+	}
+
+	return IRQ_HANDLED;
+}
+
 static int sun8i_codec_probe(struct platform_device *pdev)
 {
 	struct sun8i_codec *scodec;
@@ -1344,6 +1678,22 @@ static int sun8i_codec_probe(struct platform_device *pdev)
 		return PTR_ERR(scodec->regmap);
 	}
 
+	if (scodec->quirks->jack_detection) {
+		scodec->jack_irq = platform_get_irq(pdev, 0);
+		if (scodec->jack_irq < 0)
+			return scodec->jack_irq;
+
+		ret = devm_request_threaded_irq(&pdev->dev, scodec->jack_irq,
+						NULL, sun8i_codec_jack_irq,
+						IRQF_ONESHOT | IRQF_NO_AUTOEN,
+						dev_name(&pdev->dev), scodec);
+		if (ret)
+			return ret;
+
+		INIT_DELAYED_WORK(&scodec->jack_work, sun8i_codec_jack_work);
+		mutex_init(&scodec->jack_mutex);
+	}
+
 	regcache_cache_only(scodec->regmap, true);
 	pm_runtime_enable(&pdev->dev);
 	if (!pm_runtime_enabled(&pdev->dev)) {
@@ -1387,6 +1737,7 @@ static const struct sun8i_codec_quirks sun8i_a33_quirks = {
 
 static const struct sun8i_codec_quirks sun50i_a64_quirks = {
 	.bus_clock	= true,
+	.jack_detection	= true,
 };
 
 static const struct of_device_id sun8i_codec_of_match[] = {
-- 
2.43.0



From megi at xff.cz  Thu Feb 22 10:18:43 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Thu, 22 Feb 2024 19:18:43 +0100
Subject: [PATCH 0/4] Add support for jack detection to codec present in A64 SoC
Message-ID: <20240222181851.3398254-1-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

This series adds support for jack detection to this codec. I used
and tested this on Pinephone. It works quite nicely. I tested it
against Android headset mic button resistor specification.

The patches are improved and debugged version of the original
ones from Arnaud Ferraris and Samuel Holland, imrpoved to better
handle headset button presses and with more robust plug-in/out
event debouncing.

Please take a look. :)

Thank you very much,
	Ond?ej Jirman

Arnaud Ferraris (2):
  ASoC: sun50i-codec-analog: Enable jack detection on startup
  ASoC: sun8i-codec: Implement jack and accessory detection

Samuel Holland (2):
  ASoC: sun50i-codec-analog: Move suspend/resume to set_bias_level
  ASoC: sun8i-codec: Enable bus clock at STANDBY and higher bias

 sound/soc/sunxi/sun50i-codec-analog.c |  73 ++++-
 sound/soc/sunxi/sun8i-codec.c         | 388 +++++++++++++++++++++++++-
 2 files changed, 443 insertions(+), 18 deletions(-)

-- 
2.43.0



From mripard at kernel.org  Thu Feb 22 10:14:19 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:19 +0100
Subject: [PATCH v7 33/36] drm/sun4i: hdmi: Move mode_set into enable
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-33-8f4af575fce2@kernel.org>

We're not doing anything special in atomic_mode_set so we can simply
merge it into atomic_enable.

Acked-by: Sui Jingfeng <sui.jingfeng at linux.dev>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 38 +++++++++++++---------------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 799a26215cc2..bae69d696765 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -103,33 +103,11 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
 	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
 	struct drm_display_info *display = &hdmi->connector.display_info;
+	unsigned int x, y;
 	u32 val = 0;
 
 	DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
 
-	clk_prepare_enable(hdmi->tmds_clk);
-
-	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
-	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
-	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
-	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
-
-	val = SUN4I_HDMI_VID_CTRL_ENABLE;
-	if (display->is_hdmi)
-		val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE;
-
-	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
-}
-
-static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
-				struct drm_crtc_state *crtc_state,
-				struct drm_connector_state *conn_state)
-{
-	const struct drm_display_mode *mode = &crtc_state->mode;
-	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
-	unsigned int x, y;
-	u32 val;
-
 	clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
 	clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
 
@@ -181,6 +159,19 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
 		val |= SUN4I_HDMI_VID_TIMING_POL_VSYNC;
 
 	writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG);
+
+	clk_prepare_enable(hdmi->tmds_clk);
+
+	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
+	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
+	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
+	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
+
+	val = SUN4I_HDMI_VID_CTRL_ENABLE;
+	if (display->is_hdmi)
+		val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE;
+
+	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
 }
 
 static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
@@ -206,7 +197,6 @@ static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
 	.atomic_check	= sun4i_hdmi_atomic_check,
 	.atomic_disable	= sun4i_hdmi_disable,
 	.atomic_enable	= sun4i_hdmi_enable,
-	.atomic_mode_set	= sun4i_hdmi_mode_set,
 	.mode_valid	= sun4i_hdmi_mode_valid,
 };
 

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:20 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:20 +0100
Subject: [PATCH v7 34/36] drm/sun4i: hdmi: Switch to container_of_const
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-34-8f4af575fce2@kernel.org>

container_of_const() allows to preserve the pointer constness and is
thus more flexible than inline functions.

Let's switch all our instances of container_of() to container_of_const().

Reviewed-by: Sui Jingfeng <sui.jingfeng at linux.dev>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index bae69d696765..c276d984da6b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -30,19 +30,11 @@
 #include "sun4i_drv.h"
 #include "sun4i_hdmi.h"
 
-static inline struct sun4i_hdmi *
-drm_encoder_to_sun4i_hdmi(struct drm_encoder *encoder)
-{
-	return container_of(encoder, struct sun4i_hdmi,
-			    encoder);
-}
+#define drm_encoder_to_sun4i_hdmi(e)		\
+	container_of_const(e, struct sun4i_hdmi, encoder)
 
-static inline struct sun4i_hdmi *
-drm_connector_to_sun4i_hdmi(struct drm_connector *connector)
-{
-	return container_of(connector, struct sun4i_hdmi,
-			    connector);
-}
+#define drm_connector_to_sun4i_hdmi(c)		\
+	container_of_const(c, struct sun4i_hdmi, connector)
 
 static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
 					   struct drm_display_mode *mode)

-- 
2.43.2



From fancer.lancer at gmail.com  Thu Feb 22 10:12:57 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:12:57 +0300
Subject: [PATCH v5 12/20] EDAC/synopsys: Drop redundant info from the error messages
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-13-fancer.lancer@gmail.com>

Currently the custom error messages are needlessly long so the logged text
gets to be printed in several lines in console. There is some
duplicated/redundant information which can be freely removed from it: drop
the message prefix "DDR ECC error type:%s" since the resultant text
printed to the log by the edac_mc_printk() method will contain the error
type and the memory controller id referring to the device detected the
error anyway; with no harm to readability shorten out the phrase "Bit
Position" to being just "Bit".

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>
---
 drivers/edac/synopsys_edac.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index b0ff831287f5..dfe1abe7c86c 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -478,13 +478,13 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 		pinf = &p->ceinfo;
 		if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "DDR ECC error type:%s Row %d Col %d Bank %d Bank Group %d Bit Position: %d Data: 0x%08x",
-				 "CE", pinf->row, pinf->col, pinf->bank,
-				 pinf->bankgrp, pinf->bitpos, pinf->data);
+				 "Row %d Col %d Bank %d Bank Group %d Bit %d Data 0x%08x",
+				 pinf->row, pinf->col, pinf->bank, pinf->bankgrp,
+				 pinf->bitpos, pinf->data);
 		} else {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "DDR ECC error type:%s Row %d Bank %d Col %d Bit Position: %d Data: 0x%08x",
-				 "CE", pinf->row, pinf->bank, pinf->col,
+				 "Row %d Bank %d Col %d Bit: %d Data: 0x%08x",
+				 pinf->row, pinf->bank, pinf->col,
 				 pinf->bitpos, pinf->data);
 		}
 
@@ -497,13 +497,12 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 		pinf = &p->ueinfo;
 		if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "DDR ECC error type :%s Row %d Col %d Bank %d Bank Group %d",
-				 "UE", pinf->row, pinf->col, pinf->bank,
-				 pinf->bankgrp);
+				 "Row %d Col %d Bank %d Bank Group %d",
+				 pinf->row, pinf->col, pinf->bank, pinf->bankgrp);
 		} else {
 			snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
-				 "DDR ECC error type :%s Row %d Bank %d Col %d ",
-				 "UE", pinf->row, pinf->bank, pinf->col);
+				 "Row %d Bank %d Col %d",
+				 pinf->row, pinf->bank, pinf->col);
 		}
 
 		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
-- 
2.43.0



From mripard at kernel.org  Thu Feb 22 10:14:18 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:18 +0100
Subject: [PATCH v7 32/36] drm/sun4i: hdmi: Convert encoder to atomic
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-32-8f4af575fce2@kernel.org>

The sun4i_hdmi driver still uses the non-atomic variants of the encoder
hooks, so let's convert to their atomic equivalents.

Acked-by: Sui Jingfeng <sui.jingfeng at linux.dev>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 152375f3de2e..799a26215cc2 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -82,7 +82,8 @@ static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder,
 	return 0;
 }
 
-static void sun4i_hdmi_disable(struct drm_encoder *encoder)
+static void sun4i_hdmi_disable(struct drm_encoder *encoder,
+			       struct drm_atomic_state *state)
 {
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
 	u32 val;
@@ -96,7 +97,8 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder)
 	clk_disable_unprepare(hdmi->tmds_clk);
 }
 
-static void sun4i_hdmi_enable(struct drm_encoder *encoder)
+static void sun4i_hdmi_enable(struct drm_encoder *encoder,
+			      struct drm_atomic_state *state)
 {
 	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
@@ -120,9 +122,10 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder)
 }
 
 static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
+				struct drm_crtc_state *crtc_state,
+				struct drm_connector_state *conn_state)
 {
+	const struct drm_display_mode *mode = &crtc_state->mode;
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
 	unsigned int x, y;
 	u32 val;
@@ -201,9 +204,9 @@ static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
 
 static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
 	.atomic_check	= sun4i_hdmi_atomic_check,
-	.disable	= sun4i_hdmi_disable,
-	.enable		= sun4i_hdmi_enable,
-	.mode_set	= sun4i_hdmi_mode_set,
+	.atomic_disable	= sun4i_hdmi_disable,
+	.atomic_enable	= sun4i_hdmi_enable,
+	.atomic_mode_set	= sun4i_hdmi_mode_set,
 	.mode_valid	= sun4i_hdmi_mode_valid,
 };
 

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:21 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:21 +0100
Subject: [PATCH v7 35/36] drm/sun4i: hdmi: Consolidate atomic_check and
 mode_valid
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-35-8f4af575fce2@kernel.org>

atomic_check and mode_valid do not check for the same things which can
lead to surprising result if the userspace commits a mode that didn't go
through mode_valid. Let's merge the two implementations into a function
called by both.

Acked-by: Sui Jingfeng <sui.jingfeng at linux.dev>
Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 74 +++++++++++++++++++++-------------
 1 file changed, 47 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index c276d984da6b..b7cf369b1906 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -62,18 +62,6 @@ static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
 	return 0;
 }
 
-static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder,
-				   struct drm_crtc_state *crtc_state,
-				   struct drm_connector_state *conn_state)
-{
-	struct drm_display_mode *mode = &crtc_state->mode;
-
-	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
-		return -EINVAL;
-
-	return 0;
-}
-
 static void sun4i_hdmi_disable(struct drm_encoder *encoder,
 			       struct drm_atomic_state *state)
 {
@@ -166,31 +154,61 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
 	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
 }
 
-static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
-					const struct drm_display_mode *mode)
+static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
+	.atomic_disable	= sun4i_hdmi_disable,
+	.atomic_enable	= sun4i_hdmi_enable,
+};
+
+static enum drm_mode_status
+sun4i_hdmi_connector_clock_valid(const struct drm_connector *connector,
+				 const struct drm_display_mode *mode,
+				 unsigned long long clock)
 {
-	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
-	unsigned long rate = mode->clock * 1000;
-	unsigned long diff = rate / 200; /* +-0.5% allowed by HDMI spec */
+	const struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
+	unsigned long diff = clock / 200; /* +-0.5% allowed by HDMI spec */
 	long rounded_rate;
 
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		return MODE_BAD;
+
 	/* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */
-	if (rate > 165000000)
+	if (clock > 165000000)
 		return MODE_CLOCK_HIGH;
-	rounded_rate = clk_round_rate(hdmi->tmds_clk, rate);
+
+	rounded_rate = clk_round_rate(hdmi->tmds_clk, clock);
 	if (rounded_rate > 0 &&
-	    max_t(unsigned long, rounded_rate, rate) -
-	    min_t(unsigned long, rounded_rate, rate) < diff)
+	    max_t(unsigned long, rounded_rate, clock) -
+	    min_t(unsigned long, rounded_rate, clock) < diff)
 		return MODE_OK;
+
 	return MODE_NOCLOCK;
 }
 
-static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
-	.atomic_check	= sun4i_hdmi_atomic_check,
-	.atomic_disable	= sun4i_hdmi_disable,
-	.atomic_enable	= sun4i_hdmi_enable,
-	.mode_valid	= sun4i_hdmi_mode_valid,
-};
+static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector,
+					     struct drm_atomic_state *state)
+{
+	struct drm_connector_state *conn_state =
+		drm_atomic_get_new_connector_state(state, connector);
+	struct drm_crtc *crtc = conn_state->crtc;
+	struct drm_crtc_state *crtc_state = crtc->state;
+	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+	enum drm_mode_status status;
+
+	status = sun4i_hdmi_connector_clock_valid(connector, mode,
+						  mode->clock * 1000);
+	if (status != MODE_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static enum drm_mode_status
+sun4i_hdmi_connector_mode_valid(struct drm_connector *connector,
+				struct drm_display_mode *mode)
+{
+	return sun4i_hdmi_connector_clock_valid(connector, mode,
+						mode->clock * 1000);
+}
 
 static int sun4i_hdmi_get_modes(struct drm_connector *connector)
 {
@@ -236,6 +254,8 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev)
 }
 
 static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = {
+	.atomic_check	= sun4i_hdmi_connector_atomic_check,
+	.mode_valid	= sun4i_hdmi_connector_mode_valid,
 	.get_modes	= sun4i_hdmi_get_modes,
 };
 

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:16 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:16 +0100
Subject: [PATCH v7 30/36] drm/vc4: tests: Convert to plane creation helper
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-30-8f4af575fce2@kernel.org>

Now that we have a plane create helper for kunit mocked drivers, let's
convert to it in vc4.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 34 +++++++-----------------------
 1 file changed, 8 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
index 973f5f929097..14357db82238 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
@@ -1,43 +1,25 @@
 // SPDX-License-Identifier: GPL-2.0
 
-#include <drm/drm_atomic_state_helper.h>
-#include <drm/drm_fourcc.h>
-#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_kunit_helpers.h>
 #include <drm/drm_plane.h>
 
 #include <kunit/test.h>
 
 #include "vc4_mock.h"
 
-static const struct drm_plane_helper_funcs vc4_dummy_plane_helper_funcs = {
-};
-
-static const struct drm_plane_funcs vc4_dummy_plane_funcs = {
-	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
-	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
-	.reset			= drm_atomic_helper_plane_reset,
-};
-
-static const uint32_t vc4_dummy_plane_formats[] = {
-	DRM_FORMAT_XRGB8888,
-};
-
 struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
 				  enum drm_plane_type type)
 {
 	struct drm_plane *plane;
 
-	plane = __drmm_universal_plane_alloc(drm, sizeof(struct drm_plane), 0,
-						 0,
-						 &vc4_dummy_plane_funcs,
-						 vc4_dummy_plane_formats,
-						 ARRAY_SIZE(vc4_dummy_plane_formats),
-						 NULL,
-						 DRM_PLANE_TYPE_PRIMARY,
-						 NULL);
+	KUNIT_ASSERT_EQ(test, type, DRM_PLANE_TYPE_PRIMARY);
+
+	plane = drm_kunit_helper_create_primary_plane(test, drm,
+						      NULL,
+						      NULL,
+						      NULL, 0,
+						      NULL);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
 
-	drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs);
-
 	return plane;
 }

-- 
2.43.2



From mripard at kernel.org  Thu Feb 22 10:14:17 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 22 Feb 2024 19:14:17 +0100
Subject: [PATCH v7 31/36] drm/rockchip: inno_hdmi: Switch to HDMI connector
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <20240222-kms-hdmi-connector-state-v7-31-8f4af575fce2@kernel.org>

The new HDMI connector infrastructure allows to remove some boilerplate,
especially to generate infoframes. Let's switch to it.

Signed-off-by: Maxime Ripard <mripard at kernel.org>
---
 drivers/gpu/drm/rockchip/inno_hdmi.c | 123 ++++++++++++-----------------------
 1 file changed, 42 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 1d2261643743..d59947679042 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -67,9 +67,7 @@ struct inno_hdmi {
 
 struct inno_hdmi_connector_state {
 	struct drm_connector_state	base;
-	unsigned int			enc_out_format;
 	unsigned int			colorimetry;
-	bool				rgb_limited_range;
 };
 
 static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
@@ -257,26 +255,29 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
 	inno_hdmi_standby(hdmi);
 }
 
-static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
-				    enum hdmi_infoframe_type type)
+static int inno_hdmi_disable_frame(struct drm_connector *connector,
+				   enum hdmi_infoframe_type type)
 {
-	struct drm_connector *connector = &hdmi->connector;
+	struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
 
 	if (type != HDMI_INFOFRAME_TYPE_AVI) {
 		drm_err(connector->dev,
 			"Unsupported infoframe type: %u\n", type);
-		return;
+		return 0;
 	}
 
 	hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
+
+	return 0;
 }
 
-static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
-				  union hdmi_infoframe *frame, enum hdmi_infoframe_type type)
+static int inno_hdmi_upload_frame(struct drm_connector *connector,
+				  enum hdmi_infoframe_type type,
+				  const u8 *buffer, size_t len)
 {
-	struct drm_connector *connector = &hdmi->connector;
+	struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
 	u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
-	ssize_t rc, i;
+	ssize_t i;
 
 	if (type != HDMI_INFOFRAME_TYPE_AVI) {
 		drm_err(connector->dev,
@@ -284,59 +285,19 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
 		return 0;
 	}
 
-	inno_hdmi_disable_frame(hdmi, type);
+	inno_hdmi_disable_frame(connector, type);
 
-	rc = hdmi_infoframe_pack(frame, packed_frame,
-				 sizeof(packed_frame));
-	if (rc < 0)
-		return rc;
-
-	for (i = 0; i < rc; i++)
+	for (i = 0; i < len; i++)
 		hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
 			    packed_frame[i]);
 
 	return 0;
 }
 
-static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
-				      struct drm_display_mode *mode)
-{
-	struct drm_connector *connector = &hdmi->connector;
-	struct drm_connector_state *conn_state = connector->state;
-	struct inno_hdmi_connector_state *inno_conn_state =
-					to_inno_hdmi_conn_state(conn_state);
-	union hdmi_infoframe frame;
-	int rc;
-
-	rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
-						      &hdmi->connector,
-						      mode);
-	if (rc) {
-		inno_hdmi_disable_frame(hdmi, HDMI_INFOFRAME_TYPE_AVI);
-		return rc;
-	}
-
-	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444)
-		frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
-	else if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV422)
-		frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
-	else
-		frame.avi.colorspace = HDMI_COLORSPACE_RGB;
-
-	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
-		drm_hdmi_avi_infoframe_quant_range(&frame.avi,
-						   connector, mode,
-						   inno_conn_state->rgb_limited_range ?
-						   HDMI_QUANTIZATION_RANGE_LIMITED :
-						   HDMI_QUANTIZATION_RANGE_FULL);
-	} else {
-		frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
-		frame.avi.ycc_quantization_range =
-			HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
-	}
-
-	return inno_hdmi_upload_frame(hdmi, &frame, HDMI_INFOFRAME_TYPE_AVI);
-}
+static const struct drm_connector_hdmi_funcs inno_hdmi_hdmi_connector_funcs = {
+	.clear_infoframe	= inno_hdmi_disable_frame,
+	.write_infoframe	= inno_hdmi_upload_frame,
+};
 
 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
 {
@@ -361,8 +322,8 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
 		v_VIDEO_INPUT_CSP(0);
 	hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
 
-	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
-		if (inno_conn_state->rgb_limited_range) {
+	if (conn_state->hdmi.output_format == HDMI_COLORSPACE_RGB) {
+		if (!conn_state->hdmi.is_full_range) {
 			csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
 			auto_csc = AUTO_CSC_DISABLE;
 			c0_c2_change = C0_C2_CHANGE_DISABLE;
@@ -380,14 +341,14 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
 		}
 	} else {
 		if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
-			if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
+			if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) {
 				csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
 				auto_csc = AUTO_CSC_DISABLE;
 				c0_c2_change = C0_C2_CHANGE_DISABLE;
 				csc_enable = v_CSC_ENABLE;
 			}
 		} else {
-			if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
+			if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) {
 				csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
 				auto_csc = AUTO_CSC_DISABLE;
 				c0_c2_change = C0_C2_CHANGE_DISABLE;
@@ -462,10 +423,12 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
 }
 
 static int inno_hdmi_setup(struct inno_hdmi *hdmi,
-			   struct drm_display_mode *mode)
+			   struct drm_crtc_state *new_crtc_state,
+			   struct drm_connector_state *new_conn_state)
 {
-	struct drm_display_info *display = &hdmi->connector.display_info;
-	unsigned long mpixelclock = mode->clock * 1000;
+	struct drm_connector *connector = &hdmi->connector;
+	struct drm_display_info *display = &connector->display_info;
+	struct drm_display_mode *mode = &new_crtc_state->adjusted_mode;
 
 	/* Mute video and audio output */
 	hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
@@ -479,8 +442,8 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
 
 	inno_hdmi_config_video_csc(hdmi);
 
-	if (display->is_hdmi)
-		inno_hdmi_config_video_avi(hdmi, mode);
+	drm_atomic_helper_connector_hdmi_update_infoframes(connector,
+							   new_conn_state->state);
 
 	/*
 	 * When IP controller have configured to an accurate video
@@ -488,13 +451,13 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
 	 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
 	 * clock rate, and reconfigure the DDC clock.
 	 */
-	inno_hdmi_i2c_init(hdmi, mpixelclock);
+	inno_hdmi_i2c_init(hdmi, new_conn_state->hdmi.tmds_char_rate);
 
 	/* Unmute video and audio output */
 	hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
 		  v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
 
-	inno_hdmi_power_up(hdmi, mpixelclock);
+	inno_hdmi_power_up(hdmi, new_conn_state->hdmi.tmds_char_rate);
 
 	return 0;
 }
@@ -546,7 +509,7 @@ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
 	if (WARN_ON(!crtc_state))
 		return;
 
-	inno_hdmi_setup(hdmi, &crtc_state->adjusted_mode);
+	inno_hdmi_setup(hdmi, crtc_state, conn_state);
 }
 
 static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
@@ -563,7 +526,6 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 			       struct drm_connector_state *conn_state)
 {
 	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
-	struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
 	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 	u8 vic = drm_match_cea_mode(mode);
 	struct inno_hdmi_connector_state *inno_conn_state =
@@ -580,12 +542,7 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
 	else
 		inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
 
-	inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
-	inno_conn_state->rgb_limited_range =
-		drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED;
-
-	return  inno_hdmi_display_mode_valid(hdmi,
-				&crtc_state->adjusted_mode) == MODE_OK ? 0 : -EINVAL;
+	return 0;
 }
 
 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
@@ -662,10 +619,9 @@ static void inno_hdmi_connector_reset(struct drm_connector *connector)
 		return;
 
 	__drm_atomic_helper_connector_reset(connector, &inno_conn_state->base);
+	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
 
 	inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
-	inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
-	inno_conn_state->rgb_limited_range = false;
 }
 
 static struct drm_connector_state *
@@ -698,6 +654,7 @@ static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
 };
 
 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
+	.atomic_check = drm_atomic_helper_connector_hdmi_check,
 	.get_modes = inno_hdmi_connector_get_modes,
 	.mode_valid = inno_hdmi_connector_mode_valid,
 };
@@ -725,10 +682,14 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &inno_hdmi_connector_helper_funcs);
-	drm_connector_init_with_ddc(drm, &hdmi->connector,
-				    &inno_hdmi_connector_funcs,
-				    DRM_MODE_CONNECTOR_HDMIA,
-				    hdmi->ddc);
+	drmm_connector_hdmi_init(drm, &hdmi->connector,
+				 "Rockchip", "Inno HDMI",
+				 &inno_hdmi_connector_funcs,
+				 &inno_hdmi_hdmi_connector_funcs,
+				 DRM_MODE_CONNECTOR_HDMIA,
+				 hdmi->ddc,
+				 BIT(HDMI_COLORSPACE_RGB),
+				 8);
 
 	drm_connector_attach_encoder(&hdmi->connector, encoder);
 

-- 
2.43.2



From fancer.lancer at gmail.com  Thu Feb 22 10:13:04 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 22 Feb 2024 21:13:04 +0300
Subject: [PATCH v5 19/20] EDAC/synopsys: Unify struct/macro/function prefixes
In-Reply-To: <20240222181324.28242-1-fancer.lancer@gmail.com>
References: <20240222181324.28242-1-fancer.lancer@gmail.com>
Message-ID: <20240222181324.28242-20-fancer.lancer@gmail.com>

Currently the driver entities naming schema is kind of random. There are
structures and methods with the "synps" prefix, there are structures and
methods with no driver-specific prefix, there are methods with the "edac"
prefix, there are structure instances with "zynqmp" and "synopsys"
prefixes, there are macros with "SYNPS", "ECC" and "DDR" prefixes.
Moreover some time ago some of function names were shortened out by
completely removing the vendor-specific prefixes thus leaving the driver
with no strict entities naming convention (see commit bb894bc46ed0 ("EDAC,
synopsys: Shorten static function names")).

All of that makes the code much harder to read for no much reason (except
shorter names utilization) since there is no easy way to distinguish now
the local, EDAC core and global name spaces right from the code context.
Similarly the kernel code index services (like elixir) gets to find the
different functions with the same name, which harden the kernel hacking.

Fix all of that by unifying the driver local entity names like functions,
structures and non-CSR-related macros especially seeing the same approach
has been used in the most of the EDAC LLDD. Use the "snps" prefix here as
the shortest version of the controller vendor name. While at it add a more
detailed controller name (DW uMCTL2 DDRC) to the driver comments and
string literals where it's appropriate.

Signed-off-by: Serge Semin <fancer.lancer at gmail.com>

---

Note "dw" prefix would be even shorter alternative. But we decided to
stick with "snps" since "synopsys" has already been used in the module
name.

Changelog v2:
- Forgot to fix some of the SYNPS_ZYNQMP_IRQ_REGS macro utilizations.
  (@tbot)
---
 drivers/edac/synopsys_edac.c | 241 ++++++++++++++++++-----------------
 1 file changed, 121 insertions(+), 120 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 1de9f3f86d5a..c46cee035c0d 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Synopsys DDR ECC Driver
+ * Synopsys DW uMCTL2 DDR ECC Driver
  * This driver is based on ppc4xx_edac.c drivers
  *
  * Copyright (C) 2012 - 2014 Xilinx, Inc.
@@ -16,23 +16,23 @@
 #include "edac_module.h"
 
 /* Number of cs_rows needed per memory controller */
-#define SYNPS_EDAC_NR_CSROWS		1
+#define SNPS_EDAC_NR_CSROWS		1
 
 /* Number of channels per memory controller */
-#define SYNPS_EDAC_NR_CHANS		1
+#define SNPS_EDAC_NR_CHANS		1
 
 /* Granularity of reported error in bytes */
-#define SYNPS_EDAC_ERR_GRAIN		1
+#define SNPS_EDAC_ERR_GRAIN		1
 
-#define SYNPS_EDAC_MSG_SIZE		256
+#define SNPS_EDAC_MSG_SIZE		256
 
-#define SYNPS_EDAC_MOD_STRING		"synps_edac"
-#define SYNPS_EDAC_MOD_VER		"1"
+#define SNPS_EDAC_MOD_STRING		"snps_edac"
+#define SNPS_EDAC_MOD_VER		"1"
 
 /* DDR ECC Quirks */
-#define SYNPS_ZYNQMP_IRQ_REGS		BIT(0)
+#define SNPS_ZYNQMP_IRQ_REGS		BIT(0)
 
-/* Synopsys DDR memory controller registers that are relevant to ECC */
+/* Synopsys uMCTL2 DDR controller registers that are relevant to ECC */
 
 /* DDRC Master 0 Register */
 #define DDR_MSTR_OFST			0x0
@@ -214,7 +214,7 @@
 #define ZYNQMP_DDR_QOS_IRQ_MASK		0x6
 
 /**
- * struct ecc_error_info - ECC error log information.
+ * struct snps_ecc_error_info - ECC error log information.
  * @row:	Row number.
  * @col:	Column number.
  * @bank:	Bank number.
@@ -222,7 +222,7 @@
  * @bitpos:	Bit position.
  * @data:	Data causing the error.
  */
-struct ecc_error_info {
+struct snps_ecc_error_info {
 	u32 row;
 	u32 col;
 	u32 bank;
@@ -232,21 +232,21 @@ struct ecc_error_info {
 };
 
 /**
- * struct synps_ecc_status - ECC status information to report.
+ * struct snps_ecc_status - ECC status information to report.
  * @ce_cnt:	Correctable error count.
  * @ue_cnt:	Uncorrectable error count.
  * @ceinfo:	Correctable error log information.
  * @ueinfo:	Uncorrectable error log information.
  */
-struct synps_ecc_status {
+struct snps_ecc_status {
 	u32 ce_cnt;
 	u32 ue_cnt;
-	struct ecc_error_info ceinfo;
-	struct ecc_error_info ueinfo;
+	struct snps_ecc_error_info ceinfo;
+	struct snps_ecc_error_info ueinfo;
 };
 
 /**
- * struct synps_edac_priv - DDR memory controller private instance data.
+ * struct snps_edac_priv - DDR memory controller private data.
  * @baseaddr:		Base address of the DDR controller.
  * @reglock:		Concurrent CSRs access lock.
  * @message:		Buffer for framing the event specific info.
@@ -259,12 +259,12 @@ struct synps_ecc_status {
  * @bankgrp_shift:	Bit shifts for bank group bit.
  * @rank_shift:		Bit shifts for rank bit.
  */
-struct synps_edac_priv {
+struct snps_edac_priv {
 	void __iomem *baseaddr;
 	spinlock_t reglock;
-	char message[SYNPS_EDAC_MSG_SIZE];
-	struct synps_ecc_status stat;
-	const struct synps_platform_data *p_data;
+	char message[SNPS_EDAC_MSG_SIZE];
+	struct snps_ecc_status stat;
+	const struct snps_platform_data *p_data;
 #ifdef CONFIG_EDAC_DEBUG
 	ulong poison_addr;
 	u32 row_shift[18];
@@ -276,22 +276,22 @@ struct synps_edac_priv {
 };
 
 /**
- * struct synps_platform_data - Synopsys uMCTL2 DDRC platform data.
+ * struct snps_platform_data - Synopsys uMCTL2 DDRC platform data.
  * @quirks:	IP-core specific quirks.
  */
-struct synps_platform_data {
+struct snps_platform_data {
 	u32 quirks;
 };
 
 /**
- * synps_get_error_info - Get the current ECC error info.
+ * snps_get_error_info - Get the current ECC error info.
  * @priv:	DDR memory controller private instance data.
  *
  * Return: one if there is no error otherwise returns zero.
  */
-static int synps_get_error_info(struct synps_edac_priv *priv)
+static int snps_get_error_info(struct snps_edac_priv *priv)
 {
-	struct synps_ecc_status *p;
+	struct snps_ecc_status *p;
 	u32 regval, clearval;
 	unsigned long flags;
 	void __iomem *base;
@@ -350,21 +350,21 @@ static int synps_get_error_info(struct synps_edac_priv *priv)
 }
 
 /**
- * handle_error - Handle Correctable and Uncorrectable errors.
+ * snps_handle_error - Handle Correctable and Uncorrectable errors.
  * @mci:	EDAC memory controller instance.
  * @p:		Synopsys ECC status structure.
  *
  * Handles ECC correctable and uncorrectable errors.
  */
-static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
+static void snps_handle_error(struct mem_ctl_info *mci, struct snps_ecc_status *p)
 {
-	struct synps_edac_priv *priv = mci->pvt_info;
-	struct ecc_error_info *pinf;
+	struct snps_edac_priv *priv = mci->pvt_info;
+	struct snps_ecc_error_info *pinf;
 
 	if (p->ce_cnt) {
 		pinf = &p->ceinfo;
 
-		snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
+		snprintf(priv->message, SNPS_EDAC_MSG_SIZE,
 			 "Row %d Col %d Bank %d Bank Group %d Bit %d Data 0x%08x",
 			 pinf->row, pinf->col, pinf->bank, pinf->bankgrp,
 			 pinf->bitpos, pinf->data);
@@ -377,7 +377,7 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 	if (p->ue_cnt) {
 		pinf = &p->ueinfo;
 
-		snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
+		snprintf(priv->message, SNPS_EDAC_MSG_SIZE,
 			 "Row %d Col %d Bank %d Bank Group %d",
 			 pinf->row, pinf->col, pinf->bank, pinf->bankgrp);
 
@@ -389,12 +389,12 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 	memset(p, 0, sizeof(*p));
 }
 
-static void enable_intr(struct synps_edac_priv *priv)
+static void snps_enable_irq(struct snps_edac_priv *priv)
 {
 	unsigned long flags;
 
 	/* Enable UE/CE Interrupts */
-	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) {
+	if (priv->p_data->quirks & SNPS_ZYNQMP_IRQ_REGS) {
 		writel(ZYNQMP_DDR_QOS_UE_MASK | ZYNQMP_DDR_QOS_CE_MASK,
 		       priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_EN_OFST);
 
@@ -413,12 +413,12 @@ static void enable_intr(struct synps_edac_priv *priv)
 	spin_unlock_irqrestore(&priv->reglock, flags);
 }
 
-static void disable_intr(struct synps_edac_priv *priv)
+static void snps_disable_irq(struct snps_edac_priv *priv)
 {
 	unsigned long flags;
 
 	/* Disable UE/CE Interrupts */
-	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) {
+	if (priv->p_data->quirks & SNPS_ZYNQMP_IRQ_REGS) {
 		writel(ZYNQMP_DDR_QOS_UE_MASK | ZYNQMP_DDR_QOS_CE_MASK,
 		       priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_DB_OFST);
 
@@ -433,41 +433,41 @@ static void disable_intr(struct synps_edac_priv *priv)
 }
 
 /**
- * intr_handler - Interrupt Handler for ECC interrupts.
+ * snps_irq_handler - Interrupt Handler for ECC interrupts.
  * @irq:        IRQ number.
  * @dev_id:     Device ID.
  *
  * Return: IRQ_NONE, if interrupt not set or IRQ_HANDLED otherwise.
  */
-static irqreturn_t intr_handler(int irq, void *dev_id)
+static irqreturn_t snps_irq_handler(int irq, void *dev_id)
 {
 	struct mem_ctl_info *mci = dev_id;
-	struct synps_edac_priv *priv;
+	struct snps_edac_priv *priv;
 	int status, regval;
 
 	priv = mci->pvt_info;
 
-	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) {
+	if (priv->p_data->quirks & SNPS_ZYNQMP_IRQ_REGS) {
 		regval = readl(priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_STAT_OFST);
 		regval &= (ZYNQMP_DDR_QOS_CE_MASK | ZYNQMP_DDR_QOS_UE_MASK);
 		if (!(regval & ZYNQMP_DDR_QOS_IRQ_MASK))
 			return IRQ_NONE;
 	}
 
-	status = synps_get_error_info(priv);
+	status = snps_get_error_info(priv);
 	if (status)
 		return IRQ_NONE;
 
-	handle_error(mci, &priv->stat);
+	snps_handle_error(mci, &priv->stat);
 
-	if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS)
+	if (priv->p_data->quirks & SNPS_ZYNQMP_IRQ_REGS)
 		writel(regval, priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_STAT_OFST);
 
 	return IRQ_HANDLED;
 }
 
 /**
- * synps_get_dtype - Return the controller memory width.
+ * snps_get_dtype - Return the controller memory width.
  * @base:	DDR memory controller base address.
  *
  * Get the EDAC device type width appropriate for the current controller
@@ -475,7 +475,7 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
  *
  * Return: a device type width enumeration.
  */
-static enum dev_type synps_get_dtype(const void __iomem *base)
+static enum dev_type snps_get_dtype(const void __iomem *base)
 {
 	u32 regval;
 
@@ -499,14 +499,14 @@ static enum dev_type synps_get_dtype(const void __iomem *base)
 }
 
 /**
- * synps_get_ecc_state - Return the controller ECC enable/disable status.
+ * snps_get_ecc_state - Return the controller ECC enable/disable status.
  * @base:	DDR memory controller base address.
  *
  * Get the ECC enable/disable status for the controller.
  *
  * Return: a ECC status boolean i.e true/false - enabled/disabled.
  */
-static bool synps_get_ecc_state(void __iomem *base)
+static bool snps_get_ecc_state(void __iomem *base)
 {
 	u32 regval;
 
@@ -516,11 +516,11 @@ static bool synps_get_ecc_state(void __iomem *base)
 }
 
 /**
- * get_memsize - Read the size of the attached memory device.
+ * snps_get_memsize - Read the size of the attached memory device.
  *
  * Return: the memory size in bytes.
  */
-static u32 get_memsize(void)
+static u32 snps_get_memsize(void)
 {
 	struct sysinfo inf;
 
@@ -530,7 +530,7 @@ static u32 get_memsize(void)
 }
 
 /**
- * synps_get_mtype - Returns controller memory type.
+ * snps_get_mtype - Returns controller memory type.
  * @base:	Synopsys ECC status structure.
  *
  * Get the EDAC memory type appropriate for the current controller
@@ -538,7 +538,7 @@ static u32 get_memsize(void)
  *
  * Return: a memory type enumeration.
  */
-static enum mem_type synps_get_mtype(const void __iomem *base)
+static enum mem_type snps_get_mtype(const void __iomem *base)
 {
 	enum mem_type mt;
 	u32 memtype;
@@ -558,15 +558,15 @@ static enum mem_type synps_get_mtype(const void __iomem *base)
 }
 
 /**
- * init_csrows - Initialize the csrow data.
+ * snps_init_csrows - Initialize the csrow data.
  * @mci:	EDAC memory controller instance.
  *
  * Initialize the chip select rows associated with the EDAC memory
  * controller instance.
  */
-static void init_csrows(struct mem_ctl_info *mci)
+static void snps_init_csrows(struct mem_ctl_info *mci)
 {
-	struct synps_edac_priv *priv = mci->pvt_info;
+	struct snps_edac_priv *priv = mci->pvt_info;
 	struct csrow_info *csi;
 	struct dimm_info *dimm;
 	u32 size, row;
@@ -574,21 +574,21 @@ static void init_csrows(struct mem_ctl_info *mci)
 
 	for (row = 0; row < mci->nr_csrows; row++) {
 		csi = mci->csrows[row];
-		size = get_memsize();
+		size = snps_get_memsize();
 
 		for (j = 0; j < csi->nr_channels; j++) {
 			dimm		= csi->channels[j]->dimm;
 			dimm->edac_mode	= EDAC_SECDED;
-			dimm->mtype	= synps_get_mtype(priv->baseaddr);
+			dimm->mtype	= snps_get_mtype(priv->baseaddr);
 			dimm->nr_pages	= (size >> PAGE_SHIFT) / csi->nr_channels;
-			dimm->grain	= SYNPS_EDAC_ERR_GRAIN;
-			dimm->dtype	= synps_get_dtype(priv->baseaddr);
+			dimm->grain	= SNPS_EDAC_ERR_GRAIN;
+			dimm->dtype	= snps_get_dtype(priv->baseaddr);
 		}
 	}
 }
 
 /**
- * mc_init - Initialize one driver instance.
+ * snps_mc_init - Initialize one driver instance.
  * @mci:	EDAC memory controller instance.
  * @pdev:	platform device.
  *
@@ -596,7 +596,7 @@ static void init_csrows(struct mem_ctl_info *mci)
  * related driver-private data associated with the memory controller the
  * instance is bound to.
  */
-static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
+static void snps_mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
 {
 	mci->pdev = &pdev->dev;
 	platform_set_drvdata(pdev, mci);
@@ -608,21 +608,22 @@ static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
 	mci->scrub_mode = SCRUB_NONE;
 
 	mci->edac_cap = EDAC_FLAG_SECDED;
-	mci->ctl_name = "synps_ddr_controller";
-	mci->dev_name = SYNPS_EDAC_MOD_STRING;
-	mci->mod_name = SYNPS_EDAC_MOD_VER;
+	mci->ctl_name = "snps_umctl2_ddrc";
+	mci->dev_name = SNPS_EDAC_MOD_STRING;
+	mci->mod_name = SNPS_EDAC_MOD_VER;
 
 	edac_op_state = EDAC_OPSTATE_INT;
 
 	mci->ctl_page_to_phys = NULL;
 
-	init_csrows(mci);
+	snps_init_csrows(mci);
 }
 
-static int setup_irq(struct mem_ctl_info *mci,
-		     struct platform_device *pdev)
+
+
+static int snps_setup_irq(struct mem_ctl_info *mci, struct platform_device *pdev)
 {
-	struct synps_edac_priv *priv = mci->pvt_info;
+	struct snps_edac_priv *priv = mci->pvt_info;
 	int ret, irq;
 
 	irq = platform_get_irq(pdev, 0);
@@ -632,14 +633,14 @@ static int setup_irq(struct mem_ctl_info *mci,
 		return irq;
 	}
 
-	ret = devm_request_irq(&pdev->dev, irq, intr_handler,
+	ret = devm_request_irq(&pdev->dev, irq, snps_irq_handler,
 			       0, dev_name(&pdev->dev), mci);
 	if (ret < 0) {
 		edac_printk(KERN_ERR, EDAC_MC, "Failed to request IRQ\n");
 		return ret;
 	}
 
-	enable_intr(priv);
+	snps_enable_irq(priv);
 
 	return 0;
 }
@@ -647,13 +648,13 @@ static int setup_irq(struct mem_ctl_info *mci,
 #ifdef CONFIG_EDAC_DEBUG
 
 /**
- * ddr_poison_setup -	Update poison registers.
+ * snps_data_poison_setup - Update poison registers.
  * @priv:		DDR memory controller private instance data.
  *
  * Update poison registers as per DDR mapping.
  * Return: none.
  */
-static void ddr_poison_setup(struct synps_edac_priv *priv)
+static void snps_data_poison_setup(struct snps_edac_priv *priv)
 {
 	int col = 0, row = 0, bank = 0, bankgrp = 0, rank = 0, regval;
 	int index;
@@ -711,7 +712,7 @@ static ssize_t inject_data_error_show(struct device *dev,
 				      char *data)
 {
 	struct mem_ctl_info *mci = to_mci(dev);
-	struct synps_edac_priv *priv = mci->pvt_info;
+	struct snps_edac_priv *priv = mci->pvt_info;
 
 	return sprintf(data, "Poison0 Addr: 0x%08x\n\rPoison1 Addr: 0x%08x\n\r"
 			"Error injection Address: 0x%lx\n\r",
@@ -725,12 +726,12 @@ static ssize_t inject_data_error_store(struct device *dev,
 				       const char *data, size_t count)
 {
 	struct mem_ctl_info *mci = to_mci(dev);
-	struct synps_edac_priv *priv = mci->pvt_info;
+	struct snps_edac_priv *priv = mci->pvt_info;
 
 	if (kstrtoul(data, 0, &priv->poison_addr))
 		return -EINVAL;
 
-	ddr_poison_setup(priv);
+	snps_data_poison_setup(priv);
 
 	return count;
 }
@@ -740,7 +741,7 @@ static ssize_t inject_data_poison_show(struct device *dev,
 				       char *data)
 {
 	struct mem_ctl_info *mci = to_mci(dev);
-	struct synps_edac_priv *priv = mci->pvt_info;
+	struct snps_edac_priv *priv = mci->pvt_info;
 
 	return sprintf(data, "Data Poisoning: %s\n\r",
 			(((readl(priv->baseaddr + ECC_CFG1_OFST)) & 0x3) == 0x3)
@@ -752,7 +753,7 @@ static ssize_t inject_data_poison_store(struct device *dev,
 					const char *data, size_t count)
 {
 	struct mem_ctl_info *mci = to_mci(dev);
-	struct synps_edac_priv *priv = mci->pvt_info;
+	struct snps_edac_priv *priv = mci->pvt_info;
 
 	writel(0, priv->baseaddr + DDR_SWCTL);
 	if (strncmp(data, "CE", 2) == 0)
@@ -767,7 +768,7 @@ static ssize_t inject_data_poison_store(struct device *dev,
 static DEVICE_ATTR_RW(inject_data_error);
 static DEVICE_ATTR_RW(inject_data_poison);
 
-static int edac_create_sysfs_attributes(struct mem_ctl_info *mci)
+static int snps_create_sysfs_attributes(struct mem_ctl_info *mci)
 {
 	int rc;
 
@@ -780,13 +781,13 @@ static int edac_create_sysfs_attributes(struct mem_ctl_info *mci)
 	return 0;
 }
 
-static void edac_remove_sysfs_attributes(struct mem_ctl_info *mci)
+static void snps_remove_sysfs_attributes(struct mem_ctl_info *mci)
 {
 	device_remove_file(&mci->dev, &dev_attr_inject_data_error);
 	device_remove_file(&mci->dev, &dev_attr_inject_data_poison);
 }
 
-static void setup_row_address_map(struct synps_edac_priv *priv, u32 *addrmap)
+static void snps_setup_row_address_map(struct snps_edac_priv *priv, u32 *addrmap)
 {
 	u32 addrmap_row_b2_10;
 	int index;
@@ -845,7 +846,7 @@ static void setup_row_address_map(struct synps_edac_priv *priv, u32 *addrmap)
 				ROW_MAX_VAL_MASK) + ROW_B17_BASE);
 }
 
-static void setup_column_address_map(struct synps_edac_priv *priv, u32 *addrmap)
+static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addrmap)
 {
 	u32 width, memtype;
 	int index;
@@ -947,7 +948,7 @@ static void setup_column_address_map(struct synps_edac_priv *priv, u32 *addrmap)
 
 }
 
-static void setup_bank_address_map(struct synps_edac_priv *priv, u32 *addrmap)
+static void snps_setup_bank_address_map(struct snps_edac_priv *priv, u32 *addrmap)
 {
 	priv->bank_shift[0] = (addrmap[1] & BANK_MAX_VAL_MASK) + BANK_B0_BASE;
 	priv->bank_shift[1] = ((addrmap[1] >> 8) &
@@ -959,7 +960,7 @@ static void setup_bank_address_map(struct synps_edac_priv *priv, u32 *addrmap)
 
 }
 
-static void setup_bg_address_map(struct synps_edac_priv *priv, u32 *addrmap)
+static void snps_setup_bg_address_map(struct snps_edac_priv *priv, u32 *addrmap)
 {
 	priv->bankgrp_shift[0] = (addrmap[8] &
 				BANKGRP_MAX_VAL_MASK) + BANKGRP_B0_BASE;
@@ -969,7 +970,7 @@ static void setup_bg_address_map(struct synps_edac_priv *priv, u32 *addrmap)
 
 }
 
-static void setup_rank_address_map(struct synps_edac_priv *priv, u32 *addrmap)
+static void snps_setup_rank_address_map(struct snps_edac_priv *priv, u32 *addrmap)
 {
 	priv->rank_shift[0] = ((addrmap[0] & RANK_MAX_VAL_MASK) ==
 				RANK_MAX_VAL_MASK) ? 0 : ((addrmap[0] &
@@ -977,14 +978,14 @@ static void setup_rank_address_map(struct synps_edac_priv *priv, u32 *addrmap)
 }
 
 /**
- * setup_address_map -	Set Address Map by querying ADDRMAP registers.
+ * snps_setup_address_map -	Set Address Map by querying ADDRMAP registers.
  * @priv:		DDR memory controller private instance data.
  *
  * Set Address Map by querying ADDRMAP registers.
  *
  * Return: none.
  */
-static void setup_address_map(struct synps_edac_priv *priv)
+static void snps_setup_address_map(struct snps_edac_priv *priv)
 {
 	u32 addrmap[12];
 	int index;
@@ -996,20 +997,20 @@ static void setup_address_map(struct synps_edac_priv *priv)
 		addrmap[index] = readl(priv->baseaddr + addrmap_offset);
 	}
 
-	setup_row_address_map(priv, addrmap);
+	snps_setup_row_address_map(priv, addrmap);
 
-	setup_column_address_map(priv, addrmap);
+	snps_setup_column_address_map(priv, addrmap);
 
-	setup_bank_address_map(priv, addrmap);
+	snps_setup_bank_address_map(priv, addrmap);
 
-	setup_bg_address_map(priv, addrmap);
+	snps_setup_bg_address_map(priv, addrmap);
 
-	setup_rank_address_map(priv, addrmap);
+	snps_setup_rank_address_map(priv, addrmap);
 }
 #endif /* CONFIG_EDAC_DEBUG */
 
 /**
- * mc_probe - Check controller and bind driver.
+ * snps_mc_probe - Check controller and bind driver.
  * @pdev:	platform device.
  *
  * Probe a specific controller instance for binding with the driver.
@@ -1017,11 +1018,11 @@ static void setup_address_map(struct synps_edac_priv *priv)
  * Return: 0 if the controller instance was successfully bound to the
  * driver; otherwise, < 0 on error.
  */
-static int mc_probe(struct platform_device *pdev)
+static int snps_mc_probe(struct platform_device *pdev)
 {
-	const struct synps_platform_data *p_data;
+	const struct snps_platform_data *p_data;
 	struct edac_mc_layer layers[2];
-	struct synps_edac_priv *priv;
+	struct snps_edac_priv *priv;
 	struct mem_ctl_info *mci;
 	void __iomem *baseaddr;
 	int rc;
@@ -1034,20 +1035,20 @@ static int mc_probe(struct platform_device *pdev)
 	if (!p_data)
 		return -ENODEV;
 
-	if (!synps_get_ecc_state(baseaddr)) {
+	if (!snps_get_ecc_state(baseaddr)) {
 		edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
 		return -ENXIO;
 	}
 
 	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
-	layers[0].size = SYNPS_EDAC_NR_CSROWS;
+	layers[0].size = SNPS_EDAC_NR_CSROWS;
 	layers[0].is_virt_csrow = true;
 	layers[1].type = EDAC_MC_LAYER_CHANNEL;
-	layers[1].size = SYNPS_EDAC_NR_CHANS;
+	layers[1].size = SNPS_EDAC_NR_CHANS;
 	layers[1].is_virt_csrow = false;
 
 	mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers,
-			    sizeof(struct synps_edac_priv));
+			    sizeof(struct snps_edac_priv));
 	if (!mci) {
 		edac_printk(KERN_ERR, EDAC_MC,
 			    "Failed memory allocation for mc instance\n");
@@ -1059,9 +1060,9 @@ static int mc_probe(struct platform_device *pdev)
 	priv->p_data = p_data;
 	spin_lock_init(&priv->reglock);
 
-	mc_init(mci, pdev);
+	snps_mc_init(mci, pdev);
 
-	rc = setup_irq(mci, pdev);
+	rc = snps_setup_irq(mci, pdev);
 	if (rc)
 		goto free_edac_mc;
 
@@ -1073,13 +1074,13 @@ static int mc_probe(struct platform_device *pdev)
 	}
 
 #ifdef CONFIG_EDAC_DEBUG
-	rc = edac_create_sysfs_attributes(mci);
+	rc = snps_create_sysfs_attributes(mci);
 	if (rc) {
 		edac_printk(KERN_ERR, EDAC_MC, "Failed to create sysfs entries\n");
 		goto free_edac_mc;
 	}
 
-	setup_address_map(priv);
+	snps_setup_address_map(priv);
 #endif
 
 	return rc;
@@ -1091,52 +1092,52 @@ static int mc_probe(struct platform_device *pdev)
 }
 
 /**
- * mc_remove - Unbind driver from controller.
+ * snps_mc_remove - Unbind driver from device.
  * @pdev:	Platform device.
  *
  * Return: Unconditionally 0
  */
-static void mc_remove(struct platform_device *pdev)
+
+static void snps_mc_remove(struct platform_device *pdev)
 {
 	struct mem_ctl_info *mci = platform_get_drvdata(pdev);
-	struct synps_edac_priv *priv = mci->pvt_info;
+	struct snps_edac_priv *priv = mci->pvt_info;
 
-	disable_intr(priv);
+	snps_disable_irq(priv);
 
 #ifdef CONFIG_EDAC_DEBUG
-	edac_remove_sysfs_attributes(mci);
+	snps_remove_sysfs_attributes(mci);
 #endif
 
 	edac_mc_del_mc(&pdev->dev);
 	edac_mc_free(mci);
 }
 
-static const struct synps_platform_data zynqmp_edac_def = {
-	.quirks = SYNPS_ZYNQMP_IRQ_REGS,
+static const struct snps_platform_data zynqmp_edac_def = {
+	.quirks = SNPS_ZYNQMP_IRQ_REGS,
 };
 
-static const struct synps_platform_data synopsys_edac_def = {
+static const struct snps_platform_data snps_edac_def = {
 	.quirks = 0,
 };
 
-static const struct of_device_id synps_edac_match[] = {
+static const struct of_device_id snps_edac_match[] = {
 	{ .compatible = "xlnx,zynqmp-ddrc-2.40a", .data = &zynqmp_edac_def },
-	{ .compatible = "snps,ddrc-3.80a", .data = &synopsys_edac_def },
+	{ .compatible = "snps,ddrc-3.80a", .data = &snps_edac_def },
 	{ }
 };
-MODULE_DEVICE_TABLE(of, synps_edac_match);
+MODULE_DEVICE_TABLE(of, snps_edac_match);
 
-static struct platform_driver synps_edac_mc_driver = {
+static struct platform_driver snps_edac_mc_driver = {
 	.driver = {
-		   .name = "synopsys-edac",
-		   .of_match_table = synps_edac_match,
+		   .name = "snps-edac",
+		   .of_match_table = snps_edac_match,
 		   },
-	.probe = mc_probe,
-	.remove_new = mc_remove,
+	.probe = snps_mc_probe,
+	.remove_new = snps_mc_remove,
 };
-
-module_platform_driver(synps_edac_mc_driver);
+module_platform_driver(snps_edac_mc_driver);
 
 MODULE_AUTHOR("Xilinx Inc");
-MODULE_DESCRIPTION("Synopsys DDR ECC driver");
+MODULE_DESCRIPTION("Synopsys uMCTL2 DDR ECC driver");
 MODULE_LICENSE("GPL v2");
-- 
2.43.0



From broonie at kernel.org  Thu Feb 22 10:41:13 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 22 Feb 2024 18:41:13 +0000
Subject: [PATCH 4/4] ASoC: sun8i-codec: Implement jack and accessory
 detection
In-Reply-To: <20240222181851.3398254-5-megi@xff.cz>
References: <20240222181851.3398254-1-megi@xff.cz>
 <20240222181851.3398254-5-megi@xff.cz>
Message-ID: <0c351386-f1df-443f-a997-261f5c60c852@sirena.org.uk>

On Thu, Feb 22, 2024 at 07:18:47PM +0100, Ond?ej Jirman wrote:

> +static struct snd_soc_jack_pin sun8i_codec_jack_pins[] = {
> +	{
> +		.pin	= "Headphone Jack",
> +		.mask	= SND_JACK_HEADPHONE,
> +	},
> +	{
> +		.pin	= "Headset Microphone",
> +		.mask	= SND_JACK_MICROPHONE,
> +	},
> +};
> +

The jack being a headset jack is going to be system specific isn't it?
Some systems might have separate headphone and microphone jacks.  I'd
not expect to see any pin handling code at all in a CODEC driver, that
belongs in the machine driver.

>  static int sun8i_codec_component_probe(struct snd_soc_component *component)
>  {
>  	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
>  	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
>  	int ret;
>  
> +	scodec->card = component->card;
> +

The fact that you're needing to look at the card here should be a bit of
a warning sign there.
-------------- 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/20240222/ee08a653/attachment.sig>

From daniel.lezcano at linaro.org  Thu Feb 22 10:44:12 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Thu, 22 Feb 2024 19:44:12 +0100
Subject: [PATCH v5 1/7] soc: sunxi: sram: export register 0 for THS on
 H616
In-Reply-To: <2717467.mvXUDI8C0e@jernej-laptop>
References: <20240219153639.179814-1-andre.przywara@arm.com>
 <20240219153639.179814-2-andre.przywara@arm.com>
 <2717467.mvXUDI8C0e@jernej-laptop>
Message-ID: <dcd115fd-dc38-4f48-8485-9e4d64f53b4a@linaro.org>

On 22/02/2024 19:26, Jernej ?krabec wrote:
> Dne ponedeljek, 19. februar 2024 ob 16:36:33 CET je Andre Przywara napisal(a):
>> The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
>> in the SRAM control block. If bit 16 is set (the reset value), the
>> temperature readings of the THS are way off, leading to reports about
>> 200C, at normal ambient temperatures. Clearing this bits brings the
>> reported values down to the expected values.
>> The BSP code clears this bit in firmware (U-Boot), and has an explicit
>> comment about this, but offers no real explanation.
>>
>> Experiments in U-Boot show that register 0x0 has no effect on the SRAM C
>> visibility: all tested bit settings still allow full read and write
>> access by the CPU to the whole of SRAM C. Only bit 24 of the register at
>> offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling
>> the THS switch functionality as an SRAM region would not reflect reality.
>>
>> Since we should not rely on firmware settings, allow other code (the THS
>> driver) to access this register, by exporting it through the already
>> existing regmap. This mimics what we already do for the LDO control and
>> the EMAC register.
>>
>> To avoid concurrent accesses to the same register at the same time, by
>> the SRAM switch code and the regmap code, use the same lock to protect
>> the access. The regmap subsystem allows to use an existing lock, so we
>> just need to hook in there.
>>
>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> 
> Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> 
> I guess this one goes through sunxi tree, right?

I'll pick this patch along with the patch 2-6, so through the thermal 
tree. The patch 7/7 will go indeed via the sunxi tree


-- 
<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 broonie at kernel.org  Thu Feb 22 10:46:53 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 22 Feb 2024 18:46:53 +0000
Subject: [PATCH 0/4] Add support for jack detection to codec present in
 A64 SoC
In-Reply-To: <20240222181851.3398254-1-megi@xff.cz>
References: <20240222181851.3398254-1-megi@xff.cz>
Message-ID: <e9f22300-d303-4ca2-84ca-47f7130a0dc1@sirena.org.uk>

On Thu, Feb 22, 2024 at 07:18:43PM +0100, Ond?ej Jirman wrote:
> From: Ondrej Jirman <megi at xff.cz>
> 
> This series adds support for jack detection to this codec. I used
> and tested this on Pinephone. It works quite nicely. I tested it
> against Android headset mic button resistor specification.

I'd expect to see this implementing a set_jack() operation in the CODEC
driver and then using that from the machine driver.
-------------- 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/20240222/c472d01d/attachment.sig>

From u.kleine-koenig at pengutronix.de  Thu Feb 22 10:52:32 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Thu, 22 Feb 2024 19:52:32 +0100
Subject: [PATCH 0/7] ACPI: Convert to platform remove callback returning void
Message-ID: <cover.1708627599.git.u.kleine-koenig@pengutronix.de>

Hello,

this series converts all drivers below drivers/acpi to struct
platform_driver::remove_new(). See commit 5c5a7680e67b ("platform:
Provide a remove callback that returns no value") for an extended
explanation and the eventual goal.

All conversations are trivial, because their .remove() callbacks
returned zero unconditionally.

There are no interdependencies between these patches, so they could be
picked up individually. But I'd hope that they get picked up all
together by Rafael.

There is another driver that needs adaption (as of today's next), but
this is discussed separately, see
https://lore.kernel.org/linux-acpi/CAJZ5v0jJX-6L9f_TLe-cv2MNnZVK7au=drbKCn-tEWEagY-9ZA at mail.gmail.com
.

Best regards
Uwe

Uwe Kleine-K?nig (7):
  ACPI: TAD: Convert to platform remove callback returning void
  ACPI: AGDI: Convert to platform remove callback returning void
  ACPI: DPTF: Convert to platform remove callback returning void
  ACPI: GED: Convert to platform remove callback returning void
  ACPI: fan: Convert to platform remove callback returning void
  ACPI: pfr_telemetry: Convert to platform remove callback returning void
  ACPI: pfr_update: Convert to platform remove callback returning void

 drivers/acpi/acpi_tad.c           | 5 ++---
 drivers/acpi/arm64/agdi.c         | 8 +++-----
 drivers/acpi/dptf/dptf_pch_fivr.c | 6 ++----
 drivers/acpi/dptf/dptf_power.c    | 6 ++----
 drivers/acpi/evged.c              | 5 ++---
 drivers/acpi/fan_core.c           | 6 ++----
 drivers/acpi/pfr_telemetry.c      | 6 ++----
 drivers/acpi/pfr_update.c         | 6 ++----
 8 files changed, 17 insertions(+), 31 deletions(-)

base-commit: 4893c639cc3659cefaa675bf1e59f4e7571afb5c
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Thu Feb 22 10:52:34 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Thu, 22 Feb 2024 19:52:34 +0100
Subject: [PATCH 2/7] ACPI: AGDI: Convert to platform remove callback returning void
In-Reply-To: <cover.1708627599.git.u.kleine-koenig@pengutronix.de>
References: <cover.1708627599.git.u.kleine-koenig@pengutronix.de>
Message-ID: <c41853160b8947e865357f99171cfbdbb4b4804e.1708627599.git.u.kleine-koenig@pengutronix.de>

The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.

To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new(), which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().

Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/acpi/arm64/agdi.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
index 8b3c7d42b41b..f5f21dd0d277 100644
--- a/drivers/acpi/arm64/agdi.c
+++ b/drivers/acpi/arm64/agdi.c
@@ -58,7 +58,7 @@ static int agdi_probe(struct platform_device *pdev)
 	return agdi_sdei_probe(pdev, adata);
 }
 
-static int agdi_remove(struct platform_device *pdev)
+static void agdi_remove(struct platform_device *pdev)
 {
 	struct agdi_data *adata = dev_get_platdata(&pdev->dev);
 	int err, i;
@@ -67,7 +67,7 @@ static int agdi_remove(struct platform_device *pdev)
 	if (err) {
 		dev_err(&pdev->dev, "Failed to disable sdei-event #%d (%pe)\n",
 			adata->sdei_event, ERR_PTR(err));
-		return 0;
+		return;
 	}
 
 	for (i = 0; i < 3; i++) {
@@ -81,8 +81,6 @@ static int agdi_remove(struct platform_device *pdev)
 	if (err)
 		dev_err(&pdev->dev, "Failed to unregister sdei-event #%d (%pe)\n",
 			adata->sdei_event, ERR_PTR(err));
-
-	return 0;
 }
 
 static struct platform_driver agdi_driver = {
@@ -90,7 +88,7 @@ static struct platform_driver agdi_driver = {
 		.name = "agdi",
 	},
 	.probe = agdi_probe,
-	.remove = agdi_remove,
+	.remove_new = agdi_remove,
 };
 
 void __init acpi_agdi_init(void)
-- 
2.43.0



From linus.walleij at linaro.org  Thu Feb 22 10:53:30 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 22 Feb 2024 19:53:30 +0100
Subject: [PATCH v2 4/4] ARM: Implement privileged no-access using TTBR0
 page table walks disabling
In-Reply-To: <20240221-arm32-lpae-pan-v2-4-991096bba5d8@linaro.org>
References: <20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org> <20240221-arm32-lpae-pan-v2-4-991096bba5d8@linaro.org>
Message-ID: <CACRpkdYFna6peiz6YeHVmaN82ZBnN1kmgE3iurX3NoUJ1SsU9Q@mail.gmail.com>

On Wed, Feb 21, 2024 at 12:04?AM Linus Walleij <linus.walleij at linaro.org> wrote:

>  static inline unsigned int uaccess_save_and_enable(void)
> @@ -54,6 +78,12 @@ static inline void uaccess_restore(unsigned int flags)
>  {
>  }
>
> +static inline bool uaccess_disabled(struct pt_regs *regs)
> +{
> +       /* Without PAN userspace is always available */
> +       return false;
> +}
> +
>  #endif

Yes I forgot this unused stub here. I have deleted it from my tree.

Yours,
Linus Walleij


From mathieu.poirier at linaro.org  Thu Feb 22 11:02:40 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 22 Feb 2024 12:02:40 -0700
Subject: [PATCH v3 7/7] remoteproc: stm32: Add support of an OP-TEE TA to
 load the firmware
In-Reply-To: <20240214172127.1022199-8-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <20240214172127.1022199-8-arnaud.pouliquen@foss.st.com>
Message-ID: <ZdeaUGpWlqGOG31u@p14s>

Hi,

On Wed, Feb 14, 2024 at 06:21:27PM +0100, Arnaud Pouliquen wrote:
> The new TEE remoteproc device is used to manage remote firmware in a
> secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
> introduced to delegate the loading of the firmware to the trusted
> execution context. In such cases, the firmware should be signed and
> adhere to the image format defined by the TEE.
> 
> A new "to_attach" field is introduced to differentiate the use cases
> "firmware loaded by the boot stage" and "firmware loaded by the TEE".
> 
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
> ---
> V2 to V3 update:
> - remove stm32_rproc_tee_elf_sanity_check(), stm32_rproc_tee_elf_load()
>   stm32_rproc_tee_elf_find_loaded_rsc_table() and  stm32_rproc_tee_start() that are bnow unused
> - use new rproc::alt_boot field to sepcify that the alternate fboot method is used
> - use stm32_rproc::to_attach field to differenciate attch mode from remoteproc tee boot mode.
> - remove the used of stm32_rproc::fw_loaded
> ---
>  drivers/remoteproc/stm32_rproc.c | 85 +++++++++++++++++++++++++++++---
>  1 file changed, 79 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
> index fcc0001e2657..9cfcf66462e0 100644
> --- a/drivers/remoteproc/stm32_rproc.c
> +++ b/drivers/remoteproc/stm32_rproc.c
> @@ -20,6 +20,7 @@
>  #include <linux/remoteproc.h>
>  #include <linux/reset.h>
>  #include <linux/slab.h>
> +#include <linux/tee_remoteproc.h>
>  #include <linux/workqueue.h>
>  
>  #include "remoteproc_internal.h"
> @@ -49,6 +50,9 @@
>  #define M4_STATE_STANDBY	4
>  #define M4_STATE_CRASH		5
>  
> +/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
> +#define STM32_MP1_M4_PROC_ID    0
> +
>  struct stm32_syscon {
>  	struct regmap *map;
>  	u32 reg;
> @@ -90,6 +94,8 @@ struct stm32_rproc {
>  	struct stm32_mbox mb[MBOX_NB_MBX];
>  	struct workqueue_struct *workqueue;
>  	bool hold_boot_smc;
> +	bool to_attach;
> +	struct tee_rproc *trproc;
>  	void __iomem *rsc_va;
>  };
>  
> @@ -253,10 +259,30 @@ static int stm32_rproc_release(struct rproc *rproc)
>  			return err;
>  		}
>  	}
> +	ddata->to_attach = false;
>  
>  	return err;
>  }
>  
> +static int stm32_rproc_tee_attach(struct rproc *rproc)
> +{
> +	/* Nothing to do, remote proc already started by the secured context. */
> +	return 0;
> +}
> +
> +static int stm32_rproc_tee_stop(struct rproc *rproc)
> +{
> +	int err;
> +
> +	stm32_rproc_request_shutdown(rproc);
> +
> +	err = tee_rproc_stop(rproc);
> +	if (err)
> +		return err;
> +
> +	return stm32_rproc_release(rproc);
> +}
> +
>  static int stm32_rproc_prepare(struct rproc *rproc)
>  {
>  	struct device *dev = rproc->dev.parent;
> @@ -637,10 +663,14 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
>  {
>  	struct stm32_rproc *ddata = rproc->priv;
>  	struct device *dev = rproc->dev.parent;
> +	struct tee_rproc *trproc = ddata->trproc;
>  	phys_addr_t rsc_pa;
>  	u32 rsc_da;
>  	int err;
>  
> +	if (trproc && !ddata->to_attach)
> +		return tee_rproc_get_loaded_rsc_table(rproc, table_sz);
> +

Why do we need a flag at all?  Why can't st_rproc_tee_ops::get_loaded_rsc_table
be set to tee_rproc_get_loaded_rsc_table()?

>  	/* The resource table has already been mapped, nothing to do */
>  	if (ddata->rsc_va)
>  		goto done;
> @@ -693,8 +723,20 @@ static const struct rproc_ops st_rproc_ops = {
>  	.get_boot_addr	= rproc_elf_get_boot_addr,
>  };
>  
> +static const struct rproc_ops st_rproc_tee_ops = {
> +	.prepare	= stm32_rproc_prepare,
> +	.start		= tee_rproc_start,
> +	.stop		= stm32_rproc_tee_stop,
> +	.attach		= stm32_rproc_tee_attach,
> +	.kick		= stm32_rproc_kick,
> +	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
> +	.find_loaded_rsc_table = tee_rproc_find_loaded_rsc_table,
> +	.load		= tee_rproc_load_fw,
> +};
> +
>  static const struct of_device_id stm32_rproc_match[] = {
> -	{ .compatible = "st,stm32mp1-m4" },
> +	{.compatible = "st,stm32mp1-m4",},
> +	{.compatible = "st,stm32mp1-m4-tee",},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, stm32_rproc_match);
> @@ -853,6 +895,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct stm32_rproc *ddata;
>  	struct device_node *np = dev->of_node;
> +	struct tee_rproc *trproc = NULL;
>  	struct rproc *rproc;
>  	unsigned int state;
>  	int ret;
> @@ -861,12 +904,33 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> -	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
> -	if (!rproc)
> -		return -ENOMEM;

This patch doesn't apply to rproc-next - please rebase.


> +	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
> +		/*
> +		 * Delegate the firmware management to the secure context.
> +		 * The firmware loaded has to be signed.
> +		 */
> +		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
> +		if (IS_ERR(trproc)) {
> +			dev_err_probe(dev, PTR_ERR(trproc),
> +				      "signed firmware not supported by TEE\n");
> +			return PTR_ERR(trproc);
> +		}
> +	}
>  
> -	ddata = rproc->priv;
> +	rproc = rproc_alloc(dev, np->name,
> +			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
> +			    NULL, sizeof(*ddata));
> +	if (!rproc) {
> +		ret = -ENOMEM;
> +		goto free_tee;
> +	}
>  
> +	ddata = rproc->priv;
> +	ddata->trproc = trproc;

My opinion hasn't changed from the previous patchet, i.e tee_rproc should be
folded in struct rproc as rproc::tee_interface.

More comments to come shortly...

> +	if (trproc) {
> +		rproc->alt_boot = true;
> +		trproc->rproc = rproc;
> +	}
>  	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
>  
>  	ret = stm32_rproc_parse_dt(pdev, ddata, &rproc->auto_boot);
> @@ -881,8 +945,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto free_rproc;
>  
> -	if (state == M4_STATE_CRUN)
> +	if (state == M4_STATE_CRUN) {
>  		rproc->state = RPROC_DETACHED;
> +		ddata->to_attach = true;
> +	}
>  
>  	rproc->has_iommu = false;
>  	ddata->workqueue = create_workqueue(dev_name(dev));
> @@ -916,6 +982,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>  		device_init_wakeup(dev, false);
>  	}
>  	rproc_free(rproc);
> +free_tee:
> +	if (trproc)
> +		tee_rproc_unregister(trproc);
> +
>  	return ret;
>  }
>  
> @@ -923,6 +993,7 @@ static void stm32_rproc_remove(struct platform_device *pdev)
>  {
>  	struct rproc *rproc = platform_get_drvdata(pdev);
>  	struct stm32_rproc *ddata = rproc->priv;
> +	struct tee_rproc *trproc = ddata->trproc;
>  	struct device *dev = &pdev->dev;
>  
>  	if (atomic_read(&rproc->power) > 0)
> @@ -937,6 +1008,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
>  		device_init_wakeup(dev, false);
>  	}
>  	rproc_free(rproc);
> +	if (trproc)
> +		tee_rproc_unregister(trproc);
>  }
>  
>  static int stm32_rproc_suspend(struct device *dev)
> -- 
> 2.25.1
> 


From jernej.skrabec at gmail.com  Thu Feb 22 11:08:05 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 20:08:05 +0100
Subject: [PATCH v7 32/36] drm/sun4i: hdmi: Convert encoder to atomic
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-32-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-32-8f4af575fce2@kernel.org>
Message-ID: <4545275.LvFx2qVVIh@jernej-laptop>

Dne ?etrtek, 22. februar 2024 ob 19:14:18 CET je Maxime Ripard napisal(a):
> The sun4i_hdmi driver still uses the non-atomic variants of the encoder
> hooks, so let's convert to their atomic equivalents.
> 
> Acked-by: Sui Jingfeng <sui.jingfeng at linux.dev>
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 17 ++++++++++-------
>  1 file changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index 152375f3de2e..799a26215cc2 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -82,7 +82,8 @@ static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder,
>  	return 0;
>  }
>  
> -static void sun4i_hdmi_disable(struct drm_encoder *encoder)
> +static void sun4i_hdmi_disable(struct drm_encoder *encoder,
> +			       struct drm_atomic_state *state)
>  {
>  	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
>  	u32 val;
> @@ -96,7 +97,8 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder)
>  	clk_disable_unprepare(hdmi->tmds_clk);
>  }
>  
> -static void sun4i_hdmi_enable(struct drm_encoder *encoder)
> +static void sun4i_hdmi_enable(struct drm_encoder *encoder,
> +			      struct drm_atomic_state *state)
>  {
>  	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
>  	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
> @@ -120,9 +122,10 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder)
>  }
>  
>  static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
> -				struct drm_display_mode *mode,
> -				struct drm_display_mode *adjusted_mode)
> +				struct drm_crtc_state *crtc_state,
> +				struct drm_connector_state *conn_state)
>  {
> +	const struct drm_display_mode *mode = &crtc_state->mode;
>  	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
>  	unsigned int x, y;
>  	u32 val;
> @@ -201,9 +204,9 @@ static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
>  
>  static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
>  	.atomic_check	= sun4i_hdmi_atomic_check,
> -	.disable	= sun4i_hdmi_disable,
> -	.enable		= sun4i_hdmi_enable,
> -	.mode_set	= sun4i_hdmi_mode_set,
> +	.atomic_disable	= sun4i_hdmi_disable,
> +	.atomic_enable	= sun4i_hdmi_enable,
> +	.atomic_mode_set	= sun4i_hdmi_mode_set,
>  	.mode_valid	= sun4i_hdmi_mode_valid,
>  };
>  
> 
> 






From jernej.skrabec at gmail.com  Thu Feb 22 11:08:26 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 20:08:26 +0100
Subject: [PATCH v7 33/36] drm/sun4i: hdmi: Move mode_set into enable
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-33-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-33-8f4af575fce2@kernel.org>
Message-ID: <4868938.GXAFRqVoOG@jernej-laptop>

Dne ?etrtek, 22. februar 2024 ob 19:14:19 CET je Maxime Ripard napisal(a):
> We're not doing anything special in atomic_mode_set so we can simply
> merge it into atomic_enable.
> 
> Acked-by: Sui Jingfeng <sui.jingfeng at linux.dev>
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 38 +++++++++++++---------------------
>  1 file changed, 14 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index 799a26215cc2..bae69d696765 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -103,33 +103,11 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
>  	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
>  	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
>  	struct drm_display_info *display = &hdmi->connector.display_info;
> +	unsigned int x, y;
>  	u32 val = 0;
>  
>  	DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
>  
> -	clk_prepare_enable(hdmi->tmds_clk);
> -
> -	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
> -	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
> -	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
> -	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
> -
> -	val = SUN4I_HDMI_VID_CTRL_ENABLE;
> -	if (display->is_hdmi)
> -		val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE;
> -
> -	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
> -}
> -
> -static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
> -				struct drm_crtc_state *crtc_state,
> -				struct drm_connector_state *conn_state)
> -{
> -	const struct drm_display_mode *mode = &crtc_state->mode;
> -	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
> -	unsigned int x, y;
> -	u32 val;
> -
>  	clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
>  	clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
>  
> @@ -181,6 +159,19 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
>  		val |= SUN4I_HDMI_VID_TIMING_POL_VSYNC;
>  
>  	writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG);
> +
> +	clk_prepare_enable(hdmi->tmds_clk);
> +
> +	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
> +	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
> +	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
> +	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
> +
> +	val = SUN4I_HDMI_VID_CTRL_ENABLE;
> +	if (display->is_hdmi)
> +		val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE;
> +
> +	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
>  }
>  
>  static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
> @@ -206,7 +197,6 @@ static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
>  	.atomic_check	= sun4i_hdmi_atomic_check,
>  	.atomic_disable	= sun4i_hdmi_disable,
>  	.atomic_enable	= sun4i_hdmi_enable,
> -	.atomic_mode_set	= sun4i_hdmi_mode_set,
>  	.mode_valid	= sun4i_hdmi_mode_valid,
>  };
>  
> 
> 






From jernej.skrabec at gmail.com  Thu Feb 22 11:08:58 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 20:08:58 +0100
Subject: [PATCH v7 34/36] drm/sun4i: hdmi: Switch to container_of_const
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-34-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-34-8f4af575fce2@kernel.org>
Message-ID: <2172115.irdbgypaU6@jernej-laptop>

Dne ?etrtek, 22. februar 2024 ob 19:14:20 CET je Maxime Ripard napisal(a):
> container_of_const() allows to preserve the pointer constness and is
> thus more flexible than inline functions.
> 
> Let's switch all our instances of container_of() to container_of_const().
> 
> Reviewed-by: Sui Jingfeng <sui.jingfeng at linux.dev>
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 16 ++++------------
>  1 file changed, 4 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index bae69d696765..c276d984da6b 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -30,19 +30,11 @@
>  #include "sun4i_drv.h"
>  #include "sun4i_hdmi.h"
>  
> -static inline struct sun4i_hdmi *
> -drm_encoder_to_sun4i_hdmi(struct drm_encoder *encoder)
> -{
> -	return container_of(encoder, struct sun4i_hdmi,
> -			    encoder);
> -}
> +#define drm_encoder_to_sun4i_hdmi(e)		\
> +	container_of_const(e, struct sun4i_hdmi, encoder)
>  
> -static inline struct sun4i_hdmi *
> -drm_connector_to_sun4i_hdmi(struct drm_connector *connector)
> -{
> -	return container_of(connector, struct sun4i_hdmi,
> -			    connector);
> -}
> +#define drm_connector_to_sun4i_hdmi(c)		\
> +	container_of_const(c, struct sun4i_hdmi, connector)
>  
>  static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
>  					   struct drm_display_mode *mode)
> 
> 






From broonie at kernel.org  Thu Feb 22 11:11:04 2024
From: broonie at kernel.org (Mark Brown)
Date: Thu, 22 Feb 2024 19:11:04 +0000
Subject: [PATCH v8 33/38] kselftest/arm64: Add a GCS test program built
 with the system libc
In-Reply-To: <87sf1n7uea.fsf@linaro.org>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <20240203-arm64-gcs-v8-33-c9fec77673ef@kernel.org>
 <87sf1n7uea.fsf@linaro.org>
Message-ID: <9b899b4e-7410-4c3b-967b-7794dac742e4@sirena.org.uk>

On Mon, Feb 19, 2024 at 11:15:57PM -0300, Thiago Jung Bauermann wrote:

> The only issue as can be seen above is that the can_call_function test
> is failing. The child is getting a GCS Segmentation fault when returning
> from fork().

> I tried debugging it with GDB, but I don't see what's wrong since the
> address in LR matches the first entry in GCSPR. Here is the
> debug session:

I believe based on prior discussions that you're running this using
shrinkwrap - can you confirm exactly how please, including things like
which firmware configuration you're using?  I'm using current git with

  shrinkwrap run \
        --rtvar KERNEL=arch/arm64/boot/Image \
        --rtvar ROOTFS=${ROOTFS} \
        --rtvar CMDLINE="${CMDLINE}" \
        --overlay=arch/v9.4.yaml ns-edk2.yaml

and a locally built yocto and everything seems perfectly happy.
-------------- 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/20240222/118388f6/attachment.sig>

From jernej.skrabec at gmail.com  Thu Feb 22 11:12:29 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 20:12:29 +0100
Subject: [PATCH v7 35/36] drm/sun4i: hdmi: Consolidate atomic_check and mode_valid
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-35-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-35-8f4af575fce2@kernel.org>
Message-ID: <2921783.e9J7NaK4W3@jernej-laptop>

Dne ?etrtek, 22. februar 2024 ob 19:14:21 CET je Maxime Ripard napisal(a):
> atomic_check and mode_valid do not check for the same things which can
> lead to surprising result if the userspace commits a mode that didn't go
> through mode_valid. Let's merge the two implementations into a function
> called by both.
> 
> Acked-by: Sui Jingfeng <sui.jingfeng at linux.dev>
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 74 +++++++++++++++++++++-------------
>  1 file changed, 47 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index c276d984da6b..b7cf369b1906 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -62,18 +62,6 @@ static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
>  	return 0;
>  }
>  
> -static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder,
> -				   struct drm_crtc_state *crtc_state,
> -				   struct drm_connector_state *conn_state)
> -{
> -	struct drm_display_mode *mode = &crtc_state->mode;
> -
> -	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> -		return -EINVAL;
> -
> -	return 0;
> -}
> -
>  static void sun4i_hdmi_disable(struct drm_encoder *encoder,
>  			       struct drm_atomic_state *state)
>  {
> @@ -166,31 +154,61 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
>  	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
>  }
>  
> -static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
> -					const struct drm_display_mode *mode)
> +static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
> +	.atomic_disable	= sun4i_hdmi_disable,
> +	.atomic_enable	= sun4i_hdmi_enable,
> +};
> +
> +static enum drm_mode_status
> +sun4i_hdmi_connector_clock_valid(const struct drm_connector *connector,
> +				 const struct drm_display_mode *mode,
> +				 unsigned long long clock)
>  {
> -	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
> -	unsigned long rate = mode->clock * 1000;
> -	unsigned long diff = rate / 200; /* +-0.5% allowed by HDMI spec */
> +	const struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
> +	unsigned long diff = clock / 200; /* +-0.5% allowed by HDMI spec */
>  	long rounded_rate;
>  
> +	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> +		return MODE_BAD;
> +
>  	/* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */
> -	if (rate > 165000000)
> +	if (clock > 165000000)
>  		return MODE_CLOCK_HIGH;
> -	rounded_rate = clk_round_rate(hdmi->tmds_clk, rate);
> +
> +	rounded_rate = clk_round_rate(hdmi->tmds_clk, clock);
>  	if (rounded_rate > 0 &&
> -	    max_t(unsigned long, rounded_rate, rate) -
> -	    min_t(unsigned long, rounded_rate, rate) < diff)
> +	    max_t(unsigned long, rounded_rate, clock) -
> +	    min_t(unsigned long, rounded_rate, clock) < diff)
>  		return MODE_OK;
> +
>  	return MODE_NOCLOCK;
>  }
>  
> -static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
> -	.atomic_check	= sun4i_hdmi_atomic_check,
> -	.atomic_disable	= sun4i_hdmi_disable,
> -	.atomic_enable	= sun4i_hdmi_enable,
> -	.mode_valid	= sun4i_hdmi_mode_valid,
> -};
> +static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector,
> +					     struct drm_atomic_state *state)
> +{
> +	struct drm_connector_state *conn_state =
> +		drm_atomic_get_new_connector_state(state, connector);
> +	struct drm_crtc *crtc = conn_state->crtc;
> +	struct drm_crtc_state *crtc_state = crtc->state;
> +	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
> +	enum drm_mode_status status;
> +
> +	status = sun4i_hdmi_connector_clock_valid(connector, mode,
> +						  mode->clock * 1000);
> +	if (status != MODE_OK)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static enum drm_mode_status
> +sun4i_hdmi_connector_mode_valid(struct drm_connector *connector,
> +				struct drm_display_mode *mode)
> +{
> +	return sun4i_hdmi_connector_clock_valid(connector, mode,
> +						mode->clock * 1000);
> +}
>  
>  static int sun4i_hdmi_get_modes(struct drm_connector *connector)
>  {
> @@ -236,6 +254,8 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev)
>  }
>  
>  static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = {
> +	.atomic_check	= sun4i_hdmi_connector_atomic_check,
> +	.mode_valid	= sun4i_hdmi_connector_mode_valid,
>  	.get_modes	= sun4i_hdmi_get_modes,
>  };
>  
> 
> 






From jernej.skrabec at gmail.com  Thu Feb 22 11:14:12 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 20:14:12 +0100
Subject: [PATCH v7 36/36] drm/sun4i: hdmi: Switch to HDMI connector
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-36-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-36-8f4af575fce2@kernel.org>
Message-ID: <8335826.T7Z3S40VBb@jernej-laptop>

Dne ?etrtek, 22. februar 2024 ob 19:14:22 CET je Maxime Ripard napisal(a):
> The new HDMI connector infrastructure allows to remove some boilerplate,
> especially to generate infoframes. Let's switch to it.
> 
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 80 ++++++++++++++++++++++------------
>  1 file changed, 51 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> index b7cf369b1906..8a9106a39f23 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
> @@ -36,30 +36,24 @@
>  #define drm_connector_to_sun4i_hdmi(c)		\
>  	container_of_const(c, struct sun4i_hdmi, connector)
>  
> -static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
> -					   struct drm_display_mode *mode)
> +static int sun4i_hdmi_write_infoframe(struct drm_connector *connector,
> +				      enum hdmi_infoframe_type type,
> +				      const u8 *buffer, size_t len)
>  {
> -	struct hdmi_avi_infoframe frame;
> -	u8 buffer[17];
> -	int i, ret;
> +	struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
> +	int i;
>  
> -	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
> -						       &hdmi->connector, mode);
> -	if (ret < 0) {
> -		DRM_ERROR("Failed to get infoframes from mode\n");
> -		return ret;
> +	if (type != HDMI_INFOFRAME_TYPE_AVI) {
> +		drm_err(connector->dev,
> +			"Unsupported infoframe type: %u\n", type);
> +		return 0;
>  	}
>  
> -	ret = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
> -	if (ret < 0) {
> -		DRM_ERROR("Failed to pack infoframes\n");
> -		return ret;
> -	}
> -
> -	for (i = 0; i < sizeof(buffer); i++)
> +	for (i = 0; i < len; i++)
>  		writeb(buffer[i], hdmi->base + SUN4I_HDMI_AVI_INFOFRAME_REG(i));
>  
>  	return 0;
> +
>  }
>  
>  static void sun4i_hdmi_disable(struct drm_encoder *encoder,
> @@ -82,14 +76,18 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
>  {
>  	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
>  	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
> -	struct drm_display_info *display = &hdmi->connector.display_info;
> +	struct drm_connector *connector = &hdmi->connector;
> +	struct drm_display_info *display = &connector->display_info;
> +	struct drm_connector_state *conn_state =
> +		drm_atomic_get_new_connector_state(state, connector);
> +	unsigned long long tmds_rate = conn_state->hdmi.tmds_char_rate;
>  	unsigned int x, y;
>  	u32 val = 0;
>  
>  	DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
>  
> -	clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
> -	clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
> +	clk_set_rate(hdmi->mod_clk, tmds_rate);
> +	clk_set_rate(hdmi->tmds_clk, tmds_rate);
>  
>  	/* Set input sync enable */
>  	writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC,
> @@ -142,7 +140,8 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
>  
>  	clk_prepare_enable(hdmi->tmds_clk);
>  
> -	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
> +	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
> +
>  	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
>  	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
>  	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
> @@ -195,7 +194,7 @@ static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector,
>  	enum drm_mode_status status;
>  
>  	status = sun4i_hdmi_connector_clock_valid(connector, mode,
> -						  mode->clock * 1000);
> +						  conn_state->hdmi.tmds_char_rate);
>  	if (status != MODE_OK)
>  		return -EINVAL;
>  
> @@ -206,8 +205,11 @@ static enum drm_mode_status
>  sun4i_hdmi_connector_mode_valid(struct drm_connector *connector,
>  				struct drm_display_mode *mode)
>  {
> -	return sun4i_hdmi_connector_clock_valid(connector, mode,
> -						mode->clock * 1000);
> +	unsigned long long rate =
> +		drm_connector_hdmi_compute_mode_clock(mode, 8,
> +						      HDMI_COLORSPACE_RGB);
> +
> +	return sun4i_hdmi_connector_clock_valid(connector, mode, rate);
>  }
>  
>  static int sun4i_hdmi_get_modes(struct drm_connector *connector)
> @@ -253,6 +255,11 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev)
>  	return ddc;
>  }
>  
> +static const struct drm_connector_hdmi_funcs sun4i_hdmi_hdmi_connector_funcs = {
> +	.tmds_char_rate_valid	= sun4i_hdmi_connector_clock_valid,
> +	.write_infoframe	= sun4i_hdmi_write_infoframe,
> +};
> +
>  static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = {
>  	.atomic_check	= sun4i_hdmi_connector_atomic_check,
>  	.mode_valid	= sun4i_hdmi_connector_mode_valid,
> @@ -274,11 +281,17 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  	return connector_status_connected;
>  }
>  
> +static void sun4i_hdmi_connector_reset(struct drm_connector *connector)
> +{
> +	drm_atomic_helper_connector_reset(connector);
> +	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
> +}
> +
>  static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
>  	.detect			= sun4i_hdmi_connector_detect,
>  	.fill_modes		= drm_helper_probe_single_connector_modes,
>  	.destroy		= drm_connector_cleanup,
> -	.reset			= drm_atomic_helper_connector_reset,
> +	.reset			= sun4i_hdmi_connector_reset,
>  	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
>  	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
>  };
> @@ -637,10 +650,19 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
>  
>  	drm_connector_helper_add(&hdmi->connector,
>  				 &sun4i_hdmi_connector_helper_funcs);
> -	ret = drm_connector_init_with_ddc(drm, &hdmi->connector,
> -					  &sun4i_hdmi_connector_funcs,
> -					  DRM_MODE_CONNECTOR_HDMIA,
> -					  hdmi->ddc_i2c);
> +	ret = drmm_connector_hdmi_init(drm, &hdmi->connector,
> +				       /*
> +					* NOTE: Those are likely to be
> +					* wrong, but I couldn't find the
> +					* actual ones in the BSP.
> +					*/
> +				       "AW", "HDMI",
> +				       &sun4i_hdmi_connector_funcs,
> +				       &sun4i_hdmi_hdmi_connector_funcs,
> +				       DRM_MODE_CONNECTOR_HDMIA,
> +				       hdmi->ddc_i2c,
> +				       BIT(HDMI_COLORSPACE_RGB),
> +				       8);
>  	if (ret) {
>  		dev_err(dev,
>  			"Couldn't initialise the HDMI connector\n");
> 
> 






From jernej.skrabec at gmail.com  Thu Feb 22 11:15:24 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 20:15:24 +0100
Subject: [PATCH v5 1/7] soc: sunxi: sram: export register 0 for THS on H616
In-Reply-To: <dcd115fd-dc38-4f48-8485-9e4d64f53b4a@linaro.org>
References: <20240219153639.179814-1-andre.przywara@arm.com>
 <2717467.mvXUDI8C0e@jernej-laptop>
 <dcd115fd-dc38-4f48-8485-9e4d64f53b4a@linaro.org>
Message-ID: <1956003.PYKUYFuaPT@jernej-laptop>

Dne ?etrtek, 22. februar 2024 ob 19:44:12 CET je Daniel Lezcano napisal(a):
> On 22/02/2024 19:26, Jernej ?krabec wrote:
> > Dne ponedeljek, 19. februar 2024 ob 16:36:33 CET je Andre Przywara napisal(a):
> >> The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
> >> in the SRAM control block. If bit 16 is set (the reset value), the
> >> temperature readings of the THS are way off, leading to reports about
> >> 200C, at normal ambient temperatures. Clearing this bits brings the
> >> reported values down to the expected values.
> >> The BSP code clears this bit in firmware (U-Boot), and has an explicit
> >> comment about this, but offers no real explanation.
> >>
> >> Experiments in U-Boot show that register 0x0 has no effect on the SRAM C
> >> visibility: all tested bit settings still allow full read and write
> >> access by the CPU to the whole of SRAM C. Only bit 24 of the register at
> >> offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling
> >> the THS switch functionality as an SRAM region would not reflect reality.
> >>
> >> Since we should not rely on firmware settings, allow other code (the THS
> >> driver) to access this register, by exporting it through the already
> >> existing regmap. This mimics what we already do for the LDO control and
> >> the EMAC register.
> >>
> >> To avoid concurrent accesses to the same register at the same time, by
> >> the SRAM switch code and the regmap code, use the same lock to protect
> >> the access. The regmap subsystem allows to use an existing lock, so we
> >> just need to hook in there.
> >>
> >> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > 
> > Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> > 
> > I guess this one goes through sunxi tree, right?
> 
> I'll pick this patch along with the patch 2-6, so through the thermal 
> tree. The patch 7/7 will go indeed via the sunxi tree

Ok.

Best regards,
Jernej





From jernej.skrabec at gmail.com  Thu Feb 22 11:17:33 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 20:17:33 +0100
Subject: [PATCH 1/3] drm/sun4i: Unify sun8i_*_layer structs
In-Reply-To: <20240216190430.1374132-2-megi@xff.cz>
References: <20240216190430.1374132-1-megi@xff.cz> <20240216190430.1374132-2-megi@xff.cz>
Message-ID: <3789585.kQq0lBPeGt@jernej-laptop>

Dne petek, 16. februar 2024 ob 20:04:24 CET je Ond?ej Jirman napisal(a):
> From: Ondrej Jirman <megi at xff.cz>
> 
> These structs are identical, use a single struct to represent private
> data for the DRM plane. This is a preparation for configuring layer
> routing from the CRTC (mixer) instead of current approach of setting
> up routing from individual layer's atomic_update callback.
> 
> Signed-off-by: Ondrej Jirman <megi at xff.cz>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun8i_mixer.c    |  4 ++--
>  drivers/gpu/drm/sun4i/sun8i_mixer.h    | 14 ++++++++++++++
>  drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 14 +++++++-------
>  drivers/gpu/drm/sun4i/sun8i_ui_layer.h | 20 ++++----------------
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 14 +++++++-------
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.h | 20 ++++----------------
>  6 files changed, 38 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> index 01382860aaee..1e681314e379 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -271,7 +271,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
>  		return ERR_PTR(-ENOMEM);
>  
>  	for (i = 0; i < mixer->cfg->vi_num; i++) {
> -		struct sun8i_vi_layer *layer;
> +		struct sun8i_layer *layer;
>  
>  		layer = sun8i_vi_layer_init_one(drm, mixer, i);
>  		if (IS_ERR(layer)) {
> @@ -284,7 +284,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
>  	}
>  
>  	for (i = 0; i < mixer->cfg->ui_num; i++) {
> -		struct sun8i_ui_layer *layer;
> +		struct sun8i_layer *layer;
>  
>  		layer = sun8i_ui_layer_init_one(drm, mixer, i);
>  		if (IS_ERR(layer)) {
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> index 85c94884fb9a..5a610ee30301 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> @@ -9,6 +9,7 @@
>  #include <linux/clk.h>
>  #include <linux/regmap.h>
>  #include <linux/reset.h>
> +#include <drm/drm_plane.h>
>  
>  #include "sunxi_engine.h"
>  
> @@ -185,6 +186,19 @@ struct sun8i_mixer {
>  	struct clk			*mod_clk;
>  };
>  
> +struct sun8i_layer {
> +	struct drm_plane	plane;
> +	struct sun8i_mixer	*mixer;
> +	int			channel;
> +	int			overlay;
> +};
> +
> +static inline struct sun8i_layer *
> +plane_to_sun8i_layer(struct drm_plane *plane)
> +{
> +	return container_of(plane, struct sun8i_layer, plane);
> +}
> +
>  static inline struct sun8i_mixer *
>  engine_to_sun8i_mixer(struct sunxi_engine *engine)
>  {
> diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> index ca75ca0835a6..248fbb606ede 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> @@ -232,7 +232,7 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
>  {
>  	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
>  										 plane);
> -	struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
> +	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
>  	struct drm_crtc *crtc = new_plane_state->crtc;
>  	struct drm_crtc_state *crtc_state;
>  	int min_scale, max_scale;
> @@ -264,7 +264,7 @@ static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane,
>  {
>  	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
>  									   plane);
> -	struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
> +	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
>  	unsigned int old_zpos = old_state->normalized_zpos;
>  	struct sun8i_mixer *mixer = layer->mixer;
>  
> @@ -279,7 +279,7 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
>  									   plane);
>  	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
>  									   plane);
> -	struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
> +	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
>  	unsigned int zpos = new_state->normalized_zpos;
>  	unsigned int old_zpos = old_state->normalized_zpos;
>  	struct sun8i_mixer *mixer = layer->mixer;
> @@ -345,13 +345,13 @@ static const uint64_t sun8i_layer_modifiers[] = {
>  	DRM_FORMAT_MOD_INVALID
>  };
>  
> -struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
> -					       struct sun8i_mixer *mixer,
> -					       int index)
> +struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
> +					    struct sun8i_mixer *mixer,
> +					    int index)
>  {
>  	enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY;
>  	int channel = mixer->cfg->vi_num + index;
> -	struct sun8i_ui_layer *layer;
> +	struct sun8i_layer *layer;
>  	unsigned int plane_cnt;
>  	int ret;
>  
> diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
> index e3e32ee1178d..83892f6ff211 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
> @@ -47,21 +47,9 @@
>  #define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_COMBINED	((2) << 1)
>  
>  struct sun8i_mixer;
> +struct sun8i_layer;
>  
> -struct sun8i_ui_layer {
> -	struct drm_plane	plane;
> -	struct sun8i_mixer	*mixer;
> -	int			channel;
> -	int			overlay;
> -};
> -
> -static inline struct sun8i_ui_layer *
> -plane_to_sun8i_ui_layer(struct drm_plane *plane)
> -{
> -	return container_of(plane, struct sun8i_ui_layer, plane);
> -}
> -
> -struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
> -					       struct sun8i_mixer *mixer,
> -					       int index);
> +struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
> +					    struct sun8i_mixer *mixer,
> +					    int index);
>  #endif /* _SUN8I_UI_LAYER_H_ */
> diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> index f9c0a56d3a14..0c0f1ac80517 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> @@ -366,7 +366,7 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
>  {
>  	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
>  										 plane);
> -	struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
> +	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
>  	struct drm_crtc *crtc = new_plane_state->crtc;
>  	struct drm_crtc_state *crtc_state;
>  	int min_scale, max_scale;
> @@ -398,7 +398,7 @@ static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane,
>  {
>  	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
>  									   plane);
> -	struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
> +	struct sun8i_layer *layer = plane_to_sun8i_vi_layer(plane);
>  	unsigned int old_zpos = old_state->normalized_zpos;
>  	struct sun8i_mixer *mixer = layer->mixer;
>  
> @@ -413,7 +413,7 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
>  									   plane);
>  	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
>  									   plane);
> -	struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
> +	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
>  	unsigned int zpos = new_state->normalized_zpos;
>  	unsigned int old_zpos = old_state->normalized_zpos;
>  	struct sun8i_mixer *mixer = layer->mixer;
> @@ -539,14 +539,14 @@ static const uint64_t sun8i_layer_modifiers[] = {
>  	DRM_FORMAT_MOD_INVALID
>  };
>  
> -struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
> -					       struct sun8i_mixer *mixer,
> -					       int index)
> +struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
> +					    struct sun8i_mixer *mixer,
> +					    int index)
>  {
>  	enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY;
>  	u32 supported_encodings, supported_ranges;
>  	unsigned int plane_cnt, format_count;
> -	struct sun8i_vi_layer *layer;
> +	struct sun8i_layer *layer;
>  	const u32 *formats;
>  	int ret;
>  
> diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> index 48c399e1c86d..655440cdc78f 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> @@ -52,21 +52,9 @@
>  #define SUN8I_MIXER_CHAN_VI_DS_M(x)			((x) << 0)
>  
>  struct sun8i_mixer;
> +struct sun8i_layer;
>  
> -struct sun8i_vi_layer {
> -	struct drm_plane	plane;
> -	struct sun8i_mixer	*mixer;
> -	int			channel;
> -	int			overlay;
> -};
> -
> -static inline struct sun8i_vi_layer *
> -plane_to_sun8i_vi_layer(struct drm_plane *plane)
> -{
> -	return container_of(plane, struct sun8i_vi_layer, plane);
> -}
> -
> -struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
> -					       struct sun8i_mixer *mixer,
> -					       int index);
> +struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
> +					    struct sun8i_mixer *mixer,
> +					    int index);
>  #endif /* _SUN8I_VI_LAYER_H_ */
> 






From jernej.skrabec at gmail.com  Thu Feb 22 11:18:13 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 20:18:13 +0100
Subject: [PATCH 2/3] drm/sun4i: Add more parameters to sunxi_engine commit
 callback
In-Reply-To: <20240216190430.1374132-3-megi@xff.cz>
References: <20240216190430.1374132-1-megi@xff.cz> <20240216190430.1374132-3-megi@xff.cz>
Message-ID: <9236885.CDJkKcVGEf@jernej-laptop>

Dne petek, 16. februar 2024 ob 20:04:25 CET je Ond?ej Jirman napisal(a):
> From: Ondrej Jirman <megi at xff.cz>
> 
> These will be needed later on when we move layer configuration to
> crtc update.
> 
> Signed-off-by: Ondrej Jirman <megi at xff.cz>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  drivers/gpu/drm/sun4i/sun4i_backend.c |  4 +++-
>  drivers/gpu/drm/sun4i/sun4i_crtc.c    |  2 +-
>  drivers/gpu/drm/sun4i/sun8i_mixer.c   |  5 ++++-
>  drivers/gpu/drm/sun4i/sunxi_engine.h  | 13 ++++++++++---
>  4 files changed, 18 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
> index 335fd0edb904..e89eb96d3131 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_backend.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
> @@ -69,7 +69,9 @@ static void sun4i_backend_disable_color_correction(struct sunxi_engine *engine)
>  			   SUN4I_BACKEND_OCCTL_ENABLE, 0);
>  }
>  
> -static void sun4i_backend_commit(struct sunxi_engine *engine)
> +static void sun4i_backend_commit(struct sunxi_engine *engine,
> +				 struct drm_crtc *crtc,
> +				 struct drm_atomic_state *state)
>  {
>  	DRM_DEBUG_DRIVER("Committing changes\n");
>  
> diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
> index c06d7cd45388..18e74047b0f5 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
> @@ -91,7 +91,7 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
>  
>  	DRM_DEBUG_DRIVER("Committing plane changes\n");
>  
> -	sunxi_engine_commit(scrtc->engine);
> +	sunxi_engine_commit(scrtc->engine, crtc, state);
>  
>  	if (event) {
>  		crtc->state->event = NULL;
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> index 1e681314e379..bdeb9b80e038 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -16,6 +16,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/reset.h>
>  
> +#include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_framebuffer.h>
> @@ -249,7 +250,9 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format)
>  	return -EINVAL;
>  }
>  
> -static void sun8i_mixer_commit(struct sunxi_engine *engine)
> +static void sun8i_mixer_commit(struct sunxi_engine *engine,
> +			       struct drm_crtc *crtc,
> +			       struct drm_atomic_state *state)
>  {
>  	DRM_DEBUG_DRIVER("Committing changes\n");
>  
> diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h
> index ec8cf9b2bda4..ec0c4932f15c 100644
> --- a/drivers/gpu/drm/sun4i/sunxi_engine.h
> +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h
> @@ -7,6 +7,7 @@
>  #define _SUNXI_ENGINE_H_
>  
>  struct drm_plane;
> +struct drm_crtc;
>  struct drm_device;
>  struct drm_crtc_state;
>  struct drm_display_mode;
> @@ -59,7 +60,9 @@ struct sunxi_engine_ops {
>  	 *
>  	 * This function is optional.
>  	 */
> -	void (*commit)(struct sunxi_engine *engine);
> +	void (*commit)(struct sunxi_engine *engine,
> +		       struct drm_crtc *crtc,
> +		       struct drm_atomic_state *state);
>  
>  	/**
>  	 * @layers_init:
> @@ -144,12 +147,16 @@ struct sunxi_engine {
>  /**
>   * sunxi_engine_commit() - commit all changes of the engine
>   * @engine:	pointer to the engine
> + * @crtc:	pointer to crtc the engine is associated with
> + * @state:	atomic state
>   */
>  static inline void
> -sunxi_engine_commit(struct sunxi_engine *engine)
> +sunxi_engine_commit(struct sunxi_engine *engine,
> +		    struct drm_crtc *crtc,
> +		    struct drm_atomic_state *state)
>  {
>  	if (engine->ops && engine->ops->commit)
> -		engine->ops->commit(engine);
> +		engine->ops->commit(engine, crtc, state);
>  }
>  
>  /**
> 






From wsa at kernel.org  Thu Feb 22 11:28:14 2024
From: wsa at kernel.org (Wolfram Sang)
Date: Thu, 22 Feb 2024 20:28:14 +0100
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <20240222171404.GA3334332-robh@kernel.org>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>
 <20240216022704.GB850600-robh@kernel.org>
 <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>
 <CACRpkdZZhhzg5SY7U5dv_OfLEVejRFom4V9nCfkQXunAw1ZXSw@mail.gmail.com>
 <CZ94LGRSF9KN.15ZO1VRMIQVR8@bootlin.com>
 <CZAX02IL1N1J.2GQR9D73GLRZB@bootlin.com>
 <ZdY2WzKbElloXC4-@shikoro>
 <20240222171404.GA3334332-robh@kernel.org>
Message-ID: <ZdegTjJpDJGEgdvo@shikoro>


> > @Rob: My memory fails a little bit about these two schemas: we have the
> > github one for generic bindings, not strictly related to Linux, right?
> 
> Well, NONE of the bindings are strictly related to linux unless they say 
> 'linux,' prefix.

Ok, right, of course. What I meant was probably: why do we have
controller bindings in the kernel and schema bindings in a github tree?

For me, this is a tad more difficult to maintain. Like
i2c-controller.yaml file has the "no-detect" binding which IMO is wrong
in many ways. I rejected the supporting code for Linux.

> We need to remove i2c.txt. Often that hasn't happened because we need to 
> relicense the text from GPL only to dual licensed. From a quick look, 
> i2c/i2c-controller.yaml appears to have everything in i2c.txt, so I 
> think we can go ahead and remove it. There's only a few references to 
> i2c.txt to update with that. I'll send a patch, but please double check 
> whether you think i2c-controller.yaml is missing anything.

Will do, 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/20240222/7f6ca4f8/attachment.sig>

From catalin.marinas at arm.com  Thu Feb 22 11:28:13 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 22 Feb 2024 19:28:13 +0000
Subject: [PATCH bpf-next v3 1/2] arm64: stacktrace: Implement
 arch_bpf_stack_walk() for the BPF JIT
In-Reply-To: <20240201125225.72796-2-puranjay12@gmail.com>
References: <20240201125225.72796-1-puranjay12@gmail.com>
 <20240201125225.72796-2-puranjay12@gmail.com>
Message-ID: <ZdegTX9x2ye-7xIt@arm.com>

On Thu, Feb 01, 2024 at 12:52:24PM +0000, Puranjay Mohan wrote:
> This will be used by bpf_throw() to unwind till the program marked as
> exception boundary and run the callback with the stack of the main
> program.
> 
> This is required for supporting BPF exceptions on ARM64.
> 
> Signed-off-by: Puranjay Mohan <puranjay12 at gmail.com>
> ---
>  arch/arm64/kernel/stacktrace.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index 7f88028a00c0..66cffc5fc0be 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -7,6 +7,7 @@
>  #include <linux/kernel.h>
>  #include <linux/efi.h>
>  #include <linux/export.h>
> +#include <linux/filter.h>
>  #include <linux/ftrace.h>
>  #include <linux/kprobes.h>
>  #include <linux/sched.h>
> @@ -266,6 +267,31 @@ noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
>  	kunwind_stack_walk(arch_kunwind_consume_entry, &data, task, regs);
>  }
>  
> +struct bpf_unwind_consume_entry_data {
> +	bool (*consume_entry)(void *cookie, u64 ip, u64 sp, u64 fp);
> +	void *cookie;
> +};
> +
> +static bool
> +arch_bpf_unwind_consume_entry(const struct kunwind_state *state, void *cookie)
> +{
> +	struct bpf_unwind_consume_entry_data *data = cookie;
> +
> +	return data->consume_entry(data->cookie, state->common.pc, 0,
> +				   state->common.fp);
> +}
> +
> +noinline noinstr void arch_bpf_stack_walk(bool (*consume_entry)(void *cookie, u64 ip, u64 sp,
> +								u64 fp), void *cookie)
> +{
> +	struct bpf_unwind_consume_entry_data data = {
> +		.consume_entry = consume_entry,
> +		.cookie = cookie,
> +	};
> +
> +	kunwind_stack_walk(arch_bpf_unwind_consume_entry, &data, current, NULL);
> +}

Too many "cookies", I found reading this confusing. If you ever respin,
please use some different "cookie" names.

I guess you want this to be merged via the bpf tree?

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From florian.fainelli at broadcom.com  Thu Feb 22 11:30:27 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Thu, 22 Feb 2024 11:30:27 -0800
Subject: [PATCH] MAINTAINERS: Update SCMI entry with HWMON driver
Message-ID: <20240222193027.920006-1-florian.fainelli@broadcom.com>

scmi-hwmon.c is tightly coupled with the SCMI subsystem, fold it under
the SCMI subsystem MAINTAINERS umbrella.

Signed-off-by: Florian Fainelli <florian.fainelli at broadcom.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 466a0fc46f76..92973c5a0e83 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21327,6 +21327,7 @@ F:	drivers/clk/clk-sc[mp]i.c
 F:	drivers/cpufreq/sc[mp]i-cpufreq.c
 F:	drivers/firmware/arm_scmi/
 F:	drivers/firmware/arm_scpi.c
+F:	drivers/hwmon/scmi-hwmon.c
 F:	drivers/pmdomain/arm/
 F:	drivers/powercap/arm_scmi_powercap.c
 F:	drivers/regulator/scmi-regulator.c
-- 
2.34.1



From florian.fainelli at broadcom.com  Thu Feb 22 11:35:21 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Thu, 22 Feb 2024 11:35:21 -0800
Subject: SCMI support for sensors shared memory?
Message-ID: <4ed10434-0620-4fd3-b595-61f2c6080722@broadcom.com>

Hi Sudeep, Christian,

AFAICT there is no support within scmi-hwmon.c for a sensors shared 
memory, even though the SCMI specification describes how to use it.

Is this something that you are working on by any chance, or should we 
contribute it once we have it ready?

Thanks!
-- 
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240222/61d4e735/attachment-0001.p7s>

From robh at kernel.org  Thu Feb 22 11:36:42 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 13:36:42 -0600
Subject: [PATCH v1 1/6] dt-bindings: cache: Document the
 sifive,perfmon-counters property
In-Reply-To: <6ac4005b-01e6-48c2-971e-d6a127134d13@linaro.org>
References: <20240216000837.1868917-1-samuel.holland@sifive.com>
 <20240216000837.1868917-2-samuel.holland@sifive.com>
 <eeb2331d-10e6-4902-91ba-85896a8f0ee1@linaro.org>
 <72221da1-4a1a-4947-a202-9de203032f5c@sifive.com>
 <6ac4005b-01e6-48c2-971e-d6a127134d13@linaro.org>
Message-ID: <20240222193642.GA3713418-robh@kernel.org>

On Sun, Feb 18, 2024 at 07:35:35PM +0100, Krzysztof Kozlowski wrote:
> On 18/02/2024 16:29, Samuel Holland wrote:
> > Hi Krzysztof,
> > 
> > On 2024-02-17 3:00 AM, Krzysztof Kozlowski wrote:
> >> On 16/02/2024 01:08, Samuel Holland wrote:
> >>> The SiFive Composable Cache controller contains an optional PMU with a
> >>> configurable number of event counters. Document a property which
> >>
> >> Configurable in what context? By chip designers or by OS? Why this
> >> cannot be deduced from the compatible?
> > 
> > This parameter is configurable by the chip designers.
> > 
> > The information certainly can be deduced from the SoC-specific compatible
> > string, but doing so makes the driver only work on that specific list of SoCs.
> 
> Usually that's exactly what's expected, so why here usual approach is wrong?
> 
> > When provided via a property, the driver can work without changes on any SoC
> > that uses this IP block. (None of the SoCs currently listed in the binding
> 
> Sorry, properties are not a work-around for missing compatibles.
> 
> > contain a PMU, so there is no backward compatibility concern with adding the new
> > property.)
> > 
> > My understanding of the purpose of the SoC-specific compatible string is to
> > handle eventualities (silicon bugs, integration quirks, etc.), not to
> > intentionally limit the driver to a narrow list of hardware.
> 
> Depends what is the hardware. For most of licensed blocks, the final
> design is the hardware so equals to its compatible.

While I generally agree, I think a property is fine here for 2 reasons. 

This is going to vary on just about every design. That's true for any 
PMU. So maybe this shouldn't even be SiFfive specific.

The second is counters available to the OS may not equal the number in 
h/w because counters could be reserved for different priviledge levels 
(secure, hypervisor, guest, etc.). No idea if Risc-V supports this, but 
if not it is a matter of time. That's more likely for a core PMU than an 
uncore PMU.

Rob


From sdf at google.com  Thu Feb 22 11:53:14 2024
From: sdf at google.com (Stanislav Fomichev)
Date: Thu, 22 Feb 2024 11:53:14 -0800
Subject: [PATCH net] net: stmmac: Complete meta data only when enabled
In-Reply-To: <20240222-stmmac_xdp-v1-1-e8d2d2b79ff0@linutronix.de>
References: <20240222-stmmac_xdp-v1-1-e8d2d2b79ff0@linutronix.de>
Message-ID: <CAKH8qBsCrYuT+18CsydQ5TeauRzu0Hdz7mZQ2c0W7er0KrJnkg@mail.gmail.com>

On Thu, Feb 22, 2024 at 1:45?AM Kurt Kanzenbach <kurt at linutronix.de> wrote:
>
> Currently using XDP/ZC sockets on stmmac results in a kernel crash:
>
> |[  255.822584] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
> |[...]
> |[  255.822764] Call trace:
> |[  255.822766]  stmmac_tx_clean.constprop.0+0x848/0xc38
>
> The program counter indicates xsk_tx_metadata_complete(). However, this
> function shouldn't be called unless metadata is actually enabled.
>
> Tested on imx93 without XDP, with XDP and with XDP/ZC.
>
> Fixes: 1347b419318d ("net: stmmac: Add Tx HWTS support to XDP ZC")
> Suggested-by: Serge Semin <fancer.lancer at gmail.com>
> Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
> Tested-by: Serge Semin <fancer.lancer at gmail.com>
> Link: https://lore.kernel.org/netdev/87r0h7wg8u.fsf at kurt.kurt.home/

Acked-by: Stanislav Fomichev <sdf at google.com>

LGTM, thanks!

> ---
>  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 e80d77bd9f1f..8b77c0952071 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -2672,7 +2672,8 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue,
>                         }
>                         if (skb) {
>                                 stmmac_get_tx_hwtstamp(priv, p, skb);
> -                       } else {
> +                       } else if (tx_q->xsk_pool &&
> +                                  xp_tx_metadata_enabled(tx_q->xsk_pool)) {
>                                 struct stmmac_xsk_tx_complete tx_compl = {
>                                         .priv = priv,
>                                         .desc = p,
>
> ---
> base-commit: 603ead96582d85903baec2d55f021b8dac5c25d2
> change-id: 20240222-stmmac_xdp-585ebf1680b3
>
> Best regards,
> --
> Kurt Kanzenbach <kurt at linutronix.de>
>


From florian.fainelli at broadcom.com  Thu Feb 22 11:54:46 2024
From: florian.fainelli at broadcom.com (Florian Fainelli)
Date: Thu, 22 Feb 2024 11:54:46 -0800
Subject: [PATCH v1 10/14] serial: 8250_of: Switch to use
 uart_read_port_properties()
In-Reply-To: <e5fd9d8b-84eb-4ef9-82ab-ff4ecc41c0d5@broadcom.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-11-andriy.shevchenko@linux.intel.com>
 <0a828f2c50de712940fb9a881702ac1678a35b7c.camel@codeconstruct.com.au>
 <ZddKzHplwOX7naLv@smile.fi.intel.com> <Zdd5m2xIPlGI0_Qv@smile.fi.intel.com>
 <Zdd6lnXwvpPPUhRR@smile.fi.intel.com>
 <e5fd9d8b-84eb-4ef9-82ab-ff4ecc41c0d5@broadcom.com>
Message-ID: <ad91eec0-39da-4b9c-8da7-f1e98bb4565b@broadcom.com>

On 2/22/24 09:39, Florian Fainelli wrote:
> On 2/22/24 08:47, Andy Shevchenko wrote:
>> On Thu, Feb 22, 2024 at 06:43:08PM +0200, Andy Shevchenko wrote:
>>> On Thu, Feb 22, 2024 at 03:23:24PM +0200, Andy Shevchenko wrote:
>>>> On Thu, Feb 22, 2024 at 11:07:05AM +1030, Andrew Jeffery wrote:
>>>>> On Wed, 2024-02-21 at 20:31 +0200, Andy Shevchenko wrote:
>>>>>> Since we have now a common helper to read port properties
>>>>>> use it instead of sparse home grown solution.
>>>>>
>>>>> I did some brief testing of the series for the Aspeed machines under
>>>>> qemu, building them on top of v6.8-rc5:
>>>>>
>>>>> export ARCH=arm
>>>>> export CROSS_COMPILE=arm-linux-gnueabihf-
>>>>> make aspeed_g5_defconfig
>>>>> make -j$(nproc)
>>>>> qemu-system-arm -M rainier-bmc -nographic -no-reboot -kernel 
>>>>> arch/arm/boot/zImage -dtb 
>>>>> arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dtb -initrd ...
>>>>>
>>>>> I got an oops during boot, which bisected to this change:
>>>>
>>>> Thank you for prompt testing! I will look at it.
>>>
>>> I found the issue, will be fixed in next version.
>>
>> Whoever is going to test this series, the
>>
>> -??????? port->iotype = use_defaults ? UPIO_MEM : port->iotype;
>> +??????? port->iotype = UPIO_MEM;
>>
>> should be applied to uart_read_port_properties() implementation.
>>
> 
> Thanks, on 8250_bcm7271.c with the above hunk applied, I did not spot 
> any differences between the values returned by stty or a cat 
> /sys/class/tty/ttyS0/* before or after, the console remained fully 
> functional. I will see if I can run an additional test where I removed 
> the DT's "clocks" property and confirm that the fall back to 
> "clock-frequency" works.
> 
> Thanks Andy!

Also appears to work properly on a Raspberry Pi 4 with the console using 
the bcm2835-aux driver, will provide Tested-by tags on the next 
submission, thanks!
-- 
Florian

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4221 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240222/f8cc7634/attachment-0001.p7s>

From vanshikonda at os.amperecomputing.com  Thu Feb 22 11:55:51 2024
From: vanshikonda at os.amperecomputing.com (Vanshidhar Konda)
Date: Thu, 22 Feb 2024 11:55:51 -0800
Subject: [PATCH v2 1/2] arm64: Provide an AMU-based version of
 arch_freq_get_on_cpu
In-Reply-To: <20231127160838.1403404-2-beata.michalska@arm.com>
References: <20231127160838.1403404-1-beata.michalska@arm.com>
 <20231127160838.1403404-2-beata.michalska@arm.com>
Message-ID: <7eozim2xnepacnnkzxlbx34hib4otycnbn4dqymfziqou5lw5u@5xzpv3t7sxo3>

Hello Beata,

I tested this patch based on the discussion in [1] on an AmpereOne
system when the system was mostly idle. The results below are when only
I applied the first patch in this series to the kernel. I noticed that
the frequency reported through scaling_cur_freq vs cpuinfo_cur_freq is
quite different for some cores. When the cores are loaded using
stress-ng, the scaling_cur_freq and cpuinfo_cur_freq values are quite
similar.

Applying the second patch in this series causes the difference between
scaling_cur_freq and cpuinfo_cur_freq to disappear, but calculating the
core frequency based on the feedback_ctrs shows that the value is
incorrect for both.

The kernel I compiled for testing is based on the Fedora 39 config file.
These configs seem relevant to the discussion:

CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
# CONFIG_NO_HZ_IDLE is not set
CONFIG_NO_HZ_FULL=y
CONFIG_CONTEXT_TRACKING_USER=y
# CONFIG_CONTEXT_TRACKING_USER_FORCE is not set
CONFIG_NO_HZ=y

[1]: https://lore.kernel.org/linux-arm-kernel/20231212072617.14756-1-lihuisong at huawei.com/

Results:
cpu_num scaling_cur_freq  cpuinfo_cur_freq
[11]:	  1874560	          1000000
[12]:	  2056158	          1385000
[13]:	  1974146	          1000000
[21]:	  1587518	          1000000
[23]:	  1593376           1000000
...
... skipping similar results for ~50 other cores for brevity
...
nohz_full=113-118
[113]:	1874560	          1000000
[114]:	1968288	          1000000
[115]:	1962430	          1000000
[116]:	1871631	          1000000
[117]:	1877489	          1000000
[118]:	1877489	          1000000
isolcpus=119-127
[119]:	2999296	          1000000
[120]:	2999296	          1000000
[121]:	2999296	          1000000
[125]:	2999296	          1000000
[126]:	2999296	          1000000
[127]:	2999296	          1000000

Thanks,
Vanshi

On Mon, Nov 27, 2023 at 04:08:37PM +0000, Beata Michalska wrote:
>With the Frequency Invariance Engine (FIE) being already wired up with
>sched tick and making use of relevant (core counter and constant
>counter) AMU counters, getting the current frequency for a given CPU
>on supported platforms, can be achieved by utilizing the frequency scale
>factor which reflects an average CPU frequency for the last tick period
>length.
>
>Suggested-by: Ionela Voinescu <ionela.voinescu at arm.com>
>Signed-off-by: Beata Michalska <beata.michalska at arm.com>
>Reviewed-by: Sudeep Holla <sudeep.holla at arm.com>
>---
>
>Notes:
>    Due to [1], if merged, there might be a need to modify the patch to
>    accommodate changes [1] introduces:
>
>    	freq = cpufreq_get_hw_max_freq(cpu) >> SCHED_CAPACITY_SHIFT
>    	to
>    	freq = per_cpu(capacity_freq_ref, cpu); >> SCHED_CAPACITY_SHIFT
>    [1]
>    https://lore.kernel.org/linux-arm-kernel/20231121154349.GA1938 at willie-the-truck/T/#mcb018d076dbce6f60ed2779634a9b6ffe622641e
>
> arch/arm64/kernel/topology.c | 39 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
>
>diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
>index 615c1a20129f..ae2445f6e7da 100644
>--- a/arch/arm64/kernel/topology.c
>+++ b/arch/arm64/kernel/topology.c
>@@ -17,6 +17,7 @@
> #include <linux/cpufreq.h>
> #include <linux/init.h>
> #include <linux/percpu.h>
>+#include <linux/sched/isolation.h>
>
> #include <asm/cpu.h>
> #include <asm/cputype.h>
>@@ -186,6 +187,44 @@ static void amu_scale_freq_tick(void)
> 	this_cpu_write(arch_freq_scale, (unsigned long)scale);
> }
>
>+unsigned int arch_freq_get_on_cpu(int cpu)
>+{
>+	unsigned int freq;
>+	u64 scale;
>+
>+	if (!cpumask_test_cpu(cpu, amu_fie_cpus))
>+		return 0;
>+
>+	/*
>+	 * For those CPUs that are in full dynticks mode, try an alternative
>+	 * source for the counters (and thus freq scale),
>+	 * if available for given policy
>+	 */
>+	if (!housekeeping_cpu(cpu, HK_TYPE_TICK)) {
>+		struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
>+		int ref_cpu = nr_cpu_ids;
>+
>+		if (cpumask_intersects(housekeeping_cpumask(HK_TYPE_TICK),
>+				       policy->cpus))
>+			ref_cpu = cpumask_nth_and(cpu, policy->cpus,
>+						  housekeeping_cpumask(HK_TYPE_TICK));
>+		cpufreq_cpu_put(policy);
>+		if (ref_cpu >= nr_cpu_ids)
>+			return 0;
>+		cpu = ref_cpu;
>+	}
>+
>+	/*
>+	 * Reversed computation to the one used to determine
>+	 * the arch_freq_scale value
>+	 * (see amu_scale_freq_tick for details)
>+	 */
>+	scale = per_cpu(arch_freq_scale, cpu);
>+	freq = cpufreq_get_hw_max_freq(cpu) >> SCHED_CAPACITY_SHIFT;
>+	freq *= scale;
>+	return freq;
>+}
>+
> static struct scale_freq_data amu_sfd = {
> 	.source = SCALE_FREQ_SOURCE_ARCH,
> 	.set_freq_scale = amu_scale_freq_tick,
>-- 
>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 jernej.skrabec at gmail.com  Thu Feb 22 12:02:53 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 21:02:53 +0100
Subject: [PATCH 3/3] drm/sun4i: Fix layer zpos change/atomic modesetting
In-Reply-To: <inuhwnlexpt6dpre4uailtvytjhms4uqeerzehbntczurhcxol@fc4nvkdwffdd>
References: <20240216190430.1374132-1-megi@xff.cz> <20240216190430.1374132-4-megi@xff.cz>
 <inuhwnlexpt6dpre4uailtvytjhms4uqeerzehbntczurhcxol@fc4nvkdwffdd>
Message-ID: <2448947.jE0xQCEvom@jernej-laptop>

Dne sreda, 21. februar 2024 ob 14:45:20 CET je Maxime Ripard napisal(a):
> Hi,
> 
> On Fri, Feb 16, 2024 at 08:04:26PM +0100, Ond?ej Jirman wrote:
> > From: Ondrej Jirman <megi at xff.cz>
> > 
> > Identical configurations of planes can lead to different (and wrong)
> > layer -> pipe routing at HW level, depending on the order of atomic
> > plane changes.
> > 
> > For example:
> > 
> > - Layer 1 is configured to zpos 0 and thus uses pipe 0. No other layer
> >   is enabled. This is a typical situation at boot.
> > 
> > - When a compositor takes over and layer 3 is enabled,
> >   sun8i_ui_layer_enable() will get called with old_zpos=0 zpos=1, which
> >   will lead to incorrect disabling of pipe 0 and enabling of pipe 1.
> > 
> > What happens is that sun8i_ui_layer_enable() function may disable
> > blender pipes even if it is no longer assigned to its layer.
> > 
> > To correct this, move the routing setup out of individual plane's
> > atomic_update into crtc's atomic_update, where it can be calculated
> > and updated all at once.
> > 
> > Remove the atomic_disable callback because it is no longer needed.
> > 
> > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> 
> I don't have enough knowledge about the mixers code to comment on your
> patch, so I'll let Jernej review it. However, this feels to me like the
> pipe assignment is typically the sort of things that should be dealt
> with device-wide, and in atomic_check.

In DE2 and DE3.0, you cannot move planes between mixers (crtcs), because each
one is hardwired to specific mixer. Movable planes are the feature of DE3.3
and one of the pain points for upstreaming the code. Anyway, this commit only
addresses current issue of enabling and disabling planes and handling zpos.

In atomic check you can only precalculate final register values, but I don't
see any benefit doing that. I think that this code elegantly solves current
issue of enabling or disabling wrong plane in certain situations, so:

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Note, if there is new revision, please rewrite blender regmap_update_bits()
to regmap_write(). Since there is HW issue with reads, I would like to
get rid of regmap_update_bits() calls eventually.

Best regards,
Jernej

> 
> If I'm talking non-sense, it would be great to mention at least why that
> can't be an option in the commit log.
> 
> Maxime
> 






From megi at xff.cz  Thu Feb 22 12:18:00 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Thu, 22 Feb 2024 21:18:00 +0100
Subject: [PATCH 4/4] ASoC: sun8i-codec: Implement jack and accessory
 detection
In-Reply-To: <0c351386-f1df-443f-a997-261f5c60c852@sirena.org.uk>
References: <20240222181851.3398254-1-megi@xff.cz>
 <20240222181851.3398254-5-megi@xff.cz>
 <0c351386-f1df-443f-a997-261f5c60c852@sirena.org.uk>
Message-ID: <vmi3fkm47wf7cbfakubbye4ce7ol5kjpg3edkrati2lhsl6qej@57uir6fjjzq2>

Hello Mark,

On Thu, Feb 22, 2024 at 06:41:13PM +0000, Mark Brown wrote:
> On Thu, Feb 22, 2024 at 07:18:47PM +0100, Ond?ej Jirman wrote:
> 
> > +static struct snd_soc_jack_pin sun8i_codec_jack_pins[] = {
> > +	{
> > +		.pin	= "Headphone Jack",
> > +		.mask	= SND_JACK_HEADPHONE,
> > +	},
> > +	{
> > +		.pin	= "Headset Microphone",
> > +		.mask	= SND_JACK_MICROPHONE,
> > +	},
> > +};
> > +
> 
> The jack being a headset jack is going to be system specific isn't it?
> Some systems might have separate headphone and microphone jacks.  I'd
> not expect to see any pin handling code at all in a CODEC driver, that
> belongs in the machine driver.

Yeah, the only reason this and the card reference seems to be here is to
check whether jack detection should be enabled and in what capacity.

Looks like there's some set_jack component callback for that. :)

I'll look into that.

kind regards,
	o.

> >  static int sun8i_codec_component_probe(struct snd_soc_component *component)
> >  {
> >  	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
> >  	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
> >  	int ret;
> >  
> > +	scodec->card = component->card;
> > +
> 
> The fact that you're needing to look at the card here should be a bit of
> a warning sign there.




From alex.williamson at redhat.com  Thu Feb 22 12:52:40 2024
From: alex.williamson at redhat.com (Alex Williamson)
Date: Thu, 22 Feb 2024 13:52:40 -0700
Subject: [PATCH v8 4/4] vfio: convey kvm that the vfio-pci device is wc
 safe
In-Reply-To: <20240220072926.6466-5-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
	<20240220072926.6466-5-ankita@nvidia.com>
Message-ID: <20240222135240.46682bed.alex.williamson@redhat.com>

On Tue, 20 Feb 2024 12:59:26 +0530
<ankita at nvidia.com> wrote:

> From: Ankit Agrawal <ankita at nvidia.com>
> 
> The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64,
> allowing KVM stage 2 device mapping attributes to use Normal-NC
> rather than DEVICE_nGnRE, which allows guest mappings
> supporting combining attributes (WC). ARM does not architecturally
> guarantee this is safe, and indeed some MMIO regions like the GICv2
> VCPU interface can trigger uncontained faults if Normal-NC is used.
> 
> To safely use VFIO in KVM the platform must guarantee full safety
> in the guest where no action taken against a MMIO mapping can
> trigger an uncontained failure. We belive that most VFIO PCI
> platforms support this for both mapping types, at least in common
> flows, based on some expectations of how PCI IP is integrated. So
> make vfio-pci set the VM_ALLOW_ANY_UNCACHED flag.
> 
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Acked-by: Jason Gunthorpe <jgg at nvidia.com>
> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> Reviewed-by: David Hildenbrand <david at redhat.com>
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
> ---
>  drivers/vfio/pci/vfio_pci_core.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 1cbc990d42e0..c93bea18fc4b 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -1862,8 +1862,24 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
>  	/*
>  	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
>  	 * change vm_flags within the fault handler.  Set them now.
> +	 *
> +	 * VM_ALLOW_ANY_UNCACHED: The VMA flag is implemented for ARM64,
> +	 * allowing KVM stage 2 device mapping attributes to use Normal-NC
> +	 * rather than DEVICE_nGnRE, which allows guest mappings
> +	 * supporting combining attributes (WC). ARM does not
> +	 * architecturally guarantee this is safe, and indeed some MMIO
> +	 * regions like the GICv2 VCPU interface can trigger uncontained
> +	 * faults if Normal-NC is used.
> +	 *
> +	 * To safely use VFIO in KVM the platform must guarantee full
> +	 * safety in the guest where no action taken against a MMIO
> +	 * mapping can trigger an uncontained failure. We belive that
> +	 * most VFIO PCI platforms support this for both mapping types,
> +	 * at least in common flows, based on some expectations of how
> +	 * PCI IP is integrated. So set VM_ALLOW_ANY_UNCACHED in VMA flags.
>  	 */
> -	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
> +	vm_flags_set(vma, VM_ALLOW_ANY_UNCACHED | VM_IO | VM_PFNMAP |
> +			VM_DONTEXPAND | VM_DONTDUMP);
>  	vma->vm_ops = &vfio_pci_mmap_ops;
>  
>  	return 0;

Acked-by: Alex Williamson <alex.williamson at redhat.com>



From jernej.skrabec at gmail.com  Thu Feb 22 12:57:00 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 22 Feb 2024 21:57:00 +0100
Subject: [PATCH v2 4/4] arm64: dts: sun50i-a64-pinephone: change led type to
 status
In-Reply-To: <20240206185400.596979-4-aren@peacevolution.org>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <20240206185400.596979-4-aren@peacevolution.org>
Message-ID: <2792937.BEx9A2HvPv@jernej-laptop>

Dne torek, 06. februar 2024 ob 19:13:20 CET je Aren Moynihan napisal(a):
> The status function is described in the documentation as being a rgb led
> used for system notifications on phones[1][2]. This is exactly what this
> led is used for on the PinePhone, so using status is probably more
> accurate than indicator.
> 
> 1: Documentation/leds/well-known-leds.txt
> 2: include/dt-bindings/leds/common.h
> 
> Signed-off-by: Aren Moynihan <aren at peacevolution.org>

Sorry for late review.

Please update subject in patches 2-3. Instead of "sun50i-a64-pinephone:"
use "allwinner: pinephone:" (check commit history of sun50i-a64-pinephone.dtsi).
Also rgb -> RGB, led -> LED. Last, please reword commit message to exclude
links and just say DT bindings documentation.

Note that I'll merge patches 2-3 once patch 1 is merged.

Best regards,
Jernej

> ---
> I can't find any documentation describing the indicator function, so
> it's definitely less specific than status, but besides that I'm not sure
> how it compares. Please ignore this patch if it's not useful.
> 
> (no changes since v1)
> 
>  arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> index e53e0d4579a7..6d327266e6cc 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> @@ -61,7 +61,7 @@ led2: led-2 {
>  	multi-led {
>  		compatible = "leds-group-multicolor";
>  		color = <LED_COLOR_ID_RGB>;
> -		function = LED_FUNCTION_INDICATOR;
> +		function = LED_FUNCTION_STATUS;
>  		leds = <&led0>, <&led1>, <&led2>;
>  	};
>  
> 






From brgl at bgdev.pl  Thu Feb 22 13:04:41 2024
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 22 Feb 2024 22:04:41 +0100
Subject: [PATCH] arm64: gitignore: ignore relacheck
Message-ID: <20240222210441.33142-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Add the generated executable for relacheck to the list of ignored files.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 arch/arm64/kernel/pi/.gitignore | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 arch/arm64/kernel/pi/.gitignore

diff --git a/arch/arm64/kernel/pi/.gitignore b/arch/arm64/kernel/pi/.gitignore
new file mode 100644
index 000000000000..efb29b663e85
--- /dev/null
+++ b/arch/arm64/kernel/pi/.gitignore
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+relacheck
-- 
2.40.1



From m.felsch at pengutronix.de  Thu Feb 22 13:12:42 2024
From: m.felsch at pengutronix.de (Marco Felsch)
Date: Thu, 22 Feb 2024 22:12:42 +0100
Subject: [PATCH] arm64: dts: Adapt TCPC compatible
Message-ID: <20240222211242.210340-1-m.felsch@pengutronix.de>

Add the new fallback binding to all devicetrees which do have a
nxp,ptn5110 node to not cause any dt-validation regression.

Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
---
Hi,

this requires patchset
https://lore.kernel.org/all/20240222210903.208901-1-m.felsch at pengutronix.de/
to be applied.

 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi               | 2 +-
 arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi               | 2 +-
 arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts         | 2 +-
 arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts | 2 +-
 arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts     | 2 +-
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts               | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index b53104ed8919..91830f6333bd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -359,7 +359,7 @@ adv7535_out: endpoint {
 	};
 
 	ptn5110: tcpc at 50 {
-		compatible = "nxp,ptn5110";
+		compatible = "nxp,ptn5110", "tcpci";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_typec1>;
 		reg = <0x50>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
index a0e13d3324ed..648901192e99 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
@@ -213,7 +213,7 @@ adv7533_out: endpoint {
 	};
 
 	ptn5110: tcpc at 50 {
-		compatible = "nxp,ptn5110";
+		compatible = "nxp,ptn5110", "tcpci";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_typec1>;
 		reg = <0x50>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
index feae77e03835..4db3a8cd2776 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
@@ -340,7 +340,7 @@ pcieclk: clock-generator at 68 {
 &i2c3 {
 	/* Connected to USB Hub */
 	usb-typec at 52 {
-		compatible = "nxp,ptn5110";
+		compatible = "nxp,ptn5110", "tcpci";
 		reg = <0x52>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_typec>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts b/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts
index 366693f31992..e92b5d5a66b5 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts
@@ -42,7 +42,7 @@ &i2c2 {
 	status = "okay";
 
 	typec_ptn5100: usb-typec at 50 {
-		compatible = "nxp,ptn5110";
+		compatible = "nxp,ptn5110", "tcpci";
 		reg = <0x50>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_typec>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts b/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
index 8055a2c23035..b268ba7a0e12 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
@@ -429,7 +429,7 @@ ldo7_reg: LDO7 {
 	};
 
 	typec_ptn5100: usb-typec at 52 {
-		compatible = "nxp,ptn5110";
+		compatible = "nxp,ptn5110", "tcpci";
 		reg = <0x52>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_typec>;
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 8360bb851ac0..83d298c2bfd3 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -149,7 +149,7 @@ light-sensor at 44 {
 	};
 
 	ptn5110: tcpc at 50 {
-		compatible = "nxp,ptn5110";
+		compatible = "nxp,ptn5110", "tcpci";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_typec>;
 		reg = <0x50>;
-- 
2.39.2



From jernej.skrabec at gmail.com  Thu Feb 22 13:13:26 2024
From: jernej.skrabec at gmail.com (Jernej Skrabec)
Date: Thu, 22 Feb 2024 22:13:26 +0100
Subject: [PATCH] arm64: dts: allwinner: h616: Add Orange Pi Zero 2W to Makefile
Message-ID: <20240222211326.114955-1-jernej.skrabec@gmail.com>

Orange Pi Zero 2W dts file is not included in Makefile. Fix this.

Fixes: c505ee1eae18 ("arm64: dts: allwinner: h616: add Orange Pi Zero 2W support")
Signed-off-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 arch/arm64/boot/dts/allwinner/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 91d505b385de..1f1f8d865d0e 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -42,5 +42,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero2w.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
-- 
2.43.2



From vidyas at nvidia.com  Thu Feb 22 13:18:24 2024
From: vidyas at nvidia.com (Vidya Sagar)
Date: Fri, 23 Feb 2024 02:48:24 +0530
Subject: [PATCH V3] PCI: Add support for preserving boot configuration
In-Reply-To: <20240222170641.GA15593@bhelgaas>
References: <20240222170641.GA15593@bhelgaas>
Message-ID: <17a29a7e-b013-4568-8e21-9647969b6b6d@nvidia.com>



On 22-02-2024 22:36, Bjorn Helgaas wrote:
> External email: Use caution opening links or attachments
>
>
> On Thu, Feb 22, 2024 at 06:11:10PM +0530, Vidya Sagar wrote:
>> Add support for preserving the boot configuration done by the
>> platform firmware per host bridge basis, based on the presence of
>> 'linux,pci-probe-only' property in the respective PCIe host bridge
>> device-tree node. It also unifies the ACPI and DT based boot flows
>> in this regard.
>> +/**
>> + * of_pci_bridge_check_probe_only - Return true if the boot configuration
>> + *                                  needs to be preserved
> I don't like the "check_probe_only" name because it's a boolean
> function but the name doesn't tell me what a true/false return value
> means.  Something like "preserve_resources" would be better.  If you
> want "probe_only", even removing the "check" would help.
I'll change it in the next patch.
>> + * @node: Device tree node with the domain information.
>> + *
>> + * This function looks for "linux,pci-probe-only" property for a given
>> + * PCIe controller's node and returns true if found. Having this property
>> + * for a PCIe controller ensures that the kernel doesn't re-enumerate and
>> + * reconfigure the BAR resources that are already done by the platform firmware.
> This is generic PCI, not PCIe-specific (also in commit log and comment
> below).
>
> I think "enumeration" specifically refers to discovering what devices
> are present, and the kernel always does that, so drop that part.
> Reconfiguring BARs and bridge windows is what we want to prevent.
Agree and I'll address it in the next patch.
>> + * NOTE: The scope of "linux,pci-probe-only" defined within a PCIe bridge device
>> + *       is limited to the hierarchy under that particular bridge device. whereas
>> + *       the scope of "linux,pci-probe-only" defined within chosen node is
>> + *       system wide.
>> + *
>> + * Return: true if the property exists false otherwise.
>> + */
>> +bool of_pci_bridge_check_probe_only(struct device_node *node)
>> +{
>> +     return of_property_read_bool(node, "linux,pci-probe-only");
>> +}
>> +EXPORT_SYMBOL_GPL(of_pci_bridge_check_probe_only);
> Why does this need to be exported for modules and exposed via
> include/linux/pci.h?
On a second through, I think it is not required to be exported.
I'll address this also in the next patch.
>> +static void pci_check_config_preserve(struct pci_host_bridge *host_bridge)
>> +{
>> +     if (&host_bridge->dev) {
> Checking &host_bridge->dev doesn't seem like the right way to
> determine whether this is an ACPI host bridge.
Honestly, I couldn't find a clear way to differentiate between an ACPI based
host bridge and a DT based host bridge. Hence, the current code tries to get
the information using both ways and since a system can only be either 
ACPI or
DT based, but one at a time, preserve_config will be set only once (assuming
the system wants it to be set). Let me know if there is a better approach
for this?

I was looking at the way 'external_facing' gets set in both the boot 
flows and
I see that there is no common place for it and the respective flows have 
their
functions separately i.e. pci_acpi_set_external_facing() for ACPI and
pci_set_bus_of_node() for DT.

Thanks,
Vidya Sagar
>> +             union acpi_object *obj;
>> +
>> +             /*
>> +              * Evaluate the "PCI Boot Configuration" _DSM Function.  If it
>> +              * exists and returns 0, we must preserve any PCI resource
>> +              * assignments made by firmware for this host bridge.
>> +              */
>> +             obj = acpi_evaluate_dsm(ACPI_HANDLE(&host_bridge->dev), &pci_acpi_dsm_guid, 1,
>> +                                     DSM_PCI_PRESERVE_BOOT_CONFIG, NULL);
>> +             if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0)
>> +                     host_bridge->preserve_config = 1;
>> +             ACPI_FREE(obj);
>> +     }



From akpm at linux-foundation.org  Thu Feb 22 13:29:36 2024
From: akpm at linux-foundation.org (Andrew Morton)
Date: Thu, 22 Feb 2024 13:29:36 -0800
Subject: [PATCH v2 00/14] Split crash out from kexec and clean up
 related config items
In-Reply-To: <3393a42f-d9b3-4031-bdef-78bb2ce758f1@linux.ibm.com>
References: <20240119145241.769622-1-bhe@redhat.com>
	<9101bb07-70f1-476c-bec9-ec67e9899744@linux.ibm.com>
	<Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv>
	<559f2595-1477-4ef0-80e4-85ae8b426de7@linux.ibm.com>
	<20240221125752.36fbfe9c307496313198b60f@linux-foundation.org>
	<3393a42f-d9b3-4031-bdef-78bb2ce758f1@linux.ibm.com>
Message-ID: <20240222132936.e7dc50acbf5d1b653cb2e02c@linux-foundation.org>

On Thu, 22 Feb 2024 10:47:29 +0530 Hari Bathini <hbathini at linux.ibm.com> wrote:

> 
> 
> On 22/02/24 2:27 am, Andrew Morton wrote:
> > On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini <hbathini at linux.ibm.com> wrote:
> > 
> >> On 04/02/24 8:56 am, Baoquan He wrote:
> >>>>> Hope Hari and Pingfan can help have a look, see if
> >>>>> it's doable. Now, I make it either have both kexec and crash enabled, or
> >>>>> disable both of them altogether.
> >>>>
> >>>> Sure. I will take a closer look...
> >>> Thanks a lot. Please feel free to post patches to make that, or I can do
> >>> it with your support or suggestion.
> >>
> >> Tested your changes and on top of these changes, came up with the below
> >> changes to get it working for powerpc:
> >>
> >>   
> >> https://lore.kernel.org/all/20240213113150.1148276-1-hbathini at linux.ibm.com/
> > 
> > So can we take it that you're OK with Baoquan's series as-is?
> 
> Hi Andrew,
> 
> If you mean
> 
> v3 (https://lore.kernel.org/all/20240124051254.67105-1-bhe at redhat.com/)
> +
> follow-up from Baoquan 
> (https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z at MiWiFi-R3L-srv/)
> 
> Yes.
> 

Can I add your Acked-by: and/or Tested-by: to the patches in this series?


From pavel at ucw.cz  Thu Feb 22 13:36:09 2024
From: pavel at ucw.cz (Pavel Machek)
Date: Thu, 22 Feb 2024 22:36:09 +0100
Subject: [PATCH v2 1/4] leds: rgb: leds-group-multicolor: allow leds to
 stay on in suspend
In-Reply-To: <20240206185400.596979-1-aren@peacevolution.org>
References: <20240206185400.596979-1-aren@peacevolution.org>
Message-ID: <Zde+Sce+PAuC1U6g@duo.ucw.cz>

Hi!

> If none of the managed leds enable LED_CORE_SUSPENDRESUME, then we
> shouldn't need to set it here. This makes it possible to use multicolor
> groups with gpio leds that enable retain-state-suspended in the device
> tree.
> 
> Signed-off-by: Aren Moynihan <aren at peacevolution.org>

Thanks for the series.

Acked-by: Pavel Machek <pavel at ucw.cz>

Note this will change userland API and maybe break the LED for code
expecting old setup and hardcoding paths. I guess we should not
backport this to stable. But we should do this, because it is really
one LED and not three.

Best regards,
								Pavel
-- 
People of Russia, stop Putin before his war on Ukraine escalates.
-------------- 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/20240222/1387f09a/attachment.sig>

From andy.shevchenko at gmail.com  Thu Feb 22 13:42:11 2024
From: andy.shevchenko at gmail.com (andy.shevchenko at gmail.com)
Date: Thu, 22 Feb 2024 23:42:11 +0200
Subject: [PATCH 1/2] devm-helpers: Add resource managed version of mutex
 init
In-Reply-To: <20240222145838.12916-1-kabel@kernel.org>
References: <20240222145838.12916-1-kabel@kernel.org>
Message-ID: <Zde_s8iecR2ArKjC@surfacebook.localdomain>

Thu, Feb 22, 2024 at 03:58:37PM +0100, Marek Beh?n kirjoitti:
> A few drivers are doing resource-managed mutex initialization by
> implementing ad-hoc one-liner mutex dropping functions and using them
> with devm_add_action_or_reset(). Help drivers avoid these repeated
> one-liners by adding managed version of mutex initialization.
> 
> Use the new function devm_mutex_init() in the following drivers:
>   drivers/gpio/gpio-pisosr.c
>   drivers/gpio/gpio-sim.c
>   drivers/gpu/drm/xe/xe_hwmon.c
>   drivers/hwmon/nzxt-smart2.c
>   drivers/leds/leds-is31fl319x.c
>   drivers/power/supply/mt6370-charger.c
>   drivers/power/supply/rt9467-charger.c

Pardon me, but why?

https://lore.kernel.org/linux-leds/20231214173614.2820929-1-gnstark at salutedevices.com/

Can you cooperate, folks, instead of doing something independently?


> --- a/include/linux/devm-helpers.h
> +++ b/include/linux/devm-helpers.h
> @@ -24,6 +24,8 @@
>   */
>  
>  #include <linux/device.h>
> +#include <linux/kconfig.h>
> +#include <linux/mutex.h>
>  #include <linux/workqueue.h>
>  
>  static inline void devm_delayed_work_drop(void *res)
> @@ -76,4 +78,34 @@ static inline int devm_work_autocancel(struct device *dev,
>  	return devm_add_action(dev, devm_work_drop, w);
>  }
>  
> +static inline void devm_mutex_drop(void *res)
> +{
> +	mutex_destroy(res);
> +}
> +
> +/**
> + * devm_mutex_init - Resource managed mutex initialization
> + * @dev:	Device which lifetime mutex is bound to
> + * @lock:	Mutex to be initialized (and automatically destroyed)
> + *
> + * Initialize mutex which is automatically destroyed when driver is detached.
> + * A few drivers initialize mutexes which they want destroyed before driver is
> + * detached, for debugging purposes.
> + * devm_mutex_init() can be used to omit the explicit mutex_destroy() call when
> + * driver is detached.
> + */
> +static inline int devm_mutex_init(struct device *dev, struct mutex *lock)
> +{
> +	mutex_init(lock);
> +
> +	/*
> +	 * mutex_destroy() is an empty function if CONFIG_DEBUG_MUTEXES is
> +	 * disabled. No need to allocate an action in that case.
> +	 */
> +	if (IS_ENABLED(CONFIG_DEBUG_MUTEXES))
> +		return devm_add_action_or_reset(dev, devm_mutex_drop, lock);
> +	else
> +		return 0;
> +}

Cc: George Stark <gnstark at salutedevices.com>

-- 
With Best Regards,
Andy Shevchenko




From elliott at hpe.com  Thu Feb 22 13:50:44 2024
From: elliott at hpe.com (Elliott, Robert (Servers))
Date: Thu, 22 Feb 2024 21:50:44 +0000
Subject: [PATCH v2 2/6] crypto: crc64 - add crc64-iso framework
In-Reply-To: <87jztserrf.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
References: <20230719-mcrc-upstream-v2-0-4152b987e4c2@ti.com>
 <20230719-mcrc-upstream-v2-2-4152b987e4c2@ti.com>
 <20230812025520.GE971@sol.localdomain>
 <87jztserrf.fsf@kamlesh.i-did-not-set--mail-host-address--so-tickle-me>
Message-ID: <MW5PR84MB18424EC8DDB4863777D302E2AB562@MW5PR84MB1842.NAMPRD84.PROD.OUTLOOK.COM>



> -----Original Message-----
> From: Kamlesh Gurudasani <kamlesh at ti.com>
> Sent: Friday, August 18, 2023 2:26 AM
> Subject: Re: [EXTERNAL] Re: [PATCH v2 2/6] crypto: crc64 - add crc64-iso
> framework
> 
> Eric Biggers <ebiggers at kernel.org> writes:
> 
> > Is "crc64-iso" clear enough, or should it be "crc64-iso3309"?  There are
> > thousands of ISO standards.  Different CRC variants are specified by
> different
> > ISO standards.  Is this particular variant indeed commonly referred to
> as simply
> > the "ISO" CRC-64?  Even if it's currently the case that all other CRCs
> in ISO
> > standards are different widths than 64 bits (which may be unlikely?),
> I'm not
> > sure we should count on no CRC-64 variant ever being standardized by
> ISO.
> >
> > - Eric
> https://en.wikipedia.org/wiki/Cyclic_redundancy_check
> 
> Last entry CRC-64-ISO in the table.
> It is mentioned as crc64-iso and that's the
> only 64-bit CRC standardized by ISO. 

ECMA-182 (DLT-1 tapes) was contributed to become ISO/IEC 13421 in 1993, so
that was another "64-bit CRC standardized by ISO." Plus, ISO could publish new
standards with new CRCs at any time.

> But I do agree that crc64-iso3309 would be more specific, will change it
> to crc64-iso3309 in next revision. Thanks.
> 
> Regards,
> Kamlesh

ISO-3309:1991 was withdrawn and revised by
ISO/IEC 3309:1993, which was withdrawn and revised by
ISO/IEC 13239:2002, which was confirmed in 2007 and is still current.

Apparently only the 1991 version defined a CRC-64; later versions dropped
that.

Is there really a demand for adding a 23 year old deprecated algorithm to
the kernel?




From martin.blumenstingl at googlemail.com  Thu Feb 22 13:57:02 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Thu, 22 Feb 2024 22:57:02 +0100
Subject: [PATCH v1] clocksource/drivers/arm_global_timer: Simplify
 prescaler register access
In-Reply-To: <a4f8fa60-7c03-4946-a135-a405d53f361b@linaro.org>
References: <20240221214348.2299636-1-martin.blumenstingl@googlemail.com> <a4f8fa60-7c03-4946-a135-a405d53f361b@linaro.org>
Message-ID: <CAFBinCA3ho9fAb-iJhUEVw-=_Jbgd6UU8_9WEyvpt-+CL_V6ew@mail.gmail.com>

Hi Daniel,

On Thu, Feb 22, 2024 at 11:02?AM Daniel Lezcano
<daniel.lezcano at linaro.org> wrote:
[ ... ]
>
> >               /* prescaler within legal range? */
> > -             if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
> > +             if (psv < 0 || psv > FIELD_GET(GT_CONTROL_PRESCALER_MASK, ~0))
>
>                 FIELD_MAX() ?
Oh, I was not aware of FIELD_MAX() - thank you!
While researching that I found that there's also FIELD_FIT() which I
think is perfect here. What do you think?


Best regards,
Martin


From catalin.marinas at arm.com  Thu Feb 22 14:04:55 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 22 Feb 2024 22:04:55 +0000
Subject: [PATCH 0/2] arm64/fp: Initialise all bits in vector control registers to known values
In-Reply-To: <20240213-arm64-fp-init-vec-cr-v1-0-7e7c2d584f26@kernel.org>
References: <20240213-arm64-fp-init-vec-cr-v1-0-7e7c2d584f26@kernel.org>
Message-ID: <170863948635.1616990.11657354558055243881.b4-ty@arm.com>

On Tue, 13 Feb 2024 15:32:44 +0000, Mark Brown wrote:
> We currently do read/modify/write sequences whenever we update fields in
> ZCR_EL1 and SMCR_EL1 so fields we are not explicitly handling will not
> be initialised to known values, fix this.  The EL2 registers are already
> fully configured.
> 
> 

Applied to arm64 (for-next/misc), thanks!

[1/2] arm64/sve: Ensure that all fields in ZCR_EL1 are set to known values
      https://git.kernel.org/arm64/c/2f0090549b64
[2/2] arm64/sme: Ensure that all fields in SMCR_EL1 are set to known values
      https://git.kernel.org/arm64/c/93576e349887

-- 
Catalin



From catalin.marinas at arm.com  Thu Feb 22 14:05:08 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 22 Feb 2024 22:05:08 +0000
Subject: [PATCH v2] arm64/sve: Document that __SVE_VQ_MAX is much larger than needed
In-Reply-To: <20240209-arm64-sve-vl-max-comment-v2-1-111b283469ee@kernel.org>
References: <20240209-arm64-sve-vl-max-comment-v2-1-111b283469ee@kernel.org>
Message-ID: <170863948635.1616990.16270415841585916103.b4-ty@arm.com>

On Fri, 09 Feb 2024 16:53:36 +0000, Mark Brown wrote:
> __SVE_VQ_MAX is defined without comment as 512 but the actual
> architectural maximum is 16, a substantial difference which might not
> be obvious to readers especially given the several different units used
> for specifying vector sizes in various contexts and the fact that it's
> often used via macros.  In an effort to minimise surprises for users who
> might assume the value is the architectural maximum and use it to do
> things like size allocations add a comment noting the difference, and
> add a note for SVE_VQ_MAX to aid discoverability.
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64/sve: Document that __SVE_VQ_MAX is much larger than needed
      https://git.kernel.org/arm64/c/21eb468e9fc1

-- 
Catalin



From catalin.marinas at arm.com  Thu Feb 22 14:05:21 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 22 Feb 2024 22:05:21 +0000
Subject: [PATCH] arm64: remove unneeded BUILD_BUG_ON assertion
In-Reply-To: <20240202040211.3118918-1-dawei.li@shingroup.cn>
References: <20240202040211.3118918-1-dawei.li@shingroup.cn>
Message-ID: <170863948630.1616990.3978730044792626566.b4-ty@arm.com>

On Fri, 02 Feb 2024 12:02:11 +0800, Dawei Li wrote:
> Since commit c02433dd6de3 ("arm64: split thread_info from task stack"),
> CONFIG_THREAD_INFO_IN_TASK is enabled unconditionally for arm64. So
> remove this always-true assertion from arch_dup_task_struct.
> 
> 

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: remove unneeded BUILD_BUG_ON assertion
      https://git.kernel.org/arm64/c/bce79b0c8097

-- 
Catalin



From David.Laight at ACULAB.COM  Thu Feb 22 14:05:04 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Thu, 22 Feb 2024 22:05:04 +0000
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
Message-ID: <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>

From: Jason Gunthorpe
> Sent: 21 February 2024 01:17
> 
> The kernel provides driver support for using write combining IO memory
> through the __iowriteXX_copy() API which is commonly used as an optional
> optimization to generate 16/32/64 byte MemWr TLPs in a PCIe environment.
> 
...
> Implement __iowrite32/64_copy() specifically for ARM64 and use inline
> assembly to build consecutive blocks of STR instructions. Provide direct
> support for 64/32/16 large TLP generation in this manner. Optimize for
> common constant lengths so that the compiler can directly inline the store
> blocks.
...
> +/*
> + * This generates a memcpy that works on a from/to address which is aligned to
> + * bits. Count is in terms of the number of bits sized quantities to copy. It
> + * optimizes to use the STR groupings when possible so that it is WC friendly.
> + */
> +#define memcpy_toio_aligned(to, from, count, bits)                        \
> +	({                                                                \
> +		volatile u##bits __iomem *_to = to;                       \
> +		const u##bits *_from = from;                              \
> +		size_t _count = count;                                    \
> +		const u##bits *_end_from = _from + ALIGN_DOWN(_count, 8); \
> +                                                                          \
> +		for (; _from < _end_from; _from += 8, _to += 8)           \
> +			__const_memcpy_toio_aligned##bits(_to, _from, 8); \
> +		if ((_count % 8) >= 4) {    

If (_count & 4) {
                              \
> +			__const_memcpy_toio_aligned##bits(_to, _from, 4); \
> +			_from += 4;                                       \
> +			_to += 4;                                         \
> +		}                                                         \
> +		if ((_count % 4) >= 2) {                                  \
Ditto
> +			__const_memcpy_toio_aligned##bits(_to, _from, 2); \
> +			_from += 2;                                       \
> +			_to += 2;                                         \
> +		}                                                         \
> +		if (_count % 2)                                           \
and again
> +			__const_memcpy_toio_aligned##bits(_to, _from, 1); \
> +	})

But that looks bit a bit large to be inlined.
Except, perhaps, for small constant lengths.
I'd guess that even with write-combining and posted PCIe writes it
doesn't take much for it to be PCIe limited rather than cpu limited?

Is there a sane way to do the same for reads - they are far worse
than writes.

I solved the problem a few years back on a little ppc by using an on-cpu
DMA controller that could do PCIe master accesses and spinning until
the transfer completed.
But that sort of DMA controller seems uncommon.
We now initiate most of the transfers from the slave (an fpga) - after
writing a suitable/sane dma controller for that end.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From catalin.marinas at arm.com  Thu Feb 22 14:05:31 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 22 Feb 2024 22:05:31 +0000
Subject: [PATCH] arm64: make member of struct pt_regs and it's offset macro in the same order
In-Reply-To: <20240130175504.106364-1-shikemeng@huaweicloud.com>
References: <20240130175504.106364-1-shikemeng@huaweicloud.com>
Message-ID: <170863948634.1616990.12613009434270992544.b4-ty@arm.com>

On Wed, 31 Jan 2024 01:55:04 +0800, Kemeng Shi wrote:
> In struct pt_regs, member pstate is after member pc. Move offset macro
> of pstate after offset macro of pc to improve readability a little.
> 
> 

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: make member of struct pt_regs and it's offset macro in the same order
      https://git.kernel.org/arm64/c/58a0484eaf5e

-- 
Catalin



From catalin.marinas at arm.com  Thu Feb 22 14:05:51 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 22 Feb 2024 22:05:51 +0000
Subject: [PATCH] arm64: gitignore: ignore relacheck
In-Reply-To: <20240222210441.33142-1-brgl@bgdev.pl>
References: <20240222210441.33142-1-brgl@bgdev.pl>
Message-ID: <170863954734.1625463.11560852190517987488.b4-ty@arm.com>

On Thu, 22 Feb 2024 22:04:41 +0100, Bartosz Golaszewski wrote:
> Add the generated executable for relacheck to the list of ignored files.
> 
> 

Applied to arm64 (for-next/stage1-lpa2), thanks!

[1/1] arm64: gitignore: ignore relacheck
      https://git.kernel.org/arm64/c/275826914925

-- 
Catalin



From helgaas at kernel.org  Thu Feb 22 14:08:11 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 22 Feb 2024 16:08:11 -0600
Subject: [PATCH V3] PCI: Add support for preserving boot configuration
In-Reply-To: <17a29a7e-b013-4568-8e21-9647969b6b6d@nvidia.com>
Message-ID: <20240222220811.GA31251@bhelgaas>

On Fri, Feb 23, 2024 at 02:48:24AM +0530, Vidya Sagar wrote:
> On 22-02-2024 22:36, Bjorn Helgaas wrote:
> > On Thu, Feb 22, 2024 at 06:11:10PM +0530, Vidya Sagar wrote:

> > > +     if (&host_bridge->dev) {
> > Checking &host_bridge->dev doesn't seem like the right way to
> > determine whether this is an ACPI host bridge.

BTW, I think this condition is *always* true, since it's testing the
address of a member of a struct.

> Honestly, I couldn't find a clear way to differentiate between an
> ACPI based host bridge and a DT based host bridge. Hence, the
> current code tries to get the information using both ways and since
> a system can only be either ACPI or DT based, but one at a time,
> preserve_config will be set only once (assuming the system wants it
> to be set). Let me know if there is a better approach for this?

I'm not sure ACPI and DT will always be mutually exclusive; I think
we're headed toward some combinations, e.g.,
https://lore.kernel.org/linux-pci/1692120000-46900-1-git-send-email-lizhi.hou at amd.com/

But I think "if (ACPI_HANDLE(&host_bridge->dev))" would work.

Bjorn


From andre.przywara at arm.com  Thu Feb 22 14:12:45 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Thu, 22 Feb 2024 22:12:45 +0000
Subject: [PATCH] arm64: dts: allwinner: h616: Add Orange Pi Zero 2W to
 Makefile
In-Reply-To: <20240222211326.114955-1-jernej.skrabec@gmail.com>
References: <20240222211326.114955-1-jernej.skrabec@gmail.com>
Message-ID: <20240222221245.216f403a@minigeek.lan>

On Thu, 22 Feb 2024 22:13:26 +0100
Jernej Skrabec <jernej.skrabec at gmail.com> wrote:

Hi,

> Orange Pi Zero 2W dts file is not included in Makefile. Fix this.
> 
> Fixes: c505ee1eae18 ("arm64: dts: allwinner: h616: add Orange Pi Zero 2W support")
> Signed-off-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Ah, sorry, I think this was lost during a rebase, when the other H618
boards were merged.

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/arm64/boot/dts/allwinner/Makefile | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> index 91d505b385de..1f1f8d865d0e 100644
> --- a/arch/arm64/boot/dts/allwinner/Makefile
> +++ b/arch/arm64/boot/dts/allwinner/Makefile
> @@ -42,5 +42,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero2w.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
>  dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb



From daniel.lezcano at linaro.org  Thu Feb 22 14:34:24 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Thu, 22 Feb 2024 23:34:24 +0100
Subject: [PATCH v1] clocksource/drivers/arm_global_timer: Simplify
 prescaler register access
In-Reply-To: <CAFBinCA3ho9fAb-iJhUEVw-=_Jbgd6UU8_9WEyvpt-+CL_V6ew@mail.gmail.com>
References: <20240221214348.2299636-1-martin.blumenstingl@googlemail.com>
 <a4f8fa60-7c03-4946-a135-a405d53f361b@linaro.org>
 <CAFBinCA3ho9fAb-iJhUEVw-=_Jbgd6UU8_9WEyvpt-+CL_V6ew@mail.gmail.com>
Message-ID: <230587eb-dd68-414b-af15-47b1eb3d14e3@linaro.org>

On 22/02/2024 22:57, Martin Blumenstingl wrote:
> Hi Daniel,
> 
> On Thu, Feb 22, 2024 at 11:02?AM Daniel Lezcano
> <daniel.lezcano at linaro.org> wrote:
> [ ... ]
>>
>>>                /* prescaler within legal range? */
>>> -             if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
>>> +             if (psv < 0 || psv > FIELD_GET(GT_CONTROL_PRESCALER_MASK, ~0))
>>
>>                  FIELD_MAX() ?
> Oh, I was not aware of FIELD_MAX() - thank you!
> While researching that I found that there's also FIELD_FIT() which I
> think is perfect here. What do you think?

Ah yes, even better :)

-- 
<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 jgg at nvidia.com  Thu Feb 22 14:36:17 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 22 Feb 2024 18:36:17 -0400
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
Message-ID: <20240222223617.GC13330@nvidia.com>

On Thu, Feb 22, 2024 at 10:05:04PM +0000, David Laight wrote:
> From: Jason Gunthorpe
> > Sent: 21 February 2024 01:17
> > 
> > The kernel provides driver support for using write combining IO memory
> > through the __iowriteXX_copy() API which is commonly used as an optional
> > optimization to generate 16/32/64 byte MemWr TLPs in a PCIe environment.
> > 
> ...
> > Implement __iowrite32/64_copy() specifically for ARM64 and use inline
> > assembly to build consecutive blocks of STR instructions. Provide direct
> > support for 64/32/16 large TLP generation in this manner. Optimize for
> > common constant lengths so that the compiler can directly inline the store
> > blocks.
> ...
> > +/*
> > + * This generates a memcpy that works on a from/to address which is aligned to
> > + * bits. Count is in terms of the number of bits sized quantities to copy. It
> > + * optimizes to use the STR groupings when possible so that it is WC friendly.
> > + */
> > +#define memcpy_toio_aligned(to, from, count, bits)                        \
> > +	({                                                                \
> > +		volatile u##bits __iomem *_to = to;                       \
> > +		const u##bits *_from = from;                              \
> > +		size_t _count = count;                                    \
> > +		const u##bits *_end_from = _from + ALIGN_DOWN(_count, 8); \
> > +                                                                          \
> > +		for (; _from < _end_from; _from += 8, _to += 8)           \
> > +			__const_memcpy_toio_aligned##bits(_to, _from, 8); \
> > +		if ((_count % 8) >= 4) {    
> 
> If (_count & 4) {

That would be obfuscating, IMHO. The compiler doesn't need such things
to generate optimal code.

> > +			__const_memcpy_toio_aligned##bits(_to, _from, 1); \
> > +	})
> 
> But that looks bit a bit large to be inlined.

You trimmed alot, this #define is in a C file and it is a template to
generate the 32 and 64 bit out of line functions. Things are done like
this because the 32/64 version are exactly the same logic except just
with different types and sizes.

Jason


From seanjc at google.com  Thu Feb 22 14:42:10 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 14:42:10 -0800
Subject: [PATCH v8 10/10] KVM: selftests: Add a basic SEV smoke test
In-Reply-To: <ZcKYRsNUAngWGy2a@google.com>
References: <20240203000917.376631-1-seanjc@google.com> <20240203000917.376631-11-seanjc@google.com>
 <ZcKYRsNUAngWGy2a@google.com>
Message-ID: <ZdfNwhe2s0Mn2gB4@google.com>

On Tue, Feb 06, 2024, Sean Christopherson wrote:
> On Fri, Feb 02, 2024, Sean Christopherson wrote:
> > +int main(int argc, char *argv[])
> > +{
> > +	TEST_REQUIRE(is_kvm_sev_supported());
> 
> This also needs
> 
> 	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV));
> 
> to handle the case where the platform supports SEV, i.e. /dev/sev exists, but
> KVM doesn't support SEV, e.g. if TDP is disabled, if SEV was explicitly disabled
> via module param, etc.

Thinking more about this, I think we should simply delete is_kvm_sev_supported().
(a) it obviously doesn't query _KVM_ support, and (b) if KVM says SEV is supported,
then it darn well actually be supported.


From seanjc at google.com  Thu Feb 22 14:55:30 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 14:55:30 -0800
Subject: [PATCH v8 10/10] KVM: selftests: Add a basic SEV smoke test
In-Reply-To: <ZdfNwhe2s0Mn2gB4@google.com>
References: <20240203000917.376631-1-seanjc@google.com> <20240203000917.376631-11-seanjc@google.com>
 <ZcKYRsNUAngWGy2a@google.com> <ZdfNwhe2s0Mn2gB4@google.com>
Message-ID: <ZdfQ4jI8yT-bvbV4@google.com>

On Thu, Feb 22, 2024, Sean Christopherson wrote:
> On Tue, Feb 06, 2024, Sean Christopherson wrote:
> > On Fri, Feb 02, 2024, Sean Christopherson wrote:
> > > +int main(int argc, char *argv[])
> > > +{
> > > +	TEST_REQUIRE(is_kvm_sev_supported());
> > 
> > This also needs
> > 
> > 	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV));
> > 
> > to handle the case where the platform supports SEV, i.e. /dev/sev exists, but
> > KVM doesn't support SEV, e.g. if TDP is disabled, if SEV was explicitly disabled
> > via module param, etc.
> 
> Thinking more about this, I think we should simply delete is_kvm_sev_supported().
> (a) it obviously doesn't query _KVM_ support, and (b) if KVM says SEV is supported,
> then it darn well actually be supported.

Ugh, and selftests also need to handle the scenario where SEV is enabled, but all
ASIDs are assigned to SEV-ES.  We could try to create a dummy VM and check for an
-EBUSY return, but that is ugly and could result in missing KVM bugs due to tests
being skipped instead of failing.

That's a future problem though, because I think we'll need new KVM functionality
to surface that information.


From aishwarya.tcv at arm.com  Thu Feb 22 14:59:58 2024
From: aishwarya.tcv at arm.com (Aishwarya TCV)
Date: Thu, 22 Feb 2024 22:59:58 +0000
Subject: [PATCH v12 02/25] genirq/irqdomain: Remove the param count
 restriction from select()
In-Reply-To: <87edd4a2fo.wl-maz@kernel.org>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
 <20240127161753.114685-3-apatel@ventanamicro.com>
 <e42b76a9-fc5f-4ab7-96a2-629261a9c983@arm.com> <87edd4a2fo.wl-maz@kernel.org>
Message-ID: <27ad9614-e3de-4965-9f4e-865bc541eb4c@arm.com>



On 22/02/2024 16:28, Marc Zyngier wrote:
> On Thu, 22 Feb 2024 13:01:32 +0000,
> Aishwarya TCV <aishwarya.tcv at arm.com> wrote:
>>
>>
>>
>> On 27/01/2024 16:17, Anup Patel wrote:
>>> From: Thomas Gleixner <tglx at linutronix.de>
>>>
>>> Now that the GIC-v3 callback can handle invocation with a fwspec parameter
>>> count of 0 lift the restriction in the core code and invoke select()
>>> unconditionally when the domain provides it.
>>>
>>> Preparatory change for per device MSI domains.
>>>
>>> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
>>> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
>>> ---
>>
>> Hi Thomas/Anup
>>
>> Currently when booting the kernel against next-master(next-20240222)
>> with Arm64 on Qualcomm boards RB5/DB845C, the kernel is resulting in
>> boot failures for our CI. I can send the full logs if required. Most
>> other boards seem to be fine.
>>
>> A bisect (full log below) identified this patch as introducing the
>> failure. Bisected it on the tag "next-20240220" at repo
>> "https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git".
>>
>> This works fine on Linux v6.8-rc5
> 
> Can you please try [1]?
> 
> 	M.
> 
> [1] https://lore.kernel.org/linux-kernel/20240220114731.1898534-1-maz at kernel.org
> 

With the patch[1] applied on next-master(next-20240222), successfully
tested booting the kernel with Arm64 on Qualcomm boards RB5/DB845C.
Confirming that the patch is resolving the boot issue on RB5/DB845C

Thanks
Aishwarya


From kuba at kernel.org  Thu Feb 22 15:10:23 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Thu, 22 Feb 2024 15:10:23 -0800
Subject: [PATCH net-next v8 08/13] netlink: specs: add ethnl PHY_GET
 command set
In-Reply-To: <20240222084948.16f33760@device-28.home>
References: <20240220184217.3689988-1-maxime.chevallier@bootlin.com>
	<20240220184217.3689988-9-maxime.chevallier@bootlin.com>
	<20240221170023.452a01ca@kernel.org>
	<20240222084948.16f33760@device-28.home>
Message-ID: <20240222151023.64abe662@kernel.org>

On Thu, 22 Feb 2024 08:49:48 +0100 Maxime Chevallier wrote:
> > ethtool-user.c:689:10: error: ?ETHTOOL_A_PHY_UPSTREAM_PHY_INDEX? undeclared here (not in a function); did you mean ?ETHTOOL_A_PHY_UPSTREAM_INDEX??
> >   689 |         [ETHTOOL_A_PHY_UPSTREAM_PHY_INDEX] = { .name = "upstream-phy-index", .type = YNL_PT_U32, },
> >       |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >       |          ETHTOOL_A_PHY_UPSTREAM_INDEX
> > 
> > Unfortunately ethtool in the in-between state where we can auto-gen
> > user space code (or rather most of it) but the uAPI header is not
> > auto-generated so we need to take extra care to keep things in sync :(  
> 
> Is there anything I run for testing, so that I can make sure this
> doesn't happen again ?

make -C tools/net/ynl

will run the build. It needs some basic python libs, should be easy to
figure out from stack traces if they are missing. 

I didn't mention it to you because.. it may not build for you on
net-next until what I'm about to post gets merged.


From quic_eberman at quicinc.com  Thu Feb 22 15:16:24 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:24 -0800
Subject: [PATCH v17 01/35] docs: gunyah: Introduce Gunyah Hypervisor
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-1-1e9da6763d38@quicinc.com>

Gunyah is an open-source Type-1 hypervisor developed by Qualcomm. It
does not depend on any lower-privileged OS/kernel code for its core
functionality. This increases its security and can support a smaller
trusted computing based when compared to Type-2 hypervisors.

Add documentation describing the Gunyah hypervisor and the main
components of the Gunyah hypervisor which are of interest to Linux
virtualization development.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 Documentation/virt/gunyah/index.rst         | 135 ++++++++++++++++++++++++++++
 Documentation/virt/gunyah/message-queue.rst |  68 ++++++++++++++
 Documentation/virt/index.rst                |   1 +
 3 files changed, 204 insertions(+)

diff --git a/Documentation/virt/gunyah/index.rst b/Documentation/virt/gunyah/index.rst
new file mode 100644
index 0000000000000..fba2c7a11d0f8
--- /dev/null
+++ b/Documentation/virt/gunyah/index.rst
@@ -0,0 +1,135 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+Gunyah Hypervisor
+=================
+
+.. toctree::
+   :maxdepth: 1
+
+   message-queue
+
+Gunyah is a Type-1 hypervisor which is independent of any OS kernel, and runs in
+a more privileged CPU level (EL2 on Aarch64). It does not depend on a less
+privileged operating system for its core functionality. This increases its
+security and can support a much smaller trusted computing base than a Type-2
+hypervisor.
+
+Gunyah is an open source hypervisor. The source repository is available at
+https://github.com/quic/gunyah-hypervisor.
+
+Gunyah provides these following features.
+
+- Scheduling:
+
+  A scheduler for virtual CPUs (vCPUs) on physical CPUs enables time-sharing
+  of the CPUs. Gunyah supports two models of scheduling which can coexist on
+  a running system:
+
+    1. Hypervisor vCPU scheduling in which Gunyah hypervisor schedules vCPUS on
+       its own. The default is a real-time priority with round-robin scheduler.
+    2. "Proxy" scheduling in which an owner-VM can donate the remainder of its
+       own vCPU's time slice to an owned-VM's vCPU via a hypercall.
+
+- Memory Management:
+
+  APIs handling memory, abstracted as objects, limiting direct use of physical
+  addresses. Memory ownership and usage tracking of all memory under its control.
+  Memory partitioning between VMs is a fundamental security feature.
+
+- Interrupt Virtualization:
+
+  Interrupt ownership is tracked and interrupt delivery is directly to the
+  assigned VM. Gunyah makes use of hardware interrupt virtualization where
+  possible.
+
+- Inter-VM Communication:
+
+  There are several different mechanisms provided for communicating between VMs.
+
+    1. Message queues
+    2. Doorbells
+    3. Virtio MMIO transport
+    4. Shared memory
+
+- Virtual platform:
+
+  Architectural devices such as interrupt controllers and CPU timers are
+  directly provided by the hypervisor as well as core virtual platform devices
+  and system APIs such as ARM PSCI.
+
+- Device Virtualization:
+
+  Para-virtualization of devices is supported using inter-VM communication and
+  virtio transport support. Select stage 2 faults by virtual machines that use
+  proxy-scheduled vCPUs can be handled directly by Linux to provide Type-2
+  hypervisor style on-demand paging and/or device emulation.
+
+Architectures supported
+=======================
+AArch64 with a GICv3 or GICv4.1
+
+Resources and Capabilities
+==========================
+
+Services/resources provided by the Gunyah hypervisor are accessible to a
+virtual machine through capabilities. A capability is an access control
+token granting the holder a set of permissions to operate on a specific
+hypervisor object (conceptually similar to a file-descriptor).
+For example, inter-VM communication using Gunyah doorbells and message queues
+is performed using hypercalls taking Capability ID arguments for the required
+IPC objects. These resources are described in Linux as a struct gunyah_resource.
+
+Unlike UNIX file descriptors, there is no path-based or similar lookup of
+an object to create a new Capability, meaning simpler security analysis.
+Creation of a new Capability requires the holding of a set of privileged
+Capabilities which are typically never given out by the Resource Manager (RM).
+
+Gunyah itself provides no APIs for Capability ID discovery. Enumeration of
+Capability IDs is provided by RM as a higher level service to VMs.
+
+Resource Manager
+================
+
+The Gunyah Resource Manager (RM) is a privileged application VM supporting the
+Gunyah Hypervisor. It provides policy enforcement aspects of the virtualization
+system. The resource manager can be treated as an extension of the Hypervisor
+but is separated to its own partition to ensure that the hypervisor layer itself
+remains small and secure and to maintain a separation of policy and mechanism in
+the platform. The resource manager runs at arm64 NS-EL1, similar to other
+virtual machines.
+
+Communication with the resource manager from other virtual machines happens as
+described in message-queue.rst. Details about the specific messages can be found
+in drivers/virt/gunyah/rsc_mgr.c
+
+::
+
+  +-------+   +--------+   +--------+
+  |  RM   |   |  VM_A  |   |  VM_B  |
+  +-.-.-.-+   +---.----+   +---.----+
+    | |           |            |
+  +-.-.-----------.------------.----+
+  | | \==========/             |    |
+  |  \========================/     |
+  |            Gunyah               |
+  +---------------------------------+
+
+The source for the resource manager is available at
+https://github.com/quic/gunyah-resource-manager.
+
+The resource manager provides the following features:
+
+- VM lifecycle management: allocating a VM, starting VMs, destruction of VMs
+- VM access control policy, including memory sharing and lending
+- Interrupt routing configuration
+- Forwarding of system-level events (e.g. VM shutdown) to owner VM
+- Resource (capability) discovery
+
+A VM requires boot configuration to establish communication with the resource
+manager. This is provided to VMs via a 'hypervisor' device tree node which is
+overlaid to the VMs DT by the RM. This node lets guests know they are running
+as a Gunyah guest VM, how to communicate with resource manager, and basic
+description and capabilities of this VM. See
+Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml for a
+description of this node.
diff --git a/Documentation/virt/gunyah/message-queue.rst b/Documentation/virt/gunyah/message-queue.rst
new file mode 100644
index 0000000000000..96864708f442e
--- /dev/null
+++ b/Documentation/virt/gunyah/message-queue.rst
@@ -0,0 +1,68 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Message Queues
+==============
+Message queue is a simple low-capacity IPC channel between two virtual machines.
+It is intended for sending small control and configuration messages. Each
+message queue is unidirectional and buffered in the hypervisor. A full-duplex
+IPC channel requires a pair of queues.
+
+The size of the queue and the maximum size of the message that can be passed is
+fixed at creation of the message queue. Resource manager is presently the only
+use case for message queues, and creates messages queues between itself and VMs
+with a fixed maximum message size of 240 bytes. Longer messages require a
+further protocol on top of the message queue messages themselves. For instance,
+communication with the resource manager adds a header field for sending longer
+messages which are split into smaller fragments.
+
+The diagram below shows how message queue works. A typical configuration
+involves 2 message queues. Message queue 1 allows VM_A to send messages to VM_B.
+Message queue 2 allows VM_B to send messages to VM_A.
+
+1. VM_A sends a message of up to 240 bytes in length. It makes a hypercall
+   with the message to request the hypervisor to add the message to
+   message queue 1's queue. The hypervisor copies memory into the internal
+   message queue buffer; the memory doesn't need to be shared between
+   VM_A and VM_B.
+
+2. Gunyah raises the corresponding interrupt for VM_B (Rx vIRQ) when any of
+   these happens:
+
+   a. gunyah_msgq_send() has PUSH flag. This is a typical case when the message
+      queue is being used to implement an RPC-like interface.
+   b. Explicitly with gunyah_msgq_push hypercall from VM_A.
+   c. Message queue has reached a threshold depth. Typically, this threshold
+      depth is the size of the queue (in other words: when queue is full, Rx
+      vIRQ is raised).
+
+3. VM_B calls gunyah_msgq_recv() and Gunyah copies message to requested buffer.
+
+4. Gunyah raises the corresponding interrupt for VM_A (Tx vIRQ) when the message
+   queue falls below a watermark depth. Typically, this is when the queue is
+   drained. Note the watermark depth and the threshold depth for the Rx vIRQ are
+   independent values. Coincidentally, this signal is conceptually similar to
+   Clear-to-Send.
+
+For VM_B to send a message to VM_A, the process is identical, except that
+hypercalls reference message queue 2's capability ID. The IRQ will be different
+for the second message queue.
+
+::
+
+      +-------------------+         +-----------------+         +-------------------+
+      |        VM_A       |         |Gunyah hypervisor|         |        VM_B       |
+      |                   |         |                 |         |                   |
+      |                   |         |                 |         |                   |
+      |                   |   Tx    |                 |         |                   |
+      |                   |-------->|                 | Rx vIRQ |                   |
+      |gunyah_msgq_send() | Tx vIRQ |Message queue 1  |-------->|gunyah_msgq_recv() |
+      |                   |<------- |                 |         |                   |
+      |                   |         |                 |         |                   |
+      |                   |         |                 |         |                   |
+      |                   |         |                 |   Tx    |                   |
+      |                   | Rx vIRQ |                 |<--------|                   |
+      |gunyah_msgq_recv() |<--------|Message queue 2  | Tx vIRQ |gunyah_msgq_send() |
+      |                   |         |                 |-------->|                   |
+      |                   |         |                 |         |                   |
+      |                   |         |                 |         |                   |
+      +-------------------+         +-----------------+         +---------------+
diff --git a/Documentation/virt/index.rst b/Documentation/virt/index.rst
index 7fb55ae08598d..15869ee059b35 100644
--- a/Documentation/virt/index.rst
+++ b/Documentation/virt/index.rst
@@ -16,6 +16,7 @@ Virtualization Support
    coco/sev-guest
    coco/tdx-guest
    hyperv/index
+   gunyah/index
 
 .. only:: html and subproject
 

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:31 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:31 -0800
Subject: [PATCH v17 08/35] gunyah: vm_mgr: Introduce basic VM Manager
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-8-1e9da6763d38@quicinc.com>

Gunyah VM manager is a kernel moduel which exposes an interface to
userspace to load, run, and interact with other Gunyah virtual machines.
The interface is a character device at /dev/gunyah.

Add a basic VM manager driver. Upcoming patches will add more ioctls
into this driver.

Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
Reviewed-by: Alex Elder <elder at linaro.org>
Co-developed-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 Documentation/userspace-api/ioctl/ioctl-number.rst |  1 +
 drivers/virt/gunyah/Makefile                       |  2 +-
 drivers/virt/gunyah/rsc_mgr.c                      | 50 +++++++++++-
 drivers/virt/gunyah/rsc_mgr.h                      |  2 +
 drivers/virt/gunyah/vm_mgr.c                       | 94 ++++++++++++++++++++++
 drivers/virt/gunyah/vm_mgr.h                       | 28 +++++++
 include/uapi/linux/gunyah.h                        | 23 ++++++
 7 files changed, 198 insertions(+), 2 deletions(-)

diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 457e16f06e04d..149e3899ad785 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -136,6 +136,7 @@ Code  Seq#    Include File                                           Comments
 'F'   DD     video/sstfb.h                                           conflict!
 'G'   00-3F  drivers/misc/sgi-gru/grulib.h                           conflict!
 'G'   00-0F  xen/gntalloc.h, xen/gntdev.h                            conflict!
+'G'   00-0F  linux/gunyah.h                                          conflict!
 'H'   00-7F  linux/hiddev.h                                          conflict!
 'H'   00-0F  linux/hidraw.h                                          conflict!
 'H'   01     linux/mei.h                                             conflict!
diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
index c2308389f5517..ceccbbe68b380 100644
--- a/drivers/virt/gunyah/Makefile
+++ b/drivers/virt/gunyah/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
-gunyah_rsc_mgr-y += rsc_mgr.o
+gunyah_rsc_mgr-y += rsc_mgr.o vm_mgr.o
 
 obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o
diff --git a/drivers/virt/gunyah/rsc_mgr.c b/drivers/virt/gunyah/rsc_mgr.c
index 4ac946da0ca7f..fb0efe68f0e22 100644
--- a/drivers/virt/gunyah/rsc_mgr.c
+++ b/drivers/virt/gunyah/rsc_mgr.c
@@ -10,8 +10,10 @@
 #include <linux/notifier.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/miscdevice.h>
 
 #include "rsc_mgr.h"
+#include "vm_mgr.h"
 
 /* clang-format off */
 #define RM_RPC_API_VERSION_MASK		GENMASK(3, 0)
@@ -118,6 +120,7 @@ struct gunyah_rm_message {
  * @send_lock: synchronization to allow only one request to be sent at a time
  * @send_ready: completed when we know Tx message queue can take more messages
  * @nh: notifier chain for clients interested in RM notification messages
+ * @miscdev: /dev/gunyah
  */
 struct gunyah_rm {
 	struct device *dev;
@@ -133,6 +136,8 @@ struct gunyah_rm {
 	struct mutex send_lock;
 	struct completion send_ready;
 	struct blocking_notifier_head nh;
+
+	struct miscdevice miscdev;
 };
 
 /**
@@ -613,6 +618,36 @@ int gunyah_rm_notifier_unregister(struct gunyah_rm *rm,
 }
 EXPORT_SYMBOL_GPL(gunyah_rm_notifier_unregister);
 
+struct device *gunyah_rm_get(struct gunyah_rm *rm)
+{
+	return get_device(rm->miscdev.this_device);
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_get);
+
+void gunyah_rm_put(struct gunyah_rm *rm)
+{
+	put_device(rm->miscdev.this_device);
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_put);
+
+static long gunyah_dev_ioctl(struct file *filp, unsigned int cmd,
+			     unsigned long arg)
+{
+	struct miscdevice *miscdev = filp->private_data;
+	struct gunyah_rm *rm = container_of(miscdev, struct gunyah_rm, miscdev);
+
+	return gunyah_dev_vm_mgr_ioctl(rm, cmd, arg);
+}
+
+static const struct file_operations gunyah_dev_fops = {
+	/* clang-format off */
+	.owner		= THIS_MODULE,
+	.unlocked_ioctl	= gunyah_dev_ioctl,
+	.compat_ioctl	= compat_ptr_ioctl,
+	.llseek		= noop_llseek,
+	/* clang-format on */
+};
+
 static int gunyah_platform_probe_capability(struct platform_device *pdev,
 					    int idx,
 					    struct gunyah_resource *ghrsc)
@@ -699,7 +734,19 @@ static int gunyah_rm_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	return 0;
+	rm->miscdev.parent = &pdev->dev;
+	rm->miscdev.name = "gunyah";
+	rm->miscdev.minor = MISC_DYNAMIC_MINOR;
+	rm->miscdev.fops = &gunyah_dev_fops;
+
+	return misc_register(&rm->miscdev);
+}
+
+static void gunyah_rm_remove(struct platform_device *pdev)
+{
+	struct gunyah_rm *rm = platform_get_drvdata(pdev);
+
+	misc_deregister(&rm->miscdev);
 }
 
 static const struct of_device_id gunyah_rm_of_match[] = {
@@ -710,6 +757,7 @@ MODULE_DEVICE_TABLE(of, gunyah_rm_of_match);
 
 static struct platform_driver gunyah_rm_driver = {
 	.probe = gunyah_rm_probe,
+	.remove_new = gunyah_rm_remove,
 	.driver = {
 		.name = "gunyah_rsc_mgr",
 		.of_match_table = gunyah_rm_of_match,
diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h
index 48b69dbf2190b..21318ef25040c 100644
--- a/drivers/virt/gunyah/rsc_mgr.h
+++ b/drivers/virt/gunyah/rsc_mgr.h
@@ -17,6 +17,8 @@ int gunyah_rm_notifier_register(struct gunyah_rm *rm,
 				struct notifier_block *nb);
 int gunyah_rm_notifier_unregister(struct gunyah_rm *rm,
 				  struct notifier_block *nb);
+struct device *gunyah_rm_get(struct gunyah_rm *rm);
+void gunyah_rm_put(struct gunyah_rm *rm);
 
 
 int gunyah_rm_call(struct gunyah_rm *rsc_mgr, u32 message_id,
diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
new file mode 100644
index 0000000000000..e9dff733e35ef
--- /dev/null
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "gunyah_vm_mgr: " fmt
+
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+
+#include <uapi/linux/gunyah.h>
+
+#include "rsc_mgr.h"
+#include "vm_mgr.h"
+
+static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
+{
+	struct gunyah_vm *ghvm;
+
+	ghvm = kzalloc(sizeof(*ghvm), GFP_KERNEL);
+	if (!ghvm)
+		return ERR_PTR(-ENOMEM);
+
+	ghvm->parent = gunyah_rm_get(rm);
+	ghvm->rm = rm;
+
+	return ghvm;
+}
+
+static int gunyah_vm_release(struct inode *inode, struct file *filp)
+{
+	struct gunyah_vm *ghvm = filp->private_data;
+
+	gunyah_rm_put(ghvm->rm);
+	kfree(ghvm);
+	return 0;
+}
+
+static const struct file_operations gunyah_vm_fops = {
+	.owner = THIS_MODULE,
+	.release = gunyah_vm_release,
+	.llseek = noop_llseek,
+};
+
+static long gunyah_dev_ioctl_create_vm(struct gunyah_rm *rm, unsigned long arg)
+{
+	struct gunyah_vm *ghvm;
+	struct file *file;
+	int fd, err;
+
+	/* arg reserved for future use. */
+	if (arg)
+		return -EINVAL;
+
+	ghvm = gunyah_vm_alloc(rm);
+	if (IS_ERR(ghvm))
+		return PTR_ERR(ghvm);
+
+	fd = get_unused_fd_flags(O_CLOEXEC);
+	if (fd < 0) {
+		err = fd;
+		goto err_destroy_vm;
+	}
+
+	file = anon_inode_getfile("gunyah-vm", &gunyah_vm_fops, ghvm, O_RDWR);
+	if (IS_ERR(file)) {
+		err = PTR_ERR(file);
+		goto err_put_fd;
+	}
+
+	fd_install(fd, file);
+
+	return fd;
+
+err_put_fd:
+	put_unused_fd(fd);
+err_destroy_vm:
+	gunyah_rm_put(ghvm->rm);
+	kfree(ghvm);
+	return err;
+}
+
+long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
+			     unsigned long arg)
+{
+	switch (cmd) {
+	case GUNYAH_CREATE_VM:
+		return gunyah_dev_ioctl_create_vm(rm, arg);
+	default:
+		return -ENOTTY;
+	}
+}
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
new file mode 100644
index 0000000000000..50790d4026765
--- /dev/null
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _GUNYAH_VM_MGR_PRIV_H
+#define _GUNYAH_VM_MGR_PRIV_H
+
+#include <linux/device.h>
+
+#include <uapi/linux/gunyah.h>
+
+#include "rsc_mgr.h"
+
+long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
+			     unsigned long arg);
+
+/**
+ * struct gunyah_vm - Main representation of a Gunyah Virtual machine
+ * @rm: Pointer to the resource manager struct to make RM calls
+ * @parent: For logging
+ */
+struct gunyah_vm {
+	struct gunyah_rm *rm;
+	struct device *parent;
+};
+
+#endif
diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h
new file mode 100644
index 0000000000000..ac338ec4b85dd
--- /dev/null
+++ b/include/uapi/linux/gunyah.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _UAPI_LINUX_GUNYAH_H
+#define _UAPI_LINUX_GUNYAH_H
+
+/*
+ * Userspace interface for /dev/gunyah - gunyah based virtual machine
+ */
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define GUNYAH_IOCTL_TYPE 'G'
+
+/*
+ * ioctls for /dev/gunyah fds:
+ */
+#define GUNYAH_CREATE_VM _IO(GUNYAH_IOCTL_TYPE, 0x0) /* Returns a Gunyah VM fd */
+
+#endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:33 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:33 -0800
Subject: [PATCH v17 10/35] gunyah: vm_mgr: Add VM start/stop
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-10-1e9da6763d38@quicinc.com>

Add ioctl to trigger the start of a Gunyah virtual machine. Subsequent
commits will provide memory to the virtual machine and add ability to
interact with the resources (capabilities) of the virtual machine.
Although start of the virtual machine can be done implicitly on the
first vCPU run for proxy-schedule virtual machines, there is a
non-trivial number of calls to Gunyah: a more precise error can be given
to userspace which calls VM_START without looking at kernel logs because
userspace can detect that the VM start failed instead of "couldn't run
the vCPU".

Co-developed-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/vm_mgr.c | 198 +++++++++++++++++++++++++++++++++++++++++++
 drivers/virt/gunyah/vm_mgr.h |  19 +++++
 include/uapi/linux/gunyah.h  |   5 ++
 3 files changed, 222 insertions(+)

diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index e9dff733e35ef..364a53cad643e 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -15,6 +15,68 @@
 #include "rsc_mgr.h"
 #include "vm_mgr.h"
 
+static int gunyah_vm_rm_notification_status(struct gunyah_vm *ghvm, void *data)
+{
+	struct gunyah_rm_vm_status_payload *payload = data;
+
+	if (le16_to_cpu(payload->vmid) != ghvm->vmid)
+		return NOTIFY_OK;
+
+	/* All other state transitions are synchronous to a corresponding RM call */
+	if (payload->vm_status == GUNYAH_RM_VM_STATUS_RESET) {
+		down_write(&ghvm->status_lock);
+		ghvm->vm_status = payload->vm_status;
+		up_write(&ghvm->status_lock);
+		wake_up(&ghvm->vm_status_wait);
+	}
+
+	return NOTIFY_DONE;
+}
+
+static int gunyah_vm_rm_notification_exited(struct gunyah_vm *ghvm, void *data)
+{
+	struct gunyah_rm_vm_exited_payload *payload = data;
+
+	if (le16_to_cpu(payload->vmid) != ghvm->vmid)
+		return NOTIFY_OK;
+
+	down_write(&ghvm->status_lock);
+	ghvm->vm_status = GUNYAH_RM_VM_STATUS_EXITED;
+	up_write(&ghvm->status_lock);
+	wake_up(&ghvm->vm_status_wait);
+
+	return NOTIFY_DONE;
+}
+
+static int gunyah_vm_rm_notification(struct notifier_block *nb,
+				     unsigned long action, void *data)
+{
+	struct gunyah_vm *ghvm = container_of(nb, struct gunyah_vm, nb);
+
+	switch (action) {
+	case GUNYAH_RM_NOTIFICATION_VM_STATUS:
+		return gunyah_vm_rm_notification_status(ghvm, data);
+	case GUNYAH_RM_NOTIFICATION_VM_EXITED:
+		return gunyah_vm_rm_notification_exited(ghvm, data);
+	default:
+		return NOTIFY_OK;
+	}
+}
+
+static void gunyah_vm_stop(struct gunyah_vm *ghvm)
+{
+	int ret;
+
+	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_RUNNING) {
+		ret = gunyah_rm_vm_stop(ghvm->rm, ghvm->vmid);
+		if (ret)
+			dev_warn(ghvm->parent, "Failed to stop VM: %d\n", ret);
+	}
+
+	wait_event(ghvm->vm_status_wait,
+		   ghvm->vm_status != GUNYAH_RM_VM_STATUS_RUNNING);
+}
+
 static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 {
 	struct gunyah_vm *ghvm;
@@ -24,14 +86,148 @@ static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 		return ERR_PTR(-ENOMEM);
 
 	ghvm->parent = gunyah_rm_get(rm);
+	ghvm->vmid = GUNYAH_VMID_INVAL;
 	ghvm->rm = rm;
 
+	init_rwsem(&ghvm->status_lock);
+	init_waitqueue_head(&ghvm->vm_status_wait);
+	ghvm->vm_status = GUNYAH_RM_VM_STATUS_NO_STATE;
+
 	return ghvm;
 }
 
+static int gunyah_vm_start(struct gunyah_vm *ghvm)
+{
+	int ret;
+
+	down_write(&ghvm->status_lock);
+	if (ghvm->vm_status != GUNYAH_RM_VM_STATUS_NO_STATE) {
+		up_write(&ghvm->status_lock);
+		return 0;
+	}
+
+	ghvm->nb.notifier_call = gunyah_vm_rm_notification;
+	ret = gunyah_rm_notifier_register(ghvm->rm, &ghvm->nb);
+	if (ret)
+		goto err;
+
+	ret = gunyah_rm_alloc_vmid(ghvm->rm, 0);
+	if (ret < 0) {
+		gunyah_rm_notifier_unregister(ghvm->rm, &ghvm->nb);
+		goto err;
+	}
+	ghvm->vmid = ret;
+	ghvm->vm_status = GUNYAH_RM_VM_STATUS_LOAD;
+
+	ret = gunyah_rm_vm_configure(ghvm->rm, ghvm->vmid, ghvm->auth, 0, 0, 0,
+				     0, 0);
+	if (ret) {
+		dev_warn(ghvm->parent, "Failed to configure VM: %d\n", ret);
+		goto err;
+	}
+
+	ret = gunyah_rm_vm_init(ghvm->rm, ghvm->vmid);
+	if (ret) {
+		ghvm->vm_status = GUNYAH_RM_VM_STATUS_INIT_FAILED;
+		dev_warn(ghvm->parent, "Failed to initialize VM: %d\n", ret);
+		goto err;
+	}
+	ghvm->vm_status = GUNYAH_RM_VM_STATUS_READY;
+
+	ret = gunyah_rm_vm_start(ghvm->rm, ghvm->vmid);
+	if (ret) {
+		dev_warn(ghvm->parent, "Failed to start VM: %d\n", ret);
+		goto err;
+	}
+
+	ghvm->vm_status = GUNYAH_RM_VM_STATUS_RUNNING;
+	up_write(&ghvm->status_lock);
+	return ret;
+err:
+	/* gunyah_vm_free will handle releasing resources and reclaiming memory */
+	up_write(&ghvm->status_lock);
+	return ret;
+}
+
+static int gunyah_vm_ensure_started(struct gunyah_vm *ghvm)
+{
+	int ret;
+
+	ret = down_read_interruptible(&ghvm->status_lock);
+	if (ret)
+		return ret;
+
+	/* Unlikely because VM is typically started */
+	if (unlikely(ghvm->vm_status == GUNYAH_RM_VM_STATUS_NO_STATE)) {
+		up_read(&ghvm->status_lock);
+		ret = gunyah_vm_start(ghvm);
+		if (ret)
+			return ret;
+		ret = down_read_interruptible(&ghvm->status_lock);
+		if (ret)
+			return ret;
+	}
+
+	/* Unlikely because VM is typically running */
+	if (unlikely(ghvm->vm_status != GUNYAH_RM_VM_STATUS_RUNNING))
+		ret = -ENODEV;
+
+	up_read(&ghvm->status_lock);
+	return ret;
+}
+
+static long gunyah_vm_ioctl(struct file *filp, unsigned int cmd,
+			    unsigned long arg)
+{
+	struct gunyah_vm *ghvm = filp->private_data;
+	long r;
+
+	switch (cmd) {
+	case GUNYAH_VM_START: {
+		r = gunyah_vm_ensure_started(ghvm);
+		break;
+	}
+	default:
+		r = -ENOTTY;
+		break;
+	}
+
+	return r;
+}
+
 static int gunyah_vm_release(struct inode *inode, struct file *filp)
 {
 	struct gunyah_vm *ghvm = filp->private_data;
+	int ret;
+
+	/**
+	 * We might race with a VM exit notification, but that's ok:
+	 * gh_rm_vm_stop() will just return right away.
+	 */
+	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_RUNNING)
+		gunyah_vm_stop(ghvm);
+
+	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_EXITED ||
+	    ghvm->vm_status == GUNYAH_RM_VM_STATUS_READY ||
+	    ghvm->vm_status == GUNYAH_RM_VM_STATUS_INIT_FAILED) {
+		ret = gunyah_rm_vm_reset(ghvm->rm, ghvm->vmid);
+		/* clang-format off */
+		if (!ret)
+			wait_event(ghvm->vm_status_wait,
+				   ghvm->vm_status == GUNYAH_RM_VM_STATUS_RESET);
+		else
+			dev_err(ghvm->parent, "Failed to reset the vm: %d\n",ret);
+		/* clang-format on */
+	}
+
+	if (ghvm->vm_status > GUNYAH_RM_VM_STATUS_NO_STATE) {
+		gunyah_rm_notifier_unregister(ghvm->rm, &ghvm->nb);
+
+		ret = gunyah_rm_dealloc_vmid(ghvm->rm, ghvm->vmid);
+		if (ret)
+			dev_warn(ghvm->parent,
+				 "Failed to deallocate vmid: %d\n", ret);
+	}
 
 	gunyah_rm_put(ghvm->rm);
 	kfree(ghvm);
@@ -40,6 +236,8 @@ static int gunyah_vm_release(struct inode *inode, struct file *filp)
 
 static const struct file_operations gunyah_vm_fops = {
 	.owner = THIS_MODULE,
+	.unlocked_ioctl = gunyah_vm_ioctl,
+	.compat_ioctl = compat_ptr_ioctl,
 	.release = gunyah_vm_release,
 	.llseek = noop_llseek,
 };
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index 50790d4026765..e6cc9aead0b67 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -7,6 +7,8 @@
 #define _GUNYAH_VM_MGR_PRIV_H
 
 #include <linux/device.h>
+#include <linux/rwsem.h>
+#include <linux/wait.h>
 
 #include <uapi/linux/gunyah.h>
 
@@ -17,12 +19,29 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
 
 /**
  * struct gunyah_vm - Main representation of a Gunyah Virtual machine
+ * @vmid: Gunyah's VMID for this virtual machine
  * @rm: Pointer to the resource manager struct to make RM calls
  * @parent: For logging
+ * @nb: Notifier block for RM notifications
+ * @vm_status: Current state of the VM, as last reported by RM
+ * @vm_status_wait: Wait queue for status @vm_status changes
+ * @status_lock: Serializing state transitions
+ * @auth: Authentication mechanism to be used by resource manager when
+ *        launching the VM
+ *
+ * Members are grouped by hot path.
  */
 struct gunyah_vm {
+	u16 vmid;
 	struct gunyah_rm *rm;
+
+	struct notifier_block nb;
+	enum gunyah_rm_vm_status vm_status;
+	wait_queue_head_t vm_status_wait;
+	struct rw_semaphore status_lock;
+
 	struct device *parent;
+	enum gunyah_rm_vm_auth_mechanism auth;
 };
 
 #endif
diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h
index ac338ec4b85dd..31e7f79a6c398 100644
--- a/include/uapi/linux/gunyah.h
+++ b/include/uapi/linux/gunyah.h
@@ -20,4 +20,9 @@
  */
 #define GUNYAH_CREATE_VM _IO(GUNYAH_IOCTL_TYPE, 0x0) /* Returns a Gunyah VM fd */
 
+/*
+ * ioctls for gunyah-vm fds (returned by GUNYAH_CREATE_VM)
+ */
+#define GUNYAH_VM_START		_IO(GUNYAH_IOCTL_TYPE, 0x3)
+
 #endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:32 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:32 -0800
Subject: [PATCH v17 09/35] gunyah: rsc_mgr: Add VM lifecycle RPC
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-9-1e9da6763d38@quicinc.com>

Add Gunyah Resource Manager RPC interfaces to launch an unauthenticated
virtual machine.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/Makefile      |   2 +-
 drivers/virt/gunyah/rsc_mgr.h     |  78 ++++++++++++
 drivers/virt/gunyah/rsc_mgr_rpc.c | 248 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 327 insertions(+), 1 deletion(-)

diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
index ceccbbe68b380..47f1fae5419bf 100644
--- a/drivers/virt/gunyah/Makefile
+++ b/drivers/virt/gunyah/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
-gunyah_rsc_mgr-y += rsc_mgr.o vm_mgr.o
+gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o
 
 obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o
diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h
index 21318ef25040c..205b9ea735e53 100644
--- a/drivers/virt/gunyah/rsc_mgr.h
+++ b/drivers/virt/gunyah/rsc_mgr.h
@@ -20,6 +20,84 @@ int gunyah_rm_notifier_unregister(struct gunyah_rm *rm,
 struct device *gunyah_rm_get(struct gunyah_rm *rm);
 void gunyah_rm_put(struct gunyah_rm *rm);
 
+struct gunyah_rm_vm_exited_payload {
+	__le16 vmid;
+	__le16 exit_type;
+	__le32 exit_reason_size;
+	u8 exit_reason[];
+} __packed;
+
+enum gunyah_rm_notification_id {
+	/* clang-format off */
+	GUNYAH_RM_NOTIFICATION_VM_EXITED		 = 0x56100001,
+	GUNYAH_RM_NOTIFICATION_VM_STATUS		 = 0x56100008,
+	/* clang-format on */
+};
+
+enum gunyah_rm_vm_status {
+	/* clang-format off */
+	GUNYAH_RM_VM_STATUS_NO_STATE		= 0,
+	GUNYAH_RM_VM_STATUS_INIT		= 1,
+	GUNYAH_RM_VM_STATUS_READY		= 2,
+	GUNYAH_RM_VM_STATUS_RUNNING		= 3,
+	GUNYAH_RM_VM_STATUS_PAUSED		= 4,
+	GUNYAH_RM_VM_STATUS_LOAD		= 5,
+	GUNYAH_RM_VM_STATUS_AUTH		= 6,
+	GUNYAH_RM_VM_STATUS_INIT_FAILED		= 8,
+	GUNYAH_RM_VM_STATUS_EXITED		= 9,
+	GUNYAH_RM_VM_STATUS_RESETTING		= 10,
+	GUNYAH_RM_VM_STATUS_RESET		= 11,
+	/* clang-format on */
+};
+
+struct gunyah_rm_vm_status_payload {
+	__le16 vmid;
+	u16 reserved;
+	u8 vm_status;
+	u8 os_status;
+	__le16 app_status;
+} __packed;
+
+int gunyah_rm_alloc_vmid(struct gunyah_rm *rm, u16 vmid);
+int gunyah_rm_dealloc_vmid(struct gunyah_rm *rm, u16 vmid);
+int gunyah_rm_vm_reset(struct gunyah_rm *rm, u16 vmid);
+int gunyah_rm_vm_start(struct gunyah_rm *rm, u16 vmid);
+int gunyah_rm_vm_stop(struct gunyah_rm *rm, u16 vmid);
+
+enum gunyah_rm_vm_auth_mechanism {
+	/* clang-format off */
+	GUNYAH_RM_VM_AUTH_NONE			= 0,
+	GUNYAH_RM_VM_AUTH_QCOM_PIL_ELF		= 1,
+	GUNYAH_RM_VM_AUTH_QCOM_ANDROID_PVM	= 2,
+	/* clang-format on */
+};
+
+int gunyah_rm_vm_configure(struct gunyah_rm *rm, u16 vmid,
+			   enum gunyah_rm_vm_auth_mechanism auth_mechanism,
+			   u32 mem_handle, u64 image_offset, u64 image_size,
+			   u64 dtb_offset, u64 dtb_size);
+int gunyah_rm_vm_init(struct gunyah_rm *rm, u16 vmid);
+
+struct gunyah_rm_hyp_resource {
+	u8 type;
+	u8 reserved;
+	__le16 partner_vmid;
+	__le32 resource_handle;
+	__le32 resource_label;
+	__le64 cap_id;
+	__le32 virq_handle;
+	__le32 virq;
+	__le64 base;
+	__le64 size;
+} __packed;
+
+struct gunyah_rm_hyp_resources {
+	__le32 n_entries;
+	struct gunyah_rm_hyp_resource entries[];
+} __packed;
+
+int gunyah_rm_get_hyp_resources(struct gunyah_rm *rm, u16 vmid,
+				struct gunyah_rm_hyp_resources **resources);
 
 int gunyah_rm_call(struct gunyah_rm *rsc_mgr, u32 message_id,
 		   const void *req_buf, size_t req_buf_size, void **resp_buf,
diff --git a/drivers/virt/gunyah/rsc_mgr_rpc.c b/drivers/virt/gunyah/rsc_mgr_rpc.c
new file mode 100644
index 0000000000000..c2f4ccae8f3bc
--- /dev/null
+++ b/drivers/virt/gunyah/rsc_mgr_rpc.c
@@ -0,0 +1,248 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/error-injection.h>
+
+#include "rsc_mgr.h"
+
+/* Message IDs: VM Management */
+/* clang-format off */
+#define GUNYAH_RM_RPC_VM_ALLOC_VMID		0x56000001
+#define GUNYAH_RM_RPC_VM_DEALLOC_VMID		0x56000002
+#define GUNYAH_RM_RPC_VM_START			0x56000004
+#define GUNYAH_RM_RPC_VM_STOP			0x56000005
+#define GUNYAH_RM_RPC_VM_RESET			0x56000006
+#define GUNYAH_RM_RPC_VM_CONFIG_IMAGE		0x56000009
+#define GUNYAH_RM_RPC_VM_INIT			0x5600000B
+#define GUNYAH_RM_RPC_VM_GET_HYP_RESOURCES	0x56000020
+/* clang-format on */
+
+struct gunyah_rm_vm_common_vmid_req {
+	__le16 vmid;
+	__le16 _padding;
+} __packed;
+
+/* Call: VM_ALLOC */
+struct gunyah_rm_vm_alloc_vmid_resp {
+	__le16 vmid;
+	__le16 _padding;
+} __packed;
+
+/* Call: VM_STOP */
+#define GUNYAH_RM_VM_STOP_FLAG_FORCE_STOP BIT(0)
+
+#define GUNYAH_RM_VM_STOP_REASON_FORCE_STOP 3
+
+struct gunyah_rm_vm_stop_req {
+	__le16 vmid;
+	u8 flags;
+	u8 _padding;
+	__le32 stop_reason;
+} __packed;
+
+/* Call: VM_CONFIG_IMAGE */
+struct gunyah_rm_vm_config_image_req {
+	__le16 vmid;
+	__le16 auth_mech;
+	__le32 mem_handle;
+	__le64 image_offset;
+	__le64 image_size;
+	__le64 dtb_offset;
+	__le64 dtb_size;
+} __packed;
+
+/*
+ * Several RM calls take only a VMID as a parameter and give only standard
+ * response back. Deduplicate boilerplate code by using this common call.
+ */
+static int gunyah_rm_common_vmid_call(struct gunyah_rm *rm, u32 message_id,
+				      u16 vmid)
+{
+	struct gunyah_rm_vm_common_vmid_req req_payload = {
+		.vmid = cpu_to_le16(vmid),
+	};
+
+	return gunyah_rm_call(rm, message_id, &req_payload, sizeof(req_payload),
+			      NULL, NULL);
+}
+
+/**
+ * gunyah_rm_alloc_vmid() - Allocate a new VM in Gunyah. Returns the VM identifier.
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: Use 0 to dynamically allocate a VM. A reserved VMID can be supplied
+ *        to request allocation of a platform-defined VM.
+ *
+ * Return: the allocated VMID or negative value on error
+ */
+int gunyah_rm_alloc_vmid(struct gunyah_rm *rm, u16 vmid)
+{
+	struct gunyah_rm_vm_common_vmid_req req_payload = {
+		.vmid = cpu_to_le16(vmid),
+	};
+	struct gunyah_rm_vm_alloc_vmid_resp *resp_payload;
+	size_t resp_size;
+	void *resp;
+	int ret;
+
+	ret = gunyah_rm_call(rm, GUNYAH_RM_RPC_VM_ALLOC_VMID, &req_payload,
+			     sizeof(req_payload), &resp, &resp_size);
+	if (ret)
+		return ret;
+
+	if (!vmid) {
+		resp_payload = resp;
+		ret = le16_to_cpu(resp_payload->vmid);
+		kfree(resp);
+	}
+
+	return ret;
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_alloc_vmid, ERRNO);
+
+/**
+ * gunyah_rm_dealloc_vmid() - Dispose of a VMID
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: VM identifier allocated with gunyah_rm_alloc_vmid
+ */
+int gunyah_rm_dealloc_vmid(struct gunyah_rm *rm, u16 vmid)
+{
+	return gunyah_rm_common_vmid_call(rm, GUNYAH_RM_RPC_VM_DEALLOC_VMID,
+					  vmid);
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_dealloc_vmid, ERRNO);
+
+/**
+ * gunyah_rm_vm_reset() - Reset a VM's resources
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: VM identifier allocated with gunyah_rm_alloc_vmid
+ *
+ * As part of tearing down the VM, request RM to clean up all the VM resources
+ * associated with the VM. Only after this, Linux can clean up all the
+ * references it maintains to resources.
+ */
+int gunyah_rm_vm_reset(struct gunyah_rm *rm, u16 vmid)
+{
+	return gunyah_rm_common_vmid_call(rm, GUNYAH_RM_RPC_VM_RESET, vmid);
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_vm_reset, ERRNO);
+
+/**
+ * gunyah_rm_vm_start() - Move a VM into "ready to run" state
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: VM identifier allocated with gunyah_rm_alloc_vmid
+ *
+ * On VMs which use proxy scheduling, vcpu_run is needed to actually run the VM.
+ * On VMs which use Gunyah's scheduling, the vCPUs start executing in accordance with Gunyah
+ * scheduling policies.
+ */
+int gunyah_rm_vm_start(struct gunyah_rm *rm, u16 vmid)
+{
+	return gunyah_rm_common_vmid_call(rm, GUNYAH_RM_RPC_VM_START, vmid);
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_vm_start, ERRNO);
+
+/**
+ * gunyah_rm_vm_stop() - Send a request to Resource Manager VM to forcibly stop a VM.
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: VM identifier allocated with gunyah_rm_alloc_vmid
+ */
+int gunyah_rm_vm_stop(struct gunyah_rm *rm, u16 vmid)
+{
+	struct gunyah_rm_vm_stop_req req_payload = {
+		.vmid = cpu_to_le16(vmid),
+		.flags = GUNYAH_RM_VM_STOP_FLAG_FORCE_STOP,
+		.stop_reason = cpu_to_le32(GUNYAH_RM_VM_STOP_REASON_FORCE_STOP),
+	};
+
+	return gunyah_rm_call(rm, GUNYAH_RM_RPC_VM_STOP, &req_payload,
+			      sizeof(req_payload), NULL, NULL);
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_vm_stop, ERRNO);
+
+/**
+ * gunyah_rm_vm_configure() - Prepare a VM to start and provide the common
+ *			  configuration needed by RM to configure a VM
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: VM identifier allocated with gunyah_rm_alloc_vmid
+ * @auth_mechanism: Authentication mechanism used by resource manager to verify
+ *                  the virtual machine
+ * @mem_handle: Handle to a previously shared memparcel that contains all parts
+ *              of the VM image subject to authentication.
+ * @image_offset: Start address of VM image, relative to the start of memparcel
+ * @image_size: Size of the VM image
+ * @dtb_offset: Start address of the devicetree binary with VM configuration,
+ *              relative to start of memparcel.
+ * @dtb_size: Maximum size of devicetree binary.
+ */
+int gunyah_rm_vm_configure(struct gunyah_rm *rm, u16 vmid,
+			   enum gunyah_rm_vm_auth_mechanism auth_mechanism,
+			   u32 mem_handle, u64 image_offset, u64 image_size,
+			   u64 dtb_offset, u64 dtb_size)
+{
+	struct gunyah_rm_vm_config_image_req req_payload = {
+		.vmid = cpu_to_le16(vmid),
+		.auth_mech = cpu_to_le16(auth_mechanism),
+		.mem_handle = cpu_to_le32(mem_handle),
+		.image_offset = cpu_to_le64(image_offset),
+		.image_size = cpu_to_le64(image_size),
+		.dtb_offset = cpu_to_le64(dtb_offset),
+		.dtb_size = cpu_to_le64(dtb_size),
+	};
+
+	return gunyah_rm_call(rm, GUNYAH_RM_RPC_VM_CONFIG_IMAGE, &req_payload,
+			      sizeof(req_payload), NULL, NULL);
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_vm_configure, ERRNO);
+
+/**
+ * gunyah_rm_vm_init() - Move the VM to initialized state.
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: VM identifier
+ *
+ * RM will allocate needed resources for the VM.
+ */
+int gunyah_rm_vm_init(struct gunyah_rm *rm, u16 vmid)
+{
+	return gunyah_rm_common_vmid_call(rm, GUNYAH_RM_RPC_VM_INIT, vmid);
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_vm_init, ERRNO);
+
+/**
+ * gunyah_rm_get_hyp_resources() - Retrieve hypervisor resources (capabilities) associated with a VM
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: VMID of the other VM to get the resources of
+ * @resources: Set by gunyah_rm_get_hyp_resources and contains the returned hypervisor resources.
+ *             Caller must free the resources pointer if successful.
+ */
+int gunyah_rm_get_hyp_resources(struct gunyah_rm *rm, u16 vmid,
+				struct gunyah_rm_hyp_resources **resources)
+{
+	struct gunyah_rm_vm_common_vmid_req req_payload = {
+		.vmid = cpu_to_le16(vmid),
+	};
+	struct gunyah_rm_hyp_resources *resp;
+	size_t resp_size;
+	int ret;
+
+	ret = gunyah_rm_call(rm, GUNYAH_RM_RPC_VM_GET_HYP_RESOURCES,
+			     &req_payload, sizeof(req_payload), (void **)&resp,
+			     &resp_size);
+	if (ret)
+		return ret;
+
+	if (!resp_size)
+		return -EBADMSG;
+
+	if (resp_size < struct_size(resp, entries, 0) ||
+	    resp_size !=
+		    struct_size(resp, entries, le32_to_cpu(resp->n_entries))) {
+		kfree(resp);
+		return -EBADMSG;
+	}
+
+	*resources = resp;
+	return 0;
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_get_hyp_resources, ERRNO);

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:28 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:28 -0800
Subject: [PATCH v17 05/35] virt: gunyah: Add hypervisor driver
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-5-1e9da6763d38@quicinc.com>

Add driver to detect when running under Gunyah. It performs basic
identification hypercall and populates the platform bus for resource
manager to probe.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/Makefile        |  1 +
 drivers/virt/gunyah/Makefile |  3 +++
 drivers/virt/gunyah/gunyah.c | 52 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile
index f29901bd78205..ef6a3835d078c 100644
--- a/drivers/virt/Makefile
+++ b/drivers/virt/Makefile
@@ -10,3 +10,4 @@ obj-y				+= vboxguest/
 obj-$(CONFIG_NITRO_ENCLAVES)	+= nitro_enclaves/
 obj-$(CONFIG_ACRN_HSM)		+= acrn/
 obj-y				+= coco/
+obj-y				+= gunyah/
diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
new file mode 100644
index 0000000000000..34f32110faf9a
--- /dev/null
+++ b/drivers/virt/gunyah/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_GUNYAH) += gunyah.o
diff --git a/drivers/virt/gunyah/gunyah.c b/drivers/virt/gunyah/gunyah.c
new file mode 100644
index 0000000000000..ef8a85f275905
--- /dev/null
+++ b/drivers/virt/gunyah/gunyah.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/gunyah.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+static int gunyah_probe(struct platform_device *pdev)
+{
+	struct gunyah_hypercall_hyp_identify_resp gunyah_api;
+
+	if (!arch_is_gunyah_guest())
+		return -ENODEV;
+
+	gunyah_hypercall_hyp_identify(&gunyah_api);
+
+	pr_info("Running under Gunyah hypervisor %llx/v%u\n",
+		FIELD_GET(GUNYAH_API_INFO_VARIANT_MASK, gunyah_api.api_info),
+		gunyah_api_version(&gunyah_api));
+
+	/* Might move this out to individual drivers if there's ever an API version bump */
+	if (gunyah_api_version(&gunyah_api) != GUNYAH_API_V1) {
+		pr_info("Unsupported Gunyah version: %u\n",
+			gunyah_api_version(&gunyah_api));
+		return -ENODEV;
+	}
+
+	return devm_of_platform_populate(&pdev->dev);
+}
+
+static const struct of_device_id gunyah_of_match[] = {
+	{ .compatible = "gunyah-hypervisor" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, gunyah_of_match);
+
+/* clang-format off */
+static struct platform_driver gunyah_driver = {
+	.probe = gunyah_probe,
+	.driver = {
+		.name = "gunyah",
+		.of_match_table = gunyah_of_match,
+	}
+};
+/* clang-format on */
+module_platform_driver(gunyah_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Gunyah Driver");

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:34 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:34 -0800
Subject: [PATCH v17 11/35] virt: gunyah: Translate gh_rm_hyp_resource into
 gunyah_resource
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-11-1e9da6763d38@quicinc.com>

When booting a Gunyah virtual machine, the host VM may gain capabilities
to interact with resources for the guest virtual machine. Examples of
such resources are vCPUs or message queues. To use those resources, we
need to translate the RM response into a gunyah_resource structure which
are useful to Linux drivers. Presently, Linux drivers need only to know
the type of resource, the capability ID, and an interrupt.

On ARM64 systems, the interrupt reported by Gunyah is the GIC interrupt
ID number and always a SPI or extended SPI.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 arch/arm64/include/asm/gunyah.h | 36 ++++++++++++++++++++++
 drivers/virt/gunyah/rsc_mgr.c   | 67 +++++++++++++++++++++++++++++++++++++++++
 drivers/virt/gunyah/rsc_mgr.h   |  5 +++
 include/linux/gunyah.h          |  2 ++
 4 files changed, 110 insertions(+)

diff --git a/arch/arm64/include/asm/gunyah.h b/arch/arm64/include/asm/gunyah.h
new file mode 100644
index 0000000000000..0cd3debe22b64
--- /dev/null
+++ b/arch/arm64/include/asm/gunyah.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef _ASM_GUNYAH_H
+#define _ASM_GUNYAH_H
+
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+
+static inline int arch_gunyah_fill_irq_fwspec_params(u32 virq,
+						 struct irq_fwspec *fwspec)
+{
+	/* Assume that Gunyah gave us an SPI or ESPI; defensively check it */
+	if (WARN(virq < 32, "Unexpected virq: %d\n", virq)) {
+		return -EINVAL;
+	} else if (virq <= 1019) {
+		fwspec->param_count = 3;
+		fwspec->param[0] = 0; /* GIC_SPI */
+		fwspec->param[1] = virq - 32; /* virq 32 -> SPI 0 */
+		fwspec->param[2] = IRQ_TYPE_EDGE_RISING;
+	} else if (WARN(virq < 4096, "Unexpected virq: %d\n", virq)) {
+		return -EINVAL;
+	} else if (virq < 5120) {
+		fwspec->param_count = 3;
+		fwspec->param[0] = 2; /* GIC_ESPI */
+		fwspec->param[1] = virq - 4096; /* virq 4096 -> ESPI 0 */
+		fwspec->param[2] = IRQ_TYPE_EDGE_RISING;
+	} else {
+		WARN(1, "Unexpected virq: %d\n", virq);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+#endif
diff --git a/drivers/virt/gunyah/rsc_mgr.c b/drivers/virt/gunyah/rsc_mgr.c
index fb0efe68f0e22..c320c9ceaf8ac 100644
--- a/drivers/virt/gunyah/rsc_mgr.c
+++ b/drivers/virt/gunyah/rsc_mgr.c
@@ -9,9 +9,12 @@
 #include <linux/mutex.h>
 #include <linux/notifier.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/miscdevice.h>
 
+#include <asm/gunyah.h>
+
 #include "rsc_mgr.h"
 #include "vm_mgr.h"
 
@@ -121,6 +124,7 @@ struct gunyah_rm_message {
  * @send_ready: completed when we know Tx message queue can take more messages
  * @nh: notifier chain for clients interested in RM notification messages
  * @miscdev: /dev/gunyah
+ * @parent_fwnode: Parent IRQ fwnode to translate Gunyah hwirqs to Linux irqs
  */
 struct gunyah_rm {
 	struct device *dev;
@@ -138,6 +142,7 @@ struct gunyah_rm {
 	struct blocking_notifier_head nh;
 
 	struct miscdevice miscdev;
+	struct fwnode_handle *parent_fwnode;
 };
 
 /**
@@ -178,6 +183,53 @@ static inline int gunyah_rm_error_remap(enum gunyah_rm_error rm_error)
 	}
 }
 
+struct gunyah_resource *
+gunyah_rm_alloc_resource(struct gunyah_rm *rm,
+			 struct gunyah_rm_hyp_resource *hyp_resource)
+{
+	struct gunyah_resource *ghrsc;
+	int ret;
+
+	ghrsc = kzalloc(sizeof(*ghrsc), GFP_KERNEL);
+	if (!ghrsc)
+		return NULL;
+
+	ghrsc->type = hyp_resource->type;
+	ghrsc->capid = le64_to_cpu(hyp_resource->cap_id);
+	ghrsc->irq = IRQ_NOTCONNECTED;
+	ghrsc->rm_label = le32_to_cpu(hyp_resource->resource_label);
+	if (hyp_resource->virq) {
+		struct irq_fwspec fwspec;
+
+
+		fwspec.fwnode = rm->parent_fwnode;
+		ret = arch_gunyah_fill_irq_fwspec_params(le32_to_cpu(hyp_resource->virq), &fwspec);
+		if (ret) {
+			dev_err(rm->dev,
+				"Failed to translate interrupt for resource %d label: %d: %d\n",
+				ghrsc->type, ghrsc->rm_label, ret);
+		}
+
+		ret = irq_create_fwspec_mapping(&fwspec);
+		if (ret < 0) {
+			dev_err(rm->dev,
+				"Failed to allocate interrupt for resource %d label: %d: %d\n",
+				ghrsc->type, ghrsc->rm_label, ret);
+			kfree(ghrsc);
+			return NULL;
+		}
+		ghrsc->irq = ret;
+	}
+
+	return ghrsc;
+}
+
+void gunyah_rm_free_resource(struct gunyah_resource *ghrsc)
+{
+	irq_dispose_mapping(ghrsc->irq);
+	kfree(ghrsc);
+}
+
 static int gunyah_rm_init_message_payload(struct gunyah_rm_message *message,
 					  const void *msg, size_t hdr_size,
 					  size_t msg_size)
@@ -707,6 +759,7 @@ static int gunyah_rm_probe_rx_msgq(struct gunyah_rm *rm,
 
 static int gunyah_rm_probe(struct platform_device *pdev)
 {
+	struct device_node *parent_irq_node;
 	struct gunyah_rm *rm;
 	int ret;
 
@@ -734,6 +787,20 @@ static int gunyah_rm_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	parent_irq_node = of_irq_find_parent(pdev->dev.of_node);
+	if (!parent_irq_node) {
+		dev_err(&pdev->dev,
+			"Failed to find interrupt parent of resource manager\n");
+		return -ENODEV;
+	}
+
+	rm->parent_fwnode = of_node_to_fwnode(parent_irq_node);
+	if (!rm->parent_fwnode) {
+		dev_err(&pdev->dev,
+			"Failed to find interrupt parent domain of resource manager\n");
+		return -ENODEV;
+	}
+
 	rm->miscdev.parent = &pdev->dev;
 	rm->miscdev.name = "gunyah";
 	rm->miscdev.minor = MISC_DYNAMIC_MINOR;
diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h
index 205b9ea735e53..52711de77bb79 100644
--- a/drivers/virt/gunyah/rsc_mgr.h
+++ b/drivers/virt/gunyah/rsc_mgr.h
@@ -99,6 +99,11 @@ struct gunyah_rm_hyp_resources {
 int gunyah_rm_get_hyp_resources(struct gunyah_rm *rm, u16 vmid,
 				struct gunyah_rm_hyp_resources **resources);
 
+struct gunyah_resource *
+gunyah_rm_alloc_resource(struct gunyah_rm *rm,
+			 struct gunyah_rm_hyp_resource *hyp_resource);
+void gunyah_rm_free_resource(struct gunyah_resource *ghrsc);
+
 int gunyah_rm_call(struct gunyah_rm *rsc_mgr, u32 message_id,
 		   const void *req_buf, size_t req_buf_size, void **resp_buf,
 		   size_t *resp_buf_size);
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index acd70f9824253..45033bdb5e151 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -29,6 +29,8 @@ struct gunyah_resource {
 	enum gunyah_resource_type type;
 	u64 capid;
 	unsigned int irq;
+
+	u32 rm_label;
 };
 
 /******************************************************************************/

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:29 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:29 -0800
Subject: [PATCH v17 06/35] virt: gunyah: msgq: Add hypercalls to send and
 receive messages
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-6-1e9da6763d38@quicinc.com>

Add hypercalls to send and receive messages on a Gunyah message queue.

Reviewed-by: Alex Elder <elder at linaro.org>
Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 arch/arm64/gunyah/gunyah_hypercall.c | 55 ++++++++++++++++++++++++++++++++++++
 include/linux/gunyah.h               |  8 ++++++
 2 files changed, 63 insertions(+)

diff --git a/arch/arm64/gunyah/gunyah_hypercall.c b/arch/arm64/gunyah/gunyah_hypercall.c
index d44663334f381..1302e128be6e9 100644
--- a/arch/arm64/gunyah/gunyah_hypercall.c
+++ b/arch/arm64/gunyah/gunyah_hypercall.c
@@ -37,6 +37,8 @@ EXPORT_SYMBOL_GPL(arch_is_gunyah_guest);
 
 /* clang-format off */
 #define GUNYAH_HYPERCALL_HYP_IDENTIFY		GUNYAH_HYPERCALL(0x8000)
+#define GUNYAH_HYPERCALL_MSGQ_SEND		GUNYAH_HYPERCALL(0x801B)
+#define GUNYAH_HYPERCALL_MSGQ_RECV		GUNYAH_HYPERCALL(0x801C)
 /* clang-format on */
 
 /**
@@ -58,5 +60,58 @@ void gunyah_hypercall_hyp_identify(
 }
 EXPORT_SYMBOL_GPL(gunyah_hypercall_hyp_identify);
 
+/**
+ * gunyah_hypercall_msgq_send() - Send a buffer on a message queue
+ * @capid: capability ID of the message queue to add message
+ * @size: Size of @buff
+ * @buff: Address of buffer to send
+ * @tx_flags: See GUNYAH_HYPERCALL_MSGQ_TX_FLAGS_*
+ * @ready: If the send was successful, ready is filled with true if more
+ *         messages can be sent on the queue. If false, then the tx IRQ will
+ *         be raised in future when send can succeed.
+ */
+enum gunyah_error gunyah_hypercall_msgq_send(u64 capid, size_t size, void *buff,
+					     u64 tx_flags, bool *ready)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GUNYAH_HYPERCALL_MSGQ_SEND, capid, size,
+			  (uintptr_t)buff, tx_flags, 0, &res);
+
+	if (res.a0 == GUNYAH_ERROR_OK)
+		*ready = !!res.a1;
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_msgq_send);
+
+/**
+ * gunyah_hypercall_msgq_recv() - Send a buffer on a message queue
+ * @capid: capability ID of the message queue to add message
+ * @buff: Address of buffer to copy received data into
+ * @size: Size of @buff
+ * @recv_size: If the receive was successful, recv_size is filled with the
+ *             size of data received. Will be <= size.
+ * @ready: If the receive was successful, ready is filled with true if more
+ *         messages are ready to be received on the queue. If false, then the
+ *         rx IRQ will be raised in future when recv can succeed.
+ */
+enum gunyah_error gunyah_hypercall_msgq_recv(u64 capid, void *buff, size_t size,
+					     size_t *recv_size, bool *ready)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GUNYAH_HYPERCALL_MSGQ_RECV, capid, (uintptr_t)buff,
+			  size, 0, &res);
+
+	if (res.a0 == GUNYAH_ERROR_OK) {
+		*recv_size = res.a1;
+		*ready = !!res.a2;
+	}
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_msgq_recv);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Gunyah Hypervisor Hypercalls");
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index 33bcbd22d39f7..acd70f9824253 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -141,4 +141,12 @@ gunyah_api_version(const struct gunyah_hypercall_hyp_identify_resp *gunyah_api)
 void gunyah_hypercall_hyp_identify(
 	struct gunyah_hypercall_hyp_identify_resp *hyp_identity);
 
+/* Immediately raise RX vIRQ on receiver VM */
+#define GUNYAH_HYPERCALL_MSGQ_TX_FLAGS_PUSH BIT(0)
+
+enum gunyah_error gunyah_hypercall_msgq_send(u64 capid, size_t size, void *buff,
+					     u64 tx_flags, bool *ready);
+enum gunyah_error gunyah_hypercall_msgq_recv(u64 capid, void *buff, size_t size,
+					     size_t *recv_size, bool *ready);
+
 #endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:26 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:26 -0800
Subject: [PATCH v17 03/35] gunyah: Common types and error codes for Gunyah
 hypercalls
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-3-1e9da6763d38@quicinc.com>

Add architecture-independent standard error codes, types, and macros for
Gunyah hypercalls.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
Reviewed-by: Alex Elder <elder at linaro.org>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 include/linux/gunyah.h | 106 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
new file mode 100644
index 0000000000000..1eab631a49b6d
--- /dev/null
+++ b/include/linux/gunyah.h
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _LINUX_GUNYAH_H
+#define _LINUX_GUNYAH_H
+
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/limits.h>
+
+/* Matches resource manager's resource types for VM_GET_HYP_RESOURCES RPC */
+enum gunyah_resource_type {
+	/* clang-format off */
+	GUNYAH_RESOURCE_TYPE_BELL_TX	= 0,
+	GUNYAH_RESOURCE_TYPE_BELL_RX	= 1,
+	GUNYAH_RESOURCE_TYPE_MSGQ_TX	= 2,
+	GUNYAH_RESOURCE_TYPE_MSGQ_RX	= 3,
+	GUNYAH_RESOURCE_TYPE_VCPU	= 4,
+	GUNYAH_RESOURCE_TYPE_MEM_EXTENT	= 9,
+	GUNYAH_RESOURCE_TYPE_ADDR_SPACE	= 10,
+	/* clang-format on */
+};
+
+struct gunyah_resource {
+	enum gunyah_resource_type type;
+	u64 capid;
+	unsigned int irq;
+};
+
+/******************************************************************************/
+/* Common arch-independent definitions for Gunyah hypercalls                  */
+#define GUNYAH_CAPID_INVAL U64_MAX
+#define GUNYAH_VMID_ROOT_VM 0xff
+
+enum gunyah_error {
+	/* clang-format off */
+	GUNYAH_ERROR_OK				= 0,
+	GUNYAH_ERROR_UNIMPLEMENTED		= -1,
+	GUNYAH_ERROR_RETRY			= -2,
+
+	GUNYAH_ERROR_ARG_INVAL			= 1,
+	GUNYAH_ERROR_ARG_SIZE			= 2,
+	GUNYAH_ERROR_ARG_ALIGN			= 3,
+
+	GUNYAH_ERROR_NOMEM			= 10,
+
+	GUNYAH_ERROR_ADDR_OVFL			= 20,
+	GUNYAH_ERROR_ADDR_UNFL			= 21,
+	GUNYAH_ERROR_ADDR_INVAL			= 22,
+
+	GUNYAH_ERROR_DENIED			= 30,
+	GUNYAH_ERROR_BUSY			= 31,
+	GUNYAH_ERROR_IDLE			= 32,
+
+	GUNYAH_ERROR_IRQ_BOUND			= 40,
+	GUNYAH_ERROR_IRQ_UNBOUND		= 41,
+
+	GUNYAH_ERROR_CSPACE_CAP_NULL		= 50,
+	GUNYAH_ERROR_CSPACE_CAP_REVOKED		= 51,
+	GUNYAH_ERROR_CSPACE_WRONG_OBJ_TYPE	= 52,
+	GUNYAH_ERROR_CSPACE_INSUF_RIGHTS	= 53,
+	GUNYAH_ERROR_CSPACE_FULL		= 54,
+
+	GUNYAH_ERROR_MSGQUEUE_EMPTY		= 60,
+	GUNYAH_ERROR_MSGQUEUE_FULL		= 61,
+	/* clang-format on */
+};
+
+/**
+ * gunyah_error_remap() - Remap Gunyah hypervisor errors into a Linux error code
+ * @gunyah_error: Gunyah hypercall return value
+ */
+static inline int gunyah_error_remap(enum gunyah_error gunyah_error)
+{
+	switch (gunyah_error) {
+	case GUNYAH_ERROR_OK:
+		return 0;
+	case GUNYAH_ERROR_NOMEM:
+		return -ENOMEM;
+	case GUNYAH_ERROR_DENIED:
+	case GUNYAH_ERROR_CSPACE_CAP_NULL:
+	case GUNYAH_ERROR_CSPACE_CAP_REVOKED:
+	case GUNYAH_ERROR_CSPACE_WRONG_OBJ_TYPE:
+	case GUNYAH_ERROR_CSPACE_INSUF_RIGHTS:
+		return -EACCES;
+	case GUNYAH_ERROR_CSPACE_FULL:
+	case GUNYAH_ERROR_BUSY:
+	case GUNYAH_ERROR_IDLE:
+		return -EBUSY;
+	case GUNYAH_ERROR_IRQ_BOUND:
+	case GUNYAH_ERROR_IRQ_UNBOUND:
+	case GUNYAH_ERROR_MSGQUEUE_FULL:
+	case GUNYAH_ERROR_MSGQUEUE_EMPTY:
+		return -EIO;
+	case GUNYAH_ERROR_UNIMPLEMENTED:
+		return -EOPNOTSUPP;
+	case GUNYAH_ERROR_RETRY:
+		return -EAGAIN;
+	default:
+		return -EINVAL;
+	}
+}
+
+#endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:23 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:23 -0800
Subject: [PATCH v17 00/35] Drivers for Gunyah hypervisor
Message-ID: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>

Gunyah is a Type-1 hypervisor independent of any high-level OS kernel,
and runs in a higher CPU privilege level. It does not depend on any
lower-privileged OS kernel/code for its core functionality. This
increases its security and can support a much smaller trusted computing
base than a Type-2 hypervisor. Gunyah is designed for isolated virtual
machine use cases and to support launching trusted+isolated virtual
machines from a relatively less trusted host virtual machine.

Gunyah is an open source hypervisor. The source repo is available at
https://github.com/quic/gunyah-hypervisor.

The diagram below shows the architecture for AArch64.

::

         VM A                    VM B
     +-----+ +-----+  | +-----+ +-----+ +-----+
     |     | |     |  | |     | |     | |     |
 EL0 | APP | | APP |  | | APP | | APP | | APP |
     |     | |     |  | |     | |     | |     |
     +-----+ +-----+  | +-----+ +-----+ +-----+
 ---------------------|-------------------------
     +--------------+ | +----------------------+
     |              | | |                      |
 EL1 | Linux Kernel | | |Linux kernel/Other OS |   ...
     |              | | |                      |
     +--------------+ | +----------------------+
 --------hvc/smc------|------hvc/smc------------

     +----------------------------------------+
     |                                        |
 EL2 |            Gunyah Hypervisor           |
     |                                        |
     +----------------------------------------+

Gunyah provides these following features.

- Threads and Scheduling: The scheduler schedules virtual CPUs (VCPUs)
  on physical CPUs and enables time-sharing of the CPUs.
- Memory Management: Gunyah tracks memory ownership and use of all
  memory under its control. It provides low level dynamic memory
  management APIs on top of which higher level donation, lending and sharing
  is built. Gunyah provides strong VM memory isolation for trusted VMs.
- Interrupt Virtualization: Interrupts are managed by the hypervisor
  and are routed directly to the assigned VM.
- Inter-VM Communication: There are several different mechanisms
  provided for communicating between VMs.
- Device Virtualization: Para-virtualization of devices is supported
  using inter-VM communication and virtio primitives. Low level architecture
  features and devices such as cpu timers, interrupt controllers are supported
  with hardware virtualization and emulation where required.
- Resource Manager: Gunyah supports a "root" VM that initially owns all
  VM memory and IO resources. The Gunyah Resource Manager is the default
  bundled root VM and provides high-level services including dynamic VM
  management and secure memory donation, lending and sharing.

This series adds the basic framework for detecting that Linux is running
under Gunyah as a virtual machine, communication with the Gunyah
Resource Manager, and a sample virtual machine manager capable of
launching virtual machines.

Changes in v17:
 - Replace RM's irq_chip with irq_create_fwspec_mapping
 - Unmap lent memory from kernel logical map
 - Small optimization to unlock folio earlier to allow vCPUs racing for
   the same folio to run sooner
 - Add missed "safe to lend" checks for a folio when constructing mem
   parcel

Changes in v16:
https://lore.kernel.org/r/20240109-gunyah-v16-0-634904bf4ce9 at quicinc.com
 - Fleshed out memory reclaim while VM is running
 - Documentation and comments

Changes in v15:
https://lore.kernel.org/r/20231215-gunyah-v15-0-192a5d872a30 at quicinc.com
 - First implementation of virtual machines backed by guestmemfd and
using demand paging to provide memory instead of all up front.
 - Use message queue hypercalls directly instead of traversing through
mailbox framework.

Changes in v14: https://lore.kernel.org/all/20230613172054.3959700-1-quic_eberman at quicinc.com/
 - Coding/cosmetic tweaks suggested by Alex
 - Mark IRQs as wake-up capable

Changes in v13:
https://lore.kernel.org/all/20230509204801.2824351-1-quic_eberman at quicinc.com/
 - Tweaks to message queue driver to address race condition between IRQ
and mailbox registration
 - Allow removal of VM functions by function-specific comparison --
specifically to allow
   removing irqfd by label only and not requiring original FD to be
provided.

Changes in v12:
https://lore.kernel.org/all/20230424231558.70911-1-quic_eberman at quicinc.com/
 - Stylistic/cosmetic tweaks suggested by Alex
 - Remove patch "virt: gunyah: Identify hypervisor version" and squash
the
   check that we're running under a reasonable Gunyah hypervisor into RM
driver
 - Refactor platform hooks into a separate module per suggestion from
Srini
 - GFP_KERNEL_ACCOUNT and account_locked_vm() for page pinning
 - enum-ify related constants

Changes in v11:
https://lore.kernel.org/all/20230304010632.2127470-1-quic_eberman at quicinc.com/
 - Rename struct gh_vm_dtb_config:gpa -> guest_phys_addr & overflow
checks for this
 - More docstrings throughout
 - Make resp_buf and resp_buf_size optional
 - Replace deprecated idr with xarray
 - Refconting on misc device instead of RM's platform device
 - Renaming variables, structs, etc. from gunyah_ -> gh_
 - Drop removal of user mem regions
 - Drop mem_lend functionality; to converge with restricted_memfd later

Changes in v10:
https://lore.kernel.org/all/20230214211229.3239350-1-quic_eberman at quicinc.com/
 - Fix bisectability (end result of series is same, --fixups applied to
wrong commits)
 - Convert GH_ERROR_* and GH_RM_ERROR_* to enums
 - Correct race condition between allocating/freeing user memory
 - Replace offsetof with struct_size
 - Series-wide renaming of functions to be more consistent
 - VM shutdown & restart support added in vCPU and VM Manager patches
 - Convert VM function name (string) to type (number)
 - Convert VM function argument to value (which could be a pointer) to
remove memory wastage for arguments
 - Remove defensive checks of hypervisor correctness
 - Clean ups to ioeventfd as suggested by Srivatsa

Changes in v9:
https://lore.kernel.org/all/20230120224627.4053418-1-quic_eberman at quicinc.com/
 - Refactor Gunyah API flags to be exposed as feature flags at kernel
level
 - Move mbox client cleanup into gunyah_msgq_remove()
 - Simplify gh_rm_call return value and response payload
 - Missing clean-up/error handling/little endian fixes as suggested by
Srivatsa and Alex in v8 series

Changes in v8:
https://lore.kernel.org/all/20221219225850.2397345-1-quic_eberman at quicinc.com/
 - Treat VM manager as a library of RM
 - Add patches 21-28 as RFC to support proxy-scheduled vCPUs and
necessary bits to support virtio
   from Gunyah userspace

Changes in v7:
https://lore.kernel.org/all/20221121140009.2353512-1-quic_eberman at quicinc.com/
 - Refactor to remove gunyah RM bus
 - Refactor allow multiple RM device instances
 - Bump UAPI to start at 0x0
 - Refactor QCOM SCM's platform hooks to allow
CONFIG_QCOM_SCM=Y/CONFIG_GUNYAH=M combinations

Changes in v6:
https://lore.kernel.org/all/20221026185846.3983888-1-quic_eberman at quicinc.com/
 - *Replace gunyah-console with gunyah VM Manager*
 - Move include/asm-generic/gunyah.h into include/linux/gunyah.h
 - s/gunyah_msgq/gh_msgq/
 - Minor tweaks and documentation tidying based on comments from Jiri,
Greg, Arnd, Dmitry, and Bagas.

Changes in v5
https://lore.kernel.org/all/20221011000840.289033-1-quic_eberman at quicinc.com/
 - Dropped sysfs nodes
 - Switch from aux bus to Gunyah RM bus for the subdevices
 - Cleaning up RM console

Changes in v4:
https://lore.kernel.org/all/20220928195633.2348848-1-quic_eberman at quicinc.com/
 - Tidied up documentation throughout based on questions/feedback received
 - Switched message queue implementation to use mailboxes
 - Renamed "gunyah_device" as "gunyah_resource"

Changes in v3:
https://lore.kernel.org/all/20220811214107.1074343-1-quic_eberman at quicinc.com/
 - /Maintained/Supported/ in MAINTAINERS
 - Tidied up documentation throughout based on questions/feedback received
 - Moved hypercalls into arch/arm64/gunyah/; following hyper-v's implementation
 - Drop opaque typedefs
 - Move sysfs nodes under /sys/hypervisor/gunyah/
 - Moved Gunyah console driver to drivers/tty/
 - Reworked gh_device design to drop the Gunyah bus.

Changes in v2: https://lore.kernel.org/all/20220801211240.597859-1-quic_eberman at quicinc.com/
 - DT bindings clean up
 - Switch hypercalls to follow SMCCC 

v1: https://lore.kernel.org/all/20220223233729.1571114-1-quic_eberman at quicinc.com/

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
Elliot Berman (35):
      docs: gunyah: Introduce Gunyah Hypervisor
      dt-bindings: Add binding for gunyah hypervisor
      gunyah: Common types and error codes for Gunyah hypercalls
      virt: gunyah: Add hypercalls to identify Gunyah
      virt: gunyah: Add hypervisor driver
      virt: gunyah: msgq: Add hypercalls to send and receive messages
      gunyah: rsc_mgr: Add resource manager RPC core
      gunyah: vm_mgr: Introduce basic VM Manager
      gunyah: rsc_mgr: Add VM lifecycle RPC
      gunyah: vm_mgr: Add VM start/stop
      virt: gunyah: Translate gh_rm_hyp_resource into gunyah_resource
      virt: gunyah: Add resource tickets
      gunyah: vm_mgr: Add framework for VM Functions
      virt: gunyah: Add hypercalls for running a vCPU
      virt: gunyah: Add proxy-scheduled vCPUs
      gunyah: Add hypercalls for demand paging
      gunyah: rsc_mgr: Add memory parcel RPC
      mm/interval_tree: Export iter_first/iter_next
      arch/mm: Export direct {un,}map functions
      virt: gunyah: Add interfaces to map memory into guest address space
      gunyah: rsc_mgr: Add platform ops on mem_lend/mem_reclaim
      virt: gunyah: Add Qualcomm Gunyah platform ops
      virt: gunyah: Implement guestmemfd
      virt: gunyah: Add ioctl to bind guestmem to VMs
      virt: gunyah: guestmem: Initialize RM mem parcels from guestmem
      virt: gunyah: Share guest VM dtb configuration to Gunyah
      gunyah: rsc_mgr: Add RPC to enable demand paging
      virt: gunyah: Enable demand paging
      gunyah: rsc_mgr: Add RPC to set VM boot context
      virt: gunyah: Allow userspace to initialize context of primary vCPU
      virt: gunyah: Add hypercalls for sending doorbell
      virt: gunyah: Add irqfd interface
      virt: gunyah: Add IO handlers
      virt: gunyah: Add ioeventfd
      MAINTAINERS: Add Gunyah hypervisor drivers section

 .../bindings/firmware/gunyah-hypervisor.yaml       |  82 ++
 Documentation/userspace-api/ioctl/ioctl-number.rst |   1 +
 Documentation/virt/gunyah/index.rst                | 135 +++
 Documentation/virt/gunyah/message-queue.rst        |  68 ++
 Documentation/virt/index.rst                       |   1 +
 MAINTAINERS                                        |  12 +
 arch/arm64/Kbuild                                  |   1 +
 arch/arm64/gunyah/Makefile                         |   3 +
 arch/arm64/gunyah/gunyah_hypercall.c               | 279 ++++++
 arch/arm64/include/asm/gunyah.h                    |  57 ++
 arch/arm64/mm/pageattr.c                           |   3 +
 drivers/virt/Kconfig                               |   2 +
 drivers/virt/Makefile                              |   1 +
 drivers/virt/gunyah/Kconfig                        |  47 +
 drivers/virt/gunyah/Makefile                       |   9 +
 drivers/virt/gunyah/guest_memfd.c                  | 987 ++++++++++++++++++++
 drivers/virt/gunyah/gunyah.c                       |  52 ++
 drivers/virt/gunyah/gunyah_ioeventfd.c             | 139 +++
 drivers/virt/gunyah/gunyah_irqfd.c                 | 187 ++++
 drivers/virt/gunyah/gunyah_platform_hooks.c        | 117 +++
 drivers/virt/gunyah/gunyah_qcom.c                  | 220 +++++
 drivers/virt/gunyah/gunyah_vcpu.c                  | 590 ++++++++++++
 drivers/virt/gunyah/rsc_mgr.c                      | 836 +++++++++++++++++
 drivers/virt/gunyah/rsc_mgr.h                      | 144 +++
 drivers/virt/gunyah/rsc_mgr_rpc.c                  | 602 +++++++++++++
 drivers/virt/gunyah/vm_mgr.c                       | 993 +++++++++++++++++++++
 drivers/virt/gunyah/vm_mgr.h                       | 215 +++++
 drivers/virt/gunyah/vm_mgr_mem.c                   | 356 ++++++++
 include/linux/gunyah.h                             | 483 ++++++++++
 include/uapi/linux/gunyah.h                        | 378 ++++++++
 mm/interval_tree.c                                 |   3 +
 31 files changed, 7003 insertions(+)
---
base-commit: ffd2cb6b718e189e7e2d5d0c19c25611f92e061a
change-id: 20231208-gunyah-952aca7668e0

Best regards,
-- 
Elliot Berman <quic_eberman at quicinc.com>



From quic_eberman at quicinc.com  Thu Feb 22 15:16:37 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:37 -0800
Subject: [PATCH v17 14/35] virt: gunyah: Add hypercalls for running a vCPU
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-14-1e9da6763d38@quicinc.com>

Add hypercall to donate CPU time to a vCPU.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 arch/arm64/gunyah/gunyah_hypercall.c | 37 ++++++++++++++++++++++++++++++++++++
 include/linux/gunyah.h               | 35 ++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/arch/arm64/gunyah/gunyah_hypercall.c b/arch/arm64/gunyah/gunyah_hypercall.c
index 1302e128be6e9..fee21df42c176 100644
--- a/arch/arm64/gunyah/gunyah_hypercall.c
+++ b/arch/arm64/gunyah/gunyah_hypercall.c
@@ -39,6 +39,7 @@ EXPORT_SYMBOL_GPL(arch_is_gunyah_guest);
 #define GUNYAH_HYPERCALL_HYP_IDENTIFY		GUNYAH_HYPERCALL(0x8000)
 #define GUNYAH_HYPERCALL_MSGQ_SEND		GUNYAH_HYPERCALL(0x801B)
 #define GUNYAH_HYPERCALL_MSGQ_RECV		GUNYAH_HYPERCALL(0x801C)
+#define GUNYAH_HYPERCALL_VCPU_RUN		GUNYAH_HYPERCALL(0x8065)
 /* clang-format on */
 
 /**
@@ -113,5 +114,41 @@ enum gunyah_error gunyah_hypercall_msgq_recv(u64 capid, void *buff, size_t size,
 }
 EXPORT_SYMBOL_GPL(gunyah_hypercall_msgq_recv);
 
+/**
+ * gunyah_hypercall_vcpu_run() - Donate CPU time to a vcpu
+ * @capid: capability ID of the vCPU to run
+ * @resume_data: Array of 3 state-specific resume data
+ * @resp: Filled reason why vCPU exited when return value is GUNYAH_ERROR_OK
+ *
+ * See also:
+ * https://github.com/quic/gunyah-hypervisor/blob/develop/docs/api/gunyah_api.md#run-a-proxy-scheduled-vcpu-thread
+ */
+enum gunyah_error
+gunyah_hypercall_vcpu_run(u64 capid, unsigned long *resume_data,
+			  struct gunyah_hypercall_vcpu_run_resp *resp)
+{
+	struct arm_smccc_1_2_regs args = {
+		.a0 = GUNYAH_HYPERCALL_VCPU_RUN,
+		.a1 = capid,
+		.a2 = resume_data[0],
+		.a3 = resume_data[1],
+		.a4 = resume_data[2],
+		/* C language says this will be implictly zero. Gunyah requires 0, so be explicit */
+		.a5 = 0,
+	};
+	struct arm_smccc_1_2_regs res;
+
+	arm_smccc_1_2_hvc(&args, &res);
+	if (res.a0 == GUNYAH_ERROR_OK) {
+		resp->sized_state = res.a1;
+		resp->state_data[0] = res.a2;
+		resp->state_data[1] = res.a3;
+		resp->state_data[2] = res.a4;
+	}
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_vcpu_run);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Gunyah Hypervisor Hypercalls");
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index 18ecebf41a3ff..6c24544f38dc9 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -273,4 +273,39 @@ enum gunyah_error gunyah_hypercall_msgq_send(u64 capid, size_t size, void *buff,
 enum gunyah_error gunyah_hypercall_msgq_recv(u64 capid, void *buff, size_t size,
 					     size_t *recv_size, bool *ready);
 
+struct gunyah_hypercall_vcpu_run_resp {
+	union {
+		enum {
+			/* clang-format off */
+			/* VCPU is ready to run */
+			GUNYAH_VCPU_STATE_READY			= 0,
+			/* VCPU is sleeping until an interrupt arrives */
+			GUNYAH_VCPU_STATE_EXPECTS_WAKEUP	= 1,
+			/* VCPU is powered off */
+			GUNYAH_VCPU_STATE_POWERED_OFF		= 2,
+			/* VCPU is blocked in EL2 for unspecified reason */
+			GUNYAH_VCPU_STATE_BLOCKED		= 3,
+			/* VCPU has returned for MMIO READ */
+			GUNYAH_VCPU_ADDRSPACE_VMMIO_READ	= 4,
+			/* VCPU has returned for MMIO WRITE */
+			GUNYAH_VCPU_ADDRSPACE_VMMIO_WRITE	= 5,
+			/* VCPU blocked on fault where we can demand page */
+			GUNYAH_VCPU_ADDRSPACE_PAGE_FAULT	= 7,
+			/* clang-format on */
+		} state;
+		u64 sized_state;
+	};
+	u64 state_data[3];
+};
+
+enum {
+	GUNYAH_ADDRSPACE_VMMIO_ACTION_EMULATE = 0,
+	GUNYAH_ADDRSPACE_VMMIO_ACTION_RETRY = 1,
+	GUNYAH_ADDRSPACE_VMMIO_ACTION_FAULT = 2,
+};
+
+enum gunyah_error
+gunyah_hypercall_vcpu_run(u64 capid, unsigned long *resume_data,
+			  struct gunyah_hypercall_vcpu_run_resp *resp);
+
 #endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:55 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:55 -0800
Subject: [PATCH v17 32/35] virt: gunyah: Add irqfd interface
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-32-1e9da6763d38@quicinc.com>

Enable support for creating irqfds which can raise an interrupt on a
Gunyah virtual machine. irqfds are exposed to userspace as a Gunyah VM
function with the name "irqfd". If the VM devicetree is not configured
to create a doorbell with the corresponding label, userspace will still
be able to assert the eventfd but no interrupt will be raised on the
guest.

Acked-by: Alex Elder <elder at linaro.org>
Co-developed-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/Kconfig        |   9 ++
 drivers/virt/gunyah/Makefile       |   1 +
 drivers/virt/gunyah/gunyah_irqfd.c | 187 +++++++++++++++++++++++++++++++++++++
 include/uapi/linux/gunyah.h        |  35 +++++++
 4 files changed, 232 insertions(+)

diff --git a/drivers/virt/gunyah/Kconfig b/drivers/virt/gunyah/Kconfig
index fe2823dc48bac..1685b75fb77a0 100644
--- a/drivers/virt/gunyah/Kconfig
+++ b/drivers/virt/gunyah/Kconfig
@@ -27,3 +27,12 @@ config GUNYAH_QCOM_PLATFORM
 	  extra platform-specific support.
 
 	  Say Y/M here to use Gunyah on Qualcomm platforms.
+
+config GUNYAH_IRQFD
+	tristate "Gunyah irqfd interface"
+	depends on GUNYAH
+	help
+	  Enable kernel support for creating irqfds which can raise an interrupt
+	  on Gunyah virtual machine.
+
+	  Say Y/M here if unsure and you want to support Gunyah VMMs.
diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
index c4505fce177dd..b41b02792921c 100644
--- a/drivers/virt/gunyah/Makefile
+++ b/drivers/virt/gunyah/Makefile
@@ -5,3 +5,4 @@ gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o vm_mgr_mem.o guest_memfd.o
 obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o gunyah_vcpu.o
 obj-$(CONFIG_GUNYAH_PLATFORM_HOOKS) += gunyah_platform_hooks.o
 obj-$(CONFIG_GUNYAH_QCOM_PLATFORM) += gunyah_qcom.o
+obj-$(CONFIG_GUNYAH_IRQFD) += gunyah_irqfd.o
diff --git a/drivers/virt/gunyah/gunyah_irqfd.c b/drivers/virt/gunyah/gunyah_irqfd.c
new file mode 100644
index 0000000000000..951da6e8d321e
--- /dev/null
+++ b/drivers/virt/gunyah/gunyah_irqfd.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/eventfd.h>
+#include <linux/device/driver.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/gunyah.h>
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <linux/printk.h>
+
+#include <uapi/linux/gunyah.h>
+
+struct gunyah_irqfd {
+	struct gunyah_resource *ghrsc;
+	struct gunyah_vm_resource_ticket ticket;
+	struct gunyah_vm_function_instance *f;
+
+	bool level;
+
+	struct eventfd_ctx *ctx;
+	wait_queue_entry_t wait;
+	poll_table pt;
+};
+
+static int irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode, int sync,
+			void *key)
+{
+	struct gunyah_irqfd *irqfd =
+		container_of(wait, struct gunyah_irqfd, wait);
+	__poll_t flags = key_to_poll(key);
+	int ret = 0;
+
+	if (flags & EPOLLIN) {
+		if (irqfd->ghrsc) {
+			ret = gunyah_hypercall_bell_send(irqfd->ghrsc->capid, 1,
+							 NULL);
+			if (ret)
+				pr_err_ratelimited(
+					"Failed to inject interrupt %d: %d\n",
+					irqfd->ticket.label, ret);
+		} else
+			pr_err_ratelimited(
+				"Premature injection of interrupt\n");
+	}
+
+	return 0;
+}
+
+static void irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
+				    poll_table *pt)
+{
+	struct gunyah_irqfd *irq_ctx =
+		container_of(pt, struct gunyah_irqfd, pt);
+
+	add_wait_queue(wqh, &irq_ctx->wait);
+}
+
+static bool gunyah_irqfd_populate(struct gunyah_vm_resource_ticket *ticket,
+				  struct gunyah_resource *ghrsc)
+{
+	struct gunyah_irqfd *irqfd =
+		container_of(ticket, struct gunyah_irqfd, ticket);
+	int ret;
+
+	if (irqfd->ghrsc) {
+		pr_warn("irqfd%d already got a Gunyah resource. Check if multiple resources with same label were configured.\n",
+			irqfd->ticket.label);
+		return false;
+	}
+
+	irqfd->ghrsc = ghrsc;
+	if (irqfd->level) {
+		/* Configure the bell to trigger when bit 0 is asserted (see
+		 * irq_wakeup) and for bell to automatically clear bit 0 once
+		 * received by the VM (ack_mask).  need to make sure bit 0 is cleared right away,
+		 * otherwise the line will never be deasserted. Emulating edge
+		 * trigger interrupt does not need to set either mask
+		 * because irq is listed only once per gunyah_hypercall_bell_send
+		 */
+		ret = gunyah_hypercall_bell_set_mask(irqfd->ghrsc->capid, 1, 1);
+		if (ret)
+			pr_warn("irq %d couldn't be set as level triggered. Might cause IRQ storm if asserted\n",
+				irqfd->ticket.label);
+	}
+
+	return true;
+}
+
+static void gunyah_irqfd_unpopulate(struct gunyah_vm_resource_ticket *ticket,
+				    struct gunyah_resource *ghrsc)
+{
+}
+
+static long gunyah_irqfd_bind(struct gunyah_vm_function_instance *f)
+{
+	struct gunyah_fn_irqfd_arg *args = f->argp;
+	struct gunyah_irqfd *irqfd;
+	__poll_t events;
+	struct fd fd;
+	long r;
+
+	if (f->arg_size != sizeof(*args))
+		return -EINVAL;
+
+	/* All other flag bits are reserved for future use */
+	if (args->flags & ~GUNYAH_IRQFD_FLAGS_LEVEL)
+		return -EINVAL;
+
+	irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
+	if (!irqfd)
+		return -ENOMEM;
+
+	irqfd->f = f;
+	f->data = irqfd;
+
+	fd = fdget(args->fd);
+	if (!fd.file) {
+		kfree(irqfd);
+		return -EBADF;
+	}
+
+	irqfd->ctx = eventfd_ctx_fileget(fd.file);
+	if (IS_ERR(irqfd->ctx)) {
+		r = PTR_ERR(irqfd->ctx);
+		goto err_fdput;
+	}
+
+	if (args->flags & GUNYAH_IRQFD_FLAGS_LEVEL)
+		irqfd->level = true;
+
+	init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup);
+	init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc);
+
+	irqfd->ticket.resource_type = GUNYAH_RESOURCE_TYPE_BELL_TX;
+	irqfd->ticket.label = args->label;
+	irqfd->ticket.owner = THIS_MODULE;
+	irqfd->ticket.populate = gunyah_irqfd_populate;
+	irqfd->ticket.unpopulate = gunyah_irqfd_unpopulate;
+
+	r = gunyah_vm_add_resource_ticket(f->ghvm, &irqfd->ticket);
+	if (r)
+		goto err_ctx;
+
+	events = vfs_poll(fd.file, &irqfd->pt);
+	if (events & EPOLLIN)
+		pr_warn("Premature injection of interrupt\n");
+	fdput(fd);
+
+	return 0;
+err_ctx:
+	eventfd_ctx_put(irqfd->ctx);
+err_fdput:
+	fdput(fd);
+	kfree(irqfd);
+	return r;
+}
+
+static void gunyah_irqfd_unbind(struct gunyah_vm_function_instance *f)
+{
+	struct gunyah_irqfd *irqfd = f->data;
+	u64 cnt;
+
+	eventfd_ctx_remove_wait_queue(irqfd->ctx, &irqfd->wait, &cnt);
+	gunyah_vm_remove_resource_ticket(irqfd->f->ghvm, &irqfd->ticket);
+	eventfd_ctx_put(irqfd->ctx);
+	kfree(irqfd);
+}
+
+static bool gunyah_irqfd_compare(const struct gunyah_vm_function_instance *f,
+				 const void *arg, size_t size)
+{
+	const struct gunyah_fn_irqfd_arg *instance = f->argp, *other = arg;
+
+	if (sizeof(*other) != size)
+		return false;
+
+	return instance->label == other->label;
+}
+
+DECLARE_GUNYAH_VM_FUNCTION_INIT(irqfd, GUNYAH_FN_IRQFD, 2, gunyah_irqfd_bind,
+				gunyah_irqfd_unbind, gunyah_irqfd_compare);
+MODULE_DESCRIPTION("Gunyah irqfd VM Function");
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h
index 574116f544722..cb7b0bb9bef38 100644
--- a/include/uapi/linux/gunyah.h
+++ b/include/uapi/linux/gunyah.h
@@ -63,9 +63,12 @@ struct gunyah_vm_dtb_config {
  * @GUNYAH_FN_VCPU: create a vCPU instance to control a vCPU
  *              &struct gunyah_fn_desc.arg is a pointer to &struct gunyah_fn_vcpu_arg
  *              Return: file descriptor to manipulate the vcpu.
+ * @GUNYAH_FN_IRQFD: register eventfd to assert a Gunyah doorbell
+ *               &struct gunyah_fn_desc.arg is a pointer to &struct gunyah_fn_irqfd_arg
  */
 enum gunyah_fn_type {
 	GUNYAH_FN_VCPU = 1,
+	GUNYAH_FN_IRQFD,
 };
 
 #define GUNYAH_FN_MAX_ARG_SIZE		256
@@ -85,6 +88,38 @@ struct gunyah_fn_vcpu_arg {
 	__u32 id;
 };
 
+/**
+ * enum gunyah_irqfd_flags - flags for use in gunyah_fn_irqfd_arg
+ * @GUNYAH_IRQFD_FLAGS_LEVEL: make the interrupt operate like a level triggered
+ *                        interrupt on guest side. Triggering IRQFD before
+ *                        guest handles the interrupt causes interrupt to
+ *                        stay asserted.
+ */
+enum gunyah_irqfd_flags {
+	GUNYAH_IRQFD_FLAGS_LEVEL		= 1UL << 0,
+};
+
+/**
+ * struct gunyah_fn_irqfd_arg - Arguments to create an irqfd function.
+ *
+ * Create this function with &GUNYAH_VM_ADD_FUNCTION using type &GUNYAH_FN_IRQFD.
+ *
+ * Allows setting an eventfd to directly trigger a guest interrupt.
+ * irqfd.fd specifies the file descriptor to use as the eventfd.
+ * irqfd.label corresponds to the doorbell label used in the guest VM's devicetree.
+ *
+ * @fd: an eventfd which when written to will raise a doorbell
+ * @label: Label of the doorbell created on the guest VM
+ * @flags: see &enum gunyah_irqfd_flags
+ * @padding: padding bytes
+ */
+struct gunyah_fn_irqfd_arg {
+	__u32 fd;
+	__u32 label;
+	__u32 flags;
+	__u32 padding;
+};
+
 /**
  * struct gunyah_fn_desc - Arguments to create a VM function
  * @type: Type of the function. See &enum gunyah_fn_type.

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:45 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:45 -0800
Subject: [PATCH v17 22/35] virt: gunyah: Add Qualcomm Gunyah platform ops
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-22-1e9da6763d38@quicinc.com>

Qualcomm platforms have a firmware entity which performs access control
to physical pages. Dynamically started Gunyah virtual machines use the
QCOM_SCM_RM_MANAGED_VMID for access. Linux thus needs to assign access
to the memory used by guest VMs. Gunyah doesn't do this operation for us
since it is the current VM (typically VMID_HLOS) delegating the access
and not Gunyah itself. Use the Gunyah platform ops to achieve this so
that only Qualcomm platforms attempt to make the needed SCM calls.

Reviewed-by: Alex Elder <elder at linaro.org>
Co-developed-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/Kconfig       |  13 +++
 drivers/virt/gunyah/Makefile      |   1 +
 drivers/virt/gunyah/gunyah_qcom.c | 220 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 234 insertions(+)

diff --git a/drivers/virt/gunyah/Kconfig b/drivers/virt/gunyah/Kconfig
index 23ba523d25dc8..fe2823dc48bac 100644
--- a/drivers/virt/gunyah/Kconfig
+++ b/drivers/virt/gunyah/Kconfig
@@ -4,6 +4,7 @@ config GUNYAH
 	tristate "Gunyah Virtualization drivers"
 	depends on ARM64
 	select GUNYAH_PLATFORM_HOOKS
+	imply GUNYAH_QCOM_PLATFORM if ARCH_QCOM
 	help
 	  The Gunyah drivers are the helper interfaces that run in a guest VM
 	  such as basic inter-VM IPC and signaling mechanisms, and higher level
@@ -14,3 +15,15 @@ config GUNYAH
 
 config GUNYAH_PLATFORM_HOOKS
 	tristate
+
+config GUNYAH_QCOM_PLATFORM
+	tristate "Support for Gunyah on Qualcomm platforms"
+	depends on GUNYAH
+	select GUNYAH_PLATFORM_HOOKS
+	select QCOM_SCM
+	help
+	  Enable support for interacting with Gunyah on Qualcomm
+	  platforms. Interaction with Qualcomm firmware requires
+	  extra platform-specific support.
+
+	  Say Y/M here to use Gunyah on Qualcomm platforms.
diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
index ffcde0e0ccfa9..a6c6f29b887a6 100644
--- a/drivers/virt/gunyah/Makefile
+++ b/drivers/virt/gunyah/Makefile
@@ -4,3 +4,4 @@ gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o vm_mgr_mem.o
 
 obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o gunyah_vcpu.o
 obj-$(CONFIG_GUNYAH_PLATFORM_HOOKS) += gunyah_platform_hooks.o
+obj-$(CONFIG_GUNYAH_QCOM_PLATFORM) += gunyah_qcom.o
diff --git a/drivers/virt/gunyah/gunyah_qcom.c b/drivers/virt/gunyah/gunyah_qcom.c
new file mode 100644
index 0000000000000..f2342d51a0184
--- /dev/null
+++ b/drivers/virt/gunyah/gunyah_qcom.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/gunyah.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/types.h>
+#include <linux/uuid.h>
+
+#define QCOM_SCM_RM_MANAGED_VMID 0x3A
+#define QCOM_SCM_MAX_MANAGED_VMID 0x3F
+
+static int
+qcom_scm_gunyah_rm_pre_mem_share(struct gunyah_rm *rm,
+				 struct gunyah_rm_mem_parcel *mem_parcel)
+{
+	struct qcom_scm_vmperm *new_perms __free(kfree) = NULL;
+	u64 src, src_cpy;
+	int ret = 0, i, n;
+	u16 vmid;
+
+	new_perms = kcalloc(mem_parcel->n_acl_entries, sizeof(*new_perms),
+			    GFP_KERNEL);
+	if (!new_perms)
+		return -ENOMEM;
+
+	for (n = 0; n < mem_parcel->n_acl_entries; n++) {
+		vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid);
+		if (vmid <= QCOM_SCM_MAX_MANAGED_VMID)
+			new_perms[n].vmid = vmid;
+		else
+			new_perms[n].vmid = QCOM_SCM_RM_MANAGED_VMID;
+		if (mem_parcel->acl_entries[n].perms & GUNYAH_RM_ACL_X)
+			new_perms[n].perm |= QCOM_SCM_PERM_EXEC;
+		if (mem_parcel->acl_entries[n].perms & GUNYAH_RM_ACL_W)
+			new_perms[n].perm |= QCOM_SCM_PERM_WRITE;
+		if (mem_parcel->acl_entries[n].perms & GUNYAH_RM_ACL_R)
+			new_perms[n].perm |= QCOM_SCM_PERM_READ;
+	}
+
+	src = BIT_ULL(QCOM_SCM_VMID_HLOS);
+
+	for (i = 0; i < mem_parcel->n_mem_entries; i++) {
+		src_cpy = src;
+		ret = qcom_scm_assign_mem(
+			le64_to_cpu(mem_parcel->mem_entries[i].phys_addr),
+			le64_to_cpu(mem_parcel->mem_entries[i].size), &src_cpy,
+			new_perms, mem_parcel->n_acl_entries);
+		if (ret)
+			break;
+	}
+
+	/* Did it work ok? */
+	if (!ret)
+		return 0;
+
+	src = 0;
+	for (n = 0; n < mem_parcel->n_acl_entries; n++) {
+		vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid);
+		if (vmid <= QCOM_SCM_MAX_MANAGED_VMID)
+			src |= BIT_ULL(vmid);
+		else
+			src |= BIT_ULL(QCOM_SCM_RM_MANAGED_VMID);
+	}
+
+	new_perms[0].vmid = QCOM_SCM_VMID_HLOS;
+	new_perms[0].perm = QCOM_SCM_PERM_EXEC | QCOM_SCM_PERM_WRITE |
+			    QCOM_SCM_PERM_READ;
+
+	for (i--; i >= 0; i--) {
+		src_cpy = src;
+		WARN_ON_ONCE(qcom_scm_assign_mem(
+			le64_to_cpu(mem_parcel->mem_entries[i].phys_addr),
+			le64_to_cpu(mem_parcel->mem_entries[i].size), &src_cpy,
+			new_perms, 1));
+	}
+
+	return ret;
+}
+
+static int
+qcom_scm_gunyah_rm_post_mem_reclaim(struct gunyah_rm *rm,
+				    struct gunyah_rm_mem_parcel *mem_parcel)
+{
+	struct qcom_scm_vmperm new_perms;
+	u64 src = 0, src_cpy;
+	int ret = 0, i, n;
+	u16 vmid;
+
+	new_perms.vmid = QCOM_SCM_VMID_HLOS;
+	new_perms.perm = QCOM_SCM_PERM_EXEC | QCOM_SCM_PERM_WRITE |
+			 QCOM_SCM_PERM_READ;
+
+	for (n = 0; n < mem_parcel->n_acl_entries; n++) {
+		vmid = le16_to_cpu(mem_parcel->acl_entries[n].vmid);
+		if (vmid <= QCOM_SCM_MAX_MANAGED_VMID)
+			src |= (1ull << vmid);
+		else
+			src |= (1ull << QCOM_SCM_RM_MANAGED_VMID);
+	}
+
+	for (i = 0; i < mem_parcel->n_mem_entries; i++) {
+		src_cpy = src;
+		ret = qcom_scm_assign_mem(
+			le64_to_cpu(mem_parcel->mem_entries[i].phys_addr),
+			le64_to_cpu(mem_parcel->mem_entries[i].size), &src_cpy,
+			&new_perms, 1);
+		WARN_ON_ONCE(ret);
+	}
+
+	return ret;
+}
+
+static int
+qcom_scm_gunyah_rm_pre_demand_page(struct gunyah_rm *rm, u16 vmid,
+				   enum gunyah_pagetable_access access,
+				   struct folio *folio)
+{
+	struct qcom_scm_vmperm new_perms[2];
+	unsigned int n = 1;
+	u64 src;
+
+	new_perms[0].vmid = QCOM_SCM_RM_MANAGED_VMID;
+	new_perms[0].perm = QCOM_SCM_PERM_EXEC | QCOM_SCM_PERM_WRITE |
+			    QCOM_SCM_PERM_READ;
+	if (access != GUNYAH_PAGETABLE_ACCESS_X &&
+	    access != GUNYAH_PAGETABLE_ACCESS_RX &&
+	    access != GUNYAH_PAGETABLE_ACCESS_RWX) {
+		new_perms[1].vmid = QCOM_SCM_VMID_HLOS;
+		new_perms[1].perm = QCOM_SCM_PERM_EXEC | QCOM_SCM_PERM_WRITE |
+				    QCOM_SCM_PERM_READ;
+		n++;
+	}
+
+	src = BIT_ULL(QCOM_SCM_VMID_HLOS);
+
+	return qcom_scm_assign_mem(__pfn_to_phys(folio_pfn(folio)),
+				   folio_size(folio), &src, new_perms, n);
+}
+
+static int
+qcom_scm_gunyah_rm_release_demand_page(struct gunyah_rm *rm, u16 vmid,
+				       enum gunyah_pagetable_access access,
+				       struct folio *folio)
+{
+	struct qcom_scm_vmperm new_perms;
+	u64 src;
+
+	new_perms.vmid = QCOM_SCM_VMID_HLOS;
+	new_perms.perm = QCOM_SCM_PERM_EXEC | QCOM_SCM_PERM_WRITE |
+			 QCOM_SCM_PERM_READ;
+
+	src = BIT_ULL(QCOM_SCM_RM_MANAGED_VMID);
+
+	if (access != GUNYAH_PAGETABLE_ACCESS_X &&
+	    access != GUNYAH_PAGETABLE_ACCESS_RX &&
+	    access != GUNYAH_PAGETABLE_ACCESS_RWX)
+		src |= BIT_ULL(QCOM_SCM_VMID_HLOS);
+
+	return qcom_scm_assign_mem(__pfn_to_phys(folio_pfn(folio)),
+				   folio_size(folio), &src, &new_perms, 1);
+}
+
+static struct gunyah_rm_platform_ops qcom_scm_gunyah_rm_platform_ops = {
+	.pre_mem_share = qcom_scm_gunyah_rm_pre_mem_share,
+	.post_mem_reclaim = qcom_scm_gunyah_rm_post_mem_reclaim,
+	.pre_demand_page = qcom_scm_gunyah_rm_pre_demand_page,
+	.release_demand_page = qcom_scm_gunyah_rm_release_demand_page,
+};
+
+/* {19bd54bd-0b37-571b-946f-609b54539de6} */
+static const uuid_t QCOM_EXT_UUID = UUID_INIT(0x19bd54bd, 0x0b37, 0x571b, 0x94,
+					      0x6f, 0x60, 0x9b, 0x54, 0x53,
+					      0x9d, 0xe6);
+
+#define GUNYAH_QCOM_EXT_CALL_UUID_ID                              \
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
+			   ARM_SMCCC_OWNER_VENDOR_HYP, 0x3f01)
+
+static bool gunyah_has_qcom_extensions(void)
+{
+	struct arm_smccc_res res;
+	uuid_t uuid;
+	u32 *up;
+
+	arm_smccc_1_1_smc(GUNYAH_QCOM_EXT_CALL_UUID_ID, &res);
+
+	up = (u32 *)&uuid.b[0];
+	up[0] = lower_32_bits(res.a0);
+	up[1] = lower_32_bits(res.a1);
+	up[2] = lower_32_bits(res.a2);
+	up[3] = lower_32_bits(res.a3);
+
+	return uuid_equal(&uuid, &QCOM_EXT_UUID);
+}
+
+static int __init qcom_gunyah_platform_hooks_register(void)
+{
+	if (!gunyah_has_qcom_extensions())
+		return -ENODEV;
+
+	pr_info("Enabling Gunyah hooks for Qualcomm platforms.\n");
+
+	return gunyah_rm_register_platform_ops(
+		&qcom_scm_gunyah_rm_platform_ops);
+}
+
+static void __exit qcom_gunyah_platform_hooks_unregister(void)
+{
+	gunyah_rm_unregister_platform_ops(&qcom_scm_gunyah_rm_platform_ops);
+}
+
+module_init(qcom_gunyah_platform_hooks_register);
+module_exit(qcom_gunyah_platform_hooks_unregister);
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Platform Hooks for Gunyah");
+MODULE_LICENSE("GPL");

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:54 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:54 -0800
Subject: [PATCH v17 31/35] virt: gunyah: Add hypercalls for sending
 doorbell
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-31-1e9da6763d38@quicinc.com>

Gunyah doorbells allow a virtual machine to signal another using
interrupts. Add the hypercalls needed to assert the interrupt.

Reviewed-by: Alex Elder <elder at linaro.org>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 arch/arm64/gunyah/gunyah_hypercall.c | 38 ++++++++++++++++++++++++++++++++++++
 include/linux/gunyah.h               |  5 +++++
 2 files changed, 43 insertions(+)

diff --git a/arch/arm64/gunyah/gunyah_hypercall.c b/arch/arm64/gunyah/gunyah_hypercall.c
index 38403dc28c66f..3c2672d683ae2 100644
--- a/arch/arm64/gunyah/gunyah_hypercall.c
+++ b/arch/arm64/gunyah/gunyah_hypercall.c
@@ -37,6 +37,8 @@ EXPORT_SYMBOL_GPL(arch_is_gunyah_guest);
 
 /* clang-format off */
 #define GUNYAH_HYPERCALL_HYP_IDENTIFY		GUNYAH_HYPERCALL(0x8000)
+#define GUNYAH_HYPERCALL_BELL_SEND		GUNYAH_HYPERCALL(0x8012)
+#define GUNYAH_HYPERCALL_BELL_SET_MASK		GUNYAH_HYPERCALL(0x8015)
 #define GUNYAH_HYPERCALL_MSGQ_SEND		GUNYAH_HYPERCALL(0x801B)
 #define GUNYAH_HYPERCALL_MSGQ_RECV		GUNYAH_HYPERCALL(0x801C)
 #define GUNYAH_HYPERCALL_ADDRSPACE_MAP		GUNYAH_HYPERCALL(0x802B)
@@ -64,6 +66,42 @@ void gunyah_hypercall_hyp_identify(
 }
 EXPORT_SYMBOL_GPL(gunyah_hypercall_hyp_identify);
 
+/**
+ * gunyah_hypercall_bell_send() - Assert a gunyah doorbell
+ * @capid: capability ID of the doorbell
+ * @new_flags: bits to set on the doorbell
+ * @old_flags: Filled with the bits set before the send call if return value is GUNYAH_ERROR_OK
+ */
+enum gunyah_error gunyah_hypercall_bell_send(u64 capid, u64 new_flags, u64 *old_flags)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GUNYAH_HYPERCALL_BELL_SEND, capid, new_flags, 0, &res);
+
+	if (res.a0 == GUNYAH_ERROR_OK && old_flags)
+		*old_flags = res.a1;
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_bell_send);
+
+/**
+ * gunyah_hypercall_bell_set_mask() - Set masks on a Gunyah doorbell
+ * @capid: capability ID of the doorbell
+ * @enable_mask: which bits trigger the receiver interrupt
+ * @ack_mask: which bits are automatically acknowledged when the receiver
+ *            interrupt is ack'd
+ */
+enum gunyah_error gunyah_hypercall_bell_set_mask(u64 capid, u64 enable_mask, u64 ack_mask)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GUNYAH_HYPERCALL_BELL_SET_MASK, capid, enable_mask, ack_mask, 0, &res);
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_bell_set_mask);
+
 /**
  * gunyah_hypercall_msgq_send() - Send a buffer on a message queue
  * @capid: capability ID of the message queue to add message
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index cfb80f40d4e4a..a9d58150de696 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -359,6 +359,11 @@ gunyah_api_version(const struct gunyah_hypercall_hyp_identify_resp *gunyah_api)
 void gunyah_hypercall_hyp_identify(
 	struct gunyah_hypercall_hyp_identify_resp *hyp_identity);
 
+enum gunyah_error gunyah_hypercall_bell_send(u64 capid, u64 new_flags,
+					     u64 *old_flags);
+enum gunyah_error gunyah_hypercall_bell_set_mask(u64 capid, u64 enable_mask,
+						 u64 ack_mask);
+
 /* Immediately raise RX vIRQ on receiver VM */
 #define GUNYAH_HYPERCALL_MSGQ_TX_FLAGS_PUSH BIT(0)
 

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:51 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:51 -0800
Subject: [PATCH v17 28/35] virt: gunyah: Enable demand paging
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-28-1e9da6763d38@quicinc.com>

Tell resource manager to enable demand paging and wire vCPU faults to
provide the backing folio when a guestmemfd is bound to the faulting
access.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/guest_memfd.c | 94 +++++++++++++++++++++++++++++++++++++++
 drivers/virt/gunyah/gunyah_vcpu.c | 41 +++++++++++++----
 drivers/virt/gunyah/vm_mgr.c      | 29 ++++++++++++
 drivers/virt/gunyah/vm_mgr.h      |  3 ++
 4 files changed, 159 insertions(+), 8 deletions(-)

diff --git a/drivers/virt/gunyah/guest_memfd.c b/drivers/virt/gunyah/guest_memfd.c
index 0c35ffa616d9c..797bc29a520bc 100644
--- a/drivers/virt/gunyah/guest_memfd.c
+++ b/drivers/virt/gunyah/guest_memfd.c
@@ -891,3 +891,97 @@ int gunyah_gmem_reclaim_parcel(struct gunyah_vm *ghvm,
 
 	return 0;
 }
+
+int gunyah_gmem_setup_demand_paging(struct gunyah_vm *ghvm)
+{
+	struct gunyah_rm_mem_entry *entries;
+	struct gunyah_gmem_binding *b;
+	unsigned long index = 0;
+	u32 count = 0, i;
+	int ret = 0;
+
+	down_read(&ghvm->bindings_lock);
+	mt_for_each(&ghvm->bindings, b, index, ULONG_MAX)
+		if (gunyah_guest_mem_is_lend(ghvm, b->flags))
+			count++;
+
+	if (!count)
+		goto out;
+
+	entries = kcalloc(count, sizeof(*entries), GFP_KERNEL);
+	if (!entries) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	index = i = 0;
+	mt_for_each(&ghvm->bindings, b, index, ULONG_MAX) {
+		if (!gunyah_guest_mem_is_lend(ghvm, b->flags))
+			continue;
+		entries[i].phys_addr = cpu_to_le64(gunyah_gfn_to_gpa(b->gfn));
+		entries[i].size = cpu_to_le64(b->nr << PAGE_SHIFT);
+		if (++i == count)
+			break;
+	}
+
+	ret = gunyah_rm_vm_set_demand_paging(ghvm->rm, ghvm->vmid, i, entries);
+	kfree(entries);
+out:
+	up_read(&ghvm->bindings_lock);
+	return ret;
+}
+
+int gunyah_gmem_demand_page(struct gunyah_vm *ghvm, u64 gpa, bool write)
+{
+	unsigned long gfn = gunyah_gpa_to_gfn(gpa);
+	struct gunyah_gmem_binding *b;
+	struct folio *folio;
+	int ret;
+
+	down_read(&ghvm->bindings_lock);
+	b = mtree_load(&ghvm->bindings, gfn);
+	if (!b) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	if (write && !(b->flags & GUNYAH_MEM_ALLOW_WRITE)) {
+		ret = -EPERM;
+		goto unlock;
+	}
+
+	folio = gunyah_gmem_get_folio(file_inode(b->file),
+				      gunyah_gfn_to_off(b, gfn));
+	if (!folio) {
+		ret = -ENOMEM;
+		pr_err_ratelimited("Failed to obtain memory for guest addr %016llx\n", gpa);
+		goto unlock;
+	}
+
+	/**
+	 * the folio covers the requested guest address, but the folio may not
+	 * start at the requested guest address. recompute the gfn based on the
+	 * folio itself.
+	 */
+	gfn = gunyah_off_to_gfn(b, folio_index(folio));
+
+	filemap_invalidate_lock_shared(b->file->f_mapping);
+	ret = gunyah_vm_provide_folio(ghvm, folio, gfn,
+				      !gunyah_guest_mem_is_lend(ghvm, b->flags),
+				      !!(b->flags & GUNYAH_MEM_ALLOW_WRITE));
+	filemap_invalidate_unlock_shared(b->file->f_mapping);
+	if (ret) {
+		if (ret != -EAGAIN)
+			pr_err_ratelimited(
+				"Failed to provide folio for guest addr: %016llx: %d\n",
+				gpa, ret);
+		goto out;
+	}
+out:
+	folio_unlock(folio);
+	folio_put(folio);
+unlock:
+	up_read(&ghvm->bindings_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_gmem_demand_page);
diff --git a/drivers/virt/gunyah/gunyah_vcpu.c b/drivers/virt/gunyah/gunyah_vcpu.c
index 8192350f180b0..f8306620b1dd6 100644
--- a/drivers/virt/gunyah/gunyah_vcpu.c
+++ b/drivers/virt/gunyah/gunyah_vcpu.c
@@ -89,29 +89,44 @@ static irqreturn_t gunyah_vcpu_irq_handler(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static void gunyah_handle_page_fault(
+static bool gunyah_handle_page_fault(
 	struct gunyah_vcpu *vcpu,
 	const struct gunyah_hypercall_vcpu_run_resp *vcpu_run_resp)
 {
 	u64 addr = vcpu_run_resp->state_data[0];
+	bool write = !!vcpu_run_resp->state_data[1];
+	int ret = 0;
+
+	ret = gunyah_gmem_demand_page(vcpu->ghvm, addr, write);
+	if (!ret || ret == -EAGAIN)
+		return true;
 
 	vcpu->vcpu_run->page_fault.resume_action = GUNYAH_VCPU_RESUME_FAULT;
-	vcpu->vcpu_run->page_fault.attempt = 0;
+	vcpu->vcpu_run->page_fault.attempt = ret;
 	vcpu->vcpu_run->page_fault.phys_addr = addr;
 	vcpu->vcpu_run->exit_reason = GUNYAH_VCPU_EXIT_PAGE_FAULT;
+	return false;
 }
 
-static void
-gunyah_handle_mmio(struct gunyah_vcpu *vcpu,
+static bool
+gunyah_handle_mmio(struct gunyah_vcpu *vcpu, unsigned long resume_data[3],
 		   const struct gunyah_hypercall_vcpu_run_resp *vcpu_run_resp)
 {
 	u64 addr = vcpu_run_resp->state_data[0],
 	    len = vcpu_run_resp->state_data[1],
 	    data = vcpu_run_resp->state_data[2];
+	int ret;
 
 	if (WARN_ON(len > sizeof(u64)))
 		len = sizeof(u64);
 
+	ret = gunyah_gmem_demand_page(vcpu->ghvm, addr,
+				      vcpu->vcpu_run->mmio.is_write);
+	if (!ret || ret == -EAGAIN) {
+		resume_data[1] = GUNYAH_ADDRSPACE_VMMIO_ACTION_RETRY;
+		return true;
+	}
+
 	if (vcpu_run_resp->state == GUNYAH_VCPU_ADDRSPACE_VMMIO_READ) {
 		vcpu->vcpu_run->mmio.is_write = 0;
 		/* Record that we need to give vCPU user's supplied value next gunyah_vcpu_run() */
@@ -128,11 +143,15 @@ gunyah_handle_mmio(struct gunyah_vcpu *vcpu,
 	vcpu->mmio_addr = vcpu->vcpu_run->mmio.phys_addr = addr;
 	vcpu->vcpu_run->mmio.len = len;
 	vcpu->vcpu_run->exit_reason = GUNYAH_VCPU_EXIT_MMIO;
+
+	return false;
 }
 
 static int gunyah_handle_mmio_resume(struct gunyah_vcpu *vcpu,
 				     unsigned long resume_data[3])
 {
+	bool write = vcpu->state == GUNYAH_VCPU_RUN_STATE_MMIO_WRITE;
+
 	switch (vcpu->vcpu_run->mmio.resume_action) {
 	case GUNYAH_VCPU_RESUME_HANDLED:
 		if (vcpu->state == GUNYAH_VCPU_RUN_STATE_MMIO_READ) {
@@ -148,6 +167,8 @@ static int gunyah_handle_mmio_resume(struct gunyah_vcpu *vcpu,
 		resume_data[1] = GUNYAH_ADDRSPACE_VMMIO_ACTION_FAULT;
 		break;
 	case GUNYAH_VCPU_RESUME_RETRY:
+		/* userspace probably added a memory binding */
+		gunyah_gmem_demand_page(vcpu->ghvm, vcpu->mmio_addr, write);
 		resume_data[1] = GUNYAH_ADDRSPACE_VMMIO_ACTION_RETRY;
 		break;
 	default:
@@ -310,11 +331,15 @@ static int gunyah_vcpu_run(struct gunyah_vcpu *vcpu)
 				break;
 			case GUNYAH_VCPU_ADDRSPACE_VMMIO_READ:
 			case GUNYAH_VCPU_ADDRSPACE_VMMIO_WRITE:
-				gunyah_handle_mmio(vcpu, &vcpu_run_resp);
-				goto out;
+				if (!gunyah_handle_mmio(vcpu, resume_data,
+							&vcpu_run_resp))
+					goto out;
+				break;
 			case GUNYAH_VCPU_ADDRSPACE_PAGE_FAULT:
-				gunyah_handle_page_fault(vcpu, &vcpu_run_resp);
-				goto out;
+				if (!gunyah_handle_page_fault(vcpu,
+							      &vcpu_run_resp))
+					goto out;
+				break;
 			default:
 				pr_warn_ratelimited(
 					"Unknown vCPU state: %llx\n",
diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index 198a99d78c44c..473740a1f97d0 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -474,6 +474,23 @@ static int gunyah_vm_start(struct gunyah_vm *ghvm)
 		goto err;
 	}
 
+	ret = gunyah_gmem_setup_demand_paging(ghvm);
+	if (ret) {
+		dev_warn(ghvm->parent,
+			 "Failed to set up gmem demand paging: %d\n", ret);
+		goto err;
+	}
+
+	ret = gunyah_rm_vm_set_address_layout(
+		ghvm->rm, ghvm->vmid, GUNYAH_RM_RANGE_ID_IMAGE,
+		ghvm->dtb.parcel_start << PAGE_SHIFT,
+		ghvm->dtb.parcel_pages << PAGE_SHIFT);
+	if (ret) {
+		dev_warn(ghvm->parent,
+			 "Failed to set location of DTB mem parcel: %d\n", ret);
+		goto err;
+	}
+
 	ret = gunyah_rm_vm_init(ghvm->rm, ghvm->vmid);
 	if (ret) {
 		ghvm->vm_status = GUNYAH_RM_VM_STATUS_INIT_FAILED;
@@ -501,8 +518,20 @@ static int gunyah_vm_start(struct gunyah_vm *ghvm)
 		gunyah_vm_add_resource(ghvm, ghrsc);
 	}
 
+	ret = gunyah_vm_parcel_to_paged(ghvm, &ghvm->dtb.parcel,
+					ghvm->dtb.parcel_start,
+					ghvm->dtb.parcel_pages);
+	if (ret)
+		goto err;
+
 	ret = gunyah_rm_vm_start(ghvm->rm, ghvm->vmid);
 	if (ret) {
+		/**
+		 * need to rollback parcel_to_paged because RM is still
+		 * tracking the parcel
+		 */
+		gunyah_vm_mm_erase_range(ghvm, ghvm->dtb.parcel_start,
+					 ghvm->dtb.parcel_pages);
 		dev_warn(ghvm->parent, "Failed to start VM: %d\n", ret);
 		goto err;
 	}
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index d8c299e5cf7cc..5eb14f30ba965 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -199,4 +199,7 @@ int gunyah_gmem_reclaim_parcel(struct gunyah_vm *ghvm,
 			       struct gunyah_rm_mem_parcel *parcel, u64 gfn,
 			       u64 nr);
 
+int gunyah_gmem_setup_demand_paging(struct gunyah_vm *ghvm);
+int gunyah_gmem_demand_page(struct gunyah_vm *ghvm, u64 gpa, bool write);
+
 #endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:27 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:27 -0800
Subject: [PATCH v17 04/35] virt: gunyah: Add hypercalls to identify Gunyah
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-4-1e9da6763d38@quicinc.com>

Add hypercalls to identify when Linux is running in a virtual machine
under Gunyah.

There are two calls to help identify Gunyah:

1. gh_hypercall_get_uid() returns a UID when running under a Gunyah
   hypervisor.
2. gh_hypercall_hyp_identify() returns build information and a set of
   feature flags that are supported by Gunyah.

Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
Reviewed-by: Alex Elder <elder at linaro.org>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 arch/arm64/Kbuild                    |  1 +
 arch/arm64/gunyah/Makefile           |  3 ++
 arch/arm64/gunyah/gunyah_hypercall.c | 62 ++++++++++++++++++++++++++++++++++++
 drivers/virt/Kconfig                 |  2 ++
 drivers/virt/gunyah/Kconfig          | 12 +++++++
 include/linux/gunyah.h               | 38 ++++++++++++++++++++++
 6 files changed, 118 insertions(+)

diff --git a/arch/arm64/Kbuild b/arch/arm64/Kbuild
index 5bfbf7d79c99b..e4847ba0e3c95 100644
--- a/arch/arm64/Kbuild
+++ b/arch/arm64/Kbuild
@@ -3,6 +3,7 @@ obj-y			+= kernel/ mm/ net/
 obj-$(CONFIG_KVM)	+= kvm/
 obj-$(CONFIG_XEN)	+= xen/
 obj-$(subst m,y,$(CONFIG_HYPERV))	+= hyperv/
+obj-$(CONFIG_GUNYAH)	+= gunyah/
 obj-$(CONFIG_CRYPTO)	+= crypto/
 
 # for cleaning
diff --git a/arch/arm64/gunyah/Makefile b/arch/arm64/gunyah/Makefile
new file mode 100644
index 0000000000000..84f1e38cafb1e
--- /dev/null
+++ b/arch/arm64/gunyah/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_GUNYAH) += gunyah_hypercall.o
diff --git a/arch/arm64/gunyah/gunyah_hypercall.c b/arch/arm64/gunyah/gunyah_hypercall.c
new file mode 100644
index 0000000000000..d44663334f381
--- /dev/null
+++ b/arch/arm64/gunyah/gunyah_hypercall.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/module.h>
+#include <linux/gunyah.h>
+#include <linux/uuid.h>
+
+/* {c1d58fcd-a453-5fdb-9265-ce36673d5f14} */
+static const uuid_t GUNYAH_UUID = UUID_INIT(0xc1d58fcd, 0xa453, 0x5fdb, 0x92,
+					    0x65, 0xce, 0x36, 0x67, 0x3d, 0x5f,
+					    0x14);
+
+bool arch_is_gunyah_guest(void)
+{
+	struct arm_smccc_res res;
+	uuid_t uuid;
+	u32 *up;
+
+	arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res);
+
+	up = (u32 *)&uuid.b[0];
+	up[0] = lower_32_bits(res.a0);
+	up[1] = lower_32_bits(res.a1);
+	up[2] = lower_32_bits(res.a2);
+	up[3] = lower_32_bits(res.a3);
+
+	return uuid_equal(&uuid, &GUNYAH_UUID);
+}
+EXPORT_SYMBOL_GPL(arch_is_gunyah_guest);
+
+#define GUNYAH_HYPERCALL(fn)                                      \
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
+			   ARM_SMCCC_OWNER_VENDOR_HYP, fn)
+
+/* clang-format off */
+#define GUNYAH_HYPERCALL_HYP_IDENTIFY		GUNYAH_HYPERCALL(0x8000)
+/* clang-format on */
+
+/**
+ * gunyah_hypercall_hyp_identify() - Returns build information and feature flags
+ *                               supported by Gunyah.
+ * @hyp_identity: filled by the hypercall with the API info and feature flags.
+ */
+void gunyah_hypercall_hyp_identify(
+	struct gunyah_hypercall_hyp_identify_resp *hyp_identity)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GUNYAH_HYPERCALL_HYP_IDENTIFY, &res);
+
+	hyp_identity->api_info = res.a0;
+	hyp_identity->flags[0] = res.a1;
+	hyp_identity->flags[1] = res.a2;
+	hyp_identity->flags[2] = res.a3;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_hyp_identify);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Gunyah Hypervisor Hypercalls");
diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig
index 40129b6f0eca4..172a6a12073c3 100644
--- a/drivers/virt/Kconfig
+++ b/drivers/virt/Kconfig
@@ -50,4 +50,6 @@ source "drivers/virt/acrn/Kconfig"
 
 source "drivers/virt/coco/Kconfig"
 
+source "drivers/virt/gunyah/Kconfig"
+
 endif
diff --git a/drivers/virt/gunyah/Kconfig b/drivers/virt/gunyah/Kconfig
new file mode 100644
index 0000000000000..6f4c85db80b52
--- /dev/null
+++ b/drivers/virt/gunyah/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config GUNYAH
+	tristate "Gunyah Virtualization drivers"
+	depends on ARM64
+	help
+	  The Gunyah drivers are the helper interfaces that run in a guest VM
+	  such as basic inter-VM IPC and signaling mechanisms, and higher level
+	  services such as memory/device sharing, IRQ sharing, and so on.
+
+	  Say Y/M here to enable the drivers needed to interact in a Gunyah
+	  virtual environment.
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index 1eab631a49b6d..33bcbd22d39f7 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -6,9 +6,11 @@
 #ifndef _LINUX_GUNYAH_H
 #define _LINUX_GUNYAH_H
 
+#include <linux/bitfield.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/limits.h>
+#include <linux/types.h>
 
 /* Matches resource manager's resource types for VM_GET_HYP_RESOURCES RPC */
 enum gunyah_resource_type {
@@ -103,4 +105,40 @@ static inline int gunyah_error_remap(enum gunyah_error gunyah_error)
 	}
 }
 
+enum gunyah_api_feature {
+	/* clang-format off */
+	GUNYAH_FEATURE_DOORBELL		= 1,
+	GUNYAH_FEATURE_MSGQUEUE		= 2,
+	GUNYAH_FEATURE_VCPU		= 5,
+	GUNYAH_FEATURE_MEMEXTENT	= 6,
+	/* clang-format on */
+};
+
+bool arch_is_gunyah_guest(void);
+
+#define GUNYAH_API_V1 1
+
+/* Other bits reserved for future use and will be zero */
+/* clang-format off */
+#define GUNYAH_API_INFO_API_VERSION_MASK	GENMASK_ULL(13, 0)
+#define GUNYAH_API_INFO_BIG_ENDIAN		BIT_ULL(14)
+#define GUNYAH_API_INFO_IS_64BIT		BIT_ULL(15)
+#define GUNYAH_API_INFO_VARIANT_MASK 		GENMASK_ULL(63, 56)
+/* clang-format on */
+
+struct gunyah_hypercall_hyp_identify_resp {
+	u64 api_info;
+	u64 flags[3];
+};
+
+static inline u16
+gunyah_api_version(const struct gunyah_hypercall_hyp_identify_resp *gunyah_api)
+{
+	return FIELD_GET(GUNYAH_API_INFO_API_VERSION_MASK,
+			 gunyah_api->api_info);
+}
+
+void gunyah_hypercall_hyp_identify(
+	struct gunyah_hypercall_hyp_identify_resp *hyp_identity);
+
 #endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:25 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:25 -0800
Subject: [PATCH v17 02/35] dt-bindings: Add binding for gunyah hypervisor
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-2-1e9da6763d38@quicinc.com>

The Gunyah Resource Manager applies a devicetree overlay describing the
virtual platform configuration of the guest VM, such as the message
queue capability IDs for communicating with the Resource Manager. This
information is not otherwise discoverable by a VM: the Gunyah hypervisor
core does not provide a direct interface to discover capability IDs nor
a way to communicate with RM without having already known the
corresponding message queue capability ID. Add the DT bindings that
Gunyah adheres for the hypervisor node and message queues.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 .../bindings/firmware/gunyah-hypervisor.yaml       | 82 ++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml b/Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml
new file mode 100644
index 0000000000000..cdeb4885a8072
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/gunyah-hypervisor.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Gunyah Hypervisor
+
+maintainers:
+  - Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
+  - Elliot Berman <quic_eberman at quicinc.com>
+
+description: |+
+  Gunyah virtual machines use this information to determine the capability IDs
+  of the message queues used to communicate with the Gunyah Resource Manager.
+  See also: https://github.com/quic/gunyah-resource-manager/blob/develop/src/vm_creation/dto_construct.c
+
+properties:
+  compatible:
+    const: gunyah-hypervisor
+
+  "#address-cells":
+    description: Number of cells needed to represent 64-bit capability IDs.
+    const: 2
+
+  "#size-cells":
+    description: must be 0, because capability IDs are not memory address
+                  ranges and do not have a size.
+    const: 0
+
+patternProperties:
+  "^gunyah-resource-mgr(@.*)?":
+    type: object
+    description:
+      Resource Manager node which is required to communicate to Resource
+      Manager VM using Gunyah Message Queues.
+
+    properties:
+      compatible:
+        const: gunyah-resource-manager
+
+      reg:
+        items:
+          - description: Gunyah capability ID of the TX message queue
+          - description: Gunyah capability ID of the RX message queue
+
+      interrupts:
+        items:
+          - description: Interrupt for the TX message queue
+          - description: Interrupt for the RX message queue
+
+    additionalProperties: false
+
+    required:
+      - compatible
+      - reg
+      - interrupts
+
+additionalProperties: false
+
+required:
+  - compatible
+  - "#address-cells"
+  - "#size-cells"
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    hypervisor {
+        #address-cells = <2>;
+        #size-cells = <0>;
+        compatible = "gunyah-hypervisor";
+
+        gunyah-resource-mgr at 0 {
+            compatible = "gunyah-resource-manager";
+            interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>, /* TX allowed IRQ */
+                         <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>; /* RX requested IRQ */
+            reg = <0x00000000 0x00000000>, /* TX capability ID */
+                  <0x00000000 0x00000001>; /* RX capability ID */
+        };
+    };

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:41 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:41 -0800
Subject: [PATCH v17 18/35] mm/interval_tree: Export iter_first/iter_next
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-18-1e9da6763d38@quicinc.com>

Export vma_interval_tree_iter_first and vma_interval_tree_iter_next for
vma_interval_tree_foreach.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 mm/interval_tree.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/mm/interval_tree.c b/mm/interval_tree.c
index 32e390c42c53f..faa50767496c3 100644
--- a/mm/interval_tree.c
+++ b/mm/interval_tree.c
@@ -24,6 +24,9 @@ INTERVAL_TREE_DEFINE(struct vm_area_struct, shared.rb,
 		     unsigned long, shared.rb_subtree_last,
 		     vma_start_pgoff, vma_last_pgoff, /* empty */, vma_interval_tree)
 
+EXPORT_SYMBOL_GPL(vma_interval_tree_iter_first);
+EXPORT_SYMBOL_GPL(vma_interval_tree_iter_next);
+
 /* Insert node immediately after prev in the interval tree */
 void vma_interval_tree_insert_after(struct vm_area_struct *node,
 				    struct vm_area_struct *prev,

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:52 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:52 -0800
Subject: [PATCH v17 29/35] gunyah: rsc_mgr: Add RPC to set VM boot context
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-29-1e9da6763d38@quicinc.com>

The initial context of a the primary vCPU can be initialized by
performing RM RPC calls.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/rsc_mgr.h     |  2 ++
 drivers/virt/gunyah/rsc_mgr_rpc.c | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h
index 99c2db18579ca..2acaf8dff365e 100644
--- a/drivers/virt/gunyah/rsc_mgr.h
+++ b/drivers/virt/gunyah/rsc_mgr.h
@@ -84,6 +84,8 @@ int gunyah_rm_vm_configure(struct gunyah_rm *rm, u16 vmid,
 			   u32 mem_handle, u64 image_offset, u64 image_size,
 			   u64 dtb_offset, u64 dtb_size);
 int gunyah_rm_vm_init(struct gunyah_rm *rm, u16 vmid);
+int gunyah_rm_vm_set_boot_context(struct gunyah_rm *rm, u16 vmid, u8 reg_set,
+				  u8 reg_index, u64 value);
 
 struct gunyah_rm_hyp_resource {
 	u8 type;
diff --git a/drivers/virt/gunyah/rsc_mgr_rpc.c b/drivers/virt/gunyah/rsc_mgr_rpc.c
index dfffcf02ddaea..eabf8659eb8f9 100644
--- a/drivers/virt/gunyah/rsc_mgr_rpc.c
+++ b/drivers/virt/gunyah/rsc_mgr_rpc.c
@@ -24,6 +24,7 @@
 #define GUNYAH_RM_RPC_VM_INIT			0x5600000B
 #define GUNYAH_RM_RPC_VM_GET_HYP_RESOURCES	0x56000020
 #define GUNYAH_RM_RPC_VM_GET_VMID		0x56000024
+#define GUNYAH_RM_RPC_VM_SET_BOOT_CONTEXT	0x56000031
 #define GUNYAH_RM_RPC_VM_SET_DEMAND_PAGING	0x56000033
 #define GUNYAH_RM_RPC_VM_SET_ADDRESS_LAYOUT	0x56000034
 /* clang-format on */
@@ -105,6 +106,15 @@ struct gunyah_rm_vm_config_image_req {
 	__le64 dtb_size;
 } __packed;
 
+/* Call: VM_SET_BOOT_CONTEXT */
+struct gunyah_rm_vm_set_boot_context_req {
+	__le16 vmid;
+	u8 reg_set;
+	u8 reg_index;
+	__le32 _padding;
+	__le64 value;
+} __packed;
+
 /* Call: VM_SET_DEMAND_PAGING */
 struct gunyah_rm_vm_set_demand_paging_req {
 	__le16 vmid;
@@ -447,6 +457,29 @@ int gunyah_rm_vm_init(struct gunyah_rm *rm, u16 vmid)
 }
 ALLOW_ERROR_INJECTION(gunyah_rm_vm_init, ERRNO);
 
+/**
+ * gunyah_rm_vm_set_boot_context() - set the initial boot context of the primary vCPU
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: VM identifier
+ * @reg_set: See &enum gunyah_vm_boot_context_reg
+ * @reg_index: Which register to set; must be 0 for REG_SET_PC
+ * @value: Value to set in the register
+ */
+int gunyah_rm_vm_set_boot_context(struct gunyah_rm *rm, u16 vmid, u8 reg_set,
+				  u8 reg_index, u64 value)
+{
+	struct gunyah_rm_vm_set_boot_context_req req_payload = {
+		.vmid = cpu_to_le16(vmid),
+		.reg_set = reg_set,
+		.reg_index = reg_index,
+		.value = cpu_to_le64(value),
+	};
+
+	return gunyah_rm_call(rm, GUNYAH_RM_RPC_VM_SET_BOOT_CONTEXT,
+			      &req_payload, sizeof(req_payload), NULL, NULL);
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_vm_set_boot_context, ERRNO);
+
 /**
  * gunyah_rm_get_hyp_resources() - Retrieve hypervisor resources (capabilities) associated with a VM
  * @rm: Handle to a Gunyah resource manager

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:46 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:46 -0800
Subject: [PATCH v17 23/35] virt: gunyah: Implement guestmemfd
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-23-1e9da6763d38@quicinc.com>

Memory provided to Gunyah virtual machines are provided by a
Gunyah guestmemfd. Because memory provided to virtual machines may be
unmapped at stage-2 from the host (i.e. in the hypervisor's page tables
for the host), special care needs to be taken to ensure that the kernel
doesn't have a page mapped when it is lent to the guest. Without this
tracking, a kernel panic could be induced  by userspace tricking the
kernel into accessing guest-private memory.

Introduce the basic guestmemfd ops and ioctl. Userspace should be able
to access the memory unless it is provided to the guest virtual machine:
this is necessary to allow userspace to preload binaries such as the
kernel Image prior to running the VM. Subsequent commits will wire up
providing the memory to the guest.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/Makefile      |   2 +-
 drivers/virt/gunyah/guest_memfd.c | 276 ++++++++++++++++++++++++++++++++++++++
 drivers/virt/gunyah/vm_mgr.c      |   9 ++
 drivers/virt/gunyah/vm_mgr.h      |   2 +
 include/uapi/linux/gunyah.h       |  19 +++
 5 files changed, 307 insertions(+), 1 deletion(-)

diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
index a6c6f29b887a6..c4505fce177dd 100644
--- a/drivers/virt/gunyah/Makefile
+++ b/drivers/virt/gunyah/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o vm_mgr_mem.o
+gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o vm_mgr_mem.o guest_memfd.o
 
 obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o gunyah_vcpu.o
 obj-$(CONFIG_GUNYAH_PLATFORM_HOOKS) += gunyah_platform_hooks.o
diff --git a/drivers/virt/gunyah/guest_memfd.c b/drivers/virt/gunyah/guest_memfd.c
new file mode 100644
index 0000000000000..19c72aa1d0e5e
--- /dev/null
+++ b/drivers/virt/gunyah/guest_memfd.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "gunyah_guest_mem: " fmt
+
+#include <linux/anon_inodes.h>
+#include <linux/types.h>
+#include <linux/falloc.h>
+#include <linux/file.h>
+#include <linux/migrate.h>
+#include <linux/pagemap.h>
+
+#include <uapi/linux/gunyah.h>
+
+#include "vm_mgr.h"
+
+static struct folio *gunyah_gmem_get_huge_folio(struct inode *inode,
+						pgoff_t index)
+{
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+	unsigned long huge_index = round_down(index, HPAGE_PMD_NR);
+	unsigned long flags = (unsigned long)inode->i_private;
+	struct address_space *mapping = inode->i_mapping;
+	gfp_t gfp = mapping_gfp_mask(mapping);
+	struct folio *folio;
+
+	if (!(flags & GHMF_ALLOW_HUGEPAGE))
+		return NULL;
+
+	if (filemap_range_has_page(mapping, huge_index << PAGE_SHIFT,
+				   (huge_index + HPAGE_PMD_NR - 1)
+					   << PAGE_SHIFT))
+		return NULL;
+
+	folio = filemap_alloc_folio(gfp, HPAGE_PMD_ORDER);
+	if (!folio)
+		return NULL;
+
+	if (filemap_add_folio(mapping, folio, huge_index, gfp)) {
+		folio_put(folio);
+		return NULL;
+	}
+
+	return folio;
+#else
+	return NULL;
+#endif
+}
+
+static struct folio *gunyah_gmem_get_folio(struct inode *inode, pgoff_t index)
+{
+	struct folio *folio;
+
+	folio = gunyah_gmem_get_huge_folio(inode, index);
+	if (!folio) {
+		folio = filemap_grab_folio(inode->i_mapping, index);
+		if (IS_ERR_OR_NULL(folio))
+			return NULL;
+	}
+
+	/*
+	 * Use the up-to-date flag to track whether or not the memory has been
+	 * zeroed before being handed off to the guest.  There is no backing
+	 * storage for the memory, so the folio will remain up-to-date until
+	 * it's removed.
+	 */
+	if (!folio_test_uptodate(folio)) {
+		unsigned long nr_pages = folio_nr_pages(folio);
+		unsigned long i;
+
+		for (i = 0; i < nr_pages; i++)
+			clear_highpage(folio_page(folio, i));
+
+		folio_mark_uptodate(folio);
+	}
+
+	/*
+	 * Ignore accessed, referenced, and dirty flags.  The memory is
+	 * unevictable and there is no storage to write back to.
+	 */
+	return folio;
+}
+
+static vm_fault_t gunyah_gmem_host_fault(struct vm_fault *vmf)
+{
+	struct folio *folio;
+
+	folio = gunyah_gmem_get_folio(file_inode(vmf->vma->vm_file),
+				      vmf->pgoff);
+	if (!folio)
+		return VM_FAULT_SIGBUS;
+
+	vmf->page = folio_file_page(folio, vmf->pgoff);
+
+	return VM_FAULT_LOCKED;
+}
+
+static const struct vm_operations_struct gunyah_gmem_vm_ops = {
+	.fault = gunyah_gmem_host_fault,
+};
+
+static int gunyah_gmem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	file_accessed(file);
+	vma->vm_ops = &gunyah_gmem_vm_ops;
+	return 0;
+}
+
+/**
+ * gunyah_gmem_punch_hole() - try to reclaim a range of pages
+ * @inode: guest memfd inode
+ * @offset: Offset into memfd to start reclaim
+ * @len: length to reclaim
+ *
+ * Will try to unmap from virtual machines any folios covered by
+ * [offset, offset+len]. If unmapped, then tries to free those folios
+ *
+ * Returns - error code if any folio in the range couldn't be freed.
+ */
+static long gunyah_gmem_punch_hole(struct inode *inode, loff_t offset,
+				   loff_t len)
+{
+	truncate_inode_pages_range(inode->i_mapping, offset, offset + len - 1);
+
+	return 0;
+}
+
+static long gunyah_gmem_allocate(struct inode *inode, loff_t offset, loff_t len)
+{
+	struct address_space *mapping = inode->i_mapping;
+	pgoff_t start, index, end;
+	int r;
+
+	/* Dedicated guest is immutable by default. */
+	if (offset + len > i_size_read(inode))
+		return -EINVAL;
+
+	filemap_invalidate_lock_shared(mapping);
+
+	start = offset >> PAGE_SHIFT;
+	end = (offset + len) >> PAGE_SHIFT;
+
+	r = 0;
+	for (index = start; index < end;) {
+		struct folio *folio;
+
+		if (signal_pending(current)) {
+			r = -EINTR;
+			break;
+		}
+
+		folio = gunyah_gmem_get_folio(inode, index);
+		if (!folio) {
+			r = -ENOMEM;
+			break;
+		}
+
+		index = folio_next_index(folio);
+
+		folio_unlock(folio);
+		folio_put(folio);
+
+		/* 64-bit only, wrapping the index should be impossible. */
+		if (WARN_ON_ONCE(!index))
+			break;
+
+		cond_resched();
+	}
+
+	filemap_invalidate_unlock_shared(mapping);
+
+	return r;
+}
+
+static long gunyah_gmem_fallocate(struct file *file, int mode, loff_t offset,
+				  loff_t len)
+{
+	long ret;
+
+	if (!(mode & FALLOC_FL_KEEP_SIZE))
+		return -EOPNOTSUPP;
+
+	if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+		     FALLOC_FL_ZERO_RANGE))
+		return -EOPNOTSUPP;
+
+	if (!PAGE_ALIGNED(offset) || !PAGE_ALIGNED(len))
+		return -EINVAL;
+
+	if (mode & FALLOC_FL_PUNCH_HOLE)
+		ret = gunyah_gmem_punch_hole(file_inode(file), offset, len);
+	else
+		ret = gunyah_gmem_allocate(file_inode(file), offset, len);
+
+	if (!ret)
+		file_modified(file);
+	return ret;
+}
+
+static int gunyah_gmem_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static const struct file_operations gunyah_gmem_fops = {
+	.owner = THIS_MODULE,
+	.llseek = generic_file_llseek,
+	.mmap = gunyah_gmem_mmap,
+	.open = generic_file_open,
+	.fallocate = gunyah_gmem_fallocate,
+	.release = gunyah_gmem_release,
+};
+
+static const struct address_space_operations gunyah_gmem_aops = {
+	.dirty_folio = noop_dirty_folio,
+	.migrate_folio = migrate_folio,
+	.error_remove_folio = generic_error_remove_folio,
+};
+
+int gunyah_guest_mem_create(struct gunyah_create_mem_args *args)
+{
+	const char *anon_name = "[gh-gmem]";
+	unsigned long fd_flags = 0;
+	struct inode *inode;
+	struct file *file;
+	int fd, err;
+
+	if (!PAGE_ALIGNED(args->size))
+		return -EINVAL;
+
+	if (args->flags & ~(GHMF_CLOEXEC | GHMF_ALLOW_HUGEPAGE))
+		return -EINVAL;
+
+	if (args->flags & GHMF_CLOEXEC)
+		fd_flags |= O_CLOEXEC;
+
+	fd = get_unused_fd_flags(fd_flags);
+	if (fd < 0)
+		return fd;
+
+	/*
+	 * Use the so called "secure" variant, which creates a unique inode
+	 * instead of reusing a single inode.  Each guest_memfd instance needs
+	 * its own inode to track the size, flags, etc.
+	 */
+	file = anon_inode_create_getfile(anon_name, &gunyah_gmem_fops, NULL,
+					 O_RDWR, NULL);
+	if (IS_ERR(file)) {
+		err = PTR_ERR(file);
+		goto err_fd;
+	}
+
+	file->f_flags |= O_LARGEFILE;
+
+	inode = file->f_inode;
+	WARN_ON(file->f_mapping != inode->i_mapping);
+
+	inode->i_private = (void *)(unsigned long)args->flags;
+	inode->i_mapping->a_ops = &gunyah_gmem_aops;
+	inode->i_mode |= S_IFREG;
+	inode->i_size = args->size;
+	mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
+	mapping_set_large_folios(inode->i_mapping);
+	mapping_set_unmovable(inode->i_mapping);
+	/* Unmovable mappings are supposed to be marked unevictable as well. */
+	WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping));
+
+	fd_install(fd, file);
+	return fd;
+
+err_fd:
+	put_unused_fd(fd);
+	return err;
+}
diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index 64967a8b72885..238a7a4da554b 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -696,6 +696,15 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
 	switch (cmd) {
 	case GUNYAH_CREATE_VM:
 		return gunyah_dev_ioctl_create_vm(rm, arg);
+	case GUNYAH_CREATE_GUEST_MEM: {
+		struct gunyah_create_mem_args args;
+
+		if (copy_from_user(&args, (const void __user *)arg,
+				   sizeof(args)))
+			return -EFAULT;
+
+		return gunyah_guest_mem_create(&args);
+	}
 	default:
 		return -ENOTTY;
 	}
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index a6a4efa4138b7..7ac0dd066991b 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -171,4 +171,6 @@ int gunyah_vm_provide_folio(struct gunyah_vm *ghvm, struct folio *folio,
 int gunyah_vm_reclaim_folio(struct gunyah_vm *ghvm, u64 gfn, struct folio *folio);
 int gunyah_vm_reclaim_range(struct gunyah_vm *ghvm, u64 gfn, u64 nr);
 
+int gunyah_guest_mem_create(struct gunyah_create_mem_args *args);
+
 #endif
diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h
index 46f7d3aa61d05..c5f506350364d 100644
--- a/include/uapi/linux/gunyah.h
+++ b/include/uapi/linux/gunyah.h
@@ -20,6 +20,25 @@
  */
 #define GUNYAH_CREATE_VM _IO(GUNYAH_IOCTL_TYPE, 0x0) /* Returns a Gunyah VM fd */
 
+enum gunyah_mem_flags {
+	GHMF_CLOEXEC = (1UL << 0),
+	GHMF_ALLOW_HUGEPAGE = (1UL << 1),
+};
+
+/**
+ * struct gunyah_create_mem_args - Description of guest memory to create
+ * @flags: See GHMF_*.
+ */
+struct gunyah_create_mem_args {
+	__u64 flags;
+	__u64 size;
+	__u64 reserved[6];
+};
+
+#define GUNYAH_CREATE_GUEST_MEM      \
+	_IOW(GUNYAH_IOCTL_TYPE, 0x8, \
+	     struct gunyah_create_mem_args) /* Returns a Gunyah memory fd */
+
 /*
  * ioctls for gunyah-vm fds (returned by GUNYAH_CREATE_VM)
  */

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:49 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:49 -0800
Subject: [PATCH v17 26/35] virt: gunyah: Share guest VM dtb configuration
 to Gunyah
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-26-1e9da6763d38@quicinc.com>

Gunyah Resource Manager sets up a virtual machine based on a device tree
which lives in guest memory. Resource manager requires this memory to be
provided as a memory parcel for it to read and manipulate. Construct a
memory parcel, lend it to the virtual machine, and inform resource
manager about the device tree location (the memory parcel ID and offset
into the memory parcel).

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/vm_mgr.c | 45 ++++++++++++++++++++++++++++++++++++++++++--
 drivers/virt/gunyah/vm_mgr.h | 13 ++++++++++++-
 include/uapi/linux/gunyah.h  | 14 ++++++++++++++
 3 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index 43878a39d4714..198a99d78c44c 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -452,8 +452,23 @@ static int gunyah_vm_start(struct gunyah_vm *ghvm)
 	ghvm->vmid = ret;
 	ghvm->vm_status = GUNYAH_RM_VM_STATUS_LOAD;
 
-	ret = gunyah_rm_vm_configure(ghvm->rm, ghvm->vmid, ghvm->auth, 0, 0, 0,
-				     0, 0);
+	ghvm->dtb.parcel_start = ghvm->dtb.config.guest_phys_addr >> PAGE_SHIFT;
+	ghvm->dtb.parcel_pages = ghvm->dtb.config.size >> PAGE_SHIFT;
+	ret = gunyah_gmem_share_parcel(ghvm, &ghvm->dtb.parcel,
+				       &ghvm->dtb.parcel_start,
+				       &ghvm->dtb.parcel_pages);
+	if (ret) {
+		dev_warn(ghvm->parent,
+			 "Failed to allocate parcel for DTB: %d\n", ret);
+		goto err;
+	}
+
+	ret = gunyah_rm_vm_configure(ghvm->rm, ghvm->vmid, ghvm->auth,
+				     ghvm->dtb.parcel.mem_handle, 0, 0,
+				     ghvm->dtb.config.guest_phys_addr -
+					     (ghvm->dtb.parcel_start
+					      << PAGE_SHIFT),
+				     ghvm->dtb.config.size);
 	if (ret) {
 		dev_warn(ghvm->parent, "Failed to configure VM: %d\n", ret);
 		goto err;
@@ -536,6 +551,21 @@ static long gunyah_vm_ioctl(struct file *filp, unsigned int cmd,
 	long r;
 
 	switch (cmd) {
+	case GUNYAH_VM_SET_DTB_CONFIG: {
+		struct gunyah_vm_dtb_config dtb_config;
+
+		if (copy_from_user(&dtb_config, argp, sizeof(dtb_config)))
+			return -EFAULT;
+
+		if (overflows_type(dtb_config.guest_phys_addr + dtb_config.size,
+				   u64))
+			return -EOVERFLOW;
+
+		ghvm->dtb.config = dtb_config;
+
+		r = 0;
+		break;
+	}
 	case GUNYAH_VM_START: {
 		r = gunyah_vm_ensure_started(ghvm);
 		break;
@@ -594,6 +624,17 @@ static void _gunyah_vm_put(struct kref *kref)
 	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_RUNNING)
 		gunyah_vm_stop(ghvm);
 
+	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_LOAD ||
+	    ghvm->vm_status == GUNYAH_RM_VM_STATUS_READY ||
+	    ghvm->vm_status == GUNYAH_RM_VM_STATUS_INIT_FAILED) {
+		ret = gunyah_gmem_reclaim_parcel(ghvm, &ghvm->dtb.parcel,
+						 ghvm->dtb.parcel_start,
+						 ghvm->dtb.parcel_pages);
+		if (ret)
+			dev_err(ghvm->parent,
+				"Failed to reclaim DTB parcel: %d\n", ret);
+	}
+
 	gunyah_vm_remove_functions(ghvm);
 
 	down_write(&ghvm->bindings_lock);
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index b6bc66f018b09..d8c299e5cf7cc 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -74,6 +74,13 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
  * @resource_tickets: List of &struct gunyah_vm_resource_ticket
  * @auth: Authentication mechanism to be used by resource manager when
  *        launching the VM
+ * @dtb: For tracking dtb configuration when launching the VM
+ * @dtb.config: Location of the DTB in the guest memory
+ * @dtb.parcel_start: Guest frame number where the memory parcel that we lent to
+ *                    VM (DTB could start in middle of folio; we lend entire
+ *                    folio; parcel_start is start of the folio)
+ * @dtb.parcel_pages: Number of pages lent for the memory parcel
+ * @dtb.parcel: Data for resource manager to lend the parcel
  *
  * Members are grouped by hot path.
  */
@@ -103,7 +110,11 @@ struct gunyah_vm {
 
 	struct device *parent;
 	enum gunyah_rm_vm_auth_mechanism auth;
-
+	struct {
+		struct gunyah_vm_dtb_config config;
+		u64 parcel_start, parcel_pages;
+		struct gunyah_rm_mem_parcel parcel;
+	} dtb;
 };
 
 /**
diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h
index 1af4c5ae6bc3e..a89d9bedf3e5d 100644
--- a/include/uapi/linux/gunyah.h
+++ b/include/uapi/linux/gunyah.h
@@ -42,6 +42,20 @@ struct gunyah_create_mem_args {
 /*
  * ioctls for gunyah-vm fds (returned by GUNYAH_CREATE_VM)
  */
+
+/**
+ * struct gunyah_vm_dtb_config - Set the location of the VM's devicetree blob
+ * @guest_phys_addr: Address of the VM's devicetree in guest memory.
+ * @size: Maximum size of the devicetree including space for overlays.
+ *        Resource manager applies an overlay to the DTB and dtb_size should
+ *        include room for the overlay. A page of memory is typicaly plenty.
+ */
+struct gunyah_vm_dtb_config {
+	__u64 guest_phys_addr;
+	__u64 size;
+};
+#define GUNYAH_VM_SET_DTB_CONFIG	_IOW(GUNYAH_IOCTL_TYPE, 0x2, struct gunyah_vm_dtb_config)
+
 #define GUNYAH_VM_START		_IO(GUNYAH_IOCTL_TYPE, 0x3)
 
 /**

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:44 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:44 -0800
Subject: [PATCH v17 21/35] gunyah: rsc_mgr: Add platform ops on
 mem_lend/mem_reclaim
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-21-1e9da6763d38@quicinc.com>

On Qualcomm platforms, there is a firmware entity which controls access
to physical pages. In order to share memory with another VM, this entity
needs to be informed that the guest VM should have access to the memory.

Co-developed-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/Kconfig                 |   4 +
 drivers/virt/gunyah/Makefile                |   1 +
 drivers/virt/gunyah/gunyah_platform_hooks.c | 117 ++++++++++++++++++++++++++++
 drivers/virt/gunyah/rsc_mgr.h               |  10 +++
 drivers/virt/gunyah/rsc_mgr_rpc.c           |  20 ++++-
 drivers/virt/gunyah/vm_mgr_mem.c            |  39 +++++++++-
 include/linux/gunyah.h                      |  63 ++++++++++++---
 7 files changed, 237 insertions(+), 17 deletions(-)

diff --git a/drivers/virt/gunyah/Kconfig b/drivers/virt/gunyah/Kconfig
index 6f4c85db80b52..23ba523d25dc8 100644
--- a/drivers/virt/gunyah/Kconfig
+++ b/drivers/virt/gunyah/Kconfig
@@ -3,6 +3,7 @@
 config GUNYAH
 	tristate "Gunyah Virtualization drivers"
 	depends on ARM64
+	select GUNYAH_PLATFORM_HOOKS
 	help
 	  The Gunyah drivers are the helper interfaces that run in a guest VM
 	  such as basic inter-VM IPC and signaling mechanisms, and higher level
@@ -10,3 +11,6 @@ config GUNYAH
 
 	  Say Y/M here to enable the drivers needed to interact in a Gunyah
 	  virtual environment.
+
+config GUNYAH_PLATFORM_HOOKS
+	tristate
diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
index f3c9507224eeb..ffcde0e0ccfa9 100644
--- a/drivers/virt/gunyah/Makefile
+++ b/drivers/virt/gunyah/Makefile
@@ -3,3 +3,4 @@
 gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o vm_mgr_mem.o
 
 obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o gunyah_vcpu.o
+obj-$(CONFIG_GUNYAH_PLATFORM_HOOKS) += gunyah_platform_hooks.o
diff --git a/drivers/virt/gunyah/gunyah_platform_hooks.c b/drivers/virt/gunyah/gunyah_platform_hooks.c
new file mode 100644
index 0000000000000..b03795df00144
--- /dev/null
+++ b/drivers/virt/gunyah/gunyah_platform_hooks.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/device.h>
+#include <linux/gunyah.h>
+#include <linux/module.h>
+#include <linux/rwsem.h>
+
+#include "rsc_mgr.h"
+
+static const struct gunyah_rm_platform_ops *rm_platform_ops;
+static DECLARE_RWSEM(rm_platform_ops_lock);
+
+int gunyah_rm_platform_pre_mem_share(struct gunyah_rm *rm,
+				     struct gunyah_rm_mem_parcel *mem_parcel)
+{
+	int ret = 0;
+
+	down_read(&rm_platform_ops_lock);
+	if (rm_platform_ops && rm_platform_ops->pre_mem_share)
+		ret = rm_platform_ops->pre_mem_share(rm, mem_parcel);
+	up_read(&rm_platform_ops_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_platform_pre_mem_share);
+
+int gunyah_rm_platform_post_mem_reclaim(struct gunyah_rm *rm,
+					struct gunyah_rm_mem_parcel *mem_parcel)
+{
+	int ret = 0;
+
+	down_read(&rm_platform_ops_lock);
+	if (rm_platform_ops && rm_platform_ops->post_mem_reclaim)
+		ret = rm_platform_ops->post_mem_reclaim(rm, mem_parcel);
+	up_read(&rm_platform_ops_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_platform_post_mem_reclaim);
+
+int gunyah_rm_platform_pre_demand_page(struct gunyah_rm *rm, u16 vmid,
+				       enum gunyah_pagetable_access access,
+				       struct folio *folio)
+{
+	int ret = 0;
+
+	down_read(&rm_platform_ops_lock);
+	if (rm_platform_ops && rm_platform_ops->pre_demand_page)
+		ret = rm_platform_ops->pre_demand_page(rm, vmid, access, folio);
+	up_read(&rm_platform_ops_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_platform_pre_demand_page);
+
+int gunyah_rm_platform_reclaim_demand_page(struct gunyah_rm *rm, u16 vmid,
+					   enum gunyah_pagetable_access access,
+					   struct folio *folio)
+{
+	int ret = 0;
+
+	down_read(&rm_platform_ops_lock);
+	if (rm_platform_ops && rm_platform_ops->pre_demand_page)
+		ret = rm_platform_ops->release_demand_page(rm, vmid, access,
+							   folio);
+	up_read(&rm_platform_ops_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_platform_reclaim_demand_page);
+
+int gunyah_rm_register_platform_ops(
+	const struct gunyah_rm_platform_ops *platform_ops)
+{
+	int ret = 0;
+
+	down_write(&rm_platform_ops_lock);
+	if (!rm_platform_ops)
+		rm_platform_ops = platform_ops;
+	else
+		ret = -EEXIST;
+	up_write(&rm_platform_ops_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_register_platform_ops);
+
+void gunyah_rm_unregister_platform_ops(
+	const struct gunyah_rm_platform_ops *platform_ops)
+{
+	down_write(&rm_platform_ops_lock);
+	if (rm_platform_ops == platform_ops)
+		rm_platform_ops = NULL;
+	up_write(&rm_platform_ops_lock);
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_unregister_platform_ops);
+
+static void _devm_gunyah_rm_unregister_platform_ops(void *data)
+{
+	gunyah_rm_unregister_platform_ops(
+		(const struct gunyah_rm_platform_ops *)data);
+}
+
+int devm_gunyah_rm_register_platform_ops(
+	struct device *dev, const struct gunyah_rm_platform_ops *ops)
+{
+	int ret;
+
+	ret = gunyah_rm_register_platform_ops(ops);
+	if (ret)
+		return ret;
+
+	return devm_add_action(dev, _devm_gunyah_rm_unregister_platform_ops,
+			       (void *)ops);
+}
+EXPORT_SYMBOL_GPL(devm_gunyah_rm_register_platform_ops);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Gunyah Platform Hooks");
diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h
index ec8ad8149e8ef..68d08d3cff02d 100644
--- a/drivers/virt/gunyah/rsc_mgr.h
+++ b/drivers/virt/gunyah/rsc_mgr.h
@@ -117,4 +117,14 @@ int gunyah_rm_call(struct gunyah_rm *rsc_mgr, u32 message_id,
 		   const void *req_buf, size_t req_buf_size, void **resp_buf,
 		   size_t *resp_buf_size);
 
+int gunyah_rm_platform_pre_mem_share(struct gunyah_rm *rm,
+				     struct gunyah_rm_mem_parcel *mem_parcel);
+int gunyah_rm_platform_post_mem_reclaim(
+	struct gunyah_rm *rm, struct gunyah_rm_mem_parcel *mem_parcel);
+
+int gunyah_rm_platform_pre_demand_page(struct gunyah_rm *rm, u16 vmid,
+				       u32 flags, struct folio *folio);
+int gunyah_rm_platform_reclaim_demand_page(struct gunyah_rm *rm, u16 vmid,
+					   u32 flags, struct folio *folio);
+
 #endif
diff --git a/drivers/virt/gunyah/rsc_mgr_rpc.c b/drivers/virt/gunyah/rsc_mgr_rpc.c
index eb06940bb3c53..99e5a3f1a5bb9 100644
--- a/drivers/virt/gunyah/rsc_mgr_rpc.c
+++ b/drivers/virt/gunyah/rsc_mgr_rpc.c
@@ -209,6 +209,12 @@ int gunyah_rm_mem_share(struct gunyah_rm *rm, struct gunyah_rm_mem_parcel *p)
 	if (!msg)
 		return -ENOMEM;
 
+	ret = gunyah_rm_platform_pre_mem_share(rm, p);
+	if (ret) {
+		kfree(msg);
+		return ret;
+	}
+
 	req_header = msg;
 	acl = (void *)req_header + sizeof(*req_header);
 	mem = (void *)acl + acl_size;
@@ -234,8 +240,10 @@ int gunyah_rm_mem_share(struct gunyah_rm *rm, struct gunyah_rm_mem_parcel *p)
 			     &resp_size);
 	kfree(msg);
 
-	if (ret)
+	if (ret) {
+		gunyah_rm_platform_post_mem_reclaim(rm, p);
 		return ret;
+	}
 
 	p->mem_handle = le32_to_cpu(*resp);
 	kfree(resp);
@@ -267,9 +275,15 @@ int gunyah_rm_mem_reclaim(struct gunyah_rm *rm,
 	struct gunyah_rm_mem_release_req req = {
 		.mem_handle = cpu_to_le32(parcel->mem_handle),
 	};
+	int ret;
 
-	return gunyah_rm_call(rm, GUNYAH_RM_RPC_MEM_RECLAIM, &req, sizeof(req),
-			      NULL, NULL);
+	ret = gunyah_rm_call(rm, GUNYAH_RM_RPC_MEM_RECLAIM, &req, sizeof(req),
+			     NULL, NULL);
+	/* Only call platform mem reclaim hooks if we reclaimed the memory */
+	if (ret)
+		return ret;
+
+	return gunyah_rm_platform_post_mem_reclaim(rm, parcel);
 }
 ALLOW_ERROR_INJECTION(gunyah_rm_mem_reclaim, ERRNO);
 
diff --git a/drivers/virt/gunyah/vm_mgr_mem.c b/drivers/virt/gunyah/vm_mgr_mem.c
index bcc84473004be..5a4ea2b1a12ee 100644
--- a/drivers/virt/gunyah/vm_mgr_mem.c
+++ b/drivers/virt/gunyah/vm_mgr_mem.c
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 
+#include "rsc_mgr.h"
 #include "vm_mgr.h"
 
 #define WRITE_TAG (1 << 0)
@@ -107,7 +108,7 @@ int gunyah_vm_provide_folio(struct gunyah_vm *ghvm, struct folio *folio,
 	size_t size = folio_size(folio);
 	enum gunyah_error gunyah_error;
 	unsigned long tag = 0;
-	int ret;
+	int ret, tmp;
 
 	/* clang-format off */
 	if (share) {
@@ -158,6 +159,11 @@ int gunyah_vm_provide_folio(struct gunyah_vm *ghvm, struct folio *folio,
 	else /* !share && !write */
 		access = GUNYAH_PAGETABLE_ACCESS_RX;
 
+	ret = gunyah_rm_platform_pre_demand_page(ghvm->rm, ghvm->vmid, access,
+						 folio);
+	if (ret)
+		goto reclaim_host;
+
 	gunyah_error = gunyah_hypercall_memextent_donate(donate_flags(share),
 							 host_extent->capid,
 							 guest_extent->capid,
@@ -166,7 +172,7 @@ int gunyah_vm_provide_folio(struct gunyah_vm *ghvm, struct folio *folio,
 		pr_err("Failed to donate memory for guest address 0x%016llx: %d\n",
 		       gpa, gunyah_error);
 		ret = gunyah_error_remap(gunyah_error);
-		goto remove;
+		goto platform_release;
 	}
 
 	extent_attrs =
@@ -197,6 +203,16 @@ int gunyah_vm_provide_folio(struct gunyah_vm *ghvm, struct folio *folio,
 	if (gunyah_error != GUNYAH_ERROR_OK)
 		pr_err("Failed to reclaim memory donation for guest address 0x%016llx: %d\n",
 		       gpa, gunyah_error);
+platform_release:
+	tmp = gunyah_rm_platform_reclaim_demand_page(ghvm->rm, ghvm->vmid,
+						     access, folio);
+	if (tmp) {
+		pr_err("Platform failed to reclaim memory for guest address 0x%016llx: %d",
+		       gpa, tmp);
+		return ret;
+	}
+reclaim_host:
+	gunyah_folio_host_reclaim(folio);
 remove:
 	mtree_erase(&ghvm->mm, gfn);
 	return ret;
@@ -207,6 +223,7 @@ static int __gunyah_vm_reclaim_folio_locked(struct gunyah_vm *ghvm, void *entry,
 {
 	u32 map_flags = BIT(GUNYAH_ADDRSPACE_MAP_FLAG_PARTIAL);
 	struct gunyah_resource *guest_extent, *host_extent, *addrspace;
+	enum gunyah_pagetable_access access;
 	enum gunyah_error gunyah_error;
 	struct folio *folio;
 	bool write, share;
@@ -264,6 +281,24 @@ static int __gunyah_vm_reclaim_folio_locked(struct gunyah_vm *ghvm, void *entry,
 		goto err;
 	}
 
+	if (share && write)
+		access = GUNYAH_PAGETABLE_ACCESS_RW;
+	else if (share && !write)
+		access = GUNYAH_PAGETABLE_ACCESS_R;
+	else if (!share && write)
+		access = GUNYAH_PAGETABLE_ACCESS_RWX;
+	else /* !share && !write */
+		access = GUNYAH_PAGETABLE_ACCESS_RX;
+
+	ret = gunyah_rm_platform_reclaim_demand_page(ghvm->rm, ghvm->vmid,
+						     access, folio);
+	if (ret) {
+		pr_err_ratelimited(
+			"Platform failed to reclaim memory for guest address 0x%016llx: %d",
+			gunyah_gfn_to_gpa(gfn), ret);
+		goto err;
+	}
+
 	BUG_ON(mtree_erase(&ghvm->mm, gfn) != entry);
 
 	if (folio_test_private(folio)) {
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index c23e1a88703e8..cfb80f40d4e4a 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -198,6 +198,57 @@ struct gunyah_rm_mem_parcel {
 	u32 mem_handle;
 };
 
+enum gunyah_pagetable_access {
+	/* clang-format off */
+	GUNYAH_PAGETABLE_ACCESS_NONE		= 0,
+	GUNYAH_PAGETABLE_ACCESS_X		= 1,
+	GUNYAH_PAGETABLE_ACCESS_W		= 2,
+	GUNYAH_PAGETABLE_ACCESS_R		= 4,
+	GUNYAH_PAGETABLE_ACCESS_RX		= 5,
+	GUNYAH_PAGETABLE_ACCESS_RW		= 6,
+	GUNYAH_PAGETABLE_ACCESS_RWX		= 7,
+	/* clang-format on */
+};
+
+struct gunyah_rm_platform_ops {
+	int (*pre_mem_share)(struct gunyah_rm *rm,
+			     struct gunyah_rm_mem_parcel *mem_parcel);
+	int (*post_mem_reclaim)(struct gunyah_rm *rm,
+				struct gunyah_rm_mem_parcel *mem_parcel);
+
+	int (*pre_demand_page)(struct gunyah_rm *rm, u16 vmid,
+			       enum gunyah_pagetable_access access,
+			       struct folio *folio);
+	int (*release_demand_page)(struct gunyah_rm *rm, u16 vmid,
+				   enum gunyah_pagetable_access access,
+				   struct folio *folio);
+};
+
+#if IS_ENABLED(CONFIG_GUNYAH_PLATFORM_HOOKS)
+int gunyah_rm_register_platform_ops(
+	const struct gunyah_rm_platform_ops *platform_ops);
+void gunyah_rm_unregister_platform_ops(
+	const struct gunyah_rm_platform_ops *platform_ops);
+int devm_gunyah_rm_register_platform_ops(
+	struct device *dev, const struct gunyah_rm_platform_ops *ops);
+#else
+static inline int gunyah_rm_register_platform_ops(
+	const struct gunyah_rm_platform_ops *platform_ops)
+{
+	return 0;
+}
+static inline void gunyah_rm_unregister_platform_ops(
+	const struct gunyah_rm_platform_ops *platform_ops)
+{
+}
+static inline int
+devm_gunyah_rm_register_platform_ops(struct device *dev,
+				     const struct gunyah_rm_platform_ops *ops)
+{
+	return 0;
+}
+#endif
+
 /******************************************************************************/
 /* Common arch-independent definitions for Gunyah hypercalls                  */
 #define GUNYAH_CAPID_INVAL U64_MAX
@@ -318,18 +369,6 @@ enum gunyah_error gunyah_hypercall_msgq_recv(u64 capid, void *buff, size_t size,
 
 #define GUNYAH_ADDRSPACE_SELF_CAP 0
 
-enum gunyah_pagetable_access {
-	/* clang-format off */
-	GUNYAH_PAGETABLE_ACCESS_NONE		= 0,
-	GUNYAH_PAGETABLE_ACCESS_X		= 1,
-	GUNYAH_PAGETABLE_ACCESS_W		= 2,
-	GUNYAH_PAGETABLE_ACCESS_R		= 4,
-	GUNYAH_PAGETABLE_ACCESS_RX		= 5,
-	GUNYAH_PAGETABLE_ACCESS_RW		= 6,
-	GUNYAH_PAGETABLE_ACCESS_RWX		= 7,
-	/* clang-format on */
-};
-
 /* clang-format off */
 #define GUNYAH_MEMEXTENT_MAPPING_USER_ACCESS		GENMASK_ULL(2, 0)
 #define GUNYAH_MEMEXTENT_MAPPING_KERNEL_ACCESS		GENMASK_ULL(6, 4)

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:40 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:40 -0800
Subject: [PATCH v17 17/35] gunyah: rsc_mgr: Add memory parcel RPC
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-17-1e9da6763d38@quicinc.com>

In a Gunyah hypervisor system using the Gunyah Resource Manager, the
"standard" unit of donating, lending and sharing memory is called a
memory parcel (memparcel).  A memparcel is an abstraction used by the
resource manager for securely managing donating, lending and sharing
memory, which may be physically and virtually fragmented, without
dealing directly with physical memory addresses.

Memparcels are created and managed through the RM RPC functions for
lending, sharing and reclaiming memory from VMs.

When creating a new VM the initial VM memory containing the VM image and
the VM's device tree blob must be provided as a memparcel. The memparcel
must be created using the RM RPC for lending and mapping the memory to
the VM.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/rsc_mgr.h     |   9 ++
 drivers/virt/gunyah/rsc_mgr_rpc.c | 234 ++++++++++++++++++++++++++++++++++++++
 include/linux/gunyah.h            |  43 +++++++
 3 files changed, 286 insertions(+)

diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h
index 52711de77bb79..ec8ad8149e8ef 100644
--- a/drivers/virt/gunyah/rsc_mgr.h
+++ b/drivers/virt/gunyah/rsc_mgr.h
@@ -10,6 +10,7 @@
 #include <linux/types.h>
 
 #define GUNYAH_VMID_INVAL U16_MAX
+#define GUNYAH_MEM_HANDLE_INVAL U32_MAX
 
 struct gunyah_rm;
 
@@ -58,6 +59,12 @@ struct gunyah_rm_vm_status_payload {
 	__le16 app_status;
 } __packed;
 
+/* RPC Calls */
+int gunyah_rm_mem_share(struct gunyah_rm *rm,
+			struct gunyah_rm_mem_parcel *parcel);
+int gunyah_rm_mem_reclaim(struct gunyah_rm *rm,
+			  struct gunyah_rm_mem_parcel *parcel);
+
 int gunyah_rm_alloc_vmid(struct gunyah_rm *rm, u16 vmid);
 int gunyah_rm_dealloc_vmid(struct gunyah_rm *rm, u16 vmid);
 int gunyah_rm_vm_reset(struct gunyah_rm *rm, u16 vmid);
@@ -99,6 +106,8 @@ struct gunyah_rm_hyp_resources {
 int gunyah_rm_get_hyp_resources(struct gunyah_rm *rm, u16 vmid,
 				struct gunyah_rm_hyp_resources **resources);
 
+int gunyah_rm_get_vmid(struct gunyah_rm *rm, u16 *vmid);
+
 struct gunyah_resource *
 gunyah_rm_alloc_resource(struct gunyah_rm *rm,
 			 struct gunyah_rm_hyp_resource *hyp_resource);
diff --git a/drivers/virt/gunyah/rsc_mgr_rpc.c b/drivers/virt/gunyah/rsc_mgr_rpc.c
index c2f4ccae8f3bc..eb06940bb3c53 100644
--- a/drivers/virt/gunyah/rsc_mgr_rpc.c
+++ b/drivers/virt/gunyah/rsc_mgr_rpc.c
@@ -7,6 +7,12 @@
 
 #include "rsc_mgr.h"
 
+/* Message IDs: Memory Management */
+#define GUNYAH_RM_RPC_MEM_LEND 0x51000012
+#define GUNYAH_RM_RPC_MEM_SHARE 0x51000013
+#define GUNYAH_RM_RPC_MEM_RECLAIM 0x51000015
+#define GUNYAH_RM_RPC_MEM_APPEND 0x51000018
+
 /* Message IDs: VM Management */
 /* clang-format off */
 #define GUNYAH_RM_RPC_VM_ALLOC_VMID		0x56000001
@@ -17,6 +23,7 @@
 #define GUNYAH_RM_RPC_VM_CONFIG_IMAGE		0x56000009
 #define GUNYAH_RM_RPC_VM_INIT			0x5600000B
 #define GUNYAH_RM_RPC_VM_GET_HYP_RESOURCES	0x56000020
+#define GUNYAH_RM_RPC_VM_GET_VMID		0x56000024
 /* clang-format on */
 
 struct gunyah_rm_vm_common_vmid_req {
@@ -24,6 +31,49 @@ struct gunyah_rm_vm_common_vmid_req {
 	__le16 _padding;
 } __packed;
 
+/* Call: MEM_LEND, MEM_SHARE */
+#define GUNYAH_RM_MAX_MEM_ENTRIES 512
+
+#define GUNYAH_MEM_SHARE_REQ_FLAGS_APPEND BIT(1)
+
+struct gunyah_rm_mem_share_req_header {
+	u8 mem_type;
+	u8 _padding0;
+	u8 flags;
+	u8 _padding1;
+	__le32 label;
+} __packed;
+
+struct gunyah_rm_mem_share_req_acl_section {
+	__le16 n_entries;
+	__le16 _padding;
+	struct gunyah_rm_mem_acl_entry entries[];
+} __packed;
+
+struct gunyah_rm_mem_share_req_mem_section {
+	__le16 n_entries;
+	__le16 _padding;
+	struct gunyah_rm_mem_entry entries[];
+} __packed;
+
+/* Call: MEM_RELEASE */
+struct gunyah_rm_mem_release_req {
+	__le32 mem_handle;
+	u8 flags; /* currently not used */
+	u8 _padding0;
+	__le16 _padding1;
+} __packed;
+
+/* Call: MEM_APPEND */
+#define GUNYAH_MEM_APPEND_REQ_FLAGS_END BIT(0)
+
+struct gunyah_rm_mem_append_req_header {
+	__le32 mem_handle;
+	u8 flags;
+	u8 _padding0;
+	__le16 _padding1;
+} __packed;
+
 /* Call: VM_ALLOC */
 struct gunyah_rm_vm_alloc_vmid_resp {
 	__le16 vmid;
@@ -68,6 +118,161 @@ static int gunyah_rm_common_vmid_call(struct gunyah_rm *rm, u32 message_id,
 			      NULL, NULL);
 }
 
+static int gunyah_rm_mem_append(struct gunyah_rm *rm, u32 mem_handle,
+				struct gunyah_rm_mem_entry *entries,
+				size_t n_entries)
+{
+	struct gunyah_rm_mem_append_req_header *req __free(kfree) = NULL;
+	struct gunyah_rm_mem_share_req_mem_section *mem;
+	int ret = 0;
+	size_t n;
+
+	req = kzalloc(sizeof(*req) + struct_size(mem, entries, GUNYAH_RM_MAX_MEM_ENTRIES),
+		      GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	req->mem_handle = cpu_to_le32(mem_handle);
+	mem = (void *)(req + 1);
+
+	while (n_entries) {
+		req->flags = 0;
+		if (n_entries > GUNYAH_RM_MAX_MEM_ENTRIES) {
+			n = GUNYAH_RM_MAX_MEM_ENTRIES;
+		} else {
+			req->flags |= GUNYAH_MEM_APPEND_REQ_FLAGS_END;
+			n = n_entries;
+		}
+
+		mem->n_entries = cpu_to_le16(n);
+		memcpy(mem->entries, entries, sizeof(*entries) * n);
+
+		ret = gunyah_rm_call(rm, GUNYAH_RM_RPC_MEM_APPEND, req,
+				     sizeof(*req) + struct_size(mem, entries, n),
+				     NULL, NULL);
+		if (ret)
+			break;
+
+		entries += n;
+		n_entries -= n;
+	}
+
+	return ret;
+}
+
+/**
+ * gunyah_rm_mem_share() - Share memory with other virtual machines.
+ * @rm: Handle to a Gunyah resource manager
+ * @p: Information about the memory to be shared.
+ *
+ * Sharing keeps Linux's access to the memory while the memory parcel is shared.
+ */
+int gunyah_rm_mem_share(struct gunyah_rm *rm, struct gunyah_rm_mem_parcel *p)
+{
+	u32 message_id = p->n_acl_entries == 1 ? GUNYAH_RM_RPC_MEM_LEND :
+						 GUNYAH_RM_RPC_MEM_SHARE;
+	size_t msg_size, initial_mem_entries = p->n_mem_entries, resp_size;
+	struct gunyah_rm_mem_share_req_acl_section *acl;
+	struct gunyah_rm_mem_share_req_mem_section *mem;
+	struct gunyah_rm_mem_share_req_header *req_header;
+	size_t acl_size, mem_size;
+	u32 *attr_section;
+	bool need_append = false;
+	__le32 *resp;
+	void *msg;
+	int ret;
+
+	if (!p->acl_entries || !p->n_acl_entries || !p->mem_entries ||
+	    !p->n_mem_entries || p->n_acl_entries > U8_MAX ||
+	    p->mem_handle != GUNYAH_MEM_HANDLE_INVAL)
+		return -EINVAL;
+
+	if (initial_mem_entries > GUNYAH_RM_MAX_MEM_ENTRIES) {
+		initial_mem_entries = GUNYAH_RM_MAX_MEM_ENTRIES;
+		need_append = true;
+	}
+
+	acl_size = struct_size(acl, entries, p->n_acl_entries);
+	mem_size = struct_size(mem, entries, initial_mem_entries);
+
+	/* The format of the message goes:
+	 * request header
+	 * ACL entries (which VMs get what kind of access to this memory parcel)
+	 * Memory entries (list of memory regions to share)
+	 * Memory attributes (currently unused, we'll hard-code the size to 0)
+	 */
+	msg_size = sizeof(struct gunyah_rm_mem_share_req_header) + acl_size +
+		   mem_size +
+		   sizeof(u32); /* for memory attributes, currently unused */
+
+	msg = kzalloc(msg_size, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	req_header = msg;
+	acl = (void *)req_header + sizeof(*req_header);
+	mem = (void *)acl + acl_size;
+	attr_section = (void *)mem + mem_size;
+
+	req_header->mem_type = p->mem_type;
+	if (need_append)
+		req_header->flags |= GUNYAH_MEM_SHARE_REQ_FLAGS_APPEND;
+	req_header->label = cpu_to_le32(p->label);
+
+	acl->n_entries = cpu_to_le32(p->n_acl_entries);
+	memcpy(acl->entries, p->acl_entries,
+	       flex_array_size(acl, entries, p->n_acl_entries));
+
+	mem->n_entries = cpu_to_le16(initial_mem_entries);
+	memcpy(mem->entries, p->mem_entries,
+	       flex_array_size(mem, entries, initial_mem_entries));
+
+	/* Set n_entries for memory attribute section to 0 */
+	*attr_section = 0;
+
+	ret = gunyah_rm_call(rm, message_id, msg, msg_size, (void **)&resp,
+			     &resp_size);
+	kfree(msg);
+
+	if (ret)
+		return ret;
+
+	p->mem_handle = le32_to_cpu(*resp);
+	kfree(resp);
+
+	if (need_append) {
+		ret = gunyah_rm_mem_append(
+			rm, p->mem_handle, &p->mem_entries[initial_mem_entries],
+			p->n_mem_entries - initial_mem_entries);
+		if (ret) {
+			gunyah_rm_mem_reclaim(rm, p);
+			p->mem_handle = GUNYAH_MEM_HANDLE_INVAL;
+		}
+	}
+
+	return ret;
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_mem_share, ERRNO);
+
+/**
+ * gunyah_rm_mem_reclaim() - Reclaim a memory parcel
+ * @rm: Handle to a Gunyah resource manager
+ * @parcel: Information about the memory to be reclaimed.
+ *
+ * RM maps the associated memory back into the stage-2 page tables of the owner VM.
+ */
+int gunyah_rm_mem_reclaim(struct gunyah_rm *rm,
+			  struct gunyah_rm_mem_parcel *parcel)
+{
+	struct gunyah_rm_mem_release_req req = {
+		.mem_handle = cpu_to_le32(parcel->mem_handle),
+	};
+
+	return gunyah_rm_call(rm, GUNYAH_RM_RPC_MEM_RECLAIM, &req, sizeof(req),
+			      NULL, NULL);
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_mem_reclaim, ERRNO);
+
 /**
  * gunyah_rm_alloc_vmid() - Allocate a new VM in Gunyah. Returns the VM identifier.
  * @rm: Handle to a Gunyah resource manager
@@ -246,3 +451,32 @@ int gunyah_rm_get_hyp_resources(struct gunyah_rm *rm, u16 vmid,
 	return 0;
 }
 ALLOW_ERROR_INJECTION(gunyah_rm_get_hyp_resources, ERRNO);
+
+/**
+ * gunyah_rm_get_vmid() - Retrieve VMID of this virtual machine
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: Filled with the VMID of this VM
+ */
+int gunyah_rm_get_vmid(struct gunyah_rm *rm, u16 *vmid)
+{
+	static u16 cached_vmid = GUNYAH_VMID_INVAL;
+	size_t resp_size;
+	__le32 *resp;
+	int ret;
+
+	if (cached_vmid != GUNYAH_VMID_INVAL) {
+		*vmid = cached_vmid;
+		return 0;
+	}
+
+	ret = gunyah_rm_call(rm, GUNYAH_RM_RPC_VM_GET_VMID, NULL, 0,
+			     (void **)&resp, &resp_size);
+	if (ret)
+		return ret;
+
+	*vmid = cached_vmid = lower_16_bits(le32_to_cpu(*resp));
+	kfree(resp);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_get_vmid);
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index 24c02c6827738..c23e1a88703e8 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -155,6 +155,49 @@ int gunyah_vm_add_resource_ticket(struct gunyah_vm *ghvm,
 void gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
 				      struct gunyah_vm_resource_ticket *ticket);
 
+#define GUNYAH_RM_ACL_X BIT(0)
+#define GUNYAH_RM_ACL_W BIT(1)
+#define GUNYAH_RM_ACL_R BIT(2)
+
+struct gunyah_rm_mem_acl_entry {
+	__le16 vmid;
+	u8 perms;
+	u8 reserved;
+} __packed;
+
+struct gunyah_rm_mem_entry {
+	__le64 phys_addr;
+	__le64 size;
+} __packed;
+
+enum gunyah_rm_mem_type {
+	GUNYAH_RM_MEM_TYPE_NORMAL = 0,
+	GUNYAH_RM_MEM_TYPE_IO = 1,
+};
+
+/*
+ * struct gunyah_rm_mem_parcel - Info about memory to be lent/shared/donated/reclaimed
+ * @mem_type: The type of memory: normal (DDR) or IO
+ * @label: An client-specified identifier which can be used by the other VMs to identify the purpose
+ *         of the memory parcel.
+ * @n_acl_entries: Count of the number of entries in the @acl_entries array.
+ * @acl_entries: An array of access control entries. Each entry specifies a VM and what access
+ *               is allowed for the memory parcel.
+ * @n_mem_entries: Count of the number of entries in the @mem_entries array.
+ * @mem_entries: An array of regions to be associated with the memory parcel. Addresses should be
+ *               (intermediate) physical addresses from Linux's perspective.
+ * @mem_handle: On success, filled with memory handle that RM allocates for this memory parcel
+ */
+struct gunyah_rm_mem_parcel {
+	enum gunyah_rm_mem_type mem_type;
+	u32 label;
+	size_t n_acl_entries;
+	struct gunyah_rm_mem_acl_entry *acl_entries;
+	size_t n_mem_entries;
+	struct gunyah_rm_mem_entry *mem_entries;
+	u32 mem_handle;
+};
+
 /******************************************************************************/
 /* Common arch-independent definitions for Gunyah hypercalls                  */
 #define GUNYAH_CAPID_INVAL U64_MAX

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:35 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:35 -0800
Subject: [PATCH v17 12/35] virt: gunyah: Add resource tickets
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-12-1e9da6763d38@quicinc.com>

Some VM functions need to acquire Gunyah resources. For instance, Gunyah
vCPUs are exposed to the host as a resource. The Gunyah vCPU function
will register a resource ticket and be able to interact with the
hypervisor once the resource ticket is filled.

Resource tickets are the mechanism for functions to acquire ownership of
Gunyah resources. Gunyah functions can be created before the VM's
resources are created and made available to Linux. A resource ticket
identifies a type of resource and a label of a resource which the ticket
holder is interested in.

Resources are created by Gunyah as configured in the VM's devicetree
configuration. Gunyah doesn't process the label and that makes it
possible for userspace to create multiple resources with the same label.
Resource ticket owners need to be prepared for populate to be called
multiple times if userspace created multiple resources with the same
label.

Reviewed-by: Alex Elder <elder at linaro.org>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/vm_mgr.c | 135 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/virt/gunyah/vm_mgr.h |   7 +++
 include/linux/gunyah.h       |  40 +++++++++++++
 3 files changed, 181 insertions(+), 1 deletion(-)

diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index 364a53cad643e..2cde4d501204a 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -15,6 +15,113 @@
 #include "rsc_mgr.h"
 #include "vm_mgr.h"
 
+int gunyah_vm_add_resource_ticket(struct gunyah_vm *ghvm,
+				  struct gunyah_vm_resource_ticket *ticket)
+{
+	struct gunyah_vm_resource_ticket *iter;
+	struct gunyah_resource *ghrsc, *rsc_iter;
+	int ret = 0;
+
+	mutex_lock(&ghvm->resources_lock);
+	list_for_each_entry(iter, &ghvm->resource_tickets, vm_list) {
+		if (iter->resource_type == ticket->resource_type &&
+		    iter->label == ticket->label) {
+			ret = -EEXIST;
+			goto out;
+		}
+	}
+
+	if (!try_module_get(ticket->owner)) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	list_add(&ticket->vm_list, &ghvm->resource_tickets);
+	INIT_LIST_HEAD(&ticket->resources);
+
+	list_for_each_entry_safe(ghrsc, rsc_iter, &ghvm->resources, list) {
+		if (ghrsc->type == ticket->resource_type &&
+		    ghrsc->rm_label == ticket->label) {
+			if (ticket->populate(ticket, ghrsc))
+				list_move(&ghrsc->list, &ticket->resources);
+		}
+	}
+out:
+	mutex_unlock(&ghvm->resources_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_add_resource_ticket);
+
+static void
+__gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
+				   struct gunyah_vm_resource_ticket *ticket)
+{
+	struct gunyah_resource *ghrsc, *iter;
+
+	list_for_each_entry_safe(ghrsc, iter, &ticket->resources, list) {
+		ticket->unpopulate(ticket, ghrsc);
+		list_move(&ghrsc->list, &ghvm->resources);
+	}
+
+	module_put(ticket->owner);
+	list_del(&ticket->vm_list);
+}
+
+void gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
+				      struct gunyah_vm_resource_ticket *ticket)
+{
+	mutex_lock(&ghvm->resources_lock);
+	__gunyah_vm_remove_resource_ticket(ghvm, ticket);
+	mutex_unlock(&ghvm->resources_lock);
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_remove_resource_ticket);
+
+static void gunyah_vm_add_resource(struct gunyah_vm *ghvm,
+				   struct gunyah_resource *ghrsc)
+{
+	struct gunyah_vm_resource_ticket *ticket;
+
+	mutex_lock(&ghvm->resources_lock);
+	list_for_each_entry(ticket, &ghvm->resource_tickets, vm_list) {
+		if (ghrsc->type == ticket->resource_type &&
+		    ghrsc->rm_label == ticket->label) {
+			if (ticket->populate(ticket, ghrsc))
+				list_add(&ghrsc->list, &ticket->resources);
+			else
+				list_add(&ghrsc->list, &ghvm->resources);
+			/* unconditonal -- we prevent multiple identical
+			 * resource tickets so there will not be some other
+			 * ticket elsewhere in the list if populate() failed.
+			 */
+			goto found;
+		}
+	}
+	list_add(&ghrsc->list, &ghvm->resources);
+found:
+	mutex_unlock(&ghvm->resources_lock);
+}
+
+static void gunyah_vm_clean_resources(struct gunyah_vm *ghvm)
+{
+	struct gunyah_vm_resource_ticket *ticket, *titer;
+	struct gunyah_resource *ghrsc, *riter;
+
+	mutex_lock(&ghvm->resources_lock);
+	if (!list_empty(&ghvm->resource_tickets)) {
+		dev_warn(ghvm->parent, "Dangling resource tickets:\n");
+		list_for_each_entry_safe(ticket, titer, &ghvm->resource_tickets,
+					 vm_list) {
+			dev_warn(ghvm->parent, "  %pS\n", ticket->populate);
+			__gunyah_vm_remove_resource_ticket(ghvm, ticket);
+		}
+	}
+
+	list_for_each_entry_safe(ghrsc, riter, &ghvm->resources, list) {
+		gunyah_rm_free_resource(ghrsc);
+	}
+	mutex_unlock(&ghvm->resources_lock);
+}
+
 static int gunyah_vm_rm_notification_status(struct gunyah_vm *ghvm, void *data)
 {
 	struct gunyah_rm_vm_status_payload *payload = data;
@@ -92,13 +199,18 @@ static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 	init_rwsem(&ghvm->status_lock);
 	init_waitqueue_head(&ghvm->vm_status_wait);
 	ghvm->vm_status = GUNYAH_RM_VM_STATUS_NO_STATE;
+	mutex_init(&ghvm->resources_lock);
+	INIT_LIST_HEAD(&ghvm->resources);
+	INIT_LIST_HEAD(&ghvm->resource_tickets);
 
 	return ghvm;
 }
 
 static int gunyah_vm_start(struct gunyah_vm *ghvm)
 {
-	int ret;
+	struct gunyah_rm_hyp_resources *resources;
+	struct gunyah_resource *ghrsc;
+	int ret, i, n;
 
 	down_write(&ghvm->status_lock);
 	if (ghvm->vm_status != GUNYAH_RM_VM_STATUS_NO_STATE) {
@@ -134,6 +246,25 @@ static int gunyah_vm_start(struct gunyah_vm *ghvm)
 	}
 	ghvm->vm_status = GUNYAH_RM_VM_STATUS_READY;
 
+	ret = gunyah_rm_get_hyp_resources(ghvm->rm, ghvm->vmid, &resources);
+	if (ret) {
+		dev_warn(ghvm->parent,
+			 "Failed to get hypervisor resources for VM: %d\n",
+			 ret);
+		goto err;
+	}
+
+	for (i = 0, n = le32_to_cpu(resources->n_entries); i < n; i++) {
+		ghrsc = gunyah_rm_alloc_resource(ghvm->rm,
+						 &resources->entries[i]);
+		if (!ghrsc) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		gunyah_vm_add_resource(ghvm, ghrsc);
+	}
+
 	ret = gunyah_rm_vm_start(ghvm->rm, ghvm->vmid);
 	if (ret) {
 		dev_warn(ghvm->parent, "Failed to start VM: %d\n", ret);
@@ -207,6 +338,8 @@ static int gunyah_vm_release(struct inode *inode, struct file *filp)
 	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_RUNNING)
 		gunyah_vm_stop(ghvm);
 
+	gunyah_vm_clean_resources(ghvm);
+
 	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_EXITED ||
 	    ghvm->vm_status == GUNYAH_RM_VM_STATUS_READY ||
 	    ghvm->vm_status == GUNYAH_RM_VM_STATUS_INIT_FAILED) {
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index e6cc9aead0b67..0d291f7228859 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -26,6 +26,9 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
  * @vm_status: Current state of the VM, as last reported by RM
  * @vm_status_wait: Wait queue for status @vm_status changes
  * @status_lock: Serializing state transitions
+ * @resource_lock: Serializing addition of resources and resource tickets
+ * @resources: List of &struct gunyah_resource that are associated with this VM
+ * @resource_tickets: List of &struct gunyah_vm_resource_ticket
  * @auth: Authentication mechanism to be used by resource manager when
  *        launching the VM
  *
@@ -39,9 +42,13 @@ struct gunyah_vm {
 	enum gunyah_rm_vm_status vm_status;
 	wait_queue_head_t vm_status_wait;
 	struct rw_semaphore status_lock;
+	struct mutex resources_lock;
+	struct list_head resources;
+	struct list_head resource_tickets;
 
 	struct device *parent;
 	enum gunyah_rm_vm_auth_mechanism auth;
+
 };
 
 #endif
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index 45033bdb5e151..0017691002607 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/limits.h>
+#include <linux/list.h>
 #include <linux/types.h>
 
 /* Matches resource manager's resource types for VM_GET_HYP_RESOURCES RPC */
@@ -30,9 +31,48 @@ struct gunyah_resource {
 	u64 capid;
 	unsigned int irq;
 
+	struct list_head list;
 	u32 rm_label;
 };
 
+struct gunyah_vm;
+
+/**
+ * struct gunyah_vm_resource_ticket - Represents a ticket to reserve access to VM resource(s)
+ * @vm_list: for @gunyah_vm->resource_tickets
+ * @resources: List of resource(s) associated with this ticket
+ *             (members are from @gunyah_resource->list)
+ * @resource_type: Type of resource this ticket reserves
+ * @label: Label of the resource from resource manager this ticket reserves.
+ * @owner: owner of the ticket
+ * @populate: callback provided by the ticket owner and called when a resource is found that
+ *            matches @resource_type and @label. Note that this callback could be called
+ *            multiple times if userspace created mutliple resources with the same type/label.
+ *            This callback may also have significant delay after gunyah_vm_add_resource_ticket()
+ *            since gunyah_vm_add_resource_ticket() could be called before the VM starts.
+ * @unpopulate: callback provided by the ticket owner and called when the ticket owner should no
+ *              longer use the resource provided in the argument. When unpopulate() returns,
+ *              the ticket owner should not be able to use the resource any more as the resource
+ *              might being freed.
+ */
+struct gunyah_vm_resource_ticket {
+	struct list_head vm_list;
+	struct list_head resources;
+	enum gunyah_resource_type resource_type;
+	u32 label;
+
+	struct module *owner;
+	bool (*populate)(struct gunyah_vm_resource_ticket *ticket,
+			 struct gunyah_resource *ghrsc);
+	void (*unpopulate)(struct gunyah_vm_resource_ticket *ticket,
+			   struct gunyah_resource *ghrsc);
+};
+
+int gunyah_vm_add_resource_ticket(struct gunyah_vm *ghvm,
+				  struct gunyah_vm_resource_ticket *ticket);
+void gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
+				      struct gunyah_vm_resource_ticket *ticket);
+
 /******************************************************************************/
 /* Common arch-independent definitions for Gunyah hypercalls                  */
 #define GUNYAH_CAPID_INVAL U64_MAX

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:57 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:57 -0800
Subject: [PATCH v17 34/35] virt: gunyah: Add ioeventfd
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-34-1e9da6763d38@quicinc.com>

Allow userspace to attach an ioeventfd to an mmio address within the
guest.  Userspace provides a description of the type of write to
"subscribe" to and eventfd to trigger when that type of write is
performed by the guest. This mechanism allows userspace to respond
asynchronously to a guest manipulating a virtualized device and is
similar to KVM's ioeventfd.

Reviewed-by: Alex Elder <elder at linaro.org>
Co-developed-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/Kconfig            |   9 +++
 drivers/virt/gunyah/Makefile           |   1 +
 drivers/virt/gunyah/gunyah_ioeventfd.c | 139 +++++++++++++++++++++++++++++++++
 include/uapi/linux/gunyah.h            |  37 +++++++++
 4 files changed, 186 insertions(+)

diff --git a/drivers/virt/gunyah/Kconfig b/drivers/virt/gunyah/Kconfig
index 1685b75fb77a0..855d41a88b160 100644
--- a/drivers/virt/gunyah/Kconfig
+++ b/drivers/virt/gunyah/Kconfig
@@ -36,3 +36,12 @@ config GUNYAH_IRQFD
 	  on Gunyah virtual machine.
 
 	  Say Y/M here if unsure and you want to support Gunyah VMMs.
+
+config GUNYAH_IOEVENTFD
+	tristate "Gunyah ioeventfd interface"
+	depends on GUNYAH
+	help
+	  Enable kernel support for creating ioeventfds which can alert userspace
+	  when a Gunyah virtual machine accesses a memory address.
+
+	  Say Y/M here if unsure and you want to support Gunyah VMMs.
diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
index b41b02792921c..2aec5989402b0 100644
--- a/drivers/virt/gunyah/Makefile
+++ b/drivers/virt/gunyah/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o gunyah_vcpu.o
 obj-$(CONFIG_GUNYAH_PLATFORM_HOOKS) += gunyah_platform_hooks.o
 obj-$(CONFIG_GUNYAH_QCOM_PLATFORM) += gunyah_qcom.o
 obj-$(CONFIG_GUNYAH_IRQFD) += gunyah_irqfd.o
+obj-$(CONFIG_GUNYAH_IOEVENTFD) += gunyah_ioeventfd.o
diff --git a/drivers/virt/gunyah/gunyah_ioeventfd.c b/drivers/virt/gunyah/gunyah_ioeventfd.c
new file mode 100644
index 0000000000000..894d303968c4c
--- /dev/null
+++ b/drivers/virt/gunyah/gunyah_ioeventfd.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/eventfd.h>
+#include <linux/device/driver.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/gunyah.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+
+#include <uapi/linux/gunyah.h>
+
+struct gunyah_ioeventfd {
+	struct gunyah_vm_function_instance *f;
+	struct gunyah_vm_io_handler io_handler;
+
+	struct eventfd_ctx *ctx;
+};
+
+static int gunyah_write_ioeventfd(struct gunyah_vm_io_handler *io_dev, u64 addr,
+				  u32 len, u64 data)
+{
+	struct gunyah_ioeventfd *iofd =
+		container_of(io_dev, struct gunyah_ioeventfd, io_handler);
+
+	eventfd_signal(iofd->ctx);
+	return 0;
+}
+
+static struct gunyah_vm_io_handler_ops io_ops = {
+	.write = gunyah_write_ioeventfd,
+};
+
+static long gunyah_ioeventfd_bind(struct gunyah_vm_function_instance *f)
+{
+	const struct gunyah_fn_ioeventfd_arg *args = f->argp;
+	struct gunyah_ioeventfd *iofd;
+	struct eventfd_ctx *ctx;
+	int ret;
+
+	if (f->arg_size != sizeof(*args))
+		return -EINVAL;
+
+	/* All other flag bits are reserved for future use */
+	if (args->flags & ~GUNYAH_IOEVENTFD_FLAGS_DATAMATCH)
+		return -EINVAL;
+
+	/* must be natural-word sized, or 0 to ignore length */
+	switch (args->len) {
+	case 0:
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* check for range overflow */
+	if (overflows_type(args->addr + args->len, u64))
+		return -EINVAL;
+
+	/* ioeventfd with no length can't be combined with DATAMATCH */
+	if (!args->len && (args->flags & GUNYAH_IOEVENTFD_FLAGS_DATAMATCH))
+		return -EINVAL;
+
+	ctx = eventfd_ctx_fdget(args->fd);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	iofd = kzalloc(sizeof(*iofd), GFP_KERNEL);
+	if (!iofd) {
+		ret = -ENOMEM;
+		goto err_eventfd;
+	}
+
+	f->data = iofd;
+	iofd->f = f;
+
+	iofd->ctx = ctx;
+
+	if (args->flags & GUNYAH_IOEVENTFD_FLAGS_DATAMATCH) {
+		iofd->io_handler.datamatch = true;
+		iofd->io_handler.len = args->len;
+		iofd->io_handler.data = args->datamatch;
+	}
+	iofd->io_handler.addr = args->addr;
+	iofd->io_handler.ops = &io_ops;
+
+	ret = gunyah_vm_add_io_handler(f->ghvm, &iofd->io_handler);
+	if (ret)
+		goto err_io_dev_add;
+
+	return 0;
+
+err_io_dev_add:
+	kfree(iofd);
+err_eventfd:
+	eventfd_ctx_put(ctx);
+	return ret;
+}
+
+static void gunyah_ioevent_unbind(struct gunyah_vm_function_instance *f)
+{
+	struct gunyah_ioeventfd *iofd = f->data;
+
+	gunyah_vm_remove_io_handler(iofd->f->ghvm, &iofd->io_handler);
+	eventfd_ctx_put(iofd->ctx);
+	kfree(iofd);
+}
+
+static bool gunyah_ioevent_compare(const struct gunyah_vm_function_instance *f,
+				   const void *arg, size_t size)
+{
+	const struct gunyah_fn_ioeventfd_arg *instance = f->argp, *other = arg;
+
+	if (sizeof(*other) != size)
+		return false;
+
+	if (instance->addr != other->addr || instance->len != other->len ||
+	    instance->flags != other->flags)
+		return false;
+
+	if ((instance->flags & GUNYAH_IOEVENTFD_FLAGS_DATAMATCH) &&
+	    instance->datamatch != other->datamatch)
+		return false;
+
+	return true;
+}
+
+DECLARE_GUNYAH_VM_FUNCTION_INIT(ioeventfd, GUNYAH_FN_IOEVENTFD, 3,
+				gunyah_ioeventfd_bind, gunyah_ioevent_unbind,
+				gunyah_ioevent_compare);
+MODULE_DESCRIPTION("Gunyah ioeventfd VM Function");
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h
index cb7b0bb9bef38..fd461e2fe8b58 100644
--- a/include/uapi/linux/gunyah.h
+++ b/include/uapi/linux/gunyah.h
@@ -65,10 +65,13 @@ struct gunyah_vm_dtb_config {
  *              Return: file descriptor to manipulate the vcpu.
  * @GUNYAH_FN_IRQFD: register eventfd to assert a Gunyah doorbell
  *               &struct gunyah_fn_desc.arg is a pointer to &struct gunyah_fn_irqfd_arg
+ * @GUNYAH_FN_IOEVENTFD: register ioeventfd to trigger when VM faults on parameter
+ *                   &struct gunyah_fn_desc.arg is a pointer to &struct gunyah_fn_ioeventfd_arg
  */
 enum gunyah_fn_type {
 	GUNYAH_FN_VCPU = 1,
 	GUNYAH_FN_IRQFD,
+	GUNYAH_FN_IOEVENTFD,
 };
 
 #define GUNYAH_FN_MAX_ARG_SIZE		256
@@ -120,6 +123,40 @@ struct gunyah_fn_irqfd_arg {
 	__u32 padding;
 };
 
+/**
+ * enum gunyah_ioeventfd_flags - flags for use in gunyah_fn_ioeventfd_arg
+ * @GUNYAH_IOEVENTFD_FLAGS_DATAMATCH: the event will be signaled only if the
+ *                                written value to the registered address is
+ *                                equal to &struct gunyah_fn_ioeventfd_arg.datamatch
+ */
+enum gunyah_ioeventfd_flags {
+	GUNYAH_IOEVENTFD_FLAGS_DATAMATCH	= 1UL << 0,
+};
+
+/**
+ * struct gunyah_fn_ioeventfd_arg - Arguments to create an ioeventfd function
+ * @datamatch: data used when GUNYAH_IOEVENTFD_DATAMATCH is set
+ * @addr: Address in guest memory
+ * @len: Length of access
+ * @fd: When ioeventfd is matched, this eventfd is written
+ * @flags: See &enum gunyah_ioeventfd_flags
+ * @padding: padding bytes
+ *
+ * Create this function with &GUNYAH_VM_ADD_FUNCTION using type &GUNYAH_FN_IOEVENTFD.
+ *
+ * Attaches an ioeventfd to a legal mmio address within the guest. A guest write
+ * in the registered address will signal the provided event instead of triggering
+ * an exit on the GUNYAH_VCPU_RUN ioctl.
+ */
+struct gunyah_fn_ioeventfd_arg {
+	__u64 datamatch;
+	__u64 addr;        /* legal mmio address */
+	__u32 len;         /* 1, 2, 4, or 8 bytes; or 0 to ignore length */
+	__s32 fd;
+	__u32 flags;
+	__u32 padding;
+};
+
 /**
  * struct gunyah_fn_desc - Arguments to create a VM function
  * @type: Type of the function. See &enum gunyah_fn_type.

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:30 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:30 -0800
Subject: [PATCH v17 07/35] gunyah: rsc_mgr: Add resource manager RPC core
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-7-1e9da6763d38@quicinc.com>

The resource manager is a special virtual machine which is always
running on a Gunyah system. It provides APIs for creating and destroying
VMs, secure memory management, sharing/lending of memory between VMs,
and setup of inter-VM communication. Calls to the resource manager are
made via message queues.

This patch implements the basic probing and RPC mechanism to make those
API calls. Request/response calls can be made with gh_rm_call.
Drivers can also register to notifications pushed by RM via
gh_rm_register_notifier

Specific API calls that resource manager supports will be implemented in
subsequent patches.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/Makefile  |   4 +-
 drivers/virt/gunyah/rsc_mgr.c | 721 ++++++++++++++++++++++++++++++++++++++++++
 drivers/virt/gunyah/rsc_mgr.h |  26 ++
 3 files changed, 750 insertions(+), 1 deletion(-)

diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
index 34f32110faf9a..c2308389f5517 100644
--- a/drivers/virt/gunyah/Makefile
+++ b/drivers/virt/gunyah/Makefile
@@ -1,3 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-$(CONFIG_GUNYAH) += gunyah.o
+gunyah_rsc_mgr-y += rsc_mgr.o
+
+obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o
diff --git a/drivers/virt/gunyah/rsc_mgr.c b/drivers/virt/gunyah/rsc_mgr.c
new file mode 100644
index 0000000000000..4ac946da0ca7f
--- /dev/null
+++ b/drivers/virt/gunyah/rsc_mgr.c
@@ -0,0 +1,721 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/completion.h>
+#include <linux/gunyah.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "rsc_mgr.h"
+
+/* clang-format off */
+#define RM_RPC_API_VERSION_MASK		GENMASK(3, 0)
+#define RM_RPC_HEADER_WORDS_MASK	GENMASK(7, 4)
+#define RM_RPC_API_VERSION		FIELD_PREP(RM_RPC_API_VERSION_MASK, 1)
+#define RM_RPC_HEADER_WORDS		FIELD_PREP(RM_RPC_HEADER_WORDS_MASK, \
+						(sizeof(struct gunyah_rm_rpc_hdr) / sizeof(u32)))
+#define RM_RPC_API			(RM_RPC_API_VERSION | RM_RPC_HEADER_WORDS)
+
+#define RM_RPC_TYPE_CONTINUATION	0x0
+#define RM_RPC_TYPE_REQUEST		0x1
+#define RM_RPC_TYPE_REPLY		0x2
+#define RM_RPC_TYPE_NOTIF		0x3
+#define RM_RPC_TYPE_MASK		GENMASK(1, 0)
+
+#define GUNYAH_RM_MAX_NUM_FRAGMENTS		62
+#define RM_RPC_FRAGMENTS_MASK		GENMASK(7, 2)
+/* clang-format on */
+
+struct gunyah_rm_rpc_hdr {
+	u8 api;
+	u8 type;
+	__le16 seq;
+	__le32 msg_id;
+} __packed;
+
+struct gunyah_rm_rpc_reply_hdr {
+	struct gunyah_rm_rpc_hdr hdr;
+	__le32 err_code; /* GUNYAH_RM_ERROR_* */
+} __packed;
+
+#define GUNYAH_RM_MSGQ_MSG_SIZE 240
+#define GUNYAH_RM_PAYLOAD_SIZE \
+	(GUNYAH_RM_MSGQ_MSG_SIZE - sizeof(struct gunyah_rm_rpc_hdr))
+
+/* RM Error codes */
+enum gunyah_rm_error {
+	/* clang-format off */
+	GUNYAH_RM_ERROR_OK			= 0x0,
+	GUNYAH_RM_ERROR_UNIMPLEMENTED		= 0xFFFFFFFF,
+	GUNYAH_RM_ERROR_NOMEM			= 0x1,
+	GUNYAH_RM_ERROR_NORESOURCE		= 0x2,
+	GUNYAH_RM_ERROR_DENIED			= 0x3,
+	GUNYAH_RM_ERROR_INVALID			= 0x4,
+	GUNYAH_RM_ERROR_BUSY			= 0x5,
+	GUNYAH_RM_ERROR_ARGUMENT_INVALID	= 0x6,
+	GUNYAH_RM_ERROR_HANDLE_INVALID		= 0x7,
+	GUNYAH_RM_ERROR_VALIDATE_FAILED		= 0x8,
+	GUNYAH_RM_ERROR_MAP_FAILED		= 0x9,
+	GUNYAH_RM_ERROR_MEM_INVALID		= 0xA,
+	GUNYAH_RM_ERROR_MEM_INUSE		= 0xB,
+	GUNYAH_RM_ERROR_MEM_RELEASED		= 0xC,
+	GUNYAH_RM_ERROR_VMID_INVALID		= 0xD,
+	GUNYAH_RM_ERROR_LOOKUP_FAILED		= 0xE,
+	GUNYAH_RM_ERROR_IRQ_INVALID		= 0xF,
+	GUNYAH_RM_ERROR_IRQ_INUSE		= 0x10,
+	GUNYAH_RM_ERROR_IRQ_RELEASED		= 0x11,
+	/* clang-format on */
+};
+
+/**
+ * struct gunyah_rm_message - Represents a complete message from resource manager
+ * @payload: Combined payload of all the fragments (msg headers stripped off).
+ * @size: Size of the payload received so far.
+ * @msg_id: Message ID from the header.
+ * @type: RM_RPC_TYPE_REPLY or RM_RPC_TYPE_NOTIF.
+ * @num_fragments: total number of fragments expected to be received.
+ * @fragments_received: fragments received so far.
+ * @reply: Fields used for request/reply sequences
+ */
+struct gunyah_rm_message {
+	void *payload;
+	size_t size;
+	u32 msg_id;
+	u8 type;
+
+	u8 num_fragments;
+	u8 fragments_received;
+
+	/**
+	 * @ret: Linux return code, there was an error processing message
+	 * @seq: Sequence ID for the main message.
+	 * @rm_error: For request/reply sequences with standard replies
+	 * @seq_done: Signals caller that the RM reply has been received
+	 */
+	struct {
+		int ret;
+		u16 seq;
+		enum gunyah_rm_error rm_error;
+		struct completion seq_done;
+	} reply;
+};
+
+/**
+ * struct gunyah_rm - private data for communicating w/Gunyah resource manager
+ * @dev: pointer to RM platform device
+ * @tx_ghrsc: message queue resource to TX to RM
+ * @rx_ghrsc: message queue resource to RX from RM
+ * @active_rx_message: ongoing gunyah_rm_message for which we're receiving fragments
+ * @call_xarray: xarray to allocate & lookup sequence IDs for Request/Response flows
+ * @next_seq: next ID to allocate (for xa_alloc_cyclic)
+ * @recv_msg: cached allocation for Rx messages
+ * @send_msg: cached allocation for Tx messages. Must hold @send_lock to manipulate.
+ * @send_lock: synchronization to allow only one request to be sent at a time
+ * @send_ready: completed when we know Tx message queue can take more messages
+ * @nh: notifier chain for clients interested in RM notification messages
+ */
+struct gunyah_rm {
+	struct device *dev;
+	struct gunyah_resource tx_ghrsc;
+	struct gunyah_resource rx_ghrsc;
+	struct gunyah_rm_message *active_rx_message;
+
+	struct xarray call_xarray;
+	u32 next_seq;
+
+	unsigned char recv_msg[GUNYAH_RM_MSGQ_MSG_SIZE];
+	unsigned char send_msg[GUNYAH_RM_MSGQ_MSG_SIZE];
+	struct mutex send_lock;
+	struct completion send_ready;
+	struct blocking_notifier_head nh;
+};
+
+/**
+ * gunyah_rm_error_remap() - Remap Gunyah resource manager errors into a Linux error code
+ * @rm_error: "Standard" return value from Gunyah resource manager
+ */
+static inline int gunyah_rm_error_remap(enum gunyah_rm_error rm_error)
+{
+	switch (rm_error) {
+	case GUNYAH_RM_ERROR_OK:
+		return 0;
+	case GUNYAH_RM_ERROR_UNIMPLEMENTED:
+		return -EOPNOTSUPP;
+	case GUNYAH_RM_ERROR_NOMEM:
+		return -ENOMEM;
+	case GUNYAH_RM_ERROR_NORESOURCE:
+		return -ENODEV;
+	case GUNYAH_RM_ERROR_DENIED:
+		return -EPERM;
+	case GUNYAH_RM_ERROR_BUSY:
+		return -EBUSY;
+	case GUNYAH_RM_ERROR_INVALID:
+	case GUNYAH_RM_ERROR_ARGUMENT_INVALID:
+	case GUNYAH_RM_ERROR_HANDLE_INVALID:
+	case GUNYAH_RM_ERROR_VALIDATE_FAILED:
+	case GUNYAH_RM_ERROR_MAP_FAILED:
+	case GUNYAH_RM_ERROR_MEM_INVALID:
+	case GUNYAH_RM_ERROR_MEM_INUSE:
+	case GUNYAH_RM_ERROR_MEM_RELEASED:
+	case GUNYAH_RM_ERROR_VMID_INVALID:
+	case GUNYAH_RM_ERROR_LOOKUP_FAILED:
+	case GUNYAH_RM_ERROR_IRQ_INVALID:
+	case GUNYAH_RM_ERROR_IRQ_INUSE:
+	case GUNYAH_RM_ERROR_IRQ_RELEASED:
+		return -EINVAL;
+	default:
+		return -EBADMSG;
+	}
+}
+
+static int gunyah_rm_init_message_payload(struct gunyah_rm_message *message,
+					  const void *msg, size_t hdr_size,
+					  size_t msg_size)
+{
+	const struct gunyah_rm_rpc_hdr *hdr = msg;
+	size_t max_buf_size, payload_size;
+
+	if (msg_size < hdr_size)
+		return -EINVAL;
+
+	payload_size = msg_size - hdr_size;
+
+	message->num_fragments = FIELD_GET(RM_RPC_FRAGMENTS_MASK, hdr->type);
+	message->fragments_received = 0;
+
+	/* There's not going to be any payload, no need to allocate buffer. */
+	if (!payload_size && !message->num_fragments)
+		return 0;
+
+	if (message->num_fragments > GUNYAH_RM_MAX_NUM_FRAGMENTS)
+		return -EINVAL;
+
+	max_buf_size = payload_size +
+		       (message->num_fragments * GUNYAH_RM_PAYLOAD_SIZE);
+
+	message->payload = kzalloc(max_buf_size, GFP_KERNEL);
+	if (!message->payload)
+		return -ENOMEM;
+
+	memcpy(message->payload, msg + hdr_size, payload_size);
+	message->size = payload_size;
+	return 0;
+}
+
+static void gunyah_rm_abort_message(struct gunyah_rm *rm)
+{
+	kfree(rm->active_rx_message->payload);
+
+	switch (rm->active_rx_message->type) {
+	case RM_RPC_TYPE_REPLY:
+		rm->active_rx_message->reply.ret = -EIO;
+		complete(&rm->active_rx_message->reply.seq_done);
+		break;
+	case RM_RPC_TYPE_NOTIF:
+		fallthrough;
+	default:
+		kfree(rm->active_rx_message);
+	}
+
+	rm->active_rx_message = NULL;
+}
+
+static inline void gunyah_rm_try_complete_message(struct gunyah_rm *rm)
+{
+	struct gunyah_rm_message *message = rm->active_rx_message;
+
+	if (!message || message->fragments_received != message->num_fragments)
+		return;
+
+	switch (message->type) {
+	case RM_RPC_TYPE_REPLY:
+		complete(&message->reply.seq_done);
+		break;
+	case RM_RPC_TYPE_NOTIF:
+		blocking_notifier_call_chain(&rm->nh, message->msg_id,
+					     message->payload);
+
+		kfree(message->payload);
+		kfree(message);
+		break;
+	default:
+		dev_err_ratelimited(rm->dev,
+				    "Invalid message type (%u) received\n",
+				    message->type);
+		gunyah_rm_abort_message(rm);
+		break;
+	}
+
+	rm->active_rx_message = NULL;
+}
+
+static void gunyah_rm_process_notif(struct gunyah_rm *rm, const void *msg,
+				    size_t msg_size)
+{
+	const struct gunyah_rm_rpc_hdr *hdr = msg;
+	struct gunyah_rm_message *message;
+	int ret;
+
+	if (rm->active_rx_message) {
+		dev_err(rm->dev,
+			"Unexpected new notification, still processing an active message");
+		gunyah_rm_abort_message(rm);
+	}
+
+	message = kzalloc(sizeof(*message), GFP_KERNEL);
+	if (!message)
+		return;
+
+	message->type = RM_RPC_TYPE_NOTIF;
+	message->msg_id = le32_to_cpu(hdr->msg_id);
+
+	ret = gunyah_rm_init_message_payload(message, msg, sizeof(*hdr),
+					     msg_size);
+	if (ret) {
+		dev_err(rm->dev,
+			"Failed to initialize message for notification: %d\n",
+			ret);
+		kfree(message);
+		return;
+	}
+
+	rm->active_rx_message = message;
+
+	gunyah_rm_try_complete_message(rm);
+}
+
+static void gunyah_rm_process_reply(struct gunyah_rm *rm, const void *msg,
+				    size_t msg_size)
+{
+	const struct gunyah_rm_rpc_reply_hdr *reply_hdr = msg;
+	struct gunyah_rm_message *message;
+	u16 seq_id;
+
+	seq_id = le16_to_cpu(reply_hdr->hdr.seq);
+	message = xa_load(&rm->call_xarray, seq_id);
+
+	if (!message || message->msg_id != le32_to_cpu(reply_hdr->hdr.msg_id))
+		return;
+
+	if (rm->active_rx_message) {
+		dev_err(rm->dev,
+			"Unexpected new reply, still processing an active message");
+		gunyah_rm_abort_message(rm);
+	}
+
+	if (gunyah_rm_init_message_payload(message, msg, sizeof(*reply_hdr),
+					   msg_size)) {
+		dev_err(rm->dev,
+			"Failed to alloc message buffer for sequence %d\n",
+			seq_id);
+		/* Send message complete and error the client. */
+		message->reply.ret = -ENOMEM;
+		complete(&message->reply.seq_done);
+		return;
+	}
+
+	message->reply.rm_error = le32_to_cpu(reply_hdr->err_code);
+	rm->active_rx_message = message;
+
+	gunyah_rm_try_complete_message(rm);
+}
+
+static void gunyah_rm_process_cont(struct gunyah_rm *rm,
+				   struct gunyah_rm_message *message,
+				   const void *msg, size_t msg_size)
+{
+	const struct gunyah_rm_rpc_hdr *hdr = msg;
+	size_t payload_size = msg_size - sizeof(*hdr);
+
+	if (!rm->active_rx_message)
+		return;
+
+	/*
+	 * hdr->fragments and hdr->msg_id preserves the value from first reply
+	 * or notif message. To detect mishandling, check it's still intact.
+	 */
+	if (message->msg_id != le32_to_cpu(hdr->msg_id) ||
+	    message->num_fragments !=
+		    FIELD_GET(RM_RPC_FRAGMENTS_MASK, hdr->type)) {
+		gunyah_rm_abort_message(rm);
+		return;
+	}
+
+	memcpy(message->payload + message->size, msg + sizeof(*hdr),
+	       payload_size);
+	message->size += payload_size;
+	message->fragments_received++;
+
+	gunyah_rm_try_complete_message(rm);
+}
+
+static irqreturn_t gunyah_rm_rx(int irq, void *data)
+{
+	enum gunyah_error gunyah_error;
+	struct gunyah_rm_rpc_hdr *hdr;
+	struct gunyah_rm *rm = data;
+	void *msg = &rm->recv_msg[0];
+	size_t len;
+	bool ready;
+
+	do {
+		gunyah_error = gunyah_hypercall_msgq_recv(rm->rx_ghrsc.capid,
+							  msg,
+							  sizeof(rm->recv_msg),
+							  &len, &ready);
+		if (gunyah_error != GUNYAH_ERROR_OK) {
+			if (gunyah_error != GUNYAH_ERROR_MSGQUEUE_EMPTY)
+				dev_warn(rm->dev,
+					 "Failed to receive data: %d\n",
+					 gunyah_error);
+			return IRQ_HANDLED;
+		}
+
+		if (len < sizeof(*hdr)) {
+			dev_err_ratelimited(
+				rm->dev,
+				"Too small message received. size=%ld\n", len);
+			continue;
+		}
+
+		hdr = msg;
+		if (hdr->api != RM_RPC_API) {
+			dev_err(rm->dev, "Unknown RM RPC API version: %x\n",
+				hdr->api);
+			return IRQ_HANDLED;
+		}
+
+		switch (FIELD_GET(RM_RPC_TYPE_MASK, hdr->type)) {
+		case RM_RPC_TYPE_NOTIF:
+			gunyah_rm_process_notif(rm, msg, len);
+			break;
+		case RM_RPC_TYPE_REPLY:
+			gunyah_rm_process_reply(rm, msg, len);
+			break;
+		case RM_RPC_TYPE_CONTINUATION:
+			gunyah_rm_process_cont(rm, rm->active_rx_message, msg,
+					       len);
+			break;
+		default:
+			dev_err(rm->dev,
+				"Invalid message type (%lu) received\n",
+				FIELD_GET(RM_RPC_TYPE_MASK, hdr->type));
+			return IRQ_HANDLED;
+		}
+	} while (ready);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t gunyah_rm_tx(int irq, void *data)
+{
+	struct gunyah_rm *rm = data;
+
+	complete(&rm->send_ready);
+
+	return IRQ_HANDLED;
+}
+
+static int gunyah_rm_msgq_send(struct gunyah_rm *rm, size_t size, bool push)
+{
+	const u64 tx_flags = push ? GUNYAH_HYPERCALL_MSGQ_TX_FLAGS_PUSH : 0;
+	enum gunyah_error gunyah_error;
+	void *data = &rm->send_msg[0];
+	bool ready;
+
+	lockdep_assert_held(&rm->send_lock);
+
+again:
+	wait_for_completion(&rm->send_ready);
+	gunyah_error = gunyah_hypercall_msgq_send(rm->tx_ghrsc.capid, size,
+						  data, tx_flags, &ready);
+
+	/* Should never happen because Linux properly tracks the ready-state of the msgq */
+	if (WARN_ON(gunyah_error == GUNYAH_ERROR_MSGQUEUE_FULL))
+		goto again;
+
+	if (ready)
+		complete(&rm->send_ready);
+
+	return gunyah_error_remap(gunyah_error);
+}
+
+static int gunyah_rm_send_request(struct gunyah_rm *rm, u32 message_id,
+				  const void *req_buf, size_t req_buf_size,
+				  struct gunyah_rm_message *message)
+{
+	size_t buf_size_remaining = req_buf_size;
+	const void *req_buf_curr = req_buf;
+	struct gunyah_rm_rpc_hdr *hdr =
+		(struct gunyah_rm_rpc_hdr *)&rm->send_msg[0];
+	struct gunyah_rm_rpc_hdr hdr_template;
+	void *payload = hdr + 1;
+	u32 cont_fragments = 0;
+	size_t payload_size;
+	bool push;
+	int ret;
+
+	if (req_buf_size >
+	    GUNYAH_RM_MAX_NUM_FRAGMENTS * GUNYAH_RM_PAYLOAD_SIZE) {
+		dev_warn(
+			rm->dev,
+			"Limit (%lu bytes) exceeded for the maximum message size: %lu\n",
+			GUNYAH_RM_MAX_NUM_FRAGMENTS * GUNYAH_RM_PAYLOAD_SIZE,
+			req_buf_size);
+		dump_stack();
+		return -E2BIG;
+	}
+
+	if (req_buf_size)
+		cont_fragments = (req_buf_size - 1) / GUNYAH_RM_PAYLOAD_SIZE;
+
+	hdr_template.api = RM_RPC_API;
+	hdr_template.type = FIELD_PREP(RM_RPC_TYPE_MASK, RM_RPC_TYPE_REQUEST) |
+			    FIELD_PREP(RM_RPC_FRAGMENTS_MASK, cont_fragments);
+	hdr_template.seq = cpu_to_le16(message->reply.seq);
+	hdr_template.msg_id = cpu_to_le32(message_id);
+
+	ret = mutex_lock_interruptible(&rm->send_lock);
+	if (ret)
+		return ret;
+
+	do {
+		*hdr = hdr_template;
+
+		/* Copy payload */
+		payload_size = min(buf_size_remaining, GUNYAH_RM_PAYLOAD_SIZE);
+		memcpy(payload, req_buf_curr, payload_size);
+		req_buf_curr += payload_size;
+		buf_size_remaining -= payload_size;
+
+		/* Only the last message should have push flag set */
+		push = !buf_size_remaining;
+		ret = gunyah_rm_msgq_send(rm, sizeof(*hdr) + payload_size,
+					  push);
+		if (ret)
+			break;
+
+		hdr_template.type =
+			FIELD_PREP(RM_RPC_TYPE_MASK, RM_RPC_TYPE_CONTINUATION) |
+			FIELD_PREP(RM_RPC_FRAGMENTS_MASK, cont_fragments);
+	} while (buf_size_remaining);
+
+	mutex_unlock(&rm->send_lock);
+	return ret;
+}
+
+/**
+ * gunyah_rm_call: Achieve request-response type communication with RPC
+ * @rm: Pointer to Gunyah resource manager internal data
+ * @message_id: The RM RPC message-id
+ * @req_buf: Request buffer that contains the payload
+ * @req_buf_size: Total size of the payload
+ * @resp_buf: Pointer to a response buffer
+ * @resp_buf_size: Size of the response buffer
+ *
+ * Make a request to the Resource Manager and wait for reply back. For a successful
+ * response, the function returns the payload. The size of the payload is set in
+ * resp_buf_size. The resp_buf must be freed by the caller when 0 is returned
+ * and resp_buf_size != 0.
+ *
+ * req_buf should be not NULL for req_buf_size >0. If req_buf_size == 0,
+ * req_buf *can* be NULL and no additional payload is sent.
+ *
+ * Context: Process context. Will sleep waiting for reply.
+ * Return: 0 on success. <0 if error.
+ */
+int gunyah_rm_call(struct gunyah_rm *rm, u32 message_id, const void *req_buf,
+		   size_t req_buf_size, void **resp_buf, size_t *resp_buf_size)
+{
+	struct gunyah_rm_message message = { 0 };
+	u32 seq_id;
+	int ret;
+
+	/* message_id 0 is reserved. req_buf_size implies req_buf is not NULL */
+	if (!rm || !message_id || (!req_buf && req_buf_size))
+		return -EINVAL;
+
+	message.type = RM_RPC_TYPE_REPLY;
+	message.msg_id = message_id;
+
+	message.reply.seq_done =
+		COMPLETION_INITIALIZER_ONSTACK(message.reply.seq_done);
+
+	/* Allocate a new seq number for this message */
+	ret = xa_alloc_cyclic(&rm->call_xarray, &seq_id, &message, xa_limit_16b,
+			      &rm->next_seq, GFP_KERNEL);
+	if (ret < 0)
+		return ret;
+	message.reply.seq = lower_16_bits(seq_id);
+
+	/* Send the request to the Resource Manager */
+	ret = gunyah_rm_send_request(rm, message_id, req_buf, req_buf_size,
+				     &message);
+	if (ret < 0) {
+		dev_warn(rm->dev, "Failed to send request. Error: %d\n", ret);
+		goto out;
+	}
+
+	/*
+	 * Wait for response. Uninterruptible because rollback based on what RM did to VM
+	 * requires us to know how RM handled the call.
+	 */
+	wait_for_completion(&message.reply.seq_done);
+
+	/* Check for internal (kernel) error waiting for the response */
+	if (message.reply.ret) {
+		ret = message.reply.ret;
+		goto out;
+	}
+
+	/* Got a response, did resource manager give us an error? */
+	if (message.reply.rm_error != GUNYAH_RM_ERROR_OK) {
+		dev_warn(rm->dev, "RM rejected message %08x. Error: %d\n",
+			 message_id, message.reply.rm_error);
+		ret = gunyah_rm_error_remap(message.reply.rm_error);
+		kfree(message.payload);
+		goto out;
+	}
+
+	/* Everything looks good, return the payload */
+	if (resp_buf_size)
+		*resp_buf_size = message.size;
+
+	if (message.size && resp_buf) {
+		*resp_buf = message.payload;
+	} else {
+		/* kfree in case RM sent us multiple fragments but never any data in
+		 * those fragments. We would've allocated memory for it, but message.size == 0
+		 */
+		kfree(message.payload);
+	}
+
+out:
+	xa_erase(&rm->call_xarray, message.reply.seq);
+	return ret;
+}
+
+int gunyah_rm_notifier_register(struct gunyah_rm *rm, struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&rm->nh, nb);
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_notifier_register);
+
+int gunyah_rm_notifier_unregister(struct gunyah_rm *rm,
+				  struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&rm->nh, nb);
+}
+EXPORT_SYMBOL_GPL(gunyah_rm_notifier_unregister);
+
+static int gunyah_platform_probe_capability(struct platform_device *pdev,
+					    int idx,
+					    struct gunyah_resource *ghrsc)
+{
+	int ret;
+
+	ghrsc->irq = platform_get_irq(pdev, idx);
+	if (ghrsc->irq < 0) {
+		dev_err(&pdev->dev, "Failed to get %s irq: %d\n",
+			idx ? "rx" : "tx", ghrsc->irq);
+		return ghrsc->irq;
+	}
+
+	ret = of_property_read_u64_index(pdev->dev.of_node, "reg", idx,
+					 &ghrsc->capid);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to get %s capid: %d\n",
+			idx ? "rx" : "tx", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int gunyah_rm_probe_tx_msgq(struct gunyah_rm *rm,
+				   struct platform_device *pdev)
+{
+	int ret;
+
+	rm->tx_ghrsc.type = GUNYAH_RESOURCE_TYPE_MSGQ_TX;
+	ret = gunyah_platform_probe_capability(pdev, 0, &rm->tx_ghrsc);
+	if (ret)
+		return ret;
+
+	enable_irq_wake(rm->tx_ghrsc.irq);
+
+	return devm_request_irq(rm->dev, rm->tx_ghrsc.irq, gunyah_rm_tx, 0,
+				"gunyah_rm_tx", rm);
+}
+
+static int gunyah_rm_probe_rx_msgq(struct gunyah_rm *rm,
+				   struct platform_device *pdev)
+{
+	int ret;
+
+	rm->rx_ghrsc.type = GUNYAH_RESOURCE_TYPE_MSGQ_RX;
+	ret = gunyah_platform_probe_capability(pdev, 1, &rm->rx_ghrsc);
+	if (ret)
+		return ret;
+
+	enable_irq_wake(rm->rx_ghrsc.irq);
+
+	return devm_request_threaded_irq(rm->dev, rm->rx_ghrsc.irq, NULL,
+					 gunyah_rm_rx, IRQF_ONESHOT,
+					 "gunyah_rm_rx", rm);
+}
+
+static int gunyah_rm_probe(struct platform_device *pdev)
+{
+	struct gunyah_rm *rm;
+	int ret;
+
+	rm = devm_kzalloc(&pdev->dev, sizeof(*rm), GFP_KERNEL);
+	if (!rm)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, rm);
+	rm->dev = &pdev->dev;
+
+	mutex_init(&rm->send_lock);
+	init_completion(&rm->send_ready);
+	BLOCKING_INIT_NOTIFIER_HEAD(&rm->nh);
+	xa_init_flags(&rm->call_xarray, XA_FLAGS_ALLOC);
+
+	device_init_wakeup(&pdev->dev, true);
+
+	ret = gunyah_rm_probe_tx_msgq(rm, pdev);
+	if (ret)
+		return ret;
+	/* assume RM is ready to receive messages from us */
+	complete(&rm->send_ready);
+
+	ret = gunyah_rm_probe_rx_msgq(rm, pdev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct of_device_id gunyah_rm_of_match[] = {
+	{ .compatible = "gunyah-resource-manager" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, gunyah_rm_of_match);
+
+static struct platform_driver gunyah_rm_driver = {
+	.probe = gunyah_rm_probe,
+	.driver = {
+		.name = "gunyah_rsc_mgr",
+		.of_match_table = gunyah_rm_of_match,
+	},
+};
+module_platform_driver(gunyah_rm_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Gunyah Resource Manager Driver");
diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h
new file mode 100644
index 0000000000000..48b69dbf2190b
--- /dev/null
+++ b/drivers/virt/gunyah/rsc_mgr.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef __GUNYAH_RSC_MGR_PRIV_H
+#define __GUNYAH_RSC_MGR_PRIV_H
+
+#include <linux/gunyah.h>
+#include <linux/notifier.h>
+#include <linux/types.h>
+
+#define GUNYAH_VMID_INVAL U16_MAX
+
+struct gunyah_rm;
+
+int gunyah_rm_notifier_register(struct gunyah_rm *rm,
+				struct notifier_block *nb);
+int gunyah_rm_notifier_unregister(struct gunyah_rm *rm,
+				  struct notifier_block *nb);
+
+
+int gunyah_rm_call(struct gunyah_rm *rsc_mgr, u32 message_id,
+		   const void *req_buf, size_t req_buf_size, void **resp_buf,
+		   size_t *resp_buf_size);
+
+#endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:56 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:56 -0800
Subject: [PATCH v17 33/35] virt: gunyah: Add IO handlers
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-33-1e9da6763d38@quicinc.com>

Add framework for VM functions to handle stage-2 write faults from Gunyah
guest virtual machines. IO handlers have a range of addresses which they
apply to. Optionally, they may apply to only when the value written
matches the IO handler's value.

Reviewed-by: Alex Elder <elder at linaro.org>
Co-developed-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/gunyah_vcpu.c |   4 ++
 drivers/virt/gunyah/vm_mgr.c      | 115 ++++++++++++++++++++++++++++++++++++++
 drivers/virt/gunyah/vm_mgr.h      |   8 +++
 include/linux/gunyah.h            |  29 ++++++++++
 4 files changed, 156 insertions(+)

diff --git a/drivers/virt/gunyah/gunyah_vcpu.c b/drivers/virt/gunyah/gunyah_vcpu.c
index f8306620b1dd6..ef78503fe586d 100644
--- a/drivers/virt/gunyah/gunyah_vcpu.c
+++ b/drivers/virt/gunyah/gunyah_vcpu.c
@@ -133,6 +133,10 @@ gunyah_handle_mmio(struct gunyah_vcpu *vcpu, unsigned long resume_data[3],
 		vcpu->state = GUNYAH_VCPU_RUN_STATE_MMIO_READ;
 		vcpu->mmio_read_len = len;
 	} else { /* GUNYAH_VCPU_ADDRSPACE_VMMIO_WRITE */
+		if (!gunyah_vm_mmio_write(vcpu->ghvm, addr, len, data)) {
+			resume_data[0] = GUNYAH_ADDRSPACE_VMMIO_ACTION_EMULATE;
+			return true;
+		}
 		vcpu->vcpu_run->mmio.is_write = 1;
 		memcpy(vcpu->vcpu_run->mmio.data, &data, len);
 		vcpu->state = GUNYAH_VCPU_RUN_STATE_MMIO_WRITE;
diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index a61a3f3ae92f1..2434be5dffe08 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -302,6 +302,118 @@ static void gunyah_vm_clean_resources(struct gunyah_vm *ghvm)
 	mutex_unlock(&ghvm->resources_lock);
 }
 
+static int _gunyah_vm_io_handler_compare(const struct rb_node *node,
+					 const struct rb_node *parent)
+{
+	struct gunyah_vm_io_handler *n =
+		container_of(node, struct gunyah_vm_io_handler, node);
+	struct gunyah_vm_io_handler *p =
+		container_of(parent, struct gunyah_vm_io_handler, node);
+
+	if (n->addr < p->addr)
+		return -1;
+	if (n->addr > p->addr)
+		return 1;
+	if ((n->len && !p->len) || (!n->len && p->len))
+		return 0;
+	if (n->len < p->len)
+		return -1;
+	if (n->len > p->len)
+		return 1;
+	/* one of the io handlers doesn't have datamatch and the other does.
+	 * For purposes of comparison, that makes them identical since the
+	 * one that doesn't have datamatch will cover the same handler that
+	 * does.
+	 */
+	if (n->datamatch != p->datamatch)
+		return 0;
+	if (n->data < p->data)
+		return -1;
+	if (n->data > p->data)
+		return 1;
+	return 0;
+}
+
+static int gunyah_vm_io_handler_compare(struct rb_node *node,
+					const struct rb_node *parent)
+{
+	return _gunyah_vm_io_handler_compare(node, parent);
+}
+
+static int gunyah_vm_io_handler_find(const void *key,
+				     const struct rb_node *node)
+{
+	const struct gunyah_vm_io_handler *k = key;
+
+	return _gunyah_vm_io_handler_compare(&k->node, node);
+}
+
+static struct gunyah_vm_io_handler *
+gunyah_vm_mgr_find_io_hdlr(struct gunyah_vm *ghvm, u64 addr, u64 len, u64 data)
+{
+	struct gunyah_vm_io_handler key = {
+		.addr = addr,
+		.len = len,
+		.datamatch = true,
+		.data = data,
+	};
+	struct rb_node *node;
+
+	node = rb_find(&key, &ghvm->mmio_handler_root,
+		       gunyah_vm_io_handler_find);
+	if (!node)
+		return NULL;
+
+	return container_of(node, struct gunyah_vm_io_handler, node);
+}
+
+int gunyah_vm_mmio_write(struct gunyah_vm *ghvm, u64 addr, u32 len, u64 data)
+{
+	struct gunyah_vm_io_handler *io_hdlr = NULL;
+	int ret;
+
+	down_read(&ghvm->mmio_handler_lock);
+	io_hdlr = gunyah_vm_mgr_find_io_hdlr(ghvm, addr, len, data);
+	if (!io_hdlr || !io_hdlr->ops || !io_hdlr->ops->write) {
+		ret = -ENOENT;
+		goto out;
+	}
+
+	ret = io_hdlr->ops->write(io_hdlr, addr, len, data);
+
+out:
+	up_read(&ghvm->mmio_handler_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_mmio_write);
+
+int gunyah_vm_add_io_handler(struct gunyah_vm *ghvm,
+			     struct gunyah_vm_io_handler *io_hdlr)
+{
+	struct rb_node *found;
+
+	if (io_hdlr->datamatch &&
+	    (!io_hdlr->len || io_hdlr->len > sizeof(io_hdlr->data)))
+		return -EINVAL;
+
+	down_write(&ghvm->mmio_handler_lock);
+	found = rb_find_add(&io_hdlr->node, &ghvm->mmio_handler_root,
+			    gunyah_vm_io_handler_compare);
+	up_write(&ghvm->mmio_handler_lock);
+
+	return found ? -EEXIST : 0;
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_add_io_handler);
+
+void gunyah_vm_remove_io_handler(struct gunyah_vm *ghvm,
+				 struct gunyah_vm_io_handler *io_hdlr)
+{
+	down_write(&ghvm->mmio_handler_lock);
+	rb_erase(&io_hdlr->node, &ghvm->mmio_handler_root);
+	up_write(&ghvm->mmio_handler_lock);
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_remove_io_handler);
+
 static int gunyah_vm_rm_notification_status(struct gunyah_vm *ghvm, void *data)
 {
 	struct gunyah_rm_vm_status_payload *payload = data;
@@ -404,6 +516,9 @@ static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 	INIT_LIST_HEAD(&ghvm->resource_tickets);
 	xa_init(&ghvm->boot_context);
 
+	init_rwsem(&ghvm->mmio_handler_lock);
+	ghvm->mmio_handler_root = RB_ROOT;
+
 	mt_init(&ghvm->mm);
 	mt_init(&ghvm->bindings);
 	init_rwsem(&ghvm->bindings_lock);
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index 8cee93e551700..daddb1d0cb70b 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -11,6 +11,7 @@
 #include <linux/maple_tree.h>
 #include <linux/mutex.h>
 #include <linux/pagemap.h>
+#include <linux/rbtree.h>
 #include <linux/rwsem.h>
 #include <linux/set_memory.h>
 #include <linux/wait.h>
@@ -58,6 +59,9 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
  * @guest_shared_extent_ticket: Resource ticket to the capability for
  *                              the memory extent that represents
  *                              memory shared with the guest.
+ * @mmio_handler_root: RB tree of MMIO handlers.
+ *                     Entries are &struct gunyah_vm_io_handler
+ * @mmio_handler_lock: Serialization of traversing @mmio_handler_root
  * @rm: Pointer to the resource manager struct to make RM calls
  * @parent: For logging
  * @nb: Notifier block for RM notifications
@@ -93,6 +97,8 @@ struct gunyah_vm {
 	struct gunyah_vm_resource_ticket addrspace_ticket,
 		host_private_extent_ticket, host_shared_extent_ticket,
 		guest_private_extent_ticket, guest_shared_extent_ticket;
+	struct rb_root mmio_handler_root;
+	struct rw_semaphore mmio_handler_lock;
 
 	struct gunyah_rm *rm;
 
@@ -119,6 +125,8 @@ struct gunyah_vm {
 	struct xarray boot_context;
 };
 
+int gunyah_vm_mmio_write(struct gunyah_vm *ghvm, u64 addr, u32 len, u64 data);
+
 /**
  * folio_mmapped() - Returns true if the folio is mapped into any vma
  * @folio: Folio to test
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index a9d58150de696..dbd5b0251b491 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -155,6 +155,35 @@ int gunyah_vm_add_resource_ticket(struct gunyah_vm *ghvm,
 void gunyah_vm_remove_resource_ticket(struct gunyah_vm *ghvm,
 				      struct gunyah_vm_resource_ticket *ticket);
 
+/*
+ * gunyah_vm_io_handler contains the info about an io device and its associated
+ * addr and the ops associated with the io device.
+ */
+struct gunyah_vm_io_handler {
+	struct rb_node node;
+	u64 addr;
+
+	bool datamatch;
+	u8 len;
+	u64 data;
+	struct gunyah_vm_io_handler_ops *ops;
+};
+
+/*
+ * gunyah_vm_io_handler_ops contains function pointers associated with an iodevice.
+ */
+struct gunyah_vm_io_handler_ops {
+	int (*read)(struct gunyah_vm_io_handler *io_dev, u64 addr, u32 len,
+		    u64 data);
+	int (*write)(struct gunyah_vm_io_handler *io_dev, u64 addr, u32 len,
+		     u64 data);
+};
+
+int gunyah_vm_add_io_handler(struct gunyah_vm *ghvm,
+			     struct gunyah_vm_io_handler *io_dev);
+void gunyah_vm_remove_io_handler(struct gunyah_vm *ghvm,
+				 struct gunyah_vm_io_handler *io_dev);
+
 #define GUNYAH_RM_ACL_X BIT(0)
 #define GUNYAH_RM_ACL_W BIT(1)
 #define GUNYAH_RM_ACL_R BIT(2)

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:43 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:43 -0800
Subject: [PATCH v17 20/35] virt: gunyah: Add interfaces to map memory into
 guest address space
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-20-1e9da6763d38@quicinc.com>

Gunyah virtual machines are created with either all memory provided at
VM creation using the Resource Manager memory parcel construct, or
Incrementally by enabling VM demand paging.

The Gunyah demand paging support is provided directly by the hypervisor
and does not require the creation of resource manager memory parcels.

Demand paging allows the host to map/unmap contiguous pages (folios) to
a Gunyah memory extent object with the correct rights allowing its
contained pages to be mapped into the Guest VM's address space. Memory
extents are Gunyah's mechanism for handling system memory abstracting
from the direct use of physical page numbers. Memory extents are
hypervisor objects and are therefore referenced and access controlled
with capabilities.

When a virtual machine is configured for demand paging, 3 memory
extent and 1 address space capabilities are provided to the host. The
resource manager defined policy is such that memory in the "host-only"
extent (the default) is private to the host. Memory in the "guest-only"
extent can be used for guest private mappings, and are unmapped from the
host. Memory in the "host-and-guest-shared" extent can be mapped
concurrently and shared between the host and guest VMs.

Implement two functions which Linux can use to move memory between the
virtual machines: gunyah_provide_folio and gunyah_reclaim_folio. Memory
that has been provided to the guest is tracked in a maple tree to be
reclaimed later. Folios provided to the virtual machine are assumed to
be owned Gunyah stack: the folio's ->private field is used for
bookkeeping about whether page is mapped into virtual machine.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/Makefile     |   2 +-
 drivers/virt/gunyah/vm_mgr.c     |  69 +++++++++
 drivers/virt/gunyah/vm_mgr.h     | 108 +++++++++++++
 drivers/virt/gunyah/vm_mgr_mem.c | 321 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 499 insertions(+), 1 deletion(-)

diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
index 3f82af8c5ce79..f3c9507224eeb 100644
--- a/drivers/virt/gunyah/Makefile
+++ b/drivers/virt/gunyah/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
-gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o
+gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o vm_mgr_mem.o
 
 obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o gunyah_vcpu.o
diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index a6e25901dcea3..64967a8b72885 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -17,6 +17,16 @@
 #include "rsc_mgr.h"
 #include "vm_mgr.h"
 
+#define GUNYAH_VM_ADDRSPACE_LABEL 0
+// "To" extent for memory private to guest
+#define GUNYAH_VM_MEM_EXTENT_GUEST_PRIVATE_LABEL 0
+// "From" extent for memory shared with guest
+#define GUNYAH_VM_MEM_EXTENT_HOST_SHARED_LABEL 1
+// "To" extent for memory shared with the guest
+#define GUNYAH_VM_MEM_EXTENT_GUEST_SHARED_LABEL 3
+// "From" extent for memory private to guest
+#define GUNYAH_VM_MEM_EXTENT_HOST_PRIVATE_LABEL 2
+
 static DEFINE_XARRAY(gunyah_vm_functions);
 
 static void gunyah_vm_put_function(struct gunyah_vm_function *fn)
@@ -175,6 +185,16 @@ void gunyah_vm_function_unregister(struct gunyah_vm_function *fn)
 }
 EXPORT_SYMBOL_GPL(gunyah_vm_function_unregister);
 
+static bool gunyah_vm_resource_ticket_populate_noop(
+	struct gunyah_vm_resource_ticket *ticket, struct gunyah_resource *ghrsc)
+{
+	return true;
+}
+static void gunyah_vm_resource_ticket_unpopulate_noop(
+	struct gunyah_vm_resource_ticket *ticket, struct gunyah_resource *ghrsc)
+{
+}
+
 int gunyah_vm_add_resource_ticket(struct gunyah_vm *ghvm,
 				  struct gunyah_vm_resource_ticket *ticket)
 {
@@ -349,6 +369,17 @@ static void gunyah_vm_stop(struct gunyah_vm *ghvm)
 		   ghvm->vm_status != GUNYAH_RM_VM_STATUS_RUNNING);
 }
 
+static inline void setup_extent_ticket(struct gunyah_vm *ghvm,
+				       struct gunyah_vm_resource_ticket *ticket,
+				       u32 label)
+{
+	ticket->resource_type = GUNYAH_RESOURCE_TYPE_MEM_EXTENT;
+	ticket->label = label;
+	ticket->populate = gunyah_vm_resource_ticket_populate_noop;
+	ticket->unpopulate = gunyah_vm_resource_ticket_unpopulate_noop;
+	gunyah_vm_add_resource_ticket(ghvm, ticket);
+}
+
 static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 {
 	struct gunyah_vm *ghvm;
@@ -372,6 +403,25 @@ static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 	INIT_LIST_HEAD(&ghvm->resources);
 	INIT_LIST_HEAD(&ghvm->resource_tickets);
 
+	mt_init(&ghvm->mm);
+
+	ghvm->addrspace_ticket.resource_type = GUNYAH_RESOURCE_TYPE_ADDR_SPACE;
+	ghvm->addrspace_ticket.label = GUNYAH_VM_ADDRSPACE_LABEL;
+	ghvm->addrspace_ticket.populate =
+		gunyah_vm_resource_ticket_populate_noop;
+	ghvm->addrspace_ticket.unpopulate =
+		gunyah_vm_resource_ticket_unpopulate_noop;
+	gunyah_vm_add_resource_ticket(ghvm, &ghvm->addrspace_ticket);
+
+	setup_extent_ticket(ghvm, &ghvm->host_private_extent_ticket,
+			    GUNYAH_VM_MEM_EXTENT_HOST_PRIVATE_LABEL);
+	setup_extent_ticket(ghvm, &ghvm->host_shared_extent_ticket,
+			    GUNYAH_VM_MEM_EXTENT_HOST_SHARED_LABEL);
+	setup_extent_ticket(ghvm, &ghvm->guest_private_extent_ticket,
+			    GUNYAH_VM_MEM_EXTENT_GUEST_PRIVATE_LABEL);
+	setup_extent_ticket(ghvm, &ghvm->guest_shared_extent_ticket,
+			    GUNYAH_VM_MEM_EXTENT_GUEST_SHARED_LABEL);
+
 	return ghvm;
 }
 
@@ -533,6 +583,23 @@ static void _gunyah_vm_put(struct kref *kref)
 		gunyah_vm_stop(ghvm);
 
 	gunyah_vm_remove_functions(ghvm);
+
+	/**
+	 * If this fails, we're going to lose the memory for good and is
+	 * BUG_ON-worthy, but not unrecoverable (we just lose memory).
+	 * This call should always succeed though because the VM is in not
+	 * running and RM will let us reclaim all the memory.
+	 */
+	WARN_ON(gunyah_vm_reclaim_range(ghvm, 0, U64_MAX));
+
+	/* clang-format off */
+	gunyah_vm_remove_resource_ticket(ghvm, &ghvm->addrspace_ticket);
+	gunyah_vm_remove_resource_ticket(ghvm, &ghvm->host_shared_extent_ticket);
+	gunyah_vm_remove_resource_ticket(ghvm, &ghvm->host_private_extent_ticket);
+	gunyah_vm_remove_resource_ticket(ghvm, &ghvm->guest_shared_extent_ticket);
+	gunyah_vm_remove_resource_ticket(ghvm, &ghvm->guest_private_extent_ticket);
+	/* clang-format on */
+
 	gunyah_vm_clean_resources(ghvm);
 
 	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_EXITED ||
@@ -548,6 +615,8 @@ static void _gunyah_vm_put(struct kref *kref)
 		/* clang-format on */
 	}
 
+	mtree_destroy(&ghvm->mm);
+
 	if (ghvm->vm_status > GUNYAH_RM_VM_STATUS_NO_STATE) {
 		gunyah_rm_notifier_unregister(ghvm->rm, &ghvm->nb);
 
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index 8c5b94101b2cf..a6a4efa4138b7 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -8,20 +8,53 @@
 
 #include <linux/device.h>
 #include <linux/kref.h>
+#include <linux/maple_tree.h>
 #include <linux/mutex.h>
+#include <linux/pagemap.h>
 #include <linux/rwsem.h>
+#include <linux/set_memory.h>
 #include <linux/wait.h>
 
 #include <uapi/linux/gunyah.h>
 
 #include "rsc_mgr.h"
 
+static inline u64 gunyah_gpa_to_gfn(u64 gpa)
+{
+	return gpa >> PAGE_SHIFT;
+}
+
+static inline u64 gunyah_gfn_to_gpa(u64 gfn)
+{
+	return gfn << PAGE_SHIFT;
+}
+
 long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
 			     unsigned long arg);
 
 /**
  * struct gunyah_vm - Main representation of a Gunyah Virtual machine
  * @vmid: Gunyah's VMID for this virtual machine
+ * @mm: A maple tree of all memory that has been mapped to a VM.
+ *      Indices are guest frame numbers; entries are either folios or
+ *      RM mem parcels
+ * @addrspace_ticket: Resource ticket to the capability for guest VM's
+ *                    address space
+ * @host_private_extent_ticket: Resource ticket to the capability for our
+ *                              memory extent from which to lend private
+ *                              memory to the guest
+ * @host_shared_extent_ticket: Resource ticket to the capaiblity for our
+ *                             memory extent from which to share memory
+ *                             with the guest. Distinction with
+ *                             @host_private_extent_ticket needed for
+ *                             current Qualcomm platforms; on non-Qualcomm
+ *                             platforms, this is the same capability ID
+ * @guest_private_extent_ticket: Resource ticket to the capaiblity for
+ *                               the guest's memory extent to lend private
+ *                               memory to
+ * @guest_shared_extent_ticket: Resource ticket to the capability for
+ *                              the memory extent that represents
+ *                              memory shared with the guest.
  * @rm: Pointer to the resource manager struct to make RM calls
  * @parent: For logging
  * @nb: Notifier block for RM notifications
@@ -43,6 +76,11 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
  */
 struct gunyah_vm {
 	u16 vmid;
+	struct maple_tree mm;
+	struct gunyah_vm_resource_ticket addrspace_ticket,
+		host_private_extent_ticket, host_shared_extent_ticket,
+		guest_private_extent_ticket, guest_shared_extent_ticket;
+
 	struct gunyah_rm *rm;
 
 	struct notifier_block nb;
@@ -63,4 +101,74 @@ struct gunyah_vm {
 
 };
 
+/**
+ * folio_mmapped() - Returns true if the folio is mapped into any vma
+ * @folio: Folio to test
+ */
+static bool folio_mmapped(struct folio *folio)
+{
+	struct address_space *mapping = folio->mapping;
+	struct vm_area_struct *vma;
+	bool ret = false;
+
+	i_mmap_lock_read(mapping);
+	vma_interval_tree_foreach(vma, &mapping->i_mmap, folio_index(folio),
+				  folio_index(folio) + folio_nr_pages(folio)) {
+		ret = true;
+		break;
+	}
+	i_mmap_unlock_read(mapping);
+	return ret;
+}
+
+/**
+ * gunyah_folio_lend_safe() - Returns true if folio is ready to be lent to guest
+ * @folio: Folio to prepare
+ *
+ * Tests if the folio is mapped anywhere outside the kernel logical map
+ * and whether any userspace has a vma containing the folio, even if it hasn't
+ * paged it in. We want to avoid causing fault to userspace.
+ * If userspace doesn't have it mapped anywhere, then unmap from kernel
+ * logical map to prevent accidental access (e.g. by load_unaligned_zeropad)
+ */
+static inline bool gunyah_folio_lend_safe(struct folio *folio)
+{
+	long i;
+
+	if (folio_mapped(folio) || folio_mmapped(folio))
+		return false;
+
+	for (i = 0; i < folio_nr_pages(folio); i++)
+		set_direct_map_invalid_noflush(folio_page(folio, i));
+	/**
+	 * No need to flush tlb on armv8/9: hypervisor will flush when it
+	 * removes from our stage 2
+	 */
+	return true;
+}
+
+/**
+ * gunyah_folio_host_reclaim() - Restores kernel logical map to folio
+ * @folio: folio to reclaim by host
+ *
+ * See also gunyah_folio_lend_safe().
+ */
+static inline void gunyah_folio_host_reclaim(struct folio *folio)
+{
+	long i;
+	for (i = 0; i < folio_nr_pages(folio); i++)
+		set_direct_map_default_noflush(folio_page(folio, i));
+}
+
+int gunyah_vm_parcel_to_paged(struct gunyah_vm *ghvm,
+			      struct gunyah_rm_mem_parcel *parcel, u64 gfn,
+			      u64 nr);
+void gunyah_vm_mm_erase_range(struct gunyah_vm *ghvm, u64 gfn, u64 nr);
+int gunyah_vm_reclaim_parcel(struct gunyah_vm *ghvm,
+			     struct gunyah_rm_mem_parcel *parcel, u64 gfn);
+int gunyah_vm_provide_folio(struct gunyah_vm *ghvm, struct folio *folio,
+			    u64 gfn, bool share, bool write);
+int gunyah_vm_reclaim_folio(struct gunyah_vm *ghvm, u64 gfn, struct folio *folio);
+int gunyah_vm_reclaim_range(struct gunyah_vm *ghvm, u64 gfn, u64 nr);
+
 #endif
diff --git a/drivers/virt/gunyah/vm_mgr_mem.c b/drivers/virt/gunyah/vm_mgr_mem.c
new file mode 100644
index 0000000000000..bcc84473004be
--- /dev/null
+++ b/drivers/virt/gunyah/vm_mgr_mem.c
@@ -0,0 +1,321 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "gunyah_vm_mgr: " fmt
+
+#include <asm/gunyah.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+
+#include "vm_mgr.h"
+
+#define WRITE_TAG (1 << 0)
+#define SHARE_TAG (1 << 1)
+
+static inline struct gunyah_resource *
+__first_resource(struct gunyah_vm_resource_ticket *ticket)
+{
+	return list_first_entry_or_null(&ticket->resources,
+					struct gunyah_resource, list);
+}
+
+int gunyah_vm_parcel_to_paged(struct gunyah_vm *ghvm,
+			      struct gunyah_rm_mem_parcel *parcel, u64 gfn,
+			      u64 nr)
+{
+	struct gunyah_rm_mem_entry *entry;
+	unsigned long i, tag = 0;
+	struct folio *folio;
+	pgoff_t off = 0;
+	int ret;
+
+	if (parcel->n_acl_entries > 1)
+		tag |= SHARE_TAG;
+	if (parcel->acl_entries[0].perms & GUNYAH_RM_ACL_W)
+		tag |= WRITE_TAG;
+
+	for (i = 0; i < parcel->n_mem_entries; i++) {
+		entry = &parcel->mem_entries[i];
+
+		folio = pfn_folio(PHYS_PFN(le64_to_cpu(entry->phys_addr)));
+		ret = mtree_insert_range(&ghvm->mm, gfn + off,
+					 gfn + off + folio_nr_pages(folio) - 1,
+					 xa_tag_pointer(folio, tag),
+					 GFP_KERNEL);
+		if (ret) {
+			WARN_ON(ret != -ENOMEM);
+			gunyah_vm_mm_erase_range(ghvm, gfn, off - 1);
+			return ret;
+		}
+		off += folio_nr_pages(folio);
+	}
+
+	return 0;
+}
+
+/**
+ * gunyah_vm_mm_erase_range() - Erases a range of folios from ghvm's mm
+ * @ghvm: gunyah vm
+ * @gfn: start guest frame number
+ * @nr: number of pages to erase
+ *
+ * Do not use this function unless rolling back gunyah_vm_parcel_to_paged.
+ */
+void gunyah_vm_mm_erase_range(struct gunyah_vm *ghvm, u64 gfn, u64 nr)
+{
+	struct folio *folio;
+	u64 off = gfn;
+
+	while (off < gfn + nr) {
+		folio = xa_untag_pointer(mtree_erase(&ghvm->mm, off));
+		if (!folio)
+			return;
+		off += folio_nr_pages(folio);
+	}
+}
+
+static inline u32 donate_flags(bool share)
+{
+	if (share)
+		return FIELD_PREP_CONST(GUNYAH_MEMEXTENT_OPTION_TYPE_MASK,
+					GUNYAH_MEMEXTENT_DONATE_TO_SIBLING);
+	else
+		return FIELD_PREP_CONST(GUNYAH_MEMEXTENT_OPTION_TYPE_MASK,
+					GUNYAH_MEMEXTENT_DONATE_TO_PROTECTED);
+}
+
+static inline u32 reclaim_flags(bool share)
+{
+	if (share)
+		return FIELD_PREP_CONST(GUNYAH_MEMEXTENT_OPTION_TYPE_MASK,
+					GUNYAH_MEMEXTENT_DONATE_TO_SIBLING);
+	else
+		return FIELD_PREP_CONST(GUNYAH_MEMEXTENT_OPTION_TYPE_MASK,
+					GUNYAH_MEMEXTENT_DONATE_FROM_PROTECTED);
+}
+
+int gunyah_vm_provide_folio(struct gunyah_vm *ghvm, struct folio *folio,
+			    u64 gfn, bool share, bool write)
+{
+	struct gunyah_resource *guest_extent, *host_extent, *addrspace;
+	u32 map_flags = BIT(GUNYAH_ADDRSPACE_MAP_FLAG_PARTIAL);
+	u64 extent_attrs, gpa = gunyah_gfn_to_gpa(gfn);
+	phys_addr_t pa = PFN_PHYS(folio_pfn(folio));
+	enum gunyah_pagetable_access access;
+	size_t size = folio_size(folio);
+	enum gunyah_error gunyah_error;
+	unsigned long tag = 0;
+	int ret;
+
+	/* clang-format off */
+	if (share) {
+		guest_extent = __first_resource(&ghvm->guest_shared_extent_ticket);
+		host_extent = __first_resource(&ghvm->host_shared_extent_ticket);
+	} else {
+		guest_extent = __first_resource(&ghvm->guest_private_extent_ticket);
+		host_extent = __first_resource(&ghvm->host_private_extent_ticket);
+	}
+	/* clang-format on */
+	addrspace = __first_resource(&ghvm->addrspace_ticket);
+
+	if (!addrspace || !guest_extent || !host_extent) {
+		folio_unlock(folio);
+		return -ENODEV;
+	}
+
+	if (share) {
+		map_flags |= BIT(GUNYAH_ADDRSPACE_MAP_FLAG_VMMIO);
+		tag |= SHARE_TAG;
+	} else {
+		map_flags |= BIT(GUNYAH_ADDRSPACE_MAP_FLAG_PRIVATE);
+	}
+
+	if (write)
+		tag |= WRITE_TAG;
+
+	ret = mtree_insert_range(&ghvm->mm, gfn,
+				 gfn + folio_nr_pages(folio) - 1,
+				 xa_tag_pointer(folio, tag), GFP_KERNEL);
+	if (ret == -EEXIST)
+		ret = -EAGAIN;
+	if (ret)
+		return ret;
+
+	/* don't lend a folio that is (or could be) mapped by Linux */
+	if (!share && !gunyah_folio_lend_safe(folio)) {
+		ret = -EPERM;
+		goto remove;
+	}
+
+	if (share && write)
+		access = GUNYAH_PAGETABLE_ACCESS_RW;
+	else if (share && !write)
+		access = GUNYAH_PAGETABLE_ACCESS_R;
+	else if (!share && write)
+		access = GUNYAH_PAGETABLE_ACCESS_RWX;
+	else /* !share && !write */
+		access = GUNYAH_PAGETABLE_ACCESS_RX;
+
+	gunyah_error = gunyah_hypercall_memextent_donate(donate_flags(share),
+							 host_extent->capid,
+							 guest_extent->capid,
+							 pa, size);
+	if (gunyah_error != GUNYAH_ERROR_OK) {
+		pr_err("Failed to donate memory for guest address 0x%016llx: %d\n",
+		       gpa, gunyah_error);
+		ret = gunyah_error_remap(gunyah_error);
+		goto remove;
+	}
+
+	extent_attrs =
+		FIELD_PREP_CONST(GUNYAH_MEMEXTENT_MAPPING_TYPE,
+				 ARCH_GUNYAH_DEFAULT_MEMTYPE) |
+		FIELD_PREP(GUNYAH_MEMEXTENT_MAPPING_USER_ACCESS, access) |
+		FIELD_PREP(GUNYAH_MEMEXTENT_MAPPING_KERNEL_ACCESS, access);
+	gunyah_error = gunyah_hypercall_addrspace_map(addrspace->capid,
+						      guest_extent->capid, gpa,
+						      extent_attrs, map_flags,
+						      pa, size);
+	if (gunyah_error != GUNYAH_ERROR_OK) {
+		pr_err("Failed to map guest address 0x%016llx: %d\n", gpa,
+		       gunyah_error);
+		ret = gunyah_error_remap(gunyah_error);
+		goto memextent_reclaim;
+	}
+
+	folio_get(folio);
+	if (!share)
+		folio_set_private(folio);
+	return 0;
+memextent_reclaim:
+	gunyah_error = gunyah_hypercall_memextent_donate(reclaim_flags(share),
+							 guest_extent->capid,
+							 host_extent->capid, pa,
+							 size);
+	if (gunyah_error != GUNYAH_ERROR_OK)
+		pr_err("Failed to reclaim memory donation for guest address 0x%016llx: %d\n",
+		       gpa, gunyah_error);
+remove:
+	mtree_erase(&ghvm->mm, gfn);
+	return ret;
+}
+
+static int __gunyah_vm_reclaim_folio_locked(struct gunyah_vm *ghvm, void *entry,
+					    u64 gfn, const bool sync)
+{
+	u32 map_flags = BIT(GUNYAH_ADDRSPACE_MAP_FLAG_PARTIAL);
+	struct gunyah_resource *guest_extent, *host_extent, *addrspace;
+	enum gunyah_error gunyah_error;
+	struct folio *folio;
+	bool write, share;
+	phys_addr_t pa;
+	size_t size;
+	int ret;
+
+	addrspace = __first_resource(&ghvm->addrspace_ticket);
+	if (!addrspace)
+		return -ENODEV;
+
+	share = !!(xa_pointer_tag(entry) & SHARE_TAG);
+	write = !!(xa_pointer_tag(entry) & WRITE_TAG);
+	folio = xa_untag_pointer(entry);
+
+	if (!sync)
+		map_flags |= BIT(GUNYAH_ADDRSPACE_MAP_FLAG_NOSYNC);
+
+	/* clang-format off */
+	if (share) {
+		guest_extent = __first_resource(&ghvm->guest_shared_extent_ticket);
+		host_extent = __first_resource(&ghvm->host_shared_extent_ticket);
+		map_flags |= BIT(GUNYAH_ADDRSPACE_MAP_FLAG_VMMIO);
+	} else {
+		guest_extent = __first_resource(&ghvm->guest_private_extent_ticket);
+		host_extent = __first_resource(&ghvm->host_private_extent_ticket);
+		map_flags |= BIT(GUNYAH_ADDRSPACE_MAP_FLAG_PRIVATE);
+	}
+	/* clang-format on */
+
+	pa = PFN_PHYS(folio_pfn(folio));
+	size = folio_size(folio);
+
+	gunyah_error = gunyah_hypercall_addrspace_unmap(addrspace->capid,
+							guest_extent->capid,
+							gunyah_gfn_to_gpa(gfn),
+							map_flags, pa, size);
+	if (gunyah_error != GUNYAH_ERROR_OK) {
+		pr_err_ratelimited(
+			"Failed to unmap guest address 0x%016llx: %d\n",
+			gunyah_gfn_to_gpa(gfn), gunyah_error);
+		ret = gunyah_error_remap(gunyah_error);
+		goto err;
+	}
+
+	gunyah_error = gunyah_hypercall_memextent_donate(reclaim_flags(share),
+							 guest_extent->capid,
+							 host_extent->capid, pa,
+							 size);
+	if (gunyah_error != GUNYAH_ERROR_OK) {
+		pr_err_ratelimited(
+			"Failed to reclaim memory donation for guest address 0x%016llx: %d\n",
+			gunyah_gfn_to_gpa(gfn), gunyah_error);
+		ret = gunyah_error_remap(gunyah_error);
+		goto err;
+	}
+
+	BUG_ON(mtree_erase(&ghvm->mm, gfn) != entry);
+
+	if (folio_test_private(folio)) {
+		gunyah_folio_host_reclaim(folio);
+		folio_clear_private(folio);
+	}
+
+	folio_put(folio);
+	return 0;
+err:
+	return ret;
+}
+
+int gunyah_vm_reclaim_folio(struct gunyah_vm *ghvm, u64 gfn, struct folio *folio)
+{
+	void *entry;
+
+	entry = mtree_load(&ghvm->mm, gfn);
+	if (!entry)
+		return 0;
+
+	if (folio != xa_untag_pointer(entry))
+		return -EAGAIN;
+
+	return __gunyah_vm_reclaim_folio_locked(ghvm, entry, gfn, true);
+}
+
+int gunyah_vm_reclaim_range(struct gunyah_vm *ghvm, u64 gfn, u64 nr)
+{
+	unsigned long next = gfn, g;
+	struct folio *folio;
+	int ret, ret2 = 0;
+	void *entry;
+	bool sync;
+
+	mt_for_each(&ghvm->mm, entry, next, gfn + nr) {
+		folio = xa_untag_pointer(entry);
+		g = next;
+		sync = !!mt_find_after(&ghvm->mm, &g, gfn + nr);
+
+		g = next - folio_nr_pages(folio);
+		folio_get(folio);
+		folio_lock(folio);
+		if (mtree_load(&ghvm->mm, g) == entry)
+			ret = __gunyah_vm_reclaim_folio_locked(ghvm, entry, g, sync);
+		else
+			ret = -EAGAIN;
+		folio_unlock(folio);
+		folio_put(folio);
+		if (ret && ret2 != -EAGAIN)
+			ret2 = ret;
+	}
+
+	return ret2;
+}

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:47 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:47 -0800
Subject: [PATCH v17 24/35] virt: gunyah: Add ioctl to bind guestmem to VMs
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-24-1e9da6763d38@quicinc.com>

A maple tree is used to maintain a map from guest address ranges to a
guestmemfd that provides the memory for that range of memory for the
guest. The mapping of guest address range to guestmemfd is called a
binding. Implement an ioctl to add/remove bindings to the virtual
machine. The binding determines whether the memory is shared (host
retains access) or lent (host loses access).

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/guest_memfd.c | 426 +++++++++++++++++++++++++++++++++++++-
 drivers/virt/gunyah/vm_mgr.c      |  20 ++
 drivers/virt/gunyah/vm_mgr.h      |   9 +
 include/uapi/linux/gunyah.h       |  41 ++++
 4 files changed, 488 insertions(+), 8 deletions(-)

diff --git a/drivers/virt/gunyah/guest_memfd.c b/drivers/virt/gunyah/guest_memfd.c
index 19c72aa1d0e5e..d6be8bf67d996 100644
--- a/drivers/virt/gunyah/guest_memfd.c
+++ b/drivers/virt/gunyah/guest_memfd.c
@@ -16,6 +16,51 @@
 
 #include "vm_mgr.h"
 
+/**
+ * struct gunyah_gmem_binding - Represents a binding of guestmem to a Gunyah VM
+ * @gfn: Guest address to place acquired folios
+ * @ghvm: Pointer to Gunyah VM in this binding
+ * @i_off: offset into the guestmem to grab folios from
+ * @file: Pointer to guest_memfd
+ * @i_entry: list entry for inode->i_private_list
+ * @flags: Access flags for the binding
+ * @nr: Number of pages covered by this binding
+ */
+struct gunyah_gmem_binding {
+	u64 gfn;
+	struct gunyah_vm *ghvm;
+
+	pgoff_t i_off;
+	struct file *file;
+	struct list_head i_entry;
+
+	u32 flags;
+	unsigned long nr;
+};
+
+static inline pgoff_t gunyah_gfn_to_off(struct gunyah_gmem_binding *b, u64 gfn)
+{
+	return gfn - b->gfn + b->i_off;
+}
+
+static inline u64 gunyah_off_to_gfn(struct gunyah_gmem_binding *b, pgoff_t off)
+{
+	return off - b->i_off + b->gfn;
+}
+
+static inline bool gunyah_guest_mem_is_lend(struct gunyah_vm *ghvm, u32 flags)
+{
+	u8 access = flags & GUNYAH_MEM_ACCESS_MASK;
+
+	if (access == GUNYAH_MEM_FORCE_LEND)
+		return true;
+	else if (access == GUNYAH_MEM_FORCE_SHARE)
+		return false;
+
+	/* RM requires all VMs to be protected (isolated) */
+	return true;
+}
+
 static struct folio *gunyah_gmem_get_huge_folio(struct inode *inode,
 						pgoff_t index)
 {
@@ -83,6 +128,38 @@ static struct folio *gunyah_gmem_get_folio(struct inode *inode, pgoff_t index)
 	return folio;
 }
 
+/**
+ * gunyah_gmem_launder_folio() - Tries to unmap one folio from virtual machine(s)
+ * @folio: The folio to unmap
+ *
+ * Returns - 0 if the folio has been reclaimed from any virtual machine(s) that
+ *           folio was mapped into.
+ */
+static int gunyah_gmem_launder_folio(struct folio *folio)
+{
+	struct address_space *const mapping = folio->mapping;
+	struct gunyah_gmem_binding *b;
+	pgoff_t index = folio_index(folio);
+	int ret = 0;
+	u64 gfn;
+
+	filemap_invalidate_lock_shared(mapping);
+	list_for_each_entry(b, &mapping->i_private_list, i_entry) {
+		/* if the mapping doesn't cover this folio: skip */
+		if (b->i_off > index || index > b->i_off + b->nr)
+			continue;
+
+		gfn = gunyah_off_to_gfn(b, index);
+		ret = gunyah_vm_reclaim_folio(b->ghvm, gfn, folio);
+		if (WARN_RATELIMIT(ret, "failed to reclaim gfn: %08llx %d\n",
+				   gfn, ret))
+			break;
+	}
+	filemap_invalidate_unlock_shared(mapping);
+
+	return ret;
+}
+
 static vm_fault_t gunyah_gmem_host_fault(struct vm_fault *vmf)
 {
 	struct folio *folio;
@@ -92,6 +169,15 @@ static vm_fault_t gunyah_gmem_host_fault(struct vm_fault *vmf)
 	if (!folio)
 		return VM_FAULT_SIGBUS;
 
+	/* If the folio is lent to a VM, try to reclaim it */
+	if (folio_test_private(folio) && gunyah_gmem_launder_folio(folio)) {
+		folio_unlock(folio);
+		folio_put(folio);
+		return VM_FAULT_SIGBUS;
+	}
+	/* gunyah_gmem_launder_folio should clear the private bit if it returns 0 */
+	BUG_ON(folio_test_private(folio));
+
 	vmf->page = folio_file_page(folio, vmf->pgoff);
 
 	return VM_FAULT_LOCKED;
@@ -103,9 +189,48 @@ static const struct vm_operations_struct gunyah_gmem_vm_ops = {
 
 static int gunyah_gmem_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	file_accessed(file);
-	vma->vm_ops = &gunyah_gmem_vm_ops;
-	return 0;
+	struct address_space *const mapping = file->f_mapping;
+	struct gunyah_gmem_binding *b;
+	pgoff_t end_off;
+	int ret = 0;
+	u64 gfn, nr;
+
+	/* No support for private mappings to avoid COW.  */
+	if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) !=
+	    (VM_SHARED | VM_MAYSHARE)) {
+		return -EINVAL;
+	}
+
+	filemap_invalidate_lock_shared(mapping);
+	/**
+	 * userspace can only mmap if the folios covered by the requested
+	 * offset are not lent to the guest
+	 */
+	list_for_each_entry(b, &mapping->i_private_list, i_entry) {
+		if (!gunyah_guest_mem_is_lend(b->ghvm, b->flags))
+			continue;
+
+		/* if the binding doesn't cover this vma: skip */
+		if (vma->vm_pgoff + vma_pages(vma) < b->i_off)
+			continue;
+		if (vma->vm_pgoff > b->i_off + b->nr)
+			continue;
+
+		gfn = gunyah_off_to_gfn(b, vma->vm_pgoff);
+		end_off = max(vma->vm_pgoff + vma_pages(vma), b->i_off + b->nr);
+		nr = gunyah_off_to_gfn(b, end_off) - gfn;
+		ret = gunyah_vm_reclaim_range(b->ghvm, gfn, nr);
+		if (ret)
+			break;
+	}
+	filemap_invalidate_unlock_shared(mapping);
+
+	if (!ret) {
+		file_accessed(file);
+		vma->vm_ops = &gunyah_gmem_vm_ops;
+	}
+
+	return ret;
 }
 
 /**
@@ -122,9 +247,7 @@ static int gunyah_gmem_mmap(struct file *file, struct vm_area_struct *vma)
 static long gunyah_gmem_punch_hole(struct inode *inode, loff_t offset,
 				   loff_t len)
 {
-	truncate_inode_pages_range(inode->i_mapping, offset, offset + len - 1);
-
-	return 0;
+	return invalidate_inode_pages2_range(inode->i_mapping, offset, offset + len - 1);
 }
 
 static long gunyah_gmem_allocate(struct inode *inode, loff_t offset, loff_t len)
@@ -201,6 +324,12 @@ static long gunyah_gmem_fallocate(struct file *file, int mode, loff_t offset,
 
 static int gunyah_gmem_release(struct inode *inode, struct file *file)
 {
+	/**
+	 * each binding increments refcount on file, so we shouldn't be here
+	 * if i_private_list not empty.
+	 */
+	BUG_ON(!list_empty(&inode->i_mapping->i_private_list));
+
 	return 0;
 }
 
@@ -213,10 +342,26 @@ static const struct file_operations gunyah_gmem_fops = {
 	.release = gunyah_gmem_release,
 };
 
+static bool gunyah_gmem_release_folio(struct folio *folio, gfp_t gfp_flags)
+{
+	/* should return true if released; launder folio returns 0 if freed */
+	return !gunyah_gmem_launder_folio(folio);
+}
+
+static int gunyah_gmem_remove_folio(struct address_space *mapping,
+				    struct folio *folio)
+{
+	if (mapping != folio->mapping)
+		return -EINVAL;
+
+	return gunyah_gmem_launder_folio(folio);
+}
+
 static const struct address_space_operations gunyah_gmem_aops = {
 	.dirty_folio = noop_dirty_folio,
-	.migrate_folio = migrate_folio,
-	.error_remove_folio = generic_error_remove_folio,
+	.release_folio = gunyah_gmem_release_folio,
+	.launder_folio = gunyah_gmem_launder_folio,
+	.error_remove_folio = gunyah_gmem_remove_folio,
 };
 
 int gunyah_guest_mem_create(struct gunyah_create_mem_args *args)
@@ -264,6 +409,7 @@ int gunyah_guest_mem_create(struct gunyah_create_mem_args *args)
 	mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
 	mapping_set_large_folios(inode->i_mapping);
 	mapping_set_unmovable(inode->i_mapping);
+	mapping_set_release_always(inode->i_mapping);
 	/* Unmovable mappings are supposed to be marked unevictable as well. */
 	WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping));
 
@@ -274,3 +420,267 @@ int gunyah_guest_mem_create(struct gunyah_create_mem_args *args)
 	put_unused_fd(fd);
 	return err;
 }
+
+void gunyah_gmem_remove_binding(struct gunyah_gmem_binding *b)
+{
+	WARN_ON(gunyah_vm_reclaim_range(b->ghvm, b->gfn, b->nr));
+	mtree_erase(&b->ghvm->bindings, b->gfn);
+	list_del(&b->i_entry);
+	fput(b->file);
+	kfree(b);
+}
+
+static inline unsigned long gunyah_gmem_page_mask(struct file *file)
+{
+	unsigned long gmem_flags = (unsigned long)file_inode(file)->i_private;
+
+	if (gmem_flags & GHMF_ALLOW_HUGEPAGE) {
+#if IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)
+		return HPAGE_PMD_MASK;
+#else
+		return ULONG_MAX;
+#endif
+	}
+
+	return PAGE_MASK;
+}
+
+static int gunyah_gmem_init_binding(struct gunyah_vm *ghvm, struct file *file,
+				    struct gunyah_map_mem_args *args,
+				    struct gunyah_gmem_binding *binding)
+{
+	const unsigned long page_mask = ~gunyah_gmem_page_mask(file);
+
+	if (args->flags & ~(GUNYAH_MEM_ALLOW_RWX | GUNYAH_MEM_ACCESS_MASK))
+		return -EINVAL;
+
+	if (args->guest_addr & page_mask)
+		return -EINVAL;
+
+	if (args->offset & page_mask)
+		return -EINVAL;
+
+	if (args->size & page_mask)
+		return -EINVAL;
+
+	binding->gfn = gunyah_gpa_to_gfn(args->guest_addr);
+	binding->ghvm = ghvm;
+	binding->i_off = args->offset >> PAGE_SHIFT;
+	binding->file = file;
+	binding->flags = args->flags;
+	binding->nr = args->size >> PAGE_SHIFT;
+
+	return 0;
+}
+
+static int gunyah_gmem_trim_binding(struct gunyah_gmem_binding *b,
+				    unsigned long start_delta,
+				    unsigned long end_delta)
+{
+	struct gunyah_vm *ghvm = b->ghvm;
+	int ret;
+
+	down_write(&ghvm->bindings_lock);
+	if (!start_delta && !end_delta) {
+		ret = gunyah_vm_reclaim_range(ghvm, b->gfn, b->nr);
+		if (ret)
+			goto unlock;
+		gunyah_gmem_remove_binding(b);
+	} else if (start_delta && !end_delta) {
+		/* keep the start */
+		ret = gunyah_vm_reclaim_range(ghvm, b->gfn + start_delta,
+					      b->gfn + b->nr);
+		if (ret)
+			goto unlock;
+		mtree_erase(&ghvm->bindings, b->gfn);
+		b->nr = start_delta;
+		ret = mtree_insert_range(&ghvm->bindings, b->gfn,
+					 b->gfn + b->nr - 1, b, GFP_KERNEL);
+	} else if (!start_delta && end_delta) {
+		/* keep the end */
+		ret = gunyah_vm_reclaim_range(ghvm, b->gfn,
+					      b->gfn + b->nr - end_delta);
+		if (ret)
+			goto unlock;
+		mtree_erase(&ghvm->bindings, b->gfn);
+		b->gfn += b->nr - end_delta;
+		b->i_off += b->nr - end_delta;
+		b->nr = end_delta;
+		ret = mtree_insert_range(&ghvm->bindings, b->gfn,
+					 b->gfn + b->nr - 1, b, GFP_KERNEL);
+	} else {
+		/* TODO: split the mapping into 2 */
+		ret = -EINVAL;
+	}
+
+unlock:
+	up_write(&ghvm->bindings_lock);
+	return ret;
+}
+
+static int gunyah_gmem_remove_mapping(struct gunyah_vm *ghvm, struct file *file,
+				      struct gunyah_map_mem_args *args)
+{
+	struct inode *inode = file_inode(file);
+	struct gunyah_gmem_binding *b = NULL;
+	unsigned long start_delta, end_delta;
+	struct gunyah_gmem_binding remove;
+	int ret;
+
+	ret = gunyah_gmem_init_binding(ghvm, file, args, &remove);
+	if (ret)
+		return ret;
+
+	ret = -ENOENT;
+	filemap_invalidate_lock(inode->i_mapping);
+	list_for_each_entry(b, &inode->i_mapping->i_private_list, i_entry) {
+		if (b->ghvm != remove.ghvm || b->flags != remove.flags ||
+		    WARN_ON(b->file != remove.file))
+			continue;
+		/**
+		 * Test if the binding to remove is within this binding
+		 *  [gfn       b          nr]
+		 *   [gfn   remove   nr]
+		 */
+		if (b->gfn > remove.gfn)
+			continue;
+		if (b->gfn + b->nr < remove.gfn + remove.nr)
+			continue;
+
+		/**
+		 * We found the binding!
+		 * Compute the delta in gfn start and make sure the offset
+		 * into guest memfd matches.
+		 */
+		start_delta = remove.gfn - b->gfn;
+		if (remove.i_off - b->i_off != start_delta)
+			break;
+		end_delta = b->gfn + b->nr - remove.gfn - remove.nr;
+
+		ret = gunyah_gmem_trim_binding(b, start_delta, end_delta);
+		break;
+	}
+
+	filemap_invalidate_unlock(inode->i_mapping);
+	return ret;
+}
+
+static bool gunyah_gmem_binding_overlaps(struct gunyah_gmem_binding *a,
+						struct gunyah_gmem_binding *b)
+{
+	/* assumes we are operating on the same file, check to be sure */
+	BUG_ON(a->file != b->file);
+
+	/**
+	 * Gunyah only guarantees we can share a page with one VM and
+	 * doesn't (currently) allow us to share same page with multiple VMs,
+	 * regardless whether host can also access.
+	 * Gunyah supports, but Linux hasn't implemented mapping same page
+	 * into 2 separate addresses in guest's address space. This doesn't
+	 * seem reasonable today, but we could do it later.
+	 * All this to justify: check that the `a` region doesn't overlap with
+	 * `b` region w.r.t. file offsets.
+	 */
+	if (a->i_off + a->nr <= b->i_off)
+		return false;
+	if (a->i_off >= b->i_off + b->nr)
+		return false;
+
+	return true;
+}
+
+static int gunyah_gmem_add_mapping(struct gunyah_vm *ghvm, struct file *file,
+				   struct gunyah_map_mem_args *args)
+{
+	struct gunyah_gmem_binding *b, *tmp = NULL;
+	struct inode *inode = file_inode(file);
+	int ret;
+
+	b = kzalloc(sizeof(*b), GFP_KERNEL);
+	if (!b)
+		return -ENOMEM;
+
+	ret = gunyah_gmem_init_binding(ghvm, file, args, b);
+	if (ret)
+		return ret;
+
+	/**
+	 * When lending memory, we need to unmap single page from kernel's
+	 * logical map. To do that, we need can_set_direct_map().
+	 * arm64 doesn't map at page granularity without rodata=full.
+	 */
+	if (gunyah_guest_mem_is_lend(ghvm, b->flags) && !can_set_direct_map()) {
+		kfree(b);
+		pr_warn_once("Cannot lend memory without rodata=full");
+		return -EINVAL;
+	}
+
+	/**
+	 * First, check that the region of guets memfd user is binding isn't
+	 * already bound to some other guest region.
+	 */
+	filemap_invalidate_lock(inode->i_mapping);
+	list_for_each_entry(tmp, &inode->i_mapping->i_private_list, i_entry) {
+		if (gunyah_gmem_binding_overlaps(b, tmp)) {
+			ret = -EEXIST;
+			goto unlock;
+		}
+	}
+
+	/**
+	 * mtree_insert_range will check that user hasn't mapped some other guest
+	 * memfd region to the same addresses.
+	 */
+	ret = mtree_insert_range(&ghvm->bindings, b->gfn, b->gfn + b->nr - 1, b,
+				 GFP_KERNEL);
+	if (ret)
+		goto unlock;
+
+	list_add(&b->i_entry, &inode->i_mapping->i_private_list);
+
+unlock:
+	filemap_invalidate_unlock(inode->i_mapping);
+	return ret;
+}
+
+int gunyah_gmem_modify_mapping(struct gunyah_vm *ghvm,
+			       struct gunyah_map_mem_args *args)
+{
+	u8 access = args->flags & GUNYAH_MEM_ACCESS_MASK;
+	struct file *file;
+	int ret = -EINVAL;
+
+	file = fget(args->guest_mem_fd);
+	if (!file)
+		return -EINVAL;
+
+	if (file->f_op != &gunyah_gmem_fops)
+		goto err_file;
+
+	if (args->flags & ~(GUNYAH_MEM_ALLOW_RWX | GUNYAH_MEM_UNMAP | GUNYAH_MEM_ACCESS_MASK))
+		goto err_file;
+
+	/* VM needs to have some permissions to the memory */
+	if (!(args->flags & GUNYAH_MEM_ALLOW_RWX))
+		goto err_file;
+
+	if (access != GUNYAH_MEM_DEFAULT_ACCESS &&
+	    access != GUNYAH_MEM_FORCE_LEND && access != GUNYAH_MEM_FORCE_SHARE)
+		goto err_file;
+
+	if (!PAGE_ALIGNED(args->guest_addr) || !PAGE_ALIGNED(args->offset) ||
+	    !PAGE_ALIGNED(args->size))
+		goto err_file;
+
+	if (args->flags & GUNYAH_MEM_UNMAP) {
+		args->flags &= ~GUNYAH_MEM_UNMAP;
+		ret = gunyah_gmem_remove_mapping(ghvm, file, args);
+	} else {
+		ret = gunyah_gmem_add_mapping(ghvm, file, args);
+	}
+
+err_file:
+	if (ret)
+		fput(file);
+	return ret;
+}
diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index 238a7a4da554b..43878a39d4714 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -404,6 +404,8 @@ static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 	INIT_LIST_HEAD(&ghvm->resource_tickets);
 
 	mt_init(&ghvm->mm);
+	mt_init(&ghvm->bindings);
+	init_rwsem(&ghvm->bindings_lock);
 
 	ghvm->addrspace_ticket.resource_type = GUNYAH_RESOURCE_TYPE_ADDR_SPACE;
 	ghvm->addrspace_ticket.label = GUNYAH_VM_ADDRSPACE_LABEL;
@@ -556,6 +558,14 @@ static long gunyah_vm_ioctl(struct file *filp, unsigned int cmd,
 		r = gunyah_vm_rm_function_instance(ghvm, &f);
 		break;
 	}
+	case GUNYAH_VM_MAP_MEM: {
+		struct gunyah_map_mem_args args;
+
+		if (copy_from_user(&args, argp, sizeof(args)))
+			return -EFAULT;
+
+		return gunyah_gmem_modify_mapping(ghvm, &args);
+	}
 	default:
 		r = -ENOTTY;
 		break;
@@ -573,6 +583,8 @@ EXPORT_SYMBOL_GPL(gunyah_vm_get);
 static void _gunyah_vm_put(struct kref *kref)
 {
 	struct gunyah_vm *ghvm = container_of(kref, struct gunyah_vm, kref);
+	struct gunyah_gmem_binding *b;
+	unsigned long idx = 0;
 	int ret;
 
 	/**
@@ -584,6 +596,13 @@ static void _gunyah_vm_put(struct kref *kref)
 
 	gunyah_vm_remove_functions(ghvm);
 
+	down_write(&ghvm->bindings_lock);
+	mt_for_each(&ghvm->bindings, b, idx, ULONG_MAX) {
+		gunyah_gmem_remove_binding(b);
+	}
+	up_write(&ghvm->bindings_lock);
+	WARN_ON(!mtree_empty(&ghvm->bindings));
+	mtree_destroy(&ghvm->bindings);
 	/**
 	 * If this fails, we're going to lose the memory for good and is
 	 * BUG_ON-worthy, but not unrecoverable (we just lose memory).
@@ -615,6 +634,7 @@ static void _gunyah_vm_put(struct kref *kref)
 		/* clang-format on */
 	}
 
+	WARN_ON(!mtree_empty(&ghvm->mm));
 	mtree_destroy(&ghvm->mm);
 
 	if (ghvm->vm_status > GUNYAH_RM_VM_STATUS_NO_STATE) {
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index 7ac0dd066991b..d9f101fc52632 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -38,6 +38,9 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
  * @mm: A maple tree of all memory that has been mapped to a VM.
  *      Indices are guest frame numbers; entries are either folios or
  *      RM mem parcels
+ * @bindings: A maple tree of guest memfd bindings. Indices are guest frame
+ *            numbers; entries are &struct gunyah_gmem_binding
+ * @bindings_lock: For serialization to @bindings
  * @addrspace_ticket: Resource ticket to the capability for guest VM's
  *                    address space
  * @host_private_extent_ticket: Resource ticket to the capability for our
@@ -77,6 +80,8 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
 struct gunyah_vm {
 	u16 vmid;
 	struct maple_tree mm;
+	struct maple_tree bindings;
+	struct rw_semaphore bindings_lock;
 	struct gunyah_vm_resource_ticket addrspace_ticket,
 		host_private_extent_ticket, host_shared_extent_ticket,
 		guest_private_extent_ticket, guest_shared_extent_ticket;
@@ -172,5 +177,9 @@ int gunyah_vm_reclaim_folio(struct gunyah_vm *ghvm, u64 gfn, struct folio *folio
 int gunyah_vm_reclaim_range(struct gunyah_vm *ghvm, u64 gfn, u64 nr);
 
 int gunyah_guest_mem_create(struct gunyah_create_mem_args *args);
+int gunyah_gmem_modify_mapping(struct gunyah_vm *ghvm,
+			       struct gunyah_map_mem_args *args);
+struct gunyah_gmem_binding;
+void gunyah_gmem_remove_binding(struct gunyah_gmem_binding *binding);
 
 #endif
diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h
index c5f506350364d..1af4c5ae6bc3e 100644
--- a/include/uapi/linux/gunyah.h
+++ b/include/uapi/linux/gunyah.h
@@ -87,6 +87,47 @@ struct gunyah_fn_desc {
 #define GUNYAH_VM_ADD_FUNCTION	_IOW(GUNYAH_IOCTL_TYPE, 0x4, struct gunyah_fn_desc)
 #define GUNYAH_VM_REMOVE_FUNCTION	_IOW(GUNYAH_IOCTL_TYPE, 0x7, struct gunyah_fn_desc)
 
+/**
+ * enum gunyah_map_flags- Possible flags on &struct gunyah_map_mem_args
+ * @GUNYAH_MEM_DEFAULT_SHARE: Use default host access for the VM type
+ * @GUNYAH_MEM_FORCE_LEND: Force unmapping the memory once the guest starts to use
+ * @GUNYAH_MEM_FORCE_SHARE: Allow host to continue accessing memory when guest starts to use
+ * @GUNYAH_MEM_ALLOW_READ: Allow guest to read memory
+ * @GUNYAH_MEM_ALLOW_WRITE: Allow guest to write to the memory
+ * @GUNYAH_MEM_ALLOW_EXEC: Allow guest to execute instructions in the memory
+ */
+enum gunyah_map_flags {
+	GUNYAH_MEM_DEFAULT_ACCESS = 0,
+	GUNYAH_MEM_FORCE_LEND = 1,
+	GUNYAH_MEM_FORCE_SHARE = 2,
+#define GUNYAH_MEM_ACCESS_MASK 0x7
+
+	GUNYAH_MEM_ALLOW_READ = 1UL << 4,
+	GUNYAH_MEM_ALLOW_WRITE = 1UL << 5,
+	GUNYAH_MEM_ALLOW_EXEC = 1UL << 6,
+	GUNYAH_MEM_ALLOW_RWX =
+		(GUNYAH_MEM_ALLOW_READ | GUNYAH_MEM_ALLOW_WRITE | GUNYAH_MEM_ALLOW_EXEC),
+
+	GUNYAH_MEM_UNMAP = 1UL << 8,
+};
+
+/**
+ * struct gunyah_map_mem_args - Description to provide guest memory into a VM
+ * @guest_addr: Location in guest address space to place the memory
+ * @flags: See &enum gunyah_map_flags.
+ * @guest_mem_fd: File descriptor created by GUNYAH_CREATE_GUEST_MEM
+ * @offset: Offset into the guest memory file
+ */
+struct gunyah_map_mem_args {
+	__u64 guest_addr;
+	__u32 flags;
+	__u32 guest_mem_fd;
+	__u64 offset;
+	__u64 size;
+};
+
+#define GUNYAH_VM_MAP_MEM _IOW(GUNYAH_IOCTL_TYPE, 0x9, struct gunyah_map_mem_args)
+
 /*
  * ioctls for vCPU fds
  */

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:39 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:39 -0800
Subject: [PATCH v17 16/35] gunyah: Add hypercalls for demand paging
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-16-1e9da6763d38@quicinc.com>

Three hypercalls are needed to support demand paging.
In create page mappings for a virtual machine's address space, memory
must be moved to a memory extent that is allowed to be mapped into that
address space. Memory extents are Gunyah's implementation of access
control. Once the memory is moved to the proper memory extent, the
memory can be mapped into the VM's address space. Implement the
bindings to perform those hypercalls.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 arch/arm64/gunyah/gunyah_hypercall.c | 87 ++++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/gunyah.h      | 21 +++++++++
 include/linux/gunyah.h               | 56 +++++++++++++++++++++++
 3 files changed, 164 insertions(+)

diff --git a/arch/arm64/gunyah/gunyah_hypercall.c b/arch/arm64/gunyah/gunyah_hypercall.c
index fee21df42c176..38403dc28c66f 100644
--- a/arch/arm64/gunyah/gunyah_hypercall.c
+++ b/arch/arm64/gunyah/gunyah_hypercall.c
@@ -39,6 +39,9 @@ EXPORT_SYMBOL_GPL(arch_is_gunyah_guest);
 #define GUNYAH_HYPERCALL_HYP_IDENTIFY		GUNYAH_HYPERCALL(0x8000)
 #define GUNYAH_HYPERCALL_MSGQ_SEND		GUNYAH_HYPERCALL(0x801B)
 #define GUNYAH_HYPERCALL_MSGQ_RECV		GUNYAH_HYPERCALL(0x801C)
+#define GUNYAH_HYPERCALL_ADDRSPACE_MAP		GUNYAH_HYPERCALL(0x802B)
+#define GUNYAH_HYPERCALL_ADDRSPACE_UNMAP	GUNYAH_HYPERCALL(0x802C)
+#define GUNYAH_HYPERCALL_MEMEXTENT_DONATE	GUNYAH_HYPERCALL(0x8061)
 #define GUNYAH_HYPERCALL_VCPU_RUN		GUNYAH_HYPERCALL(0x8065)
 /* clang-format on */
 
@@ -114,6 +117,90 @@ enum gunyah_error gunyah_hypercall_msgq_recv(u64 capid, void *buff, size_t size,
 }
 EXPORT_SYMBOL_GPL(gunyah_hypercall_msgq_recv);
 
+/**
+ * gunyah_hypercall_addrspace_map() - Add memory to an address space from a memory extent
+ * @capid: Address space capability ID
+ * @extent_capid: Memory extent capability ID
+ * @vbase: location in address space
+ * @extent_attrs: Attributes for the memory
+ * @flags: Flags for address space mapping
+ * @offset: Offset into memory extent (physical address of memory)
+ * @size: Size of memory to map; must be page-aligned
+ */
+enum gunyah_error gunyah_hypercall_addrspace_map(u64 capid, u64 extent_capid, u64 vbase,
+					u32 extent_attrs, u32 flags, u64 offset, u64 size)
+{
+	struct arm_smccc_1_2_regs args = {
+		.a0 = GUNYAH_HYPERCALL_ADDRSPACE_MAP,
+		.a1 = capid,
+		.a2 = extent_capid,
+		.a3 = vbase,
+		.a4 = extent_attrs,
+		.a5 = flags,
+		.a6 = offset,
+		.a7 = size,
+		/* C language says this will be implictly zero. Gunyah requires 0, so be explicit */
+		.a8 = 0,
+	};
+	struct arm_smccc_1_2_regs res;
+
+	arm_smccc_1_2_hvc(&args, &res);
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_addrspace_map);
+
+/**
+ * gunyah_hypercall_addrspace_unmap() - Remove memory from an address space
+ * @capid: Address space capability ID
+ * @extent_capid: Memory extent capability ID
+ * @vbase: location in address space
+ * @flags: Flags for address space mapping
+ * @offset: Offset into memory extent (physical address of memory)
+ * @size: Size of memory to map; must be page-aligned
+ */
+enum gunyah_error gunyah_hypercall_addrspace_unmap(u64 capid, u64 extent_capid, u64 vbase,
+					u32 flags, u64 offset, u64 size)
+{
+	struct arm_smccc_1_2_regs args = {
+		.a0 = GUNYAH_HYPERCALL_ADDRSPACE_UNMAP,
+		.a1 = capid,
+		.a2 = extent_capid,
+		.a3 = vbase,
+		.a4 = flags,
+		.a5 = offset,
+		.a6 = size,
+		/* C language says this will be implictly zero. Gunyah requires 0, so be explicit */
+		.a7 = 0,
+	};
+	struct arm_smccc_1_2_regs res;
+
+	arm_smccc_1_2_hvc(&args, &res);
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_addrspace_unmap);
+
+/**
+ * gunyah_hypercall_memextent_donate() - Donate memory from one memory extent to another
+ * @options: donate options
+ * @from_capid: Memory extent capability ID to donate from
+ * @to_capid: Memory extent capability ID to donate to
+ * @offset: Offset into memory extent (physical address of memory)
+ * @size: Size of memory to donate; must be page-aligned
+ */
+enum gunyah_error gunyah_hypercall_memextent_donate(u32 options, u64 from_capid, u64 to_capid,
+					    u64 offset, u64 size)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GUNYAH_HYPERCALL_MEMEXTENT_DONATE, options, from_capid, to_capid,
+				offset, size, 0, &res);
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gunyah_hypercall_memextent_donate);
+
 /**
  * gunyah_hypercall_vcpu_run() - Donate CPU time to a vcpu
  * @capid: capability ID of the vCPU to run
diff --git a/arch/arm64/include/asm/gunyah.h b/arch/arm64/include/asm/gunyah.h
index 0cd3debe22b64..4adf24977fd18 100644
--- a/arch/arm64/include/asm/gunyah.h
+++ b/arch/arm64/include/asm/gunyah.h
@@ -33,4 +33,25 @@ static inline int arch_gunyah_fill_irq_fwspec_params(u32 virq,
 	return 0;
 }
 
+enum arch_gunyah_memtype {
+	/* clang-format off */
+	GUNYAH_MEMTYPE_DEVICE_nGnRnE	= 0,
+	GUNYAH_DEVICE_nGnRE		= 1,
+	GUNYAH_DEVICE_nGRE		= 2,
+	GUNYAH_DEVICE_GRE		= 3,
+
+	GUNYAH_NORMAL_NC	= 0b0101,
+	GUNYAH_NORMAL_ONC_IWT	= 0b0110,
+	GUNYAH_NORMAL_ONC_IWB	= 0b0111,
+	GUNYAH_NORMAL_OWT_INC	= 0b1001,
+	GUNYAH_NORMAL_WT	= 0b1010,
+	GUNYAH_NORMAL_OWT_IWB	= 0b1011,
+	GUNYAH_NORMAL_OWB_INC	= 0b1101,
+	GUNYAH_NORMAL_OWB_IWT	= 0b1110,
+	GUNYAH_NORMAL_WB	= 0b1111,
+	/* clang-format on */
+};
+
+#define ARCH_GUNYAH_DEFAULT_MEMTYPE	GUNYAH_NORMAL_WB
+
 #endif
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index 6c24544f38dc9..24c02c6827738 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -273,6 +273,62 @@ enum gunyah_error gunyah_hypercall_msgq_send(u64 capid, size_t size, void *buff,
 enum gunyah_error gunyah_hypercall_msgq_recv(u64 capid, void *buff, size_t size,
 					     size_t *recv_size, bool *ready);
 
+#define GUNYAH_ADDRSPACE_SELF_CAP 0
+
+enum gunyah_pagetable_access {
+	/* clang-format off */
+	GUNYAH_PAGETABLE_ACCESS_NONE		= 0,
+	GUNYAH_PAGETABLE_ACCESS_X		= 1,
+	GUNYAH_PAGETABLE_ACCESS_W		= 2,
+	GUNYAH_PAGETABLE_ACCESS_R		= 4,
+	GUNYAH_PAGETABLE_ACCESS_RX		= 5,
+	GUNYAH_PAGETABLE_ACCESS_RW		= 6,
+	GUNYAH_PAGETABLE_ACCESS_RWX		= 7,
+	/* clang-format on */
+};
+
+/* clang-format off */
+#define GUNYAH_MEMEXTENT_MAPPING_USER_ACCESS		GENMASK_ULL(2, 0)
+#define GUNYAH_MEMEXTENT_MAPPING_KERNEL_ACCESS		GENMASK_ULL(6, 4)
+#define GUNYAH_MEMEXTENT_MAPPING_TYPE			GENMASK_ULL(23, 16)
+/* clang-format on */
+
+enum gunyah_memextent_donate_type {
+	/* clang-format off */
+	GUNYAH_MEMEXTENT_DONATE_TO_CHILD		= 0,
+	GUNYAH_MEMEXTENT_DONATE_TO_PARENT		= 1,
+	GUNYAH_MEMEXTENT_DONATE_TO_SIBLING		= 2,
+	GUNYAH_MEMEXTENT_DONATE_TO_PROTECTED		= 3,
+	GUNYAH_MEMEXTENT_DONATE_FROM_PROTECTED		= 4,
+	/* clang-format on */
+};
+
+enum gunyah_addrspace_map_flag_bits {
+	/* clang-format off */
+	GUNYAH_ADDRSPACE_MAP_FLAG_PARTIAL	= 0,
+	GUNYAH_ADDRSPACE_MAP_FLAG_PRIVATE	= 1,
+	GUNYAH_ADDRSPACE_MAP_FLAG_VMMIO		= 2,
+	GUNYAH_ADDRSPACE_MAP_FLAG_NOSYNC	= 31,
+	/* clang-format on */
+};
+
+enum gunyah_error gunyah_hypercall_addrspace_map(u64 capid, u64 extent_capid,
+						 u64 vbase, u32 extent_attrs,
+						 u32 flags, u64 offset,
+						 u64 size);
+enum gunyah_error gunyah_hypercall_addrspace_unmap(u64 capid, u64 extent_capid,
+						   u64 vbase, u32 flags,
+						   u64 offset, u64 size);
+
+/* clang-format off */
+#define GUNYAH_MEMEXTENT_OPTION_TYPE_MASK	GENMASK_ULL(7, 0)
+#define GUNYAH_MEMEXTENT_OPTION_NOSYNC		BIT(31)
+/* clang-format on */
+
+enum gunyah_error gunyah_hypercall_memextent_donate(u32 options, u64 from_capid,
+						    u64 to_capid, u64 offset,
+						    u64 size);
+
 struct gunyah_hypercall_vcpu_run_resp {
 	union {
 		enum {

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:36 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:36 -0800
Subject: [PATCH v17 13/35] gunyah: vm_mgr: Add framework for VM Functions
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-13-1e9da6763d38@quicinc.com>

Introduce a framework for Gunyah userspace to install VM functions. VM
functions are optional interfaces to the virtual machine. vCPUs,
ioeventfs, and irqfds are examples of such VM functions and are
implemented in subsequent patches.

A generic framework is implemented instead of individual ioctls to
create vCPUs, irqfds, etc., in order to simplify the VM manager core
implementation and allow dynamic loading of VM function modules.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/vm_mgr.c | 207 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/virt/gunyah/vm_mgr.h |  10 +++
 include/linux/gunyah.h       |  86 +++++++++++++++++-
 include/uapi/linux/gunyah.h  |  18 ++++
 4 files changed, 317 insertions(+), 4 deletions(-)

diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index 2cde4d501204a..a619dd10972a5 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -6,15 +6,175 @@
 #define pr_fmt(fmt) "gunyah_vm_mgr: " fmt
 
 #include <linux/anon_inodes.h>
+#include <linux/compat.h>
 #include <linux/file.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
+#include <linux/xarray.h>
 
 #include <uapi/linux/gunyah.h>
 
 #include "rsc_mgr.h"
 #include "vm_mgr.h"
 
+static DEFINE_XARRAY(gunyah_vm_functions);
+
+static void gunyah_vm_put_function(struct gunyah_vm_function *fn)
+{
+	module_put(fn->mod);
+}
+
+static struct gunyah_vm_function *gunyah_vm_get_function(u32 type)
+{
+	struct gunyah_vm_function *fn;
+
+	fn = xa_load(&gunyah_vm_functions, type);
+	if (!fn) {
+		request_module("ghfunc:%d", type);
+
+		fn = xa_load(&gunyah_vm_functions, type);
+	}
+
+	if (!fn || !try_module_get(fn->mod))
+		fn = ERR_PTR(-ENOENT);
+
+	return fn;
+}
+
+static void
+gunyah_vm_remove_function_instance(struct gunyah_vm_function_instance *inst)
+	__must_hold(&inst->ghvm->fn_lock)
+{
+	inst->fn->unbind(inst);
+	list_del(&inst->vm_list);
+	gunyah_vm_put_function(inst->fn);
+	kfree(inst->argp);
+	kfree(inst);
+}
+
+static void gunyah_vm_remove_functions(struct gunyah_vm *ghvm)
+{
+	struct gunyah_vm_function_instance *inst, *iiter;
+
+	mutex_lock(&ghvm->fn_lock);
+	list_for_each_entry_safe(inst, iiter, &ghvm->functions, vm_list) {
+		gunyah_vm_remove_function_instance(inst);
+	}
+	mutex_unlock(&ghvm->fn_lock);
+}
+
+static long gunyah_vm_add_function_instance(struct gunyah_vm *ghvm,
+					    struct gunyah_fn_desc *f)
+{
+	struct gunyah_vm_function_instance *inst;
+	void __user *argp;
+	long r = 0;
+
+	if (f->arg_size > GUNYAH_FN_MAX_ARG_SIZE) {
+		dev_err_ratelimited(ghvm->parent, "%s: arg_size > %d\n",
+				    __func__, GUNYAH_FN_MAX_ARG_SIZE);
+		return -EINVAL;
+	}
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->arg_size = f->arg_size;
+	if (inst->arg_size) {
+		inst->argp = kzalloc(inst->arg_size, GFP_KERNEL);
+		if (!inst->argp) {
+			r = -ENOMEM;
+			goto free;
+		}
+
+		argp = u64_to_user_ptr(f->arg);
+		if (copy_from_user(inst->argp, argp, f->arg_size)) {
+			r = -EFAULT;
+			goto free_arg;
+		}
+	}
+
+	inst->fn = gunyah_vm_get_function(f->type);
+	if (IS_ERR(inst->fn)) {
+		r = PTR_ERR(inst->fn);
+		goto free_arg;
+	}
+
+	inst->ghvm = ghvm;
+	inst->rm = ghvm->rm;
+
+	mutex_lock(&ghvm->fn_lock);
+	r = inst->fn->bind(inst);
+	if (r < 0) {
+		mutex_unlock(&ghvm->fn_lock);
+		gunyah_vm_put_function(inst->fn);
+		goto free_arg;
+	}
+
+	list_add(&inst->vm_list, &ghvm->functions);
+	mutex_unlock(&ghvm->fn_lock);
+
+	return r;
+free_arg:
+	kfree(inst->argp);
+free:
+	kfree(inst);
+	return r;
+}
+
+static long gunyah_vm_rm_function_instance(struct gunyah_vm *ghvm,
+					   struct gunyah_fn_desc *f)
+{
+	struct gunyah_vm_function_instance *inst, *iter;
+	void __user *user_argp;
+	void *argp __free(kfree) = NULL;
+	long r = 0;
+
+	if (f->arg_size) {
+		argp = kzalloc(f->arg_size, GFP_KERNEL);
+		if (!argp)
+			return -ENOMEM;
+
+		user_argp = u64_to_user_ptr(f->arg);
+		if (copy_from_user(argp, user_argp, f->arg_size))
+			return -EFAULT;
+	}
+
+	r = mutex_lock_interruptible(&ghvm->fn_lock);
+	if (r)
+		return r;
+
+	r = -ENOENT;
+	list_for_each_entry_safe(inst, iter, &ghvm->functions, vm_list) {
+		if (inst->fn->type == f->type &&
+		    inst->fn->compare(inst, argp, f->arg_size)) {
+			gunyah_vm_remove_function_instance(inst);
+			r = 0;
+		}
+	}
+
+	mutex_unlock(&ghvm->fn_lock);
+	return r;
+}
+
+int gunyah_vm_function_register(struct gunyah_vm_function *fn)
+{
+	if (!fn->bind || !fn->unbind)
+		return -EINVAL;
+
+	return xa_err(xa_store(&gunyah_vm_functions, fn->type, fn, GFP_KERNEL));
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_function_register);
+
+void gunyah_vm_function_unregister(struct gunyah_vm_function *fn)
+{
+	/* Expecting unregister to only come when unloading a module */
+	WARN_ON(fn->mod && module_refcount(fn->mod));
+	xa_erase(&gunyah_vm_functions, fn->type);
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_function_unregister);
+
 int gunyah_vm_add_resource_ticket(struct gunyah_vm *ghvm,
 				  struct gunyah_vm_resource_ticket *ticket)
 {
@@ -198,7 +358,11 @@ static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 
 	init_rwsem(&ghvm->status_lock);
 	init_waitqueue_head(&ghvm->vm_status_wait);
+	kref_init(&ghvm->kref);
 	ghvm->vm_status = GUNYAH_RM_VM_STATUS_NO_STATE;
+
+	INIT_LIST_HEAD(&ghvm->functions);
+	mutex_init(&ghvm->fn_lock);
 	mutex_init(&ghvm->resources_lock);
 	INIT_LIST_HEAD(&ghvm->resources);
 	INIT_LIST_HEAD(&ghvm->resource_tickets);
@@ -311,6 +475,7 @@ static long gunyah_vm_ioctl(struct file *filp, unsigned int cmd,
 			    unsigned long arg)
 {
 	struct gunyah_vm *ghvm = filp->private_data;
+	void __user *argp = (void __user *)arg;
 	long r;
 
 	switch (cmd) {
@@ -318,6 +483,24 @@ static long gunyah_vm_ioctl(struct file *filp, unsigned int cmd,
 		r = gunyah_vm_ensure_started(ghvm);
 		break;
 	}
+	case GUNYAH_VM_ADD_FUNCTION: {
+		struct gunyah_fn_desc f;
+
+		if (copy_from_user(&f, argp, sizeof(f)))
+			return -EFAULT;
+
+		r = gunyah_vm_add_function_instance(ghvm, &f);
+		break;
+	}
+	case GUNYAH_VM_REMOVE_FUNCTION: {
+		struct gunyah_fn_desc f;
+
+		if (copy_from_user(&f, argp, sizeof(f)))
+			return -EFAULT;
+
+		r = gunyah_vm_rm_function_instance(ghvm, &f);
+		break;
+	}
 	default:
 		r = -ENOTTY;
 		break;
@@ -326,9 +509,15 @@ static long gunyah_vm_ioctl(struct file *filp, unsigned int cmd,
 	return r;
 }
 
-static int gunyah_vm_release(struct inode *inode, struct file *filp)
+int __must_check gunyah_vm_get(struct gunyah_vm *ghvm)
 {
-	struct gunyah_vm *ghvm = filp->private_data;
+	return kref_get_unless_zero(&ghvm->kref);
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_get);
+
+static void _gunyah_vm_put(struct kref *kref)
+{
+	struct gunyah_vm *ghvm = container_of(kref, struct gunyah_vm, kref);
 	int ret;
 
 	/**
@@ -338,6 +527,7 @@ static int gunyah_vm_release(struct inode *inode, struct file *filp)
 	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_RUNNING)
 		gunyah_vm_stop(ghvm);
 
+	gunyah_vm_remove_functions(ghvm);
 	gunyah_vm_clean_resources(ghvm);
 
 	if (ghvm->vm_status == GUNYAH_RM_VM_STATUS_EXITED ||
@@ -364,6 +554,19 @@ static int gunyah_vm_release(struct inode *inode, struct file *filp)
 
 	gunyah_rm_put(ghvm->rm);
 	kfree(ghvm);
+}
+
+void gunyah_vm_put(struct gunyah_vm *ghvm)
+{
+	kref_put(&ghvm->kref, _gunyah_vm_put);
+}
+EXPORT_SYMBOL_GPL(gunyah_vm_put);
+
+static int gunyah_vm_release(struct inode *inode, struct file *filp)
+{
+	struct gunyah_vm *ghvm = filp->private_data;
+
+	gunyah_vm_put(ghvm);
 	return 0;
 }
 
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index 0d291f7228859..190a95ee8da64 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -7,6 +7,8 @@
 #define _GUNYAH_VM_MGR_PRIV_H
 
 #include <linux/device.h>
+#include <linux/kref.h>
+#include <linux/mutex.h>
 #include <linux/rwsem.h>
 #include <linux/wait.h>
 
@@ -26,6 +28,10 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
  * @vm_status: Current state of the VM, as last reported by RM
  * @vm_status_wait: Wait queue for status @vm_status changes
  * @status_lock: Serializing state transitions
+ * @kref: Reference counter for VM functions
+ * @fn_lock: Serialization addition of functions
+ * @functions: List of &struct gunyah_vm_function_instance that have been
+ *             created by user for this VM.
  * @resource_lock: Serializing addition of resources and resource tickets
  * @resources: List of &struct gunyah_resource that are associated with this VM
  * @resource_tickets: List of &struct gunyah_vm_resource_ticket
@@ -42,6 +48,10 @@ struct gunyah_vm {
 	enum gunyah_rm_vm_status vm_status;
 	wait_queue_head_t vm_status_wait;
 	struct rw_semaphore status_lock;
+
+	struct kref kref;
+	struct mutex fn_lock;
+	struct list_head functions;
 	struct mutex resources_lock;
 	struct list_head resources;
 	struct list_head resource_tickets;
diff --git a/include/linux/gunyah.h b/include/linux/gunyah.h
index 0017691002607..18ecebf41a3ff 100644
--- a/include/linux/gunyah.h
+++ b/include/linux/gunyah.h
@@ -11,8 +11,92 @@
 #include <linux/interrupt.h>
 #include <linux/limits.h>
 #include <linux/list.h>
+#include <linux/mod_devicetable.h>
 #include <linux/types.h>
 
+#include <uapi/linux/gunyah.h>
+
+struct gunyah_vm;
+
+int __must_check gunyah_vm_get(struct gunyah_vm *ghvm);
+void gunyah_vm_put(struct gunyah_vm *ghvm);
+
+struct gunyah_vm_function_instance;
+/**
+ * struct gunyah_vm_function - Represents a function type
+ * @type: value from &enum gunyah_fn_type
+ * @name: friendly name for debug purposes
+ * @mod: owner of the function type
+ * @bind: Called when a new function of this type has been allocated.
+ * @unbind: Called when the function instance is being destroyed.
+ * @compare: Compare function instance @f's argument to the provided arg.
+ *           Return true if they are equivalent. Used on GUNYAH_VM_REMOVE_FUNCTION.
+ */
+struct gunyah_vm_function {
+	u32 type;
+	const char *name;
+	struct module *mod;
+	long (*bind)(struct gunyah_vm_function_instance *f);
+	void (*unbind)(struct gunyah_vm_function_instance *f);
+	bool (*compare)(const struct gunyah_vm_function_instance *f,
+			const void *arg, size_t size);
+};
+
+/**
+ * struct gunyah_vm_function_instance - Represents one function instance
+ * @arg_size: size of user argument
+ * @argp: pointer to user argument
+ * @ghvm: Pointer to VM instance
+ * @rm: Pointer to resource manager for the VM instance
+ * @fn: The ops for the function
+ * @data: Private data for function
+ * @vm_list: for gunyah_vm's functions list
+ */
+struct gunyah_vm_function_instance {
+	size_t arg_size;
+	void *argp;
+	struct gunyah_vm *ghvm;
+	struct gunyah_rm *rm;
+	struct gunyah_vm_function *fn;
+	void *data;
+	struct list_head vm_list;
+};
+
+int gunyah_vm_function_register(struct gunyah_vm_function *f);
+void gunyah_vm_function_unregister(struct gunyah_vm_function *f);
+
+/* Since the function identifiers were setup in a uapi header as an
+ * enum and we do no want to change that, the user must supply the expanded
+ * constant as well and the compiler checks they are the same.
+ * See also MODULE_ALIAS_RDMA_NETLINK.
+ */
+#define MODULE_ALIAS_GUNYAH_VM_FUNCTION(_type, _idx)        \
+	static inline void __maybe_unused __chk##_idx(void) \
+	{                                                   \
+		BUILD_BUG_ON(_type != _idx);                \
+	}                                                   \
+	MODULE_ALIAS("ghfunc:" __stringify(_idx))
+
+#define DECLARE_GUNYAH_VM_FUNCTION(_name, _type, _bind, _unbind, _compare) \
+	static struct gunyah_vm_function _name = {                         \
+		.type = _type,                                             \
+		.name = __stringify(_name),                                \
+		.mod = THIS_MODULE,                                        \
+		.bind = _bind,                                             \
+		.unbind = _unbind,                                         \
+		.compare = _compare,                                       \
+	}
+
+#define module_gunyah_vm_function(__gf)                  \
+	module_driver(__gf, gunyah_vm_function_register, \
+		      gunyah_vm_function_unregister)
+
+#define DECLARE_GUNYAH_VM_FUNCTION_INIT(_name, _type, _idx, _bind, _unbind, \
+					_compare)                           \
+	DECLARE_GUNYAH_VM_FUNCTION(_name, _type, _bind, _unbind, _compare); \
+	module_gunyah_vm_function(_name);                                   \
+	MODULE_ALIAS_GUNYAH_VM_FUNCTION(_type, _idx)
+
 /* Matches resource manager's resource types for VM_GET_HYP_RESOURCES RPC */
 enum gunyah_resource_type {
 	/* clang-format off */
@@ -35,8 +119,6 @@ struct gunyah_resource {
 	u32 rm_label;
 };
 
-struct gunyah_vm;
-
 /**
  * struct gunyah_vm_resource_ticket - Represents a ticket to reserve access to VM resource(s)
  * @vm_list: for @gunyah_vm->resource_tickets
diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h
index 31e7f79a6c398..1b7cb5fde70a2 100644
--- a/include/uapi/linux/gunyah.h
+++ b/include/uapi/linux/gunyah.h
@@ -25,4 +25,22 @@
  */
 #define GUNYAH_VM_START		_IO(GUNYAH_IOCTL_TYPE, 0x3)
 
+#define GUNYAH_FN_MAX_ARG_SIZE		256
+
+/**
+ * struct gunyah_fn_desc - Arguments to create a VM function
+ * @type: Type of the function. See &enum gunyah_fn_type.
+ * @arg_size: Size of argument to pass to the function. arg_size <= GUNYAH_FN_MAX_ARG_SIZE
+ * @arg: Pointer to argument given to the function. See &enum gunyah_fn_type for expected
+ *       arguments for a function type.
+ */
+struct gunyah_fn_desc {
+	__u32 type;
+	__u32 arg_size;
+	__u64 arg;
+};
+
+#define GUNYAH_VM_ADD_FUNCTION	_IOW(GUNYAH_IOCTL_TYPE, 0x4, struct gunyah_fn_desc)
+#define GUNYAH_VM_REMOVE_FUNCTION	_IOW(GUNYAH_IOCTL_TYPE, 0x7, struct gunyah_fn_desc)
+
 #endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:48 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:48 -0800
Subject: [PATCH v17 25/35] virt: gunyah: guestmem: Initialize RM mem
 parcels from guestmem
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-25-1e9da6763d38@quicinc.com>

Gunyah Resource Manager sets up a virtual machine based on a device
tree which lives in guest memory. Resource manager requires this memory
to be provided as a memory parcel for it to read and manipulate.
Implement a function to construct a memory parcel from a guestmem
binding.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/guest_memfd.c | 207 ++++++++++++++++++++++++++++++++++++++
 drivers/virt/gunyah/vm_mgr.h      |   6 ++
 2 files changed, 213 insertions(+)

diff --git a/drivers/virt/gunyah/guest_memfd.c b/drivers/virt/gunyah/guest_memfd.c
index d6be8bf67d996..0c35ffa616d9c 100644
--- a/drivers/virt/gunyah/guest_memfd.c
+++ b/drivers/virt/gunyah/guest_memfd.c
@@ -684,3 +684,210 @@ int gunyah_gmem_modify_mapping(struct gunyah_vm *ghvm,
 		fput(file);
 	return ret;
 }
+
+int gunyah_gmem_share_parcel(struct gunyah_vm *ghvm, struct gunyah_rm_mem_parcel *parcel,
+			     u64 *gfn, u64 *nr)
+{
+	struct folio *folio, *prev_folio;
+	unsigned long nr_entries, i, j, start, end;
+	struct gunyah_gmem_binding *b;
+	bool lend;
+	int ret;
+
+	parcel->mem_handle = GUNYAH_MEM_HANDLE_INVAL;
+
+	if (!*nr)
+		return -EINVAL;
+
+	down_read(&ghvm->bindings_lock);
+	b = mtree_load(&ghvm->bindings, *gfn);
+	if (!b || *gfn > b->gfn + b->nr || *gfn < b->gfn) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	/**
+	 * Generally, indices can be based on gfn, guest_memfd offset, or
+	 * offset into binding. start and end are based on offset into binding.
+	 */
+	start = *gfn - b->gfn;
+
+	if (start + *nr > b->nr) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+
+	end = start + *nr;
+	lend = gunyah_guest_mem_is_lend(ghvm, b->flags);
+
+	/**
+	 * First, calculate the number of physically discontiguous regions
+	 * the parcel covers. Each memory entry corresponds to one folio.
+	 * In future, each memory entry could correspond to contiguous
+	 * folios that are also adjacent in guest_memfd, but parcels
+	 * are only being used for small amounts of memory for now, so
+	 * this optimization is premature.
+	 */
+	nr_entries = 0;
+	prev_folio = NULL;
+	for (i = start + b->i_off; i < end + b->i_off;) {
+		folio = gunyah_gmem_get_folio(file_inode(b->file), i); /* A */
+		if (!folio) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		if (lend) {
+			/* don't lend a folio that is mapped by host */
+			if (!gunyah_folio_lend_safe(folio)) {
+				folio_unlock(folio);
+				folio_put(folio);
+				ret = -EPERM;
+				goto out;
+			}
+			folio_set_private(folio);
+		}
+
+		nr_entries++;
+		i = folio_index(folio) + folio_nr_pages(folio);
+	}
+	end = i - b->i_off;
+
+	parcel->mem_entries =
+		kcalloc(nr_entries, sizeof(*parcel->mem_entries), GFP_KERNEL);
+	if (!parcel->mem_entries) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/**
+	 * Walk through all the folios again, now filling the mem_entries array.
+	 */
+	j = 0;
+	prev_folio = NULL;
+	for (i = start + b->i_off; i < end + b->i_off; j++) {
+		folio = filemap_get_folio(file_inode(b->file)->i_mapping, i); /* B */
+		if (WARN_ON(IS_ERR(folio))) {
+			ret = PTR_ERR(folio);
+			i = end + b->i_off;
+			goto out;
+		}
+
+		parcel->mem_entries[j].size = cpu_to_le64(folio_size(folio));
+		parcel->mem_entries[j].phys_addr = cpu_to_le64(PFN_PHYS(folio_pfn(folio)));
+		i = folio_index(folio) + folio_nr_pages(folio);
+		folio_put(folio); /* B */
+	}
+	BUG_ON(j != nr_entries);
+	parcel->n_mem_entries = nr_entries;
+
+	if (lend)
+		parcel->n_acl_entries = 1;
+
+	parcel->acl_entries = kcalloc(parcel->n_acl_entries,
+				      sizeof(*parcel->acl_entries), GFP_KERNEL);
+	if (!parcel->n_acl_entries) {
+		ret = -ENOMEM;
+		goto free_entries;
+	}
+
+	parcel->acl_entries[0].vmid = cpu_to_le16(ghvm->vmid);
+	if (b->flags & GUNYAH_MEM_ALLOW_READ)
+		parcel->acl_entries[0].perms |= GUNYAH_RM_ACL_R;
+	if (b->flags & GUNYAH_MEM_ALLOW_WRITE)
+		parcel->acl_entries[0].perms |= GUNYAH_RM_ACL_W;
+	if (b->flags & GUNYAH_MEM_ALLOW_EXEC)
+		parcel->acl_entries[0].perms |= GUNYAH_RM_ACL_X;
+
+	if (!lend) {
+		u16 host_vmid;
+
+		ret = gunyah_rm_get_vmid(ghvm->rm, &host_vmid);
+		if (ret)
+			goto free_acl;
+
+		parcel->acl_entries[1].vmid = cpu_to_le16(host_vmid);
+		parcel->acl_entries[1].perms = GUNYAH_RM_ACL_R | GUNYAH_RM_ACL_W | GUNYAH_RM_ACL_X;
+	}
+
+	parcel->mem_handle = GUNYAH_MEM_HANDLE_INVAL;
+	folio = filemap_get_folio(file_inode(b->file)->i_mapping, start); /* C */
+	*gfn = folio_index(folio) - b->i_off + b->gfn;
+	*nr = end - (folio_index(folio) - b->i_off);
+	folio_put(folio); /* C */
+
+	ret = gunyah_rm_mem_share(ghvm->rm, parcel);
+	goto out;
+free_acl:
+	kfree(parcel->acl_entries);
+	parcel->acl_entries = NULL;
+free_entries:
+	kfree(parcel->mem_entries);
+	parcel->mem_entries = NULL;
+	parcel->n_mem_entries = 0;
+out:
+	/* unlock the folios */
+	for (j = start + b->i_off; j < i;) {
+		folio = filemap_get_folio(file_inode(b->file)->i_mapping, j); /* D */
+		if (WARN_ON(IS_ERR(folio)))
+			continue;
+		j = folio_index(folio) + folio_nr_pages(folio);
+		folio_unlock(folio); /* A */
+		if (ret) {
+			if (folio_test_private(folio)) {
+				gunyah_folio_host_reclaim(folio);
+				folio_clear_private(folio);
+			}
+			folio_put(folio); /* A */
+		}
+		folio_put(folio); /* D */
+		/* matching folio_put for A is done at
+		 * (1) gunyah_gmem_reclaim_parcel or
+		 * (2) after gunyah_gmem_parcel_to_paged, gunyah_vm_reclaim_folio
+		 */
+	}
+unlock:
+	up_read(&ghvm->bindings_lock);
+	return ret;
+}
+
+int gunyah_gmem_reclaim_parcel(struct gunyah_vm *ghvm,
+			       struct gunyah_rm_mem_parcel *parcel, u64 gfn,
+			       u64 nr)
+{
+	struct gunyah_rm_mem_entry *entry;
+	struct folio *folio;
+	pgoff_t i;
+	int ret;
+
+	if (parcel->mem_handle != GUNYAH_MEM_HANDLE_INVAL) {
+		ret = gunyah_rm_mem_reclaim(ghvm->rm, parcel);
+		if (ret) {
+			dev_err(ghvm->parent, "Failed to reclaim parcel: %d\n",
+				ret);
+			/* We can't reclaim the pages -- hold onto the pages
+			 * forever because we don't know what state the memory
+			 * is in
+			 */
+			return ret;
+		}
+		parcel->mem_handle = GUNYAH_MEM_HANDLE_INVAL;
+
+		for (i = 0; i < parcel->n_mem_entries; i++) {
+			entry = &parcel->mem_entries[i];
+
+			folio = pfn_folio(PHYS_PFN(le64_to_cpu(entry->phys_addr)));
+
+			if (folio_test_private(folio))
+				gunyah_folio_host_reclaim(folio);
+
+			folio_clear_private(folio);
+			folio_put(folio); /* A */
+		}
+
+		kfree(parcel->mem_entries);
+		kfree(parcel->acl_entries);
+	}
+
+	return 0;
+}
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index d9f101fc52632..b6bc66f018b09 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -181,5 +181,11 @@ int gunyah_gmem_modify_mapping(struct gunyah_vm *ghvm,
 			       struct gunyah_map_mem_args *args);
 struct gunyah_gmem_binding;
 void gunyah_gmem_remove_binding(struct gunyah_gmem_binding *binding);
+int gunyah_gmem_share_parcel(struct gunyah_vm *ghvm,
+			     struct gunyah_rm_mem_parcel *parcel, u64 *gfn,
+			     u64 *nr);
+int gunyah_gmem_reclaim_parcel(struct gunyah_vm *ghvm,
+			       struct gunyah_rm_mem_parcel *parcel, u64 gfn,
+			       u64 nr);
 
 #endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:42 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:42 -0800
Subject: [PATCH v17 19/35] arch/mm: Export direct {un,}map functions
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-19-1e9da6763d38@quicinc.com>

Firmware and hypervisor drivers can donate system heap memory to their
respective firmware/hypervisor entities. Those drivers should unmap the
pages from the kernel's logical map before doing so.

Export can_set_direct_map, set_direct_map_invalid_noflush, and
set_direct_map_default_noflush.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 arch/arm64/mm/pageattr.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 924843f1f661b..a9bd84588c98a 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -32,6 +32,7 @@ bool can_set_direct_map(void)
 	return rodata_full || debug_pagealloc_enabled() ||
 	       arm64_kfence_can_set_direct_map();
 }
+EXPORT_SYMBOL_GPL(can_set_direct_map);
 
 static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
 {
@@ -176,6 +177,7 @@ int set_direct_map_invalid_noflush(struct page *page)
 				   (unsigned long)page_address(page),
 				   PAGE_SIZE, change_page_range, &data);
 }
+EXPORT_SYMBOL_GPL(set_direct_map_invalid_noflush);
 
 int set_direct_map_default_noflush(struct page *page)
 {
@@ -191,6 +193,7 @@ int set_direct_map_default_noflush(struct page *page)
 				   (unsigned long)page_address(page),
 				   PAGE_SIZE, change_page_range, &data);
 }
+EXPORT_SYMBOL_GPL(set_direct_map_default_noflush);
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
 void __kernel_map_pages(struct page *page, int numpages, int enable)

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:50 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:50 -0800
Subject: [PATCH v17 27/35] gunyah: rsc_mgr: Add RPC to enable demand paging
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-27-1e9da6763d38@quicinc.com>

Add Gunyah Resource Manager RPC to enable demand paging for a virtual
machine. Resource manager needs to be informed of private memory regions
which will be demand paged and the location where the DTB memory parcel
should live in the guest's address space.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/rsc_mgr.h     | 12 +++++++
 drivers/virt/gunyah/rsc_mgr_rpc.c | 73 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)

diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h
index 68d08d3cff02d..99c2db18579ca 100644
--- a/drivers/virt/gunyah/rsc_mgr.h
+++ b/drivers/virt/gunyah/rsc_mgr.h
@@ -108,6 +108,18 @@ int gunyah_rm_get_hyp_resources(struct gunyah_rm *rm, u16 vmid,
 
 int gunyah_rm_get_vmid(struct gunyah_rm *rm, u16 *vmid);
 
+int gunyah_rm_vm_set_demand_paging(struct gunyah_rm *rm, u16 vmid, u32 count,
+				   struct gunyah_rm_mem_entry *mem_entries);
+
+enum gunyah_rm_range_id {
+	GUNYAH_RM_RANGE_ID_IMAGE = 0,
+	GUNYAH_RM_RANGE_ID_FIRMWARE = 1,
+};
+
+int gunyah_rm_vm_set_address_layout(struct gunyah_rm *rm, u16 vmid,
+				    enum gunyah_rm_range_id range_id,
+				    u64 base_address, u64 size);
+
 struct gunyah_resource *
 gunyah_rm_alloc_resource(struct gunyah_rm *rm,
 			 struct gunyah_rm_hyp_resource *hyp_resource);
diff --git a/drivers/virt/gunyah/rsc_mgr_rpc.c b/drivers/virt/gunyah/rsc_mgr_rpc.c
index 99e5a3f1a5bb9..dfffcf02ddaea 100644
--- a/drivers/virt/gunyah/rsc_mgr_rpc.c
+++ b/drivers/virt/gunyah/rsc_mgr_rpc.c
@@ -24,6 +24,8 @@
 #define GUNYAH_RM_RPC_VM_INIT			0x5600000B
 #define GUNYAH_RM_RPC_VM_GET_HYP_RESOURCES	0x56000020
 #define GUNYAH_RM_RPC_VM_GET_VMID		0x56000024
+#define GUNYAH_RM_RPC_VM_SET_DEMAND_PAGING	0x56000033
+#define GUNYAH_RM_RPC_VM_SET_ADDRESS_LAYOUT	0x56000034
 /* clang-format on */
 
 struct gunyah_rm_vm_common_vmid_req {
@@ -103,6 +105,23 @@ struct gunyah_rm_vm_config_image_req {
 	__le64 dtb_size;
 } __packed;
 
+/* Call: VM_SET_DEMAND_PAGING */
+struct gunyah_rm_vm_set_demand_paging_req {
+	__le16 vmid;
+	__le16 _padding;
+	__le32 range_count;
+	DECLARE_FLEX_ARRAY(struct gunyah_rm_mem_entry, ranges);
+} __packed;
+
+/* Call: VM_SET_ADDRESS_LAYOUT */
+struct gunyah_rm_vm_set_address_layout_req {
+	__le16 vmid;
+	__le16 _padding;
+	__le32 range_id;
+	__le64 range_base;
+	__le64 range_size;
+} __packed;
+
 /*
  * Several RM calls take only a VMID as a parameter and give only standard
  * response back. Deduplicate boilerplate code by using this common call.
@@ -494,3 +513,57 @@ int gunyah_rm_get_vmid(struct gunyah_rm *rm, u16 *vmid)
 	return ret;
 }
 EXPORT_SYMBOL_GPL(gunyah_rm_get_vmid);
+
+/**
+ * gunyah_rm_vm_set_demand_paging() - Enable demand paging of memory regions
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: VMID of the other VM
+ * @count: Number of demand paged memory regions
+ * @entries: Array of the regions
+ */
+int gunyah_rm_vm_set_demand_paging(struct gunyah_rm *rm, u16 vmid, u32 count,
+				   struct gunyah_rm_mem_entry *entries)
+{
+	struct gunyah_rm_vm_set_demand_paging_req *req __free(kfree) = NULL;
+	size_t req_size;
+
+	req_size = struct_size(req, ranges, count);
+	if (req_size == SIZE_MAX)
+		return -EINVAL;
+
+	req = kzalloc(req_size, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	req->vmid = cpu_to_le16(vmid);
+	req->range_count = cpu_to_le32(count);
+	memcpy(req->ranges, entries, sizeof(*entries) * count);
+
+	return gunyah_rm_call(rm, GUNYAH_RM_RPC_VM_SET_DEMAND_PAGING, req,
+			      req_size, NULL, NULL);
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_vm_set_demand_paging, ERRNO);
+
+/**
+ * gunyah_rm_vm_set_address_layout() - Set the start address of images
+ * @rm: Handle to a Gunyah resource manager
+ * @vmid: VMID of the other VM
+ * @range_id: Which image to set
+ * @base_address: Base address
+ * @size: Size
+ */
+int gunyah_rm_vm_set_address_layout(struct gunyah_rm *rm, u16 vmid,
+				    enum gunyah_rm_range_id range_id,
+				    u64 base_address, u64 size)
+{
+	struct gunyah_rm_vm_set_address_layout_req req = {
+		.vmid = cpu_to_le16(vmid),
+		.range_id = cpu_to_le32(range_id),
+		.range_base = cpu_to_le64(base_address),
+		.range_size = cpu_to_le64(size),
+	};
+
+	return gunyah_rm_call(rm, GUNYAH_RM_RPC_VM_SET_ADDRESS_LAYOUT, &req,
+			      sizeof(req), NULL, NULL);
+}
+ALLOW_ERROR_INJECTION(gunyah_rm_vm_set_address_layout, ERRNO);

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:58 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:58 -0800
Subject: [PATCH v17 35/35] MAINTAINERS: Add Gunyah hypervisor drivers
 section
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-35-1e9da6763d38@quicinc.com>

Add myself and Prakruthi as maintainers of Gunyah hypervisor drivers.

Reviewed-by: Alex Elder <elder at linaro.org>
Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bf77be03fb2b..07d8ea2393a9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9322,6 +9322,18 @@ L:	linux-efi at vger.kernel.org
 S:	Maintained
 F:	block/partitions/efi.*
 
+GUNYAH HYPERVISOR DRIVER
+M:	Elliot Berman <quic_eberman at quicinc.com>
+M:	Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
+L:	linux-arm-msm at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml
+F:	Documentation/virt/gunyah/
+F:	arch/arm64/gunyah/
+F:	drivers/virt/gunyah/
+F:	include/linux/gunyah*.h
+K:	gunyah
+
 HABANALABS PCI DRIVER
 M:	Oded Gabbay <ogabbay at kernel.org>
 L:	dri-devel at lists.freedesktop.org

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:38 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:38 -0800
Subject: [PATCH v17 15/35] virt: gunyah: Add proxy-scheduled vCPUs
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-15-1e9da6763d38@quicinc.com>

Gunyah allows vCPUs that are configured as proxy-scheduled to be scheduled by
another virtual machine (host) that holds capabilities to those vCPUs with
suitable rights.

Gunyah also supports configuring regions of a proxy-scheduled VM's address
space to be virtualized by the host VM. This permits a host VMM to emulate MMIO
devices in the proxy-scheduled VM.

vCPUs are presented to the host as a Gunyah resource and represented to
userspace as a Gunyah VM function.

Creating the vcpu function on the VM will create a file descriptor that:
 - can handle an ioctl to run the vCPU. When called, Gunyah will directly
   context-switch to the selected vCPU and run it until one of the following
   events occurs:
    * the host vcpu's time slice ends
    * the host vcpu receives an interrupt or would have been pre-empted
      by the hypervisor
    * a fault occurs in the proxy-scheduled vcpu
    * a power management event, such as idle or cpu-off call in the vcpu
 - can be mmap'd to share the gunyah_vcpu_run structure with userspace. This
   allows the vcpu_run result codes to be accessed, and for arguments to
   vcpu_run to be passed, e.g. for resuming the vcpu when handling certain fault
   and exit cases.

Co-developed-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Prakruthi Deepak Heragu <quic_pheragu at quicinc.com>
Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/Makefile      |   2 +-
 drivers/virt/gunyah/gunyah_vcpu.c | 561 ++++++++++++++++++++++++++++++++++++++
 drivers/virt/gunyah/vm_mgr.c      |   5 +
 drivers/virt/gunyah/vm_mgr.h      |   2 +
 include/uapi/linux/gunyah.h       | 163 +++++++++++
 5 files changed, 732 insertions(+), 1 deletion(-)

diff --git a/drivers/virt/gunyah/Makefile b/drivers/virt/gunyah/Makefile
index 47f1fae5419bf..3f82af8c5ce79 100644
--- a/drivers/virt/gunyah/Makefile
+++ b/drivers/virt/gunyah/Makefile
@@ -2,4 +2,4 @@
 
 gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o
 
-obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o
+obj-$(CONFIG_GUNYAH) += gunyah.o gunyah_rsc_mgr.o gunyah_vcpu.o
diff --git a/drivers/virt/gunyah/gunyah_vcpu.c b/drivers/virt/gunyah/gunyah_vcpu.c
new file mode 100644
index 0000000000000..8192350f180b0
--- /dev/null
+++ b/drivers/virt/gunyah/gunyah_vcpu.c
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
+#include <linux/gunyah.h>
+#include <linux/interrupt.h>
+#include <linux/kref.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+
+#include "vm_mgr.h"
+
+#include <uapi/linux/gunyah.h>
+
+#define MAX_VCPU_NAME 20 /* gh-vcpu:strlen(U32::MAX)+NUL */
+
+/**
+ * struct gunyah_vcpu - Track an instance of gunyah vCPU
+ * @f: Function instance (how we get associated with the main VM)
+ * @rsc: Pointer to the Gunyah vCPU resource, will be NULL until VM starts
+ * @run_lock: One userspace thread at a time should run the vCPU
+ * @ghvm: Pointer to the main VM struct; quicker look up than going through
+ *        @f->ghvm
+ * @vcpu_run: Pointer to page shared with userspace to communicate vCPU state
+ * @state: Our copy of the state of the vCPU, since userspace could trick
+ *         kernel to behave incorrectly if we relied on @vcpu_run
+ * @mmio_read_len: Our copy of @vcpu_run->mmio.len; see also @state
+ * @mmio_addr: Our copy of @vcpu_run->mmio.phys_addr; see also @state
+ * @ready: if vCPU goes to sleep, hypervisor reports to us that it's sleeping
+ *         and will signal interrupt (from @rsc) when it's time to wake up.
+ *         This completion signals that we can run vCPU again.
+ * @nb: When VM exits, the status of VM is reported via @vcpu_run->status.
+ *      We need to track overall VM status, and the nb gives us the updates from
+ *      Resource Manager.
+ * @ticket: resource ticket to claim vCPU# for the VM
+ * @kref: Reference counter
+ */
+struct gunyah_vcpu {
+	struct gunyah_vm_function_instance *f;
+	struct gunyah_resource *rsc;
+	struct mutex run_lock;
+	struct gunyah_vm *ghvm;
+
+	struct gunyah_vcpu_run *vcpu_run;
+
+	/**
+	 * Track why the vcpu_run hypercall returned. This mirrors the vcpu_run
+	 * structure shared with userspace, except is used internally to avoid
+	 * trusting userspace to not modify the vcpu_run structure.
+	 */
+	enum {
+		GUNYAH_VCPU_RUN_STATE_UNKNOWN = 0,
+		GUNYAH_VCPU_RUN_STATE_READY,
+		GUNYAH_VCPU_RUN_STATE_MMIO_READ,
+		GUNYAH_VCPU_RUN_STATE_MMIO_WRITE,
+		GUNYAH_VCPU_RUN_STATE_SYSTEM_DOWN,
+	} state;
+	u8 mmio_read_len;
+	u64 mmio_addr;
+
+	struct completion ready;
+
+	struct notifier_block nb;
+	struct gunyah_vm_resource_ticket ticket;
+	struct kref kref;
+};
+
+static void vcpu_release(struct kref *kref)
+{
+	struct gunyah_vcpu *vcpu = container_of(kref, struct gunyah_vcpu, kref);
+
+	free_page((unsigned long)vcpu->vcpu_run);
+	kfree(vcpu);
+}
+
+/*
+ * When hypervisor allows us to schedule vCPU again, it gives us an interrupt
+ */
+static irqreturn_t gunyah_vcpu_irq_handler(int irq, void *data)
+{
+	struct gunyah_vcpu *vcpu = data;
+
+	complete(&vcpu->ready);
+	return IRQ_HANDLED;
+}
+
+static void gunyah_handle_page_fault(
+	struct gunyah_vcpu *vcpu,
+	const struct gunyah_hypercall_vcpu_run_resp *vcpu_run_resp)
+{
+	u64 addr = vcpu_run_resp->state_data[0];
+
+	vcpu->vcpu_run->page_fault.resume_action = GUNYAH_VCPU_RESUME_FAULT;
+	vcpu->vcpu_run->page_fault.attempt = 0;
+	vcpu->vcpu_run->page_fault.phys_addr = addr;
+	vcpu->vcpu_run->exit_reason = GUNYAH_VCPU_EXIT_PAGE_FAULT;
+}
+
+static void
+gunyah_handle_mmio(struct gunyah_vcpu *vcpu,
+		   const struct gunyah_hypercall_vcpu_run_resp *vcpu_run_resp)
+{
+	u64 addr = vcpu_run_resp->state_data[0],
+	    len = vcpu_run_resp->state_data[1],
+	    data = vcpu_run_resp->state_data[2];
+
+	if (WARN_ON(len > sizeof(u64)))
+		len = sizeof(u64);
+
+	if (vcpu_run_resp->state == GUNYAH_VCPU_ADDRSPACE_VMMIO_READ) {
+		vcpu->vcpu_run->mmio.is_write = 0;
+		/* Record that we need to give vCPU user's supplied value next gunyah_vcpu_run() */
+		vcpu->state = GUNYAH_VCPU_RUN_STATE_MMIO_READ;
+		vcpu->mmio_read_len = len;
+	} else { /* GUNYAH_VCPU_ADDRSPACE_VMMIO_WRITE */
+		vcpu->vcpu_run->mmio.is_write = 1;
+		memcpy(vcpu->vcpu_run->mmio.data, &data, len);
+		vcpu->state = GUNYAH_VCPU_RUN_STATE_MMIO_WRITE;
+	}
+
+	/* Assume userspace is okay and handles the access due to existing userspace */
+	vcpu->vcpu_run->mmio.resume_action = GUNYAH_VCPU_RESUME_HANDLED;
+	vcpu->mmio_addr = vcpu->vcpu_run->mmio.phys_addr = addr;
+	vcpu->vcpu_run->mmio.len = len;
+	vcpu->vcpu_run->exit_reason = GUNYAH_VCPU_EXIT_MMIO;
+}
+
+static int gunyah_handle_mmio_resume(struct gunyah_vcpu *vcpu,
+				     unsigned long resume_data[3])
+{
+	switch (vcpu->vcpu_run->mmio.resume_action) {
+	case GUNYAH_VCPU_RESUME_HANDLED:
+		if (vcpu->state == GUNYAH_VCPU_RUN_STATE_MMIO_READ) {
+			if (unlikely(vcpu->mmio_read_len >
+				     sizeof(resume_data[0])))
+				vcpu->mmio_read_len = sizeof(resume_data[0]);
+			memcpy(&resume_data[0], vcpu->vcpu_run->mmio.data,
+			       vcpu->mmio_read_len);
+		}
+		resume_data[1] = GUNYAH_ADDRSPACE_VMMIO_ACTION_EMULATE;
+		break;
+	case GUNYAH_VCPU_RESUME_FAULT:
+		resume_data[1] = GUNYAH_ADDRSPACE_VMMIO_ACTION_FAULT;
+		break;
+	case GUNYAH_VCPU_RESUME_RETRY:
+		resume_data[1] = GUNYAH_ADDRSPACE_VMMIO_ACTION_RETRY;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int gunyah_vcpu_rm_notification(struct notifier_block *nb,
+				       unsigned long action, void *data)
+{
+	struct gunyah_vcpu *vcpu = container_of(nb, struct gunyah_vcpu, nb);
+	struct gunyah_rm_vm_exited_payload *exit_payload = data;
+
+	/* Wake up userspace waiting for the vCPU to be runnable again */
+	if (action == GUNYAH_RM_NOTIFICATION_VM_EXITED &&
+	    le16_to_cpu(exit_payload->vmid) == vcpu->ghvm->vmid)
+		complete(&vcpu->ready);
+
+	return NOTIFY_OK;
+}
+
+static inline enum gunyah_vm_status
+remap_vm_status(enum gunyah_rm_vm_status rm_status)
+{
+	switch (rm_status) {
+	case GUNYAH_RM_VM_STATUS_INIT_FAILED:
+		return GUNYAH_VM_STATUS_LOAD_FAILED;
+	case GUNYAH_RM_VM_STATUS_EXITED:
+		return GUNYAH_VM_STATUS_EXITED;
+	default:
+		return GUNYAH_VM_STATUS_CRASHED;
+	}
+}
+
+/**
+ * gunyah_vcpu_check_system() - Check whether VM as a whole is running
+ * @vcpu: Pointer to gunyah_vcpu
+ *
+ * Returns true if the VM is alive.
+ * Returns false if the vCPU is the VM is not alive (can only be that VM is shutting down).
+ */
+static bool gunyah_vcpu_check_system(struct gunyah_vcpu *vcpu)
+	__must_hold(&vcpu->run_lock)
+{
+	bool ret = true;
+
+	down_read(&vcpu->ghvm->status_lock);
+	if (likely(vcpu->ghvm->vm_status == GUNYAH_RM_VM_STATUS_RUNNING))
+		goto out;
+
+	vcpu->vcpu_run->status.status = remap_vm_status(vcpu->ghvm->vm_status);
+	vcpu->vcpu_run->status.exit_info = vcpu->ghvm->exit_info;
+	vcpu->vcpu_run->exit_reason = GUNYAH_VCPU_EXIT_STATUS;
+	vcpu->state = GUNYAH_VCPU_RUN_STATE_SYSTEM_DOWN;
+	ret = false;
+out:
+	up_read(&vcpu->ghvm->status_lock);
+	return ret;
+}
+
+/**
+ * gunyah_vcpu_run() - Request Gunyah to begin scheduling this vCPU.
+ * @vcpu: The client descriptor that was obtained via gunyah_vcpu_alloc()
+ */
+static int gunyah_vcpu_run(struct gunyah_vcpu *vcpu)
+{
+	struct gunyah_hypercall_vcpu_run_resp vcpu_run_resp;
+	unsigned long resume_data[3] = { 0 };
+	enum gunyah_error gunyah_error;
+	int ret = 0;
+
+	if (!vcpu->f)
+		return -ENODEV;
+
+	if (mutex_lock_interruptible(&vcpu->run_lock))
+		return -ERESTARTSYS;
+
+	if (!vcpu->rsc) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	switch (vcpu->state) {
+	case GUNYAH_VCPU_RUN_STATE_UNKNOWN:
+		if (vcpu->ghvm->vm_status != GUNYAH_RM_VM_STATUS_RUNNING) {
+			/**
+			 * Check if VM is up. If VM is starting, will block
+			 * until VM is fully up since that thread does
+			 * down_write.
+			 */
+			if (!gunyah_vcpu_check_system(vcpu))
+				goto out;
+		}
+		vcpu->state = GUNYAH_VCPU_RUN_STATE_READY;
+		break;
+	case GUNYAH_VCPU_RUN_STATE_MMIO_READ:
+	case GUNYAH_VCPU_RUN_STATE_MMIO_WRITE:
+		ret = gunyah_handle_mmio_resume(vcpu, resume_data);
+		if (ret)
+			goto out;
+		vcpu->state = GUNYAH_VCPU_RUN_STATE_READY;
+		break;
+	case GUNYAH_VCPU_RUN_STATE_SYSTEM_DOWN:
+		goto out;
+	default:
+		break;
+	}
+
+	while (!ret && !signal_pending(current)) {
+		if (vcpu->vcpu_run->immediate_exit) {
+			ret = -EINTR;
+			goto out;
+		}
+
+		gunyah_error = gunyah_hypercall_vcpu_run(
+			vcpu->rsc->capid, resume_data, &vcpu_run_resp);
+		if (gunyah_error == GUNYAH_ERROR_OK) {
+			memset(resume_data, 0, sizeof(resume_data));
+			switch (vcpu_run_resp.state) {
+			case GUNYAH_VCPU_STATE_READY:
+				if (need_resched())
+					schedule();
+				break;
+			case GUNYAH_VCPU_STATE_POWERED_OFF:
+				/**
+				 * vcpu might be off because the VM is shut down
+				 * If so, it won't ever run again
+				 */
+				if (!gunyah_vcpu_check_system(vcpu))
+					goto out;
+				/**
+				 * Otherwise, another vcpu will turn it on (e.g.
+				 * by PSCI) and hyp sends an interrupt to wake
+				 * Linux up.
+				 */
+				fallthrough;
+			case GUNYAH_VCPU_STATE_EXPECTS_WAKEUP:
+				ret = wait_for_completion_interruptible(
+					&vcpu->ready);
+				/**
+				 * reinitialize completion before next
+				 * hypercall. If we reinitialize after the
+				 * hypercall, interrupt may have already come
+				 * before re-initializing the completion and
+				 * then end up waiting for event that already
+				 * happened.
+				 */
+				reinit_completion(&vcpu->ready);
+				/**
+				 * Check VM status again. Completion
+				 * might've come from VM exiting
+				 */
+				if (!ret && !gunyah_vcpu_check_system(vcpu))
+					goto out;
+				break;
+			case GUNYAH_VCPU_STATE_BLOCKED:
+				schedule();
+				break;
+			case GUNYAH_VCPU_ADDRSPACE_VMMIO_READ:
+			case GUNYAH_VCPU_ADDRSPACE_VMMIO_WRITE:
+				gunyah_handle_mmio(vcpu, &vcpu_run_resp);
+				goto out;
+			case GUNYAH_VCPU_ADDRSPACE_PAGE_FAULT:
+				gunyah_handle_page_fault(vcpu, &vcpu_run_resp);
+				goto out;
+			default:
+				pr_warn_ratelimited(
+					"Unknown vCPU state: %llx\n",
+					vcpu_run_resp.sized_state);
+				schedule();
+				break;
+			}
+		} else if (gunyah_error == GUNYAH_ERROR_RETRY) {
+			schedule();
+		} else {
+			ret = gunyah_error_remap(gunyah_error);
+		}
+	}
+
+out:
+	mutex_unlock(&vcpu->run_lock);
+
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+
+	return ret;
+}
+
+static long gunyah_vcpu_ioctl(struct file *filp, unsigned int cmd,
+			      unsigned long arg)
+{
+	struct gunyah_vcpu *vcpu = filp->private_data;
+	long ret = -ENOTTY;
+
+	switch (cmd) {
+	case GUNYAH_VCPU_RUN:
+		ret = gunyah_vcpu_run(vcpu);
+		break;
+	case GUNYAH_VCPU_MMAP_SIZE:
+		ret = PAGE_SIZE;
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+static int gunyah_vcpu_release(struct inode *inode, struct file *filp)
+{
+	struct gunyah_vcpu *vcpu = filp->private_data;
+
+	gunyah_vm_put(vcpu->ghvm);
+	kref_put(&vcpu->kref, vcpu_release);
+	return 0;
+}
+
+static vm_fault_t gunyah_vcpu_fault(struct vm_fault *vmf)
+{
+	struct gunyah_vcpu *vcpu = vmf->vma->vm_file->private_data;
+	struct page *page;
+
+	if (vmf->pgoff)
+		return VM_FAULT_SIGBUS;
+
+	page = virt_to_page(vcpu->vcpu_run);
+	get_page(page);
+	vmf->page = page;
+	return 0;
+}
+
+static const struct vm_operations_struct gunyah_vcpu_ops = {
+	.fault = gunyah_vcpu_fault,
+};
+
+static int gunyah_vcpu_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	vma->vm_ops = &gunyah_vcpu_ops;
+	return 0;
+}
+
+static const struct file_operations gunyah_vcpu_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = gunyah_vcpu_ioctl,
+	.release = gunyah_vcpu_release,
+	.llseek = noop_llseek,
+	.mmap = gunyah_vcpu_mmap,
+};
+
+static bool gunyah_vcpu_populate(struct gunyah_vm_resource_ticket *ticket,
+				 struct gunyah_resource *ghrsc)
+{
+	struct gunyah_vcpu *vcpu =
+		container_of(ticket, struct gunyah_vcpu, ticket);
+	int ret;
+
+	mutex_lock(&vcpu->run_lock);
+	if (vcpu->rsc) {
+		pr_warn("vcpu%d already got a Gunyah resource. Check if multiple resources with same label were configured.\n",
+			vcpu->ticket.label);
+		ret = -EEXIST;
+		goto out;
+	}
+
+	vcpu->rsc = ghrsc;
+
+	ret = request_irq(vcpu->rsc->irq, gunyah_vcpu_irq_handler,
+			  IRQF_TRIGGER_RISING, "gunyah_vcpu", vcpu);
+	if (ret) {
+		pr_warn("Failed to request vcpu irq %d: %d", vcpu->rsc->irq,
+			ret);
+		goto out;
+	}
+
+	enable_irq_wake(vcpu->rsc->irq);
+
+out:
+	mutex_unlock(&vcpu->run_lock);
+	return !ret;
+}
+
+static void gunyah_vcpu_unpopulate(struct gunyah_vm_resource_ticket *ticket,
+				   struct gunyah_resource *ghrsc)
+{
+	struct gunyah_vcpu *vcpu =
+		container_of(ticket, struct gunyah_vcpu, ticket);
+
+	vcpu->vcpu_run->immediate_exit = true;
+	complete_all(&vcpu->ready);
+	mutex_lock(&vcpu->run_lock);
+	free_irq(vcpu->rsc->irq, vcpu);
+	vcpu->rsc = NULL;
+	mutex_unlock(&vcpu->run_lock);
+}
+
+static long gunyah_vcpu_bind(struct gunyah_vm_function_instance *f)
+{
+	struct gunyah_fn_vcpu_arg *arg = f->argp;
+	struct gunyah_vcpu *vcpu;
+	char name[MAX_VCPU_NAME];
+	struct file *file;
+	struct page *page;
+	int fd;
+	long r;
+
+	if (f->arg_size != sizeof(*arg))
+		return -EINVAL;
+
+	vcpu = kzalloc(sizeof(*vcpu), GFP_KERNEL);
+	if (!vcpu)
+		return -ENOMEM;
+
+	vcpu->f = f;
+	f->data = vcpu;
+	mutex_init(&vcpu->run_lock);
+	kref_init(&vcpu->kref);
+	init_completion(&vcpu->ready);
+
+	page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+	if (!page) {
+		r = -ENOMEM;
+		goto err_destroy_vcpu;
+	}
+	vcpu->vcpu_run = page_address(page);
+
+	vcpu->ticket.resource_type = GUNYAH_RESOURCE_TYPE_VCPU;
+	vcpu->ticket.label = arg->id;
+	vcpu->ticket.owner = THIS_MODULE;
+	vcpu->ticket.populate = gunyah_vcpu_populate;
+	vcpu->ticket.unpopulate = gunyah_vcpu_unpopulate;
+
+	r = gunyah_vm_add_resource_ticket(f->ghvm, &vcpu->ticket);
+	if (r)
+		goto err_destroy_page;
+
+	if (!gunyah_vm_get(f->ghvm)) {
+		r = -ENODEV;
+		goto err_remove_resource_ticket;
+	}
+	vcpu->ghvm = f->ghvm;
+
+	vcpu->nb.notifier_call = gunyah_vcpu_rm_notification;
+	/**
+	 * Ensure we run after the vm_mgr handles the notification and does
+	 * any necessary state changes.
+	 */
+	vcpu->nb.priority = -1;
+	r = gunyah_rm_notifier_register(f->rm, &vcpu->nb);
+	if (r)
+		goto err_put_gunyah_vm;
+
+	kref_get(&vcpu->kref);
+
+	fd = get_unused_fd_flags(O_CLOEXEC);
+	if (fd < 0) {
+		r = fd;
+		goto err_notifier;
+	}
+
+	snprintf(name, sizeof(name), "gh-vcpu:%u", vcpu->ticket.label);
+	file = anon_inode_getfile(name, &gunyah_vcpu_fops, vcpu, O_RDWR);
+	if (IS_ERR(file)) {
+		r = PTR_ERR(file);
+		goto err_put_fd;
+	}
+
+	fd_install(fd, file);
+
+	return fd;
+err_put_fd:
+	put_unused_fd(fd);
+err_notifier:
+	gunyah_rm_notifier_unregister(f->rm, &vcpu->nb);
+err_put_gunyah_vm:
+	gunyah_vm_put(vcpu->ghvm);
+err_remove_resource_ticket:
+	gunyah_vm_remove_resource_ticket(f->ghvm, &vcpu->ticket);
+err_destroy_page:
+	free_page((unsigned long)vcpu->vcpu_run);
+err_destroy_vcpu:
+	kfree(vcpu);
+	return r;
+}
+
+static void gunyah_vcpu_unbind(struct gunyah_vm_function_instance *f)
+{
+	struct gunyah_vcpu *vcpu = f->data;
+
+	gunyah_rm_notifier_unregister(f->rm, &vcpu->nb);
+	gunyah_vm_remove_resource_ticket(vcpu->ghvm, &vcpu->ticket);
+	vcpu->f = NULL;
+
+	kref_put(&vcpu->kref, vcpu_release);
+}
+
+static bool gunyah_vcpu_compare(const struct gunyah_vm_function_instance *f,
+				const void *arg, size_t size)
+{
+	const struct gunyah_fn_vcpu_arg *instance = f->argp, *other = arg;
+
+	if (sizeof(*other) != size)
+		return false;
+
+	return instance->id == other->id;
+}
+
+DECLARE_GUNYAH_VM_FUNCTION_INIT(vcpu, GUNYAH_FN_VCPU, 1, gunyah_vcpu_bind,
+				gunyah_vcpu_unbind, gunyah_vcpu_compare);
+MODULE_DESCRIPTION("Gunyah vCPU Function");
+MODULE_LICENSE("GPL");
diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index a619dd10972a5..a6e25901dcea3 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -309,6 +309,11 @@ static int gunyah_vm_rm_notification_exited(struct gunyah_vm *ghvm, void *data)
 
 	down_write(&ghvm->status_lock);
 	ghvm->vm_status = GUNYAH_RM_VM_STATUS_EXITED;
+	ghvm->exit_info.type = le16_to_cpu(payload->exit_type);
+	ghvm->exit_info.reason_size = le32_to_cpu(payload->exit_reason_size);
+	memcpy(&ghvm->exit_info.reason, payload->exit_reason,
+	       min(GUNYAH_VM_MAX_EXIT_REASON_SIZE,
+		   ghvm->exit_info.reason_size));
 	up_write(&ghvm->status_lock);
 	wake_up(&ghvm->vm_status_wait);
 
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index 190a95ee8da64..8c5b94101b2cf 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -28,6 +28,7 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
  * @vm_status: Current state of the VM, as last reported by RM
  * @vm_status_wait: Wait queue for status @vm_status changes
  * @status_lock: Serializing state transitions
+ * @exit_info: Breadcrumbs why VM is not running anymore
  * @kref: Reference counter for VM functions
  * @fn_lock: Serialization addition of functions
  * @functions: List of &struct gunyah_vm_function_instance that have been
@@ -48,6 +49,7 @@ struct gunyah_vm {
 	enum gunyah_rm_vm_status vm_status;
 	wait_queue_head_t vm_status_wait;
 	struct rw_semaphore status_lock;
+	struct gunyah_vm_exit_info exit_info;
 
 	struct kref kref;
 	struct mutex fn_lock;
diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h
index 1b7cb5fde70a2..46f7d3aa61d05 100644
--- a/include/uapi/linux/gunyah.h
+++ b/include/uapi/linux/gunyah.h
@@ -25,8 +25,33 @@
  */
 #define GUNYAH_VM_START		_IO(GUNYAH_IOCTL_TYPE, 0x3)
 
+/**
+ * enum gunyah_fn_type - Valid types of Gunyah VM functions
+ * @GUNYAH_FN_VCPU: create a vCPU instance to control a vCPU
+ *              &struct gunyah_fn_desc.arg is a pointer to &struct gunyah_fn_vcpu_arg
+ *              Return: file descriptor to manipulate the vcpu.
+ */
+enum gunyah_fn_type {
+	GUNYAH_FN_VCPU = 1,
+};
+
 #define GUNYAH_FN_MAX_ARG_SIZE		256
 
+/**
+ * struct gunyah_fn_vcpu_arg - Arguments to create a vCPU.
+ * @id: vcpu id
+ *
+ * Create this function with &GUNYAH_VM_ADD_FUNCTION using type &GUNYAH_FN_VCPU.
+ *
+ * The vcpu type will register with the VM Manager to expect to control
+ * vCPU number `vcpu_id`. It returns a file descriptor allowing interaction with
+ * the vCPU. See the Gunyah vCPU API description sections for interacting with
+ * the Gunyah vCPU file descriptors.
+ */
+struct gunyah_fn_vcpu_arg {
+	__u32 id;
+};
+
 /**
  * struct gunyah_fn_desc - Arguments to create a VM function
  * @type: Type of the function. See &enum gunyah_fn_type.
@@ -43,4 +68,142 @@ struct gunyah_fn_desc {
 #define GUNYAH_VM_ADD_FUNCTION	_IOW(GUNYAH_IOCTL_TYPE, 0x4, struct gunyah_fn_desc)
 #define GUNYAH_VM_REMOVE_FUNCTION	_IOW(GUNYAH_IOCTL_TYPE, 0x7, struct gunyah_fn_desc)
 
+/*
+ * ioctls for vCPU fds
+ */
+
+/**
+ * enum gunyah_vm_status - Stores status reason why VM is not runnable (exited).
+ * @GUNYAH_VM_STATUS_LOAD_FAILED: VM didn't start because it couldn't be loaded.
+ * @GUNYAH_VM_STATUS_EXITED: VM requested shutdown/reboot.
+ *                       Use &struct gunyah_vm_exit_info.reason for further details.
+ * @GUNYAH_VM_STATUS_CRASHED: VM state is unknown and has crashed.
+ */
+enum gunyah_vm_status {
+	GUNYAH_VM_STATUS_LOAD_FAILED	= 1,
+	GUNYAH_VM_STATUS_EXITED		= 2,
+	GUNYAH_VM_STATUS_CRASHED		= 3,
+};
+
+/*
+ * Gunyah presently sends max 4 bytes of exit_reason.
+ * If that changes, this macro can be safely increased without breaking
+ * userspace so long as struct gunyah_vcpu_run < PAGE_SIZE.
+ */
+#define GUNYAH_VM_MAX_EXIT_REASON_SIZE	8u
+
+/**
+ * struct gunyah_vm_exit_info - Reason for VM exit as reported by Gunyah
+ * See Gunyah documentation for values.
+ * @type: Describes how VM exited
+ * @padding: padding bytes
+ * @reason_size: Number of bytes valid for `reason`
+ * @reason: See Gunyah documentation for interpretation. Note: these values are
+ *          not interpreted by Linux and need to be converted from little-endian
+ *          as applicable.
+ */
+struct gunyah_vm_exit_info {
+	__u16 type;
+	__u16 padding;
+	__u32 reason_size;
+	__u8 reason[GUNYAH_VM_MAX_EXIT_REASON_SIZE];
+};
+
+/**
+ * enum gunyah_vcpu_exit - Stores reason why &GUNYAH_VCPU_RUN ioctl recently exited with status 0
+ * @GUNYAH_VCPU_EXIT_UNKNOWN: Not used, status != 0
+ * @GUNYAH_VCPU_EXIT_MMIO: vCPU performed a read or write that could not be handled
+ *                     by hypervisor or Linux. Use @struct gunyah_vcpu_run.mmio for
+ *                     details of the read/write.
+ * @GUNYAH_VCPU_EXIT_STATUS: vCPU not able to run because the VM has exited.
+ *                       Use @struct gunyah_vcpu_run.status for why VM has exited.
+ * @GUNYAH_VCPU_EXIT_PAGE_FAULT: vCPU tried to execute an instruction at an address
+ *                               for which memory hasn't been provided. Use
+ *                               @struct gunyah_vcpu_run.page_fault for details.
+ */
+enum gunyah_vcpu_exit {
+	GUNYAH_VCPU_EXIT_UNKNOWN,
+	GUNYAH_VCPU_EXIT_MMIO,
+	GUNYAH_VCPU_EXIT_STATUS,
+	GUNYAH_VCPU_EXIT_PAGE_FAULT,
+};
+
+/**
+ * enum gunyah_vcpu_resume_action - Provide resume action after an MMIO or page fault
+ * @GUNYAH_VCPU_RESUME_HANDLED: The mmio or page fault has been handled, continue
+ *                              normal operation of vCPU
+ * @GUNYAH_VCPU_RESUME_FAULT: The mmio or page fault could not be satisfied and
+ *                            inject the original fault back to the guest.
+ * @GUNYAH_VCPU_RESUME_RETRY: Retry the faulting instruction. Perhaps you added
+ *                            memory binding to satisfy the request.
+ */
+enum gunyah_vcpu_resume_action {
+	GUNYAH_VCPU_RESUME_HANDLED = 0,
+	GUNYAH_VCPU_RESUME_FAULT,
+	GUNYAH_VCPU_RESUME_RETRY,
+};
+
+/**
+ * struct gunyah_vcpu_run - Application code obtains a pointer to the gunyah_vcpu_run
+ *                      structure by mmap()ing a vcpu fd.
+ * @immediate_exit: polled when scheduling the vcpu. If set, immediately returns -EINTR.
+ * @padding: padding bytes
+ * @exit_reason: Set when GUNYAH_VCPU_RUN returns successfully and gives reason why
+ *               GUNYAH_VCPU_RUN has stopped running the vCPU. See &enum gunyah_vcpu_exit.
+ * @mmio: Used when exit_reason == GUNYAH_VCPU_EXIT_MMIO
+ *        The guest has faulted on an memory-mapped I/O that
+ *        couldn't be satisfied by gunyah.
+ * @mmio.phys_addr: Address guest tried to access
+ * @mmio.data: the value that was written if `is_write == 1`. Filled by
+ *        user for reads (`is_write == 0`).
+ * @mmio.len: Length of write. Only the first `len` bytes of `data`
+ *       are considered by Gunyah.
+ * @mmio.is_write: 1 if VM tried to perform a write, 0 for a read
+ * @mmio.resume_action: See &enum gunyah_vcpu_resume_action
+ * @status: Used when exit_reason == GUNYAH_VCPU_EXIT_STATUS.
+ *          The guest VM is no longer runnable. This struct informs why.
+ * @status.status: See &enum gunyah_vm_status for possible values
+ * @status.exit_info: Used when status == GUNYAH_VM_STATUS_EXITED
+ * @page_fault: Used when EXIT_REASON == GUNYAH_VCPU_EXIT_PAGE_FAULT
+ *              The guest has faulted on a region that can only be provided
+ *              by mapping memory at phys_addr.
+ * @page_fault.phys_addr: Address guest tried to access.
+ * @page_fault.attempt: Error code why Linux wasn't able to handle fault itself
+ *                      Typically, if no memory was mapped: -ENOENT,
+ *                      If permission bits weren't what the VM wanted: -EPERM
+ * @page_fault.resume_action: See &enum gunyah_vcpu_resume_action
+ */
+struct gunyah_vcpu_run {
+	/* in */
+	__u8 immediate_exit;
+	__u8 padding[7];
+
+	/* out */
+	__u32 exit_reason;
+
+	union {
+		struct {
+			__u64 phys_addr;
+			__u8  data[8];
+			__u32 len;
+			__u8  is_write;
+			__u8  resume_action;
+		} mmio;
+
+		struct {
+			enum gunyah_vm_status status;
+			struct gunyah_vm_exit_info exit_info;
+		} status;
+
+		struct {
+			__u64 phys_addr;
+			__s32 attempt;
+			__u8  resume_action;
+		} page_fault;
+	};
+};
+
+#define GUNYAH_VCPU_RUN		_IO(GUNYAH_IOCTL_TYPE, 0x5)
+#define GUNYAH_VCPU_MMAP_SIZE	_IO(GUNYAH_IOCTL_TYPE, 0x6)
+
 #endif

-- 
2.34.1



From quic_eberman at quicinc.com  Thu Feb 22 15:16:53 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Thu, 22 Feb 2024 15:16:53 -0800
Subject: [PATCH v17 30/35] virt: gunyah: Allow userspace to initialize
 context of primary vCPU
In-Reply-To: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
Message-ID: <20240222-gunyah-v17-30-1e9da6763d38@quicinc.com>

RM provides APIs to fill boot context the initial registers upon
starting the vCPU. Most importantly, this allows userspace to set the
initial PC for the primary vCPU when the VM starts to run.

Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
---
 drivers/virt/gunyah/vm_mgr.c | 77 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/virt/gunyah/vm_mgr.h |  2 ++
 include/uapi/linux/gunyah.h  | 23 +++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c
index 473740a1f97d0..a61a3f3ae92f1 100644
--- a/drivers/virt/gunyah/vm_mgr.c
+++ b/drivers/virt/gunyah/vm_mgr.c
@@ -402,6 +402,7 @@ static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 	mutex_init(&ghvm->resources_lock);
 	INIT_LIST_HEAD(&ghvm->resources);
 	INIT_LIST_HEAD(&ghvm->resource_tickets);
+	xa_init(&ghvm->boot_context);
 
 	mt_init(&ghvm->mm);
 	mt_init(&ghvm->bindings);
@@ -427,6 +428,66 @@ static __must_check struct gunyah_vm *gunyah_vm_alloc(struct gunyah_rm *rm)
 	return ghvm;
 }
 
+static long gunyah_vm_set_boot_context(struct gunyah_vm *ghvm,
+				       struct gunyah_vm_boot_context *boot_ctx)
+{
+	u8 reg_set, reg_index; /* to check values are reasonable */
+	int ret;
+
+	reg_set = (boot_ctx->reg >> GUNYAH_VM_BOOT_CONTEXT_REG_SHIFT) & 0xff;
+	reg_index = boot_ctx->reg & 0xff;
+
+	switch (reg_set) {
+	case REG_SET_X:
+		if (reg_index > 31)
+			return -EINVAL;
+		break;
+	case REG_SET_PC:
+		if (reg_index)
+			return -EINVAL;
+		break;
+	case REG_SET_SP:
+		if (reg_index > 2)
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = down_read_interruptible(&ghvm->status_lock);
+	if (ret)
+		return ret;
+
+	if (ghvm->vm_status != GUNYAH_RM_VM_STATUS_NO_STATE) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = xa_err(xa_store(&ghvm->boot_context, boot_ctx->reg,
+			      (void *)boot_ctx->value, GFP_KERNEL));
+out:
+	up_read(&ghvm->status_lock);
+	return ret;
+}
+
+static inline int gunyah_vm_fill_boot_context(struct gunyah_vm *ghvm)
+{
+	unsigned long reg_set, reg_index, id;
+	void *entry;
+	int ret;
+
+	xa_for_each(&ghvm->boot_context, id, entry) {
+		reg_set = (id >> GUNYAH_VM_BOOT_CONTEXT_REG_SHIFT) & 0xff;
+		reg_index = id & 0xff;
+		ret = gunyah_rm_vm_set_boot_context(
+			ghvm->rm, ghvm->vmid, reg_set, reg_index, (u64)entry);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static int gunyah_vm_start(struct gunyah_vm *ghvm)
 {
 	struct gunyah_rm_hyp_resources *resources;
@@ -499,6 +560,13 @@ static int gunyah_vm_start(struct gunyah_vm *ghvm)
 	}
 	ghvm->vm_status = GUNYAH_RM_VM_STATUS_READY;
 
+	ret = gunyah_vm_fill_boot_context(ghvm);
+	if (ret) {
+		dev_warn(ghvm->parent, "Failed to setup boot context: %d\n",
+			 ret);
+		goto err;
+	}
+
 	ret = gunyah_rm_get_hyp_resources(ghvm->rm, ghvm->vmid, &resources);
 	if (ret) {
 		dev_warn(ghvm->parent,
@@ -625,6 +693,14 @@ static long gunyah_vm_ioctl(struct file *filp, unsigned int cmd,
 
 		return gunyah_gmem_modify_mapping(ghvm, &args);
 	}
+	case GUNYAH_VM_SET_BOOT_CONTEXT: {
+		struct gunyah_vm_boot_context boot_ctx;
+
+		if (copy_from_user(&boot_ctx, argp, sizeof(boot_ctx)))
+			return -EFAULT;
+
+		return gunyah_vm_set_boot_context(ghvm, &boot_ctx);
+	}
 	default:
 		r = -ENOTTY;
 		break;
@@ -716,6 +792,7 @@ static void _gunyah_vm_put(struct kref *kref)
 				 "Failed to deallocate vmid: %d\n", ret);
 	}
 
+	xa_destroy(&ghvm->boot_context);
 	gunyah_rm_put(ghvm->rm);
 	kfree(ghvm);
 }
diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h
index 5eb14f30ba965..8cee93e551700 100644
--- a/drivers/virt/gunyah/vm_mgr.h
+++ b/drivers/virt/gunyah/vm_mgr.h
@@ -81,6 +81,7 @@ long gunyah_dev_vm_mgr_ioctl(struct gunyah_rm *rm, unsigned int cmd,
  *                    folio; parcel_start is start of the folio)
  * @dtb.parcel_pages: Number of pages lent for the memory parcel
  * @dtb.parcel: Data for resource manager to lend the parcel
+ * @boot_context: Requested initial boot context to set when launching the VM
  *
  * Members are grouped by hot path.
  */
@@ -115,6 +116,7 @@ struct gunyah_vm {
 		u64 parcel_start, parcel_pages;
 		struct gunyah_rm_mem_parcel parcel;
 	} dtb;
+	struct xarray boot_context;
 };
 
 /**
diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h
index a89d9bedf3e5d..574116f544722 100644
--- a/include/uapi/linux/gunyah.h
+++ b/include/uapi/linux/gunyah.h
@@ -142,6 +142,29 @@ struct gunyah_map_mem_args {
 
 #define GUNYAH_VM_MAP_MEM _IOW(GUNYAH_IOCTL_TYPE, 0x9, struct gunyah_map_mem_args)
 
+enum gunyah_vm_boot_context_reg {
+	REG_SET_X		= 0,
+	REG_SET_PC		= 1,
+	REG_SET_SP		= 2,
+};
+
+#define GUNYAH_VM_BOOT_CONTEXT_REG_SHIFT	8
+#define GUNYAH_VM_BOOT_CONTEXT_REG(reg, idx) (((reg & 0xff) << GUNYAH_VM_BOOT_CONTEXT_REG_SHIFT) |\
+					      (idx & 0xff))
+
+/**
+ * struct gunyah_vm_boot_context - Set an initial register for the VM
+ * @reg: Register to set. See GUNYAH_VM_BOOT_CONTEXT_REG_* macros
+ * @reserved: reserved for alignment
+ * @value: value to fill in the register
+ */
+struct gunyah_vm_boot_context {
+	__u32 reg;
+	__u32 reserved;
+	__u64 value;
+};
+#define GUNYAH_VM_SET_BOOT_CONTEXT	_IOW(GUNYAH_IOCTL_TYPE, 0xa, struct gunyah_vm_boot_context)
+
 /*
  * ioctls for vCPU fds
  */

-- 
2.34.1



From robh at kernel.org  Thu Feb 22 15:21:18 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 16:21:18 -0700
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <9dbfbeac-3a00-4571-95c0-83e4d47737c5@microchip.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
 <ffd43756-b24e-4f19-be33-0e33047ad70c@microchip.com>
 <20240220082026.GG10170@google.com>
 <9dbfbeac-3a00-4571-95c0-83e4d47737c5@microchip.com>
Message-ID: <20240222232118.GA3786028-robh@kernel.org>

On Tue, Feb 20, 2024 at 08:30:38AM +0000, Dharma.B at microchip.com wrote:
> Hi Lee,
> 
> On 20/02/24 1:50 pm, Lee Jones wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > 
> > On Tue, 20 Feb 2024, Dharma.B at microchip.com wrote:
> > 
> >> Hi Krzysztof,
> >>
> >> On 12/02/24 3:53 pm, Krzysztof Kozlowski wrote:
> >>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> >>>
> >>> On 08/02/2024 11:43, Lee Jones wrote:
> >>>> On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
> >>>>> Convert the atmel,hlcdc binding to DT schema format.
> >>>>>
> >>>>> Align clocks and clock-names properties to clearly indicate that the LCD
> >>>>> controller expects lvds_pll_clk when interfaced with the lvds display. This
> >>>>> alignment with the specific hardware requirements ensures accurate device tree
> >>>>> configuration for systems utilizing the HLCDC IP.
> >>>>>
> >>>>> [...]
> >>>>
> >>>> Applied, thanks!
> >>>>
> >>>> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
> >>>>         commit: cb946db1335b599ece363d33966bf653ed0fa58a
> >>>>
> >>>
> >>> Next is still failing.
> >>>
> >>> Dharma,
> >>> You must explain and clearly mark dependencies between patches.
> >>
> >> I sincerely apologize for any confusion caused by the oversight. I have
> >> organized the patches according to their dependencies in the patch
> >> series, but unfortunately, I neglected to explicitly mention these
> >> dependencies. I understand the importance of clear communication in our
> >> collaborative efforts. Please feel free to provide guidance on how I can
> >> assist you further in resolving this matter.
> > 
> > If this continues to be an issue, I can just remove the commit.
> 
> There won't be any issue if both pwm and display binding goes before the 
> mfd binding.
> 
> Could you please pick the display binding as well?

As this is still not resolved, I've applied the display binding. Not 
ideal, but should fix next.

Rob


From robh at kernel.org  Thu Feb 22 15:43:00 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 16:43:00 -0700
Subject: [PATCH 02/12] dt-bindings: interrupt-controller: stm32-exti: Add
 irq nexus child node
In-Reply-To: <20240216094758.916722-3-antonio.borneo@foss.st.com>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
 <20240216094758.916722-3-antonio.borneo@foss.st.com>
Message-ID: <20240222234300.GA3809915-robh@kernel.org>

On Fri, Feb 16, 2024 at 10:47:47AM +0100, Antonio Borneo wrote:
> The mapping of EXTI interrupts to its parent interrupt controller
> is both SoC and instance dependent.
> The current implementation requires adding a new table to the
> driver's code and a new compatible for each new EXTI instance.
> 
> Add to the binding an interrupt nexus child node that will be
> used on the new EXTI instances and can be optionally used on the
> existing instances.
> The property 'interrupt-map' in the nexus node maps each EXTI
> interrupt to the parent interrupt.
> Align #address-cells and #interrupt-cells between the EXTI node
> and its nexus node.

Looks like an abuse of interrupt-map. You avoid adding yourself to the 
abuser list by putting it in a child node. Clever. (See list in 
drivers/of/irq.c if you don't know what I'm talking about)

I assume the EXTI has 0..N interrupts. Just define 'interrupts' with N 
entries with each entry mapping EXTI interrupt N to 'interrupts' entry 
N.

Rob


From lkp at intel.com  Thu Feb 22 15:52:13 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 23 Feb 2024 07:52:13 +0800
Subject: [PATCH 3/3] arch: Rename fbdev header and source files
In-Reply-To: <20240221161431.8245-4-tzimmermann@suse.de>
References: <20240221161431.8245-4-tzimmermann@suse.de>
Message-ID: <202402230737.e7gWpGUp-lkp@intel.com>

Hi Thomas,

kernel test robot noticed the following build errors:

[auto build test ERROR on tip/x86/core]
[also build test ERROR on deller-parisc/for-next arnd-asm-generic/master linus/master v6.8-rc5]
[cannot apply to next-20240222]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Thomas-Zimmermann/arch-Select-fbdev-helpers-with-CONFIG_VIDEO/20240222-001622
base:   tip/x86/core
patch link:    https://lore.kernel.org/r/20240221161431.8245-4-tzimmermann%40suse.de
patch subject: [PATCH 3/3] arch: Rename fbdev header and source files
config: um-randconfig-002-20240222 (https://download.01.org/0day-ci/archive/20240223/202402230737.e7gWpGUp-lkp at intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project edd4aee4dd9b5b98b2576a6f783e4086173d902a)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240223/202402230737.e7gWpGUp-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402230737.e7gWpGUp-lkp at intel.com/

All errors (new ones prefixed by >>):

   /usr/bin/ld: warning: .tmp_vmlinux.kallsyms1 has a LOAD segment with RWX permissions
   /usr/bin/ld: drivers/video/fbdev/core/fb_io_fops.o: in function `fb_io_mmap':
>> drivers/video/fbdev/core/fb_io_fops.c:164: undefined reference to `pgprot_framebuffer'
   clang: error: linker command failed with exit code 1 (use -v to see invocation)


vim +164 drivers/video/fbdev/core/fb_io_fops.c

6b180f66c0dd62 Thomas Zimmermann 2023-09-27  140  
33253d9e01d405 Thomas Zimmermann 2023-11-27  141  int fb_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
33253d9e01d405 Thomas Zimmermann 2023-11-27  142  {
33253d9e01d405 Thomas Zimmermann 2023-11-27  143  	unsigned long start = info->fix.smem_start;
33253d9e01d405 Thomas Zimmermann 2023-11-27  144  	u32 len = info->fix.smem_len;
33253d9e01d405 Thomas Zimmermann 2023-11-27  145  	unsigned long mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
33253d9e01d405 Thomas Zimmermann 2023-11-27  146  
b3e8813773c568 Thomas Zimmermann 2023-11-27  147  	if (info->flags & FBINFO_VIRTFB)
b3e8813773c568 Thomas Zimmermann 2023-11-27  148  		fb_warn_once(info, "Framebuffer is not in I/O address space.");
b3e8813773c568 Thomas Zimmermann 2023-11-27  149  
33253d9e01d405 Thomas Zimmermann 2023-11-27  150  	/*
33253d9e01d405 Thomas Zimmermann 2023-11-27  151  	 * This can be either the framebuffer mapping, or if pgoff points
33253d9e01d405 Thomas Zimmermann 2023-11-27  152  	 * past it, the mmio mapping.
33253d9e01d405 Thomas Zimmermann 2023-11-27  153  	 */
33253d9e01d405 Thomas Zimmermann 2023-11-27  154  	if (vma->vm_pgoff >= mmio_pgoff) {
33253d9e01d405 Thomas Zimmermann 2023-11-27  155  		if (info->var.accel_flags)
33253d9e01d405 Thomas Zimmermann 2023-11-27  156  			return -EINVAL;
33253d9e01d405 Thomas Zimmermann 2023-11-27  157  
33253d9e01d405 Thomas Zimmermann 2023-11-27  158  		vma->vm_pgoff -= mmio_pgoff;
33253d9e01d405 Thomas Zimmermann 2023-11-27  159  		start = info->fix.mmio_start;
33253d9e01d405 Thomas Zimmermann 2023-11-27  160  		len = info->fix.mmio_len;
33253d9e01d405 Thomas Zimmermann 2023-11-27  161  	}
33253d9e01d405 Thomas Zimmermann 2023-11-27  162  
33253d9e01d405 Thomas Zimmermann 2023-11-27  163  	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
33253d9e01d405 Thomas Zimmermann 2023-11-27 @164  	vma->vm_page_prot = pgprot_framebuffer(vma->vm_page_prot, vma->vm_start,
33253d9e01d405 Thomas Zimmermann 2023-11-27  165  					       vma->vm_end, start);
33253d9e01d405 Thomas Zimmermann 2023-11-27  166  
33253d9e01d405 Thomas Zimmermann 2023-11-27  167  	return vm_iomap_memory(vma, start, len);
33253d9e01d405 Thomas Zimmermann 2023-11-27  168  }
33253d9e01d405 Thomas Zimmermann 2023-11-27  169  EXPORT_SYMBOL(fb_io_mmap);
33253d9e01d405 Thomas Zimmermann 2023-11-27  170  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From robh at kernel.org  Thu Feb 22 15:56:42 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 16:56:42 -0700
Subject: [PATCH v5 06/18] dt-bindings: new: wireless: describe the ath12k
 PCI module
In-Reply-To: <20240216203215.40870-7-brgl@bgdev.pl>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <20240216203215.40870-7-brgl@bgdev.pl>
Message-ID: <20240222235642.GA3830828-robh@kernel.org>

On Fri, Feb 16, 2024 at 09:32:03PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

s/new/net/ in the subject.

> 
> Add device-tree bindings for the ATH12K module found in the WCN7850
> package.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---
>  .../net/wireless/qcom,ath12k-pci.yaml         | 103 ++++++++++++++++++
>  1 file changed, 103 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/wireless/qcom,ath12k-pci.yaml


From robh at kernel.org  Thu Feb 22 16:03:17 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 17:03:17 -0700
Subject: [PATCH v4 5/7] arm64: Unconditionally call
 unflatten_device_tree()
In-Reply-To: <20240217010557.2381548-6-sboyd@kernel.org>
References: <20240217010557.2381548-1-sboyd@kernel.org>
 <20240217010557.2381548-6-sboyd@kernel.org>
Message-ID: <20240223000317.GA3835346-robh@kernel.org>

On Fri, Feb 16, 2024 at 05:05:54PM -0800, Stephen Boyd wrote:
> Call this function unconditionally so that we can populate an empty DTB
> on platforms that don't boot with a firmware provided or builtin DTB.
> When ACPI is in use, unflatten_device_tree() ignores the
> 'initial_boot_params' pointer so the live DT on those systems won't be
> whatever that's pointing to. Similarly, when kexec copies the DT data
> the previous kernel to the new one on ACPI systems,
> of_kexec_alloc_and_setup_fdt() will ignore the live DT (the empty root
> one) and copy the 'initial_boot_params' data.
> 
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Frank Rowand <frowand.list 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: <linux-arm-kernel at lists.infradead.org>
> Signed-off-by: Stephen Boyd <sboyd at kernel.org>
> ---
>  arch/arm64/kernel/setup.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

Catalin, Will, Can I get an ack on this so I can take the series via the 
DT tree.

Rob


From robh at kernel.org  Thu Feb 22 16:09:46 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 17:09:46 -0700
Subject: [PATCH v2 4/4] dt-bindings: display: simple: hardware can use
 several properties
In-Reply-To: <20240217-ltdc_mp13-v2-4-50881f1b394e@foss.st.com>
References: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>
 <20240217-ltdc_mp13-v2-4-50881f1b394e@foss.st.com>
Message-ID: <20240223000946.GA3848625-robh@kernel.org>

On Sat, Feb 17, 2024 at 12:02:58PM +0100, Raphael Gallais-Pou wrote:
> Setting a panel-timing in the device-tree overwrite the one specified in
> the driver and set it as preferred.  In that case 'height-mm',
> 'width-mm' and 'panel-timing' are properties that can be use for simple
> panels, according to panel-common.yaml
> 
> Fixes following warnings:
> arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-rgb: 'height-mm', 'panel-timing', 'width-mm' do not match any of the regexes: 'pinctrl-[0-9]+'
> 	from schema $id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#
> 
> Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
> ---
>  Documentation/devicetree/bindings/display/panel/panel-simple.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> index 634a10c6f2dd..c02cbbc7a100 100644
> --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> @@ -352,6 +352,9 @@ properties:
>    no-hpd: true
>    hpd-gpios: true
>    data-mapping: true
> +  height-mm: true
> +  width-mm: true
> +  panel-timing: true

Instead, just change 'additionalProperties' to 'unevaluateProperties' 
and drop all these 'prop: true' lines. Pretty much anything from 
panel-common.yaml should be allowed.

Rob


From robh at kernel.org  Thu Feb 22 16:13:17 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 17:13:17 -0700
Subject: [PATCH 1/3] dt-bindings: arm: fsl: add i.MX95 19x19 EVK board
In-Reply-To: <20240218-imx95-dts-v1-1-2959f89f2018@nxp.com>
References: <20240218-imx95-dts-v1-0-2959f89f2018@nxp.com>
 <20240218-imx95-dts-v1-1-2959f89f2018@nxp.com>
Message-ID: <20240223001317.GA3857129-robh@kernel.org>

On Sun, Feb 18, 2024 at 02:38:51PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add DT compatible string for NXP i.MX95 19x19 EVK board.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  Documentation/devicetree/bindings/arm/fsl.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
> index 39378879777b..3b318c518e35 100644
> --- a/Documentation/devicetree/bindings/arm/fsl.yaml
> +++ b/Documentation/devicetree/bindings/arm/fsl.yaml
> @@ -1264,6 +1264,12 @@ properties:
>                - fsl,imx93-11x11-evk       # i.MX93 11x11 EVK Board
>            - const: fsl,imx93
>  
> +      - description: i.MX95 based Boards
> +        items:
> +          - enum:
> +              - fsl,imx95-19x19-evk       # i.MX95 19x19 EVK Board
> +          - const: fsl,imx93

imx93 or imx95?

> +
>        - description: i.MXRT1050 based Boards
>          items:
>            - enum:
> 
> -- 
> 2.37.1
> 


From robh at kernel.org  Thu Feb 22 16:14:50 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 17:14:50 -0700
Subject: [PATCH 1/8] dt-bindings: arm-smmu: Add QCM2290 GPU SMMU
In-Reply-To: <20240219-topic-rb1_gpu-v1-1-d260fa854707@linaro.org>
References: <20240219-topic-rb1_gpu-v1-0-d260fa854707@linaro.org>
 <20240219-topic-rb1_gpu-v1-1-d260fa854707@linaro.org>
Message-ID: <170864728970.3860293.1851655437327503155.robh@kernel.org>


On Mon, 19 Feb 2024 14:35:46 +0100, Konrad Dybcio wrote:
> The GPU SMMU on QCM2290 nicely fits into the description we already have
> for SM61[12]5. Add it.
> 
> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> ---
>  Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 

Acked-by: Rob Herring <robh at kernel.org>



From robh at kernel.org  Thu Feb 22 16:26:36 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 17:26:36 -0700
Subject: [PATCH 01/14] media: dt-bindings: media: video-interfaces: add
 defines for sampling modes
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-1-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
 <20240220-v6-8-topic-rk3568-vicap-v1-1-2680a1fa640b@wolfvision.net>
Message-ID: <170864799569.3932038.15905786640208782418.robh@kernel.org>


On Tue, 20 Feb 2024 10:39:11 +0100, Michael Riesch wrote:
> Add defines for the pixel clock sampling modes (rising edge, falling edge,
> dual edge) for parallel video interfaces.
> This avoids hardcoded constants in device tree sources.
> 
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
>  include/dt-bindings/media/video-interfaces.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>



From robh at kernel.org  Thu Feb 22 16:28:34 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 17:28:34 -0700
Subject: [PATCH 02/14] media: dt-bindings: media: rockchip-cif: add port
 definitions
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-2-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
 <20240220-v6-8-topic-rk3568-vicap-v1-2-2680a1fa640b@wolfvision.net>
Message-ID: <20240223002834.GA3933946-robh@kernel.org>

On Tue, Feb 20, 2024 at 10:39:12AM +0100, Michael Riesch wrote:
> The different variants of the Rockchip Camera Interface may feature
> various ports. Add a new header file with port definitions to avoid
> hardcoded constants in device tree sources.

We generally don't do defines for 'port' numbering. I don't see a reason 
to start.

> 
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
>  include/dt-bindings/media/rockchip-cif.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/include/dt-bindings/media/rockchip-cif.h b/include/dt-bindings/media/rockchip-cif.h
> new file mode 100644
> index 000000000000..37364ee1f7bc
> --- /dev/null
> +++ b/include/dt-bindings/media/rockchip-cif.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
> +/*
> + * Copyright (C) 2023 Michael Riesch <michael.riesch at wolfvision.net>
> + */
> +
> +#ifndef __DT_BINDINGS_MEDIA_ROCKCHIP_CIF_H__
> +#define __DT_BINDINGS_MEDIA_ROCKCHIP_CIF_H__
> +
> +#define MEDIA_ROCKCHIP_CIF_DVP		0
> +#define MEDIA_ROCKCHIP_CIF_MIPI		1
> +
> +#endif /* __DT_BINDINGS_MEDIA_ROCKCHIP_CIF_H__ */
> 
> -- 
> 2.30.2
> 


From robh at kernel.org  Thu Feb 22 16:29:25 2024
From: robh at kernel.org (Rob Herring)
Date: Thu, 22 Feb 2024 17:29:25 -0700
Subject: [PATCH 03/14] media: dt-bindings: media: rockchip,px30-vip: add
 optional property iommus
In-Reply-To: <20240220-v6-8-topic-rk3568-vicap-v1-3-2680a1fa640b@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
 <20240220-v6-8-topic-rk3568-vicap-v1-3-2680a1fa640b@wolfvision.net>
Message-ID: <170864816486.3960279.12154290757664269303.robh@kernel.org>


On Tue, 20 Feb 2024 10:39:13 +0100, Michael Riesch wrote:
> The PX30 VIP features an IOMMU and can be operated with or without using
> it. Document the property iommus in order to support the former case.
> 
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
>  Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>



From bot at kernelci.org  Thu Feb 22 16:30:22 2024
From: bot at kernelci.org (kernelci.org bot)
Date: Thu, 22 Feb 2024 16:30:22 -0800 (PST)
Subject: arm64/for-kernelci build: 1 build: 0 failed, 1 passed,
 1 warning (v6.8-rc5-80-g9abbc24128bc5)
Message-ID: <65d7e71e.a70a0220.3db06.03d1@mx.google.com>

arm64/for-kernelci build: 1 build: 0 failed, 1 passed, 1 warning (v6.8-rc5-80-g9abbc24128bc5)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v6.8-rc5-80-g9abbc24128bc5/

Tree: arm64
Branch: for-kernelci
Git Describe: v6.8-rc5-80-g9abbc24128bc5
Git Commit: 9abbc24128bc518a48899107a05e10d1ac4f2391
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

Warnings Detected:

arm64:
    defconfig (gcc-10): 1 warning


Warnings summary:

    1    security/security.c:811:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
defconfig (arm64, gcc-10) ? PASS, 0 errors, 1 warning, 0 section mismatches

Warnings:
    security/security.c:811:2: warning: ?memcpy? offset 32 is out of the bounds [0, 0] [-Warray-bounds]

---
For more info write to <info at kernelci.org>


From seanjc at google.com  Thu Feb 22 16:42:48 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:48 -0800
Subject: [PATCH v9 01/11] KVM: selftests: Extend VM creation's @shape to allow
 control of VM subtype
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-2-seanjc@google.com>

Carve out space in the @shape passed to the various VM creation helpers to
allow using the shape to control the subtype of VM, e.g. to identify x86's
SEV VMs (which are "regular" VMs as far as KVM is concerned).

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerley Tng <ackerleytng at google.com>
Cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/include/kvm_util_base.h | 9 +++++++--
 tools/testing/selftests/kvm/lib/kvm_util.c          | 1 +
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index 070f250036fc..d9dc31af2f96 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -90,6 +90,7 @@ enum kvm_mem_region_type {
 struct kvm_vm {
 	int mode;
 	unsigned long type;
+	uint8_t subtype;
 	int kvm_fd;
 	int fd;
 	unsigned int pgtable_levels;
@@ -191,10 +192,14 @@ enum vm_guest_mode {
 };
 
 struct vm_shape {
-	enum vm_guest_mode mode;
-	unsigned int type;
+	uint32_t type;
+	uint8_t  mode;
+	uint8_t  subtype;
+	uint16_t padding;
 };
 
+kvm_static_assert(sizeof(struct vm_shape) == sizeof(uint64_t));
+
 #define VM_TYPE_DEFAULT			0
 
 #define VM_SHAPE(__mode)			\
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 4994afbdab40..a53caf81eb87 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -276,6 +276,7 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
 
 	vm->mode = shape.mode;
 	vm->type = shape.type;
+	vm->subtype = shape.subtype;
 
 	vm->pa_bits = vm_guest_mode_params[vm->mode].pa_bits;
 	vm->va_bits = vm_guest_mode_params[vm->mode].va_bits;
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:49 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:49 -0800
Subject: [PATCH v9 02/11] KVM: selftests: Make sparsebit structs const where appropriate
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-3-seanjc@google.com>

From: Michael Roth <michael.roth at amd.com>

Make all sparsebit struct pointers "const" where appropriate.  This will
allow adding a bitmap to track protected/encrypted physical memory that
tests can access in a read-only fashion.

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerley Tng <ackerleytng at google.com>
Cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>
Signed-off-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
[sean: massage changelog]
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../testing/selftests/kvm/include/sparsebit.h | 36 +++++++-------
 tools/testing/selftests/kvm/lib/sparsebit.c   | 48 +++++++++----------
 2 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/sparsebit.h b/tools/testing/selftests/kvm/include/sparsebit.h
index 12a9a4b9cead..fb5170d57fcb 100644
--- a/tools/testing/selftests/kvm/include/sparsebit.h
+++ b/tools/testing/selftests/kvm/include/sparsebit.h
@@ -30,26 +30,26 @@ typedef uint64_t sparsebit_num_t;
 
 struct sparsebit *sparsebit_alloc(void);
 void sparsebit_free(struct sparsebit **sbitp);
-void sparsebit_copy(struct sparsebit *dstp, struct sparsebit *src);
+void sparsebit_copy(struct sparsebit *dstp, const struct sparsebit *src);
 
-bool sparsebit_is_set(struct sparsebit *sbit, sparsebit_idx_t idx);
-bool sparsebit_is_set_num(struct sparsebit *sbit,
+bool sparsebit_is_set(const struct sparsebit *sbit, sparsebit_idx_t idx);
+bool sparsebit_is_set_num(const struct sparsebit *sbit,
 			  sparsebit_idx_t idx, sparsebit_num_t num);
-bool sparsebit_is_clear(struct sparsebit *sbit, sparsebit_idx_t idx);
-bool sparsebit_is_clear_num(struct sparsebit *sbit,
+bool sparsebit_is_clear(const struct sparsebit *sbit, sparsebit_idx_t idx);
+bool sparsebit_is_clear_num(const struct sparsebit *sbit,
 			    sparsebit_idx_t idx, sparsebit_num_t num);
-sparsebit_num_t sparsebit_num_set(struct sparsebit *sbit);
-bool sparsebit_any_set(struct sparsebit *sbit);
-bool sparsebit_any_clear(struct sparsebit *sbit);
-bool sparsebit_all_set(struct sparsebit *sbit);
-bool sparsebit_all_clear(struct sparsebit *sbit);
-sparsebit_idx_t sparsebit_first_set(struct sparsebit *sbit);
-sparsebit_idx_t sparsebit_first_clear(struct sparsebit *sbit);
-sparsebit_idx_t sparsebit_next_set(struct sparsebit *sbit, sparsebit_idx_t prev);
-sparsebit_idx_t sparsebit_next_clear(struct sparsebit *sbit, sparsebit_idx_t prev);
-sparsebit_idx_t sparsebit_next_set_num(struct sparsebit *sbit,
+sparsebit_num_t sparsebit_num_set(const struct sparsebit *sbit);
+bool sparsebit_any_set(const struct sparsebit *sbit);
+bool sparsebit_any_clear(const struct sparsebit *sbit);
+bool sparsebit_all_set(const struct sparsebit *sbit);
+bool sparsebit_all_clear(const struct sparsebit *sbit);
+sparsebit_idx_t sparsebit_first_set(const struct sparsebit *sbit);
+sparsebit_idx_t sparsebit_first_clear(const struct sparsebit *sbit);
+sparsebit_idx_t sparsebit_next_set(const struct sparsebit *sbit, sparsebit_idx_t prev);
+sparsebit_idx_t sparsebit_next_clear(const struct sparsebit *sbit, sparsebit_idx_t prev);
+sparsebit_idx_t sparsebit_next_set_num(const struct sparsebit *sbit,
 				       sparsebit_idx_t start, sparsebit_num_t num);
-sparsebit_idx_t sparsebit_next_clear_num(struct sparsebit *sbit,
+sparsebit_idx_t sparsebit_next_clear_num(const struct sparsebit *sbit,
 					 sparsebit_idx_t start, sparsebit_num_t num);
 
 void sparsebit_set(struct sparsebit *sbitp, sparsebit_idx_t idx);
@@ -62,9 +62,9 @@ void sparsebit_clear_num(struct sparsebit *sbitp,
 			 sparsebit_idx_t start, sparsebit_num_t num);
 void sparsebit_clear_all(struct sparsebit *sbitp);
 
-void sparsebit_dump(FILE *stream, struct sparsebit *sbit,
+void sparsebit_dump(FILE *stream, const struct sparsebit *sbit,
 		    unsigned int indent);
-void sparsebit_validate_internal(struct sparsebit *sbit);
+void sparsebit_validate_internal(const struct sparsebit *sbit);
 
 #ifdef __cplusplus
 }
diff --git a/tools/testing/selftests/kvm/lib/sparsebit.c b/tools/testing/selftests/kvm/lib/sparsebit.c
index 88cb6b84e6f3..cfed9d26cc71 100644
--- a/tools/testing/selftests/kvm/lib/sparsebit.c
+++ b/tools/testing/selftests/kvm/lib/sparsebit.c
@@ -202,7 +202,7 @@ static sparsebit_num_t node_num_set(struct node *nodep)
 /* Returns a pointer to the node that describes the
  * lowest bit index.
  */
-static struct node *node_first(struct sparsebit *s)
+static struct node *node_first(const struct sparsebit *s)
 {
 	struct node *nodep;
 
@@ -216,7 +216,7 @@ static struct node *node_first(struct sparsebit *s)
  * lowest bit index > the index of the node pointed to by np.
  * Returns NULL if no node with a higher index exists.
  */
-static struct node *node_next(struct sparsebit *s, struct node *np)
+static struct node *node_next(const struct sparsebit *s, struct node *np)
 {
 	struct node *nodep = np;
 
@@ -244,7 +244,7 @@ static struct node *node_next(struct sparsebit *s, struct node *np)
  * highest index < the index of the node pointed to by np.
  * Returns NULL if no node with a lower index exists.
  */
-static struct node *node_prev(struct sparsebit *s, struct node *np)
+static struct node *node_prev(const struct sparsebit *s, struct node *np)
 {
 	struct node *nodep = np;
 
@@ -273,7 +273,7 @@ static struct node *node_prev(struct sparsebit *s, struct node *np)
  * subtree and duplicates the bit settings to the newly allocated nodes.
  * Returns the newly allocated copy of subtree.
  */
-static struct node *node_copy_subtree(struct node *subtree)
+static struct node *node_copy_subtree(const struct node *subtree)
 {
 	struct node *root;
 
@@ -307,7 +307,7 @@ static struct node *node_copy_subtree(struct node *subtree)
  * index is within the bits described by the mask bits or the number of
  * contiguous bits set after the mask.  Returns NULL if there is no such node.
  */
-static struct node *node_find(struct sparsebit *s, sparsebit_idx_t idx)
+static struct node *node_find(const struct sparsebit *s, sparsebit_idx_t idx)
 {
 	struct node *nodep;
 
@@ -393,7 +393,7 @@ static struct node *node_add(struct sparsebit *s, sparsebit_idx_t idx)
 }
 
 /* Returns whether all the bits in the sparsebit array are set.  */
-bool sparsebit_all_set(struct sparsebit *s)
+bool sparsebit_all_set(const struct sparsebit *s)
 {
 	/*
 	 * If any nodes there must be at least one bit set.  Only case
@@ -775,7 +775,7 @@ static void node_reduce(struct sparsebit *s, struct node *nodep)
 /* Returns whether the bit at the index given by idx, within the
  * sparsebit array is set or not.
  */
-bool sparsebit_is_set(struct sparsebit *s, sparsebit_idx_t idx)
+bool sparsebit_is_set(const struct sparsebit *s, sparsebit_idx_t idx)
 {
 	struct node *nodep;
 
@@ -921,7 +921,7 @@ static inline sparsebit_idx_t node_first_clear(struct node *nodep, int start)
  * used by test cases after they detect an unexpected condition, as a means
  * to capture diagnostic information.
  */
-static void sparsebit_dump_internal(FILE *stream, struct sparsebit *s,
+static void sparsebit_dump_internal(FILE *stream, const struct sparsebit *s,
 	unsigned int indent)
 {
 	/* Dump the contents of s */
@@ -969,7 +969,7 @@ void sparsebit_free(struct sparsebit **sbitp)
  * sparsebit_alloc().  It can though already have bits set, which
  * if different from src will be cleared.
  */
-void sparsebit_copy(struct sparsebit *d, struct sparsebit *s)
+void sparsebit_copy(struct sparsebit *d, const struct sparsebit *s)
 {
 	/* First clear any bits already set in the destination */
 	sparsebit_clear_all(d);
@@ -981,7 +981,7 @@ void sparsebit_copy(struct sparsebit *d, struct sparsebit *s)
 }
 
 /* Returns whether num consecutive bits starting at idx are all set.  */
-bool sparsebit_is_set_num(struct sparsebit *s,
+bool sparsebit_is_set_num(const struct sparsebit *s,
 	sparsebit_idx_t idx, sparsebit_num_t num)
 {
 	sparsebit_idx_t next_cleared;
@@ -1005,14 +1005,14 @@ bool sparsebit_is_set_num(struct sparsebit *s,
 }
 
 /* Returns whether the bit at the index given by idx.  */
-bool sparsebit_is_clear(struct sparsebit *s,
+bool sparsebit_is_clear(const struct sparsebit *s,
 	sparsebit_idx_t idx)
 {
 	return !sparsebit_is_set(s, idx);
 }
 
 /* Returns whether num consecutive bits starting at idx are all cleared.  */
-bool sparsebit_is_clear_num(struct sparsebit *s,
+bool sparsebit_is_clear_num(const struct sparsebit *s,
 	sparsebit_idx_t idx, sparsebit_num_t num)
 {
 	sparsebit_idx_t next_set;
@@ -1041,13 +1041,13 @@ bool sparsebit_is_clear_num(struct sparsebit *s,
  * value.  Use sparsebit_any_set(), instead of sparsebit_num_set() > 0,
  * to determine if the sparsebit array has any bits set.
  */
-sparsebit_num_t sparsebit_num_set(struct sparsebit *s)
+sparsebit_num_t sparsebit_num_set(const struct sparsebit *s)
 {
 	return s->num_set;
 }
 
 /* Returns whether any bit is set in the sparsebit array.  */
-bool sparsebit_any_set(struct sparsebit *s)
+bool sparsebit_any_set(const struct sparsebit *s)
 {
 	/*
 	 * Nodes only describe set bits.  If any nodes then there
@@ -1070,20 +1070,20 @@ bool sparsebit_any_set(struct sparsebit *s)
 }
 
 /* Returns whether all the bits in the sparsebit array are cleared.  */
-bool sparsebit_all_clear(struct sparsebit *s)
+bool sparsebit_all_clear(const struct sparsebit *s)
 {
 	return !sparsebit_any_set(s);
 }
 
 /* Returns whether all the bits in the sparsebit array are set.  */
-bool sparsebit_any_clear(struct sparsebit *s)
+bool sparsebit_any_clear(const struct sparsebit *s)
 {
 	return !sparsebit_all_set(s);
 }
 
 /* Returns the index of the first set bit.  Abort if no bits are set.
  */
-sparsebit_idx_t sparsebit_first_set(struct sparsebit *s)
+sparsebit_idx_t sparsebit_first_set(const struct sparsebit *s)
 {
 	struct node *nodep;
 
@@ -1097,7 +1097,7 @@ sparsebit_idx_t sparsebit_first_set(struct sparsebit *s)
 /* Returns the index of the first cleared bit.  Abort if
  * no bits are cleared.
  */
-sparsebit_idx_t sparsebit_first_clear(struct sparsebit *s)
+sparsebit_idx_t sparsebit_first_clear(const struct sparsebit *s)
 {
 	struct node *nodep1, *nodep2;
 
@@ -1151,7 +1151,7 @@ sparsebit_idx_t sparsebit_first_clear(struct sparsebit *s)
 /* Returns index of next bit set within s after the index given by prev.
  * Returns 0 if there are no bits after prev that are set.
  */
-sparsebit_idx_t sparsebit_next_set(struct sparsebit *s,
+sparsebit_idx_t sparsebit_next_set(const struct sparsebit *s,
 	sparsebit_idx_t prev)
 {
 	sparsebit_idx_t lowest_possible = prev + 1;
@@ -1244,7 +1244,7 @@ sparsebit_idx_t sparsebit_next_set(struct sparsebit *s,
 /* Returns index of next bit cleared within s after the index given by prev.
  * Returns 0 if there are no bits after prev that are cleared.
  */
-sparsebit_idx_t sparsebit_next_clear(struct sparsebit *s,
+sparsebit_idx_t sparsebit_next_clear(const struct sparsebit *s,
 	sparsebit_idx_t prev)
 {
 	sparsebit_idx_t lowest_possible = prev + 1;
@@ -1300,7 +1300,7 @@ sparsebit_idx_t sparsebit_next_clear(struct sparsebit *s,
  * and returns the index of the first sequence of num consecutively set
  * bits.  Returns a value of 0 of no such sequence exists.
  */
-sparsebit_idx_t sparsebit_next_set_num(struct sparsebit *s,
+sparsebit_idx_t sparsebit_next_set_num(const struct sparsebit *s,
 	sparsebit_idx_t start, sparsebit_num_t num)
 {
 	sparsebit_idx_t idx;
@@ -1335,7 +1335,7 @@ sparsebit_idx_t sparsebit_next_set_num(struct sparsebit *s,
  * and returns the index of the first sequence of num consecutively cleared
  * bits.  Returns a value of 0 of no such sequence exists.
  */
-sparsebit_idx_t sparsebit_next_clear_num(struct sparsebit *s,
+sparsebit_idx_t sparsebit_next_clear_num(const struct sparsebit *s,
 	sparsebit_idx_t start, sparsebit_num_t num)
 {
 	sparsebit_idx_t idx;
@@ -1583,7 +1583,7 @@ static size_t display_range(FILE *stream, sparsebit_idx_t low,
  * contiguous bits.  This is done because '-' is used to specify command-line
  * options, and sometimes ranges are specified as command-line arguments.
  */
-void sparsebit_dump(FILE *stream, struct sparsebit *s,
+void sparsebit_dump(FILE *stream, const struct sparsebit *s,
 	unsigned int indent)
 {
 	size_t current_line_len = 0;
@@ -1681,7 +1681,7 @@ void sparsebit_dump(FILE *stream, struct sparsebit *s,
  * s.  On error, diagnostic information is printed to stderr and
  * abort is called.
  */
-void sparsebit_validate_internal(struct sparsebit *s)
+void sparsebit_validate_internal(const struct sparsebit *s)
 {
 	bool error_detected = false;
 	struct node *nodep, *prev = NULL;
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:47 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:47 -0800
Subject: [PATCH v9 00/11] KVM: selftests: Add SEV and SEV-ES smoke tests
Message-ID: <20240223004258.3104051-1-seanjc@google.com>

Add basic SEV and SEV-ES smoke tests.  Unlike the intra-host migration tests,
this one actually runs a small chunk of code in the guest.

Unless anyone strongly objects to the quick and dirty approach I've taken for 
SEV-ES, I'll get all of this queued for 6.9 soon-ish.

As for _why_ I added the quick-and-dirty SEV-ES testcase, I have a series to
cleanup __svm_sev_es_vcpu_run(), and found out that apparently I have a version
of OVMF that doesn't quite have to the right <something> for SEV-ES, and so I
could even get a "real" VM to reach KVM_RUN.  I assumed (correctly, yay!) that
hacking together a selftest would be faster than figuring out what firmware
magic I am missing.

v9:
 - Drop is_kvm_sev_supported() and rely purely on KVM capabilities.
 - Check X86_FEATURE_SEV to ensure SEV is actually enabled.
 - Collect tags. [Carlos, Itaru]

v8:
 - https://lore.kernel.org/all/cc9a1951-e76c-470d-a4d1-8ad67bae5794 at amd.com
 - Undo the kvm.h uAPI breakage.
 - Take advantage of "struct vm_shape", introduced by the guest_memfd
   selftests, to simply tracking the SEV/SEV-ES subtypes.
 - Rename the test to "sev_smoke_test" instead of "sev_all_boot_test",
   as the "all" is rather nonsensical, and the test isn't booting anything
   in the traditional sense of the word.
 - Drop vm->protected and instead add an arch hook to query if the VM has
   protected memory.
 - Assert that the target memory region supports protected memory when
   allocating protected memory.
 - Allocate protected_phy_pages for memory regions if and only if the VM
   supports protected memory.
 - Rename kvm_host.h to kvm_util_arch.h, and move it to selftests/kvm where
   it belongs.
 - Fix up some SoB goofs.
 - Convert the intrahost SEV/SEV-ES migration tests to use common ioctl()
   wrappers.

Ackerley Tng (1):
  KVM: selftests: Add a macro to iterate over a sparsebit range

Michael Roth (2):
  KVM: selftests: Make sparsebit structs const where appropriate
  KVM: selftests: Add support for protected vm_vaddr_* allocations

Peter Gonda (5):
  KVM: selftests: Add support for allocating/managing protected guest
    memory
  KVM: selftests: Explicitly ucall pool from shared memory
  KVM: selftests: Allow tagging protected memory in guest page tables
  KVM: selftests: Add library for creating and interacting with SEV
    guests
  KVM: selftests: Add a basic SEV smoke test

Sean Christopherson (3):
  KVM: selftests: Extend VM creation's @shape to allow control of VM
    subtype
  KVM: selftests: Use the SEV library APIs in the intra-host migration
    test
  KVM: selftests: Add a basic SEV-ES smoke test

 tools/testing/selftests/kvm/Makefile          |   2 +
 .../kvm/include/aarch64/kvm_util_arch.h       |   7 ++
 .../selftests/kvm/include/kvm_util_base.h     |  50 +++++++-
 .../kvm/include/riscv/kvm_util_arch.h         |   7 ++
 .../kvm/include/s390x/kvm_util_arch.h         |   7 ++
 .../testing/selftests/kvm/include/sparsebit.h |  56 ++++++---
 .../kvm/include/x86_64/kvm_util_arch.h        |  23 ++++
 .../selftests/kvm/include/x86_64/processor.h  |   8 ++
 .../selftests/kvm/include/x86_64/sev.h        | 107 ++++++++++++++++
 tools/testing/selftests/kvm/lib/kvm_util.c    |  67 ++++++++--
 tools/testing/selftests/kvm/lib/sparsebit.c   |  48 ++++----
 .../testing/selftests/kvm/lib/ucall_common.c  |   3 +-
 .../selftests/kvm/lib/x86_64/processor.c      |  32 ++++-
 tools/testing/selftests/kvm/lib/x86_64/sev.c  | 114 ++++++++++++++++++
 .../selftests/kvm/x86_64/sev_migrate_tests.c  |  67 ++++------
 .../selftests/kvm/x86_64/sev_smoke_test.c     |  88 ++++++++++++++
 16 files changed, 583 insertions(+), 103 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/x86_64/sev.h
 create mode 100644 tools/testing/selftests/kvm/lib/x86_64/sev.c
 create mode 100644 tools/testing/selftests/kvm/x86_64/sev_smoke_test.c


base-commit: 60eedcfceda9db46f1b333e5e1aa9359793f04fb
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:51 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:51 -0800
Subject: [PATCH v9 04/11] KVM: selftests: Add support for allocating/managing
 protected guest memory
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-5-seanjc@google.com>

From: Peter Gonda <pgonda at google.com>

Add support for differentiating between protected (a.k.a. private, a.k.a.
encrypted) memory and normal (a.k.a. shared) memory for VMs that support
protected guest memory, e.g. x86's SEV.  Provide and manage a common
bitmap for tracking whether a given physical page resides in protected
memory, as support for protected memory isn't x86 specific, i.e. adding a
arch hook would be a net negative now, and in the future.

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerley Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Reviewed-by: Itaru Kitayama <itaru.kitayama at fujitsu.com>
Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>
Originally-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
Co-developed-by: Sean Christopherson <seanjc at google.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../selftests/kvm/include/kvm_util_base.h     | 25 +++++++++++++++++--
 tools/testing/selftests/kvm/lib/kvm_util.c    | 22 +++++++++++++---
 2 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index d9dc31af2f96..a82149305349 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -46,6 +46,7 @@ typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */
 struct userspace_mem_region {
 	struct kvm_userspace_memory_region2 region;
 	struct sparsebit *unused_phy_pages;
+	struct sparsebit *protected_phy_pages;
 	int fd;
 	off_t offset;
 	enum vm_mem_backing_src_type backing_src_type;
@@ -573,6 +574,13 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,
 		uint64_t guest_paddr, uint32_t slot, uint64_t npages,
 		uint32_t flags, int guest_memfd_fd, uint64_t guest_memfd_offset);
 
+#ifndef vm_arch_has_protected_memory
+static inline bool vm_arch_has_protected_memory(struct kvm_vm *vm)
+{
+	return false;
+}
+#endif
+
 void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags);
 void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa);
 void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot);
@@ -836,10 +844,23 @@ const char *exit_reason_str(unsigned int exit_reason);
 
 vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm, vm_paddr_t paddr_min,
 			     uint32_t memslot);
-vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
-			      vm_paddr_t paddr_min, uint32_t memslot);
+vm_paddr_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
+				vm_paddr_t paddr_min, uint32_t memslot,
+				bool protected);
 vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm);
 
+static inline vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
+					    vm_paddr_t paddr_min, uint32_t memslot)
+{
+	/*
+	 * By default, allocate memory as protected for VMs that support
+	 * protected memory, as the majority of memory for such VMs is
+	 * protected, i.e. using shared memory is effectively opt-in.
+	 */
+	return __vm_phy_pages_alloc(vm, num, paddr_min, memslot,
+				    vm_arch_has_protected_memory(vm));
+}
+
 /*
  * ____vm_create() does KVM_CREATE_VM and little else.  __vm_create() also
  * loads the test binary into guest memory and creates an IRQ chip (x86 only).
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index a53caf81eb87..ea677aa019ef 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -717,6 +717,7 @@ static void __vm_mem_region_delete(struct kvm_vm *vm,
 	vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION2, &region->region);
 
 	sparsebit_free(&region->unused_phy_pages);
+	sparsebit_free(&region->protected_phy_pages);
 	ret = munmap(region->mmap_start, region->mmap_size);
 	TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("munmap()", ret));
 	if (region->fd >= 0) {
@@ -1098,6 +1099,8 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,
 	}
 
 	region->unused_phy_pages = sparsebit_alloc();
+	if (vm_arch_has_protected_memory(vm))
+		region->protected_phy_pages = sparsebit_alloc();
 	sparsebit_set_num(region->unused_phy_pages,
 		guest_paddr >> vm->page_shift, npages);
 	region->region.slot = slot;
@@ -1924,6 +1927,10 @@ void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
 			region->host_mem);
 		fprintf(stream, "%*sunused_phy_pages: ", indent + 2, "");
 		sparsebit_dump(stream, region->unused_phy_pages, 0);
+		if (region->protected_phy_pages) {
+			fprintf(stream, "%*sprotected_phy_pages: ", indent + 2, "");
+			sparsebit_dump(stream, region->protected_phy_pages, 0);
+		}
 	}
 	fprintf(stream, "%*sMapped Virtual Pages:\n", indent, "");
 	sparsebit_dump(stream, vm->vpages_mapped, indent + 2);
@@ -2025,6 +2032,7 @@ const char *exit_reason_str(unsigned int exit_reason)
  *   num - number of pages
  *   paddr_min - Physical address minimum
  *   memslot - Memory region to allocate page from
+ *   protected - True if the pages will be used as protected/private memory
  *
  * Output Args: None
  *
@@ -2036,8 +2044,9 @@ const char *exit_reason_str(unsigned int exit_reason)
  * and their base address is returned. A TEST_ASSERT failure occurs if
  * not enough pages are available at or above paddr_min.
  */
-vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
-			      vm_paddr_t paddr_min, uint32_t memslot)
+vm_paddr_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
+				vm_paddr_t paddr_min, uint32_t memslot,
+				bool protected)
 {
 	struct userspace_mem_region *region;
 	sparsebit_idx_t pg, base;
@@ -2050,8 +2059,10 @@ vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
 		paddr_min, vm->page_size);
 
 	region = memslot2region(vm, memslot);
+	TEST_ASSERT(!protected || region->protected_phy_pages,
+		    "Region doesn't support protected memory");
+
 	base = pg = paddr_min >> vm->page_shift;
-
 	do {
 		for (; pg < base + num; ++pg) {
 			if (!sparsebit_is_set(region->unused_phy_pages, pg)) {
@@ -2070,8 +2081,11 @@ vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
 		abort();
 	}
 
-	for (pg = base; pg < base + num; ++pg)
+	for (pg = base; pg < base + num; ++pg) {
 		sparsebit_clear(region->unused_phy_pages, pg);
+		if (protected)
+			sparsebit_set(region->protected_phy_pages, pg);
+	}
 
 	return base * vm->page_size;
 }
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:50 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:50 -0800
Subject: [PATCH v9 03/11] KVM: selftests: Add a macro to iterate over a
 sparsebit range
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-4-seanjc@google.com>

From: Ackerley Tng <ackerleytng at google.com>

Add sparsebit_for_each_set_range() to allow iterator over a range of set
bits in a range.  This will be used by x86 SEV guests to process protected
physical pages (each such page needs to be encrypted _after_ being "added"
to the VM).

Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>
Signed-off-by: Ackerley Tng <ackerleytng at google.com>
[sean: split to separate patch]
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../testing/selftests/kvm/include/sparsebit.h | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/sparsebit.h b/tools/testing/selftests/kvm/include/sparsebit.h
index fb5170d57fcb..bc760761e1a3 100644
--- a/tools/testing/selftests/kvm/include/sparsebit.h
+++ b/tools/testing/selftests/kvm/include/sparsebit.h
@@ -66,6 +66,26 @@ void sparsebit_dump(FILE *stream, const struct sparsebit *sbit,
 		    unsigned int indent);
 void sparsebit_validate_internal(const struct sparsebit *sbit);
 
+/*
+ * Iterate over an inclusive ranges within sparsebit @s. In each iteration,
+ * @range_begin and @range_end will take the beginning and end of the set
+ * range, which are of type sparsebit_idx_t.
+ *
+ * For example, if the range [3, 7] (inclusive) is set, within the
+ * iteration, at range_begin will take the value 3 and @range_end will take
+ * the value 7.
+ *
+ * Ensure that there is at least one bit set before using this macro with
+ * sparsebit_any_set(), because sparsebit_first_set() will abort if none
+ * are set.
+ */
+#define sparsebit_for_each_set_range(s, range_begin, range_end)         \
+	for (range_begin = sparsebit_first_set(s),                      \
+	     range_end = sparsebit_next_clear(s, range_begin) - 1;	\
+	     range_begin && range_end;                                  \
+	     range_begin = sparsebit_next_set(s, range_end),            \
+	     range_end = sparsebit_next_clear(s, range_begin) - 1)
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:53 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:53 -0800
Subject: [PATCH v9 06/11] KVM: selftests: Explicitly ucall pool from shared memory
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-7-seanjc@google.com>

From: Peter Gonda <pgonda at google.com>

Allocate the common ucall pool using vm_vaddr_alloc_shared() so that the
ucall structures will be placed in shared (unencrypted) memory for VMs
with support for protected (encrypted) memory, e.g. x86's SEV.

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerly Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
[sean: massage changelog]
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/lib/ucall_common.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c b/tools/testing/selftests/kvm/lib/ucall_common.c
index 816a3fa109bf..f5af65a41c29 100644
--- a/tools/testing/selftests/kvm/lib/ucall_common.c
+++ b/tools/testing/selftests/kvm/lib/ucall_common.c
@@ -29,7 +29,8 @@ void ucall_init(struct kvm_vm *vm, vm_paddr_t mmio_gpa)
 	vm_vaddr_t vaddr;
 	int i;
 
-	vaddr = __vm_vaddr_alloc(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR, MEM_REGION_DATA);
+	vaddr = vm_vaddr_alloc_shared(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR,
+				      MEM_REGION_DATA);
 	hdr = (struct ucall_header *)addr_gva2hva(vm, vaddr);
 	memset(hdr, 0, sizeof(*hdr));
 
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:54 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:54 -0800
Subject: [PATCH v9 07/11] KVM: selftests: Allow tagging protected memory in
 guest page tables
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-8-seanjc@google.com>

From: Peter Gonda <pgonda at google.com>

Add support for tagging and untagging guest physical address, e.g. to
allow x86's SEV and TDX guests to embed shared vs. private information in
the GPA.  SEV (encryption, a.k.a. C-bit) and TDX (shared, a.k.a. S-bit)
steal bits from the guest's physical address space that is consumed by the
CPU metadata, i.e. effectively aliases the "real" GPA.

Implement generic "tagging" so that the shared vs. private metadata can be
managed by x86 without bleeding too many details into common code.

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerly Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>
Originally-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../kvm/include/aarch64/kvm_util_arch.h       |  7 +++++++
 .../selftests/kvm/include/kvm_util_base.h     | 13 ++++++++++++
 .../kvm/include/riscv/kvm_util_arch.h         |  7 +++++++
 .../kvm/include/s390x/kvm_util_arch.h         |  7 +++++++
 .../kvm/include/x86_64/kvm_util_arch.h        | 21 +++++++++++++++++++
 tools/testing/selftests/kvm/lib/kvm_util.c    | 17 +++++++++++++++
 .../selftests/kvm/lib/x86_64/processor.c      | 15 ++++++++++++-
 7 files changed, 86 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
 create mode 100644 tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h

diff --git a/tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
new file mode 100644
index 000000000000..218f5cdf0d86
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _TOOLS_LINUX_ASM_ARM64_KVM_HOST_H
+#define _TOOLS_LINUX_ASM_ARM64_KVM_HOST_H
+
+struct kvm_vm_arch {};
+
+#endif  // _TOOLS_LINUX_ASM_ARM64_KVM_HOST_H
diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index cb3159af6db3..4b266dc0c9bd 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -18,9 +18,11 @@
 #include <linux/types.h>
 
 #include <asm/atomic.h>
+#include <asm/kvm.h>
 
 #include <sys/ioctl.h>
 
+#include "kvm_util_arch.h"
 #include "sparsebit.h"
 
 /*
@@ -113,6 +115,9 @@ struct kvm_vm {
 	vm_vaddr_t idt;
 	vm_vaddr_t handlers;
 	uint32_t dirty_ring_size;
+	uint64_t gpa_tag_mask;
+
+	struct kvm_vm_arch arch;
 
 	/* Cache of information for binary stats interface */
 	int stats_fd;
@@ -605,6 +610,12 @@ void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva);
 vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva);
 void *addr_gpa2alias(struct kvm_vm *vm, vm_paddr_t gpa);
 
+
+static inline vm_paddr_t vm_untag_gpa(struct kvm_vm *vm, vm_paddr_t gpa)
+{
+	return gpa & ~vm->gpa_tag_mask;
+}
+
 void vcpu_run(struct kvm_vcpu *vcpu);
 int _vcpu_run(struct kvm_vcpu *vcpu);
 
@@ -1114,4 +1125,6 @@ void kvm_selftest_arch_init(void);
 
 void kvm_arch_vm_post_create(struct kvm_vm *vm);
 
+bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr);
+
 #endif /* SELFTEST_KVM_UTIL_BASE_H */
diff --git a/tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h b/tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
new file mode 100644
index 000000000000..c8280d5659ce
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/riscv/kvm_util_arch.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _TOOLS_LINUX_ASM_RISCV_KVM_HOST_H
+#define _TOOLS_LINUX_ASM_RISCV_KVM_HOST_H
+
+struct kvm_vm_arch {};
+
+#endif  // _TOOLS_LINUX_ASM_RISCV_KVM_HOST_H
diff --git a/tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h b/tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
new file mode 100644
index 000000000000..4c4c1c1e4bf8
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _TOOLS_LINUX_ASM_S390_KVM_HOST_H
+#define _TOOLS_LINUX_ASM_S390_KVM_HOST_H
+
+struct kvm_vm_arch {};
+
+#endif  // _TOOLS_LINUX_ASM_S390_KVM_HOST_H
diff --git a/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
new file mode 100644
index 000000000000..17bb38236d97
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _TOOLS_LINUX_ASM_X86_KVM_HOST_H
+#define _TOOLS_LINUX_ASM_X86_KVM_HOST_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+struct kvm_vm_arch {
+	uint64_t c_bit;
+	uint64_t s_bit;
+};
+
+static inline bool __vm_arch_has_protected_memory(struct kvm_vm_arch *arch)
+{
+	return arch->c_bit || arch->s_bit;
+}
+
+#define vm_arch_has_protected_memory(vm) \
+	__vm_arch_has_protected_memory(&(vm)->arch)
+
+#endif  // _TOOLS_LINUX_ASM_X86_KVM_HOST_H
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index e7f4f84f2e68..19511137d1ae 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1597,6 +1597,8 @@ void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa)
 {
 	struct userspace_mem_region *region;
 
+	gpa = vm_untag_gpa(vm, gpa);
+
 	region = userspace_mem_region_find(vm, gpa, gpa);
 	if (!region) {
 		TEST_FAIL("No vm physical memory at 0x%lx", gpa);
@@ -2305,3 +2307,18 @@ void __attribute((constructor)) kvm_selftest_init(void)
 
 	kvm_selftest_arch_init();
 }
+
+bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr)
+{
+	sparsebit_idx_t pg = 0;
+	struct userspace_mem_region *region;
+
+	if (!vm_arch_has_protected_memory(vm))
+		return false;
+
+	region = userspace_mem_region_find(vm, paddr, paddr);
+	TEST_ASSERT(region, "No vm physical memory at 0x%lx", paddr);
+
+	pg = paddr >> vm->page_shift;
+	return sparsebit_is_set(region->protected_phy_pages, pg);
+}
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
index 615d05247470..6c1d2c0ec584 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
@@ -157,6 +157,8 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *vm,
 {
 	uint64_t *pte = virt_get_pte(vm, parent_pte, vaddr, current_level);
 
+	paddr = vm_untag_gpa(vm, paddr);
+
 	if (!(*pte & PTE_PRESENT_MASK)) {
 		*pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK;
 		if (current_level == target_level)
@@ -200,6 +202,8 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level)
 		    "Physical address beyond maximum supported,\n"
 		    "  paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
 		    paddr, vm->max_gfn, vm->page_size);
+	TEST_ASSERT(vm_untag_gpa(vm, paddr) == paddr,
+		    "Unexpected bits in paddr: %lx", paddr);
 
 	/*
 	 * Allocate upper level page tables, if not already present.  Return
@@ -222,6 +226,15 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level)
 	TEST_ASSERT(!(*pte & PTE_PRESENT_MASK),
 		    "PTE already present for 4k page at vaddr: 0x%lx", vaddr);
 	*pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MASK);
+
+	/*
+	 * Neither SEV nor TDX supports shared page tables, so only the final
+	 * leaf PTE needs manually set the C/S-bit.
+	 */
+	if (vm_is_gpa_protected(vm, paddr))
+		*pte |= vm->arch.c_bit;
+	else
+		*pte |= vm->arch.s_bit;
 }
 
 void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr)
@@ -496,7 +509,7 @@ vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva)
 	 * No need for a hugepage mask on the PTE, x86-64 requires the "unused"
 	 * address bits to be zero.
 	 */
-	return PTE_GET_PA(*pte) | (gva & ~HUGEPAGE_MASK(level));
+	return vm_untag_gpa(vm, PTE_GET_PA(*pte)) | (gva & ~HUGEPAGE_MASK(level));
 }
 
 static void kvm_setup_gdt(struct kvm_vm *vm, struct kvm_dtable *dt)
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:55 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:55 -0800
Subject: [PATCH v9 08/11] KVM: selftests: Add library for creating and
 interacting with SEV guests
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-9-seanjc@google.com>

From: Peter Gonda <pgonda at google.com>

Add a library/APIs for creating and interfacing with SEV guests, all of
which need some amount of common functionality, e.g. an open file handle
for the SEV driver (/dev/sev), ioctl() wrappers to pass said file handle
to KVM, tracking of the C-bit, etc.

Add an x86-specific hook to initialize address properties, a.k.a. the
location of the C-bit.  An arch specific hook is rather gross, but x86
already has a dedicated #ifdef-protected kvm_get_cpu_address_width() hook,
i.e. the ugliest code already exists.

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerly Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>
Originally-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
Co-developed-by: Sean Christopherson <seanjc at google.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/include/x86_64/kvm_util_arch.h        |   2 +
 .../selftests/kvm/include/x86_64/processor.h  |   8 ++
 .../selftests/kvm/include/x86_64/sev.h        | 105 +++++++++++++++++
 tools/testing/selftests/kvm/lib/kvm_util.c    |   1 +
 .../selftests/kvm/lib/x86_64/processor.c      |  17 +++
 tools/testing/selftests/kvm/lib/x86_64/sev.c  | 110 ++++++++++++++++++
 7 files changed, 244 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/include/x86_64/sev.h
 create mode 100644 tools/testing/selftests/kvm/lib/x86_64/sev.c

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index ce58098d80fd..169b6ee8f733 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -38,6 +38,7 @@ LIBKVM_x86_64 += lib/x86_64/hyperv.c
 LIBKVM_x86_64 += lib/x86_64/memstress.c
 LIBKVM_x86_64 += lib/x86_64/pmu.c
 LIBKVM_x86_64 += lib/x86_64/processor.c
+LIBKVM_x86_64 += lib/x86_64/sev.c
 LIBKVM_x86_64 += lib/x86_64/svm.c
 LIBKVM_x86_64 += lib/x86_64/ucall.c
 LIBKVM_x86_64 += lib/x86_64/vmx.c
diff --git a/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
index 17bb38236d97..205ed788aeb8 100644
--- a/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
+++ b/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
@@ -8,6 +8,8 @@
 struct kvm_vm_arch {
 	uint64_t c_bit;
 	uint64_t s_bit;
+	int sev_fd;
+	bool is_pt_protected;
 };
 
 static inline bool __vm_arch_has_protected_memory(struct kvm_vm_arch *arch)
diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h
index 0f4792083d01..3bd03b088dda 100644
--- a/tools/testing/selftests/kvm/include/x86_64/processor.h
+++ b/tools/testing/selftests/kvm/include/x86_64/processor.h
@@ -23,6 +23,12 @@
 extern bool host_cpu_is_intel;
 extern bool host_cpu_is_amd;
 
+enum vm_guest_x86_subtype {
+	VM_SUBTYPE_NONE = 0,
+	VM_SUBTYPE_SEV,
+	VM_SUBTYPE_SEV_ES,
+};
+
 /* Forced emulation prefix, used to invoke the emulator unconditionally. */
 #define KVM_FEP "ud2; .byte 'k', 'v', 'm';"
 
@@ -276,6 +282,7 @@ struct kvm_x86_cpu_property {
 #define X86_PROPERTY_MAX_EXT_LEAF		KVM_X86_CPU_PROPERTY(0x80000000, 0, EAX, 0, 31)
 #define X86_PROPERTY_MAX_PHY_ADDR		KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 0, 7)
 #define X86_PROPERTY_MAX_VIRT_ADDR		KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 8, 15)
+#define X86_PROPERTY_SEV_C_BIT			KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 0, 5)
 #define X86_PROPERTY_PHYS_ADDR_REDUCTION	KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 6, 11)
 
 #define X86_PROPERTY_MAX_CENTAUR_LEAF		KVM_X86_CPU_PROPERTY(0xC0000000, 0, EAX, 0, 31)
@@ -1093,6 +1100,7 @@ do {											\
 } while (0)
 
 void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits);
+void kvm_init_vm_address_properties(struct kvm_vm *vm);
 bool vm_is_unrestricted_guest(struct kvm_vm *vm);
 
 struct ex_regs {
diff --git a/tools/testing/selftests/kvm/include/x86_64/sev.h b/tools/testing/selftests/kvm/include/x86_64/sev.h
new file mode 100644
index 000000000000..de5283bef752
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/x86_64/sev.h
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Helpers used for SEV guests
+ *
+ */
+#ifndef SELFTEST_KVM_SEV_H
+#define SELFTEST_KVM_SEV_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "linux/psp-sev.h"
+
+#include "kvm_util.h"
+#include "svm_util.h"
+#include "processor.h"
+
+enum sev_guest_state {
+	SEV_GUEST_STATE_UNINITIALIZED = 0,
+	SEV_GUEST_STATE_LAUNCH_UPDATE,
+	SEV_GUEST_STATE_LAUNCH_SECRET,
+	SEV_GUEST_STATE_RUNNING,
+};
+
+#define SEV_POLICY_NO_DBG	(1UL << 0)
+#define SEV_POLICY_ES		(1UL << 2)
+
+void sev_vm_launch(struct kvm_vm *vm, uint32_t policy);
+void sev_vm_launch_measure(struct kvm_vm *vm, uint8_t *measurement);
+void sev_vm_launch_finish(struct kvm_vm *vm);
+
+struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t policy, void *guest_code,
+					   struct kvm_vcpu **cpu);
+
+kvm_static_assert(SEV_RET_SUCCESS == 0);
+
+/*
+ * The KVM_MEMORY_ENCRYPT_OP uAPI is utter garbage and takes an "unsigned long"
+ * instead of a proper struct.  The size of the parameter is embedded in the
+ * ioctl number, i.e. is ABI and thus immutable.  Hack around the mess by
+ * creating an overlay to pass in an "unsigned long" without a cast (casting
+ * will make the compiler unhappy due to dereferencing an aliased pointer).
+ */
+#define __vm_sev_ioctl(vm, cmd, arg)					\
+({									\
+	int r;								\
+									\
+	union {								\
+		struct kvm_sev_cmd c;					\
+		unsigned long raw;					\
+	} sev_cmd = { .c = {						\
+		.id = (cmd),						\
+		.data = (uint64_t)(arg),				\
+		.sev_fd = (vm)->arch.sev_fd,				\
+	} };								\
+									\
+	r = __vm_ioctl(vm, KVM_MEMORY_ENCRYPT_OP, &sev_cmd.raw);	\
+	r ?: sev_cmd.c.error;						\
+})
+
+#define vm_sev_ioctl(vm, cmd, arg)					\
+({									\
+	int ret = __vm_sev_ioctl(vm, cmd, arg);				\
+									\
+	__TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd,	ret, vm);		\
+})
+
+static inline void sev_vm_init(struct kvm_vm *vm)
+{
+	vm->arch.sev_fd = open_sev_dev_path_or_exit();
+
+	vm_sev_ioctl(vm, KVM_SEV_INIT, NULL);
+}
+
+
+static inline void sev_es_vm_init(struct kvm_vm *vm)
+{
+	vm->arch.sev_fd = open_sev_dev_path_or_exit();
+
+	vm_sev_ioctl(vm, KVM_SEV_ES_INIT, NULL);
+}
+
+static inline void sev_register_encrypted_memory(struct kvm_vm *vm,
+						 struct userspace_mem_region *region)
+{
+	struct kvm_enc_region range = {
+		.addr = region->region.userspace_addr,
+		.size = region->region.memory_size,
+	};
+
+	vm_ioctl(vm, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
+}
+
+static inline void sev_launch_update_data(struct kvm_vm *vm, vm_paddr_t gpa,
+					  uint64_t size)
+{
+	struct kvm_sev_launch_update_data update_data = {
+		.uaddr = (unsigned long)addr_gpa2hva(vm, gpa),
+		.len = size,
+	};
+
+	vm_sev_ioctl(vm, KVM_SEV_LAUNCH_UPDATE_DATA, &update_data);
+}
+
+#endif /* SELFTEST_KVM_SEV_H */
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 19511137d1ae..b2262b5fad9e 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -317,6 +317,7 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
 	case VM_MODE_PXXV48_4K:
 #ifdef __x86_64__
 		kvm_get_cpu_address_width(&vm->pa_bits, &vm->va_bits);
+		kvm_init_vm_address_properties(vm);
 		/*
 		 * Ignore KVM support for 5-level paging (vm->va_bits == 57),
 		 * it doesn't take effect unless a CR4.LA57 is set, which it
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
index 6c1d2c0ec584..aa92220bf5da 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
@@ -9,6 +9,7 @@
 #include "test_util.h"
 #include "kvm_util.h"
 #include "processor.h"
+#include "sev.h"
 
 #ifndef NUM_INTERRUPTS
 #define NUM_INTERRUPTS 256
@@ -278,6 +279,9 @@ uint64_t *__vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr,
 {
 	uint64_t *pml4e, *pdpe, *pde;
 
+	TEST_ASSERT(!vm->arch.is_pt_protected,
+		    "Walking page tables of protected guests is impossible");
+
 	TEST_ASSERT(*level >= PG_LEVEL_NONE && *level < PG_LEVEL_NUM,
 		    "Invalid PG_LEVEL_* '%d'", *level);
 
@@ -573,6 +577,11 @@ void kvm_arch_vm_post_create(struct kvm_vm *vm)
 	vm_create_irqchip(vm);
 	sync_global_to_guest(vm, host_cpu_is_intel);
 	sync_global_to_guest(vm, host_cpu_is_amd);
+
+	if (vm->subtype == VM_SUBTYPE_SEV)
+		sev_vm_init(vm);
+	else if (vm->subtype == VM_SUBTYPE_SEV_ES)
+		sev_es_vm_init(vm);
 }
 
 struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id,
@@ -1063,6 +1072,14 @@ void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits)
 	}
 }
 
+void kvm_init_vm_address_properties(struct kvm_vm *vm)
+{
+	if (vm->subtype == VM_SUBTYPE_SEV) {
+		vm->arch.c_bit = BIT_ULL(this_cpu_property(X86_PROPERTY_SEV_C_BIT));
+		vm->gpa_tag_mask = vm->arch.c_bit;
+	}
+}
+
 static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr,
 			  int dpl, unsigned short selector)
 {
diff --git a/tools/testing/selftests/kvm/lib/x86_64/sev.c b/tools/testing/selftests/kvm/lib/x86_64/sev.c
new file mode 100644
index 000000000000..9f5a3dbb5e65
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/x86_64/sev.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#define _GNU_SOURCE /* for program_invocation_short_name */
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "sev.h"
+
+/*
+ * sparsebit_next_clear() can return 0 if [x, 2**64-1] are all set, and the
+ * -1 would then cause an underflow back to 2**64 - 1. This is expected and
+ * correct.
+ *
+ * If the last range in the sparsebit is [x, y] and we try to iterate,
+ * sparsebit_next_set() will return 0, and sparsebit_next_clear() will try
+ * and find the first range, but that's correct because the condition
+ * expression would cause us to quit the loop.
+ */
+static void encrypt_region(struct kvm_vm *vm, struct userspace_mem_region *region)
+{
+	const struct sparsebit *protected_phy_pages = region->protected_phy_pages;
+	const vm_paddr_t gpa_base = region->region.guest_phys_addr;
+	const sparsebit_idx_t lowest_page_in_region = gpa_base >> vm->page_shift;
+	sparsebit_idx_t i, j;
+
+	if (!sparsebit_any_set(protected_phy_pages))
+		return;
+
+	sev_register_encrypted_memory(vm, region);
+
+	sparsebit_for_each_set_range(protected_phy_pages, i, j) {
+		const uint64_t size = (j - i + 1) * vm->page_size;
+		const uint64_t offset = (i - lowest_page_in_region) * vm->page_size;
+
+		sev_launch_update_data(vm, gpa_base + offset, size);
+	}
+}
+
+void sev_vm_launch(struct kvm_vm *vm, uint32_t policy)
+{
+	struct kvm_sev_launch_start launch_start = {
+		.policy = policy,
+	};
+	struct userspace_mem_region *region;
+	struct kvm_sev_guest_status status;
+	int ctr;
+
+	vm_sev_ioctl(vm, KVM_SEV_LAUNCH_START, &launch_start);
+	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &status);
+
+	TEST_ASSERT_EQ(status.policy, policy);
+	TEST_ASSERT_EQ(status.state, SEV_GUEST_STATE_LAUNCH_UPDATE);
+
+	hash_for_each(vm->regions.slot_hash, ctr, region, slot_node)
+		encrypt_region(vm, region);
+
+	vm->arch.is_pt_protected = true;
+}
+
+void sev_vm_launch_measure(struct kvm_vm *vm, uint8_t *measurement)
+{
+	struct kvm_sev_launch_measure launch_measure;
+	struct kvm_sev_guest_status guest_status;
+
+	launch_measure.len = 256;
+	launch_measure.uaddr = (__u64)measurement;
+	vm_sev_ioctl(vm, KVM_SEV_LAUNCH_MEASURE, &launch_measure);
+
+	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &guest_status);
+	TEST_ASSERT_EQ(guest_status.state, SEV_GUEST_STATE_LAUNCH_SECRET);
+}
+
+void sev_vm_launch_finish(struct kvm_vm *vm)
+{
+	struct kvm_sev_guest_status status;
+
+	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &status);
+	TEST_ASSERT(status.state == SEV_GUEST_STATE_LAUNCH_UPDATE ||
+		    status.state == SEV_GUEST_STATE_LAUNCH_SECRET,
+		    "Unexpected guest state: %d", status.state);
+
+	vm_sev_ioctl(vm, KVM_SEV_LAUNCH_FINISH, NULL);
+
+	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &status);
+	TEST_ASSERT_EQ(status.state, SEV_GUEST_STATE_RUNNING);
+}
+
+struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t policy, void *guest_code,
+					   struct kvm_vcpu **cpu)
+{
+	struct vm_shape shape = {
+		.type = VM_TYPE_DEFAULT,
+		.mode = VM_MODE_DEFAULT,
+		.subtype = VM_SUBTYPE_SEV,
+	};
+	struct kvm_vm *vm;
+	struct kvm_vcpu *cpus[1];
+	uint8_t measurement[512];
+
+	vm = __vm_create_with_vcpus(shape, 1, 0, guest_code, cpus);
+	*cpu = cpus[0];
+
+	sev_vm_launch(vm, policy);
+
+	/* TODO: Validate the measurement is as expected. */
+	sev_vm_launch_measure(vm, measurement);
+
+	sev_vm_launch_finish(vm);
+
+	return vm;
+}
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:56 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:56 -0800
Subject: [PATCH v9 09/11] KVM: selftests: Use the SEV library APIs in the
 intra-host migration test
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-10-seanjc@google.com>

Port the existing intra-host SEV(-ES) migration test to the recently added
SEV library, which handles much of the boilerplate needed to create and
configure SEV guests.

Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../selftests/kvm/x86_64/sev_migrate_tests.c  | 67 ++++++-------------
 1 file changed, 21 insertions(+), 46 deletions(-)

diff --git a/tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c b/tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c
index a49828adf294..d6f7428e42c6 100644
--- a/tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c
+++ b/tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c
@@ -10,11 +10,9 @@
 #include "test_util.h"
 #include "kvm_util.h"
 #include "processor.h"
-#include "svm_util.h"
+#include "sev.h"
 #include "kselftest.h"
 
-#define SEV_POLICY_ES 0b100
-
 #define NR_MIGRATE_TEST_VCPUS 4
 #define NR_MIGRATE_TEST_VMS 3
 #define NR_LOCK_TESTING_THREADS 3
@@ -22,46 +20,24 @@
 
 bool have_sev_es;
 
-static int __sev_ioctl(int vm_fd, int cmd_id, void *data, __u32 *fw_error)
-{
-	struct kvm_sev_cmd cmd = {
-		.id = cmd_id,
-		.data = (uint64_t)data,
-		.sev_fd = open_sev_dev_path_or_exit(),
-	};
-	int ret;
-
-	ret = ioctl(vm_fd, KVM_MEMORY_ENCRYPT_OP, &cmd);
-	*fw_error = cmd.error;
-	return ret;
-}
-
-static void sev_ioctl(int vm_fd, int cmd_id, void *data)
-{
-	int ret;
-	__u32 fw_error;
-
-	ret = __sev_ioctl(vm_fd, cmd_id, data, &fw_error);
-	TEST_ASSERT(ret == 0 && fw_error == SEV_RET_SUCCESS,
-		    "%d failed: return code: %d, errno: %d, fw error: %d",
-		    cmd_id, ret, errno, fw_error);
-}
-
 static struct kvm_vm *sev_vm_create(bool es)
 {
 	struct kvm_vm *vm;
-	struct kvm_sev_launch_start start = { 0 };
 	int i;
 
 	vm = vm_create_barebones();
-	sev_ioctl(vm->fd, es ? KVM_SEV_ES_INIT : KVM_SEV_INIT, NULL);
+	if (!es)
+		sev_vm_init(vm);
+	else
+		sev_es_vm_init(vm);
+
 	for (i = 0; i < NR_MIGRATE_TEST_VCPUS; ++i)
 		__vm_vcpu_add(vm, i);
+
+	sev_vm_launch(vm, es ? SEV_POLICY_ES : 0);
+
 	if (es)
-		start.policy |= SEV_POLICY_ES;
-	sev_ioctl(vm->fd, KVM_SEV_LAUNCH_START, &start);
-	if (es)
-		sev_ioctl(vm->fd, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL);
+		vm_sev_ioctl(vm, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL);
 	return vm;
 }
 
@@ -181,7 +157,7 @@ static void test_sev_migrate_parameters(void)
 	sev_vm = sev_vm_create(/* es= */ false);
 	sev_es_vm = sev_vm_create(/* es= */ true);
 	sev_es_vm_no_vmsa = vm_create_barebones();
-	sev_ioctl(sev_es_vm_no_vmsa->fd, KVM_SEV_ES_INIT, NULL);
+	sev_es_vm_init(sev_es_vm_no_vmsa);
 	__vm_vcpu_add(sev_es_vm_no_vmsa, 1);
 
 	ret = __sev_migrate_from(sev_vm, sev_es_vm);
@@ -230,13 +206,13 @@ static void sev_mirror_create(struct kvm_vm *dst, struct kvm_vm *src)
 	TEST_ASSERT(!ret, "Copying context failed, ret: %d, errno: %d", ret, errno);
 }
 
-static void verify_mirror_allowed_cmds(int vm_fd)
+static void verify_mirror_allowed_cmds(struct kvm_vm *vm)
 {
 	struct kvm_sev_guest_status status;
+	int cmd_id;
 
-	for (int cmd_id = KVM_SEV_INIT; cmd_id < KVM_SEV_NR_MAX; ++cmd_id) {
+	for (cmd_id = KVM_SEV_INIT; cmd_id < KVM_SEV_NR_MAX; ++cmd_id) {
 		int ret;
-		__u32 fw_error;
 
 		/*
 		 * These commands are allowed for mirror VMs, all others are
@@ -256,14 +232,13 @@ static void verify_mirror_allowed_cmds(int vm_fd)
 		 * These commands should be disallowed before the data
 		 * parameter is examined so NULL is OK here.
 		 */
-		ret = __sev_ioctl(vm_fd, cmd_id, NULL, &fw_error);
-		TEST_ASSERT(
-			ret == -1 && errno == EINVAL,
-			"Should not be able call command: %d. ret: %d, errno: %d",
-			cmd_id, ret, errno);
+		ret = __vm_sev_ioctl(vm, cmd_id, NULL);
+		TEST_ASSERT(ret == -1 && errno == EINVAL,
+			    "Should not be able call command: %d. ret: %d, errno: %d",
+			    cmd_id, ret, errno);
 	}
 
-	sev_ioctl(vm_fd, KVM_SEV_GUEST_STATUS, &status);
+	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &status);
 }
 
 static void test_sev_mirror(bool es)
@@ -281,9 +256,9 @@ static void test_sev_mirror(bool es)
 		__vm_vcpu_add(dst_vm, i);
 
 	if (es)
-		sev_ioctl(dst_vm->fd, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL);
+		vm_sev_ioctl(dst_vm, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL);
 
-	verify_mirror_allowed_cmds(dst_vm->fd);
+	verify_mirror_allowed_cmds(dst_vm);
 
 	kvm_vm_free(src_vm);
 	kvm_vm_free(dst_vm);
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:57 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:57 -0800
Subject: [PATCH v9 10/11] KVM: selftests: Add a basic SEV smoke test
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-11-seanjc@google.com>

From: Peter Gonda <pgonda at google.com>

Add a basic smoke test for SEV guests to verify that KVM can launch an
SEV guest and run a few instructions without exploding.  To verify that
SEV is indeed enabled, assert that SEV is reported as enabled in
MSR_AMD64_SEV, a.k.a. SEV_STATUS, which cannot be intercepted by KVM
(architecturally enforced).

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerly Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Suggested-by: Michael Roth <michael.roth at amd.com>
Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
[sean: rename to "sev_smoke_test"]
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/Makefile          |  1 +
 .../selftests/kvm/x86_64/sev_smoke_test.c     | 58 +++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/x86_64/sev_smoke_test.c

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 169b6ee8f733..da20e6bb43ed 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -120,6 +120,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/vmx_pmu_caps_test
 TEST_GEN_PROGS_x86_64 += x86_64/xen_shinfo_test
 TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test
 TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests
+TEST_GEN_PROGS_x86_64 += x86_64/sev_smoke_test
 TEST_GEN_PROGS_x86_64 += x86_64/amx_test
 TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test
 TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test
diff --git a/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c b/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
new file mode 100644
index 000000000000..54d72efd9b4d
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "processor.h"
+#include "svm_util.h"
+#include "linux/psp-sev.h"
+#include "sev.h"
+
+static void guest_sev_code(void)
+{
+	GUEST_ASSERT(this_cpu_has(X86_FEATURE_SEV));
+	GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ENABLED);
+
+	GUEST_DONE();
+}
+
+static void test_sev(void *guest_code, uint64_t policy)
+{
+	struct kvm_vcpu *vcpu;
+	struct kvm_vm *vm;
+	struct ucall uc;
+
+	vm = vm_sev_create_with_one_vcpu(policy, guest_code, &vcpu);
+
+	for (;;) {
+		vcpu_run(vcpu);
+
+		switch (get_ucall(vcpu, &uc)) {
+		case UCALL_SYNC:
+			continue;
+		case UCALL_DONE:
+			return;
+		case UCALL_ABORT:
+			REPORT_GUEST_ASSERT(uc);
+		default:
+			TEST_FAIL("Unexpected exit: %s",
+				  exit_reason_str(vcpu->run->exit_reason));
+		}
+	}
+
+	kvm_vm_free(vm);
+}
+
+int main(int argc, char *argv[])
+{
+	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV));
+
+	test_sev(guest_sev_code, SEV_POLICY_NO_DBG);
+	test_sev(guest_sev_code, 0);
+
+	return 0;
+}
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:58 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:58 -0800
Subject: [PATCH v9 11/11] KVM: selftests: Add a basic SEV-ES smoke test
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-12-seanjc@google.com>

Extend sev_smoke_test to also run a minimal SEV-ES smoke test so that it's
possible to test KVM's unique VMRUN=>#VMEXIT path for SEV-ES guests
without needing a full blown SEV-ES capable VM, which requires a rather
absurd amount of properly configured collateral.

Punt on proper GHCB and ucall support, and instead use the GHCB MSR
protocol to signal test completion.  The most important thing at this
point is to have _any_ kind of testing of KVM's __svm_sev_es_vcpu_run().

Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Cc: Peter Gonda <pgonda at google.com>
Cc: Carlos Bilbao <carlos.bilbao at amd.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../selftests/kvm/include/x86_64/sev.h        |  2 ++
 .../selftests/kvm/lib/x86_64/processor.c      |  2 +-
 tools/testing/selftests/kvm/lib/x86_64/sev.c  |  6 +++-
 .../selftests/kvm/x86_64/sev_smoke_test.c     | 30 +++++++++++++++++++
 4 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86_64/sev.h b/tools/testing/selftests/kvm/include/x86_64/sev.h
index de5283bef752..8a1bf88474c9 100644
--- a/tools/testing/selftests/kvm/include/x86_64/sev.h
+++ b/tools/testing/selftests/kvm/include/x86_64/sev.h
@@ -25,6 +25,8 @@ enum sev_guest_state {
 #define SEV_POLICY_NO_DBG	(1UL << 0)
 #define SEV_POLICY_ES		(1UL << 2)
 
+#define GHCB_MSR_TERM_REQ	0x100
+
 void sev_vm_launch(struct kvm_vm *vm, uint32_t policy);
 void sev_vm_launch_measure(struct kvm_vm *vm, uint8_t *measurement);
 void sev_vm_launch_finish(struct kvm_vm *vm);
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
index aa92220bf5da..a33289a5b89a 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
@@ -1074,7 +1074,7 @@ void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits)
 
 void kvm_init_vm_address_properties(struct kvm_vm *vm)
 {
-	if (vm->subtype == VM_SUBTYPE_SEV) {
+	if (vm->subtype == VM_SUBTYPE_SEV || vm->subtype == VM_SUBTYPE_SEV_ES) {
 		vm->arch.c_bit = BIT_ULL(this_cpu_property(X86_PROPERTY_SEV_C_BIT));
 		vm->gpa_tag_mask = vm->arch.c_bit;
 	}
diff --git a/tools/testing/selftests/kvm/lib/x86_64/sev.c b/tools/testing/selftests/kvm/lib/x86_64/sev.c
index 9f5a3dbb5e65..e248d3364b9c 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/sev.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/sev.c
@@ -53,6 +53,9 @@ void sev_vm_launch(struct kvm_vm *vm, uint32_t policy)
 	hash_for_each(vm->regions.slot_hash, ctr, region, slot_node)
 		encrypt_region(vm, region);
 
+	if (policy & SEV_POLICY_ES)
+		vm_sev_ioctl(vm, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL);
+
 	vm->arch.is_pt_protected = true;
 }
 
@@ -90,7 +93,8 @@ struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t policy, void *guest_code,
 	struct vm_shape shape = {
 		.type = VM_TYPE_DEFAULT,
 		.mode = VM_MODE_DEFAULT,
-		.subtype = VM_SUBTYPE_SEV,
+		.subtype = policy & SEV_POLICY_ES ? VM_SUBTYPE_SEV_ES :
+						    VM_SUBTYPE_SEV,
 	};
 	struct kvm_vm *vm;
 	struct kvm_vcpu *cpus[1];
diff --git a/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c b/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
index 54d72efd9b4d..026779f3ed06 100644
--- a/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
+++ b/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
@@ -12,6 +12,21 @@
 #include "linux/psp-sev.h"
 #include "sev.h"
 
+
+static void guest_sev_es_code(void)
+{
+	/* TODO: Check CPUID after GHCB-based hypercall support is added. */
+	GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ENABLED);
+	GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ES_ENABLED);
+
+	/*
+	 * TODO: Add GHCB and ucall support for SEV-ES guests.  For now, simply
+	 * force "termination" to signal "done" via the GHCB MSR protocol.
+	 */
+	wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_TERM_REQ);
+	__asm__ __volatile__("rep; vmmcall");
+}
+
 static void guest_sev_code(void)
 {
 	GUEST_ASSERT(this_cpu_has(X86_FEATURE_SEV));
@@ -31,6 +46,16 @@ static void test_sev(void *guest_code, uint64_t policy)
 	for (;;) {
 		vcpu_run(vcpu);
 
+		if (policy & SEV_POLICY_ES) {
+			TEST_ASSERT(vcpu->run->exit_reason == KVM_EXIT_SYSTEM_EVENT,
+				    "Wanted SYSTEM_EVENT, got %s",
+				    exit_reason_str(vcpu->run->exit_reason));
+			TEST_ASSERT_EQ(vcpu->run->system_event.type, KVM_SYSTEM_EVENT_SEV_TERM);
+			TEST_ASSERT_EQ(vcpu->run->system_event.ndata, 1);
+			TEST_ASSERT_EQ(vcpu->run->system_event.data[0], GHCB_MSR_TERM_REQ);
+			break;
+		}
+
 		switch (get_ucall(vcpu, &uc)) {
 		case UCALL_SYNC:
 			continue;
@@ -54,5 +79,10 @@ int main(int argc, char *argv[])
 	test_sev(guest_sev_code, SEV_POLICY_NO_DBG);
 	test_sev(guest_sev_code, 0);
 
+	if (kvm_cpu_has(X86_FEATURE_SEV_ES)) {
+		test_sev(guest_sev_es_code, SEV_POLICY_ES | SEV_POLICY_NO_DBG);
+		test_sev(guest_sev_es_code, SEV_POLICY_ES);
+	}
+
 	return 0;
 }
-- 
2.44.0.rc0.258.g7320e95886-goog



From seanjc at google.com  Thu Feb 22 16:42:52 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 22 Feb 2024 16:42:52 -0800
Subject: [PATCH v9 05/11] KVM: selftests: Add support for protected vm_vaddr_* allocations
In-Reply-To: <20240223004258.3104051-1-seanjc@google.com>
References: <20240223004258.3104051-1-seanjc@google.com>
Message-ID: <20240223004258.3104051-6-seanjc@google.com>

From: Michael Roth <michael.roth at amd.com>

Test programs may wish to allocate shared vaddrs for things like
sharing memory with the guest. Since protected vms will have their
memory encrypted by default an interface is needed to explicitly
request shared pages.

Implement this by splitting the common code out from vm_vaddr_alloc()
and introducing a new vm_vaddr_alloc_shared().

Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Sean Christopherson <seanjc at google.com>
Cc: Vishal Annapurve <vannapurve at google.com>
Cc: Ackerly Tng <ackerleytng at google.com>
cc: Andrew Jones <andrew.jones at linux.dev>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Michael Roth <michael.roth at amd.com>
Reviewed-by: Itaru Kitayama <itaru.kitayama at fujitsu.com>
Tested-by: Carlos Bilbao <carlos.bilbao at amd.com>
Signed-off-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Peter Gonda <pgonda at google.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../selftests/kvm/include/kvm_util_base.h     |  3 +++
 tools/testing/selftests/kvm/lib/kvm_util.c    | 26 +++++++++++++++----
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index a82149305349..cb3159af6db3 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -590,6 +590,9 @@ vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_mi
 vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min);
 vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
 			    enum kvm_mem_region_type type);
+vm_vaddr_t vm_vaddr_alloc_shared(struct kvm_vm *vm, size_t sz,
+				 vm_vaddr_t vaddr_min,
+				 enum kvm_mem_region_type type);
 vm_vaddr_t vm_vaddr_alloc_pages(struct kvm_vm *vm, int nr_pages);
 vm_vaddr_t __vm_vaddr_alloc_page(struct kvm_vm *vm,
 				 enum kvm_mem_region_type type);
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index ea677aa019ef..e7f4f84f2e68 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1431,15 +1431,17 @@ vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz,
 	return pgidx_start * vm->page_size;
 }
 
-vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
-			    enum kvm_mem_region_type type)
+static vm_vaddr_t ____vm_vaddr_alloc(struct kvm_vm *vm, size_t sz,
+				     vm_vaddr_t vaddr_min,
+				     enum kvm_mem_region_type type,
+				     bool protected)
 {
 	uint64_t pages = (sz >> vm->page_shift) + ((sz % vm->page_size) != 0);
 
 	virt_pgd_alloc(vm);
-	vm_paddr_t paddr = vm_phy_pages_alloc(vm, pages,
-					      KVM_UTIL_MIN_PFN * vm->page_size,
-					      vm->memslots[type]);
+	vm_paddr_t paddr = __vm_phy_pages_alloc(vm, pages,
+						KVM_UTIL_MIN_PFN * vm->page_size,
+						vm->memslots[type], protected);
 
 	/*
 	 * Find an unused range of virtual page addresses of at least
@@ -1459,6 +1461,20 @@ vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
 	return vaddr_start;
 }
 
+vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
+			    enum kvm_mem_region_type type)
+{
+	return ____vm_vaddr_alloc(vm, sz, vaddr_min, type,
+				  vm_arch_has_protected_memory(vm));
+}
+
+vm_vaddr_t vm_vaddr_alloc_shared(struct kvm_vm *vm, size_t sz,
+				 vm_vaddr_t vaddr_min,
+				 enum kvm_mem_region_type type)
+{
+	return ____vm_vaddr_alloc(vm, sz, vaddr_min, type, false);
+}
+
 /*
  * VM Virtual Address Allocate
  *
-- 
2.44.0.rc0.258.g7320e95886-goog



From peng.fan at oss.nxp.com  Thu Feb 22 17:16:37 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 23 Feb 2024 09:16:37 +0800
Subject: [PATCH v4 0/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
Message-ID: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>

This patchset is a rework from Oleksii's RFC v5 patchset
https://lore.kernel.org/all/cover.1698353854.git.oleksii_moisieiev at epam.com/

This patchset introduces some changes based on RFC v5:
- introduce helper get_max_msg_size
- support compatible string
- iterate the id_table
- Support multiple configs in one command
- Added i.MX support
- Patch 5 firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support
  is almost same as RFCv5 expect multiple configs support.
- Patch 4 the dt-bindings includes compatible string to support i.MX
- Rebased on 2023-12-15 linux-next/master

If any comments from RFC v5 are missed, I am sorry in advance.

This PINCTRL Protocol is following Version 3.2 SCMI Spec Beta release.

On ARM-based systems, a separate Cortex-M based System Control Processor
(SCP) provides control on pins, as well as with power, clocks, reset
controllers. So implement the driver to support such cases.

The i.MX95 Example as below:

Configuration:
The scmi-pinctrl driver can be configured using DT bindings.
For example:
/ {
	sram0: sram at 445b1000 {
		compatible = "mmio-sram";
		reg = <0x0 0x445b1000 0x0 0x400>;

		#address-cells = <1>;
		#size-cells = <1>;
		ranges = <0x0 0x0 0x445b1000 0x400>;

		scmi_buf0: scmi-sram-section at 0 {
			compatible = "arm,scmi-shmem";
			reg = <0x0 0x80>;
		};

		scmi_buf1: scmi-sram-section at 80 {
			compatible = "arm,scmi-shmem";
			reg = <0x80 0x80>;
		};
	};

	firmware {
		scmi {
			compatible = "arm,scmi";
			mboxes = <&mu2 5 0>, <&mu2 3 0>, <&mu2 3 1>;
			shmem = <&scmi_buf0>, <&scmi_buf1>;
			#address-cells = <1>;
			#size-cells = <0>;

			scmi_iomuxc: protocol at 19 {
				compatible = "fsl,imx95-scmi-pinctrl";
				reg = <0x19>;
			};
		};
	};
};

&scmi_iomuxc {
	pinctrl_tpm3: tpm3grp {
		fsl,pins = <
			IMX95_PAD_GPIO_IO12__TPM3_CH2		0x51e
		>;
	};
};

This patchset has been tested on i.MX95-19x19-EVK board.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Changes in v4:
- Rebased to next-20240222
- Drop pinctrl-scmi-imx and compatible patches in V3
- Add T-b and R-b collected from v3
- Link to v3: https://lore.kernel.org/r/20240121-pinctrl-scmi-v3-0-8d94ba79dca8 at nxp.com

Changes in v3:
- Add R-b for dt-binding patch
- Use 80 chars per line to align with other scmi drivers
- Add pinctrl_scmi_alloc_configs pinctrl_scmi_free_configs to replace
  driver global config_value and config_type array to avoid in parrell
  access issue. When num_configs is larger than 4, use alloc, else use
  stack.
- Drop the separate MAITAINERS entry for firmware scmi pinctrl
- Use enum type, not u8 when referring the scmi or generic pin conf type
- Drop scmi_pinctrl_config_get_all which is not used at all for now.
- Update copyright year to 2024
- Move the enum scmi_pinctrl_conf_type above pinctrl_proto_ops for consistency
- Link to v2: https://lore.kernel.org/r/20240104-pinctrl-scmi-v2-0-a9bd86ab5a84 at nxp.com

Changes in v2:
 Added comments, and added R-b for Patch 1
 Moved the compatile string and i.MX patch to the end, marked NOT APPLY
 Patchset based on lore.kernel.org/all/20231221151129.325749-1-cristian.marussi at arm.com/
 Addressed the binding doc issue, dropped i.MX content.
 For the firmware pinctrl scmi driver, addressed the comments from Cristian
 For the pinctrl scmi driver, addressed comments from Cristian

 For the i.MX95 OEM stuff, I not have good idea, expect using compatbile
 string. Maybe the firmware public an protocol attribute to indicate it is
 VENDOR stuff or NXP use a new protocol id, not 0x19. But I think
 current pinctrl-scmi.c not able to support OEM config, should we extend
 it with some method? Anyway if patch 1-4 is good enough, they could
 be picked up first.

 Since I am only able to test the patch on i.MX95 which not support
 geneirc pinconf, only OEM configs are tested in my side.

---
Oleksii Moisieiev (1):
      firmware: arm_scmi: Add SCMI v3.2 pincontrol protocol basic support

Peng Fan (3):
      firmware: arm_scmi: introduce helper get_max_msg_size
      dt-bindings: firmware: arm,scmi: support pinctrl protocol
      pinctrl: Implementation of the generic scmi-pinctrl driver

 .../devicetree/bindings/firmware/arm,scmi.yaml     |  50 ++
 MAINTAINERS                                        |   1 +
 drivers/firmware/arm_scmi/Makefile                 |   1 +
 drivers/firmware/arm_scmi/driver.c                 |  17 +
 drivers/firmware/arm_scmi/pinctrl.c                | 908 +++++++++++++++++++++
 drivers/firmware/arm_scmi/protocols.h              |   3 +
 drivers/pinctrl/Kconfig                            |  11 +
 drivers/pinctrl/Makefile                           |   1 +
 drivers/pinctrl/pinctrl-scmi.c                     | 593 ++++++++++++++
 include/linux/scmi_protocol.h                      |  75 ++
 10 files changed, 1660 insertions(+)
---
base-commit: e31185ce00a96232308300008db193416ceb9769
change-id: 20231215-pinctrl-scmi-4c5b0374f4c6

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Thu Feb 22 17:16:38 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 23 Feb 2024 09:16:38 +0800
Subject: [PATCH v4 1/4] firmware: arm_scmi: introduce helper
 get_max_msg_size
In-Reply-To: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>
References: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>
Message-ID: <20240223-pinctrl-scmi-v4-1-10eb5a379274@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

When Agent sending data to SCMI server, the Agent driver could check
the size to avoid protocol buffer overflow. So introduce the helper
get_max_msg_size.

Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/firmware/arm_scmi/driver.c    | 15 +++++++++++++++
 drivers/firmware/arm_scmi/protocols.h |  2 ++
 2 files changed, 17 insertions(+)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 34d77802c990..6f059a585896 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1488,6 +1488,20 @@ static int scmi_common_extended_name_get(const struct scmi_protocol_handle *ph,
 	return ret;
 }
 
+/**
+ * scmi_common_get_max_msg_size  - Get maximum message size
+ * @ph: A protocol handle reference.
+ *
+ * Return: Maximum message size for the current protocol.
+ */
+static int scmi_common_get_max_msg_size(const struct scmi_protocol_handle *ph)
+{
+	const struct scmi_protocol_instance *pi = ph_to_pi(ph);
+	struct scmi_info *info = handle_to_scmi_info(pi->handle);
+
+	return info->desc->max_msg_size;
+}
+
 /**
  * struct scmi_iterator  - Iterator descriptor
  * @msg: A reference to the message TX buffer; filled by @prepare_message with
@@ -1796,6 +1810,7 @@ static int scmi_protocol_msg_check(const struct scmi_protocol_handle *ph,
 
 static const struct scmi_proto_helpers_ops helpers_ops = {
 	.extended_name_get = scmi_common_extended_name_get,
+	.get_max_msg_size = scmi_common_get_max_msg_size,
 	.iter_response_init = scmi_iterator_init,
 	.iter_response_run = scmi_iterator_run,
 	.protocol_msg_check = scmi_protocol_msg_check,
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index 693019fff0f6..9c8edb1aa901 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -257,6 +257,7 @@ struct scmi_fc_info {
  * @fastchannel_init: A common helper used to initialize FC descriptors by
  *		      gathering FC descriptions from the SCMI platform server.
  * @fastchannel_db_ring: A common helper to ring a FC doorbell.
+ * @get_max_msg_size: A common helper to get the maximum message size.
  */
 struct scmi_proto_helpers_ops {
 	int (*extended_name_get)(const struct scmi_protocol_handle *ph,
@@ -275,6 +276,7 @@ struct scmi_proto_helpers_ops {
 				 void __iomem **p_addr,
 				 struct scmi_fc_db_info **p_db);
 	void (*fastchannel_db_ring)(struct scmi_fc_db_info *db);
+	int (*get_max_msg_size)(const struct scmi_protocol_handle *ph);
 };
 
 /**

-- 
2.37.1



From peng.fan at oss.nxp.com  Thu Feb 22 17:16:39 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 23 Feb 2024 09:16:39 +0800
Subject: [PATCH v4 2/4] dt-bindings: firmware: arm,scmi: support pinctrl
 protocol
In-Reply-To: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>
References: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>
Message-ID: <20240223-pinctrl-scmi-v4-2-10eb5a379274@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add SCMI v3.2 pinctrl protocol bindings and example.

Reviewed-by: Rob Herring <robh at kernel.org>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/firmware/arm,scmi.yaml     | 50 ++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
index 4591523b51a0..bba4a37de6b4 100644
--- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
+++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
@@ -247,6 +247,37 @@ properties:
       reg:
         const: 0x18
 
+  protocol at 19:
+    type: object
+    allOf:
+      - $ref: '#/$defs/protocol-node'
+      - $ref: /schemas/pinctrl/pinctrl.yaml
+
+    unevaluatedProperties: false
+
+    properties:
+      reg:
+        const: 0x19
+
+    patternProperties:
+      '-pins$':
+        type: object
+        allOf:
+          - $ref: /schemas/pinctrl/pincfg-node.yaml#
+          - $ref: /schemas/pinctrl/pinmux-node.yaml#
+        unevaluatedProperties: false
+
+        description:
+          A pin multiplexing sub-node describe how to configure a
+          set of pins is some desired function.
+          A single sub-node may define several pin configurations.
+          This sub-node is using default pinctrl bindings to configure
+          pin multiplexing and using SCMI protocol to apply specified
+          configuration using SCMI protocol.
+
+    required:
+      - reg
+
 additionalProperties: false
 
 $defs:
@@ -401,6 +432,25 @@ examples:
             scmi_powercap: protocol at 18 {
                 reg = <0x18>;
             };
+
+            scmi_pinctrl: protocol at 19 {
+                reg = <0x19>;
+
+                i2c2-pins {
+                    groups = "g_i2c2_a", "g_i2c2_b";
+                    function = "f_i2c2";
+                };
+
+                mdio-pins {
+                    groups = "g_avb_mdio";
+                    drive-strength = <24>;
+                };
+
+                keys_pins: keys-pins {
+                    pins = "gpio_5_17", "gpio_5_20", "gpio_5_22", "gpio_2_1";
+                    bias-pull-up;
+                };
+            };
         };
     };
 

-- 
2.37.1



From peng.fan at oss.nxp.com  Thu Feb 22 17:16:40 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 23 Feb 2024 09:16:40 +0800
Subject: [PATCH v4 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>
References: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>
Message-ID: <20240223-pinctrl-scmi-v4-3-10eb5a379274@nxp.com>

From: Oleksii Moisieiev <oleksii_moisieiev at epam.com>

Add basic implementation of the SCMI v3.2 pincontrol protocol.

Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>
Tested-by: Cristian Marussi <cristian.marussi at arm.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev at epam.com>
Co-developed-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/firmware/arm_scmi/Makefile    |   1 +
 drivers/firmware/arm_scmi/driver.c    |   2 +
 drivers/firmware/arm_scmi/pinctrl.c   | 908 ++++++++++++++++++++++++++++++++++
 drivers/firmware/arm_scmi/protocols.h |   1 +
 include/linux/scmi_protocol.h         |  75 +++
 5 files changed, 987 insertions(+)

diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
index a7bc4796519c..8e3874ff1544 100644
--- a/drivers/firmware/arm_scmi/Makefile
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -11,6 +11,7 @@ scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o powercap.o
+scmi-protocols-y += pinctrl.o
 scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
 
 obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 6f059a585896..1a4123758b2d 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -3139,6 +3139,7 @@ static int __init scmi_driver_init(void)
 	scmi_voltage_register();
 	scmi_system_register();
 	scmi_powercap_register();
+	scmi_pinctrl_register();
 
 	return platform_driver_register(&scmi_driver);
 }
@@ -3156,6 +3157,7 @@ static void __exit scmi_driver_exit(void)
 	scmi_voltage_unregister();
 	scmi_system_unregister();
 	scmi_powercap_unregister();
+	scmi_pinctrl_unregister();
 
 	scmi_transports_exit();
 
diff --git a/drivers/firmware/arm_scmi/pinctrl.c b/drivers/firmware/arm_scmi/pinctrl.c
new file mode 100644
index 000000000000..0fcfa4269473
--- /dev/null
+++ b/drivers/firmware/arm_scmi/pinctrl.c
@@ -0,0 +1,908 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Pinctrl Protocol
+ *
+ * Copyright (C) 2024 EPAM
+ * Copyright 2024 NXP
+ */
+
+#include <linux/module.h>
+#include <linux/scmi_protocol.h>
+#include <linux/slab.h>
+
+#include "common.h"
+#include "protocols.h"
+
+/* Updated only after ALL the mandatory features for that version are merged */
+#define SCMI_PROTOCOL_SUPPORTED_VERSION                0x0
+
+#define REG_TYPE_BITS GENMASK(9, 8)
+#define REG_CONFIG GENMASK(7, 0)
+
+#define GET_GROUPS_NR(x)	le32_get_bits((x), GENMASK(31, 16))
+#define GET_PINS_NR(x)		le32_get_bits((x), GENMASK(15, 0))
+#define GET_FUNCTIONS_NR(x)	le32_get_bits((x), GENMASK(15, 0))
+
+#define EXT_NAME_FLAG(x)	le32_get_bits((x), BIT(31))
+#define NUM_ELEMS(x)		le32_get_bits((x), GENMASK(15, 0))
+
+#define REMAINING(x)		le32_get_bits((x), GENMASK(31, 16))
+#define RETURNED(x)		le32_get_bits((x), GENMASK(11, 0))
+
+enum scmi_pinctrl_protocol_cmd {
+	PINCTRL_ATTRIBUTES = 0x3,
+	PINCTRL_LIST_ASSOCIATIONS = 0x4,
+	PINCTRL_CONFIG_GET = 0x5,
+	PINCTRL_CONFIG_SET = 0x6,
+	PINCTRL_FUNCTION_SELECT = 0x7,
+	PINCTRL_REQUEST = 0x8,
+	PINCTRL_RELEASE = 0x9,
+	PINCTRL_NAME_GET = 0xa,
+	PINCTRL_SET_PERMISSIONS = 0xb
+};
+
+struct scmi_msg_conf_set {
+	__le32 identifier;
+	__le32 attributes;
+	__le32 configs[];
+};
+
+struct scmi_msg_conf_get {
+	__le32 identifier;
+	__le32 attributes;
+};
+
+struct scmi_resp_conf_get {
+	__le32 num_configs;
+	__le32 configs[];
+};
+
+struct scmi_msg_pinctrl_protocol_attributes {
+	__le32 attributes_low;
+	__le32 attributes_high;
+};
+
+struct scmi_msg_pinctrl_attributes {
+	__le32 identifier;
+	__le32 flags;
+};
+
+struct scmi_resp_pinctrl_attributes {
+	__le32 attributes;
+	u8 name[SCMI_SHORT_NAME_MAX_SIZE];
+};
+
+struct scmi_msg_pinctrl_list_assoc {
+	__le32 identifier;
+	__le32 flags;
+	__le32 index;
+};
+
+struct scmi_resp_pinctrl_list_assoc {
+	__le32 flags;
+	__le16 array[];
+};
+
+struct scmi_msg_func_set {
+	__le32 identifier;
+	__le32 function_id;
+	__le32 flags;
+};
+
+struct scmi_msg_request {
+	__le32 identifier;
+	__le32 flags;
+};
+
+struct scmi_group_info {
+	char name[SCMI_MAX_STR_SIZE];
+	bool present;
+	unsigned int *group_pins;
+	unsigned int nr_pins;
+};
+
+struct scmi_function_info {
+	char name[SCMI_MAX_STR_SIZE];
+	bool present;
+	unsigned int *groups;
+	unsigned int nr_groups;
+};
+
+struct scmi_pin_info {
+	char name[SCMI_MAX_STR_SIZE];
+	bool present;
+};
+
+struct scmi_pinctrl_info {
+	u32 version;
+	int nr_groups;
+	int nr_functions;
+	int nr_pins;
+	struct scmi_group_info *groups;
+	struct scmi_function_info *functions;
+	struct scmi_pin_info *pins;
+};
+
+static int scmi_pinctrl_attributes_get(const struct scmi_protocol_handle *ph,
+				       struct scmi_pinctrl_info *pi)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_pinctrl_protocol_attributes *attr;
+
+	ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0, sizeof(*attr),
+				      &t);
+	if (ret)
+		return ret;
+
+	attr = t->rx.buf;
+
+	ret = ph->xops->do_xfer(ph, t);
+	if (!ret) {
+		pi->nr_functions = GET_FUNCTIONS_NR(attr->attributes_high);
+		pi->nr_groups = GET_GROUPS_NR(attr->attributes_low);
+		pi->nr_pins = GET_PINS_NR(attr->attributes_low);
+	}
+
+	ph->xops->xfer_put(ph, t);
+	return ret;
+}
+
+static int scmi_pinctrl_count_get(const struct scmi_protocol_handle *ph,
+				  enum scmi_pinctrl_selector_type type)
+{
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+	switch (type) {
+	case PIN_TYPE:
+		return pi->nr_pins;
+	case GROUP_TYPE:
+		return pi->nr_groups;
+	case FUNCTION_TYPE:
+		return pi->nr_functions;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int scmi_pinctrl_validate_id(const struct scmi_protocol_handle *ph,
+				    u32 identifier,
+				    enum scmi_pinctrl_selector_type type)
+{
+	int value;
+
+	value = scmi_pinctrl_count_get(ph, type);
+	if (value < 0)
+		return value;
+
+	if (identifier >= value)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int scmi_pinctrl_attributes(const struct scmi_protocol_handle *ph,
+				   enum scmi_pinctrl_selector_type type,
+				   u32 selector, char *name,
+				   unsigned int *n_elems)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_pinctrl_attributes *tx;
+	struct scmi_resp_pinctrl_attributes *rx;
+
+	if (!name)
+		return -EINVAL;
+
+	ret = scmi_pinctrl_validate_id(ph, selector, type);
+	if (ret)
+		return ret;
+
+	ret = ph->xops->xfer_get_init(ph, PINCTRL_ATTRIBUTES, sizeof(*tx),
+				      sizeof(*rx), &t);
+	if (ret)
+		return ret;
+
+	tx = t->tx.buf;
+	rx = t->rx.buf;
+	tx->identifier = cpu_to_le32(selector);
+	tx->flags = cpu_to_le32(type);
+
+	ret = ph->xops->do_xfer(ph, t);
+	if (!ret) {
+		if (n_elems)
+			*n_elems = NUM_ELEMS(rx->attributes);
+
+		strscpy(name, rx->name, SCMI_SHORT_NAME_MAX_SIZE);
+	}
+
+	ph->xops->xfer_put(ph, t);
+
+	/*
+	 * If supported overwrite short name with the extended one;
+	 * on error just carry on and use already provided short name.
+	 */
+	if (!ret && EXT_NAME_FLAG(rx->attributes))
+		ph->hops->extended_name_get(ph, PINCTRL_NAME_GET, selector,
+					    (u32 *)&type, name,
+					    SCMI_MAX_STR_SIZE);
+	return ret;
+}
+
+struct scmi_pinctrl_ipriv {
+	u32 selector;
+	enum scmi_pinctrl_selector_type type;
+	unsigned int *array;
+};
+
+static void iter_pinctrl_assoc_prepare_message(void *message,
+					       unsigned int desc_index,
+					       const void *priv)
+{
+	struct scmi_msg_pinctrl_list_assoc *msg = message;
+	const struct scmi_pinctrl_ipriv *p = priv;
+
+	msg->identifier = cpu_to_le32(p->selector);
+	msg->flags = cpu_to_le32(p->type);
+	/* Set the number of OPPs to be skipped/already read */
+	msg->index = cpu_to_le32(desc_index);
+}
+
+static int iter_pinctrl_assoc_update_state(struct scmi_iterator_state *st,
+					   const void *response, void *priv)
+{
+	const struct scmi_resp_pinctrl_list_assoc *r = response;
+
+	st->num_returned = RETURNED(r->flags);
+	st->num_remaining = REMAINING(r->flags);
+
+	return 0;
+}
+
+static int
+iter_pinctrl_assoc_process_response(const struct scmi_protocol_handle *ph,
+				    const void *response,
+				    struct scmi_iterator_state *st, void *priv)
+{
+	const struct scmi_resp_pinctrl_list_assoc *r = response;
+	struct scmi_pinctrl_ipriv *p = priv;
+
+	p->array[st->desc_index + st->loop_idx] =
+		le16_to_cpu(r->array[st->loop_idx]);
+
+	return 0;
+}
+
+static int scmi_pinctrl_list_associations(const struct scmi_protocol_handle *ph,
+					  u32 selector,
+					  enum scmi_pinctrl_selector_type type,
+					  u16 size, unsigned int *array)
+{
+	int ret;
+	void *iter;
+	struct scmi_iterator_ops ops = {
+		.prepare_message = iter_pinctrl_assoc_prepare_message,
+		.update_state = iter_pinctrl_assoc_update_state,
+		.process_response = iter_pinctrl_assoc_process_response,
+	};
+	struct scmi_pinctrl_ipriv ipriv = {
+		.selector = selector,
+		.type = type,
+		.array = array,
+	};
+
+	if (!array || !size || type == PIN_TYPE)
+		return -EINVAL;
+
+	ret = scmi_pinctrl_validate_id(ph, selector, type);
+	if (ret)
+		return ret;
+
+	iter = ph->hops->iter_response_init(ph, &ops, size,
+					    PINCTRL_LIST_ASSOCIATIONS,
+					    sizeof(struct scmi_msg_pinctrl_list_assoc),
+					    &ipriv);
+
+	if (IS_ERR(iter))
+		return PTR_ERR(iter);
+
+	return ph->hops->iter_response_run(iter);
+}
+
+struct scmi_conf_get_ipriv {
+	u32 selector;
+	enum scmi_pinctrl_selector_type type;
+	u8 all;
+	enum scmi_pinctrl_conf_type *config_types;
+	u32 *config_values;
+};
+
+static void iter_pinctrl_conf_get_prepare_message(void *message,
+						  unsigned int desc_index,
+						  const void *priv)
+{
+	struct scmi_msg_conf_get *msg = message;
+	const struct scmi_conf_get_ipriv *p = priv;
+	u32 attributes;
+
+	attributes = FIELD_PREP(BIT(18), p->all) |
+		     FIELD_PREP(GENMASK(17, 16), p->type);
+
+	if (p->all)
+		attributes |= FIELD_PREP(GENMASK(15, 8), desc_index);
+	else
+		attributes |= FIELD_PREP(GENMASK(7, 0), p->config_types[0]);
+
+	msg->attributes = cpu_to_le32(attributes);
+	msg->identifier = cpu_to_le32(p->selector);
+}
+
+static int iter_pinctrl_conf_get_update_state(struct scmi_iterator_state *st,
+					      const void *response, void *priv)
+{
+	const struct scmi_resp_conf_get *r = response;
+	struct scmi_conf_get_ipriv *p = priv;
+
+	if (!p->all) {
+		st->num_returned = 1;
+		st->num_remaining = 0;
+	} else {
+		st->num_returned = le32_get_bits(r->num_configs, GENMASK(7, 0));
+		st->num_remaining = le32_get_bits(r->num_configs,
+						  GENMASK(31, 24));
+	}
+
+	return 0;
+}
+
+static int
+iter_pinctrl_conf_get_process_response(const struct scmi_protocol_handle *ph,
+				       const void *response,
+				       struct scmi_iterator_state *st,
+				       void *priv)
+{
+	const struct scmi_resp_conf_get *r = response;
+	struct scmi_conf_get_ipriv *p = priv;
+
+	if (!p->all) {
+		if (p->config_types[0] !=
+		    le32_get_bits(r->configs[st->loop_idx * 2], GENMASK(7, 0)))
+			return -EINVAL;
+	} else {
+		p->config_types[st->desc_index + st->loop_idx] =
+			le32_get_bits(r->configs[st->loop_idx * 2],
+				      GENMASK(7, 0));
+	}
+
+	p->config_values[st->desc_index + st->loop_idx] =
+		le32_to_cpu(r->configs[st->loop_idx * 2 + 1]);
+
+	return 0;
+}
+
+static int
+scmi_pinctrl_config_get(const struct scmi_protocol_handle *ph, u32 selector,
+			enum scmi_pinctrl_selector_type type,
+			enum scmi_pinctrl_conf_type config_type,
+			u32 *config_value)
+{
+	int ret;
+	void *iter;
+	struct scmi_iterator_ops ops = {
+		.prepare_message = iter_pinctrl_conf_get_prepare_message,
+		.update_state = iter_pinctrl_conf_get_update_state,
+		.process_response = iter_pinctrl_conf_get_process_response,
+	};
+	struct scmi_conf_get_ipriv ipriv = {
+		.selector = selector,
+		.type = type,
+		.all = 0,
+		.config_types = &config_type,
+		.config_values = config_value,
+	};
+
+	if (!config_value || type == FUNCTION_TYPE)
+		return -EINVAL;
+
+	ret = scmi_pinctrl_validate_id(ph, selector, type);
+	if (ret)
+		return ret;
+
+	iter = ph->hops->iter_response_init(ph, &ops, 1, PINCTRL_CONFIG_GET,
+					    sizeof(struct scmi_msg_conf_get),
+					    &ipriv);
+
+	if (IS_ERR(iter))
+		return PTR_ERR(iter);
+
+	return ph->hops->iter_response_run(iter);
+}
+
+static int
+scmi_pinctrl_config_set(const struct scmi_protocol_handle *ph, u32 selector,
+			enum scmi_pinctrl_selector_type type,
+			unsigned int nr_configs,
+			enum scmi_pinctrl_conf_type *config_type,
+			u32 *config_value)
+{
+	struct scmi_xfer *t;
+	struct scmi_msg_conf_set *tx;
+	u32 attributes;
+	int ret, i;
+	unsigned int configs_in_chunk, conf_num = 0;
+	unsigned int chunk;
+	int max_msg_size = ph->hops->get_max_msg_size(ph);
+
+	if (!config_type || !config_value || type == FUNCTION_TYPE)
+		return -EINVAL;
+
+	ret = scmi_pinctrl_validate_id(ph, selector, type);
+	if (ret)
+		return ret;
+
+	configs_in_chunk = (max_msg_size - sizeof(*tx)) / (sizeof(__le32) * 2);
+	while (conf_num < nr_configs) {
+		chunk = (nr_configs - conf_num > configs_in_chunk) ?
+			configs_in_chunk : nr_configs - conf_num;
+
+		ret = ph->xops->xfer_get_init(ph, PINCTRL_CONFIG_SET,
+					      sizeof(*tx) +
+					      chunk * 2 * sizeof(__le32),
+					      0, &t);
+		if (ret)
+			return ret;
+
+		tx = t->tx.buf;
+		tx->identifier = cpu_to_le32(selector);
+		attributes = FIELD_PREP(GENMASK(1, 0), type) |
+			FIELD_PREP(GENMASK(9, 2), chunk);
+		tx->attributes = cpu_to_le32(attributes);
+
+		for (i = 0; i < chunk; i++) {
+			tx->configs[i * 2] =
+				cpu_to_le32(config_type[conf_num + i]);
+			tx->configs[i * 2 + 1] =
+				cpu_to_le32(config_value[conf_num + i]);
+		}
+
+		ret = ph->xops->do_xfer(ph, t);
+
+		ph->xops->xfer_put(ph, t);
+
+		if (ret)
+			break;
+
+		conf_num += chunk;
+	}
+
+	return ret;
+}
+
+static int scmi_pinctrl_function_select(const struct scmi_protocol_handle *ph,
+					u32 identifier,
+					enum scmi_pinctrl_selector_type type,
+					u32 function_id)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_func_set *tx;
+
+	if (type == FUNCTION_TYPE)
+		return -EINVAL;
+
+	ret = scmi_pinctrl_validate_id(ph, identifier, type);
+	if (ret)
+		return ret;
+
+	ret = ph->xops->xfer_get_init(ph, PINCTRL_FUNCTION_SELECT, sizeof(*tx),
+				      0, &t);
+	if (ret)
+		return ret;
+
+	tx = t->tx.buf;
+	tx->identifier = cpu_to_le32(identifier);
+	tx->function_id = cpu_to_le32(function_id);
+	tx->flags = cpu_to_le32(type);
+
+	ret = ph->xops->do_xfer(ph, t);
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_pinctrl_request(const struct scmi_protocol_handle *ph,
+				u32 identifier,
+				enum scmi_pinctrl_selector_type type)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_request *tx;
+
+	if (type == FUNCTION_TYPE)
+		return -EINVAL;
+
+	ret = scmi_pinctrl_validate_id(ph, identifier, type);
+	if (ret)
+		return ret;
+
+	ret = ph->xops->xfer_get_init(ph, PINCTRL_REQUEST, sizeof(*tx), 0, &t);
+
+	tx = t->tx.buf;
+	tx->identifier = cpu_to_le32(identifier);
+	tx->flags = cpu_to_le32(type);
+
+	ret = ph->xops->do_xfer(ph, t);
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_pinctrl_pin_request(const struct scmi_protocol_handle *ph,
+				    u32 pin)
+{
+	return scmi_pinctrl_request(ph, pin, PIN_TYPE);
+}
+
+static int scmi_pinctrl_free(const struct scmi_protocol_handle *ph,
+			     u32 identifier,
+			     enum scmi_pinctrl_selector_type type)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_request *tx;
+
+	if (type == FUNCTION_TYPE)
+		return -EINVAL;
+
+	ret = scmi_pinctrl_validate_id(ph, identifier, type);
+	if (ret)
+		return ret;
+
+	ret = ph->xops->xfer_get_init(ph, PINCTRL_RELEASE, sizeof(*tx), 0, &t);
+
+	tx = t->tx.buf;
+	tx->identifier = cpu_to_le32(identifier);
+	tx->flags = cpu_to_le32(type);
+
+	ret = ph->xops->do_xfer(ph, t);
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_pinctrl_pin_free(const struct scmi_protocol_handle *ph, u32 pin)
+{
+	return scmi_pinctrl_free(ph, pin, PIN_TYPE);
+}
+
+static int scmi_pinctrl_get_group_info(const struct scmi_protocol_handle *ph,
+				       u32 selector,
+				       struct scmi_group_info *group)
+{
+	int ret;
+
+	if (!group)
+		return -EINVAL;
+
+	ret = scmi_pinctrl_attributes(ph, GROUP_TYPE, selector,
+				      group->name,
+				      &group->nr_pins);
+	if (ret)
+		return ret;
+
+	if (!group->nr_pins) {
+		dev_err(ph->dev, "Group %d has 0 elements", selector);
+		return -ENODATA;
+	}
+
+	group->group_pins = kmalloc_array(group->nr_pins,
+					  sizeof(*group->group_pins),
+					  GFP_KERNEL);
+	if (!group->group_pins)
+		return -ENOMEM;
+
+	ret = scmi_pinctrl_list_associations(ph, selector, GROUP_TYPE,
+					     group->nr_pins, group->group_pins);
+	if (ret) {
+		kfree(group->group_pins);
+		return ret;
+	}
+
+	group->present = true;
+	return 0;
+}
+
+static int scmi_pinctrl_get_group_name(const struct scmi_protocol_handle *ph,
+				       u32 selector, const char **name)
+{
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+	if (!name)
+		return -EINVAL;
+
+	if (selector >= pi->nr_groups)
+		return -EINVAL;
+
+	if (!pi->groups[selector].present) {
+		int ret;
+
+		ret = scmi_pinctrl_get_group_info(ph, selector,
+						  &pi->groups[selector]);
+		if (ret)
+			return ret;
+	}
+
+	*name = pi->groups[selector].name;
+
+	return 0;
+}
+
+static int scmi_pinctrl_group_pins_get(const struct scmi_protocol_handle *ph,
+				       u32 selector, const unsigned int **pins,
+				       unsigned int *nr_pins)
+{
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+	if (!pins || !nr_pins)
+		return -EINVAL;
+
+	if (selector >= pi->nr_groups)
+		return -EINVAL;
+
+	if (!pi->groups[selector].present) {
+		int ret;
+
+		ret = scmi_pinctrl_get_group_info(ph, selector,
+						  &pi->groups[selector]);
+		if (ret)
+			return ret;
+	}
+
+	*pins = pi->groups[selector].group_pins;
+	*nr_pins = pi->groups[selector].nr_pins;
+
+	return 0;
+}
+
+static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph,
+					  u32 selector,
+					  struct scmi_function_info *func)
+{
+	int ret;
+
+	if (!func)
+		return -EINVAL;
+
+	ret = scmi_pinctrl_attributes(ph, FUNCTION_TYPE, selector,
+				      func->name,
+				      &func->nr_groups);
+	if (ret)
+		return ret;
+
+	if (!func->nr_groups) {
+		dev_err(ph->dev, "Function %d has 0 elements", selector);
+		return -ENODATA;
+	}
+
+	func->groups = kmalloc_array(func->nr_groups, sizeof(*func->groups),
+				     GFP_KERNEL);
+	if (!func->groups)
+		return -ENOMEM;
+
+	ret = scmi_pinctrl_list_associations(ph, selector, FUNCTION_TYPE,
+					     func->nr_groups, func->groups);
+	if (ret) {
+		kfree(func->groups);
+		return ret;
+	}
+
+	func->present = true;
+	return 0;
+}
+
+static int scmi_pinctrl_get_function_name(const struct scmi_protocol_handle *ph,
+					  u32 selector, const char **name)
+{
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+	if (!name)
+		return -EINVAL;
+
+	if (selector >= pi->nr_functions)
+		return -EINVAL;
+
+	if (!pi->functions[selector].present) {
+		int ret;
+
+		ret = scmi_pinctrl_get_function_info(ph, selector,
+						     &pi->functions[selector]);
+		if (ret)
+			return ret;
+	}
+
+	*name = pi->functions[selector].name;
+	return 0;
+}
+
+static int
+scmi_pinctrl_function_groups_get(const struct scmi_protocol_handle *ph,
+				 u32 selector, unsigned int *nr_groups,
+				 const unsigned int **groups)
+{
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+	if (!groups || !nr_groups)
+		return -EINVAL;
+
+	if (selector >= pi->nr_functions)
+		return -EINVAL;
+
+	if (!pi->functions[selector].present) {
+		int ret;
+
+		ret = scmi_pinctrl_get_function_info(ph, selector,
+						     &pi->functions[selector]);
+		if (ret)
+			return ret;
+	}
+
+	*groups = pi->functions[selector].groups;
+	*nr_groups = pi->functions[selector].nr_groups;
+
+	return 0;
+}
+
+static int scmi_pinctrl_mux_set(const struct scmi_protocol_handle *ph,
+				u32 selector, u32 group)
+{
+	return scmi_pinctrl_function_select(ph, group, GROUP_TYPE,
+					    selector);
+}
+
+static int scmi_pinctrl_get_pin_info(const struct scmi_protocol_handle *ph,
+				     u32 selector, struct scmi_pin_info *pin)
+{
+	int ret;
+
+	if (!pin)
+		return -EINVAL;
+
+	ret = scmi_pinctrl_attributes(ph, PIN_TYPE, selector,
+				      pin->name, NULL);
+	if (ret)
+		return ret;
+
+	pin->present = true;
+	return 0;
+}
+
+static int scmi_pinctrl_get_pin_name(const struct scmi_protocol_handle *ph,
+				     u32 selector, const char **name)
+{
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+	if (!name)
+		return -EINVAL;
+
+	if (selector >= pi->nr_pins)
+		return -EINVAL;
+
+	if (!pi->pins[selector].present) {
+		int ret;
+
+		ret = scmi_pinctrl_get_pin_info(ph, selector,
+						&pi->pins[selector]);
+		if (ret)
+			return ret;
+	}
+
+	*name = pi->pins[selector].name;
+
+	return 0;
+}
+
+static int scmi_pinctrl_name_get(const struct scmi_protocol_handle *ph,
+				 u32 selector,
+				 enum scmi_pinctrl_selector_type type,
+				 const char **name)
+{
+	switch (type) {
+	case PIN_TYPE:
+		return scmi_pinctrl_get_pin_name(ph, selector, name);
+	case GROUP_TYPE:
+		return scmi_pinctrl_get_group_name(ph, selector, name);
+	case FUNCTION_TYPE:
+		return scmi_pinctrl_get_function_name(ph, selector, name);
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct scmi_pinctrl_proto_ops pinctrl_proto_ops = {
+	.count_get = scmi_pinctrl_count_get,
+	.name_get = scmi_pinctrl_name_get,
+	.group_pins_get = scmi_pinctrl_group_pins_get,
+	.function_groups_get = scmi_pinctrl_function_groups_get,
+	.mux_set = scmi_pinctrl_mux_set,
+	.config_get = scmi_pinctrl_config_get,
+	.config_set = scmi_pinctrl_config_set,
+	.pin_request = scmi_pinctrl_pin_request,
+	.pin_free = scmi_pinctrl_pin_free,
+};
+
+static int scmi_pinctrl_protocol_init(const struct scmi_protocol_handle *ph)
+{
+	int ret;
+	u32 version;
+	struct scmi_pinctrl_info *pinfo;
+
+	ret = ph->xops->version_get(ph, &version);
+	if (ret)
+		return ret;
+
+	dev_dbg(ph->dev, "Pinctrl Version %d.%d\n",
+		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
+
+	pinfo = devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL);
+	if (!pinfo)
+		return -ENOMEM;
+
+	ret = scmi_pinctrl_attributes_get(ph, pinfo);
+	if (ret)
+		return ret;
+
+	pinfo->pins = devm_kcalloc(ph->dev, pinfo->nr_pins,
+				   sizeof(*pinfo->pins),
+				   GFP_KERNEL);
+	if (!pinfo->pins)
+		return -ENOMEM;
+
+	pinfo->groups = devm_kcalloc(ph->dev, pinfo->nr_groups,
+				     sizeof(*pinfo->groups),
+				     GFP_KERNEL);
+	if (!pinfo->groups)
+		return -ENOMEM;
+
+	pinfo->functions = devm_kcalloc(ph->dev, pinfo->nr_functions,
+					sizeof(*pinfo->functions),
+					GFP_KERNEL);
+	if (!pinfo->functions)
+		return -ENOMEM;
+
+	pinfo->version = version;
+
+	return ph->set_priv(ph, pinfo, version);
+}
+
+static int scmi_pinctrl_protocol_deinit(const struct scmi_protocol_handle *ph)
+{
+	int i;
+	struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+	for (i = 0; i < pi->nr_groups; i++) {
+		if (pi->groups[i].present) {
+			kfree(pi->groups[i].group_pins);
+			pi->groups[i].present = false;
+		}
+	}
+
+	for (i = 0; i < pi->nr_functions; i++) {
+		if (pi->functions[i].present) {
+			kfree(pi->functions[i].groups);
+			pi->functions[i].present = false;
+		}
+	}
+
+	return 0;
+}
+
+static const struct scmi_protocol scmi_pinctrl = {
+	.id = SCMI_PROTOCOL_PINCTRL,
+	.owner = THIS_MODULE,
+	.instance_init = &scmi_pinctrl_protocol_init,
+	.instance_deinit = &scmi_pinctrl_protocol_deinit,
+	.ops = &pinctrl_proto_ops,
+	.supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION,
+};
+
+DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(pinctrl, scmi_pinctrl)
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index 9c8edb1aa901..f1cde7752187 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -353,6 +353,7 @@ void __exit scmi_##name##_unregister(void)			\
 DECLARE_SCMI_REGISTER_UNREGISTER(base);
 DECLARE_SCMI_REGISTER_UNREGISTER(clock);
 DECLARE_SCMI_REGISTER_UNREGISTER(perf);
+DECLARE_SCMI_REGISTER_UNREGISTER(pinctrl);
 DECLARE_SCMI_REGISTER_UNREGISTER(power);
 DECLARE_SCMI_REGISTER_UNREGISTER(reset);
 DECLARE_SCMI_REGISTER_UNREGISTER(sensors);
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 2ee94ff0320c..3fcc3ad15263 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -729,6 +729,80 @@ struct scmi_powercap_proto_ops {
 					  u32 *power_thresh_high);
 };
 
+enum scmi_pinctrl_selector_type {
+	PIN_TYPE = 0,
+	GROUP_TYPE,
+	FUNCTION_TYPE,
+};
+
+enum scmi_pinctrl_conf_type {
+	SCMI_PIN_NONE = 0x0,
+	SCMI_PIN_BIAS_BUS_HOLD = 0x1,
+	SCMI_PIN_BIAS_DISABLE = 0x2,
+	SCMI_PIN_BIAS_HIGH_IMPEDANCE = 0x3,
+	SCMI_PIN_BIAS_PULL_UP = 0x4,
+	SCMI_PIN_BIAS_PULL_DEFAULT = 0x5,
+	SCMI_PIN_BIAS_PULL_DOWN = 0x6,
+	SCMI_PIN_DRIVE_OPEN_DRAIN = 0x7,
+	SCMI_PIN_DRIVE_OPEN_SOURCE = 0x8,
+	SCMI_PIN_DRIVE_PUSH_PULL = 0x9,
+	SCMI_PIN_DRIVE_STRENGTH = 0xA,
+	SCMI_PIN_INPUT_DEBOUNCE = 0xB,
+	SCMI_PIN_INPUT_MODE = 0xC,
+	SCMI_PIN_PULL_MODE = 0xD,
+	SCMI_PIN_INPUT_VALUE = 0xE,
+	SCMI_PIN_INPUT_SCHMITT = 0xF,
+	SCMI_PIN_LOW_POWER_MODE = 0x10,
+	SCMI_PIN_OUTPUT_MODE = 0x11,
+	SCMI_PIN_OUTPUT_VALUE = 0x12,
+	SCMI_PIN_POWER_SOURCE = 0x13,
+	SCMI_PIN_SLEW_RATE = 0x20,
+	SCMI_PIN_OEM_START = 0xC0,
+	SCMI_PIN_OEM_END = 0xFF,
+};
+
+/**
+ * struct scmi_pinctrl_proto_ops - represents the various operations provided
+ * by SCMI Pinctrl Protocol
+ *
+ * @count_get: returns count of the registered elements in given type
+ * @name_get: returns name by index of given type
+ * @group_pins_get: returns the set of pins, assigned to the specified group
+ * @function_groups_get: returns the set of groups, assigned to the specified
+ *	function
+ * @mux_set: set muxing function for groups of pins
+ * @config_get: returns configuration parameter for pin or group
+ * @config_set: sets the configuration parameter for pin or group
+ * @pin_request: aquire pin before selecting mux setting
+ * @pin_free: frees pin, acquired by request_pin call
+ */
+struct scmi_pinctrl_proto_ops {
+	int (*count_get)(const struct scmi_protocol_handle *ph,
+			 enum scmi_pinctrl_selector_type type);
+	int (*name_get)(const struct scmi_protocol_handle *ph, u32 selector,
+			enum scmi_pinctrl_selector_type type,
+			const char **name);
+	int (*group_pins_get)(const struct scmi_protocol_handle *ph,
+			      u32 selector, const unsigned int **pins,
+			      unsigned int *nr_pins);
+	int (*function_groups_get)(const struct scmi_protocol_handle *ph,
+				   u32 selector, unsigned int *nr_groups,
+				   const unsigned int **groups);
+	int (*mux_set)(const struct scmi_protocol_handle *ph, u32 selector,
+		       u32 group);
+	int (*config_get)(const struct scmi_protocol_handle *ph, u32 selector,
+			  enum scmi_pinctrl_selector_type type,
+			  enum scmi_pinctrl_conf_type config_type,
+			  u32 *config_value);
+	int (*config_set)(const struct scmi_protocol_handle *ph, u32 selector,
+			  enum scmi_pinctrl_selector_type type,
+			  unsigned int nr_configs,
+			  enum scmi_pinctrl_conf_type *config_type,
+			  u32 *config_value);
+	int (*pin_request)(const struct scmi_protocol_handle *ph, u32 pin);
+	int (*pin_free)(const struct scmi_protocol_handle *ph, u32 pin);
+};
+
 /**
  * struct scmi_notify_ops  - represents notifications' operations provided by
  * SCMI core
@@ -836,6 +910,7 @@ enum scmi_std_protocol {
 	SCMI_PROTOCOL_RESET = 0x16,
 	SCMI_PROTOCOL_VOLTAGE = 0x17,
 	SCMI_PROTOCOL_POWERCAP = 0x18,
+	SCMI_PROTOCOL_PINCTRL = 0x19,
 };
 
 enum scmi_system_events {

-- 
2.37.1



From peng.fan at oss.nxp.com  Thu Feb 22 17:16:41 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 23 Feb 2024 09:16:41 +0800
Subject: [PATCH v4 4/4] pinctrl: Implementation of the generic scmi-pinctrl
 driver
In-Reply-To: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>
References: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>
Message-ID: <20240223-pinctrl-scmi-v4-4-10eb5a379274@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

scmi-pinctrl driver implements pinctrl driver interface and using
SCMI protocol to redirect messages from pinctrl subsystem SDK to
SCMI platform firmware, which does the changes in HW.

Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>
Tested-by: Cristian Marussi <cristian.marussi at arm.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Co-developed-by: Oleksii Moisieiev <oleksii_moisieiev at epam.com>
Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev at epam.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 MAINTAINERS                    |   1 +
 drivers/pinctrl/Kconfig        |  11 +
 drivers/pinctrl/Makefile       |   1 +
 drivers/pinctrl/pinctrl-scmi.c | 593 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 606 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c042ca394893..851216ba59b0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21447,6 +21447,7 @@ F:	drivers/clk/clk-sc[mp]i.c
 F:	drivers/cpufreq/sc[mp]i-cpufreq.c
 F:	drivers/firmware/arm_scmi/
 F:	drivers/firmware/arm_scpi.c
+F:	drivers/pinctrl/pinctrl-scmi.c
 F:	drivers/pmdomain/arm/
 F:	drivers/powercap/arm_scmi_powercap.c
 F:	drivers/regulator/scmi-regulator.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8163a5983166..27b26e428f60 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -432,6 +432,17 @@ config PINCTRL_ROCKCHIP
 	help
           This support pinctrl and GPIO driver for Rockchip SoCs.
 
+config PINCTRL_SCMI
+	tristate "Pinctrl driver using SCMI protocol interface"
+	depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
+	select PINMUX
+	select GENERIC_PINCONF
+	help
+	  This driver provides support for pinctrl which is controlled
+	  by firmware that implements the SCMI interface.
+	  It uses SCMI Message Protocol to interact with the
+	  firmware providing all the pinctrl controls.
+
 config PINCTRL_SINGLE
 	tristate "One-register-per-pin type device tree based pinctrl driver"
 	depends on OF
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 1071f301cc70..ba755ed2d46c 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_PINCTRL_PIC32)	+= pinctrl-pic32.o
 obj-$(CONFIG_PINCTRL_PISTACHIO)	+= pinctrl-pistachio.o
 obj-$(CONFIG_PINCTRL_RK805)	+= pinctrl-rk805.o
 obj-$(CONFIG_PINCTRL_ROCKCHIP)	+= pinctrl-rockchip.o
+obj-$(CONFIG_PINCTRL_SCMI)	+= pinctrl-scmi.o
 obj-$(CONFIG_PINCTRL_SINGLE)	+= pinctrl-single.o
 obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
 obj-$(CONFIG_PINCTRL_STMFX) 	+= pinctrl-stmfx.o
diff --git a/drivers/pinctrl/pinctrl-scmi.c b/drivers/pinctrl/pinctrl-scmi.c
new file mode 100644
index 000000000000..f2fef3fb85ae
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-scmi.c
@@ -0,0 +1,593 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Power Interface (SCMI) Protocol based pinctrl driver
+ *
+ * Copyright (C) 2024 EPAM
+ * Copyright 2024 NXP
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/scmi_protocol.h>
+#include <linux/slab.h>
+
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-utils.h"
+#include "core.h"
+#include "pinconf.h"
+
+#define DRV_NAME "scmi-pinctrl"
+
+/* Define num configs, if not large than 4 use stack, else use kcalloc */
+#define SCMI_NUM_CONFIGS	4
+
+static const struct scmi_pinctrl_proto_ops *pinctrl_ops;
+
+struct scmi_pinctrl_funcs {
+	unsigned int num_groups;
+	const char **groups;
+};
+
+struct scmi_pinctrl {
+	struct device *dev;
+	struct scmi_protocol_handle *ph;
+	struct pinctrl_dev *pctldev;
+	struct pinctrl_desc pctl_desc;
+	struct scmi_pinctrl_funcs *functions;
+	unsigned int nr_functions;
+	char **groups;
+	unsigned int nr_groups;
+	struct pinctrl_pin_desc *pins;
+	unsigned int nr_pins;
+};
+
+static int pinctrl_scmi_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	return pinctrl_ops->count_get(pmx->ph, GROUP_TYPE);
+}
+
+static const char *pinctrl_scmi_get_group_name(struct pinctrl_dev *pctldev,
+					       unsigned int selector)
+{
+	int ret;
+	const char *name;
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	ret = pinctrl_ops->name_get(pmx->ph, selector, GROUP_TYPE, &name);
+	if (ret) {
+		dev_err(pmx->dev, "get name failed with err %d", ret);
+		return NULL;
+	}
+
+	return name;
+}
+
+static int pinctrl_scmi_get_group_pins(struct pinctrl_dev *pctldev,
+				       unsigned int selector,
+				       const unsigned int **pins,
+				       unsigned int *num_pins)
+{
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	return pinctrl_ops->group_pins_get(pmx->ph, selector, pins, num_pins);
+}
+
+static const struct pinctrl_ops pinctrl_scmi_pinctrl_ops = {
+	.get_groups_count = pinctrl_scmi_get_groups_count,
+	.get_group_name = pinctrl_scmi_get_group_name,
+	.get_group_pins = pinctrl_scmi_get_group_pins,
+#ifdef CONFIG_OF
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+	.dt_free_map = pinconf_generic_dt_free_map,
+#endif
+};
+
+static int pinctrl_scmi_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	return pinctrl_ops->count_get(pmx->ph, FUNCTION_TYPE);
+}
+
+static const char *pinctrl_scmi_get_function_name(struct pinctrl_dev *pctldev,
+						  unsigned int selector)
+{
+	int ret;
+	const char *name;
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	ret = pinctrl_ops->name_get(pmx->ph, selector, FUNCTION_TYPE, &name);
+	if (ret) {
+		dev_err(pmx->dev, "get name failed with err %d", ret);
+		return NULL;
+	}
+
+	return name;
+}
+
+static int pinctrl_scmi_get_function_groups(struct pinctrl_dev *pctldev,
+					    unsigned int selector,
+					    const char * const **groups,
+					    unsigned int * const num_groups)
+{
+	const unsigned int *group_ids;
+	int ret, i;
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	if (!groups || !num_groups)
+		return -EINVAL;
+
+	if (selector < pmx->nr_functions &&
+	    pmx->functions[selector].num_groups) {
+		*groups = (const char * const *)pmx->functions[selector].groups;
+		*num_groups = pmx->functions[selector].num_groups;
+		return 0;
+	}
+
+	ret = pinctrl_ops->function_groups_get(pmx->ph, selector,
+					       &pmx->functions[selector].num_groups,
+					       &group_ids);
+	if (ret) {
+		dev_err(pmx->dev, "Unable to get function groups, err %d", ret);
+		return ret;
+	}
+
+	*num_groups = pmx->functions[selector].num_groups;
+	if (!*num_groups)
+		return -EINVAL;
+
+	pmx->functions[selector].groups =
+		devm_kcalloc(pmx->dev, *num_groups,
+			     sizeof(*pmx->functions[selector].groups),
+			     GFP_KERNEL);
+	if (!pmx->functions[selector].groups)
+		return -ENOMEM;
+
+	for (i = 0; i < *num_groups; i++) {
+		pmx->functions[selector].groups[i] =
+			pinctrl_scmi_get_group_name(pmx->pctldev,
+						    group_ids[i]);
+		if (!pmx->functions[selector].groups[i]) {
+			ret = -ENOMEM;
+			goto err_free;
+		}
+	}
+
+	*groups = (const char * const *)pmx->functions[selector].groups;
+
+	return 0;
+
+err_free:
+	devm_kfree(pmx->dev, pmx->functions[selector].groups);
+
+	return ret;
+}
+
+static int pinctrl_scmi_func_set_mux(struct pinctrl_dev *pctldev,
+				     unsigned int selector, unsigned int group)
+{
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	return pinctrl_ops->mux_set(pmx->ph, selector, group);
+}
+
+static int pinctrl_scmi_request(struct pinctrl_dev *pctldev,
+				unsigned int offset)
+{
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	return pinctrl_ops->pin_request(pmx->ph, offset);
+}
+
+static int pinctrl_scmi_free(struct pinctrl_dev *pctldev, unsigned int offset)
+{
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	return pinctrl_ops->pin_free(pmx->ph, offset);
+}
+
+static const struct pinmux_ops pinctrl_scmi_pinmux_ops = {
+	.request = pinctrl_scmi_request,
+	.free = pinctrl_scmi_free,
+	.get_functions_count = pinctrl_scmi_get_functions_count,
+	.get_function_name = pinctrl_scmi_get_function_name,
+	.get_function_groups = pinctrl_scmi_get_function_groups,
+	.set_mux = pinctrl_scmi_func_set_mux,
+};
+
+static int pinctrl_scmi_map_pinconf_type(enum pin_config_param param,
+					 enum scmi_pinctrl_conf_type *type)
+{
+	u32 arg = param;
+
+	switch (arg) {
+	case PIN_CONFIG_BIAS_BUS_HOLD:
+		*type = SCMI_PIN_BIAS_BUS_HOLD;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		*type = SCMI_PIN_BIAS_DISABLE;
+		break;
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+		*type = SCMI_PIN_BIAS_HIGH_IMPEDANCE;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		*type = SCMI_PIN_BIAS_PULL_DOWN;
+		break;
+	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+		*type = SCMI_PIN_BIAS_PULL_DEFAULT;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		*type = SCMI_PIN_BIAS_PULL_UP;
+		break;
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		*type = SCMI_PIN_DRIVE_OPEN_DRAIN;
+		break;
+	case PIN_CONFIG_DRIVE_OPEN_SOURCE:
+		*type = SCMI_PIN_DRIVE_OPEN_SOURCE;
+		break;
+	case PIN_CONFIG_DRIVE_PUSH_PULL:
+		*type = SCMI_PIN_DRIVE_PUSH_PULL;
+		break;
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		*type = SCMI_PIN_DRIVE_STRENGTH;
+		break;
+	case PIN_CONFIG_DRIVE_STRENGTH_UA:
+		*type = SCMI_PIN_DRIVE_STRENGTH;
+		break;
+	case PIN_CONFIG_INPUT_DEBOUNCE:
+		*type = SCMI_PIN_INPUT_DEBOUNCE;
+		break;
+	case PIN_CONFIG_INPUT_ENABLE:
+		*type = SCMI_PIN_INPUT_MODE;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT:
+		*type = SCMI_PIN_INPUT_SCHMITT;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		*type = SCMI_PIN_INPUT_MODE;
+		break;
+	case PIN_CONFIG_MODE_LOW_POWER:
+		*type = SCMI_PIN_LOW_POWER_MODE;
+		break;
+	case PIN_CONFIG_OUTPUT:
+		*type = SCMI_PIN_OUTPUT_VALUE;
+		break;
+	case PIN_CONFIG_OUTPUT_ENABLE:
+		*type = SCMI_PIN_OUTPUT_MODE;
+		break;
+	case PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS:
+		*type = SCMI_PIN_OUTPUT_VALUE;
+		break;
+	case PIN_CONFIG_POWER_SOURCE:
+		*type = SCMI_PIN_POWER_SOURCE;
+		break;
+	case PIN_CONFIG_SLEW_RATE:
+		*type = SCMI_PIN_SLEW_RATE;
+		break;
+	case SCMI_PIN_OEM_START ... SCMI_PIN_OEM_END:
+		*type = arg;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int pinctrl_scmi_pinconf_get(struct pinctrl_dev *pctldev,
+				    unsigned int _pin, unsigned long *config)
+{
+	int ret;
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param config_type;
+	enum scmi_pinctrl_conf_type type;
+	u32 config_value;
+
+	if (!config)
+		return -EINVAL;
+
+	config_type = pinconf_to_config_param(*config);
+
+	ret = pinctrl_scmi_map_pinconf_type(config_type, &type);
+	if (ret) {
+		dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
+		return ret;
+	}
+
+	ret = pinctrl_ops->config_get(pmx->ph, _pin, PIN_TYPE, type,
+				      &config_value);
+	if (ret)
+		return ret;
+
+	*config = pinconf_to_config_packed(config_type, config_value);
+
+	return 0;
+}
+
+static int
+pinctrl_scmi_alloc_configs(struct pinctrl_dev *pctldev, u32 num_configs,
+			   u32 **p_config_value,
+			   enum scmi_pinctrl_conf_type **p_config_type)
+{
+	if (num_configs <= SCMI_NUM_CONFIGS)
+		return 0;
+
+	*p_config_value = kcalloc(num_configs, sizeof(u32), GFP_KERNEL);
+	*p_config_type = kcalloc(num_configs,
+				 sizeof(enum scmi_pinctrl_conf_type),
+				 GFP_KERNEL);
+
+	if (!*p_config_value || !*p_config_type) {
+		kfree(*p_config_value);
+		kfree(*p_config_type);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void
+pinctrl_scmi_free_configs(struct pinctrl_dev *pctldev, u32 num_configs,
+			  u32 **p_config_value,
+			  enum scmi_pinctrl_conf_type **p_config_type)
+{
+	if (num_configs <= SCMI_NUM_CONFIGS)
+		return;
+
+	kfree(*p_config_value);
+	kfree(*p_config_type);
+}
+
+static int pinctrl_scmi_pinconf_set(struct pinctrl_dev *pctldev,
+				    unsigned int _pin,
+				    unsigned long *configs,
+				    unsigned int num_configs)
+{
+	int i, ret;
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+	enum scmi_pinctrl_conf_type config_type[SCMI_NUM_CONFIGS];
+	u32 config_value[SCMI_NUM_CONFIGS];
+	enum scmi_pinctrl_conf_type *p_config_type = config_type;
+	u32 *p_config_value = config_value;
+	enum pin_config_param param;
+
+	if (!configs || !num_configs)
+		return -EINVAL;
+
+	ret = pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type,
+					 &p_config_value);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		ret = pinctrl_scmi_map_pinconf_type(param, &p_config_type[i]);
+		if (ret) {
+			dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
+			goto free_config;
+		}
+		p_config_value[i] = pinconf_to_config_argument(configs[i]);
+	}
+
+	ret = pinctrl_ops->config_set(pmx->ph, _pin, PIN_TYPE, num_configs,
+				      p_config_type,  p_config_value);
+	if (ret)
+		dev_err(pmx->dev, "Error parsing config %d\n", ret);
+
+free_config:
+	pinctrl_scmi_free_configs(pctldev, num_configs, &p_config_type,
+				  &p_config_value);
+	return ret;
+}
+
+static int pinctrl_scmi_pinconf_group_set(struct pinctrl_dev *pctldev,
+					  unsigned int group,
+					  unsigned long *configs,
+					  unsigned int num_configs)
+{
+	int i, ret;
+	struct scmi_pinctrl *pmx =  pinctrl_dev_get_drvdata(pctldev);
+	enum scmi_pinctrl_conf_type config_type[SCMI_NUM_CONFIGS];
+	u32 config_value[SCMI_NUM_CONFIGS];
+	enum scmi_pinctrl_conf_type *p_config_type = config_type;
+	u32 *p_config_value = config_value;
+	enum pin_config_param param;
+
+	if (!configs || !num_configs)
+		return -EINVAL;
+
+	ret = pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type,
+					 &p_config_value);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		ret = pinctrl_scmi_map_pinconf_type(param,
+						    &p_config_type[i]);
+		if (ret) {
+			dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
+			goto free_config;
+		}
+
+		p_config_value[i] = pinconf_to_config_argument(configs[i]);
+	}
+
+	ret = pinctrl_ops->config_set(pmx->ph, group, GROUP_TYPE, num_configs,
+				      p_config_type, p_config_value);
+	if (ret)
+		dev_err(pmx->dev, "Error parsing config %d", ret);
+
+free_config:
+	pinctrl_scmi_free_configs(pctldev, num_configs, &p_config_type,
+				  &p_config_value);
+	return ret;
+};
+
+static int pinctrl_scmi_pinconf_group_get(struct pinctrl_dev *pctldev,
+					  unsigned int group,
+					  unsigned long *config)
+{
+	int ret;
+	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param config_type;
+	enum scmi_pinctrl_conf_type type;
+	u32 config_value;
+
+	if (!config)
+		return -EINVAL;
+
+	config_type = pinconf_to_config_param(*config);
+	ret = pinctrl_scmi_map_pinconf_type(config_type, &type);
+	if (ret) {
+		dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
+		return ret;
+	}
+
+	ret = pinctrl_ops->config_get(pmx->ph, group, GROUP_TYPE, type,
+				      &config_value);
+	if (ret)
+		return ret;
+
+	*config = pinconf_to_config_packed(config_type, config_value);
+
+	return 0;
+}
+
+static const struct pinconf_ops pinctrl_scmi_pinconf_ops = {
+	.is_generic = true,
+	.pin_config_get = pinctrl_scmi_pinconf_get,
+	.pin_config_set = pinctrl_scmi_pinconf_set,
+	.pin_config_group_set = pinctrl_scmi_pinconf_group_set,
+	.pin_config_group_get = pinctrl_scmi_pinconf_group_get,
+	.pin_config_config_dbg_show = pinconf_generic_dump_config,
+};
+
+static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx,
+				 unsigned int *nr_pins,
+				 const struct pinctrl_pin_desc **pins)
+{
+	int ret, i;
+
+	if (!pins || !nr_pins)
+		return -EINVAL;
+
+	if (pmx->nr_pins) {
+		*pins = pmx->pins;
+		*nr_pins = pmx->nr_pins;
+		return 0;
+	}
+
+	*nr_pins = pinctrl_ops->count_get(pmx->ph, PIN_TYPE);
+
+	pmx->nr_pins = *nr_pins;
+	pmx->pins = devm_kmalloc_array(pmx->dev, *nr_pins, sizeof(*pmx->pins),
+				       GFP_KERNEL);
+	if (!pmx->pins)
+		return -ENOMEM;
+
+	for (i = 0; i < *nr_pins; i++) {
+		pmx->pins[i].number = i;
+		ret = pinctrl_ops->name_get(pmx->ph, i, PIN_TYPE,
+					    &pmx->pins[i].name);
+		if (ret) {
+			dev_err(pmx->dev, "Can't get name for pin %d: rc %d", i, ret);
+			pmx->nr_pins = 0;
+			return ret;
+		}
+	}
+
+	*pins = pmx->pins;
+	dev_dbg(pmx->dev, "got pins %d", *nr_pins);
+
+	return 0;
+}
+
+static const struct scmi_device_id scmi_id_table[] = {
+	{ SCMI_PROTOCOL_PINCTRL, "pinctrl" },
+	{ }
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static int scmi_pinctrl_probe(struct scmi_device *sdev)
+{
+	int ret;
+	struct device *dev = &sdev->dev;
+	struct scmi_pinctrl *pmx;
+	const struct scmi_handle *handle;
+	struct scmi_protocol_handle *ph;
+
+	if (!sdev || !sdev->handle)
+		return -EINVAL;
+
+	handle = sdev->handle;
+
+	pinctrl_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PINCTRL,
+						&ph);
+	if (IS_ERR(pinctrl_ops))
+		return PTR_ERR(pinctrl_ops);
+
+	pmx = devm_kzalloc(dev, sizeof(*pmx), GFP_KERNEL);
+	if (!pmx)
+		return -ENOMEM;
+
+	pmx->ph = ph;
+
+	pmx->dev = dev;
+	pmx->pctl_desc.name = DRV_NAME;
+	pmx->pctl_desc.owner = THIS_MODULE;
+	pmx->pctl_desc.pctlops = &pinctrl_scmi_pinctrl_ops;
+	pmx->pctl_desc.pmxops = &pinctrl_scmi_pinmux_ops;
+	pmx->pctl_desc.confops = &pinctrl_scmi_pinconf_ops;
+
+	ret = pinctrl_scmi_get_pins(pmx, &pmx->pctl_desc.npins,
+				    &pmx->pctl_desc.pins);
+	if (ret)
+		return ret;
+
+	ret = devm_pinctrl_register_and_init(dev, &pmx->pctl_desc, pmx,
+					     &pmx->pctldev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to register pinctrl\n");
+
+	pmx->nr_functions = pinctrl_scmi_get_functions_count(pmx->pctldev);
+	pmx->nr_groups = pinctrl_scmi_get_groups_count(pmx->pctldev);
+
+	if (pmx->nr_functions) {
+		pmx->functions = devm_kcalloc(dev, pmx->nr_functions,
+					      sizeof(*pmx->functions),
+					      GFP_KERNEL);
+		if (!pmx->functions)
+			return -ENOMEM;
+	}
+
+	if (pmx->nr_groups) {
+		pmx->groups = devm_kcalloc(dev, pmx->nr_groups,
+					   sizeof(*pmx->groups), GFP_KERNEL);
+		if (!pmx->groups)
+			return -ENOMEM;
+	}
+
+	return pinctrl_enable(pmx->pctldev);
+}
+
+static struct scmi_driver scmi_pinctrl_driver = {
+	.name = DRV_NAME,
+	.probe = scmi_pinctrl_probe,
+	.id_table = scmi_id_table,
+};
+module_scmi_driver(scmi_pinctrl_driver);
+
+MODULE_AUTHOR("Oleksii Moisieiev <oleksii_moisieiev at epam.com>");
+MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
+MODULE_DESCRIPTION("ARM SCMI pin controller driver");
+MODULE_LICENSE("GPL");

-- 
2.37.1



From bot at kernelci.org  Thu Feb 22 17:13:40 2024
From: bot at kernelci.org (kernelci.org bot)
Date: Thu, 22 Feb 2024 17:13:40 -0800 (PST)
Subject: arm64/for-kernelci baseline: 33 runs,
 8 regressions (v6.8-rc5-80-g9abbc24128bc5)
Message-ID: <65d7f144.050a0220.bd7b1.9044@mx.google.com>

arm64/for-kernelci baseline: 33 runs, 8 regressions (v6.8-rc5-80-g9abbc24128bc5)

Regressions Summary
-------------------

platform                 | arch  | lab             | compiler | defconfig | regressions
-------------------------+-------+-----------------+----------+-----------+------------
imx8mm-innocomm-wb15-evk | arm64 | lab-pengutronix | gcc-10   | defconfig | 1          
kontron-kbox-a-230-ls    | arm64 | lab-kontron     | gcc-10   | defconfig | 5          
kontron-sl28-var3-ads2   | arm64 | lab-kontron     | gcc-10   | defconfig | 2          

  Details:  https://kernelci.org/test/job/arm64/branch/for-kernelci/kernel/v6.8-rc5-80-g9abbc24128bc5/plan/baseline/

  Test:     baseline
  Tree:     arm64
  Branch:   for-kernelci
  Describe: v6.8-rc5-80-g9abbc24128bc5
  URL:      https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
  SHA:      9abbc24128bc518a48899107a05e10d1ac4f2391 


Test Regressions
---------------- 


platform                 | arch  | lab             | compiler | defconfig | regressions
-------------------------+-------+-----------------+----------+-----------+------------
imx8mm-innocomm-wb15-evk | arm64 | lab-pengutronix | gcc-10   | defconfig | 1          

  Details:     https://kernelci.org/test/plan/id/65d7e71e39ca71333a637032

  Results:     0 PASS, 1 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-10 (aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc5-80-g9abbc24128bc5/arm64/defconfig/gcc-10/lab-pengutronix/baseline-imx8mm-innocomm-wb15-evk.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc5-80-g9abbc24128bc5/arm64/defconfig/gcc-10/lab-pengutronix/baseline-imx8mm-innocomm-wb15-evk.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230623.0/arm64/rootfs.cpio.gz 


  * baseline.login: https://kernelci.org/test/case/id/65d7e71e39ca71333a637033
        new failure (last pass: v6.8-rc5-58-g83d49ede4b181) 
 


platform                 | arch  | lab             | compiler | defconfig | regressions
-------------------------+-------+-----------------+----------+-----------+------------
kontron-kbox-a-230-ls    | arm64 | lab-kontron     | gcc-10   | defconfig | 5          

  Details:     https://kernelci.org/test/plan/id/65d7e7055dc9374ca1637012

  Results:     90 PASS, 5 FAIL, 1 SKIP
  Full config: defconfig
  Compiler:    gcc-10 (aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc5-80-g9abbc24128bc5/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-kbox-a-230-ls.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc5-80-g9abbc24128bc5/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-kbox-a-230-ls.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230623.0/arm64/rootfs.cpio.gz 


  * baseline.bootrr.deferred-probe-empty: https://kernelci.org/test/case/id/65d7e7065dc9374ca1637019
        failing since 23 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-23T00:29:40.260583  / # #
    2024-02-23T00:29:40.362057  export SHELL=/bin/sh
    2024-02-23T00:29:40.362771  #
    2024-02-23T00:29:40.464232  / # export SHELL=/bin/sh. /lava-433999/environment
    2024-02-23T00:29:40.464955  
    2024-02-23T00:29:40.566299  / # . /lava-433999/environment/lava-433999/bin/lava-test-runner /lava-433999/1
    2024-02-23T00:29:40.567408  
    2024-02-23T00:29:40.571810  / # /lava-433999/bin/lava-test-runner /lava-433999/1
    2024-02-23T00:29:40.630146  + export 'TESTRUN_ID=1_bootrr'
    2024-02-23T00:29:40.630574  + <8>[   20.756367] <LAVA_SIGNAL_STARTRUN 1_bootrr 433999_1.5.2.4.5> 
    ... (16 line(s) more)  

  * baseline.bootrr.fsl_enetc-enetc2-probed: https://kernelci.org/test/case/id/65d7e7065dc9374ca163701d
        failing since 23 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-23T00:29:42.703728  /lava-433999/1/../bin/lava-test-case
    2024-02-23T00:29:42.738075  <8>[   22.866651] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc2-probed RESULT=fail>
    2024-02-23T00:29:42.738197  /lava-433999/1/../bin/lava-test-case   

  * baseline.bootrr.mscc_felix-probed: https://kernelci.org/test/case/id/65d7e7065dc9374ca163701f
        failing since 23 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-23T00:29:43.799291  /lava-433999/1/../bin/lava-test-case
    2024-02-23T00:29:43.799747  <8>[   23.905416] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=mscc_felix-probed RESULT=fail>
    2024-02-23T00:29:43.800107  /lava-433999/1/../bin/lava-test-case
    2024-02-23T00:29:43.800390  <8>[   23.922649] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=leds-gpio-driver-present RESULT=pass>   

  * baseline.bootrr.fsl_enetc-enetc0-probed: https://kernelci.org/test/case/id/65d7e7065dc9374ca1637024
        failing since 23 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-23T00:29:44.879066  /lava-433999/1/../bin/lava-test-case   

  * baseline.bootrr.fsl_enetc-enetc1-probed: https://kernelci.org/test/case/id/65d7e7065dc9374ca1637025
        failing since 23 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-23T00:29:44.882359  <8>[   25.023872] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc0-probed RESULT=fail>
    2024-02-23T00:29:45.936772  /lava-433999/1/../bin/lava-test-case
    2024-02-23T00:29:45.937160  <8>[   26.045536] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc1-probed RESULT=fail>
    2024-02-23T00:29:45.937405  /lava-433999/1/../bin/lava-test-case   
 


platform                 | arch  | lab             | compiler | defconfig | regressions
-------------------------+-------+-----------------+----------+-----------+------------
kontron-sl28-var3-ads2   | arm64 | lab-kontron     | gcc-10   | defconfig | 2          

  Details:     https://kernelci.org/test/plan/id/65d7e70727ce41a9eb63702f

  Results:     101 PASS, 2 FAIL, 1 SKIP
  Full config: defconfig
  Compiler:    gcc-10 (aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc5-80-g9abbc24128bc5/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-sl28-var3-ads2.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v6.8-rc5-80-g9abbc24128bc5/arm64/defconfig/gcc-10/lab-kontron/baseline-kontron-sl28-var3-ads2.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230623.0/arm64/rootfs.cpio.gz 


  * baseline.bootrr.deferred-probe-empty: https://kernelci.org/test/case/id/65d7e70727ce41a9eb637036
        failing since 23 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-23T00:29:35.952469  / # #
    2024-02-23T00:29:36.054612  export SHELL=/bin/sh
    2024-02-23T00:29:36.055352  #
    2024-02-23T00:29:36.156609  / # export SHELL=/bin/sh. /lava-434000/environment
    2024-02-23T00:29:36.157359  
    2024-02-23T00:29:36.258746  / # . /lava-434000/environment/lava-434000/bin/lava-test-runner /lava-434000/1
    2024-02-23T00:29:36.259709  
    2024-02-23T00:29:36.264341  / # /lava-434000/bin/lava-test-runner /lava-434000/1
    2024-02-23T00:29:36.332194  + export 'TESTRUN_ID=1_bootrr'
    2024-02-23T00:29:36.332635  + <8>[   21.012709] <LAVA_SIGNAL_STARTRUN 1_bootrr 434000_1.5.2.4.5> 
    ... (11 line(s) more)  

  * baseline.bootrr.fsl_enetc-enetc0-probed: https://kernelci.org/test/case/id/65d7e70727ce41a9eb637049
        failing since 23 days (last pass: v6.7-rc8-101-g0802e17d9aca, first fail: v6.8-rc2)

    2024-02-23T00:29:38.770496  /lava-434000/1/../bin/lava-test-case
    2024-02-23T00:29:38.770983  <8>[   23.437901] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc-enetc0-probed RESULT=fail>
    2024-02-23T00:29:38.771280  /lava-434000/1/../bin/lava-test-case
    2024-02-23T00:29:38.771502  <8>[   23.455670] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=fsl_enetc_mdio-driver-present RESULT=pass>
    2024-02-23T00:29:38.771716  /lava-434000/1/../bin/lava-test-case   
  


From lkp at intel.com  Thu Feb 22 17:26:10 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 23 Feb 2024 09:26:10 +0800
Subject: [PATCH 2/3] arch: Remove struct fb_info from video helpers
In-Reply-To: <20240221161431.8245-3-tzimmermann@suse.de>
References: <20240221161431.8245-3-tzimmermann@suse.de>
Message-ID: <202402230941.JZdvHHEX-lkp@intel.com>

Hi Thomas,

kernel test robot noticed the following build errors:

[auto build test ERROR on tip/x86/core]
[also build test ERROR on deller-parisc/for-next arnd-asm-generic/master linus/master v6.8-rc5]
[cannot apply to next-20240222]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Thomas-Zimmermann/arch-Select-fbdev-helpers-with-CONFIG_VIDEO/20240222-001622
base:   tip/x86/core
patch link:    https://lore.kernel.org/r/20240221161431.8245-3-tzimmermann%40suse.de
patch subject: [PATCH 2/3] arch: Remove struct fb_info from video helpers
config: x86_64-rhel-8.3 (https://download.01.org/0day-ci/archive/20240223/202402230941.JZdvHHEX-lkp at intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240223/202402230941.JZdvHHEX-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402230941.JZdvHHEX-lkp at intel.com/

All errors (new ones prefixed by >>):

   ld: vmlinux.o: in function `fbcon_select_primary':
>> drivers/video/fbdev/core/fbcon.c:2944: undefined reference to `video_is_primary_device'
   ld: vmlinux.o: in function `fb_io_mmap':
   drivers/video/fbdev/core/fb_io_fops.c:164: undefined reference to `pgprot_framebuffer'


vim +2944 drivers/video/fbdev/core/fbcon.c

  2939	
  2940	#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
  2941	static void fbcon_select_primary(struct fb_info *info)
  2942	{
  2943		if (!map_override && primary_device == -1 &&
> 2944		    video_is_primary_device(info->device)) {
  2945			int i;
  2946	
  2947			printk(KERN_INFO "fbcon: %s (fb%i) is primary device\n",
  2948			       info->fix.id, info->node);
  2949			primary_device = info->node;
  2950	
  2951			for (i = first_fb_vc; i <= last_fb_vc; i++)
  2952				con2fb_map_boot[i] = primary_device;
  2953	
  2954			if (con_is_bound(&fb_con)) {
  2955				printk(KERN_INFO "fbcon: Remapping primary device, "
  2956				       "fb%i, to tty %i-%i\n", info->node,
  2957				       first_fb_vc + 1, last_fb_vc + 1);
  2958				info_idx = primary_device;
  2959			}
  2960		}
  2961	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From liuyuntao12 at huawei.com  Thu Feb 22 17:39:29 2024
From: liuyuntao12 at huawei.com (liuyuntao (F))
Date: Fri, 23 Feb 2024 09:39:29 +0800
Subject: [PATCH -next] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
In-Reply-To: <58297ee9-4f33-4b3b-bd00-b44e86965892@app.fastmail.com>
References: <20240220081527.23408-1-liuyuntao12@huawei.com>
 <1342759e-b967-4ec4-98d5-48146f81f695@app.fastmail.com>
 <38c09a4b-69cc-4dc5-8a68-e5f5597613ac@huawei.com>
 <30b01c65-12f2-4ee0-81d5-c7a2da2c36b4@app.fastmail.com>
 <4e9396ca-460b-49ca-818e-73f0a8997b15@huawei.com>
 <58297ee9-4f33-4b3b-bd00-b44e86965892@app.fastmail.com>
Message-ID: <7396cdc0-e878-48fe-85b9-d88611d28444@huawei.com>



On 2024/2/23 0:04, Arnd Bergmann wrote:
> On Thu, Feb 22, 2024, at 12:24, liuyuntao (F) wrote:
>>
>> The position of the caret has been moved below the right brace
>> of { KEEP(*(.vectors.bhb.loop8)) }, indicating that lld is treating
>> the entire `KEEP(*(.vectors))` as a file name. This could potentially be
>> a bug in lld. Perhaps we can temporarily
>> enable the DCE option only when option LD_IS_LLD is disabled,
>> like risc-v:
>>
>> `select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if !LD_IS_LLD`.
> 
> I would really like to see this working with lld if at all
> possible, as it allows the combination of gc-sections with
> lto and CONFIG_TRIM_UNUSED_KSYMS.
> 
> I experimented with lld myself now and I did get a booting
> kernel even without the the KEEP() on the vectors. I also

When the kernel booted up successfully, was config DCE enabled?

> see that this is the only use of OVERLAY in the kernel, so
> I hope that we can find a way to make it work with existing
> lld after all, either without the KEEP or without the OVERLAY.

Yeah, i will try other way to make it work.

> 
> Did you see any problems without the KEEP() on the vectors?
> 
>       Arnd

Without the KEEP(),disable DCE, qemu boots well,
enable DCE,qemu hangs on startup.
I experimented with lld using vexpress_defconfig.


From megi at xff.cz  Thu Feb 22 17:52:11 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Fri, 23 Feb 2024 02:52:11 +0100
Subject: [PATCH v2 1/5] dt-bindings: sound: Add jack-type property to sun8i-a33-codec
In-Reply-To: <20240223015219.3618111-1-megi@xff.cz>
References: <20240223015219.3618111-1-megi@xff.cz>
Message-ID: <20240223015219.3618111-2-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

The codec driver needs to know what jack connector is connected to
on the board. Add proprty to describe the type of connector.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 .../bindings/sound/allwinner,sun8i-a33-codec.yaml        | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
index 63eadc4200ac..399fc00ad3f4 100644
--- a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
@@ -44,6 +44,15 @@ properties:
       - const: bus
       - const: mod
 
+  jack-type:
+    enum:
+      - headset
+      - headphone
+    description:
+      Type of jack connector connected to the codec. This can be either
+      a 3-pin headphone connector or 4-pin headset connector. If not
+      specified, jack detection is disabled.
+
 required:
   - "#sound-dai-cells"
   - compatible
-- 
2.43.0



From megi at xff.cz  Thu Feb 22 17:52:14 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Fri, 23 Feb 2024 02:52:14 +0100
Subject: [PATCH v2 4/5] ASoC: sun50i-codec-analog: Enable jack detection on startup
In-Reply-To: <20240223015219.3618111-1-megi@xff.cz>
References: <20240223015219.3618111-1-megi@xff.cz>
Message-ID: <20240223015219.3618111-5-megi@xff.cz>

From: Arnaud Ferraris <arnaud.ferraris at collabora.com>

This commit adds the necessary setup to enable jack detection on startup
as well as the callback function enabling the microphone ADC when
headset bias is enabled. The microphone ADC is also disabled in suspend.

Signed-off-by: Arnaud Ferraris <arnaud.ferraris at collabora.com>
[Samuel: Moved MICADCEN setup to HBIAS event, added bias hooks]
Signed-off-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Ond?ej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun50i-codec-analog.c | 32 ++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index cedd4de42d1a..2081721a8ff2 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -116,8 +116,10 @@
 #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN	7
 
 #define SUN50I_ADDA_JACK_MIC_CTRL	0x1d
+#define SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN	7
 #define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN	6
 #define SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN	5
+#define SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN	4
 
 /* mixer controls */
 static const struct snd_kcontrol_new sun50i_a64_codec_mixer_controls[] = {
@@ -296,6 +298,19 @@ static const struct snd_kcontrol_new sun50i_codec_earpiece_switch[] = {
 			SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE, 1, 0),
 };
 
+static int sun50i_codec_hbias_event(struct snd_soc_dapm_widget *w,
+				    struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	u32 value = !!SND_SOC_DAPM_EVENT_ON(event);
+
+	regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
+			   BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN),
+			   value << SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN);
+
+	return 0;
+}
+
 static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
 	/* DAC */
 	SND_SOC_DAPM_DAC("Left DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL,
@@ -367,7 +382,8 @@ static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
 	/* Microphone Bias */
 	SND_SOC_DAPM_SUPPLY("HBIAS", SUN50I_ADDA_JACK_MIC_CTRL,
 			    SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN,
-			    0, NULL, 0),
+			    0, sun50i_codec_hbias_event,
+			    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
 	/* Mic input path */
 	SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN50I_ADDA_MIC2_CTRL,
@@ -474,14 +490,28 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
 static int sun50i_a64_codec_set_bias_level(struct snd_soc_component *component,
 					   enum snd_soc_bias_level level)
 {
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	int hbias;
+
 	switch (level) {
 	case SND_SOC_BIAS_OFF:
+		regmap_clear_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) |
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN));
+
 		regmap_set_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
 				BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		regmap_clear_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
 				   BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
+
+		hbias = snd_soc_dapm_get_pin_status(dapm, "HBIAS");
+		regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) |
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN),
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) |
+				   hbias << SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN);
 		break;
 	default:
 		break;
-- 
2.43.0



From megi at xff.cz  Thu Feb 22 17:52:13 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Fri, 23 Feb 2024 02:52:13 +0100
Subject: [PATCH v2 3/5] ASoC: sun8i-codec: Enable bus clock at STANDBY and higher bias
In-Reply-To: <20240223015219.3618111-1-megi@xff.cz>
References: <20240223015219.3618111-1-megi@xff.cz>
Message-ID: <20240223015219.3618111-4-megi@xff.cz>

From: Samuel Holland <samuel at sholland.org>

For codec variants that have a bus clock, that clock must be running to
receive interrupts. Since jack and mic accessory detection should work
even when no audio is playing, that means the bus clock should be
enabled any time the system is on.

Accomplish that by tying the bus clock to the runtime PM state, which is
then tied to the bias level not being OFF. Since the codec sets
idle_bias_on, bias will generally never be OFF. However, we can set
suspend_bias_off to maintain the power savings of gating the bus clock
during suspend, when we don't expect jack/accessory detection to work.

Signed-off-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Ond?ej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun8i-codec.c | 41 ++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 7b45ddffe990..2a46b96b03cc 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -177,12 +177,14 @@ struct sun8i_codec_aif {
 };
 
 struct sun8i_codec_quirks {
-	bool legacy_widgets	: 1;
-	bool lrck_inversion	: 1;
+	bool	bus_clock	: 1;
+	bool	legacy_widgets	: 1;
+	bool	lrck_inversion	: 1;
 };
 
 struct sun8i_codec {
 	struct regmap			*regmap;
+	struct clk			*clk_bus;
 	struct clk			*clk_module;
 	const struct sun8i_codec_quirks	*quirks;
 	struct sun8i_codec_aif		aifs[SUN8I_CODEC_NAIFS];
@@ -197,6 +199,14 @@ static int sun8i_codec_runtime_resume(struct device *dev)
 	struct sun8i_codec *scodec = dev_get_drvdata(dev);
 	int ret;
 
+	if (scodec->clk_bus) {
+		ret = clk_prepare_enable(scodec->clk_bus);
+		if (ret) {
+			dev_err(dev, "Failed to enable the bus clock\n");
+			return ret;
+		}
+	}
+
 	regcache_cache_only(scodec->regmap, false);
 
 	ret = regcache_sync(scodec->regmap);
@@ -215,6 +225,9 @@ static int sun8i_codec_runtime_suspend(struct device *dev)
 	regcache_cache_only(scodec->regmap, true);
 	regcache_mark_dirty(scodec->regmap);
 
+	if (scodec->clk_bus)
+		clk_disable_unprepare(scodec->clk_bus);
+
 	return 0;
 }
 
@@ -1277,6 +1290,7 @@ static const struct snd_soc_component_driver sun8i_soc_component = {
 	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
 	.probe			= sun8i_codec_component_probe,
 	.idle_bias_on		= 1,
+	.suspend_bias_off	= 1,
 	.endianness		= 1,
 };
 
@@ -1299,6 +1313,18 @@ static int sun8i_codec_probe(struct platform_device *pdev)
 	if (!scodec)
 		return -ENOMEM;
 
+	scodec->quirks = of_device_get_match_data(&pdev->dev);
+
+	platform_set_drvdata(pdev, scodec);
+
+	if (scodec->quirks->bus_clock) {
+		scodec->clk_bus = devm_clk_get(&pdev->dev, "bus");
+		if (IS_ERR(scodec->clk_bus)) {
+			dev_err(&pdev->dev, "Failed to get the bus clock\n");
+			return PTR_ERR(scodec->clk_bus);
+		}
+	}
+
 	scodec->clk_module = devm_clk_get(&pdev->dev, "mod");
 	if (IS_ERR(scodec->clk_module)) {
 		dev_err(&pdev->dev, "Failed to get the module clock\n");
@@ -1311,17 +1337,14 @@ static int sun8i_codec_probe(struct platform_device *pdev)
 		return PTR_ERR(base);
 	}
 
-	scodec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "bus", base,
-						   &sun8i_codec_regmap_config);
+	scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+					       &sun8i_codec_regmap_config);
 	if (IS_ERR(scodec->regmap)) {
 		dev_err(&pdev->dev, "Failed to create our regmap\n");
 		return PTR_ERR(scodec->regmap);
 	}
 
-	scodec->quirks = of_device_get_match_data(&pdev->dev);
-
-	platform_set_drvdata(pdev, scodec);
-
+	regcache_cache_only(scodec->regmap, true);
 	pm_runtime_enable(&pdev->dev);
 	if (!pm_runtime_enabled(&pdev->dev)) {
 		ret = sun8i_codec_runtime_resume(&pdev->dev);
@@ -1357,11 +1380,13 @@ static void sun8i_codec_remove(struct platform_device *pdev)
 }
 
 static const struct sun8i_codec_quirks sun8i_a33_quirks = {
+	.bus_clock	= true,
 	.legacy_widgets	= true,
 	.lrck_inversion	= true,
 };
 
 static const struct sun8i_codec_quirks sun50i_a64_quirks = {
+	.bus_clock	= true,
 };
 
 static const struct of_device_id sun8i_codec_of_match[] = {
-- 
2.43.0



From megi at xff.cz  Thu Feb 22 17:52:10 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Fri, 23 Feb 2024 02:52:10 +0100
Subject: [PATCH v2 0/5] Add support for jack detection to codec present in A64 SoC
Message-ID: <20240223015219.3618111-1-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

This series adds support for jack detection to this codec. I used
and tested this on Pinephone. It works quite nicely. I tested it
against Android headset mic button resistor specification.

The patches are improved and debugged version of the original
ones from Arnaud Ferraris and Samuel Holland, imrpoved to better
handle headset button presses and with more robust plug-in/out
event debouncing.

Please take a look. :)

v2:
- use set_jack/get_jack_type
- get rid of some custom poking inside card internals to figure
  out what kind of jack port we should setup the codec for
- read jack-type from OF as suggested here: 
  https://elixir.bootlin.com/linux/latest/source/sound/soc/soc-component.c#L288
- add DT bindings

Thank you very much,
	Ond?ej Jirman

Arnaud Ferraris (2):
  ASoC: sun50i-codec-analog: Enable jack detection on startup
  ASoC: sun8i-codec: Implement jack and accessory detection

Ondrej Jirman (1):
  dt-bindings: sound: Add jack-type property to sun8i-a33-codec

Samuel Holland (2):
  ASoC: sun50i-codec-analog: Move suspend/resume to set_bias_level
  ASoC: sun8i-codec: Enable bus clock at STANDBY and higher bias

 .../sound/allwinner,sun8i-a33-codec.yaml      |   9 +
 sound/soc/sunxi/sun50i-codec-analog.c         |  73 +++-
 sound/soc/sunxi/sun8i-codec.c                 | 359 +++++++++++++++++-
 3 files changed, 421 insertions(+), 20 deletions(-)

-- 
2.43.0



From megi at xff.cz  Thu Feb 22 17:52:12 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Fri, 23 Feb 2024 02:52:12 +0100
Subject: [PATCH v2 2/5] ASoC: sun50i-codec-analog: Move suspend/resume to set_bias_level
In-Reply-To: <20240223015219.3618111-1-megi@xff.cz>
References: <20240223015219.3618111-1-megi@xff.cz>
Message-ID: <20240223015219.3618111-3-megi@xff.cz>

From: Samuel Holland <samuel at sholland.org>

With idle_bias_on and suspend_bias_off, there are bias level transitions
that match the suspend/resume callbacks. However, there are also
transitions during probe (OFF => STANDBY) and removal (STANDBY => OFF).

By using the set_bias_level hook, the driver can have one copy of code
that would otherwise be duplicated between the probe/resume and
suspend/remove hooks.

Signed-off-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Ond?ej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun50i-codec-analog.c | 29 +++++++++++++++++----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index 8a32d05e23e1..cedd4de42d1a 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -471,17 +471,23 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
 	{ "EARPIECE", NULL, "Earpiece Amp" },
 };
 
-static int sun50i_a64_codec_suspend(struct snd_soc_component *component)
+static int sun50i_a64_codec_set_bias_level(struct snd_soc_component *component,
+					   enum snd_soc_bias_level level)
 {
-	return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
-				  BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE),
-				  BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
-}
+	switch (level) {
+	case SND_SOC_BIAS_OFF:
+		regmap_set_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
+				BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
+		break;
+	case SND_SOC_BIAS_STANDBY:
+		regmap_clear_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
+				   BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
+		break;
+	default:
+		break;
+	}
 
-static int sun50i_a64_codec_resume(struct snd_soc_component *component)
-{
-	return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
-				  BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE), 0);
+	return 0;
 }
 
 static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = {
@@ -491,8 +497,9 @@ static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = {
 	.num_dapm_widgets	= ARRAY_SIZE(sun50i_a64_codec_widgets),
 	.dapm_routes		= sun50i_a64_codec_routes,
 	.num_dapm_routes	= ARRAY_SIZE(sun50i_a64_codec_routes),
-	.suspend		= sun50i_a64_codec_suspend,
-	.resume			= sun50i_a64_codec_resume,
+	.set_bias_level		= sun50i_a64_codec_set_bias_level,
+	.idle_bias_on		= true,
+	.suspend_bias_off	= true,
 };
 
 static const struct of_device_id sun50i_codec_analog_of_match[] = {
-- 
2.43.0



From megi at xff.cz  Thu Feb 22 17:52:15 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Fri, 23 Feb 2024 02:52:15 +0100
Subject: [PATCH v2 5/5] ASoC: sun8i-codec: Implement jack and accessory detection
In-Reply-To: <20240223015219.3618111-1-megi@xff.cz>
References: <20240223015219.3618111-1-megi@xff.cz>
Message-ID: <20240223015219.3618111-6-megi@xff.cz>

From: Arnaud Ferraris <arnaud.ferraris at collabora.com>

Add support for the jack detection functionality in the A64 variant,
which uses a pair of IRQs; and microphone accessory (button) detection,
which uses an ADC with an IRQ trigger.

IRQs will only be triggered if the JACKDETEN, HMICBIASEN, and MICADCEN
bits are set appropriately in the analog codec component
(sun50i-codec-analog), but there is no direct software dependency
between the two components.

Setup ADC so that it samples with period of 16ms, disable smoothing
and enable MDATA threshold (should be below idle voltage/HMIC_DATA
value). Also enable HMIC_N, which makes sure we get HMIC_N samples
after HMIC_DATA crosses the threshold.

This allows us to perform steady state detection of HMIC_DATA, by
comparing current and previous ADC samples, to detect end of the
transient when the user de-presses the button. Otherwise ADC could
sample anywhere within the transient, and the driver may mis-issue
key-press events for other buttons attached to the resistor ladder.

Signed-off-by: Arnaud Ferraris <arnaud.ferraris at collabora.com>
[Samuel: Decouple from analog codec, fixes]
Co-developed-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Samuel Holland <samuel at sholland.org>
[Ondrej: Almost complete rewrite of the patch, change to use set_jack/
get_jack_type. Better de-bounce, fix mic button handling, better
interrupt processing.]
Co-developed-by: Ondrej Jirman <megi at xff.cz>
Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun50i-codec-analog.c |  12 +
 sound/soc/sunxi/sun8i-codec.c         | 318 ++++++++++++++++++++++++++
 2 files changed, 330 insertions(+)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index 2081721a8ff2..2dcdf113b66e 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -115,6 +115,11 @@
 #define SUN50I_ADDA_HS_MBIAS_CTRL	0x0e
 #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN	7
 
+#define SUN50I_ADDA_MDET_CTRL		0x1c
+#define SUN50I_ADDA_MDET_CTRL_SELDETADC_FS	4
+#define SUN50I_ADDA_MDET_CTRL_SELDETADC_DB	2
+#define SUN50I_ADDA_MDET_CTRL_SELDETADC_BF	0
+
 #define SUN50I_ADDA_JACK_MIC_CTRL	0x1d
 #define SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN	7
 #define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN	6
@@ -564,6 +569,13 @@ static int sun50i_codec_analog_probe(struct platform_device *pdev)
 			   BIT(SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN),
 			   enable << SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN);
 
+	/* Select sample interval of the ADC sample to 16ms */
+	regmap_update_bits(regmap, SUN50I_ADDA_MDET_CTRL,
+			   0x7 << SUN50I_ADDA_MDET_CTRL_SELDETADC_FS |
+			   0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_BF,
+			   0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_FS |
+			   0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_BF);
+
 	return devm_snd_soc_register_component(&pdev->dev,
 					       &sun50i_codec_analog_cmpnt_drv,
 					       NULL, 0);
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 2a46b96b03cc..097418364985 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -12,12 +12,16 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/input.h>
 #include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/log2.h>
 
+#include <sound/jack.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
@@ -118,6 +122,23 @@
 #define SUN8I_ADC_VOL_CTRL				0x104
 #define SUN8I_ADC_VOL_CTRL_ADCL_VOL			8
 #define SUN8I_ADC_VOL_CTRL_ADCR_VOL			0
+#define SUN8I_HMIC_CTRL1				0x110
+#define SUN8I_HMIC_CTRL1_HMIC_M				12
+#define SUN8I_HMIC_CTRL1_HMIC_N				8
+#define SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB		5
+#define SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN		4
+#define SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN			3
+#define SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN		0
+#define SUN8I_HMIC_CTRL2				0x114
+#define SUN8I_HMIC_CTRL2_HMIC_SAMPLE			14
+#define SUN8I_HMIC_CTRL2_HMIC_MDATA_THRESHOLD		8
+#define SUN8I_HMIC_CTRL2_HMIC_SF			6
+#define SUN8I_HMIC_STS					0x118
+#define SUN8I_HMIC_STS_MDATA_DISCARD			13
+#define SUN8I_HMIC_STS_HMIC_DATA			8
+#define SUN8I_HMIC_STS_JACK_OUT_IRQ_ST			4
+#define SUN8I_HMIC_STS_JACK_IN_IRQ_ST			3
+#define SUN8I_HMIC_STS_HMIC_DATA_IRQ_ST			0
 #define SUN8I_DAC_DIG_CTRL				0x120
 #define SUN8I_DAC_DIG_CTRL_ENDA				15
 #define SUN8I_DAC_VOL_CTRL				0x124
@@ -143,6 +164,17 @@
 #define SUN8I_AIF_CLK_CTRL_WORD_SIZ_MASK	GENMASK(5, 4)
 #define SUN8I_AIF_CLK_CTRL_DATA_FMT_MASK	GENMASK(3, 2)
 #define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK	GENMASK(1, 0)
+#define SUN8I_HMIC_CTRL1_HMIC_M_MASK		GENMASK(15, 12)
+#define SUN8I_HMIC_CTRL1_HMIC_N_MASK		GENMASK(11, 8)
+#define SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB_MASK GENMASK(6, 5)
+#define SUN8I_HMIC_CTRL2_HMIC_SAMPLE_MASK	GENMASK(15, 14)
+#define SUN8I_HMIC_CTRL2_HMIC_SF_MASK		GENMASK(7, 6)
+#define SUN8I_HMIC_STS_HMIC_DATA_MASK		GENMASK(12, 8)
+
+#define SUN8I_CODEC_BUTTONS	(SND_JACK_BTN_0|\
+				 SND_JACK_BTN_1|\
+				 SND_JACK_BTN_2|\
+				 SND_JACK_BTN_3)
 
 #define SUN8I_CODEC_PASSTHROUGH_SAMPLE_RATE 48000
 
@@ -178,16 +210,32 @@ struct sun8i_codec_aif {
 
 struct sun8i_codec_quirks {
 	bool	bus_clock	: 1;
+	bool	jack_detection	: 1;
 	bool	legacy_widgets	: 1;
 	bool	lrck_inversion	: 1;
 };
 
+enum {
+	SUN8I_JACK_STATUS_DISCONNECTED,
+	SUN8I_JACK_STATUS_WAITING_HBIAS,
+	SUN8I_JACK_STATUS_CONNECTED,
+};
+
 struct sun8i_codec {
+	struct snd_soc_component	*component;
 	struct regmap			*regmap;
 	struct clk			*clk_bus;
 	struct clk			*clk_module;
 	const struct sun8i_codec_quirks	*quirks;
 	struct sun8i_codec_aif		aifs[SUN8I_CODEC_NAIFS];
+	struct snd_soc_jack		*jack;
+	struct delayed_work		jack_work;
+	int				jack_irq;
+	int				jack_status;
+	int				jack_last_sample;
+	ktime_t				jack_hbias_ready;
+	struct mutex			jack_mutex;
+	int				last_hmic_irq;
 	unsigned int			sysclk_rate;
 	int				sysclk_refcnt;
 };
@@ -1245,6 +1293,8 @@ static int sun8i_codec_component_probe(struct snd_soc_component *component)
 	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
 	int ret;
 
+	scodec->component = component;
+
 	/* Add widgets for backward compatibility with old device trees. */
 	if (scodec->quirks->legacy_widgets) {
 		ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_legacy_widgets,
@@ -1281,6 +1331,263 @@ static int sun8i_codec_component_probe(struct snd_soc_component *component)
 	return 0;
 }
 
+static void sun8i_codec_set_hmic_bias(struct sun8i_codec *scodec, bool enable)
+{
+	struct snd_soc_dapm_context *dapm = &scodec->component->card->dapm;
+	int irq_mask = BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN);
+
+	if (enable)
+		snd_soc_dapm_force_enable_pin(dapm, "HBIAS");
+	else
+		snd_soc_dapm_disable_pin(dapm, "HBIAS");
+
+	snd_soc_dapm_sync(dapm);
+
+	regmap_update_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
+			   irq_mask, enable ? irq_mask : 0);
+}
+
+static void sun8i_codec_jack_work(struct work_struct *work)
+{
+	struct sun8i_codec *scodec = container_of(work, struct sun8i_codec,
+						  jack_work.work);
+	unsigned int mdata;
+	int type_mask = scodec->jack->jack->type;
+	int type;
+
+	guard(mutex)(&scodec->jack_mutex);
+
+	if (scodec->jack_status == SUN8I_JACK_STATUS_DISCONNECTED) {
+		if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_IN_IRQ_ST)
+			return;
+
+		scodec->jack_last_sample = -1;
+
+		if (type_mask & SND_JACK_MICROPHONE) {
+			/*
+			 * If we were in disconnected state, we enable HBIAS and
+			 * wait 600ms before reading initial HDATA value.
+			 */
+			scodec->jack_hbias_ready = ktime_add_ms(ktime_get(), 600);
+			sun8i_codec_set_hmic_bias(scodec, true);
+			queue_delayed_work(system_power_efficient_wq,
+					   &scodec->jack_work,
+					   msecs_to_jiffies(610));
+			scodec->jack_status = SUN8I_JACK_STATUS_WAITING_HBIAS;
+		} else {
+			snd_soc_jack_report(scodec->jack, SND_JACK_HEADPHONE,
+					    type_mask);
+			scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED;
+		}
+	} else if (scodec->jack_status == SUN8I_JACK_STATUS_WAITING_HBIAS) {
+		/*
+		 * If we're waiting for HBIAS to stabilize, and we get plug-out
+		 * interrupt and nothing more for > 100ms, just cancel the
+		 * initialization.
+		 */
+		if (scodec->last_hmic_irq == SUN8I_HMIC_STS_JACK_OUT_IRQ_ST) {
+			scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED;
+			sun8i_codec_set_hmic_bias(scodec, false);
+			return;
+		}
+
+		/*
+		 * If we're not done waiting for HBIAS to stabilize, wait more.
+		 */
+		if (!ktime_after(ktime_get(), scodec->jack_hbias_ready)) {
+			s64 msecs = ktime_ms_delta(scodec->jack_hbias_ready,
+						   ktime_get());
+
+			queue_delayed_work(system_power_efficient_wq,
+					   &scodec->jack_work,
+					   msecs_to_jiffies(msecs + 10));
+			return;
+		}
+
+		/*
+		 * Everything is stabilized, determine jack type and report it.
+		 */
+		regmap_read(scodec->regmap, SUN8I_HMIC_STS, &mdata);
+		mdata &= SUN8I_HMIC_STS_HMIC_DATA_MASK;
+		mdata >>= SUN8I_HMIC_STS_HMIC_DATA;
+
+		regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0);
+
+		type = mdata < 16 ? SND_JACK_HEADPHONE : SND_JACK_HEADSET;
+		if (type == SND_JACK_HEADPHONE)
+			sun8i_codec_set_hmic_bias(scodec, false);
+
+		snd_soc_jack_report(scodec->jack, type, type_mask);
+		scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED;
+	} else if (scodec->jack_status == SUN8I_JACK_STATUS_CONNECTED) {
+		if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_OUT_IRQ_ST)
+			return;
+
+		scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED;
+		if (type_mask & SND_JACK_MICROPHONE)
+			sun8i_codec_set_hmic_bias(scodec, false);
+
+		snd_soc_jack_report(scodec->jack, 0, type_mask);
+	}
+}
+
+static irqreturn_t sun8i_codec_jack_irq(int irq, void *dev_id)
+{
+	struct sun8i_codec *scodec = dev_id;
+	int type = SND_JACK_HEADSET;
+	unsigned int status, value;
+
+	guard(mutex)(&scodec->jack_mutex);
+
+	regmap_read(scodec->regmap, SUN8I_HMIC_STS, &status);
+	regmap_write(scodec->regmap, SUN8I_HMIC_STS, status);
+
+	/*
+	 * De-bounce in/out interrupts via a delayed work re-scheduling to
+	 * 100ms after each interrupt..
+	 */
+	if (status & BIT(SUN8I_HMIC_STS_JACK_OUT_IRQ_ST)) {
+		/*
+		 * Out interrupt has priority over in interrupt so that if
+		 * we get both, we assume the disconnected state, which is
+		 * safer.
+		 */
+		scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_OUT_IRQ_ST;
+		mod_delayed_work(system_power_efficient_wq, &scodec->jack_work,
+				 msecs_to_jiffies(100));
+	} else if (status & BIT(SUN8I_HMIC_STS_JACK_IN_IRQ_ST)) {
+		scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_IN_IRQ_ST;
+		mod_delayed_work(system_power_efficient_wq, &scodec->jack_work,
+				 msecs_to_jiffies(100));
+	} else if (status & BIT(SUN8I_HMIC_STS_HMIC_DATA_IRQ_ST)) {
+		/*
+		 * Ignore data interrupts until jack status turns to connected
+		 * state, which is after HMIC enable stabilization is completed.
+		 * Until then tha data are bogus.
+		 */
+		if (scodec->jack_status != SUN8I_JACK_STATUS_CONNECTED)
+			return IRQ_HANDLED;
+
+		value = (status & SUN8I_HMIC_STS_HMIC_DATA_MASK) >>
+			SUN8I_HMIC_STS_HMIC_DATA;
+
+		/*
+		 * Assumes 60 mV per ADC LSB increment, 2V bias voltage, 2.2kOhm
+		 * bias resistor.
+		 */
+		if (value == 0)
+			type |= SND_JACK_BTN_0;
+		else if (value == 1)
+			type |= SND_JACK_BTN_3;
+		else if (value <= 3)
+			type |= SND_JACK_BTN_1;
+		else if (value <= 8)
+			type |= SND_JACK_BTN_2;
+
+		/*
+		 * De-bounce. Only report button after two consecutive A/D
+		 * samples are identical.
+		 */
+		if (scodec->jack_last_sample >= 0 &&
+		    scodec->jack_last_sample == value)
+			snd_soc_jack_report(scodec->jack, type,
+					    scodec->jack->jack->type);
+
+		scodec->jack_last_sample = value;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int sun8i_codec_enable_jack_detect(struct snd_soc_component *component,
+					  struct snd_soc_jack *jack, void *data)
+{
+	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
+	struct platform_device *pdev = to_platform_device(component->dev);
+	int ret;
+
+	if (!scodec->quirks->jack_detection)
+		return 0;
+
+	scodec->jack = jack;
+
+	scodec->jack_irq = platform_get_irq(pdev, 0);
+	if (scodec->jack_irq < 0)
+		return scodec->jack_irq;
+
+	/* Reserved value required for jack IRQs to trigger. */
+	regmap_write(scodec->regmap, SUN8I_HMIC_CTRL1,
+			   0xf << SUN8I_HMIC_CTRL1_HMIC_N |
+			   0x0 << SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB |
+			   0x4 << SUN8I_HMIC_CTRL1_HMIC_M);
+
+	/* Sample the ADC at 128 Hz; bypass smooth filter. */
+	regmap_write(scodec->regmap, SUN8I_HMIC_CTRL2,
+			   0x0 << SUN8I_HMIC_CTRL2_HMIC_SAMPLE |
+			   0x17 << SUN8I_HMIC_CTRL2_HMIC_MDATA_THRESHOLD |
+			   0x0 << SUN8I_HMIC_CTRL2_HMIC_SF);
+
+	/* Do not discard any MDATA, enable user written MDATA threshold. */
+	regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0);
+
+	regmap_set_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
+			BIT(SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN) |
+			BIT(SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN));
+
+	ret = devm_request_threaded_irq(&pdev->dev, scodec->jack_irq,
+					NULL, sun8i_codec_jack_irq,
+					IRQF_ONESHOT,
+					dev_name(&pdev->dev), scodec);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void sun8i_codec_disable_jack_detect(struct snd_soc_component *component)
+{
+	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
+
+	if (!scodec->quirks->jack_detection)
+		return;
+
+	devm_free_irq(component->dev, scodec->jack_irq, scodec);
+
+	cancel_delayed_work_sync(&scodec->jack_work);
+
+	regmap_clear_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
+			  BIT(SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN) |
+			  BIT(SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN) |
+			  BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN));
+
+	scodec->jack = NULL;
+}
+
+static int sun8i_codec_component_get_jack_type(struct snd_soc_component *component)
+{
+	struct device_node *node = component->dev->of_node;
+
+	if (of_property_match_string(node, "jack-type", "headset") >= 0)
+		return SND_JACK_HEADSET | SUN8I_CODEC_BUTTONS;
+	else if (of_property_match_string(node, "jack-type", "headphone") >= 0)
+		return SND_JACK_HEADPHONE;
+
+	return 0;
+}
+
+static int sun8i_codec_component_set_jack(struct snd_soc_component *component,
+					  struct snd_soc_jack *jack, void *data)
+{
+	int ret = 0;
+
+	if (jack)
+		ret = sun8i_codec_enable_jack_detect(component, jack, data);
+	else
+		sun8i_codec_disable_jack_detect(component);
+
+	return ret;
+}
+
 static const struct snd_soc_component_driver sun8i_soc_component = {
 	.controls		= sun8i_codec_controls,
 	.num_controls		= ARRAY_SIZE(sun8i_codec_controls),
@@ -1288,16 +1595,24 @@ static const struct snd_soc_component_driver sun8i_soc_component = {
 	.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
 	.dapm_routes		= sun8i_codec_dapm_routes,
 	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
+	.set_jack		= sun8i_codec_component_set_jack,
+	.get_jack_type		= sun8i_codec_component_get_jack_type,
 	.probe			= sun8i_codec_component_probe,
 	.idle_bias_on		= 1,
 	.suspend_bias_off	= 1,
 	.endianness		= 1,
 };
 
+static bool sun8i_codec_volatile_reg(struct device *dev, unsigned int reg)
+{
+	return reg == SUN8I_HMIC_STS;
+}
+
 static const struct regmap_config sun8i_codec_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
 	.val_bits	= 32,
+	.volatile_reg	= sun8i_codec_volatile_reg,
 	.max_register	= SUN8I_DAC_MXR_SRC,
 
 	.cache_type	= REGCACHE_FLAT,
@@ -1314,6 +1629,8 @@ static int sun8i_codec_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	scodec->quirks = of_device_get_match_data(&pdev->dev);
+	INIT_DELAYED_WORK(&scodec->jack_work, sun8i_codec_jack_work);
+	mutex_init(&scodec->jack_mutex);
 
 	platform_set_drvdata(pdev, scodec);
 
@@ -1387,6 +1704,7 @@ static const struct sun8i_codec_quirks sun8i_a33_quirks = {
 
 static const struct sun8i_codec_quirks sun50i_a64_quirks = {
 	.bus_clock	= true,
+	.jack_detection	= true,
 };
 
 static const struct of_device_id sun8i_codec_of_match[] = {
-- 
2.43.0



From shawnguo2 at yeah.net  Thu Feb 22 17:56:47 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Fri, 23 Feb 2024 09:56:47 +0800
Subject: [PATCH 1/2] arm64: dts: imx8dxl: add fsl-dma.h dt-binding header
 file
In-Reply-To: <20240129201633.234255-1-Frank.Li@nxp.com>
References: <20240129201633.234255-1-Frank.Li@nxp.com>
Message-ID: <Zdf7X5T/Gf8Bmigk@dragon>

On Mon, Jan 29, 2024 at 03:16:31PM -0500, Frank Li wrote:
> Add fsl-dma.h dt-binding header file in imx8dxl chip dtsi file.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied both, thanks!



From liuyongqiang13 at huawei.com  Thu Feb 22 17:57:29 2024
From: liuyongqiang13 at huawei.com (Yongqiang Liu)
Date: Fri, 23 Feb 2024 09:57:29 +0800
Subject: [PATCH] arm: flush: check if the folio is reserved for IMO
 addresses
In-Reply-To: <ZddUrO7i5KZn57FY@casper.infradead.org>
References: <20240222140147.1880357-1-liuyongqiang13@huawei.com>
 <ZddUrO7i5KZn57FY@casper.infradead.org>
Message-ID: <16b0b45c-721b-2e61-65cf-306b160d713d@huawei.com>


? 2024/2/22 22:05, Matthew Wilcox ??:
> On Thu, Feb 22, 2024 at 10:01:47PM +0800, Yongqiang Liu wrote:
>> @@ -296,6 +297,9 @@ void __sync_icache_dcache(pte_t pteval)
>>   		return;
>>   
>>   	folio = page_folio(pfn_to_page(pfn));
>> +	if (test_bit(PG_reserved, &folio->flags))
>> +		return;
> Why are you using PG_foo directly instead of the helpers?
>
> 	if (folio_test_reserved(folio))
> .
Sorry, I will send v2.


From shawnguo2 at yeah.net  Thu Feb 22 17:59:09 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Fri, 23 Feb 2024 09:59:09 +0800
Subject: [PATCH] ARM: imx_v6_v7_defconfig: Restore
 CONFIG_BACKLIGHT_CLASS_DEVICE
In-Reply-To: <20240201180054.3869350-1-festevam@gmail.com>
References: <20240201180054.3869350-1-festevam@gmail.com>
Message-ID: <Zdf77f97P0GPpfi4@dragon>

On Thu, Feb 01, 2024 at 03:00:54PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> Since commit bfac19e239a7 ("fbdev: mx3fb: Remove the driver") backlight
> is no longer functional.
> 
> The fbdev mx3fb driver used to automatically select 
> CONFIG_BACKLIGHT_CLASS_DEVICE.
> 
> Now that the mx3fb driver has been removed, enable the
> CONFIG_BACKLIGHT_CLASS_DEVICE option so that backlight can still work
> by default.
> 
> Tested on a imx6dl-sabresd board.
> 
> Cc: stable at vger.kernel.org
> Fixes: bfac19e239a7 ("fbdev: mx3fb: Remove the driver")
> Signed-off-by: Fabio Estevam <festevam at denx.de>

Applied, thanks!



From alexei.starovoitov at gmail.com  Thu Feb 22 18:04:35 2024
From: alexei.starovoitov at gmail.com (Alexei Starovoitov)
Date: Thu, 22 Feb 2024 18:04:35 -0800
Subject: [PATCH bpf-next v3 1/2] arm64: stacktrace: Implement
 arch_bpf_stack_walk() for the BPF JIT
In-Reply-To: <ZdegTX9x2ye-7xIt@arm.com>
References: <20240201125225.72796-1-puranjay12@gmail.com> <20240201125225.72796-2-puranjay12@gmail.com>
 <ZdegTX9x2ye-7xIt@arm.com>
Message-ID: <CAADnVQLGGTshMiQAWwJ9UzrEVDR4Z8yk+ki9pUqKLgcH0DRAjA@mail.gmail.com>

On Thu, Feb 22, 2024 at 11:28?AM Catalin Marinas
<catalin.marinas at arm.com> wrote:
>
> On Thu, Feb 01, 2024 at 12:52:24PM +0000, Puranjay Mohan wrote:
> > This will be used by bpf_throw() to unwind till the program marked as
> > exception boundary and run the callback with the stack of the main
> > program.
> >
> > This is required for supporting BPF exceptions on ARM64.
> >
> > Signed-off-by: Puranjay Mohan <puranjay12 at gmail.com>
> > ---
> >  arch/arm64/kernel/stacktrace.c | 26 ++++++++++++++++++++++++++
> >  1 file changed, 26 insertions(+)
> >
> > diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> > index 7f88028a00c0..66cffc5fc0be 100644
> > --- a/arch/arm64/kernel/stacktrace.c
> > +++ b/arch/arm64/kernel/stacktrace.c
> > @@ -7,6 +7,7 @@
> >  #include <linux/kernel.h>
> >  #include <linux/efi.h>
> >  #include <linux/export.h>
> > +#include <linux/filter.h>
> >  #include <linux/ftrace.h>
> >  #include <linux/kprobes.h>
> >  #include <linux/sched.h>
> > @@ -266,6 +267,31 @@ noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
> >       kunwind_stack_walk(arch_kunwind_consume_entry, &data, task, regs);
> >  }
> >
> > +struct bpf_unwind_consume_entry_data {
> > +     bool (*consume_entry)(void *cookie, u64 ip, u64 sp, u64 fp);
> > +     void *cookie;
> > +};
> > +
> > +static bool
> > +arch_bpf_unwind_consume_entry(const struct kunwind_state *state, void *cookie)
> > +{
> > +     struct bpf_unwind_consume_entry_data *data = cookie;
> > +
> > +     return data->consume_entry(data->cookie, state->common.pc, 0,
> > +                                state->common.fp);
> > +}
> > +
> > +noinline noinstr void arch_bpf_stack_walk(bool (*consume_entry)(void *cookie, u64 ip, u64 sp,
> > +                                                             u64 fp), void *cookie)
> > +{
> > +     struct bpf_unwind_consume_entry_data data = {
> > +             .consume_entry = consume_entry,
> > +             .cookie = cookie,
> > +     };
> > +
> > +     kunwind_stack_walk(arch_bpf_unwind_consume_entry, &data, current, NULL);
> > +}
>
> Too many "cookies", I found reading this confusing. If you ever respin,
> please use some different "cookie" names.
>
> I guess you want this to be merged via the bpf tree?

We typically take bpf jit patches through bpf-next, since
we do cross arch jits refactoring from time to time,
but nothing like this is pending for this merge window,
so if you want it to go through arm64 tree that's fine with us.

> Acked-by: Catalin Marinas <catalin.marinas at arm.com>

Thank you for the review!


From shawnguo2 at yeah.net  Thu Feb 22 18:07:39 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Fri, 23 Feb 2024 10:07:39 +0800
Subject: [PATCH v2 0/4] Add 8qm SMMU information
In-Reply-To: <20240206074151.577d33f1@kernel.org>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
 <20240202110511.135d26b7@kernel.org>
 <ZcIPCxgO3Gxc/aXh@dragon>
 <20240206074151.577d33f1@kernel.org>
Message-ID: <Zdf96y7q4298dkmG@dragon>

On Tue, Feb 06, 2024 at 07:41:51AM -0800, Jakub Kicinski wrote:
> On Tue, 6 Feb 2024 18:50:51 +0800 Shawn Guo wrote:
> > > Any preference on whether all these go via a platform tree,
> > > or should we pick up the net patch to netdev? I guess taking
> > > the DTB via netdev would be the usual way to handle this?  
> > 
> > No, it's not.  Taking DTS changes through arch/platform tree is the
> > usual way.
> 
> I said DTB.

If the DTB here means Device Tree Blob which is generated by DTC (Device
Tree Compiler) taking DTS (Device Tree Source) as input, it's a build
result and so neither of us could take.

Shawn



From thiago.bauermann at linaro.org  Thu Feb 22 18:24:59 2024
From: thiago.bauermann at linaro.org (Thiago Jung Bauermann)
Date: Thu, 22 Feb 2024 23:24:59 -0300
Subject: [PATCH v8 33/38] kselftest/arm64: Add a GCS test program built
 with the system libc
In-Reply-To: <9b899b4e-7410-4c3b-967b-7794dac742e4@sirena.org.uk>
References: <20240203-arm64-gcs-v8-0-c9fec77673ef@kernel.org>
 <20240203-arm64-gcs-v8-33-c9fec77673ef@kernel.org>
 <87sf1n7uea.fsf@linaro.org>
 <9b899b4e-7410-4c3b-967b-7794dac742e4@sirena.org.uk>
Message-ID: <87ttlzsyro.fsf@linaro.org>


Mark Brown <broonie at kernel.org> writes:

> On Mon, Feb 19, 2024 at 11:15:57PM -0300, Thiago Jung Bauermann wrote:
>
>> The only issue as can be seen above is that the can_call_function test
>> is failing. The child is getting a GCS Segmentation fault when returning
>> from fork().
>
>> I tried debugging it with GDB, but I don't see what's wrong since the
>> address in LR matches the first entry in GCSPR. Here is the
>> debug session:
>
> I believe based on prior discussions that you're running this using
> shrinkwrap - can you confirm exactly how please, including things like
> which firmware configuration you're using?  I'm using current git with
>
>   shrinkwrap run \
>         --rtvar KERNEL=arch/arm64/boot/Image \
>         --rtvar ROOTFS=${ROOTFS} \
>         --rtvar CMDLINE="${CMDLINE}" \
>         --overlay=arch/v9.4.yaml ns-edk2.yaml
>
> and a locally built yocto and everything seems perfectly happy.

Yes, this is how I'm running it:

  CMDLINE="Image dtb=fdt.dtb console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda2 ip=dhcp maxcpus=1"

  shrinkwrap run \
      --rtvar=KERNEL=Image-gcs-v8-v6.7-rc4-14743-ga551a7d7af93 \
      --rtvar=ROOTFS=$HOME/VMs/ubuntu-aarch64.img \
      --rtvar=CMDLINE="$CMDLINE" \
      ns-edk2.yaml

I ran the following to set up the FVP VM:

$ shrinkwrap build --overlay=arch/v9.4.yaml ns-edk2.yaml

My rootfs is Ubuntu 22.04.3. In case it's useful, my kernel config is
here:

https://people.linaro.org/~thiago.bauermann/gcs/config-v6.8.0-rc2

I tried removing "maxcpus=1" from the kernel command line, but it made
no difference.

I also tried resetting my Shrinkwrap setup and starting from scratch,
but it also made no difference: I just pulled from the current main
branch and removed Shrinkwrap's build and package directories, and also
removed all Docker images and the one container I had.

Here are some firmware versions from early boot:

  NOTICE:  Booting Trusted Firmware
  NOTICE:  BL1: v2.10.0   (release):v2.10.0
  NOTICE:  BL1: Built : 00:07:29, Feb 23 2024
     ?
  NOTICE:  BL2: v2.10.0   (release):v2.10.0
  NOTICE:  BL2: Built : 00:07:29, Feb 23 2024
     ?
  NOTICE:  BL31: v2.10.0  (release):v2.10.0
  NOTICE:  BL31: Built : 00:07:29, Feb 23 2024
     ?
  [  edk2 ] UEFI firmware (version  built at 00:06:55 on Feb 23 2024)
  Press ESCAPE for boot options ...........UEFI Interactive Shell v2.2
  EDK II
  UEFI v2.70 (EDK II, 0x00010000)

It looks like our main differences are the kernel config and the distro.

-- 
Thiago


From kuba at kernel.org  Thu Feb 22 18:26:45 2024
From: kuba at kernel.org (Jakub Kicinski)
Date: Thu, 22 Feb 2024 18:26:45 -0800
Subject: [PATCH v2 0/4] Add 8qm SMMU information
In-Reply-To: <Zdf96y7q4298dkmG@dragon>
References: <20240201-8qm_smmu-v2-0-3d12a80201a3@nxp.com>
	<20240202110511.135d26b7@kernel.org>
	<ZcIPCxgO3Gxc/aXh@dragon>
	<20240206074151.577d33f1@kernel.org>
	<Zdf96y7q4298dkmG@dragon>
Message-ID: <20240222182645.16f0d3bf@kernel.org>

On Fri, 23 Feb 2024 10:07:39 +0800 Shawn Guo wrote:
> On Tue, Feb 06, 2024 at 07:41:51AM -0800, Jakub Kicinski wrote:
> > I said DTB.  
> 
> If the DTB here means Device Tree Blob which is generated by DTC (Device
> Tree Compiler) taking DTS (Device Tree Source) as input, it's a build
> result and so neither of us could take.

I see, thanks for the explainer, I was referring to DeviceTree/Bindings.
I'll say binding next time.


From festevam at gmail.com  Thu Feb 22 18:43:37 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 22 Feb 2024 23:43:37 -0300
Subject: [PATCH] arm64: dts: imx93-var-som: Remove phy-supply from eqos
Message-ID: <20240223024337.1138755-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

Per nxp,dwmac-imx.yaml, phy-supply is not a valid property. 

Remove it to fix the following dt-schema warning:

imx93-var-som-symphony.dtb: ethernet at 428a0000: Unevaluated properties are not allowed ('phy-supply' was unexpected)
	from schema $id: http://devicetree.org/schemas/net/nxp,dwmac-imx.yaml#

The reg_eqos_phy regulator is marked as 'regulator-always-on', so it is
safe to remove the phy-supply property.

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
 arch/arm64/boot/dts/freescale/imx93-var-som.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi
index 8210d1f63c31..783938245e4f 100644
--- a/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi
@@ -39,7 +39,6 @@ &eqos {
 	pinctrl-0 = <&pinctrl_eqos>;
 	phy-mode = "rgmii";
 	phy-handle = <&ethphy0>;
-	phy-supply = <&reg_eqos_phy>;
 	status = "okay";
 
 	mdio {
-- 
2.34.1



From Kelly_Hung at asus.com  Thu Feb 22 18:47:25 2024
From: Kelly_Hung at asus.com (=?big5?B?S2VsbHkgSHVuZyiseLnFsvop?=)
Date: Fri, 23 Feb 2024 02:47:25 +0000
Subject: [PATCH 1/2] dt-bindings: arm: aspeed: add ASUS X4TF board
In-Reply-To: <20240222-getting-nebulizer-8f75ba8063b1@spud>
References: <20240222085914.1218037-1-Kelly_Hung@asus.com>
 <20240222-getting-nebulizer-8f75ba8063b1@spud>
Message-ID: <TYZPR04MB6596ED7F905CB53191F48A289D552@TYZPR04MB6596.apcprd04.prod.outlook.com>

External email : Ensure your email is secure before opening links and attachments.

Document the new compatibles used on ASUS X4TF.

Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
---
 Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 749ee54a3..80009948e 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -74,6 +74,7 @@ properties:
               - ampere,mtmitchell-bmc
               - aspeed,ast2600-evb
               - aspeed,ast2600-evb-a1
+              - asus,x4tf-bmc
               - facebook,bletchley-bmc
               - facebook,cloudripper-bmc
               - facebook,elbert-bmc
--
2.25.1


<p></p>

-----Original Message-----
From: Conor Dooley <conor at kernel.org>
Sent: Friday, February 23, 2024 12:02 AM
To: Kelly Hung <ppighouse at gmail.com>
Cc: robh+dt at kernel.org; krzysztof.kozlowski+dt at linaro.org; conor+dt at kernel.org; joel at jms.id.au; andrew at codeconstruct.com.au; devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-aspeed at lists.ozlabs.org; linux-kernel at vger.kernel.org; openbmc at lists.ozlabs.org; Kelly Hung(???) <Kelly_Hung at asus.com>; AllenYY Hsu(???) <AllenYY_Hsu at asus.com>
Subject: Re: [PATCH 1/2] dt-bindings: arm: aspeed: add ASUS X4TF board

On Thu, Feb 22, 2024 at 04:59:13PM +0800, Kelly Hung wrote:
> Document the new compatibles used on ASUS X4TF.

It would be good to mention here what the x4tf is - is it a bmc or an sbc etc.

Otherwise,
Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

>
> Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
> ---
>  Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> index 749ee54a3..80009948e 100644
> --- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> +++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
> @@ -74,6 +74,7 @@ properties:
>                - ampere,mtmitchell-bmc
>                - aspeed,ast2600-evb
>                - aspeed,ast2600-evb-a1
> +              - asus,x4tf
>                - facebook,bletchley-bmc
>                - facebook,cloudripper-bmc
>                - facebook,elbert-bmc
> --
> 2.25.1
>
===================================================================================================================================
This email and any attachments to it contain confidential information and are intended solely for the use of the individual to whom it is addressed. If you are not the intended recipient or receive it accidentally, please immediately notify the sender by e-mail and delete the message and any attachments from your computer system, and destroy all hard copies. Please be advised that any unauthorized disclosure, copying, distribution or any action taken or omitted in reliance on this, is illegal and prohibited. Any views or opinions expressed are solely those of the author and do not represent those of ASUSTeK.

For pricing information, ASUS is only entitled to set a recommendation resale price. All customers are free to set their own price as they wish.
===================================================================================================================================

From victor.liu at nxp.com  Thu Feb 22 18:57:38 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Fri, 23 Feb 2024 10:57:38 +0800
Subject: [PATCH] arm64: dts: imx8mp-evk: Fix hdmi@3d node
Message-ID: <20240223025738.2486807-1-victor.liu@nxp.com>

The hdmi at 3d node's compatible string is "adi,adv7535" instead of
"adi,adv7533" or "adi,adv751*".

Fix the hdmi at 3d node by means of:
* Use default register addresses for "cec", "edid" and "packet", because
  there is no need to use a non-default address map.
* Add missing interrupt related properties.
* Drop "adi,input-*" properties which are only valid for adv751*.
* Add VEXT_3V3 fixed regulator.
* Add "*-supply" properties, since most are required.
* Fix label names - s/adv7533/adv7535/.

Fixes: 65344b9bed3a ("arm64: dts: imx8mp-evk: Add HDMI support")
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 33 +++++++++++++-------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index f87fa5a948cc..9beba8d6a0df 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -23,7 +23,7 @@ hdmi-connector {
 
 		port {
 			hdmi_connector_in: endpoint {
-				remote-endpoint = <&adv7533_out>;
+				remote-endpoint = <&adv7535_out>;
 			};
 		};
 	};
@@ -107,6 +107,13 @@ reg_usdhc2_vmmc: regulator-usdhc2 {
 		enable-active-high;
 	};
 
+	reg_vext_3v3: regulator-vext-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VEXT_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
 	sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,name = "wm8960-audio";
@@ -364,7 +371,7 @@ BUCK4 {
 				regulator-always-on;
 			};
 
-			BUCK5 {
+			reg_buck5: BUCK5 {
 				regulator-name = "BUCK5";
 				regulator-min-microvolt = <1650000>;
 				regulator-max-microvolt = <1950000>;
@@ -415,14 +422,16 @@ &i2c2 {
 
 	hdmi at 3d {
 		compatible = "adi,adv7535";
-		reg = <0x3d>, <0x3c>, <0x3e>, <0x3f>;
-		reg-names = "main", "cec", "edid", "packet";
+		reg = <0x3d>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
 		adi,dsi-lanes = <4>;
-		adi,input-depth = <8>;
-		adi,input-colorspace = "rgb";
-		adi,input-clock = "1x";
-		adi,input-style = <1>;
-		adi,input-justification = "evenly";
+		avdd-supply = <&reg_buck5>;
+		dvdd-supply = <&reg_buck5>;
+		pvdd-supply = <&reg_buck5>;
+		a2vdd-supply = <&reg_buck5>;
+		v3p3-supply = <&reg_vext_3v3>;
+		v1p2-supply = <&reg_buck5>;
 
 		ports {
 			#address-cells = <1>;
@@ -431,7 +440,7 @@ ports {
 			port at 0 {
 				reg = <0>;
 
-				adv7533_in: endpoint {
+				adv7535_in: endpoint {
 					remote-endpoint = <&dsi_out>;
 				};
 			};
@@ -439,7 +448,7 @@ adv7533_in: endpoint {
 			port at 1 {
 				reg = <1>;
 
-				adv7533_out: endpoint {
+				adv7535_out: endpoint {
 					remote-endpoint = <&hdmi_connector_in>;
 				};
 			};
@@ -524,7 +533,7 @@ port at 1 {
 			reg = <1>;
 
 			dsi_out: endpoint {
-				remote-endpoint = <&adv7533_in>;
+				remote-endpoint = <&adv7535_in>;
 				data-lanes = <1 2 3 4>;
 			};
 		};
-- 
2.37.1



From sudeep.holla at arm.com  Thu Feb 22 19:32:48 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 23 Feb 2024 03:32:48 +0000
Subject: [GIT PULL] firmware: arm_ffa: Update for v6.9
Message-ID: <20240223033250.117878-1-sudeep.holla@arm.com>

Hi ARM SoC Team,

Please pull !

Regards,
Sudeep

-->8

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/ffa-update-6.9

for you to fetch changes up to 989e8661dc45babf43070d519011dfc1e33c8875:

  firmware: arm_ffa: Make ffa_bus_type const (2024-02-20 06:40:34 +0000)

----------------------------------------------------------------
Arm FF-A update for v6.9

Another single and simple update to just constify the ffa_bus_type
structure similar to other changes done treewide following the driver
core changes to accomodate the same.

----------------------------------------------------------------
Ricardo B. Marliere (1):
      firmware: arm_ffa: Make ffa_bus_type const

 drivers/firmware/arm_ffa/bus.c | 2 +-
 include/linux/arm_ffa.h        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)


From sudeep.holla at arm.com  Thu Feb 22 19:33:06 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 23 Feb 2024 03:33:06 +0000
Subject: [GIT PULL] ARM: vexpress: Update for v6.9
Message-ID: <20240223033307.117906-1-sudeep.holla@arm.com>

Hi ARM SoC Team,

Please pull !

Regards,
Sudeep

-->8

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/vexpress-update-6.9

for you to fetch changes up to bd2cb11fd765f4acc04fc47a4b2a38686890738a:

  ARM: dts: vexpress: Set stdout-path to serial0 in the chosen node (2024-02-15 11:14:51 +0000)

----------------------------------------------------------------
Arm Vexpress update for v6.9

Just a single update to add stdout-path in the device tree chosen node
so that the system console can be routed to this serial/uart port.

----------------------------------------------------------------
Ole P. Orhagen (1):
      ARM: dts: vexpress: Set stdout-path to serial0 in the chosen node

 arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)


From sudeep.holla at arm.com  Thu Feb 22 19:34:13 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 23 Feb 2024 03:34:13 +0000
Subject: [PATCH] MAINTAINERS: Update SCMI entry with HWMON driver
In-Reply-To: <20240222193027.920006-1-florian.fainelli@broadcom.com>
References: <20240222193027.920006-1-florian.fainelli@broadcom.com>
Message-ID: <170865920980.117930.1362332661461808684.b4-ty@arm.com>

On Thu, 22 Feb 2024 11:30:27 -0800, Florian Fainelli wrote:
> scmi-hwmon.c is tightly coupled with the SCMI subsystem, fold it under
> the SCMI subsystem MAINTAINERS umbrella.
>
>

Applied to sudeep.holla/linux (for-linux-next), thanks!

[1/1] MAINTAINERS: Update SCMI entry with HWMON driver
      https://git.kernel.org/sudeep.holla/c/c2f0961a45c4
--
Regards,
Sudeep



From sudeep.holla at arm.com  Thu Feb 22 19:34:33 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 23 Feb 2024 03:34:33 +0000
Subject: [GIT PULL] firmware: arm_scmi: Updates for v6.9
Message-ID: <20240223033435.118028-1-sudeep.holla@arm.com>

Hi ARM SoC Team,

Please pull !

Sorry for the delayed pull request, was waiting for Ack from clk
maintainers for some trivial changes but Stephen had some comments/
discussion on one of them, so dropped all clk changes due to dependencies.
All the other changes are in -next for a while now.

Regards,
Sudeep

-->8

The following changes since commit 6bd1b3fede83d8ba5314886062a9bfdada5102a9:

  firmware: arm_scmi: Fix the clock protocol supported version (2024-01-22 10:01:17 +0000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/scmi-updates-6.9

for you to fetch changes up to c2f0961a45c4a973437285871540c155bed18ccb:

  MAINTAINERS: Update SCMI entry with HWMON driver (2024-02-23 02:01:13 +0000)

----------------------------------------------------------------
Arm SCMI updates for v6.9

Quite a few changes to extend support to SCMI v3.2 specification,
to enhance notification handling and other miscellaneous updates.

1. Enhancements to notification handling

   Until now, trying to register a notifier for an unsuppported
   notification returned an error genrating unneeded message exchanges
   with the SCMI platform. This can be avoided by looking up in advance
   the specific protocol and resources available.

   With these changes SCMI driver user will fail to register a notifier
   if the related command or resource is not supported (like before)
   without the need of exchanging any message.

   Perf notifications are also extended to provide the pre-calculated
   frequencies corresponding to the level or index carried by the

2. More SCMI v3.2 related updates

   One of the main addition includes a centralized support to the SCMI
   core to handle v3.2 optional protocol version negotiation, so that
   at protocol initialization time, if the platform advertised version
   is newer than supported by the kernel and protocol version negotiation
   is supported, the SCMI core will attempt to negotiate an older protocol
   version.

   It also includes the clock get permissions which indicates if any of
   the clock operations are forbidden by the platform for the OSPM agent.
   It can be used in the clock driver to avoid unnecessary message
   exchanges between the kernel and the platform which will always end
   up with the failure. It also includes other missing bits of clock
   v3.2 protocol so that the supported protocol version can be bumped
   to 0x30000 (v3.2).

3. Miscellaneous updates

   This includes addition of warning if the domain frequency multiplier
   is 0 or rounded off to indicate the actual frequencies are either
   wrong ot rounded off, hardening of clock domain info lookups, addition
   of multiple protocols registration support within a SCMI driver,
   update to SCMI entry in MAINTAINERS to include HWMON driver and
   constifying the scmi_bus_type structure.

   This also includes couple for fixes to minor issues: double free in
   SMC transport cleanup path and struct kernel-doc warnings in optee
   transport.

----------------------------------------------------------------
Andre Przywara (1):
      firmware: arm_scmi: Fix double free in SMC transport cleanup path

Cristian Marussi (17):
      firmware: arm_scmi: Rework clock domain info lookups
      firmware: arm_scmi: Add multiple protocols registration support
      firmware: arm_scmi: Check for notification support
      firmware: arm_scmi: Add a common helper to check if a message is supported
      firmware: arm_scmi: Implement is_notify_supported callback in perf protocol
      firmware: arm_scmi: Implement is_notify_supported callback in power protocol
      firmware: arm_scmi: Implement is_notify_supported callback in system power protocol
      firmware: arm_scmi: Implement is_notify_supported callback in clock protocol
      firmware: arm_scmi: Implement is_notify_supported callback in sensor protocol
      firmware: arm_scmi: Implement is_notify_supported callback in reset protocol
      firmware: arm_scmi: Implement is_notify_supported callback in powercap protocol
      firmware: arm_scmi: Use opps_by_lvl to store opps
      firmware: arm_scmi: Report frequencies in the perf notifications
      firmware: arm_scmi: Add support for v3.2 NEGOTIATE_PROTOCOL_VERSION
      firmware: arm_scmi: Add clock check for extended config support
      firmware: arm_scmi: Add standard clock OEM definitions
      firmware: arm_scmi: Update the supported clock protocol version

Florian Fainelli (1):
      MAINTAINERS: Update SCMI entry with HWMON driver

Peng Fan (1):
      firmware: arm_scmi: Implement clock get permissions

Randy Dunlap (1):
      firmware: arm_scmi: Fix struct kernel-doc warnings in optee transport

Ricardo B. Marliere (1):
      firmware: arm_scmi: Make scmi_bus_type const

Sudeep Holla (1):
      firmware: arm_scmi: Warn if domain frequency multiplier is 0 or rounded off

 MAINTAINERS                           |   1 +
 drivers/firmware/arm_scmi/bus.c       |  26 ++++-
 drivers/firmware/arm_scmi/clock.c     | 194 +++++++++++++++++++++++++++++-----
 drivers/firmware/arm_scmi/common.h    |   2 +-
 drivers/firmware/arm_scmi/driver.c    |  99 ++++++++++++++++-
 drivers/firmware/arm_scmi/notify.c    |  17 ++-
 drivers/firmware/arm_scmi/notify.h    |   4 +
 drivers/firmware/arm_scmi/optee.c     |   6 +-
 drivers/firmware/arm_scmi/perf.c      | 163 +++++++++++++++++++++++++---
 drivers/firmware/arm_scmi/power.c     |  30 +++++-
 drivers/firmware/arm_scmi/powercap.c  |  45 +++++++-
 drivers/firmware/arm_scmi/protocols.h |   5 +
 drivers/firmware/arm_scmi/reset.c     |  37 +++++--
 drivers/firmware/arm_scmi/sensors.c   |  37 ++++++-
 drivers/firmware/arm_scmi/smc.c       |   7 ++
 drivers/firmware/arm_scmi/system.c    |  16 +++
 include/linux/scmi_protocol.h         |  21 +++-
 17 files changed, 635 insertions(+), 75 deletions(-)


From william.zhang at broadcom.com  Thu Feb 22 19:35:12 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:35:12 -0800
Subject: [PATCH v5 09/12] mtd: rawnand: brcmnand: Add support for getting
 ecc setting from strap
In-Reply-To: <20240220105313.5e3c600d@xps-13>
References: <20240207202257.271784-1-william.zhang@broadcom.com>
 <20240207202257.271784-10-william.zhang@broadcom.com>
 <20240220105313.5e3c600d@xps-13>
Message-ID: <cc0e98e4-b92f-4da5-879d-7535e787b98f@broadcom.com>

Hi Miquel,

On 2/20/24 01:53, Miquel Raynal wrote:
> Hi William,
> 
> william.zhang at broadcom.com wrote on Wed,  7 Feb 2024 12:22:54 -0800:
> 
>> BCMBCA broadband SoC based board design does not specify ecc setting in
>> dts but rather use the SoC NAND strap info to obtain the ecc strength
>> and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
>> this purpose and update driver to support this option.
>>
>> The generic nand ecc settings still take precedence over this flag. For
>> example, if nand-ecc-strength is set in the dts, the driver ignores the
>> strap setting and falls back to original behavior. This makes sure that
>> the existing BCMBCA board dts still works the old way even the strap
>> flag is set in the BCMBCA chip dtsi.
>>
>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>> Reviewed-by: David Regan <dregan at broadcom.com>
>>
>> ---
>>
>> Changes in v5: None
>> Changes in v4:
>> - Update the comments for ecc setting selection
>>
>> Changes in v3: None
>> Changes in v2:
>> - Minor cosmetic fixes
>>
>>   drivers/mtd/nand/raw/brcmnand/brcmnand.c | 83 ++++++++++++++++++++++--
>>   1 file changed, 76 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
>> index 73fdf7ce21aa..efeee9e80213 100644
>> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
>> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
>> @@ -1038,6 +1038,19 @@ static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl)
>>   		return -1;
>>   }
>>   
>> +static int brcmnand_get_sector_size_1k(struct brcmnand_host *host)
>> +{
>> +	struct brcmnand_controller *ctrl = host->ctrl;
>> +	int shift = brcmnand_sector_1k_shift(ctrl);
>> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
>> +						  BRCMNAND_CS_ACC_CONTROL);
>> +
>> +	if (shift < 0)
>> +		return 0;
>> +
>> +	return (nand_readreg(ctrl, acc_control_offs) >> shift) & 0x1;
> 
> What is this & 0x1 ? If you return a yes/no value, please make this
> function return a bool. Also, please use intermediate steps to clarify
> what you do.
> 
> sector_1k_bit = ...;
> acc = nand_readreg();
> return acc & BIT(sector_1k_bit);
> 
> Or something like that.
> 
This sector 1k bit is just single bit field. But we do want to return 
negative for error condition and 0 for 512 sector and 1 for 1K sector 
size. Will add intermediate steps.

>> +}
>> +
>>   static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
>>   {
>>   	struct brcmnand_controller *ctrl = host->ctrl;
>> @@ -1055,6 +1068,38 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
>>   	nand_writereg(ctrl, acc_control_offs, tmp);
>>   }
>>   
>> +static int brcmnand_get_spare_size(struct brcmnand_host *host)
>> +{
>> +	struct brcmnand_controller *ctrl = host->ctrl;
>> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
>> +						  BRCMNAND_CS_ACC_CONTROL);
>> +	u32 acc = nand_readreg(ctrl, acc_control_offs);
>> +
>> +	return (acc & brcmnand_spare_area_mask(ctrl));
>> +}
>> +
>> +static int brcmnand_get_ecc_strength(struct brcmnand_host *host)
> 
> 					_from_strap
> 
>> +{
>> +	struct brcmnand_controller *ctrl = host->ctrl;
>> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
>> +						  BRCMNAND_CS_ACC_CONTROL);
>> +	int sector_size_1k = brcmnand_get_sector_size_1k(host);
>> +	int spare_area_size, ecc_level, ecc_strength;
>> +	u32 acc;
>> +
>> +	spare_area_size = brcmnand_get_spare_size(host);
>> +	acc = nand_readreg(ctrl, acc_control_offs);
>> +	ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl->ecc_level_shift;
> 
> Please use FIELD_PREP/FIELD_GET.
> 
These macros do not work here as the mask is not constant.

>> +	if (sector_size_1k)
>> +		ecc_strength = ecc_level * 2;
>> +	else if (spare_area_size == 16 && ecc_level == 15)
>> +		ecc_strength = 1; /* hamming */
>> +	else
>> +		ecc_strength = ecc_level;
>> +
>> +	return ecc_strength;
>> +}
>> +
>>   /***********************************************************************
>>    * CS_NAND_SELECT
>>    ***********************************************************************/
>> @@ -2622,19 +2667,43 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
>>   		nanddev_get_memorg(&chip->base);
>>   	struct brcmnand_controller *ctrl = host->ctrl;
>>   	struct brcmnand_cfg *cfg = &host->hwcfg;
>> -	char msg[128];
>> +	struct device_node *np = nand_get_flash_node(chip);
>>   	u32 offs, tmp, oob_sector;
>> -	int ret;
>> +	int ret, sector_size_1k = 0;
>> +	bool use_strap = false;
>> +	char msg[128];
>>   
>>   	memset(cfg, 0, sizeof(*cfg));
>> +	use_strap = of_property_read_bool(np, "brcm,nand-ecc-use-strap");
>>   
>> -	ret = of_property_read_u32(nand_get_flash_node(chip),
>> -				   "brcm,nand-oob-sector-size",
>> +	/*
>> +	 * Set ECC size and strength based on hw configuration from strap
>> +	 * if brcm,nand-ecc-use-strap is set. However if nand-ecc-strength
>> +	 * is set, its value will be used and ignore the strap setting.
> 
> Please error out in this case. It's one or the other, not both.
> 
Will update.

>> +	 */
>> +	if (chip->ecc.strength)
>> +		use_strap = 0;
>> +
>> +	if (use_strap) {
>> +		chip->ecc.strength = brcmnand_get_ecc_strength(host);
>> +		sector_size_1k = brcmnand_get_sector_size_1k(host);
>> +		if (chip->ecc.size == 0) {
>> +			if (sector_size_1k < 0)
>> +				chip->ecc.size = 512;
>> +			else
>> +				chip->ecc.size = 512 << sector_size_1k;
>> +		}
> 
> I'd instead make a function named brcmnand_get_ecc_settings() with the
> chip->ecc parameter, so you can directly fill the entries without
> getting another time the sector_size_1k thing.
> 
> Strength and step size are tightly linked, it does make sense to derive
> them both at the same time.
> 
Will update.

>> +	}
>> +
>> +	ret = of_property_read_u32(np, "brcm,nand-oob-sector-size",
>>   				   &oob_sector);
>>   	if (ret) {
>> -		/* Use detected size */
>> -		cfg->spare_area_size = mtd->oobsize /
>> -					(mtd->writesize >> FC_SHIFT);
>> +		if (use_strap)
>> +			cfg->spare_area_size = brcmnand_get_spare_size(host);
>> +		else
>> +			/* Use detected size */
>> +			cfg->spare_area_size = mtd->oobsize /
>> +						(mtd->writesize >> FC_SHIFT);
>>   	} else {
>>   		cfg->spare_area_size = oob_sector;
>>   	}
> 
> 
> Thanks,
> Miqu?l
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240222/d8ae51c8/attachment.p7s>

From william.zhang at broadcom.com  Thu Feb 22 19:47:46 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:46 -0800
Subject: [PATCH v6 01/13] mtd: rawnand: brcmnand: exec_op helper functions return type fixes
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-2-william.zhang@broadcom.com>

From: David Regan <dregan at broadcom.com>

Fix return types for exec_op reset and status helper functions.

Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
Signed-off-by: David Regan <dregan at broadcom.com>
Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v6:
- Moved style fixes to a separate patch

Changes in v5: None
Changes in v4:
- Fix the commit id in the fixes tag

Changes in v3: None
Changes in v2:
- Added to patch series

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 8faca43ae1ff..b8e70fc64348 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -625,7 +625,7 @@ enum {
 /* Only for v7.2 */
 #define	ACC_CONTROL_ECC_EXT_SHIFT		13
 
-static u8 brcmnand_status(struct brcmnand_host *host);
+static int brcmnand_status(struct brcmnand_host *host);
 
 static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
 {
@@ -1690,7 +1690,7 @@ static int brcmnand_waitfunc(struct nand_chip *chip)
 				 INTFC_FLASH_STATUS;
 }
 
-static u8 brcmnand_status(struct brcmnand_host *host)
+static int brcmnand_status(struct brcmnand_host *host)
 {
 	struct nand_chip *chip = &host->chip;
 	struct mtd_info *mtd = nand_to_mtd(chip);
@@ -1701,7 +1701,7 @@ static u8 brcmnand_status(struct brcmnand_host *host)
 	return brcmnand_waitfunc(chip);
 }
 
-static u8 brcmnand_reset(struct brcmnand_host *host)
+static int brcmnand_reset(struct brcmnand_host *host)
 {
 	struct nand_chip *chip = &host->chip;
 
@@ -2433,7 +2433,11 @@ static int brcmnand_exec_op(struct nand_chip *chip,
 
 	if (brcmnand_op_is_status(op)) {
 		status = op->instrs[1].ctx.data.buf.in;
-		*status = brcmnand_status(host);
+		ret = brcmnand_status(host);
+		if (ret < 0)
+			return ret;
+
+		*status = ret & 0xFF;
 
 		return 0;
 	}
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:45 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:45 -0800
Subject: [PATCH v6 00/13] mtd: rawnand: brcmnand: driver and doc updates
Message-ID: <20240223034758.13753-1-william.zhang@broadcom.com>

This patch series is an update from the previous version [1] after
exex_op support and fixes (patch 1 to 4 from the previous version.)

It updates all the BCMBCA SoC to support the nand controller and add
functions to handle BCMBCA specific needs on ECC and Write Protection
usage. The device tree document is also updated accordingly with the new
properties needed by the driver.

In addition there is a bug fix for exec_op helper functions, log level
adjustment on uncorrectable ECC error and some coding style fixes.

[1] https://lore.kernel.org/lkml/20230606231252.94838-1-william.zhang at broadcom.com/

Changes in v6:
- Moved style fixes to a separate patch
- Fix style issue
- Add reviewed-by tags
- Add other nand ecc properties to the exclude check list
- Update the brcm,nand-ecc-use-strap property description
- Combine the ecc step size and ecc strength into one get function
- Treat it as error condition if both brcm,nand-ecc-use-strap and nand
ecc dts properties are set
- Add intermediate steps to get the sector size bitfield

Changes in v5:
- Update the commit message
- Add reviewed-by tag
- Update the description of this new property
- Update the description for this ecc strap property
- Add check to make sure brcm,nand-ecc-use-strap and
  nand-ecc-strength/brcm,nand-oob-sector-size can not be used at the
  same time

Changes in v4:
- Fix the commit id in the fixes tag
- Revert the log level change for correctable ecc error
- Split the yaml changes into three patches. This is the first one
- Move the WP pin property to this separate patch and change it to
boolean type.
- Move ecc strap property to this separate patch and remove some
non-binding related text from the description
- Move the board related dts setting from SoC dtsi to board dts
- Move the board related dts setting from SoC dtsi to board dts
- Update the comments for ecc setting selection
- Use the new brcm,wp-not-connected property based on the dts binding
change

Changes in v3:
- Update brcm,nand-use-wp description
- Revert the description change to BCM63168 SoC-specific NAND controller
- Updated bcmbca_read_data_bus comment

Changes in v2:
- Added to patch series
- Added to patch series
- Revert the new compatible string nand-bcmbca
- Drop the BCM63168 compatible fix to avoid any potential ABI
incompatibility issue
- Simplify the explanation for brcm,nand-use-wp
- Keep the interrupt name requirement when interrupt number is specified
- Add nand controller node label for 4908 so it is consistent with other
SoCs and can be referenced by board dts file
- Drop the is_param argument to the read data bus function now that we
have the exec_op API to read the parameter page and ONFI data
- Remove be32_to_cpu from brcmnand_read_data_bus
- Minor cosmetic fixes

David Regan (2):
  mtd: rawnand: brcmnand: exec_op helper functions return type fixes
  mtd: rawnand: brcmnand: update log level messages

William Zhang (11):
  mtd: rawnand: brcmnand: fix style issues
  dt-bindings: mtd: brcmnand: Updates for bcmbca SoCs
  dt-bindings: mtd: brcmnand: Add WP pin connection property
  dt-bindings: mtd: brcmnand: Add ecc strap property
  ARM: dts: broadcom: bcmbca: Add NAND controller node
  arm64: dts: broadcom: bcmbca: Add NAND controller node
  arm64: dts: broadcom: bcmbca: Update router boards
  mtd: rawnand: brcmnand: Rename bcm63138 nand driver
  mtd: rawnand: brcmnand: Add BCMBCA read data bus interface
  mtd: rawnand: brcmnand: Add support for getting ecc setting from strap
  mtd: rawnand: brcmnand: Support write protection setting from dts

 .../bindings/mtd/brcm,brcmnand.yaml           |  44 +++++-
 arch/arm/boot/dts/broadcom/bcm47622.dtsi      |  14 ++
 arch/arm/boot/dts/broadcom/bcm63138.dtsi      |   7 +-
 arch/arm/boot/dts/broadcom/bcm63148.dtsi      |  14 ++
 arch/arm/boot/dts/broadcom/bcm63178.dtsi      |  14 ++
 arch/arm/boot/dts/broadcom/bcm6756.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm6846.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm6855.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm6878.dtsi       |  14 ++
 arch/arm/boot/dts/broadcom/bcm947622.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm963138.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm963138dvt.dts   |  14 +-
 arch/arm/boot/dts/broadcom/bcm963148.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm963178.dts      |  10 ++
 arch/arm/boot/dts/broadcom/bcm96756.dts       |  10 ++
 arch/arm/boot/dts/broadcom/bcm96846.dts       |  10 ++
 arch/arm/boot/dts/broadcom/bcm96855.dts       |  10 ++
 arch/arm/boot/dts/broadcom/bcm96878.dts       |  10 ++
 .../bcmbca/bcm4906-netgear-r8000p.dts         |   5 +
 .../bcmbca/bcm4906-tplink-archer-c2300-v1.dts |   5 +
 .../bcmbca/bcm4908-asus-gt-ac5300.dts         |   6 +-
 .../boot/dts/broadcom/bcmbca/bcm4908.dtsi     |   4 +-
 .../boot/dts/broadcom/bcmbca/bcm4912.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm63146.dtsi    |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm63158.dtsi    |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm6813.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm6856.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm6858.dtsi     |  14 ++
 .../boot/dts/broadcom/bcmbca/bcm94908.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm94912.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm963146.dts    |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm963158.dts    |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm96813.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm96856.dts     |  10 ++
 .../boot/dts/broadcom/bcmbca/bcm96858.dts     |  10 ++
 drivers/mtd/nand/raw/brcmnand/Makefile        |   2 +-
 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c |  99 ------------
 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c   | 126 +++++++++++++++
 drivers/mtd/nand/raw/brcmnand/brcmnand.c      | 148 ++++++++++++++----
 drivers/mtd/nand/raw/brcmnand/brcmnand.h      |   2 +
 40 files changed, 650 insertions(+), 144 deletions(-)
 delete mode 100644 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
 create mode 100644 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c

-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:48 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:48 -0800
Subject: [PATCH v6 03/13] mtd: rawnand: brcmnand: update log level messages
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-4-william.zhang@broadcom.com>

From: David Regan <dregan at broadcom.com>

Update log level messages so that more critical messages can be logged
to console and help the troubleshooting with field devices.

Signed-off-by: David Regan <dregan at broadcom.com>
Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v6:
- Fix style issue

Changes in v5:
- Update the commit message

Changes in v4:
- Revert the log level change for correctable ecc error

Changes in v3: None
Changes in v2:
- Added to patch series

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 5f34e5a51d25..f1f0de50b5f7 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1084,8 +1084,8 @@ static int bcmnand_ctrl_poll_status(struct brcmnand_host *host,
 	if ((val & mask) == expected_val)
 		return 0;
 
-	dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
-		 expected_val, val & mask);
+	dev_err(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
+		expected_val, val & mask);
 
 	return -ETIMEDOUT;
 }
@@ -2137,7 +2137,7 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
 				return err;
 		}
 
-		dev_dbg(ctrl->dev, "uncorrectable error at 0x%llx\n",
+		dev_err(ctrl->dev, "uncorrectable error at 0x%llx\n",
 			(unsigned long long)err_addr);
 		mtd->ecc_stats.failed++;
 		/* NAND layer expects zero on ECC errors */
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:49 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:49 -0800
Subject: [PATCH v6 04/13] dt-bindings: mtd: brcmnand: Updates for bcmbca SoCs
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-5-william.zhang@broadcom.com>

Update the descriptions to reflect different families of broadband SoC and
use the general name bcmbca for ARM based SoC.

Remove the requirement of interrupts property to reflect the driver
code and only require interrupt-names when interrupts property present.

Also add myself to the list of maintainers.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>

---

Changes in v6:
- Add reviewed-by tag

Changes in v5:
- Add reviewed-by tag

Changes in v4:
- Split the yaml changes into three patches. This is the first one

Changes in v3:
- Update brcm,nand-use-wp description
- Revert the description change to BCM63168 SoC-specific NAND controller

Changes in v2:
- Revert the new compatible string nand-bcmbca
- Drop the BCM63168 compatible fix to avoid any potential ABI
incompatibility issue
- Simplify the explanation for brcm,nand-use-wp
- Keep the interrupt name requirement when interrupt number is specified

 .../devicetree/bindings/mtd/brcm,brcmnand.yaml      | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
index f57e96374e67..e54ca08a798a 100644
--- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
+++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
@@ -9,6 +9,7 @@ title: Broadcom STB NAND Controller
 maintainers:
   - Brian Norris <computersforpeace at gmail.com>
   - Kamal Dasu <kdasu.kdev at gmail.com>
+  - William Zhang <william.zhang at broadcom.com>
 
 description: |
   The Broadcom Set-Top Box NAND controller supports low-level access to raw NAND
@@ -18,9 +19,10 @@ description: |
   supports basic PROGRAM and READ functions, among other features.
 
   This controller was originally designed for STB SoCs (BCM7xxx) but is now
-  available on a variety of Broadcom SoCs, including some BCM3xxx, BCM63xx, and
-  iProc/Cygnus. Its history includes several similar (but not fully register
-  compatible) versions.
+  available on a variety of Broadcom SoCs, including some BCM3xxx, MIPS based
+  Broadband SoC (BCM63xx), ARM based Broadband SoC (BCMBCA) and iProc/Cygnus.
+  Its history includes several similar (but not fully register compatible)
+  versions.
 
   -- Additional SoC-specific NAND controller properties --
 
@@ -53,7 +55,7 @@ properties:
               - brcm,brcmnand-v7.2
               - brcm,brcmnand-v7.3
           - const: brcm,brcmnand
-      - description: BCM63138 SoC-specific NAND controller
+      - description: BCMBCA SoC-specific NAND controller
         items:
           - const: brcm,nand-bcm63138
           - enum:
@@ -177,6 +179,8 @@ allOf:
             - const: iproc-idm
             - const: iproc-ext
   - if:
+      required:
+        - interrupts
       properties:
         interrupts:
           minItems: 2
@@ -189,7 +193,6 @@ unevaluatedProperties: false
 required:
   - reg
   - reg-names
-  - interrupts
 
 examples:
   - |
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:52 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:52 -0800
Subject: [PATCH v6 07/13] ARM: dts: broadcom: bcmbca: Add NAND controller node
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-8-william.zhang@broadcom.com>

Add support for Broadcom STB NAND controller in BCMBCA ARMv7 chip dts
files.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Move the board related dts setting from SoC dtsi to board dts

Changes in v3: None
Changes in v2: None

 arch/arm/boot/dts/broadcom/bcm47622.dtsi    | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm63138.dtsi    |  7 ++++++-
 arch/arm/boot/dts/broadcom/bcm63148.dtsi    | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm63178.dtsi    | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6756.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6846.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6855.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm6878.dtsi     | 14 ++++++++++++++
 arch/arm/boot/dts/broadcom/bcm947622.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm963138.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm963138dvt.dts | 14 +++++++-------
 arch/arm/boot/dts/broadcom/bcm963148.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm963178.dts    | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96756.dts     | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96846.dts     | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96855.dts     | 10 ++++++++++
 arch/arm/boot/dts/broadcom/bcm96878.dts     | 10 ++++++++++
 17 files changed, 191 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/broadcom/bcm47622.dtsi b/arch/arm/boot/dts/broadcom/bcm47622.dtsi
index 7cd38de118c3..485863f9c420 100644
--- a/arch/arm/boot/dts/broadcom/bcm47622.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm47622.dtsi
@@ -138,6 +138,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm63138.dtsi b/arch/arm/boot/dts/broadcom/bcm63138.dtsi
index 4ef02283612b..e74ba6bf370d 100644
--- a/arch/arm/boot/dts/broadcom/bcm63138.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63138.dtsi
@@ -229,7 +229,12 @@ nand_controller: nand-controller at 2000 {
 			reg-names = "nand", "nand-int-base";
 			status = "disabled";
 			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "nand";
+			interrupt-names = "nand_ctlrdy";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
 		};
 
 		serial at 4400 {
diff --git a/arch/arm/boot/dts/broadcom/bcm63148.dtsi b/arch/arm/boot/dts/broadcom/bcm63148.dtsi
index 24431de1810e..53703827ee3f 100644
--- a/arch/arm/boot/dts/broadcom/bcm63148.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63148.dtsi
@@ -119,5 +119,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 2000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x2000 0x600>, <0xf0 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/broadcom/bcm63178.dtsi b/arch/arm/boot/dts/broadcom/bcm63178.dtsi
index 3f9aed96babf..6d8d33498983 100644
--- a/arch/arm/boot/dts/broadcom/bcm63178.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63178.dtsi
@@ -129,6 +129,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6756.dtsi b/arch/arm/boot/dts/broadcom/bcm6756.dtsi
index 1d8d957d65dd..6433f8fa5eff 100644
--- a/arch/arm/boot/dts/broadcom/bcm6756.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6756.dtsi
@@ -139,6 +139,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6846.dtsi b/arch/arm/boot/dts/broadcom/bcm6846.dtsi
index cf92cf8c4693..ee361cb00b7c 100644
--- a/arch/arm/boot/dts/broadcom/bcm6846.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6846.dtsi
@@ -119,5 +119,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/broadcom/bcm6855.dtsi b/arch/arm/boot/dts/broadcom/bcm6855.dtsi
index 52d6bc89f9f8..52915ec6f339 100644
--- a/arch/arm/boot/dts/broadcom/bcm6855.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6855.dtsi
@@ -129,6 +129,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6878.dtsi b/arch/arm/boot/dts/broadcom/bcm6878.dtsi
index 2c5d706bac7e..70cf23a65fdb 100644
--- a/arch/arm/boot/dts/broadcom/bcm6878.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6878.dtsi
@@ -120,6 +120,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm947622.dts b/arch/arm/boot/dts/broadcom/bcm947622.dts
index 93b8ce22678d..6241485408d3 100644
--- a/arch/arm/boot/dts/broadcom/bcm947622.dts
+++ b/arch/arm/boot/dts/broadcom/bcm947622.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963138.dts b/arch/arm/boot/dts/broadcom/bcm963138.dts
index 1b405c249213..7fd87e05ec20 100644
--- a/arch/arm/boot/dts/broadcom/bcm963138.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963138.dts
@@ -29,3 +29,13 @@ &serial0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963138dvt.dts b/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
index b5af61853a07..f60d09908ab9 100644
--- a/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
@@ -32,15 +32,15 @@ &serial1 {
 };
 
 &nand_controller {
+	brcm,wp-not-connected;
 	status = "okay";
+};
 
-	nand at 0 {
-		compatible = "brcm,nandcs";
-		reg = <0>;
-		nand-ecc-strength = <4>;
-		nand-ecc-step-size = <512>;
-		brcm,nand-oob-sectors-size = <16>;
-	};
+&nandcs {
+	nand-ecc-strength = <4>;
+	nand-ecc-step-size = <512>;
+	brcm,nand-oob-sector-size = <16>;
+	nand-on-flash-bbt;
 };
 
 &ahci {
diff --git a/arch/arm/boot/dts/broadcom/bcm963148.dts b/arch/arm/boot/dts/broadcom/bcm963148.dts
index 1f5d6d783f09..44bca063a327 100644
--- a/arch/arm/boot/dts/broadcom/bcm963148.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963148.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963178.dts b/arch/arm/boot/dts/broadcom/bcm963178.dts
index d036e99dd8d1..098a222cd71a 100644
--- a/arch/arm/boot/dts/broadcom/bcm963178.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963178.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96756.dts b/arch/arm/boot/dts/broadcom/bcm96756.dts
index 8b104f3fb14a..402038d3cd0c 100644
--- a/arch/arm/boot/dts/broadcom/bcm96756.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96756.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96846.dts b/arch/arm/boot/dts/broadcom/bcm96846.dts
index 55852c229608..943896afb7cc 100644
--- a/arch/arm/boot/dts/broadcom/bcm96846.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96846.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96855.dts b/arch/arm/boot/dts/broadcom/bcm96855.dts
index 2ad880af2104..571663d9a1ea 100644
--- a/arch/arm/boot/dts/broadcom/bcm96855.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96855.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96878.dts b/arch/arm/boot/dts/broadcom/bcm96878.dts
index b7af8ade7a9d..8d6eddd54c6e 100644
--- a/arch/arm/boot/dts/broadcom/bcm96878.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96878.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:53 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:53 -0800
Subject: [PATCH v6 08/13] arm64: dts: broadcom: bcmbca: Add NAND controller node
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-9-william.zhang@broadcom.com>

Add support for Broadcom STB NAND controller in BCMBCA ARMv8 chip dts
files.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Move the board related dts setting from SoC dtsi to board dts

Changes in v3: None
Changes in v2:
- Add nand controller node label for 4908 so it is consistent with other
SoCs and can be referenced by board dts file

 arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi  |  4 ++--
 arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi  | 14 ++++++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts  | 10 ++++++++++
 arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts  | 10 ++++++++++
 14 files changed, 156 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
index 2f124b027bbf..336016e334d9 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
@@ -589,7 +589,7 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
-		nand-controller at 1800 {
+		nand_controller: nand-controller at 1800 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
@@ -597,7 +597,7 @@ nand-controller at 1800 {
 			reg-names = "nand", "nand-int-base";
 			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "nand_ctlrdy";
-			status = "okay";
+			status = "disabled";
 
 			nandcs: nand at 0 {
 				compatible = "brcm,nandcs";
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
index d658c81f7285..14b2adfb817c 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
@@ -138,6 +138,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
index 4f474d47022e..589b8a1efc72 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
@@ -119,6 +119,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
index 909f254dc47d..48d618e75866 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
@@ -137,6 +137,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
index 685ae32951c9..1d1303cf90f3 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
@@ -138,6 +138,20 @@ hsspi: spi at 1000 {
 			status = "disabled";
 		};
 
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
+
 		uart0: serial at 12000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
index 820553ce541b..00c62c1e5df0 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
@@ -119,5 +119,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
index 0eb93c298297..caeaf428dc15 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
@@ -156,5 +156,19 @@ hsspi: spi at 1000 {
 			num-cs = <8>;
 			status = "disabled";
 		};
+
+		nand_controller: nand-controller at 1800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+			reg = <0x1800 0x600>, <0x2000 0x10>;
+			reg-names = "nand", "nand-int-base";
+			status = "disabled";
+
+			nandcs: nand at 0 {
+				compatible = "brcm,nandcs";
+				reg = <0>;
+			};
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
index c4e6e71f6310..030ffa5364fb 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
index e69cd683211a..4b779e6c22e1 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
index db2c82d6dfd8..2851e8e41bf4 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
index 25c12bc63545..17dc594fe83f 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
index faba21f03120..34832a734734 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
index 9808331eede2..e1396b5544b7 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
index 1f561c8e13b0..30bbf6f2917e 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
@@ -32,3 +32,13 @@ &uart0 {
 &hsspi {
 	status = "okay";
 };
+
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
+&nandcs {
+	nand-on-flash-bbt;
+	brcm,nand-ecc-use-strap;
+};
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:56 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:56 -0800
Subject: [PATCH v6 11/13] mtd: rawnand: brcmnand: Add BCMBCA read data bus interface
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-12-william.zhang@broadcom.com>

The BCMBCA broadband SoC integrates the NAND controller differently than
STB, iProc and other SoCs.  It has different endianness for NAND cache
data.

Add a SoC read data bus shim for BCMBCA to meet the specific SoC need
and performance improvement using the optimized memcpy function on NAND
cache memory.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v6:
- Fix style issue

Changes in v5: None
Changes in v4: None
Changes in v3:
- Updated bcmbca_read_data_bus comment

Changes in v2:
- Drop the is_param argument to the read data bus function now that we
have the exec_op API to read the parameter page and ONFI data
- Remove be32_to_cpu from brcmnand_read_data_bus

 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c | 27 +++++++++++++++++++++
 drivers/mtd/nand/raw/brcmnand/brcmnand.c    | 20 ++++++++++++---
 drivers/mtd/nand/raw/brcmnand/brcmnand.h    |  2 ++
 3 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
index 3e2f3b79788d..7ad3e7a98f97 100644
--- a/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
+++ b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
@@ -26,6 +26,18 @@ enum {
 	BCMBCA_CTLRDY		= BIT(4),
 };
 
+#if defined(CONFIG_ARM64)
+#define ALIGN_REQ		8
+#else
+#define ALIGN_REQ		4
+#endif
+
+static inline bool bcmbca_nand_is_buf_aligned(void *flash_cache,  void *buffer)
+{
+	return IS_ALIGNED((uintptr_t)buffer, ALIGN_REQ) &&
+				IS_ALIGNED((uintptr_t)flash_cache, ALIGN_REQ);
+}
+
 static bool bcmbca_nand_intc_ack(struct brcmnand_soc *soc)
 {
 	struct bcmbca_nand_soc *priv =
@@ -56,6 +68,20 @@ static void bcmbca_nand_intc_set(struct brcmnand_soc *soc, bool en)
 	brcmnand_writel(val, mmio);
 }
 
+static void bcmbca_read_data_bus(struct brcmnand_soc *soc,
+				 void __iomem *flash_cache,  u32 *buffer, int fc_words)
+{
+	/*
+	 * memcpy can do unaligned aligned access depending on source
+	 * and dest address, which is incompatible with nand cache. Fallback
+	 * to the memcpy_fromio in such case
+	 */
+	if (bcmbca_nand_is_buf_aligned((void *)flash_cache, buffer))
+		memcpy((void *)buffer, (void *)flash_cache, fc_words * 4);
+	else
+		memcpy_fromio((void *)buffer, flash_cache, fc_words * 4);
+}
+
 static int bcmbca_nand_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -73,6 +99,7 @@ static int bcmbca_nand_probe(struct platform_device *pdev)
 
 	soc->ctlrdy_ack = bcmbca_nand_intc_ack;
 	soc->ctlrdy_set_enabled = bcmbca_nand_intc_set;
+	soc->read_data_bus = bcmbca_read_data_bus;
 
 	return brcmnand_probe(pdev, soc);
 }
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index f1f0de50b5f7..ef7d340475be 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -851,6 +851,20 @@ static inline u32 edu_readl(struct brcmnand_controller *ctrl,
 	return brcmnand_readl(ctrl->edu_base + offs);
 }
 
+static inline void brcmnand_read_data_bus(struct brcmnand_controller *ctrl,
+					  void __iomem *flash_cache, u32 *buffer, int fc_words)
+{
+	struct brcmnand_soc *soc = ctrl->soc;
+	int i;
+
+	if (soc->read_data_bus) {
+		soc->read_data_bus(soc, flash_cache, buffer, fc_words);
+	} else {
+		for (i = 0; i < fc_words; i++)
+			buffer[i] = brcmnand_read_fc(ctrl, i);
+	}
+}
+
 static void brcmnand_clear_ecc_addr(struct brcmnand_controller *ctrl)
 {
 
@@ -1975,7 +1989,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	struct brcmnand_host *host = nand_get_controller_data(chip);
 	struct brcmnand_controller *ctrl = host->ctrl;
-	int i, j, ret = 0;
+	int i, ret = 0;
 
 	brcmnand_clear_ecc_addr(ctrl);
 
@@ -1988,8 +2002,8 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
 		if (likely(buf)) {
 			brcmnand_soc_data_bus_prepare(ctrl->soc, false);
 
-			for (j = 0; j < FC_WORDS; j++, buf++)
-				*buf = brcmnand_read_fc(ctrl, j);
+			brcmnand_read_data_bus(ctrl, ctrl->nand_fc, buf, FC_WORDS);
+			buf += FC_WORDS;
 
 			brcmnand_soc_data_bus_unprepare(ctrl->soc, false);
 		}
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.h b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
index 928114c0be5e..9f171252a2ae 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
@@ -24,6 +24,8 @@ struct brcmnand_soc {
 	void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
 	void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
 				 bool is_param);
+	void (*read_data_bus)(struct brcmnand_soc *soc, void __iomem *flash_cache,
+			      u32 *buffer, int fc_words);
 	const struct brcmnand_io_ops *ops;
 };
 
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:54 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:54 -0800
Subject: [PATCH v6 09/13] arm64: dts: broadcom: bcmbca: Update router boards
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-10-william.zhang@broadcom.com>

Enable the nand controller and add WP pin connection property in actual
board dts as they are board level properties now that they are disabled
and moved out from SoC dtsi.

Also remove the unnecessary brcm,nand-has-wp property from AC5300 board.
This property is only needed for some old controller that this board
does not apply.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 .../boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts     | 5 +++++
 .../dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts  | 5 +++++
 .../boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts     | 6 +++++-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
index 78204d71ecd2..999d93730240 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
@@ -125,6 +125,11 @@ port at 7 {
 	};
 };
 
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
 &nandcs {
 	nand-ecc-strength = <4>;
 	nand-ecc-step-size = <512>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
index fcf092c81b59..19fc03ef47a0 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
@@ -155,6 +155,11 @@ port at 7 {
 	};
 };
 
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
 &nandcs {
 	nand-ecc-strength = <4>;
 	nand-ecc-step-size = <512>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
index d94a53d68320..52f928dbfa3c 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
@@ -166,11 +166,15 @@ led at 19 {
 	};
 };
 
+&nand_controller {
+	brcm,wp-not-connected;
+	status = "okay";
+};
+
 &nandcs {
 	nand-ecc-strength = <4>;
 	nand-ecc-step-size = <512>;
 	nand-on-flash-bbt;
-	brcm,nand-has-wp;
 
 	#address-cells = <1>;
 	#size-cells = <0>;
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:58 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:58 -0800
Subject: [PATCH v6 13/13] mtd: rawnand: brcmnand: Support write protection setting from dts
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-14-william.zhang@broadcom.com>

The write protection feature is controlled by the module parameter wp_on
with default set to enabled. But not all the board use this feature
especially in BCMBCA broadband board. And module parameter is not
sufficient as different board can have different option.  Add a device
tree property and allow this feature to be configured through the board
dts on per board basis.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
Reviewed-by: Kamal Dasu <kamal.dasu at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Use the new brcm,wp-not-connected property based on the dts binding
change

Changes in v3: None
Changes in v2: None

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index e8ffc283b365..4810345d0d8a 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -3223,6 +3223,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 	/* Disable XOR addressing */
 	brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0);
 
+	/* Check if the board connects the WP pin */
+	if (of_property_read_bool(dn, "brcm,wp-not-connected"))
+		wp_on = 0;
+
 	if (ctrl->features & BRCMNAND_HAS_WP) {
 		/* Permanently disable write protection */
 		if (wp_on == 2)
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:47 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:47 -0800
Subject: [PATCH v6 02/13] mtd: rawnand: brcmnand: fix style issues
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-3-william.zhang@broadcom.com>

Fix various style issues.

Signed-off-by: David Regan <dregan at broadcom.com>
Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v6:
- Added to patch series

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index b8e70fc64348..5f34e5a51d25 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2339,7 +2339,7 @@ static int brcmnand_write_oob_raw(struct nand_chip *chip, int page)
 }
 
 static int brcmnand_exec_instr(struct brcmnand_host *host, int i,
-				const struct nand_operation *op)
+		const struct nand_operation *op)
 {
 	const struct nand_op_instr *instr = &op->instrs[i];
 	struct brcmnand_controller *ctrl = host->ctrl;
@@ -2353,7 +2353,7 @@ static int brcmnand_exec_instr(struct brcmnand_host *host, int i,
 	 * (WAITRDY excepted).
 	 */
 	last_op = ((i == (op->ninstrs - 1)) && (instr->type != NAND_OP_WAITRDY_INSTR)) ||
-		  ((i == (op->ninstrs - 2)) && (op->instrs[i+1].type == NAND_OP_WAITRDY_INSTR));
+		  ((i == (op->ninstrs - 2)) && (op->instrs[i + 1].type == NAND_OP_WAITRDY_INSTR));
 
 	switch (instr->type) {
 	case NAND_OP_CMD_INSTR:
@@ -2398,10 +2398,10 @@ static int brcmnand_exec_instr(struct brcmnand_host *host, int i,
 
 static int brcmnand_op_is_status(const struct nand_operation *op)
 {
-	if ((op->ninstrs == 2) &&
-	    (op->instrs[0].type == NAND_OP_CMD_INSTR) &&
-	    (op->instrs[0].ctx.cmd.opcode == NAND_CMD_STATUS) &&
-	    (op->instrs[1].type == NAND_OP_DATA_IN_INSTR))
+	if (op->ninstrs == 2 &&
+	    op->instrs[0].type == NAND_OP_CMD_INSTR &&
+	    op->instrs[0].ctx.cmd.opcode == NAND_CMD_STATUS &&
+	    op->instrs[1].type == NAND_OP_DATA_IN_INSTR)
 		return 1;
 
 	return 0;
@@ -2409,10 +2409,10 @@ static int brcmnand_op_is_status(const struct nand_operation *op)
 
 static int brcmnand_op_is_reset(const struct nand_operation *op)
 {
-	if ((op->ninstrs == 2) &&
-	    (op->instrs[0].type == NAND_OP_CMD_INSTR) &&
-	    (op->instrs[0].ctx.cmd.opcode == NAND_CMD_RESET) &&
-	    (op->instrs[1].type == NAND_OP_WAITRDY_INSTR))
+	if (op->ninstrs == 2 &&
+	    op->instrs[0].type == NAND_OP_CMD_INSTR &&
+	    op->instrs[0].ctx.cmd.opcode == NAND_CMD_RESET &&
+	    op->instrs[1].type == NAND_OP_WAITRDY_INSTR)
 		return 1;
 
 	return 0;
@@ -2440,8 +2440,7 @@ static int brcmnand_exec_op(struct nand_chip *chip,
 		*status = ret & 0xFF;
 
 		return 0;
-	}
-	else if (brcmnand_op_is_reset(op)) {
+	} else if (brcmnand_op_is_reset(op)) {
 		ret = brcmnand_reset(host);
 		if (ret < 0)
 			return ret;
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:50 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:50 -0800
Subject: [PATCH v6 05/13] dt-bindings: mtd: brcmnand: Add WP pin connection property
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-6-william.zhang@broadcom.com>

Add brcm,wp-not-connected property to have an option for disabling this
feature on broadband board design that does not connect WP pin.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>

---

Changes in v6:
- Add reviewed-by tags

Changes in v5:
- Update the description of this new property

Changes in v4:
- Move the WP pin property to this separate patch and change it to
boolean type.

Changes in v3: None
Changes in v2: None

 Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
index e54ca08a798a..6a717bcedfd3 100644
--- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
+++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
@@ -113,6 +113,13 @@ properties:
       earlier versions of this core that include WP
     type: boolean
 
+  brcm,wp-not-connected:
+    description:
+      Use this property when WP pin is not physically wired to the NAND chip.
+      Write protection feature cannot be used. By default, controller assumes
+      the pin is connected and feature is used.
+    $ref: /schemas/types.yaml#/definitions/flag
+
 patternProperties:
   "^nand@[a-f0-9]$":
     type: object
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:57 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:57 -0800
Subject: [PATCH v6 12/13] mtd: rawnand: brcmnand: Add support for getting ecc setting from strap
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-13-william.zhang@broadcom.com>

BCMBCA broadband SoC based board design does not specify ecc setting in
dts but rather use the SoC NAND strap info to obtain the ecc strength
and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
this purpose and update driver to support this option. However these two
options can not be used at the same time.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>

---

Changes in v6:
- Combine the ecc step size and ecc strength into one get function
- Treat it as error condition if both brcm,nand-ecc-use-strap and nand
ecc dts properties are set
- Add intermediate steps to get the sector size bitfield

Changes in v5: None
Changes in v4:
- Update the comments for ecc setting selection

Changes in v3: None
Changes in v2:
- Minor cosmetic fixes

 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 83 ++++++++++++++++++++++--
 1 file changed, 77 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index ef7d340475be..e8ffc283b365 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1038,6 +1038,22 @@ static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl)
 		return -1;
 }
 
+static int brcmnand_get_sector_size_1k(struct brcmnand_host *host)
+{
+	struct brcmnand_controller *ctrl = host->ctrl;
+	int sector_size_bit = brcmnand_sector_1k_shift(ctrl);
+	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+						  BRCMNAND_CS_ACC_CONTROL);
+	u32 acc_control;
+
+	if (sector_size_bit < 0)
+		return 0;
+
+	acc_control = nand_readreg(ctrl, acc_control_offs);
+
+	return (acc_control & BIT(sector_size_bit)) >> sector_size_bit;
+}
+
 static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
 {
 	struct brcmnand_controller *ctrl = host->ctrl;
@@ -1055,6 +1071,43 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
 	nand_writereg(ctrl, acc_control_offs, tmp);
 }
 
+static int brcmnand_get_spare_size(struct brcmnand_host *host)
+{
+	struct brcmnand_controller *ctrl = host->ctrl;
+	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+						  BRCMNAND_CS_ACC_CONTROL);
+	u32 acc = nand_readreg(ctrl, acc_control_offs);
+
+	return (acc & brcmnand_spare_area_mask(ctrl));
+}
+
+static void brcmnand_get_ecc_settings(struct brcmnand_host *host, struct nand_chip *chip)
+{
+	struct brcmnand_controller *ctrl = host->ctrl;
+	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+						  BRCMNAND_CS_ACC_CONTROL);
+	int sector_size_1k = brcmnand_get_sector_size_1k(host);
+	int spare_area_size, ecc_level;
+	u32 acc;
+
+	spare_area_size = brcmnand_get_spare_size(host);
+	acc = nand_readreg(ctrl, acc_control_offs);
+	ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl->ecc_level_shift;
+	if (sector_size_1k)
+		chip->ecc.strength = ecc_level * 2;
+	else if (spare_area_size == 16 && ecc_level == 15)
+		chip->ecc.strength = 1; /* hamming */
+	else
+		chip->ecc.strength = ecc_level;
+
+	if (chip->ecc.size == 0) {
+		if (sector_size_1k < 0)
+			chip->ecc.size = 512;
+		else
+			chip->ecc.size = 512 << sector_size_1k;
+	}
+}
+
 /***********************************************************************
  * CS_NAND_SELECT
  ***********************************************************************/
@@ -2625,19 +2678,37 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
 		nanddev_get_memorg(&chip->base);
 	struct brcmnand_controller *ctrl = host->ctrl;
 	struct brcmnand_cfg *cfg = &host->hwcfg;
-	char msg[128];
+	struct device_node *np = nand_get_flash_node(chip);
 	u32 offs, tmp, oob_sector;
+	bool use_strap = false;
+	char msg[128];
 	int ret;
 
 	memset(cfg, 0, sizeof(*cfg));
+	use_strap = of_property_read_bool(np, "brcm,nand-ecc-use-strap");
 
-	ret = of_property_read_u32(nand_get_flash_node(chip),
-				   "brcm,nand-oob-sector-size",
+	/*
+	 * Either nand-ecc-xxx or brcm,nand-ecc-use-strap can be set. Error out
+	 * if both exist.
+	 */
+	if (chip->ecc.strength && use_strap) {
+		dev_err(ctrl->dev,
+			"nand ecc and strap ecc settings can't be set at the same time\n");
+		return -EINVAL;
+	}
+
+	if (use_strap)
+		brcmnand_get_ecc_settings(host, chip);
+
+	ret = of_property_read_u32(np, "brcm,nand-oob-sector-size",
 				   &oob_sector);
 	if (ret) {
-		/* Use detected size */
-		cfg->spare_area_size = mtd->oobsize /
-					(mtd->writesize >> FC_SHIFT);
+		if (use_strap)
+			cfg->spare_area_size = brcmnand_get_spare_size(host);
+		else
+			/* Use detected size */
+			cfg->spare_area_size = mtd->oobsize /
+						(mtd->writesize >> FC_SHIFT);
 	} else {
 		cfg->spare_area_size = oob_sector;
 	}
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:55 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:55 -0800
Subject: [PATCH v6 10/13] mtd: rawnand: brcmnand: Rename bcm63138 nand driver
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-11-william.zhang@broadcom.com>

In preparing to support multiple BCMBCA SoCs, rename bcm63138 to bcmbca
in the driver code and driver file name.

Signed-off-by: William Zhang <william.zhang at broadcom.com>
Reviewed-by: David Regan <dregan at broadcom.com>
Acked-by: Florian Fainelli <florian.fainelli at broadcom.com>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/mtd/nand/raw/brcmnand/Makefile        |  2 +-
 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c | 99 -------------------
 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c   | 99 +++++++++++++++++++
 3 files changed, 100 insertions(+), 100 deletions(-)
 delete mode 100644 drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
 create mode 100644 drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c

diff --git a/drivers/mtd/nand/raw/brcmnand/Makefile b/drivers/mtd/nand/raw/brcmnand/Makefile
index 9907e3ec4bb2..0536568c6467 100644
--- a/drivers/mtd/nand/raw/brcmnand/Makefile
+++ b/drivers/mtd/nand/raw/brcmnand/Makefile
@@ -2,7 +2,7 @@
 # link order matters; don't link the more generic brcmstb_nand.o before the
 # more specific iproc_nand.o, for instance
 obj-$(CONFIG_MTD_NAND_BRCMNAND_IPROC)	+= iproc_nand.o
-obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMBCA)	+= bcm63138_nand.o
+obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMBCA)	+= bcmbca_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND_BCM63XX)	+= bcm6368_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND_BRCMSTB)	+= brcmstb_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmnand.o
diff --git a/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c b/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
deleted file mode 100644
index 968c5b674b08..000000000000
--- a/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c
+++ /dev/null
@@ -1,99 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright ? 2015 Broadcom Corporation
- */
-
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include "brcmnand.h"
-
-struct bcm63138_nand_soc {
-	struct brcmnand_soc soc;
-	void __iomem *base;
-};
-
-#define BCM63138_NAND_INT_STATUS		0x00
-#define BCM63138_NAND_INT_EN			0x04
-
-enum {
-	BCM63138_CTLRDY		= BIT(4),
-};
-
-static bool bcm63138_nand_intc_ack(struct brcmnand_soc *soc)
-{
-	struct bcm63138_nand_soc *priv =
-			container_of(soc, struct bcm63138_nand_soc, soc);
-	void __iomem *mmio = priv->base + BCM63138_NAND_INT_STATUS;
-	u32 val = brcmnand_readl(mmio);
-
-	if (val & BCM63138_CTLRDY) {
-		brcmnand_writel(val & ~BCM63138_CTLRDY, mmio);
-		return true;
-	}
-
-	return false;
-}
-
-static void bcm63138_nand_intc_set(struct brcmnand_soc *soc, bool en)
-{
-	struct bcm63138_nand_soc *priv =
-			container_of(soc, struct bcm63138_nand_soc, soc);
-	void __iomem *mmio = priv->base + BCM63138_NAND_INT_EN;
-	u32 val = brcmnand_readl(mmio);
-
-	if (en)
-		val |= BCM63138_CTLRDY;
-	else
-		val &= ~BCM63138_CTLRDY;
-
-	brcmnand_writel(val, mmio);
-}
-
-static int bcm63138_nand_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct bcm63138_nand_soc *priv;
-	struct brcmnand_soc *soc;
-
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-	soc = &priv->soc;
-
-	priv->base = devm_platform_ioremap_resource_byname(pdev, "nand-int-base");
-	if (IS_ERR(priv->base))
-		return PTR_ERR(priv->base);
-
-	soc->ctlrdy_ack = bcm63138_nand_intc_ack;
-	soc->ctlrdy_set_enabled = bcm63138_nand_intc_set;
-
-	return brcmnand_probe(pdev, soc);
-}
-
-static const struct of_device_id bcm63138_nand_of_match[] = {
-	{ .compatible = "brcm,nand-bcm63138" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, bcm63138_nand_of_match);
-
-static struct platform_driver bcm63138_nand_driver = {
-	.probe			= bcm63138_nand_probe,
-	.remove_new		= brcmnand_remove,
-	.driver = {
-		.name		= "bcm63138_nand",
-		.pm		= &brcmnand_pm_ops,
-		.of_match_table	= bcm63138_nand_of_match,
-	}
-};
-module_platform_driver(bcm63138_nand_driver);
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Brian Norris");
-MODULE_DESCRIPTION("NAND driver for BCM63138");
diff --git a/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
new file mode 100644
index 000000000000..3e2f3b79788d
--- /dev/null
+++ b/drivers/mtd/nand/raw/brcmnand/bcmbca_nand.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright ? 2015 Broadcom Corporation
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "brcmnand.h"
+
+struct bcmbca_nand_soc {
+	struct brcmnand_soc soc;
+	void __iomem *base;
+};
+
+#define BCMBCA_NAND_INT_STATUS		0x00
+#define BCMBCA_NAND_INT_EN			0x04
+
+enum {
+	BCMBCA_CTLRDY		= BIT(4),
+};
+
+static bool bcmbca_nand_intc_ack(struct brcmnand_soc *soc)
+{
+	struct bcmbca_nand_soc *priv =
+			container_of(soc, struct bcmbca_nand_soc, soc);
+	void __iomem *mmio = priv->base + BCMBCA_NAND_INT_STATUS;
+	u32 val = brcmnand_readl(mmio);
+
+	if (val & BCMBCA_CTLRDY) {
+		brcmnand_writel(val & ~BCMBCA_CTLRDY, mmio);
+		return true;
+	}
+
+	return false;
+}
+
+static void bcmbca_nand_intc_set(struct brcmnand_soc *soc, bool en)
+{
+	struct bcmbca_nand_soc *priv =
+			container_of(soc, struct bcmbca_nand_soc, soc);
+	void __iomem *mmio = priv->base + BCMBCA_NAND_INT_EN;
+	u32 val = brcmnand_readl(mmio);
+
+	if (en)
+		val |= BCMBCA_CTLRDY;
+	else
+		val &= ~BCMBCA_CTLRDY;
+
+	brcmnand_writel(val, mmio);
+}
+
+static int bcmbca_nand_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct bcmbca_nand_soc *priv;
+	struct brcmnand_soc *soc;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	soc = &priv->soc;
+
+	priv->base = devm_platform_ioremap_resource_byname(pdev, "nand-int-base");
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	soc->ctlrdy_ack = bcmbca_nand_intc_ack;
+	soc->ctlrdy_set_enabled = bcmbca_nand_intc_set;
+
+	return brcmnand_probe(pdev, soc);
+}
+
+static const struct of_device_id bcmbca_nand_of_match[] = {
+	{ .compatible = "brcm,nand-bcm63138" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcmbca_nand_of_match);
+
+static struct platform_driver bcmbca_nand_driver = {
+	.probe			= bcmbca_nand_probe,
+	.remove_new		= brcmnand_remove,
+	.driver = {
+		.name		= "bcmbca_nand",
+		.pm		= &brcmnand_pm_ops,
+		.of_match_table	= bcmbca_nand_of_match,
+	}
+};
+module_platform_driver(bcmbca_nand_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Brian Norris");
+MODULE_DESCRIPTION("NAND driver for BCMBCA");
-- 
2.37.3



From william.zhang at broadcom.com  Thu Feb 22 19:47:51 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Thu, 22 Feb 2024 19:47:51 -0800
Subject: [PATCH v6 06/13] dt-bindings: mtd: brcmnand: Add ecc strap property
In-Reply-To: <20240223034758.13753-1-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
Message-ID: <20240223034758.13753-7-william.zhang@broadcom.com>

Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
board boot strap for broadband board designs because they do not specify
ecc setting in dts but rather using the strap setting.

Signed-off-by: William Zhang <william.zhang at broadcom.com>

---

Changes in v6:
- Add other nand ecc properties to the exclude check list
- Update the brcm,nand-ecc-use-strap property description

Changes in v5:
- Update the description for this ecc strap property
- Add check to make sure brcm,nand-ecc-use-strap and
  nand-ecc-strength/brcm,nand-oob-sector-size can not be used at the
  same time

Changes in v4:
- Move ecc strap property to this separate patch and remove some
non-binding related text from the description

Changes in v3: None
Changes in v2: None

 .../bindings/mtd/brcm,brcmnand.yaml           | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
index 6a717bcedfd3..064e840aeaa1 100644
--- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
+++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
@@ -146,6 +146,15 @@ patternProperties:
           layout.
         $ref: /schemas/types.yaml#/definitions/uint32
 
+      brcm,nand-ecc-use-strap:
+        description:
+          This property requires the host system to get the ECC related
+          settings from the SoC NAND boot strap configuration instead of
+          the generic NAND ECC settings. This is a common hardware design
+          on BCMBCA based boards. This strap ECC option and generic NAND
+          ECC option can not be specified at the same time.
+        $ref: /schemas/types.yaml#/definitions/flag
+
     unevaluatedProperties: false
 
 allOf:
@@ -195,6 +204,21 @@ allOf:
       required:
         - interrupt-names
 
+  - if:
+      patternProperties:
+        "^nand@[a-f0-9]$":
+          required:
+            - brcm,nand-ecc-use-strap
+    then:
+      patternProperties:
+        "^nand@[a-f0-9]$":
+          properties:
+            nand-ecc-strength: false
+            nand-ecc-step-size: false
+            nand-ecc-maximize: false
+            nand-ecc-algo: false
+            brcm,nand-oob-sector-size: false
+
 unevaluatedProperties: false
 
 required:
-- 
2.37.3



From tommy_huang at aspeedtech.com  Thu Feb 22 19:49:17 2024
From: tommy_huang at aspeedtech.com (Tommy Huang)
Date: Fri, 23 Feb 2024 03:49:17 +0000
Subject: [PATCH] i2c: aspeed: Fix the dummy irq expected print
In-Reply-To: <v4nawwb4rwjiy2g7xv2sfyhc545mhk4izb3g22f7jupcevjuzb@nxmqgf2zjyqs>
References: <20240216120455.4138642-1-tommy_huang@aspeedtech.com>
 <nbkkaktcozbhly44hii3zwie7ivsra3qxzdibyzhyhooxrudvb@zik6skmkki2c>
 <TYZPR06MB61911F076C8719C6A7D57B97E1562@TYZPR06MB6191.apcprd06.prod.outlook.com>
 <v4nawwb4rwjiy2g7xv2sfyhc545mhk4izb3g22f7jupcevjuzb@nxmqgf2zjyqs>
Message-ID: <TYZPR06MB61912715EE2869DDB7C3763DE1552@TYZPR06MB6191.apcprd06.prod.outlook.com>

Hi Andi,

	Sure~
	Below is my re-word commit and fixes tag.

	When the i2c error condition occurred and master state was not
	idle, the master irq function will goto complete state without any
    other interrupt handling. It would cause dummy irq expected print.
    Under this condition, assign the irq_status into irq_handle.

	For example, when the abnormal start / stop occurred (bit 5) with normal stop
	status (bit 4) at same time. Then the normal stop status would not be handled 
	and it would cause irq expected print in the aspeed_i2c_bus_irq.

	...
	aspeed-i2c-bus xxxxxxxx. i2c-bus: irq handled != irq. Expected 0x00000030, but was 0x00000020
	...
 
	Fixes: 3e9efc3299dd ("i2c: aspeed: Handle master/slave combined irq events properly")
	Cc: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>

	Tommy

> -----Original Message-----
> From: Andi Shyti <andi.shyti at kernel.org>
> Sent: Thursday, February 22, 2024 4:58 PM
> To: Tommy Huang <tommy_huang at aspeedtech.com>
> Cc: brendan.higgins at linux.dev; p.zabel at pengutronix.de;
> linux-i2c at vger.kernel.org; openbmc at lists.ozlabs.org;
> benh at kernel.crashing.org; joel at jms.id.au; andrew at aj.id.au;
> linux-arm-kernel at lists.infradead.org; linux-aspeed at lists.ozlabs.org;
> linux-kernel at vger.kernel.org; BMC-SW <BMC-SW at aspeedtech.com>
> Subject: Re: [PATCH] i2c: aspeed: Fix the dummy irq expected print
> 
> Hi Tommy,
> 
> On Thu, Feb 22, 2024 at 01:10:39AM +0000, Tommy Huang wrote:
> > > On Fri, Feb 16, 2024 at 08:04:55PM +0800, Tommy Huang wrote:
> > > > When the i2c error condition occurred and master state was not
> > > > idle, the master irq function will goto complete state without any
> > > > other interrupt handling. It would cause dummy irq expected print.
> > > > Under this condition, assign the irq_status into irq_handle.
> > >
> > > I'm sorry, but I don't understand much from your log here.
> > >
> > > Do you mean that irq_handled in aspeed_i2c_master_irq() is left with
> > > some states that is not supposed to have and then you end up printing
> here:
> > >
> > > 	dev_err(bus->dev,
> > > 		"irq handled != irq. expected 0x%08x, but was 0x%08x\n",
> > > 		irq_received, irq_handled);
> > >
> > > Can you please explain better?
> > >
> >
> > Yes. If the platform met any irq error condition and the i2c wasn't stated
> under ASPEED_I2C_MASTER_INACTIVE.
> > Then the code flow would goto the end of aspeed_i2c_master_irq.
> >
> > 	ret = aspeed_i2c_is_irq_error(irq_status);
> > 	if (ret) {
> > 		...
> > 		irq_handled |= (irq_status & ASPEED_I2CD_INTR_MASTER_ERRORS);
> > 		if (bus->master_state != ASPEED_I2C_MASTER_INACTIVE) {
> > 			bus->cmd_err = ret;
> > 			bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
> > 			goto out_complete;
> > 		}
> > 	}
> >
> > Some master interrupt states were not handled under this situation.
> > The fake irq not equaled message would be filled into whole of demsg.
> > It's most like below example.
> >
> > ...
> > aspeed-i2c-bus 1e78a780. i2c-bus: irq handled != irq. expected
> > 0x00000030, but was 0x00000020 aspeed-i2c-bus 1e78a780. i2c-bus: irq
> > handled != irq. expected 0x00000030, but was 0x00000020 aspeed-i2c-bus
> > 1e78a780. i2c-bus: irq handled != irq. expected 0x00000030, but was
> 0x00000020 ...
> >
> > I thought the bus->cmd_err has been filled error reason and it would be
> returned to upper layer.
> > So, I didn't think the print should be existed.
> 
> thanks! Can you please write a commit that explains better the fix you are
> doing?
> 
> > > If that's the case, wouldn't it make more sense to check for
> > > bus->master_state != ASPEED_I2C_MASTER_INACTIVE) earlier?
> >
> > Did you suggest to add "bus->master_state !=
> ASPEED_I2C_MASTER_INACTIVE" judgement before print the irq not equal
> print?
> 
> no, not really, but nevermind, on a second look, what I'm suggesting doesn't
> make much sense.
> 
> If you want, please reword the commit message as reply to this e-mail and I
> will take care of it.
> 
> > > And, still, If that's the case, I believe you might need the Fixes
> > > tag. It's true that you are not really failing, but you are not reporting a
> failure by mistake.
> 
> Please, also consider adding the Fixes tag if you see it necessary; I think you
> should, but it's borderline.
> 
> Andi


From shawnguo2 at yeah.net  Thu Feb 22 20:00:13 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Fri, 23 Feb 2024 12:00:13 +0800
Subject: [PATCH v2 1/2] arm64: dts: freescale: imx8-ss-dma: Fix edma3's
 location
In-Reply-To: <20240206080459.1741172-1-alexander.stein@ew.tq-group.com>
References: <20240206080459.1741172-1-alexander.stein@ew.tq-group.com>
Message-ID: <ZdgYTQh6avExV4qp@dragon>

On Tue, Feb 06, 2024 at 09:04:58AM +0100, Alexander Stein wrote:
> Sort nodes by base address. edma3 comes later in the memory map.
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied both, thanks!



From shawnguo2 at yeah.net  Thu Feb 22 20:01:04 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Fri, 23 Feb 2024 12:01:04 +0800
Subject: [PATCH v2] arm64: dts: imx8mp: Enable SAI audio on Data Modul
 i.MX8M Plus eDM SBC
In-Reply-To: <20240206125541.37959-1-marex@denx.de>
References: <20240206125541.37959-1-marex@denx.de>
Message-ID: <ZdgYgHs1G9pK9t7K@dragon>

On Tue, Feb 06, 2024 at 01:55:17PM +0100, Marek Vasut wrote:
> Add SAI I2S and audio bindings to Data Modul i.MX8M Plus eDM SBC.
> 
> The SGTL5000 is attached to SAI3, however the SGTL5000 codec MCLK
> must be supplied even if the SAI3 is not in use and is controlled
> separately by the codec. The MCLK is also used to drive the codec
> I2C block, so without MCLK, I2C access to the codec would not be
> possible.
> 
> To provide such flexible MCLK control, use PWM4 with period 1 and
> duty cycle 50% as 12 MHz clock source, as there is no direct way
> to route MX8MP CCM clock to the MCLK pin. Use codec as bitclock
> and frame clock master, so that the SGTL5000 PLL can be used to
> generate derived clock.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>

Applied, thanks!



From shawnguo2 at yeah.net  Thu Feb 22 20:02:31 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Fri, 23 Feb 2024 12:02:31 +0800
Subject: [PATCH v2] ARM: dts: imx53-qsb: add support for the HDMI expander
In-Reply-To: <20240206-imx53-qsb-hdmi-v2-1-a025fe0c4362@linaro.org>
References: <20240206-imx53-qsb-hdmi-v2-1-a025fe0c4362@linaro.org>
Message-ID: <ZdgY1ykfswUGgfd2@dragon>

On Tue, Feb 06, 2024 at 05:26:29PM +0200, Dmitry Baryshkov wrote:
> Add support for the MCIMXHDMICARD expansion card attached to the iMX53
> QSB / QSRB platforms. This enables HDMI output on those devices.
> 
> Reviewed-by: Fabio Estevam <festevam at gmail.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Applied, thanks!



From hejunhao3 at huawei.com  Thu Feb 22 20:05:24 2024
From: hejunhao3 at huawei.com (hejunhao)
Date: Fri, 23 Feb 2024 12:05:24 +0800
Subject: [PATCH] drivers/perf: hisi: Enable HiSilicon Erratum
 162700402 quirk for UC PMU
In-Reply-To: <20240208105047.000023c7@Huawei.com>
References: <20240207094245.34195-1-hejunhao3@huawei.com>
 <20240208105047.000023c7@Huawei.com>
Message-ID: <2a6dde28-a74d-0992-3f9d-7346e36a0b9c@huawei.com>


On 2024/2/8 18:50, Jonathan Cameron wrote:
> On Wed, 7 Feb 2024 17:42:45 +0800
> Junhao He <hejunhao3 at huawei.com> wrote:
>
>> HiSilicon UC PMU v2 suffers the erratum 162700402 that the PMU counter
>> cannot be set due to the lack of clock under power saving mode. This will
>> lead to error or inaccurate counts. The clock can be enabled by the PMU
>> global enabling control.
>>
>> This patch tries to fix this by set the UC PMU enable before set event
>> period to turn on the clock, and then restore the UC PMU configuration.
>> The counter register can hold its value without a clock.
>>
>> Signed-off-by: Junhao He <hejunhao3 at huawei.com>
> Hi.
>
> Some very minor comments about the comments inline.

Hi, Jonathan


Thanks for the comments.

>
> Jonathan
>
>> ---
>>   drivers/perf/hisilicon/hisi_uncore_uc_pmu.c | 40 ++++++++++++++++++++-
>>   1 file changed, 39 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
>> index 636fb79647c8..8e7a9e1f419a 100644
>> --- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
>> +++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
>> @@ -287,10 +287,48 @@ static u64 hisi_uc_pmu_read_counter(struct hisi_pmu *uc_pmu,
>>   	return readq(uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
>>   }
>>   
>> -static void hisi_uc_pmu_write_counter(struct hisi_pmu *uc_pmu,
>> +static bool hisi_uc_pmu_get_glb_en_state(struct hisi_pmu *uc_pmu)
>> +{
>> +	u32 val;
>> +
>> +	val = readl(uc_pmu->base + HISI_UC_EVENT_CTRL_REG);
>> +	return !!FIELD_GET(HISI_UC_EVENT_GLB_EN, val);
>> +}
>> +
>> +static void hisi_uc_pmu_write_counter_quirk_hip09(struct hisi_pmu *uc_pmu,
>>   				      struct hw_perf_event *hwc, u64 val)
>>   {
>> +	bool enable = hisi_uc_pmu_get_glb_en_state(uc_pmu);
>> +
>> +	/* Set the UC PMU enable to turn on the clock. */
> Comment from below here but adjusted to say which path has the device
> already enabled.

This quirk function is simple. I'm going to consolidate all the comments
to annotate the quirk function.

Best regards,
Junhao.

>> +	if (!enable)
>> +		hisi_uc_pmu_start_counters(uc_pmu);
>> +
>>   	writeq(val, uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
>> +
>> +	/*
>> +	 * The counter register can hold its value without a clock. We need
>> +	 * restore the UC PMU configuration. The irq handler will also call
>> +	 * the function to set period. At this time, PMU is still enabled and
>> +	 * we cannot directly disable the PMU.
> I think the comment is more relevant above...

Okay, I'm going to replace the comment with the following

        /*
         * Restore PMU enable status, the counter can hold its value
         * without a clock.
         */

>> +	 */
>> +	if (!enable)
>> +		hisi_uc_pmu_stop_counters(uc_pmu);
>> +}
>> +
>> +static void hisi_uc_pmu_write_counter(struct hisi_pmu *uc_pmu,
>> +				      struct hw_perf_event *hwc, u64 val)
>> +{
>> +	/*
>> +	 * HiSilicon UC PMU v2 suffers the erratum 162700402 that the PMU
>> +	 * counter cannot be set due to the lack of clock under power saving
>> +	 * mode. This will lead to error or inaccurate counts. The clock can
>> +	 * be enabled by the PMU global enabling control.
> I'd move the comment to next to the quirk function so that people can immediately
> see what is being done.  Down here we just need to know there is a quirk.

I'd comment the quirk function.


>
>> +	 */
>> +	if (uc_pmu->identifier == HISI_PMU_V2)
>> +		hisi_uc_pmu_write_counter_quirk_hip09(uc_pmu, hwc, val);
>> +	else
>> +		writeq(val, uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
>>   }
>>   
>>   static void hisi_uc_pmu_enable_counter_int(struct hisi_pmu *uc_pmu,
>



From lkp at intel.com  Thu Feb 22 20:14:38 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 23 Feb 2024 12:14:38 +0800
Subject: [PATCH v1 06/14] serial: 8250_bcm7271: Switch to use
 uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-7-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-7-andriy.shevchenko@linux.intel.com>
Message-ID: <202402231238.AWqLyIoM-lkp@intel.com>

Hi Andy,

kernel test robot noticed the following build warnings:

[auto build test WARNING on tty/tty-testing]
[also build test WARNING on tty/tty-next tty/tty-linus usb/usb-testing usb/usb-next usb/usb-linus linus/master v6.8-rc5 next-20240222]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andy-Shevchenko/serial-core-Move-struct-uart_port-quirks-closer-to-possible-values/20240222-023850
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
patch link:    https://lore.kernel.org/r/20240221183442.4124354-7-andriy.shevchenko%40linux.intel.com
patch subject: [PATCH v1 06/14] serial: 8250_bcm7271: Switch to use uart_read_port_properties()
config: hexagon-randconfig-r123-20240222 (https://download.01.org/0day-ci/archive/20240223/202402231238.AWqLyIoM-lkp at intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 36adfec155de366d722f2bac8ff9162289dcf06c)
reproduce: (https://download.01.org/0day-ci/archive/20240223/202402231238.AWqLyIoM-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402231238.AWqLyIoM-lkp at intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/tty/serial/8250/8250_bcm7271.c:15:
   In file included from include/linux/tty.h:11:
   In file included from include/linux/tty_port.h:5:
   In file included from include/linux/kfifo.h:42:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     547 |         val = __raw_readb(PCI_IOBASE + addr);
         |                           ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     560 |         val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
      37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
         |                                                   ^
   In file included from drivers/tty/serial/8250/8250_bcm7271.c:15:
   In file included from include/linux/tty.h:11:
   In file included from include/linux/tty_port.h:5:
   In file included from include/linux/kfifo.h:42:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     573 |         val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
      35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
         |                                                   ^
   In file included from drivers/tty/serial/8250/8250_bcm7271.c:15:
   In file included from include/linux/tty.h:11:
   In file included from include/linux/tty_port.h:5:
   In file included from include/linux/kfifo.h:42:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     584 |         __raw_writeb(value, PCI_IOBASE + addr);
         |                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     594 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     604 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
>> drivers/tty/serial/8250/8250_bcm7271.c:938:22: warning: unused variable 'np' [-Wunused-variable]
     938 |         struct device_node *np = pdev->dev.of_node;
         |                             ^~
   7 warnings generated.


vim +/np +938 drivers/tty/serial/8250/8250_bcm7271.c

41a469482de257e Al Cooper       2021-03-25   933  
41a469482de257e Al Cooper       2021-03-25   934  
41a469482de257e Al Cooper       2021-03-25   935  static int brcmuart_probe(struct platform_device *pdev)
41a469482de257e Al Cooper       2021-03-25   936  {
41a469482de257e Al Cooper       2021-03-25   937  	struct resource *regs;
41a469482de257e Al Cooper       2021-03-25  @938  	struct device_node *np = pdev->dev.of_node;
41a469482de257e Al Cooper       2021-03-25   939  	const struct of_device_id *of_id = NULL;
41a469482de257e Al Cooper       2021-03-25   940  	struct uart_8250_port *new_port;
41a469482de257e Al Cooper       2021-03-25   941  	struct device *dev = &pdev->dev;
41a469482de257e Al Cooper       2021-03-25   942  	struct brcmuart_priv *priv;
41a469482de257e Al Cooper       2021-03-25   943  	struct clk *baud_mux_clk;
41a469482de257e Al Cooper       2021-03-25   944  	struct uart_8250_port up;
8a66b31a15966ea Colin Ian King  2021-07-19   945  	void __iomem *membase = NULL;
41a469482de257e Al Cooper       2021-03-25   946  	resource_size_t mapbase = 0;
41a469482de257e Al Cooper       2021-03-25   947  	int ret;
41a469482de257e Al Cooper       2021-03-25   948  	int x;
41a469482de257e Al Cooper       2021-03-25   949  	int dma_irq;
41a469482de257e Al Cooper       2021-03-25   950  	static const char * const reg_names[REGS_MAX] = {
41a469482de257e Al Cooper       2021-03-25   951  		"uart", "dma_rx", "dma_tx", "dma_intr2", "dma_arb"
41a469482de257e Al Cooper       2021-03-25   952  	};
41a469482de257e Al Cooper       2021-03-25   953  
41a469482de257e Al Cooper       2021-03-25   954  	priv = devm_kzalloc(dev, sizeof(struct brcmuart_priv),
41a469482de257e Al Cooper       2021-03-25   955  			GFP_KERNEL);
41a469482de257e Al Cooper       2021-03-25   956  	if (!priv)
41a469482de257e Al Cooper       2021-03-25   957  		return -ENOMEM;
41a469482de257e Al Cooper       2021-03-25   958  
41a469482de257e Al Cooper       2021-03-25   959  	of_id = of_match_node(brcmuart_dt_ids, np);
41a469482de257e Al Cooper       2021-03-25   960  	if (!of_id || !of_id->data)
41a469482de257e Al Cooper       2021-03-25   961  		priv->rate_table = brcmstb_rate_table;
41a469482de257e Al Cooper       2021-03-25   962  	else
41a469482de257e Al Cooper       2021-03-25   963  		priv->rate_table = of_id->data;
41a469482de257e Al Cooper       2021-03-25   964  
41a469482de257e Al Cooper       2021-03-25   965  	for (x = 0; x < REGS_MAX; x++) {
41a469482de257e Al Cooper       2021-03-25   966  		regs = platform_get_resource_byname(pdev, IORESOURCE_MEM,
41a469482de257e Al Cooper       2021-03-25   967  						reg_names[x]);
41a469482de257e Al Cooper       2021-03-25   968  		if (!regs)
41a469482de257e Al Cooper       2021-03-25   969  			break;
41a469482de257e Al Cooper       2021-03-25   970  		priv->regs[x] =	devm_ioremap(dev, regs->start,
41a469482de257e Al Cooper       2021-03-25   971  					     resource_size(regs));
64b1510642f845d Wei Yongjun     2021-03-29   972  		if (!priv->regs[x])
64b1510642f845d Wei Yongjun     2021-03-29   973  			return -ENOMEM;
41a469482de257e Al Cooper       2021-03-25   974  		if (x == REGS_8250) {
41a469482de257e Al Cooper       2021-03-25   975  			mapbase = regs->start;
41a469482de257e Al Cooper       2021-03-25   976  			membase = priv->regs[x];
41a469482de257e Al Cooper       2021-03-25   977  		}
41a469482de257e Al Cooper       2021-03-25   978  	}
41a469482de257e Al Cooper       2021-03-25   979  
41a469482de257e Al Cooper       2021-03-25   980  	/* We should have just the uart base registers or all the registers */
c77247a52be2359 Andy Shevchenko 2023-09-18   981  	if (x != 1 && x != REGS_MAX)
c77247a52be2359 Andy Shevchenko 2023-09-18   982  		return dev_err_probe(dev, -EINVAL, "%s registers not specified\n",
c77247a52be2359 Andy Shevchenko 2023-09-18   983  				     reg_names[x]);
41a469482de257e Al Cooper       2021-03-25   984  
41a469482de257e Al Cooper       2021-03-25   985  	/* if the DMA registers were specified, try to enable DMA */
41a469482de257e Al Cooper       2021-03-25   986  	if (x > REGS_DMA_RX) {
41a469482de257e Al Cooper       2021-03-25   987  		if (brcmuart_arbitration(priv, 1) == 0) {
41a469482de257e Al Cooper       2021-03-25   988  			u32 txrev = 0;
41a469482de257e Al Cooper       2021-03-25   989  			u32 rxrev = 0;
41a469482de257e Al Cooper       2021-03-25   990  
41a469482de257e Al Cooper       2021-03-25   991  			txrev = udma_readl(priv, REGS_DMA_RX, UDMA_RX_REVISION);
41a469482de257e Al Cooper       2021-03-25   992  			rxrev = udma_readl(priv, REGS_DMA_TX, UDMA_TX_REVISION);
41a469482de257e Al Cooper       2021-03-25   993  			if ((txrev >= UDMA_TX_REVISION_REQUIRED) &&
41a469482de257e Al Cooper       2021-03-25   994  				(rxrev >= UDMA_RX_REVISION_REQUIRED)) {
41a469482de257e Al Cooper       2021-03-25   995  
41a469482de257e Al Cooper       2021-03-25   996  				/* Enable the use of the DMA hardware */
41a469482de257e Al Cooper       2021-03-25   997  				priv->dma_enabled = true;
41a469482de257e Al Cooper       2021-03-25   998  			} else {
41a469482de257e Al Cooper       2021-03-25   999  				brcmuart_arbitration(priv, 0);
41a469482de257e Al Cooper       2021-03-25  1000  				dev_err(dev,
41a469482de257e Al Cooper       2021-03-25  1001  					"Unsupported DMA Hardware Revision\n");
41a469482de257e Al Cooper       2021-03-25  1002  			}
41a469482de257e Al Cooper       2021-03-25  1003  		} else {
41a469482de257e Al Cooper       2021-03-25  1004  			dev_err(dev,
41a469482de257e Al Cooper       2021-03-25  1005  				"Timeout arbitrating for UART DMA hardware\n");
41a469482de257e Al Cooper       2021-03-25  1006  		}
41a469482de257e Al Cooper       2021-03-25  1007  	}
41a469482de257e Al Cooper       2021-03-25  1008  
19010c5b7125670 Andy Shevchenko 2024-02-21  1009  	dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not ");
19010c5b7125670 Andy Shevchenko 2024-02-21  1010  
19010c5b7125670 Andy Shevchenko 2024-02-21  1011  	memset(&up, 0, sizeof(up));
19010c5b7125670 Andy Shevchenko 2024-02-21  1012  	up.port.type = PORT_BCM7271;
19010c5b7125670 Andy Shevchenko 2024-02-21  1013  	up.port.dev = dev;
19010c5b7125670 Andy Shevchenko 2024-02-21  1014  	up.port.mapbase = mapbase;
19010c5b7125670 Andy Shevchenko 2024-02-21  1015  	up.port.membase = membase;
19010c5b7125670 Andy Shevchenko 2024-02-21  1016  	up.port.handle_irq = brcmuart_handle_irq;
19010c5b7125670 Andy Shevchenko 2024-02-21  1017  	up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_FIXED_TYPE;
19010c5b7125670 Andy Shevchenko 2024-02-21  1018  	up.port.private_data = priv;
19010c5b7125670 Andy Shevchenko 2024-02-21  1019  
19010c5b7125670 Andy Shevchenko 2024-02-21  1020  	ret = uart_read_port_properties(&up.port, true);
19010c5b7125670 Andy Shevchenko 2024-02-21  1021  	if (ret)
19010c5b7125670 Andy Shevchenko 2024-02-21  1022  		goto release_dma;
19010c5b7125670 Andy Shevchenko 2024-02-21  1023  
19010c5b7125670 Andy Shevchenko 2024-02-21  1024  	up.port.regshift = 2;
19010c5b7125670 Andy Shevchenko 2024-02-21  1025  	up.port.iotype = device_is_big_endian(dev) ? UPIO_MEM32BE : UPIO_MEM32;
41a469482de257e Al Cooper       2021-03-25  1026  
41a469482de257e Al Cooper       2021-03-25  1027  	/* See if a Baud clock has been specified */
1f34e3defb5c0a0 Andy Shevchenko 2023-10-05  1028  	baud_mux_clk = devm_clk_get_optional_enabled(dev, "sw_baud");
1f34e3defb5c0a0 Andy Shevchenko 2023-10-05  1029  	ret = PTR_ERR_OR_ZERO(baud_mux_clk);
41a469482de257e Al Cooper       2021-03-25  1030  	if (ret)
15ac1122fd6d4bf Doug Berger     2023-03-09  1031  		goto release_dma;
1f34e3defb5c0a0 Andy Shevchenko 2023-10-05  1032  	if (baud_mux_clk) {
1f34e3defb5c0a0 Andy Shevchenko 2023-10-05  1033  		dev_dbg(dev, "BAUD MUX clock found\n");
1f34e3defb5c0a0 Andy Shevchenko 2023-10-05  1034  
41a469482de257e Al Cooper       2021-03-25  1035  		priv->baud_mux_clk = baud_mux_clk;
41a469482de257e Al Cooper       2021-03-25  1036  		init_real_clk_rates(dev, priv);
19010c5b7125670 Andy Shevchenko 2024-02-21  1037  		up.port.uartclk = priv->default_mux_rate;
1f34e3defb5c0a0 Andy Shevchenko 2023-10-05  1038  	} else {
1f34e3defb5c0a0 Andy Shevchenko 2023-10-05  1039  		dev_dbg(dev, "BAUD MUX clock not specified\n");
41a469482de257e Al Cooper       2021-03-25  1040  	}
41a469482de257e Al Cooper       2021-03-25  1041  
41a469482de257e Al Cooper       2021-03-25  1042  	/* setup HR timer */
41a469482de257e Al Cooper       2021-03-25  1043  	hrtimer_init(&priv->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
41a469482de257e Al Cooper       2021-03-25  1044  	priv->hrt.function = brcmuart_hrtimer_func;
41a469482de257e Al Cooper       2021-03-25  1045  
41a469482de257e Al Cooper       2021-03-25  1046  	up.port.shutdown = brcmuart_shutdown;
41a469482de257e Al Cooper       2021-03-25  1047  	up.port.startup = brcmuart_startup;
41a469482de257e Al Cooper       2021-03-25  1048  	up.port.throttle = brcmuart_throttle;
41a469482de257e Al Cooper       2021-03-25  1049  	up.port.unthrottle = brcmuart_unthrottle;
41a469482de257e Al Cooper       2021-03-25  1050  	up.port.set_termios = brcmstb_set_termios;
41a469482de257e Al Cooper       2021-03-25  1051  
41a469482de257e Al Cooper       2021-03-25  1052  	if (priv->dma_enabled) {
41a469482de257e Al Cooper       2021-03-25  1053  		priv->rx_size = RX_BUF_SIZE * RX_BUFS_COUNT;
41a469482de257e Al Cooper       2021-03-25  1054  		priv->rx_bufs = dma_alloc_coherent(dev,
41a469482de257e Al Cooper       2021-03-25  1055  						   priv->rx_size,
41a469482de257e Al Cooper       2021-03-25  1056  						   &priv->rx_addr, GFP_KERNEL);
c195438f1e84de8 Lad Prabhakar   2021-12-24  1057  		if (!priv->rx_bufs) {
0e479b460e342c5 Lad Prabhakar   2022-01-05  1058  			ret = -ENOMEM;
41a469482de257e Al Cooper       2021-03-25  1059  			goto err;
c195438f1e84de8 Lad Prabhakar   2021-12-24  1060  		}
41a469482de257e Al Cooper       2021-03-25  1061  		priv->tx_size = UART_XMIT_SIZE;
41a469482de257e Al Cooper       2021-03-25  1062  		priv->tx_buf = dma_alloc_coherent(dev,
41a469482de257e Al Cooper       2021-03-25  1063  						  priv->tx_size,
41a469482de257e Al Cooper       2021-03-25  1064  						  &priv->tx_addr, GFP_KERNEL);
c195438f1e84de8 Lad Prabhakar   2021-12-24  1065  		if (!priv->tx_buf) {
0e479b460e342c5 Lad Prabhakar   2022-01-05  1066  			ret = -ENOMEM;
41a469482de257e Al Cooper       2021-03-25  1067  			goto err;
41a469482de257e Al Cooper       2021-03-25  1068  		}
c195438f1e84de8 Lad Prabhakar   2021-12-24  1069  	}
41a469482de257e Al Cooper       2021-03-25  1070  
41a469482de257e Al Cooper       2021-03-25  1071  	ret = serial8250_register_8250_port(&up);
41a469482de257e Al Cooper       2021-03-25  1072  	if (ret < 0) {
c77247a52be2359 Andy Shevchenko 2023-09-18  1073  		dev_err_probe(dev, ret, "unable to register 8250 port\n");
41a469482de257e Al Cooper       2021-03-25  1074  		goto err;
41a469482de257e Al Cooper       2021-03-25  1075  	}
41a469482de257e Al Cooper       2021-03-25  1076  	priv->line = ret;
41a469482de257e Al Cooper       2021-03-25  1077  	new_port = serial8250_get_port(ret);
41a469482de257e Al Cooper       2021-03-25  1078  	priv->up = &new_port->port;
41a469482de257e Al Cooper       2021-03-25  1079  	if (priv->dma_enabled) {
41a469482de257e Al Cooper       2021-03-25  1080  		dma_irq = platform_get_irq_byname(pdev,  "dma");
41a469482de257e Al Cooper       2021-03-25  1081  		if (dma_irq < 0) {
c77247a52be2359 Andy Shevchenko 2023-09-18  1082  			ret = dev_err_probe(dev, dma_irq, "no IRQ resource info\n");
41a469482de257e Al Cooper       2021-03-25  1083  			goto err1;
41a469482de257e Al Cooper       2021-03-25  1084  		}
41a469482de257e Al Cooper       2021-03-25  1085  		ret = devm_request_irq(dev, dma_irq, brcmuart_isr,
41a469482de257e Al Cooper       2021-03-25  1086  				IRQF_SHARED, "uart DMA irq", &new_port->port);
41a469482de257e Al Cooper       2021-03-25  1087  		if (ret) {
c77247a52be2359 Andy Shevchenko 2023-09-18  1088  			dev_err_probe(dev, ret, "unable to register IRQ handler\n");
41a469482de257e Al Cooper       2021-03-25  1089  			goto err1;
41a469482de257e Al Cooper       2021-03-25  1090  		}
41a469482de257e Al Cooper       2021-03-25  1091  	}
41a469482de257e Al Cooper       2021-03-25  1092  	platform_set_drvdata(pdev, priv);
41a469482de257e Al Cooper       2021-03-25  1093  	brcmuart_init_debugfs(priv, dev_name(&pdev->dev));
41a469482de257e Al Cooper       2021-03-25  1094  	return 0;
41a469482de257e Al Cooper       2021-03-25  1095  
41a469482de257e Al Cooper       2021-03-25  1096  err1:
41a469482de257e Al Cooper       2021-03-25  1097  	serial8250_unregister_port(priv->line);
41a469482de257e Al Cooper       2021-03-25  1098  err:
41a469482de257e Al Cooper       2021-03-25  1099  	brcmuart_free_bufs(dev, priv);
15ac1122fd6d4bf Doug Berger     2023-03-09  1100  release_dma:
15ac1122fd6d4bf Doug Berger     2023-03-09  1101  	if (priv->dma_enabled)
41a469482de257e Al Cooper       2021-03-25  1102  		brcmuart_arbitration(priv, 0);
c195438f1e84de8 Lad Prabhakar   2021-12-24  1103  	return ret;
41a469482de257e Al Cooper       2021-03-25  1104  }
41a469482de257e Al Cooper       2021-03-25  1105  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From f.fainelli at gmail.com  Thu Feb 22 20:20:08 2024
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 22 Feb 2024 20:20:08 -0800
Subject: [PATCH v6 01/13] mtd: rawnand: brcmnand: exec_op helper functions
 return type fixes
In-Reply-To: <20240223034758.13753-2-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
 <20240223034758.13753-2-william.zhang@broadcom.com>
Message-ID: <dd64a40d-0a7e-4f70-a516-632a3d57807a@gmail.com>



On 2/22/2024 7:47 PM, William Zhang wrote:
> From: David Regan <dregan at broadcom.com>
> 
> Fix return types for exec_op reset and status helper functions.
> 
> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
> Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
> Signed-off-by: David Regan <dregan at broadcom.com>
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: William Zhang <william.zhang at broadcom.com>

Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
-- 
Florian


From wenst at chromium.org  Thu Feb 22 20:27:28 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Fri, 23 Feb 2024 12:27:28 +0800
Subject: [PATCH v3 1/2] clk: mediatek: Introduce need_pm_runtime to mtk_clk_desc
In-Reply-To: <20240108081834.408403-1-treapking@chromium.org>
References: <20240108081834.408403-1-treapking@chromium.org>
Message-ID: <CAGXv+5EnBt+7WrNb-QyziEaCihvjhFVf2tpzk=XyAoeELqucaw@mail.gmail.com>

On Mon, Jan 8, 2024 at 4:18?PM Pin-yen Lin <treapking at chromium.org> wrote:
>
> Introduce a new need_pm_runtime variable to mtk_clk_desc to indicate
> this clock controller needs runtime PM for its operations.
> Also do a runtime PM get on the clock controller during the
> probing stage to workaround a possible deadlock.
>
> Signed-off-by: Pin-yen Lin <treapking at chromium.org>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>

The patch itself looks fine.

Besides the MT8183 MFG clock issues, we do actually need this for the
MT8192 ADSP clock. Its power domain is not enabled by default.

> ---
>
> Changes in v3:
> - Update the commit message and the comments before runtime PM call
>
> Changes in v2:
> - Fix the order of error handling
> - Update the commit message and add a comment before the runtime PM call
>
>  drivers/clk/mediatek/clk-mtk.c | 19 +++++++++++++++++++
>  drivers/clk/mediatek/clk-mtk.h |  2 ++
>  2 files changed, 21 insertions(+)
>
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index 2e55368dc4d8..ba1d1c495bc2 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -13,6 +13,7 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
>  #include <linux/slab.h>
>
>  #include "clk-mtk.h"
> @@ -494,6 +495,18 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
>                         return IS_ERR(base) ? PTR_ERR(base) : -ENOMEM;
>         }
>
> +
> +       if (mcd->need_runtime_pm) {
> +               devm_pm_runtime_enable(&pdev->dev);
> +               /*
> +                * Do a pm_runtime_resume_and_get() to workaround a possible
> +                * deadlock between clk_register() and the genpd framework.
> +                */
> +               r = pm_runtime_resume_and_get(&pdev->dev);
> +               if (r)
> +                       return r;
> +       }
> +
>         /* Calculate how many clk_hw_onecell_data entries to allocate */
>         num_clks = mcd->num_clks + mcd->num_composite_clks;
>         num_clks += mcd->num_fixed_clks + mcd->num_factor_clks;
> @@ -574,6 +587,9 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
>                         goto unregister_clks;
>         }
>
> +       if (mcd->need_runtime_pm)
> +               pm_runtime_put(&pdev->dev);
> +
>         return r;
>
>  unregister_clks:
> @@ -604,6 +620,9 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
>  free_base:
>         if (mcd->shared_io && base)
>                 iounmap(base);
> +
> +       if (mcd->need_runtime_pm)
> +               pm_runtime_put(&pdev->dev);
>         return r;
>  }
>
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 22096501a60a..c17fe1c2d732 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -237,6 +237,8 @@ struct mtk_clk_desc {
>
>         int (*clk_notifier_func)(struct device *dev, struct clk *clk);
>         unsigned int mfg_clk_idx;
> +
> +       bool need_runtime_pm;
>  };
>
>  int mtk_clk_pdev_probe(struct platform_device *pdev);
> --
> 2.43.0.472.g3155946c3a-goog
>


From lkp at intel.com  Thu Feb 22 20:29:28 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 23 Feb 2024 12:29:28 +0800
Subject: [linux-next:master] BUILD REGRESSION
 e31185ce00a96232308300008db193416ceb9769
Message-ID: <202402231222.DVB9DC74-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: e31185ce00a96232308300008db193416ceb9769  Add linux-next specific files for 20240222

Error/Warning reports:

https://lore.kernel.org/oe-kbuild-all/202402222223.h9rFmYj4-lkp at intel.com
https://lore.kernel.org/oe-kbuild-all/202402222314.J6A7eb4B-lkp at intel.com
https://lore.kernel.org/oe-kbuild-all/202402230537.2s6Nhfsn-lkp at intel.com

Error/Warning: (recently discovered and may have been fixed)

arch/arm/boot/compressed/misc.c:157:6: warning: no previous prototype for function '__fortify_panic' [-Wmissing-prototypes]
arch/arm/boot/compressed/misc.h:13:36: error: macro "fortify_panic" requires 2 arguments, but only 1 given
arch/sh/boot/compressed/../../../../lib/decompress_unxz.c:350:(.text+0x20b4): undefined reference to `__ubsan_handle_out_of_bounds'
sh4-linux-ld: arch/sh/boot/compressed/../../../../lib/xz/xz_dec_lzma2.c:751:(.text+0x904): undefined reference to `__ubsan_handle_out_of_bounds'

Error/Warning ids grouped by kconfigs:

gcc_recent_errors
|-- alpha-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- arc-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- arc-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- arc-randconfig-001-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- arc-randconfig-002-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- arc-randconfig-r122-20240223
|   |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
|   |-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|   |-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le32
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le64
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le64-degrades-to-integer
|   `-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|-- arc-randconfig-r133-20240223
|   |-- drivers-leds-flash-leds-ktd2692.c:sparse:sparse:symbol-ktd2692_timing-was-not-declared.-Should-it-be-static
|   |-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|   |-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|   |-- sound-core-sound_kunit.c:sparse:sparse:incorrect-type-in-argument-(different-base-types)-expected-restricted-snd_pcm_format_t-usertype-format-got-int
|   `-- sound-core-sound_kunit.c:sparse:sparse:restricted-snd_pcm_format_t-degrades-to-integer
|-- arm-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- arm-aspeed_g5_defconfig
|   `-- arch-arm-boot-compressed-misc.h:error:macro-fortify_panic-requires-arguments-but-only-given
|-- arm-multi_v7_defconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- arm-randconfig-001-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- arm-tegra_defconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- arm64-defconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- csky-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- csky-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- csky-randconfig-001-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- csky-randconfig-002-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- i386-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- i386-buildonly-randconfig-006-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- i386-randconfig-003-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- i386-randconfig-013-20240222
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-061-20240223
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le32
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le64
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le64-degrades-to-integer
|   `-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|-- i386-randconfig-062-20240223
|   |-- drivers-leds-flash-leds-ktd2692.c:sparse:sparse:symbol-ktd2692_timing-was-not-declared.-Should-it-be-static
|   |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
|   `-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|-- i386-randconfig-063-20240223
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   |-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|   |-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le32
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le64
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le32-degrades-to-integer
|   `-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le64-degrades-to-integer
|-- i386-randconfig-141-20240222
|   |-- drivers-bluetooth-btintel.c-btintel_read_version()-warn:passing-zero-to-PTR_ERR
|   `-- mm-page_owner.c-stack_print()-warn:unsigned-nr_entries-is-never-less-than-zero.
|-- loongarch-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- loongarch-randconfig-001-20240222
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- microblaze-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- microblaze-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- microblaze-randconfig-r111-20240223
|   |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
|   `-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|-- mips-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- nios2-randconfig-r054-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- openrisc-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- parisc-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- parisc-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- parisc-defconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- parisc64-defconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- powerpc-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- powerpc-randconfig-r113-20240223
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   |-- drivers-leds-flash-leds-ktd2692.c:sparse:sparse:symbol-ktd2692_timing-was-not-declared.-Should-it-be-static
|   |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
|   |-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|   |-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le32
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le64
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le64-degrades-to-integer
|   |-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|   |-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-struct-em_perf_state-table-got-struct-em_perf_state-noderef-__rcu
|   |-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-struct-kref-kref-got-struct-kref-noderef-__rcu
|   |-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-objp-got-struct-em_perf_table-noderef-__rcu-assigned-em_table
|   `-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-struct-em_perf_state-new_ps-got-struct-em_perf_state-noderef-__rcu
|-- powerpc64-randconfig-r123-20240223
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
|   `-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|-- riscv-randconfig-r112-20240223
|   |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
|   |-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|   |-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
|   `-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|-- s390-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- s390-randconfig-r123-20240222
|   |-- lib-string_helpers.c:sparse:sparse:incompatible-types-for-operation-(-):
|   `-- lib-string_helpers.c:sparse:sparse:incompatible-types-in-conditional-expression-(different-types):
|-- sh-buildonly-randconfig-r002-20230612
|   |-- arch-sh-boot-compressed-..-..-..-..-lib-decompress_unxz.c:(.text):undefined-reference-to-__ubsan_handle_out_of_bounds
|   `-- sh4-linux-ld:arch-sh-boot-compressed-..-..-..-..-lib-xz-xz_dec_lzma2.c:(.text):undefined-reference-to-__ubsan_handle_out_of_bounds
|-- sh-randconfig-002-20240222
|   |-- standard-input:Error:unknown-pseudo-op:l142
|   |-- standard-input:Warning:overflow-in-branch-to-.L90-converted-into-longer-instruction-sequence
|   `-- standard-input:Warning:overflow-in-branch-to-.L99-converted-into-longer-instruction-sequence
|-- sparc-allmodconfig
|   |-- Error:vdso-image-contains-dynamic-relocations
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   |-- sparc64-linux-ld:vclock_gettime.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|   |-- sparc64-linux-objcopy:arch-sparc-vdso-vdso64.so.dbg:No-such-file
|   `-- vclock_gettime.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|-- sparc-randconfig-001-20240222
|   `-- (.head.text):relocation-truncated-to-fit:R_SPARC_WDISP22-against-init.text
|-- sparc-randconfig-002-20240222
|   |-- Error:vdso-image-contains-dynamic-relocations
|   |-- sparc64-linux-ld:vclock_gettime.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|   |-- sparc64-linux-objcopy:arch-sparc-vdso-vdso64.so.dbg:No-such-file
|   `-- vclock_gettime.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|-- sparc-randconfig-r053-20240222
|   |-- Error:vdso-image-contains-dynamic-relocations
|   |-- sparc64-linux-ld:vclock_gettime.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|   |-- sparc64-linux-objcopy:arch-sparc-vdso-vdso64.so.dbg:No-such-file
|   `-- vclock_gettime.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|-- sparc64-allmodconfig
|   |-- Error:vdso-image-contains-dynamic-relocations
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   |-- sparc64-linux-ld:vclock_gettime.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|   |-- sparc64-linux-objcopy:arch-sparc-vdso-vdso64.so.dbg:No-such-file
|   `-- vclock_gettime.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|-- sparc64-allyesconfig
|   |-- Error:vdso-image-contains-dynamic-relocations
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   |-- sparc64-linux-ld:vclock_gettime.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|   |-- sparc64-linux-objcopy:arch-sparc-vdso-vdso64.so.dbg:No-such-file
|   `-- vclock_gettime.c:(.text):undefined-reference-to-__ubsan_handle_shift_out_of_bounds
|-- sparc64-randconfig-001-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- sparc64-randconfig-r121-20240223
|   |-- drivers-leds-flash-leds-ktd2692.c:sparse:sparse:symbol-ktd2692_timing-was-not-declared.-Should-it-be-static
|   |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
|   `-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|-- um-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- um-randconfig-r132-20240223
|   |-- drivers-leds-flash-leds-ktd2692.c:sparse:sparse:symbol-ktd2692_timing-was-not-declared.-Should-it-be-static
|   |-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le32
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le64
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le64-degrades-to-integer
|   `-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|-- x86_64-randconfig-005-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- x86_64-randconfig-006-20240222
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-014-20240222
|   `-- include-kunit-test.h:warning:s-directive-argument-is-null
|-- x86_64-randconfig-074-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-075-20240222
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-076-20240222
|   |-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|   `-- include-kunit-test.h:warning:s-directive-argument-is-null
|-- x86_64-randconfig-123-20240223
|   |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le32
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le64
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le32-degrades-to-integer
|   |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le64-degrades-to-integer
|   |-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
|   |-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-struct-em_perf_state-table-got-struct-em_perf_state-noderef-__rcu
|   |-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-struct-kref-kref-got-struct-kref-noderef-__rcu
|   |-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-objp-got-struct-em_perf_table-noderef-__rcu-assigned-em_table
|   `-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-struct-em_perf_state-new_ps-got-struct-em_perf_state-noderef-__rcu
`-- x86_64-randconfig-161-20240222
    |-- mm-page_owner.c-stack_print()-warn:unsigned-nr_entries-is-never-less-than-zero.
    `-- mm-userfaultfd.c-uffd_move_lock()-error:we-previously-assumed-src_vmap-could-be-null-(see-line-)
clang_recent_errors
|-- arm-defconfig
|   |-- arch-arm-boot-compressed-misc.c:warning:no-previous-prototype-for-function-__fortify_panic
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- arm-randconfig-003-20240222
|   `-- arch-arm-boot-compressed-misc.c:warning:no-previous-prototype-for-function-__fortify_panic
|-- arm-randconfig-004-20240222
|   `-- arch-arm-boot-compressed-misc.c:warning:no-previous-prototype-for-function-__fortify_panic
|-- arm-realview_defconfig
|   `-- arch-arm-boot-compressed-misc.c:warning:no-previous-prototype-for-function-__fortify_panic
|-- arm64-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- hexagon-randconfig-002-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-buildonly-randconfig-002-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- i386-buildonly-randconfig-005-20240222
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-004-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- i386-randconfig-012-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- i386-randconfig-053-20240222
|   |-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- powerpc-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- powerpc-randconfig-002-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- powerpc-randconfig-003-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- powerpc64-randconfig-001-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- riscv-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- riscv-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- riscv-defconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- riscv-randconfig-001-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- s390-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- x86_64-allmodconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- x86_64-allyesconfig
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- x86_64-buildonly-randconfig-001-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-buildonly-randconfig-004-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-002-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- x86_64-randconfig-013-20240222
|   `-- drivers-gpu-drm-nouveau-nvkm-subdev-gsp-r535.c:warning:Function-parameter-or-struct-member-gsp-not-described-in-nvkm_gsp_radix3_sg
|-- x86_64-randconfig-103-20240222
|   `-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
|-- x86_64-randconfig-121-20240223
|   |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
|   `-- io_uring-io_uring.c:sparse:sparse:cast-to-restricted-io_req_flags_t
`-- x86_64-randconfig-122-20240223
    |-- drivers-leds-flash-leds-ktd2692.c:sparse:sparse:symbol-ktd2692_timing-was-not-declared.-Should-it-be-static
    |-- drivers-video-backlight-ktd2801-backlight.c:sparse:sparse:symbol-ktd2801_timing-was-not-declared.-Should-it-be-static
    |-- fs-ntfs3-frecord.c:warning:unused-variable-i_size
    |-- fs-ntfs3-fslog.c:sparse:sparse:restricted-__le32-degrades-to-integer
    |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le32
    |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:cast-to-restricted-__le64
    |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le32-degrades-to-integer
    |-- include-trace-..-..-drivers-bus-mhi-host-trace.h:sparse:sparse:restricted-__le64-degrades-to-integer
    |-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-struct-em_perf_state-table-got-struct-em_perf_state-noderef-__rcu
    |-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-struct-kref-kref-got-struct-kref-noderef-__rcu
    |-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-objp-got-struct-em_perf_table-noderef-__rcu-assigned-em_table
    `-- kernel-power-energy_model.c:sparse:sparse:incorrect-type-in-assignment-(different-address-spaces)-expected-struct-em_perf_state-new_ps-got-struct-em_perf_state-noderef-__rcu

elapsed time: 922m

configs tested: 179
configs skipped: 4

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                   randconfig-001-20240222   gcc  
arc                   randconfig-002-20240222   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                     am200epdkit_defconfig   gcc  
arm                                 defconfig   clang
arm                        multi_v7_defconfig   gcc  
arm                       omap2plus_defconfig   gcc  
arm                   randconfig-001-20240222   gcc  
arm                   randconfig-002-20240222   gcc  
arm                   randconfig-003-20240222   clang
arm                   randconfig-004-20240222   clang
arm                        realview_defconfig   clang
arm                           tegra_defconfig   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240222   clang
arm64                 randconfig-002-20240222   gcc  
arm64                 randconfig-003-20240222   clang
arm64                 randconfig-004-20240222   clang
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240222   gcc  
csky                  randconfig-002-20240222   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
hexagon               randconfig-001-20240222   clang
hexagon               randconfig-002-20240222   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-001-20240222   gcc  
i386         buildonly-randconfig-002-20240222   clang
i386         buildonly-randconfig-003-20240222   clang
i386         buildonly-randconfig-004-20240222   gcc  
i386         buildonly-randconfig-005-20240222   clang
i386         buildonly-randconfig-006-20240222   gcc  
i386                                defconfig   clang
i386                  randconfig-001-20240222   clang
i386                  randconfig-002-20240222   clang
i386                  randconfig-003-20240222   gcc  
i386                  randconfig-004-20240222   clang
i386                  randconfig-005-20240222   gcc  
i386                  randconfig-006-20240222   clang
i386                  randconfig-011-20240222   gcc  
i386                  randconfig-012-20240222   clang
i386                  randconfig-013-20240222   gcc  
i386                  randconfig-014-20240222   gcc  
i386                  randconfig-015-20240222   clang
i386                  randconfig-016-20240222   gcc  
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240222   gcc  
loongarch             randconfig-002-20240222   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
m68k                          multi_defconfig   gcc  
m68k                        stmark2_defconfig   gcc  
microblaze                       alldefconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                           gcw0_defconfig   clang
mips                            gpr_defconfig   clang
mips                      pic32mzda_defconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240222   gcc  
nios2                 randconfig-002-20240222   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                randconfig-001-20240222   gcc  
parisc                randconfig-002-20240222   gcc  
parisc64                            defconfig   gcc  
powerpc                    adder875_defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc                        cell_defconfig   gcc  
powerpc               randconfig-001-20240222   clang
powerpc               randconfig-002-20240222   clang
powerpc               randconfig-003-20240222   clang
powerpc64             randconfig-001-20240222   clang
powerpc64             randconfig-002-20240222   clang
powerpc64             randconfig-003-20240222   gcc  
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                    nommu_k210_defconfig   clang
riscv                 randconfig-001-20240222   clang
riscv                 randconfig-002-20240222   gcc  
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240222   gcc  
s390                  randconfig-002-20240222   clang
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                         ap325rxa_defconfig   gcc  
sh                                  defconfig   gcc  
sh                    randconfig-001-20240222   gcc  
sh                    randconfig-002-20240222   gcc  
sh                          rsk7264_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240222   gcc  
sparc64               randconfig-002-20240222   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                    randconfig-001-20240222   clang
um                    randconfig-002-20240222   clang
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240222   clang
x86_64       buildonly-randconfig-002-20240222   clang
x86_64       buildonly-randconfig-003-20240222   gcc  
x86_64       buildonly-randconfig-004-20240222   clang
x86_64       buildonly-randconfig-005-20240222   gcc  
x86_64       buildonly-randconfig-006-20240222   gcc  
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240222   clang
x86_64                randconfig-002-20240222   clang
x86_64                randconfig-003-20240222   clang
x86_64                randconfig-004-20240222   clang
x86_64                randconfig-005-20240222   gcc  
x86_64                randconfig-006-20240222   gcc  
x86_64                randconfig-011-20240222   clang
x86_64                randconfig-012-20240222   gcc  
x86_64                randconfig-013-20240222   clang
x86_64                randconfig-014-20240222   gcc  
x86_64                randconfig-015-20240222   clang
x86_64                randconfig-016-20240222   clang
x86_64                randconfig-071-20240222   clang
x86_64                randconfig-072-20240222   clang
x86_64                randconfig-073-20240222   clang
x86_64                randconfig-074-20240222   gcc  
x86_64                randconfig-075-20240222   gcc  
x86_64                randconfig-076-20240222   gcc  
x86_64                          rhel-8.3-rust   clang
xtensa                            allnoconfig   gcc  
xtensa                randconfig-001-20240222   gcc  
xtensa                randconfig-002-20240222   gcc  
xtensa                    xip_kc705_defconfig   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From wenst at chromium.org  Thu Feb 22 20:43:39 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Fri, 23 Feb 2024 12:43:39 +0800
Subject: [PATCH v3 2/2] clk: mediatek: mt8183: Enable need_runtime_pm on mt8183-mfgcfg
In-Reply-To: <20240108081834.408403-2-treapking@chromium.org>
References: <20240108081834.408403-1-treapking@chromium.org> <20240108081834.408403-2-treapking@chromium.org>
Message-ID: <CAGXv+5GoAauw77wVXx6SXsSma9zP_A1vXLRo=GH2ptjvY=kLgA@mail.gmail.com>

On Mon, Jan 8, 2024 at 4:18?PM Pin-yen Lin <treapking at chromium.org> wrote:
>
> mt8183-mfgcfg has a mutual dependency with genpd during the probing
> stage, so enable need_runtim_pm to prevent a deadlock in the following
> call stack:
>
> CPU0:  genpd_lock --> clk_prepare_lock
> genpd_power_off_work_fn()
>  genpd_lock()
>  generic_pm_domain::power_off()
>     clk_unprepare()
>       clk_prepare_lock()
>
> CPU1: clk_prepare_lock --> genpd_lock
> clk_register()
>   __clk_core_init()
>     clk_prepare_lock()
>     clk_pm_runtime_get()
>       genpd_lock()
>
> Do a runtime PM get at the probe function to make sure clk_register()
> won't acquire the genpd lock.
>
> Fixes: acddfc2c261b ("clk: mediatek: Add MT8183 clock support")
> Signed-off-by: Pin-yen Lin <treapking at chromium.org>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>

Note that this compliments a patch [1] adding the power domain for the mfgcfg
clock controller node, which has been floating around for almost 3 years.

[1] https://lore.kernel.org/linux-mediatek/20210414073108.3899082-1-ikjn at chromium.org/

> ---
>
> (no changes since v1)
>
>  drivers/clk/mediatek/clk-mt8183-mfgcfg.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
> index ba504e19d420..62d876e150e1 100644
> --- a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
> +++ b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
> @@ -29,6 +29,7 @@ static const struct mtk_gate mfg_clks[] = {
>  static const struct mtk_clk_desc mfg_desc = {
>         .clks = mfg_clks,
>         .num_clks = ARRAY_SIZE(mfg_clks),
> +       .need_runtime_pm = true,
>  };
>
>  static const struct of_device_id of_match_clk_mt8183_mfg[] = {
> --
> 2.43.0.472.g3155946c3a-goog
>


From anshuman.khandual at arm.com  Thu Feb 22 21:28:12 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 23 Feb 2024 10:58:12 +0530
Subject: [PATCH V16 1/8] arm64/sysreg: Add BRBE registers and fields
In-Reply-To: <7fe52cb9-12b9-4b03-8e55-08e59b4bef27@sirena.org.uk>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-2-anshuman.khandual@arm.com>
 <ZdYAJvZf4Ut5f5Rf@FVFF77S0Q05N>
 <e89ecbde-0967-4b8e-af77-3a72f207f3d7@sirena.org.uk>
 <ZdYDJPe1n5-V-AnT@FVFF77S0Q05N>
 <7fe52cb9-12b9-4b03-8e55-08e59b4bef27@sirena.org.uk>
Message-ID: <b2dfcaf1-f466-4e81-8ca4-02bf3fa837e5@arm.com>



On 2/21/24 19:37, Mark Brown wrote:
> On Wed, Feb 21, 2024 at 02:05:24PM +0000, Mark Rutland wrote:
>> On Wed, Feb 21, 2024 at 01:59:03PM +0000, Mark Brown wrote:
>>> On Wed, Feb 21, 2024 at 01:52:38PM +0000, Mark Rutland wrote:
> 
>>> It's a good point about the sorting, though the file is currently mostly
>>> sorted by encoding rather than alphanumerically (similarly to how
>>> sysreg.h was done).
> 
>> Sure, we're inconsistent. I'd just prefer that there's *some* local ordering
>> here, as the patch is neither ordered as above nor by encoding:
> 
> I agree, I'm just saying that if we're going to fix the ordering it'd
> probably be better to go along with what the rest of the file is doing.

Sure, will change the registers order as has been suggested earlier i.e
alphanumerically instead. Because ordering registers with encoding will
push BRBCR_EL2/12 after all other BRBE registers, including BRBIDR0_EL1.

After the change

BRBCR_EL1
BRBCR_EL12
BRBCR_EL2


From tudor.ambarus at linaro.org  Thu Feb 22 21:37:15 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Fri, 23 Feb 2024 05:37:15 +0000
Subject: [PATCH v2 0/7] ARM: dts: samsung: specify the SPI FIFO depth
In-Reply-To: <be85edb1-4f65-4b5e-a137-76e4e92d8fe4@linaro.org>
References: <20240216140449.2564625-1-tudor.ambarus@linaro.org>
 <be85edb1-4f65-4b5e-a137-76e4e92d8fe4@linaro.org>
Message-ID: <115e1e9f-2067-41f4-8642-43e9d6819798@linaro.org>



On 2/22/24 08:49, Krzysztof Kozlowski wrote:
> On 16/02/2024 15:04, Tudor Ambarus wrote:
>> Bindings patch sent but not yet integrated:
>> https://lore.kernel.org/linux-spi/20240216070555.2483977-2-tudor.ambarus at linaro.org/
> 
> I still wait for bindings to be applied. This means it might be too late
> to apply it for this cycle. Just letting you know, that I did not forget
> about this patchset.
> 

Thanks, Krzysztof, no worries. I'll reply here once Mark queues the
bindings.

Cheers,
ta


From christophe.leroy at csgroup.eu  Thu Feb 22 21:38:18 2024
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 23 Feb 2024 05:38:18 +0000
Subject: [RESEND2 PATCH net v4 2/2] soc: fsl: qbman: Use raw spinlock for
 cgr_lock
In-Reply-To: <20240222170749.2607485-2-sean.anderson@linux.dev>
References: <20240222170749.2607485-1-sean.anderson@linux.dev>
 <20240222170749.2607485-2-sean.anderson@linux.dev>
Message-ID: <53b401d7-934c-4937-ab83-6732af47668d@csgroup.eu>



Le 22/02/2024 ? 18:07, Sean Anderson a ?crit?:
> [Vous ne recevez pas souvent de courriers de sean.anderson at linux.dev. D?couvrez pourquoi ceci est important ? https://aka.ms/LearnAboutSenderIdentification ]
> 
> cgr_lock may be locked with interrupts already disabled by
> smp_call_function_single. As such, we must use a raw spinlock to avoid
> problems on PREEMPT_RT kernels. Although this bug has existed for a
> while, it was not apparent until commit ef2a8d5478b9 ("net: dpaa: Adjust
> queue depth on rate change") which invokes smp_call_function_single via
> qman_update_cgr_safe every time a link goes up or down.

Why a raw spinlock to avoid problems on PREEMPT_RT, can you elaborate ?

If the problem is that interrupts are already disabled, shouldn't you 
just change the spin_lock_irq() by spin_lock_irqsave() ?

Christophe


> 
> Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
> CC: stable at vger.kernel.org
> Reported-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> Closes: https://lore.kernel.org/all/20230323153935.nofnjucqjqnz34ej at skbuf/
> Reported-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
> Closes: https://lore.kernel.org/linux-arm-kernel/87wmsyvclu.fsf at pengutronix.de/
> Signed-off-by: Sean Anderson <sean.anderson at linux.dev>
> Reviewed-by: Camelia Groza <camelia.groza at nxp.com>
> Tested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> 
> ---
> 
> Changes in v4:
> - Add a note about how raw spinlocks aren't quite right
> 
> Changes in v3:
> - Change blamed commit to something more appropriate
> 
>   drivers/soc/fsl/qbman/qman.c | 25 ++++++++++++++-----------
>   1 file changed, 14 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
> index 1bf1f1ea67f0..7e9074519ad2 100644
> --- a/drivers/soc/fsl/qbman/qman.c
> +++ b/drivers/soc/fsl/qbman/qman.c
> @@ -991,7 +991,7 @@ struct qman_portal {
>          /* linked-list of CSCN handlers. */
>          struct list_head cgr_cbs;
>          /* list lock */
> -       spinlock_t cgr_lock;
> +       raw_spinlock_t cgr_lock;
>          struct work_struct congestion_work;
>          struct work_struct mr_work;
>          char irqname[MAX_IRQNAME];
> @@ -1281,7 +1281,7 @@ static int qman_create_portal(struct qman_portal *portal,
>                  /* if the given mask is NULL, assume all CGRs can be seen */
>                  qman_cgrs_fill(&portal->cgrs[0]);
>          INIT_LIST_HEAD(&portal->cgr_cbs);
> -       spin_lock_init(&portal->cgr_lock);
> +       raw_spin_lock_init(&portal->cgr_lock);
>          INIT_WORK(&portal->congestion_work, qm_congestion_task);
>          INIT_WORK(&portal->mr_work, qm_mr_process_task);
>          portal->bits = 0;
> @@ -1456,11 +1456,14 @@ static void qm_congestion_task(struct work_struct *work)
>          union qm_mc_result *mcr;
>          struct qman_cgr *cgr;
> 
> -       spin_lock_irq(&p->cgr_lock);
> +       /*
> +        * FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock!
> +        */
> +       raw_spin_lock_irq(&p->cgr_lock);
>          qm_mc_start(&p->p);
>          qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
>          if (!qm_mc_result_timeout(&p->p, &mcr)) {
> -               spin_unlock_irq(&p->cgr_lock);
> +               raw_spin_unlock_irq(&p->cgr_lock);
>                  dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
>                  qman_p_irqsource_add(p, QM_PIRQ_CSCI);
>                  return;
> @@ -1476,7 +1479,7 @@ static void qm_congestion_task(struct work_struct *work)
>          list_for_each_entry(cgr, &p->cgr_cbs, node)
>                  if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
>                          cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
> -       spin_unlock_irq(&p->cgr_lock);
> +       raw_spin_unlock_irq(&p->cgr_lock);
>          qman_p_irqsource_add(p, QM_PIRQ_CSCI);
>   }
> 
> @@ -2440,7 +2443,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
>          preempt_enable();
> 
>          cgr->chan = p->config->channel;
> -       spin_lock_irq(&p->cgr_lock);
> +       raw_spin_lock_irq(&p->cgr_lock);
> 
>          if (opts) {
>                  struct qm_mcc_initcgr local_opts = *opts;
> @@ -2477,7 +2480,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
>              qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
>                  cgr->cb(p, cgr, 1);
>   out:
> -       spin_unlock_irq(&p->cgr_lock);
> +       raw_spin_unlock_irq(&p->cgr_lock);
>          put_affine_portal();
>          return ret;
>   }
> @@ -2512,7 +2515,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
>                  return -EINVAL;
> 
>          memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
> -       spin_lock_irqsave(&p->cgr_lock, irqflags);
> +       raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
>          list_del(&cgr->node);
>          /*
>           * If there are no other CGR objects for this CGRID in the list,
> @@ -2537,7 +2540,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
>                  /* add back to the list */
>                  list_add(&cgr->node, &p->cgr_cbs);
>   release_lock:
> -       spin_unlock_irqrestore(&p->cgr_lock, irqflags);
> +       raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
>          put_affine_portal();
>          return ret;
>   }
> @@ -2577,9 +2580,9 @@ static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
>          if (!p)
>                  return -EINVAL;
> 
> -       spin_lock_irqsave(&p->cgr_lock, irqflags);
> +       raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
>          ret = qm_modify_cgr(cgr, 0, opts);
> -       spin_unlock_irqrestore(&p->cgr_lock, irqflags);
> +       raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
>          put_affine_portal();
>          return ret;
>   }
> --
> 2.35.1.1320.gc452695387.dirty
> 

From hbathini at linux.ibm.com  Thu Feb 22 21:41:41 2024
From: hbathini at linux.ibm.com (Hari Bathini)
Date: Fri, 23 Feb 2024 11:11:41 +0530
Subject: [PATCH v2 00/14] Split crash out from kexec and clean up related
 config items
In-Reply-To: <20240222132936.e7dc50acbf5d1b653cb2e02c@linux-foundation.org>
References: <20240119145241.769622-1-bhe@redhat.com>
 <9101bb07-70f1-476c-bec9-ec67e9899744@linux.ibm.com>
 <Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv>
 <559f2595-1477-4ef0-80e4-85ae8b426de7@linux.ibm.com>
 <20240221125752.36fbfe9c307496313198b60f@linux-foundation.org>
 <3393a42f-d9b3-4031-bdef-78bb2ce758f1@linux.ibm.com>
 <20240222132936.e7dc50acbf5d1b653cb2e02c@linux-foundation.org>
Message-ID: <386202f8-852c-477e-b9c4-f37896559a34@linux.ibm.com>



On 23/02/24 2:59 am, Andrew Morton wrote:
> On Thu, 22 Feb 2024 10:47:29 +0530 Hari Bathini <hbathini at linux.ibm.com> wrote:
> 
>>
>>
>> On 22/02/24 2:27 am, Andrew Morton wrote:
>>> On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini <hbathini at linux.ibm.com> wrote:
>>>
>>>> On 04/02/24 8:56 am, Baoquan He wrote:
>>>>>>> Hope Hari and Pingfan can help have a look, see if
>>>>>>> it's doable. Now, I make it either have both kexec and crash enabled, or
>>>>>>> disable both of them altogether.
>>>>>>
>>>>>> Sure. I will take a closer look...
>>>>> Thanks a lot. Please feel free to post patches to make that, or I can do
>>>>> it with your support or suggestion.
>>>>
>>>> Tested your changes and on top of these changes, came up with the below
>>>> changes to get it working for powerpc:
>>>>
>>>>    
>>>> https://lore.kernel.org/all/20240213113150.1148276-1-hbathini at linux.ibm.com/
>>>
>>> So can we take it that you're OK with Baoquan's series as-is?
>>
>> Hi Andrew,
>>
>> If you mean
>>
>> v3 (https://lore.kernel.org/all/20240124051254.67105-1-bhe at redhat.com/)
>> +
>> follow-up from Baoquan
>> (https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z at MiWiFi-R3L-srv/)
>>
>> Yes.
>>
> 
> Can I add your Acked-by: and/or Tested-by: to the patches in this series?

Sure, Andrew.

Acked-by: Hari Bathini <hbathini at linux.ibm.com>

for..

Patches 1-5 & 8 in:

   https://lore.kernel.org/all/20240124051254.67105-1-bhe at redhat.com/

and this follow-up patch:

   https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z at MiWiFi-R3L-srv/

Thanks
Hari


From jirislaby at kernel.org  Thu Feb 22 21:42:15 2024
From: jirislaby at kernel.org (Jiri Slaby)
Date: Fri, 23 Feb 2024 06:42:15 +0100
Subject: [PATCH v1 02/14] serial: core: Add UPIO_UNSET constant for unset
 port type
In-Reply-To: <ZddKaaB7HO0CyldD@smile.fi.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-3-andriy.shevchenko@linux.intel.com>
 <5aeee02f-45a6-48e5-a6f4-e55b76d4b959@kernel.org>
 <ZddKaaB7HO0CyldD@smile.fi.intel.com>
Message-ID: <fa46f220-a1c4-43f4-91e1-5929ff335be0@kernel.org>

On 22. 02. 24, 14:21, Andy Shevchenko wrote:
> On Thu, Feb 22, 2024 at 07:58:32AM +0100, Jiri Slaby wrote:
>> On 21. 02. 24, 19:31, Andy Shevchenko wrote:
> 
> ...
> 
>>>    	unsigned char		iotype;			/* io access style */
>>> +#define UPIO_UNSET		((unsigned char)~0U)	/* UCHAR_MAX */
>>
>> Perhaps making the var u8 and this U8_MAX then? It would make more sense to
>> me.
> 
> WFM, should it be a separate change?

Likely.

> Btw, how can I justify it?

Hmm, thinking about it, why is it not an enum?

But it could be also an u8 because you want it be exactly 8 bits as you 
want to be sure values up to 255 fit.

thanks,
-- 
js
suse labs



From ck.hu at mediatek.com  Thu Feb 22 21:50:23 2024
From: ck.hu at mediatek.com (=?utf-8?B?Q0sgSHUgKOiDoeS/iuWFiSk=?=)
Date: Fri, 23 Feb 2024 05:50:23 +0000
Subject: [PATCH v3 1/1] drm/mediatek: Filter modes according to hardware
 capability
In-Reply-To: <20240220093711.20546-2-shawn.sung@mediatek.com>
References: <20240220093711.20546-1-shawn.sung@mediatek.com>
	 <20240220093711.20546-2-shawn.sung@mediatek.com>
Message-ID: <e16f7a6ce9f2271846f06184fb89cd5cc4ae0682.camel@mediatek.com>

Hi, Shawn:

On Tue, 2024-02-20 at 17:37 +0800, Shawn Sung wrote:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> We found a stability issue on MT8188 when connecting an external
> monitor
> in 2560x1440 at 144Hz mode. Checked with the designer, there is a
> function
> called "prefetch" which is working during VBP (triggered by VSYNC).
> If the duration of VBP is too short, the throughput requirement could
> increase more than 3 times and lead to stability issues.
> 
> The mode settings that VDOSYS supports are mainly affected by clock
> rate and throughput, display driver should filter these settings
> according to the SoC's limitation to avoid unstable conditions.
> 
> Since currently the mode filter is only available on MT8195 and
> MT8188
> and they share the same compatible name, the reference number (8250)
> is hard coded instead of in the driver data.

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

> 
> Signed-off-by: Hsiao Chien Sung <
> shawn.sung at mediatek.corp-partner.google.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  4 ++
>  drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 65
> +++++++++++++++++++
>  .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 17 +++++
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 17 +++++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  1 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   | 12 ++++
>  6 files changed, 116 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index eb738f14f09e3..4a5661334fb1a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -72,6 +72,8 @@ void mtk_merge_advance_config(struct device *dev,
> unsigned int l_w, unsigned int
>  			      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);
> +enum drm_mode_status mtk_merge_mode_valid(struct device *dev,
> +					  const struct drm_display_mode
> *mode);
>  
>  void mtk_ovl_bgclr_in_on(struct device *dev);
>  void mtk_ovl_bgclr_in_off(struct device *dev);
> @@ -130,6 +132,8 @@ unsigned int mtk_ovl_adaptor_layer_nr(struct
> device *dev);
>  struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev);
>  const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
>  size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
> +enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
> +						const struct
> drm_display_mode *mode);
>  
>  void mtk_rdma_bypass_shadow(struct device *dev);
>  int mtk_rdma_clk_enable(struct device *dev);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> index c19fb1836034d..80953b3e8ace6 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> @@ -223,6 +223,71 @@ void mtk_merge_clk_disable(struct device *dev)
>  	clk_disable_unprepare(priv->clk);
>  }
>  
> +enum drm_mode_status mtk_merge_mode_valid(struct device *dev,
> +					  const struct drm_display_mode
> *mode)
> +{
> +	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> +	unsigned long rate = 0;
> +
> +	rate = clk_get_rate(priv->clk);
> +
> +	/* Convert to KHz and round the number */
> +	rate = (rate + 500) / 1000;
> +
> +	if (rate && mode->clock > rate) {
> +		dev_dbg(dev, "invalid clock: %d (>%lu)\n", mode->clock, 
> rate);
> +		return MODE_CLOCK_HIGH;
> +	}
> +
> +	/*
> +	 * Measure the bandwidth requirement of hardware prefetch (per
> frame)
> +	 *
> +	 * let N = prefetch buffer size in lines
> +	 *         (ex. N=3, then prefetch buffer size = 3 lines)
> +	 *
> +	 * prefetch size = htotal * N (pixels)
> +	 * time per line = 1 / fps / vtotal (seconds)
> +	 * duration      = vbp * time per line
> +	 *               = vbp / fps / vtotal
> +	 *
> +	 * data rate = prefetch size / duration
> +	 *           = htotal * N / (vbp / fps / vtotal)
> +	 *           = htotal * vtotal * fps * N / vbp
> +	 *           = clk * N / vbp (pixels per second)
> +	 *
> +	 * Say 4K60 (CEA-861) is the maximum mode supported by the SoC
> +	 * data rate = 594000K * N / 72 = 8250 (standard)
> +	 * (remove K * N due to the same unit)
> +	 *
> +	 * For 2560x1440 at 144 (clk=583600K, vbp=17):
> +	 * data rate = 583600 / 17 ~= 34329 > 8250 (NG)
> +	 *
> +	 * For 2560x1440 at 120 (clk=497760K, vbp=77):
> +	 * data rate = 497760 / 77 ~= 6464 < 8250 (OK)
> +	 *
> +	 * A non-standard 4K60 timing (clk=521280K, vbp=54)
> +	 * data rate = 521280 / 54 ~= 9653 > 8250 (NG)
> +	 *
> +	 * Bandwidth requirement of hardware prefetch increases
> significantly
> +	 * when the VBP decreases (more than 4x in this example).
> +	 *
> +	 * The proposed formula is only one way to estimate whether our
> SoC
> +	 * supports the mode setting. The basic idea behind it is just
> to check
> +	 * if the data rate requirement is too high (directly
> proportional to
> +	 * pixel clock, inversely proportional to vbp). Please adjust
> the
> +	 * function if it doesn't fit your situation in the future.
> +	 */
> +	rate = mode->clock / (mode->vtotal - mode->vsync_end);
> +
> +	if (rate > 8250) {
> +		dev_dbg(dev, "invalid rate: %lu (>8250): " DRM_MODE_FMT
> "\n",
> +			rate, DRM_MODE_ARG(mode));
> +		return MODE_BAD;
> +	}
> +
> +	return MODE_OK;
> +}
> +
>  static int mtk_disp_merge_bind(struct device *dev, struct device
> *master,
>  			       void *data)
>  {
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> index 10d23e76acaa9..6d4334955e3d3 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> @@ -88,6 +88,7 @@ static const struct mtk_ddp_comp_funcs ethdr = {
>  static const struct mtk_ddp_comp_funcs merge = {
>  	.clk_enable = mtk_merge_clk_enable,
>  	.clk_disable = mtk_merge_clk_disable,
> +	.mode_valid = mtk_merge_mode_valid,
>  };
>  
>  static const struct mtk_ddp_comp_funcs padding = {
> @@ -341,6 +342,22 @@ void mtk_ovl_adaptor_clk_disable(struct device
> *dev)
>  	}
>  }
>  
> +enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
> +						const struct
> drm_display_mode *mode)
> +
> +{
> +	int i;
> +	struct mtk_disp_ovl_adaptor *ovl_adaptor =
> dev_get_drvdata(dev);
> +
> +	for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
> +		dev = ovl_adaptor->ovl_adaptor_comp[i];
> +		if (!dev || !comp_matches[i].funcs->mode_valid)
> +			continue;
> +		return comp_matches[i].funcs->mode_valid(dev, mode);
> +	}
> +	return MODE_OK;
> +}
> +
>  unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev)
>  {
>  	return MTK_OVL_ADAPTOR_LAYER_NUM;
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 1dac8d0fbc669..14cf75fa217f9 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -212,6 +212,22 @@ static void mtk_drm_crtc_destroy_state(struct
> drm_crtc *crtc,
>  	kfree(to_mtk_crtc_state(state));
>  }
>  
> +static enum drm_mode_status
> +mtk_drm_crtc_mode_valid(struct drm_crtc *crtc,
> +			const struct drm_display_mode *mode)
> +{
> +	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
> +	enum drm_mode_status status = MODE_OK;
> +	int i;
> +
> +	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
> +		status = mtk_ddp_comp_mode_valid(mtk_crtc->ddp_comp[i], 
> mode);
> +		if (status != MODE_OK)
> +			break;
> +	}
> +	return status;
> +}
> +
>  static bool mtk_drm_crtc_mode_fixup(struct drm_crtc *crtc,
>  				    const struct drm_display_mode
> *mode,
>  				    struct drm_display_mode
> *adjusted_mode)
> @@ -830,6 +846,7 @@ static const struct drm_crtc_funcs mtk_crtc_funcs
> = {
>  static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
>  	.mode_fixup	= mtk_drm_crtc_mode_fixup,
>  	.mode_set_nofb	= mtk_drm_crtc_mode_set_nofb,
> +	.mode_valid	= mtk_drm_crtc_mode_valid,
>  	.atomic_begin	= mtk_drm_crtc_atomic_begin,
>  	.atomic_flush	= mtk_drm_crtc_atomic_flush,
>  	.atomic_enable	= mtk_drm_crtc_atomic_enable,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 9633e860cc3ce..94590227c56a9 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -416,6 +416,7 @@ static const struct mtk_ddp_comp_funcs
> ddp_ovl_adaptor = {
>  	.remove = mtk_ovl_adaptor_remove_comp,
>  	.get_formats = mtk_ovl_adaptor_get_formats,
>  	.get_num_formats = mtk_ovl_adaptor_get_num_formats,
> +	.mode_valid = mtk_ovl_adaptor_mode_valid,
>  };
>  
>  static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] =
> {
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index f8c7e8d8ddc12..215b7234ff13c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -12,6 +12,8 @@
>  #include <linux/soc/mediatek/mtk-mmsys.h>
>  #include <linux/soc/mediatek/mtk-mutex.h>
>  
> +#include <drm/drm_modes.h>
> +
>  struct device;
>  struct device_node;
>  struct drm_crtc;
> @@ -84,6 +86,7 @@ struct mtk_ddp_comp_funcs {
>  	void (*add)(struct device *dev, struct mtk_mutex *mutex);
>  	void (*remove)(struct device *dev, struct mtk_mutex *mutex);
>  	unsigned int (*encoder_index)(struct device *dev);
> +	enum drm_mode_status (*mode_valid)(struct device *dev, const
> struct drm_display_mode *mode);
>  };
>  
>  struct mtk_ddp_comp {
> @@ -125,6 +128,15 @@ static inline void
> mtk_ddp_comp_clk_disable(struct mtk_ddp_comp *comp)
>  		comp->funcs->clk_disable(comp->dev);
>  }
>  
> +static inline
> +enum drm_mode_status mtk_ddp_comp_mode_valid(struct mtk_ddp_comp
> *comp,
> +					     const struct
> drm_display_mode *mode)
> +{
> +	if (comp && comp->funcs && comp->funcs->mode_valid)
> +		return comp->funcs->mode_valid(comp->dev, mode);
> +	return MODE_OK;
> +}
> +
>  static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
>  				       unsigned int w, unsigned int h,
>  				       unsigned int vrefresh, unsigned
> int bpc,

From sudeep.holla at arm.com  Thu Feb 22 22:15:22 2024
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 23 Feb 2024 06:15:22 +0000
Subject: SCMI support for sensors shared memory?
In-Reply-To: <4ed10434-0620-4fd3-b595-61f2c6080722@broadcom.com>
References: <4ed10434-0620-4fd3-b595-61f2c6080722@broadcom.com>
Message-ID: <20240223061522.lmhmwobub34mbfgd@bogus>

On Thu, Feb 22, 2024 at 11:35:21AM -0800, Florian Fainelli wrote:
> Hi Sudeep, Christian,
>
> AFAICT there is no support within scmi-hwmon.c for a sensors shared memory,
> even though the SCMI specification describes how to use it.
>

Correct, in fact lots of other features which includes statistic information
that use additional shared memory like this one is not supported in the
kernel driver. Though there was request to have such a feature when the
specification was initially developed, it was soon realised that most of
the platforms can't afford to have large amounts of shared memory needed
for this purpose. Yes even 512 or 1kB can be considered large on some
platforms that use dedicated SRAM for this SCMI communication as the
co-processor incharge of providing SCMI platform may not have access to
DRAM and hence DRAM curv eout is not an option.

So AFAIU, there was no known platform requiring this feature until now,
hence we never added it to the kernel as we can't test the same.

> Is this something that you are working on by any chance, or should we
> contribute it once we have it ready?
>

We are not working on it. So feel free to contribute, happy to review and
get that merged if required/supported on certain platforms.

--
Regards,
Sudeep


From arnd at arndb.de  Thu Feb 22 22:32:32 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 23 Feb 2024 07:32:32 +0100
Subject: [PATCH -next] arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION
In-Reply-To: <7396cdc0-e878-48fe-85b9-d88611d28444@huawei.com>
References: <20240220081527.23408-1-liuyuntao12@huawei.com>
 <1342759e-b967-4ec4-98d5-48146f81f695@app.fastmail.com>
 <38c09a4b-69cc-4dc5-8a68-e5f5597613ac@huawei.com>
 <30b01c65-12f2-4ee0-81d5-c7a2da2c36b4@app.fastmail.com>
 <4e9396ca-460b-49ca-818e-73f0a8997b15@huawei.com>
 <58297ee9-4f33-4b3b-bd00-b44e86965892@app.fastmail.com>
 <7396cdc0-e878-48fe-85b9-d88611d28444@huawei.com>
Message-ID: <e7f5c111-6c8b-47e6-a6af-05abdb9c6595@app.fastmail.com>

On Fri, Feb 23, 2024, at 02:39, liuyuntao (F) wrote:
> On 2024/2/23 0:04, Arnd Bergmann wrote:
>> On Thu, Feb 22, 2024, at 12:24, liuyuntao (F) wrote:
>>>
>>> The position of the caret has been moved below the right brace
>>> of { KEEP(*(.vectors.bhb.loop8)) }, indicating that lld is treating
>>> the entire `KEEP(*(.vectors))` as a file name. This could potentially be
>>> a bug in lld. Perhaps we can temporarily
>>> enable the DCE option only when option LD_IS_LLD is disabled,
>>> like risc-v:
>>>
>>> `select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if !LD_IS_LLD`.
>> 
>> I would really like to see this working with lld if at all
>> possible, as it allows the combination of gc-sections with
>> lto and CONFIG_TRIM_UNUSED_KSYMS.
>> 
>> I experimented with lld myself now and I did get a booting
>> kernel even without the the KEEP() on the vectors. I also
>
> When the kernel booted up successfully, was config DCE enabled?

My mistake. I did have DCE enabled in the kernel I built,
but ended up passing an older image to it in the end,
and that did not boot.

     Arnd


From liuyongqiang13 at huawei.com  Thu Feb 22 22:36:08 2024
From: liuyongqiang13 at huawei.com (Yongqiang Liu)
Date: Fri, 23 Feb 2024 14:36:08 +0800
Subject: [PATCH v2] arm: flush: check if the folio is reserved for no-mapping addresses
Message-ID: <20240223063608.2605736-1-liuyongqiang13@huawei.com>

Since commit a4d5613c4dc6 ("arm: extend pfn_valid to take into account
freed memory map alignment") changes the semantics of pfn_valid() to check
presence of the memory map for a PFN. A valid page for an address which
is reserved but not mapped by the kernel[1], the system crashed during
some uio test with the following memory layout:

 node   0: [mem 0x00000000c0a00000-0x00000000cc8fffff]
 node   0: [mem 0x00000000d0000000-0x00000000da1fffff]
 the uio layout is?0xc0900000, 0x100000

the crash backtrace like:

  Unable to handle kernel paging request at virtual address bff00000
  [...]
  CPU: 1 PID: 465 Comm: startapp.bin Tainted: G           O      5.10.0 #1
  Hardware name: Generic DT based system
  PC is at b15_flush_kern_dcache_area+0x24/0x3c
  LR is at __sync_icache_dcache+0x6c/0x98
  [...]
   (b15_flush_kern_dcache_area) from (__sync_icache_dcache+0x6c/0x98)
   (__sync_icache_dcache) from (set_pte_at+0x28/0x54)
   (set_pte_at) from (remap_pfn_range+0x1a0/0x274)
   (remap_pfn_range) from (uio_mmap+0x184/0x1b8 [uio])
   (uio_mmap [uio]) from (__mmap_region+0x264/0x5f4)
   (__mmap_region) from (__do_mmap_mm+0x3ec/0x440)
   (__do_mmap_mm) from (do_mmap+0x50/0x58)
   (do_mmap) from (vm_mmap_pgoff+0xfc/0x188)
   (vm_mmap_pgoff) from (ksys_mmap_pgoff+0xac/0xc4)
   (ksys_mmap_pgoff) from (ret_fast_syscall+0x0/0x5c)
  Code: e0801001 e2423001 e1c00003 f57ff04f (ee070f3e)
  ---[ end trace 09cf0734c3805d52 ]---
  Kernel panic - not syncing: Fatal exception

So check if PG_reserved was set to solve this issue.

[1]: https://lore.kernel.org/lkml/Zbtdue57RO0QScJM at linux.ibm.com/

Fixes: a4d5613c4dc6 ("arm: extend pfn_valid to take into account freed memory map alignment")
Suggested-by: Mike Rapoport <rppt at linux.ibm.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13 at huawei.com>
---
v1 -> v2
 - Improve commit message
 - Use helpers instead of PG_reserved
 - drop the unnecessary include headers

 arch/arm/mm/flush.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index d19d140a10c7..0749cf8a6637 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -296,6 +296,9 @@ void __sync_icache_dcache(pte_t pteval)
 		return;
 
 	folio = page_folio(pfn_to_page(pfn));
+	if (folio_test_reserved(folio))
+		return;
+
 	if (cache_is_vipt_aliasing())
 		mapping = folio_flush_mapping(folio);
 	else
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Feb 22 22:36:54 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 23 Feb 2024 12:06:54 +0530
Subject: [PATCH V16 1/8] arm64/sysreg: Add BRBE registers and fields
In-Reply-To: <ZdYAJvZf4Ut5f5Rf@FVFF77S0Q05N>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-2-anshuman.khandual@arm.com>
 <ZdYAJvZf4Ut5f5Rf@FVFF77S0Q05N>
Message-ID: <008e381b-52cd-44c5-8a18-ece90db8bba8@arm.com>

On 2/21/24 19:22, Mark Rutland wrote:
> On Thu, Jan 25, 2024 at 03:11:12PM +0530, Anshuman Khandual 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: 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>
>> ---
>> Changes in V16:
>>
>> - Updated BRBINFx_EL1.TYPE = 0b110000 as field IMPDEF_TRAP_EL3
>> - Updated BRBCR_ELx[9] as field FZPSS
>> - Updated BRBINFINJ_EL1 to use sysreg field BRBINFx_EL1
>>
>>  arch/arm64/include/asm/sysreg.h | 109 ++++++++++++++++++++++++++
>>  arch/arm64/tools/sysreg         | 131 ++++++++++++++++++++++++++++++++
>>  2 files changed, 240 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
>> index c3b19b376c86..72544b5c4951 100644
>> --- a/arch/arm64/include/asm/sysreg.h
>> +++ b/arch/arm64/include/asm/sysreg.h
>> @@ -272,6 +272,109 @@
>>  
>>  #define SYS_BRBCR_EL2			sys_reg(2, 4, 9, 0, 0)
>>  
>> +#define __SYS_BRBINF(n)			sys_reg(2, 1, 8, ((n) & 0xf), ((((n) & 0x10) >> 2) + 0))
>> +#define __SYS_BRBSRC(n)			sys_reg(2, 1, 8, ((n) & 0xf), ((((n) & 0x10) >> 2) + 1))
>> +#define __SYS_BRBTGT(n)			sys_reg(2, 1, 8, ((n) & 0xf), ((((n) & 0x10) >> 2) + 2))
> 
> We already have definitions for these since v6.5, added in commit:
> 
>   57596c8f991c9aac ("arm64: Add debug registers affected by HDFGxTR_EL2:)
> 
> That commit also added register encoding definitions:
> 
> | #define SYS_BRBINF_EL1(n)              sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 0))
> | #define SYS_BRBINFINJ_EL1              sys_reg(2, 1, 9, 1, 0)
> | #define SYS_BRBSRC_EL1(n)              sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 1))
> | #define SYS_BRBSRCINJ_EL1              sys_reg(2, 1, 9, 1, 1)
> | #define SYS_BRBTGT_EL1(n)              sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 2))
> | #define SYS_BRBTGTINJ_EL1              sys_reg(2, 1, 9, 1, 2)
> | #define SYS_BRBTS_EL1                  sys_reg(2, 1, 9, 0, 2)
> 
> I don't think we need to add new encoding definitions for BRBINF<n>_EL1,
> BRBSRC<n>_EL1, or BRBTGT<n>_EL1; we can just use those existing defintions
> directly. That also means we don't need to add all of the expanded 0..31
> definitions; the driver can use SYS_BRBINF_EL1(n) and friends directly.

Right, that seems feasible. Hence with the following change to the BRBE driver
and arm64 KVM, we can convert using existing SYS_BRBXXX_EL1(n) format.

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 6a06dc2f0c06..739d861b9ef3 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1304,10 +1304,10 @@ static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
        return 0;
 }
 
-#define BRB_INF_SRC_TGT_EL1(n)                                 \
-       { SYS_DESC(SYS_BRBINF##n##_EL1), undef_access },        \
-       { SYS_DESC(SYS_BRBSRC##n##_EL1), undef_access },        \
-       { SYS_DESC(SYS_BRBTGT##n##_EL1), undef_access }         \
+#define BRB_INF_SRC_TGT_EL1(n)                         \
+       { SYS_DESC(SYS_BRBINF_EL1(n)), undef_access },  \
+       { SYS_DESC(SYS_BRBSRC_EL1(n)), undef_access },  \
+       { SYS_DESC(SYS_BRBTGT_EL1(n)), undef_access }   \
 
 /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
 #define DBG_BCR_BVR_WCR_WVR_EL1(n)                                     \
diff --git a/drivers/perf/arm_brbe.c b/drivers/perf/arm_brbe.c
index 22924023e0f1..dfaf098432ff 100644
--- a/drivers/perf/arm_brbe.c
+++ b/drivers/perf/arm_brbe.c
@@ -104,13 +104,13 @@ enum brbe_bank_idx {
 };
 
 #define RETURN_READ_BRBSRCN(n) \
-       read_sysreg_s(SYS_BRBSRC##n##_EL1)
+       read_sysreg_s(SYS_BRBSRC_EL1(n))
 
 #define RETURN_READ_BRBTGTN(n) \
-       read_sysreg_s(SYS_BRBTGT##n##_EL1)
+       read_sysreg_s(SYS_BRBTGT_EL1(n))
 
 #define RETURN_READ_BRBINFN(n) \
-       read_sysreg_s(SYS_BRBINF##n##_EL1)
+       read_sysreg_s(SYS_BRBINF_EL1(n))
 
 #define BRBE_REGN_CASE(n, case_macro) \
        case n: return case_macro(n); break

But while here, will also drop previously added other BRBE registers
from (arch/arm64/include/asm/sysreg.h), as they are now being added
via (arch/arm64/tools/sysreg) instead which is the right place.

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 9a919a102cf1..481c7d186dfa 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -195,16 +195,8 @@
 #define SYS_DBGVCR32_EL2               sys_reg(2, 4, 0, 7, 0)
 
 #define SYS_BRBINF_EL1(n)              sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 0))
-#define SYS_BRBINFINJ_EL1              sys_reg(2, 1, 9, 1, 0)
 #define SYS_BRBSRC_EL1(n)              sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 1))
-#define SYS_BRBSRCINJ_EL1              sys_reg(2, 1, 9, 1, 1)
 #define SYS_BRBTGT_EL1(n)              sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 2))
-#define SYS_BRBTGTINJ_EL1              sys_reg(2, 1, 9, 1, 2)
-#define SYS_BRBTS_EL1                  sys_reg(2, 1, 9, 0, 2)
-
-#define SYS_BRBCR_EL1                  sys_reg(2, 1, 9, 0, 0)
-#define SYS_BRBFCR_EL1                 sys_reg(2, 1, 9, 0, 1)
-#define SYS_BRBIDR0_EL1                        sys_reg(2, 1, 9, 2, 0)
 
 #define SYS_TRCITECR_EL1               sys_reg(3, 0, 1, 2, 3)
 #define SYS_TRCACATR(m)                        sys_reg(2, 1, 2, ((m & 7) << 1), (2 | (m >> 3)))
@@ -270,8 +262,6 @@
 /* ETM */
 #define SYS_TRCOSLAR                   sys_reg(2, 1, 1, 0, 4)
 
-#define SYS_BRBCR_EL2                  sys_reg(2, 4, 9, 0, 0)
-
 #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)
@@ -601,7 +591,6 @@
 #define SYS_CNTHV_CVAL_EL2             sys_reg(3, 4, 14, 3, 2)
 
 /* VHE encodings for architectural EL0/1 system registers */
-#define SYS_BRBCR_EL12                 sys_reg(2, 5, 9, 0, 0)
 #define SYS_SCTLR_EL12                 sys_reg(3, 5, 1, 0, 0)
 #define SYS_CPACR_EL12                 sys_reg(3, 5, 1, 0, 2)
 #define SYS_SCTLR2_EL12                        sys_reg(3, 5, 1, 0, 3)


> 
> [...]
> 
>> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
>> index 4c9b67934367..caf851ba5dc0 100644
>> --- a/arch/arm64/tools/sysreg
>> +++ b/arch/arm64/tools/sysreg
>> @@ -1023,6 +1023,137 @@ UnsignedEnum	3:0	MTEPERM
>>  EndEnum
>>  EndSysreg
>>  
>> +
>> +SysregFields BRBINFx_EL1
>> +Res0	63:47
>> +Field	46	CCU
>> +Field	45:32	CC
>> +Res0	31:18
>> +Field	17	LASTFAILED
>> +Field	16	T
>> +Res0	15:14
>> +Enum	13:8		TYPE
>> +	0b000000	UNCOND_DIRECT
>> +	0b000001	INDIRECT
>> +	0b000010	DIRECT_LINK
>> +	0b000011	INDIRECT_LINK
>> +	0b000101	RET
>> +	0b000111	ERET
>> +	0b001000	COND_DIRECT
> 
> Minor nit, but for consistency with DIRECT_LINK, could we please use
> DIRECT_UNCOND and DIRECT_COND?

Sure, will change as above.

> 
>> +	0b100001	DEBUG_HALT
>> +	0b100010	CALL
>> +	0b100011	TRAP
>> +	0b100100	SERROR
>> +	0b100110	INSN_DEBUG
>> +	0b100111	DATA_DEBUG
>> +	0b101010	ALIGN_FAULT
>> +	0b101011	INSN_FAULT
>> +	0b101100	DATA_FAULT
>> +	0b101110	IRQ
>> +	0b101111	FIQ
>> +	0b110000	IMPDEF_TRAP_EL3
>> +	0b111001	DEBUG_EXIT
> 
> That IMPDEF_TRAP_EL3 encoding doesn't seem to exist in the latest ARM ARM (ARM
> DDI 0487J.a), and I see Mark Brown checked against the "Arm A-profile
> Architecture Registers" document (ARM DDI 0601 ID121123, AKA 2023-12).

That's correct.

> 
> Could you please mention that in the commihttps://developer.arm.com/documentation/ddi0601/2023-12/) ?
> That'll make it easier for anyone else to review this, and it'll be good it message, and link to that version
> of the document (n
> case anyone needs to figure out where this came from in future.
> 

Sure, will do that.

>> +EndEnum
>> +Enum	7:6	EL
>> +	0b00	EL0
>> +	0b01	EL1
>> +	0b10	EL2
>> +	0b11	EL3
>> +EndEnum
>> +Field	5	MPRED
>> +Res0	4:2
>> +Enum	1:0	VALID
>> +	0b00	NONE
>> +	0b01	TARGET
>> +	0b10	SOURCE
>> +	0b11	FULL
>> +EndEnum
>> +EndSysregFields
> 
> The other fields here all look good per the ARM ARM and sysreg document.
> 
>> +SysregFields	BRBCR_ELx
>> +Res0	63:24
>> +Field	23 	EXCEPTION
>> +Field	22 	ERTN
>> +Res0	21:10
>> +Field	9	FZPSS
>> +Field	8 	FZP
>> +Res0	7
>> +Enum	6:5	TS
>> +	0b01	VIRTUAL
>> +	0b10	GUEST_PHYSICAL
>> +	0b11	PHYSICAL
>> +EndEnum
>> +Field	4	MPRED
>> +Field	3	CC
>> +Res0	2
>> +Field	1	ExBRE
>> +Field	0	E0BRE
>> +EndSysregFields
> 
> This looks good per the ARM ARM and sysreg document.
> 
>> +Sysreg	BRBCR_EL2	2	4	9	0	0
>> +Fields	BRBCR_ELx
>> +EndSysreg
>> +
>> +Sysreg	BRBCR_EL1	2	1	9	0	0
>> +Fields	BRBCR_ELx
>> +EndSysreg
>> +
>> +Sysreg	BRBCR_EL12	2	5	9	0	0
>> +Fields	BRBCR_ELx
>> +EndSysreg
> 
> These all look good per the ARM ARM and sysreg document.
> 
> Minor nit, but could we please list thse in order:
> 
> 	BRBCR_EL1
> 	BRBCR_EL12
> 	BRBCR_EL2
> 
> ... since that way the names are ordered alphnumerically, which is what we've
> done for other groups (e.g. PIR_EL{1,12,2}), and it's the way the ARM ARM
> happens to be ordered.
> 
>> +Sysreg	BRBFCR_EL1	2	1	9	0	1
>> +Res0	63:30
>> +Enum	29:28	BANK
>> +	0b0	FIRST
>> +	0b1	SECOND
> 
> Nit: since this is a 2-bit field, please pad these as '0b00' and '0b01'.
> 
> Could we please use BANK_0 and BANK_1 rather than FIRST and SECOND?
> 
> That'd also be easier to use behind macros.

Sure, will change as above.

> 
>> +EndEnum
>> +Res0	27:23
>> +Field	22	CONDDIR
>> +Field	21	DIRCALL
>> +Field	20	INDCALL
>> +Field	19	RTN
>> +Field	18	INDIRECT
>> +Field	17	DIRECT
>> +Field	16	EnI
>> +Res0	15:8
>> +Field	7	PAUSED
>> +Field	6	LASTFAILED
>> +Res0	5:0
>> +EndSysreg
> 
> Other than the nit, this looks good per the ARM ARM and sysreg document.

Okay

> 
> [...]
> 
>> +Sysreg	BRBIDR0_EL1	2	1	9	2	0
>> +Res0	63:16
>> +Enum	15:12	CC
>> +	0b101	20_BIT
>> +EndEnum
>> +Enum	11:8	FORMAT
>> +	0b0	0
>> +EndEnum
>> +Enum	7:0		NUMREC
>> +	0b0001000	8
>> +	0b0010000	16
>> +	0b0100000	32
>> +	0b1000000	64
> 
> This is an 8-bit field; please pad these to 8 bits (they all need a leading
> '0').

Sure, will change as above.

> 
>> +EndEnum
>> +EndSysreg
> 
> Aside from the comments above, this looks good to me.
> 
> Mark.


From shawnguo2 at yeah.net  Thu Feb 22 22:39:13 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Fri, 23 Feb 2024 14:39:13 +0800
Subject: [PATCH 1/2] arm64: dts: imx8qm: add i2c4 and i2c4_lpcg node
In-Reply-To: <20240206225904.3565362-1-Frank.Li@nxp.com>
References: <20240206225904.3565362-1-Frank.Li@nxp.com>
Message-ID: <Zdg9kT35cKT+sVra@dragon>

On Tue, Feb 06, 2024 at 05:59:03PM -0500, Frank Li wrote:
> Add i2c4 and i2c4_lpcg node for imx8qm.
> 
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied both, thanks!



From swboyd at chromium.org  Thu Feb 22 22:40:29 2024
From: swboyd at chromium.org (Stephen Boyd)
Date: Thu, 22 Feb 2024 22:40:29 -0800
Subject: [PATCH] arm64: ftrace: Don't forbid CALL_OPS+CC_OPTIMIZE_FOR_SIZE with Clang
Message-ID: <20240223064032.3463229-1-swboyd@chromium.org>

Per commit b3f11af9b2ce ("arm64: ftrace: forbid CALL_OPS with
CC_OPTIMIZE_FOR_SIZE"), GCC is silently ignoring `-falign-functions=N`
when passed `-Os`, causing functions to be improperly aligned. This
doesn't seem to be a problem with Clang though, where enabling CALL_OPS
with CC_OPTIMIZE_FOR_SIZE doesn't spit out any warnings at boot about
misaligned patch-sites. Only forbid CALL_OPS if GCC is used and we're
optimizing for size so that CALL_OPS can be used with clang optimizing
for size.

Cc: Jason Ling <jasonling at chromium.org>
Cc: Florian Fainelli <f.fainelli at gmail.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Nathan Chancellor <nathan at kernel.org>
Cc: Nick Desaulniers <ndesaulniers at google.com>
Cc: Bill Wendling <morbo at google.com>
Cc: Justin Stitt <justinstitt at google.com>
Cc: <llvm at lists.linux.dev>
Fixes: b3f11af9b2ce ("arm64: ftrace: forbid CALL_OPS with CC_OPTIMIZE_FOR_SIZE")
Signed-off-by: Stephen Boyd <swboyd at chromium.org>
---
 arch/arm64/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aa7c1d435139..6b96d75a3a3d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -198,7 +198,7 @@ config ARM64
 		if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS
 	select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \
 		if (DYNAMIC_FTRACE_WITH_ARGS && !CFI_CLANG && \
-		    !CC_OPTIMIZE_FOR_SIZE)
+		    (CC_IS_CLANG || !CC_OPTIMIZE_FOR_SIZE))
 	select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \
 		if DYNAMIC_FTRACE_WITH_ARGS
 	select HAVE_SAMPLE_FTRACE_DIRECT

base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
-- 
https://chromeos.dev



From shawnguo2 at yeah.net  Thu Feb 22 22:50:26 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Fri, 23 Feb 2024 14:50:26 +0800
Subject: [PATCH 1/1] arm64: dts: ls1088a: Add the PME interrupt for PCIe
 EP node
In-Reply-To: <20240206230525.3578868-1-Frank.Li@nxp.com>
References: <20240206230525.3578868-1-Frank.Li@nxp.com>
Message-ID: <ZdhAMmOILyw3pUz3@dragon>

On Tue, Feb 06, 2024 at 06:05:25PM -0500, Frank Li wrote:
> From: Xiaowei Bao <xiaowei.bao at nxp.com>
> 
> Add the PME interrupt porperty in PCIe EP node.
> 
> Signed-off-by: Xiaowei Bao <xiaowei.bao at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied, thanks!



From shawnguo2 at yeah.net  Thu Feb 22 22:51:55 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Fri, 23 Feb 2024 14:51:55 +0800
Subject: [PATCH 1/1] arm64: dts: lx2160a: Fix DTS for full PL011 UART
In-Reply-To: <20240206231521.3600089-1-Frank.Li@nxp.com>
References: <20240206231521.3600089-1-Frank.Li@nxp.com>
Message-ID: <ZdhAiy3m/ytfEc1j@dragon>

On Tue, Feb 06, 2024 at 06:15:21PM -0500, Frank Li wrote:
> From: Heinz Wrobel <Heinz.Wrobel at nxp.com>
> 
> The prior configuration was an SBSA UART that can't be configured or
> modified, or even enabled if it isn't the boot console. With properly
> defined clocks, the PL011 configuration can be used.
> 
> Signed-off-by: Heinz Wrobel <Heinz.Wrobel at nxp.com>
> Signed-off-by: Li Yang <leoyang.li at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied, thanks!



From michael.riesch at wolfvision.net  Thu Feb 22 22:53:58 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Fri, 23 Feb 2024 07:53:58 +0100
Subject: [PATCH 02/14] media: dt-bindings: media: rockchip-cif: add port
 definitions
In-Reply-To: <20240223002834.GA3933946-robh@kernel.org>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
 <20240220-v6-8-topic-rk3568-vicap-v1-2-2680a1fa640b@wolfvision.net>
 <20240223002834.GA3933946-robh@kernel.org>
Message-ID: <7ee26662-caab-462b-a5f1-3267e55a6313@wolfvision.net>

Hi Rob,

On 2/23/24 01:28, Rob Herring wrote:
> On Tue, Feb 20, 2024 at 10:39:12AM +0100, Michael Riesch wrote:
>> The different variants of the Rockchip Camera Interface may feature
>> various ports. Add a new header file with port definitions to avoid
>> hardcoded constants in device tree sources.
> 
> We generally don't do defines for 'port' numbering. I don't see a reason 
> to start.

OK. I'll drop patches 2 and 8, then.

Best regards,
Michael

>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
>> ---
>>  include/dt-bindings/media/rockchip-cif.h | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/include/dt-bindings/media/rockchip-cif.h b/include/dt-bindings/media/rockchip-cif.h
>> new file mode 100644
>> index 000000000000..37364ee1f7bc
>> --- /dev/null
>> +++ b/include/dt-bindings/media/rockchip-cif.h
>> @@ -0,0 +1,12 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>> +/*
>> + * Copyright (C) 2023 Michael Riesch <michael.riesch at wolfvision.net>
>> + */
>> +
>> +#ifndef __DT_BINDINGS_MEDIA_ROCKCHIP_CIF_H__
>> +#define __DT_BINDINGS_MEDIA_ROCKCHIP_CIF_H__
>> +
>> +#define MEDIA_ROCKCHIP_CIF_DVP		0
>> +#define MEDIA_ROCKCHIP_CIF_MIPI		1
>> +
>> +#endif /* __DT_BINDINGS_MEDIA_ROCKCHIP_CIF_H__ */
>>
>> -- 
>> 2.30.2
>>


From weifeng.voon at intel.com  Thu Feb 22 22:58:55 2024
From: weifeng.voon at intel.com (Voon, Weifeng)
Date: Fri, 23 Feb 2024 06:58:55 +0000
Subject: [PATCH net-next v5 1/9] net: phylink: provide
 mac_get_pcs_neg_mode() function
In-Reply-To: <Zc47T/qv8Xg2SA21@shell.armlinux.org.uk>
References: <20240215030500.3067426-1-yong.liang.choong@linux.intel.com>
 <20240215030500.3067426-2-yong.liang.choong@linux.intel.com>
 <Zc47T/qv8Xg2SA21@shell.armlinux.org.uk>
Message-ID: <PH7PR11MB65210C62342088CF5C484A2888552@PH7PR11MB6521.namprd11.prod.outlook.com>

> > For instance, if the interface switches from 2500baseX to SGMII mode,
> > and the current link mode is MLO_AN_PHY, calling
> 'phylink_pcs_neg_mode'
> > would yield PHYLINK_PCS_NEG_OUTBAND. Since the MAC and PCS driver
> > require PHYLINK_PCS_NEG_INBAND_ENABLED, the
> 'mac_get_pcs_neg_mode'
> > function will calculate the mode based on the interface, current link
> > negotiation mode, and advertising link mode, returning
> > PHYLINK_PCS_NEG_OUTBAND to enable the PCS to configure the correct
> settings.
> 
> This paragraph doesn't make sense - at least to me. It first talks about
> requiring PHYLINK_PCS_NEG_INBAND_ENABLED when in SGMII mode. On
> this:

The example given here is a very specific condition and that probably why there are some confusions here. Basically, this patch provides an optional function for MAC driver to change the phy interface on-the-fly without the need of reinitialize the Ethernet driver. As we know that the 2500base-x is messy, in our case the 2500base-x does not support inband. To complete the picture, we are using SGMII c37 to handle speed 10/100/1000. Hence, to enable user to switch link speed from 2500 to 1000/100/10 and vice versa on-the-fly, the phy interface need to be configured to inband SGMII for speed 10/100/1000, and outband 2500base-x for speed 2500. Lastly, the newly introduced "mac_get_pcs_neg_mode"callback function enables MAC driver to reconfigure pcs negotiation mode to inband or outband based on the interface mode, current link negotiation mode, and advertising link mode.

> 
> 1) are you sure that the hardware can't be programmed for the SGMII
> symbol repititions?
> 

No, the HW can be program for SGMII symbol repetitions.

> 2) what happens if you're paired with a PHY (e.g. on a SFP module) which
> uses SGMII but has no capability of providing the inband data?
> (They do exist.) If your hardware truly does require inband data, it is going to
> be fundamentally inoperative with these modules.
> 

Above explanation should have already cleared your doubts. Inband or outband capability is configured based on the phy interface.

> Next, you then talk about returning PHYLINK_PCS_NEG_OUTBAND for the
> "correct settings". How does this relate to the first part where you basically
> describe the problem as SGMII requring inband? Basically the two don't
> follow.

It should be a typo mistake. SGMII should return PHYLINK_PCS_NEG_INBAND_ENABLED.

> 
> How, from a design point of view, because this fundamentally allows drivers
> to change how the system behaves, it will allow radically different behaviours
> for the same parameters between different drivers.
> I am opposed to that - I want to see a situation where we have uniform
> behaviour for the same configuration, and where hardware doesn't support
> something, we have some way to indicate that via some form of capabilities.
> 

Hi Russell,
If I understand you correctly, MAC driver should not interfere with pcs negotiation mode and it should be standardized in the generic function, e.g., phylink_pcs_neg_mode()?

> The issue of whether 2500base-X has inband or not is a long standing issue,
> and there are arguments (and hardware) that take totally opposing views on
> this. There is hardware where 2500base-X inband _must_ be used or the link
> doesn't come up. There is also hardware where 2500base-X inband is not
> "supported" in documentation but works in practice. There is also hardware
> where 2500base-X inband doesn't work. The whole thing is a total mess
> (thanks IEEE 802.3 for not getting on top of this early enough... and what's
> now stated in 802.3 for 2500base-X is now irrelevant because they were too
> late to the
> party.)
> 

Agreed. And I have also seen some of your comments regarding the 2500SGMII and 2500BASEX.



From michael.riesch at wolfvision.net  Thu Feb 22 23:03:20 2024
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Fri, 23 Feb 2024 08:03:20 +0100
Subject: [PATCH 04/14] media: dt-bindings: media: rockchip,px30-vip: allow
 for different variants
In-Reply-To: <20240220-catchy-cupcake-e600e5af7650@spud>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
 <20240220-v6-8-topic-rk3568-vicap-v1-4-2680a1fa640b@wolfvision.net>
 <20240220-catchy-cupcake-e600e5af7650@spud>
Message-ID: <5bb0b0a9-3d4c-4303-aa43-38789bee286d@wolfvision.net>

Hi Conor,

On 2/20/24 19:58, Conor Dooley wrote:
> Hey,
> 
> On Tue, Feb 20, 2024 at 10:39:14AM +0100, Michael Riesch wrote:
>> Move the documentation of clocks and resets to a allOf: structure in order
>> to allow for different variants of the IP block.
>>
>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
>> ---
>>  .../bindings/media/rockchip,px30-vip.yaml          | 58 ++++++++++++++--------
>>  1 file changed, 37 insertions(+), 21 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
>> index 675a1ea47210..7168f166798c 100644
>> --- a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
>> +++ b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
>> @@ -24,32 +24,16 @@ properties:
>>    interrupts:
>>      maxItems: 1
>>  
>> -  clocks:
>> -    items:
>> -      - description: ACLK
>> -      - description: HCLK
>> -      - description: PCLK
>> -
>> -  clock-names:
>> -    items:
>> -      - const: aclk
>> -      - const: hclk
>> -      - const: pclk
>> +  clocks: true
>> +
>> +  clock-names: true
> 
> This is, unfortunately, not how we like multiple soc support to be
> handled. Instead, the widest constraints are added at the top level
> and constrained by the allOf. If none of the names etc are shared, at
> least the widest constraints for minItems and maxItems should be able to
> be here.

Just to make sure I got it right:

clocks:
  minItems: 3
  maxItems: 4
  items:
    - const: aclk
    - const: hclk

...

allOf:
...
  - if:
      properties:
        compatible:
          contains:
            const: rockchip,rk3568-vicap
    then:
      properties:
        clocks:
          - const: aclk
          - const: hclk
          - const: dclk
          - const: iclk

Is this the desired way?

> That said, this patch should be squashed with the patch that actually
> adds the other device to the binding.

That can be arranged.

Best regards,
Michael

> 
> Cheers,
> Conor.
> 
>>  
>>    iommus:
>>      maxItems: 1
>>  
>> -  resets:
>> -    items:
>> -      - description: AXI
>> -      - description: AHB
>> -      - description: PCLK IN
>> +  resets: true
>>  
>> -  reset-names:
>> -    items:
>> -      - const: axi
>> -      - const: ahb
>> -      - const: pclkin
>> +  reset-names: true
>>  
>>    power-domains:
>>      maxItems: 1
>> @@ -85,6 +69,38 @@ required:
>>    - clocks
>>    - ports
>>  
>> +allOf:
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: rockchip,px30-vip
>> +    then:
>> +      properties:
>> +        clocks:
>> +          items:
>> +            - description: ACLK
>> +            - description: HCLK
>> +            - description: PCLK
>> +
>> +        clock-names:
>> +          items:
>> +            - const: aclk
>> +            - const: hclk
>> +            - const: pclk
>> +
>> +        resets:
>> +          items:
>> +            - description: AXI
>> +            - description: AHB
>> +            - description: PCLK IN
>> +
>> +        reset-names:
>> +          items:
>> +            - const: axi
>> +            - const: ahb
>> +            - const: pclkin
>> +
>>  additionalProperties: false
>>  
>>  examples:
>>
>> -- 
>> 2.30.2
>>


From peng.fan at oss.nxp.com  Thu Feb 22 23:15:57 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Fri, 23 Feb 2024 15:15:57 +0800
Subject: [PATCH] pinctrl: scmi: support i.MX OEM pin configuration type
Message-ID: <20240223071557.2681316-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX95 System Manager FW supports SCMI PINCTRL protocol, but uses
OEM Pin Configuration type, so extend the driver to support custom
params.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---

V1:
 Based on https://lore.kernel.org/all/20240223-pinctrl-scmi-v4-0-10eb5a379274 at nxp.com/
 This is an reimplementation for supporting i.MX95 OEM settings.
 With this patch, the dts will be like:

+#define IMX95_PAD_SD1_CLK__USDHC1_CLK(val)	\
+	sd1clk {				\
+		pins = "sd1clk";		\
+		imx,func-id = <0>;		\
+		imx,pin-conf = <val>;		\
+	}
  ....
+
+	pinctrl_usdhc1: usdhc1grp {
+		IMX95_PAD_SD1_CLK__USDHC1_CLK(0x158e);
+		IMX95_PAD_SD1_CMD__USDHC1_CMD(0x138e);
 ....
+	};

 drivers/pinctrl/pinctrl-scmi.c | 10 ++++++++++
 drivers/pinctrl/pinctrl-scmi.h | 15 +++++++++++++++
 2 files changed, 25 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-scmi.h

diff --git a/drivers/pinctrl/pinctrl-scmi.c b/drivers/pinctrl/pinctrl-scmi.c
index f2fef3fb85ae..e58f1aaf9963 100644
--- a/drivers/pinctrl/pinctrl-scmi.c
+++ b/drivers/pinctrl/pinctrl-scmi.c
@@ -19,6 +19,7 @@
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 
+#include "pinctrl-scmi.h"
 #include "pinctrl-utils.h"
 #include "core.h"
 #include "pinconf.h"
@@ -472,6 +473,13 @@ static const struct pinconf_ops pinctrl_scmi_pinconf_ops = {
 	.pin_config_config_dbg_show = pinconf_generic_dump_config,
 };
 
+static const struct pinconf_generic_params pinctrl_scmi_oem_dt_params[] = {
+	{"imx,func-id", IMX_SCMI_PIN_MUX, -1},
+	{"imx,daisy-id", IMX_SCMI_PIN_DAISY_ID, -1},
+	{"imx,daisy-conf", IMX_SCMI_PIN_DAISY_CFG, -1},
+	{"imx,pin-conf", IMX_SCMI_PIN_CONF, -1},
+};
+
 static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx,
 				 unsigned int *nr_pins,
 				 const struct pinctrl_pin_desc **pins)
@@ -548,6 +556,8 @@ static int scmi_pinctrl_probe(struct scmi_device *sdev)
 	pmx->pctl_desc.pctlops = &pinctrl_scmi_pinctrl_ops;
 	pmx->pctl_desc.pmxops = &pinctrl_scmi_pinmux_ops;
 	pmx->pctl_desc.confops = &pinctrl_scmi_pinconf_ops;
+	pmx->pctl_desc.custom_params = pinctrl_scmi_oem_dt_params;
+	pmx->pctl_desc.num_custom_params = ARRAY_SIZE(pinctrl_scmi_oem_dt_params);
 
 	ret = pinctrl_scmi_get_pins(pmx, &pmx->pctl_desc.npins,
 				    &pmx->pctl_desc.pins);
diff --git a/drivers/pinctrl/pinctrl-scmi.h b/drivers/pinctrl/pinctrl-scmi.h
new file mode 100644
index 000000000000..fcc61bc19c98
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-scmi.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DRIVERS_PINCTRL_SCMI_H
+#define __DRIVERS_PINCTRL_SCMI_H
+
+/* OEM VENDOR Pin Configuration Type */
+#define IMX_SCMI_PIN_MUX	192
+#define IMX_SCMI_PIN_CONF	193
+#define IMX_SCMI_PIN_DAISY_ID	194
+#define IMX_SCMI_PIN_DAISY_CFG	195
+
+#endif /* __DRIVERS_PINCTRL_SCMI_H */
-- 
2.37.1



From hch at infradead.org  Thu Feb 22 23:09:40 2024
From: hch at infradead.org (Christoph Hellwig)
Date: Thu, 22 Feb 2024 23:09:40 -0800
Subject: [PATCH v17 19/35] arch/mm: Export direct {un,}map functions
In-Reply-To: <20240222-gunyah-v17-19-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
 <20240222-gunyah-v17-19-1e9da6763d38@quicinc.com>
Message-ID: <ZdhEtH7xzbzdhS2j@infradead.org>

On Thu, Feb 22, 2024 at 03:16:42PM -0800, Elliot Berman wrote:
> Firmware and hypervisor drivers can donate system heap memory to their
> respective firmware/hypervisor entities. Those drivers should unmap the
> pages from the kernel's logical map before doing so.
> 
> Export can_set_direct_map, set_direct_map_invalid_noflush, and
> set_direct_map_default_noflush.

Err, not they should not.  And not using such super low-level interfaces
from modular code.


From anshuman.khandual at arm.com  Thu Feb 22 23:28:48 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 23 Feb 2024 12:58:48 +0530
Subject: [PATCH V16 2/8] KVM: arm64: Prevent guest accesses into BRBE
 system registers/instructions
In-Reply-To: <ZdYCUi9YVDNDz7fr@FVFF77S0Q05N>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-3-anshuman.khandual@arm.com>
 <ZdYCUi9YVDNDz7fr@FVFF77S0Q05N>
Message-ID: <ab50e67e-3d06-4ba7-a5f8-4684e9ef98a4@arm.com>



On 2/21/24 19:31, Mark Rutland wrote:
> On Thu, Jan 25, 2024 at 03:11:13PM +0530, Anshuman Khandual wrote:
>> Currently BRBE feature is not supported in a guest environment. This hides
>> BRBE feature availability via masking ID_AA64DFR0_EL1.BRBE field.
> 
> Does that means that a guest can currently see BRBE advertised in the
> ID_AA64DFR0_EL1.BRB field, or is that hidden by the regular cpufeature code
> today?

IIRC it is hidden, but will have to double check. When experimenting for BRBE
guest support enablement earlier, following changes were need for the feature
to be visible in ID_AA64DFR0_EL1.

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 646591c67e7a..f258568535a8 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -445,6 +445,7 @@ static const struct arm64_ftr_bits ftr_id_mmfr0[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
+       S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_EL1_BRBE_SHIFT, 4, ID_AA64DFR0_EL1_BRBE_IMP),
        S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_EL1_DoubleLock_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR0_EL1_PMSVer_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_EL1_CTX_CMPs_SHIFT, 4, 0),

Should we add the following entry - explicitly hiding BRBE from the guest
as a prerequisite patch ?

S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_EL1_BRBE_SHIFT, 4, ID_AA64DFR0_EL1_BRBE_NI)

> 
>> This also blocks guest accesses into BRBE system registers and instructions
>> as if the underlying hardware never implemented FEAT_BRBE feature.
>>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: Oliver Upton <oliver.upton at linux.dev>
>> Cc: James Morse <james.morse at arm.com>
>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: kvmarm at lists.linux.dev
>> 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>
>> ---
>> Changes in V16:
>>
>> - Added BRB_INF_SRC_TGT_EL1 macro for corresponding BRB_[INF|SRC|TGT] expansion
>>
>>  arch/arm64/kvm/sys_regs.c | 56 +++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 56 insertions(+)
>>
>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>> index 30253bd19917..6a06dc2f0c06 100644
>> --- a/arch/arm64/kvm/sys_regs.c
>> +++ b/arch/arm64/kvm/sys_regs.c
>> @@ -1304,6 +1304,11 @@ static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
>>  	return 0;
>>  }
>>  
>> +#define BRB_INF_SRC_TGT_EL1(n)					\
>> +	{ SYS_DESC(SYS_BRBINF##n##_EL1), undef_access },	\
>> +	{ SYS_DESC(SYS_BRBSRC##n##_EL1), undef_access },	\
>> +	{ SYS_DESC(SYS_BRBTGT##n##_EL1), undef_access }		\
> 
> With the changes suggested on the previous patch, this would need to change to be:
> 
> 	#define BRB_INF_SRC_TGT_EL1(n)					\
> 		{ SYS_DESC(SYS_BRBINF_EL1(n)), undef_access },	\
> 		{ SYS_DESC(SYS_BRBSRC_EL1(n)), undef_access },	\
> 		{ SYS_DESC(SYS_BRBTGT_EL1(n)), undef_access }	\

Sure, already folded back in these above changes.

> 
> 
> ... which would also be easier for backporting (if necessary), since those
> definitions have existed for a while.
> 
> Otherwise (modulo Suzuki's comment about rebasing), this looks good to me.

Okay.

> 
> Mark.
> 
>>  /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
>>  #define DBG_BCR_BVR_WCR_WVR_EL1(n)					\
>>  	{ SYS_DESC(SYS_DBGBVRn_EL1(n)),					\
>> @@ -1707,6 +1712,9 @@ static u64 read_sanitised_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
>>  	/* Hide SPE from guests */
>>  	val &= ~ID_AA64DFR0_EL1_PMSVer_MASK;
>>  
>> +	/* Hide BRBE from guests */
>> +	val &= ~ID_AA64DFR0_EL1_BRBE_MASK;
>> +
>>  	return val;
>>  }
>>  
>> @@ -2195,6 +2203,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>>  	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
>>  	{ SYS_DESC(SYS_DC_CIGSW), access_dcgsw },
>>  	{ SYS_DESC(SYS_DC_CIGDSW), access_dcgsw },
>> +	{ SYS_DESC(OP_BRB_IALL), undef_access },
>> +	{ SYS_DESC(OP_BRB_INJ), undef_access },
>>  
>>  	DBG_BCR_BVR_WCR_WVR_EL1(0),
>>  	DBG_BCR_BVR_WCR_WVR_EL1(1),
>> @@ -2225,6 +2235,52 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>>  	{ SYS_DESC(SYS_DBGCLAIMCLR_EL1), trap_raz_wi },
>>  	{ SYS_DESC(SYS_DBGAUTHSTATUS_EL1), trap_dbgauthstatus_el1 },
>>  
>> +	/*
>> +	 * BRBE branch record sysreg address space is interleaved between
>> +	 * corresponding BRBINF<N>_EL1, BRBSRC<N>_EL1, and BRBTGT<N>_EL1.
>> +	 */
>> +	BRB_INF_SRC_TGT_EL1(0),
>> +	BRB_INF_SRC_TGT_EL1(16),
>> +	BRB_INF_SRC_TGT_EL1(1),
>> +	BRB_INF_SRC_TGT_EL1(17),
>> +	BRB_INF_SRC_TGT_EL1(2),
>> +	BRB_INF_SRC_TGT_EL1(18),
>> +	BRB_INF_SRC_TGT_EL1(3),
>> +	BRB_INF_SRC_TGT_EL1(19),
>> +	BRB_INF_SRC_TGT_EL1(4),
>> +	BRB_INF_SRC_TGT_EL1(20),
>> +	BRB_INF_SRC_TGT_EL1(5),
>> +	BRB_INF_SRC_TGT_EL1(21),
>> +	BRB_INF_SRC_TGT_EL1(6),
>> +	BRB_INF_SRC_TGT_EL1(22),
>> +	BRB_INF_SRC_TGT_EL1(7),
>> +	BRB_INF_SRC_TGT_EL1(23),
>> +	BRB_INF_SRC_TGT_EL1(8),
>> +	BRB_INF_SRC_TGT_EL1(24),
>> +	BRB_INF_SRC_TGT_EL1(9),
>> +	BRB_INF_SRC_TGT_EL1(25),
>> +	BRB_INF_SRC_TGT_EL1(10),
>> +	BRB_INF_SRC_TGT_EL1(26),
>> +	BRB_INF_SRC_TGT_EL1(11),
>> +	BRB_INF_SRC_TGT_EL1(27),
>> +	BRB_INF_SRC_TGT_EL1(12),
>> +	BRB_INF_SRC_TGT_EL1(28),
>> +	BRB_INF_SRC_TGT_EL1(13),
>> +	BRB_INF_SRC_TGT_EL1(29),
>> +	BRB_INF_SRC_TGT_EL1(14),
>> +	BRB_INF_SRC_TGT_EL1(30),
>> +	BRB_INF_SRC_TGT_EL1(15),
>> +	BRB_INF_SRC_TGT_EL1(31),
>> +
>> +	/* Remaining BRBE sysreg addresses space */
>> +	{ SYS_DESC(SYS_BRBCR_EL1), undef_access },
>> +	{ SYS_DESC(SYS_BRBFCR_EL1), undef_access },
>> +	{ SYS_DESC(SYS_BRBTS_EL1), undef_access },
>> +	{ SYS_DESC(SYS_BRBINFINJ_EL1), undef_access },
>> +	{ SYS_DESC(SYS_BRBSRCINJ_EL1), undef_access },
>> +	{ SYS_DESC(SYS_BRBTGTINJ_EL1), undef_access },
>> +	{ SYS_DESC(SYS_BRBIDR0_EL1), undef_access },
>> +
>>  	{ SYS_DESC(SYS_MDCCSR_EL0), trap_raz_wi },
>>  	{ SYS_DESC(SYS_DBGDTR_EL0), trap_raz_wi },
>>  	// DBGDTR[TR]X_EL0 share the same encoding
>> -- 
>> 2.25.1
>>


From vidyas at nvidia.com  Fri Feb 23 00:00:21 2024
From: vidyas at nvidia.com (Vidya Sagar)
Date: Fri, 23 Feb 2024 13:30:21 +0530
Subject: [PATCH V4] PCI: Add support for preserving boot configuration
In-Reply-To: <20240222124110.2681455-1-vidyas@nvidia.com>
References: <20240222124110.2681455-1-vidyas@nvidia.com>
Message-ID: <20240223080021.1692996-1-vidyas@nvidia.com>

Add support for preserving the boot configuration done by the
platform firmware per host bridge basis, based on the presence of
'linux,pci-probe-only' property in the respective PCI host bridge
device-tree node. It also unifies the ACPI and DT based boot flows
in this regard.

Signed-off-by: Vidya Sagar <vidyas at nvidia.com>
---
V4:
* Addressed Bjorn's review comments

V3:
* Unified ACPI and DT flows as part of addressing Bjorn's review comments

V2:
* Addressed issues reported by kernel test robot <lkp at intel.com>

 drivers/acpi/pci_root.c                  | 12 -------
 drivers/pci/controller/pci-host-common.c |  4 ---
 drivers/pci/of.c                         | 21 +++++++++++
 drivers/pci/probe.c                      | 46 ++++++++++++++++++------
 include/linux/of_pci.h                   |  6 ++++
 5 files changed, 62 insertions(+), 27 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 84030804a763..ddc2b3e89111 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -1008,7 +1008,6 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	int node = acpi_get_node(device->handle);
 	struct pci_bus *bus;
 	struct pci_host_bridge *host_bridge;
-	union acpi_object *obj;
 
 	info->root = root;
 	info->bridge = device;
@@ -1050,17 +1049,6 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	if (!(root->osc_ext_control_set & OSC_CXL_ERROR_REPORTING_CONTROL))
 		host_bridge->native_cxl_error = 0;
 
-	/*
-	 * Evaluate the "PCI Boot Configuration" _DSM Function.  If it
-	 * exists and returns 0, we must preserve any PCI resource
-	 * assignments made by firmware for this host bridge.
-	 */
-	obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 1,
-				DSM_PCI_PRESERVE_BOOT_CONFIG, NULL);
-	if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0)
-		host_bridge->preserve_config = 1;
-	ACPI_FREE(obj);
-
 	acpi_dev_power_up_children_with_adr(device);
 
 	pci_scan_child_bus(bus);
diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index 6be3266cd7b5..e2602e38ae45 100644
--- a/drivers/pci/controller/pci-host-common.c
+++ b/drivers/pci/controller/pci-host-common.c
@@ -73,10 +73,6 @@ int pci_host_common_probe(struct platform_device *pdev)
 	if (IS_ERR(cfg))
 		return PTR_ERR(cfg);
 
-	/* Do not reassign resources if probe only */
-	if (!pci_has_flag(PCI_PROBE_ONLY))
-		pci_add_flags(PCI_REASSIGN_ALL_BUS);
-
 	bridge->sysdata = cfg;
 	bridge->ops = (struct pci_ops *)&ops->pci_ops;
 	bridge->msi_domain = true;
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 51e3dd0ea5ab..f0f1156040a5 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -258,6 +258,27 @@ void of_pci_check_probe_only(void)
 }
 EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
 
+/**
+ * of_pci_bridge_preserve_resources - Return true if the boot configuration
+ *                                    needs to be preserved
+ * @node: Device tree node with the domain information.
+ *
+ * This function looks for "linux,pci-probe-only" property for a given
+ * PCI controller's node and returns true if found. Having this property
+ * for a PCI controller ensures that the kernel doesn't reconfigure the
+ * BARs and bridge windows that are already done by the platform firmware.
+ * NOTE: The scope of "linux,pci-probe-only" defined within a PCI bridge device
+ *       is limited to the hierarchy under that particular bridge device. whereas
+ *       the scope of "linux,pci-probe-only" defined within chosen node is
+ *       system wide.
+ *
+ * Return: true if the property exists false otherwise.
+ */
+bool of_pci_bridge_preserve_resources(struct device_node *node)
+{
+	return of_property_read_bool(node, "linux,pci-probe-only");
+}
+
 /**
  * devm_of_pci_get_host_bridge_resources() - Resource-managed parsing of PCI
  *                                           host bridge resources from DT
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 795534589b98..c57648084503 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -15,6 +15,7 @@
 #include <linux/cpumask.h>
 #include <linux/aer.h>
 #include <linux/acpi.h>
+#include <linux/pci-acpi.h>
 #include <linux/hypervisor.h>
 #include <linux/irqdomain.h>
 #include <linux/pm_runtime.h>
@@ -877,6 +878,28 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus)
 	dev_set_msi_domain(&bus->dev, d);
 }
 
+static void pci_check_config_preserve(struct pci_host_bridge *host_bridge)
+{
+	if (ACPI_HANDLE(&host_bridge->dev)) {
+		union acpi_object *obj;
+
+		/*
+		 * Evaluate the "PCI Boot Configuration" _DSM Function.  If it
+		 * exists and returns 0, we must preserve any PCI resource
+		 * assignments made by firmware for this host bridge.
+		 */
+		obj = acpi_evaluate_dsm(ACPI_HANDLE(&host_bridge->dev), &pci_acpi_dsm_guid, 1,
+					DSM_PCI_PRESERVE_BOOT_CONFIG, NULL);
+		if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0)
+			host_bridge->preserve_config = 1;
+		ACPI_FREE(obj);
+	}
+
+	if (host_bridge->dev.parent && host_bridge->dev.parent->of_node)
+		host_bridge->preserve_config =
+			of_pci_bridge_preserve_resources(host_bridge->dev.parent->of_node);
+}
+
 static int pci_register_host_bridge(struct pci_host_bridge *bridge)
 {
 	struct device *parent = bridge->dev.parent;
@@ -971,6 +994,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
 	if (nr_node_ids > 1 && pcibus_to_node(bus) == NUMA_NO_NODE)
 		dev_warn(&bus->dev, "Unknown NUMA node; performance will be reduced\n");
 
+	/* Check if the boot configuration by FW needs to be preserved */
+	pci_check_config_preserve(bridge);
+
 	/* Coalesce contiguous windows */
 	resource_list_for_each_entry_safe(window, n, &resources) {
 		if (list_is_last(&window->node, &resources))
@@ -3080,20 +3106,18 @@ int pci_host_probe(struct pci_host_bridge *bridge)
 
 	bus = bridge->bus;
 
+	/* If we must preserve the resource configuration, claim now */
+	if (pci_has_flag(PCI_PROBE_ONLY) || bridge->preserve_config)
+		pci_bus_claim_resources(bus);
+
 	/*
-	 * We insert PCI resources into the iomem_resource and
-	 * ioport_resource trees in either pci_bus_claim_resources()
-	 * or pci_bus_assign_resources().
+	 * Assign whatever was left unassigned. If we didn't claim above,
+	 * this will reassign everything.
 	 */
-	if (pci_has_flag(PCI_PROBE_ONLY)) {
-		pci_bus_claim_resources(bus);
-	} else {
-		pci_bus_size_bridges(bus);
-		pci_bus_assign_resources(bus);
+	pci_assign_unassigned_root_bus_resources(bus);
 
-		list_for_each_entry(child, &bus->children, node)
-			pcie_bus_configure_settings(child);
-	}
+	list_for_each_entry(child, &bus->children, node)
+		pcie_bus_configure_settings(child);
 
 	pci_bus_add_devices(bus);
 	return 0;
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 29658c0ee71f..3f3909a5d55d 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -13,6 +13,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
 					     unsigned int devfn);
 int of_pci_get_devfn(struct device_node *np);
 void of_pci_check_probe_only(void);
+bool of_pci_bridge_preserve_resources(struct device_node *node);
 #else
 static inline struct device_node *of_pci_find_child_device(struct device_node *parent,
 					     unsigned int devfn)
@@ -26,6 +27,11 @@ static inline int of_pci_get_devfn(struct device_node *np)
 }
 
 static inline void of_pci_check_probe_only(void) { }
+
+static inline bool of_pci_bridge_preserve_resources(struct device_node *node)
+{
+	return false;
+}
 #endif
 
 #if IS_ENABLED(CONFIG_OF_IRQ)
-- 
2.25.1



From shengjiu.wang at nxp.com  Fri Feb 23 00:02:18 2024
From: shengjiu.wang at nxp.com (Shengjiu Wang)
Date: Fri, 23 Feb 2024 16:02:18 +0800
Subject: [PATCH 1/2] arm64: dts: imx8mp-evk: Add HDMI audio sound card support
Message-ID: <1708675339-8180-1-git-send-email-shengjiu.wang@nxp.com>

The AUD2HTX is a digital module that provides a bridge between
the Audio Subsystem and the HDMI RTX Subsystem. This
module includes intermediate storage to queue SDMA transactions
prior to being synchronized and passed to the HDMI
RTX Subsystem over the Audio Link.

AUD2HTX works as the cpu dai in HDMI audio sound card.

Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 12 ++++++++++++
 arch/arm64/boot/dts/freescale/imx8mp.dtsi    | 10 ++++++++++
 2 files changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index f87fa5a948cc..63f6e72fa18a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -138,6 +138,14 @@ simple-audio-card,codec {
 
 	};
 
+	sound-hdmi {
+		compatible = "fsl,imx-audio-hdmi";
+		model = "audio-hdmi";
+		audio-cpu = <&aud2htx>;
+		hdmi-out;
+		status = "okay";
+	};
+
 	reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
@@ -191,6 +199,10 @@ &A53_3 {
 	cpu-supply = <&reg_arm>;
 };
 
+&aud2htx {
+	status = "okay";
+};
+
 &eqos {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_eqos>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 9ab9c057f41e..721ab630d895 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1513,6 +1513,16 @@ micfil: audio-controller at 30ca0000 {
 					status = "disabled";
 				};
 
+				aud2htx: aud2htx at 30cb0000 {
+					compatible = "fsl,imx8mp-aud2htx";
+					reg = <0x30cb0000 0x10000>;
+					interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG>;
+					clock-names = "bus";
+					dmas = <&sdma2 26 2 0>;
+					dma-names = "tx";
+					status = "disabled";
+				};
 			};
 
 			sdma3: dma-controller at 30e00000 {
-- 
2.34.1



From shengjiu.wang at nxp.com  Fri Feb 23 00:02:19 2024
From: shengjiu.wang at nxp.com (Shengjiu Wang)
Date: Fri, 23 Feb 2024 16:02:19 +0800
Subject: [PATCH 2/2] arm64: dts: imx8mp-evk:Add PDM micphone sound card support
In-Reply-To: <1708675339-8180-1-git-send-email-shengjiu.wang@nxp.com>
References: <1708675339-8180-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <1708675339-8180-2-git-send-email-shengjiu.wang@nxp.com>

Add PDM micphone sound card support, configure the pinmux.

This sound card supports recording sound from PDM micphone
and convert the PDM format data to PCM data.

Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 34 ++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index 63f6e72fa18a..fdcd1158a34a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -146,6 +146,20 @@ sound-hdmi {
 		status = "okay";
 	};
 
+	sound-micfil {
+		compatible = "fsl,imx-audio-card";
+		model = "micfil-audio";
+
+		pri-dai-link {
+			link-name = "micfil hifi";
+			format = "i2s";
+
+			cpu {
+				sound-dai = <&micfil>;
+			};
+		};
+	};
+
 	reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
@@ -527,6 +541,16 @@ &lcdif1 {
 	status = "okay";
 };
 
+&micfil {
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pdm>;
+	assigned-clocks = <&clk IMX8MP_CLK_PDM>;
+	assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+	assigned-clock-rates = <196608000>;
+	status = "okay";
+};
+
 &mipi_dsi {
 	samsung,esc-clock-frequency = <10000000>;
 	status = "okay";
@@ -793,6 +817,16 @@ MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06	0x40
 		>;
 	};
 
+	pinctrl_pdm: pdmgrp {
+		fsl,pins = <
+			MX8MP_IOMUXC_SAI5_RXC__AUDIOMIX_PDM_CLK		0xd6
+			MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_PDM_BIT_STREAM00	0xd6
+			MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_PDM_BIT_STREAM01	0xd6
+			MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_PDM_BIT_STREAM02	0xd6
+			MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_PDM_BIT_STREAM03	0xd6
+		>;
+	};
+
 	pinctrl_pmic: pmicgrp {
 		fsl,pins = <
 			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03	0x000001c0
-- 
2.34.1



From megi at xff.cz  Fri Feb 23 00:20:17 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Fri, 23 Feb 2024 09:20:17 +0100
Subject: [PATCH 3/3] drm/sun4i: Fix layer zpos change/atomic modesetting
In-Reply-To: <2448947.jE0xQCEvom@jernej-laptop>
References: <20240216190430.1374132-1-megi@xff.cz>
 <20240216190430.1374132-4-megi@xff.cz>
 <inuhwnlexpt6dpre4uailtvytjhms4uqeerzehbntczurhcxol@fc4nvkdwffdd>
 <2448947.jE0xQCEvom@jernej-laptop>
Message-ID: <iboaf4yyieqq6yeuu2amwjnwsao3vx7fzeqldhuplx5j6z2zxf@ex57tbxhzzk6>

On Thu, Feb 22, 2024 at 09:02:53PM +0100, Jernej ?krabec wrote:
> Dne sreda, 21. februar 2024 ob 14:45:20 CET je Maxime Ripard napisal(a):
> > Hi,
> > 
> > On Fri, Feb 16, 2024 at 08:04:26PM +0100, Ond?ej Jirman wrote:
> > > From: Ondrej Jirman <megi at xff.cz>
> > > 
> > > Identical configurations of planes can lead to different (and wrong)
> > > layer -> pipe routing at HW level, depending on the order of atomic
> > > plane changes.
> > > 
> > > For example:
> > > 
> > > - Layer 1 is configured to zpos 0 and thus uses pipe 0. No other layer
> > >   is enabled. This is a typical situation at boot.
> > > 
> > > - When a compositor takes over and layer 3 is enabled,
> > >   sun8i_ui_layer_enable() will get called with old_zpos=0 zpos=1, which
> > >   will lead to incorrect disabling of pipe 0 and enabling of pipe 1.
> > > 
> > > What happens is that sun8i_ui_layer_enable() function may disable
> > > blender pipes even if it is no longer assigned to its layer.
> > > 
> > > To correct this, move the routing setup out of individual plane's
> > > atomic_update into crtc's atomic_update, where it can be calculated
> > > and updated all at once.
> > > 
> > > Remove the atomic_disable callback because it is no longer needed.
> > > 
> > > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > 
> > I don't have enough knowledge about the mixers code to comment on your
> > patch, so I'll let Jernej review it. However, this feels to me like the
> > pipe assignment is typically the sort of things that should be dealt
> > with device-wide, and in atomic_check.
> 
> In DE2 and DE3.0, you cannot move planes between mixers (crtcs), because each
> one is hardwired to specific mixer. Movable planes are the feature of DE3.3
> and one of the pain points for upstreaming the code. Anyway, this commit only
> addresses current issue of enabling and disabling planes and handling zpos.
> 
> In atomic check you can only precalculate final register values, but I don't
> see any benefit doing that. I think that this code elegantly solves current
> issue of enabling or disabling wrong plane in certain situations, so:
> 
> Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Thanks for the review.

> Note, if there is new revision, please rewrite blender regmap_update_bits()
> to regmap_write(). Since there is HW issue with reads, I would like to
> get rid of regmap_update_bits() calls eventually.

BTW as a side note, one observation I made about a year back after some testing
with a setup like this:

- PIN photodiode in a black box directed at a display (Pinephone)
  attached to the oscilloscope
- GPIO signal routed to another input of the scope
- sun4i-drm driver modification that toggles the GPIO any number of times so
  that I can correlate brightness changes as seen by photodiode on the
  scope with the timing of what's happening in the driver

is that if you do atomic commit right after receiving the flip event there's
a high chance that what you're commiting will get displayed right away,
basically skipping the update from the previous atomic commit.

It's very easy to reproduce with a test application that flips between two
completely white and completely black framebuffers back and forth right
after flip event. What you see on the display is seemingly random blinking
pattern: https://megous.com/dl/tmp/c9a286427ce66d80.png when it should be
a peridic flipping between black and white pixels like this
https://megous.com/dl/tmp/c085a50ccd387257.png

This goes away for me when introducing a >150us delay between flip event
and next atomic commit.

I did a more complex test with a test app that switches between 4 framebuffers
of decreasing shades of gray, so that the resulting pattern of brightness should
be a stariwise stepping signal pattern on the scope, along with gpio indicating which
framebuffer just got commited (by the number of pulses 1-4). What I saw was
that normally there's a 1 frame delay between commit and the corresponding
brightness change, but often enough the brightness change is immediate.

I think the hardware indicates a flip (vsync irq) some time before it performs
the double buffered register update to shadow register for the next frame. So
sometimes the driver manages to overwrite the values stored during the previous
commit before they get flipped to shadow registers. Again, intorducing a 150us
delay between flip event and atomic commit reliably fixes this, and I see
a perfect stairwise pattern on the scope instead of occasional skipped ahead
steps.

It seems to me that those 150us are related to display timing.

Vertical blanking cycle on Pinephone lasts about 400us with 45us long vsync
pulse roughly in the middle. In my observation it seems likely that HW signals
VSYNC interrupt at the start or end of the VSYNC pulse and flips the double
buffered HW registers at the end of the blanking cycle, leaving some 150us of
time in between for a quick atomic commit to still mess up the register settings
for the upcoming scan out, before they get commited to shadow regs. I don't have
a way to observe vsync signal on a scope, because it's MIPI-DSI display to
verify this exactly.

The certain thing is that after vsync interrupt, the double buffered registers
are not switched, yet. There's still some time left before that happens.

Anyway, just something I'd thought I share that may help us understand this
HW better. :)

kind regards,
	o.

> Best regards,
> Jernej
> 
> > 
> > If I'm talking non-sense, it would be great to mention at least why that
> > can't be an option in the commit log.
> > 
> > Maxime
> > 
> 
> 
> 
> 


From linus.walleij at linaro.org  Fri Feb 23 00:28:12 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 23 Feb 2024 09:28:12 +0100
Subject: [PATCH v4 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <20240223-pinctrl-scmi-v4-3-10eb5a379274@nxp.com>
References: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com> <20240223-pinctrl-scmi-v4-3-10eb5a379274@nxp.com>
Message-ID: <CACRpkdZLuWwecacBAimT=Vj67dGabzBH-7aaqzoyj1B1sY6o_A@mail.gmail.com>

On Fri, Feb 23, 2024 at 2:08?AM Peng Fan (OSS) <peng.fan at oss.nxp.com> wrote:

> From: Oleksii Moisieiev <oleksii_moisieiev at epam.com>
>
> Add basic implementation of the SCMI v3.2 pincontrol protocol.
>
> Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>
> Tested-by: Cristian Marussi <cristian.marussi at arm.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev at epam.com>
> Co-developed-by: Peng Fan <peng.fan at nxp.com>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>

This looks ripe for merging for me, there are clearly dependencies in the SCMI
firmware tree so I can't apply this to the pin control tree, but if
someone creates
an immutable branch from the SCMI firmware repo (based off v6.8-rc1 or so)
I'm happy to also pull the branch into pin control.

Yours,
Linus Walleij


From angelogioacchino.delregno at collabora.com  Fri Feb 23 00:28:29 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 23 Feb 2024 09:28:29 +0100
Subject: [PATCH v3,2/2] media: mediatek: vcodec: adding lock to protect
 encoder context list
In-Reply-To: <20240222092609.31382-3-yunfei.dong@mediatek.com>
References: <20240222092609.31382-1-yunfei.dong@mediatek.com>
 <20240222092609.31382-3-yunfei.dong@mediatek.com>
Message-ID: <298d953d-6320-4dda-b31e-c9503dc91cdb@collabora.com>

Il 22/02/24 10:26, Yunfei Dong ha scritto:
> The ctx_list will be deleted when scp getting unexpected behavior, then the
> ctx_list->next will be NULL, the kernel driver maybe access NULL pointer in
> function vpu_enc_ipi_handler when going through each context, then reboot.
> 
> Need to add lock to protect the ctx_list to make sure the ctx_list->next isn't
> NULL pointer.
> 
> Fixes: 1972e32431ed ("media: mediatek: vcodec: Fix possible invalid memory access for encoder")
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Fri Feb 23 00:28:30 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 23 Feb 2024 09:28:30 +0100
Subject: [PATCH v3,1/2] media: mediatek: vcodec: adding lock to protect
 decoder context list
In-Reply-To: <20240222092609.31382-2-yunfei.dong@mediatek.com>
References: <20240222092609.31382-1-yunfei.dong@mediatek.com>
 <20240222092609.31382-2-yunfei.dong@mediatek.com>
Message-ID: <a7e30fbe-6a82-4c26-afef-e7b75c1c0102@collabora.com>

Il 22/02/24 10:26, Yunfei Dong ha scritto:
> The ctx_list will be deleted when scp getting unexpected behavior, then the
> ctx_list->next will be NULL, the kernel driver maybe access NULL pointer in
> function vpu_dec_ipi_handler when going through each context, then reboot.
> 
> Need to add lock to protect the ctx_list to make sure the ctx_list->next isn't
> NULL pointer.
> 
> Hardware name: Google juniper sku16 board (DT)
> pstate: 20400005 (nzCv daif +PAN -UAO -TCO BTYPE=--)
> pc : vpu_dec_ipi_handler+0x58/0x1f8 [mtk_vcodec_dec]
> lr : scp_ipi_handler+0xd0/0x194 [mtk_scp]
> sp : ffffffc0131dbbd0
> x29: ffffffc0131dbbd0 x28: 0000000000000000
> x27: ffffff9bb277f348 x26: ffffff9bb242ad00
> x25: ffffffd2d440d3b8 x24: ffffffd2a13ff1d4
> x23: ffffff9bb7fe85a0 x22: ffffffc0133fbdb0
> x21: 0000000000000010 x20: ffffff9b050ea328
> x19: ffffffc0131dbc08 x18: 0000000000001000
> x17: 0000000000000000 x16: ffffffd2d461c6e0
> x15: 0000000000000242 x14: 000000000000018f
> x13: 000000000000004d x12: 0000000000000000
> x11: 0000000000000001 x10: fffffffffffffff0
> x9 : ffffff9bb6e793a8 x8 : 0000000000000000
> x7 : 0000000000000000 x6 : 000000000000003f
> x5 : 0000000000000040 x4 : fffffffffffffff0
> x3 : 0000000000000020 x2 : ffffff9bb6e79080
> x1 : 0000000000000010 x0 : ffffffc0131dbc08
> Call trace:
> vpu_dec_ipi_handler+0x58/0x1f8 [mtk_vcodec_dec (HASH:6c3f 2)]
> scp_ipi_handler+0xd0/0x194 [mtk_scp (HASH:7046 3)]
> mt8183_scp_irq_handler+0x44/0x88 [mtk_scp (HASH:7046 3)]
> scp_irq_handler+0x48/0x90 [mtk_scp (HASH:7046 3)]
> irq_thread_fn+0x38/0x94
> irq_thread+0x100/0x1c0
> kthread+0x140/0x1fc
> ret_from_fork+0x10/0x30
> Code: 54000088 f94ca50a eb14015f 54000060 (f9400108)
> ---[ end trace ace43ce36cbd5c93 ]---
> Kernel panic - not syncing: Oops: Fatal exception
> SMP: stopping secondary CPUs
> Kernel Offset: 0x12c4000000 from 0xffffffc010000000
> PHYS_OFFSET: 0xffffffe580000000
> CPU features: 0x08240002,2188200c
> Memory Limit: none
> 
> Fixes: 655b86e52eac ("media: mediatek: vcodec: Fix possible invalid memory access for decoder")
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From tglx at linutronix.de  Fri Feb 23 00:28:39 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 23 Feb 2024 09:28:39 +0100
Subject: [PATCH v14 11/18] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <20240222094006.1030709-12-apatel@ventanamicro.com>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
 <20240222094006.1030709-12-apatel@ventanamicro.com>
Message-ID: <87a5nreg94.ffs@tglx>

On Thu, Feb 22 2024 at 15:09, Anup Patel wrote:
> +	/*
> +	 * Setup cpuhp state (must be done after setting imsic_parent_irq)
> +	 *
> +	 * Don't disable per-CPU IMSIC file when CPU goes offline
> +	 * because this affects IPI and the masking/unmasking of
> +	 * virtual IPIs is done via generic IPI-Mux
> +	 */
> +	cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "irqchip/riscv/imsic:starting",
> +			  imsic_starting_cpu, imsic_dying_cpu);

This is not really correct. IPIs should be working right away when a CPU
comes online and on the unplug side until it really goes offline.

So this wants to be in the starting range, i.e. between CPUHP_AP_OFFLINE
and CPUHP_AP_ONLINE. No?

Thanks,

        tglx


From cristian.marussi at arm.com  Fri Feb 23 00:33:55 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Fri, 23 Feb 2024 08:33:55 +0000
Subject: [PATCH v4 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <CACRpkdZLuWwecacBAimT=Vj67dGabzBH-7aaqzoyj1B1sY6o_A@mail.gmail.com>
References: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>
 <20240223-pinctrl-scmi-v4-3-10eb5a379274@nxp.com>
 <CACRpkdZLuWwecacBAimT=Vj67dGabzBH-7aaqzoyj1B1sY6o_A@mail.gmail.com>
Message-ID: <ZdhYc90uy7yuYrx2@pluto>

On Fri, Feb 23, 2024 at 09:28:12AM +0100, Linus Walleij wrote:
> On Fri, Feb 23, 2024 at 2:08?AM Peng Fan (OSS) <peng.fan at oss.nxp.com> wrote:
> 
> > From: Oleksii Moisieiev <oleksii_moisieiev at epam.com>
> >
> > Add basic implementation of the SCMI v3.2 pincontrol protocol.
> >
> > Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>
> > Tested-by: Cristian Marussi <cristian.marussi at arm.com>
> > Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> > Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev at epam.com>
> > Co-developed-by: Peng Fan <peng.fan at nxp.com>
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> 
> This looks ripe for merging for me, there are clearly dependencies in the SCMI
> firmware tree so I can't apply this to the pin control tree, but if
> someone creates
> an immutable branch from the SCMI firmware repo (based off v6.8-rc1 or so)
> I'm happy to also pull the branch into pin control.
> 

Well, AFAIK there is another upcoming change in the v3.2 SCMI spec and
I am not sure if this series accounts for it...indeed the v3.2 -bet4 was
still pending fr feedback AFAIK (and I doubt latest changes are in since
they have been discussed like yesterday...)....but I maybe wrong, I will
chase for the final spec and look into this to verify if it is
compliant...

Anyway, given the particularly long history of changes in PINCTRL v3.2
SCMI I would wait to have the final spec officially frozen at this
point before merging....

Thanks,
Cristian



From linus.walleij at linaro.org  Fri Feb 23 00:35:33 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 23 Feb 2024 09:35:33 +0100
Subject: [PATCH v4 3/4] firmware: arm_scmi: Add SCMI v3.2 pincontrol
 protocol basic support
In-Reply-To: <ZdhYc90uy7yuYrx2@pluto>
References: <20240223-pinctrl-scmi-v4-0-10eb5a379274@nxp.com>
 <20240223-pinctrl-scmi-v4-3-10eb5a379274@nxp.com> <CACRpkdZLuWwecacBAimT=Vj67dGabzBH-7aaqzoyj1B1sY6o_A@mail.gmail.com>
 <ZdhYc90uy7yuYrx2@pluto>
Message-ID: <CACRpkdYZuHh4JuwwgUEeVR_0jG1DPtj212AMOgnaxWdkT_sowg@mail.gmail.com>

On Fri, Feb 23, 2024 at 9:34?AM Cristian Marussi
<cristian.marussi at arm.com> wrote:

> Well, AFAIK there is another upcoming change in the v3.2 SCMI spec and
> I am not sure if this series accounts for it...indeed the v3.2 -bet4 was
> still pending fr feedback AFAIK (and I doubt latest changes are in since
> they have been discussed like yesterday...)....but I maybe wrong, I will
> chase for the final spec and look into this to verify if it is
> compliant...
>
> Anyway, given the particularly long history of changes in PINCTRL v3.2
> SCMI I would wait to have the final spec officially frozen at this
> point before merging....

OK fair enough, I hold my horses!

Maybe we should mark the series as pending spec or something.

Yours,
Linus Walleij


From megi at xff.cz  Fri Feb 23 00:46:25 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Fri, 23 Feb 2024 09:46:25 +0100
Subject: [PATCH v2 3/4] arm64: dts: sun50i-a64-pinephone: add multicolor
 led node
In-Reply-To: <20240206185400.596979-3-aren@peacevolution.org>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <20240206185400.596979-3-aren@peacevolution.org>
Message-ID: <sixgkkllo7medcjwjnmbkpqkgfvnmrtlhlwarwuxid5oqwrht5@gl65b6fetq2b>

Hello Aren,

On Tue, Feb 06, 2024 at 01:13:19PM -0500, Aren Moynihan wrote:
> The red, green, and blue leds currently in the device tree represent a
> single rgb led on the front of the PinePhone.
> 
> Signed-off-by: Aren Moynihan <aren at peacevolution.org>
> ---
> 
> Changes in v2:
>  - remove function property from individual led nodes
> 
>  .../boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> index ad2476ee01e4..e53e0d4579a7 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> @@ -39,28 +39,32 @@ chosen {
>  	leds {
>  		compatible = "gpio-leds";
>  
> -		led-0 {
> -			function = LED_FUNCTION_INDICATOR;

This looks like a needless change that will just break people's current scripts
and setup. It does mine, and there sure are others that will be surprised, too.

This leads to a change in sysfs path from:

  /sys/class/leds/blue:indicator

to

  /sys/class/leds/blue:

which is 1) a weird name and 2) a backwards compatibility break for seemingly
no apparent reason. Any reaons for the change?

People normally hardcode these paths in eg. /etc/tmpfiles.d to apply LED triggers
to particular LEDs.

Kind regards,
	o.

> +		led0: led-0 {
>  			color = <LED_COLOR_ID_BLUE>;
>  			gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */
>  			retain-state-suspended;
>  		};
>  
> -		led-1 {
> -			function = LED_FUNCTION_INDICATOR;
> +		led1: led-1 {
>  			color = <LED_COLOR_ID_GREEN>;
>  			gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */
>  			retain-state-suspended;
>  		};
>  
> -		led-2 {
> -			function = LED_FUNCTION_INDICATOR;
> +		led2: led-2 {
>  			color = <LED_COLOR_ID_RED>;
>  			gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */
>  			retain-state-suspended;
>  		};
>  	};
>  
> +	multi-led {
> +		compatible = "leds-group-multicolor";
> +		color = <LED_COLOR_ID_RGB>;
> +		function = LED_FUNCTION_INDICATOR;
> +		leds = <&led0>, <&led1>, <&led2>;
> +	};
> +
>  	reg_ps: ps-regulator {
>  		compatible = "regulator-fixed";
>  		regulator-name = "ps";
> -- 
> 2.43.0
> 


From d-gole at ti.com  Fri Feb 23 01:04:10 2024
From: d-gole at ti.com (Dhruva Gole)
Date: Fri, 23 Feb 2024 14:34:10 +0530
Subject: [PATCH] firmware/psci: Move psci_init_system_suspend() to
 late_initcall()
In-Reply-To: <dc16acc1-6ad1-4a81-8eeb-aadaf837ff2c@quicinc.com>
References: <20240219-suspend_ops_late_init-v1-1-6330ca9597fa@quicinc.com>
 <ZdOP5oAwZvEhNAsn@lpieralisi>
 <dc16acc1-6ad1-4a81-8eeb-aadaf837ff2c@quicinc.com>
Message-ID: <20240223090410.mgsu47wqinw33wep@dhruva>

On Feb 20, 2024 at 11:18:39 +0530, Maulik Shah (mkshah) wrote:
> 
> 
> On 2/19/2024 10:59 PM, Lorenzo Pieralisi wrote:
> > On Mon, Feb 19, 2024 at 03:02:04PM +0530, Maulik Shah wrote:
> > > psci_init_system_suspend() invokes suspend_set_ops() very early during
> > > bootup even before kernel command line for mem_sleep_default is setup.
> > > This leads to kernel command line mem_sleep_default=s2idle not working
> > > as mem_sleep_current gets changed to deep via suspend_set_ops() and never
> > > changes back to s2idle.
> > > 
> > > Move psci_init_system_suspend() to late_initcall() to make sure kernel
> > > command line mem_sleep_default=s2idle sets up s2idle as default suspend
> > > mode.
> > 
> > Why can't we fix it the other way around, namely enforce
> > mem_sleep_current according to the mem_sleep_default command line
> > even if suspend_set_ops() was already called ?
> 
> yes, this may be fixed other way also and i did not implement other way
> since mem_sleep_default_setup() only update mem_sleep_default and to avoid
> this race, it needs to also need to update mem_sleep_current along
> with it. Below change also resolves the issue.
> 
> --- a/kernel/power/suspend.c
> +++ b/kernel/power/suspend.c
> @@ -192,6 +192,7 @@ static int __init mem_sleep_default_setup(char *str)
>                 if (mem_sleep_labels[state] &&
>                     !strcmp(str, mem_sleep_labels[state])) {
>                         mem_sleep_default = state;
> +                       mem_sleep_current = state;
>                         break;
>                 }
> 
> however it may be erasing thin line between mem_sleep_default v/s
> mem_sleep_current as both gets updated while set up of mem_sleep_default.
> 
> if this change looks Ok, i can send v2 with it.

Honestly, I don't see too much of a problem with this, it only makes
sense that we're starting off with a default sleep state which means
that it will be considered as "current" sleep state.

For the issue that you described originally, I think this is a fine
solution.

> 
> > 
> > Just asking, I am not super keen on using initcalls ordering, it
> > looks fragile to me.
> 
> i agree with above.

Same.


-- 
Best regards,
Dhruva Gole <d-gole at ti.com>


From alexander.stein at ew.tq-group.com  Fri Feb 23 01:06:33 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 23 Feb 2024 10:06:33 +0100
Subject: [PATCH 1/2] arm64: dts: imx8mp-evk: Add HDMI audio sound card support
In-Reply-To: <1708675339-8180-1-git-send-email-shengjiu.wang@nxp.com>
References: <1708675339-8180-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <1786327.VLH7GnMWUR@steina-w>

Hi,

thanks for the patch.

Am Freitag, 23. Februar 2024, 09:02:18 CET schrieb Shengjiu Wang:
> The AUD2HTX is a digital module that provides a bridge between
> the Audio Subsystem and the HDMI RTX Subsystem. This
> module includes intermediate storage to queue SDMA transactions
> prior to being synchronized and passed to the HDMI
> RTX Subsystem over the Audio Link.
> 
> AUD2HTX works as the cpu dai in HDMI audio sound card.
> 
> Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 12 ++++++++++++
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi    | 10 ++++++++++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> index f87fa5a948cc..63f6e72fa18a 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> @@ -138,6 +138,14 @@ simple-audio-card,codec {
>  
>  	};
>  
> +	sound-hdmi {
> +		compatible = "fsl,imx-audio-hdmi";
> +		model = "audio-hdmi";
> +		audio-cpu = <&aud2htx>;
> +		hdmi-out;
> +		status = "okay";

No need for 'status' here.

Don't you need to configure the PAI as well? See [1]
for downstream implementation. I'm wondering because I had to hack something
similar. Without I got no HDMI audio.

Best regards,
Alexander

[1] https://github.com/Freescale/linux-fslc/blob/6.1-2.0.x-imx/drivers/gpu/drm/imx/imx8mp-hdmi-pavi.c#L51-L59

> +	};
> +
>  	reserved-memory {
>  		#address-cells = <2>;
>  		#size-cells = <2>;
> @@ -191,6 +199,10 @@ &A53_3 {
>  	cpu-supply = <&reg_arm>;
>  };
>  
> +&aud2htx {
> +	status = "okay";
> +};
> +
>  &eqos {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_eqos>;
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> index 9ab9c057f41e..721ab630d895 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -1513,6 +1513,16 @@ micfil: audio-controller at 30ca0000 {
>  					status = "disabled";
>  				};
>  
> +				aud2htx: aud2htx at 30cb0000 {
> +					compatible = "fsl,imx8mp-aud2htx";
> +					reg = <0x30cb0000 0x10000>;
> +					interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
> +					clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG>;
> +					clock-names = "bus";
> +					dmas = <&sdma2 26 2 0>;
> +					dma-names = "tx";
> +					status = "disabled";
> +				};
>  			};
>  
>  			sdma3: dma-controller at 30e00000 {
> 


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From victor.liu at nxp.com  Fri Feb 23 01:15:22 2024
From: victor.liu at nxp.com (Liu Ying)
Date: Fri, 23 Feb 2024 17:15:22 +0800
Subject: [PATCH] arm64: dts: imx8mp: Fix LDB clocks property
Message-ID: <20240223091522.2880155-1-victor.liu@nxp.com>

The "media_ldb_root_clk" is the gate clock to enable or disable the clock
provided by CCM(Clock Control Module) to LDB instead of the "media_ldb"
clock which is the parent of the "media_ldb_root_clk" clock as a composite
clock.  Fix LDB clocks property by referencing the "media_ldb_root_clk"
clock instead of the "media_ldb" clock.

Fixes: e7567840ecd3 ("arm64: dts: imx8mp: Reorder clock and reg properties")
Fixes: 94e6197dadc9 ("arm64: dts: imx8mp: Add LCDIF2 & LDB nodes")
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 9ab9c057f41e..bfc5c81a5bd4 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1824,7 +1824,7 @@ lvds_bridge: bridge at 5c {
 					compatible = "fsl,imx8mp-ldb";
 					reg = <0x5c 0x4>, <0x128 0x4>;
 					reg-names = "ldb", "lvds";
-					clocks = <&clk IMX8MP_CLK_MEDIA_LDB>;
+					clocks = <&clk IMX8MP_CLK_MEDIA_LDB_ROOT>;
 					clock-names = "ldb";
 					assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>;
 					assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>;
-- 
2.37.1



From David.Laight at ACULAB.COM  Fri Feb 23 01:07:27 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 23 Feb 2024 09:07:27 +0000
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <20240222223617.GC13330@nvidia.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
 <20240222223617.GC13330@nvidia.com>
Message-ID: <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>

From: Jason Gunthorpe
> Sent: 22 February 2024 22:36
> To: David Laight <David.Laight at ACULAB.COM>
> 
> On Thu, Feb 22, 2024 at 10:05:04PM +0000, David Laight wrote:
> > From: Jason Gunthorpe
> > > Sent: 21 February 2024 01:17
> > >
> > > The kernel provides driver support for using write combining IO memory
> > > through the __iowriteXX_copy() API which is commonly used as an optional
> > > optimization to generate 16/32/64 byte MemWr TLPs in a PCIe environment.
> > >
> > ...
> > > Implement __iowrite32/64_copy() specifically for ARM64 and use inline
> > > assembly to build consecutive blocks of STR instructions. Provide direct
> > > support for 64/32/16 large TLP generation in this manner. Optimize for
> > > common constant lengths so that the compiler can directly inline the store
> > > blocks.
> > ...
> > > +/*
> > > + * This generates a memcpy that works on a from/to address which is aligned to
> > > + * bits. Count is in terms of the number of bits sized quantities to copy. It
> > > + * optimizes to use the STR groupings when possible so that it is WC friendly.
> > > + */
> > > +#define memcpy_toio_aligned(to, from, count, bits)                        \
> > > +	({                                                                \
> > > +		volatile u##bits __iomem *_to = to;                       \
> > > +		const u##bits *_from = from;                              \
> > > +		size_t _count = count;                                    \
> > > +		const u##bits *_end_from = _from + ALIGN_DOWN(_count, 8); \
> > > +                                                                          \
> > > +		for (; _from < _end_from; _from += 8, _to += 8)           \
> > > +			__const_memcpy_toio_aligned##bits(_to, _from, 8); \
> > > +		if ((_count % 8) >= 4) {
> >
> > If (_count & 4) {
> 
> That would be obfuscating, IMHO. The compiler doesn't need such things
> to generate optimal code.

Try it: https://godbolt.org/z/EvvGrTxv3 
And it isn't that obfuscated - no more so than your version.

> > > +			__const_memcpy_toio_aligned##bits(_to, _from, 1); \
> > > +	})
> >
> > But that looks bit a bit large to be inlined.
> 
> You trimmed alot, this #define is in a C file and it is a template to
> generate the 32 and 64 bit out of line functions. Things are done like
> this because the 32/64 version are exactly the same logic except just
> with different types and sizes.

I missed that in a quick read at 11pm :-(

Although I doubt that generating long TLP from byte writes is
really necessary.
IIRC you were merging at most 4 writes.
So better to do a single 32bit write instead.
(Unless you have misaligned source data - unlikely.)

While write-combining to generate long TLP is probably mostly
safe for PCIe targets, there are some that will only handle
TLP for single 32bit data items.
Which might be why the code is explicitly requesting 4 byte copies.
So it may be entirely wrong to write-combine anything except
the generic memcpy_toio().

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From naresh.kamboju at linaro.org  Fri Feb 23 01:10:17 2024
From: naresh.kamboju at linaro.org (Naresh Kamboju)
Date: Fri, 23 Feb 2024 14:40:17 +0530
Subject: arch/arm64/include/asm/atomic_ll_sc.h:298:9: error: unknown type name 'u128'
Message-ID: <CA+G9fYtrXXm_KO9fNPz3XaRxHV7UD_yQp-TEuPQrNRHU+_0W_Q@mail.gmail.com>

The arm64 defconfig builds failed on today's Linux next tag  next-20240223.

arm64:
    defconfig: gcc-13 - Failed
    defconfig: clang-17 - Failed

Build log:
------
2024/02/23 08:03:02 socat-internal[923] W waitpid(-1, {}, WNOHANG): no
child has exited
2024/02/23 08:03:02 socat-internal[923] W waitpid(-1, {}, WNOHANG): no
child has exited
2024/02/23 08:03:02 socat-external[919] W waitpid(-1, {}, WNOHANG): no
child has exited
arch/arm64/boot/dts/freescale/mba8xx.dtsi:233.20-249.4: Warning
(interrupt_provider): /bus at 5a000000/i2c at 5a810000/gpio at 70: Missing
'#interrupt-cells' in interrupt provider
arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dtb: Warning
(interrupt_map): Failed prerequisite 'interrupt_provider'
2024/02/23 08:03:04 socat-internal[923] W waitpid(-1, {}, WNOHANG): no
child has exited
2024/02/23 08:03:06 socat-external[919] W waitpid(-1, {}, WNOHANG): no
child has exited
In file included from arch/arm64/include/asm/lse.h:5,
                 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:68,
                 from arch/arm64/include/asm/memory.h:209,
                 from arch/arm64/include/asm/page.h:46,
                 from include/vdso/datapage.h:22,
                 from lib/vdso/gettimeofday.c:5,
                 from <command-line>:
arch/arm64/include/asm/atomic_ll_sc.h:298:9: error: unknown type name 'u128'
  298 |         u128 full;
      |         ^~~~
arch/arm64/include/asm/atomic_ll_sc.h:305:24: error: unknown type name 'u128'
  305 | static __always_inline u128
         \
      |

Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>

Steps to reproduce:
 $ tuxmake --runtime podman --target-arch arm64 --toolchain gcc-13
--kconfig defconfig

Links:
 - https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20240223/testrun/22811036/suite/build/test/gcc-13-defconfig/details/
 - https://storage.tuxsuite.com/public/linaro/lkft/builds/2cl8paYnjzOljEurAWeMOWjikoy/


--
Linaro LKFT
https://lkft.linaro.org


From wenst at chromium.org  Fri Feb 23 01:11:21 2024
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Fri, 23 Feb 2024 17:11:21 +0800
Subject: [PATCH] arm64: dts: mediatek: mt8183: Add power-domains properity to mfgcfg
Message-ID: <20240223091122.2430037-1-wenst@chromium.org>

From: Ikjoon Jang <ikjn at chromium.org>

mfgcfg clock is under MFG_ASYNC power domain.

Fixes: e526c9bc11f8 ("arm64: dts: Add Mediatek SoC MT8183 and evaluation board dts and Makefile")
Fixes: 37fb78b9aeb7 ("arm64: dts: mediatek: Add mt8183 power domains controller")
Signed-off-by: Weiyi Lu <weiyi.lu at mediatek.com>
Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
This patch is long overdue. Could we merge it for fixes for this or the
next release?

Changes since v2:
- Rebased onto current tree
- Added Fixes tags
- Fix up subject prefix

 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 93dfbf130231..774ae5d9143f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1637,6 +1637,7 @@ mfgcfg: syscon at 13000000 {
 			compatible = "mediatek,mt8183-mfgcfg", "syscon";
 			reg = <0 0x13000000 0 0x1000>;
 			#clock-cells = <1>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_MFG_ASYNC>;
 		};
 
 		gpu: gpu at 13040000 {
-- 
2.44.0.rc0.258.g7320e95886-goog



From dharma.b at microchip.com  Fri Feb 23 01:14:48 2024
From: dharma.b at microchip.com (Dharma Balasubiramani)
Date: Fri, 23 Feb 2024 14:44:48 +0530
Subject: [PATCH] dt-bindings: display: atmel,lcdc: convert to dtschema
Message-ID: <20240223-lcdc-fb-v1-1-4c64cb6277df@microchip.com>

Convert the atmel,lcdc bindings to DT schema.
Changes during conversion: add missing clocks and clock-names properties.

Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
---
 .../devicetree/bindings/display/atmel,lcdc.txt     |  87 --------------
 .../devicetree/bindings/display/atmel,lcdc.yaml    | 133 +++++++++++++++++++++
 2 files changed, 133 insertions(+), 87 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/atmel,lcdc.txt b/Documentation/devicetree/bindings/display/atmel,lcdc.txt
deleted file mode 100644
index b5e355ada2fa..000000000000
--- a/Documentation/devicetree/bindings/display/atmel,lcdc.txt
+++ /dev/null
@@ -1,87 +0,0 @@
-Atmel LCDC Framebuffer
------------------------------------------------------
-
-Required properties:
-- compatible :
-	"atmel,at91sam9261-lcdc" , 
-	"atmel,at91sam9263-lcdc" ,
-	"atmel,at91sam9g10-lcdc" ,
-	"atmel,at91sam9g45-lcdc" ,
-	"atmel,at91sam9g45es-lcdc" ,
-	"atmel,at91sam9rl-lcdc" ,
-- reg : Should contain 1 register ranges(address and length).
-	Can contain an additional register range(address and length)
-	for fixed framebuffer memory. Useful for dedicated memories.
-- interrupts : framebuffer controller interrupt
-- display: a phandle pointing to the display node
-
-Required nodes:
-- display: a display node is required to initialize the lcd panel
-	This should be in the board dts.
-- default-mode: a videomode within the display with timing parameters
-	as specified below.
-
-Optional properties:
-- lcd-supply: Regulator for LCD supply voltage.
-
-Example:
-
-	fb0: fb at 00500000 {
-		compatible = "atmel,at91sam9g45-lcdc";
-		reg = <0x00500000 0x1000>;
-		interrupts = <23 3 0>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_fb>;
-		display = <&display0>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-
-	};
-
-Example for fixed framebuffer memory:
-
-	fb0: fb at 00500000 {
-		compatible = "atmel,at91sam9263-lcdc";
-		reg = <0x00700000 0x1000 0x70000000 0x200000>;
-		[...]
-	};
-
-Atmel LCDC Display
------------------------------------------------------
-Required properties (as per of_videomode_helper):
-
- - atmel,dmacon: dma controller configuration
- - atmel,lcdcon2: lcd controller configuration
- - atmel,guard-time: lcd guard time (Delay in frame periods)
- - bits-per-pixel: lcd panel bit-depth.
-
-Optional properties (as per of_videomode_helper):
- - atmel,lcdcon-backlight: enable backlight
- - atmel,lcdcon-backlight-inverted: invert backlight PWM polarity
- - atmel,lcd-wiring-mode: lcd wiring mode "RGB" or "BRG"
- - atmel,power-control-gpio: gpio to power on or off the LCD (as many as needed)
-
-Example:
-	display0: display {
-		bits-per-pixel = <32>;
-		atmel,lcdcon-backlight;
-		atmel,dmacon = <0x1>;
-		atmel,lcdcon2 = <0x80008002>;
-		atmel,guard-time = <9>;
-		atmel,lcd-wiring-mode = <1>;
-
-		display-timings {
-			native-mode = <&timing0>;
-			timing0: timing0 {
-				clock-frequency = <9000000>;
-				hactive = <480>;
-				vactive = <272>;
-				hback-porch = <1>;
-				hfront-porch = <1>;
-				vback-porch = <40>;
-				vfront-porch = <1>;
-				hsync-len = <45>;
-				vsync-len = <1>;
-			};
-		};
-	};
diff --git a/Documentation/devicetree/bindings/display/atmel,lcdc.yaml b/Documentation/devicetree/bindings/display/atmel,lcdc.yaml
new file mode 100644
index 000000000000..4a1de5a8d64b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/atmel,lcdc.yaml
@@ -0,0 +1,133 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/atmel,lcdc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip's LCDC Framebuffer
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
+  - Dharma Balasubiramani <dharma.b at microchip.com>
+
+description:
+  The LCDC works with a framebuffer, which is a section of memory that contains
+  a complete frame of data representing pixel values for the display. The LCDC
+  reads the pixel data from the framebuffer and sends it to the LCD panel to
+  render the image.
+
+properties:
+  compatible:
+    enum:
+      - atmel,at91sam9261-lcdc 
+      - atmel,at91sam9263-lcdc
+      - atmel,at91sam9g10-lcdc
+      - atmel,at91sam9g45-lcdc
+      - atmel,at91sam9g45es-lcdc
+      - atmel,at91sam9rl-lcdc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks: 
+    maxItems: 2
+ 
+  clock-names:
+    items:
+      - const: hclk
+      - const: lcdc_clk
+
+  display:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: A phandle pointing to the display node.
+
+    properties:
+      atmel,dmacon:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: dma controller configuration
+
+      atmel,lcdcon2:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: lcd controller configuration
+
+      atmel,guard-time:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: lcd guard time (Delay in frame periods)
+
+      bits-per-pixel:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: lcd panel bit-depth.
+
+      atmel,lcdcon-backlight: 
+        $ref: /schemas/types.yaml#/definitions/flag
+        description: enable backlight
+
+      atmel,lcdcon-backlight-inverted:
+        $ref: /schemas/types.yaml#/definitions/flag
+        description: invert backlight PWM polarity
+
+      atmel,lcd-wiring-mode:
+        $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+        description: lcd wiring mode "RGB" or "BRG"
+
+      atmel,power-control-gpio:
+        description: gpio to power on or off the LCD (as many as needed)
+
+    required:
+      - atmel,dmacon
+      - atmel,lcdcon2
+      - atmel,guard-time
+      - bits-per-pixel 
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - display
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/at91.h>
+    fb at 500000 {
+      compatible = "atmel,at91sam9g45-lcdc";
+      reg = <0x00500000 0x1000>;
+      interrupts = <23 3 0>;
+      pinctrl-names = "default";
+      pinctrl-0 = <&pinctrl_fb>;
+      clocks = <&pmc PMC_TYPE_PERIPHERAL 23>, <&pmc PMC_TYPE_PERIPHERAL 23>;
+      clock-names = "hclk", "lcdc_clk";
+      display = <&display0>;
+    };
+
+    display {
+      bits-per-pixel = <32>;
+      atmel,lcdcon-backlight;
+      atmel,dmacon = <0x1>;
+      atmel,lcdcon2 = <0x80008002>;
+      atmel,guard-time = <9>;
+      atmel,lcd-wiring-mode = <1>;
+      
+      display-timings {
+        native-mode = <&timing0>;
+        timing0: timing0 {
+          clock-frequency = <9000000>;
+          hactive = <480>;
+          vactive = <272>;
+          hback-porch = <1>;
+          hfront-porch = <1>;
+          vback-porch = <40>;
+          vfront-porch = <1>;
+          hsync-len = <45>;
+          vsync-len = <1>;
+        };
+      };
+    };

---
base-commit: ffd2cb6b718e189e7e2d5d0c19c25611f92e061a
change-id: 20240223-lcdc-fb-b8d2e2f3c914

Best regards,
-- 
Dharma Balasubiramani <dharma.b at microchip.com>



From balakrishnan.s at microchip.com  Fri Feb 23 01:16:22 2024
From: balakrishnan.s at microchip.com (Balakrishnan Sambath)
Date: Fri, 23 Feb 2024 14:46:22 +0530
Subject: [PATCH v2 1/2] ARM: dts: microchip: sama7g5: add sama7g5
 compatible
In-Reply-To: <20240223-b4-sama5d2-flexcom-yaml-v2-0-7e96c60c7701@microchip.com>
References: <20240223-b4-sama5d2-flexcom-yaml-v2-0-7e96c60c7701@microchip.com>
Message-ID: <20240223-b4-sama5d2-flexcom-yaml-v2-1-7e96c60c7701@microchip.com>

Add sama7g5 flexcom specific compatible in DT with fallbacks.

Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>
---
 arch/arm/boot/dts/microchip/sama7g5.dtsi | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
index 269e0a3ca269..6496a4ca376f 100644
--- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
+++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
@@ -698,7 +698,7 @@ sha: crypto at e1814000 {
 		};
 
 		flx0: flexcom at e1818000 {
-			compatible = "atmel,sama5d2-flexcom";
+			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
 			reg = <0xe1818000 0x200>;
 			clocks = <&pmc PMC_TYPE_PERIPHERAL 38>;
 			#address-cells = <1>;
@@ -723,7 +723,7 @@ uart0: serial at 200 {
 		};
 
 		flx1: flexcom at e181c000 {
-			compatible = "atmel,sama5d2-flexcom";
+			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
 			reg = <0xe181c000 0x200>;
 			clocks = <&pmc PMC_TYPE_PERIPHERAL 39>;
 			#address-cells = <1>;
@@ -747,7 +747,7 @@ i2c1: i2c at 600 {
 		};
 
 		flx3: flexcom at e1824000 {
-			compatible = "atmel,sama5d2-flexcom";
+			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
 			reg = <0xe1824000 0x200>;
 			clocks = <&pmc PMC_TYPE_PERIPHERAL 41>;
 			#address-cells = <1>;
@@ -791,7 +791,7 @@ tdes: crypto at e2014000 {
 		};
 
 		flx4: flexcom at e2018000 {
-			compatible = "atmel,sama5d2-flexcom";
+			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
 			reg = <0xe2018000 0x200>;
 			clocks = <&pmc PMC_TYPE_PERIPHERAL 42>;
 			#address-cells = <1>;
@@ -817,7 +817,7 @@ uart4: serial at 200 {
 		};
 
 		flx7: flexcom at e2024000 {
-			compatible = "atmel,sama5d2-flexcom";
+			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
 			reg = <0xe2024000 0x200>;
 			clocks = <&pmc PMC_TYPE_PERIPHERAL 45>;
 			#address-cells = <1>;
@@ -911,7 +911,7 @@ tcb0: timer at e2814000 {
 		};
 
 		flx8: flexcom at e2818000 {
-			compatible = "atmel,sama5d2-flexcom";
+			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
 			reg = <0xe2818000 0x200>;
 			clocks = <&pmc PMC_TYPE_PERIPHERAL 46>;
 			#address-cells = <1>;
@@ -935,7 +935,7 @@ i2c8: i2c at 600 {
 		};
 
 		flx9: flexcom at e281c000 {
-			compatible = "atmel,sama5d2-flexcom";
+			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
 			reg = <0xe281c000 0x200>;
 			clocks = <&pmc PMC_TYPE_PERIPHERAL 47>;
 			#address-cells = <1>;
@@ -959,7 +959,7 @@ i2c9: i2c at 600 {
 		};
 
 		flx11: flexcom at e2824000 {
-			compatible = "atmel,sama5d2-flexcom";
+			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
 			reg = <0xe2824000 0x200>;
 			clocks = <&pmc PMC_TYPE_PERIPHERAL 49>;
 			#address-cells = <1>;

-- 
2.25.1



From balakrishnan.s at microchip.com  Fri Feb 23 01:16:21 2024
From: balakrishnan.s at microchip.com (Balakrishnan Sambath)
Date: Fri, 23 Feb 2024 14:46:21 +0530
Subject: [PATCH v2 0/2] Convert atmel-flexcom to json-schema
Message-ID: <20240223-b4-sama5d2-flexcom-yaml-v2-0-7e96c60c7701@microchip.com>

The yaml DT bindings for the atmel-flexcom driver were submitted
upstream in a separate patch series in 2022 [1] which was Acked-by
Krzysztof Kozlowski. However, it has been observed recently that the
patch has not been merged into the mainline codebase.When attempting to
apply the patch to the latest upstream kernel,a conflict arose due to a
recent addition to the original device tree binding in text format. The
conflict has now been resolved and we are sending a updated version of
the patch.Also updated the DTS changes as recommended in [2].

[1]https://lore.kernel.org/linux-arm-kernel/22063373-6060-d605-62af-35d82ba1729c at linaro.org/
[2]https://lore.kernel.org/lkml/0798f21e-1ab6-4fd2-b7e3-18f35163fad1 at tuxon.dev/

Note: The patch "[PATCH 2/2] dt-bindings: mfd: Convert atmel-flexcom to
json-schema" has dependency on "[PATCH 1/2] ARM: dts:microchip: sama7g5:
add sama7g5 compatible"

Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>
---
changes in v2:
--------------
- Added sama7g5 specific compatible in DT with fallbacks.
- Added sam9x7, sama7g5 compatible in DT bindings.
- Replaced "Atmel" with "Microchip" in DT bindings.
- Link to v1:https://lore.kernel.org/lkml/20240214-sama5d2-flexcom-yaml-v1-1-5dedd0eba08e at microchip.com/

---
Balakrishnan Sambath (2):
      ARM: dts: microchip: sama7g5: add sama7g5 compatible
      dt-bindings: mfd: Convert atmel-flexcom to json-schema

 .../bindings/mfd/atmel,sama5d2-flexcom.yaml        | 99 ++++++++++++++++++++++
 .../devicetree/bindings/mfd/atmel-flexcom.txt      | 64 --------------
 arch/arm/boot/dts/microchip/sama7g5.dtsi           | 16 ++--
 3 files changed, 107 insertions(+), 72 deletions(-)
---
base-commit: ffd2cb6b718e189e7e2d5d0c19c25611f92e061a
change-id: 20240223-b4-sama5d2-flexcom-yaml-b071c28da959

Best regards,
-- 
Balakrishnan Sambath <balakrishnan.s at microchip.com>



From balakrishnan.s at microchip.com  Fri Feb 23 01:16:23 2024
From: balakrishnan.s at microchip.com (Balakrishnan Sambath)
Date: Fri, 23 Feb 2024 14:46:23 +0530
Subject: [PATCH v2 2/2] dt-bindings: mfd: Convert atmel-flexcom to
 json-schema
In-Reply-To: <20240223-b4-sama5d2-flexcom-yaml-v2-0-7e96c60c7701@microchip.com>
References: <20240223-b4-sama5d2-flexcom-yaml-v2-0-7e96c60c7701@microchip.com>
Message-ID: <20240223-b4-sama5d2-flexcom-yaml-v2-2-7e96c60c7701@microchip.com>

Convert the Atmel flexcom device tree bindings to json schema.

Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>
---
 .../bindings/mfd/atmel,sama5d2-flexcom.yaml        | 99 ++++++++++++++++++++++
 .../devicetree/bindings/mfd/atmel-flexcom.txt      | 64 --------------
 2 files changed, 99 insertions(+), 64 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml b/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml
new file mode 100644
index 000000000000..0dc6a40b63f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/atmel,sama5d2-flexcom.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip Flexcom (Flexible Serial Communication Unit)
+
+maintainers:
+  - Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
+
+description:
+  The Microchip Flexcom is just a wrapper which embeds a SPI controller,
+  an I2C controller and an USART. Only one function can be used at a
+  time and is chosen at boot time according to the device tree.
+
+properties:
+  compatible:
+    oneOf:
+      - const: atmel,sama5d2-flexcom
+      - items:
+          - const: microchip,sam9x7-flexcom
+          - const: atmel,sama5d2-flexcom
+      - items:
+          - const: microchip,sama7g5-flexcom
+          - const: atmel,sama5d2-flexcom
+
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges:
+    description:
+      One range for the full I/O register region. (including USART,
+      TWI and SPI registers).
+    items:
+      maxItems: 3
+
+  atmel,flexcom-mode:
+    description: |
+      Specifies the flexcom mode as follows:
+      1: USART
+      2: SPI
+      3: I2C.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2, 3]
+
+patternProperties:
+  "^serial@[0-9a-f]+$":
+    type: object
+    description:
+      Child node describing USART. See atmel-usart.txt for details
+      of USART bindings.
+
+  "^spi@[0-9a-f]+$":
+    type: object
+    description:
+      Child node describing SPI. See ../spi/spi_atmel.txt for details
+      of SPI bindings.
+
+  "^i2c@[0-9a-f]+$":
+    $ref: /schemas/i2c/atmel,at91sam-i2c.yaml
+    description:
+      Child node describing I2C.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+  - atmel,flexcom-mode
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    flx0: flexcom at f8034000 {
+        compatible = "atmel,sama5d2-flexcom";
+        reg = <0xf8034000 0x200>;
+        clocks = <&flx0_clk>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0x0 0xf8034000 0x800>;
+        atmel,flexcom-mode = <2>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt b/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt
deleted file mode 100644
index af692e8833a5..000000000000
--- a/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-* Device tree bindings for Atmel Flexcom (Flexible Serial Communication Unit)
-
-The Atmel Flexcom is just a wrapper which embeds a SPI controller, an I2C
-controller and an USART. Only one function can be used at a time and is chosen
-at boot time according to the device tree.
-
-Required properties:
-- compatible:		Should be "atmel,sama5d2-flexcom"
-			or "microchip,sam9x7-flexcom", "atmel,sama5d2-flexcom"
-- reg:			Should be the offset/length value for Flexcom dedicated
-			I/O registers (without USART, TWI or SPI registers).
-- clocks:		Should be the Flexcom peripheral clock from PMC.
-- #address-cells:	Should be <1>
-- #size-cells:		Should be <1>
-- ranges:		Should be one range for the full I/O register region
-			(including USART, TWI and SPI registers).
-- atmel,flexcom-mode:	Should be one of the following values:
-			- <1> for USART
-			- <2> for SPI
-			- <3> for I2C
-
-Required child:
-A single available child device of type matching the "atmel,flexcom-mode"
-property.
-
-The phandle provided by the clocks property of the child is the same as one for
-the Flexcom parent.
-
-For other properties, please refer to the documentations of the respective
-device:
-- ../serial/atmel-usart.txt
-- ../spi/spi_atmel.txt
-- ../i2c/i2c-at91.txt
-
-Example:
-
-flexcom at f8034000 {
-	compatible = "atmel,sama5d2-flexcom";
-	reg = <0xf8034000 0x200>;
-	clocks = <&flx0_clk>;
-	#address-cells = <1>;
-	#size-cells = <1>;
-	ranges = <0x0 0xf8034000 0x800>;
-	atmel,flexcom-mode = <2>;
-
-	spi at 400 {
-		compatible = "atmel,at91rm9200-spi";
-		reg = <0x400 0x200>;
-		interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_flx0_default>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		clocks = <&flx0_clk>;
-		clock-names = "spi_clk";
-		atmel,fifo-size = <32>;
-
-		flash at 0 {
-			compatible = "atmel,at25f512b";
-			reg = <0>;
-			spi-max-frequency = <20000000>;
-		};
-	};
-};

-- 
2.25.1



From miquel.raynal at bootlin.com  Fri Feb 23 01:18:52 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri, 23 Feb 2024 10:18:52 +0100
Subject: [PATCH v6 12/13] mtd: rawnand: brcmnand: Add support for
 getting ecc setting from strap
In-Reply-To: <20240223034758.13753-13-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
	<20240223034758.13753-13-william.zhang@broadcom.com>
Message-ID: <20240223101852.005da3ad@xps-13>

Hi William,

william.zhang at broadcom.com wrote on Thu, 22 Feb 2024 19:47:57 -0800:

> BCMBCA broadband SoC based board design does not specify ecc setting in
> dts but rather use the SoC NAND strap info to obtain the ecc strength
> and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
> this purpose and update driver to support this option. However these two
> options can not be used at the same time.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>
> 

FYI I did not receive patches 7, 8, 9, which makes the series numbering
very odd.

> ---
> 
> Changes in v6:
> - Combine the ecc step size and ecc strength into one get function
> - Treat it as error condition if both brcm,nand-ecc-use-strap and nand
> ecc dts properties are set
> - Add intermediate steps to get the sector size bitfield
> 
> Changes in v5: None
> Changes in v4:
> - Update the comments for ecc setting selection
> 
> Changes in v3: None
> Changes in v2:
> - Minor cosmetic fixes
> 
>  drivers/mtd/nand/raw/brcmnand/brcmnand.c | 83 ++++++++++++++++++++++--
>  1 file changed, 77 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index ef7d340475be..e8ffc283b365 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -1038,6 +1038,22 @@ static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl)
>  		return -1;
>  }
>  
> +static int brcmnand_get_sector_size_1k(struct brcmnand_host *host)
> +{
> +	struct brcmnand_controller *ctrl = host->ctrl;
> +	int sector_size_bit = brcmnand_sector_1k_shift(ctrl);
> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> +						  BRCMNAND_CS_ACC_CONTROL);
> +	u32 acc_control;
> +
> +	if (sector_size_bit < 0)
> +		return 0;
> +
> +	acc_control = nand_readreg(ctrl, acc_control_offs);
> +
> +	return (acc_control & BIT(sector_size_bit)) >> sector_size_bit;

FIELD_PREP, FIELD_GET, *please*.

> +}
> +
>  static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
>  {
>  	struct brcmnand_controller *ctrl = host->ctrl;
> @@ -1055,6 +1071,43 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
>  	nand_writereg(ctrl, acc_control_offs, tmp);
>  }
>  
> +static int brcmnand_get_spare_size(struct brcmnand_host *host)
> +{
> +	struct brcmnand_controller *ctrl = host->ctrl;
> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> +						  BRCMNAND_CS_ACC_CONTROL);
> +	u32 acc = nand_readreg(ctrl, acc_control_offs);
> +
> +	return (acc & brcmnand_spare_area_mask(ctrl));
> +}
> +
> +static void brcmnand_get_ecc_settings(struct brcmnand_host *host, struct nand_chip *chip)
> +{
> +	struct brcmnand_controller *ctrl = host->ctrl;
> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> +						  BRCMNAND_CS_ACC_CONTROL);
> +	int sector_size_1k = brcmnand_get_sector_size_1k(host);
> +	int spare_area_size, ecc_level;
> +	u32 acc;
> +
> +	spare_area_size = brcmnand_get_spare_size(host);
> +	acc = nand_readreg(ctrl, acc_control_offs);
> +	ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl->ecc_level_shift;

ditto

> +	if (sector_size_1k)
> +		chip->ecc.strength = ecc_level * 2;
> +	else if (spare_area_size == 16 && ecc_level == 15)
> +		chip->ecc.strength = 1; /* hamming */
> +	else
> +		chip->ecc.strength = ecc_level;
> +
> +	if (chip->ecc.size == 0) {
> +		if (sector_size_1k < 0)

Should be <= 0 I guess

> +			chip->ecc.size = 512;
> +		else
> +			chip->ecc.size = 512 << sector_size_1k;

What is this? Are you expecting sector_size_1k to be 0 or 1
and thus multiply 512 by two?

Please just use:
			chip->ecc.size = SZ_1K;
			
> +	}
> +}
> +
>  /***********************************************************************
>   * CS_NAND_SELECT
>   ***********************************************************************/
> @@ -2625,19 +2678,37 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
>  		nanddev_get_memorg(&chip->base);
>  	struct brcmnand_controller *ctrl = host->ctrl;
>  	struct brcmnand_cfg *cfg = &host->hwcfg;
> -	char msg[128];
> +	struct device_node *np = nand_get_flash_node(chip);
>  	u32 offs, tmp, oob_sector;
> +	bool use_strap = false;
> +	char msg[128];
>  	int ret;
>  
>  	memset(cfg, 0, sizeof(*cfg));
> +	use_strap = of_property_read_bool(np, "brcm,nand-ecc-use-strap");
>  
> -	ret = of_property_read_u32(nand_get_flash_node(chip),
> -				   "brcm,nand-oob-sector-size",
> +	/*
> +	 * Either nand-ecc-xxx or brcm,nand-ecc-use-strap can be set. Error out
> +	 * if both exist.
> +	 */

Thanks for the comment but I think the error string is clear enough.

> +	if (chip->ecc.strength && use_strap) {
> +		dev_err(ctrl->dev,
> +			"nand ecc and strap ecc settings can't be set at the same time\n");

Can we change to
"ECC strap and DT ECC configuration properties are mutually exclusive"

> +		return -EINVAL;
> +	}
> +
> +	if (use_strap)
> +		brcmnand_get_ecc_settings(host, chip);
> +
> +	ret = of_property_read_u32(np, "brcm,nand-oob-sector-size",
>  				   &oob_sector);
>  	if (ret) {
> -		/* Use detected size */
> -		cfg->spare_area_size = mtd->oobsize /
> -					(mtd->writesize >> FC_SHIFT);
> +		if (use_strap)
> +			cfg->spare_area_size = brcmnand_get_spare_size(host);
> +		else
> +			/* Use detected size */
> +			cfg->spare_area_size = mtd->oobsize /
> +						(mtd->writesize >> FC_SHIFT);
>  	} else {
>  		cfg->spare_area_size = oob_sector;
>  	}

The rest of the series looks good to me.

Thanks,
Miqu?l


From maciej.przybylski at bizuniversal.pl  Fri Feb 23 01:15:48 2024
From: maciej.przybylski at bizuniversal.pl (Maciej Przybylski)
Date: Fri, 23 Feb 2024 09:15:48 GMT
Subject: =?UTF-8?Q?Prosz=C4=99_o_kontakt?=
Message-ID: <20240223084501-0.1.1l.6avu.0.g1jieohcxm@bizuniversal.pl>

Dzie? dobry,

Czy jest mo?liwo?? nawi?zania wsp??pracy z Pa?stwem?

Z ch?ci? porozmawiam z osob? zajmuj?c? si? dzia?aniami zwi?zanymi ze sprzeda??.

Pomagamy skutecznie pozyskiwa? nowych klient?w.

Zapraszam do kontaktu.


Pozdrawiam
Maciej Przybylski


From arnd at arndb.de  Fri Feb 23 01:25:49 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 23 Feb 2024 10:25:49 +0100
Subject: arch/arm64/include/asm/atomic_ll_sc.h:298:9: error: unknown type name
 'u128'
In-Reply-To: <CA+G9fYtrXXm_KO9fNPz3XaRxHV7UD_yQp-TEuPQrNRHU+_0W_Q@mail.gmail.com>
References: <CA+G9fYtrXXm_KO9fNPz3XaRxHV7UD_yQp-TEuPQrNRHU+_0W_Q@mail.gmail.com>
Message-ID: <0fe0add2-6b17-441f-a0e1-7c1ee9b0ea71@app.fastmail.com>

On Fri, Feb 23, 2024, at 10:10, Naresh Kamboju wrote:
> In file included from arch/arm64/include/asm/lse.h:5,
>                  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:68,
>                  from arch/arm64/include/asm/memory.h:209,
>                  from arch/arm64/include/asm/page.h:46,
>                  from include/vdso/datapage.h:22,
>                  from lib/vdso/gettimeofday.c:5,
>
>                  from <command-line>:
> arch/arm64/include/asm/atomic_ll_sc.h:298:9: error: unknown type name 'u128'
>   298 |         u128 full;
>       |         ^~~~
> arch/arm64/include/asm/atomic_ll_sc.h:305:24: error: unknown type name 'u128'
>   305 | static __always_inline u128

The problem here is the separation of vdso/*.h headers and
linux/*.h headers.

Commit a0d2fcd62ac2 ("vdso/ARM: Make union vdso_data_store
available for all architectures") introduced a reference to
the asm/page.h in include/vdso/datapage.h, but this is outside
of the vdso/*.h namespace and doesn't work in the compat vdso.

I think it is only needed because of the PAGE_SIZE macro,
so that constant needs to come from somewhere else.

I have an older patch that I never merged to unify the
page size configuration in Kconfig, and could try to
dig that out if nobody has a better idea. If we do that,
we could introduce a CONFIG_PAGE_SIZE.

    Arnd


From Balakrishnan.S at microchip.com  Fri Feb 23 01:27:26 2024
From: Balakrishnan.S at microchip.com (Balakrishnan.S at microchip.com)
Date: Fri, 23 Feb 2024 09:27:26 +0000
Subject: [PATCH] dt-bindings: sound:atmel-at91sam9g20ek: convert bindings
 to json-schema
In-Reply-To: <20240214135824.GA692740-robh@kernel.org>
References: <20240214-at91sam9g20ek-wm8731-yaml-v1-1-33333e17383b@microchip.com>
 <20240214135824.GA692740-robh@kernel.org>
Message-ID: <62a9f501-64de-47f6-9d0f-f1b48df6e5e6@microchip.com>

Hi Rob,

On 14/02/24 7:28 pm, Rob Herring wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Wed, Feb 14, 2024 at 12:10:06PM +0530, Balakrishnan Sambath wrote:
>> Convert atmel-at91sam9g20ek-wm8731-audio DT binding to yaml
>> based json-schema.Change file name to match json-scheme naming.
>>
>> Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>
>> ---
>>   .../bindings/sound/atmel,at91sam9g20ek-wm8731.yaml | 60 ++++++++++++++++++++++
>>   .../sound/atmel-at91sam9g20ek-wm8731-audio.txt     | 26 ----------
>>   2 files changed, 60 insertions(+), 26 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml b/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml
>> new file mode 100644
>> index 000000000000..f6330707fe1b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml
>> @@ -0,0 +1,60 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/sound/atmel,at91sam9g20ek-wm8731.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Atmel at91sam9g20ek wm8731 audio complex
>> +
>> +maintainers:
>> +  - Balakrishnan Sambath <balakrishnan.s at microchip.com>
>> +
>> +properties:
>> +  compatible:
>> +    const: atmel,at91sam9g20ek-wm8731-audio
>> +
>> +  atmel,model:
>> +    $ref: /schemas/types.yaml#/definitions/string
>> +    description: The user-visible name of this sound complex.
> 
> blank line between DT properties
> 
sure, thanks for pointing it out. I'll fix this in v2
>> +  atmel,audio-routing:
>> +    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
>> +    description: A list of the connections between audio components.
>> +    minItems: 2
> 
> No max?
> 

Here, there's no explicit constraint on the maximum number of items, so 
I only enforced minItems. Please let me know if I'm doing something wrong.

>> +    items:
>> +      enum:
>> +        # Board Connectors
>> +        - "Ext Spk"
>> +        - "Int MIC"
>> +
>> +        # CODEC Pins
>> +        - LHPOUT
>> +        - MICIN
>> +  atmel,ssc-controller:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description: The phandle of the SSC controller
>> +  atmel,audio-codec:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description: The phandle of WM8731 audio codec
>> +
>> +required:
>> +  - compatible
>> +  - atmel,model
>> +  - atmel,audio-routing
>> +  - atmel,ssc-controller
>> +  - atmel,audio-codec
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    sound {
>> +        compatible = "atmel,at91sam9g20ek-wm8731-audio";
>> +        pinctrl-names = "default";
>> +        pinctrl-0 = <&pinctrl_pck0_as_mck>;
>> +        atmel,model = "wm8731 @ AT91SAMG20EK";
>> +        atmel,audio-routing =
>> +            "Ext Spk", "LHPOUT",
>> +            "Int MIC", "MICIN";
>> +        atmel,ssc-controller = <&ssc0>;
>> +        atmel,audio-codec = <&wm8731>;
>> +    };

-- 
Best regards,
Balakrishnan S


From pekka.paalanen at collabora.com  Fri Feb 23 01:28:37 2024
From: pekka.paalanen at collabora.com (Pekka Paalanen)
Date: Fri, 23 Feb 2024 11:28:37 +0200
Subject: [PATCH v7 21/36] drm/connector: hdmi: Add Broadcast RGB
 property
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-21-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
	<20240222-kms-hdmi-connector-state-v7-21-8f4af575fce2@kernel.org>
Message-ID: <20240223112837.7c0394d7.pekka.paalanen@collabora.com>

On Thu, 22 Feb 2024 19:14:07 +0100
Maxime Ripard <mripard at kernel.org> wrote:

> The i915 driver has a property to force the RGB range of an HDMI output.
> The vc4 driver then implemented the same property with the same
> semantics. KWin has support for it, and a PR for mutter is also there to
> support it.
> 
> Both drivers implementing the same property with the same semantics,
> plus the userspace having support for it, is proof enough that it's
> pretty much a de-facto standard now and we can provide helpers for it.
> 
> Let's plumb it into the newly created HDMI connector.
> 
> Reviewed-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> Signed-off-by: Maxime Ripard <mripard at kernel.org>
> ---
>  Documentation/gpu/kms-properties.csv      |  1 -
>  drivers/gpu/drm/drm_atomic.c              |  2 +
>  drivers/gpu/drm/drm_atomic_state_helper.c |  4 +-
>  drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
>  drivers/gpu/drm/drm_connector.c           | 89 +++++++++++++++++++++++++++++++
>  include/drm/drm_connector.h               | 36 +++++++++++++
>  6 files changed, 134 insertions(+), 2 deletions(-)

...

> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 591d2d500f61..6ffe59d01698 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1212,6 +1212,29 @@ static const u32 dp_colorspaces =
>  	BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) |
>  	BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);
>  
> +static const struct drm_prop_enum_list broadcast_rgb_names[] = {
> +	{ DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic" },
> +	{ DRM_HDMI_BROADCAST_RGB_FULL, "Full" },
> +	{ DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" },
> +};
> +
> +/*
> + * drm_hdmi_connector_get_broadcast_rgb_name - Return a string for HDMI connector RGB broadcast selection
> + * @broadcast_rgb: Broadcast RGB selection to compute name of
> + *
> + * Returns: the name of the Broadcast RGB selection, or NULL if the type
> + * is not valid.
> + */
> +const char *
> +drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb)
> +{
> +	if (broadcast_rgb > DRM_HDMI_BROADCAST_RGB_LIMITED)
> +		return NULL;
> +
> +	return broadcast_rgb_names[broadcast_rgb].name;
> +}
> +EXPORT_SYMBOL(drm_hdmi_connector_get_broadcast_rgb_name);
> +
>  static const char * const output_format_str[] = {
>  	[HDMI_COLORSPACE_RGB]		= "RGB",
>  	[HDMI_COLORSPACE_YUV420]	= "YUV 4:2:0",
> @@ -1708,6 +1731,39 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
>  /**
>   * DOC: HDMI connector properties
>   *
> + * Broadcast RGB (HDMI specific)
> + *      Indicates the Quantization Range (Full vs Limited) used. The color
> + *      processing pipeline will be adjusted to match the value of the
> + *      property, and the Infoframes will be generated and sent accordingly.
> + *
> + *      This property is only relevant if the HDMI output format is RGB. If
> + *      it's one of the YCbCr variant, it will be ignored and the output will
> + *      use a limited quantization range.
> + *
> + *      The CRTC attached to the connector must be configured by user-space to
> + *      always produce full-range pixels.
> + *
> + *      The value of this property can be one of the following:
> + *
> + *      Automatic:
> + *              The quantization range is selected automatically based on the
> + *              mode according to the HDMI specifications (HDMI 1.4b - Section
> + *              6.6 - Video Quantization Ranges).
> + *
> + *      Full:
> + *              Full quantization range is forced.
> + *
> + *      Limited 16:235:
> + *              Limited quantization range is forced. Unlike the name suggests,
> + *              this works for any number of bits-per-component.
> + *
> + *      Property values other than Automatic can result in colors being off (if
> + *      limited is selected but the display expects full), or a black screen
> + *      (if full is selected but the display expects limited).
> + *
> + *      Drivers can set up this property by calling
> + *      drm_connector_attach_broadcast_rgb_property().
> + *
>   * content type (HDMI specific):
>   *	Indicates content type setting to be used in HDMI infoframes to indicate
>   *	content type for the external device, so that it adjusts its display

This piece of doc looks good to me, so

Acked-by: Pekka Paalanen <pekka.paalanen at collabora.com>


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240223/b142a61b/attachment.sig>

From bhargav.r at ltts.com  Fri Feb 23 01:36:47 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:47 +0530
Subject: [PATCH v2 00/14]  Add support for TI TPS65224 PMIC
Message-ID: <20240223093701.66034-1-bhargav.r@ltts.com>

This series modifies the existing TPS6594 drivers to add support for the
TPS65224 PMIC device that is a derivative of TPS6594. TPS65224 has a
similar register map to TPS6594 with a few differences. SPI, I2C, ESM,
PFSM, Regulators and GPIO features overlap between the two devices.

TPS65224 is a Power Management IC (PMIC) which provides regulators and
other features like GPIOs, Watchdog, Error Signal Monitor (ESM) and
Pre-configurable Finite State Machine (PFSM). The SoC and the PMIC can
communicate through the I2C or SPI interfaces. The PMIC TPS65224
additionally has a 12-bit ADC.
Data Sheet for TPS65224: https://www.ti.com/product/TPS65224-Q1

Driver re-use is applied following the advice of the following series:
https://lore.kernel.org/lkml/2f467b0a-1d11-4ec7-8ca6-6c4ba66e5887 at baylibre.com/

The features implemented in this series are:
- TPS65224 Register definitions
- Core (MFD I2C and SPI entry points)
- PFSM	
- ESM
- Regulators
- Pinctrl

TPS65224 Register definitions:
This patch adds macros for register field definitions of TPS65224
to the existing TPS6594 driver.  

Core description:
I2C and SPI interface protocols are implemented, with and without
the bit-integrity error detection feature (CRC mode).

PFSM description:
Strictly speaking, PFSM is not hardware. It is a piece of code.
PMIC integrates a state machine which manages operational modes.
Depending on the current operational mode, some voltage domains
remain energized while others can be off.
PFSM driver can be used to trigger transitions between configured
states.

ESM description:
This device monitors the SoC error output signal at its nERR_MCU
input pin. On error detection, ESM driver toggles the PMIC nRSTOUT pin
to reset the SoC.

Regulators description:
4 BUCKs and 3 LDOs.
BUCK12 can be used in dual-phase mode.

Pinctrl description:
TPS65224 family has 6 GPIOs. Those GPIOs can also serve different
functions such as I2C or SPI interface or watchdog disable functions.
The driver provides both pinmuxing for the functions and GPIO capability.

This series was tested on linux-next tag: next-20240118

Test logs can be found here:
https://gist.github.com/LeonardMH/58ec135921fb1062ffd4a8b384831eb0

Changelog v1 -> v2:
- Changes to patch sign-off
- Commit message change in dt-bindings patch
- regmap config included in the of_match_table data field

Bhargav Raviprakash (11):
  mfd: tps6594: use volatile_table instead of volatile_reg
  mfd: tps6594: add regmap config in match data
  dt-bindings: mfd: ti,tps6594: Add TI TPS65224 PMIC
  mfd: tps6594-i2c: Add TI TPS65224 PMIC I2C
  mfd: tps6594-spi: Add TI TPS65224 PMIC SPI
  mfd: tps6594-core: Add TI TPS65224 PMIC core
  misc: tps6594-pfsm: Add TI TPS65224 PMIC PFSM
  misc: tps6594-esm: reversion check limited to TPS6594 family
  misc: tps6594-esm: use regmap_field
  misc: tps6594-esm: Add TI TPS65224 PMIC ESM
  arch: arm64: dts: ti: k3-am62p5-sk: Add TPS65224 PMIC support in AM62P
    dts

Nirmala Devi Mal Nadar (3):
  mfd: tps6594: Add register definitions for TI TPS65224 PMIC
  regulator: tps6594-regulator: Add TI TPS65224 PMIC regulators
  pinctrl: pinctrl-tps6594: Add TPS65224 PMIC pinctrl and GPIO

 .../devicetree/bindings/mfd/ti,tps6594.yaml   |   1 +
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts       |  95 +++++
 drivers/mfd/tps6594-core.c                    | 266 +++++++++++--
 drivers/mfd/tps6594-i2c.c                     |  41 +-
 drivers/mfd/tps6594-spi.c                     |  41 +-
 drivers/misc/tps6594-esm.c                    |  89 +++--
 drivers/misc/tps6594-pfsm.c                   |  55 ++-
 drivers/pinctrl/pinctrl-tps6594.c             | 287 ++++++++++++--
 drivers/regulator/Kconfig                     |   4 +-
 drivers/regulator/tps6594-regulator.c         | 244 ++++++++++--
 include/linux/mfd/tps6594.h                   | 369 +++++++++++++++++-
 11 files changed, 1325 insertions(+), 167 deletions(-)


base-commit: 2863b714f3ad0a9686f2de1b779228ad8c7a8052
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:48 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:48 +0530
Subject: [PATCH v2 01/14] mfd: tps6594: Add register definitions for TI TPS65224 PMIC
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-2-bhargav.r@ltts.com>

From: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>

Extend TPS6594 PMIC register and field definitions to support TPS65224
power management IC.

TPS65224 is software compatible to TPS6594 and can re-use many of the
same definitions, new definitions are added to support additional
controls available on TPS65224.

Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 include/linux/mfd/tps6594.h | 354 ++++++++++++++++++++++++++++++++++--
 1 file changed, 342 insertions(+), 12 deletions(-)

diff --git a/include/linux/mfd/tps6594.h b/include/linux/mfd/tps6594.h
index 3f7c5e23c..1d8969594 100644
--- a/include/linux/mfd/tps6594.h
+++ b/include/linux/mfd/tps6594.h
@@ -18,12 +18,13 @@ enum pmic_id {
 	TPS6594,
 	TPS6593,
 	LP8764,
+	TPS65224,
 };
 
 /* Macro to get page index from register address */
 #define TPS6594_REG_TO_PAGE(reg)	((reg) >> 8)
 
-/* Registers for page 0 of TPS6594 */
+/* Registers for page 0 */
 #define TPS6594_REG_DEV_REV				0x01
 
 #define TPS6594_REG_NVM_CODE_1				0x02
@@ -56,9 +57,6 @@ enum pmic_id {
 #define TPS6594_REG_GPIOX_OUT(gpio_inst)		(TPS6594_REG_GPIO_OUT_1 + (gpio_inst) / 8)
 #define TPS6594_REG_GPIOX_IN(gpio_inst)			(TPS6594_REG_GPIO_IN_1 + (gpio_inst) / 8)
 
-#define TPS6594_REG_GPIO_IN_1				0x3f
-#define TPS6594_REG_GPIO_IN_2				0x40
-
 #define TPS6594_REG_RAIL_SEL_1				0x41
 #define TPS6594_REG_RAIL_SEL_2				0x42
 #define TPS6594_REG_RAIL_SEL_3				0x43
@@ -70,13 +68,15 @@ enum pmic_id {
 #define TPS6594_REG_FSM_TRIG_MASK_3			0x48
 
 #define TPS6594_REG_MASK_BUCK1_2			0x49
+#define TPS65224_REG_MASK_BUCKS				0x49
 #define TPS6594_REG_MASK_BUCK3_4			0x4a
 #define TPS6594_REG_MASK_BUCK5				0x4b
 #define TPS6594_REG_MASK_LDO1_2				0x4c
+#define TPS65224_REG_MASK_LDOS				0x4c
 #define TPS6594_REG_MASK_LDO3_4				0x4d
 #define TPS6594_REG_MASK_VMON				0x4e
-#define TPS6594_REG_MASK_GPIO1_8_FALL			0x4f
-#define TPS6594_REG_MASK_GPIO1_8_RISE			0x50
+#define TPS6594_REG_MASK_GPIO_FALL			0x4f
+#define TPS6594_REG_MASK_GPIO_RISE			0x50
 #define TPS6594_REG_MASK_GPIO9_11			0x51
 #define TPS6594_REG_MASK_STARTUP			0x52
 #define TPS6594_REG_MASK_MISC				0x53
@@ -174,6 +174,10 @@ enum pmic_id {
 
 #define TPS6594_REG_REGISTER_LOCK			0xa1
 
+#define TPS65224_REG_SRAM_ACCESS_1			0xa2
+#define TPS65224_REG_SRAM_ACCESS_2			0xa3
+#define TPS65224_REG_SRAM_ADDR_CTRL			0xa4
+#define TPS65224_REG_RECOV_CNT_PFSM_INCR		0xa5
 #define TPS6594_REG_MANUFACTURING_VER			0xa6
 
 #define TPS6594_REG_CUSTOMER_NVM_ID_REG			0xa7
@@ -182,6 +186,9 @@ enum pmic_id {
 
 #define TPS6594_REG_SOFT_REBOOT_REG			0xab
 
+#define TPS65224_REG_ADC_CTRL				0xac
+#define TPS65224_REG_ADC_RESULT_REG_1			0xad
+#define TPS65224_REG_ADC_RESULT_REG_2			0xae
 #define TPS6594_REG_RTC_SECONDS				0xb5
 #define TPS6594_REG_RTC_MINUTES				0xb6
 #define TPS6594_REG_RTC_HOURS				0xb7
@@ -199,6 +206,7 @@ enum pmic_id {
 
 #define TPS6594_REG_RTC_CTRL_1				0xc2
 #define TPS6594_REG_RTC_CTRL_2				0xc3
+#define TPS65224_REG_STARTUP_CTRL			0xc3
 #define TPS6594_REG_RTC_STATUS				0xc4
 #define TPS6594_REG_RTC_INTERRUPTS			0xc5
 #define TPS6594_REG_RTC_COMP_LSB			0xc6
@@ -214,13 +222,17 @@ enum pmic_id {
 #define TPS6594_REG_PFSM_DELAY_REG_2			0xce
 #define TPS6594_REG_PFSM_DELAY_REG_3			0xcf
 #define TPS6594_REG_PFSM_DELAY_REG_4			0xd0
+#define TPS65224_REG_ADC_GAIN_COMP_REG			0xd0
+#define TPS65224_REG_CRC_CALC_CONTROL			0xef
+#define TPS65224_REG_REGMAP_USER_CRC_LOW		0xf0
+#define TPS65224_REG_REGMAP_USER_CRC_HIGH		0xf1
 
-/* Registers for page 1 of TPS6594 */
+/* Registers for page 1 */
 #define TPS6594_REG_SERIAL_IF_CONFIG			0x11a
 #define TPS6594_REG_I2C1_ID				0x122
 #define TPS6594_REG_I2C2_ID				0x123
 
-/* Registers for page 4 of TPS6594 */
+/* Registers for page 4 */
 #define TPS6594_REG_WD_ANSWER_REG			0x401
 #define TPS6594_REG_WD_QUESTION_ANSW_CNT		0x402
 #define TPS6594_REG_WD_WIN1_CFG				0x403
@@ -241,16 +253,26 @@ enum pmic_id {
 #define TPS6594_BIT_BUCK_PLDN				BIT(5)
 #define TPS6594_BIT_BUCK_RV_SEL				BIT(7)
 
-/* BUCKX_CONF register field definition */
+/* TPS6594 BUCKX_CONF register field definition */
 #define TPS6594_MASK_BUCK_SLEW_RATE			GENMASK(2, 0)
 #define TPS6594_MASK_BUCK_ILIM				GENMASK(5, 3)
 
-/* BUCKX_PG_WINDOW register field definition */
+/* TPS65224 BUCKX_CONF register field definition */
+#define TPS65224_MASK_BUCK_SLEW_RATE			GENMASK(1, 0)
+
+/* TPS6594 BUCKX_PG_WINDOW register field definition */
 #define TPS6594_MASK_BUCK_OV_THR			GENMASK(2, 0)
 #define TPS6594_MASK_BUCK_UV_THR			GENMASK(5, 3)
 
-/* BUCKX VSET */
-#define TPS6594_MASK_BUCKS_VSET GENMASK(7, 0)
+/* TPS65224 BUCKX_PG_WINDOW register field definition */
+#define TPS65224_MASK_BUCK_VMON_THR			GENMASK(1, 0)
+
+/* TPS6594 BUCKX_VOUT register field definition */
+#define TPS6594_MASK_BUCKS_VSET				GENMASK(7, 0)
+
+/* TPS65224 BUCKX_VOUT register field definition */
+#define TPS65224_MASK_BUCK1_VSET			GENMASK(7, 0)
+#define TPS65224_MASK_BUCKS_VSET			GENMASK(6, 0)
 
 /* LDOX_CTRL register field definition */
 #define TPS6594_BIT_LDO_EN				BIT(0)
@@ -258,6 +280,7 @@ enum pmic_id {
 #define TPS6594_BIT_LDO_VMON_EN				BIT(4)
 #define TPS6594_MASK_LDO_PLDN				GENMASK(6, 5)
 #define TPS6594_BIT_LDO_RV_SEL				BIT(7)
+#define TPS65224_BIT_LDO_DISCHARGE_EN			BIT(5)
 
 /* LDORTC_CTRL register field definition */
 #define TPS6594_BIT_LDORTC_DIS				BIT(0)
@@ -271,6 +294,9 @@ enum pmic_id {
 #define TPS6594_MASK_LDO_OV_THR				GENMASK(2, 0)
 #define TPS6594_MASK_LDO_UV_THR				GENMASK(5, 3)
 
+/* LDOX_PG_WINDOW register field definition */
+#define TPS65224_MASK_LDO_VMON_THR			GENMASK(1, 0)
+
 /* VCCA_VMON_CTRL register field definition */
 #define TPS6594_BIT_VMON_EN				BIT(0)
 #define TPS6594_BIT_VMON1_EN				BIT(1)
@@ -278,10 +304,12 @@ enum pmic_id {
 #define TPS6594_BIT_VMON2_EN				BIT(3)
 #define TPS6594_BIT_VMON2_RV_SEL			BIT(4)
 #define TPS6594_BIT_VMON_DEGLITCH_SEL			BIT(5)
+#define TPS65224_BIT_VMON_DEGLITCH_SEL			GENMASK(7, 5)
 
 /* VCCA_PG_WINDOW register field definition */
 #define TPS6594_MASK_VCCA_OV_THR			GENMASK(2, 0)
 #define TPS6594_MASK_VCCA_UV_THR			GENMASK(5, 3)
+#define TPS65224_MASK_VCCA_VMON_THR			GENMASK(1, 0)
 #define TPS6594_BIT_VCCA_PG_SET				BIT(6)
 
 /* VMONX_PG_WINDOW register field definition */
@@ -289,6 +317,9 @@ enum pmic_id {
 #define TPS6594_MASK_VMONX_UV_THR			GENMASK(5, 3)
 #define TPS6594_BIT_VMONX_RANGE				BIT(6)
 
+/* VMONX_PG_WINDOW register field definition */
+#define TPS65224_MASK_VMONX_THR				GENMASK(1, 0)
+
 /* GPIOX_CONF register field definition */
 #define TPS6594_BIT_GPIO_DIR				BIT(0)
 #define TPS6594_BIT_GPIO_OD				BIT(1)
@@ -296,6 +327,8 @@ enum pmic_id {
 #define TPS6594_BIT_GPIO_PU_PD_EN			BIT(3)
 #define TPS6594_BIT_GPIO_DEGLITCH_EN			BIT(4)
 #define TPS6594_MASK_GPIO_SEL				GENMASK(7, 5)
+#define TPS65224_MASK_GPIO_SEL				GENMASK(6, 5)
+#define TPS65224_MASK_GPIO_SEL_GPIO6			GENMASK(7, 5)
 
 /* NPWRON_CONF register field definition */
 #define TPS6594_BIT_NRSTOUT_OD				BIT(0)
@@ -305,6 +338,12 @@ enum pmic_id {
 #define TPS6594_BIT_ENABLE_POL				BIT(5)
 #define TPS6594_MASK_NPWRON_SEL				GENMASK(7, 6)
 
+/* POWER_ON_CONFIG register field definition */
+#define TPS65224_BIT_NINT_ENDRV_PU_SEL			BIT(0)
+#define TPS65224_BIT_NINT_ENDRV_SEL			BIT(1)
+#define TPS65224_BIT_EN_PB_DEGL				BIT(5)
+#define TPS65224_MASK_EN_PB_VSENSE_CONFIG		GENMASK(7, 6)
+
 /* GPIO_OUT_X register field definition */
 #define TPS6594_BIT_GPIOX_OUT(gpio_inst)		BIT((gpio_inst) % 8)
 
@@ -312,6 +351,12 @@ enum pmic_id {
 #define TPS6594_BIT_GPIOX_IN(gpio_inst)			BIT((gpio_inst) % 8)
 #define TPS6594_BIT_NPWRON_IN				BIT(3)
 
+/* GPIO_OUT_X register field definition */
+#define TPS65224_BIT_GPIOX_OUT(gpio_inst)		BIT((gpio_inst))
+
+/* GPIO_IN_X register field definition */
+#define TPS65224_BIT_GPIOX_IN(gpio_inst)		BIT((gpio_inst))
+
 /* RAIL_SEL_1 register field definition */
 #define TPS6594_MASK_BUCK1_GRP_SEL			GENMASK(1, 0)
 #define TPS6594_MASK_BUCK2_GRP_SEL			GENMASK(3, 2)
@@ -343,6 +388,9 @@ enum pmic_id {
 #define TPS6594_BIT_GPIOX_FSM_MASK(gpio_inst)		BIT(((gpio_inst) << 1) % 8)
 #define TPS6594_BIT_GPIOX_FSM_MASK_POL(gpio_inst)	BIT(((gpio_inst) << 1) % 8 + 1)
 
+#define TPS65224_BIT_GPIOX_FSM_MASK(gpio_inst)		BIT(((gpio_inst) << 1) % 6)
+#define TPS65224_BIT_GPIOX_FSM_MASK_POL(gpio_inst)	BIT(((gpio_inst) << 1) % 6 + 1)
+
 /* MASK_BUCKX register field definition */
 #define TPS6594_BIT_BUCKX_OV_MASK(buck_inst)		BIT(((buck_inst) << 2) % 8)
 #define TPS6594_BIT_BUCKX_UV_MASK(buck_inst)		BIT(((buck_inst) << 2) % 8 + 1)
@@ -361,22 +409,46 @@ enum pmic_id {
 #define TPS6594_BIT_VMON2_OV_MASK			BIT(5)
 #define TPS6594_BIT_VMON2_UV_MASK			BIT(6)
 
+/* MASK_BUCK Register field definition */
+#define TPS65224_BIT_BUCK1_UVOV_MASK			BIT(0)
+#define TPS65224_BIT_BUCK2_UVOV_MASK			BIT(1)
+#define TPS65224_BIT_BUCK3_UVOV_MASK			BIT(2)
+#define TPS65224_BIT_BUCK4_UVOV_MASK			BIT(4)
+
+/* MASK_LDO_VMON register field definition */
+#define TPS65224_BIT_LDO1_UVOV_MASK			BIT(0)
+#define TPS65224_BIT_LDO2_UVOV_MASK			BIT(1)
+#define TPS65224_BIT_LDO3_UVOV_MASK			BIT(2)
+#define TPS65224_BIT_VCCA_UVOV_MASK			BIT(4)
+#define TPS65224_BIT_VMON1_UVOV_MASK			BIT(5)
+#define TPS65224_BIT_VMON2_UVOV_MASK			BIT(6)
+
 /* MASK_GPIOX register field definition */
 #define TPS6594_BIT_GPIOX_FALL_MASK(gpio_inst)		BIT((gpio_inst) < 8 ? \
 							    (gpio_inst) : (gpio_inst) % 8)
 #define TPS6594_BIT_GPIOX_RISE_MASK(gpio_inst)		BIT((gpio_inst) < 8 ? \
 							    (gpio_inst) : (gpio_inst) % 8 + 3)
+/* MASK_GPIOX register field definition */
+#define TPS65224_BIT_GPIOX_FALL_MASK(gpio_inst)		BIT((gpio_inst))
+#define TPS65224_BIT_GPIOX_RISE_MASK(gpio_inst)		BIT((gpio_inst))
 
 /* MASK_STARTUP register field definition */
 #define TPS6594_BIT_NPWRON_START_MASK			BIT(0)
 #define TPS6594_BIT_ENABLE_MASK				BIT(1)
 #define TPS6594_BIT_FSD_MASK				BIT(4)
 #define TPS6594_BIT_SOFT_REBOOT_MASK			BIT(5)
+#define TPS65224_BIT_VSENSE_MASK			BIT(0)
+#define TPS65224_BIT_PB_SHORT_MASK			BIT(2)
 
 /* MASK_MISC register field definition */
 #define TPS6594_BIT_BIST_PASS_MASK			BIT(0)
 #define TPS6594_BIT_EXT_CLK_MASK			BIT(1)
+#define TPS65224_BIT_REG_UNLOCK_MASK			BIT(2)
 #define TPS6594_BIT_TWARN_MASK				BIT(3)
+#define TPS65224_BIT_PB_LONG_MASK			BIT(4)
+#define TPS65224_BIT_PB_FALL_MASK			BIT(5)
+#define TPS65224_BIT_PB_RISE_MASK			BIT(6)
+#define TPS65224_BIT_ADC_CONV_READY_MASK		BIT(7)
 
 /* MASK_MODERATE_ERR register field definition */
 #define TPS6594_BIT_BIST_FAIL_MASK			BIT(1)
@@ -391,6 +463,8 @@ enum pmic_id {
 #define TPS6594_BIT_ORD_SHUTDOWN_MASK			BIT(1)
 #define TPS6594_BIT_MCU_PWR_ERR_MASK			BIT(2)
 #define TPS6594_BIT_SOC_PWR_ERR_MASK			BIT(3)
+#define TPS65224_BIT_COMM_ERR_MASK			BIT(4)
+#define TPS65224_BIT_I2C2_ERR_MASK			BIT(5)
 
 /* MASK_COMM_ERR register field definition */
 #define TPS6594_BIT_COMM_FRM_ERR_MASK			BIT(0)
@@ -426,6 +500,12 @@ enum pmic_id {
 #define TPS6594_BIT_BUCK3_4_INT				BIT(1)
 #define TPS6594_BIT_BUCK5_INT				BIT(2)
 
+/* INT_BUCK register field definition */
+#define TPS65224_BIT_BUCK1_UVOV_INT			BIT(0)
+#define TPS65224_BIT_BUCK2_UVOV_INT			BIT(1)
+#define TPS65224_BIT_BUCK3_UVOV_INT			BIT(2)
+#define TPS65224_BIT_BUCK4_UVOV_INT			BIT(3)
+
 /* INT_BUCKX register field definition */
 #define TPS6594_BIT_BUCKX_OV_INT(buck_inst)		BIT(((buck_inst) << 2) % 8)
 #define TPS6594_BIT_BUCKX_UV_INT(buck_inst)		BIT(((buck_inst) << 2) % 8 + 1)
@@ -437,6 +517,14 @@ enum pmic_id {
 #define TPS6594_BIT_LDO3_4_INT				BIT(1)
 #define TPS6594_BIT_VCCA_INT				BIT(4)
 
+/* INT_LDO_VMON register field definition */
+#define TPS65224_BIT_LDO1_UVOV_INT			BIT(0)
+#define TPS65224_BIT_LDO2_UVOV_INT			BIT(1)
+#define TPS65224_BIT_LDO3_UVOV_INT			BIT(2)
+#define TPS65224_BIT_VCCA_UVOV_INT			BIT(4)
+#define TPS65224_BIT_VMON1_UVOV_INT			BIT(5)
+#define TPS65224_BIT_VMON2_UVOV_INT			BIT(6)
+
 /* INT_LDOX register field definition */
 #define TPS6594_BIT_LDOX_OV_INT(ldo_inst)		BIT(((ldo_inst) << 2) % 8)
 #define TPS6594_BIT_LDOX_UV_INT(ldo_inst)		BIT(((ldo_inst) << 2) % 8 + 1)
@@ -462,17 +550,32 @@ enum pmic_id {
 /* INT_GPIOX register field definition */
 #define TPS6594_BIT_GPIOX_INT(gpio_inst)		BIT(gpio_inst)
 
+/* INT_GPIO register field definition */
+#define TPS65224_BIT_GPIO1_INT				BIT(0)
+#define TPS65224_BIT_GPIO2_INT				BIT(1)
+#define TPS65224_BIT_GPIO3_INT				BIT(2)
+#define TPS65224_BIT_GPIO4_INT				BIT(3)
+#define TPS65224_BIT_GPIO5_INT				BIT(4)
+#define TPS65224_BIT_GPIO6_INT				BIT(5)
+
 /* INT_STARTUP register field definition */
 #define TPS6594_BIT_NPWRON_START_INT			BIT(0)
+#define TPS65224_BIT_VSENSE_INT				BIT(0)
 #define TPS6594_BIT_ENABLE_INT				BIT(1)
 #define TPS6594_BIT_RTC_INT				BIT(2)
+#define TPS65224_BIT_PB_SHORT_INT			BIT(2)
 #define TPS6594_BIT_FSD_INT				BIT(4)
 #define TPS6594_BIT_SOFT_REBOOT_INT			BIT(5)
 
 /* INT_MISC register field definition */
 #define TPS6594_BIT_BIST_PASS_INT			BIT(0)
 #define TPS6594_BIT_EXT_CLK_INT				BIT(1)
+#define TPS65224_BIT_REG_UNLOCK_INT			BIT(2)
 #define TPS6594_BIT_TWARN_INT				BIT(3)
+#define TPS65224_BIT_PB_LONG_INT			BIT(4)
+#define TPS65224_BIT_PB_FALL_INT			BIT(5)
+#define TPS65224_BIT_PB_RISE_INT			BIT(6)
+#define TPS65224_BIT_ADC_CONV_READY_INT			BIT(7)
 
 /* INT_MODERATE_ERR register field definition */
 #define TPS6594_BIT_TSD_ORD_INT				BIT(0)
@@ -488,6 +591,7 @@ enum pmic_id {
 #define TPS6594_BIT_TSD_IMM_INT				BIT(0)
 #define TPS6594_BIT_VCCA_OVP_INT			BIT(1)
 #define TPS6594_BIT_PFSM_ERR_INT			BIT(2)
+#define TPS65224_BIT_BG_XMON_INT			BIT(3)
 
 /* INT_FSM_ERR register field definition */
 #define TPS6594_BIT_IMM_SHUTDOWN_INT			BIT(0)
@@ -496,6 +600,7 @@ enum pmic_id {
 #define TPS6594_BIT_SOC_PWR_ERR_INT			BIT(3)
 #define TPS6594_BIT_COMM_ERR_INT			BIT(4)
 #define TPS6594_BIT_READBACK_ERR_INT			BIT(5)
+#define TPS65224_BIT_I2C2_ERR_INT			BIT(5)
 #define TPS6594_BIT_ESM_INT				BIT(6)
 #define TPS6594_BIT_WD_INT				BIT(7)
 
@@ -536,8 +641,18 @@ enum pmic_id {
 #define TPS6594_BIT_VMON2_OV_STAT			BIT(5)
 #define TPS6594_BIT_VMON2_UV_STAT			BIT(6)
 
+/* STAT_LDO_VMON register field definition */
+#define TPS65224_BIT_LDO1_UVOV_STAT			BIT(0)
+#define TPS65224_BIT_LDO2_UVOV_STAT			BIT(1)
+#define TPS65224_BIT_LDO3_UVOV_STAT			BIT(2)
+#define TPS65224_BIT_VCCA_UVOV_STAT			BIT(4)
+#define TPS65224_BIT_VMON1_UVOV_STAT			BIT(5)
+#define TPS65224_BIT_VMON2_UVOV_STAT			BIT(6)
+
 /* STAT_STARTUP register field definition */
+#define TPS65224_BIT_VSENSE_STAT			BIT(0)
 #define TPS6594_BIT_ENABLE_STAT				BIT(1)
+#define TPS65224_BIT_PB_LEVEL_STAT			BIT(2)
 
 /* STAT_MISC register field definition */
 #define TPS6594_BIT_EXT_CLK_STAT			BIT(1)
@@ -549,6 +664,7 @@ enum pmic_id {
 /* STAT_SEVERE_ERR register field definition */
 #define TPS6594_BIT_TSD_IMM_STAT			BIT(0)
 #define TPS6594_BIT_VCCA_OVP_STAT			BIT(1)
+#define TPS65224_BIT_BG_XMON_STAT			BIT(3)
 
 /* STAT_READBACK_ERR register field definition */
 #define TPS6594_BIT_EN_DRV_READBACK_STAT		BIT(0)
@@ -597,6 +713,8 @@ enum pmic_id {
 #define TPS6594_BIT_BB_CHARGER_EN			BIT(0)
 #define TPS6594_BIT_BB_ICHR				BIT(1)
 #define TPS6594_MASK_BB_VEOC				GENMASK(3, 2)
+#define TPS65224_BIT_I2C1_SPI_CRC_EN			BIT(4)
+#define TPS65224_BIT_I2C2_CRC_EN			BIT(5)
 #define TPS6594_BB_EOC_RDY				BIT(7)
 
 /* ENABLE_DRV_REG register field definition */
@@ -617,6 +735,7 @@ enum pmic_id {
 #define TPS6594_BIT_NRSTOUT_SOC_IN			BIT(2)
 #define TPS6594_BIT_FORCE_EN_DRV_LOW			BIT(3)
 #define TPS6594_BIT_SPMI_LPM_EN				BIT(4)
+#define TPS65224_BIT_TSD_DISABLE			BIT(5)
 
 /* RECOV_CNT_REG_1 register field definition */
 #define TPS6594_MASK_RECOV_CNT				GENMASK(3, 0)
@@ -671,15 +790,27 @@ enum pmic_id {
 /* ESM_SOC_START_REG register field definition */
 #define TPS6594_BIT_ESM_SOC_START			BIT(0)
 
+/* ESM_MCU_START_REG register field definition */
+#define TPS65224_BIT_ESM_MCU_START			BIT(0)
+
 /* ESM_SOC_MODE_CFG register field definition */
 #define TPS6594_MASK_ESM_SOC_ERR_CNT_TH			GENMASK(3, 0)
 #define TPS6594_BIT_ESM_SOC_ENDRV			BIT(5)
 #define TPS6594_BIT_ESM_SOC_EN				BIT(6)
 #define TPS6594_BIT_ESM_SOC_MODE			BIT(7)
 
+/* ESM_MCU_MODE_CFG register field definition */
+#define TPS65224_MASK_ESM_MCU_ERR_CNT_TH		GENMASK(3, 0)
+#define TPS65224_BIT_ESM_MCU_ENDRV			BIT(5)
+#define TPS65224_BIT_ESM_MCU_EN				BIT(6)
+#define TPS65224_BIT_ESM_MCU_MODE			BIT(7)
+
 /* ESM_SOC_ERR_CNT_REG register field definition */
 #define TPS6594_MASK_ESM_SOC_ERR_CNT			GENMASK(4, 0)
 
+/* ESM_MCU_ERR_CNT_REG register field definition */
+#define TPS6594_MASK_ESM_MCU_ERR_CNT			GENMASK(4, 0)
+
 /* REGISTER_LOCK register field definition */
 #define TPS6594_BIT_REGISTER_LOCK_STATUS		BIT(0)
 
@@ -687,6 +818,29 @@ enum pmic_id {
 #define TPS6594_MASK_VMON1_SLEW_RATE			GENMASK(2, 0)
 #define TPS6594_MASK_VMON2_SLEW_RATE			GENMASK(5, 3)
 
+/* SRAM_ACCESS_1 Register field definition */
+#define TPS65224_MASk_SRAM_UNLOCK_SEQ			GENMASK(7, 0)
+
+/* SRAM_ACCESS_2 Register field definition */
+#define TPS65224_BIT_SRAM_WRITE_MODE			BIT(0)
+#define TPS65224_BIT_OTP_PROG_USER			BIT(1)
+#define TPS65224_BIT_OTP_PROG_PFSM			BIT(2)
+#define TPS65224_BIT_OTP_PROG_STATUS			BIT(3)
+#define TPS65224_BIT_SRAM_UNLOCKED			BIT(6)
+#define TPS65224_USER_PROG_ALLOWED			BIT(7)
+
+/* SRAM_ADDR_CTRL Register field definition */
+#define TPS65224_MASk_SRAM_SEL				GENMASK(1, 0)
+
+/* RECOV_CNT_PFSM_INCR Register field definition */
+#define TPS65224_BIT_INCREMENT_RECOV_CNT		BIT(0)
+
+/* MANUFACTURING_VER Register field definition */
+#define TPS65224_MASK_SILICON_REV			GENMASK(7, 0)
+
+/* CUSTOMER_NVM_ID_REG Register field definition */
+#define TPS65224_MASK_CUSTOMER_NVM_ID			GENMASK(7, 0)
+
 /* SOFT_REBOOT_REG register field definition */
 #define TPS6594_BIT_SOFT_REBOOT				BIT(0)
 
@@ -755,14 +909,83 @@ enum pmic_id {
 #define TPS6594_BIT_I2C2_CRC_EN				BIT(2)
 #define TPS6594_MASK_T_CRC				GENMASK(7, 3)
 
+/* ADC_CTRL Register field definition */
+#define TPS65224_BIT_ADC_START				BIT(0)
+#define TPS65224_BIT_ADC_CONT_CONV			BIT(1)
+#define TPS65224_BIT_ADC_THERMAL_SEL			BIT(2)
+#define TPS65224_BIT_ADC_RDIV_EN			BIT(3)
+#define TPS65224_BIT_ADC_STATUS				BIT(7)
+
+/* ADC_RESULT_REG_1 Register field definition */
+#define TPS65224_MASK_ADC_RESULT_11_4			GENMASK(7, 0)
+
+/* ADC_RESULT_REG_2 Register field definition */
+#define TPS65224_MASK_ADC_RESULT_3_0			GENMASK(7, 4)
+
+/* STARTUP_CTRL Register field definition */
+#define TPS65224_MASK_STARTUP_DEST			GENMASK(6, 5)
+#define TPS65224_BIT_FIRST_STARTUP_DONE			BIT(7)
+
+/* SCRATCH_PAD_REG_1 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_1			GENMASK(7, 0)
+
+/* SCRATCH_PAD_REG_2 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_2			GENMASK(7, 0)
+
+/* SCRATCH_PAD_REG_3 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_3			GENMASK(7, 0)
+
+/* SCRATCH_PAD_REG_4 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_4			GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_1 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY1			GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_2 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY2			GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_3 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY3			GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_4 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY4			GENMASK(7, 0)
+
+/* CRC_CALC_CONTROL Register field definition */
+#define TPS65224_BIT_RUN_CRC_BIST			BIT(0)
+#define TPS65224_BIT_RUN_CRC_UPDATE			BIT(1)
+
+/* ADC_GAIN_COMP_REG Register field definition */
+#define TPS65224_MASK_ADC_GAIN_COMP			GENMASK(7, 0)
+
+/* REGMAP_USER_CRC_LOW Register field definition */
+#define TPS65224_MASK_REGMAP_USER_CRC16_LOW		GENMASK(7, 0)
+
+/* REGMAP_USER_CRC_HIGH Register field definition */
+#define TPS65224_MASK_REGMAP_USER_CRC16_HIGH		GENMASK(7, 0)
+
+/* WD_ANSWER_REG Register field definition */
+#define TPS6594_MASK_WD_ANSWER				GENMASK(7, 0)
+
 /* WD_QUESTION_ANSW_CNT register field definition */
 #define TPS6594_MASK_WD_QUESTION			GENMASK(3, 0)
 #define TPS6594_MASK_WD_ANSW_CNT			GENMASK(5, 4)
+#define TPS65224_BIT_INT_TOP_STATUS			BIT(7)
+
+/* WD WIN1_CFG register field definition */
+#define TPS6594_MASK_WD_WIN1_CFG			GENMASK(6, 0)
+
+/* WD WIN2_CFG register field definition */
+#define TPS6594_MASK_WD_WIN2_CFG			GENMASK(6, 0)
+
+/* WD LongWin register field definition */
+#define TPS6594_MASK_WD_LONGWIN_CFG			GENMASK(7, 0)
 
 /* WD_MODE_REG register field definition */
 #define TPS6594_BIT_WD_RETURN_LONGWIN			BIT(0)
 #define TPS6594_BIT_WD_MODE_SELECT			BIT(1)
 #define TPS6594_BIT_WD_PWRHOLD				BIT(2)
+#define TPS65224_BIT_WD_ENDRV_SEL			BIT(6)
+#define TPS65224_BIT_WD_CNT_SEL				BIT(7)
 
 /* WD_QA_CFG register field definition */
 #define TPS6594_MASK_WD_QUESTION_SEED			GENMASK(3, 0)
@@ -993,6 +1216,113 @@ enum tps6594_irqs {
 #define TPS6594_IRQ_NAME_ALARM			"alarm"
 #define TPS6594_IRQ_NAME_POWERUP		"powerup"
 
+/* IRQs */
+enum tps65224_irqs {
+	/* INT_BUCK register */
+	TPS65224_IRQ_BUCK1_UVOV,
+	TPS65224_IRQ_BUCK2_UVOV,
+	TPS65224_IRQ_BUCK3_UVOV,
+	TPS65224_IRQ_BUCK4_UVOV,
+	/* INT_LDO_VMON register */
+	TPS65224_IRQ_LDO1_UVOV,
+	TPS65224_IRQ_LDO2_UVOV,
+	TPS65224_IRQ_LDO3_UVOV,
+	TPS65224_IRQ_VCCA_UVOV,
+	TPS65224_IRQ_VMON1_UVOV,
+	TPS65224_IRQ_VMON2_UVOV,
+	/* INT_GPIO register */
+	TPS65224_IRQ_GPIO1,
+	TPS65224_IRQ_GPIO2,
+	TPS65224_IRQ_GPIO3,
+	TPS65224_IRQ_GPIO4,
+	TPS65224_IRQ_GPIO5,
+	TPS65224_IRQ_GPIO6,
+	/* INT_STARTUP register */
+	TPS65224_IRQ_VSENSE,
+	TPS65224_IRQ_ENABLE,
+	TPS65224_IRQ_PB_SHORT,
+	TPS65224_IRQ_FSD,
+	TPS65224_IRQ_SOFT_REBOOT,
+	/* INT_MISC register */
+	TPS65224_IRQ_BIST_PASS,
+	TPS65224_IRQ_EXT_CLK,
+	TPS65224_IRQ_REG_UNLOCK,
+	TPS65224_IRQ_TWARN,
+	TPS65224_IRQ_PB_LONG,
+	TPS65224_IRQ_PB_FALL,
+	TPS65224_IRQ_PB_RISE,
+	TPS65224_IRQ_ADC_CONV_READY,
+	/* INT_MODERATE_ERR register */
+	TPS65224_IRQ_TSD_ORD,
+	TPS65224_IRQ_BIST_FAIL,
+	TPS65224_IRQ_REG_CRC_ERR,
+	TPS65224_IRQ_RECOV_CNT,
+	/* INT_SEVERE_ERR register */
+	TPS65224_IRQ_TSD_IMM,
+	TPS65224_IRQ_VCCA_OVP,
+	TPS65224_IRQ_PFSM_ERR,
+	TPS65224_IRQ_BG_XMON,
+	/* INT_FSM_ERR register */
+	TPS65224_IRQ_IMM_SHUTDOWN,
+	TPS65224_IRQ_ORD_SHUTDOWN,
+	TPS65224_IRQ_MCU_PWR_ERR,
+	TPS65224_IRQ_SOC_PWR_ERR,
+	TPS65224_IRQ_COMM_ERR,
+	TPS65224_IRQ_I2C2_ERR,
+	/* INT_ESM register */
+	TPS65224_IRQ_ESM_MCU_PIN,
+	TPS65224_IRQ_ESM_MCU_FAIL,
+	TPS65224_IRQ_ESM_MCU_RST,
+};
+
+#define TPS65224_IRQ_NAME_BUCK1_UVOV		"buck1_uvov"
+#define TPS65224_IRQ_NAME_BUCK2_UVOV		"buck2_uvov"
+#define TPS65224_IRQ_NAME_BUCK3_UVOV		"buck3_uvov"
+#define TPS65224_IRQ_NAME_BUCK4_UVOV		"buck4_uvov"
+#define TPS65224_IRQ_NAME_LDO1_UVOV		"ldo1_uvov"
+#define TPS65224_IRQ_NAME_LDO2_UVOV		"ldo2_uvov"
+#define TPS65224_IRQ_NAME_LDO3_UVOV		"ldo3_uvov"
+#define TPS65224_IRQ_NAME_VCCA_UVOV		"vcca_uvov"
+#define TPS65224_IRQ_NAME_VMON1_UVOV		"vmon1_uvov"
+#define TPS65224_IRQ_NAME_VMON2_UVOV		"vmon2_uvov"
+#define TPS65224_IRQ_NAME_GPIO1			"gpio1"
+#define TPS65224_IRQ_NAME_GPIO2			"gpio2"
+#define TPS65224_IRQ_NAME_GPIO3			"gpio3"
+#define TPS65224_IRQ_NAME_GPIO4			"gpio4"
+#define TPS65224_IRQ_NAME_GPIO5			"gpio5"
+#define TPS65224_IRQ_NAME_GPIO6			"gpio6"
+#define TPS65224_IRQ_NAME_VSENSE	        "vsense"
+#define TPS65224_IRQ_NAME_ENABLE		"enable"
+#define TPS65224_IRQ_NAME_PB_SHORT		"pb_short"
+#define TPS65224_IRQ_NAME_FSD			"fsd"
+#define TPS65224_IRQ_NAME_SOFT_REBOOT		"soft_reboot"
+#define TPS65224_IRQ_NAME_BIST_PASS		"bist_pass"
+#define TPS65224_IRQ_NAME_EXT_CLK		"ext_clk"
+#define TPS65224_IRQ_NAME_REG_UNLOCK		"reg_unlock"
+#define TPS65224_IRQ_NAME_TWARN			"twarn"
+#define TPS65224_IRQ_NAME_PB_LONG		"pb_long"
+#define TPS65224_IRQ_NAME_PB_FALL		"pb_fall"
+#define TPS65224_IRQ_NAME_PB_RISE		"pb_rise"
+#define TPS65224_IRQ_NAME_ADC_CONV_READY	"adc_conv_ready"
+#define TPS65224_IRQ_NAME_TSD_ORD		"tsd_ord"
+#define TPS65224_IRQ_NAME_BIST_FAIL		"bist_fail"
+#define TPS65224_IRQ_NAME_REG_CRC_ERR		"reg_crc_err"
+#define TPS65224_IRQ_NAME_RECOV_CNT		"recov_cnt"
+#define TPS65224_IRQ_NAME_TSD_IMM		"tsd_imm"
+#define TPS65224_IRQ_NAME_VCCA_OVP		"vcca_ovp"
+#define TPS65224_IRQ_NAME_PFSM_ERR		"pfsm_err"
+#define TPS65224_IRQ_NAME_BG_XMON		"bg_xmon"
+#define TPS65224_IRQ_NAME_IMM_SHUTDOWN		"imm_shutdown"
+#define TPS65224_IRQ_NAME_ORD_SHUTDOWN		"ord_shutdown"
+#define TPS65224_IRQ_NAME_MCU_PWR_ERR		"mcu_pwr_err"
+#define TPS65224_IRQ_NAME_SOC_PWR_ERR		"soc_pwr_err"
+#define TPS65224_IRQ_NAME_COMM_ERR		"comm_err"
+#define TPS65224_IRQ_NAME_I2C2_ERR		"i2c2_err"
+#define TPS65224_IRQ_NAME_ESM_MCU_PIN		"esm_mcu_pin"
+#define TPS65224_IRQ_NAME_ESM_MCU_FAIL		"esm_mcu_fail"
+#define TPS65224_IRQ_NAME_ESM_MCU_RST		"esm_mcu_rst"
+#define TPS65224_IRQ_NAME_POWERUP		"powerup"
+
 /**
  * struct tps6594 - device private data structure
  *
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:50 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:50 +0530
Subject: [PATCH v2 03/14] mfd: tps6594: add regmap config in match data
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-4-bhargav.r@ltts.com>

Introduces a new struct tps6594_match_data. This struct
holds fields for chip id and regmap config. Using this
struct in of_device_id data field.
This helps in adding support for TPS65224 PMIC.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/mfd/tps6594-i2c.c   | 24 ++++++++++++++++--------
 drivers/mfd/tps6594-spi.c   | 24 ++++++++++++++++--------
 include/linux/mfd/tps6594.h | 11 +++++++++++
 3 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/drivers/mfd/tps6594-i2c.c b/drivers/mfd/tps6594-i2c.c
index c125b474b..e80e0af2b 100644
--- a/drivers/mfd/tps6594-i2c.c
+++ b/drivers/mfd/tps6594-i2c.c
@@ -192,10 +192,16 @@ static const struct regmap_config tps6594_i2c_regmap_config = {
 	.write = tps6594_i2c_write,
 };
 
+static const struct tps6594_match_data match_data[] = {
+	[TPS6594] = {TPS6594, &tps6594_i2c_regmap_config},
+	[TPS6593] = {TPS6593, &tps6594_i2c_regmap_config},
+	[LP8764] = {LP8764, &tps6594_i2c_regmap_config},
+};
+
 static const struct of_device_id tps6594_i2c_of_match_table[] = {
-	{ .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
-	{ .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
-	{ .compatible = "ti,lp8764-q1",  .data = (void *)LP8764,  },
+	{ .compatible = "ti,tps6594-q1", .data = (void *)&match_data[TPS6594], },
+	{ .compatible = "ti,tps6593-q1", .data = (void *)&match_data[TPS6593], },
+	{ .compatible = "ti,lp8764-q1",  .data = (void *)&match_data[LP8764], },
 	{}
 };
 MODULE_DEVICE_TABLE(of, tps6594_i2c_of_match_table);
@@ -205,6 +211,7 @@ static int tps6594_i2c_probe(struct i2c_client *client)
 	struct device *dev = &client->dev;
 	struct tps6594 *tps;
 	const struct of_device_id *match;
+	const struct tps6594_match_data *mdata;
 
 	tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
 	if (!tps)
@@ -216,14 +223,15 @@ static int tps6594_i2c_probe(struct i2c_client *client)
 	tps->reg = client->addr;
 	tps->irq = client->irq;
 
-	tps->regmap = devm_regmap_init(dev, NULL, client, &tps6594_i2c_regmap_config);
-	if (IS_ERR(tps->regmap))
-		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
-
 	match = of_match_device(tps6594_i2c_of_match_table, dev);
 	if (!match)
 		return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n");
-	tps->chip_id = (unsigned long)match->data;
+	mdata = (struct tps6594_match_data *)match->data;
+	tps->chip_id = mdata->chip_id;
+
+	tps->regmap = devm_regmap_init(dev, NULL, client, mdata->config);
+	if (IS_ERR(tps->regmap))
+		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
 
 	crc8_populate_msb(tps6594_i2c_crc_table, TPS6594_CRC8_POLYNOMIAL);
 
diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
index 5afb1736f..b9428dc12 100644
--- a/drivers/mfd/tps6594-spi.c
+++ b/drivers/mfd/tps6594-spi.c
@@ -77,10 +77,16 @@ static const struct regmap_config tps6594_spi_regmap_config = {
 	.use_single_write = true,
 };
 
+static const struct tps6594_match_data match_data[] = {
+	[TPS6594] = {TPS6594, &tps6594_spi_regmap_config},
+	[TPS6593] = {TPS6593, &tps6594_spi_regmap_config},
+	[LP8764] = {LP8764, &tps6594_spi_regmap_config},
+};
+
 static const struct of_device_id tps6594_spi_of_match_table[] = {
-	{ .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
-	{ .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
-	{ .compatible = "ti,lp8764-q1",  .data = (void *)LP8764,  },
+	{ .compatible = "ti,tps6594-q1", .data = (void *)&match_data[TPS6594], },
+	{ .compatible = "ti,tps6593-q1", .data = (void *)&match_data[TPS6593], },
+	{ .compatible = "ti,lp8764-q1",  .data = (void *)&match_data[LP8764], },
 	{}
 };
 MODULE_DEVICE_TABLE(of, tps6594_spi_of_match_table);
@@ -90,6 +96,7 @@ static int tps6594_spi_probe(struct spi_device *spi)
 	struct device *dev = &spi->dev;
 	struct tps6594 *tps;
 	const struct of_device_id *match;
+	const struct tps6594_match_data *mdata;
 
 	tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
 	if (!tps)
@@ -101,14 +108,15 @@ static int tps6594_spi_probe(struct spi_device *spi)
 	tps->reg = spi_get_chipselect(spi, 0);
 	tps->irq = spi->irq;
 
-	tps->regmap = devm_regmap_init(dev, NULL, spi, &tps6594_spi_regmap_config);
-	if (IS_ERR(tps->regmap))
-		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
-
 	match = of_match_device(tps6594_spi_of_match_table, dev);
 	if (!match)
 		return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n");
-	tps->chip_id = (unsigned long)match->data;
+	mdata = (struct tps6594_match_data *)match->data;
+	tps->chip_id = mdata->chip_id;
+
+	tps->regmap = devm_regmap_init(dev, NULL, spi, mdata->config);
+	if (IS_ERR(tps->regmap))
+		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
 
 	crc8_populate_msb(tps6594_spi_crc_table, TPS6594_CRC8_POLYNOMIAL);
 
diff --git a/include/linux/mfd/tps6594.h b/include/linux/mfd/tps6594.h
index 6c5a2889f..615529591 100644
--- a/include/linux/mfd/tps6594.h
+++ b/include/linux/mfd/tps6594.h
@@ -1344,6 +1344,17 @@ struct tps6594 {
 	struct regmap_irq_chip_data *irq_data;
 };
 
+/**
+ * struct tps6594_match_data - of match data of PMIC
+ *
+ * @chip_id: chip ID of PMIC
+ * @config: regmap config of PMIC
+ */
+struct tps6594_match_data {
+	unsigned long chip_id;
+	const struct regmap_config *config;
+};
+
 extern const struct regmap_access_table tps6594_volatile_table;
 extern const struct regmap_access_table tps65224_volatile_table;
 
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:51 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:51 +0530
Subject: [PATCH v2 04/14] dt-bindings: mfd: ti,tps6594: Add TI TPS65224 PMIC
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-5-bhargav.r@ltts.com>

TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
regulators, it includes additional features like GPIOs, watchdog, ESMs
(Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
managing the state of the device.

In addition TPS65224 has support for 12-bit ADC and does not have RTC
unlike TPS6594.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 Documentation/devicetree/bindings/mfd/ti,tps6594.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
index 9d43376be..6341b6070 100644
--- a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
+++ b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
@@ -21,6 +21,7 @@ properties:
       - ti,lp8764-q1
       - ti,tps6593-q1
       - ti,tps6594-q1
+      - ti,tps65224-q1
 
   reg:
     description: I2C slave address or SPI chip select number.
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:55 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:55 +0530
Subject: [PATCH v2 08/14] misc: tps6594-pfsm: Add TI TPS65224 PMIC PFSM
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-9-bhargav.r@ltts.com>

Add support for TPS65224 PFSM in the TPS6594 PFSM driver
as they share significant functionality.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/misc/tps6594-pfsm.c | 55 +++++++++++++++++++++++++++----------
 1 file changed, 40 insertions(+), 15 deletions(-)

diff --git a/drivers/misc/tps6594-pfsm.c b/drivers/misc/tps6594-pfsm.c
index 88dcac814..4fa071093 100644
--- a/drivers/misc/tps6594-pfsm.c
+++ b/drivers/misc/tps6594-pfsm.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * PFSM (Pre-configurable Finite State Machine) driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * PFSM (Pre-configurable Finite State Machine) driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
@@ -34,15 +34,17 @@
 
 #define TPS6594_FILE_TO_PFSM(f) container_of((f)->private_data, struct tps6594_pfsm, miscdev)
 
-/**
+/*
  * struct tps6594_pfsm - device private data structure
  *
  * @miscdev: misc device infos
  * @regmap:  regmap for accessing the device registers
+ * @chip_id: chip identifier of the device
  */
 struct tps6594_pfsm {
 	struct miscdevice miscdev;
 	struct regmap *regmap;
+	unsigned long chip_id;
 };
 
 static ssize_t tps6594_pfsm_read(struct file *f, char __user *buf,
@@ -133,21 +135,29 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
 	struct tps6594_pfsm *pfsm = TPS6594_FILE_TO_PFSM(f);
 	struct pmic_state_opt state_opt;
 	void __user *argp = (void __user *)arg;
+	unsigned int regmap_reg, mask;
 	int ret = -ENOIOCTLCMD;
 
 	switch (cmd) {
 	case PMIC_GOTO_STANDBY:
-		/* Disable LP mode */
-		ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
-					TPS6594_BIT_LP_STANDBY_SEL);
-		if (ret)
-			return ret;
+		/* Disable LP mode on TPS6594 Family PMIC */
+		if (pfsm->chip_id != TPS65224) {
+			ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
+						TPS6594_BIT_LP_STANDBY_SEL);
+
+			if (ret)
+				return ret;
+		}
 
 		/* Force trigger */
 		ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_FSM_I2C_TRIGGERS,
 					TPS6594_BIT_TRIGGER_I2C(0), TPS6594_BIT_TRIGGER_I2C(0));
 		break;
 	case PMIC_GOTO_LP_STANDBY:
+		/* TPS65224 does not support LP STANDBY */
+		if (pfsm->chip_id == TPS65224)
+			return ret;
+
 		/* Enable LP mode */
 		ret = regmap_set_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
 				      TPS6594_BIT_LP_STANDBY_SEL);
@@ -169,6 +179,10 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
 				      TPS6594_BIT_NSLEEP1B | TPS6594_BIT_NSLEEP2B);
 		break;
 	case PMIC_SET_MCU_ONLY_STATE:
+		/* TPS65224 does not support MCU_ONLY_STATE */
+		if (pfsm->chip_id == TPS65224)
+			return ret;
+
 		if (copy_from_user(&state_opt, argp, sizeof(state_opt)))
 			return -EFAULT;
 
@@ -192,14 +206,20 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
 			return -EFAULT;
 
 		/* Configure wake-up destination */
+		if (pfsm->chip_id == TPS65224) {
+			regmap_reg = TPS65224_REG_STARTUP_CTRL;
+			mask = TPS65224_MASK_STARTUP_DEST;
+		} else {
+			regmap_reg = TPS6594_REG_RTC_CTRL_2;
+			mask = TPS6594_MASK_STARTUP_DEST;
+		}
+
 		if (state_opt.mcu_only_startup_dest)
-			ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
-						TPS6594_MASK_STARTUP_DEST,
-						TPS6594_STARTUP_DEST_MCU_ONLY);
+			ret = regmap_write_bits(pfsm->regmap, regmap_reg,
+						mask, TPS6594_STARTUP_DEST_MCU_ONLY);
 		else
-			ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
-						TPS6594_MASK_STARTUP_DEST,
-						TPS6594_STARTUP_DEST_ACTIVE);
+			ret = regmap_write_bits(pfsm->regmap, regmap_reg,
+						mask, TPS6594_STARTUP_DEST_ACTIVE);
 		if (ret)
 			return ret;
 
@@ -210,8 +230,12 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
 			return ret;
 
 		/* Modify NSLEEP1-2 bits */
-		ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
-					TPS6594_BIT_NSLEEP2B);
+		if (pfsm->chip_id == TPS65224)
+			ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
+						TPS6594_BIT_NSLEEP1B);
+		else
+			ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
+						TPS6594_BIT_NSLEEP2B);
 		break;
 	}
 
@@ -262,6 +286,7 @@ static int tps6594_pfsm_probe(struct platform_device *pdev)
 					    tps->chip_id, tps->reg);
 	pfsm->miscdev.fops = &tps6594_pfsm_fops;
 	pfsm->miscdev.parent = dev->parent;
+	pfsm->chip_id = tps->chip_id;
 
 	for (i = 0 ; i < pdev->num_resources ; i++) {
 		irq = platform_get_irq_byname(pdev, pdev->resource[i].name);
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:57 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:57 +0530
Subject: [PATCH v2 10/14] misc: tps6594-esm: use regmap_field
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-11-bhargav.r@ltts.com>

Use regmap_field and associated APIs to update the ESM_MODE_CFG and
ESM_START registers. This helps in adding support for TPS65224 PMIC.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/misc/tps6594-esm.c | 60 ++++++++++++++++++++++++++++----------
 1 file changed, 45 insertions(+), 15 deletions(-)

diff --git a/drivers/misc/tps6594-esm.c b/drivers/misc/tps6594-esm.c
index 8ec5af9dc..d0f86b0e9 100644
--- a/drivers/misc/tps6594-esm.c
+++ b/drivers/misc/tps6594-esm.c
@@ -15,6 +15,19 @@
 
 #define TPS6594_DEV_REV_1 0x08
 
+#define ESM_MODE_CFG_SET  0xff
+#define ESM_START_SET     0xff
+#define ESM_MODE_CFG_CLR  0x0
+#define ESM_START_CLR     0x0
+
+static struct reg_field tps6594_esm_mode_cfg  = REG_FIELD(TPS6594_REG_ESM_SOC_MODE_CFG,  5, 6);
+static struct reg_field tps6594_esm_start     = REG_FIELD(TPS6594_REG_ESM_SOC_START_REG, 0, 0);
+
+struct tps6594_esm {
+	struct regmap_field *esm_mode_cfg;
+	struct regmap_field *esm_start;
+};
+
 static irqreturn_t tps6594_esm_isr(int irq, void *dev_id)
 {
 	struct platform_device *pdev = dev_id;
@@ -34,6 +47,7 @@ static int tps6594_esm_probe(struct platform_device *pdev)
 {
 	struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
 	struct device *dev = &pdev->dev;
+	struct tps6594_esm *esm;
 	unsigned int rev;
 	int irq;
 	int ret;
@@ -69,13 +83,30 @@ static int tps6594_esm_probe(struct platform_device *pdev)
 			return dev_err_probe(dev, ret, "Failed to request irq\n");
 	}
 
-	ret = regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_MODE_CFG,
-			      TPS6594_BIT_ESM_SOC_EN | TPS6594_BIT_ESM_SOC_ENDRV);
+	esm = devm_kzalloc(dev, sizeof(struct tps6594_esm), GFP_KERNEL);
+	if (!esm)
+		return -ENOMEM;
+
+	esm->esm_mode_cfg = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_mode_cfg);
+	esm->esm_start = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_start);
+
+	if (IS_ERR(esm->esm_mode_cfg)) {
+		dev_err(dev, "esm_mode_cfg reg field init failed\n");
+		return PTR_ERR(esm->esm_mode_cfg);
+	}
+
+	if (IS_ERR(esm->esm_start)) {
+		dev_err(dev, "esm_start reg field init failed\n");
+		return PTR_ERR(esm->esm_start);
+	}
+
+	platform_set_drvdata(pdev, esm);
+
+	ret = regmap_field_write(esm->esm_mode_cfg, ESM_MODE_CFG_SET);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to configure ESM\n");
 
-	ret = regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG,
-			      TPS6594_BIT_ESM_SOC_START);
+	ret = regmap_field_write(esm->esm_start, ESM_START_SET);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to start ESM\n");
 
@@ -87,19 +118,17 @@ static int tps6594_esm_probe(struct platform_device *pdev)
 
 static void tps6594_esm_remove(struct platform_device *pdev)
 {
-	struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
 	struct device *dev = &pdev->dev;
+	struct tps6594_esm *esm = platform_get_drvdata(pdev);
 	int ret;
 
-	ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG,
-				TPS6594_BIT_ESM_SOC_START);
+	ret = regmap_field_write(esm->esm_start, ESM_START_CLR);
 	if (ret) {
 		dev_err(dev, "Failed to stop ESM\n");
 		goto out;
 	}
 
-	ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_MODE_CFG,
-				TPS6594_BIT_ESM_SOC_EN | TPS6594_BIT_ESM_SOC_ENDRV);
+	ret = regmap_field_write(esm->esm_mode_cfg, ESM_MODE_CFG_CLR);
 	if (ret)
 		dev_err(dev, "Failed to unconfigure ESM\n");
 
@@ -110,11 +139,12 @@ static void tps6594_esm_remove(struct platform_device *pdev)
 
 static int tps6594_esm_suspend(struct device *dev)
 {
-	struct tps6594 *tps = dev_get_drvdata(dev->parent);
+	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
+	struct tps6594_esm *esm = platform_get_drvdata(pdev);
+
 	int ret;
 
-	ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG,
-				TPS6594_BIT_ESM_SOC_START);
+	ret = regmap_field_write(esm->esm_start, ESM_START_CLR);
 
 	pm_runtime_put_sync(dev);
 
@@ -123,12 +153,12 @@ static int tps6594_esm_suspend(struct device *dev)
 
 static int tps6594_esm_resume(struct device *dev)
 {
-	struct tps6594 *tps = dev_get_drvdata(dev->parent);
+	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
+	struct tps6594_esm *esm = platform_get_drvdata(pdev);
 
 	pm_runtime_get_sync(dev);
 
-	return regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG,
-			       TPS6594_BIT_ESM_SOC_START);
+	return regmap_field_write(esm->esm_start, ESM_START_SET);
 }
 
 static DEFINE_SIMPLE_DEV_PM_OPS(tps6594_esm_pm_ops, tps6594_esm_suspend, tps6594_esm_resume);
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:59 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:59 +0530
Subject: [PATCH v2 12/14] regulator: tps6594-regulator: Add TI TPS65224 PMIC regulators
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-13-bhargav.r@ltts.com>

From: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>

Add support for TPS65224 regulators (bucks and LDOs) to TPS6594 driver
as they have significant functional overlap.
TPS65224 PMIC has 4 buck regulators and 3 LDOs. BUCK12 can operate in
dual phase.
The output voltages are configurable and are meant to supply power to
the main processor and other components.

Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/regulator/Kconfig             |   4 +-
 drivers/regulator/tps6594-regulator.c | 244 +++++++++++++++++++++++---
 2 files changed, 218 insertions(+), 30 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 7db0a29b5..1e4119f00 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1563,13 +1563,15 @@ config REGULATOR_TPS6594
 	depends on MFD_TPS6594 && OF
 	default MFD_TPS6594
 	help
-	  This driver supports TPS6594 voltage regulator chips.
+	  This driver supports TPS6594 series and TPS65224 voltage regulator chips.
 	  TPS6594 series of PMICs have 5 BUCKs and 4 LDOs
 	  voltage regulators.
 	  BUCKs 1,2,3,4 can be used in single phase or multiphase mode.
 	  Part number defines which single or multiphase mode is i used.
 	  It supports software based voltage control
 	  for different voltage domains.
+	  TPS65224 PMIC has 4 BUCKs and 3 LDOs. BUCK12 can be used in dual phase.
+	  All BUCKs and LDOs volatge can be controlled through software.
 
 config REGULATOR_TPS6524X
 	tristate "TI TPS6524X Power regulators"
diff --git a/drivers/regulator/tps6594-regulator.c b/drivers/regulator/tps6594-regulator.c
index b7f0c8779..3f32dba90 100644
--- a/drivers/regulator/tps6594-regulator.c
+++ b/drivers/regulator/tps6594-regulator.c
@@ -66,6 +66,15 @@ static struct tps6594_regulator_irq_type tps6594_ext_regulator_irq_types[] = {
 	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
 };
 
+static struct tps6594_regulator_irq_type tps65224_ext_regulator_irq_types[] = {
+	{ TPS65224_IRQ_NAME_VCCA_UVOV, "VCCA", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ TPS65224_IRQ_NAME_VMON1_UVOV, "VMON1", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+	{ TPS65224_IRQ_NAME_VMON2_UVOV, "VMON2", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
 struct tps6594_regulator_irq_data {
 	struct device *dev;
 	struct tps6594_regulator_irq_type *type;
@@ -122,6 +131,27 @@ static const struct linear_range ldos_4_ranges[] = {
 	REGULATOR_LINEAR_RANGE(1200000, 0x20, 0x74, 25000),
 };
 
+/* Voltage range for TPS65224 Bucks and LDOs */
+static const struct linear_range tps65224_bucks_1_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0x0a, 0x0e, 20000),
+	REGULATOR_LINEAR_RANGE(600000, 0x0f, 0x72, 5000),
+	REGULATOR_LINEAR_RANGE(1100000, 0x73, 0xaa, 10000),
+	REGULATOR_LINEAR_RANGE(1660000, 0xab, 0xfd, 20000),
+};
+
+static const struct linear_range tps65224_bucks_2_3_4_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0x0, 0x1a, 25000),
+	REGULATOR_LINEAR_RANGE(1200000, 0x1b, 0x45, 50000),
+};
+
+static const struct linear_range tps65224_ldos_1_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1200000, 0xC, 0x36, 50000),
+};
+
+static const struct linear_range tps65224_ldos_2_3_ranges[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x38, 50000),
+};
+
 /* Operations permitted on BUCK1/2/3/4/5 */
 static const struct regulator_ops tps6594_bucks_ops = {
 	.is_enabled		= regulator_is_enabled_regmap,
@@ -197,6 +227,38 @@ static const struct regulator_desc buck_regs[] = {
 			  4, 0, 0, NULL, 0, 0),
 };
 
+/* Buck configuration for TPS65224 */
+static const struct regulator_desc tps65224_buck_regs[] = {
+	TPS6594_REGULATOR("BUCK1", "buck1", TPS6594_BUCK_1,
+			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCK1_VSET,
+			  TPS6594_REG_BUCKX_VOUT_1(0),
+			  TPS65224_MASK_BUCK1_VSET,
+			  TPS6594_REG_BUCKX_CTRL(0),
+			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_1_ranges,
+			  4, 0, 0, NULL, 0, 0),
+	TPS6594_REGULATOR("BUCK2", "buck2", TPS6594_BUCK_2,
+			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_VOUT_1(1),
+			  TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_CTRL(1),
+			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
+			  4, 0, 0, NULL, 0, 0),
+	TPS6594_REGULATOR("BUCK3", "buck3", TPS6594_BUCK_3,
+			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_VOUT_1(2),
+			  TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_CTRL(2),
+			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
+			  4, 0, 0, NULL, 0, 0),
+	TPS6594_REGULATOR("BUCK4", "buck4", TPS6594_BUCK_4,
+			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_VOUT_1(3),
+			  TPS65224_MASK_BUCKS_VSET,
+			  TPS6594_REG_BUCKX_CTRL(3),
+			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
+			  4, 0, 0, NULL, 0, 0),
+};
+
 static struct tps6594_regulator_irq_type tps6594_buck1_irq_types[] = {
 	{ TPS6594_IRQ_NAME_BUCK1_OV, "BUCK1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
 	{ TPS6594_IRQ_NAME_BUCK1_UV, "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
@@ -269,6 +331,41 @@ static struct tps6594_regulator_irq_type tps6594_ldo4_irq_types[] = {
 	  REGULATOR_EVENT_OVER_CURRENT },
 };
 
+static struct tps6594_regulator_irq_type tps65224_buck1_irq_types[] = {
+	{ TPS65224_IRQ_NAME_BUCK1_UVOV, "BUCK1", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_buck2_irq_types[] = {
+	{ TPS65224_IRQ_NAME_BUCK2_UVOV, "BUCK2", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_buck3_irq_types[] = {
+	{ TPS65224_IRQ_NAME_BUCK3_UVOV, "BUCK3", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_buck4_irq_types[] = {
+	{ TPS65224_IRQ_NAME_BUCK4_UVOV, "BUCK4", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_ldo1_irq_types[] = {
+	{ TPS65224_IRQ_NAME_LDO1_UVOV, "LDO1", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_ldo2_irq_types[] = {
+	{ TPS65224_IRQ_NAME_LDO2_UVOV, "LDO2", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
+static struct tps6594_regulator_irq_type tps65224_ldo3_irq_types[] = {
+	{ TPS65224_IRQ_NAME_LDO3_UVOV, "LDO3", "voltage out of range",
+	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },
+};
+
 static struct tps6594_regulator_irq_type *tps6594_bucks_irq_types[] = {
 	tps6594_buck1_irq_types,
 	tps6594_buck2_irq_types,
@@ -284,7 +381,20 @@ static struct tps6594_regulator_irq_type *tps6594_ldos_irq_types[] = {
 	tps6594_ldo4_irq_types,
 };
 
-static const struct regulator_desc multi_regs[] = {
+static struct tps6594_regulator_irq_type *tps65224_bucks_irq_types[] = {
+	tps65224_buck1_irq_types,
+	tps65224_buck2_irq_types,
+	tps65224_buck3_irq_types,
+	tps65224_buck4_irq_types,
+};
+
+static struct tps6594_regulator_irq_type *tps65224_ldos_irq_types[] = {
+	tps65224_ldo1_irq_types,
+	tps65224_ldo2_irq_types,
+	tps65224_ldo3_irq_types,
+};
+
+static const struct regulator_desc tps6594_multi_regs[] = {
 	TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,
 			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
 			  TPS6594_REG_BUCKX_VOUT_1(1),
@@ -315,7 +425,17 @@ static const struct regulator_desc multi_regs[] = {
 			  4, 4000, 0, NULL, 0, 0),
 };
 
-static const struct regulator_desc ldo_regs[] = {
+static const struct regulator_desc tps65224_multi_regs[] = {
+	TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,
+			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCK1_VSET,
+			  TPS6594_REG_BUCKX_VOUT_1(0),
+			  TPS65224_MASK_BUCK1_VSET,
+			  TPS6594_REG_BUCKX_CTRL(0),
+			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_1_ranges,
+			  4, 4000, 0, NULL, 0, 0),
+};
+
+static const struct regulator_desc tps6594_ldo_regs[] = {
 	TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,
 			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
 			  TPS6594_REG_LDOX_VOUT(0),
@@ -346,6 +466,30 @@ static const struct regulator_desc ldo_regs[] = {
 			  1, 0, 0, NULL, 0, 0),
 };
 
+static const struct regulator_desc tps65224_ldo_regs[] = {
+	TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,
+			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_VOUT(0),
+			  TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_CTRL(0),
+			  TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_1_ranges,
+			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+	TPS6594_REGULATOR("LDO2", "ldo2", TPS6594_LDO_2,
+			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_VOUT(1),
+			  TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_CTRL(1),
+			  TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_2_3_ranges,
+			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+	TPS6594_REGULATOR("LDO3", "ldo3", TPS6594_LDO_3,
+			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_VOUT(2),
+			  TPS6594_MASK_LDO123_VSET,
+			  TPS6594_REG_LDOX_CTRL(2),
+			  TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_2_3_ranges,
+			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+};
+
 static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data)
 {
 	struct tps6594_regulator_irq_data *irq_data = data;
@@ -374,11 +518,17 @@ static int tps6594_request_reg_irqs(struct platform_device *pdev,
 {
 	struct tps6594_regulator_irq_type *irq_type;
 	struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
-	int j;
+	size_t j;
 	int irq;
 	int error;
+	size_t interrupt_cnt;
 
-	for (j = 0; j < REGS_INT_NB; j++) {
+	/* Number of interrupts supported by each voltage source */
+	interrupt_cnt = (tps->chip_id == TPS6594) ?
+			 ARRAY_SIZE(tps6594_buck1_irq_types) :
+			 ARRAY_SIZE(tps65224_buck1_irq_types);
+
+	for (j = 0; j < interrupt_cnt; j++) {
 		irq_type = &tps6594_regs_irq_types[j];
 		irq = platform_get_irq_byname(pdev, irq_type->irq_name);
 		if (irq < 0)
@@ -412,14 +562,20 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 	struct tps6594_ext_regulator_irq_data *irq_ext_reg_data;
 	struct tps6594_regulator_irq_type *irq_type;
 	u8 buck_configured[BUCK_NB] = { 0 };
+	u8 ldo_configured[LDO_NB] = { 0 };
 	u8 buck_multi[MULTI_PHASE_NB] = { 0 };
 	static const char * const multiphases[] = {"buck12", "buck123", "buck1234", "buck34"};
+	static const char * const tps65224_multiphases[] = {"buck12"};
 	static const char *npname;
 	int error, i, irq, multi, delta;
 	int irq_idx = 0;
 	int buck_idx = 0;
+	unsigned int multi_phase_cnt = 0;
 	size_t ext_reg_irq_nb = 2;
 	size_t reg_irq_nb;
+	struct tps6594_regulator_irq_type **bucks_irq_types = (tps->chip_id == TPS65224) ?
+							       tps65224_bucks_irq_types :
+							       tps6594_bucks_irq_types;
 	enum {
 		MULTI_BUCK12,
 		MULTI_BUCK123,
@@ -434,6 +590,10 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 	config.driver_data = tps;
 	config.regmap = tps->regmap;
 
+	multi_phase_cnt = (tps->chip_id == TPS65224) ?
+			   ARRAY_SIZE(tps65224_multiphases) :
+			   ARRAY_SIZE(multiphases);
+
 	/*
 	 * Switch case defines different possible multi phase config
 	 * This is based on dts buck node name.
@@ -442,7 +602,7 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 	 * In case of Multiphase configuration, value should be defined for
 	 * buck_configured to avoid creating bucks for every buck in multiphase
 	 */
-	for (multi = MULTI_FIRST; multi < MULTI_NUM; multi++) {
+	for (multi = MULTI_FIRST; multi < multi_phase_cnt; multi++) {
 		np = of_find_node_by_name(tps->dev->of_node, multiphases[multi]);
 		npname = of_node_full_name(np);
 		np_pmic_parent = of_get_parent(of_get_parent(np));
@@ -486,6 +646,11 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 		/* There is only 4 buck on LP8764 */
 		buck_configured[4] = 1;
 		reg_irq_nb = size_mul(REGS_INT_NB, (BUCK_NB - 1));
+	} else if (tps->chip_id == TPS65224) {
+		/* TPS65224 has 4 bucks and 3 LDOs. 1 Interrupt for each buck and ldo */
+		buck_configured[4] = 1;
+		ldo_configured[3] = 1;
+		reg_irq_nb = size_mul(1, (size_add((BUCK_NB - 1), (LDO_NB - 1))));
 	} else {
 		reg_irq_nb = size_mul(REGS_INT_NB, (size_add(BUCK_NB, LDO_NB)));
 	}
@@ -495,25 +660,30 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 	if (!irq_data)
 		return -ENOMEM;
 
-	for (i = 0; i < MULTI_PHASE_NB; i++) {
+	for (i = 0; i < multi_phase_cnt; i++) {
 		if (buck_multi[i] == 0)
 			continue;
 
+		const struct regulator_desc *multi_regs = (tps->chip_id == TPS65224) ?
+							   tps65224_multi_regs :
+							   tps6594_multi_regs;
 		rdev = devm_regulator_register(&pdev->dev, &multi_regs[i], &config);
-		if (IS_ERR(rdev))
-			return dev_err_probe(tps->dev, PTR_ERR(rdev),
-					     "failed to register %s regulator\n",
-					     pdev->name);
+			if (IS_ERR(rdev))
+				return dev_err_probe(tps->dev, PTR_ERR(rdev),
+						     "failed to register %s regulator\n",
+						     pdev->name);
 
 		/* config multiphase buck12+buck34 */
 		if (i == 1)
 			buck_idx = 2;
+
 		error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
-						 tps6594_bucks_irq_types[buck_idx], &irq_idx);
+						 bucks_irq_types[buck_idx], &irq_idx);
 		if (error)
 			return error;
+
 		error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
-						 tps6594_bucks_irq_types[buck_idx + 1], &irq_idx);
+						 bucks_irq_types[buck_idx + 1], &irq_idx);
 		if (error)
 			return error;
 
@@ -537,37 +707,49 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 		if (buck_configured[i] == 1)
 			continue;
 
-		rdev = devm_regulator_register(&pdev->dev, &buck_regs[i], &config);
+		const struct regulator_desc *buck_cfg = (tps->chip_id == TPS65224) ?
+							 tps65224_buck_regs : buck_regs;
+
+		rdev = devm_regulator_register(&pdev->dev, &buck_cfg[i], &config);
 		if (IS_ERR(rdev))
 			return dev_err_probe(tps->dev, PTR_ERR(rdev),
-					     "failed to register %s regulator\n",
-					     pdev->name);
+					     "failed to register %s regulator\n", pdev->name);
 
 		error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
-						 tps6594_bucks_irq_types[i], &irq_idx);
+						 bucks_irq_types[i], &irq_idx);
 		if (error)
 			return error;
 	}
 
-	/* LP8764 dosen't have LDO */
+	/* LP8764 doesn't have LDO */
 	if (tps->chip_id != LP8764) {
-		for (i = 0; i < ARRAY_SIZE(ldo_regs); i++) {
-			rdev = devm_regulator_register(&pdev->dev, &ldo_regs[i], &config);
-			if (IS_ERR(rdev))
-				return dev_err_probe(tps->dev, PTR_ERR(rdev),
-						     "failed to register %s regulator\n",
-						     pdev->name);
+		for (i = 0; i < LDO_NB; i++) {
+			if (ldo_configured[i] == 1)
+				continue;
 
-			error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
-							 tps6594_ldos_irq_types[i],
-							 &irq_idx);
-			if (error)
-				return error;
+		struct tps6594_regulator_irq_type **ldos_irq_types = (tps->chip_id == TPS65224) ?
+								       tps65224_ldos_irq_types :
+								       tps6594_ldos_irq_types;
+
+		const struct regulator_desc *ldo_regs = (tps->chip_id == TPS65224) ?
+							 tps65224_ldo_regs :
+							 tps6594_ldo_regs;
+
+		rdev = devm_regulator_register(&pdev->dev, &ldo_regs[i], &config);
+		if (IS_ERR(rdev))
+			return dev_err_probe(tps->dev, PTR_ERR(rdev),
+					     "failed to register %s regulator\n", pdev->name);
+
+		error = tps6594_request_reg_irqs(pdev, rdev, irq_data, ldos_irq_types[i], &irq_idx);
+		if (error)
+			return error;
 		}
 	}
 
 	if (tps->chip_id == LP8764)
 		ext_reg_irq_nb = ARRAY_SIZE(tps6594_ext_regulator_irq_types);
+	else if (tps->chip_id == TPS65224)
+		ext_reg_irq_nb = ARRAY_SIZE(tps65224_ext_regulator_irq_types);
 
 	irq_ext_reg_data = devm_kmalloc_array(tps->dev,
 					ext_reg_irq_nb,
@@ -577,7 +759,10 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	for (i = 0; i < ext_reg_irq_nb; ++i) {
-		irq_type = &tps6594_ext_regulator_irq_types[i];
+		if (tps->chip_id == TPS65224)
+			irq_type = &tps65224_ext_regulator_irq_types[i];
+		else
+			irq_type = &tps6594_ext_regulator_irq_types[i];
 
 		irq = platform_get_irq_byname(pdev, irq_type->irq_name);
 		if (irq < 0)
@@ -610,5 +795,6 @@ module_platform_driver(tps6594_regulator_driver);
 
 MODULE_ALIAS("platform:tps6594-regulator");
 MODULE_AUTHOR("Jerome Neanne <jneanne at baylibre.com>");
+MODULE_AUTHOR("Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>");
 MODULE_DESCRIPTION("TPS6594 voltage regulator driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:37:00 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:07:00 +0530
Subject: [PATCH v2 13/14] pinctrl: pinctrl-tps6594: Add TPS65224 PMIC pinctrl and GPIO
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-14-bhargav.r@ltts.com>

From: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>

Add support for TPS65224 pinctrl and GPIOs to TPS6594 driver as they
have significant functional overlap.
TPS65224 PMIC has 6 GPIOS which can be configured as GPIO or other
dedicated device functions.

Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/pinctrl/pinctrl-tps6594.c | 287 +++++++++++++++++++++++++-----
 1 file changed, 246 insertions(+), 41 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-tps6594.c b/drivers/pinctrl/pinctrl-tps6594.c
index 66985e54b..5da21aa14 100644
--- a/drivers/pinctrl/pinctrl-tps6594.c
+++ b/drivers/pinctrl/pinctrl-tps6594.c
@@ -14,8 +14,6 @@
 
 #include <linux/mfd/tps6594.h>
 
-#define TPS6594_PINCTRL_PINS_NB 11
-
 #define TPS6594_PINCTRL_GPIO_FUNCTION 0
 #define TPS6594_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION 1
 #define TPS6594_PINCTRL_TRIG_WDOG_FUNCTION 1
@@ -40,17 +38,40 @@
 #define TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION_GPIO8 3
 #define TPS6594_PINCTRL_CLK32KOUT_FUNCTION_GPIO9 3
 
+/* TPS65224 pin muxval */
+#define TPS65224_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION 1
+#define TPS65224_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION 1
+#define TPS65224_PINCTRL_VMON1_FUNCTION 1
+#define TPS65224_PINCTRL_VMON2_FUNCTION 1
+#define TPS65224_PINCTRL_WKUP_FUNCTION 1
+#define TPS65224_PINCTRL_NSLEEP2_FUNCTION 2
+#define TPS65224_PINCTRL_NSLEEP1_FUNCTION 2
+#define TPS65224_PINCTRL_SYNCCLKIN_FUNCTION 2
+#define TPS65224_PINCTRL_NERR_MCU_FUNCTION 2
+#define TPS65224_PINCTRL_NINT_FUNCTION 3
+#define TPS65224_PINCTRL_TRIG_WDOG_FUNCTION 3
+#define TPS65224_PINCTRL_PB_FUNCTION 3
+#define TPS65224_PINCTRL_ADC_IN_FUNCTION 3
+
+/* TPS65224 Special muxval for recalcitrant pins */
+#define TPS65224_PINCTRL_NSLEEP2_FUNCTION_GPIO5 1
+#define TPS65224_PINCTRL_WKUP_FUNCTION_GPIO5 4
+#define TPS65224_PINCTRL_SYNCCLKIN_FUNCTION_GPIO5 3
+
 #define TPS6594_OFFSET_GPIO_SEL 5
 
-#define FUNCTION(fname, v)									\
+#define TPS65224_NGPIO_PER_REG 6
+#define TPS6594_NGPIO_PER_REG  8
+
+#define FUNCTION(dev_name, fname, v)							\
 {											\
 	.pinfunction = PINCTRL_PINFUNCTION(#fname,					\
-					tps6594_##fname##_func_group_names,		\
-					ARRAY_SIZE(tps6594_##fname##_func_group_names)),\
+					dev_name##_##fname##_func_group_names,		\
+					ARRAY_SIZE(dev_name##_##fname##_func_group_names)),\
 	.muxval = v,									\
 }
 
-static const struct pinctrl_pin_desc tps6594_pins[TPS6594_PINCTRL_PINS_NB] = {
+static const struct pinctrl_pin_desc tps6594_pins[] = {
 	PINCTRL_PIN(0, "GPIO0"),   PINCTRL_PIN(1, "GPIO1"),
 	PINCTRL_PIN(2, "GPIO2"),   PINCTRL_PIN(3, "GPIO3"),
 	PINCTRL_PIN(4, "GPIO4"),   PINCTRL_PIN(5, "GPIO5"),
@@ -143,30 +164,127 @@ static const char *const tps6594_syncclkin_func_group_names[] = {
 	"GPIO9",
 };
 
+static const struct pinctrl_pin_desc tps65224_pins[] = {
+	PINCTRL_PIN(0, "GPIO0"),   PINCTRL_PIN(1, "GPIO1"),
+	PINCTRL_PIN(2, "GPIO2"),   PINCTRL_PIN(3, "GPIO3"),
+	PINCTRL_PIN(4, "GPIO4"),   PINCTRL_PIN(5, "GPIO5"),
+};
+
+static const char *const tps65224_gpio_func_group_names[] = {
+	"GPIO0", "GPIO1", "GPIO2", "GPIO3", "GPIO4", "GPIO5",
+};
+
+static const char *const tps65224_sda_i2c2_sdo_spi_func_group_names[] = {
+	"GPIO0",
+};
+
+static const char *const tps65224_nsleep2_func_group_names[] = {
+	"GPIO0", "GPIO5",
+};
+
+static const char *const tps65224_nint_func_group_names[] = {
+	"GPIO0",
+};
+
+static const char *const tps65224_scl_i2c2_cs_spi_func_group_names[] = {
+	"GPIO1",
+};
+
+static const char *const tps65224_nsleep1_func_group_names[] = {
+	"GPIO1", "GPIO2", "GPIO3",
+};
+
+static const char *const tps65224_trig_wdog_func_group_names[] = {
+	"GPIO1",
+};
+
+static const char *const tps65224_vmon1_func_group_names[] = {
+	"GPIO2",
+};
+
+static const char *const tps65224_pb_func_group_names[] = {
+	"GPIO2",
+};
+
+static const char *const tps65224_vmon2_func_group_names[] = {
+	"GPIO3",
+};
+
+static const char *const tps65224_adc_in_func_group_names[] = {
+	"GPIO3", "GPIO4",
+};
+
+static const char *const tps65224_wkup_func_group_names[] = {
+	"GPIO4", "GPIO5",
+};
+
+static const char *const tps65224_syncclkin_func_group_names[] = {
+	"GPIO4", "GPIO5",
+};
+
+static const char *const tps65224_nerr_mcu_func_group_names[] = {
+	"GPIO5",
+};
+
 struct tps6594_pinctrl_function {
 	struct pinfunction pinfunction;
 	u8 muxval;
 };
 
+struct muxval_remap {
+	unsigned int group;
+	u8 muxval;
+	u8 remap;
+};
+
+struct muxval_remap tps65224_muxval_remap[] = {
+	{5, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION, TPS65224_PINCTRL_WKUP_FUNCTION_GPIO5},
+	{5, TPS65224_PINCTRL_SYNCCLKIN_FUNCTION, TPS65224_PINCTRL_SYNCCLKIN_FUNCTION_GPIO5},
+	{5, TPS65224_PINCTRL_NSLEEP2_FUNCTION, TPS65224_PINCTRL_NSLEEP2_FUNCTION_GPIO5},
+};
+
+struct muxval_remap tps6594_muxval_remap[] = {
+	{8, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION_GPIO8},
+	{8, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION_GPIO8},
+	{9, TPS6594_PINCTRL_CLK32KOUT_FUNCTION, TPS6594_PINCTRL_CLK32KOUT_FUNCTION_GPIO9},
+};
+
 static const struct tps6594_pinctrl_function pinctrl_functions[] = {
-	FUNCTION(gpio, TPS6594_PINCTRL_GPIO_FUNCTION),
-	FUNCTION(nsleep1, TPS6594_PINCTRL_NSLEEP1_FUNCTION),
-	FUNCTION(nsleep2, TPS6594_PINCTRL_NSLEEP2_FUNCTION),
-	FUNCTION(wkup1, TPS6594_PINCTRL_WKUP1_FUNCTION),
-	FUNCTION(wkup2, TPS6594_PINCTRL_WKUP2_FUNCTION),
-	FUNCTION(scl_i2c2_cs_spi, TPS6594_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION),
-	FUNCTION(nrstout_soc, TPS6594_PINCTRL_NRSTOUT_SOC_FUNCTION),
-	FUNCTION(trig_wdog, TPS6594_PINCTRL_TRIG_WDOG_FUNCTION),
-	FUNCTION(sda_i2c2_sdo_spi, TPS6594_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION),
-	FUNCTION(clk32kout, TPS6594_PINCTRL_CLK32KOUT_FUNCTION),
-	FUNCTION(nerr_soc, TPS6594_PINCTRL_NERR_SOC_FUNCTION),
-	FUNCTION(sclk_spmi, TPS6594_PINCTRL_SCLK_SPMI_FUNCTION),
-	FUNCTION(sdata_spmi, TPS6594_PINCTRL_SDATA_SPMI_FUNCTION),
-	FUNCTION(nerr_mcu, TPS6594_PINCTRL_NERR_MCU_FUNCTION),
-	FUNCTION(syncclkout, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION),
-	FUNCTION(disable_wdog, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION),
-	FUNCTION(pdog, TPS6594_PINCTRL_PDOG_FUNCTION),
-	FUNCTION(syncclkin, TPS6594_PINCTRL_SYNCCLKIN_FUNCTION),
+	FUNCTION(tps6594, gpio, TPS6594_PINCTRL_GPIO_FUNCTION),
+	FUNCTION(tps6594, nsleep1, TPS6594_PINCTRL_NSLEEP1_FUNCTION),
+	FUNCTION(tps6594, nsleep2, TPS6594_PINCTRL_NSLEEP2_FUNCTION),
+	FUNCTION(tps6594, wkup1, TPS6594_PINCTRL_WKUP1_FUNCTION),
+	FUNCTION(tps6594, wkup2, TPS6594_PINCTRL_WKUP2_FUNCTION),
+	FUNCTION(tps6594, scl_i2c2_cs_spi, TPS6594_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION),
+	FUNCTION(tps6594, nrstout_soc, TPS6594_PINCTRL_NRSTOUT_SOC_FUNCTION),
+	FUNCTION(tps6594, trig_wdog, TPS6594_PINCTRL_TRIG_WDOG_FUNCTION),
+	FUNCTION(tps6594, sda_i2c2_sdo_spi, TPS6594_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION),
+	FUNCTION(tps6594, clk32kout, TPS6594_PINCTRL_CLK32KOUT_FUNCTION),
+	FUNCTION(tps6594, nerr_soc, TPS6594_PINCTRL_NERR_SOC_FUNCTION),
+	FUNCTION(tps6594, sclk_spmi, TPS6594_PINCTRL_SCLK_SPMI_FUNCTION),
+	FUNCTION(tps6594, sdata_spmi, TPS6594_PINCTRL_SDATA_SPMI_FUNCTION),
+	FUNCTION(tps6594, nerr_mcu, TPS6594_PINCTRL_NERR_MCU_FUNCTION),
+	FUNCTION(tps6594, syncclkout, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION),
+	FUNCTION(tps6594, disable_wdog, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION),
+	FUNCTION(tps6594, pdog, TPS6594_PINCTRL_PDOG_FUNCTION),
+	FUNCTION(tps6594, syncclkin, TPS6594_PINCTRL_SYNCCLKIN_FUNCTION),
+};
+
+static const struct tps6594_pinctrl_function tps65224_pinctrl_functions[] = {
+	FUNCTION(tps65224, gpio, TPS6594_PINCTRL_GPIO_FUNCTION),
+	FUNCTION(tps65224, sda_i2c2_sdo_spi, TPS65224_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION),
+	FUNCTION(tps65224, nsleep2, TPS65224_PINCTRL_NSLEEP2_FUNCTION),
+	FUNCTION(tps65224, nint, TPS65224_PINCTRL_NINT_FUNCTION),
+	FUNCTION(tps65224, scl_i2c2_cs_spi, TPS65224_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION),
+	FUNCTION(tps65224, nsleep1, TPS65224_PINCTRL_NSLEEP1_FUNCTION),
+	FUNCTION(tps65224, trig_wdog, TPS65224_PINCTRL_TRIG_WDOG_FUNCTION),
+	FUNCTION(tps65224, vmon1, TPS65224_PINCTRL_VMON1_FUNCTION),
+	FUNCTION(tps65224, pb, TPS65224_PINCTRL_PB_FUNCTION),
+	FUNCTION(tps65224, vmon2, TPS65224_PINCTRL_VMON2_FUNCTION),
+	FUNCTION(tps65224, adc_in, TPS65224_PINCTRL_ADC_IN_FUNCTION),
+	FUNCTION(tps65224, wkup, TPS65224_PINCTRL_WKUP_FUNCTION),
+	FUNCTION(tps65224, syncclkin, TPS65224_PINCTRL_SYNCCLKIN_FUNCTION),
+	FUNCTION(tps65224, nerr_mcu, TPS65224_PINCTRL_NERR_MCU_FUNCTION),
 };
 
 struct tps6594_pinctrl {
@@ -201,7 +319,21 @@ static int tps6594_gpio_regmap_xlate(struct gpio_regmap *gpio,
 
 static int tps6594_pmx_func_cnt(struct pinctrl_dev *pctldev)
 {
-	return ARRAY_SIZE(pinctrl_functions);
+	struct tps6594_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+	int func_cnt = 0;
+
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		func_cnt = ARRAY_SIZE(tps65224_pinctrl_functions);
+		break;
+	case TPS6594:
+		func_cnt = ARRAY_SIZE(pinctrl_functions);
+		break;
+	default:
+		break;
+	}
+
+	return func_cnt;
 }
 
 static const char *tps6594_pmx_func_name(struct pinctrl_dev *pctldev,
@@ -229,10 +361,26 @@ static int tps6594_pmx_set(struct tps6594_pinctrl *pinctrl, unsigned int pin,
 			   u8 muxval)
 {
 	u8 mux_sel_val = muxval << TPS6594_OFFSET_GPIO_SEL;
+	u8 mux_sel_mask = 0;
+
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		mux_sel_mask = TPS65224_MASK_GPIO_SEL;
+		/* GPIO6 has a different mask in TPS65224*/
+		if (pin == 5)
+			mux_sel_mask = TPS65224_MASK_GPIO_SEL_GPIO6;
+		mux_sel_mask = TPS6594_MASK_GPIO_SEL;
+		break;
+	case TPS6594:
+		mux_sel_mask = TPS6594_MASK_GPIO_SEL;
+		break;
+	default:
+		break;
+	}
 
 	return regmap_update_bits(pinctrl->tps->regmap,
 				  TPS6594_REG_GPIOX_CONF(pin),
-				  TPS6594_MASK_GPIO_SEL, mux_sel_val);
+				  mux_sel_mask, mux_sel_val);
 }
 
 static int tps6594_pmx_set_mux(struct pinctrl_dev *pctldev,
@@ -240,16 +388,28 @@ static int tps6594_pmx_set_mux(struct pinctrl_dev *pctldev,
 {
 	struct tps6594_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
 	u8 muxval = pinctrl->funcs[function].muxval;
+	unsigned int remap_cnt = 0;
+	struct muxval_remap *remap;
 
 	/* Some pins don't have the same muxval for the same function... */
-	if (group == 8) {
-		if (muxval == TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION)
-			muxval = TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION_GPIO8;
-		else if (muxval == TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION)
-			muxval = TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION_GPIO8;
-	} else if (group == 9) {
-		if (muxval == TPS6594_PINCTRL_CLK32KOUT_FUNCTION)
-			muxval = TPS6594_PINCTRL_CLK32KOUT_FUNCTION_GPIO9;
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		remap = tps65224_muxval_remap;
+		remap_cnt = ARRAY_SIZE(tps65224_muxval_remap);
+		break;
+	case TPS6594:
+		remap = tps6594_muxval_remap;
+		remap_cnt = ARRAY_SIZE(tps6594_muxval_remap);
+		break;
+	default:
+		break;
+	}
+
+	for (unsigned int i = 0; i < remap_cnt; i++) {
+		if (group == remap[i].group && muxval == remap[i].muxval) {
+			muxval = remap[i].remap;
+			break;
+		}
 	}
 
 	return tps6594_pmx_set(pinctrl, group, muxval);
@@ -276,7 +436,21 @@ static const struct pinmux_ops tps6594_pmx_ops = {
 
 static int tps6594_groups_cnt(struct pinctrl_dev *pctldev)
 {
-	return ARRAY_SIZE(tps6594_pins);
+	struct tps6594_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+	int num_pins = 0;
+
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		num_pins = ARRAY_SIZE(tps65224_pins);
+		break;
+	case TPS6594:
+		num_pins = ARRAY_SIZE(tps6594_pins);
+		break;
+	default:
+		break;
+	}
+
+	return num_pins;
 }
 
 static int tps6594_group_pins(struct pinctrl_dev *pctldev,
@@ -320,8 +494,18 @@ static int tps6594_pinctrl_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	pctrl_desc->name = dev_name(dev);
 	pctrl_desc->owner = THIS_MODULE;
-	pctrl_desc->pins = tps6594_pins;
-	pctrl_desc->npins = ARRAY_SIZE(tps6594_pins);
+	switch (tps->chip_id) {
+	case TPS65224:
+		pctrl_desc->pins = tps65224_pins;
+		pctrl_desc->npins = ARRAY_SIZE(tps65224_pins);
+		break;
+	case TPS6594:
+		pctrl_desc->pins = tps6594_pins;
+		pctrl_desc->npins = ARRAY_SIZE(tps6594_pins);
+		break;
+	default:
+		break;
+	}
 	pctrl_desc->pctlops = &tps6594_pctrl_ops;
 	pctrl_desc->pmxops = &tps6594_pmx_ops;
 
@@ -329,8 +513,18 @@ static int tps6594_pinctrl_probe(struct platform_device *pdev)
 	if (!pinctrl)
 		return -ENOMEM;
 	pinctrl->tps = dev_get_drvdata(dev->parent);
-	pinctrl->funcs = pinctrl_functions;
-	pinctrl->pins = tps6594_pins;
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		pinctrl->funcs = tps65224_pinctrl_functions;
+		pinctrl->pins = tps65224_pins;
+		break;
+	case TPS6594:
+		pinctrl->funcs = pinctrl_functions;
+		pinctrl->pins = tps6594_pins;
+		break;
+	default:
+		break;
+	}
 	pinctrl->pctl_dev = devm_pinctrl_register(dev, pctrl_desc, pinctrl);
 	if (IS_ERR(pinctrl->pctl_dev))
 		return dev_err_probe(dev, PTR_ERR(pinctrl->pctl_dev),
@@ -338,8 +532,18 @@ static int tps6594_pinctrl_probe(struct platform_device *pdev)
 
 	config.parent = tps->dev;
 	config.regmap = tps->regmap;
-	config.ngpio = TPS6594_PINCTRL_PINS_NB;
-	config.ngpio_per_reg = 8;
+	switch (pinctrl->tps->chip_id) {
+	case TPS65224:
+		config.ngpio = ARRAY_SIZE(tps65224_gpio_func_group_names);
+		config.ngpio_per_reg = TPS65224_NGPIO_PER_REG;
+		break;
+	case TPS6594:
+		config.ngpio = ARRAY_SIZE(tps6594_gpio_func_group_names);
+		config.ngpio_per_reg = TPS6594_NGPIO_PER_REG;
+		break;
+	default:
+		break;
+	}
 	config.reg_dat_base = TPS6594_REG_GPIO_IN_1;
 	config.reg_set_base = TPS6594_REG_GPIO_OUT_1;
 	config.reg_dir_out_base = TPS6594_REG_GPIOX_CONF(0);
@@ -369,5 +573,6 @@ static struct platform_driver tps6594_pinctrl_driver = {
 module_platform_driver(tps6594_pinctrl_driver);
 
 MODULE_AUTHOR("Esteban Blanc <eblanc at baylibre.com>");
+MODULE_AUTHOR("Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>");
 MODULE_DESCRIPTION("TPS6594 pinctrl and GPIO driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:52 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:52 +0530
Subject: [PATCH v2 05/14] mfd: tps6594-i2c: Add TI TPS65224 PMIC I2C
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-6-bhargav.r@ltts.com>

Add support for TPS65224 PMIC in TPS6594's I2C driver which has
significant functional overlap.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/mfd/tps6594-i2c.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/tps6594-i2c.c b/drivers/mfd/tps6594-i2c.c
index e80e0af2b..c5b352ecc 100644
--- a/drivers/mfd/tps6594-i2c.c
+++ b/drivers/mfd/tps6594-i2c.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * I2C access driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * I2C access driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
@@ -192,16 +192,27 @@ static const struct regmap_config tps6594_i2c_regmap_config = {
 	.write = tps6594_i2c_write,
 };
 
+static const struct regmap_config tps65224_i2c_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 8,
+	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
+	.volatile_table = &tps65224_volatile_table,
+	.read = tps6594_i2c_read,
+	.write = tps6594_i2c_write,
+};
+
 static const struct tps6594_match_data match_data[] = {
 	[TPS6594] = {TPS6594, &tps6594_i2c_regmap_config},
 	[TPS6593] = {TPS6593, &tps6594_i2c_regmap_config},
 	[LP8764] = {LP8764, &tps6594_i2c_regmap_config},
+	[TPS65224] = {TPS65224, &tps65224_i2c_regmap_config},
 };
 
 static const struct of_device_id tps6594_i2c_of_match_table[] = {
 	{ .compatible = "ti,tps6594-q1", .data = (void *)&match_data[TPS6594], },
 	{ .compatible = "ti,tps6593-q1", .data = (void *)&match_data[TPS6593], },
 	{ .compatible = "ti,lp8764-q1",  .data = (void *)&match_data[LP8764], },
+	{ .compatible = "ti,tps65224-q1", .data = (void *)&match_data[TPS65224], },
 	{}
 };
 MODULE_DEVICE_TABLE(of, tps6594_i2c_of_match_table);
@@ -248,5 +259,5 @@ static struct i2c_driver tps6594_i2c_driver = {
 module_i2c_driver(tps6594_i2c_driver);
 
 MODULE_AUTHOR("Julien Panis <jpanis at baylibre.com>");
-MODULE_DESCRIPTION("TPS6594 I2C Interface Driver");
+MODULE_DESCRIPTION("I2C Interface Driver for TPS65224, TPS6594/3, and LP8764");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:53 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:53 +0530
Subject: [PATCH v2 06/14] mfd: tps6594-spi: Add TI TPS65224 PMIC SPI
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-7-bhargav.r@ltts.com>

Add support for TPS65224 PMIC in the TPS6594 driver as they share
significant functional overlap.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/mfd/tps6594-spi.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
index b9428dc12..4458c5db7 100644
--- a/drivers/mfd/tps6594-spi.c
+++ b/drivers/mfd/tps6594-spi.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SPI access driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * SPI access driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
@@ -77,16 +77,29 @@ static const struct regmap_config tps6594_spi_regmap_config = {
 	.use_single_write = true,
 };
 
+static const struct regmap_config tps65224_spi_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 8,
+	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
+	.volatile_table = &tps65224_volatile_table,
+	.reg_read = tps6594_spi_reg_read,
+	.reg_write = tps6594_spi_reg_write,
+	.use_single_read = true,
+	.use_single_write = true,
+};
+
 static const struct tps6594_match_data match_data[] = {
 	[TPS6594] = {TPS6594, &tps6594_spi_regmap_config},
 	[TPS6593] = {TPS6593, &tps6594_spi_regmap_config},
 	[LP8764] = {LP8764, &tps6594_spi_regmap_config},
+	[TPS65224] = {TPS65224, &tps65224_spi_regmap_config},
 };
 
 static const struct of_device_id tps6594_spi_of_match_table[] = {
 	{ .compatible = "ti,tps6594-q1", .data = (void *)&match_data[TPS6594], },
 	{ .compatible = "ti,tps6593-q1", .data = (void *)&match_data[TPS6593], },
 	{ .compatible = "ti,lp8764-q1",  .data = (void *)&match_data[LP8764], },
+	{ .compatible = "ti,tps65224-q1", .data = (void *)&match_data[TPS65224],},
 	{}
 };
 MODULE_DEVICE_TABLE(of, tps6594_spi_of_match_table);
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:56 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:56 +0530
Subject: [PATCH v2 09/14] misc: tps6594-esm: reversion check limited to TPS6594 family
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-10-bhargav.r@ltts.com>

The reversion check is only applicable on TPS6594 family of PMICs.
Conditionally add that check if the chip_id is one of the PMIC in
the TPS6594 family.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/misc/tps6594-esm.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/misc/tps6594-esm.c b/drivers/misc/tps6594-esm.c
index b4d67a1a2..8ec5af9dc 100644
--- a/drivers/misc/tps6594-esm.c
+++ b/drivers/misc/tps6594-esm.c
@@ -45,13 +45,17 @@ static int tps6594_esm_probe(struct platform_device *pdev)
 	 * As a consequence, ESM can not be used on those PMIC.
 	 * Check the version and return an error in case of revision 1.
 	 */
-	ret = regmap_read(tps->regmap, TPS6594_REG_DEV_REV, &rev);
-	if (ret)
-		return dev_err_probe(dev, ret,
-				     "Failed to read PMIC revision\n");
-	if (rev == TPS6594_DEV_REV_1)
-		return dev_err_probe(dev, -ENODEV,
-			      "ESM not supported for revision 1 PMIC\n");
+	if (tps->chip_id == TPS6594 ||
+	    tps->chip_id == TPS6593 ||
+	    tps->chip_id == LP8764) {
+		ret = regmap_read(tps->regmap, TPS6594_REG_DEV_REV, &rev);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "Failed to read PMIC revision\n");
+		if (rev == TPS6594_DEV_REV_1)
+			return dev_err_probe(dev, -ENODEV,
+				      "ESM not supported for revision 1 PMIC\n");
+	}
 
 	for (i = 0; i < pdev->num_resources; i++) {
 		irq = platform_get_irq_byname(pdev, pdev->resource[i].name);
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:37:01 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:07:01 +0530
Subject: [PATCH v2 14/14] arch: arm64: dts: ti: k3-am62p5-sk: Add TPS65224 PMIC support in AM62P dts
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-15-bhargav.r@ltts.com>

Add support for TPS65224 PMIC in device tree of AM62P EVM. Adds
regulator configuration, pinmux configurations and pmic device nodes.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 95 +++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 1773c05f7..5d8e4321b 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -112,6 +112,16 @@ vddshv_sdio: regulator-3 {
 		bootph-all;
 	};
 
+	vcc_3v3_main: regulator-4 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_main";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vmain_pd>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
@@ -580,6 +590,12 @@ &main_uart1 {
 &mcu_pmx0 {
 	bootph-all;
 
+	pmic_irq_pins_default: pmic-irq-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_MCU_IOPAD(0x000, PIN_INPUT, 7) /* (B10) MCU_GPIO0_0 */
+		>;
+	};
+
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
 			AM62PX_MCU_IOPAD(0x02c, PIN_INPUT, 0)	/* (C7) WKUP_UART0_CTSn */
@@ -589,6 +605,13 @@ AM62PX_MCU_IOPAD(0x028, PIN_OUTPUT, 0)	/* (D7) WKUP_UART0_TXD */
 		>;
 		bootph-all;
 	};
+
+	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_MCU_IOPAD(0x04c, PIN_INPUT, 0) /* (A13) WKUP_I2C0_SCL */
+			AM62PX_MCU_IOPAD(0x050, PIN_INPUT, 0) /* (C11) WKUP_I2C0_SDA */
+		>;
+	};
 };
 
 &wkup_uart0 {
@@ -599,6 +622,78 @@ &wkup_uart0 {
 	bootph-all;
 };
 
+&wkup_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&wkup_i2c0_pins_default>;
+	clock-frequency = <400000>;
+
+	tps65224: pmic at 48 {
+		compatible = "ti,tps65224-q1";
+		reg = <0x48>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_irq_pins_default>;
+		interrupt-parent = <&mcu_gpio0>;
+		interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+		ti,primary-pmic;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		buck12-supply = <&vcc_3v3_main>;
+		buck3-supply = <&vcc_3v3_main>;
+		buck4-supply = <&vcc_3v3_main>;
+
+		ldo1-supply = <&vcc_3v3_main>;
+		ldo2-supply = <&vcc_3v3_main>;
+		ldo3-supply = <&vcc1v8_sys>;
+
+		regulators {
+			vcc_core: buck12 {
+				regulator-name = "vcc_core_buck12";
+				regulator-min-microvolt = <715000>;
+				regulator-max-microvolt = <895000>;
+				regulator-always-on;
+			};
+
+			vcc1v8_sys: buck3 {
+				regulator-name = "vcc1v8_sys_buck3";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			vcc1v1: buck4 {
+				regulator-name = "vcc1v1_buck4";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			vdda1v8: ldo1 {
+				regulator-name = "vdda1v8_ldo1";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+
+			dvdd3v3: ldo2 {
+				regulator-name = "dvdd3v3_ldo2";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vcc_0v85: ldo3 {
+				regulator-name = "vcc_0v85_ldo3";
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
 /* mcu_gpio0 and mcu_gpio_intr are reserved for mcu firmware usage */
 &mcu_gpio0 {
 	status = "reserved";
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:58 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:58 +0530
Subject: [PATCH v2 11/14] misc: tps6594-esm: Add TI TPS65224 PMIC ESM
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-12-bhargav.r@ltts.com>

Add support for TPS65224 Error Signal Monitor in the TPS6594 ESM driver
as they share significant functionality.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/misc/tps6594-esm.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/tps6594-esm.c b/drivers/misc/tps6594-esm.c
index d0f86b0e9..445d82bd3 100644
--- a/drivers/misc/tps6594-esm.c
+++ b/drivers/misc/tps6594-esm.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * ESM (Error Signal Monitor) driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * ESM (Error Signal Monitor) driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
@@ -20,6 +20,8 @@
 #define ESM_MODE_CFG_CLR  0x0
 #define ESM_START_CLR     0x0
 
+static struct reg_field tps65224_esm_mode_cfg = REG_FIELD(TPS6594_REG_ESM_MCU_MODE_CFG,  5, 6);
+static struct reg_field tps65224_esm_start    = REG_FIELD(TPS6594_REG_ESM_MCU_START_REG, 0, 0);
 static struct reg_field tps6594_esm_mode_cfg  = REG_FIELD(TPS6594_REG_ESM_SOC_MODE_CFG,  5, 6);
 static struct reg_field tps6594_esm_start     = REG_FIELD(TPS6594_REG_ESM_SOC_START_REG, 0, 0);
 
@@ -87,8 +89,14 @@ static int tps6594_esm_probe(struct platform_device *pdev)
 	if (!esm)
 		return -ENOMEM;
 
-	esm->esm_mode_cfg = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_mode_cfg);
-	esm->esm_start = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_start);
+	if (tps->chip_id == TPS65224) {
+		esm->esm_mode_cfg = devm_regmap_field_alloc(dev, tps->regmap,
+							    tps65224_esm_mode_cfg);
+		esm->esm_start = devm_regmap_field_alloc(dev, tps->regmap, tps65224_esm_start);
+	} else {
+		esm->esm_mode_cfg = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_mode_cfg);
+		esm->esm_start = devm_regmap_field_alloc(dev, tps->regmap, tps6594_esm_start);
+	}
 
 	if (IS_ERR(esm->esm_mode_cfg)) {
 		dev_err(dev, "esm_mode_cfg reg field init failed\n");
@@ -176,5 +184,6 @@ module_platform_driver(tps6594_esm_driver);
 
 MODULE_ALIAS("platform:tps6594-esm");
 MODULE_AUTHOR("Julien Panis <jpanis at baylibre.com>");
+MODULE_AUTHOR("Bhargav Raviprakash <bhargav.r at ltts.com>");
 MODULE_DESCRIPTION("TPS6594 Error Signal Monitor Driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From marex at denx.de  Fri Feb 23 01:47:37 2024
From: marex at denx.de (Marek Vasut)
Date: Fri, 23 Feb 2024 10:47:37 +0100
Subject: [PATCH] drm/lcdif: Do not disable clock on already suspended
 hardware
In-Reply-To: <20240118183924.144221-1-marex@denx.de>
References: <20240118183924.144221-1-marex@denx.de>
Message-ID: <1898e9b8-9b88-4458-86bb-cd013cb95875@denx.de>

On 1/18/24 19:39, Marek Vasut wrote:
> In case the LCDIF is enabled in DT but unused, the clock used by the
> LCDIF are not enabled. Those clock may even have a use count of 0 in
> case there are no other users of those clock. This can happen e.g. in
> case the LCDIF drives HDMI bridge which has no panel plugged into the
> HDMI connector.
> 
> Do not attempt to disable clock in the suspend callback and re-enable
> clock in the resume callback unless the LCDIF is enabled and was in
> use before the system entered suspend, otherwise the driver might end
> up trying to disable clock which are already disabled with use count
> 0, and would trigger a warning from clock core about this condition.
> 
> Note that the lcdif_rpm_suspend() and lcdif_rpm_resume() functions
> internally perform the clock disable and enable operations and act
> as runtime PM hooks too.
> 
> Fixes: 9db35bb349a0 ("drm: lcdif: Add support for i.MX8MP LCDIF variant")
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: David Airlie <airlied at gmail.com>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: Liu Ying <victor.liu at nxp.com>
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
> Cc: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Stefan Agner <stefan at agner.ch>
> Cc: Thomas Zimmermann <tzimmermann at suse.de>
> Cc: dri-devel at lists.freedesktop.org
> Cc: linux-arm-kernel at lists.infradead.org
> ---
>   drivers/gpu/drm/mxsfb/lcdif_drv.c | 6 +++++-
>   1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> index ea10bf81582e9..0f895b8a99d62 100644
> --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
> +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> @@ -343,6 +343,9 @@ static int __maybe_unused lcdif_suspend(struct device *dev)
>   	if (ret)
>   		return ret;
>   
> +	if (pm_runtime_suspended(dev))
> +		return 0;
> +
>   	return lcdif_rpm_suspend(dev);
>   }
>   
> @@ -350,7 +353,8 @@ static int __maybe_unused lcdif_resume(struct device *dev)
>   {
>   	struct drm_device *drm = dev_get_drvdata(dev);
>   
> -	lcdif_rpm_resume(dev);
> +	if (!pm_runtime_suspended(dev))
> +		lcdif_rpm_resume(dev);
>   
>   	return drm_mode_config_helper_resume(drm);
>   }

Moving Victor to To: , it would be good to get some input on this as it 
fixes suspend/resume on MX8MP with HDMI .


From bhargav.r at ltts.com  Fri Feb 23 01:36:49 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:49 +0530
Subject: [PATCH v2 02/14] mfd: tps6594: use volatile_table instead of volatile_reg
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-3-bhargav.r@ltts.com>

In regmap_config use volatile_table instead of volatile_reg.
This change makes it easier to add support for TPS65224 PMIC.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/mfd/tps6594-core.c  | 16 ++++++++++------
 drivers/mfd/tps6594-i2c.c   |  2 +-
 drivers/mfd/tps6594-spi.c   |  2 +-
 include/linux/mfd/tps6594.h |  4 +++-
 4 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/tps6594-core.c b/drivers/mfd/tps6594-core.c
index 783ee5990..089ab8cc8 100644
--- a/drivers/mfd/tps6594-core.c
+++ b/drivers/mfd/tps6594-core.c
@@ -319,12 +319,16 @@ static struct regmap_irq_chip tps6594_irq_chip = {
 	.handle_post_irq = tps6594_handle_post_irq,
 };
 
-bool tps6594_is_volatile_reg(struct device *dev, unsigned int reg)
-{
-	return (reg >= TPS6594_REG_INT_TOP && reg <= TPS6594_REG_STAT_READBACK_ERR) ||
-	       reg == TPS6594_REG_RTC_STATUS;
-}
-EXPORT_SYMBOL_GPL(tps6594_is_volatile_reg);
+static const struct regmap_range tps6594_volatile_ranges[] = {
+	regmap_reg_range(TPS6594_REG_INT_TOP, TPS6594_REG_STAT_READBACK_ERR),
+	regmap_reg_range(TPS6594_REG_RTC_STATUS, TPS6594_REG_RTC_STATUS),
+};
+
+const struct regmap_access_table tps6594_volatile_table = {
+	.yes_ranges = tps6594_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(tps6594_volatile_ranges),
+};
+EXPORT_SYMBOL_GPL(tps6594_volatile_table);
 
 static int tps6594_check_crc_mode(struct tps6594 *tps, bool primary_pmic)
 {
diff --git a/drivers/mfd/tps6594-i2c.c b/drivers/mfd/tps6594-i2c.c
index 899c88c0f..c125b474b 100644
--- a/drivers/mfd/tps6594-i2c.c
+++ b/drivers/mfd/tps6594-i2c.c
@@ -187,7 +187,7 @@ static const struct regmap_config tps6594_i2c_regmap_config = {
 	.reg_bits = 16,
 	.val_bits = 8,
 	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
-	.volatile_reg = tps6594_is_volatile_reg,
+	.volatile_table = &tps6594_volatile_table,
 	.read = tps6594_i2c_read,
 	.write = tps6594_i2c_write,
 };
diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
index 24b72847e..5afb1736f 100644
--- a/drivers/mfd/tps6594-spi.c
+++ b/drivers/mfd/tps6594-spi.c
@@ -70,7 +70,7 @@ static const struct regmap_config tps6594_spi_regmap_config = {
 	.reg_bits = 16,
 	.val_bits = 8,
 	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
-	.volatile_reg = tps6594_is_volatile_reg,
+	.volatile_table = &tps6594_volatile_table,
 	.reg_read = tps6594_spi_reg_read,
 	.reg_write = tps6594_spi_reg_write,
 	.use_single_read = true,
diff --git a/include/linux/mfd/tps6594.h b/include/linux/mfd/tps6594.h
index 1d8969594..6c5a2889f 100644
--- a/include/linux/mfd/tps6594.h
+++ b/include/linux/mfd/tps6594.h
@@ -1344,7 +1344,9 @@ struct tps6594 {
 	struct regmap_irq_chip_data *irq_data;
 };
 
-bool tps6594_is_volatile_reg(struct device *dev, unsigned int reg);
+extern const struct regmap_access_table tps6594_volatile_table;
+extern const struct regmap_access_table tps65224_volatile_table;
+
 int tps6594_device_init(struct tps6594 *tps, bool enable_crc);
 
 #endif /*  __LINUX_MFD_TPS6594_H */
-- 
2.25.1



From bhargav.r at ltts.com  Fri Feb 23 01:36:54 2024
From: bhargav.r at ltts.com (Bhargav Raviprakash)
Date: Fri, 23 Feb 2024 15:06:54 +0530
Subject: [PATCH v2 07/14] mfd: tps6594-core: Add TI TPS65224 PMIC core
In-Reply-To: <20240223093701.66034-1-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
Message-ID: <20240223093701.66034-8-bhargav.r@ltts.com>

Add functionality of the TPS65224 PMIC to the TPS6594 core driver. This
includes adding IRQ resource, MFD cells, and device initialization for
TPS65224.

Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
---
 drivers/mfd/tps6594-core.c | 250 ++++++++++++++++++++++++++++++++++---
 1 file changed, 232 insertions(+), 18 deletions(-)

diff --git a/drivers/mfd/tps6594-core.c b/drivers/mfd/tps6594-core.c
index 089ab8cc8..b00df00f8 100644
--- a/drivers/mfd/tps6594-core.c
+++ b/drivers/mfd/tps6594-core.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Core functions for TI TPS6594/TPS6593/LP8764 PMICs
+ * Core functions for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
@@ -278,16 +278,172 @@ static const unsigned int tps6594_irq_reg[] = {
 	TPS6594_REG_RTC_STATUS,
 };
 
+/* TPS65224 Resources */
+
+static const struct resource tps65224_regulator_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BUCK1_UVOV, TPS65224_IRQ_NAME_BUCK1_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BUCK2_UVOV, TPS65224_IRQ_NAME_BUCK2_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BUCK3_UVOV, TPS65224_IRQ_NAME_BUCK3_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BUCK4_UVOV, TPS65224_IRQ_NAME_BUCK4_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_LDO1_UVOV, TPS65224_IRQ_NAME_LDO1_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_LDO2_UVOV, TPS65224_IRQ_NAME_LDO2_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_LDO3_UVOV, TPS65224_IRQ_NAME_LDO3_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_VCCA_UVOV, TPS65224_IRQ_NAME_VCCA_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_VMON1_UVOV, TPS65224_IRQ_NAME_VMON1_UVOV),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_VMON2_UVOV, TPS65224_IRQ_NAME_VMON2_UVOV),
+};
+
+static const struct resource tps65224_pinctrl_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO1, TPS65224_IRQ_NAME_GPIO1),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO2, TPS65224_IRQ_NAME_GPIO2),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO3, TPS65224_IRQ_NAME_GPIO3),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO4, TPS65224_IRQ_NAME_GPIO4),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO5, TPS65224_IRQ_NAME_GPIO5),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_GPIO6, TPS65224_IRQ_NAME_GPIO6),
+};
+
+static const struct resource tps65224_pfsm_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_VSENSE, TPS65224_IRQ_NAME_VSENSE),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ENABLE, TPS65224_IRQ_NAME_ENABLE),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_SHORT, TPS65224_IRQ_NAME_PB_SHORT),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_FSD, TPS65224_IRQ_NAME_FSD),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_SOFT_REBOOT, TPS65224_IRQ_NAME_SOFT_REBOOT),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BIST_PASS, TPS65224_IRQ_NAME_BIST_PASS),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_EXT_CLK, TPS65224_IRQ_NAME_EXT_CLK),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_REG_UNLOCK, TPS65224_IRQ_NAME_REG_UNLOCK),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_TWARN, TPS65224_IRQ_NAME_TWARN),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_LONG, TPS65224_IRQ_NAME_PB_LONG),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_FALL, TPS65224_IRQ_NAME_PB_FALL),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_RISE, TPS65224_IRQ_NAME_PB_RISE),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_TSD_ORD, TPS65224_IRQ_NAME_TSD_ORD),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BIST_FAIL, TPS65224_IRQ_NAME_BIST_FAIL),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_REG_CRC_ERR, TPS65224_IRQ_NAME_REG_CRC_ERR),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_RECOV_CNT, TPS65224_IRQ_NAME_RECOV_CNT),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_TSD_IMM, TPS65224_IRQ_NAME_TSD_IMM),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_VCCA_OVP, TPS65224_IRQ_NAME_VCCA_OVP),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PFSM_ERR, TPS65224_IRQ_NAME_PFSM_ERR),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BG_XMON, TPS65224_IRQ_NAME_BG_XMON),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_IMM_SHUTDOWN, TPS65224_IRQ_NAME_IMM_SHUTDOWN),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ORD_SHUTDOWN, TPS65224_IRQ_NAME_ORD_SHUTDOWN),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_MCU_PWR_ERR, TPS65224_IRQ_NAME_MCU_PWR_ERR),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_SOC_PWR_ERR, TPS65224_IRQ_NAME_SOC_PWR_ERR),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_COMM_ERR, TPS65224_IRQ_NAME_COMM_ERR),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_I2C2_ERR, TPS65224_IRQ_NAME_I2C2_ERR),
+};
+
+static const struct resource tps65224_esm_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ESM_MCU_PIN, TPS65224_IRQ_NAME_ESM_MCU_PIN),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ESM_MCU_FAIL, TPS65224_IRQ_NAME_ESM_MCU_FAIL),
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ESM_MCU_RST, TPS65224_IRQ_NAME_ESM_MCU_RST),
+};
+
+static const struct resource tps65224_adc_resources[] = {
+	DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_ADC_CONV_READY, TPS65224_IRQ_NAME_ADC_CONV_READY),
+};
+
+static const struct mfd_cell tps65224_common_cells[] = {
+	MFD_CELL_RES("tps65224-adc", tps65224_adc_resources),
+	MFD_CELL_RES("tps6594-esm", tps65224_esm_resources),
+	MFD_CELL_RES("tps6594-pfsm", tps65224_pfsm_resources),
+	MFD_CELL_RES("tps6594-pinctrl", tps65224_pinctrl_resources),
+	MFD_CELL_RES("tps6594-regulator", tps65224_regulator_resources),
+};
+
+static const struct regmap_irq tps65224_irqs[] = {
+	/* INT_BUCK register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_BUCK1_UVOV, 0, TPS65224_BIT_BUCK1_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_BUCK2_UVOV, 0, TPS65224_BIT_BUCK2_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_BUCK3_UVOV, 0, TPS65224_BIT_BUCK3_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_BUCK4_UVOV, 0, TPS65224_BIT_BUCK4_UVOV_INT),
+
+	/* INT_VMON_LDO register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_LDO1_UVOV, 1, TPS65224_BIT_LDO1_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_LDO2_UVOV, 1, TPS65224_BIT_LDO2_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_LDO3_UVOV, 1, TPS65224_BIT_LDO3_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_VCCA_UVOV, 1, TPS65224_BIT_VCCA_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_VMON1_UVOV, 1, TPS65224_BIT_VMON1_UVOV_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_VMON2_UVOV, 1, TPS65224_BIT_VMON2_UVOV_INT),
+
+	/* INT_GPIO register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO1, 2, TPS65224_BIT_GPIO1_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO2, 2, TPS65224_BIT_GPIO2_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO3, 2, TPS65224_BIT_GPIO3_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO4, 2, TPS65224_BIT_GPIO4_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO5, 2, TPS65224_BIT_GPIO5_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_GPIO6, 2, TPS65224_BIT_GPIO6_INT),
+
+	/* INT_STARTUP register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_VSENSE, 3, TPS65224_BIT_VSENSE_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_ENABLE, 3, TPS6594_BIT_ENABLE_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_PB_SHORT, 3, TPS65224_BIT_PB_SHORT_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_FSD, 3, TPS6594_BIT_FSD_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_SOFT_REBOOT, 3, TPS6594_BIT_SOFT_REBOOT_INT),
+
+	/* INT_MISC register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_BIST_PASS, 4, TPS6594_BIT_BIST_PASS_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_EXT_CLK, 4, TPS6594_BIT_EXT_CLK_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_REG_UNLOCK, 4, TPS65224_BIT_REG_UNLOCK_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_TWARN, 4, TPS6594_BIT_TWARN_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_PB_LONG, 4, TPS65224_BIT_PB_LONG_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_PB_FALL, 4, TPS65224_BIT_PB_FALL_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_PB_RISE, 4, TPS65224_BIT_PB_RISE_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_ADC_CONV_READY, 4, TPS65224_BIT_ADC_CONV_READY_INT),
+
+	/* INT_MODERATE_ERR register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_TSD_ORD, 5, TPS6594_BIT_TSD_ORD_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_BIST_FAIL, 5, TPS6594_BIT_BIST_FAIL_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_REG_CRC_ERR, 5, TPS6594_BIT_REG_CRC_ERR_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_RECOV_CNT, 5, TPS6594_BIT_RECOV_CNT_INT),
+
+	/* INT_SEVERE_ERR register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_TSD_IMM, 6, TPS6594_BIT_TSD_IMM_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_VCCA_OVP, 6, TPS6594_BIT_VCCA_OVP_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_PFSM_ERR, 6, TPS6594_BIT_PFSM_ERR_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_BG_XMON, 6, TPS65224_BIT_BG_XMON_INT),
+
+	/* INT_FSM_ERR register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_IMM_SHUTDOWN, 7, TPS6594_BIT_IMM_SHUTDOWN_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_ORD_SHUTDOWN, 7, TPS6594_BIT_ORD_SHUTDOWN_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_MCU_PWR_ERR, 7, TPS6594_BIT_MCU_PWR_ERR_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_SOC_PWR_ERR, 7, TPS6594_BIT_SOC_PWR_ERR_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_COMM_ERR, 7, TPS6594_BIT_COMM_ERR_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_I2C2_ERR, 7, TPS65224_BIT_I2C2_ERR_INT),
+
+	/* INT_ESM register */
+	REGMAP_IRQ_REG(TPS65224_IRQ_ESM_MCU_PIN, 8, TPS6594_BIT_ESM_MCU_PIN_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_ESM_MCU_FAIL, 8, TPS6594_BIT_ESM_MCU_FAIL_INT),
+	REGMAP_IRQ_REG(TPS65224_IRQ_ESM_MCU_RST, 8, TPS6594_BIT_ESM_MCU_RST_INT),
+};
+
+static const unsigned int tps65224_irq_reg[] = {
+	TPS6594_REG_INT_BUCK,
+	TPS6594_REG_INT_LDO_VMON,
+	TPS6594_REG_INT_GPIO,
+	TPS6594_REG_INT_STARTUP,
+	TPS6594_REG_INT_MISC,
+	TPS6594_REG_INT_MODERATE_ERR,
+	TPS6594_REG_INT_SEVERE_ERR,
+	TPS6594_REG_INT_FSM_ERR,
+	TPS6594_REG_INT_ESM,
+};
+
 static inline unsigned int tps6594_get_irq_reg(struct regmap_irq_chip_data *data,
 					       unsigned int base, int index)
 {
 	return tps6594_irq_reg[index];
 };
 
+static inline unsigned int tps65224_get_irq_reg(struct regmap_irq_chip_data *data,
+						unsigned int base, int index)
+{
+	return tps65224_irq_reg[index];
+};
+
 static int tps6594_handle_post_irq(void *irq_drv_data)
 {
 	struct tps6594 *tps = irq_drv_data;
 	int ret = 0;
+	unsigned int regmap_reg, mask_val;
 
 	/*
 	 * When CRC is enabled, writing to a read-only bit triggers an error,
@@ -299,10 +455,17 @@ static int tps6594_handle_post_irq(void *irq_drv_data)
 	 * COMM_ADR_ERR_INT bit set. Clear immediately this bit to avoid raising
 	 * a new interrupt.
 	 */
-	if (tps->use_crc)
-		ret = regmap_write_bits(tps->regmap, TPS6594_REG_INT_COMM_ERR,
-					TPS6594_BIT_COMM_ADR_ERR_INT,
-					TPS6594_BIT_COMM_ADR_ERR_INT);
+	if (tps->use_crc) {
+		if (tps->chip_id == TPS65224) {
+			regmap_reg = TPS6594_REG_INT_FSM_ERR;
+			mask_val = TPS6594_BIT_COMM_ERR_INT;
+		} else {
+			regmap_reg = TPS6594_REG_INT_COMM_ERR;
+			mask_val = TPS6594_BIT_COMM_ADR_ERR_INT;
+		}
+
+		ret = regmap_write_bits(tps->regmap, regmap_reg, mask_val, mask_val);
+	}
 
 	return ret;
 };
@@ -319,6 +482,18 @@ static struct regmap_irq_chip tps6594_irq_chip = {
 	.handle_post_irq = tps6594_handle_post_irq,
 };
 
+static struct regmap_irq_chip tps65224_irq_chip = {
+	.ack_base = TPS6594_REG_INT_BUCK,
+	.ack_invert = 1,
+	.clear_ack = 1,
+	.init_ack_masked = 1,
+	.num_regs = ARRAY_SIZE(tps65224_irq_reg),
+	.irqs = tps65224_irqs,
+	.num_irqs = ARRAY_SIZE(tps65224_irqs),
+	.get_irq_reg = tps65224_get_irq_reg,
+	.handle_post_irq = tps6594_handle_post_irq,
+};
+
 static const struct regmap_range tps6594_volatile_ranges[] = {
 	regmap_reg_range(TPS6594_REG_INT_TOP, TPS6594_REG_STAT_READBACK_ERR),
 	regmap_reg_range(TPS6594_REG_RTC_STATUS, TPS6594_REG_RTC_STATUS),
@@ -330,17 +505,35 @@ const struct regmap_access_table tps6594_volatile_table = {
 };
 EXPORT_SYMBOL_GPL(tps6594_volatile_table);
 
+static const struct regmap_range tps65224_volatile_ranges[] = {
+	regmap_reg_range(TPS6594_REG_INT_TOP, TPS6594_REG_STAT_SEVERE_ERR),
+};
+
+const struct regmap_access_table tps65224_volatile_table = {
+	.yes_ranges = tps65224_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(tps65224_volatile_ranges),
+};
+EXPORT_SYMBOL_GPL(tps65224_volatile_table);
+
 static int tps6594_check_crc_mode(struct tps6594 *tps, bool primary_pmic)
 {
 	int ret;
+	unsigned int regmap_reg, mask_val;
+
+	if (tps->chip_id == TPS65224) {
+		regmap_reg = TPS6594_REG_CONFIG_2;
+		mask_val = TPS65224_BIT_I2C1_SPI_CRC_EN;
+	} else {
+		regmap_reg = TPS6594_REG_SERIAL_IF_CONFIG;
+		mask_val = TPS6594_BIT_I2C1_SPI_CRC_EN;
+	};
 
 	/*
 	 * Check if CRC is enabled.
 	 * Once CRC is enabled, it can't be disabled until next power cycle.
 	 */
 	tps->use_crc = true;
-	ret = regmap_test_bits(tps->regmap, TPS6594_REG_SERIAL_IF_CONFIG,
-			       TPS6594_BIT_I2C1_SPI_CRC_EN);
+	ret = regmap_test_bits(tps->regmap, regmap_reg, mask_val);
 	if (ret == 0) {
 		ret = -EIO;
 	} else if (ret > 0) {
@@ -355,6 +548,15 @@ static int tps6594_check_crc_mode(struct tps6594 *tps, bool primary_pmic)
 static int tps6594_set_crc_feature(struct tps6594 *tps)
 {
 	int ret;
+	unsigned int regmap_reg, mask_val;
+
+	if (tps->chip_id == TPS65224) {
+		regmap_reg = TPS6594_REG_CONFIG_2;
+		mask_val = TPS65224_BIT_I2C1_SPI_CRC_EN;
+	} else {
+		regmap_reg = TPS6594_REG_FSM_I2C_TRIGGERS;
+		mask_val = TPS6594_BIT_TRIGGER_I2C(2);
+	}
 
 	ret = tps6594_check_crc_mode(tps, true);
 	if (ret) {
@@ -363,8 +565,7 @@ static int tps6594_set_crc_feature(struct tps6594 *tps)
 		 * on primary PMIC.
 		 */
 		tps->use_crc = false;
-		ret = regmap_write_bits(tps->regmap, TPS6594_REG_FSM_I2C_TRIGGERS,
-					TPS6594_BIT_TRIGGER_I2C(2), TPS6594_BIT_TRIGGER_I2C(2));
+		ret = regmap_write_bits(tps->regmap, regmap_reg, mask_val, mask_val);
 		if (ret)
 			return ret;
 
@@ -420,6 +621,9 @@ int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
 {
 	struct device *dev = tps->dev;
 	int ret;
+	struct regmap_irq_chip *irq_chip;
+	const struct mfd_cell *cells;
+	int n_cells;
 
 	if (enable_crc) {
 		ret = tps6594_enable_crc(tps);
@@ -433,26 +637,35 @@ int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to set PMIC state\n");
 
-	tps6594_irq_chip.irq_drv_data = tps;
-	tps6594_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL, "%s-%ld-0x%02x",
-					       dev->driver->name, tps->chip_id, tps->reg);
+	if (tps->chip_id == TPS65224) {
+		irq_chip = &tps65224_irq_chip;
+		n_cells = ARRAY_SIZE(tps65224_common_cells);
+		cells = tps65224_common_cells;
+	} else {
+		irq_chip = &tps6594_irq_chip;
+		n_cells = ARRAY_SIZE(tps6594_common_cells);
+		cells = tps6594_common_cells;
+	}
+
+	irq_chip->irq_drv_data = tps;
+	irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-%ld-0x%02x",
+					dev->driver->name, tps->chip_id, tps->reg);
 
-	if (!tps6594_irq_chip.name)
+	if (!irq_chip->name)
 		return -ENOMEM;
 
 	ret = devm_regmap_add_irq_chip(dev, tps->regmap, tps->irq, IRQF_SHARED | IRQF_ONESHOT,
-				       0, &tps6594_irq_chip, &tps->irq_data);
+				       0, irq_chip, &tps->irq_data);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to add regmap IRQ\n");
 
-	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, tps6594_common_cells,
-				   ARRAY_SIZE(tps6594_common_cells), NULL, 0,
+	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, n_cells, NULL, 0,
 				   regmap_irq_get_domain(tps->irq_data));
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to add common child devices\n");
 
-	/* No RTC for LP8764 */
-	if (tps->chip_id != LP8764) {
+	/* No RTC for LP8764 and TPS65224 */
+	if (tps->chip_id != LP8764 && tps->chip_id != TPS65224) {
 		ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, tps6594_rtc_cells,
 					   ARRAY_SIZE(tps6594_rtc_cells), NULL, 0,
 					   regmap_irq_get_domain(tps->irq_data));
@@ -465,5 +678,6 @@ int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
 EXPORT_SYMBOL_GPL(tps6594_device_init);
 
 MODULE_AUTHOR("Julien Panis <jpanis at baylibre.com>");
+MODULE_AUTHOR("Bhargav Raviprakash <bhargav.r at ltts.com");
 MODULE_DESCRIPTION("TPS6594 Driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From anshuman.khandual at arm.com  Fri Feb 23 01:46:15 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 23 Feb 2024 15:16:15 +0530
Subject: [PATCH] arm64/hw_breakpoint: Define an ISS code for watchpoint exception
Message-ID: <20240223094615.3977323-1-anshuman.khandual@arm.com>

This defines a new ISS code macro i.e ESR_ELx_WnR for watchpoint exception.
This represents an instruction's either writing to or reading from a memory
location during an watchpoint exception, and also moves this macro into the
ESR header as required. This drops non-standard AARCH64_ESR_ACCESS_MASK.

Cc: Catalin Marinas <catalin.marinas at arm.com>
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>
---
This applies on v6.8-rc5

 arch/arm64/include/asm/esr.h           | 4 ++++
 arch/arm64/include/asm/hw_breakpoint.h | 1 -
 arch/arm64/kernel/hw_breakpoint.c      | 3 ++-
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 353fe08546cf..6c0a0b77fd2c 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -143,6 +143,10 @@
 #define ESR_ELx_CM_SHIFT	(8)
 #define ESR_ELx_CM 		(UL(1) << ESR_ELx_CM_SHIFT)
 
+/* ISS field definitions for Watchpoint exception */
+#define ESR_ELx_WnR_SHIFT	(6)
+#define ESR_ELx_WnR		(UL(1) << ESR_ELx_WnR_SHIFT)
+
 /* ISS2 field definitions for Data Aborts */
 #define ESR_ELx_TnD_SHIFT	(10)
 #define ESR_ELx_TnD 		(UL(1) << ESR_ELx_TnD_SHIFT)
diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index d67c02e53a4a..6e4862e3d238 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -67,7 +67,6 @@ static inline void decode_ctrl_reg(u32 reg,
 /* Watchpoints */
 #define ARM_BREAKPOINT_LOAD	1
 #define ARM_BREAKPOINT_STORE	2
-#define AARCH64_ESR_ACCESS_MASK	(1 << 6)
 
 /* Lengths */
 #define ARM_BREAKPOINT_LEN_1	0x1
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 86bdb2d68732..a73364a18c69 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -21,6 +21,7 @@
 
 #include <asm/current.h>
 #include <asm/debug-monitors.h>
+#include <asm/esr.h>
 #include <asm/hw_breakpoint.h>
 #include <asm/traps.h>
 #include <asm/cputype.h>
@@ -792,7 +793,7 @@ static int watchpoint_handler(unsigned long addr, unsigned long esr,
 		 * Check that the access type matches.
 		 * 0 => load, otherwise => store
 		 */
-		access = (esr & AARCH64_ESR_ACCESS_MASK) ? HW_BREAKPOINT_W :
+		access = (esr & ESR_ELx_WnR) ? HW_BREAKPOINT_W :
 			 HW_BREAKPOINT_R;
 		if (!(access & hw_breakpoint_type(wp)))
 			continue;
-- 
2.25.1



From heiko at sntech.de  Fri Feb 23 01:40:56 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 23 Feb 2024 10:40:56 +0100
Subject: [PATCH v7 31/36] drm/rockchip: inno_hdmi: Switch to HDMI connector
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-31-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-31-8f4af575fce2@kernel.org>
Message-ID: <2680721.q0ZmV6gNhb@diego>

Am Donnerstag, 22. Februar 2024, 19:14:17 CET schrieb Maxime Ripard:
> The new HDMI connector infrastructure allows to remove some boilerplate,
> especially to generate infoframes. Let's switch to it.
> 
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>

> ---
>  drivers/gpu/drm/rockchip/inno_hdmi.c | 123 ++++++++++++-----------------------
>  1 file changed, 42 insertions(+), 81 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
> index 1d2261643743..d59947679042 100644
> --- a/drivers/gpu/drm/rockchip/inno_hdmi.c
> +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
> @@ -67,9 +67,7 @@ struct inno_hdmi {
>  
>  struct inno_hdmi_connector_state {
>  	struct drm_connector_state	base;
> -	unsigned int			enc_out_format;
>  	unsigned int			colorimetry;
> -	bool				rgb_limited_range;
>  };
>  
>  static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
> @@ -257,26 +255,29 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
>  	inno_hdmi_standby(hdmi);
>  }
>  
> -static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
> -				    enum hdmi_infoframe_type type)
> +static int inno_hdmi_disable_frame(struct drm_connector *connector,
> +				   enum hdmi_infoframe_type type)
>  {
> -	struct drm_connector *connector = &hdmi->connector;
> +	struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
>  
>  	if (type != HDMI_INFOFRAME_TYPE_AVI) {
>  		drm_err(connector->dev,
>  			"Unsupported infoframe type: %u\n", type);
> -		return;
> +		return 0;
>  	}
>  
>  	hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
> +
> +	return 0;
>  }
>  
> -static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
> -				  union hdmi_infoframe *frame, enum hdmi_infoframe_type type)
> +static int inno_hdmi_upload_frame(struct drm_connector *connector,
> +				  enum hdmi_infoframe_type type,
> +				  const u8 *buffer, size_t len)
>  {
> -	struct drm_connector *connector = &hdmi->connector;
> +	struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
>  	u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
> -	ssize_t rc, i;
> +	ssize_t i;
>  
>  	if (type != HDMI_INFOFRAME_TYPE_AVI) {
>  		drm_err(connector->dev,
> @@ -284,59 +285,19 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
>  		return 0;
>  	}
>  
> -	inno_hdmi_disable_frame(hdmi, type);
> +	inno_hdmi_disable_frame(connector, type);
>  
> -	rc = hdmi_infoframe_pack(frame, packed_frame,
> -				 sizeof(packed_frame));
> -	if (rc < 0)
> -		return rc;
> -
> -	for (i = 0; i < rc; i++)
> +	for (i = 0; i < len; i++)
>  		hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
>  			    packed_frame[i]);
>  
>  	return 0;
>  }
>  
> -static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
> -				      struct drm_display_mode *mode)
> -{
> -	struct drm_connector *connector = &hdmi->connector;
> -	struct drm_connector_state *conn_state = connector->state;
> -	struct inno_hdmi_connector_state *inno_conn_state =
> -					to_inno_hdmi_conn_state(conn_state);
> -	union hdmi_infoframe frame;
> -	int rc;
> -
> -	rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
> -						      &hdmi->connector,
> -						      mode);
> -	if (rc) {
> -		inno_hdmi_disable_frame(hdmi, HDMI_INFOFRAME_TYPE_AVI);
> -		return rc;
> -	}
> -
> -	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444)
> -		frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
> -	else if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV422)
> -		frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
> -	else
> -		frame.avi.colorspace = HDMI_COLORSPACE_RGB;
> -
> -	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
> -		drm_hdmi_avi_infoframe_quant_range(&frame.avi,
> -						   connector, mode,
> -						   inno_conn_state->rgb_limited_range ?
> -						   HDMI_QUANTIZATION_RANGE_LIMITED :
> -						   HDMI_QUANTIZATION_RANGE_FULL);
> -	} else {
> -		frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
> -		frame.avi.ycc_quantization_range =
> -			HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
> -	}
> -
> -	return inno_hdmi_upload_frame(hdmi, &frame, HDMI_INFOFRAME_TYPE_AVI);
> -}
> +static const struct drm_connector_hdmi_funcs inno_hdmi_hdmi_connector_funcs = {
> +	.clear_infoframe	= inno_hdmi_disable_frame,
> +	.write_infoframe	= inno_hdmi_upload_frame,
> +};
>  
>  static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
>  {
> @@ -361,8 +322,8 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
>  		v_VIDEO_INPUT_CSP(0);
>  	hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
>  
> -	if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
> -		if (inno_conn_state->rgb_limited_range) {
> +	if (conn_state->hdmi.output_format == HDMI_COLORSPACE_RGB) {
> +		if (!conn_state->hdmi.is_full_range) {
>  			csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
>  			auto_csc = AUTO_CSC_DISABLE;
>  			c0_c2_change = C0_C2_CHANGE_DISABLE;
> @@ -380,14 +341,14 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
>  		}
>  	} else {
>  		if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
> -			if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
> +			if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) {
>  				csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
>  				auto_csc = AUTO_CSC_DISABLE;
>  				c0_c2_change = C0_C2_CHANGE_DISABLE;
>  				csc_enable = v_CSC_ENABLE;
>  			}
>  		} else {
> -			if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
> +			if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) {
>  				csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
>  				auto_csc = AUTO_CSC_DISABLE;
>  				c0_c2_change = C0_C2_CHANGE_DISABLE;
> @@ -462,10 +423,12 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
>  }
>  
>  static int inno_hdmi_setup(struct inno_hdmi *hdmi,
> -			   struct drm_display_mode *mode)
> +			   struct drm_crtc_state *new_crtc_state,
> +			   struct drm_connector_state *new_conn_state)
>  {
> -	struct drm_display_info *display = &hdmi->connector.display_info;
> -	unsigned long mpixelclock = mode->clock * 1000;
> +	struct drm_connector *connector = &hdmi->connector;
> +	struct drm_display_info *display = &connector->display_info;
> +	struct drm_display_mode *mode = &new_crtc_state->adjusted_mode;
>  
>  	/* Mute video and audio output */
>  	hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
> @@ -479,8 +442,8 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
>  
>  	inno_hdmi_config_video_csc(hdmi);
>  
> -	if (display->is_hdmi)
> -		inno_hdmi_config_video_avi(hdmi, mode);
> +	drm_atomic_helper_connector_hdmi_update_infoframes(connector,
> +							   new_conn_state->state);
>  
>  	/*
>  	 * When IP controller have configured to an accurate video
> @@ -488,13 +451,13 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
>  	 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
>  	 * clock rate, and reconfigure the DDC clock.
>  	 */
> -	inno_hdmi_i2c_init(hdmi, mpixelclock);
> +	inno_hdmi_i2c_init(hdmi, new_conn_state->hdmi.tmds_char_rate);
>  
>  	/* Unmute video and audio output */
>  	hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
>  		  v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
>  
> -	inno_hdmi_power_up(hdmi, mpixelclock);
> +	inno_hdmi_power_up(hdmi, new_conn_state->hdmi.tmds_char_rate);
>  
>  	return 0;
>  }
> @@ -546,7 +509,7 @@ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
>  	if (WARN_ON(!crtc_state))
>  		return;
>  
> -	inno_hdmi_setup(hdmi, &crtc_state->adjusted_mode);
> +	inno_hdmi_setup(hdmi, crtc_state, conn_state);
>  }
>  
>  static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
> @@ -563,7 +526,6 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
>  			       struct drm_connector_state *conn_state)
>  {
>  	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
> -	struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
>  	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
>  	u8 vic = drm_match_cea_mode(mode);
>  	struct inno_hdmi_connector_state *inno_conn_state =
> @@ -580,12 +542,7 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
>  	else
>  		inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
>  
> -	inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
> -	inno_conn_state->rgb_limited_range =
> -		drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED;
> -
> -	return  inno_hdmi_display_mode_valid(hdmi,
> -				&crtc_state->adjusted_mode) == MODE_OK ? 0 : -EINVAL;
> +	return 0;
>  }
>  
>  static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
> @@ -662,10 +619,9 @@ static void inno_hdmi_connector_reset(struct drm_connector *connector)
>  		return;
>  
>  	__drm_atomic_helper_connector_reset(connector, &inno_conn_state->base);
> +	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
>  
>  	inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
> -	inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
> -	inno_conn_state->rgb_limited_range = false;
>  }
>  
>  static struct drm_connector_state *
> @@ -698,6 +654,7 @@ static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
>  };
>  
>  static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
> +	.atomic_check = drm_atomic_helper_connector_hdmi_check,
>  	.get_modes = inno_hdmi_connector_get_modes,
>  	.mode_valid = inno_hdmi_connector_mode_valid,
>  };
> @@ -725,10 +682,14 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
>  
>  	drm_connector_helper_add(&hdmi->connector,
>  				 &inno_hdmi_connector_helper_funcs);
> -	drm_connector_init_with_ddc(drm, &hdmi->connector,
> -				    &inno_hdmi_connector_funcs,
> -				    DRM_MODE_CONNECTOR_HDMIA,
> -				    hdmi->ddc);
> +	drmm_connector_hdmi_init(drm, &hdmi->connector,
> +				 "Rockchip", "Inno HDMI",
> +				 &inno_hdmi_connector_funcs,
> +				 &inno_hdmi_hdmi_connector_funcs,
> +				 DRM_MODE_CONNECTOR_HDMIA,
> +				 hdmi->ddc,
> +				 BIT(HDMI_COLORSPACE_RGB),
> +				 8);
>  
>  	drm_connector_attach_encoder(&hdmi->connector, encoder);
>  
> 
> 






From balint.dobszay at arm.com  Fri Feb 23 01:51:30 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Fri, 23 Feb 2024 10:51:30 +0100
Subject: [PATCH v2 0/3] TEE driver for Trusted Services
Message-ID: <20240223095133.109046-1-balint.dobszay@arm.com>

This series introduces a TEE driver for Trusted Services [1].

Trusted Services is a TrustedFirmware.org project that provides a
framework for developing and deploying device Root of Trust services in
FF-A [2] Secure Partitions. The project hosts the reference
implementation of Arm Platform Security Architecture [3] for Arm
A-profile devices.

The FF-A Secure Partitions are accessible through the FF-A driver in
Linux. However, the FF-A driver doesn't have a user space interface so
user space clients currently cannot access Trusted Services. The goal of
this TEE driver is to bridge this gap and make Trusted Services
functionality accessible from user space.

Changelog:
v1[5] -> v2:
  - Refactor session handling to use XArray instead of IDR and linked
    list (the linked list was redundant as pointed out by Jens, and IDR
    is now deprecated in favor of XArray)
  - Refactor tstee_probe() to not call tee_device_unregister() before
    calling tee_device_register()
  - Address comments from Krzysztof and Jens
  - Address documentation comments from Randy
  - Use module_ffa_driver() macro instead of separate module init / exit
    functions
  - Reformat max line length 100 -> 80

RFC[4] -> v1:
  - Add patch for moving pool_op helper functions to the TEE subsystem,
    as suggested by Jens
  - Address comments from Sumit, add patch for documentation

[1] https://www.trustedfirmware.org/projects/trusted-services/
[2] https://developer.arm.com/documentation/den0077/
[3] https://www.arm.com/architecture/security-features/platform-security
[4] https://lore.kernel.org/linux-arm-kernel/20230927152145.111777-1-balint.dobszay at arm.com/
[5] https://lore.kernel.org/lkml/20240213145239.379875-1-balint.dobszay at arm.com/


Balint Dobszay (3):
  tee: optee: Move pool_op helper functions
  tee: tstee: Add Trusted Services TEE driver
  Documentation: tee: Add TS-TEE driver

 Documentation/tee/index.rst       |   1 +
 Documentation/tee/ts-tee.rst      |  71 +++++
 drivers/tee/Kconfig               |   1 +
 drivers/tee/Makefile              |   1 +
 drivers/tee/optee/core.c          |  64 ----
 drivers/tee/optee/ffa_abi.c       |   6 +-
 drivers/tee/optee/optee_private.h |  12 -
 drivers/tee/optee/smc_abi.c       |  11 +-
 drivers/tee/tee_shm.c             |  65 ++++
 drivers/tee/tstee/Kconfig         |  11 +
 drivers/tee/tstee/Makefile        |   3 +
 drivers/tee/tstee/core.c          | 490 ++++++++++++++++++++++++++++++
 drivers/tee/tstee/tstee_private.h |  94 ++++++
 include/linux/tee_drv.h           |  11 +
 include/uapi/linux/tee.h          |   1 +
 15 files changed, 758 insertions(+), 84 deletions(-)
 create mode 100644 Documentation/tee/ts-tee.rst
 create mode 100644 drivers/tee/tstee/Kconfig
 create mode 100644 drivers/tee/tstee/Makefile
 create mode 100644 drivers/tee/tstee/core.c
 create mode 100644 drivers/tee/tstee/tstee_private.h

-- 
2.34.1



From balint.dobszay at arm.com  Fri Feb 23 01:51:31 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Fri, 23 Feb 2024 10:51:31 +0100
Subject: [PATCH v2 1/3] tee: optee: Move pool_op helper functions
In-Reply-To: <20240223095133.109046-1-balint.dobszay@arm.com>
References: <20240223095133.109046-1-balint.dobszay@arm.com>
Message-ID: <20240223095133.109046-2-balint.dobszay@arm.com>

Move the pool alloc and free helper functions from the OP-TEE driver to
the TEE subsystem, since these could be reused in other TEE drivers.
This patch is not supposed to change behavior, it's only reorganizing
the code.

Suggested-by: Jens Wiklander <jens.wiklander at linaro.org>
Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
---
 drivers/tee/optee/core.c          | 64 ------------------------------
 drivers/tee/optee/ffa_abi.c       |  6 +--
 drivers/tee/optee/optee_private.h | 12 ------
 drivers/tee/optee/smc_abi.c       | 11 +++---
 drivers/tee/tee_shm.c             | 65 +++++++++++++++++++++++++++++++
 include/linux/tee_drv.h           | 11 ++++++
 6 files changed, 85 insertions(+), 84 deletions(-)

diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 3aed554bc8d8..9390f21f9902 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -9,7 +9,6 @@
 #include <linux/crash_dump.h>
 #include <linux/errno.h>
 #include <linux/io.h>
-#include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@@ -17,69 +16,6 @@
 #include <linux/types.h>
 #include "optee_private.h"
 
-int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-			       size_t size, size_t align,
-			       int (*shm_register)(struct tee_context *ctx,
-						   struct tee_shm *shm,
-						   struct page **pages,
-						   size_t num_pages,
-						   unsigned long start))
-{
-	size_t nr_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE;
-	struct page **pages;
-	unsigned int i;
-	int rc = 0;
-
-	/*
-	 * Ignore alignment since this is already going to be page aligned
-	 * and there's no need for any larger alignment.
-	 */
-	shm->kaddr = alloc_pages_exact(nr_pages * PAGE_SIZE,
-				       GFP_KERNEL | __GFP_ZERO);
-	if (!shm->kaddr)
-		return -ENOMEM;
-
-	shm->paddr = virt_to_phys(shm->kaddr);
-	shm->size = nr_pages * PAGE_SIZE;
-
-	pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL);
-	if (!pages) {
-		rc = -ENOMEM;
-		goto err;
-	}
-
-	for (i = 0; i < nr_pages; i++)
-		pages[i] = virt_to_page((u8 *)shm->kaddr + i * PAGE_SIZE);
-
-	shm->pages = pages;
-	shm->num_pages = nr_pages;
-
-	if (shm_register) {
-		rc = shm_register(shm->ctx, shm, pages, nr_pages,
-				  (unsigned long)shm->kaddr);
-		if (rc)
-			goto err;
-	}
-
-	return 0;
-err:
-	free_pages_exact(shm->kaddr, shm->size);
-	shm->kaddr = NULL;
-	return rc;
-}
-
-void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-			       int (*shm_unregister)(struct tee_context *ctx,
-						     struct tee_shm *shm))
-{
-	if (shm_unregister)
-		shm_unregister(shm->ctx, shm);
-	free_pages_exact(shm->kaddr, shm->size);
-	shm->kaddr = NULL;
-	kfree(shm->pages);
-	shm->pages = NULL;
-}
-
 static void optee_bus_scan(struct work_struct *work)
 {
 	WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP));
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index ecb5eb079408..ee11918a2b35 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -374,14 +374,14 @@ static int optee_ffa_shm_unregister_supp(struct tee_context *ctx,
 static int pool_ffa_op_alloc(struct tee_shm_pool *pool,
 			     struct tee_shm *shm, size_t size, size_t align)
 {
-	return optee_pool_op_alloc_helper(pool, shm, size, align,
-					  optee_ffa_shm_register);
+	return tee_shm_pool_op_alloc_helper(pool, shm, size, align,
+					    optee_ffa_shm_register);
 }
 
 static void pool_ffa_op_free(struct tee_shm_pool *pool,
 			     struct tee_shm *shm)
 {
-	optee_pool_op_free_helper(pool, shm, optee_ffa_shm_unregister);
+	tee_shm_pool_op_free_helper(pool, shm, optee_ffa_shm_unregister);
 }
 
 static void pool_ffa_op_destroy_pool(struct tee_shm_pool *pool)
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 7a5243c78b55..a153285a1919 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -283,18 +283,6 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
 int optee_enumerate_devices(u32 func);
 void optee_unregister_devices(void);
 
-int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-			       size_t size, size_t align,
-			       int (*shm_register)(struct tee_context *ctx,
-						   struct tee_shm *shm,
-						   struct page **pages,
-						   size_t num_pages,
-						   unsigned long start));
-void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-			       int (*shm_unregister)(struct tee_context *ctx,
-						     struct tee_shm *shm));
-
-
 void optee_remove_common(struct optee *optee);
 int optee_open(struct tee_context *ctx, bool cap_memref_null);
 void optee_release(struct tee_context *ctx);
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
index a37f87087e5c..b0c616b6870d 100644
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -592,19 +592,20 @@ static int pool_op_alloc(struct tee_shm_pool *pool,
 	 * to be registered with OP-TEE.
 	 */
 	if (shm->flags & TEE_SHM_PRIV)
-		return optee_pool_op_alloc_helper(pool, shm, size, align, NULL);
+		return tee_shm_pool_op_alloc_helper(pool, shm, size, align,
+						    NULL);
 
-	return optee_pool_op_alloc_helper(pool, shm, size, align,
-					  optee_shm_register);
+	return tee_shm_pool_op_alloc_helper(pool, shm, size, align,
+					    optee_shm_register);
 }
 
 static void pool_op_free(struct tee_shm_pool *pool,
 			 struct tee_shm *shm)
 {
 	if (!(shm->flags & TEE_SHM_PRIV))
-		optee_pool_op_free_helper(pool, shm, optee_shm_unregister);
+		tee_shm_pool_op_free_helper(pool, shm, optee_shm_unregister);
 	else
-		optee_pool_op_free_helper(pool, shm, NULL);
+		tee_shm_pool_op_free_helper(pool, shm, NULL);
 }
 
 static void pool_op_destroy_pool(struct tee_shm_pool *pool)
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c
index 731d9028b67f..641aad92ffe2 100644
--- a/drivers/tee/tee_shm.c
+++ b/drivers/tee/tee_shm.c
@@ -202,6 +202,71 @@ struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size)
 }
 EXPORT_SYMBOL_GPL(tee_shm_alloc_priv_buf);
 
+int tee_shm_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
+				 size_t size, size_t align,
+				 int (*shm_register)(struct tee_context *ctx,
+						     struct tee_shm *shm,
+						     struct page **pages,
+						     size_t num_pages,
+						     unsigned long start))
+{
+	size_t nr_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE;
+	struct page **pages;
+	unsigned int i;
+	int rc = 0;
+
+	/*
+	 * Ignore alignment since this is already going to be page aligned
+	 * and there's no need for any larger alignment.
+	 */
+	shm->kaddr = alloc_pages_exact(nr_pages * PAGE_SIZE,
+				       GFP_KERNEL | __GFP_ZERO);
+	if (!shm->kaddr)
+		return -ENOMEM;
+
+	shm->paddr = virt_to_phys(shm->kaddr);
+	shm->size = nr_pages * PAGE_SIZE;
+
+	pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL);
+	if (!pages) {
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < nr_pages; i++)
+		pages[i] = virt_to_page((u8 *)shm->kaddr + i * PAGE_SIZE);
+
+	shm->pages = pages;
+	shm->num_pages = nr_pages;
+
+	if (shm_register) {
+		rc = shm_register(shm->ctx, shm, pages, nr_pages,
+				  (unsigned long)shm->kaddr);
+		if (rc)
+			goto err;
+	}
+
+	return 0;
+err:
+	free_pages_exact(shm->kaddr, shm->size);
+	shm->kaddr = NULL;
+	return rc;
+}
+EXPORT_SYMBOL_GPL(tee_shm_pool_op_alloc_helper);
+
+void tee_shm_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
+				 int (*shm_unregister)(struct tee_context *ctx,
+						       struct tee_shm *shm))
+{
+	if (shm_unregister)
+		shm_unregister(shm->ctx, shm);
+	free_pages_exact(shm->kaddr, shm->size);
+	shm->kaddr = NULL;
+	kfree(shm->pages);
+	shm->pages = NULL;
+}
+EXPORT_SYMBOL_GPL(tee_shm_pool_op_free_helper);
+
 static struct tee_shm *
 register_shm_helper(struct tee_context *ctx, struct iov_iter *iter, u32 flags,
 		    int id)
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index 911ddf92dcee..4cf402424e71 100644
--- a/include/linux/tee_drv.h
+++ b/include/linux/tee_drv.h
@@ -275,6 +275,17 @@ void *tee_get_drvdata(struct tee_device *teedev);
 struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size);
 struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size);
 
+int tee_shm_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
+				 size_t size, size_t align,
+				 int (*shm_register)(struct tee_context *ctx,
+						     struct tee_shm *shm,
+						     struct page **pages,
+						     size_t num_pages,
+						     unsigned long start));
+void tee_shm_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
+				 int (*shm_unregister)(struct tee_context *ctx,
+						       struct tee_shm *shm));
+
 struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx,
 					    void *addr, size_t length);
 
-- 
2.34.1



From balint.dobszay at arm.com  Fri Feb 23 01:51:32 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Fri, 23 Feb 2024 10:51:32 +0100
Subject: [PATCH v2 2/3] tee: tstee: Add Trusted Services TEE driver
In-Reply-To: <20240223095133.109046-1-balint.dobszay@arm.com>
References: <20240223095133.109046-1-balint.dobszay@arm.com>
Message-ID: <20240223095133.109046-3-balint.dobszay@arm.com>

The Trusted Services project provides a framework for developing and
deploying device Root of Trust services in FF-A Secure Partitions. The
FF-A SPs are accessible through the FF-A driver, but this doesn't
provide a user space interface. The goal of this TEE driver is to make
Trusted Services SPs accessible for user space clients.

All TS SPs have the same FF-A UUID, it identifies the RPC protocol used
by TS. A TS SP can host one or more services, a service is identified by
its service UUID. The same type of service cannot be present twice in
the same SP. During SP boot each service in an SP is assigned an
interface ID, this is just a short ID to simplify message addressing.
There is 1:1 mapping between TS SPs and TEE devices, i.e. a separate TEE
device is registered for each TS SP. This is required since contrary to
the generic TEE design where memory is shared with the whole TEE
implementation, in case of FF-A, memory is shared with a specific SP. A
user space client has to be able to separately share memory with each SP
based on its endpoint ID.

Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
---
 drivers/tee/Kconfig               |   1 +
 drivers/tee/Makefile              |   1 +
 drivers/tee/tstee/Kconfig         |  11 +
 drivers/tee/tstee/Makefile        |   3 +
 drivers/tee/tstee/core.c          | 490 ++++++++++++++++++++++++++++++
 drivers/tee/tstee/tstee_private.h |  94 ++++++
 include/uapi/linux/tee.h          |   1 +
 7 files changed, 601 insertions(+)
 create mode 100644 drivers/tee/tstee/Kconfig
 create mode 100644 drivers/tee/tstee/Makefile
 create mode 100644 drivers/tee/tstee/core.c
 create mode 100644 drivers/tee/tstee/tstee_private.h

diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig
index 73a147202e88..61b507c18780 100644
--- a/drivers/tee/Kconfig
+++ b/drivers/tee/Kconfig
@@ -15,5 +15,6 @@ if TEE
 
 source "drivers/tee/optee/Kconfig"
 source "drivers/tee/amdtee/Kconfig"
+source "drivers/tee/tstee/Kconfig"
 
 endif
diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
index 68da044afbfa..5488cba30bd2 100644
--- a/drivers/tee/Makefile
+++ b/drivers/tee/Makefile
@@ -5,3 +5,4 @@ tee-objs += tee_shm.o
 tee-objs += tee_shm_pool.o
 obj-$(CONFIG_OPTEE) += optee/
 obj-$(CONFIG_AMDTEE) += amdtee/
+obj-$(CONFIG_ARM_TSTEE) += tstee/
diff --git a/drivers/tee/tstee/Kconfig b/drivers/tee/tstee/Kconfig
new file mode 100644
index 000000000000..d32f91d47398
--- /dev/null
+++ b/drivers/tee/tstee/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config ARM_TSTEE
+	tristate "Arm Trusted Services TEE driver"
+	depends on ARM_FFA_TRANSPORT
+	default n
+	help
+	  The Trusted Services project provides a framework for developing and
+	  deploying device Root of Trust services in FF-A Secure Partitions.
+	  This driver provides an interface to make Trusted Services Secure
+	  Partitions accessible for user space clients, since the FF-A driver
+	  doesn't implement a user space interface directly.
diff --git a/drivers/tee/tstee/Makefile b/drivers/tee/tstee/Makefile
new file mode 100644
index 000000000000..5227020ebd30
--- /dev/null
+++ b/drivers/tee/tstee/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+arm-tstee-objs := core.o
+obj-$(CONFIG_ARM_TSTEE) = arm-tstee.o
diff --git a/drivers/tee/tstee/core.c b/drivers/tee/tstee/core.c
new file mode 100644
index 000000000000..2932be017dbe
--- /dev/null
+++ b/drivers/tee/tstee/core.c
@@ -0,0 +1,490 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, Arm Limited
+ */
+
+#define DRIVER_NAME "Arm TSTEE"
+#define pr_fmt(fmt) DRIVER_NAME ": " fmt
+
+#include <linux/arm_ffa.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/limits.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/tee_drv.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+
+#include "tstee_private.h"
+
+#define FFA_DIRECT_REQ_ARG_NUM 5
+#define FFA_INVALID_MEM_HANDLE U64_MAX
+
+static void arg_list_to_ffa_data(const u32 *args,
+				 struct ffa_send_direct_data *data)
+{
+	data->data0 = args[0];
+	data->data1 = args[1];
+	data->data2 = args[2];
+	data->data3 = args[3];
+	data->data4 = args[4];
+}
+
+static void arg_list_from_ffa_data(const struct ffa_send_direct_data *data,
+				   u32 *args)
+{
+	args[0] = lower_32_bits(data->data0);
+	args[1] = lower_32_bits(data->data1);
+	args[2] = lower_32_bits(data->data2);
+	args[3] = lower_32_bits(data->data3);
+	args[4] = lower_32_bits(data->data4);
+}
+
+static void tstee_get_version(struct tee_device *teedev,
+			      struct tee_ioctl_version_data *vers)
+{
+	struct tstee *tstee = tee_get_drvdata(teedev);
+	struct tee_ioctl_version_data v = {
+		.impl_id = TEE_IMPL_ID_TSTEE,
+		/* FF-A endpoint ID only uses the lower 16 bits */
+		.impl_caps = lower_16_bits(tstee->ffa_dev->vm_id),
+		.gen_caps = 0,
+	};
+
+	*vers = v;
+}
+
+static int tstee_open(struct tee_context *ctx)
+{
+	struct ts_context_data *ctxdata;
+
+	ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
+	if (!ctxdata)
+		return -ENOMEM;
+
+	mutex_init(&ctxdata->mutex);
+	xa_init_flags(&ctxdata->sess_list, XA_FLAGS_ALLOC);
+
+	ctx->data = ctxdata;
+
+	return 0;
+}
+
+static void tstee_release(struct tee_context *ctx)
+{
+	struct ts_context_data *ctxdata = ctx->data;
+	struct ts_session *sess;
+	unsigned long idx;
+
+	if (!ctxdata)
+		return;
+
+	xa_for_each(&ctxdata->sess_list, idx, sess) {
+		xa_erase(&ctxdata->sess_list, idx);
+		kfree(sess);
+	}
+
+	xa_destroy(&ctxdata->sess_list);
+	mutex_destroy(&ctxdata->mutex);
+
+	kfree(ctxdata);
+	ctx->data = NULL;
+}
+
+static int tstee_open_session(struct tee_context *ctx,
+			      struct tee_ioctl_open_session_arg *arg,
+			      struct tee_param *param __always_unused)
+{
+	struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+	struct ffa_device *ffa_dev = tstee->ffa_dev;
+	struct ts_context_data *ctxdata = ctx->data;
+	struct ffa_send_direct_data ffa_data;
+	struct ts_session *sess = NULL;
+	u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+	u32 sess_id;
+	int rc;
+
+	ffa_args[TS_RPC_CTRL_REG] =
+		TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+					      TS_RPC_OP_SERVICE_INFO);
+
+	memcpy(ffa_args + TS_RPC_SERVICE_INFO_UUID0, arg->uuid, UUID_SIZE);
+
+	arg_list_to_ffa_data(ffa_args, &ffa_data);
+	rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+	if (rc)
+		return rc;
+
+	arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+	if (ffa_args[TS_RPC_SERVICE_INFO_RPC_STATUS] != TS_RPC_OK)
+		return -ENODEV;
+
+	if (ffa_args[TS_RPC_SERVICE_INFO_IFACE] > U8_MAX)
+		return -EINVAL;
+
+	sess = kzalloc(sizeof(*sess), GFP_KERNEL);
+	if (!sess)
+		return -ENOMEM;
+
+	sess->iface_id = ffa_args[TS_RPC_SERVICE_INFO_IFACE];
+
+	rc = xa_alloc(&ctxdata->sess_list, &sess_id, sess, xa_limit_32b,
+		      GFP_KERNEL);
+	if (rc) {
+		kfree(sess);
+		return rc;
+	}
+
+	arg->session = sess_id;
+	arg->ret = 0;
+
+	return 0;
+}
+
+static int tstee_close_session(struct tee_context *ctx, u32 session)
+{
+	struct ts_context_data *ctxdata = ctx->data;
+	struct ts_session *sess;
+
+	mutex_lock(&ctxdata->mutex);
+	sess = xa_erase(&ctxdata->sess_list, session);
+	mutex_unlock(&ctxdata->mutex);
+	if (!sess)
+		return -EINVAL;
+
+	kfree(sess);
+
+	return 0;
+}
+
+static int tstee_invoke_func(struct tee_context *ctx,
+			     struct tee_ioctl_invoke_arg *arg,
+			     struct tee_param *param)
+{
+	struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+	struct ffa_device *ffa_dev = tstee->ffa_dev;
+	struct ts_context_data *ctxdata = ctx->data;
+	struct ffa_send_direct_data ffa_data;
+	struct tee_shm *shm = NULL;
+	struct ts_session *sess;
+	u32 req_len, ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+	int shm_id, rc;
+	u8 iface_id;
+	u64 handle;
+	u16 opcode;
+
+	mutex_lock(&ctxdata->mutex);
+	sess = xa_load(&ctxdata->sess_list, arg->session);
+
+	/*
+	 * Do this while holding the mutex to make sure that the session wasn't
+	 * closed meanwhile
+	 */
+	if (sess)
+		iface_id = sess->iface_id;
+
+	mutex_unlock(&ctxdata->mutex);
+	if (!sess)
+		return -EINVAL;
+
+	opcode = lower_16_bits(arg->func);
+	shm_id = lower_32_bits(param[0].u.value.a);
+	req_len = lower_32_bits(param[0].u.value.b);
+
+	if (shm_id != 0) {
+		shm = tee_shm_get_from_id(ctx, shm_id);
+		if (IS_ERR(shm))
+			return PTR_ERR(shm);
+
+		if (shm->size < req_len) {
+			pr_err("request doesn't fit into shared memory buffer\n");
+			rc = -EINVAL;
+			goto out;
+		}
+
+		handle = shm->sec_world_id;
+	} else {
+		handle = FFA_INVALID_MEM_HANDLE;
+	}
+
+	ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(iface_id,
+								  opcode);
+	ffa_args[TS_RPC_SERVICE_MEM_HANDLE_LSW] = lower_32_bits(handle);
+	ffa_args[TS_RPC_SERVICE_MEM_HANDLE_MSW] = upper_32_bits(handle);
+	ffa_args[TS_RPC_SERVICE_REQ_LEN] = req_len;
+	ffa_args[TS_RPC_SERVICE_CLIENT_ID] = 0;
+
+	arg_list_to_ffa_data(ffa_args, &ffa_data);
+	rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+	if (rc)
+		goto out;
+
+	arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+	if (ffa_args[TS_RPC_SERVICE_RPC_STATUS] != TS_RPC_OK) {
+		pr_err("invoke_func rpc status: %d\n",
+		       ffa_args[TS_RPC_SERVICE_RPC_STATUS]);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	arg->ret = ffa_args[TS_RPC_SERVICE_STATUS];
+	if (shm && shm->size >= ffa_args[TS_RPC_SERVICE_RESP_LEN])
+		param[0].u.value.a = ffa_args[TS_RPC_SERVICE_RESP_LEN];
+
+out:
+	if (shm)
+		tee_shm_put(shm);
+
+	return rc;
+}
+
+static int tstee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
+			      struct page **pages, size_t num_pages,
+			      unsigned long start __always_unused)
+{
+	struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+	struct ffa_device *ffa_dev = tstee->ffa_dev;
+	struct ffa_mem_region_attributes mem_attr = {
+		.receiver = tstee->ffa_dev->vm_id,
+		.attrs = FFA_MEM_RW,
+		.flag = 0,
+	};
+	struct ffa_mem_ops_args mem_args = {
+		.attrs = &mem_attr,
+		.use_txbuf = true,
+		.nattrs = 1,
+		.flags = 0,
+	};
+	struct ffa_send_direct_data ffa_data;
+	struct sg_table sgt;
+	u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+	int rc;
+
+	rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0,
+				       num_pages * PAGE_SIZE, GFP_KERNEL);
+	if (rc)
+		return rc;
+
+	mem_args.sg = sgt.sgl;
+	rc = ffa_dev->ops->mem_ops->memory_share(&mem_args);
+	sg_free_table(&sgt);
+	if (rc)
+		return rc;
+
+	shm->sec_world_id = mem_args.g_handle;
+
+	ffa_args[TS_RPC_CTRL_REG] =
+			TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+						      TS_RPC_OP_RETRIEVE_MEM);
+	ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_LSW] =
+			lower_32_bits(shm->sec_world_id);
+	ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_MSW] =
+			upper_32_bits(shm->sec_world_id);
+	ffa_args[TS_RPC_RETRIEVE_MEM_TAG_LSW] = 0;
+	ffa_args[TS_RPC_RETRIEVE_MEM_TAG_MSW] = 0;
+
+	arg_list_to_ffa_data(ffa_args, &ffa_data);
+	rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+	if (rc) {
+		(void)ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id,
+							    0);
+		return rc;
+	}
+
+	arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+	if (ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS] != TS_RPC_OK) {
+		pr_err("shm_register rpc status: %d\n",
+		       ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS]);
+		ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int tstee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
+{
+	struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+	struct ffa_device *ffa_dev = tstee->ffa_dev;
+	struct ffa_send_direct_data ffa_data;
+	u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+	int rc;
+
+	ffa_args[TS_RPC_CTRL_REG] =
+			TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+						      TS_RPC_OP_RELINQ_MEM);
+	ffa_args[TS_RPC_RELINQ_MEM_HANDLE_LSW] =
+			lower_32_bits(shm->sec_world_id);
+	ffa_args[TS_RPC_RELINQ_MEM_HANDLE_MSW] =
+			upper_32_bits(shm->sec_world_id);
+
+	arg_list_to_ffa_data(ffa_args, &ffa_data);
+	rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+	if (rc)
+		return rc;
+	arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+	if (ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS] != TS_RPC_OK) {
+		pr_err("shm_unregister rpc status: %d\n",
+		       ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS]);
+		return -EINVAL;
+	}
+
+	rc = ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
+
+	return rc;
+}
+
+static const struct tee_driver_ops tstee_ops = {
+	.get_version = tstee_get_version,
+	.open = tstee_open,
+	.release = tstee_release,
+	.open_session = tstee_open_session,
+	.close_session = tstee_close_session,
+	.invoke_func = tstee_invoke_func,
+	.shm_register = tstee_shm_register,
+	.shm_unregister = tstee_shm_unregister,
+};
+
+static const struct tee_desc tstee_desc = {
+	.name = "tstee-clnt",
+	.ops = &tstee_ops,
+	.owner = THIS_MODULE,
+};
+
+static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
+			 size_t size, size_t align)
+{
+	return tee_shm_pool_op_alloc_helper(pool, shm, size, align,
+					    tstee_shm_register);
+}
+
+static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm)
+{
+	tee_shm_pool_op_free_helper(pool, shm, tstee_shm_unregister);
+}
+
+static void pool_op_destroy_pool(struct tee_shm_pool *pool)
+{
+	kfree(pool);
+}
+
+static const struct tee_shm_pool_ops pool_ops = {
+	.alloc = pool_op_alloc,
+	.free = pool_op_free,
+	.destroy_pool = pool_op_destroy_pool,
+};
+
+static struct tee_shm_pool *tstee_create_shm_pool(void)
+{
+	struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+
+	if (!pool)
+		return ERR_PTR(-ENOMEM);
+
+	pool->ops = &pool_ops;
+
+	return pool;
+}
+
+static bool tstee_check_rpc_compatible(struct ffa_device *ffa_dev)
+{
+	struct ffa_send_direct_data ffa_data;
+	u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+
+	ffa_args[TS_RPC_CTRL_REG] =
+			TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+						      TS_RPC_OP_GET_VERSION);
+
+	arg_list_to_ffa_data(ffa_args, &ffa_data);
+	if (ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data))
+		return false;
+
+	arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+	return ffa_args[TS_RPC_GET_VERSION_RESP] == TS_RPC_PROTOCOL_VERSION;
+}
+
+static int tstee_probe(struct ffa_device *ffa_dev)
+{
+	struct tstee *tstee;
+	int rc;
+
+	ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev);
+
+	if (!tstee_check_rpc_compatible(ffa_dev))
+		return -EINVAL;
+
+	tstee = kzalloc(sizeof(*tstee), GFP_KERNEL);
+	if (!tstee)
+		return -ENOMEM;
+
+	tstee->ffa_dev = ffa_dev;
+
+	tstee->pool = tstee_create_shm_pool();
+	if (IS_ERR(tstee->pool)) {
+		rc = PTR_ERR(tstee->pool);
+		tstee->pool = NULL;
+		goto err_free_tstee;
+	}
+
+	tstee->teedev = tee_device_alloc(&tstee_desc, NULL, tstee->pool, tstee);
+	if (IS_ERR(tstee->teedev)) {
+		rc = PTR_ERR(tstee->teedev);
+		tstee->teedev = NULL;
+		goto err_free_pool;
+	}
+
+	rc = tee_device_register(tstee->teedev);
+	if (rc)
+		goto err_unreg_teedev;
+
+	ffa_dev_set_drvdata(ffa_dev, tstee);
+
+	return 0;
+
+err_unreg_teedev:
+	tee_device_unregister(tstee->teedev);
+err_free_pool:
+	tee_shm_pool_free(tstee->pool);
+err_free_tstee:
+	kfree(tstee);
+	return rc;
+}
+
+static void tstee_remove(struct ffa_device *ffa_dev)
+{
+	struct tstee *tstee = ffa_dev->dev.driver_data;
+
+	tee_device_unregister(tstee->teedev);
+	tee_shm_pool_free(tstee->pool);
+	kfree(tstee);
+}
+
+static const struct ffa_device_id tstee_device_ids[] = {
+	/* TS RPC protocol UUID: bdcd76d7-825e-4751-963b-86d4f84943ac */
+	{ TS_RPC_UUID },
+	{}
+};
+
+static struct ffa_driver tstee_driver = {
+	.name = "arm_tstee",
+	.probe = tstee_probe,
+	.remove = tstee_remove,
+	.id_table = tstee_device_ids,
+};
+
+module_ffa_driver(tstee_driver);
+
+MODULE_AUTHOR("Balint Dobszay <balint.dobszay at arm.com>");
+MODULE_DESCRIPTION("Arm Trusted Services TEE driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tee/tstee/tstee_private.h b/drivers/tee/tstee/tstee_private.h
new file mode 100644
index 000000000000..6d24cf0dbbc2
--- /dev/null
+++ b/drivers/tee/tstee/tstee_private.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023, Arm Limited
+ */
+
+#ifndef TSTEE_PRIVATE_H
+#define TSTEE_PRIVATE_H
+
+#include <linux/arm_ffa.h>
+#include <linux/bitops.h>
+#include <linux/tee_drv.h>
+#include <linux/types.h>
+#include <linux/uuid.h>
+#include <linux/xarray.h>
+
+/*
+ * The description of the ABI implemented in this file is available at
+ * https://trusted-services.readthedocs.io/en/v1.0.0/developer/service-access-protocols.html#abi
+ */
+
+/* UUID of this protocol */
+#define TS_RPC_UUID UUID_INIT(0xbdcd76d7, 0x825e, 0x4751, \
+			      0x96, 0x3b, 0x86, 0xd4, 0xf8, 0x49, 0x43, 0xac)
+
+/* Protocol version*/
+#define TS_RPC_PROTOCOL_VERSION		(1)
+
+/* Status codes */
+#define TS_RPC_OK			(0)
+
+/* RPC control register */
+#define TS_RPC_CTRL_REG			(0)
+#define OPCODE_MASK			GENMASK(15, 0)
+#define IFACE_ID_MASK			GENMASK(23, 16)
+#define TS_RPC_CTRL_OPCODE(x)		((u16)(FIELD_GET(OPCODE_MASK, (x))))
+#define TS_RPC_CTRL_IFACE_ID(x)		((u8)(FIELD_GET(IFACE_ID_MASK, (x))))
+#define TS_RPC_CTRL_PACK_IFACE_OPCODE(i, o)	\
+	(FIELD_PREP(IFACE_ID_MASK, (i)) | FIELD_PREP(OPCODE_MASK, (o)))
+#define TS_RPC_CTRL_SAP_RC		BIT(30)
+#define TS_RPC_CTRL_SAP_ERR		BIT(31)
+
+/* Interface ID for RPC management operations */
+#define TS_RPC_MGMT_IFACE_ID		(0xff)
+
+/* Management calls */
+#define TS_RPC_OP_GET_VERSION		(0x0000)
+#define TS_RPC_GET_VERSION_RESP		(1)
+
+#define TS_RPC_OP_RETRIEVE_MEM		(0x0001)
+#define TS_RPC_RETRIEVE_MEM_HANDLE_LSW	(1)
+#define TS_RPC_RETRIEVE_MEM_HANDLE_MSW	(2)
+#define TS_RPC_RETRIEVE_MEM_TAG_LSW	(3)
+#define TS_RPC_RETRIEVE_MEM_TAG_MSW	(4)
+#define TS_RPC_RETRIEVE_MEM_RPC_STATUS	(1)
+
+#define TS_RPC_OP_RELINQ_MEM		(0x0002)
+#define TS_RPC_RELINQ_MEM_HANDLE_LSW	(1)
+#define TS_RPC_RELINQ_MEM_HANDLE_MSW	(2)
+#define TS_RPC_RELINQ_MEM_RPC_STATUS	(1)
+
+#define TS_RPC_OP_SERVICE_INFO		(0x0003)
+#define TS_RPC_SERVICE_INFO_UUID0	(1)
+#define TS_RPC_SERVICE_INFO_UUID1	(2)
+#define TS_RPC_SERVICE_INFO_UUID2	(3)
+#define TS_RPC_SERVICE_INFO_UUID3	(4)
+#define TS_RPC_SERVICE_INFO_RPC_STATUS	(1)
+#define TS_RPC_SERVICE_INFO_IFACE	(2)
+
+/* Service call */
+#define TS_RPC_SERVICE_MEM_HANDLE_LSW	(1)
+#define TS_RPC_SERVICE_MEM_HANDLE_MSW	(2)
+#define TS_RPC_SERVICE_REQ_LEN		(3)
+#define TS_RPC_SERVICE_CLIENT_ID	(4)
+#define TS_RPC_SERVICE_RPC_STATUS	(1)
+#define TS_RPC_SERVICE_STATUS		(2)
+#define TS_RPC_SERVICE_RESP_LEN		(3)
+
+struct tstee {
+	struct ffa_device *ffa_dev;
+	struct tee_device *teedev;
+	struct tee_shm_pool *pool;
+};
+
+struct ts_session {
+	u8 iface_id;
+};
+
+struct ts_context_data {
+	struct xarray sess_list;
+	/* Serializes access to the session list */
+	struct mutex mutex;
+};
+
+#endif /* TSTEE_PRIVATE_H */
diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
index 23e57164693c..d0430bee8292 100644
--- a/include/uapi/linux/tee.h
+++ b/include/uapi/linux/tee.h
@@ -56,6 +56,7 @@
  */
 #define TEE_IMPL_ID_OPTEE	1
 #define TEE_IMPL_ID_AMDTEE	2
+#define TEE_IMPL_ID_TSTEE	3
 
 /*
  * OP-TEE specific capabilities
-- 
2.34.1



From anup at brainfault.org  Fri Feb 23 01:52:59 2024
From: anup at brainfault.org (Anup Patel)
Date: Fri, 23 Feb 2024 15:22:59 +0530
Subject: [PATCH v14 11/18] irqchip: Add RISC-V incoming MSI controller
 early driver
In-Reply-To: <87a5nreg94.ffs@tglx>
References: <20240222094006.1030709-1-apatel@ventanamicro.com>
 <20240222094006.1030709-12-apatel@ventanamicro.com> <87a5nreg94.ffs@tglx>
Message-ID: <CAAhSdy1jdHsuwRhbRgig98-AVDOGwp_XxHurg9o3Rsj1AVOqbA@mail.gmail.com>

On Fri, Feb 23, 2024 at 1:58?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Thu, Feb 22 2024 at 15:09, Anup Patel wrote:
> > +     /*
> > +      * Setup cpuhp state (must be done after setting imsic_parent_irq)
> > +      *
> > +      * Don't disable per-CPU IMSIC file when CPU goes offline
> > +      * because this affects IPI and the masking/unmasking of
> > +      * virtual IPIs is done via generic IPI-Mux
> > +      */
> > +     cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "irqchip/riscv/imsic:starting",
> > +                       imsic_starting_cpu, imsic_dying_cpu);
>
> This is not really correct. IPIs should be working right away when a CPU
> comes online and on the unplug side until it really goes offline.
>
> So this wants to be in the starting range, i.e. between CPUHP_AP_OFFLINE
> and CPUHP_AP_ONLINE. No?

Yes, it has to be as early as possible but I was not sure about
introducing yet another driver specific CPUHP_AP_xyz state
considering CPUHP_AP_ONLINE_DYN worked fine.

Since you suggested, let me introduce
CPUHP_AP_IRQ_RISCV_IMSIC_STARTING in the next revision.

Regards,
Anup


From balint.dobszay at arm.com  Fri Feb 23 01:51:33 2024
From: balint.dobszay at arm.com (Balint Dobszay)
Date: Fri, 23 Feb 2024 10:51:33 +0100
Subject: [PATCH v2 3/3] Documentation: tee: Add TS-TEE driver
In-Reply-To: <20240223095133.109046-1-balint.dobszay@arm.com>
References: <20240223095133.109046-1-balint.dobszay@arm.com>
Message-ID: <20240223095133.109046-4-balint.dobszay@arm.com>

Add documentation for the Trusted Services TEE driver.

Signed-off-by: Balint Dobszay <balint.dobszay at arm.com>
---
 Documentation/tee/index.rst  |  1 +
 Documentation/tee/ts-tee.rst | 71 ++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)
 create mode 100644 Documentation/tee/ts-tee.rst

diff --git a/Documentation/tee/index.rst b/Documentation/tee/index.rst
index a23bd08847e5..4be6e69d7837 100644
--- a/Documentation/tee/index.rst
+++ b/Documentation/tee/index.rst
@@ -10,6 +10,7 @@ TEE Subsystem
    tee
    op-tee
    amd-tee
+   ts-tee
 
 .. only::  subproject and html
 
diff --git a/Documentation/tee/ts-tee.rst b/Documentation/tee/ts-tee.rst
new file mode 100644
index 000000000000..843e34422648
--- /dev/null
+++ b/Documentation/tee/ts-tee.rst
@@ -0,0 +1,71 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================================
+TS-TEE (Trusted Services project)
+=================================
+
+This driver provides access to secure services implemented by Trusted Services.
+
+Trusted Services [1] is a TrustedFirmware.org project that provides a framework
+for developing and deploying device Root of Trust services in FF-A [2] S-EL0
+Secure Partitions. The project hosts the reference implementation of the Arm
+Platform Security Architecture [3] for Arm A-profile devices.
+
+The FF-A Secure Partitions (SP) are accessible through the FF-A driver [4] which
+provides the low level communication for this driver. On top of that the Trusted
+Services RPC protocol is used [5]. To use the driver from user space a reference
+implementation is provided at [6], which is part of the Trusted Services client
+library called libts [7].
+
+All Trusted Services (TS) SPs have the same FF-A UUID; it identifies the TS RPC
+protocol. A TS SP can host one or more services (e.g. PSA Crypto, PSA ITS, etc).
+A service is identified by its service UUID; the same type of service cannot be
+present twice in the same SP. During SP boot each service in the SP is assigned
+an "interface ID". This is just a short ID to simplify message addressing.
+
+The generic TEE design is to share memory at once with the Trusted OS, which can
+then be reused to communicate with multiple applications running on the Trusted
+OS. However, in case of FF-A, memory sharing works on an endpoint level, i.e.
+memory is shared with a specific SP. User space has to be able to separately
+share memory with each SP based on its endpoint ID; therefore a separate TEE
+device is registered for each discovered TS SP. Opening the SP corresponds to
+opening the TEE device and creating a TEE context. A TS SP hosts one or more
+services. Opening a service corresponds to opening a session in the given
+tee_context.
+
+Overview of a system with Trusted Services components::
+
+   User space                  Kernel space                   Secure world
+   ~~~~~~~~~~                  ~~~~~~~~~~~~                   ~~~~~~~~~~~~
+   +--------+                                               +-------------+
+   | Client |                                               | Trusted     |
+   +--------+                                               | Services SP |
+      /\                                                    +-------------+
+      ||                                                          /\
+      ||                                                          ||
+      ||                                                          ||
+      \/                                                          \/
+   +-------+                +----------+--------+           +-------------+
+   | libts |                |  TEE     | TS-TEE |           |  FF-A SPMC  |
+   |       |                |  subsys  | driver |           |   + SPMD    |
+   +-------+----------------+----+-----+--------+-----------+-------------+
+   |      Generic TEE API        |     |  FF-A  |     TS RPC protocol     |
+   |      IOCTL (TEE_IOC_*)      |     | driver |        over FF-A        |
+   +-----------------------------+     +--------+-------------------------+
+
+References
+==========
+
+[1] https://www.trustedfirmware.org/projects/trusted-services/
+
+[2] https://developer.arm.com/documentation/den0077/
+
+[3] https://www.arm.com/architecture/security-features/platform-security
+
+[4] drivers/firmware/arm_ffa/
+
+[5] https://trusted-services.readthedocs.io/en/v1.0.0/developer/service-access-protocols.html#abi
+
+[6] https://git.trustedfirmware.org/TS/trusted-services.git/tree/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c?h=v1.0.0
+
+[7] https://git.trustedfirmware.org/TS/trusted-services.git/tree/deployments/libts/arm-linux/CMakeLists.txt?h=v1.0.0
-- 
2.34.1



From marex at denx.de  Fri Feb 23 01:54:59 2024
From: marex at denx.de (Marek Vasut)
Date: Fri, 23 Feb 2024 10:54:59 +0100
Subject: [PATCH] arm64: dts: imx8mp: Fix LDB clocks property
In-Reply-To: <20240223091522.2880155-1-victor.liu@nxp.com>
References: <20240223091522.2880155-1-victor.liu@nxp.com>
Message-ID: <906acc9a-0dc2-4b39-a2f1-297690a7db63@denx.de>

On 2/23/24 10:15, Liu Ying wrote:
> The "media_ldb_root_clk" is the gate clock to enable or disable the clock
> provided by CCM(Clock Control Module) to LDB instead of the "media_ldb"
> clock which is the parent of the "media_ldb_root_clk" clock as a composite
> clock.  Fix LDB clocks property by referencing the "media_ldb_root_clk"
> clock instead of the "media_ldb" clock.
> 
> Fixes: e7567840ecd3 ("arm64: dts: imx8mp: Reorder clock and reg properties")
> Fixes: 94e6197dadc9 ("arm64: dts: imx8mp: Add LCDIF2 & LDB nodes")
> Signed-off-by: Liu Ying <victor.liu at nxp.com>

Reviewed-by: Marek Vasut <marex at denx.de>


From suzuki.poulose at arm.com  Fri Feb 23 02:03:32 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 23 Feb 2024 10:03:32 +0000
Subject: [PATCH v5 5/7] arm64: KVM: Add interface to set guest value for
 TRFCR register
In-Reply-To: <20240220100924.2761706-6-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
 <20240220100924.2761706-6-james.clark@arm.com>
Message-ID: <c8819064-13c3-41c6-8b2e-779ef8a22ee8@arm.com>

On 20/02/2024 10:09, James Clark wrote:
> Add an interface for the Coresight driver to use to set the value of the
> TRFCR register for the guest. This register controls the exclude
> settings for trace at different exception levels, and is used to honor
> the exclude_host and exclude_guest parameters from the Perf session.
> This will be used to later write TRFCR_EL1 on nVHE at guest switch. For
> VHE, the host trace is controlled by TRFCR_EL2 and thus we can write to
> the TRFCR_EL1 immediately. Because guest writes to the register are
> trapped, the value will persist and can't be modified.
> 
> Instead of adding a load of infrastructure to share the host's per-cpu
> offsets with the hypervisor, just define the new storage as a NR_CPUS
> array.
> 
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>   arch/arm64/include/asm/kvm_host.h |  3 +++
>   arch/arm64/kernel/image-vars.h    |  1 +
>   arch/arm64/kvm/debug.c            | 26 ++++++++++++++++++++++++++
>   3 files changed, 30 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 85b5477bd1b4..56b7f7eca195 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -509,6 +509,7 @@ struct kvm_host_psci_config {
>   	bool psci_0_1_cpu_off_implemented;
>   	bool psci_0_1_migrate_implemented;
>   };
> +extern u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
>   
>   extern struct kvm_host_psci_config kvm_nvhe_sym(kvm_host_psci_config);
>   #define kvm_host_psci_config CHOOSE_NVHE_SYM(kvm_host_psci_config)
> @@ -1174,6 +1175,7 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu);
>   void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr);
>   void kvm_clr_pmu_events(u32 clr);
>   bool kvm_set_pmuserenr(u64 val);
> +void kvm_etm_set_guest_trfcr(u64 trfcr_guest);
>   #else
>   static inline void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) {}
>   static inline void kvm_clr_pmu_events(u32 clr) {}
> @@ -1181,6 +1183,7 @@ static inline bool kvm_set_pmuserenr(u64 val)
>   {
>   	return false;
>   }
> +static inline void kvm_etm_set_guest_trfcr(u64 trfcr_guest) {}
>   #endif
>   
>   void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
> diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
> index 5e4dc72ab1bd..a451e4f10804 100644
> --- a/arch/arm64/kernel/image-vars.h
> +++ b/arch/arm64/kernel/image-vars.h
> @@ -59,6 +59,7 @@ KVM_NVHE_ALIAS(alt_cb_patch_nops);
>   
>   /* Global kernel state accessed by nVHE hyp code. */
>   KVM_NVHE_ALIAS(kvm_vgic_global_state);
> +KVM_NVHE_ALIAS(kvm_guest_trfcr);
>   
>   /* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */
>   KVM_NVHE_ALIAS(nvhe_hyp_panic_handler);
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index 49a13e72ddd2..c8d936ce6e2b 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -22,6 +22,7 @@
>   				DBG_MDSCR_MDE)
>   
>   static DEFINE_PER_CPU(u64, mdcr_el2);
> +u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
>   
>   /*
>    * save/restore_guest_debug_regs
> @@ -359,3 +360,28 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
>   	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
>   	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
>   }
> +
> +/*
> + * Interface for the Coresight driver to use to set the value of the TRFCR
> + * register for the guest. This register controls the exclude settings for trace
> + * at different exception levels, and is used to honor the exclude_host and
> + * exclude_guest parameters from the Perf session.
> + *
> + * This will be used to later write TRFCR_EL1 on nVHE at guest switch. For VHE,
> + * the host trace is controlled by TRFCR_EL2 and thus we can write to the
> + * TRFCR_EL1 immediately. Because guest writes to the register are trapped, the
> + * value will persist and can't be modified. For pKVM, kvm_guest_trfcr can't
> + * be read by the hypervisor, so don't bother writing it.
> + */
> +void kvm_etm_set_guest_trfcr(u64 trfcr_guest)
> +{
> +	if (WARN_ON_ONCE(!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
> +							       ID_AA64DFR0_EL1_TraceFilt_SHIFT)))
> +		return;
> +
> +	if (has_vhe())
> +		write_sysreg_s(trfcr_guest, SYS_TRFCR_EL12);
> +	else if (!is_protected_kvm_enabled())
> +		kvm_guest_trfcr[smp_processor_id()] = trfcr_guest;

smp_processor_id() could sleep in some configurations ? Should we switch 
to raw_smp_processor_id() to be safer ?

Otherwise looks good to me.

Suzuki

> +}
> +EXPORT_SYMBOL_GPL(kvm_etm_set_guest_trfcr);



From zajec5 at gmail.com  Fri Feb 23 02:17:05 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 23 Feb 2024 11:17:05 +0100
Subject: [PATCH V2 0/4] dts: mediatek: add Cudy WR3000 V1 wireless router
Message-ID: <20240223101709.30072-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Cudy WR3000 V1 is a MediaTek Filogic 820 based 802.11ax wireless router.

https://www.cudy.com/productinfo/1637722.html

Rafa? Mi?ecki (4):
  dt-bindings: vendor-prefixes: add Cudy
  dt-bindings: arm64: dts: mediatek: Add Cudy WR3000 V1 router
  arm64: dts: mediatek: mt7981: add pinctrl
  arm64: dts: mediatek: Add Cudy WR3000 V1

 .../devicetree/bindings/arm/mediatek.yaml     |  1 +
 .../devicetree/bindings/vendor-prefixes.yaml  |  2 +
 arch/arm64/boot/dts/mediatek/Makefile         |  1 +
 .../dts/mediatek/mt7981b-cudy-wr3000-v1.dts   | 74 +++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7981b.dtsi     | 22 ++++++
 5 files changed, 100 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts

-- 
2.35.3



From zajec5 at gmail.com  Fri Feb 23 02:17:07 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 23 Feb 2024 11:17:07 +0100
Subject: [PATCH V2 2/4] dt-bindings: arm64: dts: mediatek: Add Cudy WR3000 V1 router
In-Reply-To: <20240223101709.30072-1-zajec5@gmail.com>
References: <20240223101709.30072-1-zajec5@gmail.com>
Message-ID: <20240223101709.30072-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Cudy WR3000 V1 is an MT7981B (AKA Filogic 820) based wireless router.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 Documentation/devicetree/bindings/arm/mediatek.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 09f9ffd3ff7b..1cf47db94c57 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -85,6 +85,7 @@ properties:
           - const: mediatek,mt7629
       - items:
           - enum:
+              - cudy,wr3000-v1
               - xiaomi,ax3000t
           - const: mediatek,mt7981b
       - items:
-- 
2.35.3



From zajec5 at gmail.com  Fri Feb 23 02:17:09 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 23 Feb 2024 11:17:09 +0100
Subject: [PATCH V2 4/4] arm64: dts: mediatek: Add Cudy WR3000 V1
In-Reply-To: <20240223101709.30072-1-zajec5@gmail.com>
References: <20240223101709.30072-1-zajec5@gmail.com>
Message-ID: <20240223101709.30072-5-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Cudy WR3000 V1 is an MT7981B (AKA Filogic 820) based wireless router. It
has 256 MiB of RAM, some LEDs & buttons and (not described yet) 4
Ethernet ports.

There is one slightly uncommon LED with a label of globe icon described
in the Quick Installation Guide as having 2 meanings:
1. "Not connected to the Internet"
2. "Connected to the Internet"

Vendor designed it to light up when some Internet-accessible IP can be
reached. This change will be follow by an attempt to define some
predefined FUNCTION for it.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Reorder properties
    Describe online LED

 arch/arm64/boot/dts/mediatek/Makefile         |  1 +
 .../dts/mediatek/mt7981b-cudy-wr3000-v1.dts   | 74 +++++++++++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 37b4ca3a87c9..96da4ad640aa 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-cudy-wr3000-v1.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7981b-xiaomi-ax3000t.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-acelink-ew-7886cax.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
new file mode 100644
index 000000000000..2a988218039c
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7981b-cudy-wr3000-v1.dts
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+#include "mt7981b.dtsi"
+
+/ {
+	compatible = "cudy,wr3000-v1", "mediatek,mt7981b";
+	model = "Cudy WR3000 V1";
+
+	memory at 40000000 {
+		reg = <0 0x40000000 0 0x10000000>;
+		device_type = "memory";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		key-wps {
+			label = "WPS";
+			gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		key-reset {
+			label = "RESET";
+			gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			color = <LED_COLOR_ID_BLUE>;
+			function = LED_FUNCTION_WAN;
+			gpios = <&pio 5 GPIO_ACTIVE_LOW>;
+		};
+
+		led-1 {
+			color = <LED_COLOR_ID_BLUE>;
+			function = LED_FUNCTION_WLAN_2GHZ;
+			gpios = <&pio 6 GPIO_ACTIVE_LOW>;
+		};
+
+		led-2 {
+			color = <LED_COLOR_ID_BLUE>;
+			function = LED_FUNCTION_WLAN_5GHZ;
+			gpios = <&pio 7 GPIO_ACTIVE_LOW>;
+		};
+
+		led-3 {
+			color = <LED_COLOR_ID_BLUE>;
+			function = LED_FUNCTION_LAN;
+			gpios = <&pio 9 GPIO_ACTIVE_LOW>;
+		};
+
+		led-4 {
+			color = <LED_COLOR_ID_BLUE>;
+			function = LED_FUNCTION_STATUS;
+			gpios = <&pio 10 GPIO_ACTIVE_LOW>;
+		};
+
+		led-5 {
+			color = <LED_COLOR_ID_BLUE>;
+			function = "wan-online";
+			gpios = <&pio 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
-- 
2.35.3



From zajec5 at gmail.com  Fri Feb 23 02:17:06 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 23 Feb 2024 11:17:06 +0100
Subject: [PATCH V2 1/4] dt-bindings: vendor-prefixes: add Cudy
In-Reply-To: <20240223101709.30072-1-zajec5@gmail.com>
References: <20240223101709.30072-1-zajec5@gmail.com>
Message-ID: <20240223101709.30072-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Cudy is a Chinese company providing networking products.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.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 20ed04148092..57f91c83152e 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -334,6 +334,8 @@ patternProperties:
     description: Czech Technical University in Prague
   "^cubietech,.*":
     description: Cubietech, Ltd.
+  "^cudy,.*":
+    description: Shenzhen Cudy Technology Co., Ltd.
   "^cui,.*":
     description: CUI Devices
   "^cypress,.*":
-- 
2.35.3



From zajec5 at gmail.com  Fri Feb 23 02:17:08 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 23 Feb 2024 11:17:08 +0100
Subject: [PATCH V2 3/4] arm64: dts: mediatek: mt7981: add pinctrl
In-Reply-To: <20240223101709.30072-1-zajec5@gmail.com>
References: <20240223101709.30072-1-zajec5@gmail.com>
Message-ID: <20240223101709.30072-4-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

MT7981 contains on-SoC PIN controller that is also a GPIO provider.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Drop board specific code

 arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
index a187a34d12ee..5674ac81d1f8 100644
--- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
@@ -94,6 +94,28 @@ pwm at 10048000 {
 			#pwm-cells = <2>;
 		};
 
+		pio: pinctrl at 11d00000 {
+			compatible = "mediatek,mt7981-pinctrl";
+			reg = <0 0x11d00000 0 0x1000>,
+			      <0 0x11c00000 0 0x1000>,
+			      <0 0x11c10000 0 0x1000>,
+			      <0 0x11d20000 0 0x1000>,
+			      <0 0x11e00000 0 0x1000>,
+			      <0 0x11e20000 0 0x1000>,
+			      <0 0x11f00000 0 0x1000>,
+			      <0 0x11f10000 0 0x1000>,
+			      <0 0x1000b000 0 0x1000>;
+			reg-names = "gpio", "iocfg_rt", "iocfg_rm", "iocfg_rb", "iocfg_lb",
+				    "iocfg_bl", "iocfg_tm", "iocfg_tl", "eint";
+			interrupt-controller;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&gic>;
+			gpio-ranges = <&pio 0 0 56>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			#interrupt-cells = <2>;
+		};
+
 		clock-controller at 15000000 {
 			compatible = "mediatek,mt7981-ethsys", "syscon";
 			reg = <0 0x15000000 0 0x1000>;
-- 
2.35.3



From quic_kathirav at quicinc.com  Fri Feb 23 02:18:27 2024
From: quic_kathirav at quicinc.com (Kathiravan Thirumoorthy)
Date: Fri, 23 Feb 2024 15:48:27 +0530
Subject: [PATCH v4 2/8] clk: qcom: ipq5332: enable few nssnoc clocks in
 driver probe
In-Reply-To: <CAA8EJppP_bAPRH7Upnq8dO7__xQPOJ6F_Lc-fpRAcutKKzk0eA@mail.gmail.com>
References: <20240122-ipq5332-nsscc-v4-0-19fa30019770@quicinc.com>
 <20240122-ipq5332-nsscc-v4-2-19fa30019770@quicinc.com>
 <7a69a68d-44c2-4589-b286-466d2f2a0809@lunn.ch>
 <11fda059-3d8d-4030-922a-8fef16349a65@quicinc.com>
 <17e2400e-6881-4e9e-90c2-9c4f77a0d41d@lunn.ch>
 <8c9ee34c-a97b-4acf-a093-9ac2afc28d0e@quicinc.com>
 <CAA8EJppe6aNf2WJ5BvaX8SPTbuaEwzRm74F8QKyFtbmnGQt=1w@mail.gmail.com>
 <74f585c2-d220-4324-96eb-1a945fef9608@quicinc.com>
 <CAA8EJppuNRB9fhjimg4SUR2PydX7-KLWSb9H-nC-oSMYVOME-Q@mail.gmail.com>
 <d518dbc1-41aa-46f9-b549-c95a33b06ee0@quicinc.com>
 <CAA8EJppP_bAPRH7Upnq8dO7__xQPOJ6F_Lc-fpRAcutKKzk0eA@mail.gmail.com>
Message-ID: <3a6d301d-16f6-4a11-8be5-6bbb6eb501f4@quicinc.com>



On 2/19/2024 3:53 PM, Dmitry Baryshkov wrote:
> On Sun, 18 Feb 2024 at 06:29, Kathiravan Thirumoorthy
> <quic_kathirav at quicinc.com> wrote:
>>
>>
>>
>> On 2/17/2024 10:15 PM, Dmitry Baryshkov wrote:
>>> On Sat, 17 Feb 2024 at 17:45, Kathiravan Thirumoorthy
>>> <quic_kathirav at quicinc.com> wrote:
>>>>
>>>>
>>>> <snip>
>>>>
>>>>>> Reason being, to access the NSSCC clocks, these GCC clocks
>>>>>> (gcc_snoc_nssnoc_clk, gcc_snoc_nssnoc_1_clk, gcc_nssnoc_nsscc_clk)
>>>>>> should be turned ON. But CCF disables these clocks as well due to the
>>>>>> lack of consumer.
>>>>>
>>>>> This means that NSSCC is also a consumer of those clocks. Please fix
>>>>> both DT and nsscc driver to handle NSSNOC clocks.
>>>>
>>>>
>>>> Thanks Dmitry. I shall include these clocks in the NSSCC DT node and
>>>> enable the same in the NSSCC driver probe.
>>>
>>> Or use them through pm_clk. This might be better, as the system
>>> doesn't need these clocks if NSSCC is suspended.
>>
>>
>> IPQ53XX SoC doesn't support the PM(suspend / resume) functionality, so
>> that, can I enable these clocks in NSSCC driver probe itself?
> 
> There is a difference between PM (suspend/resume) and runtime PM.
> 
> 

Thanks Dmitry. IIUC your question correctly, runtime PM for the 
peripherals are not supported (except CPU cores which supports DVFS). 
Since these are router based products, once system is powered on, all 
the peripherals are configured to the required frequency and it will be 
never go into low power modes.

Please let me know if this answers your questions.


From m.szyprowski at samsung.com  Fri Feb 23 02:22:55 2024
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Fri, 23 Feb 2024 11:22:55 +0100
Subject: [PATCH v12 02/25] genirq/irqdomain: Remove the param count
 restriction from select()
In-Reply-To: <20240127161753.114685-3-apatel@ventanamicro.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
	<20240127161753.114685-3-apatel@ventanamicro.com>
	<CGME20240223102258eucas1p119f38e40f769c883c0a502e9e26be888@eucas1p1.samsung.com>
Message-ID: <481aa3b9-55c2-4ccb-bb4a-58b924d77ad7@samsung.com>

Dear All,

On 27.01.2024 17:17, Anup Patel wrote:
> From: Thomas Gleixner <tglx at linutronix.de>
>
> Now that the GIC-v3 callback can handle invocation with a fwspec parameter
> count of 0 lift the restriction in the core code and invoke select()
> unconditionally when the domain provides it.
>
> Preparatory change for per device MSI domains.
>
> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
> Signed-off-by: Anup Patel <apatel at ventanamicro.com>


This patch landed recently in linux-next (next-20240221) as commit 
de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from 
select()"). I've noticed that it breaks booting of Qualcomm's Robotics 
RB5 ARM64 board (arch/arm64/boot/dts/qcom/qrb5165-rb5.dts). Booting 
freezes after "clk: Disabling unused clocks", but this is probably a 
consequence of some earlier failure. Reverting $subject on top of 
next-20240221 fixes this problem. Let me know how can I help debugging 
this issue.


> ---
>   kernel/irq/irqdomain.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index 0bdef4fe925b..8fee37918195 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -448,7 +448,7 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
>   	 */
>   	mutex_lock(&irq_domain_mutex);
>   	list_for_each_entry(h, &irq_domain_list, link) {
> -		if (h->ops->select && fwspec->param_count)
> +		if (h->ops->select)
>   			rc = h->ops->select(h, fwspec, bus_token);
>   		else if (h->ops->match)
>   			rc = h->ops->match(h, to_of_node(fwnode), bus_token);

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From will at kernel.org  Fri Feb 23 02:23:45 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 23 Feb 2024 10:23:45 +0000
Subject: [PATCH v4 5/7] arm64: Unconditionally call
 unflatten_device_tree()
In-Reply-To: <20240223000317.GA3835346-robh@kernel.org>
References: <20240217010557.2381548-1-sboyd@kernel.org>
 <20240217010557.2381548-6-sboyd@kernel.org>
 <20240223000317.GA3835346-robh@kernel.org>
Message-ID: <20240223102345.GA10274@willie-the-truck>

On Thu, Feb 22, 2024 at 05:03:17PM -0700, Rob Herring wrote:
> On Fri, Feb 16, 2024 at 05:05:54PM -0800, Stephen Boyd wrote:
> > Call this function unconditionally so that we can populate an empty DTB
> > on platforms that don't boot with a firmware provided or builtin DTB.
> > When ACPI is in use, unflatten_device_tree() ignores the
> > 'initial_boot_params' pointer so the live DT on those systems won't be
> > whatever that's pointing to. Similarly, when kexec copies the DT data
> > the previous kernel to the new one on ACPI systems,
> > of_kexec_alloc_and_setup_fdt() will ignore the live DT (the empty root
> > one) and copy the 'initial_boot_params' data.
> > 
> > Cc: Rob Herring <robh+dt at kernel.org>
> > Cc: Frank Rowand <frowand.list 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: <linux-arm-kernel at lists.infradead.org>
> > Signed-off-by: Stephen Boyd <sboyd at kernel.org>
> > ---
> >  arch/arm64/kernel/setup.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> Catalin, Will, Can I get an ack on this so I can take the series via the 
> DT tree.

Mark had strong pretty strong objections to this in version one:

https://lore.kernel.org/all/ZaZtbU9hre3YhZam at FVFF77S0Q05N/

and this patch looks the same now as it did then. Did something else
change?

Will


From lee at kernel.org  Fri Feb 23 02:23:52 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 10:23:52 +0000
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <9dbfbeac-3a00-4571-95c0-83e4d47737c5@microchip.com>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
 <ffd43756-b24e-4f19-be33-0e33047ad70c@microchip.com>
 <20240220082026.GG10170@google.com>
 <9dbfbeac-3a00-4571-95c0-83e4d47737c5@microchip.com>
Message-ID: <20240223102352.GL10170@google.com>

On Tue, 20 Feb 2024, Dharma.B at microchip.com wrote:

> Hi Lee,
> 
> On 20/02/24 1:50 pm, Lee Jones wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > 
> > On Tue, 20 Feb 2024, Dharma.B at microchip.com wrote:
> > 
> >> Hi Krzysztof,
> >>
> >> On 12/02/24 3:53 pm, Krzysztof Kozlowski wrote:
> >>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> >>>
> >>> On 08/02/2024 11:43, Lee Jones wrote:
> >>>> On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
> >>>>> Convert the atmel,hlcdc binding to DT schema format.
> >>>>>
> >>>>> Align clocks and clock-names properties to clearly indicate that the LCD
> >>>>> controller expects lvds_pll_clk when interfaced with the lvds display. This
> >>>>> alignment with the specific hardware requirements ensures accurate device tree
> >>>>> configuration for systems utilizing the HLCDC IP.
> >>>>>
> >>>>> [...]
> >>>>
> >>>> Applied, thanks!
> >>>>
> >>>> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
> >>>>         commit: cb946db1335b599ece363d33966bf653ed0fa58a
> >>>>
> >>>
> >>> Next is still failing.
> >>>
> >>> Dharma,
> >>> You must explain and clearly mark dependencies between patches.
> >>
> >> I sincerely apologize for any confusion caused by the oversight. I have
> >> organized the patches according to their dependencies in the patch
> >> series, but unfortunately, I neglected to explicitly mention these
> >> dependencies. I understand the importance of clear communication in our
> >> collaborative efforts. Please feel free to provide guidance on how I can
> >> assist you further in resolving this matter.
> > 
> > If this continues to be an issue, I can just remove the commit.
> 
> There won't be any issue if both pwm and display binding goes before the 
> mfd binding.
> 
> Could you please pick the display binding as well?

Only with an ACK from the relevant Maintainers.

-- 
Lee Jones [???]


From lee at kernel.org  Fri Feb 23 02:25:17 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 10:25:17 +0000
Subject: (subset) [linux][PATCH v6 3/3] dt-bindings: mfd: atmel,hlcdc:
 Convert to DT schema format
In-Reply-To: <20240222232118.GA3786028-robh@kernel.org>
References: <20240202001733.91455-1-dharma.b@microchip.com>
 <20240202001733.91455-4-dharma.b@microchip.com>
 <170738899221.920003.15342446791449663430.b4-ty@kernel.org>
 <cedecdb7-fe4a-42ea-9a11-faa82f84b57d@linaro.org>
 <ffd43756-b24e-4f19-be33-0e33047ad70c@microchip.com>
 <20240220082026.GG10170@google.com>
 <9dbfbeac-3a00-4571-95c0-83e4d47737c5@microchip.com>
 <20240222232118.GA3786028-robh@kernel.org>
Message-ID: <20240223102517.GM10170@google.com>

On Thu, 22 Feb 2024, Rob Herring wrote:

> On Tue, Feb 20, 2024 at 08:30:38AM +0000, Dharma.B at microchip.com wrote:
> > Hi Lee,
> > 
> > On 20/02/24 1:50 pm, Lee Jones wrote:
> > > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > > 
> > > On Tue, 20 Feb 2024, Dharma.B at microchip.com wrote:
> > > 
> > >> Hi Krzysztof,
> > >>
> > >> On 12/02/24 3:53 pm, Krzysztof Kozlowski wrote:
> > >>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > >>>
> > >>> On 08/02/2024 11:43, Lee Jones wrote:
> > >>>> On Fri, 02 Feb 2024 05:47:33 +0530, Dharma Balasubiramani wrote:
> > >>>>> Convert the atmel,hlcdc binding to DT schema format.
> > >>>>>
> > >>>>> Align clocks and clock-names properties to clearly indicate that the LCD
> > >>>>> controller expects lvds_pll_clk when interfaced with the lvds display. This
> > >>>>> alignment with the specific hardware requirements ensures accurate device tree
> > >>>>> configuration for systems utilizing the HLCDC IP.
> > >>>>>
> > >>>>> [...]
> > >>>>
> > >>>> Applied, thanks!
> > >>>>
> > >>>> [3/3] dt-bindings: mfd: atmel,hlcdc: Convert to DT schema format
> > >>>>         commit: cb946db1335b599ece363d33966bf653ed0fa58a
> > >>>>
> > >>>
> > >>> Next is still failing.
> > >>>
> > >>> Dharma,
> > >>> You must explain and clearly mark dependencies between patches.
> > >>
> > >> I sincerely apologize for any confusion caused by the oversight. I have
> > >> organized the patches according to their dependencies in the patch
> > >> series, but unfortunately, I neglected to explicitly mention these
> > >> dependencies. I understand the importance of clear communication in our
> > >> collaborative efforts. Please feel free to provide guidance on how I can
> > >> assist you further in resolving this matter.
> > > 
> > > If this continues to be an issue, I can just remove the commit.
> > 
> > There won't be any issue if both pwm and display binding goes before the 
> > mfd binding.
> > 
> > Could you please pick the display binding as well?
> 
> As this is still not resolved, I've applied the display binding. Not 
> ideal, but should fix next.

Works for me.

-- 
Lee Jones [???]


From will at kernel.org  Fri Feb 23 02:25:32 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 23 Feb 2024 10:25:32 +0000
Subject: [GIT PULL] arm64 fixes for -rc6
Message-ID: <20240223102531.GB10274@willie-the-truck>

Hi Linus,

Please pull this weekly batch of arm64 fixes for -rc6. The summary is in
the tag, but it's a simple fix to a definition in the CXL PMU driver, a
couple of patches to restore SME control registers on the resume path
(since Arm's fast model now clears them) and a revert for our jump label
asm constraints after Geert noticed they broke the build with GCC 5.5.

There was then the ensuing discussion about raising the minimum GCC (and
corresponding binutils) versions at [1], but for now we'll keep things
working as they were until that goes ahead.

Cheers,

Will

[1] https://lore.kernel.org/lkml/CAMj1kXHh_m=V0QsiTpHrUXpFBXFbFfezdysz8quhPSgUrZg1MA at mail.gmail.com/

--->8

The following changes since commit 2813926261e436d33bc74486b51cce60b76edf78:

  arm64/sve: Lower the maximum allocation for the SVE ptrace regset (2024-02-15 11:48:00 +0000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

for you to fetch changes up to d7b77a0d565b048cb0808fa8a4fb031352b22a01:

  arm64/sme: Restore SMCR_EL1.EZT0 on exit from suspend (2024-02-20 12:19:16 +0000)

----------------------------------------------------------------
arm64 fixes for -rc6

- Revert fix to jump label asm constraints, as it regresses the build
  with some GCC 5.5 toolchains.

- Restore SME control registers when resuming from suspend

- Fix incorrect filter definition in CXL PMU driver

----------------------------------------------------------------
Hojin Nam (1):
      perf: CXL: fix CPMU filter value mask length

Mark Brown (2):
      arm64/sme: Restore SME registers on exit from suspend
      arm64/sme: Restore SMCR_EL1.EZT0 on exit from suspend

Will Deacon (1):
      Revert "arm64: jump_label: use constraints "Si" instead of "i""

 arch/arm64/include/asm/fpsimd.h     |  2 ++
 arch/arm64/include/asm/jump_label.h | 12 ++++--------
 arch/arm64/kernel/fpsimd.c          | 16 ++++++++++++++++
 arch/arm64/kernel/suspend.c         |  3 +++
 drivers/perf/cxl_pmu.c              | 10 +++++-----
 5 files changed, 30 insertions(+), 13 deletions(-)


From lee at kernel.org  Fri Feb 23 02:28:14 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 10:28:14 +0000
Subject: [PATCH v2 1/4] leds: rgb: leds-group-multicolor: allow leds to
 stay on in suspend
In-Reply-To: <Zde+Sce+PAuC1U6g@duo.ucw.cz>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <Zde+Sce+PAuC1U6g@duo.ucw.cz>
Message-ID: <20240223102814.GN10170@google.com>

On Thu, 22 Feb 2024, Pavel Machek wrote:

> Hi!
> 
> > If none of the managed leds enable LED_CORE_SUSPENDRESUME, then we
> > shouldn't need to set it here. This makes it possible to use multicolor
> > groups with gpio leds that enable retain-state-suspended in the device
> > tree.
> > 
> > Signed-off-by: Aren Moynihan <aren at peacevolution.org>
> 
> Thanks for the series.
> 
> Acked-by: Pavel Machek <pavel at ucw.cz>
> 
> Note this will change userland API and maybe break the LED for code
> expecting old setup and hardcoding paths. I guess we should not
> backport this to stable. But we should do this, because it is really
> one LED and not three.

Thanks Pavel.

Is this tied to the other patches in the set?

Will thing break if this is applied on its own?

-- 
Lee Jones [???]


From lee at kernel.org  Fri Feb 23 02:29:14 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 10:29:14 +0000
Subject: [PATCH v2 4/4] arm64: dts: sun50i-a64-pinephone: change led type
 to status
In-Reply-To: <2792937.BEx9A2HvPv@jernej-laptop>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <20240206185400.596979-4-aren@peacevolution.org>
 <2792937.BEx9A2HvPv@jernej-laptop>
Message-ID: <20240223102914.GO10170@google.com>

On Thu, 22 Feb 2024, Jernej ?krabec wrote:

> Dne torek, 06. februar 2024 ob 19:13:20 CET je Aren Moynihan napisal(a):
> > The status function is described in the documentation as being a rgb led
> > used for system notifications on phones[1][2]. This is exactly what this
> > led is used for on the PinePhone, so using status is probably more
> > accurate than indicator.
> > 
> > 1: Documentation/leds/well-known-leds.txt
> > 2: include/dt-bindings/leds/common.h
> > 
> > Signed-off-by: Aren Moynihan <aren at peacevolution.org>
> 
> Sorry for late review.
> 
> Please update subject in patches 2-3. Instead of "sun50i-a64-pinephone:"
> use "allwinner: pinephone:" (check commit history of sun50i-a64-pinephone.dtsi).
> Also rgb -> RGB, led -> LED. Last, please reword commit message to exclude
> links and just say DT bindings documentation.
> 
> Note that I'll merge patches 2-3 once patch 1 is merged.

Works for me - I'll go apply it now.

-- 
Lee Jones [???]


From angelogioacchino.delregno at collabora.com  Fri Feb 23 02:30:09 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 23 Feb 2024 11:30:09 +0100
Subject: [PATCH v2 03/12] soc: mediatek: cmdq: Rename cmdq_pkt_jump() to
 cmdq_pkt_jump_abs()
In-Reply-To: <20240222154120.16959-4-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
 <20240222154120.16959-4-chunkuang.hu@kernel.org>
Message-ID: <c365c2c8-8211-4e36-8ba1-8b4638e81039@collabora.com>

Il 22/02/24 16:41, Chun-Kuang Hu ha scritto:
> In order to distinguish absolute jump and relative jump,
> cmdq_pkt_jump() append absolute jump command, so rename it to
> cmdq_pkt_jump_abs().
> 
> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>


Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Fri Feb 23 02:30:11 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 23 Feb 2024 11:30:11 +0100
Subject: [PATCH v2 04/12] soc: mediatek: cmdq: Add cmdq_pkt_jump_rel()
 helper function
In-Reply-To: <20240222154120.16959-5-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
 <20240222154120.16959-5-chunkuang.hu@kernel.org>
Message-ID: <0a09cbe4-3a36-4d44-a826-5b1dbab6dd49@collabora.com>

Il 22/02/24 16:41, Chun-Kuang Hu ha scritto:
> cmdq_pkt_jump_rel() append relative jump command to the packet.
> Relative jump change PC to the target address with offset from
> current PC.
> 
> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Fri Feb 23 02:30:11 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 23 Feb 2024 11:30:11 +0100
Subject: [PATCH v2 01/12] soc: mediatek: cmdq: Fix typo of
 CMDQ_JUMP_RELATIVE
In-Reply-To: <20240222154120.16959-2-chunkuang.hu@kernel.org>
References: <20240222154120.16959-1-chunkuang.hu@kernel.org>
 <20240222154120.16959-2-chunkuang.hu@kernel.org>
Message-ID: <0a98ae3c-6d89-4a93-94bf-542092ae8e1d@collabora.com>

Il 22/02/24 16:41, Chun-Kuang Hu ha scritto:
> For cmdq jump command, offset 0 means relative jump and offset 1
> means absolute jump. cmdq_pkt_jump() is absolute jump, so fix the
> typo of CMDQ_JUMP_RELATIVE in cmdq_pkt_jump().
> 
> Fixes: 946f1792d3d7 ("soc: mediatek: cmdq: add jump function")
> Signed-off-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From shengjiu.wang at nxp.com  Fri Feb 23 02:15:51 2024
From: shengjiu.wang at nxp.com (Shengjiu Wang)
Date: Fri, 23 Feb 2024 18:15:51 +0800
Subject: [PATCH] clk: imx: imx8mp: Fix SAI_MCLK_SEL definition
Message-ID: <1708683351-8504-1-git-send-email-shengjiu.wang@nxp.com>

There is SAI1, SAI2, SAI3, SAI5, SAI6, SAI7 existing in this block
control, the order is discontinuous. The definition of SAI_MCLK_SEL(n)
is not match with the usage of CLK_SAIn(n).

So define SAI##n##_MCLK_SEL separately to fix the issue.

Fixes: 6cd95f7b151c ("clk: imx: imx8mp: Add audiomix block control")
Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
---
 drivers/clk/imx/clk-imx8mp-audiomix.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8mp-audiomix.c b/drivers/clk/imx/clk-imx8mp-audiomix.c
index e4300df88f1a..55ed211a5e0b 100644
--- a/drivers/clk/imx/clk-imx8mp-audiomix.c
+++ b/drivers/clk/imx/clk-imx8mp-audiomix.c
@@ -18,7 +18,12 @@
 
 #define CLKEN0			0x000
 #define CLKEN1			0x004
-#define SAI_MCLK_SEL(n)		(0x300 + 4 * (n))	/* n in 0..5 */
+#define SAI1_MCLK_SEL		0x300
+#define SAI2_MCLK_SEL		0x304
+#define SAI3_MCLK_SEL		0x308
+#define SAI5_MCLK_SEL		0x30C
+#define SAI6_MCLK_SEL		0x310
+#define SAI7_MCLK_SEL		0x314
 #define PDM_SEL			0x318
 #define SAI_PLL_GNRL_CTL	0x400
 
@@ -95,13 +100,13 @@ static const struct clk_parent_data clk_imx8mp_audiomix_pll_bypass_sels[] = {
 		IMX8MP_CLK_AUDIOMIX_SAI##n##_MCLK1_SEL, {},		\
 		clk_imx8mp_audiomix_sai##n##_mclk1_parents,		\
 		ARRAY_SIZE(clk_imx8mp_audiomix_sai##n##_mclk1_parents), \
-		SAI_MCLK_SEL(n), 1, 0					\
+		SAI##n##_MCLK_SEL, 1, 0					\
 	}, {								\
 		"sai"__stringify(n)"_mclk2_sel",			\
 		IMX8MP_CLK_AUDIOMIX_SAI##n##_MCLK2_SEL, {},		\
 		clk_imx8mp_audiomix_sai_mclk2_parents,			\
 		ARRAY_SIZE(clk_imx8mp_audiomix_sai_mclk2_parents),	\
-		SAI_MCLK_SEL(n), 4, 1					\
+		SAI##n##_MCLK_SEL, 4, 1					\
 	}, {								\
 		"sai"__stringify(n)"_ipg_cg",				\
 		IMX8MP_CLK_AUDIOMIX_SAI##n##_IPG,			\
-- 
2.34.1



From lee at kernel.org  Fri Feb 23 02:31:30 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 10:31:30 +0000
Subject: (subset) [PATCH v2 1/4] leds: rgb: leds-group-multicolor:
 allow leds to stay on in suspend
In-Reply-To: <20240206185400.596979-1-aren@peacevolution.org>
References: <20240206185400.596979-1-aren@peacevolution.org>
Message-ID: <170868429025.1582603.10651778411484887304.b4-ty@kernel.org>

On Tue, 06 Feb 2024 13:13:17 -0500, Aren Moynihan wrote:
> If none of the managed leds enable LED_CORE_SUSPENDRESUME, then we
> shouldn't need to set it here. This makes it possible to use multicolor
> groups with gpio leds that enable retain-state-suspended in the device
> tree.
> 
> 

Applied, thanks!

[1/4] leds: rgb: leds-group-multicolor: allow leds to stay on in suspend
      commit: 68552911e71d59e62dd5e50e9ac56ebfc32f0c71

--
Lee Jones [???]



From lee at kernel.org  Fri Feb 23 02:35:37 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 10:35:37 +0000
Subject: (subset) [PATCH v2 1/4] leds: rgb: leds-group-multicolor: allow
 leds to stay on in suspend
In-Reply-To: <170868429025.1582603.10651778411484887304.b4-ty@kernel.org>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <170868429025.1582603.10651778411484887304.b4-ty@kernel.org>
Message-ID: <20240223103537.GA1585387@google.com>

On Fri, 23 Feb 2024, Lee Jones wrote:

> On Tue, 06 Feb 2024 13:13:17 -0500, Aren Moynihan wrote:
> > If none of the managed leds enable LED_CORE_SUSPENDRESUME, then we
> > shouldn't need to set it here. This makes it possible to use multicolor
> > groups with gpio leds that enable retain-state-suspended in the device
> > tree.
> > 
> > 
> 
> Applied, thanks!
> 
> [1/4] leds: rgb: leds-group-multicolor: allow leds to stay on in suspend
>       commit: 68552911e71d59e62dd5e50e9ac56ebfc32f0c71

Note that I changed a bunch of grammatical issues.

led  => LED
gpio => GPIO

Capitalised the first word of the comment, etc.

-- 
Lee Jones [???]


From yangyicong at huawei.com  Fri Feb 23 02:33:57 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 23 Feb 2024 18:33:57 +0800
Subject: [PATCH v2 6/8] drivers/perf: hisi_pcie: Relax the check on related events
In-Reply-To: <20240223103359.18669-1-yangyicong@huawei.com>
References: <20240223103359.18669-1-yangyicong@huawei.com>
Message-ID: <20240223103359.18669-7-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

If we use two events with the same filter and related event type
(see the following example), the driver check whether they are related
events and are in the same group, otherwise the function
hisi_pcie_pmu_find_related_event() return -EINVAL, then the 2nd event
cannot count but the 1st event is running, although the PCIe PMU has
other idle counters.

In this case, The perf event scheduler will make the two events to
multiplex a counter, if the user use the formula
(1st event_value / 2nd event_value) to calculate the bandwidth, he/she
won't get the correct value, because they are not counting at the
same period.

This patch tries to fix this by making the related events to use
different idle counters if they are not in the same event group.

And finally, I'm going to say. The related events are best used in the
same group [1]. There are two ways to know if they are related events.
a) By event name, such as the latency events "xxx_latency, xxx_cnt" or
bandwidth events "xxx_flux, xxx_time".
b) By event type, such as "event=0xXXXX, event=0x1XXXX".

Use group to count the related events:
  [1] -e "{pmu_name/xxx_latency,port=1/,pmu_name/xxx_cnt,port=1/}"

  example:
    1st event: hisi_pcie0_core1/event=0x804,port=1
    2nd event: hisi_pcie0_core1/event=0x10804,port=1

  test cmd:
    perf stat -e hisi_pcie0_core1/event=0x804,port=1/ \
               -e hisi_pcie0_core1/event=0x10804,port=1/

  before patch:
            25,281      hisi_pcie0_core1/event=0x804,port=1/    (49.91%)
           470,598      hisi_pcie0_core1/event=0x10804,port=1/    (50.09%)

  after patch:
            24,147      hisi_pcie0_core1/event=0x804,port=1/
           474,558      hisi_pcie0_core1/event=0x10804,port=1/

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index b2dde7559639..5b15f3698188 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -409,14 +409,10 @@ static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
 		if (!sibling)
 			continue;
 
-		if (!hisi_pcie_pmu_cmp_event(sibling, event))
-			continue;
-
 		/* Related events must be used in group */
-		if (sibling->group_leader == event->group_leader)
+		if (hisi_pcie_pmu_cmp_event(sibling, event) &&
+		    sibling->group_leader == event->group_leader)
 			return idx;
-		else
-			return -EINVAL;
 	}
 
 	return idx;
-- 
2.24.0



From yangyicong at huawei.com  Fri Feb 23 02:33:51 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 23 Feb 2024 18:33:51 +0800
Subject: [PATCH v2 0/8] drivers/perf: hisi_pcie: Several updates for HiSilicon PCIe PMU driver
Message-ID: <20240223103359.18669-1-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

This series mainly fix and optimize the several usage of the driver:
- Add more events to complement the TLP bandwidth counting
- Fix the wrong counting on using the event group
- Properly check the target filter to avoid invalid filter value
- Optimize the handling of related events which are not in an event group
- Update the docs

Change since v1:
- Rename hisi_pcie_pmu_{config,clear}_filter() to properly reflect its function.
- Add some test case logs to the Patch 5/8 comments.
- Avoid use HISI_PCIE_MAX_COUNTER outside of functions in Patch 7/8.
Link: https://lore.kernel.org/all/20240204074527.47110-1-yangyicong at huawei.com/

Junhao He (4):
  drivers/perf: hisi_pcie: Check the target filter properly
  drivers/perf: hisi_pcie: Relax the check on related events
  drivers/perf: hisi_pcie: Merge find_related_event() and
    get_event_idx()
  docs: perf: Update usage for target filter of hisi-pcie-pmu

Yicong Yang (4):
  drivers/perf: hisi_pcie: Rename hisi_pcie_pmu_{config,clear}_filter()
  drivers/perf: hisi_pcie: Introduce hisi_pcie_pmu_get_event_ctrl_val()
  drivers/perf: hisi_pcie: Fix incorrect counting under metric mode
  drivers/perf: hisi_pcie: Add more events for counting TLP bandwidth

 .../admin-guide/perf/hisi-pcie-pmu.rst        |  31 ++++--
 drivers/perf/hisilicon/hisi_pcie_pmu.c        | 102 +++++++++---------
 2 files changed, 76 insertions(+), 57 deletions(-)

-- 
2.24.0



From yangyicong at huawei.com  Fri Feb 23 02:33:54 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 23 Feb 2024 18:33:54 +0800
Subject: [PATCH v2 3/8] drivers/perf: hisi_pcie: Fix incorrect counting under metric mode
In-Reply-To: <20240223103359.18669-1-yangyicong@huawei.com>
References: <20240223103359.18669-1-yangyicong@huawei.com>
Message-ID: <20240223103359.18669-4-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

The metric counting shows incorrect results if the events in the
metric group using the same event but different filter options.
This is because we only judge the event code to decide whether
the event in the metric group should share the same hardware
counter, but ignore the settings of the filter.

For example, on a platform of 2 ports 0x1 and 0x2 but only port
0x1 has a downstream PCIe NVME device. The metric counting
shows both ports have the same counts because we misassign these
two events to one same hardware counter:
[root at localhost perf-iostat]# ./perf stat -e '{hisi_pcie0_core1/event=0x0104,port=0x2/,hisi_pcie0_core1/event=0x0104,port=0x1/}'

 Performance counter stats for 'system wide':

        7907484924      hisi_pcie0_core1/event=0x0104,port=0x2/
        7907484924      hisi_pcie0_core1/event=0x0104,port=0x1/

      10.153863691 seconds time elapsed

Fix this by using the whole config rather than the event only
to judge whether two events are the same and should share the
same hardware counter. With this patch, the metric counting in
the above case tends to be corrected:

[root at localhost perf-iostat]# ./perf stat -e '{hisi_pcie0_core1/event=0x0104,port=0x2/,hisi_pcie0_core1/event=0x0104,port=0x1/}'

 Performance counter stats for 'system wide':

                 0      hisi_pcie0_core1/event=0x0104,port=0x2/
        8123122077      hisi_pcie0_core1/event=0x0104,port=0x1/

      10.152875631 seconds time elapsed

Fixes: 8404b0fbc7fb ("drivers/perf: hisi: Add driver for HiSilicon PCIe PMU")
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 2468cf3b007c..9176242eadb3 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -314,10 +314,16 @@ static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
 	return true;
 }
 
+/*
+ * Check Whether two events share the same config. The same config means not
+ * only the event code, but also the filter settings of the two events are
+ * the same.
+ */
 static bool hisi_pcie_pmu_cmp_event(struct perf_event *target,
 					struct perf_event *event)
 {
-	return hisi_pcie_get_real_event(target) == hisi_pcie_get_real_event(event);
+	return hisi_pcie_pmu_get_event_ctrl_val(target) ==
+	       hisi_pcie_pmu_get_event_ctrl_val(event);
 }
 
 static bool hisi_pcie_pmu_validate_event_group(struct perf_event *event)
-- 
2.24.0



From yangyicong at huawei.com  Fri Feb 23 02:33:56 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 23 Feb 2024 18:33:56 +0800
Subject: [PATCH v2 5/8] drivers/perf: hisi_pcie: Check the target filter properly
In-Reply-To: <20240223103359.18669-1-yangyicong@huawei.com>
References: <20240223103359.18669-1-yangyicong@huawei.com>
Message-ID: <20240223103359.18669-6-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

The PMU can monitor traffic of certain target Root Port or downstream
target Endpoint. User can specify the target filter by the "port" or
"bdf" option respectively. The PMU can only monitor the Root Port or
Endpoint on the same PCIe core so the value of "port" or "bdf" should
be valid and will be checked by the driver.

Currently at least and only one of "port" and "bdf" option must be set.
If "port" filter is not set or is set explicitly to zero (default),
driver will regard the user specifies a "bdf" option since "port" option
is a bitmask of the target Root Ports and zero is not a valid
value.

If user not explicitly set "port" or "bdf" filter, the driver uses "bdf"
default value (zero) to set target filter, but driver will skip the
check of bdf=0, although it's a valid value (meaning 0000:000:00.0).
Then the user just gets zero.

Therefore, we need to check if both "port" and "bdf" are invalid, then
return failure and report warning.

Testing:
before the patch:
                   0      hisi_pcie0_core1/rx_mrd_flux/
                   0      hisi_pcie0_core1/rx_mrd_flux,port=0/
              24,124      hisi_pcie0_core1/rx_mrd_flux,port=1/
                   0      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
                   0      hisi_pcie0_core1/rx_mrd_flux,port=0x800/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/
              24,132      hisi_pcie0_core1/rx_mrd_flux,bdf=0x1700/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,port=0x0,bdf=0x0/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,port=0x0,bdf=0x1/
              24,138      hisi_pcie0_core1/rx_mrd_flux,port=0x0,bdf=0x1700/
              24,126      hisi_pcie0_core1/rx_mrd_flux,port=0x1,bdf=0x0/

after the patch:
     <not supported>      hisi_pcie0_core1/rx_mrd_flux/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,port=0/
              24,153      hisi_pcie0_core1/rx_mrd_flux,port=1/
                   0      hisi_pcie0_core1/rx_mrd_flux,port=0x800/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=0/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,bdf=1/
              24,117      hisi_pcie0_core1/rx_mrd_flux,bdf=0x1700/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,port=0x0,bdf=0x0/
     <not supported>      hisi_pcie0_core1/rx_mrd_flux,port=0x0,bdf=0x1/
              24,120      hisi_pcie0_core1/rx_mrd_flux,port=0x0,bdf=0x1700/
              24,123      hisi_pcie0_core1/rx_mrd_flux,port=0x1,bdf=0x0/

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 6f39cb82661e..b2dde7559639 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -306,10 +306,10 @@ static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
 	if (hisi_pcie_get_trig_len(event) > HISI_PCIE_TRIG_MAX_VAL)
 		return false;
 
-	if (requester_id) {
-		if (!hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
-			return false;
-	}
+	/* Need to explicitly set filter of "port" or "bdf" */
+	if (!hisi_pcie_get_port(event) &&
+	    !hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
+		return false;
 
 	return true;
 }
-- 
2.24.0



From yangyicong at huawei.com  Fri Feb 23 02:33:58 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 23 Feb 2024 18:33:58 +0800
Subject: [PATCH v2 7/8] drivers/perf: hisi_pcie: Merge find_related_event() and get_event_idx()
In-Reply-To: <20240223103359.18669-1-yangyicong@huawei.com>
References: <20240223103359.18669-1-yangyicong@huawei.com>
Message-ID: <20240223103359.18669-8-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

The function xxx_find_related_event() scan all working events to find
related events. During this process, we also can find the idle counters.
If not found related events, return the first idle counter to simplify
the code.

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 51 ++++++++++----------------
 1 file changed, 19 insertions(+), 32 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 5b15f3698188..5d1f0e9fdb08 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -398,16 +398,24 @@ static u64 hisi_pcie_pmu_read_counter(struct perf_event *event)
 	return hisi_pcie_pmu_readq(pcie_pmu, event->hw.event_base, idx);
 }
 
-static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
-					    struct perf_event *event)
+/*
+ * Check all work events, if a relevant event is found then we return it
+ * first, otherwise return the first idle counter (need to reset).
+ */
+static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu,
+					struct perf_event *event)
 {
+	int first_idle = -EAGAIN;
 	struct perf_event *sibling;
 	int idx;
 
 	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
 		sibling = pcie_pmu->hw_events[idx];
-		if (!sibling)
+		if (!sibling) {
+			if (first_idle == -EAGAIN)
+				first_idle = idx;
 			continue;
+		}
 
 		/* Related events must be used in group */
 		if (hisi_pcie_pmu_cmp_event(sibling, event) &&
@@ -415,19 +423,7 @@ static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
 			return idx;
 	}
 
-	return idx;
-}
-
-static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu)
-{
-	int idx;
-
-	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
-		if (!pcie_pmu->hw_events[idx])
-			return idx;
-	}
-
-	return -EINVAL;
+	return first_idle;
 }
 
 static void hisi_pcie_pmu_event_update(struct perf_event *event)
@@ -553,27 +549,18 @@ static int hisi_pcie_pmu_add(struct perf_event *event, int flags)
 
 	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
 
-	/* Check all working events to find a related event. */
-	idx = hisi_pcie_pmu_find_related_event(pcie_pmu, event);
-	if (idx < 0)
-		return idx;
-
-	/* Current event shares an enabled counter with the related event */
-	if (idx < HISI_PCIE_MAX_COUNTERS) {
-		hwc->idx = idx;
-		goto start_count;
-	}
-
-	idx = hisi_pcie_pmu_get_event_idx(pcie_pmu);
+	idx = hisi_pcie_pmu_get_event_idx(pcie_pmu, event);
 	if (idx < 0)
 		return idx;
 
 	hwc->idx = idx;
-	pcie_pmu->hw_events[idx] = event;
-	/* Reset Counter to avoid previous statistic interference. */
-	hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
 
-start_count:
+	/* No enabled counter found with related event, reset it */
+	if (!pcie_pmu->hw_events[idx]) {
+		hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
+		pcie_pmu->hw_events[idx] = event;
+	}
+
 	if (flags & PERF_EF_START)
 		hisi_pcie_pmu_start(event, PERF_EF_RELOAD);
 
-- 
2.24.0



From yangyicong at huawei.com  Fri Feb 23 02:33:52 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 23 Feb 2024 18:33:52 +0800
Subject: [PATCH v2 1/8] drivers/perf: hisi_pcie: Rename hisi_pcie_pmu_{config,clear}_filter()
In-Reply-To: <20240223103359.18669-1-yangyicong@huawei.com>
References: <20240223103359.18669-1-yangyicong@huawei.com>
Message-ID: <20240223103359.18669-2-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

hisi_pcie_pmu_{config,clear}_filter() are config/clear HISI_PCIE_EVENT_CTRL
register which contains not only the filter but also the event code. The
function names are bit misleading. Rename it to
hisi_pcie_pmu_{config,clear}_event_ctrl() to reflects their functions
more accurately.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index b90ba8aca3fa..9760ddde46fd 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -216,7 +216,7 @@ static void hisi_pcie_pmu_writeq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
 	writeq_relaxed(val, pcie_pmu->base + offset);
 }
 
-static void hisi_pcie_pmu_config_filter(struct perf_event *event)
+static void hisi_pcie_pmu_config_event_ctrl(struct perf_event *event)
 {
 	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
@@ -259,7 +259,7 @@ static void hisi_pcie_pmu_config_filter(struct perf_event *event)
 	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
 }
 
-static void hisi_pcie_pmu_clear_filter(struct perf_event *event)
+static void hisi_pcie_pmu_clear_event_ctrl(struct perf_event *event)
 {
 	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
@@ -505,7 +505,7 @@ static void hisi_pcie_pmu_start(struct perf_event *event, int flags)
 	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
 	hwc->state = 0;
 
-	hisi_pcie_pmu_config_filter(event);
+	hisi_pcie_pmu_config_event_ctrl(event);
 	hisi_pcie_pmu_enable_counter(pcie_pmu, hwc);
 	hisi_pcie_pmu_enable_int(pcie_pmu, hwc);
 	hisi_pcie_pmu_set_period(event);
@@ -526,7 +526,7 @@ static void hisi_pcie_pmu_stop(struct perf_event *event, int flags)
 	hisi_pcie_pmu_event_update(event);
 	hisi_pcie_pmu_disable_int(pcie_pmu, hwc);
 	hisi_pcie_pmu_disable_counter(pcie_pmu, hwc);
-	hisi_pcie_pmu_clear_filter(event);
+	hisi_pcie_pmu_clear_event_ctrl(event);
 	WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
 	hwc->state |= PERF_HES_STOPPED;
 
-- 
2.24.0



From yangyicong at huawei.com  Fri Feb 23 02:33:53 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 23 Feb 2024 18:33:53 +0800
Subject: [PATCH v2 2/8] drivers/perf: hisi_pcie: Introduce hisi_pcie_pmu_get_event_ctrl_val()
In-Reply-To: <20240223103359.18669-1-yangyicong@huawei.com>
References: <20240223103359.18669-1-yangyicong@huawei.com>
Message-ID: <20240223103359.18669-3-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

Factor out retrieving of the register value for the
corresponding event from hisi_pcie_config_event_ctrl() into a
new function hisi_pcie_pmu_get_event_ctrl_val() allowing future
reuse.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 9760ddde46fd..2468cf3b007c 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -216,10 +216,8 @@ static void hisi_pcie_pmu_writeq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
 	writeq_relaxed(val, pcie_pmu->base + offset);
 }
 
-static void hisi_pcie_pmu_config_event_ctrl(struct perf_event *event)
+static u64 hisi_pcie_pmu_get_event_ctrl_val(struct perf_event *event)
 {
-	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
-	struct hw_perf_event *hwc = &event->hw;
 	u64 port, trig_len, thr_len, len_mode;
 	u64 reg = HISI_PCIE_INIT_SET;
 
@@ -256,6 +254,15 @@ static void hisi_pcie_pmu_config_event_ctrl(struct perf_event *event)
 	else
 		reg |= FIELD_PREP(HISI_PCIE_LEN_M, HISI_PCIE_LEN_M_DEFAULT);
 
+	return reg;
+}
+
+static void hisi_pcie_pmu_config_event_ctrl(struct perf_event *event)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u64 reg = hisi_pcie_pmu_get_event_ctrl_val(event);
+
 	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
 }
 
-- 
2.24.0



From yangyicong at huawei.com  Fri Feb 23 02:33:59 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 23 Feb 2024 18:33:59 +0800
Subject: [PATCH v2 8/8] docs: perf: Update usage for target filter of hisi-pcie-pmu
In-Reply-To: <20240223103359.18669-1-yangyicong@huawei.com>
References: <20240223103359.18669-1-yangyicong@huawei.com>
Message-ID: <20240223103359.18669-9-yangyicong@huawei.com>

From: Junhao He <hejunhao3 at huawei.com>

One of the "port" and "bdf" target filter interface must be set, and
the related events should preferably used in the same group.
Update the usage in the documentation.

Signed-off-by: Junhao He <hejunhao3 at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 .../admin-guide/perf/hisi-pcie-pmu.rst        | 31 ++++++++++++++-----
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
index 7e863662e2d4..678d3865560c 100644
--- a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
+++ b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
@@ -37,9 +37,20 @@ Example usage of perf::
   hisi_pcie0_core0/rx_mwr_cnt/ [kernel PMU event]
   ------------------------------------------
 
-  $# perf stat -e hisi_pcie0_core0/rx_mwr_latency/
-  $# perf stat -e hisi_pcie0_core0/rx_mwr_cnt/
-  $# perf stat -g -e hisi_pcie0_core0/rx_mwr_latency/ -e hisi_pcie0_core0/rx_mwr_cnt/
+  $# perf stat -e hisi_pcie0_core0/rx_mwr_latency,port=0xffff/
+  $# perf stat -e hisi_pcie0_core0/rx_mwr_cnt,port=0xffff/
+
+The related events usually used to calculate the bandwidth, latency or others.
+They need to start and end counting at the same time, therefore related events
+are best used in the same event group to get the expected value. There are two
+ways to know if they are related events:
+a) By event name, such as the latency events "xxx_latency, xxx_cnt" or
+   bandwidth events "xxx_flux, xxx_time".
+b) By event type, such as "event=0xXXXX, event=0x1XXXX".
+
+Example usage of perf group::
+
+  $# perf stat -e "{hisi_pcie0_core0/rx_mwr_latency,port=0xffff/,hisi_pcie0_core0/rx_mwr_cnt,port=0xffff/}"
 
 The current driver does not support sampling. So "perf record" is unsupported.
 Also attach to a task is unsupported for PCIe PMU.
@@ -51,8 +62,12 @@ Filter options
 
    PMU could only monitor the performance of traffic downstream target Root
    Ports or downstream target Endpoint. PCIe PMU driver support "port" and
-   "bdf" interfaces for users, and these two interfaces aren't supported at the
-   same time.
+   "bdf" interfaces for users.
+   Please notice that, one of these two interfaces must be set, and these two
+   interfaces aren't supported at the same time. If they are both set, only
+   "port" filter is valid.
+   If "port" filter not being set or is set explicitly to zero (default), the
+   "bdf" filter will be in effect, because "bdf=0" meaning 0000:000:00.0.
 
    - port
 
@@ -95,7 +110,7 @@ Filter options
 
    Example usage of perf::
 
-     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,trig_len=0x4,trig_mode=1/ sleep 5
+     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,port=0xffff,trig_len=0x4,trig_mode=1/ sleep 5
 
 3. Threshold filter
 
@@ -109,7 +124,7 @@ Filter options
 
    Example usage of perf::
 
-     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,thr_len=0x4,thr_mode=1/ sleep 5
+     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,port=0xffff,thr_len=0x4,thr_mode=1/ sleep 5
 
 4. TLP Length filter
 
@@ -127,4 +142,4 @@ Filter options
 
    Example usage of perf::
 
-     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,len_mode=0x1/ sleep 5
+     $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,port=0xffff,len_mode=0x1/ sleep 5
-- 
2.24.0



From yangyicong at huawei.com  Fri Feb 23 02:33:55 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Fri, 23 Feb 2024 18:33:55 +0800
Subject: [PATCH v2 4/8] drivers/perf: hisi_pcie: Add more events for counting TLP bandwidth
In-Reply-To: <20240223103359.18669-1-yangyicong@huawei.com>
References: <20240223103359.18669-1-yangyicong@huawei.com>
Message-ID: <20240223103359.18669-5-yangyicong@huawei.com>

From: Yicong Yang <yangyicong at hisilicon.com>

A typical PCIe transaction is consisted of various TLP packets in both
direction. For counting bandwidth only memory read events are exported
currently. Add memory write and completion counting events of both
direction to complete the bandwidth counting.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
---
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
index 9176242eadb3..6f39cb82661e 100644
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -727,10 +727,18 @@ static struct attribute *hisi_pcie_pmu_events_attr[] = {
 	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
 	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
 	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_flux, 0x0104),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_time, 0x10104),
 	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x0804),
 	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x10804),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_cpl_flux, 0x2004),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_cpl_time, 0x12004),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_mwr_flux, 0x0105),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_mwr_time, 0x10105),
 	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x0405),
 	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x10405),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_cpl_flux, 0x1005),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_cpl_time, 0x11005),
 	NULL
 };
 
-- 
2.24.0



From biju.das.jz at bp.renesas.com  Fri Feb 23 02:45:07 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Fri, 23 Feb 2024 10:45:07 +0000
Subject: [PATCH v12 02/25] genirq/irqdomain: Remove the param count
 restriction from select()
In-Reply-To: <481aa3b9-55c2-4ccb-bb4a-58b924d77ad7@samsung.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
	<20240127161753.114685-3-apatel@ventanamicro.com>
	<CGME20240223102258eucas1p119f38e40f769c883c0a502e9e26be888@eucas1p1.samsung.com>
 <481aa3b9-55c2-4ccb-bb4a-58b924d77ad7@samsung.com>
Message-ID: <TYCPR01MB112692BF27640D12CEF5987BE86552@TYCPR01MB11269.jpnprd01.prod.outlook.com>

Hi Marek Szyprowski,

> -----Original Message-----
> From: linux-arm-kernel <linux-arm-kernel-bounces at lists.infradead.org> On
> Behalf Of Marek Szyprowski
> Sent: Friday, February 23, 2024 10:23 AM
> Subject: Re: [PATCH v12 02/25] genirq/irqdomain: Remove the param count
> restriction from select()
> 
> Dear All,
> 
> On 27.01.2024 17:17, Anup Patel wrote:
> > From: Thomas Gleixner <tglx at linutronix.de>
> >
> > Now that the GIC-v3 callback can handle invocation with a fwspec
> > parameter count of 0 lift the restriction in the core code and invoke
> > select() unconditionally when the domain provides it.
> >
> > Preparatory change for per device MSI domains.
> >
> > Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
> > Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> 
> 
> This patch landed recently in linux-next (next-20240221) as commit
> de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from
> select()"). I've noticed that it breaks booting of Qualcomm's Robotics
> RB5 ARM64 board (arch/arm64/boot/dts/qcom/qrb5165-rb5.dts). Booting
> freezes after "clk: Disabling unused clocks", but this is probably a
> consequence of some earlier failure. Reverting $subject on top of
> next-20240221 fixes this problem. Let me know how can I help debugging
> this issue.
> 
> 
> > ---
> >   kernel/irq/irqdomain.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index
> > 0bdef4fe925b..8fee37918195 100644
> > --- a/kernel/irq/irqdomain.c
> > +++ b/kernel/irq/irqdomain.c
> > @@ -448,7 +448,7 @@ struct irq_domain *irq_find_matching_fwspec(struct
> irq_fwspec *fwspec,
> >   	 */
> >   	mutex_lock(&irq_domain_mutex);
> >   	list_for_each_entry(h, &irq_domain_list, link) {
> > -		if (h->ops->select && fwspec->param_count)
> > +		if (h->ops->select)
> >   			rc = h->ops->select(h, fwspec, bus_token);
> >   		else if (h->ops->match)
> >   			rc = h->ops->match(h, to_of_node(fwnode), bus_token);

This patch looks reverted on todays's next. But there was a fix for fixing the issue you mentioned [1]

[1] https://lore.kernel.org/all/170844679345.398.17551290253758129895.tip-bot2 at tip-bot2/

Cheers,
Biju


From m.szyprowski at samsung.com  Fri Feb 23 02:56:32 2024
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Fri, 23 Feb 2024 11:56:32 +0100
Subject: [PATCH v12 02/25] genirq/irqdomain: Remove the param count
 restriction from select()
In-Reply-To: <TYCPR01MB112692BF27640D12CEF5987BE86552@TYCPR01MB11269.jpnprd01.prod.outlook.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
	<20240127161753.114685-3-apatel@ventanamicro.com>
	<CGME20240223102258eucas1p119f38e40f769c883c0a502e9e26be888@eucas1p1.samsung.com>
	<481aa3b9-55c2-4ccb-bb4a-58b924d77ad7@samsung.com>
	<TYCPR01MB112692BF27640D12CEF5987BE86552@TYCPR01MB11269.jpnprd01.prod.outlook.com>
Message-ID: <870534fc-eaa6-4da6-9180-a051443fbaa6@samsung.com>

On 23.02.2024 11:45, Biju Das wrote:
>> On 27.01.2024 17:17, Anup Patel wrote:
>>> From: Thomas Gleixner <tglx at linutronix.de>
>>>
>>> Now that the GIC-v3 callback can handle invocation with a fwspec
>>> parameter count of 0 lift the restriction in the core code and invoke
>>> select() unconditionally when the domain provides it.
>>>
>>> Preparatory change for per device MSI domains.
>>>
>>> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
>>> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
>>
>> This patch landed recently in linux-next (next-20240221) as commit
>> de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from
>> select()"). I've noticed that it breaks booting of Qualcomm's Robotics
>> RB5 ARM64 board (arch/arm64/boot/dts/qcom/qrb5165-rb5.dts). Booting
>> freezes after "clk: Disabling unused clocks", but this is probably a
>> consequence of some earlier failure. Reverting $subject on top of
>> next-20240221 fixes this problem. Let me know how can I help debugging
>> this issue.
>>
>>
>>> ---
>>>    kernel/irq/irqdomain.c | 2 +-
>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index
>>> 0bdef4fe925b..8fee37918195 100644
>>> --- a/kernel/irq/irqdomain.c
>>> +++ b/kernel/irq/irqdomain.c
>>> @@ -448,7 +448,7 @@ struct irq_domain *irq_find_matching_fwspec(struct
>> irq_fwspec *fwspec,
>>>    	 */
>>>    	mutex_lock(&irq_domain_mutex);
>>>    	list_for_each_entry(h, &irq_domain_list, link) {
>>> -		if (h->ops->select && fwspec->param_count)
>>> +		if (h->ops->select)
>>>    			rc = h->ops->select(h, fwspec, bus_token);
>>>    		else if (h->ops->match)
>>>    			rc = h->ops->match(h, to_of_node(fwnode), bus_token);
> This patch looks reverted on todays's next. But there was a fix for fixing the issue you mentioned [1]
>
> [1] https://lore.kernel.org/all/170844679345.398.17551290253758129895.tip-bot2 at tip-bot2/

Thanks! Today's next seems to be broken on ARM64 (doesn't compile here), 
so I've missed it.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From patchwork-bot+netdevbpf at kernel.org  Fri Feb 23 03:00:28 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 23 Feb 2024 11:00:28 +0000
Subject: [PATCH net-next v5] net: stmmac: dwmac-qcom-ethqos: Add support for
 2.5G SGMII
In-Reply-To: <20240220050735.29507-1-quic_snehshah@quicinc.com>
References: <20240220050735.29507-1-quic_snehshah@quicinc.com>
Message-ID: <170868602872.17679.14029425242387308539.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by David S. Miller <davem at davemloft.net>:

On Tue, 20 Feb 2024 10:37:35 +0530 you wrote:
> Serdes phy needs to operate at 2500 mode for 2.5G speed and 1000
> mode for 1G/100M/10M speed.
> Added changes to configure serdes phy and mac based on link speed.
> Changing serdes phy speed involves multiple register writes for
> serdes block. To avoid redundant write operations only update serdes
> phy when new speed is different.
> For 2500 speed MAC PCS autoneg needs to disabled. Added changes to
> disable MAC PCS autoneg if ANE parameter is not set.
> 
> [...]

Here is the summary with links:
  - [net-next,v5] net: stmmac: dwmac-qcom-ethqos: Add support for 2.5G SGMII
    https://git.kernel.org/netdev/net-next/c/a818bd12538c

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From biju.das.jz at bp.renesas.com  Fri Feb 23 03:01:18 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Fri, 23 Feb 2024 11:01:18 +0000
Subject: [PATCH v12 02/25] genirq/irqdomain: Remove the param count
 restriction from select()
In-Reply-To: <870534fc-eaa6-4da6-9180-a051443fbaa6@samsung.com>
References: <20240127161753.114685-1-apatel@ventanamicro.com>
	<20240127161753.114685-3-apatel@ventanamicro.com>
	<CGME20240223102258eucas1p119f38e40f769c883c0a502e9e26be888@eucas1p1.samsung.com>
	<481aa3b9-55c2-4ccb-bb4a-58b924d77ad7@samsung.com>
	<TYCPR01MB112692BF27640D12CEF5987BE86552@TYCPR01MB11269.jpnprd01.prod.outlook.com>
 <870534fc-eaa6-4da6-9180-a051443fbaa6@samsung.com>
Message-ID: <TYCPR01MB11269D56CFF46F731F932245886552@TYCPR01MB11269.jpnprd01.prod.outlook.com>

Hi Marek Szyprowski,

> -----Original Message-----
> From: Marek Szyprowski <m.szyprowski at samsung.com>
> Sent: Friday, February 23, 2024 10:57 AM
> Subject: Re: [PATCH v12 02/25] genirq/irqdomain: Remove the param count
> restriction from select()
> 
> On 23.02.2024 11:45, Biju Das wrote:
> >> On 27.01.2024 17:17, Anup Patel wrote:
> >>> From: Thomas Gleixner <tglx at linutronix.de>
> >>>
> >>> Now that the GIC-v3 callback can handle invocation with a fwspec
> >>> parameter count of 0 lift the restriction in the core code and
> >>> invoke
> >>> select() unconditionally when the domain provides it.
> >>>
> >>> Preparatory change for per device MSI domains.
> >>>
> >>> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
> >>> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
> >>
> >> This patch landed recently in linux-next (next-20240221) as commit
> >> de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction
> >> from select()"). I've noticed that it breaks booting of Qualcomm's
> >> Robotics
> >> RB5 ARM64 board (arch/arm64/boot/dts/qcom/qrb5165-rb5.dts). Booting
> >> freezes after "clk: Disabling unused clocks", but this is probably a
> >> consequence of some earlier failure. Reverting $subject on top of
> >> next-20240221 fixes this problem. Let me know how can I help
> >> debugging this issue.
> >>
> >>
> >>> ---
> >>>    kernel/irq/irqdomain.c | 2 +-
> >>>    1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index
> >>> 0bdef4fe925b..8fee37918195 100644
> >>> --- a/kernel/irq/irqdomain.c
> >>> +++ b/kernel/irq/irqdomain.c
> >>> @@ -448,7 +448,7 @@ struct irq_domain
> >>> *irq_find_matching_fwspec(struct
> >> irq_fwspec *fwspec,
> >>>    	 */
> >>>    	mutex_lock(&irq_domain_mutex);
> >>>    	list_for_each_entry(h, &irq_domain_list, link) {
> >>> -		if (h->ops->select && fwspec->param_count)
> >>> +		if (h->ops->select)
> >>>    			rc = h->ops->select(h, fwspec, bus_token);
> >>>    		else if (h->ops->match)
> >>>    			rc = h->ops->match(h, to_of_node(fwnode),
> bus_token);
> > This patch looks reverted on todays's next. But there was a fix for
> > fixing the issue you mentioned [1]
> >
> > [1]
> > https://jpn01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore
> > .kernel.org%2Fall%2F170844679345.398.17551290253758129895.tip-bot2%40t
> > ip-bot2%2F&data=05%7C02%7Cbiju.das.jz%40bp.renesas.com%7Cffce754120ba4
> > ff0f8d708dc345e1c1a%7C53d82571da1947e49cb4625a166a4a2a%7C0%7C0%7C63844
> > 2825998732581%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2lu
> > MzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=lYLVpa4tz2fEU1Jc
> > DDGUF6eigi2YJuGDouMXrJSlibo%3D&reserved=0
> 
> Thanks! Today's next seems to be broken on ARM64 (doesn't compile here),
> so I've missed it.

FYI, ARM64 defconfig works for me.
Linux smarc-rzg2l 6.8.0-rc5-next-20240223-gfebe82167ab7 #1430 SMP PREEMPT Fri Feb 23 07:41:52 GMT 2024 aarch64 GNU/Linux

Cheers,
Biju




From schnelle at linux.ibm.com  Fri Feb 23 03:01:24 2024
From: schnelle at linux.ibm.com (Niklas Schnelle)
Date: Fri, 23 Feb 2024 12:01:24 +0100
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
	 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
	 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
	 <20240222223617.GC13330@nvidia.com>
	 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
Message-ID: <61931c626d9bc54369d73fda8f8ee59bbb5e95bc.camel@linux.ibm.com>

On Fri, 2024-02-23 at 09:07 +0000, David Laight wrote:
> From: Jason Gunthorpe
> > Sent: 22 February 2024 22:36
> > To: David Laight <David.Laight at ACULAB.COM>
> > 
> > On Thu, Feb 22, 2024 at 10:05:04PM +0000, David Laight wrote:
> > > From: Jason Gunthorpe
> > > > Sent: 21 February 2024 01:17
> > > > 
> > > > The kernel provides driver support for using write combining IO memory
> > > > through the __iowriteXX_copy() API which is commonly used as an optional
> > > > optimization to generate 16/32/64 byte MemWr TLPs in a PCIe environment.
> > > > 
> > > ...
> > > > Implement __iowrite32/64_copy() specifically for ARM64 and use inline
> > > > assembly to build consecutive blocks of STR instructions. Provide direct
> > > > support for 64/32/16 large TLP generation in this manner. Optimize for
> > > > common constant lengths so that the compiler can directly inline the store
> > > > blocks.
> > > ...
> > > > +/*
> > > > + * This generates a memcpy that works on a from/to address which is aligned to
> > > > + * bits. Count is in terms of the number of bits sized quantities to copy. It
> > > > + * optimizes to use the STR groupings when possible so that it is WC friendly.
> > > > + */
> > > > +#define memcpy_toio_aligned(to, from, count, bits)                        \
> > > > +	({                                                                \
> > > > +		volatile u##bits __iomem *_to = to;                       \
> > > > +		const u##bits *_from = from;                              \
> > > > +		size_t _count = count;                                    \
> > > > +		const u##bits *_end_from = _from + ALIGN_DOWN(_count, 8); \
> > > > +                                                                          \
> > > > +		for (; _from < _end_from; _from += 8, _to += 8)           \
> > > > +			__const_memcpy_toio_aligned##bits(_to, _from, 8); \
> > > > +		if ((_count % 8) >= 4) {
> > > 
> > > If (_count & 4) {
> > 
> > That would be obfuscating, IMHO. The compiler doesn't need such things
> > to generate optimal code.
> 
> Try it: https://godbolt.org/z/EvvGrTxv3 
> And it isn't that obfuscated - no more so than your version.

The godbolt link does "n % 8 > 4" instead of "... >= 4" as in Jason's
original code. With ">=" the compiled code matches that for "n & 4".


From David.Laight at ACULAB.COM  Fri Feb 23 03:05:29 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 23 Feb 2024 11:05:29 +0000
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <61931c626d9bc54369d73fda8f8ee59bbb5e95bc.camel@linux.ibm.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
	 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
	 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
	 <20240222223617.GC13330@nvidia.com>
	 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
 <61931c626d9bc54369d73fda8f8ee59bbb5e95bc.camel@linux.ibm.com>
Message-ID: <3227d5224a9745e388738d016fdae87a@AcuMS.aculab.com>

...
> > > > > +		if ((_count % 8) >= 4) {
> > > >
> > > > If (_count & 4) {
> > >
> > > That would be obfuscating, IMHO. The compiler doesn't need such things
> > > to generate optimal code.
> >
> > Try it: https://godbolt.org/z/EvvGrTxv3
> > And it isn't that obfuscated - no more so than your version.
> 
> The godbolt link does "n % 8 > 4" instead of "... >= 4" as in Jason's
> original code. With ">=" the compiled code matches that for "n & 4".

Bugger :-)

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From maz at kernel.org  Fri Feb 23 03:07:02 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 23 Feb 2024 11:07:02 +0000
Subject: [PATCH v4 03/14] arm64/fpsimd: Support FEAT_FPMR
In-Reply-To: <20240122-arm64-2023-dpisa-v4-3-776e094861df@kernel.org>
References: <20240122-arm64-2023-dpisa-v4-0-776e094861df@kernel.org>
	<20240122-arm64-2023-dpisa-v4-3-776e094861df@kernel.org>
Message-ID: <86r0h330dl.wl-maz@kernel.org>

On Mon, 22 Jan 2024 16:28:06 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> FEAT_FPMR defines a new EL0 accessible register FPMR use to configure the
> FP8 related features added to the architecture at the same time. Detect
> support for this register and context switch it for EL0 when present.
> 
> Due to the sharing of responsibility for saving floating point state
> between the host kernel and KVM FP8 support is not yet implemented in KVM
> and a stub similar to that used for SVCR is provided for FPMR in order to
> avoid bisection issues. To make it easier to share host state with the
> hypervisor we store FPMR as a hardened usercopy field in uw (along with
> some padding).
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/include/asm/cpufeature.h |  5 +++++
>  arch/arm64/include/asm/fpsimd.h     |  2 ++
>  arch/arm64/include/asm/kvm_host.h   |  1 +
>  arch/arm64/include/asm/processor.h  |  4 ++++
>  arch/arm64/kernel/cpufeature.c      |  9 +++++++++
>  arch/arm64/kernel/fpsimd.c          | 13 +++++++++++++
>  arch/arm64/kvm/fpsimd.c             |  1 +
>  arch/arm64/tools/cpucaps            |  1 +
>  8 files changed, 36 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index 21c824edf8ce..34fcdbc65d7d 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -768,6 +768,11 @@ static __always_inline bool system_supports_tpidr2(void)
>  	return system_supports_sme();
>  }
>  
> +static __always_inline bool system_supports_fpmr(void)
> +{
> +	return alternative_has_cap_unlikely(ARM64_HAS_FPMR);
> +}
> +
>  static __always_inline bool system_supports_cnp(void)
>  {
>  	return alternative_has_cap_unlikely(ARM64_HAS_CNP);
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index 50e5f25d3024..6cf72b0d2c04 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -89,6 +89,7 @@ struct cpu_fp_state {
>  	void *sve_state;
>  	void *sme_state;
>  	u64 *svcr;
> +	unsigned long *fpmr;
>  	unsigned int sve_vl;
>  	unsigned int sme_vl;
>  	enum fp_type *fp_type;
> @@ -154,6 +155,7 @@ extern void cpu_enable_sve(const struct arm64_cpu_capabilities *__unused);
>  extern void cpu_enable_sme(const struct arm64_cpu_capabilities *__unused);
>  extern void cpu_enable_sme2(const struct arm64_cpu_capabilities *__unused);
>  extern void cpu_enable_fa64(const struct arm64_cpu_capabilities *__unused);
> +extern void cpu_enable_fpmr(const struct arm64_cpu_capabilities *__unused);
>  
>  extern u64 read_smcr_features(void);
>  
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 21c57b812569..7993694a54af 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -543,6 +543,7 @@ struct kvm_vcpu_arch {
>  	enum fp_type fp_type;
>  	unsigned int sve_max_vl;
>  	u64 svcr;
> +	unsigned long fpmr;

As this directly represents a register, I'd rather you use a type that
represents the size of that register unambiguously (u64).

>  
>  	/* 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 5b0a04810b23..b453c66d3fae 100644
> --- a/arch/arm64/include/asm/processor.h
> +++ b/arch/arm64/include/asm/processor.h
> @@ -155,6 +155,8 @@ struct thread_struct {
>  	struct {
>  		unsigned long	tp_value;	/* TLS register */
>  		unsigned long	tp2_value;
> +		unsigned long	fpmr;
> +		unsigned long	pad;
>  		struct user_fpsimd_state fpsimd_state;
>  	} uw;
>  
> @@ -253,6 +255,8 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,
>  	BUILD_BUG_ON(sizeof_field(struct thread_struct, uw) !=
>  		     sizeof_field(struct thread_struct, uw.tp_value) +
>  		     sizeof_field(struct thread_struct, uw.tp2_value) +
> +		     sizeof_field(struct thread_struct, uw.fpmr) +
> +		     sizeof_field(struct thread_struct, uw.pad) +
>  		     sizeof_field(struct thread_struct, uw.fpsimd_state));
>  
>  	*offset = offsetof(struct thread_struct, uw);
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index eae59ec0f4b0..0263565f617a 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -272,6 +272,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
>  };
>  
>  static const struct arm64_ftr_bits ftr_id_aa64pfr2[] = {
> +	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_FPMR_SHIFT, 4, 0),
>  	ARM64_FTR_END,
>  };
>  
> @@ -2767,6 +2768,14 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>  		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
>  		.matches = has_lpa2,
>  	},
> +	{
> +		.desc = "FPMR",
> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> +		.capability = ARM64_HAS_FPMR,
> +		.matches = has_cpuid_feature,
> +		.cpu_enable = cpu_enable_fpmr,
> +		ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, FPMR, IMP)
> +	},
>  	{},
>  };
>  
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index a5dc6f764195..8e24b5e5e192 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -359,6 +359,9 @@ static void task_fpsimd_load(void)
>  	WARN_ON(preemptible());
>  	WARN_ON(test_thread_flag(TIF_KERNEL_FPSTATE));
>  
> +	if (system_supports_fpmr())
> +		write_sysreg_s(current->thread.uw.fpmr, SYS_FPMR);
> +
>  	if (system_supports_sve() || system_supports_sme()) {
>  		switch (current->thread.fp_type) {
>  		case FP_STATE_FPSIMD:
> @@ -446,6 +449,9 @@ static void fpsimd_save_user_state(void)
>  	if (test_thread_flag(TIF_FOREIGN_FPSTATE))
>  		return;
>  
> +	if (system_supports_fpmr())
> +		*(last->fpmr) = read_sysreg_s(SYS_FPMR);
> +
>  	/*
>  	 * If a task is in a syscall the ABI allows us to only
>  	 * preserve the state shared with FPSIMD so don't bother
> @@ -688,6 +694,12 @@ static void sve_to_fpsimd(struct task_struct *task)
>  	}
>  }
>  
> +void cpu_enable_fpmr(const struct arm64_cpu_capabilities *__always_unused p)
> +{
> +	write_sysreg_s(read_sysreg_s(SYS_SCTLR_EL1) | SCTLR_EL1_EnFPM_MASK,
> +		       SYS_SCTLR_EL1);
> +}
> +
>  #ifdef CONFIG_ARM64_SVE
>  /*
>   * Call __sve_free() directly only if you know task can't be scheduled
> @@ -1680,6 +1692,7 @@ static void fpsimd_bind_task_to_cpu(void)
>  	last->sve_vl = task_get_sve_vl(current);
>  	last->sme_vl = task_get_sme_vl(current);
>  	last->svcr = &current->thread.svcr;
> +	last->fpmr = &current->thread.uw.fpmr;
>  	last->fp_type = &current->thread.fp_type;
>  	last->to_save = FP_STATE_CURRENT;
>  	current->thread.fpsimd_cpu = smp_processor_id();
> diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
> index 8c1d0d4853df..e3e611e30e91 100644
> --- a/arch/arm64/kvm/fpsimd.c
> +++ b/arch/arm64/kvm/fpsimd.c
> @@ -153,6 +153,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
>  		fp_state.sve_vl = vcpu->arch.sve_max_vl;
>  		fp_state.sme_state = NULL;
>  		fp_state.svcr = &vcpu->arch.svcr;
> +		fp_state.fpmr = &vcpu->arch.fpmr;
>  		fp_state.fp_type = &vcpu->arch.fp_type;

Given the number of fields you keep track of, it would make a lot more
sense if these FP-related fields were in their own little structure
and tracked by a single pointer (I don't think there is a case where
we track them independently).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Fri Feb 23 03:18:51 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 23 Feb 2024 11:18:51 +0000
Subject: [PATCH v4 12/14] KVM: arm64: Support FEAT_FPMR for guests
In-Reply-To: <20240122-arm64-2023-dpisa-v4-12-776e094861df@kernel.org>
References: <20240122-arm64-2023-dpisa-v4-0-776e094861df@kernel.org>
	<20240122-arm64-2023-dpisa-v4-12-776e094861df@kernel.org>
Message-ID: <86plwn2ztw.wl-maz@kernel.org>

On Mon, 22 Jan 2024 16:28:15 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> FEAT_FPMR introduces a new system register FPMR which allows configuration
> of floating point behaviour, currently for FP8 specific features. Allow use
> of this in guests, disabling the trap while guests are running and saving
> and restoring the value along with the rest of the floating point state.
> Since FPMR is stored immediately after the main floating point state we
> share it with the hypervisor by adjusting the size of the shared region.
> 
> Access to FPMR is covered by both a register specific trap HCRX_EL2.EnFPM
> and the overall floating point access trap so we just unconditionally
> enable the FPMR specific trap and rely on the floating point access trap to
> detect guest floating point usage.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_arm.h        |  2 +-
>  arch/arm64/include/asm/kvm_host.h       |  3 ++-
>  arch/arm64/kvm/emulate-nested.c         |  8 ++++++++
>  arch/arm64/kvm/fpsimd.c                 |  2 +-
>  arch/arm64/kvm/hyp/include/hyp/switch.h |  7 ++++++-
>  arch/arm64/kvm/sys_regs.c               | 11 +++++++++++
>  6 files changed, 29 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 7f45ce9170bb..b2ddb6165953 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -103,7 +103,7 @@
>  #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
>  
>  #define HCRX_GUEST_FLAGS \
> -	(HCRX_EL2_SMPME | HCRX_EL2_TCR2En | \
> +	(HCRX_EL2_SMPME | HCRX_EL2_TCR2En | HCRX_EL2_EnFPM | \

No. We don't do that anymore. This can only be enabled if the guest
has it advertised via ID_AA64PFR2_EL1.FPMR.

>  	 (cpus_have_final_cap(ARM64_HAS_MOPS) ? (HCRX_EL2_MSCEn | HCRX_EL2_MCE2) : 0))
>  #define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En | HCRX_EL2_EnFPM)
>  
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index c4fdcc94d733..99c0f8944f04 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -384,6 +384,8 @@ enum vcpu_sysreg {
>  	APGAKEYLO_EL1,
>  	APGAKEYHI_EL1,
>  
> +	FPMR,
> +
>  	/* Memory Tagging Extension registers */
>  	RGSR_EL1,	/* Random Allocation Tag Seed Register */
>  	GCR_EL1,	/* Tag Control Register */
> @@ -544,7 +546,6 @@ struct kvm_vcpu_arch {
>  	enum fp_type fp_type;
>  	unsigned int sve_max_vl;
>  	u64 svcr;
> -	unsigned long fpmr;
>  
>  	/* Stage 2 paging state used by the hardware on next switch */
>  	struct kvm_s2_mmu *hw_mmu;
> diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
> index 431fd429932d..3af5fd0e28dc 100644
> --- a/arch/arm64/kvm/emulate-nested.c
> +++ b/arch/arm64/kvm/emulate-nested.c
> @@ -67,6 +67,8 @@ enum cgt_group_id {
>  	CGT_HCR_TTLBIS,
>  	CGT_HCR_TTLBOS,
>  
> +	CGT_HCRX_EnFPM,
> +
>  	CGT_MDCR_TPMCR,
>  	CGT_MDCR_TPM,
>  	CGT_MDCR_TDE,
> @@ -279,6 +281,11 @@ static const struct trap_bits coarse_trap_bits[] = {
>  		.mask		= HCR_TTLBOS,
>  		.behaviour	= BEHAVE_FORWARD_ANY,
>  	},
> +	[CGT_HCRX_EnFPM] = {
> +		.index		= HCRX_EL2,
> +		.mask		= HCRX_EL2_EnFPM,
> +		.behaviour	= BEHAVE_FORWARD_ANY,

This is obviously incorrect.

> +	},
>  	[CGT_MDCR_TPMCR] = {
>  		.index		= MDCR_EL2,
>  		.value		= MDCR_EL2_TPMCR,
> @@ -478,6 +485,7 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
>  	SR_TRAP(SYS_AIDR_EL1,		CGT_HCR_TID1),
>  	SR_TRAP(SYS_SMIDR_EL1,		CGT_HCR_TID1),
>  	SR_TRAP(SYS_CTR_EL0,		CGT_HCR_TID2),
> +	SR_TRAP(SYS_FPMR,		CGT_HCRX_EnFPM),
>  	SR_TRAP(SYS_CCSIDR_EL1,		CGT_HCR_TID2_TID4),
>  	SR_TRAP(SYS_CCSIDR2_EL1,	CGT_HCR_TID2_TID4),
>  	SR_TRAP(SYS_CLIDR_EL1,		CGT_HCR_TID2_TID4),
> diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
> index 6cf22cd8f020..9e002489c843 100644
> --- a/arch/arm64/kvm/fpsimd.c
> +++ b/arch/arm64/kvm/fpsimd.c
> @@ -152,7 +152,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
>  		fp_state.sve_vl = vcpu->arch.sve_max_vl;
>  		fp_state.sme_state = NULL;
>  		fp_state.svcr = &vcpu->arch.svcr;
> -		fp_state.fpmr = &vcpu->arch.fpmr;
> +		fp_state.fpmr = (unsigned long *)&__vcpu_sys_reg(vcpu, FPMR);
>  		fp_state.fp_type = &vcpu->arch.fp_type;
>  
>  		if (vcpu_has_sve(vcpu))
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index 27fcdfd432b9..abf785c473d0 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -370,10 +370,15 @@ 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.fp_state == FP_STATE_HOST_OWNED)
> +	if (vcpu->arch.fp_state == FP_STATE_HOST_OWNED) {
>  		__fpsimd_save_state(&(vcpu->arch.host_uw->fpsimd_state));
> +		if (cpus_have_final_cap(ARM64_HAS_FPMR))

Same thing as above: this cannot be unconditional.

> +			vcpu->arch.host_uw->fpmr = read_sysreg_s(SYS_FPMR);
> +	}
>  
>  	/* Restore the guest state */
> +	if (cpus_have_final_cap(ARM64_HAS_FPMR))
> +		write_sysreg_s(__vcpu_sys_reg(vcpu, FPMR), SYS_FPMR);
>  	if (sve_guest)
>  		__hyp_sve_restore_guest(vcpu);
>  	else
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 38503b1cd2eb..216eac44c124 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -2067,6 +2067,15 @@ static unsigned int hidden_user_visibility(const struct kvm_vcpu *vcpu,
>  	.visibility = hidden_user_visibility,	\
>  }
>  
> +static unsigned int fpmr_visibility(const struct kvm_vcpu *vcpu,
> +				    const struct sys_reg_desc *rd)
> +{
> +	if (cpus_have_final_cap(ARM64_HAS_FPMR))
> +		return 0;

Same thing.

> +
> +	return REG_HIDDEN;
> +}
> +
>  /*
>   * Since reset() callback and field val are not used for idregs, they will be
>   * used for specific purposes for idregs.
> @@ -2463,6 +2472,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 },
>  	{ SYS_DESC(SYS_CTR_EL0), access_ctr },
>  	{ SYS_DESC(SYS_SVCR), undef_access },
> +	{ SYS_DESC(SYS_FPMR), access_rw, reset_unknown, FPMR,
> +	  .visibility = fpmr_visibility },
>  
>  	{ PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, .reset = reset_pmcr,
>  	  .reg = PMCR_EL0, .get_user = get_pmcr, .set_user = set_pmcr },
> 

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From geert+renesas at glider.be  Fri Feb 23 03:20:58 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 23 Feb 2024 12:20:58 +0100
Subject: [GIT PULL 1/2] Renesas DT binding updates for v6.9 (take two)
In-Reply-To: <cover.1708687130.git.geert+renesas@glider.be>
References: <cover.1708687130.git.geert+renesas@glider.be>
Message-ID: <cover.1708687132.git.geert+renesas@glider.be>

The following changes since commit 49558e814fefdf33bf0b2d1c46c30d6a3f9634f3:

  dt-bindings: soc: renesas: Document R-Car V4M Gray Hawk Single (2024-01-31 15:06:52 +0100)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-dt-bindings-for-v6.9-tag2

for you to fetch changes up to 3a9856e830500e20e61b92f5ea6b8cc505e085be:

  dt-bindings: renesas: Document preferred compatible naming (2024-02-19 11:21:04 +0100)

----------------------------------------------------------------
Renesas DT binding updates for v6.9 (take two)

  - Restore sort order,
  - Document preferred compatible naming,

----------------------------------------------------------------
Lad Prabhakar (1):
      dt-bindings: soc: renesas: Preserve the order of SoCs based on their part numbers

Niklas S?derlund (1):
      dt-bindings: renesas: Document preferred compatible naming

 .../bindings/soc/renesas/renesas-soc.yaml          | 73 ++++++++++++++++++++++
 .../devicetree/bindings/soc/renesas/renesas.yaml   | 12 ++--
 2 files changed, 79 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas-soc.yaml


From geert+renesas at glider.be  Fri Feb 23 03:20:59 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 23 Feb 2024 12:20:59 +0100
Subject: [GIT PULL 2/2] Renesas DTS updates for v6.9 (take two)
In-Reply-To: <cover.1708687130.git.geert+renesas@glider.be>
References: <cover.1708687130.git.geert+renesas@glider.be>
Message-ID: <cover.1708687134.git.geert+renesas@glider.be>

The following changes since commit 785b3c25761a828c5e22b3361541c50fd3b92fde:

  arm64: dts: renesas: gray-hawk-single: Enable watchdog timer (2024-02-06 10:48:35 +0100)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-dts-for-v6.9-tag2

for you to fetch changes up to eaa5907bcc7611c7a07e994a69a905deca34a9b6:

  arm64: dts: renesas: rzg2l-smarc: Enable DU and link with DSI (2024-02-23 11:42:41 +0100)

----------------------------------------------------------------
Renesas DTS updates for v6.9 (take two)

  - Add pin control, I2C, GPIO, CA76 cluster, Ethernet, SD/MMC, DMA, and
    HyperFLASH/QSPI (RPC) support for the R-Car V4M SoC,
  - Add I2C EEPROM, Ethernet, eMMC, and QSPI FLASH support for the Gray
    Hawk Single development board,
  - Fix PCIe power on ULCB development boards equipped with the
    Shimafuji Kingfisher extension,
  - Add PSCI support for the RZ/G3S SoC,
  - Add camera support for the RZ/G2UL SMARC EVK development board,
  - Add display support for the RZ/G2L{,C} and RZ/V2L SoCs and SMARC EVK
    development boards,
  - Miscellaneous fixes and improvements,

----------------------------------------------------------------
Biju Das (4):
      arm64: dts: renesas: rzg2ul-smarc: Enable CRU, CSI support
      arm64: dts: renesas: r9a07g044: Add DU node
      arm64: dts: renesas: r9a07g054: Add DU node
      arm64: dts: renesas: rzg2l-smarc: Enable DU and link with DSI

Claudiu Beznea (2):
      arm64: dts: renesas: rzg3s-smarc-som: Guard Ethernet IRQ GPIO hogs
      arm64: dts: renesas: r9a08g045: Add PSCI support

Cong Dang (5):
      arm64: dts: renesas: r8a779h0: Add GPIO nodes
      arm64: dts: renesas: r8a779h0: Add SD/MMC node
      arm64: dts: renesas: gray-hawk-single: Add eMMC support
      arm64: dts: renesas: r8a779h0: Add RPC node
      arm64: dts: renesas: gray-hawk-single: Add QSPI FLASH support

Duy Nguyen (5):
      arm64: dts: renesas: r8a779h0: Add L3 cache controller
      arm64: dts: renesas: r8a779h0: Add secondary CA76 CPU cores
      arm64: dts: renesas: r8a779h0: Add CPUIdle support
      arm64: dts: renesas: r8a779h0: Add CPU core clocks
      arm64: dts: renesas: r8a779h0: Add CA76 operating points

Geert Uytterhoeven (5):
      arm64: dts: renesas: gray-hawk-single: Add serial console pin control
      arm64: dts: renesas: gray-hawk-single: Add I2C0 and EEPROMs
      arm64: dts: renesas: r8a779a0: Correct avb[01] reg sizes
      arm64: dts: renesas: r8a779g0: Correct avb[01] reg sizes
      arm64: dts: renesas: r8a779h0: Add DMA support

Hai Pham (2):
      arm64: dts: renesas: r8a779h0: Add pinctrl device node
      arm64: dts: renesas: r8a779h0: Add I2C nodes

Kuninori Morimoto (1):
      ARM: dts: renesas: r8a7778: Add missing reg-names to sound node

Lad Prabhakar (2):
      arm64: dts: renesas: rzg2l: Add missing interrupts to IRQC nodes
      arm64: dts: renesas: r9a08g045: Add missing interrupts to IRQC node

Thanh Quan (2):
      arm64: dts: renesas: r8a779h0: Add Ethernet-AVB support
      arm64: dts: renesas: gray-hawk-single: Add Ethernet support

Wolfram Sang (3):
      arm64: dts: renesas: ulcb-kf: Add regulators for PCIe ch1
      arm64: dts: renesas: ulcb-kf: Adapt 1.8V HDMI regulator to schematics
      arm64: dts: renesas: ulcb-kf: Adapt sound 5v regulator to schematics

 arch/arm/boot/dts/renesas/r8a7778.dtsi             |   2 +
 arch/arm64/boot/dts/renesas/Makefile               |   3 +
 arch/arm64/boot/dts/renesas/r8a779a0.dtsi          |   4 +-
 arch/arm64/boot/dts/renesas/r8a779g0.dtsi          |   4 +-
 .../boot/dts/renesas/r8a779h0-gray-hawk-single.dts | 173 +++++++
 arch/arm64/boot/dts/renesas/r8a779h0.dtsi          | 532 +++++++++++++++++++++
 arch/arm64/boot/dts/renesas/r9a07g043u.dtsi        |  12 +-
 .../renesas/r9a07g043u11-smarc-cru-csi-ov5645.dtso |  21 +
 arch/arm64/boot/dts/renesas/r9a07g044.dtsi         |  68 ++-
 arch/arm64/boot/dts/renesas/r9a07g054.dtsi         |  69 ++-
 arch/arm64/boot/dts/renesas/r9a08g045.dtsi         |  13 +-
 arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi       |  14 +-
 arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi      |  14 +-
 arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi   |   4 +
 arch/arm64/boot/dts/renesas/ulcb-kf.dtsi           |  49 +-
 15 files changed, 940 insertions(+), 42 deletions(-)
 create mode 100644 arch/arm64/boot/dts/renesas/r9a07g043u11-smarc-cru-csi-ov5645.dtso


From geert+renesas at glider.be  Fri Feb 23 03:20:57 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 23 Feb 2024 12:20:57 +0100
Subject: [GIT PULL 0/2] Renesas SoC updates for v6.9 (take two)
Message-ID: <cover.1708687130.git.geert+renesas@glider.be>

	Hi SoC folks,

This is my second pull request for the inclusion of Renesas SoC updates
for v6.9.

It consists of 2 parts:

  [GIT PULL 1/2] Renesas DT binding updates for v6.9 (take two)

    - Restore sort order,
    - Document preferred compatible naming,

  [GIT PULL 2/2] Renesas DTS updates for v6.9 (take two)

    - Add pin control, I2C, GPIO, CA76 cluster, Ethernet, SD/MMC, DMA, and
      HyperFLASH/QSPI (RPC) support for the R-Car V4M SoC,
    - Add I2C EEPROM, Ethernet, eMMC, and QSPI FLASH support for the Gray
      Hawk Single development board,
    - Fix PCIe power on ULCB development boards equipped with the
      Shimafuji Kingfisher extension,
    - Add PSCI support for the RZ/G3S SoC,
    - Add camera support for the RZ/G2UL SMARC EVK development board,
    - Add display support for the RZ/G2L{,C} and RZ/V2L SoCs and SMARC EVK
      development boards,
    - Miscellaneous fixes and improvements,

Thanks for pulling!

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 zajec5 at gmail.com  Fri Feb 23 03:22:23 2024
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Fri, 23 Feb 2024 12:22:23 +0100
Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_WAN_ONLINE for Internet access
Message-ID: <20240223112223.1368-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

It's common for routers to have LED indicating link on the WAN port.

Some devices however have an extra LED that's meant to be used if WAN
connection is actually "online" (there is Internet access available).

It was suggested to add #define for such use case.

Link: https://lore.kernel.org/linux-devicetree/80e92209-5578-44e7-bd4b-603a29053ddf at collabora.com/T/#u
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 include/dt-bindings/leds/common.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/leds/common.h b/include/dt-bindings/leds/common.h
index c56785bb9c9c..ecea167930d9 100644
--- a/include/dt-bindings/leds/common.h
+++ b/include/dt-bindings/leds/common.h
@@ -100,6 +100,7 @@
 #define LED_FUNCTION_TX "tx"
 #define LED_FUNCTION_USB "usb"
 #define LED_FUNCTION_WAN "wan"
+#define LED_FUNCTION_WAN_ONLINE "wan-online"
 #define LED_FUNCTION_WLAN "wlan"
 #define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz"
 #define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz"
-- 
2.35.3



From will at kernel.org  Fri Feb 23 03:26:33 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 23 Feb 2024 11:26:33 +0000
Subject: [PATCH v6 1/4] perf: starfive: Add StarLink PMU support
In-Reply-To: <20240129095141.3262366-2-jisheng.teoh@starfivetech.com>
References: <20240129095141.3262366-1-jisheng.teoh@starfivetech.com>
 <20240129095141.3262366-2-jisheng.teoh@starfivetech.com>
Message-ID: <20240223112633.GA10403@willie-the-truck>

Hi,

On Mon, Jan 29, 2024 at 05:51:38PM +0800, Ji Sheng Teoh wrote:
> This patch adds support for StarFive's StarLink PMU (Performance
> Monitor Unit). StarLink PMU integrates one or more CPU cores with
> a shared L3 memory system. The PMU supports overflow interrupt,
> up to 16 programmable 64bit event counters, and an independent
> 64bit cycle counter. StarLink PMU is accessed via MMIO.

Since Palmer acked this (thanks!), I queued it locally but then ran into
a few small issues with my build testing. Comments below.

> diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
> index 273d67ecf6d2..41278742ef88 100644
> --- a/drivers/perf/Kconfig
> +++ b/drivers/perf/Kconfig
> @@ -86,6 +86,15 @@ config RISCV_PMU_SBI
>  	  full perf feature support i.e. counter overflow, privilege mode
>  	  filtering, counter configuration.
>  
> +config STARFIVE_STARLINK_PMU
> +	depends on ARCH_STARFIVE

Please can you add "|| COMPILE_TEST" to this dependency so that you get
build coverage from other architectures?

> +	bool "StarFive StarLink PMU"
> +	help
> +	   Provide support for StarLink Performance Monitor Unit.
> +	   StarLink Performance Monitor Unit integrates one or more cores with
> +	   an L3 memory system. The L3 cache events are added into perf event
> +	   subsystem, allowing monitoring of various L3 cache perf events.
> +
>  config ARM_PMU_ACPI
>  	depends on ARM_PMU && ACPI
>  	def_bool y

[...]

> diff --git a/drivers/perf/starfive_starlink_pmu.c b/drivers/perf/starfive_starlink_pmu.c
> new file mode 100644
> index 000000000000..2447ca09a471
> --- /dev/null
> +++ b/drivers/perf/starfive_starlink_pmu.c
> @@ -0,0 +1,643 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * StarFive's StarLink PMU driver
> + *
> + * Copyright (C) 2023 StarFive Technology Co., Ltd.
> + *
> + * Author: Ji Sheng Teoh <jisheng.teoh at starfivetech.com>
> + *
> + */

[...]

> +static void starlink_pmu_counter_start(struct perf_event *event,
> +				       struct starlink_pmu *starlink_pmu)
> +{
> +	struct hw_perf_event *hwc = &event->hw;
> +	int idx = event->hw.idx;
> +	u64 val;
> +
> +	/*
> +	 * Enable counter overflow interrupt[63:0],
> +	 * which is mapped as follow:
> +	 *
> +	 * event counter 0	- Bit [0]
> +	 * event counter 1	- Bit [1]
> +	 * ...
> +	 * cycle counter	- Bit [63]
> +	 */
> +	val = readq(starlink_pmu->pmu_base + STARLINK_PMU_INTERRUPT_ENABLE);
> +
> +	if (hwc->config == STARLINK_CYCLES) {
> +		/*
> +		 * Cycle count has its dedicated register, and it starts
> +		 * counting as soon as STARLINK_PMU_GLOBAL_ENABLE is set.
> +		 */
> +		val |= STARLINK_PMU_CYCLE_OVERFLOW_MASK;
> +	} else {
> +		writeq(event->hw.config, starlink_pmu->pmu_base +
> +		       STARLINK_PMU_EVENT_SELECT + idx * sizeof(u64));
> +
> +		val |= (1 << idx);
> +	}

I think this needs to be a u64 on the right hand side, or just use the
BIT_ULL() macro.

> +
> +	writeq(val, starlink_pmu->pmu_base + STARLINK_PMU_INTERRUPT_ENABLE);
> +
> +	writeq(STARLINK_PMU_GLOBAL_ENABLE, starlink_pmu->pmu_base +
> +	       STARLINK_PMU_CONTROL);
> +}

[...]

> +static irqreturn_t starlink_pmu_handle_irq(int irq_num, void *data)
> +{
> +	struct starlink_pmu *starlink_pmu = data;
> +	struct starlink_hw_events *hw_events =
> +			this_cpu_ptr(starlink_pmu->hw_events);
> +	bool handled = false;
> +	int idx;
> +	u64 overflow_status;
> +
> +	for (idx = 0; idx < STARLINK_PMU_MAX_COUNTERS; idx++) {
> +		struct perf_event *event = hw_events->events[idx];
> +
> +		if (!event)
> +			continue;
> +
> +		overflow_status = readq(starlink_pmu->pmu_base +
> +					STARLINK_PMU_COUNTER_OVERFLOW_STATUS);
> +		if (!(overflow_status & BIT(idx)))
> +			continue;
> +
> +		writeq(1 << idx, starlink_pmu->pmu_base +
> +		       STARLINK_PMU_COUNTER_OVERFLOW_STATUS);

Same shifting problem here.

> +static int starlink_pmu_probe(struct platform_device *pdev)
> +{
> +	struct starlink_pmu *starlink_pmu;
> +	struct starlink_hw_events *hw_events;
> +	struct resource *res;
> +	int cpuid, i, ret;
> +
> +	starlink_pmu = devm_kzalloc(&pdev->dev, sizeof(*starlink_pmu), GFP_KERNEL);
> +	if (!starlink_pmu)
> +		return -ENOMEM;
> +
> +	starlink_pmu->pmu_base =
> +			devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> +	if (IS_ERR(starlink_pmu->pmu_base))
> +		return PTR_ERR(starlink_pmu->pmu_base);
> +
> +	starlink_pmu->hw_events = alloc_percpu_gfp(struct starlink_hw_events,
> +						   GFP_KERNEL);
> +	if (!starlink_pmu->hw_events) {
> +		dev_err(&pdev->dev, "Failed to allocate per-cpu PMU data\n");
> +		kfree(starlink_pmu);

You shouldn't call kfree() on a device-managed object (i.e. allocated with
devm_kzalloc()).

Will


From anshuman.khandual at arm.com  Fri Feb 23 03:31:02 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 23 Feb 2024 17:01:02 +0530
Subject: [PATCH] arm64/hw_breakpoint: Determine lengths from generic perf breakpoint macros
Message-ID: <20240223113102.4027779-1-anshuman.khandual@arm.com>

Both platform i.e ARM_BREAKPOINT_LEN_X and generic i.e HW_BREAKPOINT_LEN_X
macros are used interchangeably to convert event->attr.bp_len and platform
breakpoint control arch_hw_breakpoint_ctrl->len. Let's be consistent while
deriving one from the other. This does not cause any functional changes.

Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas 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 v6.8-rc5

 arch/arm64/kernel/hw_breakpoint.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 35225632d70a..1ab9fc865ddd 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -301,28 +301,28 @@ static int get_hbp_len(u8 hbp_len)
 
 	switch (hbp_len) {
 	case ARM_BREAKPOINT_LEN_1:
-		len_in_bytes = 1;
+		len_in_bytes = HW_BREAKPOINT_LEN_1;
 		break;
 	case ARM_BREAKPOINT_LEN_2:
-		len_in_bytes = 2;
+		len_in_bytes = HW_BREAKPOINT_LEN_2;
 		break;
 	case ARM_BREAKPOINT_LEN_3:
-		len_in_bytes = 3;
+		len_in_bytes = HW_BREAKPOINT_LEN_3;
 		break;
 	case ARM_BREAKPOINT_LEN_4:
-		len_in_bytes = 4;
+		len_in_bytes = HW_BREAKPOINT_LEN_4;
 		break;
 	case ARM_BREAKPOINT_LEN_5:
-		len_in_bytes = 5;
+		len_in_bytes = HW_BREAKPOINT_LEN_5;
 		break;
 	case ARM_BREAKPOINT_LEN_6:
-		len_in_bytes = 6;
+		len_in_bytes = HW_BREAKPOINT_LEN_6;
 		break;
 	case ARM_BREAKPOINT_LEN_7:
-		len_in_bytes = 7;
+		len_in_bytes = HW_BREAKPOINT_LEN_7;
 		break;
 	case ARM_BREAKPOINT_LEN_8:
-		len_in_bytes = 8;
+		len_in_bytes = HW_BREAKPOINT_LEN_8;
 		break;
 	}
 
-- 
2.25.1



From maz at kernel.org  Fri Feb 23 03:33:29 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 23 Feb 2024 11:33:29 +0000
Subject: [PATCH v4 11/14] KVM: arm64: Add newly allocated ID registers to register descriptions
In-Reply-To: <20240122-arm64-2023-dpisa-v4-11-776e094861df@kernel.org>
References: <20240122-arm64-2023-dpisa-v4-0-776e094861df@kernel.org>
	<20240122-arm64-2023-dpisa-v4-11-776e094861df@kernel.org>
Message-ID: <86o7c72z5i.wl-maz@kernel.org>

On Mon, 22 Jan 2024 16:28:14 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> The 2023 architecture extensions have allocated some new ID registers, add
> them to the KVM system register descriptions so that they are visible to
> guests.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/kvm/sys_regs.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 30253bd19917..38503b1cd2eb 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -2292,12 +2292,12 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  		   ID_AA64PFR0_EL1_AdvSIMD |
>  		   ID_AA64PFR0_EL1_FP), },
>  	ID_SANITISED(ID_AA64PFR1_EL1),
> -	ID_UNALLOCATED(4,2),
> +	ID_SANITISED(ID_AA64PFR2_EL1),

So you now expose all sort of MTE things to the guest?

>  	ID_UNALLOCATED(4,3),
>  	ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0),
>  	ID_HIDDEN(ID_AA64SMFR0_EL1),
>  	ID_UNALLOCATED(4,6),
> -	ID_UNALLOCATED(4,7),
> +	ID_SANITISED(ID_AA64FPFR0_EL1),
>  
>  	/* CRm=5 */
>  	{ SYS_DESC(SYS_ID_AA64DFR0_EL1),
> @@ -2324,7 +2324,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	ID_WRITABLE(ID_AA64ISAR2_EL1, ~(ID_AA64ISAR2_EL1_RES0 |
>  					ID_AA64ISAR2_EL1_APA3 |
>  					ID_AA64ISAR2_EL1_GPA3)),
> -	ID_UNALLOCATED(6,3),
> +	ID_WRITABLE(ID_AA64ISAR3_EL1, ~ID_AA64ISAR3_EL1_RES0),

How about the non dpISA stuff that is advertised in the same register,
and for which no support exists?

>  	ID_UNALLOCATED(6,4),
>  	ID_UNALLOCATED(6,5),
>  	ID_UNALLOCATED(6,6),
> 

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Fri Feb 23 03:34:03 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 23 Feb 2024 11:34:03 +0000
Subject: [PATCH v4 02/14] arm64/fpsimd: Enable host kernel access to FPMR
In-Reply-To: <20240122-arm64-2023-dpisa-v4-2-776e094861df@kernel.org>
References: <20240122-arm64-2023-dpisa-v4-0-776e094861df@kernel.org>
	<20240122-arm64-2023-dpisa-v4-2-776e094861df@kernel.org>
Message-ID: <86msrr2z4k.wl-maz@kernel.org>

On Mon, 22 Jan 2024 16:28:05 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> FEAT_FPMR provides a new generally accessible architectural register FPMR.
> This is only accessible to EL0 and EL1 when HCRX_EL2.EnFPM is set to 1,
> do this when the host is running. The guest part will be done along with
> context switching the new register and exposing it via guest management.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_arm.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 3c6f8ba1e479..7f45ce9170bb 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -105,7 +105,7 @@
>  #define HCRX_GUEST_FLAGS \
>  	(HCRX_EL2_SMPME | HCRX_EL2_TCR2En | \
>  	 (cpus_have_final_cap(ARM64_HAS_MOPS) ? (HCRX_EL2_MSCEn | HCRX_EL2_MCE2) : 0))
> -#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En)
> +#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En | HCRX_EL2_EnFPM)
>  
>  /* TCR_EL2 Registers bits */
>  #define TCR_EL2_DS		(1UL << 32)
> 

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

	M.

-- 
Without deviation from the norm, progress is not possible.


From cristian.marussi at arm.com  Fri Feb 23 03:38:09 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Fri, 23 Feb 2024 11:38:09 +0000
Subject: [PATCH 1/5] dt-bindings: firmware: add i.MX SCMI Extension
 protocol
In-Reply-To: <20240202-imx95-bbm-misc-v1-1-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
 <20240202-imx95-bbm-misc-v1-1-3cb743020933@nxp.com>
Message-ID: <ZdiDob6oBc7Jh28a@pluto>

On Fri, Feb 02, 2024 at 02:34:39PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add i.MX SCMI Extension protocol BBM and MISC binding.
> 

Hi,

just a few remarks down below only about the SCMI related stuff...

> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  .../devicetree/bindings/firmware/nxp,scmi.yaml     | 64 ++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/firmware/nxp,scmi.yaml b/Documentation/devicetree/bindings/firmware/nxp,scmi.yaml
> new file mode 100644
> index 000000000000..00d6361bbbea
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/firmware/nxp,scmi.yaml
> @@ -0,0 +1,64 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2024 NXP
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/firmware/nxp,scmi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: i.MX System Control and Management Interface (SCMI) Protocol Extension
> +

... (SCMI) Vendor Protocols

> +maintainers:
> +  - Peng Fan <peng.fan at nxp.com>
> +
> +allOf:
> +  - $ref: arm,scmi.yaml#
> +
> +properties:
> +  protocol at 11:

protocol at 81 ?

> +    $ref: 'arm,scmi.yaml#/$defs/protocol-node'
> +    unevaluatedProperties: false
> +
> +    properties:
> +      reg:
> +        const: 0x81
> +
> +  protocol at 13:

protocol at 84 ?

> +    $ref: 'arm,scmi.yaml#/$defs/protocol-node'
> +    unevaluatedProperties: false
> +
> +    properties:
> +      reg:
> +        const: 0x84
> +
> +      wakeup-sources:
> +        description: each entry consists of 2 integers and represents the source and edge
> +        items:
> +          items:
> +            - description: the wakeup source
> +            - description: the wakeup edge
> +        $ref: /schemas/types.yaml#/definitions/uint32-matrix
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    firmware {
> +        scmi {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            protocol at 81 {
> +              reg = <0x81>;
> +            };
> +
> +            protocol at 84 {
> +              reg = <0x84>;
> +              wakeup-sources = <6 1
> +                                7 1
> +                                8 1
> +                                9 1
> +                                10 1>;
> +            };
> +         };
> +    };
> +...
> 

Thanks,
Cristian


From schnelle at linux.ibm.com  Fri Feb 23 03:38:18 2024
From: schnelle at linux.ibm.com (Niklas Schnelle)
Date: Fri, 23 Feb 2024 12:38:18 +0100
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
	 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
	 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
	 <20240222223617.GC13330@nvidia.com>
	 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
Message-ID: <e78f6e6294c31d889ace4de3a3c3cebad04f4213.camel@linux.ibm.com>

On Fri, 2024-02-23 at 09:07 +0000, David Laight wrote:
> From: Jason Gunthorpe
> > Sent: 22 February 2024 22:36
> > To: David Laight <David.Laight at ACULAB.COM>
> > 
> > On Thu, Feb 22, 2024 at 10:05:04PM +0000, David Laight wrote:
> > > From: Jason Gunthorpe
> > > > Sent: 21 February 2024 01:17
> > > > 
> > > > The kernel provides driver support for using write combining IO memory
> > > > through the __iowriteXX_copy() API which is commonly used as an optional
> > > > optimization to generate 16/32/64 byte MemWr TLPs in a PCIe environment.
> > > > 
> > > ...
> > > > Implement __iowrite32/64_copy() specifically for ARM64 and use inline
> > > > assembly to build consecutive blocks of STR instructions. Provide direct
> > > > support for 64/32/16 large TLP generation in this manner. Optimize for
> > > > common constant lengths so that the compiler can directly inline the store
> > > > blocks.
> > > ...
> > > > +/*
> > > > + * This generates a memcpy that works on a from/to address which is aligned to
> > > > + * bits. Count is in terms of the number of bits sized quantities to copy. It
> > > > + * optimizes to use the STR groupings when possible so that it is WC friendly.
> > > > + */
> > > > +#define memcpy_toio_aligned(to, from, count, bits)                        \
> > > > +	({                                                                \
> > > > +		volatile u##bits __iomem *_to = to;                       \
> > > > +		const u##bits *_from = from;                              \
> > > > +		size_t _count = count;                                    \
> > > > +		const u##bits *_end_from = _from + ALIGN_DOWN(_count, 8); \
> > > > +                                                                          \
> > > > +		for (; _from < _end_from; _from += 8, _to += 8)           \
> > > > +			__const_memcpy_toio_aligned##bits(_to, _from, 8); \
> > > > +		if ((_count % 8) >= 4) {
> > > 
> > > If (_count & 4) {
> > 
> > That would be obfuscating, IMHO. The compiler doesn't need such things
> > to generate optimal code.
> 
> Try it: https://godbolt.org/z/EvvGrTxv3 
> And it isn't that obfuscated - no more so than your version.
> 
> > > > +			__const_memcpy_toio_aligned##bits(_to, _from, 1); \
> > > > +	})
> > > 
> > > But that looks bit a bit large to be inlined.
> > 
> > You trimmed alot, this #define is in a C file and it is a template to
> > generate the 32 and 64 bit out of line functions. Things are done like
> > this because the 32/64 version are exactly the same logic except just
> > with different types and sizes.
> 
> I missed that in a quick read at 11pm :-(
> 
> Although I doubt that generating long TLP from byte writes is
> really necessary.

I might have gotten confused but I think these are not byte writes.
Remember that the count is in terms of the number of bits sized
quantities to copy so "count == 1" is 4/8 bytes here.

> IIRC you were merging at most 4 writes.
> So better to do a single 32bit write instead.
> (Unless you have misaligned source data - unlikely.)
> 
> While write-combining to generate long TLP is probably mostly
> safe for PCIe targets, there are some that will only handle
> TLP for single 32bit data items.
> Which might be why the code is explicitly requesting 4 byte copies.
> So it may be entirely wrong to write-combine anything except
> the generic memcpy_toio().
> 
> 	David

On anything other than s390x this should only do write-combine if the
memory mapping allows it, no? Meaning a driver that can't handle larger
TLPs really shouldn't use ioremap_wc() then.

On s390x one could argue that our version of __iowriteXX_copy() is
strictly speaking not correct in that zpci_memcpy_toio() doesn't really
use XX bit writes which is why for us memcpy_toio() was actually a
better fit indeed. On the other hand doing 32 bit PCI stores (an s390x
thing) can't combine multiple stores into a single TLP which these
functions are used for and which has much more use cases than forcing a
copy loop with 32/64 bit sized writes which would also be a lot slower
on s390x than an aligned zpci_memcpy_toio().


From will at kernel.org  Fri Feb 23 03:50:43 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 23 Feb 2024 11:50:43 +0000
Subject: [GIT PULL] iommu/arm-smmu: Fixes for 6.8-rc
Message-ID: <20240223115043.GA10608@willie-the-truck>

Hi Joerg,

Please can you pull these two Arm SMMU fixes for 6.8-rc? I appreciate
it's getting late in the cycle, but it took us a little while to fix the
SVA allocation problem properly. The summary is in the tag.

I'll send you my 6.9 queue next week and it will be based on these
fixes.

Cheers,

Will

--->8

The following changes since commit 41bccc98fb7931d63d03f326a746ac4d429c1dd3:

  Linux 6.8-rc2 (2024-01-28 17:01:12 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git tags/arm-smmu-fixes

for you to fetch changes up to b5bf7778b722105d7a04b1d51e884497b542638b:

  iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock (2024-02-22 12:34:11 +0000)

----------------------------------------------------------------
Arm SMMU fixes for 6.8

- Fix CD allocation from atomic context when using SVA with SMMUv3

- Revert the conversion of SMMUv2 to domain_alloc_paging(), as it
  breaks the boot for Qualcomm MSM8996 devices

----------------------------------------------------------------
Dmitry Baryshkov (1):
      Revert "iommu/arm-smmu: Convert to domain_alloc_paging()"

Jason Gunthorpe (1):
      iommu/arm-smmu-v3: Do not use GFP_KERNEL under as spinlock

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 38 ++++++++-----------------
 drivers/iommu/arm/arm-smmu/arm-smmu.c           | 17 ++++-------
 2 files changed, 18 insertions(+), 37 deletions(-)


From raphael.gallais-pou at foss.st.com  Fri Feb 23 03:59:44 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Fri, 23 Feb 2024 12:59:44 +0100
Subject: [PATCH v2 4/4] dt-bindings: display: simple: hardware can use
 several properties
In-Reply-To: <20240223000946.GA3848625-robh@kernel.org>
References: <20240217-ltdc_mp13-v2-0-50881f1b394e@foss.st.com>
 <20240217-ltdc_mp13-v2-4-50881f1b394e@foss.st.com>
 <20240223000946.GA3848625-robh@kernel.org>
Message-ID: <833a7287-69ff-4976-bfc6-16fabf2fa6a5@foss.st.com>


On 2/23/24 01:09, Rob Herring wrote:
> On Sat, Feb 17, 2024 at 12:02:58PM +0100, Raphael Gallais-Pou wrote:
>> Setting a panel-timing in the device-tree overwrite the one specified in
>> the driver and set it as preferred.  In that case 'height-mm',
>> 'width-mm' and 'panel-timing' are properties that can be use for simple
>> panels, according to panel-common.yaml
>>
>> Fixes following warnings:
>> arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-rgb: 'height-mm', 'panel-timing', 'width-mm' do not match any of the regexes: 'pinctrl-[0-9]+'
>> 	from schema $id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#
>>
>> Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
>> ---
>>  Documentation/devicetree/bindings/display/panel/panel-simple.yaml | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
>> index 634a10c6f2dd..c02cbbc7a100 100644
>> --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
>> +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
>> @@ -352,6 +352,9 @@ properties:
>>    no-hpd: true
>>    hpd-gpios: true
>>    data-mapping: true
>> +  height-mm: true
>> +  width-mm: true
>> +  panel-timing: true
Hi Rob,
> Instead, just change 'additionalProperties' to 'unevaluateProperties' 
> and drop all these 'prop: true' lines. Pretty much anything from 
> panel-common.yaml should be allowed.


Will do, thanks :)


Best regards,

Rapha?l

>
> Rob


From mbrugger at suse.com  Fri Feb 23 04:02:00 2024
From: mbrugger at suse.com (Matthias Brugger)
Date: Fri, 23 Feb 2024 13:02:00 +0100
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <e6f6070e-8355-4a0b-a904-1a24970f249b@linaro.org>
References: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
 <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
 <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
 <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>
 <e6f6070e-8355-4a0b-a904-1a24970f249b@linaro.org>
Message-ID: <e530d504-dfa3-4d39-b903-b2570bb8b014@suse.com>



On 22/02/2024 12:13, Krzysztof Kozlowski wrote:
> On 21/02/2024 18:00, Ghennadi Procopciuc wrote:
>> On 2/21/24 17:43, Krzysztof Kozlowski wrote:
>>> On 21/02/2024 16:19, Ghennadi Procopciuc wrote:
>>>> On 2/21/24 16:45, Krzysztof Kozlowski wrote:
>>>>> On 21/02/2024 15:42, Krzysztof Kozlowski wrote:
>>>>>> On 21/02/2024 13:01, Ghennadi Procopciuc wrote:
>>>>>>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>>>>>>
>>>>>>> Add myself as a maintainer of the NXP S32G DT files.
>>>>>>
>>>>>> No need for cover letters for single patches. OTOH, this commit msg is
>>>>>> empty...
>>>> Thank you, I can correct that.
>>>>
>>>>>> Plus your patch looks corrupted (wrong encoding): F??rber
>>>>
>>>> Indeed, it is due to 'Content-Type: text/plain; charset="us-ascii"'.
>>>> I can fix this as part of v2.
>>>>
>>>>>> BTW, did you contribute anything to the upstream Linux kernel? Do you
>>>>>> know the process? Downstream does not really matter.
>>>>>
>>>>> I found the answer:
>>>>>
>>>>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>>>> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at oss.nxp.com>
>>>>>
>>>>> Does not look like. Please get some upstream work experience first.
>>>>>
>>>>> https://lore.kernel.org/all/?q=f%3Aghennadi.procopciuc%40oss.nxp.com
>>>>
>>>> Although I am new to upstream communities and may make mistakes, I am
>>>> eager to learn and improve.
>>>>
>>>> After leaving SuSe[0], the current maintainer of the NXP S32G DT files
>>>> became inactive[1]. As a result, this area is not currently being
>>>> maintained. This is the actual reason why I attempted to add myself as a
>>>> maintainer of that area. Although I acknowledge that I may not have
>>>> enough experience to become a maintainer, I am concerned that the NXP
>>>> S32G DT patch submission may be blocked for everyone due to the current
>>>> situation.
>>>
>>> I would be just happy to see first actual contributions or any sort of
>>> activity, like reviewing, before taking over something.
>>>
>>> You do not need to become maintainer to provide reviews. By reviewing
>>> patches you already reduce burden/work from the maintainers.
>>>
>>> Best regards,
>>> Krzysztof
>>>
>>
>> I fully understand and agree with your perspective on this matter and
>> accept the fact that I will not be a maintainer as initially intended.
>> Furthermore, I am very willing to participate in any reviews related to
>> S32G SoCs.
> 
> Just give it some time...
> 
>>
>> Patches, including those I have created ([0], [1]), will likely be
>> submitted for this area. This is because each enabled driver for S32G
>> SoCs is expected to have at least one node in the device tree. These
>> patches will undergo review and receive feedback. However, the upstream
>> process will come to a halt at this point since there are no maintainers
>> to apply and integrate them.
> 
> Indeed that's a problem.
> 
>>
>> I do not know how this situation should be handled, given my lack of
>> experience in upstreaming maintenance. The documentation for the Linux
>> kernel is insufficient in providing guidance [2] on how to handle
>> inactive maintainers and it is unclear who should take over their
>> responsibilities. This is likely not the first time this has happened in
>> the kernel's history.
>>
>> Could you please guide me on how these patches should be integrated into
>> a maintainer's? tree and by whom?
> 
> Chester left Suse, so maybe this also means less interest in maintaining
> it? Stepping up in such case, so your proposal, is reasonable, so in
> general I agree and thank you for trying to do something here.
> 
> Andreas or Matthias,
> Maybe you could change your R: into M: and take s32g patches?
> 
> If not, then I will ack this patch making Ghennadi the maintainer.
> 

Normal process would be that Arnd would contact Chester to see if he is not able 
to do the maintainer work any more. In that case maybe Arnd could take over.

I agree with you that some one should get maintainer for a SoC because he is 
involved in the Linux kernel community and not because he is working on 
downstream patches for the same silicon. Especially being paid by the company 
that produces the silicon can quickly get you into dificult situation. Think for 
example that NXP, which pays you, wants something to be added in the upstream 
kernel, but the code is not in a shape to be part of Linux kernel. That can 
generate conflict and for the upstream community it is important that the only 
criteria to accept something upstream is the fact that it is in a good shape for 
that, not any comercial roadmap by a company.

I'm not saying that Ghennadi won't be able to defend this, if it ever occurs. 
Basically because I don't have a good track record of him due to missing 
upstream collaboration.

I would prefer that Arnd (or Andreas) step up to take the maintainer role. I 
already have one and it's difficult for me to find the time to do it in an 
acceptable way.

Regards,
Matthias


From vkoul at kernel.org  Fri Feb 23 04:15:57 2024
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 23 Feb 2024 17:45:57 +0530
Subject: [PATCH] phy: constify of_phandle_args in xlate
In-Reply-To: <20240217093937.58234-1-krzysztof.kozlowski@linaro.org>
References: <20240217093937.58234-1-krzysztof.kozlowski@linaro.org>
Message-ID: <170869055762.530534.10335046810476136989.b4-ty@kernel.org>


On Sat, 17 Feb 2024 10:39:37 +0100, Krzysztof Kozlowski wrote:
> The xlate callbacks are supposed to translate of_phandle_args to proper
> provider without modifying the of_phandle_args.  Make the argument
> pointer to const for code safety and readability.
> 
> 

Applied, thanks!

[1/1] phy: constify of_phandle_args in xlate
      commit: 00ca8a15dafa990d391abc37f2b8256ddf909b35

Best regards,
-- 
~Vinod




From David.Laight at ACULAB.COM  Fri Feb 23 04:19:24 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 23 Feb 2024 12:19:24 +0000
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <e78f6e6294c31d889ace4de3a3c3cebad04f4213.camel@linux.ibm.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
	 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
	 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
	 <20240222223617.GC13330@nvidia.com>
	 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
 <e78f6e6294c31d889ace4de3a3c3cebad04f4213.camel@linux.ibm.com>
Message-ID: <d4150af74d7c45b79c770cd1c5d8eed7@AcuMS.aculab.com>

From: Niklas Schnelle
> Sent: 23 February 2024 11:38
...
> > Although I doubt that generating long TLP from byte writes is
> > really necessary.
> 
> I might have gotten confused but I think these are not byte writes.
> Remember that the count is in terms of the number of bits sized
> quantities to copy so "count == 1" is 4/8 bytes here.

Something made me think you were generating a byte version
as well as the 32 and 64 bit ones.

...
> > While write-combining to generate long TLP is probably mostly
> > safe for PCIe targets, there are some that will only handle
> > TLP for single 32bit data items.
> > Which might be why the code is explicitly requesting 4 byte copies.
> > So it may be entirely wrong to write-combine anything except
> > the generic memcpy_toio().
> >
> > 	David
> 
> On anything other than s390x this should only do write-combine if the
> memory mapping allows it, no? Meaning a driver that can't handle larger
> TLPs really shouldn't use ioremap_wc() then.

I can't decide whether merged writes could be required for some
target addresses but be problematic on others.
Probably not.

> On s390x one could argue that our version of __iowriteXX_copy() is
> strictly speaking not correct in that zpci_memcpy_toio() doesn't really
> use XX bit writes which is why for us memcpy_toio() was actually a
> better fit indeed. On the other hand doing 32 bit PCI stores (an s390x
> thing) can't combine multiple stores into a single TLP which these
> functions are used for and which has much more use cases than forcing a
> copy loop with 32/64 bit sized writes which would also be a lot slower
> on s390x than an aligned zpci_memcpy_toio().

If I read that correctly 32bit writes don't get merged?
Indeed any code that will benefit from merging can (probably)
do 64bit writes so is even attempting to merge 32bit ones
worth the effort?

Since writes get 'posted' all over the place.
How many writes do you need to do before write-combining makes a difference?
We've logic in our fpga to trace the RX and TX TLP [1].
Although the link is slow; back to back writes are limited by
what happens later in the fpga logic - not the pcie link.

Reads are another matter entirely.
The x86 cpu I've used assign a tag to each cpu core.
So while reads from multiple processes happen in parallel, those
from a single process are definitely synchronous.
The cpu stalls for a few thousand clock on every read.

Large read TLPs (and overlapped read TLPs) would have a much
bigger effect than large write TLP.

[1] It is nice to be able to see what is going on without having
to beg/steal/borrow an expensive PCIe analyser and persuade the
hardware to work with it connected.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From rogerq at kernel.org  Fri Feb 23 04:23:17 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 23 Feb 2024 14:23:17 +0200
Subject: [PATCH v4 1/3] dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl
 compatible
In-Reply-To: <8a1efca0-9a63-472a-8c0f-0aeb3efa2baa@ti.com>
References: <20240205135908.54656-1-rogerq@kernel.org>
 <20240205135908.54656-2-rogerq@kernel.org>
 <8a1efca0-9a63-472a-8c0f-0aeb3efa2baa@ti.com>
Message-ID: <5b65da27-c1c9-4d91-87d4-08073ff220d7@kernel.org>

Hi Vignesh,

On 22/02/2024 10:51, Vignesh Raghavendra wrote:
> Hi Roger,
> 
> On 05/02/24 19:29, Roger Quadros wrote:
>> Add the compatible for TI AM62 USB PHY Control register. This
>> register is found in the TI AM62 WKUP_CTRL_MMR0 space [1]. It
>> is used to indicate the USB PHY PLL reference clock rate and
>> core voltage level to the USB controller.
>>
>> [1] - https://www.ti.com/lit/pdf/spruiv7
>>
>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>> Acked-by: Rob Herring <robh at kernel.org>
>> ---
>>
>> Notes:
>>     Changelog:
>>     
>>     v4 - no change. Added Rob's Acked-by
>>     
>>     v3 - add compatibles in alphabetical order
>>     https://lore.kernel.org/all/20240201120332.4811-2-rogerq at kernel.org/
>>     
>>     v2 - New patch
>>
>>  Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
> 
> You don't have right maintainer in CC for this file.

I'll resend this series with Acks and updated CC list.

> 
>> index 084b5c2a2a3c..9437705af92f 100644
>> --- a/Documentation/devicetree/bindings/mfd/syscon.yaml
>> +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
>> @@ -72,6 +72,7 @@ properties:
>>                - rockchip,rk3588-qos
>>                - rockchip,rv1126-qos
>>                - starfive,jh7100-sysmain
>> +              - ti,am62-usb-phy-ctrl
>>                - ti,am654-dss-oldi-io-ctrl
>>  
>>            - const: syscon
> 

-- 
cheers,
-roger


From kabel at kernel.org  Fri Feb 23 04:26:41 2024
From: kabel at kernel.org (Marek =?UTF-8?B?QmVow7pu?=)
Date: Fri, 23 Feb 2024 13:26:41 +0100
Subject: [PATCH 1/2] devm-helpers: Add resource managed version of mutex
 init
In-Reply-To: <Zde_s8iecR2ArKjC@surfacebook.localdomain>
References: <20240222145838.12916-1-kabel@kernel.org>
	<Zde_s8iecR2ArKjC@surfacebook.localdomain>
Message-ID: <20240223132641.3e2ba16c@dellmb>

On Thu, 22 Feb 2024 23:42:11 +0200
andy.shevchenko at gmail.com wrote:

> Thu, Feb 22, 2024 at 03:58:37PM +0100, Marek Beh?n kirjoitti:
> > A few drivers are doing resource-managed mutex initialization by
> > implementing ad-hoc one-liner mutex dropping functions and using them
> > with devm_add_action_or_reset(). Help drivers avoid these repeated
> > one-liners by adding managed version of mutex initialization.
> > 
> > Use the new function devm_mutex_init() in the following drivers:
> >   drivers/gpio/gpio-pisosr.c
> >   drivers/gpio/gpio-sim.c
> >   drivers/gpu/drm/xe/xe_hwmon.c
> >   drivers/hwmon/nzxt-smart2.c
> >   drivers/leds/leds-is31fl319x.c
> >   drivers/power/supply/mt6370-charger.c
> >   drivers/power/supply/rt9467-charger.c  
> 
> Pardon me, but why?
> 
> https://lore.kernel.org/linux-leds/20231214173614.2820929-1-gnstark at salutedevices.com/
> 
> Can you cooperate, folks, instead of doing something independently?

Thanks Andy for pointing to George's patch series.

I can drop the mutex_init() part and add just the debugfs part.

Marek


From arnd at arndb.de  Fri Feb 23 04:29:10 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 23 Feb 2024 13:29:10 +0100
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <e530d504-dfa3-4d39-b903-b2570bb8b014@suse.com>
References: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
 <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
 <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
 <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>
 <e6f6070e-8355-4a0b-a904-1a24970f249b@linaro.org>
 <e530d504-dfa3-4d39-b903-b2570bb8b014@suse.com>
Message-ID: <c3e68c62-b81f-475b-9b15-c983c94aed8b@app.fastmail.com>

On Fri, Feb 23, 2024, at 13:02, Matthias Brugger wrote:
> On 22/02/2024 12:13, Krzysztof Kozlowski wrote:
>> On 21/02/2024 18:00, Ghennadi Procopciuc wrote:
>> 
>> Andreas or Matthias,
>> Maybe you could change your R: into M: and take s32g patches?
>> 
>> If not, then I will ack this patch making Ghennadi the maintainer.
>> 
>
> Normal process would be that Arnd would contact Chester to see if he is 
> not able 
> to do the maintainer work any more. In that case maybe Arnd could take 
> over.

I was hoping to see a reply from Chester one way or another,
I see he has been on Cc for the entire thread but not
chimed in.

> I'm not saying that Ghennadi won't be able to defend this, if it ever occurs. 
> Basically because I don't have a good track record of him due to missing 
> upstream collaboration.
>
> I would prefer that Arnd (or Andreas) step up to take the maintainer role. I 
> already have one and it's difficult for me to find the time to do it in an 
> acceptable way.

It appears that we already cover the dts files in the IMX
entry, whether that is intentional or not:

ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
M:      Shawn Guo <shawnguo at kernel.org>
M:      Sascha Hauer <s.hauer at pengutronix.de>
R:      Pengutronix Kernel Team <kernel at pengutronix.de>
R:      Fabio Estevam <festevam at gmail.com>
R:      NXP Linux Team <linux-imx at nxp.com> 
L:      linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
S:      Maintained
T:      git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
F:      arch/arm/boot/dts/nxp/imx/
F:      arch/arm/boot/dts/nxp/mxs/
F:      arch/arm64/boot/dts/freescale/

Added everyone there to Cc, having any s32 patches go through
the imx tree would be the easiest way as far as I'm concerned.
I've added the maintainers to Cc, let's see what they think.

I also noticed that the pinctrl driver entry still has Chester's
old email address listed as the only maintainer, so we should
probably fix that as well:

PIN CONTROLLER - NXP S32
M:      Chester Lin <clin at suse.com>
R:      NXP S32 Linux Team <s32 at nxp.com>
L:      linux-gpio at vger.kernel.org
S:      Maintained
F:      Documentation/devicetree/bindings/pinctrl/nxp,s32*
F:      drivers/pinctrl/nxp/

       Arnd


From biju.das.jz at bp.renesas.com  Fri Feb 23 04:36:46 2024
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Fri, 23 Feb 2024 12:36:46 +0000
Subject: [PATCH] arm64: defconfig: Enable Renesas RZ/G2L display unit DRM driver
Message-ID: <20240223123646.245655-1-biju.das.jz@bp.renesas.com>

Enable the RZ/G2L display unit DRM driver used in RZ/{G2L,G2LC,V2L} SMARC
EVK development boards.

Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 34681284043f..099ed9b61e83 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -851,6 +851,7 @@ CONFIG_DRM_RCAR_DU=m
 CONFIG_DRM_RCAR_DW_HDMI=m
 CONFIG_DRM_RCAR_MIPI_DSI=m
 CONFIG_DRM_RZG2L_MIPI_DSI=m
+CONFIG_DRM_RZG2L_DU=m
 CONFIG_DRM_SUN4I=m
 CONFIG_DRM_SUN6I_DSI=m
 CONFIG_DRM_SUN8I_DW_HDMI=m
-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Fri Feb 23 04:36:47 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Fri, 23 Feb 2024 13:36:47 +0100
Subject: [PATCH v3 0/4] Add display support for stm32mp135f-dk board
Message-ID: <20240223-ltdc_mp13-v3-0-7f92a59ca11f@foss.st.com>

This serie aims to enable display support for the stm32mp135f-dk board

Those are only patches of the device-tree since the driver support has
already been added [1].

It respectivelly:
	- adds support for the display controller on stm32mp135
	- adds pinctrl for the display controller
	- enables panel, backlight and display controller on
	  stm32mp135f-dk

Finally it fixes the flags on the panel default mode in the
'panel-simple' driver, allowing to override the default mode by one
described in the device tree, and push further the blanking limit on the
panel.

[1] commit 1726cee3d053 ("drm/stm: ltdc: support of new hardware version")

Changes in v3:
  - [4/4] Allow every properties from panel-common in panel-simple.yaml
  - [4/4] Rewrite commit description to match changes

Changes in v2:
  - Removed already merged patches
https://lore.kernel.org/lkml/170729755552.1647630.4818786052103823648.b4-ty at linaro.org/
https://lore.kernel.org/lkml/170729755662.1647630.425379349649657352.b4-ty at linaro.org/
  - Fixed CHECK_DTBS warnings
  - Added missing properties in panel-simple.yaml

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Raphael Gallais-Pou (4):
      ARM: dts: stm32: add LTDC support for STM32MP13x SoC family
      ARM: dts: stm32: add LTDC pinctrl on STM32MP13x SoC family
      ARM: dts: stm32: enable display support on stm32mp135f-dk board
      dt-bindings: display: simple: allow panel-common properties

 .../bindings/display/panel/panel-simple.yaml       | 11 +----
 arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi        | 57 ++++++++++++++++++++++
 arch/arm/boot/dts/st/stm32mp135.dtsi               | 11 +++++
 arch/arm/boot/dts/st/stm32mp135f-dk.dts            | 53 ++++++++++++++++++++
 4 files changed, 122 insertions(+), 10 deletions(-)
---
base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
change-id: 20240124-ltdc_mp13-2f86a782424c

Best regards,
-- 
Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>



From raphael.gallais-pou at foss.st.com  Fri Feb 23 04:36:50 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Fri, 23 Feb 2024 13:36:50 +0100
Subject: [PATCH v3 3/4] ARM: dts: stm32: enable display support on
 stm32mp135f-dk board
In-Reply-To: <20240223-ltdc_mp13-v3-0-7f92a59ca11f@foss.st.com>
References: <20240223-ltdc_mp13-v3-0-7f92a59ca11f@foss.st.com>
Message-ID: <20240223-ltdc_mp13-v3-3-7f92a59ca11f@foss.st.com>

Link panel and display controller.
Enable panel, backlight and display controller.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>

---
Changes in v2:
  - Fixed dtbs_check warnings :
arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-backlight: 'default-brightness-level' does not match any of the regexes: 'pinctrl-[0-9]+'
??from schema $id: http://devicetree.org/schemas/leds/backlight/gpio-backlight.yaml#
arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-rgb: data-mapping:0: 'bgr666' is not one of ['jeida-18', 'jeida-24', 'vesa-24']
??from schema $id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#
arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-rgb: compatible: ['rocktech,rk043fn48h', 'panel-dpi'] is too long
??from schema $id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#
arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-rgb: data-mapping: False schema does not allow ['bgr666']
??from schema $id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#
---
 arch/arm/boot/dts/st/stm32mp135f-dk.dts | 53 +++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
index eea740d097c7..c918f332cbfd 100644
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -66,6 +66,46 @@ led-blue {
 			default-state = "off";
 		};
 	};
+
+	panel_backlight: panel-backlight {
+		compatible = "gpio-backlight";
+		gpios = <&gpioe 12 GPIO_ACTIVE_HIGH>;
+		default-on;
+		status = "okay";
+	};
+
+	panel_rgb: panel-rgb {
+		compatible = "rocktech,rk043fn48h";
+		enable-gpios = <&gpioi 7 GPIO_ACTIVE_HIGH>;
+		backlight = <&panel_backlight>;
+		power-supply = <&scmi_v3v3_sw>;
+		status = "okay";
+
+		width-mm = <105>;
+		height-mm = <67>;
+
+		panel-timing {
+			clock-frequency = <10000000>;
+			hactive = <480>;
+			hback-porch = <43>;
+			hfront-porch = <10>;
+			hsync-len = <1>;
+			hsync-active = <0>;
+			vactive = <272>;
+			vback-porch = <26>;
+			vfront-porch = <4>;
+			vsync-len = <10>;
+			vsync-active = <0>;
+			de-active = <1>;
+			pixelclk-active = <1>;
+		};
+
+		port {
+			panel_in_rgb: endpoint {
+				remote-endpoint = <&ltdc_out_rgb>;
+			};
+		};
+	};
 };
 
 &adc_1 {
@@ -160,6 +200,19 @@ &iwdg2 {
 	status = "okay";
 };
 
+&ltdc {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&ltdc_pins_a>;
+	pinctrl-1 = <&ltdc_sleep_pins_a>;
+	status = "okay";
+
+	port {
+		ltdc_out_rgb: endpoint {
+			remote-endpoint = <&panel_in_rgb>;
+		};
+	};
+};
+
 &rtc {
 	status = "okay";
 };

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Fri Feb 23 04:36:51 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Fri, 23 Feb 2024 13:36:51 +0100
Subject: [PATCH v3 4/4] dt-bindings: display: simple: allow panel-common
 properties
In-Reply-To: <20240223-ltdc_mp13-v3-0-7f92a59ca11f@foss.st.com>
References: <20240223-ltdc_mp13-v3-0-7f92a59ca11f@foss.st.com>
Message-ID: <20240223-ltdc_mp13-v3-4-7f92a59ca11f@foss.st.com>

This device inherits properties from panel-common. Those should be allowed
to use, instead of specifying properties to true for each specific use.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Changes in v3:
  - Allow every properties instead of adding each properties to true as
    Rob suggested
  - Rewrite commit log to match changes

Changes in v2:
  - Added this patch

Fixes following warnings:
arch/arm/boot/dts/st/stm32mp135f-dk.dtb: panel-rgb: 'height-mm', 'panel-timing', 'width-mm' do not match any of the regexes: 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/display/panel/panel-simple.yaml#
---
 .../devicetree/bindings/display/panel/panel-simple.yaml       | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 634a10c6f2dd..01c9153da3d3 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -344,15 +344,6 @@ properties:
         # Yes Optoelectronics YTC700TLAG-05-201C 7" TFT LCD panel
       - yes-optoelectronics,ytc700tlag-05-201c
 
-  backlight: true
-  ddc-i2c-bus: true
-  enable-gpios: true
-  port: true
-  power-supply: true
-  no-hpd: true
-  hpd-gpios: true
-  data-mapping: true
-
 if:
   not:
     properties:
@@ -363,7 +354,7 @@ then:
   properties:
     data-mapping: false
 
-additionalProperties: false
+unevaluatedProperties: false
 
 required:
   - compatible

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Fri Feb 23 04:36:48 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Fri, 23 Feb 2024 13:36:48 +0100
Subject: [PATCH v3 1/4] ARM: dts: stm32: add LTDC support for STM32MP13x
 SoC family
In-Reply-To: <20240223-ltdc_mp13-v3-0-7f92a59ca11f@foss.st.com>
References: <20240223-ltdc_mp13-v3-0-7f92a59ca11f@foss.st.com>
Message-ID: <20240223-ltdc_mp13-v3-1-7f92a59ca11f@foss.st.com>

STM32MP13x SoC family embeds a new version of LTDC (Liquid crystal
display - Thin film transistor) Display Controller.

It provides a parallel digital RGB (red, green, blue) and signals for
horizontal, vertical synchronization, pixel clock and data enable as
output to interface directly to a variety of LCD-TFT panels.

Main features
  * 2 input layers blended together to compose the display
  * Cropping of layers from any input size and location
  * Multiple input pixel formats:
    ? Predefined ARGB, with 7 formats: ARGB8888, ABGR8888, RGBA8888,
    BGRA8888, RGB565, BGR565, RGB888packed.
    ? Flexible ARGB, allowing any width and location for A,R,G,B
    components.
    ? Predefined YUV, with 3 formats: YUV422-1L (FourCC: YUYV,
    Interleaved), YUV420-2L (FourCC: NV12, semi planar), YUV420-3L
    (FourCC: Yxx, full planar) with some flexibility on the sequence of
    the component.
  * Color look-up table (CLUT) up to 256 colors (256x24 bits) per layer
  * Color transparency keying
  * Composition with flexible window position and size versus output
  display
  * Blending with flexible layer order and alpha value (per pixel or
  constant)
  * Background underlying color
  * Gamma with non-linear configurable table
  * Dithering for output with less bits per component (pseudo-random on
  2 bits)
  * Polarity inversion for HSync, VSync, and DataEnable outputs
  * Output as RGB888 24 bpp or YUV422 16 bpp
  * Secure layer (using Layer2) capability, with grouped regs and
  additional interrupt set
  * Interrupts based on 7 different events
  * AXI master interface with long efficient bursts (64 or 128 bytes)

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp135.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp135.dtsi b/arch/arm/boot/dts/st/stm32mp135.dtsi
index 68d32f9f5314..834a4d545fe4 100644
--- a/arch/arm/boot/dts/st/stm32mp135.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp135.dtsi
@@ -19,5 +19,16 @@ dcmipp: dcmipp at 5a000000 {
 			port {
 			};
 		};
+
+		ltdc: display-controller at 5a001000 {
+			compatible = "st,stm32-ltdc";
+			reg = <0x5a001000 0x400>;
+			interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&rcc LTDC_PX>;
+			clock-names = "lcd";
+			resets = <&scmi_reset RST_SCMI_LTDC>;
+			status = "disabled";
+		};
 	};
 };

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Fri Feb 23 04:36:49 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Fri, 23 Feb 2024 13:36:49 +0100
Subject: [PATCH v3 2/4] ARM: dts: stm32: add LTDC pinctrl on STM32MP13x SoC
 family
In-Reply-To: <20240223-ltdc_mp13-v3-0-7f92a59ca11f@foss.st.com>
References: <20240223-ltdc_mp13-v3-0-7f92a59ca11f@foss.st.com>
Message-ID: <20240223-ltdc_mp13-v3-2-7f92a59ca11f@foss.st.com>

Adds LTDC pinctrl support and assigns dedicated GPIO pins.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 57 +++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
index 27e0c3826789..32c5d8a1e06a 100644
--- a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
@@ -47,6 +47,63 @@ pins {
 		};
 	};
 
+	ltdc_pins_a: ltdc-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D',  9, AF13)>, /* LCD_CLK */
+				 <STM32_PINMUX('C',  6, AF14)>, /* LCD_HSYNC */
+				 <STM32_PINMUX('G',  4, AF11)>, /* LCD_VSYNC */
+				 <STM32_PINMUX('H',  9, AF11)>, /* LCD_DE */
+				 <STM32_PINMUX('G',  7, AF14)>, /* LCD_R2 */
+				 <STM32_PINMUX('B', 12, AF13)>, /* LCD_R3 */
+				 <STM32_PINMUX('D', 14, AF14)>, /* LCD_R4 */
+				 <STM32_PINMUX('E',  7, AF14)>, /* LCD_R5 */
+				 <STM32_PINMUX('E', 13, AF14)>, /* LCD_R6 */
+				 <STM32_PINMUX('E',  9, AF14)>, /* LCD_R7 */
+				 <STM32_PINMUX('H', 13, AF14)>, /* LCD_G2 */
+				 <STM32_PINMUX('F',  3, AF14)>, /* LCD_G3 */
+				 <STM32_PINMUX('D',  5, AF14)>, /* LCD_G4 */
+				 <STM32_PINMUX('G',  0, AF14)>, /* LCD_G5 */
+				 <STM32_PINMUX('C',  7, AF14)>, /* LCD_G6 */
+				 <STM32_PINMUX('A', 15, AF11)>, /* LCD_G7 */
+				 <STM32_PINMUX('D', 10, AF14)>, /* LCD_B2 */
+				 <STM32_PINMUX('F',  2, AF14)>, /* LCD_B3 */
+				 <STM32_PINMUX('H', 14, AF11)>, /* LCD_B4 */
+				 <STM32_PINMUX('E',  0, AF14)>, /* LCD_B5 */
+				 <STM32_PINMUX('B',  6, AF7)>,  /* LCD_B6 */
+				 <STM32_PINMUX('F',  1, AF13)>; /* LCD_B7 */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	ltdc_sleep_pins_a: ltdc-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D',  9, ANALOG)>, /* LCD_CLK */
+				 <STM32_PINMUX('C',  6, ANALOG)>, /* LCD_HSYNC */
+				 <STM32_PINMUX('G',  4, ANALOG)>, /* LCD_VSYNC */
+				 <STM32_PINMUX('H',  9, ANALOG)>, /* LCD_DE */
+				 <STM32_PINMUX('G',  7, ANALOG)>, /* LCD_R2 */
+				 <STM32_PINMUX('B', 12, ANALOG)>, /* LCD_R3 */
+				 <STM32_PINMUX('D', 14, ANALOG)>, /* LCD_R4 */
+				 <STM32_PINMUX('E',  7, ANALOG)>, /* LCD_R5 */
+				 <STM32_PINMUX('E', 13, ANALOG)>, /* LCD_R6 */
+				 <STM32_PINMUX('E',  9, ANALOG)>, /* LCD_R7 */
+				 <STM32_PINMUX('H', 13, ANALOG)>, /* LCD_G2 */
+				 <STM32_PINMUX('F',  3, ANALOG)>, /* LCD_G3 */
+				 <STM32_PINMUX('D',  5, ANALOG)>, /* LCD_G4 */
+				 <STM32_PINMUX('G',  0, ANALOG)>, /* LCD_G5 */
+				 <STM32_PINMUX('C',  7, ANALOG)>, /* LCD_G6 */
+				 <STM32_PINMUX('A', 15, ANALOG)>, /* LCD_G7 */
+				 <STM32_PINMUX('D', 10, ANALOG)>, /* LCD_B2 */
+				 <STM32_PINMUX('F',  2, ANALOG)>, /* LCD_B3 */
+				 <STM32_PINMUX('H', 14, ANALOG)>, /* LCD_B4 */
+				 <STM32_PINMUX('E',  0, ANALOG)>, /* LCD_B5 */
+				 <STM32_PINMUX('B',  6, ANALOG)>, /* LCD_B6 */
+				 <STM32_PINMUX('F',  1, ANALOG)>; /* LCD_B7 */
+		};
+	};
+
 	mcp23017_pins_a: mcp23017-0 {
 		pins {
 			pinmux = <STM32_PINMUX('G', 12, GPIO)>;

-- 
2.25.1



From foss+kernel at 0leil.net  Fri Feb 23 04:45:20 2024
From: foss+kernel at 0leil.net (Quentin Schulz)
Date: Fri, 23 Feb 2024 13:45:20 +0100
Subject: [PATCH 0/3] iio: adc: rockchip_saradc: fix bitmasking and remove
 custom logic for getting reset
Message-ID: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>

The mask for the channel selection is incorrect as it's specified to be
16b wide by is actually only 4.

Also, the 16 lower bits in the SARADC_CONV_CON register are write
protected. Whatever their value is can only be written to the hardware
block if their associated bit in the higher 16 bits is set. Considering
that the channel bitmask is 4b wide but that we can write e.g. 0 in
there, we shouldn't use the value shifted by 16 as a mask but rather the
bitmask for that value shifted by 16. This is currently NOT an issue
because the only SoC with SARADCv2 IP is the RK3588 which has a reset
defined in the SoC DTSI. When that is the case, the reset is asserted
before every channel conversion is started. This means the registers are
reset so effectively, we do not need to write zeros so the wrong mask
still works because where we should be writing zeroes, there are already
zeroes. However, let's fix this in case there comes a day there's an SoC
which doesn't require to reset the controller before every channel
conversion is started.

Lastly, let's use the appropriate function from the reset subsystem
for getting an optional exclusive reset instead of rolling out our own
logic.

Those three patches should not be changing any behavior.

Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
---
Quentin Schulz (3):
      iio: adc: rockchip_saradc: fix bitmask for channels on SARADCv2
      iio: adc: rockchip_saradc: use mask for write_enable bitfield
      iio: adc: rockchip_saradc: replace custom logic with devm_reset_control_get_optional_exclusive

 drivers/iio/adc/rockchip_saradc.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)
---
base-commit: 39133352cbed6626956d38ed72012f49b0421e7b
change-id: 20240222-saradcv2-chan-mask-593585865256

Best regards,
-- 
Quentin Schulz <quentin.schulz at theobroma-systems.com>



From foss+kernel at 0leil.net  Fri Feb 23 04:45:23 2024
From: foss+kernel at 0leil.net (Quentin Schulz)
Date: Fri, 23 Feb 2024 13:45:23 +0100
Subject: [PATCH 3/3] iio: adc: rockchip_saradc: replace custom logic with
 devm_reset_control_get_optional_exclusive
In-Reply-To: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
Message-ID: <20240223-saradcv2-chan-mask-v1-3-84b06a0f623a@theobroma-systems.com>

From: Quentin Schulz <quentin.schulz at theobroma-systems.com>

devm_reset_control_get_optional_exclusive does what this driver is
trying to do in its probe function, therefore let's switch over to that
subsystem function.

Cc: Quentin Schulz <foss+kernel at 0leil.net>
Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
---
 drivers/iio/adc/rockchip_saradc.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c
index 1c0042fbbb54..bbe954a738c7 100644
--- a/drivers/iio/adc/rockchip_saradc.c
+++ b/drivers/iio/adc/rockchip_saradc.c
@@ -450,16 +450,11 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
 	 * The reset should be an optional property, as it should work
 	 * with old devicetrees as well
 	 */
-	info->reset = devm_reset_control_get_exclusive(&pdev->dev,
-						       "saradc-apb");
+	info->reset = devm_reset_control_get_optional_exclusive(&pdev->dev,
+								"saradc-apb");
 	if (IS_ERR(info->reset)) {
 		ret = PTR_ERR(info->reset);
-		if (ret != -ENOENT)
-			return dev_err_probe(&pdev->dev, ret,
-					     "failed to get saradc-apb\n");
-
-		dev_dbg(&pdev->dev, "no reset control found\n");
-		info->reset = NULL;
+		return dev_err_probe(&pdev->dev, ret, "failed to get saradc-apb\n");
 	}
 
 	init_completion(&info->completion);

-- 
2.43.2



From foss+kernel at 0leil.net  Fri Feb 23 04:45:21 2024
From: foss+kernel at 0leil.net (Quentin Schulz)
Date: Fri, 23 Feb 2024 13:45:21 +0100
Subject: [PATCH 1/3] iio: adc: rockchip_saradc: fix bitmask for channels on
 SARADCv2
In-Reply-To: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
Message-ID: <20240223-saradcv2-chan-mask-v1-1-84b06a0f623a@theobroma-systems.com>

From: Quentin Schulz <quentin.schulz at theobroma-systems.com>

The SARADCv2 on RK3588 (the only SoC currently supported that has an
SARADCv2) selects the channel through the channel_sel bitfield which is
the 4 lowest bits, therefore the mask should be GENMASK(3, 0) and not
GENMASK(15, 0).

Fixes: 757953f8ec69 ("iio: adc: rockchip_saradc: Add support for RK3588")
Cc: Quentin Schulz <foss+kernel at 0leil.net>
Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
---
 drivers/iio/adc/rockchip_saradc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c
index dd94667a623b..2da8d6f3241a 100644
--- a/drivers/iio/adc/rockchip_saradc.c
+++ b/drivers/iio/adc/rockchip_saradc.c
@@ -52,7 +52,7 @@
 #define SARADC2_START			BIT(4)
 #define SARADC2_SINGLE_MODE		BIT(5)
 
-#define SARADC2_CONV_CHANNELS GENMASK(15, 0)
+#define SARADC2_CONV_CHANNELS GENMASK(3, 0)
 
 struct rockchip_saradc;
 

-- 
2.43.2



From foss+kernel at 0leil.net  Fri Feb 23 04:45:22 2024
From: foss+kernel at 0leil.net (Quentin Schulz)
Date: Fri, 23 Feb 2024 13:45:22 +0100
Subject: [PATCH 2/3] iio: adc: rockchip_saradc: use mask for write_enable
 bitfield
In-Reply-To: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
Message-ID: <20240223-saradcv2-chan-mask-v1-2-84b06a0f623a@theobroma-systems.com>

From: Quentin Schulz <quentin.schulz at theobroma-systems.com>

Some of the registers on the SARADCv2 have bits write protected except
if another bit is set. This is usually done by having the lowest 16 bits
store the data to write and the highest 16 bits specify which of the 16
lowest bits should have their value written to the hardware block.

The write_enable mask for the channel selection was incorrect because it
was just the value shifted by 16 bits, which means it would only ever
write bits and never clear them. So e.g. if someone starts a conversion
on channel 5, the lowest 4 bits would be 0x5, then starts a conversion
on channel 0, it would still be 5.

Instead of shifting the value by 16 as the mask, let's use the OR'ing of
the appropriate masks shifted by 16.

Note that this is not an issue currently because the only SARADCv2
currently supported has a reset defined in its Device Tree, that reset
resets the SARADC controller before starting a conversion on a channel.
However, this reset is handled as optional by the probe function and
thus proper masking should be used in the event an SARADCv2 without a
reset ever makes it upstream.

Fixes: 757953f8ec69 ("iio: adc: rockchip_saradc: Add support for RK3588")
Cc: Quentin Schulz <foss+kernel at 0leil.net>
Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
---
 drivers/iio/adc/rockchip_saradc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c
index 2da8d6f3241a..1c0042fbbb54 100644
--- a/drivers/iio/adc/rockchip_saradc.c
+++ b/drivers/iio/adc/rockchip_saradc.c
@@ -102,12 +102,12 @@ static void rockchip_saradc_start_v2(struct rockchip_saradc *info, int chn)
 	writel_relaxed(0xc, info->regs + SARADC_T_DAS_SOC);
 	writel_relaxed(0x20, info->regs + SARADC_T_PD_SOC);
 	val = FIELD_PREP(SARADC2_EN_END_INT, 1);
-	val |= val << 16;
+	val |= SARADC2_EN_END_INT << 16;
 	writel_relaxed(val, info->regs + SARADC2_END_INT_EN);
 	val = FIELD_PREP(SARADC2_START, 1) |
 	      FIELD_PREP(SARADC2_SINGLE_MODE, 1) |
 	      FIELD_PREP(SARADC2_CONV_CHANNELS, chn);
-	val |= val << 16;
+	val |= (SARADC2_START | SARADC2_SINGLE_MODE | SARADC2_CONV_CHANNELS) << 16;
 	writel(val, info->regs + SARADC2_CONV_CON);
 }
 

-- 
2.43.2



From alexander.stein at ew.tq-group.com  Fri Feb 23 04:47:43 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 23 Feb 2024 13:47:43 +0100
Subject: [PATCH 1/1] media: dt-bindings: sony,imx290: Allow props from video-interface-devices
Message-ID: <20240223124744.545955-1-alexander.stein@ew.tq-group.com>

Allow properties from video-interface-devices. This aligns the bindings
to sony,imx415.yaml. Changes inspired by commit e2e73ed46c395 ("media:
dt-bindings: sony,imx415: Allow props from video-interface-devices")

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
index a531badc16c98..e957b5dd4284d 100644
--- a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
@@ -23,6 +23,9 @@ description: |-
   is treated the same as this as it was the original compatible string.
   imx290llr is the mono version of the sensor.
 
+allOf:
+  - $ref: ../video-interface-devices.yaml#
+
 properties:
   compatible:
     oneOf:
@@ -101,7 +104,7 @@ required:
   - vdddo-supply
   - port
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |
-- 
2.34.1



From alexander.stein at ew.tq-group.com  Fri Feb 23 04:51:40 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 23 Feb 2024 13:51:40 +0100
Subject: [PATCH] arm64: dts: imx8mp: Fix LDB clocks property
In-Reply-To: <20240223091522.2880155-1-victor.liu@nxp.com>
References: <20240223091522.2880155-1-victor.liu@nxp.com>
Message-ID: <1979964.usQuhbGJ8B@steina-w>

Am Freitag, 23. Februar 2024, 10:15:22 CET schrieb Liu Ying:
> The "media_ldb_root_clk" is the gate clock to enable or disable the clock
> provided by CCM(Clock Control Module) to LDB instead of the "media_ldb"
> clock which is the parent of the "media_ldb_root_clk" clock as a composite
> clock.  Fix LDB clocks property by referencing the "media_ldb_root_clk"
> clock instead of the "media_ldb" clock.
> 
> Fixes: e7567840ecd3 ("arm64: dts: imx8mp: Reorder clock and reg properties")
> Fixes: 94e6197dadc9 ("arm64: dts: imx8mp: Add LCDIF2 & LDB nodes")
> Signed-off-by: Liu Ying <victor.liu at nxp.com>

Thanks.
Reviewed-by: Alexander Stein <alexander.stein at ew.tq-group.com>

> ---
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> index 9ab9c057f41e..bfc5c81a5bd4 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -1824,7 +1824,7 @@ lvds_bridge: bridge at 5c {
>  					compatible = "fsl,imx8mp-ldb";
>  					reg = <0x5c 0x4>, <0x128 0x4>;
>  					reg-names = "ldb", "lvds";
> -					clocks = <&clk IMX8MP_CLK_MEDIA_LDB>;
> +					clocks = <&clk IMX8MP_CLK_MEDIA_LDB_ROOT>;
>  					clock-names = "ldb";
>  					assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>;
>  					assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>;
> 


-- 
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/




From will at kernel.org  Fri Feb 23 04:52:24 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 23 Feb 2024 12:52:24 +0000
Subject: [PATCH] arm64/hw_breakpoint: Determine lengths from generic perf
 breakpoint macros
In-Reply-To: <20240223113102.4027779-1-anshuman.khandual@arm.com>
References: <20240223113102.4027779-1-anshuman.khandual@arm.com>
Message-ID: <20240223125224.GC10641@willie-the-truck>

On Fri, Feb 23, 2024 at 05:01:02PM +0530, Anshuman Khandual wrote:
> Both platform i.e ARM_BREAKPOINT_LEN_X and generic i.e HW_BREAKPOINT_LEN_X
> macros are used interchangeably to convert event->attr.bp_len and platform
> breakpoint control arch_hw_breakpoint_ctrl->len. Let's be consistent while
> deriving one from the other. This does not cause any functional changes.
> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas 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 v6.8-rc5
> 
>  arch/arm64/kernel/hw_breakpoint.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
> index 35225632d70a..1ab9fc865ddd 100644
> --- a/arch/arm64/kernel/hw_breakpoint.c
> +++ b/arch/arm64/kernel/hw_breakpoint.c
> @@ -301,28 +301,28 @@ static int get_hbp_len(u8 hbp_len)
>  
>  	switch (hbp_len) {
>  	case ARM_BREAKPOINT_LEN_1:
> -		len_in_bytes = 1;
> +		len_in_bytes = HW_BREAKPOINT_LEN_1;

I don't think we should do this. The HW_BREAKPOINT_LEN_* definitions are
part of the user ABI and, although they correspond to the length in bytes,
that's not necessarily something we should rely on.

Will


From jgg at nvidia.com  Fri Feb 23 04:53:43 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 23 Feb 2024 08:53:43 -0400
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <3227d5224a9745e388738d016fdae87a@AcuMS.aculab.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
 <20240222223617.GC13330@nvidia.com>
 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
 <61931c626d9bc54369d73fda8f8ee59bbb5e95bc.camel@linux.ibm.com>
 <3227d5224a9745e388738d016fdae87a@AcuMS.aculab.com>
Message-ID: <20240223125343.GD13330@nvidia.com>

On Fri, Feb 23, 2024 at 11:05:29AM +0000, David Laight wrote:
> ...
> > > > > > +		if ((_count % 8) >= 4) {
> > > > >
> > > > > If (_count & 4) {
> > > >
> > > > That would be obfuscating, IMHO. The compiler doesn't need such things
> > > > to generate optimal code.
> > >
> > > Try it: https://godbolt.org/z/EvvGrTxv3
> > > And it isn't that obfuscated - no more so than your version.
> > 
> > The godbolt link does "n % 8 > 4" instead of "... >= 4" as in Jason's
> > original code. With ">=" the compiled code matches that for "n & 4".
> 
> Bugger :-)

Yes, I already fine tuned things to get good codegen.

Jason


From claudiu.beznea at tuxon.dev  Fri Feb 23 04:56:04 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Fri, 23 Feb 2024 14:56:04 +0200
Subject: [PATCH v2 1/2] ARM: dts: microchip: sama7g5: add sama7g5
 compatible
In-Reply-To: <20240223-b4-sama5d2-flexcom-yaml-v2-1-7e96c60c7701@microchip.com>
References: <20240223-b4-sama5d2-flexcom-yaml-v2-0-7e96c60c7701@microchip.com>
 <20240223-b4-sama5d2-flexcom-yaml-v2-1-7e96c60c7701@microchip.com>
Message-ID: <2063e4a0-4287-4b02-b7d1-d762c4a69966@tuxon.dev>

Hi, Balakrishnan,

On 23.02.2024 11:16, Balakrishnan Sambath wrote:
> Add sama7g5 flexcom specific compatible in DT with fallbacks.

Can you also take care of lan966x and sam9x60?

Thank you,
Claudiu Beznea

> 
> Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>
> ---
>  arch/arm/boot/dts/microchip/sama7g5.dtsi | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> index 269e0a3ca269..6496a4ca376f 100644
> --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
> +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
> @@ -698,7 +698,7 @@ sha: crypto at e1814000 {
>  		};
>  
>  		flx0: flexcom at e1818000 {
> -			compatible = "atmel,sama5d2-flexcom";
> +			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
>  			reg = <0xe1818000 0x200>;
>  			clocks = <&pmc PMC_TYPE_PERIPHERAL 38>;
>  			#address-cells = <1>;
> @@ -723,7 +723,7 @@ uart0: serial at 200 {
>  		};
>  
>  		flx1: flexcom at e181c000 {
> -			compatible = "atmel,sama5d2-flexcom";
> +			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
>  			reg = <0xe181c000 0x200>;
>  			clocks = <&pmc PMC_TYPE_PERIPHERAL 39>;
>  			#address-cells = <1>;
> @@ -747,7 +747,7 @@ i2c1: i2c at 600 {
>  		};
>  
>  		flx3: flexcom at e1824000 {
> -			compatible = "atmel,sama5d2-flexcom";
> +			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
>  			reg = <0xe1824000 0x200>;
>  			clocks = <&pmc PMC_TYPE_PERIPHERAL 41>;
>  			#address-cells = <1>;
> @@ -791,7 +791,7 @@ tdes: crypto at e2014000 {
>  		};
>  
>  		flx4: flexcom at e2018000 {
> -			compatible = "atmel,sama5d2-flexcom";
> +			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
>  			reg = <0xe2018000 0x200>;
>  			clocks = <&pmc PMC_TYPE_PERIPHERAL 42>;
>  			#address-cells = <1>;
> @@ -817,7 +817,7 @@ uart4: serial at 200 {
>  		};
>  
>  		flx7: flexcom at e2024000 {
> -			compatible = "atmel,sama5d2-flexcom";
> +			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
>  			reg = <0xe2024000 0x200>;
>  			clocks = <&pmc PMC_TYPE_PERIPHERAL 45>;
>  			#address-cells = <1>;
> @@ -911,7 +911,7 @@ tcb0: timer at e2814000 {
>  		};
>  
>  		flx8: flexcom at e2818000 {
> -			compatible = "atmel,sama5d2-flexcom";
> +			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
>  			reg = <0xe2818000 0x200>;
>  			clocks = <&pmc PMC_TYPE_PERIPHERAL 46>;
>  			#address-cells = <1>;
> @@ -935,7 +935,7 @@ i2c8: i2c at 600 {
>  		};
>  
>  		flx9: flexcom at e281c000 {
> -			compatible = "atmel,sama5d2-flexcom";
> +			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
>  			reg = <0xe281c000 0x200>;
>  			clocks = <&pmc PMC_TYPE_PERIPHERAL 47>;
>  			#address-cells = <1>;
> @@ -959,7 +959,7 @@ i2c9: i2c at 600 {
>  		};
>  
>  		flx11: flexcom at e2824000 {
> -			compatible = "atmel,sama5d2-flexcom";
> +			compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
>  			reg = <0xe2824000 0x200>;
>  			clocks = <&pmc PMC_TYPE_PERIPHERAL 49>;
>  			#address-cells = <1>;
> 


From jgg at nvidia.com  Fri Feb 23 04:58:52 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 23 Feb 2024 08:58:52 -0400
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <e78f6e6294c31d889ace4de3a3c3cebad04f4213.camel@linux.ibm.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
 <20240222223617.GC13330@nvidia.com>
 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
 <e78f6e6294c31d889ace4de3a3c3cebad04f4213.camel@linux.ibm.com>
Message-ID: <20240223125852.GE13330@nvidia.com>

On Fri, Feb 23, 2024 at 12:38:18PM +0100, Niklas Schnelle wrote:
> > Although I doubt that generating long TLP from byte writes is
> > really necessary.
> 
> I might have gotten confused but I think these are not byte writes.
> Remember that the count is in terms of the number of bits sized
> quantities to copy so "count == 1" is 4/8 bytes here.

Right.

There seem to be two callers of this API in the kernel, one is calling
with a constant size and wants a large TLP

Another seems to want memcpy_to_io with a guarenteed 32/64 bit store.

> > IIRC you were merging at most 4 writes.
> > So better to do a single 32bit write instead.
> > (Unless you have misaligned source data - unlikely.)
> > 
> > While write-combining to generate long TLP is probably mostly
> > safe for PCIe targets, there are some that will only handle
> > TLP for single 32bit data items.
> > Which might be why the code is explicitly requesting 4 byte copies.
> > So it may be entirely wrong to write-combine anything except
> > the generic memcpy_toio().
> 
> On anything other than s390x this should only do write-combine if the
> memory mapping allows it, no? Meaning a driver that can't handle larger
> TLPs really shouldn't use ioremap_wc() then.

Right.

> On s390x one could argue that our version of __iowriteXX_copy() is
> strictly speaking not correct in that zpci_memcpy_toio() doesn't really
> use XX bit writes which is why for us memcpy_toio() was actually a
> better fit indeed. On the other hand doing 32 bit PCI stores (an s390x
> thing) can't combine multiple stores into a single TLP which these
> functions are used for and which has much more use cases than forcing a
> copy loop with 32/64 bit sized writes which would also be a lot slower
> on s390x than an aligned zpci_memcpy_toio().

mlx5 will definitely not work right if __iowrite64_copy() results in
anything smaller than 32/64 bit PCIe TLPs.

Jason


From u.kleine-koenig at pengutronix.de  Fri Feb 23 04:59:07 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 23 Feb 2024 13:59:07 +0100
Subject: [PATCH 4/5] media: stm32-dcmipp: Convert to platform remove callback returning void
In-Reply-To: <cover.1708692946.git.u.kleine-koenig@pengutronix.de>
References: <cover.1708692946.git.u.kleine-koenig@pengutronix.de>
Message-ID: <7e85adb3c2f11fc10e5a18bb341c5af8b35c4d88.1708692946.git.u.kleine-koenig@pengutronix.de>

The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.

To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new(), which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().

Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
index 32c6619be9a2..bce821eb71ce 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
@@ -517,7 +517,7 @@ static int dcmipp_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int dcmipp_remove(struct platform_device *pdev)
+static void dcmipp_remove(struct platform_device *pdev)
 {
 	struct dcmipp_device *dcmipp = platform_get_drvdata(pdev);
 	unsigned int i;
@@ -534,8 +534,6 @@ static int dcmipp_remove(struct platform_device *pdev)
 	media_device_cleanup(&dcmipp->mdev);
 
 	v4l2_device_unregister(&dcmipp->v4l2_dev);
-
-	return 0;
 }
 
 static int dcmipp_runtime_suspend(struct device *dev)
@@ -588,7 +586,7 @@ static const struct dev_pm_ops dcmipp_pm_ops = {
 
 static struct platform_driver dcmipp_pdrv = {
 	.probe		= dcmipp_probe,
-	.remove		= dcmipp_remove,
+	.remove_new	= dcmipp_remove,
 	.driver		= {
 		.name	= DCMIPP_PDEV_NAME,
 		.of_match_table = dcmipp_of_match,
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Fri Feb 23 04:59:06 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 23 Feb 2024 13:59:06 +0100
Subject: [PATCH 3/5] media: nxp: imx8-isi: Convert to platform remove callback returning void
In-Reply-To: <cover.1708692946.git.u.kleine-koenig@pengutronix.de>
References: <cover.1708692946.git.u.kleine-koenig@pengutronix.de>
Message-ID: <2ccfcae7bab286651fcf6deff988e23c5113ac22.1708692946.git.u.kleine-koenig@pengutronix.de>

The .remove() callback for a platform driver returns an int which makes
many driver authors wrongly assume it's possible to do error handling by
returning an error code. However the value returned is ignored (apart
from emitting a warning) and this typically results in resource leaks.

To improve here there is a quest to make the remove callback return
void. In the first step of this quest all drivers are converted to
.remove_new(), which already returns void. Eventually after all drivers
are converted, .remove_new() will be renamed to .remove().

Trivially convert this driver from always returning zero in the remove
callback to the void returning variant.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
index f73facb97dc5..c2013995049c 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
@@ -506,7 +506,7 @@ static int mxc_isi_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static int mxc_isi_remove(struct platform_device *pdev)
+static void mxc_isi_remove(struct platform_device *pdev)
 {
 	struct mxc_isi_dev *isi = platform_get_drvdata(pdev);
 	unsigned int i;
@@ -523,8 +523,6 @@ static int mxc_isi_remove(struct platform_device *pdev)
 	mxc_isi_v4l2_cleanup(isi);
 
 	pm_runtime_disable(isi->dev);
-
-	return 0;
 }
 
 static const struct of_device_id mxc_isi_of_match[] = {
@@ -537,7 +535,7 @@ MODULE_DEVICE_TABLE(of, mxc_isi_of_match);
 
 static struct platform_driver mxc_isi_driver = {
 	.probe		= mxc_isi_probe,
-	.remove		= mxc_isi_remove,
+	.remove_new	= mxc_isi_remove,
 	.driver = {
 		.of_match_table = mxc_isi_of_match,
 		.name		= MXC_ISI_DRIVER_NAME,
-- 
2.43.0



From u.kleine-koenig at pengutronix.de  Fri Feb 23 04:59:03 2024
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 23 Feb 2024 13:59:03 +0100
Subject: [PATCH 0/5] media: Convert to platform remove callback returning void
Message-ID: <cover.1708692946.git.u.kleine-koenig@pengutronix.de>

Hello,

this series converts all drivers below drivers/media/platform to struct
platform_driver::remove_new(). See commit 5c5a7680e67b ("platform:
Provide a remove callback that returns no value") for an extended
explanation and the eventual goal.

All conversations are trivial, because their .remove() callbacks
returned zero unconditionally.

There are no interdependencies between these patches, so they could be
picked up individually. But I'd hope that they get picked up all
together by Mauro.

Best regards
Uwe

Uwe Kleine-K?nig (5):
  media: chips-media: wave5: Convert to platform remove callback
    returning void
  media: nuvoton: Convert to platform remove callback returning void
  media: nxp: imx8-isi: Convert to platform remove callback returning
    void
  media: stm32-dcmipp: Convert to platform remove callback returning
    void
  media: ti: j721e-csi2rx: Convert to platform remove callback returning
    void

 drivers/media/platform/chips-media/wave5/wave5-vpu.c       | 6 ++----
 drivers/media/platform/nuvoton/npcm-video.c                | 6 ++----
 drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c        | 6 ++----
 drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c | 6 ++----
 drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c      | 6 ++----
 5 files changed, 10 insertions(+), 20 deletions(-)


base-commit: 33e1d31873f87d119e5120b88cd350efa68ef276
-- 
2.43.0



From andy.shevchenko at gmail.com  Fri Feb 23 05:00:06 2024
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 15:00:06 +0200
Subject: [PATCH 3/3] iio: adc: rockchip_saradc: replace custom logic with devm_reset_control_get_optional_exclusive
In-Reply-To: <20240223-saradcv2-chan-mask-v1-3-84b06a0f623a@theobroma-systems.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
 <20240223-saradcv2-chan-mask-v1-3-84b06a0f623a@theobroma-systems.com>
Message-ID: <CAHp75VfVTJsQDwaPoPgGiT6jnymXAR3WpETqaKai8rXAC70iLw@mail.gmail.com>

On Fri, Feb 23, 2024 at 2:46?PM Quentin Schulz <foss+kernel at 0leil.net> wrote:
>
> From: Quentin Schulz <quentin.schulz at theobroma-systems.com>
>
> devm_reset_control_get_optional_exclusive does what this driver is

devm_reset_control_get_optional_exclusive()

> trying to do in its probe function, therefore let's switch over to that

do it in

> subsystem function.

> Cc: Quentin Schulz <foss+kernel at 0leil.net>

You may use the --cc option to `git send-email` instead of polluting
commit messages, or move this after the '---' cutter line.

-- 
With Best Regards,
Andy Shevchenko


From andy.shevchenko at gmail.com  Fri Feb 23 05:01:30 2024
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 15:01:30 +0200
Subject: [PATCH 0/3] iio: adc: rockchip_saradc: fix bitmasking and remove
 custom logic for getting reset
In-Reply-To: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
Message-ID: <CAHp75VfmsDeTP97srRJU09gA988xw68+ZHsXvXT3W_wv1HEauA@mail.gmail.com>

On Fri, Feb 23, 2024 at 2:46?PM Quentin Schulz <foss+kernel at 0leil.net> wrote:
>
> The mask for the channel selection is incorrect as it's specified to be
> 16b wide by is actually only 4.
>
> Also, the 16 lower bits in the SARADC_CONV_CON register are write
> protected. Whatever their value is can only be written to the hardware
> block if their associated bit in the higher 16 bits is set. Considering
> that the channel bitmask is 4b wide but that we can write e.g. 0 in
> there, we shouldn't use the value shifted by 16 as a mask but rather the
> bitmask for that value shifted by 16. This is currently NOT an issue
> because the only SoC with SARADCv2 IP is the RK3588 which has a reset
> defined in the SoC DTSI. When that is the case, the reset is asserted
> before every channel conversion is started. This means the registers are
> reset so effectively, we do not need to write zeros so the wrong mask
> still works because where we should be writing zeroes, there are already
> zeroes. However, let's fix this in case there comes a day there's an SoC
> which doesn't require to reset the controller before every channel
> conversion is started.
>
> Lastly, let's use the appropriate function from the reset subsystem
> for getting an optional exclusive reset instead of rolling out our own
> logic.
>
> Those three patches should not be changing any behavior.

Nice series, I have the comments in patch 3, but no need to resend
until Jonathan asks for. He might address that whilst applying.

Reviewed-by: Andy Shevchenko <andy.shevchenko at gmail.com>

-- 
With Best Regards,
Andy Shevchenko


From jgg at nvidia.com  Fri Feb 23 05:03:08 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 23 Feb 2024 09:03:08 -0400
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <d4150af74d7c45b79c770cd1c5d8eed7@AcuMS.aculab.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
 <20240222223617.GC13330@nvidia.com>
 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
 <e78f6e6294c31d889ace4de3a3c3cebad04f4213.camel@linux.ibm.com>
 <d4150af74d7c45b79c770cd1c5d8eed7@AcuMS.aculab.com>
Message-ID: <20240223130308.GF13330@nvidia.com>

On Fri, Feb 23, 2024 at 12:19:24PM +0000, David Laight wrote:

> Since writes get 'posted' all over the place.
> How many writes do you need to do before write-combining makes a
> difference?

The issue is that the HW can optimize if the entire transaction is
presented in one TLP, if it has to reassemble the transaction it takes
a big slow path hit.

Jason


From quentin.schulz at theobroma-systems.com  Fri Feb 23 05:10:16 2024
From: quentin.schulz at theobroma-systems.com (Quentin Schulz)
Date: Fri, 23 Feb 2024 14:10:16 +0100
Subject: [PATCH 3/3] iio: adc: rockchip_saradc: replace custom logic with
 devm_reset_control_get_optional_exclusive
In-Reply-To: <CAHp75VfVTJsQDwaPoPgGiT6jnymXAR3WpETqaKai8rXAC70iLw@mail.gmail.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
 <20240223-saradcv2-chan-mask-v1-3-84b06a0f623a@theobroma-systems.com>
 <CAHp75VfVTJsQDwaPoPgGiT6jnymXAR3WpETqaKai8rXAC70iLw@mail.gmail.com>
Message-ID: <6f76ffab-69fe-4afb-9d7e-d3cdfe37c28c@theobroma-systems.com>

Hi Andy,

Thanks for the prompt feedback on the whole series.

On 2/23/24 14:00, Andy Shevchenko wrote:
> On Fri, Feb 23, 2024 at 2:46?PM Quentin Schulz <foss+kernel at 0leil.net> wrote:
>>
>> From: Quentin Schulz <quentin.schulz at theobroma-systems.com>
>>
>> devm_reset_control_get_optional_exclusive does what this driver is
> 
> devm_reset_control_get_optional_exclusive()
> 
>> trying to do in its probe function, therefore let's switch over to that
> 
> do it in
> 
>> subsystem function.
> 
>> Cc: Quentin Schulz <foss+kernel at 0leil.net>
> 
> You may use the --cc option to `git send-email` instead of polluting
> commit messages, or move this after the '---' cutter line.
> 

The whole point is that my SoB and authorship is from my professional 
mail address which is likely to change over time, the Cc is my personal 
one for development. Basically, in the event that I change my employer, 
I would still be reachable at that Cc address without having to modify 
the .mailmap after the fact (which won't make it to an earlier version 
of the kernel for example). Some maintainers don't really like this, 
some don't mind, we'll see in which category the IIO maintainer(s) fall 
in :) (I don't mind either way just to be clear).

Cheers,
Quentin


From rogerq at kernel.org  Fri Feb 23 05:12:37 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 23 Feb 2024 15:12:37 +0200
Subject: [PATCH v5 0/4] arm64: dts: ti: am62: Add USB support for k3-am62p
Message-ID: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18@kernel.org>

Hi,

This series first adds device nodes for USB0_PHY_CTRL and USB1_PHY_CTRL
in the wkup_conf node and fixus up the USB nodes to use the newly
added nodes.

Then it adds USB support for AM62P SoC and AM62P5-SK board.

In v5, we disable USB LPM support for all USB nodes as it is not supported.
Also Acks were added and To list updated.

Changelog in each patch.

cheers,
-roger

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
Roger Quadros (4):
      dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl compatible
      arm64: dts: ti: k3-am62/a: use sub-node for USB_PHY_CTRL registers
      arm64: dts: ti: k3-am62p: add the USB sub-system
      arm64: dts: ti: k3-am62a: Disable USB LPM

 Documentation/devicetree/bindings/mfd/syscon.yaml |  1 +
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi          |  4 +-
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi        | 10 ++++
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi         |  8 ++-
 arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi       | 10 ++++
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi         | 50 +++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi       | 10 ++++
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts           | 67 +++++++++++++++++++++++
 8 files changed, 156 insertions(+), 4 deletions(-)
---
base-commit: ab480b8036fde8c1ea628bb1027919bf399468e9
change-id: 20240223-b4-for-v6-5-am62-usb-typec-dt-769eec4c8c4a

Best regards,
-- 
Roger Quadros <rogerq at kernel.org>



From rogerq at kernel.org  Fri Feb 23 05:12:39 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 23 Feb 2024 15:12:39 +0200
Subject: [PATCH v5 2/4] arm64: dts: ti: k3-am62/a: use sub-node for
 USB_PHY_CTRL registers
In-Reply-To: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18@kernel.org>
References: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18@kernel.org>
Message-ID: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-2-4b5854d17d18@kernel.org>

Exposing the entire CTRL_MMR space to syscon is not a good idea.
Add sub-nodes for USB0_PHY_CTRL and USB1_PHY_CTRL and use them
in the USB0/USB1 nodes.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
Reviewed-by: Andrew Davis <afd at ti.com>
---
Changelog:
v5 - no change.
v4 - no change. Added Andrew's Reviewed-by
     https://lore.kernel.org/all/20240205135908.54656-3-rogerq at kernel.org/
v3 - no change
     https://lore.kernel.org/all/20240201120332.4811-3-rogerq at kernel.org/
v2:
- moved am62p changes to next patch
- use new compatible for USB PHY CTRL node
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi    |  4 ++--
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi  | 10 ++++++++++
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi   |  4 ++--
 arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi | 10 ++++++++++
 4 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index e9cffca073ef..23f1464b26ed 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -622,7 +622,7 @@ usbss0: dwc3-usb at f900000 {
 		reg = <0x00 0x0f900000 0x00 0x800>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
@@ -647,7 +647,7 @@ usbss1: dwc3-usb at f910000 {
 		reg = <0x00 0x0f910000 0x00 0x800>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
index 23ce1bfda8d6..66ddf2dc51af 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -21,6 +21,16 @@ chipid: chipid at 14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	target-module at 2b300050 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index aa1e057082f0..a158df0d0ba6 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -606,7 +606,7 @@ usbss0: dwc3-usb at f900000 {
 		reg = <0x00 0x0f900000 0x00 0x800>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
@@ -629,7 +629,7 @@ usbss1: dwc3-usb at f910000 {
 		reg = <0x00 0x0f910000 0x00 0x800>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
index f7bec484705a..98043e9aa316 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
@@ -17,6 +17,16 @@ chipid: chipid at 14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	wkup_uart0: serial at 2b300000 {

-- 
2.34.1



From rogerq at kernel.org  Fri Feb 23 05:12:38 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 23 Feb 2024 15:12:38 +0200
Subject: [PATCH v5 1/4] dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl
 compatible
In-Reply-To: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18@kernel.org>
References: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18@kernel.org>
Message-ID: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-1-4b5854d17d18@kernel.org>

Add the compatible for TI AM62 USB PHY Control register. This
register is found in the TI AM62 WKUP_CTRL_MMR0 space [1]. It
is used to indicate the USB PHY PLL reference clock rate and
core voltage level to the USB controller.

[1] - https://www.ti.com/lit/pdf/spruiv7

Signed-off-by: Roger Quadros <rogerq at kernel.org>
Acked-by: Rob Herring <robh at kernel.org>
---
Changelog:
v5 - no change. Added Lee Jones in To list
v4 - no change. Added Rob's Acked-by
     https://lore.kernel.org/all/20240205135908.54656-2-rogerq at kernel.org/
v3 - add compatibles in alphabetical order
     https://lore.kernel.org/all/20240201120332.4811-2-rogerq at kernel.org/
v2 - New patch
---
 Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index 084b5c2a2a3c..9437705af92f 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -72,6 +72,7 @@ properties:
               - rockchip,rk3588-qos
               - rockchip,rv1126-qos
               - starfive,jh7100-sysmain
+              - ti,am62-usb-phy-ctrl
               - ti,am654-dss-oldi-io-ctrl
 
           - const: syscon

-- 
2.34.1



From rogerq at kernel.org  Fri Feb 23 05:12:40 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 23 Feb 2024 15:12:40 +0200
Subject: [PATCH v5 3/4] arm64: dts: ti: k3-am62p: add the USB sub-system
In-Reply-To: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18@kernel.org>
References: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18@kernel.org>
Message-ID: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-3-4b5854d17d18@kernel.org>

There are two USB instances available on the am62p5 starter kit. Include
and enable them for use on the board.

USB LPM feature is kept disabled as it is not supported.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Roger Quadros <rogerq at kernel.org>
Reviewed-by: Andrew Davis <afd at ti.com>
---
Changelog:
v5 - disabled USB LPM feature as it is not supported.
v4 - no change. Added Andrew's Reviewed-by
     https://lore.kernel.org/all/20240205135908.54656-4-rogerq at kernel.org/
v3 - no change
     https://lore.kernel.org/all/20240201120332.4811-3-rogerq at kernel.org/
v2:
- moved am62p changes to next patch
- use new compatible for USB PHY CTRL node
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi   | 50 +++++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi | 10 +++++
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts     | 67 +++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 7337a9e13535..46d35036d2d5 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -635,6 +635,56 @@ sdhci2: mmc at fa20000 {
 		status = "disabled";
 	};
 
+	usbss0: usb at f900000 {
+		compatible = "ti,am62-usb";
+		reg = <0x00 0x0f900000 0x00 0x800>;
+		clocks = <&k3_clks 161 3>;
+		clock-names = "ref";
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
+		ranges;
+		status = "disabled";
+
+		usb0: usb at 31000000 {
+			compatible = "snps,dwc3";
+			reg = <0x00 0x31000000 0x00 0x50000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+			<GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+			interrupt-names = "host", "peripheral";
+			maximum-speed = "high-speed";
+			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
+		};
+	};
+
+	usbss1: usb at f910000 {
+		compatible = "ti,am62-usb";
+		reg = <0x00 0x0f910000 0x00 0x800>;
+		clocks = <&k3_clks 162 3>;
+		clock-names = "ref";
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
+		ranges;
+		status = "disabled";
+
+		usb1: usb at 31100000 {
+			compatible = "snps,dwc3";
+			reg = <0x00 0x31100000 0x00 0x50000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+			<GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+			interrupt-names = "host", "peripheral";
+			maximum-speed = "high-speed";
+			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
+		};
+	};
+
 	fss: bus at fc00000 {
 		compatible = "simple-bus";
 		reg = <0x00 0x0fc00000 0x00 0x70000>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
index a84756c336d0..c71d9624ea27 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
@@ -18,6 +18,16 @@ chipid: chipid at 14 {
 			reg = <0x14 0x4>;
 			bootph-all;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	wkup_uart0: serial at 2b300000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index e86f34e835c1..b63888a4842d 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -27,6 +27,8 @@ aliases {
 		spi0 = &ospi0;
 		ethernet0 = &cpsw_port1;
 		ethernet1 = &cpsw_port2;
+		usb0 = &usb0;
+		usb1 = &usb1;
 	};
 
 	chosen {
@@ -297,6 +299,12 @@ AM62PX_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (G20) MCASP0_ACLKR.UART1_TXD */
 		bootph-all;
 	};
 
+	main_usb1_pins_default: main-usb1-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
+		>;
+	};
+
 	main_wlirq_pins_default: main-wlirq-default-pins {
 		pinctrl-single,pins = <
 			AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
@@ -340,6 +348,36 @@ AM62PX_IOPAD(0x0124, PIN_INPUT, 7) /* (J25) MMC2_SDCD.GPIO0_71 */
 	};
 };
 
+&main_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+
+	typec_pd0: usb-power-controller at 3f {
+		compatible = "ti,tps6598x";
+		reg = <0x3f>;
+
+		connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			self-powered;
+			data-role = "dual";
+			power-role = "sink";
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port at 0 {
+					reg = <0>;
+					usb_con_hs: endpoint {
+						remote-endpoint = <&usb0_hs_ep>;
+					};
+				};
+			};
+		};
+	};
+};
+
 &main_i2c1 {
 	status = "okay";
 	pinctrl-names = "default";
@@ -463,6 +501,35 @@ cpsw3g_phy1: ethernet-phy at 1 {
 	};
 };
 
+&usbss0 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usbss1 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usb0 {
+	usb-role-switch;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port at 0 {
+		reg = <0>;
+		usb0_hs_ep: endpoint {
+			remote-endpoint = <&usb_con_hs>;
+		};
+	};
+};
+
+&usb1 {
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_usb1_pins_default>;
+};
+
 &mcasp1 {
 	status = "okay";
 	#sound-dai-cells = <0>;

-- 
2.34.1



From rogerq at kernel.org  Fri Feb 23 05:12:41 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 23 Feb 2024 15:12:41 +0200
Subject: [PATCH v5 4/4] arm64: dts: ti: k3-am62a: Disable USB LPM
In-Reply-To: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18@kernel.org>
References: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18@kernel.org>
Message-ID: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-4-4b5854d17d18@kernel.org>

As per AM62A TRM [1] USB Link Power Management (LPM)
feature is not supported. Disable it else it may
cause enumeration failure on some devices.

> 4.9.2.1 USB2SS Unsupported Features
> The following features are not supported on this family of devices:
> ...
> - USB 2.0 ECN: Link Power Management (LPM)
> ...

[1] - https://www.ti.com/lit/pdf/spruj16

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
Changelog:
v5: new patch
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index a158df0d0ba6..adaf578280f9 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -621,6 +621,8 @@ usb0: usb at 31000000 {
 			interrupt-names = "host", "peripheral";
 			maximum-speed = "high-speed";
 			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
 		};
 	};
 
@@ -644,6 +646,8 @@ usb1: usb at 31100000 {
 			interrupt-names = "host", "peripheral";
 			maximum-speed = "high-speed";
 			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
 		};
 	};
 

-- 
2.34.1



From laurent.pinchart at ideasonboard.com  Fri Feb 23 05:14:12 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 23 Feb 2024 15:14:12 +0200
Subject: [PATCH 3/5] media: nxp: imx8-isi: Convert to platform remove
 callback returning void
In-Reply-To: <2ccfcae7bab286651fcf6deff988e23c5113ac22.1708692946.git.u.kleine-koenig@pengutronix.de>
References: <cover.1708692946.git.u.kleine-koenig@pengutronix.de>
 <2ccfcae7bab286651fcf6deff988e23c5113ac22.1708692946.git.u.kleine-koenig@pengutronix.de>
Message-ID: <20240223131412.GW31348@pendragon.ideasonboard.com>

Hi Uwe,

Thank you for the patch.

On Fri, Feb 23, 2024 at 01:59:06PM +0100, Uwe Kleine-K?nig wrote:
> The .remove() callback for a platform driver returns an int which makes
> many driver authors wrongly assume it's possible to do error handling by
> returning an error code. However the value returned is ignored (apart
> from emitting a warning) and this typically results in resource leaks.
> 
> To improve here there is a quest to make the remove callback return
> void. In the first step of this quest all drivers are converted to
> .remove_new(), which already returns void. Eventually after all drivers
> are converted, .remove_new() will be renamed to .remove().
> 
> Trivially convert this driver from always returning zero in the remove
> callback to the void returning variant.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
>  drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
> index f73facb97dc5..c2013995049c 100644
> --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
> +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
> @@ -506,7 +506,7 @@ static int mxc_isi_probe(struct platform_device *pdev)
>  	return ret;
>  }
>  
> -static int mxc_isi_remove(struct platform_device *pdev)
> +static void mxc_isi_remove(struct platform_device *pdev)
>  {
>  	struct mxc_isi_dev *isi = platform_get_drvdata(pdev);
>  	unsigned int i;
> @@ -523,8 +523,6 @@ static int mxc_isi_remove(struct platform_device *pdev)
>  	mxc_isi_v4l2_cleanup(isi);
>  
>  	pm_runtime_disable(isi->dev);
> -
> -	return 0;
>  }
>  
>  static const struct of_device_id mxc_isi_of_match[] = {
> @@ -537,7 +535,7 @@ MODULE_DEVICE_TABLE(of, mxc_isi_of_match);
>  
>  static struct platform_driver mxc_isi_driver = {
>  	.probe		= mxc_isi_probe,
> -	.remove		= mxc_isi_remove,
> +	.remove_new	= mxc_isi_remove,
>  	.driver = {
>  		.of_match_table = mxc_isi_of_match,
>  		.name		= MXC_ISI_DRIVER_NAME,

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Fri Feb 23 05:16:59 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 23 Feb 2024 15:16:59 +0200
Subject: [PATCH 1/1] media: dt-bindings: sony,imx290: Allow props from
 video-interface-devices
In-Reply-To: <20240223124744.545955-1-alexander.stein@ew.tq-group.com>
References: <20240223124744.545955-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240223131659.GX31348@pendragon.ideasonboard.com>

Hi Alexander,

Thank you for the patch.

On Fri, Feb 23, 2024 at 01:47:43PM +0100, Alexander Stein wrote:
> Allow properties from video-interface-devices. This aligns the bindings
> to sony,imx415.yaml. Changes inspired by commit e2e73ed46c395 ("media:
> dt-bindings: sony,imx415: Allow props from video-interface-devices")
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> ---
>  Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
> index a531badc16c98..e957b5dd4284d 100644
> --- a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
> @@ -23,6 +23,9 @@ description: |-
>    is treated the same as this as it was the original compatible string.
>    imx290llr is the mono version of the sensor.
>  
> +allOf:
> +  - $ref: ../video-interface-devices.yaml#

I think this should be

  - $ref: /schemas/media/video-interface-devices.yaml#

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Bonus points if you would like to send patches to the DT bindings of the
gc0308, gc2145, imx214 and imx415 to fix that :-)

> +
>  properties:
>    compatible:
>      oneOf:
> @@ -101,7 +104,7 @@ required:
>    - vdddo-supply
>    - port
>  
> -additionalProperties: false
> +unevaluatedProperties: false
>  
>  examples:
>    - |

-- 
Regards,

Laurent Pinchart


From cristian.marussi at arm.com  Fri Feb 23 05:24:23 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Fri, 23 Feb 2024 13:24:23 +0000
Subject: [PATCH 2/5] firmware: arm_scmi: add initial support for i.MX BBM
 protocol
In-Reply-To: <20240202-imx95-bbm-misc-v1-2-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
 <20240202-imx95-bbm-misc-v1-2-3cb743020933@nxp.com>
Message-ID: <Zdich_nSNzAVgIJa@pluto>

On Fri, Feb 02, 2024 at 02:34:40PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> The i.MX BBM protocol is for managing i.MX BBM module which provides
> RTC and BUTTON feature.
> 

Hi,

> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/firmware/arm_scmi/Kconfig      |  10 +
>  drivers/firmware/arm_scmi/Makefile     |   1 +
>  drivers/firmware/arm_scmi/imx-sm-bbm.c | 381 +++++++++++++++++++++++++++++++++
>  include/linux/scmi_nxp_protocol.h      |  50 +++++
>  4 files changed, 442 insertions(+)
> 
> diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
> index aa5842be19b2..56d11c9d9f47 100644
> --- a/drivers/firmware/arm_scmi/Kconfig
> +++ b/drivers/firmware/arm_scmi/Kconfig
> @@ -181,3 +181,13 @@ config ARM_SCMI_POWER_CONTROL
>  	  early shutdown/reboot SCMI requests.
>  
>  endmenu
> +
> +config IMX_SCMI_BBM_EXT
> +	tristate "i.MX SCMI BBM EXTENSION"
> +	depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF)
> +	default y if ARCH_MXC
> +	help
> +	  This enables i.MX System BBM control logic which supports RTC
> +	  and BUTTON.
> +
> +	  This driver can also be built as a module.
> diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
> index a7bc4796519c..327687acf857 100644
> --- a/drivers/firmware/arm_scmi/Makefile
> +++ b/drivers/firmware/arm_scmi/Makefile
> @@ -11,6 +11,7 @@ scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
>  scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
>  scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
>  scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o powercap.o
> +scmi-protocols-$(CONFIG_IMX_SCMI_BBM_EXT) += imx-sm-bbm.o
>  scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
>  
>  obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
> diff --git a/drivers/firmware/arm_scmi/imx-sm-bbm.c b/drivers/firmware/arm_scmi/imx-sm-bbm.c
> new file mode 100644
> index 000000000000..0e12aaeabc42
> --- /dev/null
> +++ b/drivers/firmware/arm_scmi/imx-sm-bbm.c
> @@ -0,0 +1,381 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * System Control and Management Interface (SCMI) NXP BBM Protocol
> + *
> + * Copyright 2024 NXP
> + */
> +
> +#define pr_fmt(fmt) "SCMI Notifications BBM - " fmt
> +
> +#include <linux/bits.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/scmi_protocol.h>
> +#include <linux/scmi_nxp_protocol.h>
> +
> +#include "protocols.h"
> +#include "notify.h"
> +
> +#define SCMI_PROTOCOL_SUPPORTED_VERSION		0x0

Supported version 0 is a bit awkward...unless you fw returns version 0 too
for this protocol version, it will cause an attempted protocol version
negotitation (which is optionally supported on the fw side) and a splat of
warnings from the Kernel trying to use an older version (0) with a newer
platform version...it will carry-on anyway, just be aware of this.

> +
> +enum scmi_imx_bbm_protocol_cmd {
> +	IMX_BBM_GPR_SET = 0x3,
> +	IMX_BBM_GPR_GET = 0x4,
> +	IMX_BBM_RTC_ATTRIBUTES = 0x5,
> +	IMX_BBM_RTC_TIME_SET = 0x6,
> +	IMX_BBM_RTC_TIME_GET = 0x7,
> +	IMX_BBM_RTC_ALARM_SET = 0x8,
> +	IMX_BBM_BUTTON_GET = 0x9,
> +	IMX_BBM_RTC_NOTIFY = 0xA,
> +	IMX_BBM_BUTTON_NOTIFY = 0xB,
> +};
> +
> +#define BBM_PROTO_ATTR_NUM_RTC(x)  (((x) & 0xFFU) << 16U)
> +#define BBM_PROTO_ATTR_NUM_GPR(x)  (((x) & 0xFFFFU) << 0U)

Are these 2 used anywhere ? (use bitfield & GENMASK anyway if needed)

> +
> +#define GET_RTCS_NR(x)	le32_get_bits((x), GENMASK(23, 16))
> +#define GET_GPRS_NR(x)	le32_get_bits((x), GENMASK(15, 0))
> +
> +#define SCMI_IMX_BBM_NOTIFY_RTC_UPDATED		BIT(2)
> +#define SCMI_IMX_BBM_NOTIFY_RTC_ROLLOVER	BIT(1)
> +#define SCMI_IMX_BBM_NOTIFY_RTC_ALARM		BIT(0)
> +
> +#define SCMI_IMX_BBM_RTC_ALARM_ENABLE_FLAG	BIT(0)
> +
> +#define SCMI_IMX_BBM_NOTIFY_RTC_FLAG	\
> +	(SCMI_IMX_BBM_NOTIFY_RTC_UPDATED | \
> +	 SCMI_IMX_BBM_NOTIFY_RTC_ROLLOVER | \
> +	 SCMI_IMX_BBM_NOTIFY_RTC_ALARM)
> +
> +#define SCMI_IMX_BBM_EVENT_RTC_ID(x)        (((x) >> 24) & 0xFF)

bitfield.h ... but more on this down below...

> +
> +struct scmi_imx_bbm_info {
> +	u32 version;
> +	int nr_rtc;
> +	int nr_gpr;
> +};
> +
> +struct scmi_msg_imx_bbm_protocol_attributes {
> +	__le32 attributes;
> +};
> +
> +struct scmi_imx_bbm_set_time {
> +	__le32 id;
> +	__le32 flags;
> +	__le32 value_low;
> +	__le32 value_high;
> +};
> +
> +struct scmi_imx_bbm_get_time {
> +	__le32 id;
> +	__le32 flags;
> +};
> +
> +struct scmi_imx_bbm_alarm_time {
> +	__le32 id;
> +	__le32 flags;
> +	__le32 value_low;
> +	__le32 value_high;
> +};
> +
> +struct scmi_msg_imx_bbm_rtc_notify {
> +	__le32 rtc_id;
> +	__le32 flags;
> +};
> +
> +struct scmi_msg_imx_bbm_button_notify {
> +	__le32 flags;
> +};
> +
> +struct scmi_imx_bbm_notify_payld {
> +	__le32 flags;
> +};
> +
> +static int scmi_imx_bbm_attributes_get(const struct scmi_protocol_handle *ph,
> +				       struct scmi_imx_bbm_info *pi)
> +{
> +	int ret;
> +	struct scmi_xfer *t;
> +	struct scmi_msg_imx_bbm_protocol_attributes *attr;
> +
> +	ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0, sizeof(*attr), &t);
> +	if (ret)
> +		return ret;
> +
> +	attr = t->rx.buf;
> +
> +	ret = ph->xops->do_xfer(ph, t);
> +	if (!ret) {
> +		pi->nr_rtc = GET_RTCS_NR(attr->attributes);
> +		pi->nr_gpr = GET_GPRS_NR(attr->attributes);
> +	}
> +
> +	ph->xops->xfer_put(ph, t);
> +
> +	return ret;
> +}
> +
> +static int scmi_imx_bbm_notify(const struct scmi_protocol_handle *ph,
> +			       u32 src_id, int message_id, bool enable)
> +{
> +	int ret;
> +	struct scmi_xfer *t;
> +	struct scmi_msg_imx_bbm_rtc_notify *rtc_notify;
> +	struct scmi_msg_imx_bbm_button_notify *button_notify;

You can move these 2, each one inside its if blocks, right ?

> +
> +	if (message_id == IMX_BBM_RTC_NOTIFY) {
> +		ret = ph->xops->xfer_get_init(ph, message_id, sizeof(*rtc_notify), 0, &t);
> +		if (ret)
> +			return ret;
> +
> +		rtc_notify = t->tx.buf;
> +		rtc_notify->rtc_id = cpu_to_le32(0);
> +		rtc_notify->flags = cpu_to_le32(enable ? SCMI_IMX_BBM_NOTIFY_RTC_FLAG : 0);
> +	} else if (message_id == IMX_BBM_BUTTON_NOTIFY) {
> +		ret = ph->xops->xfer_get_init(ph, message_id, sizeof(*button_notify), 0, &t);
> +		if (ret)
> +			return ret;
> +
> +		button_notify = t->tx.buf;
> +		button_notify->flags = cpu_to_le32(enable ? 1 : 0);
> +	} else {
> +		return -EINVAL;
> +	}
> +
> +	ret = ph->xops->do_xfer(ph, t);
> +
> +	ph->xops->xfer_put(ph, t);
> +	return ret;
> +}
> +
> +static enum scmi_imx_bbm_protocol_cmd evt_2_cmd[] = {
> +	IMX_BBM_RTC_NOTIFY,
> +	IMX_BBM_BUTTON_NOTIFY
> +};
> +
> +static int scmi_imx_bbm_set_notify_enabled(const struct scmi_protocol_handle *ph,
> +					   u8 evt_id, u32 src_id, bool enable)
> +{
> +	int ret, cmd_id;
> +
> +	if (evt_id >= ARRAY_SIZE(evt_2_cmd))
> +		return -EINVAL;
> +
> +	cmd_id = evt_2_cmd[evt_id];
> +	ret = scmi_imx_bbm_notify(ph, src_id, cmd_id, enable);
> +	if (ret)
> +		pr_debug("FAIL_ENABLED - evt[%X] dom[%d] - ret:%d\n",
> +			 evt_id, src_id, ret);
> +
> +	return ret;
> +}
> +
> +static void *scmi_imx_bbm_fill_custom_report(const struct scmi_protocol_handle *ph,
> +					     u8 evt_id, ktime_t timestamp,
> +					     const void *payld, size_t payld_sz,
> +					     void *report, u32 *src_id)
> +{
> +	const struct scmi_imx_bbm_notify_payld *p = payld;
> +	struct scmi_imx_bbm_notif_report *r = report;
> +
> +	if (sizeof(*p) != payld_sz)
> +		return NULL;
> +
> +	if (evt_id == SCMI_EVENT_IMX_BBM_RTC) {
> +		r->is_rtc = true;
> +		r->is_button = false;
> +		r->timestamp = timestamp;
> +		r->rtc_id = SCMI_IMX_BBM_EVENT_RTC_ID(le32_to_cpu(p->flags));

mmm... are you sure you want to handle endianity on a bitfield before
extracting the ID ?

looking at SCMI_IMX_BBM_EVENT_RTC_ID above , cannot this just be something like

	le32_get_bits(p->flags, GENMASK(31, 24))

> +		r->rtc_evt = le32_to_cpu(p->flags) & SCMI_IMX_BBM_NOTIFY_RTC_FLAG;

Same here...I dont thing endianity-conversion play on a flag bitfield is
right...dont you just need bit 0,1,2 here to extract ? .... maybe wrong
since I can only guess what all the payoad fields represents...

> +		dev_dbg(ph->dev, "RTC: %d evt: %x\n", r->rtc_id, r->rtc_evt);
> +		*src_id = r->rtc_evt;
> +	} else if (evt_id == SCMI_EVENT_IMX_BBM_BUTTON) {
> +		r->is_rtc = false;
> +		r->is_button = true;
> +		r->timestamp = timestamp;
> +		dev_dbg(ph->dev, "BBM Button\n");
> +		*src_id = 0;
> +	} else {
> +		WARN_ON(1);

...this can be heavy on receveing malformed notif... WARN_ON_ONCE() ?

> +		return NULL;
> +	}
> +
> +	return r;
> +}
> +
> +static int scmi_imx_bbm_get_num_sources(const struct scmi_protocol_handle *ph)
> +{
> +	return 1;
> +}

You can drop this...see down below.

> +
> +static const struct scmi_event scmi_imx_bbm_events[] = {
> +	{
> +		.id = SCMI_EVENT_IMX_BBM_RTC,
> +		.max_payld_sz = sizeof(struct scmi_imx_bbm_notify_payld),
> +		.max_report_sz = sizeof(struct scmi_imx_bbm_notif_report),
> +	},
> +	{
> +		.id = SCMI_EVENT_IMX_BBM_BUTTON,
> +		.max_payld_sz = sizeof(struct scmi_imx_bbm_notify_payld),
> +		.max_report_sz = sizeof(struct scmi_imx_bbm_notif_report),
> +	},
> +};
> +
> +static const struct scmi_event_ops scmi_imx_bbm_event_ops = {
> +	.get_num_sources = scmi_imx_bbm_get_num_sources,

if the number of sources is statically defined, you dont need this
helper and just set .num_sources=1 down below...as in
	
	drivers/firmware/arm_scmi/system.c

> +	.set_notify_enabled = scmi_imx_bbm_set_notify_enabled,
> +	.fill_custom_report = scmi_imx_bbm_fill_custom_report,
> +};
> +
> +static const struct scmi_protocol_events scmi_imx_bbm_protocol_events = {
> +	.queue_sz = SCMI_PROTO_QUEUE_SZ,
> +	.ops = &scmi_imx_bbm_event_ops,
> +	.evts = scmi_imx_bbm_events,
> +	.num_events = ARRAY_SIZE(scmi_imx_bbm_events),

.num_sources = 1

> +};
> +
> +static int scmi_imx_bbm_protocol_init(const struct scmi_protocol_handle *ph)
> +{
> +	u32 version;
> +	int ret;
> +	struct scmi_imx_bbm_info *binfo;
> +
> +	ret = ph->xops->version_get(ph, &version);
> +	if (ret)
> +		return ret;
> +
> +	dev_info(ph->dev, "NXP SM BBM Version %d.%d\n",
> +		 PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
> +
> +	binfo = devm_kzalloc(ph->dev, sizeof(*binfo), GFP_KERNEL);
> +	if (!binfo)
> +		return -ENOMEM;
> +
> +	ret = scmi_imx_bbm_attributes_get(ph, binfo);
> +	if (ret)
> +		return ret;
> +
> +	return ph->set_priv(ph, binfo, version);
> +}
> +
> +static int scmi_imx_bbm_rtc_time_set(const struct scmi_protocol_handle *ph,
> +				     u32 rtc_id, u64 sec)
> +{
> +	struct scmi_imx_bbm_info *pi = ph->get_priv(ph);
> +	struct scmi_imx_bbm_set_time *cfg;
> +	struct scmi_xfer *t;
> +	int ret;
> +
> +	if (rtc_id >= pi->nr_rtc)
> +		return -EINVAL;
> +
> +	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_BBM_RTC_TIME_SET, sizeof(*cfg), 0, &t);
> +	if (ret)
> +		return ret;
> +
> +	cfg = t->tx.buf;
> +	cfg->id = cpu_to_le32(rtc_id);
> +	cfg->flags = 0;
> +	cfg->value_low = cpu_to_le32(sec & 0xffffffff);
> +	cfg->value_high = cpu_to_le32(sec >> 32);
> +
lower_32_bits() / upper_32_bits .. it also handles casting

> +	ret = ph->xops->do_xfer(ph, t);
> +
> +	ph->xops->xfer_put(ph, t);
> +
> +	return ret;
> +}
> +
> +static int scmi_imx_bbm_rtc_time_get(const struct scmi_protocol_handle *ph,
> +				     u32 rtc_id, u64 *value)
> +{
> +	struct scmi_imx_bbm_info *pi = ph->get_priv(ph);
> +	struct scmi_imx_bbm_get_time *cfg;
> +	struct scmi_xfer *t;
> +	int ret;
> +
> +	if (rtc_id >= pi->nr_rtc)
> +		return -EINVAL;
> +
> +	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_BBM_RTC_TIME_GET, sizeof(*cfg), sizeof(u64), &t);
> +	if (ret)
> +		return ret;
> +
> +	cfg = t->tx.buf;
> +	cfg->id = cpu_to_le32(rtc_id);
> +	cfg->flags = 0;
> +
> +	ret = ph->xops->do_xfer(ph, t);
> +	if (!ret)
> +		*value = get_unaligned_le64(t->rx.buf);
> +
> +	ph->xops->xfer_put(ph, t);
> +
> +	return ret;
> +}
> +
> +static int scmi_imx_bbm_rtc_alarm_set(const struct scmi_protocol_handle *ph,
> +				      u32 rtc_id, u64 sec)
> +{
> +	struct scmi_imx_bbm_info *pi = ph->get_priv(ph);
> +	struct scmi_imx_bbm_alarm_time *cfg;
> +	struct scmi_xfer *t;
> +	int ret;
> +
> +	if (rtc_id >= pi->nr_rtc)
> +		return -EINVAL;
> +
> +	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_BBM_RTC_ALARM_SET, sizeof(*cfg), 0, &t);
> +	if (ret)
> +		return ret;
> +
> +	cfg = t->tx.buf;
> +	cfg->id = cpu_to_le32(rtc_id);
> +	cfg->flags = SCMI_IMX_BBM_RTC_ALARM_ENABLE_FLAG;
> +	cfg->value_low = cpu_to_le32(sec & 0xffffffff);
> +	cfg->value_high = cpu_to_le32(sec >> 32);

lower_32_bits() / upper_32_bits
> +
> +	ret = ph->xops->do_xfer(ph, t);
> +
> +	ph->xops->xfer_put(ph, t);
> +
> +	return ret;
> +}
> +
> +static int scmi_imx_bbm_button_get(const struct scmi_protocol_handle *ph, u32 *state)
> +{
> +	struct scmi_xfer *t;
> +	int ret;
> +
> +	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_BBM_BUTTON_GET, 0, sizeof(u32), &t);
> +	if (ret)
> +		return ret;
> +
> +	ret = ph->xops->do_xfer(ph, t);
> +	if (!ret)
> +		*state = get_unaligned_le32(t->rx.buf);
> +
> +	ph->xops->xfer_put(ph, t);
> +
> +	return ret;
> +}
> +
> +static const struct scmi_imx_bbm_proto_ops scmi_imx_bbm_proto_ops = {
> +	.rtc_time_get = scmi_imx_bbm_rtc_time_get,
> +	.rtc_time_set = scmi_imx_bbm_rtc_time_set,
> +	.rtc_alarm_set = scmi_imx_bbm_rtc_alarm_set,
> +	.button_get = scmi_imx_bbm_button_get,
> +};
> +
> +static const struct scmi_protocol scmi_imx_bbm = {
> +	.id = SCMI_PROTOCOL_IMX_BBM,
> +	.owner = THIS_MODULE,
> +	.instance_init = &scmi_imx_bbm_protocol_init,
> +	.ops = &scmi_imx_bbm_proto_ops,
> +	.events = &scmi_imx_bbm_protocol_events,
> +	.supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION,

...as said elsewhere you will *probably* need to add here:

	.vendor_id = "NXP_vendor_id"

or whatever is your 16-bytes NULL terminated vendor_id as exposed by
your platform SCMI fw in response the BASE_DISCOVER_VENDOR

and optionally a .sub_vendor_id / impl_ver (up to you)

.. *probably* because the mechanism has just been posted and
is under review

> +};
> +
> +module_scmi_protocol(scmi_imx_bbm);
> diff --git a/include/linux/scmi_nxp_protocol.h b/include/linux/scmi_nxp_protocol.h
> new file mode 100644
> index 000000000000..a2077e1ef5d8
> --- /dev/null
> +++ b/include/linux/scmi_nxp_protocol.h
> @@ -0,0 +1,50 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * SCMI Message Protocol driver NXP extension header
> + *
> + * Copyright 2024 NXP.
> + */
> +
> +#ifndef _LINUX_SCMI_NXP_PROTOCOL_H
> +#define _LINUX_SCMI_NXP_PROTOCOL_H
> +
> +#include <linux/bitfield.h>
> +#include <linux/device.h>
> +#include <linux/notifier.h>
> +#include <linux/types.h>
> +
> +enum scmi_nxp_protocol {
> +	SCMI_PROTOCOL_IMX_BBM = 0x81,
> +};
> +
> +struct scmi_imx_bbm_proto_ops {
> +	int (*rtc_time_set)(const struct scmi_protocol_handle *ph, u32 id,
> +			    uint64_t sec);
> +	int (*rtc_time_get)(const struct scmi_protocol_handle *ph, u32 id,
> +			    u64 *val);
> +	int (*rtc_alarm_set)(const struct scmi_protocol_handle *ph, u32 id,
> +			     u64 sec);
> +	int (*button_get)(const struct scmi_protocol_handle *ph, u32 *state);
> +};
> +
> +enum scmi_nxp_notification_events {
> +	SCMI_EVENT_IMX_BBM_RTC = 0x0,
> +	SCMI_EVENT_IMX_BBM_BUTTON = 0x1,
> +	SCMI_EVENT_IMX_MISC_CONTROL_DISABLED = 0x0,
> +	SCMI_EVENT_IMX_MISC_CONTROL_FALLING_EDGE = 0x1,
> +	SCMI_EVENT_IMX_MISC_CONTROL_RISING_EDGE = 0x2,
> +};
> +
> +#define SCMI_IMX_BBM_RTC_TIME_SET	0x6
> +#define SCMI_IMX_BBM_RTC_TIME_GET	0x7
> +#define SCMI_IMX_BBM_RTC_ALARM_SET	0x8
> +#define SCMI_IMX_BBM_BUTTON_GET		0x9
> +

Why these protocol internal commands are exposed here too ? they are
already defined above in the file containing the protocol implemenation
(rightly so)

> +struct scmi_imx_bbm_notif_report {
> +	bool			is_rtc;
> +	bool			is_button;
> +	ktime_t			timestamp;
> +	unsigned int		rtc_id;
> +	unsigned int		rtc_evt;
> +};
> +#endif
> 


All in all, beside the minor remarks above, LGTM.

Main open thing which remains (on our side) is the handling of vendor
protocol module by the core (as said)...I will chase Sudeep for an
opinion..also about the layout in the source code of all these new
upcoming vendor modules...maybe a common subdir ?

Thank,
Cristian


From sui.jingfeng at linux.dev  Fri Feb 23 05:24:38 2024
From: sui.jingfeng at linux.dev (Sui Jingfeng)
Date: Fri, 23 Feb 2024 21:24:38 +0800
Subject: [PATCH v7 36/36] drm/sun4i: hdmi: Switch to HDMI connector
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-36-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-36-8f4af575fce2@kernel.org>
Message-ID: <6163624c-4886-4cbe-a59f-e2f974f52c14@linux.dev>

Hi,

On 2024/2/23 02:14, Maxime Ripard wrote:
> The new HDMI connector infrastructure allows to remove some boilerplate,
> especially to generate infoframes. Let's switch to it.
>
> Signed-off-by: Maxime Ripard <mripard at kernel.org>


Acked-by: Sui Jingfeng <sui.jingfeng at linux.dev>



From broonie at kernel.org  Fri Feb 23 05:31:58 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 23 Feb 2024 13:31:58 +0000
Subject: [PATCH V16 1/8] arm64/sysreg: Add BRBE registers and fields
In-Reply-To: <b2dfcaf1-f466-4e81-8ca4-02bf3fa837e5@arm.com>
References: <20240125094119.2542332-1-anshuman.khandual@arm.com>
 <20240125094119.2542332-2-anshuman.khandual@arm.com>
 <ZdYAJvZf4Ut5f5Rf@FVFF77S0Q05N>
 <e89ecbde-0967-4b8e-af77-3a72f207f3d7@sirena.org.uk>
 <ZdYDJPe1n5-V-AnT@FVFF77S0Q05N>
 <7fe52cb9-12b9-4b03-8e55-08e59b4bef27@sirena.org.uk>
 <b2dfcaf1-f466-4e81-8ca4-02bf3fa837e5@arm.com>
Message-ID: <ZdieTjUeTLXvp39E@finisterre.sirena.org.uk>

On Fri, Feb 23, 2024 at 10:58:12AM +0530, Anshuman Khandual wrote:
> On 2/21/24 19:37, Mark Brown wrote:
> > On Wed, Feb 21, 2024 at 02:05:24PM +0000, Mark Rutland wrote:

> >> Sure, we're inconsistent. I'd just prefer that there's *some* local ordering
> >> here, as the patch is neither ordered as above nor by encoding:

> > I agree, I'm just saying that if we're going to fix the ordering it'd
> > probably be better to go along with what the rest of the file is doing.

> Sure, will change the registers order as has been suggested earlier i.e
> alphanumerically instead. Because ordering registers with encoding will
> push BRBCR_EL2/12 after all other BRBE registers, including BRBIDR0_EL1.

> After the change

> BRBCR_EL1
> BRBCR_EL12
> BRBCR_EL2

The _EL2/12 registers generally come at the end of the file due to the
way the encodings work?
-------------- 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/20240223/ef9c5a96/attachment.sig>

From antonio.borneo at foss.st.com  Fri Feb 23 05:39:25 2024
From: antonio.borneo at foss.st.com (Antonio Borneo)
Date: Fri, 23 Feb 2024 14:39:25 +0100
Subject: [PATCH 02/12] dt-bindings: interrupt-controller: stm32-exti:
 Add irq nexus child node
In-Reply-To: <20240222234300.GA3809915-robh@kernel.org>
References: <20240216094758.916722-1-antonio.borneo@foss.st.com>
	 <20240216094758.916722-3-antonio.borneo@foss.st.com>
	 <20240222234300.GA3809915-robh@kernel.org>
Message-ID: <2eb11bf9dc0c5f49de3fb72c44dd16d8ca136813.camel@foss.st.com>

On Thu, 2024-02-22 at 16:43 -0700, Rob Herring wrote:
> On Fri, Feb 16, 2024 at 10:47:47AM +0100, Antonio Borneo wrote:
> > The mapping of EXTI interrupts to its parent interrupt controller
> > is both SoC and instance dependent.
> > The current implementation requires adding a new table to the
> > driver's code and a new compatible for each new EXTI instance.
> > 
> > Add to the binding an interrupt nexus child node that will be
> > used on the new EXTI instances and can be optionally used on the
> > existing instances.
> > The property 'interrupt-map' in the nexus node maps each EXTI
> > interrupt to the parent interrupt.
> > Align #address-cells and #interrupt-cells between the EXTI node
> > and its nexus node.
> 
> Looks like an abuse of interrupt-map. You avoid adding yourself to the 
> abuser list by putting it in a child node. Clever. (See list in 
> drivers/of/irq.c if you don't know what I'm talking about)

Hi Rob,
thanks for the review.

Yes, I know already about the abuser list but, from the commit
message and the associated comment, I interpret it as an incorrect
use of the property interrupt-map with custom syntax thus relying 
on custom parsing code.
The child nexus node in this series allows using the default parser
in kernel.

>From your reply, looks like my interpretation is incorrect and I
missed the real concern about the abuser list.
Could you please explain why this use of interrupt-map is incorrect
and/or which are the correct use cases?

> I assume the EXTI has 0..N interrupts. Just define 'interrupts' with N 
> entries with each entry mapping EXTI interrupt N to 'interrupts' entry 
> N.

Yes, EXTI has 0..N interrupts that can be mapped to multiple
parent interrupt controllers and the mapping table has holes.
While the DT in this series only use one interrupt parent, a second
parent will follow.
So 'interrupts-extended' property would be a better matching than
'interrupts' to handle the multiple parents.

But how to code the missing entries in an 'interrupts-extended' list?
As in the example in Documentation/devicetree/bindings/dma/apple,admac.yaml ?

The 'interrupt-map' contains the matching EXTI index, thus allowing
a 'sparse' map where holes are simply ignored.

Best Regards,
Antonio



From heiko at sntech.de  Fri Feb 23 05:40:37 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 23 Feb 2024 14:40:37 +0100
Subject: [PATCH 1/3] iio: adc: rockchip_saradc: fix bitmask for channels on
 SARADCv2
In-Reply-To: <20240223-saradcv2-chan-mask-v1-1-84b06a0f623a@theobroma-systems.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
 <20240223-saradcv2-chan-mask-v1-1-84b06a0f623a@theobroma-systems.com>
Message-ID: <4499105.Wku2Vz74k6@diego>

Am Freitag, 23. Februar 2024, 13:45:21 CET schrieb Quentin Schulz:
> From: Quentin Schulz <quentin.schulz at theobroma-systems.com>
> 
> The SARADCv2 on RK3588 (the only SoC currently supported that has an
> SARADCv2) selects the channel through the channel_sel bitfield which is
> the 4 lowest bits, therefore the mask should be GENMASK(3, 0) and not
> GENMASK(15, 0).
> 
> Fixes: 757953f8ec69 ("iio: adc: rockchip_saradc: Add support for RK3588")
> Cc: Quentin Schulz <foss+kernel at 0leil.net>
> Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>

after checking against the TRM

Reviewed-by: Heiko Stuebner <heiko at sntech.de>




From colin.i.king at gmail.com  Fri Feb 23 05:43:47 2024
From: colin.i.king at gmail.com (Colin Ian King)
Date: Fri, 23 Feb 2024 13:43:47 +0000
Subject: [PATCH] clk: clocking-wizard: Remove redundant initialization of pointer div_addr
Message-ID: <20240223134347.3908301-1-colin.i.king@gmail.com>

The pointer div_addr is being assigned a value that is never used, it is
being re-assigned a different value near the end of the function where
it is being read in the next statement. The initialization is redundant
and can be removed.

Cleans up clang scan build warning:
drivers/clk/xilinx/clk-xlnx-clock-wizard.c:501:16: warning: Value stored
to 'div_addr' during its initialization is never read [deadcode.DeadStores]

Signed-off-by: Colin Ian King <colin.i.king at gmail.com>
---
 drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index 6a6e5d9292e8..19eb3fb7ae31 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -498,7 +498,7 @@ static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
 {
 	struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
 	unsigned long vco_freq, rate_div, clockout0_div;
-	void __iomem *div_addr = divider->base;
+	void __iomem *div_addr;
 	u32 reg, pre, f;
 	int err;
 
-- 
2.39.2



From heiko at sntech.de  Fri Feb 23 05:43:41 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 23 Feb 2024 14:43:41 +0100
Subject: [PATCH 2/3] iio: adc: rockchip_saradc: use mask for write_enable bitfield
In-Reply-To: <20240223-saradcv2-chan-mask-v1-2-84b06a0f623a@theobroma-systems.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
 <20240223-saradcv2-chan-mask-v1-2-84b06a0f623a@theobroma-systems.com>
Message-ID: <2385656.yKrmzQ4Hd0@diego>

Am Freitag, 23. Februar 2024, 13:45:22 CET schrieb Quentin Schulz:
> From: Quentin Schulz <quentin.schulz at theobroma-systems.com>
> 
> Some of the registers on the SARADCv2 have bits write protected except
> if another bit is set. This is usually done by having the lowest 16 bits
> store the data to write and the highest 16 bits specify which of the 16
> lowest bits should have their value written to the hardware block.
> 
> The write_enable mask for the channel selection was incorrect because it
> was just the value shifted by 16 bits, which means it would only ever
> write bits and never clear them. So e.g. if someone starts a conversion
> on channel 5, the lowest 4 bits would be 0x5, then starts a conversion
> on channel 0, it would still be 5.
> 
> Instead of shifting the value by 16 as the mask, let's use the OR'ing of
> the appropriate masks shifted by 16.
> 
> Note that this is not an issue currently because the only SARADCv2
> currently supported has a reset defined in its Device Tree, that reset
> resets the SARADC controller before starting a conversion on a channel.
> However, this reset is handled as optional by the probe function and
> thus proper masking should be used in the event an SARADCv2 without a
> reset ever makes it upstream.
> 
> Fixes: 757953f8ec69 ("iio: adc: rockchip_saradc: Add support for RK3588")
> Cc: Quentin Schulz <foss+kernel at 0leil.net>
> Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>




From heiko at sntech.de  Fri Feb 23 05:44:52 2024
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 23 Feb 2024 14:44:52 +0100
Subject: [PATCH 3/3] iio: adc: rockchip_saradc: replace custom logic with
 devm_reset_control_get_optional_exclusive
In-Reply-To: <20240223-saradcv2-chan-mask-v1-3-84b06a0f623a@theobroma-systems.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
 <20240223-saradcv2-chan-mask-v1-3-84b06a0f623a@theobroma-systems.com>
Message-ID: <3172660.fEcJ0Lxnt5@diego>

Am Freitag, 23. Februar 2024, 13:45:23 CET schrieb Quentin Schulz:
> From: Quentin Schulz <quentin.schulz at theobroma-systems.com>
> 
> devm_reset_control_get_optional_exclusive does what this driver is
> trying to do in its probe function, therefore let's switch over to that
> subsystem function.
> 
> Cc: Quentin Schulz <foss+kernel at 0leil.net>
> Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>




From robh at kernel.org  Fri Feb 23 05:48:15 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 23 Feb 2024 06:48:15 -0700
Subject: [PATCH v3 2/7] ASoC: dt-bindings: Add Rockchip RK3308 internal
 audio codec
In-Reply-To: <20240221-rk3308-audio-codec-v3-2-dfa34abfcef6@bootlin.com>
References: <20240221-rk3308-audio-codec-v3-0-dfa34abfcef6@bootlin.com>
 <20240221-rk3308-audio-codec-v3-2-dfa34abfcef6@bootlin.com>
Message-ID: <170869609254.1763035.9305540137750026528.robh@kernel.org>


On Wed, 21 Feb 2024 11:22:46 +0100, Luca Ceresoli wrote:
> Add device tree bindings document for the internal audio codec of the
> Rockchip RK3308 SoC.
> 
> Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> 
> ---
> 
> Changed in v3:
>  - fix underscore in DT label
> 
> Changed in v2:
>  - reword commit title
>  - add maxItems to resets
>  - remove quotes from reset-names
>  - use percent values for rockchip,micbias-avdd-multiplier
>  - use name compliant to the docs in the example
> ---
>  .../bindings/sound/rockchip,rk3308-codec.yaml      | 98 ++++++++++++++++++++++
>  MAINTAINERS                                        |  5 ++
>  2 files changed, 103 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From robh at kernel.org  Fri Feb 23 05:51:24 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 23 Feb 2024 06:51:24 -0700
Subject: [PATCH v14 2/3] dt-bindings: hwmon: Support Aspeed g6 PWM TACH
 Control
In-Reply-To: <20240221104025.1306227-3-billy_tsai@aspeedtech.com>
References: <20240221104025.1306227-1-billy_tsai@aspeedtech.com>
 <20240221104025.1306227-3-billy_tsai@aspeedtech.com>
Message-ID: <170869628286.1766501.17404664389550900332.robh@kernel.org>


On Wed, 21 Feb 2024 18:40:24 +0800, Billy Tsai wrote:
> Document the compatible for aspeed,ast2600-pwm-tach device, which can
> support up to 16 PWM outputs and 16 fan tach input.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  .../bindings/hwmon/aspeed,g6-pwm-tach.yaml    | 71 +++++++++++++++++++
>  1 file changed, 71 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>



From David.Laight at ACULAB.COM  Fri Feb 23 05:52:37 2024
From: David.Laight at ACULAB.COM (David Laight)
Date: Fri, 23 Feb 2024 13:52:37 +0000
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <20240223130308.GF13330@nvidia.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
 <20240222223617.GC13330@nvidia.com>
 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
 <e78f6e6294c31d889ace4de3a3c3cebad04f4213.camel@linux.ibm.com>
 <d4150af74d7c45b79c770cd1c5d8eed7@AcuMS.aculab.com>
 <20240223130308.GF13330@nvidia.com>
Message-ID: <18248cc6f411441c8a68a55f68416150@AcuMS.aculab.com>

From: Jason Gunthorpe
> Sent: 23 February 2024 13:03
> 
> On Fri, Feb 23, 2024 at 12:19:24PM +0000, David Laight wrote:
> 
> > Since writes get 'posted' all over the place.
> > How many writes do you need to do before write-combining makes a
> > difference?
> 
> The issue is that the HW can optimize if the entire transaction is
> presented in one TLP, if it has to reassemble the transaction it takes
> a big slow path hit.

Ah, so you aren't optimising to reduce the number of TLP for
(effectively) a write to a memory buffer, but have a pcie slave
that really want to see (for example) the writes for a ring buffer
entry in a single TLP?

So you really want something that (should) generate a 16 (or 32)
byte TLP? Rather than abusing the function that is expected to
generate multiple 8 byte TLP to generate larger TLP.

I'm guessing that on arm64 the ldp/stp instructions will generate
a single 16 byte TLP regardless of write combining?
They would definitely help memcpy_fromio().

Are they enough for arm64?
Getting but TLP on x86 is probably harder.
(Unless you use AVX512 registers and aligned accesses.)

It is rather a shame that there isn't an efficient way to get
access to a couple of large SIMD registers.
(eg save on stack and have the fpu code where they are for
a lazy fpu switch.)
There is quite a bit of code that would benefit, but kernel_fpu_begin()
is just too expensive.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From arnaud.pouliquen at foss.st.com  Fri Feb 23 05:54:13 2024
From: arnaud.pouliquen at foss.st.com (Arnaud POULIQUEN)
Date: Fri, 23 Feb 2024 14:54:13 +0100
Subject: [PATCH v3 7/7] remoteproc: stm32: Add support of an OP-TEE TA to
 load the firmware
In-Reply-To: <ZdeaUGpWlqGOG31u@p14s>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <20240214172127.1022199-8-arnaud.pouliquen@foss.st.com>
 <ZdeaUGpWlqGOG31u@p14s>
Message-ID: <609373ba-c81d-4aee-81cb-8628e2c6897b@foss.st.com>

Hello Mathieu,

On 2/22/24 20:02, Mathieu Poirier wrote:
> Hi,
> 
> On Wed, Feb 14, 2024 at 06:21:27PM +0100, Arnaud Pouliquen wrote:
>> The new TEE remoteproc device is used to manage remote firmware in a
>> secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
>> introduced to delegate the loading of the firmware to the trusted
>> execution context. In such cases, the firmware should be signed and
>> adhere to the image format defined by the TEE.
>>
>> A new "to_attach" field is introduced to differentiate the use cases
>> "firmware loaded by the boot stage" and "firmware loaded by the TEE".
>>
>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
>> ---
>> V2 to V3 update:
>> - remove stm32_rproc_tee_elf_sanity_check(), stm32_rproc_tee_elf_load()
>>   stm32_rproc_tee_elf_find_loaded_rsc_table() and  stm32_rproc_tee_start() that are bnow unused
>> - use new rproc::alt_boot field to sepcify that the alternate fboot method is used
>> - use stm32_rproc::to_attach field to differenciate attch mode from remoteproc tee boot mode.
>> - remove the used of stm32_rproc::fw_loaded
>> ---
>>  drivers/remoteproc/stm32_rproc.c | 85 +++++++++++++++++++++++++++++---
>>  1 file changed, 79 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
>> index fcc0001e2657..9cfcf66462e0 100644
>> --- a/drivers/remoteproc/stm32_rproc.c
>> +++ b/drivers/remoteproc/stm32_rproc.c
>> @@ -20,6 +20,7 @@
>>  #include <linux/remoteproc.h>
>>  #include <linux/reset.h>
>>  #include <linux/slab.h>
>> +#include <linux/tee_remoteproc.h>
>>  #include <linux/workqueue.h>
>>  
>>  #include "remoteproc_internal.h"
>> @@ -49,6 +50,9 @@
>>  #define M4_STATE_STANDBY	4
>>  #define M4_STATE_CRASH		5
>>  
>> +/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
>> +#define STM32_MP1_M4_PROC_ID    0
>> +
>>  struct stm32_syscon {
>>  	struct regmap *map;
>>  	u32 reg;
>> @@ -90,6 +94,8 @@ struct stm32_rproc {
>>  	struct stm32_mbox mb[MBOX_NB_MBX];
>>  	struct workqueue_struct *workqueue;
>>  	bool hold_boot_smc;
>> +	bool to_attach;
>> +	struct tee_rproc *trproc;
>>  	void __iomem *rsc_va;
>>  };
>>  
>> @@ -253,10 +259,30 @@ static int stm32_rproc_release(struct rproc *rproc)
>>  			return err;
>>  		}
>>  	}
>> +	ddata->to_attach = false;
>>  
>>  	return err;
>>  }
>>  
>> +static int stm32_rproc_tee_attach(struct rproc *rproc)
>> +{
>> +	/* Nothing to do, remote proc already started by the secured context. */
>> +	return 0;
>> +}
>> +
>> +static int stm32_rproc_tee_stop(struct rproc *rproc)
>> +{
>> +	int err;
>> +
>> +	stm32_rproc_request_shutdown(rproc);
>> +
>> +	err = tee_rproc_stop(rproc);
>> +	if (err)
>> +		return err;
>> +
>> +	return stm32_rproc_release(rproc);
>> +}
>> +
>>  static int stm32_rproc_prepare(struct rproc *rproc)
>>  {
>>  	struct device *dev = rproc->dev.parent;
>> @@ -637,10 +663,14 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
>>  {
>>  	struct stm32_rproc *ddata = rproc->priv;
>>  	struct device *dev = rproc->dev.parent;
>> +	struct tee_rproc *trproc = ddata->trproc;
>>  	phys_addr_t rsc_pa;
>>  	u32 rsc_da;
>>  	int err;
>>  
>> +	if (trproc && !ddata->to_attach)
>> +		return tee_rproc_get_loaded_rsc_table(rproc, table_sz);
>> +
> 
> Why do we need a flag at all?  Why can't st_rproc_tee_ops::get_loaded_rsc_table
> be set to tee_rproc_get_loaded_rsc_table()?


This function is used to retrieve the address of the resource table in 3 cases
- attach to a firmware started by the boot loader (U-boot).
- load of the firmware by OP-TEE.
- crash recovery on a signed firmware started by the boot loader.

The flag is used to differentiate the attch from the other uses cases
For instance we support this use case.
1) attach to the firmware on boot
2) crash during runtime
  2a) stop the firmware by OP-TEE( ddata->to_attach set to 0)
  2b) load the firmware by OP-TEE
  2c) get the loaded resource table from OP-TEE (we can not guaranty
      that the firmware loaded on recovery is the same)
  2d) restart the firmware by OP-TEE

> 
>>  	/* The resource table has already been mapped, nothing to do */
>>  	if (ddata->rsc_va)
>>  		goto done;
>> @@ -693,8 +723,20 @@ static const struct rproc_ops st_rproc_ops = {
>>  	.get_boot_addr	= rproc_elf_get_boot_addr,
>>  };
>>  
>> +static const struct rproc_ops st_rproc_tee_ops = {
>> +	.prepare	= stm32_rproc_prepare,
>> +	.start		= tee_rproc_start,
>> +	.stop		= stm32_rproc_tee_stop,
>> +	.attach		= stm32_rproc_tee_attach,
>> +	.kick		= stm32_rproc_kick,
>> +	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
>> +	.find_loaded_rsc_table = tee_rproc_find_loaded_rsc_table,
>> +	.load		= tee_rproc_load_fw,
>> +};
>> +
>>  static const struct of_device_id stm32_rproc_match[] = {
>> -	{ .compatible = "st,stm32mp1-m4" },
>> +	{.compatible = "st,stm32mp1-m4",},
>> +	{.compatible = "st,stm32mp1-m4-tee",},
>>  	{},
>>  };
>>  MODULE_DEVICE_TABLE(of, stm32_rproc_match);
>> @@ -853,6 +895,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>  	struct device *dev = &pdev->dev;
>>  	struct stm32_rproc *ddata;
>>  	struct device_node *np = dev->of_node;
>> +	struct tee_rproc *trproc = NULL;
>>  	struct rproc *rproc;
>>  	unsigned int state;
>>  	int ret;
>> @@ -861,12 +904,33 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>  	if (ret)
>>  		return ret;
>>  
>> -	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
>> -	if (!rproc)
>> -		return -ENOMEM;
> 
> This patch doesn't apply to rproc-next - please rebase.

Yes, sure. I forgot to mention in my cover letter that my series has been
applied and tested on 841c35169323 (Linux 6.8-rc4).

> 
> 
>> +	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
>> +		/*
>> +		 * Delegate the firmware management to the secure context.
>> +		 * The firmware loaded has to be signed.
>> +		 */
>> +		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
>> +		if (IS_ERR(trproc)) {
>> +			dev_err_probe(dev, PTR_ERR(trproc),
>> +				      "signed firmware not supported by TEE\n");
>> +			return PTR_ERR(trproc);
>> +		}
>> +	}
>>  
>> -	ddata = rproc->priv;
>> +	rproc = rproc_alloc(dev, np->name,
>> +			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
>> +			    NULL, sizeof(*ddata));
>> +	if (!rproc) {
>> +		ret = -ENOMEM;
>> +		goto free_tee;
>> +	}
>>  
>> +	ddata = rproc->priv;
>> +	ddata->trproc = trproc;
> 
> My opinion hasn't changed from the previous patchet, i.e tee_rproc should be
> folded in struct rproc as rproc::tee_interface.

Sure, I will do it in next version

> 
> More comments to come shortly...
> 

Thanks!
Arnaud

>> +	if (trproc) {
>> +		rproc->alt_boot = true;
>> +		trproc->rproc = rproc;
>> +	}
>>  	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
>>  
>>  	ret = stm32_rproc_parse_dt(pdev, ddata, &rproc->auto_boot);
>> @@ -881,8 +945,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>  	if (ret)
>>  		goto free_rproc;
>>  
>> -	if (state == M4_STATE_CRUN)
>> +	if (state == M4_STATE_CRUN) {
>>  		rproc->state = RPROC_DETACHED;
>> +		ddata->to_attach = true;
>> +	}
>>  
>>  	rproc->has_iommu = false;
>>  	ddata->workqueue = create_workqueue(dev_name(dev));
>> @@ -916,6 +982,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
>>  		device_init_wakeup(dev, false);
>>  	}
>>  	rproc_free(rproc);
>> +free_tee:
>> +	if (trproc)
>> +		tee_rproc_unregister(trproc);
>> +
>>  	return ret;
>>  }
>>  
>> @@ -923,6 +993,7 @@ static void stm32_rproc_remove(struct platform_device *pdev)
>>  {
>>  	struct rproc *rproc = platform_get_drvdata(pdev);
>>  	struct stm32_rproc *ddata = rproc->priv;
>> +	struct tee_rproc *trproc = ddata->trproc;
>>  	struct device *dev = &pdev->dev;
>>  
>>  	if (atomic_read(&rproc->power) > 0)
>> @@ -937,6 +1008,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
>>  		device_init_wakeup(dev, false);
>>  	}
>>  	rproc_free(rproc);
>> +	if (trproc)
>> +		tee_rproc_unregister(trproc);
>>  }
>>  
>>  static int stm32_rproc_suspend(struct device *dev)
>> -- 
>> 2.25.1
>>
> 


From robh at kernel.org  Fri Feb 23 06:02:56 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 23 Feb 2024 07:02:56 -0700
Subject: [PATCH v6 4/9] dt-bindings: usb: add NXP ChipIdea USB2
 Controller schema
In-Reply-To: <20240221145846.1611627-4-xu.yang_2@nxp.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
 <20240221145846.1611627-4-xu.yang_2@nxp.com>
Message-ID: <20240223140256.GA1768266-robh@kernel.org>

On Wed, Feb 21, 2024 at 10:58:41PM +0800, Xu Yang wrote:
> As more and more NXP i.MX chips come out, it becomes harder to maintain
> ci-hdrc-usb2.yaml if more stuffs like property restrictions are added to
> this file. This will separate i.MX parts out of ci-hdrc-usb2.yaml and add
> a new schema for NXP ChipIdea USB2 Controller.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v6:
>  - new patch
> ---
>  .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 75 +++++++++++++++++++
>  1 file changed, 75 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
> 
> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
> new file mode 100644
> index 000000000000..2ec62f564bf5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
> @@ -0,0 +1,75 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/usb/ci-hdrc-usb2-imx.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP USB2 ChipIdea USB controller
> +
> +maintainers:
> +  - Xu Yang <xu.yang_2 at nxp.com>
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - enum:
> +          - fsl,imx27-usb
> +      - items:
> +          - enum:
> +              - fsl,imx23-usb
> +              - fsl,imx25-usb
> +              - fsl,imx28-usb
> +              - fsl,imx35-usb
> +              - fsl,imx50-usb
> +              - fsl,imx51-usb
> +              - fsl,imx53-usb
> +              - fsl,imx6q-usb
> +              - fsl,imx6sl-usb
> +              - fsl,imx6sx-usb
> +              - fsl,imx6ul-usb
> +              - fsl,imx7d-usb
> +              - fsl,vf610-usb
> +          - const: fsl,imx27-usb
> +      - items:
> +          - enum:
> +              - fsl,imx8dxl-usb
> +              - fsl,imx8ulp-usb
> +          - const: fsl,imx7ulp-usb
> +          - const: fsl,imx6ul-usb
> +      - items:
> +          - enum:
> +              - fsl,imx8mm-usb
> +              - fsl,imx8mn-usb
> +          - const: fsl,imx7d-usb
> +          - const: fsl,imx27-usb
> +      - items:
> +          - enum:
> +              - fsl,imx6sll-usb
> +              - fsl,imx7ulp-usb
> +          - const: fsl,imx6ul-usb
> +          - const: fsl,imx27-usb

Now you just duplicated all the compatibles, and now any new compatibles 
have to be added in 2 places. For this to work, you have to split 
ci-hdrc-usb2.yaml into 2 files. One with all the common properties and 
one with compatibles (minus imx). This is also needed if imx has any 
extra properties the other don't.

Didn't I say this already?

Rob



From alexander.stein at ew.tq-group.com  Fri Feb 23 06:04:42 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 23 Feb 2024 15:04:42 +0100
Subject: [PATCH 0/3] i.MX8M Nano ISI single port support
Message-ID: <20240223140445.1885083-1-alexander.stein@ew.tq-group.com>

Hi,

I'm trying to fix the dtbs_check warning:
/soc at 0/bus at 32c00000/isi at 32e20000/ports: graph node has single child node
'port at 0', #address-cells/#size-cells are not necessary

OF graphs with a single port should be placed inside a 'port' node, rather than
a single 'port' node inside a 'ports' node. Bindings were designed for the
latter case.
Adjust the bindings so a seconds port (port at 1) is not allowed for
single-pipeline models and allow both 'ports' (current one) and 'port' based
OF graph connections for single-pipeline models.

Best regards,
Alexander

Alexander Stein (3):
  media: dt-bindings: nxp,imx8-isi: Refuse port at 1 for single pipeline
    models
  media: dt-bindings: nxp,imx8-isi: Allow single port for single
    pipeline models
  arm64: dts: imx8mn: Use single port for ISI

 .../devicetree/bindings/media/nxp,imx8-isi.yaml   | 15 ++++++++++++++-
 arch/arm64/boot/dts/freescale/imx8mn.dtsi         | 12 +++---------
 2 files changed, 17 insertions(+), 10 deletions(-)

-- 
2.34.1



From alexander.stein at ew.tq-group.com  Fri Feb 23 06:04:44 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 23 Feb 2024 15:04:44 +0100
Subject: [PATCH 2/3] media: dt-bindings: nxp,imx8-isi: Allow single port for single pipeline models
In-Reply-To: <20240223140445.1885083-1-alexander.stein@ew.tq-group.com>
References: <20240223140445.1885083-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240223140445.1885083-3-alexander.stein@ew.tq-group.com>

In case the hardware only supports just one pipeline, allow using a
single port node as well.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 .../devicetree/bindings/media/nxp,imx8-isi.yaml    | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
index 4d5348d456a1f..f855f3cc91fea 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
@@ -53,6 +53,12 @@ properties:
   power-domains:
     maxItems: 1
 
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description: |
+      Port representing the Pixel Link input to the ISI. Used for
+      single-pipeline models. The port shall have a single endpoint.
+
   ports:
     $ref: /schemas/graph.yaml#/properties/ports
     description: |
@@ -66,7 +72,6 @@ required:
   - clocks
   - clock-names
   - fsl,blk-ctrl
-  - ports
 
 allOf:
   - if:
@@ -87,6 +92,11 @@ allOf:
             port at 1: false
           required:
             - port at 0
+      oneOf:
+        - required:
+            - port
+        - required:
+            - ports
 
   - if:
       properties:
@@ -106,6 +116,8 @@ allOf:
           required:
             - port at 0
             - port at 1
+      required:
+        - ports
 
 additionalProperties: false
 
-- 
2.34.1



From alexander.stein at ew.tq-group.com  Fri Feb 23 06:04:43 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 23 Feb 2024 15:04:43 +0100
Subject: [PATCH 1/3] media: dt-bindings: nxp,imx8-isi: Refuse port@1 for single pipeline models
In-Reply-To: <20240223140445.1885083-1-alexander.stein@ew.tq-group.com>
References: <20240223140445.1885083-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240223140445.1885083-2-alexander.stein@ew.tq-group.com>

In case the hardware only supports just one pipeline, explicitly refuse
port at 1 in ports node.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
index e4665469a86c3..4d5348d456a1f 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
@@ -84,6 +84,7 @@ allOf:
           properties:
             port at 0:
               description: MIPI CSI-2 RX
+            port at 1: false
           required:
             - port at 0
 
-- 
2.34.1



From alexander.stein at ew.tq-group.com  Fri Feb 23 06:04:45 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 23 Feb 2024 15:04:45 +0100
Subject: [PATCH 3/3] arm64: dts: imx8mn: Use single port for ISI
In-Reply-To: <20240223140445.1885083-1-alexander.stein@ew.tq-group.com>
References: <20240223140445.1885083-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240223140445.1885083-4-alexander.stein@ew.tq-group.com>

The ISI on i.MX8M Nano only has one port/channel, so use the single port
node. Fixes the DTBS_CHECK warning:
/soc at 0/bus at 32c00000/isi at 32e20000/ports: graph node has single child node
'port at 0', #address-cells/#size-cells are not necessary

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index 136e75c51251a..de7704aafbc1a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -1118,15 +1118,9 @@ isi: isi at 32e20000 {
 				power-domains = <&disp_blk_ctrl IMX8MN_DISPBLK_PD_ISI>;
 				status = "disabled";
 
-				ports {
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					port at 0 {
-						reg = <0>;
-						isi_in: endpoint {
-							remote-endpoint = <&mipi_csi_out>;
-						};
+				port {
+					isi_in: endpoint {
+						remote-endpoint = <&mipi_csi_out>;
 					};
 				};
 			};
-- 
2.34.1



From arnaud.pouliquen at foss.st.com  Fri Feb 23 06:10:03 2024
From: arnaud.pouliquen at foss.st.com (Arnaud POULIQUEN)
Date: Fri, 23 Feb 2024 15:10:03 +0100
Subject: [PATCH v3 0/7] Introduction of a remoteproc tee to load signed
 firmware
In-Reply-To: <8af59b01-53cf-4fc4-9946-6c630fb7b38e@quicinc.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <fe4ec29f-7521-4369-a382-bae50dbf0ee5@quicinc.com>
 <adcf0c0d-f452-4285-8651-c147fcca001b@foss.st.com>
 <8af59b01-53cf-4fc4-9946-6c630fb7b38e@quicinc.com>
Message-ID: <c80d0ca1-1ae3-4af3-ba84-6dc5efaff1c7@foss.st.com>



On 2/22/24 10:55, Naman Jain wrote:
> On 2/22/2024 2:17 PM, Arnaud POULIQUEN wrote:
>> Hello Naman,
>>
>> On 2/22/24 06:43, Naman Jain wrote:
>>> On 2/14/2024 10:51 PM, Arnaud Pouliquen wrote:
>>>> Updates from the previous version [1]:
>>>>
>>>> This version proposes another approach based on an alternate load and boot
>>>> of the coprocessor. Therefore, the constraint introduced by tee_remoteproc
>>>> is that the firmware has to be authenticated and loaded before the resource
>>>> table can be obtained.
>>>>
>>>> The existing boot sequence is: >
>>>> ??? 1) Get the resource table and store it in a cache,
>>>> ?????? calling rproc->ops->parse_fw().
>>>> ??? 2) Parse the resource table and handle resources,
>>>> ?????? calling rproc_handle_resources.
>>>> ??? 3) Load the firmware, calling rproc->ops->load().
>>>> ??? 4) Start the firmware, calling rproc->ops->start().
>>>> ?? => Steps 1 and 2 are executed in rproc_fw_boot(), while steps 3 and 4 are
>>>> ???? executed in rproc_start().
>>>> => the use of rproc->ops->load() ops is mandatory
>>>>
>>>> The boot sequence needed for TEE boot is:
>>>>
>>>> ??? 1) Load the firmware.
>>>> ??? 2) Get the loaded resource, no cache.
>>>> ??? 3) Parse the resource table and handle resources.
>>>> ??? 4) Start the firmware.
>>>
>>> Hi,
>>> What problem are we really addressing here by reordering load, parse of
>>> FW resources?
>>
>> The feature introduced in TEE is the signature of the firmware images. That
>> means that before getting the resource table, we need to first authenticate the
>> firmware images.
>> Authenticating a firmware image means that we have to copy the firmware into
>> protected memory that cannot be corrupted by the non-secure and then verify the
>> signature.
>> The strategy implemented in OP-TEE is to load the firmware into destination
>> memory and then authenticate it.
>> This strategy avoids having a temporary copy of the whole images in a secure
>> memory.
>> This strategy imposes loading the firmware images before retrieving the resource
>> table.
>>
>>> Basically, what are the limitations of the current design you are referring to?
>>> I understood that TEE is designed that way.
>>
>> The limitation of the current design is that we obtain the resource table before
>> loading the firmware. Following the current design would impose constraints in
>> TEE that are not straightforward. Step 1 (getting the resource table and storing
>> it in a cache) would require having a copy of the resource table in TEE after
>> authenticating the images. However, authenticating the firmware, as explained
>> before, depends on the strategy implemented. In TEE implementation, we load the
>> firmware to authenticate it in the destination memory.
>>
>> Regards,
>> Arnaud
> 
> 
> Hello Arnaud,
> I think now I got your point. In TEE, you don't want to do anything(read
> resource table) with FW images, until its loaded and authenticated.
> Since current design was not allowing you to do it, you had to reorganize the
> code so that this can be achieved.
> 
> Generally speaking, in current design, if authentication fails for some
> reason later, one can handle it, but it depends on the implementation of
> parse_fw op if the damage is already done.
> 
> Please correct me if this is wrong assumption.

That's correct.

Regards,
Arnaud

> Patch looks good to me.
> 
> Regards,
> Naman Jain


From laurent.pinchart at ideasonboard.com  Fri Feb 23 06:16:30 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 23 Feb 2024 16:16:30 +0200
Subject: [PATCH 2/3] media: dt-bindings: nxp,imx8-isi: Allow single port
 for single pipeline models
In-Reply-To: <20240223140445.1885083-3-alexander.stein@ew.tq-group.com>
References: <20240223140445.1885083-1-alexander.stein@ew.tq-group.com>
 <20240223140445.1885083-3-alexander.stein@ew.tq-group.com>
Message-ID: <20240223141630.GA1313@pendragon.ideasonboard.com>

Hi Alexander,

Thank you for the patch.

On Fri, Feb 23, 2024 at 03:04:44PM +0100, Alexander Stein wrote:
> In case the hardware only supports just one pipeline, allow using a
> single port node as well.

This is frowned upon in DT bindings, as it makes them more complicated
for little gain. The recommendation is to always use a ports node if a
device can have multiple ports for at least one of its compatibles.

> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> ---
>  .../devicetree/bindings/media/nxp,imx8-isi.yaml    | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
> index 4d5348d456a1f..f855f3cc91fea 100644
> --- a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
> +++ b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
> @@ -53,6 +53,12 @@ properties:
>    power-domains:
>      maxItems: 1
>  
> +  port:
> +    $ref: /schemas/graph.yaml#/properties/port
> +    description: |
> +      Port representing the Pixel Link input to the ISI. Used for
> +      single-pipeline models. The port shall have a single endpoint.
> +
>    ports:
>      $ref: /schemas/graph.yaml#/properties/ports
>      description: |
> @@ -66,7 +72,6 @@ required:
>    - clocks
>    - clock-names
>    - fsl,blk-ctrl
> -  - ports
>  
>  allOf:
>    - if:
> @@ -87,6 +92,11 @@ allOf:
>              port at 1: false
>            required:
>              - port at 0
> +      oneOf:
> +        - required:
> +            - port
> +        - required:
> +            - ports
>  
>    - if:
>        properties:
> @@ -106,6 +116,8 @@ allOf:
>            required:
>              - port at 0
>              - port at 1
> +      required:
> +        - ports
>  
>  additionalProperties: false
>  

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Fri Feb 23 06:17:31 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 23 Feb 2024 16:17:31 +0200
Subject: [PATCH 2/3] media: dt-bindings: nxp,imx8-isi: Allow single port
 for single pipeline models
In-Reply-To: <20240223141630.GA1313@pendragon.ideasonboard.com>
References: <20240223140445.1885083-1-alexander.stein@ew.tq-group.com>
 <20240223140445.1885083-3-alexander.stein@ew.tq-group.com>
 <20240223141630.GA1313@pendragon.ideasonboard.com>
Message-ID: <20240223141731.GB1313@pendragon.ideasonboard.com>

On Fri, Feb 23, 2024 at 04:16:31PM +0200, Laurent Pinchart wrote:
> Hi Alexander,
> 
> Thank you for the patch.
> 
> On Fri, Feb 23, 2024 at 03:04:44PM +0100, Alexander Stein wrote:
> > In case the hardware only supports just one pipeline, allow using a
> > single port node as well.
> 
> This is frowned upon in DT bindings, as it makes them more complicated
> for little gain. The recommendation is to always use a ports node if a
> device can have multiple ports for at least one of its compatibles.

And reading the cover letter, I see this causes warnings. I think we
need guidance from Rob on this.

> > Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> >  .../devicetree/bindings/media/nxp,imx8-isi.yaml    | 14 +++++++++++++-
> >  1 file changed, 13 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
> > index 4d5348d456a1f..f855f3cc91fea 100644
> > --- a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
> > +++ b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
> > @@ -53,6 +53,12 @@ properties:
> >    power-domains:
> >      maxItems: 1
> >  
> > +  port:
> > +    $ref: /schemas/graph.yaml#/properties/port
> > +    description: |
> > +      Port representing the Pixel Link input to the ISI. Used for
> > +      single-pipeline models. The port shall have a single endpoint.
> > +
> >    ports:
> >      $ref: /schemas/graph.yaml#/properties/ports
> >      description: |
> > @@ -66,7 +72,6 @@ required:
> >    - clocks
> >    - clock-names
> >    - fsl,blk-ctrl
> > -  - ports
> >  
> >  allOf:
> >    - if:
> > @@ -87,6 +92,11 @@ allOf:
> >              port at 1: false
> >            required:
> >              - port at 0
> > +      oneOf:
> > +        - required:
> > +            - port
> > +        - required:
> > +            - ports
> >  
> >    - if:
> >        properties:
> > @@ -106,6 +116,8 @@ allOf:
> >            required:
> >              - port at 0
> >              - port at 1
> > +      required:
> > +        - ports
> >  
> >  additionalProperties: false
> >  

-- 
Regards,

Laurent Pinchart


From michael.j.ruhl at intel.com  Fri Feb 23 06:18:14 2024
From: michael.j.ruhl at intel.com (Michael J. Ruhl)
Date: Fri, 23 Feb 2024 09:18:14 -0500
Subject: [PATCH] clkdev: Update clkdev id usage to allow for longer names
Message-ID: <20240223141857.3794855-1-michael.j.ruhl@intel.com>

clkdev ID information is limited to arrays of 20 and 16 bytes
(MAX_DEV_ID/MAX_CON_ID).  It is possible that the IDs could be
longer that.  If so, the lookup will fail because the "real ID"
will not match the copied value.

Increase the size of the IDs to allow for longer names.

Signed-off-by: Michael J. Ruhl <michael.j.ruhl at intel.com>
---
 drivers/clk/clkdev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index ee37d0be6877..38549db691f4 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -144,8 +144,8 @@ void clkdev_add_table(struct clk_lookup *cl, size_t num)
 	mutex_unlock(&clocks_mutex);
 }
 
-#define MAX_DEV_ID	20
-#define MAX_CON_ID	16
+#define MAX_DEV_ID	32
+#define MAX_CON_ID	32
 
 struct clk_lookup_alloc {
 	struct clk_lookup cl;
-- 
2.41.0



From andy.shevchenko at gmail.com  Fri Feb 23 06:39:20 2024
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 16:39:20 +0200
Subject: [PATCH 3/3] iio: adc: rockchip_saradc: replace custom logic with devm_reset_control_get_optional_exclusive
In-Reply-To: <6f76ffab-69fe-4afb-9d7e-d3cdfe37c28c@theobroma-systems.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
 <20240223-saradcv2-chan-mask-v1-3-84b06a0f623a@theobroma-systems.com>
 <CAHp75VfVTJsQDwaPoPgGiT6jnymXAR3WpETqaKai8rXAC70iLw@mail.gmail.com> <6f76ffab-69fe-4afb-9d7e-d3cdfe37c28c@theobroma-systems.com>
Message-ID: <CAHp75Vft3kJEF9JiuEqVsS3biQ6YsuDXON_P3FOZRjtb8NaB2w@mail.gmail.com>

On Fri, Feb 23, 2024 at 3:10?PM Quentin Schulz
<quentin.schulz at theobroma-systems.com> wrote:
> On 2/23/24 14:00, Andy Shevchenko wrote:
> > On Fri, Feb 23, 2024 at 2:46?PM Quentin Schulz <foss+kernel at 0leil.net> wrote:

...

> >> Cc: Quentin Schulz <foss+kernel at 0leil.net>
> >
> > You may use the --cc option to `git send-email` instead of polluting
> > commit messages, or move this after the '---' cutter line.
>
> The whole point is that my SoB and authorship is from my professional
> mail address which is likely to change over time, the Cc is my personal
> one for development. Basically, in the event that I change my employer,
> I would still be reachable at that Cc address without having to modify
> the .mailmap after the fact (which won't make it to an earlier version
> of the kernel for example). Some maintainers don't really like this,
> some don't mind, we'll see in which category the IIO maintainer(s) fall
> in :) (I don't mind either way just to be clear).

My point is that Cc and other similar (non-real-tags) stuff is
polluting commit messages. It means that this will be copied to the
Git index to all kernel git repositories in the world from now and
then, This is at bare minimum makes additional burden on git log (and
parsing and so on) and moreover, wastes resources becoming less
environment friendly (no jokes). Using --cc or moving to the behind
the commit message will keep email copied with cleaner commit
messages. Yet, all email tags are available in lore archive
(lore.kernel.org). Please, really reconsider the commit messages
content in the Linux kernel project and elsewhere, it will help to
make the world more friendly.

-- 
With Best Regards,
Andy Shevchenko


From shawnguo2 at yeah.net  Fri Feb 23 06:42:58 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Fri, 23 Feb 2024 22:42:58 +0800
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <c3e68c62-b81f-475b-9b15-c983c94aed8b@app.fastmail.com>
References: <20240221120123.1118552-1-ghennadi.procopciuc@oss.nxp.com>
 <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
 <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
 <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>
 <e6f6070e-8355-4a0b-a904-1a24970f249b@linaro.org>
 <e530d504-dfa3-4d39-b903-b2570bb8b014@suse.com>
 <c3e68c62-b81f-475b-9b15-c983c94aed8b@app.fastmail.com>
Message-ID: <Zdiu8s5Cgz9s6dLP@dragon>

On Fri, Feb 23, 2024 at 01:29:10PM +0100, Arnd Bergmann wrote:
> On Fri, Feb 23, 2024, at 13:02, Matthias Brugger wrote:
> > On 22/02/2024 12:13, Krzysztof Kozlowski wrote:
> >> On 21/02/2024 18:00, Ghennadi Procopciuc wrote:
> >> 
> >> Andreas or Matthias,
> >> Maybe you could change your R: into M: and take s32g patches?
> >> 
> >> If not, then I will ack this patch making Ghennadi the maintainer.
> >> 
> >
> > Normal process would be that Arnd would contact Chester to see if he is 
> > not able 
> > to do the maintainer work any more. In that case maybe Arnd could take 
> > over.
> 
> I was hoping to see a reply from Chester one way or another,
> I see he has been on Cc for the entire thread but not
> chimed in.
> 
> > I'm not saying that Ghennadi won't be able to defend this, if it ever occurs. 
> > Basically because I don't have a good track record of him due to missing 
> > upstream collaboration.
> >
> > I would prefer that Arnd (or Andreas) step up to take the maintainer role. I 
> > already have one and it's difficult for me to find the time to do it in an 
> > acceptable way.
> 
> It appears that we already cover the dts files in the IMX
> entry, whether that is intentional or not:
> 
> ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
> M:      Shawn Guo <shawnguo at kernel.org>
> M:      Sascha Hauer <s.hauer at pengutronix.de>
> R:      Pengutronix Kernel Team <kernel at pengutronix.de>
> R:      Fabio Estevam <festevam at gmail.com>
> R:      NXP Linux Team <linux-imx at nxp.com> 
> L:      linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> S:      Maintained
> T:      git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
> F:      arch/arm/boot/dts/nxp/imx/
> F:      arch/arm/boot/dts/nxp/mxs/
> F:      arch/arm64/boot/dts/freescale/
> 
> Added everyone there to Cc, having any s32 patches go through
> the imx tree would be the easiest way as far as I'm concerned.
> I've added the maintainers to Cc, let's see what they think.

It's unintentional that IMX entry covers s32 dts files, as they have a
dedicated entry.

ARM/NXP S32G ARCHITECTURE
M:      Chester Lin <chester62515 at gmail.com>
R:      Andreas F?rber <afaerber at suse.de>
R:      Matthias Brugger <mbrugger at suse.com>
R:      NXP S32 Linux Team <s32 at nxp.com>
L:      linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
S:      Maintained
F:      arch/arm64/boot/dts/freescale/s32g*.dts*

However I'm fine with collecting and sending patches through IMX tree,
if S32G folks help review them.

Shawn



From jgg at nvidia.com  Fri Feb 23 06:44:02 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 23 Feb 2024 10:44:02 -0400
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <18248cc6f411441c8a68a55f68416150@AcuMS.aculab.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
 <20240222223617.GC13330@nvidia.com>
 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
 <e78f6e6294c31d889ace4de3a3c3cebad04f4213.camel@linux.ibm.com>
 <d4150af74d7c45b79c770cd1c5d8eed7@AcuMS.aculab.com>
 <20240223130308.GF13330@nvidia.com>
 <18248cc6f411441c8a68a55f68416150@AcuMS.aculab.com>
Message-ID: <20240223144402.GG13330@nvidia.com>

On Fri, Feb 23, 2024 at 01:52:37PM +0000, David Laight wrote:
> > > Since writes get 'posted' all over the place.
> > > How many writes do you need to do before write-combining makes a
> > > difference?
> > 
> > The issue is that the HW can optimize if the entire transaction is
> > presented in one TLP, if it has to reassemble the transaction it takes
> > a big slow path hit.
> 
> Ah, so you aren't optimising to reduce the number of TLP for
> (effectively) a write to a memory buffer, but have a pcie slave
> that really want to see (for example) the writes for a ring buffer
> entry in a single TLP?
> 
> So you really want something that (should) generate a 16 (or 32)
> byte TLP? Rather than abusing the function that is expected to
> generate multiple 8 byte TLP to generate larger TLP.

__iowriteXX_copy() was originally created by Pathscale (an RDMA device
company) to support RDMA drivers doing exactly this workload. It is
not an abuse.

> It is rather a shame that there isn't an efficient way to get
> access to a couple of large SIMD registers.

Yes, userspace uses SIMD to make this work alot better and run faster.

Jason


From broonie at kernel.org  Fri Feb 23 06:46:56 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 23 Feb 2024 14:46:56 +0000
Subject: [PATCH v4 12/14] KVM: arm64: Support FEAT_FPMR for guests
In-Reply-To: <86plwn2ztw.wl-maz@kernel.org>
References: <20240122-arm64-2023-dpisa-v4-0-776e094861df@kernel.org>
 <20240122-arm64-2023-dpisa-v4-12-776e094861df@kernel.org>
 <86plwn2ztw.wl-maz@kernel.org>
Message-ID: <Zdiv4E+sjo6JeiP8@finisterre.sirena.org.uk>

On Fri, Feb 23, 2024 at 11:18:51AM +0000, Marc Zyngier wrote:
> Mark Brown <broonie at kernel.org> wrote:

> >  #define HCRX_GUEST_FLAGS \
> > -	(HCRX_EL2_SMPME | HCRX_EL2_TCR2En | \
> > +	(HCRX_EL2_SMPME | HCRX_EL2_TCR2En | HCRX_EL2_EnFPM | \

> No. We don't do that anymore. This can only be enabled if the guest
> has it advertised via ID_AA64PFR2_EL1.FPMR.

Right, as mentioned in the cover letter (and previously discussed with
one of the other serieses) this needs a rework against your at the time
of posting still pending changes to parse the ID registers.  It looks
like everything is there for those now so I'll do that after the merge
window.
-------------- 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/20240223/f0768de0/attachment.sig>

From alexander.stein at ew.tq-group.com  Fri Feb 23 06:47:41 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 23 Feb 2024 15:47:41 +0100
Subject: [PATCH v2 1/5] media: dt-bindings: sony,imx290: Allow props from video-interface-devices
Message-ID: <20240223144746.2583749-1-alexander.stein@ew.tq-group.com>

Allow properties from video-interface-devices. This aligns the bindings
to sony,imx415.yaml. Changes inspired by commit e2e73ed46c395 ("media:
dt-bindings: sony,imx415: Allow props from video-interface-devices")

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
Changes in v2:
* Use absolute path to other schemas

 Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
index a531badc16c98..bf05ca48601ab 100644
--- a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
@@ -23,6 +23,9 @@ description: |-
   is treated the same as this as it was the original compatible string.
   imx290llr is the mono version of the sensor.
 
+allOf:
+  - $ref: /schemas/media/video-interface-devices.yaml#
+
 properties:
   compatible:
     oneOf:
@@ -101,7 +104,7 @@ required:
   - vdddo-supply
   - port
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |
-- 
2.34.1



From alexander.stein at ew.tq-group.com  Fri Feb 23 06:47:44 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 23 Feb 2024 15:47:44 +0100
Subject: [PATCH v2 4/5] media: dt-bindings: sony,imx214: use absolute path to other schema
In-Reply-To: <20240223144746.2583749-1-alexander.stein@ew.tq-group.com>
References: <20240223144746.2583749-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240223144746.2583749-4-alexander.stein@ew.tq-group.com>

Absolute path to other DT schema is preferred over relative one.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
Changes in v2:
* Added new patch

 Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml
index 60903da84e1f3..0162eec8ca993 100644
--- a/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml
@@ -16,7 +16,7 @@ description: |
   maximum throughput of 1.2Gbps/lane.
 
 allOf:
-  - $ref: ../video-interface-devices.yaml#
+  - $ref: /schemas/media/video-interface-devices.yaml#
 
 properties:
   compatible:
-- 
2.34.1



From alexander.stein at ew.tq-group.com  Fri Feb 23 06:47:45 2024
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 23 Feb 2024 15:47:45 +0100
Subject: [PATCH v2 5/5] media: dt-bindings: sony,imx415: use absolute path to other schema
In-Reply-To: <20240223144746.2583749-1-alexander.stein@ew.tq-group.com>
References: <20240223144746.2583749-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240223144746.2583749-5-alexander.stein@ew.tq-group.com>

Absolute path to other DT schema is preferred over relative one.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
Changes in v2:
* Added new patch

 Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
index 9a00dab2e8a3f..34962c5c70065 100644
--- a/Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
@@ -18,7 +18,7 @@ description: |-
   available via CSI-2 serial data output (two or four lanes).
 
 allOf:
-  - $ref: ../video-interface-devices.yaml#
+  - $ref: /schemas/media/video-interface-devices.yaml#
 
 properties:
   compatible:
-- 
2.34.1



From maz at kernel.org  Fri Feb 23 06:49:16 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 23 Feb 2024 14:49:16 +0000
Subject: [PATCH v2] perf print-events: make is_event_supported() more
 robust
In-Reply-To: <20240126145605.1005472-1-mark.rutland@arm.com>
References: <20240126145605.1005472-1-mark.rutland@arm.com>
Message-ID: <8bc9dcbab11aa25115d0d278d353188e@kernel.org>

On 2024-01-26 14:56, Mark Rutland wrote:
> Currently the perf tool doesn't detect support for extended event types
> on Apple M1/M2 systems, and will not auto-expand plain PERF_EVENT_TYPE
> hardware events into per-PMU events. This is due to the detection of
> extended event types not handling mandatory filters required by the
> M1/M2 PMU driver.
> 
> PMU drivers and the core perf_events code can require that
> perf_event_attr::exclude_* filters are configured in a specific way and
> may reject certain configurations of filters, for example:
> 
> (a) Many PMUs lack support for any event filtering, and require all
>     perf_event_attr::exclude_* bits to be clear. This includes Alpha's
>     CPU PMU, and ARM CPU PMUs prior to the introduction of PMUv2 in
>     ARMv7,
> 
> (b) When /proc/sys/kernel/perf_event_paranoid >= 2, the perf core
>     requires that perf_event_attr::exclude_kernel is set.
> 
> (c) The Apple M1/M2 PMU requires that perf_event_attr::exclude_guest is
>     set as the hardware PMU does not count while a guest is running 
> (but
>     might be extended in future to do so).
> 
> In is_event_supported(), we try to account for cases (a) and (b), first
> attempting to open an event without any filters, and if this fails,
> retrying with perf_event_attr::exclude_kernel set. We do not account 
> for
> case (c), or any other filters that drivers could theoretically require
> to be set.
> 
> Thus is_event_supported() will fail to detect support for any events
> targeting an Apple M1/M2 PMU, even where events would be supported with
> perf_event_attr:::exclude_guest set.
> 
> Since commit:
> 
>   82fe2e45cdb00de4 ("perf pmus: Check if we can encode the PMU number
> in perf_event_attr.type")
> 
> ... we use is_event_supported() to detect support for extended types,
> with the PMU ID encoded into the perf_event_attr::type. As above, on an
> Apple M1/M2 system this will always fail to detect that the event is
> supported, and consequently we fail to detect support for extended 
> types
> even when these are supported, as they have been since commit:
> 
>   5c816728651ae425 ("arm_pmu: Add PERF_PMU_CAP_EXTENDED_HW_TYPE 
> capability")
> 
> Due to this, the perf tool will not automatically expand plain
> PERF_TYPE_HARDWARE events into per-PMU events, even when all the
> necessary kernel support is present.
> 
> This patch updates is_event_supported() to additionally try opening
> events with perf_event_attr::exclude_guest set, allowing support for
> events to be detected on Apple M1/M2 systems. I believe that this is
> sufficient for all contemporary CPU PMU drivers, though in future it 
> may
> be necessary to check for other combinations of filter bits.
> 
> I've deliberately changed the check to not expect a specific error code
> for missing filters, as today ;the kernel may return a number of
> different error codes for missing filters (e.g. -EACCESS, -EINVAL, or
> -EOPNOTSUPP) depending on why and where the filter configuration is
> rejected, and retrying for any error is more robust.
> 
> Note that this does not remove the need for commit:
> 
>   a24d9d9dc096fc0d ("perf parse-events: Make legacy events lower
> priority than sysfs/JSON")
> 
> ... which is still necessary so that named-pmu/event/ events work on
> kernels without extended type support, even if the event name happens 
> to
> be the same as a PERF_EVENT_TYPE_HARDWARE event (e.g. as is the case 
> for
> the M1/M2 PMU's 'cycles' and 'instructions' events).
> 
> Fixes: 82fe2e45cdb00de4 ("perf pmus: Check if we can encode the PMU
> number in perf_event_attr.type")
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Tested-by: Ian Rogers <irogers at google.com>
> Tested-by: James Clark <james.clark at arm.com>
> Cc: Arnaldo Carvalho de Melo <acme at redhat.com>
> Cc: Hector Martin <marcan at marcan.st>
> Cc: Ian Rogers <irogers at google.com>
> Cc: James Clark <james.clark at arm.com>
> Cc: John Garry <john.g.garry at oracle.com>
> Cc: Leo Yan <leo.yan at linaro.org>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Namhyung Kim <namhyung at kernel.org>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Thomas Richter <tmricht at linux.ibm.com>
> Cc: Will Deacon <will at kernel.org>

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

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


From colin.i.king at gmail.com  Fri Feb 23 06:53:27 2024
From: colin.i.king at gmail.com (Colin Ian King)
Date: Fri, 23 Feb 2024 14:53:27 +0000
Subject: [PATCH][next] soc: fsl: dpio: remove redundant assignment to pointer p
Message-ID: <20240223145327.3909835-1-colin.i.king@gmail.com>

There are two places where pointer p is being assigned a value that
is never read, the pointer is re-assingned later. The assignments
are redundant and can be removed.

Cleans up two clang scan build warnings:
drivers/soc/fsl/dpio/qbman-portal.c:662:3: warning: Value stored to 'p'
is never read [deadcode.DeadStores]
drivers/soc/fsl/dpio/qbman-portal.c:820:3: warning: Value stored to 'p'
is never read [deadcode.DeadStores]

Signed-off-by: Colin Ian King <colin.i.king at gmail.com>
---
 drivers/soc/fsl/dpio/qbman-portal.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/soc/fsl/dpio/qbman-portal.c b/drivers/soc/fsl/dpio/qbman-portal.c
index 0a3fb6c115f4..03cc374f11d7 100644
--- a/drivers/soc/fsl/dpio/qbman-portal.c
+++ b/drivers/soc/fsl/dpio/qbman-portal.c
@@ -659,7 +659,6 @@ int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
 
 	if (!s->eqcr.available) {
 		eqcr_ci = s->eqcr.ci;
-		p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI;
 		s->eqcr.ci = qbman_read_register(s, QBMAN_CINH_SWP_EQCR_CI);
 		s->eqcr.ci &= full_mask;
 
@@ -817,7 +816,6 @@ int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
 	full_mask = s->eqcr.pi_ci_mask;
 	if (!s->eqcr.available) {
 		eqcr_ci = s->eqcr.ci;
-		p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI;
 		s->eqcr.ci = qbman_read_register(s, QBMAN_CINH_SWP_EQCR_CI);
 		s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
 					eqcr_ci, s->eqcr.ci);
-- 
2.39.2



From laurent.pinchart at ideasonboard.com  Fri Feb 23 06:54:11 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 23 Feb 2024 16:54:11 +0200
Subject: [PATCH v2 1/5] media: dt-bindings: sony,imx290: Allow props from
 video-interface-devices
In-Reply-To: <20240223144746.2583749-1-alexander.stein@ew.tq-group.com>
References: <20240223144746.2583749-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240223145411.GC1313@pendragon.ideasonboard.com>

On Fri, Feb 23, 2024 at 03:47:41PM +0100, Alexander Stein wrote:
> Allow properties from video-interface-devices. This aligns the bindings
> to sony,imx415.yaml. Changes inspired by commit e2e73ed46c395 ("media:
> dt-bindings: sony,imx415: Allow props from video-interface-devices")
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
> Changes in v2:
> * Use absolute path to other schemas
> 
>  Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
> index a531badc16c98..bf05ca48601ab 100644
> --- a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
> @@ -23,6 +23,9 @@ description: |-
>    is treated the same as this as it was the original compatible string.
>    imx290llr is the mono version of the sensor.
>  
> +allOf:
> +  - $ref: /schemas/media/video-interface-devices.yaml#
> +
>  properties:
>    compatible:
>      oneOf:
> @@ -101,7 +104,7 @@ required:
>    - vdddo-supply
>    - port
>  
> -additionalProperties: false
> +unevaluatedProperties: false
>  
>  examples:
>    - |

-- 
Regards,

Laurent Pinchart


From xu.yang_2 at nxp.com  Fri Feb 23 06:56:03 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Fri, 23 Feb 2024 14:56:03 +0000
Subject: [EXT] Re: [PATCH v6 4/9] dt-bindings: usb: add NXP ChipIdea USB2
 Controller schema
In-Reply-To: <20240223140256.GA1768266-robh@kernel.org>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
 <20240221145846.1611627-4-xu.yang_2@nxp.com>
 <20240223140256.GA1768266-robh@kernel.org>
Message-ID: <DU2PR04MB882234D1A9D5718D8355928B8C552@DU2PR04MB8822.eurprd04.prod.outlook.com>

Hi Rob,

>
> On Wed, Feb 21, 2024 at 10:58:41PM +0800, Xu Yang wrote:
> > As more and more NXP i.MX chips come out, it becomes harder to maintain
> > ci-hdrc-usb2.yaml if more stuffs like property restrictions are added to
> > this file. This will separate i.MX parts out of ci-hdrc-usb2.yaml and add
> > a new schema for NXP ChipIdea USB2 Controller.
> >
> > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> >
> > ---
> > Changes in v6:
> >  - new patch
> > ---
> >  .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 75 +++++++++++++++++++
> >  1 file changed, 75 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml b/Documentation/devicetree/bindings/usb/ci-
> hdrc-usb2-imx.yaml
> > new file mode 100644
> > index 000000000000..2ec62f564bf5
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
> > @@ -0,0 +1,75 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/usb/ci-hdrc-
> usb2-
> imx.yaml%23&data=05%7C02%7Cxu.yang_2%40nxp.com%7C4ac0c60cd4b4433f0f9f08dc34782572%7C686ea1d3bc2b4c6fa92c
> d99c5c301635%7C0%7C0%7C638442937830606824%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIi
> LCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=7p1DzvYmBsTgN44jypH7lc56z9hVBsFBYXUwsblk9z8%3D&reserv
> ed=0
> > +$schema: http://devicetree.org/meta-
> schemas%2Fcore.yaml%23&data=05%7C02%7Cxu.yang_2%40nxp.com%7C4ac0c60cd4b4433f0f9f08dc34782572%7C686ea1d3
> bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638442937830615622%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLC
> JQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=fWWy9enbGK5yeKiovday7go3Gss5L%2F%2Fe%2F
> OZcANny0QA%3D&reserved=0
> > +
> > +title: NXP USB2 ChipIdea USB controller
> > +
> > +maintainers:
> > +  - Xu Yang <xu.yang_2 at nxp.com>
> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - enum:
> > +          - fsl,imx27-usb
> > +      - items:
> > +          - enum:
> > +              - fsl,imx23-usb
> > +              - fsl,imx25-usb
> > +              - fsl,imx28-usb
> > +              - fsl,imx35-usb
> > +              - fsl,imx50-usb
> > +              - fsl,imx51-usb
> > +              - fsl,imx53-usb
> > +              - fsl,imx6q-usb
> > +              - fsl,imx6sl-usb
> > +              - fsl,imx6sx-usb
> > +              - fsl,imx6ul-usb
> > +              - fsl,imx7d-usb
> > +              - fsl,vf610-usb
> > +          - const: fsl,imx27-usb
> > +      - items:
> > +          - enum:
> > +              - fsl,imx8dxl-usb
> > +              - fsl,imx8ulp-usb
> > +          - const: fsl,imx7ulp-usb
> > +          - const: fsl,imx6ul-usb
> > +      - items:
> > +          - enum:
> > +              - fsl,imx8mm-usb
> > +              - fsl,imx8mn-usb
> > +          - const: fsl,imx7d-usb
> > +          - const: fsl,imx27-usb
> > +      - items:
> > +          - enum:
> > +              - fsl,imx6sll-usb
> > +              - fsl,imx7ulp-usb
> > +          - const: fsl,imx6ul-usb
> > +          - const: fsl,imx27-usb
>
> Now you just duplicated all the compatibles, and now any new compatibles
> have to be added in 2 places. For this to work, you have to split
> ci-hdrc-usb2.yaml into 2 files. One with all the common properties and
> one with compatibles (minus imx). This is also needed if imx has any
> extra properties the other don't.
>
> Didn't I say this already?
>

Yes, I know.

But according to your words, I need to split ci-hdrc-usb2.yaml into 1 common
file and more than 1 vendor specific files (imx, nvidia, qcom, nuvoton and
others). In this patchset, I only focus on imx part and KK said he or someone
will take over other parts, therefore I just duplicated all the imx compatibles.
If I only create imx specific yaml file and remove all compatilbles from common
file, nvidia, qcom, nuvoton and others compatible info will be lost, is this
feasible? Or should I create mutiple vendor specific files at the same time?

Thanks,
Xu Yang


From andriy.shevchenko at linux.intel.com  Fri Feb 23 06:59:24 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 16:59:24 +0200
Subject: [PATCH v1 02/14] serial: core: Add UPIO_UNSET constant for unset
 port type
In-Reply-To: <fa46f220-a1c4-43f4-91e1-5929ff335be0@kernel.org>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-3-andriy.shevchenko@linux.intel.com>
 <5aeee02f-45a6-48e5-a6f4-e55b76d4b959@kernel.org>
 <ZddKaaB7HO0CyldD@smile.fi.intel.com>
 <fa46f220-a1c4-43f4-91e1-5929ff335be0@kernel.org>
Message-ID: <ZdiyzKMZPlkN462G@smile.fi.intel.com>

On Fri, Feb 23, 2024 at 06:42:15AM +0100, Jiri Slaby wrote:
> On 22. 02. 24, 14:21, Andy Shevchenko wrote:
> > On Thu, Feb 22, 2024 at 07:58:32AM +0100, Jiri Slaby wrote:
> > > On 21. 02. 24, 19:31, Andy Shevchenko wrote:

...

> > > >    	unsigned char		iotype;			/* io access style */
> > > > +#define UPIO_UNSET		((unsigned char)~0U)	/* UCHAR_MAX */
> > > 
> > > Perhaps making the var u8 and this U8_MAX then? It would make more sense to
> > > me.
> > 
> > WFM, should it be a separate change?
> 
> Likely.

Then I need a commit message, because I'm unable to justify this change myself.

> > Btw, how can I justify it?
> 
> Hmm, thinking about it, why is it not an enum?

Maybe, but it is a replica of UAPI definitions, do we want to see it as a enum?
To me it will be a bit ugly looking.

> But it could be also an u8 because you want it be exactly 8 bits as you want
> to be sure values up to 255 fit.

Depends on what we assume UAPI does with those flags. It maybe even less than
8 bits, or great than, currently 8 bits is enough...

TL;DR: I would rather take a patch from you and incorporate into the series
than trying hard to invent a justification and proper type.

-- 
With Best Regards,
Andy Shevchenko




From andriy.shevchenko at linux.intel.com  Fri Feb 23 07:01:43 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 17:01:43 +0200
Subject: [PATCH v1 06/14] serial: 8250_bcm7271: Switch to use
 uart_read_port_properties()
In-Reply-To: <202402231238.AWqLyIoM-lkp@intel.com>
References: <20240221183442.4124354-7-andriy.shevchenko@linux.intel.com>
 <202402231238.AWqLyIoM-lkp@intel.com>
Message-ID: <ZdizV7sbAtCZ4AyO@smile.fi.intel.com>

On Fri, Feb 23, 2024 at 12:14:38PM +0800, kernel test robot wrote:
> Hi Andy,
> 
> kernel test robot noticed the following build warnings:

> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp at intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202402231238.AWqLyIoM-lkp at intel.com/
> 
> All warnings (new ones prefixed by >>):
> 

>    In file included from arch/hexagon/include/asm/io.h:328:
>    include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>      547 |         val = __raw_readb(PCI_IOBASE + addr);
>          |                           ~~~~~~~~~~ ^

Okay, the above is well known issue with hexagon arch, not related to the series.

> >> drivers/tty/serial/8250/8250_bcm7271.c:938:22: warning: unused variable 'np' [-Wunused-variable]
>      938 |         struct device_node *np = pdev->dev.of_node;
>          |                             ^~

This one is a good catch! Will be fixed in a new version.

-- 
With Best Regards,
Andy Shevchenko




From andriy.shevchenko at linux.intel.com  Fri Feb 23 07:02:29 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 17:02:29 +0200
Subject: [PATCH v1 10/14] serial: 8250_of: Switch to use
 uart_read_port_properties()
In-Reply-To: <ad91eec0-39da-4b9c-8da7-f1e98bb4565b@broadcom.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
 <20240221183442.4124354-11-andriy.shevchenko@linux.intel.com>
 <0a828f2c50de712940fb9a881702ac1678a35b7c.camel@codeconstruct.com.au>
 <ZddKzHplwOX7naLv@smile.fi.intel.com>
 <Zdd5m2xIPlGI0_Qv@smile.fi.intel.com>
 <Zdd6lnXwvpPPUhRR@smile.fi.intel.com>
 <e5fd9d8b-84eb-4ef9-82ab-ff4ecc41c0d5@broadcom.com>
 <ad91eec0-39da-4b9c-8da7-f1e98bb4565b@broadcom.com>
Message-ID: <ZdizhVPfwFp72ioI@smile.fi.intel.com>

On Thu, Feb 22, 2024 at 11:54:46AM -0800, Florian Fainelli wrote:
> On 2/22/24 09:39, Florian Fainelli wrote:
> > On 2/22/24 08:47, Andy Shevchenko wrote:

...

> > Thanks, on 8250_bcm7271.c with the above hunk applied, I did not spot
> > any differences between the values returned by stty or a cat
> > /sys/class/tty/ttyS0/* before or after, the console remained fully
> > functional. I will see if I can run an additional test where I removed
> > the DT's "clocks" property and confirm that the fall back to
> > "clock-frequency" works.
> 
> Also appears to work properly on a Raspberry Pi 4 with the console using the
> bcm2835-aux driver, will provide Tested-by tags on the next submission,
> thanks!

Thank you for prompt testing on real HW!

-- 
With Best Regards,
Andy Shevchenko




From jgg at nvidia.com  Fri Feb 23 07:18:41 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 23 Feb 2024 11:18:41 -0400
Subject: [PATCH v5 01/17] iommu/arm-smmu-v3: Make STE programming
 independent of the callers
In-Reply-To: <20240222174346.GB9488@willie-the-truck>
References: <0-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <1-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <20240215134952.GA690@willie-the-truck>
 <20240215160135.GL1088888@nvidia.com>
 <20240221134923.GA7362@willie-the-truck>
 <20240221140818.GA2635804@nvidia.com>
 <20240222174346.GB9488@willie-the-truck>
Message-ID: <20240223151841.GH13330@nvidia.com>

On Thu, Feb 22, 2024 at 05:43:46PM +0000, Will Deacon wrote:
> On Wed, Feb 21, 2024 at 10:08:18AM -0400, Jason Gunthorpe wrote:
> > On Wed, Feb 21, 2024 at 01:49:23PM +0000, Will Deacon wrote:
> > 
> > > Very roughly, yes, although I'd go further and just return a bitmap of
> > > used qwords instead of tracking these bits. Basically, we could have some
> > > #defines saying which qwords are used by which configs, 
> > 
> > I don't think this will work well for CD's EPD0 case..
> > 
> > static void arm_smmu_get_cd_used(const __le64 *ent, __le64 *used_bits)
> > {
> > 	used_bits[0] = cpu_to_le64(CTXDESC_CD_0_V);
> > 	if (!(ent[0] & cpu_to_le64(CTXDESC_CD_0_V)))
> > 		return;
> > 	memset(used_bits, 0xFF, sizeof(struct arm_smmu_cd));
> > 
> > 	/* EPD0 means T0SZ/TG0/IR0/OR0/SH0/TTB0 are IGNORED */
> > 	if (ent[0] & cpu_to_le64(CTXDESC_CD_0_TCR_EPD0)) {
> > 		used_bits[0] &= ~cpu_to_le64(
> > 			CTXDESC_CD_0_TCR_T0SZ | CTXDESC_CD_0_TCR_TG0 |
> > 			CTXDESC_CD_0_TCR_IRGN0 | CTXDESC_CD_0_TCR_ORGN0 |
> > 			CTXDESC_CD_0_TCR_SH0);
> > 		used_bits[1] &= ~cpu_to_le64(CTXDESC_CD_1_TTB0_MASK);
> > 	}
> > }
> 
> Please can you explain more about the issue here? I know what EPDx are,
> but I'm not understanding why they're problematic. This presumably
> involves a hitless transition to/from an aborting CD?

When a process using SVA exits uncleanly the MM is released so the
SMMU HW must stop chasing the page table pointers since all that
memory will be freed.

However, in an unclean exit we can't control the order of shutdown so
something like uacce or RDMA may not have quieted the DMA device yet.

So there is a period during shutdown where the mm has been released
and the device is doing DMA, the desire is that the DMA continue to be
handled as a PRI and the SW will return failure for all PRI requests.

Specifically we do not want to trigger any dmesg log events during
this condition.

Jean-Philippe came up with this solution where we hitlessly use EPD0
in release to allow the mm to release the page table while continuing
to use the PRI flow.

So it is going from a "SVA domain with a page table" to a "SVA domain
without a page table but EPD0 set", hitlessly.


> I'm just trying to avoid introducing dynamic behaviours to the driver
> which aren't actually used, and per-qword tracking feels like an easier
> way to maintain the hitless updates for the cases you care about. It's
> really not about throwing away the entire logic of the design -- as I
> said, I think this is looking pretty good. I'm also absolutely open to
> being convinced that per-field makes more sense and per-qword is terrible,
> so I'd really like to understand the E0PD case more.

It is not more sense/terrible, it is more that we have to make some
trade offs. I outlined what I think would be needed to make per-qw
work in the other email:

 - get_used becomes harder to explain but shorter (we ignore the used
   qw 1 for bypass/abort)
 - arm_smmu_entry_qword_diff becomes a bit simpler, less bitwise logic,
   no unused_update
 - arm_smmu_write_entry() has the same logic but unused_update is
   replaced by target
 - We have to hack something to make SHCFG=1 - change the make
   functions or have arm_smmu_write_ste() force SHCFG=1.
 - We have to write a seperate programming logic for CD -
   always do V=0/1 for normal updates, and a special EPD0 flow.

I think it is worse over all because none of those trade offs really
make the code clearer, and I dislike the idea of open coding
CD. Especially now that we have a test suite that requires the ops
anyhow.

It is a minor decision, trust Michael and I make this choice, we both
agree now and have spent alot of time studying this.

> As an aside: is this per-field/per-qword discussion the only thing holding
> up a v6?

As far as I know, yes. I have not typed in every feedback yet, but I
hope to get that done today. I will try to post it by Monday so we can
see what it looks like with Robin's suggestion but without per-qw.

> With the rest of the feedback addressed and a version of Michael's
> selftest that exercises stage-2 translating domains, I'd like to
> think we could get it queued up soon.

I would really like this, we have so many more patches to work on, you
probably saw the HTTU stuff was re posted again, we have a clean full
BTM enablement now on the list for the first time, nesting patches,
and more. Including this, I'm tracking a work list of about 100-150
patches for SMMUv3 in the next little bit.

This is not unique to SMMUv3, AMD is on part 6 of work for their
driver, and Intel has been pushing ~10-20 patches/cycle pretty
reliably. iommufd has opened the door to actually solving alot of the
stuck problems and everyone is rushing to complete their previously
stalled HW enablement. I have to review and help design all of this
work too! :)

BTW Michael's self test won't be in part 1 because it needs the ops to
be restored in order to work (now done in part 2), and has a few other
more minor dependencies on part 2 and 3.

Thanks,
Jason


From lee at kernel.org  Fri Feb 23 07:20:00 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 15:20:00 +0000
Subject: [PATCH v2 0/6] mfd: tmio: simplify header and move to
 platform_data
In-Reply-To: <20240213220221.2380-8-wsa+renesas@sang-engineering.com>
References: <20240213220221.2380-8-wsa+renesas@sang-engineering.com>
Message-ID: <170870160052.1698319.4712751560931025638.b4-ty@kernel.org>

On Tue, 13 Feb 2024 23:02:19 +0100, Wolfram Sang wrote:
> Changes since v1:
> 
> * rebased to rc4
> * collected all needed acks (Thanks!)
> * capitalized first letter in commit subject
> 
> The MFD parts of the TMIO have been removed by Arnd, so that only the
> SD/MMC related functionality is left. Remove the outdated remains in the
> public header file and then move it to platform_data as the data is now
> specific for the SD/MMC part.
> 
> [...]

Applied, thanks!

[1/6] mfd: tmio: Remove obsolete platform_data
      commit: 58d6d15662e4039fab7d786f0426843befa77ad4
[2/6] mfd: tmio: Remove obsolete io accessors
      commit: e927d7bac109d8ca1729dda47a8dbc220efdb50e
[3/6] mmc: tmio/sdhi: Fix includes
      commit: bed05c68aa8f078206143700cd37e42a0084155f
[4/6] mfd: tmio: Update include files
      commit: 3ef94c41db82573dc1e1dd6c259aec8ef6caaaf3
[5/6] mfd: tmio: Sanitize comments
      commit: 2d417dda59123b9523a19ce75fea3fd1056c3b4c
[6/6] mfd: tmio: Move header to platform_data
      commit: 858b29729c9d319b9cd1441646cc3af246d3c3f9

--
Lee Jones [???]



From aren at peacevolution.org  Fri Feb 23 07:22:36 2024
From: aren at peacevolution.org (Aren)
Date: Fri, 23 Feb 2024 10:22:36 -0500
Subject: [PATCH v2 3/4] arm64: dts: sun50i-a64-pinephone: add multicolor
 led node
In-Reply-To: <sixgkkllo7medcjwjnmbkpqkgfvnmrtlhlwarwuxid5oqwrht5@gl65b6fetq2b>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <20240206185400.596979-3-aren@peacevolution.org>
 <sixgkkllo7medcjwjnmbkpqkgfvnmrtlhlwarwuxid5oqwrht5@gl65b6fetq2b>
Message-ID: <5hqfabcolgqcu22hs3xnaimojwuz26tzi63px3rvbsgxa6kjss@ik42w7k26see>

On Fri, Feb 23, 2024 at 09:46:25AM +0100, Ond?ej Jirman wrote:
> Hello Aren,
> 
> On Tue, Feb 06, 2024 at 01:13:19PM -0500, Aren Moynihan wrote:
> > The red, green, and blue leds currently in the device tree represent a
> > single rgb led on the front of the PinePhone.
> > 
> > Signed-off-by: Aren Moynihan <aren at peacevolution.org>
> > ---
> > 
> > Changes in v2:
> >  - remove function property from individual led nodes
> > 
> >  .../boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 16 ++++++++++------
> >  1 file changed, 10 insertions(+), 6 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > index ad2476ee01e4..e53e0d4579a7 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > @@ -39,28 +39,32 @@ chosen {
> >  	leds {
> >  		compatible = "gpio-leds";
> >  
> > -		led-0 {
> > -			function = LED_FUNCTION_INDICATOR;
> 
> This looks like a needless change that will just break people's current scripts
> and setup. It does mine, and there sure are others that will be surprised, too.
> 
> This leads to a change in sysfs path from:
> 
>   /sys/class/leds/blue:indicator
> 
> to
> 
>   /sys/class/leds/blue:
> 
> which is 1) a weird name and 2) a backwards compatibility break for seemingly
> no apparent reason. Any reaons for the change?

Leds-group-multicolor will make those read-only, so that will break when
it's enabled either way. Removing the function property makes it less
likely that programs attempting to discover leds will use the wrong
path.

I left these in v1 of this patch, but was recommended to remove them.
https://lore.kernel.org/lkml/k26bellccok4tj3kz2nrtp2vth2rnsiea677e2kzm56m767wjx at pnkqiz5hmiyb/

Thanks for taking a look at this
 - Aren

> People normally hardcode these paths in eg. /etc/tmpfiles.d to apply LED triggers
> to particular LEDs.
> 
> Kind regards,
> 	o.
> 
> > +		led0: led-0 {
> >  			color = <LED_COLOR_ID_BLUE>;
> >  			gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */
> >  			retain-state-suspended;
> >  		};
> >  
> > -		led-1 {
> > -			function = LED_FUNCTION_INDICATOR;
> > +		led1: led-1 {
> >  			color = <LED_COLOR_ID_GREEN>;
> >  			gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */
> >  			retain-state-suspended;
> >  		};
> >  
> > -		led-2 {
> > -			function = LED_FUNCTION_INDICATOR;
> > +		led2: led-2 {
> >  			color = <LED_COLOR_ID_RED>;
> >  			gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */
> >  			retain-state-suspended;
> >  		};
> >  	};
> >  
> > +	multi-led {
> > +		compatible = "leds-group-multicolor";
> > +		color = <LED_COLOR_ID_RGB>;
> > +		function = LED_FUNCTION_INDICATOR;
> > +		leds = <&led0>, <&led1>, <&led2>;
> > +	};
> > +
> >  	reg_ps: ps-regulator {
> >  		compatible = "regulator-fixed";
> >  		regulator-name = "ps";
> > -- 
> > 2.43.0
> > 


From lpieralisi at kernel.org  Fri Feb 23 07:23:24 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Fri, 23 Feb 2024 16:23:24 +0100
Subject: [PATCH v11 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <20240220161924.3871774-1-Frank.Li@nxp.com>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
Message-ID: <170870177640.190909.13423263048571416476.b4-ty@kernel.org>

On Tue, 20 Feb 2024 11:19:10 -0500, Frank Li wrote:
> first 6 patches use drvdata: flags to simplify some switch-case code.
> Improve maintaince and easy to read code.
> 
> Then add imx95 basic pci host function.
> 
> follow two patch do endpoint code clean up.
> Then add imx95 basic endpont function.
> 
> [...]

Applied to enumeration, thanks!

[01/14] PCI: imx6: Simplify clock handling by using clk_bulk*() function
        https://git.kernel.org/pci/pci/c/6a4018583875
[02/14] PCI: imx6: Simplify phy handling by using IMX6_PCIE_FLAG_HAS_PHYDRV
        https://git.kernel.org/pci/pci/c/4e37c2f48712
[03/14] PCI: imx6: Simplify reset handling by using by using *_FLAG_HAS_*_RESET
        https://git.kernel.org/pci/pci/c/666a7beb942c
[04/14] PCI: imx6: Simplify ltssm_enable() by using ltssm_off and ltssm_mask
        https://git.kernel.org/pci/pci/c/cb7b0cd26d3a
[05/14] PCI: imx6: Simplify configure_type() by using mode_off and mode_mask
        https://git.kernel.org/pci/pci/c/e35c3c580740
[06/14] PCI: imx6: Simplify switch-case logic by involve init_phy callback
        https://git.kernel.org/pci/pci/c/a6afefd72856
[07/14] dt-bindings: imx6q-pcie: Clean up irrationality clocks check
        https://git.kernel.org/pci/pci/c/0aa0c28fd259
[08/14] dt-bindings: imx6q-pcie: Restruct reg and reg-name
        https://git.kernel.org/pci/pci/c/0efd53a842c8
[09/14] dt-bindings: imx6q-pcie: Add imx95 pcie compatible string
        https://git.kernel.org/pci/pci/c/41b116c2cf24
[10/14] PCI: imx6: Add iMX95 PCIe Root Complex support
        https://git.kernel.org/pci/pci/c/98e97fb574b1
[11/14] PCI: imx6: Clean up get addr_space code
        https://git.kernel.org/pci/pci/c/b16b852e3175
[12/14] PCI: imx6: Add epc_features in imx6_pcie_drvdata
        https://git.kernel.org/pci/pci/c/e2f2029ddf3f
[13/14] dt-bindings: imx6q-pcie: Add iMX95 pcie endpoint compatible string
        https://git.kernel.org/pci/pci/c/4d80ef68c2c7
[14/14] PCI: imx6: Add iMX95 Endpoint (EP) support
        https://git.kernel.org/pci/pci/c/b73259dcd670

Thanks,
Lorenzo


From lpieralisi at kernel.org  Fri Feb 23 07:30:18 2024
From: lpieralisi at kernel.org (Lorenzo Pieralisi)
Date: Fri, 23 Feb 2024 16:30:18 +0100
Subject: [PATCH v11 00/14] PCI: imx6: Clean up and add imx95 pci support
In-Reply-To: <170870177640.190909.13423263048571416476.b4-ty@kernel.org>
References: <20240220161924.3871774-1-Frank.Li@nxp.com>
 <170870177640.190909.13423263048571416476.b4-ty@kernel.org>
Message-ID: <Zdi6CqmNjKfSWCXj@lpieralisi>

On Fri, Feb 23, 2024 at 04:23:24PM +0100, Lorenzo Pieralisi wrote:
> On Tue, 20 Feb 2024 11:19:10 -0500, Frank Li wrote:
> > first 6 patches use drvdata: flags to simplify some switch-case code.
> > Improve maintaince and easy to read code.
> > 
> > Then add imx95 basic pci host function.
> > 
> > follow two patch do endpoint code clean up.
> > Then add imx95 basic endpont function.
> > 
> > [...]
> 
> Applied to enumeration, thanks!

Sorry, scripting messed it up, it is the controller/imx branch.

Thanks,
Lorenzo


From aren at peacevolution.org  Fri Feb 23 07:32:34 2024
From: aren at peacevolution.org (Aren)
Date: Fri, 23 Feb 2024 10:32:34 -0500
Subject: (subset) [PATCH v2 1/4] leds: rgb: leds-group-multicolor: allow
 leds to stay on in suspend
In-Reply-To: <20240223103537.GA1585387@google.com>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <170868429025.1582603.10651778411484887304.b4-ty@kernel.org>
 <20240223103537.GA1585387@google.com>
Message-ID: <hjug4ilzxvtf7in64zw4jcjudzknqh2onvicd5cjuc3e47nl4w@3uiabmqehx5n>

On Fri, Feb 23, 2024 at 10:35:37AM +0000, Lee Jones wrote:
> On Fri, 23 Feb 2024, Lee Jones wrote:
> 
> > On Tue, 06 Feb 2024 13:13:17 -0500, Aren Moynihan wrote:
> > > If none of the managed leds enable LED_CORE_SUSPENDRESUME, then we
> > > shouldn't need to set it here. This makes it possible to use multicolor
> > > groups with gpio leds that enable retain-state-suspended in the device
> > > tree.
> > > 
> > > 
> > 
> > Applied, thanks!
> > 
> > [1/4] leds: rgb: leds-group-multicolor: allow leds to stay on in suspend
> >       commit: 68552911e71d59e62dd5e50e9ac56ebfc32f0c71
> 
> Note that I changed a bunch of grammatical issues.
> 
> led  => LED
> gpio => GPIO
> 
> Capitalised the first word of the comment, etc.

Awesome, thank you
 - Aren

> -- 
> Lee Jones [???]


From joro at 8bytes.org  Fri Feb 23 07:44:33 2024
From: joro at 8bytes.org (Joerg Roedel)
Date: Fri, 23 Feb 2024 16:44:33 +0100
Subject: [GIT PULL] iommu/arm-smmu: Fixes for 6.8-rc
In-Reply-To: <20240223115043.GA10608@willie-the-truck>
References: <20240223115043.GA10608@willie-the-truck>
Message-ID: <Zdi9YcGDlXskO_hO@8bytes.org>

On Fri, Feb 23, 2024 at 11:50:43AM +0000, Will Deacon wrote:
>   git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git tags/arm-smmu-fixes

Pulled, thanks Will.


From kees at kernel.org  Fri Feb 23 07:46:40 2024
From: kees at kernel.org (Kees Cook)
Date: Fri, 23 Feb 2024 07:46:40 -0800
Subject: =?US-ASCII?Q?Re=3A_=5Blinux-next=3Amaster=5D_BUILD_REGRESSION?= =?US-ASCII?Q?_e31185ce00a96232308300008db193416ceb9769?=
In-Reply-To: <202402231222.DVB9DC74-lkp@intel.com>
References: <202402231222.DVB9DC74-lkp@intel.com>
Message-ID: <3532AACB-176A-4C48-9855-CCD6C97FDE91@kernel.org>



On February 22, 2024 8:29:28 PM PST, kernel test robot <lkp at intel.com> wrote:
>tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
>branch HEAD: e31185ce00a96232308300008db193416ceb9769  Add linux-next specific files for 20240222
>
>Error/Warning reports:
>
>https://lore.kernel.org/oe-kbuild-all/202402222223.h9rFmYj4-lkp at intel.com
>https://lore.kernel.org/oe-kbuild-all/202402222314.J6A7eb4B-lkp at intel.com
>https://lore.kernel.org/oe-kbuild-all/202402230537.2s6Nhfsn-lkp at intel.com
>
>Error/Warning: (recently discovered and may have been fixed)
>
>arch/arm/boot/compressed/misc.c:157:6: warning: no previous prototype for function '__fortify_panic' [-Wmissing-prototypes]
>arch/arm/boot/compressed/misc.h:13:36: error: macro "fortify_panic" requires 2 arguments, but only 1 given

This is fixed for the subsequent -next tree.

>arch/sh/boot/compressed/../../../../lib/decompress_unxz.c:350:(.text+0x20b4): undefined reference to `__ubsan_handle_out_of_bounds'
>sh4-linux-ld: arch/sh/boot/compressed/../../../../lib/xz/xz_dec_lzma2.c:751:(.text+0x904): undefined reference to `__ubsan_handle_out_of_bounds'

This is fixed here and is waiting to land:
https://lore.kernel.org/linux-hardening/20240130232717.work.088-kees at kernel.org/

-Kees

-- 
Kees Cook


From andriy.shevchenko at linux.intel.com  Fri Feb 23 07:48:18 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 17:48:18 +0200
Subject: [PATCH] clkdev: Update clkdev id usage to allow for longer names
In-Reply-To: <20240223141857.3794855-1-michael.j.ruhl@intel.com>
References: <20240223141857.3794855-1-michael.j.ruhl@intel.com>
Message-ID: <Zdi-QnkPYUFWLJIe@smile.fi.intel.com>

On Fri, Feb 23, 2024 at 09:18:14AM -0500, Michael J. Ruhl wrote:
> clkdev ID information is limited to arrays of 20 and 16 bytes
> (MAX_DEV_ID/MAX_CON_ID).  It is possible that the IDs could be
> longer that.  If so, the lookup will fail because the "real ID"
> will not match the copied value.

Perhaps you need to add a real example.

> Increase the size of the IDs to allow for longer names.

...

> -#define MAX_DEV_ID	20
> -#define MAX_CON_ID	16
> +#define MAX_DEV_ID	32
> +#define MAX_CON_ID	32

Do we need to alter both?

-- 
With Best Regards,
Andy Shevchenko




From ptyadav at amazon.de  Fri Feb 23 07:53:25 2024
From: ptyadav at amazon.de (Pratyush Yadav)
Date: Fri, 23 Feb 2024 16:53:25 +0100
Subject: [PATCH v3 02/17] memblock: Declare scratch memory as CMA
In-Reply-To: <20240117144704.602-3-graf@amazon.com> (Alexander Graf's message
	of "Wed, 17 Jan 2024 14:46:49 +0000")
References: <20240117144704.602-1-graf@amazon.com>
	<20240117144704.602-3-graf@amazon.com>
Message-ID: <mafs0r0h36utm.fsf@amazon.de>

Hi,

On Wed, Jan 17 2024, Alexander Graf wrote:

> When we finish populating our memory, we don't want to lose the scratch
> region as memory we can use for useful data. Do do that, we mark it as
> CMA memory. That means that any allocation within it only happens with
> movable memory which we can then happily discard for the next kexec.
>
> That way we don't lose the scratch region's memory anymore for
> allocations after boot.
>
> Signed-off-by: Alexander Graf <graf at amazon.com>
>
[...]
> @@ -2188,6 +2185,16 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end)
>  	}
>  }
>  
> +static void mark_phys_as_cma(phys_addr_t start, phys_addr_t end)
> +{
> +	ulong start_pfn = pageblock_start_pfn(PFN_DOWN(start));
> +	ulong end_pfn = pageblock_align(PFN_UP(end));
> +	ulong pfn;
> +
> +	for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages)
> +		set_pageblock_migratetype(pfn_to_page(pfn), MIGRATE_CMA);

This fails to compile if CONFIG_CMA is disabled. I think you should add
it as a dependency for CONFIG_MEMBLOCK_SCRATCH.

> +}
> +
>  static unsigned long __init __free_memory_core(phys_addr_t start,
>  				 phys_addr_t end)
>  {
> @@ -2249,6 +2256,17 @@ static unsigned long __init free_low_memory_core_early(void)
>  
>  	memmap_init_reserved_pages();
>  
> +	if (IS_ENABLED(CONFIG_MEMBLOCK_SCRATCH)) {
> +		/*
> +		 * Mark scratch mem as CMA before we return it. That way we
> +		 * ensure that no kernel allocations happen on it. That means
> +		 * we can reuse it as scratch memory again later.
> +		 */
> +		__for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE,
> +				     MEMBLOCK_SCRATCH, &start, &end, NULL)
> +			mark_phys_as_cma(start, end);
> +	}
> +
>  	/*
>  	 * We need to use NUMA_NO_NODE instead of NODE_DATA(0)->node_id
>  	 *  because in some case like Node0 doesn't have RAM installed

-- 
Regards,
Pratyush Yadav



Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879





From cristian.marussi at arm.com  Fri Feb 23 07:56:30 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Fri, 23 Feb 2024 15:56:30 +0000
Subject: [PATCH 3/5] firmware: arm_scmi: add initial support for i.MX
 MISC protocol
In-Reply-To: <20240202-imx95-bbm-misc-v1-3-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
 <20240202-imx95-bbm-misc-v1-3-3cb743020933@nxp.com>
Message-ID: <ZdjALicBK4XB89b9@pluto>

On Fri, Feb 02, 2024 at 02:34:41PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> The i.MX MISC protocol is for misc settings, such as gpio expander
> wakeup.
> 

Hi,

> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/firmware/arm_scmi/Kconfig       |  10 ++
>  drivers/firmware/arm_scmi/Makefile      |   1 +
>  drivers/firmware/arm_scmi/imx-sm-misc.c | 289 ++++++++++++++++++++++++++++++++
>  include/linux/scmi_nxp_protocol.h       |  17 ++
>  4 files changed, 317 insertions(+)
> 
> diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
> index 56d11c9d9f47..bfeae92f6420 100644
> --- a/drivers/firmware/arm_scmi/Kconfig
> +++ b/drivers/firmware/arm_scmi/Kconfig
> @@ -191,3 +191,13 @@ config IMX_SCMI_BBM_EXT
>  	  and BUTTON.
>  
>  	  This driver can also be built as a module.
> +
> +config IMX_SCMI_MISC_EXT
> +	tristate "i.MX SCMI MISC EXTENSION"
> +	depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF)
> +	default y if ARCH_MXC
> +	help
> +	  This enables i.MX System MISC control logic such as gpio expander
> +	  wakeup
> +
> +	  This driver can also be built as a module.
> diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
> index 327687acf857..a23fde721222 100644
> --- a/drivers/firmware/arm_scmi/Makefile
> +++ b/drivers/firmware/arm_scmi/Makefile
> @@ -12,6 +12,7 @@ scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
>  scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
>  scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o powercap.o
>  scmi-protocols-$(CONFIG_IMX_SCMI_BBM_EXT) += imx-sm-bbm.o
> +scmi-protocols-$(CONFIG_IMX_SCMI_MISC_EXT) += imx-sm-misc.o
>  scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
>  
>  obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
> diff --git a/drivers/firmware/arm_scmi/imx-sm-misc.c b/drivers/firmware/arm_scmi/imx-sm-misc.c
> new file mode 100644
> index 000000000000..7805d41cca4d
> --- /dev/null
> +++ b/drivers/firmware/arm_scmi/imx-sm-misc.c
> @@ -0,0 +1,289 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * System control and Management Interface (SCMI) NXP MISC Protocol
> + *
> + * Copyright 2024 NXP
> + */
> +
> +#define pr_fmt(fmt) "SCMI Notifications MISC - " fmt
> +
> +#include <linux/bits.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/scmi_protocol.h>
> +#include <linux/scmi_nxp_protocol.h>
> +
> +#include "protocols.h"
> +#include "notify.h"
> +
> +#define SCMI_PROTOCOL_SUPPORTED_VERSION		0x0
> +

Same considerations on this 0-versioning as in previous patch.

> +enum scmi_imx_misc_protocol_cmd {
> +	SCMI_IMX_MISC_CTRL_SET	= 0x3,
> +	SCMI_IMX_MISC_CTRL_GET	= 0x4,
> +	SCMI_IMX_MISC_CTRL_NOTIFY = 0x8,
> +};
> +
> +struct scmi_imx_misc_info {
> +	u32 version;
> +	u32 nr_ctrl;
> +	u32 nr_reason;
> +};
> +
> +struct scmi_msg_imx_misc_protocol_attributes {
> +	__le32 attributes;
> +};
> +
> +#define GET_REASONS_NR(x)	le32_get_bits((x), GENMASK(23, 16))
> +#define GET_CTRLS_NR(x)		le32_get_bits((x), GENMASK(15, 0))
> +

Please lineup this tabs

> +struct scmi_imx_misc_ctrl_set_in {
> +	__le32 id;
> +	__le32 num;
> +	__le32 value[MISC_MAX_VAL];
> +};
> +
> +struct scmi_imx_misc_ctrl_notify_in {
> +	__le32 ctrl_id;
> +	__le32 flags;
> +};
> +
> +struct scmi_imx_misc_ctrl_notify_payld {
> +	__le32 ctrl_id;
> +	__le32 flags;
> +};
> +
> +struct scmi_imx_misc_ctrl_get_out {
> +	__le32 num;
> +	__le32 val[MISC_MAX_VAL];
> +};
> +
> +static int scmi_imx_misc_attributes_get(const struct scmi_protocol_handle *ph,
> +					struct scmi_imx_misc_info *mi)
> +{
> +	int ret;
> +	struct scmi_xfer *t;
> +	struct scmi_msg_imx_misc_protocol_attributes *attr;
> +
> +	ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0,
> +				      sizeof(*attr), &t);
> +	if (ret)
> +		return ret;
> +
> +	attr = t->rx.buf;
> +
> +	ret = ph->xops->do_xfer(ph, t);
> +	if (!ret) {
> +		mi->nr_ctrl = GET_CTRLS_NR(attr->attributes);
> +		mi->nr_reason = GET_REASONS_NR(attr->attributes);
> +		dev_info(ph->dev, "i.MX MISC NUM CTRL: %d, NUM Reason: %d\n",
> +			 mi->nr_ctrl, mi->nr_reason);
> +	}
> +
> +	ph->xops->xfer_put(ph, t);
> +
> +	return ret;
> +}
> +
> +static int scmi_imx_misc_ctrl_notify(const struct scmi_protocol_handle *ph,
> +				     u32 ctrl_id, u32 flags)
> +{
> +	struct scmi_imx_misc_info *mi = ph->get_priv(ph);
> +	struct scmi_imx_misc_ctrl_notify_in *in;
> +	struct scmi_xfer *t;
> +	int ret;
> +
> +	if (ctrl_id >= mi->nr_ctrl)
> +		return -EINVAL;
> +
> +	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_CTRL_NOTIFY,
> +				      sizeof(*in), 0, &t);
> +	if (ret)
> +		return ret;
> +
> +	in = t->tx.buf;
> +	in->ctrl_id = cpu_to_le32(ctrl_id);
> +	in->flags = cpu_to_le32(flags);

so this is an evt_id I see below...maybe calling this param or event
instead of flags is less misleading....I would not expect to see endian
handling on a bitfield (and flags suggests just that to me...

> +
> +	ret = ph->xops->do_xfer(ph, t);
> +
> +	ph->xops->xfer_put(ph, t);
> +
> +	return ret;
> +}
> +
> +static int
> +scmi_imx_misc_ctrl_set_notify_enabled(const struct scmi_protocol_handle *ph,
> +				      u8 evt_id, u32 src_id, bool enable)
> +{
> +	int ret;
> +
> +	ret = scmi_imx_misc_ctrl_notify(ph, src_id, enable ? evt_id : 0);
> +	if (ret) {

No need for braces here. Please run checkpatch --strict on your next
series.

> +		dev_err(ph->dev, "FAIL_ENABLED - evt[%X] src[%d] - ret:%d\n",
> +			evt_id, src_id, ret);
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +scmi_imx_misc_ctrl_get_num_sources(const struct scmi_protocol_handle *ph)
> +{
> +	struct scmi_imx_misc_info *mi = ph->get_priv(ph);
> +
> +	return mi->nr_ctrl;
> +}
> +
> +static void *
> +scmi_imx_misc_ctrl_fill_custom_report(const struct scmi_protocol_handle *ph,
> +				      u8 evt_id, ktime_t timestamp,
> +				      const void *payld, size_t payld_sz,
> +				      void *report, u32 *src_id)
> +{
> +	const struct scmi_imx_misc_ctrl_notify_payld *p = payld;
> +	struct scmi_imx_misc_ctrl_notify_report *r = report;
> +
> +	if (sizeof(*p) != payld_sz)
> +		return NULL;
> +
> +	r->timestamp = timestamp;
> +	r->ctrl_id = p->ctrl_id;
> +	r->flags = p->flags;

Here you DO need instead endian-helpers when you access the payload p->
A static analyzer like smatch will have spotted this.

> +	if (src_id)

src_id param is assured to be non-NULL here...not neeed to check...as
you did not check in BBM module indeed...

> +		*src_id = r->ctrl_id;
> +	dev_dbg(ph->dev, "%s: ctrl_id: %d flags: %d\n", __func__, r->ctrl_id, r->flags);
> +
> +	return r;
> +}
> +
> +static const struct scmi_event_ops scmi_imx_misc_event_ops = {
> +	.get_num_sources = scmi_imx_misc_ctrl_get_num_sources,
> +	.set_notify_enabled = scmi_imx_misc_ctrl_set_notify_enabled,
> +	.fill_custom_report = scmi_imx_misc_ctrl_fill_custom_report,
> +};
> +
> +static const struct scmi_event scmi_imx_misc_events[] = {
> +	{
> +		.id = SCMI_EVENT_IMX_MISC_CONTROL_DISABLED,
> +		.max_payld_sz = sizeof(struct scmi_imx_misc_ctrl_notify_payld),
> +		.max_report_sz = sizeof(struct scmi_imx_misc_ctrl_notify_report),
> +	},
> +	{
> +		.id = SCMI_EVENT_IMX_MISC_CONTROL_FALLING_EDGE,
> +		.max_payld_sz = sizeof(struct scmi_imx_misc_ctrl_notify_payld),
> +		.max_report_sz = sizeof(struct scmi_imx_misc_ctrl_notify_report),
> +	},
> +	{
> +		.id = SCMI_EVENT_IMX_MISC_CONTROL_RISING_EDGE,
> +		.max_payld_sz = sizeof(struct scmi_imx_misc_ctrl_notify_payld),
> +		.max_report_sz = sizeof(struct scmi_imx_misc_ctrl_notify_report),
> +	}
> +};
> +
> +static struct scmi_protocol_events scmi_imx_misc_protocol_events = {
> +	.queue_sz = SCMI_PROTO_QUEUE_SZ,
> +	.ops = &scmi_imx_misc_event_ops,
> +	.evts = scmi_imx_misc_events,
> +	.num_events = ARRAY_SIZE(scmi_imx_misc_events),
> +};
> +
> +static int scmi_imx_misc_protocol_init(const struct scmi_protocol_handle *ph)
> +{
> +	struct scmi_imx_misc_info *minfo;
> +	u32 version;
> +	int ret;
> +
> +	ret = ph->xops->version_get(ph, &version);
> +	if (ret)
> +		return ret;
> +
> +	dev_info(ph->dev, "NXP SM MISC Version %d.%d\n",
> +		 PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
> +
> +	minfo = devm_kzalloc(ph->dev, sizeof(*minfo), GFP_KERNEL);
> +	if (!minfo)
> +		return -ENOMEM;
> +
> +	ret = scmi_imx_misc_attributes_get(ph, minfo);
> +	if (ret)
> +		return ret;
> +
> +	return ph->set_priv(ph, minfo, version);
> +}
> +
> +static int scmi_imx_misc_ctrl_get(const struct scmi_protocol_handle *ph,
> +				  u32 ctrl_id, u32 *num, u32 *val)
> +{

Does *num here contains val[] max size on input and number of elements
filled into val[] on output ? I assume so down below

> +	struct scmi_imx_misc_info *mi = ph->get_priv(ph);
> +	struct scmi_imx_misc_ctrl_get_out *out;
> +	struct scmi_xfer *t;
> +	int ret, i;
> +
> +	if (ctrl_id >= mi->nr_ctrl)
> +		return -EINVAL;
> +
> +	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_CTRL_GET, sizeof(u32),
> +				      sizeof(*out), &t);

This *out size you require is really capped by the max transport size...so this
could fail depending on the transport...just be aware of this...not saying is bad
by itself...an alternative would be to define value inside the struct as 

  __le32 *value;

and here ask for an rx_size of 0 instead of sizeof(*out) so that you get
max transport payload size....then you will have to check if the
returned payload is as long as expected by the caller though...up 2 you really

> +	if (ret)
> +		return ret;
> +
> +	put_unaligned_le32(ctrl_id, t->tx.buf);
> +	ret = ph->xops->do_xfer(ph, t);
> +	if (!ret) {
> +		out = t->rx.buf;
> +		*num = le32_to_cpu(out->num);

out->num MUST be smaller than the original *num passed as input to fit
into *val...please check this before overwriting *num and bail out on overflow...

...moreover...out->val[] size is statically defined as MISC_MAX_VAL and
if you get here you know that you have enough space in t->rx.buf BUT you will
have also to check that the returned out->num is < MISC_MAX_VAL to avoid any
possible overflow while reading the payload if the value provided by fw
is bogus...

> +		for (i = 0; i < *num; i++)
> +			val[i] = le32_to_cpu(out->val[i]);
> +	}
> +
> +	ph->xops->xfer_put(ph, t);
> +
> +	return ret;
> +}
> +
> +static int scmi_imx_misc_ctrl_set(const struct scmi_protocol_handle *ph,
> +				  u32 ctrl_id, u32 num, u32 *val)
> +{
> +	struct scmi_imx_misc_info *mi = ph->get_priv(ph);
> +	struct scmi_imx_misc_ctrl_set_in *in;
> +	struct scmi_xfer *t;
> +	int ret, i;
> +
> +	if (ctrl_id >= mi->nr_ctrl)
> +		return -EINVAL;
> +
> +	ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_CTRL_SET, sizeof(*in),
> +				      0, &t);

Similarly as above here you could fail if the requestes size for TX is
bigger than allowed by the transport..

> +	if (ret)
> +		return ret;
> +
> +	in = t->tx.buf;
> +	in->id = cpu_to_le32(ctrl_id);
> +	in->num = cpu_to_le32(num);
> +	for (i = 0; i < num; i++)

and num must be checked anyway to be < MISC_MAX_VAL before looping in->value

> +		in->value[i] = cpu_to_le32(val[i]);
> +
> +	ret = ph->xops->do_xfer(ph, t);
> +
> +	ph->xops->xfer_put(ph, t);
> +
> +	return ret;
> +}
> +
> +static const struct scmi_imx_misc_proto_ops scmi_imx_misc_proto_ops = {
> +	.misc_ctrl_set = scmi_imx_misc_ctrl_set,
> +	.misc_ctrl_get = scmi_imx_misc_ctrl_get,
> +};
> +
> +static const struct scmi_protocol scmi_imx_misc = {
> +	.id = SCMI_PROTOCOL_IMX_MISC,
> +	.owner = THIS_MODULE,
> +	.instance_init = &scmi_imx_misc_protocol_init,
> +	.ops = &scmi_imx_misc_proto_ops,
> +	.events = &scmi_imx_misc_protocol_events,
> +};
> +
> +module_scmi_protocol(scmi_imx_misc);
> diff --git a/include/linux/scmi_nxp_protocol.h b/include/linux/scmi_nxp_protocol.h
> index a2077e1ef5d8..45415a6ff845 100644
> --- a/include/linux/scmi_nxp_protocol.h
> +++ b/include/linux/scmi_nxp_protocol.h
> @@ -13,8 +13,14 @@
>  #include <linux/notifier.h>
>  #include <linux/types.h>
>  
> +#define SCMI_PAYLOAD_LEN	100
> +
> +#define SCMI_ARRAY(X, Y)	((SCMI_PAYLOAD_LEN - (X)) / sizeof(Y))
> +#define MISC_MAX_VAL		SCMI_ARRAY(8, uint32_t)
> +

All of these payload size calculation does NOT consider the fact that
the underlying buffer inside scmi_xfer are really dependent on
transport max_size...so as said above all the xfer_get_init could fail
depending on the size of the configured transport...just a heads
up...fine for me.

>  enum scmi_nxp_protocol {
>  	SCMI_PROTOCOL_IMX_BBM = 0x81,
> +	SCMI_PROTOCOL_IMX_MISC = 0x84,
>  };
>  
>  struct scmi_imx_bbm_proto_ops {
> @@ -47,4 +53,15 @@ struct scmi_imx_bbm_notif_report {
>  	unsigned int		rtc_id;
>  	unsigned int		rtc_evt;
>  };
> +
> +struct scmi_imx_misc_ctrl_notify_report {
> +	ktime_t			timestamp;
> +	unsigned int		ctrl_id;
> +	unsigned int		flags;
> +};
> +
> +struct scmi_imx_misc_proto_ops {
> +	int (*misc_ctrl_set)(const struct scmi_protocol_handle *ph, u32 id, u32 num, u32 *val);
> +	int (*misc_ctrl_get)(const struct scmi_protocol_handle *ph, u32 id, u32 *num, u32 *val);
> +};

Please add some Doc commenting describing these protocol_ops as in any
proto_ops found in scmi_protocol.h

(same for the other BBM Vendor protocol ops in the previous patch that I
missed in the other review.

Thanks,
Cristian


From lee at kernel.org  Fri Feb 23 08:02:34 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 16:02:34 +0000
Subject: [PATCH 0/3] mfd syscon and altera-sysmgr cleanup
In-Reply-To: <20240220115012.471689-1-peter.griffin@linaro.org>
References: <20240220115012.471689-1-peter.griffin@linaro.org>
Message-ID: <170870415412.1726445.3923431976204064450.b4-ty@kernel.org>

On Tue, 20 Feb 2024 11:50:09 +0000, Peter Griffin wrote:
> Whilst implementing a driver similar to altera-sysmgr for exynos
> it was noticed during the review feedback that we should only call
> of_node_put() if the property is provided otherwise nothing has
> taken a reference on the node. Both syscon and altera-sysmgr also
> have the same issue which this series fixes.
> 
> Another piece of review feedback was not to use extern keyword in
> the header file, so I also cleaned that up whilst being here.
> 
> [...]

Applied, thanks!

[1/3] mfd: syscon: call of_node_put() only when of_parse_phandle() takes a ref
      commit: d2b0680cf3b05490b579e71b0df6e07451977745
[2/3] mfd: syscon: remove extern from function prototypes
      commit: 0db017f8edd9b9af818bc1d68ba578df1b4c4628
[3/3] mfd: altera-sysmgr: call of_node_put() only when of_parse_phandle() takes a ref
      commit: e28c28a34ee9fa2ea671a20e5e7064e6220d55e7

--
Lee Jones [???]



From andre.przywara at arm.com  Fri Feb 23 08:02:58 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 23 Feb 2024 16:02:58 +0000
Subject: [PATCH v5 1/7] soc: sunxi: sram: export register 0 for THS on
 H616
In-Reply-To: <dcd115fd-dc38-4f48-8485-9e4d64f53b4a@linaro.org>
References: <20240219153639.179814-1-andre.przywara@arm.com>
	<20240219153639.179814-2-andre.przywara@arm.com>
	<2717467.mvXUDI8C0e@jernej-laptop>
	<dcd115fd-dc38-4f48-8485-9e4d64f53b4a@linaro.org>
Message-ID: <20240223160258.504a1577@donnerap.manchester.arm.com>

On Thu, 22 Feb 2024 19:44:12 +0100
Daniel Lezcano <daniel.lezcano at linaro.org> wrote:

Hi Daniel,

> On 22/02/2024 19:26, Jernej ?krabec wrote:
> > Dne ponedeljek, 19. februar 2024 ob 16:36:33 CET je Andre Przywara napisal(a):  
> >> The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
> >> in the SRAM control block. If bit 16 is set (the reset value), the
> >> temperature readings of the THS are way off, leading to reports about
> >> 200C, at normal ambient temperatures. Clearing this bits brings the
> >> reported values down to the expected values.
> >> The BSP code clears this bit in firmware (U-Boot), and has an explicit
> >> comment about this, but offers no real explanation.
> >>
> >> Experiments in U-Boot show that register 0x0 has no effect on the SRAM C
> >> visibility: all tested bit settings still allow full read and write
> >> access by the CPU to the whole of SRAM C. Only bit 24 of the register at
> >> offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling
> >> the THS switch functionality as an SRAM region would not reflect reality.
> >>
> >> Since we should not rely on firmware settings, allow other code (the THS
> >> driver) to access this register, by exporting it through the already
> >> existing regmap. This mimics what we already do for the LDO control and
> >> the EMAC register.
> >>
> >> To avoid concurrent accesses to the same register at the same time, by
> >> the SRAM switch code and the regmap code, use the same lock to protect
> >> the access. The regmap subsystem allows to use an existing lock, so we
> >> just need to hook in there.
> >>
> >> Signed-off-by: Andre Przywara <andre.przywara at arm.com>  
> > 
> > Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> > 
> > I guess this one goes through sunxi tree, right?  
> 
> I'll pick this patch along with the patch 2-6, so through the thermal 
> tree. The patch 7/7 will go indeed via the sunxi tree

many thanks for picking those up! I see them in your bleeding-edge branch,
but are they on route for 6.9, so will you put them in -next soon? Or are
you waiting for more ACKs?

Cheers,
Andre


From sean.anderson at linux.dev  Fri Feb 23 08:02:50 2024
From: sean.anderson at linux.dev (Sean Anderson)
Date: Fri, 23 Feb 2024 11:02:50 -0500
Subject: [RESEND2 PATCH net v4 2/2] soc: fsl: qbman: Use raw spinlock for
 cgr_lock
In-Reply-To: <53b401d7-934c-4937-ab83-6732af47668d@csgroup.eu>
References: <20240222170749.2607485-1-sean.anderson@linux.dev>
 <20240222170749.2607485-2-sean.anderson@linux.dev>
 <53b401d7-934c-4937-ab83-6732af47668d@csgroup.eu>
Message-ID: <34da1e7b-029e-410b-8735-a10d6d267e2b@linux.dev>

On 2/23/24 00:38, Christophe Leroy wrote:
> Le 22/02/2024 ? 18:07, Sean Anderson a ?crit :
>> [Vous ne recevez pas souvent de courriers de sean.anderson at linux.dev. D?couvrez pourquoi ceci est important ? https://aka.ms/LearnAboutSenderIdentification ]
>> 
>> cgr_lock may be locked with interrupts already disabled by
>> smp_call_function_single. As such, we must use a raw spinlock to avoid
>> problems on PREEMPT_RT kernels. Although this bug has existed for a
>> while, it was not apparent until commit ef2a8d5478b9 ("net: dpaa: Adjust
>> queue depth on rate change") which invokes smp_call_function_single via
>> qman_update_cgr_safe every time a link goes up or down.
> 
> Why a raw spinlock to avoid problems on PREEMPT_RT, can you elaborate ?

smp_call_function always runs its callback in hard IRQ context, even on
PREEMPT_RT, where spinlocks can sleep. So we need to use raw spinlocks
to ensure we aren't waiting on a sleeping task. See the first bug report
for more discussion.

In the longer term it would be better to switch to some other
abstraction.

--Sean

> If the problem is that interrupts are already disabled, shouldn't you 
> just change the spin_lock_irq() by spin_lock_irqsave() ?
>
> Christophe
> 
> 
>> 
>> Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
>> CC: stable at vger.kernel.org
>> Reported-by: Vladimir Oltean <vladimir.oltean at nxp.com>
>> Closes: https://lore.kernel.org/all/20230323153935.nofnjucqjqnz34ej at skbuf/
>> Reported-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
>> Closes: https://lore.kernel.org/linux-arm-kernel/87wmsyvclu.fsf at pengutronix.de/
>> Signed-off-by: Sean Anderson <sean.anderson at linux.dev>
>> Reviewed-by: Camelia Groza <camelia.groza at nxp.com>
>> Tested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
>> 
>> ---
>> 
>> Changes in v4:
>> - Add a note about how raw spinlocks aren't quite right
>> 
>> Changes in v3:
>> - Change blamed commit to something more appropriate
>> 
>>   drivers/soc/fsl/qbman/qman.c | 25 ++++++++++++++-----------
>>   1 file changed, 14 insertions(+), 11 deletions(-)
>> 
>> diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
>> index 1bf1f1ea67f0..7e9074519ad2 100644
>> --- a/drivers/soc/fsl/qbman/qman.c
>> +++ b/drivers/soc/fsl/qbman/qman.c
>> @@ -991,7 +991,7 @@ struct qman_portal {
>>          /* linked-list of CSCN handlers. */
>>          struct list_head cgr_cbs;
>>          /* list lock */
>> -       spinlock_t cgr_lock;
>> +       raw_spinlock_t cgr_lock;
>>          struct work_struct congestion_work;
>>          struct work_struct mr_work;
>>          char irqname[MAX_IRQNAME];
>> @@ -1281,7 +1281,7 @@ static int qman_create_portal(struct qman_portal *portal,
>>                  /* if the given mask is NULL, assume all CGRs can be seen */
>>                  qman_cgrs_fill(&portal->cgrs[0]);
>>          INIT_LIST_HEAD(&portal->cgr_cbs);
>> -       spin_lock_init(&portal->cgr_lock);
>> +       raw_spin_lock_init(&portal->cgr_lock);
>>          INIT_WORK(&portal->congestion_work, qm_congestion_task);
>>          INIT_WORK(&portal->mr_work, qm_mr_process_task);
>>          portal->bits = 0;
>> @@ -1456,11 +1456,14 @@ static void qm_congestion_task(struct work_struct *work)
>>          union qm_mc_result *mcr;
>>          struct qman_cgr *cgr;
>> 
>> -       spin_lock_irq(&p->cgr_lock);
>> +       /*
>> +        * FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock!
>> +        */
>> +       raw_spin_lock_irq(&p->cgr_lock);
>>          qm_mc_start(&p->p);
>>          qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
>>          if (!qm_mc_result_timeout(&p->p, &mcr)) {
>> -               spin_unlock_irq(&p->cgr_lock);
>> +               raw_spin_unlock_irq(&p->cgr_lock);
>>                  dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
>>                  qman_p_irqsource_add(p, QM_PIRQ_CSCI);
>>                  return;
>> @@ -1476,7 +1479,7 @@ static void qm_congestion_task(struct work_struct *work)
>>          list_for_each_entry(cgr, &p->cgr_cbs, node)
>>                  if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
>>                          cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
>> -       spin_unlock_irq(&p->cgr_lock);
>> +       raw_spin_unlock_irq(&p->cgr_lock);
>>          qman_p_irqsource_add(p, QM_PIRQ_CSCI);
>>   }
>> 
>> @@ -2440,7 +2443,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
>>          preempt_enable();
>> 
>>          cgr->chan = p->config->channel;
>> -       spin_lock_irq(&p->cgr_lock);
>> +       raw_spin_lock_irq(&p->cgr_lock);
>> 
>>          if (opts) {
>>                  struct qm_mcc_initcgr local_opts = *opts;
>> @@ -2477,7 +2480,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
>>              qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
>>                  cgr->cb(p, cgr, 1);
>>   out:
>> -       spin_unlock_irq(&p->cgr_lock);
>> +       raw_spin_unlock_irq(&p->cgr_lock);
>>          put_affine_portal();
>>          return ret;
>>   }
>> @@ -2512,7 +2515,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
>>                  return -EINVAL;
>> 
>>          memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
>> -       spin_lock_irqsave(&p->cgr_lock, irqflags);
>> +       raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
>>          list_del(&cgr->node);
>>          /*
>>           * If there are no other CGR objects for this CGRID in the list,
>> @@ -2537,7 +2540,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
>>                  /* add back to the list */
>>                  list_add(&cgr->node, &p->cgr_cbs);
>>   release_lock:
>> -       spin_unlock_irqrestore(&p->cgr_lock, irqflags);
>> +       raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
>>          put_affine_portal();
>>          return ret;
>>   }
>> @@ -2577,9 +2580,9 @@ static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
>>          if (!p)
>>                  return -EINVAL;
>> 
>> -       spin_lock_irqsave(&p->cgr_lock, irqflags);
>> +       raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
>>          ret = qm_modify_cgr(cgr, 0, opts);
>> -       spin_unlock_irqrestore(&p->cgr_lock, irqflags);
>> +       raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
>>          put_affine_portal();
>>          return ret;
>>   }
>> --
>> 2.35.1.1320.gc452695387.dirty
>> 


From glaubitz at physik.fu-berlin.de  Fri Feb 23 08:04:21 2024
From: glaubitz at physik.fu-berlin.de (John Paul Adrian Glaubitz)
Date: Fri, 23 Feb 2024 17:04:21 +0100
Subject: [linux-next:master] BUILD REGRESSION
 e31185ce00a96232308300008db193416ceb9769
In-Reply-To: <3532AACB-176A-4C48-9855-CCD6C97FDE91@kernel.org>
References: <202402231222.DVB9DC74-lkp@intel.com>
	 <3532AACB-176A-4C48-9855-CCD6C97FDE91@kernel.org>
Message-ID: <0f2060fcda53ac33fe893a27634f015f6e42bbe8.camel@physik.fu-berlin.de>

On Fri, 2024-02-23 at 07:46 -0800, Kees Cook wrote:
> > arch/sh/boot/compressed/../../../../lib/decompress_unxz.c:350:(.text+0x20b4): undefined reference to `__ubsan_handle_out_of_bounds'
> > sh4-linux-ld: arch/sh/boot/compressed/../../../../lib/xz/xz_dec_lzma2.c:751:(.text+0x904): undefined reference to `__ubsan_handle_out_of_bounds'
> 
> This is fixed here and is waiting to land:
> https://lore.kernel.org/linux-hardening/20240130232717.work.088-kees at kernel.org/

I was unable to reproduce this issue.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913


From theo.lebrun at bootlin.com  Fri Feb 23 08:05:26 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 23 Feb 2024 17:05:26 +0100
Subject: [PATCH v3 2/8] dt-bindings: usb: ti,j721e-usb: add ti,j7200-usb
 compatible
In-Reply-To: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
Message-ID: <20240223-j7200-usb-suspend-v3-2-b41c9893a130@bootlin.com>

On J7200, the controller & its wrapper are reset on resume. This makes
it have a different behavior from other platforms.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
index 949f45eb45c2..d52d5b2965aa 100644
--- a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
+++ b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
@@ -14,6 +14,7 @@ properties:
     enum:
       - ti,j721e-usb
       - ti,am64-usb
+      - ti,j7200-usb
 
   reg:
     maxItems: 1

-- 
2.43.2



From theo.lebrun at bootlin.com  Fri Feb 23 08:05:24 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 23 Feb 2024 17:05:24 +0100
Subject: [PATCH v3 0/8] usb: cdns: fix suspend on J7200 by assuming
 reset-on-resume
Message-ID: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>

Hi,

Here is a new revision of the J7200 USB suspend fix. It is currently
broken on the platform, leading to a kernel panic at resume. Patches
are tested on a J7200 evaluation board, both s2idle and suspend-to-RAM.

Previous discussion showed that runtime PM was not to be deleted.
Indeed, we cannot guarantee PM domains will stay active if we don't
register to runtime PM.

We therefore rely fully on runtime PM and put our init sequence
previously done in the probe in our ->runtime_resume(). We then do the
necessary to get it called at system-wide resume for the J7200
platform.

Have a nice day,
Th?o

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
Changes in v3:
- dt-bindings: use an enum to list compatibles instead of the previous
  odd construct. This is done in a separate patch from the one adding
  J7200 compatible.
- dt-bindings: dropped Acked-by Conor as the changes were modified a lot.
- Add runtime PM back. Put the init sequence in ->runtime_resume(). It
  gets called at probe for all compatibles and at resume for J7200.
- Introduce a cdns_ti_match_data struct rather than rely on compatible
  from code.
- Reorder code changes. Add infrastructure based on match data THEN add
  compatible and its match data.
- DTSI: use only J7200 compatible rather than both J7200 then J721E.
- Link to v2: https://lore.kernel.org/r/20231120-j7200-usb-suspend-v2-0-038c7e4a3df4 at bootlin.com

Changes in v2:
- Remove runtime PM from cdns3-ti; it brings nothing. That means our
  cdns3-ti suspend/resume patch is simpler; there is no need to handle
  runtime PM at suspend/resume.
- Do not add cdns3 host role suspend/resume callbacks; they are not
  needed as core detects reset on resume & calls cdns_drd_host_on when
  needed.
- cdns3-ti: Move usb2_refclk_rate_code assignment closer to the value
  computation.
- cdns3/host.c: do not pass XHCI_SUSPEND_RESUME_CLKS quirk to xHCI; it
  is unneeded on our platform.
- Link to v1: https://lore.kernel.org/r/20231113-j7200-usb-suspend-v1-0-ad1ee714835c at bootlin.com

---
Th?o Lebrun (8):
      dt-bindings: usb: ti,j721e-usb: drop useless compatible list
      dt-bindings: usb: ti,j721e-usb: add ti,j7200-usb compatible
      usb: cdns3-ti: move reg writes from probe into ->runtime_resume()
      usb: cdns3-ti: support reset-on-resume behavior
      usb: cdns3-ti: pass auxdata from match data to of_platform_populate()
      usb: cdns3: add quirk to platform data for reset-on-resume
      usb: cdns3-ti: add J7200 support with reset-on-resume behavior
      arm64: dts: ti: k3-j7200: use J7200-specific USB compatible

 .../devicetree/bindings/usb/ti,j721e-usb.yaml      |  10 +-
 arch/arm64/boot/dts/ti/k3-j7200-main.dtsi          |   2 +-
 drivers/usb/cdns3/cdns3-ti.c                       | 125 ++++++++++++++++-----
 drivers/usb/cdns3/core.h                           |   1 +
 drivers/usb/cdns3/host.c                           |   3 +
 5 files changed, 104 insertions(+), 37 deletions(-)
---
base-commit: 1871c27e3539e5b812d50ec6ccad7567ec5414f2
change-id: 20231113-j7200-usb-suspend-2a47f2281e04

Best regards,
-- 
Th?o Lebrun <theo.lebrun at bootlin.com>



From theo.lebrun at bootlin.com  Fri Feb 23 08:05:25 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 23 Feb 2024 17:05:25 +0100
Subject: [PATCH v3 1/8] dt-bindings: usb: ti,j721e-usb: drop useless
 compatible list
In-Reply-To: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
Message-ID: <20240223-j7200-usb-suspend-v3-1-b41c9893a130@bootlin.com>

Compatible can be A or B, not A or B or A+B. Remove last option.
A=ti,j721e-usb and B=ti,am64-usb.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
index 95ff9791baea..949f45eb45c2 100644
--- a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
+++ b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
@@ -11,12 +11,9 @@ maintainers:
 
 properties:
   compatible:
-    oneOf:
-      - const: ti,j721e-usb
-      - const: ti,am64-usb
-      - items:
-          - const: ti,j721e-usb
-          - const: ti,am64-usb
+    enum:
+      - ti,j721e-usb
+      - ti,am64-usb
 
   reg:
     maxItems: 1

-- 
2.43.2



From theo.lebrun at bootlin.com  Fri Feb 23 08:05:27 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 23 Feb 2024 17:05:27 +0100
Subject: [PATCH v3 3/8] usb: cdns3-ti: move reg writes from probe into
 ->runtime_resume()
In-Reply-To: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
Message-ID: <20240223-j7200-usb-suspend-v3-3-b41c9893a130@bootlin.com>

The hardware initialisation register write sequence is only used at
probe. Move it from being done at explicitely at probe to being done
implicitely by pm_runtime_get_sync() that calls ->runtime_resume().

Keep devicetree parsing in probe and add a new field in the private
struct to remember the USB2 refclk rate code computation result.

This opens the door to having the init sequence being executed later
down the road, at system-wide resume for example. This is NOT currently
happening because runtime PM is disabled at suspend without the
refcount being affected.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/usb/cdns3/cdns3-ti.c | 90 +++++++++++++++++++++++++-------------------
 1 file changed, 52 insertions(+), 38 deletions(-)

diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c
index 5945c4b1e11f..4c8a557e6a6f 100644
--- a/drivers/usb/cdns3/cdns3-ti.c
+++ b/drivers/usb/cdns3/cdns3-ti.c
@@ -57,6 +57,7 @@ struct cdns_ti {
 	unsigned vbus_divider:1;
 	struct clk *usb2_refclk;
 	struct clk *lpm_clk;
+	int usb2_refclk_rate_code;
 };
 
 static const int cdns_ti_rate_table[] = {	/* in KHZ */
@@ -90,10 +91,8 @@ static int cdns_ti_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *node = pdev->dev.of_node;
 	struct cdns_ti *data;
-	int error;
-	u32 reg;
-	int rate_code, i;
 	unsigned long rate;
+	int error, i;
 
 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 	if (!data)
@@ -133,7 +132,9 @@ static int cdns_ti_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	rate_code = i;
+	data->usb2_refclk_rate_code = i;
+	data->vbus_divider = device_property_read_bool(dev, "ti,vbus-divider");
+	data->usb2_only = device_property_read_bool(dev, "ti,usb2-only");
 
 	pm_runtime_enable(dev);
 	error = pm_runtime_get_sync(dev);
@@ -142,40 +143,6 @@ static int cdns_ti_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	/* assert RESET */
-	reg = cdns_ti_readl(data, USBSS_W1);
-	reg &= ~USBSS_W1_PWRUP_RST;
-	cdns_ti_writel(data, USBSS_W1, reg);
-
-	/* set static config */
-	reg = cdns_ti_readl(data, USBSS_STATIC_CONFIG);
-	reg &= ~USBSS1_STATIC_PLL_REF_SEL_MASK;
-	reg |= rate_code << USBSS1_STATIC_PLL_REF_SEL_SHIFT;
-
-	reg &= ~USBSS1_STATIC_VBUS_SEL_MASK;
-	data->vbus_divider = device_property_read_bool(dev, "ti,vbus-divider");
-	if (data->vbus_divider)
-		reg |= 1 << USBSS1_STATIC_VBUS_SEL_SHIFT;
-
-	cdns_ti_writel(data, USBSS_STATIC_CONFIG, reg);
-	reg = cdns_ti_readl(data, USBSS_STATIC_CONFIG);
-
-	/* set USB2_ONLY mode if requested */
-	reg = cdns_ti_readl(data, USBSS_W1);
-	data->usb2_only = device_property_read_bool(dev, "ti,usb2-only");
-	if (data->usb2_only)
-		reg |= USBSS_W1_USB2_ONLY;
-
-	/* set default modestrap */
-	reg |= USBSS_W1_MODESTRAP_SEL;
-	reg &= ~USBSS_W1_MODESTRAP_MASK;
-	reg |= USBSS_MODESTRAP_MODE_NONE << USBSS_W1_MODESTRAP_SHIFT;
-	cdns_ti_writel(data, USBSS_W1, reg);
-
-	/* de-assert RESET */
-	reg |= USBSS_W1_PWRUP_RST;
-	cdns_ti_writel(data, USBSS_W1, reg);
-
 	error = of_platform_populate(node, NULL, NULL, dev);
 	if (error) {
 		dev_err(dev, "failed to create children: %d\n", error);
@@ -211,6 +178,52 @@ static void cdns_ti_remove(struct platform_device *pdev)
 	platform_set_drvdata(pdev, NULL);
 }
 
+static int cdns_ti_runtime_resume(struct device *dev)
+{
+	struct cdns_ti *data = dev_get_drvdata(dev);
+	u32 reg;
+
+	/* assert RESET */
+	reg = cdns_ti_readl(data, USBSS_W1);
+	reg &= ~USBSS_W1_PWRUP_RST;
+	cdns_ti_writel(data, USBSS_W1, reg);
+
+	/* set static config */
+	reg = cdns_ti_readl(data, USBSS_STATIC_CONFIG);
+	reg &= ~USBSS1_STATIC_PLL_REF_SEL_MASK;
+	reg |= data->usb2_refclk_rate_code << USBSS1_STATIC_PLL_REF_SEL_SHIFT;
+
+	reg &= ~USBSS1_STATIC_VBUS_SEL_MASK;
+
+	if (data->vbus_divider)
+		reg |= 1 << USBSS1_STATIC_VBUS_SEL_SHIFT;
+
+	cdns_ti_writel(data, USBSS_STATIC_CONFIG, reg);
+	reg = cdns_ti_readl(data, USBSS_STATIC_CONFIG);
+
+	/* set USB2_ONLY mode if requested */
+	reg = cdns_ti_readl(data, USBSS_W1);
+
+	if (data->usb2_only)
+		reg |= USBSS_W1_USB2_ONLY;
+
+	/* set default modestrap */
+	reg |= USBSS_W1_MODESTRAP_SEL;
+	reg &= ~USBSS_W1_MODESTRAP_MASK;
+	reg |= USBSS_MODESTRAP_MODE_NONE << USBSS_W1_MODESTRAP_SHIFT;
+	cdns_ti_writel(data, USBSS_W1, reg);
+
+	/* de-assert RESET */
+	reg |= USBSS_W1_PWRUP_RST;
+	cdns_ti_writel(data, USBSS_W1, reg);
+
+	return 0;
+}
+
+static const struct dev_pm_ops cdns_ti_pm_ops = {
+	RUNTIME_PM_OPS(NULL, cdns_ti_runtime_resume, NULL)
+};
+
 static const struct of_device_id cdns_ti_of_match[] = {
 	{ .compatible = "ti,j721e-usb", },
 	{ .compatible = "ti,am64-usb", },
@@ -224,6 +237,7 @@ static struct platform_driver cdns_ti_driver = {
 	.driver		= {
 		.name	= "cdns3-ti",
 		.of_match_table	= cdns_ti_of_match,
+		.pm	= pm_ptr(&cdns_ti_pm_ops),
 	},
 };
 

-- 
2.43.2



From theo.lebrun at bootlin.com  Fri Feb 23 08:05:29 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 23 Feb 2024 17:05:29 +0100
Subject: [PATCH v3 5/8] usb: cdns3-ti: pass auxdata from match data to
 of_platform_populate()
In-Reply-To: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
Message-ID: <20240223-j7200-usb-suspend-v3-5-b41c9893a130@bootlin.com>

Allow compatible to pick auxdata given to child platform devices.

No compatible exploits this functionality, just yet.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/usb/cdns3/cdns3-ti.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c
index f76327566798..29fb24c811b3 100644
--- a/drivers/usb/cdns3/cdns3-ti.c
+++ b/drivers/usb/cdns3/cdns3-ti.c
@@ -62,7 +62,8 @@ struct cdns_ti {
 };
 
 struct cdns_ti_match_data {
-	bool reset_on_resume;
+	bool				reset_on_resume;
+	const struct of_dev_auxdata	*auxdata;
 };
 
 static const int cdns_ti_rate_table[] = {	/* in KHZ */
@@ -95,6 +96,7 @@ static int cdns_ti_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *node = pdev->dev.of_node;
+	const struct of_dev_auxdata *auxdata = NULL;
 	struct cdns_ti *data;
 	unsigned long rate;
 	int error, i;
@@ -149,7 +151,9 @@ static int cdns_ti_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	error = of_platform_populate(node, NULL, NULL, dev);
+	if (data->match_data)
+		auxdata = data->match_data->auxdata;
+	error = of_platform_populate(node, NULL, auxdata, dev);
 	if (error) {
 		dev_err(dev, "failed to create children: %d\n", error);
 		goto err;

-- 
2.43.2



From theo.lebrun at bootlin.com  Fri Feb 23 08:05:28 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 23 Feb 2024 17:05:28 +0100
Subject: [PATCH v3 4/8] usb: cdns3-ti: support reset-on-resume behavior
In-Reply-To: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
Message-ID: <20240223-j7200-usb-suspend-v3-4-b41c9893a130@bootlin.com>

Add match data support, with one boolean to indicate whether the
hardware resets after a system-wide suspend. If hardware resets, we
force execute ->runtime_resume() at system-wide resume to run the
hardware init sequence.

No compatible exploits this functionality, just yet.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/usb/cdns3/cdns3-ti.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c
index 4c8a557e6a6f..f76327566798 100644
--- a/drivers/usb/cdns3/cdns3-ti.c
+++ b/drivers/usb/cdns3/cdns3-ti.c
@@ -57,9 +57,14 @@ struct cdns_ti {
 	unsigned vbus_divider:1;
 	struct clk *usb2_refclk;
 	struct clk *lpm_clk;
+	const struct cdns_ti_match_data *match_data;
 	int usb2_refclk_rate_code;
 };
 
+struct cdns_ti_match_data {
+	bool reset_on_resume;
+};
+
 static const int cdns_ti_rate_table[] = {	/* in KHZ */
 	9600,
 	10000,
@@ -101,6 +106,7 @@ static int cdns_ti_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, data);
 
 	data->dev = dev;
+	data->match_data = device_get_match_data(dev);
 
 	data->usbss = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->usbss)) {
@@ -220,8 +226,29 @@ static int cdns_ti_runtime_resume(struct device *dev)
 	return 0;
 }
 
+static int cdns_ti_suspend(struct device *dev)
+{
+	struct cdns_ti *data = dev_get_drvdata(dev);
+
+	if (data->match_data && data->match_data->reset_on_resume)
+		return pm_runtime_force_suspend(dev);
+	else
+		return 0;
+}
+
+static int cdns_ti_resume(struct device *dev)
+{
+	struct cdns_ti *data = dev_get_drvdata(dev);
+
+	if (data->match_data && data->match_data->reset_on_resume)
+		return pm_runtime_force_resume(dev);
+	else
+		return 0;
+}
+
 static const struct dev_pm_ops cdns_ti_pm_ops = {
 	RUNTIME_PM_OPS(NULL, cdns_ti_runtime_resume, NULL)
+	SYSTEM_SLEEP_PM_OPS(cdns_ti_suspend, cdns_ti_resume)
 };
 
 static const struct of_device_id cdns_ti_of_match[] = {

-- 
2.43.2



From theo.lebrun at bootlin.com  Fri Feb 23 08:05:30 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 23 Feb 2024 17:05:30 +0100
Subject: [PATCH v3 6/8] usb: cdns3: add quirk to platform data for
 reset-on-resume
In-Reply-To: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
Message-ID: <20240223-j7200-usb-suspend-v3-6-b41c9893a130@bootlin.com>

The cdns3 host role does not care about reset-on-resume. xHCI however
reconfigures itself in silence rather than printing a warning about a
resume error. Related warning example:

  [   16.017462] xhci-hcd xhci-hcd.1.auto: xHC error in resume, USBSTS 0x401, Reinit

Allow passing a CDNS3_RESET_ON_RESUME quirk flag from cdns3 pdata down
to xHCI pdata. The goal is to allow signaling about reset-on-resume
behavior from platform wrapper drivers.

When used, remote wakeup is not expected to work.

Acked-by: Peter Chen <peter.chen at kernel.org>
Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/usb/cdns3/core.h | 1 +
 drivers/usb/cdns3/host.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/usb/cdns3/core.h b/drivers/usb/cdns3/core.h
index 81a9c9d6be08..7487067ba23f 100644
--- a/drivers/usb/cdns3/core.h
+++ b/drivers/usb/cdns3/core.h
@@ -44,6 +44,7 @@ struct cdns3_platform_data {
 			bool suspend, bool wakeup);
 	unsigned long quirks;
 #define CDNS3_DEFAULT_PM_RUNTIME_ALLOW	BIT(0)
+#define CDNS3_RESET_ON_RESUME		BIT(1)
 };
 
 /**
diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c
index 6164fc4c96a4..28c4d1deb231 100644
--- a/drivers/usb/cdns3/host.c
+++ b/drivers/usb/cdns3/host.c
@@ -91,6 +91,9 @@ static int __cdns_host_init(struct cdns *cdns)
 	if (cdns->pdata && (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW))
 		cdns->xhci_plat_data->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
 
+	if (cdns->pdata && (cdns->pdata->quirks & CDNS3_RESET_ON_RESUME))
+		cdns->xhci_plat_data->quirks |= XHCI_RESET_ON_RESUME;
+
 	ret = platform_device_add_data(xhci, cdns->xhci_plat_data,
 			sizeof(struct xhci_plat_priv));
 	if (ret)

-- 
2.43.2



From theo.lebrun at bootlin.com  Fri Feb 23 08:05:31 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 23 Feb 2024 17:05:31 +0100
Subject: [PATCH v3 7/8] usb: cdns3-ti: add J7200 support with
 reset-on-resume behavior
In-Reply-To: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
Message-ID: <20240223-j7200-usb-suspend-v3-7-b41c9893a130@bootlin.com>

Add ti,j7200-usb compatible. Match data indicates the controller resets
on resume meaning:
 - The cdns3-ti wrapper init sequence must be ran at resume.
 - Tell the cdns3 core that we reset on resume. This silences a xHCI
   warning visible in cases of unexpected resets.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/usb/cdns3/cdns3-ti.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c
index 29fb24c811b3..648243a27987 100644
--- a/drivers/usb/cdns3/cdns3-ti.c
+++ b/drivers/usb/cdns3/cdns3-ti.c
@@ -17,6 +17,8 @@
 #include <linux/pm_runtime.h>
 #include <linux/property.h>
 
+#include "core.h"
+
 /* USB Wrapper register offsets */
 #define USBSS_PID		0x0
 #define	USBSS_W1		0x4
@@ -255,7 +257,25 @@ static const struct dev_pm_ops cdns_ti_pm_ops = {
 	SYSTEM_SLEEP_PM_OPS(cdns_ti_suspend, cdns_ti_resume)
 };
 
+static struct cdns3_platform_data cdns_ti_j7200_pdata = {
+       .quirks = CDNS3_RESET_ON_RESUME,
+};
+
+static const struct of_dev_auxdata cdns_ti_j7200_auxdata[] = {
+       {
+               .compatible = "cdns,usb3",
+               .platform_data = &cdns_ti_j7200_pdata,
+       },
+       {},
+};
+
+static const struct cdns_ti_match_data cdns_ti_j7200_match_data = {
+       .reset_on_resume = true,
+       .auxdata = cdns_ti_j7200_auxdata,
+};
+
 static const struct of_device_id cdns_ti_of_match[] = {
+	{ .compatible = "ti,j7200-usb", .data = &cdns_ti_j7200_match_data, },
 	{ .compatible = "ti,j721e-usb", },
 	{ .compatible = "ti,am64-usb", },
 	{},

-- 
2.43.2



From theo.lebrun at bootlin.com  Fri Feb 23 08:05:32 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Fri, 23 Feb 2024 17:05:32 +0100
Subject: [PATCH v3 8/8] arm64: dts: ti: k3-j7200: use J7200-specific USB
 compatible
In-Reply-To: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
Message-ID: <20240223-j7200-usb-suspend-v3-8-b41c9893a130@bootlin.com>

On our platform, suspend-to-idle or suspend-to-RAM turn the controller
off. This compatible triggers reset-on-resume behavior to reconfigure
the hardware.

Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 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 45ba9c2d0344..134d6e5f3b01 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -793,7 +793,7 @@ pcie1_ep: pcie-ep at 2910000 {
 	};
 
 	usbss0: cdns-usb at 4104000 {
-		compatible = "ti,j721e-usb";
+		compatible = "ti,j7200-usb";
 		reg = <0x00 0x4104000 0x00 0x100>;
 		dma-coherent;
 		power-domains = <&k3_pds 288 TI_SCI_PD_EXCLUSIVE>;

-- 
2.43.2



From michael.j.ruhl at intel.com  Fri Feb 23 08:09:03 2024
From: michael.j.ruhl at intel.com (Ruhl, Michael J)
Date: Fri, 23 Feb 2024 16:09:03 +0000
Subject: [PATCH] clkdev: Update clkdev id usage to allow for longer names
In-Reply-To: <Zdi-QnkPYUFWLJIe@smile.fi.intel.com>
References: <20240223141857.3794855-1-michael.j.ruhl@intel.com>
 <Zdi-QnkPYUFWLJIe@smile.fi.intel.com>
Message-ID: <DS0PR11MB64245B3F3AB02C32B53F3F64C1552@DS0PR11MB6424.namprd11.prod.outlook.com>

>-----Original Message-----
>From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
>Sent: Friday, February 23, 2024 10:48 AM
>To: Ruhl, Michael J <michael.j.ruhl at intel.com>
>Cc: linux at armlinux.org.uk; linux-arm-kernel at lists.infradead.org; linux-
>kernel at vger.kernel.org
>Subject: Re: [PATCH] clkdev: Update clkdev id usage to allow for longer names
>
>On Fri, Feb 23, 2024 at 09:18:14AM -0500, Michael J. Ruhl wrote:
>> clkdev ID information is limited to arrays of 20 and 16 bytes
>> (MAX_DEV_ID/MAX_CON_ID).  It is possible that the IDs could be
>> longer that.  If so, the lookup will fail because the "real ID"
>> will not match the copied value.
>
>Perhaps you need to add a real example.

How about:

Generating a device name for the I2C Designware module using the PCI
ID can result in a name of:

i2c_designware.39424

clkdev_create will store:

i2c_designware.3942

The stored name is one off and will not match correctly during probe.

>> Increase the size of the IDs to allow for longer names.
>
>...
>
>> -#define MAX_DEV_ID	20
>> -#define MAX_CON_ID	16
>> +#define MAX_DEV_ID	32
>> +#define MAX_CON_ID	32
>
>Do we need to alter both?

It wasn't clear to why there was a difference in sizes.  At the moment the CON_ID isn't
causing me an issue.  Shall I drop that part of the change?

Thanks!

Mike

>--
>With Best Regards,
>Andy Shevchenko
>



From andriy.shevchenko at linux.intel.com  Fri Feb 23 08:19:44 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 18:19:44 +0200
Subject: [PATCH] clkdev: Update clkdev id usage to allow for longer names
In-Reply-To: <DS0PR11MB64245B3F3AB02C32B53F3F64C1552@DS0PR11MB6424.namprd11.prod.outlook.com>
References: <20240223141857.3794855-1-michael.j.ruhl@intel.com>
 <Zdi-QnkPYUFWLJIe@smile.fi.intel.com>
 <DS0PR11MB64245B3F3AB02C32B53F3F64C1552@DS0PR11MB6424.namprd11.prod.outlook.com>
Message-ID: <ZdjFoLP6uqi7JsYy@smile.fi.intel.com>

On Fri, Feb 23, 2024 at 04:09:03PM +0000, Ruhl, Michael J wrote:
> >From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> >Sent: Friday, February 23, 2024 10:48 AM
> >On Fri, Feb 23, 2024 at 09:18:14AM -0500, Michael J. Ruhl wrote:
> >> clkdev ID information is limited to arrays of 20 and 16 bytes
> >> (MAX_DEV_ID/MAX_CON_ID).  It is possible that the IDs could be
> >> longer that.  If so, the lookup will fail because the "real ID"
> >> will not match the copied value.
> >
> >Perhaps you need to add a real example.
> 
> How about:
> 
> Generating a device name for the I2C Designware module using the PCI
> ID can result in a name of:
> 
> i2c_designware.39424
> 
> clkdev_create will store:

clkdev_create()

> i2c_designware.3942
> 
> The stored name is one off and will not match correctly during probe.
> 
> >> Increase the size of the IDs to allow for longer names.

...

> >> -#define MAX_DEV_ID	20
> >> -#define MAX_CON_ID	16
> >> +#define MAX_DEV_ID	32

So with the above example increasing by 4 is enough, right?
Maybe we can be modest for now as it will solve your issue?

#define MAX_DEV_ID	24

> >> +#define MAX_CON_ID	32
> >
> >Do we need to alter both?
> 
> It wasn't clear to why there was a difference in sizes.  At the moment the CON_ID isn't
> causing me an issue.  Shall I drop that part of the change?

I think so.

-- 
With Best Regards,
Andy Shevchenko




From ni_liqiang at 126.com  Fri Feb 23 08:20:10 2024
From: ni_liqiang at 126.com (ni.liqiang)
Date: Sat, 24 Feb 2024 00:20:10 +0800
Subject: [PATCH] drivers/iommu: Ensure that the queue base address is successfully written during SMMU initialization.
In-Reply-To: <20240221160849.GB7362@willie-the-truck>
References: <20240221160849.GB7362@willie-the-truck>
Message-ID: <20240223162010.6884-1-ni_liqiang@126.com>

> (Disclaimer: I don't know what a CCG port is)

CCG(CXL Gateway) is a part of the CMN700 Coherent Mesh Network. It plays
a crucial role in facilitating cross-die access in a multi-chip system.

> Hmmm. The part that doesn't make sense to me here is that migrating between
> CPUs implies context-switching, and we have a DSB on that path in
> __switch_to(). So why would adding barriers to the driver help? Maybe it
> just changes the timing?

This is very likely. Through our experiments, adding a delay before CMDQEN
does not reproduce the failure of writing to the CMDQ base register.

> I'm not sure what you're proposing, but I don't think Linux should be
> changed to accomodate this.

I am very grateful for the responses from both of you experts. We will
continue to check the current hardware configuration of the system
and attempt to fix this issue.
Once again, I express my thanks. Thank you.



From aren at peacevolution.org  Fri Feb 23 08:30:00 2024
From: aren at peacevolution.org (Aren)
Date: Fri, 23 Feb 2024 11:30:00 -0500
Subject: [PATCH v2 4/4] arm64: dts: sun50i-a64-pinephone: change led type
 to status
In-Reply-To: <2792937.BEx9A2HvPv@jernej-laptop>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <20240206185400.596979-4-aren@peacevolution.org>
 <2792937.BEx9A2HvPv@jernej-laptop>
Message-ID: <n5rmhx7ez7xoqainjqxpdk47e3bw2pvtsgswofnhjdxtrk72j2@debhbdxsxz4m>

On Thu, Feb 22, 2024 at 09:57:00PM +0100, Jernej ?krabec wrote:
> Dne torek, 06. februar 2024 ob 19:13:20 CET je Aren Moynihan napisal(a):
> > The status function is described in the documentation as being a rgb led
> > used for system notifications on phones[1][2]. This is exactly what this
> > led is used for on the PinePhone, so using status is probably more
> > accurate than indicator.
> > 
> > 1: Documentation/leds/well-known-leds.txt
> > 2: include/dt-bindings/leds/common.h
> > 
> > Signed-off-by: Aren Moynihan <aren at peacevolution.org>
> 
> Sorry for late review.
> 
> Please update subject in patches 2-3. Instead of "sun50i-a64-pinephone:"
> use "allwinner: pinephone:" (check commit history of sun50i-a64-pinephone.dtsi).
> Also rgb -> RGB, led -> LED. Last, please reword commit message to exclude
> links and just say DT bindings documentation.
> 
> Note that I'll merge patches 2-3 once patch 1 is merged.

Would you like me to reword and resend the patches, or is it quicker
for you to just do it when you apply them?

Thanks for taking a look at this,
 - Aren

> Best regards,
> Jernej
> 
> > ---
> > I can't find any documentation describing the indicator function, so
> > it's definitely less specific than status, but besides that I'm not sure
> > how it compares. Please ignore this patch if it's not useful.
> > 
> > (no changes since v1)
> > 
> >  arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > index e53e0d4579a7..6d327266e6cc 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > @@ -61,7 +61,7 @@ led2: led-2 {
> >  	multi-led {
> >  		compatible = "leds-group-multicolor";
> >  		color = <LED_COLOR_ID_RGB>;
> > -		function = LED_FUNCTION_INDICATOR;
> > +		function = LED_FUNCTION_STATUS;
> >  		leds = <&led0>, <&led1>, <&led2>;
> >  	};
> >  
> > 
> 
> 
> 
> 


From robh at kernel.org  Fri Feb 23 08:34:34 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 23 Feb 2024 09:34:34 -0700
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <ZdegTjJpDJGEgdvo@shikoro>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com> <20240216022704.GB850600-robh@kernel.org>
 <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com> <CACRpkdZZhhzg5SY7U5dv_OfLEVejRFom4V9nCfkQXunAw1ZXSw@mail.gmail.com>
 <CZ94LGRSF9KN.15ZO1VRMIQVR8@bootlin.com> <CZAX02IL1N1J.2GQR9D73GLRZB@bootlin.com>
 <ZdY2WzKbElloXC4-@shikoro> <20240222171404.GA3334332-robh@kernel.org> <ZdegTjJpDJGEgdvo@shikoro>
Message-ID: <CAL_JsqLk3UbrXAymTvLQeeS-ACY7makTVYxa9CetO-G-v3TuqA@mail.gmail.com>

On Thu, Feb 22, 2024 at 12:28?PM Wolfram Sang <wsa at kernel.org> wrote:
>
>
> > > @Rob: My memory fails a little bit about these two schemas: we have the
> > > github one for generic bindings, not strictly related to Linux, right?
> >
> > Well, NONE of the bindings are strictly related to linux unless they say
> > 'linux,' prefix.
>
> Ok, right, of course. What I meant was probably: why do we have
> controller bindings in the kernel and schema bindings in a github tree?

Generally the split is common, stable bindings go in dtschema. This is
anything we'd consider should be in the DT spec. Though I have 0 plans
to add anything to the spec because I'd like to generate the spec from
schema. (Not really working on doing that either though). What's
stable? Well, no solid definition there other than not new. So new
things generally go into the kernel tree first.

For device specific bindings, they will never go into dtschema and
will live where the dts files are.

> For me, this is a tad more difficult to maintain. Like
> i2c-controller.yaml file has the "no-detect" binding which IMO is wrong
> in many ways. I rejected the supporting code for Linux.

It was probably added to i2c.txt and I probably said, looks fine, but
add it to dtschema. Then the Linux support got rejected. We can simply
remove it if it is not being used.

This is why I'm generally against moving all the DT stuff out of the
kernel. The reviewing would dry up. I'll try to make sure you see any
future i2c changes. I take either patches on devicetree-spec list or
GH PR. Shockingly, I mainly get GH PR.

Rob


From michael.j.ruhl at intel.com  Fri Feb 23 08:35:16 2024
From: michael.j.ruhl at intel.com (Michael J. Ruhl)
Date: Fri, 23 Feb 2024 11:35:16 -0500
Subject: [PATCH v2] clkdev: Update clkdev id usage to allow for longer names
Message-ID: <20240223163516.796606-1-michael.j.ruhl@intel.com>

clkdev DEV ID information is limited to an array of 20 bytes
(MAX_DEV_ID).  It is possible that the ID could be longer than
that.  If so, the lookup will fail because the "real ID" will
not match the copied value.

For instance, generating a device name for the I2C Designware
module using the PCI ID can result in a name of:

i2c_designware.39424

clkdev_create() will store:

i2c_designware.3942

The stored name is one off and will not match correctly during probe.

Increase the size of the ID to allow for a longer name.

v2: Removed CON_ID update and added example to commit

Signed-off-by: Michael J. Ruhl <michael.j.ruhl at intel.com>
---
 drivers/clk/clkdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index ee37d0be6877..9cd80522ca2d 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -144,7 +144,7 @@ void clkdev_add_table(struct clk_lookup *cl, size_t num)
 	mutex_unlock(&clocks_mutex);
 }
 
-#define MAX_DEV_ID	20
+#define MAX_DEV_ID	24
 #define MAX_CON_ID	16
 
 struct clk_lookup_alloc {
-- 
2.41.0



From schnelle at linux.ibm.com  Fri Feb 23 08:35:42 2024
From: schnelle at linux.ibm.com (Niklas Schnelle)
Date: Fri, 23 Feb 2024 17:35:42 +0100
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <20240223125852.GE13330@nvidia.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
	 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
	 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
	 <20240222223617.GC13330@nvidia.com>
	 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
	 <e78f6e6294c31d889ace4de3a3c3cebad04f4213.camel@linux.ibm.com>
	 <20240223125852.GE13330@nvidia.com>
Message-ID: <eea8b03c20fc49cd88b159959a589f78521ff53b.camel@linux.ibm.com>

On Fri, 2024-02-23 at 08:58 -0400, Jason Gunthorpe wrote:
> On Fri, Feb 23, 2024 at 12:38:18PM +0100, Niklas Schnelle wrote:
> > > Although I doubt that generating long TLP from byte writes is
> > > really necessary.
> > 
> > I might have gotten confused but I think these are not byte writes.
> > Remember that the count is in terms of the number of bits sized
> > quantities to copy so "count == 1" is 4/8 bytes here.
> 
> Right.
> 
> There seem to be two callers of this API in the kernel, one is calling
> with a constant size and wants a large TLP
> 
> Another seems to want memcpy_to_io with a guarenteed 32/64 bit store.

I don't really understand how that works together with the order not
being guaranteed. Do they use normal ioremap() and then require 32/64
bit TLPs and don't care about the order? But then the generic and ARM
variants do things in order so who knows if they actually rely on that.

> 
> > > IIRC you were merging at most 4 writes.
> > > So better to do a single 32bit write instead.
> > > (Unless you have misaligned source data - unlikely.)
> > > 
> > > While write-combining to generate long TLP is probably mostly
> > > safe for PCIe targets, there are some that will only handle
> > > TLP for single 32bit data items.
> > > Which might be why the code is explicitly requesting 4 byte copies.
> > > So it may be entirely wrong to write-combine anything except
> > > the generic memcpy_toio().
> > 
> > On anything other than s390x this should only do write-combine if the
> > memory mapping allows it, no? Meaning a driver that can't handle larger
> > TLPs really shouldn't use ioremap_wc() then.
> 
> Right.
> 
> > On s390x one could argue that our version of __iowriteXX_copy() is
> > strictly speaking not correct in that zpci_memcpy_toio() doesn't really
> > use XX bit writes which is why for us memcpy_toio() was actually a
> > better fit indeed. On the other hand doing 32 bit PCI stores (an s390x
> > thing) can't combine multiple stores into a single TLP which these
> > functions are used for and which has much more use cases than forcing a
> > copy loop with 32/64 bit sized writes which would also be a lot slower
> > on s390x than an aligned zpci_memcpy_toio().
> 
> mlx5 will definitely not work right if __iowrite64_copy() results in
> anything smaller than 32/64 bit PCIe TLPs.
> 
> Jason

Yes and we do actually have mlx5 on s390x so this is my priority.


From jernej.skrabec at gmail.com  Fri Feb 23 08:36:42 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Fri, 23 Feb 2024 17:36:42 +0100
Subject: [PATCH v2 4/4] arm64: dts: sun50i-a64-pinephone: change led type to
 status
In-Reply-To: <n5rmhx7ez7xoqainjqxpdk47e3bw2pvtsgswofnhjdxtrk72j2@debhbdxsxz4m>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <2792937.BEx9A2HvPv@jernej-laptop>
 <n5rmhx7ez7xoqainjqxpdk47e3bw2pvtsgswofnhjdxtrk72j2@debhbdxsxz4m>
Message-ID: <4545459.LvFx2qVVIh@jernej-laptop>

Dne petek, 23. februar 2024 ob 17:30:00 CET je Aren napisal(a):
> On Thu, Feb 22, 2024 at 09:57:00PM +0100, Jernej ?krabec wrote:
> > Dne torek, 06. februar 2024 ob 19:13:20 CET je Aren Moynihan napisal(a):
> > > The status function is described in the documentation as being a rgb led
> > > used for system notifications on phones[1][2]. This is exactly what this
> > > led is used for on the PinePhone, so using status is probably more
> > > accurate than indicator.
> > > 
> > > 1: Documentation/leds/well-known-leds.txt
> > > 2: include/dt-bindings/leds/common.h
> > > 
> > > Signed-off-by: Aren Moynihan <aren at peacevolution.org>
> > 
> > Sorry for late review.
> > 
> > Please update subject in patches 2-3. Instead of "sun50i-a64-pinephone:"
> > use "allwinner: pinephone:" (check commit history of sun50i-a64-pinephone.dtsi).
> > Also rgb -> RGB, led -> LED. Last, please reword commit message to exclude
> > links and just say DT bindings documentation.
> > 
> > Note that I'll merge patches 2-3 once patch 1 is merged.
> 
> Would you like me to reword and resend the patches, or is it quicker
> for you to just do it when you apply them?

Since Ond?ej raised concerns, let's finish that discussion first. It's possible
that this patch will be rejected. That would also mean new revision of patches.

Sadly, this means DT patches will miss v6.9 window.

Best regards,
Jernej

> 
> Thanks for taking a look at this,
>  - Aren
> 
> > Best regards,
> > Jernej
> > 
> > > ---
> > > I can't find any documentation describing the indicator function, so
> > > it's definitely less specific than status, but besides that I'm not sure
> > > how it compares. Please ignore this patch if it's not useful.
> > > 
> > > (no changes since v1)
> > > 
> > >  arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > index e53e0d4579a7..6d327266e6cc 100644
> > > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > @@ -61,7 +61,7 @@ led2: led-2 {
> > >  	multi-led {
> > >  		compatible = "leds-group-multicolor";
> > >  		color = <LED_COLOR_ID_RGB>;
> > > -		function = LED_FUNCTION_INDICATOR;
> > > +		function = LED_FUNCTION_STATUS;
> > >  		leds = <&led0>, <&led1>, <&led2>;
> > >  	};
> > >  
> > > 
> > 
> > 
> > 
> > 
> 






From james.clark at arm.com  Fri Feb 23 08:39:55 2024
From: james.clark at arm.com (James Clark)
Date: Fri, 23 Feb 2024 16:39:55 +0000
Subject: [PATCH v5 5/7] arm64: KVM: Add interface to set guest value for
 TRFCR register
In-Reply-To: <c8819064-13c3-41c6-8b2e-779ef8a22ee8@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
 <20240220100924.2761706-6-james.clark@arm.com>
 <c8819064-13c3-41c6-8b2e-779ef8a22ee8@arm.com>
Message-ID: <9d3f9f70-0b34-7426-8b62-93dc173a0bb2@arm.com>



On 23/02/2024 10:03, Suzuki K Poulose wrote:
> On 20/02/2024 10:09, James Clark wrote:
>> Add an interface for the Coresight driver to use to set the value of the
>> TRFCR register for the guest. This register controls the exclude
>> settings for trace at different exception levels, and is used to honor
>> the exclude_host and exclude_guest parameters from the Perf session.
>> This will be used to later write TRFCR_EL1 on nVHE at guest switch. For
>> VHE, the host trace is controlled by TRFCR_EL2 and thus we can write to
>> the TRFCR_EL1 immediately. Because guest writes to the register are
>> trapped, the value will persist and can't be modified.
>>
>> Instead of adding a load of infrastructure to share the host's per-cpu
>> offsets with the hypervisor, just define the new storage as a NR_CPUS
>> array.
>>
>> Signed-off-by: James Clark <james.clark at arm.com>
>> ---
>> ? arch/arm64/include/asm/kvm_host.h |? 3 +++
>> ? arch/arm64/kernel/image-vars.h??? |? 1 +
>> ? arch/arm64/kvm/debug.c??????????? | 26 ++++++++++++++++++++++++++
>> ? 3 files changed, 30 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/kvm_host.h
>> b/arch/arm64/include/asm/kvm_host.h
>> index 85b5477bd1b4..56b7f7eca195 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -509,6 +509,7 @@ struct kvm_host_psci_config {
>> ????? bool psci_0_1_cpu_off_implemented;
>> ????? bool psci_0_1_migrate_implemented;
>> ? };
>> +extern u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
>> ? ? extern struct kvm_host_psci_config
>> kvm_nvhe_sym(kvm_host_psci_config);
>> ? #define kvm_host_psci_config CHOOSE_NVHE_SYM(kvm_host_psci_config)
>> @@ -1174,6 +1175,7 @@ void kvm_arch_vcpu_put_debug_state_flags(struct
>> kvm_vcpu *vcpu);
>> ? void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr);
>> ? void kvm_clr_pmu_events(u32 clr);
>> ? bool kvm_set_pmuserenr(u64 val);
>> +void kvm_etm_set_guest_trfcr(u64 trfcr_guest);
>> ? #else
>> ? static inline void kvm_set_pmu_events(u32 set, struct
>> perf_event_attr *attr) {}
>> ? static inline void kvm_clr_pmu_events(u32 clr) {}
>> @@ -1181,6 +1183,7 @@ static inline bool kvm_set_pmuserenr(u64 val)
>> ? {
>> ????? return false;
>> ? }
>> +static inline void kvm_etm_set_guest_trfcr(u64 trfcr_guest) {}
>> ? #endif
>> ? ? void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
>> diff --git a/arch/arm64/kernel/image-vars.h
>> b/arch/arm64/kernel/image-vars.h
>> index 5e4dc72ab1bd..a451e4f10804 100644
>> --- a/arch/arm64/kernel/image-vars.h
>> +++ b/arch/arm64/kernel/image-vars.h
>> @@ -59,6 +59,7 @@ KVM_NVHE_ALIAS(alt_cb_patch_nops);
>> ? ? /* Global kernel state accessed by nVHE hyp code. */
>> ? KVM_NVHE_ALIAS(kvm_vgic_global_state);
>> +KVM_NVHE_ALIAS(kvm_guest_trfcr);
>> ? ? /* Kernel symbols used to call panic() from nVHE hyp code (via
>> ERET). */
>> ? KVM_NVHE_ALIAS(nvhe_hyp_panic_handler);
>> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
>> index 49a13e72ddd2..c8d936ce6e2b 100644
>> --- a/arch/arm64/kvm/debug.c
>> +++ b/arch/arm64/kvm/debug.c
>> @@ -22,6 +22,7 @@
>> ????????????????? DBG_MDSCR_MDE)
>> ? ? static DEFINE_PER_CPU(u64, mdcr_el2);
>> +u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
>> ? ? /*
>> ?? * save/restore_guest_debug_regs
>> @@ -359,3 +360,28 @@ void kvm_arch_vcpu_put_debug_state_flags(struct
>> kvm_vcpu *vcpu)
>> ????? vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
>> ????? vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
>> ? }
>> +
>> +/*
>> + * Interface for the Coresight driver to use to set the value of the
>> TRFCR
>> + * register for the guest. This register controls the exclude
>> settings for trace
>> + * at different exception levels, and is used to honor the
>> exclude_host and
>> + * exclude_guest parameters from the Perf session.
>> + *
>> + * This will be used to later write TRFCR_EL1 on nVHE at guest
>> switch. For VHE,
>> + * the host trace is controlled by TRFCR_EL2 and thus we can write to
>> the
>> + * TRFCR_EL1 immediately. Because guest writes to the register are
>> trapped, the
>> + * value will persist and can't be modified. For pKVM,
>> kvm_guest_trfcr can't
>> + * be read by the hypervisor, so don't bother writing it.
>> + */
>> +void kvm_etm_set_guest_trfcr(u64 trfcr_guest)
>> +{
>> +??? if
>> (WARN_ON_ONCE(!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
>> +?????????????????????????????????? ID_AA64DFR0_EL1_TraceFilt_SHIFT)))
>> +??????? return;
>> +
>> +??? if (has_vhe())
>> +??????? write_sysreg_s(trfcr_guest, SYS_TRFCR_EL12);
>> +??? else if (!is_protected_kvm_enabled())
>> +??????? kvm_guest_trfcr[smp_processor_id()] = trfcr_guest;
> 
> smp_processor_id() could sleep in some configurations ? Should we switch
> to raw_smp_processor_id() to be safer ?
> 

I don't think so, it's #defined to raw_smp_processor_id() anyway. Unless
DEBUG_PREEMPT is on, then it's still raw_smp_processor_id() but it
validates that preemption is disabled so the value isn't stale.

We actually want that validation, so should leave it as
smp_processor_id(). I can add a comment saying that this function should
only be called with preemption disabled, but I wouldn't add any extra
validation. Every smp_processor_id() call is already checked when
DEBUG_PREEMPT is on and this one doesn't seem to be special in any way.

I also checked that the warning isn't triggered with DEBUG_PREEMPT on,
and there are also a lot of other smp_processor_id() calls on similar
paths in the Coresight driver.

> Otherwise looks good to me.
> 
> Suzuki
> 
>> +}
>> +EXPORT_SYMBOL_GPL(kvm_etm_set_guest_trfcr);
> 


From maciej.fijalkowski at intel.com  Fri Feb 23 08:45:50 2024
From: maciej.fijalkowski at intel.com (Maciej Fijalkowski)
Date: Fri, 23 Feb 2024 17:45:50 +0100
Subject: [PATCH net] net: stmmac: Complete meta data only when enabled
In-Reply-To: <CAKH8qBsCrYuT+18CsydQ5TeauRzu0Hdz7mZQ2c0W7er0KrJnkg@mail.gmail.com>
References: <20240222-stmmac_xdp-v1-1-e8d2d2b79ff0@linutronix.de>
 <CAKH8qBsCrYuT+18CsydQ5TeauRzu0Hdz7mZQ2c0W7er0KrJnkg@mail.gmail.com>
Message-ID: <ZdjLvrBhW+NIcp85@boxer>

On Thu, Feb 22, 2024 at 11:53:14AM -0800, Stanislav Fomichev wrote:
> On Thu, Feb 22, 2024 at 1:45?AM Kurt Kanzenbach <kurt at linutronix.de> wrote:
> >
> > Currently using XDP/ZC sockets on stmmac results in a kernel crash:
> >
> > |[  255.822584] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000

would be good to explain where it comes from, no?

xsk_tx_metadata_to_compl() works on meta == NULL, it does not set
compl->tx_timestamp and later on xsk_tx_metadata_complete() tries to
dereference that.

> > |[...]
> > |[  255.822764] Call trace:
> > |[  255.822766]  stmmac_tx_clean.constprop.0+0x848/0xc38
> >
> > The program counter indicates xsk_tx_metadata_complete(). However, this
> > function shouldn't be called unless metadata is actually enabled.
> >
> > Tested on imx93 without XDP, with XDP and with XDP/ZC.
> >
> > Fixes: 1347b419318d ("net: stmmac: Add Tx HWTS support to XDP ZC")
> > Suggested-by: Serge Semin <fancer.lancer at gmail.com>
> > Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
> > Tested-by: Serge Semin <fancer.lancer at gmail.com>
> > Link: https://lore.kernel.org/netdev/87r0h7wg8u.fsf at kurt.kurt.home/
> 
> Acked-by: Stanislav Fomichev <sdf at google.com>
> 
> LGTM, thanks!
> 
> > ---
> >  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 e80d77bd9f1f..8b77c0952071 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > @@ -2672,7 +2672,8 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue,
> >                         }
> >                         if (skb) {
> >                                 stmmac_get_tx_hwtstamp(priv, p, skb);
> > -                       } else {
> > +                       } else if (tx_q->xsk_pool &&
> > +                                  xp_tx_metadata_enabled(tx_q->xsk_pool)) {
> >                                 struct stmmac_xsk_tx_complete tx_compl = {
> >                                         .priv = priv,
> >                                         .desc = p,
> >
> > ---
> > base-commit: 603ead96582d85903baec2d55f021b8dac5c25d2
> > change-id: 20240222-stmmac_xdp-585ebf1680b3
> >
> > Best regards,
> > --
> > Kurt Kanzenbach <kurt at linutronix.de>
> >


From arnd at arndb.de  Fri Feb 23 09:00:07 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 23 Feb 2024 18:00:07 +0100
Subject: [GIT PULL] Arm and RISC-V SoC fixes for 6.8, part 2
Message-ID: <04be5855-9b18-4ff0-8554-8b9d626a7845@app.fastmail.com>

The following changes since commit 841c35169323cd833294798e58b9bf63fa4fa1de:

  Linux 6.8-rc4 (2024-02-11 12:18:13 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm-fixes-6.8-2

for you to fetch changes up to dcb8e53e339e534eecfd86fb21674d7eef7380eb:

  Merge tag 'renesas-fixes-for-v6.8-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into arm/fixes (2024-02-23 13:54:37 +0100)

----------------------------------------------------------------
Arm and RISC-V SoC fixes for 6.8, part 2

The Rockchip and IMX8 platforms get a number of fixes for dts files in
order to address some misconfigurations, including a regression for
USB-C support on some boards.

The other dts fixes are part of a series by Rob Herring to clean up
another class of dtc compiler warnings across all platforms, with
a few others helping out as well. With this, we can enable the warning
for the coming merge window without introducing regressions.

Conor Dooley has collected fixes for RISC-V platforms, both for the
dts files and for platofrm specific drivers.

The ep93xx platform gets a regression for for its gpio descriptors.

----------------------------------------------------------------
Alexander Stein (1):
      arm64: dts: tqma8mpql: fix audio codec iov-supply

Andy Yan (4):
      arm64: dts: rockchip: aliase sdmmc as mmc1 for Cool Pi 4B
      arm64: dts: rockchip: aliase sdmmc as mmc1 for Cool Pi CM5 EVB
      arm64: dts: rockchip: rename vcc5v0_usb30_host regulator for Cool Pi CM5 EVB
      arm64: dts: rockchip: Fix the num-lanes of pcie3x4 on Cool Pi CM5 EVB

Arnd Bergmann (7):
      Merge tag 'imx-fixes-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/fixes
      Merge tag 'v6.8-rockchip-dtsfixes1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into arm/fixes
      Merge tag 'riscv-cache-fixes-for-v6.8-rc6' of https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux into arm/fixes
      Merge tag 'riscv-firmware-fixes-for-v6.8-rc6' of https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux into arm/fixes
      Merge tag 'riscv-soc-drivers-fixes-for-v6.8-rc6' of https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux into arm/fixes
      Merge tag 'riscv-dt-fixes-for-v6.8-rc6' of https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux into arm/fixes
      Merge tag 'renesas-fixes-for-v6.8-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into arm/fixes

Chris Morgan (1):
      arm64: dts: rockchip: Correct Indiedroid Nova GPIO Names

Conor Dooley (1):
      riscv: dts: sifive: add missing #interrupt-cells to pmic

Fabio Estevam (2):
      Revert "arm64: dts: imx8mp-dhcom-pdk3: Describe the USB-C connector"
      Revert "arm64: dts: imx8mn-var-som-symphony: Describe the USB-C connector"

Geert Uytterhoeven (2):
      soc: microchip: Fix POLARFIRE_SOC_SYS_CTRL input prompt
      ARM: dts: renesas: rcar-gen2: Add missing #interrupt-cells to DA9063 nodes

Heiko Stuebner (2):
      arm64: dts: rockchip: drop unneeded status from rk3588-jaguar gpio-leds
      arm64: dts: rockchip: set num-cs property for spi on px30

Johan Jonker (1):
      arm64: dts: rockchip: Drop interrupts property from rk3328 pwm-rockchip node

Krzysztof Kozlowski (2):
      riscv: dts: starfive: replace underscores in node names
      arm64: dts: rockchip: minor rk3588 whitespace cleanup

Lad Prabhakar (1):
      cache: ax45mp_cache: Align end size to cache boundary in ax45mp_dma_cache_wback()

Lucas Stach (1):
      bus: imx-weim: fix valid range check

Marek Vasut (1):
      arm64: dts: imx8mp: Disable UART4 by default on Data Modul i.MX8M Plus eDM SBC

Nikita Shubin (1):
      ARM: ep93xx: Add terminator to gpiod_lookup_table

Rob Herring (5):
      arm64: dts: freescale: Disable interrupt_map check
      arm: dts: Fix dtc interrupt_provider warnings
      arm64: dts: Fix dtc interrupt_provider warnings
      arm: dts: Fix dtc interrupt_map warnings
      arm64: dts: qcom: Fix interrupt-map cell sizes

Samasth Norway Ananda (1):
      firmware: microchip: fix wrong sizeof argument

Sebastian Reichel (1):
      arm64: dts: rockchip: mark system power controller on rk3588-evb1

Uwe Kleine-K?nig (1):
      ARM: dts: rockchip: Drop interrupts property from pwm-rockchip nodes

 arch/arm/boot/dts/amazon/alpine.dtsi                  |  1 -
 arch/arm/boot/dts/aspeed/aspeed-g4.dtsi               | 14 --------------
 arch/arm/boot/dts/aspeed/aspeed-g5.dtsi               | 15 +--------------
 arch/arm/boot/dts/aspeed/aspeed-g6.dtsi               | 18 ++----------------
 arch/arm/boot/dts/broadcom/bcm-cygnus.dtsi            |  3 +++
 arch/arm/boot/dts/broadcom/bcm-hr2.dtsi               |  1 +
 arch/arm/boot/dts/broadcom/bcm-nsp.dtsi               |  2 ++
 .../boot/dts/intel/ixp/intel-ixp42x-gateway-7001.dts  |  2 ++
 .../dts/intel/ixp/intel-ixp42x-goramo-multilink.dts   |  2 ++
 arch/arm/boot/dts/marvell/kirkwood-l-50.dts           |  2 ++
 arch/arm/boot/dts/nuvoton/nuvoton-wpcm450.dtsi        |  2 ++
 arch/arm/boot/dts/nvidia/tegra30-apalis-v1.1.dtsi     |  1 -
 arch/arm/boot/dts/nvidia/tegra30-apalis.dtsi          |  1 -
 arch/arm/boot/dts/nvidia/tegra30-colibri.dtsi         |  1 -
 arch/arm/boot/dts/nxp/imx/imx6q-b850v3.dts            |  3 ---
 arch/arm/boot/dts/nxp/imx/imx6q-bx50v3.dtsi           |  2 +-
 arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi         |  1 -
 arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi        |  1 -
 arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi          |  1 -
 arch/arm/boot/dts/nxp/imx/imx6qdl-phytec-pfla02.dtsi  |  1 +
 .../boot/dts/nxp/imx/imx6qdl-phytec-phycore-som.dtsi  |  1 +
 arch/arm/boot/dts/nxp/imx/imx7d-pico-dwarf.dts        |  1 +
 arch/arm/boot/dts/nxp/vf/vf610-zii-dev-rev-b.dts      |  1 +
 arch/arm/boot/dts/qcom/qcom-sdx55.dtsi                |  8 ++++----
 arch/arm/boot/dts/renesas/r8a7790-lager.dts           |  1 +
 arch/arm/boot/dts/renesas/r8a7790-stout.dts           |  1 +
 arch/arm/boot/dts/renesas/r8a7791-koelsch.dts         |  1 +
 arch/arm/boot/dts/renesas/r8a7791-porter.dts          |  1 +
 arch/arm/boot/dts/renesas/r8a7792-blanche.dts         |  1 +
 arch/arm/boot/dts/renesas/r8a7793-gose.dts            |  1 +
 arch/arm/boot/dts/renesas/r8a7794-alt.dts             |  1 +
 arch/arm/boot/dts/renesas/r8a7794-silk.dts            |  1 +
 arch/arm/boot/dts/rockchip/rv1108.dtsi                |  8 --------
 arch/arm/boot/dts/st/stm32429i-eval.dts               |  1 -
 arch/arm/boot/dts/st/stm32mp157c-dk2.dts              |  1 -
 arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts     |  1 -
 arch/arm/mach-ep93xx/core.c                           |  1 +
 arch/arm64/boot/dts/amazon/alpine-v2.dtsi             |  1 -
 arch/arm64/boot/dts/amazon/alpine-v3.dtsi             |  1 -
 arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi      |  1 +
 arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi   |  1 +
 arch/arm64/boot/dts/freescale/Makefile                | 19 +++++++++++++++++++
 .../boot/dts/freescale/imx8mn-var-som-symphony.dts    | 11 +++--------
 .../boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts  |  2 +-
 arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts   | 12 ++++--------
 .../boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts  |  9 ++++++++-
 arch/arm64/boot/dts/lg/lg1312.dtsi                    |  1 -
 arch/arm64/boot/dts/lg/lg1313.dtsi                    |  1 -
 arch/arm64/boot/dts/marvell/armada-ap80x.dtsi         |  1 -
 arch/arm64/boot/dts/mediatek/mt8195-demo.dts          |  1 +
 arch/arm64/boot/dts/qcom/ipq6018.dtsi                 |  8 ++++----
 arch/arm64/boot/dts/qcom/ipq8074.dtsi                 | 16 ++++++++--------
 arch/arm64/boot/dts/renesas/ulcb-kf.dtsi              |  4 ++++
 arch/arm64/boot/dts/rockchip/px30.dtsi                |  2 ++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi              |  1 -
 .../arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts |  8 +++++---
 arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi   |  4 ++--
 arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts      |  1 +
 arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts        |  1 -
 arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts     |  8 ++++----
 arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts    |  4 ++--
 .../boot/dts/rockchip/rk3588s-indiedroid-nova.dts     | 10 +++++-----
 arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts   |  1 +
 arch/riscv/boot/dts/starfive/jh7100.dtsi              | 12 ++++++------
 arch/riscv/boot/dts/starfive/jh7110.dtsi              |  4 ++--
 drivers/bus/imx-weim.c                                |  2 +-
 drivers/cache/ax45mp_cache.c                          |  4 ++++
 drivers/firmware/microchip/mpfs-auto-update.c         |  2 +-
 drivers/soc/microchip/Kconfig                         |  2 +-
 69 files changed, 126 insertions(+), 134 deletions(-)


From daniel.lezcano at linaro.org  Fri Feb 23 09:00:51 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 23 Feb 2024 18:00:51 +0100
Subject: [PATCH v5 1/7] soc: sunxi: sram: export register 0 for THS on
 H616
In-Reply-To: <20240223160258.504a1577@donnerap.manchester.arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
 <20240219153639.179814-2-andre.przywara@arm.com>
 <2717467.mvXUDI8C0e@jernej-laptop>
 <dcd115fd-dc38-4f48-8485-9e4d64f53b4a@linaro.org>
 <20240223160258.504a1577@donnerap.manchester.arm.com>
Message-ID: <469e83f3-57ef-492b-8f27-5a052b064106@linaro.org>

On 23/02/2024 17:02, Andre Przywara wrote:
> On Thu, 22 Feb 2024 19:44:12 +0100
> Daniel Lezcano <daniel.lezcano at linaro.org> wrote:
> 
> Hi Daniel,
> 
>> On 22/02/2024 19:26, Jernej ?krabec wrote:
>>> Dne ponedeljek, 19. februar 2024 ob 16:36:33 CET je Andre Przywara napisal(a):
>>>> The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
>>>> in the SRAM control block. If bit 16 is set (the reset value), the
>>>> temperature readings of the THS are way off, leading to reports about
>>>> 200C, at normal ambient temperatures. Clearing this bits brings the
>>>> reported values down to the expected values.
>>>> The BSP code clears this bit in firmware (U-Boot), and has an explicit
>>>> comment about this, but offers no real explanation.
>>>>
>>>> Experiments in U-Boot show that register 0x0 has no effect on the SRAM C
>>>> visibility: all tested bit settings still allow full read and write
>>>> access by the CPU to the whole of SRAM C. Only bit 24 of the register at
>>>> offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling
>>>> the THS switch functionality as an SRAM region would not reflect reality.
>>>>
>>>> Since we should not rely on firmware settings, allow other code (the THS
>>>> driver) to access this register, by exporting it through the already
>>>> existing regmap. This mimics what we already do for the LDO control and
>>>> the EMAC register.
>>>>
>>>> To avoid concurrent accesses to the same register at the same time, by
>>>> the SRAM switch code and the regmap code, use the same lock to protect
>>>> the access. The regmap subsystem allows to use an existing lock, so we
>>>> just need to hook in there.
>>>>
>>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>>
>>> Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
>>>
>>> I guess this one goes through sunxi tree, right?
>>
>> I'll pick this patch along with the patch 2-6, so through the thermal
>> tree. The patch 7/7 will go indeed via the sunxi tree
> 
> many thanks for picking those up! I see them in your bleeding-edge branch,
> but are they on route for 6.9, so will you put them in -next soon? Or are
> you waiting for more ACKs?

I've enough ack. The bleeding-edge is merged with the linux-pm tree. If 
everything is going well, I will move it to the linux-next branch 
probably today or Monday



-- 
<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 maz at kernel.org  Fri Feb 23 09:02:08 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 23 Feb 2024 17:02:08 +0000
Subject: [PATCH v8 0/4] kvm: arm64: allow the VM to select DEVICE_* and NORMAL_NC for IO memory
In-Reply-To: <20240220072926.6466-1-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
Message-ID: <86jzmv2jxr.wl-maz@kernel.org>

On Tue, 20 Feb 2024 07:29:22 +0000,
<ankita at nvidia.com> wrote:
> 
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> Currently, KVM for ARM64 maps at stage 2 memory that is considered device
> with DEVICE_nGnRE memory attributes; this setting overrides (per
> ARM architecture [1]) any device MMIO mapping present at stage 1,
> resulting in a set-up whereby a guest operating system cannot
> determine device MMIO mapping memory attributes on its own but
> it is always overridden by the KVM stage 2 default.
> 
> This set-up does not allow guest operating systems to select device
> memory attributes independently from KVM stage-2 mappings
> (refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
> which turns out to be an issue in that guest operating systems
> (e.g. Linux) may request to map devices MMIO regions with memory
> attributes that guarantee better performance (e.g. gathering
> attribute - that for some devices can generate larger PCIe memory
> writes TLPs) and specific operations (e.g. unaligned transactions)
> such as the NormalNC memory type.
> 
> The default device stage 2 mapping was chosen in KVM for ARM64 since
> it was considered safer (i.e. it would not allow guests to trigger
> uncontained failures ultimately crashing the machine) but this
> turned out to be asynchronous (SError) defeating the purpose.
> 
> For these reasons, relax the KVM stage 2 device memory attributes
> from DEVICE_nGnRE to Normal-NC.
> 
> Generalizing to other devices may be problematic, however. E.g.
> GICv2 VCPU interface, which is effectively a shared peripheral, can
> allow a guest to affect another guest's interrupt distribution. Hence
> limit the change to VFIO PCI as caution. This is achieved by
> making the VFIO PCI core module set a flag that is tested by KVM
> to activate the code. This could be extended to other devices in
> the future once that is deemed safe.
> 
> [1] section D8.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
> 
> Applied over v6.8-rc5.

For the series,

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

	M.

-- 
Without deviation from the norm, progress is not possible.


From lee at kernel.org  Fri Feb 23 09:04:33 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 17:04:33 +0000
Subject: [PATCH v8 2/7] drm: atmel-hlcdc: Define XLCDC specific registers
In-Reply-To: <20240221053531.12701-3-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
 <20240221053531.12701-3-manikandan.m@microchip.com>
Message-ID: <20240223170433.GM1666215@google.com>

On Wed, 21 Feb 2024, Manikandan Muralidharan wrote:

> From: Durai Manickam KR <durai.manickamkr at microchip.com>
> 
> The register address of the XLCDC IP used in SAM9X7 SoC family
> are different from the previous HLCDC. Defining those address
> space with valid macros.
> 
> Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
> [manikandan.m at microchip.com: Remove unused macro definitions]
> Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 42 ++++++++++++++++++++

>  include/linux/mfd/atmel-hlcdc.h              | 10 +++++

Acked-by: Lee Jones <lee at kernel.org>

-- 
Lee Jones [???]


From jgg at nvidia.com  Fri Feb 23 09:05:34 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 23 Feb 2024 13:05:34 -0400
Subject: [PATCH 4/6] arm64/io: Provide a WC friendly __iowriteXX_copy()
In-Reply-To: <eea8b03c20fc49cd88b159959a589f78521ff53b.camel@linux.ibm.com>
References: <0-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <4-v1-38290193eace+5-mlx5_arm_wc_jgg@nvidia.com>
 <6d335e8701334a15b220b75d49b98d77@AcuMS.aculab.com>
 <20240222223617.GC13330@nvidia.com>
 <efc727fbb8de45c8b669b6ec174f95ce@AcuMS.aculab.com>
 <e78f6e6294c31d889ace4de3a3c3cebad04f4213.camel@linux.ibm.com>
 <20240223125852.GE13330@nvidia.com>
 <eea8b03c20fc49cd88b159959a589f78521ff53b.camel@linux.ibm.com>
Message-ID: <20240223170534.GI13330@nvidia.com>

On Fri, Feb 23, 2024 at 05:35:42PM +0100, Niklas Schnelle wrote:
> On Fri, 2024-02-23 at 08:58 -0400, Jason Gunthorpe wrote:
> > On Fri, Feb 23, 2024 at 12:38:18PM +0100, Niklas Schnelle wrote:
> > > > Although I doubt that generating long TLP from byte writes is
> > > > really necessary.
> > > 
> > > I might have gotten confused but I think these are not byte writes.
> > > Remember that the count is in terms of the number of bits sized
> > > quantities to copy so "count == 1" is 4/8 bytes here.
> > 
> > Right.
> > 
> > There seem to be two callers of this API in the kernel, one is calling
> > with a constant size and wants a large TLP
> > 
> > Another seems to want memcpy_to_io with a guarenteed 32/64 bit store.
> 
> I don't really understand how that works together with the order not
> being guaranteed. Do they use normal ioremap() and then require 32/64
> bit TLPs and don't care about the order?

Yes, I assume so. From my impression the cases looked like they were
copying to MMIO memory so order probably doesn't matter.

Jason


From maz at kernel.org  Fri Feb 23 09:07:28 2024
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 23 Feb 2024 17:07:28 +0000
Subject: [PATCH v8 3/4] kvm: arm64: set io memory s2 pte as normalnc for vfio pci device
In-Reply-To: <20240220072926.6466-4-ankita@nvidia.com>
References: <20240220072926.6466-1-ankita@nvidia.com>
	<20240220072926.6466-4-ankita@nvidia.com>
Message-ID: <86il2f2jov.wl-maz@kernel.org>

On Tue, 20 Feb 2024 07:29:25 +0000,
<ankita at nvidia.com> wrote:
> 
> From: Ankit Agrawal <ankita at nvidia.com>
> 
> To provide VM with the ability to get device IO memory with NormalNC
> property, map device MMIO in KVM for ARM64 at stage2 as NormalNC.
> Having NormalNC S2 default puts guests in control (based on [1],
> "Combining stage 1 and stage 2 memory type attributes") of device
> MMIO regions memory mappings. The rules are summarized below:
> ([(S1) - stage1], [(S2) - stage 2])
> 
> S1           |  S2           | Result
> NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
> NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
> NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
> DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>
> 
> Still this cannot be generalized to non PCI devices such as GICv2.
> There is insufficient information and uncertainity in the behavior
> of non PCI driver. A driver must indicate support using the
> new flag VM_ALLOW_ANY_UNCACHED.
> 
> Adapt KVM to make use of the flag VM_ALLOW_ANY_UNCACHED as indicator to
> activate the S2 setting to NormalNc.
> 
> [1] section D8.5.5 of DDI0487J_a_a-profile_architecture_reference_manual.pdf
> 
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Acked-by: Jason Gunthorpe <jgg at nvidia.com>
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
> Signed-off-by: Ankit Agrawal <ankita at nvidia.com>

Since people have asked for various commit message updates, I'll add
my own: for the KVM/arm64 tree, the convention for the subject line is
"KVM: arm64: Something starting with a capital".

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From lee at kernel.org  Fri Feb 23 09:11:28 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 17:11:28 +0000
Subject: (subset) [PATCH v2 2/2] dt-bindings: mfd: Convert
 atmel-flexcom to json-schema
In-Reply-To: <20240223-b4-sama5d2-flexcom-yaml-v2-2-7e96c60c7701@microchip.com>
References: <20240223-b4-sama5d2-flexcom-yaml-v2-0-7e96c60c7701@microchip.com>
 <20240223-b4-sama5d2-flexcom-yaml-v2-2-7e96c60c7701@microchip.com>
Message-ID: <170870828885.1762468.16286629959924191287.b4-ty@kernel.org>

On Fri, 23 Feb 2024 14:46:23 +0530, Balakrishnan Sambath wrote:
> Convert the Atmel flexcom device tree bindings to json schema.
> 
> 

Applied, thanks!

[2/2] dt-bindings: mfd: Convert atmel-flexcom to json-schema
      commit: fddc5d727e4503481db8dce243ad7355c40f45db

--
Lee Jones [???]



From lee at kernel.org  Fri Feb 23 09:12:31 2024
From: lee at kernel.org (Lee Jones)
Date: Fri, 23 Feb 2024 17:12:31 +0000
Subject: [PATCH v5 1/4] dt-bindings: mfd: syscon: Add
 ti,am62-usb-phy-ctrl compatible
In-Reply-To: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-1-4b5854d17d18@kernel.org>
References: <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18@kernel.org>
 <20240223-b4-for-v6-5-am62-usb-typec-dt-v5-1-4b5854d17d18@kernel.org>
Message-ID: <20240223171231.GN1666215@google.com>

On Fri, 23 Feb 2024, Roger Quadros wrote:

> Add the compatible for TI AM62 USB PHY Control register. This
> register is found in the TI AM62 WKUP_CTRL_MMR0 space [1]. It
> is used to indicate the USB PHY PLL reference clock rate and
> core voltage level to the USB controller.
> 
> [1] - https://www.ti.com/lit/pdf/spruiv7
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> Acked-by: Rob Herring <robh at kernel.org>
> ---
> Changelog:
> v5 - no change. Added Lee Jones in To list
> v4 - no change. Added Rob's Acked-by
>      https://lore.kernel.org/all/20240205135908.54656-2-rogerq at kernel.org/
> v3 - add compatibles in alphabetical order
>      https://lore.kernel.org/all/20240201120332.4811-2-rogerq at kernel.org/
> v2 - New patch
> ---
>  Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
> index 084b5c2a2a3c..9437705af92f 100644
> --- a/Documentation/devicetree/bindings/mfd/syscon.yaml
> +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
> @@ -72,6 +72,7 @@ properties:
>                - rockchip,rk3588-qos
>                - rockchip,rv1126-qos
>                - starfive,jh7100-sysmain
> +              - ti,am62-usb-phy-ctrl
>                - ti,am654-dss-oldi-io-ctrl

Doesn't apply.  Please rebase on tomorrow's -next.

-- 
Lee Jones [???]


From francesco at dolcini.it  Fri Feb 23 09:19:01 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Fri, 23 Feb 2024 18:19:01 +0100
Subject: [PATCH v1] ARM: dts: imx7: remove DSI port endpoints
In-Reply-To: <20240216104255.21052-1-francesco@dolcini.it>
References: <20240216104255.21052-1-francesco@dolcini.it>
Message-ID: <20240223171901.GA22584@francesco-nb>

On Fri, Feb 16, 2024 at 11:42:55AM +0100, Francesco Dolcini wrote:
> From: Francesco Dolcini <francesco.dolcini at toradex.com>
> 
> This fixes the display not working on colibri imx7, the driver fails to
> load with the following error:
> 
>   mxsfb 30730000.lcdif: error -ENODEV: Cannot connect bridge
> 
> NXP i.MX7 LCDIF is connected to both the Parallel LCD Display and to a
> MIPI DSI IP block, currently it's not possible to describe the
> connection to both.
> 
> Remove the port endpoint from the SOC dtsi to prevent regressions, this
> would need to be defined on the board DTS.
> 
> Reported-by: Hiago De Franco <hiagofranco at gmail.com>
> Closes: https://lore.kernel.org/r/34yzygh3mbwpqr2re7nxmhyxy3s7qmqy4vhxvoyxnoguktriur at z66m7gvpqlia/
> Fixes: edbbae7fba49 ("ARM: dts: imx7: add MIPI-DSI support")
> Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>

Hello Shawn, what do you plan to do with this?

This fixes a regression from v6.8-rc1 and would be nice to have it into
the final v6.8.

Francesco



From y.varakala at phytec.de  Fri Feb 23 09:22:07 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Fri, 23 Feb 2024 18:22:07 +0100
Subject: [PATCH v3 0/4] Update of phyBOARD-Pollux-i.MX8MP
Message-ID: <20240223172211.6592-1-y.varakala@phytec.de>

Hello,

These patches will update the imx8mp-phyboard-pollux devicetree
with the Muxing and RTC properties.
 
Thankyou,
yashwanth.

Changes in v3:
-Rebased on linux-next/master to avoid conflicts.

Changes in v2: 
-Corrected the commit message.
-Corrected the authorship.

Dominik Haller (1):
  arm64: dts: imx8mp-phyboard-pollux: Disable pull-up for CD GPIO

Teresa Remmet (1):
  arm64: dts: imx8mp-phyboard-pollux: Reduce drive strength for eqos tx
    lines

Yannic Moog (1):
  arm64: dts: imx8mp-phyboard-pollux: Set debug uart muxing to 0x140

Yashwanth Varakala (1):
  arm64: dts: imx8mp-phyboard-pollux: Add and update rtc devicetree node

 .../freescale/imx8mp-phyboard-pollux-rdk.dts  | 33 ++++++++++++++-----
 .../dts/freescale/imx8mp-phycore-som.dtsi     |  1 -
 2 files changed, 24 insertions(+), 10 deletions(-)

-- 
2.34.1



From y.varakala at phytec.de  Fri Feb 23 09:22:08 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Fri, 23 Feb 2024 18:22:08 +0100
Subject: [PATCH v3 1/4] arm64: dts: imx8mp-phyboard-pollux: Add and update rtc devicetree node
In-Reply-To: <20240223172211.6592-1-y.varakala@phytec.de>
References: <20240223172211.6592-1-y.varakala@phytec.de>
Message-ID: <20240223172211.6592-2-y.varakala@phytec.de>

The interrupt of the RTC is connected on the carrier board
phyBOARD-i.MX8MP-Pollux.

RTC trickle-charger devicetree property is dependent on the
phyboard-pollux design.

Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
---
Changes in v2:
-Corrected the commit message.

 .../dts/freescale/imx8mp-phyboard-pollux-rdk.dts  | 15 +++++++++++++++
 .../boot/dts/freescale/imx8mp-phycore-som.dtsi    |  1 -
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index 9e8afceba65e..894905fb42b0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -191,6 +191,15 @@ ldb_lvds_ch1: endpoint {
 	};
 };
 
+&rv3028 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rtc>;
+	interrupt-parent = <&gpio4>;
+	interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+	wakeup-source;
+	trickle-resistor-ohms = <3000>;
+};
+
 &snvs_pwrkey {
 	status = "okay";
 };
@@ -369,6 +378,12 @@ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40
 		>;
 	};
 
+	pinctrl_rtc: rtcgrp {
+		fsl,pins = <
+			MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19	0x1C0
+		>;
+	};
+
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
 			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x40
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
index c976c3b6cbc6..e6ffa6a6b68b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
@@ -175,7 +175,6 @@ eeprom at 51 {
 	rv3028: rtc at 52 {
 		compatible = "microcrystal,rv3028";
 		reg = <0x52>;
-		trickle-resistor-ohms = <3000>;
 	};
 };
 
-- 
2.34.1



From y.varakala at phytec.de  Fri Feb 23 09:22:10 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Fri, 23 Feb 2024 18:22:10 +0100
Subject: [PATCH v3 3/4] arm64: dts: imx8mp-phyboard-pollux: Reduce drive strength for eqos tx lines
In-Reply-To: <20240223172211.6592-1-y.varakala@phytec.de>
References: <20240223172211.6592-1-y.varakala@phytec.de>
Message-ID: <20240223172211.6592-4-y.varakala@phytec.de>

From: Teresa Remmet <t.remmet at phytec.de>

Reduce drive strength on eqos tx lines for signal quality improvements.

Signed-off-by: Teresa Remmet <t.remmet at phytec.de>
Signed-off-by: Benjamin Hahn <B.Hahn at phytec.de>
Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
---
Changes in v2:
-Corrected the Authorship.

 .../dts/freescale/imx8mp-phyboard-pollux-rdk.dts     | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index f95af797531a..e85176d23376 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -310,12 +310,12 @@ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2		0x90
 			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3		0x90
 			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x90
 			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL		0x90
-			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x16
-			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x16
-			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x16
-			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x16
-			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x16
-			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x16
+			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x12
+			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x12
+			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x12
+			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x12
+			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x12
+			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x12
 			MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20			0x10
 		>;
 	};
-- 
2.34.1



From y.varakala at phytec.de  Fri Feb 23 09:22:11 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Fri, 23 Feb 2024 18:22:11 +0100
Subject: [PATCH v3 4/4] arm64: dts: imx8mp-phyboard-pollux: Disable pull-up for CD GPIO
In-Reply-To: <20240223172211.6592-1-y.varakala@phytec.de>
References: <20240223172211.6592-1-y.varakala@phytec.de>
Message-ID: <20240223172211.6592-5-y.varakala@phytec.de>

From: Dominik Haller <d.haller at phytec.de>

Removes the pull-up resistor from the pad's settings to keep it
consistent for all boards. We have pull-ups in hardware on all boards so we
don't need to set the additional one from the iomux controller.

Signed-off-by: Dominik Haller <d.haller at phytec.de>
Signed-off-by: Benjamin Hahn <B.Hahn at phytec.de>
Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
---
Changes in v2:
-Corrected the Authorship.

 arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index e85176d23376..7ed843d6ea72 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -408,7 +408,7 @@ MX8MP_IOMUXC_SAI3_RXD__UART2_DCE_RTS	0x140
 
 	pinctrl_usdhc2_pins: usdhc2-gpiogrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12	0x1c4
+			MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12	0x40
 		>;
 	};
 
-- 
2.34.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:22:50 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:52:50 +0530
Subject: [PATCH v4 02/39] dt-bindings: atmel-sysreg: add sam9x7
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172250.671606-1-varshini.rajendran@microchip.com>

Add RAM controller & SFR DT bindings.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
Changes in v4:
- Updated Acked-by tag
---
 Documentation/devicetree/bindings/arm/atmel-sysregs.txt | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
index 67a66bf74895..1339298203c6 100644
--- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
@@ -11,7 +11,8 @@ PIT Timer required properties:
   shared across all System Controller members.
 
 PIT64B Timer required properties:
-- compatible: Should be "microchip,sam9x60-pit64b"
+- compatible: Should be "microchip,sam9x60-pit64b" or
+			"microchip,sam9x7-pit64b", "microchip,sam9x60-pit64b"
 - reg: Should contain registers location and length
 - interrupts: Should contain interrupt for PIT64B timer
 - clocks: Should contain the available clock sources for PIT64B timer.
@@ -31,7 +32,8 @@ RAMC SDRAM/DDR Controller required properties:
 			"atmel,at91sam9g45-ddramc",
 			"atmel,sama5d3-ddramc",
 			"microchip,sam9x60-ddramc",
-			"microchip,sama7g5-uddrc"
+			"microchip,sama7g5-uddrc",
+			"microchip,sam9x7-ddramc", "atmel,sama5d3-ddramc".
 - reg: Should contain registers location and length
 
 Examples:
@@ -63,6 +65,7 @@ required properties:
 	"atmel,<chip>-sfrbu", "syscon"
   <chip> can be "sama5d3", "sama5d4" or "sama5d2".
   It also can be "microchip,sam9x60-sfr", "syscon".
+  It also can be "microchip,sam9x7-sfr", "microchip,sam9x60-sfr", "syscon".
 - reg: Should contain registers location and length
 
 	sfr at f0038000 {
-- 
2.25.1



From y.varakala at phytec.de  Fri Feb 23 09:22:09 2024
From: y.varakala at phytec.de (Yashwanth Varakala)
Date: Fri, 23 Feb 2024 18:22:09 +0100
Subject: [PATCH v3 2/4] arm64: dts: imx8mp-phyboard-pollux: Set debug uart muxing to 0x140
In-Reply-To: <20240223172211.6592-1-y.varakala@phytec.de>
References: <20240223172211.6592-1-y.varakala@phytec.de>
Message-ID: <20240223172211.6592-3-y.varakala@phytec.de>

From: Yannic Moog <y.moog at phytec.de>

Set Pull Resistors Enable bit to put signal into a defined state.

Signed-off-by: Yannic Moog <y.moog at phytec.de>
Signed-off-by: Benjamin Hahn <B.Hahn at phytec.de>
Signed-off-by: Yashwanth Varakala <y.varakala at phytec.de>
---
Changes in v2:
-Corrected the Authorship.

 arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index 894905fb42b0..f95af797531a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -386,8 +386,8 @@ MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19	0x1C0
 
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x40
-			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x40
+			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x140
+			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x140
 		>;
 	};
 
-- 
2.34.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:23:10 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:53:10 +0530
Subject: [PATCH v4 03/39] dt-bindings: crypto: add sam9x7 in Atmel AES
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172310.671661-1-varshini.rajendran@microchip.com>

Add DT bindings for atmel AES.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Acked-by: Rob Herring <robh at kernel.org>
---
Changes in v4:
- Updated Acked-by tag
---
 .../devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml   | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml
index 0b7383b3106b..7dc0748444fd 100644
--- a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml
+++ b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml
@@ -12,7 +12,11 @@ maintainers:
 
 properties:
   compatible:
-    const: atmel,at91sam9g46-aes
+    oneOf:
+      - const: atmel,at91sam9g46-aes
+      - items:
+          - const: microchip,sam9x7-aes
+          - const: atmel,at91sam9g46-aes
 
   reg:
     maxItems: 1
-- 
2.25.1



From william.zhang at broadcom.com  Fri Feb 23 09:25:09 2024
From: william.zhang at broadcom.com (William Zhang)
Date: Fri, 23 Feb 2024 09:25:09 -0800
Subject: [PATCH v6 12/13] mtd: rawnand: brcmnand: Add support for getting
 ecc setting from strap
In-Reply-To: <20240223101852.005da3ad@xps-13>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
 <20240223034758.13753-13-william.zhang@broadcom.com>
 <20240223101852.005da3ad@xps-13>
Message-ID: <db1c1e68-40e2-4c6c-afb2-2fb591883a46@broadcom.com>

Hi Miquel,

On 2/23/24 01:18, Miquel Raynal wrote:
> Hi William,
> 
> william.zhang at broadcom.com wrote on Thu, 22 Feb 2024 19:47:57 -0800:
> 
>> BCMBCA broadband SoC based board design does not specify ecc setting in
>> dts but rather use the SoC NAND strap info to obtain the ecc strength
>> and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
>> this purpose and update driver to support this option. However these two
>> options can not be used at the same time.
>>
>> Signed-off-by: William Zhang <william.zhang at broadcom.com>
>> Reviewed-by: David Regan <dregan at broadcom.com>
>>
> 
> FYI I did not receive patches 7, 8, 9, which makes the series numbering
> very odd.
> 
I was using the get maintainer script mainly and it sends to the linux 
MTD list.  I will add your email directly next time.
>> ---
>>
>> Changes in v6:
>> - Combine the ecc step size and ecc strength into one get function
>> - Treat it as error condition if both brcm,nand-ecc-use-strap and nand
>> ecc dts properties are set
>> - Add intermediate steps to get the sector size bitfield
>>
>> Changes in v5: None
>> Changes in v4:
>> - Update the comments for ecc setting selection
>>
>> Changes in v3: None
>> Changes in v2:
>> - Minor cosmetic fixes
>>
>>   drivers/mtd/nand/raw/brcmnand/brcmnand.c | 83 ++++++++++++++++++++++--
>>   1 file changed, 77 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
>> index ef7d340475be..e8ffc283b365 100644
>> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
>> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
>> @@ -1038,6 +1038,22 @@ static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl)
>>   		return -1;
>>   }
>>   
>> +static int brcmnand_get_sector_size_1k(struct brcmnand_host *host)
>> +{
>> +	struct brcmnand_controller *ctrl = host->ctrl;
>> +	int sector_size_bit = brcmnand_sector_1k_shift(ctrl);
>> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
>> +						  BRCMNAND_CS_ACC_CONTROL);
>> +	u32 acc_control;
>> +
>> +	if (sector_size_bit < 0)
>> +		return 0;
>> +
>> +	acc_control = nand_readreg(ctrl, acc_control_offs);
>> +
>> +	return (acc_control & BIT(sector_size_bit)) >> sector_size_bit;
> 
> FIELD_PREP, FIELD_GET, *please*.
You probably missed my reply to your comments on the same patch in v5. 
Here is the link for the post in case it lost in your email:
https://lore.kernel.org/lkml/c145b90c-e9f0-4d82-94cc-baf7bfda5954 at gmail.com/T/#m1d911d2f119f3bd345c575a81b60bc2bd8c461eb

The mask is not constant here and cause build errors.
> 
>> +}
>> +
>>   static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
>>   {
>>   	struct brcmnand_controller *ctrl = host->ctrl;
>> @@ -1055,6 +1071,43 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
>>   	nand_writereg(ctrl, acc_control_offs, tmp);
>>   }
>>   
>> +static int brcmnand_get_spare_size(struct brcmnand_host *host)
>> +{
>> +	struct brcmnand_controller *ctrl = host->ctrl;
>> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
>> +						  BRCMNAND_CS_ACC_CONTROL);
>> +	u32 acc = nand_readreg(ctrl, acc_control_offs);
>> +
>> +	return (acc & brcmnand_spare_area_mask(ctrl));
>> +}
>> +
>> +static void brcmnand_get_ecc_settings(struct brcmnand_host *host, struct nand_chip *chip)
>> +{
>> +	struct brcmnand_controller *ctrl = host->ctrl;
>> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
>> +						  BRCMNAND_CS_ACC_CONTROL);
>> +	int sector_size_1k = brcmnand_get_sector_size_1k(host);
>> +	int spare_area_size, ecc_level;
>> +	u32 acc;
>> +
>> +	spare_area_size = brcmnand_get_spare_size(host);
>> +	acc = nand_readreg(ctrl, acc_control_offs);
>> +	ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl->ecc_level_shift;
> 
> ditto
> 
>> +	if (sector_size_1k)
>> +		chip->ecc.strength = ecc_level * 2;
>> +	else if (spare_area_size == 16 && ecc_level == 15)
>> +		chip->ecc.strength = 1; /* hamming */
>> +	else
>> +		chip->ecc.strength = ecc_level;
>> +
>> +	if (chip->ecc.size == 0) {
>> +		if (sector_size_1k < 0)
> 
> Should be <= 0 I guess
> 
>> +			chip->ecc.size = 512;
>> +		else
>> +			chip->ecc.size = 512 << sector_size_1k;
> 
> What is this? Are you expecting sector_size_1k to be 0 or 1
> and thus multiply 512 by two?
> 
Explained in the same post above. Sector_size_1k can be negative number 
for error condition where we default to 512 step size. Otherwise 0 for 
512 and 1 for 1K which the above shift takes care of.
> Please just use:
> 			chip->ecc.size = SZ_1K;
> 			
>> +	}
>> +}
>> +
>>   /***********************************************************************
>>    * CS_NAND_SELECT
>>    ***********************************************************************/
>> @@ -2625,19 +2678,37 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
>>   		nanddev_get_memorg(&chip->base);
>>   	struct brcmnand_controller *ctrl = host->ctrl;
>>   	struct brcmnand_cfg *cfg = &host->hwcfg;
>> -	char msg[128];
>> +	struct device_node *np = nand_get_flash_node(chip);
>>   	u32 offs, tmp, oob_sector;
>> +	bool use_strap = false;
>> +	char msg[128];
>>   	int ret;
>>   
>>   	memset(cfg, 0, sizeof(*cfg));
>> +	use_strap = of_property_read_bool(np, "brcm,nand-ecc-use-strap");
>>   
>> -	ret = of_property_read_u32(nand_get_flash_node(chip),
>> -				   "brcm,nand-oob-sector-size",
>> +	/*
>> +	 * Either nand-ecc-xxx or brcm,nand-ecc-use-strap can be set. Error out
>> +	 * if both exist.
>> +	 */
> 
> Thanks for the comment but I think the error string is clear enough.
> 
>> +	if (chip->ecc.strength && use_strap) {
>> +		dev_err(ctrl->dev,
>> +			"nand ecc and strap ecc settings can't be set at the same time\n");
> 
> Can we change to
> "ECC strap and DT ECC configuration properties are mutually exclusive"
> 
Will do.

>> +		return -EINVAL;
>> +	}
>> +
>> +	if (use_strap)
>> +		brcmnand_get_ecc_settings(host, chip);
>> +
>> +	ret = of_property_read_u32(np, "brcm,nand-oob-sector-size",
>>   				   &oob_sector);
>>   	if (ret) {
>> -		/* Use detected size */
>> -		cfg->spare_area_size = mtd->oobsize /
>> -					(mtd->writesize >> FC_SHIFT);
>> +		if (use_strap)
>> +			cfg->spare_area_size = brcmnand_get_spare_size(host);
>> +		else
>> +			/* Use detected size */
>> +			cfg->spare_area_size = mtd->oobsize /
>> +						(mtd->writesize >> FC_SHIFT);
>>   	} else {
>>   		cfg->spare_area_size = oob_sector;
>>   	}
> 
> The rest of the series looks good to me.
> 
> Thanks,
> Miqu?l
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4212 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240223/a894bd60/attachment-0001.p7s>

From varshini.rajendran at microchip.com  Fri Feb 23 09:24:59 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:54:59 +0530
Subject: [PATCH v4 06/39] dt-bindings: i2c: at91: Add sam9x7 compatible string
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172459.671832-1-varshini.rajendran@microchip.com>

Add compatible string for sam9x7.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Made sam9x7 compatible as an enum with sama7g5 compatible
- Removed the sam9x7 compatible from allOf section as it was not needed
  like pointed out
---
 Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml
index 6adedd3ec399..b1c13bab2472 100644
--- a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml
@@ -25,7 +25,9 @@ properties:
               - atmel,sama5d2-i2c
               - microchip,sam9x60-i2c
       - items:
-          - const: microchip,sama7g5-i2c
+          - enum:
+              - microchip,sama7g5-i2c
+              - microchip,sam9x7-i2c
           - const: microchip,sam9x60-i2c
 
   reg:
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:23:58 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:53:58 +0530
Subject: [PATCH v4 04/39] dt-bindings: crypto: add sam9x7 in Atmel SHA
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172358.671722-1-varshini.rajendran@microchip.com>

Add DT bindings for atmel SHA.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Acked-by: Rob Herring <robh at kernel.org>
---
Changes in v4:
- Updated Acked-by tag
---
 .../devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml   | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml
index ee2ffb034325..d378c53314dd 100644
--- a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml
+++ b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml
@@ -12,7 +12,11 @@ maintainers:
 
 properties:
   compatible:
-    const: atmel,at91sam9g46-sha
+    oneOf:
+      - const: atmel,at91sam9g46-sha
+      - items:
+          - const: microchip,sam9x7-sha
+          - const: atmel,at91sam9g46-sha
 
   reg:
     maxItems: 1
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:24:45 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:54:45 +0530
Subject: [PATCH v4 05/39] dt-bindings: crypto: add sam9x7 in Atmel TDES
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172445.671783-1-varshini.rajendran@microchip.com>

Add DT bindings for atmel TDES.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
Changes in v4:
- Updated Acked-by tag
---
 .../devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml  | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml
index 3d6ed24b1b00..6a441f79efea 100644
--- a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml
+++ b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml
@@ -12,7 +12,11 @@ maintainers:
 
 properties:
   compatible:
-    const: atmel,at91sam9g46-tdes
+    oneOf:
+      - const: atmel,at91sam9g46-tdes
+      - items:
+          - const: microchip,sam9x7-tdes
+          - const: atmel,at91sam9g46-tdes
 
   reg:
     maxItems: 1
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:25:20 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:55:20 +0530
Subject: [PATCH v4 08/39] dt-bindings: atmel-nand: add microchip,sam9x7-pmecc
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172520.671940-1-varshini.rajendran@microchip.com>

Add microchip,sam9x7-pmecc to DT bindings documentation.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
 Documentation/devicetree/bindings/mtd/atmel-nand.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
index 50645828ac20..4598930851d9 100644
--- a/Documentation/devicetree/bindings/mtd/atmel-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
@@ -56,6 +56,7 @@ Required properties:
 	"atmel,sama5d4-pmecc"
 	"atmel,sama5d2-pmecc"
 	"microchip,sam9x60-pmecc"
+	"microchip,sam9x7-pmecc", "atmel,at91sam9g45-pmecc"
 - reg: should contain 2 register ranges. The first one is pointing to the PMECC
        block, and the second one to the PMECC_ERRLOC block.
 
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:25:59 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:55:59 +0530
Subject: [PATCH v4 12/39] dt-bindings: serial: atmel,at91-usart: add compatible for sam9x7.
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172559.672142-1-varshini.rajendran@microchip.com>

Add sam9x7 compatible to DT bindings documentation.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Fixed the wrong addition of compatible
- Added further compatibles that are possible correct (as per DT)
---
 .../devicetree/bindings/serial/atmel,at91-usart.yaml | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml b/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
index 65cb2e5c5eee..30af537e8e81 100644
--- a/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
+++ b/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
@@ -23,11 +23,17 @@ properties:
           - const: atmel,at91sam9260-dbgu
           - const: atmel,at91sam9260-usart
       - items:
-          - const: microchip,sam9x60-usart
+          - enum:
+              - microchip,sam9x60-usart
+              - microchip,sam9x7-usart
           - const: atmel,at91sam9260-usart
       - items:
-          - const: microchip,sam9x60-dbgu
-          - const: microchip,sam9x60-usart
+          - enum:
+              - microchip,sam9x60-dbgu
+              - microchip,sam9x7-dbgu
+          - enum:
+              - microchip,sam9x60-usart
+              - microchip,sam9x7-usart
           - const: atmel,at91sam9260-dbgu
           - const: atmel,at91sam9260-usart
 
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:25:40 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:55:40 +0530
Subject: [PATCH v4 10/39] dt-bindings: rng: atmel,at91-trng: add sam9x7 TRNG
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172540.672044-1-varshini.rajendran@microchip.com>

Add compatbile for Microchip sam9x7 TRNG.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
Changes in v4:
- Updated Reviewed-by tag
---
 Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
index 3ce45456d867..b38f8252342e 100644
--- a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
+++ b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
@@ -21,6 +21,10 @@ properties:
           - enum:
               - microchip,sama7g5-trng
           - const: atmel,at91sam9g45-trng
+      - items:
+          - enum:
+              - microchip,sam9x7-trng
+          - const: microchip,sam9x60-trng
 
   clocks:
     maxItems: 1
-- 
2.25.1



From andre.przywara at arm.com  Fri Feb 23 09:25:51 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 23 Feb 2024 17:25:51 +0000
Subject: [PATCH v5 1/7] soc: sunxi: sram: export register 0 for THS on
 H616
In-Reply-To: <469e83f3-57ef-492b-8f27-5a052b064106@linaro.org>
References: <20240219153639.179814-1-andre.przywara@arm.com>
	<20240219153639.179814-2-andre.przywara@arm.com>
	<2717467.mvXUDI8C0e@jernej-laptop>
	<dcd115fd-dc38-4f48-8485-9e4d64f53b4a@linaro.org>
	<20240223160258.504a1577@donnerap.manchester.arm.com>
	<469e83f3-57ef-492b-8f27-5a052b064106@linaro.org>
Message-ID: <20240223172551.57b7e066@donnerap.manchester.arm.com>

On Fri, 23 Feb 2024 18:00:51 +0100
Daniel Lezcano <daniel.lezcano at linaro.org> wrote:

Hi Daniel,

> On 23/02/2024 17:02, Andre Przywara wrote:
> > On Thu, 22 Feb 2024 19:44:12 +0100
> > Daniel Lezcano <daniel.lezcano at linaro.org> wrote:
> > 
> > Hi Daniel,
> >   
> >> On 22/02/2024 19:26, Jernej ?krabec wrote:  
> >>> Dne ponedeljek, 19. februar 2024 ob 16:36:33 CET je Andre Przywara napisal(a):  
> >>>> The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
> >>>> in the SRAM control block. If bit 16 is set (the reset value), the
> >>>> temperature readings of the THS are way off, leading to reports about
> >>>> 200C, at normal ambient temperatures. Clearing this bits brings the
> >>>> reported values down to the expected values.
> >>>> The BSP code clears this bit in firmware (U-Boot), and has an explicit
> >>>> comment about this, but offers no real explanation.
> >>>>
> >>>> Experiments in U-Boot show that register 0x0 has no effect on the SRAM C
> >>>> visibility: all tested bit settings still allow full read and write
> >>>> access by the CPU to the whole of SRAM C. Only bit 24 of the register at
> >>>> offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling
> >>>> the THS switch functionality as an SRAM region would not reflect reality.
> >>>>
> >>>> Since we should not rely on firmware settings, allow other code (the THS
> >>>> driver) to access this register, by exporting it through the already
> >>>> existing regmap. This mimics what we already do for the LDO control and
> >>>> the EMAC register.
> >>>>
> >>>> To avoid concurrent accesses to the same register at the same time, by
> >>>> the SRAM switch code and the regmap code, use the same lock to protect
> >>>> the access. The regmap subsystem allows to use an existing lock, so we
> >>>> just need to hook in there.
> >>>>
> >>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>  
> >>>
> >>> Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> >>>
> >>> I guess this one goes through sunxi tree, right?  
> >>
> >> I'll pick this patch along with the patch 2-6, so through the thermal
> >> tree. The patch 7/7 will go indeed via the sunxi tree  
> > 
> > many thanks for picking those up! I see them in your bleeding-edge branch,
> > but are they on route for 6.9, so will you put them in -next soon? Or are
> > you waiting for more ACKs?  
> 
> I've enough ack. The bleeding-edge is merged with the linux-pm tree. If 
> everything is going well, I will move it to the linux-next branch 
> probably today or Monday

thanks for the quick reply, that's great to hear. All fine then!

Thanks,
Andre



From varshini.rajendran at microchip.com  Fri Feb 23 09:25:09 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:55:09 +0530
Subject: [PATCH v4 07/39] dt-bindings: atmel-ssc: add microchip,sam9x7-ssc
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172509.671880-1-varshini.rajendran@microchip.com>

Add microchip,sam9x7-ssc to DT bindings documentation.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
Changes in v4:
- Updated Acked-by tag
---
 Documentation/devicetree/bindings/misc/atmel-ssc.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt
index f9fb412642fe..894875826de9 100644
--- a/Documentation/devicetree/bindings/misc/atmel-ssc.txt
+++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt
@@ -2,6 +2,7 @@
 
 Required properties:
 - compatible: "atmel,at91rm9200-ssc" or "atmel,at91sam9g45-ssc"
+	       or "microchip,sam9x7-ssc", "atmel,at91sam9g45-ssc"
 	- atmel,at91rm9200-ssc: support pdc transfer
 	- atmel,at91sam9g45-ssc: support dma transfer
 - reg: Should contain SSC registers location and length
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:25:31 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:55:31 +0530
Subject: [PATCH v4 09/39] dt-bindings: pinctrl: at91: add sam9x7
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172531.671993-1-varshini.rajendran@microchip.com>

Add device tree binding for SAM9X7 pin controller.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
Changes in v4:
- Updated Acked-by tag
---
 .../devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt          | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
index e8abbdad7b5d..0aa1a53012d6 100644
--- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
@@ -20,6 +20,7 @@ such as pull-up, multi drive, etc.
 Required properties for iomux controller:
 - compatible: "atmel,at91rm9200-pinctrl" or "atmel,at91sam9x5-pinctrl"
 		or "atmel,sama5d3-pinctrl" or "microchip,sam9x60-pinctrl"
+		or "microchip,sam9x7-pinctrl", "microchip,sam9x60-pinctrl"
 - atmel,mux-mask: array of mask (periph per bank) to describe if a pin can be
   configured in this periph mode. All the periph and bank need to be describe.
 
@@ -120,6 +121,7 @@ Some requirements for using atmel,at91rm9200-pinctrl binding:
 For each bank the required properties are:
 - compatible: "atmel,at91sam9x5-gpio" or "atmel,at91rm9200-gpio" or
   "microchip,sam9x60-gpio"
+  or "microchip,sam9x7-gpio", "microchip,sam9x60-gpio", "atmel,at91rm9200-gpio"
 - reg: physical base address and length of the controller's registers
 - interrupts: interrupt outputs from the controller
 - interrupt-controller: marks the device node as an interrupt controller
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:26:19 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:56:19 +0530
Subject: [PATCH v4 14/39] dt-bindings: pwm: at91: Add sam9x7 compatible strings list
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172619.672262-1-varshini.rajendran@microchip.com>

Add compatible strings list for SAM9X7.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
 Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml b/Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml
index d84268b59784..96cd6f3c3546 100644
--- a/Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml
@@ -25,6 +25,9 @@ properties:
       - items:
           - const: microchip,sama7g5-pwm
           - const: atmel,sama5d2-pwm
+      - items:
+          - const: microchip,sam9x7-pwm
+          - const: microchip,sam9x60-pwm
 
   reg:
     maxItems: 1
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:26:08 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:56:08 +0530
Subject: [PATCH v4 13/39] ASoC: dt-bindings: atmel-classd: add sam9x7 compatible
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172608.672190-1-varshini.rajendran@microchip.com>

Add sam9x7 compatible to DT bindings documentation.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Changed the subject prefix matching the subsystem
- Removed unwanted '-items' from the syntax
---
 .../devicetree/bindings/sound/atmel,sama5d2-classd.yaml    | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/atmel,sama5d2-classd.yaml b/Documentation/devicetree/bindings/sound/atmel,sama5d2-classd.yaml
index 43d04702ac2d..ae3162fcfe02 100644
--- a/Documentation/devicetree/bindings/sound/atmel,sama5d2-classd.yaml
+++ b/Documentation/devicetree/bindings/sound/atmel,sama5d2-classd.yaml
@@ -18,7 +18,12 @@ description:
 
 properties:
   compatible:
-    const: atmel,sama5d2-classd
+    oneOf:
+      - items:
+          - const: atmel,sama5d2-classd
+      - items:
+          - const: microchip,sam9x7-classd
+          - const: atmel,sama5d2-classd
 
   reg:
     maxItems: 1
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:25:52 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:55:52 +0530
Subject: [PATCH v4 11/39] dt-bindings: rtt: at91rm9260: add sam9x7 compatible
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172552.672094-1-varshini.rajendran@microchip.com>

Add compatible for SAM9X7 RTT.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Made sam9x7 compatible as an enum with sam9x60 compatible as
  suggested
---
 .../devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml        | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml b/Documentation/devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml
index b80b85c394ac..a7f6c1d1a08a 100644
--- a/Documentation/devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml
+++ b/Documentation/devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml
@@ -19,7 +19,9 @@ properties:
       - items:
           - const: atmel,at91sam9260-rtt
       - items:
-          - const: microchip,sam9x60-rtt
+          - enum:
+              - microchip,sam9x60-rtt
+              - microchip,sam9x7-rtt
           - const: atmel,at91sam9260-rtt
       - items:
           - const: microchip,sama7g5-rtt
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:26:27 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:56:27 +0530
Subject: [PATCH v4 15/39] dt-bindings: watchdog: sama5d4-wdt: add compatible for sam9x7-wdt
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172627.672316-1-varshini.rajendran@microchip.com>

Add compatible microchip,sam9x7-wdt to DT bindings documentation.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Removed unnecessary '-items' from the syntax
- Changed enum as const as per the comment
---
 .../bindings/watchdog/atmel,sama5d4-wdt.yaml         | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/watchdog/atmel,sama5d4-wdt.yaml b/Documentation/devicetree/bindings/watchdog/atmel,sama5d4-wdt.yaml
index 816f85ee2c77..cdf87db36183 100644
--- a/Documentation/devicetree/bindings/watchdog/atmel,sama5d4-wdt.yaml
+++ b/Documentation/devicetree/bindings/watchdog/atmel,sama5d4-wdt.yaml
@@ -14,10 +14,14 @@ allOf:
 
 properties:
   compatible:
-    enum:
-      - atmel,sama5d4-wdt
-      - microchip,sam9x60-wdt
-      - microchip,sama7g5-wdt
+    oneOf:
+      - enum:
+          - atmel,sama5d4-wdt
+          - microchip,sam9x60-wdt
+          - microchip,sama7g5-wdt
+      - items:
+          - const: microchip,sam9x7-wdt
+          - const: microchip,sam9x60-wdt
 
   reg:
     maxItems: 1
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:26:38 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:56:38 +0530
Subject: [PATCH v4 16/39] spi: dt-bindings: atmel,at91rm9200-spi: remove 9x60 compatible from list
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172638.672366-1-varshini.rajendran@microchip.com>

Remove microchip,sam9x60-spi compatible from the list as the driver used
has the compatible atmel,at91rm9200-spi and sam9x60 devices also use the
same compatible as fallback. So removing the microchip,sam9x60-spi
compatible from the list since it is not needed.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Elaborated the explanation in the commit message to justify the patch
---
 Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml b/Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml
index 58367587bfbc..32e7c14033c2 100644
--- a/Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml
+++ b/Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml
@@ -22,7 +22,6 @@ properties:
           - const: atmel,at91rm9200-spi
       - items:
           - const: microchip,sam9x7-spi
-          - const: microchip,sam9x60-spi
           - const: atmel,at91rm9200-spi
 
   reg:
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:27:41 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:57:41 +0530
Subject: [PATCH v4 22/39] dt-bindings: clk: at91: add sam9x7 clock controller
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172741.672694-1-varshini.rajendran@microchip.com>

Add bindings for SAM9X7's pmc.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Added the sam9x7 compatible in the allOf section
---
 .../devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml         | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml b/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml
index c1bdcd9058ed..eb5cd33ea9aa 100644
--- a/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml
+++ b/Documentation/devicetree/bindings/clock/atmel,at91rm9200-pmc.yaml
@@ -43,6 +43,7 @@ properties:
               - atmel,sama5d4-pmc
               - microchip,sam9x60-pmc
               - microchip,sama7g5-pmc
+              - microchip,sam9x7-pmc
           - const: syscon
 
   reg:
@@ -89,6 +90,7 @@ allOf:
             enum:
               - microchip,sam9x60-pmc
               - microchip,sama7g5-pmc
+              - microchip,sam9x7-pmc
     then:
       properties:
         clocks:
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:27:50 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:57:50 +0530
Subject: [PATCH v4 23/39] clk: at91: clk-sam9x60-pll: re-factor to support individual core freq outputs
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172750.672745-1-varshini.rajendran@microchip.com>

SAM9X7 SoC family supports different core output frequencies for
different PLL IDs. To handle the same in the PLL driver, a separate
parameter core_output is added. The sam9x60 and sama7g5 SoC PMC drivers
are aligned to the PLL driver by adding the core output freq range in
the PLL characteristics configurations.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
 drivers/clk/at91/clk-sam9x60-pll.c | 12 ++++++------
 drivers/clk/at91/pmc.h             |  1 +
 drivers/clk/at91/sam9x60.c         |  7 +++++++
 drivers/clk/at91/sama7g5.c         |  7 +++++++
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
index ff65f7b916f0..b0314dfd7393 100644
--- a/drivers/clk/at91/clk-sam9x60-pll.c
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -23,9 +23,6 @@
 #define UPLL_DIV		2
 #define PLL_MUL_MAX		(FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
 
-#define FCORE_MIN		(600000000)
-#define FCORE_MAX		(1200000000)
-
 #define PLL_MAX_ID		7
 
 struct sam9x60_pll_core {
@@ -194,7 +191,8 @@ static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core,
 	unsigned long nmul = 0;
 	unsigned long nfrac = 0;
 
-	if (rate < FCORE_MIN || rate > FCORE_MAX)
+	if (rate < core->characteristics->core_output[0].min ||
+	    rate > core->characteristics->core_output[0].max)
 		return -ERANGE;
 
 	/*
@@ -214,7 +212,8 @@ static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core,
 	}
 
 	/* Check if resulted rate is a valid.  */
-	if (tmprate < FCORE_MIN || tmprate > FCORE_MAX)
+	if (tmprate < core->characteristics->core_output[0].min ||
+	    tmprate > core->characteristics->core_output[0].max)
 		return -ERANGE;
 
 	if (update) {
@@ -669,7 +668,8 @@ sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
 			goto free;
 		}
 
-		ret = sam9x60_frac_pll_compute_mul_frac(&frac->core, FCORE_MIN,
+		ret = sam9x60_frac_pll_compute_mul_frac(&frac->core,
+							characteristics->core_output[0].min,
 							parent_rate, true);
 		if (ret < 0) {
 			hw = ERR_PTR(ret);
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 0f52e80bcd49..bb9da35198d9 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -75,6 +75,7 @@ struct clk_pll_characteristics {
 	struct clk_range input;
 	int num_output;
 	const struct clk_range *output;
+	const struct clk_range *core_output;
 	u16 *icpll;
 	u8 *out;
 	u8 upll : 1;
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
index e309cbf3cb9a..db6db9e2073e 100644
--- a/drivers/clk/at91/sam9x60.c
+++ b/drivers/clk/at91/sam9x60.c
@@ -26,10 +26,16 @@ static const struct clk_range plla_outputs[] = {
 	{ .min = 2343750, .max = 1200000000 },
 };
 
+/* Fractional PLL core output range. */
+static const struct clk_range core_outputs[] = {
+	{ .min = 600000000, .max = 1200000000 },
+};
+
 static const struct clk_pll_characteristics plla_characteristics = {
 	.input = { .min = 12000000, .max = 48000000 },
 	.num_output = ARRAY_SIZE(plla_outputs),
 	.output = plla_outputs,
+	.core_output = core_outputs,
 };
 
 static const struct clk_range upll_outputs[] = {
@@ -40,6 +46,7 @@ static const struct clk_pll_characteristics upll_characteristics = {
 	.input = { .min = 12000000, .max = 48000000 },
 	.num_output = ARRAY_SIZE(upll_outputs),
 	.output = upll_outputs,
+	.core_output = core_outputs,
 	.upll = true,
 };
 
diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c
index 91b5c6f14819..e6eb5afba93d 100644
--- a/drivers/clk/at91/sama7g5.c
+++ b/drivers/clk/at91/sama7g5.c
@@ -116,11 +116,17 @@ static const struct clk_range pll_outputs[] = {
 	{ .min = 2343750, .max = 1200000000 },
 };
 
+/* Fractional PLL core output range. */
+static const struct clk_range core_outputs[] = {
+	{ .min = 600000000, .max = 1200000000 },
+};
+
 /* CPU PLL characteristics. */
 static const struct clk_pll_characteristics cpu_pll_characteristics = {
 	.input = { .min = 12000000, .max = 50000000 },
 	.num_output = ARRAY_SIZE(cpu_pll_outputs),
 	.output = cpu_pll_outputs,
+	.core_output = core_outputs,
 };
 
 /* PLL characteristics. */
@@ -128,6 +134,7 @@ static const struct clk_pll_characteristics pll_characteristics = {
 	.input = { .min = 12000000, .max = 50000000 },
 	.num_output = ARRAY_SIZE(pll_outputs),
 	.output = pll_outputs,
+	.core_output = core_outputs,
 };
 
 /*
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:27:32 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:57:32 +0530
Subject: [PATCH v4 21/39] dt-bindings: clk: at91: add sam9x7
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172732.672645-1-varshini.rajendran@microchip.com>

Add bindings for SAM9X7's slow clock controller.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Added sam9x7 compatible as an enum with sama7g5 compatible as per the
  review comment
---
 .../devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml      | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml b/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
index 7be29877e6d2..ab81f0b55ad5 100644
--- a/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
+++ b/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
@@ -18,7 +18,9 @@ properties:
           - atmel,sama5d4-sckc
           - microchip,sam9x60-sckc
       - items:
-          - const: microchip,sama7g5-sckc
+          - enum:
+              - microchip,sama7g5-sckc
+              - microchip,sam9x7-sckc
           - const: microchip,sam9x60-sckc
 
   reg:
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:27:13 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:57:13 +0530
Subject: [PATCH v4 19/39] ARM: at91: pm: add sam9x7 SoC init config
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172713.672537-1-varshini.rajendran@microchip.com>

Add SoC init config for sam9x7 family.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
 arch/arm/mach-at91/Makefile |  1 +
 arch/arm/mach-at91/sam9x7.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 arch/arm/mach-at91/sam9x7.c

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 794bd12ab0a8..7d8a7bc44e65 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_SOC_AT91RM9200)	+= at91rm9200.o
 obj-$(CONFIG_SOC_AT91SAM9)	+= at91sam9.o
 obj-$(CONFIG_SOC_SAM9X60)	+= sam9x60.o
+obj-$(CONFIG_SOC_SAM9X7)	+= sam9x7.o
 obj-$(CONFIG_SOC_SAMA5)		+= sama5.o sam_secure.o
 obj-$(CONFIG_SOC_SAMA7)		+= sama7.o
 obj-$(CONFIG_SOC_SAMV7)		+= samv7.o
diff --git a/arch/arm/mach-at91/sam9x7.c b/arch/arm/mach-at91/sam9x7.c
new file mode 100644
index 000000000000..d998fb327860
--- /dev/null
+++ b/arch/arm/mach-at91/sam9x7.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Setup code for SAM9X7.
+ *
+ * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Varshini Rajendran <varshini.rajendran at microchip.com>
+ */
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/system_misc.h>
+
+#include "generic.h"
+
+static void __init sam9x7_init(void)
+{
+	of_platform_default_populate(NULL, NULL, NULL);
+
+	sam9x7_pm_init();
+}
+
+static const char *const sam9x7_dt_board_compat[] __initconst = {
+	"microchip,sam9x7",
+	NULL
+};
+
+DT_MACHINE_START(sam9x7_dt, "Microchip SAM9X7")
+	/* Maintainer: Microchip */
+	.init_machine	= sam9x7_init,
+	.dt_compat	= sam9x7_dt_board_compat,
+MACHINE_END
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:27:22 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:57:22 +0530
Subject: [PATCH v4 20/39] ARM: at91: add support in SoC driver for new sam9x7
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172722.672592-1-varshini.rajendran@microchip.com>

Add support for SAM9X7 SoC in the SoC driver.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
Changes in v4:
- Sorted the entries alphabetically as per comment from Claudiu
- Updated EXID
Note: Did not remove the Reviewed-by tag since the changes were only
cosmetic and did not affect functionality
---
 drivers/soc/atmel/soc.c | 23 +++++++++++++++++++++++
 drivers/soc/atmel/soc.h |  9 +++++++++
 2 files changed, 32 insertions(+)

diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c
index cc9a3e107479..cae3452cbc60 100644
--- a/drivers/soc/atmel/soc.c
+++ b/drivers/soc/atmel/soc.c
@@ -101,6 +101,29 @@ static const struct at91_soc socs[] __initconst = {
 		 AT91_CIDR_VERSION_MASK, SAM9X60_D6K_EXID_MATCH,
 		 "sam9x60 8MiB SDRAM SiP", "sam9x60"),
 #endif
+#ifdef CONFIG_SOC_SAM9X7
+	AT91_SOC(SAM9X7_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
+		 AT91_CIDR_VERSION_MASK, SAM9X75_EXID_MATCH,
+		 "sam9x75", "sam9x7"),
+	AT91_SOC(SAM9X7_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
+		 AT91_CIDR_VERSION_MASK, SAM9X72_EXID_MATCH,
+		 "sam9x72", "sam9x7"),
+	AT91_SOC(SAM9X7_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
+		 AT91_CIDR_VERSION_MASK, SAM9X70_EXID_MATCH,
+		 "sam9x70", "sam9x7"),
+	AT91_SOC(SAM9X7_CIDR_MATCH, SAM9X75_D1G_EXID_MATCH,
+		 AT91_CIDR_VERSION_MASK, SAM9X75_EXID_MATCH,
+		 "sam9x75 1Gb DDR3L SiP ", "sam9x7"),
+	AT91_SOC(SAM9X7_CIDR_MATCH, SAM9X75_D5M_EXID_MATCH,
+		 AT91_CIDR_VERSION_MASK, SAM9X75_EXID_MATCH,
+		 "sam9x75 512Mb DDR2 SiP", "sam9x7"),
+	AT91_SOC(SAM9X7_CIDR_MATCH, SAM9X75_D1M_EXID_MATCH,
+		 AT91_CIDR_VERSION_MASK, SAM9X75_EXID_MATCH,
+		 "sam9x75 128Mb DDR2 SiP", "sam9x7"),
+	AT91_SOC(SAM9X7_CIDR_MATCH, SAM9X75_D2G_EXID_MATCH,
+		 AT91_CIDR_VERSION_MASK, SAM9X75_EXID_MATCH,
+		 "sam9x75 2Gb DDR3L SiP", "sam9x7"),
+#endif
 #ifdef CONFIG_SOC_SAMA5
 	AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
 		 AT91_CIDR_VERSION_MASK, SAMA5D21CU_EXID_MATCH,
diff --git a/drivers/soc/atmel/soc.h b/drivers/soc/atmel/soc.h
index 7a9f47ce85fb..fc4157c5f6e3 100644
--- a/drivers/soc/atmel/soc.h
+++ b/drivers/soc/atmel/soc.h
@@ -44,6 +44,7 @@ at91_soc_init(const struct at91_soc *socs);
 #define AT91SAM9X5_CIDR_MATCH		0x019a05a0
 #define AT91SAM9N12_CIDR_MATCH		0x019a07a0
 #define SAM9X60_CIDR_MATCH		0x019b35a0
+#define SAM9X7_CIDR_MATCH		0x09750020
 #define SAMA7G5_CIDR_MATCH		0x00162100
 
 #define AT91SAM9M11_EXID_MATCH		0x00000001
@@ -74,6 +75,14 @@ at91_soc_init(const struct at91_soc *socs);
 #define SAMA7G54_D2G_EXID_MATCH		0x00000020
 #define SAMA7G54_D4G_EXID_MATCH		0x00000028
 
+#define SAM9X70_EXID_MATCH		0x00000005
+#define SAM9X72_EXID_MATCH		0x00000004
+#define SAM9X75_D1G_EXID_MATCH		0x00000018
+#define SAM9X75_D2G_EXID_MATCH		0x00000020
+#define SAM9X75_D1M_EXID_MATCH		0x00000003
+#define SAM9X75_D5M_EXID_MATCH		0x00000010
+#define SAM9X75_EXID_MATCH		0x00000000
+
 #define AT91SAM9XE128_CIDR_MATCH	0x329973a0
 #define AT91SAM9XE256_CIDR_MATCH	0x329a93a0
 #define AT91SAM9XE512_CIDR_MATCH	0x329aa3a0
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:27:05 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:57:05 +0530
Subject: [PATCH v4 18/39] ARM: at91: pm: add support for sam9x7 SoC family
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172705.672488-1-varshini.rajendran@microchip.com>

Add support and pm init config for sam9x7 SoC.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/mach-at91/generic.h |  2 ++
 arch/arm/mach-at91/pm.c      | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 0c3960a8b3eb..acf0b3c82a30 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -12,6 +12,7 @@
 extern void __init at91rm9200_pm_init(void);
 extern void __init at91sam9_pm_init(void);
 extern void __init sam9x60_pm_init(void);
+extern void __init sam9x7_pm_init(void);
 extern void __init sama5_pm_init(void);
 extern void __init sama5d2_pm_init(void);
 extern void __init sama7_pm_init(void);
@@ -19,6 +20,7 @@ extern void __init sama7_pm_init(void);
 static inline void __init at91rm9200_pm_init(void) { }
 static inline void __init at91sam9_pm_init(void) { }
 static inline void __init sam9x60_pm_init(void) { }
+static inline void __init sam9x7_pm_init(void) { }
 static inline void __init sama5_pm_init(void) { }
 static inline void __init sama5d2_pm_init(void) { }
 static inline void __init sama7_pm_init(void) { }
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 345b91dc6627..b81556387aa3 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -233,6 +233,17 @@ static const struct of_device_id sama7g5_ws_ids[] = {
 	{ /* sentinel */ }
 };
 
+static const struct of_device_id sam9x7_ws_ids[] = {
+	{ .compatible = "microchip,sam9x60-rtc",	.data = &ws_info[1] },
+	{ .compatible = "atmel,at91rm9200-ohci",	.data = &ws_info[2] },
+	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
+	{ .compatible = "atmel,at91sam9g45-ehci",	.data = &ws_info[2] },
+	{ .compatible = "usb-ehci",			.data = &ws_info[2] },
+	{ .compatible = "microchip,sam9x60-rtt",	.data = &ws_info[4] },
+	{ .compatible = "microchip,sam9x7-gem",		.data = &ws_info[5] },
+	{ /* sentinel */ }
+};
+
 static int at91_pm_config_ws(unsigned int pm_mode, bool set)
 {
 	const struct wakeup_source_info *wsi;
@@ -1135,6 +1146,7 @@ static const struct of_device_id gmac_ids[] __initconst = {
 	{ .compatible = "atmel,sama5d2-gem" },
 	{ .compatible = "atmel,sama5d29-gem" },
 	{ .compatible = "microchip,sama7g5-gem" },
+	{ .compatible = "microchip,sam9x7-gem" },
 	{ },
 };
 
@@ -1362,6 +1374,7 @@ static const struct of_device_id atmel_pmc_ids[] __initconst = {
 	{ .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
 	{ .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[4] },
 	{ .compatible = "microchip,sama7g5-pmc", .data = &pmc_infos[5] },
+	{ .compatible = "microchip,sam9x7-pmc", .data = &pmc_infos[4] },
 	{ /* sentinel */ },
 };
 
@@ -1499,6 +1512,28 @@ void __init sam9x60_pm_init(void)
 	soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;
 }
 
+void __init sam9x7_pm_init(void)
+{
+	static const int modes[] __initconst = {
+		AT91_PM_STANDBY, AT91_PM_ULP0,
+	};
+
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_SOC_SAM9X7))
+		return;
+
+	at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
+	ret = at91_dt_ramc(false);
+	if (ret)
+		return;
+
+	at91_pm_init(NULL);
+
+	soc_pm.ws_ids = sam9x7_ws_ids;
+	soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;
+}
+
 void __init at91sam9_pm_init(void)
 {
 	int ret;
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:27:58 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:57:58 +0530
Subject: [PATCH v4 24/39] clk: at91: sam9x7: add support for HW PLL freq dividers
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172758.672796-1-varshini.rajendran@microchip.com>

Add support for hardware dividers for PLL IDs in sam9x7 SoC. The system
PLL - PLLA and the system PLL divided by 2 - PLLADIV2 with PLL ID 0 and
4 respectively, both have a hardware divider /2. This has to taken into
account in the software to obtain the right frequencies. Support for the
same is added in the PLL driver.

fcorepllack -----> HW Div = 2 -+--> fpllack
                               |
                               +--> HW Div = 2 ---> fplladiv2ck

In this case the corepll freq is 1600 MHz. So, the plla freq is 800 MHz
after the hardware divider and the plladiv2 freq is 400 MHz after the
hardware divider (Given that the DIVPMC is 0).

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
 drivers/clk/at91/clk-sam9x60-pll.c | 38 ++++++++++++++++++++++++++----
 drivers/clk/at91/pmc.h             |  1 +
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
index b0314dfd7393..1f80759309c0 100644
--- a/drivers/clk/at91/clk-sam9x60-pll.c
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -73,9 +73,15 @@ static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw,
 {
 	struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
 	struct sam9x60_frac *frac = to_sam9x60_frac(core);
+	unsigned long freq;
 
-	return parent_rate * (frac->mul + 1) +
+	freq = parent_rate * (frac->mul + 1) +
 		DIV_ROUND_CLOSEST_ULL((u64)parent_rate * frac->frac, (1 << 22));
+
+	if (core->layout->div2)
+		freq >>= 1;
+
+	return freq;
 }
 
 static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)
@@ -432,6 +438,12 @@ static unsigned long sam9x60_div_pll_recalc_rate(struct clk_hw *hw,
 	return DIV_ROUND_CLOSEST_ULL(parent_rate, (div->div + 1));
 }
 
+static unsigned long sam9x60_fixed_div_pll_recalc_rate(struct clk_hw *hw,
+						       unsigned long parent_rate)
+{
+	return parent_rate >> 1;
+}
+
 static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
 					unsigned long *parent_rate,
 					unsigned long rate)
@@ -606,6 +618,16 @@ static const struct clk_ops sam9x60_div_pll_ops_chg = {
 	.restore_context = sam9x60_div_pll_restore_context,
 };
 
+static const struct clk_ops sam9x60_fixed_div_pll_ops = {
+	.prepare = sam9x60_div_pll_prepare,
+	.unprepare = sam9x60_div_pll_unprepare,
+	.is_prepared = sam9x60_div_pll_is_prepared,
+	.recalc_rate = sam9x60_fixed_div_pll_recalc_rate,
+	.round_rate = sam9x60_div_pll_round_rate,
+	.save_context = sam9x60_div_pll_save_context,
+	.restore_context = sam9x60_div_pll_restore_context,
+};
+
 struct clk_hw * __init
 sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
 			      const char *name, const char *parent_name,
@@ -725,10 +747,16 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock,
 	else
 		init.parent_names = &parent_name;
 	init.num_parents = 1;
-	if (flags & CLK_SET_RATE_GATE)
-		init.ops = &sam9x60_div_pll_ops;
-	else
-		init.ops = &sam9x60_div_pll_ops_chg;
+
+	if (layout->div2) {
+		init.ops = &sam9x60_fixed_div_pll_ops;
+	} else {
+		if (flags & CLK_SET_RATE_GATE)
+			init.ops = &sam9x60_div_pll_ops;
+		else
+			init.ops = &sam9x60_div_pll_ops_chg;
+	}
+
 	init.flags = flags;
 
 	div->core.id = id;
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index bb9da35198d9..91d1c6305d95 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -64,6 +64,7 @@ struct clk_pll_layout {
 	u8 frac_shift;
 	u8 div_shift;
 	u8 endiv_shift;
+	u8 div2;
 };
 
 extern const struct clk_pll_layout at91rm9200_pll_layout;
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:28:10 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:58:10 +0530
Subject: [PATCH v4 25/39] clk: at91: sama7g5: move mux table macros to header file
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172810.672846-1-varshini.rajendran@microchip.com>

Move the mux table init and fill macro function definitions from the
sama7g5 pmc driver to the pmc.h header file since they will be used
by other SoC's pmc drivers as well like sam9x7.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
 drivers/clk/at91/pmc.h     | 16 ++++++++++++++++
 drivers/clk/at91/sama7g5.c | 35 ++++++++++-------------------------
 2 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 91d1c6305d95..4fb29ca111f7 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -121,6 +121,22 @@ struct at91_clk_pms {
 
 #define ndck(a, s) (a[s - 1].id + 1)
 #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
+
+#define PMC_INIT_TABLE(_table, _count)			\
+	do {						\
+		u8 _i;					\
+		for (_i = 0; _i < (_count); _i++)	\
+			(_table)[_i] = _i;		\
+	} while (0)
+
+#define PMC_FILL_TABLE(_to, _from, _count)		\
+	do {						\
+		u8 _i;					\
+		for (_i = 0; _i < (_count); _i++) {	\
+			(_to)[_i] = (_from)[_i];	\
+		}					\
+	} while (0)
+
 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
 				   unsigned int nperiph, unsigned int ngck,
 				   unsigned int npck);
diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c
index e6eb5afba93d..6706d1305baa 100644
--- a/drivers/clk/at91/sama7g5.c
+++ b/drivers/clk/at91/sama7g5.c
@@ -16,21 +16,6 @@
 
 #include "pmc.h"
 
-#define SAMA7G5_INIT_TABLE(_table, _count)		\
-	do {						\
-		u8 _i;					\
-		for (_i = 0; _i < (_count); _i++)	\
-			(_table)[_i] = _i;		\
-	} while (0)
-
-#define SAMA7G5_FILL_TABLE(_to, _from, _count)		\
-	do {						\
-		u8 _i;					\
-		for (_i = 0; _i < (_count); _i++) {	\
-			(_to)[_i] = (_from)[_i];	\
-		}					\
-	} while (0)
-
 static DEFINE_SPINLOCK(pmc_pll_lock);
 static DEFINE_SPINLOCK(pmc_mck0_lock);
 static DEFINE_SPINLOCK(pmc_mckX_lock);
@@ -1119,17 +1104,17 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
 		if (!mux_table)
 			goto err_free;
 
-		SAMA7G5_INIT_TABLE(mux_table, 3);
-		SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_mckx[i].ep_mux_table,
-				   sama7g5_mckx[i].ep_count);
+		PMC_INIT_TABLE(mux_table, 3);
+		PMC_FILL_TABLE(&mux_table[3], sama7g5_mckx[i].ep_mux_table,
+			       sama7g5_mckx[i].ep_count);
 		for (j = 0; j < sama7g5_mckx[i].ep_count; j++) {
 			u8 pll_id = sama7g5_mckx[i].ep[j].pll_id;
 			u8 pll_compid = sama7g5_mckx[i].ep[j].pll_compid;
 
 			tmp_parent_hws[j] = sama7g5_plls[pll_id][pll_compid].hw;
 		}
-		SAMA7G5_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
-				   sama7g5_mckx[i].ep_count);
+		PMC_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
+			       sama7g5_mckx[i].ep_count);
 
 		hw = at91_clk_sama7g5_register_master(regmap, sama7g5_mckx[i].n,
 				   num_parents, NULL, parent_hws, mux_table,
@@ -1215,17 +1200,17 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
 		if (!mux_table)
 			goto err_free;
 
-		SAMA7G5_INIT_TABLE(mux_table, 3);
-		SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_gck[i].pp_mux_table,
-				   sama7g5_gck[i].pp_count);
+		PMC_INIT_TABLE(mux_table, 3);
+		PMC_FILL_TABLE(&mux_table[3], sama7g5_gck[i].pp_mux_table,
+			       sama7g5_gck[i].pp_count);
 		for (j = 0; j < sama7g5_gck[i].pp_count; j++) {
 			u8 pll_id = sama7g5_gck[i].pp[j].pll_id;
 			u8 pll_compid = sama7g5_gck[i].pp[j].pll_compid;
 
 			tmp_parent_hws[j] = sama7g5_plls[pll_id][pll_compid].hw;
 		}
-		SAMA7G5_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
-				   sama7g5_gck[i].pp_count);
+		PMC_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
+			       sama7g5_gck[i].pp_count);
 
 		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
 						 &sama7g5_pcr_layout,
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:28:22 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:58:22 +0530
Subject: [PATCH v4 26/39] dt-bindings: clock: at91: Allow PLLs to be exported and referenced in DT
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172822.672902-1-varshini.rajendran@microchip.com>

Allow PLLADIV2 and LVDSPLL to be referenced as a PMC_TYPE_CORE
clock from phandle in DT for sam9x7 SoC family.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
 include/dt-bindings/clock/at91.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
index 3e3972a814c1..6ede88c3992d 100644
--- a/include/dt-bindings/clock/at91.h
+++ b/include/dt-bindings/clock/at91.h
@@ -38,6 +38,10 @@
 #define PMC_CPU			(PMC_MAIN + 9)
 #define PMC_MCK1		(PMC_MAIN + 10)
 
+/* SAM9X7 */
+#define PMC_PLLADIV2		(PMC_MAIN + 11)
+#define PMC_LVDSPLL		(PMC_MAIN + 12)
+
 #ifndef AT91_PMC_MOSCS
 #define AT91_PMC_MOSCS		0		/* MOSCS Flag */
 #define AT91_PMC_LOCKA		1		/* PLLA Lock */
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:28:55 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:58:55 +0530
Subject: [PATCH v4 28/39] dt-bindings: irqchip/atmel-aic5: Add support for sam9x7 aic
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172855.673003-1-varshini.rajendran@microchip.com>

Document the support added for the Advanced interrupt controller(AIC)
chip in the sam9x7 SoC family.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
Changes in v4:
- Updated Acked-by tag.
---
 .../devicetree/bindings/interrupt-controller/atmel,aic.txt      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
index 7079d44bf3ba..5fb9366c94a1 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
@@ -4,7 +4,7 @@ Required properties:
 - compatible: Should be:
     - "atmel,<chip>-aic" where  <chip> can be "at91rm9200", "sama5d2",
       "sama5d3" or "sama5d4"
-    - "microchip,<chip>-aic" where <chip> can be "sam9x60"
+    - "microchip,<chip>-aic" where <chip> can be "sam9x60" or "sam9x7"
 
 - interrupt-controller: Identifies the node as an interrupt controller.
 - #interrupt-cells: The number of cells to define the interrupts. It should be 3.
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:28:31 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:58:31 +0530
Subject: [PATCH v4 27/39] clk: at91: sam9x7: add sam9x7 pmc driver
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172831.672953-1-varshini.rajendran@microchip.com>

Add a driver for the PMC clocks of sam9x7 Soc family.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Changed variable name alloc_mem to clk_mux_buffer to be more
  suggestive
- Changed description of @f structure member appropriately
---
 drivers/clk/at91/Makefile |   1 +
 drivers/clk/at91/sam9x7.c | 946 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 947 insertions(+)
 create mode 100644 drivers/clk/at91/sam9x7.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 89061b85e7d2..8e3684ba2c74 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o dt-compat.
 obj-$(CONFIG_SOC_AT91SAM9) += at91sam9g45.o dt-compat.o
 obj-$(CONFIG_SOC_AT91SAM9) += at91sam9n12.o at91sam9x5.o dt-compat.o
 obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o
+obj-$(CONFIG_SOC_SAM9X7) += sam9x7.o
 obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o dt-compat.o
 obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o dt-compat.o
 obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o dt-compat.o
diff --git a/drivers/clk/at91/sam9x7.c b/drivers/clk/at91/sam9x7.c
new file mode 100644
index 000000000000..d03387d2e35a
--- /dev/null
+++ b/drivers/clk/at91/sam9x7.c
@@ -0,0 +1,946 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SAM9X7 PMC code.
+ *
+ * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Varshini Rajendran <varshini.rajendran at microchip.com>
+ *
+ */
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+static DEFINE_SPINLOCK(pmc_pll_lock);
+static DEFINE_SPINLOCK(mck_lock);
+
+/**
+ * enum pll_ids - PLL clocks identifiers
+ * @PLL_ID_PLLA:	PLLA identifier
+ * @PLL_ID_UPLL:	UPLL identifier
+ * @PLL_ID_AUDIO:	Audio PLL identifier
+ * @PLL_ID_LVDS:	LVDS PLL identifier
+ * @PLL_ID_PLLA_DIV2:	PLLA DIV2 identifier
+ * @PLL_ID_MAX:		Max PLL Identifier
+ */
+enum pll_ids {
+	PLL_ID_PLLA,
+	PLL_ID_UPLL,
+	PLL_ID_AUDIO,
+	PLL_ID_LVDS,
+	PLL_ID_PLLA_DIV2,
+	PLL_ID_MAX,
+};
+
+/**
+ * enum pll_type - PLL type identifiers
+ * @PLL_TYPE_FRAC:	fractional PLL identifier
+ * @PLL_TYPE_DIV:	divider PLL identifier
+ */
+enum pll_type {
+	PLL_TYPE_FRAC,
+	PLL_TYPE_DIV,
+};
+
+static const struct clk_master_characteristics mck_characteristics = {
+	.output = { .min = 32000000, .max = 266666667 },
+	.divisors = { 1, 2, 4, 3, 5},
+	.have_div3_pres = 1,
+};
+
+static const struct clk_master_layout sam9x7_master_layout = {
+	.mask = 0x373,
+	.pres_shift = 4,
+	.offset = 0x28,
+};
+
+/* Fractional PLL core output range. */
+static const struct clk_range plla_core_outputs[] = {
+	{ .min = 375000000, .max = 1600000000 },
+};
+
+static const struct clk_range upll_core_outputs[] = {
+	{ .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_range lvdspll_core_outputs[] = {
+	{ .min = 400000000, .max = 800000000 },
+};
+
+static const struct clk_range audiopll_core_outputs[] = {
+	{ .min = 400000000, .max = 800000000 },
+};
+
+static const struct clk_range plladiv2_core_outputs[] = {
+	{ .min = 375000000, .max = 1600000000 },
+};
+
+/* Fractional PLL output range. */
+static const struct clk_range plla_outputs[] = {
+	{ .min = 732421, .max = 800000000 },
+};
+
+static const struct clk_range upll_outputs[] = {
+	{ .min = 300000000, .max = 600000000 },
+};
+
+static const struct clk_range lvdspll_outputs[] = {
+	{ .min = 10000000, .max = 800000000 },
+};
+
+static const struct clk_range audiopll_outputs[] = {
+	{ .min = 10000000, .max = 800000000 },
+};
+
+static const struct clk_range plladiv2_outputs[] = {
+	{ .min = 366210, .max = 400000000 },
+};
+
+/* PLL characteristics. */
+static const struct clk_pll_characteristics plla_characteristics = {
+	.input = { .min = 20000000, .max = 50000000 },
+	.num_output = ARRAY_SIZE(plla_outputs),
+	.output = plla_outputs,
+	.core_output = plla_core_outputs,
+};
+
+static const struct clk_pll_characteristics upll_characteristics = {
+	.input = { .min = 20000000, .max = 50000000 },
+	.num_output = ARRAY_SIZE(upll_outputs),
+	.output = upll_outputs,
+	.core_output = upll_core_outputs,
+	.upll = true,
+};
+
+static const struct clk_pll_characteristics lvdspll_characteristics = {
+	.input = { .min = 20000000, .max = 50000000 },
+	.num_output = ARRAY_SIZE(lvdspll_outputs),
+	.output = lvdspll_outputs,
+	.core_output = lvdspll_core_outputs,
+};
+
+static const struct clk_pll_characteristics audiopll_characteristics = {
+	.input = { .min = 20000000, .max = 50000000 },
+	.num_output = ARRAY_SIZE(audiopll_outputs),
+	.output = audiopll_outputs,
+	.core_output = audiopll_core_outputs,
+};
+
+static const struct clk_pll_characteristics plladiv2_characteristics = {
+	.input = { .min = 20000000, .max = 50000000 },
+	.num_output = ARRAY_SIZE(plladiv2_outputs),
+	.output = plladiv2_outputs,
+	.core_output = plladiv2_core_outputs,
+};
+
+/* Layout for fractional PLL ID PLLA. */
+static const struct clk_pll_layout plla_frac_layout = {
+	.mul_mask = GENMASK(31, 24),
+	.frac_mask = GENMASK(21, 0),
+	.mul_shift = 24,
+	.frac_shift = 0,
+	.div2 = 1,
+};
+
+/* Layout for fractional PLLs. */
+static const struct clk_pll_layout pll_frac_layout = {
+	.mul_mask = GENMASK(31, 24),
+	.frac_mask = GENMASK(21, 0),
+	.mul_shift = 24,
+	.frac_shift = 0,
+};
+
+/* Layout for DIV PLLs. */
+static const struct clk_pll_layout pll_divpmc_layout = {
+	.div_mask = GENMASK(7, 0),
+	.endiv_mask = BIT(29),
+	.div_shift = 0,
+	.endiv_shift = 29,
+};
+
+/* Layout for DIV PLL ID PLLADIV2. */
+static const struct clk_pll_layout plladiv2_divpmc_layout = {
+	.div_mask = GENMASK(7, 0),
+	.endiv_mask = BIT(29),
+	.div_shift = 0,
+	.endiv_shift = 29,
+	.div2 = 1,
+};
+
+/* Layout for DIVIO dividers. */
+static const struct clk_pll_layout pll_divio_layout = {
+	.div_mask	= GENMASK(19, 12),
+	.endiv_mask	= BIT(30),
+	.div_shift	= 12,
+	.endiv_shift	= 30,
+};
+
+/*
+ * PLL clocks description
+ * @n:		clock name
+ * @p:		clock parent
+ * @l:		clock layout
+ * @t:		clock type
+ * @c:		pll characteristics
+ * @f:		clock flags
+ * @eid:	export index in sam9x7->chws[] array
+ */
+static const struct {
+	const char *n;
+	const char *p;
+	const struct clk_pll_layout *l;
+	u8 t;
+	const struct clk_pll_characteristics *c;
+	unsigned long f;
+	u8 eid;
+} sam9x7_plls[][PLL_ID_MAX] = {
+	[PLL_ID_PLLA] = {
+		{
+			.n = "plla_fracck",
+			.p = "mainck",
+			.l = &plla_frac_layout,
+			.t = PLL_TYPE_FRAC,
+			/*
+			 * This feeds plla_divpmcck which feeds CPU. It should
+			 * not be disabled.
+			 */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+			.c = &plla_characteristics,
+		},
+
+		{
+			.n = "plla_divpmcck",
+			.p = "plla_fracck",
+			.l = &pll_divpmc_layout,
+			.t = PLL_TYPE_DIV,
+			/* This feeds CPU. It should not be disabled */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+			.eid = PMC_PLLACK,
+			.c = &plla_characteristics,
+		},
+	},
+
+	[PLL_ID_UPLL] = {
+		{
+			.n = "upll_fracck",
+			.p = "main_osc",
+			.l = &pll_frac_layout,
+			.t = PLL_TYPE_FRAC,
+			.f = CLK_SET_RATE_GATE,
+			.c = &upll_characteristics,
+		},
+
+		{
+			.n = "upll_divpmcck",
+			.p = "upll_fracck",
+			.l = &pll_divpmc_layout,
+			.t = PLL_TYPE_DIV,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.eid = PMC_UTMI,
+			.c = &upll_characteristics,
+		},
+	},
+
+	[PLL_ID_AUDIO] = {
+		{
+			.n = "audiopll_fracck",
+			.p = "main_osc",
+			.l = &pll_frac_layout,
+			.f = CLK_SET_RATE_GATE,
+			.c = &audiopll_characteristics,
+			.t = PLL_TYPE_FRAC,
+		},
+
+		{
+			.n = "audiopll_divpmcck",
+			.p = "audiopll_fracck",
+			.l = &pll_divpmc_layout,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.c = &audiopll_characteristics,
+			.eid = PMC_AUDIOPMCPLL,
+			.t = PLL_TYPE_DIV,
+		},
+
+		{
+			.n = "audiopll_diviock",
+			.p = "audiopll_fracck",
+			.l = &pll_divio_layout,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.c = &audiopll_characteristics,
+			.eid = PMC_AUDIOIOPLL,
+			.t = PLL_TYPE_DIV,
+		},
+	},
+
+	[PLL_ID_LVDS] = {
+		{
+			.n = "lvdspll_fracck",
+			.p = "main_osc",
+			.l = &pll_frac_layout,
+			.f = CLK_SET_RATE_GATE,
+			.c = &lvdspll_characteristics,
+			.t = PLL_TYPE_FRAC,
+		},
+
+		{
+			.n = "lvdspll_divpmcck",
+			.p = "lvdspll_fracck",
+			.l = &pll_divpmc_layout,
+			.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
+			     CLK_SET_RATE_PARENT,
+			.c = &lvdspll_characteristics,
+			.eid = PMC_LVDSPLL,
+			.t = PLL_TYPE_DIV,
+		},
+	},
+
+	[PLL_ID_PLLA_DIV2] = {
+		{
+			.n = "plla_div2pmcck",
+			.p = "plla_fracck",
+			.l = &plladiv2_divpmc_layout,
+			/*
+			 * This may feed critical parts of the system like timers.
+			 * It should not be disabled.
+			 */
+			.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+			.c = &plladiv2_characteristics,
+			.eid = PMC_PLLADIV2,
+			.t = PLL_TYPE_DIV,
+		},
+	},
+};
+
+static const struct clk_programmable_layout sam9x7_programmable_layout = {
+	.pres_mask = 0xff,
+	.pres_shift = 8,
+	.css_mask = 0x1f,
+	.have_slck_mck = 0,
+	.is_pres_direct = 1,
+};
+
+static const struct clk_pcr_layout sam9x7_pcr_layout = {
+	.offset = 0x88,
+	.cmd = BIT(31),
+	.gckcss_mask = GENMASK(12, 8),
+	.pid_mask = GENMASK(6, 0),
+};
+
+static const struct {
+	char *n;
+	char *p;
+	u8 id;
+	unsigned long flags;
+} sam9x7_systemck[] = {
+	/*
+	 * ddrck feeds DDR controller and is enabled by bootloader thus we need
+	 * to keep it enabled in case there is no Linux consumer for it.
+	 */
+	{ .n = "ddrck",		.p = "masterck_div",	.id = 2,	.flags = CLK_IS_CRITICAL },
+	{ .n = "uhpck",		.p = "usbck",		.id = 6 },
+	{ .n = "pck0",		.p = "prog0",		.id = 8 },
+	{ .n = "pck1",		.p = "prog1",		.id = 9 },
+};
+
+/*
+ * Peripheral clocks description
+ * @n:		clock name
+ * @f:		clock flags
+ * @id:		peripheral id
+ */
+static const struct {
+	char *n;
+	unsigned long f;
+	u8 id;
+} sam9x7_periphck[] = {
+	{ .n = "pioA_clk",	.id = 2, },
+	{ .n = "pioB_clk",	.id = 3, },
+	{ .n = "pioC_clk",	.id = 4, },
+	{ .n = "flex0_clk",	.id = 5, },
+	{ .n = "flex1_clk",	.id = 6, },
+	{ .n = "flex2_clk",	.id = 7, },
+	{ .n = "flex3_clk",	.id = 8, },
+	{ .n = "flex6_clk",	.id = 9, },
+	{ .n = "flex7_clk",	.id = 10, },
+	{ .n = "flex8_clk",	.id = 11, },
+	{ .n = "sdmmc0_clk",	.id = 12, },
+	{ .n = "flex4_clk",	.id = 13, },
+	{ .n = "flex5_clk",	.id = 14, },
+	{ .n = "flex9_clk",	.id = 15, },
+	{ .n = "flex10_clk",	.id = 16, },
+	{ .n = "tcb0_clk",	.id = 17, },
+	{ .n = "pwm_clk",	.id = 18, },
+	{ .n = "adc_clk",	.id = 19, },
+	{ .n = "dma0_clk",	.id = 20, },
+	{ .n = "uhphs_clk",	.id = 22, },
+	{ .n = "udphs_clk",	.id = 23, },
+	{ .n = "macb0_clk",	.id = 24, },
+	{ .n = "lcd_clk",	.id = 25, },
+	{ .n = "sdmmc1_clk",	.id = 26, },
+	{ .n = "ssc_clk",	.id = 28, },
+	{ .n = "can0_clk",	.id = 29, },
+	{ .n = "can1_clk",	.id = 30, },
+	{ .n = "flex11_clk",	.id = 32, },
+	{ .n = "flex12_clk",	.id = 33, },
+	{ .n = "i2s_clk",	.id = 34, },
+	{ .n = "qspi_clk",	.id = 35, },
+	{ .n = "gfx2d_clk",	.id = 36, },
+	{ .n = "pit64b0_clk",	.id = 37, },
+	{ .n = "trng_clk",	.id = 38, },
+	{ .n = "aes_clk",	.id = 39, },
+	{ .n = "tdes_clk",	.id = 40, },
+	{ .n = "sha_clk",	.id = 41, },
+	{ .n = "classd_clk",	.id = 42, },
+	{ .n = "isi_clk",	.id = 43, },
+	{ .n = "pioD_clk",	.id = 44, },
+	{ .n = "tcb1_clk",	.id = 45, },
+	{ .n = "dbgu_clk",	.id = 47, },
+	/*
+	 * mpddr_clk feeds DDR controller and is enabled by bootloader thus we
+	 * need to keep it enabled in case there is no Linux consumer for it.
+	 */
+	{ .n = "mpddr_clk",	.id = 49,	.f = CLK_IS_CRITICAL },
+	{ .n = "csi2dc_clk",	.id = 52, },
+	{ .n = "csi4l_clk",	.id = 53, },
+	{ .n = "dsi4l_clk",	.id = 54, },
+	{ .n = "lvdsc_clk",	.id = 56, },
+	{ .n = "pit64b1_clk",	.id = 58, },
+	{ .n = "puf_clk",	.id = 59, },
+	{ .n = "gmactsu_clk",	.id = 67, },
+};
+
+/*
+ * Generic clock description
+ * @n:			clock name
+ * @pp:			PLL parents
+ * @pp_mux_table:	PLL parents mux table
+ * @r:			clock output range
+ * @pp_chg_id:		id in parent array of changeable PLL parent
+ * @pp_count:		PLL parents count
+ * @id:			clock id
+ */
+static const struct {
+	const char *n;
+	const char *pp[8];
+	const char pp_mux_table[8];
+	struct clk_range r;
+	int pp_chg_id;
+	u8 pp_count;
+	u8 id;
+} sam9x7_gck[] = {
+	{
+		.n = "flex0_gclk",
+		.id = 5,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex1_gclk",
+		.id = 6,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex2_gclk",
+		.id = 7,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex3_gclk",
+		.id = 8,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex6_gclk",
+		.id = 9,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex7_gclk",
+		.id = 10,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex8_gclk",
+		.id = 11,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "sdmmc0_gclk",
+		.id = 12,
+		.r = { .max = 105000000 },
+		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 6, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex4_gclk",
+		.id = 13,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex5_gclk",
+		.id = 14,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex9_gclk",
+		.id = 15,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex10_gclk",
+		.id = 16,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "tcb0_gclk",
+		.id = 17,
+		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 6, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "adc_gclk",
+		.id = 19,
+		.pp = { "upll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 5, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "lcd_gclk",
+		.id = 25,
+		.r = { .max = 75000000 },
+		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 6, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "sdmmc1_gclk",
+		.id = 26,
+		.r = { .max = 105000000 },
+		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 6, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "mcan0_gclk",
+		.id = 29,
+		.r = { .max = 80000000 },
+		.pp = { "upll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 5, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "mcan1_gclk",
+		.id = 30,
+		.r = { .max = 80000000 },
+		.pp = { "upll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 5, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex11_gclk",
+		.id = 32,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "flex12_gclk",
+		.id = 33,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "i2s_gclk",
+		.id = 34,
+		.r = { .max = 100000000 },
+		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 6, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "qspi_gclk",
+		.id = 35,
+		.r = { .max = 20000000 },
+		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 6, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "pit64b0_gclk",
+		.id = 37,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "classd_gclk",
+		.id = 42,
+		.r = { .max = 100000000 },
+		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 6, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "tcb1_gclk",
+		.id = 45,
+		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 6, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "dbgu_gclk",
+		.id = 47,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "mipiphy_gclk",
+		.id = 55,
+		.r = { .max = 27000000 },
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "pit64b1_gclk",
+		.id = 58,
+		.pp = { "plla_div2pmcck", },
+		.pp_mux_table = { 8, },
+		.pp_count = 1,
+		.pp_chg_id = INT_MIN,
+	},
+
+	{
+		.n = "gmac_gclk",
+		.id = 67,
+		.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+		.pp_mux_table = { 6, 8, },
+		.pp_count = 2,
+		.pp_chg_id = INT_MIN,
+	},
+};
+
+static void __init sam9x7_pmc_setup(struct device_node *np)
+{
+	struct clk_range range = CLK_RANGE(0, 0);
+	const char *td_slck_name, *md_slck_name, *mainxtal_name;
+	struct pmc_data *sam9x7_pmc;
+	const char *parent_names[9];
+	void **clk_mux_buffer = NULL;
+	int clk_mux_buffer_size = 0;
+	struct clk_hw *main_osc_hw;
+	struct regmap *regmap;
+	struct clk_hw *hw;
+	int i, j;
+
+	i = of_property_match_string(np, "clock-names", "td_slck");
+	if (i < 0)
+		return;
+
+	td_slck_name = of_clk_get_parent_name(np, i);
+
+	i = of_property_match_string(np, "clock-names", "md_slck");
+	if (i < 0)
+		return;
+
+	md_slck_name = of_clk_get_parent_name(np, i);
+
+	i = of_property_match_string(np, "clock-names", "main_xtal");
+	if (i < 0)
+		return;
+	mainxtal_name = of_clk_get_parent_name(np, i);
+
+	regmap = device_node_to_regmap(np);
+	if (IS_ERR(regmap))
+		return;
+
+	sam9x7_pmc = pmc_data_allocate(PMC_LVDSPLL + 1,
+				       nck(sam9x7_systemck),
+				       nck(sam9x7_periphck),
+				       nck(sam9x7_gck), 8);
+	if (!sam9x7_pmc)
+		return;
+
+	clk_mux_buffer = kmalloc(sizeof(void *) *
+				 (ARRAY_SIZE(sam9x7_gck)),
+				 GFP_KERNEL);
+	if (!clk_mux_buffer)
+		goto err_free;
+
+	hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
+					   50000000);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, NULL, 0);
+	if (IS_ERR(hw))
+		goto err_free;
+	main_osc_hw = hw;
+
+	parent_names[0] = "main_rc_osc";
+	parent_names[1] = "main_osc";
+	hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, NULL, 2);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	sam9x7_pmc->chws[PMC_MAIN] = hw;
+
+	for (i = 0; i < PLL_ID_MAX; i++) {
+		for (j = 0; j < 3; j++) {
+			struct clk_hw *parent_hw;
+
+			if (!sam9x7_plls[i][j].n)
+				continue;
+
+			switch (sam9x7_plls[i][j].t) {
+			case PLL_TYPE_FRAC:
+				if (!strcmp(sam9x7_plls[i][j].p, "mainck"))
+					parent_hw = sam9x7_pmc->chws[PMC_MAIN];
+				else if (!strcmp(sam9x7_plls[i][j].p, "main_osc"))
+					parent_hw = main_osc_hw;
+				else
+					parent_hw = __clk_get_hw(of_clk_get_by_name
+								 (np, sam9x7_plls[i][j].p));
+
+				hw = sam9x60_clk_register_frac_pll(regmap,
+								   &pmc_pll_lock,
+								   sam9x7_plls[i][j].n,
+								   sam9x7_plls[i][j].p,
+								   parent_hw, i,
+								   sam9x7_plls[i][j].c,
+								   sam9x7_plls[i][j].l,
+								   sam9x7_plls[i][j].f);
+				break;
+
+			case PLL_TYPE_DIV:
+				hw = sam9x60_clk_register_div_pll(regmap,
+								  &pmc_pll_lock,
+								  sam9x7_plls[i][j].n,
+								  sam9x7_plls[i][j].p, NULL, i,
+								  sam9x7_plls[i][j].c,
+								  sam9x7_plls[i][j].l,
+								  sam9x7_plls[i][j].f, 0);
+				break;
+
+			default:
+				continue;
+			}
+
+			if (IS_ERR(hw))
+				goto err_free;
+
+			if (sam9x7_plls[i][j].eid)
+				sam9x7_pmc->chws[sam9x7_plls[i][j].eid] = hw;
+		}
+	}
+
+	parent_names[0] = md_slck_name;
+	parent_names[1] = "mainck";
+	parent_names[2] = "plla_divpmcck";
+	parent_names[3] = "upll_divpmcck";
+	hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,
+					   parent_names, NULL, &sam9x7_master_layout,
+					   &mck_characteristics, &mck_lock);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	hw = at91_clk_register_master_div(regmap, "masterck_div",
+					  "masterck_pres", NULL, &sam9x7_master_layout,
+					  &mck_characteristics, &mck_lock,
+					  CLK_SET_RATE_GATE, 0);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	sam9x7_pmc->chws[PMC_MCK] = hw;
+
+	parent_names[0] = "plla_divpmcck";
+	parent_names[1] = "upll_divpmcck";
+	parent_names[2] = "main_osc";
+	hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	parent_names[0] = md_slck_name;
+	parent_names[1] = td_slck_name;
+	parent_names[2] = "mainck";
+	parent_names[3] = "masterck_div";
+	parent_names[4] = "plla_divpmcck";
+	parent_names[5] = "upll_divpmcck";
+	parent_names[6] = "audiopll_divpmcck";
+	for (i = 0; i < 2; i++) {
+		char name[6];
+
+		snprintf(name, sizeof(name), "prog%d", i);
+
+		hw = at91_clk_register_programmable(regmap, name,
+						    parent_names, NULL, 7, i,
+						    &sam9x7_programmable_layout,
+						    NULL);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sam9x7_pmc->pchws[i] = hw;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sam9x7_systemck); i++) {
+		hw = at91_clk_register_system(regmap, sam9x7_systemck[i].n,
+					      sam9x7_systemck[i].p, NULL,
+					      sam9x7_systemck[i].id,
+					      sam9x7_systemck[i].flags);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sam9x7_pmc->shws[sam9x7_systemck[i].id] = hw;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sam9x7_periphck); i++) {
+		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+							 &sam9x7_pcr_layout,
+							 sam9x7_periphck[i].n,
+							 "masterck_div", NULL,
+							 sam9x7_periphck[i].id,
+							 &range, INT_MIN,
+							 sam9x7_periphck[i].f);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sam9x7_pmc->phws[sam9x7_periphck[i].id] = hw;
+	}
+
+	parent_names[0] = md_slck_name;
+	parent_names[1] = td_slck_name;
+	parent_names[2] = "mainck";
+	parent_names[3] = "masterck_div";
+	for (i = 0; i < ARRAY_SIZE(sam9x7_gck); i++) {
+		u8 num_parents = 4 + sam9x7_gck[i].pp_count;
+		u32 *mux_table;
+
+		mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
+					  GFP_KERNEL);
+		if (!mux_table)
+			goto err_free;
+
+		PMC_INIT_TABLE(mux_table, 4);
+		PMC_FILL_TABLE(&mux_table[4], sam9x7_gck[i].pp_mux_table,
+			       sam9x7_gck[i].pp_count);
+		PMC_FILL_TABLE(&parent_names[4], sam9x7_gck[i].pp,
+			       sam9x7_gck[i].pp_count);
+
+		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
+						 &sam9x7_pcr_layout,
+						 sam9x7_gck[i].n,
+						 parent_names, NULL, mux_table,
+						 num_parents,
+						 sam9x7_gck[i].id,
+						 &sam9x7_gck[i].r,
+						 sam9x7_gck[i].pp_chg_id);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sam9x7_pmc->ghws[sam9x7_gck[i].id] = hw;
+		clk_mux_buffer[clk_mux_buffer_size++] = mux_table;
+	}
+
+	of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sam9x7_pmc);
+	kfree(clk_mux_buffer);
+
+	return;
+
+err_free:
+	if (clk_mux_buffer) {
+		for (i = 0; i < clk_mux_buffer_size; i++)
+			kfree(clk_mux_buffer[i]);
+		kfree(clk_mux_buffer);
+	}
+	kfree(sam9x7_pmc);
+}
+
+/* Some clks are used for a clocksource */
+CLK_OF_DECLARE(sam9x7_pmc, "microchip,sam9x7-pmc", sam9x7_pmc_setup);
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:29:05 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:59:05 +0530
Subject: [PATCH v4 29/39] irqchip/atmel-aic5: Add support to get nirqs from DT for sam9x60 & sam9x7
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172905.673053-1-varshini.rajendran@microchip.com>

Add support to get number of IRQs from the respective DT node for sam9x60
and sam9x7 devices. Since only this factor differs between the two SoCs,
this patch adds support for the same. Adapt the sam9x60 dtsi
accordingly.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Changed the implementation to fetch the NIRQs from DT as per the
  comment to avoid introducing a new compatible when this is the only
  difference between the SoCs related to this IP.
---
 arch/arm/boot/dts/microchip/sam9x60.dtsi |  1 +
 drivers/irqchip/irq-atmel-aic5.c         | 11 ++++++++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/microchip/sam9x60.dtsi b/arch/arm/boot/dts/microchip/sam9x60.dtsi
index 73d570a17269..e405f68c9f54 100644
--- a/arch/arm/boot/dts/microchip/sam9x60.dtsi
+++ b/arch/arm/boot/dts/microchip/sam9x60.dtsi
@@ -1201,6 +1201,7 @@ aic: interrupt-controller at fffff100 {
 				interrupt-controller;
 				reg = <0xfffff100 0x100>;
 				atmel,external-irqs = <31>;
+				microchip,nr-irqs = <50>;
 			};
 
 			dbgu: serial at fffff200 {
diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c
index 145535bd7560..5d96ad8860d3 100644
--- a/drivers/irqchip/irq-atmel-aic5.c
+++ b/drivers/irqchip/irq-atmel-aic5.c
@@ -398,11 +398,16 @@ static int __init sama5d4_aic5_of_init(struct device_node *node,
 }
 IRQCHIP_DECLARE(sama5d4_aic5, "atmel,sama5d4-aic", sama5d4_aic5_of_init);
 
-#define NR_SAM9X60_IRQS		50
-
 static int __init sam9x60_aic5_of_init(struct device_node *node,
 				       struct device_node *parent)
 {
-	return aic5_of_init(node, parent, NR_SAM9X60_IRQS);
+	int ret, nr_irqs;
+
+	ret = of_property_read_u32(node, "microchip,nr-irqs", &nr_irqs);
+	if (ret) {
+		pr_err("Not found microchip,nr-irqs property\n");
+		return ret;
+	}
+	return aic5_of_init(node, parent, nr_irqs);
 }
 IRQCHIP_DECLARE(sam9x60_aic5, "microchip,sam9x60-aic", sam9x60_aic5_of_init);
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:29:20 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 22:59:20 +0530
Subject: [PATCH v4 30/39] power: reset: at91-poweroff: lookup for proper pmc dt node for sam9x7
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223172920.673110-1-varshini.rajendran@microchip.com>

Use sam9x7 pmc's compatible to lookup for in the SHDWC driver.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Acked-by: Sebastian Reichel <sebastian.reichel at collabora.com>
---
Changes in v4:
- Updated Acked-by tag
---
 drivers/power/reset/at91-sama5d2_shdwc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/power/reset/at91-sama5d2_shdwc.c b/drivers/power/reset/at91-sama5d2_shdwc.c
index 959ce0dbe91d..2121d7e74e12 100644
--- a/drivers/power/reset/at91-sama5d2_shdwc.c
+++ b/drivers/power/reset/at91-sama5d2_shdwc.c
@@ -326,6 +326,7 @@ static const struct of_device_id at91_pmc_ids[] = {
 	{ .compatible = "atmel,sama5d2-pmc" },
 	{ .compatible = "microchip,sam9x60-pmc" },
 	{ .compatible = "microchip,sama7g5-pmc" },
+	{ .compatible = "microchip,sam9x7-pmc" },
 	{ /* Sentinel. */ }
 };
 
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:30:15 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 23:00:15 +0530
Subject: [PATCH v4 33/39] dt-bindings: reset: atmel,at91sam9260-reset: add sam9x7
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223173015.673281-1-varshini.rajendran@microchip.com>

Add documentation for SAM9X7 reset controller.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Philipp Zabel <p.zabel at pengutronix.de>
---
Changes in v4:
- Updated Acked-by and Reviewed-by tags.
---
 .../devicetree/bindings/reset/atmel,at91sam9260-reset.yaml    | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/reset/atmel,at91sam9260-reset.yaml b/Documentation/devicetree/bindings/reset/atmel,at91sam9260-reset.yaml
index 98465d26949e..c3b33bbc7319 100644
--- a/Documentation/devicetree/bindings/reset/atmel,at91sam9260-reset.yaml
+++ b/Documentation/devicetree/bindings/reset/atmel,at91sam9260-reset.yaml
@@ -26,6 +26,10 @@ properties:
       - items:
           - const: atmel,sama5d3-rstc
           - const: atmel,at91sam9g45-rstc
+      - items:
+          - enum:
+              - microchip,sam9x7-rstc
+          - const: microchip,sam9x60-rstc
 
   reg:
     minItems: 1
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:30:23 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 23:00:23 +0530
Subject: [PATCH v4 34/39] dt-bindings: power: reset: atmel,sama5d2-shdwc: add sam9x7
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223173023.673336-1-varshini.rajendran@microchip.com>

Add shutdown controller DT bindings.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Sebastian Reichel <sebastian.reichel at collabora.com>
---
Changes in v4:
- Updated Acked-by and Reviewed-by tags
---
 .../devicetree/bindings/power/reset/atmel,sama5d2-shdwc.yaml   | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/reset/atmel,sama5d2-shdwc.yaml b/Documentation/devicetree/bindings/power/reset/atmel,sama5d2-shdwc.yaml
index 8c58e12cdb60..0735ceb7c103 100644
--- a/Documentation/devicetree/bindings/power/reset/atmel,sama5d2-shdwc.yaml
+++ b/Documentation/devicetree/bindings/power/reset/atmel,sama5d2-shdwc.yaml
@@ -22,6 +22,9 @@ properties:
       - enum:
           - atmel,sama5d2-shdwc
           - microchip,sam9x60-shdwc
+      - items:
+          - const: microchip,sam9x7-shdwc
+          - const: microchip,sam9x60-shdwc
 
   reg:
     maxItems: 1
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:30:35 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 23:00:35 +0530
Subject: [PATCH v4 35/39] ARM: at91: Kconfig: add config flag for SAM9X7 SoC
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223173035.673386-1-varshini.rajendran@microchip.com>

Add config flag for sam9x7 SoC.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>
---
Changes in v4:
- Updated Reviewed-by tag
---
 arch/arm/mach-at91/Kconfig | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index a8c022b4c053..49d38a3a47de 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -141,11 +141,28 @@ config SOC_SAM9X60
 	help
 	  Select this if you are using Microchip's SAM9X60 SoC
 
+config SOC_SAM9X7
+	bool "SAM9X7"
+	depends on ARCH_MULTI_V5
+	select ATMEL_AIC5_IRQ
+	select ATMEL_PM if PM
+	select ATMEL_SDRAMC
+	select CPU_ARM926T
+	select HAVE_AT91_USB_CLK
+	select HAVE_AT91_GENERATED_CLK
+	select HAVE_AT91_SAM9X60_PLL
+	select MEMORY
+	select PINCTRL_AT91
+	select SOC_SAM_V4_V5
+	select SRAM if PM
+	help
+	  Select this if you are using Microchip's SAM9X7 SoC
+
 comment "Clocksource driver selection"
 
 config ATMEL_CLOCKSOURCE_PIT
 	bool "Periodic Interval Timer (PIT) support"
-	depends on SOC_AT91SAM9 || SOC_SAM9X60 || SOC_SAMA5
+	depends on SOC_AT91SAM9 || SOC_SAM9X60 || SOC_SAM9X7 || SOC_SAMA5
 	default SOC_AT91SAM9 || SOC_SAMA5
 	select ATMEL_PIT
 	help
@@ -155,7 +172,7 @@ config ATMEL_CLOCKSOURCE_PIT
 
 config ATMEL_CLOCKSOURCE_TCB
 	bool "Timer Counter Blocks (TCB) support"
-	default SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAM9X60 || SOC_SAMA5
+	default SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAM9X60 || SOC_SAM9X7 || SOC_SAMA5
 	select ATMEL_TCB_CLKSRC
 	help
 	  Select this to get a high precision clocksource based on a
@@ -166,7 +183,7 @@ config ATMEL_CLOCKSOURCE_TCB
 
 config MICROCHIP_CLOCKSOURCE_PIT64B
 	bool "64-bit Periodic Interval Timer (PIT64B) support"
-	default SOC_SAM9X60 || SOC_SAMA7
+	default SOC_SAM9X60 || SOC_SAM9X7 || SOC_SAMA7
 	select MICROCHIP_PIT64B
 	help
 	  Select this to get a high resolution clockevent (SAM9X60) or
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:30:43 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 23:00:43 +0530
Subject: [PATCH v4 36/39] ARM: configs: at91: enable config flags for sam9x7 SoC family
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223173043.673442-1-varshini.rajendran@microchip.com>

Enable config flags for SAM9X7 SoC for the sam9x7 SoC family.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
 arch/arm/configs/at91_dt_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index 1d53aec4c836..880f0c0f4cc3 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -16,6 +16,7 @@ CONFIG_ARCH_AT91=y
 CONFIG_SOC_AT91RM9200=y
 CONFIG_SOC_AT91SAM9=y
 CONFIG_SOC_SAM9X60=y
+CONFIG_SOC_SAM9X7=y
 # CONFIG_ATMEL_CLOCKSOURCE_PIT is not set
 CONFIG_AEABI=y
 CONFIG_UACCESS_WITH_MEMCPY=y
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:31:00 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 23:01:00 +0530
Subject: [PATCH v4 38/39] dt-bindings: arm: add sam9x75 curiosity board
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223173100.673543-1-varshini.rajendran@microchip.com>

Add documentation for SAM9X75 Curiosity board.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index 89d75fbb1de4..d74d3a4701ac 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -106,6 +106,12 @@ properties:
           - const: microchip,sam9x60
           - const: atmel,at91sam9
 
+      - description: Microchip SAM9X7 Evaluation Boards
+        items:
+          - const: microchip,sam9x75-curiosity
+          - const: microchip,sam9x7
+          - const: atmel,at91sam9
+
       - description: Nattis v2 board with Natte v2 power board
         items:
           - const: axentia,nattis-2
-- 
2.25.1



From varshini.rajendran at microchip.com  Fri Feb 23 09:31:13 2024
From: varshini.rajendran at microchip.com (Varshini Rajendran)
Date: Fri, 23 Feb 2024 23:01:13 +0530
Subject: [PATCH v4 39/39] ARM: dts: at91: sam9x75_curiosity: add sam9x75 curiosity board
In-Reply-To: <20240223171342.669133-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
Message-ID: <20240223173113.673595-1-varshini.rajendran@microchip.com>

Add device tree file for sam9x75 curiosity board.

Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
---
Changes in v4:
- Removed full node paths
- Renamed Leds with color names
- Corrected regulator node names
- Added support for classd and i2s nodes and their corresponding
  pinctrl nodes
- Dropped USB nodes owing to the discussion here
https://lore.kernel.org/linux-devicetree/CAL_JsqJ9PrX6fj-EbffeJce09MXs=B7t+KS_kOinxaRx38=WxA at mail.gmail.com/
(Explained elaborately in the cover letter)
- Updated the linux,code property with the necessary value
---
 arch/arm/boot/dts/microchip/Makefile          |   3 +
 .../dts/microchip/at91-sam9x75_curiosity.dts  | 309 ++++++++++++++++++
 2 files changed, 312 insertions(+)
 create mode 100644 arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts

diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
index efde9546c8f4..5b3d518da319 100644
--- a/arch/arm/boot/dts/microchip/Makefile
+++ b/arch/arm/boot/dts/microchip/Makefile
@@ -12,6 +12,7 @@ DTC_FLAGS_at91-sama5d3_eds := -@
 DTC_FLAGS_at91-sama5d3_xplained := -@
 DTC_FLAGS_at91-sama5d4_xplained := -@
 DTC_FLAGS_at91-sama7g5ek := -@
+DTC_FLAGS_at91-sam9x75_curiosity := -@
 dtb-$(CONFIG_SOC_AT91RM9200) += \
 	at91rm9200ek.dtb \
 	mpa1600.dtb
@@ -59,6 +60,8 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \
 dtb-$(CONFIG_SOC_SAM9X60) += \
 	at91-sam9x60_curiosity.dtb \
 	at91-sam9x60ek.dtb
+dtb-$(CONFIG_SOC_SAM9X7) += \
+	at91-sam9x75_curiosity.dtb
 dtb-$(CONFIG_SOC_SAM_V7) += \
 	at91-kizbox2-2.dtb \
 	at91-kizbox3-hs.dtb \
diff --git a/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts
new file mode 100644
index 000000000000..be37022d3d05
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/at91-sam9x75_curiosity.dts
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sam9x75_curiosity.dts - Device Tree file for Microchip SAM9X75 Curiosity board
+ *
+ * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Varshini Rajendran <varshini.rajendran at microchip.com>
+ */
+/dts-v1/;
+#include "sam9x7.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Microchip SAM9X75 Curiosity";
+	compatible = "microchip,sam9x75-curiosity", "microchip,sam9x7", "atmel,at91sam9";
+
+	aliases {
+		i2c0 = &i2c6;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_key_gpio_default>;
+
+		button-user {
+			label = "USER";
+			gpios = <&pioC 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_0>;
+			wakeup-source;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_led_gpio_default>;
+
+		led-red {
+			label = "red";
+			gpios = <&pioC 19 GPIO_ACTIVE_HIGH>;
+		};
+
+		led-green {
+			label = "green";
+			gpios = <&pioC 21 GPIO_ACTIVE_HIGH>;
+		};
+
+		led-blue {
+			label = "blue";
+			gpios = <&pioC 20 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	memory at 20000000 {
+		device_type = "memory";
+		reg = <0x20000000 0x10000000>;
+	};
+};
+
+&classd {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_classd>;
+	atmel,pwm-type = "diff";
+	atmel,non-overlap-time = <10>;
+	status = "okay";
+};
+
+&dbgu {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_dbgu>;
+	status = "okay";
+};
+
+&dma0 {
+	status = "okay";
+};
+
+&flx6 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
+	status = "okay";
+};
+
+&i2c6 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flx6_default>;
+	i2c-analog-filter;
+	i2c-digital-filter;
+	i2c-digital-filter-width-ns = <35>;
+	status = "okay";
+
+	pmic at 5b {
+		compatible = "microchip,mcp16502";
+		reg = <0x5b>;
+
+		regulators {
+			vdd_3v3: VDD_IO {
+				regulator-name = "VDD_IO";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-initial-mode = <2>;
+				regulator-allowed-modes = <2>, <4>;
+				regulator-always-on;
+
+				regulator-state-standby {
+					regulator-on-in-suspend;
+					regulator-mode = <4>;
+				};
+
+				regulator-state-mem {
+					regulator-mode = <4>;
+				};
+			};
+
+			vddioddr: VDD_DDR {
+				regulator-name = "VDD_DDR";
+				regulator-min-microvolt = <1283000>;
+				regulator-max-microvolt = <1450000>;
+				regulator-initial-mode = <2>;
+				regulator-allowed-modes = <2>, <4>;
+				regulator-always-on;
+
+				regulator-state-standby {
+					regulator-on-in-suspend;
+					regulator-mode = <4>;
+				};
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-mode = <4>;
+				};
+			};
+
+			vddcore: VDD_CORE {
+				regulator-name = "VDD_CORE";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1210000>;
+				regulator-initial-mode = <2>;
+				regulator-allowed-modes = <2>, <4>;
+				regulator-always-on;
+
+				regulator-state-standby {
+					regulator-on-in-suspend;
+					regulator-mode = <4>;
+				};
+
+				regulator-state-mem {
+					regulator-mode = <4>;
+				};
+			};
+
+			vddcpu: VDD_OTHER {
+				regulator-name = "VDD_OTHER";
+				regulator-min-microvolt = <1700000>;
+				regulator-max-microvolt = <3600000>;
+				regulator-initial-mode = <2>;
+				regulator-allowed-modes = <2>, <4>;
+				regulator-ramp-delay = <3125>;
+				regulator-always-on;
+
+				regulator-state-standby {
+					regulator-on-in-suspend;
+					regulator-mode = <4>;
+				};
+
+				regulator-state-mem {
+					regulator-mode = <4>;
+				};
+			};
+
+			vldo1: LDO1 {
+				regulator-name = "LDO1";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3700000>;
+				regulator-always-on;
+
+				regulator-state-standby {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vldo2: LDO2 {
+				regulator-name = "LDO2";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3700000>;
+
+				regulator-state-standby {
+					regulator-on-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&i2s {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2s_default>;
+	#sound-dai-cells = <0>;
+	status = "disabled";
+};
+
+&main_xtal {
+	clock-frequency = <24000000>;
+};
+
+&pinctrl {
+
+	classd {
+		pinctrl_classd: classd {
+			atmel,pins =
+				<AT91_PIOA 18 AT91_PERIPH_C AT91_PINCTRL_PULL_UP
+				 AT91_PIOA 19 AT91_PERIPH_C AT91_PINCTRL_PULL_DOWN>;
+		};
+	};
+
+	dbgu {
+		pinctrl_dbgu: dbgu-0 {
+			atmel,pins = <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+				      AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+		};
+	};
+
+	flexcom {
+		pinctrl_flx6_default: flx6-twi {
+			atmel,pins =
+				<AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+				 AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+		};
+	};
+
+	gpio-keys {
+		pinctrl_key_gpio_default: key-gpio-default {
+			atmel,pins = <AT91_PIOC 9 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+		};
+	};
+
+	i2s {
+		pinctrl_i2s_default: i2s {
+			atmel,pins =
+				<AT91_PIOB 26 AT91_PERIPH_D AT91_PINCTRL_NONE		/* I2SCK */
+				 AT91_PIOB 15 AT91_PERIPH_D AT91_PINCTRL_NONE		/* I2SWS */
+				 AT91_PIOB 16 AT91_PERIPH_D AT91_PINCTRL_NONE		/* I2SDIN */
+				 AT91_PIOB 17 AT91_PERIPH_D AT91_PINCTRL_NONE		/* I2SDOUT */
+				 AT91_PIOB 25 AT91_PERIPH_D AT91_PINCTRL_NONE>;		/* I2SMCK */
+		};
+	};
+
+	leds {
+		pinctrl_led_gpio_default: led-gpio-default {
+			atmel,pins = <AT91_PIOC 19 AT91_PERIPH_GPIO AT91_PINCTRL_NONE
+				      AT91_PIOC 21 AT91_PERIPH_GPIO AT91_PINCTRL_NONE
+				      AT91_PIOC 20 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+		};
+	};
+
+	sdmmc0 {
+		pinctrl_sdmmc0_default: sdmmc0 {
+			atmel,pins =
+				<AT91_PIOA 2 AT91_PERIPH_A (AT91_PINCTRL_DRIVE_STRENGTH_HI | AT91_PINCTRL_SLEWRATE_DIS)					/* PA2 CK  periph A with pullup */
+				 AT91_PIOA 1 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DRIVE_STRENGTH_HI | AT91_PINCTRL_SLEWRATE_DIS)		/* PA1 CMD periph A with pullup */
+				 AT91_PIOA 0 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DRIVE_STRENGTH_HI | AT91_PINCTRL_SLEWRATE_DIS)		/* PA0 DAT0 periph A */
+				 AT91_PIOA 3 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DRIVE_STRENGTH_HI | AT91_PINCTRL_SLEWRATE_DIS)		/* PA3 DAT1 periph A with pullup */
+				 AT91_PIOA 4 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DRIVE_STRENGTH_HI | AT91_PINCTRL_SLEWRATE_DIS)		/* PA4 DAT2 periph A with pullup */
+				 AT91_PIOA 5 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DRIVE_STRENGTH_HI | AT91_PINCTRL_SLEWRATE_DIS)>;	/* PA5 DAT3 periph A with pullup */
+		};
+	};
+
+}; /* pinctrl */
+
+&rtt {
+	atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
+};
+
+&sdmmc0 {
+	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc0_default>;
+	cd-gpios = <&pioA 23 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	status = "okay";
+};
+
+&slow_xtal {
+	clock-frequency = <32768>;
+};
+
+&power_management {
+	debounce-delay-us = <976>;
+	status = "okay";
+
+	input at 0 {
+		reg = <0>;
+	};
+};
+
+&trng {
+	status = "okay";
+};
+
+&watchdog {
+	status = "okay";
+};
-- 
2.25.1



From andriy.shevchenko at linux.intel.com  Fri Feb 23 09:42:34 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 19:42:34 +0200
Subject: [PATCH v2] clkdev: Update clkdev id usage to allow for longer
 names
In-Reply-To: <20240223163516.796606-1-michael.j.ruhl@intel.com>
References: <20240223163516.796606-1-michael.j.ruhl@intel.com>
Message-ID: <ZdjZCrpP52Hfbs6L@smile.fi.intel.com>

On Fri, Feb 23, 2024 at 11:35:16AM -0500, Michael J. Ruhl wrote:
> clkdev DEV ID information is limited to an array of 20 bytes
> (MAX_DEV_ID).  It is possible that the ID could be longer than
> that.  If so, the lookup will fail because the "real ID" will
> not match the copied value.
> 
> For instance, generating a device name for the I2C Designware
> module using the PCI ID can result in a name of:
> 
> i2c_designware.39424
> 
> clkdev_create() will store:
> 
> i2c_designware.3942
> 
> The stored name is one off and will not match correctly during probe.
> 
> Increase the size of the ID to allow for a longer name.

> v2: Removed CON_ID update and added example to commit

Usually we put changelog out of the commit messages...

> Signed-off-by: Michael J. Ruhl <michael.j.ruhl at intel.com>
> ---

...somewhere here.

Also just noticed that you forgot CCF maintainers to be included.
I'm suggesting to use my script [1] which harvests more or less
adequate list of people and mailing lists to Cc email to.

[1]: https://github.com/andy-shev/home-bin-tools/blob/master/ge2maintainer.sh

-- 
With Best Regards,
Andy Shevchenko




From thierry.reding at gmail.com  Fri Feb 23 09:48:26 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 23 Feb 2024 18:48:26 +0100
Subject: [GIT PULL] arm64: tegra: Device tree fixes for v6.8
Message-ID: <20240223174827.1509403-1-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit 841c35169323cd833294798e58b9bf63fa4fa1de:

  Linux 6.8-rc4 (2024-02-11 12:18:13 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-6.8-arm64-dt

for you to fetch changes up to ff6bd76f4d997642ef390bffe42e93d6f7be87d3:

  arm64: tegra: Fix Tegra234 MGBE power-domains (2024-02-22 17:58:59 +0100)

Thanks,
Thierry

----------------------------------------------------------------
arm64: tegra: Device tree fixes for v6.8

This contains two fixes to make the MGBE Ethernet devices found on
Tegra234 work properly.

----------------------------------------------------------------
Jon Hunter (1):
      arm64: tegra: Fix Tegra234 MGBE power-domains

Thierry Reding (1):
      arm64: tegra: Set the correct PHY mode for MGBE

 arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts | 2 +-
 arch/arm64/boot/dts/nvidia/tegra234.dtsi                      | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)


From thierry.reding at gmail.com  Fri Feb 23 09:48:45 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 23 Feb 2024 18:48:45 +0100
Subject: [GIT PULL 2/5] firmware: tegra: Changes for v6.9-rc1
In-Reply-To: <20240223174849.1509465-1-thierry.reding@gmail.com>
References: <20240223174849.1509465-1-thierry.reding@gmail.com>
Message-ID: <20240223174849.1509465-2-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-6.9-firmware

for you to fetch changes up to 1315848f1f8a0100cb6f8a7187bc320c5d98947f:

  firmware: tegra: bpmp: Return directly after a failed kzalloc() in get_filename() (2024-02-21 17:10:32 +0100)

Thanks,
Thierry

----------------------------------------------------------------
firmware: tegra: Changes for v6.9-rc1

Contains a fix that makes sure we don't unnecessarily call kfree().

----------------------------------------------------------------
Markus Elfring (1):
      firmware: tegra: bpmp: Return directly after a failed kzalloc() in get_filename()

 drivers/firmware/tegra/bpmp-debugfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


From thierry.reding at gmail.com  Fri Feb 23 09:48:48 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 23 Feb 2024 18:48:48 +0100
Subject: [GIT PULL 5/5] arm64: tegra: Device tree changes for v6.9-rc1
In-Reply-To: <20240223174849.1509465-1-thierry.reding@gmail.com>
References: <20240223174849.1509465-1-thierry.reding@gmail.com>
Message-ID: <20240223174849.1509465-5-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-6.9-arm64-dt

for you to fetch changes up to cc36acb8a67ddfe4bc7bc722748f6c1b72eed5ed:

  arm64: tegra: Remove Jetson Orin NX and Jetson Orin Nano DTSI (2024-02-23 18:20:02 +0100)

Thanks,
Thierry

----------------------------------------------------------------
arm64: tegra: Device tree changes for v6.9-rc1

This set of changes refactors the audio-related device tree nodes on
Tegra234 and improves USB support for Jetson AGX Xavier. Furthermore
this consolidates SD/MMC aliases on Tegra234 and provides correct
configuration data for the MGBE Ethernet devices found on Tegra234
so that they can operate at full speed.

----------------------------------------------------------------
Jon Hunter (3):
      arm64: tegra: Add current monitors for Jetson Xavier
      arm64: tegra: Add USB device support for Jetson AGX Xavier
      arm64: tegra: Add USB Type-C controller for Jetson AGX Xavier

Mark Hasemeyer (1):
      arm64: tegra: Enable cros-ec-spi as wake source

Thierry Reding (2):
      arm64: tegra: Use consistent SD/MMC aliases on Tegra234
      arm64: tegra: Add AXI configuration for Tegra234 MGBE

sheetal (4):
      arm64: tegra: Move AHUB ports to SoC DTSI
      arm64: tegra: Define missing IO ports
      arm64: tegra: Add audio support for Jetson Orin NX and Jetson Orin Nano
      arm64: tegra: Remove Jetson Orin NX and Jetson Orin Nano DTSI

 arch/arm64/boot/dts/nvidia/tegra132-norrin.dts     |    1 +
 arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi     |   50 +
 arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts |   51 +-
 arch/arm64/boot/dts/nvidia/tegra194-p3668.dtsi     |   27 +
 arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi     | 1953 +-----------------
 .../dts/nvidia/tegra234-p3737-0000+p3701-0000.dts  |    1 -
 .../arm64/boot/dts/nvidia/tegra234-p3767-0000.dtsi |   14 -
 .../arm64/boot/dts/nvidia/tegra234-p3767-0005.dtsi |   14 -
 arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi     |   86 +
 .../dts/nvidia/tegra234-p3768-0000+p3767-0000.dts  |    7 +-
 .../dts/nvidia/tegra234-p3768-0000+p3767-0005.dts  |   12 +-
 arch/arm64/boot/dts/nvidia/tegra234-sim-vdk.dts    |    1 -
 arch/arm64/boot/dts/nvidia/tegra234.dtsi           | 2138 +++++++++++++++++++-
 13 files changed, 2355 insertions(+), 2000 deletions(-)
 delete mode 100644 arch/arm64/boot/dts/nvidia/tegra234-p3767-0000.dtsi
 delete mode 100644 arch/arm64/boot/dts/nvidia/tegra234-p3767-0005.dtsi


From thierry.reding at gmail.com  Fri Feb 23 09:48:44 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 23 Feb 2024 18:48:44 +0100
Subject: [GIT PULL 1/5] soc/tegra: Changes for v6.9-rc1
Message-ID: <20240223174849.1509465-1-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-6.9-soc

for you to fetch changes up to ae7d2d9b8ebe9f107c500808d5bcd68397645720:

  soc/tegra: pmc: Add SD wake event for Tegra234 (2024-02-16 12:35:56 +0100)

Thanks,
Thierry

----------------------------------------------------------------
soc/tegra: Changes for v6.9-rc1

This set of changes adds ACPI support for the APBMISC driver and cleans
up a few things like dependencies and unused code.

----------------------------------------------------------------
Arnd Bergmann (1):
      soc/tegra: Fix build failure on Tegra241

Christophe JAILLET (1):
      soc/tegra: pmc: Remove some old and deprecated functions and constants

Jon Hunter (1):
      soc/tegra: fuse: Fix crash in tegra_fuse_readl()

Kartik (9):
      mm/util: Introduce kmemdup_array()
      soc/tegra: fuse: Use dev_err_probe for probe failures
      soc/tegra: fuse: Refactor resource mapping
      soc/tegra: fuse: Add tegra_acpi_init_apbmisc()
      soc/tegra: fuse: Add function to add lookups
      soc/tegra: fuse: Add function to print SKU info
      soc/tegra: fuse: Add ACPI support for Tegra194 and Tegra234
      soc/tegra: fuse: Add support for Tegra241
      soc/tegra: fuse: Define tegra194_soc_attr_group for Tegra241

Peter Robinson (1):
      bus: tegra-aconnect: Update dependency to ARCH_TEGRA

Petlozu Pravareshwar (2):
      soc/tegra: pmc: Update address mapping sequence for PMC apertures
      soc/tegra: pmc: Update scratch as an optional aperture

Prathamesh Shete (1):
      soc/tegra: pmc: Add SD wake event for Tegra234

 drivers/bus/Kconfig                    |   5 +-
 drivers/soc/tegra/Kconfig              |   5 ++
 drivers/soc/tegra/fuse/fuse-tegra.c    | 118 +++++++++++++++++++++++++--------
 drivers/soc/tegra/fuse/fuse-tegra30.c  |  23 ++++++-
 drivers/soc/tegra/fuse/fuse.h          |   8 ++-
 drivers/soc/tegra/fuse/tegra-apbmisc.c | 108 +++++++++++++++++++++++++-----
 drivers/soc/tegra/pmc.c                |  87 +++++++++++-------------
 include/linux/string.h                 |   1 +
 include/soc/tegra/fuse.h               |   1 +
 include/soc/tegra/pmc.h                |  18 -----
 mm/util.c                              |  17 +++++
 11 files changed, 277 insertions(+), 114 deletions(-)


From thierry.reding at gmail.com  Fri Feb 23 09:48:46 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 23 Feb 2024 18:48:46 +0100
Subject: [GIT PULL 3/5] dt-bindings: Changes for v6.9-rc1
In-Reply-To: <20240223174849.1509465-1-thierry.reding@gmail.com>
References: <20240223174849.1509465-1-thierry.reding@gmail.com>
Message-ID: <20240223174849.1509465-3-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-6.9-dt-bindings

for you to fetch changes up to a82242d802c7cea66aa6630707c60a456657d1c2:

  dt-bindings: arm: tegra: Add LG Optimus Vu P895 and Optimus 4X P880 (2024-02-22 18:14:58 +0100)

Thanks,
Thierry

----------------------------------------------------------------
dt-bindings: Changes for v6.9-rc1

This contains device tree bindings additions for LG Optimus devices as
well as cleanups for the PMC hardware block.

----------------------------------------------------------------
Maxim Schwalm (1):
      dt-bindings: arm: tegra: Add LG Optimus Vu P895 and Optimus 4X P880

Petlozu Pravareshwar (1):
      dt-bindings: tegra: pmc: Update scratch as an optional aperture

 Documentation/devicetree/bindings/arm/tegra.yaml   |  8 +++
 .../bindings/arm/tegra/nvidia,tegra186-pmc.yaml    | 58 ++++++++++++++--------
 2 files changed, 46 insertions(+), 20 deletions(-)


From thierry.reding at gmail.com  Fri Feb 23 09:48:47 2024
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 23 Feb 2024 18:48:47 +0100
Subject: [GIT PULL 4/5] ARM: tegra: Device tree changes for v6.9-rc1
In-Reply-To: <20240223174849.1509465-1-thierry.reding@gmail.com>
References: <20240223174849.1509465-1-thierry.reding@gmail.com>
Message-ID: <20240223174849.1509465-4-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-6.9-arm-dt

for you to fetch changes up to ea5e97e9ce0466b421bf0350fdb05409f5369162:

  ARM: tegra: Add device-tree for LG Optimus 4X HD (P880) (2024-02-22 18:20:45 +0100)

Thanks,
Thierry

----------------------------------------------------------------
ARM: tegra: Device tree changes for v6.9-rc1

Add support for the LG Optimus 4X HD and LG Optimus VU devices and clean
up some minor issues.

----------------------------------------------------------------
Mark Hasemeyer (1):
      ARM: tegra: Enable cros-ec-spi as wake source

Robert Eckelmann (1):
      ARM: tegra: nexus7: Add missing clock binding into sound node

Svyatoslav Ryhel (2):
      ARM: tegra: Add device-tree for LG Optimus Vu (P895)
      ARM: tegra: Add device-tree for LG Optimus 4X HD (P880)

 arch/arm/boot/dts/nvidia/Makefile                  |    2 +
 arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi        |    1 +
 arch/arm/boot/dts/nvidia/tegra124-venice2.dts      |    1 +
 .../nvidia/tegra30-asus-nexus7-grouper-common.dtsi |    3 +
 arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts       |  489 ++++++
 arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts       |  496 ++++++
 arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi        | 1812 ++++++++++++++++++++
 7 files changed, 2804 insertions(+)
 create mode 100644 arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts
 create mode 100644 arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts
 create mode 100644 arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi


From robh at kernel.org  Fri Feb 23 09:53:14 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 23 Feb 2024 10:53:14 -0700
Subject: [EXT] Re: [PATCH v6 4/9] dt-bindings: usb: add NXP ChipIdea USB2
 Controller schema
In-Reply-To: <DU2PR04MB882234D1A9D5718D8355928B8C552@DU2PR04MB8822.eurprd04.prod.outlook.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com> <20240221145846.1611627-4-xu.yang_2@nxp.com>
 <20240223140256.GA1768266-robh@kernel.org> <DU2PR04MB882234D1A9D5718D8355928B8C552@DU2PR04MB8822.eurprd04.prod.outlook.com>
Message-ID: <CAL_JsqKXwL5sGkSikRO6CVSRwENbW1-b3Bn+oy1Acupt06=dRQ@mail.gmail.com>

On Fri, Feb 23, 2024 at 7:56?AM Xu Yang <xu.yang_2 at nxp.com> wrote:
>
> Hi Rob,
>
> >
> > On Wed, Feb 21, 2024 at 10:58:41PM +0800, Xu Yang wrote:
> > > As more and more NXP i.MX chips come out, it becomes harder to maintain
> > > ci-hdrc-usb2.yaml if more stuffs like property restrictions are added to
> > > this file. This will separate i.MX parts out of ci-hdrc-usb2.yaml and add
> > > a new schema for NXP ChipIdea USB2 Controller.
> > >
> > > Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> > >
> > > ---
> > > Changes in v6:
> > >  - new patch
> > > ---
> > >  .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 75 +++++++++++++++++++
> > >  1 file changed, 75 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
> > >
> > > diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml b/Documentation/devicetree/bindings/usb/ci-
> > hdrc-usb2-imx.yaml
> > > new file mode 100644
> > > index 000000000000..2ec62f564bf5
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
> > > @@ -0,0 +1,75 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/usb/ci-hdrc-
> > usb2-
> > imx.yaml%23&data=05%7C02%7Cxu.yang_2%40nxp.com%7C4ac0c60cd4b4433f0f9f08dc34782572%7C686ea1d3bc2b4c6fa92c
> > d99c5c301635%7C0%7C0%7C638442937830606824%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIi
> > LCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=7p1DzvYmBsTgN44jypH7lc56z9hVBsFBYXUwsblk9z8%3D&reserv
> > ed=0
> > > +$schema: http://devicetree.org/meta-
> > schemas%2Fcore.yaml%23&data=05%7C02%7Cxu.yang_2%40nxp.com%7C4ac0c60cd4b4433f0f9f08dc34782572%7C686ea1d3
> > bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638442937830615622%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLC
> > JQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=fWWy9enbGK5yeKiovday7go3Gss5L%2F%2Fe%2F
> > OZcANny0QA%3D&reserved=0
> > > +
> > > +title: NXP USB2 ChipIdea USB controller
> > > +
> > > +maintainers:
> > > +  - Xu Yang <xu.yang_2 at nxp.com>
> > > +
> > > +properties:
> > > +  compatible:
> > > +    oneOf:
> > > +      - enum:
> > > +          - fsl,imx27-usb
> > > +      - items:
> > > +          - enum:
> > > +              - fsl,imx23-usb
> > > +              - fsl,imx25-usb
> > > +              - fsl,imx28-usb
> > > +              - fsl,imx35-usb
> > > +              - fsl,imx50-usb
> > > +              - fsl,imx51-usb
> > > +              - fsl,imx53-usb
> > > +              - fsl,imx6q-usb
> > > +              - fsl,imx6sl-usb
> > > +              - fsl,imx6sx-usb
> > > +              - fsl,imx6ul-usb
> > > +              - fsl,imx7d-usb
> > > +              - fsl,vf610-usb
> > > +          - const: fsl,imx27-usb
> > > +      - items:
> > > +          - enum:
> > > +              - fsl,imx8dxl-usb
> > > +              - fsl,imx8ulp-usb
> > > +          - const: fsl,imx7ulp-usb
> > > +          - const: fsl,imx6ul-usb
> > > +      - items:
> > > +          - enum:
> > > +              - fsl,imx8mm-usb
> > > +              - fsl,imx8mn-usb
> > > +          - const: fsl,imx7d-usb
> > > +          - const: fsl,imx27-usb
> > > +      - items:
> > > +          - enum:
> > > +              - fsl,imx6sll-usb
> > > +              - fsl,imx7ulp-usb
> > > +          - const: fsl,imx6ul-usb
> > > +          - const: fsl,imx27-usb
> >
> > Now you just duplicated all the compatibles, and now any new compatibles
> > have to be added in 2 places. For this to work, you have to split
> > ci-hdrc-usb2.yaml into 2 files. One with all the common properties and
> > one with compatibles (minus imx). This is also needed if imx has any
> > extra properties the other don't.
> >
> > Didn't I say this already?
> >
>
> Yes, I know.
>
> But according to your words, I need to split ci-hdrc-usb2.yaml into 1 common
> file and more than 1 vendor specific files (imx, nvidia, qcom, nuvoton and
> others). In this patchset, I only focus on imx part and KK said he or someone
> will take over other parts, therefore I just duplicated all the imx compatibles.

This series is just wasting our time because it can't be applied without that.

> If I only create imx specific yaml file and remove all compatilbles from common
> file, nvidia, qcom, nuvoton and others compatible info will be lost, is this
> feasible? Or should I create mutiple vendor specific files at the same time?

You don't have to split each vendor to a separate vendor schema file.
Just move everything common to ci-hdrc-usb2-common.yaml and add a
reference to it. Then imx can reference the common file.

Rob


From nicolas.dufresne at collabora.com  Fri Feb 23 10:11:20 2024
From: nicolas.dufresne at collabora.com (Nicolas Dufresne)
Date: Fri, 23 Feb 2024 13:11:20 -0500
Subject: [PATCH v3,1/2] media: mediatek: vcodec: adding lock to protect
 decoder context list
In-Reply-To: <20240222092609.31382-2-yunfei.dong@mediatek.com>
References: <20240222092609.31382-1-yunfei.dong@mediatek.com>
	 <20240222092609.31382-2-yunfei.dong@mediatek.com>
Message-ID: <680e74eb187926560c8f55b5b2ca064514b985b6.camel@collabora.com>

Hi Yunfei,

Le jeudi 22 f?vrier 2024 ? 17:26 +0800, Yunfei Dong a ?crit?:
> The ctx_list will be deleted when scp getting unexpected behavior, then the
> ctx_list->next will be NULL, the kernel driver maybe access NULL pointer in
> function vpu_dec_ipi_handler when going through each context, then reboot.
> 
> Need to add lock to protect the ctx_list to make sure the ctx_list->next isn't
> NULL pointer.
> 
> Hardware name: Google juniper sku16 board (DT)
> pstate: 20400005 (nzCv daif +PAN -UAO -TCO BTYPE=--)
> pc : vpu_dec_ipi_handler+0x58/0x1f8 [mtk_vcodec_dec]
> lr : scp_ipi_handler+0xd0/0x194 [mtk_scp]
> sp : ffffffc0131dbbd0
> x29: ffffffc0131dbbd0 x28: 0000000000000000
> x27: ffffff9bb277f348 x26: ffffff9bb242ad00
> x25: ffffffd2d440d3b8 x24: ffffffd2a13ff1d4
> x23: ffffff9bb7fe85a0 x22: ffffffc0133fbdb0
> x21: 0000000000000010 x20: ffffff9b050ea328
> x19: ffffffc0131dbc08 x18: 0000000000001000
> x17: 0000000000000000 x16: ffffffd2d461c6e0
> x15: 0000000000000242 x14: 000000000000018f
> x13: 000000000000004d x12: 0000000000000000
> x11: 0000000000000001 x10: fffffffffffffff0
> x9 : ffffff9bb6e793a8 x8 : 0000000000000000
> x7 : 0000000000000000 x6 : 000000000000003f
> x5 : 0000000000000040 x4 : fffffffffffffff0
> x3 : 0000000000000020 x2 : ffffff9bb6e79080
> x1 : 0000000000000010 x0 : ffffffc0131dbc08
> Call trace:
> vpu_dec_ipi_handler+0x58/0x1f8 [mtk_vcodec_dec (HASH:6c3f 2)]
> scp_ipi_handler+0xd0/0x194 [mtk_scp (HASH:7046 3)]
> mt8183_scp_irq_handler+0x44/0x88 [mtk_scp (HASH:7046 3)]
> scp_irq_handler+0x48/0x90 [mtk_scp (HASH:7046 3)]
> irq_thread_fn+0x38/0x94
> irq_thread+0x100/0x1c0
> kthread+0x140/0x1fc
> ret_from_fork+0x10/0x30
> Code: 54000088 f94ca50a eb14015f 54000060 (f9400108)
> ---[ end trace ace43ce36cbd5c93 ]---
> Kernel panic - not syncing: Oops: Fatal exception
> SMP: stopping secondary CPUs
> Kernel Offset: 0x12c4000000 from 0xffffffc010000000
> PHYS_OFFSET: 0xffffffe580000000
> CPU features: 0x08240002,2188200c
> Memory Limit: none
> 
> Fixes: 655b86e52eac ("media: mediatek: vcodec: Fix possible invalid memory access for decoder")
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>

I've been experiencing this crasher recently, so nice to see you found the
problem.

Reviewed-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>

> ---
>  .../platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c      | 4 ++--
>  .../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c    | 5 +++++
>  .../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h    | 2 ++
>  drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c | 2 ++
>  4 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
> index 9f6e4b59455da..9a11a2c248045 100644
> --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
> +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
> @@ -58,12 +58,12 @@ static void mtk_vcodec_vpu_reset_dec_handler(void *priv)
>  
>  	dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
>  
> -	mutex_lock(&dev->dev_mutex);
> +	mutex_lock(&dev->dev_ctx_lock);
>  	list_for_each_entry(ctx, &dev->ctx_list, list) {
>  		ctx->state = MTK_STATE_ABORT;
>  		mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
>  	}
> -	mutex_unlock(&dev->dev_mutex);
> +	mutex_unlock(&dev->dev_ctx_lock);
>  }
>  
>  static void mtk_vcodec_vpu_reset_enc_handler(void *priv)
> diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
> index ad9b68380692f..d69c9fe2af6f3 100644
> --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
> +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
> @@ -267,7 +267,9 @@ static int fops_vcodec_open(struct file *file)
>  
>  	ctx->dev->vdec_pdata->init_vdec_params(ctx);
>  
> +	mutex_lock(&dev->dev_ctx_lock);
>  	list_add(&ctx->list, &dev->ctx_list);
> +	mutex_unlock(&dev->dev_ctx_lock);
>  	mtk_vcodec_dbgfs_create(ctx);
>  
>  	mutex_unlock(&dev->dev_mutex);
> @@ -310,7 +312,9 @@ static int fops_vcodec_release(struct file *file)
>  	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
>  
>  	mtk_vcodec_dbgfs_remove(dev, ctx->id);
> +	mutex_lock(&dev->dev_ctx_lock);
>  	list_del_init(&ctx->list);
> +	mutex_unlock(&dev->dev_ctx_lock);
>  	kfree(ctx);
>  	mutex_unlock(&dev->dev_mutex);
>  	return 0;
> @@ -403,6 +407,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>  	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
>  		mutex_init(&dev->dec_mutex[i]);
>  	mutex_init(&dev->dev_mutex);
> +	mutex_init(&dev->dev_ctx_lock);
>  	spin_lock_init(&dev->irqlock);
>  
>  	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
> diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
> index 849b89dd205c2..85b2c0d3d8bcd 100644
> --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
> +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
> @@ -241,6 +241,7 @@ struct mtk_vcodec_dec_ctx {
>   *
>   * @dec_mutex: decoder hardware lock
>   * @dev_mutex: video_device lock
> + * @dev_ctx_lock: the lock of context list
>   * @decode_workqueue: decode work queue
>   *
>   * @irqlock: protect data access by irq handler and work thread
> @@ -282,6 +283,7 @@ struct mtk_vcodec_dec_dev {
>  	/* decoder hardware mutex lock */
>  	struct mutex dec_mutex[MTK_VDEC_HW_MAX];
>  	struct mutex dev_mutex;
> +	struct mutex dev_ctx_lock;
>  	struct workqueue_struct *decode_workqueue;
>  
>  	spinlock_t irqlock;
> diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
> index 82e57ae983d55..da6be556727bb 100644
> --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
> +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
> @@ -77,12 +77,14 @@ static bool vpu_dec_check_ap_inst(struct mtk_vcodec_dec_dev *dec_dev, struct vde
>  	struct mtk_vcodec_dec_ctx *ctx;
>  	int ret = false;
>  
> +	mutex_lock(&dec_dev->dev_ctx_lock);
>  	list_for_each_entry(ctx, &dec_dev->ctx_list, list) {
>  		if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
>  			ret = true;
>  			break;
>  		}
>  	}
> +	mutex_unlock(&dec_dev->dev_ctx_lock);
>  
>  	return ret;
>  }



From nicolas.dufresne at collabora.com  Fri Feb 23 10:11:32 2024
From: nicolas.dufresne at collabora.com (Nicolas Dufresne)
Date: Fri, 23 Feb 2024 13:11:32 -0500
Subject: [PATCH v3,2/2] media: mediatek: vcodec: adding lock to protect
 encoder context list
In-Reply-To: <20240222092609.31382-3-yunfei.dong@mediatek.com>
References: <20240222092609.31382-1-yunfei.dong@mediatek.com>
	 <20240222092609.31382-3-yunfei.dong@mediatek.com>
Message-ID: <176094a180c0535119d487e6cf7c886c376b7d60.camel@collabora.com>

Le jeudi 22 f?vrier 2024 ? 17:26 +0800, Yunfei Dong a ?crit?:
> The ctx_list will be deleted when scp getting unexpected behavior, then the
> ctx_list->next will be NULL, the kernel driver maybe access NULL pointer in
> function vpu_enc_ipi_handler when going through each context, then reboot.
> 
> Need to add lock to protect the ctx_list to make sure the ctx_list->next isn't
> NULL pointer.
> 
> Fixes: 1972e32431ed ("media: mediatek: vcodec: Fix possible invalid memory access for encoder")
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>

Reviewed-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>

> ---
>  .../platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c      | 4 ++--
>  .../platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c    | 5 +++++
>  .../platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h    | 2 ++
>  drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c | 2 ++
>  4 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
> index 9a11a2c248045..8d578b6902148 100644
> --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
> +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
> @@ -73,12 +73,12 @@ static void mtk_vcodec_vpu_reset_enc_handler(void *priv)
>  
>  	dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
>  
> -	mutex_lock(&dev->dev_mutex);
> +	mutex_lock(&dev->dev_ctx_lock);
>  	list_for_each_entry(ctx, &dev->ctx_list, list) {
>  		ctx->state = MTK_STATE_ABORT;
>  		mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
>  	}
> -	mutex_unlock(&dev->dev_mutex);
> +	mutex_unlock(&dev->dev_ctx_lock);
>  }
>  
>  static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = {
> diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
> index 5db2bf3db4c54..29524cd59ce8b 100644
> --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
> +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
> @@ -177,7 +177,9 @@ static int fops_vcodec_open(struct file *file)
>  	mtk_v4l2_venc_dbg(2, ctx, "Create instance [%d]@%p m2m_ctx=%p ",
>  			  ctx->id, ctx, ctx->m2m_ctx);
>  
> +	mutex_lock(&dev->dev_ctx_lock);
>  	list_add(&ctx->list, &dev->ctx_list);
> +	mutex_unlock(&dev->dev_ctx_lock);
>  
>  	mutex_unlock(&dev->dev_mutex);
>  	mtk_v4l2_venc_dbg(0, ctx, "%s encoder [%d]", dev_name(&dev->plat_dev->dev),
> @@ -212,7 +214,9 @@ static int fops_vcodec_release(struct file *file)
>  	v4l2_fh_exit(&ctx->fh);
>  	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
>  
> +	mutex_lock(&dev->dev_ctx_lock);
>  	list_del_init(&ctx->list);
> +	mutex_unlock(&dev->dev_ctx_lock);
>  	kfree(ctx);
>  	mutex_unlock(&dev->dev_mutex);
>  	return 0;
> @@ -294,6 +298,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>  
>  	mutex_init(&dev->enc_mutex);
>  	mutex_init(&dev->dev_mutex);
> +	mutex_init(&dev->dev_ctx_lock);
>  	spin_lock_init(&dev->irqlock);
>  
>  	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
> diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
> index a042f607ed8d1..0bd85d0fb379a 100644
> --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
> +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
> @@ -178,6 +178,7 @@ struct mtk_vcodec_enc_ctx {
>   *
>   * @enc_mutex: encoder hardware lock.
>   * @dev_mutex: video_device lock
> + * @dev_ctx_lock: the lock of context list
>   * @encode_workqueue: encode work queue
>   *
>   * @enc_irq: h264 encoder irq resource
> @@ -205,6 +206,7 @@ struct mtk_vcodec_enc_dev {
>  	/* encoder hardware mutex lock */
>  	struct mutex enc_mutex;
>  	struct mutex dev_mutex;
> +	struct mutex dev_ctx_lock;
>  	struct workqueue_struct *encode_workqueue;
>  
>  	int enc_irq;
> diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
> index 84ad1cc6ad171..51bb7ee141b9e 100644
> --- a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
> +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
> @@ -47,12 +47,14 @@ static bool vpu_enc_check_ap_inst(struct mtk_vcodec_enc_dev *enc_dev, struct ven
>  	struct mtk_vcodec_enc_ctx *ctx;
>  	int ret = false;
>  
> +	mutex_lock(&enc_dev->dev_ctx_lock);
>  	list_for_each_entry(ctx, &enc_dev->ctx_list, list) {
>  		if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
>  			ret = true;
>  			break;
>  		}
>  	}
> +	mutex_unlock(&enc_dev->dev_ctx_lock);
>  
>  	return ret;
>  }



From conor at kernel.org  Fri Feb 23 10:12:02 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 23 Feb 2024 18:12:02 +0000
Subject: [PATCH v3 1/8] dt-bindings: usb: ti,j721e-usb: drop useless
 compatible list
In-Reply-To: <20240223-j7200-usb-suspend-v3-1-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
 <20240223-j7200-usb-suspend-v3-1-b41c9893a130@bootlin.com>
Message-ID: <20240223-clarity-variably-206b01b7276a@spud>

On Fri, Feb 23, 2024 at 05:05:25PM +0100, Th?o Lebrun wrote:
> Compatible can be A or B, not A or B or A+B. Remove last option.
> A=ti,j721e-usb and B=ti,am64-usb.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> index 95ff9791baea..949f45eb45c2 100644
> --- a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> +++ b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> @@ -11,12 +11,9 @@ maintainers:
>  
>  properties:
>    compatible:
> -    oneOf:
> -      - const: ti,j721e-usb
> -      - const: ti,am64-usb
> -      - items:
> -          - const: ti,j721e-usb
> -          - const: ti,am64-usb

Correct, this makes no sense. The devices seem to be compatible though,
so I would expect this to actually be:
oneOf:
  - const: ti,j721e-usb
  - items:
      - const: ti,am64-usb
      - const: ti,j721e-usb

> +    enum:
> +      - ti,j721e-usb
> +      - ti,am64-usb
>  
>    reg:
>      maxItems: 1
> 
> -- 
> 2.43.2
> 
-------------- 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/20240223/df313ab9/attachment-0001.sig>

From conor at kernel.org  Fri Feb 23 10:13:03 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 23 Feb 2024 18:13:03 +0000
Subject: [PATCH v3 2/8] dt-bindings: usb: ti,j721e-usb: add ti,j7200-usb
 compatible
In-Reply-To: <20240223-j7200-usb-suspend-v3-2-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
 <20240223-j7200-usb-suspend-v3-2-b41c9893a130@bootlin.com>
Message-ID: <20240223-defog-uniformed-b438aefdbc39@spud>

On Fri, Feb 23, 2024 at 05:05:26PM +0100, Th?o Lebrun wrote:
> On J7200, the controller & its wrapper are reset on resume. This makes
> it have a different behavior from other platforms.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> index 949f45eb45c2..d52d5b2965aa 100644
> --- a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> +++ b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> @@ -14,6 +14,7 @@ properties:
>      enum:
>        - ti,j721e-usb
>        - ti,am64-usb
> +      - ti,j7200-usb

This patch will change with what I mentioned on the other binding patch,
but the patch itself is reasonable.
Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

>  
>    reg:
>      maxItems: 1
> 
> -- 
> 2.43.2
> 
-------------- 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/20240223/3eb17af1/attachment-0001.sig>

From cristian.marussi at arm.com  Fri Feb 23 10:13:31 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Fri, 23 Feb 2024 18:13:31 +0000
Subject: [PATCH 4/5] firmware: imx: support BBM module
In-Reply-To: <20240202-imx95-bbm-misc-v1-4-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
 <20240202-imx95-bbm-misc-v1-4-3cb743020933@nxp.com>
Message-ID: <ZdjgSxFx9YRP107y@pluto>

On Fri, Feb 02, 2024 at 02:34:42PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> The BBM module provides RTC and BUTTON feature. To i.MX95, this module
> is managed by System Manager. Linux could use i.MX SCMI BBM Extension
> protocol to use RTC and BUTTON feature.
> 
> This driver is to use SCMI interface to get/set RTC, enable pwrkey.

Hi,

> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/firmware/imx/Makefile |   1 +
>  drivers/firmware/imx/sm-bbm.c | 317 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 318 insertions(+)
> 
> diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
> index 8f9f04a513a8..fb20e22074e1 100644
> --- a/drivers/firmware/imx/Makefile
> +++ b/drivers/firmware/imx/Makefile
> @@ -1,3 +1,4 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_IMX_DSP)		+= imx-dsp.o
>  obj-$(CONFIG_IMX_SCU)		+= imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
> +obj-${CONFIG_IMX_SCMI_BBM_EXT}	+= sm-bbm.o

So you have not added a Kconfig for this but you just rely on the SCMI NXP BBM
Vendor module to be configured....this causes the kernel-bot build failure because
I suppose that the RTC subsystem is not compiled in since its dependency is not
stated anywhere...

you could/should add a Kconfig here for this driver with a select on
CONFIG_IMX_SCMI_BBM_EXT and the RTC subsystem and put the

	default y if ARCH_MXC

instead of placing that on CONFIG_IMX_SCMI_BBM_EXT

> diff --git a/drivers/firmware/imx/sm-bbm.c b/drivers/firmware/imx/sm-bbm.c
> new file mode 100644
> index 000000000000..c5bc571881c7
> --- /dev/null
> +++ b/drivers/firmware/imx/sm-bbm.c
> @@ -0,0 +1,317 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2024 NXP.
> + */
> +
> +#include <linux/input.h>
> +#include <linux/jiffies.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/rtc.h>
> +#include <linux/scmi_protocol.h>
> +#include <linux/scmi_nxp_protocol.h>
> +#include <linux/suspend.h>
> +
> +#define DEBOUNCE_TIME		30
> +#define REPEAT_INTERVAL		60
> +
> +struct scmi_imx_bbm {
> +	struct rtc_device *rtc_dev;
> +	struct scmi_protocol_handle *ph;
> +	const struct scmi_imx_bbm_proto_ops *ops;
> +	struct notifier_block nb;
> +	int keycode;
> +	int keystate;  /* 1:pressed */
> +	bool suspended;
> +	struct delayed_work check_work;
> +	struct input_dev *input;
> +};
> +
> +static int scmi_imx_bbm_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
> +	struct scmi_protocol_handle *ph = bbnsm->ph;
> +	u64 val;
> +	int ret;
> +
> +	ret = bbnsm->ops->rtc_time_get(ph, 0, &val);
> +	if (ret)
> +		dev_err(dev, "%s: %d\n", __func__, ret);
> +
> +	rtc_time64_to_tm(val, tm);

You convert to tm and return success anyway on SCMI get error ?

> +
> +	return 0;
> +}
> +
> +static int scmi_imx_bbm_set_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
> +	struct scmi_protocol_handle *ph = bbnsm->ph;
> +	u64 val;
> +	int ret;
> +
> +	val = rtc_tm_to_time64(tm);
> +
> +	ret = bbnsm->ops->rtc_time_set(ph, 0, val);
> +	if (ret)
> +		dev_err(dev, "%s: %d\n", __func__, ret);
> +

Return Success on error to set ?

> +	return 0;
> +}
> +
> +static int scmi_imx_bbm_alarm_irq_enable(struct device *dev, unsigned int enable)
> +{
> +	return 0;
> +}
> +
> +static int scmi_imx_bbm_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
> +	struct scmi_protocol_handle *ph = bbnsm->ph;
> +	struct rtc_time *alrm_tm = &alrm->time;
> +	u64 val;
> +	int ret;
> +
> +	val = rtc_tm_to_time64(alrm_tm);
> +
> +	ret = bbnsm->ops->rtc_alarm_set(ph, 0, val);
> +	if (ret)
> +		dev_err(dev, "%s: %d\n", __func__, ret);
> +

Same pattern error--> success...I suppose is fine at this point but maybe
explain why in a comment....

> +	return 0;
> +}
> +
> +static const struct rtc_class_ops smci_imx_bbm_rtc_ops = {
> +	.read_time = scmi_imx_bbm_read_time,
> +	.set_time = scmi_imx_bbm_set_time,
> +	.set_alarm = scmi_imx_bbm_set_alarm,
> +	.alarm_irq_enable = scmi_imx_bbm_alarm_irq_enable,
> +};
> +
> +static void scmi_imx_bbm_pwrkey_check_for_events(struct work_struct *work)
> +{
> +	struct scmi_imx_bbm *bbnsm = container_of(work, struct scmi_imx_bbm, check_work.work);

there is a to_delayed_work() in workqueue.h to get the delayed work from
work and then in turn get to bbnsm...just to avoid relying on
delayed_work internal naming...

> +	struct scmi_protocol_handle *ph = bbnsm->ph;
> +	struct input_dev *input = bbnsm->input;
> +	u32 state = 0;
> +	int ret;
> +
> +	ret = bbnsm->ops->button_get(ph, &state);
> +	if (ret) {
> +		pr_err("%s: %d\n", __func__, ret);
> +		return;
> +	}
> +
> +	pr_debug("%s: state: %d, keystate %d\n", __func__, state, bbnsm->keystate);
> +
> +	/* only report new event if status changed */
> +	if (state ^ bbnsm->keystate) {
> +		bbnsm->keystate = state;
> +		input_event(input, EV_KEY, bbnsm->keycode, state);
> +		input_sync(input);
> +		pm_relax(bbnsm->input->dev.parent);
> +		pr_debug("EV_KEY: %x\n", bbnsm->keycode);
> +	}
> +
> +	/* repeat check if pressed long */
> +	if (state)
> +		schedule_delayed_work(&bbnsm->check_work, msecs_to_jiffies(REPEAT_INTERVAL));
> +}
> +
> +static int scmi_imx_bbm_pwrkey_event(struct scmi_imx_bbm *bbnsm)
> +{
> +	struct input_dev *input = bbnsm->input;
> +
> +	schedule_delayed_work(&bbnsm->check_work, msecs_to_jiffies(DEBOUNCE_TIME));
> +
> +	/*
> +	 * Directly report key event after resume to make no key press
> +	 * event is missed.
> +	 */
> +	if (bbnsm->suspended) {

So this bbnsm->suspended is checked here from inside the SCMI notifier and it
is set by a couple of pm_ops you provide down below which are called by
the core PM subsys, so is it not high likely that you could have issues with the
order of such reads/writes ? 

Would it be worth to add a READ_ONCE here and WRITE_ONCE in the
pm_ops...or I am overthinking ?

> +		bbnsm->keystate = 1;
> +		input_event(input, EV_KEY, bbnsm->keycode, 1);
> +		input_sync(input);
> +	}
> +
> +	return 0;
> +}
> +
> +static void scmi_imx_bbm_pwrkey_act(void *pdata)
> +{
> +	struct scmi_imx_bbm *bbnsm = pdata;
> +
> +	cancel_delayed_work_sync(&bbnsm->check_work);
> +}
> +
> +static int scmi_imx_bbm_notifier(struct notifier_block *nb, unsigned long event, void *data)
> +{
> +	struct scmi_imx_bbm *bbnsm = container_of(nb, struct scmi_imx_bbm, nb);
> +	struct scmi_imx_bbm_notif_report *r = data;
> +
> +	if (r->is_rtc)
> +		rtc_update_irq(bbnsm->rtc_dev, 1, RTC_AF | RTC_IRQF);
> +	if (r->is_button) {
> +		pr_debug("BBM Button Power key pressed\n");
> +		scmi_imx_bbm_pwrkey_event(bbnsm);
> +	}
> +
> +	return 0;
> +}
> +
> +static int scmi_imx_bbm_pwrkey_init(struct scmi_device *sdev)
> +{
> +	const struct scmi_handle *handle = sdev->handle;
> +	struct device *dev = &sdev->dev;
> +	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
> +	struct input_dev *input;
> +	int ret;
> +
> +	if (device_property_read_u32(dev, "linux,code", &bbnsm->keycode)) {
> +		bbnsm->keycode = KEY_POWER;
> +		dev_warn(dev, "key code is not specified, using default KEY_POWER\n");
> +	}
> +
> +	INIT_DELAYED_WORK(&bbnsm->check_work, scmi_imx_bbm_pwrkey_check_for_events);
> +
> +	input = devm_input_allocate_device(dev);
> +	if (!input) {
> +		dev_err(dev, "failed to allocate the input device for SCMI IMX BBM\n");
> +		return -ENOMEM;
> +	}
> +
> +	input->name = dev_name(dev);
> +	input->phys = "bbnsm-pwrkey/input0";
> +	input->id.bustype = BUS_HOST;
> +
> +	input_set_capability(input, EV_KEY, bbnsm->keycode);
> +
> +	ret = devm_add_action_or_reset(dev, scmi_imx_bbm_pwrkey_act, bbnsm);
> +	if (ret) {
> +		dev_err(dev, "failed to register remove action\n");
> +		return ret;
> +	}
> +
> +	bbnsm->input = input;
> +
> +	ret = handle->notify_ops->devm_event_notifier_register(sdev, SCMI_PROTOCOL_IMX_BBM,
> +							       SCMI_EVENT_IMX_BBM_BUTTON,
> +							       NULL, &bbnsm->nb);

So you are registering for another SCMI event but you want to use the
same callback and notifier_bock to handle different events, BUT internally
the SCMI core creates a DISTINCT kernel regular notification chain for each event
and each resource (or one for ALL resources of an event) against which a
devm_event_notifier_register() has been called AND so, being a notification_chain
the notifier_blocks that you provide MUST be distinct, because the notification
chain is indeed a simply-linked list and so when you register bbnsm->nb the second
time you will indeed add the nb to another list at the same....

...thing which I suppose could work in your case since you have only nb/callback
per event BUT as soon as you (or someone else) will try to register another nb 
for these same events the 2 notification chains will start melting together....

...and it will be a hell to debug...

so IOW...even if it works now for you, please use 2 distinct nb_pwr. nb_rtc
notifier blocks with 2 distinct callbacks (to be able to use container_of in
them) to register to 2 distinct events...you can register for multiple sources
using only one nb BUT you cannot register for multiple events using the same
nb/callback as of now.

With this internal design the queues and the worker threads dispatching these
notifs are dedicated to a single event and possible to a single event/resource...
...no event ever queues behind any other...

This probably would need better clarification in the SCMI docs, my bad, and
maybe a new option to register for ANY event the same nb (like you can do with
src_id if you dont specify one), IF you are fine with the possibility that your
events notification will be serialized in a single queue.

> +
> +	if (ret)
> +		dev_err(dev, "Failed to register BBM Button Events %d:", ret);
> +

So why not failing if you could NOT register the notifications ?

> +	ret = input_register_device(input);
> +	if (ret) {
> +		dev_err(dev, "failed to register input device\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int scmi_imx_bbm_rtc_init(struct scmi_device *sdev)
> +{
> +	const struct scmi_handle *handle = sdev->handle;
> +	struct device *dev = &sdev->dev;
> +	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
> +	int ret;
> +
> +	bbnsm->rtc_dev = devm_rtc_allocate_device(dev);
> +	if (IS_ERR(bbnsm->rtc_dev))
> +		return PTR_ERR(bbnsm->rtc_dev);
> +
> +	bbnsm->rtc_dev->ops = &smci_imx_bbm_rtc_ops;
> +	bbnsm->rtc_dev->range_min = 0;
> +	bbnsm->rtc_dev->range_max = U32_MAX;
> +
> +	ret = devm_rtc_register_device(bbnsm->rtc_dev);
> +	if (ret)
> +		return ret;
> +
> +	bbnsm->nb.notifier_call = &scmi_imx_bbm_notifier;
> +	return handle->notify_ops->devm_event_notifier_register(sdev, SCMI_PROTOCOL_IMX_BBM,
> +								SCMI_EVENT_IMX_BBM_RTC,
> +								NULL, &bbnsm->nb);

As said, this will get mixed up when pwrkey_init tries to register again the same nb
for a different event...

> +}
> +
> +static int scmi_imx_bbm_probe(struct scmi_device *sdev)
> +{
> +	const struct scmi_handle *handle = sdev->handle;
> +	struct device *dev = &sdev->dev;
> +	struct scmi_protocol_handle *ph;
> +	struct scmi_imx_bbm *bbnsm;
> +	int ret;
> +
> +	if (!handle)
> +		return -ENODEV;
> +
> +	bbnsm = devm_kzalloc(dev, sizeof(struct scmi_imx_bbm), GFP_KERNEL);

sizeof(*bbnsm)

> +	if (!bbnsm)
> +		return -ENOMEM;
> +
> +	bbnsm->ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_IMX_BBM, &ph);

proto ops can be global really..since are always the same pointer even
if this is probed mutiple times... this could be

	bbnsm_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_IMX_BBM, &bbnsm->ph);

with bbnsm_ops static global to this file

> +	if (IS_ERR(bbnsm->ops))
> +		return PTR_ERR(bbnsm->ops);
> +
> +	bbnsm->ph = ph;
> +
> +	device_init_wakeup(dev, true);

Not fully familiar with this, but it seems to me that when this is
issued some wakeup related sysfs entries are created too...so I suppose
you want to disable this back on failure to have those entries removed.

or maybe just move this right before the final return 0....but I am not
sure if you want to have it called BEFORE the pwrkey notifier if
registered or AFTER is fine too...potentially loosing some wakeup, though.

> +
> +	dev_set_drvdata(dev, bbnsm);
> +
> +	ret = scmi_imx_bbm_rtc_init(sdev);
> +	if (ret) {
> +		dev_err(dev, "rtc init failed: %d\n", ret);

like ??
		device_init_wakeup(dev, false);

> +		return ret;
> +	}
> +
> +	ret = scmi_imx_bbm_pwrkey_init(sdev);
> +	if (ret) {
> +		dev_err(dev, "pwr init failed: %d\n", ret);
and... 
		device_init_wakeup(dev, false);

> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused scmi_imx_bbm_suspend(struct device *dev)
> +{
> +	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
> +
> +	bbnsm->suspended = true;
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused scmi_imx_bbm_resume(struct device *dev)
> +{
> +	struct scmi_imx_bbm *bbnsm = dev_get_drvdata(dev);
> +
> +	bbnsm->suspended = false;
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(scmi_imx_bbm_pm_ops, scmi_imx_bbm_suspend, scmi_imx_bbm_resume);
> +
> +static const struct scmi_device_id scmi_id_table[] = {
> +	{ SCMI_PROTOCOL_IMX_BBM, "imx-bbm" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(scmi, scmi_id_table);
> +
> +static struct scmi_driver scmi_imx_bbm_driver = {
> +	.driver = {
> +		.pm = &scmi_imx_bbm_pm_ops,
> +	},
> +	.name = "scmi-imx-bbm",
> +	.probe = scmi_imx_bbm_probe,
> +	.id_table = scmi_id_table,
> +};
> +module_scmi_driver(scmi_imx_bbm_driver);
> +

Thanks,
Cristian


From robh at kernel.org  Fri Feb 23 10:17:02 2024
From: robh at kernel.org (Rob Herring)
Date: Fri, 23 Feb 2024 11:17:02 -0700
Subject: [PATCH v4 5/7] arm64: Unconditionally call unflatten_device_tree()
In-Reply-To: <20240223102345.GA10274@willie-the-truck>
References: <20240217010557.2381548-1-sboyd@kernel.org> <20240217010557.2381548-6-sboyd@kernel.org>
 <20240223000317.GA3835346-robh@kernel.org> <20240223102345.GA10274@willie-the-truck>
Message-ID: <CAL_JsqJSeSHeWV3YJE9n2NuY+s_iE6f7N5C_oguEJn7jTZ20xA@mail.gmail.com>

On Fri, Feb 23, 2024 at 3:23?AM Will Deacon <will at kernel.org> wrote:
>
> On Thu, Feb 22, 2024 at 05:03:17PM -0700, Rob Herring wrote:
> > On Fri, Feb 16, 2024 at 05:05:54PM -0800, Stephen Boyd wrote:
> > > Call this function unconditionally so that we can populate an empty DTB
> > > on platforms that don't boot with a firmware provided or builtin DTB.
> > > When ACPI is in use, unflatten_device_tree() ignores the
> > > 'initial_boot_params' pointer so the live DT on those systems won't be
> > > whatever that's pointing to. Similarly, when kexec copies the DT data
> > > the previous kernel to the new one on ACPI systems,
> > > of_kexec_alloc_and_setup_fdt() will ignore the live DT (the empty root
> > > one) and copy the 'initial_boot_params' data.
> > >
> > > Cc: Rob Herring <robh+dt at kernel.org>
> > > Cc: Frank Rowand <frowand.list 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: <linux-arm-kernel at lists.infradead.org>
> > > Signed-off-by: Stephen Boyd <sboyd at kernel.org>
> > > ---
> > >  arch/arm64/kernel/setup.c | 3 +--
> > >  1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > Catalin, Will, Can I get an ack on this so I can take the series via the
> > DT tree.
>
> Mark had strong pretty strong objections to this in version one:

Yes, I had concerns with it as well.

> https://lore.kernel.org/all/ZaZtbU9hre3YhZam at FVFF77S0Q05N/
>
> and this patch looks the same now as it did then. Did something else
> change?

Yes, that version unflattened the bootloader passed DT. Now within
unflatten_devicetree(), the bootloader DT is ignored if ACPI is
enabled and we unflatten an empty tree. That will prevent the kernel
getting 2 h/w descriptions if/when a platform does such a thing. Also,
kexec still uses the bootloader provided DT as before.

Rob


From michael.j.ruhl at intel.com  Fri Feb 23 10:22:13 2024
From: michael.j.ruhl at intel.com (Ruhl, Michael J)
Date: Fri, 23 Feb 2024 18:22:13 +0000
Subject: [PATCH v2] clkdev: Update clkdev id usage to allow for longer
 names
In-Reply-To: <ZdjZCrpP52Hfbs6L@smile.fi.intel.com>
References: <20240223163516.796606-1-michael.j.ruhl@intel.com>
 <ZdjZCrpP52Hfbs6L@smile.fi.intel.com>
Message-ID: <DS0PR11MB64248E0C15C0B86A1CCF945BC1552@DS0PR11MB6424.namprd11.prod.outlook.com>

>-----Original Message-----
>From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
>Sent: Friday, February 23, 2024 12:43 PM
>To: Ruhl, Michael J <michael.j.ruhl at intel.com>
>Cc: linux at armlinux.org.uk; linux-arm-kernel at lists.infradead.org; linux-
>kernel at vger.kernel.org
>Subject: Re: [PATCH v2] clkdev: Update clkdev id usage to allow for longer
>names
>
>On Fri, Feb 23, 2024 at 11:35:16AM -0500, Michael J. Ruhl wrote:
>> clkdev DEV ID information is limited to an array of 20 bytes
>> (MAX_DEV_ID).  It is possible that the ID could be longer than
>> that.  If so, the lookup will fail because the "real ID" will
>> not match the copied value.
>>
>> For instance, generating a device name for the I2C Designware
>> module using the PCI ID can result in a name of:
>>
>> i2c_designware.39424
>>
>> clkdev_create() will store:
>>
>> i2c_designware.3942
>>
>> The stored name is one off and will not match correctly during probe.
>>
>> Increase the size of the ID to allow for a longer name.
>
>> v2: Removed CON_ID update and added example to commit
>
>Usually we put changelog out of the commit messages...

Yeah, usually put it in the cover letter.  I will remove. I see your script automatically
does a cover page...will use that format int the future.

>> Signed-off-by: Michael J. Ruhl <michael.j.ruhl at intel.com>
>> ---
>
>...somewhere here.

Ok.    Will keep for future reference.

>Also just noticed that you forgot CCF maintainers to be included.
>I'm suggesting to use my script [1] which harvests more or less
>adequate list of people and mailing lists to Cc email to.
>
>[1]: https://github.com/andy-shev/home-bin-
>tools/blob/master/ge2maintainer.sh

Using your script I got:

To: "Michael J. Ruhl" <michael.j.ruhl at intel.com>,
        linux-arm-kernel at lists.infradead.org,
        linux-kernel at vger.kernel.org
Cc: Russell King <linux at armlinux.org.uk>

My list (using get_maintainers.pl) is:

linux at armlinux.org.uk
linux-arm-kernel at lists.infradead.org
linux-kernel at vger.kernel.org

They appear to be the same....

I don't have the plain text part on Russel's email (linxu at armlinux.org.uk)... Is that what is missing?

Not sure what CCF is?

M

>
>--
>With Best Regards,
>Andy Shevchenko
>



From mathieu.poirier at linaro.org  Fri Feb 23 10:27:40 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 23 Feb 2024 11:27:40 -0700
Subject: [PATCH v3 1/7] remoteproc: Add TEE support
In-Reply-To: <20240214172127.1022199-2-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <20240214172127.1022199-2-arnaud.pouliquen@foss.st.com>
Message-ID: <ZdjjnJyz7GSVDiPZ@p14s>

On Wed, Feb 14, 2024 at 06:21:21PM +0100, Arnaud Pouliquen wrote:
> From: Arnaud Pouliquen <arnaud.pouliquen at st.com>
> 
> Add a remoteproc TEE (Trusted Execution Environment) driver
> that will be probed by the TEE bus. If the associated Trusted
> application is supported on secure part this device offers a client
> interface to load a firmware in the secure part.
> This firmware could be authenticated and decrypted by the secure
> trusted application.
> 
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at st.com>
> ---
> update from V2
> - Use 'tee_rproc' prefix for all functions
> - rename tee_rproc_get_loaded_rsc_table to tee_rproc_find_loaded_rsc_table
> - redefine fonction to better match with the rproc_ops structure format
> 	- replace 'struct tee_rproc' parameter by 'struct rproc' parameter
> 	- rename 'rproc_tee_get_rsc_table()' to tee_rproc_get_loaded_rsc_table()
> 	  and rework it to remove the cached_table management.
> 	- introduce tee_rproc_get_context() to get the tee_rproc struct from the
>           rproc struct
> 	- rename tee_rproc_get_loaded_rsc_table() to tee_rproc_find_loaded_rsc_table()
> - remove useless check on tee_rproc_ctx structure in tee_rproc_register()
>   and tee_rproc_unregister()
> - fix test on the return of tee_rproc_ctx = devm_kzalloc()
> - remove useless includes and unused tee_rproc_mem structure.
> ---
>  drivers/remoteproc/Kconfig          |   9 +
>  drivers/remoteproc/Makefile         |   1 +
>  drivers/remoteproc/tee_remoteproc.c | 397 ++++++++++++++++++++++++++++
>  include/linux/tee_remoteproc.h      | 102 +++++++
>  4 files changed, 509 insertions(+)
>  create mode 100644 drivers/remoteproc/tee_remoteproc.c
>  create mode 100644 include/linux/tee_remoteproc.h
> 
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 48845dc8fa85..85299606806c 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -365,6 +365,15 @@ config XLNX_R5_REMOTEPROC
>  
>  	  It's safe to say N if not interested in using RPU r5f cores.
>  
> +
> +config TEE_REMOTEPROC
> +	tristate "trusted firmware support by a TEE application"
> +	depends on OPTEE
> +	help
> +	  Support for trusted remote processors firmware. The firmware
> +	  authentication and/or decryption are managed by a trusted application.
> +	  This can be either built-in or a loadable module.
> +
>  endif # REMOTEPROC
>  
>  endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 91314a9b43ce..fa8daebce277 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -36,6 +36,7 @@ obj-$(CONFIG_RCAR_REMOTEPROC)		+= rcar_rproc.o
>  obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
>  obj-$(CONFIG_ST_SLIM_REMOTEPROC)	+= st_slim_rproc.o
>  obj-$(CONFIG_STM32_RPROC)		+= stm32_rproc.o
> +obj-$(CONFIG_TEE_REMOTEPROC)		+= tee_remoteproc.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_XLNX_R5_REMOTEPROC)	+= xlnx_r5_remoteproc.o
> diff --git a/drivers/remoteproc/tee_remoteproc.c b/drivers/remoteproc/tee_remoteproc.c
> new file mode 100644
> index 000000000000..ac727e062d00
> --- /dev/null
> +++ b/drivers/remoteproc/tee_remoteproc.c
> @@ -0,0 +1,397 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
> + * Author: Arnaud Pouliquen <arnaud.pouliquen at st.com>
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/remoteproc.h>
> +#include <linux/slab.h>
> +#include <linux/tee_drv.h>
> +#include <linux/tee_remoteproc.h>
> +
> +#include "remoteproc_internal.h"
> +
> +#define MAX_TEE_PARAM_ARRY_MEMBER	4
> +
> +/*
> + * Authentication of the firmware and load in the remote processor memory
> + *
> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
> + * [in]	 params[1].memref:	buffer containing the image of the buffer
> + */
> +#define TA_RPROC_FW_CMD_LOAD_FW		1
> +
> +/*
> + * Start the remote processor
> + *
> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
> + */
> +#define TA_RPROC_FW_CMD_START_FW	2
> +
> +/*
> + * Stop the remote processor
> + *
> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
> + */
> +#define TA_RPROC_FW_CMD_STOP_FW		3
> +
> +/*
> + * Return the address of the resource table, or 0 if not found
> + * No check is done to verify that the address returned is accessible by
> + * the non secure context. If the resource table is loaded in a protected
> + * memory the access by the non secure context will lead to a data abort.
> + *
> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
> + * [out]  params[1].value.a:	32bit LSB resource table memory address
> + * [out]  params[1].value.b:	32bit MSB resource table memory address
> + * [out]  params[2].value.a:	32bit LSB resource table memory size
> + * [out]  params[2].value.b:	32bit MSB resource table memory size
> + */
> +#define TA_RPROC_FW_CMD_GET_RSC_TABLE	4
> +
> +/*
> + * Return the address of the core dump
> + *
> + * [in]  params[0].value.a:	unique 32bit identifier of the remote processor
> + * [out] params[1].memref:	address of the core dump image if exist,
> + *				else return Null
> + */
> +#define TA_RPROC_FW_CMD_GET_COREDUMP	5
> +
> +struct tee_rproc__context {
> +	struct list_head sessions;
> +	struct tee_context *tee_ctx;
> +	struct device *dev;
> +};
> +
> +static struct tee_rproc__context *tee_rproc_ctx;
> +
> +static void prepare_args(struct tee_rproc *trproc, int cmd,
> +			 struct tee_ioctl_invoke_arg *arg,
> +			 struct tee_param *param, unsigned int num_params)
> +{
> +	memset(arg, 0, sizeof(*arg));
> +	memset(param, 0, MAX_TEE_PARAM_ARRY_MEMBER * sizeof(*param));
> +
> +	arg->func = cmd;
> +	arg->session = trproc->session_id;
> +	arg->num_params = num_params + 1;
> +
> +	param[0] = (struct tee_param) {
> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
> +		.u.value.a = trproc->rproc_id,
> +	};
> +}
> +
> +static struct tee_rproc *tee_rproc_get_context(struct rproc *rproc)
> +{
> +	struct tee_rproc *entry, *tmp;
> +
> +	list_for_each_entry_safe(entry, tmp, &tee_rproc_ctx->sessions, node) {
> +		if (entry->rproc == rproc)
> +			return entry;
> +	}
> +
> +	return NULL;
> +}
> +
> +int tee_rproc_load_fw(struct rproc *rproc, const struct firmware *fw)
> +{
> +	struct tee_ioctl_invoke_arg arg;
> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
> +	struct tee_shm *fw_shm;
> +	int ret;
> +
> +	if (!trproc)
> +		return -EINVAL;
> +
> +	fw_shm = tee_shm_register_kernel_buf(tee_rproc_ctx->tee_ctx, (void *)fw->data, fw->size);
> +	if (IS_ERR(fw_shm))
> +		return PTR_ERR(fw_shm);
> +
> +	prepare_args(trproc, TA_RPROC_FW_CMD_LOAD_FW, &arg, param, 1);
> +
> +	/* Provide the address of the firmware image */
> +	param[1] = (struct tee_param) {
> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
> +		.u.memref = {
> +			.shm = fw_shm,
> +			.size = fw->size,
> +			.shm_offs = 0,
> +		},
> +	};
> +
> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
> +	if (ret < 0 || arg.ret != 0) {
> +		dev_err(tee_rproc_ctx->dev,
> +			"TA_RPROC_FW_CMD_LOAD_FW invoke failed TEE err: %x, ret:%x\n",
> +			arg.ret, ret);
> +		if (!ret)
> +			ret = -EIO;
> +	}
> +
> +	tee_shm_free(fw_shm);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_load_fw);
> +
> +struct resource_table *tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
> +{
> +	struct tee_ioctl_invoke_arg arg;
> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
> +	int ret;
> +
> +	if (!trproc)
> +		return ERR_PTR(-EINVAL);
> +
> +	prepare_args(trproc, TA_RPROC_FW_CMD_GET_RSC_TABLE, &arg, param, 2);
> +
> +	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
> +	param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
> +
> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
> +	if (ret < 0 || arg.ret != 0) {
> +		dev_err(tee_rproc_ctx->dev,
> +			"TA_RPROC_FW_CMD_GET_RSC_TABLE invoke failed TEE err: %x, ret:%x\n",
> +			arg.ret, ret);
> +		return ERR_PTR(-EIO);
> +	}
> +
> +	*table_sz = param[2].u.value.a;
> +
> +	/* If the size is null no resource table defined in the image */
> +	if (!*table_sz)
> +		return NULL;
> +
> +	/* Store the resource table address that would be updated by the remote core. */
> +	trproc->rsc_table = ioremap_wc(param[1].u.value.a, *table_sz);
> +	if (IS_ERR_OR_NULL(trproc->rsc_table)) {
> +		dev_err(tee_rproc_ctx->dev, "Unable to map memory region: %lld+%zx\n",
> +			param[1].u.value.a, *table_sz);
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	return trproc->rsc_table;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_get_loaded_rsc_table);

Here we are missing:

tee_rproc_parse_fw()
{
        tee_rproc_load_fw()
        resource_table = tee_rproc_get_loaded_rsc_table()

        //check error conditions here

        rproc->cached_table = resource_table;
        rproc->table_ptr = resource_table;
}

This is essentially the same as rproc_elf_load_rsc_table(). That way we don't
need rproc_alt_fw_boot() and rproc_load_segments() doesn't have to be moved
around.  The trusted application simply needs to know that if the firmware is
already loaded, it has to return.   

> +
> +struct resource_table *tee_rproc_find_loaded_rsc_table(struct rproc *rproc,
> +						       const struct firmware *fw)
> +{
> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
> +	size_t table_sz;
> +
> +	if (!trproc)
> +		return ERR_PTR(-EINVAL);
> +
> +	if (!trproc->rsc_table)
> +		trproc->rsc_table = tee_rproc_get_loaded_rsc_table(rproc, &table_sz);
> +
> +	return trproc->rsc_table;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_find_loaded_rsc_table);
> +
> +int tee_rproc_start(struct rproc *rproc)
> +{
> +	struct tee_ioctl_invoke_arg arg;
> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
> +	int ret;
> +
> +	if (!trproc)
> +		return -EINVAL;
> +
> +	prepare_args(trproc, TA_RPROC_FW_CMD_START_FW, &arg, param, 0);
> +
> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
> +	if (ret < 0 || arg.ret != 0) {
> +		dev_err(tee_rproc_ctx->dev,
> +			"TA_RPROC_FW_CMD_START_FW invoke failed TEE err: %x, ret:%x\n",
> +			arg.ret, ret);
> +		if (!ret)
> +			ret = -EIO;
> +	}
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_start);
> +
> +int tee_rproc_stop(struct rproc *rproc)
> +{
> +	struct tee_ioctl_invoke_arg arg;
> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
> +	struct tee_rproc *trproc = tee_rproc_get_context(rproc);
> +	int ret;
> +
> +	if (!trproc)
> +		return -EINVAL;
> +
> +	prepare_args(trproc, TA_RPROC_FW_CMD_STOP_FW, &arg, param, 0);
> +
> +	ret = tee_client_invoke_func(tee_rproc_ctx->tee_ctx, &arg, param);
> +	if (ret < 0 || arg.ret != 0) {
> +		dev_err(tee_rproc_ctx->dev,
> +			"TA_RPROC_FW_CMD_STOP_FW invoke failed TEE err: %x, ret:%x\n",
> +			arg.ret, ret);
> +		if (!ret)
> +			ret = -EIO;
> +	}
> +	if (trproc->rsc_table)
> +		iounmap(trproc->rsc_table);
> +	trproc->rsc_table = NULL;
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_stop);
> +
> +static const struct tee_client_device_id stm32_tee_rproc_id_table[] = {
> +	{UUID_INIT(0x80a4c275, 0x0a47, 0x4905,
> +		   0x82, 0x85, 0x14, 0x86, 0xa9, 0x77, 0x1a, 0x08)},
> +	{}
> +};
> +
> +struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id)
> +{
> +	struct tee_client_device *tee_device;
> +	struct tee_ioctl_open_session_arg sess_arg;
> +	struct tee_param param[MAX_TEE_PARAM_ARRY_MEMBER];
> +	struct tee_rproc *trproc;
> +	int ret;
> +
> +	/*
> +	 * The device is not probed by the TEE bus. We ignore the reason (bus could be not yet
> +	 * probed or service not available in the secure firmware)
> +	 * Assumption here is that the TEE bus is not probed.
> +	 */
> +	if (!tee_rproc_ctx)
> +		return ERR_PTR(-EPROBE_DEFER);
> +
> +	trproc =  devm_kzalloc(dev, sizeof(*trproc), GFP_KERNEL);
> +	if (!trproc)
> +		return ERR_PTR(-ENOMEM);
> +
> +	tee_device = to_tee_client_device(tee_rproc_ctx->dev);
> +	memset(&sess_arg, 0, sizeof(sess_arg));
> +
> +	/* Open session with rproc_tee load the OP-TEE Trusted Application */
> +	memcpy(sess_arg.uuid, tee_device->id.uuid.b, TEE_IOCTL_UUID_LEN);
> +
> +	sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
> +	sess_arg.num_params = 1;
> +
> +	param[0] = (struct tee_param) {
> +		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
> +		.u.value.a = rproc_id,
> +	};
> +
> +	ret = tee_client_open_session(tee_rproc_ctx->tee_ctx, &sess_arg, param);
> +	if (ret < 0 || sess_arg.ret != 0) {
> +		dev_err(dev, "tee_client_open_session failed, err: %x\n", sess_arg.ret);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	trproc->parent =  dev;
> +	trproc->rproc_id = rproc_id;
> +	trproc->session_id = sess_arg.session;
> +
> +	list_add_tail(&trproc->node, &tee_rproc_ctx->sessions);
> +
> +	return trproc;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_register);
> +
> +int tee_rproc_unregister(struct tee_rproc *trproc)
> +{
> +	int ret;
> +
> +	ret = tee_client_close_session(tee_rproc_ctx->tee_ctx, trproc->session_id);
> +	if (ret < 0)
> +		dev_err(trproc->parent,	"tee_client_close_session failed, err: %x\n", ret);
> +
> +	list_del(&trproc->node);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(tee_rproc_unregister);
> +
> +static int tee_rproc_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
> +{
> +	/* Today we support only the OP-TEE, could be extend to other tees */
> +	return (ver->impl_id == TEE_IMPL_ID_OPTEE);
> +}
> +
> +static int tee_rproc_probe(struct device *dev)
> +{
> +	struct tee_context *tee_ctx;
> +	int ret;
> +
> +	/* Open context with TEE driver */
> +	tee_ctx = tee_client_open_context(NULL, tee_rproc_ctx_match, NULL, NULL);
> +	if (IS_ERR(tee_ctx))
> +		return PTR_ERR(tee_ctx);
> +
> +	tee_rproc_ctx = devm_kzalloc(dev, sizeof(*tee_ctx), GFP_KERNEL);
> +	if (!tee_rproc_ctx) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	tee_rproc_ctx->dev = dev;
> +	tee_rproc_ctx->tee_ctx = tee_ctx;
> +	INIT_LIST_HEAD(&tee_rproc_ctx->sessions);
> +
> +	return 0;
> +err:
> +	tee_client_close_context(tee_ctx);
> +
> +	return ret;
> +}
> +
> +static int tee_rproc_remove(struct device *dev)
> +{
> +	struct tee_rproc *entry, *tmp;
> +
> +	list_for_each_entry_safe(entry, tmp, &tee_rproc_ctx->sessions, node) {
> +		tee_client_close_session(tee_rproc_ctx->tee_ctx, entry->session_id);
> +		list_del(&entry->node);
> +		kfree(entry);
> +	}
> +
> +	tee_client_close_context(tee_rproc_ctx->tee_ctx);
> +
> +	return 0;
> +}
> +
> +MODULE_DEVICE_TABLE(tee, stm32_tee_rproc_id_table);
> +
> +static struct tee_client_driver tee_rproc_fw_driver = {
> +	.id_table	= stm32_tee_rproc_id_table,
> +	.driver		= {
> +		.name		= KBUILD_MODNAME,
> +		.bus		= &tee_bus_type,
> +		.probe		= tee_rproc_probe,
> +		.remove		= tee_rproc_remove,
> +	},
> +};
> +
> +static int __init tee_rproc_fw_mod_init(void)
> +{
> +	return driver_register(&tee_rproc_fw_driver.driver);
> +}
> +
> +static void __exit tee_rproc_fw_mod_exit(void)
> +{
> +	driver_unregister(&tee_rproc_fw_driver.driver);
> +}
> +
> +module_init(tee_rproc_fw_mod_init);
> +module_exit(tee_rproc_fw_mod_exit);
> +
> +MODULE_DESCRIPTION(" TEE remote processor control driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/tee_remoteproc.h b/include/linux/tee_remoteproc.h
> new file mode 100644
> index 000000000000..7c9e91e989ba
> --- /dev/null
> +++ b/include/linux/tee_remoteproc.h
> @@ -0,0 +1,102 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright(c) 2023 STMicroelectronics - All Rights Reserved
> + */
> +
> +#ifndef TEE_REMOTEPROC_H
> +#define TEE_REMOTEPROC_H
> +
> +#include <linux/tee_drv.h>
> +#include <linux/firmware.h>
> +#include <linux/remoteproc.h>
> +
> +struct rproc;
> +
> +/**
> + * struct tee_rproc - TEE remoteproc structure
> + * @node:		Reference in list
> + * @rproc:		Remoteproc reference
> + * @parent:		Parent device
> + * @rproc_id:		Identifier of the target firmware
> + * @session_id:		TEE session identifier
> + * @rsc_table:		Resource table virtual address.
> + */
> +struct tee_rproc {
> +	struct list_head node;
> +	struct rproc *rproc;
> +	struct device *parent;
> +	u32 rproc_id;
> +	u32 session_id;
> +	struct resource_table *rsc_table;
> +};
> +
> +#if IS_ENABLED(CONFIG_TEE_REMOTEPROC)
> +
> +struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id);
> +int tee_rproc_unregister(struct tee_rproc *trproc);
> +
> +int tee_rproc_load_fw(struct rproc *rproc, const struct firmware *fw);
> +struct resource_table *tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz);
> +struct resource_table *tee_rproc_find_loaded_rsc_table(struct rproc *rproc,
> +						       const struct firmware *fw);
> +int tee_rproc_start(struct rproc *rproc);
> +int tee_rproc_stop(struct rproc *rproc);
> +
> +#else
> +
> +static inline struct tee_rproc *tee_rproc_register(struct device *dev, unsigned int rproc_id)
> +{
> +	return ERR_PTR(-ENODEV);
> +}
> +
> +static inline int tee_rproc_unregister(struct tee_rproc *trproc)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return 0;
> +}
> +
> +static inline int tee_rproc_load_fw(struct rproc *rproc,  const struct firmware *fw)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return 0;
> +}
> +
> +static inline int tee_rproc_start(struct rproc *rproc)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return 0;
> +}
> +
> +static inline int tee_rproc_stop(struct rproc *rproc)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return 0;
> +}
> +
> +static inline struct resource_table *
> +tee_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return NULL;
> +}
> +
> +static inline struct resource_table *
> +tee_rproc_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
> +{
> +	/* This shouldn't be possible */
> +	WARN_ON(1);
> +
> +	return NULL;
> +}
> +#endif /* CONFIG_TEE_REMOTEPROC */
> +#endif /* TEE_REMOTEPROC_H */
> -- 
> 2.25.1
> 


From andriy.shevchenko at linux.intel.com  Fri Feb 23 10:32:27 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 20:32:27 +0200
Subject: [PATCH v2] clkdev: Update clkdev id usage to allow for longer
 names
In-Reply-To: <DS0PR11MB64248E0C15C0B86A1CCF945BC1552@DS0PR11MB6424.namprd11.prod.outlook.com>
References: <20240223163516.796606-1-michael.j.ruhl@intel.com>
 <ZdjZCrpP52Hfbs6L@smile.fi.intel.com>
 <DS0PR11MB64248E0C15C0B86A1CCF945BC1552@DS0PR11MB6424.namprd11.prod.outlook.com>
Message-ID: <Zdjku0kxCvMl2HcU@smile.fi.intel.com>

On Fri, Feb 23, 2024 at 06:22:13PM +0000, Ruhl, Michael J wrote:
> >From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> >Sent: Friday, February 23, 2024 12:43 PM
> >On Fri, Feb 23, 2024 at 11:35:16AM -0500, Michael J. Ruhl wrote:

...

> I will remove.

Not remove, but move to the comments/changelog (after '---' line)

> I see your script automatically does a cover page...will use that format int
> the future.

Only if there are more than a single patch.

...

> >[1]: https://github.com/andy-shev/home-bin-
> >tools/blob/master/ge2maintainer.sh
> 
> Using your script I got:
> 
> To: "Michael J. Ruhl" <michael.j.ruhl at intel.com>,
>         linux-arm-kernel at lists.infradead.org,
>         linux-kernel at vger.kernel.org
> Cc: Russell King <linux at armlinux.org.uk>
> 
> My list (using get_maintainers.pl) is:
> 
> linux at armlinux.org.uk
> linux-arm-kernel at lists.infradead.org
> linux-kernel at vger.kernel.org
> 
> They appear to be the same....

Ah, the Russel's email looked like a mailing list, that what confused me.

> I don't have the plain text part on Russel's email (linxu at armlinux.org.uk)... Is that what is missing?

Yes :-)
But my script also uses a heuristics (which is not visible here) to add active
developers of the code in question based on the git history.

> Not sure what CCF is?

Common Clock Framework (This is how it's advertised in MAINTAINERS)

-- 
With Best Regards,
Andy Shevchenko




From mathieu.poirier at linaro.org  Fri Feb 23 10:32:47 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 23 Feb 2024 11:32:47 -0700
Subject: [PATCH v3 3/7] remoteproc: core: Add check on cached_table
 pointer
In-Reply-To: <20240214172127.1022199-4-arnaud.pouliquen@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <20240214172127.1022199-4-arnaud.pouliquen@foss.st.com>
Message-ID: <Zdjkz9bgaz+QkLg1@p14s>

On Wed, Feb 14, 2024 at 06:21:23PM +0100, Arnaud Pouliquen wrote:
> Add a check on the optional rproc->cached_table to perform the memory
> copy only if it is not null.
> 
> 2 use cases to support:
> - starting on boot, in which case rproc->cached_table can be null,
> - starting on crash recovery, where the cached table is used to save
>   the resource table configuration on stop and re-apply the configuration
>   on the re-start.
> 
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
> ---
>  drivers/remoteproc/remoteproc_core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
> index 283ca071e35c..34b0093689da 100644
> --- a/drivers/remoteproc/remoteproc_core.c
> +++ b/drivers/remoteproc/remoteproc_core.c
> @@ -1278,7 +1278,7 @@ static int rproc_start(struct rproc *rproc, const struct firmware *fw)
>  	 * that any subsequent changes will be applied to the loaded version.
>  	 */
>  	loaded_table = rproc_find_loaded_rsc_table(rproc, fw);
> -	if (loaded_table) {
> +	if (loaded_table && rproc->cached_table) {

... and this becomes:

        if (loaded_table != rproc->cached_table)

with a detailed comment about what is going on and a reference to
tee_rproc_parse_fw().

There are other things to adjust in this patchset but starting with that will
hopefully deal with a few of them.  We can address the rest at the next
iteration.

I am done reviewing this set.

Thanks,
Mathieu
>  		memcpy(loaded_table, rproc->cached_table, rproc->table_sz);
>  		rproc->table_ptr = loaded_table;
>  	}
> -- 
> 2.25.1
> 


From conor at kernel.org  Fri Feb 23 10:35:07 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 23 Feb 2024 18:35:07 +0000
Subject: [PATCH 1/1] media: dt-bindings: sony,imx290: Allow props from
 video-interface-devices
In-Reply-To: <20240223124744.545955-1-alexander.stein@ew.tq-group.com>
References: <20240223124744.545955-1-alexander.stein@ew.tq-group.com>
Message-ID: <20240223-catchable-parsley-a36bf8064154@spud>

On Fri, Feb 23, 2024 at 01:47:43PM +0100, Alexander Stein wrote:
> Allow properties from video-interface-devices. This aligns the bindings
> to sony,imx415.yaml. Changes inspired by commit e2e73ed46c395 ("media:
> dt-bindings: sony,imx415: Allow props from video-interface-devices")
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.
-------------- 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/20240223/ef53fa81/attachment.sig>

From cristian.marussi at arm.com  Fri Feb 23 10:35:22 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Fri, 23 Feb 2024 18:35:22 +0000
Subject: [PATCH 5/5] firmware: imx: add i.MX95 MISC driver
In-Reply-To: <20240202-imx95-bbm-misc-v1-5-3cb743020933@nxp.com>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
 <20240202-imx95-bbm-misc-v1-5-3cb743020933@nxp.com>
Message-ID: <ZdjlaiQQq67e52Q3@pluto>

On Fri, Feb 02, 2024 at 02:34:43PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> The i.MX95 System manager exports SCMI MISC protocol for linux to do
> various settings, such as set board gpio expander as wakeup source.
> 

Hi,

> The driver is to add the support.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/firmware/imx/Makefile   |  1 +
>  drivers/firmware/imx/sm-misc.c  | 92 +++++++++++++++++++++++++++++++++++++++++
>  include/linux/firmware/imx/sm.h | 33 +++++++++++++++
>  3 files changed, 126 insertions(+)
> 
> diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
> index fb20e22074e1..cb9c361d9b81 100644
> --- a/drivers/firmware/imx/Makefile
> +++ b/drivers/firmware/imx/Makefile
> @@ -2,3 +2,4 @@
>  obj-$(CONFIG_IMX_DSP)		+= imx-dsp.o
>  obj-$(CONFIG_IMX_SCU)		+= imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
>  obj-${CONFIG_IMX_SCMI_BBM_EXT}	+= sm-bbm.o
> +obj-${CONFIG_IMX_SCMI_MISC_EXT}	+= sm-misc.o

Same considerations about missing Kconfig as in BBM and implicit
dependency on the NXP MISC vendor module...this way also you cannot even
NOT compile this module when the Vendor protocol is compiled in for,
say, testing purposes...

> diff --git a/drivers/firmware/imx/sm-misc.c b/drivers/firmware/imx/sm-misc.c
> new file mode 100644
> index 000000000000..4410e69d256b
> --- /dev/null
> +++ b/drivers/firmware/imx/sm-misc.c
> @@ -0,0 +1,92 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2024 NXP.
> + */
> +
> +#include <linux/firmware/imx/sm.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/scmi_protocol.h>
> +#include <linux/scmi_nxp_protocol.h>
> +
> +static const struct scmi_imx_misc_proto_ops *imx_misc_ctrl_ops;
> +static struct scmi_protocol_handle *ph;

This global does NOT sound right...if there are multiple SCMI instances
defined in the DT this can be probed multiple times, and the MISC
protocol will be initialized multuple times, each instance will have
its distinct protocol_handle *ph...so store it somewhere like you did in
the BBM driver

> +struct notifier_block scmi_imx_misc_ctrl_nb;
> +
> +int scmi_imx_misc_ctrl_set(u32 id, u32 val)
> +{
> +	if (!ph)
> +		return -EPROBE_DEFER;
> +
> +	return imx_misc_ctrl_ops->misc_ctrl_set(ph, id, 1, &val);
> +};
> +EXPORT_SYMBOL(scmi_imx_misc_ctrl_set);
> +
> +int scmi_imx_misc_ctrl_get(u32 id, u32 *num, u32 *val)
> +{
> +	if (!ph)
> +		return -EPROBE_DEFER;
> +
> +	return imx_misc_ctrl_ops->misc_ctrl_get(ph, id, num, val);
> +}
> +EXPORT_SYMBOL(scmi_imx_misc_ctrl_get);
> +

Ok, now I suppose that you want to be sure to run just one instance if
this driver...

> +static int scmi_imx_misc_ctrl_notifier(struct notifier_block *nb,
> +				       unsigned long event, void *data)
> +{
> +	return 0;
> +}

What is the point of this ?

> +
> +static int scmi_imx_misc_ctrl_probe(struct scmi_device *sdev)
> +{
> +	const struct scmi_handle *handle = sdev->handle;
> +	struct device_node *np = sdev->dev.of_node;
> +	u32 src_id, evt_id, wu_num;
> +	int ret, i;
> +
> +	if (!handle)
> +		return -ENODEV;
> +
> +	imx_misc_ctrl_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_IMX_MISC, &ph);
> +	if (IS_ERR(imx_misc_ctrl_ops))
> +		return PTR_ERR(imx_misc_ctrl_ops);
> +
> +	scmi_imx_misc_ctrl_nb.notifier_call = &scmi_imx_misc_ctrl_notifier;
> +	wu_num = of_property_count_u32_elems(np, "wakeup-sources");
> +	if (wu_num % 2) {
> +		dev_err(&sdev->dev, "Invalid wakeup-sources\n");
> +		return -EINVAL;
> +	}
> +
> +	for (i = 0; i < wu_num; i += 2) {
> +		WARN_ON(of_property_read_u32_index(np, "wakeup-sources", i, &src_id));
> +		WARN_ON(of_property_read_u32_index(np, "wakeup-sources", i + 1, &evt_id));
> +		ret = handle->notify_ops->devm_event_notifier_register(sdev, SCMI_PROTOCOL_IMX_MISC,
> +								       evt_id,
> +								       &src_id,
> +								       &scmi_imx_misc_ctrl_nb);

...when probed more than once this will lead to the same global nb registered on 2
different notification chains....

> +		if (ret)
> +			dev_err(&sdev->dev, "Failed to register scmi misc event: %d\n", src_id);
> +	}
> +
> +	return 0;
> +
> +}
> +
> +static const struct scmi_device_id scmi_id_table[] = {
> +	{ SCMI_PROTOCOL_IMX_MISC, "imx-misc-ctrl" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(scmi, scmi_id_table);
> +
> +static struct scmi_driver scmi_imx_misc_ctrl_driver = {
> +	.name = "scmi-imx-misc-ctrl",
> +	.probe = scmi_imx_misc_ctrl_probe,
> +	.id_table = scmi_id_table,
> +};
> +module_scmi_driver(scmi_imx_misc_ctrl_driver);
> +

All in all, I suppose the main thing to reason about this driver is if you
want/plan to allow for multiple instances of it to be loaded/probed on the same
running system or not...

If you think that this driver HAS STRICTLY to be probed once, and having
2 DT protocol nodes for MISC it is certainly an error, we will have to
add some mechianism in the SCMI core to be able to mark this as single
instance and refuse to create more than one device for this protocol...a
sort of generalization of what is done in a custom way by the core for
SYSTEM_POWER, since we dont want to have multiple sources of shutdown
events...

Alternnatively you will have to make this survive multiple
probes...keeping track of multiple *ph for each probe() and handling
that in your EXPORTED funcs...thing that seems awkard a bit...but you
only know how this is an will be used.

> +MODULE_AUTHOR("Peng Fan <peng.fan at nxp.com>");
> +MODULE_DESCRIPTION("IMX SM MISC driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/firmware/imx/sm.h b/include/linux/firmware/imx/sm.h
> new file mode 100644
> index 000000000000..daad4bdf7d1c
> --- /dev/null
> +++ b/include/linux/firmware/imx/sm.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#ifndef _SCMI_IMX_H
> +#define _SCMI_IMX_H
> +
> +#include <linux/bitfield.h>
> +#include <linux/types.h>
> +
> +#define SCMI_IMX_CTRL_PDM_CLK_SEL	0	/* AON PDM clock sel */
> +#define SCMI_IMX_CTRL_MQS1_SETTINGS	1	/* AON MQS settings */
> +#define SCMI_IMX_CTRL_SAI1_MCLK		2	/* AON SAI1 MCLK */
> +#define SCMI_IMX_CTRL_SAI3_MCLK		3	/* WAKE SAI3 MCLK */
> +#define SCMI_IMX_CTRL_SAI4_MCLK		4	/* WAKE SAI4 MCLK */
> +#define SCMI_IMX_CTRL_SAI5_MCLK		5	/* WAKE SAI5 MCLK */
> +
> +#if IS_ENABLED(CONFIG_IMX_SCMI_MISC_EXT)
> +int scmi_imx_misc_ctrl_get(u32 id, u32 *num, u32 *val);
> +int scmi_imx_misc_ctrl_set(u32 id, u32 val);
> +#else
> +static inline int scmi_imx_misc_ctrl_get(u32 id, u32 *num, u32 *val)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +static inline int scmi_imx_misc_ctrl_set(u32 id, u32 val);
> +{
> +	return -EOPNOTSUPP;
> +}
> +#endif
> +#endif
> 

Thanks,
Cristian


From conor at kernel.org  Fri Feb 23 10:37:12 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 23 Feb 2024 18:37:12 +0000
Subject: [PATCH v2 04/14] dt-bindings: mfd: ti,tps6594: Add TI TPS65224
 PMIC
In-Reply-To: <20240223093701.66034-5-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
 <20240223093701.66034-5-bhargav.r@ltts.com>
Message-ID: <20240223-amenity-amaze-771541e8c9af@spud>

On Fri, Feb 23, 2024 at 03:06:51PM +0530, Bhargav Raviprakash wrote:
> TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
> regulators, it includes additional features like GPIOs, watchdog, ESMs
> (Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
> managing the state of the device.
> 
> In addition TPS65224 has support for 12-bit ADC and does not have RTC
> unlike TPS6594.
> 
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
>  Documentation/devicetree/bindings/mfd/ti,tps6594.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
> index 9d43376be..6341b6070 100644
> --- a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
> +++ b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
> @@ -21,6 +21,7 @@ properties:
>        - ti,lp8764-q1
>        - ti,tps6593-q1
>        - ti,tps6594-q1
> +      - ti,tps65224-q1
>  
>    reg:
>      description: I2C slave address or SPI chip select number.
> -- 
> 2.25.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/20240223/7a995bb0/attachment-0001.sig>

From mathieu.poirier at linaro.org  Fri Feb 23 10:37:29 2024
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 23 Feb 2024 11:37:29 -0700
Subject: [PATCH v3 7/7] remoteproc: stm32: Add support of an OP-TEE TA to
 load the firmware
In-Reply-To: <609373ba-c81d-4aee-81cb-8628e2c6897b@foss.st.com>
References: <20240214172127.1022199-1-arnaud.pouliquen@foss.st.com>
 <20240214172127.1022199-8-arnaud.pouliquen@foss.st.com>
 <ZdeaUGpWlqGOG31u@p14s>
 <609373ba-c81d-4aee-81cb-8628e2c6897b@foss.st.com>
Message-ID: <Zdjl6Z2ktTwi+oWp@p14s>

On Fri, Feb 23, 2024 at 02:54:13PM +0100, Arnaud POULIQUEN wrote:
> Hello Mathieu,
> 
> On 2/22/24 20:02, Mathieu Poirier wrote:
> > Hi,
> > 
> > On Wed, Feb 14, 2024 at 06:21:27PM +0100, Arnaud Pouliquen wrote:
> >> The new TEE remoteproc device is used to manage remote firmware in a
> >> secure, trusted context. The 'st,stm32mp1-m4-tee' compatibility is
> >> introduced to delegate the loading of the firmware to the trusted
> >> execution context. In such cases, the firmware should be signed and
> >> adhere to the image format defined by the TEE.
> >>
> >> A new "to_attach" field is introduced to differentiate the use cases
> >> "firmware loaded by the boot stage" and "firmware loaded by the TEE".
> >>
> >> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
> >> ---
> >> V2 to V3 update:
> >> - remove stm32_rproc_tee_elf_sanity_check(), stm32_rproc_tee_elf_load()
> >>   stm32_rproc_tee_elf_find_loaded_rsc_table() and  stm32_rproc_tee_start() that are bnow unused
> >> - use new rproc::alt_boot field to sepcify that the alternate fboot method is used
> >> - use stm32_rproc::to_attach field to differenciate attch mode from remoteproc tee boot mode.
> >> - remove the used of stm32_rproc::fw_loaded
> >> ---
> >>  drivers/remoteproc/stm32_rproc.c | 85 +++++++++++++++++++++++++++++---
> >>  1 file changed, 79 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
> >> index fcc0001e2657..9cfcf66462e0 100644
> >> --- a/drivers/remoteproc/stm32_rproc.c
> >> +++ b/drivers/remoteproc/stm32_rproc.c
> >> @@ -20,6 +20,7 @@
> >>  #include <linux/remoteproc.h>
> >>  #include <linux/reset.h>
> >>  #include <linux/slab.h>
> >> +#include <linux/tee_remoteproc.h>
> >>  #include <linux/workqueue.h>
> >>  
> >>  #include "remoteproc_internal.h"
> >> @@ -49,6 +50,9 @@
> >>  #define M4_STATE_STANDBY	4
> >>  #define M4_STATE_CRASH		5
> >>  
> >> +/* Remote processor unique identifier aligned with the Trusted Execution Environment definitions */
> >> +#define STM32_MP1_M4_PROC_ID    0
> >> +
> >>  struct stm32_syscon {
> >>  	struct regmap *map;
> >>  	u32 reg;
> >> @@ -90,6 +94,8 @@ struct stm32_rproc {
> >>  	struct stm32_mbox mb[MBOX_NB_MBX];
> >>  	struct workqueue_struct *workqueue;
> >>  	bool hold_boot_smc;
> >> +	bool to_attach;
> >> +	struct tee_rproc *trproc;
> >>  	void __iomem *rsc_va;
> >>  };
> >>  
> >> @@ -253,10 +259,30 @@ static int stm32_rproc_release(struct rproc *rproc)
> >>  			return err;
> >>  		}
> >>  	}
> >> +	ddata->to_attach = false;
> >>  
> >>  	return err;
> >>  }
> >>  
> >> +static int stm32_rproc_tee_attach(struct rproc *rproc)
> >> +{
> >> +	/* Nothing to do, remote proc already started by the secured context. */
> >> +	return 0;
> >> +}
> >> +
> >> +static int stm32_rproc_tee_stop(struct rproc *rproc)
> >> +{
> >> +	int err;
> >> +
> >> +	stm32_rproc_request_shutdown(rproc);
> >> +
> >> +	err = tee_rproc_stop(rproc);
> >> +	if (err)
> >> +		return err;
> >> +
> >> +	return stm32_rproc_release(rproc);
> >> +}
> >> +
> >>  static int stm32_rproc_prepare(struct rproc *rproc)
> >>  {
> >>  	struct device *dev = rproc->dev.parent;
> >> @@ -637,10 +663,14 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
> >>  {
> >>  	struct stm32_rproc *ddata = rproc->priv;
> >>  	struct device *dev = rproc->dev.parent;
> >> +	struct tee_rproc *trproc = ddata->trproc;
> >>  	phys_addr_t rsc_pa;
> >>  	u32 rsc_da;
> >>  	int err;
> >>  
> >> +	if (trproc && !ddata->to_attach)
> >> +		return tee_rproc_get_loaded_rsc_table(rproc, table_sz);
> >> +
> > 
> > Why do we need a flag at all?  Why can't st_rproc_tee_ops::get_loaded_rsc_table
> > be set to tee_rproc_get_loaded_rsc_table()?
> 
> 
> This function is used to retrieve the address of the resource table in 3 cases
> - attach to a firmware started by the boot loader (U-boot).
> - load of the firmware by OP-TEE.
> - crash recovery on a signed firmware started by the boot loader.
> 
> The flag is used to differentiate the attch from the other uses cases
> For instance we support this use case.
> 1) attach to the firmware on boot
> 2) crash during runtime
>   2a) stop the firmware by OP-TEE( ddata->to_attach set to 0)
>   2b) load the firmware by OP-TEE
>   2c) get the loaded resource table from OP-TEE (we can not guaranty
>       that the firmware loaded on recovery is the same)
>   2d) restart the firmware by OP-TEE

This is not maintainable and needs to be broken down into smaller
building blocks.  The introduction of tee_rproc_parse_fw() should help dealing
with some of the complexity.

> 
> > 
> >>  	/* The resource table has already been mapped, nothing to do */
> >>  	if (ddata->rsc_va)
> >>  		goto done;
> >> @@ -693,8 +723,20 @@ static const struct rproc_ops st_rproc_ops = {
> >>  	.get_boot_addr	= rproc_elf_get_boot_addr,
> >>  };
> >>  
> >> +static const struct rproc_ops st_rproc_tee_ops = {
> >> +	.prepare	= stm32_rproc_prepare,
> >> +	.start		= tee_rproc_start,
> >> +	.stop		= stm32_rproc_tee_stop,
> >> +	.attach		= stm32_rproc_tee_attach,
> >> +	.kick		= stm32_rproc_kick,
> >> +	.get_loaded_rsc_table = stm32_rproc_get_loaded_rsc_table,
> >> +	.find_loaded_rsc_table = tee_rproc_find_loaded_rsc_table,
> >> +	.load		= tee_rproc_load_fw,
> >> +};
> >> +
> >>  static const struct of_device_id stm32_rproc_match[] = {
> >> -	{ .compatible = "st,stm32mp1-m4" },
> >> +	{.compatible = "st,stm32mp1-m4",},
> >> +	{.compatible = "st,stm32mp1-m4-tee",},
> >>  	{},
> >>  };
> >>  MODULE_DEVICE_TABLE(of, stm32_rproc_match);
> >> @@ -853,6 +895,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>  	struct device *dev = &pdev->dev;
> >>  	struct stm32_rproc *ddata;
> >>  	struct device_node *np = dev->of_node;
> >> +	struct tee_rproc *trproc = NULL;
> >>  	struct rproc *rproc;
> >>  	unsigned int state;
> >>  	int ret;
> >> @@ -861,12 +904,33 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>  	if (ret)
> >>  		return ret;
> >>  
> >> -	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
> >> -	if (!rproc)
> >> -		return -ENOMEM;
> > 
> > This patch doesn't apply to rproc-next - please rebase.
> 
> Yes, sure. I forgot to mention in my cover letter that my series has been
> applied and tested on 841c35169323 (Linux 6.8-rc4).
> 
> > 
> > 
> >> +	if (of_device_is_compatible(np, "st,stm32mp1-m4-tee")) {
> >> +		/*
> >> +		 * Delegate the firmware management to the secure context.
> >> +		 * The firmware loaded has to be signed.
> >> +		 */
> >> +		trproc = tee_rproc_register(dev, STM32_MP1_M4_PROC_ID);
> >> +		if (IS_ERR(trproc)) {
> >> +			dev_err_probe(dev, PTR_ERR(trproc),
> >> +				      "signed firmware not supported by TEE\n");
> >> +			return PTR_ERR(trproc);
> >> +		}
> >> +	}
> >>  
> >> -	ddata = rproc->priv;
> >> +	rproc = rproc_alloc(dev, np->name,
> >> +			    trproc ? &st_rproc_tee_ops : &st_rproc_ops,
> >> +			    NULL, sizeof(*ddata));
> >> +	if (!rproc) {
> >> +		ret = -ENOMEM;
> >> +		goto free_tee;
> >> +	}
> >>  
> >> +	ddata = rproc->priv;
> >> +	ddata->trproc = trproc;
> > 
> > My opinion hasn't changed from the previous patchet, i.e tee_rproc should be
> > folded in struct rproc as rproc::tee_interface.
> 
> Sure, I will do it in next version
> 
> > 
> > More comments to come shortly...
> > 
> 
> Thanks!
> Arnaud
> 
> >> +	if (trproc) {
> >> +		rproc->alt_boot = true;
> >> +		trproc->rproc = rproc;
> >> +	}
> >>  	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
> >>  
> >>  	ret = stm32_rproc_parse_dt(pdev, ddata, &rproc->auto_boot);
> >> @@ -881,8 +945,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>  	if (ret)
> >>  		goto free_rproc;
> >>  
> >> -	if (state == M4_STATE_CRUN)
> >> +	if (state == M4_STATE_CRUN) {
> >>  		rproc->state = RPROC_DETACHED;
> >> +		ddata->to_attach = true;
> >> +	}
> >>  
> >>  	rproc->has_iommu = false;
> >>  	ddata->workqueue = create_workqueue(dev_name(dev));
> >> @@ -916,6 +982,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> >>  		device_init_wakeup(dev, false);
> >>  	}
> >>  	rproc_free(rproc);
> >> +free_tee:
> >> +	if (trproc)
> >> +		tee_rproc_unregister(trproc);
> >> +
> >>  	return ret;
> >>  }
> >>  
> >> @@ -923,6 +993,7 @@ static void stm32_rproc_remove(struct platform_device *pdev)
> >>  {
> >>  	struct rproc *rproc = platform_get_drvdata(pdev);
> >>  	struct stm32_rproc *ddata = rproc->priv;
> >> +	struct tee_rproc *trproc = ddata->trproc;
> >>  	struct device *dev = &pdev->dev;
> >>  
> >>  	if (atomic_read(&rproc->power) > 0)
> >> @@ -937,6 +1008,8 @@ static void stm32_rproc_remove(struct platform_device *pdev)
> >>  		device_init_wakeup(dev, false);
> >>  	}
> >>  	rproc_free(rproc);
> >> +	if (trproc)
> >> +		tee_rproc_unregister(trproc);
> >>  }
> >>  
> >>  static int stm32_rproc_suspend(struct device *dev)
> >> -- 
> >> 2.25.1
> >>
> > 


From pr-tracker-bot at kernel.org  Fri Feb 23 10:44:07 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 23 Feb 2024 18:44:07 +0000
Subject: [GIT PULL] arm64 fixes for -rc6
In-Reply-To: <20240223102531.GB10274@willie-the-truck>
References: <20240223102531.GB10274@willie-the-truck>
Message-ID: <170871384747.26987.14345883877585633830.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 23 Feb 2024 10:25:32 +0000:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/86f01602a41fb711f992ad6ab6483a4487829b4c

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From pr-tracker-bot at kernel.org  Fri Feb 23 10:44:05 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 23 Feb 2024 18:44:05 +0000
Subject: [GIT PULL] Arm and RISC-V SoC fixes for 6.8, part 2
In-Reply-To: <04be5855-9b18-4ff0-8554-8b9d626a7845@app.fastmail.com>
References: <04be5855-9b18-4ff0-8554-8b9d626a7845@app.fastmail.com>
Message-ID: <170871384578.26987.6883523533721597550.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 23 Feb 2024 18:00:07 +0100:

> https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm-fixes-6.8-2

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/e44baca779686425d0ca02491731b6d688c6711d

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From conor at kernel.org  Fri Feb 23 10:47:06 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 23 Feb 2024 18:47:06 +0000
Subject: [PATCH v6 06/13] dt-bindings: mtd: brcmnand: Add ecc strap
 property
In-Reply-To: <20240223034758.13753-7-william.zhang@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
 <20240223034758.13753-7-william.zhang@broadcom.com>
Message-ID: <20240223-revolver-astute-8fb3bdbb6b2e@spud>

On Thu, Feb 22, 2024 at 07:47:51PM -0800, William Zhang wrote:
> Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
> board boot strap for broadband board designs because they do not specify
> ecc setting in dts but rather using the strap setting.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.
-------------- 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/20240223/3cfebcfb/attachment-0001.sig>

From conor at kernel.org  Fri Feb 23 10:51:31 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 23 Feb 2024 18:51:31 +0000
Subject: [PATCH 1/2] dt-bindings: arm: aspeed: add ASUS X4TF board
In-Reply-To: <TYZPR04MB6596ED7F905CB53191F48A289D552@TYZPR04MB6596.apcprd04.prod.outlook.com>
References: <20240222085914.1218037-1-Kelly_Hung@asus.com>
 <20240222-getting-nebulizer-8f75ba8063b1@spud>
 <TYZPR04MB6596ED7F905CB53191F48A289D552@TYZPR04MB6596.apcprd04.prod.outlook.com>
Message-ID: <20240223-sprang-rework-4b0fb07ccc98@spud>

I have no idea what his email is meant to mean, it just looks like a
copy of your original patch. That said, you have a footer about the mail
contents of being confidential, so please fix that too.

Thanks,
Conor.
-------------- 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/20240223/3093fdc0/attachment.sig>

From jgg at nvidia.com  Fri Feb 23 10:53:58 2024
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 23 Feb 2024 14:53:58 -0400
Subject: [PATCH v5 02/17] iommu/arm-smmu-v3: Consolidate the STE
 generation for abort/bypass
In-Reply-To: <2ca7f64e-a9e3-4d47-b04f-726c86223fd6@arm.com>
References: <2-v5-cd1be8dd9c71+3fa-smmuv3_newapi_p1_jgg@nvidia.com>
 <2ca7f64e-a9e3-4d47-b04f-726c86223fd6@arm.com>
Message-ID: <20240223185358.GA791502@nvidia.com>

On Thu, Feb 15, 2024 at 05:27:09PM +0000, Robin Murphy wrote:
> > @@ -1583,22 +1595,20 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
> >   	arm_smmu_write_ste(master, sid, dst, &target);
> >   }
> > +/*
> > + * This can safely directly manipulate the STE memory without a sync sequence
> > + * because the STE table has not been installed in the SMMU yet.
> > + */
> >   static void arm_smmu_init_bypass_stes(struct arm_smmu_ste *strtab,
> 
> This name is long out-of-date - if we're refreshing this area, please rename
> to something relevant to what it actually does, e.g. s/bypass/initial/.

Done

> Although frankly I also think that at this point we should just get rid of
> the disable_bypass parameter altogether - it's been almost entirely
> meaningless since default domain support was added, and any tenuous cases
> for wanting inital STEs to be bypass should probably be using RMRs now
> anyway.

I can write the patch for this if you and Will agree

Thanks,
Jason


From conor at kernel.org  Fri Feb 23 10:56:20 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 23 Feb 2024 18:56:20 +0000
Subject: [PATCH 04/14] media: dt-bindings: media: rockchip,px30-vip:
 allow for different variants
In-Reply-To: <5bb0b0a9-3d4c-4303-aa43-38789bee286d@wolfvision.net>
References: <20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b@wolfvision.net>
 <20240220-v6-8-topic-rk3568-vicap-v1-4-2680a1fa640b@wolfvision.net>
 <20240220-catchy-cupcake-e600e5af7650@spud>
 <5bb0b0a9-3d4c-4303-aa43-38789bee286d@wolfvision.net>
Message-ID: <20240223-repose-snuff-54d75755e9f7@spud>

On Fri, Feb 23, 2024 at 08:03:20AM +0100, Michael Riesch wrote:
> Hi Conor,
> 
> On 2/20/24 19:58, Conor Dooley wrote:
> > Hey,
> > 
> > On Tue, Feb 20, 2024 at 10:39:14AM +0100, Michael Riesch wrote:
> >> Move the documentation of clocks and resets to a allOf: structure in order
> >> to allow for different variants of the IP block.
> >>
> >> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> >> ---
> >>  .../bindings/media/rockchip,px30-vip.yaml          | 58 ++++++++++++++--------
> >>  1 file changed, 37 insertions(+), 21 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
> >> index 675a1ea47210..7168f166798c 100644
> >> --- a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
> >> +++ b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
> >> @@ -24,32 +24,16 @@ properties:
> >>    interrupts:
> >>      maxItems: 1
> >>  
> >> -  clocks:
> >> -    items:
> >> -      - description: ACLK
> >> -      - description: HCLK
> >> -      - description: PCLK
> >> -
> >> -  clock-names:
> >> -    items:
> >> -      - const: aclk
> >> -      - const: hclk
> >> -      - const: pclk
> >> +  clocks: true
> >> +
> >> +  clock-names: true
> > 
> > This is, unfortunately, not how we like multiple soc support to be
> > handled. Instead, the widest constraints are added at the top level
> > and constrained by the allOf. If none of the names etc are shared, at
> > least the widest constraints for minItems and maxItems should be able to
> > be here.
> 
> Just to make sure I got it right:
> 
> clocks:
>   minItems: 3
>   maxItems: 4

>   items:
>     - const: aclk
>     - const: hclk

If the names themselves are all different, I wouldn't bother with this,
and just constrain the numbers at the top level.
Otherwise ye, on the right track here.
-------------- 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/20240223/6426feb2/attachment.sig>

From jernej.skrabec at gmail.com  Fri Feb 23 11:51:12 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Fri, 23 Feb 2024 20:51:12 +0100
Subject: [PATCH v3] thermal/drivers/sun8i: Don't fail probe due to zone
 registration failure
In-Reply-To: <20240123-thermal-sun8i-registration-v3-1-3e5771b1bbdd@kernel.org>
References: <20240123-thermal-sun8i-registration-v3-1-3e5771b1bbdd@kernel.org>
Message-ID: <12383045.O9o76ZdvQC@jernej-laptop>

Hi Daniel, Rafael,

is there any issue with this patch? Can you apply it?

Best regards,
Jernej

Dne sreda, 24. januar 2024 ob 00:33:07 CET je Mark Brown napisal(a):
> Currently the sun8i thermal driver will fail to probe if any of the
> thermal zones it is registering fails to register with the thermal core.
> Since we currently do not define any trip points for the GPU thermal
> zones on at least A64 or H5 this means that we have no thermal support
> on these platforms:
> 
> [    1.698703] thermal_sys: Failed to find 'trips' node
> [    1.698707] thermal_sys: Failed to find trip points for thermal-sensor id=1
> 
> even though the main CPU thermal zone on both SoCs is fully configured.
> This does not seem ideal, while we may not be able to use all the zones
> it seems better to have those zones which are usable be operational.
> Instead just carry on registering zones if we get any non-deferral
> error, allowing use of those zones which are usable.
> 
> This means that we also need to update the interrupt handler to not
> attempt to notify the core for events on zones which we have not
> registered, I didn't see an ability to mask individual interrupts and
> I would expect that interrupts would still be indicated in the ISR even
> if they were masked.
> 
> Reviewed-by: Vasily Khoruzhick <anarsoul at gmail.com>
> Acked-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> Changes in v3:
> - Rebase onto v6.8-rc1.
> - Link to v2: https://lore.kernel.org/r/20230912-thermal-sun8i-registration-v2-1-077230107768 at kernel.org
> 
> Changes in v2:
> - Rebase onto v6.6-rc1.
> - Link to v1: https://lore.kernel.org/r/20230718-thermal-sun8i-registration-v1-1-c95b1b070340 at kernel.org
> ---
>  drivers/thermal/sun8i_thermal.c | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
> index 6a8e386dbc8d..c2a8ae7f8f2f 100644
> --- a/drivers/thermal/sun8i_thermal.c
> +++ b/drivers/thermal/sun8i_thermal.c
> @@ -188,6 +188,9 @@ static irqreturn_t sun8i_irq_thread(int irq, void *data)
>  	int i;
>  
>  	for_each_set_bit(i, &irq_bitmap, tmdev->chip->sensor_num) {
> +		/* We allow some zones to not register. */
> +		if (IS_ERR(tmdev->sensor[i].tzd))
> +			continue;
>  		thermal_zone_device_update(tmdev->sensor[i].tzd,
>  					   THERMAL_EVENT_UNSPECIFIED);
>  	}
> @@ -465,8 +468,17 @@ static int sun8i_ths_register(struct ths_device *tmdev)
>  						      i,
>  						      &tmdev->sensor[i],
>  						      &ths_ops);
> -		if (IS_ERR(tmdev->sensor[i].tzd))
> -			return PTR_ERR(tmdev->sensor[i].tzd);
> +
> +		/*
> +		 * If an individual zone fails to register for reasons
> +		 * other than probe deferral (eg, a bad DT) then carry
> +		 * on, other zones might register successfully.
> +		 */
> +		if (IS_ERR(tmdev->sensor[i].tzd)) {
> +			if (PTR_ERR(tmdev->sensor[i].tzd) == -EPROBE_DEFER)
> +				return PTR_ERR(tmdev->sensor[i].tzd);
> +			continue;
> +		}
>  
>  		devm_thermal_add_hwmon_sysfs(tmdev->dev, tmdev->sensor[i].tzd);
>  	}
> 
> ---
> base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
> change-id: 20230718-thermal-sun8i-registration-df3a136ccafa
> 
> Best regards,
> 






From linux at armlinux.org.uk  Fri Feb 23 11:49:33 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 23 Feb 2024 19:49:33 +0000
Subject: [PATCH v2] clkdev: Update clkdev id usage to allow for longer
 names
In-Reply-To: <Zdjku0kxCvMl2HcU@smile.fi.intel.com>
References: <20240223163516.796606-1-michael.j.ruhl@intel.com>
 <ZdjZCrpP52Hfbs6L@smile.fi.intel.com>
 <DS0PR11MB64248E0C15C0B86A1CCF945BC1552@DS0PR11MB6424.namprd11.prod.outlook.com>
 <Zdjku0kxCvMl2HcU@smile.fi.intel.com>
Message-ID: <Zdj2zaicBvkTOZZe@shell.armlinux.org.uk>

On Fri, Feb 23, 2024 at 08:32:27PM +0200, Andy Shevchenko wrote:
> On Fri, Feb 23, 2024 at 06:22:13PM +0000, Ruhl, Michael J wrote:
> > >From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> > >Sent: Friday, February 23, 2024 12:43 PM
> > >On Fri, Feb 23, 2024 at 11:35:16AM -0500, Michael J. Ruhl wrote:
> 
> ...
> 
> > I will remove.
> 
> Not remove, but move to the comments/changelog (after '---' line)
> 
> > I see your script automatically does a cover page...will use that format int
> > the future.
> 
> Only if there are more than a single patch.
> 
> ...
> 
> > >[1]: https://github.com/andy-shev/home-bin-
> > >tools/blob/master/ge2maintainer.sh
> > 
> > Using your script I got:
> > 
> > To: "Michael J. Ruhl" <michael.j.ruhl at intel.com>,
> >         linux-arm-kernel at lists.infradead.org,
> >         linux-kernel at vger.kernel.org
> > Cc: Russell King <linux at armlinux.org.uk>
> > 
> > My list (using get_maintainers.pl) is:
> > 
> > linux at armlinux.org.uk
> > linux-arm-kernel at lists.infradead.org
> > linux-kernel at vger.kernel.org
> > 
> > They appear to be the same....
> 
> Ah, the Russel's email looked like a mailing list, that what confused me.

Joe, I think you know that I'll pick up on your mis-spelling of my
name... and I take that as an implicit right to call you something
other than your proper name. :D

Secondly, because the Cc contained my name, I fail to see how you can
confuse that with a mailing list. Maybe your script that you mentioned
strips the names from the email addresses, thereby adding to your
confusion - and maybe that isn't such a good idea after all? I'm not
the only one who uses linux at ... There are six people in total listed in
MAINTAINERS who have a linux at ... email address there.

> > I don't have the plain text part on Russel's email (linxu at armlinux.org.uk)... Is that what is missing?
> 
> Yes :-)
> But my script also uses a heuristics (which is not visible here) to add active
> developers of the code in question based on the git history.

The developers in question for this part of the code is me and not the
CCF. Therefore, what has been done by the patch author is reasonable
and no special scripts are necessary.

While my main git server is offline, I'm happy for the CCF folk
to pick this up, so:

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Michael, please resubmit with my r-b line above, and include the CCF
folk in that posting:

Michael Turquette <mturquette at baylibre.com>
Stephen Boyd <sboyd at kernel.org>
linux-clk at vger.kernel.org

Thanks!

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


From jernej.skrabec at gmail.com  Fri Feb 23 11:59:08 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Fri, 23 Feb 2024 20:59:08 +0100
Subject: [PATCH v5 7/7] arm64: dts: allwinner: h616: Add thermal sensor and zones
In-Reply-To: <20240219153639.179814-8-andre.przywara@arm.com>
References: <20240219153639.179814-1-andre.przywara@arm.com>
 <20240219153639.179814-8-andre.przywara@arm.com>
Message-ID: <6017645.lOV4Wx5bFT@jernej-laptop>

Dne ponedeljek, 19. februar 2024 ob 16:36:39 CET je Andre Przywara napisal(a):
> From: Martin Botka <martin.botka at somainline.org>
> 
> There are four thermal sensors:
> - CPU
> - GPU
> - VE
> - DRAM
> 
> Add the thermal sensor configuration and the thermal zones.
> 
> Signed-off-by: Martin Botka <martin.botka at somainline.org>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

I can't cleanly apply patch on top of sunxi/dt-for-6.9. Can you please rebase?

Best regards,
Jernej

> ---
>  .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 88 +++++++++++++++++++
>  1 file changed, 88 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> index 12ffabc79bcde..7c7d7c285505c 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> @@ -9,6 +9,7 @@
>  #include <dt-bindings/clock/sun6i-rtc.h>
>  #include <dt-bindings/reset/sun50i-h616-ccu.h>
>  #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
> +#include <dt-bindings/thermal/thermal.h>
>  
>  / {
>  	interrupt-parent = <&gic>;
> @@ -138,6 +139,10 @@ sid: efuse at 3006000 {
>  			reg = <0x03006000 0x1000>;
>  			#address-cells = <1>;
>  			#size-cells = <1>;
> +
> +			ths_calibration: thermal-sensor-calibration at 14 {
> +				reg = <0x14 0x8>;
> +			};
>  		};
>  
>  		watchdog: watchdog at 30090a0 {
> @@ -517,6 +522,19 @@ mdio0: mdio {
>  			};
>  		};
>  
> +		ths: thermal-sensor at 5070400 {
> +			compatible = "allwinner,sun50i-h616-ths";
> +			reg = <0x05070400 0x400>;
> +			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&ccu CLK_BUS_THS>;
> +			clock-names = "bus";
> +			resets = <&ccu RST_BUS_THS>;
> +			nvmem-cells = <&ths_calibration>;
> +			nvmem-cell-names = "calibration";
> +			allwinner,sram = <&syscon>;
> +			#thermal-sensor-cells = <1>;
> +		};
> +
>  		usbotg: usb at 5100000 {
>  			compatible = "allwinner,sun50i-h616-musb",
>  				     "allwinner,sun8i-h3-musb";
> @@ -761,4 +779,74 @@ r_rsb: rsb at 7083000 {
>  			#size-cells = <0>;
>  		};
>  	};
> +
> +	thermal-zones {
> +		cpu-thermal {
> +			polling-delay-passive = <500>;
> +			polling-delay = <1000>;
> +			thermal-sensors = <&ths 2>;
> +			sustainable-power = <1000>;
> +
> +			trips {
> +				cpu_threshold: cpu-trip-0 {
> +					temperature = <60000>;
> +					type = "passive";
> +					hysteresis = <0>;
> +				};
> +				cpu_target: cpu-trip-1 {
> +					temperature = <70000>;
> +					type = "passive";
> +					hysteresis = <0>;
> +				};
> +				cpu_critical: cpu-trip-2 {
> +					temperature = <110000>;
> +					type = "critical";
> +					hysteresis = <0>;
> +				};
> +			};
> +		};
> +
> +		gpu-thermal {
> +			polling-delay-passive = <500>;
> +			polling-delay = <1000>;
> +			thermal-sensors = <&ths 0>;
> +			sustainable-power = <1100>;
> +
> +			trips {
> +				gpu_temp_critical: gpu-trip-0 {
> +					temperature = <110000>;
> +					type = "critical";
> +					hysteresis = <0>;
> +				};
> +			};
> +		};
> +
> +		ve-thermal {
> +			polling-delay-passive = <0>;
> +			polling-delay = <0>;
> +			thermal-sensors = <&ths 1>;
> +
> +			trips {
> +				ve_temp_critical: ve-trip-0 {
> +					temperature = <110000>;
> +					type = "critical";
> +					hysteresis = <0>;
> +				};
> +			};
> +		};
> +
> +		ddr-thermal {
> +			polling-delay-passive = <0>;
> +			polling-delay = <0>;
> +			thermal-sensors = <&ths 3>;
> +
> +			trips {
> +				ddr_temp_critical: ddr-trip-0 {
> +					temperature = <110000>;
> +					type = "critical";
> +					hysteresis = <0>;
> +				};
> +			};
> +		};
> +	};
>  };
> 






From michael.j.ruhl at intel.com  Fri Feb 23 12:12:55 2024
From: michael.j.ruhl at intel.com (Ruhl, Michael J)
Date: Fri, 23 Feb 2024 20:12:55 +0000
Subject: [PATCH v2] clkdev: Update clkdev id usage to allow for longer
 names
In-Reply-To: <Zdj2zaicBvkTOZZe@shell.armlinux.org.uk>
References: <20240223163516.796606-1-michael.j.ruhl@intel.com>
 <ZdjZCrpP52Hfbs6L@smile.fi.intel.com>
 <DS0PR11MB64248E0C15C0B86A1CCF945BC1552@DS0PR11MB6424.namprd11.prod.outlook.com>
 <Zdjku0kxCvMl2HcU@smile.fi.intel.com>
 <Zdj2zaicBvkTOZZe@shell.armlinux.org.uk>
Message-ID: <DS0PR11MB64240F474B2D2A92D0A3BB2EC1552@DS0PR11MB6424.namprd11.prod.outlook.com>

>-----Original Message-----
>From: Russell King <linux at armlinux.org.uk>
>Sent: Friday, February 23, 2024 2:50 PM
>To: Andy Shevchenko <andriy.shevchenko at linux.intel.com>; Ruhl, Michael J
><michael.j.ruhl at intel.com>
>Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Subject: Re: [PATCH v2] clkdev: Update clkdev id usage to allow for longer
>names
>
>On Fri, Feb 23, 2024 at 08:32:27PM +0200, Andy Shevchenko wrote:
>> On Fri, Feb 23, 2024 at 06:22:13PM +0000, Ruhl, Michael J wrote:
>> > >From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
>> > >Sent: Friday, February 23, 2024 12:43 PM
>> > >On Fri, Feb 23, 2024 at 11:35:16AM -0500, Michael J. Ruhl wrote:
>>
>> ...
>>
>> > I will remove.
>>
>> Not remove, but move to the comments/changelog (after '---' line)
>>
>> > I see your script automatically does a cover page...will use that format int
>> > the future.
>>
>> Only if there are more than a single patch.
>>
>> ...
>>
>> > >[1]: https://github.com/andy-shev/home-bin-
>> > >tools/blob/master/ge2maintainer.sh
>> >
>> > Using your script I got:
>> >
>> > To: "Michael J. Ruhl" <michael.j.ruhl at intel.com>,
>> >         linux-arm-kernel at lists.infradead.org,
>> >         linux-kernel at vger.kernel.org
>> > Cc: Russell King <linux at armlinux.org.uk>
>> >
>> > My list (using get_maintainers.pl) is:
>> >
>> > linux at armlinux.org.uk
>> > linux-arm-kernel at lists.infradead.org
>> > linux-kernel at vger.kernel.org
>> >
>> > They appear to be the same....
>>
>> Ah, the Russel's email looked like a mailing list, that what confused me.
>
>Joe, I think you know that I'll pick up on your mis-spelling of my
>name... and I take that as an implicit right to call you something
>other than your proper name. :D
>
>Secondly, because the Cc contained my name, I fail to see how you can
>confuse that with a mailing list. Maybe your script that you mentioned
>strips the names from the email addresses, thereby adding to your
>confusion - and maybe that isn't such a good idea after all? I'm not
>the only one who uses linux at ... There are six people in total listed in
>MAINTAINERS who have a linux at ... email address there.

?

Andy's script picked up your name for the CC... I stripped out all but the email text
for my posting... so this is my fault....

>
>> > I don't have the plain text part on Russel's email (linxu at armlinux.org.uk)...
>Is that what is missing?
>>
>> Yes :-)
>> But my script also uses a heuristics (which is not visible here) to add active
>> developers of the code in question based on the git history.
>
>The developers in question for this part of the code is me and not the
>CCF. Therefore, what has been done by the patch author is reasonable
>and no special scripts are necessary.
>
>While my main git server is offline, I'm happy for the CCF folk
>to pick this up, so:
>
>Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
>
>Michael, please resubmit with my r-b line above, and include the CCF
>folk in that posting:

I will get the appropriate names listed and repost.

Thank you!

M

>Michael Turquette <mturquette at baylibre.com>
>Stephen Boyd <sboyd at kernel.org>
>linux-clk at vger.kernel.org
>
>Thanks!
>
>--
>RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
>FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

From andriy.shevchenko at linux.intel.com  Fri Feb 23 12:14:41 2024
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 23 Feb 2024 22:14:41 +0200
Subject: [PATCH v2] clkdev: Update clkdev id usage to allow for longer
 names
In-Reply-To: <Zdj2zaicBvkTOZZe@shell.armlinux.org.uk>
References: <20240223163516.796606-1-michael.j.ruhl@intel.com>
 <ZdjZCrpP52Hfbs6L@smile.fi.intel.com>
 <DS0PR11MB64248E0C15C0B86A1CCF945BC1552@DS0PR11MB6424.namprd11.prod.outlook.com>
 <Zdjku0kxCvMl2HcU@smile.fi.intel.com>
 <Zdj2zaicBvkTOZZe@shell.armlinux.org.uk>
Message-ID: <Zdj8sSKBG22msfYy@smile.fi.intel.com>

On Fri, Feb 23, 2024 at 07:49:33PM +0000, Russell King (Oracle) wrote:
> On Fri, Feb 23, 2024 at 08:32:27PM +0200, Andy Shevchenko wrote:
> > On Fri, Feb 23, 2024 at 06:22:13PM +0000, Ruhl, Michael J wrote:
> > > >From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> > > >Sent: Friday, February 23, 2024 12:43 PM
> > > >On Fri, Feb 23, 2024 at 11:35:16AM -0500, Michael J. Ruhl wrote:

...

> > > >[1]: https://github.com/andy-shev/home-bin-
> > > >tools/blob/master/ge2maintainer.sh
> > > 
> > > Using your script I got:
> > > 
> > > To: "Michael J. Ruhl" <michael.j.ruhl at intel.com>,
> > >         linux-arm-kernel at lists.infradead.org,
> > >         linux-kernel at vger.kernel.org
> > > Cc: Russell King <linux at armlinux.org.uk>
> > > 
> > > My list (using get_maintainers.pl) is:
> > > 
> > > linux at armlinux.org.uk
> > > linux-arm-kernel at lists.infradead.org
> > > linux-kernel at vger.kernel.org
> > > 
> > > They appear to be the same....
> > 
> > Ah, the Russel's email looked like a mailing list, that what confused me.
> 
> Joe, I think you know that I'll pick up on your mis-spelling of my
> name... and I take that as an implicit right to call you something
> other than your proper name. :D

Since, Javier, you told me that, I now remember some rumors... :D

> Secondly, because the Cc contained my name, I fail to see how you can
> confuse that with a mailing list. Maybe your script that you mentioned
> strips the names from the email addresses, thereby adding to your
> confusion - and maybe that isn't such a good idea after all?

It's other way around. My script uses full names.

> I'm not the only one who uses linux at ... There are six people in total listed
> in MAINTAINERS who have a linux at ... email address there.

Yes, but you are the only one which pops up WRT this file.

> > > I don't have the plain text part on Russel's email
> > > (linxu at armlinux.org.uk)... Is that what is missing?
> > 
> > Yes :-)
> > But my script also uses a heuristics (which is not visible here) to add active
> > developers of the code in question based on the git history.
> 
> The developers in question for this part of the code is me and not the
> CCF.

Yes, get_maintainer.pl seems to return that. It's me who naively considered you
as CCF maintainer.

> Therefore, what has been done by the patch author is reasonable
> and no special scripts are necessary.

The scripts makes life easier and robust against changes.

-- 
With Best Regards,
Andy Shevchenko




From claudiu.beznea at tuxon.dev  Fri Feb 23 12:23:41 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Fri, 23 Feb 2024 22:23:41 +0200
Subject: [PATCH v2 1/2] ARM: dts: microchip: sama7g5: add sama7g5
 compatible
In-Reply-To: <20240223-b4-sama5d2-flexcom-yaml-v2-1-7e96c60c7701@microchip.com>
References: <20240223-b4-sama5d2-flexcom-yaml-v2-0-7e96c60c7701@microchip.com>
 <20240223-b4-sama5d2-flexcom-yaml-v2-1-7e96c60c7701@microchip.com>
Message-ID: <dcce833f-7bad-4db4-bbaa-60b5838aa910@tuxon.dev>



On 23.02.2024 11:16, Balakrishnan Sambath wrote:
> Add sama7g5 flexcom specific compatible in DT with fallbacks.
> 
> Signed-off-by: Balakrishnan Sambath <balakrishnan.s at microchip.com>

Applied to at91-dt, thanks!


From michael.j.ruhl at intel.com  Fri Feb 23 12:25:56 2024
From: michael.j.ruhl at intel.com (Michael J. Ruhl)
Date: Fri, 23 Feb 2024 15:25:56 -0500
Subject: [PATCH v3] clkdev: Update clkdev id usage to allow for longer names
Message-ID: <20240223202556.2194021-1-michael.j.ruhl@intel.com>

clkdev DEV ID information is limited to an array of 20 bytes
(MAX_DEV_ID).  It is possible that the ID could be longer than
that.  If so, the lookup will fail because the "real ID" will
not match the copied value.

For instance, generating a device name for the I2C Designware
module using the PCI ID can result in a name of:

i2c_designware.39424

clkdev_create() will store:

i2c_designware.3942

The stored name is one off and will not match correctly during probe.

Increase the size of the ID to allow for a longer name.

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Michael J. Ruhl <michael.j.ruhl at intel.com>
---

v2: Removed CON_ID update and added example to commit
V3: Add r-b and move version info

 drivers/clk/clkdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index ee37d0be6877..9cd80522ca2d 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -144,7 +144,7 @@ void clkdev_add_table(struct clk_lookup *cl, size_t num)
 	mutex_unlock(&clocks_mutex);
 }
 
-#define MAX_DEV_ID	20
+#define MAX_DEV_ID	24
 #define MAX_CON_ID	16
 
 struct clk_lookup_alloc {
-- 
2.41.0



From claudiu.beznea at tuxon.dev  Fri Feb 23 12:26:27 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Fri, 23 Feb 2024 22:26:27 +0200
Subject: [PATCH v3 0/3] Add initial support for Microchip SAMA7G54
 Curiosity board
In-Reply-To: <20240215091524.14732-1-mihai.sain@microchip.com>
References: <20240215091524.14732-1-mihai.sain@microchip.com>
Message-ID: <19f3ee5e-bb7d-4677-93a1-452e5c0854b8@tuxon.dev>



On 15.02.2024 11:15, Mihai Sain wrote:
> This patch series adds initial support for Microchip SAMA7G54 Curiosity board.
> 
> Changes in v3:
> --------------
> 
> * Update flexcom 10 node in order to match previous flexcom definitions.
> * Use alphanumerical sorting in Makefile.
> * Remove adc subnode from flx10 node.
> * Use C style comment.
> 
> Changes in v2:
> --------------
> 
> * Remove bootargs.
> * Use phandle style for clock nodes.
> * Use color and function for gpio-leds.
> * Remove status okay from leds, nand, eeprom, pmic, flash.
> * Use generic name like pmic for mcp16502 regulator.
> 
> Mihai Sain (3):
>   dt-bindings: ARM: at91: Document Microchip SAMA7G54 Curiosity
>   ARM: dts: microchip: sama7g5: Add flexcom 10 node
>   ARM: dts: microchip: sama7g54_curiosity: Add initial device tree of the board

Applied to at91-dt, thanks!



From claudiu.beznea at tuxon.dev  Fri Feb 23 12:27:20 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Fri, 23 Feb 2024 22:27:20 +0200
Subject: [PATCH 0/2] ARM: dts: microchip: few DT cleanups
In-Reply-To: <20240218151353.3612621-1-claudiu.beznea@tuxon.dev>
References: <20240218151353.3612621-1-claudiu.beznea@tuxon.dev>
Message-ID: <0dac99e5-4ee0-4d55-a344-ae7bd627149e@tuxon.dev>


On 18.02.2024 17:13, Claudiu Beznea wrote:
> Hi,
> 
> Series adds minor cleanups for sam9x60 and sama7g5.
> 
> Thank you,
> Claudiu Beznea
> 
> Claudiu Beznea (2):
>   ARM: dts: microchip: sama7g5: align dmas to opening '<'
>   ARM: dts: microchip: sam9x60: align dmas to opening '<'

Applied to at91-dt, thanks!



From jesper.nilsson at axis.com  Fri Feb 23 12:37:01 2024
From: jesper.nilsson at axis.com (Jesper Nilsson)
Date: Fri, 23 Feb 2024 21:37:01 +0100
Subject: [PATCH net-next v3] net: stmmac: mmc_core: Drop interrupt
 registers from stats
Message-ID: <20240223-stmmac_stats-v3-1-5d483c2a071a@axis.com>

The MMC IPC interrupt status and interrupt mask registers are
of little use as Ethernet statistics, but incrementing counters
based on the current interrupt and interrupt mask registers
makes them actively misleading.

For example, if the interrupt mask is set to 0x08420842,
the current code will increment by that amount each iteration,
leading to the following sequence of nonsense:

mmc_rx_ipc_intr_mask: 969816526
mmc_rx_ipc_intr_mask: 1108361744

These registers have been included in the Ethernet statistics
since the first version of MMC back in 2011 (commit 1c901a46d57).
That commit also mentions the MMC interrupts as
"something to add later (if actually useful)".

If the registers are actually useful, they should probably
be part of the Ethernet register dump instead of statistics,
but for now, drop the counters for mmc_rx_ipc_intr and
mmc_rx_ipc_intr_mask completely.

Reviewed-by: Serge Semin <fancer.lancer at gmail.com>
Signed-off-by: Jesper Nilsson <jesper.nilsson at axis.com>
---
Changes in v3:
- Rebase to be against net-next
- Link to v2: https://lore.kernel.org/r/20240220-stmmac_stats-v2-1-0a78863bec70 at axis.com

Changes in v2:
- Drop the misleading registers completely
- Link to v1: https://lore.kernel.org/r/20240216-stmmac_stats-v1-1-7065fa4613f8 at axis.com
---
 drivers/net/ethernet/stmicro/stmmac/mmc.h            | 4 ----
 drivers/net/ethernet/stmicro/stmmac/mmc_core.c       | 3 ---
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 --
 3 files changed, 9 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h
index 14c9d2637dfe..dff02d75d519 100644
--- a/drivers/net/ethernet/stmicro/stmmac/mmc.h
+++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h
@@ -86,10 +86,6 @@ struct stmmac_counters {
 	unsigned int mmc_rx_discard_octets_gb;
 	unsigned int mmc_rx_align_err_frames;
 
-	/* IPC */
-	unsigned int mmc_rx_ipc_intr_mask;
-	unsigned int mmc_rx_ipc_intr;
-
 	/* IPv4 */
 	unsigned int mmc_rx_ipv4_gd;
 	unsigned int mmc_rx_ipv4_hderr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
index 8597c6abae8d..7eb477faa75a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
@@ -316,9 +316,6 @@ static void dwmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc)
 	mmc->mmc_rx_fifo_overflow += readl(mmcaddr + MMC_RX_FIFO_OVERFLOW);
 	mmc->mmc_rx_vlan_frames_gb += readl(mmcaddr + MMC_RX_VLAN_FRAMES_GB);
 	mmc->mmc_rx_watchdog_error += readl(mmcaddr + MMC_RX_WATCHDOG_ERROR);
-	/* IPC */
-	mmc->mmc_rx_ipc_intr_mask += readl(mmcaddr + MMC_RX_IPC_INTR_MASK);
-	mmc->mmc_rx_ipc_intr += readl(mmcaddr + MMC_RX_IPC_INTR);
 	/* IPv4 */
 	mmc->mmc_rx_ipv4_gd += readl(mmcaddr + MMC_RX_IPV4_GD);
 	mmc->mmc_rx_ipv4_hderr += readl(mmcaddr + MMC_RX_IPV4_HDERR);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 0e44b84fb7e7..e1537a57815f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -243,8 +243,6 @@ static const struct stmmac_stats stmmac_mmc[] = {
 	STMMAC_MMC_STAT(mmc_rx_discard_frames_gb),
 	STMMAC_MMC_STAT(mmc_rx_discard_octets_gb),
 	STMMAC_MMC_STAT(mmc_rx_align_err_frames),
-	STMMAC_MMC_STAT(mmc_rx_ipc_intr_mask),
-	STMMAC_MMC_STAT(mmc_rx_ipc_intr),
 	STMMAC_MMC_STAT(mmc_rx_ipv4_gd),
 	STMMAC_MMC_STAT(mmc_rx_ipv4_hderr),
 	STMMAC_MMC_STAT(mmc_rx_ipv4_nopay),

---
base-commit: a08689109c5989acdc5c320de8e45324f6cfa791
change-id: 20240216-stmmac_stats-e3561d460d0e

Best regards,
-- 

/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson at axis.com



From jernej.skrabec at gmail.com  Fri Feb 23 12:41:34 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Fri, 23 Feb 2024 21:41:34 +0100
Subject: [PATCH v5 7/7] arm64: dts: allwinner: h616: Add thermal sensor and zones
In-Reply-To: <6017645.lOV4Wx5bFT@jernej-laptop>
References: <20240219153639.179814-1-andre.przywara@arm.com>
 <20240219153639.179814-8-andre.przywara@arm.com>
 <6017645.lOV4Wx5bFT@jernej-laptop>
Message-ID: <4545502.LvFx2qVVIh@jernej-laptop>

Dne petek, 23. februar 2024 ob 20:59:08 CET je Jernej ?krabec napisal(a):
> Dne ponedeljek, 19. februar 2024 ob 16:36:39 CET je Andre Przywara napisal(a):
> > From: Martin Botka <martin.botka at somainline.org>
> > 
> > There are four thermal sensors:
> > - CPU
> > - GPU
> > - VE
> > - DRAM
> > 
> > Add the thermal sensor configuration and the thermal zones.
> > 
> > Signed-off-by: Martin Botka <martin.botka at somainline.org>
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> 
> I can't cleanly apply patch on top of sunxi/dt-for-6.9. Can you please rebase?

I rebased and applied. Thanks!
 
Best regards,
Jernej

> > ---
> >  .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 88 +++++++++++++++++++
> >  1 file changed, 88 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> > index 12ffabc79bcde..7c7d7c285505c 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> > @@ -9,6 +9,7 @@
> >  #include <dt-bindings/clock/sun6i-rtc.h>
> >  #include <dt-bindings/reset/sun50i-h616-ccu.h>
> >  #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
> > +#include <dt-bindings/thermal/thermal.h>
> >  
> >  / {
> >  	interrupt-parent = <&gic>;
> > @@ -138,6 +139,10 @@ sid: efuse at 3006000 {
> >  			reg = <0x03006000 0x1000>;
> >  			#address-cells = <1>;
> >  			#size-cells = <1>;
> > +
> > +			ths_calibration: thermal-sensor-calibration at 14 {
> > +				reg = <0x14 0x8>;
> > +			};
> >  		};
> >  
> >  		watchdog: watchdog at 30090a0 {
> > @@ -517,6 +522,19 @@ mdio0: mdio {
> >  			};
> >  		};
> >  
> > +		ths: thermal-sensor at 5070400 {
> > +			compatible = "allwinner,sun50i-h616-ths";
> > +			reg = <0x05070400 0x400>;
> > +			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&ccu CLK_BUS_THS>;
> > +			clock-names = "bus";
> > +			resets = <&ccu RST_BUS_THS>;
> > +			nvmem-cells = <&ths_calibration>;
> > +			nvmem-cell-names = "calibration";
> > +			allwinner,sram = <&syscon>;
> > +			#thermal-sensor-cells = <1>;
> > +		};
> > +
> >  		usbotg: usb at 5100000 {
> >  			compatible = "allwinner,sun50i-h616-musb",
> >  				     "allwinner,sun8i-h3-musb";
> > @@ -761,4 +779,74 @@ r_rsb: rsb at 7083000 {
> >  			#size-cells = <0>;
> >  		};
> >  	};
> > +
> > +	thermal-zones {
> > +		cpu-thermal {
> > +			polling-delay-passive = <500>;
> > +			polling-delay = <1000>;
> > +			thermal-sensors = <&ths 2>;
> > +			sustainable-power = <1000>;
> > +
> > +			trips {
> > +				cpu_threshold: cpu-trip-0 {
> > +					temperature = <60000>;
> > +					type = "passive";
> > +					hysteresis = <0>;
> > +				};
> > +				cpu_target: cpu-trip-1 {
> > +					temperature = <70000>;
> > +					type = "passive";
> > +					hysteresis = <0>;
> > +				};
> > +				cpu_critical: cpu-trip-2 {
> > +					temperature = <110000>;
> > +					type = "critical";
> > +					hysteresis = <0>;
> > +				};
> > +			};
> > +		};
> > +
> > +		gpu-thermal {
> > +			polling-delay-passive = <500>;
> > +			polling-delay = <1000>;
> > +			thermal-sensors = <&ths 0>;
> > +			sustainable-power = <1100>;
> > +
> > +			trips {
> > +				gpu_temp_critical: gpu-trip-0 {
> > +					temperature = <110000>;
> > +					type = "critical";
> > +					hysteresis = <0>;
> > +				};
> > +			};
> > +		};
> > +
> > +		ve-thermal {
> > +			polling-delay-passive = <0>;
> > +			polling-delay = <0>;
> > +			thermal-sensors = <&ths 1>;
> > +
> > +			trips {
> > +				ve_temp_critical: ve-trip-0 {
> > +					temperature = <110000>;
> > +					type = "critical";
> > +					hysteresis = <0>;
> > +				};
> > +			};
> > +		};
> > +
> > +		ddr-thermal {
> > +			polling-delay-passive = <0>;
> > +			polling-delay = <0>;
> > +			thermal-sensors = <&ths 3>;
> > +
> > +			trips {
> > +				ddr_temp_critical: ddr-trip-0 {
> > +					temperature = <110000>;
> > +					type = "critical";
> > +					hysteresis = <0>;
> > +				};
> > +			};
> > +		};
> > +	};
> >  };
> > 
> 
> 
> 
> 
> 






From jernej at kernel.org  Fri Feb 23 12:54:50 2024
From: jernej at kernel.org (Jernej Skrabec)
Date: Fri, 23 Feb 2024 21:54:50 +0100
Subject: [GIT PULL] Allwinner device tree fix for 6.8
Message-ID: <20240223205450.GA8881@jernej-laptop>

Hi!

Please pull following device tree fix for 6.8.

Best regards,
Jernej

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git tags/sunxi-fixes-for-6.8-1

for you to fetch changes up to cbec657208bdd4bff4ff31cac5924aa18817027c:

  arm64: dts: allwinner: h616: Add Orange Pi Zero 2W to Makefile (2024-02-23 21:02:51 +0100)

----------------------------------------------------------------
- include Orange Pi Zero 2W DT in Makefile

----------------------------------------------------------------
Jernej Skrabec (1):
      arm64: dts: allwinner: h616: Add Orange Pi Zero 2W to Makefile

 arch/arm64/boot/dts/allwinner/Makefile | 1 +
 1 file changed, 1 insertion(+)


From jernej at kernel.org  Fri Feb 23 12:57:34 2024
From: jernej at kernel.org (Jernej Skrabec)
Date: Fri, 23 Feb 2024 21:57:34 +0100
Subject: [GIT PULL] Allwinner drivers change for 6.9
Message-ID: <20240223205734.GA9027@jernej-laptop>

Hi!

Please pull following drivers change for 6.9.

Best regards,
Jernej

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git tags/sunxi-drivers-for-6.9-1

for you to fetch changes up to 0daf87e7b47e05d0c9ccab648d5e45eaddb547f8:

  bus: sunxi-rsb: make sunxi_rsb_bus const (2024-02-11 21:24:48 +0100)

----------------------------------------------------------------
- make sunxi_rsb_bus constant

----------------------------------------------------------------
Ricardo B. Marliere (1):
      bus: sunxi-rsb: make sunxi_rsb_bus const

 drivers/bus/sunxi-rsb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)


From jernej at kernel.org  Fri Feb 23 13:04:08 2024
From: jernej at kernel.org (Jernej Skrabec)
Date: Fri, 23 Feb 2024 22:04:08 +0100
Subject: [GIT PULL] Allwinner device tree changes for 6.9
Message-ID: <20240223210408.GA9248@jernej-laptop>

Hi!

Please pull following device tree changes for 6.9.

Note that this is based on top of fixes for 6.8:
https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git tags/sunxi-fixes-for-6.8-1

Best regards,
Jernej

The following changes since commit cbec657208bdd4bff4ff31cac5924aa18817027c:

  arm64: dts: allwinner: h616: Add Orange Pi Zero 2W to Makefile (2024-02-23 21:02:51 +0100)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git tags/sunxi-dt-for-6.9-1

for you to fetch changes up to f4318af40544b8e7ff5a6b667ede60e6cf808262:

  arm64: dts: allwinner: h616: Add thermal sensor and zones (2024-02-23 21:38:21 +0100)

----------------------------------------------------------------
- new H616 peripherals: SPDIF, DMA, THS
- H616 fanout pin configuration
- H6 SPDIF node update
- minor cleanups
- enabled regulator on FETA40i board
- added wifi to Transpeed 8K618-T board
- new boards: Jide Remix Mini PC, Sipeed Longan Module 3H and
  Longan Pi 3H

----------------------------------------------------------------
Andre Przywara (5):
      dt-bindings: vendor-prefixes: add Jide
      dt-bindings: arm: sunxi: document Remix Mini PC name
      arm64: dts: allwinner: Add Jide Remix Mini PC support
      arm64: dts: allwinner: h616: Add 32K fanout pin
      arm64: dts: allwinner: Transpeed 8K618-T: add WiFi nodes

Chen-Yu Tsai (3):
      arm64: dts: allwinner: h6: Add RX DMA channel for SPDIF
      arm64: dts: allwinner: h616: Add DMA controller and DMA channels
      arm64: dts: allwinner: h616: Add SPDIF device node

Fuyao Kashizuku (1):
      ARM: dts: sun8i: Open FETA40i-C regulator aldo1

Jisheng Zhang (2):
      dt-bindings: arm: sunxi: Add Sipeed Longan Module 3H and Longan Pi 3H
      arm64: dts: allwinner: h616: Add Sipeed Longan SoM 3H and Pi 3H board support

Krzysztof Kozlowski (3):
      dt-bindings: sram: narrow regex for unit address to hex numbers
      arm64: dts: allwinner: use capital "OR" for multiple licenses in SPDX
      arm64: dts: allwinner: h616: minor whitespace cleanup

Martin Botka (1):
      arm64: dts: allwinner: h616: Add thermal sensor and zones

 Documentation/devicetree/bindings/arm/sunxi.yaml   |  12 +
 .../sram/allwinner,sun4i-a10-system-control.yaml   |   2 +-
 .../devicetree/bindings/vendor-prefixes.yaml       |   2 +
 arch/arm/boot/dts/allwinner/sun8i-r40-feta40i.dtsi |   7 +
 arch/arm64/boot/dts/allwinner/Makefile             |   2 +
 .../boot/dts/allwinner/sun50i-h6-beelink-gs1.dts   |   2 +
 arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi |   2 +
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi       |   7 +-
 .../sun50i-h616-bigtreetech-cb1-manta.dts          |   2 +-
 .../dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi |   4 +-
 .../dts/allwinner/sun50i-h616-bigtreetech-pi.dts   |   2 +-
 arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi     | 155 +++++++++
 .../allwinner/sun50i-h618-longan-module-3h.dtsi    |  75 +++++
 .../boot/dts/allwinner/sun50i-h618-longanpi-3h.dts | 144 +++++++++
 .../allwinner/sun50i-h618-transpeed-8k618-t.dts    |  23 ++
 .../dts/allwinner/sun50i-h64-remix-mini-pc.dts     | 356 +++++++++++++++++++++
 16 files changed, 788 insertions(+), 9 deletions(-)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts


From konrad.dybcio at linaro.org  Fri Feb 23 13:10:47 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 23 Feb 2024 22:10:47 +0100
Subject: [PATCH v17 05/35] virt: gunyah: Add hypervisor driver
In-Reply-To: <20240222-gunyah-v17-5-1e9da6763d38@quicinc.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
 <20240222-gunyah-v17-5-1e9da6763d38@quicinc.com>
Message-ID: <a3356079-bd55-4852-9bb3-b5362a1c953e@linaro.org>

On 23.02.2024 00:16, Elliot Berman wrote:
> Add driver to detect when running under Gunyah. It performs basic
> identification hypercall and populates the platform bus for resource
> manager to probe.
> 
> Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
> ---

[...]

> +
> +	/* Might move this out to individual drivers if there's ever an API version bump */
> +	if (gunyah_api_version(&gunyah_api) != GUNYAH_API_V1) {
> +		pr_info("Unsupported Gunyah version: %u\n",
> +			gunyah_api_version(&gunyah_api));

Weird for this not to be an error, but it's probably not worth resending
over if it's the only thing

Konrad


From konrad.dybcio at linaro.org  Fri Feb 23 13:21:36 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 23 Feb 2024 22:21:36 +0100
Subject: [PATCH v2 0/7] A702 support
Message-ID: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>

Bit of a megaseries, bunched together for your testing convenience..
Needs mesa!27665 [1] on the userland part, kmscube happily spins.

I'm feeling quite lukewarm about the memory barriers in patch 3..

Patch 1 for Will/smmu, 5-6 for drm/msm, rest for qcom

[1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27665

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
Changes in v2:
- Drop applied smmu-bindings patch
- Fix the gpucc bindings patch to be even better
- Reorder HUAYRA_2290 definitions near HUAYRA (..Add HUAYRA_2290
  support..)
- Replace weird memory barriers copypasted from msm-5.4 with readback to
  ensure timely write completion (..Add HUAYRA_2290 support..)
- Keep my super amazing commit message referencing the 3D accelerator
  official naming (dts)
- Pick up tags
- Link to v1: https://lore.kernel.org/r/20240219-topic-rb1_gpu-v1-0-d260fa854707 at linaro.org

---
Konrad Dybcio (7):
      dt-bindings: clock: Add Qcom QCM2290 GPUCC
      clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
      clk: qcom: Add QCM2290 GPU clock controller driver
      drm/msm/adreno: Add missing defines for A702
      drm/msm/adreno: Add A702 support
      arm64: dts: qcom: qcm2290: Add GPU nodes
      arm64: dts: qcom: qrb2210-rb1: Enable the GPU

 .../bindings/clock/qcom,qcm2290-gpucc.yaml         |  77 ++++
 arch/arm64/boot/dts/qcom/qcm2290.dtsi              | 154 ++++++++
 arch/arm64/boot/dts/qcom/qrb2210-rb1.dts           |   8 +
 drivers/clk/qcom/Kconfig                           |   9 +
 drivers/clk/qcom/Makefile                          |   1 +
 drivers/clk/qcom/clk-alpha-pll.c                   |  47 +++
 drivers/clk/qcom/clk-alpha-pll.h                   |   3 +
 drivers/clk/qcom/gpucc-qcm2290.c                   | 423 +++++++++++++++++++++
 drivers/gpu/drm/msm/adreno/a6xx.xml.h              |  18 +
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c              |  92 ++++-
 drivers/gpu/drm/msm/adreno/adreno_device.c         |  18 +
 drivers/gpu/drm/msm/adreno/adreno_gpu.h            |  16 +-
 include/dt-bindings/clock/qcom,qcm2290-gpucc.h     |  32 ++
 13 files changed, 889 insertions(+), 9 deletions(-)
---
base-commit: 26d7d52b6253574d5b6fec16a93e1110d1489cef
change-id: 20240219-topic-rb1_gpu-3ec8c6830384

Best regards,
-- 
Konrad Dybcio <konrad.dybcio at linaro.org>



From konrad.dybcio at linaro.org  Fri Feb 23 13:21:38 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 23 Feb 2024 22:21:38 +0100
Subject: [PATCH v2 2/7] clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
In-Reply-To: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v2-2-2d3d6a0db040@linaro.org>

Commit 134b55b7e19f ("clk: qcom: support Huayra type Alpha PLL")
introduced an entry to the alpha offsets array, but diving into QCM2290
downstream and some documentation, it turned out that the name Huayra
apparently has been used quite liberally across many chips, even with
noticeably different hardware.

Introduce another set of offsets and a new configure function for the
Huayra PLL found on QCM2290. This is required e.g. for the consumers
of GPUCC_PLL0 to properly start.

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 47 ++++++++++++++++++++++++++++++++++++++++
 drivers/clk/qcom/clk-alpha-pll.h |  3 +++
 2 files changed, 50 insertions(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 8a412ef47e16..82b71f24ee7d 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -83,6 +83,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
 		[PLL_OFF_TEST_CTL_U] = 0x20,
 		[PLL_OFF_STATUS] = 0x24,
 	},
+	[CLK_ALPHA_PLL_TYPE_HUAYRA_2290] =  {
+		[PLL_OFF_L_VAL] = 0x04,
+		[PLL_OFF_ALPHA_VAL] = 0x08,
+		[PLL_OFF_USER_CTL] = 0x0c,
+		[PLL_OFF_CONFIG_CTL] = 0x10,
+		[PLL_OFF_CONFIG_CTL_U] = 0x14,
+		[PLL_OFF_CONFIG_CTL_U1] = 0x18,
+		[PLL_OFF_TEST_CTL] = 0x1c,
+		[PLL_OFF_TEST_CTL_U] = 0x20,
+		[PLL_OFF_TEST_CTL_U1] = 0x24,
+		[PLL_OFF_OPMODE] = 0x28,
+		[PLL_OFF_STATUS] = 0x38,
+	},
 	[CLK_ALPHA_PLL_TYPE_BRAMMO] =  {
 		[PLL_OFF_L_VAL] = 0x04,
 		[PLL_OFF_ALPHA_VAL] = 0x08,
@@ -779,6 +792,40 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 	return clamp(rate, min_freq, max_freq);
 }
 
+void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
+				   const struct alpha_pll_config *config)
+{
+	u32 val;
+
+	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
+	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);
+	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);
+	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);
+	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);
+	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);
+	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
+	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
+	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
+
+	/* Set PLL_BYPASSNL */
+	regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL);
+	regmap_read(regmap, PLL_MODE(pll), &val);
+
+	/* Wait 5 us between setting BYPASS and deasserting reset */
+	udelay(5);
+
+	/* Take PLL out from reset state */
+	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
+	regmap_read(regmap, PLL_MODE(pll), &val);
+
+	/* Wait 50us for PLL_LOCK_DET bit to go high */
+	usleep_range(50, 55);
+
+	/* Enable PLL output */
+	regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
+}
+EXPORT_SYMBOL(clk_huayra_2290_pll_configure);
+
 static unsigned long
 alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a)
 {
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index fb6d50263bb9..d1cd52158c17 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -15,6 +15,7 @@
 enum {
 	CLK_ALPHA_PLL_TYPE_DEFAULT,
 	CLK_ALPHA_PLL_TYPE_HUAYRA,
+	CLK_ALPHA_PLL_TYPE_HUAYRA_2290,
 	CLK_ALPHA_PLL_TYPE_BRAMMO,
 	CLK_ALPHA_PLL_TYPE_FABIA,
 	CLK_ALPHA_PLL_TYPE_TRION,
@@ -191,6 +192,8 @@ extern const struct clk_ops clk_alpha_pll_rivian_evo_ops;
 
 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 			     const struct alpha_pll_config *config);
+void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
+				   const struct alpha_pll_config *config);
 void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 				const struct alpha_pll_config *config);
 void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,

-- 
2.43.2



From konrad.dybcio at linaro.org  Fri Feb 23 13:21:40 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 23 Feb 2024 22:21:40 +0100
Subject: [PATCH v2 4/7] drm/msm/adreno: Add missing defines for A702
In-Reply-To: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v2-4-2d3d6a0db040@linaro.org>

Add some defines required for A702. Can be substituted with a header
sync after merging mesa!27665 [1].

[1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27665
Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 drivers/gpu/drm/msm/adreno/a6xx.xml.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
index 863b5e3b0e67..1ec4dbc0e746 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
@@ -1945,6 +1945,24 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00
 
 #define REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE			0x00000122
 
+#define REG_A6XX_RBBM_CLOCK_CNTL_FCHE				0x00000123
+
+#define REG_A6XX_RBBM_CLOCK_DELAY_FCHE				0x00000124
+
+#define REG_A6XX_RBBM_CLOCK_HYST_FCHE				0x00000125
+
+#define REG_A6XX_RBBM_CLOCK_CNTL_MHUB				0x00000126
+
+#define REG_A6XX_RBBM_CLOCK_DELAY_MHUB				0x00000127
+
+#define REG_A6XX_RBBM_CLOCK_HYST_MHUB				0x00000128
+
+#define REG_A6XX_RBBM_CLOCK_DELAY_GLC				0x00000129
+
+#define REG_A6XX_RBBM_CLOCK_HYST_GLC				0x0000012a
+
+#define REG_A6XX_RBBM_CLOCK_CNTL_GLC				0x0000012b
+
 #define REG_A7XX_RBBM_CLOCK_HYST2_VFD				0x0000012f
 
 #define REG_A6XX_RBBM_LPAC_GBIF_CLIENT_QOS_CNTL			0x000005ff

-- 
2.43.2



From konrad.dybcio at linaro.org  Fri Feb 23 13:21:39 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 23 Feb 2024 22:21:39 +0100
Subject: [PATCH v2 3/7] clk: qcom: Add QCM2290 GPU clock controller driver
In-Reply-To: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v2-3-2d3d6a0db040@linaro.org>

Add a driver for the GPU clock controller block found on the QCM2290 SoC.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 drivers/clk/qcom/Kconfig         |   9 +
 drivers/clk/qcom/Makefile        |   1 +
 drivers/clk/qcom/gpucc-qcm2290.c | 423 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 433 insertions(+)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 4580edbd13ea..d70ea4548755 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -65,6 +65,15 @@ config CLK_X1E80100_TCSRCC
 	  Support for the TCSR clock controller on X1E80100 devices.
 	  Say Y if you want to use peripheral devices such as SD/UFS.
 
+config CLK_QCM2290_GPUCC
+	tristate "QCM2290 Graphics Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select CLK_QCM2290_GCC
+	help
+	  Support for the graphics clock controller on QCM2290 devices.
+	  Say Y if you want to support graphics controller devices and
+	  functionality such as 3D graphics.
+
 config QCOM_A53PLL
 	tristate "MSM8916 A53 PLL"
 	help
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 1da65ca78e24..b8d49c054558 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o
 obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o
 obj-$(CONFIG_CLK_X1E80100_GPUCC) += gpucc-x1e80100.o
 obj-$(CONFIG_CLK_X1E80100_TCSRCC) += tcsrcc-x1e80100.o
+obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o
 obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o
 obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o
 obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
diff --git a/drivers/clk/qcom/gpucc-qcm2290.c b/drivers/clk/qcom/gpucc-qcm2290.c
new file mode 100644
index 000000000000..b6e20d63ac85
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-qcm2290.c
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,qcm2290-gpucc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "clk-regmap-phy-mux.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_GCC_AHB_CLK,
+	DT_BI_TCXO,
+	DT_GCC_GPU_GPLL0_CLK_SRC,
+	DT_GCC_GPU_GPLL0_DIV_CLK_SRC,
+};
+
+enum {
+	P_BI_TCXO,
+	P_GPLL0_OUT_MAIN,
+	P_GPLL0_OUT_MAIN_DIV,
+	P_GPU_CC_PLL0_2X_DIV_CLK_SRC,
+	P_GPU_CC_PLL0_OUT_AUX,
+	P_GPU_CC_PLL0_OUT_AUX2,
+	P_GPU_CC_PLL0_OUT_MAIN,
+};
+
+static const struct pll_vco huayra_vco[] = {
+	{ 600000000, 3300000000, 0 },
+	{ 600000000, 2200000000, 1 },
+};
+
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+	.l = 0x25,
+	.config_ctl_val = 0x200d4828,
+	.config_ctl_hi_val = 0x6,
+	.test_ctl_val = GENMASK(28, 26),
+	.test_ctl_hi_val = BIT(14),
+	.user_ctl_val = 0xf,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = huayra_vco,
+	.num_vco = ARRAY_SIZE(huayra_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290],
+	.clkr = {
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_huayra_ops,
+		},
+	},
+};
+
+static const struct parent_map gpu_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPU_CC_PLL0_OUT_MAIN, 1 },
+	{ P_GPLL0_OUT_MAIN, 5 },
+	{ P_GPLL0_OUT_MAIN_DIV, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO, },
+	{ .hw = &gpu_cc_pll0.clkr.hw, },
+	{ .index = DT_GCC_GPU_GPLL0_CLK_SRC, },
+	{ .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC, },
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPU_CC_PLL0_2X_DIV_CLK_SRC, 1 },
+	{ P_GPU_CC_PLL0_OUT_AUX2, 2 },
+	{ P_GPU_CC_PLL0_OUT_AUX, 3 },
+	{ P_GPLL0_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO, },
+	{ .hw = &gpu_cc_pll0.clkr.hw, },
+	{ .hw = &gpu_cc_pll0.clkr.hw, },
+	{ .hw = &gpu_cc_pll0.clkr.hw, },
+	{ .index = DT_GCC_GPU_GPLL0_CLK_SRC, },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
+	.cmd_rcgr = 0x1120,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_0,
+	.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "gpu_cc_gmu_clk_src",
+		.parent_data = gpu_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
+	F(355200000, P_GPU_CC_PLL0_OUT_AUX, 2, 0, 0),
+	F(537600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	F(672000000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	F(844800000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	F(921600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	F(1017600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	F(1123200000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
+	.cmd_rcgr = 0x101c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_1,
+	.freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "gpu_cc_gx_gfx3d_clk_src",
+		.parent_data = gpu_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_branch gpu_cc_ahb_clk = {
+	.halt_reg = 0x1078,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x1078,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_ahb_clk",
+			.flags = CLK_IS_CRITICAL,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_crc_ahb_clk = {
+	.halt_reg = 0x107c,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x107c,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_crc_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_gfx3d_clk = {
+	.halt_reg = 0x10a4,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x10a4,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cx_gfx3d_clk",
+			.parent_data = &(const struct clk_parent_data){
+				.hw = &gpu_cc_gx_gfx3d_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+	.halt_reg = 0x1098,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1098,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cx_gmu_clk",
+			.parent_data = &(const struct clk_parent_data){
+				.hw = &gpu_cc_gmu_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
+	.halt_reg = 0x108c,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x108c,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cx_snoc_dvm_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cxo_aon_clk = {
+	.halt_reg = 0x1004,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x1004,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cxo_aon_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cxo_clk = {
+	.halt_reg = 0x109c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x109c,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cxo_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gx_gfx3d_clk = {
+	.halt_reg = 0x1054,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x1054,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_gx_gfx3d_clk",
+			.parent_data = &(const struct clk_parent_data){
+				.hw = &gpu_cc_gx_gfx3d_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_sleep_clk = {
+	.halt_reg = 0x1090,
+	.halt_check = BRANCH_VOTED,
+	.clkr = {
+		.enable_reg = 0x1090,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
+	.halt_reg = 0x5000,
+	.halt_check = BRANCH_VOTED,
+	.clkr = {
+		.enable_reg = 0x5000,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			 .name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
+			 .ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc gpu_cx_gdsc = {
+	.gdscr = 0x106c,
+	.gds_hw_ctrl = 0x1540,
+	.pd = {
+		.name = "gpu_cx_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
+static struct gdsc gpu_gx_gdsc = {
+	.gdscr = 0x100c,
+	.clamp_io_ctrl = 0x1508,
+	.resets = (unsigned int []){ GPU_GX_BCR },
+	.reset_count = 1,
+	.pd = {
+		.name = "gpu_gx_gdsc",
+	},
+	.parent = &gpu_cx_gdsc.pd,
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = CLAMP_IO | AON_RESET | SW_RESET,
+};
+
+static struct clk_regmap *gpu_cc_qcm2290_clocks[] = {
+	[GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
+	[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
+	[GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr,
+	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
+	[GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
+	[GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
+	[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
+	[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
+	[GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr,
+	[GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr,
+	[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
+	[GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
+	[GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
+};
+
+static const struct qcom_reset_map gpu_cc_qcm2290_resets[] = {
+	[GPU_GX_BCR] = { 0x1008 },
+};
+
+static struct gdsc *gpu_cc_qcm2290_gdscs[] = {
+	[GPU_CX_GDSC] = &gpu_cx_gdsc,
+	[GPU_GX_GDSC] = &gpu_gx_gdsc,
+};
+
+static const struct regmap_config gpu_cc_qcm2290_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x9000,
+	.fast_io = true,
+};
+
+
+static const struct qcom_cc_desc gpu_cc_qcm2290_desc = {
+	.config = &gpu_cc_qcm2290_regmap_config,
+	.clks = gpu_cc_qcm2290_clocks,
+	.num_clks = ARRAY_SIZE(gpu_cc_qcm2290_clocks),
+	.resets = gpu_cc_qcm2290_resets,
+	.num_resets = ARRAY_SIZE(gpu_cc_qcm2290_resets),
+	.gdscs = gpu_cc_qcm2290_gdscs,
+	.num_gdscs = ARRAY_SIZE(gpu_cc_qcm2290_gdscs),
+};
+
+static const struct of_device_id gpu_cc_qcm2290_match_table[] = {
+	{ .compatible = "qcom,qcm2290-gpucc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_qcm2290_match_table);
+
+static int gpu_cc_qcm2290_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	int ret;
+
+	regmap = qcom_cc_map(pdev, &gpu_cc_qcm2290_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = devm_pm_clk_create(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = pm_clk_add(&pdev->dev, NULL);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to acquire ahb clock\n");
+		return ret;
+	}
+
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret)
+		return ret;
+
+	clk_huayra_2290_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
+
+	regmap_update_bits(regmap, 0x1060, BIT(0), BIT(0)); /* GPU_CC_GX_CXO_CLK */
+
+	ret = qcom_cc_really_probe(pdev, &gpu_cc_qcm2290_desc, regmap);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register display clock controller\n");
+		goto out_pm_runtime_put;
+	}
+
+out_pm_runtime_put:
+	pm_runtime_put_sync(&pdev->dev);
+
+	return 0;
+}
+
+static struct platform_driver gpu_cc_qcm2290_driver = {
+	.probe = gpu_cc_qcm2290_probe,
+	.driver = {
+		.name = "gpucc-qcm2290",
+		.of_match_table = gpu_cc_qcm2290_match_table,
+	},
+};
+module_platform_driver(gpu_cc_qcm2290_driver);
+
+MODULE_DESCRIPTION("QTI QCM2290 GPU clock controller driver");
+MODULE_LICENSE("GPL");

-- 
2.43.2



From konrad.dybcio at linaro.org  Fri Feb 23 13:21:37 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 23 Feb 2024 22:21:37 +0100
Subject: [PATCH v2 1/7] dt-bindings: clock: Add Qcom QCM2290 GPUCC
In-Reply-To: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v2-1-2d3d6a0db040@linaro.org>

Add device tree bindings for graphics clock controller for Qualcomm
Technology Inc's QCM2290 SoCs.

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 .../bindings/clock/qcom,qcm2290-gpucc.yaml         | 77 ++++++++++++++++++++++
 include/dt-bindings/clock/qcom,qcm2290-gpucc.h     | 32 +++++++++
 2 files changed, 109 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml
new file mode 100644
index 000000000000..734880805c1b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,qcm2290-gpucc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Graphics Clock & Reset Controller on QCM2290
+
+maintainers:
+  - Konrad Dybcio <konradybcio at kernel.org>
+
+description: |
+  Qualcomm graphics clock control module provides the clocks, resets and power
+  domains on Qualcomm SoCs.
+
+  See also::
+    include/dt-bindings/clock/qcom,qcm2290-gpucc.h
+
+properties:
+  compatible:
+    const: qcom,qcm2290-gpucc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: AHB interface clock,
+      - description: SoC CXO clock
+      - description: GPLL0 main branch source
+      - description: GPLL0 div branch source
+
+  power-domains:
+    description:
+      A phandle and PM domain specifier for the CX power domain.
+    maxItems: 1
+
+  required-opps:
+    description:
+      A phandle to an OPP node describing required CX performance point.
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - power-domains
+
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-qcm2290.h>
+    #include <dt-bindings/clock/qcom,rpmcc.h>
+    #include <dt-bindings/power/qcom-rpmpd.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller at 5990000 {
+            compatible = "qcom,qcm2290-gpucc";
+            reg = <0x0 0x05990000 0x0 0x9000>;
+            clocks = <&gcc GCC_GPU_CFG_AHB_CLK>,
+                     <&rpmcc RPM_SMD_XO_CLK_SRC>,
+                     <&gcc GCC_GPU_GPLL0_CLK_SRC>,
+                     <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
+            power-domains = <&rpmpd QCM2290_VDDCX>;
+            required-opps = <&rpmpd_opp_low_svs>;
+            #clock-cells = <1>;
+            #reset-cells = <1>;
+            #power-domain-cells = <1>;
+        };
+    };
+...
diff --git a/include/dt-bindings/clock/qcom,qcm2290-gpucc.h b/include/dt-bindings/clock/qcom,qcm2290-gpucc.h
new file mode 100644
index 000000000000..7c76dd05278f
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,qcm2290-gpucc.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_QCM2290_H
+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_QCM2290_H
+
+/* GPU_CC clocks */
+#define GPU_CC_AHB_CLK			0
+#define GPU_CC_CRC_AHB_CLK		1
+#define GPU_CC_CX_GFX3D_CLK		2
+#define GPU_CC_CX_GMU_CLK		3
+#define GPU_CC_CX_SNOC_DVM_CLK		4
+#define GPU_CC_CXO_AON_CLK		5
+#define GPU_CC_CXO_CLK			6
+#define GPU_CC_GMU_CLK_SRC		7
+#define GPU_CC_GX_GFX3D_CLK		8
+#define GPU_CC_GX_GFX3D_CLK_SRC		9
+#define GPU_CC_PLL0			10
+#define GPU_CC_SLEEP_CLK		11
+#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK	12
+
+/* Resets */
+#define GPU_GX_BCR			0
+
+/* GDSCs */
+#define GPU_CX_GDSC			0
+#define GPU_GX_GDSC			1
+
+#endif

-- 
2.43.2



From konrad.dybcio at linaro.org  Fri Feb 23 13:21:42 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 23 Feb 2024 22:21:42 +0100
Subject: [PATCH v2 6/7] arm64: dts: qcom: qcm2290: Add GPU nodes
In-Reply-To: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v2-6-2d3d6a0db040@linaro.org>

Describe the GPU hardware on the QCM2290.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 arch/arm64/boot/dts/qcom/qcm2290.dtsi | 154 ++++++++++++++++++++++++++++++++++
 1 file changed, 154 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi
index 89beac833d43..ec5aef5d9c69 100644
--- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/clock/qcom,dispcc-qcm2290.h>
 #include <dt-bindings/clock/qcom,gcc-qcm2290.h>
+#include <dt-bindings/clock/qcom,qcm2290-gpucc.h>
 #include <dt-bindings/clock/qcom,rpmcc.h>
 #include <dt-bindings/dma/qcom-gpi.h>
 #include <dt-bindings/firmware/qcom,scm.h>
@@ -737,6 +738,11 @@ qusb2_hstx_trim: hstx-trim at 25b {
 				reg = <0x25b 0x1>;
 				bits = <1 4>;
 			};
+
+			gpu_speed_bin: gpu-speed-bin at 2006 {
+				reg = <0x2006 0x2>;
+				bits = <5 8>;
+			};
 		};
 
 		pmu at 1b8e300 {
@@ -1383,6 +1389,154 @@ usb_dwc3: usb at 4e00000 {
 			};
 		};
 
+		gpu: gpu at 5900000 {
+			compatible = "qcom,adreno-07000200", "qcom,adreno";
+			reg = <0x0 0x05900000 0x0 0x40000>;
+			reg-names = "kgsl_3d0_reg_memory";
+
+			interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gpucc GPU_CC_GX_GFX3D_CLK>,
+				 <&gpucc GPU_CC_AHB_CLK>,
+				 <&gcc GCC_BIMC_GPU_AXI_CLK>,
+				 <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gpucc GPU_CC_CX_GMU_CLK>,
+				 <&gpucc GPU_CC_CXO_CLK>;
+			clock-names = "core",
+				      "iface",
+				      "mem_iface",
+				      "alt_mem_iface",
+				      "gmu",
+				      "xo";
+
+			interconnects = <&bimc MASTER_GFX3D RPM_ALWAYS_TAG
+					 &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>;
+			interconnect-names = "gfx-mem";
+
+			iommus = <&adreno_smmu 0 1>,
+				 <&adreno_smmu 2 0>;
+			operating-points-v2 = <&gpu_opp_table>;
+			power-domains = <&rpmpd QCM2290_VDDCX>;
+			qcom,gmu = <&gmu_wrapper>;
+
+			nvmem-cells = <&gpu_speed_bin>;
+			nvmem-cell-names = "speed_bin";
+			#cooling-cells = <2>;
+
+			status = "disabled";
+
+			zap-shader {
+				memory-region = <&pil_gpu_mem>;
+			};
+
+			gpu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				/* TODO: Scale RPM_SMD_BIMC_GPU_CLK w/ turbo freqs */
+				opp-1123200000 {
+					opp-hz = /bits/ 64 <1123200000>;
+					required-opps = <&rpmpd_opp_turbo_plus>;
+					opp-peak-kBps = <6881000>;
+					opp-supported-hw = <0x3>;
+					turbo-mode;
+				};
+
+				opp-1017600000 {
+					opp-hz = /bits/ 64 <1017600000>;
+					required-opps = <&rpmpd_opp_turbo>;
+					opp-peak-kBps = <6881000>;
+					opp-supported-hw = <0x3>;
+					turbo-mode;
+				};
+
+				opp-921600000 {
+					opp-hz = /bits/ 64 <921600000>;
+					required-opps = <&rpmpd_opp_nom_plus>;
+					opp-peak-kBps = <6881000>;
+					opp-supported-hw = <0x3>;
+				};
+
+				opp-844800000 {
+					opp-hz = /bits/ 64 <844800000>;
+					required-opps = <&rpmpd_opp_nom>;
+					opp-peak-kBps = <6881000>;
+					opp-supported-hw = <0x7>;
+				};
+
+				opp-672000000 {
+					opp-hz = /bits/ 64 <672000000>;
+					required-opps = <&rpmpd_opp_svs_plus>;
+					opp-peak-kBps = <3879000>;
+					opp-supported-hw = <0xf>;
+				};
+
+				opp-537600000 {
+					opp-hz = /bits/ 64 <537600000>;
+					required-opps = <&rpmpd_opp_svs>;
+					opp-peak-kBps = <2929000>;
+					opp-supported-hw = <0xf>;
+				};
+
+				opp-355200000 {
+					opp-hz = /bits/ 64 <355200000>;
+					required-opps = <&rpmpd_opp_low_svs>;
+					opp-peak-kBps = <1720000>;
+					opp-supported-hw = <0xf>;
+				};
+			};
+		};
+
+		gmu_wrapper: gmu at 596a000 {
+			compatible = "qcom,adreno-gmu-wrapper";
+			reg = <0x0 0x0596a000 0x0 0x30000>;
+			reg-names = "gmu";
+			power-domains = <&gpucc GPU_CX_GDSC>,
+					<&gpucc GPU_GX_GDSC>;
+			power-domain-names = "cx",
+					     "gx";
+		};
+
+		gpucc: clock-controller at 5990000 {
+			compatible = "qcom,qcm2290-gpucc";
+			reg = <0x0 0x05990000 0x0 0x9000>;
+			clocks = <&gcc GCC_GPU_CFG_AHB_CLK>,
+				 <&rpmcc RPM_SMD_XO_CLK_SRC>,
+				 <&gcc GCC_GPU_GPLL0_CLK_SRC>,
+				 <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
+			power-domains = <&rpmpd QCM2290_VDDCX>;
+			required-opps = <&rpmpd_opp_low_svs>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		adreno_smmu: iommu at 59a0000 {
+			compatible = "qcom,qcm2290-smmu-500", "qcom,adreno-smmu",
+				     "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x059a0000 0x0 0x10000>;
+			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+				 <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>;
+			clock-names = "mem",
+				      "hlos",
+				      "iface";
+
+			power-domains = <&gpucc GPU_CX_GDSC>;
+
+			#global-interrupts = <1>;
+			#iommu-cells = <2>;
+		};
+
 		mdss: display-subsystem at 5e00000 {
 			compatible = "qcom,qcm2290-mdss";
 			reg = <0x0 0x05e00000 0x0 0x1000>;

-- 
2.43.2



From konrad.dybcio at linaro.org  Fri Feb 23 13:21:41 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 23 Feb 2024 22:21:41 +0100
Subject: [PATCH v2 5/7] drm/msm/adreno: Add A702 support
In-Reply-To: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v2-5-2d3d6a0db040@linaro.org>

The A702 is a weird mix of 600 and 700 series.. Perhaps even a
testing ground for some A7xx features with good ol' A6xx silicon.
It's basically A610 that's been beefed up with some new registers
and hw features (like APRIV!), that was then cut back in size,
memory bus and some other ways.

Add support for it, tested with QCM2290 / RB1.

Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c      | 92 +++++++++++++++++++++++++++---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 18 ++++++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h    | 16 +++++-
 3 files changed, 117 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c9c55e2ea584..2a491a486ca1 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -837,6 +837,65 @@ const struct adreno_reglist a690_hwcg[] = {
 	{}
 };
 
+const struct adreno_reglist a702_hwcg[] = {
+	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002 },
+	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
+	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_FCHE, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_FCHE, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_FCHE, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GLC, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GLC, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GLC, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_MHUB, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_MHUB, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_MHUB, 0x00000000 },
+	{}
+};
+
 const struct adreno_reglist a730_hwcg[] = {
 	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222 },
 	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022222 },
@@ -968,6 +1027,8 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 		clock_cntl_on = 0x8aa8aa02;
 	else if (adreno_is_a610(adreno_gpu))
 		clock_cntl_on = 0xaaa8aa82;
+	else if (adreno_is_a702(adreno_gpu))
+		clock_cntl_on = 0xaaaaaa82;
 	else
 		clock_cntl_on = 0x8aa8aa82;
 
@@ -989,14 +1050,14 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 		return;
 
 	/* Disable SP clock before programming HWCG registers */
-	if (!adreno_is_a610(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
+	if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
 		gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0);
 
 	for (i = 0; (reg = &adreno_gpu->info->hwcg[i], reg->offset); i++)
 		gpu_write(gpu, reg->offset, state ? reg->value : 0);
 
 	/* Enable SP clock */
-	if (!adreno_is_a610(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
+	if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
 		gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1);
 
 	gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0);
@@ -1224,7 +1285,7 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu)
 	const u32 *regs = a6xx_protect;
 	unsigned i, count, count_max;
 
-	if (adreno_is_a650(adreno_gpu)) {
+	if (adreno_is_a650(adreno_gpu) || adreno_is_a702(adreno_gpu)) {
 		regs = a650_protect;
 		count = ARRAY_SIZE(a650_protect);
 		count_max = 48;
@@ -1320,6 +1381,12 @@ static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
 		gpu->ubwc_config.rgb565_predicator = 1;
 		gpu->ubwc_config.uavflagprd_inv = 2;
 	}
+
+	if (adreno_is_a702(gpu)) {
+		gpu->ubwc_config.highest_bank_bit = 14;
+		gpu->ubwc_config.min_acc_len = 1;
+		gpu->ubwc_config.ubwc_mode = 2;
+	}
 }
 
 static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
@@ -1453,7 +1520,7 @@ static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu,
 		return false;
 
 	/* A7xx is safe! */
-	if (adreno_is_a7xx(adreno_gpu))
+	if (adreno_is_a7xx(adreno_gpu) || adreno_is_a702(adreno_gpu))
 		return true;
 
 	/*
@@ -1671,7 +1738,7 @@ static int hw_init(struct msm_gpu *gpu)
 	a6xx_set_hwcg(gpu, true);
 
 	/* VBIF/GBIF start*/
-	if (adreno_is_a610(adreno_gpu) ||
+	if (adreno_is_a610_family(adreno_gpu) ||
 	    adreno_is_a640_family(adreno_gpu) ||
 	    adreno_is_a650_family(adreno_gpu) ||
 	    adreno_is_a7xx(adreno_gpu)) {
@@ -1705,6 +1772,7 @@ static int hw_init(struct msm_gpu *gpu)
 	}
 
 	if (!(adreno_is_a650_family(adreno_gpu) ||
+	      adreno_is_a702(adreno_gpu) ||
 	      adreno_is_a730(adreno_gpu))) {
 		gmem_range_min = adreno_is_a740_family(adreno_gpu) ? SZ_16M : SZ_1M;
 
@@ -1725,7 +1793,7 @@ static int hw_init(struct msm_gpu *gpu)
 	if (adreno_is_a640_family(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
-	} else if (adreno_is_a610(adreno_gpu)) {
+	} else if (adreno_is_a610_family(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x00800060);
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x40201b16);
 	} else if (!adreno_is_a7xx(adreno_gpu)) {
@@ -1740,13 +1808,18 @@ static int hw_init(struct msm_gpu *gpu)
 	if (adreno_is_a610(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 48);
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 47);
+	} else if (adreno_is_a702(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 64);
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 63);
 	} else if (!adreno_is_a7xx(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
 
 	/* Setting the primFifo thresholds default values,
 	 * and vccCacheSkipDis=1 bit (0x200) for A640 and newer
 	*/
-	if (adreno_is_a690(adreno_gpu))
+	if (adreno_is_a702(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x0000c000);
+	else if (adreno_is_a690(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00800200);
 	else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
@@ -1786,7 +1859,7 @@ static int hw_init(struct msm_gpu *gpu)
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4fffff);
 	else if (adreno_is_a619(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff);
-	else if (adreno_is_a610(adreno_gpu))
+	else if (adreno_is_a610(adreno_gpu) || adreno_is_a702(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3ffff);
 	else
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff);
@@ -1822,6 +1895,9 @@ static int hw_init(struct msm_gpu *gpu)
 		else
 			gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1);
 		gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0);
+	} else if (adreno_is_a702(adreno_gpu)) {
+		/* Something to do with the HLSQ cluster */
+		gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(24));
 	}
 
 	if (adreno_is_a690(adreno_gpu))
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 2ce7d7b1690d..b121abc71338 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -492,6 +492,24 @@ static const struct adreno_info gpulist[] = {
 		.zapfw = "a690_zap.mdt",
 		.hwcg = a690_hwcg,
 		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x07000200),
+		.family = ADRENO_6XX_GEN1, /* NOT a mistake! */
+		.fw = {
+			[ADRENO_FW_SQE] = "a702_sqe.fw",
+		},
+		.gmem = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a702_zap.mbn",
+		.hwcg = a702_hwcg,
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 236, 1 },
+			{ 178, 2 },
+			{ 142, 3 },
+		),
 	}, {
 		.chip_ids = ADRENO_CHIP_IDS(0x07030001),
 		.family = ADRENO_7XX_GEN1,
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index bc14df96feb0..f451881a6ddf 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -77,7 +77,7 @@ struct adreno_reglist {
 };
 
 extern const struct adreno_reglist a612_hwcg[], a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[];
-extern const struct adreno_reglist a660_hwcg[], a690_hwcg[], a730_hwcg[], a740_hwcg[];
+extern const struct adreno_reglist a660_hwcg[], a690_hwcg[], a702_hwcg[], a730_hwcg[], a740_hwcg[];
 
 struct adreno_speedbin {
 	uint16_t fuse;
@@ -382,6 +382,20 @@ static inline int adreno_is_a690(const struct adreno_gpu *gpu)
 	return gpu->info->chip_ids[0] == 0x06090000;
 }
 
+static inline int adreno_is_a702(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x07000200;
+}
+
+static inline int adreno_is_a610_family(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+
+	/* TODO: A612 */
+	return adreno_is_a610(gpu) || adreno_is_a702(gpu);
+}
+
 /* check for a615, a616, a618, a619 or any a630 derivatives */
 static inline int adreno_is_a630_family(const struct adreno_gpu *gpu)
 {

-- 
2.43.2



From konrad.dybcio at linaro.org  Fri Feb 23 13:21:43 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Fri, 23 Feb 2024 22:21:43 +0100
Subject: [PATCH v2 7/7] arm64: dts: qcom: qrb2210-rb1: Enable the GPU
In-Reply-To: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
Message-ID: <20240219-topic-rb1_gpu-v2-7-2d3d6a0db040@linaro.org>

Enable the A702 GPU (also marketed as "3D accelerator by qcom [1], lol).

[1] https://docs.qualcomm.com/bundle/publicresource/87-61720-1_REV_A_QUALCOMM_ROBOTICS_RB1_PLATFORM__QUALCOMM_QRB2210__PRODUCT_BRIEF.pdf

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
---
 arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
index 6e9dd0312adc..c9abca5a7e39 100644
--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
+++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
@@ -199,6 +199,14 @@ &gpi_dma0 {
 	status = "okay";
 };
 
+&gpu {
+	status = "okay";
+
+	zap-shader {
+		firmware-name = "qcom/qcm2290/a702_zap.mbn";
+	};
+};
+
 &i2c2 {
 	clock-frequency = <400000>;
 	status = "okay";

-- 
2.43.2



From hsinyi at chromium.org  Fri Feb 23 13:23:29 2024
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Fri, 23 Feb 2024 13:23:29 -0800
Subject: [PATCH] drm/mediatek: Fix a null pointer crash in mtk_drm_crtc_finish_page_flip
Message-ID: <20240223212404.3709690-1-hsinyi@chromium.org>

It's possible that mtk_crtc->event is NULL in
mtk_drm_crtc_finish_page_flip().

pending_needs_vblank value is set by mtk_crtc->event, but in
mtk_drm_crtc_atomic_flush(), it's is not guarded by the same
lock in mtk_drm_finish_page_flip(), thus a race condition happens.

Consider the following case:

CPU1                              CPU2
step 1:
mtk_drm_crtc_atomic_begin()
mtk_crtc->event is not null,
                                  step 1:
                                  mtk_drm_crtc_atomic_flush:
                                  mtk_drm_crtc_update_config(
                                      !!mtk_crtc->event)
step 2:
mtk_crtc_ddp_irq ->
mtk_drm_finish_page_flip:
lock
mtk_crtc->event set to null,
pending_needs_vblank set to false
unlock
                                  pending_needs_vblank set to true,

                                  step 2:
                                  mtk_crtc_ddp_irq ->
                                  mtk_drm_finish_page_flip called again,
                                  pending_needs_vblank is still true
                                  //null pointer

Instead of guarding the entire mtk_drm_crtc_atomic_flush(), it's more
efficient to just check if mtk_crtc->event is null before use.

Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index db43f9dff912..d645b85f9721 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -95,11 +95,13 @@ static void mtk_drm_crtc_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
 	struct drm_crtc *crtc = &mtk_crtc->base;
 	unsigned long flags;
 
-	spin_lock_irqsave(&crtc->dev->event_lock, flags);
-	drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
-	drm_crtc_vblank_put(crtc);
-	mtk_crtc->event = NULL;
-	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+	if (mtk_crtc->event) {
+		spin_lock_irqsave(&crtc->dev->event_lock, flags);
+		drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
+		drm_crtc_vblank_put(crtc);
+		mtk_crtc->event = NULL;
+		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+	}
 }
 
 static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
-- 
2.44.0.rc0.258.g7320e95886-goog



From dmitry.baryshkov at linaro.org  Fri Feb 23 13:24:19 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 23 Feb 2024 23:24:19 +0200
Subject: [PATCH v2 2/7] clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
In-Reply-To: <20240219-topic-rb1_gpu-v2-2-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org> <20240219-topic-rb1_gpu-v2-2-2d3d6a0db040@linaro.org>
Message-ID: <CAA8EJprR=tPUsFit7DEzh0U9TDOm8TY29m=JVJwXQwH6vEN49A@mail.gmail.com>

On Fri, 23 Feb 2024 at 23:21, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>
> Commit 134b55b7e19f ("clk: qcom: support Huayra type Alpha PLL")
> introduced an entry to the alpha offsets array, but diving into QCM2290
> downstream and some documentation, it turned out that the name Huayra
> apparently has been used quite liberally across many chips, even with
> noticeably different hardware.
>
> Introduce another set of offsets and a new configure function for the
> Huayra PLL found on QCM2290. This is required e.g. for the consumers
> of GPUCC_PLL0 to properly start.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> ---
>  drivers/clk/qcom/clk-alpha-pll.c | 47 ++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/qcom/clk-alpha-pll.h |  3 +++
>  2 files changed, 50 insertions(+)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Fri Feb 23 13:24:42 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Fri, 23 Feb 2024 23:24:42 +0200
Subject: [PATCH v2 4/7] drm/msm/adreno: Add missing defines for A702
In-Reply-To: <20240219-topic-rb1_gpu-v2-4-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org> <20240219-topic-rb1_gpu-v2-4-2d3d6a0db040@linaro.org>
Message-ID: <CAA8EJpqnAoCDer93V34BaFHf5mhiNOFMQTP1Xaeoio0BWaPzhA@mail.gmail.com>

On Fri, 23 Feb 2024 at 23:21, Konrad Dybcio <konrad.dybcio at linaro.org> wrote:
>
> Add some defines required for A702. Can be substituted with a header
> sync after merging mesa!27665 [1].
>
> [1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27665
> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> ---
>  drivers/gpu/drm/msm/adreno/a6xx.xml.h | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

-- 
With best wishes
Dmitry


From zweiss at equinix.com  Fri Feb 23 13:56:30 2024
From: zweiss at equinix.com (Zev Weiss)
Date: Fri, 23 Feb 2024 21:56:30 +0000
Subject: [PATCH 2/2] ARM: dts: aspeed: x4tf: Add dts for asus x4tf project
In-Reply-To: <20240222085914.1218037-2-Kelly_Hung@asus.com>
References: <20240222085914.1218037-1-Kelly_Hung@asus.com>
 <20240222085914.1218037-2-Kelly_Hung@asus.com>
Message-ID: <20240223215620.GA9299@packtop>

On Thu, Feb 22, 2024 at 12:59:14AM PST, Kelly Hung wrote:
>Base on aspeed-g6.dtsi and can boot into BMC console.
>
>Signed-off-by: Kelly Hung <Kelly_Hung at asus.com>
>---
> arch/arm/boot/dts/aspeed/Makefile             |   1 +
> .../boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts  | 592 ++++++++++++++++++
> 2 files changed, 593 insertions(+)
> create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
>
>diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
>index d3ac20e31..32c41f3d9 100644
>--- a/arch/arm/boot/dts/aspeed/Makefile
>+++ b/arch/arm/boot/dts/aspeed/Makefile
>@@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
> 	aspeed-bmc-arm-stardragon4800-rep2.dtb \
> 	aspeed-bmc-asrock-e3c246d4i.dtb \
> 	aspeed-bmc-asrock-romed8hm3.dtb \
>+	aspeed-bmc-asus-x4tf.dtb \
> 	aspeed-bmc-bytedance-g220a.dtb \
> 	aspeed-bmc-delta-ahe50dc.dtb \
> 	aspeed-bmc-facebook-bletchley.dtb \
>diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
>new file mode 100644
>index 000000000..1bda14a66
>--- /dev/null
>+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asus-x4tf.dts
>@@ -0,0 +1,592 @@
>+// SPDX-License-Identifier: GPL-2.0-or-later
>+// Copyright 2024 ASUS Corp.
>+
>+/dts-v1/;
>+
>+#include "aspeed-g6.dtsi"
>+#include "aspeed-g6-pinctrl.dtsi"
>+#include <dt-bindings/i2c/i2c.h>
>+#include <dt-bindings/gpio/aspeed-gpio.h>
>+
>+/ {
>+	model = "ASUS-X4TF";
>+	compatible = "asus,x4tf", "aspeed,ast2600";
>+
>+	aliases {
>+		serial4 = &uart5;
>+	};
>+
>+	chosen {
>+		stdout-path = "serial4:115200n8";
>+	};
>+
>+	memory at 80000000 {
>+		device_type = "memory";
>+		reg = <0x80000000 0x40000000>;
>+	};
>+
>+	reserved-memory {
>+		#address-cells = <1>;
>+		#size-cells = <1>;
>+		ranges;
>+
>+		video_engine_memory: video {
>+			size = <0x04000000>;
>+			alignment = <0x01000000>;
>+			compatible = "shared-dma-pool";
>+			reusable;
>+		};
>+	};
>+
>+	iio-hwmon {
>+		compatible = "iio-hwmon";
>+		io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
>+				<&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
>+				<&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>,
>+				<&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>;
>+	};
>+
>+	leds {
>+		compatible = "gpio-leds";
>+
>+		led-heartbeat {
>+			gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
>+			linux,default-trigger = "heartbeat";
>+		};
>+
>+		led-uid {
>+			gpios = <&gpio0 ASPEED_GPIO(P, 1) (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
>+			default-state = "off";
>+		};
>+
>+		led-status_Y {
>+			gpios = <&gpio1 ASPEED_GPIO(B, 1) GPIO_ACTIVE_LOW>;
>+			default-state = "off";
>+		};
>+
>+		led-sys_boot_status {
>+			gpios = <&gpio1 ASPEED_GPIO(B, 0) GPIO_ACTIVE_LOW>;
>+			default-state = "off";
>+		};
>+	};
>+};
>+
>+&adc0 {
>+	vref = <2500>;
>+	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>;
>+};
>+
>+&adc1 {
>+	vref = <2500>;
>+	status = "okay";
>+	pinctrl-names = "default";
>+	pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc9_default
>+		&pinctrl_adc10_default &pinctrl_adc11_default
>+		&pinctrl_adc12_default &pinctrl_adc13_default
>+		&pinctrl_adc14_default &pinctrl_adc15_default>;
>+};
>+
>+&peci0 {
>+	status = "okay";
>+};
>+
>+&lpc_snoop {
>+	snoop-ports = <0x80>;
>+	status = "okay";
>+};
>+
>+&mac2 {
>+	status = "okay";
>+	phy-mode = "rmii";
>+	use-ncsi;
>+	pinctrl-names = "default";
>+	pinctrl-0 = <&pinctrl_rmii3_default>;
>+};
>+
>+&mac3 {
>+	status = "okay";
>+	phy-mode = "rmii";
>+	use-ncsi;
>+	pinctrl-names = "default";
>+	pinctrl-0 = <&pinctrl_rmii4_default>;
>+};
>+
>+&fmc {
>+	status = "okay";
>+
>+	flash at 0 {
>+		status = "okay";
>+		m25p,fast-read;
>+		label = "bmc-spi";

Is this specific label needed or desired for some particular reason?
Most OpenBMC platforms just call it "bmc", and I think some of the
firmware-update machinery may have assumptions about that baked in, so I
wouldn't be surprised if this naming breaks things...

>+		spi-max-frequency = <50000000>;
>+#include "openbmc-flash-layout-128.dtsi"

Just to confirm, this is actually a 128MB flash chip?  I ask because the
previous version of this patch had some indication of it being 64MB
(though there was a lot that looked wonky with the partition layout, so
maybe that was wrong too).

>+	};
>+};
>+
>+&spi1 {
>+	status = "okay";
>+	pinctrl-names = "default";
>+	pinctrl-0 = <&pinctrl_spi1_default>;
>+
>+	flash at 0 {
>+		status = "okay";
>+		label = "bios-spi";
>+		spi-max-frequency = <50000000>;
>+
>+		partitions {
>+			compatible = "fixed-partitions";
>+			#address-cells = <1>;
>+			#size-cells = <1>;
>+
>+			biosfullimg at 0 {
>+				reg = <0x0 0x2000000>; //32768 *1024 = 32 MB
>+				label = "biosfullimg";
>+			};
>+		};

If there's only one partition that's just covering the whole chip
there's no need to include the 'partitions' child node.

>+	};
>+};
>+
>+&i2c0 {
>+	status = "okay";
>+};
>+
>+&i2c1 {
>+	status = "okay";
>+};
>+
>+&i2c2 {
>+	status = "okay";
>+};
>+
>+&i2c3 {
>+	status = "okay";
>+};
>+
>+&i2c4 {
>+	status = "okay";
>+
>+	temperature-sensor at 48 {
>+		compatible = "ti,tmp75";
>+		reg = <0x48>;
>+	};
>+
>+	temperature-sensor at 49 {
>+		compatible = "ti,tmp75";
>+		reg = <0x49>;
>+	};
>+
>+	pca9555_4_20: gpio at 20 {
>+		compatible = "nxp,pca9555";
>+		reg = <0x20>;
>+		gpio-controller;
>+		#gpio-cells = <2>;
>+	};
>+
>+	pca9555_4_22: gpio at 22 {
>+		compatible = "nxp,pca9555";
>+		reg = <0x22>;
>+		gpio-controller;
>+		#gpio-cells = <2>;
>+	};
>+
>+	pca9555_4_24: gpio at 24 {
>+		compatible = "nxp,pca9555";
>+		reg = <0x24>;
>+		gpio-controller;
>+		#gpio-cells = <2>;
>+		gpio-line-names =
>+		/*A0 - A3 0*/	"", "STRAP_BMC_BATTERY_GPIO1", "", "",
>+		/*A4 - A7 4*/	"", "", "", "",
>+		/*B0 - B7 8*/	"", "", "", "", "", "", "", "";
>+	};
>+
>+	pca9555_4_26: gpio at 26 {
>+		compatible = "nxp,pca9555";
>+		reg = <0x26>;
>+		gpio-controller;
>+		#gpio-cells = <2>;
>+	};
>+
>+	i2c-mux at 70 {
>+		compatible = "nxp,pca9546";
>+		status = "okay";
>+		reg = <0x70>;
>+		#address-cells = <1>;
>+		#size-cells = <0>;
>+
>+		channel_1: i2c at 0 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <0>;
>+		};
>+
>+		channel_2: i2c at 1 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <1>;
>+		};
>+
>+		channel_3: i2c at 2 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <2>;
>+		};
>+
>+		channel_4: i2c at 3 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <3>;
>+		};
>+	};
>+};
>+
>+&i2c5 {
>+	status = "okay";
>+
>+	pca9555_5_24: gpio at 24 {
>+		compatible = "nxp,pca9555";
>+		reg = <0x24>;
>+		gpio-controller;
>+		#gpio-cells = <2>;
>+	};
>+
>+	i2c-mux at 70  {
>+		compatible = "nxp,pca9546";
>+		status = "okay";
>+		reg = <0x70 >;
>+		#address-cells = <1>;
>+		#size-cells = <0>;
>+
>+		channel_5: i2c at 0 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <0>;
>+
>+			pca9555_5_5_20: gpio at 20 {
>+				compatible = "nxp,pca9555";
>+				reg = <0x20>;
>+				gpio-controller;
>+				#gpio-cells = <2>;
>+				gpio-line-names =
>+					"", "", "", "", "", "", "", "",
>+					"", "", "SYS_FAN6", "SYS_FAN5",
>+					"SYS_FAN4", "SYS_FAN3",
>+					"SYS_FAN2", "SYS_FAN1";
>+			};
>+
>+			pca9555_5_5_21: gpio at 21 {
>+				compatible = "nxp,pca9555";
>+				reg = <0x21>;
>+				gpio-controller;
>+				#gpio-cells = <2>;
>+			};
>+
>+			power-monitor at 44 {
>+				compatible = "ti,ina219";
>+				reg = <0x44>;
>+				shunt-resistor = <2>;
>+			};
>+		};
>+
>+		channel_6: i2c at 1 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <1>;
>+		};
>+
>+		channel_7: i2c at 2 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <2>;
>+		};
>+
>+		channel_8: i2c at 3 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <3>;
>+		};
>+	};
>+};
>+
>+&i2c6 {
>+	status = "okay";
>+
>+	pca9555_6_27: gpio at 27 {
>+		compatible = "nxp,pca9555";
>+		reg = <0x27>;
>+		gpio-controller;
>+		#gpio-cells = <2>;
>+	};
>+
>+	pca9555_6_20: gpio at 20 {
>+		compatible = "nxp,pca9555";
>+		reg = <0x20>;
>+		gpio-controller;
>+		#gpio-cells = <2>;
>+		gpio-line-names =
>+		/*A0 0*/	"", "", "", "", "", "", "", "",
>+		/*B0 8*/	"Drive_NVMe1", "Drive_NVMe2", "", "",
>+		/*B4 12*/	"", "", "", "";
>+	};
>+
>+	pca9555_6_21: gpio at 21 {
>+		compatible = "nxp,pca9555";
>+		reg = <0x21>;
>+		gpio-controller;
>+		#gpio-cells = <2>;
>+	};
>+};
>+
>+&i2c7 {
>+	status = "okay";
>+
>+	i2c-mux at 70 {
>+		compatible = "nxp,pca9546";
>+		status = "okay";
>+		reg = <0x70>;
>+		#address-cells = <1>;
>+		#size-cells = <0>;
>+		idle-state = <1>;
>+
>+		channel_9: i2c at 0 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <0>;
>+
>+			temperature-sensor at 48 {
>+				compatible = "ti,tmp75";
>+				reg = <0x48>;
>+			};
>+
>+			temperature-sensor at 49 {
>+				compatible = "ti,tmp75";
>+				reg = <0x49>;
>+			};
>+
>+			power-monitor at 40 {
>+				compatible = "ti,ina219";
>+				reg = <0x40>;
>+				shunt-resistor = <2>;
>+			};
>+
>+			power-monitor at 41 {
>+				compatible = "ti,ina219";
>+				reg = <0x41>;
>+				shunt-resistor = <5>;
>+			};
>+		};
>+
>+		channel_10: i2c at 1 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <1>;
>+		};
>+
>+		channel_11: i2c at 2 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <2>;
>+		};
>+
>+		channel_12: i2c at 3 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <3>;
>+		};
>+	};
>+
>+	i2c-mux at 71 {
>+		compatible = "nxp,pca9546";
>+		status = "okay";
>+		reg = <0x71>;
>+		#address-cells = <1>;
>+		#size-cells = <0>;
>+		i2c-mux-idle-disconnect;
>+
>+		channel_13: i2c at 0 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <0>;
>+		};
>+
>+		channel_14: i2c at 1 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <1>;
>+		};
>+
>+		channel_15: i2c at 2 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <2>;
>+		};
>+
>+		channel_16: i2c at 3 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <3>;
>+		};
>+	};
>+};
>+
>+&i2c8 {
>+	status = "okay";
>+
>+	i2c-mux at 70 {
>+		compatible = "nxp,pca9546";
>+		status = "okay";
>+		reg = <0x70>;
>+		#address-cells = <1>;
>+		#size-cells = <0>;
>+		i2c-mux-idle-disconnect;
>+
>+		channel_17: i2c at 0 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <0>;
>+		};
>+
>+		channel_18: i2c at 1 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <1>;
>+
>+			temperature-sensor at 48 {
>+				compatible = "ti,tmp75";
>+				reg = <0x48>;
>+			};
>+
>+			power-monitor at 41 {
>+				compatible = "ti,ina219";
>+				reg = <0x41>;
>+				shunt-resistor = <5>;
>+			};
>+		};
>+
>+		channel_19: i2c at 2 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <2>;
>+		};
>+
>+		channel_20: i2c at 3 {
>+			#address-cells = <1>;
>+			#size-cells = <0>;
>+			reg = <3>;
>+		};
>+	};
>+};
>+
>+&i2c9 {
>+	status = "okay";
>+};
>+
>+&i2c10 {
>+	status = "okay";
>+};
>+
>+&i2c11 {
>+	status = "okay";
>+};
>+
>+&i2c14 {
>+	status = "okay";
>+	multi-master;
>+
>+	eeprom at 50 {
>+		compatible = "atmel,24c08";
>+		reg = <0x50>;
>+	};
>+
>+	eeprom at 51 {
>+		compatible = "atmel,24c08";
>+		reg = <0x51>;
>+	};
>+};
>+
>+&sgpiom0 {
>+	status = "okay";
>+	ngpios = <128>;
>+};
>+
>+&video {
>+	status = "okay";
>+	memory-region = <&video_engine_memory>;
>+};
>+
>+&sdc {
>+	status = "okay";
>+};
>+
>+&lpc_snoop {
>+	status = "okay";
>+	snoop-ports = <0x80>;
>+};
>+
>+&kcs1 {
>+	aspeed,lpc-io-reg = <0xca0>;
>+	status = "okay";
>+};
>+
>+&kcs2 {
>+	aspeed,lpc-io-reg = <0xca8>;
>+	status = "okay";
>+};
>+
>+&kcs3 {
>+	aspeed,lpc-io-reg = <0xca2>;
>+	status = "okay";
>+};
>+
>+&uart3 {
>+	status = "okay";
>+};
>+
>+&uart5 {
>+	status = "okay";
>+};
>+
>+&uart_routing {
>+	status = "okay";
>+};
>+
>+&vhub {
>+	status = "okay";
>+};
>+
>+&gpio0 {
>+	gpio-line-names =
>+	/*A0 0*/	"", "", "", "", "", "", "", "",
>+	/*B0 8*/	"", "", "", "", "", "", "PS_PWROK", "",
>+	/*C0 16*/	"", "", "", "", "", "", "", "",
>+	/*D0 24*/	"", "", "", "", "", "", "", "",
>+	/*E0 32*/	"", "", "", "", "", "", "", "",
>+	/*F0 40*/	"", "", "", "", "", "", "", "",
>+	/*G0 48*/	"", "", "", "", "", "", "", "",
>+	/*H0 56*/	"", "", "", "", "", "", "", "",
>+	/*I0 64*/	"", "", "", "", "", "", "", "",
>+	/*J0 72*/	"", "", "", "", "", "", "", "",
>+	/*K0 80*/	"", "", "", "", "", "", "", "",
>+	/*L0 88*/	"", "", "", "", "", "", "", "",
>+	/*M0 96*/	"", "", "", "", "", "", "", "",
>+	/*N0 104*/	"", "", "", "",
>+	/*N4 108*/	"POST_COMPLETE", "ESR1_GPIO_AST_SPISEL", "", "",
>+	/*O0 112*/	"", "", "", "", "", "", "", "",
>+	/*P0 120*/	"ID_BUTTON", "ID_OUT", "POWER_BUTTON", "POWER_OUT",
>+	/*P4 124*/	"RESET_BUTTON", "RESET_OUT", "", "HEARTBEAT",
>+	/*Q0 128*/	"", "", "", "", "", "", "", "",
>+	/*R0 136*/	"", "", "", "", "", "", "", "",
>+	/*S0 144*/	"", "", "", "", "", "", "", "",
>+	/*T0 152*/	"", "", "", "", "", "", "", "",
>+	/*U0 160*/	"", "", "", "", "", "", "", "",
>+	/*V0 168*/	"", "", "", "", "", "", "", "",
>+	/*W0 176*/	"", "", "", "", "", "", "", "",
>+	/*X0 184*/	"", "", "", "", "", "", "", "",
>+	/*Y0 192*/	"", "", "", "", "", "", "", "",
>+	/*Z0 200*/	"", "", "", "", "", "", "", "";
>+};
>-- 
>2.25.1
>

From zweiss at equinix.com  Fri Feb 23 14:01:15 2024
From: zweiss at equinix.com (Zev Weiss)
Date: Fri, 23 Feb 2024 22:01:15 +0000
Subject: [PATCH 1/2] dt-bindings: arm: aspeed: add ASUS X4TF board
In-Reply-To: <20240222-getting-nebulizer-8f75ba8063b1@spud>
References: <20240222085914.1218037-1-Kelly_Hung@asus.com>
 <20240222-getting-nebulizer-8f75ba8063b1@spud>
Message-ID: <20240223220115.GB9299@packtop>

On Thu, Feb 22, 2024 at 08:02:07AM PST, Conor Dooley wrote:
>On Thu, Feb 22, 2024 at 04:59:13PM +0800, Kelly Hung wrote:
>> Document the new compatibles used on ASUS X4TF.
>
>It would be good to mention here what the x4tf is - is it a bmc or
>an sbc etc.
>

...and if, as a quick web search indicates is likely the case, it's a
BMC for a server (or family of servers), following the existing naming
convention with something more like "asus,x4tf-bmc" might be nice.

Also, Kelly -- when sending revised versions of patches please use the
'-v' flag to git format-patch to include a version number in the subject
line so it's clearer what's going on.  (So when posting the next version
incorporating the feedback on this one use '-v3', since this appears to
be a v2.)

Zev


From fancer.lancer at gmail.com  Fri Feb 23 14:24:54 2024
From: fancer.lancer at gmail.com (Serge Semin)
Date: Sat, 24 Feb 2024 01:24:54 +0300
Subject: [PATCH net-next v3 3/3] net: stmmac: Configure AXI on Tegra234
 MGBE
In-Reply-To: <CZ9Z70HO2C7J.398BRNM8NBIG1@gmail.com>
References: <20240219-stmmac-axi-config-v3-0-fca7f046e6ee@nvidia.com>
 <20240219-stmmac-axi-config-v3-3-fca7f046e6ee@nvidia.com>
 <xne2i6jwqaptsrd2hjdahxbscysgtj7iabqendyjb75fnrjc5z@js7n7qngtzym>
 <CZ9Z70HO2C7J.398BRNM8NBIG1@gmail.com>
Message-ID: <kns2u6o4nhz4vda74r2mscyyp6yjgo2p62vryeenucm4o3ngzb@j6ch3sl6xha2>

On Tue, Feb 20, 2024 at 03:28:39PM +0100, Thierry Reding wrote:
> On Mon Feb 19, 2024 at 7:32 PM CET, Serge Semin wrote:
> > On Mon, Feb 19, 2024 at 05:46:06PM +0100, Thierry Reding wrote:
> > > From: Thierry Reding <treding at nvidia.com>
> > > 
> > > Allow the device to use bursts and increase the maximum number of
> > > outstanding requests to improve performance. Measurements show an
> > > increase in throughput of around 5x on a 1 Gbps link.
> > > 
> > > Signed-off-by: Thierry Reding <treding at nvidia.com>
> > > ---
> > >  drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c | 9 +++++++++
> > >  1 file changed, 9 insertions(+)
> > > 
> > > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> > > index bab57d1675df..b6bfa48f279d 100644
> > > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> > > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
> > > @@ -199,6 +199,12 @@ static void mgbe_uphy_lane_bringup_serdes_down(struct net_device *ndev, void *mg
> > >  	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
> > >  }
> > >  
> > > +static const struct stmmac_axi tegra234_mgbe_axi = {
> > > +	.axi_wr_osr_lmt = 63,
> > > +	.axi_rd_osr_lmt = 63,
> > > +	.axi_blen = { 256, },
> > > +};
> > > +
> > >  static int tegra_mgbe_probe(struct platform_device *pdev)
> > >  {
> > >  	struct plat_stmmacenet_data *plat;
> > > @@ -284,6 +290,9 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
> > >  	if (err < 0)
> > >  		goto disable_clks;
> > >  
> > > +	/* setup default AXI configuration */
> > > +	res.axi = &tegra234_mgbe_axi;
> > > +
> > >  	plat = devm_stmmac_probe_config_dt(pdev, &res);
> > >  	if (IS_ERR(plat)) {
> > >  		err = PTR_ERR(plat);
> >
> > Let's get back to the v2 discussion:
> >
> > On Mon Feb 5, 2024 at 1:44 AM CET, Serge Semin wrote:
> > > The entire series can be converted to just a few lines of change:
> > >     plat = devm_stmmac_probe_config_dt(pdev, res.mac);
> > >     if (IS_ERR(plat)) {
> > >             err = PTR_ERR(plat);
> > >             goto disable_clks;
> > >     }
> > > +
> > > +   if (IS_ERR_OR_NULL(plat->axi)) {
> > > +           plat->axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
> > > +           if (!plat->axi) {
> > > +                   ret = -ENOMEM;
> > > +                   goto disable_clks;
> > > +           }
> > > +   } /* else memset plat->axi with zeros if you wish */
> > > +
> > > +   plat->axi->axi_wr_osr_lmt = 63;
> > > +   plat->axi->axi_rd_osr_lmt = 63;
> > > +   plat->axi->axi_blen[0] = 256;
> > >  
> > >     plat->has_xgmac = 1;
> > >     plat->flags |= STMMAC_FLAG_TSO_EN;
> > >     plat->pmt = 1;
> > >
> > > Please don't overcomplicate the already overcomplicated driver with a
> > > functionality which can be reached by the default one. In this case
> > > the easiest way is to let the generic code work and then
> > > override/replace/fix/etc the retrieved values. Thus there won't be
> > > need in adding the redundant functionality and keep the generic
> > > DT-platform code a bit simpler to read.
> >
> > You responded with:
> >
> > On Tue, Feb 13, 2024 at 04:51:34PM +0100, Thierry Reding wrote:
> > > I'm not sure I understand how this is overcomplicating things. The code
> > > is pretty much unchanged, except that the AXI configuration can now have
> > > driver-specified defaults before the DT is parsed. Perhaps I need to add
> > > comments to make that a bit clearer?
> > > 
> > > While your version is certainly simpler it has the drawback that it no
> > > longer allows the platform defaults to be overridden in device tree. I
> > > would prefer if the defaults can be derived from the compatible string
> > > but if need be for those defaults to still be overridable from device
> > > tree.
> >
> > Currently available functionality is easier to read and understand: by
> > default the data is retrieved from the DT, if no AXI DT-node found you
> > can allocate/create your own AXI-configs, if there is AXI DT-node you
> > can fix it up in whatever way your wish. Thus the default behavior is
> > straightforward. You on the contrary suggest to add an additional
> > field to the resources structure which would need to be merged in with
> > the data retrieved from DT. It makes the stmmac_axi_setup() method and
> > the entire logic more complex and thus harder to comprehend.
> 
> I suppose that's subjective. Being able to let the driver provide
> defaults that can then be overridden by values from DT doesn't seem like
> a very exotic (or complicated) feature to me. We do that elsewhere all
> the time. Do the comments that I added in this version not sufficiently
> explain what's going on?

I have perfectly understood what was going on since v1. My concern is
the implementation. Here is the way the platform-specific setup
currently works.

There are two structures: stmmac_resources and plat_stmmacenet_data.
The former one contains the generic platform resources like CSRs
mapping, IRQs and MAC-address. The later one mainly has the DW
MAC-specific settings. Yes, plat_stmmacenet_data has been evolved to
an ugly monster with many redundant flags (fixing code and data here
and there in the driver) and with some generic platform resources
(which should have been added to the stmmac_resources structure in the
first place, like clocks and resets). But still it's purpose is
more-or-less defined. Both of these structures can be filled in with
data either directly by the glue drivers or by calling the
ready-to-use DW MAC platform data getters (stmmac_probe_config_dt()
and stmmac_get_platform_resources()). Most importantly is that
currently these structures have independent init semantics: no common
data, no fields used in both contexts. There are tons of problematic
places or questionable implementations in the driver, but at least
this one is more-or-less defined: coherency is minimal, logic is
linear.

You suggest to break that logic by introducing a new stmmac_resources
field which doesn't represent a generic resource data, but which
purpose is to tweak the AXI-settings in the plat_stmmacenet_data
structure. The pointer won't be even ever initialized in the
stmmac_get_platform_resources() method because it's done in the
stmmac_probe_config_dt() function. Based on all of that the change you
suggest look more like a fixup of the problem with your particular
device/platform.

Let's assume you patches are accepted. In sometime an another
developer comes with a need to pre-define say MTL Tx/Rx queue configs,
then another one with DMA configs, MDIO-bus settings, and so on. Thus
the stmmac_resources structure will eventually turn in a set of the
tweaks and the plat_stmmacenet_data pre-defines. That's how the
plat_stmmacenet_data structure has turned in what it is now. This
doesn't look like a right path to take again.

> 
> > The driver is already overwhelmed with flags and private/platform data
> > fixing the code here and there (see plat_stmmacenet_data, it's a
> > madness). So please justify in more details why do you need one more
> > complexity added instead of:
> > 1. overriding the AXI-configs retrieved from DT,
> 
> Again, overriding the AXI configs read from DT doesn't keep the current
> default behaviour of DT being the final authority. That's a policy that
> should remain intact. This patch (series) is about allowing the driver
> to override the AXI defaults with something that's sensible based on
> the compatible string. The current defaults, for example, cause the GBE
> on Tegra devices to run at around 100 Mbps even on a 1 Gbps link.
> 
> > 2. updating DT on your platform
> 

> That's one possibility and was in fact the first variant I used, but it
> has a few drawbacks. For example, it means that I need to create the AXI
> node just to make the device functional, but if possible it's better to
> derive all necessary information from the compatible string. Having this
> in a separate AXI configuration node is duplicating information that's
> already implied by the compatible string.
> 
> Also, on Tegra we have a few instances of this device that are all
> configured the same way. Since the AXI configuration node is supposed to
> be a child of the Ethernet controller node, we end up having to
> duplicate even more information.

None of that sounds like big problems. The default behavior doesn't
make your devices not-working. Yes, the performance is poor, but they
still work. Regarding the AXI-config DT-nodes it's not a problem at
all. A lot of the DW *MAC instances currently have the AXI-config
DT-subnodes. It's absolutely fine to have them setting up the same
configs.

Once again having the pre-defined configs is fine. All I am worried
about is the implementation you suggest especially in using the
stmmac_resources structure to tweak up the plat_stmmacenet_data data.
So the easiest solutions in your case are:
1. Initialize the plat_stmmacenet_data->axi pointer if no AXI
DT-subnode was detected by the stmmac_probe_config_dt() method, after
the method is called. This will provide almost the same semantics as
you suggest. The only difference is that it would work not on the
property level but on the node-level one. (Note the implementation
suggested by you doesn't provide the AXI-configs pre-definition for
the boolean properties. So it doesn't provide a complete AXI-config
default pre-definition.)
2. Add the proper AXI-config DT-subnodes to the respective device tree
sources.

If despite of all my reasoning you still insist on having a
pre-defined setting pattern, then we'll need to come up with some
better solution. On the top of my mind it might be for example a
pre-definition of the entire plat_stmmacenet_data structure instance
or using the software nodes.

-Serge(y)

> 
> Thierry




From daniel.lezcano at linaro.org  Fri Feb 23 14:27:41 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 23 Feb 2024 23:27:41 +0100
Subject: [PATCH v3] thermal/drivers/sun8i: Don't fail probe due to zone
 registration failure
In-Reply-To: <20240123-thermal-sun8i-registration-v3-1-3e5771b1bbdd@kernel.org>
References: <20240123-thermal-sun8i-registration-v3-1-3e5771b1bbdd@kernel.org>
Message-ID: <c93b9ec4-2447-4be1-b316-3395d35eb8f5@linaro.org>

On 24/01/2024 00:33, Mark Brown wrote:
> Currently the sun8i thermal driver will fail to probe if any of the
> thermal zones it is registering fails to register with the thermal core.
> Since we currently do not define any trip points for the GPU thermal
> zones on at least A64 or H5 this means that we have no thermal support
> on these platforms:
> 
> [    1.698703] thermal_sys: Failed to find 'trips' node
> [    1.698707] thermal_sys: Failed to find trip points for thermal-sensor id=1
> 
> even though the main CPU thermal zone on both SoCs is fully configured.
> This does not seem ideal, while we may not be able to use all the zones
> it seems better to have those zones which are usable be operational.
> Instead just carry on registering zones if we get any non-deferral
> error, allowing use of those zones which are usable.
> 
> This means that we also need to update the interrupt handler to not
> attempt to notify the core for events on zones which we have not
> registered, I didn't see an ability to mask individual interrupts and
> I would expect that interrupts would still be indicated in the ISR even
> if they were masked.
> 
> Reviewed-by: Vasily Khoruzhick <anarsoul at gmail.com>
> Acked-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---

Applied, thanks

-- 
<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 quic_tsoni at quicinc.com  Fri Feb 23 14:48:49 2024
From: quic_tsoni at quicinc.com (Trilok Soni)
Date: Fri, 23 Feb 2024 14:48:49 -0800
Subject: [PATCH v2 2/7] clk: qcom: clk-alpha-pll: Add HUAYRA_2290 support
In-Reply-To: <20240219-topic-rb1_gpu-v2-2-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
 <20240219-topic-rb1_gpu-v2-2-2d3d6a0db040@linaro.org>
Message-ID: <605d9e50-d61b-b0ce-1664-00554ba70b41@quicinc.com>

On 2/23/2024 1:21 PM, Konrad Dybcio wrote:
> +	/* Wait 50us for PLL_LOCK_DET bit to go high */
> +	usleep_range(50, 55);
> +
> +	/* Enable PLL output */
> +	regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
> +}
> +EXPORT_SYMBOL(clk_huayra_2290_pll_configure);

Please use EXPORT_SYMBOL_GPL. 

-- 
---Trilok Soni



From quic_eberman at quicinc.com  Fri Feb 23 14:58:43 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Fri, 23 Feb 2024 14:58:43 -0800
Subject: [PATCH v17 05/35] virt: gunyah: Add hypervisor driver
In-Reply-To: <a3356079-bd55-4852-9bb3-b5362a1c953e@linaro.org>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
 <20240222-gunyah-v17-5-1e9da6763d38@quicinc.com>
 <a3356079-bd55-4852-9bb3-b5362a1c953e@linaro.org>
Message-ID: <20240223144844667-0800.eberman@hu-eberman-lv.qualcomm.com>

On Fri, Feb 23, 2024 at 10:10:47PM +0100, Konrad Dybcio wrote:
> On 23.02.2024 00:16, Elliot Berman wrote:
> > Add driver to detect when running under Gunyah. It performs basic
> > identification hypercall and populates the platform bus for resource
> > manager to probe.
> > 
> > Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
> > ---
> 
> [...]
> 
> > +
> > +	/* Might move this out to individual drivers if there's ever an API version bump */
> > +	if (gunyah_api_version(&gunyah_api) != GUNYAH_API_V1) {
> > +		pr_info("Unsupported Gunyah version: %u\n",
> > +			gunyah_api_version(&gunyah_api));
> 
> Weird for this not to be an error, but it's probably not worth resending
> over if it's the only thing

It is an error, but maybe I misunderstood:

> > +	/* Might move this out to individual drivers if there's ever an API version bump */
> > +	if (gunyah_api_version(&gunyah_api) != GUNYAH_API_V1) {
> > +		pr_info("Unsupported Gunyah version: %u\n",
> > +			gunyah_api_version(&gunyah_api));
> > +		return -ENODEV;
> > +	}



From festevam at gmail.com  Fri Feb 23 15:01:13 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Fri, 23 Feb 2024 20:01:13 -0300
Subject: [PATCH] arm64: imx8-apalis-v1.1: Remove reset-names from ethernet-phy
Message-ID: <20240223230113.1258120-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

The 'reset-names' property is not a valid one under ethernet-phy
and causes the following dt-schema warning:

/imx8qm-apalis-v1.1-eval-v1.2.dtb: ethernet-phy at 7: 'resets' is a dependency of 'reset-names'
	from schema $id: http://devicetree.org/schemas/reset/reset.yaml#

Remove this property.

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
 arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
index f69b0c17560a..160153853b68 100644
--- a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
@@ -261,7 +261,6 @@ ethphy0: ethernet-phy at 7 {
 			reset-assert-us = <2>;
 			reset-deassert-us = <2>;
 			reset-gpios = <&lsio_gpio1 11 GPIO_ACTIVE_LOW>;
-			reset-names = "phy";
 		};
 	};
 };
-- 
2.34.1



From festevam at gmail.com  Fri Feb 23 15:09:16 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Fri, 23 Feb 2024 20:09:16 -0300
Subject: [PATCH] arm64: dts: imx8mm-kontron-bl-osm-s: Fix Ethernet PHY compatible
Message-ID: <20240223230916.1261467-1-festevam@gmail.com>

From: Fabio Estevam <festevam at denx.de>

According to motorcomm,yt8xxx.yaml, the compatible string must be
only 'ethernet-phy-id4f51.e91b'.

Remove 'ethernet-phy-ieee802.3-c22' to fix the following dt-schema warning:

imx8mm-kontron-bl-osm-s.dtb: ethernet-phy at 0: compatible: ['ethernet-phy-id4f51.e91b', 'ethernet-phy-ieee802.3-c22'] is too long
	from schema $id: http://devicetree.org/schemas/net/motorcomm,yt8xxx.yaml#

Signed-off-by: Fabio Estevam <festevam at denx.de>
---
 arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
index efadfdff00af..33f8d7d1970e 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
@@ -107,8 +107,7 @@ mdio {
 		#size-cells = <0>;
 
 		ethphy: ethernet-phy at 0 {
-			compatible = "ethernet-phy-id4f51.e91b",
-				     "ethernet-phy-ieee802.3-c22";
+			compatible = "ethernet-phy-id4f51.e91b";
 			reg = <0>;
 			reset-assert-us = <10000>;
 			reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
-- 
2.34.1



From megi at xff.cz  Fri Feb 23 15:28:36 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Sat, 24 Feb 2024 00:28:36 +0100
Subject: [PATCH v2 3/4] arm64: dts: sun50i-a64-pinephone: add multicolor
 led node
In-Reply-To: <5hqfabcolgqcu22hs3xnaimojwuz26tzi63px3rvbsgxa6kjss@ik42w7k26see>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <20240206185400.596979-3-aren@peacevolution.org>
 <sixgkkllo7medcjwjnmbkpqkgfvnmrtlhlwarwuxid5oqwrht5@gl65b6fetq2b>
 <5hqfabcolgqcu22hs3xnaimojwuz26tzi63px3rvbsgxa6kjss@ik42w7k26see>
Message-ID: <xhowm7pne2og7iyhoa7wi26qa5q23fvl2ptaxtwnp4upgunubo@q5unl6mzvluy>

Hello Aren,

On Fri, Feb 23, 2024 at 10:22:36AM -0500, Aren wrote:
> On Fri, Feb 23, 2024 at 09:46:25AM +0100, Ond?ej Jirman wrote:
> > Hello Aren,
> > 
> > On Tue, Feb 06, 2024 at 01:13:19PM -0500, Aren Moynihan wrote:
> > > The red, green, and blue leds currently in the device tree represent a
> > > single rgb led on the front of the PinePhone.
> > > 
> > > Signed-off-by: Aren Moynihan <aren at peacevolution.org>
> > > ---
> > > 
> > > Changes in v2:
> > >  - remove function property from individual led nodes
> > > 
> > >  .../boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 16 ++++++++++------
> > >  1 file changed, 10 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > index ad2476ee01e4..e53e0d4579a7 100644
> > > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > @@ -39,28 +39,32 @@ chosen {
> > >  	leds {
> > >  		compatible = "gpio-leds";
> > >  
> > > -		led-0 {
> > > -			function = LED_FUNCTION_INDICATOR;
> > 
> > This looks like a needless change that will just break people's current scripts
> > and setup. It does mine, and there sure are others that will be surprised, too.
> > 
> > This leads to a change in sysfs path from:
> > 
> >   /sys/class/leds/blue:indicator
> > 
> > to
> > 
> >   /sys/class/leds/blue:
> > 
> > which is 1) a weird name and 2) a backwards compatibility break for seemingly
> > no apparent reason. Any reaons for the change?
> 
> Leds-group-multicolor will make those read-only, so that will break when
> it's enabled either way. Removing the function property makes it less
> likely that programs attempting to discover leds will use the wrong
> path.

Allright. Then this breaks even more usecases then I thought. I quite depend on
being able to apply various kernel based LED triggers to individual LEDs in the
RGB LED. (The LED is not really multi-color in practice - you don't get a mix of
colors. It's only technically a RGB LED, but if you turn on red and green, you
see red and green, individually. I suspect it's a clear capped LED, not
a diffused one and expects an external difuser - which Pinephone doesn't have.
So this works out quite fine from the user perspective, because you see
individual colors and can assign meanings to them individually)

So this change makes it that I'll not be able to map different triggers
to individual colors now.

Eg. I have a power manager driver for Pinephone keyboard that exports LED triggers
to indicate various charging states of the keyboard battery, so that I get
warnings when the KB is discharged, or disconnected from control algorithm
due to its tendency to shut off, and disappear from I2C bus, etc. AXP20x driver
also exports a bunch of useful triggers.

---

As a side note, this new multicolor abstraction seems a bit lacking and
cumbersome, too.

I still have to control individual LEDs via multi_intensity file and have to
parse multi_index to even know which number corresponds to what color. In addition
I have to ensure correct value in brightness file.

If I want to change one of the LEDs, I now have to first read the whole status
of multi-color LED and update it somehow in a non-racy way, which is
impossible with this API without going through some userspace daemon that
centralizes the LED control. 

If this is expected to be usable in device independent way, then there's another
problem:  multi_intensity values don't seem to have any range defined in sysfs,
so I can't know what is the max usable value. How do I know the range is 0-1 vs
0-255 or 0-200000? There's max_brightness but that seems to be related to
possible values in brightness file. Seems like I can write pretty much anything
to multi_intensity, even things like this:

  https://megous.com/dl/tmp/4c6db9376f148951.png

(looks like all LEDs are turned on even for negative intensity)

If multi_intensity is supposed to be some relative measure of brightenss of
individual LEDs in RGB LED, then echo '1 1 1000' > multi_intensity 
should pretty much result in only red LED being on. But all are on at full
brightness. So the kernel doesn't even represent the desired color properly,
based on HW limitations it knows about. There's no aproximation/rounding to the
limits of control of individual LEDs. Even 1 millionth of relative intensity
will result in the LED being turned fully on.

Discoverability of how to control the LEDs is also quite lacking. Individual
directories under /sys/class/leds are still there for individual parts of RGB
LED, and it's not clearly identifiable that you can't control them. brightness
file still has -rw-r--r-- permissions. But writing to it produces EBUSY.
As far as I can see, the only indication that something is amiss is that
there's a device/consumer:platform:multi-led symlink under the individual LEDs.
But that can have any name in practice, and how can one know that just because
some device has a in-kernel consumer, that it's a kind of a consumer that blocks
changes to the device?

If I have to discover that some LED is controlled by some other driver only
by trying to light it up, then that's not a great API, I'd say.

End of side note. :)

---

^^^^ All this from the PoV of a (API) user. I can understand the device-tree
appeal of representing the technically RGB LED as RGB node, but as a user who
messes with sysfs, and likes the simplicity and flexibility of how things work
now, with the upstream Pinephone DT, I really dislike the change, because it
forces unpleasant userspace changes, incl. necessity for some userspace LED
control daemon to get race-free LED control from multiple sources. And I'm not
even sure what I'd do with the keyboard driver, and how to keep the triggers
working.

Anyway, I and others can get around all this by:

  echo multi-led > /sys/class/leds/rgb:status/device/driver/unbind

at system startup and get back control via idndividual LED directories.
But please don't change the names of directories that were there up to now. That
will just break many people's scripts for no reason. So my only request is to
make this fallback to previous way it worked easy.

Kind regards,
	o.

> I left these in v1 of this patch, but was recommended to remove them.
> https://lore.kernel.org/lkml/k26bellccok4tj3kz2nrtp2vth2rnsiea677e2kzm56m767wjx at pnkqiz5hmiyb/
>
> Thanks for taking a look at this
>  - Aren
> 
> > People normally hardcode these paths in eg. /etc/tmpfiles.d to apply LED triggers
> > to particular LEDs.
> > 
> > Kind regards,
> > 	o.
> > 
> > > +		led0: led-0 {
> > >  			color = <LED_COLOR_ID_BLUE>;
> > >  			gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */
> > >  			retain-state-suspended;
> > >  		};
> > >  
> > > -		led-1 {
> > > -			function = LED_FUNCTION_INDICATOR;
> > > +		led1: led-1 {
> > >  			color = <LED_COLOR_ID_GREEN>;
> > >  			gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */
> > >  			retain-state-suspended;
> > >  		};
> > >  
> > > -		led-2 {
> > > -			function = LED_FUNCTION_INDICATOR;
> > > +		led2: led-2 {
> > >  			color = <LED_COLOR_ID_RED>;
> > >  			gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */
> > >  			retain-state-suspended;
> > >  		};
> > >  	};
> > >  
> > > +	multi-led {
> > > +		compatible = "leds-group-multicolor";
> > > +		color = <LED_COLOR_ID_RGB>;
> > > +		function = LED_FUNCTION_INDICATOR;
> > > +		leds = <&led0>, <&led1>, <&led2>;
> > > +	};
> > > +
> > >  	reg_ps: ps-regulator {
> > >  		compatible = "regulator-fixed";
> > >  		regulator-name = "ps";
> > > -- 
> > > 2.43.0
> > > 


From shawnguo2 at yeah.net  Fri Feb 23 15:30:24 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sat, 24 Feb 2024 07:30:24 +0800
Subject: [PATCH] arm64: dts: freescale: minor whitespace cleanup
In-Reply-To: <20240208105217.128748-1-krzysztof.kozlowski@linaro.org>
References: <20240208105217.128748-1-krzysztof.kozlowski@linaro.org>
Message-ID: <ZdkqkFjL6U9zEpX7@dragon>

On Thu, Feb 08, 2024 at 11:52:17AM +0100, Krzysztof Kozlowski wrote:
> The DTS code coding style expects exactly one space before '{'
> character.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Applied, thanks!



From shawnguo2 at yeah.net  Fri Feb 23 15:33:09 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sat, 24 Feb 2024 07:33:09 +0800
Subject: [PATCH] ARM: dts: imx6ul: Set macaddress location in ocotp
In-Reply-To: <20240208122012.1959628-1-manuel.traut@mt.com>
References: <20240208122012.1959628-1-manuel.traut@mt.com>
Message-ID: <ZdkrNfkXGo2pprLW@dragon>

On Thu, Feb 08, 2024 at 01:19:59PM +0100, Manuel Traut wrote:
> If a bootloader does not configure the MAC address, devices come up with
> a random MAC at the moment.
> 
> ocotp provides registers for storing the mac-address.
> Configure those for i.MX6UL and i.MX6ULL allows net/core to retrieve it from
> there.
> 
> Signed-off-by: Manuel Traut <manuel.traut at mt.com>
> ---
>  arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
> index a27a7554c2e7..e5e8bf814f77 100644
> --- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
> +++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
> @@ -538,6 +538,8 @@ fec2: ethernet at 20b4000 {
>  				fsl,num-rx-queues = <1>;
>  				fsl,stop-mode = <&gpr 0x10 4>;
>  				fsl,magic-packet;
> +				nvmem-cells = <&fec2_mac_addr>;
> +				nvmem-cell-names = "mac-address";
>  				status = "disabled";
>  			};
>  
> @@ -897,6 +899,8 @@ fec1: ethernet at 2188000 {
>  				fsl,num-rx-queues = <1>;
>  				fsl,stop-mode = <&gpr 0x10 3>;
>  				fsl,magic-packet;
> +				nvmem-cells = <&fec1_mac_addr>;
> +				nvmem-cell-names = "mac-address";
>  				status = "disabled";
>  			};
>  
> @@ -1004,6 +1008,14 @@ tempmon_temp_grade: temp-grade at 20 {
>  				cpu_speed_grade: speed-grade at 10 {
>  					reg = <0x10 4>;
>  				};

Have a newline between nodes.

> +				fec1_mac_addr: mac-addr at 88 {
> +					reg = <0x88 6>;
> +				};
> +
> +				fec2_mac_addr: mac-addr at 8e {
> +					reg = <0x8e 6>;
> +				};
> +

Dropped this one.

I fixed them up and applied the patch.

Shawn

>  			};
>  
>  			csi: csi at 21c4000 {
> -- 
> 2.43.0
> 



From konrad.dybcio at linaro.org  Fri Feb 23 15:46:31 2024
From: konrad.dybcio at linaro.org (Konrad Dybcio)
Date: Sat, 24 Feb 2024 00:46:31 +0100
Subject: [PATCH v17 05/35] virt: gunyah: Add hypervisor driver
In-Reply-To: <20240223144844667-0800.eberman@hu-eberman-lv.qualcomm.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
 <20240222-gunyah-v17-5-1e9da6763d38@quicinc.com>
 <a3356079-bd55-4852-9bb3-b5362a1c953e@linaro.org>
 <20240223144844667-0800.eberman@hu-eberman-lv.qualcomm.com>
Message-ID: <b50aae99-151b-47ed-b610-99f4748790bf@linaro.org>

On 23.02.2024 23:58, Elliot Berman wrote:
> On Fri, Feb 23, 2024 at 10:10:47PM +0100, Konrad Dybcio wrote:
>> On 23.02.2024 00:16, Elliot Berman wrote:
>>> Add driver to detect when running under Gunyah. It performs basic
>>> identification hypercall and populates the platform bus for resource
>>> manager to probe.
>>>
>>> Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
>>> ---
>>
>> [...]
>>
>>> +
>>> +	/* Might move this out to individual drivers if there's ever an API version bump */
>>> +	if (gunyah_api_version(&gunyah_api) != GUNYAH_API_V1) {
>>> +		pr_info("Unsupported Gunyah version: %u\n",
>>> +			gunyah_api_version(&gunyah_api));
>>
>> Weird for this not to be an error, but it's probably not worth resending
>> over if it's the only thing
> 
> It is an error, but maybe I misunderstood:

Sorry, I meant "pr_info might have been pr_err"

Konrad

> 
>>> +	/* Might move this out to individual drivers if there's ever an API version bump */
>>> +	if (gunyah_api_version(&gunyah_api) != GUNYAH_API_V1) {
>>> +		pr_info("Unsupported Gunyah version: %u\n",
>>> +			gunyah_api_version(&gunyah_api));
>>> +		return -ENODEV;
>>> +	}
> 


From quic_eberman at quicinc.com  Fri Feb 23 16:37:23 2024
From: quic_eberman at quicinc.com (Elliot Berman)
Date: Fri, 23 Feb 2024 16:37:23 -0800
Subject: [PATCH v17 19/35] arch/mm: Export direct {un,}map functions
In-Reply-To: <ZdhEtH7xzbzdhS2j@infradead.org>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
 <20240222-gunyah-v17-19-1e9da6763d38@quicinc.com>
 <ZdhEtH7xzbzdhS2j@infradead.org>
Message-ID: <20240223071006483-0800.eberman@hu-eberman-lv.qualcomm.com>

On Thu, Feb 22, 2024 at 11:09:40PM -0800, Christoph Hellwig wrote:
> On Thu, Feb 22, 2024 at 03:16:42PM -0800, Elliot Berman wrote:
> > Firmware and hypervisor drivers can donate system heap memory to their
> > respective firmware/hypervisor entities. Those drivers should unmap the
> > pages from the kernel's logical map before doing so.
> > 
> > Export can_set_direct_map, set_direct_map_invalid_noflush, and
> > set_direct_map_default_noflush.
> 
> Err, not they should not.  And not using such super low-level interfaces
> from modular code.

Hi Cristoph,
 
We've observed a few times that Linux can unintentionally access a page
we've unmapped from host's stage 2 page table via an unaligned load from
an adjacent page. The stage 2 is managed by Gunyah. There are few
scenarios where even though we allocate and own a page from buddy,
someone else could try to access the page without going through the
hypervisor driver. One such instance we know about is
load_unaligned_zeropad() via pathlookup_at() [1].
 
load_unaligned_zeropad() could be called near the end of a page. If the
next page isn't mapped by the kernel in the stage one page tables, then
the access from to the unmapped page from load_unaligned_zeropad() will
land in __do_kernel_fault(), call fixup_exception(), and fill the
remainder of the load with zeroes. If the page in question is mapped in
stage 1 but was unmapped from stage 2, then the access lands back in
Linux in do_sea(), leading to a panic().
 
Our preference would be to add fixup_exception() to S2 PTW errors for
two reasons:
1. It's cheaper to do performance wise: we've already manipulated S2
   page table and prevent intentional access to the page because
   pKVM/Gunyah drivers know that access to the page has been lost.
2. Page-granular S1 mappings only happen on arm64 with rodata=full.
 
In an off-list discussion with the Android pkvm folks, their preference
was to have the pages unmapped from stage 1. I've gone with that
approach to get started but welcome discussion on the best approach.
 
The Android (downstream) implementation of arm64 pkvm is currently
implementing a hack where s2 ptw faults are given back to the host as s1
ptw faults (i.e. __do_kernel_fault() gets called and not do_sea()) --
allowing the kernel to fixup the exception.
 
arm64 pKVM will also face this issue when implementing guest_memfd or
when donating more memory to the hyp for s2 page tables, etc. As far as
I can tell, this isn't an issue for arm64 pKVM today because memory
isn't being dynamically donated to the hypervisor.
 
Thanks,
Elliot

[1]:
path_lookupat+0x340/0x3228
filename_lookup+0xbc/0x1c0
__arm64_sys_newfstatat+0xb0/0x4a0
invoke_syscall+0x58/0x118



From herbert at gondor.apana.org.au  Fri Feb 23 16:49:56 2024
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Sat, 24 Feb 2024 08:49:56 +0800
Subject: [PATCH] [v2] ARM: crypto: fix function cast warnings
In-Reply-To: <20240213135000.3400052-1-arnd@kernel.org>
References: <20240213135000.3400052-1-arnd@kernel.org>
Message-ID: <Zdk9NLCwfmsiDhTQ@gondor.apana.org.au>

On Tue, Feb 13, 2024 at 02:49:46PM +0100, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> clang-16 warns about casting between incompatible function types:
> 
> arch/arm/crypto/sha256_glue.c:37:5: error: cast from 'void (*)(u32 *, const void *, unsigned int)' (aka 'void (*)(unsigned int *, const void *, unsigned int)') to 'sha256_block_fn *' (aka 'void (*)(struct sha256_state *, const unsigned char *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>    37 |                                 (sha256_block_fn *)sha256_block_data_order);
>       |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> arch/arm/crypto/sha512-glue.c:34:3: error: cast from 'void (*)(u64 *, const u8 *, int)' (aka 'void (*)(unsigned long long *, const unsigned char *, int)') to 'sha512_block_fn *' (aka 'void (*)(struct sha512_state *, const unsigned char *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
>    34 |                 (sha512_block_fn *)sha512_block_data_order);
>       |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Fix the prototypes for the assembler functions to match the typedef.
> The code already relies on the digest being the first part of the
> state structure, so there is no change in behavior.
> 
> Fixes: c80ae7ca3726 ("crypto: arm/sha512 - accelerated SHA-512 using ARM generic ASM and NEON")
> Fixes: b59e2ae3690c ("crypto: arm/sha256 - move SHA-224/256 ASM/NEON implementation to base layer")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> ---
> v2: rewrite change as suggested by Herbert Xu.
> ---
>  arch/arm/crypto/sha256_glue.c | 13 +++++--------
>  arch/arm/crypto/sha512-glue.c | 12 +++++-------
>  2 files changed, 10 insertions(+), 15 deletions(-)

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  Fri Feb 23 16:52:13 2024
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Sat, 24 Feb 2024 08:52:13 +0800
Subject: [PATCH] crypto: rockchip - fix to check return value
In-Reply-To: <20240218221658.131043-1-kilian.zinnecker@mail.de>
References: <20240218221658.131043-1-kilian.zinnecker@mail.de>
Message-ID: <Zdk9vc7OPEPcXA1/@gondor.apana.org.au>

On Sun, Feb 18, 2024 at 11:16:58PM +0100, Kilian Zinnecker wrote:
> crypto_engine_alloc_init may fail, e.g., as result of a fail of
> devm_kzalloc or kthread_create_worker. Other drivers (e.g.,
> amlogic-gxl-core.c, aspeed-acry.c, aspeed-hace.c, jr.c, etc.) check
> crypto_engine_alloc_init's return value and return -ENOMEM in case
> a NULL pointer is returned. This patch inserts a corresponding
> return value check to rk3288_crypto.c.
> 
> Signed-off-by: Kilian Zinnecker <kilian.zinnecker at mail.de>
> ---
>  drivers/crypto/rockchip/rk3288_crypto.c | 5 +++++
>  1 file changed, 5 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 keescook at chromium.org  Fri Feb 23 17:01:21 2024
From: keescook at chromium.org (Kees Cook)
Date: Fri, 23 Feb 2024 17:01:21 -0800
Subject: [PATCH] mm: Revert x86_64 and arm64 ELF_ET_DYN_BASE base
In-Reply-To: <CACT4Y+ZnNdb1z7oSq0zb3XHFTcdEwSMFvcvLJxm1VrgnpaohMw@mail.gmail.com>
References: <20170807201542.GA21271@beast>
 <202402162238.E5D08F5968@keescook>
 <CACT4Y+ZnNdb1z7oSq0zb3XHFTcdEwSMFvcvLJxm1VrgnpaohMw@mail.gmail.com>
Message-ID: <202402231649.086D1A3A@keescook>

On Tue, Feb 20, 2024 at 08:47:09AM +0100, Dmitry Vyukov wrote:
> On Sat, 17 Feb 2024 at 07:50, Kees Cook <keescook at chromium.org> wrote:
> >
> > *extreme thread[1] necromancy*
> >
> > On Mon, Aug 07, 2017 at 01:15:42PM -0700, Kees Cook wrote:
> > > Moving the x86_64 and arm64 PIE base from 0x555555554000 to 0x000100000000
> > > broke AddressSanitizer. This is a partial revert of:
> > >
> > >   commit eab09532d400 ("binfmt_elf: use ELF_ET_DYN_BASE only for PIE")
> > >   commit 02445990a96e ("arm64: move ELF_ET_DYN_BASE to 4GB / 4MB")
> > >
> > > The AddressSanitizer tool has hard-coded expectations about where
> > > executable mappings are loaded. The motivation for changing the PIE
> > > base in the above commits was to avoid the Stack-Clash CVEs that
> > > allowed executable mappings to get too close to heap and stack. This
> > > was mainly a problem on 32-bit, but the 64-bit bases were moved too,
> > > in an effort to proactively protect those systems (proofs of concept
> > > do exist that show 64-bit collisions, but other recent changes to fix
> > > stack accounting and setuid behaviors will minimize the impact).
> >
> > I happened to be looking at this again today, and wondered where things
> > stood. It seems like ASan's mappings are documented here:
> > https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm#64-bit
> >
> > This implies that it would be safe to move the ELF_ET_DYN_BASE from
> > 0x555555554000 down to 0x200000000000, since the shadow map ends at
> > 0x10007fff7fff. (Well, anything above there would work, I was just
> > picking a "round" number above it. We could just as well use
> > 0x100080000000, I think.)
> >
> > Is this correct? I'd like to open up some more room between mmap and
> > stack...

Thanks for the details!

> Note that there is also TSAN and MSAN with their own mappings.
> These are also different per-arch, e.g. TSAN/Linux/x86_64:
> https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/tsan/rtl/tsan_platform.h#L48-L58
> Search "linux/" in that file for other arches, e.g.:
> https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/tsan/rtl/tsan_platform.h#L156-L165
> https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/tsan/rtl/tsan_platform.h#L187-L196
> https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/tsan/rtl/tsan_platform.h#L218-L227
> https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/tsan/rtl/tsan_platform.h#L252-L263

Depending on VA size, these are effectively all below 0x3800 0000 0000.

> 
> And MSAN mappings:
> https://github.com/llvm/llvm-project/blob/d2a26a7bd5fc7cc5752337b7f4f999642feb37dc/compiler-rt/lib/msan/msan.h#L44-L61

These are all below 0x1000 0000 0000.

So there probably isn't much benefit in reducing the PIE program
position below the current 0x55....

Okay, thanks!

-- 
Kees Cook


From jisheng.teoh at starfivetech.com  Fri Feb 23 17:12:39 2024
From: jisheng.teoh at starfivetech.com (JiSheng Teoh)
Date: Sat, 24 Feb 2024 01:12:39 +0000
Subject: [PATCH v6 1/4] perf: starfive: Add StarLink PMU support
In-Reply-To: <20240223112633.GA10403@willie-the-truck>
References: <20240129095141.3262366-1-jisheng.teoh@starfivetech.com>
 <20240129095141.3262366-2-jisheng.teoh@starfivetech.com>
 <20240223112633.GA10403@willie-the-truck>
Message-ID: <ZQ0PR01MB1160A9376461CAE829BEA13AEB54A@ZQ0PR01MB1160.CHNPR01.prod.partner.outlook.cn>

> On Mon, Jan 29, 2024 at 05:51:38PM +0800, Ji Sheng Teoh wrote:
> > This patch adds support for StarFive's StarLink PMU (Performance
> > Monitor Unit). StarLink PMU integrates one or more CPU cores with a
> > shared L3 memory system. The PMU supports overflow interrupt, up to 16
> > programmable 64bit event counters, and an independent 64bit cycle
> > counter. StarLink PMU is accessed via MMIO.
> 
> Since Palmer acked this (thanks!), I queued it locally but then ran into a few small issues with my build testing. Comments below.
> 
> > diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig index
> > 273d67ecf6d2..41278742ef88 100644
> > --- a/drivers/perf/Kconfig
> > +++ b/drivers/perf/Kconfig
> > @@ -86,6 +86,15 @@ config RISCV_PMU_SBI
> >  	  full perf feature support i.e. counter overflow, privilege mode
> >  	  filtering, counter configuration.
> >
> > +config STARFIVE_STARLINK_PMU
> > +	depends on ARCH_STARFIVE
> 
> Please can you add "|| COMPILE_TEST" to this dependency so that you get build coverage from other architectures?
> 
Sure, will add it in the next revision.

> > +	bool "StarFive StarLink PMU"
> > +	help
> > +	   Provide support for StarLink Performance Monitor Unit.
> > +	   StarLink Performance Monitor Unit integrates one or more cores with
> > +	   an L3 memory system. The L3 cache events are added into perf event
> > +	   subsystem, allowing monitoring of various L3 cache perf events.
> > +
> >  config ARM_PMU_ACPI
> >  	depends on ARM_PMU && ACPI
> >  	def_bool y
> 
> [...]
> 
> > diff --git a/drivers/perf/starfive_starlink_pmu.c
> > b/drivers/perf/starfive_starlink_pmu.c
> > new file mode 100644
> > index 000000000000..2447ca09a471
> > --- /dev/null
> > +++ b/drivers/perf/starfive_starlink_pmu.c
> > @@ -0,0 +1,643 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * StarFive's StarLink PMU driver
> > + *
> > + * Copyright (C) 2023 StarFive Technology Co., Ltd.
> > + *
> > + * Author: Ji Sheng Teoh <jisheng.teoh at starfivetech.com>
> > + *
> > + */
> 
> [...]
> 
> > +static void starlink_pmu_counter_start(struct perf_event *event,
> > +				       struct starlink_pmu *starlink_pmu) {
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	int idx = event->hw.idx;
> > +	u64 val;
> > +
> > +	/*
> > +	 * Enable counter overflow interrupt[63:0],
> > +	 * which is mapped as follow:
> > +	 *
> > +	 * event counter 0	- Bit [0]
> > +	 * event counter 1	- Bit [1]
> > +	 * ...
> > +	 * cycle counter	- Bit [63]
> > +	 */
> > +	val = readq(starlink_pmu->pmu_base + STARLINK_PMU_INTERRUPT_ENABLE);
> > +
> > +	if (hwc->config == STARLINK_CYCLES) {
> > +		/*
> > +		 * Cycle count has its dedicated register, and it starts
> > +		 * counting as soon as STARLINK_PMU_GLOBAL_ENABLE is set.
> > +		 */
> > +		val |= STARLINK_PMU_CYCLE_OVERFLOW_MASK;
> > +	} else {
> > +		writeq(event->hw.config, starlink_pmu->pmu_base +
> > +		       STARLINK_PMU_EVENT_SELECT + idx * sizeof(u64));
> > +
> > +		val |= (1 << idx);
> > +	}
> 
> I think this needs to be a u64 on the right hand side, or just use the
> BIT_ULL() macro.
> 
Ahh ok, will just append it with BIT_ULL() macro.

> > +
> > +	writeq(val, starlink_pmu->pmu_base + STARLINK_PMU_INTERRUPT_ENABLE);
> > +
> > +	writeq(STARLINK_PMU_GLOBAL_ENABLE, starlink_pmu->pmu_base +
> > +	       STARLINK_PMU_CONTROL);
> > +}
> 
> [...]
> 
> > +static irqreturn_t starlink_pmu_handle_irq(int irq_num, void *data) {
> > +	struct starlink_pmu *starlink_pmu = data;
> > +	struct starlink_hw_events *hw_events =
> > +			this_cpu_ptr(starlink_pmu->hw_events);
> > +	bool handled = false;
> > +	int idx;
> > +	u64 overflow_status;
> > +
> > +	for (idx = 0; idx < STARLINK_PMU_MAX_COUNTERS; idx++) {
> > +		struct perf_event *event = hw_events->events[idx];
> > +
> > +		if (!event)
> > +			continue;
> > +
> > +		overflow_status = readq(starlink_pmu->pmu_base +
> > +					STARLINK_PMU_COUNTER_OVERFLOW_STATUS);
> > +		if (!(overflow_status & BIT(idx)))
> > +			continue;
> > +
> > +		writeq(1 << idx, starlink_pmu->pmu_base +
> > +		       STARLINK_PMU_COUNTER_OVERFLOW_STATUS);
> 
> Same shifting problem here.
> 
Got it.

> > +static int starlink_pmu_probe(struct platform_device *pdev) {
> > +	struct starlink_pmu *starlink_pmu;
> > +	struct starlink_hw_events *hw_events;
> > +	struct resource *res;
> > +	int cpuid, i, ret;
> > +
> > +	starlink_pmu = devm_kzalloc(&pdev->dev, sizeof(*starlink_pmu), GFP_KERNEL);
> > +	if (!starlink_pmu)
> > +		return -ENOMEM;
> > +
> > +	starlink_pmu->pmu_base =
> > +			devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> > +	if (IS_ERR(starlink_pmu->pmu_base))
> > +		return PTR_ERR(starlink_pmu->pmu_base);
> > +
> > +	starlink_pmu->hw_events = alloc_percpu_gfp(struct starlink_hw_events,
> > +						   GFP_KERNEL);
> > +	if (!starlink_pmu->hw_events) {
> > +		dev_err(&pdev->dev, "Failed to allocate per-cpu PMU data\n");
> > +		kfree(starlink_pmu);
> 
> You shouldn't call kfree() on a device-managed object (i.e. allocated with devm_kzalloc()).
> 
You are right, I will drop it.

Thanks for the review Will.

JiSheng


From megi at xff.cz  Fri Feb 23 18:20:43 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Sat, 24 Feb 2024 03:20:43 +0100
Subject: [PATCH 3/3] drm/sun4i: Fix layer zpos change/atomic modesetting
In-Reply-To: <2448947.jE0xQCEvom@jernej-laptop>
References: <20240216190430.1374132-1-megi@xff.cz>
 <20240216190430.1374132-4-megi@xff.cz>
 <inuhwnlexpt6dpre4uailtvytjhms4uqeerzehbntczurhcxol@fc4nvkdwffdd>
 <2448947.jE0xQCEvom@jernej-laptop>
Message-ID: <5h7jcwsdlpe7w2xylbhlw2asfww3znqlmlnszwvvosz5ssokkq@dxhn4v4sy4nq>

On Thu, Feb 22, 2024 at 09:02:53PM +0100, Jernej ?krabec wrote:
> Dne sreda, 21. februar 2024 ob 14:45:20 CET je Maxime Ripard napisal(a):
> > Hi,
> > 
> > On Fri, Feb 16, 2024 at 08:04:26PM +0100, Ond?ej Jirman wrote:
> > > From: Ondrej Jirman <megi at xff.cz>
> > > 
> > > Identical configurations of planes can lead to different (and wrong)
> > > layer -> pipe routing at HW level, depending on the order of atomic
> > > plane changes.
> > > 
> > > For example:
> > > 
> > > - Layer 1 is configured to zpos 0 and thus uses pipe 0. No other layer
> > >   is enabled. This is a typical situation at boot.
> > > 
> > > - When a compositor takes over and layer 3 is enabled,
> > >   sun8i_ui_layer_enable() will get called with old_zpos=0 zpos=1, which
> > >   will lead to incorrect disabling of pipe 0 and enabling of pipe 1.
> > > 
> > > What happens is that sun8i_ui_layer_enable() function may disable
> > > blender pipes even if it is no longer assigned to its layer.
> > > 
> > > To correct this, move the routing setup out of individual plane's
> > > atomic_update into crtc's atomic_update, where it can be calculated
> > > and updated all at once.
> > > 
> > > Remove the atomic_disable callback because it is no longer needed.
> > > 
> > > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > 
> > I don't have enough knowledge about the mixers code to comment on your
> > patch, so I'll let Jernej review it. However, this feels to me like the
> > pipe assignment is typically the sort of things that should be dealt
> > with device-wide, and in atomic_check.
> 
> In DE2 and DE3.0, you cannot move planes between mixers (crtcs), because each
> one is hardwired to specific mixer. Movable planes are the feature of DE3.3
> and one of the pain points for upstreaming the code. Anyway, this commit only
> addresses current issue of enabling and disabling planes and handling zpos.
> 
> In atomic check you can only precalculate final register values, but I don't
> see any benefit doing that. I think that this code elegantly solves current
> issue of enabling or disabling wrong plane in certain situations, so:
> 
> Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> 
> Note, if there is new revision, please rewrite blender regmap_update_bits()
> to regmap_write(). Since there is HW issue with reads, I would like to
> get rid of regmap_update_bits() calls eventually.

I've looked into it and I can probably rewrite these quite readily:

+	regmap_update_bits(mixer->engine.regs,
+			   SUN8I_MIXER_BLEND_ROUTE(bld_base),
+			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(0) |
+			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(1) |
+			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(2) |
+			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(3),
+			   route);

The mask here covers all implemented bits in the register.

+	regmap_update_bits(mixer->engine.regs,
+			   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(0) |
+			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(1) |
+			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(2) |
+			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(3),
+			   pipe_en);
+

The mask here doesn't cover BLD_FILL_COLOR_CTL.Px_FCEN bits that implement solid
color filling. But those can be 0 anyway except for pipe0 which is hardcoded by
the driver to 1, I think:

631         /*
632          * Set fill color of bottom plane to black. Generally not needed
633          * except when VI plane is at bottom (zpos = 0) and enabled.
634          */
635         regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
636                      SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));

I will not be able to get rid of regmap_update_bits in sun8i_layer_enable
because that register there has other important things in it like framebuffer
pixel format, etc.

kind regards,
	o.

> Best regards,
> Jernej
> 
> > 
> > If I'm talking non-sense, it would be great to mention at least why that
> > can't be an option in the commit log.
> > 
> > Maxime
> > 
> 
> 
> 
> 


From aren at peacevolution.org  Fri Feb 23 18:52:04 2024
From: aren at peacevolution.org (Aren)
Date: Fri, 23 Feb 2024 21:52:04 -0500
Subject: [PATCH v2 3/4] arm64: dts: sun50i-a64-pinephone: add multicolor
 led node
In-Reply-To: <xhowm7pne2og7iyhoa7wi26qa5q23fvl2ptaxtwnp4upgunubo@q5unl6mzvluy>
References: <20240206185400.596979-1-aren@peacevolution.org>
 <20240206185400.596979-3-aren@peacevolution.org>
 <sixgkkllo7medcjwjnmbkpqkgfvnmrtlhlwarwuxid5oqwrht5@gl65b6fetq2b>
 <5hqfabcolgqcu22hs3xnaimojwuz26tzi63px3rvbsgxa6kjss@ik42w7k26see>
 <xhowm7pne2og7iyhoa7wi26qa5q23fvl2ptaxtwnp4upgunubo@q5unl6mzvluy>
Message-ID: <lkhwdfw67nfgsz2pectd7xgr724owf4z2qlyinmxncv5ncf4mw@si7tvaao7ums>

On Sat, Feb 24, 2024 at 12:28:36AM +0100, Ond?ej Jirman wrote:
> Hello Aren,
> 
> On Fri, Feb 23, 2024 at 10:22:36AM -0500, Aren wrote:
> > On Fri, Feb 23, 2024 at 09:46:25AM +0100, Ond?ej Jirman wrote:
> > > Hello Aren,
> > > 
> > > On Tue, Feb 06, 2024 at 01:13:19PM -0500, Aren Moynihan wrote:
> > > > The red, green, and blue leds currently in the device tree represent a
> > > > single rgb led on the front of the PinePhone.
> > > > 
> > > > Signed-off-by: Aren Moynihan <aren at peacevolution.org>
> > > > ---
> > > > 
> > > > Changes in v2:
> > > >  - remove function property from individual led nodes
> > > > 
> > > >  .../boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 16 ++++++++++------
> > > >  1 file changed, 10 insertions(+), 6 deletions(-)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > > index ad2476ee01e4..e53e0d4579a7 100644
> > > > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > > > @@ -39,28 +39,32 @@ chosen {
> > > >  	leds {
> > > >  		compatible = "gpio-leds";
> > > >  
> > > > -		led-0 {
> > > > -			function = LED_FUNCTION_INDICATOR;
> > > 
> > > This looks like a needless change that will just break people's current scripts
> > > and setup. It does mine, and there sure are others that will be surprised, too.
> > > 
> > > This leads to a change in sysfs path from:
> > > 
> > >   /sys/class/leds/blue:indicator
> > > 
> > > to
> > > 
> > >   /sys/class/leds/blue:
> > > 
> > > which is 1) a weird name and 2) a backwards compatibility break for seemingly
> > > no apparent reason. Any reaons for the change?
> > 
> > Leds-group-multicolor will make those read-only, so that will break when
> > it's enabled either way. Removing the function property makes it less
> > likely that programs attempting to discover leds will use the wrong
> > path.
> 
> Allright. Then this breaks even more usecases then I thought. I quite depend on
> being able to apply various kernel based LED triggers to individual LEDs in the
> RGB LED. (The LED is not really multi-color in practice - you don't get a mix of
> colors. It's only technically a RGB LED, but if you turn on red and green, you
> see red and green, individually. I suspect it's a clear capped LED, not
> a diffused one and expects an external difuser - which Pinephone doesn't have.
> So this works out quite fine from the user perspective, because you see
> individual colors and can assign meanings to them individually)
> 
> So this change makes it that I'll not be able to map different triggers
> to individual colors now.
> 
> Eg. I have a power manager driver for Pinephone keyboard that exports LED triggers
> to indicate various charging states of the keyboard battery, so that I get
> warnings when the KB is discharged, or disconnected from control algorithm
> due to its tendency to shut off, and disappear from I2C bus, etc. AXP20x driver
> also exports a bunch of useful triggers.
> 
> ---
> 
> As a side note, this new multicolor abstraction seems a bit lacking and
> cumbersome, too.
> 
> I still have to control individual LEDs via multi_intensity file and have to
> parse multi_index to even know which number corresponds to what color. In addition
> I have to ensure correct value in brightness file.
> 
> If I want to change one of the LEDs, I now have to first read the whole status
> of multi-color LED and update it somehow in a non-racy way, which is
> impossible with this API without going through some userspace daemon that
> centralizes the LED control. 
> 
> If this is expected to be usable in device independent way, then there's another
> problem:  multi_intensity values don't seem to have any range defined in sysfs,
> so I can't know what is the max usable value. How do I know the range is 0-1 vs
> 0-255 or 0-200000? There's max_brightness but that seems to be related to
> possible values in brightness file. Seems like I can write pretty much anything
> to multi_intensity, even things like this:
> 
>   https://megous.com/dl/tmp/4c6db9376f148951.png
> 
> (looks like all LEDs are turned on even for negative intensity)
> 
> If multi_intensity is supposed to be some relative measure of brightenss of
> individual LEDs in RGB LED, then echo '1 1 1000' > multi_intensity 
> should pretty much result in only red LED being on. But all are on at full
> brightness. So the kernel doesn't even represent the desired color properly,
> based on HW limitations it knows about. There's no aproximation/rounding to the
> limits of control of individual LEDs. Even 1 millionth of relative intensity
> will result in the LED being turned fully on.
> 
> Discoverability of how to control the LEDs is also quite lacking. Individual
> directories under /sys/class/leds are still there for individual parts of RGB
> LED, and it's not clearly identifiable that you can't control them. brightness
> file still has -rw-r--r-- permissions. But writing to it produces EBUSY.
> As far as I can see, the only indication that something is amiss is that
> there's a device/consumer:platform:multi-led symlink under the individual LEDs.
> But that can have any name in practice, and how can one know that just because
> some device has a in-kernel consumer, that it's a kind of a consumer that blocks
> changes to the device?
> 
> If I have to discover that some LED is controlled by some other driver only
> by trying to light it up, then that's not a great API, I'd say.
> 
> End of side note. :)
> 
> ---
> 
> ^^^^ All this from the PoV of a (API) user. I can understand the device-tree
> appeal of representing the technically RGB LED as RGB node, but as a user who
> messes with sysfs, and likes the simplicity and flexibility of how things work
> now, with the upstream Pinephone DT, I really dislike the change, because it
> forces unpleasant userspace changes, incl. necessity for some userspace LED
> control daemon to get race-free LED control from multiple sources. And I'm not
> even sure what I'd do with the keyboard driver, and how to keep the triggers
> working.
> 
> Anyway, I and others can get around all this by:
> 
>   echo multi-led > /sys/class/leds/rgb:status/device/driver/unbind
> 
> at system startup and get back control via idndividual LED directories.
> But please don't change the names of directories that were there up to now. That
> will just break many people's scripts for no reason. So my only request is to
> make this fallback to previous way it worked easy.

Makes sense, I'll send v1 again with a revised commit message when I get
a chance (this was the only change to the device tree part of this
patchset between v1 and v2).

Thanks
 - Aren

> Kind regards,
> 	o.
> 
> > I left these in v1 of this patch, but was recommended to remove them.
> > https://lore.kernel.org/lkml/k26bellccok4tj3kz2nrtp2vth2rnsiea677e2kzm56m767wjx at pnkqiz5hmiyb/
> >
> > Thanks for taking a look at this
> >  - Aren
> > 
> > > People normally hardcode these paths in eg. /etc/tmpfiles.d to apply LED triggers
> > > to particular LEDs.
> > > 
> > > Kind regards,
> > > 	o.
> > > 
> > > > +		led0: led-0 {
> > > >  			color = <LED_COLOR_ID_BLUE>;
> > > >  			gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */
> > > >  			retain-state-suspended;
> > > >  		};
> > > >  
> > > > -		led-1 {
> > > > -			function = LED_FUNCTION_INDICATOR;
> > > > +		led1: led-1 {
> > > >  			color = <LED_COLOR_ID_GREEN>;
> > > >  			gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */
> > > >  			retain-state-suspended;
> > > >  		};
> > > >  
> > > > -		led-2 {
> > > > -			function = LED_FUNCTION_INDICATOR;
> > > > +		led2: led-2 {
> > > >  			color = <LED_COLOR_ID_RED>;
> > > >  			gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */
> > > >  			retain-state-suspended;
> > > >  		};
> > > >  	};
> > > >  
> > > > +	multi-led {
> > > > +		compatible = "leds-group-multicolor";
> > > > +		color = <LED_COLOR_ID_RGB>;
> > > > +		function = LED_FUNCTION_INDICATOR;
> > > > +		leds = <&led0>, <&led1>, <&led2>;
> > > > +	};
> > > > +
> > > >  	reg_ps: ps-regulator {
> > > >  		compatible = "regulator-fixed";
> > > >  		regulator-name = "ps";
> > > > -- 
> > > > 2.43.0
> > > > 


From zenghui.yu at linux.dev  Fri Feb 23 20:39:34 2024
From: zenghui.yu at linux.dev (Zenghui Yu)
Date: Sat, 24 Feb 2024 12:39:34 +0800
Subject: [PATCH 5/8] KVM: arm64: Fix typos
In-Reply-To: <20240103231605.1801364-6-helgaas@kernel.org>
References: <20240103231605.1801364-1-helgaas@kernel.org>
 <20240103231605.1801364-6-helgaas@kernel.org>
Message-ID: <2cd87332-b3f9-e415-6458-57eb3615c43e@linux.dev>

On 2024/1/4 07:16, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
> 
> Fix typos, most reported by "codespell arch/arm64".  Only touches comments,
> no code changes.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> Cc: James Morse <james.morse at arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Zenghui Yu <yuzenghui at huawei.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: kvmarm at lists.linux.dev

Oliver, mind taking it into 6.9?


From lkp at intel.com  Fri Feb 23 21:58:05 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 24 Feb 2024 13:58:05 +0800
Subject: [soc:for-next] BUILD SUCCESS
 d6f69171ea309b76ee2b03a184bdb1047eb1a387
Message-ID: <202402241301.YztIos3z-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: d6f69171ea309b76ee2b03a184bdb1047eb1a387  soc: document merges

elapsed time: 948m

configs tested: 164
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                   randconfig-001-20240224   gcc  
arc                   randconfig-002-20240224   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                     am200epdkit_defconfig   gcc  
arm                                 defconfig   clang
arm                            hisi_defconfig   gcc  
arm                   randconfig-001-20240224   gcc  
arm                   randconfig-002-20240224   gcc  
arm                   randconfig-003-20240224   gcc  
arm                   randconfig-004-20240224   gcc  
arm                          sp7021_defconfig   gcc  
arm                           u8500_defconfig   gcc  
arm                         wpcm450_defconfig   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240224   gcc  
arm64                 randconfig-002-20240224   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240224   gcc  
csky                  randconfig-002-20240224   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-002-20240224   clang
i386         buildonly-randconfig-005-20240224   clang
i386         buildonly-randconfig-006-20240224   clang
i386                                defconfig   clang
i386                  randconfig-002-20240224   clang
i386                  randconfig-003-20240224   clang
i386                  randconfig-013-20240224   clang
i386                  randconfig-014-20240224   clang
i386                  randconfig-015-20240224   clang
i386                  randconfig-016-20240224   clang
loongarch                        alldefconfig   gcc  
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                        allyesconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240224   gcc  
loongarch             randconfig-002-20240224   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
m68k                        m5407c3_defconfig   gcc  
m68k                       m5475evb_defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                             allmodconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                         bigsur_defconfig   gcc  
mips                       bmips_be_defconfig   gcc  
mips                      fuloong2e_defconfig   gcc  
mips                           ip28_defconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240224   gcc  
nios2                 randconfig-002-20240224   gcc  
openrisc                         allmodconfig   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
openrisc                    or1ksim_defconfig   gcc  
openrisc                 simple_smp_defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                randconfig-001-20240224   gcc  
parisc                randconfig-002-20240224   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc                     ksi8560_defconfig   gcc  
powerpc                     powernv_defconfig   gcc  
powerpc64             randconfig-001-20240224   gcc  
powerpc64             randconfig-003-20240224   gcc  
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                 randconfig-001-20240224   gcc  
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240224   gcc  
s390                  randconfig-002-20240224   gcc  
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                ecovec24-romimage_defconfig   gcc  
sh                          landisk_defconfig   gcc  
sh                     magicpanelr2_defconfig   gcc  
sh                    randconfig-001-20240224   gcc  
sh                    randconfig-002-20240224   gcc  
sh                          rsk7201_defconfig   gcc  
sh                           se7721_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                            allyesconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240224   gcc  
sparc64               randconfig-002-20240224   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                    randconfig-001-20240224   gcc  
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240224   clang
x86_64       buildonly-randconfig-002-20240224   clang
x86_64       buildonly-randconfig-003-20240224   clang
x86_64       buildonly-randconfig-004-20240224   clang
x86_64       buildonly-randconfig-005-20240224   clang
x86_64       buildonly-randconfig-006-20240224   clang
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240224   clang
x86_64                randconfig-003-20240224   clang
x86_64                randconfig-006-20240224   clang
x86_64                randconfig-014-20240224   clang
x86_64                randconfig-015-20240224   clang
x86_64                randconfig-016-20240224   clang
x86_64                randconfig-072-20240224   clang
x86_64                randconfig-073-20240224   clang
x86_64                randconfig-076-20240224   clang
x86_64                          rhel-8.3-rust   clang
x86_64                               rhel-8.3   gcc  
xtensa                            allnoconfig   gcc  
xtensa                           allyesconfig   gcc  
xtensa                generic_kc705_defconfig   gcc  
xtensa                  nommu_kc705_defconfig   gcc  
xtensa                randconfig-001-20240224   gcc  
xtensa                randconfig-002-20240224   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:06 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:06 +0530
Subject: [PATCH v8 00/10] PCI: dwc: ep: Fix DBI access failure for drivers
 requiring refclk from host
Message-ID: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>

Hello,

This series is the continuation of previous work by Vidya Sagar [1] to fix the
issues related to accessing DBI register space before completing the core
initialization in some EP platforms like Tegra194/234 and Qcom EP.

Since Vidya is busy, I took over the series based on his consent (off-list
discussion).

NOTE
====

Based on the comments received in v7 [2], I've heavily modified the series
to fix several other issues reported by Bjorn and Niklas. One noticeable
change is getting rid of the 'core_init_notifer' flag added to differentiate
between glue drivers requiring refclk from host and drivers getting refclk
locally.

By getting rid of this flag, now both the DWC EP driver and the EPF drivers
can use a single flow and need not distinguish between the glue drivers.

We can also get rid of the 'link_up_notifier' flag in the future by following
the same convention.

Testing
=======

I've tested the series on Qcom SM8450 based dev board that depends on refclk
from host with EPF_MHI driver. It'd be good to test this series on platforms
that generate refclk locally and also with EPF_TEST driver.

- Mani

[1] https://lore.kernel.org/linux-pci/20221013175712.7539-1-vidyas at nvidia.com/
[2] https://lore.kernel.org/linux-pci/20231120084014.108274-1-manivannan.sadhasivam at linaro.org/

Changes in v8:

- Rebased on top of v6.8-rc1
- Removed the deinit callback from struct dw_pcie_ep_ops
- Renamed dw_pcie_ep_exit() to dw_pcie_ep_deinit()
- Introduced dw_pcie_ep_cleanup() API for drivers supporting PERST#
- Renamed dw_pcie_ep_init_complete() to dw_pcie_ep_init_registers()
- Called dw_pcie_ep_init_registers() API directly from all glue drivers
- Removed "core_init_notifier" flag
- Added a generic dw_pcie_ep_linkdown() API to handle LINK_DOWN event and used
  it in qcom driver
- Added Kernel-doc comments for DWC EP APIs

Changes in v7:

- Rebased on top of v6.7-rc1
- Kept the current dw_pcie_ep_init_complete() API instead of renaming it to
  dw_pcie_ep_init_late(), since changing the name causes a slight ambiguity.
- Splitted the change that moves pci_epc_init_notify() inside
  dw_pcie_ep_init_notify() to help bisecting and also to avoid build issue.
- Added a new patch that moves pci_epc_init_notify() inside
  dw_pcie_ep_init_notify().
- Took over the authorship and dropped the previous Ack as the patches are
  heavily modified.

Changes in v6:

- Rebased on top of pci/next (6e2fca71e187)
- removed ep_init_late() callback as it is no longer necessary

For previous changelog, please refer [1].

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
Manivannan Sadhasivam (10):
      PCI: dwc: ep: Remove deinit() callback from struct dw_pcie_ep_ops
      PCI: dwc: ep: Rename dw_pcie_ep_exit() to dw_pcie_ep_deinit()
      PCI: dwc: ep: Introduce dw_pcie_ep_cleanup() API for drivers supporting PERST#
      PCI: dwc: ep: Fix DBI access failure for drivers requiring refclk from host
      PCI: dwc: ep: Rename dw_pcie_ep_init_complete() to dw_pcie_ep_init_registers()
      PCI: dwc: ep: Call dw_pcie_ep_init_registers() API directly from all glue drivers
      PCI: dwc: ep: Remove "core_init_notifier" flag
      PCI: dwc: ep: Add a generic dw_pcie_ep_linkdown() API to handle LINK_DOWN event
      PCI: qcom-ep: Use the generic dw_pcie_ep_linkdown() API to handle LINK_DOWN event
      PCI: dwc: ep: Add Kernel-doc comments for APIs

 drivers/pci/controller/dwc/pci-dra7xx.c           |   9 +
 drivers/pci/controller/dwc/pci-imx6.c             |  10 +
 drivers/pci/controller/dwc/pci-keystone.c         |  11 +
 drivers/pci/controller/dwc/pci-layerscape-ep.c    |   9 +
 drivers/pci/controller/dwc/pcie-designware-ep.c   | 307 +++++++++++++++-------
 drivers/pci/controller/dwc/pcie-designware-plat.c |  11 +
 drivers/pci/controller/dwc/pcie-designware.h      |  19 +-
 drivers/pci/controller/dwc/pcie-qcom-ep.c         |   6 +-
 drivers/pci/controller/dwc/pcie-rcar-gen4.c       |  28 +-
 drivers/pci/controller/dwc/pcie-tegra194.c        |   5 +-
 drivers/pci/controller/dwc/pcie-uniphier-ep.c     |  15 +-
 drivers/pci/endpoint/functions/pci-epf-test.c     |  18 +-
 include/linux/pci-epc.h                           |   3 -
 13 files changed, 321 insertions(+), 130 deletions(-)
---
base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
change-id: 20240224-pci-dbi-rework-b2e99a62930c

Best regards,
-- 
Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>



From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:07 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:07 +0530
Subject: [PATCH v8 01/10] PCI: dwc: ep: Remove deinit() callback from
 struct dw_pcie_ep_ops
In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
Message-ID: <20240224-pci-dbi-rework-v8-1-64c7fd0cfe64@linaro.org>

deinit() callback was solely introduced for the pcie-rcar-gen4 driver where
it is used to do platform specific resource deallocation. And this callback
is called right at the end of the dw_pcie_ep_exit() API. So it doesn't
matter whether it is called within or outside of dw_pcie_ep_exit() API.

So let's remove this callback and directly call rcar_gen4_pcie_ep_deinit()
in pcie-rcar-gen4 driver to do resource deallocation after the completion
of dw_pcie_ep_exit() API in rcar_gen4_remove_dw_pcie_ep().

This simplifies the DWC layer.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pcie-designware-ep.c |  9 +--------
 drivers/pci/controller/dwc/pcie-designware.h    |  1 -
 drivers/pci/controller/dwc/pcie-rcar-gen4.c     | 14 ++++++++------
 3 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 5befed2dc02b..d305f9b4cdfe 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -575,9 +575,6 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
 			      epc->mem->window.page_size);
 
 	pci_epc_mem_exit(epc);
-
-	if (ep->ops->deinit)
-		ep->ops->deinit(ep);
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_exit);
 
@@ -738,7 +735,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 			       ep->page_size);
 	if (ret < 0) {
 		dev_err(dev, "Failed to initialize address space\n");
-		goto err_ep_deinit;
+		return ret;
 	}
 
 	ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
@@ -775,10 +772,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 err_exit_epc_mem:
 	pci_epc_mem_exit(epc);
 
-err_ep_deinit:
-	if (ep->ops->deinit)
-		ep->ops->deinit(ep);
-
 	return ret;
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_init);
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 26dae4837462..ab7431a37209 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -333,7 +333,6 @@ struct dw_pcie_rp {
 struct dw_pcie_ep_ops {
 	void	(*pre_init)(struct dw_pcie_ep *ep);
 	void	(*init)(struct dw_pcie_ep *ep);
-	void	(*deinit)(struct dw_pcie_ep *ep);
 	int	(*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,
 			     unsigned int type, u16 interrupt_num);
 	const struct pci_epc_features* (*get_features)(struct dw_pcie_ep *ep);
diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index e9166619b1f9..ac97d594ea47 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -352,11 +352,8 @@ static void rcar_gen4_pcie_ep_init(struct dw_pcie_ep *ep)
 		dw_pcie_ep_reset_bar(pci, bar);
 }
 
-static void rcar_gen4_pcie_ep_deinit(struct dw_pcie_ep *ep)
+static void rcar_gen4_pcie_ep_deinit(struct rcar_gen4_pcie *rcar)
 {
-	struct dw_pcie *dw = to_dw_pcie_from_ep(ep);
-	struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
-
 	writel(0, rcar->base + PCIEDMAINTSTSEN);
 	rcar_gen4_pcie_common_deinit(rcar);
 }
@@ -408,7 +405,6 @@ static unsigned int rcar_gen4_pcie_ep_get_dbi2_offset(struct dw_pcie_ep *ep,
 static const struct dw_pcie_ep_ops pcie_ep_ops = {
 	.pre_init = rcar_gen4_pcie_ep_pre_init,
 	.init = rcar_gen4_pcie_ep_init,
-	.deinit = rcar_gen4_pcie_ep_deinit,
 	.raise_irq = rcar_gen4_pcie_ep_raise_irq,
 	.get_features = rcar_gen4_pcie_ep_get_features,
 	.get_dbi_offset = rcar_gen4_pcie_ep_get_dbi_offset,
@@ -418,18 +414,24 @@ static const struct dw_pcie_ep_ops pcie_ep_ops = {
 static int rcar_gen4_add_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
 {
 	struct dw_pcie_ep *ep = &rcar->dw.ep;
+	int ret;
 
 	if (!IS_ENABLED(CONFIG_PCIE_RCAR_GEN4_EP))
 		return -ENODEV;
 
 	ep->ops = &pcie_ep_ops;
 
-	return dw_pcie_ep_init(ep);
+	ret = dw_pcie_ep_init(ep);
+	if (ret)
+		rcar_gen4_pcie_ep_deinit(rcar);
+
+	return ret;
 }
 
 static void rcar_gen4_remove_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
 {
 	dw_pcie_ep_exit(&rcar->dw.ep);
+	rcar_gen4_pcie_ep_deinit(rcar);
 }
 
 /* Common */

-- 
2.25.1



From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:08 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:08 +0530
Subject: [PATCH v8 02/10] PCI: dwc: ep: Rename dw_pcie_ep_exit() to
 dw_pcie_ep_deinit()
In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
Message-ID: <20240224-pci-dbi-rework-v8-2-64c7fd0cfe64@linaro.org>

dw_pcie_ep_exit() API is undoing what the dw_pcie_ep_init() API has done
already (at least partly). But the API name dw_pcie_ep_exit() is not quite
reflecting that. So let's rename it to dw_pcie_ep_deinit() to make the
purpose of this API clear. This also aligns with the DWC host driver.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pcie-designware-ep.c | 4 ++--
 drivers/pci/controller/dwc/pcie-designware.h    | 4 ++--
 drivers/pci/controller/dwc/pcie-rcar-gen4.c     | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index d305f9b4cdfe..2b11290aab4c 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -564,7 +564,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 	return 0;
 }
 
-void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
+void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 	struct pci_epc *epc = ep->epc;
@@ -576,7 +576,7 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
 
 	pci_epc_mem_exit(epc);
 }
-EXPORT_SYMBOL_GPL(dw_pcie_ep_exit);
+EXPORT_SYMBOL_GPL(dw_pcie_ep_deinit);
 
 static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
 {
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index ab7431a37209..61465203bb60 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -671,7 +671,7 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
 int dw_pcie_ep_init(struct dw_pcie_ep *ep);
 int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep);
 void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep);
-void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
+void dw_pcie_ep_deinit(struct dw_pcie_ep *ep);
 int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no);
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 			     u8 interrupt_num);
@@ -701,7 +701,7 @@ static inline void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
 {
 }
 
-static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
+static inline void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
 {
 }
 
diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index ac97d594ea47..9d9d22e367bb 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -430,7 +430,7 @@ static int rcar_gen4_add_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
 
 static void rcar_gen4_remove_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
 {
-	dw_pcie_ep_exit(&rcar->dw.ep);
+	dw_pcie_ep_deinit(&rcar->dw.ep);
 	rcar_gen4_pcie_ep_deinit(rcar);
 }
 

-- 
2.25.1



From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:09 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:09 +0530
Subject: [PATCH v8 03/10] PCI: dwc: ep: Introduce dw_pcie_ep_cleanup() API
 for drivers supporting PERST#
In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
Message-ID: <20240224-pci-dbi-rework-v8-3-64c7fd0cfe64@linaro.org>

For DWC glue drivers supporting PERST# (currently Qcom and Tegra194), some
of the DWC resources like eDMA should be cleaned up during the PERST#
assert time.

So let's introduce a dw_pcie_ep_cleanup() API that could be called by these
drivers to cleanup the DWC specific resources. Currently, it just removes
eDMA.

Reported-by: Niklas Cassel <cassel at kernel.org>
Closes: https://lore.kernel.org/linux-pci/ZWYmX8Y%2F7Q9WMxES at x1-carbon
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pcie-designware-ep.c | 11 +++++++++--
 drivers/pci/controller/dwc/pcie-designware.h    |  5 +++++
 drivers/pci/controller/dwc/pcie-qcom-ep.c       |  1 +
 drivers/pci/controller/dwc/pcie-tegra194.c      |  2 ++
 4 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 2b11290aab4c..1205bfba8310 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -564,12 +564,19 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 	return 0;
 }
 
-void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
+void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-	struct pci_epc *epc = ep->epc;
 
 	dw_pcie_edma_remove(pci);
+}
+EXPORT_SYMBOL_GPL(dw_pcie_ep_cleanup);
+
+void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
+{
+	struct pci_epc *epc = ep->epc;
+
+	dw_pcie_ep_cleanup(ep);
 
 	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
 			      epc->mem->window.page_size);
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 61465203bb60..351d2fe3ea4d 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -672,6 +672,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep);
 int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep);
 void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep);
 void dw_pcie_ep_deinit(struct dw_pcie_ep *ep);
+void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep);
 int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no);
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 			     u8 interrupt_num);
@@ -705,6 +706,10 @@ static inline void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
 {
 }
 
+static inline void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
+{
+}
+
 static inline int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no)
 {
 	return 0;
diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 36e5e80cd22f..59b1c0110288 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -507,6 +507,7 @@ static void qcom_pcie_perst_assert(struct dw_pcie *pci)
 		return;
 	}
 
+	dw_pcie_ep_cleanup(&pci->ep);
 	qcom_pcie_disable_resources(pcie_ep);
 	pcie_ep->link_status = QCOM_PCIE_EP_LINK_DISABLED;
 }
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 7afa9e9aabe2..68bfeed3429b 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -1715,6 +1715,8 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie)
 	if (ret)
 		dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret);
 
+	dw_pcie_ep_cleanup(&pcie->pci.ep);
+
 	reset_control_assert(pcie->core_rst);
 
 	tegra_pcie_disable_phy(pcie);

-- 
2.25.1



From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:10 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:10 +0530
Subject: [PATCH v8 04/10] PCI: dwc: ep: Fix DBI access failure for drivers
 requiring refclk from host
In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
Message-ID: <20240224-pci-dbi-rework-v8-4-64c7fd0cfe64@linaro.org>

The DWC glue drivers requiring an active reference clock from the PCIe host
for initializing their PCIe EP core, set a flag called 'core_init_notifier'
to let DWC driver know that these drivers need a special attention during
initialization. In these drivers, access to the hw registers (like DBI)
before receiving the active refclk from host will result in access failure
and also could cause a whole system hang.

But the current DWC EP driver doesn't honor the requirements of the drivers
setting 'core_init_notifier' flag and tries to access the DBI registers
during dw_pcie_ep_init(). This causes the system hang for glue drivers such
as Tegra194 and Qcom EP as they depend on refclk from host and have set the
above mentioned flag.

To workaround this issue, users of the affected platforms have to maintain
the dependency with the PCIe host by booting the PCIe EP after host boot.
But this won't provide a good user experience, since PCIe EP is _one_ of
the features of those platforms and it doesn't make sense to delay the
whole platform booting due to PCIe requiring active refclk.

So to fix this issue, let's move all the DBI access from
dw_pcie_ep_init() in the DWC EP driver to the dw_pcie_ep_init_complete()
API. This API will only be called by the drivers setting
'core_init_notifier' flag once refclk is received from host. For the rest
of the drivers that gets the refclk locally, this API will be called
within dw_pcie_ep_init().

Fixes: e966f7390da9 ("PCI: dwc: Refactor core initialization code for EP mode")
Co-developed-by: Vidya Sagar <vidyas at nvidia.com>
Signed-off-by: Vidya Sagar <vidyas at nvidia.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pcie-designware-ep.c | 120 ++++++++++++++----------
 1 file changed, 71 insertions(+), 49 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 1205bfba8310..99d66b0fa59b 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -606,11 +606,16 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
 int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct dw_pcie_ep_func *ep_func;
+	struct device *dev = pci->dev;
+	struct pci_epc *epc = ep->epc;
 	unsigned int offset, ptm_cap_base;
 	unsigned int nbars;
 	u8 hdr_type;
+	u8 func_no;
+	int i, ret;
+	void *addr;
 	u32 reg;
-	int i;
 
 	hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) &
 		   PCI_HEADER_TYPE_MASK;
@@ -621,6 +626,58 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
 		return -EIO;
 	}
 
+	dw_pcie_version_detect(pci);
+
+	dw_pcie_iatu_detect(pci);
+
+	ret = dw_pcie_edma_detect(pci);
+	if (ret)
+		return ret;
+
+	if (!ep->ib_window_map) {
+		ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows,
+						       GFP_KERNEL);
+		if (!ep->ib_window_map)
+			goto err_remove_edma;
+	}
+
+	if (!ep->ob_window_map) {
+		ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows,
+						       GFP_KERNEL);
+		if (!ep->ob_window_map)
+			goto err_remove_edma;
+	}
+
+	if (!ep->outbound_addr) {
+		addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t),
+				    GFP_KERNEL);
+		if (!addr)
+			goto err_remove_edma;
+		ep->outbound_addr = addr;
+	}
+
+	for (func_no = 0; func_no < epc->max_functions; func_no++) {
+
+		ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no);
+		if (ep_func)
+			continue;
+
+		ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL);
+		if (!ep_func)
+			goto err_remove_edma;
+
+		ep_func->func_no = func_no;
+		ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no,
+							      PCI_CAP_ID_MSI);
+		ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no,
+							       PCI_CAP_ID_MSIX);
+
+		list_add_tail(&ep_func->list, &ep->func_list);
+	}
+
+	if (ep->ops->init)
+		ep->ops->init(ep);
+
 	offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
 	ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
 
@@ -655,14 +712,17 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
 	dw_pcie_dbi_ro_wr_dis(pci);
 
 	return 0;
+
+err_remove_edma:
+	dw_pcie_edma_remove(pci);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete);
 
 int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 {
 	int ret;
-	void *addr;
-	u8 func_no;
 	struct resource *res;
 	struct pci_epc *epc;
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -670,7 +730,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *np = dev->of_node;
 	const struct pci_epc_features *epc_features;
-	struct dw_pcie_ep_func *ep_func;
 
 	INIT_LIST_HEAD(&ep->func_list);
 
@@ -688,26 +747,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	if (ep->ops->pre_init)
 		ep->ops->pre_init(ep);
 
-	dw_pcie_version_detect(pci);
-
-	dw_pcie_iatu_detect(pci);
-
-	ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows,
-					       GFP_KERNEL);
-	if (!ep->ib_window_map)
-		return -ENOMEM;
-
-	ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows,
-					       GFP_KERNEL);
-	if (!ep->ob_window_map)
-		return -ENOMEM;
-
-	addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t),
-			    GFP_KERNEL);
-	if (!addr)
-		return -ENOMEM;
-	ep->outbound_addr = addr;
-
 	epc = devm_pci_epc_create(dev, &epc_ops);
 	if (IS_ERR(epc)) {
 		dev_err(dev, "Failed to create epc device\n");
@@ -721,23 +760,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	if (ret < 0)
 		epc->max_functions = 1;
 
-	for (func_no = 0; func_no < epc->max_functions; func_no++) {
-		ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL);
-		if (!ep_func)
-			return -ENOMEM;
-
-		ep_func->func_no = func_no;
-		ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no,
-							      PCI_CAP_ID_MSI);
-		ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no,
-							       PCI_CAP_ID_MSIX);
-
-		list_add_tail(&ep_func->list, &ep->func_list);
-	}
-
-	if (ep->ops->init)
-		ep->ops->init(ep);
-
 	ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
 			       ep->page_size);
 	if (ret < 0) {
@@ -753,25 +775,25 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 		goto err_exit_epc_mem;
 	}
 
-	ret = dw_pcie_edma_detect(pci);
-	if (ret)
-		goto err_free_epc_mem;
-
 	if (ep->ops->get_features) {
 		epc_features = ep->ops->get_features(ep);
 		if (epc_features->core_init_notifier)
 			return 0;
 	}
 
+	/*
+	 * NOTE:- Avoid accessing the hardware (Ex:- DBI space) before this
+	 * step as platforms that implement 'core_init_notifier' feature may
+	 * not have the hardware ready (i.e. core initialized) for access
+	 * (Ex: tegra194). Any hardware access on such platforms result
+	 * in system hang.
+	 */
 	ret = dw_pcie_ep_init_complete(ep);
 	if (ret)
-		goto err_remove_edma;
+		goto err_free_epc_mem;
 
 	return 0;
 
-err_remove_edma:
-	dw_pcie_edma_remove(pci);
-
 err_free_epc_mem:
 	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
 			      epc->mem->window.page_size);

-- 
2.25.1



From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:11 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:11 +0530
Subject: [PATCH v8 05/10] PCI: dwc: ep: Rename dw_pcie_ep_init_complete()
 to dw_pcie_ep_init_registers()
In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
Message-ID: <20240224-pci-dbi-rework-v8-5-64c7fd0cfe64@linaro.org>

The goal of the dw_pcie_ep_init_complete() API is to initialize the DWC
specific registers post registering the controller with the EP framework.

But the naming doesn't reflect its functionality and causes confusion. So,
let's rename it to dw_pcie_ep_init_registers() to make it clear that it
initializes the DWC specific registers.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pcie-designware-ep.c | 6 +++---
 drivers/pci/controller/dwc/pcie-designware.h    | 4 ++--
 drivers/pci/controller/dwc/pcie-qcom-ep.c       | 2 +-
 drivers/pci/controller/dwc/pcie-tegra194.c      | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 99d66b0fa59b..ed1f2afd830a 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -603,7 +603,7 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
 	return 0;
 }
 
-int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
+int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 	struct dw_pcie_ep_func *ep_func;
@@ -718,7 +718,7 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete);
+EXPORT_SYMBOL_GPL(dw_pcie_ep_init_registers);
 
 int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 {
@@ -788,7 +788,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	 * (Ex: tegra194). Any hardware access on such platforms result
 	 * in system hang.
 	 */
-	ret = dw_pcie_ep_init_complete(ep);
+	ret = dw_pcie_ep_init_registers(ep);
 	if (ret)
 		goto err_free_epc_mem;
 
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 351d2fe3ea4d..f8e5431a207b 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -669,7 +669,7 @@ static inline void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus,
 #ifdef CONFIG_PCIE_DW_EP
 void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
 int dw_pcie_ep_init(struct dw_pcie_ep *ep);
-int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep);
+int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep);
 void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep);
 void dw_pcie_ep_deinit(struct dw_pcie_ep *ep);
 void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep);
@@ -693,7 +693,7 @@ static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	return 0;
 }
 
-static inline int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
+static inline int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
 {
 	return 0;
 }
diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 59b1c0110288..3697b4a944cc 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -463,7 +463,7 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
 	      PARF_INT_ALL_LINK_UP | PARF_INT_ALL_EDMA;
 	writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_MASK);
 
-	ret = dw_pcie_ep_init_complete(&pcie_ep->pci.ep);
+	ret = dw_pcie_ep_init_registers(&pcie_ep->pci.ep);
 	if (ret) {
 		dev_err(dev, "Failed to complete initialization: %d\n", ret);
 		goto err_disable_resources;
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 68bfeed3429b..264ee76bf008 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -1897,7 +1897,7 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)
 	val = (upper_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK);
 	dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_HIGH_OFF, val);
 
-	ret = dw_pcie_ep_init_complete(ep);
+	ret = dw_pcie_ep_init_registers(ep);
 	if (ret) {
 		dev_err(dev, "Failed to complete initialization: %d\n", ret);
 		goto fail_init_complete;

-- 
2.25.1



From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:12 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:12 +0530
Subject: [PATCH v8 06/10] PCI: dwc: ep: Call dw_pcie_ep_init_registers()
 API directly from all glue drivers
In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
Message-ID: <20240224-pci-dbi-rework-v8-6-64c7fd0cfe64@linaro.org>

Currently, dw_pcie_ep_init_registers() API is directly called by the glue
drivers requiring active refclk from host. But for the other drivers, it is
getting called implicitly by dw_pcie_ep_init(). This is due to the fact
that this API initializes DWC EP specific registers and that requires an
active refclk (either from host or generated locally by endpoint itsef).

But, this causes a discrepancy among the glue drivers. So to avoid this
confusion, let's call this API directly from all glue drivers irrespective
of refclk dependency. Only difference here is that the drivers requiring
refclk from host will call this API only after the refclk is received and
other drivers without refclk dependency will call this API right after
dw_pcie_ep_init().

This change will also allow us to remove the "core_init_notifier" flag in
the later commits.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pci-dra7xx.c           |  7 +++++++
 drivers/pci/controller/dwc/pci-imx6.c             |  8 ++++++++
 drivers/pci/controller/dwc/pci-keystone.c         |  9 +++++++++
 drivers/pci/controller/dwc/pci-layerscape-ep.c    |  7 +++++++
 drivers/pci/controller/dwc/pcie-designware-ep.c   | 22 ----------------------
 drivers/pci/controller/dwc/pcie-designware-plat.c |  9 +++++++++
 drivers/pci/controller/dwc/pcie-rcar-gen4.c       | 12 +++++++++++-
 drivers/pci/controller/dwc/pcie-uniphier-ep.c     | 13 ++++++++++++-
 8 files changed, 63 insertions(+), 24 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index 0e406677060d..395042b29ffc 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -467,6 +467,13 @@ static int dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
 		return ret;
 	}
 
+	ret = dw_pcie_ep_init_registers(ep);
+	if (ret) {
+		dev_err(dev, "Failed to initialize DWC endpoint registers\n");
+		dw_pcie_ep_deinit(ep);
+		return ret;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index dc2c036ab28c..bfcafa440ddb 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1136,6 +1136,14 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
 		dev_err(dev, "failed to initialize endpoint\n");
 		return ret;
 	}
+
+	ret = dw_pcie_ep_init_registers(ep);
+	if (ret) {
+		dev_err(dev, "Failed to initialize DWC endpoint registers\n");
+		dw_pcie_ep_deinit(ep);
+		return ret;
+	}
+
 	/* Start LTSSM. */
 	imx6_pcie_ltssm_enable(dev);
 
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index c0c62533a3f1..8392894ed286 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -1286,6 +1286,13 @@ static int ks_pcie_probe(struct platform_device *pdev)
 		ret = dw_pcie_ep_init(&pci->ep);
 		if (ret < 0)
 			goto err_get_sync;
+
+		ret = dw_pcie_ep_init_registers(&pci->ep);
+		if (ret < 0) {
+			dev_err(dev, "Failed to initialize DWC endpoint registers\n");
+			goto err_ep_init;
+		}
+
 		break;
 	default:
 		dev_err(dev, "INVALID device type %d\n", mode);
@@ -1295,6 +1302,8 @@ static int ks_pcie_probe(struct platform_device *pdev)
 
 	return 0;
 
+err_ep_init:
+	dw_pcie_ep_deinit(&pci->ep);
 err_get_sync:
 	pm_runtime_put(dev);
 	pm_runtime_disable(dev);
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index 2e398494e7c0..b712fdd06549 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -276,6 +276,13 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = dw_pcie_ep_init_registers(&pci->ep);
+	if (ret) {
+		dev_err(dev, "Failed to initialize DWC endpoint registers\n");
+		dw_pcie_ep_deinit(&pci->ep);
+		return ret;
+	}
+
 	return ls_pcie_ep_interrupt_init(pcie, pdev);
 }
 
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index ed1f2afd830a..278bdc9b2269 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -729,7 +729,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	struct device *dev = pci->dev;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *np = dev->of_node;
-	const struct pci_epc_features *epc_features;
 
 	INIT_LIST_HEAD(&ep->func_list);
 
@@ -775,29 +774,8 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 		goto err_exit_epc_mem;
 	}
 
-	if (ep->ops->get_features) {
-		epc_features = ep->ops->get_features(ep);
-		if (epc_features->core_init_notifier)
-			return 0;
-	}
-
-	/*
-	 * NOTE:- Avoid accessing the hardware (Ex:- DBI space) before this
-	 * step as platforms that implement 'core_init_notifier' feature may
-	 * not have the hardware ready (i.e. core initialized) for access
-	 * (Ex: tegra194). Any hardware access on such platforms result
-	 * in system hang.
-	 */
-	ret = dw_pcie_ep_init_registers(ep);
-	if (ret)
-		goto err_free_epc_mem;
-
 	return 0;
 
-err_free_epc_mem:
-	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
-			      epc->mem->window.page_size);
-
 err_exit_epc_mem:
 	pci_epc_mem_exit(epc);
 
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
index 778588b4be70..ca9b22e654cd 100644
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -145,6 +145,15 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
 
 		pci->ep.ops = &pcie_ep_ops;
 		ret = dw_pcie_ep_init(&pci->ep);
+		if (ret)
+			return ret;
+
+		ret = dw_pcie_ep_init_registers(&pci->ep);
+		if (ret) {
+			dev_err(dev, "Failed to initialize DWC endpoint registers\n");
+			dw_pcie_ep_deinit(&pci->ep);
+		}
+
 		break;
 	default:
 		dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->mode);
diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index 9d9d22e367bb..fb7c03639a53 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -414,6 +414,7 @@ static const struct dw_pcie_ep_ops pcie_ep_ops = {
 static int rcar_gen4_add_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
 {
 	struct dw_pcie_ep *ep = &rcar->dw.ep;
+	struct device *dev = rcar->dw.dev;
 	int ret;
 
 	if (!IS_ENABLED(CONFIG_PCIE_RCAR_GEN4_EP))
@@ -422,8 +423,17 @@ static int rcar_gen4_add_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
 	ep->ops = &pcie_ep_ops;
 
 	ret = dw_pcie_ep_init(ep);
-	if (ret)
+	if (ret) {
 		rcar_gen4_pcie_ep_deinit(rcar);
+		return ret;
+	}
+
+	ret = dw_pcie_ep_init_registers(ep);
+	if (ret) {
+		dev_err(dev, "Failed to initialize DWC endpoint registers\n");
+		dw_pcie_ep_deinit(ep);
+		rcar_gen4_pcie_ep_deinit(rcar);
+	}
 
 	return ret;
 }
diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
index 3fced0d3e851..82ccaea089be 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
@@ -399,7 +399,18 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
 		return ret;
 
 	priv->pci.ep.ops = &uniphier_pcie_ep_ops;
-	return dw_pcie_ep_init(&priv->pci.ep);
+	ret = dw_pcie_ep_init(&priv->pci.ep);
+	if (ret)
+		return ret;
+
+	ret = dw_pcie_ep_init_registers(&priv->pci.ep);
+	if (ret) {
+		dev_err(dev, "Failed to initialize DWC endpoint registers\n");
+		dw_pcie_ep_deinit(&priv->pci.ep);
+		return ret;
+	}
+
+	return 0;
 }
 
 static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = {

-- 
2.25.1



From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:13 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:13 +0530
Subject: [PATCH v8 07/10] PCI: dwc: ep: Remove "core_init_notifier" flag
In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
Message-ID: <20240224-pci-dbi-rework-v8-7-64c7fd0cfe64@linaro.org>

"core_init_notifier" flag is set by the glue drivers requiring refclk from
the host to complete the DWC core initialization. Also, those drivers will
send a notification to the EPF drivers once the initialization is fully
completed using the pci_epc_init_notify() API. Only then, the EPF drivers
will start functioning.

For the rest of the drivers generating refclk locally, EPF drivers will
start functioning post binding with them. EPF drivers rely on the
'core_init_notifier' flag to differentiate between the drivers.
Unfortunately, this creates two different flows for the EPF drivers.

So to avoid that, let's get rid of the "core_init_notifier" flag and follow
a single initialization flow for the EPF drivers. This is done by calling
the dw_pcie_ep_init_notify() from all glue drivers after the completion of
dw_pcie_ep_init_registers() API. This will allow all the glue drivers to
send the notification to the EPF drivers once the initialization is fully
completed.

Only difference here is that, the drivers requiring refclk from host will
send the notification once refclk is received, while others will send it
during probe time itself.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pci-dra7xx.c           |  2 ++
 drivers/pci/controller/dwc/pci-imx6.c             |  2 ++
 drivers/pci/controller/dwc/pci-keystone.c         |  2 ++
 drivers/pci/controller/dwc/pci-layerscape-ep.c    |  2 ++
 drivers/pci/controller/dwc/pcie-designware-plat.c |  2 ++
 drivers/pci/controller/dwc/pcie-qcom-ep.c         |  1 -
 drivers/pci/controller/dwc/pcie-rcar-gen4.c       |  2 ++
 drivers/pci/controller/dwc/pcie-tegra194.c        |  1 -
 drivers/pci/controller/dwc/pcie-uniphier-ep.c     |  2 ++
 drivers/pci/endpoint/functions/pci-epf-test.c     | 18 +++++-------------
 include/linux/pci-epc.h                           |  3 ---
 11 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index 395042b29ffc..d2d17d37d3e0 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -474,6 +474,8 @@ static int dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
 		return ret;
 	}
 
+	dw_pcie_ep_init_notify(ep);
+
 	return 0;
 }
 
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index bfcafa440ddb..894b5de76e3a 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1144,6 +1144,8 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
 		return ret;
 	}
 
+	dw_pcie_ep_init_notify(ep);
+
 	/* Start LTSSM. */
 	imx6_pcie_ltssm_enable(dev);
 
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index 8392894ed286..1d00c5fa14ce 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -1293,6 +1293,8 @@ static int ks_pcie_probe(struct platform_device *pdev)
 			goto err_ep_init;
 		}
 
+		dw_pcie_ep_init_notify(&pci->ep);
+
 		break;
 	default:
 		dev_err(dev, "INVALID device type %d\n", mode);
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index b712fdd06549..c513598a46d7 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -283,6 +283,8 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	dw_pcie_ep_init_notify(&pci->ep);
+
 	return ls_pcie_ep_interrupt_init(pcie, pdev);
 }
 
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
index ca9b22e654cd..8490c5d6ff9f 100644
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -154,6 +154,8 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
 			dw_pcie_ep_deinit(&pci->ep);
 		}
 
+		dw_pcie_ep_init_notify(&pci->ep);
+
 		break;
 	default:
 		dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->mode);
diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 3697b4a944cc..2fb8c15e7a91 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -775,7 +775,6 @@ static void qcom_pcie_ep_init_debugfs(struct qcom_pcie_ep *pcie_ep)
 
 static const struct pci_epc_features qcom_pcie_epc_features = {
 	.linkup_notifier = true,
-	.core_init_notifier = true,
 	.msi_capable = true,
 	.msix_capable = false,
 	.align = SZ_4K,
diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index fb7c03639a53..0448928017f3 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -435,6 +435,8 @@ static int rcar_gen4_add_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
 		rcar_gen4_pcie_ep_deinit(rcar);
 	}
 
+	dw_pcie_ep_init_notify(ep);
+
 	return ret;
 }
 
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 264ee76bf008..e02deb31a72d 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -2006,7 +2006,6 @@ static int tegra_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
 
 static const struct pci_epc_features tegra_pcie_epc_features = {
 	.linkup_notifier = true,
-	.core_init_notifier = true,
 	.msi_capable = false,
 	.msix_capable = false,
 	.reserved_bar = 1 << BAR_2 | 1 << BAR_3 | 1 << BAR_4 | 1 << BAR_5,
diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
index 82ccaea089be..eb1d79fdb1f1 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
@@ -410,6 +410,8 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	dw_pcie_ep_init_notify(&priv->pci.ep);
+
 	return 0;
 }
 
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 18c80002d3bd..fc0282b0d626 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -753,6 +753,7 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 	const struct pci_epc_features *epc_features;
 	struct pci_epc *epc = epf->epc;
 	struct device *dev = &epf->dev;
+	bool linkup_notifier = false;
 	bool msix_capable = false;
 	bool msi_capable = true;
 	int ret;
@@ -795,6 +796,10 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 		}
 	}
 
+	linkup_notifier = epc_features->linkup_notifier;
+	if (!linkup_notifier)
+		queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);
+
 	return 0;
 }
 
@@ -901,8 +906,6 @@ static int pci_epf_test_bind(struct pci_epf *epf)
 	const struct pci_epc_features *epc_features;
 	enum pci_barno test_reg_bar = BAR_0;
 	struct pci_epc *epc = epf->epc;
-	bool linkup_notifier = false;
-	bool core_init_notifier = false;
 
 	if (WARN_ON_ONCE(!epc))
 		return -EINVAL;
@@ -913,8 +916,6 @@ static int pci_epf_test_bind(struct pci_epf *epf)
 		return -EOPNOTSUPP;
 	}
 
-	linkup_notifier = epc_features->linkup_notifier;
-	core_init_notifier = epc_features->core_init_notifier;
 	test_reg_bar = pci_epc_get_first_free_bar(epc_features);
 	if (test_reg_bar < 0)
 		return -EINVAL;
@@ -927,21 +928,12 @@ static int pci_epf_test_bind(struct pci_epf *epf)
 	if (ret)
 		return ret;
 
-	if (!core_init_notifier) {
-		ret = pci_epf_test_core_init(epf);
-		if (ret)
-			return ret;
-	}
-
 	epf_test->dma_supported = true;
 
 	ret = pci_epf_test_init_dma_chan(epf_test);
 	if (ret)
 		epf_test->dma_supported = false;
 
-	if (!linkup_notifier && !core_init_notifier)
-		queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);
-
 	return 0;
 }
 
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 40ea18f5aa02..03d22aed5ac6 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -148,8 +148,6 @@ struct pci_epc {
 /**
  * struct pci_epc_features - features supported by a EPC device per function
  * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up
- * @core_init_notifier: indicate cores that can notify about their availability
- *			for initialization
  * @msi_capable: indicate if the endpoint function has MSI capability
  * @msix_capable: indicate if the endpoint function has MSI-X capability
  * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver
@@ -159,7 +157,6 @@ struct pci_epc {
  */
 struct pci_epc_features {
 	unsigned int	linkup_notifier : 1;
-	unsigned int	core_init_notifier : 1;
 	unsigned int	msi_capable : 1;
 	unsigned int	msix_capable : 1;
 	u8	reserved_bar;

-- 
2.25.1



From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:14 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:14 +0530
Subject: [PATCH v8 08/10] PCI: dwc: ep: Add a generic dw_pcie_ep_linkdown()
 API to handle LINK_DOWN event
In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
Message-ID: <20240224-pci-dbi-rework-v8-8-64c7fd0cfe64@linaro.org>

The PCIe link can go to LINK_DOWN state in one of the following scenarios:

1. Fundamental (PERST#)/hot/warm reset
2. Link transition from L2/L3 to L0

In those cases, LINK_DOWN causes some non-sticky DWC registers to loose the
state (like REBAR, PTM_CAP etc...). So the drivers need to reinitialize
them to function properly once the link comes back again.

This is not a problem for drivers supporting PERST# IRQ, since they can
reinitialize the registers in the PERST# IRQ callback. But for the drivers
not supporting PERST#, there is no way they can reinitialize the registers
other than relying on LINK_DOWN IRQ received when the link goes down. So
let's add a DWC generic API dw_pcie_ep_linkdown() that reinitializes the
non-sticky registers and also notifies the EPF drivers about link going
down.

This API can also be used by the drivers supporting PERST# to handle the
scenario (2) mentioned above.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pcie-designware-ep.c | 111 ++++++++++++++----------
 drivers/pci/controller/dwc/pcie-designware.h    |   5 ++
 2 files changed, 72 insertions(+), 44 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 278bdc9b2269..fed4c2936c78 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -14,14 +14,6 @@
 #include <linux/pci-epc.h>
 #include <linux/pci-epf.h>
 
-void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
-{
-	struct pci_epc *epc = ep->epc;
-
-	pci_epc_linkup(epc);
-}
-EXPORT_SYMBOL_GPL(dw_pcie_ep_linkup);
-
 void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
 {
 	struct pci_epc *epc = ep->epc;
@@ -603,19 +595,56 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
 	return 0;
 }
 
+static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
+{
+	unsigned int offset, ptm_cap_base;
+	unsigned int nbars;
+	u32 reg, i;
+
+	offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
+	ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
+
+	dw_pcie_dbi_ro_wr_en(pci);
+
+	if (offset) {
+		reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
+		nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
+			PCI_REBAR_CTRL_NBAR_SHIFT;
+
+		for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL)
+			dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0);
+	}
+
+	/*
+	 * PTM responder capability can be disabled only after disabling
+	 * PTM root capability.
+	 */
+	if (ptm_cap_base) {
+		dw_pcie_dbi_ro_wr_en(pci);
+		reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP);
+		reg &= ~PCI_PTM_CAP_ROOT;
+		dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg);
+
+		reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP);
+		reg &= ~(PCI_PTM_CAP_RES | PCI_PTM_GRANULARITY_MASK);
+		dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg);
+		dw_pcie_dbi_ro_wr_dis(pci);
+	}
+
+	dw_pcie_setup(pci);
+	dw_pcie_dbi_ro_wr_dis(pci);
+}
+
 int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 	struct dw_pcie_ep_func *ep_func;
 	struct device *dev = pci->dev;
 	struct pci_epc *epc = ep->epc;
-	unsigned int offset, ptm_cap_base;
-	unsigned int nbars;
 	u8 hdr_type;
 	u8 func_no;
-	int i, ret;
 	void *addr;
-	u32 reg;
+	int ret;
 
 	hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) &
 		   PCI_HEADER_TYPE_MASK;
@@ -678,38 +707,7 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
 	if (ep->ops->init)
 		ep->ops->init(ep);
 
-	offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR);
-	ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
-
-	dw_pcie_dbi_ro_wr_en(pci);
-
-	if (offset) {
-		reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL);
-		nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
-			PCI_REBAR_CTRL_NBAR_SHIFT;
-
-		for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL)
-			dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0);
-	}
-
-	/*
-	 * PTM responder capability can be disabled only after disabling
-	 * PTM root capability.
-	 */
-	if (ptm_cap_base) {
-		dw_pcie_dbi_ro_wr_en(pci);
-		reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP);
-		reg &= ~PCI_PTM_CAP_ROOT;
-		dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg);
-
-		reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP);
-		reg &= ~(PCI_PTM_CAP_RES | PCI_PTM_GRANULARITY_MASK);
-		dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg);
-		dw_pcie_dbi_ro_wr_dis(pci);
-	}
-
-	dw_pcie_setup(pci);
-	dw_pcie_dbi_ro_wr_dis(pci);
+	dw_pcie_ep_init_non_sticky_registers(pci);
 
 	return 0;
 
@@ -720,6 +718,31 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_init_registers);
 
+void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
+{
+	struct pci_epc *epc = ep->epc;
+
+	pci_epc_linkup(epc);
+}
+EXPORT_SYMBOL_GPL(dw_pcie_ep_linkup);
+
+void dw_pcie_ep_linkdown(struct dw_pcie_ep *ep)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct pci_epc *epc = ep->epc;
+
+	/*
+	 * Initialize the non-sticky DWC registers as they would've reset post
+	 * LINK_DOWN. This is specifically needed for drivers not supporting
+	 * PERST# as they have no way to reinitialize the registers before the
+	 * link comes back again.
+	 */
+	dw_pcie_ep_init_non_sticky_registers(pci);
+
+	pci_epc_linkdown(epc);
+}
+EXPORT_SYMBOL_GPL(dw_pcie_ep_linkdown);
+
 int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 {
 	int ret;
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index f8e5431a207b..152969545b0a 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -668,6 +668,7 @@ static inline void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus,
 
 #ifdef CONFIG_PCIE_DW_EP
 void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
+void dw_pcie_ep_linkdown(struct dw_pcie_ep *ep);
 int dw_pcie_ep_init(struct dw_pcie_ep *ep);
 int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep);
 void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep);
@@ -688,6 +689,10 @@ static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
 {
 }
 
+static inline void dw_pcie_ep_linkdown(struct dw_pcie_ep *ep)
+{
+}
+
 static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 {
 	return 0;

-- 
2.25.1



From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:15 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:15 +0530
Subject: [PATCH v8 09/10] PCI: qcom-ep: Use the generic
 dw_pcie_ep_linkdown() API to handle LINK_DOWN event
In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
Message-ID: <20240224-pci-dbi-rework-v8-9-64c7fd0cfe64@linaro.org>

Now that the API is available, let's make use of it. It also handles the
reinitialization of DWC non-sticky registers in addition to sending the
notification to EPF drivers.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pcie-qcom-ep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 2fb8c15e7a91..4e45bc4bca45 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -640,7 +640,7 @@ static irqreturn_t qcom_pcie_ep_global_irq_thread(int irq, void *data)
 	if (FIELD_GET(PARF_INT_ALL_LINK_DOWN, status)) {
 		dev_dbg(dev, "Received Linkdown event\n");
 		pcie_ep->link_status = QCOM_PCIE_EP_LINK_DOWN;
-		pci_epc_linkdown(pci->ep.epc);
+		dw_pcie_ep_linkdown(&pci->ep);
 	} else if (FIELD_GET(PARF_INT_ALL_BME, status)) {
 		dev_dbg(dev, "Received BME event. Link is enabled!\n");
 		pcie_ep->link_status = QCOM_PCIE_EP_LINK_ENABLED;

-- 
2.25.1



From manivannan.sadhasivam at linaro.org  Fri Feb 23 22:54:16 2024
From: manivannan.sadhasivam at linaro.org (Manivannan Sadhasivam)
Date: Sat, 24 Feb 2024 12:24:16 +0530
Subject: [PATCH v8 10/10] PCI: dwc: ep: Add Kernel-doc comments for APIs
In-Reply-To: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
References: <20240224-pci-dbi-rework-v8-0-64c7fd0cfe64@linaro.org>
Message-ID: <20240224-pci-dbi-rework-v8-10-64c7fd0cfe64@linaro.org>

All of the APIs are missing the Kernel-doc comments. Hence, add them.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
---
 drivers/pci/controller/dwc/pcie-designware-ep.c | 92 +++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index fed4c2936c78..cdcb33a279db 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -14,6 +14,11 @@
 #include <linux/pci-epc.h>
 #include <linux/pci-epf.h>
 
+/**
+ * dw_pcie_ep_init_notify - Notify EPF drivers about EPC initialization
+ *			    complete
+ * @ep: DWC EP device
+ */
 void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
 {
 	struct pci_epc *epc = ep->epc;
@@ -22,6 +27,14 @@ void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_init_notify);
 
+/**
+ * dw_pcie_ep_get_func_from_ep - Get the struct dw_pcie_ep_func corresponding to
+ *				 the endpoint function
+ * @ep: DWC EP device
+ * @func_no: Function number of the endpoint device
+ *
+ * Return: struct dw_pcie_ep_func if success, NULL otherwise.
+ */
 struct dw_pcie_ep_func *
 dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)
 {
@@ -52,6 +65,11 @@ static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no,
 	dw_pcie_dbi_ro_wr_dis(pci);
 }
 
+/**
+ * dw_pcie_ep_reset_bar - Reset endpoint BAR
+ * @pci: DWC PCI device
+ * @bar: BAR number of the endpoint
+ */
 void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
 {
 	u8 func_no, funcs;
@@ -431,6 +449,13 @@ static const struct pci_epc_ops epc_ops = {
 	.get_features		= dw_pcie_ep_get_features,
 };
 
+/**
+ * dw_pcie_ep_raise_intx_irq - Raise INTx IRQ to the host
+ * @ep: DWC EP device
+ * @func_no: Function number of the endpoint
+ *
+ * Return: 0 if success, errono otherwise.
+ */
 int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -442,6 +467,14 @@ int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no)
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_intx_irq);
 
+/**
+ * dw_pcie_ep_raise_msi_irq - Raise MSI IRQ to the host
+ * @ep: DWC EP device
+ * @func_no: Function number of the endpoint
+ * @interrupt_num: Interrupt number to be raised
+ *
+ * Return: 0 if success, errono otherwise.
+ */
 int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 			     u8 interrupt_num)
 {
@@ -490,6 +523,15 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_msi_irq);
 
+/**
+ * dw_pcie_ep_raise_msix_irq_doorbell - Raise MSIX to the host using Doorbell
+ *					method
+ * @ep: DWC EP device
+ * @func_no: Function number of the endpoint device
+ * @interrupt_num: Interrupt number to be raised
+ *
+ * Return: 0 if success, errno otherwise.
+ */
 int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
 				       u16 interrupt_num)
 {
@@ -509,6 +551,14 @@ int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
 	return 0;
 }
 
+/**
+ * dw_pcie_ep_raise_msix_irq - Raise MSIX to the host
+ * @ep: DWC EP device
+ * @func_no: Function number of the endpoint device
+ * @interrupt_num: Interrupt number to be raised
+ *
+ * Return: 0 if success, errno otherwise.
+ */
 int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 			      u16 interrupt_num)
 {
@@ -556,6 +606,12 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 	return 0;
 }
 
+/**
+ * dw_pcie_ep_cleanup - Cleanup DWC EP resources
+ * @ep: DWC EP device
+ *
+ * Cleans up the DWC EP specific resources like eDMA etc...
+ */
 void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -564,6 +620,13 @@ void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_cleanup);
 
+/**
+ * dw_pcie_ep_deinit - Deinitialize the endpoint device
+ * @ep: DWC EP device
+ *
+ * Deinitialize the endpoint device. EPC device is not destroyed since that will
+ * taken care by Devres.
+ */
 void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
 {
 	struct pci_epc *epc = ep->epc;
@@ -635,6 +698,14 @@ static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
 	dw_pcie_dbi_ro_wr_dis(pci);
 }
 
+/**
+ * dw_pcie_ep_init_registers - Initialize DWC EP specific registers
+ * @ep: DWC EP device
+ *
+ * Initialize the registers (CSRs) specific to DWC EP. This API should be called
+ * only when the endpoint receives an active refclk (either from host or
+ * generated locally).
+ */
 int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -718,6 +789,10 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_init_registers);
 
+/**
+ * dw_pcie_ep_linkup - Notify EPF drivers about link up event
+ * @ep: DWC EP device
+ */
 void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
 {
 	struct pci_epc *epc = ep->epc;
@@ -726,6 +801,14 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_linkup);
 
+/**
+ * dw_pcie_ep_linkdown - Notify EPF drivers about link down event
+ * @ep: DWC EP device
+ *
+ * Non-sticky registers are also initialized before sending the notification to
+ * the EPF drivers. This is needed since the registers need to be initialized
+ * before the link comes back again.
+ */
 void dw_pcie_ep_linkdown(struct dw_pcie_ep *ep)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -743,6 +826,15 @@ void dw_pcie_ep_linkdown(struct dw_pcie_ep *ep)
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_linkdown);
 
+/**
+ * dw_pcie_ep_init - Initialize the endpoint device
+ * @ep: DWC EP device
+ *
+ * Initialize the endpoint device. Allocate resources and create the EPC
+ * device with the endpoint framework.
+ *
+ * Return: 0 if success, errno otherwise.
+ */
 int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 {
 	int ret;

-- 
2.25.1



From jernej.skrabec at gmail.com  Fri Feb 23 23:10:05 2024
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Sat, 24 Feb 2024 08:10:05 +0100
Subject: [PATCH 3/3] drm/sun4i: Fix layer zpos change/atomic modesetting
In-Reply-To: <5h7jcwsdlpe7w2xylbhlw2asfww3znqlmlnszwvvosz5ssokkq@dxhn4v4sy4nq>
References: <20240216190430.1374132-1-megi@xff.cz> <2448947.jE0xQCEvom@jernej-laptop>
 <5h7jcwsdlpe7w2xylbhlw2asfww3znqlmlnszwvvosz5ssokkq@dxhn4v4sy4nq>
Message-ID: <6018948.lOV4Wx5bFT@archlinux>

On Saturday, February 24, 2024 3:20:43 AM CET Ond?ej Jirman wrote:
> On Thu, Feb 22, 2024 at 09:02:53PM +0100, Jernej ?krabec wrote:
> > Dne sreda, 21. februar 2024 ob 14:45:20 CET je Maxime Ripard napisal(a):
> > > Hi,
> > > 
> > > On Fri, Feb 16, 2024 at 08:04:26PM +0100, Ond?ej Jirman wrote:
> > > > From: Ondrej Jirman <megi at xff.cz>
> > > > 
> > > > Identical configurations of planes can lead to different (and wrong)
> > > > layer -> pipe routing at HW level, depending on the order of atomic
> > > > plane changes.
> > > > 
> > > > For example:
> > > > 
> > > > - Layer 1 is configured to zpos 0 and thus uses pipe 0. No other layer
> > > >   is enabled. This is a typical situation at boot.
> > > > 
> > > > - When a compositor takes over and layer 3 is enabled,
> > > >   sun8i_ui_layer_enable() will get called with old_zpos=0 zpos=1, which
> > > >   will lead to incorrect disabling of pipe 0 and enabling of pipe 1.
> > > > 
> > > > What happens is that sun8i_ui_layer_enable() function may disable
> > > > blender pipes even if it is no longer assigned to its layer.
> > > > 
> > > > To correct this, move the routing setup out of individual plane's
> > > > atomic_update into crtc's atomic_update, where it can be calculated
> > > > and updated all at once.
> > > > 
> > > > Remove the atomic_disable callback because it is no longer needed.
> > > > 
> > > > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > > 
> > > I don't have enough knowledge about the mixers code to comment on your
> > > patch, so I'll let Jernej review it. However, this feels to me like the
> > > pipe assignment is typically the sort of things that should be dealt
> > > with device-wide, and in atomic_check.
> > 
> > In DE2 and DE3.0, you cannot move planes between mixers (crtcs), because each
> > one is hardwired to specific mixer. Movable planes are the feature of DE3.3
> > and one of the pain points for upstreaming the code. Anyway, this commit only
> > addresses current issue of enabling and disabling planes and handling zpos.
> > 
> > In atomic check you can only precalculate final register values, but I don't
> > see any benefit doing that. I think that this code elegantly solves current
> > issue of enabling or disabling wrong plane in certain situations, so:
> > 
> > Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> > 
> > Note, if there is new revision, please rewrite blender regmap_update_bits()
> > to regmap_write(). Since there is HW issue with reads, I would like to
> > get rid of regmap_update_bits() calls eventually.
> 
> I've looked into it and I can probably rewrite these quite readily:
> 
> +	regmap_update_bits(mixer->engine.regs,
> +			   SUN8I_MIXER_BLEND_ROUTE(bld_base),
> +			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(0) |
> +			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(1) |
> +			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(2) |
> +			   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(3),
> +			   route);
> 
> The mask here covers all implemented bits in the register.
> 
> +	regmap_update_bits(mixer->engine.regs,
> +			   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
> +			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(0) |
> +			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(1) |
> +			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(2) |
> +			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(3),
> +			   pipe_en);
> +
> 
> The mask here doesn't cover BLD_FILL_COLOR_CTL.Px_FCEN bits that implement solid
> color filling. But those can be 0 anyway except for pipe0 which is hardcoded by
> the driver to 1, I think:
> 
> 631         /*
> 632          * Set fill color of bottom plane to black. Generally not needed
> 633          * except when VI plane is at bottom (zpos = 0) and enabled.
> 634          */
> 635         regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
> 636                      SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));

Correct on all counts. That's what I've meant.

> 
> I will not be able to get rid of regmap_update_bits in sun8i_layer_enable
> because that register there has other important things in it like framebuffer
> pixel format, etc.

Yeah, this rework would certainly be more involved, so it's out of the scope of
this series.

Best regards,
Jernej

> 
> kind regards,
> 	o.
> 
> > Best regards,
> > Jernej
> > 
> > > 
> > > If I'm talking non-sense, it would be great to mention at least why that
> > > can't be an option in the commit log.
> > > 
> > > Maxime
> > > 
> > 
> > 
> > 
> > 
> 






From ptsm at linux.microsoft.com  Fri Feb 23 23:20:51 2024
From: ptsm at linux.microsoft.com (Prasanna Kumar T S M)
Date: Fri, 23 Feb 2024 23:20:51 -0800
Subject: [PATCH v5 1/5] firmware: xilinx: Update firmware call interface
 to support additional args
In-Reply-To: <20231129112713.22718-2-jay.buddhabhatti@amd.com>
References: <20231129112713.22718-1-jay.buddhabhatti@amd.com>
 <20231129112713.22718-2-jay.buddhabhatti@amd.com>
Message-ID: <20240224072051.GA22366@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>

> Wed, Nov 29, 2023 at 03:27:09AM -0800, Jay Buddhabhatti wrote:
> System-level platform management layer (do_fw_call()) has support for
> maximum of 5 arguments as of now (1 EEMI API ID + 4 command arguments).
> In order to support new EEMI PM_IOCTL IDs (Secure Read/Write), this
> support must be extended to support one additional argument, which
> results in a configuration of - 1 EEMI API ID + 5 command arguments.
> 
> Update zynqmp_pm_invoke_fn() and do_fw_call() with this new definition
> containing variable arguments. As a result, update all the references
> to pm invoke function with the updated definition.
> 
> Co-developed-by: Izhar Ameer Shaikh <izhar.ameer.shaikh at amd.com>
> Signed-off-by: Izhar Ameer Shaikh <izhar.ameer.shaikh at amd.com>
> Signed-off-by: Jay Buddhabhatti <jay.buddhabhatti at amd.com>
> ---
>  drivers/firmware/xilinx/zynqmp.c        | 278 +++++++++++-------------
>  drivers/soc/xilinx/xlnx_event_manager.c |   2 +-
>  drivers/soc/xilinx/zynqmp_power.c       |   2 +-
>  include/linux/firmware/xlnx-zynqmp.h    |   3 +-
>  4 files changed, 132 insertions(+), 153 deletions(-)
> 
> diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
> index b0d22d4455d9..c9ec2c75cf0a 100644
> --- a/drivers/firmware/xilinx/zynqmp.c
> +++ b/drivers/firmware/xilinx/zynqmp.c
> @@ -106,8 +106,7 @@ static int zynqmp_pm_ret_code(u32 ret_status)
>  	}
>  }
>  
> -static noinline int do_fw_call_fail(u64 arg0, u64 arg1, u64 arg2,
> -				    u32 *ret_payload)
> +static noinline int do_fw_call_fail(u32 *ret_payload, u32 num_args, ...)
>  {
>  	return -ENODEV;
>  }
> @@ -116,25 +115,35 @@ static noinline int do_fw_call_fail(u64 arg0, u64 arg1, u64 arg2,
>   * PM function call wrapper
>   * Invoke do_fw_call_smc or do_fw_call_hvc, depending on the configuration
>   */
> -static int (*do_fw_call)(u64, u64, u64, u32 *ret_payload) = do_fw_call_fail;
> +static int (*do_fw_call)(u32 *ret_payload, u32, ...) = do_fw_call_fail;
>  
>  /**
>   * do_fw_call_smc() - Call system-level platform management layer (SMC)
> - * @arg0:		Argument 0 to SMC call
> - * @arg1:		Argument 1 to SMC call
> - * @arg2:		Argument 2 to SMC call
> + * @num_args:		Number of variable arguments should be <= 8
>   * @ret_payload:	Returned value array
>   *
>   * Invoke platform management function via SMC call (no hypervisor present).
>   *
>   * Return: Returns status, either success or error+reason
>   */
> -static noinline int do_fw_call_smc(u64 arg0, u64 arg1, u64 arg2,
> -				   u32 *ret_payload)
> +static noinline int do_fw_call_smc(u32 *ret_payload, u32 num_args, ...)
>  {
>  	struct arm_smccc_res res;
> +	u64 args[8] = {0};
> +	va_list arg_list;
> +	u8 i;
>  
> -	arm_smccc_smc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res);
> +	if (num_args > 8)
> +		return -EINVAL;
> +
> +	va_start(arg_list, num_args);
> +
> +	for (i = 0; i < num_args; i++)
> +		args[i] = va_arg(arg_list, u64);
> +
> +	va_end(arg_list);
> +
> +	arm_smccc_smc(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], &res);
>  
>  	if (ret_payload) {
>  		ret_payload[0] = lower_32_bits(res.a0);
> @@ -148,9 +157,7 @@ static noinline int do_fw_call_smc(u64 arg0, u64 arg1, u64 arg2,
>  
>  /**
>   * do_fw_call_hvc() - Call system-level platform management layer (HVC)
> - * @arg0:		Argument 0 to HVC call
> - * @arg1:		Argument 1 to HVC call
> - * @arg2:		Argument 2 to HVC call
> + * @num_args:		Number of variable arguments should be <= 8
>   * @ret_payload:	Returned value array
>   *
>   * Invoke platform management function via HVC
> @@ -159,12 +166,24 @@ static noinline int do_fw_call_smc(u64 arg0, u64 arg1, u64 arg2,
>   *
>   * Return: Returns status, either success or error+reason
>   */
> -static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2,
> -				   u32 *ret_payload)
> +static noinline int do_fw_call_hvc(u32 *ret_payload, u32 num_args, ...)
>  {
>  	struct arm_smccc_res res;
> +	u64 args[8] = {0};
> +	va_list arg_list;
> +	u8 i;
> +
> +	if (num_args > 8)
> +		return -EINVAL;
> +
> +	va_start(arg_list, num_args);
> +
> +	for (i = 0; i < num_args; i++)
> +		args[i] = va_arg(arg_list, u64);
>  
> -	arm_smccc_hvc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res);
> +	va_end(arg_list);
> +
> +	arm_smccc_hvc(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], &res);
>  
>  	if (ret_payload) {
>  		ret_payload[0] = lower_32_bits(res.a0);
> @@ -184,7 +203,7 @@ static int __do_feature_check_call(const u32 api_id, u32 *ret_payload)
>  	smc_arg[0] = PM_SIP_SVC | PM_FEATURE_CHECK;
>  	smc_arg[1] = api_id;
>  
> -	ret = do_fw_call(smc_arg[0], smc_arg[1], 0, ret_payload);
> +	ret = do_fw_call(ret_payload, 2, smc_arg[0], smc_arg[1]);
>  	if (ret)
>  		ret = -EOPNOTSUPP;
>  	else
> @@ -295,11 +314,8 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_is_function_supported);
>   * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer
>   *			   caller function depending on the configuration
>   * @pm_api_id:		Requested PM-API call
> - * @arg0:		Argument 0 to requested PM-API call
> - * @arg1:		Argument 1 to requested PM-API call
> - * @arg2:		Argument 2 to requested PM-API call
> - * @arg3:		Argument 3 to requested PM-API call
>   * @ret_payload:	Returned value array
> + * @num_args:		Number of arguments to requested PM-API call
>   *
>   * Invoke platform management function for SMC or HVC call, depending on
>   * configuration.
> @@ -316,26 +332,38 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_is_function_supported);
>   *
>   * Return: Returns status, either success or error+reason
>   */
> -int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
> -			u32 arg2, u32 arg3, u32 *ret_payload)
> +int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 *ret_payload, u32 num_args, ...)
>  {
>  	/*
>  	 * Added SIP service call Function Identifier
>  	 * Make sure to stay in x0 register
>  	 */
> -	u64 smc_arg[4];
> -	int ret;
> +	u64 smc_arg[8];
> +	int ret, i;
> +	va_list arg_list;
> +	u32 args[14] = {0};
> +
> +	if (num_args > 14)
> +		return -EINVAL;
> +
> +	va_start(arg_list, num_args);
>  
>  	/* Check if feature is supported or not */
>  	ret = zynqmp_pm_feature(pm_api_id);
>  	if (ret < 0)
>  		return ret;
>  
> +	for (i = 0; i < num_args; i++)
> +		args[i] = va_arg(arg_list, u32);
> +
> +	va_end(arg_list);
> +
>  	smc_arg[0] = PM_SIP_SVC | pm_api_id;
> -	smc_arg[1] = ((u64)arg1 << 32) | arg0;
> -	smc_arg[2] = ((u64)arg3 << 32) | arg2;
> +	for (i = 0; i < 7; i++)
> +		smc_arg[i + 1] = ((u64)args[(i * 2) + 1] << 32) | args[i * 2];
>  
> -	return do_fw_call(smc_arg[0], smc_arg[1], smc_arg[2], ret_payload);
> +	return do_fw_call(ret_payload, 8, smc_arg[0], smc_arg[1], smc_arg[2], smc_arg[3],
> +			  smc_arg[4], smc_arg[5], smc_arg[6], smc_arg[7]);
>  }
>  
>  static u32 pm_api_version;
> @@ -347,14 +375,12 @@ int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset)
>  {
>  	int ret;
>  
> -	ret = zynqmp_pm_invoke_fn(TF_A_PM_REGISTER_SGI, sgi_num, reset, 0, 0,
> -				  NULL);
> +	ret = zynqmp_pm_invoke_fn(TF_A_PM_REGISTER_SGI, NULL, 2, sgi_num, reset);
>  	if (!ret)
>  		return ret;
>  
>  	/* try old implementation as fallback strategy if above fails */
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_REGISTER_SGI, sgi_num,
> -				   reset, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, IOCTL_REGISTER_SGI, sgi_num, reset);
>  }
>  
>  /**
> @@ -376,7 +402,7 @@ int zynqmp_pm_get_api_version(u32 *version)
>  		*version = pm_api_version;
>  		return 0;
>  	}
> -	ret = zynqmp_pm_invoke_fn(PM_GET_API_VERSION, 0, 0, 0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_GET_API_VERSION, ret_payload, 0);
>  	*version = ret_payload[1];
>  
>  	return ret;
> @@ -399,7 +425,7 @@ int zynqmp_pm_get_chipid(u32 *idcode, u32 *version)
>  	if (!idcode || !version)
>  		return -EINVAL;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, ret_payload, 0);
>  	*idcode = ret_payload[1];
>  	*version = ret_payload[2];
>  
> @@ -427,7 +453,7 @@ static int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily)
>  		return 0;
>  	}
>  
> -	ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, ret_payload, 0);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -459,8 +485,7 @@ static int zynqmp_pm_get_trustzone_version(u32 *version)
>  		*version = pm_tz_version;
>  		return 0;
>  	}
> -	ret = zynqmp_pm_invoke_fn(PM_GET_TRUSTZONE_VERSION, 0, 0,
> -				  0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_GET_TRUSTZONE_VERSION, ret_payload, 0);
>  	*version = ret_payload[1];
>  
>  	return ret;
> @@ -507,8 +532,8 @@ int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out)
>  {
>  	int ret;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, qdata.qid, qdata.arg1,
> -				  qdata.arg2, qdata.arg3, out);
> +	ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, out, 4, qdata.qid, qdata.arg1, qdata.arg2,
> +				  qdata.arg3);
>  
>  	/*
>  	 * For clock name query, all bytes in SMC response are clock name
> @@ -530,7 +555,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_query_data);
>   */
>  int zynqmp_pm_clock_enable(u32 clock_id)
>  {
> -	return zynqmp_pm_invoke_fn(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_CLOCK_ENABLE, NULL, 1, clock_id);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_clock_enable);
>  
> @@ -545,7 +570,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_enable);
>   */
>  int zynqmp_pm_clock_disable(u32 clock_id)
>  {
> -	return zynqmp_pm_invoke_fn(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_CLOCK_DISABLE, NULL, 1, clock_id);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_clock_disable);
>  
> @@ -564,8 +589,7 @@ int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state)
>  	u32 ret_payload[PAYLOAD_ARG_CNT];
>  	int ret;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETSTATE, clock_id, 0,
> -				  0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETSTATE, ret_payload, 1, clock_id);
>  	*state = ret_payload[1];
>  
>  	return ret;
> @@ -584,8 +608,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getstate);
>   */
>  int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider)
>  {
> -	return zynqmp_pm_invoke_fn(PM_CLOCK_SETDIVIDER, clock_id, divider,
> -				   0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_CLOCK_SETDIVIDER, NULL, 2, clock_id, divider);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setdivider);
>  
> @@ -604,8 +627,7 @@ int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider)
>  	u32 ret_payload[PAYLOAD_ARG_CNT];
>  	int ret;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETDIVIDER, clock_id, 0,
> -				  0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETDIVIDER, ret_payload, 1, clock_id);
>  	*divider = ret_payload[1];
>  
>  	return ret;
> @@ -623,10 +645,8 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getdivider);
>   */
>  int zynqmp_pm_clock_setrate(u32 clock_id, u64 rate)
>  {
> -	return zynqmp_pm_invoke_fn(PM_CLOCK_SETRATE, clock_id,
> -				   lower_32_bits(rate),
> -				   upper_32_bits(rate),
> -				   0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_CLOCK_SETRATE, NULL, 3, clock_id, lower_32_bits(rate),
> +				   upper_32_bits(rate));
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setrate);
>  
> @@ -645,8 +665,7 @@ int zynqmp_pm_clock_getrate(u32 clock_id, u64 *rate)
>  	u32 ret_payload[PAYLOAD_ARG_CNT];
>  	int ret;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETRATE, clock_id, 0,
> -				  0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETRATE, ret_payload, 1, clock_id);
>  	*rate = ((u64)ret_payload[2] << 32) | ret_payload[1];
>  
>  	return ret;
> @@ -664,8 +683,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getrate);
>   */
>  int zynqmp_pm_clock_setparent(u32 clock_id, u32 parent_id)
>  {
> -	return zynqmp_pm_invoke_fn(PM_CLOCK_SETPARENT, clock_id,
> -				   parent_id, 0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_CLOCK_SETPARENT, NULL, 2, clock_id, parent_id);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setparent);
>  
> @@ -684,8 +702,7 @@ int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id)
>  	u32 ret_payload[PAYLOAD_ARG_CNT];
>  	int ret;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETPARENT, clock_id, 0,
> -				  0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETPARENT, ret_payload, 1, clock_id);
>  	*parent_id = ret_payload[1];
>  
>  	return ret;
> @@ -704,8 +721,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getparent);
>   */
>  int zynqmp_pm_set_pll_frac_mode(u32 clk_id, u32 mode)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_PLL_FRAC_MODE,
> -				   clk_id, mode, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_SET_PLL_FRAC_MODE, clk_id, mode);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_set_pll_frac_mode);
>  
> @@ -721,8 +737,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_pll_frac_mode);
>   */
>  int zynqmp_pm_get_pll_frac_mode(u32 clk_id, u32 *mode)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_GET_PLL_FRAC_MODE,
> -				   clk_id, 0, mode);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, mode, 3, 0, IOCTL_GET_PLL_FRAC_MODE, clk_id);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_mode);
>  
> @@ -739,8 +754,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_mode);
>   */
>  int zynqmp_pm_set_pll_frac_data(u32 clk_id, u32 data)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_PLL_FRAC_DATA,
> -				   clk_id, data, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_SET_PLL_FRAC_DATA, clk_id, data);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_set_pll_frac_data);
>  
> @@ -756,8 +770,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_pll_frac_data);
>   */
>  int zynqmp_pm_get_pll_frac_data(u32 clk_id, u32 *data)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_GET_PLL_FRAC_DATA,
> -				   clk_id, 0, data);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, data, 3, 0, IOCTL_GET_PLL_FRAC_DATA, clk_id);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_data);
>  
> @@ -778,9 +791,8 @@ int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value)
>  	u32 mask = (node_id == NODE_SD_0) ? GENMASK(15, 0) : GENMASK(31, 16);
>  
>  	if (value) {
> -		return zynqmp_pm_invoke_fn(PM_IOCTL, node_id,
> -					   IOCTL_SET_SD_TAPDELAY,
> -					   type, value, NULL);
> +		return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, node_id, IOCTL_SET_SD_TAPDELAY, type,
> +					   value);
>  	}
>  
>  	/*
> @@ -798,7 +810,7 @@ int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value)
>  	 * Use PM_MMIO_READ/PM_MMIO_WRITE to re-implement the missing counter
>  	 * part of IOCTL_SET_SD_TAPDELAY which clears SDx_ITAPDLYENA bits.
>  	 */
> -	return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, reg, mask, 0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, NULL, 2, reg, mask);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay);
>  
> @@ -814,8 +826,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay);
>   */
>  int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SD_DLL_RESET,
> -				   type, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, node_id, IOCTL_SD_DLL_RESET, type);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset);
>  
> @@ -831,8 +842,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset);
>   */
>  int zynqmp_pm_ospi_mux_select(u32 dev_id, u32 select)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, dev_id, IOCTL_OSPI_MUX_SELECT,
> -				   select, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, dev_id, IOCTL_OSPI_MUX_SELECT, select);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_ospi_mux_select);
>  
> @@ -847,8 +857,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_ospi_mux_select);
>   */
>  int zynqmp_pm_write_ggs(u32 index, u32 value)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_WRITE_GGS,
> -				   index, value, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_WRITE_GGS, index, value);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_write_ggs);
>  
> @@ -863,8 +872,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_write_ggs);
>   */
>  int zynqmp_pm_read_ggs(u32 index, u32 *value)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_READ_GGS,
> -				   index, 0, value);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, value, 3, 0, IOCTL_READ_GGS, index);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_read_ggs);
>  
> @@ -880,8 +888,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_read_ggs);
>   */
>  int zynqmp_pm_write_pggs(u32 index, u32 value)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_WRITE_PGGS, index, value,
> -				   NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_WRITE_PGGS, index, value);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_write_pggs);
>  
> @@ -897,15 +904,13 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_write_pggs);
>   */
>  int zynqmp_pm_read_pggs(u32 index, u32 *value)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_READ_PGGS, index, 0,
> -				   value);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, value, 3, 0, IOCTL_READ_PGGS, index);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs);
>  
>  int zynqmp_pm_set_tapdelay_bypass(u32 index, u32 value)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_TAPDELAY_BYPASS,
> -				   index, value, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_SET_TAPDELAY_BYPASS, index, value);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_set_tapdelay_bypass);
>  
> @@ -920,8 +925,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_tapdelay_bypass);
>   */
>  int zynqmp_pm_set_boot_health_status(u32 value)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_BOOT_HEALTH_STATUS,
> -				   value, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, 0, IOCTL_SET_BOOT_HEALTH_STATUS, value);
>  }
>  
>  /**
> @@ -935,8 +939,7 @@ int zynqmp_pm_set_boot_health_status(u32 value)
>  int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
>  			   const enum zynqmp_pm_reset_action assert_flag)
>  {
> -	return zynqmp_pm_invoke_fn(PM_RESET_ASSERT, reset, assert_flag,
> -				   0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_RESET_ASSERT, NULL, 2, reset, assert_flag);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_reset_assert);
>  
> @@ -955,8 +958,7 @@ int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, u32 *status)
>  	if (!status)
>  		return -EINVAL;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_RESET_GET_STATUS, reset, 0,
> -				  0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_RESET_GET_STATUS, ret_payload, 1, reset);
>  	*status = ret_payload[1];
>  
>  	return ret;
> @@ -981,9 +983,8 @@ int zynqmp_pm_fpga_load(const u64 address, const u32 size, const u32 flags)
>  	u32 ret_payload[PAYLOAD_ARG_CNT];
>  	int ret;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_FPGA_LOAD, lower_32_bits(address),
> -				  upper_32_bits(address), size, flags,
> -				  ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_FPGA_LOAD, ret_payload, 4, lower_32_bits(address),
> +				  upper_32_bits(address), size, flags);
>  	if (ret_payload[0])
>  		return -ret_payload[0];
>  
> @@ -1008,7 +1009,7 @@ int zynqmp_pm_fpga_get_status(u32 *value)
>  	if (!value)
>  		return -EINVAL;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_STATUS, 0, 0, 0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_STATUS, ret_payload, 0);
>  	*value = ret_payload[1];
>  
>  	return ret;
> @@ -1036,11 +1037,9 @@ int zynqmp_pm_fpga_get_config_status(u32 *value)
>  	lower_addr = lower_32_bits((u64)&buf);
>  	upper_addr = upper_32_bits((u64)&buf);
>  
> -	ret = zynqmp_pm_invoke_fn(PM_FPGA_READ,
> -				  XILINX_ZYNQMP_PM_FPGA_CONFIG_STAT_OFFSET,
> -				  lower_addr, upper_addr,
> -				  XILINX_ZYNQMP_PM_FPGA_READ_CONFIG_REG,
> -				  ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_FPGA_READ, ret_payload, 4,
> +				  XILINX_ZYNQMP_PM_FPGA_CONFIG_STAT_OFFSET, lower_addr, upper_addr,
> +				  XILINX_ZYNQMP_PM_FPGA_READ_CONFIG_REG);
>  
>  	*value = ret_payload[1];
>  
> @@ -1058,7 +1057,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_config_status);
>   */
>  int zynqmp_pm_pinctrl_request(const u32 pin)
>  {
> -	return zynqmp_pm_invoke_fn(PM_PINCTRL_REQUEST, pin, 0, 0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_PINCTRL_REQUEST, NULL, 1, pin);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_request);
>  
> @@ -1072,7 +1071,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_request);
>   */
>  int zynqmp_pm_pinctrl_release(const u32 pin)
>  {
> -	return zynqmp_pm_invoke_fn(PM_PINCTRL_RELEASE, pin, 0, 0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_PINCTRL_RELEASE, NULL, 1, pin);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_release);
>  
> @@ -1093,8 +1092,7 @@ int zynqmp_pm_pinctrl_get_function(const u32 pin, u32 *id)
>  	if (!id)
>  		return -EINVAL;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_PINCTRL_GET_FUNCTION, pin, 0,
> -				  0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_PINCTRL_GET_FUNCTION, ret_payload, 1, pin);
>  	*id = ret_payload[1];
>  
>  	return ret;
> @@ -1112,8 +1110,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_get_function);
>   */
>  int zynqmp_pm_pinctrl_set_function(const u32 pin, const u32 id)
>  {
> -	return zynqmp_pm_invoke_fn(PM_PINCTRL_SET_FUNCTION, pin, id,
> -				   0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_PINCTRL_SET_FUNCTION, NULL, 2, pin, id);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_function);
>  
> @@ -1136,8 +1133,7 @@ int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param,
>  	if (!value)
>  		return -EINVAL;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_GET, pin, param,
> -				  0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_GET, ret_payload, 2, pin, param);
>  	*value = ret_payload[1];
>  
>  	return ret;
> @@ -1166,8 +1162,7 @@ int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param,
>  			return -EOPNOTSUPP;
>  	}
>  
> -	return zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_SET, pin,
> -				   param, value, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_SET, NULL, 3, pin, param, value);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_config);
>  
> @@ -1185,8 +1180,7 @@ unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode)
>  	unsigned int ret;
>  	u32 ret_payload[PAYLOAD_ARG_CNT];
>  
> -	ret = zynqmp_pm_invoke_fn(PM_MMIO_READ, CRL_APB_BOOT_PIN_CTRL, 0,
> -				  0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_MMIO_READ, ret_payload, 1, CRL_APB_BOOT_PIN_CTRL);
>  
>  	*ps_mode = ret_payload[1];
>  
> @@ -1205,8 +1199,8 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_read);
>   */
>  int zynqmp_pm_bootmode_write(u32 ps_mode)
>  {
> -	return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, CRL_APB_BOOT_PIN_CTRL,
> -				   CRL_APB_BOOTPIN_CTRL_MASK, ps_mode, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, NULL, 3, CRL_APB_BOOT_PIN_CTRL,
> +				   CRL_APB_BOOTPIN_CTRL_MASK, ps_mode);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_write);
>  
> @@ -1221,7 +1215,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_write);
>   */
>  int zynqmp_pm_init_finalize(void)
>  {
> -	return zynqmp_pm_invoke_fn(PM_PM_INIT_FINALIZE, 0, 0, 0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_PM_INIT_FINALIZE, NULL, 0);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_init_finalize);
>  
> @@ -1235,7 +1229,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_init_finalize);
>   */
>  int zynqmp_pm_set_suspend_mode(u32 mode)
>  {
> -	return zynqmp_pm_invoke_fn(PM_SET_SUSPEND_MODE, mode, 0, 0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_SET_SUSPEND_MODE, NULL, 1, mode);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_set_suspend_mode);
>  
> @@ -1254,8 +1248,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_suspend_mode);
>  int zynqmp_pm_request_node(const u32 node, const u32 capabilities,
>  			   const u32 qos, const enum zynqmp_pm_request_ack ack)
>  {
> -	return zynqmp_pm_invoke_fn(PM_REQUEST_NODE, node, capabilities,
> -				   qos, ack, NULL);
> +	return zynqmp_pm_invoke_fn(PM_REQUEST_NODE, NULL, 4, node, capabilities, qos, ack);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_request_node);
>  
> @@ -1271,7 +1264,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_request_node);
>   */
>  int zynqmp_pm_release_node(const u32 node)
>  {
> -	return zynqmp_pm_invoke_fn(PM_RELEASE_NODE, node, 0, 0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_RELEASE_NODE, NULL, 1, node);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_release_node);
>  
> @@ -1290,8 +1283,7 @@ int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mode)
>  	u32 ret_payload[PAYLOAD_ARG_CNT];
>  	int ret;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_IOCTL, node_id,
> -				  IOCTL_GET_RPU_OPER_MODE, 0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_IOCTL, ret_payload, 2, node_id, IOCTL_GET_RPU_OPER_MODE);
>  
>  	/* only set rpu_mode if no error */
>  	if (ret == XST_PM_SUCCESS)
> @@ -1313,9 +1305,8 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_get_rpu_mode);
>   */
>  int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, node_id,
> -				   IOCTL_SET_RPU_OPER_MODE, (u32)rpu_mode,
> -				   0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, node_id, IOCTL_SET_RPU_OPER_MODE,
> +				   (u32)rpu_mode);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_set_rpu_mode);
>  
> @@ -1331,9 +1322,8 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_rpu_mode);
>   */
>  int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, node_id,
> -				   IOCTL_TCM_COMB_CONFIG, (u32)tcm_mode, 0,
> -				   NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, node_id, IOCTL_TCM_COMB_CONFIG,
> +				   (u32)tcm_mode);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_set_tcm_config);
>  
> @@ -1348,7 +1338,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_tcm_config);
>  int zynqmp_pm_force_pwrdwn(const u32 node,
>  			   const enum zynqmp_pm_request_ack ack)
>  {
> -	return zynqmp_pm_invoke_fn(PM_FORCE_POWERDOWN, node, ack, 0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_FORCE_POWERDOWN, NULL, 2, node, ack);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_force_pwrdwn);
>  
> @@ -1367,8 +1357,8 @@ int zynqmp_pm_request_wake(const u32 node,
>  			   const enum zynqmp_pm_request_ack ack)
>  {
>  	/* set_addr flag is encoded into 1st bit of address */
> -	return zynqmp_pm_invoke_fn(PM_REQUEST_WAKEUP, node, address | set_addr,
> -				   address >> 32, ack, NULL);
> +	return zynqmp_pm_invoke_fn(PM_REQUEST_WAKEUP, NULL, 4, node, address | set_addr,
> +				   address >> 32, ack);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_request_wake);
>  
> @@ -1388,8 +1378,7 @@ int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities,
>  			      const u32 qos,
>  			      const enum zynqmp_pm_request_ack ack)
>  {
> -	return zynqmp_pm_invoke_fn(PM_SET_REQUIREMENT, node, capabilities,
> -				   qos, ack, NULL);
> +	return zynqmp_pm_invoke_fn(PM_SET_REQUIREMENT, NULL, 4, node, capabilities, qos, ack);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_set_requirement);
>  
> @@ -1404,9 +1393,8 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_requirement);
>   */
>  int zynqmp_pm_load_pdi(const u32 src, const u64 address)
>  {
> -	return zynqmp_pm_invoke_fn(PM_LOAD_PDI, src,
> -				   lower_32_bits(address),
> -				   upper_32_bits(address), 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_LOAD_PDI, NULL, 3, src, lower_32_bits(address),
> +				   upper_32_bits(address));
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_load_pdi);
>  
> @@ -1426,9 +1414,8 @@ int zynqmp_pm_aes_engine(const u64 address, u32 *out)
>  	if (!out)
>  		return -EINVAL;
>  
> -	ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, upper_32_bits(address),
> -				  lower_32_bits(address),
> -				  0, 0, ret_payload);
> +	ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, ret_payload, 2, upper_32_bits(address),
> +				  lower_32_bits(address));
>  	*out = ret_payload[1];
>  
>  	return ret;
> @@ -1456,8 +1443,7 @@ 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);
> +	return zynqmp_pm_invoke_fn(PM_SECURE_SHA, NULL, 4, upper_addr, lower_addr, size, flags);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash);
>  
> @@ -1479,8 +1465,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash);
>  int zynqmp_pm_register_notifier(const u32 node, const u32 event,
>  				const u32 wake, const u32 enable)
>  {
> -	return zynqmp_pm_invoke_fn(PM_REGISTER_NOTIFIER, node, event,
> -				   wake, enable, NULL);
> +	return zynqmp_pm_invoke_fn(PM_REGISTER_NOTIFIER, NULL, 4, node, event, wake, enable);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_register_notifier);
>  
> @@ -1493,8 +1478,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_register_notifier);
>   */
>  int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype)
>  {
> -	return zynqmp_pm_invoke_fn(PM_SYSTEM_SHUTDOWN, type, subtype,
> -				   0, 0, NULL);
> +	return zynqmp_pm_invoke_fn(PM_SYSTEM_SHUTDOWN, NULL, 2, type, subtype);
>  }
>  
>  /**
> @@ -1506,8 +1490,7 @@ int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype)
>   */
>  int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_FEATURE_CONFIG,
> -				   id, value, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_SET_FEATURE_CONFIG, id, value);
>  }
>  
>  /**
> @@ -1520,8 +1503,7 @@ int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value)
>  int zynqmp_pm_get_feature_config(enum pm_feature_config_id id,
>  				 u32 *payload)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_GET_FEATURE_CONFIG,
> -				   id, 0, payload);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, payload, 3, 0, IOCTL_GET_FEATURE_CONFIG, id);
>  }
>  
>  /**
> @@ -1534,8 +1516,7 @@ int zynqmp_pm_get_feature_config(enum pm_feature_config_id id,
>   */
>  int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, node, IOCTL_SET_SD_CONFIG,
> -				   config, value, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, node, IOCTL_SET_SD_CONFIG, config, value);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_config);
>  
> @@ -1550,8 +1531,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_config);
>  int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
>  			     u32 value)
>  {
> -	return zynqmp_pm_invoke_fn(PM_IOCTL, node, IOCTL_SET_GEM_CONFIG,
> -				   config, value, NULL);
> +	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, node, IOCTL_SET_GEM_CONFIG, config, value);
>  }
>  EXPORT_SYMBOL_GPL(zynqmp_pm_set_gem_config);
>  
> diff --git a/drivers/soc/xilinx/xlnx_event_manager.c b/drivers/soc/xilinx/xlnx_event_manager.c
> index 86a048a10a13..adb875f89829 100644
> --- a/drivers/soc/xilinx/xlnx_event_manager.c
> +++ b/drivers/soc/xilinx/xlnx_event_manager.c
> @@ -483,7 +483,7 @@ static void xlnx_call_notify_cb_handler(const u32 *payload)
>  
>  static void xlnx_get_event_callback_data(u32 *buf)
>  {
> -	zynqmp_pm_invoke_fn(GET_CALLBACK_DATA, 0, 0, 0, 0, buf);
> +	zynqmp_pm_invoke_fn(GET_CALLBACK_DATA, buf, 0);
>  }
>  
>  static irqreturn_t xlnx_event_handler(int irq, void *dev_id)
> diff --git a/drivers/soc/xilinx/zynqmp_power.c b/drivers/soc/xilinx/zynqmp_power.c
> index c2c819701eec..0de0acf80ef8 100644
> --- a/drivers/soc/xilinx/zynqmp_power.c
> +++ b/drivers/soc/xilinx/zynqmp_power.c
> @@ -51,7 +51,7 @@ static enum pm_suspend_mode suspend_mode = PM_SUSPEND_MODE_STD;
>  
>  static void zynqmp_pm_get_callback_data(u32 *buf)
>  {
> -	zynqmp_pm_invoke_fn(GET_CALLBACK_DATA, 0, 0, 0, 0, buf);
> +	zynqmp_pm_invoke_fn(GET_CALLBACK_DATA, buf, 0);
>  }
>  
>  static void suspend_event_callback(const u32 *payload, void *data)
> diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
> index d1ea3898564c..a7e24f5a71b6 100644
> --- a/include/linux/firmware/xlnx-zynqmp.h
> +++ b/include/linux/firmware/xlnx-zynqmp.h
> @@ -509,8 +509,7 @@ struct zynqmp_pm_query_data {
>  	u32 arg3;
>  };
>  
> -int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
> -			u32 arg2, u32 arg3, u32 *ret_payload);
> +int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 *ret_payload, u32 num_args, ...);
>  
>  #if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE)
>  int zynqmp_pm_get_api_version(u32 *version);

Looks good to me.

Reviewed-by: Prasanna Kumar TSM <ptsm at linux.microsoft.com>


From chester62515 at gmail.com  Fri Feb 23 23:25:20 2024
From: chester62515 at gmail.com (Chester Lin)
Date: Sat, 24 Feb 2024 15:25:20 +0800
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <Zdiu8s5Cgz9s6dLP@dragon>
References: <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
 <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
 <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>
 <e6f6070e-8355-4a0b-a904-1a24970f249b@linaro.org>
 <e530d504-dfa3-4d39-b903-b2570bb8b014@suse.com>
 <c3e68c62-b81f-475b-9b15-c983c94aed8b@app.fastmail.com>
 <Zdiu8s5Cgz9s6dLP@dragon>
Message-ID: <ZdmZ4JC0CsX2qs5C@linux-8mug>

Hi all,

Sorry for the late reply since I lost connection with upstream due to a
health condition, which affected my eyesights for a while so I tried to use
my eyes as less as possible. Please accept my apologies anyway.

On Fri, Feb 23, 2024 at 10:42:58PM +0800, Shawn Guo wrote:
> On Fri, Feb 23, 2024 at 01:29:10PM +0100, Arnd Bergmann wrote:
> > On Fri, Feb 23, 2024, at 13:02, Matthias Brugger wrote:
> > > On 22/02/2024 12:13, Krzysztof Kozlowski wrote:
> > >> On 21/02/2024 18:00, Ghennadi Procopciuc wrote:
> > >> 
> > >> Andreas or Matthias,
> > >> Maybe you could change your R: into M: and take s32g patches?
> > >> 
> > >> If not, then I will ack this patch making Ghennadi the maintainer.
> > >> 
> > >
> > > Normal process would be that Arnd would contact Chester to see if he is 
> > > not able 
> > > to do the maintainer work any more. In that case maybe Arnd could take 
> > > over.
> > 
> > I was hoping to see a reply from Chester one way or another,
> > I see he has been on Cc for the entire thread but not
> > chimed in.
> > 

Before leaving SUSE I reached NXP to see if anyone could take over it but I
didn't get response unfortunately. Maybe it was too rush to find a right person
at the moment but I still wish that someone can take over this role based on the
following reasons:

- Since I have returned my S32G boards to SUSE, currently I do not have a platform
to verify S32G patches unless I could get a new one. I wish I could still help
out but hardware & doc resources will be the biggest challenge to me.

- My current employee may have competitive relationship with NXP in automotive
field, which means I may not be fit in this role unless nobody cares.

> > > I'm not saying that Ghennadi won't be able to defend this, if it ever occurs. 
> > > Basically because I don't have a good track record of him due to missing 
> > > upstream collaboration.
> > >
> > > I would prefer that Arnd (or Andreas) step up to take the maintainer role. I 
> > > already have one and it's difficult for me to find the time to do it in an 
> > > acceptable way.
> > 
> > It appears that we already cover the dts files in the IMX
> > entry, whether that is intentional or not:
> > 
> > ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
> > M:      Shawn Guo <shawnguo at kernel.org>
> > M:      Sascha Hauer <s.hauer at pengutronix.de>
> > R:      Pengutronix Kernel Team <kernel at pengutronix.de>
> > R:      Fabio Estevam <festevam at gmail.com>
> > R:      NXP Linux Team <linux-imx at nxp.com> 
> > L:      linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> > S:      Maintained
> > T:      git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
> > F:      arch/arm/boot/dts/nxp/imx/
> > F:      arch/arm/boot/dts/nxp/mxs/
> > F:      arch/arm64/boot/dts/freescale/
> > 
> > Added everyone there to Cc, having any s32 patches go through
> > the imx tree would be the easiest way as far as I'm concerned.
> > I've added the maintainers to Cc, let's see what they think.
> 
> It's unintentional that IMX entry covers s32 dts files, as they have a
> dedicated entry.
> 
> ARM/NXP S32G ARCHITECTURE
> M:      Chester Lin <chester62515 at gmail.com>
> R:      Andreas F?rber <afaerber at suse.de>
> R:      Matthias Brugger <mbrugger at suse.com>
> R:      NXP S32 Linux Team <s32 at nxp.com>
> L:      linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> S:      Maintained
> F:      arch/arm64/boot/dts/freescale/s32g*.dts*
> 
> However I'm fine with collecting and sending patches through IMX tree,
> if S32G folks help review them.
> 
> Shawn
> 

This looks good to me as well.

Regards,
Chester


From chester62515 at gmail.com  Fri Feb 23 23:56:12 2024
From: chester62515 at gmail.com (Chester Lin)
Date: Sat, 24 Feb 2024 15:56:12 +0800
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <ZdmZ4JC0CsX2qs5C@linux-8mug>
References: <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
 <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
 <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>
 <e6f6070e-8355-4a0b-a904-1a24970f249b@linaro.org>
 <e530d504-dfa3-4d39-b903-b2570bb8b014@suse.com>
 <c3e68c62-b81f-475b-9b15-c983c94aed8b@app.fastmail.com>
 <Zdiu8s5Cgz9s6dLP@dragon>
 <ZdmZ4JC0CsX2qs5C@linux-8mug>
Message-ID: <ZdmhHEbpbzNNeNb/@linux-8mug>

On Sat, Feb 24, 2024 at 03:25:59PM +0800, Chester Lin wrote:
> Hi all,
> 
> Sorry for the late reply since I lost connection with upstream due to a
> health condition, which affected my eyesight for a while so I tried to use
> my eyes as less as possible. Please accept my apologies anyway.
> 
> On Fri, Feb 23, 2024 at 10:42:58PM +0800, Shawn Guo wrote:
> > On Fri, Feb 23, 2024 at 01:29:10PM +0100, Arnd Bergmann wrote:
> > > On Fri, Feb 23, 2024, at 13:02, Matthias Brugger wrote:
> > > > On 22/02/2024 12:13, Krzysztof Kozlowski wrote:
> > > >> On 21/02/2024 18:00, Ghennadi Procopciuc wrote:
> > > >> 
> > > >> Andreas or Matthias,
> > > >> Maybe you could change your R: into M: and take s32g patches?
> > > >> 
> > > >> If not, then I will ack this patch making Ghennadi the maintainer.
> > > >> 
> > > >
> > > > Normal process would be that Arnd would contact Chester to see if he is 
> > > > not able 
> > > > to do the maintainer work any more. In that case maybe Arnd could take 
> > > > over.
> > > 
> > > I was hoping to see a reply from Chester one way or another,
> > > I see he has been on Cc for the entire thread but not
> > > chimed in.
> > > 
> 
> Before leaving SUSE I reached NXP to see if anyone could take over it but I
> didn't get response unfortunately. Maybe it was too rushed to find a right person
> at the moment but I still wish that someone can take over this role based on the
> following reasons:
> 
> - Since I have returned my S32G boards to SUSE, currently I do not have a platform
> to verify S32G patches unless I could get a new one. I wish I could still help
> out but hardware & doc resources will be the biggest challenge to me.
> 
> - My current employee may have competitive relationship with NXP in automotive

"My current employer". Sorry for my stupid typo.

Chester

> field, which means I may not be fit in this role unless nobody cares.
> 
> > > > I'm not saying that Ghennadi won't be able to defend this, if it ever occurs. 
> > > > Basically because I don't have a good track record of him due to missing 
> > > > upstream collaboration.
> > > >
> > > > I would prefer that Arnd (or Andreas) step up to take the maintainer role. I 
> > > > already have one and it's difficult for me to find the time to do it in an 
> > > > acceptable way.
> > > 
> > > It appears that we already cover the dts files in the IMX
> > > entry, whether that is intentional or not:
> > > 
> > > ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
> > > M:      Shawn Guo <shawnguo at kernel.org>
> > > M:      Sascha Hauer <s.hauer at pengutronix.de>
> > > R:      Pengutronix Kernel Team <kernel at pengutronix.de>
> > > R:      Fabio Estevam <festevam at gmail.com>
> > > R:      NXP Linux Team <linux-imx at nxp.com> 
> > > L:      linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> > > S:      Maintained
> > > T:      git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
> > > F:      arch/arm/boot/dts/nxp/imx/
> > > F:      arch/arm/boot/dts/nxp/mxs/
> > > F:      arch/arm64/boot/dts/freescale/
> > > 
> > > Added everyone there to Cc, having any s32 patches go through
> > > the imx tree would be the easiest way as far as I'm concerned.
> > > I've added the maintainers to Cc, let's see what they think.
> > 
> > It's unintentional that IMX entry covers s32 dts files, as they have a
> > dedicated entry.
> > 
> > ARM/NXP S32G ARCHITECTURE
> > M:      Chester Lin <chester62515 at gmail.com>
> > R:      Andreas F?rber <afaerber at suse.de>
> > R:      Matthias Brugger <mbrugger at suse.com>
> > R:      NXP S32 Linux Team <s32 at nxp.com>
> > L:      linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> > S:      Maintained
> > F:      arch/arm64/boot/dts/freescale/s32g*.dts*
> > 
> > However I'm fine with collecting and sending patches through IMX tree,
> > if S32G folks help review them.
> > 
> > Shawn
> > 
> 
> This looks good to me as well.
> 
> Regards,
> Chester


From chester62515 at gmail.com  Sat Feb 24 00:14:21 2024
From: chester62515 at gmail.com (Chester Lin)
Date: Sat, 24 Feb 2024 16:14:21 +0800
Subject: [PATCH v2 1/2] arm64: dts: s32g: add SCMI firmware node
In-Reply-To: <94742ebd-bc3a-4726-9ba7-5954203e4da1@suse.com>
References: <20240122140602.1006813-1-ghennadi.procopciuc@oss.nxp.com>
 <20240122140602.1006813-2-ghennadi.procopciuc@oss.nxp.com>
 <94742ebd-bc3a-4726-9ba7-5954203e4da1@suse.com>
Message-ID: <ZdmlXYq962azlVRe@linux-8mug>

Hi Ghennadi,

On Mon, Jan 22, 2024 at 03:39:09PM +0100, Matthias Brugger wrote:
> 
> 
> On 22/01/2024 15:06, Ghennadi Procopciuc wrote:
> > From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> > 
> > Linux controls the clocks over SCMI on S32G SoCs. Therefore,
> > add the SCMI device tree node and the reserved region for SCMI

Is there any dt-binding required to match the SCMI clock IDs declared in
SCMI? I assume that s32g series will need fixed dt-bindings for clocks to make
sure there will be no kabi issue in the future.

Thanks,
Chester

> > messages.
> > 
> > Signed-off-by: Catalin Udma <catalin-dan.udma at nxp.com>
> > Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> 
> Reviewed-by: Matthias Brugger <mbrugger at suse.com>
> 
> > ---
> >   arch/arm64/boot/dts/freescale/s32g2.dtsi | 27 +++++++++++++++++++++++-
> >   1 file changed, 26 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > index 5ac1cc9ff50e..ef1a1d61f2ba 100644
> > --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > @@ -3,7 +3,7 @@
> >    * NXP S32G2 SoC family
> >    *
> >    * Copyright (c) 2021 SUSE LLC
> > - * Copyright (c) 2017-2021 NXP
> > + * Copyright 2017-2021, 2024 NXP
> >    */
> >   #include <dt-bindings/interrupt-controller/arm-gic.h>
> > @@ -14,6 +14,18 @@ / {
> >   	#address-cells = <2>;
> >   	#size-cells = <2>;
> > +	reserved-memory  {
> > +		#address-cells = <2>;
> > +		#size-cells = <2>;
> > +		ranges;
> > +
> > +		scmi_buf: shm at d0000000 {
> > +			compatible = "arm,scmi-shmem";
> > +			reg = <0x0 0xd0000000 0x0 0x80>;
> > +			no-map;
> > +		};
> > +	};
> > +
> >   	cpus {
> >   		#address-cells = <1>;
> >   		#size-cells = <0>;
> > @@ -77,6 +89,19 @@ timer {
> >   	};
> >   	firmware {
> > +		scmi {
> > +			compatible = "arm,scmi-smc";
> > +			arm,smc-id = <0xc20000fe>;
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +			shmem = <&scmi_buf>;
> > +
> > +			clks: protocol at 14 {
> > +				reg = <0x14>;
> > +				#clock-cells = <1>;
> > +			};
> > +		};
> > +
> >   		psci {
> >   			compatible = "arm,psci-1.0";
> >   			method = "smc";


From chester62515 at gmail.com  Sat Feb 24 00:22:25 2024
From: chester62515 at gmail.com (Chester Lin)
Date: Sat, 24 Feb 2024 16:22:25 +0800
Subject: [PATCH v2 2/2] arm64: dts: s32g: add uSDHC node
In-Reply-To: <20240122140602.1006813-3-ghennadi.procopciuc@oss.nxp.com>
References: <20240122140602.1006813-1-ghennadi.procopciuc@oss.nxp.com>
 <20240122140602.1006813-3-ghennadi.procopciuc@oss.nxp.com>
Message-ID: <ZdmnQTtUxOEUy06L@linux-8mug>

Hi Ghennadi,

On Mon, Jan 22, 2024 at 04:06:01PM +0200, Ghennadi Procopciuc wrote:
> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> 
> Add the uSDHC node for the boards that are based on S32G SoCs.
> 
> Signed-off-by: Ciprian Costea <ciprianmarian.costea at nxp.com>
> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/s32g2.dtsi        | 10 ++++++++++
>  arch/arm64/boot/dts/freescale/s32g274a-evb.dts  |  6 +++++-
>  arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts |  6 +++++-
>  3 files changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> index ef1a1d61f2ba..fc19ae2e8d3b 100644
> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> @@ -138,6 +138,16 @@ uart2: serial at 402bc000 {
>  			status = "disabled";
>  		};
>  
> +		usdhc0: mmc at 402f0000 {
> +			compatible = "nxp,s32g2-usdhc";
> +			reg = <0x402f0000 0x1000>;
> +			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clks 32>, <&clks 31>, <&clks 33>;

Same as I have mentioned in [PATCH v2 1/2], could we have fixed dt-bindings to
replace with these raw clock id values (32, 31, 33)?

Chester
> +			clock-names = "ipg", "ahb", "per";
> +			bus-width = <8>;
> +			status = "disabled";
> +		};
> +
>  		gic: interrupt-controller at 50800000 {
>  			compatible = "arm,gic-v3";
>  			reg = <0x50800000 0x10000>,
> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> index 9118d8d2ee01..00070c949e2a 100644
> --- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> @@ -1,7 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
>  /*
>   * Copyright (c) 2021 SUSE LLC
> - * Copyright (c) 2019-2021 NXP
> + * Copyright 2019-2021, 2024 NXP
>   */
>  
>  /dts-v1/;
> @@ -32,3 +32,7 @@ memory at 80000000 {
>  &uart0 {
>  	status = "okay";
>  };
> +
> +&usdhc0 {
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> index e05ee854cdf5..b3fc12899cae 100644
> --- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> @@ -1,7 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
>  /*
>   * Copyright (c) 2021 SUSE LLC
> - * Copyright (c) 2019-2021 NXP
> + * Copyright 2019-2021, 2024 NXP
>   */
>  
>  /dts-v1/;
> @@ -38,3 +38,7 @@ &uart0 {
>  &uart1 {
>  	status = "okay";
>  };
> +
> +&usdhc0 {
> +	status = "okay";
> +};
> -- 
> 2.43.0
> 


From krzysztof.kozlowski at linaro.org  Sat Feb 24 00:52:18 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 24 Feb 2024 09:52:18 +0100
Subject: [PATCH v5 00/18] power: sequencing: implement the subsystem and
 add first users
In-Reply-To: <CAMRc=MfkQuaJ3FnVwbVKQRQEgmJKbZh7SJoK3Kbmb5ebzE2rKA@mail.gmail.com>
References: <20240216203215.40870-1-brgl@bgdev.pl>
 <CAA8EJppt4-L1RyDeG=1SbbzkTDhLkGcmAbZQeY0S6wGnBbFbvw@mail.gmail.com>
 <e4cddd9f-9d76-43b7-9091-413f923d27f2@linaro.org>
 <CAA8EJpp6+2w65o2Bfcr44tE_ircMoON6hvGgyWfvFuh3HamoSQ@mail.gmail.com>
 <4d2a6f16-bb48-4d4e-b8fd-7e4b14563ffa@linaro.org>
 <CAA8EJpq=iyOfYzNATRbpqfBaYSdJV1Ao5t2ewLK+wY+vEaFYAQ@mail.gmail.com>
 <CAMRc=Mfnpusf+mb-CB5S8_p7QwVW6owekC5KcQF0qrR=iOQ=oA@mail.gmail.com>
 <CAA8EJppY7VTrDz3-FMZh2qHoU+JSGUjCVEi5x=OZgNVxQLm3eQ@mail.gmail.com>
 <b9a31374-8ea9-407e-9ec3-008a95e2b18b@linaro.org>
 <CAA8EJppWY8c-pF75WaMadWtEuaAyCc5A1VLEq=JmB2Ngzk-zyw@mail.gmail.com>
 <CAMRc=Md6SoXukoGb4bW-CSYgjpO4RL+0Uu3tYrZzgSgVtFH6Sw@mail.gmail.com>
 <CAA8EJprUM6=ZqTwWLB8rW8WRDqwncafa-szSsTvPQCOOSXUn_w@mail.gmail.com>
 <CAMRc=Metemd=24t0RJw-O9Z0-cg4mESouOfvMVLs_rJDCwRBPQ@mail.gmail.com>
 <CAA8EJprJTj7o0ATrQbF_38tW+kLspF1nBySg+_y_RWmadVnV9A@mail.gmail.com>
 <CAMRc=MfkQuaJ3FnVwbVKQRQEgmJKbZh7SJoK3Kbmb5ebzE2rKA@mail.gmail.com>
Message-ID: <50ab0f43-9dd0-414c-b722-a406e04d9a48@linaro.org>

On 22/02/2024 13:50, Bartosz Golaszewski wrote:
> On Thu, Feb 22, 2024 at 1:47?PM Dmitry Baryshkov
> <dmitry.baryshkov at linaro.org> wrote:
>>
>> On Thu, 22 Feb 2024 at 14:27, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>>>
>>> On Thu, Feb 22, 2024 at 12:27?PM Dmitry Baryshkov
>>> <dmitry.baryshkov at linaro.org> wrote:
>>>>
>>>> On Thu, 22 Feb 2024 at 13:00, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>>>>>
>>>>> On Mon, Feb 19, 2024 at 11:21?PM Dmitry Baryshkov
>>>>> <dmitry.baryshkov at linaro.org> wrote:
>>>>>>
>>>>>> On Mon, 19 Feb 2024 at 19:18, <neil.armstrong at linaro.org> wrote:
>>>>>>>
>>>>>>> On 19/02/2024 13:33, Dmitry Baryshkov wrote:
>>>>>>>> On Mon, 19 Feb 2024 at 14:23, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>>>>>>>>>
>>>>>>>>> On Mon, Feb 19, 2024 at 11:26?AM Dmitry Baryshkov
>>>>>>>>> <dmitry.baryshkov at linaro.org> wrote:
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> [snip]
>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> For WCN7850 we hide the existence of the PMU as modeling it is simply not
>>>>>>>>>>>>>>> necessary. The BT and WLAN devices on the device-tree are represented as
>>>>>>>>>>>>>>> consuming the inputs (relevant to the functionality of each) of the PMU
>>>>>>>>>>>>>>> directly.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> We are describing the hardware. From the hardware point of view, there
>>>>>>>>>>>>>> is a PMU. I think at some point we would really like to describe all
>>>>>>>>>>>>>> Qualcomm/Atheros WiFI+BT units using this PMU approach, including the
>>>>>>>>>>>>>> older ath10k units present on RB3 (WCN3990) and db820c (QCA6174).
>>>>>>>>>>>>>
>>>>>>>>>>>>> While I agree with older WiFi+BT units, I don't think it's needed for
>>>>>>>>>>>>> WCN7850 since BT+WiFi are now designed to be fully independent and PMU is
>>>>>>>>>>>>> transparent.
>>>>>>>>>>>>
>>>>>>>>>>>> I don't see any significant difference between WCN6750/WCN6855 and
>>>>>>>>>>>> WCN7850 from the PMU / power up point of view. Could you please point
>>>>>>>>>>>> me to the difference?
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> The WCN7850 datasheet clearly states there's not contraint on the WLAN_EN
>>>>>>>>>>> and BT_EN ordering and the only requirement is to have all input regulators
>>>>>>>>>>> up before pulling up WLAN_EN and/or BT_EN.
>>>>>>>>>>>
>>>>>>>>>>> This makes the PMU transparent and BT and WLAN can be described as independent.
>>>>>>>>>>
>>>>>>>>>>  From the hardware perspective, there is a PMU. It has several LDOs. So
>>>>>>>>>> the device tree should have the same style as the previous
>>>>>>>>>> generations.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> My thinking was this: yes, there is a PMU but describing it has no
>>>>>>>>> benefit (unlike QCA6x90). If we do describe, then we'll end up having
>>>>>>>>> to use pwrseq here despite it not being needed because now we won't be
>>>>>>>>> able to just get regulators from WLAN/BT drivers directly.
>>>>>>>>>
>>>>>>>>> So I also vote for keeping it this way. Let's go into the package
>>>>>>>>> detail only if it's required.
>>>>>>>>
>>>>>>>> The WiFi / BT parts are not powered up by the board regulators. They
>>>>>>>> are powered up by the PSU. So we are not describing it in the accurate
>>>>>>>> way.
>>>>>>>
>>>>>>> I disagree, the WCN7850 can also be used as a discrete PCIe M.2 card, and in
>>>>>>> this situation the PCIe part is powered with the M.2 slot and the BT side
>>>>>>> is powered separately as we currently do it now.
>>>>>>
>>>>>> QCA6390 can also be used as a discrete M.2 card.
>>>>>>
>>>>>>> So yes there's a PMU, but it's not an always visible hardware part, from the
>>>>>>> SoC PoV, only the separate PCIe and BT subsystems are visible/controllable/powerable.
>>>>>>
>>>>>> From the hardware point:
>>>>>> - There is a PMU
>>>>>> - The PMU is connected to the board supplies
>>>>>> - Both WiFi and BT parts are connected to the PMU
>>>>>> - The BT_EN / WLAN_EN pins are not connected to the PMU
>>>>>>
>>>>>> So, not representing the PMU in the device tree is a simplification.
>>>>>>
>>>>>
>>>>> What about the existing WLAN and BT users of similar packages? We
>>>>> would have to deprecate a lot of existing bindings. I don't think it's
>>>>> worth it.
>>>>
>>>> We have bindings that are not reflecting the hardware. So yes, we
>>>> should gradually update them once the powerseq is merged.
>>>>
>>>>> The WCN7850 is already described in bindings as consuming what is PMUs
>>>>> inputs and not its outputs.
>>>>
>>>> So do WCN6855 and QCA6391 BlueTooth parts.
>>>>
>>>
>>> That is not true for the latter, this series is adding regulators for it.
>>
>> But the bindings exist already, so you still have to extend it,
>> deprecating regulator-less bindings.
>>
>> Bartosz, I really don't understand what is the issue there. There is a
>> PMU. As such it should be represented in the DT and it can be handled
>> by the same driver as you are adding for QCA6390.
>>
> 
> The issue is that we'll pull in the pwrseq subsystem for WCN7850 which
> clearly does not require it in practice.
> 
> I'd like to hear Krzysztof, Conor or Rob chime in here and make the
> decision on how to proceed.

There's like 12 emails here, so please don't just point "MR X, please
read everything to find the question I want to ask", but just ask the
question with short intro. We all (and I bet you as well) are way too
busy to read long threads...

If I got it correctly, you ask if some other, existing QCA/WCN chips
should be changed to this PMU approach?

If yes, then:
1. It depends whether they have the PMU, so some sort of analysis of
datasheet should be done.
2. You could but you don't have to. Bindings were done, they represent
the hardware more-or-less, maybe less, but still good enough.
3. It does not have to impact actual behavior of Linux. You don't have
to bind entire pwrseq driver to that QCA/WCN compatible. Anyway Linux
behavior is here a bit separate question - it can change, it can stay
the same, up to you.

Best regards,
Krzysztof



From sergei.shtylyov at gmail.com  Sat Feb 24 01:08:58 2024
From: sergei.shtylyov at gmail.com (Sergei Shtylyov)
Date: Sat, 24 Feb 2024 12:08:58 +0300
Subject: [PATCH v3 4/8] usb: cdns3-ti: support reset-on-resume behavior
In-Reply-To: <20240223-j7200-usb-suspend-v3-4-b41c9893a130@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
 <20240223-j7200-usb-suspend-v3-4-b41c9893a130@bootlin.com>
Message-ID: <b778d2e8-3fcf-afe4-2e48-0348be19a085@gmail.com>

On 2/23/24 7:05 PM, Th?o Lebrun wrote:

> Add match data support, with one boolean to indicate whether the
> hardware resets after a system-wide suspend. If hardware resets, we
> force execute ->runtime_resume() at system-wide resume to run the
> hardware init sequence.
> 
> No compatible exploits this functionality, just yet.
> 
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> ---
>  drivers/usb/cdns3/cdns3-ti.c | 27 +++++++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c
> index 4c8a557e6a6f..f76327566798 100644
> --- a/drivers/usb/cdns3/cdns3-ti.c
> +++ b/drivers/usb/cdns3/cdns3-ti.c
[...]
> @@ -220,8 +226,29 @@ static int cdns_ti_runtime_resume(struct device *dev)
>  	return 0;
>  }
>  
> +static int cdns_ti_suspend(struct device *dev)
> +{
> +	struct cdns_ti *data = dev_get_drvdata(dev);
> +
> +	if (data->match_data && data->match_data->reset_on_resume)
> +		return pm_runtime_force_suspend(dev);
> +	else

   Pointless *else* after *return*...

> +		return 0;
> +}
> +
> +static int cdns_ti_resume(struct device *dev)
> +{
> +	struct cdns_ti *data = dev_get_drvdata(dev);
> +
> +	if (data->match_data && data->match_data->reset_on_resume)
> +		return pm_runtime_force_resume(dev);
> +	else

   Here as well...

> +		return 0;
> +}
> +
>  static const struct dev_pm_ops cdns_ti_pm_ops = {
>  	RUNTIME_PM_OPS(NULL, cdns_ti_runtime_resume, NULL)
> +	SYSTEM_SLEEP_PM_OPS(cdns_ti_suspend, cdns_ti_resume)
>  };
>  
>  static const struct of_device_id cdns_ti_of_match[] = {

MBR, Sergey


From lkp at intel.com  Sat Feb 24 01:12:20 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 24 Feb 2024 17:12:20 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS
 dcb8e53e339e534eecfd86fb21674d7eef7380eb
Message-ID: <202402241717.nfoAOWru-lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: dcb8e53e339e534eecfd86fb21674d7eef7380eb  Merge tag 'renesas-fixes-for-v6.8-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into arm/fixes

elapsed time: 1142m

configs tested: 173
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig   gcc  
alpha                            allyesconfig   gcc  
alpha                               defconfig   gcc  
arc                              allmodconfig   gcc  
arc                               allnoconfig   gcc  
arc                              allyesconfig   gcc  
arc                                 defconfig   gcc  
arc                   randconfig-001-20240224   gcc  
arc                   randconfig-002-20240224   gcc  
arm                              allmodconfig   gcc  
arm                               allnoconfig   clang
arm                              allyesconfig   gcc  
arm                     am200epdkit_defconfig   gcc  
arm                          collie_defconfig   gcc  
arm                                 defconfig   clang
arm                            hisi_defconfig   gcc  
arm                             pxa_defconfig   gcc  
arm                   randconfig-001-20240224   gcc  
arm                   randconfig-002-20240224   gcc  
arm                   randconfig-003-20240224   gcc  
arm                   randconfig-004-20240224   gcc  
arm                          sp7021_defconfig   gcc  
arm                           u8500_defconfig   gcc  
arm                         wpcm450_defconfig   gcc  
arm64                            allmodconfig   clang
arm64                             allnoconfig   gcc  
arm64                               defconfig   gcc  
arm64                 randconfig-001-20240224   gcc  
arm64                 randconfig-002-20240224   gcc  
csky                             allmodconfig   gcc  
csky                              allnoconfig   gcc  
csky                             allyesconfig   gcc  
csky                                defconfig   gcc  
csky                  randconfig-001-20240224   gcc  
csky                  randconfig-002-20240224   gcc  
hexagon                          allmodconfig   clang
hexagon                           allnoconfig   clang
hexagon                          allyesconfig   clang
hexagon                             defconfig   clang
i386                             allmodconfig   gcc  
i386                              allnoconfig   gcc  
i386                             allyesconfig   gcc  
i386         buildonly-randconfig-002-20240224   clang
i386         buildonly-randconfig-005-20240224   clang
i386         buildonly-randconfig-006-20240224   clang
i386                                defconfig   clang
i386                  randconfig-002-20240224   clang
i386                  randconfig-003-20240224   clang
i386                  randconfig-013-20240224   clang
i386                  randconfig-014-20240224   clang
i386                  randconfig-015-20240224   clang
i386                  randconfig-016-20240224   clang
loongarch                        alldefconfig   gcc  
loongarch                        allmodconfig   gcc  
loongarch                         allnoconfig   gcc  
loongarch                        allyesconfig   gcc  
loongarch                           defconfig   gcc  
loongarch             randconfig-001-20240224   gcc  
loongarch             randconfig-002-20240224   gcc  
m68k                             allmodconfig   gcc  
m68k                              allnoconfig   gcc  
m68k                             allyesconfig   gcc  
m68k                                defconfig   gcc  
m68k                        m5407c3_defconfig   gcc  
m68k                       m5475evb_defconfig   gcc  
microblaze                       allmodconfig   gcc  
microblaze                        allnoconfig   gcc  
microblaze                       allyesconfig   gcc  
microblaze                          defconfig   gcc  
mips                             allmodconfig   gcc  
mips                              allnoconfig   gcc  
mips                             allyesconfig   gcc  
mips                         bigsur_defconfig   gcc  
mips                       bmips_be_defconfig   gcc  
mips                  cavium_octeon_defconfig   gcc  
mips                      fuloong2e_defconfig   gcc  
mips                           ip28_defconfig   gcc  
mips                      maltasmvp_defconfig   gcc  
mips                          rm200_defconfig   gcc  
nios2                            allmodconfig   gcc  
nios2                             allnoconfig   gcc  
nios2                            allyesconfig   gcc  
nios2                               defconfig   gcc  
nios2                 randconfig-001-20240224   gcc  
nios2                 randconfig-002-20240224   gcc  
openrisc                         allmodconfig   gcc  
openrisc                          allnoconfig   gcc  
openrisc                         allyesconfig   gcc  
openrisc                            defconfig   gcc  
openrisc                    or1ksim_defconfig   gcc  
openrisc                 simple_smp_defconfig   gcc  
openrisc                       virt_defconfig   gcc  
parisc                           allmodconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                           allyesconfig   gcc  
parisc                              defconfig   gcc  
parisc                generic-64bit_defconfig   gcc  
parisc                randconfig-001-20240224   gcc  
parisc                randconfig-002-20240224   gcc  
parisc64                            defconfig   gcc  
powerpc                          allmodconfig   gcc  
powerpc                           allnoconfig   gcc  
powerpc                          allyesconfig   clang
powerpc                     ksi8560_defconfig   gcc  
powerpc                    mvme5100_defconfig   gcc  
powerpc                     powernv_defconfig   gcc  
powerpc64             randconfig-001-20240224   gcc  
powerpc64             randconfig-003-20240224   gcc  
riscv                            allmodconfig   clang
riscv                             allnoconfig   gcc  
riscv                            allyesconfig   clang
riscv                               defconfig   clang
riscv                 randconfig-001-20240224   gcc  
s390                             allmodconfig   clang
s390                              allnoconfig   clang
s390                             allyesconfig   gcc  
s390                                defconfig   clang
s390                  randconfig-001-20240224   gcc  
s390                  randconfig-002-20240224   gcc  
sh                               allmodconfig   gcc  
sh                                allnoconfig   gcc  
sh                               allyesconfig   gcc  
sh                                  defconfig   gcc  
sh                ecovec24-romimage_defconfig   gcc  
sh                          landisk_defconfig   gcc  
sh                     magicpanelr2_defconfig   gcc  
sh                    randconfig-001-20240224   gcc  
sh                    randconfig-002-20240224   gcc  
sh                          rsk7201_defconfig   gcc  
sh                   rts7751r2dplus_defconfig   gcc  
sh                           se7721_defconfig   gcc  
sparc                            allmodconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                            allyesconfig   gcc  
sparc                               defconfig   gcc  
sparc64                          allmodconfig   gcc  
sparc64                          allyesconfig   gcc  
sparc64                             defconfig   gcc  
sparc64               randconfig-001-20240224   gcc  
sparc64               randconfig-002-20240224   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                               allyesconfig   gcc  
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                    randconfig-001-20240224   gcc  
um                           x86_64_defconfig   clang
x86_64                            allnoconfig   clang
x86_64                           allyesconfig   clang
x86_64       buildonly-randconfig-001-20240224   clang
x86_64       buildonly-randconfig-002-20240224   clang
x86_64       buildonly-randconfig-003-20240224   clang
x86_64       buildonly-randconfig-004-20240224   clang
x86_64       buildonly-randconfig-005-20240224   clang
x86_64       buildonly-randconfig-006-20240224   clang
x86_64                              defconfig   gcc  
x86_64                randconfig-001-20240224   clang
x86_64                randconfig-003-20240224   clang
x86_64                randconfig-006-20240224   clang
x86_64                randconfig-014-20240224   clang
x86_64                randconfig-015-20240224   clang
x86_64                randconfig-016-20240224   clang
x86_64                randconfig-072-20240224   clang
x86_64                randconfig-073-20240224   clang
x86_64                randconfig-076-20240224   clang
x86_64                          rhel-8.3-rust   clang
x86_64                               rhel-8.3   gcc  
xtensa                            allnoconfig   gcc  
xtensa                           allyesconfig   gcc  
xtensa                generic_kc705_defconfig   gcc  
xtensa                  nommu_kc705_defconfig   gcc  
xtensa                randconfig-001-20240224   gcc  
xtensa                randconfig-002-20240224   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From oliver.upton at linux.dev  Sat Feb 24 01:12:51 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Sat, 24 Feb 2024 09:12:51 +0000
Subject: [PATCH 5/8] KVM: arm64: Fix typos
In-Reply-To: <2cd87332-b3f9-e415-6458-57eb3615c43e@linux.dev>
References: <20240103231605.1801364-1-helgaas@kernel.org>
 <20240103231605.1801364-6-helgaas@kernel.org>
 <2cd87332-b3f9-e415-6458-57eb3615c43e@linux.dev>
Message-ID: <ZdmzE_Yg4EAv8cAn@linux.dev>

On Sat, Feb 24, 2024 at 12:39:34PM +0800, Zenghui Yu wrote:
> On 2024/1/4 07:16, Bjorn Helgaas wrote:
> > From: Bjorn Helgaas <bhelgaas at google.com>
> > 
> > Fix typos, most reported by "codespell arch/arm64".  Only touches comments,
> > no code changes.
> > 
> > Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> > Cc: James Morse <james.morse at arm.com>
> > Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> > Cc: Zenghui Yu <yuzenghui at huawei.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: kvmarm at lists.linux.dev
> 
> Oliver, mind taking it into 6.9?

Thanks for the nudge!

-- 
Thanks,
Oliver


From oliver.upton at linux.dev  Sat Feb 24 01:15:35 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Sat, 24 Feb 2024 09:15:35 +0000
Subject: (subset) [PATCH 5/8] KVM: arm64: Fix typos
In-Reply-To: <20240103231605.1801364-6-helgaas@kernel.org>
References: <20240103231605.1801364-1-helgaas@kernel.org> <20240103231605.1801364-6-helgaas@kernel.org>
Message-ID: <170876611826.323614.1992753993268344387.b4-ty@linux.dev>

On Wed, 3 Jan 2024 17:16:02 -0600, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
> 
> Fix typos, most reported by "codespell arch/arm64".  Only touches comments,
> no code changes.
> 
> 

Applied to kvmarm/next, thanks!

[5/8] KVM: arm64: Fix typos
      https://git.kernel.org/kvmarm/kvmarm/c/75841d89f3ed

--
Best,
Oliver


From krzysztof.kozlowski at linaro.org  Sat Feb 24 02:20:29 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 24 Feb 2024 11:20:29 +0100
Subject: [PATCH v2 1/7] dt-bindings: clock: Add Qcom QCM2290 GPUCC
In-Reply-To: <20240219-topic-rb1_gpu-v2-1-2d3d6a0db040@linaro.org>
References: <20240219-topic-rb1_gpu-v2-0-2d3d6a0db040@linaro.org>
 <20240219-topic-rb1_gpu-v2-1-2d3d6a0db040@linaro.org>
Message-ID: <133c1185-8e13-4471-8e00-8968b38df970@linaro.org>

On 23/02/2024 22:21, Konrad Dybcio wrote:
> Add device tree bindings for graphics clock controller for Qualcomm
> Technology Inc's QCM2290 SoCs.
> 
> Signed-off-by: Konrad Dybcio <konrad.dybcio at linaro.org>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From maz at kernel.org  Sat Feb 24 02:30:04 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 24 Feb 2024 10:30:04 +0000
Subject: [PATCH 2/3] irqchip/gic-v3-its: Spin off GICv4 init into a separate function
In-Reply-To: <20240219185809.286724-3-oliver.upton@linux.dev>
References: <20240219185809.286724-1-oliver.upton@linux.dev>
	<20240219185809.286724-3-oliver.upton@linux.dev>
Message-ID: <87cysm9mtv.wl-maz@kernel.org>

On Mon, 19 Feb 2024 18:58:07 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> Burying the GICv4 redistributor initialization into the routine for LPIs
> is a bit confusing, and can lead to sillies where unexpected codepaths
> may not fully initialize the RD.
> 
> Hoist it out of its_cpu_init_lpis() into a dedicated function.
> 
> Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 32 +++++++++++++++++++++-----------
>  1 file changed, 21 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 0022852ce494..63d1743f08cc 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -3173,8 +3173,25 @@ static void its_cpu_init_lpis(void)
>  	writel_relaxed(val, rbase + GICR_CTLR);
>  
>  out:
> -	if (gic_rdists->has_vlpis && !gic_rdists->has_rvpeid) {
> +	/* Make sure the GIC has seen the above */
> +	dsb(sy);

So having hoisted the dsb() here...

> +	gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED;
> +	pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n",
> +		smp_processor_id(),
> +		gic_data_rdist()->flags & RD_LOCAL_PENDTABLE_PREALLOCATED ?
> +		"reserved" : "allocated",
> +		&paddr);
> +}
> +
> +static void its_cpu_init_vlpis(void)
> +{
> +	/* No vLPIs? No problem. */
> +	if (!gic_rdists->has_vlpis)
> +		return;
> +
> +	if (!gic_rdists->has_rvpeid) {
>  		void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
> +		u64 val;
>  
>  		/*
>  		 * It's possible for CPU to receive VLPIs before it is
> @@ -3193,7 +3210,8 @@ static void its_cpu_init_lpis(void)
>  		 * ancient programming gets left in and has possibility of
>  		 * corrupting memory.
>  		 */
> -		val = its_clear_vpend_valid(vlpi_base, 0, 0);
> +		its_clear_vpend_valid(vlpi_base, 0, 0);
> +		return;

I'm not sure about the necessity of this return statement.
allocate_vpe_l1_table() checks for rvpeid already, so it should be
fine to carry on.

>  	}
>  
>  	if (allocate_vpe_l1_table()) {
> @@ -3205,15 +3223,6 @@ static void its_cpu_init_lpis(void)
>  		gic_rdists->has_rvpeid = false;
>  		gic_rdists->has_vlpis = false;
>  	}
> -
> -	/* Make sure the GIC has seen the above */
> -	dsb(sy);

... we're now missing a dsb affecting the VPE table programming, as we
expect things to take effect immediately.

> -	gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED;
> -	pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n",
> -		smp_processor_id(),
> -		gic_data_rdist()->flags & RD_LOCAL_PENDTABLE_PREALLOCATED ?
> -		"reserved" : "allocated",
> -		&paddr);
>  }
>  
>  static void its_cpu_init_collection(struct its_node *its)
> @@ -5265,6 +5274,7 @@ int its_cpu_init(void)
>  			return ret;
>  
>  		its_cpu_init_lpis();
> +		its_cpu_init_vlpis();
>  		its_cpu_init_collections();
>  	}
>  

I'm otherwise OK with the idea of splitting things up.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From krzk at kernel.org  Sat Feb 24 02:31:07 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 24 Feb 2024 11:31:07 +0100
Subject: [PATCH v2 1/5] dt-bindings: sound: Add jack-type property to
 sun8i-a33-codec
In-Reply-To: <20240223015219.3618111-2-megi@xff.cz>
References: <20240223015219.3618111-1-megi@xff.cz>
 <20240223015219.3618111-2-megi@xff.cz>
Message-ID: <42d3ac7d-4b51-4332-8892-a4f03a315a80@kernel.org>

On 23/02/2024 02:52, Ond?ej Jirman wrote:
> From: Ondrej Jirman <megi at xff.cz>
> 
> The codec driver needs to know what jack connector is connected to
> on the board. Add proprty to describe the type of connector.
> 
> Signed-off-by: Ondrej Jirman <megi at xff.cz>
> ---

Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline), work on fork of kernel
(don't, instead use mainline) or you ignore some maintainers (really
don't). Just use b4 and everything should be fine, although remember
about `b4 prep --auto-to-cc` if you added new patches to the patchset.

You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time, thus I will skip this patch entirely till you follow
the process allowing the patch to be tested.

Please kindly resend and include all necessary To/Cc entries.


Best regards,
Krzysztof



From zev at bewilderbeest.net  Sat Feb 24 02:37:07 2024
From: zev at bewilderbeest.net (Zev Weiss)
Date: Sat, 24 Feb 2024 02:37:07 -0800
Subject: [PATCH] ARM: dts: aspeed: Add vendor prefixes to lm25066 compat strings
Message-ID: <20240224103712.20864-2-zev@bewilderbeest.net>

Due to the way i2c driver matching works (falling back to the driver's
id_table if of_match_table fails) this didn't actually cause any
misbehavior, but let's add the vendor prefixes so things actually work
the way they were intended to.

Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts | 4 ++--
 arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts    | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
index 4554abf0c7cd..9aa2de3723b5 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
@@ -98,14 +98,14 @@ w83773g at 4c {
 
 	/* IPB PMIC */
 	lm25066 at 40 {
-		compatible = "lm25066";
+		compatible = "ti,lm25066";
 		reg = <0x40>;
 		shunt-resistor-micro-ohms = <1000>;
 	};
 
 	/* 12VSB PMIC */
 	lm25066 at 41 {
-		compatible = "lm25066";
+		compatible = "ti,lm25066";
 		reg = <0x41>;
 		shunt-resistor-micro-ohms = <10000>;
 	};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
index 6600f7e9bf5e..e830fec0570f 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
@@ -14,7 +14,7 @@ efuse##n {					\
 
 #define EFUSE(hexaddr, num)							\
 	efuse@##hexaddr {							\
-		compatible = "lm25066";						\
+		compatible = "ti,lm25066";					\
 		reg = <0x##hexaddr>;						\
 		shunt-resistor-micro-ohms = <675>;				\
 		regulators {							\
-- 
2.43.2



From maz at kernel.org  Sat Feb 24 02:41:36 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 24 Feb 2024 10:41:36 +0000
Subject: [PATCH 3/3] irqchip/gic-v3-its: Print the vPE table installed in redistributor
In-Reply-To: <20240219185809.286724-4-oliver.upton@linux.dev>
References: <20240219185809.286724-1-oliver.upton@linux.dev>
	<20240219185809.286724-4-oliver.upton@linux.dev>
Message-ID: <87bk869man.wl-maz@kernel.org>

On Mon, 19 Feb 2024 18:58:08 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> Hindsight is 20/20 of course, but the recent vPE table programming bug
> could've been root caused a bit more quickly if we print the table
> getting installed at every redistributor.
> 
> Promote to pr_info() and add some additional context, such as the
> provenance of the installed vPE table.
> 
> Signed-off-by: Oliver Upton <oliver.upton at linux.dev>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 63d1743f08cc..c3ef9665a2ad 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -2835,7 +2835,8 @@ static int allocate_vpe_l1_table(void)
>  	u64 val, gpsz, npg, pa;
>  	unsigned int psz = SZ_64K;
>  	unsigned int np, epp, esz;
> -	struct page *page;
> +	struct page *page = NULL;
> +	bool from_its = false;
>  
>  	if (!gic_rdists->has_rvpeid)
>  		return 0;
> @@ -2865,8 +2866,10 @@ static int allocate_vpe_l1_table(void)
>  		return -ENOMEM;
>  
>  	val = inherit_vpe_l1_table_from_its();
> -	if (val & GICR_VPROPBASER_4_1_VALID)
> +	if (val & GICR_VPROPBASER_4_1_VALID) {
> +		from_its = true;
>  		goto out;
> +	}

nit:
	from_its = val & GICR_VPROPBASER_4_1_VALID;
	if (from_its)
		...

>  
>  	/* First probe the page size */
>  	val = FIELD_PREP(GICR_VPROPBASER_4_1_PAGE_SIZE, GIC_PAGE_SIZE_64K);
> @@ -2945,9 +2948,12 @@ static int allocate_vpe_l1_table(void)
>  	gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
>  	cpumask_set_cpu(smp_processor_id(), gic_data_rdist()->vpe_table_mask);
>  
> -	pr_debug("CPU%d: VPROPBASER = %llx %*pbl\n",
> -		 smp_processor_id(), val,
> -		 cpumask_pr_args(gic_data_rdist()->vpe_table_mask));
> +	pr_info("CPU%d: Using %s vPE table @%llx (%s)\n",
> +		smp_processor_id(),
> +		(val & GICR_VPROPBASER_4_1_INDIRECT) ? "indirect" : "direct",
> +		val & GICR_VPROPBASER_4_1_ADDR,
> +		(page) ? "allocated" :
> +			 ((from_its) ? "inherited from ITS" : "inherited from RD"));

From past experience, having the vpe_table_mask value displayed did
help tracking VPE table affinity bugs.

This said, my problem with this patch is that we already have tons of
these statement printed once per CPU/RD. This is really huge and
accounts for a significant part of the boot time on large machines
(64+ CPUs).

Before we add more of those, I'd really want to have a way to tone
them down and only print them at runtime *if* required by the user.
Kind of a dymanic debug, but driven from the command-line and present
early enough.

What do you think?

	M.

-- 
Without deviation from the norm, progress is not possible.


From chester62515 at gmail.com  Sat Feb 24 02:44:55 2024
From: chester62515 at gmail.com (Chester Lin)
Date: Sat, 24 Feb 2024 18:44:55 +0800
Subject: [PATCH v2 2/2] arm64: dts: s32g: add uSDHC node
In-Reply-To: <ZdmnQTtUxOEUy06L@linux-8mug>
References: <20240122140602.1006813-1-ghennadi.procopciuc@oss.nxp.com>
 <20240122140602.1006813-3-ghennadi.procopciuc@oss.nxp.com>
 <ZdmnQTtUxOEUy06L@linux-8mug>
Message-ID: <ZdnIp8PPtfbuIzwP@linux-8mug>

Hi Ghennadi,

On Sat, Feb 24, 2024 at 04:22:30PM +0800, Chester Lin wrote:
> Hi Ghennadi,
> 
> On Mon, Jan 22, 2024 at 04:06:01PM +0200, Ghennadi Procopciuc wrote:
> > From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> > 
> > Add the uSDHC node for the boards that are based on S32G SoCs.
> > 
> > Signed-off-by: Ciprian Costea <ciprianmarian.costea at nxp.com>
> > Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
> > ---
> >  arch/arm64/boot/dts/freescale/s32g2.dtsi        | 10 ++++++++++
> >  arch/arm64/boot/dts/freescale/s32g274a-evb.dts  |  6 +++++-
> >  arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts |  6 +++++-
> >  3 files changed, 20 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > index ef1a1d61f2ba..fc19ae2e8d3b 100644
> > --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > @@ -138,6 +138,16 @@ uart2: serial at 402bc000 {
> >  			status = "disabled";
> >  		};
> >  
> > +		usdhc0: mmc at 402f0000 {
> > +			compatible = "nxp,s32g2-usdhc";
> > +			reg = <0x402f0000 0x1000>;
> > +			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&clks 32>, <&clks 31>, <&clks 33>;
> 
> Same as I have mentioned in [PATCH v2 1/2], could we have fixed dt-bindings to
> replace with these raw clock id values (32, 31, 33)?
> 

Just found the previous review discussion in v1:
https://lore.kernel.org/all/f54d947c-58dc-498f-8871-b472f97be4a8 at oss.nxp.com/

What I'm worried is that, could these raw clock IDs be rearranged in the
downstream TF-A? If so it would cause ABI inconsistency and clock issues
since the kernel is not aware of any raw ID changes in downstream TF-A.

Chester

> > +			clock-names = "ipg", "ahb", "per";
> > +			bus-width = <8>;
> > +			status = "disabled";
> > +		};
> > +
> >  		gic: interrupt-controller at 50800000 {
> >  			compatible = "arm,gic-v3";
> >  			reg = <0x50800000 0x10000>,
> > diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> > index 9118d8d2ee01..00070c949e2a 100644
> > --- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> > +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> > @@ -1,7 +1,7 @@
> >  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> >  /*
> >   * Copyright (c) 2021 SUSE LLC
> > - * Copyright (c) 2019-2021 NXP
> > + * Copyright 2019-2021, 2024 NXP
> >   */
> >  
> >  /dts-v1/;
> > @@ -32,3 +32,7 @@ memory at 80000000 {
> >  &uart0 {
> >  	status = "okay";
> >  };
> > +
> > +&usdhc0 {
> > +	status = "okay";
> > +};
> > diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> > index e05ee854cdf5..b3fc12899cae 100644
> > --- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> > +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> > @@ -1,7 +1,7 @@
> >  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> >  /*
> >   * Copyright (c) 2021 SUSE LLC
> > - * Copyright (c) 2019-2021 NXP
> > + * Copyright 2019-2021, 2024 NXP
> >   */
> >  
> >  /dts-v1/;
> > @@ -38,3 +38,7 @@ &uart0 {
> >  &uart1 {
> >  	status = "okay";
> >  };
> > +
> > +&usdhc0 {
> > +	status = "okay";
> > +};
> > -- 
> > 2.43.0
> > 


From leif.middelschulte at gmail.com  Sat Feb 24 03:00:02 2024
From: leif.middelschulte at gmail.com (Leif Middelschulte)
Date: Sat, 24 Feb 2024 12:00:02 +0100
Subject: [PATCH v3 1/4] pwm: imx27: fix race condition .apply,.get_state
In-Reply-To: <20230906154215.4ikrrbx4xgx2nmu5@pengutronix.de>
References: <20230310174517.rb7xxrougkse2lrc@pengutronix.de>
 <20230815104332.55044-1-Leif.Middelschulte@gmail.com>
 <20230906154215.4ikrrbx4xgx2nmu5@pengutronix.de>
Message-ID: <294551D8-53E1-489E-A043-09714722C4EA@gmail.com>


> Am 06.09.2023 um 17:42 schrieb Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>:
> 
> On Tue, Aug 15, 2023 at 12:43:29PM +0200, Leif Middelschulte wrote:
>> From: Leif Middelschulte <Leif.Middelschulte at klsmartin.com>
>> 
>> With CONFIG_PWM_DEBUG=y after writing a value to the PWMSAR
>> register in .apply(), the register is read in .get_state().
>> Unless a period completed in the meantime, this read yields the
>> previously used duty cycle configuration. As the PWM_DEBUG code
>> applies the read out configuration for testing purposes this
>> effectively undoes the intended effect by rewriting the previous
>> hardware state.
>> 
>> Note that this change merely implements a sensible heuristic.
>> The i.MX has a 4 slot FIFO to configure the duty cycle. This FIFO
>> cannot be read back in its entirety. The "write x then read back
>> x from hw" semantics are therefore not easily applicable.
>> With this change, the .get_state() function tries to wait for some
>> stabilization in the FIFO (empty state). In this state it keeps
>> applying the last value written to the sample register.
>> 
>> Signed-off-by: Leif Middelschulte <Leif.Middelschulte at klsmartin.com>
>> ---
>> drivers/pwm/pwm-imx27.c | 50 ++++++++++++++++++++++++++++++++++++++---
>> 1 file changed, 47 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
>> index 29a3089c534c..32389ca2da3e 100644
>> --- a/drivers/pwm/pwm-imx27.c
>> +++ b/drivers/pwm/pwm-imx27.c
>> @@ -75,6 +75,7 @@
>>   (x)) + 1)
>> 
>> #define MX3_PWM_SWR_LOOP 5
>> +#define MX3_PWM_FIFOAV_EMPTY_LOOP 4
>> 
>> /* PWMPR register value of 0xffff has the same effect as 0xfffe */
>> #define MX3_PWMPR_MAX 0xfffe
>> @@ -118,8 +119,28 @@ static void pwm_imx27_clk_disable_unprepare(struct pwm_imx27_chip *imx)
>> clk_disable_unprepare(imx->clk_ipg);
>> }
>> 
>> +static int pwm_imx27_wait_fifo_empty(struct pwm_chip *chip,
>> +     struct pwm_device *pwm)
>> +{
>> + struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
>> + struct device *dev = chip->dev;
>> + unsigned int period_ms = DIV_ROUND_UP_ULL(pwm_get_period(pwm), NSEC_PER_MSEC);
>> + int tries = MX3_PWM_FIFOAV_EMPTY_LOOP;
>> + int fifoav;
>> + u32 sr;
>> +
>> + while (tries--) {
>> + sr = readl(imx->mmio_base + MX3_PWMSR);
>> + fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr);
>> + if (fifoav == MX3_PWMSR_FIFOAV_EMPTY)
>> + return;
>> + msleep(period_ms);
>> + }
>> + dev_warn(dev, "FIFO has been refilled concurrently\n");
>> +}
>> +
>> static int pwm_imx27_get_state(struct pwm_chip *chip,
>> -       struct pwm_device *pwm, struct pwm_state *state)
>> + struct pwm_device *pwm, struct pwm_state *state)
> 
> This looks wrong. Aligning at the opening ( was right.

Good catch. That change as unintentional.

> 
>> {
>> struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
>> u32 period, prescaler, pwm_clk, val;
>> @@ -161,10 +182,33 @@ static int pwm_imx27_get_state(struct pwm_chip *chip,
>> * PWMSAR can be read only if PWM is enabled. If the PWM is disabled,
>> * use the cached value.
>> */
>> - if (state->enabled)
>> + if (state->enabled) {
>> + /*
>> + * From the i.MX PWM reference manual:
>> + * "A read on the sample register yields the current FIFO value that
>> + *  is being used, or will be used, by the PWM for generation on the
>> + *  output signal. Therefore, a write and a subsequent read on the
>> + *  sample register may result in different values being obtained."
>> + * Furthermore:
>> + * "When a new value is written, the duty cycle changes after the
>> + *  current period is over."
>> + * Note "changes" vs. "changes to the given value"!
>> + * Finally:
>> + * "The PWM will run at the last set duty-cycle setting if all the
>> + *  values of the FIFO has been utilized, until the FIFO is reloaded
>> + *  or the PWM is disabled."
>> + * Try to be at least a bit more deterministic about which value is
>> + * read by waiting until the FIFO is empty. In this state the last/most
>> + * recently pushed sample (duty cycle) value is continuously applied.
>> + * Beware that this approach is still racy, as a new value could have
>> + * been supplied and a period expired between the call of the wait
>> + * function and the subsequent readl.
> 
> this would only happen if there are concurrent calls into the driver,
> wouldn't it? I think it's safe to assume this doesn't happen.

This assessment seems correct at them moment. This comment is supposed to be a source of explanation to future developers if - for some reason - the driver/subsystem is changed and they trip over this behaviour (again), just as I did.

> 
> Patch 3 of this series improves the function that is only introduced
> here. I suggest to squash these together.

I will provide v4 with the changes squashed into the initial commit, that introduced the function.

> 
> Best regards
> Uwe
> 
> -- 
> Pengutronix e.K.                           | Uwe Kleine-K?nig            |
> Industrial Linux Solutions                 | https://www.pengutronix.de/ |

Thank you,

Leif

From oliver.upton at linux.dev  Sat Feb 24 03:02:40 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Sat, 24 Feb 2024 11:02:40 +0000
Subject: [PATCH 2/3] irqchip/gic-v3-its: Spin off GICv4 init into a
 separate function
In-Reply-To: <87cysm9mtv.wl-maz@kernel.org>
References: <20240219185809.286724-1-oliver.upton@linux.dev>
 <20240219185809.286724-3-oliver.upton@linux.dev>
 <87cysm9mtv.wl-maz@kernel.org>
Message-ID: <ZdnM0DDsGCTPMpwl@linux.dev>

On Sat, Feb 24, 2024 at 10:30:04AM +0000, Marc Zyngier wrote:
> On Mon, 19 Feb 2024 18:58:07 +0000, Oliver Upton <oliver.upton at linux.dev> wrote:
> > @@ -3193,7 +3210,8 @@ static void its_cpu_init_lpis(void)
> >  		 * ancient programming gets left in and has possibility of
> >  		 * corrupting memory.
> >  		 */
> > -		val = its_clear_vpend_valid(vlpi_base, 0, 0);
> > +		its_clear_vpend_valid(vlpi_base, 0, 0);
> > +		return;
> 
> I'm not sure about the necessity of this return statement.
> allocate_vpe_l1_table() checks for rvpeid already, so it should be
> fine to carry on.

Yup, definitely not necessary. My aim was to have the control flow make
it a bit more obvious to the reader what's going on.

Having what reads as an allocation helper do a feature check isn't
entirely obvious.

I have no opinion either way though.

> >  	}
> >  
> >  	if (allocate_vpe_l1_table()) {
> > @@ -3205,15 +3223,6 @@ static void its_cpu_init_lpis(void)
> >  		gic_rdists->has_rvpeid = false;
> >  		gic_rdists->has_vlpis = false;
> >  	}
> > -
> > -	/* Make sure the GIC has seen the above */
> > -	dsb(sy);
> 
> ... we're now missing a dsb affecting the VPE table programming, as we
> expect things to take effect immediately.

LOL, and on the back of a bugfix no less. I'll fix this.

-- 
Thanks,
Oliver


From maz at kernel.org  Sat Feb 24 03:10:21 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 24 Feb 2024 11:10:21 +0000
Subject: [PATCH 2/3] irqchip/gic-v3-its: Spin off GICv4 init into a separate function
In-Reply-To: <ZdnM0DDsGCTPMpwl@linux.dev>
References: <20240219185809.286724-1-oliver.upton@linux.dev>
	<20240219185809.286724-3-oliver.upton@linux.dev>
	<87cysm9mtv.wl-maz@kernel.org>
	<ZdnM0DDsGCTPMpwl@linux.dev>
Message-ID: <87a5nq9kyq.wl-maz@kernel.org>

On Sat, 24 Feb 2024 11:02:40 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Sat, Feb 24, 2024 at 10:30:04AM +0000, Marc Zyngier wrote:
> > On Mon, 19 Feb 2024 18:58:07 +0000, Oliver Upton <oliver.upton at linux.dev> wrote:
> > > @@ -3193,7 +3210,8 @@ static void its_cpu_init_lpis(void)
> > >  		 * ancient programming gets left in and has possibility of
> > >  		 * corrupting memory.
> > >  		 */
> > > -		val = its_clear_vpend_valid(vlpi_base, 0, 0);
> > > +		its_clear_vpend_valid(vlpi_base, 0, 0);
> > > +		return;
> > 
> > I'm not sure about the necessity of this return statement.
> > allocate_vpe_l1_table() checks for rvpeid already, so it should be
> > fine to carry on.
> 
> Yup, definitely not necessary. My aim was to have the control flow make
> it a bit more obvious to the reader what's going on.
> 
> Having what reads as an allocation helper do a feature check isn't
> entirely obvious.
> 
> I have no opinion either way though.

You could move the if (allocate_vpe_l1_table()) as an 'else' branch,
as the two are mutually exclusive.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From oliver.upton at linux.dev  Sat Feb 24 03:11:41 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Sat, 24 Feb 2024 11:11:41 +0000
Subject: [PATCH 3/3] irqchip/gic-v3-its: Print the vPE table installed in
 redistributor
In-Reply-To: <87bk869man.wl-maz@kernel.org>
References: <20240219185809.286724-1-oliver.upton@linux.dev>
 <20240219185809.286724-4-oliver.upton@linux.dev>
 <87bk869man.wl-maz@kernel.org>
Message-ID: <ZdnO7QIYkxgDdl0i@linux.dev>

On Sat, Feb 24, 2024 at 10:41:36AM +0000, Marc Zyngier wrote:
> On Mon, 19 Feb 2024 18:58:08 +0000, Oliver Upton <oliver.upton at linux.dev> wrote:
> > -	pr_debug("CPU%d: VPROPBASER = %llx %*pbl\n",
> > -		 smp_processor_id(), val,
> > -		 cpumask_pr_args(gic_data_rdist()->vpe_table_mask));
> > +	pr_info("CPU%d: Using %s vPE table @%llx (%s)\n",
> > +		smp_processor_id(),
> > +		(val & GICR_VPROPBASER_4_1_INDIRECT) ? "indirect" : "direct",
> > +		val & GICR_VPROPBASER_4_1_ADDR,
> > +		(page) ? "allocated" :
> > +			 ((from_its) ? "inherited from ITS" : "inherited from RD"));
> 
> From past experience, having the vpe_table_mask value displayed did
> help tracking VPE table affinity bugs.

My reasoning behind it was that the change expanded the table mask by
way of printing what's going on at every RD. But easy enough to throw
back in!

> This said, my problem with this patch is that we already have tons of
> these statement printed once per CPU/RD. This is really huge and
> accounts for a significant part of the boot time on large machines
> (64+ CPUs).
> 
> Before we add more of those, I'd really want to have a way to tone
> them down and only print them at runtime *if* required by the user.
> Kind of a dymanic debug, but driven from the command-line and present
> early enough.

Yeah, what'd be really nice is a way to enable pr_debug() on a per
file / driver / whatever basis, since turning on all of it becomes a bit
of a firehose... But I guess that's what grep is for.

WDYT about leaving it at pr_debug() for now, with the additional context
of what exactly VPROPBASE is getting programmend with?

-- 
Thanks,
Oliver


From guohanjun at huawei.com  Sat Feb 24 03:28:39 2024
From: guohanjun at huawei.com (Hanjun Guo)
Date: Sat, 24 Feb 2024 19:28:39 +0800
Subject: [PATCH 2/7] ACPI: AGDI: Convert to platform remove callback
 returning void
In-Reply-To: <c41853160b8947e865357f99171cfbdbb4b4804e.1708627599.git.u.kleine-koenig@pengutronix.de>
References: <cover.1708627599.git.u.kleine-koenig@pengutronix.de>
 <c41853160b8947e865357f99171cfbdbb4b4804e.1708627599.git.u.kleine-koenig@pengutronix.de>
Message-ID: <23789259-f11a-dea0-6dae-f45bcdccbf12@huawei.com>

On 2024/2/23 2:52, Uwe Kleine-K?nig wrote:
> The .remove() callback for a platform driver returns an int which makes
> many driver authors wrongly assume it's possible to do error handling by
> returning an error code. However the value returned is ignored (apart
> from emitting a warning) and this typically results in resource leaks.
> 
> To improve here there is a quest to make the remove callback return
> void. In the first step of this quest all drivers are converted to
> .remove_new(), which already returns void. Eventually after all drivers
> are converted, .remove_new() will be renamed to .remove().
> 
> Trivially convert this driver from always returning zero in the remove
> callback to the void returning variant.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> ---
>   drivers/acpi/arm64/agdi.c | 8 +++-----
>   1 file changed, 3 insertions(+), 5 deletions(-)

Looks good to me,

Acked-by: Hanjun Guo <guohanjun at huawei.com>


From leif.middelschulte at gmail.com  Sat Feb 24 03:29:00 2024
From: leif.middelschulte at gmail.com (Leif Middelschulte)
Date: Sat, 24 Feb 2024 12:29:00 +0100
Subject: [PATCH v4 1/2] pwm: imx27: fix race condition .apply,.get_state
In-Reply-To: <20230906154215.4ikrrbx4xgx2nmu5@pengutronix.de>
References: <20230906154215.4ikrrbx4xgx2nmu5@pengutronix.de>
Message-ID: <20240224112902.55539-1-Leif.Middelschulte@gmail.com>

From: Leif Middelschulte <Leif.Middelschulte at klsmartin.com>

With CONFIG_PWM_DEBUG=y after writing a value to the PWMSAR
register in .apply(), the register is read in .get_state().
Unless a period completed in the meantime, this read yields the
previously used duty cycle configuration. As the PWM_DEBUG code
applies the read out configuration for testing purposes this
effectively undoes the intended effect by rewriting the previous
hardware state.

Note that this change merely implements a sensible heuristic.
The i.MX has a 4 slot FIFO to configure the duty cycle. This FIFO
cannot be read back in its entirety. The "write x then read back
x from hw" semantics are therefore not easily applicable.
With this change, the .get_state() function tries to wait for some
stabilization in the FIFO (empty state). In this state it keeps
applying the last value written to the sample register.

Signed-off-by: Leif Middelschulte <Leif.Middelschulte at klsmartin.com>
---
 drivers/pwm/pwm-imx27.c | 55 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
index 7d9bc43f12b0..cb564460b79c 100644
--- a/drivers/pwm/pwm-imx27.c
+++ b/drivers/pwm/pwm-imx27.c
@@ -75,6 +75,7 @@
 						   (x)) + 1)
 
 #define MX3_PWM_SWR_LOOP		5
+#define MX3_PWM_FIFOAV_EMPTY_LOOP	4
 
 /* PWMPR register value of 0xffff has the same effect as 0xfffe */
 #define MX3_PWMPR_MAX			0xfffe
@@ -118,6 +119,31 @@ static void pwm_imx27_clk_disable_unprepare(struct pwm_imx27_chip *imx)
 	clk_disable_unprepare(imx->clk_ipg);
 }
 
+static int pwm_imx27_wait_fifo_empty(struct pwm_chip *chip,
+				     struct pwm_device *pwm)
+{
+	struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
+	struct device *dev = chip->dev;
+	unsigned int period_ms = DIV_ROUND_UP_ULL(pwm->state.period, NSEC_PER_MSEC);
+	int tries = MX3_PWM_FIFOAV_EMPTY_LOOP;
+	int fifoav, previous_fifoav = INT_MAX;
+	u32 sr;
+
+	while (tries--) {
+		sr = readl(imx->mmio_base + MX3_PWMSR);
+		fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr);
+		if (fifoav == MX3_PWMSR_FIFOAV_EMPTY)
+			return 0;
+		/* if the FIFO value does not decrease, there is another problem */
+		if (previous_fifoav == fifoav)
+			break;
+		previous_fifoav = fifoav;
+		msleep(period_ms);
+	}
+
+	return -EAGAIN;
+}
+
 static int pwm_imx27_get_state(struct pwm_chip *chip,
 			       struct pwm_device *pwm, struct pwm_state *state)
 {
@@ -161,10 +187,35 @@ static int pwm_imx27_get_state(struct pwm_chip *chip,
 	 * PWMSAR can be read only if PWM is enabled. If the PWM is disabled,
 	 * use the cached value.
 	 */
-	if (state->enabled)
+	if (state->enabled) {
+		/*
+		 * From the i.MX PWM reference manual:
+		 * "A read on the sample register yields the current FIFO value that
+		 *  is being used, or will be used, by the PWM for generation on the
+		 *  output signal. Therefore, a write and a subsequent read on the
+		 *  sample register may result in different values being obtained."
+		 * Furthermore:
+		 * "When a new value is written, the duty cycle changes after the
+		 *  current period is over."
+		 * Note "changes" vs. "changes to the given value"!
+		 * Finally:
+		 * "The PWM will run at the last set duty-cycle setting if all the
+		 *  values of the FIFO has been utilized, until the FIFO is reloaded
+		 *  or the PWM is disabled."
+		 * Try to be at least a bit more deterministic about which value is
+		 * read by waiting until the FIFO is empty. In this state the last/most
+		 * recently pushed sample (duty cycle) value is continuously applied.
+		 * Beware that this approach is still racy, as a new value could have
+		 * been supplied and a period expired between the call of the wait
+		 * function and the subsequent readl.
+		 */
+		ret = pwm_imx27_wait_fifo_empty(chip, pwm);
+		if (ret)
+			return ret;
 		val = readl(imx->mmio_base + MX3_PWMSAR);
-	else
+	} else {
 		val = imx->duty_cycle;
+	}
 
 	tmp = NSEC_PER_SEC * (u64)(val) * prescaler;
 	state->duty_cycle = DIV_ROUND_UP_ULL(tmp, pwm_clk);
-- 
2.39.3 (Apple Git-145)



From leif.middelschulte at gmail.com  Sat Feb 24 03:29:01 2024
From: leif.middelschulte at gmail.com (Leif Middelschulte)
Date: Sat, 24 Feb 2024 12:29:01 +0100
Subject: [PATCH v4 2/2] pwm: imx27: avoid PWM consumer API
In-Reply-To: <20240224112902.55539-1-Leif.Middelschulte@gmail.com>
References: <20230906154215.4ikrrbx4xgx2nmu5@pengutronix.de>
 <20240224112902.55539-1-Leif.Middelschulte@gmail.com>
Message-ID: <20240224112902.55539-2-Leif.Middelschulte@gmail.com>

Access struct members directly.

Signed-off-by: Leif Middelschulte <Leif.Middelschulte at gmail.com>
---
 drivers/pwm/pwm-imx27.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
index cb564460b79c..d00d79a5edb1 100644
--- a/drivers/pwm/pwm-imx27.c
+++ b/drivers/pwm/pwm-imx27.c
@@ -255,7 +255,7 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
 	sr = readl(imx->mmio_base + MX3_PWMSR);
 	fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr);
 	if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) {
-		period_ms = DIV_ROUND_UP_ULL(pwm_get_period(pwm),
+		period_ms = DIV_ROUND_UP_ULL(pwm->state.period,
 					 NSEC_PER_MSEC);
 		msleep(period_ms);
 
-- 
2.39.3 (Apple Git-145)



From maz at kernel.org  Sat Feb 24 03:31:05 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 24 Feb 2024 11:31:05 +0000
Subject: [PATCH 3/3] irqchip/gic-v3-its: Print the vPE table installed in redistributor
In-Reply-To: <ZdnO7QIYkxgDdl0i@linux.dev>
References: <20240219185809.286724-1-oliver.upton@linux.dev>
	<20240219185809.286724-4-oliver.upton@linux.dev>
	<87bk869man.wl-maz@kernel.org>
	<ZdnO7QIYkxgDdl0i@linux.dev>
Message-ID: <878r3a9k06.wl-maz@kernel.org>

On Sat, 24 Feb 2024 11:11:41 +0000,
Oliver Upton <oliver.upton at linux.dev> wrote:
> 
> On Sat, Feb 24, 2024 at 10:41:36AM +0000, Marc Zyngier wrote:
> > On Mon, 19 Feb 2024 18:58:08 +0000, Oliver Upton <oliver.upton at linux.dev> wrote:
> > > -	pr_debug("CPU%d: VPROPBASER = %llx %*pbl\n",
> > > -		 smp_processor_id(), val,
> > > -		 cpumask_pr_args(gic_data_rdist()->vpe_table_mask));
> > > +	pr_info("CPU%d: Using %s vPE table @%llx (%s)\n",
> > > +		smp_processor_id(),
> > > +		(val & GICR_VPROPBASER_4_1_INDIRECT) ? "indirect" : "direct",
> > > +		val & GICR_VPROPBASER_4_1_ADDR,
> > > +		(page) ? "allocated" :
> > > +			 ((from_its) ? "inherited from ITS" : "inherited from RD"));
> > 
> > From past experience, having the vpe_table_mask value displayed did
> > help tracking VPE table affinity bugs.
> 
> My reasoning behind it was that the change expanded the table mask by
> way of printing what's going on at every RD. But easy enough to throw
> back in!

Yeah, true enough. But the mask presents a nice, concise way to
express the affinities that comparing a bunch of lines doesn't exactly
convey.

> 
> > This said, my problem with this patch is that we already have tons of
> > these statement printed once per CPU/RD. This is really huge and
> > accounts for a significant part of the boot time on large machines
> > (64+ CPUs).
> > 
> > Before we add more of those, I'd really want to have a way to tone
> > them down and only print them at runtime *if* required by the user.
> > Kind of a dymanic debug, but driven from the command-line and present
> > early enough.
> 
> Yeah, what'd be really nice is a way to enable pr_debug() on a per
> file / driver / whatever basis, since turning on all of it becomes a bit
> of a firehose... But I guess that's what grep is for.
> 
> WDYT about leaving it at pr_debug() for now, with the additional context
> of what exactly VPROPBASE is getting programmend with?

Yup, I'm all for that. Hopefully we can find a good way to way to
control the debug output in the near future.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From guohanjun at huawei.com  Sat Feb 24 03:32:17 2024
From: guohanjun at huawei.com (Hanjun Guo)
Date: Sat, 24 Feb 2024 19:32:17 +0800
Subject: [PATCH v3 0/7] dma-mapping: Simplify arch_setup_dma_ops()
In-Reply-To: <cover.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
Message-ID: <1ae0973c-a440-3f12-6d78-e780ddc0a16d@huawei.com>

On 2024/2/10 0:49, Robin Murphy wrote:
> v2: https://lore.kernel.org/linux-iommu/cover.1702486837.git.robin.murphy at arm.com/
> 
> Hi all,
> 
> Here's v3, rebased and fixing the thinko from v2, so unless anything
> else has changed behind my back I hope it's good to go (via the IOMMU
> tree, as mentioned before).

Compiled with/without ACPI enabled, and test this patch set on an
ARM64 server with ACPI booting, looks good.

Tested-by: Hanjun Guo <guohanjun at huawei.com>

Thanks
Hanjun


From arnd at arndb.de  Sat Feb 24 03:42:30 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 24 Feb 2024 12:42:30 +0100
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <ZdmZ4JC0CsX2qs5C@linux-8mug>
References: <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
 <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
 <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>
 <e6f6070e-8355-4a0b-a904-1a24970f249b@linaro.org>
 <e530d504-dfa3-4d39-b903-b2570bb8b014@suse.com>
 <c3e68c62-b81f-475b-9b15-c983c94aed8b@app.fastmail.com>
 <Zdiu8s5Cgz9s6dLP@dragon> <ZdmZ4JC0CsX2qs5C@linux-8mug>
Message-ID: <57dce440-d24b-4638-9395-62dfb03ec002@app.fastmail.com>

On Sat, Feb 24, 2024, at 08:25, Chester Lin wrote:
> Hi all,
>
> Sorry for the late reply since I lost connection with upstream due to a
> health condition, which affected my eyesights for a while so I tried to use
> my eyes as less as possible. Please accept my apologies anyway.

No worries, and thanks for the clarifications.

> On Fri, Feb 23, 2024 at 10:42:58PM +0800, Shawn Guo wrote:
>> On Fri, Feb 23, 2024 at 01:29:10PM +0100, Arnd Bergmann wrote:
>
> Before leaving SUSE I reached NXP to see if anyone could take over it but I
> didn't get response unfortunately. Maybe it was too rush to find a right person
> at the moment but I still wish that someone can take over this role based on the
> following reasons:
>
> - Since I have returned my S32G boards to SUSE, currently I do not have 
> a platform
> to verify S32G patches unless I could get a new one. I wish I could 
> still help
> out but hardware & doc resources will be the biggest challenge to me.
>
> - My current employee may have competitive relationship with NXP in automotive
> field, which means I may not be fit in this role unless nobody cares.

In general, there no problem to just retire from a maintainer
position or mark it as 'Odd fixes' instead of 'Maintained' when
you are no longer planning to actively maintain it.

>> > 
>> > Added everyone there to Cc, having any s32 patches go through
>> > the imx tree would be the easiest way as far as I'm concerned.
>> > I've added the maintainers to Cc, let's see what they think.
>> 
>> It's unintentional that IMX entry covers s32 dts files, as they have a
>> dedicated entry.
>> 
>> ARM/NXP S32G ARCHITECTURE
>> M:      Chester Lin <chester62515 at gmail.com>
>> R:      Andreas F?rber <afaerber at suse.de>
>> R:      Matthias Brugger <mbrugger at suse.com>
>> R:      NXP S32 Linux Team <s32 at nxp.com>
>> L:      linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>> S:      Maintained
>> F:      arch/arm64/boot/dts/freescale/s32g*.dts*
>> 
>> However I'm fine with collecting and sending patches through IMX tree,
>> if S32G folks help review them.
>> 
>
> This looks good to me as well.

Ok, in this case I would suggest we change this section to
only have 'R:' entries and no 'M:' for the moment.

Between the four of you (Chester, Andreas, Matthias, Ghennadi),
I think we can choose to keep everyone or drop those that are
unlikely to actually review patches. Please let us know you
would like to be included as a reviewer or not.

For the pinctrl driver, I would add the files to the "freescale"
pinctrl entry in a similar way and end up with

diff --git a/MAINTAINERS b/MAINTAINERS
index efeaeb51f183..c1924c0053bc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2555,13 +2555,14 @@ F:      drivers/*/*/*wpcm*
 F:     drivers/*/*wpcm*
 
 ARM/NXP S32G ARCHITECTURE
-M:     Chester Lin <chester62515 at gmail.com>
+R:     Chester Lin <chester62515 at gmail.com>
 R:     Andreas F?rber <afaerber at suse.de>
 R:     Matthias Brugger <mbrugger at suse.com>
 R:     NXP S32 Linux Team <s32 at nxp.com>
 L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm64/boot/dts/freescale/s32g*.dts*
+F:     drivers/pinctrl/nxp/
 
 ARM/Orion SoC/Technologic Systems TS-78xx platform support
 M:     Alexander Clouter <alex at digriz.org.uk>
@@ -17415,7 +17416,9 @@ R:      Pengutronix Kernel Team <kernel at pengutronix.de>
 L:     linux-gpio at vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/pinctrl/fsl,*
+F:     Documentation/devicetree/bindings/pinctrl/nxp,s32*
 F:     drivers/pinctrl/freescale/
+F:     drivers/pinctrl/nxp/
 
 PIN CONTROLLER - INTEL
 M:     Mika Westerberg <mika.westerberg at linux.intel.com>
@@ -17469,14 +17472,6 @@ S:     Supported
 F:     drivers/gpio/gpio-sama5d2-piobu.c
 F:     drivers/pinctrl/pinctrl-at91*
 
-PIN CONTROLLER - NXP S32
-M:     Chester Lin <clin at suse.com>
-R:     NXP S32 Linux Team <s32 at nxp.com>
-L:     linux-gpio at vger.kernel.org
-S:     Maintained
-F:     Documentation/devicetree/bindings/pinctrl/nxp,s32*
-F:     drivers/pinctrl/nxp/
-
 PIN CONTROLLER - QUALCOMM
 M:     Bjorn Andersson <andersson at kernel.org>
 L:     linux-arm-msm at vger.kernel.org


From guohanjun at huawei.com  Sat Feb 24 03:43:27 2024
From: guohanjun at huawei.com (Hanjun Guo)
Date: Sat, 24 Feb 2024 19:43:27 +0800
Subject: [PATCH v3 3/7] ACPI/IORT: Handle memory address size limits as
 limits
In-Reply-To: <5d52d580bf33d475053f9b05188fe3541cbe8798.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
 <5d52d580bf33d475053f9b05188fe3541cbe8798.1707493264.git.robin.murphy@arm.com>
Message-ID: <ab2099fd-b0b7-63d3-bdba-a4462ec230a8@huawei.com>

On 2024/2/10 0:50, Robin Murphy wrote:
> Return the Root Complex/Named Component memory address size limit as an
> inclusive limit value, rather than an exclusive size. This saves having
> to fudge an off-by-one for the 64-bit case, and simplifies our caller.
> 
> Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
> v2: Avoid undefined shifts (grr...)
> ---
>   drivers/acpi/arm64/dma.c  |  9 +++------
>   drivers/acpi/arm64/iort.c | 20 ++++++++++----------
>   include/linux/acpi_iort.h |  4 ++--
>   3 files changed, 15 insertions(+), 18 deletions(-)

This also makes the code easier to read,

Acked-by: Hanjun Guo <guohanjun at huawei.com>

Thanks
Hanjun


From guohanjun at huawei.com  Sat Feb 24 03:47:27 2024
From: guohanjun at huawei.com (Hanjun Guo)
Date: Sat, 24 Feb 2024 19:47:27 +0800
Subject: [PATCH v3 4/7] dma-mapping: Add helpers for dma_range_map bounds
In-Reply-To: <cc90d296daa52e9cfe9fdd6681c68df4773a5e6a.1707493264.git.robin.murphy@arm.com>
References: <cover.1707493264.git.robin.murphy@arm.com>
 <cc90d296daa52e9cfe9fdd6681c68df4773a5e6a.1707493264.git.robin.murphy@arm.com>
Message-ID: <6e837f8b-b855-99b6-6f73-721de97b3fa4@huawei.com>

On 2024/2/10 0:50, Robin Murphy wrote:
> Several places want to compute the lower and/or upper bounds of a
> dma_range_map, so let's factor that out into reusable helpers.
> 
> Acked-by: Rob Herring <robh at kernel.org>
> Reviewed-by: Christoph Hellwig <hch at lst.de>
> Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
> v2: fix warning for 32-bit builds
> ---
>   arch/loongarch/kernel/dma.c |  9 ++-------
>   drivers/acpi/arm64/dma.c    |  8 +-------
>   drivers/of/device.c         | 11 ++---------
>   include/linux/dma-direct.h  | 18 ++++++++++++++++++
>   4 files changed, 23 insertions(+), 23 deletions(-)

For the ARM64 code,

Reviewed-by: Hanjun Guo <guohanjun at huawei.com>

Thanks
Hanjun


From krzysztof.kozlowski at linaro.org  Sat Feb 24 04:02:15 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 24 Feb 2024 13:02:15 +0100
Subject: [EXT] Re: [PATCH v6 4/9] dt-bindings: usb: add NXP ChipIdea USB2
 Controller schema
In-Reply-To: <DU2PR04MB882234D1A9D5718D8355928B8C552@DU2PR04MB8822.eurprd04.prod.outlook.com>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
 <20240221145846.1611627-4-xu.yang_2@nxp.com>
 <20240223140256.GA1768266-robh@kernel.org>
 <DU2PR04MB882234D1A9D5718D8355928B8C552@DU2PR04MB8822.eurprd04.prod.outlook.com>
Message-ID: <6c5c0233-dab8-4bd1-9f08-0b609d01defd@linaro.org>

On 23/02/2024 15:56, Xu Yang wrote:
> Hi Rob,
> 
>>
>> On Wed, Feb 21, 2024 at 10:58:41PM +0800, Xu Yang wrote:
>>> As more and more NXP i.MX chips come out, it becomes harder to maintain
>>> ci-hdrc-usb2.yaml if more stuffs like property restrictions are added to
>>> this file. This will separate i.MX parts out of ci-hdrc-usb2.yaml and add
>>> a new schema for NXP ChipIdea USB2 Controller.
>>>
>>> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
>>>
>>> ---
>>> Changes in v6:
>>>  - new patch
>>> ---
>>>  .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 75 +++++++++++++++++++
>>>  1 file changed, 75 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml b/Documentation/devicetree/bindings/usb/ci-
>> hdrc-usb2-imx.yaml
>>> new file mode 100644
>>> index 000000000000..2ec62f564bf5
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
>>> @@ -0,0 +1,75 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/usb/ci-hdrc-
>> usb2-
>> imx.yaml%23&data=05%7C02%7Cxu.yang_2%40nxp.com%7C4ac0c60cd4b4433f0f9f08dc34782572%7C686ea1d3bc2b4c6fa92c
>> d99c5c301635%7C0%7C0%7C638442937830606824%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIi
>> LCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=7p1DzvYmBsTgN44jypH7lc56z9hVBsFBYXUwsblk9z8%3D&reserv
>> ed=0
>>> +$schema: http://devicetree.org/meta-
>> schemas%2Fcore.yaml%23&data=05%7C02%7Cxu.yang_2%40nxp.com%7C4ac0c60cd4b4433f0f9f08dc34782572%7C686ea1d3
>> bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638442937830615622%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLC
>> JQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=fWWy9enbGK5yeKiovday7go3Gss5L%2F%2Fe%2F
>> OZcANny0QA%3D&reserved=0
>>> +
>>> +title: NXP USB2 ChipIdea USB controller
>>> +
>>> +maintainers:
>>> +  - Xu Yang <xu.yang_2 at nxp.com>
>>> +
>>> +properties:
>>> +  compatible:
>>> +    oneOf:
>>> +      - enum:
>>> +          - fsl,imx27-usb
>>> +      - items:
>>> +          - enum:
>>> +              - fsl,imx23-usb
>>> +              - fsl,imx25-usb
>>> +              - fsl,imx28-usb
>>> +              - fsl,imx35-usb
>>> +              - fsl,imx50-usb
>>> +              - fsl,imx51-usb
>>> +              - fsl,imx53-usb
>>> +              - fsl,imx6q-usb
>>> +              - fsl,imx6sl-usb
>>> +              - fsl,imx6sx-usb
>>> +              - fsl,imx6ul-usb
>>> +              - fsl,imx7d-usb
>>> +              - fsl,vf610-usb
>>> +          - const: fsl,imx27-usb
>>> +      - items:
>>> +          - enum:
>>> +              - fsl,imx8dxl-usb
>>> +              - fsl,imx8ulp-usb
>>> +          - const: fsl,imx7ulp-usb
>>> +          - const: fsl,imx6ul-usb
>>> +      - items:
>>> +          - enum:
>>> +              - fsl,imx8mm-usb
>>> +              - fsl,imx8mn-usb
>>> +          - const: fsl,imx7d-usb
>>> +          - const: fsl,imx27-usb
>>> +      - items:
>>> +          - enum:
>>> +              - fsl,imx6sll-usb
>>> +              - fsl,imx7ulp-usb
>>> +          - const: fsl,imx6ul-usb
>>> +          - const: fsl,imx27-usb
>>
>> Now you just duplicated all the compatibles, and now any new compatibles
>> have to be added in 2 places. For this to work, you have to split
>> ci-hdrc-usb2.yaml into 2 files. One with all the common properties and
>> one with compatibles (minus imx). This is also needed if imx has any
>> extra properties the other don't.
>>
>> Didn't I say this already?
>>
> 
> Yes, I know.
> 
> But according to your words, I need to split ci-hdrc-usb2.yaml into 1 common
> file and more than 1 vendor specific files (imx, nvidia, qcom, nuvoton and
> others). In this patchset, I only focus on imx part and KK said he or someone
> will take over other parts, therefore I just duplicated all the imx compatibles.

Someone will take over their bits, but it does not mean you can
duplicate IMX. Why you cannot use the approach I asked - move IMX out of
that schema?

https://lore.kernel.org/all/a0134089-a283-488b-8d7f-3f59dd938b60 at linaro.org/

Look:
"... and move IMX to own file."

Move is not "copy". Please run: `man mv`

> If I only create imx specific yaml file and remove all compatilbles from common

Why would you remove ALL of others? What is the point of this.

> file, nvidia, qcom, nuvoton and others compatible info will be lost, is this
> feasible? Or should I create mutiple vendor specific files at the same time?

You can take a look how it is done in my recent Qualcomm PCI dt-bindings
series.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 24 04:03:07 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 24 Feb 2024 13:03:07 +0100
Subject: [RESEND v6 4/9] dt-bindings: usb: add NXP ChipIdea USB2
 Controller schema
In-Reply-To: <20240221080238.1615536-4-xu.yang_2@nxp.com>
References: <20240221080238.1615536-1-xu.yang_2@nxp.com>
 <20240221080238.1615536-4-xu.yang_2@nxp.com>
Message-ID: <cf021cab-83d8-4661-a568-8808a0acca09@linaro.org>

On 21/02/2024 09:02, Xu Yang wrote:
> As more and more NXP i.MX chips come out, it becomes harder to maintain
> ci-hdrc-usb2.yaml if more stuffs like property restrictions are added to
> this file. This will separate i.MX parts out of ci-hdrc-usb2.yaml and add
> a new schema for NXP ChipIdea USB2 Controller.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v6:
>  - new patch
> ---

Discussion is on other thread, so let's be clear here:
NAK, because you ignored what I asked for.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sat Feb 24 04:03:38 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sat, 24 Feb 2024 13:03:38 +0100
Subject: [RESEND v6 5/9] dt-bindings: usb: ci-hdrc-usb2-imx: add
 restrictions for reg, interrupts, clock and clock-names properties
In-Reply-To: <20240221080238.1615536-5-xu.yang_2@nxp.com>
References: <20240221080238.1615536-1-xu.yang_2@nxp.com>
 <20240221080238.1615536-5-xu.yang_2@nxp.com>
Message-ID: <ed34a1a5-de7d-4e5c-bd75-e99af764c782@linaro.org>

On 21/02/2024 09:02, Xu Yang wrote:
> Add restrictions for reg, interrupts, clock and clock-names properties
> for imx Socs.
> 
> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> 
> ---
> Changes in v4:
>  - new patch since v3's discussion
>  - split the reg, interrupts, clock and clock-names properties into

Duplicated patchset, discussion is in other thread. To make it explicit
that it should not be applied:

NAK

Best regards,
Krzysztof



From arnd at kernel.org  Sat Feb 24 04:10:22 2024
From: arnd at kernel.org (Arnd Bergmann)
Date: Sat, 24 Feb 2024 13:10:22 +0100
Subject: [PATCH] media: mediatek: vcodec: avoid -Wcast-function-type-strict warning
Message-ID: <20240224121059.1806691-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

The ipi handler here tries hard to maintain const-ness of its argument,
but by doing that causes a warning about function type casts:

drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c:38:32: error: cast from 'mtk_vcodec_ipi_handler' (aka 'void (*)(void *, unsigned int, void *)') to 'ipi_handler_t' (aka 'void (*)(const void *, unsigned int, void *)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
   38 |         ipi_handler_t handler_const = (ipi_handler_t)handler;
      |                                       ^~~~~~~~~~~~~~~~~~~~~~

Remove the hack and just use a non-const argument.

Fixes: bf1d556ad4e0 ("media: mtk-vcodec: abstract firmware interface")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c      |  2 +-
 .../mediatek/vcodec/common/mtk_vcodec_fw_vpu.c         | 10 +---------
 drivers/media/platform/mediatek/vpu/mtk_vpu.c          |  2 +-
 drivers/media/platform/mediatek/vpu/mtk_vpu.h          |  2 +-
 4 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
index b065ccd06914..378a1cba0144 100644
--- a/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
+++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
@@ -26,7 +26,7 @@ static void mtk_mdp_vpu_handle_init_ack(const struct mdp_ipi_comm_ack *msg)
 	vpu->inst_addr = msg->vpu_inst_addr;
 }
 
-static void mtk_mdp_vpu_ipi_handler(const void *data, unsigned int len,
+static void mtk_mdp_vpu_ipi_handler(void *data, unsigned int len,
 				    void *priv)
 {
 	const struct mdp_ipi_comm_ack *msg = data;
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
index 9f6e4b59455d..4c34344dc7dc 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
@@ -29,15 +29,7 @@ static int mtk_vcodec_vpu_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
 					   mtk_vcodec_ipi_handler handler,
 					   const char *name, void *priv)
 {
-	/*
-	 * The handler we receive takes a void * as its first argument. We
-	 * cannot change this because it needs to be passed down to the rproc
-	 * subsystem when SCP is used. VPU takes a const argument, which is
-	 * more constrained, so the conversion below is safe.
-	 */
-	ipi_handler_t handler_const = (ipi_handler_t)handler;
-
-	return vpu_ipi_register(fw->pdev, id, handler_const, name, priv);
+	return vpu_ipi_register(fw->pdev, id, handler, name, priv);
 }
 
 static int mtk_vcodec_vpu_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.c b/drivers/media/platform/mediatek/vpu/mtk_vpu.c
index 7243604a82a5..724ae7c2ab3b 100644
--- a/drivers/media/platform/mediatek/vpu/mtk_vpu.c
+++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.c
@@ -635,7 +635,7 @@ int vpu_load_firmware(struct platform_device *pdev)
 }
 EXPORT_SYMBOL_GPL(vpu_load_firmware);
 
-static void vpu_init_ipi_handler(const void *data, unsigned int len, void *priv)
+static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv)
 {
 	struct mtk_vpu *vpu = priv;
 	const struct vpu_run *run = data;
diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.h b/drivers/media/platform/mediatek/vpu/mtk_vpu.h
index a56053ff135a..da05f3e74081 100644
--- a/drivers/media/platform/mediatek/vpu/mtk_vpu.h
+++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.h
@@ -17,7 +17,7 @@
  * VPU interfaces with other blocks by share memory and interrupt.
  */
 
-typedef void (*ipi_handler_t) (const void *data,
+typedef void (*ipi_handler_t) (void *data,
 			       unsigned int len,
 			       void *priv);
 
-- 
2.39.2



From claudiu.beznea at tuxon.dev  Sat Feb 24 04:50:02 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 24 Feb 2024 14:50:02 +0200
Subject: [PATCH v8 1/7] drm: atmel-hlcdc: add driver ops to differentiate
 HLCDC and XLCDC IP
In-Reply-To: <20240221053531.12701-2-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
 <20240221053531.12701-2-manikandan.m@microchip.com>
Message-ID: <0d794962-3403-41b5-b2fb-570d2882ac8a@tuxon.dev>



On 21.02.2024 07:35, Manikandan Muralidharan wrote:
> Add LCD IP specific ops in driver data to differentiate
> HLCDC and XLCDC code within the atmel-hlcdc driver files.
> XLCDC in SAM9X7 has different sets of registers and additional
> configuration bits when compared to previous HLCDC IP. Read/write
> operation on the controller register and functionality is now
> separated using the LCD IP specific ops.
> 
> Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c  |   5 +
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h  |  84 ++++++---
>  .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   | 167 +++++++++++-------
>  3 files changed, 173 insertions(+), 83 deletions(-)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> index 84c54e8622d1..b09df821cbc0 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> @@ -58,6 +58,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9n12 = {
>  	.conflicting_output_formats = true,
>  	.nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9n12_layers),
>  	.layers = atmel_hlcdc_at91sam9n12_layers,
> +	.ops = &atmel_hlcdc_ops,
>  };
>  
>  static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
> @@ -151,6 +152,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9x5 = {
>  	.conflicting_output_formats = true,
>  	.nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9x5_layers),
>  	.layers = atmel_hlcdc_at91sam9x5_layers,
> +	.ops = &atmel_hlcdc_ops,
>  };
>  
>  static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
> @@ -269,6 +271,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d3 = {
>  	.conflicting_output_formats = true,
>  	.nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d3_layers),
>  	.layers = atmel_hlcdc_sama5d3_layers,
> +	.ops = &atmel_hlcdc_ops,
>  };
>  
>  static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
> @@ -364,6 +367,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d4 = {
>  	.max_hpw = 0x3ff,
>  	.nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d4_layers),
>  	.layers = atmel_hlcdc_sama5d4_layers,
> +	.ops = &atmel_hlcdc_ops,
>  };
>  
>  static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sam9x60_layers[] = {
> @@ -460,6 +464,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = {
>  	.fixed_clksrc = true,
>  	.nlayers = ARRAY_SIZE(atmel_hlcdc_sam9x60_layers),
>  	.layers = atmel_hlcdc_sam9x60_layers,
> +	.ops = &atmel_hlcdc_ops,
>  };
>  
>  static const struct of_device_id atmel_hlcdc_of_match[] = {
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> index 5b5c774e0edf..ad732edfef0b 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> @@ -288,6 +288,64 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer)
>  	return container_of(layer, struct atmel_hlcdc_plane, layer);
>  }
>  
> +/**
> + * Atmel HLCDC Display Controller.

This doens't comply w/ recommendation at
https://docs.kernel.org/doc-guide/kernel-doc.html#structure-union-and-enumeration-documentation

> + *
> + * @desc: HLCDC Display Controller description
> + * @dscrpool: DMA coherent pool used to allocate DMA descriptors
> + * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device
> + * @fbdev: framebuffer device attached to the Display Controller
> + * @crtc: CRTC provided by the display controller
> + * @planes: instantiated planes
> + * @layers: active HLCDC layers
> + * @suspend: used to store the HLCDC state when entering suspend

Check this for nested struct documentation:
https://docs.kernel.org/doc-guide/kernel-doc.html#nested-structs-unions

> + */
> +struct atmel_hlcdc_dc {
> +	const struct atmel_hlcdc_dc_desc *desc;
> +	struct dma_pool *dscrpool;
> +	struct atmel_hlcdc *hlcdc;
> +	struct drm_crtc *crtc;
> +	struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS];
> +	struct {
> +		u32 imr;
> +		struct drm_atomic_state *state;
> +	} suspend;
> +};
> +
> +struct atmel_hlcdc_plane_state;
> +
> +/**
> + * struct atmel_lcdc_dc_ops - describes atmel_lcdc ops group
> + * to differentiate HLCDC and XLCDC IP code support
> + * @plane_setup_scaler: update the vertical and horizontal scaling factors
> + * @update_lcdc_buffers: update the each LCDC layers DMA registers
> + * @lcdc_atomic_disable: disable LCDC interrupts and layers
> + * @lcdc_update_general_settings: update each LCDC layers general
> + * confiugration register

s/confiugration/configuration

> + * @lcdc_atomic_update: enable the LCDC layers and interrupts
> + * @lcdc_csc_init: update the color space conversion co-efficient of
> + * High-end overlay register
> + * @lcdc_irq_dbg: to raise alert incase of interrupt overrun in any LCDC layer
> + */
> +struct atmel_lcdc_dc_ops {
> +	void (*plane_setup_scaler)(struct atmel_hlcdc_plane *plane,
> +				   struct atmel_hlcdc_plane_state *state);
> +	void (*update_lcdc_buffers)(struct atmel_hlcdc_plane *plane,
> +				    struct atmel_hlcdc_plane_state *state,
> +				    u32 sr, int i);
> +	void (*lcdc_atomic_disable)(struct atmel_hlcdc_plane *plane);
> +	void (*lcdc_update_general_settings)(struct atmel_hlcdc_plane *plane,
> +					     struct atmel_hlcdc_plane_state *state);
> +	void (*lcdc_atomic_update)(struct atmel_hlcdc_plane *plane,
> +				   struct atmel_hlcdc_dc *dc);
> +	void (*lcdc_csc_init)(struct atmel_hlcdc_plane *plane,
> +			      const struct atmel_hlcdc_layer_desc *desc);
> +	void (*lcdc_irq_dbg)(struct atmel_hlcdc_plane *plane,
> +			     const struct atmel_hlcdc_layer_desc *desc);
> +};
> +
> +extern const struct atmel_lcdc_dc_ops atmel_hlcdc_ops;
> +
>  /**
>   * Atmel HLCDC Display Controller description structure.
>   *
> @@ -306,6 +364,7 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer)
>   * @fixed_clksrc: true if clock source is fixed
>   * @layers: a layer description table describing available layers
>   * @nlayers: layer description table size
> + * @ops: atmel lcdc dc ops
>   */
>  struct atmel_hlcdc_dc_desc {
>  	int min_width;
> @@ -319,30 +378,7 @@ struct atmel_hlcdc_dc_desc {
>  	bool fixed_clksrc;
>  	const struct atmel_hlcdc_layer_desc *layers;
>  	int nlayers;
> -};
> -
> -/**
> - * Atmel HLCDC Display Controller.
> - *
> - * @desc: HLCDC Display Controller description
> - * @dscrpool: DMA coherent pool used to allocate DMA descriptors
> - * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device
> - * @fbdev: framebuffer device attached to the Display Controller
> - * @crtc: CRTC provided by the display controller
> - * @planes: instantiated planes
> - * @layers: active HLCDC layers
> - * @suspend: used to store the HLCDC state when entering suspend
> - */
> -struct atmel_hlcdc_dc {
> -	const struct atmel_hlcdc_dc_desc *desc;
> -	struct dma_pool *dscrpool;
> -	struct atmel_hlcdc *hlcdc;
> -	struct drm_crtc *crtc;
> -	struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS];
> -	struct {
> -		u32 imr;
> -		struct drm_atomic_state *state;
> -	} suspend;
> +	const struct atmel_lcdc_dc_ops *ops;
>  };
>  
>  extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats;
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index daa508504f47..3427546cd58c 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -282,8 +282,9 @@ atmel_hlcdc_plane_scaler_set_phicoeff(struct atmel_hlcdc_plane *plane,
>  					    coeff_tab[i]);
>  }
>  
> -static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
> -					   struct atmel_hlcdc_plane_state *state)
> +static
> +void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
> +				    struct atmel_hlcdc_plane_state *state)
>  {
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
>  	u32 xfactor, yfactor;
> @@ -335,6 +336,7 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
>  				      struct atmel_hlcdc_plane_state *state)
>  {
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
>  
>  	if (desc->layout.size)
>  		atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.size,
> @@ -352,12 +354,12 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
>  					ATMEL_HLCDC_LAYER_POS(state->crtc_x,
>  							      state->crtc_y));
>  
> -	atmel_hlcdc_plane_setup_scaler(plane, state);
> +	dc->desc->ops->plane_setup_scaler(plane, state);
>  }
>  
> -static void
> -atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> -					struct atmel_hlcdc_plane_state *state)
> +static
> +void atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> +					       struct atmel_hlcdc_plane_state *state)
>  {
>  	unsigned int cfg = ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id;
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> @@ -437,10 +439,33 @@ static void atmel_hlcdc_plane_update_clut(struct atmel_hlcdc_plane *plane,
>  	}
>  }
>  
> +static void update_hlcdc_buffers(struct atmel_hlcdc_plane *plane,

would be good to keep in in the atmel_hlcdc/atmel namespace thus, rename it
something like:

*atmel_hlcdc*_update_buffers()

to avoid conflicting with any subsystem specific APIs, if any. And also
keep consistency with the rest of the HLCDC driver code.

> +				 struct atmel_hlcdc_plane_state *state,
> +				 u32 sr, int i)
> +{
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
> +				    state->dscrs[i]->self);
> +
> +	if (sr & ATMEL_HLCDC_LAYER_EN)
> +		return;
> +
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
> +				    state->dscrs[i]->addr);
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
> +				    state->dscrs[i]->ctrl);
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
> +				    state->dscrs[i]->self);
> +}
> +
>  static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
> -					struct atmel_hlcdc_plane_state *state)
> +					     struct atmel_hlcdc_plane_state *state)
>  {
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	u32 sr;
>  	int i;
> @@ -452,21 +477,7 @@ static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
>  
>  		state->dscrs[i]->addr = gem->dma_addr + state->offsets[i];
>  
> -		atmel_hlcdc_layer_write_reg(&plane->layer,
> -					    ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
> -					    state->dscrs[i]->self);
> -
> -		if (!(sr & ATMEL_HLCDC_LAYER_EN)) {
> -			atmel_hlcdc_layer_write_reg(&plane->layer,
> -					ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
> -					state->dscrs[i]->addr);
> -			atmel_hlcdc_layer_write_reg(&plane->layer,
> -					ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
> -					state->dscrs[i]->ctrl);
> -			atmel_hlcdc_layer_write_reg(&plane->layer,
> -					ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
> -					state->dscrs[i]->self);
> -		}
> +		dc->desc->ops->update_lcdc_buffers(plane, state, sr, i);
>  
>  		if (desc->layout.xstride[i])
>  			atmel_hlcdc_layer_write_cfg(&plane->layer,
> @@ -712,11 +723,8 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
>  	return 0;
>  }
>  
> -static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
> -					     struct drm_atomic_state *state)
> +static void hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)

Same here, e.g., *atmel_hlcdc*_atomic_disable()

>  {
> -	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
> -
>  	/* Disable interrupts */
>  	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IDR,
>  				    0xffffffff);
> @@ -731,6 +739,34 @@ static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
>  	atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
>  }
>  
> +static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
> +					     struct drm_atomic_state *state)
> +{
> +	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
> +	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
> +
> +	dc->desc->ops->lcdc_atomic_disable(plane);
> +}
> +
> +static void hlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
> +				struct atmel_hlcdc_dc *dc)

Same here, e.g., *atmel_hlcdc*_hlcdc_atomic_update()

> +{
> +	u32 sr;
> +
> +	/* Enable the overrun interrupts. */
> +	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
> +				    ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
> +				    ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
> +				    ATMEL_HLCDC_LAYER_OVR_IRQ(2));
> +
> +	/* Apply the new config at the next SOF event. */
> +	sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
> +	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
> +				    ATMEL_HLCDC_LAYER_UPDATE |
> +				    (sr & ATMEL_HLCDC_LAYER_EN ?
> +				    ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
> +}
> +
>  static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
>  					    struct drm_atomic_state *state)
>  {
> @@ -739,7 +775,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
>  	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
>  	struct atmel_hlcdc_plane_state *hstate =
>  			drm_plane_state_to_atmel_hlcdc_plane_state(new_s);
> -	u32 sr;
> +	struct atmel_hlcdc_dc *dc = p->dev->dev_private;
>  
>  	if (!new_s->crtc || !new_s->fb)
>  		return;
> @@ -750,29 +786,39 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
>  	}
>  
>  	atmel_hlcdc_plane_update_pos_and_size(plane, hstate);
> -	atmel_hlcdc_plane_update_general_settings(plane, hstate);
> +	dc->desc->ops->lcdc_update_general_settings(plane, hstate);
>  	atmel_hlcdc_plane_update_format(plane, hstate);
>  	atmel_hlcdc_plane_update_clut(plane, hstate);
>  	atmel_hlcdc_plane_update_buffers(plane, hstate);
>  	atmel_hlcdc_plane_update_disc_area(plane, hstate);
>  
> -	/* Enable the overrun interrupts. */
> -	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
> -				    ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
> -				    ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
> -				    ATMEL_HLCDC_LAYER_OVR_IRQ(2));
> +	dc->desc->ops->lcdc_atomic_update(plane, dc);
> +}
>  
> -	/* Apply the new config at the next SOF event. */
> -	sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
> -	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
> -			ATMEL_HLCDC_LAYER_UPDATE |
> -			(sr & ATMEL_HLCDC_LAYER_EN ?
> -			 ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
> +static void hlcdc_csc_init(struct atmel_hlcdc_plane *plane,
> +			   const struct atmel_hlcdc_layer_desc *desc)

Same here.

> +{
> +	/*
> +	 * TODO: declare a "yuv-to-rgb-conv-factors" property to let
> +	 * userspace modify these factors (using a BLOB property ?).
> +	 */
> +	static const u32 hlcdc_csc_coeffs[] = {
> +		0x4c900091,
> +		0x7a5f5090,
> +		0x40040890
> +	};
> +
> +	for (int i = 0; i < ARRAY_SIZE(hlcdc_csc_coeffs); i++) {
> +		atmel_hlcdc_layer_write_cfg(&plane->layer,
> +					    desc->layout.csc + i,
> +					    hlcdc_csc_coeffs[i]);
> +	}
>  }
>  
>  static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
>  {
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
>  
>  	if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
>  	    desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
> @@ -796,31 +842,16 @@ static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
>  			return ret;
>  	}
>  
> -	if (desc->layout.csc) {
> -		/*
> -		 * TODO: decare a "yuv-to-rgb-conv-factors" property to let
> -		 * userspace modify these factors (using a BLOB property ?).
> -		 */
> -		atmel_hlcdc_layer_write_cfg(&plane->layer,
> -					    desc->layout.csc,
> -					    0x4c900091);
> -		atmel_hlcdc_layer_write_cfg(&plane->layer,
> -					    desc->layout.csc + 1,
> -					    0x7a5f5090);
> -		atmel_hlcdc_layer_write_cfg(&plane->layer,
> -					    desc->layout.csc + 2,
> -					    0x40040890);
> -	}
> +	if (desc->layout.csc)
> +		dc->desc->ops->lcdc_csc_init(plane, desc);
>  
>  	return 0;
>  }
>  
> -void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
> +static void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
> +			  const struct atmel_hlcdc_layer_desc *desc)

same here.

>  {
> -	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> -	u32 isr;
> -
> -	isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
> +	u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
>  
>  	/*
>  	 * There's not much we can do in case of overrun except informing
> @@ -834,6 +865,24 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
>  			desc->name);
>  }
>  
> +void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
> +{
> +	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
> +
> +	dc->desc->ops->lcdc_irq_dbg(plane, desc);
> +}
> +
> +const struct atmel_lcdc_dc_ops atmel_hlcdc_ops = {
> +	.plane_setup_scaler = atmel_hlcdc_plane_setup_scaler,
> +	.update_lcdc_buffers = update_hlcdc_buffers,
> +	.lcdc_atomic_disable = hlcdc_atomic_disable,
> +	.lcdc_update_general_settings = atmel_hlcdc_plane_update_general_settings,
> +	.lcdc_atomic_update = hlcdc_atomic_update,
> +	.lcdc_csc_init = hlcdc_csc_init,
> +	.lcdc_irq_dbg = hlcdc_irq_dbg,
> +};
> +
>  static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
>  	.atomic_check = atmel_hlcdc_plane_atomic_check,
>  	.atomic_update = atmel_hlcdc_plane_atomic_update,


From claudiu.beznea at tuxon.dev  Sat Feb 24 04:50:11 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 24 Feb 2024 14:50:11 +0200
Subject: [PATCH v8 6/7] drm: atmel-hlcdc: add support for DSI output
 formats
In-Reply-To: <20240221053531.12701-7-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
 <20240221053531.12701-7-manikandan.m@microchip.com>
Message-ID: <c75bd63c-05f8-4b45-bd01-99e1240b921a@tuxon.dev>



On 21.02.2024 07:35, Manikandan Muralidharan wrote:
> Add support for the following DPI mode if the encoder type
> is DSI as per the XLCDC IP datasheet:
> - 16BPPCFG1
> - 16BPPCFG2
> - 16BPPCFG3
> - 18BPPCFG1
> - 18BPPCFG2
> - 24BPP
> 
> Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
> [durai.manickamkr at microchip.com: update output format using is_xlcdc flag]
> Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
> ---
>  .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c    | 74 +++++++++++++++++--
>  1 file changed, 68 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> index fdd3a6bc0f79..0dbe85686fc2 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> @@ -301,11 +301,64 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
>  
>  }
>  
> -#define ATMEL_HLCDC_RGB444_OUTPUT	BIT(0)
> -#define ATMEL_HLCDC_RGB565_OUTPUT	BIT(1)
> -#define ATMEL_HLCDC_RGB666_OUTPUT	BIT(2)
> -#define ATMEL_HLCDC_RGB888_OUTPUT	BIT(3)
> -#define ATMEL_HLCDC_OUTPUT_MODE_MASK	GENMASK(3, 0)
> +#define ATMEL_HLCDC_RGB444_OUTPUT		BIT(0)
> +#define ATMEL_HLCDC_RGB565_OUTPUT		BIT(1)
> +#define ATMEL_HLCDC_RGB666_OUTPUT		BIT(2)
> +#define ATMEL_HLCDC_RGB888_OUTPUT		BIT(3)
> +#define ATMEL_HLCDC_DPI_RGB565C1_OUTPUT		BIT(4)
> +#define ATMEL_HLCDC_DPI_RGB565C2_OUTPUT		BIT(5)
> +#define ATMEL_HLCDC_DPI_RGB565C3_OUTPUT		BIT(6)
> +#define ATMEL_HLCDC_DPI_RGB666C1_OUTPUT		BIT(7)
> +#define ATMEL_HLCDC_DPI_RGB666C2_OUTPUT		BIT(8)
> +#define ATMEL_HLCDC_DPI_RGB888_OUTPUT		BIT(9)
> +#define ATMEL_HLCDC_OUTPUT_MODE_MASK		GENMASK(3, 0)
> +#define ATMEL_XLCDC_OUTPUT_MODE_MASK		GENMASK(9, 0)
> +
> +static int atmel_hlcdc_connector_output_dsi(struct drm_encoder *encoder,
> +					    struct drm_display_info *info)
> +{
> +	int j;
> +	unsigned int supported_fmts = 0;
> +
> +	switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
> +	case 0:
> +		break;
> +	case MEDIA_BUS_FMT_RGB565_1X16:
> +		return ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
> +	case MEDIA_BUS_FMT_RGB666_1X18:
> +		return ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
> +	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
> +		return ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
> +	case MEDIA_BUS_FMT_RGB888_1X24:
> +		return ATMEL_HLCDC_DPI_RGB888_OUTPUT;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	for (j = 0; j < info->num_bus_formats; j++) {
> +		switch (info->bus_formats[j]) {
> +		case MEDIA_BUS_FMT_RGB565_1X16:
> +			supported_fmts |=
> +				ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;

This can fit on the above line

> +			break;
> +		case MEDIA_BUS_FMT_RGB666_1X18:
> +			supported_fmts |=
> +				ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;

Ditto

> +			break;
> +		case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
> +			supported_fmts |=
> +				ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;

Ditto

> +			break;
> +		case MEDIA_BUS_FMT_RGB888_1X24:
> +			supported_fmts |=
> +				ATMEL_HLCDC_DPI_RGB888_OUTPUT;

Ditto

> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +	return supported_fmts;
> +}
>  
>  static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
>  {
> @@ -318,6 +371,13 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
>  	encoder = state->best_encoder;
>  	if (!encoder)
>  		encoder = connector->encoder;
> +	/*
> +	 * atmel-hlcdc to support DSI formats with DSI video pipeline
> +	 * when DRM_MODE_ENCODER_DSI type is set by
> +	 * connector driver component.
> +	 */
> +	if (encoder->encoder_type == DRM_MODE_ENCODER_DSI)
> +		return atmel_hlcdc_connector_output_dsi(encoder, info);
>  
>  	switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
>  	case 0:
> @@ -358,7 +418,7 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
>  
>  static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
>  {
> -	unsigned int output_fmts = ATMEL_HLCDC_OUTPUT_MODE_MASK;
> +	unsigned int output_fmts;
>  	struct atmel_hlcdc_crtc_state *hstate;
>  	struct drm_connector_state *cstate;
>  	struct drm_connector *connector;
> @@ -366,6 +426,8 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
>  	int i;
>  
>  	crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc);
> +	output_fmts = crtc->dc->desc->is_xlcdc ? ATMEL_XLCDC_OUTPUT_MODE_MASK :
> +		      ATMEL_HLCDC_OUTPUT_MODE_MASK;
>  
>  	for_each_new_connector_in_state(state->state, connector, cstate, i) {
>  		unsigned int supported_fmts = 0;


From claudiu.beznea at tuxon.dev  Sat Feb 24 04:50:22 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 24 Feb 2024 14:50:22 +0200
Subject: [PATCH v8 3/7] drm: atmel_hlcdc: Add support for XLCDC using IP
 specific driver ops
In-Reply-To: <20240221053531.12701-4-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
 <20240221053531.12701-4-manikandan.m@microchip.com>
Message-ID: <8445b9fc-25b9-45b9-a02c-dbebc5bcfcd7@tuxon.dev>



On 21.02.2024 07:35, Manikandan Muralidharan wrote:
> Add XLCDC specific driver ops and is_xlcdc flag to separate the
> functionality and to access the controller registers.
> HEO scaling, window resampling, Alpha blending, YUV-to-RGB
> conversion in XLCDC is derived and handled using additional
> configuration bits and registers. Writing one to the Enable fields
> of each layer in LCD_ATTRE is required to reflect the values set
> in Configuration, FBA, Enable registers of each layer.
> 
> Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
> Co-developed-by: Hari Prasath Gujulan Elango <Hari.PrasathGE at microchip.com>
> Signed-off-by: Hari Prasath Gujulan Elango <Hari.PrasathGE at microchip.com>
> Co-developed-by: Durai Manickam KR <durai.manickamkr at microchip.com>
> Signed-off-by: Durai Manickam KR <durai.manickamkr at microchip.com>
> ---
>  .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c    |  81 +++++---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h  |   3 +
>  .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   | 182 +++++++++++++++++-
>  3 files changed, 242 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> index cc5cf4c2faf7..98a98b5fca85 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> @@ -164,11 +164,13 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
>  	state = drm_crtc_state_to_atmel_hlcdc_crtc_state(c->state);
>  	cfg = state->output_mode << 8;
>  
> -	if (adj->flags & DRM_MODE_FLAG_NVSYNC)
> -		cfg |= ATMEL_HLCDC_VSPOL;
> +	if (!crtc->dc->desc->is_xlcdc) {
> +		if (adj->flags & DRM_MODE_FLAG_NVSYNC)
> +			cfg |= ATMEL_HLCDC_VSPOL;
>  
> -	if (adj->flags & DRM_MODE_FLAG_NHSYNC)
> -		cfg |= ATMEL_HLCDC_HSPOL;
> +		if (adj->flags & DRM_MODE_FLAG_NHSYNC)
> +			cfg |= ATMEL_HLCDC_HSPOL;
> +	}
>  
>  	regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5),
>  			   ATMEL_HLCDC_HSPOL | ATMEL_HLCDC_VSPOL |
> @@ -202,20 +204,37 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,
>  
>  	pm_runtime_get_sync(dev->dev);
>  
> +	if (crtc->dc->desc->is_xlcdc) {
> +		regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_CM);
> +		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +					     !(status & ATMEL_XLCDC_CM),
> +					     10, 1000))
> +			dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
> +
> +		regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_SD);
> +		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +					     status & ATMEL_XLCDC_SD,
> +					     10, 1000))
> +			dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
> +	}
> +
>  	regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_DISP);
> -	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
> -	       (status & ATMEL_HLCDC_DISP))
> -		cpu_relax();
> +	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +				     !(status & ATMEL_HLCDC_DISP),
> +				    10, 1000))
> +		dev_warn(dev->dev, "Atmel LCDC status register DISPSTS timeout\n");

This is different thing than what the commit states it does but if
maintainer wants to keep it like this I don't have anything against. Valid
for the rest of regmap_read_poll_timeout() additions.

>  
>  	regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_SYNC);
> -	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
> -	       (status & ATMEL_HLCDC_SYNC))
> -		cpu_relax();
> +	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +				     !(status & ATMEL_HLCDC_SYNC),
> +				    10, 1000))
> +		dev_warn(dev->dev, "Atmel LCDC status register LCDSTS timeout\n");
>  
>  	regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_PIXEL_CLK);
> -	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
> -	       (status & ATMEL_HLCDC_PIXEL_CLK))
> -		cpu_relax();
> +	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +				     !(status & ATMEL_HLCDC_PIXEL_CLK),
> +				    10, 1000))
> +		dev_warn(dev->dev, "Atmel LCDC status register CLKSTS timeout\n");
>  
>  	clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
>  	pinctrl_pm_select_sleep_state(dev->dev);
> @@ -241,20 +260,36 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
>  	clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
>  
>  	regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PIXEL_CLK);
> -	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
> -	       !(status & ATMEL_HLCDC_PIXEL_CLK))
> -		cpu_relax();
> -
> +	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +				     status & ATMEL_HLCDC_PIXEL_CLK,
> +				     10, 1000))
> +		dev_warn(dev->dev, "Atmel LCDC status register CLKSTS timeout\n");
>  
>  	regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_SYNC);
> -	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
> -	       !(status & ATMEL_HLCDC_SYNC))
> -		cpu_relax();
> +	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +				     status & ATMEL_HLCDC_SYNC,
> +				     10, 1000))
> +		dev_warn(dev->dev, "Atmel LCDC status register LCDSTS timeout\n");
>  
>  	regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_DISP);
> -	while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
> -	       !(status & ATMEL_HLCDC_DISP))
> -		cpu_relax();
> +	if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +				     status & ATMEL_HLCDC_DISP,
> +				     10, 1000))
> +		dev_warn(dev->dev, "Atmel LCDC status register DISPSTS timeout\n");
> +
> +	if (crtc->dc->desc->is_xlcdc) {
> +		regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_CM);
> +		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +					     status & ATMEL_XLCDC_CM,
> +					     10, 1000))
> +			dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
> +
> +		regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_SD);
> +		if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> +					     !(status & ATMEL_XLCDC_SD),
> +					     10, 1000))
> +			dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
> +	}
>  
>  	pm_runtime_put_sync(dev->dev);
>  
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> index bc70a81b5275..777987b7873d 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> @@ -387,6 +387,7 @@ struct atmel_lcdc_dc_ops {
>  };
>  
>  extern const struct atmel_lcdc_dc_ops atmel_hlcdc_ops;
> +extern const struct atmel_lcdc_dc_ops atmel_xlcdc_ops;
>  
>  /**
>   * Atmel HLCDC Display Controller description structure.
> @@ -404,6 +405,7 @@ extern const struct atmel_lcdc_dc_ops atmel_hlcdc_ops;
>   * @conflicting_output_formats: true if RGBXXX output formats conflict with
>   *				each other.
>   * @fixed_clksrc: true if clock source is fixed
> + * @is_xlcdc: true if XLCDC IP is supported
>   * @layers: a layer description table describing available layers
>   * @nlayers: layer description table size
>   * @ops: atmel lcdc dc ops
> @@ -418,6 +420,7 @@ struct atmel_hlcdc_dc_desc {
>  	int max_hpw;
>  	bool conflicting_output_formats;
>  	bool fixed_clksrc;
> +	bool is_xlcdc;
>  	const struct atmel_hlcdc_layer_desc *layers;
>  	int nlayers;
>  	const struct atmel_lcdc_dc_ops *ops;
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index 3427546cd58c..59ddd743ce92 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -331,6 +331,55 @@ void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
>  								     yfactor));
>  }
>  
> +static
> +void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
> +				    struct atmel_hlcdc_plane_state *state)
> +{
> +	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	u32 xfactor, yfactor;
> +
> +	if (!desc->layout.scaler_config)
> +		return;
> +
> +	if (state->crtc_w == state->src_w && state->crtc_h == state->src_h) {
> +		atmel_hlcdc_layer_write_cfg(&plane->layer,
> +					    desc->layout.scaler_config, 0);
> +		return;
> +	}
> +
> +	/* xfactor = round[(2^20 * XMEMSIZE)/XSIZE)] */
> +	xfactor = (u32)(((1 << 20) * state->src_w) / state->crtc_w);
> +
> +	/* yfactor = round[(2^20 * YMEMSIZE)/YSIZE)] */
> +	yfactor = (u32)(((1 << 20) * state->src_h) / state->crtc_h);
> +
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config,
> +				    ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE |
> +				    ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE |
> +				    ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE |
> +				    ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE);
> +
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 1,
> +				    yfactor);
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 3,
> +				    xfactor);
> +
> +	/*
> +	 * With YCbCr 4:2:2 and YCbYcr 4:2:0 window resampling, configuration
> +	 * register LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT is half
> +	 * the value of yfactor and xfactor.
> +	 */
> +	if (state->base.fb->format->format == DRM_FORMAT_YUV420) {
> +		yfactor /= 2;
> +		xfactor /= 2;
> +	}
> +
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 2,
> +				    yfactor);
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 4,
> +				    xfactor);
> +}
> +
>  static void
>  atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
>  				      struct atmel_hlcdc_plane_state *state)
> @@ -395,6 +444,40 @@ void atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
>  				    cfg);
>  }
>  
> +static
> +void atmel_xlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> +					       struct atmel_hlcdc_plane_state *state)
> +{
> +	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> +	const struct drm_format_info *format = state->base.fb->format;
> +	unsigned int cfg;
> +
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, ATMEL_XLCDC_LAYER_DMA_CFG,
> +				    ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id);
> +
> +	cfg = ATMEL_XLCDC_LAYER_DMA | ATMEL_XLCDC_LAYER_REP;
> +
> +	if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) {
> +		/*
> +		 * Alpha Blending bits specific to SAM9X7 SoC
> +		 */
> +		cfg |= ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS |
> +		       ATMEL_XLCDC_LAYER_SFACTA_ONE |
> +		       ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS |
> +		       ATMEL_XLCDC_LAYER_DFACTA_ONE;
> +		if (format->has_alpha)
> +			cfg |= ATMEL_XLCDC_LAYER_A0(0xff);
> +		else
> +			cfg |= ATMEL_XLCDC_LAYER_A0(state->base.alpha);
> +	}
> +
> +	if (state->disc_h && state->disc_w)
> +		cfg |= ATMEL_XLCDC_LAYER_DISCEN;
> +
> +	atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.general_config,
> +				    cfg);
> +}
> +
>  static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
>  					struct atmel_hlcdc_plane_state *state)
>  {
> @@ -461,6 +544,15 @@ static void update_hlcdc_buffers(struct atmel_hlcdc_plane *plane,
>  				    state->dscrs[i]->self);
>  }
>  
> +static void update_xlcdc_buffers(struct atmel_hlcdc_plane *plane,
> +				 struct atmel_hlcdc_plane_state *state,
> +				 u32 sr, int i)

*atmel*_update_xlcdc_buffers()

> +{
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_XLCDC_LAYER_PLANE_ADDR(i),
> +				    state->dscrs[i]->addr);
> +}
> +
>  static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
>  					     struct atmel_hlcdc_plane_state *state)
>  {
> @@ -470,7 +562,8 @@ static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
>  	u32 sr;
>  	int i;
>  
> -	sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
> +	if (!dc->desc->is_xlcdc)
> +		sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
>  
>  	for (i = 0; i < state->nplanes; i++) {
>  		struct drm_gem_dma_object *gem = drm_fb_dma_get_gem_obj(fb, i);
> @@ -739,6 +832,20 @@ static void hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
>  	atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
>  }
>  
> +static void xlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)

Same here: *atmel*_xlcdc_atomic_disable()

> +{
> +	/* Disable interrupts */
> +	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IDR,
> +				    0xffffffff);
> +
> +	/* Disable the layer */
> +	atmel_hlcdc_layer_write_reg(&plane->layer,
> +				    ATMEL_XLCDC_LAYER_ENR, 0);
> +
> +	/* Clear all pending interrupts */
> +	atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
> +}
> +
>  static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
>  					     struct drm_atomic_state *state)
>  {
> @@ -767,6 +874,28 @@ static void hlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
>  				    ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
>  }
>  
> +static void xlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
> +				struct atmel_hlcdc_dc *dc)

*atmel*_xlcdc_atomic_update()

> +{
> +	/* Enable the overrun interrupts. */
> +	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IER,
> +				    ATMEL_XLCDC_LAYER_OVR_IRQ(0) |
> +				    ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
> +				    ATMEL_XLCDC_LAYER_OVR_IRQ(2));
> +
> +	atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_ENR,
> +				    ATMEL_XLCDC_LAYER_EN);
> +
> +	/*
> +	 * Updating XLCDC_xxxCFGx, XLCDC_xxxFBA and XLCDC_xxxEN,
> +	 * (where xxx indicates each layer) requires writing one to the
> +	 * Update Attribute field for each layer in LCDC_ATTRE register for SAM9X7.
> +	 */
> +	regmap_write(dc->hlcdc->regmap, ATMEL_XLCDC_ATTRE, ATMEL_XLCDC_BASE_UPDATE |
> +		     ATMEL_XLCDC_OVR1_UPDATE | ATMEL_XLCDC_OVR3_UPDATE |
> +		     ATMEL_XLCDC_HEO_UPDATE);
> +}
> +
>  static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
>  					    struct drm_atomic_state *state)
>  {
> @@ -815,6 +944,30 @@ static void hlcdc_csc_init(struct atmel_hlcdc_plane *plane,
>  	}
>  }
>  
> +static void xlcdc_csc_init(struct atmel_hlcdc_plane *plane,
> +			   const struct atmel_hlcdc_layer_desc *desc)

*atmel*_xlcdc_csc_init()

> +{
> +	/*
> +	 * yuv-to-rgb-conv-factors are now defined from LCDC_HEOCFG16 to
> +	 * LCDC_HEOCFG21 registers in SAM9X7.
> +	 */
> +	static const u32 xlcdc_csc_coeffs[] = {
> +		0x00000488,
> +		0x00000648,
> +		0x1EA00480,
> +		0x00001D28,
> +		0x08100480,
> +		0x00000000,
> +		0x00000007
> +	};
> +
> +	for (int i = 0; i < ARRAY_SIZE(xlcdc_csc_coeffs); i++) {
> +		atmel_hlcdc_layer_write_cfg(&plane->layer,
> +					    desc->layout.csc + i,
> +					    xlcdc_csc_coeffs[i]);
> +	}
> +}
> +
>  static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
>  {
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> @@ -865,6 +1018,23 @@ static void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
>  			desc->name);
>  }
>  
> +static void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
> +			  const struct atmel_hlcdc_layer_desc *desc)

*atmel*_xlcdc_irq_dbg()

> +{
> +	u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
> +
> +	/*
> +	 * There's not much we can do in case of overrun except informing
> +	 * the user. However, we are in interrupt context here, hence the
> +	 * use of dev_dbg().
> +	 */
> +	if (isr &
> +	    (ATMEL_XLCDC_LAYER_OVR_IRQ(0) | ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
> +	     ATMEL_XLCDC_LAYER_OVR_IRQ(2)))
> +		dev_dbg(plane->base.dev->dev, "overrun on plane %s\n",
> +			desc->name);
> +}
> +
>  void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
>  {
>  	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> @@ -883,6 +1053,16 @@ const struct atmel_lcdc_dc_ops atmel_hlcdc_ops = {
>  	.lcdc_irq_dbg = hlcdc_irq_dbg,
>  };
>  
> +const struct atmel_lcdc_dc_ops atmel_xlcdc_ops = {
> +	.plane_setup_scaler = atmel_xlcdc_plane_setup_scaler,
> +	.update_lcdc_buffers = update_xlcdc_buffers,
> +	.lcdc_atomic_disable = xlcdc_atomic_disable,
> +	.lcdc_update_general_settings = atmel_xlcdc_plane_update_general_settings,
> +	.lcdc_atomic_update = xlcdc_atomic_update,
> +	.lcdc_csc_init = xlcdc_csc_init,
> +	.lcdc_irq_dbg = xlcdc_irq_dbg,
> +};
> +
>  static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
>  	.atomic_check = atmel_hlcdc_plane_atomic_check,
>  	.atomic_update = atmel_hlcdc_plane_atomic_update,


From claudiu.beznea at tuxon.dev  Sat Feb 24 04:52:09 2024
From: claudiu.beznea at tuxon.dev (claudiu beznea)
Date: Sat, 24 Feb 2024 14:52:09 +0200
Subject: [PATCH v8 0/7] Add support for XLCDC to sam9x7 SoC family.
In-Reply-To: <20240221053531.12701-1-manikandan.m@microchip.com>
References: <20240221053531.12701-1-manikandan.m@microchip.com>
Message-ID: <b5d9b028-4a1e-4bbd-9572-290b0042afdc@tuxon.dev>

Hi, Manikandan,

On 21.02.2024 07:35, Manikandan Muralidharan wrote:
> This patch series aims to add support for XLCDC IP of sam9x7 SoC family
> to the DRM subsystem.XLCDC IP has additional registers and new
> configuration bits compared to the existing register set of HLCDC IP.
> The new compatible string "microchip,sam9x75-xlcdc" is defined for sam9x75
> variant of the sam9x7 SoC family.The is_xlcdc flag under driver data and
> IP specific driver ops helps to differentiate the XLCDC and existing HLCDC
> code within the same driver.
> 
> changes in v8:
> * Re-arrange the patch set to prepare and update the current HLCDC
> code base with the new LCDC IP based driver ops and then add support
> for XLCDC code changes.
> * Fix Cosmetic issues.
> 
> changes in v7:
> * LCDC IP driver ops functions are declared static and its 
> declaration are removed.
> 
> changes in v6:
> * Fixed Cosmetic defects.
> * Added comments for readability.
> 
> changes in v5:
> * return value of regmap_read_poll_timeout is checked in failure
> case.
> * HLCDC and XLCDC specific driver functions are now invoked
> using its IP specific driver ops w/o the need of checking is_xlcdc flag.
> * Removed empty spaces and blank lines.
> 
> changes in v4:
> * fixed kernel warnings reported by kernel test robot.
> 
> changes in v3:
> * Removed de-referencing the value of is_xlcdc flag multiple times in
> a single function.
> * Removed cpu_relax() call when using regmap_read_poll_timeout.
> * Updated xfactor and yfactor equations using shift operators
> * Defined CSC co-efficients in an array for code readability.
> 
> changes in v2:
> * Change the driver compatible name from "microchip,sam9x7-xlcdc" to
> "microchip,sam9x75-xlcdc".
> * Move is_xlcdc flag to driver data.
> * Remove unsed Macro definitions.
> * Add co-developed-bys tags
> * Replace regmap_read() with regmap_read_poll_timeout() call
> * Split code into two helpers for code readablitity.
> ---
> 
> Durai Manickam KR (1):
>   drm: atmel-hlcdc: Define XLCDC specific registers
> 
> Manikandan Muralidharan (6):
>   drm: atmel-hlcdc: add driver ops to differentiate HLCDC and XLCDC IP
>   drm: atmel_hlcdc: Add support for XLCDC using IP specific driver ops
>   drm: atmel-hlcdc: add DPI mode support for XLCDC
>   drm: atmel-hlcdc: add vertical and horizontal scaling support for
>     XLCDC
>   drm: atmel-hlcdc: add support for DSI output formats
>   drm: atmel-hlcdc: add LCD controller layer definition for sam9x75
> 

Only minor comments from me (check individual patches). W/ or w/o those
addressed you can add:

Reviewed-by: Claudiu Beznea <claudiu.beznea at tuxon.dev>



From megi at xff.cz  Sat Feb 24 05:50:32 2024
From: megi at xff.cz (=?utf-8?Q?Ond=C5=99ej?= Jirman)
Date: Sat, 24 Feb 2024 14:50:32 +0100
Subject: [PATCH v2 1/5] dt-bindings: sound: Add jack-type property to
 sun8i-a33-codec
In-Reply-To: <42d3ac7d-4b51-4332-8892-a4f03a315a80@kernel.org>
References: <20240223015219.3618111-1-megi@xff.cz>
 <20240223015219.3618111-2-megi@xff.cz>
 <42d3ac7d-4b51-4332-8892-a4f03a315a80@kernel.org>
Message-ID: <sdkcau552puf5afga253hyxc3lqn3dmwk4hjlhojjfe5vvl5zh@ecrx7ecvsj4b>

On Sat, Feb 24, 2024 at 11:31:07AM +0100, Krzysztof Kozlowski wrote:
> On 23/02/2024 02:52, Ond?ej Jirman wrote:
> > From: Ondrej Jirman <megi at xff.cz>
> > 
> > The codec driver needs to know what jack connector is connected to
> > on the board. Add proprty to describe the type of connector.
> > 
> > Signed-off-by: Ondrej Jirman <megi at xff.cz>
> > ---
> 
> Please use scripts/get_maintainers.pl to get a list of necessary people
> and lists to CC. It might happen, that command when run on an older
> kernel, gives you outdated entries. Therefore please be sure you base
> your patches on recent Linux kernel.
> 
> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
> people, so fix your workflow. Tools might also fail if you work on some
> ancient tree (don't, instead use mainline), work on fork of kernel
> (don't, instead use mainline) or you ignore some maintainers (really
> don't). Just use b4 and everything should be fine, although remember
> about `b4 prep --auto-to-cc` if you added new patches to the patchset.
> 
> You missed at least devicetree list (maybe more), so this won't be
> tested by automated tooling. Performing review on untested code might be
> a waste of time, thus I will skip this patch entirely till you follow
> the process allowing the patch to be tested.
> 
> Please kindly resend and include all necessary To/Cc entries.

Yeah, I did run the script on v3 where this patch was not present, and
forgot to re-run it on the new version. I'll resend. In any case I did run DT
tests on the patch.

kind regards,
	o.

> 
> Best regards,
> Krzysztof
> 


From megi at xff.cz  Sat Feb 24 05:54:53 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 24 Feb 2024 14:54:53 +0100
Subject: [RESEND PATCH v2 0/5] Add support for jack detection to codec present in A64 SoC
Message-ID: <20240224135501.3822390-1-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

This series adds support for jack detection to this codec. I used
and tested this on Pinephone. It works quite nicely. I tested it
against Android headset mic button resistor specification.

The patches are improved and debugged version of the original
ones from Arnaud Ferraris and Samuel Holland, imrpoved to better
handle headset button presses and with more robust plug-in/out
event debouncing.

Please take a look. :)

v2:
- use set_jack/get_jack_type
- get rid of some custom poking inside card internals to figure
  out what kind of jack port we should setup the codec for
- read jack-type from OF as suggested here: 
  https://elixir.bootlin.com/linux/latest/source/sound/soc/soc-component.c#L288
- add DT bindings

Thank you very much,
	Ond?ej Jirman

Arnaud Ferraris (2):
  ASoC: sun50i-codec-analog: Enable jack detection on startup
  ASoC: sun8i-codec: Implement jack and accessory detection

Ondrej Jirman (1):
  dt-bindings: sound: Add jack-type property to sun8i-a33-codec

Samuel Holland (2):
  ASoC: sun50i-codec-analog: Move suspend/resume to set_bias_level
  ASoC: sun8i-codec: Enable bus clock at STANDBY and higher bias

 .../sound/allwinner,sun8i-a33-codec.yaml      |   9 +
 sound/soc/sunxi/sun50i-codec-analog.c         |  73 +++-
 sound/soc/sunxi/sun8i-codec.c                 | 359 +++++++++++++++++-
 3 files changed, 421 insertions(+), 20 deletions(-)

-- 
2.43.0



From megi at xff.cz  Sat Feb 24 05:54:54 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 24 Feb 2024 14:54:54 +0100
Subject: [RESEND PATCH v2 1/5] dt-bindings: sound: Add jack-type property to sun8i-a33-codec
In-Reply-To: <20240224135501.3822390-1-megi@xff.cz>
References: <20240224135501.3822390-1-megi@xff.cz>
Message-ID: <20240224135501.3822390-2-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

The codec driver needs to know what jack connector it is connected to
on the board. Add proprty to describe the type of connector.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 .../bindings/sound/allwinner,sun8i-a33-codec.yaml        | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
index 63eadc4200ac..399fc00ad3f4 100644
--- a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
@@ -44,6 +44,15 @@ properties:
       - const: bus
       - const: mod
 
+  jack-type:
+    enum:
+      - headset
+      - headphone
+    description:
+      Type of jack connector connected to the codec. This can be either
+      a 3-pin headphone connector or 4-pin headset connector. If not
+      specified, jack detection is disabled.
+
 required:
   - "#sound-dai-cells"
   - compatible
-- 
2.43.0



From megi at xff.cz  Sat Feb 24 05:54:55 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 24 Feb 2024 14:54:55 +0100
Subject: [RESEND PATCH v2 2/5] ASoC: sun50i-codec-analog: Move suspend/resume to set_bias_level
In-Reply-To: <20240224135501.3822390-1-megi@xff.cz>
References: <20240224135501.3822390-1-megi@xff.cz>
Message-ID: <20240224135501.3822390-3-megi@xff.cz>

From: Samuel Holland <samuel at sholland.org>

With idle_bias_on and suspend_bias_off, there are bias level transitions
that match the suspend/resume callbacks. However, there are also
transitions during probe (OFF => STANDBY) and removal (STANDBY => OFF).

By using the set_bias_level hook, the driver can have one copy of code
that would otherwise be duplicated between the probe/resume and
suspend/remove hooks.

Signed-off-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Ond?ej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun50i-codec-analog.c | 29 +++++++++++++++++----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index 8a32d05e23e1..cedd4de42d1a 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -471,17 +471,23 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
 	{ "EARPIECE", NULL, "Earpiece Amp" },
 };
 
-static int sun50i_a64_codec_suspend(struct snd_soc_component *component)
+static int sun50i_a64_codec_set_bias_level(struct snd_soc_component *component,
+					   enum snd_soc_bias_level level)
 {
-	return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
-				  BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE),
-				  BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
-}
+	switch (level) {
+	case SND_SOC_BIAS_OFF:
+		regmap_set_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
+				BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
+		break;
+	case SND_SOC_BIAS_STANDBY:
+		regmap_clear_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
+				   BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
+		break;
+	default:
+		break;
+	}
 
-static int sun50i_a64_codec_resume(struct snd_soc_component *component)
-{
-	return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
-				  BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE), 0);
+	return 0;
 }
 
 static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = {
@@ -491,8 +497,9 @@ static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = {
 	.num_dapm_widgets	= ARRAY_SIZE(sun50i_a64_codec_widgets),
 	.dapm_routes		= sun50i_a64_codec_routes,
 	.num_dapm_routes	= ARRAY_SIZE(sun50i_a64_codec_routes),
-	.suspend		= sun50i_a64_codec_suspend,
-	.resume			= sun50i_a64_codec_resume,
+	.set_bias_level		= sun50i_a64_codec_set_bias_level,
+	.idle_bias_on		= true,
+	.suspend_bias_off	= true,
 };
 
 static const struct of_device_id sun50i_codec_analog_of_match[] = {
-- 
2.43.0



From megi at xff.cz  Sat Feb 24 05:54:56 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 24 Feb 2024 14:54:56 +0100
Subject: [RESEND PATCH v2 3/5] ASoC: sun8i-codec: Enable bus clock at STANDBY and higher bias
In-Reply-To: <20240224135501.3822390-1-megi@xff.cz>
References: <20240224135501.3822390-1-megi@xff.cz>
Message-ID: <20240224135501.3822390-4-megi@xff.cz>

From: Samuel Holland <samuel at sholland.org>

For codec variants that have a bus clock, that clock must be running to
receive interrupts. Since jack and mic accessory detection should work
even when no audio is playing, that means the bus clock should be
enabled any time the system is on.

Accomplish that by tying the bus clock to the runtime PM state, which is
then tied to the bias level not being OFF. Since the codec sets
idle_bias_on, bias will generally never be OFF. However, we can set
suspend_bias_off to maintain the power savings of gating the bus clock
during suspend, when we don't expect jack/accessory detection to work.

Signed-off-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Ond?ej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun8i-codec.c | 41 ++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 7b45ddffe990..2a46b96b03cc 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -177,12 +177,14 @@ struct sun8i_codec_aif {
 };
 
 struct sun8i_codec_quirks {
-	bool legacy_widgets	: 1;
-	bool lrck_inversion	: 1;
+	bool	bus_clock	: 1;
+	bool	legacy_widgets	: 1;
+	bool	lrck_inversion	: 1;
 };
 
 struct sun8i_codec {
 	struct regmap			*regmap;
+	struct clk			*clk_bus;
 	struct clk			*clk_module;
 	const struct sun8i_codec_quirks	*quirks;
 	struct sun8i_codec_aif		aifs[SUN8I_CODEC_NAIFS];
@@ -197,6 +199,14 @@ static int sun8i_codec_runtime_resume(struct device *dev)
 	struct sun8i_codec *scodec = dev_get_drvdata(dev);
 	int ret;
 
+	if (scodec->clk_bus) {
+		ret = clk_prepare_enable(scodec->clk_bus);
+		if (ret) {
+			dev_err(dev, "Failed to enable the bus clock\n");
+			return ret;
+		}
+	}
+
 	regcache_cache_only(scodec->regmap, false);
 
 	ret = regcache_sync(scodec->regmap);
@@ -215,6 +225,9 @@ static int sun8i_codec_runtime_suspend(struct device *dev)
 	regcache_cache_only(scodec->regmap, true);
 	regcache_mark_dirty(scodec->regmap);
 
+	if (scodec->clk_bus)
+		clk_disable_unprepare(scodec->clk_bus);
+
 	return 0;
 }
 
@@ -1277,6 +1290,7 @@ static const struct snd_soc_component_driver sun8i_soc_component = {
 	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
 	.probe			= sun8i_codec_component_probe,
 	.idle_bias_on		= 1,
+	.suspend_bias_off	= 1,
 	.endianness		= 1,
 };
 
@@ -1299,6 +1313,18 @@ static int sun8i_codec_probe(struct platform_device *pdev)
 	if (!scodec)
 		return -ENOMEM;
 
+	scodec->quirks = of_device_get_match_data(&pdev->dev);
+
+	platform_set_drvdata(pdev, scodec);
+
+	if (scodec->quirks->bus_clock) {
+		scodec->clk_bus = devm_clk_get(&pdev->dev, "bus");
+		if (IS_ERR(scodec->clk_bus)) {
+			dev_err(&pdev->dev, "Failed to get the bus clock\n");
+			return PTR_ERR(scodec->clk_bus);
+		}
+	}
+
 	scodec->clk_module = devm_clk_get(&pdev->dev, "mod");
 	if (IS_ERR(scodec->clk_module)) {
 		dev_err(&pdev->dev, "Failed to get the module clock\n");
@@ -1311,17 +1337,14 @@ static int sun8i_codec_probe(struct platform_device *pdev)
 		return PTR_ERR(base);
 	}
 
-	scodec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "bus", base,
-						   &sun8i_codec_regmap_config);
+	scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+					       &sun8i_codec_regmap_config);
 	if (IS_ERR(scodec->regmap)) {
 		dev_err(&pdev->dev, "Failed to create our regmap\n");
 		return PTR_ERR(scodec->regmap);
 	}
 
-	scodec->quirks = of_device_get_match_data(&pdev->dev);
-
-	platform_set_drvdata(pdev, scodec);
-
+	regcache_cache_only(scodec->regmap, true);
 	pm_runtime_enable(&pdev->dev);
 	if (!pm_runtime_enabled(&pdev->dev)) {
 		ret = sun8i_codec_runtime_resume(&pdev->dev);
@@ -1357,11 +1380,13 @@ static void sun8i_codec_remove(struct platform_device *pdev)
 }
 
 static const struct sun8i_codec_quirks sun8i_a33_quirks = {
+	.bus_clock	= true,
 	.legacy_widgets	= true,
 	.lrck_inversion	= true,
 };
 
 static const struct sun8i_codec_quirks sun50i_a64_quirks = {
+	.bus_clock	= true,
 };
 
 static const struct of_device_id sun8i_codec_of_match[] = {
-- 
2.43.0



From megi at xff.cz  Sat Feb 24 05:54:57 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 24 Feb 2024 14:54:57 +0100
Subject: [RESEND PATCH v2 4/5] ASoC: sun50i-codec-analog: Enable jack detection on startup
In-Reply-To: <20240224135501.3822390-1-megi@xff.cz>
References: <20240224135501.3822390-1-megi@xff.cz>
Message-ID: <20240224135501.3822390-5-megi@xff.cz>

From: Arnaud Ferraris <arnaud.ferraris at collabora.com>

This commit adds the necessary setup to enable jack detection on startup
as well as the callback function enabling the microphone ADC when
headset bias is enabled. The microphone ADC is also disabled in suspend.

Signed-off-by: Arnaud Ferraris <arnaud.ferraris at collabora.com>
[Samuel: Moved MICADCEN setup to HBIAS event, added bias hooks]
Signed-off-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Ond?ej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun50i-codec-analog.c | 32 ++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index cedd4de42d1a..2081721a8ff2 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -116,8 +116,10 @@
 #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN	7
 
 #define SUN50I_ADDA_JACK_MIC_CTRL	0x1d
+#define SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN	7
 #define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN	6
 #define SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN	5
+#define SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN	4
 
 /* mixer controls */
 static const struct snd_kcontrol_new sun50i_a64_codec_mixer_controls[] = {
@@ -296,6 +298,19 @@ static const struct snd_kcontrol_new sun50i_codec_earpiece_switch[] = {
 			SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE, 1, 0),
 };
 
+static int sun50i_codec_hbias_event(struct snd_soc_dapm_widget *w,
+				    struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+	u32 value = !!SND_SOC_DAPM_EVENT_ON(event);
+
+	regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
+			   BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN),
+			   value << SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN);
+
+	return 0;
+}
+
 static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
 	/* DAC */
 	SND_SOC_DAPM_DAC("Left DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL,
@@ -367,7 +382,8 @@ static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
 	/* Microphone Bias */
 	SND_SOC_DAPM_SUPPLY("HBIAS", SUN50I_ADDA_JACK_MIC_CTRL,
 			    SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN,
-			    0, NULL, 0),
+			    0, sun50i_codec_hbias_event,
+			    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
 	/* Mic input path */
 	SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN50I_ADDA_MIC2_CTRL,
@@ -474,14 +490,28 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
 static int sun50i_a64_codec_set_bias_level(struct snd_soc_component *component,
 					   enum snd_soc_bias_level level)
 {
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	int hbias;
+
 	switch (level) {
 	case SND_SOC_BIAS_OFF:
+		regmap_clear_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) |
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN));
+
 		regmap_set_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
 				BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		regmap_clear_bits(component->regmap, SUN50I_ADDA_HP_CTRL,
 				   BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE));
+
+		hbias = snd_soc_dapm_get_pin_status(dapm, "HBIAS");
+		regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL,
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) |
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN),
+				   BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) |
+				   hbias << SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN);
 		break;
 	default:
 		break;
-- 
2.43.0



From megi at xff.cz  Sat Feb 24 05:54:58 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 24 Feb 2024 14:54:58 +0100
Subject: [RESEND PATCH v2 5/5] ASoC: sun8i-codec: Implement jack and accessory detection
In-Reply-To: <20240224135501.3822390-1-megi@xff.cz>
References: <20240224135501.3822390-1-megi@xff.cz>
Message-ID: <20240224135501.3822390-6-megi@xff.cz>

From: Arnaud Ferraris <arnaud.ferraris at collabora.com>

Add support for the jack detection functionality in the A64 variant,
which uses a pair of IRQs; and microphone accessory (button) detection,
which uses an ADC with an IRQ trigger.

IRQs will only be triggered if the JACKDETEN, HMICBIASEN, and MICADCEN
bits are set appropriately in the analog codec component
(sun50i-codec-analog), but there is no direct software dependency
between the two components.

Setup ADC so that it samples with period of 16ms, disable smoothing
and enable MDATA threshold (should be below idle voltage/HMIC_DATA
value). Also enable HMIC_N, which makes sure we get HMIC_N samples
after HMIC_DATA crosses the threshold.

This allows us to perform steady state detection of HMIC_DATA, by
comparing current and previous ADC samples, to detect end of the
transient when the user de-presses the button. Otherwise ADC could
sample anywhere within the transient, and the driver may mis-issue
key-press events for other buttons attached to the resistor ladder.

Signed-off-by: Arnaud Ferraris <arnaud.ferraris at collabora.com>
[Samuel: Decouple from analog codec, fixes]
Co-developed-by: Samuel Holland <samuel at sholland.org>
Signed-off-by: Samuel Holland <samuel at sholland.org>
[Ondrej: Almost complete rewrite of the patch, change to use set_jack/
get_jack_type. Better de-bounce, fix mic button handling, better
interrupt processing.]
Co-developed-by: Ondrej Jirman <megi at xff.cz>
Signed-off-by: Ondrej Jirman <megi at xff.cz>
---
 sound/soc/sunxi/sun50i-codec-analog.c |  12 +
 sound/soc/sunxi/sun8i-codec.c         | 318 ++++++++++++++++++++++++++
 2 files changed, 330 insertions(+)

diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index 2081721a8ff2..2dcdf113b66e 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -115,6 +115,11 @@
 #define SUN50I_ADDA_HS_MBIAS_CTRL	0x0e
 #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN	7
 
+#define SUN50I_ADDA_MDET_CTRL		0x1c
+#define SUN50I_ADDA_MDET_CTRL_SELDETADC_FS	4
+#define SUN50I_ADDA_MDET_CTRL_SELDETADC_DB	2
+#define SUN50I_ADDA_MDET_CTRL_SELDETADC_BF	0
+
 #define SUN50I_ADDA_JACK_MIC_CTRL	0x1d
 #define SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN	7
 #define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN	6
@@ -564,6 +569,13 @@ static int sun50i_codec_analog_probe(struct platform_device *pdev)
 			   BIT(SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN),
 			   enable << SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN);
 
+	/* Select sample interval of the ADC sample to 16ms */
+	regmap_update_bits(regmap, SUN50I_ADDA_MDET_CTRL,
+			   0x7 << SUN50I_ADDA_MDET_CTRL_SELDETADC_FS |
+			   0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_BF,
+			   0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_FS |
+			   0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_BF);
+
 	return devm_snd_soc_register_component(&pdev->dev,
 					       &sun50i_codec_analog_cmpnt_drv,
 					       NULL, 0);
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 2a46b96b03cc..097418364985 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -12,12 +12,16 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/input.h>
 #include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/log2.h>
 
+#include <sound/jack.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
@@ -118,6 +122,23 @@
 #define SUN8I_ADC_VOL_CTRL				0x104
 #define SUN8I_ADC_VOL_CTRL_ADCL_VOL			8
 #define SUN8I_ADC_VOL_CTRL_ADCR_VOL			0
+#define SUN8I_HMIC_CTRL1				0x110
+#define SUN8I_HMIC_CTRL1_HMIC_M				12
+#define SUN8I_HMIC_CTRL1_HMIC_N				8
+#define SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB		5
+#define SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN		4
+#define SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN			3
+#define SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN		0
+#define SUN8I_HMIC_CTRL2				0x114
+#define SUN8I_HMIC_CTRL2_HMIC_SAMPLE			14
+#define SUN8I_HMIC_CTRL2_HMIC_MDATA_THRESHOLD		8
+#define SUN8I_HMIC_CTRL2_HMIC_SF			6
+#define SUN8I_HMIC_STS					0x118
+#define SUN8I_HMIC_STS_MDATA_DISCARD			13
+#define SUN8I_HMIC_STS_HMIC_DATA			8
+#define SUN8I_HMIC_STS_JACK_OUT_IRQ_ST			4
+#define SUN8I_HMIC_STS_JACK_IN_IRQ_ST			3
+#define SUN8I_HMIC_STS_HMIC_DATA_IRQ_ST			0
 #define SUN8I_DAC_DIG_CTRL				0x120
 #define SUN8I_DAC_DIG_CTRL_ENDA				15
 #define SUN8I_DAC_VOL_CTRL				0x124
@@ -143,6 +164,17 @@
 #define SUN8I_AIF_CLK_CTRL_WORD_SIZ_MASK	GENMASK(5, 4)
 #define SUN8I_AIF_CLK_CTRL_DATA_FMT_MASK	GENMASK(3, 2)
 #define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK	GENMASK(1, 0)
+#define SUN8I_HMIC_CTRL1_HMIC_M_MASK		GENMASK(15, 12)
+#define SUN8I_HMIC_CTRL1_HMIC_N_MASK		GENMASK(11, 8)
+#define SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB_MASK GENMASK(6, 5)
+#define SUN8I_HMIC_CTRL2_HMIC_SAMPLE_MASK	GENMASK(15, 14)
+#define SUN8I_HMIC_CTRL2_HMIC_SF_MASK		GENMASK(7, 6)
+#define SUN8I_HMIC_STS_HMIC_DATA_MASK		GENMASK(12, 8)
+
+#define SUN8I_CODEC_BUTTONS	(SND_JACK_BTN_0|\
+				 SND_JACK_BTN_1|\
+				 SND_JACK_BTN_2|\
+				 SND_JACK_BTN_3)
 
 #define SUN8I_CODEC_PASSTHROUGH_SAMPLE_RATE 48000
 
@@ -178,16 +210,32 @@ struct sun8i_codec_aif {
 
 struct sun8i_codec_quirks {
 	bool	bus_clock	: 1;
+	bool	jack_detection	: 1;
 	bool	legacy_widgets	: 1;
 	bool	lrck_inversion	: 1;
 };
 
+enum {
+	SUN8I_JACK_STATUS_DISCONNECTED,
+	SUN8I_JACK_STATUS_WAITING_HBIAS,
+	SUN8I_JACK_STATUS_CONNECTED,
+};
+
 struct sun8i_codec {
+	struct snd_soc_component	*component;
 	struct regmap			*regmap;
 	struct clk			*clk_bus;
 	struct clk			*clk_module;
 	const struct sun8i_codec_quirks	*quirks;
 	struct sun8i_codec_aif		aifs[SUN8I_CODEC_NAIFS];
+	struct snd_soc_jack		*jack;
+	struct delayed_work		jack_work;
+	int				jack_irq;
+	int				jack_status;
+	int				jack_last_sample;
+	ktime_t				jack_hbias_ready;
+	struct mutex			jack_mutex;
+	int				last_hmic_irq;
 	unsigned int			sysclk_rate;
 	int				sysclk_refcnt;
 };
@@ -1245,6 +1293,8 @@ static int sun8i_codec_component_probe(struct snd_soc_component *component)
 	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
 	int ret;
 
+	scodec->component = component;
+
 	/* Add widgets for backward compatibility with old device trees. */
 	if (scodec->quirks->legacy_widgets) {
 		ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_legacy_widgets,
@@ -1281,6 +1331,263 @@ static int sun8i_codec_component_probe(struct snd_soc_component *component)
 	return 0;
 }
 
+static void sun8i_codec_set_hmic_bias(struct sun8i_codec *scodec, bool enable)
+{
+	struct snd_soc_dapm_context *dapm = &scodec->component->card->dapm;
+	int irq_mask = BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN);
+
+	if (enable)
+		snd_soc_dapm_force_enable_pin(dapm, "HBIAS");
+	else
+		snd_soc_dapm_disable_pin(dapm, "HBIAS");
+
+	snd_soc_dapm_sync(dapm);
+
+	regmap_update_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
+			   irq_mask, enable ? irq_mask : 0);
+}
+
+static void sun8i_codec_jack_work(struct work_struct *work)
+{
+	struct sun8i_codec *scodec = container_of(work, struct sun8i_codec,
+						  jack_work.work);
+	unsigned int mdata;
+	int type_mask = scodec->jack->jack->type;
+	int type;
+
+	guard(mutex)(&scodec->jack_mutex);
+
+	if (scodec->jack_status == SUN8I_JACK_STATUS_DISCONNECTED) {
+		if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_IN_IRQ_ST)
+			return;
+
+		scodec->jack_last_sample = -1;
+
+		if (type_mask & SND_JACK_MICROPHONE) {
+			/*
+			 * If we were in disconnected state, we enable HBIAS and
+			 * wait 600ms before reading initial HDATA value.
+			 */
+			scodec->jack_hbias_ready = ktime_add_ms(ktime_get(), 600);
+			sun8i_codec_set_hmic_bias(scodec, true);
+			queue_delayed_work(system_power_efficient_wq,
+					   &scodec->jack_work,
+					   msecs_to_jiffies(610));
+			scodec->jack_status = SUN8I_JACK_STATUS_WAITING_HBIAS;
+		} else {
+			snd_soc_jack_report(scodec->jack, SND_JACK_HEADPHONE,
+					    type_mask);
+			scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED;
+		}
+	} else if (scodec->jack_status == SUN8I_JACK_STATUS_WAITING_HBIAS) {
+		/*
+		 * If we're waiting for HBIAS to stabilize, and we get plug-out
+		 * interrupt and nothing more for > 100ms, just cancel the
+		 * initialization.
+		 */
+		if (scodec->last_hmic_irq == SUN8I_HMIC_STS_JACK_OUT_IRQ_ST) {
+			scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED;
+			sun8i_codec_set_hmic_bias(scodec, false);
+			return;
+		}
+
+		/*
+		 * If we're not done waiting for HBIAS to stabilize, wait more.
+		 */
+		if (!ktime_after(ktime_get(), scodec->jack_hbias_ready)) {
+			s64 msecs = ktime_ms_delta(scodec->jack_hbias_ready,
+						   ktime_get());
+
+			queue_delayed_work(system_power_efficient_wq,
+					   &scodec->jack_work,
+					   msecs_to_jiffies(msecs + 10));
+			return;
+		}
+
+		/*
+		 * Everything is stabilized, determine jack type and report it.
+		 */
+		regmap_read(scodec->regmap, SUN8I_HMIC_STS, &mdata);
+		mdata &= SUN8I_HMIC_STS_HMIC_DATA_MASK;
+		mdata >>= SUN8I_HMIC_STS_HMIC_DATA;
+
+		regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0);
+
+		type = mdata < 16 ? SND_JACK_HEADPHONE : SND_JACK_HEADSET;
+		if (type == SND_JACK_HEADPHONE)
+			sun8i_codec_set_hmic_bias(scodec, false);
+
+		snd_soc_jack_report(scodec->jack, type, type_mask);
+		scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED;
+	} else if (scodec->jack_status == SUN8I_JACK_STATUS_CONNECTED) {
+		if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_OUT_IRQ_ST)
+			return;
+
+		scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED;
+		if (type_mask & SND_JACK_MICROPHONE)
+			sun8i_codec_set_hmic_bias(scodec, false);
+
+		snd_soc_jack_report(scodec->jack, 0, type_mask);
+	}
+}
+
+static irqreturn_t sun8i_codec_jack_irq(int irq, void *dev_id)
+{
+	struct sun8i_codec *scodec = dev_id;
+	int type = SND_JACK_HEADSET;
+	unsigned int status, value;
+
+	guard(mutex)(&scodec->jack_mutex);
+
+	regmap_read(scodec->regmap, SUN8I_HMIC_STS, &status);
+	regmap_write(scodec->regmap, SUN8I_HMIC_STS, status);
+
+	/*
+	 * De-bounce in/out interrupts via a delayed work re-scheduling to
+	 * 100ms after each interrupt..
+	 */
+	if (status & BIT(SUN8I_HMIC_STS_JACK_OUT_IRQ_ST)) {
+		/*
+		 * Out interrupt has priority over in interrupt so that if
+		 * we get both, we assume the disconnected state, which is
+		 * safer.
+		 */
+		scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_OUT_IRQ_ST;
+		mod_delayed_work(system_power_efficient_wq, &scodec->jack_work,
+				 msecs_to_jiffies(100));
+	} else if (status & BIT(SUN8I_HMIC_STS_JACK_IN_IRQ_ST)) {
+		scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_IN_IRQ_ST;
+		mod_delayed_work(system_power_efficient_wq, &scodec->jack_work,
+				 msecs_to_jiffies(100));
+	} else if (status & BIT(SUN8I_HMIC_STS_HMIC_DATA_IRQ_ST)) {
+		/*
+		 * Ignore data interrupts until jack status turns to connected
+		 * state, which is after HMIC enable stabilization is completed.
+		 * Until then tha data are bogus.
+		 */
+		if (scodec->jack_status != SUN8I_JACK_STATUS_CONNECTED)
+			return IRQ_HANDLED;
+
+		value = (status & SUN8I_HMIC_STS_HMIC_DATA_MASK) >>
+			SUN8I_HMIC_STS_HMIC_DATA;
+
+		/*
+		 * Assumes 60 mV per ADC LSB increment, 2V bias voltage, 2.2kOhm
+		 * bias resistor.
+		 */
+		if (value == 0)
+			type |= SND_JACK_BTN_0;
+		else if (value == 1)
+			type |= SND_JACK_BTN_3;
+		else if (value <= 3)
+			type |= SND_JACK_BTN_1;
+		else if (value <= 8)
+			type |= SND_JACK_BTN_2;
+
+		/*
+		 * De-bounce. Only report button after two consecutive A/D
+		 * samples are identical.
+		 */
+		if (scodec->jack_last_sample >= 0 &&
+		    scodec->jack_last_sample == value)
+			snd_soc_jack_report(scodec->jack, type,
+					    scodec->jack->jack->type);
+
+		scodec->jack_last_sample = value;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int sun8i_codec_enable_jack_detect(struct snd_soc_component *component,
+					  struct snd_soc_jack *jack, void *data)
+{
+	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
+	struct platform_device *pdev = to_platform_device(component->dev);
+	int ret;
+
+	if (!scodec->quirks->jack_detection)
+		return 0;
+
+	scodec->jack = jack;
+
+	scodec->jack_irq = platform_get_irq(pdev, 0);
+	if (scodec->jack_irq < 0)
+		return scodec->jack_irq;
+
+	/* Reserved value required for jack IRQs to trigger. */
+	regmap_write(scodec->regmap, SUN8I_HMIC_CTRL1,
+			   0xf << SUN8I_HMIC_CTRL1_HMIC_N |
+			   0x0 << SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB |
+			   0x4 << SUN8I_HMIC_CTRL1_HMIC_M);
+
+	/* Sample the ADC at 128 Hz; bypass smooth filter. */
+	regmap_write(scodec->regmap, SUN8I_HMIC_CTRL2,
+			   0x0 << SUN8I_HMIC_CTRL2_HMIC_SAMPLE |
+			   0x17 << SUN8I_HMIC_CTRL2_HMIC_MDATA_THRESHOLD |
+			   0x0 << SUN8I_HMIC_CTRL2_HMIC_SF);
+
+	/* Do not discard any MDATA, enable user written MDATA threshold. */
+	regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0);
+
+	regmap_set_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
+			BIT(SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN) |
+			BIT(SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN));
+
+	ret = devm_request_threaded_irq(&pdev->dev, scodec->jack_irq,
+					NULL, sun8i_codec_jack_irq,
+					IRQF_ONESHOT,
+					dev_name(&pdev->dev), scodec);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void sun8i_codec_disable_jack_detect(struct snd_soc_component *component)
+{
+	struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
+
+	if (!scodec->quirks->jack_detection)
+		return;
+
+	devm_free_irq(component->dev, scodec->jack_irq, scodec);
+
+	cancel_delayed_work_sync(&scodec->jack_work);
+
+	regmap_clear_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
+			  BIT(SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN) |
+			  BIT(SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN) |
+			  BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN));
+
+	scodec->jack = NULL;
+}
+
+static int sun8i_codec_component_get_jack_type(struct snd_soc_component *component)
+{
+	struct device_node *node = component->dev->of_node;
+
+	if (of_property_match_string(node, "jack-type", "headset") >= 0)
+		return SND_JACK_HEADSET | SUN8I_CODEC_BUTTONS;
+	else if (of_property_match_string(node, "jack-type", "headphone") >= 0)
+		return SND_JACK_HEADPHONE;
+
+	return 0;
+}
+
+static int sun8i_codec_component_set_jack(struct snd_soc_component *component,
+					  struct snd_soc_jack *jack, void *data)
+{
+	int ret = 0;
+
+	if (jack)
+		ret = sun8i_codec_enable_jack_detect(component, jack, data);
+	else
+		sun8i_codec_disable_jack_detect(component);
+
+	return ret;
+}
+
 static const struct snd_soc_component_driver sun8i_soc_component = {
 	.controls		= sun8i_codec_controls,
 	.num_controls		= ARRAY_SIZE(sun8i_codec_controls),
@@ -1288,16 +1595,24 @@ static const struct snd_soc_component_driver sun8i_soc_component = {
 	.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
 	.dapm_routes		= sun8i_codec_dapm_routes,
 	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
+	.set_jack		= sun8i_codec_component_set_jack,
+	.get_jack_type		= sun8i_codec_component_get_jack_type,
 	.probe			= sun8i_codec_component_probe,
 	.idle_bias_on		= 1,
 	.suspend_bias_off	= 1,
 	.endianness		= 1,
 };
 
+static bool sun8i_codec_volatile_reg(struct device *dev, unsigned int reg)
+{
+	return reg == SUN8I_HMIC_STS;
+}
+
 static const struct regmap_config sun8i_codec_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
 	.val_bits	= 32,
+	.volatile_reg	= sun8i_codec_volatile_reg,
 	.max_register	= SUN8I_DAC_MXR_SRC,
 
 	.cache_type	= REGCACHE_FLAT,
@@ -1314,6 +1629,8 @@ static int sun8i_codec_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	scodec->quirks = of_device_get_match_data(&pdev->dev);
+	INIT_DELAYED_WORK(&scodec->jack_work, sun8i_codec_jack_work);
+	mutex_init(&scodec->jack_mutex);
 
 	platform_set_drvdata(pdev, scodec);
 
@@ -1387,6 +1704,7 @@ static const struct sun8i_codec_quirks sun8i_a33_quirks = {
 
 static const struct sun8i_codec_quirks sun50i_a64_quirks = {
 	.bus_clock	= true,
+	.jack_detection	= true,
 };
 
 static const struct of_device_id sun8i_codec_of_match[] = {
-- 
2.43.0



From megi at xff.cz  Sat Feb 24 07:05:59 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 24 Feb 2024 16:05:59 +0100
Subject: [PATCH v2 2/3] drm/sun4i: Add more parameters to sunxi_engine commit callback
In-Reply-To: <20240224150604.3855534-1-megi@xff.cz>
References: <20240224150604.3855534-1-megi@xff.cz>
Message-ID: <20240224150604.3855534-3-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

These will be needed later on when we move layer configuration to
crtc update.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
Reviewed-by: Maxime Ripard <mripard at kernel.org>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/gpu/drm/sun4i/sun4i_backend.c |  4 +++-
 drivers/gpu/drm/sun4i/sun4i_crtc.c    |  2 +-
 drivers/gpu/drm/sun4i/sun8i_mixer.c   |  5 ++++-
 drivers/gpu/drm/sun4i/sunxi_engine.h  | 13 ++++++++++---
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index 335fd0edb904..e89eb96d3131 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -69,7 +69,9 @@ static void sun4i_backend_disable_color_correction(struct sunxi_engine *engine)
 			   SUN4I_BACKEND_OCCTL_ENABLE, 0);
 }
 
-static void sun4i_backend_commit(struct sunxi_engine *engine)
+static void sun4i_backend_commit(struct sunxi_engine *engine,
+				 struct drm_crtc *crtc,
+				 struct drm_atomic_state *state)
 {
 	DRM_DEBUG_DRIVER("Committing changes\n");
 
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
index c06d7cd45388..18e74047b0f5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
@@ -91,7 +91,7 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
 
 	DRM_DEBUG_DRIVER("Committing plane changes\n");
 
-	sunxi_engine_commit(scrtc->engine);
+	sunxi_engine_commit(scrtc->engine, crtc, state);
 
 	if (event) {
 		crtc->state->event = NULL;
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 1e681314e379..bdeb9b80e038 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 
+#include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_framebuffer.h>
@@ -249,7 +250,9 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format)
 	return -EINVAL;
 }
 
-static void sun8i_mixer_commit(struct sunxi_engine *engine)
+static void sun8i_mixer_commit(struct sunxi_engine *engine,
+			       struct drm_crtc *crtc,
+			       struct drm_atomic_state *state)
 {
 	DRM_DEBUG_DRIVER("Committing changes\n");
 
diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h
index ec8cf9b2bda4..ec0c4932f15c 100644
--- a/drivers/gpu/drm/sun4i/sunxi_engine.h
+++ b/drivers/gpu/drm/sun4i/sunxi_engine.h
@@ -7,6 +7,7 @@
 #define _SUNXI_ENGINE_H_
 
 struct drm_plane;
+struct drm_crtc;
 struct drm_device;
 struct drm_crtc_state;
 struct drm_display_mode;
@@ -59,7 +60,9 @@ struct sunxi_engine_ops {
 	 *
 	 * This function is optional.
 	 */
-	void (*commit)(struct sunxi_engine *engine);
+	void (*commit)(struct sunxi_engine *engine,
+		       struct drm_crtc *crtc,
+		       struct drm_atomic_state *state);
 
 	/**
 	 * @layers_init:
@@ -144,12 +147,16 @@ struct sunxi_engine {
 /**
  * sunxi_engine_commit() - commit all changes of the engine
  * @engine:	pointer to the engine
+ * @crtc:	pointer to crtc the engine is associated with
+ * @state:	atomic state
  */
 static inline void
-sunxi_engine_commit(struct sunxi_engine *engine)
+sunxi_engine_commit(struct sunxi_engine *engine,
+		    struct drm_crtc *crtc,
+		    struct drm_atomic_state *state)
 {
 	if (engine->ops && engine->ops->commit)
-		engine->ops->commit(engine);
+		engine->ops->commit(engine, crtc, state);
 }
 
 /**
-- 
2.44.0



From megi at xff.cz  Sat Feb 24 07:05:57 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 24 Feb 2024 16:05:57 +0100
Subject: [PATCH v2 0/3] Move blender setup from individual planes to crtc commit in sun4i-drm
Message-ID: <20240224150604.3855534-1-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

This series refactors blender setup from individual planes to a common
place where it can be performed at once and is easier to reason about.

In the process this fixes a few bugs that allowed blender pipes to be
disabled while corresponding DRM planes were requested to be enabled.

Please take a look. :)

v2:
- use regmap_write where possible
- add review tags

Thank you very much,
	Ond?ej Jirman

Ondrej Jirman (3):
  drm/sun4i: Unify sun8i_*_layer structs
  drm/sun4i: Add more parameters to sunxi_engine commit callback
  drm/sun4i: Fix layer zpos change/atomic modesetting

 drivers/gpu/drm/sun4i/sun4i_backend.c  |  4 +-
 drivers/gpu/drm/sun4i/sun4i_crtc.c     |  2 +-
 drivers/gpu/drm/sun4i/sun8i_mixer.c    | 70 ++++++++++++++++++++-
 drivers/gpu/drm/sun4i/sun8i_mixer.h    | 20 ++++++
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 85 +++----------------------
 drivers/gpu/drm/sun4i/sun8i_ui_layer.h | 20 ++----
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 86 +++-----------------------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.h | 20 ++----
 drivers/gpu/drm/sun4i/sunxi_engine.h   | 13 +++-
 9 files changed, 125 insertions(+), 195 deletions(-)

-- 
2.44.0



From megi at xff.cz  Sat Feb 24 07:05:58 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 24 Feb 2024 16:05:58 +0100
Subject: [PATCH v2 1/3] drm/sun4i: Unify sun8i_*_layer structs
In-Reply-To: <20240224150604.3855534-1-megi@xff.cz>
References: <20240224150604.3855534-1-megi@xff.cz>
Message-ID: <20240224150604.3855534-2-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

These structs are identical, use a single struct to represent private
data for the DRM plane. This is a preparation for configuring layer
routing from the CRTC (mixer) instead of current approach of setting
up routing from individual layer's atomic_update callback.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
Reviewed-by: Maxime Ripard <mripard at kernel.org>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c    |  4 ++--
 drivers/gpu/drm/sun4i/sun8i_mixer.h    | 14 ++++++++++++++
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 14 +++++++-------
 drivers/gpu/drm/sun4i/sun8i_ui_layer.h | 20 ++++----------------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 14 +++++++-------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.h | 20 ++++----------------
 6 files changed, 38 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 01382860aaee..1e681314e379 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -271,7 +271,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
 		return ERR_PTR(-ENOMEM);
 
 	for (i = 0; i < mixer->cfg->vi_num; i++) {
-		struct sun8i_vi_layer *layer;
+		struct sun8i_layer *layer;
 
 		layer = sun8i_vi_layer_init_one(drm, mixer, i);
 		if (IS_ERR(layer)) {
@@ -284,7 +284,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
 	}
 
 	for (i = 0; i < mixer->cfg->ui_num; i++) {
-		struct sun8i_ui_layer *layer;
+		struct sun8i_layer *layer;
 
 		layer = sun8i_ui_layer_init_one(drm, mixer, i);
 		if (IS_ERR(layer)) {
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 85c94884fb9a..5a610ee30301 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -9,6 +9,7 @@
 #include <linux/clk.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
+#include <drm/drm_plane.h>
 
 #include "sunxi_engine.h"
 
@@ -185,6 +186,19 @@ struct sun8i_mixer {
 	struct clk			*mod_clk;
 };
 
+struct sun8i_layer {
+	struct drm_plane	plane;
+	struct sun8i_mixer	*mixer;
+	int			channel;
+	int			overlay;
+};
+
+static inline struct sun8i_layer *
+plane_to_sun8i_layer(struct drm_plane *plane)
+{
+	return container_of(plane, struct sun8i_layer, plane);
+}
+
 static inline struct sun8i_mixer *
 engine_to_sun8i_mixer(struct sunxi_engine *engine)
 {
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index ca75ca0835a6..248fbb606ede 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -232,7 +232,7 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
 {
 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 										 plane);
-	struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	struct drm_crtc *crtc = new_plane_state->crtc;
 	struct drm_crtc_state *crtc_state;
 	int min_scale, max_scale;
@@ -264,7 +264,7 @@ static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane,
 {
 	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
 									   plane);
-	struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
 
@@ -279,7 +279,7 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
 									   plane);
 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
 									   plane);
-	struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	unsigned int zpos = new_state->normalized_zpos;
 	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
@@ -345,13 +345,13 @@ static const uint64_t sun8i_layer_modifiers[] = {
 	DRM_FORMAT_MOD_INVALID
 };
 
-struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
-					       struct sun8i_mixer *mixer,
-					       int index)
+struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
+					    struct sun8i_mixer *mixer,
+					    int index)
 {
 	enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY;
 	int channel = mixer->cfg->vi_num + index;
-	struct sun8i_ui_layer *layer;
+	struct sun8i_layer *layer;
 	unsigned int plane_cnt;
 	int ret;
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
index e3e32ee1178d..83892f6ff211 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
@@ -47,21 +47,9 @@
 #define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_COMBINED	((2) << 1)
 
 struct sun8i_mixer;
+struct sun8i_layer;
 
-struct sun8i_ui_layer {
-	struct drm_plane	plane;
-	struct sun8i_mixer	*mixer;
-	int			channel;
-	int			overlay;
-};
-
-static inline struct sun8i_ui_layer *
-plane_to_sun8i_ui_layer(struct drm_plane *plane)
-{
-	return container_of(plane, struct sun8i_ui_layer, plane);
-}
-
-struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
-					       struct sun8i_mixer *mixer,
-					       int index);
+struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
+					    struct sun8i_mixer *mixer,
+					    int index);
 #endif /* _SUN8I_UI_LAYER_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index f9c0a56d3a14..0c0f1ac80517 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -366,7 +366,7 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
 {
 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 										 plane);
-	struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	struct drm_crtc *crtc = new_plane_state->crtc;
 	struct drm_crtc_state *crtc_state;
 	int min_scale, max_scale;
@@ -398,7 +398,7 @@ static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane,
 {
 	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
 									   plane);
-	struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_vi_layer(plane);
 	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
 
@@ -413,7 +413,7 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
 									   plane);
 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
 									   plane);
-	struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
+	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	unsigned int zpos = new_state->normalized_zpos;
 	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
@@ -539,14 +539,14 @@ static const uint64_t sun8i_layer_modifiers[] = {
 	DRM_FORMAT_MOD_INVALID
 };
 
-struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
-					       struct sun8i_mixer *mixer,
-					       int index)
+struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
+					    struct sun8i_mixer *mixer,
+					    int index)
 {
 	enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY;
 	u32 supported_encodings, supported_ranges;
 	unsigned int plane_cnt, format_count;
-	struct sun8i_vi_layer *layer;
+	struct sun8i_layer *layer;
 	const u32 *formats;
 	int ret;
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
index 48c399e1c86d..655440cdc78f 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
@@ -52,21 +52,9 @@
 #define SUN8I_MIXER_CHAN_VI_DS_M(x)			((x) << 0)
 
 struct sun8i_mixer;
+struct sun8i_layer;
 
-struct sun8i_vi_layer {
-	struct drm_plane	plane;
-	struct sun8i_mixer	*mixer;
-	int			channel;
-	int			overlay;
-};
-
-static inline struct sun8i_vi_layer *
-plane_to_sun8i_vi_layer(struct drm_plane *plane)
-{
-	return container_of(plane, struct sun8i_vi_layer, plane);
-}
-
-struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
-					       struct sun8i_mixer *mixer,
-					       int index);
+struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
+					    struct sun8i_mixer *mixer,
+					    int index);
 #endif /* _SUN8I_VI_LAYER_H_ */
-- 
2.44.0



From megi at xff.cz  Sat Feb 24 07:06:00 2024
From: megi at xff.cz (=?UTF-8?q?Ond=C5=99ej=20Jirman?=)
Date: Sat, 24 Feb 2024 16:06:00 +0100
Subject: [PATCH v2 3/3] drm/sun4i: Fix layer zpos change/atomic modesetting
In-Reply-To: <20240224150604.3855534-1-megi@xff.cz>
References: <20240224150604.3855534-1-megi@xff.cz>
Message-ID: <20240224150604.3855534-4-megi@xff.cz>

From: Ondrej Jirman <megi at xff.cz>

Identical configurations of planes can lead to different (and wrong)
layer -> pipe routing at HW level, depending on the order of atomic
plane changes.

For example:

- Layer 1 is configured to zpos 0 and thus uses pipe 0. No other layer
  is enabled. This is a typical situation at boot.

- When a compositor takes over and layer 3 is enabled,
  sun8i_ui_layer_enable() will get called with old_zpos=0 zpos=1, which
  will lead to incorrect disabling of pipe 0 and enabling of pipe 1.

What happens is that sun8i_ui_layer_enable() function may disable
blender pipes even if it is no longer assigned to its layer.

To correct this, move the routing setup out of individual plane's
atomic_update into crtc's atomic_update, where it can be calculated
and updated all at once.

Remove the atomic_disable callback because it is no longer needed.

Signed-off-by: Ondrej Jirman <megi at xff.cz>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c    | 61 +++++++++++++++++++++
 drivers/gpu/drm/sun4i/sun8i_mixer.h    |  6 +++
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 73 +------------------------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 74 +-------------------------
 4 files changed, 71 insertions(+), 143 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index bdeb9b80e038..bd0fe2c6624e 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -250,12 +250,73 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format)
 	return -EINVAL;
 }
 
+static void sun8i_layer_enable(struct sun8i_layer *layer, bool enable)
+{
+	u32 ch_base = sun8i_channel_base(layer->mixer, layer->channel);
+	u32 val, reg, mask;
+
+	if (layer->type == SUN8I_LAYER_TYPE_UI) {
+		val = enable ? SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN : 0;
+		mask = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN;
+		reg = SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, layer->overlay);
+	} else {
+		val = enable ? SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN : 0;
+		mask = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN;
+		reg = SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, layer->overlay);
+	}
+
+	regmap_update_bits(layer->mixer->engine.regs, reg, mask, val);
+}
+
 static void sun8i_mixer_commit(struct sunxi_engine *engine,
 			       struct drm_crtc *crtc,
 			       struct drm_atomic_state *state)
 {
+	struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
+	u32 bld_base = sun8i_blender_base(mixer);
+	struct drm_plane_state *plane_state;
+	struct drm_plane *plane;
+	u32 route = 0, pipe_en = 0;
+
 	DRM_DEBUG_DRIVER("Committing changes\n");
 
+	drm_for_each_plane(plane, state->dev) {
+		struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
+		bool enable;
+		int zpos;
+
+		if (!(plane->possible_crtcs & drm_crtc_mask(crtc)) || layer->mixer != mixer)
+			continue;
+
+		plane_state = drm_atomic_get_new_plane_state(state, plane);
+		if (!plane_state)
+			plane_state = plane->state;
+
+		enable = plane_state->crtc && plane_state->visible;
+		zpos = plane_state->normalized_zpos;
+
+		DRM_DEBUG_DRIVER("  plane %d: chan=%d ovl=%d en=%d zpos=%d\n",
+				 plane->base.id, layer->channel, layer->overlay,
+				 enable, zpos);
+
+		/*
+		 * We always update the layer enable bit, because it can clear
+		 * spontaneously for unknown reasons.
+		 */
+		sun8i_layer_enable(layer, enable);
+
+		if (!enable)
+			continue;
+
+		/* Route layer to pipe based on zpos */
+		route |= layer->channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
+		pipe_en |= SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
+	}
+
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ROUTE(bld_base), route);
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+		     pipe_en | SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
+
 	regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF,
 		     SUN8I_MIXER_GLOBAL_DBUFF_ENABLE);
 }
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 5a610ee30301..d7898c9c9cc0 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -186,9 +186,15 @@ struct sun8i_mixer {
 	struct clk			*mod_clk;
 };
 
+enum {
+	SUN8I_LAYER_TYPE_UI,
+	SUN8I_LAYER_TYPE_VI,
+};
+
 struct sun8i_layer {
 	struct drm_plane	plane;
 	struct sun8i_mixer	*mixer;
+	int			type;
 	int			channel;
 	int			overlay;
 };
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index 248fbb606ede..b90e5edef4e8 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -24,55 +24,6 @@
 #include "sun8i_ui_layer.h"
 #include "sun8i_ui_scaler.h"
 
-static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
-				  int overlay, bool enable, unsigned int zpos,
-				  unsigned int old_zpos)
-{
-	u32 val, bld_base, ch_base;
-
-	bld_base = sun8i_blender_base(mixer);
-	ch_base = sun8i_channel_base(mixer, channel);
-
-	DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n",
-			 enable ? "En" : "Dis", channel, overlay);
-
-	if (enable)
-		val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN;
-	else
-		val = 0;
-
-	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
-			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
-
-	if (!enable || zpos != old_zpos) {
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
-				   SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
-				   0);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
-				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
-				   0);
-	}
-
-	if (enable) {
-		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
-				   val, val);
-
-		val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
-				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
-				   val);
-	}
-}
-
 static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
 					int overlay, struct drm_plane *plane)
 {
@@ -259,36 +210,18 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
 						   true, true);
 }
 
-static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane,
-					  struct drm_atomic_state *state)
-{
-	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
-									   plane);
-	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
-	unsigned int old_zpos = old_state->normalized_zpos;
-	struct sun8i_mixer *mixer = layer->mixer;
-
-	sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay, false, 0,
-			      old_zpos);
-}
 
 static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
 					 struct drm_atomic_state *state)
 {
-	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
-									   plane);
 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
 									   plane);
 	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	unsigned int zpos = new_state->normalized_zpos;
-	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
 
-	if (!new_state->visible) {
-		sun8i_ui_layer_enable(mixer, layer->channel,
-				      layer->overlay, false, 0, old_zpos);
+	if (!new_state->crtc || !new_state->visible)
 		return;
-	}
 
 	sun8i_ui_layer_update_coord(mixer, layer->channel,
 				    layer->overlay, plane, zpos);
@@ -298,13 +231,10 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
 				      layer->overlay, plane);
 	sun8i_ui_layer_update_buffer(mixer, layer->channel,
 				     layer->overlay, plane);
-	sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay,
-			      true, zpos, old_zpos);
 }
 
 static const struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = {
 	.atomic_check	= sun8i_ui_layer_atomic_check,
-	.atomic_disable	= sun8i_ui_layer_atomic_disable,
 	.atomic_update	= sun8i_ui_layer_atomic_update,
 };
 
@@ -390,6 +320,7 @@ struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
 
 	drm_plane_helper_add(&layer->plane, &sun8i_ui_layer_helper_funcs);
 	layer->mixer = mixer;
+	layer->type = SUN8I_LAYER_TYPE_UI;
 	layer->channel = channel;
 	layer->overlay = 0;
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index 0c0f1ac80517..9c09d9c08496 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -18,55 +18,6 @@
 #include "sun8i_vi_layer.h"
 #include "sun8i_vi_scaler.h"
 
-static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
-				  int overlay, bool enable, unsigned int zpos,
-				  unsigned int old_zpos)
-{
-	u32 val, bld_base, ch_base;
-
-	bld_base = sun8i_blender_base(mixer);
-	ch_base = sun8i_channel_base(mixer, channel);
-
-	DRM_DEBUG_DRIVER("%sabling VI channel %d overlay %d\n",
-			 enable ? "En" : "Dis", channel, overlay);
-
-	if (enable)
-		val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN;
-	else
-		val = 0;
-
-	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
-			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN, val);
-
-	if (!enable || zpos != old_zpos) {
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
-				   SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
-				   0);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
-				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
-				   0);
-	}
-
-	if (enable) {
-		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
-				   val, val);
-
-		val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
-
-		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
-				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
-				   val);
-	}
-}
-
 static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
 					int overlay, struct drm_plane *plane)
 {
@@ -393,36 +344,17 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
 						   true, true);
 }
 
-static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane,
-					  struct drm_atomic_state *state)
-{
-	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
-									   plane);
-	struct sun8i_layer *layer = plane_to_sun8i_vi_layer(plane);
-	unsigned int old_zpos = old_state->normalized_zpos;
-	struct sun8i_mixer *mixer = layer->mixer;
-
-	sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay, false, 0,
-			      old_zpos);
-}
-
 static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
 					 struct drm_atomic_state *state)
 {
-	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
-									   plane);
 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
 									   plane);
 	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	unsigned int zpos = new_state->normalized_zpos;
-	unsigned int old_zpos = old_state->normalized_zpos;
 	struct sun8i_mixer *mixer = layer->mixer;
 
-	if (!new_state->visible) {
-		sun8i_vi_layer_enable(mixer, layer->channel,
-				      layer->overlay, false, 0, old_zpos);
+	if (!new_state->crtc || !new_state->visible)
 		return;
-	}
 
 	sun8i_vi_layer_update_coord(mixer, layer->channel,
 				    layer->overlay, plane, zpos);
@@ -432,13 +364,10 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
 				      layer->overlay, plane);
 	sun8i_vi_layer_update_buffer(mixer, layer->channel,
 				     layer->overlay, plane);
-	sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay,
-			      true, zpos, old_zpos);
 }
 
 static const struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = {
 	.atomic_check	= sun8i_vi_layer_atomic_check,
-	.atomic_disable	= sun8i_vi_layer_atomic_disable,
 	.atomic_update	= sun8i_vi_layer_atomic_update,
 };
 
@@ -613,6 +542,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
 
 	drm_plane_helper_add(&layer->plane, &sun8i_vi_layer_helper_funcs);
 	layer->mixer = mixer;
+	layer->type = SUN8I_LAYER_TYPE_VI;
 	layer->channel = index;
 	layer->overlay = 0;
 
-- 
2.44.0



From ankita at nvidia.com  Sat Feb 24 07:05:42 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Sat, 24 Feb 2024 20:35:42 +0530
Subject: [PATCH v9 0/4] KVM: arm64: Allow the VM to select DEVICE_* and NORMAL_NC for IO memory
Message-ID: <20240224150546.368-1-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

Currently, KVM for ARM64 maps at stage 2 memory that is considered device
with DEVICE_nGnRE memory attributes; this setting overrides (per
ARM architecture [1]) any device MMIO mapping present at stage 1,
resulting in a set-up whereby a guest operating system cannot
determine device MMIO mapping memory attributes on its own but
it is always overridden by the KVM stage 2 default.

This set-up does not allow guest operating systems to select device
memory attributes independently from KVM stage-2 mappings
(refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
which turns out to be an issue in that guest operating systems
(e.g. Linux) may request to map devices MMIO regions with memory
attributes that guarantee better performance (e.g. gathering
attribute - that for some devices can generate larger PCIe memory
writes TLPs) and specific operations (e.g. unaligned transactions)
such as the NormalNC memory type.

The default device stage 2 mapping was chosen in KVM for ARM64 since
it was considered safer (i.e. it would not allow guests to trigger
uncontained failures ultimately crashing the machine) but this
turned out to be asynchronous (SError) defeating the purpose.

For these reasons, relax the KVM stage 2 device memory attributes
from DEVICE_nGnRE to Normal-NC.

Generalizing to other devices may be problematic, however. E.g.
GICv2 VCPU interface, which is effectively a shared peripheral, can
allow a guest to affect another guest's interrupt distribution. Hence
limit the change to VFIO PCI as caution. This is achieved by
making the VFIO PCI core module set a flag that is tested by KVM
to activate the code. This could be extended to other devices in
the future once that is deemed safe.

[1] section D8.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf

Applied over v6.8-rc5.

History
=======
v8 -> v9
- Collected Reviewed-by and Acked-by.
- Updated the commit messages in 2/4 and 4/4 to passive voice and fix
  spelling error.
- Updated subjects to align with convention of using capitalized first
  letter.
- Added links in 1/4 on the previous conversation for tracking purpose.

v7 -> v8
- Changed commit message of patches 2/4 and 4/4 to include detailed
  description of the VM_ALLOW_ANY_UNCACHED flag posted by Jason in
  the commit message.
- Added more detailed comment in the vfio_pci_core about
  VM_ALLOW_ANY_UNCACHED flag.
- Rebased to v6.8-rc5.

v6 -> v7
- Changed VM_VFIO_ALLOW_WC to VM_ALLOW_ANY_UNCACHED based on suggestion
  from Alex Williamson.
- Refactored stage2_set_prot_attr() based on Will's suggestion to
  reorganize the switch cases. Also updated the case to return -EINVAL
  when both KVM_PGTABLE_PROT_DEVICE and KVM_PGTABLE_PROT_NORMAL_NC set.
- Fixed nits pointed by Oliver and Catalin.

v5 -> v6
- Rebased to v6.8-rc2

v4 -> v5
- Moved the cover letter description text to patch 1/4.
- Cleaned up stage2_set_prot_attr() based on Marc Zyngier suggestions.
- Moved the mm header file changes to a separate patch.
- Rebased to v6.7-rc3.

v3 -> v4
- Moved the vfio-pci change to use the VM_VFIO_ALLOW_WC into
  separate patch.
- Added check to warn on the case NORMAL_NC and DEVICE are
  set simultaneously.
- Fixed miscellaneous nitpicks suggested in v3.

v2 -> v3
- Added a new patch (and converted to patch series) suggested by
  Catalin Marinas to ensure the code changes are restricted to
  VFIO PCI devices.
- Introduced VM_VFIO_ALLOW_WC flag for VFIO PCI to communicate
  with VMM.
- Reverted GIC mapping to DEVICE.

v1 -> v2
- Updated commit log to the one posted by
  Lorenzo Pieralisi <lpieralisi at kernel.org> (Thanks!)
- Added new flag to represent the NORMAL_NC setting. Updated
  stage2_set_prot_attr() to handle new flag.

v8 Link:
https://lore.kernel.org/all/20240220072926.6466-1-ankita at nvidia.com/

Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>

Ankit Agrawal (4):
  KVM: arm64: Introduce new flag for non-cacheable IO memory
  mm: Introduce new flag to indicate wc safe
  KVM: arm64: Set io memory s2 pte as normalnc for vfio pci device
  vfio: Convey kvm that the vfio-pci device is wc safe

 arch/arm64/include/asm/kvm_pgtable.h |  2 ++
 arch/arm64/include/asm/memory.h      |  2 ++
 arch/arm64/kvm/hyp/pgtable.c         | 24 +++++++++++++++++++-----
 arch/arm64/kvm/mmu.c                 | 14 ++++++++++----
 drivers/vfio/pci/vfio_pci_core.c     | 19 ++++++++++++++++++-
 include/linux/mm.h                   | 14 ++++++++++++++
 6 files changed, 65 insertions(+), 10 deletions(-)

-- 
2.34.1



From ankita at nvidia.com  Sat Feb 24 07:05:44 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Sat, 24 Feb 2024 20:35:44 +0530
Subject: [PATCH v9 2/4] mm: Introduce new flag to indicate wc safe
In-Reply-To: <20240224150546.368-1-ankita@nvidia.com>
References: <20240224150546.368-1-ankita@nvidia.com>
Message-ID: <20240224150546.368-3-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64, allowing KVM
stage 2 device mapping attributes to use NormalNC rather than
DEVICE_nGnRE, which allows guest mappings supporting write-combining
attributes (WC). ARM does not architecturally guarantee this is safe,
and indeed some MMIO regions like the GICv2 VCPU interface can trigger
uncontained faults if NormalNC is used.

Even worse, the expectation is that there are platforms where even
DEVICE_nGnRE can allow uncontained faults in corner cases. Unfortunately
existing ARM IP requires platform integration to take responsibility to
prevent this.

To safely use VFIO in KVM the platform must guarantee full safety in the
guest where no action taken against a MMIO mapping can trigger an
uncontained failure. The assumption is that most VFIO PCI platforms
support this for both mapping types, at least in common flows, based
on some expectations of how PCI IP is integrated. This can be enabled
more broadly, for instance into vfio-platform drivers, but only after
the platform vendor completes auditing for safety.

The VMA flag VM_ALLOW_ANY_UNCACHED was found to be the simplest and
cleanest way to communicate the information from VFIO to KVM that
mapping the region in S2 as NormalNC is safe. KVM consumes it to
activate the code that does the S2 mapping as NormalNC.

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>
Reviewed-by: Marc Zyngier <maz at kernel.org>
Acked-by: David Hildenbrand <david at redhat.com>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 include/linux/mm.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index f5a97dec5169..59576e56c58b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -391,6 +391,20 @@ extern unsigned int kobjsize(const void *objp);
 # define VM_UFFD_MINOR		VM_NONE
 #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
 
+/*
+ * This flag is used to connect VFIO to arch specific KVM code. It
+ * indicates that the memory under this VMA is safe for use with any
+ * non-cachable memory type inside KVM. Some VFIO devices, on some
+ * platforms, are thought to be unsafe and can cause machine crashes
+ * if KVM does not lock down the memory type.
+ */
+#ifdef CONFIG_64BIT
+#define VM_ALLOW_ANY_UNCACHED_BIT	39
+#define VM_ALLOW_ANY_UNCACHED		BIT(VM_ALLOW_ANY_UNCACHED_BIT)
+#else
+#define VM_ALLOW_ANY_UNCACHED		VM_NONE
+#endif
+
 /* Bits set in the VMA until the stack is in its final location */
 #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
 
-- 
2.34.1



From ankita at nvidia.com  Sat Feb 24 07:05:43 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Sat, 24 Feb 2024 20:35:43 +0530
Subject: [PATCH v9 1/4] KVM: arm64: Introduce new flag for non-cacheable IO memory
In-Reply-To: <20240224150546.368-1-ankita@nvidia.com>
References: <20240224150546.368-1-ankita@nvidia.com>
Message-ID: <20240224150546.368-2-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

Currently, KVM for ARM64 maps at stage 2 memory that is considered device
(i.e. it is not RAM) with DEVICE_nGnRE memory attributes; this setting
overrides (as per the ARM architecture [1]) any device MMIO mapping
present at stage 1, resulting in a set-up whereby a guest operating
system cannot determine device MMIO mapping memory attributes on its
own but it is always overridden by the KVM stage 2 default.

This set-up does not allow guest operating systems to select device
memory attributes independently from KVM stage-2 mappings
(refer to [1], "Combining stage 1 and stage 2 memory type attributes"),
which turns out to be an issue in that guest operating systems
(e.g. Linux) may request to map devices MMIO regions with memory
attributes that guarantee better performance (e.g. gathering
attribute - that for some devices can generate larger PCIe memory
writes TLPs) and specific operations (e.g. unaligned transactions)
such as the NormalNC memory type.

The default device stage 2 mapping was chosen in KVM for ARM64 since
it was considered safer (i.e. it would not allow guests to trigger
uncontained failures ultimately crashing the machine) but this
turned out to be asynchronous (SError) defeating the purpose.

Failures containability is a property of the platform and is independent
from the memory type used for MMIO device memory mappings.

Actually, DEVICE_nGnRE memory type is even more problematic than
Normal-NC memory type in terms of faults containability in that e.g.
aborts triggered on DEVICE_nGnRE loads cannot be made, architecturally,
synchronous (i.e. that would imply that the processor should issue at
most 1 load transaction at a time - it cannot pipeline them - otherwise
the synchronous abort semantics would break the no-speculation attribute
attached to DEVICE_XXX memory).

This means that regardless of the combined stage1+stage2 mappings a
platform is safe if and only if device transactions cannot trigger
uncontained failures and that in turn relies on platform capabilities
and the device type being assigned (i.e. PCIe AER/DPC error containment
and RAS architecture[3]); therefore the default KVM device stage 2
memory attributes play no role in making device assignment safer
for a given platform (if the platform design adheres to design
guidelines outlined in [3]) and therefore can be relaxed.

For all these reasons, relax the KVM stage 2 device memory attributes
from DEVICE_nGnRE to Normal-NC.

The NormalNC was chosen over a different Normal memory type default
at stage-2 (e.g. Normal Write-through) to avoid cache allocation/snooping.

Relaxing S2 KVM device MMIO mappings to Normal-NC is not expected to
trigger any issue on guest device reclaim use cases either (i.e. device
MMIO unmap followed by a device reset) at least for PCIe devices, in that
in PCIe a device reset is architected and carried out through PCI config
space transactions that are naturally ordered with respect to MMIO
transactions according to the PCI ordering rules.

Having Normal-NC S2 default puts guests in control (thanks to
stage1+stage2 combined memory attributes rules [1]) of device MMIO
regions memory mappings, according to the rules described in [1]
and summarized here ([(S1) - stage1], [(S2) - stage 2]):

S1           |  S2           | Result
NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>

It is worth noting that currently, to map devices MMIO space to user
space in a device pass-through use case the VFIO framework applies memory
attributes derived from pgprot_noncached() settings applied to VMAs, which
result in device-nGnRnE memory attributes for the stage-1 VMM mappings.

This means that a userspace mapping for device MMIO space carried
out with the current VFIO framework and a guest OS mapping for the same
MMIO space may result in a mismatched alias as described in [2].

Defaulting KVM device stage-2 mappings to Normal-NC attributes does not
change anything in this respect, in that the mismatched aliases would
only affect (refer to [2] for a detailed explanation) ordering between
the userspace and GuestOS mappings resulting stream of transactions
(i.e. it does not cause loss of property for either stream of
transactions on its own), which is harmless given that the userspace
and GuestOS access to the device is carried out through independent
transactions streams.

A Normal-NC flag is not present today. So add a new kvm_pgtable_prot
(KVM_PGTABLE_PROT_NORMAL_NC) flag for it, along with its
corresponding PTE value 0x5 (0b101) determined from [1].

Lastly, adapt the stage2 PTE property setter function
(stage2_set_prot_attr) to handle the NormalNC attribute.

The entire discussion leading to this patch series may be followed through
the following links.
Link: https://lore.kernel.org/all/20230907181459.18145-3-ankita at nvidia.com
Link: https://lore.kernel.org/r/20231205033015.10044-1-ankita at nvidia.com

[1] section D8.5.5 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
[2] section B2.8 - DDI0487J_a_a-profile_architecture_reference_manual.pdf
[3] sections 1.7.7.3/1.8.5.2/appendix C - DEN0029H_SBSA_7.1.pdf

Suggested-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Will Deacon <will at kernel.org>
Reviewed-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 arch/arm64/include/asm/kvm_pgtable.h |  2 ++
 arch/arm64/include/asm/memory.h      |  2 ++
 arch/arm64/kvm/hyp/pgtable.c         | 24 +++++++++++++++++++-----
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index cfdf40f734b1..19278dfe7978 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -197,6 +197,7 @@ enum kvm_pgtable_stage2_flags {
  * @KVM_PGTABLE_PROT_W:		Write permission.
  * @KVM_PGTABLE_PROT_R:		Read permission.
  * @KVM_PGTABLE_PROT_DEVICE:	Device attributes.
+ * @KVM_PGTABLE_PROT_NORMAL_NC:	Normal noncacheable attributes.
  * @KVM_PGTABLE_PROT_SW0:	Software bit 0.
  * @KVM_PGTABLE_PROT_SW1:	Software bit 1.
  * @KVM_PGTABLE_PROT_SW2:	Software bit 2.
@@ -208,6 +209,7 @@ enum kvm_pgtable_prot {
 	KVM_PGTABLE_PROT_R			= BIT(2),
 
 	KVM_PGTABLE_PROT_DEVICE			= BIT(3),
+	KVM_PGTABLE_PROT_NORMAL_NC		= BIT(4),
 
 	KVM_PGTABLE_PROT_SW0			= BIT(55),
 	KVM_PGTABLE_PROT_SW1			= BIT(56),
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index d82305ab420f..449ca2ff1df6 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -173,6 +173,7 @@
  * Memory types for Stage-2 translation
  */
 #define MT_S2_NORMAL		0xf
+#define MT_S2_NORMAL_NC		0x5
 #define MT_S2_DEVICE_nGnRE	0x1
 
 /*
@@ -180,6 +181,7 @@
  * Stage-2 enforces Normal-WB and Device-nGnRE
  */
 #define MT_S2_FWB_NORMAL	6
+#define MT_S2_FWB_NORMAL_NC	5
 #define MT_S2_FWB_DEVICE_nGnRE	1
 
 #ifdef CONFIG_ARM64_4K_PAGES
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index ab9d05fcf98b..3fae5830f8d2 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -717,15 +717,29 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
 static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
 				kvm_pte_t *ptep)
 {
-	bool device = prot & KVM_PGTABLE_PROT_DEVICE;
-	kvm_pte_t attr = device ? KVM_S2_MEMATTR(pgt, DEVICE_nGnRE) :
-			    KVM_S2_MEMATTR(pgt, NORMAL);
+	kvm_pte_t attr;
 	u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS;
 
+	switch (prot & (KVM_PGTABLE_PROT_DEVICE |
+			KVM_PGTABLE_PROT_NORMAL_NC)) {
+	case KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC:
+		return -EINVAL;
+	case KVM_PGTABLE_PROT_DEVICE:
+		if (prot & KVM_PGTABLE_PROT_X)
+			return -EINVAL;
+		attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
+		break;
+	case KVM_PGTABLE_PROT_NORMAL_NC:
+		if (prot & KVM_PGTABLE_PROT_X)
+			return -EINVAL;
+		attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
+		break;
+	default:
+		attr = KVM_S2_MEMATTR(pgt, NORMAL);
+	}
+
 	if (!(prot & KVM_PGTABLE_PROT_X))
 		attr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
-	else if (device)
-		return -EINVAL;
 
 	if (prot & KVM_PGTABLE_PROT_R)
 		attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
-- 
2.34.1



From ankita at nvidia.com  Sat Feb 24 07:05:45 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Sat, 24 Feb 2024 20:35:45 +0530
Subject: [PATCH v9 3/4] KVM: arm64: Set io memory s2 pte as normalnc for vfio pci device
In-Reply-To: <20240224150546.368-1-ankita@nvidia.com>
References: <20240224150546.368-1-ankita@nvidia.com>
Message-ID: <20240224150546.368-4-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

To provide VM with the ability to get device IO memory with NormalNC
property, map device MMIO in KVM for ARM64 at stage2 as NormalNC.
Having NormalNC S2 default puts guests in control (based on [1],
"Combining stage 1 and stage 2 memory type attributes") of device
MMIO regions memory mappings. The rules are summarized below:
([(S1) - stage1], [(S2) - stage 2])

S1           |  S2           | Result
NORMAL-WB    |  NORMAL-NC    | NORMAL-NC
NORMAL-WT    |  NORMAL-NC    | NORMAL-NC
NORMAL-NC    |  NORMAL-NC    | NORMAL-NC
DEVICE<attr> |  NORMAL-NC    | DEVICE<attr>

Still this cannot be generalized to non PCI devices such as GICv2.
There is insufficient information and uncertainity in the behavior
of non PCI driver. A driver must indicate support using the
new flag VM_ALLOW_ANY_UNCACHED.

Adapt KVM to make use of the flag VM_ALLOW_ANY_UNCACHED as indicator to
activate the S2 setting to NormalNc.

[1] section D8.5.5 of DDI0487J_a_a-profile_architecture_reference_manual.pdf

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Jason Gunthorpe <jgg at nvidia.com>
Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
Reviewed-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 arch/arm64/kvm/mmu.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index d14504821b79..1742fdccb432 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1381,7 +1381,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	int ret = 0;
 	bool write_fault, writable, force_pte = false;
 	bool exec_fault, mte_allowed;
-	bool device = false;
+	bool device = false, vfio_allow_any_uc = false;
 	unsigned long mmu_seq;
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
@@ -1472,6 +1472,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	gfn = fault_ipa >> PAGE_SHIFT;
 	mte_allowed = kvm_vma_mte_allowed(vma);
 
+	vfio_allow_any_uc = vma->vm_flags & VM_ALLOW_ANY_UNCACHED;
+
 	/* Don't use the VMA after the unlock -- it may have vanished */
 	vma = NULL;
 
@@ -1557,10 +1559,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	if (exec_fault)
 		prot |= KVM_PGTABLE_PROT_X;
 
-	if (device)
-		prot |= KVM_PGTABLE_PROT_DEVICE;
-	else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
+	if (device) {
+		if (vfio_allow_any_uc)
+			prot |= KVM_PGTABLE_PROT_NORMAL_NC;
+		else
+			prot |= KVM_PGTABLE_PROT_DEVICE;
+	} else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) {
 		prot |= KVM_PGTABLE_PROT_X;
+	}
 
 	/*
 	 * Under the premise of getting a FSC_PERM fault, we just need to relax
-- 
2.34.1



From ankita at nvidia.com  Sat Feb 24 07:05:46 2024
From: ankita at nvidia.com (ankita at nvidia.com)
Date: Sat, 24 Feb 2024 20:35:46 +0530
Subject: [PATCH v9 4/4] vfio: Convey kvm that the vfio-pci device is wc safe
In-Reply-To: <20240224150546.368-1-ankita@nvidia.com>
References: <20240224150546.368-1-ankita@nvidia.com>
Message-ID: <20240224150546.368-5-ankita@nvidia.com>

From: Ankit Agrawal <ankita at nvidia.com>

The VM_ALLOW_ANY_UNCACHED flag is implemented for ARM64,
allowing KVM stage 2 device mapping attributes to use Normal-NC
rather than DEVICE_nGnRE, which allows guest mappings supporting
write-combining attributes (WC). ARM does not architecturally
guarantee this is safe, and indeed some MMIO regions like the GICv2
VCPU interface can trigger uncontained faults if Normal-NC is used.

To safely use VFIO in KVM the platform must guarantee full safety
in the guest where no action taken against a MMIO mapping can
trigger an uncontained failure. The expectation is that most VFIO PCI
platforms support this for both mapping types, at least in common
flows, based on some expectations of how PCI IP is integrated. So
make vfio-pci set the VM_ALLOW_ANY_UNCACHED flag.

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Jason Gunthorpe <jgg at nvidia.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Alex Williamson <alex.williamson at redhat.com>
Reviewed-by: David Hildenbrand <david at redhat.com>
Reviewed-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Ankit Agrawal <ankita at nvidia.com>
---
 drivers/vfio/pci/vfio_pci_core.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 1cbc990d42e0..df6f99bdf70d 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1862,8 +1862,25 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
 	/*
 	 * See remap_pfn_range(), called from vfio_pci_fault() but we can't
 	 * change vm_flags within the fault handler.  Set them now.
+	 *
+	 * VM_ALLOW_ANY_UNCACHED: The VMA flag is implemented for ARM64,
+	 * allowing KVM stage 2 device mapping attributes to use Normal-NC
+	 * rather than DEVICE_nGnRE, which allows guest mappings
+	 * supporting write-combining attributes (WC). ARM does not
+	 * architecturally guarantee this is safe, and indeed some MMIO
+	 * regions like the GICv2 VCPU interface can trigger uncontained
+	 * faults if Normal-NC is used.
+	 *
+	 * To safely use VFIO in KVM the platform must guarantee full
+	 * safety in the guest where no action taken against a MMIO
+	 * mapping can trigger an uncontained failure. The assumption is
+	 * that most VFIO PCI platforms support this for both mapping types,
+	 * at least in common flows, based on some expectations of how
+	 * PCI IP is integrated. Hence VM_ALLOW_ANY_UNCACHED is set in
+	 * the VMA flags.
 	 */
-	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+	vm_flags_set(vma, VM_ALLOW_ANY_UNCACHED | VM_IO | VM_PFNMAP |
+			VM_DONTEXPAND | VM_DONTDUMP);
 	vma->vm_ops = &vfio_pci_mmap_ops;
 
 	return 0;
-- 
2.34.1



From jic23 at kernel.org  Sat Feb 24 08:36:22 2024
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 24 Feb 2024 16:36:22 +0000
Subject: [PATCH v2 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <20240219-mainline-spi-precook-message-v2-1-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
	<20240219-mainline-spi-precook-message-v2-1-4a762c6701b9@baylibre.com>
Message-ID: <20240224163622.7499cdd0@jic23-huawei>

On Mon, 19 Feb 2024 16:33:18 -0600
David Lechner <dlechner at baylibre.com> wrote:

> This adds a new spi_optimize_message() function that can be used to
> optimize SPI messages that are used more than once. Peripheral drivers
> that use the same message multiple times can use this API to perform SPI
> message validation and controller-specific optimizations once and then
> reuse the message while avoiding the overhead of revalidating the
> message on each spi_(a)sync() call.
> 
> Internally, the SPI core will also call this function for each message
> if the peripheral driver did not explicitly call it. This is done to so
> that controller drivers don't have to have multiple code paths for
> optimized and non-optimized messages.
> 
> A hook is provided for controller drivers to perform controller-specific
> optimizations.
> 
> Suggested-by: Martin Sperl <kernel at martin.sperl.org>
> Link: https://lore.kernel.org/linux-spi/39DEC004-10A1-47EF-9D77-276188D2580C at martin.sperl.org/
> Signed-off-by: David Lechner <dlechner at baylibre.com>

Very nice.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>


From jic23 at kernel.org  Sat Feb 24 08:45:58 2024
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 24 Feb 2024 16:45:58 +0000
Subject: [PATCH v2 3/5] spi: stm32: move splitting transfers to
 optimize_message
In-Reply-To: <20240219-mainline-spi-precook-message-v2-3-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
	<20240219-mainline-spi-precook-message-v2-3-4a762c6701b9@baylibre.com>
Message-ID: <20240224164558.02c08dd6@jic23-huawei>

On Mon, 19 Feb 2024 16:33:20 -0600
David Lechner <dlechner at baylibre.com> wrote:

> Since splitting transfers was moved to spi_optimize_message() in the
> core SPI code, we now need to use the optimize_message callback in the
> STM32 SPI driver to ensure that the operation is only performed once
> when spi_optimize_message() is used by peripheral drivers explicitly.
> 
> Signed-off-by: David Lechner <dlechner at baylibre.com>
Trivial comment inline. Otherwise LGTM
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

There are changes to when this happens wrt to locking but I think those
are all positive as the bus lock is held for less time and there
is nothing in here that needs that lock held.
> ---
> 
> v2 changes: none
> 
>  drivers/spi/spi-stm32.c | 28 ++++++++++++++++------------
>  1 file changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
> index c32e57bb38bd..e4e7ddb7524a 100644
> --- a/drivers/spi/spi-stm32.c
> +++ b/drivers/spi/spi-stm32.c
> @@ -1118,6 +1118,21 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
>  	return IRQ_HANDLED;
>  }
>  
> +static int stm32_spi_optimize_message(struct spi_message *msg)
> +{
> +	struct spi_controller *ctrl = msg->spi->controller;
> +	struct stm32_spi *spi = spi_controller_get_devdata(ctrl);
> +
> +	/* On STM32H7, messages should not exceed a maximum size set
If you spin a v3, this isn't in keeping with local comment style.

	/*
 	 * On...

> +	 * later via the set_number_of_data function. In order to
> +	 * ensure that, split large messages into several messages
> +	 */
> +	if (spi->cfg->set_number_of_data)
> +		return spi_split_transfers_maxwords(ctrl, msg, spi->t_size_max);
> +
> +	return 0;
> +}
> +
>  /**
>   * stm32_spi_prepare_msg - set up the controller to transfer a single message
>   * @ctrl: controller interface
> @@ -1163,18 +1178,6 @@ static int stm32_spi_prepare_msg(struct spi_controller *ctrl,
>  		!!(spi_dev->mode & SPI_LSB_FIRST),
>  		!!(spi_dev->mode & SPI_CS_HIGH));
>  
> -	/* On STM32H7, messages should not exceed a maximum size setted
> -	 * afterward via the set_number_of_data function. In order to
> -	 * ensure that, split large messages into several messages
> -	 */
> -	if (spi->cfg->set_number_of_data) {
> -		int ret;
> -
> -		ret = spi_split_transfers_maxwords(ctrl, msg, spi->t_size_max);
> -		if (ret)
> -			return ret;
> -	}
> -
>  	spin_lock_irqsave(&spi->lock, flags);
>  
>  	/* CPOL, CPHA and LSB FIRST bits have common register */
> @@ -2180,6 +2183,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
>  	ctrl->max_speed_hz = spi->clk_rate / spi->cfg->baud_rate_div_min;
>  	ctrl->min_speed_hz = spi->clk_rate / spi->cfg->baud_rate_div_max;
>  	ctrl->use_gpio_descriptors = true;
> +	ctrl->optimize_message = stm32_spi_optimize_message;
>  	ctrl->prepare_message = stm32_spi_prepare_msg;
>  	ctrl->transfer_one = stm32_spi_transfer_one;
>  	ctrl->unprepare_message = stm32_spi_unprepare_msg;
> 



From jic23 at kernel.org  Sat Feb 24 08:51:33 2024
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 24 Feb 2024 16:51:33 +0000
Subject: [PATCH v2 4/5] spi: axi-spi-engine: move message compile to
 optimize_message
In-Reply-To: <20240219-mainline-spi-precook-message-v2-4-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
	<20240219-mainline-spi-precook-message-v2-4-4a762c6701b9@baylibre.com>
Message-ID: <20240224165133.33a6ad94@jic23-huawei>

On Mon, 19 Feb 2024 16:33:21 -0600
David Lechner <dlechner at baylibre.com> wrote:

> In the AXI SPI Engine driver, compiling the message is an expensive
> operation. Previously, it was done per message transfer in the
> prepare_message hook. This patch moves the message compile to the
> optimize_message hook so that it is only done once per message in
> cases where the peripheral driver calls spi_optimize_message().
> 
> This can be a significant performance improvement for some peripherals.
> For example, the ad7380 driver saw a 13% improvement in throughput
> when using the AXI SPI Engine driver with this patch.
> 
> Since we now need two message states, one for the optimization stage
> that doesn't change for the lifetime of the message and one that is
> reset on each transfer for managing the current transfer state, the old
> msg->state is split into msg->opt_state and spi_engine->msg_state. The
> latter is included in the driver struct now since there is only one
> current message at a time that can ever use it and it is in a hot path
> so avoiding allocating a new one on each message transfer saves a few
> cpu cycles and lets us get rid of the prepare_message callback.
> 
> Signed-off-by: David Lechner <dlechner at baylibre.com>
Whilst I'm not familiar with this driver, from a quick look at this
patch and the driver code, looks fine to me. So FWIW
Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>


From jic23 at kernel.org  Sat Feb 24 08:57:06 2024
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 24 Feb 2024 16:57:06 +0000
Subject: [PATCH v2 5/5] iio: adc: ad7380: use spi_optimize_message()
In-Reply-To: <20240219-mainline-spi-precook-message-v2-5-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-0-4a762c6701b9@baylibre.com>
	<20240219-mainline-spi-precook-message-v2-5-4a762c6701b9@baylibre.com>
Message-ID: <20240224165706.18cc0d7e@jic23-huawei>

On Mon, 19 Feb 2024 16:33:22 -0600
David Lechner <dlechner at baylibre.com> wrote:

> This modifies the ad7380 ADC driver to use spi_optimize_message() to
> optimize the SPI message for the buffered read operation. Since buffered
> reads reuse the same SPI message for each read, this can improve
> performance by reducing the overhead of setting up some parts the SPI
> message in each spi_sync() call.
> 
> Signed-off-by: David Lechner <dlechner at baylibre.com>
Looks good to me.

As this is the driver you asked me to drop earlier this cycle,
how do we plan to merge this series?

If Mark is fine taking 1-4 with the user following along that's
fine by me, if not I guess we are in immutable tree territory for
next cycle?

Jonathan


From linux at roeck-us.net  Sat Feb 24 09:30:14 2024
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 24 Feb 2024 09:30:14 -0800
Subject: [PATCH 03/13] dt-bindings: hwmon: lm75: add label property
In-Reply-To: <20240215-mbly-i2c-v1-3-19a336e91dca@bootlin.com>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-3-19a336e91dca@bootlin.com>
Message-ID: <dcd5794b-aca6-4f6d-8e8d-f5548fcad644@roeck-us.net>

On Thu, Feb 15, 2024 at 05:52:10PM +0100, Th?o Lebrun wrote:
> Declare optional label devicetree property. Show usage in one example
> with dummy name.
> 
> To: Jean Delvare <jdelvare at suse.com>
> To: Guenter Roeck <linux at roeck-us.net>
> Cc: <linux-hwmon at vger.kernel.org>
> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

What is the verdict here ? Should I apply it and accept another patch
to update it, or should it be reworked to be based on the new common
hwmon schema ?

Thanks,
Guenter

> ---
>  Documentation/devicetree/bindings/hwmon/lm75.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/hwmon/lm75.yaml b/Documentation/devicetree/bindings/hwmon/lm75.yaml
> index ed269e428a3d..5ca2c83b413d 100644
> --- a/Documentation/devicetree/bindings/hwmon/lm75.yaml
> +++ b/Documentation/devicetree/bindings/hwmon/lm75.yaml
> @@ -52,6 +52,9 @@ properties:
>    interrupts:
>      maxItems: 1
>  
> +  label:
> +    description: user-facing name of the hardware monitor
> +
>  required:
>    - compatible
>    - reg
> @@ -83,6 +86,7 @@ examples:
>          compatible = "st,stlm75";
>          reg = <0x48>;
>          vs-supply = <&vs>;
> +        label = "CPU temp";
>        };
>      };
>    - |


From Markus.Elfring at web.de  Sat Feb 24 10:15:31 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Sat, 24 Feb 2024 19:15:31 +0100
Subject: [PATCH v2 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <20240219-mainline-spi-precook-message-v2-1-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-1-4a762c6701b9@baylibre.com>
Message-ID: <80b1afef-3502-4719-ba9d-682b5566688b@web.de>

>                                           ? call it. This is done to so
> that controller drivers ?

I hope that such a wording will be improved for the final change description.

Regards,
Markus


From conor at kernel.org  Sat Feb 24 11:16:43 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 19:16:43 +0000
Subject: [PATCH] ARM: dts: aspeed: Add vendor prefixes to lm25066 compat
 strings
In-Reply-To: <20240224103712.20864-2-zev@bewilderbeest.net>
References: <20240224103712.20864-2-zev@bewilderbeest.net>
Message-ID: <20240224-coyness-civic-d583b863c614@spud>

On Sat, Feb 24, 2024 at 02:37:07AM -0800, Zev Weiss wrote:
> Due to the way i2c driver matching works (falling back to the driver's
> id_table if of_match_table fails) this didn't actually cause any
> misbehavior, but let's add the vendor prefixes so things actually work
> the way they were intended to.
> 
> Signed-off-by: Zev Weiss <zev at bewilderbeest.net>

Oh sweet, I was just about to go off and write this patch - thanks!

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
>  arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts | 4 ++--
>  arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts    | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
> index 4554abf0c7cd..9aa2de3723b5 100644
> --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
> @@ -98,14 +98,14 @@ w83773g at 4c {
>  
>  	/* IPB PMIC */
>  	lm25066 at 40 {
> -		compatible = "lm25066";
> +		compatible = "ti,lm25066";
>  		reg = <0x40>;
>  		shunt-resistor-micro-ohms = <1000>;
>  	};
>  
>  	/* 12VSB PMIC */
>  	lm25066 at 41 {
> -		compatible = "lm25066";
> +		compatible = "ti,lm25066";
>  		reg = <0x41>;
>  		shunt-resistor-micro-ohms = <10000>;
>  	};
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
> index 6600f7e9bf5e..e830fec0570f 100644
> --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
> @@ -14,7 +14,7 @@ efuse##n {					\
>  
>  #define EFUSE(hexaddr, num)							\
>  	efuse@##hexaddr {							\
> -		compatible = "lm25066";						\
> +		compatible = "ti,lm25066";					\
>  		reg = <0x##hexaddr>;						\
>  		shunt-resistor-micro-ohms = <675>;				\
>  		regulators {							\
> -- 
> 2.43.2
> 
-------------- 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/20240224/3eefe0b1/attachment.sig>

From jic23 at kernel.org  Sat Feb 24 11:25:35 2024
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 24 Feb 2024 19:25:35 +0000
Subject: [PATCH 0/3] iio: adc: rockchip_saradc: fix bitmasking and
 remove custom logic for getting reset
In-Reply-To: <CAHp75VfmsDeTP97srRJU09gA988xw68+ZHsXvXT3W_wv1HEauA@mail.gmail.com>
References: <20240223-saradcv2-chan-mask-v1-0-84b06a0f623a@theobroma-systems.com>
	<CAHp75VfmsDeTP97srRJU09gA988xw68+ZHsXvXT3W_wv1HEauA@mail.gmail.com>
Message-ID: <20240224192535.237933de@jic23-huawei>

On Fri, 23 Feb 2024 15:01:30 +0200
Andy Shevchenko <andy.shevchenko at gmail.com> wrote:

> On Fri, Feb 23, 2024 at 2:46?PM Quentin Schulz <foss+kernel at 0leil.net> wrote:
> >
> > The mask for the channel selection is incorrect as it's specified to be
> > 16b wide by is actually only 4.
> >
> > Also, the 16 lower bits in the SARADC_CONV_CON register are write
> > protected. Whatever their value is can only be written to the hardware
> > block if their associated bit in the higher 16 bits is set. Considering
> > that the channel bitmask is 4b wide but that we can write e.g. 0 in
> > there, we shouldn't use the value shifted by 16 as a mask but rather the
> > bitmask for that value shifted by 16. This is currently NOT an issue
> > because the only SoC with SARADCv2 IP is the RK3588 which has a reset
> > defined in the SoC DTSI. When that is the case, the reset is asserted
> > before every channel conversion is started. This means the registers are
> > reset so effectively, we do not need to write zeros so the wrong mask
> > still works because where we should be writing zeroes, there are already
> > zeroes. However, let's fix this in case there comes a day there's an SoC
> > which doesn't require to reset the controller before every channel
> > conversion is started.
> >
> > Lastly, let's use the appropriate function from the reset subsystem
> > for getting an optional exclusive reset instead of rolling out our own
> > logic.
> >
> > Those three patches should not be changing any behavior.  
> 
> Nice series, I have the comments in patch 3, but no need to resend
> until Jonathan asks for. He might address that whilst applying.
> 
> Reviewed-by: Andy Shevchenko <andy.shevchenko at gmail.com>
> 

I've take the series through the togreg branch as we are so near the
merge windows.  Note (despite Linus not liking it :)) I use links
in my git tags so anyone really searching for Quentin can find
the discussion.

I'm usually a bit lazy on cleaning out what I would consider unnecessary
CC tags but given Andy comment on these I've dropped the extra
one.

Patches 1 and 2 marked for stable.

Jonathan


From conor at kernel.org  Sat Feb 24 11:48:35 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 19:48:35 +0000
Subject: [PATCH v4 13/39] ASoC: dt-bindings: atmel-classd: add sam9x7
 compatible
In-Reply-To: <20240223172608.672190-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172608.672190-1-varshini.rajendran@microchip.com>
Message-ID: <20240224-vice-lunchtime-fd456448d41d@spud>

On Fri, Feb 23, 2024 at 10:56:08PM +0530, Varshini Rajendran wrote:
> Add sam9x7 compatible to DT bindings documentation.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> ---
> Changes in v4:
> - Changed the subject prefix matching the subsystem

> - Removed unwanted '-items' from the syntax

Did you? The diff looks identical to v3.

Thanks,
Conor.

> ---
>  .../devicetree/bindings/sound/atmel,sama5d2-classd.yaml    | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/atmel,sama5d2-classd.yaml b/Documentation/devicetree/bindings/sound/atmel,sama5d2-classd.yaml
> index 43d04702ac2d..ae3162fcfe02 100644
> --- a/Documentation/devicetree/bindings/sound/atmel,sama5d2-classd.yaml
> +++ b/Documentation/devicetree/bindings/sound/atmel,sama5d2-classd.yaml
> @@ -18,7 +18,12 @@ description:
>  
>  properties:
>    compatible:
> -    const: atmel,sama5d2-classd
> +    oneOf:
> +      - items:
> +          - const: atmel,sama5d2-classd
> +      - items:
> +          - const: microchip,sam9x7-classd
> +          - const: atmel,sama5d2-classd
>  
>    reg:
>      maxItems: 1
> -- 
> 2.25.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/20240224/95da6a3b/attachment.sig>

From conor at kernel.org  Sat Feb 24 11:49:51 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 19:49:51 +0000
Subject: [PATCH v4 06/39] dt-bindings: i2c: at91: Add sam9x7 compatible
 string
In-Reply-To: <20240223172459.671832-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172459.671832-1-varshini.rajendran@microchip.com>
Message-ID: <20240224-unarmored-mastiff-0b6273cb7af4@spud>

On Fri, Feb 23, 2024 at 10:54:59PM +0530, Varshini Rajendran wrote:
> Add compatible string for sam9x7.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
> Changes in v4:
> - Made sam9x7 compatible as an enum with sama7g5 compatible
> - Removed the sam9x7 compatible from allOf section as it was not needed
>   like pointed out
> ---
>  Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml
> index 6adedd3ec399..b1c13bab2472 100644
> --- a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml
> +++ b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml
> @@ -25,7 +25,9 @@ properties:
>                - atmel,sama5d2-i2c
>                - microchip,sam9x60-i2c
>        - items:
> -          - const: microchip,sama7g5-i2c
> +          - enum:
> +              - microchip,sama7g5-i2c
> +              - microchip,sam9x7-i2c
>            - const: microchip,sam9x60-i2c
>  
>    reg:
> -- 
> 2.25.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/20240224/2f73460e/attachment.sig>

From conor at kernel.org  Sat Feb 24 11:50:21 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 19:50:21 +0000
Subject: [PATCH v4 05/39] dt-bindings: crypto: add sam9x7 in Atmel TDES
In-Reply-To: <20240223172445.671783-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172445.671783-1-varshini.rajendran@microchip.com>
Message-ID: <20240224-willpower-crewmate-7b433999d01f@spud>

On Fri, Feb 23, 2024 at 10:54:45PM +0530, Varshini Rajendran wrote:
> Add DT bindings for atmel TDES.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.
-------------- 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/20240224/5688ed49/attachment-0001.sig>

From conor at kernel.org  Sat Feb 24 11:50:54 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 19:50:54 +0000
Subject: [PATCH v4 08/39] dt-bindings: atmel-nand: add
 microchip,sam9x7-pmecc
In-Reply-To: <20240223172520.671940-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172520.671940-1-varshini.rajendran@microchip.com>
Message-ID: <20240224-doorknob-shrubs-ca14a595fc21@spud>

On Fri, Feb 23, 2024 at 10:55:20PM +0530, Varshini Rajendran wrote:
> Add microchip,sam9x7-pmecc to DT bindings documentation.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
>  Documentation/devicetree/bindings/mtd/atmel-nand.txt | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
> index 50645828ac20..4598930851d9 100644
> --- a/Documentation/devicetree/bindings/mtd/atmel-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
> @@ -56,6 +56,7 @@ Required properties:
>  	"atmel,sama5d4-pmecc"
>  	"atmel,sama5d2-pmecc"
>  	"microchip,sam9x60-pmecc"
> +	"microchip,sam9x7-pmecc", "atmel,at91sam9g45-pmecc"
>  - reg: should contain 2 register ranges. The first one is pointing to the PMECC
>         block, and the second one to the PMECC_ERRLOC block.
>  
> -- 
> 2.25.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/20240224/0a203e24/attachment.sig>

From conor at kernel.org  Sat Feb 24 11:51:42 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 19:51:42 +0000
Subject: [PATCH v4 11/39] dt-bindings: rtt: at91rm9260: add sam9x7
 compatible
In-Reply-To: <20240223172552.672094-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172552.672094-1-varshini.rajendran@microchip.com>
Message-ID: <20240224-unmasking-gracious-8d2734d28fea@spud>

On Fri, Feb 23, 2024 at 10:55:52PM +0530, Varshini Rajendran wrote:
> Add compatible for SAM9X7 RTT.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
> Changes in v4:
> - Made sam9x7 compatible as an enum with sam9x60 compatible as
>   suggested
> ---
>  .../devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml        | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml b/Documentation/devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml
> index b80b85c394ac..a7f6c1d1a08a 100644
> --- a/Documentation/devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml
> +++ b/Documentation/devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml
> @@ -19,7 +19,9 @@ properties:
>        - items:
>            - const: atmel,at91sam9260-rtt
>        - items:
> -          - const: microchip,sam9x60-rtt
> +          - enum:
> +              - microchip,sam9x60-rtt
> +              - microchip,sam9x7-rtt
>            - const: atmel,at91sam9260-rtt
>        - items:
>            - const: microchip,sama7g5-rtt
> -- 
> 2.25.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/20240224/e0f0afe9/attachment.sig>

From semen.protsenko at linaro.org  Sat Feb 24 11:57:35 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 13:57:35 -0600
Subject: [PATCH 11/16] clk: samsung: Keep register offsets in chip
 specific structure
In-Reply-To: <c4f7e3cb-db9b-48be-883e-33878d2510e8@linaro.org>
References: <20240216223245.12273-1-semen.protsenko@linaro.org>
 <20240216223245.12273-12-semen.protsenko@linaro.org> <ce515530-428a-4a21-8c56-5a497cc8130a@linaro.org>
 <CAPLW+4=kpk=Vg=nX-hVxcCS0OttC6xmyUcB005tmX+vtUF9TLA@mail.gmail.com> <c4f7e3cb-db9b-48be-883e-33878d2510e8@linaro.org>
Message-ID: <CAPLW+4kBHnLnPj0JKvdQ-Bm7DiEJ+_Ob-Cw60=vzwDwbOh4qOA@mail.gmail.com>

On Thu, Feb 22, 2024 at 1:47?AM Krzysztof Kozlowski
<krzysztof.kozlowski at linaro.org> wrote:
>
> On 22/02/2024 01:42, Sam Protsenko wrote:
> > On Tue, Feb 20, 2024 at 5:04?AM Krzysztof Kozlowski
> > <krzysztof.kozlowski at linaro.org> wrote:
> >>
> >> On 16/02/2024 23:32, Sam Protsenko wrote:
> >>> Abstract CPU clock registers by keeping their offsets in a dedicated
> >>> chip specific structure to accommodate for oncoming Exynos850 support,
> >>> which has different offsets for cluster 0 and cluster 1. This rework
> >>> also makes it possible to use exynos_set_safe_div() for all chips, so
> >>> exynos5433_set_safe_div() is removed here to reduce the code
> >>> duplication.
> >>>
> >>
> >> So that's the answer why you could not use flags anymore - you need an
> >> enum, not a bitmap. Such short explanation should be in previous commits
> >> justifying moving reg layout to new property.
> >
> > Will do, thanks.
> >
> >>
> >>> No functional change.
> >>>
> >>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> >>> ---
> >>>  drivers/clk/samsung/clk-cpu.c | 156 +++++++++++++++++++---------------
> >>>  1 file changed, 86 insertions(+), 70 deletions(-)
> >>>
> >>> diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
> >>> index 04394d2166c9..744b609c222d 100644
> >>> --- a/drivers/clk/samsung/clk-cpu.c
> >>> +++ b/drivers/clk/samsung/clk-cpu.c
> >>> @@ -44,12 +44,14 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
> >>>
> >>>  /**
> >>>   * struct exynos_cpuclk_chip - Chip specific data for CPU clock
> >>> + * @regs: register offsets for CPU related clocks
> >>>   * @pre_rate_cb: callback to run before CPU clock rate change
> >>>   * @post_rate_cb: callback to run after CPU clock rate change
> >>>   */
> >>>  struct exynos_cpuclk_chip {
> >>> -     exynos_rate_change_fn_t pre_rate_cb;
> >>> -     exynos_rate_change_fn_t post_rate_cb;
> >>> +     const void                              * const regs;
> >>
> >> Why this is void?
> >>
> >
> > Different chips can have very different register layout. For example,
> > older Exynos chips usually keep multiple CPU divider ratios in one
> > single register, whereas more modern chips have a dedicated register
> > for each divider clock. Also, old chips usually split divider ratio vs
> > DIV clock status between different registers, but in modern chips they
> > both live in one single register. Having (void *) makes it possible to
> > keep pointers to different structures, and each function for the
> > particular chip can "know" which exactly structure is stored there,
> > casting (void *) to a needed type. Another way to do that would be to
> > have "one-size-fits-all" structure with all possible registers for all
> > possible chips. I don't know, I just didn't like that for a couple of
> > reasons, so decided to go with (void *).
> >
> > I'll add some explanation in the commit message in v2.
>
> Currently the one-size-fits-all seems feasible, even if few fields are
> not matching, so I would prefer to go this approach.
>

Sure, no problem. Will fix it in v3.

> Best regards,
> Krzysztof
>


From conor at kernel.org  Sat Feb 24 12:02:26 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 20:02:26 +0000
Subject: [PATCH v4 12/39] dt-bindings: serial: atmel,at91-usart: add
 compatible for sam9x7.
In-Reply-To: <20240223172559.672142-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172559.672142-1-varshini.rajendran@microchip.com>
Message-ID: <20240224-kimono-stress-898eae80abd3@spud>

On Fri, Feb 23, 2024 at 10:55:59PM +0530, Varshini Rajendran wrote:
> Add sam9x7 compatible to DT bindings documentation.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> ---
> Changes in v4:
> - Fixed the wrong addition of compatible
> - Added further compatibles that are possible correct (as per DT)
> ---
>  .../devicetree/bindings/serial/atmel,at91-usart.yaml | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml b/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
> index 65cb2e5c5eee..30af537e8e81 100644
> --- a/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
> +++ b/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
> @@ -23,11 +23,17 @@ properties:
>            - const: atmel,at91sam9260-dbgu
>            - const: atmel,at91sam9260-usart
>        - items:
> -          - const: microchip,sam9x60-usart
> +          - enum:
> +              - microchip,sam9x60-usart
> +              - microchip,sam9x7-usart
>            - const: atmel,at91sam9260-usart
>        - items:
> -          - const: microchip,sam9x60-dbgu
> -          - const: microchip,sam9x60-usart
> +          - enum:
> +              - microchip,sam9x60-dbgu
> +              - microchip,sam9x7-dbgu

> +          - enum:
> +              - microchip,sam9x60-usart
> +              - microchip,sam9x7-usart

This doesn't make sense - this enum should be a const.
I don't really understand the idea behind of the original binding here that
allowed:
"microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"

Specifically, I don't get the purpose of the "microchip,sam9x60-usart".
Either make it
      - items:
          - enum:
              - microchip,sam9x60-dbgu
              - microchip,sam9x7-dbgu
          - const: microchip,sam9x60-usart
          - const: atmel,at91sam9260-dbgu
          - const: atmel,at91sam9260-usart
or add
      - items:
          - const: microchip,sam9x60-dbgu
          - const: atmel,at91sam9260-dbgu
          - const: atmel,at91sam9260-usart
or explain exactly why this needs to be
"chipa-dgbu", "chipa-usart", "chipb-dbgu", "chipb-dbgu"

Thanks,
Conor.

-------------- 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/20240224/d797a1b9/attachment.sig>

From conor at kernel.org  Sat Feb 24 12:03:34 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 20:03:34 +0000
Subject: [PATCH v4 14/39] dt-bindings: pwm: at91: Add sam9x7 compatible
 strings list
In-Reply-To: <20240223172619.672262-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172619.672262-1-varshini.rajendran@microchip.com>
Message-ID: <20240224-henna-bok-f3cd3eb4ca36@spud>

On Fri, Feb 23, 2024 at 10:56:19PM +0530, Varshini Rajendran wrote:
> Add compatible strings list for SAM9X7.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
>  Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml b/Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml
> index d84268b59784..96cd6f3c3546 100644
> --- a/Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml
> +++ b/Documentation/devicetree/bindings/pwm/atmel,at91sam-pwm.yaml
> @@ -25,6 +25,9 @@ properties:
>        - items:
>            - const: microchip,sama7g5-pwm
>            - const: atmel,sama5d2-pwm
> +      - items:
> +          - const: microchip,sam9x7-pwm
> +          - const: microchip,sam9x60-pwm
>  
>    reg:
>      maxItems: 1
> -- 
> 2.25.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/20240224/27efb93a/attachment.sig>

From conor at kernel.org  Sat Feb 24 12:04:01 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 20:04:01 +0000
Subject: [PATCH v4 15/39] dt-bindings: watchdog: sama5d4-wdt: add
 compatible for sam9x7-wdt
In-Reply-To: <20240223172627.672316-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172627.672316-1-varshini.rajendran@microchip.com>
Message-ID: <20240224-runway-seventy-18c05d9017d2@spud>

On Fri, Feb 23, 2024 at 10:56:27PM +0530, Varshini Rajendran wrote:
> Add compatible microchip,sam9x7-wdt to DT bindings documentation.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.
-------------- 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/20240224/7350b74f/attachment.sig>

From conor at kernel.org  Sat Feb 24 12:05:51 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 20:05:51 +0000
Subject: [PATCH v4 21/39] dt-bindings: clk: at91: add sam9x7
In-Reply-To: <20240223172732.672645-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172732.672645-1-varshini.rajendran@microchip.com>
Message-ID: <20240224-procreate-tumble-52241e198587@spud>

On Fri, Feb 23, 2024 at 10:57:32PM +0530, Varshini Rajendran wrote:
> Add bindings for SAM9X7's slow clock controller.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.

> ---
> Changes in v4:
> - Added sam9x7 compatible as an enum with sama7g5 compatible as per the
>   review comment
> ---
>  .../devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml      | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml b/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
> index 7be29877e6d2..ab81f0b55ad5 100644
> --- a/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
> +++ b/Documentation/devicetree/bindings/clock/atmel,at91sam9x5-sckc.yaml
> @@ -18,7 +18,9 @@ properties:
>            - atmel,sama5d4-sckc
>            - microchip,sam9x60-sckc
>        - items:
> -          - const: microchip,sama7g5-sckc
> +          - enum:
> +              - microchip,sama7g5-sckc
> +              - microchip,sam9x7-sckc
>            - const: microchip,sam9x60-sckc
>  
>    reg:
> -- 
> 2.25.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/20240224/a02d6495/attachment.sig>

From conor at kernel.org  Sat Feb 24 12:06:26 2024
From: conor at kernel.org (Conor Dooley)
Date: Sat, 24 Feb 2024 20:06:26 +0000
Subject: [PATCH v4 22/39] dt-bindings: clk: at91: add sam9x7 clock
 controller
In-Reply-To: <20240223172741.672694-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172741.672694-1-varshini.rajendran@microchip.com>
Message-ID: <20240224-fragile-unwed-f1e69bbcbaed@spud>

On Fri, Feb 23, 2024 at 10:57:41PM +0530, Varshini Rajendran wrote:
> Add bindings for SAM9X7's pmc.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>

Cheers,
Conor.
-------------- 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/20240224/e2b91bbd/attachment.sig>

From Markus.Elfring at web.de  Sat Feb 24 12:09:40 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Sat, 24 Feb 2024 21:09:40 +0100
Subject: [PATCH v2 1/5] spi: add spi_optimize_message() APIs
In-Reply-To: <20240219-mainline-spi-precook-message-v2-1-4a762c6701b9@baylibre.com>
References: <20240219-mainline-spi-precook-message-v2-1-4a762c6701b9@baylibre.com>
Message-ID: <0f25b520-563c-4b3b-96cd-d1dcc7ea6f40@web.de>

?
> +++ b/drivers/spi/spi.c
?
> +static int __spi_optimize_message(struct spi_device *spi,
> +				  struct spi_message *msg)
?

I propose to reconsider the usage of leading underscores in such identifiers.

See also:
https://wiki.sei.cmu.edu/confluence/display/c/DCL37-C.+Do+not+declare+or+define+a+reserved+identifier

Regards,
Markus


From semen.protsenko at linaro.org  Sat Feb 24 12:20:38 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:38 -0600
Subject: [PATCH v3 00/15] clk: samsung: Add CPU clocks for Exynos850
Message-ID: <20240224202053.25313-1-semen.protsenko@linaro.org>

The series implements CPU clock support for Exynos850, adds CPU CMUs to
the clock driver and enables those in dts. This is the first step
towards cpufreq implementation.

If possible, all patches should go through Krzysztof's tree. As
inter-series dependencies go:

  * All driver changes (patch 02..14) must be taken together following
    the order established in this series
  * Patch 15 (dts changes) depends on patch 01 (bindings additions)
  * Patch 14 (driver changes) depends on patch 01 (bindings additions)

The series was tested on E850-96 board, via DebugFS with
CLOCK_ALLOW_WRITE_DEBUGFS enabled, by setting different CPU clock rates,
like this:

  # cd /sys/kernel/debug/clk/cluster0_clk/
  # cat clk_rate
  1053000000
  # echo 10000000 > clk_rate
  # cat clk_rate
  130000000

Of course, DVFS/cpufreq is not implemented yet, so the CPU can't be
overclocked too much right now, and the cpufreq interface is not
available too. As per the TRM, the CPU operates at a voltage level of
0.65 V, 0.75 V, 0.85 V and 1.05 V. When the voltage is 0.85 V, A55
quad-core operates at 1.6 GHz and CoreSight at 200 MHz.

To check the actual frequency, the "perf" tool was used:

  # perf stat sleep 1

And to check that on a particular CPU core:

  # taskset -c 4 perf stat sleep 1

Some takeaways:

  * Max functional frequency right now is 1.586 GHz
  * 1.742 GHz or more leads to the system freeze, as it requires
    more voltage to be operational
  * Max possible frequency: 2.210 GHz
  * The lowest possible frequency: 130 MHz
  * Default boot up frequency: 1.053 GHz

Changes in v3:
  - Merged struct exynos850_cpuclk_regs fields into struct
    exynos_cpuclk_regs ("one-size-fits-all" approach)

Changes in v2:
  - Removed confusing "breakup by patch" list from patch #0 commit
    message
  - Dropped the patch for making clk.h a single included header
  - Rebased the series on top of the latest linux-next
  - See per-patch changes in each patch's changelog

Sam Protsenko (15):
  dt-bindings: clock: exynos850: Add CMU_CPUCLK0 and CMU_CPUCL1
  clk: samsung: Improve clk-cpu.c style
  clk: samsung: Pull struct exynos_cpuclk into clk-cpu.c
  clk: samsung: Reduce params count in exynos_register_cpu_clock()
  clk: samsung: Use single CPU clock notifier callback for all chips
  clk: samsung: Group CPU clock functions by chip
  clk: samsung: Pass actual CPU clock registers base to CPU_CLK()
  clk: samsung: Pass register layout type explicitly to CLK_CPU()
  clk: samsung: Keep CPU clock chip specific data in a dedicated struct
  clk: samsung: Keep register offsets in chip specific structure
  clk: samsung: Pass mask to wait_until_mux_stable()
  clk: samsung: Add CPU clock support for Exynos850
  clk: samsung: Implement manual PLL control for ARM64 SoCs
  clk: samsung: exynos850: Add CMU_CPUCL0 and CMU_CPUCL1
  arm64: dts: exynos: Add CPU clocks for Exynos850

 .../clock/samsung,exynos850-clock.yaml        |  42 ++
 arch/arm64/boot/dts/exynos/exynos850.dtsi     |  26 +
 drivers/clk/samsung/clk-cpu.c                 | 556 +++++++++++++-----
 drivers/clk/samsung/clk-cpu.h                 |  53 +-
 drivers/clk/samsung/clk-exynos-arm64.c        |  44 +-
 drivers/clk/samsung/clk-exynos3250.c          |   2 +-
 drivers/clk/samsung/clk-exynos4.c             |   9 +-
 drivers/clk/samsung/clk-exynos5250.c          |   5 +-
 drivers/clk/samsung/clk-exynos5420.c          |  16 +-
 drivers/clk/samsung/clk-exynos5433.c          |  10 +-
 drivers/clk/samsung/clk-exynos850.c           | 440 +++++++++++++-
 drivers/clk/samsung/clk.h                     |   9 +-
 include/dt-bindings/clock/exynos850.h         |  54 ++
 13 files changed, 1034 insertions(+), 232 deletions(-)

-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:39 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:39 -0600
Subject: [PATCH v3 01/15] dt-bindings: clock: exynos850: Add CMU_CPUCLK0 and CMU_CPUCL1
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-2-semen.protsenko@linaro.org>

Document CPU clock management unit compatibles and add corresponding
clock indices. Exynos850 has two CPU clusters (CL0 and CL1), each
containing 4 Cortex-A55 cores. CPU PLLs are generating main CPU clocks
for each cluster, and there are alternate ("switch") clocks that can be
used temporarily while re-configuring the PLL for the new rate. ACLK,
ATCLK, PCLKDBG and PERIPHCLK clocks are driving corresponding buses.
CLK_CLUSTERx_SCLK are actual leaf CPU clocks and should be used to
change CPU rates. Also some CoreSight clocks can be derived from
DBG_USER (debug clock).

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - none

 .../clock/samsung,exynos850-clock.yaml        | 42 +++++++++++++++
 include/dt-bindings/clock/exynos850.h         | 54 +++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
index c752c8985a53..cdc5ded59fe5 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
@@ -36,6 +36,8 @@ properties:
       - samsung,exynos850-cmu-aud
       - samsung,exynos850-cmu-cmgp
       - samsung,exynos850-cmu-core
+      - samsung,exynos850-cmu-cpucl0
+      - samsung,exynos850-cmu-cpucl1
       - samsung,exynos850-cmu-dpu
       - samsung,exynos850-cmu-g3d
       - samsung,exynos850-cmu-hsi
@@ -152,6 +154,46 @@ allOf:
             - const: dout_core_mmc_embd
             - const: dout_core_sss
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-cpucl0
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CPUCL0 switch clock (from CMU_TOP)
+            - description: CPUCL0 debug clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_cpucl0_switch
+            - const: dout_cpucl0_dbg
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-cpucl1
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CPUCL1 switch clock (from CMU_TOP)
+            - description: CPUCL1 debug clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_cpucl1_switch
+            - const: dout_cpucl1_dbg
+
   - if:
       properties:
         compatible:
diff --git a/include/dt-bindings/clock/exynos850.h b/include/dt-bindings/clock/exynos850.h
index bc15108aa3c2..7666241520f8 100644
--- a/include/dt-bindings/clock/exynos850.h
+++ b/include/dt-bindings/clock/exynos850.h
@@ -88,6 +88,18 @@
 #define CLK_MOUT_G3D_SWITCH		76
 #define CLK_GOUT_G3D_SWITCH		77
 #define CLK_DOUT_G3D_SWITCH		78
+#define CLK_MOUT_CPUCL0_DBG		79
+#define CLK_MOUT_CPUCL0_SWITCH		80
+#define CLK_GOUT_CPUCL0_DBG		81
+#define CLK_GOUT_CPUCL0_SWITCH		82
+#define CLK_DOUT_CPUCL0_DBG		83
+#define CLK_DOUT_CPUCL0_SWITCH		84
+#define CLK_MOUT_CPUCL1_DBG		85
+#define CLK_MOUT_CPUCL1_SWITCH		86
+#define CLK_GOUT_CPUCL1_DBG		87
+#define CLK_GOUT_CPUCL1_SWITCH		88
+#define CLK_DOUT_CPUCL1_DBG		89
+#define CLK_DOUT_CPUCL1_SWITCH		90
 
 /* CMU_APM */
 #define CLK_RCO_I3C_PMIC		1
@@ -195,6 +207,48 @@
 #define CLK_GOUT_CMGP_USI1_PCLK		14
 #define CLK_GOUT_SYSREG_CMGP_PCLK	15
 
+/* CMU_CPUCL0 */
+#define CLK_FOUT_CPUCL0_PLL		1
+#define CLK_MOUT_PLL_CPUCL0		2
+#define CLK_MOUT_CPUCL0_SWITCH_USER	3
+#define CLK_MOUT_CPUCL0_DBG_USER	4
+#define CLK_MOUT_CPUCL0_PLL		5
+#define CLK_DOUT_CPUCL0_CPU		6
+#define CLK_DOUT_CPUCL0_CMUREF		7
+#define CLK_DOUT_CPUCL0_PCLK		8
+#define CLK_DOUT_CLUSTER0_ACLK		9
+#define CLK_DOUT_CLUSTER0_ATCLK		10
+#define CLK_DOUT_CLUSTER0_PCLKDBG	11
+#define CLK_DOUT_CLUSTER0_PERIPHCLK	12
+#define CLK_GOUT_CLUSTER0_ATCLK		13
+#define CLK_GOUT_CLUSTER0_PCLK		14
+#define CLK_GOUT_CLUSTER0_PERIPHCLK	15
+#define CLK_GOUT_CLUSTER0_SCLK		16
+#define CLK_GOUT_CPUCL0_CMU_CPUCL0_PCLK	17
+#define CLK_GOUT_CLUSTER0_CPU		18
+#define CLK_CLUSTER0_SCLK		19
+
+/* CMU_CPUCL1 */
+#define CLK_FOUT_CPUCL1_PLL		1
+#define CLK_MOUT_PLL_CPUCL1		2
+#define CLK_MOUT_CPUCL1_SWITCH_USER	3
+#define CLK_MOUT_CPUCL1_DBG_USER	4
+#define CLK_MOUT_CPUCL1_PLL		5
+#define CLK_DOUT_CPUCL1_CPU		6
+#define CLK_DOUT_CPUCL1_CMUREF		7
+#define CLK_DOUT_CPUCL1_PCLK		8
+#define CLK_DOUT_CLUSTER1_ACLK		9
+#define CLK_DOUT_CLUSTER1_ATCLK		10
+#define CLK_DOUT_CLUSTER1_PCLKDBG	11
+#define CLK_DOUT_CLUSTER1_PERIPHCLK	12
+#define CLK_GOUT_CLUSTER1_ATCLK		13
+#define CLK_GOUT_CLUSTER1_PCLK		14
+#define CLK_GOUT_CLUSTER1_PERIPHCLK	15
+#define CLK_GOUT_CLUSTER1_SCLK		16
+#define CLK_GOUT_CPUCL1_CMU_CPUCL1_PCLK	17
+#define CLK_GOUT_CLUSTER1_CPU		18
+#define CLK_CLUSTER1_SCLK		19
+
 /* CMU_G3D */
 #define CLK_FOUT_G3D_PLL		1
 #define CLK_MOUT_G3D_PLL		2
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:40 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:40 -0600
Subject: [PATCH v3 02/15] clk: samsung: Improve clk-cpu.c style
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-3-semen.protsenko@linaro.org>

clk-cpu.c has numerous style issues reported by checkpatch and easily
identified otherwise. Give it some love and fix those warnings where it
makes sense. Also make stabilization time a named constant to get rid of
the magic number in clk-cpu.c.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 65 ++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 32 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 3e62ade120c5..e02730776aaa 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -16,18 +16,18 @@
  * of the SoC or supplied after the SoC characterization.
  *
  * The below implementation of the CPU clock allows the rate changes of the CPU
- * clock and the corresponding rate changes of the auxillary clocks of the CPU
+ * clock and the corresponding rate changes of the auxiliary clocks of the CPU
  * domain. The platform clock driver provides a clock register configuration
  * for each configurable rate which is then used to program the clock hardware
- * registers to acheive a fast co-oridinated rate change for all the CPU domain
+ * registers to achieve a fast coordinated rate change for all the CPU domain
  * clocks.
  *
  * On a rate change request for the CPU clock, the rate change is propagated
- * upto the PLL supplying the clock to the CPU domain clock blocks. While the
+ * up to the PLL supplying the clock to the CPU domain clock blocks. While the
  * CPU domain PLL is reconfigured, the CPU domain clocks are driven using an
  * alternate clock source. If required, the alternate clock source is divided
  * down in order to keep the output clock rate within the previous OPP limits.
-*/
+ */
 
 #include <linux/errno.h>
 #include <linux/io.h>
@@ -50,17 +50,19 @@
 #define E5433_DIV_STAT_CPU0	0x500
 #define E5433_DIV_STAT_CPU1	0x504
 
-#define E4210_DIV0_RATIO0_MASK	0x7
-#define E4210_DIV1_HPM_MASK	(0x7 << 4)
-#define E4210_DIV1_COPY_MASK	(0x7 << 0)
-#define E4210_MUX_HPM_MASK	(1 << 20)
+#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
+#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
+#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
+#define E4210_MUX_HPM_MASK	BIT(20)
 #define E4210_DIV0_ATB_SHIFT	16
 #define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
 
+/* Divider stabilization time, msec */
+#define MAX_STAB_TIME		10
 #define MAX_DIV			8
-#define DIV_MASK		7
-#define DIV_MASK_ALL		0xffffffff
-#define MUX_MASK		7
+#define DIV_MASK		GENMASK(2, 0)
+#define DIV_MASK_ALL		GENMASK(31, 0)
+#define MUX_MASK		GENMASK(2, 0)
 
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
@@ -68,7 +70,7 @@
  */
 static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
 {
-	unsigned long timeout = jiffies + msecs_to_jiffies(10);
+	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);
 
 	do {
 		if (!(readl(div_reg) & mask))
@@ -86,9 +88,9 @@ static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
  * value was changed.
  */
 static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
-					unsigned long mux_value)
+				  unsigned long mux_value)
 {
-	unsigned long timeout = jiffies + msecs_to_jiffies(10);
+	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);
 
 	do {
 		if (((readl(mux_reg) >> mux_pos) & MUX_MASK) == mux_value)
@@ -101,18 +103,18 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
 }
 
-/* common round rate callback useable for all types of CPU clocks */
-static long exynos_cpuclk_round_rate(struct clk_hw *hw,
-			unsigned long drate, unsigned long *prate)
+/* common round rate callback usable for all types of CPU clocks */
+static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate,
+				     unsigned long *prate)
 {
 	struct clk_hw *parent = clk_hw_get_parent(hw);
 	*prate = clk_hw_round_rate(parent, drate);
 	return *prate;
 }
 
-/* common recalc rate callback useable for all types of CPU clocks */
+/* common recalc rate callback usable for all types of CPU clocks */
 static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw,
-			unsigned long parent_rate)
+					       unsigned long parent_rate)
 {
 	/*
 	 * The CPU clock output (armclk) rate is the same as its parent
@@ -135,7 +137,7 @@ static const struct clk_ops exynos_cpuclk_clk_ops = {
  * dividers to be programmed.
  */
 static void exynos_set_safe_div(void __iomem *base, unsigned long div,
-					unsigned long mask)
+				unsigned long mask)
 {
 	unsigned long div0;
 
@@ -151,7 +153,6 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
-	unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
 
@@ -187,6 +188,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	 */
 	if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) {
 		unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate);
+		unsigned long alt_div, alt_div_mask = DIV_MASK;
 
 		alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
 		WARN_ON(alt_div >= MAX_DIV);
@@ -215,7 +217,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
 		writel(div1, base + E4210_DIV_CPU1);
 		wait_until_divider_stable(base + E4210_DIV_STAT_CPU1,
-				DIV_MASK_ALL);
+					  DIV_MASK_ALL);
 	}
 
 	spin_unlock_irqrestore(cpuclk->lock, flags);
@@ -263,7 +265,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
  * dividers to be programmed.
  */
 static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
-					unsigned long mask)
+				    unsigned long mask)
 {
 	unsigned long div0;
 
@@ -279,7 +281,6 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
-	unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
 
@@ -309,6 +310,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	 */
 	if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) {
 		unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate);
+		unsigned long alt_div, alt_div_mask = DIV_MASK;
 
 		alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
 		WARN_ON(alt_div >= MAX_DIV);
@@ -358,7 +360,7 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
  * notifications of the parent clock of cpuclk.
  */
 static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
-				unsigned long event, void *data)
+				     unsigned long event, void *data)
 {
 	struct clk_notifier_data *ndata = data;
 	struct exynos_cpuclk *cpuclk;
@@ -381,7 +383,7 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
  * notifications of the parent clock of cpuclk.
  */
 static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
-				unsigned long event, void *data)
+					 unsigned long event, void *data)
 {
 	struct clk_notifier_data *ndata = data;
 	struct exynos_cpuclk *cpuclk;
@@ -438,11 +440,10 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	else
 		cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
 
-
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
 		pr_err("%s: failed to register clock notifier for %s\n",
-				__func__, name);
+		       __func__, name);
 		goto free_cpuclk;
 	}
 
@@ -454,7 +455,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	ret = clk_hw_register(NULL, &cpuclk->hw);
 	if (ret) {
-		pr_err("%s: could not register cpuclk %s\n", __func__,	name);
+		pr_err("%s: could not register cpuclk %s\n", __func__, name);
 		goto free_cpuclk_data;
 	}
 
@@ -482,8 +483,8 @@ void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
 		for (num_cfgs = 0; list->cfg[num_cfgs].prate != 0; )
 			num_cfgs++;
 
-		exynos_register_cpu_clock(ctx, list->id, list->name, hws[list->parent_id],
-				hws[list->alt_parent_id], list->offset, list->cfg, num_cfgs,
-				list->flags);
+		exynos_register_cpu_clock(ctx, list->id, list->name,
+			hws[list->parent_id], hws[list->alt_parent_id],
+			list->offset, list->cfg, num_cfgs, list->flags);
 	}
 }
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:41 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:41 -0600
Subject: [PATCH v3 03/15] clk: samsung: Pull struct exynos_cpuclk into clk-cpu.c
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-4-semen.protsenko@linaro.org>

Reduce the scope of struct exynos_cpuclk, as it's only used in clk-cpu.c
internally. All drivers using clk-pll.h already include clk.h as well,
so this change doesn't break anything.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 29 +++++++++++++++++++++++++
 drivers/clk/samsung/clk-cpu.h | 41 +++++------------------------------
 2 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index e02730776aaa..6412fd2580e0 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -34,6 +34,8 @@
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+
+#include "clk.h"
 #include "clk-cpu.h"
 
 #define E4210_SRC_CPU		0x0
@@ -64,6 +66,33 @@
 #define DIV_MASK_ALL		GENMASK(31, 0)
 #define MUX_MASK		GENMASK(2, 0)
 
+/**
+ * struct exynos_cpuclk - information about clock supplied to a CPU core
+ * @hw:		handle between CCF and CPU clock
+ * @alt_parent:	alternate parent clock to use when switching the speed
+ *		of the primary parent clock
+ * @ctrl_base:	base address of the clock controller
+ * @lock:	cpu clock domain register access lock
+ * @cfg:	cpu clock rate configuration data
+ * @num_cfgs:	number of array elements in @cfg array
+ * @clk_nb:	clock notifier registered for changes in clock speed of the
+ *		primary parent clock
+ * @flags:	configuration flags for the CPU clock
+ *
+ * This structure holds information required for programming the CPU clock for
+ * various clock speeds.
+ */
+struct exynos_cpuclk {
+	struct clk_hw				hw;
+	const struct clk_hw			*alt_parent;
+	void __iomem				*ctrl_base;
+	spinlock_t				*lock;
+	const struct exynos_cpuclk_cfg_data	*cfg;
+	const unsigned long			num_cfgs;
+	struct notifier_block			clk_nb;
+	unsigned long				flags;
+};
+
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
  * value has changed.
diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h
index 0164bd9ad021..ee57f3638fed 100644
--- a/drivers/clk/samsung/clk-cpu.h
+++ b/drivers/clk/samsung/clk-cpu.h
@@ -8,7 +8,12 @@
 #ifndef __SAMSUNG_CLK_CPU_H
 #define __SAMSUNG_CLK_CPU_H
 
-#include "clk.h"
+/* The CPU clock registers have DIV1 configuration register */
+#define CLK_CPU_HAS_DIV1		BIT(0)
+/* When ALT parent is active, debug clocks need safe divider values */
+#define CLK_CPU_NEEDS_DEBUG_ALT_DIV	BIT(1)
+/* The CPU clock registers have Exynos5433-compatible layout */
+#define CLK_CPU_HAS_E5433_REGS_LAYOUT	BIT(2)
 
 /**
  * struct exynos_cpuclk_cfg_data - config data to setup cpu clocks
@@ -28,38 +33,4 @@ struct exynos_cpuclk_cfg_data {
 	unsigned long	div1;
 };
 
-/**
- * struct exynos_cpuclk - information about clock supplied to a CPU core
- * @hw:		handle between CCF and CPU clock
- * @alt_parent:	alternate parent clock to use when switching the speed
- *		of the primary parent clock
- * @ctrl_base:	base address of the clock controller
- * @lock:	cpu clock domain register access lock
- * @cfg:	cpu clock rate configuration data
- * @num_cfgs:	number of array elements in @cfg array
- * @clk_nb:	clock notifier registered for changes in clock speed of the
- *		primary parent clock
- * @flags:	configuration flags for the CPU clock
- *
- * This structure holds information required for programming the CPU clock for
- * various clock speeds.
- */
-struct exynos_cpuclk {
-	struct clk_hw				hw;
-	const struct clk_hw			*alt_parent;
-	void __iomem				*ctrl_base;
-	spinlock_t				*lock;
-	const struct exynos_cpuclk_cfg_data	*cfg;
-	const unsigned long			num_cfgs;
-	struct notifier_block			clk_nb;
-	unsigned long				flags;
-
-/* The CPU clock registers have DIV1 configuration register */
-#define CLK_CPU_HAS_DIV1		(1 << 0)
-/* When ALT parent is active, debug clocks need safe divider values */
-#define CLK_CPU_NEEDS_DEBUG_ALT_DIV	(1 << 1)
-/* The CPU clock registers have Exynos5433-compatible layout */
-#define CLK_CPU_HAS_E5433_REGS_LAYOUT	(1 << 2)
-};
-
 #endif /* __SAMSUNG_CLK_CPU_H */
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:42 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:42 -0600
Subject: [PATCH v3 04/15] clk: samsung: Reduce params count in exynos_register_cpu_clock()
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-5-semen.protsenko@linaro.org>

Pass CPU clock data structure to exynos_register_cpu_clock() instead of
passing its fields separately there. That simplifies the signature of
exynos_register_cpu_clock() and makes it easier to add more fields to
struct samsung_cpu_clock later. This style follows the example of
samsung_clk_register_pll().

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 46 +++++++++++++++++------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 6412fd2580e0..7b6fd331a7ec 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -432,16 +432,19 @@ static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
 
 /* helper function to register a CPU clock */
 static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
-		unsigned int lookup_id, const char *name,
-		const struct clk_hw *parent, const struct clk_hw *alt_parent,
-		unsigned long offset, const struct exynos_cpuclk_cfg_data *cfg,
-		unsigned long num_cfgs, unsigned long flags)
+				const struct samsung_cpu_clock *clk_data)
 {
+	const struct clk_hw *parent, *alt_parent;
+	struct clk_hw **hws;
 	struct exynos_cpuclk *cpuclk;
 	struct clk_init_data init;
 	const char *parent_name;
+	unsigned int num_cfgs;
 	int ret = 0;
 
+	hws = ctx->clk_data.hws;
+	parent = hws[clk_data->parent_id];
+	alt_parent = hws[clk_data->alt_parent_id];
 	if (IS_ERR(parent) || IS_ERR(alt_parent)) {
 		pr_err("%s: invalid parent clock(s)\n", __func__);
 		return -EINVAL;
@@ -453,7 +456,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	parent_name = clk_hw_get_name(parent);
 
-	init.name = name;
+	init.name = clk_data->name;
 	init.flags = CLK_SET_RATE_PARENT;
 	init.parent_names = &parent_name;
 	init.num_parents = 1;
@@ -461,10 +464,10 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	cpuclk->alt_parent = alt_parent;
 	cpuclk->hw.init = &init;
-	cpuclk->ctrl_base = ctx->reg_base + offset;
+	cpuclk->ctrl_base = ctx->reg_base + clk_data->offset;
 	cpuclk->lock = &ctx->lock;
-	cpuclk->flags = flags;
-	if (flags & CLK_CPU_HAS_E5433_REGS_LAYOUT)
+	cpuclk->flags = clk_data->flags;
+	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT)
 		cpuclk->clk_nb.notifier_call = exynos5433_cpuclk_notifier_cb;
 	else
 		cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
@@ -472,11 +475,16 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
 		pr_err("%s: failed to register clock notifier for %s\n",
-		       __func__, name);
+		       __func__, clk_data->name);
 		goto free_cpuclk;
 	}
 
-	cpuclk->cfg = kmemdup(cfg, sizeof(*cfg) * num_cfgs, GFP_KERNEL);
+	/* Find count of configuration rates in cfg */
+	for (num_cfgs = 0; clk_data->cfg[num_cfgs].prate != 0; )
+		num_cfgs++;
+
+	cpuclk->cfg = kmemdup(clk_data->cfg, sizeof(*clk_data->cfg) * num_cfgs,
+			      GFP_KERNEL);
 	if (!cpuclk->cfg) {
 		ret = -ENOMEM;
 		goto unregister_clk_nb;
@@ -484,11 +492,12 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	ret = clk_hw_register(NULL, &cpuclk->hw);
 	if (ret) {
-		pr_err("%s: could not register cpuclk %s\n", __func__, name);
+		pr_err("%s: could not register cpuclk %s\n", __func__,
+		       clk_data->name);
 		goto free_cpuclk_data;
 	}
 
-	samsung_clk_add_lookup(ctx, &cpuclk->hw, lookup_id);
+	samsung_clk_add_lookup(ctx, &cpuclk->hw, clk_data->id);
 	return 0;
 
 free_cpuclk_data:
@@ -504,16 +513,7 @@ void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
 		const struct samsung_cpu_clock *list, unsigned int nr_clk)
 {
 	unsigned int idx;
-	unsigned int num_cfgs;
-	struct clk_hw **hws = ctx->clk_data.hws;
 
-	for (idx = 0; idx < nr_clk; idx++, list++) {
-		/* find count of configuration rates in cfg */
-		for (num_cfgs = 0; list->cfg[num_cfgs].prate != 0; )
-			num_cfgs++;
-
-		exynos_register_cpu_clock(ctx, list->id, list->name,
-			hws[list->parent_id], hws[list->alt_parent_id],
-			list->offset, list->cfg, num_cfgs, list->flags);
-	}
+	for (idx = 0; idx < nr_clk; idx++)
+		exynos_register_cpu_clock(ctx, &list[idx]);
 }
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:43 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:43 -0600
Subject: [PATCH v3 05/15] clk: samsung: Use single CPU clock notifier callback for all chips
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-6-semen.protsenko@linaro.org>

Reduce the code duplication by making all chips use a single version of
exynos_cpuclk_notifier_cb() function. That will prevent the code bloat
when adding new chips support too.

Also don't pass base address to pre/post rate change functions, as it
can be easily derived from already passed cpuclk param.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 63 ++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 35 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 7b6fd331a7ec..427018e8dd8c 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -66,6 +66,11 @@
 #define DIV_MASK_ALL		GENMASK(31, 0)
 #define MUX_MASK		GENMASK(2, 0)
 
+struct exynos_cpuclk;
+
+typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
+				       struct exynos_cpuclk *cpuclk);
+
 /**
  * struct exynos_cpuclk - information about clock supplied to a CPU core
  * @hw:		handle between CCF and CPU clock
@@ -78,6 +83,8 @@
  * @clk_nb:	clock notifier registered for changes in clock speed of the
  *		primary parent clock
  * @flags:	configuration flags for the CPU clock
+ * @pre_rate_cb: callback to run before CPU clock rate change
+ * @post_rate_cb: callback to run after CPU clock rate change
  *
  * This structure holds information required for programming the CPU clock for
  * various clock speeds.
@@ -91,6 +98,9 @@ struct exynos_cpuclk {
 	const unsigned long			num_cfgs;
 	struct notifier_block			clk_nb;
 	unsigned long				flags;
+
+	exynos_rate_change_fn_t			pre_rate_cb;
+	exynos_rate_change_fn_t			post_rate_cb;
 };
 
 /*
@@ -178,9 +188,10 @@ static void exynos_set_safe_div(void __iomem *base, unsigned long div,
 
 /* handler for pre-rate change notification from parent clock */
 static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					 struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
@@ -255,9 +266,10 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 
 /* handler for post-rate change notification from parent clock */
 static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					  struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
 	unsigned long flags;
@@ -306,9 +318,10 @@ static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
 
 /* handler for pre-rate change notification from parent clock */
 static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					     struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
@@ -366,8 +379,9 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 
 /* handler for post-rate change notification from parent clock */
 static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
-			struct exynos_cpuclk *cpuclk, void __iomem *base)
+					      struct exynos_cpuclk *cpuclk)
 {
+	void __iomem *base = cpuclk->ctrl_base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
 	unsigned long flags;
@@ -393,39 +407,14 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
 {
 	struct clk_notifier_data *ndata = data;
 	struct exynos_cpuclk *cpuclk;
-	void __iomem *base;
 	int err = 0;
 
 	cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb);
-	base = cpuclk->ctrl_base;
 
 	if (event == PRE_RATE_CHANGE)
-		err = exynos_cpuclk_pre_rate_change(ndata, cpuclk, base);
+		err = cpuclk->pre_rate_cb(ndata, cpuclk);
 	else if (event == POST_RATE_CHANGE)
-		err = exynos_cpuclk_post_rate_change(ndata, cpuclk, base);
-
-	return notifier_from_errno(err);
-}
-
-/*
- * This notifier function is called for the pre-rate and post-rate change
- * notifications of the parent clock of cpuclk.
- */
-static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
-					 unsigned long event, void *data)
-{
-	struct clk_notifier_data *ndata = data;
-	struct exynos_cpuclk *cpuclk;
-	void __iomem *base;
-	int err = 0;
-
-	cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb);
-	base = cpuclk->ctrl_base;
-
-	if (event == PRE_RATE_CHANGE)
-		err = exynos5433_cpuclk_pre_rate_change(ndata, cpuclk, base);
-	else if (event == POST_RATE_CHANGE)
-		err = exynos5433_cpuclk_post_rate_change(ndata, cpuclk, base);
+		err = cpuclk->post_rate_cb(ndata, cpuclk);
 
 	return notifier_from_errno(err);
 }
@@ -467,10 +456,14 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	cpuclk->ctrl_base = ctx->reg_base + clk_data->offset;
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
-	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT)
-		cpuclk->clk_nb.notifier_call = exynos5433_cpuclk_notifier_cb;
-	else
-		cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
+	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
+	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT) {
+		cpuclk->pre_rate_cb = exynos5433_cpuclk_pre_rate_change;
+		cpuclk->post_rate_cb = exynos5433_cpuclk_post_rate_change;
+	} else {
+		cpuclk->pre_rate_cb = exynos_cpuclk_pre_rate_change;
+		cpuclk->post_rate_cb = exynos_cpuclk_post_rate_change;
+	}
 
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:44 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:44 -0600
Subject: [PATCH v3 06/15] clk: samsung: Group CPU clock functions by chip
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-7-semen.protsenko@linaro.org>

clk-cpu.c is going to get messy as new chips support is added.
Restructure the code by pulling related functions and definitions
together, grouping those by their relation to a particular chip or other
categories, to simplify the code navigation.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 114 ++++++++++++++++++----------------
 1 file changed, 61 insertions(+), 53 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 427018e8dd8c..d550a4bb632f 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -38,34 +38,6 @@
 #include "clk.h"
 #include "clk-cpu.h"
 
-#define E4210_SRC_CPU		0x0
-#define E4210_STAT_CPU		0x200
-#define E4210_DIV_CPU0		0x300
-#define E4210_DIV_CPU1		0x304
-#define E4210_DIV_STAT_CPU0	0x400
-#define E4210_DIV_STAT_CPU1	0x404
-
-#define E5433_MUX_SEL2		0x008
-#define E5433_MUX_STAT2		0x208
-#define E5433_DIV_CPU0		0x400
-#define E5433_DIV_CPU1		0x404
-#define E5433_DIV_STAT_CPU0	0x500
-#define E5433_DIV_STAT_CPU1	0x504
-
-#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
-#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
-#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
-#define E4210_MUX_HPM_MASK	BIT(20)
-#define E4210_DIV0_ATB_SHIFT	16
-#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
-
-/* Divider stabilization time, msec */
-#define MAX_STAB_TIME		10
-#define MAX_DIV			8
-#define DIV_MASK		GENMASK(2, 0)
-#define DIV_MASK_ALL		GENMASK(31, 0)
-#define MUX_MASK		GENMASK(2, 0)
-
 struct exynos_cpuclk;
 
 typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
@@ -103,6 +75,15 @@ struct exynos_cpuclk {
 	exynos_rate_change_fn_t			post_rate_cb;
 };
 
+/* ---- Common code --------------------------------------------------------- */
+
+/* Divider stabilization time, msec */
+#define MAX_STAB_TIME		10
+#define MAX_DIV			8
+#define DIV_MASK		GENMASK(2, 0)
+#define DIV_MASK_ALL		GENMASK(31, 0)
+#define MUX_MASK		GENMASK(2, 0)
+
 /*
  * Helper function to wait until divider(s) have stabilized after the divider
  * value has changed.
@@ -142,33 +123,21 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
 }
 
-/* common round rate callback usable for all types of CPU clocks */
-static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate,
-				     unsigned long *prate)
-{
-	struct clk_hw *parent = clk_hw_get_parent(hw);
-	*prate = clk_hw_round_rate(parent, drate);
-	return *prate;
-}
+/* ---- Exynos 3/4/5 -------------------------------------------------------- */
 
-/* common recalc rate callback usable for all types of CPU clocks */
-static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw,
-					       unsigned long parent_rate)
-{
-	/*
-	 * The CPU clock output (armclk) rate is the same as its parent
-	 * rate. Although there exist certain dividers inside the CPU
-	 * clock block that could be used to divide the parent clock,
-	 * the driver does not make use of them currently, except during
-	 * frequency transitions.
-	 */
-	return parent_rate;
-}
+#define E4210_SRC_CPU		0x0
+#define E4210_STAT_CPU		0x200
+#define E4210_DIV_CPU0		0x300
+#define E4210_DIV_CPU1		0x304
+#define E4210_DIV_STAT_CPU0	0x400
+#define E4210_DIV_STAT_CPU1	0x404
 
-static const struct clk_ops exynos_cpuclk_clk_ops = {
-	.recalc_rate = exynos_cpuclk_recalc_rate,
-	.round_rate = exynos_cpuclk_round_rate,
-};
+#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
+#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
+#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
+#define E4210_MUX_HPM_MASK	BIT(20)
+#define E4210_DIV0_ATB_SHIFT	16
+#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
 
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
@@ -300,6 +269,15 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	return 0;
 }
 
+/* ---- Exynos5433 ---------------------------------------------------------- */
+
+#define E5433_MUX_SEL2		0x008
+#define E5433_MUX_STAT2		0x208
+#define E5433_DIV_CPU0		0x400
+#define E5433_DIV_CPU1		0x404
+#define E5433_DIV_STAT_CPU0	0x500
+#define E5433_DIV_STAT_CPU1	0x504
+
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
  * div and mask contain the divider value and the register bit mask of the
@@ -398,6 +376,36 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	return 0;
 }
 
+/* -------------------------------------------------------------------------- */
+
+/* Common round rate callback usable for all types of CPU clocks */
+static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate,
+				     unsigned long *prate)
+{
+	struct clk_hw *parent = clk_hw_get_parent(hw);
+	*prate = clk_hw_round_rate(parent, drate);
+	return *prate;
+}
+
+/* Common recalc rate callback usable for all types of CPU clocks */
+static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	/*
+	 * The CPU clock output (armclk) rate is the same as its parent
+	 * rate. Although there exist certain dividers inside the CPU
+	 * clock block that could be used to divide the parent clock,
+	 * the driver does not make use of them currently, except during
+	 * frequency transitions.
+	 */
+	return parent_rate;
+}
+
+static const struct clk_ops exynos_cpuclk_clk_ops = {
+	.recalc_rate = exynos_cpuclk_recalc_rate,
+	.round_rate = exynos_cpuclk_round_rate,
+};
+
 /*
  * This notifier function is called for the pre-rate and post-rate change
  * notifications of the parent clock of cpuclk.
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:45 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:45 -0600
Subject: [PATCH v3 07/15] clk: samsung: Pass actual CPU clock registers base to CPU_CLK()
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-8-semen.protsenko@linaro.org>

The documentation for struct exynos_cpuclk says .ctrl_base field should
contain the controller base address. There are two different problems
with that:

1. All Exynos clock drivers are actually passing CPU_SRC register offset
   via CPU_CLK() macro, which in turn gets assigned to mentioned
   .ctrl_base field. Because CPU_SRC register usually already has 0x200
   offset from controller's base, all other register offsets in
   clk-cpu.c (like DIVs and MUXes) are specified as offsets from CPU_SRC
   offset, and not from controller's base. That makes things confusing
   and inconsistent with register offsets provided in Exynos clock
   drivers, also breaking the contract for .ctrl_base field as described
   in struct exynos_cpuclk doc.

2. Furthermore, some Exynos chips have an additional offset for the
   start of CPU clock registers block (inside of the CMU). There might
   be different reasons for that, e.g.:

   - The CMU contains clocks for two different CPUs (like in Exynos5420)
   - The CMU contains also non-CPU clocks as well (like in Exynos4)
   - The CPU CMU exists as a dedicated hardware block in the SoC layout,
     but is modelled as a part of bigger CMU in the driver (like in case
     of Exynos3250)

   That means the .ctrl_base field is actually not a controller's base,
   but instead it's a start address of the CPU clock registers inside of
   the CMU.

Rework all register offsets in clk-cpu.c to be actual offsets from the
CPU clock register block start, and fix offsets provided to CPU_CLK()
macro in all Exynos clock drivers. Also clarify the .ctrl_base field
documentation and rename it to just .base, because it doesn't really
contain the CMU base.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - Renamed .ctrl_base field to .base and fixed its documentation
  - Fixed typo in commit message: Exynis -> Exynos
  - Improved the commit message: mentioned that .ctrl_base is actually a
    start address of the CPU clock register block, not the CMU base

 drivers/clk/samsung/clk-cpu.c        | 38 ++++++++++++++--------------
 drivers/clk/samsung/clk-exynos3250.c |  2 +-
 drivers/clk/samsung/clk-exynos4.c    |  9 ++++---
 drivers/clk/samsung/clk-exynos5250.c |  4 +--
 drivers/clk/samsung/clk-exynos5420.c | 16 ++++++------
 drivers/clk/samsung/clk-exynos5433.c | 10 +++-----
 6 files changed, 40 insertions(+), 39 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index d550a4bb632f..82d54b0c9040 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -48,7 +48,7 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
  * @hw:		handle between CCF and CPU clock
  * @alt_parent:	alternate parent clock to use when switching the speed
  *		of the primary parent clock
- * @ctrl_base:	base address of the clock controller
+ * @base:	start address of the CPU clock registers block
  * @lock:	cpu clock domain register access lock
  * @cfg:	cpu clock rate configuration data
  * @num_cfgs:	number of array elements in @cfg array
@@ -64,7 +64,7 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
 struct exynos_cpuclk {
 	struct clk_hw				hw;
 	const struct clk_hw			*alt_parent;
-	void __iomem				*ctrl_base;
+	void __iomem				*base;
 	spinlock_t				*lock;
 	const struct exynos_cpuclk_cfg_data	*cfg;
 	const unsigned long			num_cfgs;
@@ -125,12 +125,12 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 
 /* ---- Exynos 3/4/5 -------------------------------------------------------- */
 
-#define E4210_SRC_CPU		0x0
-#define E4210_STAT_CPU		0x200
-#define E4210_DIV_CPU0		0x300
-#define E4210_DIV_CPU1		0x304
-#define E4210_DIV_STAT_CPU0	0x400
-#define E4210_DIV_STAT_CPU1	0x404
+#define E4210_SRC_CPU		0x200
+#define E4210_STAT_CPU		0x400
+#define E4210_DIV_CPU0		0x500
+#define E4210_DIV_CPU1		0x504
+#define E4210_DIV_STAT_CPU0	0x600
+#define E4210_DIV_STAT_CPU1	0x604
 
 #define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
 #define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
@@ -160,7 +160,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 					 struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
-	void __iomem *base = cpuclk->ctrl_base;
+	void __iomem *base = cpuclk->base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
@@ -238,7 +238,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 					  struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
-	void __iomem *base = cpuclk->ctrl_base;
+	void __iomem *base = cpuclk->base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
 	unsigned long flags;
@@ -271,12 +271,12 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 
 /* ---- Exynos5433 ---------------------------------------------------------- */
 
-#define E5433_MUX_SEL2		0x008
-#define E5433_MUX_STAT2		0x208
-#define E5433_DIV_CPU0		0x400
-#define E5433_DIV_CPU1		0x404
-#define E5433_DIV_STAT_CPU0	0x500
-#define E5433_DIV_STAT_CPU1	0x504
+#define E5433_MUX_SEL2		0x208
+#define E5433_MUX_STAT2		0x408
+#define E5433_DIV_CPU0		0x600
+#define E5433_DIV_CPU1		0x604
+#define E5433_DIV_STAT_CPU0	0x700
+#define E5433_DIV_STAT_CPU1	0x704
 
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
@@ -299,7 +299,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 					     struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
-	void __iomem *base = cpuclk->ctrl_base;
+	void __iomem *base = cpuclk->base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
 	unsigned long flags;
@@ -359,7 +359,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 					      struct exynos_cpuclk *cpuclk)
 {
-	void __iomem *base = cpuclk->ctrl_base;
+	void __iomem *base = cpuclk->base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
 	unsigned long flags;
@@ -461,7 +461,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 
 	cpuclk->alt_parent = alt_parent;
 	cpuclk->hw.init = &init;
-	cpuclk->ctrl_base = ctx->reg_base + clk_data->offset;
+	cpuclk->base = ctx->reg_base + clk_data->offset;
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
 	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index a02461667664..bf149fae04c3 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -775,7 +775,7 @@ static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos3250_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-			CLK_CPU_HAS_DIV1, 0x14200, e3250_armclk_d),
+		CLK_CPU_HAS_DIV1, 0x14000, e3250_armclk_d),
 };
 
 static void __init exynos3_core_down_clock(void __iomem *reg_base)
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 4ec41221e68f..d5b1e9f49d8b 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1252,17 +1252,20 @@ static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos4210_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_SCLK_MPLL,
-			CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4210_armclk_d),
+		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
+		e4210_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4212_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4212_armclk_d),
+		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
+		e4212_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4412_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-			CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4412_armclk_d),
+		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
+		e4412_armclk_d),
 };
 
 /* register exynos4 clocks */
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 8ebe6155d8b7..58df80de52ef 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -776,8 +776,8 @@ static const struct exynos_cpuclk_cfg_data exynos5250_armclk_d[] __initconst = {
 };
 
 static const struct samsung_cpu_clock exynos5250_cpu_clks[] __initconst = {
-	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL, CLK_CPU_HAS_DIV1, 0x200,
-			exynos5250_armclk_d),
+	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL,
+		CLK_CPU_HAS_DIV1, 0x0, exynos5250_armclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 199843f12ae5..bd7b304d2c00 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -1555,17 +1555,17 @@ static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = {
 };
 
 static const struct samsung_cpu_clock exynos5420_cpu_clks[] __initconst = {
-	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200,
-			exynos5420_eglclk_d),
-	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200,
-			exynos5420_kfcclk_d),
+	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
+		0x0, exynos5420_eglclk_d),
+	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
+		0x28000, exynos5420_kfcclk_d),
 };
 
 static const struct samsung_cpu_clock exynos5800_cpu_clks[] __initconst = {
-	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200,
-			exynos5800_eglclk_d),
-	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200,
-			exynos5420_kfcclk_d),
+	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
+		0x0, exynos5800_eglclk_d),
+	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
+		0x28000, exynos5420_kfcclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index 6bfc5d0cd924..d3779eefb438 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -3700,9 +3700,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_apolloclk_d[] __initconst
 
 static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL,
-			CLK_MOUT_BUS_PLL_APOLLO_USER,
-			CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200,
-			exynos5433_apolloclk_d),
+		CLK_MOUT_BUS_PLL_APOLLO_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
+		0x0, exynos5433_apolloclk_d),
 };
 
 static const struct samsung_cmu_info apollo_cmu_info __initconst = {
@@ -3945,9 +3944,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_atlasclk_d[] __initconst =
 
 static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL,
-			CLK_MOUT_BUS_PLL_ATLAS_USER,
-			CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200,
-			exynos5433_atlasclk_d),
+		CLK_MOUT_BUS_PLL_ATLAS_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
+		0x0, exynos5433_atlasclk_d),
 };
 
 static const struct samsung_cmu_info atlas_cmu_info __initconst = {
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:46 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:46 -0600
Subject: [PATCH v3 08/15] clk: samsung: Pass register layout type explicitly to CLK_CPU()
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-9-semen.protsenko@linaro.org>

Use a dedicated enum field to explicitly specify which register layout
should be used for the CPU clock, instead of passing it as a bit flag.
This way it would be possible to keep the chip-specific data in some
array, where each chip structure could be accessed by its corresponding
layout index. It prepares clk-cpu.c for adding new chips support, which
might have different data for different CPU clusters.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - Improved the commit message: explained why enum is needed for
    specifying the layout (vs bit flag)
  - Included clk-cpu.h in clk.h as it uses enum exynos_cpuclk_layout
    from clk-cpu.h (it's needed because preceding patch adding headers
    was dropped)

 drivers/clk/samsung/clk-cpu.c        |  2 +-
 drivers/clk/samsung/clk-cpu.h        | 12 ++++++++++--
 drivers/clk/samsung/clk-exynos3250.c |  2 +-
 drivers/clk/samsung/clk-exynos4.c    |  6 +++---
 drivers/clk/samsung/clk-exynos5250.c |  3 ++-
 drivers/clk/samsung/clk-exynos5420.c |  8 ++++----
 drivers/clk/samsung/clk-exynos5433.c |  8 ++++----
 drivers/clk/samsung/clk.h            |  5 ++++-
 8 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 82d54b0c9040..635ab8cc54a2 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -465,7 +465,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
 	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
-	if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT) {
+	if (clk_data->reg_layout == CPUCLK_LAYOUT_E5433) {
 		cpuclk->pre_rate_cb = exynos5433_cpuclk_pre_rate_change;
 		cpuclk->post_rate_cb = exynos5433_cpuclk_post_rate_change;
 	} else {
diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h
index ee57f3638fed..4382ab005ad3 100644
--- a/drivers/clk/samsung/clk-cpu.h
+++ b/drivers/clk/samsung/clk-cpu.h
@@ -12,8 +12,16 @@
 #define CLK_CPU_HAS_DIV1		BIT(0)
 /* When ALT parent is active, debug clocks need safe divider values */
 #define CLK_CPU_NEEDS_DEBUG_ALT_DIV	BIT(1)
-/* The CPU clock registers have Exynos5433-compatible layout */
-#define CLK_CPU_HAS_E5433_REGS_LAYOUT	BIT(2)
+
+/**
+ * enum exynos_cpuclk_layout - CPU clock registers layout compatibility
+ * @CPUCLK_LAYOUT_E4210: Exynos4210 compatible layout
+ * @CPUCLK_LAYOUT_E5433: Exynos5433 compatible layout
+ */
+enum exynos_cpuclk_layout {
+	CPUCLK_LAYOUT_E4210,
+	CPUCLK_LAYOUT_E5433,
+};
 
 /**
  * struct exynos_cpuclk_cfg_data - config data to setup cpu clocks
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index bf149fae04c3..cd4fec323a42 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -775,7 +775,7 @@ static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos3250_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
-		CLK_CPU_HAS_DIV1, 0x14000, e3250_armclk_d),
+		CLK_CPU_HAS_DIV1, 0x14000, CPUCLK_LAYOUT_E4210, e3250_armclk_d),
 };
 
 static void __init exynos3_core_down_clock(void __iomem *reg_base)
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index d5b1e9f49d8b..a026ccca7315 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1253,19 +1253,19 @@ static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
 static const struct samsung_cpu_clock exynos4210_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_SCLK_MPLL,
 		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
-		e4210_armclk_d),
+		CPUCLK_LAYOUT_E4210, e4210_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4212_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
 		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
-		e4212_armclk_d),
+		CPUCLK_LAYOUT_E4210, e4212_armclk_d),
 };
 
 static const struct samsung_cpu_clock exynos4412_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C,
 		CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000,
-		e4412_armclk_d),
+		CPUCLK_LAYOUT_E4210, e4412_armclk_d),
 };
 
 /* register exynos4 clocks */
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 58df80de52ef..e02e7c013f3d 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -777,7 +777,8 @@ static const struct exynos_cpuclk_cfg_data exynos5250_armclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos5250_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL,
-		CLK_CPU_HAS_DIV1, 0x0, exynos5250_armclk_d),
+		CLK_CPU_HAS_DIV1, 0x0, CPUCLK_LAYOUT_E4210,
+		exynos5250_armclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index bd7b304d2c00..c630135c686b 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -1556,16 +1556,16 @@ static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = {
 
 static const struct samsung_cpu_clock exynos5420_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
-		0x0, exynos5420_eglclk_d),
+		0x0, CPUCLK_LAYOUT_E4210, exynos5420_eglclk_d),
 	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
-		0x28000, exynos5420_kfcclk_d),
+		0x28000, CPUCLK_LAYOUT_E4210, exynos5420_kfcclk_d),
 };
 
 static const struct samsung_cpu_clock exynos5800_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0,
-		0x0, exynos5800_eglclk_d),
+		0x0, CPUCLK_LAYOUT_E4210, exynos5800_eglclk_d),
 	CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0,
-		0x28000, exynos5420_kfcclk_d),
+		0x28000, CPUCLK_LAYOUT_E4210, exynos5420_kfcclk_d),
 };
 
 static const struct of_device_id ext_clk_match[] __initconst = {
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index d3779eefb438..609d31a7aa52 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -3700,8 +3700,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_apolloclk_d[] __initconst
 
 static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL,
-		CLK_MOUT_BUS_PLL_APOLLO_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
-		0x0, exynos5433_apolloclk_d),
+		CLK_MOUT_BUS_PLL_APOLLO_USER, 0, 0x0,
+		CPUCLK_LAYOUT_E5433, exynos5433_apolloclk_d),
 };
 
 static const struct samsung_cmu_info apollo_cmu_info __initconst = {
@@ -3944,8 +3944,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_atlasclk_d[] __initconst =
 
 static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = {
 	CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL,
-		CLK_MOUT_BUS_PLL_ATLAS_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT,
-		0x0, exynos5433_atlasclk_d),
+		CLK_MOUT_BUS_PLL_ATLAS_USER, 0, 0x0,
+		CPUCLK_LAYOUT_E5433, exynos5433_atlasclk_d),
 };
 
 static const struct samsung_cmu_info atlas_cmu_info __initconst = {
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 516b716407e5..a763309e6f12 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -12,6 +12,7 @@
 
 #include <linux/clk-provider.h>
 #include "clk-pll.h"
+#include "clk-cpu.h"
 
 /**
  * struct samsung_clk_provider - information about clock provider
@@ -282,10 +283,11 @@ struct samsung_cpu_clock {
 	unsigned int	alt_parent_id;
 	unsigned long	flags;
 	int		offset;
+	enum exynos_cpuclk_layout reg_layout;
 	const struct exynos_cpuclk_cfg_data *cfg;
 };
 
-#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \
+#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _layout, _cfg) \
 	{							\
 		.id		  = _id,			\
 		.name		  = _name,			\
@@ -293,6 +295,7 @@ struct samsung_cpu_clock {
 		.alt_parent_id	  = _apid,			\
 		.flags		  = _flags,			\
 		.offset		  = _offset,			\
+		.reg_layout	  = _layout,			\
 		.cfg		  = _cfg,			\
 	}
 
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:47 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:47 -0600
Subject: [PATCH v3 09/15] clk: samsung: Keep CPU clock chip specific data in a dedicated struct
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-10-semen.protsenko@linaro.org>

Keep chip specific data in the data structure, don't mix it with code.
It makes it easier to add more chip specific data further. Having all
chip specific data in the table eliminates possible code bloat when
adding more rate handlers for new chips, and also makes it possible to
keep some other chip related data in that array.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - Improved the commit message: explained why it's beneficial for new
    chips to keep chip-specific data in one table

 drivers/clk/samsung/clk-cpu.c | 40 +++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 635ab8cc54a2..eb2b67d08f89 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -43,6 +43,16 @@ struct exynos_cpuclk;
 typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
 				       struct exynos_cpuclk *cpuclk);
 
+/**
+ * struct exynos_cpuclk_chip - Chip specific data for CPU clock
+ * @pre_rate_cb: callback to run before CPU clock rate change
+ * @post_rate_cb: callback to run after CPU clock rate change
+ */
+struct exynos_cpuclk_chip {
+	exynos_rate_change_fn_t	pre_rate_cb;
+	exynos_rate_change_fn_t	post_rate_cb;
+};
+
 /**
  * struct exynos_cpuclk - information about clock supplied to a CPU core
  * @hw:		handle between CCF and CPU clock
@@ -55,8 +65,7 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
  * @clk_nb:	clock notifier registered for changes in clock speed of the
  *		primary parent clock
  * @flags:	configuration flags for the CPU clock
- * @pre_rate_cb: callback to run before CPU clock rate change
- * @post_rate_cb: callback to run after CPU clock rate change
+ * @chip:	chip-specific data for the CPU clock
  *
  * This structure holds information required for programming the CPU clock for
  * various clock speeds.
@@ -70,9 +79,7 @@ struct exynos_cpuclk {
 	const unsigned long			num_cfgs;
 	struct notifier_block			clk_nb;
 	unsigned long				flags;
-
-	exynos_rate_change_fn_t			pre_rate_cb;
-	exynos_rate_change_fn_t			post_rate_cb;
+	const struct exynos_cpuclk_chip		*chip;
 };
 
 /* ---- Common code --------------------------------------------------------- */
@@ -420,13 +427,24 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
 	cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb);
 
 	if (event == PRE_RATE_CHANGE)
-		err = cpuclk->pre_rate_cb(ndata, cpuclk);
+		err = cpuclk->chip->pre_rate_cb(ndata, cpuclk);
 	else if (event == POST_RATE_CHANGE)
-		err = cpuclk->post_rate_cb(ndata, cpuclk);
+		err = cpuclk->chip->post_rate_cb(ndata, cpuclk);
 
 	return notifier_from_errno(err);
 }
 
+static const struct exynos_cpuclk_chip exynos_clkcpu_chips[] = {
+	[CPUCLK_LAYOUT_E4210] = {
+		.pre_rate_cb	= exynos_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos_cpuclk_post_rate_change,
+	},
+	[CPUCLK_LAYOUT_E5433] = {
+		.pre_rate_cb	= exynos5433_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos5433_cpuclk_post_rate_change,
+	},
+};
+
 /* helper function to register a CPU clock */
 static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 				const struct samsung_cpu_clock *clk_data)
@@ -465,13 +483,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 	cpuclk->lock = &ctx->lock;
 	cpuclk->flags = clk_data->flags;
 	cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
-	if (clk_data->reg_layout == CPUCLK_LAYOUT_E5433) {
-		cpuclk->pre_rate_cb = exynos5433_cpuclk_pre_rate_change;
-		cpuclk->post_rate_cb = exynos5433_cpuclk_post_rate_change;
-	} else {
-		cpuclk->pre_rate_cb = exynos_cpuclk_pre_rate_change;
-		cpuclk->post_rate_cb = exynos_cpuclk_post_rate_change;
-	}
+	cpuclk->chip = &exynos_clkcpu_chips[clk_data->reg_layout];
 
 	ret = clk_notifier_register(parent->clk, &cpuclk->clk_nb);
 	if (ret) {
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:48 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:48 -0600
Subject: [PATCH v3 10/15] clk: samsung: Keep register offsets in chip specific structure
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-11-semen.protsenko@linaro.org>

Abstract CPU clock registers by keeping their offsets in a dedicated
chip specific structure to accommodate for oncoming Exynos850 support,
which has different offsets for cluster 0 and cluster 1. This rework
also makes it possible to use exynos_set_safe_div() for all chips, so
exynos5433_set_safe_div() is removed here to reduce the code
duplication. The ".regs" field has to be (void *) as different Exynos
chips can have very different register layout, so this way it's possible
for ".regs" to point to different structures, each representing its own
chip's layout.

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - Changed struct exynos_cpuclk_chip.regs field type from (void *) to
    (struct exynls_cpuclk_regs *)
  - Moved struct exynos_cpuclk_regs above struct exynos_cpuclk_chip, as
    the former is used in the latter

Changes in v2:
  - Improved the commit message: explained why .regs field has to be
    (void *)
  - Changed .ctrl_base field to .base to reflect changes in previous
    commits

 drivers/clk/samsung/clk-cpu.c | 156 +++++++++++++++++++---------------
 1 file changed, 86 insertions(+), 70 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index eb2b67d08f89..e29d08a1c8b3 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -43,14 +43,34 @@ struct exynos_cpuclk;
 typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
 				       struct exynos_cpuclk *cpuclk);
 
+/**
+ * struct exynos_cpuclk_regs - Register offsets for CPU related clocks
+ * @mux_sel: offset of CPU MUX_SEL register (for selecting MUX clock parent)
+ * @mux_stat: offset of CPU MUX_STAT register (for checking MUX clock status)
+ * @div_cpu0: offset of CPU DIV0 register (for modifying divider values)
+ * @div_cpu1: offset of CPU DIV1 register (for modifying divider values)
+ * @div_stat_cpu0: offset of CPU DIV0_STAT register (for checking DIV status)
+ * @div_stat_cpu1: offset of CPU DIV1_STAT register (for checking DIV status)
+ */
+struct exynos_cpuclk_regs {
+	u32 mux_sel;
+	u32 mux_stat;
+	u32 div_cpu0;
+	u32 div_cpu1;
+	u32 div_stat_cpu0;
+	u32 div_stat_cpu1;
+};
+
 /**
  * struct exynos_cpuclk_chip - Chip specific data for CPU clock
+ * @regs: register offsets for CPU related clocks
  * @pre_rate_cb: callback to run before CPU clock rate change
  * @post_rate_cb: callback to run after CPU clock rate change
  */
 struct exynos_cpuclk_chip {
-	exynos_rate_change_fn_t	pre_rate_cb;
-	exynos_rate_change_fn_t	post_rate_cb;
+	const struct exynos_cpuclk_regs * const	regs;
+	exynos_rate_change_fn_t			pre_rate_cb;
+	exynos_rate_change_fn_t			post_rate_cb;
 };
 
 /**
@@ -130,43 +150,48 @@ static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
 }
 
-/* ---- Exynos 3/4/5 -------------------------------------------------------- */
-
-#define E4210_SRC_CPU		0x200
-#define E4210_STAT_CPU		0x400
-#define E4210_DIV_CPU0		0x500
-#define E4210_DIV_CPU1		0x504
-#define E4210_DIV_STAT_CPU0	0x600
-#define E4210_DIV_STAT_CPU1	0x604
-
-#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
-#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
-#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
-#define E4210_MUX_HPM_MASK	BIT(20)
-#define E4210_DIV0_ATB_SHIFT	16
-#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
-
 /*
  * Helper function to set the 'safe' dividers for the CPU clock. The parameters
  * div and mask contain the divider value and the register bit mask of the
  * dividers to be programmed.
  */
-static void exynos_set_safe_div(void __iomem *base, unsigned long div,
+static void exynos_set_safe_div(struct exynos_cpuclk *cpuclk, unsigned long div,
 				unsigned long mask)
 {
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
+	void __iomem *base = cpuclk->base;
 	unsigned long div0;
 
-	div0 = readl(base + E4210_DIV_CPU0);
+	div0 = readl(base + regs->div_cpu0);
 	div0 = (div0 & ~mask) | (div & mask);
-	writel(div0, base + E4210_DIV_CPU0);
-	wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, mask);
+	writel(div0, base + regs->div_cpu0);
+	wait_until_divider_stable(base + regs->div_stat_cpu0, mask);
 }
 
+/* ---- Exynos 3/4/5 -------------------------------------------------------- */
+
+#define E4210_DIV0_RATIO0_MASK	GENMASK(2, 0)
+#define E4210_DIV1_HPM_MASK	GENMASK(6, 4)
+#define E4210_DIV1_COPY_MASK	GENMASK(2, 0)
+#define E4210_MUX_HPM_MASK	BIT(20)
+#define E4210_DIV0_ATB_SHIFT	16
+#define E4210_DIV0_ATB_MASK	(DIV_MASK << E4210_DIV0_ATB_SHIFT)
+
+static const struct exynos_cpuclk_regs e4210_cpuclk_regs = {
+	.mux_sel	= 0x200,
+	.mux_stat	= 0x400,
+	.div_cpu0	= 0x500,
+	.div_cpu1	= 0x504,
+	.div_stat_cpu0	= 0x600,
+	.div_stat_cpu1	= 0x604,
+};
+
 /* handler for pre-rate change notification from parent clock */
 static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 					 struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
@@ -189,8 +214,8 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	div0 = cfg_data->div0;
 	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
 		div1 = cfg_data->div1;
-		if (readl(base + E4210_SRC_CPU) & E4210_MUX_HPM_MASK)
-			div1 = readl(base + E4210_DIV_CPU1) &
+		if (readl(base + regs->mux_sel) & E4210_MUX_HPM_MASK)
+			div1 = readl(base + regs->div_cpu1) &
 				(E4210_DIV1_HPM_MASK | E4210_DIV1_COPY_MASK);
 	}
 
@@ -217,22 +242,22 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 			alt_div |= E4210_DIV0_ATB_MASK;
 			alt_div_mask |= E4210_DIV0_ATB_MASK;
 		}
-		exynos_set_safe_div(base, alt_div, alt_div_mask);
+		exynos_set_safe_div(cpuclk, alt_div, alt_div_mask);
 		div0 |= alt_div;
 	}
 
 	/* select sclk_mpll as the alternate parent */
-	mux_reg = readl(base + E4210_SRC_CPU);
-	writel(mux_reg | (1 << 16), base + E4210_SRC_CPU);
-	wait_until_mux_stable(base + E4210_STAT_CPU, 16, 2);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg | (1 << 16), base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 16, 2);
 
 	/* alternate parent is active now. set the dividers */
-	writel(div0, base + E4210_DIV_CPU0);
-	wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, DIV_MASK_ALL);
+	writel(div0, base + regs->div_cpu0);
+	wait_until_divider_stable(base + regs->div_stat_cpu0, DIV_MASK_ALL);
 
 	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
-		writel(div1, base + E4210_DIV_CPU1);
-		wait_until_divider_stable(base + E4210_DIV_STAT_CPU1,
+		writel(div1, base + regs->div_cpu1);
+		wait_until_divider_stable(base + regs->div_stat_cpu1,
 					  DIV_MASK_ALL);
 	}
 
@@ -245,6 +270,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 					  struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
@@ -262,50 +288,37 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	spin_lock_irqsave(cpuclk->lock, flags);
 
 	/* select mout_apll as the alternate parent */
-	mux_reg = readl(base + E4210_SRC_CPU);
-	writel(mux_reg & ~(1 << 16), base + E4210_SRC_CPU);
-	wait_until_mux_stable(base + E4210_STAT_CPU, 16, 1);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg & ~(1 << 16), base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 16, 1);
 
 	if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
 		div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK);
 		div_mask |= E4210_DIV0_ATB_MASK;
 	}
 
-	exynos_set_safe_div(base, div, div_mask);
+	exynos_set_safe_div(cpuclk, div, div_mask);
 	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
 }
 
 /* ---- Exynos5433 ---------------------------------------------------------- */
 
-#define E5433_MUX_SEL2		0x208
-#define E5433_MUX_STAT2		0x408
-#define E5433_DIV_CPU0		0x600
-#define E5433_DIV_CPU1		0x604
-#define E5433_DIV_STAT_CPU0	0x700
-#define E5433_DIV_STAT_CPU1	0x704
-
-/*
- * Helper function to set the 'safe' dividers for the CPU clock. The parameters
- * div and mask contain the divider value and the register bit mask of the
- * dividers to be programmed.
- */
-static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
-				    unsigned long mask)
-{
-	unsigned long div0;
-
-	div0 = readl(base + E5433_DIV_CPU0);
-	div0 = (div0 & ~mask) | (div & mask);
-	writel(div0, base + E5433_DIV_CPU0);
-	wait_until_divider_stable(base + E5433_DIV_STAT_CPU0, mask);
-}
+static const struct exynos_cpuclk_regs e5433_cpuclk_regs = {
+	.mux_sel	= 0x208,
+	.mux_stat	= 0x408,
+	.div_cpu0	= 0x600,
+	.div_cpu1	= 0x604,
+	.div_stat_cpu0	= 0x700,
+	.div_stat_cpu1	= 0x704,
+};
 
 /* handler for pre-rate change notification from parent clock */
 static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 					     struct exynos_cpuclk *cpuclk)
 {
 	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->base;
 	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
 	unsigned long div0, div1 = 0, mux_reg;
@@ -342,21 +355,21 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 		alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
 		WARN_ON(alt_div >= MAX_DIV);
 
-		exynos5433_set_safe_div(base, alt_div, alt_div_mask);
+		exynos_set_safe_div(cpuclk, alt_div, alt_div_mask);
 		div0 |= alt_div;
 	}
 
 	/* select the alternate parent */
-	mux_reg = readl(base + E5433_MUX_SEL2);
-	writel(mux_reg | 1, base + E5433_MUX_SEL2);
-	wait_until_mux_stable(base + E5433_MUX_STAT2, 0, 2);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg | 1, base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 0, 2);
 
 	/* alternate parent is active now. set the dividers */
-	writel(div0, base + E5433_DIV_CPU0);
-	wait_until_divider_stable(base + E5433_DIV_STAT_CPU0, DIV_MASK_ALL);
+	writel(div0, base + regs->div_cpu0);
+	wait_until_divider_stable(base + regs->div_stat_cpu0, DIV_MASK_ALL);
 
-	writel(div1, base + E5433_DIV_CPU1);
-	wait_until_divider_stable(base + E5433_DIV_STAT_CPU1, DIV_MASK_ALL);
+	writel(div1, base + regs->div_cpu1);
+	wait_until_divider_stable(base + regs->div_stat_cpu1, DIV_MASK_ALL);
 
 	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
@@ -366,6 +379,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 					      struct exynos_cpuclk *cpuclk)
 {
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
 	void __iomem *base = cpuclk->base;
 	unsigned long div = 0, div_mask = DIV_MASK;
 	unsigned long mux_reg;
@@ -374,11 +388,11 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	spin_lock_irqsave(cpuclk->lock, flags);
 
 	/* select apll as the alternate parent */
-	mux_reg = readl(base + E5433_MUX_SEL2);
-	writel(mux_reg & ~1, base + E5433_MUX_SEL2);
-	wait_until_mux_stable(base + E5433_MUX_STAT2, 0, 1);
+	mux_reg = readl(base + regs->mux_sel);
+	writel(mux_reg & ~1, base + regs->mux_sel);
+	wait_until_mux_stable(base + regs->mux_stat, 0, 1);
 
-	exynos5433_set_safe_div(base, div, div_mask);
+	exynos_set_safe_div(cpuclk, div, div_mask);
 	spin_unlock_irqrestore(cpuclk->lock, flags);
 	return 0;
 }
@@ -436,10 +450,12 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
 
 static const struct exynos_cpuclk_chip exynos_clkcpu_chips[] = {
 	[CPUCLK_LAYOUT_E4210] = {
+		.regs		= &e4210_cpuclk_regs,
 		.pre_rate_cb	= exynos_cpuclk_pre_rate_change,
 		.post_rate_cb	= exynos_cpuclk_post_rate_change,
 	},
 	[CPUCLK_LAYOUT_E5433] = {
+		.regs		= &e5433_cpuclk_regs,
 		.pre_rate_cb	= exynos5433_cpuclk_pre_rate_change,
 		.post_rate_cb	= exynos5433_cpuclk_post_rate_change,
 	},
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:49 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:49 -0600
Subject: [PATCH v3 11/15] clk: samsung: Pass mask to wait_until_mux_stable()
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-12-semen.protsenko@linaro.org>

Make it possible to use wait_until_mux_stable() for MUX registers where
the mask is different from MUX_MASK (e.g. in upcoming CPU clock
implementation for Exynos850).

No functional change.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - none

 drivers/clk/samsung/clk-cpu.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index e29d08a1c8b3..0cf288138167 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -135,16 +135,16 @@ static void wait_until_divider_stable(void __iomem *div_reg, unsigned long mask)
  * value was changed.
  */
 static void wait_until_mux_stable(void __iomem *mux_reg, u32 mux_pos,
-				  unsigned long mux_value)
+				  unsigned long mask, unsigned long mux_value)
 {
 	unsigned long timeout = jiffies + msecs_to_jiffies(MAX_STAB_TIME);
 
 	do {
-		if (((readl(mux_reg) >> mux_pos) & MUX_MASK) == mux_value)
+		if (((readl(mux_reg) >> mux_pos) & mask) == mux_value)
 			return;
 	} while (time_before(jiffies, timeout));
 
-	if (((readl(mux_reg) >> mux_pos) & MUX_MASK) == mux_value)
+	if (((readl(mux_reg) >> mux_pos) & mask) == mux_value)
 		return;
 
 	pr_err("%s: re-parenting mux timed-out\n", __func__);
@@ -249,7 +249,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	/* select sclk_mpll as the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg | (1 << 16), base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 16, 2);
+	wait_until_mux_stable(base + regs->mux_stat, 16, MUX_MASK, 2);
 
 	/* alternate parent is active now. set the dividers */
 	writel(div0, base + regs->div_cpu0);
@@ -290,7 +290,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	/* select mout_apll as the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg & ~(1 << 16), base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 16, 1);
+	wait_until_mux_stable(base + regs->mux_stat, 16, MUX_MASK, 1);
 
 	if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
 		div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK);
@@ -362,7 +362,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	/* select the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg | 1, base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 0, 2);
+	wait_until_mux_stable(base + regs->mux_stat, 0, MUX_MASK, 2);
 
 	/* alternate parent is active now. set the dividers */
 	writel(div0, base + regs->div_cpu0);
@@ -390,7 +390,7 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	/* select apll as the alternate parent */
 	mux_reg = readl(base + regs->mux_sel);
 	writel(mux_reg & ~1, base + regs->mux_sel);
-	wait_until_mux_stable(base + regs->mux_stat, 0, 1);
+	wait_until_mux_stable(base + regs->mux_stat, 0, MUX_MASK, 1);
 
 	exynos_set_safe_div(cpuclk, div, div_mask);
 	spin_unlock_irqrestore(cpuclk->lock, flags);
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:50 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:50 -0600
Subject: [PATCH v3 12/15] clk: samsung: Add CPU clock support for Exynos850
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-13-semen.protsenko@linaro.org>

Implement CPU clock control for Exynos850 SoC. It follows the same
procedure which is already implemented for other SoCs in clk-cpu.c:

1. Set the correct rate for the alternate parent (if needed) before
   switching to use it as the CPU clock
2. Switch to the alternate parent, so the CPU continues to get clocked
   while the PLL is being re-configured
3. Adjust the dividers for the CPU related buses (ACLK, ATCLK, etc)
4. Re-configure the PLL for the new CPU clock rate. It's done
   automatically, as the CPU clock rate change propagates to the PLL
   clock, because the CPU clock has CLK_SET_RATE_PARENT flag set in
   exynos_register_cpu_clock()
5. Once the PLL is locked, set it back as the CPU clock source
6. Set alternate parent clock rate back to max speed

As in already existing clk-cpu.c code, the divider and mux clocks are
configured in a low-level fashion (using direct register access instead
of CCF API), to avoid affecting how DIV and MUX clock flags are declared
in the actual clock driver (clk-exynos850.c).

No functional change. This patch adds support for Exynos850 CPU clock,
but doesn't enable it per se.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - Merged struct exynos850_cpuclk_regs fields into struct
    exynos_cpuclk_regs

Changes in v2:
  - Changed .ctrl_base field to .base, to reflect changes made in
    previous commits

 drivers/clk/samsung/clk-cpu.c | 177 ++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-cpu.h |   4 +
 2 files changed, 181 insertions(+)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 0cf288138167..6ac884fccac6 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -29,6 +29,7 @@
  * down in order to keep the output clock rate within the previous OPP limits.
  */
 
+#include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/slab.h>
@@ -51,6 +52,8 @@ typedef int (*exynos_rate_change_fn_t)(struct clk_notifier_data *ndata,
  * @div_cpu1: offset of CPU DIV1 register (for modifying divider values)
  * @div_stat_cpu0: offset of CPU DIV0_STAT register (for checking DIV status)
  * @div_stat_cpu1: offset of CPU DIV1_STAT register (for checking DIV status)
+ * @mux: offset of MUX register for choosing CPU clock source
+ * @divs: offsets of DIV registers (ACLK, ATCLK, PCLKDBG and PERIPHCLK)
  */
 struct exynos_cpuclk_regs {
 	u32 mux_sel;
@@ -59,6 +62,9 @@ struct exynos_cpuclk_regs {
 	u32 div_cpu1;
 	u32 div_stat_cpu0;
 	u32 div_stat_cpu1;
+
+	u32 mux;
+	u32 divs[4];
 };
 
 /**
@@ -397,6 +403,167 @@ static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	return 0;
 }
 
+/* ---- Exynos850 ----------------------------------------------------------- */
+
+#define E850_DIV_RATIO_MASK	GENMASK(3, 0)
+#define E850_BUSY_MASK		BIT(16)
+
+/* Max time for divider or mux to stabilize, usec */
+#define E850_DIV_MUX_STAB_TIME	100
+/* OSCCLK clock rate, Hz */
+#define E850_OSCCLK		(26 * MHZ)
+
+static const struct exynos_cpuclk_regs e850cl0_cpuclk_regs = {
+	.mux	= 0x100c,
+	.divs	= { 0x1800, 0x1808, 0x180c, 0x1810 },
+};
+
+static const struct exynos_cpuclk_regs e850cl1_cpuclk_regs = {
+	.mux	= 0x1000,
+	.divs	= { 0x1800, 0x1808, 0x180c, 0x1810 },
+};
+
+/*
+ * Set alternate parent rate to "rate" value or less.
+ *
+ * rate: Desired alt_parent rate, or 0 for max alt_parent rate
+ *
+ * Exynos850 doesn't have CPU clock divider in CMU_CPUCLx block (CMUREF divider
+ * doesn't affect CPU speed). So CPUCLx_SWITCH divider from CMU_TOP is used
+ * instead to adjust alternate parent speed.
+ *
+ * It's possible to use clk_set_max_rate() instead of this function, but it
+ * would set overly pessimistic rate values to alternate parent.
+ */
+static int exynos850_alt_parent_set_max_rate(const struct clk_hw *alt_parent,
+					     unsigned long rate)
+{
+	struct clk_hw *clk_div, *clk_divp;
+	unsigned long divp_rate, div_rate, div;
+	int ret;
+
+	/* Divider from CMU_TOP */
+	clk_div = clk_hw_get_parent(alt_parent);
+	if (!clk_div)
+		return -ENOENT;
+	/* Divider's parent from CMU_TOP */
+	clk_divp = clk_hw_get_parent(clk_div);
+	if (!clk_divp)
+		return -ENOENT;
+	/* Divider input rate */
+	divp_rate = clk_hw_get_rate(clk_divp);
+	if (!divp_rate)
+		return -EINVAL;
+
+	/* Calculate new alt_parent rate for integer divider value */
+	if (rate == 0)
+		div = 1;
+	else
+		div = DIV_ROUND_UP(divp_rate, rate);
+	div_rate = DIV_ROUND_UP(divp_rate, div);
+	WARN_ON(div >= MAX_DIV);
+
+	/* alt_parent will propagate this change up to the divider */
+	ret = clk_set_rate(alt_parent->clk, div_rate);
+	if (ret)
+		return ret;
+	udelay(E850_DIV_MUX_STAB_TIME);
+
+	return 0;
+}
+
+/* Handler for pre-rate change notification from parent clock */
+static int exynos850_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
+					    struct exynos_cpuclk *cpuclk)
+{
+	const unsigned int shifts[4] = { 16, 12, 8, 4 }; /* E850_CPU_DIV0() */
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
+	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
+	const struct clk_hw *alt_parent = cpuclk->alt_parent;
+	void __iomem *base = cpuclk->base;
+	unsigned long alt_prate = clk_hw_get_rate(alt_parent);
+	unsigned long flags;
+	u32 mux_reg;
+	size_t i;
+	int ret;
+
+	/* No actions are needed when switching to or from OSCCLK parent */
+	if (ndata->new_rate == E850_OSCCLK || ndata->old_rate == E850_OSCCLK)
+		return 0;
+
+	/* Find out the divider values to use for clock data */
+	while ((cfg_data->prate * 1000) != ndata->new_rate) {
+		if (cfg_data->prate == 0)
+			return -EINVAL;
+		cfg_data++;
+	}
+
+	/*
+	 * If the old parent clock speed is less than the clock speed of
+	 * the alternate parent, then it should be ensured that at no point
+	 * the armclk speed is more than the old_prate until the dividers are
+	 * set.  Also workaround the issue of the dividers being set to lower
+	 * values before the parent clock speed is set to new lower speed
+	 * (this can result in too high speed of armclk output clocks).
+	 */
+	if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) {
+		unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate);
+
+		ret = exynos850_alt_parent_set_max_rate(alt_parent, tmp_rate);
+		if (ret)
+			return ret;
+	}
+
+	spin_lock_irqsave(cpuclk->lock, flags);
+
+	/* Select the alternate parent */
+	mux_reg = readl(base + regs->mux);
+	writel(mux_reg | 1, base + regs->mux);
+	wait_until_mux_stable(base + regs->mux, 16, 1, 0);
+
+	/* Alternate parent is active now. Set the dividers */
+	for (i = 0; i < ARRAY_SIZE(shifts); ++i) {
+		unsigned long div = (cfg_data->div0 >> shifts[i]) & 0xf;
+		u32 val;
+
+		val = readl(base + regs->divs[i]);
+		val = (val & ~E850_DIV_RATIO_MASK) | div;
+		writel(val, base + regs->divs[i]);
+		wait_until_divider_stable(base + regs->divs[i], E850_BUSY_MASK);
+	}
+
+	spin_unlock_irqrestore(cpuclk->lock, flags);
+
+	return 0;
+}
+
+/* Handler for post-rate change notification from parent clock */
+static int exynos850_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
+					     struct exynos_cpuclk *cpuclk)
+{
+	const struct exynos_cpuclk_regs * const regs = cpuclk->chip->regs;
+	const struct clk_hw *alt_parent = cpuclk->alt_parent;
+	void __iomem *base = cpuclk->base;
+	unsigned long flags;
+	u32 mux_reg;
+
+	/* No actions are needed when switching to or from OSCCLK parent */
+	if (ndata->new_rate == E850_OSCCLK || ndata->old_rate == E850_OSCCLK)
+		return 0;
+
+	spin_lock_irqsave(cpuclk->lock, flags);
+
+	/* Select main parent (PLL) for mux */
+	mux_reg = readl(base + regs->mux);
+	writel(mux_reg & ~1, base + regs->mux);
+	wait_until_mux_stable(base + regs->mux, 16, 1, 0);
+
+	spin_unlock_irqrestore(cpuclk->lock, flags);
+
+	/* Set alt_parent rate back to max */
+	return exynos850_alt_parent_set_max_rate(alt_parent, 0);
+}
+
 /* -------------------------------------------------------------------------- */
 
 /* Common round rate callback usable for all types of CPU clocks */
@@ -459,6 +626,16 @@ static const struct exynos_cpuclk_chip exynos_clkcpu_chips[] = {
 		.pre_rate_cb	= exynos5433_cpuclk_pre_rate_change,
 		.post_rate_cb	= exynos5433_cpuclk_post_rate_change,
 	},
+	[CPUCLK_LAYOUT_E850_CL0] = {
+		.regs		= &e850cl0_cpuclk_regs,
+		.pre_rate_cb	= exynos850_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos850_cpuclk_post_rate_change,
+	},
+	[CPUCLK_LAYOUT_E850_CL1] = {
+		.regs		= &e850cl1_cpuclk_regs,
+		.pre_rate_cb	= exynos850_cpuclk_pre_rate_change,
+		.post_rate_cb	= exynos850_cpuclk_post_rate_change,
+	},
 };
 
 /* helper function to register a CPU clock */
diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h
index 4382ab005ad3..892843611b0a 100644
--- a/drivers/clk/samsung/clk-cpu.h
+++ b/drivers/clk/samsung/clk-cpu.h
@@ -17,10 +17,14 @@
  * enum exynos_cpuclk_layout - CPU clock registers layout compatibility
  * @CPUCLK_LAYOUT_E4210: Exynos4210 compatible layout
  * @CPUCLK_LAYOUT_E5433: Exynos5433 compatible layout
+ * @CPUCLK_LAYOUT_E850_CL0: Exynos850 cluster 0 compatible layout
+ * @CPUCLK_LAYOUT_E850_CL1: Exynos850 cluster 1 compatible layout
  */
 enum exynos_cpuclk_layout {
 	CPUCLK_LAYOUT_E4210,
 	CPUCLK_LAYOUT_E5433,
+	CPUCLK_LAYOUT_E850_CL0,
+	CPUCLK_LAYOUT_E850_CL1,
 };
 
 /**
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:51 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:51 -0600
Subject: [PATCH v3 13/15] clk: samsung: Implement manual PLL control for ARM64 SoCs
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-14-semen.protsenko@linaro.org>

Some ARM64 Exynos chips are capable to control PLL clocks automatically.
For those chips, whether the PLL is controlled automatically or manually
is chosen in PLL_CON1 register with next bits:

    [28]  ENABLE_AUTOMATIC_CLKGATING
    [1]   MANUAL_PLL_CTRL
    [0]   AUTO_PLL_CTRL

The bl2 bootloader sets 0x10000001 value for some PLL_CON1 registers,
which means any attempt to control those PLLs manually (e.g.
disabling/enabling those PLLs or changing MUX parent clocks) would lead
to PLL lock timeout with error message like this:

    Could not lock PLL ...

At the moment, all Samsung clock drivers implement manual clock control.
So in order to make it possible to control PLLs, corresponding PLL_CON1
registers should be set to 0x2 first.

Some older ARM64 chips don't implement the automatic clock control
though. It also might be desirable to configure some PLLs for manual
control, while keeping the default configuration for the rest. So it'd
convenient to choose this PLL mode for each CMU separately. Introduce
.manual_plls field to CMU structure to choose the PLL control mode.
Because it'll be initialized with "false" in all existing CMU
structures by default, it won't affect any existing clock drivers,
allowing for this feature to be enabled gradually when it's needed with
no change for the rest of users. In case .manual_plls is set, set
PLL_CON1 registers to manual control, akin to what's already done for
gate clocks in exynos_arm64_init_clocks(). Of course, PLL_CON1 registers
should be added to corresponding struct samsung_cmu_info::clk_regs array
to make sure they get initialized.

No functional change. This patch adds a feature, but doesn't enable it
for any users.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - none

 drivers/clk/samsung/clk-exynos-arm64.c | 44 +++++++++++++++++---------
 drivers/clk/samsung/clk.h              |  4 +++
 2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos-arm64.c b/drivers/clk/samsung/clk-exynos-arm64.c
index 6fb7194df7ab..55490209b9a9 100644
--- a/drivers/clk/samsung/clk-exynos-arm64.c
+++ b/drivers/clk/samsung/clk-exynos-arm64.c
@@ -25,6 +25,19 @@
 #define GATE_OFF_START		0x2000
 #define GATE_OFF_END		0x2fff
 
+/* PLL CON register offsets range */
+#define PLL_CON_START		0x100
+#define PLL_CON_END		0x600
+
+/* PLL register bits */
+#define PLL_CON1_MANUAL		BIT(1)
+
+/* Helper macros to check for particular clock regiter by its offset */
+#define IS_GATE_REG(o)		((o) >= GATE_OFF_START && (o) <= GATE_OFF_END)
+#define IS_PLL_CONx_REG(o)	((o) >= PLL_CON_START && (o) <= PLL_CON_END)
+#define IS_PLL_CON1_REG(o)	\
+	(IS_PLL_CONx_REG(o) && ((o) & 0xf) == 0x4 && !((o) & 0x10))
+
 struct exynos_arm64_cmu_data {
 	struct samsung_clk_reg_dump *clk_save;
 	unsigned int nr_clk_save;
@@ -40,15 +53,16 @@ struct exynos_arm64_cmu_data {
 
 /**
  * exynos_arm64_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
+ * @np:		CMU device tree node with "reg" property (CMU addr)
+ * @cmu:	CMU data
  *
- * Set manual control mode for all gate clocks.
+ * Set manual control mode for all gate and PLL clocks.
  */
 static void __init exynos_arm64_init_clocks(struct device_node *np,
-		const unsigned long *reg_offs, size_t reg_offs_len)
+					    const struct samsung_cmu_info *cmu)
 {
+	const unsigned long *reg_offs = cmu->clk_regs;
+	size_t reg_offs_len = cmu->nr_clk_regs;
 	void __iomem *reg_base;
 	size_t i;
 
@@ -60,14 +74,14 @@ static void __init exynos_arm64_init_clocks(struct device_node *np,
 		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);
+		if (cmu->manual_plls && IS_PLL_CON1_REG(reg_offs[i])) {
+			writel(PLL_CON1_MANUAL, reg);
+		} else if (IS_GATE_REG(reg_offs[i])) {
+			val = readl(reg);
+			val |= GATE_MANUAL;
+			val &= ~GATE_ENABLE_HWACG;
+			writel(val, reg);
+		}
 	}
 
 	iounmap(reg_base);
@@ -177,7 +191,7 @@ void __init exynos_arm64_register_cmu(struct device *dev,
 		pr_err("%s: could not enable bus clock %s; err = %d\n",
 		       __func__, cmu->clk_name, err);
 
-	exynos_arm64_init_clocks(np, cmu->clk_regs, cmu->nr_clk_regs);
+	exynos_arm64_init_clocks(np, cmu);
 	samsung_cmu_register_one(np, cmu);
 }
 
@@ -224,7 +238,7 @@ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev,
 		       __func__, cmu->clk_name, ret);
 
 	if (set_manual)
-		exynos_arm64_init_clocks(np, cmu->clk_regs, cmu->nr_clk_regs);
+		exynos_arm64_init_clocks(np, cmu);
 
 	reg_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(reg_base))
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index a763309e6f12..a70bd7cce39f 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -330,6 +330,7 @@ struct samsung_clock_reg_cache {
  * @suspend_regs: list of clock registers to set before suspend
  * @nr_suspend_regs: count of clock registers in @suspend_regs
  * @clk_name: name of the parent clock needed for CMU register access
+ * @manual_plls: Enable manual control for PLL clocks
  */
 struct samsung_cmu_info {
 	const struct samsung_pll_clock *pll_clks;
@@ -354,6 +355,9 @@ struct samsung_cmu_info {
 	const struct samsung_clk_reg_dump *suspend_regs;
 	unsigned int nr_suspend_regs;
 	const char *clk_name;
+
+	/* ARM64 Exynos CMUs */
+	bool manual_plls;
 };
 
 struct samsung_clk_provider *samsung_clk_init(struct device *dev,
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:53 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:53 -0600
Subject: [PATCH v3 15/15] arm64: dts: exynos: Add CPU clocks for Exynos850
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-16-semen.protsenko@linaro.org>

Define CPU cluster 0 and CPU cluster 1 CMUs, which generate CPU clocks,
and add corresponding CPU clocks to CPU nodes.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - Added "for Exynos850" part to the commit title

 arch/arm64/boot/dts/exynos/exynos850.dtsi | 26 +++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
index 2ba67c3d0681..0706c8534ceb 100644
--- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -93,6 +93,8 @@ cpu0: cpu at 0 {
 			compatible = "arm,cortex-a55";
 			reg = <0x0>;
 			enable-method = "psci";
+			clocks = <&cmu_cpucl0 CLK_CLUSTER0_SCLK>;
+			clock-names = "cluster0_clk";
 		};
 		cpu1: cpu at 1 {
 			device_type = "cpu";
@@ -117,6 +119,8 @@ cpu4: cpu at 100 {
 			compatible = "arm,cortex-a55";
 			reg = <0x100>;
 			enable-method = "psci";
+			clocks = <&cmu_cpucl1 CLK_CLUSTER1_SCLK>;
+			clock-names = "cluster1_clk";
 		};
 		cpu5: cpu at 101 {
 			device_type = "cpu";
@@ -254,6 +258,28 @@ cmu_peri: clock-controller at 10030000 {
 				      "dout_peri_uart", "dout_peri_ip";
 		};
 
+		cmu_cpucl1: clock-controller at 10800000 {
+			compatible = "samsung,exynos850-cmu-cpucl1";
+			reg = <0x10800000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_CPUCL1_SWITCH>,
+				 <&cmu_top CLK_DOUT_CPUCL1_DBG>;
+			clock-names = "oscclk", "dout_cpucl1_switch",
+				      "dout_cpucl1_dbg";
+		};
+
+		cmu_cpucl0: clock-controller at 10900000 {
+			compatible = "samsung,exynos850-cmu-cpucl0";
+			reg = <0x10900000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_CPUCL0_SWITCH>,
+				 <&cmu_top CLK_DOUT_CPUCL0_DBG>;
+			clock-names = "oscclk", "dout_cpucl0_switch",
+				      "dout_cpucl0_dbg";
+		};
+
 		cmu_g3d: clock-controller at 11400000 {
 			compatible = "samsung,exynos850-cmu-g3d";
 			reg = <0x11400000 0x8000>;
-- 
2.39.2



From semen.protsenko at linaro.org  Sat Feb 24 12:20:52 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 14:20:52 -0600
Subject: [PATCH v3 14/15] clk: samsung: exynos850: Add CMU_CPUCL0 and CMU_CPUCL1
In-Reply-To: <20240224202053.25313-1-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
Message-ID: <20240224202053.25313-15-semen.protsenko@linaro.org>

Implement support for CPU clock management units:
  - CMU_CPUCL0: clocks for cluster 0: 4 x Cortex-A55 (cpu0..cpu3)
  - CMU_CPUCL1: clocks for cluster 1: 4 x Cortex-A55 (cpu4..cpu7)

CPU PLLs are generating main CPU clocks for each cluster, and there are
alternate ("switch") clocks that can be used temporarily while
re-configuring the PLL for a new rate. ACLK, ATCLK, PCLKDBG and
PERIPHCLK clocks are driving corresponding buses. CLK_CLUSTERx_SCLK are
actual leaf CPU clocks and should be used to change CPU rates. Also some
CoreSight clocks can be derived from DBG_USER (debug clock).

PLL table was extracted from ECT table. ECT stands for "Exynos
Characteristic Table", it's a Samsung specific binary data populated by
BL2 bootloader in RAM at 0x90000000 address, containing PLL tables for
various CMUs and other hardware specific information.

The particular PLL type used in CMU_CPUCL0 and CMU_CPUCL1 (pll0822x) is
an integer PLL with middle FVCO. The equation to calculate its output
rate is:

    fout = fin * M / (P*2^S)

where:

    fin = 26 MHz (OSCCLK frequency)
    M = 64..1023
    P = 1..63
    S = 0..6

The PLL table tries to keep "P" value low to reduce the locking time,
which for pll0822x is "t = P * 150" (in OSCCLK cycles).

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - none

Changes in v2:
  - none

 drivers/clk/samsung/clk-exynos850.c | 440 +++++++++++++++++++++++++++-
 1 file changed, 439 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c
index 82cfa22c0788..6215471c4ac6 100644
--- a/drivers/clk/samsung/clk-exynos850.c
+++ b/drivers/clk/samsung/clk-exynos850.c
@@ -14,13 +14,16 @@
 #include <dt-bindings/clock/exynos850.h>
 
 #include "clk.h"
+#include "clk-cpu.h"
 #include "clk-exynos-arm64.h"
 
 /* NOTE: Must be equal to the last clock ID increased by one */
-#define CLKS_NR_TOP			(CLK_DOUT_G3D_SWITCH + 1)
+#define CLKS_NR_TOP			(CLK_DOUT_CPUCL1_SWITCH + 1)
 #define CLKS_NR_APM			(CLK_GOUT_SYSREG_APM_PCLK + 1)
 #define CLKS_NR_AUD			(CLK_GOUT_AUD_CMU_AUD_PCLK + 1)
 #define CLKS_NR_CMGP			(CLK_GOUT_SYSREG_CMGP_PCLK + 1)
+#define CLKS_NR_CPUCL0			(CLK_CLUSTER0_SCLK + 1)
+#define CLKS_NR_CPUCL1			(CLK_CLUSTER1_SCLK + 1)
 #define CLKS_NR_G3D			(CLK_GOUT_G3D_SYSREG_PCLK + 1)
 #define CLKS_NR_HSI			(CLK_GOUT_HSI_CMU_HSI_PCLK + 1)
 #define CLKS_NR_IS			(CLK_GOUT_IS_SYSREG_PCLK + 1)
@@ -47,6 +50,10 @@
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI		0x1018
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD	0x101c
 #define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS		0x1020
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG	0x1024
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH	0x1028
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL1_DBG	0x102c
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH	0x1030
 #define CLK_CON_MUX_MUX_CLKCMU_DPU		0x1034
 #define CLK_CON_MUX_MUX_CLKCMU_G3D_SWITCH	0x1038
 #define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS		0x103c
@@ -69,6 +76,10 @@
 #define CLK_CON_DIV_CLKCMU_CORE_CCI		0x1824
 #define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD	0x1828
 #define CLK_CON_DIV_CLKCMU_CORE_SSS		0x182c
+#define CLK_CON_DIV_CLKCMU_CPUCL0_DBG		0x1830
+#define CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH	0x1834
+#define CLK_CON_DIV_CLKCMU_CPUCL1_DBG		0x1838
+#define CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH	0x183c
 #define CLK_CON_DIV_CLKCMU_DPU			0x1840
 #define CLK_CON_DIV_CLKCMU_G3D_SWITCH		0x1844
 #define CLK_CON_DIV_CLKCMU_HSI_BUS		0x1848
@@ -97,6 +108,10 @@
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI	0x2020
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD	0x2024
 #define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS	0x2028
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG	0x202c
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH	0x2030
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL1_DBG	0x2034
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH	0x2038
 #define CLK_CON_GAT_GATE_CLKCMU_DPU		0x203c
 #define CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH	0x2040
 #define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS		0x2044
@@ -130,6 +145,10 @@ static const unsigned long top_clk_regs[] __initconst = {
 	CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
 	CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD,
 	CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL1_DBG,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH,
 	CLK_CON_MUX_MUX_CLKCMU_DPU,
 	CLK_CON_MUX_MUX_CLKCMU_G3D_SWITCH,
 	CLK_CON_MUX_MUX_CLKCMU_HSI_BUS,
@@ -152,6 +171,10 @@ static const unsigned long top_clk_regs[] __initconst = {
 	CLK_CON_DIV_CLKCMU_CORE_CCI,
 	CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD,
 	CLK_CON_DIV_CLKCMU_CORE_SSS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_DBG,
+	CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_DIV_CLKCMU_CPUCL1_DBG,
+	CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH,
 	CLK_CON_DIV_CLKCMU_DPU,
 	CLK_CON_DIV_CLKCMU_G3D_SWITCH,
 	CLK_CON_DIV_CLKCMU_HSI_BUS,
@@ -180,6 +203,10 @@ static const unsigned long top_clk_regs[] __initconst = {
 	CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
 	CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD,
 	CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL1_DBG,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH,
 	CLK_CON_GAT_GATE_CLKCMU_DPU,
 	CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
 	CLK_CON_GAT_GATE_CLKCMU_HSI_BUS,
@@ -234,6 +261,14 @@ PNAME(mout_core_mmc_embd_p)	= { "oscclk", "dout_shared0_div2",
 				    "oscclk", "oscclk" };
 PNAME(mout_core_sss_p)		= { "dout_shared0_div3", "dout_shared1_div3",
 				    "dout_shared0_div4", "dout_shared1_div4" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_CPUCL0 */
+PNAME(mout_cpucl0_switch_p)	= { "fout_shared0_pll", "fout_shared1_pll",
+				    "dout_shared0_div2", "dout_shared1_div2" };
+PNAME(mout_cpucl0_dbg_p)	= { "dout_shared0_div4", "dout_shared1_div4" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_CPUCL1 */
+PNAME(mout_cpucl1_switch_p)	= { "fout_shared0_pll", "fout_shared1_pll",
+				    "dout_shared0_div2", "dout_shared1_div2" };
+PNAME(mout_cpucl1_dbg_p)	= { "dout_shared0_div4", "dout_shared1_div4" };
 /* List of parent clocks for Muxes in CMU_TOP: for CMU_G3D */
 PNAME(mout_g3d_switch_p)	= { "dout_shared0_div2", "dout_shared1_div2",
 				    "dout_shared0_div3", "dout_shared1_div3" };
@@ -300,6 +335,18 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = {
 	MUX(CLK_MOUT_CORE_SSS, "mout_core_sss", mout_core_sss_p,
 	    CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 0, 2),
 
+	/* CPUCL0 */
+	MUX(CLK_MOUT_CPUCL0_DBG, "mout_cpucl0_dbg", mout_cpucl0_dbg_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG, 0, 1),
+	MUX(CLK_MOUT_CPUCL0_SWITCH, "mout_cpucl0_switch", mout_cpucl0_switch_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_SWITCH, 0, 2),
+
+	/* CPUCL1 */
+	MUX(CLK_MOUT_CPUCL1_DBG, "mout_cpucl1_dbg", mout_cpucl1_dbg_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL1_DBG, 0, 1),
+	MUX(CLK_MOUT_CPUCL1_SWITCH, "mout_cpucl1_switch", mout_cpucl1_switch_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL1_SWITCH, 0, 2),
+
 	/* DPU */
 	MUX(CLK_MOUT_DPU, "mout_dpu", mout_dpu_p,
 	    CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 2),
@@ -378,6 +425,18 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
 	DIV(CLK_DOUT_CORE_SSS, "dout_core_sss", "gout_core_sss",
 	    CLK_CON_DIV_CLKCMU_CORE_SSS, 0, 4),
 
+	/* CPUCL0 */
+	DIV(CLK_DOUT_CPUCL0_DBG, "dout_cpucl0_dbg", "gout_cpucl0_dbg",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_DBG, 0, 3),
+	DIV(CLK_DOUT_CPUCL0_SWITCH, "dout_cpucl0_switch", "gout_cpucl0_switch",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH, 0, 3),
+
+	/* CPUCL1 */
+	DIV(CLK_DOUT_CPUCL1_DBG, "dout_cpucl1_dbg", "gout_cpucl1_dbg",
+	    CLK_CON_DIV_CLKCMU_CPUCL1_DBG, 0, 3),
+	DIV(CLK_DOUT_CPUCL1_SWITCH, "dout_cpucl1_switch", "gout_cpucl1_switch",
+	    CLK_CON_DIV_CLKCMU_CPUCL1_SWITCH, 0, 3),
+
 	/* DPU */
 	DIV(CLK_DOUT_DPU, "dout_dpu", "gout_dpu",
 	    CLK_CON_DIV_CLKCMU_DPU, 0, 4),
@@ -442,6 +501,18 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
 	GATE(CLK_GOUT_AUD, "gout_aud", "mout_aud",
 	     CLK_CON_GAT_GATE_CLKCMU_AUD, 21, 0, 0),
 
+	/* CPUCL0 */
+	GATE(CLK_GOUT_CPUCL0_DBG, "gout_cpucl0_dbg", "mout_cpucl0_dbg",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG, 21, 0, 0),
+	GATE(CLK_GOUT_CPUCL0_SWITCH, "gout_cpucl0_switch", "mout_cpucl0_switch",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_SWITCH, 21, 0, 0),
+
+	/* CPUCL1 */
+	GATE(CLK_GOUT_CPUCL1_DBG, "gout_cpucl1_dbg", "mout_cpucl1_dbg",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL1_DBG, 21, 0, 0),
+	GATE(CLK_GOUT_CPUCL1_SWITCH, "gout_cpucl1_switch", "mout_cpucl1_switch",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL1_SWITCH, 21, 0, 0),
+
 	/* DPU */
 	GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu",
 	     CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
@@ -1030,6 +1101,373 @@ static const struct samsung_cmu_info cmgp_cmu_info __initconst = {
 	.clk_name		= "gout_clkcmu_cmgp_bus",
 };
 
+/* ---- CMU_CPUCL0 ---------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_CPUCL0 (0x10900000) */
+#define PLL_LOCKTIME_PLL_CPUCL0				0x0000
+#define PLL_CON0_PLL_CPUCL0				0x0100
+#define PLL_CON1_PLL_CPUCL0				0x0104
+#define PLL_CON3_PLL_CPUCL0				0x010c
+#define PLL_CON0_MUX_CLKCMU_CPUCL0_DBG_USER		0x0600
+#define PLL_CON0_MUX_CLKCMU_CPUCL0_SWITCH_USER		0x0610
+#define CLK_CON_MUX_MUX_CLK_CPUCL0_PLL			0x100c
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_ACLK		0x1800
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_ATCLK		0x1808
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_PCLKDBG		0x180c
+#define CLK_CON_DIV_DIV_CLK_CLUSTER0_PERIPHCLK		0x1810
+#define CLK_CON_DIV_DIV_CLK_CPUCL0_CMUREF		0x1814
+#define CLK_CON_DIV_DIV_CLK_CPUCL0_CPU			0x1818
+#define CLK_CON_DIV_DIV_CLK_CPUCL0_PCLK			0x181c
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_ATCLK		0x2000
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PCLK		0x2004
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PERIPHCLK	0x2008
+#define CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_SCLK		0x200c
+#define CLK_CON_GAT_CLK_CPUCL0_CMU_CPUCL0_PCLK		0x2010
+#define CLK_CON_GAT_GATE_CLK_CPUCL0_CPU			0x2020
+
+static const unsigned long cpucl0_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CPUCL0,
+	PLL_CON0_PLL_CPUCL0,
+	PLL_CON1_PLL_CPUCL0,
+	PLL_CON3_PLL_CPUCL0,
+	PLL_CON0_MUX_CLKCMU_CPUCL0_DBG_USER,
+	PLL_CON0_MUX_CLKCMU_CPUCL0_SWITCH_USER,
+	CLK_CON_MUX_MUX_CLK_CPUCL0_PLL,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_ACLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_ATCLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_PCLKDBG,
+	CLK_CON_DIV_DIV_CLK_CLUSTER0_PERIPHCLK,
+	CLK_CON_DIV_DIV_CLK_CPUCL0_CMUREF,
+	CLK_CON_DIV_DIV_CLK_CPUCL0_CPU,
+	CLK_CON_DIV_DIV_CLK_CPUCL0_PCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_ATCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PERIPHCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_SCLK,
+	CLK_CON_GAT_CLK_CPUCL0_CMU_CPUCL0_PCLK,
+	CLK_CON_GAT_GATE_CLK_CPUCL0_CPU,
+};
+
+/* List of parent clocks for Muxes in CMU_CPUCL0 */
+PNAME(mout_pll_cpucl0_p)		 = { "oscclk", "fout_cpucl0_pll" };
+PNAME(mout_cpucl0_switch_user_p)	 = { "oscclk", "dout_cpucl0_switch" };
+PNAME(mout_cpucl0_dbg_user_p)		 = { "oscclk", "dout_cpucl0_dbg" };
+PNAME(mout_cpucl0_pll_p)		 = { "mout_pll_cpucl0",
+					     "mout_cpucl0_switch_user" };
+
+static const struct samsung_pll_rate_table cpu_pll_rates[] __initconst = {
+	PLL_35XX_RATE(26 * MHZ, 2210000000U, 255, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 2106000000U, 243, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 2002000000U, 231, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1846000000U, 213, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1742000000U, 201, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1586000000U, 183, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1456000000U, 168, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1300000000U, 150, 3, 0),
+	PLL_35XX_RATE(26 * MHZ, 1157000000U, 267, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 1053000000U, 243, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 949000000U,  219, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 806000000U,  186, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 650000000U,  150, 3, 1),
+	PLL_35XX_RATE(26 * MHZ, 546000000U,  252, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 442000000U,  204, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 351000000U,  162, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 247000000U,  114, 3, 2),
+	PLL_35XX_RATE(26 * MHZ, 182000000U,  168, 3, 3),
+	PLL_35XX_RATE(26 * MHZ, 130000000U,  120, 3, 3),
+};
+
+static const struct samsung_pll_clock cpucl0_pll_clks[] __initconst = {
+	PLL(pll_0822x, CLK_FOUT_CPUCL0_PLL, "fout_cpucl0_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_CPUCL0, PLL_CON3_PLL_CPUCL0, cpu_pll_rates),
+};
+
+static const struct samsung_mux_clock cpucl0_mux_clks[] __initconst = {
+	MUX_F(CLK_MOUT_PLL_CPUCL0, "mout_pll_cpucl0", mout_pll_cpucl0_p,
+	      PLL_CON0_PLL_CPUCL0, 4, 1,
+	      CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0),
+	MUX_F(CLK_MOUT_CPUCL0_SWITCH_USER, "mout_cpucl0_switch_user",
+	      mout_cpucl0_switch_user_p,
+	      PLL_CON0_MUX_CLKCMU_CPUCL0_SWITCH_USER, 4, 1,
+	      CLK_SET_RATE_PARENT, 0),
+	MUX(CLK_MOUT_CPUCL0_DBG_USER, "mout_cpucl0_dbg_user",
+	    mout_cpucl0_dbg_user_p,
+	    PLL_CON0_MUX_CLKCMU_CPUCL0_DBG_USER, 4, 1),
+	MUX_F(CLK_MOUT_CPUCL0_PLL, "mout_cpucl0_pll", mout_cpucl0_pll_p,
+	      CLK_CON_MUX_MUX_CLK_CPUCL0_PLL, 0, 1, CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_div_clock cpucl0_div_clks[] __initconst = {
+	DIV_F(CLK_DOUT_CPUCL0_CPU, "dout_cpucl0_cpu", "mout_cpucl0_pll",
+	      CLK_CON_DIV_DIV_CLK_CPUCL0_CPU, 0, 1,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL0_CMUREF, "dout_cpucl0_cmuref", "dout_cpucl0_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL0_CMUREF, 0, 3,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL0_PCLK, "dout_cpucl0_pclk", "dout_cpucl0_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL0_PCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+
+	/* EMBEDDED_CMU_CPUCL0 */
+	DIV_F(CLK_DOUT_CLUSTER0_ACLK, "dout_cluster0_aclk", "gout_cluster0_cpu",
+	      CLK_CON_DIV_DIV_CLK_CLUSTER0_ACLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER0_ATCLK, "dout_cluster0_atclk",
+	      "gout_cluster0_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER0_ATCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER0_PCLKDBG, "dout_cluster0_pclkdbg",
+	      "gout_cluster0_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER0_PCLKDBG, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER0_PERIPHCLK, "dout_cluster0_periphclk",
+	      "gout_cluster0_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER0_PERIPHCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+};
+
+static const struct samsung_gate_clock cpucl0_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_CPUCL0_CMU_CPUCL0_PCLK, "gout_cpucl0_cmu_cpucl0_pclk",
+	     "dout_cpucl0_pclk",
+	     CLK_CON_GAT_CLK_CPUCL0_CMU_CPUCL0_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+
+	/* EMBEDDED_CMU_CPUCL0 */
+	GATE(CLK_GOUT_CLUSTER0_CPU, "gout_cluster0_cpu", "dout_cpucl0_cpu",
+	     CLK_CON_GAT_GATE_CLK_CPUCL0_CPU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_SCLK, "gout_cluster0_sclk", "gout_cluster0_cpu",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_SCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_ATCLK, "gout_cluster0_atclk",
+	     "dout_cluster0_atclk",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_ATCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_PERIPHCLK, "gout_cluster0_periphclk",
+	     "dout_cluster0_periphclk",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PERIPHCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER0_PCLK, "gout_cluster0_pclk",
+	     "dout_cluster0_pclkdbg",
+	     CLK_CON_GAT_CLK_CPUCL0_CLUSTER0_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+/*
+ * Each parameter is going to be written into the corresponding DIV register. So
+ * the actual divider value for each parameter will be 1/(param+1). All these
+ * parameters must be in the range of 0..15, as the divider range for all of
+ * these DIV clocks is 1..16. The default values for these dividers is
+ * (1, 3, 3, 1).
+ */
+#define E850_CPU_DIV0(aclk, atclk, pclkdbg, periphclk) \
+	(((aclk) << 16) | ((atclk) << 12) | ((pclkdbg) << 8) | \
+	 ((periphclk) << 4))
+
+static const struct exynos_cpuclk_cfg_data exynos850_cluster_clk_d[] __initconst
+= {
+	{ 2210000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 2106000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 2002000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1846000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1742000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1586000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1456000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1300000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1157000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 1053000, E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 949000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 806000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 650000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 546000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 442000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 351000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 247000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 182000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 130000,  E850_CPU_DIV0(1, 3, 3, 1) },
+	{ 0 }
+};
+
+static const struct samsung_cpu_clock cpucl0_cpu_clks[] __initconst = {
+	CPU_CLK(CLK_CLUSTER0_SCLK, "cluster0_clk", CLK_MOUT_PLL_CPUCL0,
+		CLK_MOUT_CPUCL0_SWITCH_USER, 0, 0x0, CPUCLK_LAYOUT_E850_CL0,
+		exynos850_cluster_clk_d),
+};
+
+static const struct samsung_cmu_info cpucl0_cmu_info __initconst = {
+	.pll_clks		= cpucl0_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cpucl0_pll_clks),
+	.mux_clks		= cpucl0_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cpucl0_mux_clks),
+	.div_clks		= cpucl0_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cpucl0_div_clks),
+	.gate_clks		= cpucl0_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cpucl0_gate_clks),
+	.cpu_clks		= cpucl0_cpu_clks,
+	.nr_cpu_clks		= ARRAY_SIZE(cpucl0_cpu_clks),
+	.nr_clk_ids		= CLKS_NR_CPUCL0,
+	.clk_regs		= cpucl0_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cpucl0_clk_regs),
+	.clk_name		= "dout_cpucl0_switch",
+	.manual_plls		= true,
+};
+
+static void __init exynos850_cmu_cpucl0_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &cpucl0_cmu_info);
+}
+
+/* Register CMU_CPUCL0 early, as CPU clocks should be available ASAP */
+CLK_OF_DECLARE(exynos850_cmu_cpucl0, "samsung,exynos850-cmu-cpucl0",
+	       exynos850_cmu_cpucl0_init);
+
+/* ---- CMU_CPUCL1 ---------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_CPUCL1 (0x10800000) */
+#define PLL_LOCKTIME_PLL_CPUCL1				0x0000
+#define PLL_CON0_PLL_CPUCL1				0x0100
+#define PLL_CON1_PLL_CPUCL1				0x0104
+#define PLL_CON3_PLL_CPUCL1				0x010c
+#define PLL_CON0_MUX_CLKCMU_CPUCL1_DBG_USER		0x0600
+#define PLL_CON0_MUX_CLKCMU_CPUCL1_SWITCH_USER		0x0610
+#define CLK_CON_MUX_MUX_CLK_CPUCL1_PLL			0x1000
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_ACLK		0x1800
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_ATCLK		0x1808
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_PCLKDBG		0x180c
+#define CLK_CON_DIV_DIV_CLK_CLUSTER1_PERIPHCLK		0x1810
+#define CLK_CON_DIV_DIV_CLK_CPUCL1_CMUREF		0x1814
+#define CLK_CON_DIV_DIV_CLK_CPUCL1_CPU			0x1818
+#define CLK_CON_DIV_DIV_CLK_CPUCL1_PCLK			0x181c
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_ATCLK		0x2000
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PCLK		0x2004
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PERIPHCLK	0x2008
+#define CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_SCLK		0x200c
+#define CLK_CON_GAT_CLK_CPUCL1_CMU_CPUCL1_PCLK		0x2010
+#define CLK_CON_GAT_GATE_CLK_CPUCL1_CPU			0x2020
+
+static const unsigned long cpucl1_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CPUCL1,
+	PLL_CON0_PLL_CPUCL1,
+	PLL_CON1_PLL_CPUCL1,
+	PLL_CON3_PLL_CPUCL1,
+	PLL_CON0_MUX_CLKCMU_CPUCL1_DBG_USER,
+	PLL_CON0_MUX_CLKCMU_CPUCL1_SWITCH_USER,
+	CLK_CON_MUX_MUX_CLK_CPUCL1_PLL,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_ACLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_ATCLK,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_PCLKDBG,
+	CLK_CON_DIV_DIV_CLK_CLUSTER1_PERIPHCLK,
+	CLK_CON_DIV_DIV_CLK_CPUCL1_CMUREF,
+	CLK_CON_DIV_DIV_CLK_CPUCL1_CPU,
+	CLK_CON_DIV_DIV_CLK_CPUCL1_PCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_ATCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PERIPHCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_SCLK,
+	CLK_CON_GAT_CLK_CPUCL1_CMU_CPUCL1_PCLK,
+	CLK_CON_GAT_GATE_CLK_CPUCL1_CPU,
+};
+
+/* List of parent clocks for Muxes in CMU_CPUCL0 */
+PNAME(mout_pll_cpucl1_p)		 = { "oscclk", "fout_cpucl1_pll" };
+PNAME(mout_cpucl1_switch_user_p)	 = { "oscclk", "dout_cpucl1_switch" };
+PNAME(mout_cpucl1_dbg_user_p)		 = { "oscclk", "dout_cpucl1_dbg" };
+PNAME(mout_cpucl1_pll_p)		 = { "mout_pll_cpucl1",
+					     "mout_cpucl1_switch_user" };
+
+static const struct samsung_pll_clock cpucl1_pll_clks[] __initconst = {
+	PLL(pll_0822x, CLK_FOUT_CPUCL1_PLL, "fout_cpucl1_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_CPUCL1, PLL_CON3_PLL_CPUCL1, cpu_pll_rates),
+};
+
+static const struct samsung_mux_clock cpucl1_mux_clks[] __initconst = {
+	MUX_F(CLK_MOUT_PLL_CPUCL1, "mout_pll_cpucl1", mout_pll_cpucl1_p,
+	      PLL_CON0_PLL_CPUCL1, 4, 1,
+	      CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0),
+	MUX_F(CLK_MOUT_CPUCL1_SWITCH_USER, "mout_cpucl1_switch_user",
+	      mout_cpucl1_switch_user_p,
+	      PLL_CON0_MUX_CLKCMU_CPUCL1_SWITCH_USER, 4, 1,
+	      CLK_SET_RATE_PARENT, 0),
+	MUX(CLK_MOUT_CPUCL1_DBG_USER, "mout_cpucl1_dbg_user",
+	    mout_cpucl1_dbg_user_p,
+	    PLL_CON0_MUX_CLKCMU_CPUCL1_DBG_USER, 4, 1),
+	MUX_F(CLK_MOUT_CPUCL1_PLL, "mout_cpucl1_pll", mout_cpucl1_pll_p,
+	      CLK_CON_MUX_MUX_CLK_CPUCL1_PLL, 0, 1, CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_div_clock cpucl1_div_clks[] __initconst = {
+	DIV_F(CLK_DOUT_CPUCL1_CPU, "dout_cpucl1_cpu", "mout_cpucl1_pll",
+	      CLK_CON_DIV_DIV_CLK_CPUCL1_CPU, 0, 1,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL1_CMUREF, "dout_cpucl1_cmuref", "dout_cpucl1_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL1_CMUREF, 0, 3,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CPUCL1_PCLK, "dout_cpucl1_pclk", "dout_cpucl1_cpu",
+	      CLK_CON_DIV_DIV_CLK_CPUCL1_PCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+
+	/* EMBEDDED_CMU_CPUCL1 */
+	DIV_F(CLK_DOUT_CLUSTER1_ACLK, "dout_cluster1_aclk", "gout_cluster1_cpu",
+	      CLK_CON_DIV_DIV_CLK_CLUSTER1_ACLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER1_ATCLK, "dout_cluster1_atclk",
+	      "gout_cluster1_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER1_ATCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER1_PCLKDBG, "dout_cluster1_pclkdbg",
+	      "gout_cluster1_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER1_PCLKDBG, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+	DIV_F(CLK_DOUT_CLUSTER1_PERIPHCLK, "dout_cluster1_periphclk",
+	      "gout_cluster1_cpu", CLK_CON_DIV_DIV_CLK_CLUSTER1_PERIPHCLK, 0, 4,
+	      CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
+};
+
+static const struct samsung_gate_clock cpucl1_gate_clks[] __initconst = {
+	GATE(CLK_GOUT_CPUCL1_CMU_CPUCL1_PCLK, "gout_cpucl1_cmu_cpucl1_pclk",
+	     "dout_cpucl1_pclk",
+	     CLK_CON_GAT_CLK_CPUCL1_CMU_CPUCL1_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+
+	/* EMBEDDED_CMU_CPUCL1 */
+	GATE(CLK_GOUT_CLUSTER1_CPU, "gout_cluster1_cpu", "dout_cpucl1_cpu",
+	     CLK_CON_GAT_GATE_CLK_CPUCL1_CPU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_SCLK, "gout_cluster1_sclk", "gout_cluster1_cpu",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_SCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_ATCLK, "gout_cluster1_atclk",
+	     "dout_cluster1_atclk",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_ATCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_PERIPHCLK, "gout_cluster1_periphclk",
+	     "dout_cluster1_periphclk",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PERIPHCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CLK_GOUT_CLUSTER1_PCLK, "gout_cluster1_pclk",
+	     "dout_cluster1_pclkdbg",
+	     CLK_CON_GAT_CLK_CPUCL1_CLUSTER1_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cpu_clock cpucl1_cpu_clks[] __initconst = {
+	CPU_CLK(CLK_CLUSTER1_SCLK, "cluster1_clk", CLK_MOUT_PLL_CPUCL1,
+		CLK_MOUT_CPUCL1_SWITCH_USER, 0, 0x0, CPUCLK_LAYOUT_E850_CL1,
+		exynos850_cluster_clk_d),
+};
+
+static const struct samsung_cmu_info cpucl1_cmu_info __initconst = {
+	.pll_clks		= cpucl1_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cpucl1_pll_clks),
+	.mux_clks		= cpucl1_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cpucl1_mux_clks),
+	.div_clks		= cpucl1_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cpucl1_div_clks),
+	.gate_clks		= cpucl1_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cpucl1_gate_clks),
+	.cpu_clks		= cpucl1_cpu_clks,
+	.nr_cpu_clks		= ARRAY_SIZE(cpucl1_cpu_clks),
+	.nr_clk_ids		= CLKS_NR_CPUCL1,
+	.clk_regs		= cpucl1_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cpucl1_clk_regs),
+	.clk_name		= "dout_cpucl1_switch",
+	.manual_plls		= true,
+};
+
+static void __init exynos850_cmu_cpucl1_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &cpucl1_cmu_info);
+}
+
+/* Register CMU_CPUCL1 early, as CPU clocks should be available ASAP */
+CLK_OF_DECLARE(exynos850_cmu_cpucl1, "samsung,exynos850-cmu-cpucl1",
+	       exynos850_cmu_cpucl1_init);
+
 /* ---- CMU_G3D ------------------------------------------------------------- */
 
 /* Register Offset definitions for CMU_G3D (0x11400000) */
-- 
2.39.2



From sre at kernel.org  Sat Feb 24 13:29:38 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:38 +0100
Subject: [PATCH v4 06/16] dt-bindings: lcdif: Do not require power-domains for i.MX6ULL
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-7-sre@kernel.org>

i.MX6UL(L) uses "fsl,imx6sx-lcdif" as fallback compatible string,
but has only very lightweight DISPLAY power domain. Its DISPLAY
power domain is not supported by the binding / Linux kernel at
the moment. Since the current setup is working, let's remove the
power-domain from being required for that platform to fix the warning
printed by CHECK_DTBS=y.

Fixes: f62678a77d58 ("dt-bindings: mxsfb: Document i.MX8M/i.MX6SX/i.MX6SL power-domains property")
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/display/fsl,lcdif.yaml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
index 1c2be8d6f633..0681fc49aa1b 100644
--- a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
+++ b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
@@ -120,13 +120,19 @@ allOf:
           maxItems: 1
         clock-names:
           maxItems: 1
+  - if:
+      properties:
+        compatible:
+          const: fsl,imx6sx-lcdif
+    then:
+      required:
+        - power-domains
   - if:
       properties:
         compatible:
           contains:
             enum:
               - fsl,imx6sl-lcdif
-              - fsl,imx6sx-lcdif
               - fsl,imx8mm-lcdif
               - fsl,imx8mn-lcdif
               - fsl,imx8mp-lcdif
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:37 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:37 +0100
Subject: [PATCH v4 05/16] dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add imx6
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-6-sre@kernel.org>

Add compatibles used by different i.MX6 variants to the i.MX IOMUX
Controller GPR binding.

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml   | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
index 1da1b758b4ae..8451cb4dd87c 100644
--- a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
@@ -17,7 +17,23 @@ properties:
   compatible:
     oneOf:
       - items:
-          - const: fsl,imx8mq-iomuxc-gpr
+          - enum:
+              - fsl,imx6q-iomuxc-gpr
+              - fsl,imx8mq-iomuxc-gpr
+          - const: syscon
+          - const: simple-mfd
+      - items:
+          - enum:
+              - fsl,imx6sl-iomuxc-gpr
+              - fsl,imx6sll-iomuxc-gpr
+              - fsl,imx6ul-iomuxc-gpr
+          - const: fsl,imx6q-iomuxc-gpr
+          - const: syscon
+      - items:
+          - enum:
+              - fsl,imx6sx-iomuxc-gpr
+              - fsl,imx7d-iomuxc-gpr
+          - const: fsl,imx6q-iomuxc-gpr
           - const: syscon
           - const: simple-mfd
       - items:
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:40 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:40 +0100
Subject: [PATCH v4 08/16] ARM: dts: imx6ull: fix pinctrl node name
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-9-sre@kernel.org>

pinctrl node name must be either pinctrl or pinmux.

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ull.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
index 2bccd45e9fc2..8a1776067ecc 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
@@ -75,7 +75,7 @@ rngb: rng at 2284000 {
 				clocks = <&clks IMX6UL_CLK_DUMMY>;
 			};
 
-			iomuxc_snvs: iomuxc-snvs at 2290000 {
+			iomuxc_snvs: pinctrl at 2290000 {
 				compatible = "fsl,imx6ull-iomuxc-snvs";
 				reg = <0x02290000 0x4000>;
 			};
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:42 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:42 +0100
Subject: [PATCH v4 10/16] ARM: dts: imx6ul: add missing #thermal-sensor-cells
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-11-sre@kernel.org>

Fix the following warning found via CHECK_DTBS:

tempmon: '#thermal-sensor-cells' is a required property

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index 9eb4eee0c272..45b7605ac381 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -638,6 +638,7 @@ tempmon: tempmon {
 					nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
 					nvmem-cell-names = "calib", "temp_grade";
 					clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+					#thermal-sensor-cells = <0>;
 				};
 			};
 
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:36 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:36 +0100
Subject: [PATCH v4 04/16] dt-bindings: soc: imx: fsl,imx-anatop: add binding
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-5-sre@kernel.org>

Add missing binding for i.MX anatop syscon.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/soc/imx/fsl,imx-anatop.yaml      | 128 ++++++++++++++++++
 1 file changed, 128 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
new file mode 100644
index 000000000000..5a59e3470510
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
@@ -0,0 +1,128 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/imx/fsl,imx-anatop.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ANATOP register
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - fsl,imx6sl-anatop
+              - fsl,imx6sll-anatop
+              - fsl,imx6sx-anatop
+              - fsl,imx6ul-anatop
+              - fsl,imx7d-anatop
+          - const: fsl,imx6q-anatop
+          - const: syscon
+          - const: simple-mfd
+      - items:
+          - const: fsl,imx6q-anatop
+          - const: syscon
+          - const: simple-mfd
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Temperature sensor event
+      - description: Brown-out event on either of the support regulators
+      - description: Brown-out event on either the core, gpu or soc regulators
+
+  tempmon:
+    type: object
+    unevaluatedProperties: false
+    $ref: /schemas/thermal/imx-thermal.yaml
+
+patternProperties:
+  "regulator-((3p0)|(vddcore)|(vddsoc))$":
+    type: object
+    unevaluatedProperties: false
+    $ref: /schemas/regulator/anatop-regulator.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx6ul-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    anatop: anatop at 20c8000 {
+        compatible = "fsl,imx6ul-anatop", "fsl,imx6q-anatop",
+                     "syscon", "simple-mfd";
+        reg = <0x020c8000 0x1000>;
+        interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+
+        reg_3p0: regulator-3p0 {
+            compatible = "fsl,anatop-regulator";
+            regulator-name = "vdd3p0";
+            regulator-min-microvolt = <2625000>;
+            regulator-max-microvolt = <3400000>;
+            anatop-reg-offset = <0x120>;
+            anatop-vol-bit-shift = <8>;
+            anatop-vol-bit-width = <5>;
+            anatop-min-bit-val = <0>;
+            anatop-min-voltage = <2625000>;
+            anatop-max-voltage = <3400000>;
+            anatop-enable-bit = <0>;
+        };
+
+        reg_arm: regulator-vddcore {
+            compatible = "fsl,anatop-regulator";
+            regulator-name = "cpu";
+            regulator-min-microvolt = <725000>;
+            regulator-max-microvolt = <1450000>;
+            regulator-always-on;
+            anatop-reg-offset = <0x140>;
+            anatop-vol-bit-shift = <0>;
+            anatop-vol-bit-width = <5>;
+            anatop-delay-reg-offset = <0x170>;
+            anatop-delay-bit-shift = <24>;
+            anatop-delay-bit-width = <2>;
+            anatop-min-bit-val = <1>;
+            anatop-min-voltage = <725000>;
+            anatop-max-voltage = <1450000>;
+        };
+
+        reg_soc: regulator-vddsoc {
+            compatible = "fsl,anatop-regulator";
+            regulator-name = "vddsoc";
+            regulator-min-microvolt = <725000>;
+            regulator-max-microvolt = <1450000>;
+            regulator-always-on;
+            anatop-reg-offset = <0x140>;
+            anatop-vol-bit-shift = <18>;
+            anatop-vol-bit-width = <5>;
+            anatop-delay-reg-offset = <0x170>;
+            anatop-delay-bit-shift = <28>;
+            anatop-delay-bit-width = <2>;
+            anatop-min-bit-val = <1>;
+            anatop-min-voltage = <725000>;
+            anatop-max-voltage = <1450000>;
+        };
+
+        tempmon: tempmon {
+            compatible = "fsl,imx6ul-tempmon", "fsl,imx6sx-tempmon";
+            interrupt-parent = <&gpc>;
+            interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+            fsl,tempmon = <&anatop>;
+            nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
+            nvmem-cell-names = "calib", "temp_grade";
+            clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+            #thermal-sensor-cells = <0>;
+        };
+    };
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:33 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:33 +0100
Subject: [PATCH v4 01/16] dt-bindings: pinctrl: fsl,imx6ul-pinctrl: convert to YAML
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-2-sre@kernel.org>

Convert i.MX6UL pinctrl bindings to YAML.

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt   |  37 ------
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.yaml  | 116 ++++++++++++++++++
 2 files changed, 116 insertions(+), 37 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
deleted file mode 100644
index 7ca4f6118d9a..000000000000
--- a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-* Freescale i.MX6 UltraLite IOMUX Controller
-
-Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
-and usage.
-
-Required properties:
-- compatible: "fsl,imx6ul-iomuxc" for main IOMUX controller or
-  "fsl,imx6ull-iomuxc-snvs" for i.MX 6ULL's SNVS IOMUX controller.
-- fsl,pins: each entry consists of 6 integers and represents the mux and config
-  setting for one pin.  The first 5 integers <mux_reg conf_reg input_reg mux_val
-  input_val> are specified using a PIN_FUNC_ID macro, which can be found in
-  imx6ul-pinfunc.h under device tree source folder.  The last integer CONFIG is
-  the pad setting value like pull-up on this pin.  Please refer to i.MX6 UltraLite
-  Reference Manual for detailed CONFIG settings.
-
-CONFIG bits definition:
-PAD_CTL_HYS                     (1 << 16)
-PAD_CTL_PUS_100K_DOWN           (0 << 14)
-PAD_CTL_PUS_47K_UP              (1 << 14)
-PAD_CTL_PUS_100K_UP             (2 << 14)
-PAD_CTL_PUS_22K_UP              (3 << 14)
-PAD_CTL_PUE                     (1 << 13)
-PAD_CTL_PKE                     (1 << 12)
-PAD_CTL_ODE                     (1 << 11)
-PAD_CTL_SPEED_LOW               (0 << 6)
-PAD_CTL_SPEED_MED               (1 << 6)
-PAD_CTL_SPEED_HIGH              (3 << 6)
-PAD_CTL_DSE_DISABLE             (0 << 3)
-PAD_CTL_DSE_260ohm              (1 << 3)
-PAD_CTL_DSE_130ohm              (2 << 3)
-PAD_CTL_DSE_87ohm               (3 << 3)
-PAD_CTL_DSE_65ohm               (4 << 3)
-PAD_CTL_DSE_52ohm               (5 << 3)
-PAD_CTL_DSE_43ohm               (6 << 3)
-PAD_CTL_DSE_37ohm               (7 << 3)
-PAD_CTL_SRE_FAST                (1 << 0)
-PAD_CTL_SRE_SLOW                (0 << 0)
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
new file mode 100644
index 000000000000..906b264a9e3c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
@@ -0,0 +1,116 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/fsl,imx6ul-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale IMX6UL IOMUX Controller
+
+maintainers:
+  - Dong Aisheng <aisheng.dong at nxp.com>
+
+description:
+  Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
+  for common binding part and usage.
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx6ul-iomuxc
+      - fsl,imx6ull-iomuxc-snvs
+
+  reg:
+    maxItems: 1
+
+# Client device subnode's properties
+patternProperties:
+  'grp$':
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+
+    properties:
+      fsl,pins:
+        description:
+          each entry consists of 6 integers and represents the mux and config
+          setting for one pin. The first 5 integers <mux_reg conf_reg input_reg
+          mux_val input_val> are specified using a PIN_FUNC_ID macro, which can
+          be found in <arch/arm/boot/dts/imx6ul-pinfunc.h>. The last integer
+          CONFIG is the pad setting value like pull-up on this pin. Please
+          refer to i.MX6UL Reference Manual for detailed CONFIG settings.
+        $ref: /schemas/types.yaml#/definitions/uint32-matrix
+        items:
+          items:
+            - description: |
+                "mux_reg" indicates the offset of mux register.
+            - description: |
+                "conf_reg" indicates the offset of pad configuration register.
+            - description: |
+                "input_reg" indicates the offset of select input register.
+            - description: |
+                "mux_val" indicates the mux value to be applied.
+            - description: |
+                "input_val" indicates the select input value to be applied.
+            - description: |
+                "pad_setting" indicates the pad configuration value to be applied:
+                  PAD_CTL_HYS                     (1 << 16)
+                  PAD_CTL_PUS_100K_DOWN           (0 << 14)
+                  PAD_CTL_PUS_47K_UP              (1 << 14)
+                  PAD_CTL_PUS_100K_UP             (2 << 14)
+                  PAD_CTL_PUS_22K_UP              (3 << 14)
+                  PAD_CTL_PUE                     (1 << 13)
+                  PAD_CTL_PKE                     (1 << 12)
+                  PAD_CTL_ODE                     (1 << 11)
+                  PAD_CTL_SPEED_LOW               (0 << 6)
+                  PAD_CTL_SPEED_MED               (1 << 6)
+                  PAD_CTL_SPEED_HIGH              (3 << 6)
+                  PAD_CTL_DSE_DISABLE             (0 << 3)
+                  PAD_CTL_DSE_260ohm              (1 << 3)
+                  PAD_CTL_DSE_130ohm              (2 << 3)
+                  PAD_CTL_DSE_87ohm               (3 << 3)
+                  PAD_CTL_DSE_65ohm               (4 << 3)
+                  PAD_CTL_DSE_52ohm               (5 << 3)
+                  PAD_CTL_DSE_43ohm               (6 << 3)
+                  PAD_CTL_DSE_37ohm               (7 << 3)
+                  PAD_CTL_SRE_FAST                (1 << 0)
+                  PAD_CTL_SRE_SLOW                (0 << 0)
+
+    required:
+      - fsl,pins
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    iomuxc: pinctrl at 20e0000 {
+      compatible = "fsl,imx6ul-iomuxc";
+      reg = <0x020e0000 0x4000>;
+
+      mux_uart: uartgrp {
+        fsl,pins = <
+          0x0084 0x0310 0x0000 0 0 0x1b0b1
+          0x0088 0x0314 0x0624 0 3 0x1b0b1
+        >;
+      };
+    };
+  - |
+    iomuxc_snvs: pinctrl at 2290000 {
+      compatible = "fsl,imx6ull-iomuxc-snvs";
+      reg = <0x02290000 0x4000>;
+
+      pinctrl_snvs_usbc_det: snvsusbcdetgrp {
+        fsl,pins = <
+          0x0010 0x0054 0x0000 0x5 0x0 0x130b0
+        >;
+      };
+    };
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:32 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:32 +0100
Subject: [PATCH v4 00/16] UNI-T UTi260B support
Message-ID: <20240224213240.1854709-1-sre@kernel.org>

From: Sebastian Reichel <sebastian.reichel at collabora.com>

Hi,

This adds adds support for the UNI-T UTi260B thermal camera, which is based
on i.MX6ULL. Patches 1-14 clean up all warnings reported by CHECK_DTBS for
i.MX6ULL (i.e. for an empty board). They are not specific to the UTi260B and
in fact that machine has most of the IP handled by these patches marked as
disabled. Then patches 15+16 introduce the vendor and board compatible DT
bindings. Finally the last patches adds support for the thermal camera itself.

The DT is based on reverse engineered information. More information about
the device can be found in this presentation from Embedded Recipes 2023:

 * https://embedded-recipes.org/2023/wp-content/uploads/2023/10/Running-FOSS-on-a-Thermal-Camera-Sebastian-Reichel-compressed.pdf
 * https://www.youtube.com/watch?v=uvObsCG-Cqo

I also prepared a branch with these patches (and a minimal kernel config)
and published it here:

https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-misc.git/log/?h=uti260b-v4

Changes since PATCHv3:
 * https://lore.kernel.org/all/20240216223654.1312880-1-sre at kernel.org/
  - weim binding: use " instead of '
  - weim binding: use "if: not: required: - foo" instead of "if: properties: foo: false"
  - imx6ull-uti260b.dts: merge ecspi3_csgrp into ecspi3grp
  - collect Reviewed-by from Krzysztof Kozlowski

Changes since PATCHv2:
 * https://lore.kernel.org/all/20240213010347.1075251-1-sre at kernel.org/
  - drop fsl,imx-asrc YAML binding conversion (merged)
  - collect a bunch of Reviewed-by/Acked-by tags
  - weim DT binding: fix issue with requirements
  - xnur-gpio -> xnur-gpios change: Improve patch long description

Changes since PATCHv1:
 * https://lore.kernel.org/all/20240210012114.489102-1-sre at kernel.org/
  - uni-t,imx6ull-uti260b -> uni-t,uti260b
  - add Acked-by for uni-t vendor prefix
  - add Acked-by for HDMI audio index fix
  - add Acked-by for LCDIF power-domain requirement drop
  - anatop DT binding: Fixed indentation in example
  - anatop DT binding: Described IRQs
  - touchscreen DT binding: change tsc@ to touchscreen@ in example
  - touchscreen DT binding: change xnur-gpio to xnur-gpios
  - weim DT binding: drop acme,whatever example
  - weim DT binding: use flash@ instead of nor@
  - weim DT binding: update weim.txt reference in arcx,anybus-controller.txt
  - weim DT binding: switch to memory-controller binding
  - fsl,imx-asrc DT binding: fix ASoC patch subject prefix
  - fsl,imx-asrc DT binding: add constraints
  - add new patch fixing xnur-gpio(s) in all i.MX6UL board DT files
  - add new patch fixing touchscreen nodename in i.MX6UL SoC DT file
  - add new patch fixing weim nodename in all i.MX SoC DT files
  - device DTS: use color/functions for the led
  - device DTS: increase SPI speed
  - device DTS: add comment for SD / eMMC node

Unadressed feedback from PATCHv1:
  - anatop phandle vs parent: technically it makes sense to just use the
    parent, but this driver is only used by i.MX6. The current code makes
	use of the phandle, so we cannot drop it because of backwards
	compatibility. So I don't see a point in deprecating this property.
  - touchscreen binding: I kept measure-delay-time and pre-charge-time
    values in hex, since that is being used everywhere and the unit
	is unknown. The values are directly written into HW registers and
	the i.MX6UL TRM does not provide any hints about the unit. I do not
	have an i.MX6UL device with a touchsreen, so I cannot test either.
  - regulator name in DT: I did not rename the regulators to just
    "regulator", since the nodename must be unique.

Greetings,

-- Sebastian

Sebastian Reichel (16):
  dt-bindings: pinctrl: fsl,imx6ul-pinctrl: convert to YAML
  dt-bindings: bus: imx-weim: convert to YAML
  dt-bindings: input: touchscreen: fsl,imx6ul-tsc convert to YAML
  dt-bindings: soc: imx: fsl,imx-anatop: add binding
  dt-bindings: soc: imx: fsl,imx-iomuxc-gpr: add imx6
  dt-bindings: lcdif: Do not require power-domains for i.MX6ULL
  dt-bindings: fsl-imx-sdma: fix HDMI audio index
  ARM: dts: imx6ull: fix pinctrl node name
  ARM: dts: imx6ul: Remove fsl,anatop from usbotg1
  ARM: dts: imx6ul: add missing #thermal-sensor-cells
  ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
  ARM: dts: nxp: imx6ul: fix touchscreen node name
  ARM: dts: nxp: imx: fix weim node name
  dt-bindings: vendor-prefixes: add UNI-T
  dt-bindings: arm: add UNI-T UTi260B
  ARM: dts: imx6ull-uti260b: Add board

 .../devicetree/bindings/arm/fsl.yaml          |   1 +
 .../devicetree/bindings/bus/imx-weim.txt      | 117 ----
 .../bindings/display/fsl,lcdif.yaml           |   8 +-
 .../devicetree/bindings/dma/fsl,imx-sdma.yaml |   3 +-
 .../input/touchscreen/fsl,imx6ul-tsc.yaml     |  97 +++
 .../bindings/input/touchscreen/imx6ul_tsc.txt |  38 --
 .../fsl/fsl,imx-weim-peripherals.yaml         |  31 +
 .../memory-controllers/fsl/fsl,imx-weim.yaml  | 204 +++++++
 .../mc-peripheral-props.yaml                  |   1 +
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt   |  37 --
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.yaml  | 116 ++++
 .../bindings/soc/imx/fsl,imx-anatop.yaml      | 128 ++++
 .../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml  |  18 +-
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm/boot/dts/nxp/imx/Makefile            |   1 +
 arch/arm/boot/dts/nxp/imx/imx1.dtsi           |   2 +-
 arch/arm/boot/dts/nxp/imx/imx27.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx31.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx35.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx51.dtsi          |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi        |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6sl.dtsi         |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6sx.dtsi         |   2 +-
 .../boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi    |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts     |   2 +-
 .../nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi    |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi         |   6 +-
 .../boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi   |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts | 567 ++++++++++++++++++
 arch/arm/boot/dts/nxp/imx/imx6ull.dtsi        |   2 +-
 .../fieldbus/arcx,anybus-controller.txt       |   2 +-
 31 files changed, 1191 insertions(+), 212 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
 delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx-anatop.yaml
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts

-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:39 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:39 +0100
Subject: [PATCH v4 07/16] dt-bindings: fsl-imx-sdma: fix HDMI audio index
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-8-sre@kernel.org>

HDMI Audio has been added to the DT binding documentation with an
incorrect index. DT and the driver use index 26. This happened,
because the binding is missing MULTI_SAI type, which is using
index 25.

Reported-by: Michael Yackavage <michaely at ips-yes.com>
Fixes: 7bdbd87d4008 ("dt-bindings: fsl-imx-sdma: Convert imx sdma to DT schema")
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml b/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
index b95dd8db5a30..37135fa024f9 100644
--- a/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
+++ b/Documentation/devicetree/bindings/dma/fsl,imx-sdma.yaml
@@ -92,7 +92,8 @@ properties:
               description: needs firmware more than ver 2
           - Shared ASRC: 23
           - SAI: 24
-          - HDMI Audio: 25
+          - Multi SAI: 25
+          - HDMI Audio: 26
 
        The third cell: transfer priority ID
          enum:
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:34 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:34 +0100
Subject: [PATCH v4 02/16] dt-bindings: bus: imx-weim: convert to YAML
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-3-sre@kernel.org>

Convert the i.MX  Wireless External Interface Module binding to YAML.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../devicetree/bindings/bus/imx-weim.txt      | 117 ----------
 .../fsl/fsl,imx-weim-peripherals.yaml         |  31 +++
 .../memory-controllers/fsl/fsl,imx-weim.yaml  | 204 ++++++++++++++++++
 .../mc-peripheral-props.yaml                  |   1 +
 .../fieldbus/arcx,anybus-controller.txt       |   2 +-
 5 files changed, 237 insertions(+), 118 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/imx-weim.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml

diff --git a/Documentation/devicetree/bindings/bus/imx-weim.txt b/Documentation/devicetree/bindings/bus/imx-weim.txt
deleted file mode 100644
index e7f502070d77..000000000000
--- a/Documentation/devicetree/bindings/bus/imx-weim.txt
+++ /dev/null
@@ -1,117 +0,0 @@
-Device tree bindings for i.MX Wireless External Interface Module (WEIM)
-
-The term "wireless" does not imply that the WEIM is literally an interface
-without wires. It simply means that this module was originally designed for
-wireless and mobile applications that use low-power technology.
-
-The actual devices are instantiated from the child nodes of a WEIM node.
-
-Required properties:
-
- - compatible:		Should contain one of the following:
-			  "fsl,imx1-weim"
-			  "fsl,imx27-weim"
-			  "fsl,imx51-weim"
-			  "fsl,imx50-weim"
-			  "fsl,imx6q-weim"
- - reg:			A resource specifier for the register space
-			(see the example below)
- - clocks:		the clock, see the example below.
- - #address-cells:	Must be set to 2 to allow memory address translation
- - #size-cells:		Must be set to 1 to allow CS address passing
- - ranges:		Must be set up to reflect the memory layout with four
-			integer values for each chip-select line in use:
-
-			   <cs-number> 0 <physical address of mapping> <size>
-
-Optional properties:
-
- - fsl,weim-cs-gpr:	For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
-			devices, it should be the phandle to the system General
-			Purpose Register controller that contains WEIM CS GPR
-			register, e.g. IOMUXC_GPR1 on i.MX6Q.  IOMUXC_GPR1[11:0]
-			should be set up as one of the following 4 possible
-			values depending on the CS space configuration.
-
-			IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
-			---------------------------------------------
-				05	    128M     0M     0M     0M
-				033          64M    64M     0M     0M
-				0113         64M    32M    32M     0M
-				01111        32M    32M    32M    32M
-
-			In case that the property is absent, the reset value or
-			what bootloader sets up in IOMUXC_GPR1[11:0] will be
-			used.
-
- - fsl,burst-clk-enable	For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
-			devices, the presence of this property indicates that
-			the weim bus should operate in Burst Clock Mode.
-
- - fsl,continuous-burst-clk	Make Burst Clock to output continuous clock.
-			Without this option Burst Clock will output clock
-			only when necessary. This takes effect only if
-			"fsl,burst-clk-enable" is set.
-
-Timing property for child nodes. It is mandatory, not optional.
-
- - fsl,weim-cs-timing:	The timing array, contains timing values for the
-			child node. We get the CS indexes from the address
-			ranges in the child node's "reg" property.
-			The number of registers depends on the selected chip:
-			For i.MX1, i.MX21 ("fsl,imx1-weim") there are two
-			registers: CSxU, CSxL.
-			For i.MX25, i.MX27, i.MX31 and i.MX35 ("fsl,imx27-weim")
-			there are three registers: CSCRxU, CSCRxL, CSCRxA.
-			For i.MX50, i.MX53 ("fsl,imx50-weim"),
-			i.MX51 ("fsl,imx51-weim") and i.MX6Q ("fsl,imx6q-weim")
-			there are six registers: CSxGCR1, CSxGCR2, CSxRCR1,
-			CSxRCR2, CSxWCR1, CSxWCR2.
-
-Example for an imx6q-sabreauto board, the NOR flash connected to the WEIM:
-
-	weim: weim at 21b8000 {
-		compatible = "fsl,imx6q-weim";
-		reg = <0x021b8000 0x4000>;
-		clocks = <&clks 196>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x08000000>;
-		fsl,weim-cs-gpr = <&gpr>;
-
-		nor at 0,0 {
-			compatible = "cfi-flash";
-			reg = <0 0 0x02000000>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			bank-width = <2>;
-			fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
-					0x0000c000 0x1404a38e 0x00000000>;
-		};
-	};
-
-Example for an imx6q-based board, a multi-chipselect device connected to WEIM:
-
-In this case, both chip select 0 and 1 will be configured with the same timing
-array values.
-
-	weim: weim at 21b8000 {
-		compatible = "fsl,imx6q-weim";
-		reg = <0x021b8000 0x4000>;
-		clocks = <&clks 196>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x02000000
-			  1 0 0x0a000000 0x02000000
-			  2 0 0x0c000000 0x02000000
-			  3 0 0x0e000000 0x02000000>;
-		fsl,weim-cs-gpr = <&gpr>;
-
-		acme at 0 {
-			compatible = "acme,whatever";
-			reg = <0 0 0x100>, <0 0x400000 0x800>,
-				<1 0x400000 0x800>;
-			fsl,weim-cs-timing = <0x024400b1 0x00001010 0x20081100
-				0x00000000 0xa0000240 0x00000000>;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
new file mode 100644
index 000000000000..82fc5f4a1ed6
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,imx-weim-peripherals.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX WEIM Bus Peripheral Nodes
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+description:
+  This binding is meant for the child nodes of the WEIM node. The node
+  represents any device connected to the WEIM bus. It may be a Flash chip,
+  RAM chip or Ethernet controller, etc. These properties are meant for
+  configuring the WEIM settings/timings and will accompany the bindings
+  supported by the respective device.
+
+properties:
+  reg: true
+
+  fsl,weim-cs-timing:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Timing values for the child node.
+    minItems: 2
+    maxItems: 6
+
+# the WEIM child will have its own native properties
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
new file mode 100644
index 000000000000..3f40ca5b13f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
@@ -0,0 +1,204 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,imx-weim.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX Wireless External Interface Module (WEIM)
+
+maintainers:
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+description:
+  The term "wireless" does not imply that the WEIM is literally an interface
+  without wires. It simply means that this module was originally designed for
+  wireless and mobile applications that use low-power technology. The actual
+  devices are instantiated from the child nodes of a WEIM node.
+
+properties:
+  $nodename:
+    pattern: "^memory-controller@[0-9a-f]+$"
+
+  compatible:
+    oneOf:
+      - enum:
+          - fsl,imx1-weim
+          - fsl,imx27-weim
+          - fsl,imx50-weim
+          - fsl,imx51-weim
+          - fsl,imx6q-weim
+      - items:
+          - enum:
+              - fsl,imx31-weim
+              - fsl,imx35-weim
+          - const: fsl,imx27-weim
+      - items:
+          - enum:
+              - fsl,imx6sx-weim
+              - fsl,imx6ul-weim
+          - const: fsl,imx6q-weim
+
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  ranges: true
+
+  fsl,weim-cs-gpr:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Phandle to the system General Purpose Register controller that contains
+      WEIM CS GPR register, e.g. IOMUXC_GPR1 on i.MX6Q. IOMUXC_GPR1[11:0]
+      should be set up as one of the following 4 possible values depending on
+      the CS space configuration.
+
+      IOMUXC_GPR1[11:0]    CS0    CS1    CS2    CS3
+      ---------------------------------------------
+              05          128M     0M     0M     0M
+              033          64M    64M     0M     0M
+              0113         64M    32M    32M     0M
+              01111        32M    32M    32M    32M
+
+      In case that the property is absent, the reset value or what bootloader
+      sets up in IOMUXC_GPR1[11:0] will be used.
+
+  fsl,burst-clk-enable:
+    type: boolean
+    description:
+      The presence of this property indicates that the weim bus should operate
+      in Burst Clock Mode.
+
+  fsl,continuous-burst-clk:
+    type: boolean
+    description:
+      Make Burst Clock to output continuous clock. Without this option Burst
+      Clock will output clock only when necessary.
+
+patternProperties:
+  "^.*@[0-7],[0-9a-f]+$":
+    type: object
+    description: Devices attached to chip selects are represented as subnodes.
+    $ref: fsl,imx-weim-peripherals.yaml
+    additionalProperties: true
+    required:
+      - fsl,weim-cs-timing
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          not:
+            contains:
+              enum:
+                - fsl,imx50-weim
+                - fsl,imx6q-weim
+    then:
+      properties:
+        fsl,weim-cs-gpr: false
+        fsl,burst-clk-enable: false
+  - if:
+      not:
+        required:
+          - fsl,burst-clk-enable
+    then:
+      properties:
+        fsl,continuous-burst-clk: false
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,imx1-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSxU
+                  - description: CSxL
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx27-weim
+              - fsl,imx31-weim
+              - fsl,imx35-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSCRxU
+                  - description: CSCRxL
+                  - description: CSCRxA
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx50-weim
+              - fsl,imx51-weim
+              - fsl,imx6q-weim
+              - fsl,imx6sx-weim
+              - fsl,imx6ul-weim
+    then:
+      patternProperties:
+        "^.*@[0-7],[0-9a-f]+$":
+          properties:
+            fsl,weim-cs-timing:
+              items:
+                items:
+                  - description: CSxGCR1
+                  - description: CSxGCR2
+                  - description: CSxRCR1
+                  - description: CSxRCR2
+                  - description: CSxWCR1
+                  - description: CSxWCR2
+
+additionalProperties: false
+
+examples:
+  - |
+    memory-controller at 21b8000 {
+        compatible = "fsl,imx6q-weim";
+        reg = <0x021b8000 0x4000>;
+        clocks = <&clks 196>;
+        #address-cells = <2>;
+        #size-cells = <1>;
+        ranges = <0 0 0x08000000 0x08000000>;
+        fsl,weim-cs-gpr = <&gpr>;
+
+        flash at 0,0 {
+            compatible = "cfi-flash";
+            reg = <0 0 0x02000000>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+            bank-width = <2>;
+            fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
+                                  0x0000c000 0x1404a38e 0x00000000>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml b/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml
index 8d9dae15ade0..00deeb09f87d 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mc-peripheral-props.yaml
@@ -37,5 +37,6 @@ allOf:
   - $ref: ingenic,nemc-peripherals.yaml#
   - $ref: intel,ixp4xx-expansion-peripheral-props.yaml#
   - $ref: ti,gpmc-child.yaml#
+  - $ref: fsl/fsl,imx-weim-peripherals.yaml
 
 additionalProperties: true
diff --git a/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt b/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt
index b1f9474f36d5..f34a95611645 100644
--- a/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt
+++ b/drivers/staging/fieldbus/Documentation/devicetree/bindings/fieldbus/arcx,anybus-controller.txt
@@ -48,7 +48,7 @@ Example of usage:
 -----------------
 
 This example places the bridge on top of the i.MX WEIM parallel bus, see:
-Documentation/devicetree/bindings/bus/imx-weim.txt
+Documentation/devicetree/bindings/memory-controllers/fsl/fsl,imx-weim.yaml
 
 &weim {
 	controller at 0,0 {
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:41 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:41 +0100
Subject: [PATCH v4 09/16] ARM: dts: imx6ul: Remove fsl,anatop from usbotg1
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-10-sre@kernel.org>

fsl,anatop should only be added to the usbphy nodes.

Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index a27a7554c2e7..9eb4eee0c272 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -855,7 +855,6 @@ usbotg1: usb at 2184000 {
 				clocks = <&clks IMX6UL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
-				fsl,anatop = <&anatop>;
 				ahb-burst-config = <0x0>;
 				tx-burst-size-dword = <0x10>;
 				rx-burst-size-dword = <0x10>;
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:45 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:45 +0100
Subject: [PATCH v4 13/16] ARM: dts: nxp: imx: fix weim node name
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-14-sre@kernel.org>

DT node names should be generic, so replace "weim" node name with
"memory-controller" in all i.MX SoC DT files.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx1.dtsi    | 2 +-
 arch/arm/boot/dts/nxp/imx/imx27.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx31.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx35.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx51.dtsi   | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6sl.dtsi  | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6sx.dtsi  | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi  | 2 +-
 9 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx1.dtsi b/arch/arm/boot/dts/nxp/imx/imx1.dtsi
index 1ac10965fdfd..389ecb1ebf8f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx1.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx1.dtsi
@@ -251,7 +251,7 @@ gpio4: gpio at 21c300 {
 			};
 		};
 
-		weim: weim at 220000 {
+		weim: memory-controller at 220000 {
 			#address-cells = <2>;
 			#size-cells = <1>;
 			compatible = "fsl,imx1-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx27.dtsi b/arch/arm/boot/dts/nxp/imx/imx27.dtsi
index ec472695c71e..ec3ccc8f4095 100644
--- a/arch/arm/boot/dts/nxp/imx/imx27.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx27.dtsi
@@ -568,7 +568,7 @@ nfc: nand-controller at d8000000 {
 			status = "disabled";
 		};
 
-		weim: weim at d8002000 {
+		weim: memory-controller at d8002000 {
 			#address-cells = <2>;
 			#size-cells = <1>;
 			compatible = "fsl,imx27-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx31.dtsi b/arch/arm/boot/dts/nxp/imx/imx31.dtsi
index e1ae7c175f7d..00006c90d9a7 100644
--- a/arch/arm/boot/dts/nxp/imx/imx31.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx31.dtsi
@@ -352,7 +352,7 @@ nfc: nand at b8000000 {
 				status = "disabled";
 			};
 
-			weim: weim at b8002000 {
+			weim: memory-controller at b8002000 {
 				compatible = "fsl,imx31-weim", "fsl,imx27-weim";
 				reg = <0xb8002000 0x1000>;
 				clocks = <&clks 56>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx35.dtsi b/arch/arm/boot/dts/nxp/imx/imx35.dtsi
index 2d20e5541acc..442dc15677b8 100644
--- a/arch/arm/boot/dts/nxp/imx/imx35.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx35.dtsi
@@ -374,7 +374,7 @@ nfc: nand at bb000000 {
 				status = "disabled";
 			};
 
-			weim: weim at b8002000 {
+			weim: memory-controller at b8002000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				clocks = <&clks 0>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx51.dtsi b/arch/arm/boot/dts/nxp/imx/imx51.dtsi
index c96d6311dfa7..4efce49022e4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx51.dtsi
@@ -578,7 +578,7 @@ m4if: m4if at 83fd8000 {
 				reg = <0x83fd8000 0x1000>;
 			};
 
-			weim: weim at 83fda000 {
+			weim: memory-controller at 83fda000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx51-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
index 81142c523fa8..8431b8a994f4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
@@ -1158,7 +1158,7 @@ mmdc1: memory-controller at 21b4000 { /* MMDC1 */
 				status = "disabled";
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx6q-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
index 28111efb19a6..6aa61235e39e 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
@@ -949,7 +949,7 @@ rngb: rngb at 21b4000 {
 				clocks = <&clks IMX6SL_CLK_DUMMY>;
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				reg = <0x021b8000 0x4000>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
index df3a375f0a3e..0de359d62a47 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
@@ -1107,7 +1107,7 @@ fec2: ethernet at 21b4000 {
 				status = "disabled";
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx6sx-weim", "fsl,imx6q-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index 8aa365f837ca..aeb7e07fd309 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -975,7 +975,7 @@ memory-controller at 21b0000 {
 				clocks = <&clks IMX6UL_CLK_MMDC_P0_IPG>;
 			};
 
-			weim: weim at 21b8000 {
+			weim: memory-controller at 21b8000 {
 				#address-cells = <2>;
 				#size-cells = <1>;
 				compatible = "fsl,imx6ul-weim", "fsl,imx6q-weim";
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:35 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:35 +0100
Subject: [PATCH v4 03/16] dt-bindings: input: touchscreen: fsl,imx6ul-tsc convert to YAML
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-4-sre@kernel.org>

Convert the i.MX6UL touchscreen DT binding to YAML.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 .../input/touchscreen/fsl,imx6ul-tsc.yaml     | 97 +++++++++++++++++++
 .../bindings/input/touchscreen/imx6ul_tsc.txt | 38 --------
 2 files changed, 97 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
 delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml b/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
new file mode 100644
index 000000000000..678756ad0f92
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/fsl,imx6ul-tsc.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/fsl,imx6ul-tsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX6UL Touch Controller
+
+maintainers:
+  - Haibo Chen <haibo.chen at nxp.com>
+  - Shawn Guo <shawnguo at kernel.org>
+  - Sascha Hauer <s.hauer at pengutronix.de>
+
+properties:
+  compatible:
+    const: fsl,imx6ul-tsc
+
+  reg:
+    items:
+      - description: touch controller address
+      - description: ADC2 address
+
+  interrupts:
+    items:
+      - description: touch controller address
+      - description: ADC2 address
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: tsc
+      - const: adc
+
+  xnur-gpios:
+    maxItems: 1
+    description:
+      The X- gpio this controller connect to. This xnur-gpio returns to
+      low once the finger leave the touch screen (The last touch event
+      the touch controller capture).
+
+  measure-delay-time:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      The value of measure delay time. Before X-axis or Y-axis measurement,
+      the screen need some time before even potential distribution ready.
+    default: 0xffff
+    minimum: 0
+    maximum: 0xffffff
+
+  pre-charge-time:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      The touch screen need some time to precharge.
+    default: 0xfff
+    minimum: 0
+    maximum: 0xffffffff
+
+  touchscreen-average-samples:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: Number of data samples which are averaged for each read.
+    enum: [ 1, 4, 8, 16, 32 ]
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - xnur-gpios
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/imx6ul-clock.h>
+    #include <dt-bindings/gpio/gpio.h>
+    touchscreen at 2040000 {
+        compatible = "fsl,imx6ul-tsc";
+        reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
+        interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX6UL_CLK_IPG>,
+                 <&clks IMX6UL_CLK_ADC2>;
+        clock-names = "tsc", "adc";
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_tsc>;
+        xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+        measure-delay-time = <0xfff>;
+        pre-charge-time = <0xffff>;
+        touchscreen-average-samples = <32>;
+    };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
deleted file mode 100644
index 164915004424..000000000000
--- a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-* Freescale i.MX6UL Touch Controller
-
-Required properties:
-- compatible: must be "fsl,imx6ul-tsc".
-- reg: this touch controller address and the ADC2 address.
-- interrupts: the interrupt of this touch controller and ADC2.
-- clocks: the root clock of touch controller and ADC2.
-- clock-names; must be "tsc" and "adc".
-- xnur-gpio: the X- gpio this controller connect to.
-  This xnur-gpio returns to low once the finger leave the touch screen (The
-  last touch event the touch controller capture).
-
-Optional properties:
-- measure-delay-time: the value of measure delay time.
-  Before X-axis or Y-axis measurement, the screen need some time before
-  even potential distribution ready.
-  This value depends on the touch screen.
-- pre-charge-time: the touch screen need some time to precharge.
-  This value depends on the touch screen.
-- touchscreen-average-samples: Number of data samples which are averaged for
-  each read. Valid values are 1, 4, 8, 16 and 32.
-
-Example:
-	tsc: tsc at 2040000 {
-		compatible = "fsl,imx6ul-tsc";
-		reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
-		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clks IMX6UL_CLK_IPG>,
-			 <&clks IMX6UL_CLK_ADC2>;
-		clock-names = "tsc", "adc";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_tsc>;
-		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
-		measure-delay-time = <0xfff>;
-		pre-charge-time = <0xffff>;
-		touchscreen-average-samples = <32>;
-	};
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:46 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:46 +0100
Subject: [PATCH v4 14/16] dt-bindings: vendor-prefixes: add UNI-T
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-15-sre@kernel.org>

Uni-Trend Technology is a manufacturer of measurement
and testing tools.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre 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 1a0dc04f1db4..e945e76696c2 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1484,6 +1484,8 @@ patternProperties:
     description: Ufi Space Co., Ltd.
   "^ugoos,.*":
     description: Ugoos Industrial Co., Ltd.
+  "^uni-t,.*":
+    description: Uni-Trend Technology (China) Co., Ltd.
   "^uniwest,.*":
     description: United Western Technologies Corp (UniWest)
   "^upisemi,.*":
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:44 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:44 +0100
Subject: [PATCH v4 12/16] ARM: dts: nxp: imx6ul: fix touchscreen node name
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-13-sre@kernel.org>

The canonical node name for touchscreens is "touchscreen",
so update the i.MX6UL "tsc" node accordingly.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index 45b7605ac381..8aa365f837ca 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -370,7 +370,7 @@ asrc: asrc at 2034000 {
 				};
 			};
 
-			tsc: tsc at 2040000 {
+			tsc: touchscreen at 2040000 {
 				compatible = "fsl,imx6ul-tsc";
 				reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
 				interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:47 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:47 +0100
Subject: [PATCH v4 15/16] dt-bindings: arm: add UNI-T UTi260B
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-16-sre@kernel.org>

Add compatible value for i.MX6ULL based UNI-T UTi260B thermal camera.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 228dcc5c7d6f..7b65f9c9c1a5 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -708,6 +708,7 @@ properties:
               - toradex,colibri-imx6ull      # Colibri iMX6ULL Modules
               - toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module
               - toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Modules
+              - uni-t,uti260b             # UNI-T UTi260B Thermal Camera
           - const: fsl,imx6ull
 
       - description: i.MX6ULL Armadeus Systems OPOS6ULDev Board
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:43 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:43 +0100
Subject: [PATCH v4 11/16] ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-12-sre@kernel.org>

Replace all "xnur-gpio" with "xnur-gpios" in the i.MX6UL(L) Touchscreen
node, since the -gpio suffix is deprecated. All known implementations of
this binding can handle -gpio and -gpios since day 1, so this should be
fully backwards compatible.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi          | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts                | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi         | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
index 2ac40d69425b..f10f0525490b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
@@ -321,7 +321,7 @@ &snvs_pwrkey {
 &tsc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_tsc>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 	measure-delay-time = <0xffff>;
 	pre-charge-time = <0xfff>;
 	status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts b/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
index 875ae699c5cb..2ca18f3dad0a 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
@@ -203,7 +203,7 @@ &pwm8 {
 &tsc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_tsc>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 };
 
 &sai2 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
index 18cac19aa9b0..af337f18a266 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
@@ -156,7 +156,7 @@ &snvs_pwrkey {
 &tsc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_tsc>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 	measure-delay-time = <0xffff>;
 	pre-charge-time = <0xffff>;
 	status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
index 830b5a5064f2..6d2163250b5d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
@@ -273,7 +273,7 @@ &tsc {
 	pinctrl-names = "default";
 	pre-charge-time = <0xfff>;
 	touchscreen-average-samples = <32>;
-	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 };
 
 /* DHCOM UART1 */
-- 
2.43.0



From sre at kernel.org  Sat Feb 24 13:29:48 2024
From: sre at kernel.org (Sebastian Reichel)
Date: Sat, 24 Feb 2024 22:29:48 +0100
Subject: [PATCH v4 16/16] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <20240224213240.1854709-1-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
Message-ID: <20240224213240.1854709-17-sre@kernel.org>

Add UNI-T UTi260b thermal camera board.

Reviewed-by: Stefan Wahren <wahrenst at gmx.net>
Signed-off-by: Sebastian Reichel <sre at kernel.org>
---
 arch/arm/boot/dts/nxp/imx/Makefile            |   1 +
 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts | 567 ++++++++++++++++++
 2 files changed, 568 insertions(+)
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts

diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile
index a724d1a7a9a0..47350cf3ddeb 100644
--- a/arch/arm/boot/dts/nxp/imx/Makefile
+++ b/arch/arm/boot/dts/nxp/imx/Makefile
@@ -349,6 +349,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
 	imx6ull-tarragon-slavext.dtb \
 	imx6ull-tqma6ull2-mba6ulx.dtb \
 	imx6ull-tqma6ull2l-mba6ulx.dtb \
+	imx6ull-uti260b.dtb \
 	imx6ulz-14x14-evk.dtb \
 	imx6ulz-bsh-smm-m2.dtb
 dtb-$(CONFIG_SOC_IMX7D) += \
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
new file mode 100644
index 000000000000..8f6f092363b7
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
@@ -0,0 +1,567 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright (C) 2022-2024 Sebastian Reichel <sre at kernel.org>
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/clock/imx6ul-clock.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "UNI-T UTi260B Thermal Camera";
+	compatible = "uni-t,uti260b", "fsl,imx6ull";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_led_ctrl>;
+
+		led {
+			color = <LED_COLOR_ID_WHITE>;
+			function = LED_FUNCTION_FLASH;
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_gpio_keys>;
+		autorepeat;
+
+		up-key {
+			label = "Up";
+			gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_UP>;
+		};
+
+		down-key {
+			label = "Down";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_DOWN>;
+		};
+
+		left-key {
+			label = "Left";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_LEFT>;
+		};
+
+		right-key {
+			label = "Right";
+			gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RIGHT>;
+		};
+
+		ok-key {
+			label = "Ok";
+			gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_ENTER>;
+		};
+
+		return-key {
+			label = "Return";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_ESC>;
+		};
+
+		play-key {
+			label = "Media";
+			gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_MEDIA>;
+		};
+
+		trigger-key {
+			label = "Trigger";
+			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_TRIGGER>;
+		};
+
+		power-key {
+			label = "Power";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+
+		light-key {
+			label = "Light";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_LIGHTS_TOGGLE>;
+		};
+	};
+
+	panel_backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+		enable-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_backlight_enable>;
+		power-supply = <&reg_vsd>;
+		pwms = <&pwm1 0 50000 0>;
+	};
+
+	reg_vsd: regulator-vsd {
+		compatible = "regulator-fixed";
+		regulator-name = "VSD_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_vref: regulator-vref-4v2 {
+		compatible = "regulator-fixed";
+		regulator-name = "VREF_4V2";
+		regulator-min-microvolt = <4200000>;
+		regulator-max-microvolt = <4200000>;
+	};
+
+	tp5000: charger {
+		compatible = "gpio-charger";
+		charger-type = "usb-sdp";
+		gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_charger_stat1>;
+	};
+
+	battery: battery {
+		compatible = "simple-battery";
+		/* generic 26650 battery */
+		device-chemistry = "lithium-ion";
+		charge-full-design-microamp-hours = <5000000>;
+		voltage-max-design-microvolt = <4200000>;
+		voltage-min-design-microvolt = <3300000>;
+	};
+
+	fuel-gauge {
+		compatible = "adc-battery";
+		charged-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		io-channel-names = "voltage";
+		io-channels = <&adc1 7>;
+		monitored-battery = <&battery>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_charger_stat2>;
+		power-supplies = <&tp5000>;
+	};
+
+	poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_poweroff>;
+	};
+};
+
+&gpio1 {
+	ir-reset-hog {
+		gpio-hog;
+		gpios = <3 GPIO_ACTIVE_LOW>;
+		line-name = "ir-reset-gpio";
+		output-low;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_ir_reset>;
+	};
+};
+
+&gpio2 {
+	/* configuring this to output-high results in poweroff */
+	power-en-hog {
+		gpio-hog;
+		gpios = <6 GPIO_ACTIVE_HIGH>;
+		line-name = "power-en-gpio";
+		output-low;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_poweroff2>;
+	};
+};
+
+&ecspi3 {
+	cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_spi3>;
+	status = "okay";
+
+	panel at 0 {
+		compatible = "inanbo,t28cp45tn89-v17";
+		reg = <0>;
+		backlight = <&panel_backlight>;
+		power-supply = <&reg_vsd>;
+		spi-cpha;
+		spi-cpol;
+		spi-max-frequency = <1000000>;
+		spi-rx-bus-width = <0>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&display_out>;
+			};
+		};
+	};
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_uart>;
+	status = "okay";
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_pwm>;
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_i2c1>;
+	status = "okay";
+
+	camera at 21 {
+		compatible = "galaxycore,gc0308";
+		reg = <0x21>;
+		clocks = <&clks IMX6UL_CLK_CSI>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&mux_gc0308>;
+		powerdown-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+		vdd28-supply = <&reg_vsd>;
+
+		port {
+			gc0308_to_parallel: endpoint {
+				remote-endpoint = <&parallel_from_gc0308>;
+				bus-width = <8>;
+				data-shift = <2>; /* lines 9:2 are used */
+				hsync-active = <1>; /* active high */
+				vsync-active = <1>; /* active high */
+				data-active = <1>; /* active high */
+				pclk-sample = <1>; /* sample on rising edge */
+			};
+		};
+	};
+};
+
+&csi {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_csi>;
+
+	port {
+		parallel_from_gc0308: endpoint {
+			remote-endpoint = <&gc0308_to_parallel>;
+		};
+	};
+};
+
+&i2c2 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_i2c2>;
+	status = "okay";
+
+	rtc at 51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&lcdif {
+	assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_lcd_data>, <&mux_lcd_ctrl>;
+	status = "okay";
+
+	port {
+		display_out: endpoint {
+			remote-endpoint = <&panel_in>;
+		};
+	};
+};
+
+&usdhc1 {
+	/* MicroSD */
+	cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+	keep-power-in-suspend;
+	no-1-8-v;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&mux_sdhc1>, <&mux_sdhc1_cd>;
+	pinctrl-1 = <&mux_sdhc1_100mhz>, <&mux_sdhc1_cd>;
+	pinctrl-2 = <&mux_sdhc1_200mhz>, <&mux_sdhc1_cd>;
+	wakeup-source;
+	vmmc-supply = <&reg_vsd>;
+	status = "okay";
+};
+
+&usdhc2 {
+	/* eMMC */
+	keep-power-in-suspend;
+	no-1-8-v;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_sdhc2>;
+	wakeup-source;
+	status = "okay";
+};
+
+&wdog1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_wdog>;
+};
+
+&adc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mux_adc>;
+	vref-supply = <&reg_vref>;
+	#io-channel-cells = <1>;
+	status = "okay";
+};
+
+&usbotg1 {
+	/* USB-C connector */
+	disable-over-current;
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbotg2 {
+	/* thermal sensor */
+	disable-over-current;
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy1 {
+	fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+	fsl,tx-d-cal = <106>;
+};
+
+&iomuxc {
+	mux_ir_reset: irresetgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03		0x3008
+		>;
+	};
+
+	mux_poweroff: poweroffgrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04		0x3008
+		>;
+	};
+
+	mux_poweroff2: poweroff2grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06		0x3008
+		>;
+	};
+
+	mux_charger_stat1: charger1grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01		0x3008
+		>;
+	};
+
+	mux_charger_stat2: charger2grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO02__GPIO1_IO02		0x3008
+		>;
+	};
+
+	mux_wdog: wdoggrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY		0x30b0
+		>;
+	};
+
+	mux_sdhc1_cd: sdhc1-cd-grp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_RTS_B__GPIO1_IO19		0x17059
+		>;
+	};
+
+	mux_sdhc1: sdhc1grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x17059
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x10071
+			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
+		>;
+	};
+
+	mux_sdhc1_100mhz: sdhc1-100mhz-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x170b9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x170b9
+			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
+		>;
+	};
+
+	mux_sdhc1_200mhz: sdhc1-200mhz-grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD			0x170f9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK			0x170f9
+			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
+		>;
+	};
+
+	mux_sdhc2: sdhc2grp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_RE_B__USDHC2_CLK			0x10069
+			MX6UL_PAD_NAND_WE_B__USDHC2_CMD			0x17059
+			MX6UL_PAD_NAND_DATA00__USDHC2_DATA0		0x17059
+			MX6UL_PAD_NAND_DATA01__USDHC2_DATA1		0x17059
+			MX6UL_PAD_NAND_DATA02__USDHC2_DATA2		0x17059
+			MX6UL_PAD_NAND_DATA03__USDHC2_DATA3		0x17059
+			MX6UL_PAD_NAND_DATA04__USDHC2_DATA4		0x17059
+			MX6UL_PAD_NAND_DATA05__USDHC2_DATA5		0x17059
+			MX6UL_PAD_NAND_DATA06__USDHC2_DATA6		0x17059
+			MX6UL_PAD_NAND_DATA07__USDHC2_DATA7		0x17059
+		>;
+	};
+
+	mux_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6UL_PAD_UART4_TX_DATA__I2C1_SCL		0x4001b8b0
+			MX6UL_PAD_UART4_RX_DATA__I2C1_SDA		0x4001b8b0
+		>;
+	};
+
+	mux_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6UL_PAD_UART5_TX_DATA__I2C2_SCL		0x4001f8a8
+			MX6UL_PAD_UART5_RX_DATA__I2C2_SDA		0x4001f8a8
+		>;
+	};
+
+	mux_uart: uartgrp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX		0x1b0b1
+			MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX		0x1b0b1
+		>;
+	};
+
+	mux_gpio_keys: gpiokeygrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11		0x3008
+			MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12		0x3008
+			MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13		0x3008
+			MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10		0x3008
+			MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09		0x3008
+			MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15		0x3008
+			MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08		0x3008
+			MX6UL_PAD_ENET2_TX_CLK__GPIO2_IO14		0x3008
+			MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03		0x3008
+			MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01		0x3008
+		>;
+	};
+
+	mux_led_ctrl: ledctrlgrp {
+		fsl,pins = <
+			MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02		0x3008
+		>;
+	};
+
+	mux_adc: adcgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO07__GPIO1_IO07		0xb0
+		>;
+	};
+
+	mux_pwm: pwm1grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO08__PWM1_OUT			0x110b0
+		>;
+	};
+
+	mux_backlight_enable: blenablegrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO09__GPIO1_IO09		0x3008
+		>;
+	};
+
+	mux_lcd_data: lcdifdatgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA00__LCDIF_DATA00		0x79
+			MX6UL_PAD_LCD_DATA01__LCDIF_DATA01		0x79
+			MX6UL_PAD_LCD_DATA02__LCDIF_DATA02		0x79
+			MX6UL_PAD_LCD_DATA03__LCDIF_DATA03		0x79
+			MX6UL_PAD_LCD_DATA04__LCDIF_DATA04		0x79
+			MX6UL_PAD_LCD_DATA05__LCDIF_DATA05		0x79
+			MX6UL_PAD_LCD_DATA06__LCDIF_DATA06		0x79
+			MX6UL_PAD_LCD_DATA07__LCDIF_DATA07		0x79
+			MX6UL_PAD_LCD_DATA08__LCDIF_DATA08		0x79
+			MX6UL_PAD_LCD_DATA09__LCDIF_DATA09		0x79
+			MX6UL_PAD_LCD_DATA10__LCDIF_DATA10		0x79
+			MX6UL_PAD_LCD_DATA11__LCDIF_DATA11		0x79
+			MX6UL_PAD_LCD_DATA12__LCDIF_DATA12		0x79
+			MX6UL_PAD_LCD_DATA13__LCDIF_DATA13		0x79
+			MX6UL_PAD_LCD_DATA14__LCDIF_DATA14		0x79
+			MX6UL_PAD_LCD_DATA15__LCDIF_DATA15		0x79
+			MX6UL_PAD_LCD_DATA16__LCDIF_DATA16		0x79
+			MX6UL_PAD_LCD_DATA17__LCDIF_DATA17		0x79
+		>;
+	};
+
+	mux_lcd_ctrl: lcdifctrlgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_CLK__LCDIF_CLK			0x79
+			MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE		0x79
+			MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC		0x79
+			MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC		0x79
+		>;
+	};
+
+	mux_csi: csi1grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK		0x1b088
+			MX6UL_PAD_CSI_VSYNC__CSI_VSYNC			0x1b088
+			MX6UL_PAD_CSI_HSYNC__CSI_HSYNC			0x1b088
+			MX6UL_PAD_CSI_DATA00__CSI_DATA02		0x1b088
+			MX6UL_PAD_CSI_DATA01__CSI_DATA03		0x1b088
+			MX6UL_PAD_CSI_DATA02__CSI_DATA04		0x1b088
+			MX6UL_PAD_CSI_DATA03__CSI_DATA05		0x1b088
+			MX6UL_PAD_CSI_DATA04__CSI_DATA06		0x1b088
+			MX6UL_PAD_CSI_DATA05__CSI_DATA07		0x1b088
+			MX6UL_PAD_CSI_DATA06__CSI_DATA08		0x1b088
+			MX6UL_PAD_CSI_DATA07__CSI_DATA09		0x1b088
+		>;
+	};
+
+	mux_gc0308: gc0308grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_MCLK__CSI_MCLK			0x1e038
+			MX6UL_PAD_GPIO1_IO05__GPIO1_IO05		0x1b088
+			MX6UL_PAD_GPIO1_IO06__GPIO1_IO06		0x1b088
+		>;
+	};
+
+
+	mux_spi3: ecspi3grp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI		0x100b1
+			MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK		0x100b1
+			MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20		0x3008
+		>;
+	};
+};
-- 
2.43.0



From martin.blumenstingl at googlemail.com  Sat Feb 24 13:35:29 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 24 Feb 2024 22:35:29 +0100
Subject: [PATCH v2] clocksource/drivers/arm_global_timer: Simplify prescaler register access
Message-ID: <20240224213529.2601333-1-martin.blumenstingl@googlemail.com>

Use GENMASK() to define the prescaler mask and make the whole driver use
the mask (together with helpers such as FIELD_{GET,PREP,FIT}) instead of
needing an additional shift and max value constant.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
Changes from v1 at [0]:
- use FIELD_FIT() to check whether psv overflows the register
- update the description accordingly


[0] https://lore.kernel.org/lkml/20240221214348.2299636-1-martin.blumenstingl at googlemail.com/


 drivers/clocksource/arm_global_timer.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index 8dd1e46b7176..49b094a20717 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -9,6 +9,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/bitfield.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/cpu.h>
@@ -31,10 +32,7 @@
 #define GT_CONTROL_COMP_ENABLE		BIT(1)	/* banked */
 #define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
 #define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
-#define GT_CONTROL_PRESCALER_SHIFT      8
-#define GT_CONTROL_PRESCALER_MAX        0xFF
-#define GT_CONTROL_PRESCALER_MASK       (GT_CONTROL_PRESCALER_MAX << \
-					 GT_CONTROL_PRESCALER_SHIFT)
+#define GT_CONTROL_PRESCALER_MASK	GENMASK(15, 8)
 
 #define GT_INT_STATUS	0x0c
 #define GT_INT_STATUS_EVENT_FLAG	BIT(0)
@@ -247,7 +245,7 @@ static void gt_write_presc(u32 psv)
 
 	reg = readl(gt_base + GT_CONTROL);
 	reg &= ~GT_CONTROL_PRESCALER_MASK;
-	reg |= psv << GT_CONTROL_PRESCALER_SHIFT;
+	reg |= FIELD_PREP(GT_CONTROL_PRESCALER_MASK, psv);
 	writel(reg, gt_base + GT_CONTROL);
 }
 
@@ -256,8 +254,7 @@ static u32 gt_read_presc(void)
 	u32 reg;
 
 	reg = readl(gt_base + GT_CONTROL);
-	reg &= GT_CONTROL_PRESCALER_MASK;
-	return reg >> GT_CONTROL_PRESCALER_SHIFT;
+	return FIELD_GET(GT_CONTROL_PRESCALER_MASK, reg);
 }
 
 static void __init gt_delay_timer_init(void)
@@ -272,9 +269,9 @@ static int __init gt_clocksource_init(void)
 	writel(0, gt_base + GT_COUNTER0);
 	writel(0, gt_base + GT_COUNTER1);
 	/* set prescaler and enable timer on all the cores */
-	writel(((CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) <<
-		GT_CONTROL_PRESCALER_SHIFT)
-	       | GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
+	writel(FIELD_PREP(GT_CONTROL_PRESCALER_MASK,
+			  CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) |
+	       GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
 
 #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 	sched_clock_register(gt_sched_clock_read, 64, gt_target_rate);
@@ -301,7 +298,7 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,
 		psv--;
 
 		/* prescaler within legal range? */
-		if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
+		if (psv < 0 || !FIELD_FIT(GT_CONTROL_PRESCALER_MASK, psv))
 			return NOTIFY_BAD;
 
 		/*
-- 
2.44.0



From daniel.lezcano at linaro.org  Sat Feb 24 13:55:19 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Sat, 24 Feb 2024 22:55:19 +0100
Subject: [PATCH v2] clocksource/drivers/arm_global_timer: Simplify
 prescaler register access
In-Reply-To: <20240224213529.2601333-1-martin.blumenstingl@googlemail.com>
References: <20240224213529.2601333-1-martin.blumenstingl@googlemail.com>
Message-ID: <eb54b791-05d7-4eee-825d-373cc78df689@linaro.org>

On 24/02/2024 22:35, Martin Blumenstingl wrote:
> Use GENMASK() to define the prescaler mask and make the whole driver use
> the mask (together with helpers such as FIELD_{GET,PREP,FIT}) instead of
> needing an additional shift and max value constant.
> 
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---
> Changes from v1 at [0]:
> - use FIELD_FIT() to check whether psv overflows the register
> - update the description accordingly
> 
> 
> [0] https://lore.kernel.org/lkml/20240221214348.2299636-1-martin.blumenstingl at googlemail.com/
> 
> 
>   drivers/clocksource/arm_global_timer.c | 19 ++++++++-----------
>   1 file changed, 8 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
> index 8dd1e46b7176..49b094a20717 100644
> --- a/drivers/clocksource/arm_global_timer.c
> +++ b/drivers/clocksource/arm_global_timer.c
> @@ -9,6 +9,7 @@
>   
>   #include <linux/init.h>
>   #include <linux/interrupt.h>
> +#include <linux/bitfield.h>
>   #include <linux/clocksource.h>
>   #include <linux/clockchips.h>
>   #include <linux/cpu.h>
> @@ -31,10 +32,7 @@
>   #define GT_CONTROL_COMP_ENABLE		BIT(1)	/* banked */
>   #define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
>   #define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
> -#define GT_CONTROL_PRESCALER_SHIFT      8
> -#define GT_CONTROL_PRESCALER_MAX        0xFF
> -#define GT_CONTROL_PRESCALER_MASK       (GT_CONTROL_PRESCALER_MAX << \
> -					 GT_CONTROL_PRESCALER_SHIFT)
> +#define GT_CONTROL_PRESCALER_MASK	GENMASK(15, 8)
>   
>   #define GT_INT_STATUS	0x0c
>   #define GT_INT_STATUS_EVENT_FLAG	BIT(0)
> @@ -247,7 +245,7 @@ static void gt_write_presc(u32 psv)
>   
>   	reg = readl(gt_base + GT_CONTROL);
>   	reg &= ~GT_CONTROL_PRESCALER_MASK;
> -	reg |= psv << GT_CONTROL_PRESCALER_SHIFT;
> +	reg |= FIELD_PREP(GT_CONTROL_PRESCALER_MASK, psv);
>   	writel(reg, gt_base + GT_CONTROL);
>   }
>   
> @@ -256,8 +254,7 @@ static u32 gt_read_presc(void)
>   	u32 reg;
>   
>   	reg = readl(gt_base + GT_CONTROL);
> -	reg &= GT_CONTROL_PRESCALER_MASK;
> -	return reg >> GT_CONTROL_PRESCALER_SHIFT;
> +	return FIELD_GET(GT_CONTROL_PRESCALER_MASK, reg);
>   }
>   
>   static void __init gt_delay_timer_init(void)
> @@ -272,9 +269,9 @@ static int __init gt_clocksource_init(void)
>   	writel(0, gt_base + GT_COUNTER0);
>   	writel(0, gt_base + GT_COUNTER1);
>   	/* set prescaler and enable timer on all the cores */
> -	writel(((CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) <<
> -		GT_CONTROL_PRESCALER_SHIFT)
> -	       | GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
> +	writel(FIELD_PREP(GT_CONTROL_PRESCALER_MASK,
> +			  CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) |
> +	       GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
>   
>   #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
>   	sched_clock_register(gt_sched_clock_read, 64, gt_target_rate);
> @@ -301,7 +298,7 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,
>   		psv--;
>   
>   		/* prescaler within legal range? */
> -		if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
> +		if (psv < 0 || !FIELD_FIT(GT_CONTROL_PRESCALER_MASK, psv))
>   			return NOTIFY_BAD;

Won't FIELD_FIT cover psv < 0 also ?


-- 
<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 martin.blumenstingl at googlemail.com  Sat Feb 24 14:13:58 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 24 Feb 2024 23:13:58 +0100
Subject: [PATCH v2] clocksource/drivers/arm_global_timer: Simplify
 prescaler register access
In-Reply-To: <eb54b791-05d7-4eee-825d-373cc78df689@linaro.org>
References: <20240224213529.2601333-1-martin.blumenstingl@googlemail.com> <eb54b791-05d7-4eee-825d-373cc78df689@linaro.org>
Message-ID: <CAFBinCB6+=PThAUz+BdfeD+DqCpscw3pSwrK2pue+J07vhPh_A@mail.gmail.com>

On Sat, Feb 24, 2024 at 10:55?PM Daniel Lezcano
<daniel.lezcano at linaro.org> wrote:
[...]
> > @@ -301,7 +298,7 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,
> >               psv--;
> >
> >               /* prescaler within legal range? */
> > -             if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
> > +             if (psv < 0 || !FIELD_FIT(GT_CONTROL_PRESCALER_MASK, psv))
> >                       return NOTIFY_BAD;
>
> Won't FIELD_FIT cover psv < 0 also ?
Hmm, I wanted to reply that it doesn't because internally FIELD_FIT()
uses a cast:
((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)
My original thought was that the cast would clear the sign bit when in
fact (I think) it will not - it will result in the signed number and
BIT(31) set.
So I think you're right, FIELD_FIT() does cover it.

However, there's something else odd with this code:
We're dividing two frequencies (using DIV_ROUND_CLOSEST) which are two
unsigned values. So the result of the division can never be negative:
  psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate);
However, we're additionally decrementing psv by one:
  psv--;
So in reality it can only ever be negative if the result of the
division was zero (for example if new_rate is smaller than
gt_target_rate).
However, in that case we would have crashed - with a division by zero
- in the statement right in the middle of the two mentioned above:
  if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)

So I think we need another patch (it's best to order that before this
one): make psv an unsigned int and error out before trying to divide
by zero.
If you have any objections: let me know, otherwise I'll prepare a
patch tomorrow.


Best regards,
Martin


From semen.protsenko at linaro.org  Sat Feb 24 15:59:22 2024
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 24 Feb 2024 17:59:22 -0600
Subject: [PATCH v3 12/12] spi: s3c64xx: switch exynos850 to new port
 config data
In-Reply-To: <10f692ae-ac7a-4243-aadc-80712f781d39@linaro.org>
References: <20240216070555.2483977-1-tudor.ambarus@linaro.org>
 <20240216070555.2483977-13-tudor.ambarus@linaro.org> <10f692ae-ac7a-4243-aadc-80712f781d39@linaro.org>
Message-ID: <CAPLW+4=PYEHC3+Am1=xjtERsGcXmLsVAH218JryecaJdw8ER6g@mail.gmail.com>

On Wed, Feb 21, 2024 at 11:56?AM Tudor Ambarus <tudor.ambarus at linaro.org> wrote:
>
>
> Hey, Sam,
>
>
> On 2/16/24 07:05, Tudor Ambarus wrote:
> > Exynos850 has the same version of USI SPI (v2.1) as GS101.
>
> I tested GS101 and it worked, I guess exynos850 SPI shall work too as it
> uses the same SPI version, v2.1. Can you run a test on your side too see
> if works? If not, Mark can drop this patch I guess. Please let us know
> your preference.
>

Tested the series on E850-96:
  * All 3 SPI instances were tested
  * Tested using loopback mode only
  * Used spidev_test tool + spidev devices in dts
  * Polling, IRQ and DMA transfers were tested
  * Works fine even with no SPI aliases in dts

Feel free to add:

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

Don't have time to review the patches right now, sadly.

[snip]


From festevam at gmail.com  Sat Feb 24 17:05:18 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Sat, 24 Feb 2024 22:05:18 -0300
Subject: [PATCH v4 06/16] dt-bindings: lcdif: Do not require power-domains
 for i.MX6ULL
In-Reply-To: <20240224213240.1854709-7-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org> <20240224213240.1854709-7-sre@kernel.org>
Message-ID: <CAOMZO5DWVaAp0sENeC0DoJvxfA-fCx3sjQW4Jjr5DJBb7AeuGw@mail.gmail.com>

On Sat, Feb 24, 2024 at 6:33?PM Sebastian Reichel <sre at kernel.org> wrote:
>
> i.MX6UL(L) uses "fsl,imx6sx-lcdif" as fallback compatible string,
> but has only very lightweight DISPLAY power domain. Its DISPLAY
> power domain is not supported by the binding / Linux kernel at
> the moment. Since the current setup is working, let's remove the
> power-domain from being required for that platform to fix the warning
> printed by CHECK_DTBS=y.

Thanks, this also fixes the following imx8mq warnings:

imx8mq-evk.dtb: lcd-controller at 30320000: 'power-domains' is a required property
from schema $id: http://devicetree.org/schemas/display/fsl,lcdif.yaml#

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From festevam at gmail.com  Sat Feb 24 17:11:03 2024
From: festevam at gmail.com (Fabio Estevam)
Date: Sat, 24 Feb 2024 22:11:03 -0300
Subject: [PATCH v4 16/16] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <20240224213240.1854709-17-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org> <20240224213240.1854709-17-sre@kernel.org>
Message-ID: <CAOMZO5CWQk8__qwHF8ysXnY4zAfd_FvW+Znd1sdoPc_uPJJE4A@mail.gmail.com>

On Sat, Feb 24, 2024 at 6:33?PM Sebastian Reichel <sre at kernel.org> wrote:

> +&gpio2 {
> +       /* configuring this to output-high results in poweroff */
> +       power-en-hog {
> +               gpio-hog;
> +               gpios = <6 GPIO_ACTIVE_HIGH>;
> +               line-name = "power-en-gpio";
> +               output-low;
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&mux_poweroff2>;
> +       };
> +};
> +
> +&ecspi3 {

It is recommended to put the nodes in alphabetical order (except
iomuxc, which is the last one).

> +       mux_gc0308: gc0308grp {
> +               fsl,pins = <
> +                       MX6UL_PAD_CSI_MCLK__CSI_MCLK                    0x1e038
> +                       MX6UL_PAD_GPIO1_IO05__GPIO1_IO05                0x1b088
> +                       MX6UL_PAD_GPIO1_IO06__GPIO1_IO06                0x1b088
> +               >;
> +       };
> +
> +

There is an extra blank line here.

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From takakura at valinux.co.jp  Sat Feb 24 18:18:12 2024
From: takakura at valinux.co.jp (takakura at valinux.co.jp)
Date: Sun, 25 Feb 2024 11:18:12 +0900
Subject: [PATCH] arm64/kernel/setup: Update comment on interrupt masking
Message-ID: <20240225021812.4834-1-takakura@valinux.co.jp>

From: Ryo Takakura <takakura at valinux.co.jp>

DAIF_PROCCTX_NOIRQ contains FIQ bit.
Update the comment as only asynchronous aborts are unmasked
and FIQ is still masked.

Signed-off-by: Ryo Takakura <takakura at valinux.co.jp>
---
 arch/arm64/kernel/setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 0ea45b6d0177..9b9fdb64c684 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -298,7 +298,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 	dynamic_scs_init();
 
 	/*
-	 * Unmask asynchronous aborts and fiq after bringing up possible
+	 * Unmask asynchronous aborts after bringing up possible
 	 * earlycon. (Report possible System Errors once we can report this
 	 * occurred).
 	 */
-- 
2.34.1



From andersson at kernel.org  Sat Feb 24 18:52:04 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 24 Feb 2024 20:52:04 -0600
Subject: [GIT PULL] Qualcomm ARM64 DeviceTree fixes for 6.8
Message-ID: <20240225025205.479589-1-andersson@kernel.org>


The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-arm64-fixes-for-6.8

for you to fetch changes up to cb0bbdc4cc327ee91ba21ff744adbe07885db2b8:

  arm64: dts: qcom: sm6115: Fix missing interconnect-names (2024-02-03 11:37:47 -0600)

----------------------------------------------------------------
Qualcomm ARM64 DeviceTree fixes for 6.8

This marks an additional GPIO as protected on SM8650 devices, to avoid
a system reset caused by a security violation with some firmware
versions.

It also adds the missing interconnect-names, which resolves a regression
where one of the I2C busses on SM6115 devices would no longer probe in
Linux.

----------------------------------------------------------------
Konrad Dybcio (1):
      arm64: dts: qcom: sm6115: Fix missing interconnect-names

Neil Armstrong (2):
      arm64: dts: qcom: sm8650-qrd: add gpio74 as reserved gpio
      arm64: dts: qcom: sm8650-mtp: add gpio74 as reserved gpio

 arch/arm64/boot/dts/qcom/sm6115.dtsi    | 3 +++
 arch/arm64/boot/dts/qcom/sm8650-mtp.dts | 2 +-
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts | 2 +-
 3 files changed, 5 insertions(+), 2 deletions(-)


From andersson at kernel.org  Sat Feb 24 19:06:11 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 24 Feb 2024 21:06:11 -0600
Subject: [GIT PULL] Qualcomm driver updates for v6.9
Message-ID: <20240225030612.480241-1-andersson@kernel.org>


The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-drivers-for-6.9

for you to fetch changes up to aa05f47474c02d38d88c32c633a551911c6fdc40:

  dt-bindings: soc: qcom: qcom,saw2: add msm8226 l2 compatible (2024-02-18 22:52:55 -0600)

----------------------------------------------------------------
Qualcomm driver updates for v6.9

This introduces the Qualcomm Programmable Boot Sequencer (PBS) driver.

The Qualcomm SMEM no longer acquires the hwspinlock during the "get"
operation, to improve the system behavior during the recovery of a
remoteproc that crashed with the hwspinlock held.

The Qualcomm Always On Subsystem (AOSS) message protocol driver gains
tracepoints, printf annotation, and a debugfs interface is introduced
for tweaking system properties during development and debugging.

The Qualcomm socinfo driver gains data for SM8475, QCM8550 and
QCS8550 platforms, and the PM2250 is renamed to PM4125.

Support for controlling the voltage regulator in SPM/SAW2 is introduced.

The gfx.lvl power-domain is dropped for SA8540P, as this resource was
incorrectly inherited from SC8280XP.

Additionally some code cleanup improvements is introduced across APR,
LLCC, SMP2P and SPM.

----------------------------------------------------------------
Abel Vesa (1):
      dt-bindings: soc: qcom: qcom,pmic-glink: document X1E80100 compatible

Anjelique Melendez (2):
      dt-bindings: soc: qcom: Add qcom,pbs bindings
      soc: qcom: add QCOM PBS driver

Bjorn Andersson (5):
      soc: qcom: aoss: Mark qmp_send() __printf()
      soc: qcom: aoss: Add debugfs interface for sending messages
      soc: qcom: aoss: Add tracepoints in qmp_send()
      pmdomain: qcom: rpmhpd: Drop SA8540P gfx.lvl
      Merge branch '20240201204421.16992-2-quic_amelende at quicinc.com' into drivers-for-6.9

Danila Tikhonov (2):
      dt-bindings: arm: qcom,ids: Add IDs for SM8475 family
      soc: qcom: socinfo: Add Soc IDs for SM8475 family

Dmitry Baryshkov (6):
      soc: qcom: socinfo: rename PM2250 to PM4125
      dt-bindings: soc: qcom: merge qcom,saw2.txt into qcom,spm.yaml
      dt-bindings: soc: qcom: qcom,saw2: add missing compatible strings
      dt-bindings: soc: qcom: qcom,saw2: define optional regulator node
      soc: qcom: spm: remove driver-internal structures from the driver API
      soc: qcom: spm: add support for voltage regulator

Luca Weiss (1):
      dt-bindings: soc: qcom: qcom,saw2: add msm8226 l2 compatible

Randy Dunlap (1):
      soc: qcom: smp2p: fix all kernel-doc warnings

Ricardo B. Marliere (1):
      soc: qcom: apr: make aprbus const

Rob Herring (1):
      dt-bindings: soc/qcom: Add size constraints on "qcom,rpm-msg-ram"

Tao Zhang (1):
      soc: qcom: smem: remove hwspinlock from item get routine

Tengfei Fan (2):
      dt-bindings: arm: qcom,ids: add SoC ID for QCM8550 and QCS8550
      soc: qcom: socinfo: add SoC Info support for QCM8550 and QCS8550 platform

Unnathi Chalicheemala (1):
      soc: qcom: llcc: Check return value on Broadcast_OR reg read

 .../devicetree/bindings/arm/msm/qcom,saw2.txt      |  58 -----
 .../devicetree/bindings/soc/qcom/qcom,pbs.yaml     |  46 ++++
 .../bindings/soc/qcom/qcom,pmic-glink.yaml         |   2 +
 .../bindings/soc/qcom/qcom,rpm-master-stats.yaml   |   2 +
 .../soc/qcom/{qcom,spm.yaml => qcom,saw2.yaml}     |  46 +++-
 drivers/pmdomain/qcom/rpmhpd.c                     |   1 -
 drivers/soc/qcom/Kconfig                           |   9 +
 drivers/soc/qcom/Makefile                          |   2 +
 drivers/soc/qcom/apr.c                             |   2 +-
 drivers/soc/qcom/llcc-qcom.c                       |   2 +
 drivers/soc/qcom/qcom-pbs.c                        | 236 +++++++++++++++++++
 drivers/soc/qcom/qcom_aoss.c                       | 103 ++++++++-
 drivers/soc/qcom/smem.c                            |  11 -
 drivers/soc/qcom/smp2p.c                           |   6 +-
 drivers/soc/qcom/socinfo.c                         |   7 +-
 drivers/soc/qcom/spm.c                             | 254 ++++++++++++++++++++-
 drivers/soc/qcom/trace-aoss.h                      |  48 ++++
 include/dt-bindings/arm/qcom,ids.h                 |   5 +
 include/linux/soc/qcom/apr.h                       |   2 +-
 include/linux/soc/qcom/qcom-pbs.h                  |  30 +++
 include/soc/qcom/qcom-spmi-pmic.h                  |   2 +-
 include/soc/qcom/spm.h                             |  23 +-
 22 files changed, 787 insertions(+), 110 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
 create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,pbs.yaml
 rename Documentation/devicetree/bindings/soc/qcom/{qcom,spm.yaml => qcom,saw2.yaml} (53%)
 create mode 100644 drivers/soc/qcom/qcom-pbs.c
 create mode 100644 drivers/soc/qcom/trace-aoss.h
 create mode 100644 include/linux/soc/qcom/qcom-pbs.h


From shawnguo2 at yeah.net  Sat Feb 24 19:20:45 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 11:20:45 +0800
Subject: [PATCH] arm64: dts: imx8mp-beacon: Enable Bluetooth
In-Reply-To: <20240211131116.66490-1-aford173@gmail.com>
References: <20240211131116.66490-1-aford173@gmail.com>
Message-ID: <ZdqyDTIUsz49TefQ@dragon>

On Sun, Feb 11, 2024 at 07:11:16AM -0600, Adam Ford wrote:
> The imx8mp-beacon SOM has wireless chip supporting Wi-Fi and
> Bluetooth shared.  The Wi-Fi is already enabled via the SDIO
> interface, so enable the Bluetooth via UART1.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sat Feb 24 19:21:02 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 11:21:02 +0800
Subject: [PATCH] arm64: dts: imx8mp-beacon: Configure multiple queues on
 eqos
In-Reply-To: <20240211135535.68516-1-aford173@gmail.com>
References: <20240211135535.68516-1-aford173@gmail.com>
Message-ID: <ZdqyHj+A+BbPJMW9@dragon>

On Sun, Feb 11, 2024 at 07:55:34AM -0600, Adam Ford wrote:
> The imx8mp-beacon SOM has an integrated PHY connected to
> the EQOS ethernet controller which can support up to five
> queues.  Configure these queues in the same manor as done
> on the imx8mp-evk.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sat Feb 24 19:22:12 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 11:22:12 +0800
Subject: [PATCH] arm64: dts: imx8mn: Slow default video_pll clock rate
In-Reply-To: <20240211231508.188567-1-aford173@gmail.com>
References: <20240211231508.188567-1-aford173@gmail.com>
Message-ID: <ZdqyZCudSlazj7gW@dragon>

On Sun, Feb 11, 2024 at 05:15:08PM -0600, Adam Ford wrote:
> Since commit 8208181fe536 ("clk: imx: composite-8m:
> Add imx8m_divider_determine_rate") the lcdif controller has
> had the ability to set the disp_pixel_clk rate which propagates
> up the tree and sets the video_pll rate automatically.
> 
> By setting this value low, it will force the recalculation of
> video_pll to the lowest rate needed by lcdif instead of
> dividing a larger clock down to the desired clock speed. This
> has the  advantage of being able to lower the video_pll rate
> from 594MHz to 148.5MHz when operating at 1080p. It can go even
> lower when operating at lower resolutions and refresh rates.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sat Feb 24 19:23:24 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 11:23:24 +0800
Subject: [PATCH] arm64: dts: imx8mn-beacon: Remove unnecessary clock
 configuration
In-Reply-To: <20240211231802.188843-1-aford173@gmail.com>
References: <20240211231802.188843-1-aford173@gmail.com>
Message-ID: <ZdqyrKQAVCwSsZ6e@dragon>

On Sun, Feb 11, 2024 at 05:18:02PM -0600, Adam Ford wrote:
> Since commit 8208181fe536 ("clk: imx: composite-8m:
> Add imx8m_divider_determine_rate") the lcdif controller has
> had the ability to set the disp_pixel_clk rate which propagates
> up the tree and sets the video_pll rate automatically.
> 
> As such, there is no need to define it in the board file.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Applied, thanks!



From andersson at kernel.org  Sat Feb 24 19:24:53 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 24 Feb 2024 21:24:53 -0600
Subject: [GIT PULL] Qualcomm ARM64 defconfig updates for v6.9
Message-ID: <20240225032456.481112-1-andersson@kernel.org>


The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-arm64-defconfig-for-6.9

for you to fetch changes up to 9c5c14c066f353ac1f4e3b4dd6e19451eac61e0c:

  arm64: defconfig: Enable QCOM PBS (2024-02-16 14:32:49 -0600)

----------------------------------------------------------------
Qualcomm ARM64 defconfig updates for v6.9

Enable the Qualcomm PBS driver to resolve the dependency from the Light
Pulse Generator (LED-driver) on modern Qualcomm platforms. Enable the
X1E multimedia clock controllers, to provide clocks for the various
multimedia blocks. Enable Global clock controller and interconnect
drivers for the QDU1000/QRU1000 platforms.

Enable the audio drivers and the Goodi Berlin touchscreen driver, used
on SM8650 QRD.

Enable the MAX20411 regulator driver drive the GPU rail on SA8295P.

Lastly mark the Qualcomm interconnect providers that feeds UART
instances as builtin, to ensure the console exists when userspace is
launched.

----------------------------------------------------------------
Abel Vesa (1):
      arm64: defconfig: Enable X1E80100 multimedia clock controllers configs

Bjorn Andersson (2):
      arm64: defconfig: Enable MAX20411 regulator driver
      arm64: defconfig: Enable Qualcomm interconnect providers

Komal Bajaj (1):
      arm64: defconfig: Enable GCC and interconnect for QDU1000/QRU1000

Luca Weiss (1):
      arm64: defconfig: Enable QCOM PBS

Neil Armstrong (3):
      arm64: defconfig: enable audio drivers for SM8650 QRD board
      arm64: defconfig: enable WCD939x USBSS driver as module
      arm64: deconfig: enable Goodix Berlin SPI touchscreen driver as module

 arch/arm64/configs/defconfig | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)


From marex at denx.de  Sat Feb 24 19:33:42 2024
From: marex at denx.de (Marek Vasut)
Date: Sun, 25 Feb 2024 04:33:42 +0100
Subject: [PATCH] arm64: dts: imx8mp: Fix TC9595 reset GPIO on DH i.MX8M Plus DHCOM SoM
Message-ID: <20240225033359.416169-1-marex@denx.de>

The TC9595 reset GPIO is SAI1_RXC / GPIO4_IO01, fix the DT accordingly.
The SAI5_RXD0 / GPIO3_IO21 is thus far unused TC9595 interrupt line.

Fixes: 20d0b83e712b ("arm64: dts: imx8mp: Add TC9595 bridge on DH electronics i.MX8M Plus DHCOM")
Signed-off-by: Marek Vasut <marex at denx.de>
---
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: Fabio Estevam <festevam at gmail.com>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt at linaro.org>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
Cc: Rob Herring <robh at kernel.org>
Cc: Sascha Hauer <s.hauer at pengutronix.de>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: devicetree at vger.kernel.org
Cc: kernel at dh-electronics.com
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
index d8963f32ec84c..1f3fbfb9749d3 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
@@ -255,7 +255,7 @@ tc_bridge: bridge at f {
 				  <&clk IMX8MP_AUDIO_PLL2_OUT>;
 		assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>;
 		assigned-clock-rates = <13000000>, <13000000>, <156000000>;
-		reset-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio4 1 GPIO_ACTIVE_HIGH>;
 		status = "disabled";
 
 		ports {
-- 
2.43.0



From shawnguo2 at yeah.net  Sat Feb 24 19:38:34 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 11:38:34 +0800
Subject: [PATCH v1] ARM: dts: imx7: remove DSI port endpoints
In-Reply-To: <20240223171901.GA22584@francesco-nb>
References: <20240216104255.21052-1-francesco@dolcini.it>
 <20240223171901.GA22584@francesco-nb>
Message-ID: <Zdq2OhFYa7BOhXxt@dragon>

On Fri, Feb 23, 2024 at 06:19:01PM +0100, Francesco Dolcini wrote:
> On Fri, Feb 16, 2024 at 11:42:55AM +0100, Francesco Dolcini wrote:
> > From: Francesco Dolcini <francesco.dolcini at toradex.com>
> > 
> > This fixes the display not working on colibri imx7, the driver fails to
> > load with the following error:
> > 
> >   mxsfb 30730000.lcdif: error -ENODEV: Cannot connect bridge
> > 
> > NXP i.MX7 LCDIF is connected to both the Parallel LCD Display and to a
> > MIPI DSI IP block, currently it's not possible to describe the
> > connection to both.
> > 
> > Remove the port endpoint from the SOC dtsi to prevent regressions, this
> > would need to be defined on the board DTS.
> > 
> > Reported-by: Hiago De Franco <hiagofranco at gmail.com>
> > Closes: https://lore.kernel.org/r/34yzygh3mbwpqr2re7nxmhyxy3s7qmqy4vhxvoyxnoguktriur at z66m7gvpqlia/
> > Fixes: edbbae7fba49 ("ARM: dts: imx7: add MIPI-DSI support")
> > Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
> 
> Hello Shawn, what do you plan to do with this?
> 
> This fixes a regression from v6.8-rc1 and would be nice to have it into
> the final v6.8.

Applied as a fix for 6.8, thanks!



From andersson at kernel.org  Sat Feb 24 21:01:45 2024
From: andersson at kernel.org (Bjorn Andersson)
Date: Sat, 24 Feb 2024 23:01:45 -0600
Subject: [GIT PULL] Qualcomm ARM64 DeviceTree updates for v6.9
Message-ID: <20240225050146.484422-1-andersson@kernel.org>


The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-arm64-for-6.9

for you to fetch changes up to f176168bcb95bd1fdd32f5a794e68b7a36ac8740:

  arm64: dts: qcom: sm6115: fix USB PHY configuration (2024-02-20 11:54:53 -0600)

----------------------------------------------------------------
Qualcomm ARM64 DeviceTree updates for v6.9

Four variants of Samsung Galaxy Core Prime and Grand Prime, built on
MSM8916, and the Hardware Development Kit (HDK) for SM8550, are
introduced.

On X Elite audio and compute remoteprocs, IPCC, PCIe, AOSS QMP, SMP2P,
TCSR, USB, display, audio, and soundwire support is introduced, and
enabled across the CRD and QCP devices.

For SM8650 PCIe controllers are moved to GIC-ITS and msi-map-mask is
defined. Missing qlink-logging reserved-memory region is added for the
modem remoteproc. FastRPC compute contexts are marked dma-coherent.
Audio, USB Type-C and PM8010 support is introduced across MTP and QRD
devices.

GPU cooling devices are hooked up across MSM8916, MSM8939, SC8180X,
SDM630, SDM845, SM6115, SM8150, SM8250, SM8350, and SM8550.

UFS PHY clocks are corrected across MSM8996, MSM8998, SC8180X, SC8280XP,
SDM845, SM6115, SM6125, SM8150, SM8250, SM8350, SM8550, and SM8650.

PCI MSI interrupts are wired up across SM8150, SM8250, SM8350, SM8450,
SM8550, SM8650, SC7280, and SC8180X

On IPQ6018 QUP5 I2C, tsens sand thermal zones are defined. The Inline
Crypto Engine (ICE) is enabled for IPQ9574.

On MSM8953 the GPU and its IOMMU is introduced, the reset for the
display subsystem is also wired up.

VLS CLAMP registers are specified for USB3 PHYs on MSM8998, QCM2290, and
SM6115.

USB Type-C port management is enabled on QRB4210 RB2.

On the SA8295P ADP the MAX20411 regulator powering the GPU rails is
introduced and the GPU is enabled. The first PCI instance on SA8540P
Ride is disabled for now, as a fix for the interrupt storm produced here
has not been presented.

On SA8775P the firmware memory map has changed and is updated. Safety
IRQ is added to the Ethernet controller.

On SC7180 UFS support is introduced and the cros-ec-spi is marked as
wakeup source.

For SC7280 capacity and DPC properties are added, cryptobam definition
is improved to work in more firmware environments, more Chrome-specific
properties are moved out from main dtsi, and cros-ec-spi is maked as a
wakeup source. Slimbus definition is added to the platform.

A missing reserved-memory range is added to Fairphone FP5, PMIC GLINK
and Venus are enabled. LEDs are introduced and voltage settings
corrected on the QCM6490 IDP, and RB3gen2 sees the same voltage changes
and GCC protected clocks are introduced to make the board boot properly.

RPMh sleep stats and a variety of cleanups and fixes are introduced for
SC8180X.

On SC8280XP the additional tsens instances are introduced. Camera
Subsystem and Camera Control Interface (CCI) are added. PMIC die-temp
vadc channels are introduced on the CRD, to allow ADC channels to be
tied to the shared PMIC temp-alarms, to actually report temperature.

On SDM630 USB QMP PHY support is introduced and enabled on the Inforce
IFC6560 board. On the various Sony Xperia XA2 variants WLED is enabled
and configured.

On SM6350 display subsystem interconnects and tsens-based thermal zones
are added. On SM7125 UFS support is added.

On Fairphone FP4, on SM7225, display and GPU are enabled, and firmware
paths are corrected.

SM8150 PCIe controller definitions are corrected.

As with SM8650, the SM8550 the fastrpc compute contexts are marked
dm-coherent, and PCIe controllers are moved to use GIC-ITS. The UFS
controller frequency definition is moved to the generic opp-table.
Touchscreen is enabled on the QRD device.

As usual, a variety of smaller cleanups and corrections to match
DeviceTree bindings and style guidelines are introduced across the
various files.

----------------------------------------------------------------
Abel Vesa (9):
      dt-bindings: clock: Drop the SM8650 DISPCC dedicated schema
      dt-bindings: clock: qcom: Document the X1E80100 TCSR Clock Controller
      arm64: dts: qcom: x1e80100: Add TCSR node
      arm64: dts: qcom: x1e80100: Add USB nodes
      arm64: dts: qcom: x1e80100: Add PCIe nodes
      arm64: dts: qcom: x1e80100: Add display nodes
      arm64: dts: qcom: x1e80100-crd: Enable more support
      arm64: dts: qcom: x1e80100-qcp: Enable more support
      arm64: dts: qcom: x1e80100-qcp: Fix supplies for LDOs 3E and 2J

Ankit Sharma (1):
      arm64: dts: qcom: sc7280: Add capacity and DPC properties

Bjorn Andersson (10):
      arm64: dts: qcom: sa8540p: Drop gfx.lvl as power-domain for gpucc
      arm64: dts: qcom: sa8295p-adp: add max20411
      arm64: dts: qcom: sa8295p-adp: Enable GPU
      Merge branch '20240202-x1e80100-clock-controllers-v4-5-7fb08c861c7c at linaro.org' into arm64-for-6.9
      Merge branch '20240125-msm8953-mdss-reset-v2-1-fd7824559426 at z3ntu.xyz' into arm64-for-6.9
      Merge branch '20240131-ufs-phy-clock-v3-3-58a49d2f4605 at linaro.org' into HEAD
      arm64: dts: qcom: sc8280xp: Introduce additional tsens instances
      arm64: dts: qcom: sc8280xp-crd: Add PMIC die-temp vadc channels
      arm64: dts: qcom: sc8280xp-pmics: Define adc for temp-alarms
      arm64: dts: qcom: qcs6490-rb3gen2: Declare GCC clocks protected

Bryan O'Donoghue (2):
      arm64: dts: qcom: sc8280xp: camss: Add CCI definitions
      arm64: dts: qcom: sc8280xp: camss: Add CAMSS block definition

Christian Marangi (1):
      arm64: dts: qcom: ipq8074: add clock-frequency to MDIO node

David Heidelberg (1):
      arm64: dts: qcom: sdm845-oneplus-common: improve DAI node naming

David Wronek (3):
      dt-bindings: arm: qcom: Add Xiaomi Redmi Note 9S
      arm64: dts: qcom: sc7180: Add UFS nodes
      arm64: dts: qcom: sm7125-xiaomi-common: Add UFS nodes

Dmitry Baryshkov (12):
      arm64: dts: qcom: rename PM2250 to PM4125
      arm64: dts: qcom: sdm630: add USB QMP PHY support
      arm64: dts: qcom: sda660-ifc6560: enable USB 3.0 PHY
      dt-bindings: arm: qcom: drop the superfluous device compatibility schema
      arm64: dts: qcom: msm8998: declare VLS CLAMP register for USB3 PHY
      arm64: dts: qcom: qcm2290: declare VLS CLAMP register for USB3 PHY
      arm64: dts: qcom: sm6115: declare VLS CLAMP register for USB3 PHY
      arm64: dts: qcom: qrb2210-rb1: disable cluster power domains
      arm64: dts: qcom: pmi632: define USB-C related blocks
      arm64: dts: qcom: qrb4210-rb2: enable USB-C port handling
      arm64: dts: qcom: pm4125: define USB-C related blocks
      arm64: dts: qcom: sm6115: fix USB PHY configuration

Fenglin Wu (2):
      arm64: dts: qcom: sm8650-mtp: add PM8010 regulators
      arm64: dts: qcom: sm8650-qrd: add PM8010 regulators

Hui Liu (1):
      arm64: dts: qcom: qcm6490-idp: Add definition for three LEDs

Isaev Ruslan (1):
      arm64: dts: qcom: ipq6018: add QUP5 I2C node

Joe Mason (2):
      arm64: dts: qcom: Add support for Xiaomi Redmi Note 9S
      arm64: dts: qcom: msm8916-samsung-fortuna/rossa: Add fuel gauge

Komal Bajaj (2):
      arm64: dts: qcom: qcm6490-idp: Correct the voltage setting for vph_pwr
      arm64: dts: qcom: qcs6490-rb3gen2: Correct the voltage setting for vph_pwr

Konrad Dybcio (27):
      dt-bindings: clock: gcc-sc8180x: Add the missing CX power domain
      arm64: dts: qcom: sc8180x: Hook up VDD_CX as GCC parent domain
      arm64: dts: qcom: sc8180x: Fix up big CPU idle state entry latency
      arm64: dts: qcom: sc8180x: Add missing CPU off state
      arm64: dts: qcom: sc8180x: Fix eDP PHY power-domains
      arm64: dts: qcom: sc8180x: Don't hold MDP core clock at FMAX
      arm64: dts: qcom: sc8180x: Require LOW_SVS vote for MMCX if DISPCC is on
      arm64: dts: qcom: sc8180x: Add missing CPU<->MDP_CFG path
      arm64: dts: qcom: sc8180x: Shrink aoss_qmp register space size
      arm64: dts: qcom: sc8180x: Add RPMh sleep stats
      arm64: dts: qcom: x1e80100: Add missing system-wide PSCI power domain
      arm64: dts: qcom: x1e80100: Flush RSC sleep & wake votes
      arm64: dts: qcom: msm8916: Hook up GPU cooling device
      arm64: dts: qcom: msm8939: Hook up GPU cooling device
      arm64: dts: qcom: sc8180x: Hook up GPU cooling device
      arm64: dts: qcom: sdm845: Hook up GPU cooling device
      arm64: dts: qcom: sm6115: Hook up GPU cooling device
      arm64: dts: qcom: sm6115: Mark GPU @ 125C critical
      arm64: dts: qcom: sm8150: Hook up GPU cooling device
      arm64: dts: qcom: sm8250: Hook up GPU cooling device
      arm64: dts: qcom: sm8350: Hook up GPU cooling device
      arm64: dts: qcom: sm8450: Hook up GPU cooling device
      arm64: dts: qcom: sm8550: Hook up GPU cooling device
      arm64: dts: qcom: sdm630: Hook up GPU cooling device
      arm64: dts: qcom: sm8450: Add missing interconnects to serial
      arm64: dts: qcom: sdm845: Use the Low Power Island CX/MX for SLPI
      arm64: dts: qcom: sm8550: Switch UFS from opp-table-hz to opp-v2

Krishna Kurapati (4):
      arm64: dts: qcom: Fix hs_phy_irq for QUSB2 targets
      arm64: dts: qcom: Fix hs_phy_irq for non-QUSB2 targets
      arm64: dts: qcom: Fix hs_phy_irq for SDM670/SDM845/SM6350
      arm64: dts: qcom: Add missing interrupts for qcs404/ipq5332

Krishna chaitanya chundru (1):
      arm64: dts: qcom: sc7280: Add additional MSI interrupts

Krzysztof Kozlowski (32):
      arm64: dts: qcom: x1e80100: drop qcom,drv-count
      arm64: dts: qcom: sm8150: add necessary ref clock to PCIe
      arm64: dts: qcom: sm8450-hdk: correct AMIC4 and AMIC5 microphones
      arm64: dts: qcom: sm8150: describe all PCI MSI interrupts
      arm64: dts: qcom: sm8250: describe all PCI MSI interrupts
      arm64: dts: qcom: sm8350: describe all PCI MSI interrupts
      arm64: dts: qcom: sm8450: describe all PCI MSI interrupts
      arm64: dts: qcom: sm8550: describe all PCI MSI interrupts
      arm64: dts: qcom: sm8650: describe all PCI MSI interrupts
      arm64: dts: qcom: split PCIe interrupt-names entries per lines
      arm64: dts: qcom: x1e80100: add ADSP GPR
      arm64: dts: qcom: x1e80100: add LPASS LPI pin controller
      arm64: dts: qcom: x1e80100: add ADSP audio codec macros
      arm64: dts: qcom: x1e80100: add Soundwire controllers
      arm64: dts: qcom: x1e80100-crd: add WCD9385 Audio Codec
      arm64: dts: qcom: x1e80100-crd: add WSA8845 speakers
      arm64: dts: qcom: sm8550-qrd: correct WCD9385 TX port mapping
      arm64: dts: qcom: sm8550-mtp: correct WCD9385 TX port mapping
      arm64: dts: qcom: sm8550-qrd: add correct analogue microphones
      arm64: dts: qcom: sm8550-mtp: add correct analogue microphones
      arm64: dts: sc8280xp: correct DMIC2 and DMIC3 pin config node names
      arm64: dts: sm8450: correct DMIC2 and DMIC3 pin config node names
      arm64: dts: sm8550: correct DMIC2 and DMIC3 pin config node names
      arm64: dts: sm8650: correct DMIC2 and DMIC3 pin config node names
      arm64: dts: x1e80100: correct DMIC2 and DMIC3 pin config node names
      arm64: dts: qcom: x1e80100-crd: add sound card
      arm64: dts: qcom: ssm7125-xiaomi: drop incorrect UFS phy max current
      arm64: dts: qcom: minor whitespace cleanup
      arm64: dts: qcom: sc8180x: describe all PCI MSI interrupts
      arm64: dts: qcom: sdm845-db845c: correct PCIe wake-gpios
      arm64: dts: qcom: sm8150: correct PCIe wake-gpios
      arm64: dts: qcom: replace underscores in node names

Ling Xu (2):
      arm64: dts: qcom: sm8550: Add dma-coherent property
      arm64: dts: qcom: sm8650: Add dma-coherent property

Luca Weiss (11):
      arm64: dts: qcom: sc7280: Move video-firmware to chrome-common
      arm64: dts: qcom: qcm6490-fairphone-fp5: Enable venus node
      arm64: dts: qcom: sc7280: Add static properties to cryptobam
      arm64: dts: qcom: qcm6490-fairphone-fp5: Add missing reserved-memory
      arm64: dts: qcom: qcm6490-fairphone-fp5: Add PMIC GLINK
      arm64: dts: qcom: sm7225-fairphone-fp4: Switch firmware ext to .mbn
      arm64: dts: qcom: sm6350: Add tsens thermal zones
      arm64: dts: qcom: sm6350: Add interconnect for MDSS
      arm64: dts: qcom: sm6350: Remove "disabled" state of GMU
      arm64: dts: qcom: sm7225-fairphone-fp4: Enable display and GPU
      arm64: dts: qcom: pmi632: Add PBS client and use in LPG node

Lucas Karpinski (1):
      arm64: dts: qcom: sa8540p-ride: disable pcie2a node

Manivannan Sadhasivam (15):
      dt-bindings: clock: qcom: Add missing UFS QREF clocks
      arm64: dts: qcom: msm8996: Fix UFS PHY clocks
      arm64: dts: qcom: msm8998: Fix UFS PHY clocks
      arm64: dts: qcom: sdm845: Fix UFS PHY clocks
      arm64: dts: qcom: sm6115: Fix UFS PHY clocks
      arm64: dts: qcom: sm6125: Fix UFS PHY clocks
      arm64: dts: qcom: sm6350: Fix UFS PHY clocks
      arm64: dts: qcom: sm8150: Fix UFS PHY clocks
      arm64: dts: qcom: sm8250: Fix UFS PHY clocks
      arm64: dts: qcom: sc8180x: Fix UFS PHY clocks
      arm64: dts: qcom: sc8280xp: Fix UFS PHY clocks
      arm64: dts: qcom: sm8350: Fix UFS PHY clocks
      arm64: dts: qcom: sm8550: Fix UFS PHY clocks
      arm64: dts: qcom: sm8650: Fix UFS PHY clocks
      arm64: dts: sm8650: Add msi-map-mask for PCIe nodes

Mantas Pucka (2):
      arm64: dts: qcom: ipq6018: add tsens node
      arm64: dts: qcom: ipq6018: add thermal zones

Marijn Suijten (1):
      arm64: dts: qcom: sdm630-nile: Enable and configure PM660L WLED

Mark Hasemeyer (3):
      arm64: dts: qcom: sc7180: Enable cros-ec-spi as wake source
      arm64: dts: qcom: sc7280: Enable cros-ec-spi as wake source
      arm64: dts: qcom: sdm845: Enable cros-ec-spi as wake source

Maulik Shah (1):
      arm64: dts: qcom: sc7280: Update domain-idle-states for cluster sleep

Neil Armstrong (10):
      dt-bindings: arm: qcom: Document the HDK8550 board
      arm64: dts: qcom: sm8550: add support for the SM8550-HDK board
      arm64: dts: qcom: sm8550-qrd: enable Touchscreen
      arm64: dts: qcom: sm8650-qrd: add USB-C Altmode Support
      arm64: dts: qcom: sm8650: Use GIC-ITS for PCIe0 and PCIe1
      arm64: dts: qcom: sm8650: add missing qlink_logging reserved memory for mpss
      arm64: dts: qcom: sm8650-qrd: add Audio nodes
      arm64: dts: qcom: sm8650-mtp: add Audio sound card node
      arm64: dts: qcom: sm8550-hdk: correct WCD9385 route and port mapping
      arm64: dts: qcom: sm8550: Use GIC-ITS for PCIe0 and PCIe1

Ninad Naik (1):
      arm64: dts: qcom: sa8775p: Add new memory map updates to SA8775P

Rajendra Nayak (3):
      dt-bindings: clock: qcom: Document the X1E80100 Display Clock Controller
      dt-bindings: clock: qcom: Document the X1E80100 GPU Clock Controller
      dt-bindings: clock: qcom: Document the X1E80100 Camera Clock Controller

Raymond Hackley (1):
      dt-bindings: qcom: Document new msm8916-samsung devices

Sibi Sankar (4):
      arm64: dts: qcom: x1e80100: Add IPCC node
      arm64: dts: qcom: x1e80100: Add SMP2P nodes
      arm64: dts: qcom: x1e80100: Add QMP AOSS node
      arm64: dts: qcom: x1e80100: Add ADSP/CDSP remoteproc nodes

Stefan Hansson (1):
      dt-bindings: arm: qcom: Add Samsung Galaxy Tab 4 10.1 LTE

Stephan Gerhold (1):
      arm64: dts: qcom: apq8016-sbc-d3-camera: Use more generic node names

Suraj Jaiswal (1):
      arm64: dts: qcom: sa8775p: enable safety IRQ

Umang Chheda (1):
      arm64: dts: qcom: qcm6490-idp: Include PM7250B

Vignesh Viswanathan (1):
      arm64: dts: qcom: ipq9574: Enable Inline Crypto Engine for MMC

Viken Dadhaniya (1):
      arm64: dts: qcom: sc7280: add slimbus DT node

Vladimir Lypak (4):
      dt-bindings: clock: gcc-msm8953: add more resets
      arm64: dts: qcom: msm8953: add reset for display subsystem
      arm64: dts: qcom: msm8953: Add GPU IOMMU
      arm64: dts: qcom: msm8953: Add GPU

Vladimir Zapolskiy (1):
      arm64: dts: qcom: sm6115: drop pipe clock selection

Walter Broemeling (1):
      arm64: dts: qcom: msm8916-samsung-fortuna/rossa: Add initial device trees

Yassine Oudjana (1):
      arm64: dts: qcom: msm8996: Define UFS UniPro clock limits

 Documentation/devicetree/bindings/arm/qcom.yaml    |   58 +-
 .../bindings/clock/qcom,gcc-sc8180x.yaml           |    7 +
 .../bindings/clock/qcom,sm8450-camcc.yaml          |    2 +
 .../bindings/clock/qcom,sm8450-gpucc.yaml          |    2 +
 .../bindings/clock/qcom,sm8550-dispcc.yaml         |    7 +-
 .../bindings/clock/qcom,sm8550-tcsr.yaml           |    1 +
 .../bindings/clock/qcom,sm8650-dispcc.yaml         |  106 --
 arch/arm/boot/dts/qcom/qcom-sdx55.dtsi             |   14 +-
 arch/arm/boot/dts/qcom/qcom-sdx65.dtsi             |   14 +-
 arch/arm64/boot/dts/qcom/Makefile                  |    6 +
 .../dts/qcom/apq8016-sbc-d3-camera-mezzanine.dts   |    8 +-
 arch/arm64/boot/dts/qcom/ipq5332.dtsi              |    8 +-
 arch/arm64/boot/dts/qcom/ipq6018.dtsi              |  159 ++
 arch/arm64/boot/dts/qcom/ipq8074.dtsi              |   16 +
 arch/arm64/boot/dts/qcom/ipq9574.dtsi              |   12 +-
 .../boot/dts/qcom/msm8216-samsung-fortuna3g.dts    |   11 +
 .../dts/qcom/msm8916-samsung-fortuna-common.dtsi   |  203 +++
 .../boot/dts/qcom/msm8916-samsung-gprimeltecan.dts |   27 +
 .../dts/qcom/msm8916-samsung-grandprimelte.dts     |   16 +
 .../dts/qcom/msm8916-samsung-rossa-common.dtsi     |   16 +
 arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts |   16 +
 arch/arm64/boot/dts/qcom/msm8916.dtsi              |    9 +
 arch/arm64/boot/dts/qcom/msm8939.dtsi              |   11 +-
 arch/arm64/boot/dts/qcom/msm8953.dtsi              |  155 +-
 .../boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi  |    2 +-
 .../dts/qcom/msm8994-sony-xperia-kitakami.dtsi     |    2 +-
 arch/arm64/boot/dts/qcom/msm8994.dtsi              |    4 +-
 arch/arm64/boot/dts/qcom/msm8996.dtsi              |   18 +-
 arch/arm64/boot/dts/qcom/msm8998.dtsi              |   26 +-
 .../boot/dts/qcom/{pm2250.dtsi => pm4125.dtsi}     |   38 +-
 arch/arm64/boot/dts/qcom/pmi632.dtsi               |   39 +
 arch/arm64/boot/dts/qcom/qcm2290.dtsi              |    7 +
 arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts |   56 +-
 arch/arm64/boot/dts/qcom/qcm6490-idp.dts           |   39 +-
 arch/arm64/boot/dts/qcom/qcs404.dtsi               |   16 +
 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts       |   23 +-
 arch/arm64/boot/dts/qcom/qrb2210-rb1.dts           |   96 +-
 arch/arm64/boot/dts/qcom/qrb4210-rb2.dts           |   50 +-
 arch/arm64/boot/dts/qcom/sa8295p-adp.dts           |   68 +
 arch/arm64/boot/dts/qcom/sa8540p-ride.dts          |    4 +-
 arch/arm64/boot/dts/qcom/sa8540p.dtsi              |    3 +
 arch/arm64/boot/dts/qcom/sa8775p.dtsi              |  119 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi       |    1 +
 arch/arm64/boot/dts/qcom/sc7180.dtsi               |   86 +-
 arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi |   28 +
 arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi     |    1 +
 arch/arm64/boot/dts/qcom/sc7280-idp-ec-h1.dtsi     |    1 +
 arch/arm64/boot/dts/qcom/sc7280.dtsi               |  125 +-
 arch/arm64/boot/dts/qcom/sc8180x.dtsi              |  141 +-
 .../dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts     |   39 +-
 arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi       |   39 +-
 arch/arm64/boot/dts/qcom/sc8280xp.dtsi             |  601 ++++++-
 .../arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts |    5 +
 arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts   |    2 +-
 arch/arm64/boot/dts/qcom/sdm450.dtsi               |   14 +
 .../boot/dts/qcom/sdm630-sony-xperia-nile.dtsi     |   16 +
 arch/arm64/boot/dts/qcom/sdm630.dtsi               |   62 +-
 arch/arm64/boot/dts/qcom/sdm632.dtsi               |    8 +
 .../arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts |    6 +
 arch/arm64/boot/dts/qcom/sdm670.dtsi               |   14 +-
 arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi         |    1 +
 arch/arm64/boot/dts/qcom/sdm845-db845c.dts         |    2 +-
 .../arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi |    8 +-
 arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts  |    2 +-
 arch/arm64/boot/dts/qcom/sdm845.dtsi               |   63 +-
 arch/arm64/boot/dts/qcom/sm4450.dtsi               |    2 +-
 arch/arm64/boot/dts/qcom/sm6115.dtsi               |   95 +-
 arch/arm64/boot/dts/qcom/sm6125.dtsi               |   17 +-
 arch/arm64/boot/dts/qcom/sm6350.dtsi               |  597 ++++++-
 arch/arm64/boot/dts/qcom/sm6375.dtsi               |   12 +-
 arch/arm64/boot/dts/qcom/sm7125-xiaomi-common.dtsi |   26 +
 arch/arm64/boot/dts/qcom/sm7125-xiaomi-curtana.dts |   16 +
 arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts  |   61 +-
 arch/arm64/boot/dts/qcom/sm8150.dtsi               |  115 +-
 arch/arm64/boot/dts/qcom/sm8250.dtsi               |  107 +-
 arch/arm64/boot/dts/qcom/sm8350.dtsi               |   87 +-
 arch/arm64/boot/dts/qcom/sm8450-hdk.dts            |    6 +-
 arch/arm64/boot/dts/qcom/sm8450.dtsi               |   81 +-
 arch/arm64/boot/dts/qcom/sm8550-hdk.dts            | 1306 ++++++++++++++
 arch/arm64/boot/dts/qcom/sm8550-mtp.dts            |   11 +-
 arch/arm64/boot/dts/qcom/sm8550-qrd.dts            |   53 +-
 arch/arm64/boot/dts/qcom/sm8550.dtsi               |  187 +-
 arch/arm64/boot/dts/qcom/sm8650-mtp.dts            |  155 ++
 arch/arm64/boot/dts/qcom/sm8650-qrd.dts            |  439 ++++-
 arch/arm64/boot/dts/qcom/sm8650.dtsi               |   81 +-
 arch/arm64/boot/dts/qcom/x1e80100-crd.dts          |  450 +++++
 arch/arm64/boot/dts/qcom/x1e80100-qcp.dts          |  175 +-
 arch/arm64/boot/dts/qcom/x1e80100.dtsi             | 1777 +++++++++++++++++++-
 include/dt-bindings/clock/qcom,gcc-msm8953.h       |    4 +
 include/dt-bindings/clock/qcom,gcc-sc8180x.h       |    2 +
 include/dt-bindings/clock/qcom,x1e80100-camcc.h    |  135 ++
 include/dt-bindings/clock/qcom,x1e80100-dispcc.h   |   98 ++
 include/dt-bindings/clock/qcom,x1e80100-gpucc.h    |   41 +
 include/dt-bindings/clock/qcom,x1e80100-tcsr.h     |   23 +
 include/dt-bindings/reset/qcom,x1e80100-gpucc.h    |   19 +
 95 files changed, 8351 insertions(+), 586 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/qcom,sm8650-dispcc.yaml
 create mode 100644 arch/arm64/boot/dts/qcom/msm8216-samsung-fortuna3g.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/msm8916-samsung-gprimeltecan.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8916-samsung-grandprimelte.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts
 rename arch/arm64/boot/dts/qcom/{pm2250.dtsi => pm4125.dtsi} (56%)
 create mode 100644 arch/arm64/boot/dts/qcom/sdm450.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/sm7125-xiaomi-curtana.dts
 create mode 100644 arch/arm64/boot/dts/qcom/sm8550-hdk.dts
 create mode 100644 include/dt-bindings/clock/qcom,x1e80100-camcc.h
 create mode 100644 include/dt-bindings/clock/qcom,x1e80100-dispcc.h
 create mode 100644 include/dt-bindings/clock/qcom,x1e80100-gpucc.h
 create mode 100644 include/dt-bindings/clock/qcom,x1e80100-tcsr.h
 create mode 100644 include/dt-bindings/reset/qcom,x1e80100-gpucc.h


From duoming at zju.edu.cn  Sat Feb 24 22:04:01 2024
From: duoming at zju.edu.cn (Duoming Zhou)
Date: Sun, 25 Feb 2024 14:04:01 +0800
Subject: [PATCH] ARM: mvebu: Prevent null pointer dereference caused by kzalloc failure
Message-ID: <20240225060401.52768-1-duoming@zju.edu.cn>

The kzalloc() in i2c_quirk() will return null if the physical
memory has run out. As a result, if we dereference the new_compat
pointer, the null pointer dereference bug will happen.

This patch adds a check to avoid null pointer dereference.

Fixes: 5fd62066d290 ("ARM: mvebu: Add thermal quirk for the Armada 375 DB board")
Signed-off-by: Duoming Zhou <duoming at zju.edu.cn>
---
 arch/arm/mach-mvebu/board-v7.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
index fd5d0c8ff69..7d2cb12e349 100644
--- a/arch/arm/mach-mvebu/board-v7.c
+++ b/arch/arm/mach-mvebu/board-v7.c
@@ -125,6 +125,8 @@ static void __init i2c_quirk(void)
 		struct property *new_compat;
 
 		new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL);
+		if (!new_compat)
+			continue;
 
 		new_compat->name = kstrdup("compatible", GFP_KERNEL);
 		new_compat->length = sizeof("marvell,mv78230-a0-i2c");
-- 
2.17.1



From duoming at zju.edu.cn  Sat Feb 24 22:04:50 2024
From: duoming at zju.edu.cn (Duoming Zhou)
Date: Sun, 25 Feb 2024 14:04:50 +0800
Subject: [PATCH] ARM: mvebu: Add check in coherency.c to prevent null pointer dereference
Message-ID: <20240225060450.53044-1-duoming@zju.edu.cn>

The kzalloc() in armada_375_380_coherency_init() will return
null if the physical memory has run out. As a result, if we
dereference the property pointer, the null pointer dereference
bug will happen.

This patch adds a check to avoid null pointer dereference.

Fixes: 497a92308af8 ("ARM: mvebu: implement L2/PCIe deadlock workaround")
Signed-off-by: Duoming Zhou <duoming at zju.edu.cn>
---
 arch/arm/mach-mvebu/coherency.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index a6b621ff0b8..a81a3c8c19a 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -191,6 +191,8 @@ static void __init armada_375_380_coherency_init(struct device_node *np)
 		struct property *p;
 
 		p = kzalloc(sizeof(*p), GFP_KERNEL);
+		if (!p)
+			continue;
 		p->name = kstrdup("arm,io-coherent", GFP_KERNEL);
 		of_add_property(cache_dn, p);
 	}
-- 
2.17.1



From masahiroy at kernel.org  Sun Feb 25 00:40:39 2024
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Sun, 25 Feb 2024 17:40:39 +0900
Subject: [PATCH v10 2/2] arm64: boot: Support Flat Image Tree
In-Reply-To: <CAK7LNARBC-zPHWDzhkMj90UBVaxHs0PJ9wfUKLRGAHxzBx=Bqg@mail.gmail.com>
References: <20240202173034.221790-1-sjg@chromium.org> <20240202173034.221790-3-sjg@chromium.org>
 <CAK7LNARBC-zPHWDzhkMj90UBVaxHs0PJ9wfUKLRGAHxzBx=Bqg@mail.gmail.com>
Message-ID: <CAK7LNASFR4XtyNKDtMabm6gd+oeMefZsg4nDMaY+Qmg2KkN8ew@mail.gmail.com>

On Wed, Feb 21, 2024 at 9:37?PM Masahiro Yamada <masahiroy at kernel.org> wrote:
>
> On Sat, Feb 3, 2024 at 2:30?AM Simon Glass <sjg at chromium.org> wrote:
> >
> > Add a script which produces a Flat Image Tree (FIT), a single file
> > containing the built kernel and associated devicetree files.
> > Compression defaults to gzip which gives a good balance of size and
> > performance.
> >
> > The files compress from about 86MB to 24MB using this approach.
> >
> > The FIT can be used by bootloaders which support it, such as U-Boot
> > and Linuxboot. It permits automatic selection of the correct
> > devicetree, matching the compatible string of the running board with
> > the closest compatible string in the FIT. There is no need for
> > filenames or other workarounds.
> >
> > Add a 'make image.fit' build target for arm64, as well.
> >
> > The FIT can be examined using 'dumpimage -l'.
> >
> > This uses the 'dtbs-list' file but processes only .dtb files, ignoring
> > the overlay .dtbo files.
> >
> > This features requires pylibfdt (use 'pip install libfdt'). It also
> > requires compression utilities for the algorithm being used. Supported
> > compression options are the same as the Image.xxx files. Use
> > FIT_COMPRESSION to select an algorithm other than gzip.
> >
> > While FIT supports a ramdisk / initrd, no attempt is made to support
> > this here, since it must be built separately from the Linux build.
> >
> > Signed-off-by: Simon Glass <sjg at chromium.org>
> > ---
> >
> > Changes in v10:
> > - Make use of dtbs-list file
> > - Mention dtbs-list and FIT_COMPRESSION
> > - Update copyright year
> > - Update cover letter to take account of an applied patch
> >
> > Changes in v9:
> > - Move the compression control into Makefile.lib
> >
> > Changes in v8:
> > - Drop compatible string in FDT node
> > - Correct sorting of MAINTAINERS to before ARM64 PORT
> > - Turn compress part of the make_fit.py comment in to a sentence
> > - Add two blank lines before parse_args() and setup_fit()
> > - Use 'image.fit: dtbs' instead of BUILD_DTBS var
> > - Use '$(<D)/dts' instead of '$(dir $<)dts'
> > - Add 'mkimage' details Documentation/process/changes.rst
> > - Allow changing the compression used
> > - Tweak cover letter since there is only one clean-up patch
> >
> > Changes in v7:
> > - Add Image as a dependency of image.fit
> > - Drop kbuild tag
> > - Add dependency on dtbs
> > - Drop unnecessary path separator for dtbs
> > - Rebase to -next
> >
> > Changes in v5:
> > - Drop patch previously applied
> > - Correct compression rule which was broken in v4
> >
> > Changes in v4:
> > - Use single quotes for UIMAGE_NAME
> >
> > Changes in v3:
> > - Drop temporary file image.itk
> > - Drop patch 'Use double quotes for image name'
> > - Drop double quotes in use of UIMAGE_NAME
> > - Drop unnecessary CONFIG_EFI_ZBOOT condition for help
> > - Avoid hard-coding "arm64" for the DT architecture
> >
> > Changes in v2:
> > - Drop patch previously applied
> > - Add .gitignore file
> > - Move fit rule to Makefile.lib using an intermediate file
> > - Drop dependency on CONFIG_EFI_ZBOOT
> > - Pick up .dtb files separately from the kernel
> > - Correct pylint too-many-args warning for write_kernel()
> > - Include the kernel image in the file count
> > - Add a pointer to the FIT spec and mention of its wide industry usage
> > - Mention the kernel version in the FIT description
> >
> >  Documentation/process/changes.rst |   9 +
> >  MAINTAINERS                       |   7 +
> >  arch/arm64/Makefile               |   7 +-
> >  arch/arm64/boot/.gitignore        |   1 +
> >  arch/arm64/boot/Makefile          |   6 +-
> >  scripts/Makefile.lib              |  16 ++
> >  scripts/make_fit.py               | 298 ++++++++++++++++++++++++++++++
> >  7 files changed, 341 insertions(+), 3 deletions(-)
> >  create mode 100755 scripts/make_fit.py
> >
> > diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
> > index 50b3d1cb1115..a8110965e4e1 100644
> > --- a/Documentation/process/changes.rst
> > +++ b/Documentation/process/changes.rst
> > @@ -62,6 +62,7 @@ Sphinx\ [#f1]_         2.4.4            sphinx-build --version
> >  cpio                   any              cpio --version
> >  GNU tar                1.28             tar --version
> >  gtags (optional)       6.6.5            gtags --version
> > +mkimage (optional)     2017.01          mkimage --version
> >  ====================== ===============  ========================================
> >
> >  .. [#f1] Sphinx is needed only to build the Kernel documentation
> > @@ -189,6 +190,14 @@ The kernel build requires GNU GLOBAL version 6.6.5 or later to generate
> >  tag files through ``make gtags``.  This is due to its use of the gtags
> >  ``-C (--directory)`` flag.
> >
> > +mkimage
> > +-------
> > +
> > +This tool is used when building a Flat Image Tree (FIT), commonly used on ARM
> > +platforms. The tool is available via the ``u-boot-tools`` package or can be
> > +built from the U-Boot source code. See the instructions at
> > +https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
> > +
> >  System utilities
> >  ****************
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 61117c3afa80..10c2753d7bcc 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -3026,6 +3026,13 @@ F:       drivers/mmc/host/sdhci-of-arasan.c
> >  N:     zynq
> >  N:     xilinx
> >
> > +ARM64 FIT SUPPORT
> > +M:     Simon Glass <sjg at chromium.org>
> > +L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> > +S:     Maintained
> > +F:     arch/arm64/boot/Makefile
> > +F:     scripts/make_fit.py
> > +
> >  ARM64 PORT (AARCH64 ARCHITECTURE)
> >  M:     Catalin Marinas <catalin.marinas at arm.com>
> >  M:     Will Deacon <will at kernel.org>
> > diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> > index 83cd2b7234b9..5de2b02f549a 100644
> > --- a/arch/arm64/Makefile
> > +++ b/arch/arm64/Makefile
> > @@ -150,7 +150,7 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
> >  # Default target when executing plain make
> >  boot           := arch/arm64/boot
> >
> > -BOOT_TARGETS   := Image vmlinuz.efi
> > +BOOT_TARGETS   := Image vmlinuz.efi image.fit
> >
> >  PHONY += $(BOOT_TARGETS)
> >
> > @@ -162,7 +162,9 @@ endif
> >
> >  all:   $(notdir $(KBUILD_IMAGE))
> >
> > -vmlinuz.efi: Image
> > +image.fit: dtbs
> > +
> > +vmlinuz.efi image.fit: Image
> >  $(BOOT_TARGETS): vmlinux
> >         $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
> >
> > @@ -215,6 +217,7 @@ virtconfig:
> >  define archhelp
> >    echo  '* Image.gz      - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
> >    echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
> > +  echo  '  image.fit     - Flat Image Tree (arch/$(ARCH)/boot/image.fit)'
> >    echo  '  install       - Install uncompressed kernel'
> >    echo  '  zinstall      - Install compressed kernel'
> >    echo  '                  Install using (your) ~/bin/installkernel or'
> > diff --git a/arch/arm64/boot/.gitignore b/arch/arm64/boot/.gitignore
> > index af5dc61f8b43..abaae9de1bdd 100644
> > --- a/arch/arm64/boot/.gitignore
> > +++ b/arch/arm64/boot/.gitignore
> > @@ -2,3 +2,4 @@
> >  Image
> >  Image.gz
> >  vmlinuz*
> > +image.fit
> > diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
> > index a5a787371117..ab21af82913e 100644
> > --- a/arch/arm64/boot/Makefile
> > +++ b/arch/arm64/boot/Makefile
> > @@ -16,7 +16,8 @@
> >
> >  OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
> >
> > -targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo Image.zst
> > +targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo \
> > +       Image.zst image.fit
> >
> >  $(obj)/Image: vmlinux FORCE
> >         $(call if_changed,objcopy)
> > @@ -39,6 +40,9 @@ $(obj)/Image.lzo: $(obj)/Image FORCE
> >  $(obj)/Image.zst: $(obj)/Image FORCE
> >         $(call if_changed,zstd)
> >
> > +$(obj)/image.fit: $(obj)/Image FORCE
> > +       $(call cmd,fit)
>
>
>
> The point for using dtbs-list is
> to avoid rebuilding image.fit needlessly.
>
>
> This should be:
>
> $(obj)/image.fit: $(obj)/Image $(obj)/dts/dtbs-list FORCE
>         $(call if_changed,fit)
>
>
>
>
>
> > +
> >  EFI_ZBOOT_PAYLOAD      := Image
> >  EFI_ZBOOT_BFD_TARGET   := elf64-littleaarch64
> >  EFI_ZBOOT_MACH_TYPE    := ARM64
> > diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
> > index b35d39022a30..4efb5ad07fd7 100644
> > --- a/scripts/Makefile.lib
> > +++ b/scripts/Makefile.lib
> > @@ -502,6 +502,22 @@ quiet_cmd_uimage = UIMAGE  $@
> >                         -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \
> >                         -n '$(UIMAGE_NAME)' -d $< $@
> >
> > +# Flat Image Tree (FIT)
> > +# This allows for packaging of a kernel and all devicetrees files, using
> > +# compression.
> > +# ---------------------------------------------------------------------------
> > +
> > +MAKE_FIT := $(srctree)/scripts/make_fit.py
> > +
> > +# Use this to override the compression algorithm
> > +FIT_COMPRESSION ?= gzip
> > +
> > +quiet_cmd_fit = FIT     $@
> > +      cmd_fit = $(MAKE_FIT) -f $@ --arch $(UIMAGE_ARCH) --os linux \
> > +                       --name '$(UIMAGE_NAME)' \
> > +                       --compress $(FIT_COMPRESSION) -k $< \
> > +                       @arch/$(SRCARCH)/boot/dts/dtbs-list
>
>
>
>
> cmd_fit = $(MAKE_FIT) -f $@ --arch $(UIMAGE_ARCH) --os linux \
>                 --name '$(UIMAGE_NAME)' \
>                 --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^)
>
>
>
>
>
> > +
> >  # XZ
> >  # ---------------------------------------------------------------------------
> >  # Use xzkern to compress the kernel image and xzmisc to compress other things.
> > diff --git a/scripts/make_fit.py b/scripts/make_fit.py
> > new file mode 100755
> > index 000000000000..69eee32960ae
> > --- /dev/null
> > +++ b/scripts/make_fit.py
> > @@ -0,0 +1,298 @@
> > +#!/usr/bin/env python3
> > +# SPDX-License-Identifier: GPL-2.0+
> > +#
> > +# Copyright 2024 Google LLC
> > +# Written by Simon Glass <sjg at chromium.org>
> > +#
> > +
> > +"""Build a FIT containing a lot of devicetree files
> > +
> > +Usage:
> > +    make_fit.py -A arm64 -n 'Linux-6.6' -O linux
> > +        -f arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk
> > +        @arch/arm64/boot/dts/dtbs-list -E -c gzip
> > +
> > +Creates a FIT containing the supplied kernel and a set of devicetree files,
> > +either specified individually or listed in a file (with an '@' prefix). Files
> > +which don't end in '.dtb' are silently ignored.
>
>
> Why do you need to check the suffix?
>
>
>
> > +
> > +Use -E to generate an external FIT (where the data is placed after the
> > +FIT data structure). This allows parsing of the data without loading
> > +the entire FIT.
> > +
> > +Use -c to compress the data, using bzip2, gzip, lz4, lzma, lzo and
> > +zstd algorithms.
> > +
> > +The resulting FIT can be booted by bootloaders which support FIT, such
> > +as U-Boot, Linuxboot, Tianocore, etc.
> > +
> > +Note that this tool does not yet support adding a ramdisk / initrd.
> > +"""
> > +
> > +import argparse
> > +import collections
> > +import os
> > +import subprocess
> > +import sys
> > +import tempfile
> > +import time
> > +
> > +import libfdt
> > +
> > +
> > +# Tool extension and the name of the command-line tools
> > +CompTool = collections.namedtuple('CompTool', 'ext,tools')
> > +
> > +COMP_TOOLS = {
> > +    'bzip2': CompTool('.bz2', 'bzip2'),
> > +    'gzip': CompTool('.gz', 'pigz,gzip'),
> > +    'lz4': CompTool('.lz4', 'lz4'),
> > +    'lzma': CompTool('.lzma', 'lzma'),
> > +    'lzo': CompTool('.lzo', 'lzop'),
> > +    'zstd': CompTool('.zstd', 'zstd'),
> > +}
> > +
> > +
> > +def parse_args():
> > +    """Parse the program ArgumentParser
> > +
> > +    Returns:
> > +        Namespace object containing the arguments
> > +    """
> > +    epilog = 'Build a FIT from a directory tree containing .dtb files'
> > +    parser = argparse.ArgumentParser(epilog=epilog)
> > +    parser.add_argument('-A', '--arch', type=str, required=True,
> > +          help='Specifies the architecture')
> > +    parser.add_argument('-c', '--compress', type=str, default='none',
> > +          help='Specifies the compression')
> > +    parser.add_argument('-E', '--external', action='store_true',
> > +          help='Convert the FIT to use external data')
> > +    parser.add_argument('-n', '--name', type=str, required=True,
> > +          help='Specifies the name')
> > +    parser.add_argument('-O', '--os', type=str, required=True,
> > +          help='Specifies the operating system')
> > +    parser.add_argument('-f', '--fit', type=str, required=True,
> > +          help='Specifies the output file (.fit)')
>
>
>
> I like -o (--output) to specify the output file.
>
>
>
>     parser.add_argument('-o', '--output', type=str, required=True,
>              help='Specifies the output file (.fit)')
>
>
>
>
>
> > +    parser.add_argument('-k', '--kernel', type=str, required=True,
> > +          help='Specifies the (uncompressed) kernel input file (.itk)')
> > +    parser.add_argument('srcdir', type=str, nargs='*',
> > +          help='Specifies the directory tree that contains .dtb files')
>
>
> srcdir?
>
> You changed the positional parameters to take dtb files.
>
>
>
>
>
>
> > +
> > +    return parser.parse_args()
> > +
> > +
> > +def setup_fit(fsw, name):
> > +    """Make a start on writing the FIT
> > +
> > +    Outputs the root properties and the 'images' node
> > +
> > +    Args:
> > +        fsw (libfdt.FdtSw): Object to use for writing
> > +        name (str): Name of kernel image
> > +    """
> > +    fsw.INC_SIZE = 65536
> > +    fsw.finish_reservemap()
> > +    fsw.begin_node('')
> > +    fsw.property_string('description', f'{name} with devicetree set')
> > +    fsw.property_u32('#address-cells', 1)
> > +
> > +    fsw.property_u32('timestamp', int(time.time()))
> > +    fsw.begin_node('images')
> > +
> > +
> > +def write_kernel(fsw, data, args):
> > +    """Write out the kernel image
> > +
> > +    Writes a kernel node along with the required properties
> > +
> > +    Args:
> > +        fsw (libfdt.FdtSw): Object to use for writing
> > +        data (bytes): Data to write (possibly compressed)
> > +        args (Namespace): Contains necessary strings:
> > +            arch: FIT architecture, e.g. 'arm64'
> > +            fit_os: Operating Systems, e.g. 'linux'
> > +            name: Name of OS, e.g. 'Linux-6.6.0-rc7'
> > +            compress: Compression algorithm to use, e.g. 'gzip'
> > +    """
> > +    with fsw.add_node('kernel'):
> > +        fsw.property_string('description', args.name)
> > +        fsw.property_string('type', 'kernel_noload')
> > +        fsw.property_string('arch', args.arch)
> > +        fsw.property_string('os', args.os)
> > +        fsw.property_string('compression', args.compress)
> > +        fsw.property('data', data)
> > +        fsw.property_u32('load', 0)
> > +        fsw.property_u32('entry', 0)
> > +
> > +
> > +def finish_fit(fsw, entries):
> > +    """Finish the FIT ready for use
> > +
> > +    Writes the /configurations node and subnodes
> > +
> > +    Args:
> > +        fsw (libfdt.FdtSw): Object to use for writing
> > +        entries (list of tuple): List of configurations:
> > +            str: Description of model
> > +            str: Compatible stringlist
> > +    """
> > +    fsw.end_node()
> > +    seq = 0
> > +    with fsw.add_node('configurations'):
> > +        for model, compat in entries:
> > +            seq += 1
> > +            with fsw.add_node(f'conf-{seq}'):
> > +                fsw.property('compatible', bytes(compat))
> > +                fsw.property_string('description', model)
> > +                fsw.property_string('fdt', f'fdt-{seq}')
> > +                fsw.property_string('kernel', 'kernel')
> > +    fsw.end_node()
> > +
> > +
> > +def compress_data(inf, compress):
> > +    """Compress data using a selected algorithm
> > +
> > +    Args:
> > +        inf (IOBase): Filename containing the data to compress
> > +        compress (str): Compression algorithm, e.g. 'gzip'
> > +
> > +    Return:
> > +        bytes: Compressed data
> > +    """
> > +    if compress == 'none':
> > +        return inf.read()
> > +
> > +    comp = COMP_TOOLS.get(compress)
> > +    if not comp:
> > +        raise ValueError(f"Unknown compression algorithm '{compress}'")
> > +
> > +    with tempfile.NamedTemporaryFile() as comp_fname:
> > +        with open(comp_fname.name, 'wb') as outf:
> > +            done = False
> > +            for tool in comp.tools.split(','):
> > +                try:
> > +                    subprocess.call([tool, '-c'], stdin=inf, stdout=outf)
> > +                    done = True
> > +                    break
> > +                except FileNotFoundError:
> > +                    pass
> > +            if not done:
> > +                raise ValueError(f'Missing tool(s): {comp.tools}\n')
> > +            with open(comp_fname.name, 'rb') as compf:
> > +                comp_data = compf.read()
> > +    return comp_data
> > +
> > +
> > +def output_dtb(fsw, seq, fname, arch, compress):
> > +    """Write out a single devicetree to the FIT
> > +
> > +    Args:
> > +        fsw (libfdt.FdtSw): Object to use for writing
> > +        seq (int): Sequence number (1 for first)
> > +        fmame (str): Filename containing the DTB
> > +        arch: FIT architecture, e.g. 'arm64'
> > +        compress (str): Compressed algorithm, e.g. 'gzip'
> > +
> > +    Returns:
> > +        tuple:
> > +            str: Model name
> > +            bytes: Compatible stringlist
> > +    """
> > +    with fsw.add_node(f'fdt-{seq}'):
> > +        # Get the compatible / model information
> > +        with open(fname, 'rb') as inf:
> > +            data = inf.read()
> > +        fdt = libfdt.FdtRo(data)
> > +        model = fdt.getprop(0, 'model').as_str()
> > +        compat = fdt.getprop(0, 'compatible')
> > +
> > +        fsw.property_string('description', model)
> > +        fsw.property_string('type', 'flat_dt')
> > +        fsw.property_string('arch', arch)
> > +        fsw.property_string('compression', compress)
> > +        fsw.property('compatible', bytes(compat))
> > +
> > +        with open(fname, 'rb') as inf:
> > +            compressed = compress_data(inf, compress)
> > +        fsw.property('data', compressed)
> > +    return model, compat
> > +
> > +
> > +def build_fit(args):
> > +    """Build the FIT from the provided files and arguments
> > +
> > +    Args:
> > +        args (Namespace): Program arguments
> > +
> > +    Returns:
> > +        tuple:
> > +            bytes: FIT data
> > +            int: Number of configurations generated
> > +            size: Total uncompressed size of data
> > +    """
> > +    def add_file(fname):
> > +        nonlocal seq, size
> > +
> > +        if os.path.splitext(fname)[1] == '.dtb':
> > +            seq += 1
> > +            size += os.path.getsize(fname)
> > +            model, compat = output_dtb(fsw, seq, fname, args.arch,
> > +                                       args.compress)
> > +            entries.append([model, compat])
> > +            return True
> > +
> > +    seq = 0
> > +    size = 0
> > +    fsw = libfdt.FdtSw()
> > +    setup_fit(fsw, args.name)
> > +    entries = []
> > +
> > +    # Handle the kernel
> > +    with open(args.kernel, 'rb') as inf:
> > +        comp_data = compress_data(inf, args.compress)
> > +    size += os.path.getsize(args.kernel)
> > +    write_kernel(fsw, comp_data, args)
> > +
> > +    for path in args.srcdir:
> > +        # Handle a list of devicetree files
> > +        if path.startswith('@'):
> > +            with open(path[1:], 'r', encoding='utf-8') as inf:
> > +                for fname in inf.read().splitlines():
> > +                    add_file(fname)
>
>
>
>
> You missed the point of my suggestion.
>
>
> I did not mean the "@file" syntax
> specifically for containing the device trees.
>
>
> It is common for tools to support the "@file" syntax
> to avoid "Argument list too long" error.
>
>
>
> See "man ar", "man ld", etc. for example.
>
>
>  @file
>    Read command?line options from file. The options read are inserted in
>    place of the original @file option. If file does not exist, or cannot
>    be read, then the option will be treated literally, and not removed.
>
>
>
>
> It must be generic enough to contain any command line parameters.
>
>
> And, you do not even implement it yourself because
> it is just a matter of adding fromfile_prefix_chars='@'
>
>
> See the document.
>
>   https://docs.python.org/3/library/argparse.html#fromfile-prefix-chars





Or, if you prefer using the 'file' only for containing DTB files,
I think it is better to use a standard short/long option instead of
the @file syntax.


For example, 'tar' can take files from FILE instead of the
positional parameters of the command line.


'man tar':

  -T, --files-from=FILE
       Get names to extract or create from FILE.







-- 
Best Regards
Masahiro Yamada


From r09922117 at csie.ntu.edu.tw  Sun Feb 25 01:02:36 2024
From: r09922117 at csie.ntu.edu.tw (Wei-Lin Chang)
Date: Sun, 25 Feb 2024 17:02:36 +0800
Subject: [PATCH 0/1] KVM: arm64: Affinity level 3 support
Message-ID: <20240225090237.775573-1-r09922117@csie.ntu.edu.tw>

Hi everyone,

By supporting Aff3, we not only allow broader usage, but also get the
chance to fix the issue pointed out by Saurav [1]. The current code
returns 0s for GICR_TYPER[63:56], causing guests to fail when its VCPUs
tries to find a matching redistributor, when the VMM programs non-zero
values for VCPUs' MPIDR_EL1.Aff3.

For testing, both 64-bit (with ICH_VTR_EL2.A3V == 1) and 32-bit guests
are ran using QEMU, Aff3 usage is emulated by modifying reset_mpidr to
write non-zero test values to MPIDR_EL1.Aff3 when Aff3 is valid, and
populating the Aff3 field of kvm_sys_reg_set_user's user given value
if r->reg == MPIDR_EL1.
The 64-bit case is checked to have MPIDR_EL1.Aff3 populated and both
64-bit and 32-bit guests seem to work with interrupts being delivered
properly.

Note: I checked with Saurav to make sure he isn't planning on working on
this as well. Also thanks for the maintainers for giving directions for
improvements in [1].

[1]: https://lore.kernel.org/kvmarm/20240205184326.78814-1-sauravsc at amazon.com/

Wei-Lin Chang (1):
  KVM: arm64: Affinity level 3 support

 arch/arm64/kvm/sys_regs.c          | 24 +++++++++++++++++++++---
 arch/arm64/kvm/vgic/vgic-debug.c   |  2 +-
 arch/arm64/kvm/vgic/vgic-mmio-v3.c | 18 +++++++++++-------
 include/kvm/arm_vgic.h             |  7 ++++++-
 4 files changed, 39 insertions(+), 12 deletions(-)

-- 
2.34.1



From r09922117 at csie.ntu.edu.tw  Sun Feb 25 01:02:37 2024
From: r09922117 at csie.ntu.edu.tw (Wei-Lin Chang)
Date: Sun, 25 Feb 2024 17:02:37 +0800
Subject: [PATCH 1/1] KVM: arm64: Affinity level 3 support
In-Reply-To: <20240225090237.775573-1-r09922117@csie.ntu.edu.tw>
References: <20240225090237.775573-1-r09922117@csie.ntu.edu.tw>
Message-ID: <20240225090237.775573-2-r09922117@csie.ntu.edu.tw>

Currently, KVM ARM64 avoids using the Aff3 field for VCPUs, which saves
us from having to check for hardware support in ICH_VTR_EL2.A3V or the
guest's execution state. However a VCPU could still have its Aff3 bits
set to non-zero if the VMM directly changes the VCPU's MPIDR_EL1. This
causes a mismatch between MPIDR_EL1.Aff3 and GICR_TYPER[63:56] since 0s
are always returned for the latter, failing the GIC Redistributor
matching in the VM.

Let's fix this by only allowing userspace to write into the Aff3 field
of MPIDR_EL1 if Aff3 is valid. Additionally, extend reset_mpidr and
vgic_mmio_{read,write}_irouter to fully support Aff3. With theses
changes, GICR_TYPER can then safely return all four affinity levels.

Suggested-by: Saurav Sachidanand <sauravsc at amazon.com>
Signed-off-by: Wei-Lin Chang <r09922117 at csie.ntu.edu.tw>
---
 arch/arm64/kvm/sys_regs.c          | 24 +++++++++++++++++++++---
 arch/arm64/kvm/vgic/vgic-debug.c   |  2 +-
 arch/arm64/kvm/vgic/vgic-mmio-v3.c | 18 +++++++++++-------
 include/kvm/arm_vgic.h             |  7 ++++++-
 4 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 30253bd199..6694ce851a 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -239,6 +239,19 @@ static u8 get_min_cache_line_size(bool icache)
 	return field + 2;
 }
 
+static int set_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+		   u64 val)
+{
+	bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v();
+
+	if (!aff3_valid)
+		val &= ~((u64)MPIDR_LEVEL_MASK << MPIDR_LEVEL_SHIFT(3));
+
+	__vcpu_sys_reg(vcpu, rd->reg) = val;
+
+	return 0;
+}
+
 /* Which cache CCSIDR represents depends on CSSELR value. */
 static u32 get_ccsidr(struct kvm_vcpu *vcpu, u32 csselr)
 {
@@ -817,10 +830,12 @@ static u64 reset_actlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 static u64 reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 {
 	u64 mpidr;
+	bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v();
 
 	/*
-	 * Map the vcpu_id into the first three affinity level fields of
-	 * the MPIDR. We limit the number of VCPUs in level 0 due to a
+	 * Map the vcpu_id into the affinity level fields of the MPIDR. The
+	 * fourth level is mapped only if we are running a 64 bit guest and
+	 * A3V is supported. We limit the number of VCPUs in level 0 due to a
 	 * limitation to 16 CPUs in that level in the ICC_SGIxR registers
 	 * of the GICv3 to be able to address each CPU directly when
 	 * sending IPIs.
@@ -828,6 +843,8 @@ static u64 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);
+	if (aff3_valid)
+		mpidr |= (u64)((vcpu->vcpu_id >> 20) & 0xff) << MPIDR_LEVEL_SHIFT(3);
 	mpidr |= (1ULL << 31);
 	vcpu_write_sys_reg(vcpu, mpidr, MPIDR_EL1);
 
@@ -2232,7 +2249,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_DBGVCR32_EL2), trap_undef, reset_val, DBGVCR32_EL2, 0 },
 
-	{ SYS_DESC(SYS_MPIDR_EL1), NULL, reset_mpidr, MPIDR_EL1 },
+	{ SYS_DESC(SYS_MPIDR_EL1), NULL, reset_mpidr, MPIDR_EL1,
+	  .get_user = NULL, .set_user = set_mpidr },
 
 	/*
 	 * ID regs: all ID_SANITISED() entries here must have corresponding
diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c
index 85606a531d..726cf1bd7b 100644
--- a/arch/arm64/kvm/vgic/vgic-debug.c
+++ b/arch/arm64/kvm/vgic/vgic-debug.c
@@ -206,7 +206,7 @@ static void print_irq_state(struct seq_file *s, struct vgic_irq *irq,
 		      "    %2d "
 		      "%d%d%d%d%d%d%d "
 		      "%8d "
-		      "%8x "
+		      "%8llx "
 		      " %2x "
 		      "%3d "
 		      "     %2d "
diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
index c15ee1df03..ea0d4ad85a 100644
--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
@@ -195,13 +195,13 @@ static unsigned long vgic_mmio_read_irouter(struct kvm_vcpu *vcpu,
 {
 	int intid = VGIC_ADDR_TO_INTID(addr, 64);
 	struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, NULL, intid);
+	bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v();
 	unsigned long ret = 0;
 
 	if (!irq)
 		return 0;
 
-	/* The upper word is RAZ for us. */
-	if (!(addr & 4))
+	if (aff3_valid || !(addr & 4))
 		ret = extract_bytes(READ_ONCE(irq->mpidr), addr & 7, len);
 
 	vgic_put_irq(vcpu->kvm, irq);
@@ -213,11 +213,12 @@ static void vgic_mmio_write_irouter(struct kvm_vcpu *vcpu,
 				    unsigned long val)
 {
 	int intid = VGIC_ADDR_TO_INTID(addr, 64);
+	bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v();
 	struct vgic_irq *irq;
 	unsigned long flags;
 
-	/* The upper word is WI for us since we don't implement Aff3. */
-	if (addr & 4)
+	/* The upper word is WI if Aff3 is not valid. */
+	if (!aff3_valid && addr & 4)
 		return;
 
 	irq = vgic_get_irq(vcpu->kvm, NULL, intid);
@@ -227,8 +228,7 @@ static void vgic_mmio_write_irouter(struct kvm_vcpu *vcpu,
 
 	raw_spin_lock_irqsave(&irq->irq_lock, flags);
 
-	/* We only care about and preserve Aff0, Aff1 and Aff2. */
-	irq->mpidr = val & GENMASK(23, 0);
+	irq->mpidr = val & MPIDR_HWID_BITMASK;
 	irq->target_vcpu = kvm_mpidr_to_vcpu(vcpu->kvm, irq->mpidr);
 
 	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
@@ -323,7 +323,11 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu,
 	int target_vcpu_id = vcpu->vcpu_id;
 	u64 value;
 
-	value = (u64)(mpidr & GENMASK(23, 0)) << 32;
+	value = MPIDR_AFFINITY_LEVEL(mpidr, 3) << 56 |
+		MPIDR_AFFINITY_LEVEL(mpidr, 2) << 48 |
+		MPIDR_AFFINITY_LEVEL(mpidr, 1) << 40 |
+		MPIDR_AFFINITY_LEVEL(mpidr, 0) << 32;
+
 	value |= ((target_vcpu_id & 0xffff) << 8);
 
 	if (vgic_has_its(vcpu->kvm))
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 8cc38e836f..b464ac1b79 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -143,7 +143,7 @@ struct vgic_irq {
 	unsigned int host_irq;		/* linux irq corresponding to hwintid */
 	union {
 		u8 targets;			/* GICv2 target VCPUs mask */
-		u32 mpidr;			/* GICv3 target VCPU */
+		u64 mpidr;			/* GICv3 target VCPU */
 	};
 	u8 source;			/* GICv2 SGIs only */
 	u8 active_source;		/* GICv2 SGIs only */
@@ -413,6 +413,11 @@ static inline int kvm_vgic_get_max_vcpus(void)
 	return kvm_vgic_global_state.max_gic_vcpus;
 }
 
+static inline bool kvm_vgic_has_a3v(void)
+{
+	return kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_A3V_MASK;
+}
+
 /**
  * kvm_vgic_setup_default_irq_routing:
  * Setup a default flat gsi routing table mapping all SPIs
-- 
2.34.1



From wahrenst at gmx.net  Sun Feb 25 02:01:29 2024
From: wahrenst at gmx.net (Stefan Wahren)
Date: Sun, 25 Feb 2024 11:01:29 +0100
Subject: [PATCH RFC 0/2] pinctrl: bcm2835: Implement pin_conf_get
In-Reply-To: <553aa585-c442-4329-8a4d-fcf2f9c110c1@broadcom.com>
References: <20240204165852.166157-1-wahrenst@gmx.net>
 <CACRpkda=VsgiH0-iJVLry4hy6kLeJ_20mzMs8OrqR6Fr8eAp-g@mail.gmail.com>
 <1709f26f-0486-4856-8b2d-ba5e6fd492e2@gmx.net>
 <553aa585-c442-4329-8a4d-fcf2f9c110c1@broadcom.com>
Message-ID: <9d729c9f-94cb-457f-8a40-3ba4d62fe627@gmx.net>

Hi Florian,

Am 07.02.24 um 19:22 schrieb Florian Fainelli:
> On 2/7/24 03:33, Stefan Wahren wrote:
>> Hi Linus,
>>
>> Am 07.02.24 um 11:56 schrieb Linus Walleij:
>>> On Sun, Feb 4, 2024 at 5:59?PM Stefan Wahren <wahrenst at gmx.net> wrote:
>>>
>>>> For years, the Raspberry Pi users relied on userspace programs to read
>>>> the pin configuration. In the meantime, it has become apparent that
>>>> this
>>>> approach has reached its limits for various reasons.
>>>>
>>>> This patch series now attempts to improve the debugging
>>>> possibilities on
>>>> the kernel side in order to reduce the dependency on these userspace
>>>> programs.
>>>>
>>>> Stefan Wahren (2):
>>>> ?? pinctrl: bcm2835: Implement bcm2835_pinconf_get
>>>> ?? pinctrl: bcm2835: Implement bcm2711_pinconf_get
>>> I don't see any problems with this, can I just apply the patches or
>>> do you
>>> want to first resend them as non-RFC?
>> since the second patch hasn't been tested with BCM7211, it would be nice
>> to get a feedback from Florian or someone else with this hardware?
>
> Give me a few days to get there and I will run a test.

is there any chance to test with BCM7211?


From krzysztof.kozlowski at linaro.org  Sun Feb 25 02:41:09 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 11:41:09 +0100
Subject: [PATCH v6 0/2] Add regmap support to exynos-pmu for protected
 PMU regs
In-Reply-To: <20240220220613.797068-1-peter.griffin@linaro.org>
References: <20240220220613.797068-1-peter.griffin@linaro.org>
Message-ID: <170885766906.10417.17172064962783512739.b4-ty@linaro.org>


On Tue, 20 Feb 2024 22:06:11 +0000, Peter Griffin wrote:
> This is a v6 of the series to add support for protected PMU registers found
> on gs101 and derivative SoCs. In v2 and later it was re-worked to be based
> on a regmap abstraction that I think leads to a much neater overall
> solution.
> 
> The advantage of the regmap abstraction is that most leaf drivers that
> read/write PMU registers need minimal changes.
> 
> [...]

Applied, thanks!

[1/2] soc: samsung: exynos-pmu: Add regmap support for SoCs that protect PMU regs
      https://git.kernel.org/krzk/linux/c/0b7c6075022ccff529318597dc6b165dd6a25c8f
[2/2] watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs
      https://git.kernel.org/krzk/linux/c/746f0770f916e6c48e422d6a34e67eae16707f0e

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From kurt at linutronix.de  Sun Feb 25 02:55:52 2024
From: kurt at linutronix.de (Kurt Kanzenbach)
Date: Sun, 25 Feb 2024 11:55:52 +0100
Subject: [PATCH net] net: stmmac: Complete meta data only when enabled
In-Reply-To: <ZdjLvrBhW+NIcp85@boxer>
References: <20240222-stmmac_xdp-v1-1-e8d2d2b79ff0@linutronix.de>
 <CAKH8qBsCrYuT+18CsydQ5TeauRzu0Hdz7mZQ2c0W7er0KrJnkg@mail.gmail.com>
 <ZdjLvrBhW+NIcp85@boxer>
Message-ID: <87v86c7qyv.fsf@kurt.kurt.home>

Hello Maciej,

On Fri Feb 23 2024, Maciej Fijalkowski wrote:
> On Thu, Feb 22, 2024 at 11:53:14AM -0800, Stanislav Fomichev wrote:
>> On Thu, Feb 22, 2024 at 1:45?AM Kurt Kanzenbach <kurt at linutronix.de> wrote:
>> >
>> > Currently using XDP/ZC sockets on stmmac results in a kernel crash:
>> >
>> > |[  255.822584] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
>
> would be good to explain where it comes from, no?

Sure, no problem.

Thanks,
Kurt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 861 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20240225/89a085e1/attachment.sig>

From maz at kernel.org  Sun Feb 25 03:19:05 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 25 Feb 2024 11:19:05 +0000
Subject: [PATCH 1/1] KVM: arm64: Affinity level 3 support
In-Reply-To: <20240225090237.775573-2-r09922117@csie.ntu.edu.tw>
References: <20240225090237.775573-1-r09922117@csie.ntu.edu.tw>
	<20240225090237.775573-2-r09922117@csie.ntu.edu.tw>
Message-ID: <86frxg3i6u.wl-maz@kernel.org>

[+Eric who was looking into something related recently]

Hi Wei-Lin,

Thanks for looking into this.

On Sun, 25 Feb 2024 09:02:37 +0000,
Wei-Lin Chang <r09922117 at csie.ntu.edu.tw> wrote:
> 
> Currently, KVM ARM64 avoids using the Aff3 field for VCPUs, which saves
> us from having to check for hardware support in ICH_VTR_EL2.A3V or the

That's not strictly true. We do check for A3V support at restore time.

> guest's execution state. However a VCPU could still have its Aff3 bits
> set to non-zero if the VMM directly changes the VCPU's MPIDR_EL1. This
> causes a mismatch between MPIDR_EL1.Aff3 and GICR_TYPER[63:56] since 0s
> are always returned for the latter, failing the GIC Redistributor
> matching in the VM.
> 
> Let's fix this by only allowing userspace to write into the Aff3 field
> of MPIDR_EL1 if Aff3 is valid.

What does "valid" means here? 0 *is* a valid value. Or do you mean a
non-zero value? Also, this now creates a dependency between GICR_TYPER
and MPIDR_EL1. How is userspace supposed to order those when restoring
a VM?

> Additionally, extend reset_mpidr and
> vgic_mmio_{read,write}_irouter to fully support Aff3. With theses
> changes, GICR_TYPER can then safely return all four affinity levels.
> 
> Suggested-by: Saurav Sachidanand <sauravsc at amazon.com>
> Signed-off-by: Wei-Lin Chang <r09922117 at csie.ntu.edu.tw>
> ---
>  arch/arm64/kvm/sys_regs.c          | 24 +++++++++++++++++++++---
>  arch/arm64/kvm/vgic/vgic-debug.c   |  2 +-
>  arch/arm64/kvm/vgic/vgic-mmio-v3.c | 18 +++++++++++-------
>  include/kvm/arm_vgic.h             |  7 ++++++-
>  4 files changed, 39 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 30253bd199..6694ce851a 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -239,6 +239,19 @@ static u8 get_min_cache_line_size(bool icache)
>  	return field + 2;
>  }
>  
> +static int set_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
> +		   u64 val)
> +{
> +	bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v();

What does this mean for a guest that doesn't have a GICv3?

> +
> +	if (!aff3_valid)
> +		val &= ~((u64)MPIDR_LEVEL_MASK << MPIDR_LEVEL_SHIFT(3));
> +
> +	__vcpu_sys_reg(vcpu, rd->reg) = val;
> +
> +	return 0;
> +}
> +
>  /* Which cache CCSIDR represents depends on CSSELR value. */
>  static u32 get_ccsidr(struct kvm_vcpu *vcpu, u32 csselr)
>  {
> @@ -817,10 +830,12 @@ static u64 reset_actlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
>  static u64 reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
>  {
>  	u64 mpidr;
> +	bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v();

Same thing.

>
>  	/*
> -	 * Map the vcpu_id into the first three affinity level fields of
> -	 * the MPIDR. We limit the number of VCPUs in level 0 due to a
> +	 * Map the vcpu_id into the affinity level fields of the MPIDR. The
> +	 * fourth level is mapped only if we are running a 64 bit guest and
> +	 * A3V is supported. We limit the number of VCPUs in level 0 due to a
>  	 * limitation to 16 CPUs in that level in the ICC_SGIxR registers
>  	 * of the GICv3 to be able to address each CPU directly when
>  	 * sending IPIs.
> @@ -828,6 +843,8 @@ static u64 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);
> +	if (aff3_valid)
> +		mpidr |= (u64)((vcpu->vcpu_id >> 20) & 0xff) << MPIDR_LEVEL_SHIFT(3);

From virt/kcvm/kvm_main.c:

static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
{
	int r;
	struct kvm_vcpu *vcpu;
	struct page *page;

	if (id >= KVM_MAX_VCPU_IDS)
		return -EINVAL;

        [...]
}

So vcpu_id is capped at KVM_MAX_VCPU_IDS, which is 512 on arm64. How
does this ever produce anything other than 0? This is, by the way,
already true for Aff2. Which is why I have always found this change
extremely questionable: why do you need to describe 2^32 CPUs when you
can only create 512?

>  	mpidr |= (1ULL << 31);
>  	vcpu_write_sys_reg(vcpu, mpidr, MPIDR_EL1);
>  
> @@ -2232,7 +2249,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  
>  	{ SYS_DESC(SYS_DBGVCR32_EL2), trap_undef, reset_val, DBGVCR32_EL2, 0 },
>  
> -	{ SYS_DESC(SYS_MPIDR_EL1), NULL, reset_mpidr, MPIDR_EL1 },
> +	{ SYS_DESC(SYS_MPIDR_EL1), NULL, reset_mpidr, MPIDR_EL1,
> +	  .get_user = NULL, .set_user = set_mpidr },
>  
>  	/*
>  	 * ID regs: all ID_SANITISED() entries here must have corresponding
> diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c
> index 85606a531d..726cf1bd7b 100644
> --- a/arch/arm64/kvm/vgic/vgic-debug.c
> +++ b/arch/arm64/kvm/vgic/vgic-debug.c
> @@ -206,7 +206,7 @@ static void print_irq_state(struct seq_file *s, struct vgic_irq *irq,
>  		      "    %2d "
>  		      "%d%d%d%d%d%d%d "
>  		      "%8d "
> -		      "%8x "
> +		      "%8llx "
>  		      " %2x "
>  		      "%3d "
>  		      "     %2d "
> diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> index c15ee1df03..ea0d4ad85a 100644
> --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> @@ -195,13 +195,13 @@ static unsigned long vgic_mmio_read_irouter(struct kvm_vcpu *vcpu,
>  {
>  	int intid = VGIC_ADDR_TO_INTID(addr, 64);
>  	struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, NULL, intid);
> +	bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v();

Hint: if you need to write the same expression more than once, you
probably need a helper for it. Meaning that you will only have to fix
it once.

>  	unsigned long ret = 0;
>  
>  	if (!irq)
>  		return 0;
>  
> -	/* The upper word is RAZ for us. */
> -	if (!(addr & 4))
> +	if (aff3_valid || !(addr & 4))
>  		ret = extract_bytes(READ_ONCE(irq->mpidr), addr & 7, len);
>
>  	vgic_put_irq(vcpu->kvm, irq);
> @@ -213,11 +213,12 @@ static void vgic_mmio_write_irouter(struct kvm_vcpu *vcpu,
>  				    unsigned long val)
>  {
>  	int intid = VGIC_ADDR_TO_INTID(addr, 64);
> +	bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v();
>  	struct vgic_irq *irq;
>  	unsigned long flags;
>  
> -	/* The upper word is WI for us since we don't implement Aff3. */
> -	if (addr & 4)
> +	/* The upper word is WI if Aff3 is not valid. */
> +	if (!aff3_valid && addr & 4)
>  		return;
>  
>  	irq = vgic_get_irq(vcpu->kvm, NULL, intid);
> @@ -227,8 +228,7 @@ static void vgic_mmio_write_irouter(struct kvm_vcpu *vcpu,
>  
>  	raw_spin_lock_irqsave(&irq->irq_lock, flags);
>  
> -	/* We only care about and preserve Aff0, Aff1 and Aff2. */
> -	irq->mpidr = val & GENMASK(23, 0);
> +	irq->mpidr = val & MPIDR_HWID_BITMASK;
>  	irq->target_vcpu = kvm_mpidr_to_vcpu(vcpu->kvm, irq->mpidr);
>  
>  	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
> @@ -323,7 +323,11 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu,
>  	int target_vcpu_id = vcpu->vcpu_id;
>  	u64 value;
>  
> -	value = (u64)(mpidr & GENMASK(23, 0)) << 32;
> +	value = MPIDR_AFFINITY_LEVEL(mpidr, 3) << 56 |
> +		MPIDR_AFFINITY_LEVEL(mpidr, 2) << 48 |
> +		MPIDR_AFFINITY_LEVEL(mpidr, 1) << 40 |
> +		MPIDR_AFFINITY_LEVEL(mpidr, 0) << 32;

Maybe it is time to describe these shifts in an include file, and use
FIELD_PREP() to construct the whole thing. It will be a lot more
readable.

> +
>  	value |= ((target_vcpu_id & 0xffff) << 8);
>  
>  	if (vgic_has_its(vcpu->kvm))
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 8cc38e836f..b464ac1b79 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -143,7 +143,7 @@ struct vgic_irq {
>  	unsigned int host_irq;		/* linux irq corresponding to hwintid */
>  	union {
>  		u8 targets;			/* GICv2 target VCPUs mask */
> -		u32 mpidr;			/* GICv3 target VCPU */
> +		u64 mpidr;			/* GICv3 target VCPU */

Do we really need to grow each interrupt object by 4 bytes, specially
when we at most use 4 bytes? I'd rather we store the affinity in a
compact way and change the way we compare it to the vcpu's MPIDR_EL1.

>  	};
>  	u8 source;			/* GICv2 SGIs only */
>  	u8 active_source;		/* GICv2 SGIs only */
> @@ -413,6 +413,11 @@ static inline int kvm_vgic_get_max_vcpus(void)
>  	return kvm_vgic_global_state.max_gic_vcpus;
>  }
>  
> +static inline bool kvm_vgic_has_a3v(void)
> +{
> +	return kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_A3V_MASK;
> +}
> +

I can see multiple problems with this:

- this is the host state, which shouldn't necessarily represent the
  guest state. It should be possible to restore a VM that have a
  different A3V value and still have the same guarantees.  There is
  however a small nit around ICV_CTLR_EL1.A3V, which would require
  trapping to emulate the A3V bit.

- this assumes GICv3, which is definitely not universal (we support
  GICv2, for which no such restriction actually exists).

Finally, I don't see VM save/restore being addressed here, and I
suspect it hasn't been looked at.

Overall, this patch does too many things, and it should be split in
discrete changes. I also want to see an actual justification for Aff3
support. And if we introduce it, it must be fully virtualised
(independent of the A3V support on the host).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From linux at armlinux.org.uk  Sun Feb 25 03:30:19 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 25 Feb 2024 11:30:19 +0000
Subject: [PATCH] ARM: mvebu: Add check in coherency.c to prevent null
 pointer dereference
In-Reply-To: <20240225060450.53044-1-duoming@zju.edu.cn>
References: <20240225060450.53044-1-duoming@zju.edu.cn>
Message-ID: <Zdsky9nVdwP6Ry0E@shell.armlinux.org.uk>

On Sun, Feb 25, 2024 at 02:04:50PM +0800, Duoming Zhou wrote:
> The kzalloc() in armada_375_380_coherency_init() will return
> null if the physical memory has run out. As a result, if we
> dereference the property pointer, the null pointer dereference
> bug will happen.
> 
> This patch adds a check to avoid null pointer dereference.

Again, what if kstrdup() fails?

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


From linux at armlinux.org.uk  Sun Feb 25 03:29:53 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 25 Feb 2024 11:29:53 +0000
Subject: [PATCH] ARM: mvebu: Prevent null pointer dereference caused by
 kzalloc failure
In-Reply-To: <20240225060401.52768-1-duoming@zju.edu.cn>
References: <20240225060401.52768-1-duoming@zju.edu.cn>
Message-ID: <ZdsksQG/vMS0lWGq@shell.armlinux.org.uk>

On Sun, Feb 25, 2024 at 02:04:01PM +0800, Duoming Zhou wrote:
> The kzalloc() in i2c_quirk() will return null if the physical
> memory has run out. As a result, if we dereference the new_compat
> pointer, the null pointer dereference bug will happen.
> 
> This patch adds a check to avoid null pointer dereference.

Yet again another janitorial patch that is Way too focused on a single
issue, rather than analysing the code and proposing the best fix. :(

What if the two kstrdup() fail?

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


From kurt at linutronix.de  Sun Feb 25 03:38:37 2024
From: kurt at linutronix.de (Kurt Kanzenbach)
Date: Sun, 25 Feb 2024 12:38:37 +0100
Subject: [PATCH net v2] net: stmmac: Complete meta data only when enabled
Message-ID: <20240222-stmmac_xdp-v2-1-4beee3a037e4@linutronix.de>

Currently using plain XDP/ZC sockets on stmmac results in a kernel crash:

|[  255.822584] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
|[...]
|[  255.822764] Call trace:
|[  255.822766]  stmmac_tx_clean.constprop.0+0x848/0xc38

The program counter indicates xsk_tx_metadata_complete(). It works on
compl->tx_timestamp, which is not set by xsk_tx_metadata_to_compl() due to
missing meta data. Therefore, call xsk_tx_metadata_complete() only when
meta data is actually used.

Tested on imx93 without XDP, with XDP and with XDP/ZC.

Fixes: 1347b419318d ("net: stmmac: Add Tx HWTS support to XDP ZC")
Suggested-by: Serge Semin <fancer.lancer at gmail.com>
Tested-by: Serge Semin <fancer.lancer at gmail.com>
Link: https://lore.kernel.org/netdev/87r0h7wg8u.fsf at kurt.kurt.home/
Acked-by: Stanislav Fomichev <sdf at google.com>
Signed-off-by: Kurt Kanzenbach <kurt at linutronix.de>
---
Changes in v2:
- Add more details to change log (Maciej)
- Link to v1: https://lore.kernel.org/r/20240222-stmmac_xdp-v1-1-e8d2d2b79ff0 at linutronix.de
---
 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 e80d77bd9f1f..8b77c0952071 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2672,7 +2672,8 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue,
 			}
 			if (skb) {
 				stmmac_get_tx_hwtstamp(priv, p, skb);
-			} else {
+			} else if (tx_q->xsk_pool &&
+				   xp_tx_metadata_enabled(tx_q->xsk_pool)) {
 				struct stmmac_xsk_tx_complete tx_compl = {
 					.priv = priv,
 					.desc = p,

---
base-commit: 2a770cdc4382b457ca3d43d03f0f0064f905a0d0
change-id: 20240222-stmmac_xdp-585ebf1680b3

Best regards,
-- 
Kurt Kanzenbach <kurt at linutronix.de>



From daniel.lezcano at linaro.org  Sun Feb 25 04:37:18 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Sun, 25 Feb 2024 13:37:18 +0100
Subject: [PATCH v2] clocksource/drivers/arm_global_timer: Simplify
 prescaler register access
In-Reply-To: <CAFBinCB6+=PThAUz+BdfeD+DqCpscw3pSwrK2pue+J07vhPh_A@mail.gmail.com>
References: <20240224213529.2601333-1-martin.blumenstingl@googlemail.com>
 <eb54b791-05d7-4eee-825d-373cc78df689@linaro.org>
 <CAFBinCB6+=PThAUz+BdfeD+DqCpscw3pSwrK2pue+J07vhPh_A@mail.gmail.com>
Message-ID: <5d3b6c7c-b526-45e0-95fd-deedad2411f6@linaro.org>

On 24/02/2024 23:13, Martin Blumenstingl wrote:
> On Sat, Feb 24, 2024 at 10:55?PM Daniel Lezcano
> <daniel.lezcano at linaro.org> wrote:
> [...]
>>> @@ -301,7 +298,7 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,
>>>                psv--;
>>>
>>>                /* prescaler within legal range? */
>>> -             if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
>>> +             if (psv < 0 || !FIELD_FIT(GT_CONTROL_PRESCALER_MASK, psv))
>>>                        return NOTIFY_BAD;
>>
>> Won't FIELD_FIT cover psv < 0 also ?
> Hmm, I wanted to reply that it doesn't because internally FIELD_FIT()
> uses a cast:
> ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)
> My original thought was that the cast would clear the sign bit when in
> fact (I think) it will not - it will result in the signed number and
> BIT(31) set.
> So I think you're right, FIELD_FIT() does cover it.
> 
> However, there's something else odd with this code:
> We're dividing two frequencies (using DIV_ROUND_CLOSEST) which are two
> unsigned values. So the result of the division can never be negative:
>    psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate);
> However, we're additionally decrementing psv by one:
>    psv--;
> So in reality it can only ever be negative if the result of the
> division was zero (for example if new_rate is smaller than
> gt_target_rate).
> However, in that case we would have crashed - with a division by zero
> - in the statement right in the middle of the two mentioned above:
>    if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)
> 
> So I think we need another patch (it's best to order that before this
> one): make psv an unsigned int and error out before trying to divide
> by zero.
> If you have any objections: let me know, otherwise I'll prepare a
> patch tomorrow.

I think it makes perfectly sense, thanks for making the code nicer

-- 
<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 shawnguo2 at yeah.net  Sun Feb 25 04:45:16 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 20:45:16 +0800
Subject: [PATCH 1/1] arm64: dts: freescale: imx8mm/imx8mq: mba8mx: Use
 PCIe clock generator
In-Reply-To: <20240220142306.2514269-1-alexander.stein@ew.tq-group.com>
References: <20240220142306.2514269-1-alexander.stein@ew.tq-group.com>
Message-ID: <Zds2XDdwHX6veVDe@dragon>

On Tue, Feb 20, 2024 at 03:23:06PM +0100, Alexander Stein wrote:
> PCIe reference clock is provided by Renesas 9FGV0441. Reference this
> instead of a fixed-clock.
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 04:47:18 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 20:47:18 +0800
Subject: [PATCH 1/2] arm64: dts: imx8mq: tqma8mq-mba8mx: Add missing USB
 vbus supply
In-Reply-To: <20240220153334.2624873-1-alexander.stein@ew.tq-group.com>
References: <20240220153334.2624873-1-alexander.stein@ew.tq-group.com>
Message-ID: <Zds21pw+jQF+/YPv@dragon>

On Tue, Feb 20, 2024 at 04:33:33PM +0100, Alexander Stein wrote:
> VBUS 5V is statically provided to both USB host and on-bard USB-hub.
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 04:48:31 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 20:48:31 +0800
Subject: [PATCH 1/1] arm64: dts: imx8mn: tqma8mqnl-mba8mx: Add USB DR
 overlay
In-Reply-To: <20240220160338.2683715-1-alexander.stein@ew.tq-group.com>
References: <20240220160338.2683715-1-alexander.stein@ew.tq-group.com>
Message-ID: <Zds3H7xzaSAH3JrX@dragon>

On Tue, Feb 20, 2024 at 05:03:37PM +0100, Alexander Stein wrote:
> imx8mn has only one USB interface. The platform supports using as USB host
> (default), or switch to USB DR using this overlay.
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 04:59:26 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 20:59:26 +0800
Subject: [PATCH 1/1] arm64: dts: mba8xx: Add missing #interrupt-cells
In-Reply-To: <20240221144012.533946-1-alexander.stein@ew.tq-group.com>
References: <20240221144012.533946-1-alexander.stein@ew.tq-group.com>
Message-ID: <Zds5rnsi8DFREQXx@dragon>

On Wed, Feb 21, 2024 at 03:40:12PM +0100, Alexander Stein wrote:
> The GPIO expander is a interrupt-controller, so add the missing
>  #interrupt-cells property as well.
> 
> Fixes: 71363a485ad0c ("arm64: dts: freescale: add initial device tree for TQMa8Xx")
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:01:32 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:01:32 +0800
Subject: [PATCH 1/1] ARM: dts: ls1021a: Enable usb3-lpm-capable for usb3
 node
In-Reply-To: <20240221221510.3762096-1-Frank.Li@nxp.com>
References: <20240221221510.3762096-1-Frank.Li@nxp.com>
Message-ID: <Zds6LCtHJ2nEzIkP@dragon>

On Wed, Feb 21, 2024 at 05:15:09PM -0500, Frank Li wrote:
> From: Li Yang <leoyang.li at nxp.com>
> 
> Enable USB3 HW LPM feature.
> 
> Signed-off-by: Ran Wang <ran.wang_1 at nxp.com>
> Signed-off-by: Li Yang <leoyang.li at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:03:43 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:03:43 +0800
Subject: [PATCH] arm64: dts: imx8mm-evk: Add spdif sound card support
In-Reply-To: <1708582633-6969-1-git-send-email-shengjiu.wang@nxp.com>
References: <1708582633-6969-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <Zds6rztD3msV/gId@dragon>

On Thu, Feb 22, 2024 at 02:17:13PM +0800, Shengjiu Wang wrote:
> Add spdif sound card support, configure the pinmux.
> 
> This sound card supports recording and playing sound
> through spdif interface.
> 
> Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:10:42 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:10:42 +0800
Subject: [PATCH v2 0/4] Update of phyBOARD-Pollux-i.MX8MP
In-Reply-To: <20240222122853.41753-1-y.varakala@phytec.de>
References: <20240222122853.41753-1-y.varakala@phytec.de>
Message-ID: <Zds8Uk83YNx33ufc@dragon>

On Thu, Feb 22, 2024 at 01:28:49PM +0100, Yashwanth Varakala wrote:
> Hello,
> 
> These patches will update the imx8mp-phyboard-pollux devicetree
> with the Muxing and RTC properties.
>  
> Thankyou,
> yashwanth.
> 
> Changes in v2: 
> -Corrected the commit message.
> -Corrected the authorship.
> 
> Dominik Haller (1):
>   arm64: dts: imx8mp-phyboard-pollux: Disable pull-up for CD GPIO
> 
> Teresa Remmet (1):
>   arm64: dts: imx8mp-phyboard-pollux: Reduce drive strength for eqos tx
>     lines
> 
> Yannic Moog (1):
>   arm64: dts: imx8mp-phyboard-pollux: Set debug uart muxing to 0x140
> 
> Yashwanth Varakala (1):
>   arm64: dts: imx8mp-phyboard-pollux: Add and update rtc devicetree node

Applied all, thanks!



From duoming at zju.edu.cn  Sun Feb 25 05:12:29 2024
From: duoming at zju.edu.cn (duoming at zju.edu.cn)
Date: Sun, 25 Feb 2024 21:12:29 +0800 (GMT+08:00)
Subject: [PATCH] ARM: mvebu: Prevent null pointer dereference caused by
 kzalloc failure
In-Reply-To: <ZdsksQG/vMS0lWGq@shell.armlinux.org.uk>
References: <20240225060401.52768-1-duoming@zju.edu.cn>
 <ZdsksQG/vMS0lWGq@shell.armlinux.org.uk>
Message-ID: <7b00c2ef.133fb.18de065459c.Coremail.duoming@zju.edu.cn>

On Sun, 25 Feb 2024 11:29:53 +0000 Russell King (Oracle) wrote:
> > The kzalloc() in i2c_quirk() will return null if the physical
> > memory has run out. As a result, if we dereference the new_compat
> > pointer, the null pointer dereference bug will happen.
> > 
> > This patch adds a check to avoid null pointer dereference.
> 
> Yet again another janitorial patch that is Way too focused on a single
> issue, rather than analysing the code and proposing the best fix. :(
> 
> What if the two kstrdup() fail?

Thank you for your suggestions, I will also add a check to judge
whether two kstrdup() fail. The detail is shown below:

@@ -125,12 +125,20 @@ static void __init i2c_quirk(void)
                struct property *new_compat;

                new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL);
+               if(!new_compat)
+                       continue;

                new_compat->name = kstrdup("compatible", GFP_KERNEL);
                new_compat->length = sizeof("marvell,mv78230-a0-i2c");
                new_compat->value = kstrdup("marvell,mv78230-a0-i2c",
                                                GFP_KERNEL);

+               if (!new_compat->name || !new_compat->value) {
+                       kfree(new_compat->name);
+                       kfree(new_compat->value);
+                       kfree(new_compat);
+                       continue;
+               }
                of_update_property(np, new_compat);
        }
 }

Best regards,
Duoming Zhou

From duoming at zju.edu.cn  Sun Feb 25 05:20:07 2024
From: duoming at zju.edu.cn (duoming at zju.edu.cn)
Date: Sun, 25 Feb 2024 21:20:07 +0800 (GMT+08:00)
Subject: [PATCH] ARM: mvebu: Add check in coherency.c to prevent null
 pointer dereference
In-Reply-To: <Zdsky9nVdwP6Ry0E@shell.armlinux.org.uk>
References: <20240225060450.53044-1-duoming@zju.edu.cn>
 <Zdsky9nVdwP6Ry0E@shell.armlinux.org.uk>
Message-ID: <38bb64c0.1341f.18de06c41e0.Coremail.duoming@zju.edu.cn>

On Sun, 25 Feb 2024 11:30:20 +0000 Russell King (Oracle) wrote:
> > The kzalloc() in armada_375_380_coherency_init() will return
> > null if the physical memory has run out. As a result, if we
> > dereference the property pointer, the null pointer dereference
> > bug will happen.
> > 
> > This patch adds a check to avoid null pointer dereference.
> 
> Again, what if kstrdup() fails?

Thank you for your suggestions, I will also add a check to judge
whether kstrdup() fails.

Best regards,
Duoming Zhou

From shawnguo2 at yeah.net  Sun Feb 25 05:23:30 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:23:30 +0800
Subject: [PATCH] arm64: dts: imx8mp: Fix TC9595 reset GPIO on DH i.MX8M
 Plus DHCOM SoM
In-Reply-To: <20240225033359.416169-1-marex@denx.de>
References: <20240225033359.416169-1-marex@denx.de>
Message-ID: <Zds/UlTwBIpOp1rF@dragon>

On Sun, Feb 25, 2024 at 04:33:42AM +0100, Marek Vasut wrote:
> The TC9595 reset GPIO is SAI1_RXC / GPIO4_IO01, fix the DT accordingly.
> The SAI5_RXD0 / GPIO3_IO21 is thus far unused TC9595 interrupt line.
> 
> Fixes: 20d0b83e712b ("arm64: dts: imx8mp: Add TC9595 bridge on DH electronics i.MX8M Plus DHCOM")
> Signed-off-by: Marek Vasut <marex at denx.de>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:24:19 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:24:19 +0800
Subject: [PATCH] ARM: dts: imx28-evk: Use 'eeprom' as the node name
In-Reply-To: <20240222140127.967528-1-festevam@gmail.com>
References: <20240222140127.967528-1-festevam@gmail.com>
Message-ID: <Zds/g0r5mELwj43R@dragon>

On Thu, Feb 22, 2024 at 11:01:27AM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> Per at24.yaml, the node name should be 'eeprom'.
> 
> Change it accordingly to fix the following schema warning:
> 
> imx28-evk.dtb: at24 at 51: $nodename:0: 'at24 at 51' does not match '^eeprom@[0-9a-f]{1,2}$'
> 	from schema $id: http://devicetree.org/schemas/eeprom/at24.yaml#
> 
> Signed-off-by: Fabio Estevam <festevam at denx.de>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:25:18 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:25:18 +0800
Subject: [PATCH] ARM: dts: imx1-apf9328: Fix Ethernet node name
In-Reply-To: <20240222143449.978519-1-festevam@gmail.com>
References: <20240222143449.978519-1-festevam@gmail.com>
Message-ID: <Zds/vmGcr721UqvU@dragon>

On Thu, Feb 22, 2024 at 11:34:49AM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> Per davicom,dm9000.yaml, the Ethernet node name should be 'ethernet'.
> 
> Change it to fix the following schema warning:
> 
> imx1-apf9328.dtb: eth at 4,c00000: $nodename:0: 'eth at 4,c00000' does not match '^ethernet(@.*)?$'
> 	from schema $id: http://devicetree.org/schemas/net/davicom,dm9000.yaml#
> 
> Signed-off-by: Fabio Estevam <festevam at denx.de>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:26:58 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:26:58 +0800
Subject: [PATCH] arm64: dts: imx93-var-som: Remove phy-supply from eqos
In-Reply-To: <20240223024337.1138755-1-festevam@gmail.com>
References: <20240223024337.1138755-1-festevam@gmail.com>
Message-ID: <ZdtAItyI/dEOqQlt@dragon>

On Thu, Feb 22, 2024 at 11:43:37PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> Per nxp,dwmac-imx.yaml, phy-supply is not a valid property. 
> 
> Remove it to fix the following dt-schema warning:
> 
> imx93-var-som-symphony.dtb: ethernet at 428a0000: Unevaluated properties are not allowed ('phy-supply' was unexpected)
> 	from schema $id: http://devicetree.org/schemas/net/nxp,dwmac-imx.yaml#
> 
> The reg_eqos_phy regulator is marked as 'regulator-always-on', so it is
> safe to remove the phy-supply property.
> 
> Signed-off-by: Fabio Estevam <festevam at denx.de>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:28:44 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:28:44 +0800
Subject: [PATCH] arm64: dts: imx8mp-evk: Fix hdmi@3d node
In-Reply-To: <20240223025738.2486807-1-victor.liu@nxp.com>
References: <20240223025738.2486807-1-victor.liu@nxp.com>
Message-ID: <ZdtAjE2SylK8plBB@dragon>

On Fri, Feb 23, 2024 at 10:57:38AM +0800, Liu Ying wrote:
> The hdmi at 3d node's compatible string is "adi,adv7535" instead of
> "adi,adv7533" or "adi,adv751*".
> 
> Fix the hdmi at 3d node by means of:
> * Use default register addresses for "cec", "edid" and "packet", because
>   there is no need to use a non-default address map.
> * Add missing interrupt related properties.
> * Drop "adi,input-*" properties which are only valid for adv751*.
> * Add VEXT_3V3 fixed regulator.
> * Add "*-supply" properties, since most are required.
> * Fix label names - s/adv7533/adv7535/.
> 
> Fixes: 65344b9bed3a ("arm64: dts: imx8mp-evk: Add HDMI support")
> Signed-off-by: Liu Ying <victor.liu at nxp.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:30:48 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:30:48 +0800
Subject: [PATCH] arm64: dts: imx8mp: Fix LDB clocks property
In-Reply-To: <20240223091522.2880155-1-victor.liu@nxp.com>
References: <20240223091522.2880155-1-victor.liu@nxp.com>
Message-ID: <ZdtBCEwjonmRV0+X@dragon>

On Fri, Feb 23, 2024 at 05:15:22PM +0800, Liu Ying wrote:
> The "media_ldb_root_clk" is the gate clock to enable or disable the clock
> provided by CCM(Clock Control Module) to LDB instead of the "media_ldb"
> clock which is the parent of the "media_ldb_root_clk" clock as a composite
> clock.  Fix LDB clocks property by referencing the "media_ldb_root_clk"
> clock instead of the "media_ldb" clock.
> 
> Fixes: e7567840ecd3 ("arm64: dts: imx8mp: Reorder clock and reg properties")
> Fixes: 94e6197dadc9 ("arm64: dts: imx8mp: Add LCDIF2 & LDB nodes")
> Signed-off-by: Liu Ying <victor.liu at nxp.com>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:35:18 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:35:18 +0800
Subject: [PATCH] arm64: imx8-apalis-v1.1: Remove reset-names from
 ethernet-phy
In-Reply-To: <20240223230113.1258120-1-festevam@gmail.com>
References: <20240223230113.1258120-1-festevam@gmail.com>
Message-ID: <ZdtCFhImDUqdufhw@dragon>

On Fri, Feb 23, 2024 at 08:01:13PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> The 'reset-names' property is not a valid one under ethernet-phy
> and causes the following dt-schema warning:
> 
> /imx8qm-apalis-v1.1-eval-v1.2.dtb: ethernet-phy at 7: 'resets' is a dependency of 'reset-names'
> 	from schema $id: http://devicetree.org/schemas/reset/reset.yaml#
> 
> Remove this property.
> 
> Signed-off-by: Fabio Estevam <festevam at denx.de>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:36:22 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:36:22 +0800
Subject: [PATCH] arm64: dts: imx8mm-kontron-bl-osm-s: Fix Ethernet PHY
 compatible
In-Reply-To: <20240223230916.1261467-1-festevam@gmail.com>
References: <20240223230916.1261467-1-festevam@gmail.com>
Message-ID: <ZdtCVlDRQ+EyHXia@dragon>

On Fri, Feb 23, 2024 at 08:09:16PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam at denx.de>
> 
> According to motorcomm,yt8xxx.yaml, the compatible string must be
> only 'ethernet-phy-id4f51.e91b'.
> 
> Remove 'ethernet-phy-ieee802.3-c22' to fix the following dt-schema warning:
> 
> imx8mm-kontron-bl-osm-s.dtb: ethernet-phy at 0: compatible: ['ethernet-phy-id4f51.e91b', 'ethernet-phy-ieee802.3-c22'] is too long
> 	from schema $id: http://devicetree.org/schemas/net/motorcomm,yt8xxx.yaml#
> 
> Signed-off-by: Fabio Estevam <festevam at denx.de>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:53:59 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:53:59 +0800
Subject: [PATCH v4 10/16] ARM: dts: imx6ul: add missing
 #thermal-sensor-cells
In-Reply-To: <20240224213240.1854709-11-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
 <20240224213240.1854709-11-sre@kernel.org>
Message-ID: <ZdtGdxBtS+Zxiovq@dragon>

On Sat, Feb 24, 2024 at 10:29:42PM +0100, Sebastian Reichel wrote:
> Fix the following warning found via CHECK_DTBS:
> 
> tempmon: '#thermal-sensor-cells' is a required property
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Thanks for the patch!  But I had picked up the one [1] from Alexander
Stein.

Shawn

[1] https://lore.kernel.org/linux-arm-kernel/ZcCNdrQPb10i4rl2 at t480/T/



From shawnguo2 at yeah.net  Sun Feb 25 05:54:20 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:54:20 +0800
Subject: [PATCH v4 08/16] ARM: dts: imx6ull: fix pinctrl node name
In-Reply-To: <20240224213240.1854709-9-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
 <20240224213240.1854709-9-sre@kernel.org>
Message-ID: <ZdtGjOOEx2cWL+oK@dragon>

On Sat, Feb 24, 2024 at 10:29:40PM +0100, Sebastian Reichel wrote:
> pinctrl node name must be either pinctrl or pinmux.
> 
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:55:24 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:55:24 +0800
Subject: [PATCH v4 09/16] ARM: dts: imx6ul: Remove fsl,anatop from usbotg1
In-Reply-To: <20240224213240.1854709-10-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
 <20240224213240.1854709-10-sre@kernel.org>
Message-ID: <ZdtGzO90NGXWj+y3@dragon>

On Sat, Feb 24, 2024 at 10:29:41PM +0100, Sebastian Reichel wrote:
> fsl,anatop should only be added to the usbphy nodes.
> 
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Applied, thanks!



From knaerzche at gmail.com  Sun Feb 25 05:56:02 2024
From: knaerzche at gmail.com (Alex Bee)
Date: Sun, 25 Feb 2024 14:56:02 +0100
Subject: [PATCH v7 19/36] drm/connector: hdmi: Compute bpc and format
 automatically
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-19-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-19-8f4af575fce2@kernel.org>
Message-ID: <67e9fbc5-ed7f-48b9-ae2a-e07c5fbd2218@gmail.com>

Hi Maxime,

Am 22.02.24 um 19:14 schrieb Maxime Ripard:
> Now that we have all the infrastructure needed, we can add some code
> that will, for a given connector state and mode, compute the best output
> format and bpc.
> 
> The algorithm is equivalent to the one already found in i915 and vc4.
> 
> Signed-off-by: Maxime Ripard <mripard at kernel.org>
> ---
>   drivers/gpu/drm/drm_atomic_state_helper.c          | 184 ++++++++++++++++++++-
>   .../gpu/drm/tests/drm_atomic_state_helper_test.c   |  25 ++-
>   2 files changed, 197 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
> index 448b4a73d1c8..9f517599f117 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -31,6 +31,7 @@
>   #include <drm/drm_connector.h>
>   #include <drm/drm_crtc.h>
>   #include <drm/drm_device.h>
> +#include <drm/drm_edid.h>
>   #include <drm/drm_framebuffer.h>
>   #include <drm/drm_plane.h>
>   #include <drm/drm_print.h>
> @@ -662,6 +663,96 @@ connector_state_get_mode(const struct drm_connector_state *conn_state)
>   	return &crtc_state->mode;
>   }
>   
> +static bool
> +sink_supports_format_bpc(const struct drm_connector *connector,
> +			 const struct drm_display_info *info,
> +			 const struct drm_display_mode *mode,
> +			 unsigned int format, unsigned int bpc)
> +{
> +	struct drm_device *dev = connector->dev;
> +	u8 vic = drm_match_cea_mode(mode);
> +
> +	if (vic == 1 && bpc != 8) {
> +		drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
> +		return false;
> +	}
> +
> +	if (!info->is_hdmi &&
> +	    (format != HDMI_COLORSPACE_RGB || bpc != 8)) {
> +		drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
> +		return false;
> +	}
> +
> +	if (!(connector->hdmi.supported_formats & BIT(format))) {
> +		drm_dbg(dev, "%s format unsupported by the connector.\n",
> +			drm_hdmi_connector_get_output_format_name(format));
> +		return false;
> +	}
> +
> +	switch (format) {
> +	case HDMI_COLORSPACE_RGB:
> +		drm_dbg(dev, "RGB Format, checking the constraints.\n");
> +
> +		if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
> +			return false;
> +
> +		if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {
> +			drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
> +			return false;
> +		}
> +
> +		if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {
> +			drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
> +			return false;
> +		}
> +
> +		drm_dbg(dev, "RGB format supported in that configuration.\n");
> +
> +		return true;
> +
> +	case HDMI_COLORSPACE_YUV422:
> +		drm_dbg(dev, "YUV422 format, checking the constraints.\n");
> +
> +		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
> +			drm_dbg(dev, "Sink doesn't support YUV422.\n");
> +			return false;
> +		}
> +
> +		if (bpc != 12) {
> +			drm_dbg(dev, "YUV422 only supports 12 bpc.\n");
> +			return false;
> +		}
> +
I'm not sure this check is really necessary/helpful.
In [0] you are quoting HDMI specs which are saying that YUV422 is just
always 12 bpc - which I guess is correct. The problem I'm seeing here:
There are HDMI 1.4 controllers, like Rockchip Inno HDMI, that support
YUV422 but do not support any other color depth than 8 bpc for RGB or
YUV444. In drmm_connector_hdmi_init you are expecting to give the max bpc
as parameter and (if I'm getting it correctly) I'd had to set it to 12 to
also get YUV422 modes, but I'd also get RGB/YUV444 with bpc > 8 modes which
are not supported by this controller. I guess the same applies to other
HDMI 1.4 controllers that support YUV422. Or would I have to filter it out
myself?
So I guess the easiest way around is to drop the above check since it is
just always 12 bpc for YUV422 and there is no need to filter out anything.
(Same applies to the similar check in [0]).

Regards,
Alex

[0] 
https://lore.kernel.org/lkml/20240222-kms-hdmi-connector-state-v7-13-8f4af575fce2 at kernel.org/
> +		drm_dbg(dev, "YUV422 format supported in that configuration.\n");
> +
> +		return true;
> +
> +	case HDMI_COLORSPACE_YUV444:
> +		drm_dbg(dev, "YUV444 format, checking the constraints.\n");
> +
> +		if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {
> +			drm_dbg(dev, "Sink doesn't support YUV444.\n");
> +			return false;
> +		}
> +
> +		if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_30)) {
> +			drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
> +			return false;
> +		}
> +
> +		if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_36)) {
> +			drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
> +			return false;
> +		}
> +
> +		drm_dbg(dev, "YUV444 format supported in that configuration.\n");
> +
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
>   static enum drm_mode_status
>   hdmi_clock_valid(const struct drm_connector *connector,
>   		 const struct drm_display_mode *mode,
> @@ -706,6 +797,95 @@ hdmi_compute_clock(const struct drm_connector *connector,
>   	return 0;
>   }
>   
> +static bool
> +hdmi_try_format_bpc(const struct drm_connector *connector,
> +		    struct drm_connector_state *state,
> +		    const struct drm_display_mode *mode,
> +		    unsigned int bpc, enum hdmi_colorspace fmt)
> +{
> +	const struct drm_display_info *info = &connector->display_info;
> +	struct drm_device *dev = connector->dev;
> +	int ret;
> +
> +	drm_dbg(dev, "Trying %s output format\n",
> +		drm_hdmi_connector_get_output_format_name(fmt));
> +
> +	if (!sink_supports_format_bpc(connector, info, mode, fmt, bpc)) {
> +		drm_dbg(dev, "%s output format not supported with %u bpc\n",
> +			drm_hdmi_connector_get_output_format_name(fmt), bpc);
> +		return false;
> +	}
> +
> +	ret = hdmi_compute_clock(connector, state, mode, bpc, fmt);
> +	if (ret) {
> +		drm_dbg(dev, "Couldn't compute clock for %s output format and %u bpc\n",
> +			drm_hdmi_connector_get_output_format_name(fmt), bpc);
> +		return false;
> +	}
> +
> +	drm_dbg(dev, "%s output format supported with %u (TMDS char rate: %llu Hz)\n",
> +		drm_hdmi_connector_get_output_format_name(fmt), bpc, state->hdmi.tmds_char_rate);
> +
> +	return true;
> +}
> +
> +static int
> +hdmi_compute_format(const struct drm_connector *connector,
> +		    struct drm_connector_state *state,
> +		    const struct drm_display_mode *mode,
> +		    unsigned int bpc)
> +{
> +	struct drm_device *dev = connector->dev;
> +
> +	if (hdmi_try_format_bpc(connector, state, mode, bpc, HDMI_COLORSPACE_RGB)) {
> +		state->hdmi.output_format = HDMI_COLORSPACE_RGB;
> +		return 0;
> +	}
> +
> +	if (hdmi_try_format_bpc(connector, state, mode, bpc, HDMI_COLORSPACE_YUV422)) {
> +		state->hdmi.output_format = HDMI_COLORSPACE_YUV422;
> +		return 0;
> +	}
> +
> +	drm_dbg(dev, "Failed. No Format Supported for that bpc count.\n");
> +
> +	return -EINVAL;
> +}
> +
> +static int
> +hdmi_compute_config(const struct drm_connector *connector,
> +		    struct drm_connector_state *state,
> +		    const struct drm_display_mode *mode)
> +{
> +	struct drm_device *dev = connector->dev;
> +	unsigned int max_bpc = clamp_t(unsigned int,
> +				       state->max_bpc,
> +				       8, connector->max_bpc);
> +	unsigned int bpc;
> +	int ret;
> +
> +	for (bpc = max_bpc; bpc >= 8; bpc -= 2) {
> +		drm_dbg(dev, "Trying with a %d bpc output\n", bpc);
> +
> +		ret = hdmi_compute_format(connector, state, mode, bpc);
> +		if (ret)
> +			continue;
> +
> +		state->hdmi.output_bpc = bpc;
> +
> +		drm_dbg(dev,
> +			"Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n",
> +			mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
> +			state->hdmi.output_bpc,
> +			drm_hdmi_connector_get_output_format_name(state->hdmi.output_format),
> +			state->hdmi.tmds_char_rate);
> +
> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>   /**
>    * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
>    * @connector: DRM Connector
> @@ -729,9 +909,7 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
>   		connector_state_get_mode(new_state);
>   	int ret;
>   
> -	ret = hdmi_compute_clock(connector, new_state, mode,
> -				 new_state->hdmi.output_bpc,
> -				 new_state->hdmi.output_format);
> +	ret = hdmi_compute_config(connector, new_state, mode);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
> index 5a8750153510..f010fde0eb69 100644
> --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
> @@ -70,9 +70,6 @@ static int light_up_connector(struct kunit *test,
>   	conn_state = drm_atomic_get_connector_state(state, connector);
>   	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
>   
> -	conn_state->hdmi.output_bpc = connector->max_bpc;
> -	conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB;
> -
>   	ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
>   	KUNIT_EXPECT_EQ(test, ret, 0);
>   
> @@ -251,10 +248,15 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
>   						     10);
>   	KUNIT_ASSERT_NOT_NULL(test, priv);
>   
> +	conn = &priv->connector;
> +	ret = set_connector_edid(test, conn,
> +				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
> +				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
> +	KUNIT_ASSERT_EQ(test, ret, 0);
> +
>   	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
>   	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
>   
> -	conn = &priv->connector;
>   	preferred = find_preferred_mode(conn);
>   	KUNIT_ASSERT_NOT_NULL(test, preferred);
>   
> @@ -272,11 +274,11 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
>   	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
>   	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
>   
> -	new_conn_state->hdmi.output_bpc = 8;
> +	new_conn_state->max_requested_bpc = 8;
>   
>   	KUNIT_ASSERT_NE(test,
> -			old_conn_state->hdmi.output_bpc,
> -			new_conn_state->hdmi.output_bpc);
> +			old_conn_state->max_requested_bpc,
> +			new_conn_state->max_requested_bpc);
>   
>   	ret = drm_atomic_check_only(state);
>   	KUNIT_ASSERT_EQ(test, ret, 0);
> @@ -320,10 +322,15 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
>   						     10);
>   	KUNIT_ASSERT_NOT_NULL(test, priv);
>   
> +	conn = &priv->connector;
> +	ret = set_connector_edid(test, conn,
> +				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
> +				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
> +	KUNIT_ASSERT_EQ(test, ret, 0);
> +
>   	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
>   	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
>   
> -	conn = &priv->connector;
>   	preferred = find_preferred_mode(conn);
>   	KUNIT_ASSERT_NOT_NULL(test, preferred);
>   
> @@ -670,7 +677,7 @@ static void drm_test_check_format_value(struct kunit *test)
>   
>   	conn = &priv->connector;
>   	conn_state = conn->state;
> -	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
> +	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 0);
>   }
>   
>   /*
> 



From shawnguo2 at yeah.net  Sun Feb 25 05:55:45 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:55:45 +0800
Subject: [PATCH v4 11/16] ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
In-Reply-To: <20240224213240.1854709-12-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
 <20240224213240.1854709-12-sre@kernel.org>
Message-ID: <ZdtG4RjqshJKR32p@dragon>

On Sat, Feb 24, 2024 at 10:29:43PM +0100, Sebastian Reichel wrote:
> Replace all "xnur-gpio" with "xnur-gpios" in the i.MX6UL(L) Touchscreen
> node, since the -gpio suffix is deprecated. All known implementations of
> this binding can handle -gpio and -gpios since day 1, so this should be
> fully backwards compatible.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:56:01 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:56:01 +0800
Subject: [PATCH v4 12/16] ARM: dts: nxp: imx6ul: fix touchscreen node name
In-Reply-To: <20240224213240.1854709-13-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
 <20240224213240.1854709-13-sre@kernel.org>
Message-ID: <ZdtG8SVU36/KOEjP@dragon>

On Sat, Feb 24, 2024 at 10:29:44PM +0100, Sebastian Reichel wrote:
> The canonical node name for touchscreens is "touchscreen",
> so update the i.MX6UL "tsc" node accordingly.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:56:16 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:56:16 +0800
Subject: [PATCH v4 13/16] ARM: dts: nxp: imx: fix weim node name
In-Reply-To: <20240224213240.1854709-14-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
 <20240224213240.1854709-14-sre@kernel.org>
Message-ID: <ZdtHAF6+fTYOm2co@dragon>

On Sat, Feb 24, 2024 at 10:29:45PM +0100, Sebastian Reichel wrote:
> DT node names should be generic, so replace "weim" node name with
> "memory-controller" in all i.MX SoC DT files.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:57:21 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:57:21 +0800
Subject: [PATCH v4 14/16] dt-bindings: vendor-prefixes: add UNI-T
In-Reply-To: <20240224213240.1854709-15-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
 <20240224213240.1854709-15-sre@kernel.org>
Message-ID: <ZdtHQRK3y06pExMt@dragon>

On Sat, Feb 24, 2024 at 10:29:46PM +0100, Sebastian Reichel wrote:
> Uni-Trend Technology is a manufacturer of measurement
> and testing tools.
> 
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 05:57:35 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 21:57:35 +0800
Subject: [PATCH v4 15/16] dt-bindings: arm: add UNI-T UTi260B
In-Reply-To: <20240224213240.1854709-16-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
 <20240224213240.1854709-16-sre@kernel.org>
Message-ID: <ZdtHT2dm36/Tpz3F@dragon>

On Sat, Feb 24, 2024 at 10:29:47PM +0100, Sebastian Reichel wrote:
> Add compatible value for i.MX6ULL based UNI-T UTi260B thermal camera.
> 
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Applied, thanks!



From shawnguo2 at yeah.net  Sun Feb 25 06:15:57 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 22:15:57 +0800
Subject: [PATCH v4 16/16] ARM: dts: imx6ull-uti260b: Add board
In-Reply-To: <20240224213240.1854709-17-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
 <20240224213240.1854709-17-sre@kernel.org>
Message-ID: <ZdtLnV4IutdMbz4S@dragon>

On Sat, Feb 24, 2024 at 10:29:48PM +0100, Sebastian Reichel wrote:
> Add UNI-T UTi260b thermal camera board.
> 
> Reviewed-by: Stefan Wahren <wahrenst at gmx.net>
> Signed-off-by: Sebastian Reichel <sre at kernel.org>

Can we change the patch subject to something like below?

  ARM: dts: imx: Add UNI-T UTi260b thermal camera board

Shawn



From duoming at zju.edu.cn  Sun Feb 25 06:29:32 2024
From: duoming at zju.edu.cn (Duoming Zhou)
Date: Sun, 25 Feb 2024 22:29:32 +0800
Subject: [PATCH v2] ARM: mvebu: Add error handling in i2c_quirk to prevent bugs
Message-ID: <20240225142932.5138-1-duoming@zju.edu.cn>

The kzalloc() and the two kstrdup in i2c_quirk() will return null
if the physical memory has run out. As a result, if we dereference
these null values, the null pointer dereference bugs will happen.

This patch adds error handling to avoid null pointer dereference.

Fixes: 5fd62066d290 ("ARM: mvebu: Add thermal quirk for the Armada 375 DB board")
Signed-off-by: Duoming Zhou <duoming at zju.edu.cn>
---
Changes in v2:
  - Adds checks to judge whether two kstrdup() fail.

 arch/arm/mach-mvebu/board-v7.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
index fd5d0c8ff69..c31ac08d24a 100644
--- a/arch/arm/mach-mvebu/board-v7.c
+++ b/arch/arm/mach-mvebu/board-v7.c
@@ -125,12 +125,20 @@ static void __init i2c_quirk(void)
 		struct property *new_compat;
 
 		new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL);
+		if (!new_compat)
+			continue;
 
 		new_compat->name = kstrdup("compatible", GFP_KERNEL);
 		new_compat->length = sizeof("marvell,mv78230-a0-i2c");
 		new_compat->value = kstrdup("marvell,mv78230-a0-i2c",
 						GFP_KERNEL);
 
+		if (!new_compat->name || !new_compat->value) {
+			kfree(new_compat->name);
+			kfree(new_compat->value);
+			kfree(new_compat);
+			continue;
+		}
 		of_update_property(np, new_compat);
 	}
 }
-- 
2.17.1



From shawnguo2 at yeah.net  Sun Feb 25 06:31:03 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Sun, 25 Feb 2024 22:31:03 +0800
Subject: [GIT PULL] i.MX fixes for 6.8, round 2
Message-ID: <ZdtPJzdenRybI+Bq@dragon>

The following changes since commit 7bca405c986075c99b9f729d3587b5c45db39d01:

  bus: imx-weim: fix valid range check (2024-02-06 14:10:47 +0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-fixes-6.8-2

for you to fetch changes up to 65e32301e1a0a436bf542674c23030d0dcc1afde:

  arm64: dts: imx8mp: Fix LDB clocks property (2024-02-25 21:30:17 +0800)

----------------------------------------------------------------
i.MX fixes for 6.8, round 2:

- Update MAINTAINERS to use a public mailing list for NXP i.MX
  development.
- Re-enable CONFIG_BACKLIGHT_CLASS_DEVICE in imx_v6_v7_defconfig to fix
  a backlight regression.
- Remove DSI port endpoints from i.MX7 SoC DTSI to fix a display
  regression.
- Fix LDB clocks property for i.MX8MP device tree.
- Fix TC9595 reset GPIO on DH i.MX8M Plus DHCOM SoM.

----------------------------------------------------------------
Daniel Baluta (1):
      MAINTAINERS: Use a proper mailinglist for NXP i.MX development

Fabio Estevam (1):
      ARM: imx_v6_v7_defconfig: Restore CONFIG_BACKLIGHT_CLASS_DEVICE

Francesco Dolcini (1):
      ARM: dts: imx7: remove DSI port endpoints

Liu Ying (1):
      arm64: dts: imx8mp: Fix LDB clocks property

Marek Vasut (1):
      arm64: dts: imx8mp: Fix TC9595 reset GPIO on DH i.MX8M Plus DHCOM SoM

 MAINTAINERS                                        | 16 ++++++-------
 arch/arm/boot/dts/nxp/imx/imx7s.dtsi               | 26 ----------------------
 arch/arm/configs/imx_v6_v7_defconfig               |  1 +
 .../arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi |  2 +-
 arch/arm64/boot/dts/freescale/imx8mp.dtsi          |  2 +-
 5 files changed, 11 insertions(+), 36 deletions(-)



From duoming at zju.edu.cn  Sun Feb 25 06:31:22 2024
From: duoming at zju.edu.cn (Duoming Zhou)
Date: Sun, 25 Feb 2024 22:31:22 +0800
Subject: [PATCH v2] ARM: mvebu: Add error handling in coherency.c to prevent bugs
Message-ID: <20240225143122.5640-1-duoming@zju.edu.cn>

The kzalloc() and kstrdup() in armada_375_380_coherency_init()
will return null if the physical memory has run out. As a result,
if we dereference these null pointers, the null pointer dereference
bugs will happen.

This patch adds error handling to avoid null pointer dereference.

Fixes: 497a92308af8 ("ARM: mvebu: implement L2/PCIe deadlock workaround")
Signed-off-by: Duoming Zhou <duoming at zju.edu.cn>
---
Changes in v2:
  - Adds checks to judge whether kstrdup() fails.

 arch/arm/mach-mvebu/coherency.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index a6b621ff0b8..be50c83bfef 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -191,7 +191,13 @@ static void __init armada_375_380_coherency_init(struct device_node *np)
 		struct property *p;
 
 		p = kzalloc(sizeof(*p), GFP_KERNEL);
+		if (!p)
+			continue;
 		p->name = kstrdup("arm,io-coherent", GFP_KERNEL);
+		if (!p->name) {
+			kfree(p);
+			continue;
+		}
 		of_add_property(cache_dn, p);
 	}
 }
-- 
2.17.1



From dmitry.baryshkov at linaro.org  Sun Feb 25 06:50:00 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sun, 25 Feb 2024 16:50:00 +0200
Subject: [PATCH v7 00/36] drm/connector: Create HDMI Connector infrastructure
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
Message-ID: <CAA8EJpqB+Mf4jp88__r5dfsRSuGdAB+Q3vK5MBfBXysvRB92iQ@mail.gmail.com>

Hi Maxime,

On Thu, 22 Feb 2024 at 20:14, Maxime Ripard <mripard at kernel.org> wrote:
>
> Hi,
>
> Here's a series that creates some extra infrastructure specifically
> targeted at HDMI controllers.
>
> The idea behind this series came from a recent discussion on IRC during
> which we discussed infoframes generation of i915 vs everything else.
>
> Infoframes generation code still requires some decent boilerplate, with
> each driver doing some variation of it.
>
> In parallel, while working on vc4, we ended up converting a lot of i915
> logic (mostly around format / bpc selection, and scrambler setup) to
> apply on top of a driver that relies only on helpers.
>
> While currently sitting in the vc4 driver, none of that logic actually
> relies on any driver or hardware-specific behaviour.
>
> The only missing piece to make it shareable are a bunch of extra
> variables stored in a state (current bpc, format, RGB range selection,
> etc.).
>
> The initial implementation was relying on some generic subclass of
> drm_connector to address HDMI connectors, with a bunch of helpers that
> will take care of all the "HDMI Spec" related code. Scrambler setup is
> missing at the moment but can easily be plugged in.
>
> The feedback was that creating a connector subclass like was done for
> writeback would prevent the adoption of those helpers since it couldn't
> be used in all situations (like when the connector driver can implement
> multiple output) and required more churn to cast between the
> drm_connector and its subclass. The decision was thus to provide a set
> of helper and to store the required variables in drm_connector and
> drm_connector_state. This what has been implemented now.
>
> Hans Verkuil also expressed interest in implementing a mechanism in v4l2
> to retrieve infoframes from HDMI receiver and implementing a tool to
> decode (and eventually check) infoframes. His current work on
> edid-decode to enable that based on that series can be found here:
> https://git.linuxtv.org/hverkuil/edid-decode.git/log/?h=hverkuil
>
> And some more context here:
> https://lore.kernel.org/dri-devel/50db7366-cd3d-4675-aaad-b857202234de at xs4all.nl/
>
> This series thus leverages the infoframe generation code to expose it
> through debugfs.

[...]

>
> Let me know what you think,
> Maxime

The overall idea looks great. I've started checking how I can use that
for our msm devices family, which makes use of bridges and
drm_bridge_connector.
My current idea is to extend the drm_bridge_funcs with the new
callback to be called once the drm_connector has been instantiated.
This way all the bridges can influence new connector.
Another possibility is to follow drm_bridge_connector design closely
and let it call into drm_connector_hdmi code if it detects that the
last bridge is the HDMI one.
WDYT?

Some context, older MSM devices have an on-die HDMI encoder,
implemented as drm_bridge at drivers/gpu/drm/msm/hdmi. Newer
generation of devices has dropped the on-die HDMI implementation in
favour of using external DSI-to-HDMI bridges, like Lontium LT9611 or
LT9611UXC. I'm looking at enabling new HDMI infrastructure for both
cases.

-- 
With best wishes
Dmitry


From dmitry.baryshkov at linaro.org  Sun Feb 25 07:02:51 2024
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Sun, 25 Feb 2024 17:02:51 +0200
Subject: [PATCH v7 25/36] drm/connector: hdmi: Add Infoframes generation
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-25-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> <20240222-kms-hdmi-connector-state-v7-25-8f4af575fce2@kernel.org>
Message-ID: <CAA8EJpri_whY8YfX2BsBjMN_4JvFsU-ogfr1W-KUKrasRoH-WQ@mail.gmail.com>

On Thu, 22 Feb 2024 at 20:16, Maxime Ripard <mripard at kernel.org> wrote:
>
> Infoframes in KMS is usually handled by a bunch of low-level helpers
> that require quite some boilerplate for drivers. This leads to
> discrepancies with how drivers generate them, and which are actually
> sent.
>
> Now that we have everything needed to generate them in the HDMI
> connector state, we can generate them in our common logic so that
> drivers can simply reuse what we precomputed.
>
> Signed-off-by: Maxime Ripard <mripard at kernel.org>
> ---
>  drivers/gpu/drm/Kconfig                            |   1 +
>  drivers/gpu/drm/drm_atomic_state_helper.c          | 327 +++++++++++++++++++++
>  drivers/gpu/drm/drm_connector.c                    |  16 +
>  .../gpu/drm/tests/drm_atomic_state_helper_test.c   |   1 +
>  drivers/gpu/drm/tests/drm_connector_test.c         |  12 +
>  include/drm/drm_atomic_state_helper.h              |   8 +
>  include/drm/drm_connector.h                        | 133 +++++++++
>  7 files changed, 498 insertions(+)
>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 872edb47bb53..ad9c467e20ce 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -99,6 +99,7 @@ config DRM_KUNIT_TEST
>  config DRM_KMS_HELPER
>         tristate
>         depends on DRM
> +       select DRM_DISPLAY_HDMI_HELPER
>         help
>           CRTC helpers for KMS drivers.
>
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
> index e66272c0d006..46d9fd2ea8fa 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -38,6 +38,8 @@
>  #include <drm/drm_vblank.h>
>  #include <drm/drm_writeback.h>
>
> +#include <drm/display/drm_hdmi_helper.h>
> +
>  #include <linux/slab.h>
>  #include <linux/dma-fence.h>
>
> @@ -914,6 +916,142 @@ hdmi_compute_config(const struct drm_connector *connector,
>         return -EINVAL;
>  }
>
> +static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
> +                                      struct drm_connector_state *state)
> +{
> +       const struct drm_display_mode *mode =
> +               connector_state_get_mode(state);
> +       struct drm_connector_hdmi_infoframe *infoframe =
> +               &state->hdmi.infoframes.avi;
> +       struct hdmi_avi_infoframe *frame =
> +               &infoframe->data.avi;
> +       bool is_full_range = state->hdmi.is_full_range;
> +       enum hdmi_quantization_range rgb_quant_range =
> +               is_full_range ? HDMI_QUANTIZATION_RANGE_FULL : HDMI_QUANTIZATION_RANGE_LIMITED;
> +       int ret;
> +
> +       ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode);
> +       if (ret)
> +               return ret;
> +
> +       frame->colorspace = state->hdmi.output_format;
> +
> +       drm_hdmi_avi_infoframe_quant_range(frame, connector, mode, rgb_quant_range);
> +       drm_hdmi_avi_infoframe_colorimetry(frame, state);
> +       drm_hdmi_avi_infoframe_bars(frame, state);
> +
> +       infoframe->set = true;
> +
> +       return 0;
> +}
> +
> +static int hdmi_generate_spd_infoframe(const struct drm_connector *connector,
> +                                      struct drm_connector_state *state)
> +{
> +       struct drm_connector_hdmi_infoframe *infoframe =
> +               &state->hdmi.infoframes.spd;
> +       struct hdmi_spd_infoframe *frame =
> +               &infoframe->data.spd;
> +       int ret;
> +
> +       ret = hdmi_spd_infoframe_init(frame,
> +                                     connector->hdmi.vendor,
> +                                     connector->hdmi.product);
> +       if (ret)
> +               return ret;
> +
> +       frame->sdi = HDMI_SPD_SDI_PC;
> +
> +       infoframe->set = true;
> +
> +       return 0;
> +}
> +
> +static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector,
> +                                      struct drm_connector_state *state)
> +{
> +       struct drm_connector_hdmi_infoframe *infoframe =
> +               &state->hdmi.infoframes.hdr_drm;
> +       struct hdmi_drm_infoframe *frame =
> +               &infoframe->data.drm;
> +       int ret;
> +
> +       if (connector->max_bpc < 10)
> +               return 0;
> +
> +       if (!state->hdr_output_metadata)
> +               return 0;
> +
> +       ret = drm_hdmi_infoframe_set_hdr_metadata(frame, state);
> +       if (ret)
> +               return ret;
> +
> +       infoframe->set = true;
> +
> +       return 0;
> +}
> +
> +static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector *connector,
> +                                              struct drm_connector_state *state)
> +{
> +       const struct drm_display_mode *mode =
> +               connector_state_get_mode(state);
> +       struct drm_connector_hdmi_infoframe *infoframe =
> +               &state->hdmi.infoframes.hdmi;
> +       struct hdmi_vendor_infoframe *frame =
> +               &infoframe->data.vendor.hdmi;
> +       int ret;
> +
> +       ret = drm_hdmi_vendor_infoframe_from_display_mode(frame, connector, mode);
> +       if (ret) {
> +               if (ret == -EINVAL)
> +                       return 0;
> +
> +               return ret;
> +       }
> +
> +       infoframe->set = true;
> +
> +       return 0;
> +}
> +
> +static int
> +hdmi_generate_infoframes(const struct drm_connector *connector,
> +                        struct drm_connector_state *state)
> +{
> +       const struct drm_display_info *info = &connector->display_info;
> +       int ret;
> +
> +       if (!info->is_hdmi)
> +               return 0;
> +
> +       if (!info->has_hdmi_infoframe)
> +               return 0;
> +
> +       ret = hdmi_generate_avi_infoframe(connector, state);
> +       if (ret)
> +               return ret;
> +
> +       ret = hdmi_generate_spd_infoframe(connector, state);
> +       if (ret)
> +               return ret;
> +
> +       /*
> +        * Audio Infoframes will be generated by ALSA, and updated by
> +        * drm_atomic_helper_connector_hdmi_update_audio_infoframe().
> +        */
> +
> +       ret = hdmi_generate_hdr_infoframe(connector, state);
> +       if (ret)
> +               return ret;
> +
> +       ret = hdmi_generate_hdmi_vendor_infoframe(connector, state);
> +       if (ret)
> +               return ret;
> +
> +       return 0;
> +}
> +
>  /**
>   * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
>   * @connector: DRM Connector
> @@ -943,6 +1081,10 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
>         if (ret)
>                 return ret;
>
> +       ret = hdmi_generate_infoframes(connector, new_state);
> +       if (ret)
> +               return ret;
> +
>         if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb ||
>             old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
>             old_state->hdmi.output_format != new_state->hdmi.output_format) {
> @@ -960,6 +1102,191 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
>
> +#define HDMI_MAX_INFOFRAME_SIZE                29
> +
> +static int clear_device_infoframe(struct drm_connector *connector,
> +                                 enum hdmi_infoframe_type type)
> +{
> +       const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
> +
> +       if (!funcs || !funcs->clear_infoframe)
> +               return 0;
> +
> +       return funcs->clear_infoframe(connector, type);
> +}
> +
> +static int clear_infoframe(struct drm_connector *connector,
> +                          struct drm_connector_hdmi_infoframe *conn_frame,
> +                          struct drm_connector_hdmi_infoframe *old_frame)
> +{
> +       int ret;
> +
> +       ret = clear_device_infoframe(connector, old_frame->data.any.type);
> +       if (ret)
> +               return ret;
> +
> +       memset(old_frame, 0, sizeof(*old_frame));
> +
> +       return 0;
> +}
> +
> +static int write_device_infoframe(struct drm_connector *connector,
> +                                 union hdmi_infoframe *frame)
> +{
> +       const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
> +       u8 buffer[HDMI_MAX_INFOFRAME_SIZE];
> +       int len;
> +
> +       if (!funcs || !funcs->write_infoframe)
> +               return -ENOSYS;
> +
> +       len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer));
> +       if (len < 0)
> +               return len;
> +
> +       return funcs->write_infoframe(connector, frame->any.type, buffer, len);
> +}
> +
> +static int write_infoframe(struct drm_connector *connector,
> +                          struct drm_connector_hdmi_infoframe *conn_frame,
> +                          struct drm_connector_hdmi_infoframe *new_frame)
> +{
> +       int ret;
> +
> +       ret = write_device_infoframe(connector, &new_frame->data);
> +       if (ret)
> +               return ret;
> +
> +       if (conn_frame)
> +               memcpy(conn_frame, new_frame, sizeof(*conn_frame));
> +
> +       return 0;
> +}
> +
> +static int write_or_clear_infoframe(struct drm_connector *connector,
> +                                   struct drm_connector_hdmi_infoframe *conn_frame,
> +                                   struct drm_connector_hdmi_infoframe *old_frame,
> +                                   struct drm_connector_hdmi_infoframe *new_frame)
> +{
> +       if (new_frame->set)
> +               return write_infoframe(connector, conn_frame, new_frame);
> +
> +       if (old_frame->set && !new_frame->set)
> +               return clear_infoframe(connector, conn_frame, old_frame);
> +
> +       return 0;
> +}
> +
> +#define UPDATE_INFOFRAME(c, os, ns, i)                         \
> +       write_or_clear_infoframe(c,                             \
> +                                &(c)->hdmi.infoframes.i,       \
> +                                &(os)->hdmi.infoframes.i,      \
> +                                &(ns)->hdmi.infoframes.i)
> +
> +/**
> + * drm_atomic_helper_connector_hdmi_update_infoframes - Update the Infoframes
> + * @connector: A pointer to the HDMI connector
> + * @state: The HDMI connector state to generate the infoframe from
> + *
> + * This function is meant for HDMI connector drivers to write their
> + * infoframes. It will typically be used in a
> + * @drm_connector_helper_funcs.atomic_enable implementation.
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
> +                                                      struct drm_atomic_state *state)
> +{
> +       struct drm_connector_state *old_state =
> +               drm_atomic_get_old_connector_state(state, connector);
> +       struct drm_connector_state *new_state =
> +               drm_atomic_get_new_connector_state(state, connector);
> +       struct drm_display_info *info = &connector->display_info;
> +       int ret;
> +
> +       if (!info->is_hdmi)
> +               return 0;
> +
> +       if (!info->has_hdmi_infoframe)
> +               return 0;
> +
> +       mutex_lock(&connector->hdmi.infoframes.lock);
> +
> +       ret = UPDATE_INFOFRAME(connector, old_state, new_state, avi);
> +       if (ret)
> +               goto out;
> +
> +       if (connector->hdmi.infoframes.audio.set) {
> +               ret = write_infoframe(connector,
> +                                     NULL,
> +                                     &connector->hdmi.infoframes.audio);
> +               if (ret)
> +                       goto out;
> +       }
> +
> +       ret = UPDATE_INFOFRAME(connector, old_state, new_state, hdr_drm);
> +       if (ret)
> +               goto out;
> +
> +       ret = UPDATE_INFOFRAME(connector, old_state, new_state, spd);
> +       if (ret)
> +               goto out;
> +
> +       ret = UPDATE_INFOFRAME(connector, old_state, new_state, hdmi);
> +       if (ret)
> +               goto out;
> +
> +out:
> +       mutex_unlock(&connector->hdmi.infoframes.lock);
> +       return ret;
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_infoframes);
> +
> +#undef UPDATE_INFOFRAME
> +#undef UPDATE_INFOFRAME_TOGGLE
> +
> +/**
> + * drm_atomic_helper_connector_hdmi_update_audio_infoframe - Update the Audio Infoframe
> + * @connector: A pointer to the HDMI connector
> + * @frame: A pointer to the audio infoframe to write
> + *
> + * This function is meant for HDMI connector drivers to update their
> + * audio infoframe. It will typically be used in one of the ALSA hooks
> + * (most likely prepare).
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int
> +drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector,
> +                                                       struct hdmi_audio_infoframe *frame)
> +{
> +       struct drm_connector_hdmi_infoframe infoframe = {};
> +       struct drm_display_info *info = &connector->display_info;
> +       int ret;
> +
> +       if (!info->is_hdmi)
> +               return 0;
> +
> +       if (!info->has_hdmi_infoframe)
> +               return 0;
> +
> +       memcpy(&infoframe.data, frame, sizeof(infoframe.data));
> +       infoframe.set = true;
> +
> +       mutex_lock(&connector->hdmi.infoframes.lock);
> +
> +       ret = write_infoframe(connector,
> +                             &connector->hdmi.infoframes.audio,
> +                             &infoframe);
> +
> +       mutex_unlock(&connector->hdmi.infoframes.lock);
> +
> +       return ret;
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe);
> +
>  /**
>   * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
>   * @connector: connector object
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 6ffe59d01698..6cfc301096ef 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -456,6 +456,8 @@ EXPORT_SYMBOL(drmm_connector_init);
>   * drmm_connector_hdmi_init - Init a preallocated HDMI connector
>   * @dev: DRM device
>   * @connector: A pointer to the HDMI connector to init
> + * @vendor: HDMI Controller Vendor name
> + * @product: HDMI Controller Product name
>   * @funcs: callbacks for this connector
>   * @hdmi_funcs: HDMI-related callbacks for this connector
>   * @connector_type: user visible type of the connector
> @@ -476,6 +478,7 @@ EXPORT_SYMBOL(drmm_connector_init);
>   */
>  int drmm_connector_hdmi_init(struct drm_device *dev,
>                              struct drm_connector *connector,
> +                            const char *vendor, const char *product,
>                              const struct drm_connector_funcs *funcs,
>                              const struct drm_connector_hdmi_funcs *hdmi_funcs,
>                              int connector_type,
> @@ -485,6 +488,13 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
>  {
>         int ret;
>
> +       if (!vendor || !product)
> +               return -EINVAL;
> +
> +       if ((strlen(vendor) > DRM_CONNECTOR_HDMI_VENDOR_LEN) ||
> +           (strlen(product) > DRM_CONNECTOR_HDMI_PRODUCT_LEN))
> +               return -EINVAL;
> +
>         if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||
>               connector_type == DRM_MODE_CONNECTOR_HDMIB))
>                 return -EINVAL;
> @@ -500,6 +510,12 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
>                 return ret;
>
>         connector->hdmi.supported_formats = supported_formats;
> +       strtomem_pad(connector->hdmi.vendor, vendor, 0);
> +       strtomem_pad(connector->hdmi.product, product, 0);
> +
> +       ret = drmm_mutex_init(dev, &connector->hdmi.infoframes.lock);

I'd suggest moving this call to the generic __drm_connector_init().
This way no matter how the rest of the drm code (mis)uses the
connector, the lock is always present and valid.

> +       if (ret)
> +               return ret;
>
>         /*
>          * drm_connector_attach_max_bpc_property() requires the
> diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
> index dcc0f7486f49..b28409fe65dd 100644
> --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c
> @@ -203,6 +203,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test,
>
>         conn = &priv->connector;
>         ret = drmm_connector_hdmi_init(drm, conn,
> +                                      "Vendor", "Product",
>                                        &dummy_connector_funcs,
>                                        &dummy_connector_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
> index 6a3651b08c81..b9c80d282380 100644
> --- a/drivers/gpu/drm/tests/drm_connector_test.c
> +++ b/drivers/gpu/drm/tests/drm_connector_test.c
> @@ -189,6 +189,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> @@ -208,6 +209,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> @@ -227,6 +229,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> @@ -246,6 +249,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> @@ -269,6 +273,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> @@ -304,6 +309,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> @@ -339,6 +345,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> @@ -370,6 +377,7 @@ static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> @@ -389,6 +397,7 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> @@ -409,6 +418,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        connector_type,
> @@ -443,6 +453,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        connector_type,
> @@ -708,6 +719,7 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(
>         int ret;
>
>         ret = drmm_connector_hdmi_init(&priv->drm, connector,
> +                                      "Vendor", "Product",
>                                        &dummy_funcs,
>                                        &dummy_hdmi_funcs,
>                                        DRM_MODE_CONNECTOR_HDMIA,
> diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
> index d59d2b3aef9a..22f083968aa8 100644
> --- a/include/drm/drm_atomic_state_helper.h
> +++ b/include/drm/drm_atomic_state_helper.h
> @@ -40,6 +40,8 @@ struct drm_private_state;
>  struct drm_modeset_acquire_ctx;
>  struct drm_device;
>
> +struct hdmi_audio_infoframe;
> +
>  void __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *state,
>                                           struct drm_crtc *crtc);
>  void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
> @@ -88,6 +90,12 @@ void
>  __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state);
>  void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
>                                           struct drm_connector_state *state);
> +
> +int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector,
> +                                                           struct hdmi_audio_infoframe *frame);
> +int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
> +                                                      struct drm_atomic_state *state);
> +
>  void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
>                                                      struct drm_private_state *state);
>
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 3eaf4d54364d..5964ef283022 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -914,6 +914,21 @@ struct drm_tv_connector_state {
>         unsigned int hue;
>  };
>
> +/**
> + * struct drm_connector_hdmi_infoframe - HDMI Infoframe container
> + */
> +struct drm_connector_hdmi_infoframe {
> +       /**
> +        * @data: HDMI Infoframe structure
> +        */
> +       union hdmi_infoframe data;
> +
> +       /**
> +        * @set: Is the content of @data valid?
> +        */
> +       bool set;
> +};
> +
>  /**
>   * struct drm_connector_state - mutable connector state
>   */
> @@ -1070,6 +1085,35 @@ struct drm_connector_state {
>                  */
>                 enum drm_hdmi_broadcast_rgb broadcast_rgb;
>
> +               /**
> +                * @infoframes: HDMI Infoframes matching that state
> +                */
> +               struct {
> +                       /**
> +                        * @avi: AVI Infoframes structure matching our
> +                        * state.
> +                        */
> +                       struct drm_connector_hdmi_infoframe avi;
> +
> +                       /**
> +                        * @hdr_drm: DRM (Dynamic Range and Mastering)
> +                        * Infoframes structure matching our state.
> +                        */
> +                       struct drm_connector_hdmi_infoframe hdr_drm;
> +
> +                       /**
> +                        * @spd: SPD Infoframes structure matching our
> +                        * state.
> +                        */
> +                       struct drm_connector_hdmi_infoframe spd;
> +
> +                       /**
> +                        * @vendor: HDMI Vendor Infoframes structure
> +                        * matching our state.
> +                        */
> +                       struct drm_connector_hdmi_infoframe hdmi;
> +               } infoframes;
> +
>                 /**
>                  * @is_full_range: Is the output supposed to use a full
>                  * RGB Quantization Range or not?
> @@ -1115,6 +1159,41 @@ struct drm_connector_hdmi_funcs {
>         (*tmds_char_rate_valid)(const struct drm_connector *connector,
>                                 const struct drm_display_mode *mode,
>                                 unsigned long long tmds_rate);
> +
> +       /**
> +        * @clear_infoframe:
> +        *
> +        * This callback is invoked through
> +        * @drm_atomic_helper_hdmi_connector_update_infoframes during a
> +        * commit to clear the infoframes into the hardware. It will be
> +        * called multiple times, once for every disabled infoframe
> +        * type.
> +        *
> +        * The @clear_infoframe callback is optional.
> +        *
> +        * Returns:
> +        * 0 on success, a negative error code otherwise
> +        */
> +       int (*clear_infoframe)(struct drm_connector *connector,
> +                              enum hdmi_infoframe_type type);
> +
> +       /**
> +        * @write_infoframe:
> +        *
> +        * This callback is invoked through
> +        * @drm_atomic_helper_hdmi_connector_update_infoframes during a
> +        * commit to program the infoframes into the hardware. It will
> +        * be called multiple times, once for every updated infoframe
> +        * type.
> +        *
> +        * The @write_infoframe callback is mandatory.
> +        *
> +        * Returns:
> +        * 0 on success, a negative error code otherwise
> +        */
> +       int (*write_infoframe)(struct drm_connector *connector,
> +                              enum hdmi_infoframe_type type,
> +                              const u8 *buffer, size_t len);
>  };
>
>  /**
> @@ -1986,6 +2065,18 @@ struct drm_connector {
>          * @hdmi: HDMI-related variable and properties.
>          */
>         struct {
> +#define DRM_CONNECTOR_HDMI_VENDOR_LEN  8
> +               /**
> +                * @vendor: HDMI Controller Vendor Name
> +                */
> +               unsigned char vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] __nonstring;
> +
> +#define DRM_CONNECTOR_HDMI_PRODUCT_LEN 16
> +               /**
> +                * @product: HDMI Controller Product Name
> +                */
> +               unsigned char product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] __nonstring;
> +
>                 /**
>                  * @supported_formats: Bitmask of @hdmi_colorspace
>                  * supported by the controller.
> @@ -1996,6 +2087,47 @@ struct drm_connector {
>                  * @funcs: HDMI connector Control Functions
>                  */
>                 const struct drm_connector_hdmi_funcs *funcs;
> +
> +               /**
> +                * @infoframes: Current Infoframes output by the connector
> +                */
> +               struct {
> +                       /**
> +                        * @lock: Mutex protecting against concurrent access to
> +                        * the infoframes, most notably between KMS and ALSA.
> +                        */
> +                       struct mutex lock;
> +
> +                       /**
> +                        * @audio: Current Audio Infoframes structure. Protected
> +                        * by @lock.
> +                        */
> +                       struct drm_connector_hdmi_infoframe audio;
> +
> +                       /**
> +                        * @avi: Current AVI Infoframes structure. Protected by
> +                        * @lock.
> +                        */
> +                       struct drm_connector_hdmi_infoframe avi;
> +
> +                       /**
> +                        * @hdr_drm: Current DRM (Dynamic Range and Mastering)
> +                        * Infoframes structure. Protected by @lock.
> +                        */
> +                       struct drm_connector_hdmi_infoframe hdr_drm;
> +
> +                       /**
> +                        * @spd: Current SPD Infoframes structure. Protected by
> +                        * @lock.
> +                        */
> +                       struct drm_connector_hdmi_infoframe spd;
> +
> +                       /**
> +                        * @vendor: Current HDMI Vendor Infoframes structure.
> +                        * Protected by @lock.
> +                        */
> +                       struct drm_connector_hdmi_infoframe hdmi;
> +               } infoframes;
>         } hdmi;
>  };
>
> @@ -2017,6 +2149,7 @@ int drmm_connector_init(struct drm_device *dev,
>                         struct i2c_adapter *ddc);
>  int drmm_connector_hdmi_init(struct drm_device *dev,
>                              struct drm_connector *connector,
> +                            const char *vendor, const char *product,
>                              const struct drm_connector_funcs *funcs,
>                              const struct drm_connector_hdmi_funcs *hdmi_funcs,
>                              int connector_type,
>
> --
> 2.43.2
>


-- 
With best wishes
Dmitry


From martin.blumenstingl at googlemail.com  Sun Feb 25 07:13:33 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 25 Feb 2024 16:13:33 +0100
Subject: [PATCH v3 0/3] clocksource/drivers/arm_global_timer: Three improvements
Message-ID: <20240225151336.2728533-1-martin.blumenstingl@googlemail.com>

These are three improvements / fixes for the arm_global_timer driver.

Changes from v2 at [1]:
- add patches 1 and 2 (which is why this is now a series instead of a
  single patch) as in the code review process more issues have been
  spotted that need fixing
- remove "psv < 0" check from patch 3 (as this check is now impossible
  as patch 2 makes the variable in question an unsigned long with a
  check for zero and returning before decrementing psv).

Changes from v1 at [0]:
- use FIELD_FIT() to check whether psv overflows the register
- update the description accordingly


[0] https://lore.kernel.org/lkml/20240221214348.2299636-1-martin.blumenstingl at googlemail.com/
[1] https://lore.kernel.org/lkml/20240224213529.2601333-1-martin.blumenstingl at googlemail.com/


Martin Blumenstingl (3):
  clocksource/drivers/arm_global_timer: Make gt_target_rate unsigned
    long
  clocksource/drivers/arm_global_timer: Guard against division by zero
  clocksource/drivers/arm_global_timer: Simplify prescaler register
    access

 drivers/clocksource/arm_global_timer.c | 31 ++++++++++++--------------
 1 file changed, 14 insertions(+), 17 deletions(-)

-- 
2.44.0



From martin.blumenstingl at googlemail.com  Sun Feb 25 07:13:34 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 25 Feb 2024 16:13:34 +0100
Subject: [PATCH v3 1/3] clocksource/drivers/arm_global_timer: Make gt_target_rate unsigned long
In-Reply-To: <20240225151336.2728533-1-martin.blumenstingl@googlemail.com>
References: <20240225151336.2728533-1-martin.blumenstingl@googlemail.com>
Message-ID: <20240225151336.2728533-2-martin.blumenstingl@googlemail.com>

Change the data type of gt_target_rate to unsigned long as this is what
we get back from clk_get_rate().

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 drivers/clocksource/arm_global_timer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index 8dd1e46b7176..fb3ffd54c822 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -52,7 +52,8 @@
  */
 static void __iomem *gt_base;
 static struct notifier_block gt_clk_rate_change_nb;
-static u32 gt_psv_new, gt_psv_bck, gt_target_rate;
+static u32 gt_psv_new, gt_psv_bck;
+static unsigned long gt_target_rate;
 static int gt_ppi;
 static struct clock_event_device __percpu *gt_evt;
 
-- 
2.44.0



From martin.blumenstingl at googlemail.com  Sun Feb 25 07:13:36 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 25 Feb 2024 16:13:36 +0100
Subject: [PATCH v3 3/3] clocksource/drivers/arm_global_timer: Simplify prescaler register access
In-Reply-To: <20240225151336.2728533-1-martin.blumenstingl@googlemail.com>
References: <20240225151336.2728533-1-martin.blumenstingl@googlemail.com>
Message-ID: <20240225151336.2728533-4-martin.blumenstingl@googlemail.com>

Use GENMASK() to define the prescaler mask and make the whole driver use
the mask (together with helpers such as FIELD_{GET,PREP,FIT}) instead of
needing an additional shift and max value constant.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 drivers/clocksource/arm_global_timer.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index 257599d682f0..8a82b60b467b 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -9,6 +9,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/bitfield.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/cpu.h>
@@ -31,10 +32,7 @@
 #define GT_CONTROL_COMP_ENABLE		BIT(1)	/* banked */
 #define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
 #define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
-#define GT_CONTROL_PRESCALER_SHIFT      8
-#define GT_CONTROL_PRESCALER_MAX        0xFF
-#define GT_CONTROL_PRESCALER_MASK       (GT_CONTROL_PRESCALER_MAX << \
-					 GT_CONTROL_PRESCALER_SHIFT)
+#define GT_CONTROL_PRESCALER_MASK	GENMASK(15, 8)
 
 #define GT_INT_STATUS	0x0c
 #define GT_INT_STATUS_EVENT_FLAG	BIT(0)
@@ -248,7 +246,7 @@ static void gt_write_presc(u32 psv)
 
 	reg = readl(gt_base + GT_CONTROL);
 	reg &= ~GT_CONTROL_PRESCALER_MASK;
-	reg |= psv << GT_CONTROL_PRESCALER_SHIFT;
+	reg |= FIELD_PREP(GT_CONTROL_PRESCALER_MASK, psv);
 	writel(reg, gt_base + GT_CONTROL);
 }
 
@@ -257,8 +255,7 @@ static u32 gt_read_presc(void)
 	u32 reg;
 
 	reg = readl(gt_base + GT_CONTROL);
-	reg &= GT_CONTROL_PRESCALER_MASK;
-	return reg >> GT_CONTROL_PRESCALER_SHIFT;
+	return FIELD_GET(GT_CONTROL_PRESCALER_MASK, reg);
 }
 
 static void __init gt_delay_timer_init(void)
@@ -273,9 +270,9 @@ static int __init gt_clocksource_init(void)
 	writel(0, gt_base + GT_COUNTER0);
 	writel(0, gt_base + GT_COUNTER1);
 	/* set prescaler and enable timer on all the cores */
-	writel(((CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) <<
-		GT_CONTROL_PRESCALER_SHIFT)
-	       | GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
+	writel(FIELD_PREP(GT_CONTROL_PRESCALER_MASK,
+			  CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) |
+	       GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
 
 #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 	sched_clock_register(gt_sched_clock_read, 64, gt_target_rate);
@@ -301,7 +298,7 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,
 		psv--;
 
 		/* prescaler within legal range? */
-		if (psv > GT_CONTROL_PRESCALER_MAX)
+		if (!FIELD_FIT(GT_CONTROL_PRESCALER_MASK, psv))
 			return NOTIFY_BAD;
 
 		/*
-- 
2.44.0



From martin.blumenstingl at googlemail.com  Sun Feb 25 07:13:35 2024
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 25 Feb 2024 16:13:35 +0100
Subject: [PATCH v3 2/3] clocksource/drivers/arm_global_timer: Guard against division by zero
In-Reply-To: <20240225151336.2728533-1-martin.blumenstingl@googlemail.com>
References: <20240225151336.2728533-1-martin.blumenstingl@googlemail.com>
Message-ID: <20240225151336.2728533-3-martin.blumenstingl@googlemail.com>

The result of the division of new_rate by gt_target_rate can be zero (if
new_rate is smaller than gt_target_rate). Using that result as divisor
without checking can result in a division by zero error. Guard against
this by checking for a zero value earlier.
While here, also change the psv variable to an unsigned long to make
sure we don't overflow the datatype as all other types involved are also
unsiged long.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
---
 drivers/clocksource/arm_global_timer.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index fb3ffd54c822..257599d682f0 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -291,18 +291,17 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,
 	switch (event) {
 	case PRE_RATE_CHANGE:
 	{
-		int psv;
+		unsigned long psv;
 
-		psv = DIV_ROUND_CLOSEST(ndata->new_rate,
-					gt_target_rate);
-
-		if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)
+		psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate);
+		if (!psv ||
+		    abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)
 			return NOTIFY_BAD;
 
 		psv--;
 
 		/* prescaler within legal range? */
-		if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
+		if (psv > GT_CONTROL_PRESCALER_MAX)
 			return NOTIFY_BAD;
 
 		/*
-- 
2.44.0



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:01:23 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:01:23 +0100
Subject: [PATCH v3 10/15] clk: samsung: Keep register offsets in chip
 specific structure
In-Reply-To: <20240224202053.25313-11-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-11-semen.protsenko@linaro.org>
Message-ID: <f6d99b65-7679-4a14-bb4c-ab62aa45dd6f@linaro.org>

On 24/02/2024 21:20, Sam Protsenko wrote:
> Abstract CPU clock registers by keeping their offsets in a dedicated
> chip specific structure to accommodate for oncoming Exynos850 support,
> which has different offsets for cluster 0 and cluster 1. This rework
> also makes it possible to use exynos_set_safe_div() for all chips, so
> exynos5433_set_safe_div() is removed here to reduce the code
> duplication. The ".regs" field has to be (void *) as different Exynos
> chips can have very different register layout, so this way it's possible
> for ".regs" to point to different structures, each representing its own
> chip's layout.
> 
> No functional change.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---

Missing checkpatch --strict:
ERROR: "foo * const	bar" should be "foo * const bar"

Corrected and applied.

Best regards,
Krzysztof



From andre.przywara at arm.com  Sun Feb 25 08:06:16 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun, 25 Feb 2024 16:06:16 +0000
Subject: [RFC PATCH 1/1] clk: sunxi-ng: h6-r: add GPU power domain
In-Reply-To: <20240225160616.15001-1-andre.przywara@arm.com>
References: <20240225160616.15001-1-andre.przywara@arm.com>
Message-ID: <20240225160616.15001-2-andre.przywara@arm.com>

The Allwinner H616 features register 0x7010254 in the PRCM MMIO frame,
where bit 0 needs to be cleared to enable operation of the Mali GPU.
With this bit set (the reset default), any access to the Mali registers
hangs the bus and thus the whole system. The BSP code clears this bit
in U-Boot and their kernel never touches it again.

Register a power-domain device to control this bit. Since we claim this
MMIO region in the H6 R-CCU driver, add the code here, so that we don't
need to artificially split the MMIO range in the DT.
Since there seems to be at least one other register with similar behaviour
nearby (0x7010260), make the power domain take one cell, even though we
only support domain #0 for now.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 84 ++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
index 02b28cfc5525e..363fb7a71e9f5 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
@@ -4,9 +4,11 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/pm_domain.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -217,6 +219,86 @@ static const struct sunxi_ccu_desc sun50i_h616_r_ccu_desc = {
 	.num_resets	= ARRAY_SIZE(sun50i_h616_r_ccu_resets),
 };
 
+#define	PD_H616_GPU_REG			0x254
+
+struct sun50i_h616_ppu_pd {
+	struct generic_pm_domain	genpd;
+	void __iomem			*base;
+};
+
+#define to_sun50i_h616_ppu_pd(_genpd) \
+	container_of(_genpd, struct sun50i_h616_ppu_pd, genpd)
+
+static bool sun50i_h616_ppu_power_status(const struct sun50i_h616_ppu_pd *pd)
+{
+	return !readl(pd->base + PD_H616_GPU_REG);
+}
+
+static int sun50i_h616_ppu_pd_set_power(const struct sun50i_h616_ppu_pd *pd,
+					bool power_on)
+{
+	if (power_on)
+		writel(0, pd->base + PD_H616_GPU_REG);
+	else
+		writel(1, pd->base + PD_H616_GPU_REG);
+
+	return 0;
+}
+
+static int sun50i_h616_ppu_pd_power_on(struct generic_pm_domain *genpd)
+{
+	const struct sun50i_h616_ppu_pd *pd = to_sun50i_h616_ppu_pd(genpd);
+
+	return sun50i_h616_ppu_pd_set_power(pd, true);
+}
+
+static int sun50i_h616_ppu_pd_power_off(struct generic_pm_domain *genpd)
+{
+	const struct sun50i_h616_ppu_pd *pd = to_sun50i_h616_ppu_pd(genpd);
+
+	return sun50i_h616_ppu_pd_set_power(pd, false);
+}
+
+static int sun50i_h616_register_ppu(struct platform_device *pdev,
+				    void __iomem *base)
+{
+	struct device *dev = &pdev->dev;
+	struct genpd_onecell_data *ppu;
+	struct sun50i_h616_ppu_pd *pd;
+	int ret;
+
+	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return -ENOMEM;
+
+	ppu = devm_kzalloc(dev, sizeof(*ppu), GFP_KERNEL);
+	if (!ppu)
+		return -ENOMEM;
+
+	ppu->domains = devm_kzalloc(dev, sizeof(*ppu->domains), GFP_KERNEL);
+	if (!ppu->domains)
+		return -ENOMEM;
+
+	ppu->num_domains = 1;
+	pd->genpd.name		= "GPU";
+	pd->genpd.power_off	= sun50i_h616_ppu_pd_power_off;
+	pd->genpd.power_on	= sun50i_h616_ppu_pd_power_on;
+	pd->base		= base;
+
+	ret = pm_genpd_init(&pd->genpd, NULL, !sun50i_h616_ppu_power_status(pd));
+	if (ret) {
+		dev_warn(dev, "Failed to add GPU power domain: %d\n", ret);
+		return ret;
+	}
+
+	ppu->domains[0] = &pd->genpd;
+	ret = of_genpd_add_provider_onecell(dev->of_node, ppu);
+	if (ret)
+		dev_warn(dev, "Failed to add provider: %d\n", ret);
+
+	return 0;
+}
+
 static int sun50i_h6_r_ccu_probe(struct platform_device *pdev)
 {
 	const struct sunxi_ccu_desc *desc;
@@ -230,6 +312,8 @@ static int sun50i_h6_r_ccu_probe(struct platform_device *pdev)
 	if (IS_ERR(reg))
 		return PTR_ERR(reg);
 
+	sun50i_h616_register_ppu(pdev, reg);
+
 	return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
 }
 
-- 
2.35.8



From andre.przywara at arm.com  Sun Feb 25 08:06:15 2024
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun, 25 Feb 2024 16:06:15 +0000
Subject: [RFC PATCH 0/1] sunxi: H616: add GPU power domain driver
Message-ID: <20240225160616.15001-1-andre.przywara@arm.com>

The Allwinner provided BSP code and experiments show that the Mali GPU
on the Allwinner H616 SoC needs to have a bit in one PRCM register
cleared to work. In the WIP graphics support patches, this was typically
covered by a U-Boot one-liner hack.

This patch here adds a proper power-domain driver for this one bit.
Since "power-domains" is a generic DT property, it already works on the
Panfrost driver side, without extra code. Said register is in the PRCM
MMIO range, which we already use in the R-CCU driver, so add the power
domain registration code there.
I mark this as RFC to get answers to some questions. Once people are
happy with the approach, I will send out a proper series with the
respective Kconfig and DT patches.

- Is modelling this as a power domain the right approach in the first
  place? Is that maybe just another reset bit? The logic seems backwards
  for that (bit set = disabled), but who knows?
- Is embedding this in the R-CCU driver the right way? I also have a
  version for a standalone driver in a separate file, but we have to
  artificially split the MMIO region to not conflict with the R-CCU
  driver, which looks arbitrary. If anyone has any information about
  the PRCM (register map), it would help to make an informed decision.
- Experiments in U-Boot identify bit 0 in 0x7010260 as behaving similar
  as our bit 0 in 0x7010254 here, so chances are there is another power
  domain for some other peripheral nearby. Also bits 0x7010250[9:0] are
  writable and stick, with setting bit 2 hanging the chip. So to allow
  further extensions without breaking compatibility, I made this a
  one-cell power domain ("power-domains = <&r_ccu 0>;"). Please let me
  know if this sounds overkill and a simple ("no cell") approach would be
  better.
- This patch makes the R-CCU driver dependent on CONFIG_PM. Shall we model
  this is a simple "select" or "depends on" in Kconfig, or shall the code
  be made conditional in the R-CCU driver, to allow compilation without
  PM support enabled?
- Shall any failure in registering the PPU driver also abort the R-CCU
  probe? Or do we treat this as optional?

I'd be grateful for any feedback.

Cheers,
Andre

Andre Przywara (1):
  clk: sunxi-ng: h6-r: add GPU power domain

 drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 84 ++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

-- 
2.35.8



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:09:43 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:09:43 +0100
Subject: [PATCH v3 13/15] clk: samsung: Implement manual PLL control for
 ARM64 SoCs
In-Reply-To: <20240224202053.25313-14-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-14-semen.protsenko@linaro.org>
Message-ID: <eb968e2b-495b-44dd-aad9-3cd5eac72bdf@linaro.org>

On 24/02/2024 21:20, Sam Protsenko wrote:
> Some ARM64 Exynos chips are capable to control PLL clocks automatically.
> For those chips, whether the PLL is controlled automatically or manually
> is chosen in PLL_CON1 register with next bits:
> 
>     [28]  ENABLE_AUTOMATIC_CLKGATING
>     [1]   MANUAL_PLL_CTRL
>     [0]   AUTO_PLL_CTRL
> 
> The bl2 bootloader sets 0x10000001 value for some PLL_CON1 registers,
> which means any attempt to control those PLLs manually (e.g.
> disabling/enabling those PLLs or changing MUX parent clocks) would lead
> to PLL lock timeout with error message like this:
> 
>     Could not lock PLL ...
> 
> At the moment, all Samsung clock drivers implement manual clock control.
> So in order to make it possible to control PLLs, corresponding PLL_CON1
> registers should be set to 0x2 first.
> 
> Some older ARM64 chips don't implement the automatic clock control
> though. It also might be desirable to configure some PLLs for manual
> control, while keeping the default configuration for the rest. So it'd
> convenient to choose this PLL mode for each CMU separately. Introduce
> .manual_plls field to CMU structure to choose the PLL control mode.
> Because it'll be initialized with "false" in all existing CMU
> structures by default, it won't affect any existing clock drivers,
> allowing for this feature to be enabled gradually when it's needed with
> no change for the rest of users. In case .manual_plls is set, set
> PLL_CON1 registers to manual control, akin to what's already done for
> gate clocks in exynos_arm64_init_clocks(). Of course, PLL_CON1 registers
> should be added to corresponding struct samsung_cmu_info::clk_regs array
> to make sure they get initialized.
> 
> No functional change. This patch adds a feature, but doesn't enable it
> for any users.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> Changes in v3:
>   - none
> 
> Changes in v2:
>   - none
> 
>  drivers/clk/samsung/clk-exynos-arm64.c | 44 +++++++++++++++++---------
>  drivers/clk/samsung/clk.h              |  4 +++
>  2 files changed, 33 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos-arm64.c b/drivers/clk/samsung/clk-exynos-arm64.c
> index 6fb7194df7ab..55490209b9a9 100644
> --- a/drivers/clk/samsung/clk-exynos-arm64.c
> +++ b/drivers/clk/samsung/clk-exynos-arm64.c
> @@ -25,6 +25,19 @@
>  #define GATE_OFF_START		0x2000
>  #define GATE_OFF_END		0x2fff
>  
> +/* PLL CON register offsets range */
> +#define PLL_CON_START		0x100
> +#define PLL_CON_END		0x600
> +
> +/* PLL register bits */
> +#define PLL_CON1_MANUAL		BIT(1)
> +
> +/* Helper macros to check for particular clock regiter by its offset */
> +#define IS_GATE_REG(o)		((o) >= GATE_OFF_START && (o) <= GATE_OFF_END)
> +#define IS_PLL_CONx_REG(o)	((o) >= PLL_CON_START && (o) <= PLL_CON_END)
> +#define IS_PLL_CON1_REG(o)	\
> +	(IS_PLL_CONx_REG(o) && ((o) & 0xf) == 0x4 && !((o) & 0x10))

These should be static functions, because it leads to trickier code. See
also checkpatch warning.

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:10:48 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:10:48 +0100
Subject: (subset) [PATCH v3 01/15] dt-bindings: clock: exynos850: Add
 CMU_CPUCLK0 and CMU_CPUCL1
In-Reply-To: <20240224202053.25313-2-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-2-semen.protsenko@linaro.org>
Message-ID: <170887744864.215710.16887740186318953401.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:39 -0600, Sam Protsenko wrote:
> Document CPU clock management unit compatibles and add corresponding
> clock indices. Exynos850 has two CPU clusters (CL0 and CL1), each
> containing 4 Cortex-A55 cores. CPU PLLs are generating main CPU clocks
> for each cluster, and there are alternate ("switch") clocks that can be
> used temporarily while re-configuring the PLL for the new rate. ACLK,
> ATCLK, PCLKDBG and PERIPHCLK clocks are driving corresponding buses.
> CLK_CLUSTERx_SCLK are actual leaf CPU clocks and should be used to
> change CPU rates. Also some CoreSight clocks can be derived from
> DBG_USER (debug clock).
> 
> [...]

Applied, thanks!

[01/15] dt-bindings: clock: exynos850: Add CMU_CPUCLK0 and CMU_CPUCL1
        https://git.kernel.org/krzk/linux/c/76dedb9c0bb3cf3c6d639d043d7ecc98816053cc

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:10:50 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:10:50 +0100
Subject: (subset) [PATCH v3 02/15] clk: samsung: Improve clk-cpu.c
 style
In-Reply-To: <20240224202053.25313-3-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-3-semen.protsenko@linaro.org>
Message-ID: <170887745089.215710.13953112422812922615.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:40 -0600, Sam Protsenko wrote:
> clk-cpu.c has numerous style issues reported by checkpatch and easily
> identified otherwise. Give it some love and fix those warnings where it
> makes sense. Also make stabilization time a named constant to get rid of
> the magic number in clk-cpu.c.
> 
> No functional change.
> 
> [...]

Applied, thanks!

[02/15] clk: samsung: Improve clk-cpu.c style
        https://git.kernel.org/krzk/linux/c/f707e891eb8b655aec1b74c2171e8d529ed9c455

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:10:52 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:10:52 +0100
Subject: (subset) [PATCH v3 03/15] clk: samsung: Pull struct
 exynos_cpuclk into clk-cpu.c
In-Reply-To: <20240224202053.25313-4-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-4-semen.protsenko@linaro.org>
Message-ID: <170887745282.215710.3873782882089335493.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:41 -0600, Sam Protsenko wrote:
> Reduce the scope of struct exynos_cpuclk, as it's only used in clk-cpu.c
> internally. All drivers using clk-pll.h already include clk.h as well,
> so this change doesn't break anything.
> 
> No functional change.
> 
> 
> [...]

Applied, thanks!

[03/15] clk: samsung: Pull struct exynos_cpuclk into clk-cpu.c
        https://git.kernel.org/krzk/linux/c/a36bda74ede4c33dfa95482b56058f13fb64a426

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:10:55 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:10:55 +0100
Subject: (subset) [PATCH v3 04/15] clk: samsung: Reduce params count in
 exynos_register_cpu_clock()
In-Reply-To: <20240224202053.25313-5-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-5-semen.protsenko@linaro.org>
Message-ID: <170887745504.215710.7797838794747602399.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:42 -0600, Sam Protsenko wrote:
> Pass CPU clock data structure to exynos_register_cpu_clock() instead of
> passing its fields separately there. That simplifies the signature of
> exynos_register_cpu_clock() and makes it easier to add more fields to
> struct samsung_cpu_clock later. This style follows the example of
> samsung_clk_register_pll().
> 
> No functional change.
> 
> [...]

Applied, thanks!

[04/15] clk: samsung: Reduce params count in exynos_register_cpu_clock()
        https://git.kernel.org/krzk/linux/c/84d42803e4f163b1b6cb4ae05d91af693a1985c2

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:10:57 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:10:57 +0100
Subject: (subset) [PATCH v3 05/15] clk: samsung: Use single CPU clock
 notifier callback for all chips
In-Reply-To: <20240224202053.25313-6-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-6-semen.protsenko@linaro.org>
Message-ID: <170887745713.215710.13782897214681477333.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:43 -0600, Sam Protsenko wrote:
> Reduce the code duplication by making all chips use a single version of
> exynos_cpuclk_notifier_cb() function. That will prevent the code bloat
> when adding new chips support too.
> 
> Also don't pass base address to pre/post rate change functions, as it
> can be easily derived from already passed cpuclk param.
> 
> [...]

Applied, thanks!

[05/15] clk: samsung: Use single CPU clock notifier callback for all chips
        https://git.kernel.org/krzk/linux/c/c9bc1f778625b0ae93641e6d14d83b62d16e549d

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:10:59 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:10:59 +0100
Subject: (subset) [PATCH v3 06/15] clk: samsung: Group CPU clock
 functions by chip
In-Reply-To: <20240224202053.25313-7-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-7-semen.protsenko@linaro.org>
Message-ID: <170887745923.215710.8750487017286129944.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:44 -0600, Sam Protsenko wrote:
> clk-cpu.c is going to get messy as new chips support is added.
> Restructure the code by pulling related functions and definitions
> together, grouping those by their relation to a particular chip or other
> categories, to simplify the code navigation.
> 
> No functional change.
> 
> [...]

Applied, thanks!

[06/15] clk: samsung: Group CPU clock functions by chip
        https://git.kernel.org/krzk/linux/c/be20ccc17f41240b52106bf3dad01734a7f11080

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:11:01 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:11:01 +0100
Subject: (subset) [PATCH v3 07/15] clk: samsung: Pass actual CPU clock
 registers base to CPU_CLK()
In-Reply-To: <20240224202053.25313-8-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-8-semen.protsenko@linaro.org>
Message-ID: <170887746147.215710.9044270450868459212.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:45 -0600, Sam Protsenko wrote:
> The documentation for struct exynos_cpuclk says .ctrl_base field should
> contain the controller base address. There are two different problems
> with that:
> 
> 1. All Exynos clock drivers are actually passing CPU_SRC register offset
>    via CPU_CLK() macro, which in turn gets assigned to mentioned
>    .ctrl_base field. Because CPU_SRC register usually already has 0x200
>    offset from controller's base, all other register offsets in
>    clk-cpu.c (like DIVs and MUXes) are specified as offsets from CPU_SRC
>    offset, and not from controller's base. That makes things confusing
>    and inconsistent with register offsets provided in Exynos clock
>    drivers, also breaking the contract for .ctrl_base field as described
>    in struct exynos_cpuclk doc.
> 
> [...]

Applied, thanks!

[07/15] clk: samsung: Pass actual CPU clock registers base to CPU_CLK()
        https://git.kernel.org/krzk/linux/c/338f1c25269185cbea6e3dd966e5c859af2323f7

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:11:03 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:11:03 +0100
Subject: (subset) [PATCH v3 08/15] clk: samsung: Pass register layout
 type explicitly to CLK_CPU()
In-Reply-To: <20240224202053.25313-9-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-9-semen.protsenko@linaro.org>
Message-ID: <170887746389.215710.4982831598538068214.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:46 -0600, Sam Protsenko wrote:
> Use a dedicated enum field to explicitly specify which register layout
> should be used for the CPU clock, instead of passing it as a bit flag.
> This way it would be possible to keep the chip-specific data in some
> array, where each chip structure could be accessed by its corresponding
> layout index. It prepares clk-cpu.c for adding new chips support, which
> might have different data for different CPU clusters.
> 
> [...]

Applied, thanks!

[08/15] clk: samsung: Pass register layout type explicitly to CLK_CPU()
        https://git.kernel.org/krzk/linux/c/6d7d203ca6914e84166a00d0f0bdfda6cbce76a7

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:11:06 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:11:06 +0100
Subject: (subset) [PATCH v3 09/15] clk: samsung: Keep CPU clock chip
 specific data in a dedicated struct
In-Reply-To: <20240224202053.25313-10-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-10-semen.protsenko@linaro.org>
Message-ID: <170887746655.215710.9580664950836563273.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:47 -0600, Sam Protsenko wrote:
> Keep chip specific data in the data structure, don't mix it with code.
> It makes it easier to add more chip specific data further. Having all
> chip specific data in the table eliminates possible code bloat when
> adding more rate handlers for new chips, and also makes it possible to
> keep some other chip related data in that array.
> 
> No functional change.
> 
> [...]

Applied, thanks!

[09/15] clk: samsung: Keep CPU clock chip specific data in a dedicated struct
        https://git.kernel.org/krzk/linux/c/9c746e5afdc3f784593c903d4be3d418f75d7787

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:11:08 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:11:08 +0100
Subject: (subset) [PATCH v3 10/15] clk: samsung: Keep register offsets
 in chip specific structure
In-Reply-To: <20240224202053.25313-11-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-11-semen.protsenko@linaro.org>
Message-ID: <170887746854.215710.5270227845876951742.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:48 -0600, Sam Protsenko wrote:
> Abstract CPU clock registers by keeping their offsets in a dedicated
> chip specific structure to accommodate for oncoming Exynos850 support,
> which has different offsets for cluster 0 and cluster 1. This rework
> also makes it possible to use exynos_set_safe_div() for all chips, so
> exynos5433_set_safe_div() is removed here to reduce the code
> duplication. The ".regs" field has to be (void *) as different Exynos
> chips can have very different register layout, so this way it's possible
> for ".regs" to point to different structures, each representing its own
> chip's layout.
> 
> [...]

Applied, thanks!

[10/15] clk: samsung: Keep register offsets in chip specific structure
        https://git.kernel.org/krzk/linux/c/78bc2312ef9cea4af1073dfab4c71d91b2015b5d

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:11:10 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:11:10 +0100
Subject: (subset) [PATCH v3 11/15] clk: samsung: Pass mask to
 wait_until_mux_stable()
In-Reply-To: <20240224202053.25313-12-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-12-semen.protsenko@linaro.org>
Message-ID: <170887747056.215710.9176001640764201554.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:49 -0600, Sam Protsenko wrote:
> Make it possible to use wait_until_mux_stable() for MUX registers where
> the mask is different from MUX_MASK (e.g. in upcoming CPU clock
> implementation for Exynos850).
> 
> No functional change.
> 
> 
> [...]

Applied, thanks!

[11/15] clk: samsung: Pass mask to wait_until_mux_stable()
        https://git.kernel.org/krzk/linux/c/152cc7478677dee6a11685585fd17efbce6e9db5

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From krzysztof.kozlowski at linaro.org  Sun Feb 25 08:11:12 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Sun, 25 Feb 2024 17:11:12 +0100
Subject: (subset) [PATCH v3 12/15] clk: samsung: Add CPU clock support
 for Exynos850
In-Reply-To: <20240224202053.25313-13-semen.protsenko@linaro.org>
References: <20240224202053.25313-1-semen.protsenko@linaro.org>
 <20240224202053.25313-13-semen.protsenko@linaro.org>
Message-ID: <170887747270.215710.14391018888369319254.b4-ty@linaro.org>


On Sat, 24 Feb 2024 14:20:50 -0600, Sam Protsenko wrote:
> Implement CPU clock control for Exynos850 SoC. It follows the same
> procedure which is already implemented for other SoCs in clk-cpu.c:
> 
> 1. Set the correct rate for the alternate parent (if needed) before
>    switching to use it as the CPU clock
> 2. Switch to the alternate parent, so the CPU continues to get clocked
>    while the PLL is being re-configured
> 3. Adjust the dividers for the CPU related buses (ACLK, ATCLK, etc)
> 4. Re-configure the PLL for the new CPU clock rate. It's done
>    automatically, as the CPU clock rate change propagates to the PLL
>    clock, because the CPU clock has CLK_SET_RATE_PARENT flag set in
>    exynos_register_cpu_clock()
> 5. Once the PLL is locked, set it back as the CPU clock source
> 6. Set alternate parent clock rate back to max speed
> 
> [...]

Applied, thanks!

[12/15] clk: samsung: Add CPU clock support for Exynos850
        https://git.kernel.org/krzk/linux/c/61f4399c74d0677ee64e42f7b8d4ab01ee39de45

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From tglx at linutronix.de  Sun Feb 25 08:19:52 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Sun, 25 Feb 2024 17:19:52 +0100
Subject: [PATCH] genirq/irqdomain: Don't call ops->select for
 DOMAIN_BUS_ANY tokens
In-Reply-To: <20240220114731.1898534-1-maz@kernel.org>
References: <20240220114731.1898534-1-maz@kernel.org>
Message-ID: <878r38cy8n.ffs@tglx>

On Tue, Feb 20 2024 at 11:47, Marc Zyngier wrote:
> Users of the IRQCHIP_PLATFORM_DRIVER_{BEGIN,END} helpers rely
> on a fwspec containing only the fwnode (and crucially a number
> of parameters set to 0) together with a DOMAIN_BUS_ANY token
> to check whether a parent irqchip has probed and registered
> a domain.
>
> Since de1ff306dcf4 ("genirq/irqdomain: Remove the param count
> restriction from select()"), we call ops->select unconditionally,
> meaning that irqchips implementing select now need to handle
> ANY as a match.
>
> Instead of adding more esoteric checks to the individual drivers,
> add that condition to irq_find_matching_fwspec(), and let it
> handle the corner case, as per the comment in the function.
>
> This restores the functionnality of the above helpers.
>
> Reported-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Tested-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Reported-by: Biju Das <biju.das.jz at bp.renesas.com>
> Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count restriction from select()")
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Link: https://lore.kernel.org/r/20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f at linaro.org

Bah. That breaks x86 because it uses DOMAIN_BUS_ANY to find the MSI
parent for a fwspec (IOAPIC and HPET) which gets either picked up by the
interrupt remapping or by the root vector domain.

Fix below.

Thanks,

        tglx
---
Subject: x86/apic/msi: Use DOMAIN_BUS_GENERIC_MSI for HPET/IO-APIC domain search
From: Thomas Gleixner <tglx at linutronix.de>
Date: Sun, 25 Feb 2024 16:56:12 +0100

The recent restriction to invoke irqdomain_ops::select() only when the
domain bus toke is DOMAIN_BUS_ANY breaks the search for the parent MSI
domain of HPET and IO-APIC. The latter causes a full boot fail.

The restriction itself makes sense to avoid adding DOMAIN_BUS_ANY matches
into the various ARM specific select() callbacks. Reverting this change
would obviously break ARM platforms again and require DOMAIN_BUS_ANY
matches added to various places.

A simpler solution is to use the DOMAIN_BUS_GENERIC_MSI token for the HPET
and IO-APIC parent domain search. This works out of the box because the
affected parent domains check only for the firmware specification content
and not for the bus token.

Fixes: 5aa3c0cf5bba ("genirq/irqdomain: Don't call ops->select for DOMAIN_BUS_ANY tokens")
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
---
 arch/x86/kernel/apic/io_apic.c |    2 +-
 arch/x86/kernel/hpet.c         |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2354,7 +2354,7 @@ static int mp_irqdomain_create(int ioapi
 	fwspec.param_count = 1;
 	fwspec.param[0] = mpc_ioapic_id(ioapic);
 
-	parent = irq_find_matching_fwspec(&fwspec, DOMAIN_BUS_ANY);
+	parent = irq_find_matching_fwspec(&fwspec, DOMAIN_BUS_GENERIC_MSI);
 	if (!parent) {
 		if (!cfg->dev)
 			irq_domain_free_fwnode(fn);
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -568,7 +568,7 @@ static struct irq_domain *hpet_create_ir
 	fwspec.param_count = 1;
 	fwspec.param[0] = hpet_id;
 
-	parent = irq_find_matching_fwspec(&fwspec, DOMAIN_BUS_ANY);
+	parent = irq_find_matching_fwspec(&fwspec, DOMAIN_BUS_GENERIC_MSI);
 	if (!parent) {
 		irq_domain_free_fwnode(fn);
 		kfree(domain_info);




From frank at oltmanns.dev  Sun Feb 25 08:46:16 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Sun, 25 Feb 2024 17:46:16 +0100
Subject: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher
 clock rate
In-Reply-To: <ia7e7gqozltl5wkfdvwtf2rw2ko2dt67qxtuqbavsroyv4ifys@x4mbulqhhri5>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
 <20240205-pinephone-pll-fixes-v2-5-96a46a2d8c9b@oltmanns.dev>
 <poua4bzyciiwt65sqjf2whqfdumvoe4h3bkjpf64px2vwgumrf@sai73byg2iju>
 <87sf1zxb0s.fsf@oltmanns.dev>
 <ia7e7gqozltl5wkfdvwtf2rw2ko2dt67qxtuqbavsroyv4ifys@x4mbulqhhri5>
Message-ID: <87o7c4mqzr.fsf@oltmanns.dev>

Hi Maxime,

On 2024-02-22 at 11:29:51 +0100, Maxime Ripard <mripard at kernel.org> wrote:
> [[PGP Signed Part:Undecided]]
> On Sun, Feb 11, 2024 at 04:42:43PM +0100, Frank Oltmanns wrote:
>>
>> On 2024-02-08 at 20:05:08 +0100, Maxime Ripard <mripard at kernel.org> wrote:
>> > [[PGP Signed Part:Undecided]]
>> > Hi Frank,
>> >
>> > On Mon, Feb 05, 2024 at 04:22:28PM +0100, Frank Oltmanns wrote:
>> >> This panel is used in the pinephone that runs on a Allwinner A64 SOC.
>> >> The SOC requires pll-mipi to run at more than 500 MHz.
>> >>
>> >> This is the relevant clock tree:
>> >>  pll-mipi
>> >>     tcon0
>> >>        tcon-data-clock
>> >>
>> >> tcon-data-clock has to run at 1/4 the DSI per-lane bit rate. The XBD599
>> >> has 24 bpp and 4 lanes. Therefore, the resulting requested
>> >> tcon-data-clock rate is:
>> >>     crtc_clock * 1000 * (24 / 4) / 4
>> >>
>> >> tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it requests a
>> >> parent rate of
>> >>     4 * (crtc_clock * 1000 * (24 / 4) / 4)
>> >>
>> >> Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate of pll-mipi.
>> >>
>> >> pll-mipi's constraint to run at 500MHz or higher forces us to have a
>> >> crtc_clock >= 83333 kHz if we want a 60 Hz vertical refresh rate.
>> >>
>> >> Change [hv]sync_(start|end) so that we reach a clock rate of 83502 kHz
>> >> so that it is high enough to align with pll-pipi limits.
>> >>
>> >> Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
>> >
>> > That commit log is great, but it's kind of off-topic. It's a panel
>> > driver, it can be used on any MIPI-DSI controller, the only relevant
>> > information there should be the panel timings required in the datasheet.
>> >
>> > The PLL setup is something for the MIPI-DSI driver to adjust, not for
>> > the panel to care for.
>> >
>>
>> I absolutely agree. It even was the reason for my submission of a
>> sunxi-ng patch series last year that was accepted, to make pll-mipi more
>> flexible. :)
>>
>> The only remaining option I currently see for adjusting the sunxi-ng
>> driver to further accomodate the panel, is trying to use a higher
>> divisor than 4 for calculating tcon-data-clock from tcon0. I remember
>> reading a discussion about this, but as far as I remember that proposal
>> was rejected (by you, IIRC).
>>
>> While I appreciate other suggestion as well, I'll look into options for
>> using a different divisor than 4.
>
> Like I said, I'm not against the patch at all, it looks great to me on
> principle. I just think you should completely rephrase the commit log
> using the datasheet as the only reliable source of the display timings.
> Whether sun4i can work around the panel requirements is something
> completely orthogonal to the discussion, and thus the commit log.
>

I was trying to follow the guidelines [1] for describing the reason
behind my changes to the panel. My original commit message was a lot
shorter, which, understandably, resulted in follow up questions [2].
With the current commit log, I'm trying to address those questions.
According to the device tree, the panel is only used in the pinephone.
The only reason for the change is that the SoC used by the only user of
this panel can not provide the rate the panel requests with the current
values. I think this information is relevant.

Unfortunately, as described in [2], I cannot back these values with any
datasheets because I couldn't find any. I could only find hints that
they are not publicly available. Icenowy (added to CC) submitted the
original values.

Best regards,
  Frank

[1]: https://www.kernel.org/doc/html/v6.7/process/submitting-patches.html#describe-your-changes
[2]: https://lore.kernel.org/lkml/87wmsvo0fh.fsf at oltmanns.dev/

>
> Maxime
>
> [[End of PGP Signed Part]]


From bp at alien8.de  Sun Feb 25 09:10:20 2024
From: bp at alien8.de (Borislav Petkov)
Date: Sun, 25 Feb 2024 18:10:20 +0100
Subject: [PATCH] genirq/irqdomain: Don't call ops->select for
 DOMAIN_BUS_ANY tokens
In-Reply-To: <878r38cy8n.ffs@tglx>
References: <20240220114731.1898534-1-maz@kernel.org>
 <878r38cy8n.ffs@tglx>
Message-ID: <20240225171020.GAZdt0fAu29EuoLgJh@fat_crate.local>

On Sun, Feb 25, 2024 at 05:19:52PM +0100, Thomas Gleixner wrote:
> Bah. That breaks x86 because it uses DOMAIN_BUS_ANY to find the MSI
> parent for a fwspec (IOAPIC and HPET) which gets either picked up by the
> interrupt remapping or by the root vector domain.
> 
> Fix below.

The guest boots fine now, thx.

Tested-by: Borislav Petkov (AMD) <bp at alien8.de>

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette


From maz at kernel.org  Sun Feb 25 09:23:22 2024
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 25 Feb 2024 17:23:22 +0000
Subject: [PATCH] genirq/irqdomain: Don't call ops->select for
 DOMAIN_BUS_ANY tokens
In-Reply-To: <878r38cy8n.ffs@tglx>
References: <20240220114731.1898534-1-maz@kernel.org> <878r38cy8n.ffs@tglx>
Message-ID: <6792b2913a47b6ceb5650cdde3deecf2@kernel.org>

On 2024-02-25 16:19, Thomas Gleixner wrote:
> On Tue, Feb 20 2024 at 11:47, Marc Zyngier wrote:
>> Users of the IRQCHIP_PLATFORM_DRIVER_{BEGIN,END} helpers rely
>> on a fwspec containing only the fwnode (and crucially a number
>> of parameters set to 0) together with a DOMAIN_BUS_ANY token
>> to check whether a parent irqchip has probed and registered
>> a domain.
>> 
>> Since de1ff306dcf4 ("genirq/irqdomain: Remove the param count
>> restriction from select()"), we call ops->select unconditionally,
>> meaning that irqchips implementing select now need to handle
>> ANY as a match.
>> 
>> Instead of adding more esoteric checks to the individual drivers,
>> add that condition to irq_find_matching_fwspec(), and let it
>> handle the corner case, as per the comment in the function.
>> 
>> This restores the functionnality of the above helpers.
>> 
>> Reported-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>> Tested-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>> Reported-by: Biju Das <biju.das.jz at bp.renesas.com>
>> Fixes: de1ff306dcf4 ("genirq/irqdomain: Remove the param count 
>> restriction from select()")
>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>> Link: 
>> https://lore.kernel.org/r/20240219-gic-fix-child-domain-v1-1-09f8fd2d9a8f at linaro.org
> 
> Bah. That breaks x86 because it uses DOMAIN_BUS_ANY to find the MSI
> parent for a fwspec (IOAPIC and HPET) which gets either picked up by 
> the
> interrupt remapping or by the root vector domain.
> 
> Fix below.
> 
> Thanks,
> 
>         tglx
> ---
> Subject: x86/apic/msi: Use DOMAIN_BUS_GENERIC_MSI for HPET/IO-APIC 
> domain search
> From: Thomas Gleixner <tglx at linutronix.de>
> Date: Sun, 25 Feb 2024 16:56:12 +0100
> 
> The recent restriction to invoke irqdomain_ops::select() only when the
> domain bus toke is DOMAIN_BUS_ANY breaks the search for the parent MSI
> domain of HPET and IO-APIC. The latter causes a full boot fail.
> 
> The restriction itself makes sense to avoid adding DOMAIN_BUS_ANY 
> matches
> into the various ARM specific select() callbacks. Reverting this change
> would obviously break ARM platforms again and require DOMAIN_BUS_ANY
> matches added to various places.
> 
> A simpler solution is to use the DOMAIN_BUS_GENERIC_MSI token for the 
> HPET
> and IO-APIC parent domain search. This works out of the box because the
> affected parent domains check only for the firmware specification 
> content
> and not for the bus token.
> 
> Fixes: 5aa3c0cf5bba ("genirq/irqdomain: Don't call ops->select for
> DOMAIN_BUS_ANY tokens")
> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>

Looks good to me.

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

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


From nathan at kernel.org  Sun Feb 25 11:54:39 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Sun, 25 Feb 2024 12:54:39 -0700
Subject: [PATCH] arm64: ftrace: Don't forbid
 CALL_OPS+CC_OPTIMIZE_FOR_SIZE with Clang
In-Reply-To: <20240223064032.3463229-1-swboyd@chromium.org>
References: <20240223064032.3463229-1-swboyd@chromium.org>
Message-ID: <20240225195439.GA2972471@dev-arch.thelio-3990X>

On Thu, Feb 22, 2024 at 10:40:29PM -0800, Stephen Boyd wrote:
> Per commit b3f11af9b2ce ("arm64: ftrace: forbid CALL_OPS with
> CC_OPTIMIZE_FOR_SIZE"), GCC is silently ignoring `-falign-functions=N`
> when passed `-Os`, causing functions to be improperly aligned. This
> doesn't seem to be a problem with Clang though, where enabling CALL_OPS
> with CC_OPTIMIZE_FOR_SIZE doesn't spit out any warnings at boot about
> misaligned patch-sites. Only forbid CALL_OPS if GCC is used and we're
> optimizing for size so that CALL_OPS can be used with clang optimizing
> for size.
> 
> Cc: Jason Ling <jasonling at chromium.org>
> Cc: Florian Fainelli <f.fainelli at gmail.com>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Nathan Chancellor <nathan at kernel.org>
> Cc: Nick Desaulniers <ndesaulniers at google.com>
> Cc: Bill Wendling <morbo at google.com>
> Cc: Justin Stitt <justinstitt at google.com>
> Cc: <llvm at lists.linux.dev>
> Fixes: b3f11af9b2ce ("arm64: ftrace: forbid CALL_OPS with CC_OPTIMIZE_FOR_SIZE")
> Signed-off-by: Stephen Boyd <swboyd at chromium.org>

Seems reasonable to me.

Reviewed-by: Nathan Chancellor <nathan at kernel.org>

I wonder if that GCC issue is resolved with '-fmin-function-alignment'
that is being introduced in GCC 14 [1]. If it is, I suspect this
conditional could actually be CONFIG_CC_HAS_SANE_FUNCTION_ALIGNMENT
instead of CONFIG_CC_IS_CLANG, but that can obviously happen as a clean
up later down the road (more just food for thought for the arm64 folks,
not sure how much '-Os' is used in general)

[1]: https://git.kernel.org/masahiroy/linux-kbuild/c/5270316c9fec8cc99aa0e0a258509c5c7f789d12


> ---
>  arch/arm64/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index aa7c1d435139..6b96d75a3a3d 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -198,7 +198,7 @@ config ARM64
>  		if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS
>  	select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \
>  		if (DYNAMIC_FTRACE_WITH_ARGS && !CFI_CLANG && \
> -		    !CC_OPTIMIZE_FOR_SIZE)
> +		    (CC_IS_CLANG || !CC_OPTIMIZE_FOR_SIZE))
>  	select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \
>  		if DYNAMIC_FTRACE_WITH_ARGS
>  	select HAVE_SAMPLE_FTRACE_DIRECT
> 
> base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
> -- 
> https://chromeos.dev
> 


From linus.walleij at linaro.org  Sun Feb 25 12:08:10 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 25 Feb 2024 21:08:10 +0100
Subject: [PATCH 1/7] ARM: Support CLANG CFI
In-Reply-To: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
References: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
Message-ID: <20240225-arm32-cfi-v1-1-6943306f065b@linaro.org>

Support Control Flow Integrity (CFI) when compiling with
CLANG.

In the as-of-writing LLVM CLANG implementation (v17)
the 32-bit ARM platform is supported by the generic CFI
implementation, which isn't tailored specifically for ARM32
but works well enough to enable the feature.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0af6709570d1..1216656a40bc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -34,6 +34,7 @@ config ARM
 	select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
 	select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT if CPU_V7
 	select ARCH_SUPPORTS_ATOMIC_RMW
+	select ARCH_SUPPORTS_CFI_CLANG
 	select ARCH_SUPPORTS_HUGETLBFS if ARM_LPAE
 	select ARCH_SUPPORTS_PER_VMA_LOCK
 	select ARCH_USE_BUILTIN_BSWAP

-- 
2.34.1



From linus.walleij at linaro.org  Sun Feb 25 12:08:09 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 25 Feb 2024 21:08:09 +0100
Subject: [PATCH 0/7] CFI for ARM32 using LLVM
Message-ID: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>

This is a first patch set to support CLANG CFI (Control Flow
Integrity) on ARM32.

For information about what CFI is, see:
https://clang.llvm.org/docs/ControlFlowIntegrity.html

For the kernel KCFI flavor, see:
https://lwn.net/Articles/898040/

The base changes required to bring up KCFI on ARM32 was mostly
related to the use of custom vtables in the kernel, combined
with defines to call into these vtable members directly from
sites where they are used.

The approach to all of these vtable+define issues has been
the same: instead of a define, wrap the call in a static inline
function that explicitly calls the vtable member.

To runtime-test the patches:
- Enable CONFIG_LKDTM
- echo CFI_FORWARD_PROTO > /sys/kernel/debug/provoke-crash/DIRECT

The patch set has been booted to userspace on the following
test platforms:

- Arm Versatile (QEMU)
- Arm Versatile Express (QEMU)
- multi_v7 booted on Versatile Express (QEMU)
- Footbridge Netwinder (SA110 ARMv4)
- Ux500 (ARMv7 SMP)

I am not saying there will not be corner cases that we need
to fix in addition to this, but it is enough to get started.
Looking at what was fixed for arm64 I am a bit weary that
e.g. BPF might need something to trampoline properly.

But hopefullt people can get to testing it and help me fix
remaining issues before the final version, or we can fix it
in-tree.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Linus Walleij (7):
      ARM: Support CLANG CFI
      ARM: tlbflush: Make TLB flushes into static inlines
      ARM: bugs: Check in the vtable instead of defined aliases
      ARM: proc: Use inlines instead of defines
      ARM: delay: Turn delay functions into static inlines
      ARM: turn CPU cache flush functions into static inlines
      ARM: page: Turn highpage accesses into static inlines

 arch/arm/Kconfig                  |  1 +
 arch/arm/common/mcpm_entry.c      | 10 ++-----
 arch/arm/include/asm/cacheflush.h | 45 ++++++++++++++++++++++++-------
 arch/arm/include/asm/delay.h      | 16 ++++++++---
 arch/arm/include/asm/page.h       | 36 ++++++++++++++++++++-----
 arch/arm/include/asm/proc-fns.h   | 57 ++++++++++++++++++++++++++++++++-------
 arch/arm/include/asm/tlbflush.h   | 18 ++++++++-----
 arch/arm/kernel/bugs.c            |  2 +-
 arch/arm/mach-sunxi/mc_smp.c      |  7 +----
 arch/arm/mm/dma.h                 | 28 ++++++++++++++-----
 arch/arm/mm/proc-syms.c           |  7 +----
 arch/arm/mm/proc-v7-bugs.c        |  4 +--
 12 files changed, 167 insertions(+), 64 deletions(-)
---
base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d
change-id: 20240115-arm32-cfi-65d60f201108

Best regards,
-- 
Linus Walleij <linus.walleij at linaro.org>



From linus.walleij at linaro.org  Sun Feb 25 12:08:11 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 25 Feb 2024 21:08:11 +0100
Subject: [PATCH 2/7] ARM: tlbflush: Make TLB flushes into static inlines
In-Reply-To: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
References: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
Message-ID: <20240225-arm32-cfi-v1-2-6943306f065b@linaro.org>

Instead of just using defines to define the TLB flush functions,
use static inlines.

This has the upside that we can tag those as __nocfi so we can
execute a CFI-enabled kernel.

Move the variables around a bit so the functions can find their
global variable cpu_tlb.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/include/asm/tlbflush.h | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index 38c6e4a2a0b6..7340518ee0e9 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -210,13 +210,23 @@ struct cpu_tlb_fns {
 	unsigned long tlb_flags;
 };
 
+extern struct cpu_tlb_fns cpu_tlb;
+
+#define __cpu_tlb_flags			cpu_tlb.tlb_flags
+
 /*
  * Select the calling method
  */
 #ifdef MULTI_TLB
 
-#define __cpu_flush_user_tlb_range	cpu_tlb.flush_user_range
-#define __cpu_flush_kern_tlb_range	cpu_tlb.flush_kern_range
+static inline void __nocfi __cpu_flush_user_tlb_range(unsigned long s, unsigned long e, struct vm_area_struct *vma)
+{
+	cpu_tlb.flush_user_range(s, e, vma);
+}
+static inline void __nocfi __cpu_flush_kern_tlb_range(unsigned long s, unsigned long e)
+{
+	cpu_tlb.flush_kern_range(s, e);
+}
 
 #else
 
@@ -228,10 +238,6 @@ extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
 
 #endif
 
-extern struct cpu_tlb_fns cpu_tlb;
-
-#define __cpu_tlb_flags			cpu_tlb.tlb_flags
-
 /*
  *	TLB Management
  *	==============

-- 
2.34.1



From linus.walleij at linaro.org  Sun Feb 25 12:08:12 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 25 Feb 2024 21:08:12 +0100
Subject: [PATCH 3/7] ARM: bugs: Check in the vtable instead of defined
 aliases
In-Reply-To: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
References: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
Message-ID: <20240225-arm32-cfi-v1-3-6943306f065b@linaro.org>

Instead of checking if cpu_check_bugs() exist, check for this
callback directly in the CPU vtable: this is better because the
function is just a define to the vtable entry and this is why
the code works. But we want to be able to specify a proper
function for cpu_check_bugs() so look into the vtable instead.

In bugs.c assign PROC_VTABLE(switch_mm) instead of
assigning cpu_do_switch_mm where again this is just a define
into the vtable: this makes it possible to make
cpu_do_switch_mm() into a real function.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/kernel/bugs.c     | 2 +-
 arch/arm/mm/proc-v7-bugs.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/bugs.c b/arch/arm/kernel/bugs.c
index 087bce6ec8e9..35d39efb51ed 100644
--- a/arch/arm/kernel/bugs.c
+++ b/arch/arm/kernel/bugs.c
@@ -7,7 +7,7 @@
 void check_other_bugs(void)
 {
 #ifdef MULTI_CPU
-	if (cpu_check_bugs)
+	if (PROC_VTABLE(check_bugs))
 		cpu_check_bugs();
 #endif
 }
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
index 8bc7a2d6d6c7..ea3ee2bd7b56 100644
--- a/arch/arm/mm/proc-v7-bugs.c
+++ b/arch/arm/mm/proc-v7-bugs.c
@@ -87,14 +87,14 @@ static unsigned int spectre_v2_install_workaround(unsigned int method)
 	case SPECTRE_V2_METHOD_HVC:
 		per_cpu(harden_branch_predictor_fn, cpu) =
 			call_hvc_arch_workaround_1;
-		cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
+		PROC_VTABLE(switch_mm) = cpu_v7_hvc_switch_mm;
 		spectre_v2_method = "hypervisor";
 		break;
 
 	case SPECTRE_V2_METHOD_SMC:
 		per_cpu(harden_branch_predictor_fn, cpu) =
 			call_smc_arch_workaround_1;
-		cpu_do_switch_mm = cpu_v7_smc_switch_mm;
+		PROC_VTABLE(switch_mm) = cpu_v7_smc_switch_mm;
 		spectre_v2_method = "firmware";
 		break;
 	}

-- 
2.34.1



From linus.walleij at linaro.org  Sun Feb 25 12:08:13 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 25 Feb 2024 21:08:13 +0100
Subject: [PATCH 4/7] ARM: proc: Use inlines instead of defines
In-Reply-To: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
References: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
Message-ID: <20240225-arm32-cfi-v1-4-6943306f065b@linaro.org>

We currently access the per-cpu vtable with defines such
as:

  define cpu_proc_init PROC_VTABLE(_proc_init)

Convert all of these instances to static inlines instead:

  static inline __nocfi void cpu_proc_init(void)
  {
        PROC_VTABLE(_proc_init)();
  }

This has the upside that we can add the __nocfi tag to
the inline function so CFI can skip over this and work,
and we can simplify some platform code that was looking
into the symbol table to be able to call cpu_reset(),
now we can just call it instead.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/common/mcpm_entry.c    | 10 ++------
 arch/arm/include/asm/proc-fns.h | 57 +++++++++++++++++++++++++++++++++--------
 arch/arm/mach-sunxi/mc_smp.c    |  7 +----
 3 files changed, 50 insertions(+), 24 deletions(-)

diff --git a/arch/arm/common/mcpm_entry.c b/arch/arm/common/mcpm_entry.c
index e013ff1168d3..3e19f246caff 100644
--- a/arch/arm/common/mcpm_entry.c
+++ b/arch/arm/common/mcpm_entry.c
@@ -234,13 +234,10 @@ int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster)
 	return ret;
 }
 
-typedef typeof(cpu_reset) phys_reset_t;
-
 void mcpm_cpu_power_down(void)
 {
 	unsigned int mpidr, cpu, cluster;
 	bool cpu_going_down, last_man;
-	phys_reset_t phys_reset;
 
 	mpidr = read_cpuid_mpidr();
 	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
@@ -298,8 +295,7 @@ void mcpm_cpu_power_down(void)
 	 * the kernel as if the power_up method just had deasserted reset
 	 * on the CPU.
 	 */
-	phys_reset = (phys_reset_t)(unsigned long)__pa_symbol(cpu_reset);
-	phys_reset(__pa_symbol(mcpm_entry_point), false);
+	cpu_reset(__pa_symbol(mcpm_entry_point), false);
 
 	/* should never get here */
 	BUG();
@@ -376,7 +372,6 @@ static int __init nocache_trampoline(unsigned long _arg)
 	unsigned int mpidr = read_cpuid_mpidr();
 	unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
 	unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
-	phys_reset_t phys_reset;
 
 	mcpm_set_entry_vector(cpu, cluster, cpu_resume_no_hyp);
 	setup_mm_for_reboot();
@@ -387,8 +382,7 @@ static int __init nocache_trampoline(unsigned long _arg)
 	__mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN);
 	__mcpm_cpu_down(cpu, cluster);
 
-	phys_reset = (phys_reset_t)(unsigned long)__pa_symbol(cpu_reset);
-	phys_reset(__pa_symbol(mcpm_entry_point), false);
+	cpu_reset(__pa_symbol(mcpm_entry_point), false);
 	BUG();
 }
 
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 280396483f5d..9bd6bf5f901a 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -131,18 +131,55 @@ static inline void init_proc_vtable(const struct processor *p)
 }
 #endif
 
-#define cpu_proc_init			PROC_VTABLE(_proc_init)
-#define cpu_check_bugs			PROC_VTABLE(check_bugs)
-#define cpu_proc_fin			PROC_VTABLE(_proc_fin)
-#define cpu_reset			PROC_VTABLE(reset)
-#define cpu_do_idle			PROC_VTABLE(_do_idle)
-#define cpu_dcache_clean_area		PROC_TABLE(dcache_clean_area)
-#define cpu_set_pte_ext			PROC_TABLE(set_pte_ext)
-#define cpu_do_switch_mm		PROC_VTABLE(switch_mm)
+static inline void __nocfi cpu_proc_init(void)
+{
+	PROC_VTABLE(_proc_init)();
+}
+static inline void __nocfi cpu_check_bugs(void)
+{
+	PROC_VTABLE(check_bugs)();
+}
+static inline void __nocfi cpu_proc_fin(void)
+{
+	PROC_VTABLE(_proc_fin)();
+}
+static inline void __nocfi cpu_reset(unsigned long addr, bool hvc)
+{
+	PROC_VTABLE(reset)(addr, hvc);
+}
+static inline int __nocfi cpu_do_idle(void)
+{
+	return PROC_VTABLE(_do_idle)();
+}
+static inline void __nocfi cpu_dcache_clean_area(void *addr, int size)
+{
+	PROC_TABLE(dcache_clean_area)(addr, size);
+}
+#ifdef CONFIG_ARM_LPAE
+static inline void __nocfi cpu_set_pte_ext(pte_t *ptep, pte_t pte)
+{
+	PROC_TABLE(set_pte_ext)(ptep, pte);
+}
+#else
+static inline void __nocfi cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext)
+{
+	PROC_TABLE(set_pte_ext)(ptep, pte, ext);
+}
+#endif
+static inline void __nocfi cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm)
+{
+	PROC_VTABLE(switch_mm)(pgd_phys, mm);
+}
 
 /* These two are private to arch/arm/kernel/suspend.c */
-#define cpu_do_suspend			PROC_VTABLE(do_suspend)
-#define cpu_do_resume			PROC_VTABLE(do_resume)
+static inline void __nocfi cpu_do_suspend(void *p)
+{
+	PROC_VTABLE(do_suspend)(p);
+}
+static inline void __nocfi cpu_do_resume(void *p)
+{
+	PROC_VTABLE(do_resume)(p);
+}
 #endif
 
 extern void cpu_resume(void);
diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
index 277f6aa8e6c2..791eabb7d433 100644
--- a/arch/arm/mach-sunxi/mc_smp.c
+++ b/arch/arm/mach-sunxi/mc_smp.c
@@ -646,17 +646,12 @@ static bool __init sunxi_mc_smp_cpu_table_init(void)
  *
  * We need the trampoline code to enable CCI-400 on the first cluster
  */
-typedef typeof(cpu_reset) phys_reset_t;
-
 static int __init nocache_trampoline(unsigned long __unused)
 {
-	phys_reset_t phys_reset;
-
 	setup_mm_for_reboot();
 	sunxi_cluster_cache_disable_without_axi();
 
-	phys_reset = (phys_reset_t)(unsigned long)__pa_symbol(cpu_reset);
-	phys_reset(__pa_symbol(sunxi_mc_smp_resume), false);
+	cpu_reset(__pa_symbol(sunxi_mc_smp_resume), false);
 	BUG();
 }
 

-- 
2.34.1



From linus.walleij at linaro.org  Sun Feb 25 12:08:14 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 25 Feb 2024 21:08:14 +0100
Subject: [PATCH 5/7] ARM: delay: Turn delay functions into static inlines
In-Reply-To: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
References: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
Message-ID: <20240225-arm32-cfi-v1-5-6943306f065b@linaro.org>

The members of the vector table arm_delay_ops are called
directly using defines, but this is really confusing for
KCFI. Wrap the calls in static inlines and tag them with
__nocfi so things start to work.

Without this patch, platforms without a delay timer will
not boot (sticks in calibrating loop etc).

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/include/asm/delay.h | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
index 1d069e558d8d..7d611b810b6c 100644
--- a/arch/arm/include/asm/delay.h
+++ b/arch/arm/include/asm/delay.h
@@ -55,7 +55,10 @@ extern struct arm_delay_ops {
 	unsigned long ticks_per_jiffy;
 } arm_delay_ops;
 
-#define __delay(n)		arm_delay_ops.delay(n)
+static inline void __nocfi __delay(unsigned long n)
+{
+	arm_delay_ops.delay(n);
+}
 
 /*
  * This function intentionally does not exist; if you see references to
@@ -76,8 +79,15 @@ extern void __bad_udelay(void);
  * first constant multiplications gets optimized away if the delay is
  * a constant)
  */
-#define __udelay(n)		arm_delay_ops.udelay(n)
-#define __const_udelay(n)	arm_delay_ops.const_udelay(n)
+static inline void __nocfi __udelay(unsigned long n)
+{
+	arm_delay_ops.udelay(n);
+}
+
+static inline void __nocfi __const_udelay(unsigned long n)
+{
+	arm_delay_ops.const_udelay(n);
+}
 
 #define udelay(n)							\
 	(__builtin_constant_p(n) ?					\

-- 
2.34.1



From linus.walleij at linaro.org  Sun Feb 25 12:08:15 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 25 Feb 2024 21:08:15 +0100
Subject: [PATCH 6/7] ARM: turn CPU cache flush functions into static
 inlines
In-Reply-To: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
References: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
Message-ID: <20240225-arm32-cfi-v1-6-6943306f065b@linaro.org>

The members of the vector table struct cpu_cache_fns cpu_cache
are called directly using defines, but this is really confusing
for KCFI. Wrap the calls in static inlines and tag them with
__nocfi so things start to work.

Conversely a similar approach is used for the __glue() helpers
which define their way into an assembly ENTRY(symbol) for respective
CPU variant. We wrap these into static inlines and prefix them
with __nocfi as well. (This happens on !MULTI_CACHE systems.)
For this case we also need to invoke the __glue() macro to
provide a proper function prototype for the inner function.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/include/asm/cacheflush.h | 45 +++++++++++++++++++++++++++++++--------
 arch/arm/mm/dma.h                 | 28 ++++++++++++++++++------
 2 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 1075534b0a2e..76fb665162a4 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -122,14 +122,38 @@ struct cpu_cache_fns {
 
 extern struct cpu_cache_fns cpu_cache;
 
-#define __cpuc_flush_icache_all		cpu_cache.flush_icache_all
-#define __cpuc_flush_kern_all		cpu_cache.flush_kern_all
-#define __cpuc_flush_kern_louis		cpu_cache.flush_kern_louis
-#define __cpuc_flush_user_all		cpu_cache.flush_user_all
-#define __cpuc_flush_user_range		cpu_cache.flush_user_range
-#define __cpuc_coherent_kern_range	cpu_cache.coherent_kern_range
-#define __cpuc_coherent_user_range	cpu_cache.coherent_user_range
-#define __cpuc_flush_dcache_area	cpu_cache.flush_kern_dcache_area
+static inline void __nocfi __cpuc_flush_icache_all(void)
+{
+	cpu_cache.flush_icache_all();
+}
+static inline void __nocfi __cpuc_flush_kern_all(void)
+{
+	cpu_cache.flush_icache_all();
+}
+static inline void __nocfi __cpuc_flush_kern_louis(void)
+{
+	cpu_cache.flush_kern_louis();
+}
+static inline void __nocfi __cpuc_flush_user_all(void)
+{
+	cpu_cache.flush_user_all();
+}
+static inline void __nocfi __cpuc_flush_user_range(unsigned long start, unsigned long end, unsigned int flags)
+{
+	cpu_cache.flush_user_range(start, end, flags);
+}
+static inline void __nocfi __cpuc_coherent_kern_range(unsigned long start, unsigned long end)
+{
+	cpu_cache.coherent_kern_range(start, end);
+}
+static inline int __nocfi __cpuc_coherent_user_range(unsigned long start, unsigned long end)
+{
+	return cpu_cache.coherent_user_range(start, end);
+}
+static inline void __nocfi __cpuc_flush_dcache_area(void *kaddr, size_t sz)
+{
+	cpu_cache.flush_kern_dcache_area(kaddr, sz);
+}
 
 /*
  * These are private to the dma-mapping API.  Do not use directly.
@@ -137,7 +161,10 @@ extern struct cpu_cache_fns cpu_cache;
  * is visible to DMA, or data written by DMA to system memory is
  * visible to the CPU.
  */
-#define dmac_flush_range		cpu_cache.dma_flush_range
+static inline void __nocfi dmac_flush_range(const void *start, const void *end)
+{
+	cpu_cache.dma_flush_range(start, end);
+}
 
 #else
 
diff --git a/arch/arm/mm/dma.h b/arch/arm/mm/dma.h
index aaef64b7f177..251b8a9fffc1 100644
--- a/arch/arm/mm/dma.h
+++ b/arch/arm/mm/dma.h
@@ -5,8 +5,6 @@
 #include <asm/glue-cache.h>
 
 #ifndef MULTI_CACHE
-#define dmac_map_area			__glue(_CACHE,_dma_map_area)
-#define dmac_unmap_area 		__glue(_CACHE,_dma_unmap_area)
 
 /*
  * These are private to the dma-mapping API.  Do not use directly.
@@ -14,8 +12,20 @@
  * is visible to DMA, or data written by DMA to system memory is
  * visible to the CPU.
  */
-extern void dmac_map_area(const void *, size_t, int);
-extern void dmac_unmap_area(const void *, size_t, int);
+
+/* These turn into function declarations for each per-CPU glue function */
+void __glue(_CACHE,_dma_map_area)(const void *, size_t, int);
+void __glue(_CACHE,_dma_unmap_area)(const void *, size_t, int);
+
+static inline void __nocfi dmac_map_area(const void *start, size_t sz, int flags)
+{
+	__glue(_CACHE,_dma_map_area)(start, sz, flags);
+}
+
+static inline void __nocfi dmac_unmap_area(const void *start, size_t sz, int flags)
+{
+	__glue(_CACHE,_dma_unmap_area)(start, sz, flags);
+}
 
 #else
 
@@ -25,8 +35,14 @@ extern void dmac_unmap_area(const void *, size_t, int);
  * is visible to DMA, or data written by DMA to system memory is
  * visible to the CPU.
  */
-#define dmac_map_area			cpu_cache.dma_map_area
-#define dmac_unmap_area 		cpu_cache.dma_unmap_area
+static inline void __nocfi dmac_map_area(const void *start, size_t sz, int flags)
+{
+	cpu_cache.dma_map_area(start, sz, flags);
+}
+static inline void __nocfi dmac_unmap_area(const void *start, size_t sz, int flags)
+{
+	cpu_cache.dma_unmap_area(start, sz, flags);
+}
 
 #endif
 

-- 
2.34.1



From linus.walleij at linaro.org  Sun Feb 25 12:08:16 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 25 Feb 2024 21:08:16 +0100
Subject: [PATCH 7/7] ARM: page: Turn highpage accesses into static inlines
In-Reply-To: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
References: <20240225-arm32-cfi-v1-0-6943306f065b@linaro.org>
Message-ID: <20240225-arm32-cfi-v1-7-6943306f065b@linaro.org>

Clearing and copying pages in highmem uses either the cpu_user
vtable or the __glue() assembler stubs to call into per-CPU
versions of these functions.

This is all really confusing for KCFI so wrap these into static
inlines and prefix each inline function with __nocfi.

__cpu_clear_user_highpage() and __cpu_copy_user_highpage() are
exported in arch/arm/mm/proc-syms.c which causes a problem with
using static inlines, but it turns out that these exports are
completely unused, so we can just delete them.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/include/asm/page.h | 36 +++++++++++++++++++++++++++++-------
 arch/arm/mm/proc-syms.c     |  7 +------
 2 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 119aa85d1feb..8bf297228627 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -138,17 +138,39 @@ void xscale_mc_clear_user_highpage(struct page *page, unsigned long vaddr);
 #ifdef MULTI_USER
 extern struct cpu_user_fns cpu_user;
 
-#define __cpu_clear_user_highpage	cpu_user.cpu_clear_user_highpage
-#define __cpu_copy_user_highpage	cpu_user.cpu_copy_user_highpage
+static inline void __nocfi __cpu_clear_user_highpage(struct page *page,
+						     unsigned long vaddr)
+{
+	cpu_user.cpu_clear_user_highpage(page, vaddr);
+}
+
+static inline void __nocfi __cpu_copy_user_highpage(struct page *to,
+			struct page *from, unsigned long vaddr,
+			struct vm_area_struct *vma)
+{
+	cpu_user.cpu_copy_user_highpage(to, from, vaddr, vma);
+}
 
 #else
 
-#define __cpu_clear_user_highpage	__glue(_USER,_clear_user_highpage)
-#define __cpu_copy_user_highpage	__glue(_USER,_copy_user_highpage)
+/* These turn into function declarations for each per-CPU glue function */
+void __glue(_USER,_clear_user_highpage)(struct page *page, unsigned long vaddr);
+void __glue(_USER,_copy_user_highpage)(struct page *to, struct page *from,
+		unsigned long vaddr, struct vm_area_struct *vma);
+
+static inline void __nocfi __cpu_clear_user_highpage(struct page *page,
+						     unsigned long vaddr)
+{
+	__glue(_USER,_clear_user_highpage)(page, vaddr);
+}
+
+static inline void __nocfi __cpu_copy_user_highpage(struct page *to,
+			struct page *from, unsigned long vaddr,
+			struct vm_area_struct *vma)
+{
+	__glue(_USER,_copy_user_highpage)(to, from, vaddr, vma);
+}
 
-extern void __cpu_clear_user_highpage(struct page *page, unsigned long vaddr);
-extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
-			unsigned long vaddr, struct vm_area_struct *vma);
 #endif
 
 #define clear_user_highpage(page,vaddr)		\
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
index e21249548e9f..c93fec38d9f4 100644
--- a/arch/arm/mm/proc-syms.c
+++ b/arch/arm/mm/proc-syms.c
@@ -31,14 +31,9 @@ EXPORT_SYMBOL(__cpuc_flush_dcache_area);
 EXPORT_SYMBOL(cpu_cache);
 #endif
 
-#ifdef CONFIG_MMU
-#ifndef MULTI_USER
-EXPORT_SYMBOL(__cpu_clear_user_highpage);
-EXPORT_SYMBOL(__cpu_copy_user_highpage);
-#else
+#if defined(CONFIG_MMU) && defined(MULTI_USER)
 EXPORT_SYMBOL(cpu_user);
 #endif
-#endif
 
 /*
  * No module should need to touch the TLB (and currently

-- 
2.34.1



From kieran.bingham at ideasonboard.com  Sun Feb 25 13:22:52 2024
From: kieran.bingham at ideasonboard.com (Kieran Bingham)
Date: Sun, 25 Feb 2024 21:22:52 +0000
Subject: [PATCH v2 4/5] media: Documentation: Add Mali-C55 ISP Documentation
In-Reply-To: <20240214141906.245685-5-dan.scally@ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com> <20240214141906.245685-5-dan.scally@ideasonboard.com>
Message-ID: <170889617240.914352.11519004661256637360@ping.linuxembedded.co.uk>

Hi Dan,

Quoting Daniel Scally (2024-02-14 14:19:05)
> Add a documentation page for the mali-c55 driver, which gives a brief
> overview of the hardware and explains how to use the driver's capture
> devices and the crop/scaler functions.
> 
> Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> ---
> Changes in v2:
> 
>         - none
> 
>  .../admin-guide/media/mali-c55-graph.dot      |  19 ++
>  Documentation/admin-guide/media/mali-c55.rst  | 318 ++++++++++++++++++
>  .../admin-guide/media/v4l-drivers.rst         |   1 +
>  3 files changed, 338 insertions(+)
>  create mode 100644 Documentation/admin-guide/media/mali-c55-graph.dot
>  create mode 100644 Documentation/admin-guide/media/mali-c55.rst
> 
> diff --git a/Documentation/admin-guide/media/mali-c55-graph.dot b/Documentation/admin-guide/media/mali-c55-graph.dot
> new file mode 100644
> index 000000000000..0775ba42bf4c
> --- /dev/null
> +++ b/Documentation/admin-guide/media/mali-c55-graph.dot
> @@ -0,0 +1,19 @@
> +digraph board {
> +        rankdir=TB
> +        n00000001 [label="{{} | mali-c55 tpg\n/dev/v4l-subdev0 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
> +        n00000001:port0 -> n00000003:port0 [style=dashed]
> +        n00000003 [label="{{<port0> 0} | mali-c55 isp\n/dev/v4l-subdev1 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
> +        n00000003:port1 -> n00000007:port0 [style=bold]
> +        n00000003:port2 -> n00000007:port2 [style=bold]
> +        n00000003:port1 -> n0000000b:port0 [style=bold]
> +        n00000007 [label="{{<port0> 0 | <port2> 2} | mali-c55 resizer fr\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
> +        n00000007:port1 -> n0000000e [style=bold]
> +        n0000000b [label="{{<port0> 0} | mali-c55 resizer ds\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
> +        n0000000b:port1 -> n00000012 [style=bold]
> +        n0000000e [label="mali-c55 fr\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
> +        n00000012 [label="mali-c55 ds\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
> +        n00000022 [label="{{<port0> 0} | csi2-rx\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
> +        n00000022:port1 -> n00000003:port0
> +        n00000027 [label="{{} | imx415 1-001a\n/dev/v4l-subdev5 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
> +        n00000027:port0 -> n00000022:port0 [style=bold]
> +}
> \ No newline at end of file
> diff --git a/Documentation/admin-guide/media/mali-c55.rst b/Documentation/admin-guide/media/mali-c55.rst
> new file mode 100644
> index 000000000000..83f630c3bd9d
> --- /dev/null
> +++ b/Documentation/admin-guide/media/mali-c55.rst
> @@ -0,0 +1,318 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +==========================================
> +ARM Mali-C55 Image Signal Processor driver
> +==========================================
> +
> +Introduction
> +============
> +
> +This file documents the driver for ARM's Mali-C55 Image Signal Processor. The
> +driver is located under drivers/media/platform/arm/mali-c55.
> +
> +The Mali-C55 ISP receives data in either raw Bayer format or RGB/YUV format from
> +sensors through either a parallel interface or a memory bus before processing it
> +and outputting it through an internal DMA engine. Two output pipelines are
> +possible (though one may not be fitted, depending on the implementation). These
> +are referred to as "Full resolution" and "Downscale", but the naming is historic
> +and both pipes are capable of cropping/scaling operations. An integrated test
> +pattern generator can be used to drive the ISP and produce image data in the
> +absence of a connected camera sensor. The driver module is named mali_c55, and
> +is enabled through the CONFIG_VIDEO_MALI_C55 config option.

Can it handle metadata or other datatypes separately? anything else
that's worthy of mention? Or maybe not yet in this version.

> +
> +The driver implements V4L2, Media Controller and V4L2 Subdevice interfaces and
> +expects camera sensors connected to the ISP to have V4L2 subdevice interfaces.
> +
> +Mali-C55 ISP hardware
> +=====================
> +
> +A high level functional view of the Mali-C55 ISP is presented below. The ISP
> +takes input from either a live source or through a DMA engine for memory input,
> +depending on the SoC integration.::
> +
> +  +---------+    +----------+                                     +--------+
> +  | Sensor  |--->| CSI-2 Rx |                "Full Resolution"    |  DMA   |
> +  +---------+    +----------+   |\                 Output    +--->| Writer |
> +                       |        | \                          |    +--------+
> +                       |        |  \    +----------+  +------+---> Streaming I/O
> +  +------------+       +------->|   |   |          |  |
> +  |            |                |   |-->| Mali-C55 |--+
> +  | DMA Reader |--------------->|   |   |    ISP   |  |
> +  |            |                |  /    |          |  |      +---> Streaming I/O
> +  +------------+                | /     +----------+  |      |
> +                                |/                    +------+
> +                                                            |    +--------+
> +                                                             +--->|  DMA   |
> +                                               "Downscaled"       | Writer |
> +                                                 Output          +--------+
> +
> +Media Controller Topology
> +=========================
> +
> +An example of the ISP's topology (as implemented in a system with an IMX415
> +camera sensor and generic CSI-2 receiver) is below:
> +
> +
> +.. kernel-figure:: mali-c55-graph.dot
> +    :alt:   mali-c55-graph.dot
> +    :align: center
> +
> +The driver has 4 V4L2 subdevices:
> +
> +- `mali_c55 isp`: Responsible for configuring input crop and color space
> +                  conversion
> +- `mali_c55 tpg`: The test pattern generator, emulating a camera sensor.
> +- `mali_c55 resizer fr`: The Full-Resolution pipe resizer
> +- `mali_c55 resizer ds`: The Downscale pipe resizer
> +
> +The driver has 2 V4L2 video devices:
> +
> +- `mali-c55 fr`: The full-resolution pipe's capture device
> +- `mali-c55 ds`: The downscale pipe's capture device
> +
> +Idiosyncrasies
> +--------------
> +
> +**mali-c55 isp**
> +The `mali-c55 isp` subdevice has a single sink pad to which all sources of data
> +should be connected. The active source is selected by enabling the appropriate
> +media link and disabling all others.

By that I presume you mean you can only accept a single input link at a
time?

> The ISP has two source pads, reflecting the
> +different paths through which it can internally route data. Tap points within
> +the ISP allow users to divert data to avoid processing by some or all of the
> +hardware's processing steps. The diagram below is intended only to highlight how
> +the bypassing works and is not a true reflection of those processing steps; for
> +a high-level functional block diagram see ARM's developer page for the
> +ISP [3]_::
> +
> +  +--------------------------------------------------------------+
> +  |                Possible Internal ISP Data Routes             |
> +  |          +------------+  +----------+  +------------+        |
> +  +---+      |            |  |          |  |  Colour    |    +---+
> +  | 0 |--+-->| Processing |->| Demosaic |->|   Space    |--->| 1 |
> +  +---+  |   |            |  |          |  | Conversion |    +---+
> +  |      |   +------------+  +----------+  +------------+        |
> +  |      |                                                   +---+
> +  |      +---------------------------------------------------| 2 |
> +  |                                                          +---+
> +  |                                                              |
> +  +--------------------------------------------------------------+
> +
> +
> +.. flat-table::
> +    :header-rows: 1
> +
> +    * - Pad
> +      - Direction
> +      - Purpose
> +
> +    * - 0
> +      - sink
> +      - Data input, connected to the TPG and camera sensors
> +
> +    * - 1
> +      - source
> +      - RGB/YUV data, connected to the FR and DS V4L2 subdevices
> +
> +    * - 2
> +      - source
> +      - RAW bayer data, connected to the FR V4L2 subdevices
> +
> +**mali-c55 resizer fr**
> +The `mali-c55 resizer fr` subdevice has two _sink_ pads to reflect the different
> +insertion points in the hardware (either RAW or demosaiced data):
> +
> +.. flat-table::
> +    :header-rows: 1
> +
> +    * - Pad
> +      - Direction
> +      - Purpose
> +
> +    * - 0
> +      - sink
> +      - Data input connected to the ISP's demosaiced stream.
> +
> +    * - 1
> +      - source
> +      - Data output connected to the capture video device
> +
> +    * - 2
> +      - sink
> +      - Data input connected to the ISP's raw data stream
> +
> +The data source in use is selected through the routing API; two routes each of a
> +single stream are available:
> +
> +.. flat-table::
> +    :header-rows: 1
> +
> +    * - Sink Pad
> +      - Source Pad
> +      - Purpose
> +
> +    * - 0
> +      - 1
> +      - Demosaiced data route
> +
> +    * - 2
> +      - 1
> +      - Raw data route
> +
> +
> +If the demosaiced route is active then the FR pipe is only capable of output
> +in RGB/YUV formats. If the raw route is active then the output reflects the
> +input (which may be either Bayer or RGB/YUV data).
> +
> +Using the driver to capture video
> +=================================
> +
> +Using the media controller APIs we can configure the input source and ISP to
> +capture images in a variety of formats. In the examples below, configuring the
> +media graph is done with the v4l-utils [1]_ package's media-ctl utility.
> +Capturing the images is done with yavta [2]_.
> +
> +Configuring the input source
> +----------------------------
> +
> +The first step is to set the input source that we wish by enabling the correct
> +media link. Using the example topology above, we can select the TPG as follows:
> +
> +.. code-block:: none
> +
> +    media-ctl -l "'lte-csi2-rx':1->'mali-c55 isp':0[0]"
> +    media-ctl -l "'mali-c55 tpg':0->'mali-c55 isp':0[1]"
> +
> +Capturing bayer data from the source and processing to RGB/YUV
> +--------------------------------------------------------------
> +To capture 1920x1080 bayer data from the source and push it through the ISP's
> +full processing pipeline, we configure the data formats appropriately on the
> +source, ISP and resizer subdevices and set the FR resizer's routing to select
> +processed data. The media bus format on the resizer's source pad will be either
> +RGB121212_1X36 or YUV10_1X30, depending on whether you want to capture RGB or
> +YUV. The ISP's debayering block outputs RGB data natively, setting the source
> +pad format to YUV10_1X30 enables the colour space conversion block.
> +
> +In this example we target RGB565 output, so select RGB121212_1X36 as the resizer
> +source pad's format:
> +
> +.. code-block:: none
> +
> +    # Set formats on the TPG and ISP
> +    media-ctl -V "'mali-c55 tpg':0[fmt:SRGGB16_1X16/1920x1080]"
> +    media-ctl -V "'mali-c55 isp':0[fmt:SRGGB16_1X16/1920x1080]"
> +    media-ctl -V "'mali-c55 isp':1[fmt:SRGGB16_1X16/1920x1080]"
> +
> +    # Set routing on the FR resizer
> +    media-ctl -R "'mali-c55 resizer fr'[0/0->1/0[1],2/0->1/0[0]]"
> +
> +    # Set format on the resizer, must be done AFTER the routing.
> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/1920x1080]"
> +
> +The downscale output can also be used to stream data at the same time. In this
> +case only processed data can be captured and so no routing need be set:

Is the route automatically reset? or is it just that the default route
is already the correct choice for this instance?

> +
> +.. code-block:: none
> +
> +    # Set format on the resizer
> +    media-ctl -V "'mali-c55 resizer ds':1[fmt:RGB121212_1X36/1920x1080]"
> +
> +Following which images can be captured from both the FR and DS output's video
> +devices (simultaneously, if desired):
> +
> +.. code-block:: none
> +
> +    yavta -f RGB565 -s 1920x1080 -c10 /dev/video0
> +    yavta -f RGB565 -s 1920x1080 -c10 /dev/video1
> +

Is there any synchronisation required? Can one pipe run without the
other if they are both enabled? or will stalling on one pipe stall the
other?

> +Cropping the image
> +~~~~~~~~~~~~~~~~~~
> +
> +Both the full resolution and downscale pipes can crop to a minimum resolution of
> +640x480. To crop the image simply configure the resizer's sink pad's crop and
> +compose rectangles and set the format on the video device:
> +
> +.. code-block:: none
> +
> +    media-ctl -V "'mali-c55 resizer fr':0[fmt:RGB121212_1X36/1920x1080 crop:(480,270)/640x480 compose:(0,0)/640x480]"
> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/640x480]"
> +    yavta -f RGB565 -s 640x480 -c10 /dev/video0
> +
> +Downscaling the image
> +~~~~~~~~~~~~~~~~~~~~~
> +
> +Both the full resolution and downscale pipes can downscale the image by up to 8x
> +provided the minimum 640x480 resolution is adhered to. For the best image result

'minimum 640x480 output resolution' I presume.

Maybe the ISP limits/restrictions need to be defined before here?

> +the scaling ratio for each dimension should be the same. To configure scaling we
> +use the compose rectangle on the resizer's sink pad:
> +
> +.. code-block:: none
> +
> +    media-ctl -V "'mali-c55 resizer fr':0[fmt:RGB121212_1X36/1920x1080 crop:(0,0)/1920x1080 compose:(0,0)/640x480]"
> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/640x480]"
> +    yavta -f RGB565 -s 640x480 -c10 /dev/video0
> +
> +Capturing images in YUV formats
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +If we need to output YUV data rather than RGB the color space conversion block
> +needs to be active, which is achieved by setting MEDIA_BUS_FMT_YUV10_1X30 on the

Is 10 bit required here? (As opposed to the 12 bit before in the
pipeline? is that a limitation on the component?) or is this to match
the desired output format?

> +resizer's source pad. We can then configure a capture format like NV12 (here in
> +its multi-planar variant)
> +
> +.. code-block:: none
> +
> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:YUV10_1X30/1920x1080]"
> +    yavta -f NV12M -s 1920x1080 -c10 /dev/video0
> +
> +Capturing RGB data from the source and processing it with the resizers
> +----------------------------------------------------------------------
> +
> +The Mali-C55 ISP can work with sensors capable of outputting RGB data. In this
> +case although none of the image quality blocks would be used it can still
> +crop/scale the data in the usual way.
> +
> +To achieve this, the ISP's sink pad's format is set to
> +MEDIA_BUS_FMT_RGB202020_1X60 - this reflects the format that data must be in to
> +work with the ISP. Converting the camera sensor's output to that format is the
> +responsibility of external hardware.
> +
> +In this example we ask the test pattern generator to give us RGB data instead of
> +bayer.
> +
> +.. code-block:: none
> +
> +    media-ctl -V "'mali-c55 tpg':0[fmt:RGB202020_1X60/1920x1080]"
> +    media-ctl -V "'mali-c55 isp':0[fmt:RGB202020_1X60/1920x1080]"
> +
> +Cropping or scaling the data can be done in exactly the same way as outlined
> +earlier.
> +
> +Capturing raw data from the source and outputting it unmodified
> +-----------------------------------------------------------------
> +
> +The ISP can additionally capture raw data from the source and output it on the
> +full resolution pipe only, completely unmodified. In this case the downscale
> +pipe can still process the data normally and be used at the same time.
> +
> +To configure raw bypass the FR resizer's subdevice's routing table needs to be
> +configured, followed by formats in the appropriate places:
> +
> +.. code-block:: none
> +
> +    # We need to configure the routing table for the resizer to use the bypass
> +    # path along with set formats on the resizer's bypass sink pad. Doing this
> +    # necessitates a single media-ctl command, as multiple calls to the program
> +    # reset the routing table.
> +    media-ctl -R "'mali-c55 resizer fr'[0/0->1/0[0],2/0->1/0[1]]"\
> +    -V "'mali-c55 isp':0[fmt:RGB202020_1X60/1920x1080],"\
> +       "'mali-c55 resizer fr':2[fmt:RGB202020_1X60/1920x1080],"\
> +       "'mali-c55 resizer fr':1[fmt:RGB202020_1X60/1920x1080]"
> +
> +    # Set format on the video device and stream
> +    yavta -f RGB565 -s 1920x1080 -c10 /dev/video0
> +
> +References
> +==========
> +.. [1] https://git.linuxtv.org/v4l-utils.git/
> +.. [2] https://git.ideasonboard.org/yavta.git
> +.. [3] https://developer.arm.com/Processors/Mali-C55
> diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentation/admin-guide/media/v4l-drivers.rst
> index f4bb2605f07e..af033c892808 100644
> --- a/Documentation/admin-guide/media/v4l-drivers.rst
> +++ b/Documentation/admin-guide/media/v4l-drivers.rst
> @@ -17,6 +17,7 @@ Video4Linux (V4L) driver-specific documentation
>         imx7
>         ipu3
>         ivtv
> +       mali-c55
>         mgb4
>         omap3isp
>         omap4_camera
> -- 
> 2.34.1
>


From chris.packham at alliedtelesis.co.nz  Sun Feb 25 13:34:23 2024
From: chris.packham at alliedtelesis.co.nz (Chris Packham)
Date: Mon, 26 Feb 2024 10:34:23 +1300
Subject: [PATCH 3/3] ARM: dts: marvell: Add 7 segment LED display on x530
In-Reply-To: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz>
References: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz>
Message-ID: <20240225213423.690561-4-chris.packham@alliedtelesis.co.nz>

The Allied Telesis x530 products have a 7 segment LED display which is
used for node identification when the devices are stacked. Represent
this as a gpio-7seg device.

Signed-off-by: Chris Packham <chris.packham at alliedtelesis.co.nz>
---
 arch/arm/boot/dts/marvell/armada-385-atl-x530.dts | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/marvell/armada-385-atl-x530.dts b/arch/arm/boot/dts/marvell/armada-385-atl-x530.dts
index 5a9ab8410b7b..088b77987081 100644
--- a/arch/arm/boot/dts/marvell/armada-385-atl-x530.dts
+++ b/arch/arm/boot/dts/marvell/armada-385-atl-x530.dts
@@ -43,6 +43,17 @@ uart0: serial at 12000 {
 			};
 		};
 	};
+
+	led-7seg {
+		compatible = "generic,gpio-7seg";
+		segment-gpios = <&led_7seg_gpio 0 GPIO_ACTIVE_LOW
+				 &led_7seg_gpio 1 GPIO_ACTIVE_LOW
+				 &led_7seg_gpio 2 GPIO_ACTIVE_LOW
+				 &led_7seg_gpio 3 GPIO_ACTIVE_LOW
+				 &led_7seg_gpio 4 GPIO_ACTIVE_LOW
+				 &led_7seg_gpio 5 GPIO_ACTIVE_LOW
+				 &led_7seg_gpio 6 GPIO_ACTIVE_LOW>;
+	};
 };
 
 &pciec {
@@ -149,7 +160,7 @@ i2c at 3 {
 			#size-cells = <0>;
 			reg = <3>;
 
-			gpio at 20 {
+			led_7seg_gpio: gpio at 20 {
 				compatible = "nxp,pca9554";
 				gpio-controller;
 				#gpio-cells = <2>;
-- 
2.43.2



From chris.packham at alliedtelesis.co.nz  Sun Feb 25 13:34:22 2024
From: chris.packham at alliedtelesis.co.nz (Chris Packham)
Date: Mon, 26 Feb 2024 10:34:22 +1300
Subject: [PATCH 2/3] dt-bindings: auxdisplay: Add bindings for generic 7 segment LED
In-Reply-To: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz>
References: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz>
Message-ID: <20240225213423.690561-3-chris.packham@alliedtelesis.co.nz>

Add bindings for a generic 7 segment LED display using GPIOs.

Signed-off-by: Chris Packham <chris.packham at alliedtelesis.co.nz>
---
 .../auxdisplay/generic,gpio-7seg.yaml         | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/auxdisplay/generic,gpio-7seg.yaml

diff --git a/Documentation/devicetree/bindings/auxdisplay/generic,gpio-7seg.yaml b/Documentation/devicetree/bindings/auxdisplay/generic,gpio-7seg.yaml
new file mode 100644
index 000000000000..238da2ede740
--- /dev/null
+++ b/Documentation/devicetree/bindings/auxdisplay/generic,gpio-7seg.yaml
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/auxdisplay/generic,gpio-7seg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GPIO based LED segment display
+
+maintainers:
+  - Chris Packham <chris.packham at alliedtelesis.co.nz>
+
+properties:
+  compatible:
+    const: generic,gpio-7seg
+
+  segment-gpios:
+    description:
+      An array of GPIOs one per segment.
+    minItems: 7
+
+required:
+  - segment-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+
+    #include <dt-bindings/gpio/gpio.h>
+
+    led-7seg {
+        compatible = "generic,gpio-7seg";
+        segment-gpios = <&gpio 0 GPIO_ACTIVE_LOW
+                         &gpio 1 GPIO_ACTIVE_LOW
+                         &gpio 2 GPIO_ACTIVE_LOW
+                         &gpio 3 GPIO_ACTIVE_LOW
+                         &gpio 4 GPIO_ACTIVE_LOW
+                         &gpio 5 GPIO_ACTIVE_LOW
+                         &gpio 6 GPIO_ACTIVE_LOW>;
+    };
-- 
2.43.2



From chris.packham at alliedtelesis.co.nz  Sun Feb 25 13:34:20 2024
From: chris.packham at alliedtelesis.co.nz (Chris Packham)
Date: Mon, 26 Feb 2024 10:34:20 +1300
Subject: [PATCH 0/3] auxdisplay: 7 segment LED display
Message-ID: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz>

This series adds a driver for a 7 segment LED display.

I'd like to get some feedback on how this could be extended to support >1
character. The driver as presented is sufficient for my hardware which only has
a single character display but I can see that for this to be generically useful
supporting more characters would be desireable.

Earlier I posted an idea that the characters could be represended by
sub-nodes[1] but there doesn't seem to be a way of having that and keeping the
convenience of using devm_gpiod_get_array() (unless I've missed something).

[1] - https://lore.kernel.org/lkml/2a8d19ee-b18b-4b7c-869f-7d601cea30b6 at alliedtelesis.co.nz/

Chris Packham (3):
  auxdisplay: Add 7 segment LED display driver
  dt-bindings: auxdisplay: Add bindings for generic 7 segment LED
  ARM: dts: marvell: Add 7 segment LED display on x530

 .../auxdisplay/generic,gpio-7seg.yaml         |  40 +++++
 .../boot/dts/marvell/armada-385-atl-x530.dts  |  13 +-
 drivers/auxdisplay/Kconfig                    |   7 +
 drivers/auxdisplay/Makefile                   |   1 +
 drivers/auxdisplay/seg-led.c                  | 152 ++++++++++++++++++
 5 files changed, 212 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/auxdisplay/generic,gpio-7seg.yaml
 create mode 100644 drivers/auxdisplay/seg-led.c

-- 
2.43.2



From chris.packham at alliedtelesis.co.nz  Sun Feb 25 13:34:21 2024
From: chris.packham at alliedtelesis.co.nz (Chris Packham)
Date: Mon, 26 Feb 2024 10:34:21 +1300
Subject: [PATCH 1/3] auxdisplay: Add 7 segment LED display driver
In-Reply-To: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz>
References: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz>
Message-ID: <20240225213423.690561-2-chris.packham@alliedtelesis.co.nz>

Add a driver for a 7 segment LED display. At the moment only one
character is supported but it should be possible to expand this to
support more characters and/or 14 segment displays in the future.

Signed-off-by: Chris Packham <chris.packham at alliedtelesis.co.nz>
---
 drivers/auxdisplay/Kconfig   |   7 ++
 drivers/auxdisplay/Makefile  |   1 +
 drivers/auxdisplay/seg-led.c | 152 +++++++++++++++++++++++++++++++++++
 3 files changed, 160 insertions(+)
 create mode 100644 drivers/auxdisplay/seg-led.c

diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
index d944d5298eca..e826b5b15881 100644
--- a/drivers/auxdisplay/Kconfig
+++ b/drivers/auxdisplay/Kconfig
@@ -197,6 +197,13 @@ config ARM_CHARLCD
 	  line and the Linux version on the second line, but that's
 	  still useful.
 
+config SEG_LED
+	bool "Generic 7 segment LED display"
+	select LINEDISP
+	help
+	  This driver supports a generic 7 segment LED display made up
+	  of GPIO pins connected to the individual segments.
+
 menuconfig PARPORT_PANEL
 	tristate "Parallel port LCD/Keypad Panel support"
 	depends on PARPORT
diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile
index 6968ed4d3f0a..808fdf156bd5 100644
--- a/drivers/auxdisplay/Makefile
+++ b/drivers/auxdisplay/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_HT16K33)		+= ht16k33.o
 obj-$(CONFIG_PARPORT_PANEL)	+= panel.o
 obj-$(CONFIG_LCD2S)		+= lcd2s.o
 obj-$(CONFIG_LINEDISP)		+= line-display.o
+obj-$(CONFIG_SEG_LED)		+= seg-led.o
diff --git a/drivers/auxdisplay/seg-led.c b/drivers/auxdisplay/seg-led.c
new file mode 100644
index 000000000000..c0b302a09cbb
--- /dev/null
+++ b/drivers/auxdisplay/seg-led.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for a 7 segment LED display
+ *
+ * The GPIOs are wired to the 7 segments in a clock wise fashion starting from
+ * the top.
+ *
+ *      -a-
+ *     |   |
+ *     f   b
+ *     |   |
+ *      -g-
+ *     |   |
+ *     e   c
+ *     |   |
+ *      -d-
+ *
+ * The decimal point LED presnet on some devices is currently not
+ * supported.
+ *
+ * Copyright (C) Allied Telesis Labs
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
+#include <linux/map_to_7segment.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "line-display.h"
+
+struct seg_led_priv {
+	struct gpio_descs *segment_gpios;
+	struct delayed_work work;
+	struct linedisp linedisp;
+	struct seg7_conversion_map seg7;
+	unsigned int map_size;
+	size_t num_char;
+	char curr[];
+};
+
+static const SEG7_DEFAULT_MAP(initial_map_seg7);
+
+static ssize_t map_seg7_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct seg_led_priv *priv = dev_get_drvdata(dev);
+
+	memcpy(buf, &priv->seg7, priv->map_size);
+	return priv->map_size;
+}
+
+static ssize_t map_seg7_store(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t cnt)
+{
+	struct seg_led_priv *priv = dev_get_drvdata(dev);
+
+	if (cnt != priv->map_size)
+		return -EINVAL;
+
+	memcpy(&priv->seg7, buf, cnt);
+	return cnt;
+}
+
+static DEVICE_ATTR_RW(map_seg7);
+
+static void seg_led_linedisp_update(struct linedisp *linedisp)
+{
+	struct seg_led_priv *priv = container_of(linedisp, struct seg_led_priv, linedisp);
+
+	schedule_delayed_work(&priv->work, 0);
+}
+
+static void seg_led_update(struct work_struct *work)
+{
+	struct seg_led_priv *priv = container_of(work, struct seg_led_priv, work.work);
+	DECLARE_BITMAP(values, 8);
+
+	values[0] = map_to_seg7(&priv->seg7, priv->curr[0]);
+
+	gpiod_set_array_value_cansleep(priv->segment_gpios->ndescs, priv->segment_gpios->desc,
+				       priv->segment_gpios->info, values);
+}
+
+static const struct of_device_id seg_led_of_match[] = {
+	{ .compatible = "generic,gpio-7seg"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, seg_led_of_match);
+
+static int seg_led_probe(struct platform_device *pdev)
+{
+	struct seg_led_priv *priv;
+	int err;
+
+	priv = devm_kzalloc(&pdev->dev, struct_size(priv, curr, 1), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	priv->num_char = 1;
+
+	platform_set_drvdata(pdev, priv);
+
+	priv->segment_gpios = devm_gpiod_get_array(&pdev->dev, "segment", GPIOD_OUT_LOW);
+	if (IS_ERR(priv->segment_gpios))
+		return PTR_ERR(priv->segment_gpios);
+
+	priv->seg7 = initial_map_seg7;
+	priv->map_size = sizeof(priv->seg7);
+
+	err = device_create_file(&pdev->dev, &dev_attr_map_seg7);
+	if (err)
+		return err;
+
+	INIT_DELAYED_WORK(&priv->work, seg_led_update);
+
+	err = linedisp_register(&priv->linedisp, &pdev->dev, 1, priv->curr,
+				seg_led_linedisp_update);
+	if (err) {
+		device_remove_file(&pdev->dev, &dev_attr_map_seg7);
+		return err;
+	}
+
+	return 0;
+}
+
+static int seg_led_remove(struct platform_device *pdev)
+{
+	struct seg_led_priv *priv = platform_get_drvdata(pdev);
+
+	cancel_delayed_work_sync(&priv->work);
+	linedisp_unregister(&priv->linedisp);
+	device_remove_file(&pdev->dev, &dev_attr_map_seg7);
+
+	return 0;
+}
+
+static struct platform_driver seg_led_driver = {
+	.probe = seg_led_probe,
+	.remove = seg_led_remove,
+	.driver = {
+		.name = "seg-led",
+		.of_match_table = seg_led_of_match,
+	},
+};
+
+module_platform_driver(seg_led_driver);
+
+MODULE_AUTHOR("Chris Packham <chris.packham at alliedtelesis.co.nz>");
+MODULE_DESCRIPTION("7 segment LED driver");
+MODULE_LICENSE("GPL");
+
-- 
2.43.2



From richard at sigma-star.at  Sun Feb 25 14:20:31 2024
From: richard at sigma-star.at (Richard Weinberger)
Date: Sun, 25 Feb 2024 23:20:31 +0100
Subject: [PATCH v5 0/6] DCP as trusted keys backend
In-Reply-To: <47439997.XUcTiDjVJD@somecomputer>
References: <20231215110639.45522-1-david@sigma-star.at> <7AED262F-9387-446D-B11A-C549C02542F9@sigma-star.at> <47439997.XUcTiDjVJD@somecomputer>
Message-ID: <1733761.uacIGzncQW@somecomputer>

Mimi, James, Jarkko, David,

you remained silent for a whole release cycle.
Is there anything we can do to get this forward?

Thanks,
//richard

Am Dienstag, 13. Februar 2024, 10:59:56 CET schrieb Richard Weinberger:
> Am Montag, 5. Februar 2024, 09:39:07 CET schrieb David Gstir:
> > Hi,
> > 
> > > On 15.12.2023, at 12:06, David Gstir <david at sigma-star.at> wrote:
> > > 
> > > This is a revival of the previous patch set submitted by Richard Weinberger:
> > > https://lore.kernel.org/linux-integrity/20210614201620.30451-1-richard at nod.at/
> > > 
> > > v4 is here:
> > > https://lore.kernel.org/keyrings/20231024162024.51260-1-david at sigma-star.at/
> > > 
> > > v4 -> v5:
> > > - Make Kconfig for trust source check scalable as suggested by Jarkko Sakkinen
> > > - Add Acked-By from Herbert Xu to patch #1 - thanks!
> > > v3 -> v4:
> > > - Split changes on MAINTAINERS and documentation into dedicated patches
> > > - Use more concise wording in commit messages as suggested by Jarkko Sakkinen
> > > v2 -> v3:
> > > - Addressed review comments from Jarkko Sakkinen
> > > v1 -> v2:
> > > - Revive and rebase to latest version
> > > - Include review comments from Ahmad Fatoum
> > > 
> > > The Data CoProcessor (DCP) is an IP core built into many NXP SoCs such
> > > as i.mx6ull.
> > > 
> > > Similar to the CAAM engine used in more powerful SoCs, DCP can AES-
> > > encrypt/decrypt user data using a unique, never-disclosed,
> > > device-specific key. Unlike CAAM though, it cannot directly wrap and
> > > unwrap blobs in hardware. As DCP offers only the bare minimum feature
> > > set and a blob mechanism needs aid from software. A blob in this case
> > > is a piece of sensitive data (e.g. a key) that is encrypted and
> > > authenticated using the device-specific key so that unwrapping can only
> > > be done on the hardware where the blob was wrapped.
> > > 
> > > This patch series adds a DCP based, trusted-key backend and is similar
> > > in spirit to the one by Ahmad Fatoum [0] that does the same for CAAM.
> > > It is of interest for similar use cases as the CAAM patch set, but for
> > > lower end devices, where CAAM is not available.
> > > 
> > > Because constructing and parsing the blob has to happen in software,
> > > we needed to decide on a blob format and chose the following:
> > > 
> > > struct dcp_blob_fmt {
> > > __u8 fmt_version;
> > > __u8 blob_key[AES_KEYSIZE_128];
> > > __u8 nonce[AES_KEYSIZE_128];
> > > __le32 payload_len;
> > > __u8 payload[];
> > > } __packed;
> > > 
> > > The `fmt_version` is currently 1.
> > > 
> > > The encrypted key is stored in the payload area. It is AES-128-GCM
> > > encrypted using `blob_key` and `nonce`, GCM auth tag is attached at
> > > the end of the payload (`payload_len` does not include the size of
> > > the auth tag).
> > > 
> > > The `blob_key` itself is encrypted in AES-128-ECB mode by DCP using
> > > the OTP or UNIQUE device key. A new `blob_key` and `nonce` are generated
> > > randomly, when sealing/exporting the DCP blob.
> > > 
> > > This patchset was tested with dm-crypt on an i.MX6ULL board.
> > > 
> > > [0] https://lore.kernel.org/keyrings/20220513145705.2080323-1-a.fatoum at pengutronix.de/
> > > 
> > > David Gstir (6):
> > >  crypto: mxs-dcp: Add support for hardware-bound keys
> > >  KEYS: trusted: improve scalability of trust source config
> > >  KEYS: trusted: Introduce NXP DCP-backed trusted keys
> > >  MAINTAINERS: add entry for DCP-based trusted keys
> > >  docs: document DCP-backed trusted keys kernel params
> > >  docs: trusted-encrypted: add DCP as new trust source
> > > 
> > > .../admin-guide/kernel-parameters.txt         |  13 +
> > > .../security/keys/trusted-encrypted.rst       |  85 +++++
> > > MAINTAINERS                                   |   9 +
> > > drivers/crypto/mxs-dcp.c                      | 104 +++++-
> > > include/keys/trusted_dcp.h                    |  11 +
> > > include/soc/fsl/dcp.h                         |  17 +
> > > security/keys/trusted-keys/Kconfig            |  18 +-
> > > security/keys/trusted-keys/Makefile           |   2 +
> > > security/keys/trusted-keys/trusted_core.c     |   6 +-
> > > security/keys/trusted-keys/trusted_dcp.c      | 311 ++++++++++++++++++
> > > 10 files changed, 562 insertions(+), 14 deletions(-)
> > > create mode 100644 include/keys/trusted_dcp.h
> > > create mode 100644 include/soc/fsl/dcp.h
> > > create mode 100644 security/keys/trusted-keys/trusted_dcp.c
> > 
> > Jarkko, Mimi, David do you need anything from my side for these patches to get them merged?
> 
> Friendly ping also from my side. :-)
> 
> Thanks,
> //richard
> 
> -- 
> ?????sigma star gmbh | Eduard-Bodem-Gasse 6, 6020 Innsbruck, AUT
> UID/VAT Nr: ATU 66964118 | FN: 374287y
> 


-- 
?????sigma star gmbh | Eduard-Bodem-Gasse 6, 6020 Innsbruck, AUT
UID/VAT Nr: ATU 66964118 | FN: 374287y




From andreas at kemnade.info  Sun Feb 25 14:56:22 2024
From: andreas at kemnade.info (Andreas Kemnade)
Date: Sun, 25 Feb 2024 23:56:22 +0100
Subject: [PATCH] ARM: dts: imx6sl: tolino-shine2hd: fix IRQ config of touchscreen
Message-ID: <20240225225622.3419104-1-andreas@kemnade.info>

Correctly describe the interrupt as level low. Driver enforces that
anyways, but do not rely on that in the devicetree.

Suggested-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>
Signed-off-by: Andreas Kemnade <andreas at kemnade.info>
---
 arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
index 815119c12bd48..922749bf11bc1 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
@@ -138,7 +138,7 @@ zforce: touchscreen at 50 {
 		pinctrl-0 = <&pinctrl_zforce>;
 		reg = <0x50>;
 		interrupt-parent = <&gpio5>;
-		interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
 		vdd-supply = <&ldo1_reg>;
 		reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
 		x-size = <1072>;
-- 
2.39.2



From andreas at kemnade.info  Sun Feb 25 14:57:20 2024
From: andreas at kemnade.info (Andreas Kemnade)
Date: Sun, 25 Feb 2024 23:57:20 +0100
Subject: [PATCH] ARM: dts: imx6: fix IRQ config of RC5T619
Message-ID: <20240225225720.3419129-1-andreas@kemnade.info>

Set interrupt type to level low to correctly describe the hardware and
do not rely on the driver to do the right thing.

Signed-off-by: Andreas Kemnade <andreas at kemnade.info>
---
 arch/arm/boot/dts/nxp/imx/e60k02.dtsi                | 2 +-
 arch/arm/boot/dts/nxp/imx/e70k02.dtsi                | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/nxp/imx/e60k02.dtsi b/arch/arm/boot/dts/nxp/imx/e60k02.dtsi
index dd03e3860f97f..13756d39fb7b9 100644
--- a/arch/arm/boot/dts/nxp/imx/e60k02.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/e60k02.dtsi
@@ -127,7 +127,7 @@ ricoh619: pmic at 32 {
 		compatible = "ricoh,rc5t619";
 		reg = <0x32>;
 		interrupt-parent = <&gpio5>;
-		interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
 		system-power-controller;
 
 		regulators {
diff --git a/arch/arm/boot/dts/nxp/imx/e70k02.dtsi b/arch/arm/boot/dts/nxp/imx/e70k02.dtsi
index 4e1bf080eaca0..dcc3c9d488a88 100644
--- a/arch/arm/boot/dts/nxp/imx/e70k02.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/e70k02.dtsi
@@ -145,7 +145,7 @@ ricoh619: pmic at 32 {
 		compatible = "ricoh,rc5t619";
 		reg = <0x32>;
 		interrupt-parent = <&gpio4>;
-		interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
 		system-power-controller;
 
 		regulators {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
index 922749bf11bc1..04027627fe62b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
@@ -161,7 +161,7 @@ ricoh619: pmic at 32 {
 		pinctrl-0 = <&pinctrl_ricoh_gpio>;
 		reg = <0x32>;
 		interrupt-parent = <&gpio5>;
-		interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
 		system-power-controller;
 
 		regulators {
-- 
2.39.2



From chentao at kylinos.cn  Sun Feb 25 18:22:51 2024
From: chentao at kylinos.cn (Kunwu Chan)
Date: Mon, 26 Feb 2024 10:22:51 +0800
Subject: [PATCH] drm/exynos: use KMEM_CACHE() to create g2d_runqueue_node cache
Message-ID: <20240226022251.1781070-1-chentao@kylinos.cn>

Use the KMEM_CACHE() macro instead of kmem_cache_create() to simplify
the creation of SLAB caches when the default values are used.

Signed-off-by: Kunwu Chan <chentao at kylinos.cn>
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index f3138423612e..a5818ed6a6f7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -1456,8 +1456,7 @@ static int g2d_probe(struct platform_device *pdev)
 	if (!g2d)
 		return -ENOMEM;
 
-	g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",
-			sizeof(struct g2d_runqueue_node), 0, 0, NULL);
+	g2d->runqueue_slab = KMEM_CACHE(g2d_runqueue_node, 0);
 	if (!g2d->runqueue_slab)
 		return -ENOMEM;
 
-- 
2.39.2



From andy.shevchenko at gmail.com  Sun Feb 25 18:23:15 2024
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Mon, 26 Feb 2024 04:23:15 +0200
Subject: [PATCH 0/3] auxdisplay: 7 segment LED display
In-Reply-To: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz>
References: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz>
Message-ID: <CAHp75Vc9OBtxdKSmk9Uu9G3j+mfN8+9prTEVx3LyUcdBYFEqwg@mail.gmail.com>

On Sun, Feb 25, 2024 at 11:34?PM Chris Packham
<chris.packham at alliedtelesis.co.nz> wrote:
>
> This series adds a driver for a 7 segment LED display.
>
> I'd like to get some feedback on how this could be extended to support >1
> character. The driver as presented is sufficient for my hardware which only has
> a single character display but I can see that for this to be generically useful
> supporting more characters would be desireable.
>
> Earlier I posted an idea that the characters could be represended by
> sub-nodes[1] but there doesn't seem to be a way of having that and keeping the
> convenience of using devm_gpiod_get_array() (unless I've missed something).

It seems you didn't know that the tree for auxdisplay has been changed.
Can you rebase your stuff on top of
https://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-auxdisplay.git/log/?h=for-next?
It will reduce your code base by ~50%.

WRT subnodes, you can go with device_for_each_child_node() and
retrieve gpio array per digit. It means you will have an array of
arrays of GPIOs.

> [1] - https://lore.kernel.org/lkml/2a8d19ee-b18b-4b7c-869f-7d601cea30b6 at alliedtelesis.co.nz/



-- 
With Best Regards,
Andy Shevchenko


From andy.shevchenko at gmail.com  Sun Feb 25 18:32:06 2024
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Mon, 26 Feb 2024 04:32:06 +0200
Subject: [PATCH 1/3] auxdisplay: Add 7 segment LED display driver
In-Reply-To: <20240225213423.690561-2-chris.packham@alliedtelesis.co.nz>
References: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz> <20240225213423.690561-2-chris.packham@alliedtelesis.co.nz>
Message-ID: <CAHp75Vcntz68xdr20JuXpHjM6vog=FZm2qGYPxOTRsFhmVe32Q@mail.gmail.com>

On Sun, Feb 25, 2024 at 11:34?PM Chris Packham
<chris.packham at alliedtelesis.co.nz> wrote:
>
> Add a driver for a 7 segment LED display. At the moment only one
> character is supported but it should be possible to expand this to
> support more characters and/or 14 segment displays in the future.

(I try to comment only on the things that will remain after rebasing
on top of auxdisplay:for-next)

...

> +config SEG_LED
> +       bool "Generic 7 segment LED display"

Why can't it be a module?

> +       select LINEDISP
> +       help
> +         This driver supports a generic 7 segment LED display made up
> +         of GPIO pins connected to the individual segments.

Checkpatch wants 3+ lines of help, I would add the module name (after
changing it to be tristate, etc).

...

> + * The GPIOs are wired to the 7 segments in a clock wise fashion starting from

clockwise

> + * the top.

...

> + * The decimal point LED presnet on some devices is currently not

present

> + * supported.

...

> +#include <linux/gpio/consumer.h>
> +#include <linux/kernel.h>
> +#include <linux/map_to_7segment.h>
> +#include <linux/module.h>

> +#include <linux/of.h>

This is not used. And actually shouldn't be in a new code like this
with rare exceptions.

> +#include <linux/platform_device.h>

This is rather semirandom, please use IWYU (Include What You Use)
principle. We have, among others, container_of.h, types.h, err.h,
bitmap.h, mod_devicetable.h.

...

With

    sturct device *dev = &pdev->dev;

the below code will be neater.

> +       priv = devm_kzalloc(&pdev->dev, struct_size(priv, curr, 1), GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +       priv->num_char = 1;
> +
> +       platform_set_drvdata(pdev, priv);
> +
> +       priv->segment_gpios = devm_gpiod_get_array(&pdev->dev, "segment", GPIOD_OUT_LOW);
> +       if (IS_ERR(priv->segment_gpios))
> +               return PTR_ERR(priv->segment_gpios);

...

> +static struct platform_driver seg_led_driver = {
> +       .probe = seg_led_probe,
> +       .remove = seg_led_remove,
> +       .driver = {
> +               .name = "seg-led",
> +               .of_match_table = seg_led_of_match,
> +       },
> +};

> +

Redundant blank line.

> +module_platform_driver(seg_led_driver);
> +
> +MODULE_AUTHOR("Chris Packham <chris.packham at alliedtelesis.co.nz>");
> +MODULE_DESCRIPTION("7 segment LED driver");
> +MODULE_LICENSE("GPL");

> +

Seems like a redundant blank line at the end of the file.

-- 
With Best Regards,
Andy Shevchenko


From rdunlap at infradead.org  Sun Feb 25 18:49:50 2024
From: rdunlap at infradead.org (Randy Dunlap)
Date: Sun, 25 Feb 2024 18:49:50 -0800
Subject: [PATCH 1/3] auxdisplay: Add 7 segment LED display driver
In-Reply-To: <20240225213423.690561-2-chris.packham@alliedtelesis.co.nz>
References: <20240225213423.690561-1-chris.packham@alliedtelesis.co.nz>
 <20240225213423.690561-2-chris.packham@alliedtelesis.co.nz>
Message-ID: <7ef941f5-fd2f-4893-81e1-94f5aabf6ac3@infradead.org>

Hi--

On 2/25/24 13:34, Chris Packham wrote:
> Add a driver for a 7 segment LED display. At the moment only one
> character is supported but it should be possible to expand this to
> support more characters and/or 14 segment displays in the future.
> 
> Signed-off-by: Chris Packham <chris.packham at alliedtelesis.co.nz>
> ---
>  drivers/auxdisplay/Kconfig   |   7 ++
>  drivers/auxdisplay/Makefile  |   1 +
>  drivers/auxdisplay/seg-led.c | 152 +++++++++++++++++++++++++++++++++++
>  3 files changed, 160 insertions(+)
>  create mode 100644 drivers/auxdisplay/seg-led.c
> 
> diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
> index d944d5298eca..e826b5b15881 100644
> --- a/drivers/auxdisplay/Kconfig
> +++ b/drivers/auxdisplay/Kconfig
> @@ -197,6 +197,13 @@ config ARM_CHARLCD
>  	  line and the Linux version on the second line, but that's
>  	  still useful.
>  
> +config SEG_LED
> +	bool "Generic 7 segment LED display"
> +	select LINEDISP
> +	help
> +	  This driver supports a generic 7 segment LED display made up

	                                 7-segment

> +	  of GPIO pins connected to the individual segments.
> +
>  menuconfig PARPORT_PANEL
>  	tristate "Parallel port LCD/Keypad Panel support"
>  	depends on PARPORT
> diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile
> index 6968ed4d3f0a..808fdf156bd5 100644
> --- a/drivers/auxdisplay/Makefile
> +++ b/drivers/auxdisplay/Makefile
> @@ -14,3 +14,4 @@ obj-$(CONFIG_HT16K33)		+= ht16k33.o
>  obj-$(CONFIG_PARPORT_PANEL)	+= panel.o
>  obj-$(CONFIG_LCD2S)		+= lcd2s.o
>  obj-$(CONFIG_LINEDISP)		+= line-display.o
> +obj-$(CONFIG_SEG_LED)		+= seg-led.o
> diff --git a/drivers/auxdisplay/seg-led.c b/drivers/auxdisplay/seg-led.c
> new file mode 100644
> index 000000000000..c0b302a09cbb
> --- /dev/null
> +++ b/drivers/auxdisplay/seg-led.c
> @@ -0,0 +1,152 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for a 7 segment LED display
> + *
> + * The GPIOs are wired to the 7 segments in a clock wise fashion starting from
> + * the top.
> + *
> + *      -a-
> + *     |   |
> + *     f   b
> + *     |   |
> + *      -g-
> + *     |   |
> + *     e   c
> + *     |   |
> + *      -d-
> + *
> + * The decimal point LED presnet on some devices is currently not

                            present

> + * supported.
> + *
> + * Copyright (C) Allied Telesis Labs
> + */

-- 
#Randy


From anshuman.khandual at arm.com  Sun Feb 25 18:49:39 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 26 Feb 2024 08:19:39 +0530
Subject: [PATCH] arm64/hw_breakpoint: Determine lengths from generic perf
 breakpoint macros
In-Reply-To: <20240223125224.GC10641@willie-the-truck>
References: <20240223113102.4027779-1-anshuman.khandual@arm.com>
 <20240223125224.GC10641@willie-the-truck>
Message-ID: <1901fadb-1d71-4374-be8c-00935bb27854@arm.com>



On 2/23/24 18:22, Will Deacon wrote:
> On Fri, Feb 23, 2024 at 05:01:02PM +0530, Anshuman Khandual wrote:
>> Both platform i.e ARM_BREAKPOINT_LEN_X and generic i.e HW_BREAKPOINT_LEN_X
>> macros are used interchangeably to convert event->attr.bp_len and platform
>> breakpoint control arch_hw_breakpoint_ctrl->len. Let's be consistent while
>> deriving one from the other. This does not cause any functional changes.
>>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: Catalin Marinas <catalin.marinas 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 v6.8-rc5
>>
>>  arch/arm64/kernel/hw_breakpoint.c | 16 ++++++++--------
>>  1 file changed, 8 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
>> index 35225632d70a..1ab9fc865ddd 100644
>> --- a/arch/arm64/kernel/hw_breakpoint.c
>> +++ b/arch/arm64/kernel/hw_breakpoint.c
>> @@ -301,28 +301,28 @@ static int get_hbp_len(u8 hbp_len)
>>  
>>  	switch (hbp_len) {
>>  	case ARM_BREAKPOINT_LEN_1:
>> -		len_in_bytes = 1;
>> +		len_in_bytes = HW_BREAKPOINT_LEN_1;
> 
> I don't think we should do this. The HW_BREAKPOINT_LEN_* definitions are
> part of the user ABI and, although they correspond to the length in bytes,
> that's not necessarily something we should rely on.

Why should not we rely on the user ABI macros if these byte lengths were
initially derived from them. But also there are similar conversions in
arch_bp_generic_fields(). These hard coded raw byte length numbers seems
cryptic, where as in reality these are just inter converted from generic
HW breakpoints lengths.


From oliver.sang at intel.com  Sun Feb 25 18:51:07 2024
From: oliver.sang at intel.com (kernel test robot)
Date: Mon, 26 Feb 2024 10:51:07 +0800
Subject: [linux-next:master] [wifi]  0a44dfc070: hwsim.ap_vht80_csa.fail
Message-ID: <202402261039.708d78d3-oliver.sang@intel.com>



Hello,

kernel test robot noticed "hwsim.ap_vht80_csa.fail" on:

commit: 0a44dfc070749514b804ccac0b1fd38718f7daa1 ("wifi: mac80211: simplify non-chanctx drivers")
https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git master

[test failed on linux-next/master d37e1e4c52bc60578969f391fb81f947c3e83118]

in testcase: hwsim
version: hwsim-x86_64-717e5d7-1_20231228
with following parameters:

	test: ap_vht80_csa



compiler: gcc-12
test machine: 8 threads 1 sockets Intel(R) Core(TM) i7-4790 v3 @ 3.60GHz (Haswell) with 6G memory

(please refer to attached dmesg/kmsg for entire log/backtrace)




If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang at intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202402261039.708d78d3-oliver.sang at intel.com

group: group-33, test: ap_vht80_csa
2024-02-18 10:47:21 export USER=root
2024-02-18 10:47:21 ./build.sh
Building TNC testing tools
Building wlantest
Building hs20-osu-client
Building hostapd
Building wpa_supplicant
2024-02-18 10:48:15 ./start.sh
2024-02-18 10:48:17 ./run-tests.py ap_vht80_csa
DEV: wlan0: 02:00:00:00:00:00
DEV: wlan1: 02:00:00:00:01:00
DEV: wlan2: 02:00:00:00:02:00
APDEV: wlan3
APDEV: wlan4
START ap_vht80_csa 1/1
Test: VHT with 80 MHz channel width and CSA
Starting AP wlan3
Connect STA wlan0 to AP
Country code at the end: 00
sending data without carrier won't work
Traceback (most recent call last):
  File "/lkp/benchmarks/hwsim/tests/hwsim/./run-tests.py", line 537, in main
    t(dev, apdev)
  File "/lkp/benchmarks/hwsim/tests/hwsim/test_ap_vht.py", line 805, in test_ap_vht80_csa
    hwsim_utils.test_connectivity(dev[0], hapd)
  File "/lkp/benchmarks/hwsim/tests/hwsim/hwsim_utils.py", line 217, in test_connectivity
    raise Exception(last_err)
Exception: sending data without carrier won't work
FAIL ap_vht80_csa 4.501333 2024-02-18 10:48:23.019458
passed 0 test case(s)
skipped 0 test case(s)
failed tests: ap_vht80_csa
2024-02-18 10:48:23 ./stop.sh



The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20240226/202402261039.708d78d3-oliver.sang at intel.com



-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki



From shengjiu.wang at gmail.com  Sun Feb 25 19:06:48 2024
From: shengjiu.wang at gmail.com (Shengjiu Wang)
Date: Mon, 26 Feb 2024 11:06:48 +0800
Subject: [PATCH 1/2] arm64: dts: imx8mp-evk: Add HDMI audio sound card support
In-Reply-To: <1786327.VLH7GnMWUR@steina-w>
References: <1708675339-8180-1-git-send-email-shengjiu.wang@nxp.com> <1786327.VLH7GnMWUR@steina-w>
Message-ID: <CAA+D8AMU69B1Bf3tbbvtkJz_pYY0VNaQMhBXxZvDYug=_DHxYg@mail.gmail.com>

On Fri, Feb 23, 2024 at 5:06?PM Alexander Stein
<alexander.stein at ew.tq-group.com> wrote:
>
> Hi,
>
> thanks for the patch.
>
> Am Freitag, 23. Februar 2024, 09:02:18 CET schrieb Shengjiu Wang:
> > The AUD2HTX is a digital module that provides a bridge between
> > the Audio Subsystem and the HDMI RTX Subsystem. This
> > module includes intermediate storage to queue SDMA transactions
> > prior to being synchronized and passed to the HDMI
> > RTX Subsystem over the Audio Link.
> >
> > AUD2HTX works as the cpu dai in HDMI audio sound card.
> >
> > Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
> > ---
> >  arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 12 ++++++++++++
> >  arch/arm64/boot/dts/freescale/imx8mp.dtsi    | 10 ++++++++++
> >  2 files changed, 22 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> > index f87fa5a948cc..63f6e72fa18a 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> > +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> > @@ -138,6 +138,14 @@ simple-audio-card,codec {
> >
> >       };
> >
> > +     sound-hdmi {
> > +             compatible = "fsl,imx-audio-hdmi";
> > +             model = "audio-hdmi";
> > +             audio-cpu = <&aud2htx>;
> > +             hdmi-out;
> > +             status = "okay";
>
> No need for 'status' here.

ok, will remove it.

>
> Don't you need to configure the PAI as well? See [1]
> for downstream implementation. I'm wondering because I had to hack something
> similar. Without I got no HDMI audio.

Yes, the PAI part is needed.
But this commit is just for sound card dts update.

Best regards
Wang shengjiu

>
> Best regards,
> Alexander
>
> [1] https://github.com/Freescale/linux-fslc/blob/6.1-2.0.x-imx/drivers/gpu/drm/imx/imx8mp-hdmi-pavi.c#L51-L59
>
> > +     };
> > +
> >       reserved-memory {
> >               #address-cells = <2>;
> >               #size-cells = <2>;
> > @@ -191,6 +199,10 @@ &A53_3 {
> >       cpu-supply = <&reg_arm>;
> >  };
> >
> > +&aud2htx {
> > +     status = "okay";
> > +};
> > +
> >  &eqos {
> >       pinctrl-names = "default";
> >       pinctrl-0 = <&pinctrl_eqos>;
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > index 9ab9c057f41e..721ab630d895 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > @@ -1513,6 +1513,16 @@ micfil: audio-controller at 30ca0000 {
> >                                       status = "disabled";
> >                               };
> >
> > +                             aud2htx: aud2htx at 30cb0000 {
> > +                                     compatible = "fsl,imx8mp-aud2htx";
> > +                                     reg = <0x30cb0000 0x10000>;
> > +                                     interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
> > +                                     clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG>;
> > +                                     clock-names = "bus";
> > +                                     dmas = <&sdma2 26 2 0>;
> > +                                     dma-names = "tx";
> > +                                     status = "disabled";
> > +                             };
> >                       };
> >
> >                       sdma3: dma-controller at 30e00000 {
> >
>
>
> --
> TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht M?nchen, HRB 105018
> Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> http://www.tq-group.com/
>
>


From andrew at codeconstruct.com.au  Sun Feb 25 19:19:51 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Mon, 26 Feb 2024 13:49:51 +1030
Subject: [PATCH v2] dt-bindings: gpio: aspeed,ast2400-gpio: Convert to DT schema
Message-ID: <20240226031951.284847-1-andrew@codeconstruct.com.au>

Squash warnings such as:

```
arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-galaxy100.dtb: /ahb/apb at 1e600000/gpio at 1e780000: failed to match any schema with compatible: ['aspeed,ast2400-gpio']
```

Signed-off-by: Andrew Jeffery <andrew at codeconstruct.com.au>
---
v2: Address feedback from Krzysztof:
    https://lore.kernel.org/all/0d1dd262-b6dd-4d71-9239-8b0aec8cceff at linaro.org/

v1: https://lore.kernel.org/all/20240220052918.742793-1-andrew at codeconstruct.com.au/

 .../bindings/gpio/aspeed,ast2400-gpio.yaml    | 73 +++++++++++++++++++
 .../devicetree/bindings/gpio/gpio-aspeed.txt  | 39 ----------
 2 files changed, 73 insertions(+), 39 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
 delete mode 100644 Documentation/devicetree/bindings/gpio/gpio-aspeed.txt

diff --git a/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
new file mode 100644
index 000000000000..74d376567dfc
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/aspeed,ast2400-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Aspeed GPIO controller
+
+maintainers:
+  - Andrew Jeffery <andrew at codeconstruct.com.au>
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2400-gpio
+      - aspeed,ast2500-gpio
+      - aspeed,ast2600-gpio
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: The clock to use for debounce timings
+
+  "#gpio-cells":
+    const: 2
+
+  gpio-controller: true
+  gpio-line-names: true
+  gpio-ranges: true
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+  ngpios: true
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-controller
+  - "#interrupt-cells"
+  - "#gpio-cells"
+  - gpio-controller
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: aspeed,ast2600-gpio
+    then:
+      required:
+        - ngpios
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio at 1e780000 {
+        compatible = "aspeed,ast2400-gpio";
+        reg = <0x1e780000 0x1000>;
+        interrupts = <20>;
+        interrupt-controller;
+        #gpio-cells = <2>;
+        gpio-controller;
+    };
diff --git a/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt b/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt
deleted file mode 100644
index b2033fc3a71a..000000000000
--- a/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-Aspeed GPIO controller Device Tree Bindings
--------------------------------------------
-
-Required properties:
-- compatible		: Either "aspeed,ast2400-gpio", "aspeed,ast2500-gpio",
-					or "aspeed,ast2600-gpio".
-
-- #gpio-cells 		: Should be two
-			  - First cell is the GPIO line number
-			  - Second cell is used to specify optional
-			    parameters (unused)
-
-- reg			: Address and length of the register set for the device
-- gpio-controller	: Marks the device node as a GPIO controller.
-- interrupts		: Interrupt specifier (see interrupt bindings for
-			  details)
-- interrupt-controller	: Mark the GPIO controller as an interrupt-controller
-
-Optional properties:
-
-- clocks		: A phandle to the clock to use for debounce timings
-- ngpios		: Number of GPIOs controlled by this controller. Should	be set
-				  when there are multiple GPIO controllers on a SoC (ast2600).
-
-The gpio and interrupt properties are further described in their respective
-bindings documentation:
-
-- Documentation/devicetree/bindings/gpio/gpio.txt
-- Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
-
-  Example:
-	gpio at 1e780000 {
-		#gpio-cells = <2>;
-		compatible = "aspeed,ast2400-gpio";
-		gpio-controller;
-		interrupts = <20>;
-		reg = <0x1e780000 0x1000>;
-		interrupt-controller;
-	};
-- 
2.39.2



From xu.yang_2 at nxp.com  Sun Feb 25 19:30:16 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Mon, 26 Feb 2024 03:30:16 +0000
Subject: [EXT] Re: [PATCH v6 4/9] dt-bindings: usb: add NXP ChipIdea USB2
 Controller schema
In-Reply-To: <6c5c0233-dab8-4bd1-9f08-0b609d01defd@linaro.org>
References: <20240221145846.1611627-1-xu.yang_2@nxp.com>
 <20240221145846.1611627-4-xu.yang_2@nxp.com>
 <20240223140256.GA1768266-robh@kernel.org>
 <DU2PR04MB882234D1A9D5718D8355928B8C552@DU2PR04MB8822.eurprd04.prod.outlook.com>
 <6c5c0233-dab8-4bd1-9f08-0b609d01defd@linaro.org>
Message-ID: <DU2PR04MB8822BF43FA0CF416EB72F19A8C5A2@DU2PR04MB8822.eurprd04.prod.outlook.com>


> 
> On 23/02/2024 15:56, Xu Yang wrote:
> > Hi Rob,
> >
> >>
> >> On Wed, Feb 21, 2024 at 10:58:41PM +0800, Xu Yang wrote:
> >>> As more and more NXP i.MX chips come out, it becomes harder to maintain
> >>> ci-hdrc-usb2.yaml if more stuffs like property restrictions are added to
> >>> this file. This will separate i.MX parts out of ci-hdrc-usb2.yaml and add
> >>> a new schema for NXP ChipIdea USB2 Controller.
> >>>
> >>> Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
> >>>
> >>> ---
> >>> Changes in v6:
> >>>  - new patch
> >>> ---
> >>>  .../bindings/usb/ci-hdrc-usb2-imx.yaml        | 75 +++++++++++++++++++
> >>>  1 file changed, 75 insertions(+)
> >>>  create mode 100644 Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
> b/Documentation/devicetree/bindings/usb/ci-
> >> hdrc-usb2-imx.yaml
> >>> new file mode 100644
> >>> index 000000000000..2ec62f564bf5
> >>> --- /dev/null
> >>> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2-imx.yaml
> >>> @@ -0,0 +1,75 @@
> >>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >>> +%YAML 1.2

[...]

> 
> > If I only create imx specific yaml file and remove all compatilbles from common
> 
> Why would you remove ALL of others? What is the point of this.

I originally thought ci-hdrc-usb2.yaml should be removed and only
ci-hdrc-usb2-comm.yaml is kept. So I'm not sure where other compatibles
should go. I looked though your Qualcomm PCI dt-bindings series and now
I know how to do.

Thanks,
Xu Yang



From shawnguo2 at yeah.net  Sun Feb 25 19:41:43 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 26 Feb 2024 11:41:43 +0800
Subject: [GIT PULL 2/5] i.MX dt-bindings for 6.9
In-Reply-To: <20240226034147.233993-1-shawnguo2@yeah.net>
References: <20240226034147.233993-1-shawnguo2@yeah.net>
Message-ID: <20240226034147.233993-2-shawnguo2@yeah.net>

From: Shawn Guo <shawnguo at kernel.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-bindings-6.9

for you to fetch changes up to 65524e1453109c2f94b361274154154fa2120c85:

  dt-bindings: arm: add UNI-T UTi260B (2024-02-25 21:57:10 +0800)

----------------------------------------------------------------
i.MX dt-bindings for 6.9:

- New compatibles for boards: TQMa8Xx, Sielaff i.MX6 Solo, Toradex Apalis
  imx6q-eval-v1.2, VAR-SOM-MX93, phyBOARD-Segin-i.MX93, UNI-T UTi260B.
- Add vendor prefix for UNI-T.

----------------------------------------------------------------
Alexander Stein (1):
      dt-bindings: arm: add TQMa8Xx boards

Frieder Schrempf (1):
      dt-bindings: arm: fsl: Add Sielaff i.MX6 Solo board

Hiago De Franco (1):
      dt-bindings: arm: fsl: Add toradex,apalis_imx6q-eval-v1.2 board

Hugo Villeneuve (1):
      dt-bindings: arm: fsl: remove redundant company name

Joao Paulo Goncalves (1):
      dt-bindings: arm: fsl: add imx8qm apalis eval v1.2 carrier board

Mathieu Othacehe (2):
      dt-bindings: arm: fsl: Add VAR-SOM-MX93 with Symphony
      dt-bindings: arm: fsl: Add phyBOARD-Segin-i.MX93

Sebastian Reichel (2):
      dt-bindings: vendor-prefixes: add UNI-T
      dt-bindings: arm: add UNI-T UTi260B

 Documentation/devicetree/bindings/arm/fsl.yaml     | 41 +++++++++++++++++++---
 .../devicetree/bindings/vendor-prefixes.yaml       |  2 ++
 2 files changed, 39 insertions(+), 4 deletions(-)



From shawnguo2 at yeah.net  Sun Feb 25 19:41:42 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 26 Feb 2024 11:41:42 +0800
Subject: [GIT PULL 1/5] i.MX SoC changes for 6.9
Message-ID: <20240226034147.233993-1-shawnguo2@yeah.net>

From: Shawn Guo <shawnguo at kernel.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-soc-6.9

for you to fetch changes up to 0d04e84db74d94732821ec515365109d12a9491c:

  ARM: imx: Remove usage of the deprecated ida_simple_xx() API (2024-02-05 17:23:28 +0800)

----------------------------------------------------------------
i.MX SoC changes for 6.9:

- Remove usage of the deprecated ida_simple_xx() API from MMDC code.

----------------------------------------------------------------
Christophe JAILLET (1):
      ARM: imx: Remove usage of the deprecated ida_simple_xx() API

 arch/arm/mach-imx/mmdc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)



From shawnguo2 at yeah.net  Sun Feb 25 19:41:46 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 26 Feb 2024 11:41:46 +0800
Subject: [GIT PULL 5/5] i.MX defconfig for 6.9
In-Reply-To: <20240226034147.233993-1-shawnguo2@yeah.net>
References: <20240226034147.233993-1-shawnguo2@yeah.net>
Message-ID: <20240226034147.233993-5-shawnguo2@yeah.net>

From: Shawn Guo <shawnguo at kernel.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-defconfig-6.9

for you to fetch changes up to f1a9ff95971a879572f56bbc8b1e1ca0b1a812b8:

  arm64: defconfig: enable i.MX8MP ldb bridge (2024-02-06 18:34:58 +0800)

----------------------------------------------------------------
i.MX defconfig for 6.9:

- Enable VF610 GPIO driver for both arm64 and i.MX ARM defconfig.
- Enable i.MX8MP LDB bridge and i.MX8QXP support drivers in arm64
  defconfig.

----------------------------------------------------------------
Alexander Stein (1):
      arm64: defconfig: Enable i.MX8QXP device drivers

Martin Kaiser (2):
      ARM: imx_v6_v7_defconfig: enable the vf610 gpio driver
      arm64: defconfig: enable the vf610 gpio driver

Yannic Moog (1):
      arm64: defconfig: enable i.MX8MP ldb bridge

 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 arch/arm64/configs/defconfig         | 8 ++++++++
 2 files changed, 9 insertions(+)



From shawnguo2 at yeah.net  Sun Feb 25 19:41:45 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 26 Feb 2024 11:41:45 +0800
Subject: [GIT PULL 4/5] i.MX arm64 device tree for 6.9
In-Reply-To: <20240226034147.233993-1-shawnguo2@yeah.net>
References: <20240226034147.233993-1-shawnguo2@yeah.net>
Message-ID: <20240226034147.233993-4-shawnguo2@yeah.net>

From: Shawn Guo <shawnguo at kernel.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-dt64-6.9

for you to fetch changes up to da96424168aa85be683f418414cbfa8b35283186:

  arm64: dts: imx8mm-kontron-bl-osm-s: Fix Ethernet PHY compatible (2024-02-26 10:24:54 +0800)

----------------------------------------------------------------
i.MX arm64 device tree for 6.9:

- New board support: Apalis eval v1.2 carrier board, Variscite
  VAR-SOM-MX93, phyBOARD-Segin-i.MX93.
- A series from Adam Ford to enable bluetooth, configure multiple queues
  on eqos, remove unnecessary clock configuration for i.MX8 Beacon boards.
- Several changesets from Alexander Stein to add i.MX8DXP support, enable
  audio and GPU for i.MX8QXP, re-parent MEDIA_MIPI_PHY1_REF clock for
  i.MX8MP, and improve MBA8xx board description.
- A few dt-schema fixes from Fabio Estevam for i.MX8MM and i.MX93 devices.
- A bunch of changes from Frank Li to improve i.MX8QM and i.MX8DXL
  support, correcting edma3 power-domains and interrupt numbers, adding
  I2C, FlexCAN and SMMU devices, etc.
- A series from Frieder Schrempf to improve imx8mm-kontron board
  descriptions, disabling pulls, fixing up RTC device, adding EEPROM,
  and refactoring OSM-S module, etc.
- A set of Data Modul i.MX8M Plus eDM SBC improvements from Marek Vasut.
- A series from Shengjiu Wang to add PDM micphone and SPDIF sound card
  support for imx8mm-evk board.
- A series of imx8mm-venice boards improvement from Tim Harvey to add
  TPM device, fix USB OTG VBUS etc.
- Other small and random improvements on various boards.

----------------------------------------------------------------
Adam Ford (4):
      arm64: dts: imx8mp-beacon: Enable Bluetooth
      arm64: dts: imx8mp-beacon: Configure multiple queues on eqos
      arm64: dts: imx8mn: Slow default video_pll clock rate
      arm64: dts: imx8mn-beacon: Remove unnecessary clock configuration

Alexander Stein (16):
      arm64: dts: imx: add imx8dxp support
      arm64: dts: freescale: add initial device tree for TQMa8Xx
      arm64: dts: imx8qxp: Add ACM input clock gates
      arm64: dts: imx8qxp: Add audio clock mux node
      arm64: dts: imx8qxp: Add audio SAI nodes
      arm64: dts: imx8qxp: Add mclkout clock gates
      arm64: dts: imx8qxp: mba8xx: Add analog audio output on MBa8Xx
      arm64: dts: imx8qxp: add GPU nodes
      arm64: dts: imx8mp: reparent MEDIA_MIPI_PHY1_REF to CLK_24M
      arm64: dts: freescale: tqma9352: Update I2C eeprom compatible
      arm64: dts: freescale: imx8-ss-dma: Fix edma3's location
      arm64: dts: imx8: Fix lpuart DMA channel order
      arm64: dts: freescale: imx8mm/imx8mq: mba8mx: Use PCIe clock generator
      arm64: dts: imx8mq: tqma8mq-mba8mx: Add missing USB vbus supply
      arm64: dts: imx8mn: tqma8mqnl-mba8mx: Add USB DR overlay
      arm64: dts: mba8xx: Add missing #interrupt-cells

Dominik Haller (1):
      arm64: dts: imx8mp-phyboard-pollux: Disable pull-up for CD GPIO

Fabio Estevam (4):
      arm64: dts: ls1046a: Remove big-endian from thermal
      arm64: dts: imx93-var-som: Remove phy-supply from eqos
      arm64: dts: imx8-apalis-v1.1: Remove reset-names from ethernet-phy
      arm64: dts: imx8mm-kontron-bl-osm-s: Fix Ethernet PHY compatible

Frank Li (11):
      arm64: dts: imx8qm: Align edma3 power-domains resources indentation
      arm64: dts: imx8qm: Correct edma3 power-domains and interrupt numbers
      arm64: dts: imx8dxl: update flexcan[1-3] interrupt number
      arm64: dts: imx8dxl-evk: add i2c3 and its children nodes
      arm64: dts: imx8dxl-evk: add flexcan2 and flecan3
      arm64: dts: imx8qm: add smmu node
      arm64: dts: imx8qm: add smmu stream id information
      arm64: dts: imx8dxl: add fsl-dma.h dt-binding header file
      arm64: dts: imx8dxl update edma0 information
      arm64: dts: imx8qm: add i2c4 and i2c4_lpcg node
      arm64: dts: imx8qm: add i2c1 for imx8qm-mek board

Frieder Schrempf (12):
      arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on OSM-S i.MX8MM
      arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on SL/BL i.MX8MM
      arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals on BL OSM-S board
      arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals on BL board
      arm64: dts: imx8mm-kontron: Disable pull resistors for SD card signals on BL OSM-S board
      arm64: dts: imx8mm-kontron: Disable pull resistors for SD card signals on BL board
      arm64: dts: imx8mm-kontron: Fix interrupt for RTC on OSM-S i.MX8MM module
      arm64: dts: imx8mm-kontron: Fix OSM-S devicetrees to match latest hardware
      arm64: dts: imx8mm-kontron: Disable uneffective PUE bit in SDIO IOMUX
      arm64: dts: imx8mm-kontron: Remove useless trickle-diode-disable from RTC node
      arm64: dts: imx8mm-kontron: Add I2C EEPROM on OSM-S Kontron i.MX8MM
      arm64: dts: imx8mm-kontron: Refactor devicetree for OSM-S module and board

Heinz Wrobel (1):
      arm64: dts: lx2160a: Fix DTS for full PL011 UART

Hou Zhiqiang (1):
      arm64: dts: ls1012a: add big-endian property for PCIe nodes

Hugo Villeneuve (1):
      arm64: dts: imx8mn-rve-gateway: remove redundant company name

Joao Paulo Goncalves (1):
      arm64: dts: freescale: imx8qm: add apalis eval v1.2 carrier board

Krzysztof Kozlowski (2):
      arm64: dts: imx93: drop "master" I3C node name suffix
      arm64: dts: freescale: minor whitespace cleanup

Li Yang (2):
      arm64: dts: ls1012a: correct the size of dcfg block
      arm64: dts: ls1012a: add gpio for i2c bus recovery

Liu Ying (1):
      arm64: dts: imx8mp-evk: Fix hdmi at 3d node

Marek Vasut (3):
      arm64: dts: imx8mp: Enable PCIe to Data Modul i.MX8M Plus eDM SBC
      arm64: dts: imx8mp: Enable SAI audio on Data Modul i.MX8M Plus eDM SBC
      arm64: dts: imx8mp: Set SPI NOR to max 40 MHz on Data Modul i.MX8M Plus eDM SBC

Mathieu Othacehe (2):
      arm64: dts: imx93-var-som: Add Variscite VAR-SOM-MX93
      arm64: dts: imx93: Add phyBOARD-Segin-i.MX93 support

Philippe Schenker (1):
      arm64: dts: imx8mp-verdin: Label ldo5 and link to usdhc2

Ran Wang (1):
      arm64: dts: ls1012a: fix DWC3 USB VBUS glitch issue

Shengjiu Wang (3):
      arm64: dts: imx8mm-evk: Add PDM micphone sound card support
      arm64: dts: imx8mn-evk: Add PDM micphone sound card support
      arm64: dts: imx8mm-evk: Add spdif sound card support

Teresa Remmet (1):
      arm64: dts: imx8mp-phyboard-pollux: Reduce drive strength for eqos tx lines

Tim Harvey (5):
      arm64: dts: imx8mm-venice-gw7901: add digital I/O direction control GPIO's
      arm64: dts: imx8mm-venice-gw7901: add TPM device
      arm64: dts: imx8mm-venice-gw71xx: fix USB OTG VBUS
      arm64: dts: imx8mm-venice-gw71xx: add TPM device
      arm64: dts: imx8mp-venice-gw71xx: add TPM device

Xiaowei Bao (1):
      arm64: dts: ls1088a: Add the PME interrupt for PCIe EP node

Yannic Moog (2):
      arm64: dts: imx8mp-phyboard-pollux-rdk: add etml panel support
      arm64: dts: imx8mp-phyboard-pollux: Set debug uart muxing to 0x140

Yashwanth Varakala (1):
      arm64: dts: imx8mp-phyboard-pollux: Add and update rtc devicetree node

 arch/arm/boot/dts/nxp/ls/ls1021a.dtsi              |   1 +
 arch/arm64/boot/dts/freescale/Makefile             |   8 +
 arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi     |  10 +-
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi     |   1 -
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi     |   6 +
 arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi     |  32 +-
 .../boot/dts/freescale/imx8-apalis-eval-v1.1.dtsi  |  26 +
 .../boot/dts/freescale/imx8-apalis-eval-v1.2.dtsi  | 124 +++++
 .../arm64/boot/dts/freescale/imx8-apalis-eval.dtsi |  22 -
 .../arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi |   1 -
 arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi   | 330 ++++++++++++
 arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi     |  63 +--
 arch/arm64/boot/dts/freescale/imx8-ss-gpu0.dtsi    |  27 +
 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts      | 101 ++++
 arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi |  77 +++
 arch/arm64/boot/dts/freescale/imx8dxl.dtsi         |   1 +
 .../boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dts |  16 +
 .../arm64/boot/dts/freescale/imx8dxp-tqma8xdp.dtsi |  24 +
 arch/arm64/boot/dts/freescale/imx8dxp.dtsi         |  24 +
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi      |  69 +++
 .../boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts | 294 ++++-------
 .../arm64/boot/dts/freescale/imx8mm-kontron-bl.dts |  38 +-
 .../boot/dts/freescale/imx8mm-kontron-osm-s.dtsi   | 567 ++++++++++++++++++++-
 .../boot/dts/freescale/imx8mm-kontron-sl.dtsi      |   4 +-
 .../boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts |  14 +-
 .../boot/dts/freescale/imx8mm-venice-gw71xx.dtsi   |  40 +-
 .../boot/dts/freescale/imx8mm-venice-gw7901.dts    |  14 +-
 .../arm64/boot/dts/freescale/imx8mn-beacon-kit.dts |   2 -
 arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi      |  36 ++
 .../boot/dts/freescale/imx8mn-rve-gateway.dts      |   2 +-
 .../freescale/imx8mn-tqma8mqnl-mba8mx-usbotg.dtso  |  64 +++
 .../boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts |   5 +-
 arch/arm64/boot/dts/freescale/imx8mn.dtsi          |   2 +-
 .../boot/dts/freescale/imx8mp-beacon-som.dtsi      |  71 +++
 .../dts/freescale/imx8mp-data-modul-edm-sbc.dts    |  82 ++-
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts       |  33 +-
 .../dts/freescale/imx8mp-phyboard-pollux-rdk.dts   | 107 +++-
 .../boot/dts/freescale/imx8mp-phycore-som.dtsi     |   1 -
 .../boot/dts/freescale/imx8mp-venice-gw71xx.dtsi   |  10 +-
 arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi   |   3 +-
 arch/arm64/boot/dts/freescale/imx8mp.dtsi          |  12 +-
 .../boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts   |  24 +-
 .../boot/dts/freescale/imx8qm-apalis-eval-v1.2.dts |  16 +
 .../boot/dts/freescale/imx8qm-apalis-eval.dts      |   2 +-
 .../dts/freescale/imx8qm-apalis-v1.1-eval-v1.2.dts |  26 +
 .../boot/dts/freescale/imx8qm-apalis-v1.1-eval.dts |   2 +-
 arch/arm64/boot/dts/freescale/imx8qm-mek.dts       |  26 +
 arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi  |   5 +
 arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi   |  55 +-
 arch/arm64/boot/dts/freescale/imx8qm.dtsi          |  41 ++
 .../boot/dts/freescale/imx8qxp-tqma8xqp-mba8xx.dts |  16 +
 .../arm64/boot/dts/freescale/imx8qxp-tqma8xqp.dtsi |  14 +
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi         |   8 +
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts      |   2 +-
 .../boot/dts/freescale/imx93-phyboard-segin.dts    | 117 +++++
 .../boot/dts/freescale/imx93-phycore-som.dtsi      | 126 +++++
 arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi  |   4 +-
 .../boot/dts/freescale/imx93-var-som-symphony.dts  | 351 +++++++++++++
 arch/arm64/boot/dts/freescale/imx93-var-som.dtsi   | 110 ++++
 arch/arm64/boot/dts/freescale/imx93.dtsi           |   4 +-
 arch/arm64/boot/dts/freescale/mba8mx.dtsi          |  21 +-
 arch/arm64/boot/dts/freescale/mba8xx.dtsi          | 554 ++++++++++++++++++++
 arch/arm64/boot/dts/freescale/tqma8xx.dtsi         | 265 ++++++++++
 63 files changed, 3749 insertions(+), 404 deletions(-)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-apalis-eval-v1.1.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-apalis-eval-v1.2.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-gpu0.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8dxp.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-usbotg.dtso
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qm-apalis-eval-v1.2.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval-v1.2.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp-mba8xx.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx93-phyboard-segin.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx93-phycore-som.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx93-var-som-symphony.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx93-var-som.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/mba8xx.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/tqma8xx.dtsi



From shawnguo2 at yeah.net  Sun Feb 25 19:41:44 2024
From: shawnguo2 at yeah.net (Shawn Guo)
Date: Mon, 26 Feb 2024 11:41:44 +0800
Subject: [GIT PULL 3/5] i.MX ARM device tree for 6.9
In-Reply-To: <20240226034147.233993-1-shawnguo2@yeah.net>
References: <20240226034147.233993-1-shawnguo2@yeah.net>
Message-ID: <20240226034147.233993-3-shawnguo2@yeah.net>

From: Shawn Guo <shawnguo at kernel.org>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-dt-6.9

for you to fetch changes up to ccda9e5c365f6c4c3af5fda9c15cce3779cb2bbe:

  ARM: dts: nxp: imx: fix weim node name (2024-02-26 09:35:07 +0800)

----------------------------------------------------------------
i.MX ARM device tree for 6.9:

- New board support: Sielaff i.MX6 Solo, Apalis Evaluation Board v1.2.
- A bunch of i.MX7 TQMA7/MBA7 updates from Alexander Stein that add
  various devices, improve hardware descriptions and fix dt-schema
  warnings, etc.
- Correct touchscreen rotation for imx6sl-tolino-shine2hd board.
- An imx53-qsb update from Dmitry Baryshkov to add HDMI expander support.
- A couple of i.MX1 and i.MX28 device node name fixes from Fabio Estevam.
- Enable usb3-lpm-capable for LS1021A usb3 node.
- A couple of imx6dl-yapp4 board improvements from Michal Vok??.
- A series from Sebastian Reichel to improve imx6ull descriptions.

----------------------------------------------------------------
Alexander Stein (24):
      ARM: dts: imx7-tqma7/mba7: convert fsl,pins to uint32-matrix
      ARM: dts: imx7[d]-mba7: Move ethernet PHY reset into PHY node
      ARM: dts: imx7[d]-mba7: disable USB OC on USB host and USB OTG2
      ARM: dts: imx7[d]-mba7: disable PCIe interface
      ARM: dts: imx7[d]-mba7: hog Mini PCIe signals
      ARM: dts: imx7-mba7: Mark gpio-buttons as wakeup-source
      ARM: dts: imx7-mba7: Enable SNVS power key
      ARM: dts: imx7-mba7: Add RTC aliases
      ARM: dts: imx7-mba7: Add SPI1_SS0 as chip select 3
      ARM: dts: imx7-tqma7: Add i2c bus recovery
      ARM: dts: imx7-mba7: Add i2c bus recovery
      ARM: dts: imx7-tqma7: fix EEPROM compatible for SE97BTP
      ARM: dts: imx7-mba7: Fix iomuxc node names
      ARM: dts: imx7-tqma7: Fix iomuxc node names
      ARM: dts: imx7-mba7: restrict usdhc interface modes
      ARM: dts: imx7-tqma7: restrict usdhc interface modes
      ARM: dts: imx7-tqma7: remove superfluous status property
      ARM: dts: imx7-tqma7: mark system data eeprom as read-only
      ARM: dts: imx7-tqma7: rename node for SE97BTP
      ARM: dts: imx7d-mba7: Remove USB OTG related properties on USB node
      ARM: dts: imx7-tqma7: Add missing vcc supply to i2c eeproms
      ARM: dts: imx7-mba7: Add missing vcc supply to i2c devices
      ARM: dts: imx7-tqma7: Fix PMIC v33 rail voltage range
      ARM: dts: imx6ul: Add missing #thermal-sensor-cells to tempmon

Andreas Kemnade (1):
      ARM: dts: imx6sl-tolino-shine2hd: fix touchscreen rotation

Christoph Niedermaier (2):
      ARM: dts: imx6ull-dhcor: Remove 900MHz operating point
      ARM: dts: imx6ull-dhcom: Remove /omit-if-no-ref/ from node usdhc1-pwrseq

Dmitry Baryshkov (1):
      ARM: dts: imx53-qsb: add support for the HDMI expander

Fabio Estevam (2):
      ARM: dts: imx28-evk: Use 'eeprom' as the node name
      ARM: dts: imx1-apf9328: Fix Ethernet node name

Frieder Schrempf (1):
      ARM: dts: imx6dl: Add support for Sielaff i.MX6 Solo board

Hiago De Franco (1):
      ARM: dts: imx: Add support for Apalis Evaluation Board v1.2

Josua Mayer (1):
      ARM: dts: imx6qdl-hummingboard: Add rtc0 and rtc1 aliases to fix hctosys

Li Yang (1):
      ARM: dts: ls1021a: Enable usb3-lpm-capable for usb3 node

Manuel Traut (1):
      ARM: dts: imx6ul: Set macaddress location in ocotp

Michal Vok?? (2):
      ARM: dts: imx6dl-yapp4: Fix typo in the QCA switch register address
      ARM: dts: imx6dl-yapp4: Move the internal switch PHYs under the switch node

Oleksij Rempel (1):
      ARM: dts: imx6: skov: add aliases for all ethernet nodes

Sebastian Reichel (5):
      ARM: dts: imx6ull: fix pinctrl node name
      ARM: dts: imx6ul: Remove fsl,anatop from usbotg1
      ARM: dts: nxp: imx6ul: xnur-gpio -> xnur-gpios
      ARM: dts: nxp: imx6ul: fix touchscreen node name
      ARM: dts: nxp: imx: fix weim node name

 arch/arm/boot/dts/nxp/imx/Makefile                 |   6 +
 arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts         |   2 +-
 arch/arm/boot/dts/nxp/imx/imx1.dtsi                |   2 +-
 arch/arm/boot/dts/nxp/imx/imx27.dtsi               |   2 +-
 arch/arm/boot/dts/nxp/imx/imx31.dtsi               |   2 +-
 arch/arm/boot/dts/nxp/imx/imx35.dtsi               |   2 +-
 arch/arm/boot/dts/nxp/imx/imx51.dtsi               |   2 +-
 arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso      |  87 ++++
 arch/arm/boot/dts/nxp/imx/imx6dl-sielaff.dts       | 533 +++++++++++++++++++++
 arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi |  25 +-
 .../boot/dts/nxp/imx/imx6q-apalis-eval-v1.2.dts    | 200 ++++++++
 arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dts    | 108 +----
 arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dtsi   | 120 +++++
 .../arm/boot/dts/nxp/imx/imx6qdl-hummingboard.dtsi |   7 +-
 .../boot/dts/nxp/imx/imx6qdl-hummingboard2.dtsi    |   5 +
 arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi    |  10 +-
 arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi             |   2 +-
 .../boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts    |   6 +-
 arch/arm/boot/dts/nxp/imx/imx6sl.dtsi              |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6sx.dtsi              |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi    |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts          |   2 +-
 .../dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi     |   2 +-
 arch/arm/boot/dts/nxp/imx/imx6ul.dtsi              |  18 +-
 .../dts/nxp/imx/imx6ull-dhcom-som-cfg-sdcard.dtsi  |   4 +-
 arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi   |   4 +-
 arch/arm/boot/dts/nxp/imx/imx6ull-dhcor-som.dtsi   |   7 +-
 arch/arm/boot/dts/nxp/imx/imx6ull.dtsi             |   2 +-
 arch/arm/boot/dts/nxp/imx/imx7-mba7.dtsi           | 325 +++++++------
 arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi          | 144 +++---
 arch/arm/boot/dts/nxp/imx/imx7d-mba7.dts           |  94 ++--
 arch/arm/boot/dts/nxp/ls/ls1021a.dtsi              |   1 +
 arch/arm/boot/dts/nxp/mxs/imx28-evk.dts            |   2 +-
 33 files changed, 1338 insertions(+), 394 deletions(-)
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6dl-sielaff.dts
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval-v1.2.dts
 create mode 100644 arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dtsi



From Dharma.B at microchip.com  Sun Feb 25 20:00:52 2024
From: Dharma.B at microchip.com (Dharma.B at microchip.com)
Date: Mon, 26 Feb 2024 04:00:52 +0000
Subject: [PATCH v4 2/4] drm/bridge: add lvds controller support for sam9x7
In-Reply-To: <20240209150757.66914-3-dharma.b@microchip.com>
References: <20240209150757.66914-1-dharma.b@microchip.com>
 <20240209150757.66914-3-dharma.b@microchip.com>
Message-ID: <73b85830-b4c0-496d-a030-9080ac21e111@microchip.com>


Hi Folks,

Your feedback is valuable, and I'm eager to address any concerns or make
improvements as needed. Thank you for your consideration.

On 09/02/24 8:37 pm, Dharma B - I70843 wrote:
> Add a new LVDS controller driver for sam9x7 which does the following:
> - Prepares and enables the LVDS Peripheral clock
> - Defines its connector type as DRM_MODE_CONNECTOR_LVDS and adds itself
> to the global bridge list.
> - Identifies its output endpoint as panel and adds it to the encoder
> display pipeline
> - Enables the LVDS serializer
> 
> Signed-off-by: Manikandan Muralidharan <manikandan.m at microchip.com>
> Signed-off-by: Dharma Balasubiramani <dharma.b at microchip.com>
> ---
> Changelog
> v3 -> v4
> - No changes.
> v2 ->v3
> - Correct Typo error "serializer".
> - Consolidate get() and prepare() functions and use devm_clk_get_prepared().
> - Remove unused variable 'ret' in probe().
> - Use devm_pm_runtime_enable() and drop the mchp_lvds_remove().
> v1 -> v2
> - Drop 'res' variable and combine two lines into one.
> - Handle deferred probe properly, use dev_err_probe().
> - Don't print anything on deferred probe. Dropped print.
> - Remove the MODULE_ALIAS and add MODULE_DEVICE_TABLE().
> - symbol 'mchp_lvds_driver' was not declared. It should be static.
> ---
>   drivers/gpu/drm/bridge/Kconfig          |   7 +
>   drivers/gpu/drm/bridge/Makefile         |   1 +
>   drivers/gpu/drm/bridge/microchip-lvds.c | 228 ++++++++++++++++++++++++
>   3 files changed, 236 insertions(+)
>   create mode 100644 drivers/gpu/drm/bridge/microchip-lvds.c
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index 3e6a4e2044c0..74ca0edb4e0d 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -173,6 +173,13 @@ config DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW
>   	  to DP++. This is used with the i.MX6 imx-ldb
>   	  driver. You are likely to say N here.
>   
> +config DRM_MICROCHIP_LVDS_SERIALIZER
> +	tristate "Microchip LVDS serializer support"
> +	depends on OF
> +	depends on DRM_ATMEL_HLCDC
> +	help
> +	  Support for Microchip's LVDS serializer.
> +
>   config DRM_NWL_MIPI_DSI
>   	tristate "Northwest Logic MIPI DSI Host controller"
>   	depends on DRM
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 2b892b7ed59e..e3804e93d324 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
>   obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o
>   obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o
>   obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
> +obj-$(CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER) += microchip-lvds.o
>   obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
>   obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
>   obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
> diff --git a/drivers/gpu/drm/bridge/microchip-lvds.c b/drivers/gpu/drm/bridge/microchip-lvds.c
> new file mode 100644
> index 000000000000..d3fd9d722e36
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/microchip-lvds.c
> @@ -0,0 +1,228 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
> + *
> + * Author: Manikandan Muralidharan <manikandan.m at microchip.com>
> + * Author: Dharma Balasubiramani <dharma.b at microchip.com>
> + *
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/delay.h>
> +#include <linux/jiffies.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_graph.h>
> +#include <linux/pinctrl/devinfo.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_of.h>
> +#include <drm/drm_panel.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_probe_helper.h>
> +#include <drm/drm_simple_kms_helper.h>
> +
> +#define LVDS_POLL_TIMEOUT_MS 1000
> +
> +/* LVDSC register offsets */
> +#define LVDSC_CR	0x00
> +#define LVDSC_CFGR	0x04
> +#define LVDSC_SR	0x0C
> +#define LVDSC_WPMR	0xE4
> +
> +/* Bitfields in LVDSC_CR (Control Register) */
> +#define LVDSC_CR_SER_EN	BIT(0)
> +
> +/* Bitfields in LVDSC_CFGR (Configuration Register) */
> +#define LVDSC_CFGR_PIXSIZE_24BITS	0
> +#define LVDSC_CFGR_DEN_POL_HIGH		0
> +#define LVDSC_CFGR_DC_UNBALANCED	0
> +#define LVDSC_CFGR_MAPPING_JEIDA	BIT(6)
> +
> +/*Bitfields in LVDSC_SR */
> +#define LVDSC_SR_CS	BIT(0)
> +
> +/* Bitfields in LVDSC_WPMR (Write Protection Mode Register) */
> +#define LVDSC_WPMR_WPKEY_MASK	GENMASK(31, 8)
> +#define LVDSC_WPMR_WPKEY_PSSWD	0x4C5644
> +
> +struct mchp_lvds {
> +	struct device *dev;
> +	void __iomem *regs;
> +	struct clk *pclk;
> +	int format; /* vesa or jeida format */
> +	struct drm_panel *panel;
> +	struct drm_bridge bridge;
> +	struct drm_bridge *panel_bridge;
> +};
> +
> +static inline struct mchp_lvds *bridge_to_lvds(struct drm_bridge *bridge)
> +{
> +	return container_of(bridge, struct mchp_lvds, bridge);
> +}
> +
> +static inline u32 lvds_readl(struct mchp_lvds *lvds, u32 offset)
> +{
> +	return readl_relaxed(lvds->regs + offset);
> +}
> +
> +static inline void lvds_writel(struct mchp_lvds *lvds, u32 offset, u32 val)
> +{
> +	writel_relaxed(val, lvds->regs + offset);
> +}
> +
> +static void lvds_serialiser_on(struct mchp_lvds *lvds)
> +{
> +	unsigned long timeout = jiffies + msecs_to_jiffies(LVDS_POLL_TIMEOUT_MS);
> +
> +	/* The LVDSC registers can only be written if WPEN is cleared */
> +	lvds_writel(lvds, LVDSC_WPMR, (LVDSC_WPMR_WPKEY_PSSWD &
> +				LVDSC_WPMR_WPKEY_MASK));
> +
> +	/* Wait for the status of configuration registers to be changed */
> +	while (lvds_readl(lvds, LVDSC_SR) & LVDSC_SR_CS) {
> +		if (time_after(jiffies, timeout)) {
> +			dev_err(lvds->dev, "%s: timeout error\n", __func__);
> +			return;
> +		}
> +		usleep_range(1000, 2000);
> +	}
> +
> +	/* Configure the LVDSC */
> +	lvds_writel(lvds, LVDSC_CFGR, (LVDSC_CFGR_MAPPING_JEIDA |
> +				LVDSC_CFGR_DC_UNBALANCED |
> +				LVDSC_CFGR_DEN_POL_HIGH |
> +				LVDSC_CFGR_PIXSIZE_24BITS));
> +
> +	/* Enable the LVDS serializer */
> +	lvds_writel(lvds, LVDSC_CR, LVDSC_CR_SER_EN);
> +}
> +
> +static int mchp_lvds_attach(struct drm_bridge *bridge,
> +			    enum drm_bridge_attach_flags flags)
> +{
> +	struct mchp_lvds *lvds = bridge_to_lvds(bridge);
> +
> +	bridge->encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
> +
> +	return drm_bridge_attach(bridge->encoder, lvds->panel_bridge,
> +				 bridge, flags);
> +}
> +
> +static void mchp_lvds_enable(struct drm_bridge *bridge)
> +{
> +	struct mchp_lvds *lvds = bridge_to_lvds(bridge);
> +	int ret;
> +
> +	ret = clk_enable(lvds->pclk);
> +	if (ret < 0) {
> +		DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
> +		return;
> +	}
> +
> +	ret = pm_runtime_get_sync(lvds->dev);
> +	if (ret < 0) {
> +		DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
> +		clk_disable(lvds->pclk);
> +		return;
> +	}
> +
> +	lvds_serialiser_on(lvds);
> +}
> +
> +static void mchp_lvds_disable(struct drm_bridge *bridge)
> +{
> +	struct mchp_lvds *lvds = bridge_to_lvds(bridge);
> +
> +	pm_runtime_put(lvds->dev);
> +	clk_disable(lvds->pclk);
> +}
> +
> +static const struct drm_bridge_funcs mchp_lvds_bridge_funcs = {
> +	.attach = mchp_lvds_attach,
> +	.enable = mchp_lvds_enable,
> +	.disable = mchp_lvds_disable,
> +};
> +
> +static int mchp_lvds_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mchp_lvds *lvds;
> +	struct device_node *port;
> +
> +	if (!dev->of_node)
> +		return -ENODEV;
> +
> +	lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL);
> +	if (!lvds)
> +		return -ENOMEM;
> +
> +	lvds->dev = dev;
> +
> +	lvds->regs = devm_ioremap_resource(lvds->dev,
> +			platform_get_resource(pdev, IORESOURCE_MEM, 0));
> +	if (IS_ERR(lvds->regs))
> +		return PTR_ERR(lvds->regs);
> +
> +	lvds->pclk = devm_clk_get_prepared(lvds->dev, "pclk");
> +	if (IS_ERR(lvds->pclk))
> +		return dev_err_probe(lvds->dev, PTR_ERR(lvds->pclk),
> +				"could not get pclk_lvds prepared\n");
> +
> +	port = of_graph_get_remote_node(dev->of_node, 1, 0);
> +	if (!port) {
> +		DRM_DEV_ERROR(dev,
> +			      "can't find port point, please init lvds panel port!\n");
> +		return -EINVAL;
> +	}
> +
> +	lvds->panel = of_drm_find_panel(port);
> +	of_node_put(port);
> +
> +	if (IS_ERR(lvds->panel))
> +		return -EPROBE_DEFER;
> +
> +	lvds->panel_bridge = devm_drm_panel_bridge_add(dev, lvds->panel);
> +
> +	if (IS_ERR(lvds->panel_bridge))
> +		return PTR_ERR(lvds->panel_bridge);
> +
> +	lvds->bridge.of_node = dev->of_node;
> +	lvds->bridge.type = DRM_MODE_CONNECTOR_LVDS;
> +	lvds->bridge.funcs = &mchp_lvds_bridge_funcs;
> +
> +	dev_set_drvdata(dev, lvds);
> +	devm_pm_runtime_enable(dev);
> +
> +	drm_bridge_add(&lvds->bridge);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id mchp_lvds_dt_ids[] = {
> +	{
> +		.compatible = "microchip,sam9x75-lvds",
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, mchp_lvds_dt_ids);
> +
> +static struct platform_driver mchp_lvds_driver = {
> +	.probe = mchp_lvds_probe,
> +	.driver = {
> +		   .name = "microchip-lvds",
> +		   .of_match_table = mchp_lvds_dt_ids,
> +	},
> +};
> +module_platform_driver(mchp_lvds_driver);
> +
> +MODULE_AUTHOR("Manikandan Muralidharan <manikandan.m at microchip.com>");
> +MODULE_AUTHOR("Dharma Balasubiramani <dharma.b at microchip.com>");
> +MODULE_DESCRIPTION("Low Voltage Differential Signaling Controller Driver");
> +MODULE_LICENSE("GPL");

-- 
With Best Regards,
Dharma B.


From sgsu.park at samsung.com  Sun Feb 25 20:02:24 2024
From: sgsu.park at samsung.com (Seongsu Park)
Date: Mon, 26 Feb 2024 13:02:24 +0900
Subject: [PATCH] arm64: head: Remove the instructions that get the virtual
 offset in __relocate_kernel
References: <CGME20240226040238epcas1p189fc1471befb73603d75aab855ae37ac@epcas1p1.samsung.com>
Message-ID: <20240226040224.611039-1-sgsu.park@samsung.com>

Since relative references have been used in RELA and RELR tables,
there has been no need to know their start va and end va.
Therefore, the instructions to get virtual offset in __relocate_kernel
should be removed.

Co-developed-by: Leem ChaeHoon <infinite.run at gmail.com>
Signed-off-by: Leem ChaeHoon <infinite.run at gmail.com>
Co-developed-by: Hyongwu Kim <browoo777 at gmail.com>
Signed-off-by: Hyongwu Kim <browoo777 at gmail.com>
Co-developed-by: Gyeonggeon Choi <gychoi at student.42seoul.kr>
Signed-off-by: Gyeonggeon Choi <gychoi at student.42seoul.kr>
Co-developed-by: Soomin Cho <to.soomin at gmail.com>
Signed-off-by: Soomin Cho <to.soomin at gmail.com>
Co-developed-by: Daero Lee <skseofh at gmail.com>
Signed-off-by: Daero Lee <skseofh at gmail.com>
Co-developed-by: kmasta <kmasta.study at gmail.com>
Signed-off-by: kmasta <kmasta.study at gmail.com>
Signed-off-by: Seongsu Park <sgsu.park at samsung.com>
---
 arch/arm64/kernel/head.S | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index cab7f91949d8..90db196f7c19 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -787,8 +787,6 @@ SYM_FUNC_START_LOCAL(__relocate_kernel)
 	 */
 	adr_l	x9, __rela_start
 	adr_l	x10, __rela_end
-	mov_q	x11, KIMAGE_VADDR		// default virtual offset
-	add	x11, x11, x23			// actual virtual offset
 
 0:	cmp	x9, x10
 	b.hs	1f
-- 
2.34.1



From vigneshr at ti.com  Sun Feb 25 20:08:12 2024
From: vigneshr at ti.com (Vignesh Raghavendra)
Date: Mon, 26 Feb 2024 09:38:12 +0530
Subject: [PATCH v5] arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in serdes_ln_ctrl
In-Reply-To: <20240213080348.248916-1-s-vadapalli@ti.com>
References: <20240213080348.248916-1-s-vadapalli@ti.com>
Message-ID: <170860805561.1966114.575240163502689016.b4-ty@ti.com>

Hi Siddharth Vadapalli,

On Tue, 13 Feb 2024 13:33:48 +0530, Siddharth Vadapalli wrote:
> Change offset in mux-reg-masks property for serdes_ln_ctrl node
> since reg-mux property is used in compatible.
> 
> 

I have applied the following to branch ti-k3-dts-next on [1].
Thank you!

[1/1] arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in serdes_ln_ctrl
      commit: 9a0c0a9baa2d1f906589d715f9baeab93e7fcdcb

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant 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.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh



From apatel at ventanamicro.com  Sun Feb 25 20:07:36 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:36 +0530
Subject: [PATCH v15 00/10] Linux RISC-V AIA Support
Message-ID: <20240226040746.1396416-1-apatel@ventanamicro.com>

The RISC-V AIA specification is ratified as-per the RISC-V international
process. The latest ratified AIA specifcation can be found at:
https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf

At a high-level, the AIA specification adds three things:
1) AIA CSRs
   - Improved local interrupt support
2) Incoming Message Signaled Interrupt Controller (IMSIC)
   - Per-HART MSI controller
   - Support MSI virtualization
   - Support IPI along with virtualization
3) Advanced Platform-Level Interrupt Controller (APLIC)
   - Wired interrupt controller
   - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
   - In Direct-mode, injects external interrupts directly into HARTs

For an overview of the AIA specification, refer the AIA virtualization
talk at KVM Forum 2022:
https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
https://www.youtube.com/watch?v=r071dL8Z0yo

To test this series, use QEMU v7.2 (or higher) and OpenSBI v1.2 (or higher).

This series depends upon per-device MSI domain (and few other) patches merged
by Thomas (tglx) which are available in irq/msi branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git

These patches can also be found in the riscv_aia_v15 branch at:
https://github.com/avpatel/linux.git

Changes since v14:
 - Dropped 9 patches which are already merged by Thomas (tglx) and available in
   his irq/msi branch at git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git
 - Added new PATCH1 which adds changes missed out in merging AIA support for
   RISC-V INTC.
 - Added a separate cpuhp state for IMSIC driver in PATCH3 which ensures that
   cpuhp notifiers of IMSIC are called as early as possible.
 - Removed redundant barriers in PATCH3.
 - Addressed few other nit comments.

Changes since v13:
 - Split PATCH1 into six granular patches
 - Addressed nit comments from Thomas and Bjorn

Changes since v12:
 - Rebased on Linux-6.8-rc5
 - Dropped per-device MSI domain patches which are already merged by Thomas (tglx)
 - Addressed nit comments from Thomas and Clement
 - Added a new patch2 to fix lock dependency warning
 - Replaced local sync IPI in the IMSIC driver with per-CPU timer
 - Simplified locking in the IMSIC driver to avoid lock dependency issues
 - Added a dirty bitmap in the IMSIC driver to optimize per-CPU local sync loop

Changes since v11:
 - Rebased on Linux-6.8-rc1
 - Included kernel/irq related patches from "genirq, irqchip: Convert ARM
   MSI handling to per device MSI domains" series by Thomas.
   (PATCH7, PATCH8, PATCH9, PATCH14, PATCH16, PATCH17, PATCH18, PATCH19,
    PATCH20, PATCH21, PATCH22, PATCH23, and PATCH32 of
    https://lore.kernel.org/linux-arm-kernel/20221121135653.208611233 at linutronix.de/)
 - Updated APLIC MSI-mode driver to use the new WIRED_TO_MSI mechanism.
 - Updated IMSIC driver to support per-device MSI domains for PCI and
   platform devices.

Changes since v10:
 - Rebased on Linux-6.6-rc7
 - Dropped PATCH3 of v10 series since this has been merged by MarcZ
   for Linux-6.6-rc7
 - Changed the IMSIC ID management strategy from 1-n approach to
   x86-style 1-1 approach

Changes since v9:
 - Rebased on Linux-6.6-rc4
 - Use builtin_platform_driver() in PATCH5, PATCH9, and PATCH12

Changes since v8:
 - Rebased on Linux-6.6-rc3
 - Dropped PATCH2 of v8 series since we won't be requiring
   riscv_get_intc_hartid() based on Marc Z's comments on ACPI AIA support.
 - Addressed Saravana's comments in PATCH3 of v8 series
 - Update PATCH9 and PATCH13 of v8 series based on comments from Sunil

Changes since v7:
 - Rebased on Linux-6.6-rc1
 - Addressed comments on PATCH1 of v7 series and split it into two PATCHes
 - Use DEFINE_SIMPLE_PROP() in PATCH2 of v7 series

Changes since v6:
 - Rebased on Linux-6.5-rc4
 - Updated PATCH2 to use IS_ENABLED(CONFIG_SPARC) instead of
   !IS_ENABLED(CONFIG_OF_IRQ)
 - Added new PATCH4 to fix syscore registration in PLIC driver
 - Update PATCH5 to convert PLIC driver into full-blown platform driver
   with a re-written probe function.

Changes since v5:
 - Rebased on Linux-6.5-rc2
 - Updated the overall series to ensure that only IPI, timer, and
   INTC drivers are probed very early whereas rest of the interrupt
   controllers (such as PLIC, APLIC, and IMISC) are probed as
   regular platform drivers.
 - Renamed riscv_fw_parent_hartid() to riscv_get_intc_hartid()
 - New PATCH1 to add fw_devlink support for msi-parent DT property
 - New PATCH2 to ensure all INTC suppliers are initialized which in-turn
   fixes the probing issue for PLIC, APLIC and IMSIC as platform driver
 - New PATCH3 to use platform driver probing for PLIC
 - Re-structured the IMSIC driver into two separate drivers: early and
   platform. The IMSIC early driver (PATCH7) only initialized IMSIC state
   and provides IPIs whereas the IMSIC platform driver (PATCH8) is probed
   provides MSI domain for platform devices.
 - Re-structure the APLIC platform driver into three separe sources: main,
   direct mode, and MSI mode.

Changes since v4:
 - Rebased on Linux-6.5-rc1
 - Added "Dependencies" in the APLIC bindings (PATCH6 in v4)
 - Dropped the PATCH6 which was changing the IOMMU DMA domain APIs
 - Dropped use of IOMMU DMA APIs in the IMSIC driver (PATCH4)

Changes since v3:
 - Rebased on Linux-6.4-rc6
 - Dropped PATCH2 of v3 series instead we now set FWNODE_FLAG_BEST_EFFORT via
   IRQCHIP_DECLARE()
 - Extend riscv_fw_parent_hartid() to support both DT and ACPI in PATCH1
 - Extend iommu_dma_compose_msi_msg() instead of adding iommu_dma_select_msi()
   in PATCH6
 - Addressed Conor's comments in PATCH3
 - Addressed Conor's and Rob's comments in PATCH7

Changes since v2:
 - Rebased on Linux-6.4-rc1
 - Addressed Rob's comments on DT bindings patches 4 and 8.
 - Addessed Marc's comments on IMSIC driver PATCH5
 - Replaced use of OF apis in APLIC and IMSIC drivers with FWNODE apis
   this makes both drivers easily portable for ACPI support. This also
   removes unnecessary indirection from the APLIC and IMSIC drivers.
 - PATCH1 is a new patch for portability with ACPI support
 - PATCH2 is a new patch to fix probing in APLIC drivers for APLIC-only systems.
 - PATCH7 is a new patch which addresses the IOMMU DMA domain issues pointed
   out by SiFive

Changes since v1:
 - Rebased on Linux-6.2-rc2
 - Addressed comments on IMSIC DT bindings for PATCH4
 - Use raw_spin_lock_irqsave() on ids_lock for PATCH5
 - Improved MMIO alignment checks in PATCH5 to allow MMIO regions
   with holes.
 - Addressed comments on APLIC DT bindings for PATCH6
 - Fixed warning splat in aplic_msi_write_msg() caused by
   zeroed MSI message in PATCH7
 - Dropped DT property riscv,slow-ipi instead will have module
   parameter in future.

Anup Patel (10):
  irqchip/riscv-intc: Fix low-level interrupt handler setup for AIA
  dt-bindings: interrupt-controller: Add RISC-V incoming MSI controller
  irqchip: Add RISC-V incoming MSI controller early driver
  irqchip/riscv-imsic: Add device MSI domain support for platform
    devices
  irqchip/riscv-imsic: Add device MSI domain support for PCI devices
  dt-bindings: interrupt-controller: Add RISC-V advanced PLIC
  irqchip: Add RISC-V advanced PLIC driver for direct-mode
  irqchip/riscv-aplic: Add support for MSI-mode
  RISC-V: Select APLIC and IMSIC drivers
  MAINTAINERS: Add entry for RISC-V AIA drivers

 .../interrupt-controller/riscv,aplic.yaml     | 172 ++++
 .../interrupt-controller/riscv,imsics.yaml    | 172 ++++
 MAINTAINERS                                   |  14 +
 arch/riscv/Kconfig                            |   2 +
 drivers/irqchip/Kconfig                       |  25 +
 drivers/irqchip/Makefile                      |   3 +
 drivers/irqchip/irq-riscv-aplic-direct.c      | 326 +++++++
 drivers/irqchip/irq-riscv-aplic-main.c        | 211 +++++
 drivers/irqchip/irq-riscv-aplic-main.h        |  52 ++
 drivers/irqchip/irq-riscv-aplic-msi.c         | 263 ++++++
 drivers/irqchip/irq-riscv-imsic-early.c       | 201 ++++
 drivers/irqchip/irq-riscv-imsic-platform.c    | 374 ++++++++
 drivers/irqchip/irq-riscv-imsic-state.c       | 865 ++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.h       | 108 +++
 drivers/irqchip/irq-riscv-intc.c              |  10 +-
 include/linux/cpuhotplug.h                    |   1 +
 include/linux/irqchip/riscv-aplic.h           | 145 +++
 include/linux/irqchip/riscv-imsic.h           |  87 ++
 18 files changed, 3028 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
 create mode 100644 drivers/irqchip/irq-riscv-aplic-direct.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.h
 create mode 100644 drivers/irqchip/irq-riscv-aplic-msi.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-early.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.h
 create mode 100644 include/linux/irqchip/riscv-aplic.h
 create mode 100644 include/linux/irqchip/riscv-imsic.h

-- 
2.34.1



From apatel at ventanamicro.com  Sun Feb 25 20:07:37 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:37 +0530
Subject: [PATCH v15 01/10] irqchip/riscv-intc: Fix low-level interrupt handler setup for AIA
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <20240226040746.1396416-2-apatel@ventanamicro.com>

Use riscv_intc_aia_irq() as the low-level interrupt handler and print
"using AIA" in the INTC boot banner when AIA is available.

Fixes: c1be2ae5987a ("irqchip/riscv-intc: Add support for RISC-V AIA")
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-intc.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
index cccb65339982..f87aeab460eb 100644
--- a/drivers/irqchip/irq-riscv-intc.c
+++ b/drivers/irqchip/irq-riscv-intc.c
@@ -183,7 +183,10 @@ static int __init riscv_intc_init_common(struct fwnode_handle *fn, struct irq_ch
 		return -ENXIO;
 	}
 
-	rc = set_handle_irq(&riscv_intc_irq);
+	if (riscv_isa_extension_available(NULL, SxAIA))
+		rc = set_handle_irq(&riscv_intc_aia_irq);
+	else
+		rc = set_handle_irq(&riscv_intc_irq);
 	if (rc) {
 		pr_err("failed to set irq handler\n");
 		return rc;
@@ -191,8 +194,9 @@ static int __init riscv_intc_init_common(struct fwnode_handle *fn, struct irq_ch
 
 	riscv_set_intc_hwnode_fn(riscv_intc_hwnode);
 
-	pr_info("%d local interrupts mapped\n",
-		riscv_isa_extension_available(NULL, SxAIA) ? 64 : riscv_intc_nr_irqs);
+	pr_info("%d local interrupts mapped%s\n",
+		riscv_isa_extension_available(NULL, SxAIA) ? 64 : riscv_intc_nr_irqs,
+		riscv_isa_extension_available(NULL, SxAIA) ? " using AIA" : "");
 	if (riscv_intc_custom_nr_irqs)
 		pr_info("%d custom local interrupts mapped\n", riscv_intc_custom_nr_irqs);
 
-- 
2.34.1



From apatel at ventanamicro.com  Sun Feb 25 20:07:38 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:38 +0530
Subject: [PATCH v15 02/10] dt-bindings: interrupt-controller: Add RISC-V incoming MSI controller
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <20240226040746.1396416-3-apatel@ventanamicro.com>

Add DT bindings document for the RISC-V incoming MSI controller (IMSIC)
defined by the RISC-V advanced interrupt architecture (AIA) specification.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../interrupt-controller/riscv,imsics.yaml    | 172 ++++++++++++++++++
 1 file changed, 172 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml b/Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
new file mode 100644
index 000000000000..84976f17a4a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
@@ -0,0 +1,172 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/riscv,imsics.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Incoming MSI Controller (IMSIC)
+
+maintainers:
+  - Anup Patel <anup at brainfault.org>
+
+description: |
+  The RISC-V advanced interrupt architecture (AIA) defines a per-CPU incoming
+  MSI controller (IMSIC) for handling MSIs in a RISC-V platform. The RISC-V
+  AIA specification can be found at https://github.com/riscv/riscv-aia.
+
+  The IMSIC is a per-CPU (or per-HART) device with separate interrupt file
+  for each privilege level (machine or supervisor). The configuration of
+  a IMSIC interrupt file is done using AIA CSRs and it also has a 4KB MMIO
+  space to receive MSIs from devices. Each IMSIC interrupt file supports a
+  fixed number of interrupt identities (to distinguish MSIs from devices)
+  which is same for given privilege level across CPUs (or HARTs).
+
+  The device tree of a RISC-V platform will have one IMSIC device tree node
+  for each privilege level (machine or supervisor) which collectively describe
+  IMSIC interrupt files at that privilege level across CPUs (or HARTs).
+
+  The arrangement of IMSIC interrupt files in MMIO space of a RISC-V platform
+  follows a particular scheme defined by the RISC-V AIA specification. A IMSIC
+  group is a set of IMSIC interrupt files co-located in MMIO space and we can
+  have multiple IMSIC groups (i.e. clusters, sockets, chiplets, etc) in a
+  RISC-V platform. The MSI target address of a IMSIC interrupt file at given
+  privilege level (machine or supervisor) encodes group index, HART index,
+  and guest index (shown below).
+
+  XLEN-1            > (HART Index MSB)                  12    0
+  |                  |                                  |     |
+  -------------------------------------------------------------
+  |xxxxxx|Group Index|xxxxxxxxxxx|HART Index|Guest Index|  0  |
+  -------------------------------------------------------------
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+  - $ref: /schemas/interrupt-controller/msi-controller.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - qemu,imsics
+      - const: riscv,imsics
+
+  reg:
+    minItems: 1
+    maxItems: 16384
+    description:
+      Base address of each IMSIC group.
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 0
+
+  msi-controller: true
+
+  "#msi-cells":
+    const: 0
+
+  interrupts-extended:
+    minItems: 1
+    maxItems: 16384
+    description:
+      This property represents the set of CPUs (or HARTs) for which given
+      device tree node describes the IMSIC interrupt files. Each node pointed
+      to should be a riscv,cpu-intc node, which has a CPU node (i.e. RISC-V
+      HART) as parent.
+
+  riscv,num-ids:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 63
+    maximum: 2047
+    description:
+      Number of interrupt identities supported by IMSIC interrupt file.
+
+  riscv,num-guest-ids:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 63
+    maximum: 2047
+    description:
+      Number of interrupt identities are supported by IMSIC guest interrupt
+      file. When not specified it is assumed to be same as specified by the
+      riscv,num-ids property.
+
+  riscv,guest-index-bits:
+    minimum: 0
+    maximum: 7
+    default: 0
+    description:
+      Number of guest index bits in the MSI target address.
+
+  riscv,hart-index-bits:
+    minimum: 0
+    maximum: 15
+    description:
+      Number of HART index bits in the MSI target address. When not
+      specified it is calculated based on the interrupts-extended property.
+
+  riscv,group-index-bits:
+    minimum: 0
+    maximum: 7
+    default: 0
+    description:
+      Number of group index bits in the MSI target address.
+
+  riscv,group-index-shift:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 55
+    default: 24
+    description:
+      The least significant bit position of the group index bits in the
+      MSI target address.
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - msi-controller
+  - "#msi-cells"
+  - interrupts-extended
+  - riscv,num-ids
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    // Example 1 (Machine-level IMSIC files with just one group):
+
+    interrupt-controller at 24000000 {
+      compatible = "qemu,imsics", "riscv,imsics";
+      interrupts-extended = <&cpu1_intc 11>,
+                            <&cpu2_intc 11>,
+                            <&cpu3_intc 11>,
+                            <&cpu4_intc 11>;
+      reg = <0x28000000 0x4000>;
+      interrupt-controller;
+      #interrupt-cells = <0>;
+      msi-controller;
+      #msi-cells = <0>;
+      riscv,num-ids = <127>;
+    };
+
+  - |
+    // Example 2 (Supervisor-level IMSIC files with two groups):
+
+    interrupt-controller at 28000000 {
+      compatible = "qemu,imsics", "riscv,imsics";
+      interrupts-extended = <&cpu1_intc 9>,
+                            <&cpu2_intc 9>,
+                            <&cpu3_intc 9>,
+                            <&cpu4_intc 9>;
+      reg = <0x28000000 0x2000>, /* Group0 IMSICs */
+            <0x29000000 0x2000>; /* Group1 IMSICs */
+      interrupt-controller;
+      #interrupt-cells = <0>;
+      msi-controller;
+      #msi-cells = <0>;
+      riscv,num-ids = <127>;
+      riscv,group-index-bits = <1>;
+      riscv,group-index-shift = <24>;
+    };
+...
-- 
2.34.1



From apatel at ventanamicro.com  Sun Feb 25 20:07:39 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:39 +0530
Subject: [PATCH v15 03/10] irqchip: Add RISC-V incoming MSI controller early driver
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <20240226040746.1396416-4-apatel@ventanamicro.com>

The RISC-V advanced interrupt architecture (AIA) specification
defines a new MSI controller called incoming message signalled
interrupt controller (IMSIC) which manages MSI on per-HART (or
per-CPU) basis. It also supports IPIs as software injected MSIs.
(For more details refer https://github.com/riscv/riscv-aia)

Add an early irqchip driver for RISC-V IMSIC which sets up the
IMSIC state and provide IPIs.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                 |   7 +
 drivers/irqchip/Makefile                |   1 +
 drivers/irqchip/irq-riscv-imsic-early.c | 201 ++++++
 drivers/irqchip/irq-riscv-imsic-state.c | 865 ++++++++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.h | 107 +++
 include/linux/cpuhotplug.h              |   1 +
 include/linux/irqchip/riscv-imsic.h     |  87 +++
 7 files changed, 1269 insertions(+)
 create mode 100644 drivers/irqchip/irq-riscv-imsic-early.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.c
 create mode 100644 drivers/irqchip/irq-riscv-imsic-state.h
 create mode 100644 include/linux/irqchip/riscv-imsic.h

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index f7149d0f3d45..85f86e31c996 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -546,6 +546,13 @@ config SIFIVE_PLIC
 	select IRQ_DOMAIN_HIERARCHY
 	select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
 
+config RISCV_IMSIC
+	bool
+	depends on RISCV
+	select IRQ_DOMAIN_HIERARCHY
+	select GENERIC_IRQ_MATRIX_ALLOCATOR
+	select GENERIC_MSI_IRQ
+
 config EXYNOS_IRQ_COMBINER
 	bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
 	depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index ffd945fe71aa..d714724387ce 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
 obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
+obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
 obj-$(CONFIG_IMX_INTMUX)		+= irq-imx-intmux.o
diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
new file mode 100644
index 000000000000..886418ec06cb
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "riscv-imsic: " fmt
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-imsic-state.h"
+
+static int imsic_parent_irq;
+
+#ifdef CONFIG_SMP
+static void imsic_ipi_send(unsigned int cpu)
+{
+	struct imsic_local_config *local = per_cpu_ptr(imsic->global.local, cpu);
+
+	writel_relaxed(IMSIC_IPI_ID, local->msi_va);
+}
+
+static void imsic_ipi_starting_cpu(void)
+{
+	/* Enable IPIs for current CPU. */
+	__imsic_id_set_enable(IMSIC_IPI_ID);
+}
+
+static void imsic_ipi_dying_cpu(void)
+{
+	/* Disable IPIs for current CPU. */
+	__imsic_id_clear_enable(IMSIC_IPI_ID);
+}
+
+static int __init imsic_ipi_domain_init(void)
+{
+	int virq;
+
+	/* Create IMSIC IPI multiplexing */
+	virq = ipi_mux_create(IMSIC_NR_IPI, imsic_ipi_send);
+	if (virq <= 0)
+		return virq < 0 ? virq : -ENOMEM;
+
+	/* Set vIRQ range */
+	riscv_ipi_set_virq_range(virq, IMSIC_NR_IPI, true);
+
+	/* Announce that IMSIC is providing IPIs */
+	pr_info("%pfwP: providing IPIs using interrupt %d\n", imsic->fwnode, IMSIC_IPI_ID);
+
+	return 0;
+}
+#else
+static void imsic_ipi_starting_cpu(void) { }
+static void imsic_ipi_dying_cpu(void) { }
+static int __init imsic_ipi_domain_init(void) { return 0; }
+#endif
+
+/*
+ * To handle an interrupt, we read the TOPEI CSR and write zero in one
+ * instruction. If TOPEI CSR is non-zero then we translate TOPEI.ID to
+ * Linux interrupt number and let Linux IRQ subsystem handle it.
+ */
+static void imsic_handle_irq(struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int err, cpu = smp_processor_id();
+	struct imsic_vector *vec;
+	unsigned long local_id;
+
+	chained_irq_enter(chip, desc);
+
+	while ((local_id = csr_swap(CSR_TOPEI, 0))) {
+		local_id >>= TOPEI_ID_SHIFT;
+
+		if (local_id == IMSIC_IPI_ID) {
+			if (IS_ENABLED(CONFIG_SMP))
+				ipi_mux_process();
+			continue;
+		}
+
+		if (unlikely(!imsic->base_domain))
+			continue;
+
+		vec = imsic_vector_from_local_id(cpu, local_id);
+		if (!vec) {
+			pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id);
+			continue;
+		}
+
+		err = generic_handle_domain_irq(imsic->base_domain, vec->hwirq);
+		if (unlikely(err))
+			pr_warn_ratelimited("hwirq 0x%x mapping not found\n", vec->hwirq);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static int imsic_starting_cpu(unsigned int cpu)
+{
+	/* Mark per-CPU IMSIC state as online */
+	imsic_state_online();
+
+	/* Enable per-CPU parent interrupt */
+	enable_percpu_irq(imsic_parent_irq, irq_get_trigger_type(imsic_parent_irq));
+
+	/* Setup IPIs */
+	imsic_ipi_starting_cpu();
+
+	/*
+	 * Interrupts identities might have been enabled/disabled while
+	 * this CPU was not running so sync-up local enable/disable state.
+	 */
+	imsic_local_sync_all();
+
+	/* Enable local interrupt delivery */
+	imsic_local_delivery(true);
+
+	return 0;
+}
+
+static int imsic_dying_cpu(unsigned int cpu)
+{
+	/* Cleanup IPIs */
+	imsic_ipi_dying_cpu();
+
+	/* Mark per-CPU IMSIC state as offline */
+	imsic_state_offline();
+
+	return 0;
+}
+
+static int __init imsic_early_probe(struct fwnode_handle *fwnode)
+{
+	struct irq_domain *domain;
+	int rc;
+
+	/* Find parent domain and register chained handler */
+	domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS_ANY);
+	if (!domain) {
+		pr_err("%pfwP: Failed to find INTC domain\n", fwnode);
+		return -ENOENT;
+	}
+	imsic_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
+	if (!imsic_parent_irq) {
+		pr_err("%pfwP: Failed to create INTC mapping\n", fwnode);
+		return -ENOENT;
+	}
+
+	/* Initialize IPI domain */
+	rc = imsic_ipi_domain_init();
+	if (rc) {
+		pr_err("%pfwP: Failed to initialize IPI domain\n", fwnode);
+		return rc;
+	}
+
+	/* Setup chained handler to the parent domain interrupt */
+	irq_set_chained_handler(imsic_parent_irq, imsic_handle_irq);
+
+	/*
+	 * Setup cpuhp state (must be done after setting imsic_parent_irq)
+	 *
+	 * Don't disable per-CPU IMSIC file when CPU goes offline
+	 * because this affects IPI and the masking/unmasking of
+	 * virtual IPIs is done via generic IPI-Mux
+	 */
+	cpuhp_setup_state(CPUHP_AP_IRQ_RISCV_IMSIC_STARTING, "irqchip/riscv/imsic:starting",
+			  imsic_starting_cpu, imsic_dying_cpu);
+
+	return 0;
+}
+
+static int __init imsic_early_dt_init(struct device_node *node, struct device_node *parent)
+{
+	struct fwnode_handle *fwnode = &node->fwnode;
+	int rc;
+
+	/* Setup IMSIC state */
+	rc = imsic_setup_state(fwnode);
+	if (rc) {
+		pr_err("%pfwP: failed to setup state (error %d)\n", fwnode, rc);
+		return rc;
+	}
+
+	/* Do early setup of IPIs */
+	rc = imsic_early_probe(fwnode);
+	if (rc)
+		return rc;
+
+	/* Ensure that OF platform device gets probed */
+	of_node_clear_flag(node, OF_POPULATED);
+	return 0;
+}
+
+IRQCHIP_DECLARE(riscv_imsic, "riscv,imsics", imsic_early_dt_init);
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
new file mode 100644
index 000000000000..5479f872e62b
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "riscv-imsic: " fmt
+#include <linux/cpu.h>
+#include <linux/bitmap.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <asm/hwcap.h>
+
+#include "irq-riscv-imsic-state.h"
+
+#define IMSIC_DISABLE_EIDELIVERY		0
+#define IMSIC_ENABLE_EIDELIVERY			1
+#define IMSIC_DISABLE_EITHRESHOLD		1
+#define IMSIC_ENABLE_EITHRESHOLD		0
+
+static inline void imsic_csr_write(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	csr_write(CSR_IREG, val);
+}
+
+static inline unsigned long imsic_csr_read(unsigned long reg)
+{
+	csr_write(CSR_ISELECT, reg);
+	return csr_read(CSR_IREG);
+}
+
+static inline unsigned long imsic_csr_read_clear(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	return csr_read_clear(CSR_IREG, val);
+}
+
+static inline void imsic_csr_set(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	csr_set(CSR_IREG, val);
+}
+
+static inline void imsic_csr_clear(unsigned long reg, unsigned long val)
+{
+	csr_write(CSR_ISELECT, reg);
+	csr_clear(CSR_IREG, val);
+}
+
+struct imsic_priv *imsic;
+
+const struct imsic_global_config *imsic_get_global_config(void)
+{
+	return imsic ? &imsic->global : NULL;
+}
+EXPORT_SYMBOL_GPL(imsic_get_global_config);
+
+static bool __imsic_eix_read_clear(unsigned long id, bool pend)
+{
+	unsigned long isel, imask;
+
+	isel = id / BITS_PER_LONG;
+	isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
+	isel += pend ? IMSIC_EIP0 : IMSIC_EIE0;
+	imask = BIT(id & (__riscv_xlen - 1));
+
+	return !!(imsic_csr_read_clear(isel, imask) & imask);
+}
+
+static inline bool __imsic_id_read_clear_enabled(unsigned long id)
+{
+	return __imsic_eix_read_clear(id, false);
+}
+
+static inline bool __imsic_id_read_clear_pending(unsigned long id)
+{
+	return __imsic_eix_read_clear(id, true);
+}
+
+void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val)
+{
+	unsigned long id = base_id, last_id = base_id + num_id;
+	unsigned long i, isel, ireg;
+
+	while (id < last_id) {
+		isel = id / BITS_PER_LONG;
+		isel *= BITS_PER_LONG / IMSIC_EIPx_BITS;
+		isel += pend ? IMSIC_EIP0 : IMSIC_EIE0;
+
+		/*
+		 * Prepare the ID mask to be programmed in the
+		 * IMSIC EIEx and EIPx registers. These registers
+		 * are XLEN-wide and we must not touch IDs which
+		 * are < base_id and >= (base_id + num_id).
+		 */
+		ireg = 0;
+		for (i = id & (__riscv_xlen - 1); id < last_id && i < __riscv_xlen; i++) {
+			ireg |= BIT(i);
+			id++;
+		}
+
+		/*
+		 * The IMSIC EIEx and EIPx registers are indirectly
+		 * accessed via using ISELECT and IREG CSRs so we
+		 * need to access these CSRs without getting preempted.
+		 *
+		 * All existing users of this function call this
+		 * function with local IRQs disabled so we don't
+		 * need to do anything special here.
+		 */
+		if (val)
+			imsic_csr_set(isel, ireg);
+		else
+			imsic_csr_clear(isel, ireg);
+	}
+}
+
+static void __imsic_local_sync(struct imsic_local_priv *lpriv)
+{
+	struct imsic_local_config *mlocal;
+	struct imsic_vector *vec, *mvec;
+	int i;
+
+	lockdep_assert_held(&lpriv->lock);
+
+	for_each_set_bit(i, lpriv->dirty_bitmap, imsic->global.nr_ids + 1) {
+		if (!i || i == IMSIC_IPI_ID)
+			goto skip;
+		vec = &lpriv->vectors[i];
+
+		if (READ_ONCE(vec->enable))
+			__imsic_id_set_enable(i);
+		else
+			__imsic_id_clear_enable(i);
+
+		/*
+		 * If the ID was being moved to a new ID on some other CPU
+		 * then we can get a MSI during the movement so check the
+		 * ID pending bit and re-trigger the new ID on other CPU
+		 * using MMIO write.
+		 */
+		mvec = READ_ONCE(vec->move);
+		WRITE_ONCE(vec->move, NULL);
+		if (mvec && mvec != vec) {
+			if (__imsic_id_read_clear_pending(i)) {
+				mlocal = per_cpu_ptr(imsic->global.local, mvec->cpu);
+				writel_relaxed(mvec->local_id, mlocal->msi_va);
+			}
+
+			imsic_vector_free(&lpriv->vectors[i]);
+		}
+
+skip:
+		bitmap_clear(lpriv->dirty_bitmap, i, 1);
+	}
+}
+
+void imsic_local_sync_all(void)
+{
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
+	__imsic_local_sync(lpriv);
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+}
+
+void imsic_local_delivery(bool enable)
+{
+	if (enable) {
+		imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD);
+		imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
+		return;
+	}
+
+	imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY);
+	imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD);
+}
+
+#ifdef CONFIG_SMP
+static void imsic_local_timer_callback(struct timer_list *timer)
+{
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	__imsic_local_sync(lpriv);
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+}
+
+static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
+{
+	lockdep_assert_held(&lpriv->lock);
+
+	/*
+	 * The spinlock acquire/release semantics ensure that changes
+	 * to vector enable, vector move and dirty bitmap are visible
+	 * to the target CPU.
+	 */
+
+	/*
+	 * We schedule a timer on the target CPU if the target CPU is not
+	 * same as the current CPU. An offline CPU will unconditionally
+	 * synchronize IDs through imsic_starting_cpu() when the
+	 * CPU is brought up.
+	 */
+	if (cpu_online(cpu)) {
+		if (cpu == smp_processor_id()) {
+			__imsic_local_sync(lpriv);
+			return;
+		}
+
+		if (!timer_pending(&lpriv->timer)) {
+			lpriv->timer.expires = jiffies + 1;
+			add_timer_on(&lpriv->timer, cpu);
+		}
+	}
+}
+#else
+static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu)
+{
+	lockdep_assert_held(&lpriv->lock);
+	__imsic_local_sync(lpriv);
+}
+#endif
+
+void imsic_vector_mask(struct imsic_vector *vec)
+{
+	struct imsic_local_priv *lpriv;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
+		return;
+
+	/*
+	 * This function is called through Linux irq subsystem with
+	 * irqs disabled so no need to save/restore irq flags.
+	 */
+
+	raw_spin_lock(&lpriv->lock);
+
+	WRITE_ONCE(vec->enable, false);
+	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
+	__imsic_remote_sync(lpriv, vec->cpu);
+
+	raw_spin_unlock(&lpriv->lock);
+}
+
+void imsic_vector_unmask(struct imsic_vector *vec)
+{
+	struct imsic_local_priv *lpriv;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
+		return;
+
+	/*
+	 * This function is called through Linux irq subsystem with
+	 * irqs disabled so no need to save/restore irq flags.
+	 */
+
+	raw_spin_lock(&lpriv->lock);
+
+	WRITE_ONCE(vec->enable, true);
+	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
+	__imsic_remote_sync(lpriv, vec->cpu);
+
+	raw_spin_unlock(&lpriv->lock);
+}
+
+static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, struct imsic_vector *vec,
+				     bool new_enable, struct imsic_vector *new_move)
+{
+	unsigned long flags;
+	bool enabled;
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+
+	/* Update enable and move details */
+	enabled = READ_ONCE(vec->enable);
+	WRITE_ONCE(vec->enable, new_enable);
+	WRITE_ONCE(vec->move, new_move);
+
+	/* Mark the vector as dirty and synchronize */
+	bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1);
+	__imsic_remote_sync(lpriv, vec->cpu);
+
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+
+	return enabled;
+}
+
+void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec)
+{
+	struct imsic_local_priv *old_lpriv, *new_lpriv;
+	bool enabled;
+
+	if (WARN_ON_ONCE(old_vec->cpu == new_vec->cpu))
+		return;
+
+	old_lpriv = per_cpu_ptr(imsic->lpriv, old_vec->cpu);
+	if (WARN_ON_ONCE(&old_lpriv->vectors[old_vec->local_id] != old_vec))
+		return;
+
+	new_lpriv = per_cpu_ptr(imsic->lpriv, new_vec->cpu);
+	if (WARN_ON_ONCE(&new_lpriv->vectors[new_vec->local_id] != new_vec))
+		return;
+
+	/*
+	 * Move and re-trigger the new vector based on the pending
+	 * state of the old vector because we might get a device
+	 * interrupt on the old vector while device was being moved
+	 * to the new vector.
+	 */
+	enabled = imsic_vector_move_update(old_lpriv, old_vec, false, new_vec);
+	imsic_vector_move_update(new_lpriv, new_vec, enabled, new_vec);
+}
+
+#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
+void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind)
+{
+	struct imsic_local_priv *lpriv;
+	struct imsic_vector *mvec;
+	bool is_enabled;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, vec->cpu);
+	if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] != vec))
+		return;
+
+	is_enabled = imsic_vector_isenabled(vec);
+	mvec = imsic_vector_get_move(vec);
+
+	seq_printf(m, "%*starget_cpu      : %5u\n", ind, "", vec->cpu);
+	seq_printf(m, "%*starget_local_id : %5u\n", ind, "", vec->local_id);
+	seq_printf(m, "%*sis_reserved     : %5u\n", ind, "",
+		   (vec->local_id <= IMSIC_IPI_ID) ? 1 : 0);
+	seq_printf(m, "%*sis_enabled      : %5u\n", ind, "", is_enabled ? 1 : 0);
+	seq_printf(m, "%*sis_move_pending : %5u\n", ind, "", mvec ? 1 : 0);
+	if (mvec) {
+		seq_printf(m, "%*smove_cpu        : %5u\n", ind, "", mvec->cpu);
+		seq_printf(m, "%*smove_local_id   : %5u\n", ind, "", mvec->local_id);
+	}
+}
+
+void imsic_vector_debug_show_summary(struct seq_file *m, int ind)
+{
+	irq_matrix_debug_show(m, imsic->matrix, ind);
+}
+#endif
+
+struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id)
+{
+	struct imsic_local_priv *lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+
+	if (!lpriv || imsic->global.nr_ids < local_id)
+		return NULL;
+
+	return &lpriv->vectors[local_id];
+}
+
+struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask)
+{
+	struct imsic_vector *vec = NULL;
+	struct imsic_local_priv *lpriv;
+	unsigned long flags;
+	unsigned int cpu;
+	int local_id;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	local_id = irq_matrix_alloc(imsic->matrix, mask, false, &cpu);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+	if (local_id < 0)
+		return NULL;
+
+	lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+	vec = &lpriv->vectors[local_id];
+	vec->hwirq = hwirq;
+	vec->enable = false;
+	vec->move = NULL;
+
+	return vec;
+}
+
+void imsic_vector_free(struct imsic_vector *vec)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	vec->hwirq = UINT_MAX;
+	irq_matrix_free(imsic->matrix, vec->cpu, vec->local_id, false);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+}
+
+static void __init imsic_local_cleanup(void)
+{
+	struct imsic_local_priv *lpriv;
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+
+		bitmap_free(lpriv->dirty_bitmap);
+		kfree(lpriv->vectors);
+	}
+
+	free_percpu(imsic->lpriv);
+}
+
+static int __init imsic_local_init(void)
+{
+	struct imsic_global_config *global = &imsic->global;
+	struct imsic_local_priv *lpriv;
+	struct imsic_vector *vec;
+	int cpu, i;
+
+	/* Allocate per-CPU private state */
+	imsic->lpriv = alloc_percpu(typeof(*imsic->lpriv));
+	if (!imsic->lpriv)
+		return -ENOMEM;
+
+	/* Setup per-CPU private state */
+	for_each_possible_cpu(cpu) {
+		lpriv = per_cpu_ptr(imsic->lpriv, cpu);
+
+		raw_spin_lock_init(&lpriv->lock);
+
+		/* Allocate dirty bitmap */
+		lpriv->dirty_bitmap = bitmap_zalloc(global->nr_ids + 1, GFP_KERNEL);
+		if (!lpriv->dirty_bitmap)
+			goto fail_local_cleanup;
+
+#ifdef CONFIG_SMP
+		/* Setup lazy timer for synchronization */
+		timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED);
+#endif
+
+		/* Allocate vector array */
+		lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors),
+					 GFP_KERNEL);
+		if (!lpriv->vectors)
+			goto fail_local_cleanup;
+
+		/* Setup vector array */
+		for (i = 0; i <= global->nr_ids; i++) {
+			vec = &lpriv->vectors[i];
+			vec->cpu = cpu;
+			vec->local_id = i;
+			vec->hwirq = UINT_MAX;
+		}
+	}
+
+	return 0;
+
+fail_local_cleanup:
+	imsic_local_cleanup();
+	return -ENOMEM;
+}
+
+void imsic_state_online(void)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	irq_matrix_online(imsic->matrix);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+}
+
+void imsic_state_offline(void)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&imsic->matrix_lock, flags);
+	irq_matrix_offline(imsic->matrix);
+	raw_spin_unlock_irqrestore(&imsic->matrix_lock, flags);
+
+#ifdef CONFIG_SMP
+	struct imsic_local_priv *lpriv = this_cpu_ptr(imsic->lpriv);
+
+	raw_spin_lock_irqsave(&lpriv->lock, flags);
+	WARN_ON_ONCE(try_to_del_timer_sync(&lpriv->timer) < 0);
+	raw_spin_unlock_irqrestore(&lpriv->lock, flags);
+#endif
+}
+
+static int __init imsic_matrix_init(void)
+{
+	struct imsic_global_config *global = &imsic->global;
+
+	raw_spin_lock_init(&imsic->matrix_lock);
+	imsic->matrix = irq_alloc_matrix(global->nr_ids + 1,
+					 0, global->nr_ids + 1);
+	if (!imsic->matrix)
+		return -ENOMEM;
+
+	/* Reserve ID#0 because it is special and never implemented */
+	irq_matrix_assign_system(imsic->matrix, 0, false);
+
+	/* Reserve IPI ID because it is special and used internally */
+	irq_matrix_assign_system(imsic->matrix, IMSIC_IPI_ID, false);
+
+	return 0;
+}
+
+static int __init imsic_get_parent_hartid(struct fwnode_handle *fwnode,
+					  u32 index, unsigned long *hartid)
+{
+	struct of_phandle_args parent;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(fwnode))
+		return -EINVAL;
+
+	rc = of_irq_parse_one(to_of_node(fwnode), index, &parent);
+	if (rc)
+		return rc;
+
+	/*
+	 * Skip interrupts other than external interrupts for
+	 * current privilege level.
+	 */
+	if (parent.args[0] != RV_IRQ_EXT)
+		return -EINVAL;
+
+	return riscv_of_parent_hartid(parent.np, hartid);
+}
+
+static int __init imsic_get_mmio_resource(struct fwnode_handle *fwnode,
+					  u32 index, struct resource *res)
+{
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(fwnode))
+		return -EINVAL;
+
+	return of_address_to_resource(to_of_node(fwnode), index, res);
+}
+
+static int __init imsic_parse_fwnode(struct fwnode_handle *fwnode,
+				     struct imsic_global_config *global,
+				     u32 *nr_parent_irqs,
+				     u32 *nr_mmios)
+{
+	unsigned long hartid;
+	struct resource res;
+	int rc;
+	u32 i;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(fwnode))
+		return -EINVAL;
+
+	*nr_parent_irqs = 0;
+	*nr_mmios = 0;
+
+	/* Find number of parent interrupts */
+	while (!imsic_get_parent_hartid(fwnode, *nr_parent_irqs, &hartid))
+		(*nr_parent_irqs)++;
+	if (!*nr_parent_irqs) {
+		pr_err("%pfwP: no parent irqs available\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Find number of guest index bits in MSI address */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,guest-index-bits",
+				  &global->guest_index_bits);
+	if (rc)
+		global->guest_index_bits = 0;
+
+	/* Find number of HART index bits */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,hart-index-bits",
+				  &global->hart_index_bits);
+	if (rc) {
+		/* Assume default value */
+		global->hart_index_bits = __fls(*nr_parent_irqs);
+		if (BIT(global->hart_index_bits) < *nr_parent_irqs)
+			global->hart_index_bits++;
+	}
+
+	/* Find number of group index bits */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-bits",
+				  &global->group_index_bits);
+	if (rc)
+		global->group_index_bits = 0;
+
+	/*
+	 * Find first bit position of group index.
+	 * If not specified assumed the default APLIC-IMSIC configuration.
+	 */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,group-index-shift",
+				  &global->group_index_shift);
+	if (rc)
+		global->group_index_shift = IMSIC_MMIO_PAGE_SHIFT * 2;
+
+	/* Find number of interrupt identities */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-ids",
+				  &global->nr_ids);
+	if (rc) {
+		pr_err("%pfwP: number of interrupt identities not found\n", fwnode);
+		return rc;
+	}
+
+	/* Find number of guest interrupt identities */
+	rc = of_property_read_u32(to_of_node(fwnode), "riscv,num-guest-ids",
+				  &global->nr_guest_ids);
+	if (rc)
+		global->nr_guest_ids = global->nr_ids;
+
+	/* Sanity check guest index bits */
+	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT;
+	if (i < global->guest_index_bits) {
+		pr_err("%pfwP: guest index bits too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check HART index bits */
+	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT - global->guest_index_bits;
+	if (i < global->hart_index_bits) {
+		pr_err("%pfwP: HART index bits too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check group index bits */
+	i = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
+	    global->guest_index_bits - global->hart_index_bits;
+	if (i < global->group_index_bits) {
+		pr_err("%pfwP: group index bits too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check group index shift */
+	i = global->group_index_bits + global->group_index_shift - 1;
+	if (i >= BITS_PER_LONG) {
+		pr_err("%pfwP: group index shift too big\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check number of interrupt identities */
+	if (global->nr_ids < IMSIC_MIN_ID ||
+	    global->nr_ids >= IMSIC_MAX_ID ||
+	    (global->nr_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID) {
+		pr_err("%pfwP: invalid number of interrupt identities\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Sanity check number of guest interrupt identities */
+	if (global->nr_guest_ids < IMSIC_MIN_ID ||
+	    global->nr_guest_ids >= IMSIC_MAX_ID ||
+	    (global->nr_guest_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID) {
+		pr_err("%pfwP: invalid number of guest interrupt identities\n", fwnode);
+		return -EINVAL;
+	}
+
+	/* Compute base address */
+	rc = imsic_get_mmio_resource(fwnode, 0, &res);
+	if (rc) {
+		pr_err("%pfwP: first MMIO resource not found\n", fwnode);
+		return -EINVAL;
+	}
+	global->base_addr = res.start;
+	global->base_addr &= ~(BIT(global->guest_index_bits +
+				   global->hart_index_bits +
+				   IMSIC_MMIO_PAGE_SHIFT) - 1);
+	global->base_addr &= ~((BIT(global->group_index_bits) - 1) <<
+			       global->group_index_shift);
+
+	/* Find number of MMIO register sets */
+	while (!imsic_get_mmio_resource(fwnode, *nr_mmios, &res))
+		(*nr_mmios)++;
+
+	return 0;
+}
+
+int __init imsic_setup_state(struct fwnode_handle *fwnode)
+{
+	u32 i, j, index, nr_parent_irqs, nr_mmios, nr_handlers = 0;
+	struct imsic_global_config *global;
+	struct imsic_local_config *local;
+	void __iomem **mmios_va = NULL;
+	struct resource *mmios = NULL;
+	unsigned long reloff, hartid;
+	phys_addr_t base_addr;
+	int rc, cpu;
+
+	/*
+	 * Only one IMSIC instance allowed in a platform for clean
+	 * implementation of SMP IRQ affinity and per-CPU IPIs.
+	 *
+	 * This means on a multi-socket (or multi-die) platform we
+	 * will have multiple MMIO regions for one IMSIC instance.
+	 */
+	if (imsic) {
+		pr_err("%pfwP: already initialized hence ignoring\n", fwnode);
+		return -EALREADY;
+	}
+
+	if (!riscv_isa_extension_available(NULL, SxAIA)) {
+		pr_err("%pfwP: AIA support not available\n", fwnode);
+		return -ENODEV;
+	}
+
+	imsic = kzalloc(sizeof(*imsic), GFP_KERNEL);
+	if (!imsic)
+		return -ENOMEM;
+	imsic->fwnode = fwnode;
+	global = &imsic->global;
+
+	global->local = alloc_percpu(typeof(*global->local));
+	if (!global->local) {
+		rc = -ENOMEM;
+		goto out_free_priv;
+	}
+
+	/* Parse IMSIC fwnode */
+	rc = imsic_parse_fwnode(fwnode, global, &nr_parent_irqs, &nr_mmios);
+	if (rc)
+		goto out_free_local;
+
+	/* Allocate MMIO resource array */
+	mmios = kcalloc(nr_mmios, sizeof(*mmios), GFP_KERNEL);
+	if (!mmios) {
+		rc = -ENOMEM;
+		goto out_free_local;
+	}
+
+	/* Allocate MMIO virtual address array */
+	mmios_va = kcalloc(nr_mmios, sizeof(*mmios_va), GFP_KERNEL);
+	if (!mmios_va) {
+		rc = -ENOMEM;
+		goto out_iounmap;
+	}
+
+	/* Parse and map MMIO register sets */
+	for (i = 0; i < nr_mmios; i++) {
+		rc = imsic_get_mmio_resource(fwnode, i, &mmios[i]);
+		if (rc) {
+			pr_err("%pfwP: unable to parse MMIO regset %d\n", fwnode, i);
+			goto out_iounmap;
+		}
+
+		base_addr = mmios[i].start;
+		base_addr &= ~(BIT(global->guest_index_bits +
+				   global->hart_index_bits +
+				   IMSIC_MMIO_PAGE_SHIFT) - 1);
+		base_addr &= ~((BIT(global->group_index_bits) - 1) <<
+			       global->group_index_shift);
+		if (base_addr != global->base_addr) {
+			rc = -EINVAL;
+			pr_err("%pfwP: address mismatch for regset %d\n", fwnode, i);
+			goto out_iounmap;
+		}
+
+		mmios_va[i] = ioremap(mmios[i].start, resource_size(&mmios[i]));
+		if (!mmios_va[i]) {
+			rc = -EIO;
+			pr_err("%pfwP: unable to map MMIO regset %d\n", fwnode, i);
+			goto out_iounmap;
+		}
+	}
+
+	/* Initialize local (or per-CPU )state */
+	rc = imsic_local_init();
+	if (rc) {
+		pr_err("%pfwP: failed to initialize local state\n",
+		       fwnode);
+		goto out_iounmap;
+	}
+
+	/* Configure handlers for target CPUs */
+	for (i = 0; i < nr_parent_irqs; i++) {
+		rc = imsic_get_parent_hartid(fwnode, i, &hartid);
+		if (rc) {
+			pr_warn("%pfwP: hart ID for parent irq%d not found\n", fwnode, i);
+			continue;
+		}
+
+		cpu = riscv_hartid_to_cpuid(hartid);
+		if (cpu < 0) {
+			pr_warn("%pfwP: invalid cpuid for parent irq%d\n", fwnode, i);
+			continue;
+		}
+
+		/* Find MMIO location of MSI page */
+		index = nr_mmios;
+		reloff = i * BIT(global->guest_index_bits) *
+			 IMSIC_MMIO_PAGE_SZ;
+		for (j = 0; nr_mmios; j++) {
+			if (reloff < resource_size(&mmios[j])) {
+				index = j;
+				break;
+			}
+
+			/*
+			 * MMIO region size may not be aligned to
+			 * BIT(global->guest_index_bits) * IMSIC_MMIO_PAGE_SZ
+			 * if holes are present.
+			 */
+			reloff -= ALIGN(resource_size(&mmios[j]),
+			BIT(global->guest_index_bits) * IMSIC_MMIO_PAGE_SZ);
+		}
+		if (index >= nr_mmios) {
+			pr_warn("%pfwP: MMIO not found for parent irq%d\n", fwnode, i);
+			continue;
+		}
+
+		local = per_cpu_ptr(global->local, cpu);
+		local->msi_pa = mmios[index].start + reloff;
+		local->msi_va = mmios_va[index] + reloff;
+
+		nr_handlers++;
+	}
+
+	/* If no CPU handlers found then can't take interrupts */
+	if (!nr_handlers) {
+		pr_err("%pfwP: No CPU handlers found\n", fwnode);
+		rc = -ENODEV;
+		goto out_local_cleanup;
+	}
+
+	/* Initialize matrix allocator */
+	rc = imsic_matrix_init();
+	if (rc) {
+		pr_err("%pfwP: failed to create matrix allocator\n", fwnode);
+		goto out_local_cleanup;
+	}
+
+	/* We don't need MMIO arrays anymore so let's free-up */
+	kfree(mmios_va);
+	kfree(mmios);
+
+	return 0;
+
+out_local_cleanup:
+	imsic_local_cleanup();
+out_iounmap:
+	for (i = 0; i < nr_mmios; i++) {
+		if (mmios_va[i])
+			iounmap(mmios_va[i]);
+	}
+	kfree(mmios_va);
+	kfree(mmios);
+out_free_local:
+	free_percpu(imsic->global.local);
+out_free_priv:
+	kfree(imsic);
+	imsic = NULL;
+	return rc;
+}
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
new file mode 100644
index 000000000000..8ec9649d0d01
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#ifndef _IRQ_RISCV_IMSIC_STATE_H
+#define _IRQ_RISCV_IMSIC_STATE_H
+
+#include <linux/irqchip/riscv-imsic.h>
+#include <linux/irqdomain.h>
+#include <linux/fwnode.h>
+#include <linux/timer.h>
+
+#define IMSIC_IPI_ID				1
+#define IMSIC_NR_IPI				8
+
+struct imsic_vector {
+	/* Fixed details of the vector */
+	unsigned int				cpu;
+	unsigned int				local_id;
+	/* Details saved by driver in the vector */
+	unsigned int				hwirq;
+	/* Details accessed using local lock held */
+	bool					enable;
+	struct imsic_vector			*move;
+};
+
+struct imsic_local_priv {
+	/* Local lock to protect vector enable/move variables and dirty bitmap */
+	raw_spinlock_t				lock;
+
+	/* Local dirty bitmap for synchronization */
+	unsigned long				*dirty_bitmap;
+
+#ifdef CONFIG_SMP
+	/* Local timer for synchronization */
+	struct timer_list			timer;
+#endif
+
+	/* Local vector table */
+	struct imsic_vector			*vectors;
+};
+
+struct imsic_priv {
+	/* Device details */
+	struct fwnode_handle			*fwnode;
+
+	/* Global configuration common for all HARTs */
+	struct imsic_global_config		global;
+
+	/* Per-CPU state */
+	struct imsic_local_priv __percpu	*lpriv;
+
+	/* State of IRQ matrix allocator */
+	raw_spinlock_t				matrix_lock;
+	struct irq_matrix			*matrix;
+
+	/* IRQ domains (created by platform driver) */
+	struct irq_domain			*base_domain;
+};
+
+extern struct imsic_priv *imsic;
+
+void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val);
+
+static inline void __imsic_id_set_enable(unsigned long id)
+{
+	__imsic_eix_update(id, 1, false, true);
+}
+
+static inline void __imsic_id_clear_enable(unsigned long id)
+{
+	__imsic_eix_update(id, 1, false, false);
+}
+
+void imsic_local_sync_all(void);
+void imsic_local_delivery(bool enable);
+
+void imsic_vector_mask(struct imsic_vector *vec);
+void imsic_vector_unmask(struct imsic_vector *vec);
+
+static inline bool imsic_vector_isenabled(struct imsic_vector *vec)
+{
+	return READ_ONCE(vec->enable);
+}
+
+static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec)
+{
+	return READ_ONCE(vec->move);
+}
+
+void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec);
+
+struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id);
+
+struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask);
+void imsic_vector_free(struct imsic_vector *vector);
+
+void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind);
+void imsic_vector_debug_show_summary(struct seq_file *m, int ind);
+
+void imsic_state_online(void);
+void imsic_state_offline(void);
+int imsic_setup_state(struct fwnode_handle *fwnode);
+
+#endif
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 172d0a743e5d..39d36183d9fc 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -146,6 +146,7 @@ enum cpuhp_state {
 	CPUHP_AP_IRQ_MIPS_GIC_STARTING,
 	CPUHP_AP_IRQ_LOONGARCH_STARTING,
 	CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
+	CPUHP_AP_IRQ_RISCV_IMSIC_STARTING,
 	CPUHP_AP_ARM_MVEBU_COHERENCY,
 	CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING,
 	CPUHP_AP_PERF_X86_STARTING,
diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
new file mode 100644
index 000000000000..faf0b800b1b0
--- /dev/null
+++ b/include/linux/irqchip/riscv-imsic.h
@@ -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.
+ */
+#ifndef __LINUX_IRQCHIP_RISCV_IMSIC_H
+#define __LINUX_IRQCHIP_RISCV_IMSIC_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <asm/csr.h>
+
+#define IMSIC_MMIO_PAGE_SHIFT		12
+#define IMSIC_MMIO_PAGE_SZ		BIT(IMSIC_MMIO_PAGE_SHIFT)
+#define IMSIC_MMIO_PAGE_LE		0x00
+#define IMSIC_MMIO_PAGE_BE		0x04
+
+#define IMSIC_MIN_ID			63
+#define IMSIC_MAX_ID			2048
+
+#define IMSIC_EIDELIVERY		0x70
+
+#define IMSIC_EITHRESHOLD		0x72
+
+#define IMSIC_EIP0			0x80
+#define IMSIC_EIP63			0xbf
+#define IMSIC_EIPx_BITS			32
+
+#define IMSIC_EIE0			0xc0
+#define IMSIC_EIE63			0xff
+#define IMSIC_EIEx_BITS			32
+
+#define IMSIC_FIRST			IMSIC_EIDELIVERY
+#define IMSIC_LAST			IMSIC_EIE63
+
+#define IMSIC_MMIO_SETIPNUM_LE		0x00
+#define IMSIC_MMIO_SETIPNUM_BE		0x04
+
+struct imsic_local_config {
+	phys_addr_t				msi_pa;
+	void __iomem				*msi_va;
+};
+
+struct imsic_global_config {
+	/*
+	 * MSI Target Address Scheme
+	 *
+	 * XLEN-1                                                12     0
+	 * |                                                     |     |
+	 * -------------------------------------------------------------
+	 * |xxxxxx|Group Index|xxxxxxxxxxx|HART Index|Guest Index|  0  |
+	 * -------------------------------------------------------------
+	 */
+
+	/* Bits representing Guest index, HART index, and Group index */
+	u32					guest_index_bits;
+	u32					hart_index_bits;
+	u32					group_index_bits;
+	u32					group_index_shift;
+
+	/* Global base address matching all target MSI addresses */
+	phys_addr_t				base_addr;
+
+	/* Number of interrupt identities */
+	u32					nr_ids;
+
+	/* Number of guest interrupt identities */
+	u32					nr_guest_ids;
+
+	/* Per-CPU IMSIC addresses */
+	struct imsic_local_config __percpu	*local;
+};
+
+#ifdef CONFIG_RISCV_IMSIC
+
+const struct imsic_global_config *imsic_get_global_config(void);
+
+#else
+
+static inline const struct imsic_global_config *imsic_get_global_config(void)
+{
+	return NULL;
+}
+
+#endif
+
+#endif
-- 
2.34.1



From apatel at ventanamicro.com  Sun Feb 25 20:07:40 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:40 +0530
Subject: [PATCH v15 04/10] irqchip/riscv-imsic: Add device MSI domain support for platform devices
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <20240226040746.1396416-5-apatel@ventanamicro.com>

The Linux platform MSI support allows per-device MSI domains so add
a platform irqchip driver for RISC-V IMSIC which provides a base IRQ
domain with MSI parent support for platform device domains.

The IMSIC platform driver assumes that the IMSIC state is already
initialized by the IMSIC early driver.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Makefile                   |   2 +-
 drivers/irqchip/irq-riscv-imsic-platform.c | 343 +++++++++++++++++++++
 drivers/irqchip/irq-riscv-imsic-state.h    |   1 +
 3 files changed, 345 insertions(+), 1 deletion(-)
 create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index d714724387ce..abca445a3229 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -95,7 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
 obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
-obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o
+obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
 obj-$(CONFIG_IMX_INTMUX)		+= irq-imx-intmux.o
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
new file mode 100644
index 000000000000..35291bf90d65
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "riscv-imsic: " fmt
+#include <linux/bitmap.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-imsic-state.h"
+
+static bool imsic_cpu_page_phys(unsigned int cpu, unsigned int guest_index,
+				phys_addr_t *out_msi_pa)
+{
+	struct imsic_global_config *global;
+	struct imsic_local_config *local;
+
+	global = &imsic->global;
+	local = per_cpu_ptr(global->local, cpu);
+
+	if (BIT(global->guest_index_bits) <= guest_index)
+		return false;
+
+	if (out_msi_pa)
+		*out_msi_pa = local->msi_pa + (guest_index * IMSIC_MMIO_PAGE_SZ);
+
+	return true;
+}
+
+static void imsic_irq_mask(struct irq_data *d)
+{
+	imsic_vector_mask(irq_data_get_irq_chip_data(d));
+}
+
+static void imsic_irq_unmask(struct irq_data *d)
+{
+	imsic_vector_unmask(irq_data_get_irq_chip_data(d));
+}
+
+static int imsic_irq_retrigger(struct irq_data *d)
+{
+	struct imsic_vector *vec = irq_data_get_irq_chip_data(d);
+	struct imsic_local_config *local;
+
+	if (WARN_ON(!vec))
+		return -ENOENT;
+
+	local = per_cpu_ptr(imsic->global.local, vec->cpu);
+	writel_relaxed(vec->local_id, local->msi_va);
+	return 0;
+}
+
+static void imsic_irq_compose_vector_msg(struct imsic_vector *vec, struct msi_msg *msg)
+{
+	phys_addr_t msi_addr;
+
+	if (WARN_ON(!vec))
+		return;
+
+	if (WARN_ON(!imsic_cpu_page_phys(vec->cpu, 0, &msi_addr)))
+		return;
+
+	msg->address_hi = upper_32_bits(msi_addr);
+	msg->address_lo = lower_32_bits(msi_addr);
+	msg->data = vec->local_id;
+}
+
+static void imsic_irq_compose_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	imsic_irq_compose_vector_msg(irq_data_get_irq_chip_data(d), msg);
+}
+
+#ifdef CONFIG_SMP
+static void imsic_msi_update_msg(struct irq_data *d, struct imsic_vector *vec)
+{
+	struct msi_msg msg = { };
+
+	imsic_irq_compose_vector_msg(vec, &msg);
+	irq_data_get_irq_chip(d)->irq_write_msi_msg(d, &msg);
+}
+
+static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+				  bool force)
+{
+	struct imsic_vector *old_vec, *new_vec;
+	struct irq_data *pd = d->parent_data;
+
+	old_vec = irq_data_get_irq_chip_data(pd);
+	if (WARN_ON(!old_vec))
+		return -ENOENT;
+
+	/* If old vector cpu belongs to the target cpumask then do nothing */
+	if (cpumask_test_cpu(old_vec->cpu, mask_val))
+		return IRQ_SET_MASK_OK_DONE;
+
+	/* If move is already in-flight then return failure */
+	if (imsic_vector_get_move(old_vec))
+		return -EBUSY;
+
+	/* Get a new vector on the desired set of CPUs */
+	new_vec = imsic_vector_alloc(old_vec->hwirq, mask_val);
+	if (!new_vec)
+		return -ENOSPC;
+
+	/* Point device to the new vector */
+	imsic_msi_update_msg(d, new_vec);
+
+	/* Update irq descriptors with the new vector */
+	pd->chip_data = new_vec;
+
+	/* Update effective affinity of parent irq data */
+	irq_data_update_effective_affinity(pd, cpumask_of(new_vec->cpu));
+
+	/* Move state of the old vector to the new vector */
+	imsic_vector_move(old_vec, new_vec);
+
+	return IRQ_SET_MASK_OK_DONE;
+}
+#endif
+
+static struct irq_chip imsic_irq_base_chip = {
+	.name			= "IMSIC",
+	.irq_mask		= imsic_irq_mask,
+	.irq_unmask		= imsic_irq_unmask,
+	.irq_retrigger		= imsic_irq_retrigger,
+	.irq_compose_msi_msg	= imsic_irq_compose_msg,
+	.flags			= IRQCHIP_SKIP_SET_WAKE |
+				  IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				  unsigned int nr_irqs, void *args)
+{
+	struct imsic_vector *vec;
+
+	/* Multi-MSI is not supported yet. */
+	if (nr_irqs > 1)
+		return -EOPNOTSUPP;
+
+	vec = imsic_vector_alloc(virq, cpu_online_mask);
+	if (!vec)
+		return -ENOSPC;
+
+	irq_domain_set_info(domain, virq, virq, &imsic_irq_base_chip, vec,
+			    handle_simple_irq, NULL, NULL);
+	irq_set_noprobe(virq);
+	irq_set_affinity(virq, cpu_online_mask);
+
+	return 0;
+}
+
+static void imsic_irq_domain_free(struct irq_domain *domain, unsigned int virq,
+				  unsigned int nr_irqs)
+{
+	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+
+	imsic_vector_free(irq_data_get_irq_chip_data(d));
+	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+}
+
+static int imsic_irq_domain_select(struct irq_domain *domain, struct irq_fwspec *fwspec,
+				   enum irq_domain_bus_token bus_token)
+{
+	const struct msi_parent_ops *ops = domain->msi_parent_ops;
+	u32 busmask = BIT(bus_token);
+
+	if (fwspec->fwnode != domain->fwnode || fwspec->param_count != 0)
+		return 0;
+
+	/* Handle pure domain searches */
+	if (bus_token == ops->bus_select_token)
+		return 1;
+
+	return !!(ops->bus_select_mask & busmask);
+}
+
+#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
+static void imsic_irq_debug_show(struct seq_file *m, struct irq_domain *d,
+				 struct irq_data *irqd, int ind)
+{
+	if (!irqd) {
+		imsic_vector_debug_show_summary(m, ind);
+		return;
+	}
+
+	imsic_vector_debug_show(m, irq_data_get_irq_chip_data(irqd), ind);
+}
+#endif
+
+static const struct irq_domain_ops imsic_base_domain_ops = {
+	.alloc		= imsic_irq_domain_alloc,
+	.free		= imsic_irq_domain_free,
+	.select		= imsic_irq_domain_select,
+#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
+	.debug_show	= imsic_irq_debug_show,
+#endif
+};
+
+static bool imsic_init_dev_msi_info(struct device *dev,
+				    struct irq_domain *domain,
+				    struct irq_domain *real_parent,
+				    struct msi_domain_info *info)
+{
+	const struct msi_parent_ops *pops = real_parent->msi_parent_ops;
+
+	/* MSI parent domain specific settings */
+	switch (real_parent->bus_token) {
+	case DOMAIN_BUS_NEXUS:
+		if (WARN_ON_ONCE(domain != real_parent))
+			return false;
+#ifdef CONFIG_SMP
+		info->chip->irq_set_affinity = imsic_irq_set_affinity;
+#endif
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return false;
+	}
+
+	/* Is the target supported? */
+	switch (info->bus_token) {
+	case DOMAIN_BUS_DEVICE_MSI:
+		/*
+		 * Per-device MSI should never have any MSI feature bits
+		 * set. It's sole purpose is to create a dumb interrupt
+		 * chip which has a device specific irq_write_msi_msg()
+		 * callback.
+		 */
+		if (WARN_ON_ONCE(info->flags))
+			return false;
+
+		/* Core managed MSI descriptors */
+		info->flags |= MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS |
+			       MSI_FLAG_FREE_MSI_DESCS;
+		break;
+	case DOMAIN_BUS_WIRED_TO_MSI:
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return false;
+	}
+
+	/* Use hierarchial chip operations re-trigger */
+	info->chip->irq_retrigger = irq_chip_retrigger_hierarchy;
+
+	/*
+	 * Mask out the domain specific MSI feature flags which are not
+	 * supported by the real parent.
+	 */
+	info->flags &= pops->supported_flags;
+
+	/* Enforce the required flags */
+	info->flags |= pops->required_flags;
+
+	return true;
+}
+
+#define MATCH_PLATFORM_MSI		BIT(DOMAIN_BUS_PLATFORM_MSI)
+
+static const struct msi_parent_ops imsic_msi_parent_ops = {
+	.supported_flags	= MSI_GENERIC_FLAGS_MASK,
+	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
+				  MSI_FLAG_USE_DEF_CHIP_OPS,
+	.bus_select_token	= DOMAIN_BUS_NEXUS,
+	.bus_select_mask	= MATCH_PLATFORM_MSI,
+	.init_dev_msi_info	= imsic_init_dev_msi_info,
+};
+
+int imsic_irqdomain_init(void)
+{
+	struct imsic_global_config *global;
+
+	if (!imsic || !imsic->fwnode) {
+		pr_err("early driver not probed\n");
+		return -ENODEV;
+	}
+
+	if (imsic->base_domain) {
+		pr_err("%pfwP: irq domain already created\n", imsic->fwnode);
+		return -ENODEV;
+	}
+
+	/* Create Base IRQ domain */
+	imsic->base_domain = irq_domain_create_tree(imsic->fwnode,
+						    &imsic_base_domain_ops, imsic);
+	if (!imsic->base_domain) {
+		pr_err("%pfwP: failed to create IMSIC base domain\n", imsic->fwnode);
+		return -ENOMEM;
+	}
+	imsic->base_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
+	imsic->base_domain->msi_parent_ops = &imsic_msi_parent_ops;
+
+	irq_domain_update_bus_token(imsic->base_domain, DOMAIN_BUS_NEXUS);
+
+	global = &imsic->global;
+	pr_info("%pfwP:  hart-index-bits: %d,  guest-index-bits: %d\n",
+		imsic->fwnode, global->hart_index_bits, global->guest_index_bits);
+	pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n",
+		imsic->fwnode, global->group_index_bits, global->group_index_shift);
+	pr_info("%pfwP: per-CPU IDs %d at base PPN %pa\n",
+		imsic->fwnode, global->nr_ids, &global->base_addr);
+	pr_info("%pfwP: total %d interrupts available\n",
+		imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1));
+
+	return 0;
+}
+
+static int imsic_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	if (imsic && imsic->fwnode != dev->fwnode) {
+		dev_err(dev, "fwnode mismatch\n");
+		return -ENODEV;
+	}
+
+	return imsic_irqdomain_init();
+}
+
+static const struct of_device_id imsic_platform_match[] = {
+	{ .compatible = "riscv,imsics" },
+	{}
+};
+
+static struct platform_driver imsic_platform_driver = {
+	.driver = {
+		.name		= "riscv-imsic",
+		.of_match_table	= imsic_platform_match,
+	},
+	.probe = imsic_platform_probe,
+};
+builtin_platform_driver(imsic_platform_driver);
diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-riscv-imsic-state.h
index 8ec9649d0d01..5ae2f69b035b 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.h
+++ b/drivers/irqchip/irq-riscv-imsic-state.h
@@ -103,5 +103,6 @@ void imsic_vector_debug_show_summary(struct seq_file *m, int ind);
 void imsic_state_online(void);
 void imsic_state_offline(void);
 int imsic_setup_state(struct fwnode_handle *fwnode);
+int imsic_irqdomain_init(void);
 
 #endif
-- 
2.34.1



From apatel at ventanamicro.com  Sun Feb 25 20:07:41 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:41 +0530
Subject: [PATCH v15 05/10] irqchip/riscv-imsic: Add device MSI domain support for PCI devices
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <20240226040746.1396416-6-apatel@ventanamicro.com>

The Linux PCI framework supports per-device MSI domains for PCI devices
so extend the IMSIC driver to allow PCI per-device MSI domains.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                    |  7 +++++
 drivers/irqchip/irq-riscv-imsic-platform.c | 35 ++++++++++++++++++++--
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 85f86e31c996..2fc0cb32341a 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -553,6 +553,13 @@ config RISCV_IMSIC
 	select GENERIC_IRQ_MATRIX_ALLOCATOR
 	select GENERIC_MSI_IRQ
 
+config RISCV_IMSIC_PCI
+	bool
+	depends on RISCV_IMSIC
+	depends on PCI
+	depends on PCI_MSI
+	default RISCV_IMSIC
+
 config EXYNOS_IRQ_COMBINER
 	bool "Samsung Exynos IRQ combiner support" if COMPILE_TEST
 	depends on (ARCH_EXYNOS && ARM) || COMPILE_TEST
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 35291bf90d65..1e6dddfd3046 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -14,6 +14,7 @@
 #include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/msi.h>
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/smp.h>
@@ -207,6 +208,28 @@ static const struct irq_domain_ops imsic_base_domain_ops = {
 #endif
 };
 
+#ifdef CONFIG_RISCV_IMSIC_PCI
+
+static void imsic_pci_mask_irq(struct irq_data *d)
+{
+	pci_msi_mask_irq(d);
+	irq_chip_mask_parent(d);
+}
+
+static void imsic_pci_unmask_irq(struct irq_data *d)
+{
+	irq_chip_unmask_parent(d);
+	pci_msi_unmask_irq(d);
+}
+
+#define MATCH_PCI_MSI		BIT(DOMAIN_BUS_PCI_MSI)
+
+#else
+
+#define MATCH_PCI_MSI		0
+
+#endif
+
 static bool imsic_init_dev_msi_info(struct device *dev,
 				    struct irq_domain *domain,
 				    struct irq_domain *real_parent,
@@ -230,6 +253,13 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 
 	/* Is the target supported? */
 	switch (info->bus_token) {
+#ifdef CONFIG_RISCV_IMSIC_PCI
+	case DOMAIN_BUS_PCI_DEVICE_MSI:
+	case DOMAIN_BUS_PCI_DEVICE_MSIX:
+		info->chip->irq_mask = imsic_pci_mask_irq;
+		info->chip->irq_unmask = imsic_pci_unmask_irq;
+		break;
+#endif
 	case DOMAIN_BUS_DEVICE_MSI:
 		/*
 		 * Per-device MSI should never have any MSI feature bits
@@ -269,11 +299,12 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 #define MATCH_PLATFORM_MSI		BIT(DOMAIN_BUS_PLATFORM_MSI)
 
 static const struct msi_parent_ops imsic_msi_parent_ops = {
-	.supported_flags	= MSI_GENERIC_FLAGS_MASK,
+	.supported_flags	= MSI_GENERIC_FLAGS_MASK |
+				  MSI_FLAG_PCI_MSIX,
 	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
 				  MSI_FLAG_USE_DEF_CHIP_OPS,
 	.bus_select_token	= DOMAIN_BUS_NEXUS,
-	.bus_select_mask	= MATCH_PLATFORM_MSI,
+	.bus_select_mask	= MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
 	.init_dev_msi_info	= imsic_init_dev_msi_info,
 };
 
-- 
2.34.1



From apatel at ventanamicro.com  Sun Feb 25 20:07:42 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:42 +0530
Subject: [PATCH v15 06/10] dt-bindings: interrupt-controller: Add RISC-V advanced PLIC
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <20240226040746.1396416-7-apatel@ventanamicro.com>

Add DT bindings document for RISC-V advanced platform level interrupt
controller (APLIC) defined by the RISC-V advanced interrupt architecture
(AIA) specification.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 .../interrupt-controller/riscv,aplic.yaml     | 172 ++++++++++++++++++
 1 file changed, 172 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml b/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
new file mode 100644
index 000000000000..190a6499c932
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
@@ -0,0 +1,172 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/riscv,aplic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Advanced Platform Level Interrupt Controller (APLIC)
+
+maintainers:
+  - Anup Patel <anup at brainfault.org>
+
+description:
+  The RISC-V advanced interrupt architecture (AIA) defines an advanced
+  platform level interrupt controller (APLIC) for handling wired interrupts
+  in a RISC-V platform. The RISC-V AIA specification can be found at
+  https://github.com/riscv/riscv-aia.
+
+  The RISC-V APLIC is implemented as hierarchical APLIC domains where all
+  interrupt sources connect to the root APLIC domain and a parent APLIC
+  domain can delegate interrupt sources to it's child APLIC domains. There
+  is one device tree node for each APLIC domain.
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - qemu,aplic
+      - const: riscv,aplic
+
+  reg:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+  interrupts-extended:
+    minItems: 1
+    maxItems: 16384
+    description:
+      Given APLIC domain directly injects external interrupts to a set of
+      RISC-V HARTS (or CPUs). Each node pointed to should be a riscv,cpu-intc
+      node, which has a CPU node (i.e. RISC-V HART) as parent.
+
+  msi-parent:
+    description:
+      Given APLIC domain forwards wired interrupts as MSIs to a AIA incoming
+      message signaled interrupt controller (IMSIC). If both "msi-parent" and
+      "interrupts-extended" properties are present then it means the APLIC
+      domain supports both MSI mode and Direct mode in HW. In this case, the
+      APLIC driver has to choose between MSI mode or Direct mode.
+
+  riscv,num-sources:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 1023
+    description:
+      Specifies the number of wired interrupt sources supported by this
+      APLIC domain.
+
+  riscv,children:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 1024
+    items:
+      maxItems: 1
+    description:
+      A list of child APLIC domains for the given APLIC domain. Each child
+      APLIC domain is assigned a child index in increasing order, with the
+      first child APLIC domain assigned child index 0. The APLIC domain child
+      index is used by firmware to delegate interrupts from the given APLIC
+      domain to a particular child APLIC domain.
+
+  riscv,delegation:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 1024
+    items:
+      items:
+        - description: child APLIC domain phandle
+        - description: first interrupt number of the parent APLIC domain (inclusive)
+        - description: last interrupt number of the parent APLIC domain (inclusive)
+    description:
+      A interrupt delegation list where each entry is a triple consisting
+      of child APLIC domain phandle, first interrupt number of the parent
+      APLIC domain, and last interrupt number of the parent APLIC domain.
+      Firmware must configure interrupt delegation registers based on
+      interrupt delegation list.
+
+dependencies:
+  riscv,delegation: [ "riscv,children" ]
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - "#interrupt-cells"
+  - riscv,num-sources
+
+anyOf:
+  - required:
+      - interrupts-extended
+  - required:
+      - msi-parent
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    // Example 1 (APLIC domains directly injecting interrupt to HARTs):
+
+    interrupt-controller at c000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      interrupts-extended = <&cpu1_intc 11>,
+                            <&cpu2_intc 11>,
+                            <&cpu3_intc 11>,
+                            <&cpu4_intc 11>;
+      reg = <0xc000000 0x4080>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+      riscv,children = <&aplic1>, <&aplic2>;
+      riscv,delegation = <&aplic1 1 63>;
+    };
+
+    aplic1: interrupt-controller at d000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      interrupts-extended = <&cpu1_intc 9>,
+                            <&cpu2_intc 9>;
+      reg = <0xd000000 0x4080>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+    };
+
+    aplic2: interrupt-controller at e000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      interrupts-extended = <&cpu3_intc 9>,
+                            <&cpu4_intc 9>;
+      reg = <0xe000000 0x4080>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+    };
+
+  - |
+    // Example 2 (APLIC domains forwarding interrupts as MSIs):
+
+    interrupt-controller at c000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      msi-parent = <&imsic_mlevel>;
+      reg = <0xc000000 0x4000>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+      riscv,children = <&aplic3>;
+      riscv,delegation = <&aplic3 1 63>;
+    };
+
+    aplic3: interrupt-controller at d000000 {
+      compatible = "qemu,aplic", "riscv,aplic";
+      msi-parent = <&imsic_slevel>;
+      reg = <0xd000000 0x4000>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      riscv,num-sources = <63>;
+    };
+...
-- 
2.34.1



From apatel at ventanamicro.com  Sun Feb 25 20:07:44 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:44 +0530
Subject: [PATCH v15 08/10] irqchip/riscv-aplic: Add support for MSI-mode
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <20240226040746.1396416-9-apatel@ventanamicro.com>

The RISC-V advanced platform-level interrupt controller (APLIC) has
two modes of operation: 1) Direct mode and 2) MSI mode.
(For more details, refer https://github.com/riscv/riscv-aia)

In APLIC MSI-mode, wired interrupts are forwared as message signaled
interrupts (MSIs) to CPUs via IMSIC.

Extend the existing APLIC irqchip driver to support MSI-mode for
RISC-V platforms having both wired interrupts and MSIs.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                |   6 +
 drivers/irqchip/Makefile               |   1 +
 drivers/irqchip/irq-riscv-aplic-main.c |   2 +-
 drivers/irqchip/irq-riscv-aplic-main.h |   8 +
 drivers/irqchip/irq-riscv-aplic-msi.c  | 263 +++++++++++++++++++++++++
 5 files changed, 279 insertions(+), 1 deletion(-)
 create mode 100644 drivers/irqchip/irq-riscv-aplic-msi.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index dbc8811d3764..806b5fccb3e8 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -551,6 +551,12 @@ config RISCV_APLIC
 	depends on RISCV
 	select IRQ_DOMAIN_HIERARCHY
 
+config RISCV_APLIC_MSI
+	bool
+	depends on RISCV_APLIC
+	select GENERIC_MSI_IRQ
+	default RISCV_APLIC
+
 config RISCV_IMSIC
 	bool
 	depends on RISCV
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 7f8289790ed8..47995fdb2c60 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
 obj-$(CONFIG_RISCV_APLIC)		+= irq-riscv-aplic-main.o irq-riscv-aplic-direct.o
+obj-$(CONFIG_RISCV_APLIC_MSI)		+= irq-riscv-aplic-msi.o
 obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
index 160ff99d6979..774a0c97fdab 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.c
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -187,7 +187,7 @@ static int aplic_probe(struct platform_device *pdev)
 	if (is_of_node(dev->fwnode))
 		msi_mode = of_property_present(to_of_node(dev->fwnode), "msi-parent");
 	if (msi_mode)
-		rc = -ENODEV;
+		rc = aplic_msi_setup(dev, regs);
 	else
 		rc = aplic_direct_setup(dev, regs);
 	if (rc)
diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h
index 4cfbadf37ddc..4393927d8c80 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.h
+++ b/drivers/irqchip/irq-riscv-aplic-main.h
@@ -40,5 +40,13 @@ int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
 void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode);
 int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs);
 int aplic_direct_setup(struct device *dev, void __iomem *regs);
+#ifdef CONFIG_RISCV_APLIC_MSI
+int aplic_msi_setup(struct device *dev, void __iomem *regs);
+#else
+static inline int aplic_msi_setup(struct device *dev, void __iomem *regs)
+{
+	return -ENODEV;
+}
+#endif
 
 #endif
diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
new file mode 100644
index 000000000000..b2a25e011bb2
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-msi.c
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/riscv-aplic.h>
+#include <linux/irqchip/riscv-imsic.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-aplic-main.h"
+
+static void aplic_msi_irq_unmask(struct irq_data *d)
+{
+	aplic_irq_unmask(d);
+	irq_chip_unmask_parent(d);
+}
+
+static void aplic_msi_irq_mask(struct irq_data *d)
+{
+	irq_chip_mask_parent(d);
+	aplic_irq_mask(d);
+}
+
+static void aplic_msi_irq_eoi(struct irq_data *d)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	u32 reg_off, reg_mask;
+
+	/*
+	 * EOI handling is required only for level-triggered interrupts
+	 * when APLIC is in MSI mode.
+	 */
+
+	reg_off = APLIC_CLRIP_BASE + ((d->hwirq / APLIC_IRQBITS_PER_REG) * 4);
+	reg_mask = BIT(d->hwirq % APLIC_IRQBITS_PER_REG);
+	switch (irqd_get_trigger_type(d)) {
+	case IRQ_TYPE_LEVEL_LOW:
+		/*
+		 * If the rectified input value of the source is still low
+		 * then set the interrupt pending bit so that interrupt is
+		 * re-triggered via MSI.
+		 */
+		if (!(readl(priv->regs + reg_off) & reg_mask))
+			writel(d->hwirq, priv->regs + APLIC_SETIPNUM_LE);
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		/*
+		 * If the rectified input value of the source is still high
+		 * then set the interrupt pending bit so that interrupt is
+		 * re-triggered via MSI.
+		 */
+		if (readl(priv->regs + reg_off) & reg_mask)
+			writel(d->hwirq, priv->regs + APLIC_SETIPNUM_LE);
+		break;
+	}
+}
+
+static void aplic_msi_write_msg(struct irq_data *d, struct msi_msg *msg)
+{
+	unsigned int group_index, hart_index, guest_index, val;
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	struct aplic_msicfg *mc = &priv->msicfg;
+	phys_addr_t tppn, tbppn, msg_addr;
+	void __iomem *target;
+
+	/* For zeroed MSI, simply write zero into the target register */
+	if (!msg->address_hi && !msg->address_lo && !msg->data) {
+		target = priv->regs + APLIC_TARGET_BASE;
+		target += (d->hwirq - 1) * sizeof(u32);
+		writel(0, target);
+		return;
+	}
+
+	/* Sanity check on message data */
+	WARN_ON(msg->data > APLIC_TARGET_EIID_MASK);
+
+	/* Compute target MSI address */
+	msg_addr = (((u64)msg->address_hi) << 32) | msg->address_lo;
+	tppn = msg_addr >> APLIC_xMSICFGADDR_PPN_SHIFT;
+
+	/* Compute target HART Base PPN */
+	tbppn = tppn;
+	tbppn &= ~APLIC_xMSICFGADDR_PPN_HART(mc->lhxs);
+	tbppn &= ~APLIC_xMSICFGADDR_PPN_LHX(mc->lhxw, mc->lhxs);
+	tbppn &= ~APLIC_xMSICFGADDR_PPN_HHX(mc->hhxw, mc->hhxs);
+	WARN_ON(tbppn != mc->base_ppn);
+
+	/* Compute target group and hart indexes */
+	group_index = (tppn >> APLIC_xMSICFGADDR_PPN_HHX_SHIFT(mc->hhxs)) &
+		     APLIC_xMSICFGADDR_PPN_HHX_MASK(mc->hhxw);
+	hart_index = (tppn >> APLIC_xMSICFGADDR_PPN_LHX_SHIFT(mc->lhxs)) &
+		     APLIC_xMSICFGADDR_PPN_LHX_MASK(mc->lhxw);
+	hart_index |= (group_index << mc->lhxw);
+	WARN_ON(hart_index > APLIC_TARGET_HART_IDX_MASK);
+
+	/* Compute target guest index */
+	guest_index = tppn & APLIC_xMSICFGADDR_PPN_HART(mc->lhxs);
+	WARN_ON(guest_index > APLIC_TARGET_GUEST_IDX_MASK);
+
+	/* Update IRQ TARGET register */
+	target = priv->regs + APLIC_TARGET_BASE;
+	target += (d->hwirq - 1) * sizeof(u32);
+	val = FIELD_PREP(APLIC_TARGET_HART_IDX, hart_index);
+	val |= FIELD_PREP(APLIC_TARGET_GUEST_IDX, guest_index);
+	val |= FIELD_PREP(APLIC_TARGET_EIID, msg->data);
+	writel(val, target);
+}
+
+static void aplic_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+	arg->desc = desc;
+	arg->hwirq = (u32)desc->data.icookie.value;
+}
+
+static int aplic_msi_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
+			       unsigned long *hwirq, unsigned int *type)
+{
+	struct msi_domain_info *info = d->host_data;
+	struct aplic_priv *priv = info->data;
+
+	return aplic_irqdomain_translate(fwspec, priv->gsi_base, hwirq, type);
+}
+
+static const struct msi_domain_template aplic_msi_template = {
+	.chip = {
+		.name			= "APLIC-MSI",
+		.irq_mask		= aplic_msi_irq_mask,
+		.irq_unmask		= aplic_msi_irq_unmask,
+		.irq_set_type		= aplic_irq_set_type,
+		.irq_eoi		= aplic_msi_irq_eoi,
+#ifdef CONFIG_SMP
+		.irq_set_affinity	= irq_chip_set_affinity_parent,
+#endif
+		.irq_write_msi_msg	= aplic_msi_write_msg,
+		.flags			= IRQCHIP_SET_TYPE_MASKED |
+					  IRQCHIP_SKIP_SET_WAKE |
+					  IRQCHIP_MASK_ON_SUSPEND,
+	},
+
+	.ops = {
+		.set_desc		= aplic_msi_set_desc,
+		.msi_translate		= aplic_msi_translate,
+	},
+
+	.info = {
+		.bus_token		= DOMAIN_BUS_WIRED_TO_MSI,
+		.flags			= MSI_FLAG_USE_DEV_FWNODE,
+		.handler		= handle_fasteoi_irq,
+	},
+};
+
+int aplic_msi_setup(struct device *dev, void __iomem *regs)
+{
+	const struct imsic_global_config *imsic_global;
+	struct aplic_priv *priv;
+	struct aplic_msicfg *mc;
+	phys_addr_t pa;
+	int rc;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	rc = aplic_setup_priv(priv, dev, regs);
+	if (rc) {
+		dev_err(dev, "failed to create APLIC context\n");
+		return rc;
+	}
+	mc = &priv->msicfg;
+
+	/*
+	 * The APLIC outgoing MSI config registers assume target MSI
+	 * controller to be RISC-V AIA IMSIC controller.
+	 */
+	imsic_global = imsic_get_global_config();
+	if (!imsic_global) {
+		dev_err(dev, "IMSIC global config not found\n");
+		return -ENODEV;
+	}
+
+	/* Find number of guest index bits (LHXS) */
+	mc->lhxs = imsic_global->guest_index_bits;
+	if (APLIC_xMSICFGADDRH_LHXS_MASK < mc->lhxs) {
+		dev_err(dev, "IMSIC guest index bits big for APLIC LHXS\n");
+		return -EINVAL;
+	}
+
+	/* Find number of HART index bits (LHXW) */
+	mc->lhxw = imsic_global->hart_index_bits;
+	if (APLIC_xMSICFGADDRH_LHXW_MASK < mc->lhxw) {
+		dev_err(dev, "IMSIC hart index bits big for APLIC LHXW\n");
+		return -EINVAL;
+	}
+
+	/* Find number of group index bits (HHXW) */
+	mc->hhxw = imsic_global->group_index_bits;
+	if (APLIC_xMSICFGADDRH_HHXW_MASK < mc->hhxw) {
+		dev_err(dev, "IMSIC group index bits big for APLIC HHXW\n");
+		return -EINVAL;
+	}
+
+	/* Find first bit position of group index (HHXS) */
+	mc->hhxs = imsic_global->group_index_shift;
+	if (mc->hhxs < (2 * APLIC_xMSICFGADDR_PPN_SHIFT)) {
+		dev_err(dev, "IMSIC group index shift should be >= %d\n",
+			(2 * APLIC_xMSICFGADDR_PPN_SHIFT));
+		return -EINVAL;
+	}
+	mc->hhxs -= (2 * APLIC_xMSICFGADDR_PPN_SHIFT);
+	if (APLIC_xMSICFGADDRH_HHXS_MASK < mc->hhxs) {
+		dev_err(dev, "IMSIC group index shift big for APLIC HHXS\n");
+		return -EINVAL;
+	}
+
+	/* Compute PPN base */
+	mc->base_ppn = imsic_global->base_addr >> APLIC_xMSICFGADDR_PPN_SHIFT;
+	mc->base_ppn &= ~APLIC_xMSICFGADDR_PPN_HART(mc->lhxs);
+	mc->base_ppn &= ~APLIC_xMSICFGADDR_PPN_LHX(mc->lhxw, mc->lhxs);
+	mc->base_ppn &= ~APLIC_xMSICFGADDR_PPN_HHX(mc->hhxw, mc->hhxs);
+
+	/* Setup global config and interrupt delivery */
+	aplic_init_hw_global(priv, true);
+
+	/* Set the APLIC device MSI domain if not available */
+	if (!dev_get_msi_domain(dev)) {
+		/*
+		 * The device MSI domain for OF devices is only set at the
+		 * time of populating/creating OF device. If the device MSI
+		 * domain is discovered later after the OF device is created
+		 * then we need to set it explicitly before using any platform
+		 * MSI functions.
+		 *
+		 * In case of APLIC device, the parent MSI domain is always
+		 * IMSIC and the IMSIC MSI domains are created later through
+		 * the platform driver probing so we set it explicitly here.
+		 */
+		if (is_of_node(dev->fwnode))
+			of_msi_configure(dev, to_of_node(dev->fwnode));
+	}
+
+	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, &aplic_msi_template,
+					  priv->nr_irqs + 1, priv, priv)) {
+		dev_err(dev, "failed to create MSI irq domain\n");
+		return -ENOMEM;
+	}
+
+	/* Advertise the interrupt controller */
+	pa = priv->msicfg.base_ppn << APLIC_xMSICFGADDR_PPN_SHIFT;
+	dev_info(dev, "%d interrupts forwared to MSI base %pa\n", priv->nr_irqs, &pa);
+
+	return 0;
+}
-- 
2.34.1



From apatel at ventanamicro.com  Sun Feb 25 20:07:43 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:43 +0530
Subject: [PATCH v15 07/10] irqchip: Add RISC-V advanced PLIC driver for direct-mode
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <20240226040746.1396416-8-apatel@ventanamicro.com>

The RISC-V advanced interrupt architecture (AIA) specification defines
advanced platform-level interrupt controller (APLIC) which has two modes
of operation: 1) Direct mode and 2) MSI mode.
(For more details, refer https://github.com/riscv/riscv-aia)

In APLIC direct-mode, wired interrupts are forwared to CPUs (or HARTs)
as a local external interrupt.

Add a platform irqchip driver for the RISC-V APLIC direct-mode to
support RISC-V platforms having only wired interrupts.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 drivers/irqchip/Kconfig                  |   5 +
 drivers/irqchip/Makefile                 |   1 +
 drivers/irqchip/irq-riscv-aplic-direct.c | 326 +++++++++++++++++++++++
 drivers/irqchip/irq-riscv-aplic-main.c   | 211 +++++++++++++++
 drivers/irqchip/irq-riscv-aplic-main.h   |  44 +++
 include/linux/irqchip/riscv-aplic.h      | 145 ++++++++++
 6 files changed, 732 insertions(+)
 create mode 100644 drivers/irqchip/irq-riscv-aplic-direct.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.c
 create mode 100644 drivers/irqchip/irq-riscv-aplic-main.h
 create mode 100644 include/linux/irqchip/riscv-aplic.h

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 2fc0cb32341a..dbc8811d3764 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -546,6 +546,11 @@ config SIFIVE_PLIC
 	select IRQ_DOMAIN_HIERARCHY
 	select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
 
+config RISCV_APLIC
+	bool
+	depends on RISCV
+	select IRQ_DOMAIN_HIERARCHY
+
 config RISCV_IMSIC
 	bool
 	depends on RISCV
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index abca445a3229..7f8289790ed8 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_QCOM_MPM)			+= irq-qcom-mpm.o
 obj-$(CONFIG_CSKY_MPINTC)		+= irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_RISCV_INTC)		+= irq-riscv-intc.o
+obj-$(CONFIG_RISCV_APLIC)		+= irq-riscv-aplic-main.o irq-riscv-aplic-direct.o
 obj-$(CONFIG_RISCV_IMSIC)		+= irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
diff --git a/drivers/irqchip/irq-riscv-aplic-direct.c b/drivers/irqchip/irq-riscv-aplic-direct.c
new file mode 100644
index 000000000000..06bace9b7497
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-direct.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/riscv-aplic.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/printk.h>
+#include <linux/smp.h>
+
+#include "irq-riscv-aplic-main.h"
+
+#define APLIC_DISABLE_IDELIVERY		0
+#define APLIC_ENABLE_IDELIVERY		1
+#define APLIC_DISABLE_ITHRESHOLD	1
+#define APLIC_ENABLE_ITHRESHOLD		0
+
+struct aplic_direct {
+	struct aplic_priv	priv;
+	struct irq_domain	*irqdomain;
+	struct cpumask		lmask;
+};
+
+struct aplic_idc {
+	unsigned int		hart_index;
+	void __iomem		*regs;
+	struct aplic_direct	*direct;
+};
+
+static unsigned int aplic_direct_parent_irq;
+static DEFINE_PER_CPU(struct aplic_idc, aplic_idcs);
+
+static void aplic_direct_irq_eoi(struct irq_data *d)
+{
+	/*
+	 * The fasteoi_handler requires irq_eoi() callback hence
+	 * provide a dummy handler.
+	 */
+}
+
+#ifdef CONFIG_SMP
+static int aplic_direct_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+				     bool force)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	struct aplic_direct *direct = container_of(priv, struct aplic_direct, priv);
+	struct aplic_idc *idc;
+	unsigned int cpu, val;
+	struct cpumask amask;
+	void __iomem *target;
+
+	cpumask_and(&amask, &direct->lmask, mask_val);
+
+	if (force)
+		cpu = cpumask_first(&amask);
+	else
+		cpu = cpumask_any_and(&amask, cpu_online_mask);
+
+	if (cpu >= nr_cpu_ids)
+		return -EINVAL;
+
+	idc = per_cpu_ptr(&aplic_idcs, cpu);
+	target = priv->regs + APLIC_TARGET_BASE + (d->hwirq - 1) * sizeof(u32);
+	val = FIELD_PREP(APLIC_TARGET_HART_IDX, idc->hart_index);
+	val |= FIELD_PREP(APLIC_TARGET_IPRIO, APLIC_DEFAULT_PRIORITY);
+	writel(val, target);
+
+	irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
+	return IRQ_SET_MASK_OK_DONE;
+}
+#endif
+
+static struct irq_chip aplic_direct_chip = {
+	.name		= "APLIC-DIRECT",
+	.irq_mask	= aplic_irq_mask,
+	.irq_unmask	= aplic_irq_unmask,
+	.irq_set_type	= aplic_irq_set_type,
+	.irq_eoi	= aplic_direct_irq_eoi,
+#ifdef CONFIG_SMP
+	.irq_set_affinity = aplic_direct_set_affinity,
+#endif
+	.flags		= IRQCHIP_SET_TYPE_MASKED |
+			  IRQCHIP_SKIP_SET_WAKE |
+			  IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static int aplic_direct_irqdomain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
+					    unsigned long *hwirq, unsigned int *type)
+{
+	struct aplic_priv *priv = d->host_data;
+
+	return aplic_irqdomain_translate(fwspec, priv->gsi_base, hwirq, type);
+}
+
+static int aplic_direct_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
+					unsigned int nr_irqs, void *arg)
+{
+	struct aplic_priv *priv = domain->host_data;
+	struct aplic_direct *direct = container_of(priv, struct aplic_direct, priv);
+	struct irq_fwspec *fwspec = arg;
+	irq_hw_number_t hwirq;
+	unsigned int type;
+	int i, ret;
+
+	ret = aplic_irqdomain_translate(fwspec, priv->gsi_base, &hwirq, &type);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nr_irqs; i++) {
+		irq_domain_set_info(domain, virq + i, hwirq + i, &aplic_direct_chip,
+				    priv, handle_fasteoi_irq, NULL, NULL);
+		irq_set_affinity(virq + i, &direct->lmask);
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops aplic_direct_irqdomain_ops = {
+	.translate	= aplic_direct_irqdomain_translate,
+	.alloc		= aplic_direct_irqdomain_alloc,
+	.free		= irq_domain_free_irqs_top,
+};
+
+/*
+ * To handle an APLIC direct interrupts, we just read the CLAIMI register
+ * which will return highest priority pending interrupt and clear the
+ * pending bit of the interrupt. This process is repeated until CLAIMI
+ * register return zero value.
+ */
+static void aplic_direct_handle_irq(struct irq_desc *desc)
+{
+	struct aplic_idc *idc = this_cpu_ptr(&aplic_idcs);
+	struct irq_domain *irqdomain = idc->direct->irqdomain;
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	irq_hw_number_t hw_irq;
+	int irq;
+
+	chained_irq_enter(chip, desc);
+
+	while ((hw_irq = readl(idc->regs + APLIC_IDC_CLAIMI))) {
+		hw_irq = hw_irq >> APLIC_IDC_TOPI_ID_SHIFT;
+		irq = irq_find_mapping(irqdomain, hw_irq);
+
+		if (unlikely(irq <= 0)) {
+			dev_warn_ratelimited(idc->direct->priv.dev,
+					     "hw_irq %lu mapping not found\n", hw_irq);
+		} else {
+			generic_handle_irq(irq);
+		}
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static void aplic_idc_set_delivery(struct aplic_idc *idc, bool en)
+{
+	u32 de = (en) ? APLIC_ENABLE_IDELIVERY : APLIC_DISABLE_IDELIVERY;
+	u32 th = (en) ? APLIC_ENABLE_ITHRESHOLD : APLIC_DISABLE_ITHRESHOLD;
+
+	/* Priority must be less than threshold for interrupt triggering */
+	writel(th, idc->regs + APLIC_IDC_ITHRESHOLD);
+
+	/* Delivery must be set to 1 for interrupt triggering */
+	writel(de, idc->regs + APLIC_IDC_IDELIVERY);
+}
+
+static int aplic_direct_dying_cpu(unsigned int cpu)
+{
+	if (aplic_direct_parent_irq)
+		disable_percpu_irq(aplic_direct_parent_irq);
+
+	return 0;
+}
+
+static int aplic_direct_starting_cpu(unsigned int cpu)
+{
+	if (aplic_direct_parent_irq) {
+		enable_percpu_irq(aplic_direct_parent_irq,
+				  irq_get_trigger_type(aplic_direct_parent_irq));
+	}
+
+	return 0;
+}
+
+static int aplic_direct_parse_parent_hwirq(struct device *dev, u32 index,
+					   u32 *parent_hwirq, unsigned long *parent_hartid)
+{
+	struct of_phandle_args parent;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	rc = of_irq_parse_one(to_of_node(dev->fwnode), index, &parent);
+	if (rc)
+		return rc;
+
+	rc = riscv_of_parent_hartid(parent.np, parent_hartid);
+	if (rc)
+		return rc;
+
+	*parent_hwirq = parent.args[0];
+	return 0;
+}
+
+int aplic_direct_setup(struct device *dev, void __iomem *regs)
+{
+	int i, j, rc, cpu, current_cpu, setup_count = 0;
+	struct aplic_direct *direct;
+	struct irq_domain *domain;
+	struct aplic_priv *priv;
+	struct aplic_idc *idc;
+	unsigned long hartid;
+	u32 v, hwirq;
+
+	direct = devm_kzalloc(dev, sizeof(*direct), GFP_KERNEL);
+	if (!direct)
+		return -ENOMEM;
+	priv = &direct->priv;
+
+	rc = aplic_setup_priv(priv, dev, regs);
+	if (rc) {
+		dev_err(dev, "failed to create APLIC context\n");
+		return rc;
+	}
+
+	/* Setup per-CPU IDC and target CPU mask */
+	current_cpu = get_cpu();
+	for (i = 0; i < priv->nr_idcs; i++) {
+		rc = aplic_direct_parse_parent_hwirq(dev, i, &hwirq, &hartid);
+		if (rc) {
+			dev_warn(dev, "parent irq for IDC%d not found\n", i);
+			continue;
+		}
+
+		/*
+		 * Skip interrupts other than external interrupts for
+		 * current privilege level.
+		 */
+		if (hwirq != RV_IRQ_EXT)
+			continue;
+
+		cpu = riscv_hartid_to_cpuid(hartid);
+		if (cpu < 0) {
+			dev_warn(dev, "invalid cpuid for IDC%d\n", i);
+			continue;
+		}
+
+		cpumask_set_cpu(cpu, &direct->lmask);
+
+		idc = per_cpu_ptr(&aplic_idcs, cpu);
+		idc->hart_index = i;
+		idc->regs = priv->regs + APLIC_IDC_BASE + i * APLIC_IDC_SIZE;
+		idc->direct = direct;
+
+		aplic_idc_set_delivery(idc, true);
+
+		/*
+		 * Boot cpu might not have APLIC hart_index = 0 so check
+		 * and update target registers of all interrupts.
+		 */
+		if (cpu == current_cpu && idc->hart_index) {
+			v = FIELD_PREP(APLIC_TARGET_HART_IDX, idc->hart_index);
+			v |= FIELD_PREP(APLIC_TARGET_IPRIO, APLIC_DEFAULT_PRIORITY);
+			for (j = 1; j <= priv->nr_irqs; j++)
+				writel(v, priv->regs + APLIC_TARGET_BASE + (j - 1) * sizeof(u32));
+		}
+
+		setup_count++;
+	}
+	put_cpu();
+
+	/* Find parent domain and register chained handler */
+	domain = irq_find_matching_fwnode(riscv_get_intc_hwnode(),
+					  DOMAIN_BUS_ANY);
+	if (!aplic_direct_parent_irq && domain) {
+		aplic_direct_parent_irq = irq_create_mapping(domain, RV_IRQ_EXT);
+		if (aplic_direct_parent_irq) {
+			irq_set_chained_handler(aplic_direct_parent_irq,
+						aplic_direct_handle_irq);
+
+			/*
+			 * Setup CPUHP notifier to enable parent
+			 * interrupt on all CPUs
+			 */
+			cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
+					  "irqchip/riscv/aplic:starting",
+					  aplic_direct_starting_cpu,
+					  aplic_direct_dying_cpu);
+		}
+	}
+
+	/* Fail if we were not able to setup IDC for any CPU */
+	if (!setup_count)
+		return -ENODEV;
+
+	/* Setup global config and interrupt delivery */
+	aplic_init_hw_global(priv, false);
+
+	/* Create irq domain instance for the APLIC */
+	direct->irqdomain = irq_domain_create_linear(dev->fwnode, priv->nr_irqs + 1,
+						     &aplic_direct_irqdomain_ops, priv);
+	if (!direct->irqdomain) {
+		dev_err(dev, "failed to create direct irq domain\n");
+		return -ENOMEM;
+	}
+
+	/* Advertise the interrupt controller */
+	dev_info(dev, "%d interrupts directly connected to %d CPUs\n",
+		 priv->nr_irqs, priv->nr_idcs);
+
+	return 0;
+}
diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
new file mode 100644
index 000000000000..160ff99d6979
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/irqchip/riscv-aplic.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+
+#include "irq-riscv-aplic-main.h"
+
+void aplic_irq_unmask(struct irq_data *d)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+
+	writel(d->hwirq, priv->regs + APLIC_SETIENUM);
+}
+
+void aplic_irq_mask(struct irq_data *d)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+
+	writel(d->hwirq, priv->regs + APLIC_CLRIENUM);
+}
+
+int aplic_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+	void __iomem *sourcecfg;
+	u32 val = 0;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		val = APLIC_SOURCECFG_SM_INACTIVE;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		val = APLIC_SOURCECFG_SM_LEVEL_LOW;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		val = APLIC_SOURCECFG_SM_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		val = APLIC_SOURCECFG_SM_EDGE_FALL;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		val = APLIC_SOURCECFG_SM_EDGE_RISE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sourcecfg = priv->regs + APLIC_SOURCECFG_BASE;
+	sourcecfg += (d->hwirq - 1) * sizeof(u32);
+	writel(val, sourcecfg);
+
+	return 0;
+}
+
+int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
+			      unsigned long *hwirq, unsigned int *type)
+{
+	if (WARN_ON(fwspec->param_count < 2))
+		return -EINVAL;
+	if (WARN_ON(!fwspec->param[0]))
+		return -EINVAL;
+
+	/* For DT, gsi_base is always zero. */
+	*hwirq = fwspec->param[0] - gsi_base;
+	*type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
+
+	WARN_ON(*type == IRQ_TYPE_NONE);
+
+	return 0;
+}
+
+void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
+{
+	u32 val;
+#ifdef CONFIG_RISCV_M_MODE
+	u32 valh;
+
+	if (msi_mode) {
+		val = lower_32_bits(priv->msicfg.base_ppn);
+		valh = FIELD_PREP(APLIC_xMSICFGADDRH_BAPPN, upper_32_bits(priv->msicfg.base_ppn));
+		valh |= FIELD_PREP(APLIC_xMSICFGADDRH_LHXW, priv->msicfg.lhxw);
+		valh |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXW, priv->msicfg.hhxw);
+		valh |= FIELD_PREP(APLIC_xMSICFGADDRH_LHXS, priv->msicfg.lhxs);
+		valh |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXS, priv->msicfg.hhxs);
+		writel(val, priv->regs + APLIC_xMSICFGADDR);
+		writel(valh, priv->regs + APLIC_xMSICFGADDRH);
+	}
+#endif
+
+	/* Setup APLIC domaincfg register */
+	val = readl(priv->regs + APLIC_DOMAINCFG);
+	val |= APLIC_DOMAINCFG_IE;
+	if (msi_mode)
+		val |= APLIC_DOMAINCFG_DM;
+	writel(val, priv->regs + APLIC_DOMAINCFG);
+	if (readl(priv->regs + APLIC_DOMAINCFG) != val)
+		dev_warn(priv->dev, "unable to write 0x%x in domaincfg\n", val);
+}
+
+static void aplic_init_hw_irqs(struct aplic_priv *priv)
+{
+	int i;
+
+	/* Disable all interrupts */
+	for (i = 0; i <= priv->nr_irqs; i += 32)
+		writel(-1U, priv->regs + APLIC_CLRIE_BASE + (i / 32) * sizeof(u32));
+
+	/* Set interrupt type and default priority for all interrupts */
+	for (i = 1; i <= priv->nr_irqs; i++) {
+		writel(0, priv->regs + APLIC_SOURCECFG_BASE + (i - 1) * sizeof(u32));
+		writel(APLIC_DEFAULT_PRIORITY,
+		       priv->regs + APLIC_TARGET_BASE + (i - 1) * sizeof(u32));
+	}
+
+	/* Clear APLIC domaincfg */
+	writel(0, priv->regs + APLIC_DOMAINCFG);
+}
+
+int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs)
+{
+	struct of_phandle_args parent;
+	int rc;
+
+	/*
+	 * Currently, only OF fwnode is supported so extend this
+	 * function for ACPI support.
+	 */
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	/* Save device pointer and register base */
+	priv->dev = dev;
+	priv->regs = regs;
+
+	/* Find out number of interrupt sources */
+	rc = of_property_read_u32(to_of_node(dev->fwnode), "riscv,num-sources",
+				  &priv->nr_irqs);
+	if (rc) {
+		dev_err(dev, "failed to get number of interrupt sources\n");
+		return rc;
+	}
+
+	/*
+	 * Find out number of IDCs based on parent interrupts
+	 *
+	 * If "msi-parent" property is present then we ignore the
+	 * APLIC IDCs which forces the APLIC driver to use MSI mode.
+	 */
+	if (!of_property_present(to_of_node(dev->fwnode), "msi-parent")) {
+		while (!of_irq_parse_one(to_of_node(dev->fwnode), priv->nr_idcs, &parent))
+			priv->nr_idcs++;
+	}
+
+	/* Setup initial state APLIC interrupts */
+	aplic_init_hw_irqs(priv);
+
+	return 0;
+}
+
+static int aplic_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	bool msi_mode = false;
+	void __iomem *regs;
+	int rc;
+
+	/* Map the MMIO registers */
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (!regs) {
+		dev_err(dev, "failed map MMIO registers\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * If msi-parent property is present then setup APLIC MSI
+	 * mode otherwise setup APLIC direct mode.
+	 */
+	if (is_of_node(dev->fwnode))
+		msi_mode = of_property_present(to_of_node(dev->fwnode), "msi-parent");
+	if (msi_mode)
+		rc = -ENODEV;
+	else
+		rc = aplic_direct_setup(dev, regs);
+	if (rc)
+		dev_err(dev, "failed to setup APLIC in %s mode\n", msi_mode ? "MSI" : "direct");
+
+	return rc;
+}
+
+static const struct of_device_id aplic_match[] = {
+	{ .compatible = "riscv,aplic" },
+	{}
+};
+
+static struct platform_driver aplic_driver = {
+	.driver = {
+		.name		= "riscv-aplic",
+		.of_match_table	= aplic_match,
+	},
+	.probe = aplic_probe,
+};
+builtin_platform_driver(aplic_driver);
diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h
new file mode 100644
index 000000000000..4cfbadf37ddc
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-aplic-main.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#ifndef _IRQ_RISCV_APLIC_MAIN_H
+#define _IRQ_RISCV_APLIC_MAIN_H
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/fwnode.h>
+
+#define APLIC_DEFAULT_PRIORITY		1
+
+struct aplic_msicfg {
+	phys_addr_t		base_ppn;
+	u32			hhxs;
+	u32			hhxw;
+	u32			lhxs;
+	u32			lhxw;
+};
+
+struct aplic_priv {
+	struct device		*dev;
+	u32			gsi_base;
+	u32			nr_irqs;
+	u32			nr_idcs;
+	void __iomem		*regs;
+	struct aplic_msicfg	msicfg;
+};
+
+void aplic_irq_unmask(struct irq_data *d);
+void aplic_irq_mask(struct irq_data *d);
+int aplic_irq_set_type(struct irq_data *d, unsigned int type);
+int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
+			      unsigned long *hwirq, unsigned int *type);
+void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode);
+int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs);
+int aplic_direct_setup(struct device *dev, void __iomem *regs);
+
+#endif
diff --git a/include/linux/irqchip/riscv-aplic.h b/include/linux/irqchip/riscv-aplic.h
new file mode 100644
index 000000000000..ec8f7df50583
--- /dev/null
+++ b/include/linux/irqchip/riscv-aplic.h
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+#ifndef __LINUX_IRQCHIP_RISCV_APLIC_H
+#define __LINUX_IRQCHIP_RISCV_APLIC_H
+
+#include <linux/bitops.h>
+
+#define APLIC_MAX_IDC			BIT(14)
+#define APLIC_MAX_SOURCE		1024
+
+#define APLIC_DOMAINCFG			0x0000
+#define APLIC_DOMAINCFG_RDONLY		0x80000000
+#define APLIC_DOMAINCFG_IE		BIT(8)
+#define APLIC_DOMAINCFG_DM		BIT(2)
+#define APLIC_DOMAINCFG_BE		BIT(0)
+
+#define APLIC_SOURCECFG_BASE		0x0004
+#define APLIC_SOURCECFG_D		BIT(10)
+#define APLIC_SOURCECFG_CHILDIDX_MASK	0x000003ff
+#define APLIC_SOURCECFG_SM_MASK	0x00000007
+#define APLIC_SOURCECFG_SM_INACTIVE	0x0
+#define APLIC_SOURCECFG_SM_DETACH	0x1
+#define APLIC_SOURCECFG_SM_EDGE_RISE	0x4
+#define APLIC_SOURCECFG_SM_EDGE_FALL	0x5
+#define APLIC_SOURCECFG_SM_LEVEL_HIGH	0x6
+#define APLIC_SOURCECFG_SM_LEVEL_LOW	0x7
+
+#define APLIC_MMSICFGADDR		0x1bc0
+#define APLIC_MMSICFGADDRH		0x1bc4
+#define APLIC_SMSICFGADDR		0x1bc8
+#define APLIC_SMSICFGADDRH		0x1bcc
+
+#ifdef CONFIG_RISCV_M_MODE
+#define APLIC_xMSICFGADDR		APLIC_MMSICFGADDR
+#define APLIC_xMSICFGADDRH		APLIC_MMSICFGADDRH
+#else
+#define APLIC_xMSICFGADDR		APLIC_SMSICFGADDR
+#define APLIC_xMSICFGADDRH		APLIC_SMSICFGADDRH
+#endif
+
+#define APLIC_xMSICFGADDRH_L		BIT(31)
+#define APLIC_xMSICFGADDRH_HHXS_MASK	0x1f
+#define APLIC_xMSICFGADDRH_HHXS_SHIFT	24
+#define APLIC_xMSICFGADDRH_HHXS		(APLIC_xMSICFGADDRH_HHXS_MASK << \
+					 APLIC_xMSICFGADDRH_HHXS_SHIFT)
+#define APLIC_xMSICFGADDRH_LHXS_MASK	0x7
+#define APLIC_xMSICFGADDRH_LHXS_SHIFT	20
+#define APLIC_xMSICFGADDRH_LHXS		(APLIC_xMSICFGADDRH_LHXS_MASK << \
+					 APLIC_xMSICFGADDRH_LHXS_SHIFT)
+#define APLIC_xMSICFGADDRH_HHXW_MASK	0x7
+#define APLIC_xMSICFGADDRH_HHXW_SHIFT	16
+#define APLIC_xMSICFGADDRH_HHXW		(APLIC_xMSICFGADDRH_HHXW_MASK << \
+					 APLIC_xMSICFGADDRH_HHXW_SHIFT)
+#define APLIC_xMSICFGADDRH_LHXW_MASK	0xf
+#define APLIC_xMSICFGADDRH_LHXW_SHIFT	12
+#define APLIC_xMSICFGADDRH_LHXW		(APLIC_xMSICFGADDRH_LHXW_MASK << \
+					 APLIC_xMSICFGADDRH_LHXW_SHIFT)
+#define APLIC_xMSICFGADDRH_BAPPN_MASK	0xfff
+#define APLIC_xMSICFGADDRH_BAPPN_SHIFT	0
+#define APLIC_xMSICFGADDRH_BAPPN	(APLIC_xMSICFGADDRH_BAPPN_MASK << \
+					 APLIC_xMSICFGADDRH_BAPPN_SHIFT)
+
+#define APLIC_xMSICFGADDR_PPN_SHIFT	12
+
+#define APLIC_xMSICFGADDR_PPN_HART(__lhxs) \
+	(BIT(__lhxs) - 1)
+
+#define APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) \
+	(BIT(__lhxw) - 1)
+#define APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs) \
+	((__lhxs))
+#define APLIC_xMSICFGADDR_PPN_LHX(__lhxw, __lhxs) \
+	(APLIC_xMSICFGADDR_PPN_LHX_MASK(__lhxw) << \
+	 APLIC_xMSICFGADDR_PPN_LHX_SHIFT(__lhxs))
+
+#define APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) \
+	(BIT(__hhxw) - 1)
+#define APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs) \
+	((__hhxs) + APLIC_xMSICFGADDR_PPN_SHIFT)
+#define APLIC_xMSICFGADDR_PPN_HHX(__hhxw, __hhxs) \
+	(APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) << \
+	 APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs))
+
+#define APLIC_IRQBITS_PER_REG		32
+
+#define APLIC_SETIP_BASE		0x1c00
+#define APLIC_SETIPNUM			0x1cdc
+
+#define APLIC_CLRIP_BASE		0x1d00
+#define APLIC_CLRIPNUM			0x1ddc
+
+#define APLIC_SETIE_BASE		0x1e00
+#define APLIC_SETIENUM			0x1edc
+
+#define APLIC_CLRIE_BASE		0x1f00
+#define APLIC_CLRIENUM			0x1fdc
+
+#define APLIC_SETIPNUM_LE		0x2000
+#define APLIC_SETIPNUM_BE		0x2004
+
+#define APLIC_GENMSI			0x3000
+
+#define APLIC_TARGET_BASE		0x3004
+#define APLIC_TARGET_HART_IDX_SHIFT	18
+#define APLIC_TARGET_HART_IDX_MASK	0x3fff
+#define APLIC_TARGET_HART_IDX		(APLIC_TARGET_HART_IDX_MASK << \
+					 APLIC_TARGET_HART_IDX_SHIFT)
+#define APLIC_TARGET_GUEST_IDX_SHIFT	12
+#define APLIC_TARGET_GUEST_IDX_MASK	0x3f
+#define APLIC_TARGET_GUEST_IDX		(APLIC_TARGET_GUEST_IDX_MASK << \
+					 APLIC_TARGET_GUEST_IDX_SHIFT)
+#define APLIC_TARGET_IPRIO_SHIFT	0
+#define APLIC_TARGET_IPRIO_MASK		0xff
+#define APLIC_TARGET_IPRIO		(APLIC_TARGET_IPRIO_MASK << \
+					 APLIC_TARGET_IPRIO_SHIFT)
+#define APLIC_TARGET_EIID_SHIFT		0
+#define APLIC_TARGET_EIID_MASK		0x7ff
+#define APLIC_TARGET_EIID		(APLIC_TARGET_EIID_MASK << \
+					 APLIC_TARGET_EIID_SHIFT)
+
+#define APLIC_IDC_BASE			0x4000
+#define APLIC_IDC_SIZE			32
+
+#define APLIC_IDC_IDELIVERY		0x00
+
+#define APLIC_IDC_IFORCE		0x04
+
+#define APLIC_IDC_ITHRESHOLD		0x08
+
+#define APLIC_IDC_TOPI			0x18
+#define APLIC_IDC_TOPI_ID_SHIFT		16
+#define APLIC_IDC_TOPI_ID_MASK		0x3ff
+#define APLIC_IDC_TOPI_ID		(APLIC_IDC_TOPI_ID_MASK << \
+					 APLIC_IDC_TOPI_ID_SHIFT)
+#define APLIC_IDC_TOPI_PRIO_SHIFT	0
+#define APLIC_IDC_TOPI_PRIO_MASK	0xff
+#define APLIC_IDC_TOPI_PRIO		(APLIC_IDC_TOPI_PRIO_MASK << \
+					 APLIC_IDC_TOPI_PRIO_SHIFT)
+
+#define APLIC_IDC_CLAIMI		0x1c
+
+#endif
-- 
2.34.1



From apatel at ventanamicro.com  Sun Feb 25 20:07:45 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:45 +0530
Subject: [PATCH v15 09/10] RISC-V: Select APLIC and IMSIC drivers
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <20240226040746.1396416-10-apatel@ventanamicro.com>

The QEMU virt machine supports AIA emulation and quite a few RISC-V
platforms with AIA support are under development so select APLIC and
IMSIC drivers for all RISC-V platforms.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 arch/riscv/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index bffbd869a068..569f2b6fd60a 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -162,6 +162,8 @@ config RISCV
 	select PCI_DOMAINS_GENERIC if PCI
 	select PCI_MSI if PCI
 	select RISCV_ALTERNATIVE if !XIP_KERNEL
+	select RISCV_APLIC
+	select RISCV_IMSIC
 	select RISCV_INTC
 	select RISCV_TIMER if RISCV_SBI
 	select SIFIVE_PLIC
-- 
2.34.1



From apatel at ventanamicro.com  Sun Feb 25 20:07:46 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:37:46 +0530
Subject: [PATCH v15 10/10] MAINTAINERS: Add entry for RISC-V AIA drivers
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <20240226040746.1396416-11-apatel@ventanamicro.com>

Add myself as maintainer for RISC-V AIA drivers including the
RISC-V INTC driver which supports both AIA and non-AIA platforms.

Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 MAINTAINERS | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ed4d3868539..d948f9210f1b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18801,6 +18801,20 @@ S:	Maintained
 F:	drivers/mtd/nand/raw/r852.c
 F:	drivers/mtd/nand/raw/r852.h
 
+RISC-V AIA DRIVERS
+M:	Anup Patel <anup at brainfault.org>
+L:	linux-riscv at lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
+F:	Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
+F:	drivers/irqchip/irq-riscv-aplic-*.c
+F:	drivers/irqchip/irq-riscv-aplic-*.h
+F:	drivers/irqchip/irq-riscv-imsic-*.c
+F:	drivers/irqchip/irq-riscv-imsic-*.h
+F:	drivers/irqchip/irq-riscv-intc.c
+F:	include/linux/irqchip/riscv-aplic.h
+F:	include/linux/irqchip/riscv-imsic.h
+
 RISC-V ARCHITECTURE
 M:	Paul Walmsley <paul.walmsley at sifive.com>
 M:	Palmer Dabbelt <palmer at dabbelt.com>
-- 
2.34.1



From andrew at codeconstruct.com.au  Sun Feb 25 20:12:27 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Mon, 26 Feb 2024 14:42:27 +1030
Subject: [PATCH v1 10/14] serial: 8250_of: Switch to use
 uart_read_port_properties()
In-Reply-To: <Zdd6lnXwvpPPUhRR@smile.fi.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
	 <20240221183442.4124354-11-andriy.shevchenko@linux.intel.com>
	 <0a828f2c50de712940fb9a881702ac1678a35b7c.camel@codeconstruct.com.au>
	 <ZddKzHplwOX7naLv@smile.fi.intel.com> <Zdd5m2xIPlGI0_Qv@smile.fi.intel.com>
	 <Zdd6lnXwvpPPUhRR@smile.fi.intel.com>
Message-ID: <ab237d0e08b6919d29f25d89ec34d149341f4c57.camel@codeconstruct.com.au>

On Thu, 2024-02-22 at 18:47 +0200, Andy Shevchenko wrote:
> On Thu, Feb 22, 2024 at 06:43:08PM +0200, Andy Shevchenko wrote:
> > On Thu, Feb 22, 2024 at 03:23:24PM +0200, Andy Shevchenko wrote:
> > > On Thu, Feb 22, 2024 at 11:07:05AM +1030, Andrew Jeffery wrote:
> > > > On Wed, 2024-02-21 at 20:31 +0200, Andy Shevchenko wrote:
> > > > > Since we have now a common helper to read port properties
> > > > > use it instead of sparse home grown solution.
> > > > 
> > > > I did some brief testing of the series for the Aspeed machines under
> > > > qemu, building them on top of v6.8-rc5:
> > > > 
> > > > export ARCH=arm
> > > > export CROSS_COMPILE=arm-linux-gnueabihf-
> > > > make aspeed_g5_defconfig
> > > > make -j$(nproc)
> > > > qemu-system-arm -M rainier-bmc -nographic -no-reboot -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-rainier.dtb -initrd ...
> > > > 
> > > > I got an oops during boot, which bisected to this change:
> > > 
> > > Thank you for prompt testing! I will look at it.
> > 
> > I found the issue, will be fixed in next version.
> 
> Whoever is going to test this series, the
> 
> -		port->iotype = use_defaults ? UPIO_MEM : port->iotype;
> +		port->iotype = UPIO_MEM;
> 
> should be applied to uart_read_port_properties() implementation.
> 

Thanks, with that fix applied it works fine for me also.

Andrew


From andrew at codeconstruct.com.au  Sun Feb 25 20:13:13 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Mon, 26 Feb 2024 14:43:13 +1030
Subject: [PATCH v1 04/14] serial: 8250_aspeed_vuart: Switch to use
 uart_read_port_properties()
In-Reply-To: <20240221183442.4124354-5-andriy.shevchenko@linux.intel.com>
References: <20240221183442.4124354-1-andriy.shevchenko@linux.intel.com>
	 <20240221183442.4124354-5-andriy.shevchenko@linux.intel.com>
Message-ID: <00b5f735bd9c151812445d40348d70f4b4bd474d.camel@codeconstruct.com.au>

On Wed, 2024-02-21 at 20:31 +0200, Andy Shevchenko wrote:
> Since we have now a common helper to read port properties
> use it instead of sparse home grown solution.
> 
> Reviewed-by: Andi Shyti <andi.shyti at linux.intel.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>

Reviewed-by: Andrew Jeffery <andrew at codeconstruct.com.au>


From apatel at ventanamicro.com  Sun Feb 25 20:14:59 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 26 Feb 2024 09:44:59 +0530
Subject: [PATCH v15 00/10] Linux RISC-V AIA Support
In-Reply-To: <20240226040746.1396416-1-apatel@ventanamicro.com>
References: <20240226040746.1396416-1-apatel@ventanamicro.com>
Message-ID: <CAK9=C2W7LfM0BNQf=ovVzDjqsCoqS=5RvTUFn33SH9EVm6xjmw@mail.gmail.com>

Hi Thomas,

On Mon, Feb 26, 2024 at 9:39?AM Anup Patel <apatel at ventanamicro.com> wrote:
>
> The RISC-V AIA specification is ratified as-per the RISC-V international
> process. The latest ratified AIA specifcation can be found at:
> https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf
>
> At a high-level, the AIA specification adds three things:
> 1) AIA CSRs
>    - Improved local interrupt support
> 2) Incoming Message Signaled Interrupt Controller (IMSIC)
>    - Per-HART MSI controller
>    - Support MSI virtualization
>    - Support IPI along with virtualization
> 3) Advanced Platform-Level Interrupt Controller (APLIC)
>    - Wired interrupt controller
>    - In MSI-mode, converts wired interrupt into MSIs (i.e. MSI generator)
>    - In Direct-mode, injects external interrupts directly into HARTs
>
> For an overview of the AIA specification, refer the AIA virtualization
> talk at KVM Forum 2022:
> https://static.sched.com/hosted_files/kvmforum2022/a1/AIA_Virtualization_in_KVM_RISCV_final.pdf
> https://www.youtube.com/watch?v=r071dL8Z0yo
>
> To test this series, use QEMU v7.2 (or higher) and OpenSBI v1.2 (or higher).
>
> This series depends upon per-device MSI domain (and few other) patches merged
> by Thomas (tglx) which are available in irq/msi branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git
>
> These patches can also be found in the riscv_aia_v15 branch at:
> https://github.com/avpatel/linux.git
>
> Changes since v14:
>  - Dropped 9 patches which are already merged by Thomas (tglx) and available in
>    his irq/msi branch at git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git
>  - Added new PATCH1 which adds changes missed out in merging AIA support for
>    RISC-V INTC.
>  - Added a separate cpuhp state for IMSIC driver in PATCH3 which ensures that
>    cpuhp notifiers of IMSIC are called as early as possible.
>  - Removed redundant barriers in PATCH3.
>  - Addressed few other nit comments.
>
> Changes since v13:
>  - Split PATCH1 into six granular patches
>  - Addressed nit comments from Thomas and Bjorn
>
> Changes since v12:
>  - Rebased on Linux-6.8-rc5
>  - Dropped per-device MSI domain patches which are already merged by Thomas (tglx)
>  - Addressed nit comments from Thomas and Clement
>  - Added a new patch2 to fix lock dependency warning
>  - Replaced local sync IPI in the IMSIC driver with per-CPU timer
>  - Simplified locking in the IMSIC driver to avoid lock dependency issues
>  - Added a dirty bitmap in the IMSIC driver to optimize per-CPU local sync loop
>
> Changes since v11:
>  - Rebased on Linux-6.8-rc1
>  - Included kernel/irq related patches from "genirq, irqchip: Convert ARM
>    MSI handling to per device MSI domains" series by Thomas.
>    (PATCH7, PATCH8, PATCH9, PATCH14, PATCH16, PATCH17, PATCH18, PATCH19,
>     PATCH20, PATCH21, PATCH22, PATCH23, and PATCH32 of
>     https://lore.kernel.org/linux-arm-kernel/20221121135653.208611233 at linutronix.de/)
>  - Updated APLIC MSI-mode driver to use the new WIRED_TO_MSI mechanism.
>  - Updated IMSIC driver to support per-device MSI domains for PCI and
>    platform devices.
>
> Changes since v10:
>  - Rebased on Linux-6.6-rc7
>  - Dropped PATCH3 of v10 series since this has been merged by MarcZ
>    for Linux-6.6-rc7
>  - Changed the IMSIC ID management strategy from 1-n approach to
>    x86-style 1-1 approach
>
> Changes since v9:
>  - Rebased on Linux-6.6-rc4
>  - Use builtin_platform_driver() in PATCH5, PATCH9, and PATCH12
>
> Changes since v8:
>  - Rebased on Linux-6.6-rc3
>  - Dropped PATCH2 of v8 series since we won't be requiring
>    riscv_get_intc_hartid() based on Marc Z's comments on ACPI AIA support.
>  - Addressed Saravana's comments in PATCH3 of v8 series
>  - Update PATCH9 and PATCH13 of v8 series based on comments from Sunil
>
> Changes since v7:
>  - Rebased on Linux-6.6-rc1
>  - Addressed comments on PATCH1 of v7 series and split it into two PATCHes
>  - Use DEFINE_SIMPLE_PROP() in PATCH2 of v7 series
>
> Changes since v6:
>  - Rebased on Linux-6.5-rc4
>  - Updated PATCH2 to use IS_ENABLED(CONFIG_SPARC) instead of
>    !IS_ENABLED(CONFIG_OF_IRQ)
>  - Added new PATCH4 to fix syscore registration in PLIC driver
>  - Update PATCH5 to convert PLIC driver into full-blown platform driver
>    with a re-written probe function.
>
> Changes since v5:
>  - Rebased on Linux-6.5-rc2
>  - Updated the overall series to ensure that only IPI, timer, and
>    INTC drivers are probed very early whereas rest of the interrupt
>    controllers (such as PLIC, APLIC, and IMISC) are probed as
>    regular platform drivers.
>  - Renamed riscv_fw_parent_hartid() to riscv_get_intc_hartid()
>  - New PATCH1 to add fw_devlink support for msi-parent DT property
>  - New PATCH2 to ensure all INTC suppliers are initialized which in-turn
>    fixes the probing issue for PLIC, APLIC and IMSIC as platform driver
>  - New PATCH3 to use platform driver probing for PLIC
>  - Re-structured the IMSIC driver into two separate drivers: early and
>    platform. The IMSIC early driver (PATCH7) only initialized IMSIC state
>    and provides IPIs whereas the IMSIC platform driver (PATCH8) is probed
>    provides MSI domain for platform devices.
>  - Re-structure the APLIC platform driver into three separe sources: main,
>    direct mode, and MSI mode.
>
> Changes since v4:
>  - Rebased on Linux-6.5-rc1
>  - Added "Dependencies" in the APLIC bindings (PATCH6 in v4)
>  - Dropped the PATCH6 which was changing the IOMMU DMA domain APIs
>  - Dropped use of IOMMU DMA APIs in the IMSIC driver (PATCH4)
>
> Changes since v3:
>  - Rebased on Linux-6.4-rc6
>  - Dropped PATCH2 of v3 series instead we now set FWNODE_FLAG_BEST_EFFORT via
>    IRQCHIP_DECLARE()
>  - Extend riscv_fw_parent_hartid() to support both DT and ACPI in PATCH1
>  - Extend iommu_dma_compose_msi_msg() instead of adding iommu_dma_select_msi()
>    in PATCH6
>  - Addressed Conor's comments in PATCH3
>  - Addressed Conor's and Rob's comments in PATCH7
>
> Changes since v2:
>  - Rebased on Linux-6.4-rc1
>  - Addressed Rob's comments on DT bindings patches 4 and 8.
>  - Addessed Marc's comments on IMSIC driver PATCH5
>  - Replaced use of OF apis in APLIC and IMSIC drivers with FWNODE apis
>    this makes both drivers easily portable for ACPI support. This also
>    removes unnecessary indirection from the APLIC and IMSIC drivers.
>  - PATCH1 is a new patch for portability with ACPI support
>  - PATCH2 is a new patch to fix probing in APLIC drivers for APLIC-only systems.
>  - PATCH7 is a new patch which addresses the IOMMU DMA domain issues pointed
>    out by SiFive
>
> Changes since v1:
>  - Rebased on Linux-6.2-rc2
>  - Addressed comments on IMSIC DT bindings for PATCH4
>  - Use raw_spin_lock_irqsave() on ids_lock for PATCH5
>  - Improved MMIO alignment checks in PATCH5 to allow MMIO regions
>    with holes.
>  - Addressed comments on APLIC DT bindings for PATCH6
>  - Fixed warning splat in aplic_msi_write_msg() caused by
>    zeroed MSI message in PATCH7
>  - Dropped DT property riscv,slow-ipi instead will have module
>    parameter in future.
>
> Anup Patel (10):
>   irqchip/riscv-intc: Fix low-level interrupt handler setup for AIA
>   dt-bindings: interrupt-controller: Add RISC-V incoming MSI controller
>   irqchip: Add RISC-V incoming MSI controller early driver
>   irqchip/riscv-imsic: Add device MSI domain support for platform
>     devices
>   irqchip/riscv-imsic: Add device MSI domain support for PCI devices
>   dt-bindings: interrupt-controller: Add RISC-V advanced PLIC
>   irqchip: Add RISC-V advanced PLIC driver for direct-mode
>   irqchip/riscv-aplic: Add support for MSI-mode
>   RISC-V: Select APLIC and IMSIC drivers
>   MAINTAINERS: Add entry for RISC-V AIA drivers
>
>  .../interrupt-controller/riscv,aplic.yaml     | 172 ++++
>  .../interrupt-controller/riscv,imsics.yaml    | 172 ++++
>  MAINTAINERS                                   |  14 +
>  arch/riscv/Kconfig                            |   2 +
>  drivers/irqchip/Kconfig                       |  25 +
>  drivers/irqchip/Makefile                      |   3 +
>  drivers/irqchip/irq-riscv-aplic-direct.c      | 326 +++++++
>  drivers/irqchip/irq-riscv-aplic-main.c        | 211 +++++
>  drivers/irqchip/irq-riscv-aplic-main.h        |  52 ++
>  drivers/irqchip/irq-riscv-aplic-msi.c         | 263 ++++++
>  drivers/irqchip/irq-riscv-imsic-early.c       | 201 ++++
>  drivers/irqchip/irq-riscv-imsic-platform.c    | 374 ++++++++
>  drivers/irqchip/irq-riscv-imsic-state.c       | 865 ++++++++++++++++++
>  drivers/irqchip/irq-riscv-imsic-state.h       | 108 +++
>  drivers/irqchip/irq-riscv-intc.c              |  10 +-
>  include/linux/cpuhotplug.h                    |   1 +
>  include/linux/irqchip/riscv-aplic.h           | 145 +++
>  include/linux/irqchip/riscv-imsic.h           |  87 ++
>  18 files changed, 3028 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,aplic.yaml
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,imsics.yaml
>  create mode 100644 drivers/irqchip/irq-riscv-aplic-direct.c
>  create mode 100644 drivers/irqchip/irq-riscv-aplic-main.c
>  create mode 100644 drivers/irqchip/irq-riscv-aplic-main.h
>  create mode 100644 drivers/irqchip/irq-riscv-aplic-msi.c
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-early.c
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-platform.c
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-state.c
>  create mode 100644 drivers/irqchip/irq-riscv-imsic-state.h
>  create mode 100644 include/linux/irqchip/riscv-aplic.h
>  create mode 100644 include/linux/irqchip/riscv-imsic.h
>
> --
> 2.34.1
>

My email client reported "There was a problem delivering your
message to tglx at linutronix.de."

Link to this series is
https://lore.kernel.org/all/20240226040746.1396416-1-apatel at ventanamicro.com/

Let me know if you want me to re-send this series.

Regards,
Anup


From anshuman.khandual at arm.com  Sun Feb 25 20:22:49 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 26 Feb 2024 09:52:49 +0530
Subject: [PATCH] arm64/hw_breakpoint: Determine lengths from generic perf breakpoint macros
In-Reply-To: <20240125094119.2542332-2-anshuman.khandual@arm.com>
References: <20240125094119.2542332-2-anshuman.khandual@arm.com>
Message-ID: <20240226042249.4098185-1-anshuman.khandual@arm.com>

Both platform i.e ARM_BREAKPOINT_LEN_X and generic i.e HW_BREAKPOINT_LEN_X
macros are used interchangeably to convert event->attr.bp_len and platform
breakpoint control arch_hw_breakpoint_ctrl->len. Let's be consistent while
deriving one from the other. This does not cause any functional changes.

Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas 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 v6.8-rc5

 arch/arm64/kernel/hw_breakpoint.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 35225632d70a..1ab9fc865ddd 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -301,28 +301,28 @@ static int get_hbp_len(u8 hbp_len)
 
 	switch (hbp_len) {
 	case ARM_BREAKPOINT_LEN_1:
-		len_in_bytes = 1;
+		len_in_bytes = HW_BREAKPOINT_LEN_1;
 		break;
 	case ARM_BREAKPOINT_LEN_2:
-		len_in_bytes = 2;
+		len_in_bytes = HW_BREAKPOINT_LEN_2;
 		break;
 	case ARM_BREAKPOINT_LEN_3:
-		len_in_bytes = 3;
+		len_in_bytes = HW_BREAKPOINT_LEN_3;
 		break;
 	case ARM_BREAKPOINT_LEN_4:
-		len_in_bytes = 4;
+		len_in_bytes = HW_BREAKPOINT_LEN_4;
 		break;
 	case ARM_BREAKPOINT_LEN_5:
-		len_in_bytes = 5;
+		len_in_bytes = HW_BREAKPOINT_LEN_5;
 		break;
 	case ARM_BREAKPOINT_LEN_6:
-		len_in_bytes = 6;
+		len_in_bytes = HW_BREAKPOINT_LEN_6;
 		break;
 	case ARM_BREAKPOINT_LEN_7:
-		len_in_bytes = 7;
+		len_in_bytes = HW_BREAKPOINT_LEN_7;
 		break;
 	case ARM_BREAKPOINT_LEN_8:
-		len_in_bytes = 8;
+		len_in_bytes = HW_BREAKPOINT_LEN_8;
 		break;
 	}
 
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Feb 25 20:24:41 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 26 Feb 2024 09:54:41 +0530
Subject: [PATCH] arm64/sysreg: Add BRBE registers and fields
In-Reply-To: <20240125094119.2542332-2-anshuman.khandual@arm.com>
References: <20240125094119.2542332-2-anshuman.khandual@arm.com>
Message-ID: <20240226042441.4098806-1-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. While here, this drops redundant register definitions
from the header i.e (arch/arm64/include/asm/sysreg.h).

BRBINFx_EL1_TYPE_IMPDEF_TRAP_EL3 register field value has been derived from
latest ARM DDI 0601 ID121123, AKA 2023-12 instead of latest ARM ARM i.e ARM
DDI 0487J.a. Please find the definition here.

https://developer.arm.com/documentation/ddi0601/2023-12/

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Marc Zyngier <maz 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>
---
Please find the modified patch here for a quick review and do let me know
if this looks good for the next version i.e V17. BRBCR_EL1/12/2 organized
per their encoding. Thanks !

 arch/arm64/include/asm/sysreg.h |  17 ++---
 arch/arm64/tools/sysreg         | 131 ++++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index c3b19b376c86..481c7d186dfa 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -195,16 +195,8 @@
 #define SYS_DBGVCR32_EL2		sys_reg(2, 4, 0, 7, 0)
 
 #define SYS_BRBINF_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 0))
-#define SYS_BRBINFINJ_EL1		sys_reg(2, 1, 9, 1, 0)
 #define SYS_BRBSRC_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 1))
-#define SYS_BRBSRCINJ_EL1		sys_reg(2, 1, 9, 1, 1)
 #define SYS_BRBTGT_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 2))
-#define SYS_BRBTGTINJ_EL1		sys_reg(2, 1, 9, 1, 2)
-#define SYS_BRBTS_EL1			sys_reg(2, 1, 9, 0, 2)
-
-#define SYS_BRBCR_EL1			sys_reg(2, 1, 9, 0, 0)
-#define SYS_BRBFCR_EL1			sys_reg(2, 1, 9, 0, 1)
-#define SYS_BRBIDR0_EL1			sys_reg(2, 1, 9, 2, 0)
 
 #define SYS_TRCITECR_EL1		sys_reg(3, 0, 1, 2, 3)
 #define SYS_TRCACATR(m)			sys_reg(2, 1, 2, ((m & 7) << 1), (2 | (m >> 3)))
@@ -270,8 +262,6 @@
 /* ETM */
 #define SYS_TRCOSLAR			sys_reg(2, 1, 1, 0, 4)
 
-#define SYS_BRBCR_EL2			sys_reg(2, 4, 9, 0, 0)
-
 #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)
@@ -601,7 +591,6 @@
 #define SYS_CNTHV_CVAL_EL2		sys_reg(3, 4, 14, 3, 2)
 
 /* VHE encodings for architectural EL0/1 system registers */
-#define SYS_BRBCR_EL12			sys_reg(2, 5, 9, 0, 0)
 #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
 #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
 #define SYS_SCTLR2_EL12			sys_reg(3, 5, 1, 0, 3)
@@ -794,6 +783,12 @@
 #define OP_COSP_RCTX			sys_insn(1, 3, 7, 3, 6)
 #define OP_CPP_RCTX			sys_insn(1, 3, 7, 3, 7)
 
+/*
+ * BRBE Instructions
+ */
+#define BRB_IALL_INSN	__emit_inst(0xd5000000 | OP_BRB_IALL | (0x1f))
+#define BRB_INJ_INSN	__emit_inst(0xd5000000 | OP_BRB_INJ  | (0x1f))
+
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_ENTP2	(BIT(60))
 #define SCTLR_ELx_DSSBS	(BIT(44))
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 4c9b67934367..60d288cbd5eb 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1023,6 +1023,137 @@ UnsignedEnum	3:0	MTEPERM
 EndEnum
 EndSysreg
 
+
+SysregFields BRBINFx_EL1
+Res0	63:47
+Field	46	CCU
+Field	45:32	CC
+Res0	31:18
+Field	17	LASTFAILED
+Field	16	T
+Res0	15:14
+Enum	13:8		TYPE
+	0b000000	DIRECT_UNCOND
+	0b000001	INDIRECT
+	0b000010	DIRECT_LINK
+	0b000011	INDIRECT_LINK
+	0b000101	RET
+	0b000111	ERET
+	0b001000	DIRECT_COND
+	0b100001	DEBUG_HALT
+	0b100010	CALL
+	0b100011	TRAP
+	0b100100	SERROR
+	0b100110	INSN_DEBUG
+	0b100111	DATA_DEBUG
+	0b101010	ALIGN_FAULT
+	0b101011	INSN_FAULT
+	0b101100	DATA_FAULT
+	0b101110	IRQ
+	0b101111	FIQ
+	0b110000	IMPDEF_TRAP_EL3
+	0b111001	DEBUG_EXIT
+EndEnum
+Enum	7:6	EL
+	0b00	EL0
+	0b01	EL1
+	0b10	EL2
+	0b11	EL3
+EndEnum
+Field	5	MPRED
+Res0	4:2
+Enum	1:0	VALID
+	0b00	NONE
+	0b01	TARGET
+	0b10	SOURCE
+	0b11	FULL
+EndEnum
+EndSysregFields
+
+SysregFields	BRBCR_ELx
+Res0	63:24
+Field	23 	EXCEPTION
+Field	22 	ERTN
+Res0	21:10
+Field	9	FZPSS
+Field	8 	FZP
+Res0	7
+Enum	6:5	TS
+	0b01	VIRTUAL
+	0b10	GUEST_PHYSICAL
+	0b11	PHYSICAL
+EndEnum
+Field	4	MPRED
+Field	3	CC
+Res0	2
+Field	1	ExBRE
+Field	0	E0BRE
+EndSysregFields
+
+Sysreg	BRBCR_EL1	2	1	9	0	0
+Fields	BRBCR_ELx
+EndSysreg
+
+Sysreg	BRBFCR_EL1	2	1	9	0	1
+Res0	63:30
+Enum	29:28	BANK
+	0b00	BANK_0
+	0b01	BANK_1
+EndEnum
+Res0	27:23
+Field	22	CONDDIR
+Field	21	DIRCALL
+Field	20	INDCALL
+Field	19	RTN
+Field	18	INDIRECT
+Field	17	DIRECT
+Field	16	EnI
+Res0	15:8
+Field	7	PAUSED
+Field	6	LASTFAILED
+Res0	5:0
+EndSysreg
+
+Sysreg	BRBTS_EL1	2	1	9	0	2
+Field	63:0	TS
+EndSysreg
+
+Sysreg	BRBINFINJ_EL1	2	1	9	1	0
+Fields BRBINFx_EL1
+EndSysreg
+
+Sysreg	BRBSRCINJ_EL1	2	1	9	1	1
+Field	63:0 ADDRESS
+EndSysreg
+
+Sysreg	BRBTGTINJ_EL1	2	1	9	1	2
+Field	63:0 ADDRESS
+EndSysreg
+
+Sysreg	BRBIDR0_EL1	2	1	9	2	0
+Res0	63:16
+Enum	15:12	CC
+	0b101	20_BIT
+EndEnum
+Enum	11:8	FORMAT
+	0b0	0
+EndEnum
+Enum	7:0		NUMREC
+	0b00001000	8
+	0b00010000	16
+	0b00100000	32
+	0b01000000	64
+EndEnum
+EndSysreg
+
+Sysreg	BRBCR_EL2	2	4	9	0	0
+Fields	BRBCR_ELx
+EndSysreg
+
+Sysreg	BRBCR_EL12	2	5	9	0	0
+Fields	BRBCR_ELx
+EndSysreg
+
 Sysreg	ID_AA64ZFR0_EL1	3	0	0	4	4
 Res0	63:60
 UnsignedEnum	59:56	F64MM
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Feb 25 20:26:33 2024
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 26 Feb 2024 09:56:33 +0530
Subject: [PATCH] arm64/hw_breakpoint: Determine lengths from generic perf
 breakpoint macros
In-Reply-To: <20240226042249.4098185-1-anshuman.khandual@arm.com>
References: <20240125094119.2542332-2-anshuman.khandual@arm.com>
 <20240226042249.4098185-1-anshuman.khandual@arm.com>
Message-ID: <21ee46a1-5e5a-4e8a-b1ba-e7f26c39e325@arm.com>



On 2/26/24 09:52, Anshuman Khandual wrote:
> Both platform i.e ARM_BREAKPOINT_LEN_X and generic i.e HW_BREAKPOINT_LEN_X
> macros are used interchangeably to convert event->attr.bp_len and platform
> breakpoint control arch_hw_breakpoint_ctrl->len. Let's be consistent while
> deriving one from the other. This does not cause any functional changes.
> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas 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 v6.8-rc5
> 
>  arch/arm64/kernel/hw_breakpoint.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
> index 35225632d70a..1ab9fc865ddd 100644
> --- a/arch/arm64/kernel/hw_breakpoint.c
> +++ b/arch/arm64/kernel/hw_breakpoint.c
> @@ -301,28 +301,28 @@ static int get_hbp_len(u8 hbp_len)
>  
>  	switch (hbp_len) {
>  	case ARM_BREAKPOINT_LEN_1:
> -		len_in_bytes = 1;
> +		len_in_bytes = HW_BREAKPOINT_LEN_1;
>  		break;
>  	case ARM_BREAKPOINT_LEN_2:
> -		len_in_bytes = 2;
> +		len_in_bytes = HW_BREAKPOINT_LEN_2;
>  		break;
>  	case ARM_BREAKPOINT_LEN_3:
> -		len_in_bytes = 3;
> +		len_in_bytes = HW_BREAKPOINT_LEN_3;
>  		break;
>  	case ARM_BREAKPOINT_LEN_4:
> -		len_in_bytes = 4;
> +		len_in_bytes = HW_BREAKPOINT_LEN_4;
>  		break;
>  	case ARM_BREAKPOINT_LEN_5:
> -		len_in_bytes = 5;
> +		len_in_bytes = HW_BREAKPOINT_LEN_5;
>  		break;
>  	case ARM_BREAKPOINT_LEN_6:
> -		len_in_bytes = 6;
> +		len_in_bytes = HW_BREAKPOINT_LEN_6;
>  		break;
>  	case ARM_BREAKPOINT_LEN_7:
> -		len_in_bytes = 7;
> +		len_in_bytes = HW_BREAKPOINT_LEN_7;
>  		break;
>  	case ARM_BREAKPOINT_LEN_8:
> -		len_in_bytes = 8;
> +		len_in_bytes = HW_BREAKPOINT_LEN_8;
>  		break;
>  	}
>  

Please ignore this. Wrong patch got picked up in the git send-email :)


From robh at kernel.org  Sun Feb 25 20:32:57 2024
From: robh at kernel.org (Rob Herring)
Date: Sun, 25 Feb 2024 22:32:57 -0600
Subject: [PATCH v2] dt-bindings: gpio: aspeed,ast2400-gpio: Convert to
 DT schema
In-Reply-To: <20240226031951.284847-1-andrew@codeconstruct.com.au>
References: <20240226031951.284847-1-andrew@codeconstruct.com.au>
Message-ID: <170892197611.2260479.15343562563553959436.robh@kernel.org>


On Mon, 26 Feb 2024 13:49:51 +1030, Andrew Jeffery wrote:
> Squash warnings such as:
> 
> ```
> arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-galaxy100.dtb: /ahb/apb at 1e600000/gpio at 1e780000: failed to match any schema with compatible: ['aspeed,ast2400-gpio']
> ```
> 
> Signed-off-by: Andrew Jeffery <andrew at codeconstruct.com.au>
> ---
> v2: Address feedback from Krzysztof:
>     https://lore.kernel.org/all/0d1dd262-b6dd-4d71-9239-8b0aec8cceff at linaro.org/
> 
> v1: https://lore.kernel.org/all/20240220052918.742793-1-andrew at codeconstruct.com.au/
> 
>  .../bindings/gpio/aspeed,ast2400-gpio.yaml    | 73 +++++++++++++++++++
>  .../devicetree/bindings/gpio/gpio-aspeed.txt  | 39 ----------
>  2 files changed, 73 insertions(+), 39 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
>  delete mode 100644 Documentation/devicetree/bindings/gpio/gpio-aspeed.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/dt-review-ci/linux/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.example.dtb: gpio at 1e780000: '#interrupt-cells' is a required property
	from schema $id: http://devicetree.org/schemas/gpio/aspeed,ast2400-gpio.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240226031951.284847-1-andrew at codeconstruct.com.au

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

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 after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From uwu at icenowy.me  Sun Feb 25 20:56:55 2024
From: uwu at icenowy.me (Icenowy Zheng)
Date: Mon, 26 Feb 2024 12:56:55 +0800
Subject: [PATCH v2 5/6] drm/panel: st7703: Drive XBD599 panel at higher
 clock rate
In-Reply-To: <87o7c4mqzr.fsf@oltmanns.dev>
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
	 <20240205-pinephone-pll-fixes-v2-5-96a46a2d8c9b@oltmanns.dev>
	 <poua4bzyciiwt65sqjf2whqfdumvoe4h3bkjpf64px2vwgumrf@sai73byg2iju>
	 <87sf1zxb0s.fsf@oltmanns.dev>
	 <ia7e7gqozltl5wkfdvwtf2rw2ko2dt67qxtuqbavsroyv4ifys@x4mbulqhhri5>
	 <87o7c4mqzr.fsf@oltmanns.dev>
Message-ID: <02c27b503f379aff28563dda6ad7e2718fe7229f.camel@icenowy.me>

? 2024-02-25???? 17:46 +0100?Frank Oltmanns???
> Hi Maxime,
> 
> On 2024-02-22 at 11:29:51 +0100, Maxime Ripard <mripard at kernel.org>
> wrote:
> > [[PGP Signed Part:Undecided]]
> > On Sun, Feb 11, 2024 at 04:42:43PM +0100, Frank Oltmanns wrote:
> > > 
> > > On 2024-02-08 at 20:05:08 +0100, Maxime Ripard
> > > <mripard at kernel.org> wrote:
> > > > [[PGP Signed Part:Undecided]]
> > > > Hi Frank,
> > > > 
> > > > On Mon, Feb 05, 2024 at 04:22:28PM +0100, Frank Oltmanns wrote:
> > > > > This panel is used in the pinephone that runs on a Allwinner
> > > > > A64 SOC.
> > > > > The SOC requires pll-mipi to run at more than 500 MHz.
> > > > > 
> > > > > This is the relevant clock tree:
> > > > > ?pll-mipi
> > > > > ??? tcon0
> > > > > ?????? tcon-data-clock
> > > > > 
> > > > > tcon-data-clock has to run at 1/4 the DSI per-lane bit rate.
> > > > > The XBD599
> > > > > has 24 bpp and 4 lanes. Therefore, the resulting requested
> > > > > tcon-data-clock rate is:
> > > > > ??? crtc_clock * 1000 * (24 / 4) / 4
> > > > > 
> > > > > tcon-data-clock runs at tcon0 / 4 (fixed divisor), so it
> > > > > requests a
> > > > > parent rate of
> > > > > ??? 4 * (crtc_clock * 1000 * (24 / 4) / 4)
> > > > > 
> > > > > Since tcon0 is a ccu_mux, the rate of tcon0 equals the rate
> > > > > of pll-mipi.
> > > > > 
> > > > > pll-mipi's constraint to run at 500MHz or higher forces us to
> > > > > have a
> > > > > crtc_clock >= 83333 kHz if we want a 60 Hz vertical refresh
> > > > > rate.
> > > > > 
> > > > > Change [hv]sync_(start|end) so that we reach a clock rate of
> > > > > 83502 kHz
> > > > > so that it is high enough to align with pll-pipi limits.
> > > > > 
> > > > > Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
> > > > 
> > > > That commit log is great, but it's kind of off-topic. It's a
> > > > panel
> > > > driver, it can be used on any MIPI-DSI controller, the only
> > > > relevant
> > > > information there should be the panel timings required in the
> > > > datasheet.
> > > > 
> > > > The PLL setup is something for the MIPI-DSI driver to adjust,
> > > > not for
> > > > the panel to care for.
> > > > 
> > > 
> > > I absolutely agree. It even was the reason for my submission of a
> > > sunxi-ng patch series last year that was accepted, to make pll-
> > > mipi more
> > > flexible. :)
> > > 
> > > The only remaining option I currently see for adjusting the
> > > sunxi-ng
> > > driver to further accomodate the panel, is trying to use a higher
> > > divisor than 4 for calculating tcon-data-clock from tcon0. I
> > > remember
> > > reading a discussion about this, but as far as I remember that
> > > proposal
> > > was rejected (by you, IIRC).
> > > 
> > > While I appreciate other suggestion as well, I'll look into
> > > options for
> > > using a different divisor than 4.
> > 
> > Like I said, I'm not against the patch at all, it looks great to me
> > on
> > principle. I just think you should completely rephrase the commit
> > log
> > using the datasheet as the only reliable source of the display
> > timings.
> > Whether sun4i can work around the panel requirements is something
> > completely orthogonal to the discussion, and thus the commit log.
> > 
> 
> I was trying to follow the guidelines [1] for describing the reason
> behind my changes to the panel. My original commit message was a lot
> shorter, which, understandably, resulted in follow up questions [2].
> With the current commit log, I'm trying to address those questions.
> According to the device tree, the panel is only used in the
> pinephone.
> The only reason for the change is that the SoC used by the only user
> of
> this panel can not provide the rate the panel requests with the
> current
> values. I think this information is relevant.
> 
> Unfortunately, as described in [2], I cannot back these values with
> any
> datasheets because I couldn't find any. I could only find hints that
> they are not publicly available. Icenowy (added to CC) submitted the
> original values.

Sorry but this kind of things are just magic from the vendor that I
could hardly explain...

> 
> Best regards,
> ? Frank
> 
> [1]:
> https://www.kernel.org/doc/html/v6.7/process/submitting-patches.html#describe-your-changes
> [2]: https://lore.kernel.org/lkml/87wmsvo0fh.fsf at oltmanns.dev/
> 
> > 
> > Maxime
> > 
> > [[End of PGP Signed Part]]
> 



From andrew at codeconstruct.com.au  Sun Feb 25 21:16:45 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Mon, 26 Feb 2024 15:46:45 +1030
Subject: [PATCH v3] dt-bindings: gpio: aspeed,ast2400-gpio: Convert to DT schema
Message-ID: <20240226051645.414935-1-andrew@codeconstruct.com.au>

Squash warnings such as:

```
arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-galaxy100.dtb: /ahb/apb at 1e600000/gpio at 1e780000: failed to match any schema with compatible: ['aspeed,ast2400-gpio']
```

Signed-off-by: Andrew Jeffery <andrew at codeconstruct.com.au>
---
v3: Base on v6.8-rc6, fix yamllint warning

    Rob's bot picked the missing `#interrupt-cells` in the example on v2[1]. The
    patch was based on v6.8-rc1, and going back over my shell history I missed
    the following output from `make dt_binding_check`:

    ```
    ...
      LINT    Documentation/devicetree/bindings
      usage: yamllint [-h] [-] [-c CONFIG_FILE | -d CONFIG_DATA] [--list-files] [-f {parsable,standard,colored,github,auto}] [-s] [--no-warnings] [-v] [FILE_OR_DIR ...]
      yamllint: error: one of the arguments FILE_OR_DIR - is required   
    ...
    ```

    I've rebased on v6.8-rc6 and no-longer see the issue with the invocation
    of `yamllint`.

[1]: https://lore.kernel.org/all/170892197611.2260479.15343562563553959436.robh at kernel.org/

v2: https://lore.kernel.org/all/20240226031951.284847-1-andrew at codeconstruct.com.au/

    Address feedback from Krzysztof:
    https://lore.kernel.org/all/0d1dd262-b6dd-4d71-9239-8b0aec8cceff at linaro.org/

v1: https://lore.kernel.org/all/20240220052918.742793-1-andrew at codeconstruct.com.au/

 .../bindings/gpio/aspeed,ast2400-gpio.yaml    | 74 +++++++++++++++++++
 .../devicetree/bindings/gpio/gpio-aspeed.txt  | 39 ----------
 2 files changed, 74 insertions(+), 39 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
 delete mode 100644 Documentation/devicetree/bindings/gpio/gpio-aspeed.txt

diff --git a/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
new file mode 100644
index 000000000000..31fa8959c0e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/aspeed,ast2400-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Aspeed GPIO controller
+
+maintainers:
+  - Andrew Jeffery <andrew at codeconstruct.com.au>
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2400-gpio
+      - aspeed,ast2500-gpio
+      - aspeed,ast2600-gpio
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: The clock to use for debounce timings
+
+  gpio-controller: true
+  gpio-line-names: true
+  gpio-ranges: true
+
+  "#gpio-cells":
+    const: 2
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+  ngpios: true
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-controller
+  - "#interrupt-cells"
+  - gpio-controller
+  - "#gpio-cells"
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: aspeed,ast2600-gpio
+    then:
+      required:
+        - ngpios
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio at 1e780000 {
+        compatible = "aspeed,ast2400-gpio";
+        reg = <0x1e780000 0x1000>;
+        interrupts = <20>;
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        gpio-controller;
+        #gpio-cells = <2>;
+    };
diff --git a/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt b/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt
deleted file mode 100644
index b2033fc3a71a..000000000000
--- a/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-Aspeed GPIO controller Device Tree Bindings
--------------------------------------------
-
-Required properties:
-- compatible		: Either "aspeed,ast2400-gpio", "aspeed,ast2500-gpio",
-					or "aspeed,ast2600-gpio".
-
-- #gpio-cells 		: Should be two
-			  - First cell is the GPIO line number
-			  - Second cell is used to specify optional
-			    parameters (unused)
-
-- reg			: Address and length of the register set for the device
-- gpio-controller	: Marks the device node as a GPIO controller.
-- interrupts		: Interrupt specifier (see interrupt bindings for
-			  details)
-- interrupt-controller	: Mark the GPIO controller as an interrupt-controller
-
-Optional properties:
-
-- clocks		: A phandle to the clock to use for debounce timings
-- ngpios		: Number of GPIOs controlled by this controller. Should	be set
-				  when there are multiple GPIO controllers on a SoC (ast2600).
-
-The gpio and interrupt properties are further described in their respective
-bindings documentation:
-
-- Documentation/devicetree/bindings/gpio/gpio.txt
-- Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
-
-  Example:
-	gpio at 1e780000 {
-		#gpio-cells = <2>;
-		compatible = "aspeed,ast2400-gpio";
-		gpio-controller;
-		interrupts = <20>;
-		reg = <0x1e780000 0x1000>;
-		interrupt-controller;
-	};

base-commit: d206a76d7d2726f3b096037f2079ce0bd3ba329b
-- 
2.39.2



From anup at brainfault.org  Sun Feb 25 21:19:48 2024
From: anup at brainfault.org (Anup Patel)
Date: Mon, 26 Feb 2024 10:49:48 +0530
Subject: [PATCH v5 11/12] KVM: riscv: selftests: Change vcpu_has_ext to a
 common function
In-Reply-To: <2c96c61a-2685-4cee-9cef-963ed833bf92@rivosinc.com>
References: <cover.1705916069.git.haibo1.xu@intel.com> <68856b86a93a4188558e5d0ebac0dd6aac8e404c.1705916069.git.haibo1.xu@intel.com>
 <CAOnJCULwRTSnrQkR2o1P53R=tJ3TAxX+y+XRBesW6OFEzgFv2g@mail.gmail.com>
 <CAJve8om2oOLg5-wKX7m7cBTgzwqiMcb35x=nDi1edY8evXjyMw@mail.gmail.com> <2c96c61a-2685-4cee-9cef-963ed833bf92@rivosinc.com>
Message-ID: <CAAhSdy2TVSt=gCJRf78AzXNVFKy8MGJ+QspSEHeedT7GPAYkUQ@mail.gmail.com>

On Wed, Feb 21, 2024 at 2:07?PM Atish Patra <atishp at rivosinc.com> wrote:
>
> On 2/20/24 18:13, Haibo Xu wrote:
> > On Wed, Feb 21, 2024 at 7:03?AM Atish Patra <atishp at atishpatra.org> wrote:
> >>
> >> On Mon, Jan 22, 2024 at 1:48?AM Haibo Xu <haibo1.xu at intel.com> wrote:
> >>>
> >>> Move vcpu_has_ext to the processor.c and rename it to __vcpu_has_ext
> >>> so that other test cases can use it for vCPU extension check.
> >>>
> >>> Signed-off-by: Haibo Xu <haibo1.xu at intel.com>
> >>> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> >>> ---
> >>>   tools/testing/selftests/kvm/include/riscv/processor.h |  2 ++
> >>>   tools/testing/selftests/kvm/lib/riscv/processor.c     | 10 ++++++++++
> >>>   tools/testing/selftests/kvm/riscv/get-reg-list.c      | 11 +----------
> >>>   3 files changed, 13 insertions(+), 10 deletions(-)
> >>>
> >>> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> >>> index b68b1b731a34..bd27e1c67579 100644
> >>> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> >>> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> >>> @@ -42,6 +42,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
> >>>   #define RISCV_ISA_EXT_REG(idx) __kvm_reg_id(KVM_REG_RISCV_ISA_EXT, \
> >>>                                               idx, KVM_REG_SIZE_ULONG)
> >>>
> >>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
> >>> +
> >>>   struct ex_regs {
> >>>          unsigned long ra;
> >>>          unsigned long sp;
> >>> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> >>> index 39a1e9902dec..dad73ce18164 100644
> >>> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> >>> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> >>> @@ -15,6 +15,16 @@
> >>>
> >>>   static vm_vaddr_t exception_handlers;
> >>>
> >>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> >>> +{
> >>> +       unsigned long value = 0;
> >>> +       int ret;
> >>> +
> >>> +       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> >>> +
> >>> +       return !ret && !!value;
> >>> +}
> >>> +
> >>
> >> Not sure what was the base patch on which this was rebased. The actual
> >> commit in the queue branch looks different.
> >>
> >
> > This patch set was based on 6.7-rc8.
> >
> >> https://github.com/kvm-riscv/linux/commit/5563517cc2012e3326411b360c9924d3f2706c8d
> >>
> >> Both seem to have the same bug though the tests fail now and require
> >> the following fix.
> >> The ext id should be uint64_t and we need to pass ext directly so that
> >> SBI extension tests can also pass.
> >>
> >
> > It's weird that 6.7-rc8 has already included Andrew's change on the ISA ext reg,
> > but this patch was not generated against his change.
> >
> > commit bdf6aa328f137e184b0fce607fd585354c3742f1
> > Author: Andrew Jones <ajones at ventanamicro.com>
> > Date:   Wed Dec 13 18:09:58 2023 +0100
> >
> >      RISC-V: KVM: selftests: Treat SBI ext regs like ISA ext regs
> >
> > Anyway, your changes were right. Please go ahead to include them when merging.
> >
>
> I am not sure what happened. Probably, a merge conflict issue.
>
> I just realized I forgot to copy paste another fix in arch timer
>
> +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
> @@ -85,7 +85,7 @@ struct kvm_vm *test_vm_create(void)
>          int nr_vcpus = test_args.nr_vcpus;
>
>          vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
> -       __TEST_REQUIRE(__vcpu_has_ext(vcpus[0], KVM_RISCV_ISA_EXT_SSTC),
> +       __TEST_REQUIRE(__vcpu_has_ext(vcpus[0],
> RISCV_ISA_EXT_REG(KVM_RISCV_ISA_EXT_SSTC)),

I have squashed this change into an existing commit in riscv_kvm_queue.

Thanks,
Anup

>
>
> > Thanks,
> > Haibo
> >
> >>
> >> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> >> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> >> @@ -48,7 +48,7 @@ static inline uint64_t __kvm_reg_id(uint64_t type,
> >> uint64_t subtype,
> >> KVM_REG_RISCV_SBI_SINGLE, \
> >> idx, KVM_REG_SIZE_ULONG)
> >>
> >> -bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
> >> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext);
> >>
> >> struct ex_regs {
> >> unsigned long ra;
> >> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c
> >> b/tools/testing/selftests/kvm/lib/riscv/processor.c
> >> index 282587cd4bbc..ec66d331a127 100644
> >> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> >> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> >> @@ -15,12 +15,12 @@
> >>
> >> static vm_vaddr_t exception_handlers;
> >>
> >> -bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> >> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext)
> >> {
> >> unsigned long value = 0;
> >> int ret;
> >>
> >> - ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> >> + ret = __vcpu_get_reg(vcpu, ext, &value);
> >>
> >> return !ret && !!value;
> >> }
> >>
> >> With the above the fix, Both SBI/ISA extension tests pass.
> >> # ./get-reg-list
> >> sbi-base: PASS
> >> sbi-sta: PASS
> >> sbi-pmu: PASS
> >> sbi-dbcn: PASS
> >> aia: PASS
> >> fp_f: PASS
> >> fp_d: PASS
> >> 1..0 # SKIP - h not available, skipping tests
> >> smstateen: PASS
> >> sscofpmf: PASS
> >> sstc: PASS
> >> 1..0 # SKIP - svinval not available, skipping tests
> >> 1..0 # SKIP - svnapot not available, skipping tests
> >> 1..0 # SKIP - svpbmt not available, skipping tests
> >> zba: PASS
> >> zbb: PASS
> >> zbc: PASS
> >> 1..0 # SKIP - zbkb not available, skipping tests
> >> 1..0 # SKIP - zbkc not available, skipping tests
> >> 1..0 # SKIP - zbkx not available, skipping tests
> >> zbs: PASS
> >> zfa: PASS
> >> 1..0 # SKIP - zfh not available, skipping tests
> >> 1..0 # SKIP - zfhmin not available, skipping tests
> >> zicbom: PASS
> >> zicboz: PASS
> >> zicntr: PASS
> >> 1..0 # SKIP - zicond not available, skipping tests
> >> zicsr: PASS
> >> zifencei: PASS
> >> zihintntl: PASS
> >> zihintpause: PASS
> >> zihpm: PASS
> >>
> >>
> >>>   static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
> >>>   {
> >>>          return (v + vm->page_size) & ~(vm->page_size - 1);
> >>> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> >>> index 25de4b8bc347..ed29ba45588c 100644
> >>> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> >>> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> >>> @@ -75,15 +75,6 @@ bool check_reject_set(int err)
> >>>          return err == EINVAL;
> >>>   }
> >>>
> >>> -static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> >>> -{
> >>> -       int ret;
> >>> -       unsigned long value;
> >>> -
> >>> -       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> >>> -       return (ret) ? false : !!value;
> >>> -}
> >>> -
> >>>   void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
> >>>   {
> >>>          unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
> >>> @@ -111,7 +102,7 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
> >>>                  __vcpu_set_reg(vcpu, RISCV_ISA_EXT_REG(s->feature), 1);
> >>>
> >>>                  /* Double check whether the desired extension was enabled */
> >>> -               __TEST_REQUIRE(vcpu_has_ext(vcpu, s->feature),
> >>> +               __TEST_REQUIRE(__vcpu_has_ext(vcpu, s->feature),
> >>>                                 "%s not available, skipping tests\n", s->name);
> >>>          }
> >>>   }
> >>> --
> >>> 2.34.1
> >>>
> >>
> >>
> >> --
> >> Regards,
> >> Atish
>


From xiaobo55x at gmail.com  Sun Feb 25 21:47:42 2024
From: xiaobo55x at gmail.com (Haibo Xu)
Date: Mon, 26 Feb 2024 13:47:42 +0800
Subject: [PATCH v5 11/12] KVM: riscv: selftests: Change vcpu_has_ext to a
 common function
In-Reply-To: <CAAhSdy2TVSt=gCJRf78AzXNVFKy8MGJ+QspSEHeedT7GPAYkUQ@mail.gmail.com>
References: <cover.1705916069.git.haibo1.xu@intel.com> <68856b86a93a4188558e5d0ebac0dd6aac8e404c.1705916069.git.haibo1.xu@intel.com>
 <CAOnJCULwRTSnrQkR2o1P53R=tJ3TAxX+y+XRBesW6OFEzgFv2g@mail.gmail.com>
 <CAJve8om2oOLg5-wKX7m7cBTgzwqiMcb35x=nDi1edY8evXjyMw@mail.gmail.com>
 <2c96c61a-2685-4cee-9cef-963ed833bf92@rivosinc.com> <CAAhSdy2TVSt=gCJRf78AzXNVFKy8MGJ+QspSEHeedT7GPAYkUQ@mail.gmail.com>
Message-ID: <CAJve8onL5YB2w6duAr2H=8yJMh=SPsZCvgu+suhd=9U1_egHOg@mail.gmail.com>

On Mon, Feb 26, 2024 at 1:20?PM Anup Patel <anup at brainfault.org> wrote:
>
> On Wed, Feb 21, 2024 at 2:07?PM Atish Patra <atishp at rivosinc.com> wrote:
> >
> > On 2/20/24 18:13, Haibo Xu wrote:
> > > On Wed, Feb 21, 2024 at 7:03?AM Atish Patra <atishp at atishpatra.org> wrote:
> > >>
> > >> On Mon, Jan 22, 2024 at 1:48?AM Haibo Xu <haibo1.xu at intel.com> wrote:
> > >>>
> > >>> Move vcpu_has_ext to the processor.c and rename it to __vcpu_has_ext
> > >>> so that other test cases can use it for vCPU extension check.
> > >>>
> > >>> Signed-off-by: Haibo Xu <haibo1.xu at intel.com>
> > >>> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> > >>> ---
> > >>>   tools/testing/selftests/kvm/include/riscv/processor.h |  2 ++
> > >>>   tools/testing/selftests/kvm/lib/riscv/processor.c     | 10 ++++++++++
> > >>>   tools/testing/selftests/kvm/riscv/get-reg-list.c      | 11 +----------
> > >>>   3 files changed, 13 insertions(+), 10 deletions(-)
> > >>>
> > >>> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> > >>> index b68b1b731a34..bd27e1c67579 100644
> > >>> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> > >>> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> > >>> @@ -42,6 +42,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
> > >>>   #define RISCV_ISA_EXT_REG(idx) __kvm_reg_id(KVM_REG_RISCV_ISA_EXT, \
> > >>>                                               idx, KVM_REG_SIZE_ULONG)
> > >>>
> > >>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
> > >>> +
> > >>>   struct ex_regs {
> > >>>          unsigned long ra;
> > >>>          unsigned long sp;
> > >>> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> > >>> index 39a1e9902dec..dad73ce18164 100644
> > >>> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> > >>> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> > >>> @@ -15,6 +15,16 @@
> > >>>
> > >>>   static vm_vaddr_t exception_handlers;
> > >>>
> > >>> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> > >>> +{
> > >>> +       unsigned long value = 0;
> > >>> +       int ret;
> > >>> +
> > >>> +       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> > >>> +
> > >>> +       return !ret && !!value;
> > >>> +}
> > >>> +
> > >>
> > >> Not sure what was the base patch on which this was rebased. The actual
> > >> commit in the queue branch looks different.
> > >>
> > >
> > > This patch set was based on 6.7-rc8.
> > >
> > >> https://github.com/kvm-riscv/linux/commit/5563517cc2012e3326411b360c9924d3f2706c8d
> > >>
> > >> Both seem to have the same bug though the tests fail now and require
> > >> the following fix.
> > >> The ext id should be uint64_t and we need to pass ext directly so that
> > >> SBI extension tests can also pass.
> > >>
> > >
> > > It's weird that 6.7-rc8 has already included Andrew's change on the ISA ext reg,
> > > but this patch was not generated against his change.
> > >
> > > commit bdf6aa328f137e184b0fce607fd585354c3742f1
> > > Author: Andrew Jones <ajones at ventanamicro.com>
> > > Date:   Wed Dec 13 18:09:58 2023 +0100
> > >
> > >      RISC-V: KVM: selftests: Treat SBI ext regs like ISA ext regs
> > >
> > > Anyway, your changes were right. Please go ahead to include them when merging.
> > >
> >
> > I am not sure what happened. Probably, a merge conflict issue.
> >
> > I just realized I forgot to copy paste another fix in arch timer
> >
> > +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
> > @@ -85,7 +85,7 @@ struct kvm_vm *test_vm_create(void)
> >          int nr_vcpus = test_args.nr_vcpus;
> >
> >          vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
> > -       __TEST_REQUIRE(__vcpu_has_ext(vcpus[0], KVM_RISCV_ISA_EXT_SSTC),
> > +       __TEST_REQUIRE(__vcpu_has_ext(vcpus[0],
> > RISCV_ISA_EXT_REG(KVM_RISCV_ISA_EXT_SSTC)),
>
> I have squashed this change into an existing commit in riscv_kvm_queue.
>
> Thanks,
> Anup
>

Thanks a lot, Anup!

> >
> >
> > > Thanks,
> > > Haibo
> > >
> > >>
> > >> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> > >> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> > >> @@ -48,7 +48,7 @@ static inline uint64_t __kvm_reg_id(uint64_t type,
> > >> uint64_t subtype,
> > >> KVM_REG_RISCV_SBI_SINGLE, \
> > >> idx, KVM_REG_SIZE_ULONG)
> > >>
> > >> -bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
> > >> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext);
> > >>
> > >> struct ex_regs {
> > >> unsigned long ra;
> > >> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c
> > >> b/tools/testing/selftests/kvm/lib/riscv/processor.c
> > >> index 282587cd4bbc..ec66d331a127 100644
> > >> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> > >> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> > >> @@ -15,12 +15,12 @@
> > >>
> > >> static vm_vaddr_t exception_handlers;
> > >>
> > >> -bool __vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> > >> +bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext)
> > >> {
> > >> unsigned long value = 0;
> > >> int ret;
> > >>
> > >> - ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> > >> + ret = __vcpu_get_reg(vcpu, ext, &value);
> > >>
> > >> return !ret && !!value;
> > >> }
> > >>
> > >> With the above the fix, Both SBI/ISA extension tests pass.
> > >> # ./get-reg-list
> > >> sbi-base: PASS
> > >> sbi-sta: PASS
> > >> sbi-pmu: PASS
> > >> sbi-dbcn: PASS
> > >> aia: PASS
> > >> fp_f: PASS
> > >> fp_d: PASS
> > >> 1..0 # SKIP - h not available, skipping tests
> > >> smstateen: PASS
> > >> sscofpmf: PASS
> > >> sstc: PASS
> > >> 1..0 # SKIP - svinval not available, skipping tests
> > >> 1..0 # SKIP - svnapot not available, skipping tests
> > >> 1..0 # SKIP - svpbmt not available, skipping tests
> > >> zba: PASS
> > >> zbb: PASS
> > >> zbc: PASS
> > >> 1..0 # SKIP - zbkb not available, skipping tests
> > >> 1..0 # SKIP - zbkc not available, skipping tests
> > >> 1..0 # SKIP - zbkx not available, skipping tests
> > >> zbs: PASS
> > >> zfa: PASS
> > >> 1..0 # SKIP - zfh not available, skipping tests
> > >> 1..0 # SKIP - zfhmin not available, skipping tests
> > >> zicbom: PASS
> > >> zicboz: PASS
> > >> zicntr: PASS
> > >> 1..0 # SKIP - zicond not available, skipping tests
> > >> zicsr: PASS
> > >> zifencei: PASS
> > >> zihintntl: PASS
> > >> zihintpause: PASS
> > >> zihpm: PASS
> > >>
> > >>
> > >>>   static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
> > >>>   {
> > >>>          return (v + vm->page_size) & ~(vm->page_size - 1);
> > >>> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > >>> index 25de4b8bc347..ed29ba45588c 100644
> > >>> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > >>> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > >>> @@ -75,15 +75,6 @@ bool check_reject_set(int err)
> > >>>          return err == EINVAL;
> > >>>   }
> > >>>
> > >>> -static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> > >>> -{
> > >>> -       int ret;
> > >>> -       unsigned long value;
> > >>> -
> > >>> -       ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> > >>> -       return (ret) ? false : !!value;
> > >>> -}
> > >>> -
> > >>>   void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
> > >>>   {
> > >>>          unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
> > >>> @@ -111,7 +102,7 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
> > >>>                  __vcpu_set_reg(vcpu, RISCV_ISA_EXT_REG(s->feature), 1);
> > >>>
> > >>>                  /* Double check whether the desired extension was enabled */
> > >>> -               __TEST_REQUIRE(vcpu_has_ext(vcpu, s->feature),
> > >>> +               __TEST_REQUIRE(__vcpu_has_ext(vcpu, s->feature),
> > >>>                                 "%s not available, skipping tests\n", s->name);
> > >>>          }
> > >>>   }
> > >>> --
> > >>> 2.34.1
> > >>>
> > >>
> > >>
> > >> --
> > >> Regards,
> > >> Atish
> >


From victor.liu at nxp.com  Sun Feb 25 21:51:17 2024
From: victor.liu at nxp.com (Ying Liu)
Date: Mon, 26 Feb 2024 05:51:17 +0000
Subject: [PATCH] drm/lcdif: Do not disable clock on already suspended
 hardware
In-Reply-To: <20240118183924.144221-1-marex@denx.de>
References: <20240118183924.144221-1-marex@denx.de>
Message-ID: <AM7PR04MB7046963D28377F9EC6CF951B985A2@AM7PR04MB7046.eurprd04.prod.outlook.com>

On Friday, January 19, 2024 2:39 AM, Marek Vasut <marex at denx.de> wrote:
> In case the LCDIF is enabled in DT but unused, the clock used by the

Nit: s/clock/clocks/

> LCDIF are not enabled. Those clock may even have a use count of 0 in

Ditto.

> case there are no other users of those clock. This can happen e.g. in

Ditto.

> case the LCDIF drives HDMI bridge which has no panel plugged into the
> HDMI connector.
> 
> Do not attempt to disable clock in the suspend callback and re-enable
> clock in the resume callback unless the LCDIF is enabled and was in
> use before the system entered suspend, otherwise the driver might end
> up trying to disable clock which are already disabled with use count

Ditto.

With the nitpicks addressed:
Reviewed-by: Liu Ying <victor.liu at nxp.com>

Regards,
Liu Ying

> 0, and would trigger a warning from clock core about this condition.
> 
> Note that the lcdif_rpm_suspend() and lcdif_rpm_resume() functions
> internally perform the clock disable and enable operations and act
> as runtime PM hooks too.
> 
> Fixes: 9db35bb349a0 ("drm: lcdif: Add support for i.MX8MP LCDIF variant")
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: David Airlie <airlied at gmail.com>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: Liu Ying <victor.liu at nxp.com>
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
> Cc: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Stefan Agner <stefan at agner.ch>
> Cc: Thomas Zimmermann <tzimmermann at suse.de>
> Cc: dri-devel at lists.freedesktop.org
> Cc: linux-arm-kernel at lists.infradead.org
> ---
>  drivers/gpu/drm/mxsfb/lcdif_drv.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c
> b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> index ea10bf81582e9..0f895b8a99d62 100644
> --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
> +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> @@ -343,6 +343,9 @@ static int __maybe_unused lcdif_suspend(struct
> device *dev)
>  	if (ret)
>  		return ret;
> 
> +	if (pm_runtime_suspended(dev))
> +		return 0;
> +
>  	return lcdif_rpm_suspend(dev);
>  }
> 
> @@ -350,7 +353,8 @@ static int __maybe_unused lcdif_resume(struct
> device *dev)
>  {
>  	struct drm_device *drm = dev_get_drvdata(dev);
> 
> -	lcdif_rpm_resume(dev);
> +	if (!pm_runtime_suspended(dev))
> +		lcdif_rpm_resume(dev);
> 
>  	return drm_mode_config_helper_resume(drm);
>  }
> --
> 2.43.0



From carlos.song at nxp.com  Sun Feb 25 21:54:18 2024
From: carlos.song at nxp.com (carlos.song at nxp.com)
Date: Mon, 26 Feb 2024 13:54:18 +0800
Subject: [PATCH] i2c: imx-lpi2c: add generic GPIO recovery for LPI2C
Message-ID: <20240226055418.3314913-1-carlos.song@nxp.com>

From: Carlos Song <carlos.song at nxp.com>

This adds i2c bus recovery to the lpi2c driver.

Uses the generic recovery function setting the SCL/SDA pads as
GPIO pins and sending 9 clocks to try and recover the bus.

Signed-off-by: Carlos Song <carlos.song at nxp.com>
Reviewed-by: Clark Wang <xiaoning.wang at nxp.com>
---
 drivers/i2c/busses/i2c-imx-lpi2c.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
index 678b30e90492..6d72e4e126dd 100644
--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -106,6 +106,7 @@ struct lpi2c_imx_struct {
 	unsigned int		txfifosize;
 	unsigned int		rxfifosize;
 	enum lpi2c_imx_mode	mode;
+	struct i2c_bus_recovery_info rinfo;
 };
 
 static void lpi2c_imx_intctrl(struct lpi2c_imx_struct *lpi2c_imx,
@@ -133,6 +134,8 @@ static int lpi2c_imx_bus_busy(struct lpi2c_imx_struct *lpi2c_imx)
 
 		if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
 			dev_dbg(&lpi2c_imx->adapter.dev, "bus not work\n");
+			if (lpi2c_imx->adapter.bus_recovery_info)
+				i2c_recover_bus(&lpi2c_imx->adapter);
 			return -ETIMEDOUT;
 		}
 		schedule();
@@ -190,6 +193,8 @@ static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx)
 
 		if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
 			dev_dbg(&lpi2c_imx->adapter.dev, "stop timeout\n");
+			if (lpi2c_imx->adapter.bus_recovery_info)
+				i2c_recover_bus(&lpi2c_imx->adapter);
 			break;
 		}
 		schedule();
@@ -325,6 +330,8 @@ static int lpi2c_imx_txfifo_empty(struct lpi2c_imx_struct *lpi2c_imx)
 
 		if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
 			dev_dbg(&lpi2c_imx->adapter.dev, "txfifo empty timeout\n");
+			if (lpi2c_imx->adapter.bus_recovery_info)
+				i2c_recover_bus(&lpi2c_imx->adapter);
 			return -ETIMEDOUT;
 		}
 		schedule();
@@ -526,6 +533,20 @@ static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int lpi2c_imx_init_recovery_info(struct lpi2c_imx_struct *lpi2c_imx,
+				  struct platform_device *pdev)
+{
+	struct i2c_bus_recovery_info *bri = &lpi2c_imx->rinfo;
+
+	bri->pinctrl = devm_pinctrl_get(&pdev->dev);
+	if (IS_ERR(bri->pinctrl))
+		return PTR_ERR(bri->pinctrl);
+
+	lpi2c_imx->adapter.bus_recovery_info = bri;
+
+	return 0;
+}
+
 static u32 lpi2c_imx_func(struct i2c_adapter *adapter)
 {
 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
@@ -600,6 +621,12 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
 	lpi2c_imx->txfifosize = 1 << (temp & 0x0f);
 	lpi2c_imx->rxfifosize = 1 << ((temp >> 8) & 0x0f);
 
+	/* Init optional bus recovery function */
+	ret = lpi2c_imx_init_recovery_info(lpi2c_imx, pdev);
+	/* Give it another chance if pinctrl used is not ready yet */
+	if (ret == -EPROBE_DEFER)
+		goto rpm_disable;
+
 	ret = i2c_add_adapter(&lpi2c_imx->adapter);
 	if (ret)
 		goto rpm_disable;
-- 
2.34.1



From ghennadi.procopciuc at oss.nxp.com  Sun Feb 25 22:29:31 2024
From: ghennadi.procopciuc at oss.nxp.com (Ghennadi Procopciuc)
Date: Mon, 26 Feb 2024 08:29:31 +0200
Subject: [PATCH v2 2/2] arm64: dts: s32g: add uSDHC node
In-Reply-To: <ZdnIp8PPtfbuIzwP@linux-8mug>
References: <20240122140602.1006813-1-ghennadi.procopciuc@oss.nxp.com>
 <20240122140602.1006813-3-ghennadi.procopciuc@oss.nxp.com>
 <ZdmnQTtUxOEUy06L@linux-8mug> <ZdnIp8PPtfbuIzwP@linux-8mug>
Message-ID: <bc9bcc98-62db-420c-b30f-e4af513cbd8c@oss.nxp.com>

On 2/24/24 12:44, Chester Lin wrote:
> Hi Ghennadi,
> 
> On Sat, Feb 24, 2024 at 04:22:30PM +0800, Chester Lin wrote:
>> Hi Ghennadi,

Hi Chester,
>>
>> On Mon, Jan 22, 2024 at 04:06:01PM +0200, Ghennadi Procopciuc wrote:
>>> From: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>>
>>> Add the uSDHC node for the boards that are based on S32G SoCs.
>>>
>>> Signed-off-by: Ciprian Costea <ciprianmarian.costea at nxp.com>
>>> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc at nxp.com>
>>> ---
>>>  arch/arm64/boot/dts/freescale/s32g2.dtsi        | 10 ++++++++++
>>>  arch/arm64/boot/dts/freescale/s32g274a-evb.dts  |  6 +++++-
>>>  arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts |  6 +++++-
>>>  3 files changed, 20 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
>>> index ef1a1d61f2ba..fc19ae2e8d3b 100644
>>> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
>>> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
>>> @@ -138,6 +138,16 @@ uart2: serial at 402bc000 {
>>>  			status = "disabled";
>>>  		};
>>>  
>>> +		usdhc0: mmc at 402f0000 {
>>> +			compatible = "nxp,s32g2-usdhc";
>>> +			reg = <0x402f0000 0x1000>;
>>> +			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
>>> +			clocks = <&clks 32>, <&clks 31>, <&clks 33>;
>>
>> Same as I have mentioned in [PATCH v2 1/2], could we have fixed dt-bindings to
>> replace with these raw clock id values (32, 31, 33)?
>>
> 
> Just found the previous review discussion in v1:
> https://lore.kernel.org/all/f54d947c-58dc-498f-8871-b472f97be4a8 at oss.nxp.com/
> 
Indeed, I switched to raw clocks instead of placing them into a binding
header after receiving this feedback on v1.

> What I'm worried is that, could these raw clock IDs be rearranged in the
> downstream TF-A? If so it would cause ABI inconsistency and clock issues
> since the kernel is not aware of any raw ID changes in downstream TF-A.

These clock IDs will become immutable in the downstream version of TF-A
once the patches get merged. This will prevent any unfortunate events
when the Kernel and TF-A are not in sync with regard to SCMI clock IDs.

Best regards,
Ghennadi
> 
> Chester
> 
>>> +			clock-names = "ipg", "ahb", "per";
>>> +			bus-width = <8>;
>>> +			status = "disabled";
>>> +		};
>>> +
>>>  		gic: interrupt-controller at 50800000 {
>>>  			compatible = "arm,gic-v3";
>>>  			reg = <0x50800000 0x10000>,
>>> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>>> index 9118d8d2ee01..00070c949e2a 100644
>>> --- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>>> +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>>> @@ -1,7 +1,7 @@
>>>  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
>>>  /*
>>>   * Copyright (c) 2021 SUSE LLC
>>> - * Copyright (c) 2019-2021 NXP
>>> + * Copyright 2019-2021, 2024 NXP
>>>   */
>>>  
>>>  /dts-v1/;
>>> @@ -32,3 +32,7 @@ memory at 80000000 {
>>>  &uart0 {
>>>  	status = "okay";
>>>  };
>>> +
>>> +&usdhc0 {
>>> +	status = "okay";
>>> +};
>>> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
>>> index e05ee854cdf5..b3fc12899cae 100644
>>> --- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
>>> +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
>>> @@ -1,7 +1,7 @@
>>>  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
>>>  /*
>>>   * Copyright (c) 2021 SUSE LLC
>>> - * Copyright (c) 2019-2021 NXP
>>> + * Copyright 2019-2021, 2024 NXP
>>>   */
>>>  
>>>  /dts-v1/;
>>> @@ -38,3 +38,7 @@ &uart0 {
>>>  &uart1 {
>>>  	status = "okay";
>>>  };
>>> +
>>> +&usdhc0 {
>>> +	status = "okay";
>>> +};
>>> -- 
>>> 2.43.0
>>>

-- 
Regards,
Ghennadi



From andrew at codeconstruct.com.au  Sun Feb 25 22:55:03 2024
From: andrew at codeconstruct.com.au (Andrew Jeffery)
Date: Mon, 26 Feb 2024 17:25:03 +1030
Subject: [PATCH 1/1] ARM:dts:aspeed: Initial device tree for AMD Onyx
 Platform
In-Reply-To: <20240110033543.799919-1-supreeth.venkatesh@amd.com>
References: <20240110033543.799919-1-supreeth.venkatesh@amd.com>
Message-ID: <572d53516dee6db5af7089090056185abb4e78c7.camel@codeconstruct.com.au>

On Tue, 2024-01-09 at 21:35 -0600, Supreeth Venkatesh wrote:
> This patch adds initial device tree and makefile updates for
> AMD Onyx platform.
> 
> AMD Onyx platform is an AMD customer reference board with an Aspeed
> ast2600 BMC manufactured by AMD.
> It describes I2c devices, Fans, Kcs devices, Uarts, Mac, LEDs, etc.
> present on AMD Onyx platform.
> 
> Signed-off-by: Supreeth Venkatesh <supreeth.venkatesh at amd.com>
> ---
>  arch/arm/boot/dts/aspeed/Makefile             |  1 +
>  .../boot/dts/aspeed/aspeed-bmc-amd-onyx.dts   | 98 +++++++++++++++++++
>  2 files changed, 99 insertions(+)
>  create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts
> 
> diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
> index fb9cc95f1b60..2b27d377aae2 100644
> --- a/arch/arm/boot/dts/aspeed/Makefile
> +++ b/arch/arm/boot/dts/aspeed/Makefile
> @@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
>  	aspeed-ast2600-evb.dtb \
>  	aspeed-bmc-amd-daytonax.dtb \
>  	aspeed-bmc-amd-ethanolx.dtb \
> +	aspeed-bmc-amd-onyx.dtb \
>  	aspeed-bmc-ampere-mtjade.dtb \
>  	aspeed-bmc-ampere-mtmitchell.dtb \
>  	aspeed-bmc-arm-stardragon4800-rep2.dtb \
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts
> new file mode 100644
> index 000000000000..a7056cd29553
> --- /dev/null
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-amd-onyx.dts
> @@ -0,0 +1,98 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +// Copyright (c) 2021 - 2024 AMD Inc.
> +// Author: Supreeth Venkatesh <supreeth.venkatesh at amd.com>
> +
> +/dts-v1/;
> +
> +#include "aspeed-g6.dtsi"
> +#include <dt-bindings/gpio/aspeed-gpio.h>
> +
> +/ {
> +       model = "AMD Onyx BMC";
> +       compatible = "amd,onyx-bmc", "aspeed,ast2600";
> +
> +       aliases {
> +               serial0 = &uart1;
> +               serial4 = &uart5;
> +      };
> +
> +       chosen {
> +               stdout-path = &uart5;
> +               bootargs = "console=ttyS4,115200 earlyprintk vmalloc=512MB";

Why `vmalloc=512MB`? Can you add a comment explaining the need for
that?

That said, setting bootargs in the devicetree is generally discouraged.

> +       };
> +
> +       memory at 80000000 {
> +               device_type = "memory";
> +               reg = <0x80000000 0x80000000>;
> +       };
> +
> +};
> +
> +&mdio0 {
> +       status = "okay";
> +
> +       ethphy0: ethernet-phy at 0 {
> +               compatible = "ethernet-phy-ieee802.3-c22";
> +               reg = <0>;
> +       };
> +};
> +
> +&mac3 {
> +       status = "okay";
> +       phy-mode = "rgmii";
> +       phy-handle = <&ethphy0>;
> +
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pinctrl_rgmii4_default>;
> +};
> +
> +
> +
> +&fmc {
> +       status = "okay";
> +       flash at 0 {
> +               compatible = "jedec,spi-nor";
> +               status = "okay";
> +               #include "openbmc-flash-layout-128.dtsi"
> +       };
> +};
> +
> +//Host Console
> +&uart1 {
> +       status = "okay";
> +};

How are you managing the host console? Enabling UART1 for that on the
BMC piques my interest :)

Apologies for the delay in reviewing.

Andrew



From peng.fan at oss.nxp.com  Sun Feb 25 23:09:10 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 26 Feb 2024 15:09:10 +0800
Subject: [PATCH V2] dt-bindings: i2c: imx-lpi2c: add i.MX95 LPI2C
Message-ID: <20240226070910.3379108-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add i.MX95 LPI2C compatible entry, same as i.MX93 compatible
with i.MX7ULP.

Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---

V2:
 Add A-b
 Rebase to linux-next
 Link to v1: https://lore.kernel.org/all/20240122091230.2075378-1-peng.fan at oss.nxp.com/

 Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.yaml b/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.yaml
index 4656f5112b84..54d500be6aaa 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.yaml
@@ -24,6 +24,7 @@ properties:
               - fsl,imx8qm-lpi2c
               - fsl,imx8ulp-lpi2c
               - fsl,imx93-lpi2c
+              - fsl,imx95-lpi2c
           - const: fsl,imx7ulp-lpi2c
 
   reg:
-- 
2.37.1



From tujinjiang at huawei.com  Sun Feb 25 23:03:05 2024
From: tujinjiang at huawei.com (Jinjiang Tu)
Date: Mon, 26 Feb 2024 15:03:05 +0800
Subject: [PATCH v2] arm: flush: check if the folio is reserved for
 no-mapping addresses
In-Reply-To: <20240223063608.2605736-1-liuyongqiang13@huawei.com>
References: <20240223063608.2605736-1-liuyongqiang13@huawei.com>
Message-ID: <5a1d28b7-1e6e-da39-9b34-f86470163bb1@huawei.com>

Since some abuses of pfn_valid() have been reported, I check all the use 
of pfn_valid(), and find some suspicious cases.

phys_mem_access_prot() defined in arch/arm/mm/mmu.c returns 
pgprot_noncached() when pfn_valid() returns false.
I think it?s purpose is to return pgprot_noncached() when the pfn is not 
in RAM, and the use of pfn_valid() is incorrect.
Notably, phys_mem_access_prot() defined in arm64 uses 
pfn_is_map_memory() instead of pfn_valid() since commit
873ba463914c (arm64: decouple check whether pfn is in linear map from 
pfn_valid()).

Similarly, virt_addr_valid() defined in arm64 uses pfn_is_map_memory() 
instead of pfn_valid() since commit
873ba463914c (arm64: decouple check whether pfn is in linear map from 
pfn_valid()), But virt_addr_valid() still
uses pfn_valid(). Besides, the implementation of x86 also uses pfn_valid().

update_mmu_cache_range() defined in arch/arm/mm/fault-armv.c checks 
pfn_valid() and then calls __flush_dcache_folio().
This case is similar to the case reported by Yongqiang Liu, the pfn may 
not be a RAM pfn, and the system will crash in
__flush_dcache_folio() due to the kernel linear mapping is not 
established. virt_addr_valid() is used to check whether a
vrtual address is valid linear mapping. Are these uses of pfn_valid() 
incorrect?

pfn_modify_allowed() defined in arch/x86/mm/mmap.c checks pfn_valid(), 
and the comment says it is intended to check
whether the pfn is in real memory. So the use of pfn_valid() should be 
incorrent. This case is only involved when the cpu
is affected by X86_BUG_L1TF.

try_ram_remap() defined in kernel/iomem.c returns the linear address 
when three checks are passed. One of the checks is
pfn_valid(). The only caller memremap() guarantees the pfn passed to 
try_ram_remap() is in RAM, but the pfn may be in
NOMAP memory regions and is not mapped in linear mapping. commit 
260364d112bc (arm[64]/memremap: don't abuse
pfn_valid() to ensure presence of linear map) solves it by checking in 
arch_memremap_can_ram_remap(), However, if other
architectures involve this issue?

Do these suspicious case abuse pfn_valid() really? Thanks



From krzysztof.kozlowski at linaro.org  Sun Feb 25 23:08:42 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 26 Feb 2024 08:08:42 +0100
Subject: [PATCH v3] dt-bindings: gpio: aspeed,ast2400-gpio: Convert to DT
 schema
In-Reply-To: <20240226051645.414935-1-andrew@codeconstruct.com.au>
References: <20240226051645.414935-1-andrew@codeconstruct.com.au>
Message-ID: <458becdb-fb1e-4808-87b6-3037ec945647@linaro.org>

On 26/02/2024 06:16, Andrew Jeffery wrote:
> Squash warnings such as:
> 
> ```
> arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-galaxy100.dtb: /ahb/apb at 1e600000/gpio at 1e780000: failed to match any schema with compatible: ['aspeed,ast2400-gpio']
> ```
> 
> Signed-off-by: Andrew Jeffery <andrew at codeconstruct.com.au>

...

> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +    description: The clock to use for debounce timings
> +
> +  gpio-controller: true
> +  gpio-line-names: true

min/maxItems

> +  gpio-ranges: true
> +
> +  "#gpio-cells":
> +    const: 2
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  interrupt-controller: true
> +
> +  "#interrupt-cells":
> +    const: 2
> +
> +  ngpios: true

Where are the constraints I asked? minimum, maximum.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - interrupt-controller
> +  - "#interrupt-cells"
> +  - gpio-controller
> +  - "#gpio-cells"
> +


Best regards,
Krzysztof



From pmenzel at molgen.mpg.de  Sun Feb 25 23:10:24 2024
From: pmenzel at molgen.mpg.de (Paul Menzel)
Date: Mon, 26 Feb 2024 08:10:24 +0100
Subject: [PATCH 1/1] ARM:dts:aspeed: Initial device tree for AMD Onyx
 Platform
In-Reply-To: <572d53516dee6db5af7089090056185abb4e78c7.camel@codeconstruct.com.au>
References: <20240110033543.799919-1-supreeth.venkatesh@amd.com>
 <572d53516dee6db5af7089090056185abb4e78c7.camel@codeconstruct.com.au>
Message-ID: <74cd8a61-3d9f-437e-8e3a-22139e23bda5@molgen.mpg.de>

Dear Supreeth,


Thank you for your patch. Should you resent three more nits.

Am 26.02.24 um 07:55 schrieb Andrew Jeffery:
> On Tue, 2024-01-09 at 21:35 -0600, Supreeth Venkatesh wrote:
>> This patch adds initial device tree and makefile updates for
>> AMD Onyx platform.
>>
>> AMD Onyx platform is an AMD customer reference board with an Aspeed
>> ast2600 BMC manufactured by AMD.
>> It describes I2c devices, Fans, Kcs devices, Uarts, Mac, LEDs, etc.
>> present on AMD Onyx platform.

I?d capitalize I2Cs, UARTs, and MAC, but would write fans.

Also, could you please make the summary a statement by adding a verb in 
imperative mood. Maybe:

Add initial device tree for AMD Onyx Platform

I?d also add spaces after the colons in the commit message summary.

[?]


Kind regards,

Paul


From frank at oltmanns.dev  Sun Feb 25 23:13:42 2024
From: frank at oltmanns.dev (Frank Oltmanns)
Date: Mon, 26 Feb 2024 08:13:42 +0100
Subject: [PATCH v2 0/6] Pinephone video out fixes (flipping between two
 frames)
In-Reply-To: <87r0h8n64g.fsf@oltmanns.dev> (Frank Oltmanns's message of "Mon,
	19 Feb 2024 10:41:19 +0100")
References: <20240205-pinephone-pll-fixes-v2-0-96a46a2d8c9b@oltmanns.dev>
	<jzl3mlzk4j7qvgcedvipgale5nhinznefodrnaehwsqfnseiwc@7zzlxd4dpueh>
	<bgyyemyi4shj3spo6qy4icvk56nrp5sihnzqurnozqdyktwugc@ikurx4ojoxpi>
	<87wmrbxckj.fsf@oltmanns.dev>
	<s7uslavg5gzqzzdetwcushcknwe3nuicmqhfhb7gbapzxx2npy@srjc252uinqv>
	<87r0h8n64g.fsf@oltmanns.dev>
Message-ID: <875xybr93t.fsf@oltmanns.dev>

Hi Jernej,
hi Maxime,
hi Ond?ej,

On 2024-02-19 at 10:41:19 +0100, Frank Oltmanns <frank at oltmanns.dev> wrote:
> Hi Ond?ej,
>
> On 2024-02-11 at 20:25:29 +0100, Ond?ej Jirman <megi at xff.cz> wrote:
>> Hi Frank,
>>
>> On Sun, Feb 11, 2024 at 04:09:16PM +0100, Frank Oltmanns wrote:
>>> Hi Ond?ej,
>>>
>>> On 2024-02-05 at 17:02:00 +0100, Ond?ej Jirman <megi at xff.cz> wrote:
>>> > On Mon, Feb 05, 2024 at 04:54:07PM +0100, Ond?ej Jirman wrote:
>>> >> On Mon, Feb 05, 2024 at 04:22:23PM +0100, Frank Oltmanns wrote:
>>> >>
>>> >> [...]
>>> >>
>>> >> Also sunxi-ng clk driver does apply NM factors at once to PLL_GPU clock,
>>> >> which can cause sudden frequency increase beyond intended output frequency,
>>> >> because division is applied immediately while multiplication is reflected
>>> >> slowly.
>>> >>
>>> >> Eg. if you're changing divider from 7 to 1, you can get a sudden 7x output
>>> >> frequency spike, before PLL VCO manages to lower the frequency through N clk
>>> >> divider feedback loop and lock on again. This can mess up whatever's connected
>>> >> to the output quite badly.
>>> >>
>>> >> You'd have to put logging on kernel writes to PLL_GPU register to see what
>>> >> is written in there and if divider is lowered significantly on some GPU
>>> >> devfreq frequency transitions.
>>>
>>> By looking at the clocks in clk_summary in debugfs, the rate of PLL-GPU
>>> always matches the rate of the GPU (at least at 120, 312, and 432 MHz).
>>> This is further underlined by the fact, that none of the rates can be
>>> achieved by integer dividing one of the other rates. sunxi-ng would
>>> only favor a different rate for pll-gpu than the one that is requested
>>> for the gpu, if pll-gpu is already running at a rate such that there
>>> exists an M ? {1, 2, 3, 4, 5, 6, 7, 8}, where
>>>   rate of pll-gpu / M = requested gpu rate
>>> or if the requested rate could not be reached directly by pll-gpu. Both
>>> is not the case for the rates in question (120, 192, 312, and 432 MHz).
>>>
>>> This means that the following divisor/multipliers are used by sunxi-ng's
>>> ccu_nm:
>>> N =  5, M = 1 for 120 MHz (min value without PATCH 6)
>>> N =  8, M = 1 for 192 MHz (min value after applying PATCH 6)
>>> N = 13, M = 1 for 312 MHz
>>> N = 18, M = 1 for 432 MHz
>>>
>>> So, with or without PATCH 6, the divider stays constant and it's only
>>> the multiplier that changes. This means, there should be no unexpected
>>> frequency spikes, right?
>>
>> Maybe. Thanks for giving it a try. There may still be other kinds of glitches
>> even if the divisor stays the same. It all depends how the register update is
>> implemented in the PLL block. It's hard to say. I guess, unless Allwinner
>> guarantees glitchless output from a given PLL when changing its parameters,
>> you can't rely on the output being clean during changes.
>>
>>> >> It's also unclear what happens when FRAC_CLK_OUT or PLL_MODE_SEL changes.
>>>
>>> Those are not changed once the clock is initialized. The bug however
>>> occurs hours or days after booting. IMO, this makes it unlikely that this
>>> could be the culprit.
>>>
>>> >> Maybe not much because M is supposed to be set to 1, but you still need to
>>> >> care when enabling fractional mode, and setting M to 1 because that's exactly
>>> >> the bad scenario if M was previously higher than 1.
>>> >>
>>> >> It's tricky.
>>> >>
>>> >> Having GPU module clock gated during PLL config changes may help! You can
>>> >> do that without locking yourself out, unlike with the CPU PLL.
>>> >>
>>> >> There's a gate enable bit for it at GPU_CLK_REG.SCLK_GATING. (page 122)
>>>
>>> The GPU should already be properly gated:
>>> https://elixir.bootlin.com/linux/v6.7.4/source/drivers/clk/sunxi-ng/ccu-sun50i-a64.c#L599
>>
>> How so? That's just clock declaration. How does it guarantee the clock to the
>> module is gated during parent PLL configuration changes?
>>
>
> You're of course right.
>
> I now tried using a similar approach like the one for changes for on
> PLL-CPU. It's using a notifier to connect the CPU to the 24 MHz
> oscillator and, after PLL-CPU is at its new rate, connecting it back to
> PLL-CPU.
>
> For the GPU my approach was to disable the GPU prior to changing
> PLL-GPU's rate and then re-enabling it, once the rate change is
> complete. I think, that's what you were proposing, right?
>
> Unfortunately, this results in a frozen phone even more quickly.
>
> Below is my code. Again, it doesn't solve the problem, but maybe
> somebody can spot what I'm doing wrong.

It seems to me that all options for changing the GPU's rate in a stable
manner have been exhausted. There seems to be no common interpretation
what the phrase "Clock output of PLL_GPU can be used for GPU;and dynamic
frequency scaling is not supported" in the Allwinner A64 manual (chapter
3.3.3) means.

The BSP uses a fixed rate of 432 MHz. Unless one of you has a clever
idea, I suggest to remove the OPPs from the device tree and set the GPU
to 432 MHz.

What are your thoughts on that?

Best regards,
  Frank

>
> Best regards,
>   Frank
>
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> index d68bdf7dd342..74538259d67a 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
> @@ -977,6 +977,11 @@ static struct ccu_rate_reset_nb sun50i_a64_pll_video0_reset_tcon0_nb = {
>
>  #define CCU_MIPI_DSI_CLK 0x168
>
> +static struct ccu_div_nb sun50i_a64_gpu_nb = {
> +	.common		= &gpu_clk.common,
> +	.delay_us	= 1, /* ??? */
> +};
> +
>  static int sun50i_a64_ccu_probe(struct platform_device *pdev)
>  {
>  	void __iomem *reg;
> @@ -1025,6 +1030,10 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
>  	sun50i_a64_pll_video0_reset_tcon0_nb.target_clk = tcon0_clk.common.hw.clk;
>  	ccu_rate_reset_notifier_register(&sun50i_a64_pll_video0_reset_tcon0_nb);
>
> +	/* Gate then ungate GPU on PLL-GPU changes */
> +	ccu_div_notifier_register(pll_gpu_clk.common.hw.clk,
> +				  &sun50i_a64_gpu_nb);
> +
>  	return 0;
>  }
>
> diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c
> index cb10a3ea23f9..83813c54fb2f 100644
> --- a/drivers/clk/sunxi-ng/ccu_div.c
> +++ b/drivers/clk/sunxi-ng/ccu_div.c
> @@ -4,7 +4,9 @@
>   * Maxime Ripard <maxime.ripard at free-electrons.com>
>   */
>
> +#include <linux/clk.h>
>  #include <linux/clk-provider.h>
> +#include <linux/delay.h>
>  #include <linux/io.h>
>
>  #include "ccu_gate.h"
> @@ -142,3 +144,37 @@ const struct clk_ops ccu_div_ops = {
>  	.set_rate	= ccu_div_set_rate,
>  };
>  EXPORT_SYMBOL_NS_GPL(ccu_div_ops, SUNXI_CCU);
> +
> +static int ccu_div_notifier_cb(struct notifier_block *nb,
> +			       unsigned long event, void *data)
> +{
> +	struct ccu_div_nb *div_nb = to_ccu_div_nb(nb);
> +
> +	if (event == PRE_RATE_CHANGE) {
> +		div_nb->original_enable = ccu_div_is_enabled(&div_nb->common->hw);
> +		if (div_nb->original_enable) {
> +			ccu_div_disable(&div_nb->common->hw);
> +			udelay(div_nb->delay_us);
> +		}
> +	} else if (event == POST_RATE_CHANGE) {
> +		if (div_nb->original_enable) {
> +			ccu_div_enable(&div_nb->common->hw);
> +			udelay(div_nb->delay_us);
> +		}
> +	}
> +
> +	return NOTIFY_OK;
> +}
> +
> +int ccu_div_notifier_register(struct clk *clk, struct ccu_div_nb *div_nb)
> +{
> +	div_nb->clk_nb.notifier_call = ccu_div_notifier_cb;
> +
> +	return clk_notifier_register(clk, &div_nb->clk_nb);
> +}
> diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h
> index 90d49ee8e0cc..e096c7be5dca 100644
> --- a/drivers/clk/sunxi-ng/ccu_div.h
> +++ b/drivers/clk/sunxi-ng/ccu_div.h
> @@ -283,4 +283,16 @@ static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
>
>  extern const struct clk_ops ccu_div_ops;
>
> +struct ccu_div_nb {
> +	struct notifier_block	clk_nb;
> +	struct ccu_common	*common;
> +
> +	u32	delay_us;	/* us to wait after changing parent rate */
> +	int	original_enable;/* This is set by the notifier callback */
> +};
> +
> +#define to_ccu_div_nb(_nb) container_of(_nb, struct ccu_div_nb, clk_nb)
> +
> +int ccu_div_notifier_register(struct clk *clk, struct ccu_div_nb *mux_nb);
> +
>  #endif /* _CCU_DIV_H_ */
>
>
>
>>
>> CLK_SET_RATE_PARENT only gates output on re-parenting, not on parent rate changes,
>> according to the header:
>>
>>   https://elixir.bootlin.com/linux/v6.7.4/source/include/linux/clk-provider.h#L19
>>
>> You'd need perhaps CLK_SET_RATE_GATE *and* still verify that it actually works
>> as expected via some tracing of gpu clock enable/disable/set_rate and pll-gpu
>> set_rate. CLK_SET_RATE_GATE seems confusingly docummented:
>>
>>   https://elixir.bootlin.com/linux/v6.7.4/source/drivers/clk/clk.c#L1034
>>
>> so I don't particularly trust it does exaclty what the header claims and what
>> would be needed to test the theory that gating gpu clock during rate change
>> might help.
>>
>> kind regards,
>> 	o.
>>
>>> Thank you for your detailed proposal! It was insightful to read. But
>>> while those were all great ideas, they have all already been taken care
>>> of. I'm fresh out of ideas again (except for pinning the GPU rate).
>>>
>>> Again, thank you so much,
>>>   Frank
>>>
>>> >>
>>> >> Kind regards,
>>> >> 	o.
>>> >>
>>> >> > I very much appreciate your feedback!
>>> >> >
>>> >> > [1] https://gitlab.com/postmarketOS/pmaports/-/issues/805
>>> >> >
>>> >> > Signed-off-by: Frank Oltmanns <frank at oltmanns.dev>
>>> >> > ---
>>> >> > Changes in v2:
>>> >> > - dts: Increase minimum GPU frequency to 192 MHz.
>>> >> > - nkm and a64: Add minimum and maximum rate for PLL-MIPI.
>>> >> > - nkm: Use the same approach for skipping invalid rates in
>>> >> >   ccu_nkm_find_best() as in ccu_nkm_find_best_with_parent_adj().
>>> >> > - nkm: Improve names for ratio struct members and hence get rid of
>>> >> >   describing comments.
>>> >> > - nkm and a64: Correct description in the commit messages: M/N <= 3
>>> >> > - Remove patches for nm as they were not needed.
>>> >> > - st7703: Rework the commit message to cover more background for the
>>> >> >   change.
>>> >> > - Link to v1: https://lore.kernel.org/r/20231218-pinephone-pll-fixes-v1-0-e238b6ed6dc1 at oltmanns.dev
>>> >> >
>>> >> > ---
>>> >> > Frank Oltmanns (6):
>>> >> >       clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate
>>> >> >       clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate
>>> >> >       clk: sunxi-ng: nkm: Support minimum and maximum rate
>>> >> >       clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
>>> >> >       drm/panel: st7703: Drive XBD599 panel at higher clock rate
>>> >> >       arm64: dts: allwinner: a64: Fix minimum GPU OPP rate
>>> >> >
>>> >> >  arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  4 ++--
>>> >> >  drivers/clk/sunxi-ng/ccu-sun50i-a64.c         | 14 +++++++----
>>> >> >  drivers/clk/sunxi-ng/ccu_nkm.c                | 34 +++++++++++++++++++++++++++
>>> >> >  drivers/clk/sunxi-ng/ccu_nkm.h                |  4 ++++
>>> >> >  drivers/gpu/drm/panel/panel-sitronix-st7703.c | 14 +++++------
>>> >> >  5 files changed, 56 insertions(+), 14 deletions(-)
>>> >> > ---
>>> >> > base-commit: 059c53e877ca6e723e10490c27c1487a63e66efe
>>> >> > change-id: 20231218-pinephone-pll-fixes-0ccdfde273e4
>>> >> >
>>> >> > Best regards,
>>> >> > --
>>> >> > Frank Oltmanns <frank at oltmanns.dev>
>>> >> >


From krzysztof.kozlowski at linaro.org  Sun Feb 25 23:25:28 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 26 Feb 2024 08:25:28 +0100
Subject: (subset) [PATCH v4 02/16] dt-bindings: bus: imx-weim: convert
 to YAML
In-Reply-To: <20240224213240.1854709-3-sre@kernel.org>
References: <20240224213240.1854709-1-sre@kernel.org>
 <20240224213240.1854709-3-sre@kernel.org>
Message-ID: <170893232894.6616.17442231091055419472.b4-ty@linaro.org>


On Sat, 24 Feb 2024 22:29:34 +0100, Sebastian Reichel wrote:
> Convert the i.MX  Wireless External Interface Module binding to YAML.
> 
> 

Applied, thanks!

[02/16] dt-bindings: bus: imx-weim: convert to YAML
        https://git.kernel.org/krzk/linux-mem-ctrl/c/3884bdce169de87d3f978edf41829e5e52388072

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>



From marex at denx.de  Sun Feb 25 23:28:05 2024
From: marex at denx.de (Marek Vasut)
Date: Mon, 26 Feb 2024 08:28:05 +0100
Subject: [PATCH v2] drm/lcdif: Do not disable clocks on already suspended hardware
Message-ID: <20240226072904.26861-1-marex@denx.de>

In case the LCDIF is enabled in DT but unused, the clocks used by the
LCDIF are not enabled. Those clocks may even have a use count of 0 in
case there are no other users of those clocks. This can happen e.g. in
case the LCDIF drives HDMI bridge which has no panel plugged into the
HDMI connector.

Do not attempt to disable clocks in the suspend callback and re-enable
clocks in the resume callback unless the LCDIF is enabled and was in
use before the system entered suspend, otherwise the driver might end
up trying to disable clocks which are already disabled with use count
0, and would trigger a warning from clocks core about this condition.

Note that the lcdif_rpm_suspend() and lcdif_rpm_resume() functions
internally perform the clocks disable and enable operations and act
as runtime PM hooks too.

Reviewed-by: Liu Ying <victor.liu at nxp.com>
Fixes: 9db35bb349a0 ("drm: lcdif: Add support for i.MX8MP LCDIF variant")
Signed-off-by: Marek Vasut <marex at denx.de>
---
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: David Airlie <airlied at gmail.com>
Cc: Fabio Estevam <festevam at gmail.com>
Cc: Liu Ying <victor.liu at nxp.com>
Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
Cc: Sascha Hauer <s.hauer at pengutronix.de>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Stefan Agner <stefan at agner.ch>
Cc: Thomas Zimmermann <tzimmermann at suse.de>
Cc: dri-devel at lists.freedesktop.org
Cc: linux-arm-kernel at lists.infradead.org
---
V2: - s at clock@clocks at g in commit message
    - Add RB from Liu
---
 drivers/gpu/drm/mxsfb/lcdif_drv.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdif_drv.c
index 18de2f17e2491..6494e82707569 100644
--- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
+++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
@@ -340,6 +340,9 @@ static int __maybe_unused lcdif_suspend(struct device *dev)
 	if (ret)
 		return ret;
 
+	if (pm_runtime_suspended(dev))
+		return 0;
+
 	return lcdif_rpm_suspend(dev);
 }
 
@@ -347,7 +350,8 @@ static int __maybe_unused lcdif_resume(struct device *dev)
 {
 	struct drm_device *drm = dev_get_drvdata(dev);
 
-	lcdif_rpm_resume(dev);
+	if (!pm_runtime_suspended(dev))
+		lcdif_rpm_resume(dev);
 
 	return drm_mode_config_helper_resume(drm);
 }
-- 
2.43.0



From devnull+nikita.shubin.maquefel.me at kernel.org  Sun Feb 25 23:29:57 2024
From: devnull+nikita.shubin.maquefel.me at kernel.org (Nikita Shubin via B4 Relay)
Date: Mon, 26 Feb 2024 10:29:57 +0300
Subject: [PATCH v8 01/38] gpio: ep93xx: split device in multiple
In-Reply-To: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
References: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
Message-ID: <20240226-ep93xx-v8-1-3136dca7238f@maquefel.me>

From: Nikita Shubin <nikita.shubin at maquefel.me>

Prepare ep93xx SOC gpio to convert into device tree driver:
- dropped banks and legacy defines
- split AB IRQ and make it shared

We are relying on IRQ number information A, B ports have single shared
IRQ, while F port have dedicated IRQ for each line.

Also we had to split single ep93xx platform_device into multiple, one
for each port, without this we can't do a full working transition from
legacy platform code into device tree capable. All GPIO_LOOKUP were
change to match new chip namings.

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
Reviewed-by: Andy Shevchenko <andy at kernel.org>
Signed-off-by: Nikita Shubin <nikita.shubin at maquefel.me>
---
 arch/arm/mach-ep93xx/core.c          | 121 ++++++++++++--
 arch/arm/mach-ep93xx/edb93xx.c       |   2 +-
 arch/arm/mach-ep93xx/ts72xx.c        |   4 +-
 arch/arm/mach-ep93xx/vision_ep9307.c |  10 +-
 drivers/gpio/gpio-ep93xx.c           | 311 +++++++++++++----------------------
 5 files changed, 228 insertions(+), 220 deletions(-)

diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 8b1ec60a9a46..03bce5e9d1f1 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -35,6 +35,7 @@
 #include <linux/reboot.h>
 #include <linux/usb/ohci_pdriver.h>
 #include <linux/random.h>
+#include <linux/ioport.h>
 
 #include "hardware.h"
 #include <linux/platform_data/video-ep93xx.h>
@@ -139,9 +140,80 @@ EXPORT_SYMBOL_GPL(ep93xx_chip_revision);
 /*************************************************************************
  * EP93xx GPIO
  *************************************************************************/
-static struct resource ep93xx_gpio_resource[] = {
-	DEFINE_RES_MEM(EP93XX_GPIO_PHYS_BASE, 0xcc),
+/* port A */
+static struct resource ep93xx_a_gpio_resources[] = {
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE,        0x04, "data"),
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x10, 0x04, "dir"),
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x90, 0x1c, "intr"),
 	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO_AB),
+};
+
+static struct platform_device ep93xx_a_gpio = {
+	.name           = "gpio-ep93xx",
+	.id             = 0,
+	.num_resources = ARRAY_SIZE(ep93xx_a_gpio_resources),
+	.resource = ep93xx_a_gpio_resources,
+};
+
+/* port B */
+static struct resource ep93xx_b_gpio_resources[] = {
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x04, 0x04, "data"),
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x14, 0x04, "dir"),
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0xac, 0x1c, "intr"),
+	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO_AB),
+};
+
+static struct platform_device ep93xx_b_gpio = {
+	.name           = "gpio-ep93xx",
+	.id             = 1,
+	.num_resources = ARRAY_SIZE(ep93xx_b_gpio_resources),
+	.resource = ep93xx_b_gpio_resources,
+};
+
+/* port C */
+static struct resource ep93xx_c_gpio_resources[] = {
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x08, 0x04, "data"),
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x18, 0x04, "dir"),
+};
+
+static struct platform_device ep93xx_c_gpio = {
+	.name           = "gpio-ep93xx",
+	.id             = 2,
+	.num_resources = ARRAY_SIZE(ep93xx_c_gpio_resources),
+	.resource = ep93xx_c_gpio_resources,
+};
+
+/* port D */
+static struct resource ep93xx_d_gpio_resources[] = {
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x0c, 0x04, "data"),
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x1c, 0x04, "dir"),
+};
+
+static struct platform_device ep93xx_d_gpio = {
+	.name           = "gpio-ep93xx",
+	.id             = 3,
+	.num_resources = ARRAY_SIZE(ep93xx_d_gpio_resources),
+	.resource = ep93xx_d_gpio_resources,
+};
+
+/* port E */
+static struct resource ep93xx_e_gpio_resources[] = {
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x20, 0x04, "data"),
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x24, 0x04, "dir"),
+};
+
+static struct platform_device ep93xx_e_gpio = {
+	.name           = "gpio-ep93xx",
+	.id             = 4,
+	.num_resources = ARRAY_SIZE(ep93xx_e_gpio_resources),
+	.resource = ep93xx_e_gpio_resources,
+};
+
+/* port F */
+static struct resource ep93xx_f_gpio_resources[] = {
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x30, 0x04, "data"),
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x34, 0x04, "dir"),
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x4c, 0x1c, "intr"),
 	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO0MUX),
 	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO1MUX),
 	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO2MUX),
@@ -152,11 +224,34 @@ static struct resource ep93xx_gpio_resource[] = {
 	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO7MUX),
 };
 
-static struct platform_device ep93xx_gpio_device = {
-	.name		= "gpio-ep93xx",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(ep93xx_gpio_resource),
-	.resource	= ep93xx_gpio_resource,
+static struct platform_device ep93xx_f_gpio = {
+	.name           = "gpio-ep93xx",
+	.id             = 5,
+	.num_resources = ARRAY_SIZE(ep93xx_f_gpio_resources),
+	.resource = ep93xx_f_gpio_resources,
+};
+
+/* port G */
+static struct resource ep93xx_g_gpio_resources[] = {
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x38, 0x04, "data"),
+	DEFINE_RES_MEM_NAMED(EP93XX_GPIO_PHYS_BASE + 0x3c, 0x04, "dir"),
+};
+
+static struct platform_device ep93xx_g_gpio = {
+	.name           = "gpio-ep93xx",
+	.id             = 6,
+	.num_resources = ARRAY_SIZE(ep93xx_g_gpio_resources),
+	.resource = ep93xx_g_gpio_resources,
+};
+
+static struct platform_device *ep93xx_gpio_device[] __initdata = {
+	&ep93xx_a_gpio,
+	&ep93xx_b_gpio,
+	&ep93xx_c_gpio,
+	&ep93xx_d_gpio,
+	&ep93xx_e_gpio,
+	&ep93xx_f_gpio,
+	&ep93xx_g_gpio,
 };
 
 /*************************************************************************
@@ -335,9 +430,9 @@ static struct gpiod_lookup_table ep93xx_i2c_gpiod_table = {
 	.dev_id		= "i2c-gpio.0",
 	.table		= {
 		/* Use local offsets on gpiochip/port "G" */
-		GPIO_LOOKUP_IDX("G", 1, NULL, 0,
+		GPIO_LOOKUP_IDX("gpio-ep93xx.6", 1, NULL, 0,
 				GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
-		GPIO_LOOKUP_IDX("G", 0, NULL, 1,
+		GPIO_LOOKUP_IDX("gpio-ep93xx.6", 0, NULL, 1,
 				GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
 		{ }
 	},
@@ -441,8 +536,8 @@ static struct gpiod_lookup_table ep93xx_leds_gpio_table = {
 	.dev_id = "leds-gpio",
 	.table = {
 		/* Use local offsets on gpiochip/port "E" */
-		GPIO_LOOKUP_IDX("E", 0, NULL, 0, GPIO_ACTIVE_HIGH),
-		GPIO_LOOKUP_IDX("E", 1,	NULL, 1, GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP_IDX("gpio-ep93xx.4", 0, NULL, 0, GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP_IDX("gpio-ep93xx.4", 1, NULL, 1, GPIO_ACTIVE_HIGH),
 		{ }
 	},
 };
@@ -975,6 +1070,7 @@ static struct device __init *ep93xx_init_soc(void)
 struct device __init *ep93xx_init_devices(void)
 {
 	struct device *parent;
+	unsigned int i;
 
 	/* Disallow access to MaverickCrunch initially */
 	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
@@ -989,7 +1085,8 @@ struct device __init *ep93xx_init_devices(void)
 	parent = ep93xx_init_soc();
 
 	/* Get the GPIO working early, other devices need it */
-	platform_device_register(&ep93xx_gpio_device);
+	for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_device); i++)
+		platform_device_register(ep93xx_gpio_device[i]);
 
 	amba_device_register(&uart1_device, &iomem_resource);
 	amba_device_register(&uart2_device, &iomem_resource);
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index dbdb822a0100..356b0460c7ed 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -105,7 +105,7 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
 static struct gpiod_lookup_table edb93xx_spi_cs_gpio_table = {
 	.dev_id = "spi0",
 	.table = {
-		GPIO_LOOKUP("A", 6, "cs", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio-ep93xx.0", 6, "cs", GPIO_ACTIVE_LOW),
 		{ },
 	},
 };
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index d3de7283ecb3..0bbdf587c685 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -268,7 +268,7 @@ static struct spi_board_info bk3_spi_board_info[] __initdata = {
 static struct gpiod_lookup_table bk3_spi_cs_gpio_table = {
 	.dev_id = "spi0",
 	.table = {
-		GPIO_LOOKUP("F", 3, "cs", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio-ep93xx.5", 3, "cs", GPIO_ACTIVE_LOW),
 		{ },
 	},
 };
@@ -318,7 +318,7 @@ static struct gpiod_lookup_table ts72xx_spi_cs_gpio_table = {
 	.dev_id = "spi0",
 	.table = {
 		/* DIO_17 */
-		GPIO_LOOKUP("F", 2, "cs", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio-ep93xx.5", 2, "cs", GPIO_ACTIVE_LOW),
 		{ },
 	},
 };
diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c
index 9471938df64c..b3087b8eed3f 100644
--- a/arch/arm/mach-ep93xx/vision_ep9307.c
+++ b/arch/arm/mach-ep93xx/vision_ep9307.c
@@ -206,9 +206,9 @@ static struct gpiod_lookup_table vision_spi_mmc_gpio_table = {
 	.dev_id = "mmc_spi.2", /* "mmc_spi @ CS2 */
 	.table = {
 		/* Card detect */
-		GPIO_LOOKUP_IDX("B", 7, NULL, 0, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-ep93xx.1", 7, NULL, 0, GPIO_ACTIVE_LOW),
 		/* Write protect */
-		GPIO_LOOKUP_IDX("F", 0, NULL, 1, GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP_IDX("gpio-ep93xx.5", 0, NULL, 1, GPIO_ACTIVE_HIGH),
 		{ },
 	},
 };
@@ -253,9 +253,9 @@ static struct gpiod_lookup_table vision_spi_cs4271_gpio_table = {
 static struct gpiod_lookup_table vision_spi_cs_gpio_table = {
 	.dev_id = "spi0",
 	.table = {
-		GPIO_LOOKUP_IDX("A", 6, "cs", 0, GPIO_ACTIVE_LOW),
-		GPIO_LOOKUP_IDX("A", 7, "cs", 1, GPIO_ACTIVE_LOW),
-		GPIO_LOOKUP_IDX("G", 2, "cs", 2, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-ep93xx.0", 6, "cs", 0, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-ep93xx.0", 7, "cs", 1, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-ep93xx.6", 2, "cs", 2, GPIO_ACTIVE_LOW),
 		{ },
 	},
 };
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index 6cedf46efec6..a55f635585f4 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -18,30 +18,10 @@
 #include <linux/gpio/driver.h>
 #include <linux/bitops.h>
 #include <linux/seq_file.h>
-
-#define EP93XX_GPIO_F_INT_STATUS 0x5c
-#define EP93XX_GPIO_A_INT_STATUS 0xa0
-#define EP93XX_GPIO_B_INT_STATUS 0xbc
-
-/* Maximum value for gpio line identifiers */
-#define EP93XX_GPIO_LINE_MAX 63
-
-/* Number of GPIO chips in EP93XX */
-#define EP93XX_GPIO_CHIP_NUM 8
-
-/* Maximum value for irq capable line identifiers */
-#define EP93XX_GPIO_LINE_MAX_IRQ 23
-
-#define EP93XX_GPIO_A_IRQ_BASE 64
-#define EP93XX_GPIO_B_IRQ_BASE 72
-/*
- * Static mapping of GPIO bank F IRQS:
- * F0..F7 (16..24) to irq 80..87.
- */
-#define EP93XX_GPIO_F_IRQ_BASE 80
+#include <linux/interrupt.h>
 
 struct ep93xx_gpio_irq_chip {
-	u8 irq_offset;
+	void __iomem *base;
 	u8 int_unmasked;
 	u8 int_enabled;
 	u8 int_type1;
@@ -50,15 +30,11 @@ struct ep93xx_gpio_irq_chip {
 };
 
 struct ep93xx_gpio_chip {
+	void __iomem			*base;
 	struct gpio_chip		gc;
 	struct ep93xx_gpio_irq_chip	*eic;
 };
 
-struct ep93xx_gpio {
-	void __iomem		*base;
-	struct ep93xx_gpio_chip	gc[EP93XX_GPIO_CHIP_NUM];
-};
-
 #define to_ep93xx_gpio_chip(x) container_of(x, struct ep93xx_gpio_chip, gc)
 
 static struct ep93xx_gpio_irq_chip *to_ep93xx_gpio_irq_chip(struct gpio_chip *gc)
@@ -79,25 +55,23 @@ static struct ep93xx_gpio_irq_chip *to_ep93xx_gpio_irq_chip(struct gpio_chip *gc
 #define EP93XX_INT_RAW_STATUS_OFFSET	0x14
 #define EP93XX_INT_DEBOUNCE_OFFSET	0x18
 
-static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg,
-					  struct ep93xx_gpio_irq_chip *eic)
+static void ep93xx_gpio_update_int_params(struct ep93xx_gpio_irq_chip *eic)
 {
-	writeb_relaxed(0, epg->base + eic->irq_offset + EP93XX_INT_EN_OFFSET);
+	writeb_relaxed(0, eic->base + EP93XX_INT_EN_OFFSET);
 
 	writeb_relaxed(eic->int_type2,
-		       epg->base + eic->irq_offset + EP93XX_INT_TYPE2_OFFSET);
+		       eic->base + EP93XX_INT_TYPE2_OFFSET);
 
 	writeb_relaxed(eic->int_type1,
-		       epg->base + eic->irq_offset + EP93XX_INT_TYPE1_OFFSET);
+		       eic->base + EP93XX_INT_TYPE1_OFFSET);
 
 	writeb_relaxed(eic->int_unmasked & eic->int_enabled,
-		       epg->base + eic->irq_offset + EP93XX_INT_EN_OFFSET);
+		       eic->base + EP93XX_INT_EN_OFFSET);
 }
 
 static void ep93xx_gpio_int_debounce(struct gpio_chip *gc,
 				     unsigned int offset, bool enable)
 {
-	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 	struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
 	int port_mask = BIT(offset);
 
@@ -106,53 +80,43 @@ static void ep93xx_gpio_int_debounce(struct gpio_chip *gc,
 	else
 		eic->int_debounce &= ~port_mask;
 
-	writeb(eic->int_debounce,
-	       epg->base + eic->irq_offset + EP93XX_INT_DEBOUNCE_OFFSET);
+	writeb(eic->int_debounce, eic->base + EP93XX_INT_DEBOUNCE_OFFSET);
 }
 
-static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
+static u32 ep93xx_gpio_ab_irq_handler(struct gpio_chip *gc)
 {
-	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
 	unsigned long stat;
 	int offset;
 
-	chained_irq_enter(irqchip, desc);
-
-	/*
-	 * Dispatch the IRQs to the irqdomain of each A and B
-	 * gpiochip irqdomains depending on what has fired.
-	 * The tricky part is that the IRQ line is shared
-	 * between bank A and B and each has their own gpiochip.
-	 */
-	stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
+	stat = readb(eic->base + EP93XX_INT_STATUS_OFFSET);
 	for_each_set_bit(offset, &stat, 8)
-		generic_handle_domain_irq(epg->gc[0].gc.irq.domain,
-					  offset);
+		generic_handle_domain_irq(gc->irq.domain, offset);
 
-	stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
-	for_each_set_bit(offset, &stat, 8)
-		generic_handle_domain_irq(epg->gc[1].gc.irq.domain,
-					  offset);
+	return stat;
+}
 
-	chained_irq_exit(irqchip, desc);
+static irqreturn_t ep93xx_ab_irq_handler(int irq, void *dev_id)
+{
+	return IRQ_RETVAL(ep93xx_gpio_ab_irq_handler(dev_id));
 }
 
 static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc)
 {
-	/*
-	 * map discontiguous hw irq range to continuous sw irq range:
-	 *
-	 *  IRQ_EP93XX_GPIO{0..7}MUX -> EP93XX_GPIO_LINE_F{0..7}
-	 */
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
-	unsigned int irq = irq_desc_get_irq(desc);
-	int port_f_idx = (irq & 7) ^ 4; /* {20..23,48..51} -> {0..7} */
-	int gpio_irq = EP93XX_GPIO_F_IRQ_BASE + port_f_idx;
+	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+	struct gpio_irq_chip *gic = &gc->irq;
+	unsigned int parent = irq_desc_get_irq(desc);
+	unsigned int i;
 
 	chained_irq_enter(irqchip, desc);
-	generic_handle_irq(gpio_irq);
+	for (i = 0; i < gic->num_parents; i++)
+		if (gic->parents[i] == parent)
+			break;
+
+	if (i < gic->num_parents)
+		generic_handle_domain_irq(gc->irq.domain, i);
+
 	chained_irq_exit(irqchip, desc);
 }
 
@@ -160,31 +124,29 @@ static void ep93xx_gpio_irq_ack(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
-	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int port_mask = BIT(d->irq & 7);
+	int port_mask = BIT(irqd_to_hwirq(d));
 
 	if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
 		eic->int_type2 ^= port_mask; /* switch edge direction */
-		ep93xx_gpio_update_int_params(epg, eic);
+		ep93xx_gpio_update_int_params(eic);
 	}
 
-	writeb(port_mask, epg->base + eic->irq_offset + EP93XX_INT_EOI_OFFSET);
+	writeb(port_mask, eic->base + EP93XX_INT_EOI_OFFSET);
 }
 
 static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
-	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int port_mask = BIT(d->irq & 7);
+	int port_mask = BIT(irqd_to_hwirq(d));
 
 	if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH)
 		eic->int_type2 ^= port_mask; /* switch edge direction */
 
 	eic->int_unmasked &= ~port_mask;
-	ep93xx_gpio_update_int_params(epg, eic);
+	ep93xx_gpio_update_int_params(eic);
 
-	writeb(port_mask, epg->base + eic->irq_offset + EP93XX_INT_EOI_OFFSET);
+	writeb(port_mask, eic->base + EP93XX_INT_EOI_OFFSET);
 	gpiochip_disable_irq(gc, irqd_to_hwirq(d));
 }
 
@@ -192,10 +154,9 @@ static void ep93xx_gpio_irq_mask(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
-	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 
-	eic->int_unmasked &= ~BIT(d->irq & 7);
-	ep93xx_gpio_update_int_params(epg, eic);
+	eic->int_unmasked &= ~BIT(irqd_to_hwirq(d));
+	ep93xx_gpio_update_int_params(eic);
 	gpiochip_disable_irq(gc, irqd_to_hwirq(d));
 }
 
@@ -203,11 +164,10 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
-	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
 
 	gpiochip_enable_irq(gc, irqd_to_hwirq(d));
-	eic->int_unmasked |= BIT(d->irq & 7);
-	ep93xx_gpio_update_int_params(epg, eic);
+	eic->int_unmasked |= BIT(irqd_to_hwirq(d));
+	ep93xx_gpio_update_int_params(eic);
 }
 
 /*
@@ -219,8 +179,7 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
 {
 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 	struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc);
-	struct ep93xx_gpio *epg = gpiochip_get_data(gc);
-	int offset = d->irq & 7;
+	irq_hw_number_t offset = irqd_to_hwirq(d);
 	int port_mask = BIT(offset);
 	irq_flow_handler_t handler;
 
@@ -264,51 +223,11 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
 
 	eic->int_enabled |= port_mask;
 
-	ep93xx_gpio_update_int_params(epg, eic);
+	ep93xx_gpio_update_int_params(eic);
 
 	return 0;
 }
 
-/*************************************************************************
- * gpiolib interface for EP93xx on-chip GPIOs
- *************************************************************************/
-struct ep93xx_gpio_bank {
-	const char	*label;
-	int		data;
-	int		dir;
-	int		irq;
-	int		base;
-	bool		has_irq;
-	bool		has_hierarchical_irq;
-	unsigned int	irq_base;
-};
-
-#define EP93XX_GPIO_BANK(_label, _data, _dir, _irq, _base, _has_irq, _has_hier, _irq_base) \
-	{							\
-		.label		= _label,			\
-		.data		= _data,			\
-		.dir		= _dir,				\
-		.irq		= _irq,				\
-		.base		= _base,			\
-		.has_irq	= _has_irq,			\
-		.has_hierarchical_irq = _has_hier,		\
-		.irq_base	= _irq_base,			\
-	}
-
-static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
-	/* Bank A has 8 IRQs */
-	EP93XX_GPIO_BANK("A", 0x00, 0x10, 0x90, 0, true, false, EP93XX_GPIO_A_IRQ_BASE),
-	/* Bank B has 8 IRQs */
-	EP93XX_GPIO_BANK("B", 0x04, 0x14, 0xac, 8, true, false, EP93XX_GPIO_B_IRQ_BASE),
-	EP93XX_GPIO_BANK("C", 0x08, 0x18, 0x00, 40, false, false, 0),
-	EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 0x00, 24, false, false, 0),
-	EP93XX_GPIO_BANK("E", 0x20, 0x24, 0x00, 32, false, false, 0),
-	/* Bank F has 8 IRQs */
-	EP93XX_GPIO_BANK("F", 0x30, 0x34, 0x4c, 16, false, true, EP93XX_GPIO_F_IRQ_BASE),
-	EP93XX_GPIO_BANK("G", 0x38, 0x3c, 0x00, 48, false, false, 0),
-	EP93XX_GPIO_BANK("H", 0x40, 0x44, 0x00, 56, false, false, 0),
-};
-
 static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 				  unsigned long config)
 {
@@ -342,110 +261,102 @@ static const struct irq_chip gpio_eic_irq_chip = {
 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
 };
 
-static int ep93xx_gpio_add_bank(struct ep93xx_gpio_chip *egc,
-				struct platform_device *pdev,
-				struct ep93xx_gpio *epg,
-				struct ep93xx_gpio_bank *bank)
+static int ep93xx_setup_irqs(struct platform_device *pdev,
+			     struct ep93xx_gpio_chip *egc)
 {
-	void __iomem *data = epg->base + bank->data;
-	void __iomem *dir = epg->base + bank->dir;
 	struct gpio_chip *gc = &egc->gc;
 	struct device *dev = &pdev->dev;
-	struct gpio_irq_chip *girq;
-	int err;
+	struct gpio_irq_chip *girq = &gc->irq;
+	int ret, irq, i;
+	void __iomem *intr;
 
-	err = bgpio_init(gc, dev, 1, data, NULL, NULL, dir, NULL, 0);
-	if (err)
-		return err;
+	intr = devm_platform_ioremap_resource_byname(pdev, "intr");
+	if (IS_ERR(intr))
+		return PTR_ERR(intr);
 
-	gc->label = bank->label;
-	gc->base = bank->base;
+	gc->set_config = ep93xx_gpio_set_config;
+	egc->eic = devm_kzalloc(dev, sizeof(*egc->eic), GFP_KERNEL);
+	if (!egc->eic)
+		return -ENOMEM;
 
-	girq = &gc->irq;
-	if (bank->has_irq || bank->has_hierarchical_irq) {
-		gc->set_config = ep93xx_gpio_set_config;
-		egc->eic = devm_kcalloc(dev, 1,
-					sizeof(*egc->eic),
-					GFP_KERNEL);
-		if (!egc->eic)
-			return -ENOMEM;
-		egc->eic->irq_offset = bank->irq;
-		gpio_irq_chip_set_chip(girq, &gpio_eic_irq_chip);
-	}
+	egc->eic->base = intr;
+	gpio_irq_chip_set_chip(girq, &gpio_eic_irq_chip);
+	girq->num_parents = platform_irq_count(pdev);
+	if (girq->num_parents == 0)
+		return -EINVAL;
 
-	if (bank->has_irq) {
-		int ab_parent_irq = platform_get_irq(pdev, 0);
+	girq->parents = devm_kcalloc(dev, girq->num_parents,
+				   sizeof(*girq->parents),
+				   GFP_KERNEL);
+	if (!girq->parents)
+		return -ENOMEM;
 
-		girq->parent_handler = ep93xx_gpio_ab_irq_handler;
-		girq->num_parents = 1;
-		girq->parents = devm_kcalloc(dev, girq->num_parents,
-					     sizeof(*girq->parents),
-					     GFP_KERNEL);
-		if (!girq->parents)
-			return -ENOMEM;
-		girq->default_type = IRQ_TYPE_NONE;
-		girq->handler = handle_level_irq;
-		girq->parents[0] = ab_parent_irq;
-		girq->first = bank->irq_base;
-	}
+	if (girq->num_parents == 1) { /* A/B irqchips */
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return irq;
 
-	/* Only bank F has especially funky IRQ handling */
-	if (bank->has_hierarchical_irq) {
-		int gpio_irq;
-		int i;
+		ret = devm_request_irq(dev, irq, ep93xx_ab_irq_handler,
+				       IRQF_SHARED, gc->label, gc);
+		if (ret)
+			return dev_err_probe(dev, ret, "requesting IRQ: %d\n", irq);
 
-		/*
-		 * FIXME: convert this to use hierarchical IRQ support!
-		 * this requires fixing the root irqchip to be hierarchical.
-		 */
+		girq->parents[0] = irq;
+	} else { /* F irqchip */
 		girq->parent_handler = ep93xx_gpio_f_irq_handler;
-		girq->num_parents = 8;
-		girq->parents = devm_kcalloc(dev, girq->num_parents,
-					     sizeof(*girq->parents),
-					     GFP_KERNEL);
-		if (!girq->parents)
-			return -ENOMEM;
-		/* Pick resources 1..8 for these IRQs */
+
 		for (i = 0; i < girq->num_parents; i++) {
-			girq->parents[i] = platform_get_irq(pdev, i + 1);
-			gpio_irq = bank->irq_base + i;
-			irq_set_chip_data(gpio_irq, &epg->gc[5]);
-			irq_set_chip_and_handler(gpio_irq,
-						 girq->chip,
-						 handle_level_irq);
-			irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+			irq = platform_get_irq(pdev, i);
+			if (irq < 0)
+				continue;
+
+			girq->parents[i] = irq;
 		}
-		girq->default_type = IRQ_TYPE_NONE;
-		girq->handler = handle_level_irq;
-		girq->first = bank->irq_base;
+
+		girq->map = girq->parents;
 	}
 
-	return devm_gpiochip_add_data(dev, gc, epg);
+	girq->default_type = IRQ_TYPE_NONE;
+	/* TODO: replace with handle_bad_irq() once we are fully hierarchical */
+	girq->handler = handle_simple_irq;
+
+	return 0;
 }
 
 static int ep93xx_gpio_probe(struct platform_device *pdev)
 {
-	struct ep93xx_gpio *epg;
-	int i;
+	struct ep93xx_gpio_chip *egc;
+	struct gpio_chip *gc;
+	void __iomem *data;
+	void __iomem *dir;
+	int ret;
 
-	epg = devm_kzalloc(&pdev->dev, sizeof(*epg), GFP_KERNEL);
-	if (!epg)
+	egc = devm_kzalloc(&pdev->dev, sizeof(*egc), GFP_KERNEL);
+	if (!egc)
 		return -ENOMEM;
 
-	epg->base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(epg->base))
-		return PTR_ERR(epg->base);
+	data = devm_platform_ioremap_resource_byname(pdev, "data");
+	if (IS_ERR(data))
+		return PTR_ERR(data);
 
-	for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
-		struct ep93xx_gpio_chip *gc = &epg->gc[i];
-		struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
+	dir = devm_platform_ioremap_resource_byname(pdev, "dir");
+	if (IS_ERR(dir))
+		return PTR_ERR(dir);
 
-		if (ep93xx_gpio_add_bank(gc, pdev, epg, bank))
-			dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
-				 bank->label);
+	gc = &egc->gc;
+	ret = bgpio_init(gc, &pdev->dev, 1, data, NULL, NULL, dir, NULL, 0);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "unable to init generic GPIO\n");
+
+	gc->label = dev_name(&pdev->dev);
+	if (platform_irq_count(pdev) > 0) {
+		dev_dbg(&pdev->dev, "setting up irqs for %s\n", dev_name(&pdev->dev));
+		ret = ep93xx_setup_irqs(pdev, egc);
+		if (ret)
+			dev_err_probe(&pdev->dev, ret, "setup irqs failed");
 	}
 
-	return 0;
+	return devm_gpiochip_add_data(&pdev->dev, gc, egc);
 }
 
 static struct platform_driver ep93xx_gpio_driver = {

-- 
2.41.0



From devnull+nikita.shubin.maquefel.me at kernel.org  Sun Feb 25 23:30:22 2024
From: devnull+nikita.shubin.maquefel.me at kernel.org (Nikita Shubin via B4 Relay)
Date: Mon, 26 Feb 2024 10:30:22 +0300
Subject: [PATCH v8 26/38] ASoC: dt-bindings: ep93xx: Document DMA support
In-Reply-To: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
References: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
Message-ID: <20240226-ep93xx-v8-26-3136dca7238f@maquefel.me>

From: Nikita Shubin <nikita.shubin at maquefel.me>

Document DMA support in binding document.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Nikita Shubin <nikita.shubin at maquefel.me>
---
 .../devicetree/bindings/sound/cirrus,ep9301-i2s.yaml         | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml b/Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml
index 453d493c941f..36a320ddf534 100644
--- a/Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml
+++ b/Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml
@@ -40,6 +40,16 @@ properties:
       - const: sclk
       - const: lrclk
 
+  dmas:
+    items:
+      - description: out DMA channel
+      - description: in DMA channel
+
+  dma-names:
+    items:
+      - const: tx
+      - const: rx
+
 required:
   - compatible
   - '#sound-dai-cells'
@@ -61,6 +71,8 @@ examples:
                  <&syscon 30>,
                  <&syscon 31>;
         clock-names = "mclk", "sclk", "lrclk";
+        dmas = <&dma0 0 1>, <&dma0 0 2>;
+        dma-names = "tx", "rx";
     };
 
 ...

-- 
2.41.0



From devnull+nikita.shubin.maquefel.me at kernel.org  Sun Feb 25 23:30:19 2024
From: devnull+nikita.shubin.maquefel.me at kernel.org (Nikita Shubin via B4 Relay)
Date: Mon, 26 Feb 2024 10:30:19 +0300
Subject: [PATCH v8 23/38] input: keypad: ep93xx: add DT support for Cirrus
 EP93xx
In-Reply-To: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
References: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
Message-ID: <20240226-ep93xx-v8-23-3136dca7238f@maquefel.me>

From: Nikita Shubin <nikita.shubin at maquefel.me>

- drop flags, they were not used anyway
- add OF ID match table
- process "autorepeat", "debounce-delay-ms", prescale from device tree
- drop platform data usage and it's header
- keymap goes from device tree now on

Acked-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>
Signed-off-by: Nikita Shubin <nikita.shubin at maquefel.me>
---
 arch/arm/mach-ep93xx/core.c            | 46 ---------------------
 drivers/input/keyboard/ep93xx_keypad.c | 74 ++++++++++------------------------
 include/linux/soc/cirrus/ep93xx.h      |  4 --
 3 files changed, 22 insertions(+), 102 deletions(-)

diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 03bce5e9d1f1..b99c46d22c4d 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -697,52 +697,6 @@ void __init ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data)
 	platform_device_register(&ep93xx_keypad_device);
 }
 
-int ep93xx_keypad_acquire_gpio(struct platform_device *pdev)
-{
-	int err;
-	int i;
-
-	for (i = 0; i < 8; i++) {
-		err = gpio_request(EP93XX_GPIO_LINE_C(i), dev_name(&pdev->dev));
-		if (err)
-			goto fail_gpio_c;
-		err = gpio_request(EP93XX_GPIO_LINE_D(i), dev_name(&pdev->dev));
-		if (err)
-			goto fail_gpio_d;
-	}
-
-	/* Enable the keypad controller; GPIO ports C and D used for keypad */
-	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_KEYS |
-				 EP93XX_SYSCON_DEVCFG_GONK);
-
-	return 0;
-
-fail_gpio_d:
-	gpio_free(EP93XX_GPIO_LINE_C(i));
-fail_gpio_c:
-	for (--i; i >= 0; --i) {
-		gpio_free(EP93XX_GPIO_LINE_C(i));
-		gpio_free(EP93XX_GPIO_LINE_D(i));
-	}
-	return err;
-}
-EXPORT_SYMBOL(ep93xx_keypad_acquire_gpio);
-
-void ep93xx_keypad_release_gpio(struct platform_device *pdev)
-{
-	int i;
-
-	for (i = 0; i < 8; i++) {
-		gpio_free(EP93XX_GPIO_LINE_C(i));
-		gpio_free(EP93XX_GPIO_LINE_D(i));
-	}
-
-	/* Disable the keypad controller; GPIO ports C and D used for GPIO */
-	ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
-			       EP93XX_SYSCON_DEVCFG_GONK);
-}
-EXPORT_SYMBOL(ep93xx_keypad_release_gpio);
-
 /*************************************************************************
  * EP93xx I2S audio peripheral handling
  *************************************************************************/
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c
index 6b811d6bf625..8159134946b3 100644
--- a/drivers/input/keyboard/ep93xx_keypad.c
+++ b/drivers/input/keyboard/ep93xx_keypad.c
@@ -6,20 +6,13 @@
  *
  * Based on the pxa27x matrix keypad controller by Rodolfo Giometti.
  *
- * NOTE:
- *
- * The 3-key reset is triggered by pressing the 3 keys in
- * Row 0, Columns 2, 4, and 7 at the same time.  This action can
- * be disabled by setting the EP93XX_KEYPAD_DISABLE_3_KEY flag.
- *
- * Normal operation for the matrix does not autorepeat the key press.
- * This action can be enabled by setting the EP93XX_KEYPAD_AUTOREPEAT
- * flag.
  */
 
 #include <linux/bits.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -27,7 +20,6 @@
 #include <linux/input/matrix_keypad.h>
 #include <linux/slab.h>
 #include <linux/soc/cirrus/ep93xx.h>
-#include <linux/platform_data/keypad-ep93xx.h>
 #include <linux/pm_wakeirq.h>
 
 /*
@@ -61,12 +53,16 @@
 #define KEY_REG_KEY1_MASK	GENMASK(5, 0)
 #define KEY_REG_KEY1_SHIFT	0
 
+#define EP93XX_MATRIX_ROWS		(8)
+#define EP93XX_MATRIX_COLS		(8)
+
 #define EP93XX_MATRIX_SIZE	(EP93XX_MATRIX_ROWS * EP93XX_MATRIX_COLS)
 
 struct ep93xx_keypad {
-	struct ep93xx_keypad_platform_data *pdata;
 	struct input_dev *input_dev;
 	struct clk *clk;
+	unsigned int	debounce;
+	uint16_t	prescale;
 
 	void __iomem *mmio_base;
 
@@ -133,23 +129,11 @@ static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id)
 
 static void ep93xx_keypad_config(struct ep93xx_keypad *keypad)
 {
-	struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
 	unsigned int val = 0;
 
-	clk_set_rate(keypad->clk, pdata->clk_rate);
+	val |= (keypad->debounce << KEY_INIT_DBNC_SHIFT) & KEY_INIT_DBNC_MASK;
 
-	if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY)
-		val |= KEY_INIT_DIS3KY;
-	if (pdata->flags & EP93XX_KEYPAD_DIAG_MODE)
-		val |= KEY_INIT_DIAG;
-	if (pdata->flags & EP93XX_KEYPAD_BACK_DRIVE)
-		val |= KEY_INIT_BACK;
-	if (pdata->flags & EP93XX_KEYPAD_TEST_MODE)
-		val |= KEY_INIT_T2;
-
-	val |= ((pdata->debounce << KEY_INIT_DBNC_SHIFT) & KEY_INIT_DBNC_MASK);
-
-	val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK);
+	val |= (keypad->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK;
 
 	__raw_writel(val, keypad->mmio_base + KEY_INIT);
 }
@@ -220,17 +204,10 @@ static int ep93xx_keypad_resume(struct device *dev)
 static DEFINE_SIMPLE_DEV_PM_OPS(ep93xx_keypad_pm_ops,
 				ep93xx_keypad_suspend, ep93xx_keypad_resume);
 
-static void ep93xx_keypad_release_gpio_action(void *_pdev)
-{
-	struct platform_device *pdev = _pdev;
-
-	ep93xx_keypad_release_gpio(pdev);
-}
-
 static int ep93xx_keypad_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct ep93xx_keypad *keypad;
-	const struct matrix_keymap_data *keymap_data;
 	struct input_dev *input_dev;
 	int err;
 
@@ -238,14 +215,6 @@ static int ep93xx_keypad_probe(struct platform_device *pdev)
 	if (!keypad)
 		return -ENOMEM;
 
-	keypad->pdata = dev_get_platdata(&pdev->dev);
-	if (!keypad->pdata)
-		return -EINVAL;
-
-	keymap_data = keypad->pdata->keymap_data;
-	if (!keymap_data)
-		return -EINVAL;
-
 	keypad->irq = platform_get_irq(pdev, 0);
 	if (keypad->irq < 0)
 		return keypad->irq;
@@ -254,19 +223,13 @@ static int ep93xx_keypad_probe(struct platform_device *pdev)
 	if (IS_ERR(keypad->mmio_base))
 		return PTR_ERR(keypad->mmio_base);
 
-	err = ep93xx_keypad_acquire_gpio(pdev);
-	if (err)
-		return err;
-
-	err = devm_add_action_or_reset(&pdev->dev,
-				       ep93xx_keypad_release_gpio_action, pdev);
-	if (err)
-		return err;
-
 	keypad->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(keypad->clk))
 		return PTR_ERR(keypad->clk);
 
+	device_property_read_u32(dev, "debounce-delay-ms", &keypad->debounce);
+	device_property_read_u16(dev, "cirrus,prescale", &keypad->prescale);
+
 	input_dev = devm_input_allocate_device(&pdev->dev);
 	if (!input_dev)
 		return -ENOMEM;
@@ -278,13 +241,13 @@ static int ep93xx_keypad_probe(struct platform_device *pdev)
 	input_dev->open = ep93xx_keypad_open;
 	input_dev->close = ep93xx_keypad_close;
 
-	err = matrix_keypad_build_keymap(keymap_data, NULL,
+	err = matrix_keypad_build_keymap(NULL, NULL,
 					 EP93XX_MATRIX_ROWS, EP93XX_MATRIX_COLS,
 					 keypad->keycodes, input_dev);
 	if (err)
 		return err;
 
-	if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT)
+	if (device_property_read_bool(&pdev->dev, "autorepeat"))
 		__set_bit(EV_REP, input_dev->evbit);
 	input_set_drvdata(input_dev, keypad);
 
@@ -313,10 +276,17 @@ static void ep93xx_keypad_remove(struct platform_device *pdev)
 	dev_pm_clear_wake_irq(&pdev->dev);
 }
 
+static const struct of_device_id ep93xx_keypad_of_ids[] = {
+	{ .compatible = "cirrus,ep9307-keypad" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ep93xx_keypad_of_ids);
+
 static struct platform_driver ep93xx_keypad_driver = {
 	.driver		= {
 		.name	= "ep93xx-keypad",
 		.pm	= pm_sleep_ptr(&ep93xx_keypad_pm_ops),
+		.of_match_table = ep93xx_keypad_of_ids,
 	},
 	.probe		= ep93xx_keypad_probe,
 	.remove_new	= ep93xx_keypad_remove,
diff --git a/include/linux/soc/cirrus/ep93xx.h b/include/linux/soc/cirrus/ep93xx.h
index a27447971302..8942bfaf1545 100644
--- a/include/linux/soc/cirrus/ep93xx.h
+++ b/include/linux/soc/cirrus/ep93xx.h
@@ -41,8 +41,6 @@ int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
 void ep93xx_pwm_release_gpio(struct platform_device *pdev);
 int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
 void ep93xx_ide_release_gpio(struct platform_device *pdev);
-int ep93xx_keypad_acquire_gpio(struct platform_device *pdev);
-void ep93xx_keypad_release_gpio(struct platform_device *pdev);
 int ep93xx_i2s_acquire(void);
 void ep93xx_i2s_release(void);
 unsigned int ep93xx_chip_revision(void);
@@ -52,8 +50,6 @@ static inline int ep93xx_pwm_acquire_gpio(struct platform_device *pdev) { return
 static inline void ep93xx_pwm_release_gpio(struct platform_device *pdev) {}
 static inline int ep93xx_ide_acquire_gpio(struct platform_device *pdev) { return 0; }
 static inline void ep93xx_ide_release_gpio(struct platform_device *pdev) {}
-static inline int ep93xx_keypad_acquire_gpio(struct platform_device *pdev) { return 0; }
-static inline void ep93xx_keypad_release_gpio(struct platform_device *pdev) {}
 static inline int ep93xx_i2s_acquire(void) { return 0; }
 static inline void ep93xx_i2s_release(void) {}
 static inline unsigned int ep93xx_chip_revision(void) { return 0; }

-- 
2.41.0



From devnull+nikita.shubin.maquefel.me at kernel.org  Sun Feb 25 23:30:23 2024
From: devnull+nikita.shubin.maquefel.me at kernel.org (Nikita Shubin via B4 Relay)
Date: Mon, 26 Feb 2024 10:30:23 +0300
Subject: [PATCH v8 27/38] ASoC: dt-bindings: ep93xx: Document Audio Port
 support
In-Reply-To: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
References: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
Message-ID: <20240226-ep93xx-v8-27-3136dca7238f@maquefel.me>

From: Nikita Shubin <nikita.shubin at maquefel.me>

Document Audio Graph Port support in binding document.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Nikita Shubin <nikita.shubin at maquefel.me>
---
 Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml b/Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml
index 36a320ddf534..4693e85aed37 100644
--- a/Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml
+++ b/Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml
@@ -50,6 +50,10 @@ properties:
       - const: tx
       - const: rx
 
+  port:
+    $ref: audio-graph-port.yaml#
+    unevaluatedProperties: false
+
 required:
   - compatible
   - '#sound-dai-cells'

-- 
2.41.0



From devnull+nikita.shubin.maquefel.me at kernel.org  Sun Feb 25 23:30:28 2024
From: devnull+nikita.shubin.maquefel.me at kernel.org (Nikita Shubin via B4 Relay)
Date: Mon, 26 Feb 2024 10:30:28 +0300
Subject: [PATCH v8 32/38] ARM: ep93xx: DT for the Cirrus ep93xx SoC
 platforms
In-Reply-To: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
References: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
Message-ID: <20240226-ep93xx-v8-32-3136dca7238f@maquefel.me>

From: Nikita Shubin <nikita.shubin at maquefel.me>

Add compulsory device tree support to the Cirrus ep93xx ARMv4 platform.

- select PINCTRL_EP93xx
- select COMMON_CLK_EP93XX, as clock driver moved out of platform code
- select ARCH_HAS_RESET_CONTROLLER

Select ARM_ATAG_DTB_COMPAT to update device tree with information
about memory passed from bootloader.

We have to leave all MACH options as they are used for board checking
before decomp, to turn off watchdog and ethernet DMA.

Tested-by: Alexander Sverdlin <alexander.sverdlin at gmail.com>
Signed-off-by: Nikita Shubin <nikita.shubin at maquefel.me>
---
 arch/arm/Makefile             |  1 -
 arch/arm/mach-ep93xx/Kconfig  | 20 ++++++++++----------
 arch/arm/mach-ep93xx/Makefile | 11 -----------
 3 files changed, 10 insertions(+), 22 deletions(-)

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 473280d5adce..68a08835feed 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -178,7 +178,6 @@ machine-$(CONFIG_ARCH_CLPS711X)		+= clps711x
 machine-$(CONFIG_ARCH_DAVINCI)		+= davinci
 machine-$(CONFIG_ARCH_DIGICOLOR)	+= digicolor
 machine-$(CONFIG_ARCH_DOVE)		+= dove
-machine-$(CONFIG_ARCH_EP93XX)		+= ep93xx
 machine-$(CONFIG_ARCH_EXYNOS)		+= exynos
 machine-$(CONFIG_ARCH_FOOTBRIDGE)	+= footbridge
 machine-$(CONFIG_ARCH_GEMINI)		+= gemini
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index 703f3d232a60..812b71dcf60e 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -3,27 +3,27 @@ menuconfig ARCH_EP93XX
 	bool "EP93xx-based"
 	depends on ATAGS
 	depends on ARCH_MULTI_V4T
+	# CONFIG_ARCH_MULTI_V7 is not set
 	depends on CPU_LITTLE_ENDIAN
+	select ARCH_HAS_RESET_CONTROLLER
 	select ARCH_SPARSEMEM_ENABLE
 	select ARM_AMBA
 	select ARM_VIC
+	select ARM_APPENDED_DTB # Old Redboot bootloaders deployed
+	select ARM_ATAG_DTB_COMPAT # we need this to update dt memory node
+	select COMMON_CLK_EP93XX
+	select EP93XX_TIMER
 	select CLKSRC_MMIO
 	select CPU_ARM920T
 	select GPIOLIB
+	select PINCTRL
+	select PINCTRL_EP93XX
 	help
 	  This enables support for the Cirrus EP93xx series of CPUs.
 
 if ARCH_EP93XX
 
-menu "Cirrus EP93xx Implementation Options"
-
-config EP93XX_SOC_COMMON
-	bool
-	default y
-	select SOC_BUS
-	select LEDS_GPIO_REGISTER
-
-comment "EP93xx Platforms"
+# menu "EP93xx Platforms"
 
 config MACH_BK3
 	bool "Support Liebherr BK3.1"
@@ -103,6 +103,6 @@ config MACH_VISION_EP9307
 	  Say 'Y' here if you want your kernel to support the
 	  Vision Engraving Systems EP9307 SoM.
 
-endmenu
+# endmenu
 
 endif
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
deleted file mode 100644
index 62e37403df14..000000000000
--- a/arch/arm/mach-ep93xx/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the linux kernel.
-#
-obj-y			:= core.o clock.o timer-ep93xx.o
-
-obj-$(CONFIG_EP93XX_DMA)	+= dma.o
-
-obj-$(CONFIG_MACH_EDB93XX)	+= edb93xx.o
-obj-$(CONFIG_MACH_TS72XX)	+= ts72xx.o
-obj-$(CONFIG_MACH_VISION_EP9307)+= vision_ep9307.o

-- 
2.41.0



From devnull+nikita.shubin.maquefel.me at kernel.org  Sun Feb 25 23:30:30 2024
From: devnull+nikita.shubin.maquefel.me at kernel.org (Nikita Shubin via B4 Relay)
Date: Mon, 26 Feb 2024 10:30:30 +0300
Subject: [PATCH v8 34/38] ata: pata_ep93xx: remove legacy pinctrl use
In-Reply-To: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
References: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
Message-ID: <20240226-ep93xx-v8-34-3136dca7238f@maquefel.me>

From: Nikita Shubin <nikita.shubin at maquefel.me>

Drop legacy acquire/release since we are using pinctrl for this now.

Reviewed-by: Sergey Shtylyov <s.shtylyov at omp.ru>
Acked-by: Damien Le Moal <dlemoal at kernel.org>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Signed-off-by: Nikita Shubin <nikita.shubin at maquefel.me>
---
 arch/arm/mach-ep93xx/core.c       | 72 ---------------------------------------
 drivers/ata/pata_ep93xx.c         | 25 ++++----------
 include/linux/soc/cirrus/ep93xx.h |  4 ---
 3 files changed, 6 insertions(+), 95 deletions(-)

diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 4ddf1a4cba33..9c6154bb37b5 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -779,78 +779,6 @@ void __init ep93xx_register_ide(void)
 	platform_device_register(&ep93xx_ide_device);
 }
 
-int ep93xx_ide_acquire_gpio(struct platform_device *pdev)
-{
-	int err;
-	int i;
-
-	err = gpio_request(EP93XX_GPIO_LINE_EGPIO2, dev_name(&pdev->dev));
-	if (err)
-		return err;
-	err = gpio_request(EP93XX_GPIO_LINE_EGPIO15, dev_name(&pdev->dev));
-	if (err)
-		goto fail_egpio15;
-	for (i = 2; i < 8; i++) {
-		err = gpio_request(EP93XX_GPIO_LINE_E(i), dev_name(&pdev->dev));
-		if (err)
-			goto fail_gpio_e;
-	}
-	for (i = 4; i < 8; i++) {
-		err = gpio_request(EP93XX_GPIO_LINE_G(i), dev_name(&pdev->dev));
-		if (err)
-			goto fail_gpio_g;
-	}
-	for (i = 0; i < 8; i++) {
-		err = gpio_request(EP93XX_GPIO_LINE_H(i), dev_name(&pdev->dev));
-		if (err)
-			goto fail_gpio_h;
-	}
-
-	/* GPIO ports E[7:2], G[7:4] and H used by IDE */
-	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_EONIDE |
-				 EP93XX_SYSCON_DEVCFG_GONIDE |
-				 EP93XX_SYSCON_DEVCFG_HONIDE);
-	return 0;
-
-fail_gpio_h:
-	for (--i; i >= 0; --i)
-		gpio_free(EP93XX_GPIO_LINE_H(i));
-	i = 8;
-fail_gpio_g:
-	for (--i; i >= 4; --i)
-		gpio_free(EP93XX_GPIO_LINE_G(i));
-	i = 8;
-fail_gpio_e:
-	for (--i; i >= 2; --i)
-		gpio_free(EP93XX_GPIO_LINE_E(i));
-	gpio_free(EP93XX_GPIO_LINE_EGPIO15);
-fail_egpio15:
-	gpio_free(EP93XX_GPIO_LINE_EGPIO2);
-	return err;
-}
-EXPORT_SYMBOL(ep93xx_ide_acquire_gpio);
-
-void ep93xx_ide_release_gpio(struct platform_device *pdev)
-{
-	int i;
-
-	for (i = 2; i < 8; i++)
-		gpio_free(EP93XX_GPIO_LINE_E(i));
-	for (i = 4; i < 8; i++)
-		gpio_free(EP93XX_GPIO_LINE_G(i));
-	for (i = 0; i < 8; i++)
-		gpio_free(EP93XX_GPIO_LINE_H(i));
-	gpio_free(EP93XX_GPIO_LINE_EGPIO15);
-	gpio_free(EP93XX_GPIO_LINE_EGPIO2);
-
-
-	/* GPIO ports E[7:2], G[7:4] and H used by GPIO */
-	ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_EONIDE |
-			       EP93XX_SYSCON_DEVCFG_GONIDE |
-			       EP93XX_SYSCON_DEVCFG_HONIDE);
-}
-EXPORT_SYMBOL(ep93xx_ide_release_gpio);
-
 /*************************************************************************
  * EP93xx ADC
  *************************************************************************/
diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c
index 13246a92e29f..a8555f630097 100644
--- a/drivers/ata/pata_ep93xx.c
+++ b/drivers/ata/pata_ep93xx.c
@@ -922,28 +922,18 @@ static int ep93xx_pata_probe(struct platform_device *pdev)
 	void __iomem *ide_base;
 	int err;
 
-	err = ep93xx_ide_acquire_gpio(pdev);
-	if (err)
-		return err;
-
 	/* INT[3] (IRQ_EP93XX_EXT3) line connected as pull down */
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		err = irq;
-		goto err_rel_gpio;
-	}
+	if (irq < 0)
+		return irq;
 
 	ide_base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res);
-	if (IS_ERR(ide_base)) {
-		err = PTR_ERR(ide_base);
-		goto err_rel_gpio;
-	}
+	if (IS_ERR(ide_base))
+		return PTR_ERR(ide_base);
 
 	drv_data = devm_kzalloc(&pdev->dev, sizeof(*drv_data), GFP_KERNEL);
-	if (!drv_data) {
-		err = -ENOMEM;
-		goto err_rel_gpio;
-	}
+	if (!drv_data)
+		return -ENOMEM;
 
 	drv_data->pdev = pdev;
 	drv_data->ide_base = ide_base;
@@ -1002,8 +992,6 @@ static int ep93xx_pata_probe(struct platform_device *pdev)
 
 err_rel_dma:
 	ep93xx_pata_release_dma(drv_data);
-err_rel_gpio:
-	ep93xx_ide_release_gpio(pdev);
 	return err;
 }
 
@@ -1015,7 +1003,6 @@ static void ep93xx_pata_remove(struct platform_device *pdev)
 	ata_host_detach(host);
 	ep93xx_pata_release_dma(drv_data);
 	ep93xx_pata_clear_regs(drv_data->ide_base);
-	ep93xx_ide_release_gpio(pdev);
 }
 
 static const struct of_device_id ep93xx_pata_of_ids[] = {
diff --git a/include/linux/soc/cirrus/ep93xx.h b/include/linux/soc/cirrus/ep93xx.h
index f6376edc1b33..142c33a2d7db 100644
--- a/include/linux/soc/cirrus/ep93xx.h
+++ b/include/linux/soc/cirrus/ep93xx.h
@@ -37,15 +37,11 @@ struct ep93xx_regmap_adev {
 	container_of((_adev), struct ep93xx_regmap_adev, adev)
 
 #ifdef CONFIG_ARCH_EP93XX
-int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
-void ep93xx_ide_release_gpio(struct platform_device *pdev);
 int ep93xx_i2s_acquire(void);
 void ep93xx_i2s_release(void);
 unsigned int ep93xx_chip_revision(void);
 
 #else
-static inline int ep93xx_ide_acquire_gpio(struct platform_device *pdev) { return 0; }
-static inline void ep93xx_ide_release_gpio(struct platform_device *pdev) {}
 static inline int ep93xx_i2s_acquire(void) { return 0; }
 static inline void ep93xx_i2s_release(void) {}
 static inline unsigned int ep93xx_chip_revision(void) { return 0; }

-- 
2.41.0



From devnull+nikita.shubin.maquefel.me at kernel.org  Sun Feb 25 23:30:29 2024
From: devnull+nikita.shubin.maquefel.me at kernel.org (Nikita Shubin via B4 Relay)
Date: Mon, 26 Feb 2024 10:30:29 +0300
Subject: [PATCH v8 33/38] pwm: ep93xx: drop legacy pinctrl
In-Reply-To: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
References: <20240226-ep93xx-v8-0-3136dca7238f@maquefel.me>
Message-ID: <20240226-ep93xx-v8-33-3136dca7238f@maquefel.me>

From: Nikita Shubin <nikita.shubin at maquefel.me>

Drop legacy gpio request/free since we are using
pinctrl for this now.

Acked-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
Acked-by: Thierry Reding <thierry.reding at gmail.com>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Nikita Shubin <nikita.shubin at maquefel.me>
---
 arch/arm/mach-ep93xx/core.c       | 42 ---------------------------------------
 drivers/pwm/pwm-ep93xx.c          | 18 -----------------
 include/linux/soc/cirrus/ep93xx.h |  4 ----
 3 files changed, 64 deletions(-)

diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index b99c46d22c4d..4ddf1a4cba33 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -577,48 +577,6 @@ void __init ep93xx_register_pwm(int pwm0, int pwm1)
 		platform_device_register(&ep93xx_pwm1_device);
 }
 
-int ep93xx_pwm_acquire_gpio(struct platform_device *pdev)
-{
-	int err;
-
-	if (pdev->id == 0) {
-		err = 0;
-	} else if (pdev->id == 1) {
-		err = gpio_request(EP93XX_GPIO_LINE_EGPIO14,
-				   dev_name(&pdev->dev));
-		if (err)
-			return err;
-		err = gpio_direction_output(EP93XX_GPIO_LINE_EGPIO14, 0);
-		if (err)
-			goto fail;
-
-		/* PWM 1 output on EGPIO[14] */
-		ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_PONG);
-	} else {
-		err = -ENODEV;
-	}
-
-	return err;
-
-fail:
-	gpio_free(EP93XX_GPIO_LINE_EGPIO14);
-	return err;
-}
-EXPORT_SYMBOL(ep93xx_pwm_acquire_gpio);
-
-void ep93xx_pwm_release_gpio(struct platform_device *pdev)
-{
-	if (pdev->id == 1) {
-		gpio_direction_input(EP93XX_GPIO_LINE_EGPIO14);
-		gpio_free(EP93XX_GPIO_LINE_EGPIO14);
-
-		/* EGPIO[14] used for GPIO */
-		ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_PONG);
-	}
-}
-EXPORT_SYMBOL(ep93xx_pwm_release_gpio);
-
-
 /*************************************************************************
  * EP93xx video peripheral handling
  *************************************************************************/
diff --git a/drivers/pwm/pwm-ep93xx.c b/drivers/pwm/pwm-ep93xx.c
index 7cf05d0b78fb..0d17dbe10fcf 100644
--- a/drivers/pwm/pwm-ep93xx.c
+++ b/drivers/pwm/pwm-ep93xx.c
@@ -27,8 +27,6 @@
 
 #include <asm/div64.h>
 
-#include <linux/soc/cirrus/ep93xx.h>	/* for ep93xx_pwm_{acquire,release}_gpio() */
-
 #define EP93XX_PWMx_TERM_COUNT	0x00
 #define EP93XX_PWMx_DUTY_CYCLE	0x04
 #define EP93XX_PWMx_ENABLE	0x08
@@ -45,20 +43,6 @@ static inline struct ep93xx_pwm *to_ep93xx_pwm(struct pwm_chip *chip)
 	return container_of(chip, struct ep93xx_pwm, chip);
 }
 
-static int ep93xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-	struct platform_device *pdev = to_platform_device(chip->dev);
-
-	return ep93xx_pwm_acquire_gpio(pdev);
-}
-
-static void ep93xx_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-	struct platform_device *pdev = to_platform_device(chip->dev);
-
-	ep93xx_pwm_release_gpio(pdev);
-}
-
 static int ep93xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			    const struct pwm_state *state)
 {
@@ -157,8 +141,6 @@ static int ep93xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 }
 
 static const struct pwm_ops ep93xx_pwm_ops = {
-	.request = ep93xx_pwm_request,
-	.free = ep93xx_pwm_free,
 	.apply = ep93xx_pwm_apply,
 };
 
diff --git a/include/linux/soc/cirrus/ep93xx.h b/include/linux/soc/cirrus/ep93xx.h
index 8942bfaf1545..f6376edc1b33 100644
--- a/include/linux/soc/cirrus/ep93xx.h
+++ b/include/linux/soc/cirrus/ep93xx.h
@@ -37,8 +37,6 @@ struct ep93xx_regmap_adev {
 	container_of((_adev), struct ep93xx_regmap_adev, adev)
 
 #ifdef CONFIG_ARCH_EP93XX
-int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
-void ep93xx_pwm_release_gpio(struct platform_device *pdev);
 int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
 void ep93xx_ide_release_gpio(struct platform_device *pdev);
 int ep93xx_i2s_acquire(void);
@@ -46,8 +44,6 @@ void ep93xx_i2s_release(void);
 unsigned int ep93xx_chip_revision(void);
 
 #else
-static inline int ep93xx_pwm_acquire_gpio(struct platform_device *pdev) { return 0; }
-static inline void ep93xx_pwm_release_gpio(struct platform_device *pdev) {}
 static inline int ep93xx_ide_acquire_gpio(struct platform_device *pdev) { return 0; }
 static inline void ep93xx_ide_release_gpio(struct platform_device *pdev) {}
 static inline int ep93xx_i2s_acquire(void) { return 0; }

-- 
2.41.0



From ghennadi.procopciuc at oss.nxp.com  Sun Feb 25 23:33:44 2024
From: ghennadi.procopciuc at oss.nxp.com (Ghennadi Procopciuc)
Date: Mon, 26 Feb 2024 09:33:44 +0200
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <57dce440-d24b-4638-9395-62dfb03ec002@app.fastmail.com>
References: <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
 <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
 <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>
 <e6f6070e-8355-4a0b-a904-1a24970f249b@linaro.org>
 <e530d504-dfa3-4d39-b903-b2570bb8b014@suse.com>
 <c3e68c62-b81f-475b-9b15-c983c94aed8b@app.fastmail.com>
 <Zdiu8s5Cgz9s6dLP@dragon> <ZdmZ4JC0CsX2qs5C@linux-8mug>
 <57dce440-d24b-4638-9395-62dfb03ec002@app.fastmail.com>
Message-ID: <e9d061fb-c377-46a8-bd01-e661a75122a5@oss.nxp.com>

On 2/24/24 13:42, Arnd Bergmann wrote:
> On Sat, Feb 24, 2024, at 08:25, Chester Lin wrote:
>> Hi all,
>>
>> Sorry for the late reply since I lost connection with upstream due to a
>> health condition, which affected my eyesights for a while so I tried to use
>> my eyes as less as possible. Please accept my apologies anyway.
> 
> No worries, and thanks for the clarifications.
> 
>> On Fri, Feb 23, 2024 at 10:42:58PM +0800, Shawn Guo wrote:
>>> On Fri, Feb 23, 2024 at 01:29:10PM +0100, Arnd Bergmann wrote:
>>
>> Before leaving SUSE I reached NXP to see if anyone could take over it but I
>> didn't get response unfortunately. Maybe it was too rush to find a right person
>> at the moment but I still wish that someone can take over this role based on the
>> following reasons:
>>
>> - Since I have returned my S32G boards to SUSE, currently I do not have 
>> a platform
>> to verify S32G patches unless I could get a new one. I wish I could 
>> still help
>> out but hardware & doc resources will be the biggest challenge to me.
>>
>> - My current employee may have competitive relationship with NXP in automotive
>> field, which means I may not be fit in this role unless nobody cares.
> 
> In general, there no problem to just retire from a maintainer
> position or mark it as 'Odd fixes' instead of 'Maintained' when
> you are no longer planning to actively maintain it.
> 
>>>>
>>>> Added everyone there to Cc, having any s32 patches go through
>>>> the imx tree would be the easiest way as far as I'm concerned.
>>>> I've added the maintainers to Cc, let's see what they think.
>>>
>>> It's unintentional that IMX entry covers s32 dts files, as they have a
>>> dedicated entry.
>>>
>>> ARM/NXP S32G ARCHITECTURE
>>> M:      Chester Lin <chester62515 at gmail.com>
>>> R:      Andreas F?rber <afaerber at suse.de>
>>> R:      Matthias Brugger <mbrugger at suse.com>
>>> R:      NXP S32 Linux Team <s32 at nxp.com>
>>> L:      linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>>> S:      Maintained
>>> F:      arch/arm64/boot/dts/freescale/s32g*.dts*
>>>
>>> However I'm fine with collecting and sending patches through IMX tree,
>>> if S32G folks help review them.
>>>
>>
>> This looks good to me as well.

I agree, this looks good to me too.

> 
> Ok, in this case I would suggest we change this section to
> only have 'R:' entries and no 'M:' for the moment.
> 
> Between the four of you (Chester, Andreas, Matthias, Ghennadi),
> I think we can choose to keep everyone or drop those that are
> unlikely to actually review patches. Please let us know you
> would like to be included as a reviewer or not.

I would like to be included as reviewer.
Can we add Shawn as the maintainer since Chester agreed to pass on the
responsibility to him?

> 
> For the pinctrl driver, I would add the files to the "freescale"
> pinctrl entry in a similar way and end up with
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index efeaeb51f183..c1924c0053bc 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2555,13 +2555,14 @@ F:      drivers/*/*/*wpcm*
>  F:     drivers/*/*wpcm*
>  
>  ARM/NXP S32G ARCHITECTURE
> -M:     Chester Lin <chester62515 at gmail.com>
> +R:     Chester Lin <chester62515 at gmail.com>
>  R:     Andreas F?rber <afaerber at suse.de>
>  R:     Matthias Brugger <mbrugger at suse.com>
>  R:     NXP S32 Linux Team <s32 at nxp.com>
>  L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>  S:     Maintained
>  F:     arch/arm64/boot/dts/freescale/s32g*.dts*
> +F:     drivers/pinctrl/nxp/
>  
>  ARM/Orion SoC/Technologic Systems TS-78xx platform support
>  M:     Alexander Clouter <alex at digriz.org.uk>
> @@ -17415,7 +17416,9 @@ R:      Pengutronix Kernel Team <kernel at pengutronix.de>
>  L:     linux-gpio at vger.kernel.org
>  S:     Maintained
>  F:     Documentation/devicetree/bindings/pinctrl/fsl,*
> +F:     Documentation/devicetree/bindings/pinctrl/nxp,s32*
>  F:     drivers/pinctrl/freescale/
> +F:     drivers/pinctrl/nxp/

Could you please add 'L: NXP S32 Linux Team <s32 at nxp.com>', given that
this list is relevant for S32 patches ?

>  PIN CONTROLLER - INTEL
>  M:     Mika Westerberg <mika.westerberg at linux.intel.com>
> @@ -17469,14 +17472,6 @@ S:     Supported
>  F:     drivers/gpio/gpio-sama5d2-piobu.c
>  F:     drivers/pinctrl/pinctrl-at91*
>  
> -PIN CONTROLLER - NXP S32
> -M:     Chester Lin <clin at suse.com>
> -R:     NXP S32 Linux Team <s32 at nxp.com>
> -L:     linux-gpio at vger.kernel.org
> -S:     Maintained
> -F:     Documentation/devicetree/bindings/pinctrl/nxp,s32*
> -F:     drivers/pinctrl/nxp/
> -
>  PIN CONTROLLER - QUALCOMM
>  M:     Bjorn Andersson <andersson at kernel.org>
>  L:     linux-arm-msm at vger.kernel.org

Best regards,
Ghennadi



From krzysztof.kozlowski at linaro.org  Sun Feb 25 23:43:34 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 26 Feb 2024 08:43:34 +0100
Subject: [PATCH 03/13] dt-bindings: hwmon: lm75: add label property
In-Reply-To: <dcd5794b-aca6-4f6d-8e8d-f5548fcad644@roeck-us.net>
References: <20240215-mbly-i2c-v1-0-19a336e91dca@bootlin.com>
 <20240215-mbly-i2c-v1-3-19a336e91dca@bootlin.com>
 <dcd5794b-aca6-4f6d-8e8d-f5548fcad644@roeck-us.net>
Message-ID: <4978a002-d726-4fcc-9435-028923a32317@linaro.org>

On 24/02/2024 18:30, Guenter Roeck wrote:
> On Thu, Feb 15, 2024 at 05:52:10PM +0100, Th?o Lebrun wrote:
>> Declare optional label devicetree property. Show usage in one example
>> with dummy name.
>>
>> To: Jean Delvare <jdelvare at suse.com>
>> To: Guenter Roeck <linux at roeck-us.net>
>> Cc: <linux-hwmon at vger.kernel.org>
>> Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> What is the verdict here ? Should I apply it and accept another patch
> to update it, or should it be reworked to be based on the new common
> hwmon schema ?

This should be reworked based on the new common schema (just like my
follow up patches did for some of the bindings).

Best regards,
Krzysztof



From victor.liu at nxp.com  Sun Feb 25 23:45:25 2024
From: victor.liu at nxp.com (Ying Liu)
Date: Mon, 26 Feb 2024 07:45:25 +0000
Subject: [PATCH v2] drm/lcdif: Do not disable clocks on already suspended
 hardware
In-Reply-To: <20240226072904.26861-1-marex@denx.de>
References: <20240226072904.26861-1-marex@denx.de>
Message-ID: <AM7PR04MB70469590E3845F3B166C3F46985A2@AM7PR04MB7046.eurprd04.prod.outlook.com>

On Monday, February 26, 2024 3:28 PM, Marek Vasut <marex at denx.de> wrote:
> 0, and would trigger a warning from clocks core about this condition.

s/clocks/clock/

Liu Ying


From rgallaispou at gmail.com  Sun Feb 25 23:48:37 2024
From: rgallaispou at gmail.com (Raphael Gallais-Pou)
Date: Mon, 26 Feb 2024 08:48:37 +0100
Subject: [PATCH 0/2] Update st,stih407-thermal device
Message-ID: <20240226-thermal-v1-0-8b03589ece73@gmail.com>

Those two patches update the thermal device by converting the deprecated
txt documentation file to DT schema, and adding a required property in
the device tree where it is needed.

Signed-off-by: Raphael Gallais-Pou <rgallaispou at gmail.com>
---
Raphael Gallais-Pou (2):
      dt-bindings: thermal: convert st,stih407-thermal to DT schema
      ARM: dts: st: add thermal property on stih410.dtsi and stih418.dtsi

 .../bindings/thermal/st,stih407-thermal.yaml       | 61 ++++++++++++++++++++++
 .../devicetree/bindings/thermal/st-thermal.txt     | 32 ------------
 arch/arm/boot/dts/st/stih410.dtsi                  |  1 +
 arch/arm/boot/dts/st/stih418.dtsi                  |  1 +
 4 files changed, 63 insertions(+), 32 deletions(-)
---
base-commit: b6d69282db550689ab5980e06eedd23b64584a73
change-id: 20240225-thermal-8cd0ba7f452b

Best regards,
-- 
Raphael Gallais-Pou <rgallaispou at gmail.com>



From rgallaispou at gmail.com  Sun Feb 25 23:48:39 2024
From: rgallaispou at gmail.com (Raphael Gallais-Pou)
Date: Mon, 26 Feb 2024 08:48:39 +0100
Subject: [PATCH 2/2] ARM: dts: st: add thermal property on stih410.dtsi and
 stih418.dtsi
In-Reply-To: <20240226-thermal-v1-0-8b03589ece73@gmail.com>
References: <20240226-thermal-v1-0-8b03589ece73@gmail.com>
Message-ID: <20240226-thermal-v1-2-8b03589ece73@gmail.com>

"#thermal-sensor-cells" is required and missing in thermal nodes.
Add it.

Signed-off-by: Raphael Gallais-Pou <rgallaispou at gmail.com>
---
 arch/arm/boot/dts/st/stih410.dtsi | 1 +
 arch/arm/boot/dts/st/stih418.dtsi | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/st/stih410.dtsi b/arch/arm/boot/dts/st/stih410.dtsi
index 29e95e9d3229..a69231854f78 100644
--- a/arch/arm/boot/dts/st/stih410.dtsi
+++ b/arch/arm/boot/dts/st/stih410.dtsi
@@ -270,6 +270,7 @@ thermal at 91a0000 {
 			clock-names = "thermal";
 			clocks = <&clk_sysin>;
 			interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
+			#thermal-sensor-cells = <0>;
 		};
 
 		cec at 94a087c {
diff --git a/arch/arm/boot/dts/st/stih418.dtsi b/arch/arm/boot/dts/st/stih418.dtsi
index b35b9b7a7ccc..0f0db988a907 100644
--- a/arch/arm/boot/dts/st/stih418.dtsi
+++ b/arch/arm/boot/dts/st/stih418.dtsi
@@ -113,6 +113,7 @@ thermal at 91a0000 {
 			clock-names = "thermal";
 			clocks = <&clk_sysin>;
 			interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
+			#thermal-sensor-cells = <0>;
 		};
 	};
 };

-- 
2.43.2



From rgallaispou at gmail.com  Sun Feb 25 23:48:38 2024
From: rgallaispou at gmail.com (Raphael Gallais-Pou)
Date: Mon, 26 Feb 2024 08:48:38 +0100
Subject: [PATCH 1/2] dt-bindings: thermal: convert st,stih407-thermal to DT
 schema
In-Reply-To: <20240226-thermal-v1-0-8b03589ece73@gmail.com>
References: <20240226-thermal-v1-0-8b03589ece73@gmail.com>
Message-ID: <20240226-thermal-v1-1-8b03589ece73@gmail.com>

Converts st,stih407-thermal binding to DT schema format and cleans
unused property "st,passive_cooling_temp" which does not appear in the
device-tree.

Signed-off-by: Raphael Gallais-Pou <rgallaispou at gmail.com>
---
 .../bindings/thermal/st,stih407-thermal.yaml       | 61 ++++++++++++++++++++++
 .../devicetree/bindings/thermal/st-thermal.txt     | 32 ------------
 2 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/Documentation/devicetree/bindings/thermal/st,stih407-thermal.yaml b/Documentation/devicetree/bindings/thermal/st,stih407-thermal.yaml
new file mode 100644
index 000000000000..807f8d77edf5
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/st,stih407-thermal.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/st,stih407-thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STi digital thermal sensor (DTS)
+
+maintainers:
+  - Patrice Chotard <patrice.chotard at foss.st.com>
+  - Lee Jones <lee at kernel.org>
+
+description:
+  Binding for Thermal Sensor device for STMicroelectronics STi SoCs series.
+
+allOf:
+  - $ref: thermal-sensor.yaml
+
+properties:
+  compatible:
+    const: st,stih407-thermal
+
+  clocks:
+    maxItems: 1
+    description: Phandle of the clock used by the thermal sensor.
+
+  clock-names:
+    items:
+      - const: thermal
+
+  reg:
+    description:
+      For non-sysconf based sensors, this should be the physical base
+      address and length of the sensor's registers.
+
+  interrupts:
+    description: |
+      Standard way to define interrupt number.
+      For thermal sensor's for which no interrupt has been
+      defined, a polling delay of 1000ms will be used to read the
+      temperature from device.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    temp0 at 91a0000 {
+        compatible = "st,stih407-thermal";
+        reg = <0x91a0000 0x28>;
+        clock-names = "thermal";
+        clocks = <&CLK_SYSIN>;
+        interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
+        #thermal-sensor-cells = <0>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/thermal/st-thermal.txt b/Documentation/devicetree/bindings/thermal/st-thermal.txt
deleted file mode 100644
index a2f939137e35..000000000000
--- a/Documentation/devicetree/bindings/thermal/st-thermal.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-Binding for Thermal Sensor driver for STMicroelectronics STi series of SoCs.
-
-Required parameters:
--------------------
-
-compatible : 	Should be "st,stih407-thermal"
-
-clock-names : 	Should be "thermal".
-		  See: Documentation/devicetree/bindings/resource-names.txt
-clocks : 	Phandle of the clock used by the thermal sensor.
-		  See: Documentation/devicetree/bindings/clock/clock-bindings.txt
-
-Optional parameters:
--------------------
-
-reg : 		For non-sysconf based sensors, this should be the physical base
-		address and length of the sensor's registers.
-interrupts :	Standard way to define interrupt number.
-		  NB: For thermal sensor's for which no interrupt has been
-		  defined, a polling delay of 1000ms will be used to read the
-		  temperature from device.
-
-Example:
-
-	temp0 at 91a0000 {
-		compatible = "st,stih407-thermal";
-		reg = <0x91a0000 0x28>;
-		clock-names = "thermal";
-		clocks = <&CLK_SYSIN>;
-		interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
-		st,passive_cooling_temp = <110>;
-	};

-- 
2.43.2



From dan.scally at ideasonboard.com  Sun Feb 25 23:48:44 2024
From: dan.scally at ideasonboard.com (Dan Scally)
Date: Mon, 26 Feb 2024 07:48:44 +0000
Subject: [PATCH v2 4/5] media: Documentation: Add Mali-C55 ISP
 Documentation
In-Reply-To: <170889617240.914352.11519004661256637360@ping.linuxembedded.co.uk>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-5-dan.scally@ideasonboard.com>
 <170889617240.914352.11519004661256637360@ping.linuxembedded.co.uk>
Message-ID: <f99c9e34-182a-4b92-9ba4-050d6724f5e5@ideasonboard.com>

Morning Kieran

On 25/02/2024 21:22, Kieran Bingham wrote:
> Hi Dan,
>
> Quoting Daniel Scally (2024-02-14 14:19:05)
>> Add a documentation page for the mali-c55 driver, which gives a brief
>> overview of the hardware and explains how to use the driver's capture
>> devices and the crop/scaler functions.
>>
>> Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
>> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
>> ---
>> Changes in v2:
>>
>>          - none
>>
>>   .../admin-guide/media/mali-c55-graph.dot      |  19 ++
>>   Documentation/admin-guide/media/mali-c55.rst  | 318 ++++++++++++++++++
>>   .../admin-guide/media/v4l-drivers.rst         |   1 +
>>   3 files changed, 338 insertions(+)
>>   create mode 100644 Documentation/admin-guide/media/mali-c55-graph.dot
>>   create mode 100644 Documentation/admin-guide/media/mali-c55.rst
>>
>> diff --git a/Documentation/admin-guide/media/mali-c55-graph.dot b/Documentation/admin-guide/media/mali-c55-graph.dot
>> new file mode 100644
>> index 000000000000..0775ba42bf4c
>> --- /dev/null
>> +++ b/Documentation/admin-guide/media/mali-c55-graph.dot
>> @@ -0,0 +1,19 @@
>> +digraph board {
>> +        rankdir=TB
>> +        n00000001 [label="{{} | mali-c55 tpg\n/dev/v4l-subdev0 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
>> +        n00000001:port0 -> n00000003:port0 [style=dashed]
>> +        n00000003 [label="{{<port0> 0} | mali-c55 isp\n/dev/v4l-subdev1 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
>> +        n00000003:port1 -> n00000007:port0 [style=bold]
>> +        n00000003:port2 -> n00000007:port2 [style=bold]
>> +        n00000003:port1 -> n0000000b:port0 [style=bold]
>> +        n00000007 [label="{{<port0> 0 | <port2> 2} | mali-c55 resizer fr\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
>> +        n00000007:port1 -> n0000000e [style=bold]
>> +        n0000000b [label="{{<port0> 0} | mali-c55 resizer ds\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
>> +        n0000000b:port1 -> n00000012 [style=bold]
>> +        n0000000e [label="mali-c55 fr\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
>> +        n00000012 [label="mali-c55 ds\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
>> +        n00000022 [label="{{<port0> 0} | csi2-rx\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
>> +        n00000022:port1 -> n00000003:port0
>> +        n00000027 [label="{{} | imx415 1-001a\n/dev/v4l-subdev5 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
>> +        n00000027:port0 -> n00000022:port0 [style=bold]
>> +}
>> \ No newline at end of file
>> diff --git a/Documentation/admin-guide/media/mali-c55.rst b/Documentation/admin-guide/media/mali-c55.rst
>> new file mode 100644
>> index 000000000000..83f630c3bd9d
>> --- /dev/null
>> +++ b/Documentation/admin-guide/media/mali-c55.rst
>> @@ -0,0 +1,318 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +
>> +==========================================
>> +ARM Mali-C55 Image Signal Processor driver
>> +==========================================
>> +
>> +Introduction
>> +============
>> +
>> +This file documents the driver for ARM's Mali-C55 Image Signal Processor. The
>> +driver is located under drivers/media/platform/arm/mali-c55.
>> +
>> +The Mali-C55 ISP receives data in either raw Bayer format or RGB/YUV format from
>> +sensors through either a parallel interface or a memory bus before processing it
>> +and outputting it through an internal DMA engine. Two output pipelines are
>> +possible (though one may not be fitted, depending on the implementation). These
>> +are referred to as "Full resolution" and "Downscale", but the naming is historic
>> +and both pipes are capable of cropping/scaling operations. An integrated test
>> +pattern generator can be used to drive the ISP and produce image data in the
>> +absence of a connected camera sensor. The driver module is named mali_c55, and
>> +is enabled through the CONFIG_VIDEO_MALI_C55 config option.
> Can it handle metadata or other datatypes separately? anything else
> that's worthy of mention? Or maybe not yet in this version.


As in, can you stream the parameters/statistics without streaming video data? Not at present but the 
change to add that ability would be very very minor - though none of that is in this version.

>
>> +
>> +The driver implements V4L2, Media Controller and V4L2 Subdevice interfaces and
>> +expects camera sensors connected to the ISP to have V4L2 subdevice interfaces.
>> +
>> +Mali-C55 ISP hardware
>> +=====================
>> +
>> +A high level functional view of the Mali-C55 ISP is presented below. The ISP
>> +takes input from either a live source or through a DMA engine for memory input,
>> +depending on the SoC integration.::
>> +
>> +  +---------+    +----------+                                     +--------+
>> +  | Sensor  |--->| CSI-2 Rx |                "Full Resolution"    |  DMA   |
>> +  +---------+    +----------+   |\                 Output    +--->| Writer |
>> +                       |        | \                          |    +--------+
>> +                       |        |  \    +----------+  +------+---> Streaming I/O
>> +  +------------+       +------->|   |   |          |  |
>> +  |            |                |   |-->| Mali-C55 |--+
>> +  | DMA Reader |--------------->|   |   |    ISP   |  |
>> +  |            |                |  /    |          |  |      +---> Streaming I/O
>> +  +------------+                | /     +----------+  |      |
>> +                                |/                    +------+
>> +                                                            |    +--------+
>> +                                                             +--->|  DMA   |
>> +                                               "Downscaled"       | Writer |
>> +                                                 Output          +--------+
>> +
>> +Media Controller Topology
>> +=========================
>> +
>> +An example of the ISP's topology (as implemented in a system with an IMX415
>> +camera sensor and generic CSI-2 receiver) is below:
>> +
>> +
>> +.. kernel-figure:: mali-c55-graph.dot
>> +    :alt:   mali-c55-graph.dot
>> +    :align: center
>> +
>> +The driver has 4 V4L2 subdevices:
>> +
>> +- `mali_c55 isp`: Responsible for configuring input crop and color space
>> +                  conversion
>> +- `mali_c55 tpg`: The test pattern generator, emulating a camera sensor.
>> +- `mali_c55 resizer fr`: The Full-Resolution pipe resizer
>> +- `mali_c55 resizer ds`: The Downscale pipe resizer
>> +
>> +The driver has 2 V4L2 video devices:
>> +
>> +- `mali-c55 fr`: The full-resolution pipe's capture device
>> +- `mali-c55 ds`: The downscale pipe's capture device
>> +
>> +Idiosyncrasies
>> +--------------
>> +
>> +**mali-c55 isp**
>> +The `mali-c55 isp` subdevice has a single sink pad to which all sources of data
>> +should be connected. The active source is selected by enabling the appropriate
>> +media link and disabling all others.
> By that I presume you mean you can only accept a single input link at a
> time?


Yes

>
>> The ISP has two source pads, reflecting the
>> +different paths through which it can internally route data. Tap points within
>> +the ISP allow users to divert data to avoid processing by some or all of the
>> +hardware's processing steps. The diagram below is intended only to highlight how
>> +the bypassing works and is not a true reflection of those processing steps; for
>> +a high-level functional block diagram see ARM's developer page for the
>> +ISP [3]_::
>> +
>> +  +--------------------------------------------------------------+
>> +  |                Possible Internal ISP Data Routes             |
>> +  |          +------------+  +----------+  +------------+        |
>> +  +---+      |            |  |          |  |  Colour    |    +---+
>> +  | 0 |--+-->| Processing |->| Demosaic |->|   Space    |--->| 1 |
>> +  +---+  |   |            |  |          |  | Conversion |    +---+
>> +  |      |   +------------+  +----------+  +------------+        |
>> +  |      |                                                   +---+
>> +  |      +---------------------------------------------------| 2 |
>> +  |                                                          +---+
>> +  |                                                              |
>> +  +--------------------------------------------------------------+
>> +
>> +
>> +.. flat-table::
>> +    :header-rows: 1
>> +
>> +    * - Pad
>> +      - Direction
>> +      - Purpose
>> +
>> +    * - 0
>> +      - sink
>> +      - Data input, connected to the TPG and camera sensors
>> +
>> +    * - 1
>> +      - source
>> +      - RGB/YUV data, connected to the FR and DS V4L2 subdevices
>> +
>> +    * - 2
>> +      - source
>> +      - RAW bayer data, connected to the FR V4L2 subdevices
>> +
>> +**mali-c55 resizer fr**
>> +The `mali-c55 resizer fr` subdevice has two _sink_ pads to reflect the different
>> +insertion points in the hardware (either RAW or demosaiced data):
>> +
>> +.. flat-table::
>> +    :header-rows: 1
>> +
>> +    * - Pad
>> +      - Direction
>> +      - Purpose
>> +
>> +    * - 0
>> +      - sink
>> +      - Data input connected to the ISP's demosaiced stream.
>> +
>> +    * - 1
>> +      - source
>> +      - Data output connected to the capture video device
>> +
>> +    * - 2
>> +      - sink
>> +      - Data input connected to the ISP's raw data stream
>> +
>> +The data source in use is selected through the routing API; two routes each of a
>> +single stream are available:
>> +
>> +.. flat-table::
>> +    :header-rows: 1
>> +
>> +    * - Sink Pad
>> +      - Source Pad
>> +      - Purpose
>> +
>> +    * - 0
>> +      - 1
>> +      - Demosaiced data route
>> +
>> +    * - 2
>> +      - 1
>> +      - Raw data route
>> +
>> +
>> +If the demosaiced route is active then the FR pipe is only capable of output
>> +in RGB/YUV formats. If the raw route is active then the output reflects the
>> +input (which may be either Bayer or RGB/YUV data).
>> +
>> +Using the driver to capture video
>> +=================================
>> +
>> +Using the media controller APIs we can configure the input source and ISP to
>> +capture images in a variety of formats. In the examples below, configuring the
>> +media graph is done with the v4l-utils [1]_ package's media-ctl utility.
>> +Capturing the images is done with yavta [2]_.
>> +
>> +Configuring the input source
>> +----------------------------
>> +
>> +The first step is to set the input source that we wish by enabling the correct
>> +media link. Using the example topology above, we can select the TPG as follows:
>> +
>> +.. code-block:: none
>> +
>> +    media-ctl -l "'lte-csi2-rx':1->'mali-c55 isp':0[0]"
>> +    media-ctl -l "'mali-c55 tpg':0->'mali-c55 isp':0[1]"
>> +
>> +Capturing bayer data from the source and processing to RGB/YUV
>> +--------------------------------------------------------------
>> +To capture 1920x1080 bayer data from the source and push it through the ISP's
>> +full processing pipeline, we configure the data formats appropriately on the
>> +source, ISP and resizer subdevices and set the FR resizer's routing to select
>> +processed data. The media bus format on the resizer's source pad will be either
>> +RGB121212_1X36 or YUV10_1X30, depending on whether you want to capture RGB or
>> +YUV. The ISP's debayering block outputs RGB data natively, setting the source
>> +pad format to YUV10_1X30 enables the colour space conversion block.
>> +
>> +In this example we target RGB565 output, so select RGB121212_1X36 as the resizer
>> +source pad's format:
>> +
>> +.. code-block:: none
>> +
>> +    # Set formats on the TPG and ISP
>> +    media-ctl -V "'mali-c55 tpg':0[fmt:SRGGB16_1X16/1920x1080]"
>> +    media-ctl -V "'mali-c55 isp':0[fmt:SRGGB16_1X16/1920x1080]"
>> +    media-ctl -V "'mali-c55 isp':1[fmt:SRGGB16_1X16/1920x1080]"
>> +
>> +    # Set routing on the FR resizer
>> +    media-ctl -R "'mali-c55 resizer fr'[0/0->1/0[1],2/0->1/0[0]]"
>> +
>> +    # Set format on the resizer, must be done AFTER the routing.
>> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/1920x1080]"
>> +
>> +The downscale output can also be used to stream data at the same time. In this
>> +case only processed data can be captured and so no routing need be set:
> Is the route automatically reset? or is it just that the default route
> is already the correct choice for this instance?


Err, the default route is already the correct choice for this instance but I'm nonetheless setting 
it above...perhaps I'm misunderstanding the question?

>
>> +
>> +.. code-block:: none
>> +
>> +    # Set format on the resizer
>> +    media-ctl -V "'mali-c55 resizer ds':1[fmt:RGB121212_1X36/1920x1080]"
>> +
>> +Following which images can be captured from both the FR and DS output's video
>> +devices (simultaneously, if desired):
>> +
>> +.. code-block:: none
>> +
>> +    yavta -f RGB565 -s 1920x1080 -c10 /dev/video0
>> +    yavta -f RGB565 -s 1920x1080 -c10 /dev/video1
>> +
> Is there any synchronisation required? Can one pipe run without the
> other if they are both enabled? or will stalling on one pipe stall the
> other?


The outputs are synchronised already to the extent that if both are enabled they'll receive data 
from the same input frame at the same time. They can be run independently though, if an application 
stopped queuing frames to one but continued queuing to the other then the latter would work fine.

>
>> +Cropping the image
>> +~~~~~~~~~~~~~~~~~~
>> +
>> +Both the full resolution and downscale pipes can crop to a minimum resolution of
>> +640x480. To crop the image simply configure the resizer's sink pad's crop and
>> +compose rectangles and set the format on the video device:
>> +
>> +.. code-block:: none
>> +
>> +    media-ctl -V "'mali-c55 resizer fr':0[fmt:RGB121212_1X36/1920x1080 crop:(480,270)/640x480 compose:(0,0)/640x480]"
>> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/640x480]"
>> +    yavta -f RGB565 -s 640x480 -c10 /dev/video0
>> +
>> +Downscaling the image
>> +~~~~~~~~~~~~~~~~~~~~~
>> +
>> +Both the full resolution and downscale pipes can downscale the image by up to 8x
>> +provided the minimum 640x480 resolution is adhered to. For the best image result
> 'minimum 640x480 output resolution' I presume.


And input, actually.

>
> Maybe the ISP limits/restrictions need to be defined before here?


I'll expand on them yes.

>
>> +the scaling ratio for each dimension should be the same. To configure scaling we
>> +use the compose rectangle on the resizer's sink pad:
>> +
>> +.. code-block:: none
>> +
>> +    media-ctl -V "'mali-c55 resizer fr':0[fmt:RGB121212_1X36/1920x1080 crop:(0,0)/1920x1080 compose:(0,0)/640x480]"
>> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/640x480]"
>> +    yavta -f RGB565 -s 640x480 -c10 /dev/video0
>> +
>> +Capturing images in YUV formats
>> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> +
>> +If we need to output YUV data rather than RGB the color space conversion block
>> +needs to be active, which is achieved by setting MEDIA_BUS_FMT_YUV10_1X30 on the
> Is 10 bit required here? (As opposed to the 12 bit before in the
> pipeline? is that a limitation on the component?)


It's a reflection of the output from the colour-space conversion block.

> or is this to match
> the desired output format?


Sort of, it's used to inform the driver about which of the output formats can be generated - without 
conversion to YUV here only RGB formats can be set on the capture device nodes.

>
>> +resizer's source pad. We can then configure a capture format like NV12 (here in
>> +its multi-planar variant)
>> +
>> +.. code-block:: none
>> +
>> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:YUV10_1X30/1920x1080]"
>> +    yavta -f NV12M -s 1920x1080 -c10 /dev/video0
>> +
>> +Capturing RGB data from the source and processing it with the resizers
>> +----------------------------------------------------------------------
>> +
>> +The Mali-C55 ISP can work with sensors capable of outputting RGB data. In this
>> +case although none of the image quality blocks would be used it can still
>> +crop/scale the data in the usual way.
>> +
>> +To achieve this, the ISP's sink pad's format is set to
>> +MEDIA_BUS_FMT_RGB202020_1X60 - this reflects the format that data must be in to
>> +work with the ISP. Converting the camera sensor's output to that format is the
>> +responsibility of external hardware.
>> +
>> +In this example we ask the test pattern generator to give us RGB data instead of
>> +bayer.
>> +
>> +.. code-block:: none
>> +
>> +    media-ctl -V "'mali-c55 tpg':0[fmt:RGB202020_1X60/1920x1080]"
>> +    media-ctl -V "'mali-c55 isp':0[fmt:RGB202020_1X60/1920x1080]"
>> +
>> +Cropping or scaling the data can be done in exactly the same way as outlined
>> +earlier.
>> +
>> +Capturing raw data from the source and outputting it unmodified
>> +-----------------------------------------------------------------
>> +
>> +The ISP can additionally capture raw data from the source and output it on the
>> +full resolution pipe only, completely unmodified. In this case the downscale
>> +pipe can still process the data normally and be used at the same time.
>> +
>> +To configure raw bypass the FR resizer's subdevice's routing table needs to be
>> +configured, followed by formats in the appropriate places:
>> +
>> +.. code-block:: none
>> +
>> +    # We need to configure the routing table for the resizer to use the bypass
>> +    # path along with set formats on the resizer's bypass sink pad. Doing this
>> +    # necessitates a single media-ctl command, as multiple calls to the program
>> +    # reset the routing table.
>> +    media-ctl -R "'mali-c55 resizer fr'[0/0->1/0[0],2/0->1/0[1]]"\
>> +    -V "'mali-c55 isp':0[fmt:RGB202020_1X60/1920x1080],"\
>> +       "'mali-c55 resizer fr':2[fmt:RGB202020_1X60/1920x1080],"\
>> +       "'mali-c55 resizer fr':1[fmt:RGB202020_1X60/1920x1080]"
>> +
>> +    # Set format on the video device and stream
>> +    yavta -f RGB565 -s 1920x1080 -c10 /dev/video0
>> +
>> +References
>> +==========
>> +.. [1] https://git.linuxtv.org/v4l-utils.git/
>> +.. [2] https://git.ideasonboard.org/yavta.git
>> +.. [3] https://developer.arm.com/Processors/Mali-C55
>> diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentation/admin-guide/media/v4l-drivers.rst
>> index f4bb2605f07e..af033c892808 100644
>> --- a/Documentation/admin-guide/media/v4l-drivers.rst
>> +++ b/Documentation/admin-guide/media/v4l-drivers.rst
>> @@ -17,6 +17,7 @@ Video4Linux (V4L) driver-specific documentation
>>          imx7
>>          ipu3
>>          ivtv
>> +       mali-c55
>>          mgb4
>>          omap3isp
>>          omap4_camera
>> -- 
>> 2.34.1
>>


From fshao at chromium.org  Mon Feb 26 00:06:47 2024
From: fshao at chromium.org (Fei Shao)
Date: Mon, 26 Feb 2024 16:06:47 +0800
Subject: [PATCH] drm/mediatek: Support MT8195 OVL compatible in mtk_drm_drv
Message-ID: <20240226080721.3331649-1-fshao@chromium.org>

Specify the component type for mediatek,mt8195-disp-ovl in the MediaTek
DRM driver on top of commit 76cdcb87d391 ("drm/mediatek: Add MT8195 ovl
driver support").

With this, the compatible can function as an independent fallback for
other display overlays without relying on MT8192.

Signed-off-by: Fei Shao <fshao at chromium.org>
---

 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 14a1e0157cc4..703caba48420 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -739,6 +739,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8192-disp-ovl",
 	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8195-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
 	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt8192-disp-ovl-2l",
-- 
2.44.0.rc0.258.g7320e95886-goog



From u.kleine-koenig at pengutronix.de  Mon Feb 26 00:24:57 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Mon, 26 Feb 2024 09:24:57 +0100
Subject: [PATCH v4 1/2] pwm: imx27: fix race condition .apply,.get_state
In-Reply-To: <20240224112902.55539-1-Leif.Middelschulte@gmail.com>
References: <20230906154215.4ikrrbx4xgx2nmu5@pengutronix.de>
 <20240224112902.55539-1-Leif.Middelschulte@gmail.com>
Message-ID: <jm73itlefa5dmqxhe35tbzohg3vr7pog6kt7ieuiw3a2q2p6ml@ngwtwz2aawyn>

Hello Leif,

thanks for this new round addressing the identified issues.

On Sat, Feb 24, 2024 at 12:29:00PM +0100, Leif Middelschulte wrote:
> From: Leif Middelschulte <Leif.Middelschulte at klsmartin.com>
> 
> With CONFIG_PWM_DEBUG=y after writing a value to the PWMSAR
> register in .apply(), the register is read in .get_state().
> Unless a period completed in the meantime, this read yields the
> previously used duty cycle configuration. As the PWM_DEBUG code
> applies the read out configuration for testing purposes this
> effectively undoes the intended effect by rewriting the previous
> hardware state.
> 
> Note that this change merely implements a sensible heuristic.
> The i.MX has a 4 slot FIFO to configure the duty cycle. This FIFO
> cannot be read back in its entirety. The "write x then read back
> x from hw" semantics are therefore not easily applicable.
> With this change, the .get_state() function tries to wait for some
> stabilization in the FIFO (empty state). In this state it keeps
> applying the last value written to the sample register.
> 
> Signed-off-by: Leif Middelschulte <Leif.Middelschulte at klsmartin.com>
> ---
>  drivers/pwm/pwm-imx27.c | 55 +++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 53 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
> index 7d9bc43f12b0..cb564460b79c 100644
> --- a/drivers/pwm/pwm-imx27.c
> +++ b/drivers/pwm/pwm-imx27.c
> @@ -75,6 +75,7 @@
>  						   (x)) + 1)
>  
>  #define MX3_PWM_SWR_LOOP		5
> +#define MX3_PWM_FIFOAV_EMPTY_LOOP	4

This looks like a register definition, but it's only a number that
defines the iterations waiting for the FIFO to empty. (The same critic
applies to MX3_PWM_SWR_LOOP, though.)

>  /* PWMPR register value of 0xffff has the same effect as 0xfffe */
>  #define MX3_PWMPR_MAX			0xfffe
> @@ -118,6 +119,31 @@ static void pwm_imx27_clk_disable_unprepare(struct pwm_imx27_chip *imx)
>  	clk_disable_unprepare(imx->clk_ipg);
>  }
>  
> +static int pwm_imx27_wait_fifo_empty(struct pwm_chip *chip,
> +				     struct pwm_device *pwm)
> +{
> +	struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
> +	struct device *dev = chip->dev;
> +	unsigned int period_ms = DIV_ROUND_UP_ULL(pwm->state.period, NSEC_PER_MSEC);

Given that waiting here is unfortunate it would be nice so reduce the
waiting as much as possible. So it might make sense to read the actual
period from the hardware and use that as it might be smaller that
pwm->state.period.

> +	int tries = MX3_PWM_FIFOAV_EMPTY_LOOP;
> +	int fifoav, previous_fifoav = INT_MAX;
> +	u32 sr;

Most variables can go into the while loop.

> +	while (tries--) {
> +		sr = readl(imx->mmio_base + MX3_PWMSR);
> +		fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr);
> +		if (fifoav == MX3_PWMSR_FIFOAV_EMPTY)
> +			return 0;
> +		/* if the FIFO value does not decrease, there is another problem */
> +		if (previous_fifoav == fifoav)
> +			break;
> +		previous_fifoav = fifoav;
> +		msleep(period_ms);
> +	}

I wonder if a loop is necessary at all. Why not use
msleep(FIELD_GET(MX3_PWMSR_FIFOAV, sr) * period_ms)?

Maybe take PWMCNR into account to shorten the sleep a bit.

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/20240226/970f6b61/attachment.sig>

From marex at denx.de  Mon Feb 26 00:26:27 2024
From: marex at denx.de (Marek Vasut)
Date: Mon, 26 Feb 2024 09:26:27 +0100
Subject: [PATCH v3] drm/lcdif: Do not disable clocks on already suspended hardware
Message-ID: <20240226082644.32603-1-marex@denx.de>

In case the LCDIF is enabled in DT but unused, the clocks used by the
LCDIF are not enabled. Those clocks may even have a use count of 0 in
case there are no other users of those clocks. This can happen e.g. in
case the LCDIF drives HDMI bridge which has no panel plugged into the
HDMI connector.

Do not attempt to disable clocks in the suspend callback and re-enable
clocks in the resume callback unless the LCDIF is enabled and was in
use before the system entered suspend, otherwise the driver might end
up trying to disable clocks which are already disabled with use count
0, and would trigger a warning from clock core about this condition.

Note that the lcdif_rpm_suspend() and lcdif_rpm_resume() functions
internally perform the clocks disable and enable operations and act
as runtime PM hooks too.

Reviewed-by: Liu Ying <victor.liu at nxp.com>
Fixes: 9db35bb349a0 ("drm: lcdif: Add support for i.MX8MP LCDIF variant")
Signed-off-by: Marek Vasut <marex at denx.de>
---
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: David Airlie <airlied at gmail.com>
Cc: Fabio Estevam <festevam at gmail.com>
Cc: Liu Ying <victor.liu at nxp.com>
Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
Cc: Sascha Hauer <s.hauer at pengutronix.de>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Stefan Agner <stefan at agner.ch>
Cc: Thomas Zimmermann <tzimmermann at suse.de>
Cc: dri-devel at lists.freedesktop.org
Cc: linux-arm-kernel at lists.infradead.org
---
V2: - s at clock@clocks at g in commit message
    - Add RB from Liu
V3: - Replace clocks core with clock core
---
 drivers/gpu/drm/mxsfb/lcdif_drv.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdif_drv.c
index 18de2f17e2491..6494e82707569 100644
--- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
+++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
@@ -340,6 +340,9 @@ static int __maybe_unused lcdif_suspend(struct device *dev)
 	if (ret)
 		return ret;
 
+	if (pm_runtime_suspended(dev))
+		return 0;
+
 	return lcdif_rpm_suspend(dev);
 }
 
@@ -347,7 +350,8 @@ static int __maybe_unused lcdif_resume(struct device *dev)
 {
 	struct drm_device *drm = dev_get_drvdata(dev);
 
-	lcdif_rpm_resume(dev);
+	if (!pm_runtime_suspended(dev))
+		lcdif_rpm_resume(dev);
 
 	return drm_mode_config_helper_resume(drm);
 }
-- 
2.43.0



From misono.tomohiro at fujitsu.com  Mon Feb 26 00:30:50 2024
From: misono.tomohiro at fujitsu.com (Tomohiro Misono (Fujitsu))
Date: Mon, 26 Feb 2024 08:30:50 +0000
Subject: [PATCH v4 6/8] cpuidle-haltpoll: ARM64 support
In-Reply-To: <1707982910-27680-7-git-send-email-mihai.carabas@oracle.com>
References: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
 <1707982910-27680-7-git-send-email-mihai.carabas@oracle.com>
Message-ID: <TY2PR01MB4330E33D15DEE3DE33794B6FE55A2@TY2PR01MB4330.jpnprd01.prod.outlook.com>

Hi,
> Subject: [PATCH v4 6/8] cpuidle-haltpoll: ARM64 support
> 
> From: Joao Martins <joao.m.martins at oracle.com>
> 
> To test whether it's a guest or not for the default cases, the haltpoll
> driver uses the kvm_para* helpers to find out if it's a guest or not.
> 
> ARM64 doesn't have or defined any of these, so it remains disabled on
> the default. Although it allows to be force-loaded.
> 
> Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
> Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
> ---
>  drivers/cpuidle/Kconfig | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
> index cac5997dca50..067927eda466 100644
> --- a/drivers/cpuidle/Kconfig
> +++ b/drivers/cpuidle/Kconfig
> @@ -35,7 +35,7 @@ config CPU_IDLE_GOV_TEO
> 
>  config CPU_IDLE_GOV_HALTPOLL
>  	bool "Haltpoll governor (for virtualized systems)"
> -	depends on KVM_GUEST
> +	depends on (X86 && KVM_GUEST) || ARM64
>  	help
>  	  This governor implements haltpoll idle state selection, to be
>  	  used in conjunction with the haltpoll cpuidle driver, allowing
> @@ -73,7 +73,7 @@ endmenu
> 
>  config HALTPOLL_CPUIDLE
>  	tristate "Halt poll cpuidle driver"

I noticed that to build as a module, arch_cpu_idle needs to
be exported in arch/arm64/kernel/idle.c like x86.

Regards,
Tomohiro

> -	depends on X86 && KVM_GUEST
> +	depends on (X86 && KVM_GUEST) || ARM64
>  	select CPU_IDLE_GOV_HALTPOLL
>  	default y
>  	help
> --
> 1.8.3.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From miquel.raynal at bootlin.com  Mon Feb 26 00:36:32 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 09:36:32 +0100
Subject: [PATCH v6 12/13] mtd: rawnand: brcmnand: Add support for
 getting ecc setting from strap
In-Reply-To: <db1c1e68-40e2-4c6c-afb2-2fb591883a46@broadcom.com>
References: <20240223034758.13753-1-william.zhang@broadcom.com>
	<20240223034758.13753-13-william.zhang@broadcom.com>
	<20240223101852.005da3ad@xps-13>
	<db1c1e68-40e2-4c6c-afb2-2fb591883a46@broadcom.com>
Message-ID: <20240226093632.089d594c@xps-13>

Hi William,

william.zhang at broadcom.com wrote on Fri, 23 Feb 2024 09:25:09 -0800:

> Hi Miquel,
> 
> On 2/23/24 01:18, Miquel Raynal wrote:
> > Hi William,
> > 
> > william.zhang at broadcom.com wrote on Thu, 22 Feb 2024 19:47:57 -0800:
> >   
> >> BCMBCA broadband SoC based board design does not specify ecc setting in
> >> dts but rather use the SoC NAND strap info to obtain the ecc strength
> >> and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
> >> this purpose and update driver to support this option. However these two
> >> options can not be used at the same time.
> >>
> >> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> >> Reviewed-by: David Regan <dregan at broadcom.com>
> >>  
> > 
> > FYI I did not receive patches 7, 8, 9, which makes the series numbering
> > very odd.
> >   
> I was using the get maintainer script mainly and it sends to the linux MTD list.  I will add your email directly next time.

Yes, I prefer to be in Cc of the whole series, please.

> >> ---
> >>
> >> Changes in v6:
> >> - Combine the ecc step size and ecc strength into one get function
> >> - Treat it as error condition if both brcm,nand-ecc-use-strap and nand
> >> ecc dts properties are set
> >> - Add intermediate steps to get the sector size bitfield
> >>
> >> Changes in v5: None
> >> Changes in v4:
> >> - Update the comments for ecc setting selection
> >>
> >> Changes in v3: None
> >> Changes in v2:
> >> - Minor cosmetic fixes
> >>
> >>   drivers/mtd/nand/raw/brcmnand/brcmnand.c | 83 ++++++++++++++++++++++--
> >>   1 file changed, 77 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> >> index ef7d340475be..e8ffc283b365 100644
> >> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> >> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> >> @@ -1038,6 +1038,22 @@ static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl)
> >>   		return -1;
> >>   }  
> >>   >> +static int brcmnand_get_sector_size_1k(struct brcmnand_host *host)  
> >> +{
> >> +	struct brcmnand_controller *ctrl = host->ctrl;
> >> +	int sector_size_bit = brcmnand_sector_1k_shift(ctrl);
> >> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> >> +						  BRCMNAND_CS_ACC_CONTROL);
> >> +	u32 acc_control;
> >> +
> >> +	if (sector_size_bit < 0)
> >> +		return 0;
> >> +
> >> +	acc_control = nand_readreg(ctrl, acc_control_offs);
> >> +
> >> +	return (acc_control & BIT(sector_size_bit)) >> sector_size_bit;  
> > 
> > FIELD_PREP, FIELD_GET, *please*.  
> You probably missed my reply to your comments on the same patch in v5. Here is the link for the post in case it lost in your email:
> https://lore.kernel.org/lkml/c145b90c-e9f0-4d82-94cc-baf7bfda5954 at gmail.com/T/#m1d911d2f119f3bd345c575a81b60bc2bd8c461eb

I didn't miss it, but the reason does not sound legitimate to me.
Please work on it, it will be so much cleaner.

> The mask is not constant here and cause build errors.
> >   
> >> +}
> >> +
> >>   static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
> >>   {
> >>   	struct brcmnand_controller *ctrl = host->ctrl;
> >> @@ -1055,6 +1071,43 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
> >>   	nand_writereg(ctrl, acc_control_offs, tmp);
> >>   }  
> >>   >> +static int brcmnand_get_spare_size(struct brcmnand_host *host)  
> >> +{
> >> +	struct brcmnand_controller *ctrl = host->ctrl;
> >> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> >> +						  BRCMNAND_CS_ACC_CONTROL);
> >> +	u32 acc = nand_readreg(ctrl, acc_control_offs);
> >> +
> >> +	return (acc & brcmnand_spare_area_mask(ctrl));
> >> +}
> >> +
> >> +static void brcmnand_get_ecc_settings(struct brcmnand_host *host, struct nand_chip *chip)
> >> +{
> >> +	struct brcmnand_controller *ctrl = host->ctrl;
> >> +	u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> >> +						  BRCMNAND_CS_ACC_CONTROL);
> >> +	int sector_size_1k = brcmnand_get_sector_size_1k(host);
> >> +	int spare_area_size, ecc_level;
> >> +	u32 acc;
> >> +
> >> +	spare_area_size = brcmnand_get_spare_size(host);
> >> +	acc = nand_readreg(ctrl, acc_control_offs);
> >> +	ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl->ecc_level_shift;  
> > 
> > ditto
> >   
> >> +	if (sector_size_1k)
> >> +		chip->ecc.strength = ecc_level * 2;
> >> +	else if (spare_area_size == 16 && ecc_level == 15)
> >> +		chip->ecc.strength = 1; /* hamming */
> >> +	else
> >> +		chip->ecc.strength = ecc_level;
> >> +
> >> +	if (chip->ecc.size == 0) {
> >> +		if (sector_size_1k < 0)  
> > 
> > Should be <= 0 I guess
> >   
> >> +			chip->ecc.size = 512;
> >> +		else
> >> +			chip->ecc.size = 512 << sector_size_1k;  
> > 
> > What is this? Are you expecting sector_size_1k to be 0 or 1
> > and thus multiply 512 by two?
> >   
> Explained in the same post above. Sector_size_1k can be negative number for error condition where we default to 512 step size. Otherwise 0 for 512 and 1 for 1K which the above shift takes care of.

The logic is unclear, unnatural. Please simplify. You have the
possibility to change all the driver, so please simplify and clarify
the logic.

> > Please just use:
> > 			chip->ecc.size = SZ_1K;
> > 			  

Thanks,
Miqu?l


From misono.tomohiro at fujitsu.com  Mon Feb 26 00:36:34 2024
From: misono.tomohiro at fujitsu.com (Tomohiro Misono (Fujitsu))
Date: Mon, 26 Feb 2024 08:36:34 +0000
Subject: [PATCH v4 7/8] cpuidle/poll_state: replace cpu_relax with
 smp_cond_load_relaxed
In-Reply-To: <1707982910-27680-8-git-send-email-mihai.carabas@oracle.com>
References: <1707982910-27680-1-git-send-email-mihai.carabas@oracle.com>
 <1707982910-27680-8-git-send-email-mihai.carabas@oracle.com>
Message-ID: <TY2PR01MB4330F7FF122BBF12EC0ADE06E55A2@TY2PR01MB4330.jpnprd01.prod.outlook.com>

Hi,
> Subject: [PATCH v4 7/8] cpuidle/poll_state: replace cpu_relax with smp_cond_load_relaxed
> 
> cpu_relax on ARM64 does a simple "yield". Thus we replace it with
> smp_cond_load_relaxed which basically does a "wfe".
> 
> Suggested-by: Peter Zijlstra <peterz at infradead.org>
> Signed-off-by: Mihai Carabas <mihai.carabas at oracle.com>
> ---
>  drivers/cpuidle/poll_state.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c
> index 9b6d90a72601..1e45be906e72 100644
> --- a/drivers/cpuidle/poll_state.c
> +++ b/drivers/cpuidle/poll_state.c
> @@ -13,6 +13,7 @@
>  static int __cpuidle poll_idle(struct cpuidle_device *dev,
>  			       struct cpuidle_driver *drv, int index)
>  {
> +	unsigned long ret;
>  	u64 time_start;
> 
>  	time_start = local_clock_noinstr();
> @@ -26,12 +27,16 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev,
> 
>  		limit = cpuidle_poll_time(drv, dev);
> 
> -		while (!need_resched()) {
> -			cpu_relax();
> -			if (loop_count++ < POLL_IDLE_RELAX_COUNT)
> -				continue;
> -
> +		for (;;) {
>  			loop_count = 0;
> +
> +			ret = smp_cond_load_relaxed(&current_thread_info()->flags,
> +						    VAL & _TIF_NEED_RESCHED ||
> +						    loop_count++ >= POLL_IDLE_RELAX_COUNT);
> +
> +			if (!(ret & _TIF_NEED_RESCHED))
> +				break;

Should this be "if (ret & _TIF_NEED_RESCHED) since we want to break here
if the flag is set, or am I misunderstood?

Regards,
Tomohiro

> +
>  			if (local_clock_noinstr() - time_start > limit) {
>  				dev->poll_time_limit = true;
>  				break;
> --
> 1.8.3.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From u.kleine-koenig at pengutronix.de  Mon Feb 26 00:37:51 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Mon, 26 Feb 2024 09:37:51 +0100
Subject: [PATCH v4 2/2] pwm: imx27: avoid PWM consumer API
In-Reply-To: <20240224112902.55539-2-Leif.Middelschulte@gmail.com>
References: <20230906154215.4ikrrbx4xgx2nmu5@pengutronix.de>
 <20240224112902.55539-1-Leif.Middelschulte@gmail.com>
 <20240224112902.55539-2-Leif.Middelschulte@gmail.com>
Message-ID: <ls4rsrc5qgdz6m3663aussioibzgr4uqauh5lene2rgod5inad@d7kme4d73xi2>

Hello Leif,

On Sat, Feb 24, 2024 at 12:29:01PM +0100, Leif Middelschulte wrote:
> diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
> index cb564460b79c..d00d79a5edb1 100644
> --- a/drivers/pwm/pwm-imx27.c
> +++ b/drivers/pwm/pwm-imx27.c
> @@ -255,7 +255,7 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
>  	sr = readl(imx->mmio_base + MX3_PWMSR);
>  	fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr);
>  	if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) {
> -		period_ms = DIV_ROUND_UP_ULL(pwm_get_period(pwm),
> +		period_ms = DIV_ROUND_UP_ULL(pwm->state.period,
>  					 NSEC_PER_MSEC);
>  		msleep(period_ms);

This doesn't apply anymore on top of pwm/for-next. See commit
1706175c682fdb3fbe0b70d50b137aaa270959db which includes this change (and
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/20240226/a7c5a17c/attachment-0001.sig>

From wsa at kernel.org  Mon Feb 26 00:41:58 2024
From: wsa at kernel.org (Wolfram Sang)
Date: Mon, 26 Feb 2024 09:41:58 +0100
Subject: [PATCH 01/13] dt-bindings: i2c: nomadik: add timeout-usecs
 property bindings
In-Reply-To: <CAL_JsqLk3UbrXAymTvLQeeS-ACY7makTVYxa9CetO-G-v3TuqA@mail.gmail.com>
References: <20240215-mbly-i2c-v1-1-19a336e91dca@bootlin.com>
 <20240216022704.GB850600-robh@kernel.org>
 <CZ6E24VPJKJG.35LACFD6ZV5KE@bootlin.com>
 <CACRpkdZZhhzg5SY7U5dv_OfLEVejRFom4V9nCfkQXunAw1ZXSw@mail.gmail.com>
 <CZ94LGRSF9KN.15ZO1VRMIQVR8@bootlin.com>
 <CZAX02IL1N1J.2GQR9D73GLRZB@bootlin.com>
 <ZdY2WzKbElloXC4-@shikoro>
 <20240222171404.GA3334332-robh@kernel.org>
 <ZdegTjJpDJGEgdvo@shikoro>
 <CAL_JsqLk3UbrXAymTvLQeeS-ACY7makTVYxa9CetO-G-v3TuqA@mail.gmail.com>
Message-ID: <ZdxO1l408x7kMwsB@shikoro>

Hi Rob,

> I'll try to make sure you see any future i2c changes.

Thanks, if you mention @wsakernel I should get notified.

I looked into watching specific directories in Github and I found the
CODEOWNERS file. But code owners need to have write permissions and I
am not sure this is worth the hazzle.

Now on to checking that remaining binding...

   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/20240226/0f74b2d2/attachment.sig>

From u.kleine-koenig at pengutronix.de  Mon Feb 26 00:44:16 2024
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Mon, 26 Feb 2024 09:44:16 +0100
Subject: [PATCH v4 1/2] pwm: imx27: fix race condition .apply,.get_state
In-Reply-To: <20240224112902.55539-1-Leif.Middelschulte@gmail.com>
References: <20230906154215.4ikrrbx4xgx2nmu5@pengutronix.de>
 <20240224112902.55539-1-Leif.Middelschulte@gmail.com>
Message-ID: <qucbpwau55tuaf5m5fqpsbub2bbtxcye4djxwrwkabssd2vc4j@weuiawrzbbnn>

Hello,

On Sat, Feb 24, 2024 at 12:29:00PM +0100, Leif Middelschulte wrote:
> From: Leif Middelschulte <Leif.Middelschulte at klsmartin.com>
> 
> With CONFIG_PWM_DEBUG=y after writing a value to the PWMSAR
> register in .apply(), the register is read in .get_state().
> Unless a period completed in the meantime, this read yields the
> previously used duty cycle configuration. As the PWM_DEBUG code
> applies the read out configuration for testing purposes this
> effectively undoes the intended effect by rewriting the previous
> hardware state.
> 
> Note that this change merely implements a sensible heuristic.
> The i.MX has a 4 slot FIFO to configure the duty cycle. This FIFO
> cannot be read back in its entirety. The "write x then read back
> x from hw" semantics are therefore not easily applicable.
> With this change, the .get_state() function tries to wait for some
> stabilization in the FIFO (empty state). In this state it keeps
> applying the last value written to the sample register.
> 
> Signed-off-by: Leif Middelschulte <Leif.Middelschulte at klsmartin.com>

Another few things I noticed only after replying to this patch and
trying to apply #2:

 - Please make sure you have a S-o-b line for the sender (i.e. you with
   your gmail identity).
 - My reply to your klsmartin.com address couldn't be delivered, The MS
   mailserver told: "leif.middelschulte wasn't found at klsmartin.com."
 - Please start a new thread if you send a v5, as applying patches from
   a thread containing many patches is a bit less trivial.
 - Consider using git format-patch's --base parameter to document your
   patch base.

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/20240226/d1a2fa2c/attachment.sig>

From michal.simek at amd.com  Mon Feb 26 00:45:11 2024
From: michal.simek at amd.com (Michal Simek)
Date: Mon, 26 Feb 2024 09:45:11 +0100
Subject: [PATCH] clk: clocking-wizard: Remove redundant initialization of
 pointer div_addr
In-Reply-To: <20240223134347.3908301-1-colin.i.king@gmail.com>
References: <20240223134347.3908301-1-colin.i.king@gmail.com>
Message-ID: <fe89c82c-18e8-4acf-97c7-a319f20c26f4@amd.com>



On 2/23/24 14:43, Colin Ian King wrote:
> The pointer div_addr is being assigned a value that is never used, it is
> being re-assigned a different value near the end of the function where
> it is being read in the next statement. The initialization is redundant
> and can be removed.
> 
> Cleans up clang scan build warning:
> drivers/clk/xilinx/clk-xlnx-clock-wizard.c:501:16: warning: Value stored
> to 'div_addr' during its initialization is never read [deadcode.DeadStores]
> 
> Signed-off-by: Colin Ian King <colin.i.king at gmail.com>
> ---
>   drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
> index 6a6e5d9292e8..19eb3fb7ae31 100644
> --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
> +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
> @@ -498,7 +498,7 @@ static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
>   {
>   	struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
>   	unsigned long vco_freq, rate_div, clockout0_div;
> -	void __iomem *div_addr = divider->base;
> +	void __iomem *div_addr;
>   	u32 reg, pre, f;
>   	int err;
>   

Reviewed-by: Michal Simek <michal.simek at amd.com>

Thanks,
Michal


From shawn.sung at mediatek.com  Mon Feb 26 00:50:48 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:48 +0800
Subject: [PATCH 00/11] Rename mtk_drm_* to mtk_*
Message-ID: <20240226085059.26850-1-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename some unnecessary  "mtk_drm_*" to "mtk_*" because:
- Lower the matches when searching the native drm_* codes
- Reduce the code

Hsiao Chien Sung (11):
  drm/mediatek: Rename "mtk_drm_crtc" to "mtk_crtc"
  drm/mediatek: Rename "mtk_drm_ddp_comp" to "mtk_ddp_comp"
  drm/mediatek: Rename "mtk_drm_plane" to "mtk_plane"
  drm/mediatek: Rename "mtk_drm_gem" to "mtk_gem"
  drm/mediatek: Rename "mtk_drm_hdmi" to "mtk_hdmi"
  drm/mediatek: Rename files "mtk_drm_crtc.*" to "mtk_crtc.*"
  drm/mediatek: Rename files "mtk_drm_ddp_comp.*" to "mtk_ddp_comp.*"
  drm/mediatek: Rename files "mtk_drm_plane.*" to "mtk_plane.*"
  drm/mediatek: Rename files "mtk_drm_gem.*" to "mtk_gem.*"
  drm/mediatek: Rename mtk_ddp_comp functions
  drm/mediatek: Rename "pending_needs_vblank" to "needs_vblank"

 drivers/gpu/drm/mediatek/Makefile             |   8 +-
 .../mediatek/{mtk_drm_crtc.c => mtk_crtc.c}   | 218 +++++++++---------
 drivers/gpu/drm/mediatek/mtk_crtc.h           |  30 +++
 .../{mtk_drm_ddp_comp.c => mtk_ddp_comp.c}    |  51 ++--
 .../{mtk_drm_ddp_comp.h => mtk_ddp_comp.h}    |   9 +-
 drivers/gpu/drm/mediatek/mtk_disp_aal.c       |   4 +-
 drivers/gpu/drm/mediatek/mtk_disp_ccorr.c     |   4 +-
 drivers/gpu/drm/mediatek/mtk_disp_color.c     |   4 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   2 +-
 drivers/gpu/drm/mediatek/mtk_disp_gamma.c     |   4 +-
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     |   2 +-
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c       |   4 +-
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   |   4 +-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c      |   4 +-
 drivers/gpu/drm/mediatek/mtk_dpi.c            |   4 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h       |  30 ---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  32 +--
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   4 +-
 drivers/gpu/drm/mediatek/mtk_dsi.c            |   6 +-
 drivers/gpu/drm/mediatek/mtk_ethdr.c          |   4 +-
 .../drm/mediatek/{mtk_drm_gem.c => mtk_gem.c} |  65 +++---
 .../drm/mediatek/{mtk_drm_gem.h => mtk_gem.h} |  19 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c           |  14 +-
 drivers/gpu/drm/mediatek/mtk_padding.c        |   4 +-
 .../mediatek/{mtk_drm_plane.c => mtk_plane.c} |  26 +--
 .../mediatek/{mtk_drm_plane.h => mtk_plane.h} |   4 +-
 26 files changed, 277 insertions(+), 283 deletions(-)
 rename drivers/gpu/drm/mediatek/{mtk_drm_crtc.c => mtk_crtc.c} (82%)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_crtc.h
 rename drivers/gpu/drm/mediatek/{mtk_drm_ddp_comp.c => mtk_ddp_comp.c} (94%)
 rename drivers/gpu/drm/mediatek/{mtk_drm_ddp_comp.h => mtk_ddp_comp.h} (98%)
 delete mode 100644 drivers/gpu/drm/mediatek/mtk_drm_crtc.h
 rename drivers/gpu/drm/mediatek/{mtk_drm_gem.c => mtk_gem.c} (76%)
 rename drivers/gpu/drm/mediatek/{mtk_drm_gem.h => mtk_gem.h} (65%)
 rename drivers/gpu/drm/mediatek/{mtk_drm_plane.c => mtk_plane.c} (94%)
 rename drivers/gpu/drm/mediatek/{mtk_drm_plane.h => mtk_plane.h} (95%)

--
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:58 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:58 +0800
Subject: [PATCH 10/11] drm/mediatek: Rename mtk_ddp_comp functions
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-11-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename functions of mtk_ddp_comp:
- To align the naming rule
- To reduce the code size

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 45 ++++++++++++++-----------
 drivers/gpu/drm/mediatek/mtk_ddp_comp.h |  3 +-
 drivers/gpu/drm/mediatek/mtk_dpi.c      |  2 +-
 drivers/gpu/drm/mediatek/mtk_dsi.c      |  2 +-
 4 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
index ab846a9f98c5..f6d482d27c63 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
@@ -497,10 +497,10 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX]
 	[DDP_COMPONENT_WDMA1]		= { MTK_DISP_WDMA,		1, NULL },
 };
 
-static bool mtk_drm_find_comp_in_ddp(struct device *dev,
-				     const unsigned int *path,
-				     unsigned int path_len,
-				     struct mtk_ddp_comp *ddp_comp)
+static bool mtk_ddp_comp_find(struct device *dev,
+			      const unsigned int *path,
+			      unsigned int path_len,
+			      struct mtk_ddp_comp *ddp_comp)
 {
 	unsigned int i;
 
@@ -514,10 +514,10 @@ static bool mtk_drm_find_comp_in_ddp(struct device *dev,
 	return false;
 }
 
-static unsigned int mtk_drm_find_comp_in_ddp_conn_path(struct device *dev,
-						       const struct mtk_drm_route *routes,
-						       unsigned int num_routes,
-						       struct mtk_ddp_comp *ddp_comp)
+static unsigned int mtk_ddp_comp_find_in_route(struct device *dev,
+					       const struct mtk_drm_route *routes,
+					       unsigned int num_routes,
+					       struct mtk_ddp_comp *ddp_comp)
 {
 	int ret;
 	unsigned int i;
@@ -554,26 +554,31 @@ int mtk_ddp_comp_get_id(struct device_node *node,
 	return -EINVAL;
 }
 
-unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
-						struct device *dev)
+unsigned int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev)
 {
 	struct mtk_drm_private *private = drm->dev_private;
 	unsigned int ret = 0;
 
-	if (mtk_drm_find_comp_in_ddp(dev, private->data->main_path, private->data->main_len,
-				     private->ddp_comp))
+	if (mtk_ddp_comp_find(dev,
+			      private->data->main_path,
+			      private->data->main_len,
+			      private->ddp_comp))
 		ret = BIT(0);
-	else if (mtk_drm_find_comp_in_ddp(dev, private->data->ext_path,
-					  private->data->ext_len, private->ddp_comp))
+	else if (mtk_ddp_comp_find(dev,
+				   private->data->ext_path,
+				   private->data->ext_len,
+				   private->ddp_comp))
 		ret = BIT(1);
-	else if (mtk_drm_find_comp_in_ddp(dev, private->data->third_path,
-					  private->data->third_len, private->ddp_comp))
+	else if (mtk_ddp_comp_find(dev,
+				   private->data->third_path,
+				   private->data->third_len,
+				   private->ddp_comp))
 		ret = BIT(2);
 	else
-		ret = mtk_drm_find_comp_in_ddp_conn_path(dev,
-							 private->data->conn_routes,
-							 private->data->num_conn_routes,
-							 private->ddp_comp);
+		ret = mtk_ddp_comp_find_in_route(dev,
+						 private->data->conn_routes,
+						 private->data->num_conn_routes,
+						 private->ddp_comp);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
index ba985206fdd2..26236691ce4c 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
@@ -326,8 +326,7 @@ static inline void mtk_ddp_comp_encoder_index_set(struct mtk_ddp_comp *comp)
 
 int mtk_ddp_comp_get_id(struct device_node *node,
 			enum mtk_ddp_comp_type comp_type);
-unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
-						struct device *dev);
+unsigned int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev);
 int mtk_ddp_comp_init(struct device_node *comp_node, struct mtk_ddp_comp *comp,
 		      unsigned int comp_id);
 enum mtk_ddp_comp_type mtk_ddp_comp_get_type(unsigned int comp_id);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 84745ec9dd7c..0c83a4400088 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -805,7 +805,7 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
 		return ret;
 	}
 
-	dpi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->dev);
+	dpi->encoder.possible_crtcs = mtk_find_possible_crtcs(drm_dev, dpi->dev);
 
 	ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL,
 				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index a9071c4dce0e..811b7305668f 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -836,7 +836,7 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
 		return ret;
 	}
 
-	dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
+	dsi->encoder.possible_crtcs = mtk_find_possible_crtcs(drm, dsi->host.dev);
 
 	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
 				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
-- 
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:55 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:55 +0800
Subject: [PATCH 07/11] drm/mediatek: Rename files "mtk_drm_ddp_comp.*" to "mtk_ddp_comp.*"
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-8-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename files mtk_drm_ddp_comp.* to mtk_ddp_comp.*.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/Makefile                               | 2 +-
 drivers/gpu/drm/mediatek/mtk_crtc.c                             | 2 +-
 drivers/gpu/drm/mediatek/mtk_crtc.h                             | 2 +-
 drivers/gpu/drm/mediatek/{mtk_drm_ddp_comp.c => mtk_ddp_comp.c} | 2 +-
 drivers/gpu/drm/mediatek/{mtk_drm_ddp_comp.h => mtk_ddp_comp.h} | 0
 drivers/gpu/drm/mediatek/mtk_disp_aal.c                         | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_ccorr.c                       | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_color.c                       | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_gamma.c                       | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_merge.c                       | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c                         | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c                 | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c                        | 2 +-
 drivers/gpu/drm/mediatek/mtk_dpi.c                              | 2 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c                          | 2 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h                          | 2 +-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c                        | 2 +-
 drivers/gpu/drm/mediatek/mtk_dsi.c                              | 2 +-
 drivers/gpu/drm/mediatek/mtk_ethdr.c                            | 2 +-
 drivers/gpu/drm/mediatek/mtk_padding.c                          | 2 +-
 20 files changed, 19 insertions(+), 19 deletions(-)
 rename drivers/gpu/drm/mediatek/{mtk_drm_ddp_comp.c => mtk_ddp_comp.c} (99%)
 rename drivers/gpu/drm/mediatek/{mtk_drm_ddp_comp.h => mtk_ddp_comp.h} (100%)

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index edad718082a9..bbdf1e59ed84 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -9,7 +9,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_disp_ovl_adaptor.o \
 		  mtk_disp_rdma.o \
 		  mtk_crtc.o \
-		  mtk_drm_ddp_comp.o \
+		  mtk_ddp_comp.o \
 		  mtk_drm_drv.o \
 		  mtk_drm_gem.o \
 		  mtk_drm_plane.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
index 503bdcd7e596..7bc4f76718e5 100644
--- a/drivers/gpu/drm/mediatek/mtk_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
@@ -21,7 +21,7 @@
 
 #include "mtk_drm_drv.h"
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_gem.h"
 #include "mtk_drm_plane.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.h b/drivers/gpu/drm/mediatek/mtk_crtc.h
index f081c54a349b..5865e4955471 100644
--- a/drivers/gpu/drm/mediatek/mtk_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.h
@@ -7,7 +7,7 @@
 #define MTK_CRTC_H
 
 #include <drm/drm_crtc.h>
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_drm_plane.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
similarity index 99%
rename from drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
rename to drivers/gpu/drm/mediatek/mtk_ddp_comp.c
index b2c0665867d3..98398993500f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
@@ -17,7 +17,7 @@
 #include "mtk_disp_drv.h"
 #include "mtk_drm_drv.h"
 #include "mtk_drm_plane.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_crtc.h"
 
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
similarity index 100%
rename from drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
rename to drivers/gpu/drm/mediatek/mtk_ddp_comp.h
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_aal.c b/drivers/gpu/drm/mediatek/mtk_disp_aal.c
index 005fc9de2ee9..53ea856a31a4 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_aal.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_aal.c
@@ -13,7 +13,7 @@
 
 #include "mtk_disp_drv.h"
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
 #define DISP_AAL_EN				0x0000
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
index cbdee3986120..d97e1a15bf6e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
@@ -12,7 +12,7 @@
 
 #include "mtk_disp_drv.h"
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
 #define DISP_CCORR_EN				0x0000
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index e2124b447767..69ed886f1388 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -12,7 +12,7 @@
 
 #include "mtk_disp_drv.h"
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
 #define DISP_COLOR_CFG_MAIN			0x0400
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
index 84b02064808b..ed126ba8d600 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
@@ -13,7 +13,7 @@
 
 #include "mtk_disp_drv.h"
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
 #define DISP_GAMMA_EN				0x0000
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 4d90a274380e..2d072f049078 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -10,7 +10,7 @@
 #include <linux/reset.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_disp_drv.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 0ab680e11862..74846dc31354 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -17,7 +17,7 @@
 
 #include "mtk_disp_drv.h"
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
 #define DISP_REG_OVL_INTEN			0x0004
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index f2d9c372879a..0e80629ceae8 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -19,7 +19,7 @@
 
 #include "mtk_disp_drv.h"
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_ethdr.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index af78240229e8..669dc3f45a34 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -15,7 +15,7 @@
 
 #include "mtk_disp_drv.h"
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
 #define DISP_REG_RDMA_INT_ENABLE		0x0000
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index beb7d9d08e97..84745ec9dd7c 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -28,7 +28,7 @@
 
 #include "mtk_disp_drv.h"
 #include "mtk_dpi_regs.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
 enum mtk_dpi_out_bit_num {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 7be3b0546d3d..113fdbaac5a1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -25,7 +25,7 @@
 #include <drm/drm_vblank.h>
 
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_drm_gem.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 24c4d59085bd..78d698ede1bf 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -7,7 +7,7 @@
 #define MTK_DRM_DRV_H
 
 #include <linux/io.h>
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 
 #define MAX_CONNECTOR	2
 #define DDP_COMPONENT_DRM_OVL_ADAPTOR (DDP_COMPONENT_ID_MAX + 1)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 720f6b4b0821..63a7a24468c1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -14,7 +14,7 @@
 #include <linux/align.h>
 
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_drm_gem.h"
 #include "mtk_drm_plane.h"
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index ec9d96396d7b..a9071c4dce0e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -29,7 +29,7 @@
 #include <drm/drm_simple_kms_helper.h>
 
 #include "mtk_disp_drv.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
 #define DSI_START		0x00
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index 41efaafe26f1..9b0264bd5e73 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -15,7 +15,7 @@
 #include <linux/soc/mediatek/mtk-mmsys.h>
 
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_ethdr.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_padding.c b/drivers/gpu/drm/mediatek/mtk_padding.c
index cf233e43f95c..cdfdb7d8c449 100644
--- a/drivers/gpu/drm/mediatek/mtk_padding.c
+++ b/drivers/gpu/drm/mediatek/mtk_padding.c
@@ -13,7 +13,7 @@
 
 #include "mtk_disp_drv.h"
 #include "mtk_crtc.h"
-#include "mtk_drm_ddp_comp.h"
+#include "mtk_ddp_comp.h"
 
 #define PADDING_CONTROL_REG	0x00
 #define PADDING_BYPASS			BIT(0)
-- 
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:59 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:59 +0800
Subject: [PATCH 11/11] drm/mediatek: Rename "pending_needs_vblank" to "needs_vblank"
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-12-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename "pending_needs_vblank" to "needs_vblank" to reduce the code size.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/mtk_crtc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
index 7fe234de83a3..a1fb6c67681d 100644
--- a/drivers/gpu/drm/mediatek/mtk_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
@@ -42,7 +42,7 @@ struct mtk_crtc {
 	struct drm_crtc			base;
 	bool				enabled;
 
-	bool				pending_needs_vblank;
+	bool				needs_vblank;
 	struct drm_pending_vblank_event	*event;
 
 	struct drm_plane		*planes;
@@ -105,9 +105,9 @@ static void mtk_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc)
 static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
 {
 	drm_crtc_handle_vblank(&mtk_crtc->base);
-	if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
+	if (!mtk_crtc->config_updating && mtk_crtc->needs_vblank) {
 		mtk_crtc_finish_page_flip(mtk_crtc);
-		mtk_crtc->pending_needs_vblank = false;
+		mtk_crtc->needs_vblank = false;
 	}
 }
 
@@ -571,7 +571,7 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
 	mutex_lock(&mtk_crtc->hw_lock);
 	mtk_crtc->config_updating = true;
 	if (needs_vblank)
-		mtk_crtc->pending_needs_vblank = true;
+		mtk_crtc->needs_vblank = true;
 
 	for (i = 0; i < mtk_crtc->layer_nr; i++) {
 		struct drm_plane *plane = &mtk_crtc->planes[i];
-- 
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:53 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:53 +0800
Subject: [PATCH 05/11] drm/mediatek: Rename "mtk_drm_hdmi" to "mtk_hdmi"
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-6-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename all "mtk_drm_hdmi" to "mtk_hdmi":
- To align the naming rule
- To reduce the code size

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/mtk_hdmi.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 86133bf16326..d2876da1b43a 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1687,7 +1687,7 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
 	return 0;
 }
 
-static int mtk_drm_hdmi_probe(struct platform_device *pdev)
+static int mtk_hdmi_probe(struct platform_device *pdev)
 {
 	struct mtk_hdmi *hdmi;
 	struct device *dev = &pdev->dev;
@@ -1746,7 +1746,7 @@ static int mtk_drm_hdmi_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static void mtk_drm_hdmi_remove(struct platform_device *pdev)
+static void mtk_hdmi_remove(struct platform_device *pdev)
 {
 	struct mtk_hdmi *hdmi = platform_get_drvdata(pdev);
 
@@ -1790,7 +1790,7 @@ static const struct mtk_hdmi_conf mtk_hdmi_conf_mt8167 = {
 	.cea_modes_only = true,
 };
 
-static const struct of_device_id mtk_drm_hdmi_of_ids[] = {
+static const struct of_device_id mtk_hdmi_of_ids[] = {
 	{ .compatible = "mediatek,mt2701-hdmi",
 	  .data = &mtk_hdmi_conf_mt2701,
 	},
@@ -1801,14 +1801,14 @@ static const struct of_device_id mtk_drm_hdmi_of_ids[] = {
 	},
 	{}
 };
-MODULE_DEVICE_TABLE(of, mtk_drm_hdmi_of_ids);
+MODULE_DEVICE_TABLE(of, mtk_hdmi_of_ids);
 
 static struct platform_driver mtk_hdmi_driver = {
-	.probe = mtk_drm_hdmi_probe,
-	.remove_new = mtk_drm_hdmi_remove,
+	.probe = mtk_hdmi_probe,
+	.remove_new = mtk_hdmi_remove,
 	.driver = {
 		.name = "mediatek-drm-hdmi",
-		.of_match_table = mtk_drm_hdmi_of_ids,
+		.of_match_table = mtk_hdmi_of_ids,
 		.pm = &mtk_hdmi_pm_ops,
 	},
 };
-- 
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:52 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:52 +0800
Subject: [PATCH 04/11] drm/mediatek: Rename "mtk_drm_gem" to "mtk_gem"
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-5-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename all "mtk_drm_gem" to "mtk_gem":
- To align the naming rule
- To reduce the code size

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c   |  8 +--
 drivers/gpu/drm/mediatek/mtk_drm_gem.c   | 63 ++++++++++++------------
 drivers/gpu/drm/mediatek/mtk_drm_gem.h   | 19 ++++---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c |  2 +-
 4 files changed, 45 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index c46773569b3c..81e8aa65abd6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -576,8 +576,8 @@ DEFINE_DRM_GEM_FOPS(mtk_drm_fops);
  * We need to override this because the device used to import the memory is
  * not dev->dev, as drm_gem_prime_import() expects.
  */
-static struct drm_gem_object *mtk_drm_gem_prime_import(struct drm_device *dev,
-						       struct dma_buf *dma_buf)
+static struct drm_gem_object *mtk_gem_prime_import(struct drm_device *dev,
+						   struct dma_buf *dma_buf)
 {
 	struct mtk_drm_private *private = dev->dev_private;
 
@@ -587,9 +587,9 @@ static struct drm_gem_object *mtk_drm_gem_prime_import(struct drm_device *dev,
 static const struct drm_driver mtk_drm_driver = {
 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
 
-	.dumb_create = mtk_drm_gem_dumb_create,
+	.dumb_create = mtk_gem_dumb_create,
 
-	.gem_prime_import = mtk_drm_gem_prime_import,
+	.gem_prime_import = mtk_gem_prime_import,
 	.gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
 	.fops = &mtk_drm_fops,
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
index 4f2e3feabc0f..3ae1f12bfb46 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -14,26 +14,26 @@
 #include "mtk_drm_drv.h"
 #include "mtk_drm_gem.h"
 
-static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
+static int mtk_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
 
 static const struct vm_operations_struct vm_ops = {
 	.open = drm_gem_vm_open,
 	.close = drm_gem_vm_close,
 };
 
-static const struct drm_gem_object_funcs mtk_drm_gem_object_funcs = {
-	.free = mtk_drm_gem_free_object,
+static const struct drm_gem_object_funcs mtk_gem_object_funcs = {
+	.free = mtk_gem_free_object,
 	.get_sg_table = mtk_gem_prime_get_sg_table,
-	.vmap = mtk_drm_gem_prime_vmap,
-	.vunmap = mtk_drm_gem_prime_vunmap,
-	.mmap = mtk_drm_gem_object_mmap,
+	.vmap = mtk_gem_prime_vmap,
+	.vunmap = mtk_gem_prime_vunmap,
+	.mmap = mtk_gem_object_mmap,
 	.vm_ops = &vm_ops,
 };
 
-static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct drm_device *dev,
-						unsigned long size)
+static struct mtk_gem_obj *mtk_gem_init(struct drm_device *dev,
+					unsigned long size)
 {
-	struct mtk_drm_gem_obj *mtk_gem_obj;
+	struct mtk_gem_obj *mtk_gem_obj;
 	int ret;
 
 	size = round_up(size, PAGE_SIZE);
@@ -42,7 +42,7 @@ static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct drm_device *dev,
 	if (!mtk_gem_obj)
 		return ERR_PTR(-ENOMEM);
 
-	mtk_gem_obj->base.funcs = &mtk_drm_gem_object_funcs;
+	mtk_gem_obj->base.funcs = &mtk_gem_object_funcs;
 
 	ret = drm_gem_object_init(dev, &mtk_gem_obj->base, size);
 	if (ret < 0) {
@@ -54,15 +54,15 @@ static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct drm_device *dev,
 	return mtk_gem_obj;
 }
 
-struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev,
-					   size_t size, bool alloc_kmap)
+struct mtk_gem_obj *mtk_gem_create(struct drm_device *dev, size_t size,
+				   bool alloc_kmap)
 {
 	struct mtk_drm_private *priv = dev->dev_private;
-	struct mtk_drm_gem_obj *mtk_gem;
+	struct mtk_gem_obj *mtk_gem;
 	struct drm_gem_object *obj;
 	int ret;
 
-	mtk_gem = mtk_drm_gem_init(dev, size);
+	mtk_gem = mtk_gem_init(dev, size);
 	if (IS_ERR(mtk_gem))
 		return ERR_CAST(mtk_gem);
 
@@ -97,9 +97,9 @@ struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev,
 	return ERR_PTR(ret);
 }
 
-void mtk_drm_gem_free_object(struct drm_gem_object *obj)
+void mtk_gem_free_object(struct drm_gem_object *obj)
 {
-	struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
+	struct mtk_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
 	struct mtk_drm_private *priv = obj->dev->dev_private;
 
 	if (mtk_gem->sg)
@@ -114,10 +114,10 @@ void mtk_drm_gem_free_object(struct drm_gem_object *obj)
 	kfree(mtk_gem);
 }
 
-int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
-			    struct drm_mode_create_dumb *args)
+int mtk_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
+			struct drm_mode_create_dumb *args)
 {
-	struct mtk_drm_gem_obj *mtk_gem;
+	struct mtk_gem_obj *mtk_gem;
 	int ret;
 
 	args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
@@ -130,7 +130,7 @@ int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
 	args->size = args->pitch;
 	args->size *= args->height;
 
-	mtk_gem = mtk_drm_gem_create(dev, args->size, false);
+	mtk_gem = mtk_gem_create(dev, args->size, false);
 	if (IS_ERR(mtk_gem))
 		return PTR_ERR(mtk_gem);
 
@@ -148,16 +148,16 @@ int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
 	return 0;
 
 err_handle_create:
-	mtk_drm_gem_free_object(&mtk_gem->base);
+	mtk_gem_free_object(&mtk_gem->base);
 	return ret;
 }
 
-static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
-				   struct vm_area_struct *vma)
+static int mtk_gem_object_mmap(struct drm_gem_object *obj,
+			       struct vm_area_struct *vma)
 
 {
 	int ret;
-	struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
+	struct mtk_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
 	struct mtk_drm_private *priv = obj->dev->dev_private;
 
 	/*
@@ -188,7 +188,7 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
  */
 struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj)
 {
-	struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
+	struct mtk_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
 	struct mtk_drm_private *priv = obj->dev->dev_private;
 	struct sg_table *sgt;
 	int ret;
@@ -212,7 +212,7 @@ struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj)
 struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
 			struct dma_buf_attachment *attach, struct sg_table *sg)
 {
-	struct mtk_drm_gem_obj *mtk_gem;
+	struct mtk_gem_obj *mtk_gem;
 
 	/* check if the entries in the sg_table are contiguous */
 	if (drm_prime_get_contiguous_size(sg) < attach->dmabuf->size) {
@@ -220,7 +220,7 @@ struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
 		return ERR_PTR(-EINVAL);
 	}
 
-	mtk_gem = mtk_drm_gem_init(dev, attach->dmabuf->size);
+	mtk_gem = mtk_gem_init(dev, attach->dmabuf->size);
 	if (IS_ERR(mtk_gem))
 		return ERR_CAST(mtk_gem);
 
@@ -230,9 +230,9 @@ struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
 	return &mtk_gem->base;
 }
 
-int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map)
+int mtk_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map)
 {
-	struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
+	struct mtk_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
 	struct sg_table *sgt = NULL;
 	unsigned int npages;
 
@@ -270,10 +270,9 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map)
 	return 0;
 }
 
-void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj,
-			      struct iosys_map *map)
+void mtk_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
 {
-	struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
+	struct mtk_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
 	void *vaddr = map->vaddr;
 
 	if (!mtk_gem->pages)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.h b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
index 78f23b07a02e..8a5a760f5e6d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
@@ -22,7 +22,7 @@
  * P.S. this object would be transferred to user as kms_bo.handle so
  *	user can access the buffer through kms_bo.handle.
  */
-struct mtk_drm_gem_obj {
+struct mtk_gem_obj {
 	struct drm_gem_object	base;
 	void			*cookie;
 	void			*kvaddr;
@@ -32,18 +32,17 @@ struct mtk_drm_gem_obj {
 	struct page		**pages;
 };
 
-#define to_mtk_gem_obj(x)	container_of(x, struct mtk_drm_gem_obj, base)
+#define to_mtk_gem_obj(x) container_of(x, struct mtk_gem_obj, base)
 
-void mtk_drm_gem_free_object(struct drm_gem_object *gem);
-struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev, size_t size,
-					   bool alloc_kmap);
-int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
-			    struct drm_mode_create_dumb *args);
+void mtk_gem_free_object(struct drm_gem_object *gem);
+struct mtk_gem_obj *mtk_gem_create(struct drm_device *dev, size_t size,
+				   bool alloc_kmap);
+int mtk_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
+			struct drm_mode_create_dumb *args);
 struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj);
 struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
 			struct dma_buf_attachment *attach, struct sg_table *sg);
-int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map);
-void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj,
-			      struct iosys_map *map);
+int mtk_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map);
+void mtk_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map);
 
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 43137c46fc14..db63a32c407e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -135,7 +135,7 @@ static void mtk_plane_update_new_state(struct drm_plane_state *new_state,
 {
 	struct drm_framebuffer *fb = new_state->fb;
 	struct drm_gem_object *gem;
-	struct mtk_drm_gem_obj *mtk_gem;
+	struct mtk_gem_obj *mtk_gem;
 	unsigned int pitch, format;
 	u64 modifier;
 	dma_addr_t addr;
-- 
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:49 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:49 +0800
Subject: [PATCH 01/11] drm/mediatek: Rename "mtk_drm_crtc" to "mtk_crtc"
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-2-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename all "mtk_drm_crtc" to "mtk_crtc" due to the following benefits:
- Lower the matches when searching the native drm_crtc* codes
- Reduce the code size

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 186 +++++++++++------------
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h  |  30 ++--
 drivers/gpu/drm/mediatek/mtk_drm_drv.c   |  18 +--
 drivers/gpu/drm/mediatek/mtk_drm_drv.h   |   2 +-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c |  10 +-
 drivers/gpu/drm/mediatek/mtk_dsi.c       |   2 +-
 6 files changed, 121 insertions(+), 127 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 3b55c7a68bde..fe965ad7d282 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -26,7 +26,7 @@
 #include "mtk_drm_plane.h"
 
 /*
- * struct mtk_drm_crtc - MediaTek specific crtc structure.
+ * struct mtk_crtc - MediaTek specific crtc structure.
  * @base: crtc object.
  * @enabled: records whether crtc_enable succeeded
  * @planes: array of 4 drm_plane structures, one for each overlay plane
@@ -38,7 +38,7 @@
  *
  * TODO: Needs update: this header is missing a bunch of member descriptions.
  */
-struct mtk_drm_crtc {
+struct mtk_crtc {
 	struct drm_crtc			base;
 	bool				enabled;
 
@@ -80,9 +80,9 @@ struct mtk_crtc_state {
 	unsigned int			pending_vrefresh;
 };
 
-static inline struct mtk_drm_crtc *to_mtk_crtc(struct drm_crtc *c)
+static inline struct mtk_crtc *to_mtk_crtc(struct drm_crtc *c)
 {
-	return container_of(c, struct mtk_drm_crtc, base);
+	return container_of(c, struct mtk_crtc, base);
 }
 
 static inline struct mtk_crtc_state *to_mtk_crtc_state(struct drm_crtc_state *s)
@@ -90,7 +90,7 @@ static inline struct mtk_crtc_state *to_mtk_crtc_state(struct drm_crtc_state *s)
 	return container_of(s, struct mtk_crtc_state, base);
 }
 
-static void mtk_drm_crtc_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
+static void mtk_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc)
 {
 	struct drm_crtc *crtc = &mtk_crtc->base;
 	unsigned long flags;
@@ -102,11 +102,11 @@ static void mtk_drm_crtc_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
 	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 }
 
-static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
+static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
 {
 	drm_crtc_handle_vblank(&mtk_crtc->base);
 	if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
-		mtk_drm_crtc_finish_page_flip(mtk_crtc);
+		mtk_crtc_finish_page_flip(mtk_crtc);
 		mtk_crtc->pending_needs_vblank = false;
 	}
 }
@@ -149,9 +149,9 @@ static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
 }
 #endif
 
-static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
+static void mtk_crtc_destroy(struct drm_crtc *crtc)
 {
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	int i;
 
 	mtk_mutex_put(mtk_crtc->mutex);
@@ -174,7 +174,7 @@ static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
 	drm_crtc_cleanup(crtc);
 }
 
-static void mtk_drm_crtc_reset(struct drm_crtc *crtc)
+static void mtk_crtc_reset(struct drm_crtc *crtc)
 {
 	struct mtk_crtc_state *state;
 
@@ -189,7 +189,7 @@ static void mtk_drm_crtc_reset(struct drm_crtc *crtc)
 		__drm_atomic_helper_crtc_reset(crtc, &state->base);
 }
 
-static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc)
+static struct drm_crtc_state *mtk_crtc_duplicate_state(struct drm_crtc *crtc)
 {
 	struct mtk_crtc_state *state;
 
@@ -206,18 +206,17 @@ static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc
 	return &state->base;
 }
 
-static void mtk_drm_crtc_destroy_state(struct drm_crtc *crtc,
-				       struct drm_crtc_state *state)
+static void mtk_crtc_destroy_state(struct drm_crtc *crtc,
+				   struct drm_crtc_state *state)
 {
 	__drm_atomic_helper_crtc_destroy_state(state);
 	kfree(to_mtk_crtc_state(state));
 }
 
 static enum drm_mode_status
-mtk_drm_crtc_mode_valid(struct drm_crtc *crtc,
-			const struct drm_display_mode *mode)
+mtk_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
 {
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	enum drm_mode_status status = MODE_OK;
 	int i;
 
@@ -229,15 +228,15 @@ mtk_drm_crtc_mode_valid(struct drm_crtc *crtc,
 	return status;
 }
 
-static bool mtk_drm_crtc_mode_fixup(struct drm_crtc *crtc,
-				    const struct drm_display_mode *mode,
-				    struct drm_display_mode *adjusted_mode)
+static bool mtk_crtc_mode_fixup(struct drm_crtc *crtc,
+				const struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
 {
 	/* Nothing to do here, but this callback is mandatory. */
 	return true;
 }
 
-static void mtk_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
+static void mtk_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
 	struct mtk_crtc_state *state = to_mtk_crtc_state(crtc->state);
 
@@ -248,7 +247,7 @@ static void mtk_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 	state->pending_config = true;
 }
 
-static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
+static int mtk_crtc_ddp_clk_enable(struct mtk_crtc *mtk_crtc)
 {
 	int ret;
 	int i;
@@ -268,7 +267,7 @@ static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
 	return ret;
 }
 
-static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
+static void mtk_crtc_ddp_clk_disable(struct mtk_crtc *mtk_crtc)
 {
 	int i;
 
@@ -281,7 +280,7 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
 						struct drm_plane *plane,
 						unsigned int *local_layer)
 {
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_ddp_comp *comp;
 	int i, count = 0;
 	unsigned int local_index = plane - mtk_crtc->planes;
@@ -304,7 +303,7 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 {
 	struct cmdq_cb_data *data = mssg;
 	struct cmdq_client *cmdq_cl = container_of(cl, struct cmdq_client, client);
-	struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, cmdq_client);
+	struct mtk_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_crtc, cmdq_client);
 	struct mtk_crtc_state *state;
 	unsigned int i;
 
@@ -344,7 +343,7 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 }
 #endif
 
-static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
+static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)
 {
 	struct drm_crtc *crtc = &mtk_crtc->base;
 	struct drm_connector *connector;
@@ -444,7 +443,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 	return ret;
 }
 
-static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
+static void mtk_crtc_ddp_hw_fini(struct mtk_crtc *mtk_crtc)
 {
 	struct drm_device *drm = mtk_crtc->base.dev;
 	struct drm_crtc *crtc = &mtk_crtc->base;
@@ -489,7 +488,7 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
 static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 				struct cmdq_pkt *cmdq_handle)
 {
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
 	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 	unsigned int i;
@@ -561,8 +560,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 	}
 }
 
-static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
-				       bool needs_vblank)
+static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
 {
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	struct cmdq_pkt *cmdq_handle = &mtk_crtc->cmdq_handle;
@@ -634,7 +632,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
 static void mtk_crtc_ddp_irq(void *data)
 {
 	struct drm_crtc *crtc = data;
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_drm_private *priv = crtc->dev->dev_private;
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
@@ -650,9 +648,9 @@ static void mtk_crtc_ddp_irq(void *data)
 	mtk_drm_finish_page_flip(mtk_crtc);
 }
 
-static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
+static int mtk_crtc_enable_vblank(struct drm_crtc *crtc)
 {
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 
 	mtk_ddp_comp_enable_vblank(comp);
@@ -660,22 +658,22 @@ static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 	return 0;
 }
 
-static void mtk_drm_crtc_disable_vblank(struct drm_crtc *crtc)
+static void mtk_crtc_disable_vblank(struct drm_crtc *crtc)
 {
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 
 	mtk_ddp_comp_disable_vblank(comp);
 }
 
-static void mtk_drm_crtc_update_output(struct drm_crtc *crtc,
-				       struct drm_atomic_state *state)
+static void mtk_crtc_update_output(struct drm_crtc *crtc,
+				   struct drm_atomic_state *state)
 {
 	int crtc_index = drm_crtc_index(crtc);
 	int i;
 	struct device *dev;
 	struct drm_crtc_state *crtc_state = state->crtcs[crtc_index].new_state;
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_drm_private *priv;
 	unsigned int encoder_mask = crtc_state->encoder_mask;
 
@@ -705,8 +703,8 @@ static void mtk_drm_crtc_update_output(struct drm_crtc *crtc,
 	}
 }
 
-int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
-			     struct mtk_plane_state *state)
+int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
+			 struct mtk_plane_state *state)
 {
 	unsigned int local_layer;
 	struct mtk_ddp_comp *comp;
@@ -717,21 +715,21 @@ int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
 	return 0;
 }
 
-void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
-			       struct drm_atomic_state *state)
+void mtk_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
+			   struct drm_atomic_state *state)
 {
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 
 	if (!mtk_crtc->enabled)
 		return;
 
-	mtk_drm_crtc_update_config(mtk_crtc, false);
+	mtk_crtc_update_config(mtk_crtc, false);
 }
 
-static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
-				       struct drm_atomic_state *state)
+static void mtk_crtc_atomic_enable(struct drm_crtc *crtc,
+				   struct drm_atomic_state *state)
 {
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 	int ret;
 
@@ -743,7 +741,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 		return;
 	}
 
-	mtk_drm_crtc_update_output(crtc, state);
+	mtk_crtc_update_output(crtc, state);
 
 	ret = mtk_crtc_ddp_hw_init(mtk_crtc);
 	if (ret) {
@@ -755,10 +753,10 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 	mtk_crtc->enabled = true;
 }
 
-static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
-					struct drm_atomic_state *state)
+static void mtk_crtc_atomic_disable(struct drm_crtc *crtc,
+				    struct drm_atomic_state *state)
 {
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 	int i;
 
@@ -777,7 +775,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 	}
 	mtk_crtc->pending_planes = true;
 
-	mtk_drm_crtc_update_config(mtk_crtc, false);
+	mtk_crtc_update_config(mtk_crtc, false);
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	/* Wait for planes to be disabled by cmdq */
 	if (mtk_crtc->cmdq_client.chan)
@@ -795,13 +793,13 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 	mtk_crtc->enabled = false;
 }
 
-static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc,
-				      struct drm_atomic_state *state)
+static void mtk_crtc_atomic_begin(struct drm_crtc *crtc,
+				  struct drm_atomic_state *state)
 {
 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
 									  crtc);
 	struct mtk_crtc_state *mtk_crtc_state = to_mtk_crtc_state(crtc_state);
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	unsigned long flags;
 
 	if (mtk_crtc->event && mtk_crtc_state->base.event)
@@ -819,10 +817,10 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc,
 	}
 }
 
-static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
-				      struct drm_atomic_state *state)
+static void mtk_crtc_atomic_flush(struct drm_crtc *crtc,
+				  struct drm_atomic_state *state)
 {
-	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	int i;
 
 	if (crtc->state->color_mgmt_changed)
@@ -830,33 +828,32 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 			mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
 			mtk_ddp_ctm_set(mtk_crtc->ddp_comp[i], crtc->state);
 		}
-	mtk_drm_crtc_update_config(mtk_crtc, !!mtk_crtc->event);
+	mtk_crtc_update_config(mtk_crtc, !!mtk_crtc->event);
 }
 
 static const struct drm_crtc_funcs mtk_crtc_funcs = {
 	.set_config		= drm_atomic_helper_set_config,
 	.page_flip		= drm_atomic_helper_page_flip,
-	.destroy		= mtk_drm_crtc_destroy,
-	.reset			= mtk_drm_crtc_reset,
-	.atomic_duplicate_state	= mtk_drm_crtc_duplicate_state,
-	.atomic_destroy_state	= mtk_drm_crtc_destroy_state,
-	.enable_vblank		= mtk_drm_crtc_enable_vblank,
-	.disable_vblank		= mtk_drm_crtc_disable_vblank,
+	.destroy		= mtk_crtc_destroy,
+	.reset			= mtk_crtc_reset,
+	.atomic_duplicate_state	= mtk_crtc_duplicate_state,
+	.atomic_destroy_state	= mtk_crtc_destroy_state,
+	.enable_vblank		= mtk_crtc_enable_vblank,
+	.disable_vblank		= mtk_crtc_disable_vblank,
 };
 
 static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
-	.mode_fixup	= mtk_drm_crtc_mode_fixup,
-	.mode_set_nofb	= mtk_drm_crtc_mode_set_nofb,
-	.mode_valid	= mtk_drm_crtc_mode_valid,
-	.atomic_begin	= mtk_drm_crtc_atomic_begin,
-	.atomic_flush	= mtk_drm_crtc_atomic_flush,
-	.atomic_enable	= mtk_drm_crtc_atomic_enable,
-	.atomic_disable	= mtk_drm_crtc_atomic_disable,
+	.mode_fixup	= mtk_crtc_mode_fixup,
+	.mode_set_nofb	= mtk_crtc_mode_set_nofb,
+	.mode_valid	= mtk_crtc_mode_valid,
+	.atomic_begin	= mtk_crtc_atomic_begin,
+	.atomic_flush	= mtk_crtc_atomic_flush,
+	.atomic_enable	= mtk_crtc_atomic_enable,
+	.atomic_disable	= mtk_crtc_atomic_disable,
 };
 
-static int mtk_drm_crtc_init(struct drm_device *drm,
-			     struct mtk_drm_crtc *mtk_crtc,
-			     unsigned int pipe)
+static int mtk_crtc_init(struct drm_device *drm, struct mtk_crtc *mtk_crtc,
+			 unsigned int pipe)
 {
 	struct drm_plane *primary = NULL;
 	struct drm_plane *cursor = NULL;
@@ -883,8 +880,7 @@ static int mtk_drm_crtc_init(struct drm_device *drm,
 	return ret;
 }
 
-static int mtk_drm_crtc_num_comp_planes(struct mtk_drm_crtc *mtk_crtc,
-					int comp_idx)
+static int mtk_crtc_num_comp_planes(struct mtk_crtc *mtk_crtc, int comp_idx)
 {
 	struct mtk_ddp_comp *comp;
 
@@ -902,8 +898,8 @@ static int mtk_drm_crtc_num_comp_planes(struct mtk_drm_crtc *mtk_crtc,
 }
 
 static inline
-enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx,
-					    unsigned int num_planes)
+enum drm_plane_type mtk_crtc_plane_type(unsigned int plane_idx,
+					unsigned int num_planes)
 {
 	if (plane_idx == 0)
 		return DRM_PLANE_TYPE_PRIMARY;
@@ -914,11 +910,11 @@ enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx,
 
 }
 
-static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
-					 struct mtk_drm_crtc *mtk_crtc,
-					 int comp_idx, int pipe)
+static int mtk_crtc_init_comp_planes(struct drm_device *drm_dev,
+				     struct mtk_crtc *mtk_crtc,
+				     int comp_idx, int pipe)
 {
-	int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx);
+	int num_planes = mtk_crtc_num_comp_planes(mtk_crtc, comp_idx);
 	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[comp_idx];
 	int i, ret;
 
@@ -926,8 +922,7 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
 		ret = mtk_plane_init(drm_dev,
 				&mtk_crtc->planes[mtk_crtc->layer_nr],
 				BIT(pipe),
-				mtk_drm_crtc_plane_type(mtk_crtc->layer_nr,
-							num_planes),
+				mtk_crtc_plane_type(mtk_crtc->layer_nr, num_planes),
 				mtk_ddp_comp_supported_rotations(comp),
 				mtk_ddp_comp_get_formats(comp),
 				mtk_ddp_comp_get_num_formats(comp));
@@ -939,9 +934,9 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
 	return 0;
 }
 
-struct device *mtk_drm_crtc_dma_dev_get(struct drm_crtc *crtc)
+struct device *mtk_crtc_dma_dev_get(struct drm_crtc *crtc)
 {
-	struct mtk_drm_crtc *mtk_crtc = NULL;
+	struct mtk_crtc *mtk_crtc = NULL;
 
 	if (!crtc)
 		return NULL;
@@ -953,14 +948,14 @@ struct device *mtk_drm_crtc_dma_dev_get(struct drm_crtc *crtc)
 	return mtk_crtc->dma_dev;
 }
 
-int mtk_drm_crtc_create(struct drm_device *drm_dev,
-			const unsigned int *path, unsigned int path_len,
-			int priv_data_index, const struct mtk_drm_route *conn_routes,
-			unsigned int num_conn_routes)
+int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,
+		    unsigned int path_len, int priv_data_index,
+		    const struct mtk_drm_route *conn_routes,
+		    unsigned int num_conn_routes)
 {
 	struct mtk_drm_private *priv = drm_dev->dev_private;
 	struct device *dev = drm_dev->dev;
-	struct mtk_drm_crtc *mtk_crtc;
+	struct mtk_crtc *mtk_crtc;
 	unsigned int num_comp_planes = 0;
 	int ret;
 	int i;
@@ -1045,7 +1040,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 	}
 
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
-		num_comp_planes += mtk_drm_crtc_num_comp_planes(mtk_crtc, i);
+		num_comp_planes += mtk_crtc_num_comp_planes(mtk_crtc, i);
 
 	mtk_crtc->planes = devm_kcalloc(dev, num_comp_planes,
 					sizeof(struct drm_plane), GFP_KERNEL);
@@ -1053,8 +1048,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 		return -ENOMEM;
 
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
-		ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
-						    crtc_i);
+		ret = mtk_crtc_init_comp_planes(drm_dev, mtk_crtc, i, crtc_i);
 		if (ret)
 			return ret;
 	}
@@ -1066,7 +1060,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 	 */
 	mtk_crtc->dma_dev = mtk_ddp_comp_dma_dev_get(&priv->ddp_comp[path[0]]);
 
-	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i);
+	ret = mtk_crtc_init(drm_dev, mtk_crtc, crtc_i);
 	if (ret < 0)
 		return ret;
 
@@ -1136,7 +1130,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 		mtk_crtc->num_conn_routes = num_conn_routes;
 		mtk_crtc->conn_routes = conn_routes;
 
-		/* increase ddp_comp_nr at the end of mtk_drm_crtc_create */
+		/* increase ddp_comp_nr at the end of mtk_crtc_create */
 		mtk_crtc->ddp_comp_nr++;
 	}
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index 1f988ff1bf9f..f081c54a349b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -3,8 +3,8 @@
  * Copyright (c) 2015 MediaTek Inc.
  */
 
-#ifndef MTK_DRM_CRTC_H
-#define MTK_DRM_CRTC_H
+#ifndef MTK_CRTC_H
+#define MTK_CRTC_H
 
 #include <drm/drm_crtc.h>
 #include "mtk_drm_ddp_comp.h"
@@ -14,17 +14,17 @@
 #define MTK_MAX_BPC	10
 #define MTK_MIN_BPC	3
 
-void mtk_drm_crtc_commit(struct drm_crtc *crtc);
-int mtk_drm_crtc_create(struct drm_device *drm_dev,
-			const unsigned int *path,
-			unsigned int path_len,
-			int priv_data_index,
-			const struct mtk_drm_route *conn_routes,
-			unsigned int num_conn_routes);
-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,
-			       struct drm_atomic_state *plane_state);
-struct device *mtk_drm_crtc_dma_dev_get(struct drm_crtc *crtc);
+void mtk_crtc_commit(struct drm_crtc *crtc);
+int mtk_crtc_create(struct drm_device *drm_dev,
+		    const unsigned int *path,
+		    unsigned int path_len,
+		    int priv_data_index,
+		    const struct mtk_drm_route *conn_routes,
+		    unsigned int num_conn_routes);
+int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
+			 struct mtk_plane_state *state);
+void mtk_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
+			   struct drm_atomic_state *plane_state);
+struct device *mtk_crtc_dma_dev_get(struct drm_crtc *crtc);
 
-#endif /* MTK_DRM_CRTC_H */
+#endif /* MTK_CRTC_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 74832c213092..c46773569b3c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -494,24 +494,24 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 			priv_n = private->all_drm_private[j];
 
 			if (i == CRTC_MAIN && priv_n->data->main_len) {
-				ret = mtk_drm_crtc_create(drm, priv_n->data->main_path,
-							  priv_n->data->main_len, j,
-							  priv_n->data->conn_routes,
-							  priv_n->data->num_conn_routes);
+				ret = mtk_crtc_create(drm, priv_n->data->main_path,
+						      priv_n->data->main_len, j,
+						      priv_n->data->conn_routes,
+						      priv_n->data->num_conn_routes);
 				if (ret)
 					goto err_component_unbind;
 
 				continue;
 			} else if (i == CRTC_EXT && priv_n->data->ext_len) {
-				ret = mtk_drm_crtc_create(drm, priv_n->data->ext_path,
-							  priv_n->data->ext_len, j, NULL, 0);
+				ret = mtk_crtc_create(drm, priv_n->data->ext_path,
+						      priv_n->data->ext_len, j, NULL, 0);
 				if (ret)
 					goto err_component_unbind;
 
 				continue;
 			} else if (i == CRTC_THIRD && priv_n->data->third_len) {
-				ret = mtk_drm_crtc_create(drm, priv_n->data->third_path,
-							  priv_n->data->third_len, j, NULL, 0);
+				ret = mtk_crtc_create(drm, priv_n->data->third_path,
+						      priv_n->data->third_len, j, NULL, 0);
 				if (ret)
 					goto err_component_unbind;
 
@@ -523,7 +523,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	/* Use OVL device for all DMA memory allocations */
 	crtc = drm_crtc_from_index(drm, 0);
 	if (crtc)
-		dma_dev = mtk_drm_crtc_dma_dev_get(crtc);
+		dma_dev = mtk_crtc_dma_dev_get(crtc);
 	if (!dma_dev) {
 		ret = -ENODEV;
 		dev_err(drm->dev, "Need at least one OVL device\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 33fadb08dc1c..24c4d59085bd 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -13,7 +13,7 @@
 #define DDP_COMPONENT_DRM_OVL_ADAPTOR (DDP_COMPONENT_ID_MAX + 1)
 #define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVL_ADAPTOR + 1)
 
-enum mtk_drm_crtc_path {
+enum mtk_crtc_path {
 	CRTC_MAIN,
 	CRTC_EXT,
 	CRTC_THIRD,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index ddc9355b06d5..cbdb70677d30 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -117,8 +117,8 @@ static int mtk_plane_atomic_async_check(struct drm_plane *plane,
 	if (!plane->state->fb)
 		return -EINVAL;
 
-	ret = mtk_drm_crtc_plane_check(new_plane_state->crtc, plane,
-				       to_mtk_plane_state(new_plane_state));
+	ret = mtk_crtc_plane_check(new_plane_state->crtc, plane,
+				   to_mtk_plane_state(new_plane_state));
 	if (ret)
 		return ret;
 
@@ -232,7 +232,7 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane,
 	swap(plane->state->fb, new_state->fb);
 	wmb(); /* Make sure the above parameters are set before update */
 	new_plane_state->pending.async_dirty = true;
-	mtk_drm_crtc_async_update(new_state->crtc, plane, state);
+	mtk_crtc_async_update(new_state->crtc, plane, state);
 }
 
 static const struct drm_plane_funcs mtk_plane_funcs = {
@@ -260,8 +260,8 @@ static int mtk_plane_atomic_check(struct drm_plane *plane,
 	if (WARN_ON(!new_plane_state->crtc))
 		return 0;
 
-	ret = mtk_drm_crtc_plane_check(new_plane_state->crtc, plane,
-				       to_mtk_plane_state(new_plane_state));
+	ret = mtk_crtc_plane_check(new_plane_state->crtc, plane,
+				   to_mtk_plane_state(new_plane_state));
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 9501f4019199..ec9d96396d7b 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -662,7 +662,7 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 
 	/*
 	 * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since
-	 * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(),
+	 * mtk_dsi_stop() should be called after mtk_crtc_atomic_disable(),
 	 * which needs irq for vblank, and mtk_dsi_stop() will disable irq.
 	 * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(),
 	 * after dsi is fully set.
-- 
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:54 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:54 +0800
Subject: [PATCH 06/11] drm/mediatek: Rename files "mtk_drm_crtc.*" to "mtk_crtc.*"
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-7-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename files mtk_drm_crtc.* to mtk_crtc.*.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/Makefile                       | 2 +-
 drivers/gpu/drm/mediatek/{mtk_drm_crtc.c => mtk_crtc.c} | 2 +-
 drivers/gpu/drm/mediatek/{mtk_drm_crtc.h => mtk_crtc.h} | 0
 drivers/gpu/drm/mediatek/mtk_disp_aal.c                 | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_ccorr.c               | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_color.c               | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_gamma.c               | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c                 | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c         | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c                | 2 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c             | 2 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c                  | 2 +-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c                | 2 +-
 drivers/gpu/drm/mediatek/mtk_ethdr.c                    | 2 +-
 drivers/gpu/drm/mediatek/mtk_padding.c                  | 2 +-
 15 files changed, 14 insertions(+), 14 deletions(-)
 rename drivers/gpu/drm/mediatek/{mtk_drm_crtc.c => mtk_crtc.c} (99%)
 rename drivers/gpu/drm/mediatek/{mtk_drm_crtc.h => mtk_crtc.h} (100%)

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 5e4436403b8d..edad718082a9 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -8,7 +8,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_disp_ovl.o \
 		  mtk_disp_ovl_adaptor.o \
 		  mtk_disp_rdma.o \
-		  mtk_drm_crtc.o \
+		  mtk_crtc.o \
 		  mtk_drm_ddp_comp.o \
 		  mtk_drm_drv.o \
 		  mtk_drm_gem.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
similarity index 99%
rename from drivers/gpu/drm/mediatek/mtk_drm_crtc.c
rename to drivers/gpu/drm/mediatek/mtk_crtc.c
index d8b591aff3c2..503bdcd7e596 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
@@ -20,7 +20,7 @@
 #include <drm/drm_vblank.h>
 
 #include "mtk_drm_drv.h"
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_gem.h"
 #include "mtk_drm_plane.h"
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_crtc.h
similarity index 100%
rename from drivers/gpu/drm/mediatek/mtk_drm_crtc.h
rename to drivers/gpu/drm/mediatek/mtk_crtc.h
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_aal.c b/drivers/gpu/drm/mediatek/mtk_disp_aal.c
index 40fe403086c3..005fc9de2ee9 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_aal.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_aal.c
@@ -12,7 +12,7 @@
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_disp_drv.h"
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
index 465cddce0d32..cbdee3986120 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
@@ -11,7 +11,7 @@
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_disp_drv.h"
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index 78ea99f1444f..e2124b447767 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -11,7 +11,7 @@
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_disp_drv.h"
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
index c1bc8b00d938..84b02064808b 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
@@ -12,7 +12,7 @@
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_disp_drv.h"
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 2bffe4245466..0ab680e11862 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -16,7 +16,7 @@
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_disp_drv.h"
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index 034d31824d4d..f2d9c372879a 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -18,7 +18,7 @@
 #include <linux/soc/mediatek/mtk-mutex.h>
 
 #include "mtk_disp_drv.h"
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_ethdr.h"
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index faa907f2f443..af78240229e8 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -14,7 +14,7 @@
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_disp_drv.h"
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_drv.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index a515e96cfefc..b2c0665867d3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -18,7 +18,7 @@
 #include "mtk_drm_drv.h"
 #include "mtk_drm_plane.h"
 #include "mtk_drm_ddp_comp.h"
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 
 
 #define DISP_REG_DITHER_EN			0x0000
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 81e8aa65abd6..7be3b0546d3d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -24,7 +24,7 @@
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_drm_gem.h"
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index db63a32c407e..720f6b4b0821 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -13,7 +13,7 @@
 #include <drm/drm_gem_atomic_helper.h>
 #include <linux/align.h>
 
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_drm_gem.h"
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index 6a5d0c345aab..41efaafe26f1 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -14,7 +14,7 @@
 #include <linux/soc/mediatek/mtk-cmdq.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
 
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_ethdr.h"
diff --git a/drivers/gpu/drm/mediatek/mtk_padding.c b/drivers/gpu/drm/mediatek/mtk_padding.c
index 0d6451c149b6..cf233e43f95c 100644
--- a/drivers/gpu/drm/mediatek/mtk_padding.c
+++ b/drivers/gpu/drm/mediatek/mtk_padding.c
@@ -12,7 +12,7 @@
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_disp_drv.h"
-#include "mtk_drm_crtc.h"
+#include "mtk_crtc.h"
 #include "mtk_drm_ddp_comp.h"
 
 #define PADDING_CONTROL_REG	0x00
-- 
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:50 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:50 +0800
Subject: [PATCH 02/11] drm/mediatek: Rename "mtk_drm_ddp_comp" to "mtk_ddp_comp"
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-3-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename all "mtk_drm_ddp_comp" to "mtk_ddp_comp":
- To align the naming rule
- To reduce the code size

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 16 +++++++---------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  6 +++---
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index fe965ad7d282..d8b591aff3c2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -276,9 +276,9 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_crtc *mtk_crtc)
 }
 
 static
-struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
-						struct drm_plane *plane,
-						unsigned int *local_layer)
+struct mtk_ddp_comp *mtk_ddp_comp_for_plane(struct drm_crtc *crtc,
+					    struct drm_plane *plane,
+					    unsigned int *local_layer)
 {
 	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_ddp_comp *comp;
@@ -428,7 +428,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)
 
 		/* should not enable layer before crtc enabled */
 		plane_state->pending.enable = false;
-		comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
+		comp = mtk_ddp_comp_for_plane(crtc, plane, &local_layer);
 		if (comp)
 			mtk_ddp_comp_layer_config(comp, local_layer,
 						  plane_state, NULL);
@@ -519,8 +519,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 			if (!plane_state->pending.config)
 				continue;
 
-			comp = mtk_drm_ddp_comp_for_plane(crtc, plane,
-							  &local_layer);
+			comp = mtk_ddp_comp_for_plane(crtc, plane, &local_layer);
 
 			if (comp)
 				mtk_ddp_comp_layer_config(comp, local_layer,
@@ -544,8 +543,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 			if (!plane_state->pending.async_config)
 				continue;
 
-			comp = mtk_drm_ddp_comp_for_plane(crtc, plane,
-							  &local_layer);
+			comp = mtk_ddp_comp_for_plane(crtc, plane, &local_layer);
 
 			if (comp)
 				mtk_ddp_comp_layer_config(comp, local_layer,
@@ -709,7 +707,7 @@ int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
 	unsigned int local_layer;
 	struct mtk_ddp_comp *comp;
 
-	comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
+	comp = mtk_ddp_comp_for_plane(crtc, plane, &local_layer);
 	if (comp)
 		return mtk_ddp_comp_layer_check(comp, local_layer, state);
 	return 0;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 93d79a1366e9..ba985206fdd2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -3,8 +3,8 @@
  * Copyright (c) 2015 MediaTek Inc.
  */
 
-#ifndef MTK_DRM_DDP_COMP_H
-#define MTK_DRM_DDP_COMP_H
+#ifndef MTK_DDP_COMP_H
+#define MTK_DDP_COMP_H
 
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
@@ -340,4 +340,4 @@ void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 			struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
 			unsigned int offset, unsigned int mask);
-#endif /* MTK_DRM_DDP_COMP_H */
+#endif /* MTK_DDP_COMP_H */
-- 
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:56 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:56 +0800
Subject: [PATCH 08/11] drm/mediatek: Rename files "mtk_drm_plane.*" to "mtk_plane.*"
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-9-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename files mtk_drm_plane.* to mtk_plane.*.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/Makefile                         | 2 +-
 drivers/gpu/drm/mediatek/mtk_crtc.c                       | 2 +-
 drivers/gpu/drm/mediatek/mtk_crtc.h                       | 2 +-
 drivers/gpu/drm/mediatek/mtk_ddp_comp.c                   | 2 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h                   | 2 +-
 drivers/gpu/drm/mediatek/{mtk_drm_plane.c => mtk_plane.c} | 2 +-
 drivers/gpu/drm/mediatek/{mtk_drm_plane.h => mtk_plane.h} | 0
 7 files changed, 6 insertions(+), 6 deletions(-)
 rename drivers/gpu/drm/mediatek/{mtk_drm_plane.c => mtk_plane.c} (99%)
 rename drivers/gpu/drm/mediatek/{mtk_drm_plane.h => mtk_plane.h} (100%)

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index bbdf1e59ed84..0e198c00c6f2 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -12,7 +12,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_ddp_comp.o \
 		  mtk_drm_drv.o \
 		  mtk_drm_gem.o \
-		  mtk_drm_plane.o \
+		  mtk_plane.o \
 		  mtk_dsi.o \
 		  mtk_dpi.o \
 		  mtk_ethdr.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
index 7bc4f76718e5..96af194d0d49 100644
--- a/drivers/gpu/drm/mediatek/mtk_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
@@ -23,7 +23,7 @@
 #include "mtk_crtc.h"
 #include "mtk_ddp_comp.h"
 #include "mtk_drm_gem.h"
-#include "mtk_drm_plane.h"
+#include "mtk_plane.h"
 
 /*
  * struct mtk_crtc - MediaTek specific crtc structure.
diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.h b/drivers/gpu/drm/mediatek/mtk_crtc.h
index 5865e4955471..cc8ca7c2056c 100644
--- a/drivers/gpu/drm/mediatek/mtk_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.h
@@ -9,7 +9,7 @@
 #include <drm/drm_crtc.h>
 #include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
-#include "mtk_drm_plane.h"
+#include "mtk_plane.h"
 
 #define MTK_MAX_BPC	10
 #define MTK_MIN_BPC	3
diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
index 98398993500f..ab846a9f98c5 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
@@ -16,7 +16,7 @@
 
 #include "mtk_disp_drv.h"
 #include "mtk_drm_drv.h"
-#include "mtk_drm_plane.h"
+#include "mtk_plane.h"
 #include "mtk_ddp_comp.h"
 #include "mtk_crtc.h"
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 90e64467ea8f..d9b5a6ad3bea 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -9,7 +9,7 @@
 #include <linux/soc/mediatek/mtk-cmdq.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
 #include <linux/soc/mediatek/mtk-mutex.h>
-#include "mtk_drm_plane.h"
+#include "mtk_plane.h"
 #include "mtk_mdp_rdma.h"
 
 int mtk_aal_clk_enable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
similarity index 99%
rename from drivers/gpu/drm/mediatek/mtk_drm_plane.c
rename to drivers/gpu/drm/mediatek/mtk_plane.c
index 63a7a24468c1..95a4328a9b0b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_plane.c
@@ -17,7 +17,7 @@
 #include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
 #include "mtk_drm_gem.h"
-#include "mtk_drm_plane.h"
+#include "mtk_plane.h"
 
 static const u64 modifiers[] = {
 	DRM_FORMAT_MOD_LINEAR,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.h b/drivers/gpu/drm/mediatek/mtk_plane.h
similarity index 100%
rename from drivers/gpu/drm/mediatek/mtk_drm_plane.h
rename to drivers/gpu/drm/mediatek/mtk_plane.h
-- 
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:51 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:51 +0800
Subject: [PATCH 03/11] drm/mediatek: Rename "mtk_drm_plane" to "mtk_plane"
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-4-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename all "mtk_drm_plane" to "mtk_plane":
- To align the naming rule
- To reduce the code size

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 6 +++---
 drivers/gpu/drm/mediatek/mtk_drm_plane.h | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index cbdb70677d30..43137c46fc14 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -93,8 +93,8 @@ static bool mtk_plane_format_mod_supported(struct drm_plane *plane,
 	return true;
 }
 
-static void mtk_drm_plane_destroy_state(struct drm_plane *plane,
-					struct drm_plane_state *state)
+static void mtk_plane_destroy_state(struct drm_plane *plane,
+				    struct drm_plane_state *state)
 {
 	__drm_atomic_helper_plane_destroy_state(state);
 	kfree(to_mtk_plane_state(state));
@@ -241,7 +241,7 @@ static const struct drm_plane_funcs mtk_plane_funcs = {
 	.destroy = drm_plane_cleanup,
 	.reset = mtk_plane_reset,
 	.atomic_duplicate_state = mtk_plane_duplicate_state,
-	.atomic_destroy_state = mtk_drm_plane_destroy_state,
+	.atomic_destroy_state = mtk_plane_destroy_state,
 	.format_mod_supported = mtk_plane_format_mod_supported,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.h b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
index 99aff7da0831..231bb7aac947 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
@@ -4,8 +4,8 @@
  * Author: CK Hu <ck.hu at mediatek.com>
  */
 
-#ifndef _MTK_DRM_PLANE_H_
-#define _MTK_DRM_PLANE_H_
+#ifndef _MTK_PLANE_H_
+#define _MTK_PLANE_H_
 
 #include <drm/drm_crtc.h>
 #include <linux/types.h>
-- 
2.18.0



From shawn.sung at mediatek.com  Mon Feb 26 00:50:57 2024
From: shawn.sung at mediatek.com (Shawn Sung)
Date: Mon, 26 Feb 2024 16:50:57 +0800
Subject: [PATCH 09/11] drm/mediatek: Rename files "mtk_drm_gem.*" to "mtk_gem.*"
In-Reply-To: <20240226085059.26850-1-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
Message-ID: <20240226085059.26850-10-shawn.sung@mediatek.com>

From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Rename files mtk_drm_gem.* to mtk_gem.*.

Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
---
 drivers/gpu/drm/mediatek/Makefile                     | 2 +-
 drivers/gpu/drm/mediatek/mtk_crtc.c                   | 2 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c                | 2 +-
 drivers/gpu/drm/mediatek/{mtk_drm_gem.c => mtk_gem.c} | 2 +-
 drivers/gpu/drm/mediatek/{mtk_drm_gem.h => mtk_gem.h} | 0
 drivers/gpu/drm/mediatek/mtk_plane.c                  | 2 +-
 6 files changed, 5 insertions(+), 5 deletions(-)
 rename drivers/gpu/drm/mediatek/{mtk_drm_gem.c => mtk_gem.c} (99%)
 rename drivers/gpu/drm/mediatek/{mtk_drm_gem.h => mtk_gem.h} (100%)

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 0e198c00c6f2..7e6d4b2fadbf 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -11,7 +11,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_crtc.o \
 		  mtk_ddp_comp.o \
 		  mtk_drm_drv.o \
-		  mtk_drm_gem.o \
+		  mtk_gem.o \
 		  mtk_plane.o \
 		  mtk_dsi.o \
 		  mtk_dpi.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
index 96af194d0d49..7fe234de83a3 100644
--- a/drivers/gpu/drm/mediatek/mtk_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
@@ -22,7 +22,7 @@
 #include "mtk_drm_drv.h"
 #include "mtk_crtc.h"
 #include "mtk_ddp_comp.h"
-#include "mtk_drm_gem.h"
+#include "mtk_gem.h"
 #include "mtk_plane.h"
 
 /*
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 113fdbaac5a1..b62320f64882 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -27,7 +27,7 @@
 #include "mtk_crtc.h"
 #include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
-#include "mtk_drm_gem.h"
+#include "mtk_gem.h"
 
 #define DRIVER_NAME "mediatek"
 #define DRIVER_DESC "Mediatek SoC DRM"
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_gem.c
similarity index 99%
rename from drivers/gpu/drm/mediatek/mtk_drm_gem.c
rename to drivers/gpu/drm/mediatek/mtk_gem.c
index 3ae1f12bfb46..0fd55117ebf7 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/drivers/gpu/drm/mediatek/mtk_gem.c
@@ -12,7 +12,7 @@
 #include <drm/drm_prime.h>
 
 #include "mtk_drm_drv.h"
-#include "mtk_drm_gem.h"
+#include "mtk_gem.h"
 
 static int mtk_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.h b/drivers/gpu/drm/mediatek/mtk_gem.h
similarity index 100%
rename from drivers/gpu/drm/mediatek/mtk_drm_gem.h
rename to drivers/gpu/drm/mediatek/mtk_gem.h
diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
index 95a4328a9b0b..4625deb21d40 100644
--- a/drivers/gpu/drm/mediatek/mtk_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_plane.c
@@ -16,7 +16,7 @@
 #include "mtk_crtc.h"
 #include "mtk_ddp_comp.h"
 #include "mtk_drm_drv.h"
-#include "mtk_drm_gem.h"
+#include "mtk_gem.h"
 #include "mtk_plane.h"
 
 static const u64 modifiers[] = {
-- 
2.18.0



From angelogioacchino.delregno at collabora.com  Mon Feb 26 00:54:07 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 09:54:07 +0100
Subject: [PATCH] arm64: dts: mediatek: mt8183: Add power-domains properity
 to mfgcfg
In-Reply-To: <20240223091122.2430037-1-wenst@chromium.org>
References: <20240223091122.2430037-1-wenst@chromium.org>
Message-ID: <feab2039-5745-41a4-87c3-44fa266efc1d@collabora.com>

Il 23/02/24 10:11, Chen-Yu Tsai ha scritto:
> From: Ikjoon Jang <ikjn at chromium.org>
> 
> mfgcfg clock is under MFG_ASYNC power domain.
> 
> Fixes: e526c9bc11f8 ("arm64: dts: Add Mediatek SoC MT8183 and evaluation board dts and Makefile")
> Fixes: 37fb78b9aeb7 ("arm64: dts: mediatek: Add mt8183 power domains controller")
> Signed-off-by: Weiyi Lu <weiyi.lu at mediatek.com>
> Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
> Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
> This patch is long overdue. Could we merge it for fixes for this or the
> next release?
> 

A clock controller that needs a power domain? Can you please describe the issue
that you're trying to solve with this?

It's not very uncommon but I'm not entirely convinced that this is right, because
the MFG_BG3D is a gate - and it's *not* outputting a clock rate on its own: the
mfgcfg is entirely GPU related and if there is no GPU support this clock is not
even ever needed.

MediaTek, can you please clarify if (and why) this gate clock needs a MTCMOS to
be ungated?

Thanks,
Angelo

> Changes since v2:
> - Rebased onto current tree
> - Added Fixes tags
> - Fix up subject prefix
> 
>   arch/arm64/boot/dts/mediatek/mt8183.dtsi | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> index 93dfbf130231..774ae5d9143f 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> @@ -1637,6 +1637,7 @@ mfgcfg: syscon at 13000000 {
>   			compatible = "mediatek,mt8183-mfgcfg", "syscon";
>   			reg = <0 0x13000000 0 0x1000>;
>   			#clock-cells = <1>;
> +			power-domains = <&spm MT8183_POWER_DOMAIN_MFG_ASYNC>;
>   		};
>   
>   		gpu: gpu at 13040000 {




From angelogioacchino.delregno at collabora.com  Mon Feb 26 00:56:13 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 09:56:13 +0100
Subject: [PATCH V2 1/4] dt-bindings: vendor-prefixes: add Cudy
In-Reply-To: <20240223101709.30072-2-zajec5@gmail.com>
References: <20240223101709.30072-1-zajec5@gmail.com>
 <20240223101709.30072-2-zajec5@gmail.com>
Message-ID: <7e0a003c-7016-4de7-a193-2db28995e6ea@collabora.com>

Il 23/02/24 11:17, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Cudy is a Chinese company providing networking products.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Feb 26 00:56:32 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 09:56:32 +0100
Subject: [PATCH V2 3/4] arm64: dts: mediatek: mt7981: add pinctrl
In-Reply-To: <20240223101709.30072-4-zajec5@gmail.com>
References: <20240223101709.30072-1-zajec5@gmail.com>
 <20240223101709.30072-4-zajec5@gmail.com>
Message-ID: <70cda6ba-b6d4-4343-9afd-2a1978150f84@collabora.com>

Il 23/02/24 11:17, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> MT7981 contains on-SoC PIN controller that is also a GPIO provider.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Feb 26 00:58:50 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 09:58:50 +0100
Subject: [PATCH V2 4/4] arm64: dts: mediatek: Add Cudy WR3000 V1
In-Reply-To: <20240223101709.30072-5-zajec5@gmail.com>
References: <20240223101709.30072-1-zajec5@gmail.com>
 <20240223101709.30072-5-zajec5@gmail.com>
Message-ID: <9c114a61-ad19-4852-96c8-dbcbe8d8e38c@collabora.com>

Il 23/02/24 11:17, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Cudy WR3000 V1 is an MT7981B (AKA Filogic 820) based wireless router. It
> has 256 MiB of RAM, some LEDs & buttons and (not described yet) 4
> Ethernet ports.
> 
> There is one slightly uncommon LED with a label of globe icon described
> in the Quick Installation Guide as having 2 meanings:
> 1. "Not connected to the Internet"
> 2. "Connected to the Internet"
> 
> Vendor designed it to light up when some Internet-accessible IP can be
> reached. This change will be follow by an attempt to define some
> predefined FUNCTION for it.

Can we please try to add that predefined function before adding this devicetree
which would anyway be modified again to use that new definition?

That just makes more sense...

...if you can't get the new definition picked, I will take this one as is, but
please try that first.

Cheers,
Angelo



From krzysztof.kozlowski at linaro.org  Mon Feb 26 00:59:06 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 26 Feb 2024 09:59:06 +0100
Subject: [PATCH] arm64: dts: Adapt TCPC compatible
In-Reply-To: <20240222211242.210340-1-m.felsch@pengutronix.de>
References: <20240222211242.210340-1-m.felsch@pengutronix.de>
Message-ID: <549519dc-9787-436f-a3e0-49ba0bce2e70@linaro.org>

On 22/02/2024 22:12, Marco Felsch wrote:
> Add the new fallback binding to all devicetrees which do have a
> nxp,ptn5110 node to not cause any dt-validation regression.
> 
> Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
> ---
> Hi,
> 
> this requires patchset
> https://lore.kernel.org/all/20240222210903.208901-1-m.felsch at pengutronix.de/
> to be applied.
> 

Subject - missing prefix and a bit unspecific name. E.g.:

arm64: dts: freescale (or imx): Add TCPC fallback compatible to PTN5110

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzysztof.kozlowski at linaro.org  Mon Feb 26 01:00:26 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 26 Feb 2024 10:00:26 +0100
Subject: [PATCH] dt-bindings: mmc: fsl-imx-esdhc: add default and 100mhz
 state
In-Reply-To: <20240221184602.3639619-1-m.felsch@pengutronix.de>
References: <20240221184602.3639619-1-m.felsch@pengutronix.de>
Message-ID: <c9ff7541-ed51-4f59-884c-b63577cad834@linaro.org>

On 21/02/2024 19:46, Marco Felsch wrote:
> Some devices support only the default and the 100MHz case, add the
> support for this to the binding to avoid warnings.
> 
> Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From abel.vesa at linaro.org  Mon Feb 26 01:04:28 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Mon, 26 Feb 2024 11:04:28 +0200
Subject: [PATCH] clk: imx: imx8mp: Fix SAI_MCLK_SEL definition
In-Reply-To: <1708683351-8504-1-git-send-email-shengjiu.wang@nxp.com>
References: <1708683351-8504-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <ZdxUHAg2UZOU/s4h@linaro.org>

On 24-02-23 18:15:51, Shengjiu Wang wrote:
> There is SAI1, SAI2, SAI3, SAI5, SAI6, SAI7 existing in this block
> control, the order is discontinuous. The definition of SAI_MCLK_SEL(n)
> is not match with the usage of CLK_SAIn(n).
> 
> So define SAI##n##_MCLK_SEL separately to fix the issue.
> 
> Fixes: 6cd95f7b151c ("clk: imx: imx8mp: Add audiomix block control")
> Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>

Reviewed-by: Abel Vesa <abel.vesa at linaro.org>

> ---
>  drivers/clk/imx/clk-imx8mp-audiomix.c | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-imx8mp-audiomix.c b/drivers/clk/imx/clk-imx8mp-audiomix.c
> index e4300df88f1a..55ed211a5e0b 100644
> --- a/drivers/clk/imx/clk-imx8mp-audiomix.c
> +++ b/drivers/clk/imx/clk-imx8mp-audiomix.c
> @@ -18,7 +18,12 @@
>  
>  #define CLKEN0			0x000
>  #define CLKEN1			0x004
> -#define SAI_MCLK_SEL(n)		(0x300 + 4 * (n))	/* n in 0..5 */
> +#define SAI1_MCLK_SEL		0x300
> +#define SAI2_MCLK_SEL		0x304
> +#define SAI3_MCLK_SEL		0x308
> +#define SAI5_MCLK_SEL		0x30C
> +#define SAI6_MCLK_SEL		0x310
> +#define SAI7_MCLK_SEL		0x314
>  #define PDM_SEL			0x318
>  #define SAI_PLL_GNRL_CTL	0x400
>  
> @@ -95,13 +100,13 @@ static const struct clk_parent_data clk_imx8mp_audiomix_pll_bypass_sels[] = {
>  		IMX8MP_CLK_AUDIOMIX_SAI##n##_MCLK1_SEL, {},		\
>  		clk_imx8mp_audiomix_sai##n##_mclk1_parents,		\
>  		ARRAY_SIZE(clk_imx8mp_audiomix_sai##n##_mclk1_parents), \
> -		SAI_MCLK_SEL(n), 1, 0					\
> +		SAI##n##_MCLK_SEL, 1, 0					\
>  	}, {								\
>  		"sai"__stringify(n)"_mclk2_sel",			\
>  		IMX8MP_CLK_AUDIOMIX_SAI##n##_MCLK2_SEL, {},		\
>  		clk_imx8mp_audiomix_sai_mclk2_parents,			\
>  		ARRAY_SIZE(clk_imx8mp_audiomix_sai_mclk2_parents),	\
> -		SAI_MCLK_SEL(n), 4, 1					\
> +		SAI##n##_MCLK_SEL, 4, 1					\
>  	}, {								\
>  		"sai"__stringify(n)"_ipg_cg",				\
>  		IMX8MP_CLK_AUDIOMIX_SAI##n##_IPG,			\
> -- 
> 2.34.1
> 


From abel.vesa at linaro.org  Mon Feb 26 01:08:44 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Mon, 26 Feb 2024 11:08:44 +0200
Subject: clk: imx: scu: Use common error handling code in
 __imx_clk_gpr_scu()
In-Reply-To: <1a3c05b8-45f8-4205-8cb5-3b8f2d791877@web.de>
References: <20231210171907.3410922-1-visitorckw@gmail.com>
 <0e906ec6-fe73-4dbd-b555-a2c03b6e1030@web.de>
 <Zb04UUeE/cU9HtKZ@linaro.org>
 <1a3c05b8-45f8-4205-8cb5-3b8f2d791877@web.de>
Message-ID: <ZdxVHLce6mk975Zp@linaro.org>

On 24-02-02 21:21:19, Markus Elfring wrote:
> >> Use another label so that a bit of exception handling can be better reused
> >> at the end of this function.
> >
> > Please don't send patches as reply to other(s) patches.
> 
> This is a general possibility to connect an information sources with
> a corresponding change idea.
> Will the acceptance grow for the presented source code transformation?
> 

Nope, please don't do that. The b4 tool will pick up the old patch if
you do this.

> Regards,
> Markus


From tudor.ambarus at linaro.org  Mon Feb 26 01:09:55 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 26 Feb 2024 11:09:55 +0200
Subject: [PATCH v4 16/39] spi: dt-bindings: atmel,at91rm9200-spi: remove
 9x60 compatible from list
In-Reply-To: <20240223172638.672366-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172638.672366-1-varshini.rajendran@microchip.com>
Message-ID: <19da0e57-379b-4db3-ba8e-db7efe336e15@linaro.org>



On 23.02.2024 19:26, Varshini Rajendran wrote:
> Remove microchip,sam9x60-spi compatible from the list as the driver used
> has the compatible atmel,at91rm9200-spi and sam9x60 devices also use the
> same compatible as fallback. So removing the microchip,sam9x60-spi
> compatible from the list since it is not needed.
> 

I find this wrong. I though we shall add compatibles for each SoC. Are
the registers and fields the same for the SPI IPs in these 2 SoCs? Even
if they are the same, are you sure the IPs are integrated in the same way?

> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> ---
> Changes in v4:
> - Elaborated the explanation in the commit message to justify the patch
> ---
>  Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml b/Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml
> index 58367587bfbc..32e7c14033c2 100644
> --- a/Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml
> +++ b/Documentation/devicetree/bindings/spi/atmel,at91rm9200-spi.yaml
> @@ -22,7 +22,6 @@ properties:
>            - const: atmel,at91rm9200-spi
>        - items:
>            - const: microchip,sam9x7-spi
> -          - const: microchip,sam9x60-spi
>            - const: atmel,at91rm9200-spi
>  
>    reg:


From kieran.bingham at ideasonboard.com  Mon Feb 26 01:12:16 2024
From: kieran.bingham at ideasonboard.com (Kieran Bingham)
Date: Mon, 26 Feb 2024 09:12:16 +0000
Subject: [PATCH v2 4/5] media: Documentation: Add Mali-C55 ISP Documentation
In-Reply-To: <f99c9e34-182a-4b92-9ba4-050d6724f5e5@ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com> <20240214141906.245685-5-dan.scally@ideasonboard.com> <170889617240.914352.11519004661256637360@ping.linuxembedded.co.uk> <f99c9e34-182a-4b92-9ba4-050d6724f5e5@ideasonboard.com>
Message-ID: <170893873667.1011926.18284546733096440304@ping.linuxembedded.co.uk>

Quoting Dan Scally (2024-02-26 07:48:44)
> Morning Kieran
> 
> On 25/02/2024 21:22, Kieran Bingham wrote:
> > Hi Dan,
> >
> > Quoting Daniel Scally (2024-02-14 14:19:05)
> >> Add a documentation page for the mali-c55 driver, which gives a brief
> >> overview of the hardware and explains how to use the driver's capture
> >> devices and the crop/scaler functions.
> >>
> >> Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> >> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> >> ---
> >> Changes in v2:
> >>
> >>          - none
> >>
> >>   .../admin-guide/media/mali-c55-graph.dot      |  19 ++
> >>   Documentation/admin-guide/media/mali-c55.rst  | 318 ++++++++++++++++++
> >>   .../admin-guide/media/v4l-drivers.rst         |   1 +
> >>   3 files changed, 338 insertions(+)
> >>   create mode 100644 Documentation/admin-guide/media/mali-c55-graph.dot
> >>   create mode 100644 Documentation/admin-guide/media/mali-c55.rst
> >>
> >> diff --git a/Documentation/admin-guide/media/mali-c55-graph.dot b/Documentation/admin-guide/media/mali-c55-graph.dot
> >> new file mode 100644
> >> index 000000000000..0775ba42bf4c
> >> --- /dev/null
> >> +++ b/Documentation/admin-guide/media/mali-c55-graph.dot
> >> @@ -0,0 +1,19 @@
> >> +digraph board {
> >> +        rankdir=TB
> >> +        n00000001 [label="{{} | mali-c55 tpg\n/dev/v4l-subdev0 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
> >> +        n00000001:port0 -> n00000003:port0 [style=dashed]
> >> +        n00000003 [label="{{<port0> 0} | mali-c55 isp\n/dev/v4l-subdev1 | {<port1> 1 | <port2> 2}}", shape=Mrecord, style=filled, fillcolor=green]
> >> +        n00000003:port1 -> n00000007:port0 [style=bold]
> >> +        n00000003:port2 -> n00000007:port2 [style=bold]
> >> +        n00000003:port1 -> n0000000b:port0 [style=bold]
> >> +        n00000007 [label="{{<port0> 0 | <port2> 2} | mali-c55 resizer fr\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
> >> +        n00000007:port1 -> n0000000e [style=bold]
> >> +        n0000000b [label="{{<port0> 0} | mali-c55 resizer ds\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
> >> +        n0000000b:port1 -> n00000012 [style=bold]
> >> +        n0000000e [label="mali-c55 fr\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
> >> +        n00000012 [label="mali-c55 ds\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
> >> +        n00000022 [label="{{<port0> 0} | csi2-rx\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
> >> +        n00000022:port1 -> n00000003:port0
> >> +        n00000027 [label="{{} | imx415 1-001a\n/dev/v4l-subdev5 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
> >> +        n00000027:port0 -> n00000022:port0 [style=bold]
> >> +}
> >> \ No newline at end of file
> >> diff --git a/Documentation/admin-guide/media/mali-c55.rst b/Documentation/admin-guide/media/mali-c55.rst
> >> new file mode 100644
> >> index 000000000000..83f630c3bd9d
> >> --- /dev/null
> >> +++ b/Documentation/admin-guide/media/mali-c55.rst
> >> @@ -0,0 +1,318 @@
> >> +.. SPDX-License-Identifier: GPL-2.0
> >> +
> >> +==========================================
> >> +ARM Mali-C55 Image Signal Processor driver
> >> +==========================================
> >> +
> >> +Introduction
> >> +============
> >> +
> >> +This file documents the driver for ARM's Mali-C55 Image Signal Processor. The
> >> +driver is located under drivers/media/platform/arm/mali-c55.
> >> +
> >> +The Mali-C55 ISP receives data in either raw Bayer format or RGB/YUV format from
> >> +sensors through either a parallel interface or a memory bus before processing it
> >> +and outputting it through an internal DMA engine. Two output pipelines are
> >> +possible (though one may not be fitted, depending on the implementation). These
> >> +are referred to as "Full resolution" and "Downscale", but the naming is historic
> >> +and both pipes are capable of cropping/scaling operations. An integrated test
> >> +pattern generator can be used to drive the ISP and produce image data in the
> >> +absence of a connected camera sensor. The driver module is named mali_c55, and
> >> +is enabled through the CONFIG_VIDEO_MALI_C55 config option.
> > Can it handle metadata or other datatypes separately? anything else
> > that's worthy of mention? Or maybe not yet in this version.
> 
> 
> As in, can you stream the parameters/statistics without streaming video data? Not at present but the 
> change to add that ability would be very very minor - though none of that is in this version.

It was other stream data I was curious about clarifying. I think the
answer is the same though, not yet in this version, but will be added on
top.


> >> +
> >> +The driver implements V4L2, Media Controller and V4L2 Subdevice interfaces and
> >> +expects camera sensors connected to the ISP to have V4L2 subdevice interfaces.
> >> +
> >> +Mali-C55 ISP hardware
> >> +=====================
> >> +
> >> +A high level functional view of the Mali-C55 ISP is presented below. The ISP
> >> +takes input from either a live source or through a DMA engine for memory input,
> >> +depending on the SoC integration.::
> >> +
> >> +  +---------+    +----------+                                     +--------+
> >> +  | Sensor  |--->| CSI-2 Rx |                "Full Resolution"    |  DMA   |
> >> +  +---------+    +----------+   |\                 Output    +--->| Writer |
> >> +                       |        | \                          |    +--------+
> >> +                       |        |  \    +----------+  +------+---> Streaming I/O
> >> +  +------------+       +------->|   |   |          |  |
> >> +  |            |                |   |-->| Mali-C55 |--+
> >> +  | DMA Reader |--------------->|   |   |    ISP   |  |
> >> +  |            |                |  /    |          |  |      +---> Streaming I/O
> >> +  +------------+                | /     +----------+  |      |
> >> +                                |/                    +------+
> >> +                                                            |    +--------+
> >> +                                                             +--->|  DMA   |
> >> +                                               "Downscaled"       | Writer |
> >> +                                                 Output          +--------+
> >> +
> >> +Media Controller Topology
> >> +=========================
> >> +
> >> +An example of the ISP's topology (as implemented in a system with an IMX415
> >> +camera sensor and generic CSI-2 receiver) is below:
> >> +
> >> +
> >> +.. kernel-figure:: mali-c55-graph.dot
> >> +    :alt:   mali-c55-graph.dot
> >> +    :align: center
> >> +
> >> +The driver has 4 V4L2 subdevices:
> >> +
> >> +- `mali_c55 isp`: Responsible for configuring input crop and color space
> >> +                  conversion
> >> +- `mali_c55 tpg`: The test pattern generator, emulating a camera sensor.
> >> +- `mali_c55 resizer fr`: The Full-Resolution pipe resizer
> >> +- `mali_c55 resizer ds`: The Downscale pipe resizer
> >> +
> >> +The driver has 2 V4L2 video devices:
> >> +
> >> +- `mali-c55 fr`: The full-resolution pipe's capture device
> >> +- `mali-c55 ds`: The downscale pipe's capture device
> >> +
> >> +Idiosyncrasies
> >> +--------------
> >> +
> >> +**mali-c55 isp**
> >> +The `mali-c55 isp` subdevice has a single sink pad to which all sources of data
> >> +should be connected. The active source is selected by enabling the appropriate
> >> +media link and disabling all others.
> > By that I presume you mean you can only accept a single input link at a
> > time?
> 
> 
> Yes
> 
> >
> >> The ISP has two source pads, reflecting the
> >> +different paths through which it can internally route data. Tap points within
> >> +the ISP allow users to divert data to avoid processing by some or all of the
> >> +hardware's processing steps. The diagram below is intended only to highlight how
> >> +the bypassing works and is not a true reflection of those processing steps; for
> >> +a high-level functional block diagram see ARM's developer page for the
> >> +ISP [3]_::
> >> +
> >> +  +--------------------------------------------------------------+
> >> +  |                Possible Internal ISP Data Routes             |
> >> +  |          +------------+  +----------+  +------------+        |
> >> +  +---+      |            |  |          |  |  Colour    |    +---+
> >> +  | 0 |--+-->| Processing |->| Demosaic |->|   Space    |--->| 1 |
> >> +  +---+  |   |            |  |          |  | Conversion |    +---+
> >> +  |      |   +------------+  +----------+  +------------+        |
> >> +  |      |                                                   +---+
> >> +  |      +---------------------------------------------------| 2 |
> >> +  |                                                          +---+
> >> +  |                                                              |
> >> +  +--------------------------------------------------------------+
> >> +
> >> +
> >> +.. flat-table::
> >> +    :header-rows: 1
> >> +
> >> +    * - Pad
> >> +      - Direction
> >> +      - Purpose
> >> +
> >> +    * - 0
> >> +      - sink
> >> +      - Data input, connected to the TPG and camera sensors
> >> +
> >> +    * - 1
> >> +      - source
> >> +      - RGB/YUV data, connected to the FR and DS V4L2 subdevices
> >> +
> >> +    * - 2
> >> +      - source
> >> +      - RAW bayer data, connected to the FR V4L2 subdevices
> >> +
> >> +**mali-c55 resizer fr**
> >> +The `mali-c55 resizer fr` subdevice has two _sink_ pads to reflect the different
> >> +insertion points in the hardware (either RAW or demosaiced data):
> >> +
> >> +.. flat-table::
> >> +    :header-rows: 1
> >> +
> >> +    * - Pad
> >> +      - Direction
> >> +      - Purpose
> >> +
> >> +    * - 0
> >> +      - sink
> >> +      - Data input connected to the ISP's demosaiced stream.
> >> +
> >> +    * - 1
> >> +      - source
> >> +      - Data output connected to the capture video device
> >> +
> >> +    * - 2
> >> +      - sink
> >> +      - Data input connected to the ISP's raw data stream
> >> +
> >> +The data source in use is selected through the routing API; two routes each of a
> >> +single stream are available:
> >> +
> >> +.. flat-table::
> >> +    :header-rows: 1
> >> +
> >> +    * - Sink Pad
> >> +      - Source Pad
> >> +      - Purpose
> >> +
> >> +    * - 0
> >> +      - 1
> >> +      - Demosaiced data route
> >> +
> >> +    * - 2
> >> +      - 1
> >> +      - Raw data route
> >> +
> >> +
> >> +If the demosaiced route is active then the FR pipe is only capable of output
> >> +in RGB/YUV formats. If the raw route is active then the output reflects the
> >> +input (which may be either Bayer or RGB/YUV data).
> >> +
> >> +Using the driver to capture video
> >> +=================================
> >> +
> >> +Using the media controller APIs we can configure the input source and ISP to
> >> +capture images in a variety of formats. In the examples below, configuring the
> >> +media graph is done with the v4l-utils [1]_ package's media-ctl utility.
> >> +Capturing the images is done with yavta [2]_.
> >> +
> >> +Configuring the input source
> >> +----------------------------
> >> +
> >> +The first step is to set the input source that we wish by enabling the correct
> >> +media link. Using the example topology above, we can select the TPG as follows:
> >> +
> >> +.. code-block:: none
> >> +
> >> +    media-ctl -l "'lte-csi2-rx':1->'mali-c55 isp':0[0]"
> >> +    media-ctl -l "'mali-c55 tpg':0->'mali-c55 isp':0[1]"
> >> +
> >> +Capturing bayer data from the source and processing to RGB/YUV
> >> +--------------------------------------------------------------
> >> +To capture 1920x1080 bayer data from the source and push it through the ISP's
> >> +full processing pipeline, we configure the data formats appropriately on the
> >> +source, ISP and resizer subdevices and set the FR resizer's routing to select
> >> +processed data. The media bus format on the resizer's source pad will be either
> >> +RGB121212_1X36 or YUV10_1X30, depending on whether you want to capture RGB or
> >> +YUV. The ISP's debayering block outputs RGB data natively, setting the source
> >> +pad format to YUV10_1X30 enables the colour space conversion block.
> >> +
> >> +In this example we target RGB565 output, so select RGB121212_1X36 as the resizer
> >> +source pad's format:
> >> +
> >> +.. code-block:: none
> >> +
> >> +    # Set formats on the TPG and ISP
> >> +    media-ctl -V "'mali-c55 tpg':0[fmt:SRGGB16_1X16/1920x1080]"
> >> +    media-ctl -V "'mali-c55 isp':0[fmt:SRGGB16_1X16/1920x1080]"
> >> +    media-ctl -V "'mali-c55 isp':1[fmt:SRGGB16_1X16/1920x1080]"
> >> +
> >> +    # Set routing on the FR resizer
> >> +    media-ctl -R "'mali-c55 resizer fr'[0/0->1/0[1],2/0->1/0[0]]"
> >> +
> >> +    # Set format on the resizer, must be done AFTER the routing.
> >> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/1920x1080]"
> >> +
> >> +The downscale output can also be used to stream data at the same time. In this
> >> +case only processed data can be captured and so no routing need be set:
> > Is the route automatically reset? or is it just that the default route
> > is already the correct choice for this instance?
> 
> 
> Err, the default route is already the correct choice for this instance but I'm nonetheless setting 
> it above...perhaps I'm misunderstanding the question?

My question was on why the text stated "and so no routing need be set:"

> >> +
> >> +.. code-block:: none
> >> +
> >> +    # Set format on the resizer
> >> +    media-ctl -V "'mali-c55 resizer ds':1[fmt:RGB121212_1X36/1920x1080]"
> >> +
> >> +Following which images can be captured from both the FR and DS output's video
> >> +devices (simultaneously, if desired):
> >> +
> >> +.. code-block:: none
> >> +
> >> +    yavta -f RGB565 -s 1920x1080 -c10 /dev/video0
> >> +    yavta -f RGB565 -s 1920x1080 -c10 /dev/video1
> >> +
> > Is there any synchronisation required? Can one pipe run without the
> > other if they are both enabled? or will stalling on one pipe stall the
> > other?
> 
> 
> The outputs are synchronised already to the extent that if both are enabled they'll receive data 
> from the same input frame at the same time. They can be run independently though, if an application 
> stopped queuing frames to one but continued queuing to the other then the latter would work fine.
> 
> >
> >> +Cropping the image
> >> +~~~~~~~~~~~~~~~~~~
> >> +
> >> +Both the full resolution and downscale pipes can crop to a minimum resolution of
> >> +640x480. To crop the image simply configure the resizer's sink pad's crop and
> >> +compose rectangles and set the format on the video device:
> >> +
> >> +.. code-block:: none
> >> +
> >> +    media-ctl -V "'mali-c55 resizer fr':0[fmt:RGB121212_1X36/1920x1080 crop:(480,270)/640x480 compose:(0,0)/640x480]"
> >> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/640x480]"
> >> +    yavta -f RGB565 -s 640x480 -c10 /dev/video0
> >> +
> >> +Downscaling the image
> >> +~~~~~~~~~~~~~~~~~~~~~
> >> +
> >> +Both the full resolution and downscale pipes can downscale the image by up to 8x
> >> +provided the minimum 640x480 resolution is adhered to. For the best image result
> > 'minimum 640x480 output resolution' I presume.
> 
> 
> And input, actually.
> 
> >
> > Maybe the ISP limits/restrictions need to be defined before here?
> 
> 
> I'll expand on them yes.
> 
> >
> >> +the scaling ratio for each dimension should be the same. To configure scaling we
> >> +use the compose rectangle on the resizer's sink pad:
> >> +
> >> +.. code-block:: none
> >> +
> >> +    media-ctl -V "'mali-c55 resizer fr':0[fmt:RGB121212_1X36/1920x1080 crop:(0,0)/1920x1080 compose:(0,0)/640x480]"
> >> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:RGB121212_1X36/640x480]"
> >> +    yavta -f RGB565 -s 640x480 -c10 /dev/video0
> >> +
> >> +Capturing images in YUV formats
> >> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >> +
> >> +If we need to output YUV data rather than RGB the color space conversion block
> >> +needs to be active, which is achieved by setting MEDIA_BUS_FMT_YUV10_1X30 on the
> > Is 10 bit required here? (As opposed to the 12 bit before in the
> > pipeline? is that a limitation on the component?)
> 
> 
> It's a reflection of the output from the colour-space conversion block.
> 
> > or is this to match
> > the desired output format?
> 
> 
> Sort of, it's used to inform the driver about which of the output formats can be generated - without 
> conversion to YUV here only RGB formats can be set on the capture device nodes.

Hrm, sorry - my question is why we went from 12 bit to 10 bit in the
example. Maybe we need to document the capabilities of each stage if the
bitdepth will be reduced by force somewhere along the pipe?

> >> +resizer's source pad. We can then configure a capture format like NV12 (here in
> >> +its multi-planar variant)
> >> +
> >> +.. code-block:: none
> >> +
> >> +    media-ctl -V "'mali-c55 resizer fr':1[fmt:YUV10_1X30/1920x1080]"
> >> +    yavta -f NV12M -s 1920x1080 -c10 /dev/video0
> >> +
> >> +Capturing RGB data from the source and processing it with the resizers
> >> +----------------------------------------------------------------------
> >> +
> >> +The Mali-C55 ISP can work with sensors capable of outputting RGB data. In this
> >> +case although none of the image quality blocks would be used it can still
> >> +crop/scale the data in the usual way.
> >> +
> >> +To achieve this, the ISP's sink pad's format is set to
> >> +MEDIA_BUS_FMT_RGB202020_1X60 - this reflects the format that data must be in to
> >> +work with the ISP. Converting the camera sensor's output to that format is the
> >> +responsibility of external hardware.
> >> +
> >> +In this example we ask the test pattern generator to give us RGB data instead of
> >> +bayer.
> >> +
> >> +.. code-block:: none
> >> +
> >> +    media-ctl -V "'mali-c55 tpg':0[fmt:RGB202020_1X60/1920x1080]"
> >> +    media-ctl -V "'mali-c55 isp':0[fmt:RGB202020_1X60/1920x1080]"
> >> +
> >> +Cropping or scaling the data can be done in exactly the same way as outlined
> >> +earlier.
> >> +
> >> +Capturing raw data from the source and outputting it unmodified
> >> +-----------------------------------------------------------------
> >> +
> >> +The ISP can additionally capture raw data from the source and output it on the
> >> +full resolution pipe only, completely unmodified. In this case the downscale
> >> +pipe can still process the data normally and be used at the same time.
> >> +
> >> +To configure raw bypass the FR resizer's subdevice's routing table needs to be
> >> +configured, followed by formats in the appropriate places:
> >> +
> >> +.. code-block:: none
> >> +
> >> +    # We need to configure the routing table for the resizer to use the bypass
> >> +    # path along with set formats on the resizer's bypass sink pad. Doing this
> >> +    # necessitates a single media-ctl command, as multiple calls to the program
> >> +    # reset the routing table.
> >> +    media-ctl -R "'mali-c55 resizer fr'[0/0->1/0[0],2/0->1/0[1]]"\
> >> +    -V "'mali-c55 isp':0[fmt:RGB202020_1X60/1920x1080],"\
> >> +       "'mali-c55 resizer fr':2[fmt:RGB202020_1X60/1920x1080],"\
> >> +       "'mali-c55 resizer fr':1[fmt:RGB202020_1X60/1920x1080]"
> >> +
> >> +    # Set format on the video device and stream
> >> +    yavta -f RGB565 -s 1920x1080 -c10 /dev/video0
> >> +
> >> +References
> >> +==========
> >> +.. [1] https://git.linuxtv.org/v4l-utils.git/
> >> +.. [2] https://git.ideasonboard.org/yavta.git
> >> +.. [3] https://developer.arm.com/Processors/Mali-C55
> >> diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentation/admin-guide/media/v4l-drivers.rst
> >> index f4bb2605f07e..af033c892808 100644
> >> --- a/Documentation/admin-guide/media/v4l-drivers.rst
> >> +++ b/Documentation/admin-guide/media/v4l-drivers.rst
> >> @@ -17,6 +17,7 @@ Video4Linux (V4L) driver-specific documentation
> >>          imx7
> >>          ipu3
> >>          ivtv
> >> +       mali-c55
> >>          mgb4
> >>          omap3isp
> >>          omap4_camera
> >> -- 
> >> 2.34.1
> >>


From abel.vesa at linaro.org  Mon Feb 26 01:15:39 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Mon, 26 Feb 2024 11:15:39 +0200
Subject: [PATCH 0/2] clk: imx: composite-8m: Adjustments for __imx8m_clk_hw_composite()
In-Reply-To: <1d494176-2238-4430-bc26-4e4c78fe4ede@web.de>
References: <1d494176-2238-4430-bc26-4e4c78fe4ede@web.de>
Message-ID: <170893890773.1758840.9115935052552967417.b4-ty@linaro.org>


On Fri, 22 Dec 2023 17:33:19 +0100, Markus Elfring wrote:
> A few update suggestions were taken into account
> from source code analysis.
> 
> Markus Elfring (2):
>   Less function calls after error detection
>   Delete two unnecessary initialisations
> 
> [...]

Applied, thanks!

[1/2] clk: imx: composite-8m: Less function calls in __imx8m_clk_hw_composite() after error detection
      commit: fed6bf52c86df27ad4f39a72cdad8c27da9a50ba
[2/2] clk: imx: composite-8m: Delete two unnecessary initialisations in __imx8m_clk_hw_composite()
      commit: e1ed0b0362285981c575f12ae9e8b9dfe56a046c

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>


From abel.vesa at linaro.org  Mon Feb 26 01:16:24 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Mon, 26 Feb 2024 11:16:24 +0200
Subject: [PATCH] clk: imx: scu: Use common error handling code in
 imx_clk_scu_alloc_dev()
In-Reply-To: <01446ce9-c0e8-4467-8b2d-fd736bc5b8e4@web.de>
References: <01446ce9-c0e8-4467-8b2d-fd736bc5b8e4@web.de>
Message-ID: <170893898492.1768204.4132765783691588048.b4-ty@linaro.org>


On Fri, 22 Dec 2023 13:03:08 +0100, Markus Elfring wrote:
> Add a jump target so that a bit of exception handling can be better reused
> at the end of this function.
> 
> 

Applied, thanks!

[1/1] clk: imx: scu: Use common error handling code in imx_clk_scu_alloc_dev()
      commit: e4818d3b3f621e996b5a1d1a4913d11ccf769c24

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>



From abel.vesa at linaro.org  Mon Feb 26 01:16:48 2024
From: abel.vesa at linaro.org (Abel Vesa)
Date: Mon, 26 Feb 2024 11:16:48 +0200
Subject: [PATCH] clk: imx: imx8mp: Fix SAI_MCLK_SEL definition
In-Reply-To: <1708683351-8504-1-git-send-email-shengjiu.wang@nxp.com>
References: <1708683351-8504-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <170893900836.1770969.7795991183882277509.b4-ty@linaro.org>


On Fri, 23 Feb 2024 18:15:51 +0800, Shengjiu Wang wrote:
> There is SAI1, SAI2, SAI3, SAI5, SAI6, SAI7 existing in this block
> control, the order is discontinuous. The definition of SAI_MCLK_SEL(n)
> is not match with the usage of CLK_SAIn(n).
> 
> So define SAI##n##_MCLK_SEL separately to fix the issue.
> 
> 
> [...]

Applied, thanks!

[1/1] clk: imx: imx8mp: Fix SAI_MCLK_SEL definition
      commit: 13269dc6c70444528f0093585e3559cd2f38850a

Best regards,
-- 
Abel Vesa <abel.vesa at linaro.org>



From jarkko at kernel.org  Mon Feb 26 01:17:11 2024
From: jarkko at kernel.org (Jarkko Sakkinen)
Date: Mon, 26 Feb 2024 11:17:11 +0200
Subject: [PATCH v5 0/6] DCP as trusted keys backend
In-Reply-To: <1733761.uacIGzncQW@somecomputer>
References: <20231215110639.45522-1-david@sigma-star.at>
 <7AED262F-9387-446D-B11A-C549C02542F9@sigma-star.at>
 <47439997.XUcTiDjVJD@somecomputer> <1733761.uacIGzncQW@somecomputer>
Message-ID: <CZEWBSXM7LHU.15UW6P0T61VBN@suppilovahvero>

On Mon Feb 26, 2024 at 12:20 AM EET, Richard Weinberger wrote:
> Mimi, James, Jarkko, David,
>
> you remained silent for a whole release cycle.
> Is there anything we can do to get this forward?
>
> Thanks,
> //richard

Thanks for reminding.

>From my side, I've had pretty busy month as I've adapted to a new work
project: https://sochub.fi/

I exported the thread [1] and will look into it within this or next week
in detail (thus the large'ish time window).

[1] https://lore.kernel.org/linux-integrity/1733761.uacIGzncQW at somecomputer/t.mbox.gz

BR, Jarkko


From tudor.ambarus at linaro.org  Mon Feb 26 01:18:17 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 26 Feb 2024 11:18:17 +0200
Subject: [PATCH v4 03/39] dt-bindings: crypto: add sam9x7 in Atmel AES
In-Reply-To: <20240223172310.671661-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172310.671661-1-varshini.rajendran@microchip.com>
Message-ID: <4c1ee741-a0e9-41f0-99e1-5c2a6da06728@linaro.org>



On 23.02.2024 19:23, Varshini Rajendran wrote:
> Add DT bindings for atmel AES.
>

This would have deserved a better commit message, I (we) spent a lot of
time deciding whether this is the correct approach.
https://lore.kernel.org/linux-arm-kernel/342de8f3-852f-9bfa-39c4-4d820f349305 at linaro.org/

> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> Acked-by: Rob Herring <robh at kernel.org>

Anyway:
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
> Changes in v4:
> - Updated Acked-by tag
> ---
>  .../devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml   | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml
> index 0b7383b3106b..7dc0748444fd 100644
> --- a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml
> +++ b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-aes.yaml
> @@ -12,7 +12,11 @@ maintainers:
>  
>  properties:
>    compatible:
> -    const: atmel,at91sam9g46-aes
> +    oneOf:
> +      - const: atmel,at91sam9g46-aes
> +      - items:
> +          - const: microchip,sam9x7-aes
> +          - const: atmel,at91sam9g46-aes
>  
>    reg:
>      maxItems: 1


From zev at bewilderbeest.net  Mon Feb 26 01:17:53 2024
From: zev at bewilderbeest.net (Zev Weiss)
Date: Mon, 26 Feb 2024 01:17:53 -0800
Subject: [PATCH] ARM: dts: aspeed: ahe50dc: Update lm25066 regulator name
Message-ID: <20240226091754.16027-2-zev@bewilderbeest.net>

A recent change to the lm25066 driver changed the name of its
regulator from vout0 to vout; device-tree users of lm25066's regulator
functionality (of which ahe50dc is the only one) thus require a
corresponding update.

Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
Cc: Conor Dooley <conor+dt at kernel.org>
Cc: Guenter Roeck <linux at roeck-us.net>
---
 arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
index 6600f7e9bf5e..93f3be849071 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
@@ -18,7 +18,7 @@ efuse@##hexaddr {							\
 		reg = <0x##hexaddr>;						\
 		shunt-resistor-micro-ohms = <675>;				\
 		regulators {							\
-			efuse##num: vout0 {					\
+			efuse##num: vout {					\
 				regulator-name = __stringify(efuse##num##-reg);	\
 			};							\
 		};								\
-- 
2.43.2



From jiri at resnulli.us  Mon Feb 26 01:22:19 2024
From: jiri at resnulli.us (Jiri Pirko)
Date: Mon, 26 Feb 2024 10:22:19 +0100
Subject: [PATCH net-next v3] net: stmmac: mmc_core: Drop interrupt
 registers from stats
In-Reply-To: <20240223-stmmac_stats-v3-1-5d483c2a071a@axis.com>
References: <20240223-stmmac_stats-v3-1-5d483c2a071a@axis.com>
Message-ID: <ZdxYS6Fmd6NLScGC@nanopsycho>

Fri, Feb 23, 2024 at 09:37:01PM CET, jesper.nilsson at axis.com wrote:
>The MMC IPC interrupt status and interrupt mask registers are
>of little use as Ethernet statistics, but incrementing counters
>based on the current interrupt and interrupt mask registers
>makes them actively misleading.
>
>For example, if the interrupt mask is set to 0x08420842,
>the current code will increment by that amount each iteration,
>leading to the following sequence of nonsense:
>
>mmc_rx_ipc_intr_mask: 969816526
>mmc_rx_ipc_intr_mask: 1108361744
>
>These registers have been included in the Ethernet statistics
>since the first version of MMC back in 2011 (commit 1c901a46d57).
>That commit also mentions the MMC interrupts as
>"something to add later (if actually useful)".
>
>If the registers are actually useful, they should probably
>be part of the Ethernet register dump instead of statistics,
>but for now, drop the counters for mmc_rx_ipc_intr and
>mmc_rx_ipc_intr_mask completely.
>
>Reviewed-by: Serge Semin <fancer.lancer at gmail.com>
>Signed-off-by: Jesper Nilsson <jesper.nilsson at axis.com>

Reviewed-by: Jiri Pirko <jiri at nvidia.com>

[...]

>---
>base-commit: a08689109c5989acdc5c320de8e45324f6cfa791
>change-id: 20240216-stmmac_stats-e3561d460d0e


Not sure what this is good for...


From yilun.xu at linux.intel.com  Mon Feb 26 01:19:22 2024
From: yilun.xu at linux.intel.com (Xu Yilun)
Date: Mon, 26 Feb 2024 17:19:22 +0800
Subject: [PATCH v4 1/3] fpga: xilinx-spi: extract a common driver core
In-Reply-To: <20240221195058.1281973-2-charles.perry@savoirfairelinux.com>
References: <20240221195058.1281973-1-charles.perry@savoirfairelinux.com>
 <20240221195058.1281973-2-charles.perry@savoirfairelinux.com>
Message-ID: <ZdxXmof7r7JHahbM@yilunxu-OptiPlex-7050>

On Wed, Feb 21, 2024 at 02:50:47PM -0500, Charles Perry wrote:
> Factor out the gpio handshaking (using PROGRAM_B, INIT_B and DONE)
> protocol in xilinx-core so that it can be reused for another driver.
> This commit does not change anything functionally to xilinx-spi.
> 
> xilinx-core expects drivers to provide a single operation:
> 
>  * ->write(const char* buf, size_t count): write to the device
> 
> As well as a struct device* for resource management.
> 
> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
> ---
>  drivers/fpga/Kconfig       |   4 +
>  drivers/fpga/Makefile      |   1 +
>  drivers/fpga/xilinx-core.c | 208 ++++++++++++++++++++++++++++++++++++
>  drivers/fpga/xilinx-core.h |  28 +++++
>  drivers/fpga/xilinx-spi.c  | 212 +++----------------------------------
>  5 files changed, 254 insertions(+), 199 deletions(-)
>  create mode 100644 drivers/fpga/xilinx-core.c
>  create mode 100644 drivers/fpga/xilinx-core.h
> 
> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
> index 2f689ac4ba3a3..d27a1ebf40838 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -64,9 +64,13 @@ config FPGA_MGR_STRATIX10_SOC
>  	help
>  	  FPGA manager driver support for the Intel Stratix10 SoC.
>  
> +config FPGA_MGR_XILINX_CORE
> +	tristate
> +
>  config FPGA_MGR_XILINX_SPI
>  	tristate "Xilinx Configuration over Slave Serial (SPI)"
>  	depends on SPI
> +	select FPGA_MGR_XILINX_CORE
>  	help
>  	  FPGA manager driver support for Xilinx FPGA configuration
>  	  over slave serial interface.
> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
> index 352a2612623e0..7ec795b6a5a70 100644
> --- a/drivers/fpga/Makefile
> +++ b/drivers/fpga/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
>  obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
>  obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC)	+= stratix10-soc.o
>  obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
> +obj-$(CONFIG_FPGA_MGR_XILINX_CORE)	+= xilinx-core.o
>  obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
>  obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
>  obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA)	+= zynqmp-fpga.o
> diff --git a/drivers/fpga/xilinx-core.c b/drivers/fpga/xilinx-core.c
> new file mode 100644
> index 0000000000000..597e8b7a530b7
> --- /dev/null
> +++ b/drivers/fpga/xilinx-core.c
> @@ -0,0 +1,208 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Common parts of the Xilinx Spartan6 and 7 Series FPGA manager drivers.
> + *
> + * Copyright (C) 2017 DENX Software Engineering
> + *
> + * Anatolij Gustschin <agust at denx.de>
> + */
> +
> +#include "xilinx-core.h"
> +
> +#include <linux/delay.h>
> +#include <linux/fpga/fpga-mgr.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/of.h>
> +
> +static int get_done_gpio(struct fpga_manager *mgr)
> +{
> +	struct xilinx_fpga_core *core = mgr->priv;
> +	int ret;
> +
> +	ret = gpiod_get_value(core->done);
> +	if (ret < 0)
> +		dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret);
> +
> +	return ret;
> +}
> +
> +static enum fpga_mgr_states xilinx_core_state(struct fpga_manager *mgr)
> +{
> +	if (!get_done_gpio(mgr))
> +		return FPGA_MGR_STATE_RESET;
> +
> +	return FPGA_MGR_STATE_UNKNOWN;
> +}
> +
> +/**
> + * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
> + * a given delay if the pin is unavailable
> + *
> + * @mgr:        The FPGA manager object
> + * @value:      Value INIT_B to wait for (1 = asserted = low)
> + * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
> + *
> + * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
> + * too much time passed waiting for that. If no INIT_B GPIO is available
> + * then always return 0.
> + */
> +static int wait_for_init_b(struct fpga_manager *mgr, int value,
> +			   unsigned long alt_udelay)
> +{
> +	struct xilinx_fpga_core *core = mgr->priv;
> +	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
> +
> +	if (core->init_b) {
> +		while (time_before(jiffies, timeout)) {
> +			int ret = gpiod_get_value(core->init_b);
> +
> +			if (ret == value)
> +				return 0;
> +
> +			if (ret < 0) {
> +				dev_err(&mgr->dev,
> +					"Error reading INIT_B (%d)\n", ret);
> +				return ret;
> +			}
> +
> +			usleep_range(100, 400);
> +		}
> +
> +		dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n",
> +			value ? "assert" : "deassert");
> +		return -ETIMEDOUT;
> +	}
> +
> +	udelay(alt_udelay);
> +
> +	return 0;
> +}
> +
> +static int xilinx_core_write_init(struct fpga_manager *mgr,
> +				  struct fpga_image_info *info, const char *buf,
> +				  size_t count)
> +{
> +	struct xilinx_fpga_core *core = mgr->priv;
> +	int err;
> +
> +	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
> +		dev_err(&mgr->dev, "Partial reconfiguration not supported\n");
> +		return -EINVAL;
> +	}
> +
> +	gpiod_set_value(core->prog_b, 1);
> +
> +	err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */
> +	if (err) {
> +		gpiod_set_value(core->prog_b, 0);
> +		return err;
> +	}
> +
> +	gpiod_set_value(core->prog_b, 0);
> +
> +	err = wait_for_init_b(mgr, 0, 0);
> +	if (err)
> +		return err;
> +
> +	if (get_done_gpio(mgr)) {
> +		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
> +		return -EIO;
> +	}
> +
> +	/* program latency */
> +	usleep_range(7500, 7600);
> +	return 0;
> +}
> +
> +static int xilinx_core_write(struct fpga_manager *mgr, const char *buf,
> +			     size_t count)
> +{
> +	struct xilinx_fpga_core *core = mgr->priv;
> +
> +	return core->write(core, buf, count);
> +}
> +
> +static int xilinx_core_write_complete(struct fpga_manager *mgr,
> +				      struct fpga_image_info *info)
> +{
> +	struct xilinx_fpga_core *core = mgr->priv;
> +	unsigned long timeout =
> +		jiffies + usecs_to_jiffies(info->config_complete_timeout_us);
> +	bool expired = false;
> +	int done;
> +	int ret;
> +	const char padding[1] = { 0xff };
> +
> +	/*
> +	 * This loop is carefully written such that if the driver is
> +	 * scheduled out for more than 'timeout', we still check for DONE
> +	 * before giving up and we apply 8 extra CCLK cycles in all cases.
> +	 */
> +	while (!expired) {
> +		expired = time_after(jiffies, timeout);
> +
> +		done = get_done_gpio(mgr);
> +		if (done < 0)
> +			return done;
> +
> +		ret = core->write(core, padding, 1);
                                                 ^

sizeof(padding), Use as less immediate numbers as possible.

> +		if (ret)
> +			return ret;
> +
> +		if (done)
> +			return 0;
> +	}
> +
> +	if (core->init_b) {
> +		ret = gpiod_get_value(core->init_b);
> +
> +		if (ret < 0) {
> +			dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
> +			return ret;
> +		}
> +
> +		dev_err(&mgr->dev,
> +			ret ? "CRC error or invalid device\n" :
> +			      "Missing sync word or incomplete bitstream\n");
> +	} else {
> +		dev_err(&mgr->dev, "Timeout after config data transfer\n");
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static const struct fpga_manager_ops xilinx_core_ops = {
> +	.state = xilinx_core_state,
> +	.write_init = xilinx_core_write_init,
> +	.write = xilinx_core_write,
> +	.write_complete = xilinx_core_write_complete,
> +};
> +
> +int xilinx_core_probe(struct xilinx_fpga_core *core)
> +{
> +	struct fpga_manager *mgr;
> +
> +	if (!core || !core->dev || !core->write)
> +		return -EINVAL;
> +
> +	/* PROGRAM_B is active low */
> +	core->prog_b = devm_gpiod_get(core->dev, "prog_b", GPIOD_OUT_LOW);
> +	if (IS_ERR(core->prog_b))
> +		return dev_err_probe(core->dev, PTR_ERR(core->prog_b),
> +				     "Failed to get PROGRAM_B gpio\n");
> +
> +	core->init_b = devm_gpiod_get_optional(core->dev, "init-b", GPIOD_IN);
> +	if (IS_ERR(core->init_b))
> +		return dev_err_probe(core->dev, PTR_ERR(core->init_b),
> +				     "Failed to get INIT_B gpio\n");
> +
> +	core->done = devm_gpiod_get(core->dev, "done", GPIOD_IN);
> +	if (IS_ERR(core->done))
> +		return dev_err_probe(core->dev, PTR_ERR(core->done),
> +				     "Failed to get DONE gpio\n");
> +
> +	mgr = devm_fpga_mgr_register(core->dev,
> +				     "Xilinx Slave Serial FPGA Manager",
> +				     &xilinx_core_ops, core);
> +	return PTR_ERR_OR_ZERO(mgr);
> +}

EXPORT_SYMBOL_GPL() is needed? Have you ever built them as modules?
Try to follow Documentation/process/submit-checklist.rst as much as you can.


And MODULE_LICENSE() & MODULE_DESCRIPTION() please.

> diff --git a/drivers/fpga/xilinx-core.h b/drivers/fpga/xilinx-core.h
> new file mode 100644
> index 0000000000000..bea190287b403
> --- /dev/null
> +++ b/drivers/fpga/xilinx-core.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __XILINX_CORE_H
> +#define __XILINX_CORE_H
> +
> +#include <linux/device.h>
> +
> +/**
> + * struct xilinx_fpga_core - interface between the driver and the core manager
> + *                           of Xilinx 7 Series FPGA manager
> + * @dev:       device node, must be set by the driver
> + * @write:     write callback of the driver, must be set by the driver
> + * @prog_b:    PROGRAM_B gpio, handled by the core manager
> + * @init_b:    INIT_B gpio, handled by the core manager
> + * @done:      DONE gpio, handled by the core manager

Internal fields are not listed in the generated output documentation.

> + */
> +struct xilinx_fpga_core {
> +	struct device *dev;
> +	int (*write)(struct xilinx_fpga_core *core, const char *buf,
> +		     size_t count);
> +	struct gpio_desc *prog_b;
> +	struct gpio_desc *init_b;
> +	struct gpio_desc *done;

Use private tag here.

Please follow Documentation/doc-guide/kernel-doc.rst

> +};
> +
> +int xilinx_core_probe(struct xilinx_fpga_core *core);
> +
> +#endif /* __XILINX_CORE_H */
> diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c
> index e1a227e7ff2ae..12f401502a53a 100644
> --- a/drivers/fpga/xilinx-spi.c
> +++ b/drivers/fpga/xilinx-spi.c
> @@ -10,127 +10,24 @@
>   * the slave serial configuration interface.
>   */
>  
> -#include <linux/delay.h>
> -#include <linux/device.h>
> -#include <linux/fpga/fpga-mgr.h>
> -#include <linux/gpio/consumer.h>
> +#include "xilinx-core.h"
> +
>  #include <linux/module.h>
>  #include <linux/mod_devicetable.h>
>  #include <linux/of.h>
>  #include <linux/spi/spi.h>
> -#include <linux/sizes.h>
>  
>  struct xilinx_spi_conf {
> +	struct xilinx_fpga_core core;
>  	struct spi_device *spi;
> -	struct gpio_desc *prog_b;
> -	struct gpio_desc *init_b;
> -	struct gpio_desc *done;
>  };
>  
> -static int get_done_gpio(struct fpga_manager *mgr)
> -{
> -	struct xilinx_spi_conf *conf = mgr->priv;
> -	int ret;
> -
> -	ret = gpiod_get_value(conf->done);
> -
> -	if (ret < 0)
> -		dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret);
> -
> -	return ret;
> -}
> -
> -static enum fpga_mgr_states xilinx_spi_state(struct fpga_manager *mgr)
> -{
> -	if (!get_done_gpio(mgr))
> -		return FPGA_MGR_STATE_RESET;
> -
> -	return FPGA_MGR_STATE_UNKNOWN;
> -}
> -
> -/**
> - * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
> - * a given delay if the pin is unavailable
> - *
> - * @mgr:        The FPGA manager object
> - * @value:      Value INIT_B to wait for (1 = asserted = low)
> - * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
> - *
> - * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
> - * too much time passed waiting for that. If no INIT_B GPIO is available
> - * then always return 0.
> - */
> -static int wait_for_init_b(struct fpga_manager *mgr, int value,
> -			   unsigned long alt_udelay)
> -{
> -	struct xilinx_spi_conf *conf = mgr->priv;
> -	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
> -
> -	if (conf->init_b) {
> -		while (time_before(jiffies, timeout)) {
> -			int ret = gpiod_get_value(conf->init_b);
> -
> -			if (ret == value)
> -				return 0;
> -
> -			if (ret < 0) {
> -				dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
> -				return ret;
> -			}
> -
> -			usleep_range(100, 400);
> -		}
> -
> -		dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n",
> -			value ? "assert" : "deassert");
> -		return -ETIMEDOUT;
> -	}
> -
> -	udelay(alt_udelay);
> -
> -	return 0;
> -}
> -
> -static int xilinx_spi_write_init(struct fpga_manager *mgr,
> -				 struct fpga_image_info *info,
> -				 const char *buf, size_t count)
> -{
> -	struct xilinx_spi_conf *conf = mgr->priv;
> -	int err;
> -
> -	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
> -		dev_err(&mgr->dev, "Partial reconfiguration not supported\n");
> -		return -EINVAL;
> -	}
> -
> -	gpiod_set_value(conf->prog_b, 1);
> -
> -	err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */
> -	if (err) {
> -		gpiod_set_value(conf->prog_b, 0);
> -		return err;
> -	}
> -
> -	gpiod_set_value(conf->prog_b, 0);
> +#define to_xilinx_spi_conf(obj) container_of(obj, struct xilinx_spi_conf, core)

Use to_spi_device(), then no need the MACRO or struct xilinx_spi_conf

Thanks,
Yilun

>  
> -	err = wait_for_init_b(mgr, 0, 0);
> -	if (err)
> -		return err;
> -
> -	if (get_done_gpio(mgr)) {
> -		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
> -		return -EIO;
> -	}
> -
> -	/* program latency */
> -	usleep_range(7500, 7600);
> -	return 0;
> -}
> -
> -static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
> +static int xilinx_spi_write(struct xilinx_fpga_core *core, const char *buf,
>  			    size_t count)
>  {
> -	struct xilinx_spi_conf *conf = mgr->priv;
> +	struct xilinx_spi_conf *conf = to_xilinx_spi_conf(core);
>  	const char *fw_data = buf;
>  	const char *fw_data_end = fw_data + count;
>  
> @@ -143,7 +40,7 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
>  
>  		ret = spi_write(conf->spi, fw_data, stride);
>  		if (ret) {
> -			dev_err(&mgr->dev, "SPI error in firmware write: %d\n",
> +			dev_err(core->dev, "SPI error in firmware write: %d\n",
>  				ret);
>  			return ret;
>  		}
> @@ -153,109 +50,26 @@ static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
>  	return 0;
>  }
>  
> -static int xilinx_spi_apply_cclk_cycles(struct xilinx_spi_conf *conf)
> -{
> -	struct spi_device *spi = conf->spi;
> -	const u8 din_data[1] = { 0xff };
> -	int ret;
> -
> -	ret = spi_write(conf->spi, din_data, sizeof(din_data));
> -	if (ret)
> -		dev_err(&spi->dev, "applying CCLK cycles failed: %d\n", ret);
> -
> -	return ret;
> -}
> -
> -static int xilinx_spi_write_complete(struct fpga_manager *mgr,
> -				     struct fpga_image_info *info)
> -{
> -	struct xilinx_spi_conf *conf = mgr->priv;
> -	unsigned long timeout = jiffies + usecs_to_jiffies(info->config_complete_timeout_us);
> -	bool expired = false;
> -	int done;
> -	int ret;
> -
> -	/*
> -	 * This loop is carefully written such that if the driver is
> -	 * scheduled out for more than 'timeout', we still check for DONE
> -	 * before giving up and we apply 8 extra CCLK cycles in all cases.
> -	 */
> -	while (!expired) {
> -		expired = time_after(jiffies, timeout);
> -
> -		done = get_done_gpio(mgr);
> -		if (done < 0)
> -			return done;
> -
> -		ret = xilinx_spi_apply_cclk_cycles(conf);
> -		if (ret)
> -			return ret;
> -
> -		if (done)
> -			return 0;
> -	}
> -
> -	if (conf->init_b) {
> -		ret = gpiod_get_value(conf->init_b);
> -
> -		if (ret < 0) {
> -			dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret);
> -			return ret;
> -		}
> -
> -		dev_err(&mgr->dev,
> -			ret ? "CRC error or invalid device\n"
> -			: "Missing sync word or incomplete bitstream\n");
> -	} else {
> -		dev_err(&mgr->dev, "Timeout after config data transfer\n");
> -	}
> -
> -	return -ETIMEDOUT;
> -}
> -
> -static const struct fpga_manager_ops xilinx_spi_ops = {
> -	.state = xilinx_spi_state,
> -	.write_init = xilinx_spi_write_init,
> -	.write = xilinx_spi_write,
> -	.write_complete = xilinx_spi_write_complete,
> -};
> -
>  static int xilinx_spi_probe(struct spi_device *spi)
>  {
>  	struct xilinx_spi_conf *conf;
> -	struct fpga_manager *mgr;
>  
>  	conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL);
>  	if (!conf)
>  		return -ENOMEM;
>  
> +	conf->core.dev = &spi->dev;
> +	conf->core.write = xilinx_spi_write;
>  	conf->spi = spi;
>  
> -	/* PROGRAM_B is active low */
> -	conf->prog_b = devm_gpiod_get(&spi->dev, "prog_b", GPIOD_OUT_LOW);
> -	if (IS_ERR(conf->prog_b))
> -		return dev_err_probe(&spi->dev, PTR_ERR(conf->prog_b),
> -				     "Failed to get PROGRAM_B gpio\n");
> -
> -	conf->init_b = devm_gpiod_get_optional(&spi->dev, "init-b", GPIOD_IN);
> -	if (IS_ERR(conf->init_b))
> -		return dev_err_probe(&spi->dev, PTR_ERR(conf->init_b),
> -				     "Failed to get INIT_B gpio\n");
> -
> -	conf->done = devm_gpiod_get(&spi->dev, "done", GPIOD_IN);
> -	if (IS_ERR(conf->done))
> -		return dev_err_probe(&spi->dev, PTR_ERR(conf->done),
> -				     "Failed to get DONE gpio\n");
> -
> -	mgr = devm_fpga_mgr_register(&spi->dev,
> -				     "Xilinx Slave Serial FPGA Manager",
> -				     &xilinx_spi_ops, conf);
> -	return PTR_ERR_OR_ZERO(mgr);
> +	return xilinx_core_probe(&conf->core);
>  }
>  
>  #ifdef CONFIG_OF
>  static const struct of_device_id xlnx_spi_of_match[] = {
> -	{ .compatible = "xlnx,fpga-slave-serial", },
> +	{
> +		.compatible = "xlnx,fpga-slave-serial",
> +	},
>  	{}
>  };
>  MODULE_DEVICE_TABLE(of, xlnx_spi_of_match);
> -- 
> 2.43.0
> 
> 


From tudor.ambarus at linaro.org  Mon Feb 26 01:23:44 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 26 Feb 2024 11:23:44 +0200
Subject: [PATCH v4 04/39] dt-bindings: crypto: add sam9x7 in Atmel SHA
In-Reply-To: <20240223172358.671722-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172358.671722-1-varshini.rajendran@microchip.com>
Message-ID: <40691b0e-864d-4818-9fd0-338bf750f46b@linaro.org>



On 23.02.2024 19:23, Varshini Rajendran wrote:
> Add DT bindings for atmel SHA.

This would have deserved a better commit message, I (we) spent a lot of
time deciding whether this is the correct approach.
https://lore.kernel.org/linux-arm-kernel/342de8f3-852f-9bfa-39c4-4d820f349305 at linaro.org/

Anyway:
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>

> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> Acked-by: Rob Herring <robh at kernel.org>
> ---
> Changes in v4:
> - Updated Acked-by tag
> ---
>  .../devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml   | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml
> index ee2ffb034325..d378c53314dd 100644
> --- a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml
> +++ b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-sha.yaml
> @@ -12,7 +12,11 @@ maintainers:
>  
>  properties:
>    compatible:
> -    const: atmel,at91sam9g46-sha
> +    oneOf:
> +      - const: atmel,at91sam9g46-sha
> +      - items:
> +          - const: microchip,sam9x7-sha
> +          - const: atmel,at91sam9g46-sha
>  
>    reg:
>      maxItems: 1


From tudor.ambarus at linaro.org  Mon Feb 26 01:24:09 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 26 Feb 2024 11:24:09 +0200
Subject: [PATCH v4 05/39] dt-bindings: crypto: add sam9x7 in Atmel TDES
In-Reply-To: <20240223172445.671783-1-varshini.rajendran@microchip.com>
References: <20240223171342.669133-1-varshini.rajendran@microchip.com>
 <20240223172445.671783-1-varshini.rajendran@microchip.com>
Message-ID: <0a6fec2f-978c-4290-a189-20120a60d08b@linaro.org>



On 23.02.2024 19:24, Varshini Rajendran wrote:
> Add DT bindings for atmel TDES.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>

This would have deserved a better commit message, I (we) spent a lot of
time deciding whether this is the correct approach.
https://lore.kernel.org/linux-arm-kernel/342de8f3-852f-9bfa-39c4-4d820f349305 at linaro.org/

Anyway:
Reviewed-by: Tudor Ambarus <tudor.ambarus at linaro.org>

> ---
> Changes in v4:
> - Updated Acked-by tag
> ---
>  .../devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml  | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml
> index 3d6ed24b1b00..6a441f79efea 100644
> --- a/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml
> +++ b/Documentation/devicetree/bindings/crypto/atmel,at91sam9g46-tdes.yaml
> @@ -12,7 +12,11 @@ maintainers:
>  
>  properties:
>    compatible:
> -    const: atmel,at91sam9g46-tdes
> +    oneOf:
> +      - const: atmel,at91sam9g46-tdes
> +      - items:
> +          - const: microchip,sam9x7-tdes
> +          - const: atmel,at91sam9g46-tdes
>  
>    reg:
>      maxItems: 1


From piotrwejman90 at gmail.com  Mon Feb 26 01:31:44 2024
From: piotrwejman90 at gmail.com (Piotr Wejman)
Date: Mon, 26 Feb 2024 10:31:44 +0100
Subject: [PATCH v2] net: stmmac: fix rx queue priority assignment
Message-ID: <20240226093144.31965-1-piotrwejman90@gmail.com>

The driver should ensure that same priority is not mapped to multiple
rx queues. Currently rx_queue_priority() function is adding
priorities for a queue without clearing them from others.

>From DesignWare Cores Ethernet Quality-of-Service
Databook, section 17.1.29 MAC_RxQ_Ctrl2:
"[...]The software must ensure that the content of this field is
mutually exclusive to the PSRQ fields for other queues, that is,
the same priority is not mapped to multiple Rx queues[...]"

After this patch, rx_queue_priority() function will:
- assign desired priorities to a queue
- remove those priorities from all other queues
The write sequence of CTRL2 and CTRL3 registers is done in the way to
ensure this order.

Signed-off-by: Piotr Wejman <piotrwejman90 at gmail.com>
---
Changes in v2:
  - Add some comments
  - Apply same changes to dwxgmac2_rx_queue_prio()
  - Revert "Rename prio argument to prio_mask"
  - Link to v1: https://lore.kernel.org/netdev/20240219102405.32015-1-piotrwejman90 at gmail.com/T/#u

 .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 42 +++++++++++++++----
 .../ethernet/stmicro/stmmac/dwxgmac2_core.c   | 40 ++++++++++++++----
 2 files changed, 66 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 6b6d0de09619..76ec0c1da250 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -92,19 +92,43 @@ static void dwmac4_rx_queue_priority(struct mac_device_info *hw,
 				     u32 prio, u32 queue)
 {
 	void __iomem *ioaddr = hw->pcsr;
-	u32 base_register;
-	u32 value;
+	u32 clear_mask = 0;
+	u32 ctrl2, ctrl3;
+	int i;
 
-	base_register = (queue < 4) ? GMAC_RXQ_CTRL2 : GMAC_RXQ_CTRL3;
-	if (queue >= 4)
-		queue -= 4;
+	ctrl2 = readl(ioaddr + GMAC_RXQ_CTRL2);
+	ctrl3 = readl(ioaddr + GMAC_RXQ_CTRL3);
+	
+	/* The software must ensure that the same priority
+	 * is not mapped to multiple Rx queues.
+	 */
+	for (i = 0; i < 4; i++)
+		clear_mask |= ((prio << GMAC_RXQCTRL_PSRQX_SHIFT(i)) &
+						GMAC_RXQCTRL_PSRQX_MASK(i));
 
-	value = readl(ioaddr + base_register);
+	ctrl2 &= ~clear_mask;
+	ctrl3 &= ~clear_mask;
 
-	value &= ~GMAC_RXQCTRL_PSRQX_MASK(queue);
-	value |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
+	/* Assign new priorities to a queue and
+	 * clear them from others queues.
+	 * The CTRL2 and CTRL3 registers write sequence is done
+	 * in the way to ensure this order.
+	 */
+	if (queue < 4) {
+		ctrl2 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
 						GMAC_RXQCTRL_PSRQX_MASK(queue);
-	writel(value, ioaddr + base_register);
+
+		writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
+		writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
+	} else {
+		queue -= 4;
+
+		ctrl3 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
+						GMAC_RXQCTRL_PSRQX_MASK(queue);
+
+		writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
+		writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
+	}
 }
 
 static void dwmac4_tx_queue_priority(struct mac_device_info *hw,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index 1af2f89a0504..7ad73e1d353e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -105,17 +105,43 @@ static void dwxgmac2_rx_queue_prio(struct mac_device_info *hw, u32 prio,
 				   u32 queue)
 {
 	void __iomem *ioaddr = hw->pcsr;
-	u32 value, reg;
+	u32 clear_mask = 0;
+	u32 ctrl2, ctrl3;
+	int i;
 
-	reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
-	if (queue >= 4)
+	ctrl2 = readl(ioaddr + XGMAC_RXQ_CTRL2);
+	ctrl3 = readl(ioaddr + XGMAC_RXQ_CTRL3);
+	
+	/* The software must ensure that the same priority
+	 * is not mapped to multiple Rx queues.
+	 */
+	for (i = 0; i < 4; i++)
+		clear_mask |= ((prio << XGMAC_PSRQ_SHIFT(i)) &
+						XGMAC_PSRQ(i));
+
+	ctrl2 &= ~clear_mask;
+	ctrl3 &= ~clear_mask;
+
+	/* Assign new priorities to a queue and
+	 * clear them from others queues.
+	 * The CTRL2 and CTRL3 registers write sequence is done
+	 * in the way to ensure this order.
+	 */
+	if (queue < 4) {
+		ctrl2 |= (prio << XGMAC_PSRQ_SHIFT(queue)) &
+						XGMAC_PSRQ(queue);
+
+		writel(ctrl2, ioaddr + XGMAC_RXQ_CTRL2);
+		writel(ctrl3, ioaddr + XGMAC_RXQ_CTRL3);
+	} else {
 		queue -= 4;
 
-	value = readl(ioaddr + reg);
-	value &= ~XGMAC_PSRQ(queue);
-	value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);
+		ctrl3 |= (prio << XGMAC_PSRQ_SHIFT(queue)) &
+						XGMAC_PSRQ(queue);
 
-	writel(value, ioaddr + reg);
+		writel(ctrl3, ioaddr + XGMAC_RXQ_CTRL3);
+		writel(ctrl2, ioaddr + XGMAC_RXQ_CTRL2);
+	}
 }
 
 static void dwxgmac2_tx_queue_prio(struct mac_device_info *hw, u32 prio,
-- 
2.25.1



From tudor.ambarus at linaro.org  Mon Feb 26 01:47:18 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 26 Feb 2024 11:47:18 +0200
Subject: [PATCH] MAINTAINERS: Remove T Ambarus from few mchp entries
Message-ID: <20240226094718.29104-1-tudor.ambarus@linaro.org>

I have been no longer at Microchip for more than a year and I'm no
longer interested in maintaining these drivers. Let other mchp people
step up, thus remove myself. Thanks for the nice collaboration everyone!

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
Shall be queued through the at91 tree.

 MAINTAINERS | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index e1475ca38ff2..fd4d4e58fead 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14350,7 +14350,6 @@ F:	drivers/misc/xilinx_tmr_manager.c
 
 MICROCHIP AT91 DMA DRIVERS
 M:	Ludovic Desroches <ludovic.desroches at microchip.com>
-M:	Tudor Ambarus <tudor.ambarus at linaro.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 L:	dmaengine at vger.kernel.org
 S:	Supported
@@ -14398,12 +14397,6 @@ S:	Supported
 F:	Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
 F:	drivers/media/platform/microchip/microchip-csi2dc.c
 
-MICROCHIP ECC DRIVER
-M:	Tudor Ambarus <tudor.ambarus at linaro.org>
-L:	linux-crypto at vger.kernel.org
-S:	Maintained
-F:	drivers/crypto/atmel-ecc.*
-
 MICROCHIP EIC DRIVER
 M:	Claudiu Beznea <claudiu.beznea at tuxon.dev>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
@@ -14505,13 +14498,6 @@ M:	Aubin Constans <aubin.constans at microchip.com>
 S:	Maintained
 F:	drivers/mmc/host/atmel-mci.c
 
-MICROCHIP NAND DRIVER
-M:	Tudor Ambarus <tudor.ambarus at linaro.org>
-L:	linux-mtd at lists.infradead.org
-S:	Supported
-F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
-F:	drivers/mtd/nand/raw/atmel/*
-
 MICROCHIP OTPC DRIVER
 M:	Claudiu Beznea <claudiu.beznea at tuxon.dev>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
-- 
2.34.1



From suzuki.poulose at arm.com  Mon Feb 26 01:52:27 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 26 Feb 2024 09:52:27 +0000
Subject: [PATCH v5 5/7] arm64: KVM: Add interface to set guest value for
 TRFCR register
In-Reply-To: <9d3f9f70-0b34-7426-8b62-93dc173a0bb2@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
 <20240220100924.2761706-6-james.clark@arm.com>
 <c8819064-13c3-41c6-8b2e-779ef8a22ee8@arm.com>
 <9d3f9f70-0b34-7426-8b62-93dc173a0bb2@arm.com>
Message-ID: <125fe2f0-bd21-462f-893a-fbf80813dfbf@arm.com>

On 23/02/2024 16:39, James Clark wrote:
> 
> 
> On 23/02/2024 10:03, Suzuki K Poulose wrote:
>> On 20/02/2024 10:09, James Clark wrote:
>>> Add an interface for the Coresight driver to use to set the value of the
>>> TRFCR register for the guest. This register controls the exclude
>>> settings for trace at different exception levels, and is used to honor
>>> the exclude_host and exclude_guest parameters from the Perf session.
>>> This will be used to later write TRFCR_EL1 on nVHE at guest switch. For
>>> VHE, the host trace is controlled by TRFCR_EL2 and thus we can write to
>>> the TRFCR_EL1 immediately. Because guest writes to the register are
>>> trapped, the value will persist and can't be modified.
>>>
>>> Instead of adding a load of infrastructure to share the host's per-cpu
>>> offsets with the hypervisor, just define the new storage as a NR_CPUS
>>> array.
>>>
>>> Signed-off-by: James Clark <james.clark at arm.com>
>>> ---
>>>  ? arch/arm64/include/asm/kvm_host.h |? 3 +++
>>>  ? arch/arm64/kernel/image-vars.h??? |? 1 +
>>>  ? arch/arm64/kvm/debug.c??????????? | 26 ++++++++++++++++++++++++++
>>>  ? 3 files changed, 30 insertions(+)
>>>
>>> diff --git a/arch/arm64/include/asm/kvm_host.h
>>> b/arch/arm64/include/asm/kvm_host.h
>>> index 85b5477bd1b4..56b7f7eca195 100644
>>> --- a/arch/arm64/include/asm/kvm_host.h
>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>> @@ -509,6 +509,7 @@ struct kvm_host_psci_config {
>>>  ????? bool psci_0_1_cpu_off_implemented;
>>>  ????? bool psci_0_1_migrate_implemented;
>>>  ? };
>>> +extern u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
>>>  ? ? extern struct kvm_host_psci_config
>>> kvm_nvhe_sym(kvm_host_psci_config);
>>>  ? #define kvm_host_psci_config CHOOSE_NVHE_SYM(kvm_host_psci_config)
>>> @@ -1174,6 +1175,7 @@ void kvm_arch_vcpu_put_debug_state_flags(struct
>>> kvm_vcpu *vcpu);
>>>  ? void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr);
>>>  ? void kvm_clr_pmu_events(u32 clr);
>>>  ? bool kvm_set_pmuserenr(u64 val);
>>> +void kvm_etm_set_guest_trfcr(u64 trfcr_guest);
>>>  ? #else
>>>  ? static inline void kvm_set_pmu_events(u32 set, struct
>>> perf_event_attr *attr) {}
>>>  ? static inline void kvm_clr_pmu_events(u32 clr) {}
>>> @@ -1181,6 +1183,7 @@ static inline bool kvm_set_pmuserenr(u64 val)
>>>  ? {
>>>  ????? return false;
>>>  ? }
>>> +static inline void kvm_etm_set_guest_trfcr(u64 trfcr_guest) {}
>>>  ? #endif
>>>  ? ? void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
>>> diff --git a/arch/arm64/kernel/image-vars.h
>>> b/arch/arm64/kernel/image-vars.h
>>> index 5e4dc72ab1bd..a451e4f10804 100644
>>> --- a/arch/arm64/kernel/image-vars.h
>>> +++ b/arch/arm64/kernel/image-vars.h
>>> @@ -59,6 +59,7 @@ KVM_NVHE_ALIAS(alt_cb_patch_nops);
>>>  ? ? /* Global kernel state accessed by nVHE hyp code. */
>>>  ? KVM_NVHE_ALIAS(kvm_vgic_global_state);
>>> +KVM_NVHE_ALIAS(kvm_guest_trfcr);
>>>  ? ? /* Kernel symbols used to call panic() from nVHE hyp code (via
>>> ERET). */
>>>  ? KVM_NVHE_ALIAS(nvhe_hyp_panic_handler);
>>> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
>>> index 49a13e72ddd2..c8d936ce6e2b 100644
>>> --- a/arch/arm64/kvm/debug.c
>>> +++ b/arch/arm64/kvm/debug.c
>>> @@ -22,6 +22,7 @@
>>>  ????????????????? DBG_MDSCR_MDE)
>>>  ? ? static DEFINE_PER_CPU(u64, mdcr_el2);
>>> +u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
>>>  ? ? /*
>>>  ?? * save/restore_guest_debug_regs
>>> @@ -359,3 +360,28 @@ void kvm_arch_vcpu_put_debug_state_flags(struct
>>> kvm_vcpu *vcpu)
>>>  ????? vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
>>>  ????? vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
>>>  ? }
>>> +
>>> +/*
>>> + * Interface for the Coresight driver to use to set the value of the
>>> TRFCR
>>> + * register for the guest. This register controls the exclude
>>> settings for trace
>>> + * at different exception levels, and is used to honor the
>>> exclude_host and
>>> + * exclude_guest parameters from the Perf session.
>>> + *
>>> + * This will be used to later write TRFCR_EL1 on nVHE at guest
>>> switch. For VHE,
>>> + * the host trace is controlled by TRFCR_EL2 and thus we can write to
>>> the
>>> + * TRFCR_EL1 immediately. Because guest writes to the register are
>>> trapped, the
>>> + * value will persist and can't be modified. For pKVM,
>>> kvm_guest_trfcr can't
>>> + * be read by the hypervisor, so don't bother writing it.
>>> + */
>>> +void kvm_etm_set_guest_trfcr(u64 trfcr_guest)
>>> +{
>>> +??? if
>>> (WARN_ON_ONCE(!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
>>> +?????????????????????????????????? ID_AA64DFR0_EL1_TraceFilt_SHIFT)))
>>> +??????? return;
>>> +
>>> +??? if (has_vhe())
>>> +??????? write_sysreg_s(trfcr_guest, SYS_TRFCR_EL12);
>>> +??? else if (!is_protected_kvm_enabled())
>>> +??????? kvm_guest_trfcr[smp_processor_id()] = trfcr_guest;
>>
>> smp_processor_id() could sleep in some configurations ? Should we switch
>> to raw_smp_processor_id() to be safer ?
>>
> 
> I don't think so, it's #defined to raw_smp_processor_id() anyway. Unless
> DEBUG_PREEMPT is on, then it's still raw_smp_processor_id() but it
> validates that preemption is disabled so the value isn't stale. >
> We actually want that validation, so should leave it as

This is actually what we want. i.e., We don't want the coresight drivers
to make this call from a non-premptible context. Relying on the 
DEBUG_PREEMPT for detecting such erroneous uses is not a good idea, 
production kernels may not do this and a comment doesn't go far.
So, I think we need a :

WARN_ON(preemptible()) in here and use smp_processor_id()

> smp_processor_id(). I can add a comment saying that this function should
> only be called with preemption disabled, but I wouldn't add any extra
> validation. Every smp_processor_id() call is already checked when
> DEBUG_PREEMPT is on and this one doesn't seem to be special in any way.
> 
> I also checked that the warning isn't triggered with DEBUG_PREEMPT on,
> and there are also a lot of other smp_processor_id() calls on similar
> paths in the Coresight driver.

Here, we are setting something for the KVM to program and if we set the
filters on the wrong Physical CPU, then we mess up the tracing.

Suzuki

> 
>> Otherwise looks good to me.
>>
>> Suzuki
>>
>>> +}
>>> +EXPORT_SYMBOL_GPL(kvm_etm_set_guest_trfcr);
>>



From sinthu.raja at mistralsolutions.com  Mon Feb 26 01:52:31 2024
From: sinthu.raja at mistralsolutions.com (Sinthu Raja)
Date: Mon, 26 Feb 2024 15:22:31 +0530
Subject: [PATCH V3] arm64: dts: ti: k3-am68-sk-som: Add support for OSPI flash
Message-ID: <20240226095231.35684-1-sinthu.raja@ti.com>

From: Sinthu Raja <sinthu.raja at ti.com>

AM68 SK has an OSPI NOR flash on its SOM connected to OSPI0 instance.
Enable support for the same. Also, describe the OSPI flash partition
information through the device tree, according to the offsets in the
bootloader.

Signed-off-by: Sinthu Raja <sinthu.raja at ti.com>
---

Changes in V3:
Address review comments:
   a. Fix the make dtbs_check error related to ospi pinctrl
   b. Increase the partition 0 size to 1MB and update the following
partitions start address accordingly.

V2: https://lore.kernel.org/linux-arm-kernel/20240219075932.6458-1-sinthu.raja at ti.com/

 arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi | 78 ++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
index 0f4a5da0ebc4..d3e869c250a2 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
@@ -130,6 +130,24 @@ rtos_ipc_memory_region: ipc-memories at a8000000 {
 	};
 };
 
+&wkup_pmx0 {
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins {
+		pinctrl-single,pins = <
+			J721S2_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (D19) MCU_OSPI0_CLK */
+			J721S2_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F15) MCU_OSPI0_CSn0 */
+			J721S2_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (C19) MCU_OSPI0_D0 */
+			J721S2_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (F16) MCU_OSPI0_D1 */
+			J721S2_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (G15) MCU_OSPI0_D2 */
+			J721S2_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (F18) MCU_OSPI0_D3 */
+			J721S2_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (E19) MCU_OSPI0_D4 */
+			J721S2_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (G19) MCU_OSPI0_D5 */
+			J721S2_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (F19) MCU_OSPI0_D6 */
+			J721S2_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (F20) MCU_OSPI0_D7 */
+			J721S2_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (E18) MCU_OSPI0_DQS */
+		>;
+	};
+};
+
 &wkup_pmx2 {
 	wkup_i2c0_pins_default: wkup-i2c0-default-pins {
 		pinctrl-single,pins = <
@@ -152,6 +170,66 @@ eeprom at 51 {
 	};
 };
 
+&ospi0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <8>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <25000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <4>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "ospi.tiboot3";
+				reg = <0x0 0x100000>;
+			};
+
+			partition at 100000 {
+				label = "ospi.tispl";
+				reg = <0x100000 0x200000>;
+			};
+
+			partition at 300000 {
+				label = "ospi.u-boot";
+				reg = <0x300000 0x400000>;
+			};
+
+			partition at 700000 {
+				label = "ospi.env";
+				reg = <0x700000 0x40000>;
+			};
+
+			partition at 740000 {
+				label = "ospi.env.backup";
+				reg = <0x740000 0x40000>;
+			};
+
+			partition at 800000 {
+				label = "ospi.rootfs";
+				reg = <0x800000 0x37c0000>;
+			};
+
+			partition at 3fc0000 {
+				label = "ospi.phypattern";
+				reg = <0x3fc0000 0x40000>;
+			};
+		};
+	};
+};
+
 &mailbox0_cluster0 {
 	status = "okay";
 	interrupts = <436>;
-- 
2.34.1



From yilun.xu at linux.intel.com  Mon Feb 26 01:50:38 2024
From: yilun.xu at linux.intel.com (Xu Yilun)
Date: Mon, 26 Feb 2024 17:50:38 +0800
Subject: [PATCH v4 3/3] fpga: xilinx-selectmap: add new driver
In-Reply-To: <20240221195058.1281973-4-charles.perry@savoirfairelinux.com>
References: <20240221195058.1281973-1-charles.perry@savoirfairelinux.com>
 <20240221195058.1281973-4-charles.perry@savoirfairelinux.com>
Message-ID: <Zdxe7mvBbHDHzbiS@yilunxu-OptiPlex-7050>

On Wed, Feb 21, 2024 at 02:50:49PM -0500, Charles Perry wrote:
> Xilinx 7 series FPGA can be programmed using a parallel port named
> the SelectMAP interface in the datasheet. This interface is compatible
> with the i.MX6 EIM bus controller but other types of external memory
> mapped parallel bus might work.
> 
> xilinx-selectmap currently only supports the x8 mode where data is loaded
> at one byte per rising edge of the clock, with the MSb of each byte
> presented to the D0 pin.
> 
> Signed-off-by: Charles Perry <charles.perry at savoirfairelinux.com>
> ---
>  drivers/fpga/Kconfig            |  8 +++
>  drivers/fpga/Makefile           |  1 +
>  drivers/fpga/xilinx-selectmap.c | 97 +++++++++++++++++++++++++++++++++
>  3 files changed, 106 insertions(+)
>  create mode 100644 drivers/fpga/xilinx-selectmap.c
> 
> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
> index d27a1ebf40838..37b35f58f0dfb 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -67,6 +67,14 @@ config FPGA_MGR_STRATIX10_SOC
>  config FPGA_MGR_XILINX_CORE
>  	tristate
>  
> +config FPGA_MGR_XILINX_SELECTMAP
> +	tristate "Xilinx Configuration over SelectMAP"
> +	depends on HAS_IOMEM
> +	select FPGA_MGR_XILINX_CORE
> +	help
> +	  FPGA manager driver support for Xilinx FPGA configuration
> +	  over SelectMAP interface.
> +
>  config FPGA_MGR_XILINX_SPI
>  	tristate "Xilinx Configuration over Slave Serial (SPI)"
>  	depends on SPI
> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
> index 7ec795b6a5a70..aeb89bb13517e 100644
> --- a/drivers/fpga/Makefile
> +++ b/drivers/fpga/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
>  obj-$(CONFIG_FPGA_MGR_STRATIX10_SOC)	+= stratix10-soc.o
>  obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
>  obj-$(CONFIG_FPGA_MGR_XILINX_CORE)	+= xilinx-core.o
> +obj-$(CONFIG_FPGA_MGR_XILINX_SELECTMAP)	+= xilinx-selectmap.o
>  obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
>  obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
>  obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA)	+= zynqmp-fpga.o
> diff --git a/drivers/fpga/xilinx-selectmap.c b/drivers/fpga/xilinx-selectmap.c
> new file mode 100644
> index 0000000000000..b63f4623f8b2c
> --- /dev/null
> +++ b/drivers/fpga/xilinx-selectmap.c
> @@ -0,0 +1,97 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Xilinx Spartan6 and 7 Series SelectMAP interface driver
> + *
> + * (C) 2024 Charles Perry <charles.perry at savoirfairelinux.com>
> + *
> + * Manage Xilinx FPGA firmware loaded over the SelectMAP configuration
> + * interface.
> + */
> +
> +#include "xilinx-core.h"
> +
> +#include <linux/platform_device.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/of.h>
> +#include <linux/io.h>
> +
> +struct xilinx_selectmap_conf {
> +	struct xilinx_fpga_core core;
> +	void __iomem *base;
> +};
> +
> +#define to_xilinx_selectmap_conf(obj) \
> +	container_of(obj, struct xilinx_selectmap_conf, core)
> +
> +static int xilinx_selectmap_write(struct xilinx_fpga_core *core,
> +				  const char *buf, size_t count)
> +{
> +	struct xilinx_selectmap_conf *conf = to_xilinx_selectmap_conf(core);
> +	u32 i;
> +
> +	for (i = 0; i < count; ++i)
> +		writeb(buf[i], conf->base);
> +
> +	return 0;
> +}
> +
> +static int xilinx_selectmap_probe(struct platform_device *pdev)
> +{
> +	struct xilinx_selectmap_conf *conf;
> +	struct resource *r;
> +	void __iomem *base;
> +	struct gpio_desc *csi_b;
> +	struct gpio_desc *rdwr_b;
> +
> +	conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL);
> +	if (!conf)
> +		return -ENOMEM;
> +
> +	conf->core.dev = &pdev->dev;
> +	conf->core.write = xilinx_selectmap_write;
> +
> +	base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
> +	if (IS_ERR(base))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(base),
> +				     "ioremap error\n");
> +	conf->base = base;
> +
> +	/* CSI_B is active low */
> +	csi_b = devm_gpiod_get_optional(&pdev->dev, "csi", GPIOD_OUT_HIGH);
> +	if (IS_ERR(csi_b))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(csi_b),
> +				     "Failed to get CSI_B gpio\n");
> +
> +	/* RDWR_B is active low */
> +	rdwr_b = devm_gpiod_get_optional(&pdev->dev, "rdwr", GPIOD_OUT_HIGH);
> +	if (IS_ERR(rdwr_b))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(rdwr_b),
> +				     "Failed to get RDWR_B gpio\n");
> +
> +	return xilinx_core_probe(&conf->core);
> +}
> +
> +static const struct of_device_id xlnx_selectmap_of_match[] = {
> +	{ .compatible = "xlnx,fpga-xc7s-selectmap", }, // Spartan-7
> +	{ .compatible = "xlnx,fpga-xc7a-selectmap", }, // Artix-7
> +	{ .compatible = "xlnx,fpga-xc7k-selectmap", }, // Kintex-7
> +	{ .compatible = "xlnx,fpga-xc7v-selectmap", }, // Virtex-7
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, xlnx_selectmap_of_match);

Does the driver have to be used with OF or not?

If yes, please specify the reason and enforce in Kconfig.
If no, please ensure it decently compiles without CONFIG_OF.

Thanks,
Yilun

> +
> +static struct platform_driver xilinx_selectmap_driver = {
> +	.driver = {
> +		.name = "xilinx-selectmap",
> +		.of_match_table = xlnx_selectmap_of_match,
> +	},
> +	.probe  = xilinx_selectmap_probe,
> +};
> +
> +module_platform_driver(xilinx_selectmap_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Charles Perry <charles.perry at savoirfairelinux.com>");
> +MODULE_DESCRIPTION("Load Xilinx FPGA firmware over SelectMap");
> -- 
> 2.43.0
> 
> 


From mbrugger at suse.com  Mon Feb 26 01:55:02 2024
From: mbrugger at suse.com (Matthias Brugger)
Date: Mon, 26 Feb 2024 10:55:02 +0100
Subject: [PATCH 1/1] MAINTAINERS: Add maintainer for NXP S32G boards
In-Reply-To: <57dce440-d24b-4638-9395-62dfb03ec002@app.fastmail.com>
References: <20240221120123.1118552-2-ghennadi.procopciuc@oss.nxp.com>
 <f4465547-1fb1-4578-9a69-7d399e7661b3@linaro.org>
 <403e32c2-910e-4745-9ebe-fbf377c3fde8@linaro.org>
 <ad856766-8903-46c0-93af-24e101ad51dc@oss.nxp.com>
 <e538ded0-bd3a-4ca4-b2bd-8d20d8c8c3fe@linaro.org>
 <bcb79af4-56d9-4204-9503-cff996f1ba41@oss.nxp.com>
 <e6f6070e-8355-4a0b-a904-1a24970f249b@linaro.org>
 <e530d504-dfa3-4d39-b903-b2570bb8b014@suse.com>
 <c3e68c62-b81f-475b-9b15-c983c94aed8b@app.fastmail.com>
 <Zdiu8s5Cgz9s6dLP@dragon> <ZdmZ4JC0CsX2qs5C@linux-8mug>
 <57dce440-d24b-4638-9395-62dfb03ec002@app.fastmail.com>
Message-ID: <f988dffa-dd5c-48a5-9ebb-e13f9443989f@suse.com>



On 24/02/2024 12:42, Arnd Bergmann wrote:
[...]
>>> ARM/NXP S32G ARCHITECTURE
>>> M:      Chester Lin <chester62515 at gmail.com>
>>> R:      Andreas F?rber <afaerber at suse.de>
>>> R:      Matthias Brugger <mbrugger at suse.com>
>>> R:      NXP S32 Linux Team <s32 at nxp.com>
>>> L:      linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>>> S:      Maintained
>>> F:      arch/arm64/boot/dts/freescale/s32g*.dts*
>>>
>>> However I'm fine with collecting and sending patches through IMX tree,
>>> if S32G folks help review them.
>>>
>>
>> This looks good to me as well.
> 
> Ok, in this case I would suggest we change this section to
> only have 'R:' entries and no 'M:' for the moment.
> 
> Between the four of you (Chester, Andreas, Matthias, Ghennadi),
> I think we can choose to keep everyone or drop those that are
> unlikely to actually review patches. Please let us know you
> would like to be included as a reviewer or not.
> 

Please include me as reviewer :)

Regards,
Matthias



From mripard at kernel.org  Mon Feb 26 01:55:20 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 26 Feb 2024 10:55:20 +0100
Subject: (subset) [PATCH v7 32/36] drm/sun4i: hdmi: Convert encoder to atomic
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-32-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> <20240222-kms-hdmi-connector-state-v7-32-8f4af575fce2@kernel.org>
Message-ID: <170894131837.29486.10568875108218671603.b4-ty@kernel.org>

On Thu, 22 Feb 2024 19:14:18 +0100, Maxime Ripard wrote:
> The sun4i_hdmi driver still uses the non-atomic variants of the encoder
> hooks, so let's convert to their atomic equivalents.
> 
> 

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime


From mripard at kernel.org  Mon Feb 26 01:55:21 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 26 Feb 2024 10:55:21 +0100
Subject: (subset) [PATCH v7 33/36] drm/sun4i: hdmi: Move mode_set into enable
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-33-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> <20240222-kms-hdmi-connector-state-v7-33-8f4af575fce2@kernel.org>
Message-ID: <170894131837.29486.4668463181897393982.b4-ty@kernel.org>

On Thu, 22 Feb 2024 19:14:19 +0100, Maxime Ripard wrote:
> We're not doing anything special in atomic_mode_set so we can simply
> merge it into atomic_enable.
> 
> 

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime


From mripard at kernel.org  Mon Feb 26 01:55:22 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 26 Feb 2024 10:55:22 +0100
Subject: (subset) [PATCH v7 34/36] drm/sun4i: hdmi: Switch to container_of_const
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-34-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> <20240222-kms-hdmi-connector-state-v7-34-8f4af575fce2@kernel.org>
Message-ID: <170894131837.29486.6507796941074207475.b4-ty@kernel.org>

On Thu, 22 Feb 2024 19:14:20 +0100, Maxime Ripard wrote:
> container_of_const() allows to preserve the pointer constness and is
> thus more flexible than inline functions.
> 
> Let's switch all our instances of container_of() to container_of_const().
> 
> 

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime


From mripard at kernel.org  Mon Feb 26 01:55:23 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 26 Feb 2024 10:55:23 +0100
Subject: (subset) [PATCH v7 35/36] drm/sun4i: hdmi: Consolidate atomic_check and mode_valid
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-35-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> <20240222-kms-hdmi-connector-state-v7-35-8f4af575fce2@kernel.org>
Message-ID: <170894131837.29486.11894124011939274293.b4-ty@kernel.org>

On Thu, 22 Feb 2024 19:14:21 +0100, Maxime Ripard wrote:
> atomic_check and mode_valid do not check for the same things which can
> lead to surprising result if the userspace commits a mode that didn't go
> through mode_valid. Let's merge the two implementations into a function
> called by both.
> 
> 

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime


From maz at kernel.org  Mon Feb 26 02:05:51 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:51 +0000
Subject: [PATCH v2 03/13] KVM: arm64: nv: Drop VCPU_HYP_CONTEXT flag
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-4-maz@kernel.org>

It has become obvious that HCR_EL2.NV serves the exact same use
as VCPU_HYP_CONTEXT, only in an architectural way. So just drop
the flag for good.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 2 --
 arch/arm64/kvm/hyp/vhe/switch.c   | 7 +------
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a5ec4c7d3966..75eb8e170515 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -816,8 +816,6 @@ struct kvm_vcpu_arch {
 #define DEBUG_STATE_SAVE_SPE	__vcpu_single_flag(iflags, BIT(5))
 /* Save TRBE context if active  */
 #define DEBUG_STATE_SAVE_TRBE	__vcpu_single_flag(iflags, BIT(6))
-/* vcpu running in HYP context */
-#define VCPU_HYP_CONTEXT	__vcpu_single_flag(iflags, BIT(7))
 
 /* SVE enabled for host EL0 */
 #define HOST_SVE_ENABLED	__vcpu_single_flag(sflags, BIT(0))
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 1581df6aec87..58415783fd53 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -197,7 +197,7 @@ 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_get_flag(vcpu, VCPU_HYP_CONTEXT))) {
+	if (unlikely(read_sysreg(hcr_el2) & HCR_NV)) {
 		u64 mode = *vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT);
 
 		switch (mode) {
@@ -240,11 +240,6 @@ 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_set_flag(vcpu, VCPU_HYP_CONTEXT);
-	else
-		vcpu_clear_flag(vcpu, VCPU_HYP_CONTEXT);
-
 	do {
 		/* Jump in the fire! */
 		exit_code = __guest_enter(vcpu);
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:55 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:55 +0000
Subject: [PATCH v2 07/13] KVM: arm64: nv: Honor HFGITR_EL2.ERET being set
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-8-maz@kernel.org>

If the L1 hypervisor decides to trap ERETs while running L2,
make sure we don't try to emulate it, just like we wouldn't
if it had its NV bit set.

The exception will be reinjected from the core handler.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/vhe/switch.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index eaf242b8e0cf..3ea9bdf6b555 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -220,7 +220,8 @@ static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
 	 * Unless the trap has to be forwarded further down the line,
 	 * of course...
 	 */
-	if (__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_NV)
+	if ((__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_NV) ||
+	    (__vcpu_sys_reg(vcpu, HFGITR_EL2) & HFGITR_EL2_ERET))
 		return false;
 
 	spsr = read_sysreg_el1(SYS_SPSR);
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:58 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:58 +0000
Subject: [PATCH v2 10/13] KVM: arm64: nv: Add kvm_has_pauth() helper
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-11-maz@kernel.org>

Pointer Authentication comes in many flavors, and a faithful emulation
relies on correctly handling the flavour implemented by the HW.

For this, provide a new kvm_has_pauth() that checks whether we
expose to the guest a particular level of support. This checks
across all 3 possible authentication algorithms (Q5, Q3 and IMPDEF).

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 75eb8e170515..a97b092b7064 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1334,4 +1334,19 @@ bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
 	(get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
 	 get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
 
+/* Check for a given level of PAuth support */
+#define kvm_has_pauth(k, l)						\
+	({								\
+		bool pa, pi, pa3;					\
+									\
+		pa  = kvm_has_feat((k), ID_AA64ISAR1_EL1, APA, l);	\
+		pa &= kvm_has_feat((k), ID_AA64ISAR1_EL1, GPA, IMP);	\
+		pi  = kvm_has_feat((k), ID_AA64ISAR1_EL1, API, l);	\
+		pi &= kvm_has_feat((k), ID_AA64ISAR1_EL1, GPI, IMP);	\
+		pa3  = kvm_has_feat((k), ID_AA64ISAR2_EL1, APA3, l);	\
+		pa3 &= kvm_has_feat((k), ID_AA64ISAR2_EL1, GPA3, IMP);	\
+									\
+		(pa + pi + pa3) == 1;					\
+	})
+
 #endif /* __ARM64_KVM_HOST_H__ */
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:50 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:50 +0000
Subject: [PATCH v2 02/13] KVM: arm64: Add helpers for ESR_ELx_ERET_ISS_ERET*
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-3-maz@kernel.org>

The ESR_ELx_ERET_ISS_ERET* macros are a bit confusing:

- ESR_ELx_ERET_ISS_ERET really indicates that we have trapped an
  ERETA* instruction, as opposed to an ERET

- ESR_ELx_ERET_ISS_ERETA really indicates that we have trapped
  an ERETAB instruction, as opposed to an ERETAA.

We could repaint those to make more sense, but these are the
names that are present in the ARM ARM, and we are sentimentally
attached to those.

Instead, add two new helpers:

- esr_iss_is_eretax() being true tells you that you need to
  authenticate the ERET

- esr_iss_is_eretab() tells you that you need to use the B key
  instead of the A key

Following patches will make use of these primitives.

Suggested-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/esr.h | 12 ++++++++++++
 arch/arm64/kvm/handle_exit.c |  2 +-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 353fe08546cf..98008c16025e 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -407,6 +407,18 @@ static inline bool esr_fsc_is_access_flag_fault(unsigned long esr)
 	return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_ACCESS;
 }
 
+/* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */
+static inline bool esr_iss_is_eretax(unsigned long esr)
+{
+	return esr & ESR_ELx_ERET_ISS_ERET;
+}
+
+/* Indicate which key is used for ERETAx (false: A-Key, true: B-Key) */
+static inline bool esr_iss_is_eretab(unsigned long esr)
+{
+	return esr & ESR_ELx_ERET_ISS_ERETA;
+}
+
 const char *esr_get_class_string(unsigned long esr);
 #endif /* __ASSEMBLY */
 
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 617ae6dea5d5..15221e481ccd 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -219,7 +219,7 @@ static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
 
 static int kvm_handle_eret(struct kvm_vcpu *vcpu)
 {
-	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERET)
+	if (esr_iss_is_eretax(kvm_vcpu_get_esr(vcpu)))
 		return kvm_handle_ptrauth(vcpu);
 
 	/*
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:53 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:53 +0000
Subject: [PATCH v2 05/13] KVM: arm64: nv: Add trap forwarding for ERET and SMC
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-6-maz@kernel.org>

Honor the trap forwarding bits for both ERET and SMC, using a new
helper that checks for common conditions.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Co-developed-by: Jintack Lim <jintack.lim 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_nested.h |  1 +
 arch/arm64/kvm/emulate-nested.c     | 27 +++++++++++++++++++++++++++
 arch/arm64/kvm/handle_exit.c        |  7 +++++++
 3 files changed, 35 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index c77d795556e1..dbc4e3a67356 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -60,6 +60,7 @@ static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
 	return ttbr0 & ~GENMASK_ULL(63, 48);
 }
 
+extern bool forward_smc_trap(struct kvm_vcpu *vcpu);
 
 int kvm_init_nv_sysregs(struct kvm *kvm);
 
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 4697ba41b3a9..2d80e81ae650 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2117,6 +2117,26 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
 	return true;
 }
 
+static 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 (!is_hyp_ctxt(vcpu) && control_bit_set) {
+		kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+		return true;
+	}
+	return false;
+}
+
+bool forward_smc_trap(struct kvm_vcpu *vcpu)
+{
+	return forward_traps(vcpu, HCR_TSC);
+}
+
 static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)
 {
 	u64 mode = spsr & PSR_MODE_MASK;
@@ -2155,6 +2175,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_traps(vcpu, HCR_NV))
+		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 15221e481ccd..6a88ec024e2f 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -55,6 +55,13 @@ static int handle_hvc(struct kvm_vcpu *vcpu)
 
 static int handle_smc(struct kvm_vcpu *vcpu)
 {
+	/*
+	 * Forward this trapped smc instruction to the virtual EL2 if
+	 * the guest has asked for it.
+	 */
+	if (forward_smc_trap(vcpu))
+		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
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:49 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:49 +0000
Subject: [PATCH v2 01/13] KVM: arm64: Harden __ctxt_sys_reg() against out-of-range values
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-2-maz@kernel.org>

The unsuspecting kernel tinkerer can be easily confused into
writing something that looks like this:

	ikey.lo = __vcpu_sys_reg(vcpu, SYS_APIAKEYLO_EL1);

which seems vaguely sensible, until you realise that the second
parameter is the encoding of a sysreg, and not the index into
the vcpu sysreg file... Debugging what happens in this case is
an interesting exercise in head<->wall interactions.

As they often say: "Any resemblance to actual persons, living
or dead, or actual events is purely coincidental".

In order to save people's time, add some compile-time hardening
that will at least weed out the "stupidly out of range" values.
This will *not* catch anything that isn't a compile-time constant.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 181fef12e8e8..a5ec4c7d3966 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -895,7 +895,7 @@ struct kvm_vcpu_arch {
  * Don't bother with VNCR-based accesses in the nVHE code, it has no
  * business dealing with NV.
  */
-static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
+static inline u64 *___ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
 {
 #if !defined (__KVM_NVHE_HYPERVISOR__)
 	if (unlikely(cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
@@ -905,6 +905,13 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
 	return (u64 *)&ctxt->sys_regs[r];
 }
 
+#define __ctxt_sys_reg(c,r)						\
+	({								\
+	    	BUILD_BUG_ON(__builtin_constant_p(r) &&			\
+			     (r) >= NR_SYS_REGS);			\
+		___ctxt_sys_reg(c, r);					\
+	})
+
 #define ctxt_sys_reg(c,r)	(*__ctxt_sys_reg(c,r))
 
 u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg);
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:52 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:52 +0000
Subject: [PATCH v2 04/13] KVM: arm64: nv: Configure HCR_EL2 for FEAT_NV2
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-5-maz@kernel.org>

Add the HCR_EL2 configuration for FEAT_NV2, adding the required
bits for running a guest hypervisor, and overall merging the
allowed bits provided by the guest.

This heavily replies on unavaliable features being sanitised
when the HCR_EL2 shadow register is accessed, and only a couple
of bits must be explicitly disabled.

Non-NV guests are completely unaffected by any of this.

Reviewed-by: Joey Gouly <joey.gouly at arm.com>
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         | 35 ++++++++++++++++++++++++-
 3 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index e3fcf8c4d5b4..f5f701f309a9 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -271,10 +271,8 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
 	__deactivate_traps_hfgxtr(vcpu);
 }
 
-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 c50f8459e4fc..4103625e46c5 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -40,7 +40,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 58415783fd53..d5fdcea2b366 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -33,11 +33,44 @@ DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data);
 DEFINE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
 DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
 
+/*
+ * HCR_EL2 bits that the NV guest can freely change (no RES0/RES1
+ * semantics, irrespective of the configuration), but that cannot be
+ * applied to the actual HW as things would otherwise break badly.
+ *
+ * - TGE: we want the guest to use EL1, which is incompatible with
+ *   this bit being set
+ *
+ * - API/APK: for hysterical raisins, we enable PAuth lazily, which
+ *   means that the guest's bits cannot be directly applied (we really
+ *   want to see the traps). Revisit this at some point.
+ */
+#define NV_HCR_GUEST_EXCLUDE	(HCR_TGE | HCR_API | HCR_APK)
+
+static u64 __compute_hcr(struct kvm_vcpu *vcpu)
+{
+	u64 hcr = vcpu->arch.hcr_el2;
+
+	if (!vcpu_has_nv(vcpu))
+		return hcr;
+
+	if (is_hyp_ctxt(vcpu)) {
+		hcr |= HCR_NV | HCR_NV2 | HCR_AT | HCR_TTLB;
+
+		if (!vcpu_el2_e2h_is_set(vcpu))
+			hcr |= HCR_NV1;
+
+		write_sysreg_s(vcpu->arch.ctxt.vncr_array, SYS_VNCR_EL2);
+	}
+
+	return hcr | (__vcpu_sys_reg(vcpu, HCR_EL2) & ~NV_HCR_GUEST_EXCLUDE);
+}
+
 static void __activate_traps(struct kvm_vcpu *vcpu)
 {
 	u64 val;
 
-	___activate_traps(vcpu);
+	___activate_traps(vcpu, __compute_hcr(vcpu));
 
 	if (has_cntpoff()) {
 		struct timer_map map;
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:57 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:57 +0000
Subject: [PATCH v2 09/13] KVM: arm64: nv: Reinject PAC exceptions caused by HCR_EL2.API==0
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-10-maz@kernel.org>

In order for a L1 hypervisor to correctly handle PAuth instructions,
it must observe traps caused by a L1 PAuth instruction when
HCR_EL2.API==0. Since we already handle the case for API==1 as
a fixup, only the exception injection case needs to be handled.

Rework the kvm_handle_ptrauth() callback to reinject the trap
in this case. Note that APK==0 is already handled by the exising
triage_sysreg_trap() helper.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/handle_exit.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 6a88ec024e2f..1ba2f788b2c3 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -214,12 +214,34 @@ static int handle_sve(struct kvm_vcpu *vcpu)
 }
 
 /*
- * Guest usage of a ptrauth instruction (which the guest EL1 did not turn into
- * a NOP). If we get here, it is that we didn't fixup ptrauth on exit, and all
- * that we can do is give the guest an UNDEF.
+ * Two possibilities to handle a trapping ptrauth instruction:
+ *
+ * - Guest usage of a ptrauth instruction (which the guest EL1 did not
+ *   turn into a NOP). If we get here, it is that we didn't fixup
+ *   ptrauth on exit, and all that we can do is give the guest an
+ *   UNDEF (as the guest isn't supposed to use ptrauth without being
+ *   told it could).
+ *
+ * - Running an L2 NV guest while L1 has left HCR_EL2.API==0, and for
+ *   which we reinject the exception into L1. API==1 is handled as a
+ *   fixup so the only way to get here is when API==0.
+ *
+ * Anything else is an emulation bug (hence the WARN_ON + UNDEF).
  */
 static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
 {
+	if (!vcpu_has_ptrauth(vcpu)) {
+		kvm_inject_undefined(vcpu);
+		return 1;
+	}
+
+	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
+		kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+		return 1;
+	}
+
+	/* Really shouldn't be here! */
+	WARN_ON_ONCE(1);
 	kvm_inject_undefined(vcpu);
 	return 1;
 }
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:59 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:59 +0000
Subject: [PATCH v2 11/13] KVM: arm64: nv: Add emulation for ERETAx instructions
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-12-maz@kernel.org>

FEAT_NV has the interesting property of relying on ERET being
trapped. An added complexity is that it also traps ERETAA and
ERETAB, meaning that the Pointer Authentication aspect of these
instruction must be emulated.

Add an emulation of Pointer Authentication, limited to ERETAx
(always using SP_EL2 as the modifier and ELR_EL2 as the pointer),
using the Generic Authentication instructions.

The emulation, however small, is placed in its own compilation
unit so that it can be avoided if the configuration doesn't
include it (or the toolchan in not up to the task).

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h    |  12 ++
 arch/arm64/include/asm/pgtable-hwdef.h |   1 +
 arch/arm64/kvm/Makefile                |   1 +
 arch/arm64/kvm/pauth.c                 | 196 +++++++++++++++++++++++++
 4 files changed, 210 insertions(+)
 create mode 100644 arch/arm64/kvm/pauth.c

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index dbc4e3a67356..5e0ab0596246 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -64,4 +64,16 @@ extern bool forward_smc_trap(struct kvm_vcpu *vcpu);
 
 int kvm_init_nv_sysregs(struct kvm *kvm);
 
+#ifdef CONFIG_ARM64_PTR_AUTH
+bool kvm_auth_eretax(struct kvm_vcpu *vcpu, u64 *elr);
+#else
+static inline bool kvm_auth_eretax(struct kvm_vcpu *vcpu, u64 *elr)
+{
+	/* We really should never execute this... */
+	WARN_ON_ONCE(1);
+	*elr = 0xbad9acc0debadbad;
+	return false;
+}
+#endif
+
 #endif /* __ARM64_KVM_NESTED_H */
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index e4944d517c99..bb88e9ef6296 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -277,6 +277,7 @@
 #define TCR_TBI1		(UL(1) << 38)
 #define TCR_HA			(UL(1) << 39)
 #define TCR_HD			(UL(1) << 40)
+#define TCR_TBID0		(UL(1) << 51)
 #define TCR_TBID1		(UL(1) << 52)
 #define TCR_NFD0		(UL(1) << 53)
 #define TCR_NFD1		(UL(1) << 54)
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index c0c050e53157..04882b577575 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -23,6 +23,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 vgic/vgic-its.o vgic/vgic-debug.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
+kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
 
 always-y := hyp_constants.h hyp-constants.s
 
diff --git a/arch/arm64/kvm/pauth.c b/arch/arm64/kvm/pauth.c
new file mode 100644
index 000000000000..a3a5c404375b
--- /dev/null
+++ b/arch/arm64/kvm/pauth.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 - Google LLC
+ * Author: Marc Zyngier <maz at kernel.org>
+ *
+ * Primitive PAuth emulation for ERETAA/ERETAB.
+ *
+ * This code assumes that is is run from EL2, and that it is part of
+ * the emulation of ERETAx for a guest hypervisor. That's a lot of
+ * baked-in assumptions and shortcuts.
+ *
+ * Do no reuse for anything else!
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_emulate.h>
+#include <asm/pointer_auth.h>
+
+static u64 compute_pac(struct kvm_vcpu *vcpu, u64 ptr,
+		       struct ptrauth_key ikey)
+{
+	struct ptrauth_key gkey;
+	u64 mod, pac = 0;
+
+	preempt_disable();
+
+	if (!vcpu_get_flag(vcpu, SYSREGS_ON_CPU))
+		mod = __vcpu_sys_reg(vcpu, SP_EL2);
+	else
+		mod = read_sysreg(sp_el1);
+
+	gkey.lo = read_sysreg_s(SYS_APGAKEYLO_EL1);
+	gkey.hi = read_sysreg_s(SYS_APGAKEYHI_EL1);
+
+	__ptrauth_key_install_nosync(APGA, ikey);
+	isb();
+
+	asm volatile(ARM64_ASM_PREAMBLE ".arch_extension pauth\n"
+		     "pacga %0, %1, %2" : "=r" (pac) : "r" (ptr), "r" (mod));
+	isb();
+
+	__ptrauth_key_install_nosync(APGA, gkey);
+
+	preempt_enable();
+
+	/* PAC in the top 32bits */
+	return pac;
+}
+
+static bool effective_tbi(struct kvm_vcpu *vcpu, bool bit55)
+{
+	u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
+	bool tbi, tbid;
+
+	/*
+	 * Since we are authenticating an instruction address, we have
+	 * to take TBID into account. If E2H==0, ignore VA[55], as
+	 * TCR_EL2 only has a single TBI/TBID. If VA[55] was set in
+	 * this case, this is likely a guest bug...
+	 */
+	if (!vcpu_el2_e2h_is_set(vcpu)) {
+		tbi = tcr & BIT(20);
+		tbid = tcr & BIT(29);
+	} else if (bit55) {
+		tbi = tcr & TCR_TBI1;
+		tbid = tcr & TCR_TBID1;
+	} else {
+		tbi = tcr & TCR_TBI0;
+		tbid = tcr & TCR_TBID0;
+	}
+
+	return tbi && !tbid;
+}
+
+static int compute_bottom_pac(struct kvm_vcpu *vcpu, bool bit55)
+{
+	static const int maxtxsz = 39; // Revisit these two values once
+	static const int mintxsz = 16; // (if) we support TTST/LVA/LVA2
+	u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
+	int txsz;
+
+	if (!vcpu_el2_e2h_is_set(vcpu) || !bit55)
+		txsz = FIELD_GET(TCR_T0SZ_MASK, tcr);
+	else
+		txsz = FIELD_GET(TCR_T1SZ_MASK, tcr);
+
+	return 64 - clamp(txsz, mintxsz, maxtxsz);
+}
+
+static u64 compute_pac_mask(struct kvm_vcpu *vcpu, bool bit55)
+{
+	int bottom_pac;
+	u64 mask;
+
+	bottom_pac = compute_bottom_pac(vcpu, bit55);
+
+	mask = GENMASK(54, bottom_pac);
+	if (!effective_tbi(vcpu, bit55))
+		mask |= GENMASK(63, 56);
+
+	return mask;
+}
+
+static u64 to_canonical_addr(struct kvm_vcpu *vcpu, u64 ptr, u64 mask)
+{
+	bool bit55 = !!(ptr & BIT(55));
+
+	if (bit55)
+		return ptr | mask;
+
+	return ptr & ~mask;
+}
+
+static u64 corrupt_addr(struct kvm_vcpu *vcpu, u64 ptr)
+{
+	bool bit55 = !!(ptr & BIT(55));
+	u64 mask, error_code;
+	int shift;
+
+	if (effective_tbi(vcpu, bit55)) {
+		mask = GENMASK(54, 53);
+		shift = 53;
+	} else {
+		mask = GENMASK(62, 61);
+		shift = 61;
+	}
+
+	if (esr_iss_is_eretab(kvm_vcpu_get_esr(vcpu)))
+		error_code = 2 << shift;
+	else
+		error_code = 1 << shift;
+
+	ptr &= ~mask;
+	ptr |= error_code;
+
+	return ptr;
+}
+
+/*
+ * Authenticate an ERETAA/ERETAB instruction, returning true if the
+ * authentication succeeded and false otherwise. In all cases, *elr
+ * contains the VA to ERET to. Potential exception injection is left
+ * to the caller.
+ */
+bool kvm_auth_eretax(struct kvm_vcpu *vcpu, u64 *elr)
+{
+	u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL2);
+	u64 esr = kvm_vcpu_get_esr(vcpu);
+	u64 ptr, cptr, pac, mask;
+	struct ptrauth_key ikey;
+
+	*elr = ptr = vcpu_read_sys_reg(vcpu, ELR_EL2);
+
+	/* We assume we're already in the context of an ERETAx */
+	if (esr_iss_is_eretab(esr)) {
+		if (!(sctlr & SCTLR_EL1_EnIB))
+			return true;
+
+		ikey.lo = __vcpu_sys_reg(vcpu, APIBKEYLO_EL1);
+		ikey.hi = __vcpu_sys_reg(vcpu, APIBKEYHI_EL1);
+	} else {
+		if (!(sctlr & SCTLR_EL1_EnIA))
+			return true;
+
+		ikey.lo = __vcpu_sys_reg(vcpu, APIAKEYLO_EL1);
+		ikey.hi = __vcpu_sys_reg(vcpu, APIAKEYHI_EL1);
+	}
+
+	mask = compute_pac_mask(vcpu, !!(ptr & BIT(55)));
+	cptr = to_canonical_addr(vcpu, ptr, mask);
+
+	pac = compute_pac(vcpu, cptr, ikey);
+
+	/*
+	 * Slightly deviate from the pseudocode: if we have a PAC
+	 * match with the signed pointer, then it must be good.
+	 * Anything after this point is pure error handling.
+	 */
+	if ((pac & mask) == (ptr & mask)) {
+		*elr = cptr;
+		return true;
+	}
+
+	/*
+	 * Authentication failed, corrupt the canonical address if
+	 * PAuth2 isn't implemented, or some XORing if it is.
+	 */
+	if (!kvm_has_pauth(vcpu->kvm, PAuth2))
+		cptr = corrupt_addr(vcpu, cptr);
+	else
+		cptr = ptr ^ (pac & mask);
+
+	*elr = cptr;
+	return false;
+}
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:48 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:48 +0000
Subject: [PATCH v2 00/13] KVM/arm64: Add NV support for ERET and PAuth
Message-ID: <20240226100601.2379693-1-maz@kernel.org>

This is the second version of this series introducing ERET and PAuth
support for NV guests, and now the base prefix for the NV support
series.

Thanks to Joey for reviewing the first half of the series and
providing valuable suggestions, much appreciated!

* From v1 [1]:

  - Don't repaint the ISS_ERET* definitions, but provide reasonable
    helpers instead
  - Dropped superfluous VNCR_EL2 definition
  - Amended comments and creative spelling

[1] https://lore.kernel.org/r/20240219092014.783809-1-maz at kernel.org

Marc Zyngier (13):
  KVM: arm64: Harden __ctxt_sys_reg() against out-of-range values
  KVM: arm64: Add helpers for ESR_ELx_ERET_ISS_ERET*
  KVM: arm64: nv: Drop VCPU_HYP_CONTEXT flag
  KVM: arm64: nv: Configure HCR_EL2 for FEAT_NV2
  KVM: arm64: nv: Add trap forwarding for ERET and SMC
  KVM: arm64: nv: Fast-track 'InHost' exception returns
  KVM: arm64: nv: Honor HFGITR_EL2.ERET being set
  KVM: arm64: nv: Handle HCR_EL2.{API,APK} independently
  KVM: arm64: nv: Reinject PAC exceptions caused by HCR_EL2.API==0
  KVM: arm64: nv: Add kvm_has_pauth() helper
  KVM: arm64: nv: Add emulation for ERETAx instructions
  KVM: arm64: nv: Handle ERETA[AB] instructions
  KVM: arm64: nv: Advertise support for PAuth

 arch/arm64/include/asm/esr.h            |  12 ++
 arch/arm64/include/asm/kvm_emulate.h    |   5 -
 arch/arm64/include/asm/kvm_host.h       |  26 +++-
 arch/arm64/include/asm/kvm_nested.h     |  13 ++
 arch/arm64/include/asm/pgtable-hwdef.h  |   1 +
 arch/arm64/kvm/Makefile                 |   1 +
 arch/arm64/kvm/emulate-nested.c         |  66 +++++---
 arch/arm64/kvm/handle_exit.c            |  38 ++++-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  36 ++++-
 arch/arm64/kvm/hyp/nvhe/switch.c        |   2 +-
 arch/arm64/kvm/hyp/vhe/switch.c         |  96 +++++++++++-
 arch/arm64/kvm/nested.c                 |   8 +-
 arch/arm64/kvm/pauth.c                  | 196 ++++++++++++++++++++++++
 13 files changed, 444 insertions(+), 56 deletions(-)
 create mode 100644 arch/arm64/kvm/pauth.c

-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:54 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:54 +0000
Subject: [PATCH v2 06/13] KVM: arm64: nv: Fast-track 'InHost' exception returns
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-7-maz@kernel.org>

A significant part of the FEAT_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 | 44 +++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 2d80e81ae650..63a74c0330f1 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2172,8 +2172,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
@@ -2182,33 +2181,11 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
 	if (forward_traps(vcpu, HCR_NV))
 		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 d5fdcea2b366..eaf242b8e0cf 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -206,6 +206,49 @@ void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu)
 	__vcpu_put_switch_sysregs(vcpu);
 }
 
+static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	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);
+	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,
@@ -216,6 +259,7 @@ static const exit_handler_fn hyp_exit_handlers[] = {
 	[ESR_ELx_EC_DABT_LOW]		= kvm_hyp_handle_dabt_low,
 	[ESR_ELx_EC_WATCHPT_LOW]	= kvm_hyp_handle_watchpt_low,
 	[ESR_ELx_EC_PAC]		= kvm_hyp_handle_ptrauth,
+	[ESR_ELx_EC_ERET]		= kvm_hyp_handle_eret,
 	[ESR_ELx_EC_MOPS]		= kvm_hyp_handle_mops,
 };
 
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:05:56 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:05:56 +0000
Subject: [PATCH v2 08/13] KVM: arm64: nv: Handle HCR_EL2.{API,APK} independently
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-9-maz@kernel.org>

Although KVM couples API and APK for simplicity, the architecture
makes no such requirement, and the two can be independently set or
cleared.

Check for which of the two possible reasons we have trapped here,
and if the corresponding L1 control bit isn't set, delegate the
handling for forwarding.

Otherwise, set this exact bit in HCR_EL2 and resume the guest.
Of course, in the non-NV case, we keep setting both bits and
be done with it. Note that the entry core already saves/restores
the keys should any of the two control bits be set.

This results in a bit of rework, and the removal of the (trivial)
vcpu_ptrauth_enable() helper.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h    |  5 ----
 arch/arm64/kvm/hyp/include/hyp/switch.h | 32 +++++++++++++++++++++----
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index debc3753d2ef..d2177bc77844 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -125,11 +125,6 @@ static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu)
 	vcpu->arch.hcr_el2 |= HCR_TWI;
 }
 
-static inline void vcpu_ptrauth_enable(struct kvm_vcpu *vcpu)
-{
-	vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
-}
-
 static inline void vcpu_ptrauth_disable(struct kvm_vcpu *vcpu)
 {
 	vcpu->arch.hcr_el2 &= ~(HCR_API | HCR_APK);
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index f5f701f309a9..a0908d7a8f56 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -480,11 +480,35 @@ DECLARE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
 static bool kvm_hyp_handle_ptrauth(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	struct kvm_cpu_context *ctxt;
-	u64 val;
+	u64 enable = 0;
 
 	if (!vcpu_has_ptrauth(vcpu))
 		return false;
 
+	/*
+	 * NV requires us to handle API and APK independently, just in
+	 * case the hypervisor is totally nuts. Please barf >here<.
+	 */
+	if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
+		switch (ESR_ELx_EC(kvm_vcpu_get_esr(vcpu))) {
+		case ESR_ELx_EC_PAC:
+			if (!(__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_API))
+				return false;
+
+			enable |= HCR_API;
+			break;
+
+		case ESR_ELx_EC_SYS64:
+			if (!(__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_APK))
+				return false;
+
+			enable |= HCR_APK;
+			break;
+		}
+	} else {
+		enable = HCR_API | HCR_APK;
+	}
+
 	ctxt = this_cpu_ptr(&kvm_hyp_ctxt);
 	__ptrauth_save_key(ctxt, APIA);
 	__ptrauth_save_key(ctxt, APIB);
@@ -492,11 +516,9 @@ static bool kvm_hyp_handle_ptrauth(struct kvm_vcpu *vcpu, u64 *exit_code)
 	__ptrauth_save_key(ctxt, APDB);
 	__ptrauth_save_key(ctxt, APGA);
 
-	vcpu_ptrauth_enable(vcpu);
 
-	val = read_sysreg(hcr_el2);
-	val |= (HCR_API | HCR_APK);
-	write_sysreg(val, hcr_el2);
+	vcpu->arch.hcr_el2 |= enable;
+	sysreg_clear_set(hcr_el2, 0, enable);
 
 	return true;
 }
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:06:00 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:06:00 +0000
Subject: [PATCH v2 12/13] KVM: arm64: nv: Handle ERETA[AB] instructions
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-13-maz@kernel.org>

Now that we have some emulation in place for ERETA[AB], we can
plug it into the exception handling machinery.

As for a bare ERET, an "easy" ERETAx instruction is processed as
a fixup, while something that requires a translation regime
transition or an exception delivery is left to the slow path.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 22 ++++++++++++++++++++--
 arch/arm64/kvm/handle_exit.c    |  3 ++-
 arch/arm64/kvm/hyp/vhe/switch.c | 13 +++++++++++--
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 63a74c0330f1..72d733c74a38 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2172,7 +2172,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;
+	u64 spsr, elr, esr;
 
 	/*
 	 * Forward this trap to the virtual EL2 if the virtual
@@ -2181,12 +2181,30 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
 	if (forward_traps(vcpu, HCR_NV))
 		return;
 
+	/* Check for an ERETAx */
+	esr = kvm_vcpu_get_esr(vcpu);
+	if (esr_iss_is_eretax(esr) && !kvm_auth_eretax(vcpu, &elr)) {
+		/*
+		 * Oh no, ERETAx failed to authenticate.  If we have
+		 * FPACCOMBINE, deliver an exception right away.  If we
+		 * don't, then let the mangled ELR value trickle down the
+		 * ERET handling, and the guest will have a little surprise.
+		 */
+		if (kvm_has_pauth(vcpu->kvm, FPACCOMBINE)) {
+			esr &= ESR_ELx_ERET_ISS_ERETA;
+			esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_FPAC);
+			kvm_inject_nested_sync(vcpu, esr);
+			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);
+	if (!esr_iss_is_eretax(esr))
+		elr = __vcpu_sys_reg(vcpu, ELR_EL2);
 
 	trace_kvm_nested_eret(vcpu, elr, spsr);
 
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 1ba2f788b2c3..407bdfbb572b 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -248,7 +248,8 @@ static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
 
 static int kvm_handle_eret(struct kvm_vcpu *vcpu)
 {
-	if (esr_iss_is_eretax(kvm_vcpu_get_esr(vcpu)))
+	if (esr_iss_is_eretax(kvm_vcpu_get_esr(vcpu)) &&
+	    !vcpu_has_ptrauth(vcpu))
 		return kvm_handle_ptrauth(vcpu);
 
 	/*
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 3ea9bdf6b555..49d36666040e 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -208,7 +208,8 @@ void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu)
 
 static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
-	u64 spsr, mode;
+	u64 esr = kvm_vcpu_get_esr(vcpu);
+	u64 spsr, elr, mode;
 
 	/*
 	 * Going through the whole put/load motions is a waste of time
@@ -242,10 +243,18 @@ static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
 		return false;
 	}
 
+	/* If ERETAx fails, take the slow path */
+	if (esr_iss_is_eretax(esr)) {
+		if (!(vcpu_has_ptrauth(vcpu) && kvm_auth_eretax(vcpu, &elr)))
+			return false;
+	} else {
+		elr = read_sysreg_el1(SYS_ELR);
+	}
+
 	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);
+	write_sysreg_el2(elr, SYS_ELR);
 
 	return true;
 }
-- 
2.39.2



From maz at kernel.org  Mon Feb 26 02:06:01 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 10:06:01 +0000
Subject: [PATCH v2 13/13] KVM: arm64: nv: Advertise support for PAuth
In-Reply-To: <20240226100601.2379693-1-maz@kernel.org>
References: <20240226100601.2379693-1-maz@kernel.org>
Message-ID: <20240226100601.2379693-14-maz@kernel.org>

Now that we (hopefully) correctly handle ERETAx, drop the masking
of the PAuth feature (something that was not even complete, as
APA3 and AGA3 were still exposed).

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/nested.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index ced30c90521a..6813c7c7f00a 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -35,13 +35,9 @@ static u64 limit_nv_id_reg(u32 id, u64 val)
 		break;
 
 	case SYS_ID_AA64ISAR1_EL1:
-		/* Support everything but PtrAuth and Spec Invalidation */
+		/* Support everything but Spec Invalidation */
 		val &= ~(GENMASK_ULL(63, 56)	|
-			 NV_FTR(ISAR1, SPECRES)	|
-			 NV_FTR(ISAR1, GPI)	|
-			 NV_FTR(ISAR1, GPA)	|
-			 NV_FTR(ISAR1, API)	|
-			 NV_FTR(ISAR1, APA));
+			 NV_FTR(ISAR1, SPECRES));
 		break;
 
 	case SYS_ID_AA64PFR0_EL1:
-- 
2.39.2



From theo.lebrun at bootlin.com  Mon Feb 26 02:13:36 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 26 Feb 2024 11:13:36 +0100
Subject: [PATCH v3 4/8] usb: cdns3-ti: support reset-on-resume behavior
In-Reply-To: <b778d2e8-3fcf-afe4-2e48-0348be19a085@gmail.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
 <20240223-j7200-usb-suspend-v3-4-b41c9893a130@bootlin.com>
 <b778d2e8-3fcf-afe4-2e48-0348be19a085@gmail.com>
Message-ID: <CZEXIZWQO1XB.1YY4P72A2K1HJ@bootlin.com>

Hello Sergey,

On Sat Feb 24, 2024 at 10:08 AM CET, Sergei Shtylyov wrote:
> On 2/23/24 7:05 PM, Th?o Lebrun wrote:
> > Add match data support, with one boolean to indicate whether the
> > hardware resets after a system-wide suspend. If hardware resets, we
> > force execute ->runtime_resume() at system-wide resume to run the
> > hardware init sequence.
> > 
> > No compatible exploits this functionality, just yet.
> > 
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> > ---
> >  drivers/usb/cdns3/cdns3-ti.c | 27 +++++++++++++++++++++++++++
> >  1 file changed, 27 insertions(+)
> > 
> > diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c
> > index 4c8a557e6a6f..f76327566798 100644
> > --- a/drivers/usb/cdns3/cdns3-ti.c
> > +++ b/drivers/usb/cdns3/cdns3-ti.c
> [...]
> > @@ -220,8 +226,29 @@ static int cdns_ti_runtime_resume(struct device *dev)
> >  	return 0;
> >  }
> >  
> > +static int cdns_ti_suspend(struct device *dev)
> > +{
> > +	struct cdns_ti *data = dev_get_drvdata(dev);
> > +
> > +	if (data->match_data && data->match_data->reset_on_resume)
> > +		return pm_runtime_force_suspend(dev);
> > +	else
>
>    Pointless *else* after *return*...

Indeed! I used this form explicitely as it reads nicely: "if reset on
reset, force suspend, else do nothing". It also prevents the error of
adding behavior below the if-statement without seeing that it won't
apply to both cases.

If you do believe it would make the code better I'll happily change it
for the next revision, I do not mind.

Thanks for the review Sergey!

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From suzuki.poulose at arm.com  Mon Feb 26 02:14:56 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 26 Feb 2024 10:14:56 +0000
Subject: [PATCH v5 6/7] arm64: KVM: Write TRFCR value on guest switch with
 nVHE
In-Reply-To: <20240220100924.2761706-7-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
 <20240220100924.2761706-7-james.clark@arm.com>
Message-ID: <1d2a6c09-6892-48fc-a7fb-e171c7fbd814@arm.com>

On 20/02/2024 10:09, James Clark wrote:
> The guest value for TRFCR requested by the Coresight driver is saved in
> kvm_guest_trfcr. On guest switch this value needs to be written to
> the register. Currently TRFCR is only modified when we want to disable
> trace completely in guests due to an issue with TRBE. Expand the
> __debug_save_trace() function to always write to the register if a
> different value for guests is required, but also keep the existing TRBE
> disable behavior if that's required.
> 
> In pKVM, the kvm_guest_trfcr can't be read and the host isn't trusted,
> so always disable trace.
> 
> __debug_restore_trace() now has to restore unconditionally, because even
> a value of 0 needs to be written to overwrite whatever was set for the
> guest.
> 
> Signed-off-by: James Clark <james.clark at arm.com>

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>


> ---
>   arch/arm64/kvm/hyp/nvhe/debug-sr.c | 53 +++++++++++++++++-------------
>   1 file changed, 31 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> index 4558c02eb352..3adac2e01908 100644
> --- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> +++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> @@ -51,30 +51,39 @@ static void __debug_restore_spe(u64 pmscr_el1)
>   	write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
>   }
>   
> -static void __debug_save_trace(u64 *trfcr_el1)
> +static void __debug_save_trace(struct kvm_vcpu *vcpu)
>   {
> -	*trfcr_el1 = 0;
> -
> -	/* Check if the TRBE is enabled */
> -	if (!(read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E))
> -		return;
> -	/*
> -	 * Prohibit trace generation while we are in guest.
> -	 * Since access to TRFCR_EL1 is trapped, the guest can't
> -	 * modify the filtering set by the host.
> -	 */
> -	*trfcr_el1 = read_sysreg_s(SYS_TRFCR_EL1);
> -	write_sysreg_s(0, SYS_TRFCR_EL1);
> -	isb();
> -	/* Drain the trace buffer to memory */
> -	tsb_csync();
> +	u64 host_trfcr_el1 = read_sysreg_s(SYS_TRFCR_EL1);
> +	u64 guest_trfcr_el1;
> +
> +	vcpu->arch.host_debug_state.trfcr_el1 = host_trfcr_el1;
> +
> +	/* Check if the TRBE buffer or pKVM is enabled */
> +	if (is_protected_kvm_enabled() ||
> +	    (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE) &&
> +	     read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E)) {
> +		/*
> +		 * Prohibit trace generation while we are in guest. Since access
> +		 * to TRFCR_EL1 is trapped, the guest can't modify the filtering
> +		 * set by the host.
> +		 */
> +		write_sysreg_s(0, SYS_TRFCR_EL1);
> +		isb();
> +		/* Drain the trace buffer to memory */
> +		tsb_csync();
> +	} else {
> +		/*
> +		 * Tracing is allowed, apply the filters provided by the
> +		 * Coresight driver.
> +		 */
> +		guest_trfcr_el1 = kvm_guest_trfcr[vcpu->cpu];
> +		if (host_trfcr_el1 != guest_trfcr_el1)
> +			write_sysreg_s(guest_trfcr_el1, SYS_TRFCR_EL1);
> +	}
>   }
>   
>   static void __debug_restore_trace(u64 trfcr_el1)
>   {
> -	if (!trfcr_el1)
> -		return;
> -
>   	/* Restore trace filter controls */
>   	write_sysreg_s(trfcr_el1, SYS_TRFCR_EL1);
>   }
> @@ -85,8 +94,8 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
>   	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE))
>   		__debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1);
>   	/* Disable and flush Self-Hosted Trace generation */
> -	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE))
> -		__debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1);
> +	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRFCR))
> +		__debug_save_trace(vcpu);
>   }
>   
>   void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
> @@ -98,7 +107,7 @@ void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu)
>   {
>   	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE))
>   		__debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1);
> -	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE))
> +	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRFCR))
>   		__debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1);
>   }
>   



From miquel.raynal at bootlin.com  Mon Feb 26 02:21:32 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:21:32 +0100
Subject: [PATCH] MAINTAINERS: Remove T Ambarus from few mchp entries
In-Reply-To: <20240226094718.29104-1-tudor.ambarus@linaro.org>
References: <20240226094718.29104-1-tudor.ambarus@linaro.org>
Message-ID: <20240226112132.22025454@xps-13>

Hi Tudor,

tudor.ambarus at linaro.org wrote on Mon, 26 Feb 2024 11:47:18 +0200:

> I have been no longer at Microchip for more than a year and I'm no
> longer interested in maintaining these drivers. Let other mchp people
> step up, thus remove myself. Thanks for the nice collaboration everyone!
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
> ---
> Shall be queued through the at91 tree.
> 
>  MAINTAINERS | 14 --------------
>  1 file changed, 14 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e1475ca38ff2..fd4d4e58fead 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14350,7 +14350,6 @@ F:	drivers/misc/xilinx_tmr_manager.c
>  
>  MICROCHIP AT91 DMA DRIVERS
>  M:	Ludovic Desroches <ludovic.desroches at microchip.com>
> -M:	Tudor Ambarus <tudor.ambarus at linaro.org>
>  L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>  L:	dmaengine at vger.kernel.org
>  S:	Supported
> @@ -14398,12 +14397,6 @@ S:	Supported
>  F:	Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
>  F:	drivers/media/platform/microchip/microchip-csi2dc.c
>  
> -MICROCHIP ECC DRIVER
> -M:	Tudor Ambarus <tudor.ambarus at linaro.org>
> -L:	linux-crypto at vger.kernel.org
> -S:	Maintained
> -F:	drivers/crypto/atmel-ecc.*
> -
>  MICROCHIP EIC DRIVER
>  M:	Claudiu Beznea <claudiu.beznea at tuxon.dev>
>  L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> @@ -14505,13 +14498,6 @@ M:	Aubin Constans <aubin.constans at microchip.com>
>  S:	Maintained
>  F:	drivers/mmc/host/atmel-mci.c
>  
> -MICROCHIP NAND DRIVER
> -M:	Tudor Ambarus <tudor.ambarus at linaro.org>
> -L:	linux-mtd at lists.infradead.org
> -S:	Supported
> -F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
> -F:	drivers/mtd/nand/raw/atmel/*

Could we mark these entries orphaned instead of removing them?

> -
>  MICROCHIP OTPC DRIVER
>  M:	Claudiu Beznea <claudiu.beznea at tuxon.dev>
>  L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)


Thanks,
Miqu?l


From cki-project at redhat.com  Mon Feb 26 02:25:31 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Mon, 26 Feb 2024 10:25:31 -0000
Subject: =?utf-8?b?4pyF?= PASS (MISSED 16 of 87): Test report for for-kernelci
 (6.8.0-rc5, arm-next, 9abbc241)
Message-ID: <01197.124022605253100440@us-mta-611.us.mimecast.lan>

Hi, we tested your kernel and here are the results:

    Overall result: PASSED
             Merge: OK
           Compile: OK
              Test: OK

Tested-by: CKI Project <cki-project at redhat.com>

Kernel information:
    Commit message: Merge branch 'for-next/core' into for-kernelci

You can find all the details about the test run at
    https://datawarehouse.cki-project.org/kcidb/checkouts/130933

One or more kernel tests failed:
    We also see the following known issues which are not related to your changes:
        Issue: [rawhide] avc:  denied  { read write } for  pid=12364 comm="plymouthd" name="kmsg" dev="devtmpfs" ino=10 scontext=system_u:system_r:plymouthd_t:s0 tcontext=system_u:object_r:kmsg_device_t:s0 tclass=chr_file permissive=1
            URL: https://bugzilla.redhat.com/show_bug.cgi?id=2256442
            Affected tests:
                 aarch64 - Boot test
                 aarch64 - stress: stress-ng - cpu-cache
                 aarch64 - Reboot test
        Issue: [upstream] blktests tests nbd/001 failed
            URL: https://github.com/osandov/blktests/issues/132
            Affected tests:
                 aarch64 - Storage - blktests - blk - upstream
        Issue: [upstream] blktests tests/zbd/010 failed (WARNING: CPU: 22 PID: 44011 at fs/iomap/iter.c:51)
            URL: https://lore.kernel.org/linux-block/CAHj4cs-kfojYC9i0G73PRkYzcxCTex=-vugRFeP40g_URGvnfQ at mail.gmail.com/T/#u
            Affected tests:
                 aarch64 - Storage - blktests - blk - upstream
        Issue: [upstream] stress-ng: avc denial on secretmemory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1752
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: stress: stress-ng - memory: (panic) Comm: systemd-oomd Not tainted 6.1.0-rc3
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1461
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: Firmware test suite: mv: cannot stat 'dtcompilerparser.tab.c': No such file or directory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1544
            Affected tests:
                 aarch64 - Hardware - Firmware test suite


Tests that were not ran because of internal issues: 
     aarch64 - CKI/restraint
     aarch64 - SELinux Custom Module Setup
     aarch64 - machineinfo
     aarch64 - Boot test
     aarch64 - Storage - blktests - blk - upstream
     aarch64 - Storage - blktests - nvme-tcp - upstream
     aarch64 - Storage - swraid scsi_raid
     aarch64 - stress: stress-ng - cpu-cache
     aarch64 - stress: stress-ng - memory
     aarch64 - Reboot test
     aarch64 - Memory function: memfd_create
     aarch64 - Memory function: memfd_create
     aarch64 - xfstests - ext4
     aarch64 - xfstests - xfs
     aarch64 - xfstests - btrfs
     aarch64 - Reboot test


If you find a failure unrelated to your changes, please ask the test maintainer to review it.
This will prevent the failures from being incorrectly reported in the future.

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
           `-'
______________________________________________________________________________



From cki-project at redhat.com  Mon Feb 26 02:27:02 2024
From: cki-project at redhat.com (cki-project at redhat.com)
Date: Mon, 26 Feb 2024 10:27:02 -0000
Subject: =?utf-8?b?4pyF?= PASS (MISSED 2 of 87): Test report for for-kernelci
 (6.8.0-rc5, arm-next, 59a96b71)
Message-ID: <12048.124022605270300109@us-mta-27.us.mimecast.lan>

Hi, we tested your kernel and here are the results:

    Overall result: PASSED
             Merge: OK
           Compile: OK
              Test: OK

Tested-by: CKI Project <cki-project at redhat.com>

Kernel information:
    Commit message: Merge branch 'for-next/core' into for-kernelci

You can find all the details about the test run at
    https://datawarehouse.cki-project.org/kcidb/checkouts/130633

One or more kernel tests failed:
    We also see the following known issues which are not related to your changes:
        Issue: [rawhide] avc:  denied  { read write } for  pid=12364 comm="plymouthd" name="kmsg" dev="devtmpfs" ino=10 scontext=system_u:system_r:plymouthd_t:s0 tcontext=system_u:object_r:kmsg_device_t:s0 tclass=chr_file permissive=1
            URL: https://bugzilla.redhat.com/show_bug.cgi?id=2256442
            Affected tests:
                 aarch64 - Boot test
                 aarch64 - stress: stress-ng - cpu-cache
                 aarch64 - Reboot test
        Issue: [upstream] blktests tests nbd/001 failed
            URL: https://github.com/osandov/blktests/issues/132
            Affected tests:
                 aarch64 - Storage - blktests - blk - upstream
        Issue: [upstream] blktests tests/zbd/010 failed (WARNING: CPU: 22 PID: 44011 at fs/iomap/iter.c:51)
            URL: https://lore.kernel.org/linux-block/CAHj4cs-kfojYC9i0G73PRkYzcxCTex=-vugRFeP40g_URGvnfQ at mail.gmail.com/T/#u
            Affected tests:
                 aarch64 - Storage - blktests - blk - upstream
        Issue: [upstream] stress-ng: avc denial on secretmemory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1752
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: stress: stress-ng - memory: (panic) Comm: systemd-oomd Not tainted 6.1.0-rc3
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1461
            Affected tests:
                 aarch64 - stress: stress-ng - memory
        Issue: Firmware test suite: mv: cannot stat 'dtcompilerparser.tab.c': No such file or directory
            URL: https://gitlab.com/redhat/centos-stream/tests/kernel/kernel-tests/-/issues/1544
            Affected tests:
                 aarch64 - Hardware - Firmware test suite


Tests that were not ran because of internal issues: 
     aarch64 - Memory function: memfd_create
     aarch64 - Memory function: memfd_create


If you find a failure unrelated to your changes, please ask the test maintainer to review it.
This will prevent the failures from being incorrectly reported in the future.

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
           `-'
______________________________________________________________________________



From quic_kuldsing at quicinc.com  Mon Feb 26 02:29:56 2024
From: quic_kuldsing at quicinc.com (Kuldeep Singh)
Date: Mon, 26 Feb 2024 15:59:56 +0530
Subject: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
In-Reply-To: <CAMRc=Mc_iwMzKznfUknm+RwS3jN_GimpirdTDVCPtnYYS_1PNg@mail.gmail.com>
References: <20240205182810.58382-1-brgl@bgdev.pl>
 <20240205182810.58382-3-brgl@bgdev.pl>
 <tnylagkmj36lve2ub5voumtkqjdy6j3hr6yyk4mqkaabvc3gdv@voaiu2oqi73o>
 <CAMRc=McmfufqqEvouRCjY1ukVB_ie1r5QEocqRUK0VBheEq5Hg@mail.gmail.com>
 <CAMRc=Mc_iwMzKznfUknm+RwS3jN_GimpirdTDVCPtnYYS_1PNg@mail.gmail.com>
Message-ID: <20240226102955.GA19256@hu-kuldsing-hyd.qualcomm.com>

> > > As we're not moving from the callers freely allocating what they need,
> > > to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> > > so that we have something to fall back on when someone runs out of this
> > > space, or wonders "why not 128kb?".
> > >
> >
> > If you worry about these pools being taken out of the total memory and
> > prefer to have a way to avoid it, I was thinking about another
> > build-time mode for the allocator - one where there's no pool but it
> > just allocates chunks using dma_alloc_coherent() like before and pool
> > size is ignored. Does it sound good?
> >
> 
> Or we could even have an argument for the initial size of the pool and
> then once it's exhausted, we'd add a new chunk (maybe twice the size?)
> and so on.

Hi Bartosz,

Thanks for shmbridge patch series. Few questions.

	1. With current design of every client maintaining it's own pool,
	For any target, we might end up occupying lot more space by
	different clients than we actually need.

	2. Also, there's no option to configure pool size for each client at
	runtime level and a fixed 256K value is chosen for qcom_scm/qseecom.
	Pool size will be same for each target and thus making it less
	scalabale if there's adjustment needed at target specific level.
	Ex: For a low DDR memory target, pool size should scale down accordingly
	as 256K will become a big ask but there's no way to choose specific pool
	size for just one target.
		2.1 One way to do configure custom pool size value is to add new
		property in qcom_scm/qseecom or client DT node and then create
		pool of size with this provided value. Though there are ways to
		tackle this, but still clients specifying it's own pool size
		will always fetch more CMA region than what is actually needed.

Can you please share your ideas as well for upcoming version.

Regards
Kuldeep


From suzuki.poulose at arm.com  Mon Feb 26 02:30:19 2024
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 26 Feb 2024 10:30:19 +0000
Subject: [PATCH v5 2/7] arm64/sysreg/tools: Update tools copy of sysreg.h
In-Reply-To: <20240220100924.2761706-3-james.clark@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
 <20240220100924.2761706-3-james.clark@arm.com>
Message-ID: <122af748-327a-4272-a494-f53722333fdd@arm.com>

On 20/02/2024 10:09, James Clark wrote:

Super minor nit: Subject:

"tools: arm64: Update sysreg.h header files"


> Created with the following:
> 
>    cp include/linux/kasan-tags.h tools/include/linux/
>    cp arch/arm64/include/asm/sysreg.h tools/arch/arm64/include/asm/
> 
> Update the tools copy of sysreg.h so that the next commit to add a new
> register doesn't have unrelated changes in it. Because the new version
> of sysreg.h includes kasan-tags.h, that file also now needs to be copied
> into tools.
> 
> Signed-off-by: James Clark <james.clark at arm.com>

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>


> ---
>   tools/arch/arm64/include/asm/sysreg.h | 363 +++++++++++++++++++++++++-
>   tools/include/linux/kasan-tags.h      |  15 ++
>   2 files changed, 375 insertions(+), 3 deletions(-)
>   create mode 100644 tools/include/linux/kasan-tags.h
> 
> diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
> index ccc13e991376..9e8999592f3a 100644
> --- a/tools/arch/arm64/include/asm/sysreg.h
> +++ b/tools/arch/arm64/include/asm/sysreg.h
> @@ -11,6 +11,7 @@
>   
>   #include <linux/bits.h>
>   #include <linux/stringify.h>
> +#include <linux/kasan-tags.h>
>   
>   #include <asm/gpr-num.h>
>   
> @@ -123,6 +124,37 @@
>   #define SYS_DC_CIGSW			sys_insn(1, 0, 7, 14, 4)
>   #define SYS_DC_CIGDSW			sys_insn(1, 0, 7, 14, 6)
>   
> +#define SYS_IC_IALLUIS			sys_insn(1, 0, 7, 1, 0)
> +#define SYS_IC_IALLU			sys_insn(1, 0, 7, 5, 0)
> +#define SYS_IC_IVAU			sys_insn(1, 3, 7, 5, 1)
> +
> +#define SYS_DC_IVAC			sys_insn(1, 0, 7, 6, 1)
> +#define SYS_DC_IGVAC			sys_insn(1, 0, 7, 6, 3)
> +#define SYS_DC_IGDVAC			sys_insn(1, 0, 7, 6, 5)
> +
> +#define SYS_DC_CVAC			sys_insn(1, 3, 7, 10, 1)
> +#define SYS_DC_CGVAC			sys_insn(1, 3, 7, 10, 3)
> +#define SYS_DC_CGDVAC			sys_insn(1, 3, 7, 10, 5)
> +
> +#define SYS_DC_CVAU			sys_insn(1, 3, 7, 11, 1)
> +
> +#define SYS_DC_CVAP			sys_insn(1, 3, 7, 12, 1)
> +#define SYS_DC_CGVAP			sys_insn(1, 3, 7, 12, 3)
> +#define SYS_DC_CGDVAP			sys_insn(1, 3, 7, 12, 5)
> +
> +#define SYS_DC_CVADP			sys_insn(1, 3, 7, 13, 1)
> +#define SYS_DC_CGVADP			sys_insn(1, 3, 7, 13, 3)
> +#define SYS_DC_CGDVADP			sys_insn(1, 3, 7, 13, 5)
> +
> +#define SYS_DC_CIVAC			sys_insn(1, 3, 7, 14, 1)
> +#define SYS_DC_CIGVAC			sys_insn(1, 3, 7, 14, 3)
> +#define SYS_DC_CIGDVAC			sys_insn(1, 3, 7, 14, 5)
> +
> +/* Data cache zero operations */
> +#define SYS_DC_ZVA			sys_insn(1, 3, 7, 4, 1)
> +#define SYS_DC_GVA			sys_insn(1, 3, 7, 4, 3)
> +#define SYS_DC_GZVA			sys_insn(1, 3, 7, 4, 4)
> +
>   /*
>    * Automatically generated definitions for system registers, the
>    * manual encodings below are in the process of being converted to
> @@ -162,6 +194,84 @@
>   #define SYS_DBGDTRTX_EL0		sys_reg(2, 3, 0, 5, 0)
>   #define SYS_DBGVCR32_EL2		sys_reg(2, 4, 0, 7, 0)
>   
> +#define SYS_BRBINF_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 0))
> +#define SYS_BRBINFINJ_EL1		sys_reg(2, 1, 9, 1, 0)
> +#define SYS_BRBSRC_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 1))
> +#define SYS_BRBSRCINJ_EL1		sys_reg(2, 1, 9, 1, 1)
> +#define SYS_BRBTGT_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 2))
> +#define SYS_BRBTGTINJ_EL1		sys_reg(2, 1, 9, 1, 2)
> +#define SYS_BRBTS_EL1			sys_reg(2, 1, 9, 0, 2)
> +
> +#define SYS_BRBCR_EL1			sys_reg(2, 1, 9, 0, 0)
> +#define SYS_BRBFCR_EL1			sys_reg(2, 1, 9, 0, 1)
> +#define SYS_BRBIDR0_EL1			sys_reg(2, 1, 9, 2, 0)
> +
> +#define SYS_TRCITECR_EL1		sys_reg(3, 0, 1, 2, 3)
> +#define SYS_TRCACATR(m)			sys_reg(2, 1, 2, ((m & 7) << 1), (2 | (m >> 3)))
> +#define SYS_TRCACVR(m)			sys_reg(2, 1, 2, ((m & 7) << 1), (0 | (m >> 3)))
> +#define SYS_TRCAUTHSTATUS		sys_reg(2, 1, 7, 14, 6)
> +#define SYS_TRCAUXCTLR			sys_reg(2, 1, 0, 6, 0)
> +#define SYS_TRCBBCTLR			sys_reg(2, 1, 0, 15, 0)
> +#define SYS_TRCCCCTLR			sys_reg(2, 1, 0, 14, 0)
> +#define SYS_TRCCIDCCTLR0		sys_reg(2, 1, 3, 0, 2)
> +#define SYS_TRCCIDCCTLR1		sys_reg(2, 1, 3, 1, 2)
> +#define SYS_TRCCIDCVR(m)		sys_reg(2, 1, 3, ((m & 7) << 1), 0)
> +#define SYS_TRCCLAIMCLR			sys_reg(2, 1, 7, 9, 6)
> +#define SYS_TRCCLAIMSET			sys_reg(2, 1, 7, 8, 6)
> +#define SYS_TRCCNTCTLR(m)		sys_reg(2, 1, 0, (4 | (m & 3)), 5)
> +#define SYS_TRCCNTRLDVR(m)		sys_reg(2, 1, 0, (0 | (m & 3)), 5)
> +#define SYS_TRCCNTVR(m)			sys_reg(2, 1, 0, (8 | (m & 3)), 5)
> +#define SYS_TRCCONFIGR			sys_reg(2, 1, 0, 4, 0)
> +#define SYS_TRCDEVARCH			sys_reg(2, 1, 7, 15, 6)
> +#define SYS_TRCDEVID			sys_reg(2, 1, 7, 2, 7)
> +#define SYS_TRCEVENTCTL0R		sys_reg(2, 1, 0, 8, 0)
> +#define SYS_TRCEVENTCTL1R		sys_reg(2, 1, 0, 9, 0)
> +#define SYS_TRCEXTINSELR(m)		sys_reg(2, 1, 0, (8 | (m & 3)), 4)
> +#define SYS_TRCIDR0			sys_reg(2, 1, 0, 8, 7)
> +#define SYS_TRCIDR10			sys_reg(2, 1, 0, 2, 6)
> +#define SYS_TRCIDR11			sys_reg(2, 1, 0, 3, 6)
> +#define SYS_TRCIDR12			sys_reg(2, 1, 0, 4, 6)
> +#define SYS_TRCIDR13			sys_reg(2, 1, 0, 5, 6)
> +#define SYS_TRCIDR1			sys_reg(2, 1, 0, 9, 7)
> +#define SYS_TRCIDR2			sys_reg(2, 1, 0, 10, 7)
> +#define SYS_TRCIDR3			sys_reg(2, 1, 0, 11, 7)
> +#define SYS_TRCIDR4			sys_reg(2, 1, 0, 12, 7)
> +#define SYS_TRCIDR5			sys_reg(2, 1, 0, 13, 7)
> +#define SYS_TRCIDR6			sys_reg(2, 1, 0, 14, 7)
> +#define SYS_TRCIDR7			sys_reg(2, 1, 0, 15, 7)
> +#define SYS_TRCIDR8			sys_reg(2, 1, 0, 0, 6)
> +#define SYS_TRCIDR9			sys_reg(2, 1, 0, 1, 6)
> +#define SYS_TRCIMSPEC(m)		sys_reg(2, 1, 0, (m & 7), 7)
> +#define SYS_TRCITEEDCR			sys_reg(2, 1, 0, 2, 1)
> +#define SYS_TRCOSLSR			sys_reg(2, 1, 1, 1, 4)
> +#define SYS_TRCPRGCTLR			sys_reg(2, 1, 0, 1, 0)
> +#define SYS_TRCQCTLR			sys_reg(2, 1, 0, 1, 1)
> +#define SYS_TRCRSCTLR(m)		sys_reg(2, 1, 1, (m & 15), (0 | (m >> 4)))
> +#define SYS_TRCRSR			sys_reg(2, 1, 0, 10, 0)
> +#define SYS_TRCSEQEVR(m)		sys_reg(2, 1, 0, (m & 3), 4)
> +#define SYS_TRCSEQRSTEVR		sys_reg(2, 1, 0, 6, 4)
> +#define SYS_TRCSEQSTR			sys_reg(2, 1, 0, 7, 4)
> +#define SYS_TRCSSCCR(m)			sys_reg(2, 1, 1, (m & 7), 2)
> +#define SYS_TRCSSCSR(m)			sys_reg(2, 1, 1, (8 | (m & 7)), 2)
> +#define SYS_TRCSSPCICR(m)		sys_reg(2, 1, 1, (m & 7), 3)
> +#define SYS_TRCSTALLCTLR		sys_reg(2, 1, 0, 11, 0)
> +#define SYS_TRCSTATR			sys_reg(2, 1, 0, 3, 0)
> +#define SYS_TRCSYNCPR			sys_reg(2, 1, 0, 13, 0)
> +#define SYS_TRCTRACEIDR			sys_reg(2, 1, 0, 0, 1)
> +#define SYS_TRCTSCTLR			sys_reg(2, 1, 0, 12, 0)
> +#define SYS_TRCVICTLR			sys_reg(2, 1, 0, 0, 2)
> +#define SYS_TRCVIIECTLR			sys_reg(2, 1, 0, 1, 2)
> +#define SYS_TRCVIPCSSCTLR		sys_reg(2, 1, 0, 3, 2)
> +#define SYS_TRCVISSCTLR			sys_reg(2, 1, 0, 2, 2)
> +#define SYS_TRCVMIDCCTLR0		sys_reg(2, 1, 3, 2, 2)
> +#define SYS_TRCVMIDCCTLR1		sys_reg(2, 1, 3, 3, 2)
> +#define SYS_TRCVMIDCVR(m)		sys_reg(2, 1, 3, ((m & 7) << 1), 1)
> +
> +/* ETM */
> +#define SYS_TRCOSLAR			sys_reg(2, 1, 1, 0, 4)
> +
> +#define SYS_BRBCR_EL2			sys_reg(2, 4, 9, 0, 0)
> +
>   #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)
> @@ -202,8 +312,13 @@
>   #define SYS_ERXCTLR_EL1			sys_reg(3, 0, 5, 4, 1)
>   #define SYS_ERXSTATUS_EL1		sys_reg(3, 0, 5, 4, 2)
>   #define SYS_ERXADDR_EL1			sys_reg(3, 0, 5, 4, 3)
> +#define SYS_ERXPFGF_EL1			sys_reg(3, 0, 5, 4, 4)
> +#define SYS_ERXPFGCTL_EL1		sys_reg(3, 0, 5, 4, 5)
> +#define SYS_ERXPFGCDN_EL1		sys_reg(3, 0, 5, 4, 6)
>   #define SYS_ERXMISC0_EL1		sys_reg(3, 0, 5, 5, 0)
>   #define SYS_ERXMISC1_EL1		sys_reg(3, 0, 5, 5, 1)
> +#define SYS_ERXMISC2_EL1		sys_reg(3, 0, 5, 5, 2)
> +#define SYS_ERXMISC3_EL1		sys_reg(3, 0, 5, 5, 3)
>   #define SYS_TFSR_EL1			sys_reg(3, 0, 5, 6, 0)
>   #define SYS_TFSRE0_EL1			sys_reg(3, 0, 5, 6, 1)
>   
> @@ -274,6 +389,8 @@
>   #define SYS_ICC_IGRPEN0_EL1		sys_reg(3, 0, 12, 12, 6)
>   #define SYS_ICC_IGRPEN1_EL1		sys_reg(3, 0, 12, 12, 7)
>   
> +#define SYS_ACCDATA_EL1			sys_reg(3, 0, 13, 0, 5)
> +
>   #define SYS_CNTKCTL_EL1			sys_reg(3, 0, 14, 1, 0)
>   
>   #define SYS_AIDR_EL1			sys_reg(3, 1, 0, 0, 7)
> @@ -369,6 +486,7 @@
>   
>   #define SYS_SCTLR_EL2			sys_reg(3, 4, 1, 0, 0)
>   #define SYS_ACTLR_EL2			sys_reg(3, 4, 1, 0, 1)
> +#define SYS_SCTLR2_EL2			sys_reg(3, 4, 1, 0, 3)
>   #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)
> @@ -382,12 +500,15 @@
>   #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
>   
>   #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
> -#define SYS_HDFGRTR_EL2			sys_reg(3, 4, 3, 1, 4)
> -#define SYS_HDFGWTR_EL2			sys_reg(3, 4, 3, 1, 5)
> +#define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
>   #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_SPSR_irq			sys_reg(3, 4, 4, 3, 0)
> +#define SYS_SPSR_abt			sys_reg(3, 4, 4, 3, 1)
> +#define SYS_SPSR_und			sys_reg(3, 4, 4, 3, 2)
> +#define SYS_SPSR_fiq			sys_reg(3, 4, 4, 3, 3)
>   #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)
> @@ -401,6 +522,18 @@
>   
>   #define SYS_MAIR_EL2			sys_reg(3, 4, 10, 2, 0)
>   #define SYS_AMAIR_EL2			sys_reg(3, 4, 10, 3, 0)
> +#define SYS_MPAMHCR_EL2			sys_reg(3, 4, 10, 4, 0)
> +#define SYS_MPAMVPMV_EL2		sys_reg(3, 4, 10, 4, 1)
> +#define SYS_MPAM2_EL2			sys_reg(3, 4, 10, 5, 0)
> +#define __SYS__MPAMVPMx_EL2(x)		sys_reg(3, 4, 10, 6, x)
> +#define SYS_MPAMVPM0_EL2		__SYS__MPAMVPMx_EL2(0)
> +#define SYS_MPAMVPM1_EL2		__SYS__MPAMVPMx_EL2(1)
> +#define SYS_MPAMVPM2_EL2		__SYS__MPAMVPMx_EL2(2)
> +#define SYS_MPAMVPM3_EL2		__SYS__MPAMVPMx_EL2(3)
> +#define SYS_MPAMVPM4_EL2		__SYS__MPAMVPMx_EL2(4)
> +#define SYS_MPAMVPM5_EL2		__SYS__MPAMVPMx_EL2(5)
> +#define SYS_MPAMVPM6_EL2		__SYS__MPAMVPMx_EL2(6)
> +#define SYS_MPAMVPM7_EL2		__SYS__MPAMVPMx_EL2(7)
>   
>   #define SYS_VBAR_EL2			sys_reg(3, 4, 12, 0, 0)
>   #define SYS_RVBAR_EL2			sys_reg(3, 4, 12, 0, 1)
> @@ -449,24 +582,49 @@
>   
>   #define SYS_CONTEXTIDR_EL2		sys_reg(3, 4, 13, 0, 1)
>   #define SYS_TPIDR_EL2			sys_reg(3, 4, 13, 0, 2)
> +#define SYS_SCXTNUM_EL2			sys_reg(3, 4, 13, 0, 7)
> +
> +#define __AMEV_op2(m)			(m & 0x7)
> +#define __AMEV_CRm(n, m)		(n | ((m & 0x8) >> 3))
> +#define __SYS__AMEVCNTVOFF0n_EL2(m)	sys_reg(3, 4, 13, __AMEV_CRm(0x8, m), __AMEV_op2(m))
> +#define SYS_AMEVCNTVOFF0n_EL2(m)	__SYS__AMEVCNTVOFF0n_EL2(m)
> +#define __SYS__AMEVCNTVOFF1n_EL2(m)	sys_reg(3, 4, 13, __AMEV_CRm(0xA, m), __AMEV_op2(m))
> +#define SYS_AMEVCNTVOFF1n_EL2(m)	__SYS__AMEVCNTVOFF1n_EL2(m)
>   
>   #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_BRBCR_EL12			sys_reg(2, 5, 9, 0, 0)
>   #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
> +#define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
> +#define SYS_SCTLR2_EL12			sys_reg(3, 5, 1, 0, 3)
> +#define SYS_ZCR_EL12			sys_reg(3, 5, 1, 2, 0)
> +#define SYS_TRFCR_EL12			sys_reg(3, 5, 1, 2, 1)
> +#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)
> +#define SYS_TCR2_EL12			sys_reg(3, 5, 2, 0, 3)
>   #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)
>   #define SYS_TFSR_EL12			sys_reg(3, 5, 5, 6, 0)
> +#define SYS_FAR_EL12			sys_reg(3, 5, 6, 0, 0)
> +#define SYS_PMSCR_EL12			sys_reg(3, 5, 9, 9, 0)
>   #define SYS_MAIR_EL12			sys_reg(3, 5, 10, 2, 0)
>   #define SYS_AMAIR_EL12			sys_reg(3, 5, 10, 3, 0)
>   #define SYS_VBAR_EL12			sys_reg(3, 5, 12, 0, 0)
> +#define SYS_CONTEXTIDR_EL12		sys_reg(3, 5, 13, 0, 1)
> +#define SYS_SCXTNUM_EL12		sys_reg(3, 5, 13, 0, 7)
>   #define SYS_CNTKCTL_EL12		sys_reg(3, 5, 14, 1, 0)
>   #define SYS_CNTP_TVAL_EL02		sys_reg(3, 5, 14, 2, 0)
>   #define SYS_CNTP_CTL_EL02		sys_reg(3, 5, 14, 2, 1)
> @@ -477,6 +635,165 @@
>   
>   #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_S1E1A	sys_insn(AT_Op0, 0, AT_CRn, 9, 2)
> +#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)
> +
> +/* TLBI instructions */
> +#define OP_TLBI_VMALLE1OS		sys_insn(1, 0, 8, 1, 0)
> +#define OP_TLBI_VAE1OS			sys_insn(1, 0, 8, 1, 1)
> +#define OP_TLBI_ASIDE1OS		sys_insn(1, 0, 8, 1, 2)
> +#define OP_TLBI_VAAE1OS			sys_insn(1, 0, 8, 1, 3)
> +#define OP_TLBI_VALE1OS			sys_insn(1, 0, 8, 1, 5)
> +#define OP_TLBI_VAALE1OS		sys_insn(1, 0, 8, 1, 7)
> +#define OP_TLBI_RVAE1IS			sys_insn(1, 0, 8, 2, 1)
> +#define OP_TLBI_RVAAE1IS		sys_insn(1, 0, 8, 2, 3)
> +#define OP_TLBI_RVALE1IS		sys_insn(1, 0, 8, 2, 5)
> +#define OP_TLBI_RVAALE1IS		sys_insn(1, 0, 8, 2, 7)
> +#define OP_TLBI_VMALLE1IS		sys_insn(1, 0, 8, 3, 0)
> +#define OP_TLBI_VAE1IS			sys_insn(1, 0, 8, 3, 1)
> +#define OP_TLBI_ASIDE1IS		sys_insn(1, 0, 8, 3, 2)
> +#define OP_TLBI_VAAE1IS			sys_insn(1, 0, 8, 3, 3)
> +#define OP_TLBI_VALE1IS			sys_insn(1, 0, 8, 3, 5)
> +#define OP_TLBI_VAALE1IS		sys_insn(1, 0, 8, 3, 7)
> +#define OP_TLBI_RVAE1OS			sys_insn(1, 0, 8, 5, 1)
> +#define OP_TLBI_RVAAE1OS		sys_insn(1, 0, 8, 5, 3)
> +#define OP_TLBI_RVALE1OS		sys_insn(1, 0, 8, 5, 5)
> +#define OP_TLBI_RVAALE1OS		sys_insn(1, 0, 8, 5, 7)
> +#define OP_TLBI_RVAE1			sys_insn(1, 0, 8, 6, 1)
> +#define OP_TLBI_RVAAE1			sys_insn(1, 0, 8, 6, 3)
> +#define OP_TLBI_RVALE1			sys_insn(1, 0, 8, 6, 5)
> +#define OP_TLBI_RVAALE1			sys_insn(1, 0, 8, 6, 7)
> +#define OP_TLBI_VMALLE1			sys_insn(1, 0, 8, 7, 0)
> +#define OP_TLBI_VAE1			sys_insn(1, 0, 8, 7, 1)
> +#define OP_TLBI_ASIDE1			sys_insn(1, 0, 8, 7, 2)
> +#define OP_TLBI_VAAE1			sys_insn(1, 0, 8, 7, 3)
> +#define OP_TLBI_VALE1			sys_insn(1, 0, 8, 7, 5)
> +#define OP_TLBI_VAALE1			sys_insn(1, 0, 8, 7, 7)
> +#define OP_TLBI_VMALLE1OSNXS		sys_insn(1, 0, 9, 1, 0)
> +#define OP_TLBI_VAE1OSNXS		sys_insn(1, 0, 9, 1, 1)
> +#define OP_TLBI_ASIDE1OSNXS		sys_insn(1, 0, 9, 1, 2)
> +#define OP_TLBI_VAAE1OSNXS		sys_insn(1, 0, 9, 1, 3)
> +#define OP_TLBI_VALE1OSNXS		sys_insn(1, 0, 9, 1, 5)
> +#define OP_TLBI_VAALE1OSNXS		sys_insn(1, 0, 9, 1, 7)
> +#define OP_TLBI_RVAE1ISNXS		sys_insn(1, 0, 9, 2, 1)
> +#define OP_TLBI_RVAAE1ISNXS		sys_insn(1, 0, 9, 2, 3)
> +#define OP_TLBI_RVALE1ISNXS		sys_insn(1, 0, 9, 2, 5)
> +#define OP_TLBI_RVAALE1ISNXS		sys_insn(1, 0, 9, 2, 7)
> +#define OP_TLBI_VMALLE1ISNXS		sys_insn(1, 0, 9, 3, 0)
> +#define OP_TLBI_VAE1ISNXS		sys_insn(1, 0, 9, 3, 1)
> +#define OP_TLBI_ASIDE1ISNXS		sys_insn(1, 0, 9, 3, 2)
> +#define OP_TLBI_VAAE1ISNXS		sys_insn(1, 0, 9, 3, 3)
> +#define OP_TLBI_VALE1ISNXS		sys_insn(1, 0, 9, 3, 5)
> +#define OP_TLBI_VAALE1ISNXS		sys_insn(1, 0, 9, 3, 7)
> +#define OP_TLBI_RVAE1OSNXS		sys_insn(1, 0, 9, 5, 1)
> +#define OP_TLBI_RVAAE1OSNXS		sys_insn(1, 0, 9, 5, 3)
> +#define OP_TLBI_RVALE1OSNXS		sys_insn(1, 0, 9, 5, 5)
> +#define OP_TLBI_RVAALE1OSNXS		sys_insn(1, 0, 9, 5, 7)
> +#define OP_TLBI_RVAE1NXS		sys_insn(1, 0, 9, 6, 1)
> +#define OP_TLBI_RVAAE1NXS		sys_insn(1, 0, 9, 6, 3)
> +#define OP_TLBI_RVALE1NXS		sys_insn(1, 0, 9, 6, 5)
> +#define OP_TLBI_RVAALE1NXS		sys_insn(1, 0, 9, 6, 7)
> +#define OP_TLBI_VMALLE1NXS		sys_insn(1, 0, 9, 7, 0)
> +#define OP_TLBI_VAE1NXS			sys_insn(1, 0, 9, 7, 1)
> +#define OP_TLBI_ASIDE1NXS		sys_insn(1, 0, 9, 7, 2)
> +#define OP_TLBI_VAAE1NXS		sys_insn(1, 0, 9, 7, 3)
> +#define OP_TLBI_VALE1NXS		sys_insn(1, 0, 9, 7, 5)
> +#define OP_TLBI_VAALE1NXS		sys_insn(1, 0, 9, 7, 7)
> +#define OP_TLBI_IPAS2E1IS		sys_insn(1, 4, 8, 0, 1)
> +#define OP_TLBI_RIPAS2E1IS		sys_insn(1, 4, 8, 0, 2)
> +#define OP_TLBI_IPAS2LE1IS		sys_insn(1, 4, 8, 0, 5)
> +#define OP_TLBI_RIPAS2LE1IS		sys_insn(1, 4, 8, 0, 6)
> +#define OP_TLBI_ALLE2OS			sys_insn(1, 4, 8, 1, 0)
> +#define OP_TLBI_VAE2OS			sys_insn(1, 4, 8, 1, 1)
> +#define OP_TLBI_ALLE1OS			sys_insn(1, 4, 8, 1, 4)
> +#define OP_TLBI_VALE2OS			sys_insn(1, 4, 8, 1, 5)
> +#define OP_TLBI_VMALLS12E1OS		sys_insn(1, 4, 8, 1, 6)
> +#define OP_TLBI_RVAE2IS			sys_insn(1, 4, 8, 2, 1)
> +#define OP_TLBI_RVALE2IS		sys_insn(1, 4, 8, 2, 5)
> +#define OP_TLBI_ALLE2IS			sys_insn(1, 4, 8, 3, 0)
> +#define OP_TLBI_VAE2IS			sys_insn(1, 4, 8, 3, 1)
> +#define OP_TLBI_ALLE1IS			sys_insn(1, 4, 8, 3, 4)
> +#define OP_TLBI_VALE2IS			sys_insn(1, 4, 8, 3, 5)
> +#define OP_TLBI_VMALLS12E1IS		sys_insn(1, 4, 8, 3, 6)
> +#define OP_TLBI_IPAS2E1OS		sys_insn(1, 4, 8, 4, 0)
> +#define OP_TLBI_IPAS2E1			sys_insn(1, 4, 8, 4, 1)
> +#define OP_TLBI_RIPAS2E1		sys_insn(1, 4, 8, 4, 2)
> +#define OP_TLBI_RIPAS2E1OS		sys_insn(1, 4, 8, 4, 3)
> +#define OP_TLBI_IPAS2LE1OS		sys_insn(1, 4, 8, 4, 4)
> +#define OP_TLBI_IPAS2LE1		sys_insn(1, 4, 8, 4, 5)
> +#define OP_TLBI_RIPAS2LE1		sys_insn(1, 4, 8, 4, 6)
> +#define OP_TLBI_RIPAS2LE1OS		sys_insn(1, 4, 8, 4, 7)
> +#define OP_TLBI_RVAE2OS			sys_insn(1, 4, 8, 5, 1)
> +#define OP_TLBI_RVALE2OS		sys_insn(1, 4, 8, 5, 5)
> +#define OP_TLBI_RVAE2			sys_insn(1, 4, 8, 6, 1)
> +#define OP_TLBI_RVALE2			sys_insn(1, 4, 8, 6, 5)
> +#define OP_TLBI_ALLE2			sys_insn(1, 4, 8, 7, 0)
> +#define OP_TLBI_VAE2			sys_insn(1, 4, 8, 7, 1)
> +#define OP_TLBI_ALLE1			sys_insn(1, 4, 8, 7, 4)
> +#define OP_TLBI_VALE2			sys_insn(1, 4, 8, 7, 5)
> +#define OP_TLBI_VMALLS12E1		sys_insn(1, 4, 8, 7, 6)
> +#define OP_TLBI_IPAS2E1ISNXS		sys_insn(1, 4, 9, 0, 1)
> +#define OP_TLBI_RIPAS2E1ISNXS		sys_insn(1, 4, 9, 0, 2)
> +#define OP_TLBI_IPAS2LE1ISNXS		sys_insn(1, 4, 9, 0, 5)
> +#define OP_TLBI_RIPAS2LE1ISNXS		sys_insn(1, 4, 9, 0, 6)
> +#define OP_TLBI_ALLE2OSNXS		sys_insn(1, 4, 9, 1, 0)
> +#define OP_TLBI_VAE2OSNXS		sys_insn(1, 4, 9, 1, 1)
> +#define OP_TLBI_ALLE1OSNXS		sys_insn(1, 4, 9, 1, 4)
> +#define OP_TLBI_VALE2OSNXS		sys_insn(1, 4, 9, 1, 5)
> +#define OP_TLBI_VMALLS12E1OSNXS		sys_insn(1, 4, 9, 1, 6)
> +#define OP_TLBI_RVAE2ISNXS		sys_insn(1, 4, 9, 2, 1)
> +#define OP_TLBI_RVALE2ISNXS		sys_insn(1, 4, 9, 2, 5)
> +#define OP_TLBI_ALLE2ISNXS		sys_insn(1, 4, 9, 3, 0)
> +#define OP_TLBI_VAE2ISNXS		sys_insn(1, 4, 9, 3, 1)
> +#define OP_TLBI_ALLE1ISNXS		sys_insn(1, 4, 9, 3, 4)
> +#define OP_TLBI_VALE2ISNXS		sys_insn(1, 4, 9, 3, 5)
> +#define OP_TLBI_VMALLS12E1ISNXS		sys_insn(1, 4, 9, 3, 6)
> +#define OP_TLBI_IPAS2E1OSNXS		sys_insn(1, 4, 9, 4, 0)
> +#define OP_TLBI_IPAS2E1NXS		sys_insn(1, 4, 9, 4, 1)
> +#define OP_TLBI_RIPAS2E1NXS		sys_insn(1, 4, 9, 4, 2)
> +#define OP_TLBI_RIPAS2E1OSNXS		sys_insn(1, 4, 9, 4, 3)
> +#define OP_TLBI_IPAS2LE1OSNXS		sys_insn(1, 4, 9, 4, 4)
> +#define OP_TLBI_IPAS2LE1NXS		sys_insn(1, 4, 9, 4, 5)
> +#define OP_TLBI_RIPAS2LE1NXS		sys_insn(1, 4, 9, 4, 6)
> +#define OP_TLBI_RIPAS2LE1OSNXS		sys_insn(1, 4, 9, 4, 7)
> +#define OP_TLBI_RVAE2OSNXS		sys_insn(1, 4, 9, 5, 1)
> +#define OP_TLBI_RVALE2OSNXS		sys_insn(1, 4, 9, 5, 5)
> +#define OP_TLBI_RVAE2NXS		sys_insn(1, 4, 9, 6, 1)
> +#define OP_TLBI_RVALE2NXS		sys_insn(1, 4, 9, 6, 5)
> +#define OP_TLBI_ALLE2NXS		sys_insn(1, 4, 9, 7, 0)
> +#define OP_TLBI_VAE2NXS			sys_insn(1, 4, 9, 7, 1)
> +#define OP_TLBI_ALLE1NXS		sys_insn(1, 4, 9, 7, 4)
> +#define OP_TLBI_VALE2NXS		sys_insn(1, 4, 9, 7, 5)
> +#define OP_TLBI_VMALLS12E1NXS		sys_insn(1, 4, 9, 7, 6)
> +
> +/* Misc instructions */
> +#define OP_GCSPUSHX			sys_insn(1, 0, 7, 7, 4)
> +#define OP_GCSPOPCX			sys_insn(1, 0, 7, 7, 5)
> +#define OP_GCSPOPX			sys_insn(1, 0, 7, 7, 6)
> +#define OP_GCSPUSHM			sys_insn(1, 3, 7, 7, 0)
> +
> +#define OP_BRB_IALL			sys_insn(1, 1, 7, 2, 4)
> +#define OP_BRB_INJ			sys_insn(1, 1, 7, 2, 5)
> +#define OP_CFP_RCTX			sys_insn(1, 3, 7, 3, 4)
> +#define OP_DVP_RCTX			sys_insn(1, 3, 7, 3, 5)
> +#define OP_COSP_RCTX			sys_insn(1, 3, 7, 3, 6)
> +#define OP_CPP_RCTX			sys_insn(1, 3, 7, 3, 7)
> +
>   /* Common SCTLR_ELx flags. */
>   #define SCTLR_ELx_ENTP2	(BIT(60))
>   #define SCTLR_ELx_DSSBS	(BIT(44))
> @@ -561,10 +878,12 @@
>   
>   /* id_aa64mmfr0 */
>   #define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN	0x0
> +#define ID_AA64MMFR0_EL1_TGRAN4_LPA2		ID_AA64MMFR0_EL1_TGRAN4_52_BIT
>   #define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MAX	0x7
>   #define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED_MIN	0x0
>   #define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED_MAX	0x7
>   #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MIN	0x1
> +#define ID_AA64MMFR0_EL1_TGRAN16_LPA2		ID_AA64MMFR0_EL1_TGRAN16_52_BIT
>   #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MAX	0xf
>   
>   #define ARM64_MIN_PARANGE_BITS		32
> @@ -572,6 +891,7 @@
>   #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_DEFAULT	0x0
>   #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_NONE		0x1
>   #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MIN		0x2
> +#define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2		0x3
>   #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX		0x7
>   
>   #ifdef CONFIG_ARM64_PA_BITS_52
> @@ -582,11 +902,13 @@
>   
>   #if defined(CONFIG_ARM64_4K_PAGES)
>   #define ID_AA64MMFR0_EL1_TGRAN_SHIFT		ID_AA64MMFR0_EL1_TGRAN4_SHIFT
> +#define ID_AA64MMFR0_EL1_TGRAN_LPA2		ID_AA64MMFR0_EL1_TGRAN4_52_BIT
>   #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN
>   #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX	ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MAX
>   #define ID_AA64MMFR0_EL1_TGRAN_2_SHIFT		ID_AA64MMFR0_EL1_TGRAN4_2_SHIFT
>   #elif defined(CONFIG_ARM64_16K_PAGES)
>   #define ID_AA64MMFR0_EL1_TGRAN_SHIFT		ID_AA64MMFR0_EL1_TGRAN16_SHIFT
> +#define ID_AA64MMFR0_EL1_TGRAN_LPA2		ID_AA64MMFR0_EL1_TGRAN16_52_BIT
>   #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MIN
>   #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX	ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MAX
>   #define ID_AA64MMFR0_EL1_TGRAN_2_SHIFT		ID_AA64MMFR0_EL1_TGRAN16_2_SHIFT
> @@ -610,6 +932,19 @@
>   #define SYS_GCR_EL1_RRND	(BIT(16))
>   #define SYS_GCR_EL1_EXCL_MASK	0xffffUL
>   
> +#ifdef CONFIG_KASAN_HW_TAGS
> +/*
> + * KASAN always uses a whole byte for its tags. With CONFIG_KASAN_HW_TAGS it
> + * only uses tags in the range 0xF0-0xFF, which we map to MTE tags 0x0-0xF.
> + */
> +#define __MTE_TAG_MIN		(KASAN_TAG_MIN & 0xf)
> +#define __MTE_TAG_MAX		(KASAN_TAG_MAX & 0xf)
> +#define __MTE_TAG_INCL		GENMASK(__MTE_TAG_MAX, __MTE_TAG_MIN)
> +#define KERNEL_GCR_EL1_EXCL	(SYS_GCR_EL1_EXCL_MASK & ~__MTE_TAG_INCL)
> +#else
> +#define KERNEL_GCR_EL1_EXCL	SYS_GCR_EL1_EXCL_MASK
> +#endif
> +
>   #define KERNEL_GCR_EL1		(SYS_GCR_EL1_RRND | KERNEL_GCR_EL1_EXCL)
>   
>   /* RGSR_EL1 Definitions */
> @@ -716,6 +1051,19 @@
>   
>   #define PIRx_ELx_PERM(idx, perm)	((perm) << ((idx) * 4))
>   
> +/*
> + * Permission Overlay Extension (POE) permission encodings.
> + */
> +#define POE_NONE	UL(0x0)
> +#define POE_R		UL(0x1)
> +#define POE_X		UL(0x2)
> +#define POE_RX		UL(0x3)
> +#define POE_W		UL(0x4)
> +#define POE_RW		UL(0x5)
> +#define POE_XW		UL(0x6)
> +#define POE_RXW		UL(0x7)
> +#define POE_MASK	UL(0xf)
> +
>   #define ARM64_FEATURE_FIELD_BITS	4
>   
>   /* Defined for compatibility only, do not add new users. */
> @@ -789,15 +1137,21 @@
>   /*
>    * For registers without architectural names, or simply unsupported by
>    * GAS.
> + *
> + * __check_r forces warnings to be generated by the compiler when
> + * evaluating r which wouldn't normally happen due to being passed to
> + * the assembler via __stringify(r).
>    */
>   #define read_sysreg_s(r) ({						\
>   	u64 __val;							\
> +	u32 __maybe_unused __check_r = (u32)(r);			\
>   	asm volatile(__mrs_s("%0", r) : "=r" (__val));			\
>   	__val;								\
>   })
>   
>   #define write_sysreg_s(v, r) do {					\
>   	u64 __val = (u64)(v);						\
> +	u32 __maybe_unused __check_r = (u32)(r);			\
>   	asm volatile(__msr_s(r, "%x0") : : "rZ" (__val));		\
>   } while (0)
>   
> @@ -827,6 +1181,8 @@
>   	par;								\
>   })
>   
> +#define SYS_FIELD_VALUE(reg, field, val)	reg##_##field##_##val
> +
>   #define SYS_FIELD_GET(reg, field, val)		\
>   		 FIELD_GET(reg##_##field##_MASK, val)
>   
> @@ -834,7 +1190,8 @@
>   		 FIELD_PREP(reg##_##field##_MASK, val)
>   
>   #define SYS_FIELD_PREP_ENUM(reg, field, val)		\
> -		 FIELD_PREP(reg##_##field##_MASK, reg##_##field##_##val)
> +		 FIELD_PREP(reg##_##field##_MASK,	\
> +			    SYS_FIELD_VALUE(reg, field, val))
>   
>   #endif
>   
> diff --git a/tools/include/linux/kasan-tags.h b/tools/include/linux/kasan-tags.h
> new file mode 100644
> index 000000000000..4f85f562512c
> --- /dev/null
> +++ b/tools/include/linux/kasan-tags.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _LINUX_KASAN_TAGS_H
> +#define _LINUX_KASAN_TAGS_H
> +
> +#define KASAN_TAG_KERNEL	0xFF /* native kernel pointers tag */
> +#define KASAN_TAG_INVALID	0xFE /* inaccessible memory tag */
> +#define KASAN_TAG_MAX		0xFD /* maximum value for random tags */
> +
> +#ifdef CONFIG_KASAN_HW_TAGS
> +#define KASAN_TAG_MIN		0xF0 /* minimum value for random tags */
> +#else
> +#define KASAN_TAG_MIN		0x00 /* minimum value for random tags */
> +#endif
> +
> +#endif /* LINUX_KASAN_TAGS_H */



From theo.lebrun at bootlin.com  Mon Feb 26 02:33:06 2024
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Mon, 26 Feb 2024 11:33:06 +0100
Subject: [PATCH v3 1/8] dt-bindings: usb: ti,j721e-usb: drop useless
 compatible list
In-Reply-To: <20240223-clarity-variably-206b01b7276a@spud>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
 <20240223-j7200-usb-suspend-v3-1-b41c9893a130@bootlin.com>
 <20240223-clarity-variably-206b01b7276a@spud>
Message-ID: <CZEXXXQDZZWB.1M5CTZAFVO4YP@bootlin.com>

Hello Conor,

On Fri Feb 23, 2024 at 7:12 PM CET, Conor Dooley wrote:
> On Fri, Feb 23, 2024 at 05:05:25PM +0100, Th?o Lebrun wrote:
> > Compatible can be A or B, not A or B or A+B. Remove last option.
> > A=ti,j721e-usb and B=ti,am64-usb.
> > 
> > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> > ---
> >  Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml | 9 +++------
> >  1 file changed, 3 insertions(+), 6 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> > index 95ff9791baea..949f45eb45c2 100644
> > --- a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> > +++ b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> > @@ -11,12 +11,9 @@ maintainers:
> >  
> >  properties:
> >    compatible:
> > -    oneOf:
> > -      - const: ti,j721e-usb
> > -      - const: ti,am64-usb
> > -      - items:
> > -          - const: ti,j721e-usb
> > -          - const: ti,am64-usb
>
> Correct, this makes no sense. The devices seem to be compatible though,
> so I would expect this to actually be:
> oneOf:
>   - const: ti,j721e-usb
>   - items:
>       - const: ti,am64-usb
>       - const: ti,j721e-usb

I need your help to grasp what that change is supposed to express? Would
you mind turning it into english sentences?

A=ti,j721e-usb and B=ti,am64-usb. My understanding of your proposal is
that a device can either be compat with A or B. But B is compatible
with A so you express it as a list of items. If B is compat with A then
A is compat with B. Does the order of items matter?

I've not applied your proposal to check for dtbs_check but I'd guess it
would throw warnings for the single existing upstream DTSI (as of
v6.8-rc6) that uses "ti,am64-usb"? See:
arch/arm64/boot/dts/ti/k3-am64-main.dtsi.

Thanks Conor!

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From tony at atomide.com  Mon Feb 26 02:36:12 2024
From: tony at atomide.com (Tony Lindgren)
Date: Mon, 26 Feb 2024 12:36:12 +0200
Subject: [GIT PULL] Add PowerVR Series5 SGX GPUs for the TI SoCs
Message-ID: <pull-1708943489-872615@atomide.com>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/sgx-for-v6.9-signed

for you to fetch changes up to 21cfb2ba471bde8fefc327f4c8e2af9499f5173d:

  arm64: dts: ti: k3-am654-main: Add device tree entry for SGX GPU (2024-01-26 09:43:23 +0200)

----------------------------------------------------------------
Add PowerVR Series5 SGX GPUs for the TI SoCs

With the Imagination Rogue GPU binding added, let's also add the devicetree
binding for earlier SGX GPUs. Let's also patch the TI SoCs for the related
SGX GPU nodes.

Based on the mailing list discussions, the conclusion was that we need two
separate device tree bindings, one for Rogue and upcoming GPUS, and one for
the older SGX GPUs.

For merging the changes, I applied the binding changes together with the
TI SoC related changes into a branch leaving out the sun6i and mips changes
as suggested by Rob.

These changes are mostly 32-bit SoCs, but also contains one arm64 change.
It does not cause any merge conflicts.

----------------------------------------------------------------
Andrew Davis (9):
      dt-bindings: gpu: Rename img,powervr to img,powervr-rogue
      dt-bindings: gpu: Add PowerVR Series5 SGX GPUs
      ARM: dts: omap3: Add device tree entry for SGX GPU
      ARM: dts: omap4: Add device tree entry for SGX GPU
      ARM: dts: omap5: Add device tree entry for SGX GPU
      ARM: dts: AM33xx: Add device tree entry for SGX GPU
      ARM: dts: AM437x: Add device tree entry for SGX GPU
      ARM: dts: DRA7xx: Add device tree entry for SGX GPU
      arm64: dts: ti: k3-am654-main: Add device tree entry for SGX GPU

 .../{img,powervr.yaml => img,powervr-rogue.yaml}   |   4 +-
 .../devicetree/bindings/gpu/img,powervr-sgx.yaml   | 138 +++++++++++++++++++++
 MAINTAINERS                                        |   3 +-
 arch/arm/boot/dts/ti/omap/am33xx.dtsi              |   9 +-
 arch/arm/boot/dts/ti/omap/am3517.dtsi              |  11 +-
 arch/arm/boot/dts/ti/omap/am4372.dtsi              |   6 +
 arch/arm/boot/dts/ti/omap/dra7.dtsi                |   9 +-
 arch/arm/boot/dts/ti/omap/omap34xx.dtsi            |  11 +-
 arch/arm/boot/dts/ti/omap/omap36xx.dtsi            |   9 +-
 arch/arm/boot/dts/ti/omap/omap4.dtsi               |   9 +-
 arch/arm/boot/dts/ti/omap/omap5.dtsi               |   9 +-
 arch/arm64/boot/dts/ti/k3-am65-main.dtsi           |   7 ++
 12 files changed, 195 insertions(+), 30 deletions(-)
 rename Documentation/devicetree/bindings/gpu/{img,powervr.yaml => img,powervr-rogue.yaml} (91%)
 create mode 100644 Documentation/devicetree/bindings/gpu/img,powervr-sgx.yaml


From tony at atomide.com  Mon Feb 26 02:42:44 2024
From: tony at atomide.com (Tony Lindgren)
Date: Mon, 26 Feb 2024 12:42:44 +0200
Subject: [GIT PULL] Kerneldoc fixes for omaps for v6.9
Message-ID: <pull-1708944095-4485@atomide.com>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v6.9/soc-signed

for you to fetch changes up to c6e33edb02292059a06ce8fdc4249a5db86a6114:

  ARM: OMAP2+: fix kernel-doc warnings (2024-01-26 10:28:07 +0200)

----------------------------------------------------------------
Kerneldoc warning fixes for omaps for v6.9

A series of kerneldoc warning fixes for omaps from Randy.

----------------------------------------------------------------
Randy Dunlap (13):
      ARM: OMAP2+: am33xx-restart: fix function name in kernel-doc
      ARM: OMAP2+: clockdomain: fix kernel-doc warnings
      ARM: OMAP2+: clock: fix a function name in kernel-doc
      ARM: OMAP2+: cm33xx: use matching function name in kernel-doc
      ARM: OMAP2+: CMINST: use matching function name in kernel-doc
      ARM: OMAP2+: hwmod: remove misuse of kernel-doc
      ARM: OMAP2+: hwmod: fix kernel-doc warnings
      ARM: OMAP2+: pmic-cpcap: fix kernel-doc warnings
      ARM: OMAP2+: prm44xx: fix a kernel-doc warning
      ARM: OMAP2+: PRM: fix kernel-doc warnings
      ARM: OMAP2+: fix a kernel-doc warning
      ARM: OMAP2+: fix kernel-doc warnings
      ARM: OMAP2+: fix kernel-doc warnings

 arch/arm/mach-omap2/am33xx-restart.c         |  2 +-
 arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c |  2 +-
 arch/arm/mach-omap2/clockdomain.c            |  4 ++--
 arch/arm/mach-omap2/cm33xx.c                 |  2 +-
 arch/arm/mach-omap2/cminst44xx.c             |  2 +-
 arch/arm/mach-omap2/omap-secure.c            |  4 ++--
 arch/arm/mach-omap2/omap_hwmod.c             |  9 +++++----
 arch/arm/mach-omap2/omap_hwmod_common_data.c |  6 +++---
 arch/arm/mach-omap2/pmic-cpcap.c             | 24 ++++++++++++------------
 arch/arm/mach-omap2/powerdomain.c            |  2 +-
 arch/arm/mach-omap2/prm44xx.c                |  2 +-
 arch/arm/mach-omap2/prm_common.c             |  4 +++-
 arch/arm/mach-omap2/wd_timer.c               |  4 +++-
 13 files changed, 36 insertions(+), 31 deletions(-)


From miquel.raynal at bootlin.com  Mon Feb 26 02:43:26 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:43:26 +0100
Subject: [PATCH] mtd: lpc32xx: use typedef for dma_filter_fn
In-Reply-To: <20240208202113.630190-1-krzysztof.kozlowski@linaro.org>
Message-ID: <20240226104326.489058-1-miquel.raynal@bootlin.com>

On Thu, 2024-02-08 at 20:21:13 UTC, Krzysztof Kozlowski wrote:
> Use existing typedef for dma_filter_fn to avoid duplicating type
> definition.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Acked-by: Vladimir Zapolskiy <vz at mleia.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/next, thanks.

Miquel


From mcanal at igalia.com  Mon Feb 26 02:42:31 2024
From: mcanal at igalia.com (=?UTF-8?Q?Ma=C3=ADra_Canal?=)
Date: Mon, 26 Feb 2024 07:42:31 -0300
Subject: [PATCH v7 01/36] drm/tests: helpers: Include missing drm_drv
 header
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-1-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-1-8f4af575fce2@kernel.org>
Message-ID: <fc45b4c9-40e8-4335-b669-9307cc7325ad@igalia.com>

On 2/22/24 15:13, Maxime Ripard wrote:
> We have a few functions declared in our kunit helpers header, some of
> them dereferencing the struct drm_driver.
> 
> However, we don't include the drm_drv.h header file defining that
> structure, leading to compilation errors if we don't include both
> headers.
> 
> Fixes: d98780310719 ("drm/tests: helpers: Allow to pass a custom drm_driver")
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Ma?ra Canal <mcanal at igalia.com>

Best Regards,
- Ma?ra

> ---
>   include/drm/drm_kunit_helpers.h | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
> index ba483c87f0e7..3ae19892229d 100644
> --- a/include/drm/drm_kunit_helpers.h
> +++ b/include/drm/drm_kunit_helpers.h
> @@ -3,6 +3,8 @@
>   #ifndef DRM_KUNIT_HELPERS_H_
>   #define DRM_KUNIT_HELPERS_H_
>   
> +#include <drm/drm_drv.h>
> +
>   #include <linux/device.h>
>   
>   #include <kunit/test.h>
> 


From miquel.raynal at bootlin.com  Mon Feb 26 02:43:44 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:43:44 +0100
Subject: [PATCH v4 08/39] dt-bindings: atmel-nand: add microchip,sam9x7-pmecc
In-Reply-To: <20240223172520.671940-1-varshini.rajendran@microchip.com>
Message-ID: <20240226104344.489249-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 17:25:20 UTC, Varshini Rajendran wrote:
> Add microchip,sam9x7-pmecc to DT bindings documentation.
> 
> Signed-off-by: Varshini Rajendran <varshini.rajendran at microchip.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:43:48 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:43:48 +0100
Subject: [PATCH v6 13/13] mtd: rawnand: brcmnand: Support write protection setting from dts
In-Reply-To: <20240223034758.13753-14-william.zhang@broadcom.com>
Message-ID: <20240226104348.489295-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:58 UTC, William Zhang wrote:
> The write protection feature is controlled by the module parameter wp_on
> with default set to enabled. But not all the board use this feature
> especially in BCMBCA broadband board. And module parameter is not
> sufficient as different board can have different option.  Add a device
> tree property and allow this feature to be configured through the board
> dts on per board basis.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
> Reviewed-by: Kamal Dasu <kamal.dasu at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:43:54 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:43:54 +0100
Subject: [PATCH v6 11/13] mtd: rawnand: brcmnand: Add BCMBCA read data bus interface
In-Reply-To: <20240223034758.13753-12-william.zhang@broadcom.com>
Message-ID: <20240226104354.489350-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:56 UTC, William Zhang wrote:
> The BCMBCA broadband SoC integrates the NAND controller differently than
> STB, iProc and other SoCs.  It has different endianness for NAND cache
> data.
> 
> Add a SoC read data bus shim for BCMBCA to meet the specific SoC need
> and performance improvement using the optimized memcpy function on NAND
> cache memory.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:08 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:08 +0100
Subject: [PATCH v6 08/13] arm64: dts: broadcom: bcmbca: Add NAND controller node
In-Reply-To: <20240223034758.13753-9-william.zhang@broadcom.com>
Message-ID: <20240226104408.489472-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:53 UTC, William Zhang wrote:
> Add support for Broadcom STB NAND controller in BCMBCA ARMv8 chip dts
> files.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:43:59 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:43:59 +0100
Subject: [PATCH v6 10/13] mtd: rawnand: brcmnand: Rename bcm63138 nand driver
In-Reply-To: <20240223034758.13753-11-william.zhang@broadcom.com>
Message-ID: <20240226104359.489391-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:55 UTC, William Zhang wrote:
> In preparing to support multiple BCMBCA SoCs, rename bcm63138 to bcmbca
> in the driver code and driver file name.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>
> Acked-by: Florian Fainelli <florian.fainelli at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:11 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:11 +0100
Subject: [PATCH v6 07/13] ARM: dts: broadcom: bcmbca: Add NAND controller node
In-Reply-To: <20240223034758.13753-8-william.zhang@broadcom.com>
Message-ID: <20240226104411.489517-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:52 UTC, William Zhang wrote:
> Add support for Broadcom STB NAND controller in BCMBCA ARMv7 chip dts
> files.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:03 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:03 +0100
Subject: [PATCH v6 09/13] arm64: dts: broadcom: bcmbca: Update router boards
In-Reply-To: <20240223034758.13753-10-william.zhang@broadcom.com>
Message-ID: <20240226104403.489429-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:54 UTC, William Zhang wrote:
> Enable the nand controller and add WP pin connection property in actual
> board dts as they are board level properties now that they are disabled
> and moved out from SoC dtsi.
> 
> Also remove the unnecessary brcm,nand-has-wp property from AC5300 board.
> This property is only needed for some old controller that this board
> does not apply.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:18 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:18 +0100
Subject: [PATCH v6 06/13] dt-bindings: mtd: brcmnand: Add ecc strap property
In-Reply-To: <20240223034758.13753-7-william.zhang@broadcom.com>
Message-ID: <20240226104418.489578-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:51 UTC, William Zhang wrote:
> Add brcm,nand-ecc-use-strap to get ecc and spare area size settings from
> board boot strap for broadband board designs because they do not specify
> ecc setting in dts but rather using the strap setting.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:22 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:22 +0100
Subject: [PATCH v6 05/13] dt-bindings: mtd: brcmnand: Add WP pin connection property
In-Reply-To: <20240223034758.13753-6-william.zhang@broadcom.com>
Message-ID: <20240226104422.489635-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:50 UTC, William Zhang wrote:
> Add brcm,wp-not-connected property to have an option for disabling this
> feature on broadband board design that does not connect WP pin.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:26 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:26 +0100
Subject: [PATCH v6 04/13] dt-bindings: mtd: brcmnand: Updates for bcmbca SoCs
In-Reply-To: <20240223034758.13753-5-william.zhang@broadcom.com>
Message-ID: <20240226104426.489713-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:49 UTC, William Zhang wrote:
> Update the descriptions to reflect different families of broadband SoC and
> use the general name bcmbca for ARM based SoC.
> 
> Remove the requirement of interrupts property to reflect the driver
> code and only require interrupt-names when interrupts property present.
> 
> Also add myself to the list of maintainers.
> 
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: David Regan <dregan at broadcom.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:30 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:30 +0100
Subject: [PATCH v6 03/13] mtd: rawnand: brcmnand: update log level messages
In-Reply-To: <20240223034758.13753-4-william.zhang@broadcom.com>
Message-ID: <20240226104430.489749-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:48 UTC, William Zhang wrote:
> From: David Regan <dregan at broadcom.com>
> 
> Update log level messages so that more critical messages can be logged
> to console and help the troubleshooting with field devices.
> 
> Signed-off-by: David Regan <dregan at broadcom.com>
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: William Zhang <william.zhang at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:34 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:34 +0100
Subject: [PATCH v6 02/13] mtd: rawnand: brcmnand: fix style issues
In-Reply-To: <20240223034758.13753-3-william.zhang@broadcom.com>
Message-ID: <20240226104434.489790-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:47 UTC, William Zhang wrote:
> Fix various style issues.
> 
> Signed-off-by: David Regan <dregan at broadcom.com>
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: William Zhang <william.zhang at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:37 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:37 +0100
Subject: [PATCH v6 01/13] mtd: rawnand: brcmnand: exec_op helper functions return type fixes
In-Reply-To: <20240223034758.13753-2-william.zhang@broadcom.com>
Message-ID: <20240226104437.489832-1-miquel.raynal@bootlin.com>

On Fri, 2024-02-23 at 03:47:46 UTC, William Zhang wrote:
> From: David Regan <dregan at broadcom.com>
> 
> Fix return types for exec_op reset and status helper functions.
> 
> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> Closes: http://lists.infradead.org/pipermail/linux-mtd/2023-December/102423.html
> Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation")
> Signed-off-by: David Regan <dregan at broadcom.com>
> Signed-off-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: William Zhang <william.zhang at broadcom.com>
> Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:45:00 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:45:00 +0100
Subject: [PATCH v1] mtd: rawnand: meson: fix scrambling mode value in command macro
In-Reply-To: <20240210214551.441610-1-avkrasnov@salutedevices.com>
Message-ID: <20240226104500.490108-1-miquel.raynal@bootlin.com>

On Sat, 2024-02-10 at 21:45:51 UTC, Arseniy Krasnov wrote:
> Scrambling mode is enabled by value (1 << 19). NFC_CMD_SCRAMBLER_ENABLE
> is already (1 << 19), so there is no need to shift it again in CMDRWGEN
> macro.
> 
> Signed-off-by: Arseniy Krasnov <avkrasnov at salutedevices.com>
> Cc: <Stable at vger.kernel.org>
> Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:52 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:52 +0100
Subject: [PATCH] mtd: rawnand: lpc32xx_mlc: fix irq handler prototype
In-Reply-To: <20240213100146.455811-1-arnd@kernel.org>
Message-ID: <20240226104452.490015-1-miquel.raynal@bootlin.com>

On Tue, 2024-02-13 at 10:00:09 UTC, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> clang-16 warns about mismatched function prototypes:
> 
> drivers/mtd/nand/raw/lpc32xx_mlc.c:783:29: error: cast from 'irqreturn_t (*)(int, struct lpc32xx_nand_host *)' (aka 'enum irqreturn (*)(int, struct lpc32xx_nand_host *)') to 'irq_handler_t' (aka 'enum irqreturn (*)(int, void *)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
> 
> Change the interrupt handler to the normal way of just passing
> a void* pointer and converting it inside the function..
> 
> Fixes: 70f7cb78ec53 ("mtd: add LPC32xx MLC NAND driver")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From miquel.raynal at bootlin.com  Mon Feb 26 02:44:56 2024
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 26 Feb 2024 11:44:56 +0100
Subject: [PATCH v2] mtd: rawnand: Prefer struct_size over open coded arithmetic
In-Reply-To: <20240211091633.4545-1-erick.archer@gmx.com>
Message-ID: <20240226104456.490065-1-miquel.raynal@bootlin.com>

On Sun, 2024-02-11 at 09:16:33 UTC, Erick Archer wrote:
> This is an effort to get rid of all multiplications from allocation
> functions in order to prevent integer overflows [1].
> 
> As the "chip" variable is a pointer to "struct mtk_nfc_nand_chip" and
> this structure ends in a flexible array:
> 
> struct mtk_nfc_nand_chip {
> 	[...]
> 	u8 sels[] __counted_by(nsels);
> };
> 
> the preferred way in the kernel is to use the struct_size() helper to
> do the arithmetic instead of the argument "size + count * size" in the
> devm_kzalloc() function.
> 
> This way, the code is more readable and safer.
> 
> Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1]
> Link: https://github.com/KSPP/linux/issues/160 [2]
> Reviewed-by: Gustavo A. R. Silva <gustavoars at kernel.org>
> Signed-off-by: Erick Archer <erick.archer at gmx.com>
> Acked-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From raphael.gallais-pou at foss.st.com  Mon Feb 26 02:48:05 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Mon, 26 Feb 2024 11:48:05 +0100
Subject: [PATCH v6 1/3] dt-bindings: display: add STM32 LVDS device
In-Reply-To: <20240226-lvds-v6-0-15e3463fbe70@foss.st.com>
References: <20240226-lvds-v6-0-15e3463fbe70@foss.st.com>
Message-ID: <20240226-lvds-v6-1-15e3463fbe70@foss.st.com>

Add "st,stm32mp25-lvds" compatible.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
Depends on: "dt-bindings: stm32: add clocks and reset binding for
	    stm32mp25 platform" by Gabriel Fernandez

Changes in v6:
	- Added Conor's Reviewed-by

Changes in v5:
	- Fixed path in MAINTAINERS

Changes in v4:
	- Align filename to compatible
	- Fix compatible in the example
	- Remove redundant word in the subject

Changes in v3:
	- Clarify commit dependency
	- Fix includes in the example
	- Fix YAML
	- Add "clock-cells" description
	- s/regroups/is composed of/
	- Changed compatible to show SoC specificity

Changes in v2:
	- Switch compatible and clock-cells related areas
	- Remove faulty #include in the example.
	- Add entry in MAINTAINERS
---
 .../bindings/display/st,stm32mp25-lvds.yaml        | 119 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 2 files changed, 120 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml b/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
new file mode 100644
index 000000000000..6736f93256b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/st,stm32mp25-lvds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32 LVDS Display Interface Transmitter
+
+maintainers:
+  - Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
+  - Yannick Fertre <yannick.fertre at foss.st.com>
+
+description: |
+  The STMicroelectronics STM32 LVDS Display Interface Transmitter handles the
+  LVDS protocol: it maps the pixels received from the upstream Pixel-DMA (LTDC)
+  onto the LVDS PHY.
+
+  It is composed of three sub blocks:
+    - LVDS host: handles the LVDS protocol (FPD / OpenLDI) and maps its input
+      pixels onto the data lanes of the PHY
+    - LVDS PHY: parallelize the data and drives the LVDS data lanes
+    - LVDS wrapper: handles top-level settings
+
+  The LVDS controller driver supports the following high-level features:
+    - FDP-Link-I and OpenLDI (v0.95) protocols
+    - Single-Link or Dual-Link operation
+    - Single-Display or Double-Display (with the same content duplicated on both)
+    - Flexible Bit-Mapping, including JEIDA and VESA
+    - RGB888 or RGB666 output
+    - Synchronous design, with one input pixel per clock cycle
+
+properties:
+  compatible:
+    const: st,stm32mp25-lvds
+
+  "#clock-cells":
+    const: 0
+    description:
+      Provides the internal LVDS PHY clock to the framework.
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: APB peripheral clock
+      - description: Reference clock for the internal PLL
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: ref
+
+  resets:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          LVDS input port node, connected to the LTDC RGB output port.
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          LVDS output port node, connected to a panel or bridge input port.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+    #include <dt-bindings/reset/st,stm32mp25-rcc.h>
+
+    lvds: lvds at 48060000 {
+        compatible = "st,stm32mp25-lvds";
+        reg = <0x48060000 0x2000>;
+        #clock-cells = <0>;
+        clocks = <&rcc CK_BUS_LVDS>, <&rcc CK_KER_LVDSPHY>;
+        clock-names = "pclk", "ref";
+        resets = <&rcc LVDS_R>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port at 0 {
+                reg = <0>;
+                lvds_in: endpoint {
+                   remote-endpoint = <&ltdc_ep1_out>;
+                };
+            };
+
+            port at 1 {
+                reg = <1>;
+                lvds_out0: endpoint {
+                   remote-endpoint = <&lvds_panel_in>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 3527a2ece6cd..ff5c945f206e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7240,6 +7240,7 @@ L:	dri-devel at lists.freedesktop.org
 S:	Maintained
 T:	git git://anongit.freedesktop.org/drm/drm-misc
 F:	Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml
+F:	Documentation/devicetree/bindings/display/st,stm32mp25-lvds.yaml
 F:	drivers/gpu/drm/stm
 
 DRM DRIVERS FOR TI KEYSTONE

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Mon Feb 26 02:48:04 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Mon, 26 Feb 2024 11:48:04 +0100
Subject: [PATCH v6 0/3] Introduce STM32 LVDS driver
Message-ID: <20240226-lvds-v6-0-15e3463fbe70@foss.st.com>

This serie introduces a new DRM bridge driver for STM32MP257 platforms
based on Arm Cortex-35. It also adds an instance in the device-tree and
handle the inclusion of the driver within the DRM framework. First patch
adds a new panel compatible in the panel-lvds driver, which is used by
default on the STM32MP257.

Changes in v6:
	- [1/3] Added Conor's Reviewed-by
	- [2/3] Fixed kernel test robot warnings
	- Rebased on latest drm-misc-next

Changes in v5:
	- Fixed path in MAINTAINERS
	- Fixed compatible in driver

Changes in v4:
	- Align dt-bindings filename and compatible
	- Remove redundant word in [1/6] subject
	- Fix example on typo
	- Some minor fixes on YAML syntax
	- Explicitly include linux/platform_device.h
	- Drop device-tree related patch after internal discussions
	- Rebase on latest drm-misc-next

Changes in v3:
	- Changed the compatible to show SoC specificity
	- Fixed includes in dt-binding example
	- Added "#clock-cells" description in dt-binding example
	- Some minor fixes on typo

Changes in v2:
	- Dropped [1/8] because already merged
	- Dropped [4/8] since not mandatory for this serie
	- [1/6]: Switch compatible and clock-cells related areas
	- [1/6]: Remove faulty #include in the example.
	- [1/6]: Add missing entry in MAINTAINERS
	- [2/6]: Removed CamelCase macros
	- [2/6]: Removed hard to read debug log
	- [3/6]: Fixed my address
	- [3/6]: Fixed smatch warning
	- [5/6]: Move changes to stm32mp255.dtsi

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Raphael Gallais-Pou (3):
      dt-bindings: display: add STM32 LVDS device
      drm/stm: lvds: add new STM32 LVDS Display Interface Transmitter driver
      drm/stm: ltdc: add lvds pixel clock

 .../bindings/display/st,stm32mp25-lvds.yaml        |  119 ++
 MAINTAINERS                                        |    1 +
 drivers/gpu/drm/stm/Kconfig                        |   11 +
 drivers/gpu/drm/stm/Makefile                       |    2 +
 drivers/gpu/drm/stm/ltdc.c                         |   19 +
 drivers/gpu/drm/stm/ltdc.h                         |    1 +
 drivers/gpu/drm/stm/lvds.c                         | 1226 ++++++++++++++++++++
 7 files changed, 1379 insertions(+)
---
base-commit: de8de2c8acb931ce6197a04376a7078ccf50e821
change-id: 20240205-lvds-e084ec50e878

Best regards,
-- 
Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>



From raphael.gallais-pou at foss.st.com  Mon Feb 26 02:48:07 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Mon, 26 Feb 2024 11:48:07 +0100
Subject: [PATCH v6 3/3] drm/stm: ltdc: add lvds pixel clock
In-Reply-To: <20240226-lvds-v6-0-15e3463fbe70@foss.st.com>
References: <20240226-lvds-v6-0-15e3463fbe70@foss.st.com>
Message-ID: <20240226-lvds-v6-3-15e3463fbe70@foss.st.com>

The STM32MP25x display subsystem presents a mux which feeds the loopback
pixel clock of the current bridge in use into the LTDC. This mux is only
accessible through sysconfig registers which is not yet available in the
STM32MP25x common clock framework.

While waiting for a complete update of the clock framework, this would
allow to use the LVDS.

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
---
Changes in v2:
	- Fixed my address
	- Fixed smatch warning
---
 drivers/gpu/drm/stm/ltdc.c | 19 +++++++++++++++++++
 drivers/gpu/drm/stm/ltdc.h |  1 +
 2 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 5576fdae4962..23011a8913bd 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -838,6 +838,12 @@ ltdc_crtc_mode_valid(struct drm_crtc *crtc,
 	int target_max = target + CLK_TOLERANCE_HZ;
 	int result;
 
+	if (ldev->lvds_clk) {
+		result = clk_round_rate(ldev->lvds_clk, target);
+		DRM_DEBUG_DRIVER("lvds pixclk rate target %d, available %d\n",
+				 target, result);
+	}
+
 	result = clk_round_rate(ldev->pixel_clk, target);
 
 	DRM_DEBUG_DRIVER("clk rate target %d, available %d\n", target, result);
@@ -1896,6 +1902,8 @@ void ltdc_suspend(struct drm_device *ddev)
 
 	DRM_DEBUG_DRIVER("\n");
 	clk_disable_unprepare(ldev->pixel_clk);
+	if (ldev->lvds_clk)
+		clk_disable_unprepare(ldev->lvds_clk);
 }
 
 int ltdc_resume(struct drm_device *ddev)
@@ -1910,6 +1918,13 @@ int ltdc_resume(struct drm_device *ddev)
 		DRM_ERROR("failed to enable pixel clock (%d)\n", ret);
 		return ret;
 	}
+	if (ldev->lvds_clk) {
+		if (clk_prepare_enable(ldev->lvds_clk)) {
+			clk_disable_unprepare(ldev->pixel_clk);
+			DRM_ERROR("Unable to prepare lvds clock\n");
+			return -ENODEV;
+		}
+	}
 
 	return 0;
 }
@@ -1981,6 +1996,10 @@ int ltdc_load(struct drm_device *ddev)
 		}
 	}
 
+	ldev->lvds_clk = devm_clk_get(dev, "lvds");
+	if (IS_ERR(ldev->lvds_clk))
+		ldev->lvds_clk = NULL;
+
 	rstc = devm_reset_control_get_exclusive(dev, NULL);
 
 	mutex_init(&ldev->err_lock);
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index 9d488043ffdb..4a60ce5b610c 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -44,6 +44,7 @@ struct ltdc_device {
 	void __iomem *regs;
 	struct regmap *regmap;
 	struct clk *pixel_clk;	/* lcd pixel clock */
+	struct clk *lvds_clk;	/* lvds pixel clock */
 	struct mutex err_lock;	/* protecting error_status */
 	struct ltdc_caps caps;
 	u32 irq_status;

-- 
2.25.1



From raphael.gallais-pou at foss.st.com  Mon Feb 26 02:48:06 2024
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Mon, 26 Feb 2024 11:48:06 +0100
Subject: [PATCH v6 2/3] drm/stm: lvds: add new STM32 LVDS Display Interface
 Transmitter driver
In-Reply-To: <20240226-lvds-v6-0-15e3463fbe70@foss.st.com>
References: <20240226-lvds-v6-0-15e3463fbe70@foss.st.com>
Message-ID: <20240226-lvds-v6-2-15e3463fbe70@foss.st.com>

The Low-Voltage Differential Signaling (LVDS) Display Interface
Transmitter handles the LVDS protocol: it maps the pixels received from
the upstream Pixel-DMA LCD-TFT Display Controller (LTDC) onto the LVDS
PHY.

It is composed of three sub blocks:
	* LVDS host: handles the LVDS protocol (FPD / OpenLDI) and maps
	  its input pixels onto the data lanes of the PHY
	* LVDS PHY: parallelize the data and drives the LVDS data lanes
	* LVDS wrapper: handles top-level settings

The LVDS controller driver supports the following high-level features:
	* FDP-Link-I and OpenLDI (v0.95) protocols
	* Single-Link or Dual-Link operation
	* Single-Display or Double-Display (with the same content
	  duplicated on both)
	* Flexible Bit-Mapping, including JEIDA and VESA
	* RGB888 or RGB666 output
	* Synchronous design, with one input pixel per clock cycle

Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
---
Changes in v6:
	- Fixes sparse symbols detected by kernel test robot

Changes in v5:
	- Align compatible

Changes in v4:
	- Explicitly include linux/platform_device.h, dependency introduced by
	ef175b29a242 of: Stop circularly including of_device.h and of_platform.h

Changes in v3:
	- s/regroups/is composed of/ in commit log
	- Change the compatible to show SoC specificity

Changes in v2:
	- Fixed Camel Case macros
	- Removed debug log
---
 drivers/gpu/drm/stm/Kconfig  |   11 +
 drivers/gpu/drm/stm/Makefile |    2 +
 drivers/gpu/drm/stm/lvds.c   | 1226 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1239 insertions(+)

diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig
index fa49cde43bb2..9627814d027c 100644
--- a/drivers/gpu/drm/stm/Kconfig
+++ b/drivers/gpu/drm/stm/Kconfig
@@ -20,3 +20,14 @@ config DRM_STM_DSI
 	select DRM_DW_MIPI_DSI
 	help
 	  Choose this option for MIPI DSI support on STMicroelectronics SoC.
+
+config DRM_STM_LVDS
+	tristate "STMicroelectronics LVDS Display Interface Transmitter DRM driver"
+	depends on DRM_STM
+	help
+	  Enable support for LVDS encoders on STMicroelectronics SoC.
+	  The STM LVDS is a bridge which serialize pixel stream onto
+	  a LVDS protocol.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called lvds.
diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile
index 4df5caf01f35..ad740d6175a6 100644
--- a/drivers/gpu/drm/stm/Makefile
+++ b/drivers/gpu/drm/stm/Makefile
@@ -5,4 +5,6 @@ stm-drm-y := \
 
 obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o
 
+obj-$(CONFIG_DRM_STM_LVDS) += lvds.o
+
 obj-$(CONFIG_DRM_STM) += stm-drm.o
diff --git a/drivers/gpu/drm/stm/lvds.c b/drivers/gpu/drm/stm/lvds.c
new file mode 100644
index 000000000000..bfc8cb13fbc5
--- /dev/null
+++ b/drivers/gpu/drm/stm/lvds.c
@@ -0,0 +1,1226 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Author(s): Rapha?l GALLAIS-POU <raphael.gallais-pou at foss.st.com> for STMicroelectronics.
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_device.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/media-bus-format.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+/* LVDS Host registers */
+#define LVDS_CR		0x0000  /* configuration register */
+#define LVDS_DMLCR0	0x0004  /* data mapping lsb configuration register 0 */
+#define LVDS_DMMCR0	0x0008  /* data mapping msb configuration register 0 */
+#define LVDS_DMLCR1	0x000C  /* data mapping lsb configuration register 1 */
+#define LVDS_DMMCR1	0x0010  /* data mapping msb configuration register 1 */
+#define LVDS_DMLCR2	0x0014  /* data mapping lsb configuration register 2 */
+#define LVDS_DMMCR2	0x0018  /* data mapping msb configuration register 2 */
+#define LVDS_DMLCR3	0x001C  /* data mapping lsb configuration register 3 */
+#define LVDS_DMMCR3	0x0020  /* data mapping msb configuration register 3 */
+#define LVDS_DMLCR4	0x0024  /* data mapping lsb configuration register 4 */
+#define LVDS_DMMCR4	0x0028  /* data mapping msb configuration register 4 */
+#define LVDS_CDL1CR	0x002C  /* channel distrib link 1 configuration register */
+#define LVDS_CDL2CR	0x0030  /* channel distrib link 2 configuration register */
+
+#define CDL1CR_DEFAULT	0x04321 /* Default value for CDL1CR */
+#define CDL2CR_DEFAULT	0x59876 /* Default value for CDL2CR */
+
+#define LVDS_DMLCR(bit)	(LVDS_DMLCR0 + 0x8 * (bit))
+#define LVDS_DMMCR(bit)	(LVDS_DMMCR0 + 0x8 * (bit))
+
+/* LVDS Wrapper registers */
+#define LVDS_WCLKCR	0x11B0  /* Wrapper clock control register */
+
+#define LVDS_HWCFGR	0x1FF0  /* HW configuration register	*/
+#define LVDS_VERR	0x1FF4  /* Version register	*/
+#define LVDS_IPIDR	0x1FF8  /* Identification register	*/
+#define LVDS_SIDR	0x1FFC  /* Size Identification register	*/
+
+/* Bitfield description */
+#define CR_LVDSEN	BIT(0)  /* LVDS PHY Enable */
+#define CR_HSPOL	BIT(1)  /* Horizontal Synchronization Polarity */
+#define CR_VSPOL	BIT(2)  /* Vertical Synchronization Polarity */
+#define CR_DEPOL	BIT(3)  /* Data Enable Polarity */
+#define CR_CI		BIT(4)  /* Control Internal (software controlled bit) */
+#define CR_LKMOD	BIT(5)  /* Link Mode, for both Links */
+#define CR_LKPHA	BIT(6)  /* Link Phase, for both Links */
+#define CR_LK1POL	GENMASK(20, 16)  /* Link-1 output Polarity */
+#define CR_LK2POL	GENMASK(25, 21)  /* Link-2 output Polarity */
+
+#define DMMCR_MAP0	GENMASK(4, 0) /* Mapping for bit 0 of datalane x */
+#define DMMCR_MAP1	GENMASK(9, 5) /* Mapping for bit 1 of datalane x */
+#define DMMCR_MAP2	GENMASK(14, 10) /* Mapping for bit 2 of datalane x */
+#define DMMCR_MAP3	GENMASK(19, 15) /* Mapping for bit 3 of datalane x */
+#define DMLCR_MAP4	GENMASK(4, 0) /* Mapping for bit 4 of datalane x */
+#define DMLCR_MAP5	GENMASK(9, 5) /* Mapping for bit 5 of datalane x */
+#define DMLCR_MAP6	GENMASK(14, 10) /* Mapping for bit 6 of datalane x */
+
+#define CDLCR_DISTR0	GENMASK(3, 0) /* Channel distribution for lane 0 */
+#define CDLCR_DISTR1	GENMASK(7, 4) /* Channel distribution for lane 1 */
+#define CDLCR_DISTR2	GENMASK(11, 8) /* Channel distribution for lane 2 */
+#define CDLCR_DISTR3	GENMASK(15, 12) /* Channel distribution for lane 3 */
+#define CDLCR_DISTR4	GENMASK(19, 16) /* Channel distribution for lane 4 */
+
+#define PHY_GCR_BIT_CLK_OUT	BIT(0)  /* BIT clock enable */
+#define PHY_GCR_LS_CLK_OUT	BIT(4)  /* LS clock enable */
+#define PHY_GCR_DP_CLK_OUT	BIT(8)  /* DP clock enable */
+#define PHY_GCR_RSTZ		BIT(24) /* LVDS PHY digital reset */
+#define PHY_GCR_DIV_RSTN	BIT(25) /* Output divider reset */
+#define PHY_SCR_TX_EN		BIT(16) /* Transmission mode enable */
+/* Current mode driver enable */
+#define PHY_CMCR_CM_EN_DL	(BIT(28) | BIT(20) | BIT(12) | BIT(4))
+#define PHY_CMCR_CM_EN_DL4	BIT(4)
+/* Bias enable */
+#define PHY_BCR1_EN_BIAS_DL	(BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0))
+#define PHY_BCR2_BIAS_EN	BIT(28)
+/* Voltage mode driver enable */
+#define PHY_BCR3_VM_EN_DL	(BIT(16) | BIT(12) | BIT(8) | BIT(4) | BIT(0))
+#define PHY_DCR_POWER_OK	BIT(12)
+#define PHY_CFGCR_EN_DIG_DL	GENMASK(4, 0) /* LVDS PHY digital lane enable */
+#define PHY_PLLCR1_PLL_EN	BIT(0) /* LVDS PHY PLL enable */
+#define PHY_PLLCR1_EN_SD	BIT(1) /* LVDS PHY PLL sigma-delta signal enable */
+#define PHY_PLLCR1_EN_TWG	BIT(2) /* LVDS PHY PLL triangular wave generator enable */
+#define PHY_PLLCR1_DIV_EN	BIT(8) /* LVDS PHY PLL dividers enable */
+#define PHY_PLLCR2_NDIV		GENMASK(25, 16) /* NDIV mask value */
+#define PHY_PLLCR2_BDIV		GENMASK(9, 0)   /* BDIV mask value */
+#define PHY_PLLSR_PLL_LOCK	BIT(0) /* LVDS PHY PLL lock status */
+#define PHY_PLLSDCR1_MDIV	GENMASK(9, 0)   /* MDIV mask value */
+#define PHY_PLLTESTCR_TDIV	GENMASK(25, 16) /* TDIV mask value */
+#define PHY_PLLTESTCR_CLK_EN	BIT(0) /* Test clock enable */
+#define PHY_PLLTESTCR_EN	BIT(8) /* Test divider output enable */
+
+#define WCLKCR_SECND_CLKPIX_SEL	BIT(0) /* Pixel clock selection */
+#define WCLKCR_SRCSEL		BIT(8) /* Source selection for the pixel clock */
+
+/* Sleep & timeout for pll lock/unlock */
+#define SLEEP_US	1000
+#define TIMEOUT_US	200000
+
+/*
+ * The link phase defines whether an ODD pixel is carried over together with
+ * the next EVEN pixel or together with the previous EVEN pixel.
+ *
+ * LVDS_DUAL_LINK_EVEN_ODD_PIXELS (LKPHA = 0)
+ *
+ * ,--------.  ,--------.  ,--------.  ,--------.  ,---------.
+ * | ODD  LK \/ PIXEL  3 \/ PIXEL  1 \/ PIXEL' 1 \/ PIXEL' 3 |
+ * | EVEN LK /\ PIXEL  2 /\ PIXEL' 0 /\ PIXEL' 2 /\ PIXEL' 4 |
+ * `--------'  `--------'  `--------'  `--------'  `---------'
+ *
+ * LVDS_DUAL_LINK_ODD_EVEN_PIXELS (LKPHA = 1)
+ *
+ * ,--------.  ,--------.  ,--------.  ,--------.  ,---------.
+ * | ODD  LK \/ PIXEL  3 \/ PIXEL  1 \/ PIXEL' 1 \/ PIXEL' 3 |
+ * | EVEN LK /\ PIXEL  4 /\ PIXEL  2 /\ PIXEL' 0 /\ PIXEL' 2 |
+ * `--------'  `--------'  `--------'  `--------'  `---------'
+ *
+ */
+enum lvds_link_type {
+	LVDS_SINGLE_LINK_PRIMARY = 0,
+	LVDS_SINGLE_LINK_SECONDARY,
+	LVDS_DUAL_LINK_EVEN_ODD_PIXELS,
+	LVDS_DUAL_LINK_ODD_EVEN_PIXELS,
+};
+
+enum lvds_pixel {
+	PIX_R_0 = 0,
+	PIX_R_1,
+	PIX_R_2,
+	PIX_R_3,
+	PIX_R_4,
+	PIX_R_5,
+	PIX_R_6,
+	PIX_R_7,
+	PIX_G_0,
+	PIX_G_1,
+	PIX_G_2,
+	PIX_G_3,
+	PIX_G_4,
+	PIX_G_5,
+	PIX_G_6,
+	PIX_G_7,
+	PIX_B_0,
+	PIX_B_1,
+	PIX_B_2,
+	PIX_B_3,
+	PIX_B_4,
+	PIX_B_5,
+	PIX_B_6,
+	PIX_B_7,
+	PIX_H_S,
+	PIX_V_S,
+	PIX_D_E,
+	PIX_C_E,
+	PIX_C_I,
+	PIX_TOG,
+	PIX_ONE,
+	PIX_ZER,
+};
+
+struct phy_reg_offsets {
+	u32 GCR;	/* Global Control Register	*/
+	u32 CMCR1;    /* Current Mode Control Register 1 */
+	u32 CMCR2;    /* Current Mode Control Register 2 */
+	u32 SCR;      /* Serial Control Register	*/
+	u32 BCR1;     /* Bias Control Register 1	*/
+	u32 BCR2;     /* Bias Control Register 2	*/
+	u32 BCR3;     /* Bias Control Register 3	*/
+	u32 MPLCR;    /* Monitor PLL Lock Control Register */
+	u32 DCR;      /* Debug Control Register	*/
+	u32 SSR1;     /* Spare Status Register 1	*/
+	u32 CFGCR;    /* Configuration Control Register */
+	u32 PLLCR1;   /* PLL_MODE 1 Control Register	*/
+	u32 PLLCR2;   /* PLL_MODE 2 Control Register	*/
+	u32 PLLSR;    /* PLL Status Register	*/
+	u32 PLLSDCR1; /* PLL_SD_1 Control Register	*/
+	u32 PLLSDCR2; /* PLL_SD_2 Control Register	*/
+	u32 PLLTWGCR1;/* PLL_TWG_1 Control Register	*/
+	u32 PLLTWGCR2;/* PLL_TWG_2 Control Register	*/
+	u32 PLLCPCR;  /* PLL_CP Control Register	*/
+	u32 PLLTESTCR;/* PLL_TEST Control Register	*/
+};
+
+struct lvds_phy_info {
+	u32 base;
+	struct phy_reg_offsets ofs;
+};
+
+static struct lvds_phy_info lvds_phy_16ff_primary = {
+	.base = 0x1000,
+	.ofs = {
+		.GCR = 0x0,
+		.CMCR1 = 0xC,
+		.CMCR2 = 0x10,
+		.SCR = 0x20,
+		.BCR1 = 0x2C,
+		.BCR2 = 0x30,
+		.BCR3 = 0x34,
+		.MPLCR = 0x64,
+		.DCR = 0x84,
+		.SSR1 = 0x88,
+		.CFGCR = 0xA0,
+		.PLLCR1 = 0xC0,
+		.PLLCR2 = 0xC4,
+		.PLLSR = 0xC8,
+		.PLLSDCR1 = 0xCC,
+		.PLLSDCR2 = 0xD0,
+		.PLLTWGCR1 = 0xD4,
+		.PLLTWGCR2 = 0xD8,
+		.PLLCPCR = 0xE0,
+		.PLLTESTCR = 0xE8,
+	}
+};
+
+static struct lvds_phy_info lvds_phy_16ff_secondary = {
+	.base = 0x1100,
+	.ofs = {
+		.GCR = 0x0,
+		.CMCR1 = 0xC,
+		.CMCR2 = 0x10,
+		.SCR = 0x20,
+		.BCR1 = 0x2C,
+		.BCR2 = 0x30,
+		.BCR3 = 0x34,
+		.MPLCR = 0x64,
+		.DCR = 0x84,
+		.SSR1 = 0x88,
+		.CFGCR = 0xA0,
+		.PLLCR1 = 0xC0,
+		.PLLCR2 = 0xC4,
+		.PLLSR = 0xC8,
+		.PLLSDCR1 = 0xCC,
+		.PLLSDCR2 = 0xD0,
+		.PLLTWGCR1 = 0xD4,
+		.PLLTWGCR2 = 0xD8,
+		.PLLCPCR = 0xE0,
+		.PLLTESTCR = 0xE8,
+	}
+};
+
+struct stm_lvds {
+	void __iomem *base;
+	struct device *dev;
+	struct clk *pclk;		/* APB peripheral clock */
+	struct clk *pllref_clk;		/* Reference clock for the internal PLL */
+	struct clk_hw lvds_ck_px;	/* Pixel clock */
+	u32 pixel_clock_rate;		/* Pixel clock rate */
+
+	struct lvds_phy_info *primary;
+	struct lvds_phy_info *secondary;
+
+	struct drm_bridge lvds_bridge;
+	struct drm_bridge *next_bridge;
+	struct drm_connector connector;
+	struct drm_encoder *encoder;
+	struct drm_panel *panel;
+
+	u32 hw_version;
+	u32 link_type;
+};
+
+#define bridge_to_stm_lvds(b) \
+	container_of(b, struct stm_lvds, lvds_bridge)
+
+#define connector_to_stm_lvds(c) \
+	container_of(c, struct stm_lvds, connector)
+
+#define lvds_is_dual_link(lvds) \
+	({	\
+	typeof(lvds) __lvds = (lvds);	\
+	__lvds == LVDS_DUAL_LINK_EVEN_ODD_PIXELS ||	\
+	__lvds == LVDS_DUAL_LINK_ODD_EVEN_PIXELS;	\
+	})
+
+static inline void lvds_write(struct stm_lvds *lvds, u32 reg, u32 val)
+{
+	writel(val, lvds->base + reg);
+}
+
+static inline u32 lvds_read(struct stm_lvds *lvds, u32 reg)
+{
+	return readl(lvds->base + reg);
+}
+
+static inline void lvds_set(struct stm_lvds *lvds, u32 reg, u32 mask)
+{
+	lvds_write(lvds, reg, lvds_read(lvds, reg) | mask);
+}
+
+static inline void lvds_clear(struct stm_lvds *lvds, u32 reg, u32 mask)
+{
+	lvds_write(lvds, reg, lvds_read(lvds, reg) & ~mask);
+}
+
+/*
+ * Expected JEIDA-RGB888 data to be sent in LSB format
+ *	    bit6 ............................bit0
+ * CHAN0   {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE}
+ * CHAN1   {G2,  R7,  R6,   R5,   R4,   R3,  R2}
+ * CHAN2   {B3,  B2,  G7,   G6,   G5,   G4,  G3}
+ * CHAN3   {DE,  VS,  HS,   B7,   B6,   B5,  B4}
+ * CHAN4   {CE,  B1,  B0,   G1,   G0,   R1,  R0}
+ */
+static enum lvds_pixel lvds_bitmap_jeida_rgb888[5][7] = {
+	{ PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE },
+	{ PIX_G_2, PIX_R_7, PIX_R_6, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2 },
+	{ PIX_B_3, PIX_B_2, PIX_G_7, PIX_G_6, PIX_G_5, PIX_G_4, PIX_G_3 },
+	{ PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_7, PIX_B_6, PIX_B_5, PIX_B_4 },
+	{ PIX_C_E, PIX_B_1, PIX_B_0, PIX_G_1, PIX_G_0, PIX_R_1, PIX_R_0 }
+};
+
+/*
+ * Expected VESA-RGB888 data to be sent in LSB format
+ *	    bit6 ............................bit0
+ * CHAN0   {ONE, ONE, ZERO, ZERO, ZERO, ONE, ONE}
+ * CHAN1   {G0,  R5,  R4,   R3,   R2,   R1,  R0}
+ * CHAN2   {B1,  B0,  G5,   G4,   G3,   G2,  G1}
+ * CHAN3   {DE,  VS,  HS,   B5,   B4,   B3,  B2}
+ * CHAN4   {CE,  B7,  B6,   G7,   G6,   R7,  R6}
+ */
+static enum lvds_pixel lvds_bitmap_vesa_rgb888[5][7] = {
+	{ PIX_ONE, PIX_ONE, PIX_ZER, PIX_ZER, PIX_ZER, PIX_ONE, PIX_ONE },
+	{ PIX_G_0, PIX_R_5, PIX_R_4, PIX_R_3, PIX_R_2, PIX_R_1, PIX_R_0 },
+	{ PIX_B_1, PIX_B_0, PIX_G_5, PIX_G_4, PIX_G_3, PIX_G_2, PIX_G_1 },
+	{ PIX_D_E, PIX_V_S, PIX_H_S, PIX_B_5, PIX_B_4, PIX_B_3, PIX_B_2 },
+	{ PIX_C_E, PIX_B_7, PIX_B_6, PIX_G_7, PIX_G_6, PIX_R_7, PIX_R_6 }
+};
+
+/*
+ * Clocks and PHY related functions
+ */
+static int lvds_pll_enable(struct stm_lvds *lvds, struct lvds_phy_info *phy)
+{
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	u32 lvds_gcr;
+	int val, ret;
+
+	/*
+	 * PLL lock timing control for the monitor unmask after startup (pll_en)
+	 * Adjusted value so that the masking window is opened at start-up
+	 */
+	lvds_write(lvds, phy->base + phy->ofs.MPLCR, (0x200 - 0x160) << 16);
+
+	/* Enable bias */
+	lvds_write(lvds, phy->base + phy->ofs.BCR2, PHY_BCR2_BIAS_EN);
+
+	/* Enable DP, LS, BIT clock output */
+	lvds_gcr = PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT;
+	lvds_set(lvds, phy->base + phy->ofs.GCR, lvds_gcr);
+
+	/* Power up all output dividers */
+	lvds_set(lvds, phy->base + phy->ofs.PLLTESTCR, PHY_PLLTESTCR_EN);
+	lvds_set(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_DIV_EN);
+
+	/* Set PHY in serial transmission mode */
+	lvds_set(lvds, phy->base + phy->ofs.SCR, PHY_SCR_TX_EN);
+
+	/* Enable the LVDS PLL & wait for its lock */
+	lvds_set(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_PLL_EN);
+	ret = readl_poll_timeout_atomic(lvds->base + phy->base + phy->ofs.PLLSR,
+					val, val & PHY_PLLSR_PLL_LOCK,
+					SLEEP_US, TIMEOUT_US);
+	if (ret)
+		drm_err(drm, "!TIMEOUT! waiting PLL, let's continue\n");
+
+	/* WCLKCR_SECND_CLKPIX_SEL is for dual link */
+	lvds_write(lvds, LVDS_WCLKCR, WCLKCR_SECND_CLKPIX_SEL);
+
+	lvds_set(lvds, phy->ofs.PLLTESTCR, PHY_PLLTESTCR_CLK_EN);
+
+	return ret;
+}
+
+static int pll_get_clkout_khz(int clkin_khz, int bdiv, int mdiv, int ndiv)
+{
+	int divisor = ndiv * bdiv;
+
+	/* Prevents from division by 0 */
+	if (!divisor)
+		return 0;
+
+	return clkin_khz * mdiv / divisor;
+}
+
+#define TDIV	70
+#define NDIV_MIN	2
+#define NDIV_MAX	6
+#define BDIV_MIN	2
+#define BDIV_MAX	6
+#define MDIV_MIN	1
+#define MDIV_MAX	1023
+
+static int lvds_pll_get_params(struct stm_lvds *lvds,
+			       unsigned int clkin_khz, unsigned int clkout_khz,
+			       unsigned int *bdiv, unsigned int *mdiv, unsigned int *ndiv)
+{
+	int delta, best_delta; /* all in khz */
+	int i, o, n;
+
+	/* Early checks preventing division by 0 & odd results */
+	if (clkin_khz <= 0 || clkout_khz <= 0)
+		return -EINVAL;
+
+	best_delta = 1000000; /* big started value (1000000khz) */
+
+	for (i = NDIV_MIN; i <= NDIV_MAX; i++) {
+		for (o = BDIV_MIN; o <= BDIV_MAX; o++) {
+			n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz);
+			/* Check ndiv according to vco range */
+			if (n < MDIV_MIN || n > MDIV_MAX)
+				continue;
+			/* Check if new delta is better & saves parameters */
+			delta = pll_get_clkout_khz(clkin_khz, i, n, o) - clkout_khz;
+			if (delta < 0)
+				delta = -delta;
+			if (delta < best_delta) {
+				*ndiv = i;
+				*mdiv = n;
+				*bdiv = o;
+				best_delta = delta;
+			}
+			/* fast return in case of "perfect result" */
+			if (!delta)
+				return 0;
+		}
+	}
+
+	return 0;
+}
+
+static void lvds_pll_config(struct stm_lvds *lvds, struct lvds_phy_info *phy)
+{
+	unsigned int pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0;
+	struct clk_hw *hwclk;
+	int multiplier;
+
+	/*
+	 * The LVDS PHY includes a low power low jitter high performance and
+	 * highly configuration Phase Locked Loop supporting integer and
+	 * fractional multiplication ratios and Spread Spectrum Clocking.  In
+	 * integer mode, the only software supported feature for now, the PLL is
+	 * made of a pre-divider NDIV, a feedback multiplier MDIV, followed by
+	 * several post-dividers, each one with a specific application.
+	 *
+	 *          ,------.         ,-----.     ,-----.
+	 * Fref --> | NDIV | -Fpdf-> | PFD | --> | VCO | --------> Fvco
+	 *          `------'     ,-> |     |     `-----'  |
+	 *                       |   `-----'              |
+	 *                       |         ,------.       |
+	 *                       `-------- | MDIV | <-----'
+	 *                                 `------'
+	 *
+	 * From the output of the VCO, the clock can be optionally extracted on
+	 * the RCC clock observer, with a divider TDIV, for testing purpose, or
+	 * is passed through a programmable post-divider BDIV.  Finally, the
+	 * frequency can be divided further with two fixed dividers.
+	 *
+	 *                            ,--------.
+	 *                    ,-----> | DP div | ----------------> Fdp
+	 *          ,------.  |       `--------'
+	 * Fvco --> | BDIV | ------------------------------------> Fbit
+	 *      |   `------'    ,------.   |
+	 *      `-------------> | TDIV | --.---------------------> ClkObs
+	 *                      '------'   |    ,--------.
+	 *                                 `--> | LS div | ------> Fls
+	 *                                      '--------'
+	 *
+	 * The LS and DP clock dividers operate at a fixed ratio of 7 and 3.5
+	 * respectively with regards to fbit. LS divider converts the bit clock
+	 * to a pixel clock per lane per clock sample (Fls).  This is useful
+	 * when used to generate a dot clock for the display unit RGB output,
+	 * and DP divider is.
+	 */
+
+	hwclk = __clk_get_hw(lvds->pllref_clk);
+	if (!hwclk)
+		return;
+
+	pll_in_khz = clk_hw_get_rate(hwclk) / 1000;
+
+	if (lvds_is_dual_link(lvds->link_type))
+		multiplier = 2;
+	else
+		multiplier = 1;
+
+	lvds_pll_get_params(lvds, pll_in_khz,
+			    lvds->pixel_clock_rate * 7 / 1000 / multiplier,
+			    &bdiv, &mdiv, &ndiv);
+
+	/* Set BDIV, MDIV and NDIV */
+	lvds_write(lvds, phy->base + phy->ofs.PLLCR2, ndiv << 16);
+	lvds_set(lvds, phy->base + phy->ofs.PLLCR2, bdiv);
+	lvds_write(lvds, phy->base + phy->ofs.PLLSDCR1, mdiv);
+
+	/* Hardcode TDIV as dynamic values are not yet implemented */
+	lvds_write(lvds, phy->base + phy->ofs.PLLTESTCR, TDIV << 16);
+
+	/*
+	 * For now, PLL just needs to be in integer mode
+	 * Fractional and spread spectrum clocking are not yet implemented
+	 *
+	 * PLL integer mode:
+	 *	- PMRY_PLL_TWG_STEP = PMRY_PLL_SD_INT_RATIO
+	 *	- EN_TWG = 0
+	 *	- EN_SD = 0
+	 *	- DOWN_SPREAD = 0
+	 *
+	 * PLL fractional mode:
+	 *	- EN_TWG = 0
+	 *	- EN_SD = 1
+	 *	- DOWN_SPREAD = 0
+	 *
+	 * Spread Spectrum Clocking
+	 *	- EN_TWG = 1
+	 *	- EN_SD = 1
+	 */
+
+	/* Disable TWG and SD */
+	lvds_clear(lvds, phy->base + phy->ofs.PLLCR1, PHY_PLLCR1_EN_TWG | PHY_PLLCR1_EN_SD);
+
+	/* Power up bias and PLL dividers */
+	lvds_set(lvds, phy->base + phy->ofs.DCR, PHY_DCR_POWER_OK);
+	lvds_set(lvds, phy->base + phy->ofs.CMCR1, PHY_CMCR_CM_EN_DL);
+	lvds_set(lvds, phy->base + phy->ofs.CMCR2, PHY_CMCR_CM_EN_DL4);
+
+	/* Set up voltage mode */
+	lvds_set(lvds, phy->base + phy->ofs.PLLCPCR, 0x1);
+	lvds_set(lvds, phy->base + phy->ofs.BCR3, PHY_BCR3_VM_EN_DL);
+	lvds_set(lvds, phy->base + phy->ofs.BCR1, PHY_BCR1_EN_BIAS_DL);
+	/* Enable digital datalanes */
+	lvds_set(lvds, phy->base + phy->ofs.CFGCR, PHY_CFGCR_EN_DIG_DL);
+}
+
+static int lvds_pixel_clk_enable(struct clk_hw *hw)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	struct lvds_phy_info *phy;
+	int ret;
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		drm_err(drm, "Failed to enable lvds peripheral clk\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(lvds->pllref_clk);
+	if (ret) {
+		drm_err(drm, "Failed to enable lvds reference clk\n");
+		clk_disable_unprepare(lvds->pclk);
+		return ret;
+	}
+
+	/* In case we are operating in dual link the second PHY is set before the primary PHY. */
+	if (lvds->secondary) {
+		phy = lvds->secondary;
+
+		/* Release LVDS PHY from reset mode */
+		lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+		lvds_pll_config(lvds, phy);
+
+		ret = lvds_pll_enable(lvds, phy);
+		if (ret) {
+			drm_err(drm, "Failed to enable secondary PHY PLL: %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (lvds->primary) {
+		phy = lvds->primary;
+
+		/* Release LVDS PHY from reset mode */
+		lvds_set(lvds, phy->base + phy->ofs.GCR, PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+		lvds_pll_config(lvds, phy);
+
+		ret = lvds_pll_enable(lvds, phy);
+		if (ret) {
+			drm_err(drm, "Failed to enable primary PHY PLL: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static void lvds_pixel_clk_disable(struct clk_hw *hw)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+
+	/*
+	 * For each PHY:
+	 * Disable DP, LS, BIT clock outputs
+	 * Shutdown the PLL
+	 * Assert LVDS PHY in reset mode
+	 */
+
+	if (lvds->primary) {
+		lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR,
+			   (PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT));
+		lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR1,
+			   PHY_PLLCR1_PLL_EN);
+		lvds_clear(lvds, lvds->primary->base + lvds->primary->ofs.GCR,
+			   PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+	}
+
+	if (lvds->secondary) {
+		lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR,
+			   (PHY_GCR_DP_CLK_OUT | PHY_GCR_LS_CLK_OUT | PHY_GCR_BIT_CLK_OUT));
+		lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.PLLCR1,
+			   PHY_PLLCR1_PLL_EN);
+		lvds_clear(lvds, lvds->secondary->base + lvds->secondary->ofs.GCR,
+			   PHY_GCR_DIV_RSTN | PHY_GCR_RSTZ);
+	}
+
+	clk_disable_unprepare(lvds->pllref_clk);
+	clk_disable_unprepare(lvds->pclk);
+}
+
+static unsigned long lvds_pixel_clk_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	unsigned int pll_in_khz, bdiv, mdiv, ndiv;
+	int ret, multiplier, pll_out_khz;
+	u32 val;
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		drm_err(drm, "Failed to enable lvds peripheral clk\n");
+		return 0;
+	}
+
+	if (lvds_is_dual_link(lvds->link_type))
+		multiplier = 2;
+	else
+		multiplier = 1;
+
+	val = lvds_read(lvds, lvds->primary->base + lvds->primary->ofs.PLLCR2);
+
+	ndiv = (val & PHY_PLLCR2_NDIV) >> 16;
+	bdiv = (val & PHY_PLLCR2_BDIV) >> 0;
+
+	mdiv = (unsigned int)lvds_read(lvds,
+				       lvds->primary->base + lvds->primary->ofs.PLLSDCR1);
+
+	pll_in_khz = (unsigned int)(parent_rate / 1000);
+
+	/* Compute values if not yet accessible */
+	if (val == 0 || mdiv == 0) {
+		lvds_pll_get_params(lvds, pll_in_khz,
+				    lvds->pixel_clock_rate * 7 / 1000 / multiplier,
+				    &bdiv, &mdiv, &ndiv);
+	}
+
+	pll_out_khz = pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv);
+	drm_dbg(drm, "ndiv %d , bdiv %d, mdiv %d, pll_out_khz %d\n",
+		ndiv, bdiv, mdiv, pll_out_khz);
+
+	/*
+	 * 1/7 because for each pixel in 1 lane there is 7 bits
+	 * We want pixclk, not bitclk
+	 */
+	lvds->pixel_clock_rate = pll_out_khz * 1000 * multiplier / 7;
+
+	clk_disable_unprepare(lvds->pclk);
+
+	return (unsigned long)lvds->pixel_clock_rate;
+}
+
+static long lvds_pixel_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *parent_rate)
+{
+	struct stm_lvds *lvds = container_of(hw, struct stm_lvds, lvds_ck_px);
+	unsigned int pll_in_khz, bdiv = 0, mdiv = 0, ndiv = 0;
+	const struct drm_connector *connector;
+	const struct drm_display_mode *mode;
+	int multiplier;
+
+	connector = &lvds->connector;
+	if (!connector)
+		return -EINVAL;
+
+	if (list_empty(&connector->modes)) {
+		drm_dbg(connector->dev, "connector: empty modes list\n");
+		return -EINVAL;
+	}
+
+	mode = list_first_entry(&connector->modes,
+				struct drm_display_mode, head);
+
+	pll_in_khz = (unsigned int)(*parent_rate / 1000);
+
+	if (lvds_is_dual_link(lvds->link_type))
+		multiplier = 2;
+	else
+		multiplier = 1;
+
+	lvds_pll_get_params(lvds, pll_in_khz, mode->clock * 7 / multiplier, &bdiv, &mdiv, &ndiv);
+
+	/*
+	 * 1/7 because for each pixel in 1 lane there is 7 bits
+	 * We want pixclk, not bitclk
+	 */
+	lvds->pixel_clock_rate = (unsigned long)pll_get_clkout_khz(pll_in_khz, bdiv, mdiv, ndiv)
+					 * 1000 * multiplier / 7;
+
+	return lvds->pixel_clock_rate;
+}
+
+static const struct clk_ops lvds_pixel_clk_ops = {
+	.enable = lvds_pixel_clk_enable,
+	.disable = lvds_pixel_clk_disable,
+	.recalc_rate = lvds_pixel_clk_recalc_rate,
+	.round_rate = lvds_pixel_clk_round_rate,
+};
+
+static const struct clk_init_data clk_data = {
+	.name = "clk_pix_lvds",
+	.ops = &lvds_pixel_clk_ops,
+	.parent_names = (const char * []) {"ck_ker_lvdsphy"},
+	.num_parents = 1,
+	.flags = CLK_IGNORE_UNUSED,
+};
+
+static void lvds_pixel_clk_unregister(void *data)
+{
+	struct stm_lvds *lvds = data;
+
+	of_clk_del_provider(lvds->dev->of_node);
+	clk_hw_unregister(&lvds->lvds_ck_px);
+}
+
+static int lvds_pixel_clk_register(struct stm_lvds *lvds)
+{
+	struct device_node *node = lvds->dev->of_node;
+	int ret;
+
+	lvds->lvds_ck_px.init = &clk_data;
+
+	/* set the rate by default at 148500000 */
+	lvds->pixel_clock_rate = 148500000;
+
+	ret = clk_hw_register(lvds->dev, &lvds->lvds_ck_px);
+	if (ret)
+		return ret;
+
+	ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get,
+				     &lvds->lvds_ck_px);
+	if (ret)
+		clk_hw_unregister(&lvds->lvds_ck_px);
+
+	return ret;
+}
+
+/*
+ * Host configuration related
+ */
+static void lvds_config_data_mapping(struct stm_lvds *lvds)
+{
+	struct drm_device *drm = lvds->lvds_bridge.dev;
+	const struct drm_display_info *info;
+	enum lvds_pixel (*bitmap)[7];
+	u32 lvds_dmlcr, lvds_dmmcr;
+	int i;
+
+	info = &(&lvds->connector)->display_info;
+	if (!info->num_bus_formats || !info->bus_formats) {
+		drm_warn(drm, "No LVDS bus format reported\n");
+		return;
+	}
+
+	switch (info->bus_formats[0]) {
+	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* VESA-RGB666 */
+		drm_warn(drm, "Pixel format with data mapping not yet supported.\n");
+		return;
+	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: /* VESA-RGB888 */
+		bitmap = lvds_bitmap_vesa_rgb888;
+		break;
+	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* JEIDA-RGB888 */
+		bitmap = lvds_bitmap_jeida_rgb888;
+		break;
+	default:
+		drm_warn(drm, "Unsupported LVDS bus format 0x%04x\n", info->bus_formats[0]);
+		return;
+	}
+
+	/* Set bitmap for each lane */
+	for (i = 0; i < 5; i++) {
+		lvds_dmlcr = ((bitmap[i][0])
+			      + (bitmap[i][1] << 5)
+			      + (bitmap[i][2] << 10)
+			      + (bitmap[i][3] << 15));
+		lvds_dmmcr = ((bitmap[i][4])
+			      + (bitmap[i][5] << 5)
+			      + (bitmap[i][6] << 10));
+
+		lvds_write(lvds, LVDS_DMLCR(i), lvds_dmlcr);
+		lvds_write(lvds, LVDS_DMMCR(i), lvds_dmmcr);
+	}
+}
+
+static void lvds_config_mode(struct stm_lvds *lvds)
+{
+	u32 bus_flags, lvds_cr = 0, lvds_cdl1cr = 0, lvds_cdl2cr = 0;
+	const struct drm_display_mode *mode;
+	const struct drm_connector *connector;
+
+	connector = &lvds->connector;
+	if (!connector)
+		return;
+
+	if (list_empty(&connector->modes)) {
+		drm_dbg(connector->dev, "connector: empty modes list\n");
+		return;
+	}
+
+	bus_flags = connector->display_info.bus_flags;
+	mode = list_first_entry(&connector->modes,
+				struct drm_display_mode, head);
+
+	lvds_clear(lvds, LVDS_CR, CR_LKMOD);
+	lvds_clear(lvds, LVDS_CDL1CR, CDLCR_DISTR0 | CDLCR_DISTR1 | CDLCR_DISTR2 |
+				      CDLCR_DISTR3 | CDLCR_DISTR4);
+	lvds_clear(lvds, LVDS_CDL2CR, CDLCR_DISTR0 | CDLCR_DISTR1 | CDLCR_DISTR2 |
+				      CDLCR_DISTR3 | CDLCR_DISTR4);
+
+	/* Set channel distribution */
+	if (lvds->primary)
+		lvds_cdl1cr = CDL1CR_DEFAULT;
+
+	if (lvds->secondary) {
+		lvds_cr |= CR_LKMOD;
+		lvds_cdl2cr = CDL2CR_DEFAULT;
+	}
+
+	/* Set signal polarity */
+	if (bus_flags & DRM_BUS_FLAG_DE_LOW)
+		lvds_cr |= CR_DEPOL;
+
+	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+		lvds_cr |= CR_HSPOL;
+
+	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+		lvds_cr |= CR_VSPOL;
+
+	switch (lvds->link_type) {
+	case LVDS_DUAL_LINK_EVEN_ODD_PIXELS: /* LKPHA = 0 */
+		lvds_cr &= ~CR_LKPHA;
+		break;
+	case LVDS_DUAL_LINK_ODD_EVEN_PIXELS: /* LKPHA = 1 */
+		lvds_cr |= CR_LKPHA;
+		break;
+	default:
+		drm_notice(lvds->lvds_bridge.dev, "No phase precised, setting default\n");
+		lvds_cr &= ~CR_LKPHA;
+		break;
+	}
+
+	/* Write config to registers */
+	lvds_set(lvds, LVDS_CR, lvds_cr);
+	lvds_write(lvds, LVDS_CDL1CR, lvds_cdl1cr);
+	lvds_write(lvds, LVDS_CDL2CR, lvds_cdl2cr);
+}
+
+static int lvds_connector_get_modes(struct drm_connector *connector)
+{
+	struct stm_lvds *lvds = connector_to_stm_lvds(connector);
+
+	return drm_panel_get_modes(lvds->panel, connector);
+}
+
+static int lvds_connector_atomic_check(struct drm_connector *connector,
+				       struct drm_atomic_state *state)
+{
+	const struct drm_display_mode *panel_mode;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc_state *crtc_state;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (!conn_state)
+		return -EINVAL;
+
+	if (list_empty(&connector->modes)) {
+		drm_dbg(connector->dev, "connector: empty modes list\n");
+		return -EINVAL;
+	}
+
+	if (!conn_state->crtc)
+		return -EINVAL;
+
+	panel_mode = list_first_entry(&connector->modes,
+				      struct drm_display_mode, head);
+
+	/* We're not allowed to modify the resolution. */
+	crtc_state = drm_atomic_get_crtc_state(state, conn_state->crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
+	if (crtc_state->mode.hdisplay != panel_mode->hdisplay ||
+	    crtc_state->mode.vdisplay != panel_mode->vdisplay)
+		return -EINVAL;
+
+	/* The flat panel mode is fixed, just copy it to the adjusted mode. */
+	drm_mode_copy(&crtc_state->adjusted_mode, panel_mode);
+
+	return 0;
+}
+
+static const struct drm_connector_helper_funcs lvds_conn_helper_funcs = {
+	.get_modes = lvds_connector_get_modes,
+	.atomic_check = lvds_connector_atomic_check,
+};
+
+static const struct drm_connector_funcs lvds_conn_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 int lvds_attach(struct drm_bridge *bridge,
+		       enum drm_bridge_attach_flags flags)
+{
+	struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);
+	struct drm_connector *connector = &lvds->connector;
+	struct drm_encoder *encoder = bridge->encoder;
+	int ret;
+
+	if (!bridge->encoder) {
+		drm_err(bridge->dev, "Parent encoder object not found\n");
+		return -ENODEV;
+	}
+
+	/* Set the encoder type as caller does not know it */
+	bridge->encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
+
+	/* No cloning support */
+	bridge->encoder->possible_clones = 0;
+
+	/* If we have a next bridge just attach it. */
+	if (lvds->next_bridge)
+		return drm_bridge_attach(bridge->encoder, lvds->next_bridge,
+					 bridge, flags);
+
+	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
+		drm_err(bridge->dev, "Fix bridge driver to make connector optional!");
+		return -EINVAL;
+	}
+
+	/* Otherwise if we have a panel, create a connector. */
+	if (!lvds->panel)
+		return 0;
+
+	ret = drm_connector_init(bridge->dev, connector,
+				 &lvds_conn_funcs, DRM_MODE_CONNECTOR_LVDS);
+	if (ret < 0)
+		return ret;
+
+	drm_connector_helper_add(connector, &lvds_conn_helper_funcs);
+
+	ret = drm_connector_attach_encoder(connector, encoder);
+
+	return ret;
+}
+
+static void lvds_atomic_enable(struct drm_bridge *bridge,
+			       struct drm_bridge_state *old_bridge_state)
+{
+	struct drm_atomic_state *state = old_bridge_state->base.state;
+	struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);
+	struct drm_connector_state *conn_state;
+	struct drm_connector *connector;
+	int ret;
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		drm_err(bridge->dev, "Failed to enable lvds peripheral clk\n");
+		return;
+	}
+
+	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
+	if (!connector)
+		return;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (!conn_state)
+		return;
+
+	lvds_config_mode(lvds);
+
+	/* Set Data Mapping */
+	lvds_config_data_mapping(lvds);
+
+	/* Turn the output on. */
+	lvds_set(lvds, LVDS_CR, CR_LVDSEN);
+
+	if (lvds->panel) {
+		drm_panel_prepare(lvds->panel);
+		drm_panel_enable(lvds->panel);
+	}
+}
+
+static void lvds_atomic_disable(struct drm_bridge *bridge,
+				struct drm_bridge_state *old_bridge_state)
+{
+	struct stm_lvds *lvds = bridge_to_stm_lvds(bridge);
+
+	if (lvds->panel) {
+		drm_panel_disable(lvds->panel);
+		drm_panel_unprepare(lvds->panel);
+	}
+
+	/* Disable LVDS module */
+	lvds_clear(lvds, LVDS_CR, CR_LVDSEN);
+
+	clk_disable_unprepare(lvds->pclk);
+}
+
+static const struct drm_bridge_funcs lvds_bridge_funcs = {
+	.attach = lvds_attach,
+	.atomic_enable = lvds_atomic_enable,
+	.atomic_disable = lvds_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,
+};
+
+static int lvds_probe(struct platform_device *pdev)
+{
+	struct device_node *port1, *port2, *remote;
+	struct device *dev = &pdev->dev;
+	struct reset_control *rstc;
+	struct stm_lvds *lvds;
+	int ret, dual_link;
+
+	dev_dbg(dev, "Probing LVDS driver...\n");
+
+	lvds = devm_kzalloc(dev, sizeof(*lvds), GFP_KERNEL);
+	if (!lvds)
+		return -ENOMEM;
+
+	lvds->dev = dev;
+
+	ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0,
+					  &lvds->panel, &lvds->next_bridge);
+	if (ret) {
+		dev_err_probe(dev, ret, "Panel not found\n");
+		return ret;
+	}
+
+	lvds->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(lvds->base)) {
+		ret = PTR_ERR(lvds->base);
+		dev_err(dev, "Unable to get regs %d\n", ret);
+		return ret;
+	}
+
+	lvds->pclk = devm_clk_get(dev, "pclk");
+	if (IS_ERR(lvds->pclk)) {
+		ret = PTR_ERR(lvds->pclk);
+		dev_err(dev, "Unable to get peripheral clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(lvds->pclk);
+	if (ret) {
+		dev_err(dev, "%s: Failed to enable peripheral clk\n", __func__);
+		return ret;
+	}
+
+	rstc = devm_reset_control_get_exclusive(dev, NULL);
+
+	if (IS_ERR(rstc)) {
+		ret = PTR_ERR(rstc);
+		goto err_lvds_probe;
+	}
+
+	reset_control_assert(rstc);
+	usleep_range(10, 20);
+	reset_control_deassert(rstc);
+
+	port1 = of_graph_get_port_by_id(dev->of_node, 1);
+	port2 = of_graph_get_port_by_id(dev->of_node, 2);
+	dual_link = drm_of_lvds_get_dual_link_pixel_order(port1, port2);
+
+	switch (dual_link) {
+	case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
+		lvds->link_type = LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
+		lvds->primary = &lvds_phy_16ff_primary;
+		lvds->secondary = &lvds_phy_16ff_secondary;
+		break;
+	case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
+		lvds->link_type = LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
+		lvds->primary = &lvds_phy_16ff_primary;
+		lvds->secondary = &lvds_phy_16ff_secondary;
+		break;
+	case -EINVAL:
+		/*
+		 * drm_of_lvds_get_dual_pixel_order returns 4 possible values.
+		 * In the case where the returned value is an error, it can be
+		 * either ENODEV or EINVAL. Seeing the structure of this
+		 * function, EINVAL means that either port1 or port2 is not
+		 * present in the device tree.
+		 * In that case, the lvds panel can be a single link panel, or
+		 * there is a semantical error in the device tree code.
+		 */
+		remote = of_get_next_available_child(port1, NULL);
+		if (remote) {
+			if (of_graph_get_remote_endpoint(remote)) {
+				lvds->link_type = LVDS_SINGLE_LINK_PRIMARY;
+				lvds->primary = &lvds_phy_16ff_primary;
+				lvds->secondary = NULL;
+			} else {
+				ret = -EINVAL;
+			}
+
+			of_node_put(remote);
+		}
+
+		remote = of_get_next_available_child(port2, NULL);
+		if (remote) {
+			if (of_graph_get_remote_endpoint(remote)) {
+				lvds->link_type = LVDS_SINGLE_LINK_SECONDARY;
+				lvds->primary = NULL;
+				lvds->secondary = &lvds_phy_16ff_secondary;
+			} else {
+				ret = (ret == -EINVAL) ? -EINVAL : 0;
+			}
+
+			of_node_put(remote);
+		}
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_lvds_probe;
+	}
+	of_node_put(port1);
+	of_node_put(port2);
+
+	lvds->pllref_clk = devm_clk_get(dev, "ref");
+	if (IS_ERR(lvds->pllref_clk)) {
+		ret = PTR_ERR(lvds->pllref_clk);
+		dev_err(dev, "Unable to get reference clock: %d\n", ret);
+		goto err_lvds_probe;
+	}
+
+	ret = lvds_pixel_clk_register(lvds);
+	if (ret) {
+		dev_err(dev, "Failed to register LVDS pixel clock: %d\n", ret);
+		goto err_lvds_probe;
+	}
+
+	lvds->lvds_bridge.funcs = &lvds_bridge_funcs;
+	lvds->lvds_bridge.of_node = dev->of_node;
+	lvds->hw_version = lvds_read(lvds, LVDS_VERR);
+
+	dev_info(dev, "version 0x%02x initialized\n", lvds->hw_version);
+
+	drm_bridge_add(&lvds->lvds_bridge);
+
+	platform_set_drvdata(pdev, lvds);
+
+	clk_disable_unprepare(lvds->pclk);
+
+	return 0;
+
+err_lvds_probe:
+	clk_disable_unprepare(lvds->pclk);
+
+	return ret;
+}
+
+static int lvds_remove(struct platform_device *pdev)
+{
+	struct stm_lvds *lvds = platform_get_drvdata(pdev);
+
+	lvds_pixel_clk_unregister(lvds);
+
+	drm_bridge_remove(&lvds->lvds_bridge);
+
+	return 0;
+}
+
+static const struct of_device_id lvds_dt_ids[] = {
+	{
+		.compatible = "st,stm32mp25-lvds",
+		.data = NULL
+	},
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, lvds_dt_ids);
+
+static struct platform_driver lvds_platform_driver = {
+	.probe = lvds_probe,
+	.remove = lvds_remove,
+	.driver = {
+		.name = "stm32-display-lvds",
+		.owner = THIS_MODULE,
+		.of_match_table = lvds_dt_ids,
+	},
+};
+
+module_platform_driver(lvds_platform_driver);
+
+MODULE_AUTHOR("Rapha?l Gallais-Pou <raphael.gallais-pou at foss.st.com>");
+MODULE_AUTHOR("Philippe Cornu <philippe.cornu at foss.st.com>");
+MODULE_AUTHOR("Yannick Fertre <yannick.fertre at foss.st.com>");
+MODULE_DESCRIPTION("STMicroelectronics LVDS Display Interface Transmitter DRM driver");
+MODULE_LICENSE("GPL");

-- 
2.25.1



From francesco at dolcini.it  Mon Feb 26 02:54:35 2024
From: francesco at dolcini.it (Francesco Dolcini)
Date: Mon, 26 Feb 2024 11:54:35 +0100
Subject: [PATCH v4] clk: keystone: sci-clk: Adding support for non
 contiguous clocks
In-Reply-To: <20240213082640.457316-1-u-kumar1@ti.com>
References: <20240213082640.457316-1-u-kumar1@ti.com>
Message-ID: <20240226105435.GA11908@francesco-nb>

On Tue, Feb 13, 2024 at 01:56:40PM +0530, Udit Kumar wrote:
> Most of clocks and their parents are defined in contiguous range,
> But in few cases, there is gap in clock numbers[0].
> Driver assumes clocks to be in contiguous range, and add their clock
> ids incrementally.
> 
> New firmware started returning error while calling get_freq and is_on
> API for non-available clock ids.

Is this the kind of errors I should expect in such situation?

ti-sci-clk 44043000.system-controller:clock-controller: recalc-rate failed for dev=13, clk=7, ret=-19

If this is the case, I feel like this patch should be back-ported to
stable kernels.

Any malfunction because of these errors or just some noise in the logs?

Francesco



From mark.rutland at arm.com  Mon Feb 26 03:04:46 2024
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 26 Feb 2024 11:04:46 +0000
Subject: [PATCH] arm64/hw_breakpoint: Determine lengths from generic perf
 breakpoint macros
In-Reply-To: <1901fadb-1d71-4374-be8c-00935bb27854@arm.com>
References: <20240223113102.4027779-1-anshuman.khandual@arm.com>
 <20240223125224.GC10641@willie-the-truck>
 <1901fadb-1d71-4374-be8c-00935bb27854@arm.com>
Message-ID: <ZdxwTkUALQfqjagf@FVFF77S0Q05N>

On Mon, Feb 26, 2024 at 08:19:39AM +0530, Anshuman Khandual wrote:
> On 2/23/24 18:22, Will Deacon wrote:
> > On Fri, Feb 23, 2024 at 05:01:02PM +0530, Anshuman Khandual wrote:
> >> Both platform i.e ARM_BREAKPOINT_LEN_X and generic i.e HW_BREAKPOINT_LEN_X
> >> macros are used interchangeably to convert event->attr.bp_len and platform
> >> breakpoint control arch_hw_breakpoint_ctrl->len. Let's be consistent while
> >> deriving one from the other. This does not cause any functional changes.
> >>
> >> Cc: Will Deacon <will at kernel.org>
> >> Cc: Mark Rutland <mark.rutland at arm.com>
> >> Cc: Catalin Marinas <catalin.marinas 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 v6.8-rc5
> >>
> >>  arch/arm64/kernel/hw_breakpoint.c | 16 ++++++++--------
> >>  1 file changed, 8 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
> >> index 35225632d70a..1ab9fc865ddd 100644
> >> --- a/arch/arm64/kernel/hw_breakpoint.c
> >> +++ b/arch/arm64/kernel/hw_breakpoint.c
> >> @@ -301,28 +301,28 @@ static int get_hbp_len(u8 hbp_len)
> >>  
> >>  	switch (hbp_len) {
> >>  	case ARM_BREAKPOINT_LEN_1:
> >> -		len_in_bytes = 1;
> >> +		len_in_bytes = HW_BREAKPOINT_LEN_1;
> > 
> > I don't think we should do this. The HW_BREAKPOINT_LEN_* definitions are
> > part of the user ABI and, although they correspond to the length in bytes,
> > that's not necessarily something we should rely on.
> 
> Why should not we rely on the user ABI macros if these byte lengths were
> initially derived from them. 

Why should we change the clear:
	
	len_in_bytes = 1;

... to the longer, and less clear:

	len_in_bytes = HW_BREAKPOINT_LEN_1;

... ?

> But also there are similar conversions in arch_bp_generic_fields().

Those are specifically for converting from the rch_hw_breakpoint_ctrl encodings
to the perf_event_attr encodings. There we don't care about the specific value
of the byte, just that we're using the correct encoding.

> These hard coded raw byte length numbers seems cryptic, where as in reality
> these are just inter converted from generic HW breakpoints lengths.

There are three distinct concepts here:

1. The length in bytes, as returned above by get_hbp_len()

2. The length as encoded in the ARM_BREAKPOINT_LEN_* encoding

3. The length as encoded in the HW_BREAKPOINT_LEN_* encoding.

I think you're arguing that since 1 and 3 happen to have the values we should
treat them as the same thing. I think that Will and I believe that they should
be kept distinct because they are distinct concepts.

I don't think this needs to change, and can be left as-is.

Mark.


From hch at infradead.org  Mon Feb 26 03:06:11 2024
From: hch at infradead.org (Christoph Hellwig)
Date: Mon, 26 Feb 2024 03:06:11 -0800
Subject: [PATCH v17 19/35] arch/mm: Export direct {un,}map functions
In-Reply-To: <20240223071006483-0800.eberman@hu-eberman-lv.qualcomm.com>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
 <20240222-gunyah-v17-19-1e9da6763d38@quicinc.com>
 <ZdhEtH7xzbzdhS2j@infradead.org>
 <20240223071006483-0800.eberman@hu-eberman-lv.qualcomm.com>
Message-ID: <Zdxwo0abvklfam-Z@infradead.org>

The point is that we can't we just allow modules to unmap data from
the kernel mapping, no matter how noble your intentions are.



From jpanis at baylibre.com  Mon Feb 26 03:07:13 2024
From: jpanis at baylibre.com (Julien Panis)
Date: Mon, 26 Feb 2024 12:07:13 +0100
Subject: [PATCH v2 01/14] mfd: tps6594: Add register definitions for TI
 TPS65224 PMIC
In-Reply-To: <20240223093701.66034-2-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
 <20240223093701.66034-2-bhargav.r@ltts.com>
Message-ID: <6d82dca4-3ffe-4c51-9f74-cd6cfbac7f7a@baylibre.com>

Hi Bhargav.

Thanks for the series.

On 2/23/24 10:36, Bhargav Raviprakash wrote:
> From: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
>
> Extend TPS6594 PMIC register and field definitions to support TPS65224
> power management IC.
>
> TPS65224 is software compatible to TPS6594 and can re-use many of the
> same definitions, new definitions are added to support additional
> controls available on TPS65224.
>
> Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi at ltts.com>
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> ---
>   include/linux/mfd/tps6594.h | 354 ++++++++++++++++++++++++++++++++++--
>   1 file changed, 342 insertions(+), 12 deletions(-)

[...]
> +/* IRQs */
> +enum tps65224_irqs {
> +	/* INT_BUCK register */
> +	TPS65224_IRQ_BUCK1_UVOV,
> +	TPS65224_IRQ_BUCK2_UVOV,
> +	TPS65224_IRQ_BUCK3_UVOV,
> +	TPS65224_IRQ_BUCK4_UVOV,
> +	/* INT_LDO_VMON register */
> +	TPS65224_IRQ_LDO1_UVOV,
> +	TPS65224_IRQ_LDO2_UVOV,
> +	TPS65224_IRQ_LDO3_UVOV,
> +	TPS65224_IRQ_VCCA_UVOV,
> +	TPS65224_IRQ_VMON1_UVOV,
> +	TPS65224_IRQ_VMON2_UVOV,
> +	/* INT_GPIO register */
> +	TPS65224_IRQ_GPIO1,
> +	TPS65224_IRQ_GPIO2,
> +	TPS65224_IRQ_GPIO3,
> +	TPS65224_IRQ_GPIO4,
> +	TPS65224_IRQ_GPIO5,
> +	TPS65224_IRQ_GPIO6,
> +	/* INT_STARTUP register */
> +	TPS65224_IRQ_VSENSE,
> +	TPS65224_IRQ_ENABLE,
> +	TPS65224_IRQ_PB_SHORT,
> +	TPS65224_IRQ_FSD,
> +	TPS65224_IRQ_SOFT_REBOOT,
> +	/* INT_MISC register */
> +	TPS65224_IRQ_BIST_PASS,
> +	TPS65224_IRQ_EXT_CLK,
> +	TPS65224_IRQ_REG_UNLOCK,
> +	TPS65224_IRQ_TWARN,
> +	TPS65224_IRQ_PB_LONG,
> +	TPS65224_IRQ_PB_FALL,
> +	TPS65224_IRQ_PB_RISE,
> +	TPS65224_IRQ_ADC_CONV_READY,
> +	/* INT_MODERATE_ERR register */
> +	TPS65224_IRQ_TSD_ORD,
> +	TPS65224_IRQ_BIST_FAIL,
> +	TPS65224_IRQ_REG_CRC_ERR,
> +	TPS65224_IRQ_RECOV_CNT,
> +	/* INT_SEVERE_ERR register */
> +	TPS65224_IRQ_TSD_IMM,
> +	TPS65224_IRQ_VCCA_OVP,
> +	TPS65224_IRQ_PFSM_ERR,
> +	TPS65224_IRQ_BG_XMON,
> +	/* INT_FSM_ERR register */
> +	TPS65224_IRQ_IMM_SHUTDOWN,
> +	TPS65224_IRQ_ORD_SHUTDOWN,
> +	TPS65224_IRQ_MCU_PWR_ERR,
> +	TPS65224_IRQ_SOC_PWR_ERR,
> +	TPS65224_IRQ_COMM_ERR,
> +	TPS65224_IRQ_I2C2_ERR,
> +	/* INT_ESM register */
> +	TPS65224_IRQ_ESM_MCU_PIN,
> +	TPS65224_IRQ_ESM_MCU_FAIL,
> +	TPS65224_IRQ_ESM_MCU_RST,
> +};

For tps6594, ESM_MCU interrupts were supposed to be cleared by the MCU FW. That's why we only had to 
deal with ESM_SOC interrupts in linux. For tps65224, I would recommend double-checking with TI where 
ESM_MCU interrupts should be handled (either in MCU FW or in the linux driver). For some reason this 
might be different than tps6594's case, but it does not look very consistent to me at first sight. 
Julien Panis


From jpanis at baylibre.com  Mon Feb 26 03:15:03 2024
From: jpanis at baylibre.com (Julien Panis)
Date: Mon, 26 Feb 2024 12:15:03 +0100
Subject: [PATCH v2 02/14] mfd: tps6594: use volatile_table instead of
 volatile_reg
In-Reply-To: <20240223093701.66034-3-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
 <20240223093701.66034-3-bhargav.r@ltts.com>
Message-ID: <cc6db3bb-c5c7-45ca-bd75-819887791e16@baylibre.com>

On 2/23/24 10:36, Bhargav Raviprakash wrote:
> In regmap_config use volatile_table instead of volatile_reg.
> This change makes it easier to add support for TPS65224 PMIC.
>
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> ---
>   drivers/mfd/tps6594-core.c  | 16 ++++++++++------
>   drivers/mfd/tps6594-i2c.c   |  2 +-
>   drivers/mfd/tps6594-spi.c   |  2 +-
>   include/linux/mfd/tps6594.h |  4 +++-
>   4 files changed, 15 insertions(+), 9 deletions(-)

Acked-by: Julien Panis <jpanis at baylibre.com>



From angelogioacchino.delregno at collabora.com  Mon Feb 26 03:16:10 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 12:16:10 +0100
Subject: [PATCH v3 1/2] clk: mediatek: Introduce need_pm_runtime to
 mtk_clk_desc
In-Reply-To: <CAGXv+5EnBt+7WrNb-QyziEaCihvjhFVf2tpzk=XyAoeELqucaw@mail.gmail.com>
References: <20240108081834.408403-1-treapking@chromium.org>
 <CAGXv+5EnBt+7WrNb-QyziEaCihvjhFVf2tpzk=XyAoeELqucaw@mail.gmail.com>
Message-ID: <e0e6febf-1045-49f8-a200-8bc095b0fa50@collabora.com>

Il 23/02/24 05:27, Chen-Yu Tsai ha scritto:
> On Mon, Jan 8, 2024 at 4:18?PM Pin-yen Lin <treapking at chromium.org> wrote:
>>
>> Introduce a new need_pm_runtime variable to mtk_clk_desc to indicate
>> this clock controller needs runtime PM for its operations.
>> Also do a runtime PM get on the clock controller during the
>> probing stage to workaround a possible deadlock.
>>
>> Signed-off-by: Pin-yen Lin <treapking at chromium.org>
> 
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
> 
> The patch itself looks fine.
> 
> Besides the MT8183 MFG clock issues, we do actually need this for the
> MT8192 ADSP clock. Its power domain is not enabled by default.
> 

...but on MT8195 the ADSP clock works - because the ADSP node exists.

This poses a question: should we make clock controllers depend on power domains,
or should we keep everything powered off (hence clocks down - no power consumption)
*unless* the user exists?

For the second one, this means that the *device* gets the power domain (adsp), and
not the clock controller (which clocks are effectively useless if there's no user).

Angelo

>> ---
>>
>> Changes in v3:
>> - Update the commit message and the comments before runtime PM call
>>
>> Changes in v2:
>> - Fix the order of error handling
>> - Update the commit message and add a comment before the runtime PM call
>>
>>   drivers/clk/mediatek/clk-mtk.c | 19 +++++++++++++++++++
>>   drivers/clk/mediatek/clk-mtk.h |  2 ++
>>   2 files changed, 21 insertions(+)
>>
>> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
>> index 2e55368dc4d8..ba1d1c495bc2 100644
>> --- a/drivers/clk/mediatek/clk-mtk.c
>> +++ b/drivers/clk/mediatek/clk-mtk.c
>> @@ -13,6 +13,7 @@
>>   #include <linux/of.h>
>>   #include <linux/of_address.h>
>>   #include <linux/platform_device.h>
>> +#include <linux/pm_runtime.h>
>>   #include <linux/slab.h>
>>
>>   #include "clk-mtk.h"
>> @@ -494,6 +495,18 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
>>                          return IS_ERR(base) ? PTR_ERR(base) : -ENOMEM;
>>          }
>>
>> +
>> +       if (mcd->need_runtime_pm) {
>> +               devm_pm_runtime_enable(&pdev->dev);
>> +               /*
>> +                * Do a pm_runtime_resume_and_get() to workaround a possible
>> +                * deadlock between clk_register() and the genpd framework.
>> +                */
>> +               r = pm_runtime_resume_and_get(&pdev->dev);
>> +               if (r)
>> +                       return r;
>> +       }
>> +
>>          /* Calculate how many clk_hw_onecell_data entries to allocate */
>>          num_clks = mcd->num_clks + mcd->num_composite_clks;
>>          num_clks += mcd->num_fixed_clks + mcd->num_factor_clks;
>> @@ -574,6 +587,9 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
>>                          goto unregister_clks;
>>          }
>>
>> +       if (mcd->need_runtime_pm)
>> +               pm_runtime_put(&pdev->dev);
>> +
>>          return r;
>>
>>   unregister_clks:
>> @@ -604,6 +620,9 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
>>   free_base:
>>          if (mcd->shared_io && base)
>>                  iounmap(base);
>> +
>> +       if (mcd->need_runtime_pm)
>> +               pm_runtime_put(&pdev->dev);
>>          return r;
>>   }
>>
>> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
>> index 22096501a60a..c17fe1c2d732 100644
>> --- a/drivers/clk/mediatek/clk-mtk.h
>> +++ b/drivers/clk/mediatek/clk-mtk.h
>> @@ -237,6 +237,8 @@ struct mtk_clk_desc {
>>
>>          int (*clk_notifier_func)(struct device *dev, struct clk *clk);
>>          unsigned int mfg_clk_idx;
>> +
>> +       bool need_runtime_pm;
>>   };
>>
>>   int mtk_clk_pdev_probe(struct platform_device *pdev);
>> --
>> 2.43.0.472.g3155946c3a-goog
>>





From daniel.lezcano at linaro.org  Mon Feb 26 03:18:59 2024
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 26 Feb 2024 12:18:59 +0100
Subject: [PATCH v3 0/3] clocksource/drivers/arm_global_timer: Three
 improvements
In-Reply-To: <20240225151336.2728533-1-martin.blumenstingl@googlemail.com>
References: <20240225151336.2728533-1-martin.blumenstingl@googlemail.com>
Message-ID: <2a017b4d-f437-4752-975e-632b0293061e@linaro.org>

On 25/02/2024 16:13, Martin Blumenstingl wrote:
> These are three improvements / fixes for the arm_global_timer driver.
> 
> Changes from v2 at [1]:
> - add patches 1 and 2 (which is why this is now a series instead of a
>    single patch) as in the code review process more issues have been
>    spotted that need fixing
> - remove "psv < 0" check from patch 3 (as this check is now impossible
>    as patch 2 makes the variable in question an unsigned long with a
>    check for zero and returning before decrementing psv).
> 
> Changes from v1 at [0]:
> - use FIELD_FIT() to check whether psv overflows the register
> - update the description accordingly

Applied, thanks for the improvements


-- 
<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 fshao at chromium.org  Mon Feb 26 03:31:42 2024
From: fshao at chromium.org (Fei Shao)
Date: Mon, 26 Feb 2024 19:31:42 +0800
Subject: [PATCH] drm/mediatek: Support MT8195 OVL compatible in mtk_drm_drv
In-Reply-To: <20240226080721.3331649-1-fshao@chromium.org>
References: <20240226080721.3331649-1-fshao@chromium.org>
Message-ID: <CAC=S1niCFgbNjbnHmUD46N-9gSagYuExeQ+nUHvKOvNbS-jz1A@mail.gmail.com>

On Mon, Feb 26, 2024 at 4:07?PM Fei Shao <fshao at chromium.org> wrote:
>
> Specify the component type for mediatek,mt8195-disp-ovl in the MediaTek
> DRM driver on top of commit 76cdcb87d391 ("drm/mediatek: Add MT8195 ovl
> driver support").
>
> With this, the compatible can function as an independent fallback for
> other display overlays without relying on MT8192.
>
> Signed-off-by: Fei Shao <fshao at chromium.org>

Please disregard this patch.

With the feedback in [1], I can also fix the issue from within the
SoC's device tree.
Even taking a step back, I just learned that this is a duplicate of
[2], so it makes no sense to merge mine in any case.
Sorry for the noise.

[1]: https://lore.kernel.org/all/c4814e25-42c9-4604-b86a-8ef0bd634f78 at collabora.com/
[2]: https://lore.kernel.org/all/20240215101119.12629-3-shawn.sung at mediatek.com/

Regards,
Fei


From james.clark at arm.com  Mon Feb 26 03:30:28 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 26 Feb 2024 11:30:28 +0000
Subject: [PATCH v6 0/8] kvm/coresight: Support exclude guest and exclude host
Message-ID: <20240226113044.228403-1-james.clark@arm.com>

This is a combination of the RFC for nVHE here [1] and v3 of VHE version
here [2]. After a few of the review comments it seemed much simpler for
both versions to use the same interface and be in the same patchset.

FEAT_TRF is a Coresight feature that allows trace capture to be
completely filtered at different exception levels, unlike the existing
TRCVICTLR controls which may still emit target addresses of branches,
even if the following trace is filtered.

Without FEAT_TRF, it was possible to start a trace session on a host and
also collect trace from the guest as TRCVICTLR was never programmed to
exclude guests (and it could still emit target addresses even if it
was).

With FEAT_TRF, the current behavior of trace in guests exists depends on
whether nVHE or VHE are being used. Both of the examples below are from
the host's point of view, as Coresight isn't accessible from guests.
This patchset is only relevant to when FEAT_TRF exists, otherwise there
is no change.

  nVHE/pKVM:

  Because the host and the guest are both using TRFCR_EL1, trace will be
  generated in guests depending on the same filter rules the host is
  using. For example if the host is tracing userspace only, then guest
  userspace trace will also be collected.

  (This is further limited by whether TRBE is used because an issue
  with TRBE means that it's completely disabled in nVHE guests, but it's
  possible to have other tracing components.)

  VHE:

  With VHE, the host filters will be in TRFCR_EL2, but the filters in
  TRFCR_EL1 will be active when the guest is running. Because we don't
  write to TRFCR_EL1, guest trace will be completely disabled.

With this change, the guest filtering rules from the Perf session are
now honored for both nVHE and VHE modes. This is done by either writing
to TRFCR_EL12 at the start of the Perf session and doing nothing else
further, or caching the guest value and writing it at guest switch for
nVHE. In pKVM, trace is now be disabled for both protected and
unprotected guests.

---

Changes since V5 [4]:
  * Sort new sysreg entries by encoding
  * Add a comment about sorting arch/arm64/tools/sysreg
  * Warn on preemptible() before calling smp_processor_id()
  * Pickup tags
  * Change TRFCR_EL2 from SysregFields to Sysreg because it was only
    used once

Changes since V4 [3]:
  * Remove all V3 changes that made it work in pKVM and just disable
    trace there instead
  * Restore PMU host/hyp state sharing back to how it was
    (kvm_pmu_update_vcpu_events())
  * Simplify some of the duplication in the comments and function docs
  * Add a WARN_ON_ONCE() if kvm_etm_set_guest_trfcr() is called when
    the trace filtering feature doesn't exist.
  * Split sysreg change into a tools update followed by the new register
    addition

Changes since V3:
  * Create a new shared area to store the host state instead of copying
    it before each VCPU run
  * Drop commit that moved SPE and trace registers from host_debug_state
    into the kvm sysregs array because the guest values were never used 
  * Document kvm_etm_set_guest_trfcr()
  * Guard kvm_etm_set_guest_trfcr() with a feature check
  * Drop Mark B and Suzuki's review tags on the sysreg patch because it
    turned out that broke the Perf build and needed some unconventional
    changes to fix it (as in: to update the tools copy of the headers in
    the same commit as the kernel changes)

Changes since V2:

  * Add a new iflag to signify presence of FEAT_TRF and keep the
    existing TRBE iflag. This fixes the issue where TRBLIMITR_EL1 was
    being accessed even if TRBE didn't exist
  * Reword a commit message

Changes since V1:

  * Squashed all the arm64/tools/sysreg changes into the first commit
  * Add a new commit to move SPE and TRBE regs into the kvm sysreg array
  * Add a comment above the TRFCR global that it's per host CPU rather
    than vcpu

Changes since nVHE RFC [1]:

 * Re-write just in terms of the register value to be written for the
   host and the guest. This removes some logic from the hyp code and
   a value of kvm_vcpu_arch:trfcr_el1 = 0 no longer means "don't
   restore".
 * Remove all the conditional compilation and new files.
 * Change the kvm_etm_update_vcpu_events macro to a function.
 * Re-use DEBUG_STATE_SAVE_TRFCR so iflags don't need to be expanded
   anymore.
 * Expand the cover letter.

Changes since VHE v3 [2]:

 * Use the same interface as nVHE mode so TRFCR_EL12 is now written by
   kvm.

[1]: https://lore.kernel.org/kvmarm/20230804101317.460697-1-james.clark at arm.com/
[2]: https://lore.kernel.org/kvmarm/20230905102117.2011094-1-james.clark at arm.com/
[3]: https://lore.kernel.org/linux-arm-kernel/20240104162714.1062610-1-james.clark at arm.com/
[4]: https://lore.kernel.org/all/20240220100924.2761706-1-james.clark at arm.com/

James Clark (8):
  arm64: KVM: Fix renamed function in comment
  arm64/sysreg: Add a comment that the sysreg file should be sorted
  tools: arm64: Update sysreg.h header files
  arm64/sysreg/tools: Move TRFCR definitions to sysreg
  arm64: KVM: Add iflag for FEAT_TRF
  arm64: KVM: Add interface to set guest value for TRFCR register
  arm64: KVM: Write TRFCR value on guest switch with nVHE
  coresight: Pass guest TRFCR value to KVM

 arch/arm64/include/asm/kvm_host.h             |   7 +-
 arch/arm64/include/asm/sysreg.h               |  12 -
 arch/arm64/kernel/image-vars.h                |   1 +
 arch/arm64/kvm/debug.c                        |  53 ++-
 arch/arm64/kvm/hyp/nvhe/debug-sr.c            |  53 ++-
 arch/arm64/kvm/hyp/nvhe/setup.c               |   2 +-
 arch/arm64/tools/sysreg                       |  38 ++
 .../coresight/coresight-etm4x-core.c          |  42 +-
 drivers/hwtracing/coresight/coresight-etm4x.h |   2 +-
 drivers/hwtracing/coresight/coresight-priv.h  |   3 +
 tools/arch/arm64/include/asm/sysreg.h         | 375 +++++++++++++++++-
 tools/include/linux/kasan-tags.h              |  15 +
 12 files changed, 541 insertions(+), 62 deletions(-)
 create mode 100644 tools/include/linux/kasan-tags.h

-- 
2.34.1



From james.clark at arm.com  Mon Feb 26 03:30:29 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 26 Feb 2024 11:30:29 +0000
Subject: [PATCH v6 1/8] arm64: KVM: Fix renamed function in comment
In-Reply-To: <20240226113044.228403-1-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
Message-ID: <20240226113044.228403-2-james.clark@arm.com>

finalize_host_mappings() became fix_host_ownership() in
commit 0d16d12eb26e ("KVM: arm64: Fix-up hyp stage-1 refcounts for all
pages mapped at EL2") so update the comment.

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/kvm/hyp/nvhe/setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index 9fdcf5484dfe..f0ee75bd6ac3 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -147,7 +147,7 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 	 * can't be donated or shared with another entity.
 	 *
 	 * The ownership transition requires matching changes in the host
-	 * stage-2. This will be done later (see finalize_host_mappings()) once
+	 * stage-2. This will be done later (see fix_host_ownership()) once
 	 * the hyp_vmemmap is addressable.
 	 */
 	prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED);
-- 
2.34.1



From james.clark at arm.com  Mon Feb 26 03:30:30 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 26 Feb 2024 11:30:30 +0000
Subject: [PATCH v6 2/8] arm64/sysreg: Add a comment that the sysreg file should be sorted
In-Reply-To: <20240226113044.228403-1-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
Message-ID: <20240226113044.228403-3-james.clark@arm.com>

There are a few entries particularly at the end of the file that aren't
in order. To avoid confusion, add a comment that might help new entries
to be added in the right place.

Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/tools/sysreg | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index fa3fe0856880..a84c19c111fa 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -48,6 +48,8 @@
 # feature that introduces them (eg, FEAT_LS64_ACCDATA introduces enumeration
 # item ACCDATA) though it may be more taseful to do something else.
 
+# Please try to keep entries in this file sorted by sysreg encoding.
+
 Sysreg	OSDTRRX_EL1	2	0	0	0	2
 Res0	63:32
 Field	31:0	DTRRX
-- 
2.34.1



From james.clark at arm.com  Mon Feb 26 03:30:31 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 26 Feb 2024 11:30:31 +0000
Subject: [PATCH v6 3/8] tools: arm64: Update sysreg.h header files
In-Reply-To: <20240226113044.228403-1-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
Message-ID: <20240226113044.228403-4-james.clark@arm.com>

Created with the following:

  cp include/linux/kasan-tags.h tools/include/linux/
  cp arch/arm64/include/asm/sysreg.h tools/arch/arm64/include/asm/

Update the tools copy of sysreg.h so that the next commit to add a new
register doesn't have unrelated changes in it. Because the new version
of sysreg.h includes kasan-tags.h, that file also now needs to be copied
into tools.

Acked-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/arch/arm64/include/asm/sysreg.h | 363 +++++++++++++++++++++++++-
 tools/include/linux/kasan-tags.h      |  15 ++
 2 files changed, 375 insertions(+), 3 deletions(-)
 create mode 100644 tools/include/linux/kasan-tags.h

diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index ccc13e991376..9e8999592f3a 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -11,6 +11,7 @@
 
 #include <linux/bits.h>
 #include <linux/stringify.h>
+#include <linux/kasan-tags.h>
 
 #include <asm/gpr-num.h>
 
@@ -123,6 +124,37 @@
 #define SYS_DC_CIGSW			sys_insn(1, 0, 7, 14, 4)
 #define SYS_DC_CIGDSW			sys_insn(1, 0, 7, 14, 6)
 
+#define SYS_IC_IALLUIS			sys_insn(1, 0, 7, 1, 0)
+#define SYS_IC_IALLU			sys_insn(1, 0, 7, 5, 0)
+#define SYS_IC_IVAU			sys_insn(1, 3, 7, 5, 1)
+
+#define SYS_DC_IVAC			sys_insn(1, 0, 7, 6, 1)
+#define SYS_DC_IGVAC			sys_insn(1, 0, 7, 6, 3)
+#define SYS_DC_IGDVAC			sys_insn(1, 0, 7, 6, 5)
+
+#define SYS_DC_CVAC			sys_insn(1, 3, 7, 10, 1)
+#define SYS_DC_CGVAC			sys_insn(1, 3, 7, 10, 3)
+#define SYS_DC_CGDVAC			sys_insn(1, 3, 7, 10, 5)
+
+#define SYS_DC_CVAU			sys_insn(1, 3, 7, 11, 1)
+
+#define SYS_DC_CVAP			sys_insn(1, 3, 7, 12, 1)
+#define SYS_DC_CGVAP			sys_insn(1, 3, 7, 12, 3)
+#define SYS_DC_CGDVAP			sys_insn(1, 3, 7, 12, 5)
+
+#define SYS_DC_CVADP			sys_insn(1, 3, 7, 13, 1)
+#define SYS_DC_CGVADP			sys_insn(1, 3, 7, 13, 3)
+#define SYS_DC_CGDVADP			sys_insn(1, 3, 7, 13, 5)
+
+#define SYS_DC_CIVAC			sys_insn(1, 3, 7, 14, 1)
+#define SYS_DC_CIGVAC			sys_insn(1, 3, 7, 14, 3)
+#define SYS_DC_CIGDVAC			sys_insn(1, 3, 7, 14, 5)
+
+/* Data cache zero operations */
+#define SYS_DC_ZVA			sys_insn(1, 3, 7, 4, 1)
+#define SYS_DC_GVA			sys_insn(1, 3, 7, 4, 3)
+#define SYS_DC_GZVA			sys_insn(1, 3, 7, 4, 4)
+
 /*
  * Automatically generated definitions for system registers, the
  * manual encodings below are in the process of being converted to
@@ -162,6 +194,84 @@
 #define SYS_DBGDTRTX_EL0		sys_reg(2, 3, 0, 5, 0)
 #define SYS_DBGVCR32_EL2		sys_reg(2, 4, 0, 7, 0)
 
+#define SYS_BRBINF_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 0))
+#define SYS_BRBINFINJ_EL1		sys_reg(2, 1, 9, 1, 0)
+#define SYS_BRBSRC_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 1))
+#define SYS_BRBSRCINJ_EL1		sys_reg(2, 1, 9, 1, 1)
+#define SYS_BRBTGT_EL1(n)		sys_reg(2, 1, 8, (n & 15), (((n & 16) >> 2) | 2))
+#define SYS_BRBTGTINJ_EL1		sys_reg(2, 1, 9, 1, 2)
+#define SYS_BRBTS_EL1			sys_reg(2, 1, 9, 0, 2)
+
+#define SYS_BRBCR_EL1			sys_reg(2, 1, 9, 0, 0)
+#define SYS_BRBFCR_EL1			sys_reg(2, 1, 9, 0, 1)
+#define SYS_BRBIDR0_EL1			sys_reg(2, 1, 9, 2, 0)
+
+#define SYS_TRCITECR_EL1		sys_reg(3, 0, 1, 2, 3)
+#define SYS_TRCACATR(m)			sys_reg(2, 1, 2, ((m & 7) << 1), (2 | (m >> 3)))
+#define SYS_TRCACVR(m)			sys_reg(2, 1, 2, ((m & 7) << 1), (0 | (m >> 3)))
+#define SYS_TRCAUTHSTATUS		sys_reg(2, 1, 7, 14, 6)
+#define SYS_TRCAUXCTLR			sys_reg(2, 1, 0, 6, 0)
+#define SYS_TRCBBCTLR			sys_reg(2, 1, 0, 15, 0)
+#define SYS_TRCCCCTLR			sys_reg(2, 1, 0, 14, 0)
+#define SYS_TRCCIDCCTLR0		sys_reg(2, 1, 3, 0, 2)
+#define SYS_TRCCIDCCTLR1		sys_reg(2, 1, 3, 1, 2)
+#define SYS_TRCCIDCVR(m)		sys_reg(2, 1, 3, ((m & 7) << 1), 0)
+#define SYS_TRCCLAIMCLR			sys_reg(2, 1, 7, 9, 6)
+#define SYS_TRCCLAIMSET			sys_reg(2, 1, 7, 8, 6)
+#define SYS_TRCCNTCTLR(m)		sys_reg(2, 1, 0, (4 | (m & 3)), 5)
+#define SYS_TRCCNTRLDVR(m)		sys_reg(2, 1, 0, (0 | (m & 3)), 5)
+#define SYS_TRCCNTVR(m)			sys_reg(2, 1, 0, (8 | (m & 3)), 5)
+#define SYS_TRCCONFIGR			sys_reg(2, 1, 0, 4, 0)
+#define SYS_TRCDEVARCH			sys_reg(2, 1, 7, 15, 6)
+#define SYS_TRCDEVID			sys_reg(2, 1, 7, 2, 7)
+#define SYS_TRCEVENTCTL0R		sys_reg(2, 1, 0, 8, 0)
+#define SYS_TRCEVENTCTL1R		sys_reg(2, 1, 0, 9, 0)
+#define SYS_TRCEXTINSELR(m)		sys_reg(2, 1, 0, (8 | (m & 3)), 4)
+#define SYS_TRCIDR0			sys_reg(2, 1, 0, 8, 7)
+#define SYS_TRCIDR10			sys_reg(2, 1, 0, 2, 6)
+#define SYS_TRCIDR11			sys_reg(2, 1, 0, 3, 6)
+#define SYS_TRCIDR12			sys_reg(2, 1, 0, 4, 6)
+#define SYS_TRCIDR13			sys_reg(2, 1, 0, 5, 6)
+#define SYS_TRCIDR1			sys_reg(2, 1, 0, 9, 7)
+#define SYS_TRCIDR2			sys_reg(2, 1, 0, 10, 7)
+#define SYS_TRCIDR3			sys_reg(2, 1, 0, 11, 7)
+#define SYS_TRCIDR4			sys_reg(2, 1, 0, 12, 7)
+#define SYS_TRCIDR5			sys_reg(2, 1, 0, 13, 7)
+#define SYS_TRCIDR6			sys_reg(2, 1, 0, 14, 7)
+#define SYS_TRCIDR7			sys_reg(2, 1, 0, 15, 7)
+#define SYS_TRCIDR8			sys_reg(2, 1, 0, 0, 6)
+#define SYS_TRCIDR9			sys_reg(2, 1, 0, 1, 6)
+#define SYS_TRCIMSPEC(m)		sys_reg(2, 1, 0, (m & 7), 7)
+#define SYS_TRCITEEDCR			sys_reg(2, 1, 0, 2, 1)
+#define SYS_TRCOSLSR			sys_reg(2, 1, 1, 1, 4)
+#define SYS_TRCPRGCTLR			sys_reg(2, 1, 0, 1, 0)
+#define SYS_TRCQCTLR			sys_reg(2, 1, 0, 1, 1)
+#define SYS_TRCRSCTLR(m)		sys_reg(2, 1, 1, (m & 15), (0 | (m >> 4)))
+#define SYS_TRCRSR			sys_reg(2, 1, 0, 10, 0)
+#define SYS_TRCSEQEVR(m)		sys_reg(2, 1, 0, (m & 3), 4)
+#define SYS_TRCSEQRSTEVR		sys_reg(2, 1, 0, 6, 4)
+#define SYS_TRCSEQSTR			sys_reg(2, 1, 0, 7, 4)
+#define SYS_TRCSSCCR(m)			sys_reg(2, 1, 1, (m & 7), 2)
+#define SYS_TRCSSCSR(m)			sys_reg(2, 1, 1, (8 | (m & 7)), 2)
+#define SYS_TRCSSPCICR(m)		sys_reg(2, 1, 1, (m & 7), 3)
+#define SYS_TRCSTALLCTLR		sys_reg(2, 1, 0, 11, 0)
+#define SYS_TRCSTATR			sys_reg(2, 1, 0, 3, 0)
+#define SYS_TRCSYNCPR			sys_reg(2, 1, 0, 13, 0)
+#define SYS_TRCTRACEIDR			sys_reg(2, 1, 0, 0, 1)
+#define SYS_TRCTSCTLR			sys_reg(2, 1, 0, 12, 0)
+#define SYS_TRCVICTLR			sys_reg(2, 1, 0, 0, 2)
+#define SYS_TRCVIIECTLR			sys_reg(2, 1, 0, 1, 2)
+#define SYS_TRCVIPCSSCTLR		sys_reg(2, 1, 0, 3, 2)
+#define SYS_TRCVISSCTLR			sys_reg(2, 1, 0, 2, 2)
+#define SYS_TRCVMIDCCTLR0		sys_reg(2, 1, 3, 2, 2)
+#define SYS_TRCVMIDCCTLR1		sys_reg(2, 1, 3, 3, 2)
+#define SYS_TRCVMIDCVR(m)		sys_reg(2, 1, 3, ((m & 7) << 1), 1)
+
+/* ETM */
+#define SYS_TRCOSLAR			sys_reg(2, 1, 1, 0, 4)
+
+#define SYS_BRBCR_EL2			sys_reg(2, 4, 9, 0, 0)
+
 #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)
@@ -202,8 +312,13 @@
 #define SYS_ERXCTLR_EL1			sys_reg(3, 0, 5, 4, 1)
 #define SYS_ERXSTATUS_EL1		sys_reg(3, 0, 5, 4, 2)
 #define SYS_ERXADDR_EL1			sys_reg(3, 0, 5, 4, 3)
+#define SYS_ERXPFGF_EL1			sys_reg(3, 0, 5, 4, 4)
+#define SYS_ERXPFGCTL_EL1		sys_reg(3, 0, 5, 4, 5)
+#define SYS_ERXPFGCDN_EL1		sys_reg(3, 0, 5, 4, 6)
 #define SYS_ERXMISC0_EL1		sys_reg(3, 0, 5, 5, 0)
 #define SYS_ERXMISC1_EL1		sys_reg(3, 0, 5, 5, 1)
+#define SYS_ERXMISC2_EL1		sys_reg(3, 0, 5, 5, 2)
+#define SYS_ERXMISC3_EL1		sys_reg(3, 0, 5, 5, 3)
 #define SYS_TFSR_EL1			sys_reg(3, 0, 5, 6, 0)
 #define SYS_TFSRE0_EL1			sys_reg(3, 0, 5, 6, 1)
 
@@ -274,6 +389,8 @@
 #define SYS_ICC_IGRPEN0_EL1		sys_reg(3, 0, 12, 12, 6)
 #define SYS_ICC_IGRPEN1_EL1		sys_reg(3, 0, 12, 12, 7)
 
+#define SYS_ACCDATA_EL1			sys_reg(3, 0, 13, 0, 5)
+
 #define SYS_CNTKCTL_EL1			sys_reg(3, 0, 14, 1, 0)
 
 #define SYS_AIDR_EL1			sys_reg(3, 1, 0, 0, 7)
@@ -369,6 +486,7 @@
 
 #define SYS_SCTLR_EL2			sys_reg(3, 4, 1, 0, 0)
 #define SYS_ACTLR_EL2			sys_reg(3, 4, 1, 0, 1)
+#define SYS_SCTLR2_EL2			sys_reg(3, 4, 1, 0, 3)
 #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)
@@ -382,12 +500,15 @@
 #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
 
 #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
-#define SYS_HDFGRTR_EL2			sys_reg(3, 4, 3, 1, 4)
-#define SYS_HDFGWTR_EL2			sys_reg(3, 4, 3, 1, 5)
+#define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
 #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_SPSR_irq			sys_reg(3, 4, 4, 3, 0)
+#define SYS_SPSR_abt			sys_reg(3, 4, 4, 3, 1)
+#define SYS_SPSR_und			sys_reg(3, 4, 4, 3, 2)
+#define SYS_SPSR_fiq			sys_reg(3, 4, 4, 3, 3)
 #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)
@@ -401,6 +522,18 @@
 
 #define SYS_MAIR_EL2			sys_reg(3, 4, 10, 2, 0)
 #define SYS_AMAIR_EL2			sys_reg(3, 4, 10, 3, 0)
+#define SYS_MPAMHCR_EL2			sys_reg(3, 4, 10, 4, 0)
+#define SYS_MPAMVPMV_EL2		sys_reg(3, 4, 10, 4, 1)
+#define SYS_MPAM2_EL2			sys_reg(3, 4, 10, 5, 0)
+#define __SYS__MPAMVPMx_EL2(x)		sys_reg(3, 4, 10, 6, x)
+#define SYS_MPAMVPM0_EL2		__SYS__MPAMVPMx_EL2(0)
+#define SYS_MPAMVPM1_EL2		__SYS__MPAMVPMx_EL2(1)
+#define SYS_MPAMVPM2_EL2		__SYS__MPAMVPMx_EL2(2)
+#define SYS_MPAMVPM3_EL2		__SYS__MPAMVPMx_EL2(3)
+#define SYS_MPAMVPM4_EL2		__SYS__MPAMVPMx_EL2(4)
+#define SYS_MPAMVPM5_EL2		__SYS__MPAMVPMx_EL2(5)
+#define SYS_MPAMVPM6_EL2		__SYS__MPAMVPMx_EL2(6)
+#define SYS_MPAMVPM7_EL2		__SYS__MPAMVPMx_EL2(7)
 
 #define SYS_VBAR_EL2			sys_reg(3, 4, 12, 0, 0)
 #define SYS_RVBAR_EL2			sys_reg(3, 4, 12, 0, 1)
@@ -449,24 +582,49 @@
 
 #define SYS_CONTEXTIDR_EL2		sys_reg(3, 4, 13, 0, 1)
 #define SYS_TPIDR_EL2			sys_reg(3, 4, 13, 0, 2)
+#define SYS_SCXTNUM_EL2			sys_reg(3, 4, 13, 0, 7)
+
+#define __AMEV_op2(m)			(m & 0x7)
+#define __AMEV_CRm(n, m)		(n | ((m & 0x8) >> 3))
+#define __SYS__AMEVCNTVOFF0n_EL2(m)	sys_reg(3, 4, 13, __AMEV_CRm(0x8, m), __AMEV_op2(m))
+#define SYS_AMEVCNTVOFF0n_EL2(m)	__SYS__AMEVCNTVOFF0n_EL2(m)
+#define __SYS__AMEVCNTVOFF1n_EL2(m)	sys_reg(3, 4, 13, __AMEV_CRm(0xA, m), __AMEV_op2(m))
+#define SYS_AMEVCNTVOFF1n_EL2(m)	__SYS__AMEVCNTVOFF1n_EL2(m)
 
 #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_BRBCR_EL12			sys_reg(2, 5, 9, 0, 0)
 #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
+#define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
+#define SYS_SCTLR2_EL12			sys_reg(3, 5, 1, 0, 3)
+#define SYS_ZCR_EL12			sys_reg(3, 5, 1, 2, 0)
+#define SYS_TRFCR_EL12			sys_reg(3, 5, 1, 2, 1)
+#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)
+#define SYS_TCR2_EL12			sys_reg(3, 5, 2, 0, 3)
 #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)
 #define SYS_TFSR_EL12			sys_reg(3, 5, 5, 6, 0)
+#define SYS_FAR_EL12			sys_reg(3, 5, 6, 0, 0)
+#define SYS_PMSCR_EL12			sys_reg(3, 5, 9, 9, 0)
 #define SYS_MAIR_EL12			sys_reg(3, 5, 10, 2, 0)
 #define SYS_AMAIR_EL12			sys_reg(3, 5, 10, 3, 0)
 #define SYS_VBAR_EL12			sys_reg(3, 5, 12, 0, 0)
+#define SYS_CONTEXTIDR_EL12		sys_reg(3, 5, 13, 0, 1)
+#define SYS_SCXTNUM_EL12		sys_reg(3, 5, 13, 0, 7)
 #define SYS_CNTKCTL_EL12		sys_reg(3, 5, 14, 1, 0)
 #define SYS_CNTP_TVAL_EL02		sys_reg(3, 5, 14, 2, 0)
 #define SYS_CNTP_CTL_EL02		sys_reg(3, 5, 14, 2, 1)
@@ -477,6 +635,165 @@
 
 #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_S1E1A	sys_insn(AT_Op0, 0, AT_CRn, 9, 2)
+#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)
+
+/* TLBI instructions */
+#define OP_TLBI_VMALLE1OS		sys_insn(1, 0, 8, 1, 0)
+#define OP_TLBI_VAE1OS			sys_insn(1, 0, 8, 1, 1)
+#define OP_TLBI_ASIDE1OS		sys_insn(1, 0, 8, 1, 2)
+#define OP_TLBI_VAAE1OS			sys_insn(1, 0, 8, 1, 3)
+#define OP_TLBI_VALE1OS			sys_insn(1, 0, 8, 1, 5)
+#define OP_TLBI_VAALE1OS		sys_insn(1, 0, 8, 1, 7)
+#define OP_TLBI_RVAE1IS			sys_insn(1, 0, 8, 2, 1)
+#define OP_TLBI_RVAAE1IS		sys_insn(1, 0, 8, 2, 3)
+#define OP_TLBI_RVALE1IS		sys_insn(1, 0, 8, 2, 5)
+#define OP_TLBI_RVAALE1IS		sys_insn(1, 0, 8, 2, 7)
+#define OP_TLBI_VMALLE1IS		sys_insn(1, 0, 8, 3, 0)
+#define OP_TLBI_VAE1IS			sys_insn(1, 0, 8, 3, 1)
+#define OP_TLBI_ASIDE1IS		sys_insn(1, 0, 8, 3, 2)
+#define OP_TLBI_VAAE1IS			sys_insn(1, 0, 8, 3, 3)
+#define OP_TLBI_VALE1IS			sys_insn(1, 0, 8, 3, 5)
+#define OP_TLBI_VAALE1IS		sys_insn(1, 0, 8, 3, 7)
+#define OP_TLBI_RVAE1OS			sys_insn(1, 0, 8, 5, 1)
+#define OP_TLBI_RVAAE1OS		sys_insn(1, 0, 8, 5, 3)
+#define OP_TLBI_RVALE1OS		sys_insn(1, 0, 8, 5, 5)
+#define OP_TLBI_RVAALE1OS		sys_insn(1, 0, 8, 5, 7)
+#define OP_TLBI_RVAE1			sys_insn(1, 0, 8, 6, 1)
+#define OP_TLBI_RVAAE1			sys_insn(1, 0, 8, 6, 3)
+#define OP_TLBI_RVALE1			sys_insn(1, 0, 8, 6, 5)
+#define OP_TLBI_RVAALE1			sys_insn(1, 0, 8, 6, 7)
+#define OP_TLBI_VMALLE1			sys_insn(1, 0, 8, 7, 0)
+#define OP_TLBI_VAE1			sys_insn(1, 0, 8, 7, 1)
+#define OP_TLBI_ASIDE1			sys_insn(1, 0, 8, 7, 2)
+#define OP_TLBI_VAAE1			sys_insn(1, 0, 8, 7, 3)
+#define OP_TLBI_VALE1			sys_insn(1, 0, 8, 7, 5)
+#define OP_TLBI_VAALE1			sys_insn(1, 0, 8, 7, 7)
+#define OP_TLBI_VMALLE1OSNXS		sys_insn(1, 0, 9, 1, 0)
+#define OP_TLBI_VAE1OSNXS		sys_insn(1, 0, 9, 1, 1)
+#define OP_TLBI_ASIDE1OSNXS		sys_insn(1, 0, 9, 1, 2)
+#define OP_TLBI_VAAE1OSNXS		sys_insn(1, 0, 9, 1, 3)
+#define OP_TLBI_VALE1OSNXS		sys_insn(1, 0, 9, 1, 5)
+#define OP_TLBI_VAALE1OSNXS		sys_insn(1, 0, 9, 1, 7)
+#define OP_TLBI_RVAE1ISNXS		sys_insn(1, 0, 9, 2, 1)
+#define OP_TLBI_RVAAE1ISNXS		sys_insn(1, 0, 9, 2, 3)
+#define OP_TLBI_RVALE1ISNXS		sys_insn(1, 0, 9, 2, 5)
+#define OP_TLBI_RVAALE1ISNXS		sys_insn(1, 0, 9, 2, 7)
+#define OP_TLBI_VMALLE1ISNXS		sys_insn(1, 0, 9, 3, 0)
+#define OP_TLBI_VAE1ISNXS		sys_insn(1, 0, 9, 3, 1)
+#define OP_TLBI_ASIDE1ISNXS		sys_insn(1, 0, 9, 3, 2)
+#define OP_TLBI_VAAE1ISNXS		sys_insn(1, 0, 9, 3, 3)
+#define OP_TLBI_VALE1ISNXS		sys_insn(1, 0, 9, 3, 5)
+#define OP_TLBI_VAALE1ISNXS		sys_insn(1, 0, 9, 3, 7)
+#define OP_TLBI_RVAE1OSNXS		sys_insn(1, 0, 9, 5, 1)
+#define OP_TLBI_RVAAE1OSNXS		sys_insn(1, 0, 9, 5, 3)
+#define OP_TLBI_RVALE1OSNXS		sys_insn(1, 0, 9, 5, 5)
+#define OP_TLBI_RVAALE1OSNXS		sys_insn(1, 0, 9, 5, 7)
+#define OP_TLBI_RVAE1NXS		sys_insn(1, 0, 9, 6, 1)
+#define OP_TLBI_RVAAE1NXS		sys_insn(1, 0, 9, 6, 3)
+#define OP_TLBI_RVALE1NXS		sys_insn(1, 0, 9, 6, 5)
+#define OP_TLBI_RVAALE1NXS		sys_insn(1, 0, 9, 6, 7)
+#define OP_TLBI_VMALLE1NXS		sys_insn(1, 0, 9, 7, 0)
+#define OP_TLBI_VAE1NXS			sys_insn(1, 0, 9, 7, 1)
+#define OP_TLBI_ASIDE1NXS		sys_insn(1, 0, 9, 7, 2)
+#define OP_TLBI_VAAE1NXS		sys_insn(1, 0, 9, 7, 3)
+#define OP_TLBI_VALE1NXS		sys_insn(1, 0, 9, 7, 5)
+#define OP_TLBI_VAALE1NXS		sys_insn(1, 0, 9, 7, 7)
+#define OP_TLBI_IPAS2E1IS		sys_insn(1, 4, 8, 0, 1)
+#define OP_TLBI_RIPAS2E1IS		sys_insn(1, 4, 8, 0, 2)
+#define OP_TLBI_IPAS2LE1IS		sys_insn(1, 4, 8, 0, 5)
+#define OP_TLBI_RIPAS2LE1IS		sys_insn(1, 4, 8, 0, 6)
+#define OP_TLBI_ALLE2OS			sys_insn(1, 4, 8, 1, 0)
+#define OP_TLBI_VAE2OS			sys_insn(1, 4, 8, 1, 1)
+#define OP_TLBI_ALLE1OS			sys_insn(1, 4, 8, 1, 4)
+#define OP_TLBI_VALE2OS			sys_insn(1, 4, 8, 1, 5)
+#define OP_TLBI_VMALLS12E1OS		sys_insn(1, 4, 8, 1, 6)
+#define OP_TLBI_RVAE2IS			sys_insn(1, 4, 8, 2, 1)
+#define OP_TLBI_RVALE2IS		sys_insn(1, 4, 8, 2, 5)
+#define OP_TLBI_ALLE2IS			sys_insn(1, 4, 8, 3, 0)
+#define OP_TLBI_VAE2IS			sys_insn(1, 4, 8, 3, 1)
+#define OP_TLBI_ALLE1IS			sys_insn(1, 4, 8, 3, 4)
+#define OP_TLBI_VALE2IS			sys_insn(1, 4, 8, 3, 5)
+#define OP_TLBI_VMALLS12E1IS		sys_insn(1, 4, 8, 3, 6)
+#define OP_TLBI_IPAS2E1OS		sys_insn(1, 4, 8, 4, 0)
+#define OP_TLBI_IPAS2E1			sys_insn(1, 4, 8, 4, 1)
+#define OP_TLBI_RIPAS2E1		sys_insn(1, 4, 8, 4, 2)
+#define OP_TLBI_RIPAS2E1OS		sys_insn(1, 4, 8, 4, 3)
+#define OP_TLBI_IPAS2LE1OS		sys_insn(1, 4, 8, 4, 4)
+#define OP_TLBI_IPAS2LE1		sys_insn(1, 4, 8, 4, 5)
+#define OP_TLBI_RIPAS2LE1		sys_insn(1, 4, 8, 4, 6)
+#define OP_TLBI_RIPAS2LE1OS		sys_insn(1, 4, 8, 4, 7)
+#define OP_TLBI_RVAE2OS			sys_insn(1, 4, 8, 5, 1)
+#define OP_TLBI_RVALE2OS		sys_insn(1, 4, 8, 5, 5)
+#define OP_TLBI_RVAE2			sys_insn(1, 4, 8, 6, 1)
+#define OP_TLBI_RVALE2			sys_insn(1, 4, 8, 6, 5)
+#define OP_TLBI_ALLE2			sys_insn(1, 4, 8, 7, 0)
+#define OP_TLBI_VAE2			sys_insn(1, 4, 8, 7, 1)
+#define OP_TLBI_ALLE1			sys_insn(1, 4, 8, 7, 4)
+#define OP_TLBI_VALE2			sys_insn(1, 4, 8, 7, 5)
+#define OP_TLBI_VMALLS12E1		sys_insn(1, 4, 8, 7, 6)
+#define OP_TLBI_IPAS2E1ISNXS		sys_insn(1, 4, 9, 0, 1)
+#define OP_TLBI_RIPAS2E1ISNXS		sys_insn(1, 4, 9, 0, 2)
+#define OP_TLBI_IPAS2LE1ISNXS		sys_insn(1, 4, 9, 0, 5)
+#define OP_TLBI_RIPAS2LE1ISNXS		sys_insn(1, 4, 9, 0, 6)
+#define OP_TLBI_ALLE2OSNXS		sys_insn(1, 4, 9, 1, 0)
+#define OP_TLBI_VAE2OSNXS		sys_insn(1, 4, 9, 1, 1)
+#define OP_TLBI_ALLE1OSNXS		sys_insn(1, 4, 9, 1, 4)
+#define OP_TLBI_VALE2OSNXS		sys_insn(1, 4, 9, 1, 5)
+#define OP_TLBI_VMALLS12E1OSNXS		sys_insn(1, 4, 9, 1, 6)
+#define OP_TLBI_RVAE2ISNXS		sys_insn(1, 4, 9, 2, 1)
+#define OP_TLBI_RVALE2ISNXS		sys_insn(1, 4, 9, 2, 5)
+#define OP_TLBI_ALLE2ISNXS		sys_insn(1, 4, 9, 3, 0)
+#define OP_TLBI_VAE2ISNXS		sys_insn(1, 4, 9, 3, 1)
+#define OP_TLBI_ALLE1ISNXS		sys_insn(1, 4, 9, 3, 4)
+#define OP_TLBI_VALE2ISNXS		sys_insn(1, 4, 9, 3, 5)
+#define OP_TLBI_VMALLS12E1ISNXS		sys_insn(1, 4, 9, 3, 6)
+#define OP_TLBI_IPAS2E1OSNXS		sys_insn(1, 4, 9, 4, 0)
+#define OP_TLBI_IPAS2E1NXS		sys_insn(1, 4, 9, 4, 1)
+#define OP_TLBI_RIPAS2E1NXS		sys_insn(1, 4, 9, 4, 2)
+#define OP_TLBI_RIPAS2E1OSNXS		sys_insn(1, 4, 9, 4, 3)
+#define OP_TLBI_IPAS2LE1OSNXS		sys_insn(1, 4, 9, 4, 4)
+#define OP_TLBI_IPAS2LE1NXS		sys_insn(1, 4, 9, 4, 5)
+#define OP_TLBI_RIPAS2LE1NXS		sys_insn(1, 4, 9, 4, 6)
+#define OP_TLBI_RIPAS2LE1OSNXS		sys_insn(1, 4, 9, 4, 7)
+#define OP_TLBI_RVAE2OSNXS		sys_insn(1, 4, 9, 5, 1)
+#define OP_TLBI_RVALE2OSNXS		sys_insn(1, 4, 9, 5, 5)
+#define OP_TLBI_RVAE2NXS		sys_insn(1, 4, 9, 6, 1)
+#define OP_TLBI_RVALE2NXS		sys_insn(1, 4, 9, 6, 5)
+#define OP_TLBI_ALLE2NXS		sys_insn(1, 4, 9, 7, 0)
+#define OP_TLBI_VAE2NXS			sys_insn(1, 4, 9, 7, 1)
+#define OP_TLBI_ALLE1NXS		sys_insn(1, 4, 9, 7, 4)
+#define OP_TLBI_VALE2NXS		sys_insn(1, 4, 9, 7, 5)
+#define OP_TLBI_VMALLS12E1NXS		sys_insn(1, 4, 9, 7, 6)
+
+/* Misc instructions */
+#define OP_GCSPUSHX			sys_insn(1, 0, 7, 7, 4)
+#define OP_GCSPOPCX			sys_insn(1, 0, 7, 7, 5)
+#define OP_GCSPOPX			sys_insn(1, 0, 7, 7, 6)
+#define OP_GCSPUSHM			sys_insn(1, 3, 7, 7, 0)
+
+#define OP_BRB_IALL			sys_insn(1, 1, 7, 2, 4)
+#define OP_BRB_INJ			sys_insn(1, 1, 7, 2, 5)
+#define OP_CFP_RCTX			sys_insn(1, 3, 7, 3, 4)
+#define OP_DVP_RCTX			sys_insn(1, 3, 7, 3, 5)
+#define OP_COSP_RCTX			sys_insn(1, 3, 7, 3, 6)
+#define OP_CPP_RCTX			sys_insn(1, 3, 7, 3, 7)
+
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_ENTP2	(BIT(60))
 #define SCTLR_ELx_DSSBS	(BIT(44))
@@ -561,10 +878,12 @@
 
 /* id_aa64mmfr0 */
 #define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN	0x0
+#define ID_AA64MMFR0_EL1_TGRAN4_LPA2		ID_AA64MMFR0_EL1_TGRAN4_52_BIT
 #define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MAX	0x7
 #define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED_MIN	0x0
 #define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED_MAX	0x7
 #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MIN	0x1
+#define ID_AA64MMFR0_EL1_TGRAN16_LPA2		ID_AA64MMFR0_EL1_TGRAN16_52_BIT
 #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MAX	0xf
 
 #define ARM64_MIN_PARANGE_BITS		32
@@ -572,6 +891,7 @@
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_DEFAULT	0x0
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_NONE		0x1
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MIN		0x2
+#define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2		0x3
 #define ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX		0x7
 
 #ifdef CONFIG_ARM64_PA_BITS_52
@@ -582,11 +902,13 @@
 
 #if defined(CONFIG_ARM64_4K_PAGES)
 #define ID_AA64MMFR0_EL1_TGRAN_SHIFT		ID_AA64MMFR0_EL1_TGRAN4_SHIFT
+#define ID_AA64MMFR0_EL1_TGRAN_LPA2		ID_AA64MMFR0_EL1_TGRAN4_52_BIT
 #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN
 #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX	ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MAX
 #define ID_AA64MMFR0_EL1_TGRAN_2_SHIFT		ID_AA64MMFR0_EL1_TGRAN4_2_SHIFT
 #elif defined(CONFIG_ARM64_16K_PAGES)
 #define ID_AA64MMFR0_EL1_TGRAN_SHIFT		ID_AA64MMFR0_EL1_TGRAN16_SHIFT
+#define ID_AA64MMFR0_EL1_TGRAN_LPA2		ID_AA64MMFR0_EL1_TGRAN16_52_BIT
 #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MIN
 #define ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX	ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED_MAX
 #define ID_AA64MMFR0_EL1_TGRAN_2_SHIFT		ID_AA64MMFR0_EL1_TGRAN16_2_SHIFT
@@ -610,6 +932,19 @@
 #define SYS_GCR_EL1_RRND	(BIT(16))
 #define SYS_GCR_EL1_EXCL_MASK	0xffffUL
 
+#ifdef CONFIG_KASAN_HW_TAGS
+/*
+ * KASAN always uses a whole byte for its tags. With CONFIG_KASAN_HW_TAGS it
+ * only uses tags in the range 0xF0-0xFF, which we map to MTE tags 0x0-0xF.
+ */
+#define __MTE_TAG_MIN		(KASAN_TAG_MIN & 0xf)
+#define __MTE_TAG_MAX		(KASAN_TAG_MAX & 0xf)
+#define __MTE_TAG_INCL		GENMASK(__MTE_TAG_MAX, __MTE_TAG_MIN)
+#define KERNEL_GCR_EL1_EXCL	(SYS_GCR_EL1_EXCL_MASK & ~__MTE_TAG_INCL)
+#else
+#define KERNEL_GCR_EL1_EXCL	SYS_GCR_EL1_EXCL_MASK
+#endif
+
 #define KERNEL_GCR_EL1		(SYS_GCR_EL1_RRND | KERNEL_GCR_EL1_EXCL)
 
 /* RGSR_EL1 Definitions */
@@ -716,6 +1051,19 @@
 
 #define PIRx_ELx_PERM(idx, perm)	((perm) << ((idx) * 4))
 
+/*
+ * Permission Overlay Extension (POE) permission encodings.
+ */
+#define POE_NONE	UL(0x0)
+#define POE_R		UL(0x1)
+#define POE_X		UL(0x2)
+#define POE_RX		UL(0x3)
+#define POE_W		UL(0x4)
+#define POE_RW		UL(0x5)
+#define POE_XW		UL(0x6)
+#define POE_RXW		UL(0x7)
+#define POE_MASK	UL(0xf)
+
 #define ARM64_FEATURE_FIELD_BITS	4
 
 /* Defined for compatibility only, do not add new users. */
@@ -789,15 +1137,21 @@
 /*
  * For registers without architectural names, or simply unsupported by
  * GAS.
+ *
+ * __check_r forces warnings to be generated by the compiler when
+ * evaluating r which wouldn't normally happen due to being passed to
+ * the assembler via __stringify(r).
  */
 #define read_sysreg_s(r) ({						\
 	u64 __val;							\
+	u32 __maybe_unused __check_r = (u32)(r);			\
 	asm volatile(__mrs_s("%0", r) : "=r" (__val));			\
 	__val;								\
 })
 
 #define write_sysreg_s(v, r) do {					\
 	u64 __val = (u64)(v);						\
+	u32 __maybe_unused __check_r = (u32)(r);			\
 	asm volatile(__msr_s(r, "%x0") : : "rZ" (__val));		\
 } while (0)
 
@@ -827,6 +1181,8 @@
 	par;								\
 })
 
+#define SYS_FIELD_VALUE(reg, field, val)	reg##_##field##_##val
+
 #define SYS_FIELD_GET(reg, field, val)		\
 		 FIELD_GET(reg##_##field##_MASK, val)
 
@@ -834,7 +1190,8 @@
 		 FIELD_PREP(reg##_##field##_MASK, val)
 
 #define SYS_FIELD_PREP_ENUM(reg, field, val)		\
-		 FIELD_PREP(reg##_##field##_MASK, reg##_##field##_##val)
+		 FIELD_PREP(reg##_##field##_MASK,	\
+			    SYS_FIELD_VALUE(reg, field, val))
 
 #endif
 
diff --git a/tools/include/linux/kasan-tags.h b/tools/include/linux/kasan-tags.h
new file mode 100644
index 000000000000..4f85f562512c
--- /dev/null
+++ b/tools/include/linux/kasan-tags.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_KASAN_TAGS_H
+#define _LINUX_KASAN_TAGS_H
+
+#define KASAN_TAG_KERNEL	0xFF /* native kernel pointers tag */
+#define KASAN_TAG_INVALID	0xFE /* inaccessible memory tag */
+#define KASAN_TAG_MAX		0xFD /* maximum value for random tags */
+
+#ifdef CONFIG_KASAN_HW_TAGS
+#define KASAN_TAG_MIN		0xF0 /* minimum value for random tags */
+#else
+#define KASAN_TAG_MIN		0x00 /* minimum value for random tags */
+#endif
+
+#endif /* LINUX_KASAN_TAGS_H */
-- 
2.34.1



From james.clark at arm.com  Mon Feb 26 03:30:32 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 26 Feb 2024 11:30:32 +0000
Subject: [PATCH v6 4/8] arm64/sysreg/tools: Move TRFCR definitions to sysreg
In-Reply-To: <20240226113044.228403-1-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
Message-ID: <20240226113044.228403-5-james.clark@arm.com>

Convert TRFCR to automatic generation. Add separate definitions for ELx
and EL2 as TRFCR_EL1 doesn't have CX. This also mirrors the previous
definition so no code change is required.

Also add TRFCR_EL12 which will start to be used in a later commit.

Unfortunately, to avoid breaking the Perf build with duplicate
definition errors, the tools copy of the sysreg.h header needs to be
updated at the same time rather than the usual second commit. This is
because the generated version of sysreg
(arch/arm64/include/generated/asm/sysreg-defs.h), is currently shared
and tools/ does not have its own copy.

Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/include/asm/sysreg.h       | 12 ---------
 arch/arm64/tools/sysreg               | 36 +++++++++++++++++++++++++++
 tools/arch/arm64/include/asm/sysreg.h | 12 ---------
 3 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 9e8999592f3a..35890cf3c49f 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -280,8 +280,6 @@
 #define SYS_RGSR_EL1			sys_reg(3, 0, 1, 0, 5)
 #define SYS_GCR_EL1			sys_reg(3, 0, 1, 0, 6)
 
-#define SYS_TRFCR_EL1			sys_reg(3, 0, 1, 2, 1)
-
 #define SYS_TCR_EL1			sys_reg(3, 0, 2, 0, 2)
 
 #define SYS_APIAKEYLO_EL1		sys_reg(3, 0, 2, 1, 0)
@@ -499,7 +497,6 @@
 #define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
 #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
 
-#define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
 #define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
 #define SYS_HAFGRTR_EL2			sys_reg(3, 4, 3, 1, 6)
 #define SYS_SPSR_EL2			sys_reg(3, 4, 4, 0, 0)
@@ -961,15 +958,6 @@
 /* Safe value for MPIDR_EL1: Bit31:RES1, Bit30:U:0, Bit24:MT:0 */
 #define SYS_MPIDR_SAFE_VAL	(BIT(31))
 
-#define TRFCR_ELx_TS_SHIFT		5
-#define TRFCR_ELx_TS_MASK		((0x3UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_VIRTUAL		((0x1UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_GUEST_PHYSICAL	((0x2UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_PHYSICAL		((0x3UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_EL2_CX			BIT(3)
-#define TRFCR_ELx_ExTRE			BIT(1)
-#define TRFCR_ELx_E0TRE			BIT(0)
-
 /* GIC Hypervisor interface registers */
 /* ICH_MISR_EL2 bit definitions */
 #define ICH_MISR_EOI		(1 << 0)
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index a84c19c111fa..af0cf1ce5d03 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1919,6 +1919,22 @@ Sysreg	CPACR_EL1	3	0	1	0	2
 Fields	CPACR_ELx
 EndSysreg
 
+SysregFields TRFCR_ELx
+Res0	63:7
+UnsignedEnum	6:5	TS
+	0b0001	VIRTUAL
+	0b0010	GUEST_PHYSICAL
+	0b0011	PHYSICAL
+EndEnum
+Res0	4:2
+Field	1	ExTRE
+Field	0	E0TRE
+EndSysregFields
+
+Sysreg	TRFCR_EL1	3	0	1	2	1
+Fields	TRFCR_ELx
+EndSysreg
+
 Sysreg	SMPRI_EL1	3	0	1	2	4
 Res0	63:4
 Field	3:0	PRIORITY
@@ -2396,6 +2412,22 @@ Field	1	ICIALLU
 Field	0	ICIALLUIS
 EndSysreg
 
+Sysreg TRFCR_EL2	3	4	1	2	1
+Res0	63:7
+UnsignedEnum	6:5	TS
+	0b0000	USE_TRFCR_EL1_TS
+	0b0001	VIRTUAL
+	0b0010	GUEST_PHYSICAL
+	0b0011	PHYSICAL
+EndEnum
+Res0	4
+Field	3	CX
+Res0	2
+Field	1	E2TRE
+Field	0	E0HTRE
+EndSysreg
+
+
 Sysreg HDFGRTR_EL2	3	4	3	1	4
 Field	63	PMBIDR_EL1
 Field	62	nPMSNEVFR_EL1
@@ -2686,6 +2718,10 @@ Sysreg	ZCR_EL12	3	5	1	2	0
 Fields	ZCR_ELx
 EndSysreg
 
+Sysreg	TRFCR_EL12	3	5	1	2	1
+Fields	TRFCR_ELx
+EndSysreg
+
 Sysreg	SMCR_EL12	3	5	1	2	6
 Fields	SMCR_ELx
 EndSysreg
diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index 9e8999592f3a..35890cf3c49f 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -280,8 +280,6 @@
 #define SYS_RGSR_EL1			sys_reg(3, 0, 1, 0, 5)
 #define SYS_GCR_EL1			sys_reg(3, 0, 1, 0, 6)
 
-#define SYS_TRFCR_EL1			sys_reg(3, 0, 1, 2, 1)
-
 #define SYS_TCR_EL1			sys_reg(3, 0, 2, 0, 2)
 
 #define SYS_APIAKEYLO_EL1		sys_reg(3, 0, 2, 1, 0)
@@ -499,7 +497,6 @@
 #define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
 #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
 
-#define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
 #define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
 #define SYS_HAFGRTR_EL2			sys_reg(3, 4, 3, 1, 6)
 #define SYS_SPSR_EL2			sys_reg(3, 4, 4, 0, 0)
@@ -961,15 +958,6 @@
 /* Safe value for MPIDR_EL1: Bit31:RES1, Bit30:U:0, Bit24:MT:0 */
 #define SYS_MPIDR_SAFE_VAL	(BIT(31))
 
-#define TRFCR_ELx_TS_SHIFT		5
-#define TRFCR_ELx_TS_MASK		((0x3UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_VIRTUAL		((0x1UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_GUEST_PHYSICAL	((0x2UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_PHYSICAL		((0x3UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_EL2_CX			BIT(3)
-#define TRFCR_ELx_ExTRE			BIT(1)
-#define TRFCR_ELx_E0TRE			BIT(0)
-
 /* GIC Hypervisor interface registers */
 /* ICH_MISR_EL2 bit definitions */
 #define ICH_MISR_EOI		(1 << 0)
-- 
2.34.1



From james.clark at arm.com  Mon Feb 26 03:30:33 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 26 Feb 2024 11:30:33 +0000
Subject: [PATCH v6 5/8] arm64: KVM: Add iflag for FEAT_TRF
In-Reply-To: <20240226113044.228403-1-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
Message-ID: <20240226113044.228403-6-james.clark@arm.com>

Add an extra iflag to signify if the TRFCR register is accessible.
Because TRBE requires FEAT_TRF, DEBUG_STATE_SAVE_TRBE still has the same
behavior even though it's only set when FEAT_TRF is present.

The following holes are left in struct kvm_vcpu_arch, but there aren't
enough other 8 bit fields to rearrange it to leave any hole smaller than
7 bytes:

  u8                         cflags;               /*  2292     1 */
  /* XXX 1 byte hole, try to pack */
  u16                        iflags;               /*  2294     2 */
  u8                         sflags;               /*  2296     1 */
  bool                       pause;                /*  2297     1 */
  /* XXX 6 bytes hole, try to pack */

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  4 +++-
 arch/arm64/kvm/debug.c            | 24 ++++++++++++++++++++----
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 21c57b812569..85b5477bd1b4 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -569,7 +569,7 @@ struct kvm_vcpu_arch {
 	u8 cflags;
 
 	/* Input flags to the hypervisor code, potentially cleared after use */
-	u8 iflags;
+	u16 iflags;
 
 	/* State flags for kernel bookkeeping, unused by the hypervisor code */
 	u8 sflags;
@@ -779,6 +779,8 @@ struct kvm_vcpu_arch {
 #define DEBUG_STATE_SAVE_TRBE	__vcpu_single_flag(iflags, BIT(6))
 /* vcpu running in HYP context */
 #define VCPU_HYP_CONTEXT	__vcpu_single_flag(iflags, BIT(7))
+/* Save trace filter controls */
+#define DEBUG_STATE_SAVE_TRFCR	__vcpu_single_flag(iflags, BIT(8))
 
 /* SVE enabled for host EL0 */
 #define HOST_SVE_ENABLED	__vcpu_single_flag(sflags, BIT(0))
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index ce8886122ed3..49a13e72ddd2 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -332,14 +332,30 @@ void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu)
 	    !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(PMBIDR_EL1_P_SHIFT)))
 		vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_SPE);
 
-	/* Check if we have TRBE implemented and available at the host */
-	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) &&
-	    !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P))
-		vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
+	/*
+	 * Set SAVE_TRFCR flag if FEAT_TRF (TraceFilt) exists. This flag
+	 * signifies that the exclude_host/exclude_guest settings of any active
+	 * host Perf session on a core running a VCPU can be written into
+	 * TRFCR_EL1 on guest switch.
+	 */
+	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceFilt_SHIFT)) {
+		vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
+		/*
+		 * Check if we have TRBE implemented and available at the host.
+		 * If it's in use at the time of guest switch then trace will
+		 * need to be completely disabled. The architecture mandates
+		 * FEAT_TRF with TRBE, so we only need to check for TRBE after
+		 * TRF.
+		 */
+		if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) &&
+		    !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P))
+			vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
+	}
 }
 
 void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
 {
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
+	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
 }
-- 
2.34.1



From james.clark at arm.com  Mon Feb 26 03:30:34 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 26 Feb 2024 11:30:34 +0000
Subject: [PATCH v6 6/8] arm64: KVM: Add interface to set guest value for TRFCR register
In-Reply-To: <20240226113044.228403-1-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
Message-ID: <20240226113044.228403-7-james.clark@arm.com>

Add an interface for the Coresight driver to use to set the value of the
TRFCR register for the guest. This register controls the exclude
settings for trace at different exception levels, and is used to honor
the exclude_host and exclude_guest parameters from the Perf session.
This will be used to later write TRFCR_EL1 on nVHE at guest switch. For
VHE, the host trace is controlled by TRFCR_EL2 and thus we can write to
the TRFCR_EL1 immediately. Because guest writes to the register are
trapped, the value will persist and can't be modified.

Instead of adding a load of infrastructure to share the host's per-cpu
offsets with the hypervisor, just define the new storage as a NR_CPUS
array.

Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  3 +++
 arch/arm64/kernel/image-vars.h    |  1 +
 arch/arm64/kvm/debug.c            | 29 +++++++++++++++++++++++++++++
 3 files changed, 33 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 85b5477bd1b4..56b7f7eca195 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -509,6 +509,7 @@ struct kvm_host_psci_config {
 	bool psci_0_1_cpu_off_implemented;
 	bool psci_0_1_migrate_implemented;
 };
+extern u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
 
 extern struct kvm_host_psci_config kvm_nvhe_sym(kvm_host_psci_config);
 #define kvm_host_psci_config CHOOSE_NVHE_SYM(kvm_host_psci_config)
@@ -1174,6 +1175,7 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu);
 void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr);
 void kvm_clr_pmu_events(u32 clr);
 bool kvm_set_pmuserenr(u64 val);
+void kvm_etm_set_guest_trfcr(u64 trfcr_guest);
 #else
 static inline void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) {}
 static inline void kvm_clr_pmu_events(u32 clr) {}
@@ -1181,6 +1183,7 @@ static inline bool kvm_set_pmuserenr(u64 val)
 {
 	return false;
 }
+static inline void kvm_etm_set_guest_trfcr(u64 trfcr_guest) {}
 #endif
 
 void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 31daa1da191c..fe9e2bd7f43a 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -59,6 +59,7 @@ KVM_NVHE_ALIAS(alt_cb_patch_nops);
 
 /* Global kernel state accessed by nVHE hyp code. */
 KVM_NVHE_ALIAS(kvm_vgic_global_state);
+KVM_NVHE_ALIAS(kvm_guest_trfcr);
 
 /* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */
 KVM_NVHE_ALIAS(nvhe_hyp_panic_handler);
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 49a13e72ddd2..fe90bc7d6dd4 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -22,6 +22,7 @@
 				DBG_MDSCR_MDE)
 
 static DEFINE_PER_CPU(u64, mdcr_el2);
+u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
 
 /*
  * save/restore_guest_debug_regs
@@ -359,3 +360,31 @@ void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
 	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
 }
+
+/*
+ * Interface for the Coresight driver to use to set the value of the TRFCR
+ * register for the guest. This register controls the exclude settings for trace
+ * at different exception levels, and is used to honor the exclude_host and
+ * exclude_guest parameters from the Perf session.
+ *
+ * This will be used to later write TRFCR_EL1 on nVHE at guest switch. For VHE,
+ * the host trace is controlled by TRFCR_EL2 and thus we can write to the
+ * TRFCR_EL1 immediately. Because guest writes to the register are trapped, the
+ * value will persist and can't be modified. For pKVM, kvm_guest_trfcr can't
+ * be read by the hypervisor, so don't bother writing it.
+ */
+void kvm_etm_set_guest_trfcr(u64 trfcr_guest)
+{
+	if (WARN_ON_ONCE(!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
+							       ID_AA64DFR0_EL1_TraceFilt_SHIFT)))
+		return;
+
+	/* Warn in invalid use of smp_processor_id() */
+	WARN_ON_ONCE(preemptible());
+
+	if (has_vhe())
+		write_sysreg_s(trfcr_guest, SYS_TRFCR_EL12);
+	else if (!is_protected_kvm_enabled())
+		kvm_guest_trfcr[smp_processor_id()] = trfcr_guest;
+}
+EXPORT_SYMBOL_GPL(kvm_etm_set_guest_trfcr);
-- 
2.34.1



From james.clark at arm.com  Mon Feb 26 03:30:35 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 26 Feb 2024 11:30:35 +0000
Subject: [PATCH v6 7/8] arm64: KVM: Write TRFCR value on guest switch with nVHE
In-Reply-To: <20240226113044.228403-1-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
Message-ID: <20240226113044.228403-8-james.clark@arm.com>

The guest value for TRFCR requested by the Coresight driver is saved in
kvm_guest_trfcr. On guest switch this value needs to be written to
the register. Currently TRFCR is only modified when we want to disable
trace completely in guests due to an issue with TRBE. Expand the
__debug_save_trace() function to always write to the register if a
different value for guests is required, but also keep the existing TRBE
disable behavior if that's required.

In pKVM, the kvm_guest_trfcr can't be read and the host isn't trusted,
so always disable trace.

__debug_restore_trace() now has to restore unconditionally, because even
a value of 0 needs to be written to overwrite whatever was set for the
guest.

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: James Clark <james.clark at arm.com>
---
 arch/arm64/kvm/hyp/nvhe/debug-sr.c | 53 +++++++++++++++++-------------
 1 file changed, 31 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 4558c02eb352..3adac2e01908 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -51,30 +51,39 @@ static void __debug_restore_spe(u64 pmscr_el1)
 	write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
 }
 
-static void __debug_save_trace(u64 *trfcr_el1)
+static void __debug_save_trace(struct kvm_vcpu *vcpu)
 {
-	*trfcr_el1 = 0;
-
-	/* Check if the TRBE is enabled */
-	if (!(read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E))
-		return;
-	/*
-	 * Prohibit trace generation while we are in guest.
-	 * Since access to TRFCR_EL1 is trapped, the guest can't
-	 * modify the filtering set by the host.
-	 */
-	*trfcr_el1 = read_sysreg_s(SYS_TRFCR_EL1);
-	write_sysreg_s(0, SYS_TRFCR_EL1);
-	isb();
-	/* Drain the trace buffer to memory */
-	tsb_csync();
+	u64 host_trfcr_el1 = read_sysreg_s(SYS_TRFCR_EL1);
+	u64 guest_trfcr_el1;
+
+	vcpu->arch.host_debug_state.trfcr_el1 = host_trfcr_el1;
+
+	/* Check if the TRBE buffer or pKVM is enabled */
+	if (is_protected_kvm_enabled() ||
+	    (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE) &&
+	     read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E)) {
+		/*
+		 * Prohibit trace generation while we are in guest. Since access
+		 * to TRFCR_EL1 is trapped, the guest can't modify the filtering
+		 * set by the host.
+		 */
+		write_sysreg_s(0, SYS_TRFCR_EL1);
+		isb();
+		/* Drain the trace buffer to memory */
+		tsb_csync();
+	} else {
+		/*
+		 * Tracing is allowed, apply the filters provided by the
+		 * Coresight driver.
+		 */
+		guest_trfcr_el1 = kvm_guest_trfcr[vcpu->cpu];
+		if (host_trfcr_el1 != guest_trfcr_el1)
+			write_sysreg_s(guest_trfcr_el1, SYS_TRFCR_EL1);
+	}
 }
 
 static void __debug_restore_trace(u64 trfcr_el1)
 {
-	if (!trfcr_el1)
-		return;
-
 	/* Restore trace filter controls */
 	write_sysreg_s(trfcr_el1, SYS_TRFCR_EL1);
 }
@@ -85,8 +94,8 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
 	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE))
 		__debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1);
 	/* Disable and flush Self-Hosted Trace generation */
-	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE))
-		__debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1);
+	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRFCR))
+		__debug_save_trace(vcpu);
 }
 
 void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
@@ -98,7 +107,7 @@ void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu)
 {
 	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE))
 		__debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1);
-	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE))
+	if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRFCR))
 		__debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1);
 }
 
-- 
2.34.1



From james.clark at arm.com  Mon Feb 26 03:30:36 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 26 Feb 2024 11:30:36 +0000
Subject: [PATCH v6 8/8] coresight: Pass guest TRFCR value to KVM
In-Reply-To: <20240226113044.228403-1-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
Message-ID: <20240226113044.228403-9-james.clark@arm.com>

Currently the userspace and kernel filters for guests are never set, so
no trace will be generated for them. Add support for tracing guests by
passing the desired TRFCR value to KVM so it can be applied to the
guest.

By writing either E1TRE or E0TRE, filtering on either guest kernel or
guest userspace is also supported. And if both E1TRE and E0TRE are
cleared when exclude_guest is set, that option is supported too. This
change also brings exclude_host support which is difficult to add as a
separate commit without excess churn and resulting in no trace at all.

Testing
=======

The addresses were counted with the following:

  $ perf report -D | grep -Eo 'EL2|EL1|EL0' | sort | uniq -c

Guest kernel only:

  $ perf record -e cs_etm//Gk -a -- true
    535 EL1
      1 EL2

Guest user only (only 5 addresses because the guest runs slowly in the
model):

  $ perf record -e cs_etm//Gu -a -- true
    5 EL0

Host kernel only:

  $  perf record -e cs_etm//Hk -a -- true
   3501 EL2

Host userspace only:

  $  perf record -e cs_etm//Hu -a -- true
    408 EL0
      1 EL2

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: James Clark <james.clark at arm.com>
---
 .../coresight/coresight-etm4x-core.c          | 42 ++++++++++++++++---
 drivers/hwtracing/coresight/coresight-etm4x.h |  2 +-
 drivers/hwtracing/coresight/coresight-priv.h  |  3 ++
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index ce1995a2827f..45a69bfdc6b5 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -6,6 +6,7 @@
 #include <linux/acpi.h>
 #include <linux/bitops.h>
 #include <linux/kernel.h>
+#include <linux/kvm_host.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -271,9 +272,22 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
 	/* If the CPU doesn't support FEAT_TRF, nothing to do */
 	if (!drvdata->trfcr)
 		return;
+	kvm_etm_set_guest_trfcr(0);
 	cpu_prohibit_trace();
 }
 
+static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
+{
+	u64 trfcr = drvdata->trfcr;
+
+	if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
+		trfcr &= ~TRFCR_ELx_ExTRE;
+	if (drvdata->config.mode & ETM_MODE_EXCL_USER)
+		trfcr &= ~TRFCR_ELx_E0TRE;
+
+	return trfcr;
+}
+
 /*
  * etm4x_allow_trace - Allow CPU tracing in the respective ELs,
  * as configured by the drvdata->config.mode for the current
@@ -286,18 +300,28 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
  */
 static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
 {
-	u64 trfcr = drvdata->trfcr;
+	u64 trfcr;
 
 	/* If the CPU doesn't support FEAT_TRF, nothing to do */
-	if (!trfcr)
+	if (!drvdata->trfcr)
 		return;
 
-	if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
-		trfcr &= ~TRFCR_ELx_ExTRE;
-	if (drvdata->config.mode & ETM_MODE_EXCL_USER)
-		trfcr &= ~TRFCR_ELx_E0TRE;
+	if (drvdata->config.mode & ETM_MODE_EXCL_HOST)
+		trfcr = drvdata->trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE);
+	else
+		trfcr = etm4x_get_kern_user_filter(drvdata);
 
 	write_trfcr(trfcr);
+
+	/* Set filters for guests and pass to KVM */
+	if (drvdata->config.mode & ETM_MODE_EXCL_GUEST)
+		trfcr = drvdata->trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE);
+	else
+		trfcr = etm4x_get_kern_user_filter(drvdata);
+
+	/* TRFCR_EL1 doesn't have CX so mask it out. */
+	trfcr &= ~TRFCR_EL2_CX;
+	kvm_etm_set_guest_trfcr(trfcr);
 }
 
 #ifdef CONFIG_ETM4X_IMPDEF_FEATURE
@@ -655,6 +679,12 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
 	if (attr->exclude_user)
 		config->mode = ETM_MODE_EXCL_USER;
 
+	if (attr->exclude_host)
+		config->mode |= ETM_MODE_EXCL_HOST;
+
+	if (attr->exclude_guest)
+		config->mode |= ETM_MODE_EXCL_GUEST;
+
 	/* Always start from the default config */
 	etm4_set_default_config(config);
 
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index da17b6c49b0f..70c29e91f4b5 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -841,7 +841,7 @@ enum etm_impdef_type {
  * @s_ex_level: Secure ELs where tracing is supported.
  */
 struct etmv4_config {
-	u32				mode;
+	u64				mode;
 	u32				pe_sel;
 	u32				cfg;
 	u32				eventctrl0;
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 767076e07970..727dd27ba800 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -39,6 +39,9 @@
 
 #define ETM_MODE_EXCL_KERN	BIT(30)
 #define ETM_MODE_EXCL_USER	BIT(31)
+#define ETM_MODE_EXCL_HOST	BIT(32)
+#define ETM_MODE_EXCL_GUEST	BIT(33)
+
 struct cs_pair_attribute {
 	struct device_attribute attr;
 	u32 lo_off;
-- 
2.34.1



From christophe.leroy at csgroup.eu  Mon Feb 26 03:34:51 2024
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Mon, 26 Feb 2024 11:34:51 +0000
Subject: [PATCH v10] lib: checksum: Use aligned accesses for ip_fast_csum
 and csum_ipv6_magic tests
In-Reply-To: <20240223-fix_sparse_errors_checksum_tests-v10-1-b6a45914b7d8@rivosinc.com>
References: <20240223-fix_sparse_errors_checksum_tests-v10-1-b6a45914b7d8@rivosinc.com>
Message-ID: <7ae930a7-3b10-4470-94ee-89cb650b3349@csgroup.eu>



Le 23/02/2024 ? 23:11, Charlie Jenkins a ?crit?:
> The test cases for ip_fast_csum and csum_ipv6_magic were not properly
> aligning the IP header, which were causing failures on architectures
> that do not support misaligned accesses like some ARM platforms. To
> solve this, align the data along (14 + NET_IP_ALIGN) bytes which is the
> standard alignment of an IP header and must be supported by the
> architecture.

I'm still wondering what we are really trying to fix here.

All other tests are explicitely testing that it works with any alignment.

Shouldn't ip_fast_csum() and csum_ipv6_magic() work for any alignment as 
well ? I would expect it, I see no comment in arm code which explicits 
that assumption around those functions.

Isn't the problem only the following line, because csum_offset is 
unaligned ?

csum = *(__wsum *)(random_buf + i + csum_offset);

Otherwise, if there really is an alignment issue for the IPv6 source or 
destination address, isn't it enough to perform a 32 bits alignment ?

I guess we should involve ARM people in this discussion.

Christophe

From angelogioacchino.delregno at collabora.com  Mon Feb 26 03:35:11 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 12:35:11 +0100
Subject: [PATCH v3 2/2] clk: mediatek: mt8183: Enable need_runtime_pm on
 mt8183-mfgcfg
In-Reply-To: <CAGXv+5GoAauw77wVXx6SXsSma9zP_A1vXLRo=GH2ptjvY=kLgA@mail.gmail.com>
References: <20240108081834.408403-1-treapking@chromium.org>
 <20240108081834.408403-2-treapking@chromium.org>
 <CAGXv+5GoAauw77wVXx6SXsSma9zP_A1vXLRo=GH2ptjvY=kLgA@mail.gmail.com>
Message-ID: <a22b7703-2ee1-47dd-8933-4a72e64e9fe0@collabora.com>

Il 23/02/24 05:43, Chen-Yu Tsai ha scritto:
> On Mon, Jan 8, 2024 at 4:18?PM Pin-yen Lin <treapking at chromium.org> wrote:
>>
>> mt8183-mfgcfg has a mutual dependency with genpd during the probing
>> stage, so enable need_runtim_pm to prevent a deadlock in the following
>> call stack:
>>
>> CPU0:  genpd_lock --> clk_prepare_lock
>> genpd_power_off_work_fn()
>>   genpd_lock()
>>   generic_pm_domain::power_off()
>>      clk_unprepare()
>>        clk_prepare_lock()
>>
>> CPU1: clk_prepare_lock --> genpd_lock
>> clk_register()
>>    __clk_core_init()
>>      clk_prepare_lock()
>>      clk_pm_runtime_get()
>>        genpd_lock()
>>
>> Do a runtime PM get at the probe function to make sure clk_register()
>> won't acquire the genpd lock.
>>
>> Fixes: acddfc2c261b ("clk: mediatek: Add MT8183 clock support")
>> Signed-off-by: Pin-yen Lin <treapking at chromium.org>
> 
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
> 
> Note that this compliments a patch [1] adding the power domain for the mfgcfg
> clock controller node, which has been floating around for almost 3 years.
> 

...but why does this happen *only* on MT8183 and not on any other MediaTek SoC?

I understand what you're trying to solve here, but if we explore a bit more, we
can maybe come to the conclusion that we don't need to add this flag, and perhaps
just enable PM runtime as regular flow for all clock controllers.

That would also be cleaner, to some extent.

Cheers,
Angelo

> [1] https://lore.kernel.org/linux-mediatek/20210414073108.3899082-1-ikjn at chromium.org/
> 
>> ---
>>
>> (no changes since v1)
>>
>>   drivers/clk/mediatek/clk-mt8183-mfgcfg.c | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
>> index ba504e19d420..62d876e150e1 100644
>> --- a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
>> +++ b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
>> @@ -29,6 +29,7 @@ static const struct mtk_gate mfg_clks[] = {
>>   static const struct mtk_clk_desc mfg_desc = {
>>          .clks = mfg_clks,
>>          .num_clks = ARRAY_SIZE(mfg_clks),
>> +       .need_runtime_pm = true,
>>   };
>>
>>   static const struct of_device_id of_match_clk_mt8183_mfg[] = {
>> --
>> 2.43.0.472.g3155946c3a-goog
>>




From tony at atomide.com  Mon Feb 26 03:35:00 2024
From: tony at atomide.com (Tony Lindgren)
Date: Mon, 26 Feb 2024 13:35:00 +0200
Subject: TI am625 deepsleep wakeup from main domain
In-Reply-To: <CANh8QzwpvC7aJvbdphsiJKNUgETPpoQ5nVJy4+nVy_HV0DYyLA@mail.gmail.com>
References: <CANh8Qzx-aratebzbkYGLiL+ij5MPmvfuzZtu70AL=9JgLjZ8tw@mail.gmail.com>
 <20240219151458.2gvc3n6sjt4nyj25@dhruva>
 <CANh8QzwpvC7aJvbdphsiJKNUgETPpoQ5nVJy4+nVy_HV0DYyLA@mail.gmail.com>
Message-ID: <20240226113500.GW52537@atomide.com>

* Fuzzey, Martin <martin.fuzzey at flowbird.group> [240220 11:09]:
> Hi Dhruva,
> 
> Thank you *very* much for that.
> 
> TLDR: Enabling IO isolation indeed makes it work.

Have you guys also tested with current Linux v6.8-rc6 or Linux next?

The wkup_uart0 change is in Linux next now as is the gpio-keys wakeup
change. Would be nice to see what all is still missing :)

Regards,

Tony


From jpanis at baylibre.com  Mon Feb 26 03:35:28 2024
From: jpanis at baylibre.com (Julien Panis)
Date: Mon, 26 Feb 2024 12:35:28 +0100
Subject: [PATCH v2 03/14] mfd: tps6594: add regmap config in match data
In-Reply-To: <20240223093701.66034-4-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
 <20240223093701.66034-4-bhargav.r@ltts.com>
Message-ID: <2d589f9d-d60f-4fb4-aca9-697798b52ab8@baylibre.com>

On 2/23/24 10:36, Bhargav Raviprakash wrote:
> Introduces a new struct tps6594_match_data. This struct
> holds fields for chip id and regmap config. Using this
> struct in of_device_id data field.
> This helps in adding support for TPS65224 PMIC.
>
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> ---
>   drivers/mfd/tps6594-i2c.c   | 24 ++++++++++++++++--------
>   drivers/mfd/tps6594-spi.c   | 24 ++++++++++++++++--------
>   include/linux/mfd/tps6594.h | 11 +++++++++++
>   3 files changed, 43 insertions(+), 16 deletions(-)

For the next version of the series, you can use more chars for each line
of the commit message (the length is not limited to 56 :-) ). That said,

Acked-by: Julien Panis <jpanis at baylibre.com>



From james.clark at arm.com  Mon Feb 26 03:36:21 2024
From: james.clark at arm.com (James Clark)
Date: Mon, 26 Feb 2024 11:36:21 +0000
Subject: [PATCH v5 5/7] arm64: KVM: Add interface to set guest value for
 TRFCR register
In-Reply-To: <125fe2f0-bd21-462f-893a-fbf80813dfbf@arm.com>
References: <20240220100924.2761706-1-james.clark@arm.com>
 <20240220100924.2761706-6-james.clark@arm.com>
 <c8819064-13c3-41c6-8b2e-779ef8a22ee8@arm.com>
 <9d3f9f70-0b34-7426-8b62-93dc173a0bb2@arm.com>
 <125fe2f0-bd21-462f-893a-fbf80813dfbf@arm.com>
Message-ID: <acb73492-ccb7-5dba-d9d8-7ca096714adc@arm.com>



On 26/02/2024 09:52, Suzuki K Poulose wrote:
> On 23/02/2024 16:39, James Clark wrote:
>>
>>
>> On 23/02/2024 10:03, Suzuki K Poulose wrote:
>>> On 20/02/2024 10:09, James Clark wrote:
>>>> Add an interface for the Coresight driver to use to set the value of
>>>> the
>>>> TRFCR register for the guest. This register controls the exclude
>>>> settings for trace at different exception levels, and is used to honor
>>>> the exclude_host and exclude_guest parameters from the Perf session.
>>>> This will be used to later write TRFCR_EL1 on nVHE at guest switch. For
>>>> VHE, the host trace is controlled by TRFCR_EL2 and thus we can write to
>>>> the TRFCR_EL1 immediately. Because guest writes to the register are
>>>> trapped, the value will persist and can't be modified.
>>>>
>>>> Instead of adding a load of infrastructure to share the host's per-cpu
>>>> offsets with the hypervisor, just define the new storage as a NR_CPUS
>>>> array.
>>>>
>>>> Signed-off-by: James Clark <james.clark at arm.com>
>>>> ---
>>>> ?? arch/arm64/include/asm/kvm_host.h |? 3 +++
>>>> ?? arch/arm64/kernel/image-vars.h??? |? 1 +
>>>> ?? arch/arm64/kvm/debug.c??????????? | 26 ++++++++++++++++++++++++++
>>>> ?? 3 files changed, 30 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/include/asm/kvm_host.h
>>>> b/arch/arm64/include/asm/kvm_host.h
>>>> index 85b5477bd1b4..56b7f7eca195 100644
>>>> --- a/arch/arm64/include/asm/kvm_host.h
>>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>>> @@ -509,6 +509,7 @@ struct kvm_host_psci_config {
>>>> ?????? bool psci_0_1_cpu_off_implemented;
>>>> ?????? bool psci_0_1_migrate_implemented;
>>>> ?? };
>>>> +extern u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
>>>> ?? ? extern struct kvm_host_psci_config
>>>> kvm_nvhe_sym(kvm_host_psci_config);
>>>> ?? #define kvm_host_psci_config CHOOSE_NVHE_SYM(kvm_host_psci_config)
>>>> @@ -1174,6 +1175,7 @@ void kvm_arch_vcpu_put_debug_state_flags(struct
>>>> kvm_vcpu *vcpu);
>>>> ?? void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr);
>>>> ?? void kvm_clr_pmu_events(u32 clr);
>>>> ?? bool kvm_set_pmuserenr(u64 val);
>>>> +void kvm_etm_set_guest_trfcr(u64 trfcr_guest);
>>>> ?? #else
>>>> ?? static inline void kvm_set_pmu_events(u32 set, struct
>>>> perf_event_attr *attr) {}
>>>> ?? static inline void kvm_clr_pmu_events(u32 clr) {}
>>>> @@ -1181,6 +1183,7 @@ static inline bool kvm_set_pmuserenr(u64 val)
>>>> ?? {
>>>> ?????? return false;
>>>> ?? }
>>>> +static inline void kvm_etm_set_guest_trfcr(u64 trfcr_guest) {}
>>>> ?? #endif
>>>> ?? ? void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
>>>> diff --git a/arch/arm64/kernel/image-vars.h
>>>> b/arch/arm64/kernel/image-vars.h
>>>> index 5e4dc72ab1bd..a451e4f10804 100644
>>>> --- a/arch/arm64/kernel/image-vars.h
>>>> +++ b/arch/arm64/kernel/image-vars.h
>>>> @@ -59,6 +59,7 @@ KVM_NVHE_ALIAS(alt_cb_patch_nops);
>>>> ?? ? /* Global kernel state accessed by nVHE hyp code. */
>>>> ?? KVM_NVHE_ALIAS(kvm_vgic_global_state);
>>>> +KVM_NVHE_ALIAS(kvm_guest_trfcr);
>>>> ?? ? /* Kernel symbols used to call panic() from nVHE hyp code (via
>>>> ERET). */
>>>> ?? KVM_NVHE_ALIAS(nvhe_hyp_panic_handler);
>>>> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
>>>> index 49a13e72ddd2..c8d936ce6e2b 100644
>>>> --- a/arch/arm64/kvm/debug.c
>>>> +++ b/arch/arm64/kvm/debug.c
>>>> @@ -22,6 +22,7 @@
>>>> ?????????????????? DBG_MDSCR_MDE)
>>>> ?? ? static DEFINE_PER_CPU(u64, mdcr_el2);
>>>> +u64 ____cacheline_aligned kvm_guest_trfcr[NR_CPUS];
>>>> ?? ? /*
>>>> ??? * save/restore_guest_debug_regs
>>>> @@ -359,3 +360,28 @@ void kvm_arch_vcpu_put_debug_state_flags(struct
>>>> kvm_vcpu *vcpu)
>>>> ?????? vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
>>>> ?????? vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
>>>> ?? }
>>>> +
>>>> +/*
>>>> + * Interface for the Coresight driver to use to set the value of the
>>>> TRFCR
>>>> + * register for the guest. This register controls the exclude
>>>> settings for trace
>>>> + * at different exception levels, and is used to honor the
>>>> exclude_host and
>>>> + * exclude_guest parameters from the Perf session.
>>>> + *
>>>> + * This will be used to later write TRFCR_EL1 on nVHE at guest
>>>> switch. For VHE,
>>>> + * the host trace is controlled by TRFCR_EL2 and thus we can write to
>>>> the
>>>> + * TRFCR_EL1 immediately. Because guest writes to the register are
>>>> trapped, the
>>>> + * value will persist and can't be modified. For pKVM,
>>>> kvm_guest_trfcr can't
>>>> + * be read by the hypervisor, so don't bother writing it.
>>>> + */
>>>> +void kvm_etm_set_guest_trfcr(u64 trfcr_guest)
>>>> +{
>>>> +??? if
>>>> (WARN_ON_ONCE(!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
>>>> +?????????????????????????????????? ID_AA64DFR0_EL1_TraceFilt_SHIFT)))
>>>> +??????? return;
>>>> +
>>>> +??? if (has_vhe())
>>>> +??????? write_sysreg_s(trfcr_guest, SYS_TRFCR_EL12);
>>>> +??? else if (!is_protected_kvm_enabled())
>>>> +??????? kvm_guest_trfcr[smp_processor_id()] = trfcr_guest;
>>>
>>> smp_processor_id() could sleep in some configurations ? Should we switch
>>> to raw_smp_processor_id() to be safer ?
>>>
>>
>> I don't think so, it's #defined to raw_smp_processor_id() anyway. Unless
>> DEBUG_PREEMPT is on, then it's still raw_smp_processor_id() but it
>> validates that preemption is disabled so the value isn't stale. >
>> We actually want that validation, so should leave it as
> 
> This is actually what we want. i.e., We don't want the coresight drivers
> to make this call from a non-premptible context. Relying on the
> DEBUG_PREEMPT for detecting such erroneous uses is not a good idea,
> production kernels may not do this and a comment doesn't go far.
> So, I think we need a :
> 
> WARN_ON(preemptible()) in here and use smp_processor_id()
> 

Ok yeah that's easy enough to add. I was worried it would be redundant
with DEBUG_PREEMPT but I suppose it doesn't really cost anything.

>> smp_processor_id(). I can add a comment saying that this function should
>> only be called with preemption disabled, but I wouldn't add any extra
>> validation. Every smp_processor_id() call is already checked when
>> DEBUG_PREEMPT is on and this one doesn't seem to be special in any way.
>>
>> I also checked that the warning isn't triggered with DEBUG_PREEMPT on,
>> and there are also a lot of other smp_processor_id() calls on similar
>> paths in the Coresight driver.
> 
> Here, we are setting something for the KVM to program and if we set the
> filters on the wrong Physical CPU, then we mess up the tracing.
> 
> Suzuki
> 
>>
>>> Otherwise looks good to me.
>>>
>>> Suzuki
>>>
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(kvm_etm_set_guest_trfcr);
>>>
> 


From jpanis at baylibre.com  Mon Feb 26 03:40:31 2024
From: jpanis at baylibre.com (Julien Panis)
Date: Mon, 26 Feb 2024 12:40:31 +0100
Subject: [PATCH v2 05/14] mfd: tps6594-i2c: Add TI TPS65224 PMIC I2C
In-Reply-To: <20240223093701.66034-6-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
 <20240223093701.66034-6-bhargav.r@ltts.com>
Message-ID: <b80142a9-1cea-4c5f-8464-2ad6d33845c2@baylibre.com>

On 2/23/24 10:36, Bhargav Raviprakash wrote:
> Add support for TPS65224 PMIC in TPS6594's I2C driver which has
> significant functional overlap.
>
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> ---
>   drivers/mfd/tps6594-i2c.c | 15 +++++++++++++--
>   1 file changed, 13 insertions(+), 2 deletions(-)

Acked-by: Julien Panis <jpanis at baylibre.com>



From tudor.ambarus at linaro.org  Mon Feb 26 03:45:50 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 26 Feb 2024 13:45:50 +0200
Subject: [PATCH] MAINTAINERS: Remove T Ambarus from few mchp entries
In-Reply-To: <20240226112132.22025454@xps-13>
References: <20240226094718.29104-1-tudor.ambarus@linaro.org>
 <20240226112132.22025454@xps-13>
Message-ID: <1d7b31a1-60c4-45b3-a7ae-a3a2c2e126a8@linaro.org>



On 26.02.2024 12:21, Miquel Raynal wrote:
> Could we mark these entries orphaned instead of removing them?

ok, will send v2.


From linux at armlinux.org.uk  Mon Feb 26 03:47:44 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 26 Feb 2024 11:47:44 +0000
Subject: [PATCH v10] lib: checksum: Use aligned accesses for ip_fast_csum
 and csum_ipv6_magic tests
In-Reply-To: <7ae930a7-3b10-4470-94ee-89cb650b3349@csgroup.eu>
References: <20240223-fix_sparse_errors_checksum_tests-v10-1-b6a45914b7d8@rivosinc.com>
 <7ae930a7-3b10-4470-94ee-89cb650b3349@csgroup.eu>
Message-ID: <Zdx6YMRdPmb595M2@shell.armlinux.org.uk>

On Mon, Feb 26, 2024 at 11:34:51AM +0000, Christophe Leroy wrote:
> Le 23/02/2024 ? 23:11, Charlie Jenkins a ?crit?:
> > The test cases for ip_fast_csum and csum_ipv6_magic were not properly
> > aligning the IP header, which were causing failures on architectures
> > that do not support misaligned accesses like some ARM platforms. To
> > solve this, align the data along (14 + NET_IP_ALIGN) bytes which is the
> > standard alignment of an IP header and must be supported by the
> > architecture.
> 
> I'm still wondering what we are really trying to fix here.
> 
> All other tests are explicitely testing that it works with any alignment.
> 
> Shouldn't ip_fast_csum() and csum_ipv6_magic() work for any alignment as 
> well ? I would expect it, I see no comment in arm code which explicits 
> that assumption around those functions.

No, these functions are explicitly *not* designed to be used with any
alignment. They are for 16-bit alignment only.

I'm not sure where the idea that "any alignment" has come from, but it's
never been the case AFAIK that we've supported that - or if we do now,
that's something which has crept in under the radar.

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


From jpanis at baylibre.com  Mon Feb 26 03:52:02 2024
From: jpanis at baylibre.com (Julien Panis)
Date: Mon, 26 Feb 2024 12:52:02 +0100
Subject: [PATCH v2 06/14] mfd: tps6594-spi: Add TI TPS65224 PMIC SPI
In-Reply-To: <20240223093701.66034-7-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
 <20240223093701.66034-7-bhargav.r@ltts.com>
Message-ID: <d3c579e1-1560-45a1-ab7e-59ed32986eea@baylibre.com>

On 2/23/24 10:36, Bhargav Raviprakash wrote:
> Add support for TPS65224 PMIC in the TPS6594 driver as they share
> significant functional overlap.
>
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> ---
>   drivers/mfd/tps6594-spi.c | 15 ++++++++++++++-
>   1 file changed, 14 insertions(+), 1 deletion(-)

This might be a nitpick, but for the next version of the series, please make
commit message description for i2c VS spi drivers more homogeneous.
Same comment for MODULE_DESCRIPTION (you changed it for i2c: why not,
but then apply the same change to spi).
With these changes,

Acked-by: Julien Panis <jpanis at baylibre.com>



From tudor.ambarus at linaro.org  Mon Feb 26 03:52:25 2024
From: tudor.ambarus at linaro.org (Tudor Ambarus)
Date: Mon, 26 Feb 2024 13:52:25 +0200
Subject: [PATCH v2] MAINTAINERS: Remove T Ambarus from few mchp entries
Message-ID: <20240226115225.75675-1-tudor.ambarus@linaro.org>

I have been no longer at Microchip for more than a year and I'm no
longer interested in maintaining these drivers. Let other mchp people
step up, thus remove myself. Thanks for the nice collaboration everyone!

Signed-off-by: Tudor Ambarus <tudor.ambarus at linaro.org>
---
Shall go through the at91 tree.

v2: make entries as orphan instead of removing them

 MAINTAINERS | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index e1475ca38ff2..bce0ae12d599 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14350,7 +14350,6 @@ F:	drivers/misc/xilinx_tmr_manager.c
 
 MICROCHIP AT91 DMA DRIVERS
 M:	Ludovic Desroches <ludovic.desroches at microchip.com>
-M:	Tudor Ambarus <tudor.ambarus at linaro.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 L:	dmaengine at vger.kernel.org
 S:	Supported
@@ -14399,9 +14398,8 @@ F:	Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
 F:	drivers/media/platform/microchip/microchip-csi2dc.c
 
 MICROCHIP ECC DRIVER
-M:	Tudor Ambarus <tudor.ambarus at linaro.org>
 L:	linux-crypto at vger.kernel.org
-S:	Maintained
+S:	Orphan
 F:	drivers/crypto/atmel-ecc.*
 
 MICROCHIP EIC DRIVER
@@ -14506,9 +14504,8 @@ S:	Maintained
 F:	drivers/mmc/host/atmel-mci.c
 
 MICROCHIP NAND DRIVER
-M:	Tudor Ambarus <tudor.ambarus at linaro.org>
 L:	linux-mtd at lists.infradead.org
-S:	Supported
+S:	Orphan
 F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt
 F:	drivers/mtd/nand/raw/atmel/*
 
-- 
2.34.1



From david at redhat.com  Mon Feb 26 03:53:48 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 26 Feb 2024 12:53:48 +0100
Subject: [PATCH v17 19/35] arch/mm: Export direct {un,}map functions
In-Reply-To: <Zdxwo0abvklfam-Z@infradead.org>
References: <20240222-gunyah-v17-0-1e9da6763d38@quicinc.com>
 <20240222-gunyah-v17-19-1e9da6763d38@quicinc.com>
 <ZdhEtH7xzbzdhS2j@infradead.org>
 <20240223071006483-0800.eberman@hu-eberman-lv.qualcomm.com>
 <Zdxwo0abvklfam-Z@infradead.org>
Message-ID: <2f4c44ad-b309-4baa-ac21-2ae19efd31fb@redhat.com>

On 26.02.24 12:06, Christoph Hellwig wrote:
> The point is that we can't we just allow modules to unmap data from
> the kernel mapping, no matter how noble your intentions are.

I absolutely agree.

-- 
Cheers,

David / dhildenb



From sakari.ailus at iki.fi  Mon Feb 26 03:54:22 2024
From: sakari.ailus at iki.fi (Sakari Ailus)
Date: Mon, 26 Feb 2024 11:54:22 +0000
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240214141906.245685-3-dan.scally@ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
Message-ID: <Zdx77nyiQn4zya3h@valkosipuli.retiisi.eu>

Hi Dan,

On Wed, Feb 14, 2024 at 02:19:03PM +0000, Daniel Scally wrote:
> Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
> 
> Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> ---
> Changes in v2:
> 
> 	- Added clocks information
> 	- Fixed the warnings raised by Rob
> 
>  .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
>  1 file changed, 77 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> new file mode 100644
> index 000000000000..30038cfec3a4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> @@ -0,0 +1,77 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ARM Mali-C55 Image Signal Processor
> +
> +maintainers:
> +  - Daniel Scally <dan.scally at ideasonboard.com>
> +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> +
> +properties:
> +  compatible:
> +    const: arm,mali-c55
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: ISP video clock
> +      - description: ISP AXI clock
> +      - description: ISP AHB-lite clock
> +
> +  clock-names:
> +    items:
> +      - const: vclk
> +      - const: aclk
> +      - const: hclk
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +
> +        properties:
> +          endpoint:
> +            $ref: /schemas/graph.yaml#/properties/endpoint
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    mali_c55: isp at 400000 {
> +      compatible = "arm,mali-c55";
> +      reg = <0x400000 0x200000>;
> +      clocks = <&clk 0>, <&clk 1>, <&clk 2>;
> +      clock-names = "vclk", "aclk", "hclk";
> +      interrupts = <0>;
> +
> +      ports {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        port at 0 {
> +          reg = <0>;
> +          isp_in: endpoint {
> +              remote-endpoint = <&mipi_out>;

I suppose this is a CSI-2 interface with D-PHY?

How many lanes do you have and is lane remapping / polarity inversion
supported?

This should be reflected in bindings.

> +          };
> +        };
> +      };
> +    };
> +...

-- 
Regards,

Sakari Ailus


From conor.dooley at microchip.com  Mon Feb 26 03:56:16 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Mon, 26 Feb 2024 11:56:16 +0000
Subject: [PATCH v3 1/8] dt-bindings: usb: ti,j721e-usb: drop useless
 compatible list
In-Reply-To: <CZEXXXQDZZWB.1M5CTZAFVO4YP@bootlin.com>
References: <20240223-j7200-usb-suspend-v3-0-b41c9893a130@bootlin.com>
 <20240223-j7200-usb-suspend-v3-1-b41c9893a130@bootlin.com>
 <20240223-clarity-variably-206b01b7276a@spud>
 <CZEXXXQDZZWB.1M5CTZAFVO4YP@bootlin.com>
Message-ID: <20240226-portable-rockslide-e501667a0d9a@wendy>

On Mon, Feb 26, 2024 at 11:33:06AM +0100, Th?o Lebrun wrote:
> Hello Conor,
> 
> On Fri Feb 23, 2024 at 7:12 PM CET, Conor Dooley wrote:
> > On Fri, Feb 23, 2024 at 05:05:25PM +0100, Th?o Lebrun wrote:
> > > Compatible can be A or B, not A or B or A+B. Remove last option.
> > > A=ti,j721e-usb and B=ti,am64-usb.
> > > 
> > > Signed-off-by: Th?o Lebrun <theo.lebrun at bootlin.com>
> > > ---
> > >  Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml | 9 +++------
> > >  1 file changed, 3 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> > > index 95ff9791baea..949f45eb45c2 100644
> > > --- a/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> > > +++ b/Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
> > > @@ -11,12 +11,9 @@ maintainers:
> > >  
> > >  properties:
> > >    compatible:
> > > -    oneOf:
> > > -      - const: ti,j721e-usb
> > > -      - const: ti,am64-usb
> > > -      - items:
> > > -          - const: ti,j721e-usb
> > > -          - const: ti,am64-usb
> >
> > Correct, this makes no sense. The devices seem to be compatible though,
> > so I would expect this to actually be:
> > oneOf:
> >   - const: ti,j721e-usb
> >   - items:
> >       - const: ti,am64-usb
> >       - const: ti,j721e-usb
> 
> I need your help to grasp what that change is supposed to express? Would
> you mind turning it into english sentences?
> A=ti,j721e-usb and B=ti,am64-usb. My understanding of your proposal is
> that a device can either be compat with A or B. But B is compatible
> with A so you express it as a list of items. If B is compat with A then
> A is compat with B. Does the order of items matter?

The two devices are compatible with each other, based on an inspection of
the driver and the existing "A+B" setup. If this was a newly submitted
binding, "B" would not get approved because "A+B" allows support without
software changes and all that jazz.

Your patch says that allowing "A", "B" and "A+B" makes no sense and you
suggest removing "A+B". I am agreeing that it makes no sense to allow
all 3 of these situations.

What I also noticed is other problems with the binding. What should have
been "A+B" is actually documented as "B+A", but that doesn't make sense
when the originally supported device is "A".

Therefore my suggestion was to only allow "A" and "A+B", which is what
we would (hopefully) tell you to do were you submitting the am64 support
as a new patch today.

> I've not applied your proposal to check for dtbs_check but I'd guess it
> would throw warnings for the single existing upstream DTSI (as of
> v6.8-rc6) that uses "ti,am64-usb"? See:
> arch/arm64/boot/dts/ti/k3-am64-main.dtsi.

Yeah, it would but it's not as if that cannot be changed. There's no
concerns here about backwards compatibility here, right?
-------------- 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/20240226/63a62d59/attachment.sig>

From christophe.leroy at csgroup.eu  Mon Feb 26 03:57:24 2024
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Mon, 26 Feb 2024 11:57:24 +0000
Subject: [PATCH v10] lib: checksum: Use aligned accesses for ip_fast_csum
 and csum_ipv6_magic tests
In-Reply-To: <Zdx6YMRdPmb595M2@shell.armlinux.org.uk>
References: <20240223-fix_sparse_errors_checksum_tests-v10-1-b6a45914b7d8@rivosinc.com>
 <7ae930a7-3b10-4470-94ee-89cb650b3349@csgroup.eu>
 <Zdx6YMRdPmb595M2@shell.armlinux.org.uk>
Message-ID: <96b3fcfd-6932-4987-9831-5abdad8d445c@csgroup.eu>



Le 26/02/2024 ? 12:47, Russell King (Oracle) a ?crit?:
> On Mon, Feb 26, 2024 at 11:34:51AM +0000, Christophe Leroy wrote:
>> Le 23/02/2024 ? 23:11, Charlie Jenkins a ?crit?:
>>> The test cases for ip_fast_csum and csum_ipv6_magic were not properly
>>> aligning the IP header, which were causing failures on architectures
>>> that do not support misaligned accesses like some ARM platforms. To
>>> solve this, align the data along (14 + NET_IP_ALIGN) bytes which is the
>>> standard alignment of an IP header and must be supported by the
>>> architecture.
>>
>> I'm still wondering what we are really trying to fix here.
>>
>> All other tests are explicitely testing that it works with any alignment.
>>
>> Shouldn't ip_fast_csum() and csum_ipv6_magic() work for any alignment as
>> well ? I would expect it, I see no comment in arm code which explicits
>> that assumption around those functions.
> 
> No, these functions are explicitly *not* designed to be used with any
> alignment. They are for 16-bit alignment only.
> 
> I'm not sure where the idea that "any alignment" has come from, but it's
> never been the case AFAIK that we've supported that - or if we do now,
> that's something which has crept in under the radar.
> 

Ok, 16-bit is fine for me, then there is no need to require a (14 + 
NET_IP_ALIGN) ie a 16-bytes (128-bit) alignment as this patch is doing.

Christophe

From linux at armlinux.org.uk  Mon Feb 26 03:57:29 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 26 Feb 2024 11:57:29 +0000
Subject: [PATCH v2] arm: flush: check if the folio is reserved for
 no-mapping addresses
In-Reply-To: <788c8a64-09ed-96fd-9878-ed126b09c683@huawei.com>
References: <20240223063608.2605736-1-liuyongqiang13@huawei.com>
 <788c8a64-09ed-96fd-9878-ed126b09c683@huawei.com>
Message-ID: <Zdx8qZLyjh4pO+vx@shell.armlinux.org.uk>

On Mon, Feb 26, 2024 at 02:38:58PM +0800, Jinjiang Tu wrote:
> Since some abuses of pfn_valid() have been reported, I check all the use of
> pfn_valid(), and find some suspicious cases.

I do get really tired of kernel interfaces migrating to become something
different from what they were when code was originally written, and then
having users of that interface labelled as "suspicious" or an "abuse".

I don't follow MM stuff, so I can't comment on the rights or wrongs of
this, but what I understood was that pfn_valid() is there to check that
for a given PFN, pfn_to_page() would return a valid pointer to a struct
page. Given that we only have struct page's for memory which the kernel
is managing, this seems entirely correct.

There may be other RAM in the system which is being managed via
different mechanisms, and because those won't have a struct page
associated with them, pfn_valid() should be returning false (which
means memory carved out for e.g. other processors etc) won't be mapped
cacheable.

Or at least that's how things used to be - because 32-bit Arm's
pfn_valid() was implemented by checking memblock for memory, and
stolen memory _was_ removed from memblock.memory (see
arm_memblock_steal) or quite simply these areas were not passed to
the kernel as memory.

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


From ryan.roberts at arm.com  Mon Feb 26 04:03:19 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 26 Feb 2024 12:03:19 +0000
Subject: [PATCH 0/2] Address some contpte nits
Message-ID: <20240226120321.1055731-1-ryan.roberts@arm.com>

Hi Andrew,

These 2 patches address some nits raised by Catalin late in the review cycle for
my contpte series [1]. Unfortunately I was out on holiday last week and you have
now moved the original series to mm-stable, so sending these out as separate
patches.

They apply on top of current mm-unstable (ccbd06e764ba).

I've build-tested with allmodconfig for arm64.

Thanks,
Ryan

[1] https://lore.kernel.org/linux-mm/20240215103205.2607016-1-ryan.roberts at arm.com/

Ryan Roberts (2):
  arm64/mm: Export contpte symbols only to GPL users
  arm64/mm: Improve comment in contpte_ptep_get_lockless()

 arch/arm64/mm/contpte.c | 46 ++++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 21 deletions(-)

--
2.25.1



From ryan.roberts at arm.com  Mon Feb 26 04:03:21 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 26 Feb 2024 12:03:21 +0000
Subject: [PATCH 2/2] arm64/mm: Improve comment in contpte_ptep_get_lockless()
In-Reply-To: <20240226120321.1055731-1-ryan.roberts@arm.com>
References: <20240226120321.1055731-1-ryan.roberts@arm.com>
Message-ID: <20240226120321.1055731-3-ryan.roberts@arm.com>

Make clear the atmicity/consistency requirements of the API and how we
achieve them.

Link: https://lore.kernel.org/linux-mm/Zc-Tqqfksho3BHmU at arm.com/
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/mm/contpte.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index be0a226c4ff9..1b64b4c3f8bf 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -183,16 +183,20 @@ EXPORT_SYMBOL_GPL(contpte_ptep_get);
 pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
 {
 	/*
-	 * Gather access/dirty bits, which may be populated in any of the ptes
-	 * of the contig range. We may not be holding the PTL, so any contiguous
-	 * range may be unfolded/modified/refolded under our feet. Therefore we
-	 * ensure we read a _consistent_ contpte range by checking that all ptes
-	 * in the range are valid and have CONT_PTE set, that all pfns are
-	 * contiguous and that all pgprots are the same (ignoring access/dirty).
-	 * If we find a pte that is not consistent, then we must be racing with
-	 * an update so start again. If the target pte does not have CONT_PTE
-	 * set then that is considered consistent on its own because it is not
-	 * part of a contpte range.
+	 * The ptep_get_lockless() API requires us to read and return *orig_ptep
+	 * so that it is self-consistent, without the PTL held, so we may be
+	 * racing with other threads modifying the pte. Usually a READ_ONCE()
+	 * would suffice, but for the contpte case, we also need to gather the
+	 * access and dirty bits from across all ptes in the contiguous block,
+	 * and we can't read all of those neighbouring ptes atomically, so any
+	 * contiguous range may be unfolded/modified/refolded under our feet.
+	 * Therefore we ensure we read a _consistent_ contpte range by checking
+	 * that all ptes in the range are valid and have CONT_PTE set, that all
+	 * pfns are contiguous and that all pgprots are the same (ignoring
+	 * access/dirty). If we find a pte that is not consistent, then we must
+	 * be racing with an update so start again. If the target pte does not
+	 * have CONT_PTE set then that is considered consistent on its own
+	 * because it is not part of a contpte range.
 	 */
 
 	pgprot_t orig_prot;
-- 
2.25.1



From ryan.roberts at arm.com  Mon Feb 26 04:03:20 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 26 Feb 2024 12:03:20 +0000
Subject: [PATCH 1/2] arm64/mm: Export contpte symbols only to GPL users
In-Reply-To: <20240226120321.1055731-1-ryan.roberts@arm.com>
References: <20240226120321.1055731-1-ryan.roberts@arm.com>
Message-ID: <20240226120321.1055731-2-ryan.roberts@arm.com>

The contpte symbols must be exported since some of the public inline
ptep_* APIs are called from modules and these inlines now call the
contpte functions. Originally they were exported as EXPORT_SYMBOL() for
fear of breaking out-of-tree modules. But we subsequently concluded that
EXPORT_SYMBOL_GPL() should be safe since these functions are deeply core
mm routines, and any module operating at this level is not going to be
able to survive on EXPORT_SYMBOL alone.

Link: https://lore.kernel.org/linux-mm/f9fc2b31-11cb-4969-8961-9c89fea41b74 at nvidia.com/
Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
---
 arch/arm64/mm/contpte.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index 16788f07716d..be0a226c4ff9 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -135,7 +135,7 @@ void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
 	pte = pte_mkcont(pte);
 	contpte_convert(mm, addr, orig_ptep, pte);
 }
-EXPORT_SYMBOL(__contpte_try_fold);
+EXPORT_SYMBOL_GPL(__contpte_try_fold);
 
 void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
 			pte_t *ptep, pte_t pte)
@@ -150,7 +150,7 @@ void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
 	pte = pte_mknoncont(pte);
 	contpte_convert(mm, addr, ptep, pte);
 }
-EXPORT_SYMBOL(__contpte_try_unfold);
+EXPORT_SYMBOL_GPL(__contpte_try_unfold);
 
 pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
 {
@@ -178,7 +178,7 @@ pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
 
 	return orig_pte;
 }
-EXPORT_SYMBOL(contpte_ptep_get);
+EXPORT_SYMBOL_GPL(contpte_ptep_get);
 
 pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
 {
@@ -231,7 +231,7 @@ pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
 
 	return orig_pte;
 }
-EXPORT_SYMBOL(contpte_ptep_get_lockless);
+EXPORT_SYMBOL_GPL(contpte_ptep_get_lockless);
 
 void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
 					pte_t *ptep, pte_t pte, unsigned int nr)
@@ -274,7 +274,7 @@ void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
 
 	} while (addr != end);
 }
-EXPORT_SYMBOL(contpte_set_ptes);
+EXPORT_SYMBOL_GPL(contpte_set_ptes);
 
 void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
 				pte_t *ptep, unsigned int nr, int full)
@@ -282,7 +282,7 @@ void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
 	contpte_try_unfold_partial(mm, addr, ptep, nr);
 	__clear_full_ptes(mm, addr, ptep, nr, full);
 }
-EXPORT_SYMBOL(contpte_clear_full_ptes);
+EXPORT_SYMBOL_GPL(contpte_clear_full_ptes);
 
 pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
 				unsigned long addr, pte_t *ptep,
@@ -291,7 +291,7 @@ pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
 	contpte_try_unfold_partial(mm, addr, ptep, nr);
 	return __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
 }
-EXPORT_SYMBOL(contpte_get_and_clear_full_ptes);
+EXPORT_SYMBOL_GPL(contpte_get_and_clear_full_ptes);
 
 int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
 					unsigned long addr, pte_t *ptep)
@@ -316,7 +316,7 @@ int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
 
 	return young;
 }
-EXPORT_SYMBOL(contpte_ptep_test_and_clear_young);
+EXPORT_SYMBOL_GPL(contpte_ptep_test_and_clear_young);
 
 int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
 					unsigned long addr, pte_t *ptep)
@@ -337,7 +337,7 @@ int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
 
 	return young;
 }
-EXPORT_SYMBOL(contpte_ptep_clear_flush_young);
+EXPORT_SYMBOL_GPL(contpte_ptep_clear_flush_young);
 
 void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
 					pte_t *ptep, unsigned int nr)
@@ -355,7 +355,7 @@ void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
 	contpte_try_unfold_partial(mm, addr, ptep, nr);
 	__wrprotect_ptes(mm, addr, ptep, nr);
 }
-EXPORT_SYMBOL(contpte_wrprotect_ptes);
+EXPORT_SYMBOL_GPL(contpte_wrprotect_ptes);
 
 int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
 					unsigned long addr, pte_t *ptep,
@@ -401,4 +401,4 @@ int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
 
 	return 1;
 }
-EXPORT_SYMBOL(contpte_ptep_set_access_flags);
+EXPORT_SYMBOL_GPL(contpte_ptep_set_access_flags);
-- 
2.25.1



From linux at armlinux.org.uk  Mon Feb 26 04:03:47 2024
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 26 Feb 2024 12:03:47 +0000
Subject: [PATCH v10] lib: checksum: Use aligned accesses for ip_fast_csum
 and csum_ipv6_magic tests
In-Reply-To: <96b3fcfd-6932-4987-9831-5abdad8d445c@csgroup.eu>
References: <20240223-fix_sparse_errors_checksum_tests-v10-1-b6a45914b7d8@rivosinc.com>
 <7ae930a7-3b10-4470-94ee-89cb650b3349@csgroup.eu>
 <Zdx6YMRdPmb595M2@shell.armlinux.org.uk>
 <96b3fcfd-6932-4987-9831-5abdad8d445c@csgroup.eu>
Message-ID: <Zdx+I3V9ka3EbaHq@shell.armlinux.org.uk>

On Mon, Feb 26, 2024 at 11:57:24AM +0000, Christophe Leroy wrote:
> 
> 
> Le 26/02/2024 ? 12:47, Russell King (Oracle) a ?crit?:
> > On Mon, Feb 26, 2024 at 11:34:51AM +0000, Christophe Leroy wrote:
> >> Le 23/02/2024 ? 23:11, Charlie Jenkins a ?crit?:
> >>> The test cases for ip_fast_csum and csum_ipv6_magic were not properly
> >>> aligning the IP header, which were causing failures on architectures
> >>> that do not support misaligned accesses like some ARM platforms. To
> >>> solve this, align the data along (14 + NET_IP_ALIGN) bytes which is the
> >>> standard alignment of an IP header and must be supported by the
> >>> architecture.
> >>
> >> I'm still wondering what we are really trying to fix here.
> >>
> >> All other tests are explicitely testing that it works with any alignment.
> >>
> >> Shouldn't ip_fast_csum() and csum_ipv6_magic() work for any alignment as
> >> well ? I would expect it, I see no comment in arm code which explicits
> >> that assumption around those functions.
> > 
> > No, these functions are explicitly *not* designed to be used with any
> > alignment. They are for 16-bit alignment only.
> > 
> > I'm not sure where the idea that "any alignment" has come from, but it's
> > never been the case AFAIK that we've supported that - or if we do now,
> > that's something which has crept in under the radar.
> > 
> 
> Ok, 16-bit is fine for me, then there is no need to require a (14 + 
> NET_IP_ALIGN) ie a 16-bytes (128-bit) alignment as this patch is doing.

Looking again at these two functions, I'm mistaken - this was written for
optimal use with 32-bit alignment, not 16-bit. However, the entire IP
layer is written with the assumption that for maximum performance, the IP
header will be 32-bit aligned.

However, that may not always be the case for incoming packets, and what
saves 32-bit Arm is the ability to do unaligned loads in later revisions
of the architecture, or the alignment fault handler (slow) on older
revisions.

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


From laurent.pinchart at ideasonboard.com  Mon Feb 26 04:04:31 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 26 Feb 2024 14:04:31 +0200
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <Zdx77nyiQn4zya3h@valkosipuli.retiisi.eu>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <Zdx77nyiQn4zya3h@valkosipuli.retiisi.eu>
Message-ID: <20240226120431.GA25561@pendragon.ideasonboard.com>

Hi Sakari,

On Mon, Feb 26, 2024 at 11:54:22AM +0000, Sakari Ailus wrote:
> On Wed, Feb 14, 2024 at 02:19:03PM +0000, Daniel Scally wrote:
> > Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
> > 
> > Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> > Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> > ---
> > Changes in v2:
> > 
> > 	- Added clocks information
> > 	- Fixed the warnings raised by Rob
> > 
> >  .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
> >  1 file changed, 77 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > new file mode 100644
> > index 000000000000..30038cfec3a4
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > @@ -0,0 +1,77 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: ARM Mali-C55 Image Signal Processor
> > +
> > +maintainers:
> > +  - Daniel Scally <dan.scally at ideasonboard.com>
> > +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > +
> > +properties:
> > +  compatible:
> > +    const: arm,mali-c55
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    items:
> > +      - description: ISP video clock
> > +      - description: ISP AXI clock
> > +      - description: ISP AHB-lite clock
> > +
> > +  clock-names:
> > +    items:
> > +      - const: vclk
> > +      - const: aclk
> > +      - const: hclk
> > +
> > +  ports:
> > +    $ref: /schemas/graph.yaml#/properties/ports
> > +
> > +    properties:
> > +      port at 0:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +
> > +        properties:
> > +          endpoint:
> > +            $ref: /schemas/graph.yaml#/properties/endpoint
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - clocks
> > +  - clock-names
> > +  - ports
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    mali_c55: isp at 400000 {
> > +      compatible = "arm,mali-c55";
> > +      reg = <0x400000 0x200000>;
> > +      clocks = <&clk 0>, <&clk 1>, <&clk 2>;
> > +      clock-names = "vclk", "aclk", "hclk";
> > +      interrupts = <0>;
> > +
> > +      ports {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        port at 0 {
> > +          reg = <0>;
> > +          isp_in: endpoint {
> > +              remote-endpoint = <&mipi_out>;
> 
> I suppose this is a CSI-2 interface with D-PHY?

No, that's an internal parallel bus. Depending on the SoC integration,
it can be connected to a CSI-2 receiver, a DMA engine, or a mux to
select between different sources.

> How many lanes do you have and is lane remapping / polarity inversion
> supported?
> 
> This should be reflected in bindings.
> 
> > +          };
> > +        };
> > +      };
> > +    };
> > +...

-- 
Regards,

Laurent Pinchart


From rogerq at kernel.org  Mon Feb 26 04:03:06 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 26 Feb 2024 14:03:06 +0200
Subject: [PATCH v6 0/4] arm64: dts: ti: am62: Add USB support for k3-am62p
Message-ID: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-0-acf77fff4344@kernel.org>

Hi,

This series first adds device nodes for USB0_PHY_CTRL and USB1_PHY_CTRL
in the wkup_conf node and fixus up the USB nodes to use the newly
added nodes.

Then it adds USB support for AM62P SoC and AM62P5-SK board.

cheers,
-roger

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
Changes in v6:
- Rebased on next-20240226
- Link to v5: https://lore.kernel.org/r/20240223-b4-for-v6-5-am62-usb-typec-dt-v5-0-4b5854d17d18 at kernel.org

---
Roger Quadros (4):
      dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl compatible
      arm64: dts: ti: k3-am62/a: use sub-node for USB_PHY_CTRL registers
      arm64: dts: ti: k3-am62p: add the USB sub-system
      arm64: dts: ti: k3-am62a: Disable USB LPM

 Documentation/devicetree/bindings/mfd/syscon.yaml |  1 +
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi          |  4 +-
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi        | 10 ++++
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi         |  8 ++-
 arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi       | 10 ++++
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi         | 50 +++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi       | 10 ++++
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts           | 67 +++++++++++++++++++++++
 8 files changed, 156 insertions(+), 4 deletions(-)
---
base-commit: 8552c902efe7ef670b6961fb8885b67961aeb629
change-id: 20240223-b4-for-v6-5-am62-usb-typec-dt-769eec4c8c4a

Best regards,
-- 
Roger Quadros <rogerq at kernel.org>



From rogerq at kernel.org  Mon Feb 26 04:03:07 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 26 Feb 2024 14:03:07 +0200
Subject: [PATCH v6 1/4] dt-bindings: mfd: syscon: Add ti,am62-usb-phy-ctrl
 compatible
In-Reply-To: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-0-acf77fff4344@kernel.org>
References: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-0-acf77fff4344@kernel.org>
Message-ID: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-1-acf77fff4344@kernel.org>

Add the compatible for TI AM62 USB PHY Control register. This
register is found in the TI AM62 WKUP_CTRL_MMR0 space [1]. It
is used to indicate the USB PHY PLL reference clock rate and
core voltage level to the USB controller.

[1] - https://www.ti.com/lit/pdf/spruiv7

Signed-off-by: Roger Quadros <rogerq at kernel.org>
Acked-by: Rob Herring <robh at kernel.org>
---
Changelog:
v6 - Rebased on next-20240226
v5 - no change. Added Lee Jones in To list
v4 - no change. Added Rob's Acked-by
v3 - add compatibles in alphabetical order
v2 - New patch
---
 Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index 820c364c01f2..9d55bee155ce 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -72,6 +72,7 @@ properties:
               - rockchip,rk3588-qos
               - rockchip,rv1126-qos
               - starfive,jh7100-sysmain
+              - ti,am62-usb-phy-ctrl
               - ti,am654-dss-oldi-io-ctrl
               - ti,am654-serdes-ctrl
               - ti,j784s4-pcie-ctrl

-- 
2.34.1



From rogerq at kernel.org  Mon Feb 26 04:03:09 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 26 Feb 2024 14:03:09 +0200
Subject: [PATCH v6 3/4] arm64: dts: ti: k3-am62p: add the USB sub-system
In-Reply-To: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-0-acf77fff4344@kernel.org>
References: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-0-acf77fff4344@kernel.org>
Message-ID: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-3-acf77fff4344@kernel.org>

There are two USB instances available on the am62p5 starter kit. Include
and enable them for use on the board.

USB LPM feature is kept disabled as it is not supported.

Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Signed-off-by: Roger Quadros <rogerq at kernel.org>
Reviewed-by: Andrew Davis <afd at ti.com>
---
Changelog:
v6 - Rebased on next-20240226
v5 - disabled USB LPM feature as it is not supported.
v4 - no change. Added Andrew's Reviewed-by
v3 - no change
v2:
- moved am62p changes to next patch
- use new compatible for USB PHY CTRL node
---
 arch/arm64/boot/dts/ti/k3-am62p-main.dtsi   | 50 +++++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi | 10 +++++
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts     | 67 +++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 7337a9e13535..46d35036d2d5 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -635,6 +635,56 @@ sdhci2: mmc at fa20000 {
 		status = "disabled";
 	};
 
+	usbss0: usb at f900000 {
+		compatible = "ti,am62-usb";
+		reg = <0x00 0x0f900000 0x00 0x800>;
+		clocks = <&k3_clks 161 3>;
+		clock-names = "ref";
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
+		ranges;
+		status = "disabled";
+
+		usb0: usb at 31000000 {
+			compatible = "snps,dwc3";
+			reg = <0x00 0x31000000 0x00 0x50000>;
+			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+			<GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+			interrupt-names = "host", "peripheral";
+			maximum-speed = "high-speed";
+			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
+		};
+	};
+
+	usbss1: usb at f910000 {
+		compatible = "ti,am62-usb";
+		reg = <0x00 0x0f910000 0x00 0x800>;
+		clocks = <&k3_clks 162 3>;
+		clock-names = "ref";
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
+		ranges;
+		status = "disabled";
+
+		usb1: usb at 31100000 {
+			compatible = "snps,dwc3";
+			reg = <0x00 0x31100000 0x00 0x50000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+			<GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+			interrupt-names = "host", "peripheral";
+			maximum-speed = "high-speed";
+			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
+		};
+	};
+
 	fss: bus at fc00000 {
 		compatible = "simple-bus";
 		reg = <0x00 0x0fc00000 0x00 0x70000>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
index a84756c336d0..c71d9624ea27 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
@@ -18,6 +18,16 @@ chipid: chipid at 14 {
 			reg = <0x14 0x4>;
 			bootph-all;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	wkup_uart0: serial at 2b300000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index e86f34e835c1..b63888a4842d 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -27,6 +27,8 @@ aliases {
 		spi0 = &ospi0;
 		ethernet0 = &cpsw_port1;
 		ethernet1 = &cpsw_port2;
+		usb0 = &usb0;
+		usb1 = &usb1;
 	};
 
 	chosen {
@@ -297,6 +299,12 @@ AM62PX_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (G20) MCASP0_ACLKR.UART1_TXD */
 		bootph-all;
 	};
 
+	main_usb1_pins_default: main-usb1-default-pins {
+		pinctrl-single,pins = <
+			AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
+		>;
+	};
+
 	main_wlirq_pins_default: main-wlirq-default-pins {
 		pinctrl-single,pins = <
 			AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
@@ -340,6 +348,36 @@ AM62PX_IOPAD(0x0124, PIN_INPUT, 7) /* (J25) MMC2_SDCD.GPIO0_71 */
 	};
 };
 
+&main_i2c0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+
+	typec_pd0: usb-power-controller at 3f {
+		compatible = "ti,tps6598x";
+		reg = <0x3f>;
+
+		connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			self-powered;
+			data-role = "dual";
+			power-role = "sink";
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port at 0 {
+					reg = <0>;
+					usb_con_hs: endpoint {
+						remote-endpoint = <&usb0_hs_ep>;
+					};
+				};
+			};
+		};
+	};
+};
+
 &main_i2c1 {
 	status = "okay";
 	pinctrl-names = "default";
@@ -463,6 +501,35 @@ cpsw3g_phy1: ethernet-phy at 1 {
 	};
 };
 
+&usbss0 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usbss1 {
+	status = "okay";
+	ti,vbus-divider;
+};
+
+&usb0 {
+	usb-role-switch;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	port at 0 {
+		reg = <0>;
+		usb0_hs_ep: endpoint {
+			remote-endpoint = <&usb_con_hs>;
+		};
+	};
+};
+
+&usb1 {
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_usb1_pins_default>;
+};
+
 &mcasp1 {
 	status = "okay";
 	#sound-dai-cells = <0>;

-- 
2.34.1



From rogerq at kernel.org  Mon Feb 26 04:03:08 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 26 Feb 2024 14:03:08 +0200
Subject: [PATCH v6 2/4] arm64: dts: ti: k3-am62/a: use sub-node for
 USB_PHY_CTRL registers
In-Reply-To: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-0-acf77fff4344@kernel.org>
References: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-0-acf77fff4344@kernel.org>
Message-ID: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-2-acf77fff4344@kernel.org>

Exposing the entire CTRL_MMR space to syscon is not a good idea.
Add sub-nodes for USB0_PHY_CTRL and USB1_PHY_CTRL and use them
in the USB0/USB1 nodes.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
Reviewed-by: Andrew Davis <afd at ti.com>
---
Changelog:
v6 - Rebased on next-20240226
v5 - no change.
v4 - no change. Added Andrew's Reviewed-by
v3 - no change
v2:
- moved am62p changes to next patch
- use new compatible for USB PHY CTRL node
---
 arch/arm64/boot/dts/ti/k3-am62-main.dtsi    |  4 ++--
 arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi  | 10 ++++++++++
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi   |  4 ++--
 arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi | 10 ++++++++++
 4 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index e9cffca073ef..23f1464b26ed 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -622,7 +622,7 @@ usbss0: dwc3-usb at f900000 {
 		reg = <0x00 0x0f900000 0x00 0x800>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
@@ -647,7 +647,7 @@ usbss1: dwc3-usb at f910000 {
 		reg = <0x00 0x0f910000 0x00 0x800>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
index 23ce1bfda8d6..66ddf2dc51af 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -21,6 +21,16 @@ chipid: chipid at 14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	target-module at 2b300050 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index aa1e057082f0..a158df0d0ba6 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -606,7 +606,7 @@ usbss0: dwc3-usb at f900000 {
 		reg = <0x00 0x0f900000 0x00 0x800>;
 		clocks = <&k3_clks 161 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+		ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
@@ -629,7 +629,7 @@ usbss1: dwc3-usb at f910000 {
 		reg = <0x00 0x0f910000 0x00 0x800>;
 		clocks = <&k3_clks 162 3>;
 		clock-names = "ref";
-		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+		ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
 		#address-cells = <2>;
 		#size-cells = <2>;
 		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
index f7bec484705a..98043e9aa316 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
@@ -17,6 +17,16 @@ chipid: chipid at 14 {
 			compatible = "ti,am654-chipid";
 			reg = <0x14 0x4>;
 		};
+
+		usb0_phy_ctrl: syscon at 4008 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4008 0x4>;
+		};
+
+		usb1_phy_ctrl: syscon at 4018 {
+			compatible = "ti,am62-usb-phy-ctrl", "syscon";
+			reg = <0x4018 0x4>;
+		};
 	};
 
 	wkup_uart0: serial at 2b300000 {

-- 
2.34.1



From rogerq at kernel.org  Mon Feb 26 04:03:10 2024
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 26 Feb 2024 14:03:10 +0200
Subject: [PATCH v6 4/4] arm64: dts: ti: k3-am62a: Disable USB LPM
In-Reply-To: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-0-acf77fff4344@kernel.org>
References: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-0-acf77fff4344@kernel.org>
Message-ID: <20240226-b4-for-v6-5-am62-usb-typec-dt-v6-4-acf77fff4344@kernel.org>

As per AM62A TRM [1] USB Link Power Management (LPM)
feature is not supported. Disable it else it may
cause enumeration failure on some devices.

> 4.9.2.1 USB2SS Unsupported Features
> The following features are not supported on this family of devices:
> ...
> - USB 2.0 ECN: Link Power Management (LPM)
> ...

[1] - https://www.ti.com/lit/pdf/spruj16

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
Changelog:
v6 - Rebased on next-20240226
v5 - new patch
---
 arch/arm64/boot/dts/ti/k3-am62a-main.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index a158df0d0ba6..adaf578280f9 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -621,6 +621,8 @@ usb0: usb at 31000000 {
 			interrupt-names = "host", "peripheral";
 			maximum-speed = "high-speed";
 			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
 		};
 	};
 
@@ -644,6 +646,8 @@ usb1: usb at 31100000 {
 			interrupt-names = "host", "peripheral";
 			maximum-speed = "high-speed";
 			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
 		};
 	};
 

-- 
2.34.1



From jpanis at baylibre.com  Mon Feb 26 04:17:29 2024
From: jpanis at baylibre.com (Julien Panis)
Date: Mon, 26 Feb 2024 13:17:29 +0100
Subject: [PATCH v2 07/14] mfd: tps6594-core: Add TI TPS65224 PMIC core
In-Reply-To: <20240223093701.66034-8-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
 <20240223093701.66034-8-bhargav.r@ltts.com>
Message-ID: <45c31edd-45ea-4101-ae1d-5e0f95c88d20@baylibre.com>

On 2/23/24 10:36, Bhargav Raviprakash wrote:
> Add functionality of the TPS65224 PMIC to the TPS6594 core driver. This
> includes adding IRQ resource, MFD cells, and device initialization for
> TPS65224.
>
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> ---
>   drivers/mfd/tps6594-core.c | 250 ++++++++++++++++++++++++++++++++++---
>   1 file changed, 232 insertions(+), 18 deletions(-)

Acked-by: Julien Panis <jpanis at baylibre.com>



From sakari.ailus at iki.fi  Mon Feb 26 04:20:15 2024
From: sakari.ailus at iki.fi (Sakari Ailus)
Date: Mon, 26 Feb 2024 12:20:15 +0000
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240226120431.GA25561@pendragon.ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <Zdx77nyiQn4zya3h@valkosipuli.retiisi.eu>
 <20240226120431.GA25561@pendragon.ideasonboard.com>
Message-ID: <ZdyB_yHn9yImTuhm@valkosipuli.retiisi.eu>

Hi Laurent,

On Mon, Feb 26, 2024 at 02:04:31PM +0200, Laurent Pinchart wrote:
> Hi Sakari,
> 
> On Mon, Feb 26, 2024 at 11:54:22AM +0000, Sakari Ailus wrote:
> > On Wed, Feb 14, 2024 at 02:19:03PM +0000, Daniel Scally wrote:
> > > Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
> > > 
> > > Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> > > Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> > > ---
> > > Changes in v2:
> > > 
> > > 	- Added clocks information
> > > 	- Fixed the warnings raised by Rob
> > > 
> > >  .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
> > >  1 file changed, 77 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > > 
> > > diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > > new file mode 100644
> > > index 000000000000..30038cfec3a4
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > > @@ -0,0 +1,77 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: ARM Mali-C55 Image Signal Processor
> > > +
> > > +maintainers:
> > > +  - Daniel Scally <dan.scally at ideasonboard.com>
> > > +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > > +
> > > +properties:
> > > +  compatible:
> > > +    const: arm,mali-c55
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  interrupts:
> > > +    maxItems: 1
> > > +
> > > +  clocks:
> > > +    items:
> > > +      - description: ISP video clock
> > > +      - description: ISP AXI clock
> > > +      - description: ISP AHB-lite clock
> > > +
> > > +  clock-names:
> > > +    items:
> > > +      - const: vclk
> > > +      - const: aclk
> > > +      - const: hclk
> > > +
> > > +  ports:
> > > +    $ref: /schemas/graph.yaml#/properties/ports
> > > +
> > > +    properties:
> > > +      port at 0:
> > > +        $ref: /schemas/graph.yaml#/properties/port
> > > +
> > > +        properties:
> > > +          endpoint:
> > > +            $ref: /schemas/graph.yaml#/properties/endpoint
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - interrupts
> > > +  - clocks
> > > +  - clock-names
> > > +  - ports
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > +  - |
> > > +    mali_c55: isp at 400000 {
> > > +      compatible = "arm,mali-c55";
> > > +      reg = <0x400000 0x200000>;
> > > +      clocks = <&clk 0>, <&clk 1>, <&clk 2>;
> > > +      clock-names = "vclk", "aclk", "hclk";
> > > +      interrupts = <0>;
> > > +
> > > +      ports {
> > > +        #address-cells = <1>;
> > > +        #size-cells = <0>;
> > > +
> > > +        port at 0 {
> > > +          reg = <0>;
> > > +          isp_in: endpoint {
> > > +              remote-endpoint = <&mipi_out>;
> > 
> > I suppose this is a CSI-2 interface with D-PHY?
> 
> No, that's an internal parallel bus. Depending on the SoC integration,
> it can be connected to a CSI-2 receiver, a DMA engine, or a mux to
> select between different sources.

The name suggests otherwise. Maybe change that to something more
descriptive?

> 
> > How many lanes do you have and is lane remapping / polarity inversion
> > supported?
> > 
> > This should be reflected in bindings.
> > 
> > > +          };
> > > +        };
> > > +      };
> > > +    };
> > > +...
> 

-- 
Regards,

Sakari Ailus


From mcanal at igalia.com  Mon Feb 26 04:23:23 2024
From: mcanal at igalia.com (=?UTF-8?Q?Ma=C3=ADra_Canal?=)
Date: Mon, 26 Feb 2024 09:23:23 -0300
Subject: [PATCH v7 02/36] drm/tests: helpers: Add atomic helpers
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-2-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-2-8f4af575fce2@kernel.org>
Message-ID: <ad133922-6f11-483f-94c9-12aa8c3189df@igalia.com>

On 2/22/24 15:13, Maxime Ripard wrote:
> The mock device we were creating was missing any of the driver-wide
> helpers. That was fine before since we weren't testing the atomic state
> path, but we're going to start, so let's use the default
> implementations.
> 
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Ma?ra Canal <mcanal at igalia.com>

Best Regards,
- Ma?ra

> ---
>   drivers/gpu/drm/tests/drm_kunit_helpers.c | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> index ca4f8e4c5d5d..4fb11b938bc1 100644
> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> @@ -1,6 +1,7 @@
>   // SPDX-License-Identifier: GPL-2.0
>   
>   #include <drm/drm_atomic.h>
> +#include <drm/drm_atomic_helper.h>
>   #include <drm/drm_drv.h>
>   #include <drm/drm_kunit_helpers.h>
>   #include <drm/drm_managed.h>
> @@ -14,6 +15,8 @@
>   #define KUNIT_DEVICE_NAME	"drm-kunit-mock-device"
>   
>   static const struct drm_mode_config_funcs drm_mode_config_funcs = {
> +	.atomic_check	= drm_atomic_helper_check,
> +	.atomic_commit	= drm_atomic_helper_commit,
>   };
>   
>   /**
> 


From mcanal at igalia.com  Mon Feb 26 04:24:38 2024
From: mcanal at igalia.com (=?UTF-8?Q?Ma=C3=ADra_Canal?=)
Date: Mon, 26 Feb 2024 09:24:38 -0300
Subject: [PATCH v7 03/36] drm/tests: Add helper to create mock plane
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-3-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-3-8f4af575fce2@kernel.org>
Message-ID: <664d9eca-a3f2-4a87-9a50-9c415781cef9@igalia.com>

On 2/22/24 15:13, Maxime Ripard wrote:
> We're going to need a full-blown, functional, KMS device to test more
> components of the atomic modesetting infrastructure.
> 
> Let's add a new helper to create a dumb, mocked, primary plane. By
> default, it will create a linear XRGB8888 plane, using the default
> helpers.
> 
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Ma?ra Canal <mcanal at igalia.com>

Best Regards,
- Ma?ra

> ---
>   drivers/gpu/drm/tests/drm_kunit_helpers.c | 85 +++++++++++++++++++++++++++++++
>   include/drm/drm_kunit_helpers.h           | 11 ++++
>   2 files changed, 96 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> index 4fb11b938bc1..32dc8354641a 100644
> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> @@ -3,6 +3,7 @@
>   #include <drm/drm_atomic.h>
>   #include <drm/drm_atomic_helper.h>
>   #include <drm/drm_drv.h>
> +#include <drm/drm_fourcc.h>
>   #include <drm/drm_kunit_helpers.h>
>   #include <drm/drm_managed.h>
>   
> @@ -164,5 +165,89 @@ drm_kunit_helper_atomic_state_alloc(struct kunit *test,
>   }
>   EXPORT_SYMBOL_GPL(drm_kunit_helper_atomic_state_alloc);
>   
> +static const uint32_t default_plane_formats[] = {
> +	DRM_FORMAT_XRGB8888,
> +};
> +
> +static const uint64_t default_plane_modifiers[] = {
> +	DRM_FORMAT_MOD_LINEAR,
> +	DRM_FORMAT_MOD_INVALID
> +};
> +
> +static const struct drm_plane_helper_funcs default_plane_helper_funcs = {
> +};
> +
> +static const struct drm_plane_funcs default_plane_funcs = {
> +	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
> +	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
> +	.reset			= drm_atomic_helper_plane_reset,
> +};
> +
> +/**
> + * drm_kunit_helper_create_primary_plane - Creates a mock primary plane for a KUnit test
> + * @test: The test context object
> + * @drm: The device to alloc the plane for
> + * @funcs: Callbacks for the new plane. Optional.
> + * @helper_funcs: Helpers callbacks for the new plane. Optional.
> + * @formats: array of supported formats (DRM_FORMAT\_\*). Optional.
> + * @num_formats: number of elements in @formats
> + * @modifiers: array of struct drm_format modifiers terminated by
> + *             DRM_FORMAT_MOD_INVALID. Optional.
> + *
> + * This allocates and initializes a mock struct &drm_plane meant to be
> + * part of a mock device for a KUnit test.
> + *
> + * Resources will be cleaned up automatically.
> + *
> + * @funcs will default to the default helpers implementations.
> + * @helper_funcs will default to an empty implementation. @formats will
> + * default to XRGB8888 only. @modifiers will default to a linear
> + * modifier only.
> + *
> + * Returns:
> + * A pointer to the new plane, or an ERR_PTR() otherwise.
> + */
> +struct drm_plane *
> +drm_kunit_helper_create_primary_plane(struct kunit *test,
> +				      struct drm_device *drm,
> +				      const struct drm_plane_funcs *funcs,
> +				      const struct drm_plane_helper_funcs *helper_funcs,
> +				      const uint32_t *formats,
> +				      unsigned int num_formats,
> +				      const uint64_t *modifiers)
> +{
> +	struct drm_plane *plane;
> +
> +	if (!funcs)
> +		funcs = &default_plane_funcs;
> +
> +	if (!helper_funcs)
> +		helper_funcs = &default_plane_helper_funcs;
> +
> +	if (!formats || !num_formats) {
> +		formats = default_plane_formats;
> +		num_formats = ARRAY_SIZE(default_plane_formats);
> +	}
> +
> +	if (!modifiers)
> +		modifiers = default_plane_modifiers;
> +
> +	plane = __drmm_universal_plane_alloc(drm,
> +					     sizeof(struct drm_plane), 0,
> +					     0,
> +					     funcs,
> +					     formats,
> +					     num_formats,
> +					     default_plane_modifiers,
> +					     DRM_PLANE_TYPE_PRIMARY,
> +					     NULL);
> +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
> +
> +	drm_plane_helper_add(plane, helper_funcs);
> +
> +	return plane;
> +}
> +EXPORT_SYMBOL_GPL(drm_kunit_helper_create_primary_plane);
> +
>   MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");
>   MODULE_LICENSE("GPL");
> diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
> index 3ae19892229d..38667d624aa8 100644
> --- a/include/drm/drm_kunit_helpers.h
> +++ b/include/drm/drm_kunit_helpers.h
> @@ -10,6 +10,8 @@
>   #include <kunit/test.h>
>   
>   struct drm_device;
> +struct drm_plane_funcs;
> +struct drm_plane_helper_funcs;
>   struct kunit;
>   
>   struct device *drm_kunit_helper_alloc_device(struct kunit *test);
> @@ -99,4 +101,13 @@ drm_kunit_helper_atomic_state_alloc(struct kunit *test,
>   				    struct drm_device *drm,
>   				    struct drm_modeset_acquire_ctx *ctx);
>   
> +struct drm_plane *
> +drm_kunit_helper_create_primary_plane(struct kunit *test,
> +				      struct drm_device *drm,
> +				      const struct drm_plane_funcs *funcs,
> +				      const struct drm_plane_helper_funcs *helper_funcs,
> +				      const uint32_t *formats,
> +				      unsigned int num_formats,
> +				      const uint64_t *modifiers);
> +
>   #endif // DRM_KUNIT_HELPERS_H_
> 


From david at redhat.com  Mon Feb 26 04:25:34 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 26 Feb 2024 13:25:34 +0100
Subject: [PATCH 1/2] arm64/mm: Export contpte symbols only to GPL users
In-Reply-To: <20240226120321.1055731-2-ryan.roberts@arm.com>
References: <20240226120321.1055731-1-ryan.roberts@arm.com>
 <20240226120321.1055731-2-ryan.roberts@arm.com>
Message-ID: <c9f00402-bb95-4fcf-a309-c36a5e68ec93@redhat.com>

On 26.02.24 13:03, Ryan Roberts wrote:
> The contpte symbols must be exported since some of the public inline
> ptep_* APIs are called from modules and these inlines now call the
> contpte functions. Originally they were exported as EXPORT_SYMBOL() for
> fear of breaking out-of-tree modules. But we subsequently concluded that
> EXPORT_SYMBOL_GPL() should be safe since these functions are deeply core
> mm routines, and any module operating at this level is not going to be
> able to survive on EXPORT_SYMBOL alone.
> 

I only looked at __set_ptes() to get a feeling what would currently work.

__set_ptes() might already call __sync_icache_dcache() via 
__sync_cache_and_tags(), that is EXPORT_SYMBOL_GPL.

[mte_sync_tags() is not exported at all, so maybe it's safe to assume 
that some out-of-tree module could not make good use of set_pte_at() in 
general]

Acked-by: David Hildenbrand <david at redhat.com>

-- 
Cheers,

David / dhildenb



From ada at thorsis.com  Mon Feb 26 04:25:37 2024
From: ada at thorsis.com (Alexander Dahl)
Date: Mon, 26 Feb 2024 13:25:37 +0100
Subject: [PATCH] mtd: nand: raw: atmel: Fix comment in timings preparation
Message-ID: <20240226122537.75097-1-ada@thorsis.com>

Looks like a copy'n'paste mistake introduced when initially adding the
dynamic timings feature with commit f9ce2eddf176 ("mtd: nand: atmel: Add
->setup_data_interface() hooks").  The context around this and
especially the code itself suggests 'read' is meant instead of write.

Signed-off-by: Alexander Dahl <ada at thorsis.com>
---
 drivers/mtd/nand/raw/atmel/nand-controller.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 4cb478bbee4a..dc75d50d52e8 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1370,23 +1370,23 @@ static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand,
 	 *
 	 * NRD_PULSE = tRP
 	 */
 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tRP_min, mckperiodps);
 	totalcycles += ncycles;
 	ret = atmel_smc_cs_conf_set_pulse(smcconf, ATMEL_SMC_NRD_SHIFT,
 					  ncycles);
 	if (ret)
 		return ret;
 
 	/*
-	 * The write cycle timing is directly matching tWC, but is also
+	 * The read cycle timing is directly matching tRC, but is also
 	 * dependent on the setup and hold timings we calculated earlier,
 	 * which gives:
 	 *
 	 * NRD_CYCLE = max(tRC, NRD_PULSE + NRD_HOLD)
 	 *
 	 * NRD_SETUP is always 0.
 	 */
 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tRC_min, mckperiodps);
 	ncycles = max(totalcycles, ncycles);
 	ret = atmel_smc_cs_conf_set_cycle(smcconf, ATMEL_SMC_NRD_SHIFT,
 					  ncycles);

base-commit: d206a76d7d2726f3b096037f2079ce0bd3ba329b
-- 
2.39.2



From Markus.Elfring at web.de  Mon Feb 26 04:26:26 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Mon, 26 Feb 2024 13:26:26 +0100
Subject: [PATCH] clk: mediatek: clk-mt8173-apmixedsys: Use common error
 handling code in clk_mt8173_apmixed_probe()
Message-ID: <6a64e7b3-b1ce-46c4-9c85-89f731aee592@web.de>

From: Markus Elfring <elfring at users.sourceforge.net>
Date: Mon, 26 Feb 2024 13:10:37 +0100

Add a label so that a bit of exception handling can be better reused
at the end of this function implementation.

Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>
---
 drivers/clk/mediatek/clk-mt8173-apmixedsys.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c
index 1bbb21ab1786..6cab483b8e1e 100644
--- a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c
+++ b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c
@@ -152,8 +152,8 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev)

 	clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
 	if (IS_ERR_OR_NULL(clk_data)) {
-		iounmap(base);
-		return -ENOMEM;
+		r = -ENOMEM;
+		goto unmap_io;
 	}

 	fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs));
@@ -188,6 +188,7 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev)
 				  ARRAY_SIZE(pllfhs), clk_data);
 free_clk_data:
 	mtk_free_clk_data(clk_data);
+unmap_io:
 	iounmap(base);
 	return r;
 }
--
2.43.2



From mcanal at igalia.com  Mon Feb 26 04:26:33 2024
From: mcanal at igalia.com (=?UTF-8?Q?Ma=C3=ADra_Canal?=)
Date: Mon, 26 Feb 2024 09:26:33 -0300
Subject: [PATCH v7 04/36] drm/tests: Add helper to create mock crtc
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-4-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-4-8f4af575fce2@kernel.org>
Message-ID: <4aab64fe-18ab-425b-9dc1-e4e9dc6b0087@igalia.com>

On 2/22/24 15:13, Maxime Ripard wrote:
> We're going to need a full-blown, functional, KMS device to test more
> components of the atomic modesetting infrastructure.
> 
> Let's add a new helper to create a dumb, mocked, CRTC. By default it
> will create a CRTC relying only on the default helpers, but drivers are
> free to deviate from that.
> 
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Ma?ra Canal <mcanal at igalia.com>

Best Regards,
- Ma?ra

> ---
>   drivers/gpu/drm/tests/drm_kunit_helpers.c | 62 +++++++++++++++++++++++++++++++
>   include/drm/drm_kunit_helpers.h           | 10 +++++
>   2 files changed, 72 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> index 32dc8354641a..d5317d13d3fc 100644
> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> @@ -249,5 +249,67 @@ drm_kunit_helper_create_primary_plane(struct kunit *test,
>   }
>   EXPORT_SYMBOL_GPL(drm_kunit_helper_create_primary_plane);
>   
> +static const struct drm_crtc_helper_funcs default_crtc_helper_funcs = {
> +};
> +
> +static const struct drm_crtc_funcs default_crtc_funcs = {
> +	.atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
> +	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> +	.reset                  = drm_atomic_helper_crtc_reset,
> +};
> +
> +/**
> + * drm_kunit_helper_create_crtc - Creates a mock CRTC for a KUnit test
> + * @test: The test context object
> + * @drm: The device to alloc the plane for
> + * @primary: Primary plane for CRTC
> + * @cursor: Cursor plane for CRTC. Optional.
> + * @funcs: Callbacks for the new plane. Optional.
> + * @helper_funcs: Helpers callbacks for the new plane. Optional.
> + *
> + * This allocates and initializes a mock struct &drm_crtc meant to be
> + * part of a mock device for a KUnit test.
> + *
> + * Resources will be cleaned up automatically.
> + *
> + * @funcs will default to the default helpers implementations.
> + * @helper_funcs will default to an empty implementation.
> + *
> + * Returns:
> + * A pointer to the new CRTC, or an ERR_PTR() otherwise.
> + */
> +struct drm_crtc *
> +drm_kunit_helper_create_crtc(struct kunit *test,
> +			     struct drm_device *drm,
> +			     struct drm_plane *primary,
> +			     struct drm_plane *cursor,
> +			     const struct drm_crtc_funcs *funcs,
> +			     const struct drm_crtc_helper_funcs *helper_funcs)
> +{
> +	struct drm_crtc *crtc;
> +	int ret;
> +
> +	if (!funcs)
> +		funcs = &default_crtc_funcs;
> +
> +	if (!helper_funcs)
> +		helper_funcs = &default_crtc_helper_funcs;
> +
> +	crtc = drmm_kzalloc(drm, sizeof(*crtc), GFP_KERNEL);
> +	KUNIT_ASSERT_NOT_NULL(test, crtc);
> +
> +	ret = drmm_crtc_init_with_planes(drm, crtc,
> +					 primary,
> +					 cursor,
> +					 funcs,
> +					 NULL);
> +	KUNIT_ASSERT_EQ(test, ret, 0);
> +
> +	drm_crtc_helper_add(crtc, helper_funcs);
> +
> +	return crtc;
> +}
> +EXPORT_SYMBOL_GPL(drm_kunit_helper_create_crtc);
> +
>   MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");
>   MODULE_LICENSE("GPL");
> diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
> index 38667d624aa8..6e99627edf45 100644
> --- a/include/drm/drm_kunit_helpers.h
> +++ b/include/drm/drm_kunit_helpers.h
> @@ -9,6 +9,8 @@
>   
>   #include <kunit/test.h>
>   
> +struct drm_crtc_funcs;
> +struct drm_crtc_helper_funcs;
>   struct drm_device;
>   struct drm_plane_funcs;
>   struct drm_plane_helper_funcs;
> @@ -110,4 +112,12 @@ drm_kunit_helper_create_primary_plane(struct kunit *test,
>   				      unsigned int num_formats,
>   				      const uint64_t *modifiers);
>   
> +struct drm_crtc *
> +drm_kunit_helper_create_crtc(struct kunit *test,
> +			     struct drm_device *drm,
> +			     struct drm_plane *primary,
> +			     struct drm_plane *cursor,
> +			     const struct drm_crtc_funcs *funcs,
> +			     const struct drm_crtc_helper_funcs *helper_funcs);
> +
>   #endif // DRM_KUNIT_HELPERS_H_
> 


From mcanal at igalia.com  Mon Feb 26 04:27:36 2024
From: mcanal at igalia.com (=?UTF-8?Q?Ma=C3=ADra_Canal?=)
Date: Mon, 26 Feb 2024 09:27:36 -0300
Subject: [PATCH v7 05/36] drm/tests: connector: Add tests for
 drmm_connector_init
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-5-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-5-8f4af575fce2@kernel.org>
Message-ID: <f078cbc0-f8bd-4e14-9395-09afa851a070@igalia.com>

On 2/22/24 15:13, Maxime Ripard wrote:
> drmm_connector_init is the preferred function to initialize a
> drm_connector structure. Let's add a bunch of unit tests for it.
> 
> Signed-off-by: Maxime Ripard <mripard at kernel.org>

Reviewed-by: Ma?ra Canal <mcanal at igalia.com>

Best Regards,
- Ma?ra

> ---
>   drivers/gpu/drm/tests/drm_connector_test.c | 170 ++++++++++++++++++++++++++++-
>   1 file changed, 169 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
> index c66aa2dc8d9d..a268847be8d1 100644
> --- a/drivers/gpu/drm/tests/drm_connector_test.c
> +++ b/drivers/gpu/drm/tests/drm_connector_test.c
> @@ -3,10 +3,175 @@
>    * Kunit test for drm_modes functions
>    */
>   
> +#include <linux/i2c.h>
> +
> +#include <drm/drm_atomic_state_helper.h>
>   #include <drm/drm_connector.h>
> +#include <drm/drm_drv.h>
> +#include <drm/drm_kunit_helpers.h>
>   
>   #include <kunit/test.h>
>   
> +struct drm_connector_init_priv {
> +	struct drm_device drm;
> +	struct drm_connector connector;
> +	struct i2c_adapter ddc;
> +};
> +
> +static const struct drm_connector_funcs dummy_funcs = {
> +	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
> +	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
> +	.reset			= drm_atomic_helper_connector_reset,
> +};
> +
> +static int dummy_ddc_xfer(struct i2c_adapter *adapter,
> +			  struct i2c_msg *msgs, int num)
> +{
> +	return num;
> +}
> +
> +static u32 dummy_ddc_func(struct i2c_adapter *adapter)
> +{
> +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
> +}
> +
> +static const struct i2c_algorithm dummy_ddc_algorithm = {
> +	.master_xfer = dummy_ddc_xfer,
> +	.functionality = dummy_ddc_func,
> +};
> +
> +static void i2c_del_adapter_wrapper(void *ptr)
> +{
> +	struct i2c_adapter *adap = ptr;
> +
> +	i2c_del_adapter(adap);
> +}
> +
> +static int drm_test_connector_init(struct kunit *test)
> +{
> +	struct drm_connector_init_priv *priv;
> +	struct device *dev;
> +	int ret;
> +
> +	dev = drm_kunit_helper_alloc_device(test);
> +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
> +
> +	priv = drm_kunit_helper_alloc_drm_device(test, dev,
> +						 struct drm_connector_init_priv, drm,
> +						 DRIVER_MODESET | DRIVER_ATOMIC);
> +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
> +
> +	strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name));
> +	priv->ddc.owner = THIS_MODULE;
> +	priv->ddc.algo = &dummy_ddc_algorithm;
> +	priv->ddc.dev.parent = dev;
> +
> +	ret = i2c_add_adapter(&priv->ddc);
> +	KUNIT_ASSERT_EQ(test, ret, 0);
> +
> +	ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc);
> +	KUNIT_ASSERT_EQ(test, ret, 0);
> +
> +	test->priv = priv;
> +	return 0;
> +}
> +
> +/*
> + * Test that the registration of a bog standard connector works as
> + * expected and doesn't report any error.
> + */
> +static void drm_test_drmm_connector_init(struct kunit *test)
> +{
> +	struct drm_connector_init_priv *priv = test->priv;
> +	int ret;
> +
> +	ret = drmm_connector_init(&priv->drm, &priv->connector,
> +				  &dummy_funcs,
> +				  DRM_MODE_CONNECTOR_HDMIA,
> +				  &priv->ddc);
> +	KUNIT_EXPECT_EQ(test, ret, 0);
> +}
> +
> +/*
> + * Test that the registration of a connector without a DDC adapter
> + * doesn't report any error.
> + */
> +static void drm_test_drmm_connector_init_null_ddc(struct kunit *test)
> +{
> +	struct drm_connector_init_priv *priv = test->priv;
> +	int ret;
> +
> +	ret = drmm_connector_init(&priv->drm, &priv->connector,
> +				  &dummy_funcs,
> +				  DRM_MODE_CONNECTOR_HDMIA,
> +				  NULL);
> +	KUNIT_EXPECT_EQ(test, ret, 0);
> +}
> +
> +/*
> + * Test that the registration of a connector succeeds for all possible
> + * connector types.
> + */
> +static void drm_test_drmm_connector_init_type_valid(struct kunit *test)
> +{
> +       struct drm_connector_init_priv *priv = test->priv;
> +       unsigned int connector_type = *(unsigned int *)test->param_value;
> +       int ret;
> +
> +       ret = drmm_connector_init(&priv->drm, &priv->connector,
> +				 &dummy_funcs,
> +				 connector_type,
> +				 &priv->ddc);
> +       KUNIT_EXPECT_EQ(test, ret, 0);
> +}
> +
> +static const unsigned int drm_connector_init_type_valid_tests[] = {
> +	DRM_MODE_CONNECTOR_Unknown,
> +	DRM_MODE_CONNECTOR_VGA,
> +	DRM_MODE_CONNECTOR_DVII,
> +	DRM_MODE_CONNECTOR_DVID,
> +	DRM_MODE_CONNECTOR_DVIA,
> +	DRM_MODE_CONNECTOR_Composite,
> +	DRM_MODE_CONNECTOR_SVIDEO,
> +	DRM_MODE_CONNECTOR_LVDS,
> +	DRM_MODE_CONNECTOR_Component,
> +	DRM_MODE_CONNECTOR_9PinDIN,
> +	DRM_MODE_CONNECTOR_DisplayPort,
> +	DRM_MODE_CONNECTOR_HDMIA,
> +	DRM_MODE_CONNECTOR_HDMIB,
> +	DRM_MODE_CONNECTOR_TV,
> +	DRM_MODE_CONNECTOR_eDP,
> +	DRM_MODE_CONNECTOR_VIRTUAL,
> +	DRM_MODE_CONNECTOR_DSI,
> +	DRM_MODE_CONNECTOR_DPI,
> +	DRM_MODE_CONNECTOR_WRITEBACK,
> +	DRM_MODE_CONNECTOR_SPI,
> +	DRM_MODE_CONNECTOR_USB,
> +};
> +
> +static void drm_connector_init_type_desc(const unsigned int *type, char *desc)
> +{
> +	sprintf(desc, "%s", drm_get_connector_type_name(*type));
> +}
> +
> +KUNIT_ARRAY_PARAM(drm_connector_init_type_valid,
> +		  drm_connector_init_type_valid_tests,
> +		  drm_connector_init_type_desc);
> +
> +static struct kunit_case drmm_connector_init_tests[] = {
> +	KUNIT_CASE(drm_test_drmm_connector_init),
> +	KUNIT_CASE(drm_test_drmm_connector_init_null_ddc),
> +	KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid,
> +			 drm_connector_init_type_valid_gen_params),
> +	{ }
> +};
> +
> +static struct kunit_suite drmm_connector_init_test_suite = {
> +	.name = "drmm_connector_init",
> +	.init = drm_test_connector_init,
> +	.test_cases = drmm_connector_init_tests,
> +};
> +
>   struct drm_get_tv_mode_from_name_test {
>   	const char *name;
>   	enum drm_connector_tv_mode expected_mode;
> @@ -70,7 +235,10 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
>   	.test_cases = drm_get_tv_mode_from_name_tests,
>   };
>   
> -kunit_test_suite(drm_get_tv_mode_from_name_test_suite);
> +kunit_test_suites(
> +	&drmm_connector_init_test_suite,
> +	&drm_get_tv_mode_from_name_test_suite
> +);
>   
>   MODULE_AUTHOR("Maxime Ripard <maxime at cerno.tech>");
>   MODULE_LICENSE("GPL");
> 


From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:28:20 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:28:20 +0100
Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_WAN_ONLINE for
 Internet access
In-Reply-To: <20240223112223.1368-1-zajec5@gmail.com>
References: <20240223112223.1368-1-zajec5@gmail.com>
Message-ID: <3756ad5e-7c05-4502-9a6a-ffb58c76390e@collabora.com>

Il 23/02/24 12:22, Rafa? Mi?ecki ha scritto:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> It's common for routers to have LED indicating link on the WAN port.
> 
> Some devices however have an extra LED that's meant to be used if WAN
> connection is actually "online" (there is Internet access available).
> 
> It was suggested to add #define for such use case.

In this case, you can use the Suggested-by tag, but I'm not picky anyway :-)

> 
> Link: https://lore.kernel.org/linux-devicetree/80e92209-5578-44e7-bd4b-603a29053ddf at collabora.com/T/#u
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From krzysztof.kozlowski at linaro.org  Mon Feb 26 04:29:34 2024
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Mon, 26 Feb 2024 13:29:34 +0100
Subject: [PATCH] dt-bindings: input: allwinner,sun4i-a10-lrad: drop redundant type from label
Message-ID: <20240226122934.89257-1-krzysztof.kozlowski@linaro.org>

dtschema defines label as string, so $ref in other bindings is
redundant.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../bindings/input/allwinner,sun4i-a10-lradc-keys.yaml           | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
index 5efceb313879..c384bf0bb25d 100644
--- a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
+++ b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
@@ -49,7 +49,6 @@ patternProperties:
     $ref: input.yaml#
     properties:
       label:
-        $ref: /schemas/types.yaml#/definitions/string
         description: Descriptive name of the key
 
       linux,code: true
-- 
2.34.1



From mcanal at igalia.com  Mon Feb 26 04:29:32 2024
From: mcanal at igalia.com (=?UTF-8?Q?Ma=C3=ADra_Canal?=)
Date: Mon, 26 Feb 2024 09:29:32 -0300
Subject: [PATCH v7 29/36] drm/vc4: tests: Remove vc4_dummy_plane structure
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-29-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-29-8f4af575fce2@kernel.org>
Message-ID: <244fe6b9-f295-4c85-908a-014ada0033fa@igalia.com>

On 2/22/24 15:14, Maxime Ripard wrote:
> The vc4_dummy_plane structure is an exact equivalent to vc4_plane, so we

Maybe I understood incorrectly, but isn't the vc4_dummy_plane structure 
equivalent to drm_plane?

Best Regards,
- Ma?ra

> don't need it.
> 
> Signed-off-by: Maxime Ripard <mripard at kernel.org>
> ---
>   drivers/gpu/drm/vc4/tests/vc4_mock.c       |  6 ++----
>   drivers/gpu/drm/vc4/tests/vc4_mock.h       |  9 ++-------
>   drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 14 +++++---------
>   3 files changed, 9 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.c b/drivers/gpu/drm/vc4/tests/vc4_mock.c
> index becb3dbaa548..0731a7d85d7a 100644
> --- a/drivers/gpu/drm/vc4/tests/vc4_mock.c
> +++ b/drivers/gpu/drm/vc4/tests/vc4_mock.c
> @@ -109,16 +109,14 @@ static const struct vc4_mock_desc vc5_mock =
>   static int __build_one_pipe(struct kunit *test, struct drm_device *drm,
>   			    const struct vc4_mock_pipe_desc *pipe)
>   {
> -	struct vc4_dummy_plane *dummy_plane;
>   	struct drm_plane *plane;
>   	struct vc4_dummy_crtc *dummy_crtc;
>   	struct drm_crtc *crtc;
>   	unsigned int i;
>   
> -	dummy_plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
> -	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
> +	plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
> +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
>   
> -	plane = &dummy_plane->plane.base;
>   	dummy_crtc = vc4_mock_pv(test, drm, plane, pipe->data);
>   	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc);
>   
> diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.h b/drivers/gpu/drm/vc4/tests/vc4_mock.h
> index 2d0b339bd9f3..002b6218960c 100644
> --- a/drivers/gpu/drm/vc4/tests/vc4_mock.h
> +++ b/drivers/gpu/drm/vc4/tests/vc4_mock.h
> @@ -21,13 +21,8 @@ struct drm_crtc *vc4_find_crtc_for_encoder(struct kunit *test,
>   	return NULL;
>   }
>   
> -struct vc4_dummy_plane {
> -	struct vc4_plane plane;
> -};
> -
> -struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
> -					struct drm_device *drm,
> -					enum drm_plane_type type);
> +struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
> +				  enum drm_plane_type type);
>   
>   struct vc4_dummy_crtc {
>   	struct vc4_crtc crtc;
> diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
> index 62b18f5f41db..973f5f929097 100644
> --- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
> +++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
> @@ -22,15 +22,12 @@ static const uint32_t vc4_dummy_plane_formats[] = {
>   	DRM_FORMAT_XRGB8888,
>   };
>   
> -struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
> -					struct drm_device *drm,
> -					enum drm_plane_type type)
> +struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
> +				  enum drm_plane_type type)
>   {
> -	struct vc4_dummy_plane *dummy_plane;
>   	struct drm_plane *plane;
>   
> -	dummy_plane = drmm_universal_plane_alloc(drm,
> -						 struct vc4_dummy_plane, plane.base,
> +	plane = __drmm_universal_plane_alloc(drm, sizeof(struct drm_plane), 0,
>   						 0,
>   						 &vc4_dummy_plane_funcs,
>   						 vc4_dummy_plane_formats,
> @@ -38,10 +35,9 @@ struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
>   						 NULL,
>   						 DRM_PLANE_TYPE_PRIMARY,
>   						 NULL);
> -	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
> +	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
>   
> -	plane = &dummy_plane->plane.base;
>   	drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs);
>   
> -	return dummy_plane;
> +	return plane;
>   }
> 


From david at redhat.com  Mon Feb 26 04:30:10 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 26 Feb 2024 13:30:10 +0100
Subject: [PATCH 2/2] arm64/mm: Improve comment in
 contpte_ptep_get_lockless()
In-Reply-To: <20240226120321.1055731-3-ryan.roberts@arm.com>
References: <20240226120321.1055731-1-ryan.roberts@arm.com>
 <20240226120321.1055731-3-ryan.roberts@arm.com>
Message-ID: <4f215e3f-3395-4fab-b938-07a6d9e0a662@redhat.com>

On 26.02.24 13:03, Ryan Roberts wrote:
> Make clear the atmicity/consistency requirements of the API and how we
> achieve them.
> 
> Link: https://lore.kernel.org/linux-mm/Zc-Tqqfksho3BHmU at arm.com/
> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
> ---
>   arch/arm64/mm/contpte.c | 24 ++++++++++++++----------
>   1 file changed, 14 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
> index be0a226c4ff9..1b64b4c3f8bf 100644
> --- a/arch/arm64/mm/contpte.c
> +++ b/arch/arm64/mm/contpte.c
> @@ -183,16 +183,20 @@ EXPORT_SYMBOL_GPL(contpte_ptep_get);
>   pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
>   {
>   	/*
> -	 * Gather access/dirty bits, which may be populated in any of the ptes
> -	 * of the contig range. We may not be holding the PTL, so any contiguous
> -	 * range may be unfolded/modified/refolded under our feet. Therefore we
> -	 * ensure we read a _consistent_ contpte range by checking that all ptes
> -	 * in the range are valid and have CONT_PTE set, that all pfns are
> -	 * contiguous and that all pgprots are the same (ignoring access/dirty).
> -	 * If we find a pte that is not consistent, then we must be racing with
> -	 * an update so start again. If the target pte does not have CONT_PTE
> -	 * set then that is considered consistent on its own because it is not
> -	 * part of a contpte range.
> +	 * The ptep_get_lockless() API requires us to read and return *orig_ptep
> +	 * so that it is self-consistent, without the PTL held, so we may be
> +	 * racing with other threads modifying the pte. Usually a READ_ONCE()
> +	 * would suffice, but for the contpte case, we also need to gather the
> +	 * access and dirty bits from across all ptes in the contiguous block,
> +	 * and we can't read all of those neighbouring ptes atomically, so any
> +	 * contiguous range may be unfolded/modified/refolded under our feet.
> +	 * Therefore we ensure we read a _consistent_ contpte range by checking
> +	 * that all ptes in the range are valid and have CONT_PTE set, that all
> +	 * pfns are contiguous and that all pgprots are the same (ignoring
> +	 * access/dirty). If we find a pte that is not consistent, then we must
> +	 * be racing with an update so start again. If the target pte does not
> +	 * have CONT_PTE set then that is considered consistent on its own
> +	 * because it is not part of a contpte range.
>   	 */
>   
>   	pgprot_t orig_prot;

Reviewed-by: David Hildenbrand <david at redhat.com>

In an ideal world, we'd really not rely on any accessed/dirty on the 
lockless path and remove contpte_ptep_get_lockless() completely :)

-- 
Cheers,

David / dhildenb



From monstr at monstr.eu  Mon Feb 26 04:30:34 2024
From: monstr at monstr.eu (Michal Simek)
Date: Mon, 26 Feb 2024 13:30:34 +0100
Subject: [GIT PULL] arm64: ZynqMP DT changes for v6.9
Message-ID: <CAHTX3dLEoFMTGg1Q4+OuOwWYd8N73YBTXki8Vvj3cGHUpLJ0=A@mail.gmail.com>

Hi,

please pull these DT changes to your tree. There are some SoC related
dt binding changes and associated DT changes. Also followed by some
small updates.
All the changes have been checked against DT schema but there are
still some older descriptions which should be updated in future.

Thanks,
Michal


The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://github.com/Xilinx/linux-xlnx.git tags/zynqmp-dt-for-6.9

for you to fetch changes up to d8764d347bd737efec00fae81133ffad0ae084bb:

  dt-bindings: firmware: xilinx: Describe soc-nvmem subnode
(2024-02-06 08:01:32 +0100)

----------------------------------------------------------------
arm64: ZynqMP DT changes for 6.9

dt-bindings:
- Describe firmware for Versal NET
- Describe all firmware child nodes
- Align versal-fpga node name with dt schema
- Describe k26 rev2 and kv260

DTs:
- Align firmware node with dt schema
- Add an optee node
- Describe reset for CANs
- Update ECAM size to discover up to 256 buses
- Describe assigned-clocks for uarts
- Add u-boot node
- Comment SMMU entries
- Align dwc3 nodes with dt schema
- Rename i2c groups to match dt schema
- Small DT updates (comments)
- Fix default clock frequency for si570 (zcu102, zcu106)
- Add output-enable pins and cover MIO38 (SOM)

----------------------------------------------------------------
Ilias Apalodimas (1):
      arm64: zynqmp: Add an OP-TEE node to the device tree

Jay Buddhabhatti (1):
      dt-bindings: firmware: versal: add versal-net compatible string

Michal Simek (15):
      dt-bindings: firmware: xilinx: Fix versal-fpga node name
      dt-bindings: firmware: xilinx: Describe missing child nodes
      dt-bindings: firmware: xilinx: Sort node names (clock-controller)
      arm64: zynqmp: Rename zynqmp-power node to power-management
      arm64: zynqmp: Setup default si570 frequency to 156.25MHz
      arm64: zynqmp: Describe assigned-clocks for uarts
      arm64: zynqmp: Fix comment to be aligned with board name.
      arm64: zynqmp: Introduce u-boot options node with bootscr-address
      arm64: zynqmp: Remove incorrect comment from kv260s
      arm64: zynqmp: Rename i2c?-gpio to i2c?-gpio-grp
      arm64: zynqmp: Comment all smmu entries
      arm64: zynqmp: Align usb clock nodes with binding
      dt-bindings: soc: xilinx: Add support for K26 rev2 SOMs
      dt-bindings: soc: xilinx: Add support for KV260 CC
      dt-bindings: firmware: xilinx: Describe soc-nvmem subnode

Neal Frager (1):
      arm64: zynqmp: Add output-enable pins to SOMs

Srinivas Neeli (1):
      arm64: zynqmp: Add resets property for CAN nodes

Tejas Bhumkar (1):
      arm64: zynqmp: Disable Tri-state for MIO38 Pin

Thippeswamy Havalige (1):
      arm64: zynqmp: Update ECAM size to discover up to 256 buses

 Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.yaml
| 96 +++++++++++++++++---
 Documentation/devicetree/bindings/fpga/xlnx,versal-fpga.yaml
      |  2 +-
 Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml
      | 70 ++++++++++++--
 arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
      | 16 +++-
 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso
      | 36 +++++++-
 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso
      | 37 +++++++-
 arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
      |  2 +-
 arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
      |  2 +-
 arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts
      |  4 +-
 arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
      |  2 +-
 arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
      |  6 +-
 arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
      |  2 +-
 arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
      |  2 +-
 arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
      |  6 +-
 arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
      |  4 +-
 arch/arm64/boot/dts/xilinx/zynqmp-zcu1275-revA.dts
      |  2 +-
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi
      | 85 ++++++++++-------
 17 files changed, 295 insertions(+), 79 deletions(-)


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


From mcanal at igalia.com  Mon Feb 26 04:30:24 2024
From: mcanal at igalia.com (=?UTF-8?Q?Ma=C3=ADra_Canal?=)
Date: Mon, 26 Feb 2024 09:30:24 -0300
Subject: [PATCH v7 30/36] drm/vc4: tests: Convert to plane creation helper
In-Reply-To: <20240222-kms-hdmi-connector-state-v7-30-8f4af575fce2@kernel.org>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <20240222-kms-hdmi-connector-state-v7-30-8f4af575fce2@kernel.org>
Message-ID: <1c91ff55-e6c6-4543-bbf5-c7543cc03979@igalia.com>

On 2/22/24 15:14, Maxime Ripard wrote:
> Now that we have a plane create helper for kunit mocked drivers, let's
> convert to it in vc4.

Reviewed-by: Ma?ra Canal <mcanal at igalia.com>

Best Regards,
- Ma?ra

> 
> Signed-off-by: Maxime Ripard <mripard at kernel.org>
> ---
>   drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 34 +++++++-----------------------
>   1 file changed, 8 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
> index 973f5f929097..14357db82238 100644
> --- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
> +++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
> @@ -1,43 +1,25 @@
>   // SPDX-License-Identifier: GPL-2.0
>   
> -#include <drm/drm_atomic_state_helper.h>
> -#include <drm/drm_fourcc.h>
> -#include <drm/drm_modeset_helper_vtables.h>
> +#include <drm/drm_kunit_helpers.h>
>   #include <drm/drm_plane.h>
>   
>   #include <kunit/test.h>
>   
>   #include "vc4_mock.h"
>   
> -static const struct drm_plane_helper_funcs vc4_dummy_plane_helper_funcs = {
> -};
> -
> -static const struct drm_plane_funcs vc4_dummy_plane_funcs = {
> -	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
> -	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
> -	.reset			= drm_atomic_helper_plane_reset,
> -};
> -
> -static const uint32_t vc4_dummy_plane_formats[] = {
> -	DRM_FORMAT_XRGB8888,
> -};
> -
>   struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
>   				  enum drm_plane_type type)
>   {
>   	struct drm_plane *plane;
>   
> -	plane = __drmm_universal_plane_alloc(drm, sizeof(struct drm_plane), 0,
> -						 0,
> -						 &vc4_dummy_plane_funcs,
> -						 vc4_dummy_plane_formats,
> -						 ARRAY_SIZE(vc4_dummy_plane_formats),
> -						 NULL,
> -						 DRM_PLANE_TYPE_PRIMARY,
> -						 NULL);
> +	KUNIT_ASSERT_EQ(test, type, DRM_PLANE_TYPE_PRIMARY);
> +
> +	plane = drm_kunit_helper_create_primary_plane(test, drm,
> +						      NULL,
> +						      NULL,
> +						      NULL, 0,
> +						      NULL);
>   	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
>   
> -	drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs);
> -
>   	return plane;
>   }
> 


From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:33:56 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:33:56 +0100
Subject: [PATCH] clk: mediatek: clk-mt8173-apmixedsys: Use common error
 handling code in clk_mt8173_apmixed_probe()
In-Reply-To: <6a64e7b3-b1ce-46c4-9c85-89f731aee592@web.de>
References: <6a64e7b3-b1ce-46c4-9c85-89f731aee592@web.de>
Message-ID: <7866fd9b-6f68-402d-abdf-087b1088d28b@collabora.com>

Il 26/02/24 13:26, Markus Elfring ha scritto:
> From: Markus Elfring <elfring at users.sourceforge.net>
> Date: Mon, 26 Feb 2024 13:10:37 +0100
> 
> Add a label so that a bit of exception handling can be better reused
> at the end of this function implementation.
> 
> Signed-off-by: Markus Elfring <elfring at users.sourceforge.net>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>




From ryan.roberts at arm.com  Mon Feb 26 04:37:29 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 26 Feb 2024 12:37:29 +0000
Subject: [PATCH 2/2] arm64/mm: Improve comment in
 contpte_ptep_get_lockless()
In-Reply-To: <4f215e3f-3395-4fab-b938-07a6d9e0a662@redhat.com>
References: <20240226120321.1055731-1-ryan.roberts@arm.com>
 <20240226120321.1055731-3-ryan.roberts@arm.com>
 <4f215e3f-3395-4fab-b938-07a6d9e0a662@redhat.com>
Message-ID: <8cda557a-cbf0-4926-be19-454cefdb4fdb@arm.com>

On 26/02/2024 12:30, David Hildenbrand wrote:
> On 26.02.24 13:03, Ryan Roberts wrote:
>> Make clear the atmicity/consistency requirements of the API and how we
>> achieve them.
>>
>> Link: https://lore.kernel.org/linux-mm/Zc-Tqqfksho3BHmU at arm.com/
>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>> ---
>> ? arch/arm64/mm/contpte.c | 24 ++++++++++++++----------
>> ? 1 file changed, 14 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
>> index be0a226c4ff9..1b64b4c3f8bf 100644
>> --- a/arch/arm64/mm/contpte.c
>> +++ b/arch/arm64/mm/contpte.c
>> @@ -183,16 +183,20 @@ EXPORT_SYMBOL_GPL(contpte_ptep_get);
>> ? pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
>> ? {
>> ????? /*
>> -???? * Gather access/dirty bits, which may be populated in any of the ptes
>> -???? * of the contig range. We may not be holding the PTL, so any contiguous
>> -???? * range may be unfolded/modified/refolded under our feet. Therefore we
>> -???? * ensure we read a _consistent_ contpte range by checking that all ptes
>> -???? * in the range are valid and have CONT_PTE set, that all pfns are
>> -???? * contiguous and that all pgprots are the same (ignoring access/dirty).
>> -???? * If we find a pte that is not consistent, then we must be racing with
>> -???? * an update so start again. If the target pte does not have CONT_PTE
>> -???? * set then that is considered consistent on its own because it is not
>> -???? * part of a contpte range.
>> +???? * The ptep_get_lockless() API requires us to read and return *orig_ptep
>> +???? * so that it is self-consistent, without the PTL held, so we may be
>> +???? * racing with other threads modifying the pte. Usually a READ_ONCE()
>> +???? * would suffice, but for the contpte case, we also need to gather the
>> +???? * access and dirty bits from across all ptes in the contiguous block,
>> +???? * and we can't read all of those neighbouring ptes atomically, so any
>> +???? * contiguous range may be unfolded/modified/refolded under our feet.
>> +???? * Therefore we ensure we read a _consistent_ contpte range by checking
>> +???? * that all ptes in the range are valid and have CONT_PTE set, that all
>> +???? * pfns are contiguous and that all pgprots are the same (ignoring
>> +???? * access/dirty). If we find a pte that is not consistent, then we must
>> +???? * be racing with an update so start again. If the target pte does not
>> +???? * have CONT_PTE set then that is considered consistent on its own
>> +???? * because it is not part of a contpte range.
>> ?????? */
>> ? ????? pgprot_t orig_prot;
> 
> Reviewed-by: David Hildenbrand <david at redhat.com>

Thanks!

> 
> In an ideal world, we'd really not rely on any accessed/dirty on the lockless
> path and remove contpte_ptep_get_lockless() completely :)

Not sure if you saw my RFC to do exactly that? (well, it doesn't actually remove
[contpte_]ptep_get_lockless() but it does remove all the callers). If you have
any feedback, we could get this moving...

https://lore.kernel.org/linux-mm/20240215121756.2734131-1-ryan.roberts at arm.com/

Thanks,
Ryan




From geert at linux-m68k.org  Mon Feb 26 04:37:34 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 26 Feb 2024 13:37:34 +0100
Subject: [PATCH] arm64: defconfig: Enable Renesas RZ/G2L display unit DRM driver
In-Reply-To: <20240223123646.245655-1-biju.das.jz@bp.renesas.com>
References: <20240223123646.245655-1-biju.das.jz@bp.renesas.com>
Message-ID: <CAMuHMdUE5q+hky7Z5os0uyC64evFYcuU+2RqTP=wghFf9ux2Cg@mail.gmail.com>

On Fri, Feb 23, 2024 at 1:36?PM Biju Das <biju.das.jz at bp.renesas.com> wrote:
> Enable the RZ/G2L display unit DRM driver used in RZ/{G2L,G2LC,V2L} SMARC
> EVK development boards.
>
> Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
i.e. will queue in renesas-devel for v6.10.

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  Mon Feb 26 04:39:15 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:15 +0100
Subject: [PATCH 10/11] drm/mediatek: Rename mtk_ddp_comp functions
In-Reply-To: <20240226085059.26850-11-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-11-shawn.sung@mediatek.com>
Message-ID: <3354332e-7e9c-4caf-a38a-a7b26eba76cc@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename functions of mtk_ddp_comp:
> - To align the naming rule
> - To reduce the code size
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:39:16 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:16 +0100
Subject: [PATCH 09/11] drm/mediatek: Rename files "mtk_drm_gem.*" to
 "mtk_gem.*"
In-Reply-To: <20240226085059.26850-10-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-10-shawn.sung@mediatek.com>
Message-ID: <4a17e974-ca9c-41b4-aa5c-2d41598120a6@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename files mtk_drm_gem.* to mtk_gem.*.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:39:17 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:17 +0100
Subject: [PATCH 08/11] drm/mediatek: Rename files "mtk_drm_plane.*" to
 "mtk_plane.*"
In-Reply-To: <20240226085059.26850-9-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-9-shawn.sung@mediatek.com>
Message-ID: <9e007c06-333c-4618-98a5-17eb9283fda3@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename files mtk_drm_plane.* to mtk_plane.*.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:39:19 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:19 +0100
Subject: [PATCH 07/11] drm/mediatek: Rename files "mtk_drm_ddp_comp.*" to
 "mtk_ddp_comp.*"
In-Reply-To: <20240226085059.26850-8-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-8-shawn.sung@mediatek.com>
Message-ID: <ad23e108-85f2-4f0c-b281-99140e6f20a0@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename files mtk_drm_ddp_comp.* to mtk_ddp_comp.*.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:39:19 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:19 +0100
Subject: [PATCH 06/11] drm/mediatek: Rename files "mtk_drm_crtc.*" to
 "mtk_crtc.*"
In-Reply-To: <20240226085059.26850-7-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-7-shawn.sung@mediatek.com>
Message-ID: <ab0e22c5-3ee3-40c5-8bef-313ec7a28a50@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename files mtk_drm_crtc.* to mtk_crtc.*.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:39:20 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:20 +0100
Subject: [PATCH 04/11] drm/mediatek: Rename "mtk_drm_gem" to "mtk_gem"
In-Reply-To: <20240226085059.26850-5-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-5-shawn.sung@mediatek.com>
Message-ID: <2a980f3b-616a-4371-8799-818367f7f65c@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename all "mtk_drm_gem" to "mtk_gem":
> - To align the naming rule
> - To reduce the code size
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:39:21 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:21 +0100
Subject: [PATCH 03/11] drm/mediatek: Rename "mtk_drm_plane" to "mtk_plane"
In-Reply-To: <20240226085059.26850-4-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-4-shawn.sung@mediatek.com>
Message-ID: <db96c6cb-2d7c-4a9e-8763-d2055da3a442@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename all "mtk_drm_plane" to "mtk_plane":
> - To align the naming rule
> - To reduce the code size
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:39:22 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:22 +0100
Subject: [PATCH 02/11] drm/mediatek: Rename "mtk_drm_ddp_comp" to
 "mtk_ddp_comp"
In-Reply-To: <20240226085059.26850-3-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-3-shawn.sung@mediatek.com>
Message-ID: <89659b2c-5521-4328-86b0-1bcf967693ae@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename all "mtk_drm_ddp_comp" to "mtk_ddp_comp":
> - To align the naming rule
> - To reduce the code size
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:39:24 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:24 +0100
Subject: [PATCH 01/11] drm/mediatek: Rename "mtk_drm_crtc" to "mtk_crtc"
In-Reply-To: <20240226085059.26850-2-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-2-shawn.sung@mediatek.com>
Message-ID: <93fdbd08-2096-44f8-a623-b85e0ebe9ecd@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename all "mtk_drm_crtc" to "mtk_crtc" due to the following benefits:
> - Lower the matches when searching the native drm_crtc* codes
> - Reduce the code size
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:39:27 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:27 +0100
Subject: [PATCH 05/11] drm/mediatek: Rename "mtk_drm_hdmi" to "mtk_hdmi"
In-Reply-To: <20240226085059.26850-6-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-6-shawn.sung@mediatek.com>
Message-ID: <e36b420e-28b4-4544-b877-75e0ddcd0abb@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename all "mtk_drm_hdmi" to "mtk_hdmi":
> - To align the naming rule
> - To reduce the code size
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>

Reviewed-by: AngeloGiaocchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Feb 26 04:39:28 2024
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 26 Feb 2024 13:39:28 +0100
Subject: [PATCH 11/11] drm/mediatek: Rename "pending_needs_vblank" to
 "needs_vblank"
In-Reply-To: <20240226085059.26850-12-shawn.sung@mediatek.com>
References: <20240226085059.26850-1-shawn.sung@mediatek.com>
 <20240226085059.26850-12-shawn.sung@mediatek.com>
Message-ID: <e2f901aa-9d1b-4de9-ac18-7cfb57adb587@collabora.com>

Il 26/02/24 09:50, Shawn Sung ha scritto:
> From: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> 
> Rename "pending_needs_vblank" to "needs_vblank" to reduce the code size.
> 

This decreases human readability though, so I would prefer that we omit this one.

Regards,
Angelo

> Signed-off-by: Hsiao Chien Sung <shawn.sung at mediatek.corp-partner.google.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_crtc.c | 8 ++++----
>   1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
> index 7fe234de83a3..a1fb6c67681d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
> @@ -42,7 +42,7 @@ struct mtk_crtc {
>   	struct drm_crtc			base;
>   	bool				enabled;
>   
> -	bool				pending_needs_vblank;
> +	bool				needs_vblank;
>   	struct drm_pending_vblank_event	*event;
>   
>   	struct drm_plane		*planes;
> @@ -105,9 +105,9 @@ static void mtk_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc)
>   static void mtk_drm_finish_page_flip(struct mtk_crtc *mtk_crtc)
>   {
>   	drm_crtc_handle_vblank(&mtk_crtc->base);
> -	if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
> +	if (!mtk_crtc->config_updating && mtk_crtc->needs_vblank) {
>   		mtk_crtc_finish_page_flip(mtk_crtc);
> -		mtk_crtc->pending_needs_vblank = false;
> +		mtk_crtc->needs_vblank = false;
>   	}
>   }
>   
> @@ -571,7 +571,7 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
>   	mutex_lock(&mtk_crtc->hw_lock);
>   	mtk_crtc->config_updating = true;
>   	if (needs_vblank)
> -		mtk_crtc->pending_needs_vblank = true;
> +		mtk_crtc->needs_vblank = true;
>   
>   	for (i = 0; i < mtk_crtc->layer_nr; i++) {
>   		struct drm_plane *plane = &mtk_crtc->planes[i];




From ryan.roberts at arm.com  Mon Feb 26 04:40:55 2024
From: ryan.roberts at arm.com (Ryan Roberts)
Date: Mon, 26 Feb 2024 12:40:55 +0000
Subject: [PATCH 1/2] arm64/mm: Export contpte symbols only to GPL users
In-Reply-To: <c9f00402-bb95-4fcf-a309-c36a5e68ec93@redhat.com>
References: <20240226120321.1055731-1-ryan.roberts@arm.com>
 <20240226120321.1055731-2-ryan.roberts@arm.com>
 <c9f00402-bb95-4fcf-a309-c36a5e68ec93@redhat.com>
Message-ID: <fbdc3ddb-aaf4-4688-aa72-0cf0b88deaff@arm.com>

On 26/02/2024 12:25, David Hildenbrand wrote:
> On 26.02.24 13:03, Ryan Roberts wrote:
>> The contpte symbols must be exported since some of the public inline
>> ptep_* APIs are called from modules and these inlines now call the
>> contpte functions. Originally they were exported as EXPORT_SYMBOL() for
>> fear of breaking out-of-tree modules. But we subsequently concluded that
>> EXPORT_SYMBOL_GPL() should be safe since these functions are deeply core
>> mm routines, and any module operating at this level is not going to be
>> able to survive on EXPORT_SYMBOL alone.
>>
> 
> I only looked at __set_ptes() to get a feeling what would currently work.
> 
> __set_ptes() might already call __sync_icache_dcache() via
> __sync_cache_and_tags(), that is EXPORT_SYMBOL_GPL.
> 
> [mte_sync_tags() is not exported at all, so maybe it's safe to assume that some
> out-of-tree module could not make good use of set_pte_at() in general]

That's interesting, some grepping I previously did showed that ptep_get() and
set_pte_at() are used by in-tree drivers (which I assume can be built as modules):

https://lore.kernel.org/linux-arm-kernel/b994ff89-1a1f-26ca-9479-b08c77f94be8 at arm.com/

> 
> Acked-by: David Hildenbrand <david at redhat.com>
> 

Thanks!


From david at redhat.com  Mon Feb 26 04:40:54 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 26 Feb 2024 13:40:54 +0100
Subject: [PATCH 2/2] arm64/mm: Improve comment in
 contpte_ptep_get_lockless()
In-Reply-To: <8cda557a-cbf0-4926-be19-454cefdb4fdb@arm.com>
References: <20240226120321.1055731-1-ryan.roberts@arm.com>
 <20240226120321.1055731-3-ryan.roberts@arm.com>
 <4f215e3f-3395-4fab-b938-07a6d9e0a662@redhat.com>
 <8cda557a-cbf0-4926-be19-454cefdb4fdb@arm.com>
Message-ID: <acc20077-8fd2-4dd5-8d91-e45e07040589@redhat.com>

On 26.02.24 13:37, Ryan Roberts wrote:
> On 26/02/2024 12:30, David Hildenbrand wrote:
>> On 26.02.24 13:03, Ryan Roberts wrote:
>>> Make clear the atmicity/consistency requirements of the API and how we
>>> achieve them.
>>>
>>> Link: https://lore.kernel.org/linux-mm/Zc-Tqqfksho3BHmU at arm.com/
>>> Signed-off-by: Ryan Roberts <ryan.roberts at arm.com>
>>> ---
>>>  ? arch/arm64/mm/contpte.c | 24 ++++++++++++++----------
>>>  ? 1 file changed, 14 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
>>> index be0a226c4ff9..1b64b4c3f8bf 100644
>>> --- a/arch/arm64/mm/contpte.c
>>> +++ b/arch/arm64/mm/contpte.c
>>> @@ -183,16 +183,20 @@ EXPORT_SYMBOL_GPL(contpte_ptep_get);
>>>  ? pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
>>>  ? {
>>>  ????? /*
>>> -???? * Gather access/dirty bits, which may be populated in any of the ptes
>>> -???? * of the contig range. We may not be holding the PTL, so any contiguous
>>> -???? * range may be unfolded/modified/refolded under our feet. Therefore we
>>> -???? * ensure we read a _consistent_ contpte range by checking that all ptes
>>> -???? * in the range are valid and have CONT_PTE set, that all pfns are
>>> -???? * contiguous and that all pgprots are the same (ignoring access/dirty).
>>> -???? * If we find a pte that is not consistent, then we must be racing with
>>> -???? * an update so start again. If the target pte does not have CONT_PTE
>>> -???? * set then that is considered consistent on its own because it is not
>>> -???? * part of a contpte range.
>>> +???? * The ptep_get_lockless() API requires us to read and return *orig_ptep
>>> +???? * so that it is self-consistent, without the PTL held, so we may be
>>> +???? * racing with other threads modifying the pte. Usually a READ_ONCE()
>>> +???? * would suffice, but for the contpte case, we also need to gather the
>>> +???? * access and dirty bits from across all ptes in the contiguous block,
>>> +???? * and we can't read all of those neighbouring ptes atomically, so any
>>> +???? * contiguous range may be unfolded/modified/refolded under our feet.
>>> +???? * Therefore we ensure we read a _consistent_ contpte range by checking
>>> +???? * that all ptes in the range are valid and have CONT_PTE set, that all
>>> +???? * pfns are contiguous and that all pgprots are the same (ignoring
>>> +???? * access/dirty). If we find a pte that is not consistent, then we must
>>> +???? * be racing with an update so start again. If the target pte does not
>>> +???? * have CONT_PTE set then that is considered consistent on its own
>>> +???? * because it is not part of a contpte range.
>>>  ?????? */
>>>  ? ????? pgprot_t orig_prot;
>>
>> Reviewed-by: David Hildenbrand <david at redhat.com>
> 
> Thanks!
> 
>>
>> In an ideal world, we'd really not rely on any accessed/dirty on the lockless
>> path and remove contpte_ptep_get_lockless() completely :)
> 
> Not sure if you saw my RFC to do exactly that? (well, it doesn't actually remove
> [contpte_]ptep_get_lockless() but it does remove all the callers). If you have
> any feedback, we could get this moving...

Yes, I saw it. Hoping we can get that in and then maybe remove the 
contpte_get_lockless() once all callers are gone :)

... on my todo list.

-- 
Cheers,

David / dhildenb



From monstr at monstr.eu  Mon Feb 26 04:42:27 2024
From: monstr at monstr.eu (Michal Simek)
Date: Mon, 26 Feb 2024 13:42:27 +0100
Subject: [GIT PULL] arm64: ZynqMP SoC changes for v6.9
Message-ID: <CAHTX3d+NGUJhKXxGwskSOf6U9P0Nd9rnroFczD8X2mLhFgcm0Q@mail.gmail.com>

Hi Arnd,

We discussed this change via the side channel with Abhyuday and he is
fine with this change but he is not willing (after discussion with his
current employer and for whatever else reason) to even ack this
change. Listed xilinx email is no longer working too. That's why based
on our talk I am sending a single patch to change the maintainer of
Xilinx event management driver to unblock this situation.

Thanks,
Michal

The following changes since commit 6613476e225e090cc9aad49be7fa504e290dd33d:

  Linux 6.8-rc1 (2024-01-21 14:11:32 -0800)

are available in the Git repository at:

  https://github.com/Xilinx/linux-xlnx.git tags/zynqmp-soc-for-6.9

for you to fetch changes up to be53a3b3bc58bb5be6c4228523b071b345d5574b:

  soc: xilinx: update maintainer of event manager driver (2024-01-23
14:57:47 +0100)

----------------------------------------------------------------
arm64: ZynqMP SoC changes for 6.9

- Update maintainer for event manager

----------------------------------------------------------------
Jay Buddhabhatti (1):
      soc: xilinx: update maintainer of event manager driver

 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


From jpanis at baylibre.com  Mon Feb 26 04:43:51 2024
From: jpanis at baylibre.com (Julien Panis)
Date: Mon, 26 Feb 2024 13:43:51 +0100
Subject: [PATCH v2 08/14] misc: tps6594-pfsm: Add TI TPS65224 PMIC PFSM
In-Reply-To: <20240223093701.66034-9-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
 <20240223093701.66034-9-bhargav.r@ltts.com>
Message-ID: <8f09bc42-b85d-446f-bd9d-77155060a4b8@baylibre.com>

On 2/23/24 10:36, Bhargav Raviprakash wrote:
> Add support for TPS65224 PFSM in the TPS6594 PFSM driver
> as they share significant functionality.
>
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> ---
>   drivers/misc/tps6594-pfsm.c | 55 +++++++++++++++++++++++++++----------
>   1 file changed, 40 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/misc/tps6594-pfsm.c b/drivers/misc/tps6594-pfsm.c
> index 88dcac814..4fa071093 100644
> --- a/drivers/misc/tps6594-pfsm.c
> +++ b/drivers/misc/tps6594-pfsm.c
> @@ -1,6 +1,6 @@
>   // SPDX-License-Identifier: GPL-2.0
>   /*
> - * PFSM (Pre-configurable Finite State Machine) driver for TI TPS6594/TPS6593/LP8764 PMICs
> + * PFSM (Pre-configurable Finite State Machine) driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
>    *
>    * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
>    */
> @@ -34,15 +34,17 @@
>   
>   #define TPS6594_FILE_TO_PFSM(f) container_of((f)->private_data, struct tps6594_pfsm, miscdev)
>   
> -/**
> +/*

Here it should be /** for the structure documentation, I think.
Please check in kernel doc.

[...]

> @@ -210,8 +230,12 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
>   			return ret;
>   
>   		/* Modify NSLEEP1-2 bits */
> -		ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
> -					TPS6594_BIT_NSLEEP2B);
> +		if (pfsm->chip_id == TPS65224)
> +			ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
> +						TPS6594_BIT_NSLEEP1B);
> +		else
> +			ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
> +						TPS6594_BIT_NSLEEP2B);

Instead of this if/else, a ternary operator might do the trick here:
regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
 ????????????????????????????? pfsm->chip_id == TPS65224 ? TPS6594_BIT_NSLEEP1B : TPS6594_BIT_NSLEEP2B)

Julien



From peng.fan at oss.nxp.com  Mon Feb 26 05:02:43 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 26 Feb 2024 21:02:43 +0800
Subject: [PATCH] dt-bindings: firmware: arm,scmi: support system power protocol
Message-ID: <20240226130243.3820915-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add SCMI System Power Protocol bindings, and the protocol id is 0x12.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 Documentation/devicetree/bindings/firmware/arm,scmi.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
index 4591523b51a0..d99f1577476e 100644
--- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
+++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
@@ -141,6 +141,14 @@ properties:
     required:
       - '#power-domain-cells'
 
+  protocol at 12:
+    $ref: '#/$defs/protocol-node'
+    unevaluatedProperties: false
+
+    properties:
+      reg:
+        const: 0x12
+
   protocol at 13:
     $ref: '#/$defs/protocol-node'
     unevaluatedProperties: false
-- 
2.37.1



From jpanis at baylibre.com  Mon Feb 26 04:56:13 2024
From: jpanis at baylibre.com (Julien Panis)
Date: Mon, 26 Feb 2024 13:56:13 +0100
Subject: [PATCH v2 09/14] misc: tps6594-esm: reversion check limited to
 TPS6594 family
In-Reply-To: <20240223093701.66034-10-bhargav.r@ltts.com>
References: <20240223093701.66034-1-bhargav.r@ltts.com>
 <20240223093701.66034-10-bhargav.r@ltts.com>
Message-ID: <53abcb16-20f4-469f-b2d9-63544cbe1e9e@baylibre.com>

On 2/23/24 10:36, Bhargav Raviprakash wrote:
> The reversion check is only applicable on TPS6594 family of PMICs.
> Conditionally add that check if the chip_id is one of the PMIC in
> the TPS6594 family.
>
> Signed-off-by: Bhargav Raviprakash <bhargav.r at ltts.com>
> ---
>   drivers/misc/tps6594-esm.c | 18 +++++++++++-------
>   1 file changed, 11 insertions(+), 7 deletions(-)

Following my comment related to ESM_MCU interrupts for 'tps6594.h':
Does it really make sense to add?tps65224 ESM_MCU support in linux ?

For tps6594. TI requested a linux driver for ESM_SOC only (the "main" ESM).
No linux driver was requested for ESM_MCU.

Since tps65224 does not have ESM_SOC, I'm not sure that anything should
be done in linux for tps65224 ESM. Maybe you should discuss this point with
TI analog team (our TI contact for tps6594 was Chris Sterzik).

Julien


From nicolas.ferre at microchip.com  Mon Feb 26 04:54:58 2024
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Mon, 26 Feb 2024 13:54:58 +0100
Subject: [PATCH] mtd: nand: raw: atmel: Fix comment in timings preparation
In-Reply-To: <20240226122537.75097-1-ada@thorsis.com>
References: <20240226122537.75097-1-ada@thorsis.com>
Message-ID: <b4fadbb7-5263-4271-9728-b25cc78ebad0@microchip.com>

On 26/02/2024 at 13:25, Alexander Dahl wrote:
> Looks like a copy'n'paste mistake introduced when initially adding the
> dynamic timings feature with commit f9ce2eddf176 ("mtd: nand: atmel: Add
> ->setup_data_interface() hooks").  The context around this and
> especially the code itself suggests 'read' is meant instead of write.
> 
> Signed-off-by: Alexander Dahl <ada at thorsis.com>

Looks indeed valid:
Reviewed-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Thanks Alexander. Best regards,
   Nicolas

> ---
>   drivers/mtd/nand/raw/atmel/nand-controller.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
> index 4cb478bbee4a..dc75d50d52e8 100644
> --- a/drivers/mtd/nand/raw/atmel/nand-controller.c
> +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
> @@ -1370,23 +1370,23 @@ static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand,
>           *
>           * NRD_PULSE = tRP
>           */
>          ncycles = DIV_ROUND_UP(conf->timings.sdr.tRP_min, mckperiodps);
>          totalcycles += ncycles;
>          ret = atmel_smc_cs_conf_set_pulse(smcconf, ATMEL_SMC_NRD_SHIFT,
>                                            ncycles);
>          if (ret)
>                  return ret;
> 
>          /*
> -        * The write cycle timing is directly matching tWC, but is also
> +        * The read cycle timing is directly matching tRC, but is also
>           * dependent on the setup and hold timings we calculated earlier,
>           * which gives:
>           *
>           * NRD_CYCLE = max(tRC, NRD_PULSE + NRD_HOLD)
>           *
>           * NRD_SETUP is always 0.
>           */
>          ncycles = DIV_ROUND_UP(conf->timings.sdr.tRC_min, mckperiodps);
>          ncycles = max(totalcycles, ncycles);
>          ret = atmel_smc_cs_conf_set_cycle(smcconf, ATMEL_SMC_NRD_SHIFT,
>                                            ncycles);
> 
> base-commit: d206a76d7d2726f3b096037f2079ce0bd3ba329b
> --
> 2.39.2
> 



From laurent.pinchart at ideasonboard.com  Mon Feb 26 04:58:18 2024
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 26 Feb 2024 14:58:18 +0200
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <ZdyB_yHn9yImTuhm@valkosipuli.retiisi.eu>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <Zdx77nyiQn4zya3h@valkosipuli.retiisi.eu>
 <20240226120431.GA25561@pendragon.ideasonboard.com>
 <ZdyB_yHn9yImTuhm@valkosipuli.retiisi.eu>
Message-ID: <20240226125818.GA26163@pendragon.ideasonboard.com>

On Mon, Feb 26, 2024 at 12:20:15PM +0000, Sakari Ailus wrote:
> On Mon, Feb 26, 2024 at 02:04:31PM +0200, Laurent Pinchart wrote:
> > On Mon, Feb 26, 2024 at 11:54:22AM +0000, Sakari Ailus wrote:
> > > On Wed, Feb 14, 2024 at 02:19:03PM +0000, Daniel Scally wrote:
> > > > Add the yaml binding for ARM's Mali-C55 Image Signal Processor.
> > > > 
> > > > Acked-by: Nayden Kanchev <nayden.kanchev at arm.com>
> > > > Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> > > > ---
> > > > Changes in v2:
> > > > 
> > > > 	- Added clocks information
> > > > 	- Fixed the warnings raised by Rob
> > > > 
> > > >  .../bindings/media/arm,mali-c55.yaml          | 77 +++++++++++++++++++
> > > >  1 file changed, 77 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/media/arm,mali-c55.yaml b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > > > new file mode 100644
> > > > index 000000000000..30038cfec3a4
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/media/arm,mali-c55.yaml
> > > > @@ -0,0 +1,77 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/media/arm,mali-c55.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: ARM Mali-C55 Image Signal Processor
> > > > +
> > > > +maintainers:
> > > > +  - Daniel Scally <dan.scally at ideasonboard.com>
> > > > +  - Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +    const: arm,mali-c55
> > > > +
> > > > +  reg:
> > > > +    maxItems: 1
> > > > +
> > > > +  interrupts:
> > > > +    maxItems: 1
> > > > +
> > > > +  clocks:
> > > > +    items:
> > > > +      - description: ISP video clock
> > > > +      - description: ISP AXI clock
> > > > +      - description: ISP AHB-lite clock
> > > > +
> > > > +  clock-names:
> > > > +    items:
> > > > +      - const: vclk
> > > > +      - const: aclk
> > > > +      - const: hclk
> > > > +
> > > > +  ports:
> > > > +    $ref: /schemas/graph.yaml#/properties/ports
> > > > +
> > > > +    properties:
> > > > +      port at 0:
> > > > +        $ref: /schemas/graph.yaml#/properties/port

Adding

        description: Input parallel video bus

here would be useful.

> > > > +
> > > > +        properties:
> > > > +          endpoint:
> > > > +            $ref: /schemas/graph.yaml#/properties/endpoint
> > > > +
> > > > +required:
> > > > +  - compatible
> > > > +  - reg
> > > > +  - interrupts
> > > > +  - clocks
> > > > +  - clock-names
> > > > +  - ports
> > > > +
> > > > +additionalProperties: false
> > > > +
> > > > +examples:
> > > > +  - |
> > > > +    mali_c55: isp at 400000 {
> > > > +      compatible = "arm,mali-c55";
> > > > +      reg = <0x400000 0x200000>;
> > > > +      clocks = <&clk 0>, <&clk 1>, <&clk 2>;
> > > > +      clock-names = "vclk", "aclk", "hclk";
> > > > +      interrupts = <0>;
> > > > +
> > > > +      ports {
> > > > +        #address-cells = <1>;
> > > > +        #size-cells = <0>;
> > > > +
> > > > +        port at 0 {
> > > > +          reg = <0>;
> > > > +          isp_in: endpoint {
> > > > +              remote-endpoint = <&mipi_out>;
> > > 
> > > I suppose this is a CSI-2 interface with D-PHY?
> > 
> > No, that's an internal parallel bus. Depending on the SoC integration,
> > it can be connected to a CSI-2 receiver, a DMA engine, or a mux to
> > select between different sources.
> 
> The name suggests otherwise. Maybe change that to something more
> descriptive?

We could rename mipi_out to csi2_rx_out, sure.

> > > How many lanes do you have and is lane remapping / polarity inversion
> > > supported?
> > > 
> > > This should be reflected in bindings.
> > > 
> > > > +          };
> > > > +        };
> > > > +      };
> > > > +    };
> > > > +...

-- 
Regards,

Laurent Pinchart


From peng.fan at oss.nxp.com  Mon Feb 26 05:08:25 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 26 Feb 2024 21:08:25 +0800
Subject: [PATCH 1/2] dt-bindings: iio: adc: imx93: drop the 4th interrupt
Message-ID: <20240226130826.3824251-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Per i.MX93 Reference Mannual Rev.4, 12/2013, there is no interrupt 268,
so drop it.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml b/Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml
index dacc526dc695..dfc3f512918f 100644
--- a/Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml
@@ -31,7 +31,6 @@ properties:
       - description: normal conversion, include EOC (End of Conversion),
           ECH (End of Chain), JEOC (End of Injected Conversion) and
           JECH (End of injected Chain).
-      - description: Self-testing Interrupts.
 
   clocks:
     maxItems: 1
@@ -70,8 +69,7 @@ examples:
             reg = <0x44530000 0x10000>;
             interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
                          <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+                         <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
             clocks = <&clk IMX93_CLK_ADC1_GATE>;
             clock-names = "ipg";
             vref-supply = <&reg_vref_1v8>;
-- 
2.37.1



From peng.fan at oss.nxp.com  Mon Feb 26 05:08:26 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 26 Feb 2024 21:08:26 +0800
Subject: [PATCH 2/2] arm64: dts: imx93: drop the 4th interrupt for ADC
In-Reply-To: <20240226130826.3824251-1-peng.fan@oss.nxp.com>
References: <20240226130826.3824251-1-peng.fan@oss.nxp.com>
Message-ID: <20240226130826.3824251-2-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Per i.MX93 Reference Mannual Rev.4, 12/2023, there is no interrupt 268,
drop it.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx93.dtsi | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
index 601c94e1fac8..b8ef9b938856 100644
--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -509,8 +509,7 @@ adc1: adc at 44530000 {
 				reg = <0x44530000 0x10000>;
 				interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
 					     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
-					     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
-					     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+					     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clk IMX93_CLK_ADC1_GATE>;
 				clock-names = "ipg";
 				#io-channel-cells = <1>;
-- 
2.37.1



From peng.fan at oss.nxp.com  Mon Feb 26 05:20:15 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 26 Feb 2024 21:20:15 +0800
Subject: [PATCH v2 0/3] arm64: dts: add i.MX95 and EVK board
Message-ID: <20240226-imx95-dts-v2-0-00e36637b07e@nxp.com>

Add a minimal i.MX95 dtsi and EVK board dts.
i.MX95 has a M33 running SCMI firmware, but as of now, the scmi pinctrl
driver still not ready for i.MX95, so we count on bootloader to
configure the pinctrl for lpuart and sdhc and it boots well. After pinctrl
driver ready, we could move to use scmi pinctrl.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
Changes in v2:
- Addressed Rob and Krzysztof's comments, and fix dts_check issue
  To pass the dtbs_check, need apply:
   https://lore.kernel.org/all/20240226070910.3379108-1-peng.fan at oss.nxp.com/
   https://lore.kernel.org/all/20240226130243.3820915-1-peng.fan at oss.nxp.com/
   https://lore.kernel.org/all/20240226130516.3821803-1-peng.fan at oss.nxp.com/
   https://lore.kernel.org/all/20240226130826.3824251-1-peng.fan at oss.nxp.com/
   https://lore.kernel.org/all/20240219-imx-mailbox-v8-1-75535a87794e at nxp.com/

- Link to v1: https://lore.kernel.org/r/20240218-imx95-dts-v1-0-2959f89f2018 at nxp.com

---
Peng Fan (3):
      dt-bindings: arm: fsl: add i.MX95 19x19 EVK board
      arm64: dts: freescale: add i.MX95 basic dtsi
      arm64: dts: freescale: add i.MX95 19x19 EVK minimal board dts

 Documentation/devicetree/bindings/arm/fsl.yaml    |    6 +
 arch/arm64/boot/dts/freescale/Makefile            |    1 +
 arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts |  115 ++
 arch/arm64/boot/dts/freescale/imx95-clock.h       |  187 ++++
 arch/arm64/boot/dts/freescale/imx95-power.h       |   55 +
 arch/arm64/boot/dts/freescale/imx95.dtsi          | 1177 +++++++++++++++++++++
 6 files changed, 1541 insertions(+)
---
base-commit: d37e1e4c52bc60578969f391fb81f947c3e83118
change-id: 20240218-imx95-dts-aae4316671a7

Best regards,
-- 
Peng Fan <peng.fan at nxp.com>



From peng.fan at oss.nxp.com  Mon Feb 26 05:20:16 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 26 Feb 2024 21:20:16 +0800
Subject: [PATCH v2 1/3] dt-bindings: arm: fsl: add i.MX95 19x19 EVK board
In-Reply-To: <20240226-imx95-dts-v2-0-00e36637b07e@nxp.com>
References: <20240226-imx95-dts-v2-0-00e36637b07e@nxp.com>
Message-ID: <20240226-imx95-dts-v2-1-00e36637b07e@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add DT compatible string for NXP i.MX95 19x19 EVK board.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 39378879777b..42c6e8467dc5 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -1264,6 +1264,12 @@ properties:
               - fsl,imx93-11x11-evk       # i.MX93 11x11 EVK Board
           - const: fsl,imx93
 
+      - description: i.MX95 based Boards
+        items:
+          - enum:
+              - fsl,imx95-19x19-evk       # i.MX95 19x19 EVK Board
+          - const: fsl,imx95
+
       - description: i.MXRT1050 based Boards
         items:
           - enum:

-- 
2.37.1



From peng.fan at oss.nxp.com  Mon Feb 26 05:20:17 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 26 Feb 2024 21:20:17 +0800
Subject: [PATCH v2 2/3] arm64: dts: freescale: add i.MX95 basic dtsi
In-Reply-To: <20240226-imx95-dts-v2-0-00e36637b07e@nxp.com>
References: <20240226-imx95-dts-v2-0-00e36637b07e@nxp.com>
Message-ID: <20240226-imx95-dts-v2-2-00e36637b07e@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX95 features 6 A55 Cores, ARM Mali GPU, ISP, ML acceleration NPU,
and Edgelock secure enclave security. This patch is to add a minimal
dtsi, with cpu cores, coresight, scmi, gic, uart, mu, sdhc, lpi2c added.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx95-clock.h |  187 +++++
 arch/arm64/boot/dts/freescale/imx95-power.h |   55 ++
 arch/arm64/boot/dts/freescale/imx95.dtsi    | 1177 +++++++++++++++++++++++++++
 3 files changed, 1419 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx95-clock.h b/arch/arm64/boot/dts/freescale/imx95-clock.h
new file mode 100644
index 000000000000..5badaace3148
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-clock.h
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __CLOCK_IMX95_H
+#define __CLOCK_IMX95_H
+
+/* The index should match i.MX95 SCMI Firmware */
+#define IMX95_CLK_32K                       1
+#define IMX95_CLK_24M                       2
+#define IMX95_CLK_FRO                       3
+#define IMX95_CLK_SYSPLL1_VCO               4
+#define IMX95_CLK_SYSPLL1_PFD0_UNGATED      5
+#define IMX95_CLK_SYSPLL1_PFD0              6
+#define IMX95_CLK_SYSPLL1_PFD0_DIV2         7
+#define IMX95_CLK_SYSPLL1_PFD1_UNGATED      8
+#define IMX95_CLK_SYSPLL1_PFD1              9
+#define IMX95_CLK_SYSPLL1_PFD1_DIV2         10
+#define IMX95_CLK_SYSPLL1_PFD2_UNGATED      11
+#define IMX95_CLK_SYSPLL1_PFD2              12
+#define IMX95_CLK_SYSPLL1_PFD2_DIV2         13
+#define IMX95_CLK_AUDIOPLL1_VCO             14
+#define IMX95_CLK_AUDIOPLL1                 15
+#define IMX95_CLK_AUDIOPLL2_VCO             16
+#define IMX95_CLK_AUDIOPLL2                 17
+#define IMX95_CLK_VIDEOPLL1_VCO             18
+#define IMX95_CLK_VIDEOPLL1                 19
+#define IMX95_CLK_RESERVED20                20
+#define IMX95_CLK_RESERVED21                21
+#define IMX95_CLK_RESERVED22                22
+#define IMX95_CLK_RESERVED23                23
+#define IMX95_CLK_ARMPLL_VCO                24
+#define IMX95_CLK_ARMPLL_PFD0_UNGATED       25
+#define IMX95_CLK_ARMPLL_PFD0               26
+#define IMX95_CLK_ARMPLL_PFD1_UNGATED       27
+#define IMX95_CLK_ARMPLL_PFD1               28
+#define IMX95_CLK_ARMPLL_PFD2_UNGATED       29
+#define IMX95_CLK_ARMPLL_PFD2               30
+#define IMX95_CLK_ARMPLL_PFD3_UNGATED       31
+#define IMX95_CLK_ARMPLL_PFD3               32
+#define IMX95_CLK_DRAMPLL_VCO               33
+#define IMX95_CLK_DRAMPLL                   34
+#define IMX95_CLK_HSIOPLL_VCO               35
+#define IMX95_CLK_HSIOPLL                   36
+#define IMX95_CLK_LDBPLL_VCO                37
+#define IMX95_CLK_LDBPLL                    38
+#define IMX95_CLK_EXT1                      39
+#define IMX95_CLK_EXT2                      40
+
+#define IMX95_CCM_NUM_CLK_SRC               41
+
+#define IMX95_CLK_ADC                      (IMX95_CCM_NUM_CLK_SRC + 0)
+#define IMX95_CLK_TMU                      (IMX95_CCM_NUM_CLK_SRC + 1)
+#define IMX95_CLK_BUSAON                   (IMX95_CCM_NUM_CLK_SRC + 2)
+#define IMX95_CLK_CAN1                     (IMX95_CCM_NUM_CLK_SRC + 3)
+#define IMX95_CLK_I3C1                     (IMX95_CCM_NUM_CLK_SRC + 4)
+#define IMX95_CLK_I3C1SLOW                 (IMX95_CCM_NUM_CLK_SRC + 5)
+#define IMX95_CLK_LPI2C1                   (IMX95_CCM_NUM_CLK_SRC + 6)
+#define IMX95_CLK_LPI2C2                   (IMX95_CCM_NUM_CLK_SRC + 7)
+#define IMX95_CLK_LPSPI1                   (IMX95_CCM_NUM_CLK_SRC + 8)
+#define IMX95_CLK_LPSPI2                   (IMX95_CCM_NUM_CLK_SRC + 9)
+#define IMX95_CLK_LPTMR1                   (IMX95_CCM_NUM_CLK_SRC + 10)
+#define IMX95_CLK_LPUART1                  (IMX95_CCM_NUM_CLK_SRC + 11)
+#define IMX95_CLK_LPUART2                  (IMX95_CCM_NUM_CLK_SRC + 12)
+#define IMX95_CLK_M33                      (IMX95_CCM_NUM_CLK_SRC + 13)
+#define IMX95_CLK_M33SYSTICK               (IMX95_CCM_NUM_CLK_SRC + 14)
+#define IMX95_CLK_MQS1                     (IMX95_CCM_NUM_CLK_SRC + 15)
+#define IMX95_CLK_PDM                      (IMX95_CCM_NUM_CLK_SRC + 16)
+#define IMX95_CLK_SAI1                     (IMX95_CCM_NUM_CLK_SRC + 17)
+#define IMX95_CLK_SENTINEL                 (IMX95_CCM_NUM_CLK_SRC + 18)
+#define IMX95_CLK_TPM2                     (IMX95_CCM_NUM_CLK_SRC + 19)
+#define IMX95_CLK_TSTMR1                   (IMX95_CCM_NUM_CLK_SRC + 20)
+#define IMX95_CLK_CAMAPB                   (IMX95_CCM_NUM_CLK_SRC + 21)
+#define IMX95_CLK_CAMAXI                   (IMX95_CCM_NUM_CLK_SRC + 22)
+#define IMX95_CLK_CAMCM0                   (IMX95_CCM_NUM_CLK_SRC + 23)
+#define IMX95_CLK_CAMISI                   (IMX95_CCM_NUM_CLK_SRC + 24)
+#define IMX95_CLK_MIPIPHYCFG               (IMX95_CCM_NUM_CLK_SRC + 25)
+#define IMX95_CLK_MIPIPHYPLLBYPASS         (IMX95_CCM_NUM_CLK_SRC + 26)
+#define IMX95_CLK_MIPIPHYPLLREF            (IMX95_CCM_NUM_CLK_SRC + 27)
+#define IMX95_CLK_MIPITESTBYTE             (IMX95_CCM_NUM_CLK_SRC + 28)
+#define IMX95_CLK_A55                      (IMX95_CCM_NUM_CLK_SRC + 29)
+#define IMX95_CLK_A55MTRBUS                (IMX95_CCM_NUM_CLK_SRC + 30)
+#define IMX95_CLK_A55PERIPH                (IMX95_CCM_NUM_CLK_SRC + 31)
+#define IMX95_CLK_DRAMALT                  (IMX95_CCM_NUM_CLK_SRC + 32)
+#define IMX95_CLK_DRAMAPB                  (IMX95_CCM_NUM_CLK_SRC + 33)
+#define IMX95_CLK_DISPAPB                  (IMX95_CCM_NUM_CLK_SRC + 34)
+#define IMX95_CLK_DISPAXI                  (IMX95_CCM_NUM_CLK_SRC + 35)
+#define IMX95_CLK_DISPDP                   (IMX95_CCM_NUM_CLK_SRC + 36)
+#define IMX95_CLK_DISPOCRAM                (IMX95_CCM_NUM_CLK_SRC + 37)
+#define IMX95_CLK_DISPUSB31                (IMX95_CCM_NUM_CLK_SRC + 38)
+#define IMX95_CLK_DISP1PIX                 (IMX95_CCM_NUM_CLK_SRC + 39)
+#define IMX95_CLK_DISP2PIX                 (IMX95_CCM_NUM_CLK_SRC + 40)
+#define IMX95_CLK_DISP3PIX                 (IMX95_CCM_NUM_CLK_SRC + 41)
+#define IMX95_CLK_GPUAPB                   (IMX95_CCM_NUM_CLK_SRC + 42)
+#define IMX95_CLK_GPU                      (IMX95_CCM_NUM_CLK_SRC + 43)
+#define IMX95_CLK_HSIOACSCAN480M           (IMX95_CCM_NUM_CLK_SRC + 44)
+#define IMX95_CLK_HSIOACSCAN80M            (IMX95_CCM_NUM_CLK_SRC + 45)
+#define IMX95_CLK_HSIO                     (IMX95_CCM_NUM_CLK_SRC + 46)
+#define IMX95_CLK_HSIOPCIEAUX              (IMX95_CCM_NUM_CLK_SRC + 47)
+#define IMX95_CLK_HSIOPCIETEST160M         (IMX95_CCM_NUM_CLK_SRC + 48)
+#define IMX95_CLK_HSIOPCIETEST400M         (IMX95_CCM_NUM_CLK_SRC + 49)
+#define IMX95_CLK_HSIOPCIETEST500M         (IMX95_CCM_NUM_CLK_SRC + 50)
+#define IMX95_CLK_HSIOUSBTEST50M           (IMX95_CCM_NUM_CLK_SRC + 51)
+#define IMX95_CLK_HSIOUSBTEST60M           (IMX95_CCM_NUM_CLK_SRC + 52)
+#define IMX95_CLK_BUSM7                    (IMX95_CCM_NUM_CLK_SRC + 53)
+#define IMX95_CLK_M7                       (IMX95_CCM_NUM_CLK_SRC + 54)
+#define IMX95_CLK_M7SYSTICK                (IMX95_CCM_NUM_CLK_SRC + 55)
+#define IMX95_CLK_BUSNETCMIX               (IMX95_CCM_NUM_CLK_SRC + 56)
+#define IMX95_CLK_ENET                     (IMX95_CCM_NUM_CLK_SRC + 57)
+#define IMX95_CLK_ENETPHYTEST200M          (IMX95_CCM_NUM_CLK_SRC + 58)
+#define IMX95_CLK_ENETPHYTEST500M          (IMX95_CCM_NUM_CLK_SRC + 59)
+#define IMX95_CLK_ENETPHYTEST667M          (IMX95_CCM_NUM_CLK_SRC + 60)
+#define IMX95_CLK_ENETREF                  (IMX95_CCM_NUM_CLK_SRC + 61)
+#define IMX95_CLK_ENETTIMER1               (IMX95_CCM_NUM_CLK_SRC + 62)
+#define IMX95_CLK_MQS2                     (IMX95_CCM_NUM_CLK_SRC + 63)
+#define IMX95_CLK_SAI2                     (IMX95_CCM_NUM_CLK_SRC + 64)
+#define IMX95_CLK_NOCAPB                   (IMX95_CCM_NUM_CLK_SRC + 65)
+#define IMX95_CLK_NOC                      (IMX95_CCM_NUM_CLK_SRC + 66)
+#define IMX95_CLK_NPUAPB                   (IMX95_CCM_NUM_CLK_SRC + 67)
+#define IMX95_CLK_NPU                      (IMX95_CCM_NUM_CLK_SRC + 68)
+#define IMX95_CLK_CCMCKO1                  (IMX95_CCM_NUM_CLK_SRC + 69)
+#define IMX95_CLK_CCMCKO2                  (IMX95_CCM_NUM_CLK_SRC + 70)
+#define IMX95_CLK_CCMCKO3                  (IMX95_CCM_NUM_CLK_SRC + 71)
+#define IMX95_CLK_CCMCKO4                  (IMX95_CCM_NUM_CLK_SRC + 72)
+#define IMX95_CLK_VPUAPB                   (IMX95_CCM_NUM_CLK_SRC + 73)
+#define IMX95_CLK_VPU                      (IMX95_CCM_NUM_CLK_SRC + 74)
+#define IMX95_CLK_VPUDSP                   (IMX95_CCM_NUM_CLK_SRC + 75)
+#define IMX95_CLK_VPUJPEG                  (IMX95_CCM_NUM_CLK_SRC + 76)
+#define IMX95_CLK_AUDIOXCVR                (IMX95_CCM_NUM_CLK_SRC + 77)
+#define IMX95_CLK_BUSWAKEUP                (IMX95_CCM_NUM_CLK_SRC + 78)
+#define IMX95_CLK_CAN2                     (IMX95_CCM_NUM_CLK_SRC + 79)
+#define IMX95_CLK_CAN3                     (IMX95_CCM_NUM_CLK_SRC + 80)
+#define IMX95_CLK_CAN4                     (IMX95_CCM_NUM_CLK_SRC + 81)
+#define IMX95_CLK_CAN5                     (IMX95_CCM_NUM_CLK_SRC + 82)
+#define IMX95_CLK_FLEXIO1                  (IMX95_CCM_NUM_CLK_SRC + 83)
+#define IMX95_CLK_FLEXIO2                  (IMX95_CCM_NUM_CLK_SRC + 84)
+#define IMX95_CLK_FLEXSPI1                 (IMX95_CCM_NUM_CLK_SRC + 85)
+#define IMX95_CLK_I3C2                     (IMX95_CCM_NUM_CLK_SRC + 86)
+#define IMX95_CLK_I3C2SLOW                 (IMX95_CCM_NUM_CLK_SRC + 87)
+#define IMX95_CLK_LPI2C3                   (IMX95_CCM_NUM_CLK_SRC + 88)
+#define IMX95_CLK_LPI2C4                   (IMX95_CCM_NUM_CLK_SRC + 89)
+#define IMX95_CLK_LPI2C5                   (IMX95_CCM_NUM_CLK_SRC + 90)
+#define IMX95_CLK_LPI2C6                   (IMX95_CCM_NUM_CLK_SRC + 91)
+#define IMX95_CLK_LPI2C7                   (IMX95_CCM_NUM_CLK_SRC + 92)
+#define IMX95_CLK_LPI2C8                   (IMX95_CCM_NUM_CLK_SRC + 93)
+#define IMX95_CLK_LPSPI3                   (IMX95_CCM_NUM_CLK_SRC + 94)
+#define IMX95_CLK_LPSPI4                   (IMX95_CCM_NUM_CLK_SRC + 95)
+#define IMX95_CLK_LPSPI5                   (IMX95_CCM_NUM_CLK_SRC + 96)
+#define IMX95_CLK_LPSPI6                   (IMX95_CCM_NUM_CLK_SRC + 97)
+#define IMX95_CLK_LPSPI7                   (IMX95_CCM_NUM_CLK_SRC + 98)
+#define IMX95_CLK_LPSPI8                   (IMX95_CCM_NUM_CLK_SRC + 99)
+#define IMX95_CLK_LPTMR2                   (IMX95_CCM_NUM_CLK_SRC + 100)
+#define IMX95_CLK_LPUART3                  (IMX95_CCM_NUM_CLK_SRC + 101)
+#define IMX95_CLK_LPUART4                  (IMX95_CCM_NUM_CLK_SRC + 102)
+#define IMX95_CLK_LPUART5                  (IMX95_CCM_NUM_CLK_SRC + 103)
+#define IMX95_CLK_LPUART6                  (IMX95_CCM_NUM_CLK_SRC + 104)
+#define IMX95_CLK_LPUART7                  (IMX95_CCM_NUM_CLK_SRC + 105)
+#define IMX95_CLK_LPUART8                  (IMX95_CCM_NUM_CLK_SRC + 106)
+#define IMX95_CLK_SAI3                     (IMX95_CCM_NUM_CLK_SRC + 107)
+#define IMX95_CLK_SAI4                     (IMX95_CCM_NUM_CLK_SRC + 108)
+#define IMX95_CLK_SAI5                     (IMX95_CCM_NUM_CLK_SRC + 109)
+#define IMX95_CLK_SPDIF                    (IMX95_CCM_NUM_CLK_SRC + 110)
+#define IMX95_CLK_SWOTRACE                 (IMX95_CCM_NUM_CLK_SRC + 111)
+#define IMX95_CLK_TPM4                     (IMX95_CCM_NUM_CLK_SRC + 112)
+#define IMX95_CLK_TPM5                     (IMX95_CCM_NUM_CLK_SRC + 113)
+#define IMX95_CLK_TPM6                     (IMX95_CCM_NUM_CLK_SRC + 114)
+#define IMX95_CLK_TSTMR2                   (IMX95_CCM_NUM_CLK_SRC + 115)
+#define IMX95_CLK_USBPHYBURUNIN            (IMX95_CCM_NUM_CLK_SRC + 116)
+#define IMX95_CLK_USDHC1                   (IMX95_CCM_NUM_CLK_SRC + 117)
+#define IMX95_CLK_USDHC2                   (IMX95_CCM_NUM_CLK_SRC + 118)
+#define IMX95_CLK_USDHC3                   (IMX95_CCM_NUM_CLK_SRC + 119)
+#define IMX95_CLK_V2XPK                    (IMX95_CCM_NUM_CLK_SRC + 120)
+#define IMX95_CLK_WAKEUPAXI                (IMX95_CCM_NUM_CLK_SRC + 121)
+#define IMX95_CLK_XSPISLVROOT              (IMX95_CCM_NUM_CLK_SRC + 122)
+#define IMX95_CLK_SEL_EXT                  (IMX95_CCM_NUM_CLK_SRC + 123 + 0)
+#define IMX95_CLK_SEL_A55C0                (IMX95_CCM_NUM_CLK_SRC + 123 + 1)
+#define IMX95_CLK_SEL_A55C1                (IMX95_CCM_NUM_CLK_SRC + 123 + 2)
+#define IMX95_CLK_SEL_A55C2                (IMX95_CCM_NUM_CLK_SRC + 123 + 3)
+#define IMX95_CLK_SEL_A55C3                (IMX95_CCM_NUM_CLK_SRC + 123 + 4)
+#define IMX95_CLK_SEL_A55C4                (IMX95_CCM_NUM_CLK_SRC + 123 + 5)
+#define IMX95_CLK_SEL_A55C5                (IMX95_CCM_NUM_CLK_SRC + 123 + 6)
+#define IMX95_CLK_SEL_A55P                 (IMX95_CCM_NUM_CLK_SRC + 123 + 7)
+#define IMX95_CLK_SEL_DRAM                 (IMX95_CCM_NUM_CLK_SRC + 123 + 8)
+#define IMX95_CLK_SEL_TEMPSENSE            (IMX95_CCM_NUM_CLK_SRC + 123 + 9)
+
+#endif	/* __DT_BINDINGS_CLOCK_IMX95_H */
diff --git a/arch/arm64/boot/dts/freescale/imx95-power.h b/arch/arm64/boot/dts/freescale/imx95-power.h
new file mode 100644
index 000000000000..a43779317fed
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-power.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ *  Copyright 2024 NXP
+ */
+
+#ifndef __IMX95_POWER_H__
+#define __IMX95_POWER_H__
+
+#define IMX95_PD_ANA		0
+#define IMX95_PD_AON		1
+#define IMX95_PD_BBSM		2
+#define IMX95_PD_CAMERA		3
+#define IMX95_PD_CCMSRCGPC	4
+#define IMX95_PD_A55C0		5
+#define IMX95_PD_A55C1		6
+#define IMX95_PD_A55C2		7
+#define IMX95_PD_A55C3		8
+#define IMX95_PD_A55C4		9
+#define IMX95_PD_A55C5		10
+#define IMX95_PD_A55P		11
+#define IMX95_PD_DDR		12
+#define IMX95_PD_DISPLAY	13
+#define IMX95_PD_GPU		14
+#define IMX95_PD_HSIO_TOP	15
+#define IMX95_PD_HSIO_WAON	16
+#define IMX95_PD_M7		17
+#define IMX95_PD_NETC		18
+#define IMX95_PD_NOC		19
+#define IMX95_PD_NPU		20
+#define IMX95_PD_VPU		21
+#define IMX95_PD_WAKEUP		22
+
+#define IMX95_PERF_ELE		0
+#define IMX95_PERF_M33		1
+#define IMX95_PERF_WAKEUP	2
+#define IMX95_PERF_M7		3
+#define IMX95_PERF_DRAM		4
+#define IMX95_PERF_HSIO		5
+#define IMX95_PERF_NPU		6
+#define IMX95_PERF_NOC		7
+#define IMX95_PERF_A55		8
+#define IMX95_PERF_GPU		9
+#define IMX95_PERF_VPU		10
+#define IMX95_PERF_CAM		11
+#define IMX95_PERF_DISP		12
+#define IMX95_PERF_A55PER	13
+#define IMX95_PERF_A55P		14
+#define IMX95_PERF_A55C0	15
+#define IMX95_PERF_A55C1	16
+#define IMX95_PERF_A55C2	17
+#define IMX95_PERF_A55C3	18
+#define IMX95_PERF_A55C4	19
+#define IMX95_PERF_A55C5	20
+
+#endif
diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
new file mode 100644
index 000000000000..ef4cee2b6086
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -0,0 +1,1177 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include "imx95-clock.h"
+#include "imx95-power.h"
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		idle-states {
+			entry-method = "psci";
+
+			cpu_pd_wait: cpu-pd-wait {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x0010033>;
+				local-timer-stop;
+				entry-latency-us = <10000>;
+				exit-latency-us = <7000>;
+				min-residency-us = <27000>;
+				wakeup-latency-us = <15000>;
+				status = "disabled";
+			};
+		};
+
+		A55_0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0>;
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_pd_wait>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l0>;
+		};
+
+		A55_1: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_pd_wait>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l1>;
+		};
+
+		A55_2: cpu at 200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x200>;
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_pd_wait>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l2>;
+		};
+
+		A55_3: cpu at 300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x300>;
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l3>;
+		};
+
+		A55_4: cpu at 400 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x400>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_pd_wait>;
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l4>;
+		};
+
+		A55_5: cpu at 500 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x500>;
+			power-domains = <&scmi_devpd IMX95_PERF_A55>;
+			power-domain-names = "perf";
+			enable-method = "psci";
+			#cooling-cells = <2>;
+			cpu-idle-states = <&cpu_pd_wait>;
+			i-cache-size = <32768>;
+			i-cache-line-size = <64>;
+			i-cache-sets = <128>;
+			d-cache-size = <32768>;
+			d-cache-line-size = <64>;
+			d-cache-sets = <128>;
+			next-level-cache = <&l2_cache_l5>;
+		};
+
+		l2_cache_l0: l2-cache-l0 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l1: l2-cache-l1 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l2: l2-cache-l2 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l3: l2-cache-l3 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l4: l2-cache-l4 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l2_cache_l5: l2-cache-l5 {
+			compatible = "cache";
+			cache-size = <65536>;
+			cache-line-size = <64>;
+			cache-sets = <256>;
+			cache-level = <2>;
+			cache-unified;
+			next-level-cache = <&l3_cache>;
+		};
+
+		l3_cache: l3-cache {
+			compatible = "cache";
+			cache-size = <524288>;
+			cache-line-size = <64>;
+			cache-sets = <1024>;
+			cache-level = <3>;
+			cache-unified;
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&A55_0>;
+				};
+
+				core1 {
+					cpu = <&A55_1>;
+				};
+
+				core2 {
+					cpu = <&A55_2>;
+				};
+
+				core3 {
+					cpu = <&A55_3>;
+				};
+
+				core4 {
+					cpu = <&A55_4>;
+				};
+
+				core5 {
+					cpu = <&A55_5>;
+				};
+			};
+		};
+	};
+
+	clk_ext1: clock-ext1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <133000000>;
+		clock-output-names = "clk_ext1";
+	};
+
+	sai1_mclk: sai-mclk1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <0>;
+		clock-output-names = "sai1_mclk";
+	};
+
+	sai2_mclk: sai-mclk2 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <0>;
+		clock-output-names = "sai2_mclk";
+	};
+
+	sai3_mclk: sai-mclk3 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <0>;
+		clock-output-names = "sai3_mclk";
+	};
+
+	sai4_mclk: sai-mclk4 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <0>;
+		clock-output-names = "sai4_mclk";
+	};
+
+	sai5_mclk: sai-mclk5 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency= <0>;
+		clock-output-names = "sai5_mclk";
+	};
+
+	osc_24m: osc-24m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "osc_24m";
+	};
+
+	sram1: sram at 20480000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0x204c0000 0x0 0x18000>;
+		ranges = <0x0 0x0 0x204c0000 0x18000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+
+	firmware {
+		scmi {
+			compatible = "arm,scmi";
+			mboxes = <&mu2 5 0>, <&mu2 3 0>, <&mu2 3 1>;
+			shmem = <&scmi_buf0>, <&scmi_buf1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			scmi_devpd: protocol at 11 {
+				reg = <0x11>;
+				#power-domain-cells = <1>;
+			};
+
+			scmi_sys_power: protocol at 12 {
+				reg = <0x12>;
+			};
+
+			scmi_perf: protocol at 13 {
+				reg = <0x13>;
+				#power-domain-cells = <1>;
+			};
+
+			scmi_clk: protocol at 14 {
+				reg = <0x14>;
+				#clock-cells = <1>;
+			};
+
+			scmi_sensor: protocol at 15 {
+				reg = <0x15>;
+				#thermal-sensor-cells = <1>;
+			};
+		};
+	};
+
+	pmu {
+		compatible = "arm,cortex-a55-pmu";
+		interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	thermal-zones {
+		a55-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <2000>;
+			thermal-sensors = <&scmi_sensor 1>;
+
+			trips {
+				cpu_alert0: trip0 {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				cpu_crit0: trip1 {
+					temperature = <95000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert0>;
+					cooling-device =
+						<&A55_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&A55_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&A55_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&A55_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&A55_4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&A55_5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+	};
+
+	etm0: etm at 40840000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		reg = <0x0 0x40840000 0x0 0x10000>;
+		arm,primecell-periphid = <0xbb95d>;
+		cpu = <&A55_0>;
+		clocks = <&scmi_clk IMX95_CLK_A55PERIPH>;
+		clock-names = "apb_pclk";
+		status = "disabled";
+
+		out-ports {
+			port {
+				etm0_out_port: endpoint {
+					remote-endpoint = <&ca_funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	funnel0: funnel {
+		/*
+		 * non-configurable funnel don't show up on the AMBA
+		 * bus.  As such no need to add "arm,primecell".
+		 */
+		compatible = "arm,coresight-static-funnel";
+		status = "disabled";
+
+		in-ports {
+			port {
+				ca_funnel_in_port0: endpoint {
+					remote-endpoint = <&etm0_out_port>;
+				};
+			};
+		};
+
+		out-ports {
+			port {
+				ca_funnel_out_port0: endpoint {
+					remote-endpoint = <&hugo_funnel_in_port0>;
+				};
+			};
+		};
+	};
+
+	funnel1: funnel_sys {
+		compatible = "arm,coresight-static-funnel";
+		status = "disabled";
+
+		in-ports {
+			port {
+				hugo_funnel_in_port0: endpoint {
+					remote-endpoint = <&ca_funnel_out_port0>;
+				};
+			};
+		};
+
+		out-ports {
+			port {
+				hugo_funnel_out_port0: endpoint {
+					remote-endpoint = <&etf_in_port>;
+				};
+			};
+		};
+	};
+
+	etf: etf at 41030000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x0 0x41030000 0x0 0x1000>;
+		clocks = <&scmi_clk IMX95_CLK_A55PERIPH>;
+		clock-names = "apb_pclk";
+		status = "disabled";
+
+		in-ports {
+			port {
+				etf_in_port: endpoint {
+					remote-endpoint = <&hugo_funnel_out_port0>;
+				};
+			};
+		};
+
+		out-ports {
+			port {
+				etf_out_port: endpoint {
+					remote-endpoint = <&etr_in_port>;
+				};
+			};
+		};
+	};
+
+	etr: etr at 41040000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0x0 0x41040000 0x0 0x1000>;
+		clocks = <&scmi_clk IMX95_CLK_A55PERIPH>;
+		clock-names = "apb_pclk";
+		status = "disabled";
+
+		in-ports {
+			port {
+				etr_in_port: endpoint {
+					remote-endpoint = <&etf_out_port>;
+				};
+			};
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <24000000>;
+		arm,no-tick-in-suspend;
+		interrupt-parent = <&gic>;
+	};
+
+	gic: interrupt-controller at 48000000 {
+		compatible = "arm,gic-v3";
+		reg = <0 0x48000000 0 0x10000>,
+		      <0 0x48060000 0 0xc0000>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		dma-noncoherent;
+		ranges;
+
+		its: msi-controller at 48040000 {
+			compatible = "arm,gic-v3-its";
+			reg = <0 0x48040000 0 0x20000>;
+			msi-controller;
+			#msi-cells = <1>;
+			dma-noncoherent;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		aips2: bus at 42000000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0x0 0x42000000 0x0 0x800000>;
+			ranges = <0x42000000 0x0 0x42000000 0x8000000>,
+				 <0x28000000 0x0 0x28000000 0x10000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			mu7: mailbox at 42430000 {
+				compatible = "fsl,imx95-mu";
+				reg = <0x42430000 0x10000>;
+				interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			mu8: mailbox at 42730000 {
+				compatible = "fsl,imx95-mu";
+				reg = <0x42730000 0x10000>;
+				interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			wdog3: watchdog at 42490000 {
+				compatible = "fsl,imx93-wdt";
+				reg = <0x42490000 0x10000>;
+				interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				timeout-sec = <40>;
+				fsl,ext-reset-output;
+				status = "disabled";
+			};
+
+			tpm3: pwm at 424e0000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x424e0000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			tpm4: pwm at 424f0000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x424f0000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_TPM4>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			tpm5: pwm at 42500000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x42500000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_TPM5>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			tpm6: pwm at 42510000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x42510000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_TPM6>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			lpi2c3: i2c at 42530000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x42530000 0x10000>;
+				interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C3>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpi2c4: i2c at 42540000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x42540000 0x10000>;
+				interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C4>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi3: spi at 42550000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x42550000 0x10000>;
+				interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI3>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi4: spi at 42560000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x42560000 0x10000>;
+				interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI4>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpuart3: serial at 42570000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x42570000 0x1000>;
+				interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART3>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart4: serial at 42580000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x42580000 0x1000>;
+				interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART4>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart5: serial at 42590000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x42590000 0x1000>;
+				interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART5>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart6: serial at 425a0000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x425a0000 0x1000>;
+				interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART6>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart7: serial at 42690000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x42690000 0x1000>;
+				interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART7>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart8: serial at 426a0000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x426a0000 0x1000>;
+				interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART8>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpi2c5: i2c at 426b0000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x426b0000 0x10000>;
+				interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C5>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpi2c6: i2c at 426c0000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x426c0000 0x10000>;
+				interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C6>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpi2c7: i2c at 426d0000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x426d0000 0x10000>;
+				interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C7>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpi2c8: i2c at 426e0000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x426e0000 0x10000>;
+				interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C8>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi5: spi at 426f0000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x426f0000 0x10000>;
+				interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI5>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi6: spi at 42700000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x42700000 0x10000>;
+				interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI6>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi7: spi at 42710000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x42710000 0x10000>;
+				interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI7>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi8: spi at 42720000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x42720000 0x10000>;
+				interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI8>,
+					 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+		};
+
+		aips3: bus at 42800000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0 0x42800000 0 0x800000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x42800000 0x0 0x42800000 0x800000>;
+
+			usdhc1: mmc at 42850000 {
+				compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
+				reg = <0x42850000 0x10000>;
+				interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+					 <&scmi_clk IMX95_CLK_WAKEUPAXI>,
+					 <&scmi_clk IMX95_CLK_USDHC1>;
+				clock-names = "ipg", "ahb", "per";
+				assigned-clocks = <&scmi_clk IMX95_CLK_USDHC1>;
+				assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD1>;
+				assigned-clock-rates = <400000000>;
+				bus-width = <8>;
+				fsl,tuning-start-tap = <1>;
+				fsl,tuning-step= <2>;
+				status = "disabled";
+			};
+
+			usdhc2: mmc at 42860000 {
+				compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
+				reg = <0x42860000 0x10000>;
+				interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+					 <&scmi_clk IMX95_CLK_WAKEUPAXI>,
+					 <&scmi_clk IMX95_CLK_USDHC2>;
+				clock-names = "ipg", "ahb", "per";
+				assigned-clocks = <&scmi_clk IMX95_CLK_USDHC2>;
+				assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD1>;
+				assigned-clock-rates = <200000000>;
+				bus-width = <4>;
+				fsl,tuning-start-tap = <1>;
+				fsl,tuning-step= <2>;
+				status = "disabled";
+			};
+
+			usdhc3: mmc at 428b0000 {
+				compatible = "fsl,imx95-usdhc", "fsl,imx8mm-usdhc";
+				reg = <0x428b0000 0x10000>;
+				interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+					 <&scmi_clk IMX95_CLK_WAKEUPAXI>,
+					 <&scmi_clk IMX95_CLK_USDHC3>;
+				clock-names = "ipg", "ahb", "per";
+				bus-width = <4>;
+				fsl,tuning-start-tap = <1>;
+				fsl,tuning-step= <2>;
+				status = "disabled";
+			};
+		};
+
+		gpio2: gpio at 43810000 {
+			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+			reg = <0x0 0x43810000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+				 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+			clock-names = "gpio", "port";
+		};
+
+		gpio3: gpio at 43820000 {
+			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+			reg = <0x0 0x43820000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+				 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+			clock-names = "gpio", "port";
+		};
+
+		gpio4: gpio at 43840000 {
+			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+			reg = <0x0 0x43840000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+				 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+			clock-names = "gpio", "port";
+		};
+
+		gpio5: gpio at 43850000 {
+			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+			reg = <0x0 0x43850000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>,
+				 <&scmi_clk IMX95_CLK_BUSWAKEUP>;
+			clock-names = "gpio", "port";
+		};
+
+		aips1: bus at 44000000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0x0 0x44000000 0x0 0x800000>;
+			ranges = <0x44000000 0x0 0x44000000 0x800000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			mu1: mailbox at 44220000 {
+				compatible = "fsl,imx95-mu";
+				reg = <0x44220000 0x10000>;
+				interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			mu2: mailbox at 445b0000 {
+				compatible = "fsl,imx95-mu";
+				reg = <0x445b0000 0x1000>;
+				ranges;
+				interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				#mbox-cells = <2>;
+
+				sram0: sram at 445b1000 {
+					compatible = "mmio-sram";
+					reg = <0x445b1000 0x400>;
+					ranges = <0x0 0x445b1000 0x400>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					scmi_buf0: scmi-sram-section at 0 {
+						compatible = "arm,scmi-shmem";
+						reg = <0x0 0x80>;
+					};
+
+					scmi_buf1: scmi-sram-section at 80 {
+						compatible = "arm,scmi-shmem";
+						reg = <0x80 0x80>;
+					};
+				};
+
+			};
+
+			mu3: mailbox at 445d0000 {
+				compatible = "fsl,imx95-mu";
+				reg = <0x445d0000 0x10000>;
+				interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			mu4: mailbox at 445f0000 {
+				compatible = "fsl,imx95-mu";
+				reg = <0x445f0000 0x10000>;
+				interrupts = <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			mu6: mailbox at 44630000 {
+				compatible = "fsl,imx95-mu";
+				reg = <0x44630000 0x10000>;
+				interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+				#mbox-cells = <2>;
+				status = "disabled";
+			};
+
+			tpm1: pwm at 44310000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x44310000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_BUSAON>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			tpm2: pwm at 44320000 {
+				compatible = "fsl,imx7ulp-pwm";
+				reg = <0x44320000 0x1000>;
+				clocks = <&scmi_clk IMX95_CLK_TPM2>;
+				#pwm-cells = <3>;
+				status = "disabled";
+			};
+
+			lpi2c1: i2c at 44340000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x44340000 0x10000>;
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C1>,
+					 <&scmi_clk IMX95_CLK_BUSAON>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpi2c2: i2c at 44350000 {
+				compatible = "fsl,imx95-lpi2c", "fsl,imx7ulp-lpi2c";
+				reg = <0x44350000 0x10000>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPI2C2>,
+					 <&scmi_clk IMX95_CLK_BUSAON>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi1: spi at 44360000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x44360000 0x10000>;
+				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI1>,
+					 <&scmi_clk IMX95_CLK_BUSAON>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpspi2: spi at 44370000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx95-spi", "fsl,imx7ulp-spi";
+				reg = <0x44370000 0x10000>;
+				interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPSPI2>,
+					 <&scmi_clk IMX95_CLK_BUSAON>;
+				clock-names = "per", "ipg";
+				status = "disabled";
+			};
+
+			lpuart1: serial at 44380000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x44380000 0x1000>;
+				interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART1>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			lpuart2: serial at 44390000 {
+				compatible = "fsl,imx95-lpuart", "fsl,imx8ulp-lpuart",
+					     "fsl,imx7ulp-lpuart";
+				reg = <0x44390000 0x1000>;
+				interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_LPUART2>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			adc1: adc at 44530000 {
+				compatible = "nxp,imx93-adc";
+				reg = <0x44530000 0x10000>;
+				interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&scmi_clk IMX95_CLK_ADC>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+		};
+
+		aips4: bus at 49000000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			reg = <0x0 0x49000000 0x0 0x800000>;
+			ranges = <0x49000000 0x0 0x49000000 0x800000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			smmu: iommu at 490d0000 {
+				compatible = "arm,smmu-v3";
+				reg = <0x490d0000 0x100000>;
+				interrupts = <GIC_SPI 325 IRQ_TYPE_EDGE_RISING>,
+					     <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>,
+					     <GIC_SPI 334 IRQ_TYPE_EDGE_RISING>,
+					     <GIC_SPI 326 IRQ_TYPE_EDGE_RISING>;
+				interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+				#iommu-cells = <1>;
+				status = "disabled";
+			};
+		};
+
+		gpio1: gpio at 47400000 {
+			compatible = "fsl,imx95-gpio", "fsl,imx8ulp-gpio";
+			reg = <0x0 0x47400000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&scmi_clk IMX95_CLK_M33>,
+				 <&scmi_clk IMX95_CLK_M33>;
+			clock-names = "gpio", "port";
+			status = "disabled";
+		};
+
+		elemu0: mailbox at 47520000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47520000 0x0 0x10000>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		elemu1: mailbox at 47530000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47530000 0x0 0x10000>;
+			interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		elemu2: mailbox at 47540000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47540000 0x0 0x10000>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		elemu3: mailbox at 47550000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47550000 0x0 0x10000>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+		};
+
+		elemu4: mailbox at 47560000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47560000 0x0 0x10000>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		elemu5: mailbox at 47570000 {
+			compatible = "fsl,imx95-mu-ele";
+			reg = <0x0 0x47570000 0x0 0x10000>;
+			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		v2x_mu: mailbox at 47350000 {
+			compatible = "fsl,imx95-mu-v2x";
+			reg = <0x0 0x47350000 0x0 0x10000>;
+			interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+		};
+
+		v2x_mu6: mailbox at 47320000 {
+			compatible = "fsl,imx95-mu-v2x";
+			reg = <0x0 0x47320000 0x0 0x10000>;
+			interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+		};
+
+		displaymix_irqsteer: interrupt-controller at 4b0b0000 {
+			compatible = "fsl,imx-irqsteer";
+			reg = <0x0 0x4b0b0000 0x0 0x1000>;
+			interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,	/* reserved */
+				     <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,	/* reserved */
+				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&scmi_devpd IMX95_PD_DISPLAY>;
+			clocks = <&scmi_clk IMX95_CLK_DISPAPB>;
+			clock-names = "ipg";
+			fsl,channel = <0>;
+			fsl,num-irqs = <512>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			status = "disabled";
+		};
+	};
+};

-- 
2.37.1



From peng.fan at oss.nxp.com  Mon Feb 26 05:20:18 2024
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Mon, 26 Feb 2024 21:20:18 +0800
Subject: [PATCH v2 3/3] arm64: dts: freescale: add i.MX95 19x19 EVK minimal
 board dts
In-Reply-To: <20240226-imx95-dts-v2-0-00e36637b07e@nxp.com>
References: <20240226-imx95-dts-v2-0-00e36637b07e@nxp.com>
Message-ID: <20240226-imx95-dts-v2-3-00e36637b07e@nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add a minimal dts for i.MX95 19x19 EVK board:
 - lpuart1 as console
 - sdhc1/2 as storage

As of now, because scmi pinctrl support not ready, so count on
bootloader to set the pinctrl.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/Makefile            |   1 +
 arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts | 115 ++++++++++++++++++++++
 2 files changed, 116 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 518149d295a1..c830ff88f5f8 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -209,6 +209,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba93xxca.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba93xxla.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx93-var-som-symphony.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk.dtb
 
 imx8mm-venice-gw72xx-0x-imx219-dtbs	:= imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-imx219.dtbo
 imx8mm-venice-gw72xx-0x-rpidsi-dtbs	:= imx8mm-venice-gw72xx-0x.dtb imx8mm-venice-gw72xx-0x-rpidsi.dtbo
diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
new file mode 100644
index 000000000000..ffef1cd9eb92
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2024 NXP
+ */
+
+/dts-v1/;
+
+#include "imx95.dtsi"
+
+/ {
+	model = "NXP i.MX95 19X19 board";
+	compatible = "fsl,imx95-19x19-evk", "fsl,imx95";
+
+	aliases {
+		gpio0 = &gpio1;
+		gpio1 = &gpio2;
+		gpio2 = &gpio3;
+		gpio3 = &gpio4;
+		gpio4 = &gpio5;
+		i2c0 = &lpi2c1;
+		i2c1 = &lpi2c2;
+		i2c2 = &lpi2c3;
+		i2c3 = &lpi2c4;
+		i2c4 = &lpi2c5;
+		i2c5 = &lpi2c6;
+		i2c6 = &lpi2c7;
+		i2c7 = &lpi2c8;
+		mmc0 = &usdhc1;
+		mmc1 = &usdhc2;
+		mmc2 = &usdhc3;
+		serial0 = &lpuart1;
+		serial1 = &lpuart2;
+		serial2 = &lpuart3;
+		serial3 = &lpuart4;
+		serial4 = &lpuart5;
+		serial5 = &lpuart6;
+		serial6 = &lpuart7;
+		serial7 = &lpuart8;
+	};
+
+	chosen {
+		stdout-path = &lpuart1;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0 0x80000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		linux_cma: linux,cma {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0 0x80000000 0 0x7F000000>;
+			size = <0 0x3c000000>;
+			linux,cma-default;
+			reusable;
+		};
+	};
+
+	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_vref_1v8: regulator-adc-vref {
+		compatible = "regulator-fixed";
+		regulator-name = "vref_1v8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+};
+
+&displaymix_irqsteer {
+	status = "okay";
+};
+
+&lpuart1 {
+	/* console */
+	status = "okay";
+};
+
+&mu7 {
+	status = "okay";
+};
+
+&usdhc1 {
+	bus-width = <8>;
+	non-removable;
+	no-sdio;
+	no-sd;
+	status = "okay";
+};
+
+&usdhc2 {
+	non-removable;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&wdog3 {
+	status = "okay";
+};

-- 
2.37.1



From peng.fan at nxp.com  Mon Feb 26 05:16:51 2024
From: peng.fan at nxp.com (Peng Fan)
Date: Mon, 26 Feb 2024 13:16:51 +0000
Subject: [PATCH] pinctrl: scmi: support i.MX OEM pin configuration type
In-Reply-To: <20240223071557.2681316-1-peng.fan@oss.nxp.com>
References: <20240223071557.2681316-1-peng.fan@oss.nxp.com>
Message-ID: <DU0PR04MB94172086AB4EF0389B78CA6A885A2@DU0PR04MB9417.eurprd04.prod.outlook.com>

Hi Linus, Sudeep, Cristian,

> Subject: [PATCH] pinctrl: scmi: support i.MX OEM pin configuration type

Sorry to ping early, but this impacts the design and i.MX95 SoC upstream(
although I removed pinctrl to let uboot init pinmux as of now), so I would
like see whether are you ok with the approach or not. This is the best as
of now I could think out to not adding more size to firmware and make the
dts format similar as previous i.MX.

Thanks,
Peng.

> 
> From: Peng Fan <peng.fan at nxp.com>
> 
> i.MX95 System Manager FW supports SCMI PINCTRL protocol, but uses OEM
> Pin Configuration type, so extend the driver to support custom params.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
> 
> V1:
>  Based on https://lore.kernel.org/all/20240223-pinctrl-scmi-v4-0-
> 10eb5a379274 at nxp.com/
>  This is an reimplementation for supporting i.MX95 OEM settings.
>  With this patch, the dts will be like:
> 
> +#define IMX95_PAD_SD1_CLK__USDHC1_CLK(val)	\
> +	sd1clk {				\
> +		pins = "sd1clk";		\
> +		imx,func-id = <0>;		\
> +		imx,pin-conf = <val>;		\
> +	}
>   ....
> +
> +	pinctrl_usdhc1: usdhc1grp {
> +		IMX95_PAD_SD1_CLK__USDHC1_CLK(0x158e);
> +		IMX95_PAD_SD1_CMD__USDHC1_CMD(0x138e);
>  ....
> +	};
> 
>  drivers/pinctrl/pinctrl-scmi.c | 10 ++++++++++  drivers/pinctrl/pinctrl-scmi.h
> | 15 +++++++++++++++
>  2 files changed, 25 insertions(+)
>  create mode 100644 drivers/pinctrl/pinctrl-scmi.h
> 
> diff --git a/drivers/pinctrl/pinctrl-scmi.c b/drivers/pinctrl/pinctrl-scmi.c index
> f2fef3fb85ae..e58f1aaf9963 100644
> --- a/drivers/pinctrl/pinctrl-scmi.c
> +++ b/drivers/pinctrl/pinctrl-scmi.c
> @@ -19,6 +19,7 @@
>  #include <linux/pinctrl/pinctrl.h>
>  #include <linux/pinctrl/pinmux.h>
> 
> +#include "pinctrl-scmi.h"
>  #include "pinctrl-utils.h"
>  #include "core.h"
>  #include "pinconf.h"
> @@ -472,6 +473,13 @@ static const struct pinconf_ops
> pinctrl_scmi_pinconf_ops = {
>  	.pin_config_config_dbg_show = pinconf_generic_dump_config,  };
> 
> +static const struct pinconf_generic_params pinctrl_scmi_oem_dt_params[] =
> {
> +	{"imx,func-id", IMX_SCMI_PIN_MUX, -1},
> +	{"imx,daisy-id", IMX_SCMI_PIN_DAISY_ID, -1},
> +	{"imx,daisy-conf", IMX_SCMI_PIN_DAISY_CFG, -1},
> +	{"imx,pin-conf", IMX_SCMI_PIN_CONF, -1}, };
> +
>  static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx,
>  				 unsigned int *nr_pins,
>  				 const struct pinctrl_pin_desc **pins) @@ -
> 548,6 +556,8 @@ static int scmi_pinctrl_probe(struct scmi_device *sdev)
>  	pmx->pctl_desc.pctlops = &pinctrl_scmi_pinctrl_ops;
>  	pmx->pctl_desc.pmxops = &pinctrl_scmi_pinmux_ops;
>  	pmx->pctl_desc.confops = &pinctrl_scmi_pinconf_ops;
> +	pmx->pctl_desc.custom_params = pinctrl_scmi_oem_dt_params;
> +	pmx->pctl_desc.num_custom_params =
> +ARRAY_SIZE(pinctrl_scmi_oem_dt_params);
> 
>  	ret = pinctrl_scmi_get_pins(pmx, &pmx->pctl_desc.npins,
>  				    &pmx->pctl_desc.pins);
> diff --git a/drivers/pinctrl/pinctrl-scmi.h b/drivers/pinctrl/pinctrl-scmi.h new
> file mode 100644 index 000000000000..fcc61bc19c98
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-scmi.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#ifndef __DRIVERS_PINCTRL_SCMI_H
> +#define __DRIVERS_PINCTRL_SCMI_H
> +
> +/* OEM VENDOR Pin Configuration Type */
> +#define IMX_SCMI_PIN_MUX	192
> +#define IMX_SCMI_PIN_CONF	193
> +#define IMX_SCMI_PIN_DAISY_ID	194
> +#define IMX_SCMI_PIN_DAISY_CFG	195
> +
> +#endif /* __DRIVERS_PINCTRL_SCMI_H */
> --
> 2.37.1



From broonie at kernel.org  Mon Feb 26 05:18:16 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 26 Feb 2024 13:18:16 +0000
Subject: [PATCH] arm64/sysreg: Add BRBE registers and fields
In-Reply-To: <20240226042441.4098806-1-anshuman.khandual@arm.com>
References: <20240125094119.2542332-2-anshuman.khandual@arm.com>
 <20240226042441.4098806-1-anshuman.khandual@arm.com>
Message-ID: <79fed7cc-44f1-4afa-a969-8327be128617@sirena.org.uk>

On Mon, Feb 26, 2024 at 09:54:41AM +0530, Anshuman Khandual wrote:

> Please find the modified patch here for a quick review and do let me know
> if this looks good for the next version i.e V17. BRBCR_EL1/12/2 organized
> per their encoding. Thanks !

That looks good to me from a quick scan.
-------------- 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/20240226/ba7ffb69/attachment-0001.sig>

From broonie at kernel.org  Mon Feb 26 05:19:12 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 26 Feb 2024 13:19:12 +0000
Subject: [PATCH v6 2/8] arm64/sysreg: Add a comment that the sysreg file
 should be sorted
In-Reply-To: <20240226113044.228403-3-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
 <20240226113044.228403-3-james.clark@arm.com>
Message-ID: <169b5402-296b-4abf-a16e-91c8136b07b3@sirena.org.uk>

On Mon, Feb 26, 2024 at 11:30:30AM +0000, James Clark wrote:
> There are a few entries particularly at the end of the file that aren't
> in order. To avoid confusion, add a comment that might help new entries
> to be added in the right place.
> 
> Signed-off-by: James Clark <james.clark at arm.com>

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/20240226/5e829c05/attachment.sig>

From broonie at kernel.org  Mon Feb 26 05:21:06 2024
From: broonie at kernel.org (Mark Brown)
Date: Mon, 26 Feb 2024 13:21:06 +0000
Subject: [PATCH v6 4/8] arm64/sysreg/tools: Move TRFCR definitions to
 sysreg
In-Reply-To: <20240226113044.228403-5-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
 <20240226113044.228403-5-james.clark@arm.com>
Message-ID: <170e6979-9e85-4f7f-9aa2-1e5ecde358a4@sirena.org.uk>

On Mon, Feb 26, 2024 at 11:30:32AM +0000, James Clark wrote:
> Convert TRFCR to automatic generation. Add separate definitions for ELx
> and EL2 as TRFCR_EL1 doesn't have CX. This also mirrors the previous
> definition so no code change is required.
> 
> Also add TRFCR_EL12 which will start to be used in a later commit.

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/20240226/c49e6f4b/attachment.sig>

From mripard at kernel.org  Mon Feb 26 05:22:18 2024
From: mripard at kernel.org (Maxime Ripard)
Date: Mon, 26 Feb 2024 14:22:18 +0100
Subject: [PATCH v7 00/36] drm/connector: Create HDMI Connector
 infrastructure
In-Reply-To: <CAA8EJpqB+Mf4jp88__r5dfsRSuGdAB+Q3vK5MBfBXysvRB92iQ@mail.gmail.com>
References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org>
 <CAA8EJpqB+Mf4jp88__r5dfsRSuGdAB+Q3vK5MBfBXysvRB92iQ@mail.gmail.com>
Message-ID: <4mm45qddujasmbinalcyhjzu4iege3n2a7odbmqmcsnjifyleh@q3kdpjhvwhsq>

Hi Dmitry,

On Sun, Feb 25, 2024 at 04:50:00PM +0200, Dmitry Baryshkov wrote:
> On Thu, 22 Feb 2024 at 20:14, Maxime Ripard <mripard at kernel.org> wrote:
> > Here's a series that creates some extra infrastructure specifically
> > targeted at HDMI controllers.
> >
> > The idea behind this series came from a recent discussion on IRC during
> > which we discussed infoframes generation of i915 vs everything else.
> >
> > Infoframes generation code still requires some decent boilerplate, with
> > each driver doing some variation of it.
> >
> > In parallel, while working on vc4, we ended up converting a lot of i915
> > logic (mostly around format / bpc selection, and scrambler setup) to
> > apply on top of a driver that relies only on helpers.
> >
> > While currently sitting in the vc4 driver, none of that logic actually
> > relies on any driver or hardware-specific behaviour.
> >
> > The only missing piece to make it shareable are a bunch of extra
> > variables stored in a state (current bpc, format, RGB range selection,
> > etc.).
> >
> > The initial implementation was relying on some generic subclass of
> > drm_connector to address HDMI connectors, with a bunch of helpers that
> > will take care of all the "HDMI Spec" related code. Scrambler setup is
> > missing at the moment but can easily be plugged in.
> >
> > The feedback was that creating a connector subclass like was done for
> > writeback would prevent the adoption of those helpers since it couldn't
> > be used in all situations (like when the connector driver can implement
> > multiple output) and required more churn to cast between the
> > drm_connector and its subclass. The decision was thus to provide a set
> > of helper and to store the required variables in drm_connector and
> > drm_connector_state. This what has been implemented now.
> >
> > Hans Verkuil also expressed interest in implementing a mechanism in v4l2
> > to retrieve infoframes from HDMI receiver and implementing a tool to
> > decode (and eventually check) infoframes. His current work on
> > edid-decode to enable that based on that series can be found here:
> > https://git.linuxtv.org/hverkuil/edid-decode.git/log/?h=hverkuil
> >
> > And some more context here:
> > https://lore.kernel.org/dri-devel/50db7366-cd3d-4675-aaad-b857202234de at xs4all.nl/
> >
> > This series thus leverages the infoframe generation code to expose it
> > through debugfs.
> 
> [...]
> 
> >
> > Let me know what you think,
> > Maxime
> 
> The overall idea looks great. I've started checking how I can use that
> for our msm devices family, which makes use of bridges and
> drm_bridge_connector.

Yeah, I had that in mind for a while too. I think it would be valuable,
but it's difficult as it is already so I didn't tackle it at first :)

The format negociation especially seems to divert quite a lot from what
i915 and vc4 have been doing, and that's user facing to some extent.

> My current idea is to extend the drm_bridge_funcs with the new
> callback to be called once the drm_connector has been instantiated.
> This way all the bridges can influence new connector.
> Another possibility is to follow drm_bridge_connector design closely
> and let it call into drm_connector_hdmi code if it detects that the
> last bridge is the HDMI one.
> WDYT?

I had the latter in mind, but I haven't really tried to reconcile the
connector state output_format with the
drm_atomic_helper_bridge_propagate_bus_fmt, and plug in the output_bpc
count too.

We would have to create the max_bpc properties from the HDMI connector,
and then propagate that upstream along the bridges I guess (or we can
just ignore it for now).

So, yeah, I had the latter in mind but it might turn out that the former
is actually easier. Both make sense to me at least.

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/20240226/4fad03e2/attachment.sig>

From cristian.marussi at arm.com  Mon Feb 26 05:28:28 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 26 Feb 2024 13:28:28 +0000
Subject: [PATCH] dt-bindings: firmware: arm,scmi: support system power
 protocol
In-Reply-To: <20240226130243.3820915-1-peng.fan@oss.nxp.com>
References: <20240226130243.3820915-1-peng.fan@oss.nxp.com>
Message-ID: <ZdyR_MWeqOWga8iQ@pluto>

On Mon, Feb 26, 2024 at 09:02:43PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add SCMI System Power Protocol bindings, and the protocol id is 0x12.
> 
Hi,

yes this is something I spotted in the past it was missing and I posted
a similar patch but I was told that a protocol node without any specific
additional properties is already being described by the general protocol
node described above.

Thanks,
Cristian

> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  Documentation/devicetree/bindings/firmware/arm,scmi.yaml | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
> index 4591523b51a0..d99f1577476e 100644
> --- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
> +++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
> @@ -141,6 +141,14 @@ properties:
>      required:
>        - '#power-domain-cells'
>  
> +  protocol at 12:
> +    $ref: '#/$defs/protocol-node'
> +    unevaluatedProperties: false
> +
> +    properties:
> +      reg:
> +        const: 0x12
> +
>    protocol at 13:
>      $ref: '#/$defs/protocol-node'
>      unevaluatedProperties: false
> -- 
> 2.37.1
> 


From cristian.marussi at arm.com  Mon Feb 26 05:31:58 2024
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 26 Feb 2024 13:31:58 +0000
Subject: [PATCH 5/5] firmware: imx: add i.MX95 MISC driver
In-Reply-To: <ZdjlaiQQq67e52Q3@pluto>
References: <20240202-imx95-bbm-misc-v1-0-3cb743020933@nxp.com>
 <20240202-imx95-bbm-misc-v1-5-3cb743020933@nxp.com>
 <ZdjlaiQQq67e52Q3@pluto>
Message-ID: <ZdySzr2JzohJgppR@pluto>

On Fri, Feb 23, 2024 at 06:35:26PM +0000, Cristian Marussi wrote:
> On Fri, Feb 02, 2024 at 02:34:43PM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> > 
> > The i.MX95 System manager exports SCMI MISC protocol for linux to do
> > various settings, such as set board gpio expander as wakeup source.
> > 
> 
> Hi,
> 
> > The driver is to add the support.
> > 
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  drivers/firmware/imx/Makefile   |  1 +
> >  drivers/firmware/imx/sm-misc.c  | 92 +++++++++++++++++++++++++++++++++++++++++
> >  include/linux/firmware/imx/sm.h | 33 +++++++++++++++
> >  3 files changed, 126 insertions(+)
> > 
> > diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
> > index fb20e22074e1..cb9c361d9b81 100644
> > --- a/drivers/firmware/imx/Makefile
> > +++ b/drivers/firmware/imx/Makefile
> > @@ -2,3 +2,4 @@
> >  obj-$(CONFIG_IMX_DSP)		+= imx-dsp.o
> >  obj-$(CONFIG_IMX_SCU)		+= imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
> >  obj-${CONFIG_IMX_SCMI_BBM_EXT}	+= sm-bbm.o
> > +obj-${CONFIG_IMX_SCMI_MISC_EXT}	+= sm-misc.o
> 
> Same considerations about missing Kconfig as in BBM and implicit
> dependency on the NXP MISC vendor module...this way also you cannot even
> NOT compile this module when the Vendor protocol is compiled in for,
> say, testing purposes...
> 
> > diff --git a/drivers/firmware/imx/sm-misc.c b/drivers/firmware/imx/sm-misc.c
> > new file mode 100644
> > index 000000000000..4410e69d256b
> > --- /dev/null
> > +++ b/drivers/firmware/imx/sm-misc.c
> > @@ -0,0 +1,92 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright 2024 NXP.
> > + */
> > +
> > +#include <linux/firmware/imx/sm.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/scmi_protocol.h>
> > +#include <linux/scmi_nxp_protocol.h>
> > +
> > +static const struct scmi_imx_misc_proto_ops *imx_misc_ctrl_ops;
> > +static struct scmi_protocol_handle *ph;
> 
> This global does NOT sound right...if there are multiple SCMI instances
> defined in the DT this can be probed multiple times, and the MISC
> protocol will be initialized multuple times, each instance will have
> its distinct protocol_handle *ph...so store it somewhere like you did in
> the BBM driver
> 
> > +struct notifier_block scmi_imx_misc_ctrl_nb;
> > +
> > +int scmi_imx_misc_ctrl_set(u32 id, u32 val)
> > +{
> > +	if (!ph)
> > +		return -EPROBE_DEFER;
> > +
> > +	return imx_misc_ctrl_ops->misc_ctrl_set(ph, id, 1, &val);
> > +};
> > +EXPORT_SYMBOL(scmi_imx_misc_ctrl_set);
> > +
> > +int scmi_imx_misc_ctrl_get(u32 id, u32 *num, u32 *val)
> > +{
> > +	if (!ph)
> > +		return -EPROBE_DEFER;
> > +
> > +	return imx_misc_ctrl_ops->misc_ctrl_get(ph, id, num, val);
> > +}
> > +EXPORT_SYMBOL(scmi_imx_misc_ctrl_get);
> > +
> 
> Ok, now I suppose that you want to be sure to run just one instance if
> this driver...
> 
> > +static int scmi_imx_misc_ctrl_notifier(struct notifier_block *nb,
> > +				       unsigned long event, void *data)
> > +{
> > +	return 0;
> > +}
> 
> What is the point of this ?
> 
> > +
> > +static int scmi_imx_misc_ctrl_probe(struct scmi_device *sdev)
> > +{
> > +	const struct scmi_handle *handle = sdev->handle;
> > +	struct device_node *np = sdev->dev.of_node;
> > +	u32 src_id, evt_id, wu_num;
> > +	int ret, i;
> > +
> > +	if (!handle)
> > +		return -ENODEV;
> > +
> > +	imx_misc_ctrl_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_IMX_MISC, &ph);
> > +	if (IS_ERR(imx_misc_ctrl_ops))
> > +		return PTR_ERR(imx_misc_ctrl_ops);
> > +
> > +	scmi_imx_misc_ctrl_nb.notifier_call = &scmi_imx_misc_ctrl_notifier;
> > +	wu_num = of_property_count_u32_elems(np, "wakeup-sources");
> > +	if (wu_num % 2) {
> > +		dev_err(&sdev->dev, "Invalid wakeup-sources\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	for (i = 0; i < wu_num; i += 2) {
> > +		WARN_ON(of_property_read_u32_index(np, "wakeup-sources", i, &src_id));
> > +		WARN_ON(of_property_read_u32_index(np, "wakeup-sources", i + 1, &evt_id));
> > +		ret = handle->notify_ops->devm_event_notifier_register(sdev, SCMI_PROTOCOL_IMX_MISC,
> > +								       evt_id,
> > +								       &src_id,
> > +								       &scmi_imx_misc_ctrl_nb);
> 
> ...when probed more than once this will lead to the same global nb registered on 2
> different notification chains....
> 
> > +		if (ret)
> > +			dev_err(&sdev->dev, "Failed to register scmi misc event: %d\n", src_id);
> > +	}
> > +
> > +	return 0;
> > +
> > +}
> > +
> > +static const struct scmi_device_id scmi_id_table[] = {
> > +	{ SCMI_PROTOCOL_IMX_MISC, "imx-misc-ctrl" },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(scmi, scmi_id_table);
> > +
> > +static struct scmi_driver scmi_imx_misc_ctrl_driver = {
> > +	.name = "scmi-imx-misc-ctrl",
> > +	.probe = scmi_imx_misc_ctrl_probe,
> > +	.id_table = scmi_id_table,
> > +};
> > +module_scmi_driver(scmi_imx_misc_ctrl_driver);
> > +
> 
> All in all, I suppose the main thing to reason about this driver is if you
> want/plan to allow for multiple instances of it to be loaded/probed on the same
> running system or not...
> 
> If you think that this driver HAS STRICTLY to be probed once, and having
> 2 DT protocol nodes for MISC it is certainly an error, we will have to
> add some mechianism in the SCMI core to be able to mark this as single
> instance and refuse to create more than one device for this protocol...a
> sort of generalization of what is done in a custom way by the core for
> SYSTEM_POWER, since we dont want to have multiple sources of shutdown
> events...

An easier solution would be of course for this driver to just check if
any global ph was already retrieved on a previous probe and just bail
out, but I want to have a chat with Sudeep about this approach.

Thanks,
Cristian


From maz at kernel.org  Mon Feb 26 05:35:28 2024
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 26 Feb 2024 13:35:28 +0000
Subject: [PATCH v6 5/8] arm64: KVM: Add iflag for FEAT_TRF
In-Reply-To: <20240226113044.228403-6-james.clark@arm.com>
References: <20240226113044.228403-1-james.clark@arm.com>
	<20240226113044.228403-6-james.clark@arm.com>
Message-ID: <86edcz2vrz.wl-maz@kernel.org>

On Mon, 26 Feb 2024 11:30:33 +0000,
James Clark <james.clark at arm.com> wrote:
> 
> Add an extra iflag to signify if the TRFCR register is accessible.

That's not what this flag means: it indicates whether TRFCR needs to
be saved. At lease that's what the name suggests.

> Because TRBE requires FEAT_TRF, DEBUG_STATE_SAVE_TRBE still has the same
> behavior even though it's only set when FEAT_TRF is present.

This sentence seems completely out of context, because you didn't
explain that you were making TRBE *conditional* on TRF being
implemented, as per the architecture requirements.

> 
> The following holes are left in struct kvm_vcpu_arch, but there aren't
> enough other 8 bit fields to rearrange it to leave any hole smaller than
> 7 bytes:
> 
>   u8                         cflags;               /*  2292     1 */
>   /* XXX 1 byte hole, try to pack */
>   u16                        iflags;               /*  2294     2 */
>   u8                         sflags;               /*  2296     1 */
>   bool                       pause;                /*  2297     1 */
>   /* XXX 6 bytes hole, try to pack */

I don't think that's particularly useful in a commit message, but more
relevant to the cover letter. However, see below.

> 
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  arch/arm64/include/asm/kvm_host.h |  4 +++-
>  arch/arm64/kvm/debug.c            | 24 ++++++++++++++++++++----
>  2 files changed, 23 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 21c57b812569..85b5477bd1b4 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -569,7 +569,7 @@ struct kvm_vcpu_arch {
>  	u8 cflags;
>  
>  	/* Input flags to the hypervisor code, potentially cleared after use */
> -	u8 iflags;
> +	u16 iflags;
>  
>  	/* State flags for kernel bookkeeping, unused by the hypervisor code */
>  	u8 sflags;
> @@ -779,6 +779,8 @@ struct kvm_vcpu_arch {
>  #define DEBUG_STATE_SAVE_TRBE	__vcpu_single_flag(iflags, BIT(6))
>  /* vcpu running in HYP context */
>  #define VCPU_HYP_CONTEXT	__vcpu_single_flag(iflags, BIT(7))
> +/* Save trace filter controls */
> +#define DEBUG_STATE_SAVE_TRFCR	__vcpu_single_flag(iflags, BIT(8))

I'd rather you cherry-pick [1] and avoid expanding the iflags.

[1] https://lore.kernel.org/r/20240226100601.2379693-4-maz at kernel.org

Now, I think the whole SPE/TRBE/TRCR flag management should be
improved, see below.

>
>  /* SVE enabled for host EL0 */
>  #define HOST_SVE_ENABLED	__vcpu_single_flag(sflags, BIT(0))
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index ce8886122ed3..49a13e72ddd2 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -332,14 +332,30 @@ void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu)
>  	    !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(PMBIDR_EL1_P_SHIFT)))
>  		vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_SPE);
>  
> -	/* Check if we have TRBE implemented and available at the host */
> -	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) &&
> -	    !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P))
> -		vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
> +	/*
> +	 * Set SAVE_TRFCR flag if FEAT_TRF (TraceFilt) exists. This flag
> +	 * signifies that the exclude_host/exclude_guest settings of any active
> +	 * host Perf session on a core running a VCPU can be written into
> +	 * TRFCR_EL1 on guest switch.
> +	 */
> +	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceFilt_SHIFT)) {
> +		vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);

Can we avoid doing this unconditionally? It only makes sense to save
the trace crud if it is going to be changed, right?

> +		/*
> +		 * Check if we have TRBE implemented and available at the host.
> +		 * If it's in use at the time of guest switch then trace will
> +		 * need to be completely disabled. The architecture mandates
> +		 * FEAT_TRF with TRBE, so we only need to check for TRBE after
> +		 * TRF.
> +		 */
> +		if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) &&
> +		    !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P))
> +			vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
> +	}
>  }
>  
>  void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
>  {
>  	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
>  	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
> +	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRFCR);
>  }

Dealing with flags that are strongly coupled in a disjoined way a
pretty bad idea. Look at the generated code, and realise we flip the
preempt flag on each access.

Can we do better? You bet. The vcpu_{set,clear}_flags infrastructure
is capable of dealing with multiple flags at once, as demonstrated by
the way we deal with exception encoding.

Something like:

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index addf79ba8fa0..3e50e535fdd4 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -885,6 +885,10 @@ struct kvm_vcpu_arch {
 #define DEBUG_STATE_SAVE_SPE	__vcpu_single_flag(iflags, BIT(5))
 /* Save TRBE context if active  */
 #define DEBUG_STATE_SAVE_TRBE	__vcpu_single_flag(iflags, BIT(6))
+/* Save Trace Filter Controls  */
+#define DEBUG_STATE_SAVE_TRFCR	__vcpu_single_flag(iflags, BIT(7))
+/* Global debug mask */
+#define DEBUG_STATE_SAVE_MASK	__vcpu_single_flag(iflags, GENMASK(7, 5))
 
 /* SVE enabled for host EL0 */
 #define HOST_SVE_ENABLED	__vcpu_single_flag(sflags, BIT(0))
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 8725291cb00a..f9b197a00582 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -339,6 +339,6 @@ void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu)
 
 void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
 {
-	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE);
-	vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE);
+	if (!has_vhe())
+	    vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_MASK);
 }

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From sakari.ailus at iki.fi  Mon Feb 26 05:37:11 2024
From: sakari.ailus at iki.fi (Sakari Ailus)
Date: Mon, 26 Feb 2024 13:37:11 +0000
Subject: [PATCH v2 2/5] dt-bindings: media: Add bindings for ARM mali-c55
In-Reply-To: <20240226125818.GA26163@pendragon.ideasonboard.com>
References: <20240214141906.245685-1-dan.scally@ideasonboard.com>
 <20240214141906.245685-3-dan.scally@ideasonboard.com>
 <Zdx77nyiQn4zya3h@valkosipuli.retiisi.eu>
 <20240226120431.GA25561@pendragon.ideasonboard.com>
 <ZdyB_yHn9yImTuhm@valkosipuli.retiisi.eu>
 <20240226125818.GA26163@pendragon.ideasonboard.com>
Message-ID: <ZdyUB_SEx8Gfa7OP@valkosipuli.retiisi.eu>

Hi Laurent,

On Mon, Feb 26, 2024 at 02:58:18PM +0200, Laurent Pinchart wrote:
> > > > > +              remote-endpoint = <&mipi_out>;
> > > > 
> > > > I suppose this is a CSI-2 interface with D-PHY?
> > > 
> > > No, that's an internal parallel bus. Depending on the SoC integration,
> > > it can be connected to a CSI-2 receiver, a DMA engine, or a mux to
> > > select between different sources.
> > 
> > The name suggests otherwise. Maybe change that to something more
> > descriptive?
> 
> We could rename mipi_out to csi2_rx_out, sure.

Sounds good to me.

-- 
Sakari Ailus


From andrew at lunn.ch  Mon Feb 26 05:39:37 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 26 Feb 2024 14:39:37 +0100
Subject: [PATCH] ARM: mvebu: Add check in coherency.c to prevent null
 pointer dereference
In-Reply-To: <20240225060450.53044-1-duoming@zju.edu.cn>
References: <20240225060450.53044-1-duoming@zju.edu.cn>
Message-ID: <eb036663-2109-4d75-8386-451fa5c34889@lunn.ch>

On Sun, Feb 25, 2024 at 02:04:50PM +0800, Duoming Zhou wrote:
> The kzalloc() in armada_375_380_coherency_init() will return
> null if the physical memory has run out. As a result, if we
> dereference the property pointer, the null pointer dereference
> bug will happen.
> 
> This patch adds a check to avoid null pointer dereference.
> 
> Fixes: 497a92308af8 ("ARM: mvebu: implement L2/PCIe deadlock workaround")
> Signed-off-by: Duoming Zhou <duoming at zju.edu.cn>

I have to wounder how we can run out of memory here. This code is
being called from:

postcore_initcall(coherency_late_init);

If you look at:

https://elixir.bootlin.com/linux/latest/source/include/linux/init.h#L299

You can see that only true kernel core stuff has been called before
that. If that has consumed all the available memory, something is very
seriously wrong, and the machine is not going to last another couple
of milliseconds before it crashes no matter what checking you do.

So i do wounder if your time could be better spent in other places?

	Andrew


From geert at linux-m68k.org  Mon Feb 26 05:41:21 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 26 Feb 2024 14:41:21 +0100
Subject: [PATCH 1/4] dt-bindings: soc: renesas: Document Renesas RZ/V2H{P}
 SoC variants
In-Reply-To: <20240219160912.1206647-2-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20240219160912.1206647-1-prabhakar.mahadev-lad.rj@bp.renesas.com> <20240219160912.1206647-2-p